LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICogTm90ZTogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaWZkZWYgSEFWRV9VTklTVERfSAojIGluY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2lmZGVmIEhBVkVfU1lTX1RJTUVfSAojIGluY2x1ZGUgPHN5cy90aW1lLmg+CiNlbmRpZgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc3ZtLmgiCiNpbmNsdWRlICJ2Z2EuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CgojaWZkZWYgTVpfU1VQUE9SVEVECgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBQU1BfU0laRSAweDEwCgojZGVmaW5lIFNFRzE2KHB0cixzZWcpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpKHNlZyk8PDQpKSkKI2RlZmluZSBTRUdQVFIxNihwdHIsc2VncHRyKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKVNFTEVDVE9ST0Yoc2VncHRyKTw8NCkrT0ZGU0VUT0Yoc2VncHRyKSkpCgovKiBzdHJ1Y3R1cmVzIGZvciBFWEVDICovCgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBlbnZfc2VnOwogIERXT1JEIGNtZGxpbmUgV0lORV9QQUNLRUQ7CiAgRFdPUkQgZmNiMSBXSU5FX1BBQ0tFRDsKICBEV09SRCBmY2IyIFdJTkVfUEFDS0VEOwogIFdPUkQgaW5pdF9zcDsKICBXT1JEIGluaXRfc3M7CiAgV09SRCBpbml0X2lwOwogIFdPUkQgaW5pdF9jczsKfSBFeGVjQmxvY2s7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBsb2FkX3NlZzsKICBXT1JEIHJlbF9zZWc7Cn0gT3ZlcmxheUJsb2NrOwoKLyogZ2xvYmFsIHZhcmlhYmxlcyAqLwoKcGlkX3QgZG9zdm1fcGlkOwoKc3RhdGljIFdPUkQgaW5pdF9jcyxpbml0X2lwLGluaXRfc3MsaW5pdF9zcDsKc3RhdGljIEhBTkRMRSBkb3N2bV90aHJlYWQsIGxvb3BfdGhyZWFkOwpzdGF0aWMgRFdPUkQgZG9zdm1fdGlkLCBsb29wX3RpZDsKCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKTsKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCk7CgpzdGF0aWMgdm9pZCBNWl9DcmVhdGVQU1AoIExQVk9JRCBscFBTUCwgV09SRCBlbnYsIFdPUkQgcGFyICkKewogIFBEQjE2KnBzcD1scFBTUDsKCiAgcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogIC8qIHNvbWUgcHJvZ3JhbXMgdXNlIHRoaXMgdG8gY2FsY3VsYXRlIGhvdyBtdWNoIG1lbW9yeSB0aGV5IG5lZWQgKi8KICBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOyAvKiBGSVhNRTogdXNlIGEgcmVhbCB2YWx1ZSAqLwogIC8qIEZJWE1FOiBkaXNwYXRjaGVyICovCiAgcHNwLT5zYXZlZGludDIyID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjIpOwogIHBzcC0+c2F2ZWRpbnQyMyA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIzKTsKICBwc3AtPnNhdmVkaW50MjQgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyNCk7CiAgcHNwLT5wYXJlbnRQU1A9cGFyOwogIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgpzdGF0aWMgdm9pZCBNWl9GaWxsUFNQKCBMUFZPSUQgbHBQU1AsIExQQllURSBjbWRsaW5lLCBpbnQgbGVuZ3RoICkKewogIFBEQjE2ICAgICAgKnBzcCA9IGxwUFNQOwoKICB3aGlsZShsZW5ndGggPiAwICYmICpjbWRsaW5lICE9ICcgJykgewogICAgbGVuZ3RoLS07CiAgICBjbWRsaW5lKys7CiAgfQoKICAvKiBjb21tYW5kLmNvbSBkb2VzIG5vdCBza2lwIG92ZXIgbXVsdGlwbGUgc3BhY2VzICovCgogIGlmKGxlbmd0aCA+IDEyNikgewogICAgRVJSKCJDb21tYW5kIGxpbmUgdHJ1bmNhdGVkISAobGVuZ3RoICVkID4gbWF4aW11bSBsZW5ndGggMTI2KVxuIiwKICAgICAgIGxlbmd0aCk7CiAgICBsZW5ndGggPSAxMjY7CiAgfQoKICBwc3AtPmNtZExpbmVbMF0gPSBsZW5ndGg7CiAgaWYobGVuZ3RoID4gMCkKICAgIG1lbW1vdmUocHNwLT5jbWRMaW5lKzEsIGNtZGxpbmUsIGxlbmd0aCk7CiAgcHNwLT5jbWRMaW5lW2xlbmd0aCsxXSA9ICdccic7CgogIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgovKiBkZWZhdWx0IElOVCAwOCBoYW5kbGVyOiBpbmNyZWFzZXMgdGltZXIgdGljayBjb3VudGVyIGJ1dCBub3QgbXVjaCBtb3JlICovCnN0YXRpYyBjaGFyIGludDA4W109ewogMHhDRCwweDFDLCAgICAgICAgICAgLyogaW50ICQweDFjICovCiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4MUUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkcyAqLwogMHhCOCwweDQwLDB4MDAsICAgICAgLyogbW92dyAkMHg0MCwlYXggKi8KIDB4OEUsMHhEOCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVkcyAqLwojaWYgMAogMHg4MywweDA2LDB4NkMsMHgwMCwweDAxLCAvKiBhZGR3ICQxLCgweDZjKSAqLwogMHg4MywweDE2LDB4NkUsMHgwMCwweDAwLCAvKiBhZGN3ICQwLCgweDZlKSAqLwojZWxzZQogMHg2NiwweEZGLDB4MDYsMHg2QywweDAwLCAvKiBpbmNsICgweDZjKSAqLwojZW5kaWYKIDB4QjAsMHgyMCwgICAgICAgICAgIC8qIG1vdmIgJDB4MjAsJWFsICovCiAweEU2LDB4MjAsICAgICAgICAgICAvKiBvdXRiICVhbCwkMHgyMCAqLwogMHgxRiwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENGICAgICAgICAgICAgICAgICAvKiBpcmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0SGFuZGxlcnModm9pZCkKewogV09SRCBzZWc7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKHNpemVvZihpbnQwOCksJnNlZyk7CiBtZW1jcHkoc3RhcnQsaW50MDgsc2l6ZW9mKGludDA4KSk7Ci8qIElOVCAwODogcG9pbnQgaXQgYXQgb3VyIHRpY2staW5jcmVtZW50aW5nIGhhbmRsZXIgKi8KICgoU0VHUFRSKikwKVsweDA4XT1NQUtFU0VHUFRSKHNlZywwKTsKLyogSU5UIDFDOiBqdXN0IHBvaW50IGl0IHRvIElSRVQsIHdlIGRvbid0IHdhbnQgdG8gaGFuZGxlIGl0IG91cnNlbHZlcyAqLwogKChTRUdQVFIqKTApWzB4MUNdPU1BS0VTRUdQVFIoc2VnLHNpemVvZihpbnQwOCktMSk7Cn0KCnN0YXRpYyBXT1JEIE1aX0luaXRFbnZpcm9ubWVudCggTFBDU1RSIGVudiwgTFBDU1RSIG5hbWUgKQp7CiB1bnNpZ25lZCBzej0wOwogV09SRCBzZWc7CiBMUFNUUiBlbnZibGs7CgogaWYgKGVudikgewogIC8qIGdldCBzaXplIG9mIGVudmlyb25tZW50IGJsb2NrICovCiAgd2hpbGUgKGVudltzeisrXSkgc3orPXN0cmxlbihlbnYrc3opKzE7CiB9IGVsc2Ugc3orKzsKIC8qIGFsbG9jYXRlIGl0ICovCiBlbnZibGs9RE9TTUVNX0dldEJsb2NrKHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSh2b2lkKQp7CiAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKICAgIERPU01FTV9Jbml0KFRSVUUpOwoKICAgIE1aX0luaXRIYW5kbGVycygpOwogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MIE1aX0RvTG9hZEltYWdlKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgT3ZlcmxheUJsb2NrICpvYmxrICkKewogIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiAgQllURSpwc3Bfc3RhcnQsKmxvYWRfc3RhcnQsKm9sZGVudjsKICBpbnQgeCwgb2xkX2NvbT0wLCBhbGxvYzsKICBTRUdQVFIgcmVsb2M7CiAgV09SRCBlbnZfc2VnLCBsb2FkX3NlZywgcmVsX3NlZywgb2xkcHNwX3NlZzsKICBEV09SRCBsZW47CgogIGlmIChET1NWTV9wc3ApIHsKICAgIC8qIERPUyBwcm9jZXNzIGFscmVhZHkgcnVubmluZywgaW5oZXJpdCBmcm9tIGl0ICovCiAgICBQREIxNiogcGFyX3BzcCA9IChQREIxNiopKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICBhbGxvYz0wOwogICAgb2xkZW52ID0gKExQQllURSkoKERXT1JEKXBhcl9wc3AtPmVudmlyb25tZW50IDw8IDQpOwogICAgb2xkcHNwX3NlZyA9IERPU1ZNX3BzcDsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgbmV3IERPUyBwcm9jZXNzLCBpbmhlcml0aW5nIGZyb20gV2luZSBlbnZpcm9ubWVudCAqLwogICAgYWxsb2M9MTsKICAgIG9sZGVudiA9IEdldEVudmlyb25tZW50U3RyaW5nc0EoKTsKICAgIG9sZHBzcF9zZWcgPSAwOwogIH0KCiBTZXRGaWxlUG9pbnRlcihoRmlsZSwwLE5VTEwsRklMRV9CRUdJTik7CiBpZiAoICAgIVJlYWRGaWxlKGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlciksJmxlbixOVUxMKQogICAgIHx8IGxlbiAhPSBzaXplb2YobXpfaGVhZGVyKQogICAgIHx8IG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpIHsKICBjaGFyICpwID0gc3RycmNociggZmlsZW5hbWUsICcuJyApOwogIGlmICghcCB8fCBzdHJjYXNlY21wKCBwLCAiLmNvbSIgKSkgIC8qIGNoZWNrIGZvciAuQ09NIGV4dGVuc2lvbiAqLwogIHsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgfQogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKICBpZiAoYWxsb2MpIE1aX0luaXRNZW1vcnkoKTsKCiAgaWYgKG9ibGspIHsKICAgIC8qIGxvYWQgb3ZlcmxheSBpbnRvIHByZWFsbG9jYXRlZCBtZW1vcnkgKi8KICAgIGxvYWRfc2VnPW9ibGstPmxvYWRfc2VnOwogICAgcmVsX3NlZz1vYmxrLT5yZWxfc2VnOwogICAgbG9hZF9zdGFydD0oTFBCWVRFKSgoRFdPUkQpbG9hZF9zZWc8PDQpOwogIH0gZWxzZSB7CiAgICAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogICAgZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQob2xkZW52LCBmaWxlbmFtZSk7CgogICAgLyogYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgZXhlY3V0YWJsZSAqLwogICAgVFJBQ0UoIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogICAgYXZhaWw9RE9TTUVNX0F2YWlsYWJsZSgpOwogICAgaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgICAgIEVSUigiaW5zdWZmaWNpZW50IERPUyBtZW1vcnlcbiIpOwogICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgICB9CiAgICBpZiAoYXZhaWw+bWF4X3NpemUpIGF2YWlsPW1heF9zaXplOwogICAgcHNwX3N0YXJ0PURPU01FTV9HZXRCbG9jayhhdmFpbCwmRE9TVk1fcHNwKTsKICAgIGlmICghcHNwX3N0YXJ0KSB7CiAgICAgIEVSUigiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgbG9hZF9zZWc9RE9TVk1fcHNwKyhvbGRfY29tPzA6UFNQX1NJWkUpOwogICAgcmVsX3NlZz1sb2FkX3NlZzsKICAgIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiAgICBNWl9DcmVhdGVQU1AocHNwX3N0YXJ0LCBlbnZfc2VnLCBvbGRwc3Bfc2VnKTsKICB9CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRSgibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBTZXRGaWxlUG9pbnRlcihoRmlsZSxpbWFnZV9zdGFydCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCFSZWFkRmlsZShoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUsJmxlbixOVUxMKSB8fCBsZW4gIT0gaW1hZ2Vfc2l6ZSkgewogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICBnb3RvIGxvYWRfZXJyb3I7CiB9CgogaWYgKG16X2hlYWRlci5lX2NybGMpIHsKICAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KICBUUkFDRSgibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfY3JsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBTZXRGaWxlUG9pbnRlcihoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsTlVMTCxGSUxFX0JFR0lOKTsKICBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICAgaWYgKCFSZWFkRmlsZShoRmlsZSwmcmVsb2Msc2l6ZW9mKHJlbG9jKSwmbGVuLE5VTEwpIHx8IGxlbiAhPSBzaXplb2YocmVsb2MpKSB7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgICBnb3RvIGxvYWRfZXJyb3I7CiAgIH0KICAgKihXT1JEKilTRUdQVFIxNihsb2FkX3N0YXJ0LHJlbG9jKSs9cmVsX3NlZzsKICB9CiB9CgogIGlmICghb2JsaykgewogICAgaW5pdF9jcyA9IGxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogICAgaW5pdF9pcCA9IG16X2hlYWRlci5lX2lwOwogICAgaW5pdF9zcyA9IGxvYWRfc2VnK216X2hlYWRlci5lX3NzOwogICAgaW5pdF9zcCA9IG16X2hlYWRlci5lX3NwOwoKICAgIFRSQUNFKCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGluaXRfY3MsaW5pdF9pcCk7CiAgfQoKICBpZiAoYWxsb2MgJiYgIU1aX0luaXRUYXNrKCkpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9HRU5fRkFJTFVSRSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICByZXR1cm4gVFJVRTsKCmxvYWRfZXJyb3I6CiAgRE9TVk1fcHNwID0gb2xkcHNwX3NlZzsKCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUxvYWREb3NFeGUgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIE1aX0xvYWRJbWFnZSggTFBDU1RSIGZpbGVuYW1lLCBIQU5ETEUgaEZpbGUgKQp7CiAgaWYgKE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIE5VTEwgKSkgTVpfTGF1bmNoKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhlYwogKi8KQk9PTCBXSU5BUEkgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIC8qIHRoaXMgbWF5IG9ubHkgYmUgY2FsbGVkIGZyb20gZXhpc3RpbmcgRE9TIHByb2Nlc3NlcwogICAqIChpLmUuIG9uZSBET1MgYXBwIHNwYXduaW5nIGFub3RoZXIpICovCiAgLyogRklYTUU6IGRvIHdlIHdhbnQgdG8gY2hlY2sgYmluYXJ5IHR5cGUgZmlyc3QsIHRvIGNoZWNrCiAgICogd2hldGhlciBpdCdzIGEgTkUvUEUgZXhlY3V0YWJsZT8gKi8KICBIQU5ETEUgaEZpbGUgPSBDcmVhdGVGaWxlQSggZmlsZW5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELAoJCQkgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIDApOwogIEJPT0wgcmV0ID0gRkFMU0U7CiAgaWYgKGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSByZXR1cm4gRkFMU0U7CiAgc3dpdGNoIChmdW5jKSB7CiAgY2FzZSAwOiAvKiBsb2FkIGFuZCBleGVjdXRlICovCiAgY2FzZSAxOiAvKiBsb2FkIGJ1dCBkb24ndCBleGVjdXRlICovCiAgICB7CiAgICAgIC8qIHNhdmUgY3VycmVudCBwcm9jZXNzJ3MgcmV0dXJuIFNTOlNQIG5vdyAqLwogICAgICBMUEJZVEUgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKURPU1ZNX3BzcCA8PCA0KTsKICAgICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgcHNwLT5zYXZlU3RhY2sgPSAoRFdPUkQpTUFLRVNFR1BUUihjb250ZXh0LT5TZWdTcywgTE9XT1JEKGNvbnRleHQtPkVzcCkpOwogICAgfQogICAgcmV0ID0gTVpfRG9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgTlVMTCApOwogICAgaWYgKHJldCkgewogICAgICAvKiBNWl9Mb2FkSW1hZ2UgY3JlYXRlZCBhIG5ldyBQU1AgYW5kIGxvYWRlZCBuZXcgdmFsdWVzIGludG8gaXQsCiAgICAgICAqIGxldCdzIHdvcmsgb24gdGhlIG5ldyB2YWx1ZXMgbm93ICovCiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICBFeGVjQmxvY2sgKmJsayA9IChFeGVjQmxvY2sgKilwYXJhbWJsazsKICAgICAgTFBCWVRFIGNtZGxpbmUgPSBQVFJfUkVBTF9UT19MSU4oU0VMRUNUT1JPRihibGstPmNtZGxpbmUpLE9GRlNFVE9GKGJsay0+Y21kbGluZSkpOwoKICAgICAgLyogRmlyc3QgY2hhcmFjdGVyIGNvbnRhaW5zIHRoZSBsZW5ndGggb2YgdGhlIGNvbW1hbmQgbGluZS4gKi8KICAgICAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIGNtZGxpbmUgKyAxLCBjbWRsaW5lWzBdKTsKCiAgICAgIC8qIHRoZSBsYW1lIE1TLURPUyBlbmdpbmVlcnMgZGVjaWRlZCB0aGF0IHRoZSByZXR1cm4gYWRkcmVzcyBzaG91bGQgYmUgaW4gaW50MjIgKi8KICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjIsIChGQVJQUk9DMTYpTUFLRVNFR1BUUihjb250ZXh0LT5TZWdDcywgTE9XT1JEKGNvbnRleHQtPkVpcCkpKTsKICAgICAgaWYgKGZ1bmMpIHsKCS8qIGRvbid0IGV4ZWN1dGUsIGp1c3QgcmV0dXJuIHN0YXJ0dXAgc3RhdGUgKi8KCWJsay0+aW5pdF9jcyA9IGluaXRfY3M7CglibGstPmluaXRfaXAgPSBpbml0X2lwOwoJYmxrLT5pbml0X3NzID0gaW5pdF9zczsKCWJsay0+aW5pdF9zcCA9IGluaXRfc3A7CiAgICAgIH0gZWxzZSB7CgkvKiBleGVjdXRlIGJ5IG1ha2luZyB1cyByZXR1cm4gdG8gbmV3IHByb2Nlc3MgKi8KCWNvbnRleHQtPlNlZ0NzID0gaW5pdF9jczsKCWNvbnRleHQtPkVpcCAgID0gaW5pdF9pcDsKCWNvbnRleHQtPlNlZ1NzID0gaW5pdF9zczsKCWNvbnRleHQtPkVzcCAgID0gaW5pdF9zcDsKCWNvbnRleHQtPlNlZ0RzID0gRE9TVk1fcHNwOwoJY29udGV4dC0+U2VnRXMgPSBET1NWTV9wc3A7Cgljb250ZXh0LT5FYXggICA9IDA7CiAgICAgIH0KICAgIH0KICAgIGJyZWFrOwogIGNhc2UgMzogLyogbG9hZCBvdmVybGF5ICovCiAgICB7CiAgICAgIE92ZXJsYXlCbG9jayAqYmxrID0gKE92ZXJsYXlCbG9jayAqKXBhcmFtYmxrOwogICAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBibGsgKTsKICAgIH0KICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBGSVhNRSgiRVhFQyBsb2FkIHR5cGUgJWQgbm90IGltcGxlbWVudGVkXG4iLCBmdW5jKTsKICAgIFNldExhc3RFcnJvcihFUlJPUl9JTlZBTElEX0ZVTkNUSU9OKTsKICAgIGJyZWFrOwogIH0KICBDbG9zZUhhbmRsZShoRmlsZSk7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9BbGxvY0RQTUlUYXNrCiAqLwp2b2lkIFdJTkFQSSBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogIE1aX0luaXRNZW1vcnkoKTsKICBNWl9Jbml0VGFzaygpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX1J1bkluVGhyZWFkCiAqLwp2b2lkIFdJTkFQSSBNWl9SdW5JblRocmVhZCggUEFQQ0ZVTkMgcHJvYywgVUxPTkdfUFRSIGFyZyApCnsKICBpZiAobG9vcF90aHJlYWQpIHsKICAgIERPU19TUEMgc3BjOwogICAgSEFORExFIGV2ZW50OwoKICAgIHNwYy5wcm9jID0gcHJvYzsKICAgIHNwYy5hcmcgPSBhcmc7CiAgICBldmVudCA9IENyZWF0ZUV2ZW50QShOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICBQb3N0VGhyZWFkTWVzc2FnZUEobG9vcF90aWQsIFdNX1VTRVIsIGV2ZW50LCAoTFBBUkFNKSZzcGMpOwogICAgV2FpdEZvclNpbmdsZU9iamVjdChldmVudCwgSU5GSU5JVEUpOwogICAgQ2xvc2VIYW5kbGUoZXZlbnQpOwogIH0gZWxzZQogICAgcHJvYyhhcmcpOwp9CgpzdGF0aWMgRFdPUkQgV0lOQVBJIE1aX0RPU1ZNKCBMUFZPSUQgbHBFeHRyYSApCnsKICBDT05URVhUIGNvbnRleHQ7CiAgRFdPUkQgcmV0OwoKICBkb3N2bV9waWQgPSBnZXRwaWQoKTsKCiAgbWVtc2V0KCAmY29udGV4dCwgMCwgc2l6ZW9mKGNvbnRleHQpICk7CiAgY29udGV4dC5TZWdDcyAgPSBpbml0X2NzOwogIGNvbnRleHQuRWlwICAgID0gaW5pdF9pcDsKICBjb250ZXh0LlNlZ1NzICA9IGluaXRfc3M7CiAgY29udGV4dC5Fc3AgICAgPSBpbml0X3NwOwogIGNvbnRleHQuU2VnRHMgID0gRE9TVk1fcHNwOwogIGNvbnRleHQuU2VnRXMgID0gRE9TVk1fcHNwOwogIGNvbnRleHQuRUZsYWdzID0gMHgwMDA4MDAwMDsgIC8qIHZpcnR1YWwgaW50ZXJydXB0IGZsYWcgKi8KICBET1NWTV9TZXRUaW1lcigweDEwMDAwKTsKICByZXQgPSBET1NWTV9FbnRlciggJmNvbnRleHQgKTsKCiAgZG9zdm1fcGlkID0gMDsKICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgQk9PTCBNWl9Jbml0VGFzayh2b2lkKQp7CiAgaWYgKCFEdXBsaWNhdGVIYW5kbGUoR2V0Q3VycmVudFByb2Nlc3MoKSwgR2V0Q3VycmVudFRocmVhZCgpLAogICAgICAgICAgICAgICAgICAgICAgIEdldEN1cnJlbnRQcm9jZXNzKCksICZsb29wX3RocmVhZCwKICAgICAgICAgICAgICAgICAgICAgICAwLCBGQUxTRSwgRFVQTElDQVRFX1NBTUVfQUNDRVNTKSkKICAgIHJldHVybiBGQUxTRTsKICBkb3N2bV90aHJlYWQgPSBDcmVhdGVUaHJlYWQoTlVMTCwgMCwgTVpfRE9TVk0sIE5VTEwsIENSRUFURV9TVVNQRU5ERUQsICZkb3N2bV90aWQpOwogIGlmICghZG9zdm1fdGhyZWFkKSB7CiAgICBDbG9zZUhhbmRsZShsb29wX3RocmVhZCk7CiAgICBsb29wX3RocmVhZCA9IDA7CiAgICByZXR1cm4gRkFMU0U7CiAgfQogIGxvb3BfdGlkID0gR2V0Q3VycmVudFRocmVhZElkKCk7CiAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKQp7CiAgVERCICpwVGFzayA9IFRBU0tfR2V0UHRyKCBHZXRDdXJyZW50VGFzaygpICk7CiAgQllURSAqcHNwX3N0YXJ0ID0gUFRSX1JFQUxfVE9fTElOKCBET1NWTV9wc3AsIDAgKTsKICBMUFNUUiBjbWRsaW5lID0gR2V0Q29tbWFuZExpbmVBKCk7CiAgRFdPUkQgcnY7CiAgU1lTTEVWRUwgKmxvY2s7CgogIE1aX0ZpbGxQU1AocHNwX3N0YXJ0LCBjbWRsaW5lLCBjbWRsaW5lID8gc3RybGVuKGNtZGxpbmUpIDogMCk7CiAgcFRhc2stPmZsYWdzIHw9IFREQkZfV0lOT0xEQVA7CgogIEdldHBXaW4xNkxvY2soICZsb2NrICk7CiAgX0xlYXZlU3lzTGV2ZWwoIGxvY2sgKTsKCiAgUmVzdW1lVGhyZWFkKGRvc3ZtX3RocmVhZCk7CiAgcnYgPSBET1NWTV9Mb29wKGRvc3ZtX3RocmVhZCk7CgogIENsb3NlSGFuZGxlKGRvc3ZtX3RocmVhZCk7CiAgZG9zdm1fdGhyZWFkID0gMDsgZG9zdm1fdGlkID0gMDsKICBDbG9zZUhhbmRsZShsb29wX3RocmVhZCk7CiAgbG9vcF90aHJlYWQgPSAwOyBsb29wX3RpZCA9IDA7CgogIFZHQV9DbGVhbigpOwogIEV4aXRUaHJlYWQocnYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0V4aXQKICovCnZvaWQgV0lOQVBJIE1aX0V4aXQoIENPTlRFWFQ4NiAqY29udGV4dCwgQk9PTCBjc19wc3AsIFdPUkQgcmV0dmFsICkKewogIGlmIChET1NWTV9wc3ApIHsKICAgIFdPUkQgcHNwX3NlZyA9IGNzX3BzcCA/IGNvbnRleHQtPlNlZ0NzIDogRE9TVk1fcHNwOwogICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClwc3Bfc2VnIDw8IDQpOwogICAgUERCMTYgKnBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgIFdPUkQgcGFycHNwID0gcHNwLT5wYXJlbnRQU1A7IC8qIGNoZWNrIGZvciBwYXJlbnQgRE9TIHByb2Nlc3MgKi8KICAgIGlmIChwYXJwc3ApIHsKICAgICAgLyogcmV0cmlldmUgcGFyZW50J3MgcmV0dXJuIGFkZHJlc3MgKi8KICAgICAgRkFSUFJPQzE2IHJldGFkZHIgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyMik7CiAgICAgIC8qIHJlc3RvcmUgaW50ZXJydXB0cyAqLwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyMiwgcHNwLT5zYXZlZGludDIyKTsKICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjMsIHBzcC0+c2F2ZWRpbnQyMyk7CiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDI0LCBwc3AtPnNhdmVkaW50MjQpOwogICAgICAvKiBGSVhNRTogZGVhbGxvY2F0ZSBmaWxlIGhhbmRsZXMgZXRjICovCiAgICAgIC8qIGZyZWUgcHJvY2VzcydzIGFzc29jaWF0ZWQgbWVtb3J5CiAgICAgICAqIEZJWE1FOiB3YWxrIG1lbW9yeSBhbmQgZGVhbGxvY2F0ZSBhbGwgYmxvY2tzIG93bmVkIGJ5IHByb2Nlc3MgKi8KICAgICAgRE9TTUVNX0ZyZWVCbG9jayggUFRSX1JFQUxfVE9fTElOKHBzcC0+ZW52aXJvbm1lbnQsMCkgKTsKICAgICAgRE9TTUVNX0ZyZWVCbG9jayggUFRSX1JFQUxfVE9fTElOKERPU1ZNX3BzcCwwKSApOwogICAgICAvKiBzd2l0Y2ggdG8gcGFyZW50J3MgUFNQICovCiAgICAgIERPU1ZNX3BzcCA9IHBhcnBzcDsKICAgICAgcHNwX3N0YXJ0ID0gKExQQllURSkoKERXT1JEKXBhcnBzcCA8PCA0KTsKICAgICAgcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgICAvKiBub3cgcmV0dXJuIHRvIHBhcmVudCAqLwogICAgICBET1NWTV9yZXR2YWwgPSByZXR2YWw7CiAgICAgIGNvbnRleHQtPlNlZ0NzID0gU0VMRUNUT1JPRihyZXRhZGRyKTsKICAgICAgY29udGV4dC0+RWlwICAgPSBPRkZTRVRPRihyZXRhZGRyKTsKICAgICAgY29udGV4dC0+U2VnU3MgPSBTRUxFQ1RPUk9GKHBzcC0+c2F2ZVN0YWNrKTsKICAgICAgY29udGV4dC0+RXNwICAgPSBPRkZTRVRPRihwc3AtPnNhdmVTdGFjayk7CiAgICAgIHJldHVybjsKICAgIH0gZWxzZQogICAgICBUUkFDRSgia2lsbGluZyBET1MgdGFza1xuIik7CiAgfQogIEV4aXRUaHJlYWQoIHJldHZhbCApOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9DdXJyZW50CiAqLwpCT09MIFdJTkFQSSBNWl9DdXJyZW50KCB2b2lkICkKewogIHJldHVybiAoZG9zdm1fcGlkICE9IDApOyAvKiBGSVhNRTogZG8gYSBiZXR0ZXIgY2hlY2sgKi8KfQoKI2Vsc2UgLyogIU1aX1NVUFBPUlRFRCAqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlMb2FkRG9zRXhlIChXSU5FRE9TLkApCiAqLwp2b2lkIFdJTkFQSSBNWl9Mb2FkSW1hZ2UoIExQQ1NUUiBmaWxlbmFtZSwgSEFORExFIGhGaWxlICkKewogIFdBUk4oIkRPUyBleGVjdXRhYmxlcyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm1cbiIpOwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGVjCiAqLwpCT09MIFdJTkFQSSBNWl9FeGVjKCBDT05URVhUODYgKmNvbnRleHQsIExQQ1NUUiBmaWxlbmFtZSwgQllURSBmdW5jLCBMUFZPSUQgcGFyYW1ibGsgKQp7CiAgLyogY2FuJ3QgaGFwcGVuICovCiAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9BbGxvY0RQTUlUYXNrCiAqLwp2b2lkIFdJTkFQSSBNWl9BbGxvY0RQTUlUYXNrKCB2b2lkICkKewogICAgRVJSKCJBY3R1YWwgcmVhbC1tb2RlIGNhbGxzIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybSFcbiIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0V4aXQKICovCnZvaWQgV0lOQVBJIE1aX0V4aXQoIENPTlRFWFQ4NiAqY29udGV4dCwgQk9PTCBjc19wc3AsIFdPUkQgcmV0dmFsICkKewogIEV4aXRUaHJlYWQoIHJldHZhbCApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCU1aX0N1cnJlbnQKICovCkJPT0wgV0lOQVBJIE1aX0N1cnJlbnQoIHZvaWQgKQp7CiAgICByZXR1cm4gRkFMU0U7Cn0KCiNlbmRpZiAvKiAhTVpfU1VQUE9SVEVEICovCg==