LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgoKI2luY2x1ZGUgIm9sZTIuaCIKI2luY2x1ZGUgInZmdy5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGF2aWZpbGUpOwoKI2luY2x1ZGUgImluaXRndWlkLmgiCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKCkhNT0RVTEUgQVZJRklMRV9oTW9kdWxlICAgPSBOVUxMOwoKQk9PTCAgICBBVklGSUxFX2JMb2NrZWQgICA9IEZBTFNFOwpVSU5UICAgIEFWSUZJTEVfdVVzZUNvdW50ID0gMDsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuUXVlcnlJbnRlcmZhY2UoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsUkVGSUlEIHJpaWQsTFBWT0lEICpwcG9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuQWRkUmVmKExQQ0xBU1NGQUNUT1JZIGlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5DcmVhdGVJbnN0YW5jZShMUENMQVNTRkFDVE9SWSBpZmFjZSxMUFVOS05PV04gcE91dGVyLFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmopOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUNsYXNzRmFjdG9yeV9mbkxvY2tTZXJ2ZXIoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UsQk9PTCBkb2xvY2spOwoKc3RhdGljIGNvbnN0IElDbGFzc0ZhY3RvcnlWdGJsIGljbGFzc2ZhY3QgPSB7CiAgSUNsYXNzRmFjdG9yeV9mblF1ZXJ5SW50ZXJmYWNlLAogIElDbGFzc0ZhY3RvcnlfZm5BZGRSZWYsCiAgSUNsYXNzRmFjdG9yeV9mblJlbGVhc2UsCiAgSUNsYXNzRmFjdG9yeV9mbkNyZWF0ZUluc3RhbmNlLAogIElDbGFzc0ZhY3RvcnlfZm5Mb2NrU2VydmVyCn07Cgp0eXBlZGVmIHN0cnVjdAp7CiAgLyogSVVua25vd24gZmllbGRzICovCiAgY29uc3QgSUNsYXNzRmFjdG9yeVZ0YmwgKmxwVnRibDsKICBEV09SRAkgZHdSZWY7CgogIENMU0lEICBjbHNpZDsKfSBJQ2xhc3NGYWN0b3J5SW1wbDsKCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlQ2xhc3NGYWN0b3J5KGNvbnN0IENMU0lEICpwY2xzaWQsIGNvbnN0IElJRCAqcmlpZCwKCQkJCQkgIExQVk9JRCAqcHB2KQp7CiAgSUNsYXNzRmFjdG9yeUltcGwgKnBDbGFzc0ZhY3RvcnkgPSBOVUxMOwogIEhSRVNVTFQgICAgICAgICAgICBocjsKCiAgKnBwdiA9IE5VTEw7CgogIHBDbGFzc0ZhY3RvcnkgPSAoSUNsYXNzRmFjdG9yeUltcGwqKUxvY2FsQWxsb2MoTFBUUiwgc2l6ZW9mKCpwQ2xhc3NGYWN0b3J5KSk7CiAgaWYgKHBDbGFzc0ZhY3RvcnkgPT0gTlVMTCkKICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICBwQ2xhc3NGYWN0b3J5LT5scFZ0YmwgICAgPSAmaWNsYXNzZmFjdDsKICBwQ2xhc3NGYWN0b3J5LT5kd1JlZiAgICAgPSAwOwogIG1lbWNweSgmcENsYXNzRmFjdG9yeS0+Y2xzaWQsIHBjbHNpZCwgc2l6ZW9mKHBDbGFzc0ZhY3RvcnktPmNsc2lkKSk7CgogIGhyID0gSUNsYXNzRmFjdG9yeV9RdWVyeUludGVyZmFjZSgoSUNsYXNzRmFjdG9yeSopcENsYXNzRmFjdG9yeSwgcmlpZCwgcHB2KTsKICBpZiAoRkFJTEVEKGhyKSkgewogICAgTG9jYWxGcmVlKChITE9DQUwpcENsYXNzRmFjdG9yeSk7CiAgICAqcHB2ID0gTlVMTDsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5RdWVyeUludGVyZmFjZShMUENMQVNTRkFDVE9SWSBpZmFjZSwKCQkJCQkJICAgICBSRUZJSUQgcmlpZCxMUFZPSUQgKnBwb2JqKQp7CiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIGlmYWNlLCByaWlkLCBwcG9iaik7CgogIGlmICgoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93biwgcmlpZCkpIHx8CiAgICAgIChJc0VxdWFsR1VJRCgmSUlEX0lDbGFzc0ZhY3RvcnksIHJpaWQpKSkgewogICAgKnBwb2JqID0gaWZhY2U7CiAgICBJQ2xhc3NGYWN0b3J5X0FkZFJlZihpZmFjZSk7CiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5BZGRSZWYoTFBDTEFTU0ZBQ1RPUlkgaWZhY2UpCnsKICBJQ2xhc3NGYWN0b3J5SW1wbCAqVGhpcyA9IChJQ2xhc3NGYWN0b3J5SW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIiwgaWZhY2UpOwoKICByZXR1cm4gKysoVGhpcy0+ZHdSZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5SZWxlYXNlKExQQ0xBU1NGQUNUT1JZIGlmYWNlKQp7CiAgSUNsYXNzRmFjdG9yeUltcGwgKlRoaXMgPSAoSUNsYXNzRmFjdG9yeUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcClcbiIsIGlmYWNlKTsKICBpZiAoKC0tKFRoaXMtPmR3UmVmKSkgPiAwKQogICAgcmV0dXJuIFRoaXMtPmR3UmVmOwoKICByZXR1cm4gMDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElDbGFzc0ZhY3RvcnlfZm5DcmVhdGVJbnN0YW5jZShMUENMQVNTRkFDVE9SWSBpZmFjZSwKCQkJCQkJICAgICBMUFVOS05PV04gcE91dGVyLAoJCQkJCQkgICAgIFJFRklJRCByaWlkLExQVk9JRCAqcHBvYmopCnsKICBJQ2xhc3NGYWN0b3J5SW1wbCAqVGhpcyA9IChJQ2xhc3NGYWN0b3J5SW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVzLCVwKVxuIiwgaWZhY2UsIHBPdXRlciwgZGVidWdzdHJfZ3VpZChyaWlkKSwKCXBwb2JqKTsKCiAgaWYgKHBwb2JqID09IE5VTEwgfHwgcE91dGVyICE9IE5VTEwpCiAgICByZXR1cm4gRV9GQUlMOwogICpwcG9iaiA9IE5VTEw7CgogIGlmIChJc0VxdWFsR1VJRCgmQ0xTSURfQVZJRmlsZSwgJlRoaXMtPmNsc2lkKSkKICAgIHJldHVybiBBVklGSUxFX0NyZWF0ZUFWSUZpbGUocmlpZCxwcG9iaik7CiAgaWYgKElzRXF1YWxHVUlEKCZDTFNJRF9JQ01TdHJlYW0sICZUaGlzLT5jbHNpZCkpCiAgICByZXR1cm4gQVZJRklMRV9DcmVhdGVJQ01TdHJlYW0ocmlpZCxwcG9iaik7CiAgaWYgKElzRXF1YWxHVUlEKCZDTFNJRF9XQVZGaWxlLCAmVGhpcy0+Y2xzaWQpKQogICAgcmV0dXJuIEFWSUZJTEVfQ3JlYXRlV0FWRmlsZShyaWlkLHBwb2JqKTsKICBpZiAoSXNFcXVhbEdVSUQoJkNMU0lEX0FDTVN0cmVhbSwgJlRoaXMtPmNsc2lkKSkKICAgIHJldHVybiBBVklGSUxFX0NyZWF0ZUFDTVN0cmVhbShyaWlkLHBwb2JqKTsKCiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQ2xhc3NGYWN0b3J5X2ZuTG9ja1NlcnZlcihMUENMQVNTRkFDVE9SWSBpZmFjZSxCT09MIGRvbG9jaykKewogIFRSQUNFKCIoJXAsJWQpXG4iLGlmYWNlLGRvbG9jayk7CgogIEFWSUZJTEVfYkxvY2tlZCA9IGRvbG9jazsKCiAgcmV0dXJuIFNfT0s7Cn0KCkxQQ1dTVFIgQVZJRklMRV9CYXNlbmFtZVcoTFBDV1NUUiBzelBhdGgpCnsKI2RlZmluZSBTTEFTSCh3KSAoKHcpID09ICcvJyB8fCAodykgPT0gJ1xcJykKCiAgTFBDV1NUUiBzekN1cjsKCiAgZm9yIChzekN1ciA9IHN6UGF0aCArIGxzdHJsZW5XKHN6UGF0aCk7CiAgICAgICBzekN1ciA+IHN6UGF0aCAmJiAhU0xBU0goKnN6Q3VyKSAmJiAqc3pDdXIgIT0gJzonOykKICAgIHN6Q3VyLS07CgogIGlmIChzekN1ciA9PSBzelBhdGgpCiAgICByZXR1cm4gc3pDdXI7CiAgZWxzZQogICAgcmV0dXJuIHN6Q3VyICsgMTsKCiN1bmRlZiBTTEFTSAp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURsbEdldENsYXNzT2JqZWN0IChBVklGSUwzMi5AKQogKi8KSFJFU1VMVCBXSU5BUEkgRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcGNsc2lkLCBSRUZJSUQgcGlpZCwgTFBWT0lEICpwcHYpCnsKICBUUkFDRSgiKCVzLCVzLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChwY2xzaWQpLCBkZWJ1Z3N0cl9ndWlkKHBpaWQpLCBwcHYpOwoKICBpZiAocGNsc2lkID09IE5VTEwgfHwgcGlpZCA9PSBOVUxMIHx8IHBwdiA9PSBOVUxMKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgcmV0dXJuIEFWSUZJTEVfQ3JlYXRlQ2xhc3NGYWN0b3J5KHBjbHNpZCxwaWlkLHBwdik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRGxsQ2FuVW5sb2FkTm93CQkoQVZJRklMMzIuQCkKICovCkhSRVNVTFQgV0lOQVBJIERsbENhblVubG9hZE5vdyh2b2lkKQp7CiAgcmV0dXJuICgoQVZJRklMRV9iTG9ja2VkIHx8IEFWSUZJTEVfdVVzZUNvdW50KSA/IFNfRkFMU0UgOiBTX09LKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlEbGxNYWluCQlbQVZJRklMMzIuaW5pdF0KICovCkJPT0wgV0lOQVBJIERsbE1haW4oSElOU1RBTkNFIGhJbnN0RGxsLCBEV09SRCBmZHdSZWFzb24sIExQVk9JRCBscHZSZXNlcnZlZCkKewogIFRSQUNFKCIoJXAsJWxkLCVwKVxuIiwgaEluc3REbGwsIGZkd1JlYXNvbiwgbHB2UmVzZXJ2ZWQpOwoKICBzd2l0Y2ggKGZkd1JlYXNvbikgewogIGNhc2UgRExMX1BST0NFU1NfQVRUQUNIOgogICAgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhoSW5zdERsbCk7CiAgICBBVklGSUxFX2hNb2R1bGUgPSAoSE1PRFVMRSloSW5zdERsbDsKICAgIGJyZWFrOwogIGNhc2UgRExMX1BST0NFU1NfREVUQUNIOgogICAgYnJlYWs7CiAgfTsKCiAgcmV0dXJuIFRSVUU7Cn0K