LyoKICogRE9TIChNWikgbG9hZGVyCiAqCiAqIENvcHlyaWdodCAxOTk4IE92ZSBL5XZlbgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICoKICogTm90ZTogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHNpZ25hbC5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdGltZS5oPgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW9kdWxlLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJtaXNjZW11LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc3ZtLmgiCiNpbmNsdWRlICJ2Z2EuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG1vZHVsZSk7CgojaWZkZWYgTVpfU1VQUE9SVEVECgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiMgaW5jbHVkZSA8c3lzL21tYW4uaD4KI2VuZGlmCgovKiBkZWZpbmUgdGhpcyB0byB0cnkgbWFwcGluZyB0aHJvdWdoIC9wcm9jL3BpZC9tZW0gaW5zdGVhZCBvZiBhIHRlbXAgZmlsZSwKICAgYnV0IExpbnVzIGRvZXNuJ3QgbGlrZSBtbWFwcGluZyAvcHJvYy9waWQvbWVtLCBzbyBpdCBkb2Vzbid0IHdvcmsgZm9yIG1lICovCiN1bmRlZiBNWl9NQVBTRUxGCgojZGVmaW5lIEJJT1NfREFUQV9TRUdNRU5UIDB4NDAKI2RlZmluZSBQU1BfU0laRSAweDEwCgojZGVmaW5lIFNFRzE2KHB0cixzZWcpICgoTFBWT0lEKSgoQllURSopcHRyKygoRFdPUkQpKHNlZyk8PDQpKSkKI2RlZmluZSBTRUdQVFIxNihwdHIsc2VncHRyKSAoKExQVk9JRCkoKEJZVEUqKXB0cisoKERXT1JEKVNFTEVDVE9ST0Yoc2VncHRyKTw8NCkrT0ZGU0VUT0Yoc2VncHRyKSkpCgovKiBzdHJ1Y3R1cmVzIGZvciBFWEVDICovCgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBlbnZfc2VnOwogIERXT1JEIGNtZGxpbmUgV0lORV9QQUNLRUQ7CiAgRFdPUkQgZmNiMSBXSU5FX1BBQ0tFRDsKICBEV09SRCBmY2IyIFdJTkVfUEFDS0VEOwogIFdPUkQgaW5pdF9zcDsKICBXT1JEIGluaXRfc3M7CiAgV09SRCBpbml0X2lwOwogIFdPUkQgaW5pdF9jczsKfSBFeGVjQmxvY2s7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgV09SRCBsb2FkX3NlZzsKICBXT1JEIHJlbF9zZWc7Cn0gT3ZlcmxheUJsb2NrOwoKLyogZ2xvYmFsIHZhcmlhYmxlcyAqLwoKcGlkX3QgZG9zdm1fcGlkOwoKc3RhdGljIFdPUkQgaW5pdF9jcyxpbml0X2lwLGluaXRfc3MsaW5pdF9zcDsKc3RhdGljIEhBTkRMRSBkb3N2bV90aHJlYWQsIGxvb3BfdGhyZWFkOwpzdGF0aWMgRFdPUkQgZG9zdm1fdGlkLCBsb29wX3RpZDsKCnN0YXRpYyB2b2lkIE1aX0xhdW5jaCh2b2lkKTsKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCk7CgpzdGF0aWMgdm9pZCBNWl9DcmVhdGVQU1AoIExQVk9JRCBscFBTUCwgV09SRCBlbnYsIFdPUkQgcGFyICkKewogIFBEQjE2KnBzcD1scFBTUDsKCiAgcHNwLT5pbnQyMD0weDIwQ0Q7IC8qIGludCAyMCAqLwogIC8qIHNvbWUgcHJvZ3JhbXMgdXNlIHRoaXMgdG8gY2FsY3VsYXRlIGhvdyBtdWNoIG1lbW9yeSB0aGV5IG5lZWQgKi8KICBwc3AtPm5leHRQYXJhZ3JhcGg9MHg5RkZGOyAvKiBGSVhNRTogdXNlIGEgcmVhbCB2YWx1ZSAqLwogIC8qIEZJWE1FOiBkaXNwYXRjaGVyICovCiAgcHNwLT5zYXZlZGludDIyID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjIpOwogIHBzcC0+c2F2ZWRpbnQyMyA9IERPU1ZNX0dldFJNSGFuZGxlcigweDIzKTsKICBwc3AtPnNhdmVkaW50MjQgPSBET1NWTV9HZXRSTUhhbmRsZXIoMHgyNCk7CiAgcHNwLT5wYXJlbnRQU1A9cGFyOwogIHBzcC0+ZW52aXJvbm1lbnQ9ZW52OwogIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgpzdGF0aWMgdm9pZCBNWl9GaWxsUFNQKCBMUFZPSUQgbHBQU1AsIExQQllURSBjbWRsaW5lLCBpbnQgbGVuZ3RoICkKewogIFBEQjE2ICAgICAgKnBzcCA9IGxwUFNQOwoKICB3aGlsZShsZW5ndGggPiAwICYmICpjbWRsaW5lICE9ICcgJykgewogICAgbGVuZ3RoLS07CiAgICBjbWRsaW5lKys7CiAgfQoKICAvKiBjb21tYW5kLmNvbSBkb2VzIG5vdCBza2lwIG92ZXIgbXVsdGlwbGUgc3BhY2VzICovCgogIGlmKGxlbmd0aCA+IDEyNikgewogICAgRVJSKCJDb21tYW5kIGxpbmUgdHJ1bmNhdGVkISAobGVuZ3RoICVkID4gbWF4aW11bSBsZW5ndGggMTI2KVxuIiwKICAgICAgIGxlbmd0aCk7CiAgICBsZW5ndGggPSAxMjY7CiAgfQoKICBwc3AtPmNtZExpbmVbMF0gPSBsZW5ndGg7CiAgaWYobGVuZ3RoID4gMCkKICAgIG1lbW1vdmUocHNwLT5jbWRMaW5lKzEsIGNtZGxpbmUsIGxlbmd0aCk7CiAgcHNwLT5jbWRMaW5lW2xlbmd0aCsxXSA9ICdccic7CgogIC8qIEZJWE1FOiBtb3JlIFBTUCBzdHVmZiAqLwp9CgovKiBkZWZhdWx0IElOVCAwOCBoYW5kbGVyOiBpbmNyZWFzZXMgdGltZXIgdGljayBjb3VudGVyIGJ1dCBub3QgbXVjaCBtb3JlICovCnN0YXRpYyBjaGFyIGludDA4W109ewogMHhDRCwweDFDLCAgICAgICAgICAgLyogaW50ICQweDFjICovCiAweDUwLCAgICAgICAgICAgICAgICAvKiBwdXNodyAlYXggKi8KIDB4MUUsICAgICAgICAgICAgICAgIC8qIHB1c2h3ICVkcyAqLwogMHhCOCwweDQwLDB4MDAsICAgICAgLyogbW92dyAkMHg0MCwlYXggKi8KIDB4OEUsMHhEOCwgICAgICAgICAgIC8qIG1vdncgJWF4LCVkcyAqLwojaWYgMAogMHg4MywweDA2LDB4NkMsMHgwMCwweDAxLCAvKiBhZGR3ICQxLCgweDZjKSAqLwogMHg4MywweDE2LDB4NkUsMHgwMCwweDAwLCAvKiBhZGN3ICQwLCgweDZlKSAqLwojZWxzZQogMHg2NiwweEZGLDB4MDYsMHg2QywweDAwLCAvKiBpbmNsICgweDZjKSAqLwojZW5kaWYKIDB4QjAsMHgyMCwgICAgICAgICAgIC8qIG1vdmIgJDB4MjAsJWFsICovCiAweEU2LDB4MjAsICAgICAgICAgICAvKiBvdXRiICVhbCwkMHgyMCAqLwogMHgxRiwgICAgICAgICAgICAgICAgLyogcG9wdyAlYXggKi8KIDB4NTgsICAgICAgICAgICAgICAgIC8qIHBvcHcgJWF4ICovCiAweENGICAgICAgICAgICAgICAgICAvKiBpcmV0ICovCn07CgpzdGF0aWMgdm9pZCBNWl9Jbml0SGFuZGxlcnModm9pZCkKewogV09SRCBzZWc7CiBMUEJZVEUgc3RhcnQ9RE9TTUVNX0dldEJsb2NrKHNpemVvZihpbnQwOCksJnNlZyk7CiBtZW1jcHkoc3RhcnQsaW50MDgsc2l6ZW9mKGludDA4KSk7Ci8qIElOVCAwODogcG9pbnQgaXQgYXQgb3VyIHRpY2staW5jcmVtZW50aW5nIGhhbmRsZXIgKi8KICgoU0VHUFRSKikwKVsweDA4XT1NQUtFU0VHUFRSKHNlZywwKTsKLyogSU5UIDFDOiBqdXN0IHBvaW50IGl0IHRvIElSRVQsIHdlIGRvbid0IHdhbnQgdG8gaGFuZGxlIGl0IG91cnNlbHZlcyAqLwogKChTRUdQVFIqKTApWzB4MUNdPU1BS0VTRUdQVFIoc2VnLHNpemVvZihpbnQwOCktMSk7Cn0KCnN0YXRpYyBXT1JEIE1aX0luaXRFbnZpcm9ubWVudCggTFBDU1RSIGVudiwgTFBDU1RSIG5hbWUgKQp7CiB1bnNpZ25lZCBzej0wOwogV09SRCBzZWc7CiBMUFNUUiBlbnZibGs7CgogaWYgKGVudikgewogIC8qIGdldCBzaXplIG9mIGVudmlyb25tZW50IGJsb2NrICovCiAgd2hpbGUgKGVudltzeisrXSkgc3orPXN0cmxlbihlbnYrc3opKzE7CiB9IGVsc2Ugc3orKzsKIC8qIGFsbG9jYXRlIGl0ICovCiBlbnZibGs9RE9TTUVNX0dldEJsb2NrKHN6K3NpemVvZihXT1JEKStzdHJsZW4obmFtZSkrMSwmc2VnKTsKIC8qIGZpbGwgaXQgKi8KIGlmIChlbnYpIHsKICBtZW1jcHkoZW52YmxrLGVudixzeik7CiB9IGVsc2UgZW52YmxrWzBdPTA7CiAvKiBET1MgMy54OiB0aGUgYmxvY2sgY29udGFpbnMgMSBhZGRpdGlvbmFsIHN0cmluZyAqLwogKihXT1JEKikoZW52YmxrK3N6KT0xOwogLyogYmVpbmcgdGhlIHByb2dyYW0gbmFtZSBpdHNlbGYgKi8KIHN0cmNweShlbnZibGsrc3orc2l6ZW9mKFdPUkQpLG5hbWUpOwogcmV0dXJuIHNlZzsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdE1lbW9yeSh2b2lkKQp7CiAgICAvKiBpbml0aWFsaXplIHRoZSBtZW1vcnkgKi8KICAgIFRSQUNFKCJJbml0aWFsaXppbmcgRE9TIG1lbW9yeSBzdHJ1Y3R1cmVzXG4iKTsKICAgIERPU01FTV9Jbml0KFRSVUUpOwoKICAgIE1aX0luaXRIYW5kbGVycygpOwogICAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBCT09MIE1aX0RvTG9hZEltYWdlKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgT3ZlcmxheUJsb2NrICpvYmxrICkKewogIElNQUdFX0RPU19IRUFERVIgbXpfaGVhZGVyOwogIERXT1JEIGltYWdlX3N0YXJ0LGltYWdlX3NpemUsbWluX3NpemUsbWF4X3NpemUsYXZhaWw7CiAgQllURSpwc3Bfc3RhcnQsKmxvYWRfc3RhcnQsKm9sZGVudjsKICBpbnQgeCwgb2xkX2NvbT0wLCBhbGxvYzsKICBTRUdQVFIgcmVsb2M7CiAgV09SRCBlbnZfc2VnLCBsb2FkX3NlZywgcmVsX3NlZywgb2xkcHNwX3NlZzsKICBEV09SRCBsZW47CgogIGlmIChET1NWTV9wc3ApIHsKICAgIC8qIERPUyBwcm9jZXNzIGFscmVhZHkgcnVubmluZywgaW5oZXJpdCBmcm9tIGl0ICovCiAgICBQREIxNiogcGFyX3BzcCA9IChQREIxNiopKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICBhbGxvYz0wOwogICAgb2xkZW52ID0gKExQQllURSkoKERXT1JEKXBhcl9wc3AtPmVudmlyb25tZW50IDw8IDQpOwogICAgb2xkcHNwX3NlZyA9IERPU1ZNX3BzcDsKICB9IGVsc2UgewogICAgLyogYWxsb2NhdGUgbmV3IERPUyBwcm9jZXNzLCBpbmhlcml0aW5nIGZyb20gV2luZSBlbnZpcm9ubWVudCAqLwogICAgYWxsb2M9MTsKICAgIG9sZGVudiA9IEdldEVudmlyb25tZW50U3RyaW5nc0EoKTsKICAgIG9sZHBzcF9zZWcgPSAwOwogIH0KCiBTZXRGaWxlUG9pbnRlcihoRmlsZSwwLE5VTEwsRklMRV9CRUdJTik7CiBpZiAoICAgIVJlYWRGaWxlKGhGaWxlLCZtel9oZWFkZXIsc2l6ZW9mKG16X2hlYWRlciksJmxlbixOVUxMKQogICAgIHx8IGxlbiAhPSBzaXplb2YobXpfaGVhZGVyKQogICAgIHx8IG16X2hlYWRlci5lX21hZ2ljICE9IElNQUdFX0RPU19TSUdOQVRVUkUpIHsKICBjaGFyICpwID0gc3RycmNociggZmlsZW5hbWUsICcuJyApOwogIGlmICghcCB8fCBzdHJjYXNlY21wKCBwLCAiLmNvbSIgKSkgIC8qIGNoZWNrIGZvciAuQ09NIGV4dGVuc2lvbiAqLwogIHsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX0JBRF9GT1JNQVQpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgfQogIG9sZF9jb209MTsgLyogYXNzdW1lIC5DT00gZmlsZSAqLwogIGltYWdlX3N0YXJ0PTA7CiAgaW1hZ2Vfc2l6ZT1HZXRGaWxlU2l6ZShoRmlsZSxOVUxMKTsKICBtaW5fc2l6ZT0weDEwMDAwOyBtYXhfc2l6ZT0weDEwMDAwMDsKICBtel9oZWFkZXIuZV9jcmxjPTA7CiAgbXpfaGVhZGVyLmVfc3M9MDsgbXpfaGVhZGVyLmVfc3A9MHhGRkZFOwogIG16X2hlYWRlci5lX2NzPTA7IG16X2hlYWRlci5lX2lwPTB4MTAwOwogfSBlbHNlIHsKICAvKiBjYWxjdWxhdGUgbG9hZCBzaXplICovCiAgaW1hZ2Vfc3RhcnQ9bXpfaGVhZGVyLmVfY3Bhcmhkcjw8NDsKICBpbWFnZV9zaXplPW16X2hlYWRlci5lX2NwPDw5OyAvKiBwYWdlcyBhcmUgNTEyIGJ5dGVzICovCiAgaWYgKChtel9oZWFkZXIuZV9jYmxwIT0wKSYmKG16X2hlYWRlci5lX2NibHAhPTQpKSBpbWFnZV9zaXplLT01MTItbXpfaGVhZGVyLmVfY2JscDsKICBpbWFnZV9zaXplLT1pbWFnZV9zdGFydDsKICBtaW5fc2l6ZT1pbWFnZV9zaXplKygoRFdPUkQpbXpfaGVhZGVyLmVfbWluYWxsb2M8PDQpKyhQU1BfU0laRTw8NCk7CiAgbWF4X3NpemU9aW1hZ2Vfc2l6ZSsoKERXT1JEKW16X2hlYWRlci5lX21heGFsbG9jPDw0KSsoUFNQX1NJWkU8PDQpOwogfQoKICBpZiAoYWxsb2MpIE1aX0luaXRNZW1vcnkoKTsKCiAgaWYgKG9ibGspIHsKICAgIC8qIGxvYWQgb3ZlcmxheSBpbnRvIHByZWFsbG9jYXRlZCBtZW1vcnkgKi8KICAgIGxvYWRfc2VnPW9ibGstPmxvYWRfc2VnOwogICAgcmVsX3NlZz1vYmxrLT5yZWxfc2VnOwogICAgbG9hZF9zdGFydD0oTFBCWVRFKSgoRFdPUkQpbG9hZF9zZWc8PDQpOwogIH0gZWxzZSB7CiAgICAvKiBhbGxvY2F0ZSBlbnZpcm9ubWVudCBibG9jayAqLwogICAgZW52X3NlZz1NWl9Jbml0RW52aXJvbm1lbnQob2xkZW52LCBmaWxlbmFtZSk7CgogICAgLyogYWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgZXhlY3V0YWJsZSAqLwogICAgVFJBQ0UoIkFsbG9jYXRpbmcgRE9TIG1lbW9yeSAobWluPSVsZCwgbWF4PSVsZClcbiIsbWluX3NpemUsbWF4X3NpemUpOwogICAgYXZhaWw9RE9TTUVNX0F2YWlsYWJsZSgpOwogICAgaWYgKGF2YWlsPG1pbl9zaXplKSB7CiAgICAgIEVSUigiaW5zdWZmaWNpZW50IERPUyBtZW1vcnlcbiIpOwogICAgICBTZXRMYXN0RXJyb3IoRVJST1JfTk9UX0VOT1VHSF9NRU1PUlkpOwogICAgICBnb3RvIGxvYWRfZXJyb3I7CiAgICB9CiAgICBpZiAoYXZhaWw+bWF4X3NpemUpIGF2YWlsPW1heF9zaXplOwogICAgcHNwX3N0YXJ0PURPU01FTV9HZXRCbG9jayhhdmFpbCwmRE9TVk1fcHNwKTsKICAgIGlmICghcHNwX3N0YXJ0KSB7CiAgICAgIEVSUigiZXJyb3IgYWxsb2NhdGluZyBET1MgbWVtb3J5XG4iKTsKICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9FTk9VR0hfTUVNT1JZKTsKICAgICAgZ290byBsb2FkX2Vycm9yOwogICAgfQogICAgbG9hZF9zZWc9RE9TVk1fcHNwKyhvbGRfY29tPzA6UFNQX1NJWkUpOwogICAgcmVsX3NlZz1sb2FkX3NlZzsKICAgIGxvYWRfc3RhcnQ9cHNwX3N0YXJ0KyhQU1BfU0laRTw8NCk7CiAgICBNWl9DcmVhdGVQU1AocHNwX3N0YXJ0LCBlbnZfc2VnLCBvbGRwc3Bfc2VnKTsKICB9CgogLyogbG9hZCBleGVjdXRhYmxlIGltYWdlICovCiBUUkFDRSgibG9hZGluZyBET1MgJXMgaW1hZ2UsICUwOGx4IGJ5dGVzXG4iLG9sZF9jb20/IkNPTSI6IkVYRSIsaW1hZ2Vfc2l6ZSk7CiBTZXRGaWxlUG9pbnRlcihoRmlsZSxpbWFnZV9zdGFydCxOVUxMLEZJTEVfQkVHSU4pOwogaWYgKCFSZWFkRmlsZShoRmlsZSxsb2FkX3N0YXJ0LGltYWdlX3NpemUsJmxlbixOVUxMKSB8fCBsZW4gIT0gaW1hZ2Vfc2l6ZSkgewogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICBnb3RvIGxvYWRfZXJyb3I7CiB9CgogaWYgKG16X2hlYWRlci5lX2NybGMpIHsKICAvKiBsb2FkIHJlbG9jYXRpb24gdGFibGUgKi8KICBUUkFDRSgibG9hZGluZyBET1MgRVhFIHJlbG9jYXRpb24gdGFibGUsICVkIGVudHJpZXNcbiIsbXpfaGVhZGVyLmVfY3JsYyk7CiAgLyogRklYTUU6IGlzIHRoaXMgdG9vIHNsb3cgd2l0aG91dCByZWFkIGJ1ZmZlcmluZz8gKi8KICBTZXRGaWxlUG9pbnRlcihoRmlsZSxtel9oZWFkZXIuZV9sZmFybGMsTlVMTCxGSUxFX0JFR0lOKTsKICBmb3IgKHg9MDsgeDxtel9oZWFkZXIuZV9jcmxjOyB4KyspIHsKICAgaWYgKCFSZWFkRmlsZShoRmlsZSwmcmVsb2Msc2l6ZW9mKHJlbG9jKSwmbGVuLE5VTEwpIHx8IGxlbiAhPSBzaXplb2YocmVsb2MpKSB7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7CiAgICBnb3RvIGxvYWRfZXJyb3I7CiAgIH0KICAgKihXT1JEKilTRUdQVFIxNihsb2FkX3N0YXJ0LHJlbG9jKSs9cmVsX3NlZzsKICB9CiB9CgogIGlmICghb2JsaykgewogICAgaW5pdF9jcyA9IGxvYWRfc2VnK216X2hlYWRlci5lX2NzOwogICAgaW5pdF9pcCA9IG16X2hlYWRlci5lX2lwOwogICAgaW5pdF9zcyA9IGxvYWRfc2VnK216X2hlYWRlci5lX3NzOwogICAgaW5pdF9zcCA9IG16X2hlYWRlci5lX3NwOwoKICAgIFRSQUNFKCJlbnRyeSBwb2ludDogJTA0eDolMDR4XG4iLGluaXRfY3MsaW5pdF9pcCk7CiAgfQoKICBpZiAoYWxsb2MgJiYgIU1aX0luaXRUYXNrKCkpIHsKICAgIFNldExhc3RFcnJvcihFUlJPUl9HRU5fRkFJTFVSRSk7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICByZXR1cm4gVFJVRTsKCmxvYWRfZXJyb3I6CiAgRE9TVk1fcHNwID0gb2xkcHNwX3NlZzsKCiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCUxvYWREb3NFeGUgKFdJTkVET1MuQCkKICovCnZvaWQgV0lOQVBJIE1aX0xvYWRJbWFnZSggTFBDU1RSIGZpbGVuYW1lLCBIQU5ETEUgaEZpbGUgKQp7CiAgaWYgKE1aX0RvTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsIE5VTEwgKSkgTVpfTGF1bmNoKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhlYwogKi8KQk9PTCBXSU5BUEkgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIC8qIHRoaXMgbWF5IG9ubHkgYmUgY2FsbGVkIGZyb20gZXhpc3RpbmcgRE9TIHByb2Nlc3NlcwogICAqIChpLmUuIG9uZSBET1MgYXBwIHNwYXduaW5nIGFub3RoZXIpICovCiAgLyogRklYTUU6IGRvIHdlIHdhbnQgdG8gY2hlY2sgYmluYXJ5IHR5cGUgZmlyc3QsIHRvIGNoZWNrCiAgICogd2hldGhlciBpdCdzIGEgTkUvUEUgZXhlY3V0YWJsZT8gKi8KICBIRklMRSBoRmlsZSA9IENyZWF0ZUZpbGVBKCBmaWxlbmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsCgkJCSAgICAgTlVMTCwgT1BFTl9FWElTVElORywgMCwgMCk7CiAgQk9PTCByZXQgPSBGQUxTRTsKICBpZiAoaEZpbGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHJldHVybiBGQUxTRTsKICBzd2l0Y2ggKGZ1bmMpIHsKICBjYXNlIDA6IC8qIGxvYWQgYW5kIGV4ZWN1dGUgKi8KICBjYXNlIDE6IC8qIGxvYWQgYnV0IGRvbid0IGV4ZWN1dGUgKi8KICAgIHsKICAgICAgLyogc2F2ZSBjdXJyZW50IHByb2Nlc3MncyByZXR1cm4gU1M6U1Agbm93ICovCiAgICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpRE9TVk1fcHNwIDw8IDQpOwogICAgICBQREIxNiAqcHNwID0gKFBEQjE2ICopcHNwX3N0YXJ0OwogICAgICBwc3AtPnNhdmVTdGFjayA9IChEV09SRClNQUtFU0VHUFRSKGNvbnRleHQtPlNlZ1NzLCBMT1dPUkQoY29udGV4dC0+RXNwKSk7CiAgICB9CiAgICByZXQgPSBNWl9Eb0xvYWRJbWFnZSggaEZpbGUsIGZpbGVuYW1lLCBOVUxMICk7CiAgICBpZiAocmV0KSB7CiAgICAgIC8qIE1aX0xvYWRJbWFnZSBjcmVhdGVkIGEgbmV3IFBTUCBhbmQgbG9hZGVkIG5ldyB2YWx1ZXMgaW50byBpdCwKICAgICAgICogbGV0J3Mgd29yayBvbiB0aGUgbmV3IHZhbHVlcyBub3cgKi8KICAgICAgTFBCWVRFIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClET1NWTV9wc3AgPDwgNCk7CiAgICAgIEV4ZWNCbG9jayAqYmxrID0gKEV4ZWNCbG9jayAqKXBhcmFtYmxrOwogICAgICBMUEJZVEUgY21kbGluZSA9IERPU01FTV9NYXBSZWFsVG9MaW5lYXIoYmxrLT5jbWRsaW5lKTsKCiAgICAgIC8qIEZpcnN0IGNoYXJhY3RlciBjb250YWlucyB0aGUgbGVuZ3RoIG9mIHRoZSBjb21tYW5kIGxpbmUuICovCiAgICAgIE1aX0ZpbGxQU1AocHNwX3N0YXJ0LCBjbWRsaW5lICsgMSwgY21kbGluZVswXSk7CgogICAgICAvKiB0aGUgbGFtZSBNUy1ET1MgZW5naW5lZXJzIGRlY2lkZWQgdGhhdCB0aGUgcmV0dXJuIGFkZHJlc3Mgc2hvdWxkIGJlIGluIGludDIyICovCiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIyLCAoRkFSUFJPQzE2KU1BS0VTRUdQVFIoY29udGV4dC0+U2VnQ3MsIExPV09SRChjb250ZXh0LT5FaXApKSk7CiAgICAgIGlmIChmdW5jKSB7CgkvKiBkb24ndCBleGVjdXRlLCBqdXN0IHJldHVybiBzdGFydHVwIHN0YXRlICovCglibGstPmluaXRfY3MgPSBpbml0X2NzOwoJYmxrLT5pbml0X2lwID0gaW5pdF9pcDsKCWJsay0+aW5pdF9zcyA9IGluaXRfc3M7CglibGstPmluaXRfc3AgPSBpbml0X3NwOwogICAgICB9IGVsc2UgewoJLyogZXhlY3V0ZSBieSBtYWtpbmcgdXMgcmV0dXJuIHRvIG5ldyBwcm9jZXNzICovCgljb250ZXh0LT5TZWdDcyA9IGluaXRfY3M7Cgljb250ZXh0LT5FaXAgICA9IGluaXRfaXA7Cgljb250ZXh0LT5TZWdTcyA9IGluaXRfc3M7Cgljb250ZXh0LT5Fc3AgICA9IGluaXRfc3A7Cgljb250ZXh0LT5TZWdEcyA9IERPU1ZNX3BzcDsKCWNvbnRleHQtPlNlZ0VzID0gRE9TVk1fcHNwOwoJY29udGV4dC0+RWF4ICAgPSAwOwogICAgICB9CiAgICB9CiAgICBicmVhazsKICBjYXNlIDM6IC8qIGxvYWQgb3ZlcmxheSAqLwogICAgewogICAgICBPdmVybGF5QmxvY2sgKmJsayA9IChPdmVybGF5QmxvY2sgKilwYXJhbWJsazsKICAgICAgcmV0ID0gTVpfRG9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgYmxrICk7CiAgICB9CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgRklYTUUoIkVYRUMgbG9hZCB0eXBlICVkIG5vdCBpbXBsZW1lbnRlZFxuIiwgZnVuYyk7CiAgICBTZXRMYXN0RXJyb3IoRVJST1JfSU5WQUxJRF9GVU5DVElPTik7CiAgICBicmVhazsKICB9CiAgQ2xvc2VIYW5kbGUoaEZpbGUpOwogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQWxsb2NEUE1JVGFzawogKi8Kdm9pZCBXSU5BUEkgTVpfQWxsb2NEUE1JVGFzayggdm9pZCApCnsKICBNWl9Jbml0TWVtb3J5KCk7CiAgTVpfSW5pdFRhc2soKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9SdW5JblRocmVhZAogKi8Kdm9pZCBXSU5BUEkgTVpfUnVuSW5UaHJlYWQoIFBBUENGVU5DIHByb2MsIFVMT05HX1BUUiBhcmcgKQp7CiAgaWYgKGxvb3BfdGhyZWFkKSB7CiAgICBET1NfU1BDIHNwYzsKICAgIEhBTkRMRSBldmVudDsKCiAgICBzcGMucHJvYyA9IHByb2M7CiAgICBzcGMuYXJnID0gYXJnOwogICAgZXZlbnQgPSBDcmVhdGVFdmVudEEoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogICAgUG9zdFRocmVhZE1lc3NhZ2VBKGxvb3BfdGlkLCBXTV9VU0VSLCBldmVudCwgKExQQVJBTSkmc3BjKTsKICAgIFdhaXRGb3JTaW5nbGVPYmplY3QoZXZlbnQsIElORklOSVRFKTsKICAgIENsb3NlSGFuZGxlKGV2ZW50KTsKICB9IGVsc2UKICAgIHByb2MoYXJnKTsKfQoKc3RhdGljIERXT1JEIFdJTkFQSSBNWl9ET1NWTSggTFBWT0lEIGxwRXh0cmEgKQp7CiAgQ09OVEVYVCBjb250ZXh0OwogIERXT1JEIHJldDsKCiAgZG9zdm1fcGlkID0gZ2V0cGlkKCk7CgogIG1lbXNldCggJmNvbnRleHQsIDAsIHNpemVvZihjb250ZXh0KSApOwogIGNvbnRleHQuU2VnQ3MgID0gaW5pdF9jczsKICBjb250ZXh0LkVpcCAgICA9IGluaXRfaXA7CiAgY29udGV4dC5TZWdTcyAgPSBpbml0X3NzOwogIGNvbnRleHQuRXNwICAgID0gaW5pdF9zcDsKICBjb250ZXh0LlNlZ0RzICA9IERPU1ZNX3BzcDsKICBjb250ZXh0LlNlZ0VzICA9IERPU1ZNX3BzcDsKICBjb250ZXh0LkVGbGFncyA9IDB4MDAwODAwMDA7ICAvKiB2aXJ0dWFsIGludGVycnVwdCBmbGFnICovCiAgRE9TVk1fU2V0VGltZXIoMHgxMDAwMCk7CiAgcmV0ID0gRE9TVk1fRW50ZXIoICZjb250ZXh0ICk7CgogIGRvc3ZtX3BpZCA9IDA7CiAgcmV0dXJuIHJldDsKfQoKc3RhdGljIEJPT0wgTVpfSW5pdFRhc2sodm9pZCkKewogIGlmICghRHVwbGljYXRlSGFuZGxlKEdldEN1cnJlbnRQcm9jZXNzKCksIEdldEN1cnJlbnRUaHJlYWQoKSwKICAgICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50UHJvY2VzcygpLCAmbG9vcF90aHJlYWQsCiAgICAgICAgICAgICAgICAgICAgICAgMCwgRkFMU0UsIERVUExJQ0FURV9TQU1FX0FDQ0VTUykpCiAgICByZXR1cm4gRkFMU0U7CiAgZG9zdm1fdGhyZWFkID0gQ3JlYXRlVGhyZWFkKE5VTEwsIDAsIE1aX0RPU1ZNLCBOVUxMLCBDUkVBVEVfU1VTUEVOREVELCAmZG9zdm1fdGlkKTsKICBpZiAoIWRvc3ZtX3RocmVhZCkgewogICAgQ2xvc2VIYW5kbGUobG9vcF90aHJlYWQpOwogICAgbG9vcF90aHJlYWQgPSAwOwogICAgcmV0dXJuIEZBTFNFOwogIH0KICBsb29wX3RpZCA9IEdldEN1cnJlbnRUaHJlYWRJZCgpOwogIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgdm9pZCBNWl9MYXVuY2godm9pZCkKewogIFREQiAqcFRhc2sgPSBUQVNLX0dldEN1cnJlbnQoKTsKICBCWVRFICpwc3Bfc3RhcnQgPSBQVFJfUkVBTF9UT19MSU4oIERPU1ZNX3BzcCwgMCApOwogIExQU1RSIGNtZGxpbmUgPSBHZXRDb21tYW5kTGluZUEoKTsKICBEV09SRCBydjsKCiAgTVpfRmlsbFBTUChwc3Bfc3RhcnQsIGNtZGxpbmUsIGNtZGxpbmUgPyBzdHJsZW4oY21kbGluZSkgOiAwKTsKICBwVGFzay0+ZmxhZ3MgfD0gVERCRl9XSU5PTERBUDsKCiAgX0xlYXZlV2luMTZMb2NrKCk7CgogIFJlc3VtZVRocmVhZChkb3N2bV90aHJlYWQpOwogIHJ2ID0gRE9TVk1fTG9vcChkb3N2bV90aHJlYWQpOwoKICBDbG9zZUhhbmRsZShkb3N2bV90aHJlYWQpOwogIGRvc3ZtX3RocmVhZCA9IDA7IGRvc3ZtX3RpZCA9IDA7CiAgQ2xvc2VIYW5kbGUobG9vcF90aHJlYWQpOwogIGxvb3BfdGhyZWFkID0gMDsgbG9vcF90aWQgPSAwOwoKICBWR0FfQ2xlYW4oKTsKICBFeGl0VGhyZWFkKHJ2KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGl0CiAqLwp2b2lkIFdJTkFQSSBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBpZiAoRE9TVk1fcHNwKSB7CiAgICBXT1JEIHBzcF9zZWcgPSBjc19wc3AgPyBjb250ZXh0LT5TZWdDcyA6IERPU1ZNX3BzcDsKICAgIExQQllURSBwc3Bfc3RhcnQgPSAoTFBCWVRFKSgoRFdPUkQpcHNwX3NlZyA8PCA0KTsKICAgIFBEQjE2ICpwc3AgPSAoUERCMTYgKilwc3Bfc3RhcnQ7CiAgICBXT1JEIHBhcnBzcCA9IHBzcC0+cGFyZW50UFNQOyAvKiBjaGVjayBmb3IgcGFyZW50IERPUyBwcm9jZXNzICovCiAgICBpZiAocGFycHNwKSB7CiAgICAgIC8qIHJldHJpZXZlIHBhcmVudCdzIHJldHVybiBhZGRyZXNzICovCiAgICAgIEZBUlBST0MxNiByZXRhZGRyID0gRE9TVk1fR2V0Uk1IYW5kbGVyKDB4MjIpOwogICAgICAvKiByZXN0b3JlIGludGVycnVwdHMgKi8KICAgICAgRE9TVk1fU2V0Uk1IYW5kbGVyKDB4MjIsIHBzcC0+c2F2ZWRpbnQyMik7CiAgICAgIERPU1ZNX1NldFJNSGFuZGxlcigweDIzLCBwc3AtPnNhdmVkaW50MjMpOwogICAgICBET1NWTV9TZXRSTUhhbmRsZXIoMHgyNCwgcHNwLT5zYXZlZGludDI0KTsKICAgICAgLyogRklYTUU6IGRlYWxsb2NhdGUgZmlsZSBoYW5kbGVzIGV0YyAqLwogICAgICAvKiBmcmVlIHByb2Nlc3MncyBhc3NvY2lhdGVkIG1lbW9yeQogICAgICAgKiBGSVhNRTogd2FsayBtZW1vcnkgYW5kIGRlYWxsb2NhdGUgYWxsIGJsb2NrcyBvd25lZCBieSBwcm9jZXNzICovCiAgICAgIERPU01FTV9GcmVlQmxvY2soRE9TTUVNX01hcFJlYWxUb0xpbmVhcihNQUtFTE9ORygwLHBzcC0+ZW52aXJvbm1lbnQpKSk7CiAgICAgIERPU01FTV9GcmVlQmxvY2soRE9TTUVNX01hcFJlYWxUb0xpbmVhcihNQUtFTE9ORygwLERPU1ZNX3BzcCkpKTsKICAgICAgLyogc3dpdGNoIHRvIHBhcmVudCdzIFBTUCAqLwogICAgICBET1NWTV9wc3AgPSBwYXJwc3A7CiAgICAgIHBzcF9zdGFydCA9IChMUEJZVEUpKChEV09SRClwYXJwc3AgPDwgNCk7CiAgICAgIHBzcCA9IChQREIxNiAqKXBzcF9zdGFydDsKICAgICAgLyogbm93IHJldHVybiB0byBwYXJlbnQgKi8KICAgICAgRE9TVk1fcmV0dmFsID0gcmV0dmFsOwogICAgICBjb250ZXh0LT5TZWdDcyA9IFNFTEVDVE9ST0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPkVpcCAgID0gT0ZGU0VUT0YocmV0YWRkcik7CiAgICAgIGNvbnRleHQtPlNlZ1NzID0gU0VMRUNUT1JPRihwc3AtPnNhdmVTdGFjayk7CiAgICAgIGNvbnRleHQtPkVzcCAgID0gT0ZGU0VUT0YocHNwLT5zYXZlU3RhY2spOwogICAgICByZXR1cm47CiAgICB9IGVsc2UKICAgICAgVFJBQ0UoImtpbGxpbmcgRE9TIHRhc2tcbiIpOwogIH0KICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQ3VycmVudAogKi8KQk9PTCBXSU5BUEkgTVpfQ3VycmVudCggdm9pZCApCnsKICByZXR1cm4gKGRvc3ZtX3BpZCAhPSAwKTsgLyogRklYTUU6IGRvIGEgYmV0dGVyIGNoZWNrICovCn0KCiNlbHNlIC8qICFNWl9TVVBQT1JURUQgKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTG9hZERvc0V4ZSAoV0lORURPUy5AKQogKi8Kdm9pZCBXSU5BUEkgTVpfTG9hZEltYWdlKCBMUENTVFIgZmlsZW5hbWUsIEhBTkRMRSBoRmlsZSApCnsKICBXQVJOKCJET1MgZXhlY3V0YWJsZXMgbm90IHN1cHBvcnRlZCBvbiB0aGlzIHBsYXRmb3JtXG4iKTsKICBTZXRMYXN0RXJyb3IoRVJST1JfQkFEX0ZPUk1BVCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfRXhlYwogKi8KQk9PTCBXSU5BUEkgTVpfRXhlYyggQ09OVEVYVDg2ICpjb250ZXh0LCBMUENTVFIgZmlsZW5hbWUsIEJZVEUgZnVuYywgTFBWT0lEIHBhcmFtYmxrICkKewogIC8qIGNhbid0IGhhcHBlbiAqLwogIFNldExhc3RFcnJvcihFUlJPUl9CQURfRk9STUFUKTsKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJTVpfQWxsb2NEUE1JVGFzawogKi8Kdm9pZCBXSU5BUEkgTVpfQWxsb2NEUE1JVGFzayggdm9pZCApCnsKICAgIEVSUigiQWN0dWFsIHJlYWwtbW9kZSBjYWxscyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm0hXG4iKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9FeGl0CiAqLwp2b2lkIFdJTkFQSSBNWl9FeGl0KCBDT05URVhUODYgKmNvbnRleHQsIEJPT0wgY3NfcHNwLCBXT1JEIHJldHZhbCApCnsKICBFeGl0VGhyZWFkKCByZXR2YWwgKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlNWl9DdXJyZW50CiAqLwpCT09MIFdJTkFQSSBNWl9DdXJyZW50KCB2b2lkICkKewogICAgcmV0dXJuIEZBTFNFOwp9CgojZW5kaWYgLyogIU1aX1NVUFBPUlRFRCAqLwo=