LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICogTm90ZTogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2lmZGVmIEhBVkVfVU5JU1REX0gKIyBpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpZmRlZiBIQVZFX1NZU19USU1FX0gKIyBpbmNsdWRlIDxzeXMvdGltZS5oPgojZW5kaWYKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAiZG9zdm0uaCIKI2luY2x1ZGUgInZnYS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwobW9kdWxlKTsKCnN0YXRpYyBCT09MIERPU1ZNX2lzZG9zZXhlOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgRE9TVk1fSXNXaW4xNgogKiAKICogUmV0dXJuIFRSVUUgaWYgd2UgYXJlIGluIFdpbmRvd3MgcHJvY2Vzcy4KICovCkJPT0wgRE9TVk1fSXNXaW4xNih2b2lkKQp7CiAgcmV0dXJuIERPU1ZNX2lzZG9zZXhlID8gRkFMU0UgOiBUUlVFOwp9CgojaWZkZWYgTVpfU1VQUE9SVEVECgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBQU1BfU0laRSAweDEwCgojZGVmaW5lIFNFRzE2KHB0cixzZWcpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpKHNlZyk8PDQpKSkKI2RlZmluZSBTRUdQVFIxNihwdHIsc2VncHRyKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKVNFTEVDVE9ST0Yoc2VncHRyKTw8NCkrT0ZGU0VUT0Yoc2VncHRyKSkpCgovKiBzdHJ1Y3R1cmVzIGZvciBFWEVDICovCgojaW5jbHVkZSAicHNocGFjazEuaCIKCnR5cGVkZWYgc3RydWN0IHsKICBXT1JEIGVudl9zZWc7CiAgRFdPUkQgY21kbGluZTsKICBEV09SRCBmY2IxOwogIERXT1JEIGZjYjI7CiAgV09SRCBpbml0X3NwOwogIFdPUkQgaW5pdF9zczsKICBXT1JEIGluaXRfaXA7CiAgV09SRCBpbml0X2NzOwp9IEV4ZWNCbG9jazsKCnR5cGVkZWYgc3RydWN0IHsKICBXT1JEIGxvYWRfc2VnOwogIFdPUkQgcmVsX3NlZzsKfSBPdmVybGF5QmxvY2s7CgojaW5jbHVkZSAicG9wcGFjay5oIgoKLyogZ2xvYmFsIHZhcmlhYmxlcyAqLwoKcGlkX3QgZG9zdm1fcGlkOwoKc3RhdGljIFdPUkQgaW5pdF9jcyxpbml0X2lwLGluaXRfc3MsaW5pdF9zcDsKc3RhdGljIEhBTkRMRSBkb3N2bV90aHJlYWQsIGxvb3BfdGhyZWFkOwpzdGF0aWMgRFdPUkQgZG9zdm1fdGlkLCBsb29wX3RpZDsKCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCggTFBDU1RSIGNtZHRhaWwsIGludCBsZW5ndGggKTsKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCk7CgpzdGF0aWMgdm9pZCBNWl9DcmVhdGVQU1AoIExQVk9JRCBscFBTUCwgV09SRCBlbnYsIFdPUkQgcGFyICkKewogIFBEQjE2KnBzcD1scFBTUDsKCiAgcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogIC8qIHNvbWUgcHJvZ3JhbXMgdXNlIHRoaXMgdG8gY2FsY3VsYXRlIGhvdyBtdWNoIG1lbW9yeSB0aGV5IG5lZWQgKi8KICBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOyAvKiBGSVhNRTogdXNlIGEgcmVhbCB2YWx1ZSAqLwogIC8qIEZJWE1FOiBkaXNwYXRjaGVyICovCiAgcHNwLT5zYXZlZGludDIyID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjIpOwogIHBzcC0+c2F2ZWRpbnQyMyA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIzKTsKICBwc3AtPnNhdmVkaW50MjQgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyNCk7CiAgcHNwLT5wYXJlbnRQU1A9cGFyOwogIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgpzdGF0aWMgdm9pZCBNWl9GaWxsUFNQKCBMUFZPSUQgbHBQU1AsIExQQ1NUUiBjbWR0YWlsLCBpbnQgbGVuZ3RoICkKewogICAgUERCMTYgKnBzcCA9IGxwUFNQOwoKICAgIGlmKGxlbmd0aCA+IDEyNykgCiAgICB7CiAgICAgICAgV0FSTiggIkNvbW1hbmQgdGFpbCB0cnVuY2F0ZWQhIChsZW5ndGggJWQpXG4iLCBsZW5ndGggKTsKICAgICAgICBsZW5ndGggPSAxMjY7CiAgICB9CgogICAgcHNwLT5jbWRMaW5lWzBdID0gbGVuZ3RoOwoKICAgIC8qCiAgICAgKiBMZW5ndGggb2YgZXhhY3RseSAxMjcgYnl0ZXMgbWVhbnMgdGhhdCBmdWxsIGNvbW1hbmQgbGluZSBpcyAKICAgICAqIHN0b3JlZCBpbiBlbnZpcm9ubWVudCB2YXJpYWJsZSBDTURMSU5FIGFuZCBQU1AgY29udGFpbnMgCiAgICAgKiBjb21tYW5kIHRhaWwgdHJ1bmNhdGVkIHRvIDEyNiBieXRlcy4KICAgICAqLwogICAgaWYobGVuZ3RoID09IDEyNykKICAgICAgICBsZW5ndGggPSAxMjY7CgogICAgaWYobGVuZ3RoID4gMCkKICAgICAgICBtZW1tb3ZlKHBzcC0+Y21kTGluZSsxLCBjbWR0YWlsLCBsZW5ndGgpOwoKICAgIHBzcC0+Y21kTGluZVtsZW5ndGgrMV0gPSAnXHInOwoKICAgIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgpzdGF0aWMgV09SRCBNWl9Jbml0RW52aXJvbm1lbnQoIExQQ1NUUiBlbnYsIExQQ1NUUiBuYW1lICkKewogdW5zaWduZWQgc3o9MDsKIHVuc2lnbmVkIGk9MDsKIFdPUkQgc2VnOwogTFBTVFIgZW52YmxrOwoKIGlmIChlbnYpIHsKICAvKiBnZXQgc2l6ZSBvZiBlbnZpcm9ubWVudCBibG9jayAqLwogIHdoaWxlIChlbnZbc3orK10pIHN6Kz1zdHJsZW4oZW52K3N6KSsxOwogfSBlbHNlIHN6Kys7CiAvKiBhbGxvY2F0ZSBpdCAqLwogZW52YmxrPURPU01FTV9HZXRCbG9jayhzeitzaXplb2YoV09SRCkrc3RybGVuKG5hbWUpKzEsJnNlZyk7CiAvKiBmaWxsIGl0ICovCiBpZiAoZW52KSB7CiAgbWVtY3B5KGVudmJsayxlbnYsc3opOwogfSBlbHNlIGVudmJsa1swXT0wOwogLyogRE9TIGVudmlyb25tZW50IHZhcmlhYmxlcyBhcmUgdXBwZXJjYXNlICovCiB3aGlsZSAoZW52YmxrW2ldKXsKICB3aGlsZSAoZW52YmxrW2ldICE9ICc9Jyl7CiAgIGlmIChlbnZibGtbaV0+PSdhJyAmJiBlbnZibGtbaV0gPD0gJ3onKXsKICAgIGVudmJsa1tpXSAtPSAzMjsKICAgfQogICBpKys7CiAgfQogIGkgKz0gc3RybGVuKGVudmJsaytpKSArIDE7CiB9CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSh2b2lkKQp7CiAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKICAgIERPU01FTV9Jbml0KFRSVUUpOwogICAgRE9TREVWX0luc3RhbGxET1NEZXZpY2VzKCk7CgogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MIE1aX0RvTG9hZEltYWdlKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgT3ZlcmxheUJsb2NrICpvYmxrICkKewogIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiAgQllURSpwc3Bfc3RhcnQsKmxvYWRfc3RhcnQsKm9sZGVudjsKICBpbnQgeCwgb2xkX2NvbT0wLCBhbGxvYzsKICBTRUdQVFIgcmVsb2M7CiAgV09SRCBlbnZfc2VnLCBsb2FkX3NlZywgcmVsX3NlZywgb2xkcHNwX3NlZzsKICBEV09SRCBsZW47CgogIGlmIChET1NWTV9wc3ApIHsKICAgIC8qIERPUyBwcm9jZXNzIGFscmVhZHkgcnVubmluZywgaW5oZXJpdCBmcm9tIGl0ICovCiAgICBQREIxNiogcGFyX3BzcCA9IChQREIxNiopKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICBhbGxvYz0wOwogICAgb2xkZW52ID0gKExQQllURSkoKERXT1JEKXBhcl9wc3AtPmVudmlyb25tZW50IDw8IDQpOwogICAgb2xkcHNwX3NlZyA9IERPU1ZNX3BzcDsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgbmV3IERPUyBwcm9jZXNzLCBpbmhlcml0aW5nIGZyb20gV2luZSBlbnZpcm9ubWVudCAqLwogICAgYWxsb2M9MTsKICAgIG9sZGVudiA9IEdldEVudmlyb25tZW50U3RyaW5nc0EoKTsKICAgIG9sZHBzcF9zZWcgPSAwOwogIH0KCiBTZXRGaWxlUG9pbnRlcihoRmlsZSwwLE5VTEwsRklMRV9CRUdJTik7CiBpZiAoICAgIVJlYWRGaWxlKGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlciksJmxlbixOVUxMKQogICAgIHx8IGxlbiAhPSBzaXplb2YobXpfaGVhZGVyKQogICAgIHx8IG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpIHsKICBjaGFyICpwID0gc3RycmNociggZmlsZW5hbWUsICcuJyApOwogIGlmICghcCB8fCBzdHJjYXNlY21wKCBwLCAiLmNvbSIgKSkgIC8qIGNoZWNrIGZvciAuQ09NIGV4dGVuc2lvbiAqLwogIHsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgfQogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgLyogRnJvbSBSYWxmIEJyb3duIEludGVycnVwdCBMaXN0OiBJZiB0aGUgd29yZCBhdCBvZmZzZXQgMDJoIGlzIDQsIGl0IHNob3VsZAogICAqIGJlIHRyZWF0ZWQgYXMgMDBoLCBzaW5jZSBwcmUtMS4xMCB2ZXJzaW9ucyBvZiB0aGUgTVMgbGlua2VyIHNldCBpdCB0aGF0CiAgICogd2F5LiAqLwogIGlmICgobXpfaGVhZGVyLmVfY2JscCE9MCkmJihtel9oZWFkZXIuZV9jYmxwIT00KSkgaW1hZ2Vfc2l6ZS09NTEyLW16X2hlYWRlci5lX2NibHA7CiAgaW1hZ2Vfc2l6ZS09aW1hZ2Vfc3RhcnQ7CiAgbWluX3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21pbmFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogIG1heF9zaXplPWltYWdlX3NpemUrKChEV09SRCltel9oZWFkZXIuZV9tYXhhbGxvYzw8NCkrKFBTUF9TSVpFPDw0KTsKIH0KCiAgaWYgKGFsbG9jKSBNWl9Jbml0TWVtb3J5KCk7CgogIGlmIChvYmxrKSB7CiAgICAvKiBsb2FkIG92ZXJsYXkgaW50byBwcmVhbGxvY2F0ZWQgbWVtb3J5ICovCiAgICBsb2FkX3NlZz1vYmxrLT5sb2FkX3NlZzsKICAgIHJlbF9zZWc9b2Jsay0+cmVsX3NlZzsKICAgIGxvYWRfc3RhcnQ9KExQQllURSkoKERXT1JEKWxvYWRfc2VnPDw0KTsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgZW52aXJvbm1lbnQgYmxvY2sgKi8KICAgIGVudl9zZWc9TVpfSW5pdEVudmlyb25tZW50KG9sZGVudiwgZmlsZW5hbWUpOwoKICAgIC8qIGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGV4ZWN1dGFibGUgKi8KICAgIFRSQUNFKCJBbGxvY2F0aW5nIERPUyBtZW1vcnkgKG1pbj0lbGQsIG1heD0lbGQpXG4iLG1pbl9zaXplLG1heF9zaXplKTsKICAgIGF2YWlsPURPU01FTV9BdmFpbGFibGUoKTsKICAgIGlmIChhdmFpbDxtaW5fc2l6ZSkgewogICAgICBFUlIoImluc3VmZmljaWVudCBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgaWYgKGF2YWlsPm1heF9zaXplKSBhdmFpbD1tYXhfc2l6ZTsKICAgIHBzcF9zdGFydD1ET1NNRU1fR2V0QmxvY2soYXZhaWwsJkRPU1ZNX3BzcCk7CiAgICBpZiAoIXBzcF9zdGFydCkgewogICAgICBFUlIoImVycm9yIGFsbG9jYXRpbmcgRE9TIG1lbW9yeVxuIik7CiAgICAgIFNldExhc3RFcnJvcihFUlJPUl9OT1RfRU5PVUdIX01FTU9SWSk7CiAgICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgIH0KICAgIGxvYWRfc2VnPURPU1ZNX3BzcCsob2xkX2NvbT8wOlBTUF9TSVpFKTsKICAgIHJlbF9zZWc9bG9hZF9zZWc7CiAgICBsb2FkX3N0YXJ0PXBzcF9zdGFydCsoUFNQX1NJWkU8PDQpOwogICAgTVpfQ3JlYXRlUFNQKHBzcF9zdGFydCwgZW52X3NlZywgb2xkcHNwX3NlZyk7CiAgfQoKIC8qIGxvYWQgZXhlY3V0YWJsZSBpbWFnZSAqLwogVFJBQ0UoImxvYWRpbmcgRE9TICVzIGltYWdlLCAlMDhseCBieXRlc1xuIixvbGRfY29tPyJDT00iOiJFWEUiLGltYWdlX3NpemUpOwogU2V0RmlsZVBvaW50ZXIoaEZpbGUsaW1hZ2Vfc3RhcnQsTlVMTCxGSUxFX0JFR0lOKTsKIGlmICghUmVhZEZpbGUoaEZpbGUsbG9hZF9zdGFydCxpbWFnZV9zaXplLCZsZW4sTlVMTCkgfHwgbGVuICE9IGltYWdlX3NpemUpIHsKICAvKiBjaGVjayBpZiB0aGlzIGlzIGR1ZSB0byB0aGUgd29ya2Fyb3VuZCBmb3IgdGhlIHByZS0xLjEwIE1TIGxpbmtlciBhbmQgd2UKICAgICByZWFseSBoYWQgb25seSA0IGJ5dGVzIG9uIHRoZSBsYXN0IHBhZ2UgKi8KICBpZiAobXpfaGVhZGVyLmVfY2JscCAhPSA0IHx8IGltYWdlX3NpemUgLSBsZW4gIT0gNTEyIC0gNCkgewogICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgZ290byBsb2FkX2Vycm9yOwogIH0KIH0KCiBpZiAobXpfaGVhZGVyLmVfY3JsYykgewogIC8qIGxvYWQgcmVsb2NhdGlvbiB0YWJsZSAqLwogIFRSQUNFKCJsb2FkaW5nIERPUyBFWEUgcmVsb2NhdGlvbiB0YWJsZSwgJWQgZW50cmllc1xuIixtel9oZWFkZXIuZV9jcmxjKTsKICAvKiBGSVhNRTogaXMgdGhpcyB0b28gc2xvdyB3aXRob3V0IHJlYWQgYnVmZmVyaW5nPyAqLwogIFNldEZpbGVQb2ludGVyKGhGaWxlLG16X2hlYWRlci5lX2xmYXJsYyxOVUxMLEZJTEVfQkVHSU4pOwogIGZvciAoeD0wOyB4PG16X2hlYWRlci5lX2NybGM7IHgrKykgewogICBpZiAoIVJlYWRGaWxlKGhGaWxlLCZyZWxvYyxzaXplb2YocmVsb2MpLCZsZW4sTlVMTCkgfHwgbGVuICE9IHNpemVvZihyZWxvYykpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICAgIGdvdG8gbG9hZF9lcnJvcjsKICAgfQogICAqKFdPUkQqKVNFR1BUUjE2KGxvYWRfc3RhcnQscmVsb2MpKz1yZWxfc2VnOwogIH0KIH0KCiAgaWYgKCFvYmxrKSB7CiAgICBpbml0X2NzID0gbG9hZF9zZWcrbXpfaGVhZGVyLmVfY3M7CiAgICBpbml0X2lwID0gbXpfaGVhZGVyLmVfaXA7CiAgICBpbml0X3NzID0gbG9hZF9zZWcrbXpfaGVhZGVyLmVfc3M7CiAgICBpbml0X3NwID0gbXpfaGVhZGVyLmVfc3A7CiAgICBpZiAob2xkX2NvbSl7CiAgICAgIC8qIC5DT00gZmlsZXMgZXhpdCB3aXRoIHJldC4gTWFrZSBzdXJlIHRoZXkganVtcCB0byBwc3Agc3RhcnQgKD1pbnQgMjApICovCiAgICAgIFdPUkQqIHN0YWNrID0gUFRSX1JFQUxfVE9fTElOKGluaXRfc3MsIGluaXRfc3ApOwogICAgICAqc3RhY2sgPSAwOwogICAgfQoKICAgIFRSQUNFKCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGluaXRfY3MsaW5pdF9pcCk7CiAgfQoKICBpZiAoYWxsb2MgJiYgIU1aX0luaXRUYXNrKCkpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9HRU5fRkFJTFVSRSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICByZXR1cm4gVFJVRTsKCmxvYWRfZXJyb3I6CiAgRE9TVk1fcHNwID0gb2xkcHNwX3NlZzsKCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXdpbmVfbG9hZF9kb3NfZXhlIChXSU5FRE9TLkApCiAqCiAqIENhbGxlZCBmcm9tIFdpbmVWRE0gd2hlbiBhIG5ldyByZWFsLW1vZGUgRE9TIHByb2Nlc3MgaXMgc3RhcnRlZC4KICogTG9hZHMgRE9TIHByb2dyYW0gaW50byBtZW1vcnkgYW5kIGV4ZWN1dGVzIHRoZSBwcm9ncmFtLgogKi8Kdm9pZCBXSU5BUEkgd2luZV9sb2FkX2Rvc19leGUoIExQQ1NUUiBmaWxlbmFtZSwgTFBDU1RSIGNtZGxpbmUgKQp7CiAgICBjaGFyIGRvc19jbWR0YWlsWzEyNl07CiAgICBpbnQgIGRvc19sZW5ndGggPSAwOwoKICAgIEhBTkRMRSBoRmlsZSA9IENyZWF0ZUZpbGVBKCBmaWxlbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDAgKTsKICAgIGlmIChoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgcmV0dXJuOwogICAgRE9TVk1faXNkb3NleGUgPSBUUlVFOwoKICAgIGlmKGNtZGxpbmUgJiYgKmNtZGxpbmUpCiAgICB7CiAgICAgICAgZG9zX2xlbmd0aCA9IHN0cmxlbihjbWRsaW5lKTsKICAgICAgICBtZW1tb3ZlKCBkb3NfY21kdGFpbCArIDEsIGNtZGxpbmUsIAogICAgICAgICAgICAgICAgIChkb3NfbGVuZ3RoIDwgMTI1KSA/IGRvc19sZW5ndGggOiAxMjUgKTsKCiAgICAgICAgLyogTm9uLWVtcHR5IGNvbW1hbmQgdGFpbCBhbHdheXMgc3RhcnRzIHdpdGggYXQgbGVhc3Qgb25lIHNwYWNlLiAqLwogICAgICAgIGRvc19jbWR0YWlsWzBdID0gJyAnOwogICAgICAgIGRvc19sZW5ndGgrKzsKCiAgICAgICAgLyoKICAgICAgICAgKiBJZiBjb21tYW5kIHRhaWwgaXMgbG9uZ2VyIHRoYW4gMTI2IGNoYXJhY3RlcnMsCiAgICAgICAgICogc2V0IHRhaWwgbGVuZ3RoIHRvIDEyNyBhbmQgZmlsbCBDTURMSU5FIGVudmlyb25tZW50IHZhcmlhYmxlIAogICAgICAgICAqIHdpdGggZnVsbCBjb21tYW5kIGxpbmUgKHRoaXMgaW5jbHVkZXMgZmlsZW5hbWUpLgogICAgICAgICAqLwogICAgICAgIGlmIChkb3NfbGVuZ3RoID4gMTI2KQogICAgICAgIHsKICAgICAgICAgICAgY2hhciAqY21kID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb3NfbGVuZ3RoICsgc3RybGVuKGZpbGVuYW1lKSArIDQgKTsKICAgICAgICAgICAgY2hhciAqcHRyID0gY21kOwoKICAgICAgICAgICAgaWYgKCFjbWQpCiAgICAgICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBBcHBlbmQgZmlsZW5hbWUuIElmIHBhdGggaW5jbHVkZXMgc3BhY2VzLCBxdW90ZSB0aGUgcGF0aC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChzdHJjaHIoZmlsZW5hbWUsICcgJykpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICpwdHIrKyA9ICdcIic7CiAgICAgICAgICAgICAgICBzdHJjcHkoIHB0ciwgZmlsZW5hbWUgKTsKICAgICAgICAgICAgICAgIHB0ciArPSBzdHJsZW4oZmlsZW5hbWUpOyAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICpwdHIrKyA9ICdcIic7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdHJjcHkoIHB0ciwgZmlsZW5hbWUgKTsKICAgICAgICAgICAgICAgIHB0ciArPSBzdHJsZW4oZmlsZW5hbWUpOyAgCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEFwcGVuZCBjb21tYW5kIHRhaWwuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoY21kbGluZVswXSAhPSAnICcpCiAgICAgICAgICAgICAgICAqcHRyKysgPSAnICc7CiAgICAgICAgICAgIHN0cmNweSggcHRyLCBjbWRsaW5lICk7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTZXQgZW52aXJvbm1lbnQgdmFyaWFibGUuIFRoaXMgd2lsbCBiZSBwYXNzZWQgdG8KICAgICAgICAgICAgICogbmV3IERPUyBwcm9jZXNzLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKCFTZXRFbnZpcm9ubWVudFZhcmlhYmxlQSggIkNNRExJTkUiLCBjbWQgKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY21kICk7CiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGNtZCApOwogICAgICAgICAgICBkb3NfbGVuZ3RoID0gMTI3OwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoTVpfRG9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgTlVMTCApKSAKICAgICAgICBNWl9MYXVuY2goIGRvc19jbWR0YWlsLCBkb3NfbGVuZ3RoICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhlYwogKgogKiB0aGlzIG1heSBvbmx5IGJlIGNhbGxlZCBmcm9tIGV4aXN0aW5nIERPUyBwcm9jZXNzZXMKICovCkJPT0wgV0lOQVBJIE1aX0V4ZWMoIENPTlRFWFQ4NiAqY29udGV4dCwgTFBDU1RSIGZpbGVuYW1lLCBCWVRFIGZ1bmMsIExQVk9JRCBwYXJhbWJsayApCnsKICBEV09SRCBiaW5UeXBlOwogIFNUQVJUVVBJTkZPQSBzdDsKICBQUk9DRVNTX0lORk9STUFUSU9OIHBlOwogIEhBTkRMRSBoRmlsZTsKCiAgQk9PTCByZXQgPSBGQUxTRTsKCiAgaWYoIUdldEJpbmFyeVR5cGVBKGZpbGVuYW1lLCAmYmluVHlwZSkpICAgLyogZGV0ZXJtaW5lIHdoYXQga2luZCBvZiBiaW5hcnkgdGhpcyBpcyAqLwogIHsKICAgIHJldHVybiBGQUxTRTsgLyogYmluYXJ5IGlzIG5vdCBhbiBleGVjdXRhYmxlICovCiAgfQoKICAvKiBoYW5kbGUgbm9uLWRvcyBleGVjdXRhYmxlcyAqLwogIGlmKGJpblR5cGUgIT0gU0NTX0RPU19CSU5BUlkpCiAgewogICAgaWYoZnVuYyA9PSAwKSAvKiBsb2FkIGFuZCBleGVjdXRlICovCiAgICB7CiAgICAgIExQQllURSBmdWxsQ21kTGluZTsKICAgICAgV09SRCBmdWxsQ21kTGVuZ3RoOwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKURPU1ZNX3BzcCA8PCA0KTsKICAgICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgRXhlY0Jsb2NrICpibGsgPSAoRXhlY0Jsb2NrICopcGFyYW1ibGs7CiAgICAgIExQQllURSBjbWRsaW5lID0gUFRSX1JFQUxfVE9fTElOKFNFTEVDVE9ST0YoYmxrLT5jbWRsaW5lKSxPRkZTRVRPRihibGstPmNtZGxpbmUpKTsKICAgICAgTFBCWVRFIGVudmJsb2NrID0gUFRSX1JFQUxfVE9fTElOKHBzcC0+ZW52aXJvbm1lbnQsIDApOwogICAgICBpbnQgICAgY21kTGVuZ3RoID0gY21kbGluZVswXTsKCiAgICAgIC8qCiAgICAgICAqIElmIGNtZExlbmd0aCBpcyAxMjcsIGNvbW1hbmQgdGFpbCBpcyB0cnVuY2F0ZWQgYW5kIGVudmlyb25tZW50IAogICAgICAgKiB2YXJpYWJsZSBDTURMSU5FIHNob3VsZCBjb250YWluIGZ1bGwgY29tbWFuZCBsaW5lIAogICAgICAgKiAodGhpcyBpbmNsdWRlcyBmaWxlbmFtZSkuCiAgICAgICAqLwogICAgICBpZiAoY21kTGVuZ3RoID09IDEyNykKICAgICAgewogICAgICAgICAgRklYTUUoICJDTURMSU5FIGFyZ3VtZW50IHBhc3NpbmcgaXMgdW5pbXBsZW1lbnRlZC5cbiIgKTsKICAgICAgICAgIGNtZExlbmd0aCA9IDEyNjsgLyogRklYTUUgKi8KICAgICAgfQoKICAgICAgZnVsbENtZExlbmd0aCA9IChzdHJsZW4oZmlsZW5hbWUpICsgMSkgKyBjbWRMZW5ndGggKyAxOyAvKiBmaWxlbmFtZSArIHNwYWNlICsgY21kbGluZSArIHRlcm1pbmF0aW5nIG51bGwgY2hhcmFjdGVyICovCgogICAgICBmdWxsQ21kTGluZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBmdWxsQ21kTGVuZ3RoKTsKICAgICAgaWYoIWZ1bGxDbWRMaW5lKSByZXR1cm4gRkFMU0U7IC8qIHJldHVybiBmYWxzZSBvbiBtZW1vcnkgYWxsb2MgZmFpbHVyZSAqLwoKICAgICAgLyogYnVpbGQgdGhlIGZ1bGwgY29tbWFuZCBsaW5lIGZyb20gdGhlIGV4ZWN1dGFibGUgZmlsZSBhbmQgdGhlIGNvbW1hbmQgbGluZSBiZWluZyBwYXNzZWQgaW4gKi8KICAgICAgc25wcmludGYoZnVsbENtZExpbmUsIGZ1bGxDbWRMZW5ndGgsICIlcyAiLCBmaWxlbmFtZSk7IC8qIHN0YXJ0IG9mZiB3aXRoIHRoZSBleGVjdXRhYmxlIGZpbGVuYW1lIGFuZCBhIHNwYWNlICovCiAgICAgIG1lbWNweShmdWxsQ21kTGluZSArIHN0cmxlbihmdWxsQ21kTGluZSksIGNtZGxpbmUgKyAxLCBjbWRMZW5ndGgpOyAvKiBhcHBlbmQgY21kbGluZSBvbnRvIHRoZSBlbmQgKi8KICAgICAgZnVsbENtZExpbmVbZnVsbENtZExlbmd0aCAtIDFdID0gMDsgLyogbnVsbCB0ZXJtaW5hdGUgc3RyaW5nICovCgogICAgICBaZXJvTWVtb3J5ICgmc3QsIHNpemVvZihTVEFSVFVQSU5GT0EpKTsKICAgICAgc3QuY2IgPSBzaXplb2YoU1RBUlRVUElORk9BKTsKICAgICAgcmV0ID0gQ3JlYXRlUHJvY2Vzc0EgKE5VTEwsIGZ1bGxDbWRMaW5lLCBOVUxMLCBOVUxMLCBUUlVFLCAwLCBlbnZibG9jaywgTlVMTCwgJnN0LCAmcGUpOwoKICAgICAgLyogd2FpdCBmb3IgdGhlIGFwcCB0byBmaW5pc2ggYW5kIGNsZWFuIHVwIFBST0NFU1NfSU5GT1JNQVRJT04gaGFuZGxlcyAqLwogICAgICBpZihyZXQpCiAgICAgIHsKICAgICAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KHBlLmhQcm9jZXNzLCBJTkZJTklURSk7ICAvKiB3YWl0IGhlcmUgdW50aWwgdGhlIGNoaWxkIHByb2Nlc3MgaXMgY29tcGxldGUgKi8KICAgICAgICBDbG9zZUhhbmRsZShwZS5oUHJvY2Vzcyk7CiAgICAgICAgQ2xvc2VIYW5kbGUocGUuaFRocmVhZCk7CiAgICAgIH0KCiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGZ1bGxDbWRMaW5lKTsgIC8qIGZyZWUgdGhlIG1lbW9yeSB3ZSBhbGxvY2F0ZWQgKi8KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgRklYTUUoIkVYRUMgdHlwZSBvZiAlZCBub3QgaW1wbGVtZW50ZWQgZm9yIG5vbi1kb3MgZXhlY3V0YWJsZXNcbiIsIGZ1bmMpOwogICAgICByZXQgPSBGQUxTRTsKICAgIH0KCiAgICByZXR1cm4gcmV0OwogIH0gLyogaWYoYmluVHlwZSAhPSBTQ1NfRE9TX0JJTkFSWSkgKi8KCgogIC8qIGhhbmRsZSBkb3MgZXhlY3V0YWJsZXMgKi8KCiAgaEZpbGUgPSBDcmVhdGVGaWxlQSggZmlsZW5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELAoJCQkgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDApOwogIGlmIChoRmlsZSA9PSBJTlZBTElEX0hBTkRMRV9WQUxVRSkgcmV0dXJuIEZBTFNFOwoKICBzd2l0Y2ggKGZ1bmMpIHsKICBjYXNlIDA6IC8qIGxvYWQgYW5kIGV4ZWN1dGUgKi8KICBjYXNlIDE6IC8qIGxvYWQgYnV0IGRvbid0IGV4ZWN1dGUgKi8KICAgIHsKICAgICAgLyogc2F2ZSBjdXJyZW50IHByb2Nlc3MncyByZXR1cm4gU1M6U1Agbm93ICovCiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgICBwc3AtPnNhdmVTdGFjayA9IChEV09SRClNQUtFU0VHUFRSKGNvbnRleHQtPlNlZ1NzLCBMT1dPUkQoY29udGV4dC0+RXNwKSk7CiAgICB9CiAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBOVUxMICk7CiAgICBpZiAocmV0KSB7CiAgICAgIC8qIE1aX0xvYWRJbWFnZSBjcmVhdGVkIGEgbmV3IFBTUCBhbmQgbG9hZGVkIG5ldyB2YWx1ZXMgaW50byBpdCwKICAgICAgICogbGV0J3Mgd29yayBvbiB0aGUgbmV3IHZhbHVlcyBub3cgKi8KICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIEV4ZWNCbG9jayAqYmxrID0gKEV4ZWNCbG9jayAqKXBhcmFtYmxrOwogICAgICBMUEJZVEUgY21kbGluZSA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGJsay0+Y21kbGluZSksT0ZGU0VUT0YoYmxrLT5jbWRsaW5lKSk7CgogICAgICAvKiBGaXJzdCBjaGFyYWN0ZXIgY29udGFpbnMgdGhlIGxlbmd0aCBvZiB0aGUgY29tbWFuZCBsaW5lLiAqLwogICAgICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgY21kbGluZSArIDEsIGNtZGxpbmVbMF0pOwoKICAgICAgLyogdGhlIGxhbWUgTVMtRE9TIGVuZ2luZWVycyBkZWNpZGVkIHRoYXQgdGhlIHJldHVybiBhZGRyZXNzIHNob3VsZCBiZSBpbiBpbnQyMiAqLwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMiwgKEZBUlBST0MxNilNQUtFU0VHUFRSKGNvbnRleHQtPlNlZ0NzLCBMT1dPUkQoY29udGV4dC0+RWlwKSkpOwogICAgICBpZiAoZnVuYykgewoJLyogZG9uJ3QgZXhlY3V0ZSwganVzdCByZXR1cm4gc3RhcnR1cCBzdGF0ZSAqLwogICAgICAgIC8qCiAgICAgICAgICogRnJvbSBSYWxwaCBCcm93bjoKICAgICAgICAgKiAgRm9yIGZ1bmN0aW9uIDAxaCwgdGhlIEFYIHZhbHVlIHRvIGJlIHBhc3NlZCB0byB0aGUgY2hpbGQgcHJvZ3JhbSAKICAgICAgICAgKiAgaXMgcHV0IG9uIHRvcCBvZiB0aGUgY2hpbGQncyBzdGFjawogICAgICAgICAqLwogICAgICAgIExQQllURSBzdGFjazsKICAgICAgICBpbml0X3NwIC09IDI7CiAgICAgICAgc3RhY2sgPSAoTFBCWVRFKSBDVFhfU0VHX09GRl9UT19MSU4oY29udGV4dCwgaW5pdF9zcywgaW5pdF9zcCk7CiAgICAgICAgLyogRklYTUU6IHB1c2ggQVggY29ycmVjdGx5ICovCiAgICAgICAgc3RhY2tbMF0gPSAweDAwOyAgICAvKiBwdXNoIEFMICovCiAgICAgICAgc3RhY2tbMV0gPSAweDAwOyAgICAvKiBwdXNoIEFIICovCgkKCWJsay0+aW5pdF9jcyA9IGluaXRfY3M7CglibGstPmluaXRfaXAgPSBpbml0X2lwOwoJYmxrLT5pbml0X3NzID0gaW5pdF9zczsKCWJsay0+aW5pdF9zcCA9IGluaXRfc3A7CiAgICAgIH0gZWxzZSB7CgkvKiBleGVjdXRlIGJ5IG1ha2luZyB1cyByZXR1cm4gdG8gbmV3IHByb2Nlc3MgKi8KCWNvbnRleHQtPlNlZ0NzID0gaW5pdF9jczsKCWNvbnRleHQtPkVpcCAgID0gaW5pdF9pcDsKCWNvbnRleHQtPlNlZ1NzID0gaW5pdF9zczsKCWNvbnRleHQtPkVzcCAgID0gaW5pdF9zcDsKCWNvbnRleHQtPlNlZ0RzID0gRE9TVk1fcHNwOwoJY29udGV4dC0+U2VnRXMgPSBET1NWTV9wc3A7Cgljb250ZXh0LT5FYXggICA9IDA7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2UgMzogLyogbG9hZCBvdmVybGF5ICovCiAgICB7CiAgICAgIE92ZXJsYXlCbG9jayAqYmxrID0gKE92ZXJsYXlCbG9jayAqKXBhcmFtYmxrOwogICAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBibGsgKTsKICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBGSVhNRSgiRVhFQyBsb2FkIHR5cGUgJWQgbm90IGltcGxlbWVudGVkXG4iLCBmdW5jKTsKICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZVTkNUSU9OKTsKICAgIGJyZWFrOwogIH0KICBDbG9zZUhhbmRsZShoRmlsZSk7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9BbGxvY0RQTUlUYXNrCiAqLwp2b2lkIFdJTkFQSSBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogIE1aX0luaXRNZW1vcnkoKTsKICBNWl9Jbml0VGFzaygpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX1J1bkluVGhyZWFkCiAqLwp2b2lkIFdJTkFQSSBNWl9SdW5JblRocmVhZCggUEFQQ0ZVTkMgcHJvYywgVUxPTkdfUFRSIGFyZyApCnsKICBpZiAobG9vcF90aHJlYWQpIHsKICAgIERPU19TUEMgc3BjOwogICAgSEFORExFIGV2ZW50OwoKICAgIHNwYy5wcm9jID0gcHJvYzsKICAgIHNwYy5hcmcgPSBhcmc7CiAgICBldmVudCA9IENyZWF0ZUV2ZW50VyhOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICBQb3N0VGhyZWFkTWVzc2FnZUEobG9vcF90aWQsIFdNX1VTRVIsIChXUEFSQU0pZXZlbnQsIChMUEFSQU0pJnNwYyk7CiAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KGV2ZW50LCBJTkZJTklURSk7CiAgICBDbG9zZUhhbmRsZShldmVudCk7CiAgfSBlbHNlCiAgICBwcm9jKGFyZyk7Cn0KCnN0YXRpYyBEV09SRCBXSU5BUEkgTVpfRE9TVk0oIExQVk9JRCBscEV4dHJhICkKewogIENPTlRFWFQgY29udGV4dDsKICBEV09SRCByZXQ7CgogIGRvc3ZtX3BpZCA9IGdldHBpZCgpOwoKICBtZW1zZXQoICZjb250ZXh0LCAwLCBzaXplb2YoY29udGV4dCkgKTsKICBjb250ZXh0LlNlZ0NzICA9IGluaXRfY3M7CiAgY29udGV4dC5FaXAgICAgPSBpbml0X2lwOwogIGNvbnRleHQuU2VnU3MgID0gaW5pdF9zczsKICBjb250ZXh0LkVzcCAgICA9IGluaXRfc3A7CiAgY29udGV4dC5TZWdEcyAgPSBET1NWTV9wc3A7CiAgY29udGV4dC5TZWdFcyAgPSBET1NWTV9wc3A7CiAgY29udGV4dC5FRmxhZ3MgPSBWODZfRkxBRyB8IFZJRl9NQVNLOwogIERPU1ZNX1NldFRpbWVyKDB4MTAwMDApOwogIHJldCA9IERPU1ZNX0VudGVyKCAmY29udGV4dCApOwoKICBkb3N2bV9waWQgPSAwOwogIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpCnsKICBpZiAoIUR1cGxpY2F0ZUhhbmRsZShHZXRDdXJyZW50UHJvY2VzcygpLCBHZXRDdXJyZW50VGhyZWFkKCksCiAgICAgICAgICAgICAgICAgICAgICAgR2V0Q3VycmVudFByb2Nlc3MoKSwgJmxvb3BfdGhyZWFkLAogICAgICAgICAgICAgICAgICAgICAgIDAsIEZBTFNFLCBEVVBMSUNBVEVfU0FNRV9BQ0NFU1MpKQogICAgcmV0dXJuIEZBTFNFOwogIGRvc3ZtX3RocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBNWl9ET1NWTSwgTlVMTCwgQ1JFQVRFX1NVU1BFTkRFRCwgJmRvc3ZtX3RpZCk7CiAgaWYgKCFkb3N2bV90aHJlYWQpIHsKICAgIENsb3NlSGFuZGxlKGxvb3BfdGhyZWFkKTsKICAgIGxvb3BfdGhyZWFkID0gMDsKICAgIHJldHVybiBGQUxTRTsKICB9CiAgbG9vcF90aWQgPSBHZXRDdXJyZW50VGhyZWFkSWQoKTsKICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgTVpfTGF1bmNoKCBMUENTVFIgY21kdGFpbCwgaW50IGxlbmd0aCApCnsKICBUREIgKnBUYXNrID0gR2xvYmFsTG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiAgQllURSAqcHNwX3N0YXJ0ID0gUFRSX1JFQUxfVE9fTElOKCBET1NWTV9wc3AsIDAgKTsKICBEV09SRCBydjsKICBTWVNMRVZFTCAqbG9jazsKCiAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIGNtZHRhaWwsIGxlbmd0aCk7CiAgcFRhc2stPmZsYWdzIHw9IFREQkZfV0lOT0xEQVA7CgogIC8qIERUQSBpcyBzZXQgdG8gUFNQOjAwODBoIHdoZW4gYSBwcm9ncmFtIGlzIHN0YXJ0ZWQuICovCiAgcFRhc2stPmR0YSA9IE1BS0VTRUdQVFIoIERPU1ZNX3BzcCwgMHg4MCApOwoKICBHZXRwV2luMTZMb2NrKCAmbG9jayApOwogIF9MZWF2ZVN5c0xldmVsKCBsb2NrICk7CgogIFJlc3VtZVRocmVhZChkb3N2bV90aHJlYWQpOwogIHJ2ID0gRE9TVk1fTG9vcChkb3N2bV90aHJlYWQpOwoKICBDbG9zZUhhbmRsZShkb3N2bV90aHJlYWQpOwogIGRvc3ZtX3RocmVhZCA9IDA7IGRvc3ZtX3RpZCA9IDA7CiAgQ2xvc2VIYW5kbGUobG9vcF90aHJlYWQpOwogIGxvb3BfdGhyZWFkID0gMDsgbG9vcF90aWQgPSAwOwoKICBWR0FfQ2xlYW4oKTsKICBFeGl0UHJvY2Vzcyhydik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhpdAogKi8Kdm9pZCBXSU5BUEkgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgaWYgKERPU1ZNX3BzcCkgewogICAgV09SRCBwc3Bfc2VnID0gY3NfcHNwID8gY29udGV4dC0+U2VnQ3MgOiBET1NWTV9wc3A7CiAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKXBzcF9zZWcgPDwgNCk7CiAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgV09SRCBwYXJwc3AgPSBwc3AtPnBhcmVudFBTUDsgLyogY2hlY2sgZm9yIHBhcmVudCBET1MgcHJvY2VzcyAqLwogICAgaWYgKHBhcnBzcCkgewogICAgICAvKiByZXRyaWV2ZSBwYXJlbnQncyByZXR1cm4gYWRkcmVzcyAqLwogICAgICBGQVJQUk9DMTYgcmV0YWRkciA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIyKTsKICAgICAgLyogcmVzdG9yZSBpbnRlcnJ1cHRzICovCiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIyLCBwc3AtPnNhdmVkaW50MjIpOwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMywgcHNwLT5zYXZlZGludDIzKTsKICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjQsIHBzcC0+c2F2ZWRpbnQyNCk7CiAgICAgIC8qIEZJWE1FOiBkZWFsbG9jYXRlIGZpbGUgaGFuZGxlcyBldGMgKi8KICAgICAgLyogZnJlZSBwcm9jZXNzJ3MgYXNzb2NpYXRlZCBtZW1vcnkKICAgICAgICogRklYTUU6IHdhbGsgbWVtb3J5IGFuZCBkZWFsbG9jYXRlIGFsbCBibG9ja3Mgb3duZWQgYnkgcHJvY2VzcyAqLwogICAgICBET1NNRU1fRnJlZUJsb2NrKCBQVFJfUkVBTF9UT19MSU4ocHNwLT5lbnZpcm9ubWVudCwwKSApOwogICAgICBET1NNRU1fRnJlZUJsb2NrKCBQVFJfUkVBTF9UT19MSU4oRE9TVk1fcHNwLDApICk7CiAgICAgIC8qIHN3aXRjaCB0byBwYXJlbnQncyBQU1AgKi8KICAgICAgRE9TVk1fcHNwID0gcGFycHNwOwogICAgICBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcGFycHNwIDw8IDQpOwogICAgICBwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIC8qIG5vdyByZXR1cm4gdG8gcGFyZW50ICovCiAgICAgIERPU1ZNX3JldHZhbCA9IHJldHZhbDsKICAgICAgY29udGV4dC0+U2VnQ3MgPSBTRUxFQ1RPUk9GKHJldGFkZHIpOwogICAgICBjb250ZXh0LT5FaXAgICA9IE9GRlNFVE9GKHJldGFkZHIpOwogICAgICBjb250ZXh0LT5TZWdTcyA9IFNFTEVDVE9ST0YocHNwLT5zYXZlU3RhY2spOwogICAgICBjb250ZXh0LT5Fc3AgICA9IE9GRlNFVE9GKHBzcC0+c2F2ZVN0YWNrKTsKICAgICAgcmV0dXJuOwogICAgfSBlbHNlCiAgICAgIFRSQUNFKCJraWxsaW5nIERPUyB0YXNrXG4iKTsKICB9CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0N1cnJlbnQKICovCkJPT0wgV0lOQVBJIE1aX0N1cnJlbnQoIHZvaWQgKQp7CiAgcmV0dXJuIChkb3N2bV9waWQgIT0gMCk7IC8qIEZJWE1FOiBkbyBhIGJldHRlciBjaGVjayAqLwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCXdpbmVfbG9hZF9kb3NfZXhlIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSB3aW5lX2xvYWRfZG9zX2V4ZSggTFBDU1RSIGZpbGVuYW1lLCBMUENTVFIgY21kbGluZSApCnsKICBXQVJOKCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIHBsYXRmb3JtXG4iKTsKICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhlYwogKi8KQk9PTCBXSU5BUEkgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIC8qIGNhbid0IGhhcHBlbiAqLwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQWxsb2NEUE1JVGFzawogKi8Kdm9pZCBXSU5BUEkgTVpfQWxsb2NEUE1JVGFzayggdm9pZCApCnsKICAgIEVSUigiQWN0dWFsIHJlYWwtbW9kZSBjYWxscyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm0hXG4iKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9SdW5JblRocmVhZAogKi8Kdm9pZCBXSU5BUEkgTVpfUnVuSW5UaHJlYWQoIFBBUENGVU5DIHByb2MsIFVMT05HX1BUUiBhcmcgKQp7CiAgICBwcm9jKGFyZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhpdAogKi8Kdm9pZCBXSU5BUEkgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQ3VycmVudAogKi8KQk9PTCBXSU5BUEkgTVpfQ3VycmVudCggdm9pZCApCnsKICAgIHJldHVybiBGQUxTRTsKfQoKI2VuZGlmIC8qICFNWl9TVVBQT1JURUQgKi8K