Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBIaWdoIER5bmFtaWMgUmFuZ2UgYml0bWFwIGNvbnZlcnNpb24gcm91dGluZXMKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gTWloYWlsIE5heWRlbm92IChtbmF5ZGVub3ZAdXNlcnMuc291cmNlZm9yZ2UubmV0KQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlIDxjbWF0aD4KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgojaW5jbHVkZSAiVG9uZU1hcHBpbmcuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gQ29udmVydCBSR0IgdG8gYW5kIGZyb20gWXh5LCBzYW1lIGFzIGluIFJlaW5oYXJkIGV0IGFsLiBTSUdHUkFQSCAyMDAyCi8vIFJlZmVyZW5jZXMgOiAKLy8gWzFdIFJhZGlhbmNlIEhvbWUgUGFnZSBbT25saW5lXSBodHRwOi8vcmFkc2l0ZS5sYmwuZ292L3JhZGlhbmNlL0hPTUUuaHRtbAovLyBbMl0gRS4gUmVpbmhhcmQsIE0uIFN0YXJrLCBQLiBTaGlybGV5LCBhbmQgSi4gRmVyd2VyZGEsICAKLy8gICAgIFBob3RvZ3JhcGhpYyBUb25lIFJlcHJvZHVjdGlvbiBmb3IgRGlnaXRhbCBJbWFnZXMsIEFDTSBUcmFuc2FjdGlvbnMgb24gR3JhcGhpY3MsIAovLyAgICAgMjEoMyk6MjY3LTI3NiwgMjAwMiAoUHJvY2VlZGluZ3Mgb2YgU0lHR1JBUEggMjAwMikuIAovLyBbM10gSi4gVHVtYmxpbiBhbmQgSC5FLiBSdXNobWVpZXIsIAovLyAgICAgVG9uZSBSZXByb2R1Y3Rpb24gZm9yIFJlYWxpc3RpYyBJbWFnZXMuIElFRUUgQ29tcHV0ZXIgR3JhcGhpY3MgYW5kIEFwcGxpY2F0aW9ucywgCi8vICAgICAxMyg2KTo0Mi00OCwgMTk5My4KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCm5vbWluYWwgQ1JUIHByaW1hcmllcyAKKi8KLyoKc3RhdGljIGNvbnN0IGZsb2F0IENJRV94X3IgPSAwLjY0MEY7CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfeV9yID0gMC4zMzBGOwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3hfZyA9IDAuMjkwRjsKc3RhdGljIGNvbnN0IGZsb2F0IENJRV95X2cgPSAwLjYwMEY7CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfeF9iID0gMC4xNTBGOwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3lfYiA9IDAuMDYwRjsKc3RhdGljIGNvbnN0IGZsb2F0IENJRV94X3cgPSAwLjMzMzNGOwkvLyB1c2UgdHJ1ZSB3aGl0ZQpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3lfdyA9IDAuMzMzM0Y7CiovCi8qKgpzUkdCIHByaW1hcmllcwoqLwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3hfciA9IDAuNjQwRjsKc3RhdGljIGNvbnN0IGZsb2F0IENJRV95X3IgPSAwLjMzMEY7CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfeF9nID0gMC4zMDBGOwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3lfZyA9IDAuNjAwRjsKc3RhdGljIGNvbnN0IGZsb2F0IENJRV94X2IgPSAwLjE1MEY7CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfeV9iID0gMC4wNjBGOwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3hfdyA9IDAuMzEyN0Y7CS8vIElsbHVtaW5hbnQgRDY1CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfeV93ID0gMC4zMjkwRjsKCnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfRCA9ICggQ0lFX3hfciooQ0lFX3lfZyAtIENJRV95X2IpICsgQ0lFX3hfZyooQ0lFX3lfYiAtIENJRV95X3IpICsgQ0lFX3hfYiooQ0lFX3lfciAtIENJRV95X2cpICk7CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfQ19yRCA9ICggKDEvQ0lFX3lfdykgKiAoIENJRV94X3cqKENJRV95X2cgLSBDSUVfeV9iKSAtIENJRV95X3cqKENJRV94X2cgLSBDSUVfeF9iKSArIENJRV94X2cqQ0lFX3lfYiAtIENJRV94X2IqQ0lFX3lfZykgKTsKc3RhdGljIGNvbnN0IGZsb2F0IENJRV9DX2dEID0gKCAoMS9DSUVfeV93KSAqICggQ0lFX3hfdyooQ0lFX3lfYiAtIENJRV95X3IpIC0gQ0lFX3lfdyooQ0lFX3hfYiAtIENJRV94X3IpIC0gQ0lFX3hfcipDSUVfeV9iICsgQ0lFX3hfYipDSUVfeV9yKSApOwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX0NfYkQgPSAoICgxL0NJRV95X3cpICogKCBDSUVfeF93KihDSUVfeV9yIC0gQ0lFX3lfZykgLSBDSUVfeV93KihDSUVfeF9yIC0gQ0lFX3hfZykgKyBDSUVfeF9yKkNJRV95X2cgLSBDSUVfeF9nKkNJRV95X3IpICk7CgovKioKUkdCIHRvIFhZWiAobm8gd2hpdGUgYmFsYW5jZSkKKi8Kc3RhdGljIGNvbnN0IGZsb2F0ICBSR0IyWFlaWzNdWzNdID0gewoJeyBDSUVfeF9yKkNJRV9DX3JEIC8gQ0lFX0QsIAoJICBDSUVfeF9nKkNJRV9DX2dEIC8gQ0lFX0QsIAoJICBDSUVfeF9iKkNJRV9DX2JEIC8gQ0lFX0QgCgl9LAoJeyBDSUVfeV9yKkNJRV9DX3JEIC8gQ0lFX0QsIAoJICBDSUVfeV9nKkNJRV9DX2dEIC8gQ0lFX0QsIAoJICBDSUVfeV9iKkNJRV9DX2JEIC8gQ0lFX0QgCgl9LAoJeyAoMSAtIENJRV94X3ItQ0lFX3lfcikqQ0lFX0NfckQgLyBDSUVfRCwKCSAgKDEgLSBDSUVfeF9nLUNJRV95X2cpKkNJRV9DX2dEIC8gQ0lFX0QsCgkgICgxIC0gQ0lFX3hfYi1DSUVfeV9iKSpDSUVfQ19iRCAvIENJRV9ECgl9Cn07CgovKioKWFlaIHRvIFJHQiAobm8gd2hpdGUgYmFsYW5jZSkKKi8Kc3RhdGljIGNvbnN0IGZsb2F0ICBYWVoyUkdCWzNdWzNdID0gewoJeyhDSUVfeV9nIC0gQ0lFX3lfYiAtIENJRV94X2IqQ0lFX3lfZyArIENJRV95X2IqQ0lFX3hfZykgLyBDSUVfQ19yRCwKCSAoQ0lFX3hfYiAtIENJRV94X2cgLSBDSUVfeF9iKkNJRV95X2cgKyBDSUVfeF9nKkNJRV95X2IpIC8gQ0lFX0NfckQsCgkgKENJRV94X2cqQ0lFX3lfYiAtIENJRV94X2IqQ0lFX3lfZykgLyBDSUVfQ19yRAoJfSwKCXsoQ0lFX3lfYiAtIENJRV95X3IgLSBDSUVfeV9iKkNJRV94X3IgKyBDSUVfeV9yKkNJRV94X2IpIC8gQ0lFX0NfZ0QsCgkgKENJRV94X3IgLSBDSUVfeF9iIC0gQ0lFX3hfcipDSUVfeV9iICsgQ0lFX3hfYipDSUVfeV9yKSAvIENJRV9DX2dELAoJIChDSUVfeF9iKkNJRV95X3IgLSBDSUVfeF9yKkNJRV95X2IpIC8gQ0lFX0NfZ0QKCX0sCgl7KENJRV95X3IgLSBDSUVfeV9nIC0gQ0lFX3lfcipDSUVfeF9nICsgQ0lFX3lfZypDSUVfeF9yKSAvIENJRV9DX2JELAoJIChDSUVfeF9nIC0gQ0lFX3hfciAtIENJRV94X2cqQ0lFX3lfciArIENJRV94X3IqQ0lFX3lfZykgLyBDSUVfQ19iRCwKCSAoQ0lFX3hfcipDSUVfeV9nIC0gQ0lFX3hfZypDSUVfeV9yKSAvIENJRV9DX2JECgl9Cn07CgovKioKVGhpcyBnaXZlcyBhcHByb3hpbWF0ZWx5IHRoZSBmb2xsb3dpbmcgbWF0cmljZXMgOiAKCnN0YXRpYyBjb25zdCBmbG9hdCBSR0IyWFlaWzNdWzNdID0geyAKCXsgMC40MTIzOTA4M0YsIDAuMzU3NTg0MzNGLCAwLjE4MDQ4MDgxRiB9LAoJeyAwLjIxMjYzOTAzRiwgMC43MTUxNjg2NUYsIDAuMDcyMTkyMzE5RiB9LAoJeyAwLjAxOTMzMDgyMEYsIDAuMTE5MTk0NzNGLCAwLjk1MDUzMjIwRiB9Cn07CnN0YXRpYyBjb25zdCBmbG9hdCBYWVoyUkdCWzNdWzNdID0geyAKCXsgMy4yNDA5Njk5RiwgLTEuNTM3MzgzMkYsIC0wLjQ5ODYxMDc5RiB9LAoJeyAtMC45NjkyNDM3NkYsIDEuODc1OTY3NkYsIDAuMDQxNTU1MDg0RiB9LAoJeyAwLjA1NTYzMDAzNkYsIC0wLjIwMzk3Njg3RiwgMS4wNTY5NzE1RiB9Cn07CiovCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgY29uc3QgZmxvYXQgRVBTSUxPTiA9IDFlLTA2RjsKc3RhdGljIGNvbnN0IGZsb2F0IElORiA9IDFlKzEwRjsKCi8qKgpDb252ZXJ0IGluLXBsYWNlIGZsb2F0aW5nIHBvaW50IFJHQiBkYXRhIHRvIFl4eS48YnI+Ck9uIG91dHB1dCwgcGl4ZWwtPnJlZCA9PSBZLCBwaXhlbC0+Z3JlZW4gPT0geCwgcGl4ZWwtPmJsdWUgPT0geQpAcGFyYW0gZGliIElucHV0IFJHQkYgLyBPdXRwdXQgWXh5IGltYWdlCkByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCiovCkJPT0wgCkNvbnZlcnRJblBsYWNlUkdCRlRvWXh5KEZJQklUTUFQICpkaWIpIHsKCWZsb2F0IHJlc3VsdFszXTsKCglpZihGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYikgIT0gRklUX1JHQkYpCgkJcmV0dXJuIEZBTFNFOwoKCWNvbnN0IHVuc2lnbmVkIHdpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpOwoJY29uc3QgdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChkaWIpOwoJY29uc3QgdW5zaWduZWQgcGl0Y2ggID0gRnJlZUltYWdlX0dldFBpdGNoKGRpYik7CgkKCUJZVEUgKmJpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoZGliKTsKCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJRklSR0JGICpwaXhlbCA9IChGSVJHQkYqKWJpdHM7CgkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQlyZXN1bHRbMF0gPSByZXN1bHRbMV0gPSByZXN1bHRbMl0gPSAwOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgewoJCQkJcmVzdWx0W2ldICs9IFJHQjJYWVpbaV1bMF0gKiBwaXhlbFt4XS5yZWQ7CgkJCQlyZXN1bHRbaV0gKz0gUkdCMlhZWltpXVsxXSAqIHBpeGVsW3hdLmdyZWVuOwoJCQkJcmVzdWx0W2ldICs9IFJHQjJYWVpbaV1bMl0gKiBwaXhlbFt4XS5ibHVlOwoJCQl9CgkJCWNvbnN0IGZsb2F0IFcgPSByZXN1bHRbMF0gKyByZXN1bHRbMV0gKyByZXN1bHRbMl07CgkJCWNvbnN0IGZsb2F0IFkgPSByZXN1bHRbMV07CgkJCWlmKFcgPiAwKSB7IAoJCQkJcGl4ZWxbeF0ucmVkICAgPSBZOwkJCSAgICAvLyBZIAoJCQkJcGl4ZWxbeF0uZ3JlZW4gPSByZXN1bHRbMF0gLyBXOwkvLyB4IAoJCQkJcGl4ZWxbeF0uYmx1ZSAgPSByZXN1bHRbMV0gLyBXOwkvLyB5IAkKCQkJfSBlbHNlIHsKCQkJCXBpeGVsW3hdLnJlZCA9IHBpeGVsW3hdLmdyZWVuID0gcGl4ZWxbeF0uYmx1ZSA9IDA7CgkJCX0KCQl9CgkJLy8gbmV4dCBsaW5lCgkJYml0cyArPSBwaXRjaDsKCX0KCglyZXR1cm4gVFJVRTsKfQoKLyoqCkNvbnZlcnQgaW4tcGxhY2UgWXh5IGltYWdlIHRvIGZsb2F0aW5nIHBvaW50IFJHQiBkYXRhLjxicj4KT24gaW5wdXQsIHBpeGVsLT5yZWQgPT0gWSwgcGl4ZWwtPmdyZWVuID09IHgsIHBpeGVsLT5ibHVlID09IHkKQHBhcmFtIGRpYiBJbnB1dCBZeHkgLyBPdXRwdXQgUkdCRiBpbWFnZQpAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoqLwpCT09MIApDb252ZXJ0SW5QbGFjZVl4eVRvUkdCRihGSUJJVE1BUCAqZGliKSB7CglmbG9hdCByZXN1bHRbM107CglmbG9hdCBYLCBZLCBaOwoKCWlmKEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKSAhPSBGSVRfUkdCRikKCQlyZXR1cm4gRkFMU0U7CgoJY29uc3QgdW5zaWduZWQgd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKGRpYik7Cgljb25zdCB1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7Cgljb25zdCB1bnNpZ25lZCBwaXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZGliKTsKCglCWVRFICpiaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKGRpYik7Cglmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCUZJUkdCRiAqcGl4ZWwgPSAoRklSR0JGKiliaXRzOwoJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJWSA9IHBpeGVsW3hdLnJlZDsJICAgICAgICAvLyBZIAoJCQlyZXN1bHRbMV0gPSBwaXhlbFt4XS5ncmVlbjsJLy8geCAKCQkJcmVzdWx0WzJdID0gcGl4ZWxbeF0uYmx1ZTsJLy8geSAKCQkJaWYgKChZID4gRVBTSUxPTikgJiYgKHJlc3VsdFsxXSA+IEVQU0lMT04pICYmIChyZXN1bHRbMl0gPiBFUFNJTE9OKSkgewoJCQkJWCA9IChyZXN1bHRbMV0gKiBZKSAvIHJlc3VsdFsyXTsKCQkJCVogPSAoWCAvIHJlc3VsdFsxXSkgLSBYIC0gWTsKCQkJfSBlbHNlIHsKCQkJCVggPSBaID0gRVBTSUxPTjsKCQkJfQoJCQlwaXhlbFt4XS5yZWQgICA9IFg7CgkJCXBpeGVsW3hdLmdyZWVuID0gWTsKCQkJcGl4ZWxbeF0uYmx1ZSAgPSBaOwoJCQlyZXN1bHRbMF0gPSByZXN1bHRbMV0gPSByZXN1bHRbMl0gPSAwOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgewoJCQkJcmVzdWx0W2ldICs9IFhZWjJSR0JbaV1bMF0gKiBwaXhlbFt4XS5yZWQ7CgkJCQlyZXN1bHRbaV0gKz0gWFlaMlJHQltpXVsxXSAqIHBpeGVsW3hdLmdyZWVuOwoJCQkJcmVzdWx0W2ldICs9IFhZWjJSR0JbaV1bMl0gKiBwaXhlbFt4XS5ibHVlOwoJCQl9CgkJCXBpeGVsW3hdLnJlZCAgID0gcmVzdWx0WzBdOwkvLyBSCgkJCXBpeGVsW3hdLmdyZWVuID0gcmVzdWx0WzFdOwkvLyBHCgkJCXBpeGVsW3hdLmJsdWUgID0gcmVzdWx0WzJdOwkvLyBCCgkJfQoJCS8vIG5leHQgbGluZQoJCWJpdHMgKz0gcGl0Y2g7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCi8qKgpHZXQgdGhlIG1heGltdW0sIG1pbmltdW0gYW5kIGF2ZXJhZ2UgbHVtaW5hbmNlLjxicj4KT24gaW5wdXQsIHBpeGVsLT5yZWQgPT0gWSwgcGl4ZWwtPmdyZWVuID09IHgsIHBpeGVsLT5ibHVlID09IHkKQHBhcmFtIFl4eSBTb3VyY2UgWXh5IGltYWdlIHRvIGFuYWx5emUKQHBhcmFtIG1heEx1bSBNYXhpbXVtIGx1bWluYW5jZQpAcGFyYW0gbWluTHVtIE1pbmltdW0gbHVtaW5hbmNlCkBwYXJhbSB3b3JsZEx1bSBBdmVyYWdlIGx1bWluYW5jZSAod29ybGQgYWRhcHRhdGlvbiBsdW1pbmFuY2UpCkByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCiovCkJPT0wgCkx1bWluYW5jZUZyb21ZeHkoRklCSVRNQVAgKll4eSwgZmxvYXQgKm1heEx1bSwgZmxvYXQgKm1pbkx1bSwgZmxvYXQgKndvcmxkTHVtKSB7CglpZihGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKFl4eSkgIT0gRklUX1JHQkYpCgkJcmV0dXJuIEZBTFNFOwoKCWNvbnN0IHVuc2lnbmVkIHdpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChZeHkpOwoJY29uc3QgdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChZeHkpOwoJY29uc3QgdW5zaWduZWQgcGl0Y2ggID0gRnJlZUltYWdlX0dldFBpdGNoKFl4eSk7CgoJZmxvYXQgbWF4X2x1bSA9IDAsIG1pbl9sdW0gPSAwOwoJZG91YmxlIHN1bSA9IDA7CgoJQllURSAqYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhZeHkpOwoJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQljb25zdCBGSVJHQkYgKnBpeGVsID0gKEZJUkdCRiopYml0czsKCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCWNvbnN0IGZsb2F0IFkgPSBNQVgoMC4wRiwgcGl4ZWxbeF0ucmVkKTsvLyBhdm9pZCBuZWdhdGl2ZSB2YWx1ZXMKCQkJbWF4X2x1bSA9IChtYXhfbHVtIDwgWSkgPyBZIDogbWF4X2x1bTsJLy8gbWF4IEx1bWluYW5jZSBpbiB0aGUgc2NlbmUKCQkJbWluX2x1bSA9IChtaW5fbHVtIDwgWSkgPyBtaW5fbHVtIDogWTsJLy8gbWluIEx1bWluYW5jZSBpbiB0aGUgc2NlbmUKICAgICAgICAgICAgICAgICAgICAgICAgc3VtICs9IHN0ZDo6bG9nKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgMi4zZS01RiArIFkpOyAgLy8gY29udHJhc3QgY29uc3RhbnQgaW4gVHVtYmxpbiBwYXBlcgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLy8gbmV4dCBsaW5lCiAgICAgICAgICAgICAgICBiaXRzICs9IHBpdGNoOwoJfQoJLy8gbWF4aW11bSBsdW1pbmFuY2UKCSptYXhMdW0gPSBtYXhfbHVtOwoJLy8gbWluaW11bSBsdW1pbmFuY2UKCSptaW5MdW0gPSBtaW5fbHVtOwoJLy8gYXZlcmFnZSBsb2cgbHVtaW5hbmNlCglkb3VibGUgYXZnTG9nTHVtID0gKHN1bSAvICh3aWR0aCAqIGhlaWdodCkpOwoJLy8gd29ybGQgYWRhcHRhdGlvbiBsdW1pbmFuY2UKCSp3b3JsZEx1bSA9IChmbG9hdClleHAoYXZnTG9nTHVtKTsKCglyZXR1cm4gVFJVRTsKfQoKLyoqCkNsYW1wIFJHQkYgaW1hZ2UgaGlnaGVzdCB2YWx1ZXMgdG8gZGlzcGxheSB3aGl0ZSwgCnRoZW4gY29udmVydCB0byAyNC1iaXQgUkdCCiovCkZJQklUTUFQKiAKQ2xhbXBDb252ZXJ0UkdCRlRvMjQoRklCSVRNQVAgKnNyYykgewoJaWYoRnJlZUltYWdlX0dldEltYWdlVHlwZShzcmMpICE9IEZJVF9SR0JGKQoJCXJldHVybiBGQUxTRTsKCgljb25zdCB1bnNpZ25lZCB3aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCWNvbnN0IHVuc2lnbmVkIGhlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjKTsKCglGSUJJVE1BUCAqZHN0ID0gRnJlZUltYWdlX0FsbG9jYXRlKHdpZHRoLCBoZWlnaHQsIDI0LCBGSV9SR0JBX1JFRF9NQVNLLCBGSV9SR0JBX0dSRUVOX01BU0ssIEZJX1JHQkFfQkxVRV9NQVNLKTsKCWlmKCFkc3QpIHJldHVybiBOVUxMOwoKCWNvbnN0IHVuc2lnbmVkIHNyY19waXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goc3JjKTsKCWNvbnN0IHVuc2lnbmVkIGRzdF9waXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0KTsKCglCWVRFICpzcmNfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhzcmMpOwoJQllURSAqZHN0X2JpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoZHN0KTsKCglmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCWNvbnN0IEZJUkdCRiAqc3JjX3BpeGVsID0gKEZJUkdCRiopc3JjX2JpdHM7CgkJQllURSAqZHN0X3BpeGVsID0gKEJZVEUqKWRzdF9iaXRzOwoJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJY29uc3QgZmxvYXQgcmVkICAgPSAoc3JjX3BpeGVsW3hdLnJlZCA+IDEpICAgPyAxIDogc3JjX3BpeGVsW3hdLnJlZDsKCQkJY29uc3QgZmxvYXQgZ3JlZW4gPSAoc3JjX3BpeGVsW3hdLmdyZWVuID4gMSkgPyAxIDogc3JjX3BpeGVsW3hdLmdyZWVuOwoJCQljb25zdCBmbG9hdCBibHVlICA9IChzcmNfcGl4ZWxbeF0uYmx1ZSA+IDEpICA/IDEgOiBzcmNfcGl4ZWxbeF0uYmx1ZTsKCQkJCgkJCWRzdF9waXhlbFtGSV9SR0JBX1JFRF0gICA9IChCWVRFKSgyNTUuMEYgKiByZWQgICArIDAuNUYpOwoJCQlkc3RfcGl4ZWxbRklfUkdCQV9HUkVFTl0gPSAoQllURSkoMjU1LjBGICogZ3JlZW4gKyAwLjVGKTsKCQkJZHN0X3BpeGVsW0ZJX1JHQkFfQkxVRV0gID0gKEJZVEUpKDI1NS4wRiAqIGJsdWUgICsgMC41Rik7CgkJCWRzdF9waXhlbCArPSAzOwoJCX0KCQlzcmNfYml0cyArPSBzcmNfcGl0Y2g7CgkJZHN0X2JpdHMgKz0gZHN0X3BpdGNoOwoJfQoKCXJldHVybiBkc3Q7Cn0KCi8qKgpFeHRyYWN0IHRoZSBsdW1pbmFuY2UgY2hhbm5lbCBMIGZyb20gYSBSR0JGIGltYWdlLiAKTHVtaW5hbmNlIGlzIGNhbGN1bGF0ZWQgZnJvbSB0aGUgc1JHQiBtb2RlbCAoUkdCMlhZWiBtYXRyaXgpIAp1c2luZyBhIEQ2NSB3aGl0ZSBwb2ludCA6IApMID0gKCAwLjIxMjYgKiByICkgKyAoIDAuNzE1MiAqIGcgKSArICggMC4wNzIyICogYiApClJlZmVyZW5jZSA6IApBIFN0YW5kYXJkIERlZmF1bHQgQ29sb3IgU3BhY2UgZm9yIHRoZSBJbnRlcm5ldCAtIHNSR0IuIApbb25saW5lXSBodHRwOi8vd3d3LnczLm9yZy9HcmFwaGljcy9Db2xvci9zUkdCCiovCkZJQklUTUFQKiAgCkNvbnZlcnRSR0JGVG9ZKEZJQklUTUFQICpzcmMpIHsKCWlmKEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoc3JjKSAhPSBGSVRfUkdCRikKCQlyZXR1cm4gRkFMU0U7CgoJY29uc3QgdW5zaWduZWQgd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKHNyYyk7Cgljb25zdCB1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KHNyYyk7CgoJRklCSVRNQVAgKmRzdCA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoRklUX0ZMT0FULCB3aWR0aCwgaGVpZ2h0KTsKCWlmKCFkc3QpIHJldHVybiBOVUxMOwoKCWNvbnN0IHVuc2lnbmVkIHNyY19waXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goc3JjKTsKCWNvbnN0IHVuc2lnbmVkIGRzdF9waXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZHN0KTsKCgkKCUJZVEUgKnNyY19iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7CglCWVRFICpkc3RfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoKCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJY29uc3QgRklSR0JGICpzcmNfcGl4ZWwgPSAoRklSR0JGKilzcmNfYml0czsKCQlmbG9hdCAgKmRzdF9waXhlbCA9IChmbG9hdCopZHN0X2JpdHM7CgkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQljb25zdCBmbG9hdCBMID0gTFVNQV9SRUM3MDkoc3JjX3BpeGVsW3hdLnJlZCwgc3JjX3BpeGVsW3hdLmdyZWVuLCBzcmNfcGl4ZWxbeF0uYmx1ZSk7CgkJCWRzdF9waXhlbFt4XSA9IChMID4gMCkgPyBMIDogMDsKCQl9CgkJLy8gbmV4dCBsaW5lCgkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCX0KCglyZXR1cm4gZHN0Owp9CgovKioKR2V0IHRoZSBtYXhpbXVtLCBtaW5pbXVtLCBhdmVyYWdlIGx1bWluYW5jZSBhbmQgbG9nIGF2ZXJhZ2UgbHVtaW5hbmNlIGZyb20gYSBZIGltYWdlCkBwYXJhbSBkaWIgU291cmNlIFkgaW1hZ2UgdG8gYW5hbHl6ZQpAcGFyYW0gbWF4THVtIE1heGltdW0gbHVtaW5hbmNlCkBwYXJhbSBtaW5MdW0gTWluaW11bSBsdW1pbmFuY2UKQHBhcmFtIExhdiBBdmVyYWdlIGx1bWluYW5jZQpAcGFyYW0gTGxhdiBMb2cgYXZlcmFnZSBsdW1pbmFuY2UgKGFsc28ga25vd24gYXMgJ3dvcmxkIGFkYXB0YXRpb24gbHVtaW5hbmNlJykKQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKQHNlZSBDb252ZXJ0UkdCRlRvWSwgRnJlZUltYWdlX1Rtb1JlaW5oYXJkMDVFeAoqLwpCT09MIApMdW1pbmFuY2VGcm9tWShGSUJJVE1BUCAqZGliLCBmbG9hdCAqbWF4THVtLCBmbG9hdCAqbWluTHVtLCBmbG9hdCAqTGF2LCBmbG9hdCAqTGxhdikgewoJaWYoRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpICE9IEZJVF9GTE9BVCkKCQlyZXR1cm4gRkFMU0U7CgoJdW5zaWduZWQgd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKGRpYik7Cgl1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7Cgl1bnNpZ25lZCBwaXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZGliKTsKCglmbG9hdCBtYXhfbHVtID0gLTFlMjBGLCBtaW5fbHVtID0gMWUyMEY7Cglkb3VibGUgc3VtTHVtID0gMCwgc3VtTG9nTHVtID0gMDsKCglCWVRFICpiaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKGRpYik7Cglmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCWNvbnN0IGZsb2F0ICpwaXhlbCA9IChmbG9hdCopYml0czsKCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCWNvbnN0IGZsb2F0IFkgPSBwaXhlbFt4XTsKCQkJbWF4X2x1bSA9IChtYXhfbHVtIDwgWSkgPyBZIDogbWF4X2x1bTsJCQkJLy8gbWF4IEx1bWluYW5jZSBpbiB0aGUgc2NlbmUKCQkJbWluX2x1bSA9ICgoWSA+IDApICYmIChtaW5fbHVtIDwgWSkpID8gbWluX2x1bSA6IFk7CS8vIG1pbiBMdW1pbmFuY2UgaW4gdGhlIHNjZW5lCgkJCXN1bUx1bSArPSBZOwkJCQkJCQkJCQkvLyBhdmVyYWdlIGx1bWluYW5jZQogICAgICAgICAgICAgICAgICAgICAgICBzdW1Mb2dMdW0gKz0gc3RkOjpsb2coCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAyLjNlLTVGICsgWSk7ICAvLyBjb250cmFzdCBjb25zdGFudCBpbiBUdW1ibGluIHBhcGVyCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvLyBuZXh0IGxpbmUKICAgICAgICAgICAgICAgIGJpdHMgKz0gcGl0Y2g7Cgl9CgoJLy8gbWF4aW11bSBsdW1pbmFuY2UKCSptYXhMdW0gPSBtYXhfbHVtOwoJLy8gbWluaW11bSBsdW1pbmFuY2UKCSptaW5MdW0gPSBtaW5fbHVtOwoJLy8gYXZlcmFnZSBsdW1pbmFuY2UKCSpMYXYgPSAoZmxvYXQpKHN1bUx1bSAvICh3aWR0aCAqIGhlaWdodCkpOwoJLy8gYXZlcmFnZSBsb2cgbHVtaW5hbmNlLCBhLmsuYS4gd29ybGQgYWRhcHRhdGlvbiBsdW1pbmFuY2UKCSpMbGF2ID0gKGZsb2F0KWV4cChzdW1Mb2dMdW0gLyAod2lkdGggKiBoZWlnaHQpKTsKCglyZXR1cm4gVFJVRTsKfQovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljIHZvaWQgZmluZE1heE1pblBlcmNlbnRpbGUoRklCSVRNQVAgKlksIGZsb2F0IG1pblByY3QsIGZsb2F0ICptaW5MdW0sIGZsb2F0IG1heFByY3QsIGZsb2F0ICptYXhMdW0pIHsKCWludCB4LCB5OwoJaW50IHdpZHRoID0gRnJlZUltYWdlX0dldFdpZHRoKFkpOwoJaW50IGhlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoWSk7CglpbnQgcGl0Y2ggPSBGcmVlSW1hZ2VfR2V0UGl0Y2goWSk7CgoJc3RkOjp2ZWN0b3I8ZmxvYXQ+IHZZKHdpZHRoICogaGVpZ2h0KTsKCglCWVRFICpiaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKFkpOwoJZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQlmbG9hdCAqcGl4ZWwgPSAoZmxvYXQqKWJpdHM7CgkJZm9yKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQlpZihwaXhlbFt4XSAhPSAwKSB7CgkJCQl2WS5wdXNoX2JhY2socGl4ZWxbeF0pOwoJCQl9CgkJfQoJCWJpdHMgKz0gcGl0Y2g7Cgl9CgoJc3RkOjpzb3J0KHZZLmJlZ2luKCksIHZZLmVuZCgpKTsKCQoJKm1pbkx1bSA9IHZZLmF0KCBpbnQobWluUHJjdCAqIHZZLnNpemUoKSkgKTsKCSptYXhMdW0gPSB2WS5hdCggaW50KG1heFByY3QgKiB2WS5zaXplKCkpICk7Cn0KCi8qKgpDbGlwcGluZyBmdW5jdGlvbjxicj4KUmVtb3ZlIGFueSBleHRyZW1lbHkgYnJpZ2h0IGFuZC9vciBleHRyZW1lbHkgZGFyayBwaXhlbHMgCmFuZCBub3JtYWxpemUgYmV0d2VlbiAwIGFuZCAxLiAKQHBhcmFtIFkgSW5wdXQvT3V0cHV0IGltYWdlCkBwYXJhbSBtaW5QcmN0IE1pbmltdW0gcGVyY2VudGlsZQpAcGFyYW0gbWF4UHJjdCBNYXhpbXVtIHBlcmNlbnRpbGUKKi8Kdm9pZCAKTm9ybWFsaXplWShGSUJJVE1BUCAqWSwgZmxvYXQgbWluUHJjdCwgZmxvYXQgbWF4UHJjdCkgewoJaW50IHgsIHk7CglmbG9hdCBtYXhMdW0sIG1pbkx1bTsKCglpZihtaW5QcmN0ID4gbWF4UHJjdCkgewoJCS8vIHN3YXAgdmFsdWVzCgkJZmxvYXQgdCA9IG1pblByY3Q7IG1pblByY3QgPSBtYXhQcmN0OyBtYXhQcmN0ID0gdDsKCX0KCWlmKG1pblByY3QgPCAwKSBtaW5QcmN0ID0gMDsKCWlmKG1heFByY3QgPiAxKSBtYXhQcmN0ID0gMTsKCglpbnQgd2lkdGggPSBGcmVlSW1hZ2VfR2V0V2lkdGgoWSk7CglpbnQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChZKTsKCWludCBwaXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChZKTsKCgkvLyBmaW5kIG1heCAmIG1pbiBsdW1pbmFuY2UgdmFsdWVzCglpZigobWluUHJjdCA+IDApIHx8IChtYXhQcmN0IDwgMSkpIHsKCQltYXhMdW0gPSAwLCBtaW5MdW0gPSAwOwoJCWZpbmRNYXhNaW5QZXJjZW50aWxlKFksIG1pblByY3QsICZtaW5MdW0sIG1heFByY3QsICZtYXhMdW0pOwoJfSBlbHNlIHsKCQltYXhMdW0gPSAtMWUyMEYsIG1pbkx1bSA9IDFlMjBGOwoJCUJZVEUgKmJpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoWSk7CgkJZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJY29uc3QgZmxvYXQgKnBpeGVsID0gKGZsb2F0KiliaXRzOwoJCQlmb3IoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQljb25zdCBmbG9hdCB2YWx1ZSA9IHBpeGVsW3hdOwoJCQkJbWF4THVtID0gKG1heEx1bSA8IHZhbHVlKSA/IHZhbHVlIDogbWF4THVtOwkvLyBtYXggTHVtaW5hbmNlIGluIHRoZSBzY2VuZQoJCQkJbWluTHVtID0gKG1pbkx1bSA8IHZhbHVlKSA/IG1pbkx1bSA6IHZhbHVlOwkvLyBtaW4gTHVtaW5hbmNlIGluIHRoZSBzY2VuZQoJCQl9CgkJCS8vIG5leHQgbGluZQoJCQliaXRzICs9IHBpdGNoOwoJCX0KCX0KCWlmKG1heEx1bSA9PSBtaW5MdW0pIHJldHVybjsKCgkvLyBub3JtYWxpemUgdG8gcmFuZ2UgMC4uMSAKCWNvbnN0IGZsb2F0IGRpdmlkZXIgPSBtYXhMdW0gLSBtaW5MdW07CglCWVRFICpiaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKFkpOwoJZm9yKHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQlmbG9hdCAqcGl4ZWwgPSAoZmxvYXQqKWJpdHM7CgkJZm9yKHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQlwaXhlbFt4XSA9IChwaXhlbFt4XSAtIG1pbkx1bSkgLyBkaXZpZGVyOwoJCQlpZihwaXhlbFt4XSA8PSAwKSBwaXhlbFt4XSA9IEVQU0lMT047CgkJCWlmKHBpeGVsW3hdID4gMSkgcGl4ZWxbeF0gPSAxOwoJCX0KCQkvLyBuZXh0IGxpbmUKCQliaXRzICs9IHBpdGNoOwoJfQp9Cg==