LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKCiNpbmNsdWRlICJvbGUyLmgiCiNpbmNsdWRlICJ2ZncuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCiNpbmNsdWRlICJpbml0Z3VpZC5oIgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCgpITU9EVUxFIEFWSUZJTEVfaE1vZHVsZSAgID0gTlVMTDsKCkJPT0wgICAgQVZJRklMRV9iTG9ja2VkICAgPSBGQUxTRTsKVUlOVCAgICBBVklGSUxFX3VVc2VDb3VudCA9IDA7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mblF1ZXJ5SW50ZXJmYWNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mbkFkZFJlZihMUENMQVNTRkFDVE9SWSBpZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuUmVsZWFzZShMUENMQVNTRkFDVE9SWSBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuQ3JlYXRlSW5zdGFuY2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsTFBVTktOT1dOIHBPdXRlcixSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5Mb2NrU2VydmVyKExQQ0xBU1NGQUNUT1JZIGlmYWNlLEJPT0wgZG9sb2NrKTsKCnN0YXRpYyBJQ09NX1ZUQUJMRShJQ2xhc3NGYWN0b3J5KSBpY2xhc3NmYWN0ID0gewogIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgSUNsYXNzRmFjdG9yeV9mblF1ZXJ5SW50ZXJmYWNlLAogIElDbGFzc0ZhY3RvcnlfZm5BZGRSZWYsCiAgSUNsYXNzRmFjdG9yeV9mblJlbGVhc2UsCiAgSUNsYXNzRmFjdG9yeV9mbkNyZWF0ZUluc3RhbmNlLAogIElDbGFzc0ZhY3RvcnlfZm5Mb2NrU2VydmVyCn07Cgp0eXBlZGVmIHN0cnVjdAp7CiAgLyogSVVua25vd24gZmllbGRzICovCiAgSUNPTV9WRklFTEQoSUNsYXNzRmFjdG9yeSk7CiAgRFdPUkQJIGR3UmVmOwoKICBDTFNJRCAgY2xzaWQ7Cn0gSUNsYXNzRmFjdG9yeUltcGw7CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0NyZWF0ZUNsYXNzRmFjdG9yeShjb25zdCBDTFNJRCAqcGNsc2lkLCBjb25zdCBJSUQgKnJpaWQsCgkJCQkJICBMUFZPSUQgKnBwdikKewogIElDbGFzc0ZhY3RvcnlJbXBsICpwQ2xhc3NGYWN0b3J5ID0gTlVMTDsKICBIUkVTVUxUICAgICAgICAgICAgaHI7CgogICpwcHYgPSBOVUxMOwoKICBwQ2xhc3NGYWN0b3J5ID0gKElDbGFzc0ZhY3RvcnlJbXBsKilMb2NhbEFsbG9jKExQVFIsIHNpemVvZigqcENsYXNzRmFjdG9yeSkpOwogIGlmIChwQ2xhc3NGYWN0b3J5ID09IE5VTEwpCiAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgcENsYXNzRmFjdG9yeS0+bHBWdGJsICAgID0gJmljbGFzc2ZhY3Q7CiAgcENsYXNzRmFjdG9yeS0+ZHdSZWYgICAgID0gMDsKICBtZW1jcHkoJnBDbGFzc0ZhY3RvcnktPmNsc2lkLCBwY2xzaWQsIHNpemVvZihwQ2xhc3NGYWN0b3J5LT5jbHNpZCkpOwoKICBociA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKChJVW5rbm93biopcENsYXNzRmFjdG9yeSwgcmlpZCwgcHB2KTsKICBpZiAoRkFJTEVEKGhyKSkgewogICAgTG9jYWxGcmVlKChITE9DQUwpcENsYXNzRmFjdG9yeSk7CiAgICAqcHB2ID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5RdWVyeUludGVyZmFjZShMUENMQVNTRkFDVE9SWSBpZmFjZSwKCQkJCQkJICAgICBSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqKQp7CiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIGlmYWNlLCByaWlkLCBwcG9iaik7CgogIGlmICgoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93biwgcmlpZCkpIHx8CiAgICAgIChJc0VxdWFsR1VJRCgmSUlEX0lDbGFzc0ZhY3RvcnksIHJpaWQpKSkgewogICAgKnBwb2JqID0gaWZhY2U7CiAgICBJQ2xhc3NGYWN0b3J5X0FkZFJlZihpZmFjZSk7CiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5BZGRSZWYoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpCnsKICBJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwKVxuIiwgaWZhY2UpOwoKICByZXR1cm4gKysoVGhpcy0+ZHdSZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKQp7CiAgSUNPTV9USElTKElDbGFzc0ZhY3RvcnlJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcClcbiIsIGlmYWNlKTsKICBpZiAoKC0tKFRoaXMtPmR3UmVmKSkgPiAwKQogICAgcmV0dXJuIFRoaXMtPmR3UmVmOwoKICByZXR1cm4gMDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5DcmVhdGVJbnN0YW5jZShMUENMQVNTRkFDVE9SWSBpZmFjZSwKCQkJCQkJICAgICBMUFVOS05PV04gcE91dGVyLAoJCQkJCQkgICAgIFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmopCnsKICBJQ09NX1RISVMoSUNsYXNzRmFjdG9yeUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLCVwLCVzLCVwKVxuIiwgaWZhY2UsIHBPdXRlciwgZGVidWdzdHJfZ3VpZChyaWlkKSwKCXBwb2JqKTsKCiAgaWYgKHBwb2JqID09IE5VTEwgfHwgcE91dGVyICE9IE5VTEwpCiAgICByZXR1cm4gRV9GQUlMOwogICpwcG9iaiA9IE5VTEw7CgogIGlmIChJc0VxdWFsR1VJRCgmQ0xTSURfQVZJRmlsZSwgJlRoaXMtPmNsc2lkKSkKICAgIHJldHVybiBBVklGSUxFX0NyZWF0ZUFWSUZpbGUocmlpZCxwcG9iaik7CiAgaWYgKElzRXF1YWxHVUlEKCZDTFNJRF9JQ01TdHJlYW0sICZUaGlzLT5jbHNpZCkpCiAgICByZXR1cm4gQVZJRklMRV9DcmVhdGVJQ01TdHJlYW0ocmlpZCxwcG9iaik7CiAgaWYgKElzRXF1YWxHVUlEKCZDTFNJRF9XQVZGaWxlLCAmVGhpcy0+Y2xzaWQpKQogICAgcmV0dXJuIEFWSUZJTEVfQ3JlYXRlV0FWRmlsZShyaWlkLHBwb2JqKTsKICBpZiAoSXNFcXVhbEdVSUQoJkNMU0lEX0FDTVN0cmVhbSwgJlRoaXMtPmNsc2lkKSkKICAgIHJldHVybiBBVklGSUxFX0NyZWF0ZUFDTVN0cmVhbShyaWlkLHBwb2JqKTsKCiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSxCT09MIGRvbG9jaykKewogIFRSQUNFKCIoJXAsJWQpXG4iLGlmYWNlLGRvbG9jayk7CgogIEFWSUZJTEVfYkxvY2tlZCA9IGRvbG9jazsKCiAgcmV0dXJuIFNfT0s7Cn0KCkxQQ1dTVFIgQVZJRklMRV9CYXNlbmFtZVcoTFBDV1NUUiBzelBhdGgpCnsKI2RlZmluZSBTTEFTSCh3KSAoKHcpID09ICcvJyB8fCAodykgPT0gJ1xcJykKCiAgTFBDV1NUUiBzekN1cjsKCiAgZm9yIChzekN1ciA9IHN6UGF0aCArIGxzdHJsZW5XKHN6UGF0aCk7CiAgICAgICBzekN1ciA+IHN6UGF0aCAmJiAhU0xBU0goKnN6Q3VyKSAmJiAqc3pDdXIgIT0gJzonOykKICAgIHN6Q3VyLS07CgogIGlmIChzekN1ciA9PSBzelBhdGgpCiAgICByZXR1cm4gc3pDdXI7CiAgZWxzZQogICAgcmV0dXJuIHN6Q3VyICsgMTsKCiN1bmRlZiBTTEFTSAp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURsbEdldENsYXNzT2JqZWN0IChBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgQVZJRklMRV9EbGxHZXRDbGFzc09iamVjdChjb25zdCBDTFNJRCogcGNsc2lkLFJFRklJRCBwaWlkLExQVk9JRCAqcHB2KQp7CiAgVFJBQ0UoIiglcywlcywlcClcbiIsIGRlYnVnc3RyX2d1aWQocGNsc2lkKSwgZGVidWdzdHJfZ3VpZChwaWlkKSwgcHB2KTsKCiAgaWYgKHBjbHNpZCA9PSBOVUxMIHx8IHBpaWQgPT0gTlVMTCB8fCBwcHYgPT0gTlVMTCkKICAgIHJldHVybiBFX0ZBSUw7CgogIHJldHVybiBBVklGSUxFX0NyZWF0ZUNsYXNzRmFjdG9yeShwY2xzaWQscGlpZCxwcHYpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURsbENhblVubG9hZE5vdwkJKEFWSUZJTDMyLkApCiAqLwpEV09SRCBXSU5BUEkgQVZJRklMRV9EbGxDYW5VbmxvYWROb3codm9pZCkKewogIHJldHVybiAoKEFWSUZJTEVfYkxvY2tlZCB8fCBBVklGSUxFX3VVc2VDb3VudCkgPyBTX0ZBTFNFIDogU19PSyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRGxsTWFpbgkJW0FWSUZJTDMyLmluaXRdCiAqLwpCT09MIFdJTkFQSSBEbGxNYWluKEhJTlNUQU5DRSBoSW5zdERsbCwgRFdPUkQgZmR3UmVhc29uLCBMUFZPSUQgbHB2UmVzZXJ2ZWQpCnsKICBUUkFDRSgiKCVwLCVsdSwlcClcbiIsIGhJbnN0RGxsLCBmZHdSZWFzb24sIGxwdlJlc2VydmVkKTsKCiAgc3dpdGNoIChmZHdSZWFzb24pIHsKICBjYXNlIERMTF9QUk9DRVNTX0FUVEFDSDoKICAgIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoaEluc3REbGwpOwogICAgQVZJRklMRV9oTW9kdWxlID0gKEhNT0RVTEUpaEluc3REbGw7CiAgICBicmVhazsKICBjYXNlIERMTF9QUk9DRVNTX0RFVEFDSDoKICAgIGJyZWFrOwogIH07CgogIHJldHVybiBUUlVFOwp9Cg==