LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICogTm90ZTogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpZmRlZiBIQVZFX1NZU19USU1FX0gKIyBpbmNsdWRlIDxzeXMvdGltZS5oPgojZW5kaWYKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zdm0uaCIKI2luY2x1ZGUgInZnYS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKCnN0YXRpYyBCT09MIERPU1ZNX2lzZG9zZXhlOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgRE9TVk1fSXNXaW4xNgogKiAKICogUmV0dXJuIFRSVUUgaWYgd2UgYXJlIGluIFdpbmRvd3MgcHJvY2Vzcy4KICovCkJPT0wgRE9TVk1fSXNXaW4xNih2b2lkKQp7CiAgcmV0dXJuIERPU1ZNX2lzZG9zZXhlID8gRkFMU0UgOiBUUlVFOwp9CgojaWZkZWYgTVpfU1VQUE9SVEVECgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBQU1BfU0laRSAweDEwCgojZGVmaW5lIFNFRzE2KHB0cixzZWcpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpKHNlZyk8PDQpKSkKI2RlZmluZSBTRUdQVFIxNihwdHIsc2VncHRyKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKVNFTEVDVE9ST0Yoc2VncHRyKTw8NCkrT0ZGU0VUT0Yoc2VncHRyKSkpCgovKiBzdHJ1Y3R1cmVzIGZvciBFWEVDICovCgojaW5jbHVkZSAicHNocGFjazEuaCIKCnR5cGVkZWYgc3RydWN0IHsKICBXT1JEIGVudl9zZWc7CiAgRFdPUkQgY21kbGluZTsKICBEV09SRCBmY2IxOwogIERXT1JEIGZjYjI7CiAgV09SRCBpbml0X3NwOwogIFdPUkQgaW5pdF9zczsKICBXT1JEIGluaXRfaXA7CiAgV09SRCBpbml0X2NzOwp9IEV4ZWNCbG9jazsKCnR5cGVkZWYgc3RydWN0IHsKICBXT1JEIGxvYWRfc2VnOwogIFdPUkQgcmVsX3NlZzsKfSBPdmVybGF5QmxvY2s7CgojaW5jbHVkZSAicG9wcGFjay5oIgoKLyogZ2xvYmFsIHZhcmlhYmxlcyAqLwoKcGlkX3QgZG9zdm1fcGlkOwoKc3RhdGljIFdPUkQgaW5pdF9jcyxpbml0X2lwLGluaXRfc3MsaW5pdF9zcDsKc3RhdGljIEhBTkRMRSBkb3N2bV90aHJlYWQsIGxvb3BfdGhyZWFkOwpzdGF0aWMgRFdPUkQgZG9zdm1fdGlkLCBsb29wX3RpZDsKCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCggTFBDU1RSIGNtZHRhaWwsIGludCBsZW5ndGggKTsKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCk7CgpzdGF0aWMgdm9pZCBNWl9DcmVhdGVQU1AoIExQVk9JRCBscFBTUCwgV09SRCBlbnYsIFdPUkQgcGFyICkKewogIFBEQjE2KnBzcD1scFBTUDsKCiAgcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogIC8qIHNvbWUgcHJvZ3JhbXMgdXNlIHRoaXMgdG8gY2FsY3VsYXRlIGhvdyBtdWNoIG1lbW9yeSB0aGV5IG5lZWQgKi8KICBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOyAvKiBGSVhNRTogdXNlIGEgcmVhbCB2YWx1ZSAqLwogIC8qIEZJWE1FOiBkaXNwYXRjaGVyICovCiAgcHNwLT5zYXZlZGludDIyID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjIpOwogIHBzcC0+c2F2ZWRpbnQyMyA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIzKTsKICBwc3AtPnNhdmVkaW50MjQgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyNCk7CiAgcHNwLT5wYXJlbnRQU1A9cGFyOwogIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgpzdGF0aWMgdm9pZCBNWl9GaWxsUFNQKCBMUFZPSUQgbHBQU1AsIExQQ1NUUiBjbWR0YWlsLCBpbnQgbGVuZ3RoICkKewogICAgUERCMTYgKnBzcCA9IGxwUFNQOwoKICAgIGlmKGxlbmd0aCA+IDEyNykgCiAgICB7CiAgICAgICAgV0FSTiggIkNvbW1hbmQgdGFpbCB0cnVuY2F0ZWQhIChsZW5ndGggJWQpXG4iLCBsZW5ndGggKTsKICAgICAgICBsZW5ndGggPSAxMjY7CiAgICB9CgogICAgcHNwLT5jbWRMaW5lWzBdID0gbGVuZ3RoOwoKICAgIC8qCiAgICAgKiBMZW5ndGggb2YgZXhhY3RseSAxMjcgYnl0ZXMgbWVhbnMgdGhhdCBmdWxsIGNvbW1hbmQgbGluZSBpcyAKICAgICAqIHN0b3JlZCBpbiBlbnZpcm9ubWVudCB2YXJpYWJsZSBDTURMSU5FIGFuZCBQU1AgY29udGFpbnMgCiAgICAgKiBjb21tYW5kIHRhaWwgdHJ1bmNhdGVkIHRvIDEyNiBieXRlcy4KICAgICAqLwogICAgaWYobGVuZ3RoID09IDEyNykKICAgICAgICBsZW5ndGggPSAxMjY7CgogICAgaWYobGVuZ3RoID4gMCkKICAgICAgICBtZW1tb3ZlKHBzcC0+Y21kTGluZSsxLCBjbWR0YWlsLCBsZW5ndGgpOwoKICAgIHBzcC0+Y21kTGluZVtsZW5ndGgrMV0gPSAnXHInOwoKICAgIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgpzdGF0aWMgV09SRCBNWl9Jbml0RW52aXJvbm1lbnQoIExQQ1NUUiBlbnYsIExQQ1NUUiBuYW1lICkKewogdW5zaWduZWQgc3o9MDsKIHVuc2lnbmVkIGk9MDsKIFdPUkQgc2VnOwogTFBTVFIgZW52YmxrOwoKIGlmIChlbnYpIHsKICAvKiBnZXQgc2l6ZSBvZiBlbnZpcm9ubWVudCBibG9jayAqLwogIHdoaWxlIChlbnZbc3orK10pIHN6Kz1zdHJsZW4oZW52K3N6KSsxOwogfSBlbHNlIHN6Kys7CiAvKiBhbGxvY2F0ZSBpdCAqLwogZW52YmxrPURPU01FTV9HZXRCbG9jayhzeitzaXplb2YoV09SRCkrc3RybGVuKG5hbWUpKzEsJnNlZyk7CiAvKiBmaWxsIGl0ICovCiBpZiAoZW52KSB7CiAgbWVtY3B5KGVudmJsayxlbnYsc3opOwogfSBlbHNlIGVudmJsa1swXT0wOwogLyogRE9TIGVudmlyb25tZW50IHZhcmlhYmxlcyBhcmUgdXBwZXJjYXNlICovCiB3aGlsZSAoZW52YmxrW2ldKXsKICB3aGlsZSAoZW52YmxrW2ldICE9ICc9Jyl7CiAgIGlmIChlbnZibGtbaV0+PSdhJyAmJiBlbnZibGtbaV0gPD0gJ3onKXsKICAgIGVudmJsa1tpXSAtPSAzMjsKICAgfQogICBpKys7CiAgfQogIGkgKz0gc3RybGVuKGVudmJsaytpKSArIDE7CiB9CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSh2b2lkKQp7CiAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKICAgIERPU01FTV9Jbml0KFRSVUUpOwogICAgRE9TREVWX0luc3RhbGxET1NEZXZpY2VzKCk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MIE1aX0RvTG9hZEltYWdlKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgT3ZlcmxheUJsb2NrICpvYmxrICkKewogIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiAgQllURSpwc3Bfc3RhcnQsKmxvYWRfc3RhcnQsKm9sZGVudjsKICBpbnQgeCwgb2xkX2NvbT0wLCBhbGxvYzsKICBTRUdQVFIgcmVsb2M7CiAgV09SRCBlbnZfc2VnLCBsb2FkX3NlZywgcmVsX3NlZywgb2xkcHNwX3NlZzsKICBEV09SRCBsZW47CgogIGlmIChET1NWTV9wc3ApIHsKICAgIC8qIERPUyBwcm9jZXNzIGFscmVhZHkgcnVubmluZywgaW5oZXJpdCBmcm9tIGl0ICovCiAgICBQREIxNiogcGFyX3BzcCA9IChQREIxNiopKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICBhbGxvYz0wOwogICAgb2xkZW52ID0gKExQQllURSkoKERXT1JEKXBhcl9wc3AtPmVudmlyb25tZW50IDw8IDQpOwogICAgb2xkcHNwX3NlZyA9IERPU1ZNX3BzcDsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgbmV3IERPUyBwcm9jZXNzLCBpbmhlcml0aW5nIGZyb20gV2luZSBlbnZpcm9ubWVudCAqLwogICAgYWxsb2M9MTsKICAgIG9sZGVudiA9IEdldEVudmlyb25tZW50U3RyaW5nc0EoKTsKICAgIG9sZHBzcF9zZWcgPSAwOwogIH0KCiBTZXRGaWxlUG9pbnRlcihoRmlsZSwwLE5VTEwsRklMRV9CRUdJTik7CiBpZiAoICAgIVJlYWRGaWxlKGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlciksJmxlbixOVUxMKQogICAgIHx8IGxlbiAhPSBzaXplb2YobXpfaGVhZGVyKQogICAgIHx8IG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpIHsKICBjaGFyICpwID0gc3RycmNociggZmlsZW5hbWUsICcuJyApOwogIGlmICghcCB8fCBzdHJjYXNlY21wKCBwLCAiLmNvbSIgKSkgIC8qIGNoZWNrIGZvciAuQ09NIGV4dGVuc2lvbiAqLwogIHsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgfQogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgLyogRnJvbSBSYWxmIEJyb3duIEludGVycnVwdCBMaXN0OiBJZiB0aGUgd29yZCBhdCBvZmZzZXQgMDJoIGlzIDQsIGl0IHNob3VsZAogICAqIGJlIHRyZWF0ZWQgYXMgMDBoLCBzaW5jZSBwcmUtMS4xMCB2ZXJzaW9ucyBvZiB0aGUgTVMgbGlua2VyIHNldCBpdCB0aGF0CiAgICogd2F5LiAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiAgaWYgKGFsbG9jKSBNWl9Jbml0TWVtb3J5KCk7CgogIGlmIChvYmxrKSB7CiAgICAvKiBsb2FkIG92ZXJsYXkgaW50byBwcmVhbGxvY2F0ZWQgbWVtb3J5ICovCiAgICBsb2FkX3NlZz1vYmxrLT5sb2FkX3NlZzsKICAgIHJlbF9zZWc9b2Jsay0+cmVsX3NlZzsKICAgIGxvYWRfc3RhcnQ9KExQQllURSkoKERXT1JEKWxvYWRfc2VnPDw0KTsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgZW52aXJvbm1lbnQgYmxvY2sgKi8KICAgIGVudl9zZWc9TVpfSW5pdEVudmlyb25tZW50KG9sZGVudiwgZmlsZW5hbWUpOwoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KICAgIFRSQUNFKCJBbGxvY2F0aW5nIERPUyBtZW1vcnkgKG1pbj0lbGQsIG1heD0lbGQpXG4iLG1pbl9zaXplLG1heF9zaXplKTsKICAgIGF2YWlsPURPU01FTV9BdmFpbGFibGUoKTsKICAgIGlmIChhdmFpbDxtaW5fc2l6ZSkgewogICAgICBFUlIoImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKICAgIHBzcF9zdGFydD1ET1NNRU1fR2V0QmxvY2soYXZhaWwsJkRPU1ZNX3BzcCk7CiAgICBpZiAoIXBzcF9zdGFydCkgewogICAgICBFUlIoImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgIH0KICAgIGxvYWRfc2VnPURPU1ZNX3BzcCsob2xkX2NvbT8wOlBTUF9TSVpFKTsKICAgIHJlbF9zZWc9bG9hZF9zZWc7CiAgICBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogICAgTVpfQ3JlYXRlUFNQKHBzcF9zdGFydCwgZW52X3NlZywgb2xkcHNwX3NlZyk7CiAgfQoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UoImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDhseCBieXRlc1xuIixvbGRfY29tPyJDT00iOiJFWEUiLGltYWdlX3NpemUpOwogU2V0RmlsZVBvaW50ZXIoaEZpbGUsaW1hZ2Vfc3RhcnQsTlVMTCxGSUxFX0JFR0lOKTsKIGlmICghUmVhZEZpbGUoaEZpbGUsbG9hZF9zdGFydCxpbWFnZV9zaXplLCZsZW4sTlVMTCkgfHwgbGVuICE9IGltYWdlX3NpemUpIHsKICAvKiBjaGVjayBpZiB0aGlzIGlzIGR1ZSB0byB0aGUgd29ya2Fyb3VuZCBmb3IgdGhlIHByZS0xLjEwIE1TIGxpbmtlciBhbmQgd2UKICAgICByZWFseSBoYWQgb25seSA0IGJ5dGVzIG9uIHRoZSBsYXN0IHBhZ2UgKi8KICBpZiAobXpfaGVhZGVyLmVfY2JscCAhPSA0IHx8IGltYWdlX3NpemUgLSBsZW4gIT0gNTEyIC0gNCkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgZ290byBsb2FkX2Vycm9yOwogIH0KIH0KCiBpZiAobXpfaGVhZGVyLmVfY3JsYykgewogIC8qIGxvYWQgcmVsb2NhdGlvbiB0YWJsZSAqLwogIFRSQUNFKCJsb2FkaW5nIERPUyBFWEUgcmVsb2NhdGlvbiB0YWJsZSwgJWQgZW50cmllc1xuIixtel9oZWFkZXIuZV9jcmxjKTsKICAvKiBGSVhNRTogaXMgdGhpcyB0b28gc2xvdyB3aXRob3V0IHJlYWQgYnVmZmVyaW5nPyAqLwogIFNldEZpbGVQb2ludGVyKGhGaWxlLG16X2hlYWRlci5lX2xmYXJsYyxOVUxMLEZJTEVfQkVHSU4pOwogIGZvciAoeD0wOyB4PG16X2hlYWRlci5lX2NybGM7IHgrKykgewogICBpZiAoIVJlYWRGaWxlKGhGaWxlLCZyZWxvYyxzaXplb2YocmVsb2MpLCZsZW4sTlVMTCkgfHwgbGVuICE9IHNpemVvZihyZWxvYykpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgfQogICAqKFdPUkQqKVNFR1BUUjE2KGxvYWRfc3RhcnQscmVsb2MpKz1yZWxfc2VnOwogIH0KIH0KCiAgaWYgKCFvYmxrKSB7CiAgICBpbml0X2NzID0gbG9hZF9zZWcrbXpfaGVhZGVyLmVfY3M7CiAgICBpbml0X2lwID0gbXpfaGVhZGVyLmVfaXA7CiAgICBpbml0X3NzID0gbG9hZF9zZWcrbXpfaGVhZGVyLmVfc3M7CiAgICBpbml0X3NwID0gbXpfaGVhZGVyLmVfc3A7CgogICAgVFJBQ0UoImVudHJ5IHBvaW50OiAlMDR4OiUwNHhcbiIsaW5pdF9jcyxpbml0X2lwKTsKICB9CgogIGlmIChhbGxvYyAmJiAhTVpfSW5pdFRhc2soKSkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0dFTl9GQUlMVVJFKTsKICAgIHJldHVybiBGQUxTRTsKICB9CgogIHJldHVybiBUUlVFOwoKbG9hZF9lcnJvcjoKICBET1NWTV9wc3AgPSBvbGRwc3Bfc2VnOwoKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJd2luZV9sb2FkX2Rvc19leGUgKFdJTkVET1MuQCkKICoKICogQ2FsbGVkIGZyb20gV2luZVZETSB3aGVuIGEgbmV3IHJlYWwtbW9kZSBET1MgcHJvY2VzcyBpcyBzdGFydGVkLgogKiBMb2FkcyBET1MgcHJvZ3JhbSBpbnRvIG1lbW9yeSBhbmQgZXhlY3V0ZXMgdGhlIHByb2dyYW0uCiAqLwp2b2lkIFdJTkFQSSB3aW5lX2xvYWRfZG9zX2V4ZSggTFBDU1RSIGZpbGVuYW1lLCBMUENTVFIgY21kbGluZSApCnsKICAgIGNoYXIgZG9zX2NtZHRhaWxbMTI2XTsKICAgIGludCAgZG9zX2xlbmd0aCA9IDA7CgogICAgSEFORExFIGhGaWxlID0gQ3JlYXRlRmlsZUEoIGZpbGVuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCApOwogICAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm47CiAgICBET1NWTV9pc2Rvc2V4ZSA9IFRSVUU7CgogICAgaWYoY21kbGluZSAmJiAqY21kbGluZSkKICAgIHsKICAgICAgICBkb3NfbGVuZ3RoID0gc3RybGVuKGNtZGxpbmUpOwogICAgICAgIG1lbW1vdmUoIGRvc19jbWR0YWlsICsgMSwgY21kbGluZSwgCiAgICAgICAgICAgICAgICAgKGRvc19sZW5ndGggPCAxMjUpID8gZG9zX2xlbmd0aCA6IDEyNSApOwoKICAgICAgICAvKiBOb24tZW1wdHkgY29tbWFuZCB0YWlsIGFsd2F5cyBzdGFydHMgd2l0aCBhdCBsZWFzdCBvbmUgc3BhY2UuICovCiAgICAgICAgZG9zX2NtZHRhaWxbMF0gPSAnICc7CiAgICAgICAgZG9zX2xlbmd0aCsrOwoKICAgICAgICAvKgogICAgICAgICAqIElmIGNvbW1hbmQgdGFpbCBpcyBsb25nZXIgdGhhbiAxMjYgY2hhcmFjdGVycywKICAgICAgICAgKiBzZXQgdGFpbCBsZW5ndGggdG8gMTI3IGFuZCBmaWxsIENNRExJTkUgZW52aXJvbm1lbnQgdmFyaWFibGUgCiAgICAgICAgICogd2l0aCBmdWxsIGNvbW1hbmQgbGluZSAodGhpcyBpbmNsdWRlcyBmaWxlbmFtZSkuCiAgICAgICAgICovCiAgICAgICAgaWYgKGRvc19sZW5ndGggPiAxMjYpCiAgICAgICAgewogICAgICAgICAgICBjaGFyICpjbWQgPSBIZWFwQWxsb2MoIEdldFByb2Nlc3NIZWFwKCksIDAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvc19sZW5ndGggKyBzdHJsZW4oZmlsZW5hbWUpICsgNCApOwogICAgICAgICAgICBjaGFyICpwdHIgPSBjbWQ7CgogICAgICAgICAgICBpZiAoIWNtZCkKICAgICAgICAgICAgICAgIHJldHVybjsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEFwcGVuZCBmaWxlbmFtZS4gSWYgcGF0aCBpbmNsdWRlcyBzcGFjZXMsIHF1b3RlIHRoZSBwYXRoLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHN0cmNocihmaWxlbmFtZSwgJyAnKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgKnB0cisrID0gJ1wiJzsKICAgICAgICAgICAgICAgIHN0cmNweSggcHRyLCBmaWxlbmFtZSApOwogICAgICAgICAgICAgICAgcHRyICs9IHN0cmxlbihmaWxlbmFtZSk7ICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgKnB0cisrID0gJ1wiJzsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHN0cmNweSggcHRyLCBmaWxlbmFtZSApOwogICAgICAgICAgICAgICAgcHRyICs9IHN0cmxlbihmaWxlbmFtZSk7ICAKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogQXBwZW5kIGNvbW1hbmQgdGFpbC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChjbWRsaW5lWzBdICE9ICcgJykKICAgICAgICAgICAgICAgICpwdHIrKyA9ICcgJzsKICAgICAgICAgICAgc3RyY3B5KCBwdHIsIGNtZGxpbmUgKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNldCBlbnZpcm9ubWVudCB2YXJpYWJsZS4gVGhpcyB3aWxsIGJlIHBhc3NlZCB0bwogICAgICAgICAgICAgKiBuZXcgRE9TIHByb2Nlc3MuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoIVNldEVudmlyb25tZW50VmFyaWFibGVBKCAiQ01ETElORSIsIGNtZCApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBjbWQgKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY21kICk7CiAgICAgICAgICAgIGRvc19sZW5ndGggPSAxMjc7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBOVUxMICkpIAogICAgICAgIE1aX0xhdW5jaCggZG9zX2NtZHRhaWwsIGRvc19sZW5ndGggKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGVjCiAqCiAqIHRoaXMgbWF5IG9ubHkgYmUgY2FsbGVkIGZyb20gZXhpc3RpbmcgRE9TIHByb2Nlc3NlcwogKi8KQk9PTCBXSU5BUEkgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIERXT1JEIGJpblR5cGU7CiAgU1RBUlRVUElORk9BIHN0OwogIFBST0NFU1NfSU5GT1JNQVRJT04gcGU7CiAgSEFORExFIGhGaWxlOwoKICBCT09MIHJldCA9IEZBTFNFOwoKICBpZighR2V0QmluYXJ5VHlwZUEoZmlsZW5hbWUsICZiaW5UeXBlKSkgICAvKiBkZXRlcm1pbmUgd2hhdCBraW5kIG9mIGJpbmFyeSB0aGlzIGlzICovCiAgewogICAgcmV0dXJuIEZBTFNFOyAvKiBiaW5hcnkgaXMgbm90IGFuIGV4ZWN1dGFibGUgKi8KICB9CgogIC8qIGhhbmRsZSBub24tZG9zIGV4ZWN1dGFibGVzICovCiAgaWYoYmluVHlwZSAhPSBTQ1NfRE9TX0JJTkFSWSkKICB7CiAgICBpZihmdW5jID09IDApIC8qIGxvYWQgYW5kIGV4ZWN1dGUgKi8KICAgIHsKICAgICAgTFBCWVRFIGZ1bGxDbWRMaW5lOwogICAgICBXT1JEIGZ1bGxDbWRMZW5ndGg7CiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgICBFeGVjQmxvY2sgKmJsayA9IChFeGVjQmxvY2sgKilwYXJhbWJsazsKICAgICAgTFBCWVRFIGNtZGxpbmUgPSBQVFJfUkVBTF9UT19MSU4oU0VMRUNUT1JPRihibGstPmNtZGxpbmUpLE9GRlNFVE9GKGJsay0+Y21kbGluZSkpOwogICAgICBMUEJZVEUgZW52YmxvY2sgPSBQVFJfUkVBTF9UT19MSU4ocHNwLT5lbnZpcm9ubWVudCwgMCk7CiAgICAgIGludCAgICBjbWRMZW5ndGggPSBjbWRsaW5lWzBdOwoKICAgICAgLyoKICAgICAgICogSWYgY21kTGVuZ3RoIGlzIDEyNywgY29tbWFuZCB0YWlsIGlzIHRydW5jYXRlZCBhbmQgZW52aXJvbm1lbnQgCiAgICAgICAqIHZhcmlhYmxlIENNRExJTkUgc2hvdWxkIGNvbnRhaW4gZnVsbCBjb21tYW5kIGxpbmUgCiAgICAgICAqICh0aGlzIGluY2x1ZGVzIGZpbGVuYW1lKS4KICAgICAgICovCiAgICAgIGlmIChjbWRMZW5ndGggPT0gMTI3KQogICAgICB7CiAgICAgICAgICBGSVhNRSggIkNNRExJTkUgYXJndW1lbnQgcGFzc2luZyBpcyB1bmltcGxlbWVudGVkLlxuIiApOwogICAgICAgICAgY21kTGVuZ3RoID0gMTI2OyAvKiBGSVhNRSAqLwogICAgICB9CgogICAgICBmdWxsQ21kTGVuZ3RoID0gKHN0cmxlbihmaWxlbmFtZSkgKyAxKSArIGNtZExlbmd0aCArIDE7IC8qIGZpbGVuYW1lICsgc3BhY2UgKyBjbWRsaW5lICsgdGVybWluYXRpbmcgbnVsbCBjaGFyYWN0ZXIgKi8KCiAgICAgIGZ1bGxDbWRMaW5lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGZ1bGxDbWRMZW5ndGgpOwogICAgICBpZighZnVsbENtZExpbmUpIHJldHVybiBGQUxTRTsgLyogcmV0dXJuIGZhbHNlIG9uIG1lbW9yeSBhbGxvYyBmYWlsdXJlICovCgogICAgICAvKiBidWlsZCB0aGUgZnVsbCBjb21tYW5kIGxpbmUgZnJvbSB0aGUgZXhlY3V0YWJsZSBmaWxlIGFuZCB0aGUgY29tbWFuZCBsaW5lIGJlaW5nIHBhc3NlZCBpbiAqLwogICAgICBzbnByaW50ZihmdWxsQ21kTGluZSwgZnVsbENtZExlbmd0aCwgIiVzICIsIGZpbGVuYW1lKTsgLyogc3RhcnQgb2ZmIHdpdGggdGhlIGV4ZWN1dGFibGUgZmlsZW5hbWUgYW5kIGEgc3BhY2UgKi8KICAgICAgbWVtY3B5KGZ1bGxDbWRMaW5lICsgc3RybGVuKGZ1bGxDbWRMaW5lKSwgY21kbGluZSArIDEsIGNtZExlbmd0aCk7IC8qIGFwcGVuZCBjbWRsaW5lIG9udG8gdGhlIGVuZCAqLwogICAgICBmdWxsQ21kTGluZVtmdWxsQ21kTGVuZ3RoIC0gMV0gPSAwOyAvKiBudWxsIHRlcm1pbmF0ZSBzdHJpbmcgKi8KCiAgICAgIFplcm9NZW1vcnkgKCZzdCwgc2l6ZW9mKFNUQVJUVVBJTkZPQSkpOwogICAgICBzdC5jYiA9IHNpemVvZihTVEFSVFVQSU5GT0EpOwogICAgICByZXQgPSBDcmVhdGVQcm9jZXNzQSAoTlVMTCwgZnVsbENtZExpbmUsIE5VTEwsIE5VTEwsIFRSVUUsIDAsIGVudmJsb2NrLCBOVUxMLCAmc3QsICZwZSk7CgogICAgICAvKiB3YWl0IGZvciB0aGUgYXBwIHRvIGZpbmlzaCBhbmQgY2xlYW4gdXAgUFJPQ0VTU19JTkZPUk1BVElPTiBoYW5kbGVzICovCiAgICAgIGlmKHJldCkKICAgICAgewogICAgICAgIFdhaXRGb3JTaW5nbGVPYmplY3QocGUuaFByb2Nlc3MsIElORklOSVRFKTsgIC8qIHdhaXQgaGVyZSB1bnRpbCB0aGUgY2hpbGQgcHJvY2VzcyBpcyBjb21wbGV0ZSAqLwogICAgICAgIENsb3NlSGFuZGxlKHBlLmhQcm9jZXNzKTsKICAgICAgICBDbG9zZUhhbmRsZShwZS5oVGhyZWFkKTsKICAgICAgfQoKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZnVsbENtZExpbmUpOyAgLyogZnJlZSB0aGUgbWVtb3J5IHdlIGFsbG9jYXRlZCAqLwogICAgfQogICAgZWxzZQogICAgewogICAgICBGSVhNRSgiRVhFQyB0eXBlIG9mICVkIG5vdCBpbXBsZW1lbnRlZCBmb3Igbm9uLWRvcyBleGVjdXRhYmxlc1xuIiwgZnVuYyk7CiAgICAgIHJldCA9IEZBTFNFOwogICAgfQoKICAgIHJldHVybiByZXQ7CiAgfSAvKiBpZihiaW5UeXBlICE9IFNDU19ET1NfQklOQVJZKSAqLwoKCiAgLyogaGFuZGxlIGRvcyBleGVjdXRhYmxlcyAqLwoKICBoRmlsZSA9IENyZWF0ZUZpbGVBKCBmaWxlbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCgkJCSAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCk7CiAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm4gRkFMU0U7CgogIHN3aXRjaCAoZnVuYykgewogIGNhc2UgMDogLyogbG9hZCBhbmQgZXhlY3V0ZSAqLwogIGNhc2UgMTogLyogbG9hZCBidXQgZG9uJ3QgZXhlY3V0ZSAqLwogICAgewogICAgICAvKiBzYXZlIGN1cnJlbnQgcHJvY2VzcydzIHJldHVybiBTUzpTUCBub3cgKi8KICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIHBzcC0+c2F2ZVN0YWNrID0gKERXT1JEKU1BS0VTRUdQVFIoY29udGV4dC0+U2VnU3MsIExPV09SRChjb250ZXh0LT5Fc3ApKTsKICAgIH0KICAgIHJldCA9IE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIE5VTEwgKTsKICAgIGlmIChyZXQpIHsKICAgICAgLyogTVpfTG9hZEltYWdlIGNyZWF0ZWQgYSBuZXcgUFNQIGFuZCBsb2FkZWQgbmV3IHZhbHVlcyBpbnRvIGl0LAogICAgICAgKiBsZXQncyB3b3JrIG9uIHRoZSBuZXcgdmFsdWVzIG5vdyAqLwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKURPU1ZNX3BzcCA8PCA0KTsKICAgICAgRXhlY0Jsb2NrICpibGsgPSAoRXhlY0Jsb2NrICopcGFyYW1ibGs7CiAgICAgIExQQllURSBjbWRsaW5lID0gUFRSX1JFQUxfVE9fTElOKFNFTEVDVE9ST0YoYmxrLT5jbWRsaW5lKSxPRkZTRVRPRihibGstPmNtZGxpbmUpKTsKCiAgICAgIC8qIEZpcnN0IGNoYXJhY3RlciBjb250YWlucyB0aGUgbGVuZ3RoIG9mIHRoZSBjb21tYW5kIGxpbmUuICovCiAgICAgIE1aX0ZpbGxQU1AocHNwX3N0YXJ0LCBjbWRsaW5lICsgMSwgY21kbGluZVswXSk7CgogICAgICAvKiB0aGUgbGFtZSBNUy1ET1MgZW5naW5lZXJzIGRlY2lkZWQgdGhhdCB0aGUgcmV0dXJuIGFkZHJlc3Mgc2hvdWxkIGJlIGluIGludDIyICovCiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIyLCAoRkFSUFJPQzE2KU1BS0VTRUdQVFIoY29udGV4dC0+U2VnQ3MsIExPV09SRChjb250ZXh0LT5FaXApKSk7CiAgICAgIGlmIChmdW5jKSB7CgkvKiBkb24ndCBleGVjdXRlLCBqdXN0IHJldHVybiBzdGFydHVwIHN0YXRlICovCiAgICAgICAgLyoKICAgICAgICAgKiBGcm9tIFJhbHBoIEJyb3duOgogICAgICAgICAqICBGb3IgZnVuY3Rpb24gMDFoLCB0aGUgQVggdmFsdWUgdG8gYmUgcGFzc2VkIHRvIHRoZSBjaGlsZCBwcm9ncmFtIAogICAgICAgICAqICBpcyBwdXQgb24gdG9wIG9mIHRoZSBjaGlsZCdzIHN0YWNrCiAgICAgICAgICovCiAgICAgICAgTFBCWVRFIHN0YWNrOwogICAgICAgIGluaXRfc3AgLT0gMjsKICAgICAgICBzdGFjayA9IChMUEJZVEUpIENUWF9TRUdfT0ZGX1RPX0xJTihjb250ZXh0LCBpbml0X3NzLCBpbml0X3NwKTsKICAgICAgICAvKiBGSVhNRTogcHVzaCBBWCBjb3JyZWN0bHkgKi8KICAgICAgICBzdGFja1swXSA9IDB4MDA7ICAgIC8qIHB1c2ggQUwgKi8KICAgICAgICBzdGFja1sxXSA9IDB4MDA7ICAgIC8qIHB1c2ggQUggKi8KCQoJYmxrLT5pbml0X2NzID0gaW5pdF9jczsKCWJsay0+aW5pdF9pcCA9IGluaXRfaXA7CglibGstPmluaXRfc3MgPSBpbml0X3NzOwoJYmxrLT5pbml0X3NwID0gaW5pdF9zcDsKICAgICAgfSBlbHNlIHsKCS8qIGV4ZWN1dGUgYnkgbWFraW5nIHVzIHJldHVybiB0byBuZXcgcHJvY2VzcyAqLwoJY29udGV4dC0+U2VnQ3MgPSBpbml0X2NzOwoJY29udGV4dC0+RWlwICAgPSBpbml0X2lwOwoJY29udGV4dC0+U2VnU3MgPSBpbml0X3NzOwoJY29udGV4dC0+RXNwICAgPSBpbml0X3NwOwoJY29udGV4dC0+U2VnRHMgPSBET1NWTV9wc3A7Cgljb250ZXh0LT5TZWdFcyA9IERPU1ZNX3BzcDsKCWNvbnRleHQtPkVheCAgID0gMDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSAzOiAvKiBsb2FkIG92ZXJsYXkgKi8KICAgIHsKICAgICAgT3ZlcmxheUJsb2NrICpibGsgPSAoT3ZlcmxheUJsb2NrICopcGFyYW1ibGs7CiAgICAgIHJldCA9IE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIGJsayApOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIEZJWE1FKCJFWEVDIGxvYWQgdHlwZSAlZCBub3QgaW1wbGVtZW50ZWRcbiIsIGZ1bmMpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRlVOQ1RJT04pOwogICAgYnJlYWs7CiAgfQogIENsb3NlSGFuZGxlKGhGaWxlKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0FsbG9jRFBNSVRhc2sKICovCnZvaWQgV0lOQVBJIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgTVpfSW5pdE1lbW9yeSgpOwogIE1aX0luaXRUYXNrKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfUnVuSW5UaHJlYWQKICovCnZvaWQgV0lOQVBJIE1aX1J1bkluVGhyZWFkKCBQQVBDRlVOQyBwcm9jLCBVTE9OR19QVFIgYXJnICkKewogIGlmIChsb29wX3RocmVhZCkgewogICAgRE9TX1NQQyBzcGM7CiAgICBIQU5ETEUgZXZlbnQ7CgogICAgc3BjLnByb2MgPSBwcm9jOwogICAgc3BjLmFyZyA9IGFyZzsKICAgIGV2ZW50ID0gQ3JlYXRlRXZlbnRBKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgIFBvc3RUaHJlYWRNZXNzYWdlQShsb29wX3RpZCwgV01fVVNFUiwgKFdQQVJBTSlldmVudCwgKExQQVJBTSkmc3BjKTsKICAgIFdhaXRGb3JTaW5nbGVPYmplY3QoZXZlbnQsIElORklOSVRFKTsKICAgIENsb3NlSGFuZGxlKGV2ZW50KTsKICB9IGVsc2UKICAgIHByb2MoYXJnKTsKfQoKc3RhdGljIERXT1JEIFdJTkFQSSBNWl9ET1NWTSggTFBWT0lEIGxwRXh0cmEgKQp7CiAgQ09OVEVYVCBjb250ZXh0OwogIERXT1JEIHJldDsKCiAgZG9zdm1fcGlkID0gZ2V0cGlkKCk7CgogIG1lbXNldCggJmNvbnRleHQsIDAsIHNpemVvZihjb250ZXh0KSApOwogIGNvbnRleHQuU2VnQ3MgID0gaW5pdF9jczsKICBjb250ZXh0LkVpcCAgICA9IGluaXRfaXA7CiAgY29udGV4dC5TZWdTcyAgPSBpbml0X3NzOwogIGNvbnRleHQuRXNwICAgID0gaW5pdF9zcDsKICBjb250ZXh0LlNlZ0RzICA9IERPU1ZNX3BzcDsKICBjb250ZXh0LlNlZ0VzICA9IERPU1ZNX3BzcDsKICBjb250ZXh0LkVGbGFncyA9IFY4Nl9GTEFHIHwgVklGX01BU0s7CiAgRE9TVk1fU2V0VGltZXIoMHgxMDAwMCk7CiAgcmV0ID0gRE9TVk1fRW50ZXIoICZjb250ZXh0ICk7CgogIGRvc3ZtX3BpZCA9IDA7CiAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCkKewogIGlmICghRHVwbGljYXRlSGFuZGxlKEdldEN1cnJlbnRQcm9jZXNzKCksIEdldEN1cnJlbnRUaHJlYWQoKSwKICAgICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50UHJvY2VzcygpLCAmbG9vcF90aHJlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgMCwgRkFMU0UsIERVUExJQ0FURV9TQU1FX0FDQ0VTUykpCiAgICByZXR1cm4gRkFMU0U7CiAgZG9zdm1fdGhyZWFkID0gQ3JlYXRlVGhyZWFkKE5VTEwsIDAsIE1aX0RPU1ZNLCBOVUxMLCBDUkVBVEVfU1VTUEVOREVELCAmZG9zdm1fdGlkKTsKICBpZiAoIWRvc3ZtX3RocmVhZCkgewogICAgQ2xvc2VIYW5kbGUobG9vcF90aHJlYWQpOwogICAgbG9vcF90aHJlYWQgPSAwOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICBsb29wX3RpZCA9IEdldEN1cnJlbnRUaHJlYWRJZCgpOwogIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2goIExQQ1NUUiBjbWR0YWlsLCBpbnQgbGVuZ3RoICkKewogIFREQiAqcFRhc2sgPSBHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKICBCWVRFICpwc3Bfc3RhcnQgPSBQVFJfUkVBTF9UT19MSU4oIERPU1ZNX3BzcCwgMCApOwogIERXT1JEIHJ2OwogIFNZU0xFVkVMICpsb2NrOwoKICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgY21kdGFpbCwgbGVuZ3RoKTsKICBwVGFzay0+ZmxhZ3MgfD0gVERCRl9XSU5PTERBUDsKCiAgLyogRFRBIGlzIHNldCB0byBQU1A6MDA4MGggd2hlbiBhIHByb2dyYW0gaXMgc3RhcnRlZC4gKi8KICBwVGFzay0+ZHRhID0gTUFLRVNFR1BUUiggRE9TVk1fcHNwLCAweDgwICk7CgogIEdldHBXaW4xNkxvY2soICZsb2NrICk7CiAgX0xlYXZlU3lzTGV2ZWwoIGxvY2sgKTsKCiAgUmVzdW1lVGhyZWFkKGRvc3ZtX3RocmVhZCk7CiAgcnYgPSBET1NWTV9Mb29wKGRvc3ZtX3RocmVhZCk7CgogIENsb3NlSGFuZGxlKGRvc3ZtX3RocmVhZCk7CiAgZG9zdm1fdGhyZWFkID0gMDsgZG9zdm1fdGlkID0gMDsKICBDbG9zZUhhbmRsZShsb29wX3RocmVhZCk7CiAgbG9vcF90aHJlYWQgPSAwOyBsb29wX3RpZCA9IDA7CgogIFZHQV9DbGVhbigpOwogIEV4aXRQcm9jZXNzKHJ2KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGl0CiAqLwp2b2lkIFdJTkFQSSBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBpZiAoRE9TVk1fcHNwKSB7CiAgICBXT1JEIHBzcF9zZWcgPSBjc19wc3AgPyBjb250ZXh0LT5TZWdDcyA6IERPU1ZNX3BzcDsKICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcHNwX3NlZyA8PCA0KTsKICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICBXT1JEIHBhcnBzcCA9IHBzcC0+cGFyZW50UFNQOyAvKiBjaGVjayBmb3IgcGFyZW50IERPUyBwcm9jZXNzICovCiAgICBpZiAocGFycHNwKSB7CiAgICAgIC8qIHJldHJpZXZlIHBhcmVudCdzIHJldHVybiBhZGRyZXNzICovCiAgICAgIEZBUlBST0MxNiByZXRhZGRyID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjIpOwogICAgICAvKiByZXN0b3JlIGludGVycnVwdHMgKi8KICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjIsIHBzcC0+c2F2ZWRpbnQyMik7CiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIzLCBwc3AtPnNhdmVkaW50MjMpOwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyNCwgcHNwLT5zYXZlZGludDI0KTsKICAgICAgLyogRklYTUU6IGRlYWxsb2NhdGUgZmlsZSBoYW5kbGVzIGV0YyAqLwogICAgICAvKiBmcmVlIHByb2Nlc3MncyBhc3NvY2lhdGVkIG1lbW9yeQogICAgICAgKiBGSVhNRTogd2FsayBtZW1vcnkgYW5kIGRlYWxsb2NhdGUgYWxsIGJsb2NrcyBvd25lZCBieSBwcm9jZXNzICovCiAgICAgIERPU01FTV9GcmVlQmxvY2soIFBUUl9SRUFMX1RPX0xJTihwc3AtPmVudmlyb25tZW50LDApICk7CiAgICAgIERPU01FTV9GcmVlQmxvY2soIFBUUl9SRUFMX1RPX0xJTihET1NWTV9wc3AsMCkgKTsKICAgICAgLyogc3dpdGNoIHRvIHBhcmVudCdzIFBTUCAqLwogICAgICBET1NWTV9wc3AgPSBwYXJwc3A7CiAgICAgIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClwYXJwc3AgPDwgNCk7CiAgICAgIHBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgLyogbm93IHJldHVybiB0byBwYXJlbnQgKi8KICAgICAgRE9TVk1fcmV0dmFsID0gcmV0dmFsOwogICAgICBjb250ZXh0LT5TZWdDcyA9IFNFTEVDVE9ST0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPkVpcCAgID0gT0ZGU0VUT0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPlNlZ1NzID0gU0VMRUNUT1JPRihwc3AtPnNhdmVTdGFjayk7CiAgICAgIGNvbnRleHQtPkVzcCAgID0gT0ZGU0VUT0YocHNwLT5zYXZlU3RhY2spOwogICAgICByZXR1cm47CiAgICB9IGVsc2UKICAgICAgVFJBQ0UoImtpbGxpbmcgRE9TIHRhc2tcbiIpOwogIH0KICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQ3VycmVudAogKi8KQk9PTCBXSU5BUEkgTVpfQ3VycmVudCggdm9pZCApCnsKICByZXR1cm4gKGRvc3ZtX3BpZCAhPSAwKTsgLyogRklYTUU6IGRvIGEgYmV0dGVyIGNoZWNrICovCn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJd2luZV9sb2FkX2Rvc19leGUgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIHdpbmVfbG9hZF9kb3NfZXhlKCBMUENTVFIgZmlsZW5hbWUsIExQQ1NUUiBjbWRsaW5lICkKewogIFdBUk4oIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm1cbiIpOwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGVjCiAqLwpCT09MIFdJTkFQSSBNWl9FeGVjKCBDT05URVhUODYgKmNvbnRleHQsIExQQ1NUUiBmaWxlbmFtZSwgQllURSBmdW5jLCBMUFZPSUQgcGFyYW1ibGsgKQp7CiAgLyogY2FuJ3QgaGFwcGVuICovCiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9BbGxvY0RQTUlUYXNrCiAqLwp2b2lkIFdJTkFQSSBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogICAgRVJSKCJBY3R1YWwgcmVhbC1tb2RlIGNhbGxzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybSFcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX1J1bkluVGhyZWFkCiAqLwp2b2lkIFdJTkFQSSBNWl9SdW5JblRocmVhZCggUEFQQ0ZVTkMgcHJvYywgVUxPTkdfUFRSIGFyZyApCnsKICAgIHByb2MoYXJnKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGl0CiAqLwp2b2lkIFdJTkFQSSBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9DdXJyZW50CiAqLwpCT09MIFdJTkFQSSBNWl9DdXJyZW50KCB2b2lkICkKewogICAgcmV0dXJuIEZBTFNFOwp9CgojZW5kaWYgLyogIU1aX1NVUFBPUlRFRCAqLwo=