LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICogTm90ZTogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaWZkZWYgSEFWRV9VTklTVERfSAojIGluY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2lmZGVmIEhBVkVfU1lTX1RJTUVfSAojIGluY2x1ZGUgPHN5cy90aW1lLmg+CiNlbmRpZgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc3ZtLmgiCiNpbmNsdWRlICJ2Z2EuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CgojaWZkZWYgTVpfU1VQUE9SVEVECgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBQU1BfU0laRSAweDEwCgojZGVmaW5lIFNFRzE2KHB0cixzZWcpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpKHNlZyk8PDQpKSkKI2RlZmluZSBTRUdQVFIxNihwdHIsc2VncHRyKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKVNFTEVDVE9ST0Yoc2VncHRyKTw8NCkrT0ZGU0VUT0Yoc2VncHRyKSkpCgovKiBzdHJ1Y3R1cmVzIGZvciBFWEVDICovCgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBlbnZfc2VnOwogIERXT1JEIGNtZGxpbmUgV0lORV9QQUNLRUQ7CiAgRFdPUkQgZmNiMSBXSU5FX1BBQ0tFRDsKICBEV09SRCBmY2IyIFdJTkVfUEFDS0VEOwogIFdPUkQgaW5pdF9zcDsKICBXT1JEIGluaXRfc3M7CiAgV09SRCBpbml0X2lwOwogIFdPUkQgaW5pdF9jczsKfSBFeGVjQmxvY2s7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBsb2FkX3NlZzsKICBXT1JEIHJlbF9zZWc7Cn0gT3ZlcmxheUJsb2NrOwoKLyogZ2xvYmFsIHZhcmlhYmxlcyAqLwoKcGlkX3QgZG9zdm1fcGlkOwoKc3RhdGljIFdPUkQgaW5pdF9jcyxpbml0X2lwLGluaXRfc3MsaW5pdF9zcDsKc3RhdGljIEhBTkRMRSBkb3N2bV90aHJlYWQsIGxvb3BfdGhyZWFkOwpzdGF0aWMgRFdPUkQgZG9zdm1fdGlkLCBsb29wX3RpZDsKCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKTsKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCk7CgpzdGF0aWMgdm9pZCBNWl9DcmVhdGVQU1AoIExQVk9JRCBscFBTUCwgV09SRCBlbnYsIFdPUkQgcGFyICkKewogIFBEQjE2KnBzcD1scFBTUDsKCiAgcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogIC8qIHNvbWUgcHJvZ3JhbXMgdXNlIHRoaXMgdG8gY2FsY3VsYXRlIGhvdyBtdWNoIG1lbW9yeSB0aGV5IG5lZWQgKi8KICBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOyAvKiBGSVhNRTogdXNlIGEgcmVhbCB2YWx1ZSAqLwogIC8qIEZJWE1FOiBkaXNwYXRjaGVyICovCiAgcHNwLT5zYXZlZGludDIyID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjIpOwogIHBzcC0+c2F2ZWRpbnQyMyA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIzKTsKICBwc3AtPnNhdmVkaW50MjQgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyNCk7CiAgcHNwLT5wYXJlbnRQU1A9cGFyOwogIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgpzdGF0aWMgdm9pZCBNWl9GaWxsUFNQKCBMUFZPSUQgbHBQU1AsIExQQllURSBjbWRsaW5lLCBpbnQgbGVuZ3RoICkKewogIFBEQjE2ICAgICAgKnBzcCA9IGxwUFNQOwoKICB3aGlsZShsZW5ndGggPiAwICYmICpjbWRsaW5lICE9ICcgJykgewogICAgbGVuZ3RoLS07CiAgICBjbWRsaW5lKys7CiAgfQoKICAvKiBjb21tYW5kLmNvbSBkb2VzIG5vdCBza2lwIG92ZXIgbXVsdGlwbGUgc3BhY2VzICovCgogIGlmKGxlbmd0aCA+IDEyNikgewogICAgRVJSKCJDb21tYW5kIGxpbmUgdHJ1bmNhdGVkISAobGVuZ3RoICVkID4gbWF4aW11bSBsZW5ndGggMTI2KVxuIiwKICAgICAgIGxlbmd0aCk7CiAgICBsZW5ndGggPSAxMjY7CiAgfQoKICBwc3AtPmNtZExpbmVbMF0gPSBsZW5ndGg7CiAgaWYobGVuZ3RoID4gMCkKICAgIG1lbW1vdmUocHNwLT5jbWRMaW5lKzEsIGNtZGxpbmUsIGxlbmd0aCk7CiAgcHNwLT5jbWRMaW5lW2xlbmd0aCsxXSA9ICdccic7CgogIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgovKiBkZWZhdWx0IElOVCAwOCBoYW5kbGVyOiBpbmNyZWFzZXMgdGltZXIgdGljayBjb3VudGVyIGJ1dCBub3QgbXVjaCBtb3JlICovCnN0YXRpYyBjaGFyIGludDA4W109ewogMHhDRCwweDFDLCAgICAgICAgICAgLyogaW50ICQweDFjICovCiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4MUUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkcyAqLwogMHhCOCwweDQwLDB4MDAsICAgICAgLyogbW92dyAkMHg0MCwlYXggKi8KIDB4OEUsMHhEOCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVkcyAqLwojaWYgMAogMHg4MywweDA2LDB4NkMsMHgwMCwweDAxLCAvKiBhZGR3ICQxLCgweDZjKSAqLwogMHg4MywweDE2LDB4NkUsMHgwMCwweDAwLCAvKiBhZGN3ICQwLCgweDZlKSAqLwojZWxzZQogMHg2NiwweEZGLDB4MDYsMHg2QywweDAwLCAvKiBpbmNsICgweDZjKSAqLwojZW5kaWYKIDB4QjAsMHgyMCwgICAgICAgICAgIC8qIG1vdmIgJDB4MjAsJWFsICovCiAweEU2LDB4MjAsICAgICAgICAgICAvKiBvdXRiICVhbCwkMHgyMCAqLwogMHgxRiwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENGICAgICAgICAgICAgICAgICAvKiBpcmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0SGFuZGxlcnModm9pZCkKewogV09SRCBzZWc7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKHNpemVvZihpbnQwOCksJnNlZyk7CiBtZW1jcHkoc3RhcnQsaW50MDgsc2l6ZW9mKGludDA4KSk7Ci8qIElOVCAwODogcG9pbnQgaXQgYXQgb3VyIHRpY2staW5jcmVtZW50aW5nIGhhbmRsZXIgKi8KICgoU0VHUFRSKikwKVsweDA4XT1NQUtFU0VHUFRSKHNlZywwKTsKLyogSU5UIDFDOiBqdXN0IHBvaW50IGl0IHRvIElSRVQsIHdlIGRvbid0IHdhbnQgdG8gaGFuZGxlIGl0IG91cnNlbHZlcyAqLwogKChTRUdQVFIqKTApWzB4MUNdPU1BS0VTRUdQVFIoc2VnLHNpemVvZihpbnQwOCktMSk7Cn0KCnN0YXRpYyBXT1JEIE1aX0luaXRFbnZpcm9ubWVudCggTFBDU1RSIGVudiwgTFBDU1RSIG5hbWUgKQp7CiB1bnNpZ25lZCBzej0wOwogV09SRCBzZWc7CiBMUFNUUiBlbnZibGs7CgogaWYgKGVudikgewogIC8qIGdldCBzaXplIG9mIGVudmlyb25tZW50IGJsb2NrICovCiAgd2hpbGUgKGVudltzeisrXSkgc3orPXN0cmxlbihlbnYrc3opKzE7CiB9IGVsc2Ugc3orKzsKIC8qIGFsbG9jYXRlIGl0ICovCiBlbnZibGs9RE9TTUVNX0dldEJsb2NrKHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSh2b2lkKQp7CiAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKICAgIERPU01FTV9Jbml0KFRSVUUpOwoKICAgIE1aX0luaXRIYW5kbGVycygpOwogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MIE1aX0RvTG9hZEltYWdlKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgT3ZlcmxheUJsb2NrICpvYmxrICkKewogIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiAgQllURSpwc3Bfc3RhcnQsKmxvYWRfc3RhcnQsKm9sZGVudjsKICBpbnQgeCwgb2xkX2NvbT0wLCBhbGxvYzsKICBTRUdQVFIgcmVsb2M7CiAgV09SRCBlbnZfc2VnLCBsb2FkX3NlZywgcmVsX3NlZywgb2xkcHNwX3NlZzsKICBEV09SRCBsZW47CgogIGlmIChET1NWTV9wc3ApIHsKICAgIC8qIERPUyBwcm9jZXNzIGFscmVhZHkgcnVubmluZywgaW5oZXJpdCBmcm9tIGl0ICovCiAgICBQREIxNiogcGFyX3BzcCA9IChQREIxNiopKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICBhbGxvYz0wOwogICAgb2xkZW52ID0gKExQQllURSkoKERXT1JEKXBhcl9wc3AtPmVudmlyb25tZW50IDw8IDQpOwogICAgb2xkcHNwX3NlZyA9IERPU1ZNX3BzcDsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgbmV3IERPUyBwcm9jZXNzLCBpbmhlcml0aW5nIGZyb20gV2luZSBlbnZpcm9ubWVudCAqLwogICAgYWxsb2M9MTsKICAgIG9sZGVudiA9IEdldEVudmlyb25tZW50U3RyaW5nc0EoKTsKICAgIG9sZHBzcF9zZWcgPSAwOwogIH0KCiBTZXRGaWxlUG9pbnRlcihoRmlsZSwwLE5VTEwsRklMRV9CRUdJTik7CiBpZiAoICAgIVJlYWRGaWxlKGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlciksJmxlbixOVUxMKQogICAgIHx8IGxlbiAhPSBzaXplb2YobXpfaGVhZGVyKQogICAgIHx8IG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpIHsKICBjaGFyICpwID0gc3RycmNociggZmlsZW5hbWUsICcuJyApOwogIGlmICghcCB8fCBzdHJjYXNlY21wKCBwLCAiLmNvbSIgKSkgIC8qIGNoZWNrIGZvciAuQ09NIGV4dGVuc2lvbiAqLwogIHsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgfQogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKICBpZiAoYWxsb2MpIE1aX0luaXRNZW1vcnkoKTsKCiAgaWYgKG9ibGspIHsKICAgIC8qIGxvYWQgb3ZlcmxheSBpbnRvIHByZWFsbG9jYXRlZCBtZW1vcnkgKi8KICAgIGxvYWRfc2VnPW9ibGstPmxvYWRfc2VnOwogICAgcmVsX3NlZz1vYmxrLT5yZWxfc2VnOwogICAgbG9hZF9zdGFydD0oTFBCWVRFKSgoRFdPUkQpbG9hZF9zZWc8PDQpOwogIH0gZWxzZSB7CiAgICAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogICAgZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQob2xkZW52LCBmaWxlbmFtZSk7CgogICAgLyogYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgZXhlY3V0YWJsZSAqLwogICAgVFJBQ0UoIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogICAgYXZhaWw9RE9TTUVNX0F2YWlsYWJsZSgpOwogICAgaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgICAgIEVSUigiaW5zdWZmaWNpZW50IERPUyBtZW1vcnlcbiIpOwogICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgICB9CiAgICBpZiAoYXZhaWw+bWF4X3NpemUpIGF2YWlsPW1heF9zaXplOwogICAgcHNwX3N0YXJ0PURPU01FTV9HZXRCbG9jayhhdmFpbCwmRE9TVk1fcHNwKTsKICAgIGlmICghcHNwX3N0YXJ0KSB7CiAgICAgIEVSUigiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgbG9hZF9zZWc9RE9TVk1fcHNwKyhvbGRfY29tPzA6UFNQX1NJWkUpOwogICAgcmVsX3NlZz1sb2FkX3NlZzsKICAgIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiAgICBNWl9DcmVhdGVQU1AocHNwX3N0YXJ0LCBlbnZfc2VnLCBvbGRwc3Bfc2VnKTsKICB9CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRSgibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBTZXRGaWxlUG9pbnRlcihoRmlsZSxpbWFnZV9zdGFydCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCFSZWFkRmlsZShoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUsJmxlbixOVUxMKSB8fCBsZW4gIT0gaW1hZ2Vfc2l6ZSkgewogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICBnb3RvIGxvYWRfZXJyb3I7CiB9CgogaWYgKG16X2hlYWRlci5lX2NybGMpIHsKICAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KICBUUkFDRSgibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfY3JsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBTZXRGaWxlUG9pbnRlcihoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsTlVMTCxGSUxFX0JFR0lOKTsKICBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICAgaWYgKCFSZWFkRmlsZShoRmlsZSwmcmVsb2Msc2l6ZW9mKHJlbG9jKSwmbGVuLE5VTEwpIHx8IGxlbiAhPSBzaXplb2YocmVsb2MpKSB7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgICBnb3RvIGxvYWRfZXJyb3I7CiAgIH0KICAgKihXT1JEKilTRUdQVFIxNihsb2FkX3N0YXJ0LHJlbG9jKSs9cmVsX3NlZzsKICB9CiB9CgogIGlmICghb2JsaykgewogICAgaW5pdF9jcyA9IGxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogICAgaW5pdF9pcCA9IG16X2hlYWRlci5lX2lwOwogICAgaW5pdF9zcyA9IGxvYWRfc2VnK216X2hlYWRlci5lX3NzOwogICAgaW5pdF9zcCA9IG16X2hlYWRlci5lX3NwOwoKICAgIFRSQUNFKCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGluaXRfY3MsaW5pdF9pcCk7CiAgfQoKICBpZiAoYWxsb2MgJiYgIU1aX0luaXRUYXNrKCkpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9HRU5fRkFJTFVSRSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICByZXR1cm4gVFJVRTsKCmxvYWRfZXJyb3I6CiAgRE9TVk1fcHNwID0gb2xkcHNwX3NlZzsKCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUxvYWREb3NFeGUgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIE1aX0xvYWRJbWFnZSggTFBDU1RSIGZpbGVuYW1lLCBIQU5ETEUgaEZpbGUgKQp7CiAgaWYgKE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIE5VTEwgKSkgTVpfTGF1bmNoKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhlYwogKi8KQk9PTCBXSU5BUEkgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIC8qIHRoaXMgbWF5IG9ubHkgYmUgY2FsbGVkIGZyb20gZXhpc3RpbmcgRE9TIHByb2Nlc3NlcwogICAqIChpLmUuIG9uZSBET1MgYXBwIHNwYXduaW5nIGFub3RoZXIpICovCiAgLyogRklYTUU6IGRvIHdlIHdhbnQgdG8gY2hlY2sgYmluYXJ5IHR5cGUgZmlyc3QsIHRvIGNoZWNrCiAgICogd2hldGhlciBpdCdzIGEgTkUvUEUgZXhlY3V0YWJsZT8gKi8KICBIQU5ETEUgaEZpbGUgPSBDcmVhdGVGaWxlQSggZmlsZW5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELAoJCQkgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDApOwogIEJPT0wgcmV0ID0gRkFMU0U7CiAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm4gRkFMU0U7CiAgc3dpdGNoIChmdW5jKSB7CiAgY2FzZSAwOiAvKiBsb2FkIGFuZCBleGVjdXRlICovCiAgY2FzZSAxOiAvKiBsb2FkIGJ1dCBkb24ndCBleGVjdXRlICovCiAgICB7CiAgICAgIC8qIHNhdmUgY3VycmVudCBwcm9jZXNzJ3MgcmV0dXJuIFNTOlNQIG5vdyAqLwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKURPU1ZNX3BzcCA8PCA0KTsKICAgICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgcHNwLT5zYXZlU3RhY2sgPSAoRFdPUkQpTUFLRVNFR1BUUihjb250ZXh0LT5TZWdTcywgTE9XT1JEKGNvbnRleHQtPkVzcCkpOwogICAgfQogICAgcmV0ID0gTVpfRG9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgTlVMTCApOwogICAgaWYgKHJldCkgewogICAgICAvKiBNWl9Mb2FkSW1hZ2UgY3JlYXRlZCBhIG5ldyBQU1AgYW5kIGxvYWRlZCBuZXcgdmFsdWVzIGludG8gaXQsCiAgICAgICAqIGxldCdzIHdvcmsgb24gdGhlIG5ldyB2YWx1ZXMgbm93ICovCiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICBFeGVjQmxvY2sgKmJsayA9IChFeGVjQmxvY2sgKilwYXJhbWJsazsKICAgICAgTFBCWVRFIGNtZGxpbmUgPSBET1NNRU1fTWFwUmVhbFRvTGluZWFyKGJsay0+Y21kbGluZSk7CgogICAgICAvKiBGaXJzdCBjaGFyYWN0ZXIgY29udGFpbnMgdGhlIGxlbmd0aCBvZiB0aGUgY29tbWFuZCBsaW5lLiAqLwogICAgICBNWl9GaWxsUFNQKHBzcF9zdGFydCwgY21kbGluZSArIDEsIGNtZGxpbmVbMF0pOwoKICAgICAgLyogdGhlIGxhbWUgTVMtRE9TIGVuZ2luZWVycyBkZWNpZGVkIHRoYXQgdGhlIHJldHVybiBhZGRyZXNzIHNob3VsZCBiZSBpbiBpbnQyMiAqLwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMiwgKEZBUlBST0MxNilNQUtFU0VHUFRSKGNvbnRleHQtPlNlZ0NzLCBMT1dPUkQoY29udGV4dC0+RWlwKSkpOwogICAgICBpZiAoZnVuYykgewoJLyogZG9uJ3QgZXhlY3V0ZSwganVzdCByZXR1cm4gc3RhcnR1cCBzdGF0ZSAqLwoJYmxrLT5pbml0X2NzID0gaW5pdF9jczsKCWJsay0+aW5pdF9pcCA9IGluaXRfaXA7CglibGstPmluaXRfc3MgPSBpbml0X3NzOwoJYmxrLT5pbml0X3NwID0gaW5pdF9zcDsKICAgICAgfSBlbHNlIHsKCS8qIGV4ZWN1dGUgYnkgbWFraW5nIHVzIHJldHVybiB0byBuZXcgcHJvY2VzcyAqLwoJY29udGV4dC0+U2VnQ3MgPSBpbml0X2NzOwoJY29udGV4dC0+RWlwICAgPSBpbml0X2lwOwoJY29udGV4dC0+U2VnU3MgPSBpbml0X3NzOwoJY29udGV4dC0+RXNwICAgPSBpbml0X3NwOwoJY29udGV4dC0+U2VnRHMgPSBET1NWTV9wc3A7Cgljb250ZXh0LT5TZWdFcyA9IERPU1ZNX3BzcDsKCWNvbnRleHQtPkVheCAgID0gMDsKICAgICAgfQogICAgfQogICAgYnJlYWs7CiAgY2FzZSAzOiAvKiBsb2FkIG92ZXJsYXkgKi8KICAgIHsKICAgICAgT3ZlcmxheUJsb2NrICpibGsgPSAoT3ZlcmxheUJsb2NrICopcGFyYW1ibGs7CiAgICAgIHJldCA9IE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIGJsayApOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIEZJWE1FKCJFWEVDIGxvYWQgdHlwZSAlZCBub3QgaW1wbGVtZW50ZWRcbiIsIGZ1bmMpOwogICAgU2V0TGFzdEVycm9yKEVSUk9SX0lOVkFMSURfRlVOQ1RJT04pOwogICAgYnJlYWs7CiAgfQogIENsb3NlSGFuZGxlKGhGaWxlKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0FsbG9jRFBNSVRhc2sKICovCnZvaWQgV0lOQVBJIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgTVpfSW5pdE1lbW9yeSgpOwogIE1aX0luaXRUYXNrKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfUnVuSW5UaHJlYWQKICovCnZvaWQgV0lOQVBJIE1aX1J1bkluVGhyZWFkKCBQQVBDRlVOQyBwcm9jLCBVTE9OR19QVFIgYXJnICkKewogIGlmIChsb29wX3RocmVhZCkgewogICAgRE9TX1NQQyBzcGM7CiAgICBIQU5ETEUgZXZlbnQ7CgogICAgc3BjLnByb2MgPSBwcm9jOwogICAgc3BjLmFyZyA9IGFyZzsKICAgIGV2ZW50ID0gQ3JlYXRlRXZlbnRBKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICAgIFBvc3RUaHJlYWRNZXNzYWdlQShsb29wX3RpZCwgV01fVVNFUiwgZXZlbnQsIChMUEFSQU0pJnNwYyk7CiAgICBXYWl0Rm9yU2luZ2xlT2JqZWN0KGV2ZW50LCBJTkZJTklURSk7CiAgICBDbG9zZUhhbmRsZShldmVudCk7CiAgfSBlbHNlCiAgICBwcm9jKGFyZyk7Cn0KCnN0YXRpYyBEV09SRCBXSU5BUEkgTVpfRE9TVk0oIExQVk9JRCBscEV4dHJhICkKewogIENPTlRFWFQgY29udGV4dDsKICBEV09SRCByZXQ7CgogIGRvc3ZtX3BpZCA9IGdldHBpZCgpOwoKICBtZW1zZXQoICZjb250ZXh0LCAwLCBzaXplb2YoY29udGV4dCkgKTsKICBjb250ZXh0LlNlZ0NzICA9IGluaXRfY3M7CiAgY29udGV4dC5FaXAgICAgPSBpbml0X2lwOwogIGNvbnRleHQuU2VnU3MgID0gaW5pdF9zczsKICBjb250ZXh0LkVzcCAgICA9IGluaXRfc3A7CiAgY29udGV4dC5TZWdEcyAgPSBET1NWTV9wc3A7CiAgY29udGV4dC5TZWdFcyAgPSBET1NWTV9wc3A7CiAgY29udGV4dC5FRmxhZ3MgPSAweDAwMDgwMDAwOyAgLyogdmlydHVhbCBpbnRlcnJ1cHQgZmxhZyAqLwogIERPU1ZNX1NldFRpbWVyKDB4MTAwMDApOwogIHJldCA9IERPU1ZNX0VudGVyKCAmY29udGV4dCApOwoKICBkb3N2bV9waWQgPSAwOwogIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBCT09MIE1aX0luaXRUYXNrKHZvaWQpCnsKICBpZiAoIUR1cGxpY2F0ZUhhbmRsZShHZXRDdXJyZW50UHJvY2VzcygpLCBHZXRDdXJyZW50VGhyZWFkKCksCiAgICAgICAgICAgICAgICAgICAgICAgR2V0Q3VycmVudFByb2Nlc3MoKSwgJmxvb3BfdGhyZWFkLAogICAgICAgICAgICAgICAgICAgICAgIDAsIEZBTFNFLCBEVVBMSUNBVEVfU0FNRV9BQ0NFU1MpKQogICAgcmV0dXJuIEZBTFNFOwogIGRvc3ZtX3RocmVhZCA9IENyZWF0ZVRocmVhZChOVUxMLCAwLCBNWl9ET1NWTSwgTlVMTCwgQ1JFQVRFX1NVU1BFTkRFRCwgJmRvc3ZtX3RpZCk7CiAgaWYgKCFkb3N2bV90aHJlYWQpIHsKICAgIENsb3NlSGFuZGxlKGxvb3BfdGhyZWFkKTsKICAgIGxvb3BfdGhyZWFkID0gMDsKICAgIHJldHVybiBGQUxTRTsKICB9CiAgbG9vcF90aWQgPSBHZXRDdXJyZW50VGhyZWFkSWQoKTsKICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIHZvaWQgTVpfTGF1bmNoKHZvaWQpCnsKICBUREIgKnBUYXNrID0gVEFTS19HZXRDdXJyZW50KCk7CiAgQllURSAqcHNwX3N0YXJ0ID0gUFRSX1JFQUxfVE9fTElOKCBET1NWTV9wc3AsIDAgKTsKICBMUFNUUiBjbWRsaW5lID0gR2V0Q29tbWFuZExpbmVBKCk7CiAgRFdPUkQgcnY7CgogIE1aX0ZpbGxQU1AocHNwX3N0YXJ0LCBjbWRsaW5lLCBjbWRsaW5lID8gc3RybGVuKGNtZGxpbmUpIDogMCk7CiAgcFRhc2stPmZsYWdzIHw9IFREQkZfV0lOT0xEQVA7CgogIF9MZWF2ZVdpbjE2TG9jaygpOwoKICBSZXN1bWVUaHJlYWQoZG9zdm1fdGhyZWFkKTsKICBydiA9IERPU1ZNX0xvb3AoZG9zdm1fdGhyZWFkKTsKCiAgQ2xvc2VIYW5kbGUoZG9zdm1fdGhyZWFkKTsKICBkb3N2bV90aHJlYWQgPSAwOyBkb3N2bV90aWQgPSAwOwogIENsb3NlSGFuZGxlKGxvb3BfdGhyZWFkKTsKICBsb29wX3RocmVhZCA9IDA7IGxvb3BfdGlkID0gMDsKCiAgVkdBX0NsZWFuKCk7CiAgRXhpdFRocmVhZChydik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhpdAogKi8Kdm9pZCBXSU5BUEkgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgaWYgKERPU1ZNX3BzcCkgewogICAgV09SRCBwc3Bfc2VnID0gY3NfcHNwID8gY29udGV4dC0+U2VnQ3MgOiBET1NWTV9wc3A7CiAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKXBzcF9zZWcgPDwgNCk7CiAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgV09SRCBwYXJwc3AgPSBwc3AtPnBhcmVudFBTUDsgLyogY2hlY2sgZm9yIHBhcmVudCBET1MgcHJvY2VzcyAqLwogICAgaWYgKHBhcnBzcCkgewogICAgICAvKiByZXRyaWV2ZSBwYXJlbnQncyByZXR1cm4gYWRkcmVzcyAqLwogICAgICBGQVJQUk9DMTYgcmV0YWRkciA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIyKTsKICAgICAgLyogcmVzdG9yZSBpbnRlcnJ1cHRzICovCiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIyLCBwc3AtPnNhdmVkaW50MjIpOwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMywgcHNwLT5zYXZlZGludDIzKTsKICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjQsIHBzcC0+c2F2ZWRpbnQyNCk7CiAgICAgIC8qIEZJWE1FOiBkZWFsbG9jYXRlIGZpbGUgaGFuZGxlcyBldGMgKi8KICAgICAgLyogZnJlZSBwcm9jZXNzJ3MgYXNzb2NpYXRlZCBtZW1vcnkKICAgICAgICogRklYTUU6IHdhbGsgbWVtb3J5IGFuZCBkZWFsbG9jYXRlIGFsbCBibG9ja3Mgb3duZWQgYnkgcHJvY2VzcyAqLwogICAgICBET1NNRU1fRnJlZUJsb2NrKERPU01FTV9NYXBSZWFsVG9MaW5lYXIoTUFLRUxPTkcoMCxwc3AtPmVudmlyb25tZW50KSkpOwogICAgICBET1NNRU1fRnJlZUJsb2NrKERPU01FTV9NYXBSZWFsVG9MaW5lYXIoTUFLRUxPTkcoMCxET1NWTV9wc3ApKSk7CiAgICAgIC8qIHN3aXRjaCB0byBwYXJlbnQncyBQU1AgKi8KICAgICAgRE9TVk1fcHNwID0gcGFycHNwOwogICAgICBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcGFycHNwIDw8IDQpOwogICAgICBwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICAgIC8qIG5vdyByZXR1cm4gdG8gcGFyZW50ICovCiAgICAgIERPU1ZNX3JldHZhbCA9IHJldHZhbDsKICAgICAgY29udGV4dC0+U2VnQ3MgPSBTRUxFQ1RPUk9GKHJldGFkZHIpOwogICAgICBjb250ZXh0LT5FaXAgICA9IE9GRlNFVE9GKHJldGFkZHIpOwogICAgICBjb250ZXh0LT5TZWdTcyA9IFNFTEVDVE9ST0YocHNwLT5zYXZlU3RhY2spOwogICAgICBjb250ZXh0LT5Fc3AgICA9IE9GRlNFVE9GKHBzcC0+c2F2ZVN0YWNrKTsKICAgICAgcmV0dXJuOwogICAgfSBlbHNlCiAgICAgIFRSQUNFKCJraWxsaW5nIERPUyB0YXNrXG4iKTsKICB9CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0N1cnJlbnQKICovCkJPT0wgV0lOQVBJIE1aX0N1cnJlbnQoIHZvaWQgKQp7CiAgcmV0dXJuIChkb3N2bV9waWQgIT0gMCk7IC8qIEZJWE1FOiBkbyBhIGJldHRlciBjaGVjayAqLwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUxvYWREb3NFeGUgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIE1aX0xvYWRJbWFnZSggTFBDU1RSIGZpbGVuYW1lLCBIQU5ETEUgaEZpbGUgKQp7CiAgV0FSTigiRE9TIGV4ZWN1dGFibGVzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybVxuIik7CiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0V4ZWMKICovCkJPT0wgV0lOQVBJIE1aX0V4ZWMoIENPTlRFWFQ4NiAqY29udGV4dCwgTFBDU1RSIGZpbGVuYW1lLCBCWVRFIGZ1bmMsIExQVk9JRCBwYXJhbWJsayApCnsKICAvKiBjYW4ndCBoYXBwZW4gKi8KICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0FsbG9jRFBNSVRhc2sKICovCnZvaWQgV0lOQVBJIE1aX0FsbG9jRFBNSVRhc2soIHZvaWQgKQp7CiAgICBFUlIoIkFjdHVhbCByZWFsLW1vZGUgY2FsbHMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIHBsYXRmb3JtIVxuIik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhpdAogKi8Kdm9pZCBXSU5BUEkgTVpfRXhpdCggQ09OVEVYVDg2ICpjb250ZXh0LCBCT09MIGNzX3BzcCwgV09SRCByZXR2YWwgKQp7CiAgRXhpdFRocmVhZCggcmV0dmFsICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQ3VycmVudAogKi8KQk9PTCBXSU5BUEkgTVpfQ3VycmVudCggdm9pZCApCnsKICAgIHJldHVybiBGQUxTRTsKfQoKI2VuZGlmIC8qICFNWl9TVVBQT1JURUQgKi8K