Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBIaWdoIER5bmFtaWMgUmFuZ2UgYml0bWFwIGNvbnZlcnNpb24gcm91dGluZXMKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEhlcnbpIERyb2xvbiAoZHJvbG9uQGluZm9uaWUuZnIpCi8vIC0gTWloYWlsIE5heWRlbm92IChtbmF5ZGVub3ZAdXNlcnMuc291cmNlZm9yZ2UubmV0KQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgojaW5jbHVkZSAiVG9uZU1hcHBpbmcuaCIKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gQ29udmVydCBSR0IgdG8gYW5kIGZyb20gWXh5LCBzYW1lIGFzIGluIFJlaW5oYXJkIGV0IGFsLiBTSUdHUkFQSCAyMDAyCi8vIFJlZmVyZW5jZXMgOiAKLy8gWzFdIFJhZGlhbmNlIEhvbWUgUGFnZSBbT25saW5lXSBodHRwOi8vcmFkc2l0ZS5sYmwuZ292L3JhZGlhbmNlL0hPTUUuaHRtbAovLyBbMl0gRS4gUmVpbmhhcmQsIE0uIFN0YXJrLCBQLiBTaGlybGV5LCBhbmQgSi4gRmVyd2VyZGEsICAKLy8gICAgIFBob3RvZ3JhcGhpYyBUb25lIFJlcHJvZHVjdGlvbiBmb3IgRGlnaXRhbCBJbWFnZXMsIEFDTSBUcmFuc2FjdGlvbnMgb24gR3JhcGhpY3MsIAovLyAgICAgMjEoMyk6MjY3LTI3NiwgMjAwMiAoUHJvY2VlZGluZ3Mgb2YgU0lHR1JBUEggMjAwMikuIAovLyBbM10gSi4gVHVtYmxpbiBhbmQgSC5FLiBSdXNobWVpZXIsIAovLyAgICAgVG9uZSBSZXByb2R1Y3Rpb24gZm9yIFJlYWxpc3RpYyBJbWFnZXMuIElFRUUgQ29tcHV0ZXIgR3JhcGhpY3MgYW5kIEFwcGxpY2F0aW9ucywgCi8vICAgICAxMyg2KTo0Mi00OCwgMTk5My4KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCm5vbWluYWwgQ1JUIHByaW1hcmllcyAKKi8KLyoKc3RhdGljIGNvbnN0IGZsb2F0IENJRV94X3IgPSAwLjY0MEY7CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfeV9yID0gMC4zMzBGOwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3hfZyA9IDAuMjkwRjsKc3RhdGljIGNvbnN0IGZsb2F0IENJRV95X2cgPSAwLjYwMEY7CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfeF9iID0gMC4xNTBGOwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3lfYiA9IDAuMDYwRjsKc3RhdGljIGNvbnN0IGZsb2F0IENJRV94X3cgPSAwLjMzMzNGOwkvLyB1c2UgdHJ1ZSB3aGl0ZQpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3lfdyA9IDAuMzMzM0Y7CiovCi8qKgpzUkdCIHByaW1hcmllcwoqLwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3hfciA9IDAuNjQwRjsKc3RhdGljIGNvbnN0IGZsb2F0IENJRV95X3IgPSAwLjMzMEY7CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfeF9nID0gMC4zMDBGOwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3lfZyA9IDAuNjAwRjsKc3RhdGljIGNvbnN0IGZsb2F0IENJRV94X2IgPSAwLjE1MEY7CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfeV9iID0gMC4wNjBGOwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX3hfdyA9IDAuMzEyN0Y7CS8vIElsbHVtaW5hbnQgRDY1CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfeV93ID0gMC4zMjkwRjsKCnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfRCA9ICggQ0lFX3hfciooQ0lFX3lfZyAtIENJRV95X2IpICsgQ0lFX3hfZyooQ0lFX3lfYiAtIENJRV95X3IpICsgQ0lFX3hfYiooQ0lFX3lfciAtIENJRV95X2cpICk7CnN0YXRpYyBjb25zdCBmbG9hdCBDSUVfQ19yRCA9ICggKDEvQ0lFX3lfdykgKiAoIENJRV94X3cqKENJRV95X2cgLSBDSUVfeV9iKSAtIENJRV95X3cqKENJRV94X2cgLSBDSUVfeF9iKSArIENJRV94X2cqQ0lFX3lfYiAtIENJRV94X2IqQ0lFX3lfZykgKTsKc3RhdGljIGNvbnN0IGZsb2F0IENJRV9DX2dEID0gKCAoMS9DSUVfeV93KSAqICggQ0lFX3hfdyooQ0lFX3lfYiAtIENJRV95X3IpIC0gQ0lFX3lfdyooQ0lFX3hfYiAtIENJRV94X3IpIC0gQ0lFX3hfcipDSUVfeV9iICsgQ0lFX3hfYipDSUVfeV9yKSApOwpzdGF0aWMgY29uc3QgZmxvYXQgQ0lFX0NfYkQgPSAoICgxL0NJRV95X3cpICogKCBDSUVfeF93KihDSUVfeV9yIC0gQ0lFX3lfZykgLSBDSUVfeV93KihDSUVfeF9yIC0gQ0lFX3hfZykgKyBDSUVfeF9yKkNJRV95X2cgLSBDSUVfeF9nKkNJRV95X3IpICk7CgovKioKUkdCIHRvIFhZWiAobm8gd2hpdGUgYmFsYW5jZSkKKi8Kc3RhdGljIGNvbnN0IGZsb2F0ICBSR0IyWFlaWzNdWzNdID0gewoJeyBDSUVfeF9yKkNJRV9DX3JEIC8gQ0lFX0QsIAoJICBDSUVfeF9nKkNJRV9DX2dEIC8gQ0lFX0QsIAoJICBDSUVfeF9iKkNJRV9DX2JEIC8gQ0lFX0QgCgl9LAoJeyBDSUVfeV9yKkNJRV9DX3JEIC8gQ0lFX0QsIAoJICBDSUVfeV9nKkNJRV9DX2dEIC8gQ0lFX0QsIAoJICBDSUVfeV9iKkNJRV9DX2JEIC8gQ0lFX0QgCgl9LAoJeyAoMSAtIENJRV94X3ItQ0lFX3lfcikqQ0lFX0NfckQgLyBDSUVfRCwKCSAgKDEgLSBDSUVfeF9nLUNJRV95X2cpKkNJRV9DX2dEIC8gQ0lFX0QsCgkgICgxIC0gQ0lFX3hfYi1DSUVfeV9iKSpDSUVfQ19iRCAvIENJRV9ECgl9Cn07CgovKioKWFlaIHRvIFJHQiAobm8gd2hpdGUgYmFsYW5jZSkKKi8Kc3RhdGljIGNvbnN0IGZsb2F0ICBYWVoyUkdCWzNdWzNdID0gewoJeyhDSUVfeV9nIC0gQ0lFX3lfYiAtIENJRV94X2IqQ0lFX3lfZyArIENJRV95X2IqQ0lFX3hfZykgLyBDSUVfQ19yRCwKCSAoQ0lFX3hfYiAtIENJRV94X2cgLSBDSUVfeF9iKkNJRV95X2cgKyBDSUVfeF9nKkNJRV95X2IpIC8gQ0lFX0NfckQsCgkgKENJRV94X2cqQ0lFX3lfYiAtIENJRV94X2IqQ0lFX3lfZykgLyBDSUVfQ19yRAoJfSwKCXsoQ0lFX3lfYiAtIENJRV95X3IgLSBDSUVfeV9iKkNJRV94X3IgKyBDSUVfeV9yKkNJRV94X2IpIC8gQ0lFX0NfZ0QsCgkgKENJRV94X3IgLSBDSUVfeF9iIC0gQ0lFX3hfcipDSUVfeV9iICsgQ0lFX3hfYipDSUVfeV9yKSAvIENJRV9DX2dELAoJIChDSUVfeF9iKkNJRV95X3IgLSBDSUVfeF9yKkNJRV95X2IpIC8gQ0lFX0NfZ0QKCX0sCgl7KENJRV95X3IgLSBDSUVfeV9nIC0gQ0lFX3lfcipDSUVfeF9nICsgQ0lFX3lfZypDSUVfeF9yKSAvIENJRV9DX2JELAoJIChDSUVfeF9nIC0gQ0lFX3hfciAtIENJRV94X2cqQ0lFX3lfciArIENJRV94X3IqQ0lFX3lfZykgLyBDSUVfQ19iRCwKCSAoQ0lFX3hfcipDSUVfeV9nIC0gQ0lFX3hfZypDSUVfeV9yKSAvIENJRV9DX2JECgl9Cn07CgovKioKVGhpcyBnaXZlcyBhcHByb3hpbWF0ZWx5IHRoZSBmb2xsb3dpbmcgbWF0cmljZXMgOiAKCnN0YXRpYyBjb25zdCBmbG9hdCBSR0IyWFlaWzNdWzNdID0geyAKCXsgMC40MTIzOTA4M0YsIDAuMzU3NTg0MzNGLCAwLjE4MDQ4MDgxRiB9LAoJeyAwLjIxMjYzOTAzRiwgMC43MTUxNjg2NUYsIDAuMDcyMTkyMzE5RiB9LAoJeyAwLjAxOTMzMDgyMEYsIDAuMTE5MTk0NzNGLCAwLjk1MDUzMjIwRiB9Cn07CnN0YXRpYyBjb25zdCBmbG9hdCBYWVoyUkdCWzNdWzNdID0geyAKCXsgMy4yNDA5Njk5RiwgLTEuNTM3MzgzMkYsIC0wLjQ5ODYxMDc5RiB9LAoJeyAtMC45NjkyNDM3NkYsIDEuODc1OTY3NkYsIDAuMDQxNTU1MDg0RiB9LAoJeyAwLjA1NTYzMDAzNkYsIC0wLjIwMzk3Njg3RiwgMS4wNTY5NzE1RiB9Cn07CiovCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgY29uc3QgZmxvYXQgRVBTSUxPTiA9IDFlLTA2RjsKc3RhdGljIGNvbnN0IGZsb2F0IElORiA9IDFlKzEwRjsKCi8qKgpDb252ZXJ0IGluLXBsYWNlIGZsb2F0aW5nIHBvaW50IFJHQiBkYXRhIHRvIFl4eS48YnI+Ck9uIG91dHB1dCwgcGl4ZWwtPnJlZCA9PSBZLCBwaXhlbC0+Z3JlZW4gPT0geCwgcGl4ZWwtPmJsdWUgPT0geQpAcGFyYW0gZGliIElucHV0IFJHQkYgLyBPdXRwdXQgWXh5IGltYWdlCkByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCiovCkJPT0wgCkNvbnZlcnRJblBsYWNlUkdCRlRvWXh5KEZJQklUTUFQICpkaWIpIHsKCWZsb2F0IHJlc3VsdFszXTsKCglpZihGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKGRpYikgIT0gRklUX1JHQkYpCgkJcmV0dXJuIEZBTFNFOwoKCXVuc2lnbmVkIHdpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpOwoJdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChkaWIpOwoJdW5zaWduZWQgcGl0Y2ggID0gRnJlZUltYWdlX0dldFBpdGNoKGRpYik7CgkKCUJZVEUgKmJpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoZGliKTsKCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJRklSR0JGICpwaXhlbCA9IChGSVJHQkYqKWJpdHM7CgkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQlyZXN1bHRbMF0gPSByZXN1bHRbMV0gPSByZXN1bHRbMl0gPSAwOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgewoJCQkJcmVzdWx0W2ldICs9IFJHQjJYWVpbaV1bMF0gKiBwaXhlbFt4XS5yZWQ7CgkJCQlyZXN1bHRbaV0gKz0gUkdCMlhZWltpXVsxXSAqIHBpeGVsW3hdLmdyZWVuOwoJCQkJcmVzdWx0W2ldICs9IFJHQjJYWVpbaV1bMl0gKiBwaXhlbFt4XS5ibHVlOwoJCQl9CgkJCWZsb2F0IFcgPSByZXN1bHRbMF0gKyByZXN1bHRbMV0gKyByZXN1bHRbMl07CgkJCWZsb2F0IFkgPSByZXN1bHRbMV07CgkJCWlmKFcgPiAwKSB7IAoJCQkJcGl4ZWxbeF0ucmVkICAgPSBZOwkJCSAgICAvLyBZIAoJCQkJcGl4ZWxbeF0uZ3JlZW4gPSByZXN1bHRbMF0gLyBXOwkvLyB4IAoJCQkJcGl4ZWxbeF0uYmx1ZSAgPSByZXN1bHRbMV0gLyBXOwkvLyB5IAkKCQkJfSBlbHNlIHsKCQkJCXBpeGVsW3hdLnJlZCA9IHBpeGVsW3hdLmdyZWVuID0gcGl4ZWxbeF0uYmx1ZSA9IDA7CgkJCX0KCQl9CgkJLy8gbmV4dCBsaW5lCgkJYml0cyArPSBwaXRjaDsKCX0KCglyZXR1cm4gVFJVRTsKfQoKLyoqCkNvbnZlcnQgaW4tcGxhY2UgWXh5IGltYWdlIHRvIGZsb2F0aW5nIHBvaW50IFJHQiBkYXRhLjxicj4KT24gaW5wdXQsIHBpeGVsLT5yZWQgPT0gWSwgcGl4ZWwtPmdyZWVuID09IHgsIHBpeGVsLT5ibHVlID09IHkKQHBhcmFtIGRpYiBJbnB1dCBZeHkgLyBPdXRwdXQgUkdCRiBpbWFnZQpAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIEZBTFNFIG90aGVyd2lzZQoqLwpCT09MIApDb252ZXJ0SW5QbGFjZVl4eVRvUkdCRihGSUJJVE1BUCAqZGliKSB7CglmbG9hdCByZXN1bHRbM107CglmbG9hdCBYLCBZLCBaOwoKCWlmKEZyZWVJbWFnZV9HZXRJbWFnZVR5cGUoZGliKSAhPSBGSVRfUkdCRikKCQlyZXR1cm4gRkFMU0U7CgoJdW5zaWduZWQgd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKGRpYik7Cgl1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7Cgl1bnNpZ25lZCBwaXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZGliKTsKCglCWVRFICpiaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKGRpYik7Cglmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCUZJUkdCRiAqcGl4ZWwgPSAoRklSR0JGKiliaXRzOwoJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJWSA9IHBpeGVsW3hdLnJlZDsJICAgICAgICAvLyBZIAoJCQlyZXN1bHRbMV0gPSBwaXhlbFt4XS5ncmVlbjsJLy8geCAKCQkJcmVzdWx0WzJdID0gcGl4ZWxbeF0uYmx1ZTsJLy8geSAKCQkJaWYgKChZID4gRVBTSUxPTikgJiYgKHJlc3VsdFsxXSA+IEVQU0lMT04pICYmIChyZXN1bHRbMl0gPiBFUFNJTE9OKSkgewoJCQkJWCA9IChyZXN1bHRbMV0gKiBZKSAvIHJlc3VsdFsyXTsKCQkJCVogPSAoWCAvIHJlc3VsdFsxXSkgLSBYIC0gWTsKCQkJfSBlbHNlIHsKCQkJCVggPSBaID0gRVBTSUxPTjsKCQkJfQoJCQlwaXhlbFt4XS5yZWQgICA9IFg7CgkJCXBpeGVsW3hdLmdyZWVuID0gWTsKCQkJcGl4ZWxbeF0uYmx1ZSAgPSBaOwoJCQlyZXN1bHRbMF0gPSByZXN1bHRbMV0gPSByZXN1bHRbMl0gPSAwOwoJCQlmb3IgKGludCBpID0gMDsgaSA8IDM7IGkrKykgewoJCQkJcmVzdWx0W2ldICs9IFhZWjJSR0JbaV1bMF0gKiBwaXhlbFt4XS5yZWQ7CgkJCQlyZXN1bHRbaV0gKz0gWFlaMlJHQltpXVsxXSAqIHBpeGVsW3hdLmdyZWVuOwoJCQkJcmVzdWx0W2ldICs9IFhZWjJSR0JbaV1bMl0gKiBwaXhlbFt4XS5ibHVlOwoJCQl9CgkJCXBpeGVsW3hdLnJlZCAgID0gcmVzdWx0WzBdOwkvLyBSCgkJCXBpeGVsW3hdLmdyZWVuID0gcmVzdWx0WzFdOwkvLyBHCgkJCXBpeGVsW3hdLmJsdWUgID0gcmVzdWx0WzJdOwkvLyBCCgkJfQoJCS8vIG5leHQgbGluZQoJCWJpdHMgKz0gcGl0Y2g7Cgl9CgoJcmV0dXJuIFRSVUU7Cn0KCi8qKgpHZXQgdGhlIG1heGltdW0sIG1pbmltdW0gYW5kIGF2ZXJhZ2UgbHVtaW5hbmNlLjxicj4KT24gaW5wdXQsIHBpeGVsLT5yZWQgPT0gWSwgcGl4ZWwtPmdyZWVuID09IHgsIHBpeGVsLT5ibHVlID09IHkKQHBhcmFtIFl4eSBTb3VyY2UgWXh5IGltYWdlIHRvIGFuYWx5emUKQHBhcmFtIG1heEx1bSBNYXhpbXVtIGx1bWluYW5jZQpAcGFyYW0gbWluTHVtIE1pbmltdW0gbHVtaW5hbmNlCkBwYXJhbSB3b3JsZEx1bSBBdmVyYWdlIGx1bWluYW5jZSAod29ybGQgYWRhcHRhdGlvbiBsdW1pbmFuY2UpCkByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgRkFMU0Ugb3RoZXJ3aXNlCiovCkJPT0wgCkx1bWluYW5jZUZyb21ZeHkoRklCSVRNQVAgKll4eSwgZmxvYXQgKm1heEx1bSwgZmxvYXQgKm1pbkx1bSwgZmxvYXQgKndvcmxkTHVtKSB7CglpZihGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKFl4eSkgIT0gRklUX1JHQkYpCgkJcmV0dXJuIEZBTFNFOwoKCXVuc2lnbmVkIHdpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChZeHkpOwoJdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChZeHkpOwoJdW5zaWduZWQgcGl0Y2ggID0gRnJlZUltYWdlX0dldFBpdGNoKFl4eSk7CgoJZmxvYXQgbWF4X2x1bSA9IDAsIG1pbl9sdW0gPSAwOwoJZG91YmxlIHN1bSA9IDA7CgoJQllURSAqYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhZeHkpOwoJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQljb25zdCBGSVJHQkYgKnBpeGVsID0gKEZJUkdCRiopYml0czsKCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCWNvbnN0IGZsb2F0IFkgPSBwaXhlbFt4XS5yZWQ7CgkJCW1heF9sdW0gPSAobWF4X2x1bSA8IFkpID8gWSA6IG1heF9sdW07CS8vIG1heCBMdW1pbmFuY2UgaW4gdGhlIHNjZW5lCgkJCW1pbl9sdW0gPSAobWluX2x1bSA8IFkpID8gbWluX2x1bSA6IFk7CS8vIG1pbiBMdW1pbmFuY2UgaW4gdGhlIHNjZW5lCgkJCXN1bSArPSBsb2coMi4zZS01ICsgWSk7CQkJCQkvLyBjb250cmFzdCBjb25zdGFudCBpbiBUdW1ibGluIHBhcGVyCgkJfQoJCS8vIG5leHQgbGluZQoJCWJpdHMgKz0gcGl0Y2g7Cgl9CgkvLyBtYXhpbXVtIGx1bWluYW5jZQoJKm1heEx1bSA9IG1heF9sdW07CgkvLyBtaW5pbXVtIGx1bWluYW5jZQoJKm1pbkx1bSA9IG1pbl9sdW07CgkvLyBhdmVyYWdlIGxvZyBsdW1pbmFuY2UKCWRvdWJsZSBhdmdMb2dMdW0gPSAoc3VtIC8gKHdpZHRoICogaGVpZ2h0KSk7CgkvLyB3b3JsZCBhZGFwdGF0aW9uIGx1bWluYW5jZQoJKndvcmxkTHVtID0gKGZsb2F0KWV4cChhdmdMb2dMdW0pOwoKCXJldHVybiBUUlVFOwp9CgovKioKQ2xhbXAgUkdCRiBpbWFnZSBoaWdoZXN0IHZhbHVlcyB0byBkaXNwbGF5IHdoaXRlLCAKdGhlbiBjb252ZXJ0IHRvIDI0LWJpdCBSR0IKKi8KRklCSVRNQVAqIApDbGFtcENvbnZlcnRSR0JGVG8yNChGSUJJVE1BUCAqc3JjKSB7CglpZihGcmVlSW1hZ2VfR2V0SW1hZ2VUeXBlKHNyYykgIT0gRklUX1JHQkYpCgkJcmV0dXJuIEZBTFNFOwoKCXVuc2lnbmVkIHdpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChzcmMpOwoJdW5zaWduZWQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChzcmMpOwoKCUZJQklUTUFQICpkc3QgPSBGcmVlSW1hZ2VfQWxsb2NhdGUod2lkdGgsIGhlaWdodCwgMjQsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoJaWYoIWRzdCkgcmV0dXJuIE5VTEw7CgoJdW5zaWduZWQgc3JjX3BpdGNoICA9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmMpOwoJdW5zaWduZWQgZHN0X3BpdGNoICA9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3QpOwoKCUJZVEUgKnNyY19iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKHNyYyk7CglCWVRFICpkc3RfYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhkc3QpOwoKCWZvcih1bnNpZ25lZCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJY29uc3QgRklSR0JGICpzcmNfcGl4ZWwgPSAoRklSR0JGKilzcmNfYml0czsKCQlCWVRFICpkc3RfcGl4ZWwgPSAoQllURSopZHN0X2JpdHM7CgkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQljb25zdCBmbG9hdCByZWQgICA9IChzcmNfcGl4ZWxbeF0ucmVkID4gMSkgICA/IDEgOiBzcmNfcGl4ZWxbeF0ucmVkOwoJCQljb25zdCBmbG9hdCBncmVlbiA9IChzcmNfcGl4ZWxbeF0uZ3JlZW4gPiAxKSA/IDEgOiBzcmNfcGl4ZWxbeF0uZ3JlZW47CgkJCWNvbnN0IGZsb2F0IGJsdWUgID0gKHNyY19waXhlbFt4XS5ibHVlID4gMSkgID8gMSA6IHNyY19waXhlbFt4XS5ibHVlOwoJCQkKCQkJZHN0X3BpeGVsW0ZJX1JHQkFfUkVEXSAgID0gKEJZVEUpKDI1NSAqIHJlZCAgICsgMC41KTsKCQkJZHN0X3BpeGVsW0ZJX1JHQkFfR1JFRU5dID0gKEJZVEUpKDI1NSAqIGdyZWVuICsgMC41KTsKCQkJZHN0X3BpeGVsW0ZJX1JHQkFfQkxVRV0gID0gKEJZVEUpKDI1NSAqIGJsdWUgICsgMC41KTsKCQkJZHN0X3BpeGVsICs9IDM7CgkJfQoJCXNyY19iaXRzICs9IHNyY19waXRjaDsKCQlkc3RfYml0cyArPSBkc3RfcGl0Y2g7Cgl9CgoJcmV0dXJuIGRzdDsKfQoKLyoqCkV4dHJhY3QgdGhlIGx1bWluYW5jZSBjaGFubmVsIEwgZnJvbSBhIFJHQkYgaW1hZ2UuIApMdW1pbmFuY2UgaXMgY2FsY3VsYXRlZCBmcm9tIHRoZSBzUkdCIG1vZGVsIChSR0IyWFlaIG1hdHJpeCkgCnVzaW5nIGEgRDY1IHdoaXRlIHBvaW50IDogCkwgPSAoIDAuMjEyNiAqIHIgKSArICggMC43MTUyICogZyApICsgKCAwLjA3MjIgKiBiICkKUmVmZXJlbmNlIDogCkEgU3RhbmRhcmQgRGVmYXVsdCBDb2xvciBTcGFjZSBmb3IgdGhlIEludGVybmV0IC0gc1JHQi4gCltvbmxpbmVdIGh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL0NvbG9yL3NSR0IKKi8KRklCSVRNQVAqICAKQ29udmVydFJHQkZUb1koRklCSVRNQVAgKnNyYykgewoJaWYoRnJlZUltYWdlX0dldEltYWdlVHlwZShzcmMpICE9IEZJVF9SR0JGKQoJCXJldHVybiBGQUxTRTsKCgl1bnNpZ25lZCB3aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoc3JjKTsKCXVuc2lnbmVkIGhlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoc3JjKTsKCglGSUJJVE1BUCAqZHN0ID0gRnJlZUltYWdlX0FsbG9jYXRlVChGSVRfRkxPQVQsIHdpZHRoLCBoZWlnaHQpOwoJaWYoIWRzdCkgcmV0dXJuIE5VTEw7CgoJdW5zaWduZWQgc3JjX3BpdGNoICA9IEZyZWVJbWFnZV9HZXRQaXRjaChzcmMpOwoJdW5zaWduZWQgZHN0X3BpdGNoICA9IEZyZWVJbWFnZV9HZXRQaXRjaChkc3QpOwoKCQoJQllURSAqc3JjX2JpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoc3JjKTsKCUJZVEUgKmRzdF9iaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKGRzdCk7CgoJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQljb25zdCBGSVJHQkYgKnNyY19waXhlbCA9IChGSVJHQkYqKXNyY19iaXRzOwoJCWZsb2F0ICAqZHN0X3BpeGVsID0gKGZsb2F0Kilkc3RfYml0czsKCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCWZsb2F0IEwgPSAwLjIxMjZGICogc3JjX3BpeGVsW3hdLnJlZCArIDAuNzE1MkYgKiBzcmNfcGl4ZWxbeF0uZ3JlZW4gKyAwLjA3MjJGICogc3JjX3BpeGVsW3hdLmJsdWU7CgkJCWRzdF9waXhlbFt4XSA9IChMID4gMCkgPyBMIDogMDsKCQl9CgkJLy8gbmV4dCBsaW5lCgkJc3JjX2JpdHMgKz0gc3JjX3BpdGNoOwoJCWRzdF9iaXRzICs9IGRzdF9waXRjaDsKCX0KCglyZXR1cm4gZHN0Owp9CgovKioKR2V0IHRoZSBtYXhpbXVtLCBtaW5pbXVtLCBhdmVyYWdlIGx1bWluYW5jZSBhbmQgbG9nIGF2ZXJhZ2UgbHVtaW5hbmNlIGZyb20gYSBZIGltYWdlCkBwYXJhbSBkaWIgU291cmNlIFkgaW1hZ2UgdG8gYW5hbHl6ZQpAcGFyYW0gbWF4THVtIE1heGltdW0gbHVtaW5hbmNlCkBwYXJhbSBtaW5MdW0gTWluaW11bSBsdW1pbmFuY2UKQHBhcmFtIExhdiBBdmVyYWdlIGx1bWluYW5jZQpAcGFyYW0gTGxhdiBMb2cgYXZlcmFnZSBsdW1pbmFuY2UgKGFsc28ga25vd24gYXMgJ3dvcmxkIGFkYXB0YXRpb24gbHVtaW5hbmNlJykKQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBGQUxTRSBvdGhlcndpc2UKQHNlZSBDb252ZXJ0UkdCRlRvWSwgRnJlZUltYWdlX1Rtb1JlaW5oYXJkMDVFeAoqLwpCT09MIApMdW1pbmFuY2VGcm9tWShGSUJJVE1BUCAqZGliLCBmbG9hdCAqbWF4THVtLCBmbG9hdCAqbWluTHVtLCBmbG9hdCAqTGF2LCBmbG9hdCAqTGxhdikgewoJaWYoRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpICE9IEZJVF9GTE9BVCkKCQlyZXR1cm4gRkFMU0U7CgoJdW5zaWduZWQgd2lkdGggID0gRnJlZUltYWdlX0dldFdpZHRoKGRpYik7Cgl1bnNpZ25lZCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7Cgl1bnNpZ25lZCBwaXRjaCAgPSBGcmVlSW1hZ2VfR2V0UGl0Y2goZGliKTsKCglmbG9hdCBtYXhfbHVtID0gLTFlMjBGLCBtaW5fbHVtID0gMWUyMEY7Cglkb3VibGUgc3VtTHVtID0gMCwgc3VtTG9nTHVtID0gMDsKCglCWVRFICpiaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRCaXRzKGRpYik7Cglmb3IodW5zaWduZWQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCWNvbnN0IGZsb2F0ICpwaXhlbCA9IChmbG9hdCopYml0czsKCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCWNvbnN0IGZsb2F0IFkgPSBwaXhlbFt4XTsKCQkJbWF4X2x1bSA9IChtYXhfbHVtIDwgWSkgPyBZIDogbWF4X2x1bTsJCQkJLy8gbWF4IEx1bWluYW5jZSBpbiB0aGUgc2NlbmUKCQkJbWluX2x1bSA9ICgoWSA+IDApICYmIChtaW5fbHVtIDwgWSkpID8gbWluX2x1bSA6IFk7CS8vIG1pbiBMdW1pbmFuY2UgaW4gdGhlIHNjZW5lCgkJCXN1bUx1bSArPSBZOwkJCQkJCQkJCQkvLyBhdmVyYWdlIGx1bWluYW5jZQoJCQlzdW1Mb2dMdW0gKz0gbG9nKDIuM2UtNSArIFkpOwkJCQkJCS8vIGNvbnRyYXN0IGNvbnN0YW50IGluIFR1bWJsaW4gcGFwZXIKCQl9CgkJLy8gbmV4dCBsaW5lCgkJYml0cyArPSBwaXRjaDsKCX0KCgkvLyBtYXhpbXVtIGx1bWluYW5jZQoJKm1heEx1bSA9IG1heF9sdW07CgkvLyBtaW5pbXVtIGx1bWluYW5jZQoJKm1pbkx1bSA9IG1pbl9sdW07CgkvLyBhdmVyYWdlIGx1bWluYW5jZQoJKkxhdiA9IChmbG9hdCkoc3VtTHVtIC8gKHdpZHRoICogaGVpZ2h0KSk7CgkvLyBhdmVyYWdlIGxvZyBsdW1pbmFuY2UsIGEuay5hLiB3b3JsZCBhZGFwdGF0aW9uIGx1bWluYW5jZQoJKkxsYXYgPSAoZmxvYXQpZXhwKHN1bUxvZ0x1bSAvICh3aWR0aCAqIGhlaWdodCkpOwoKCXJldHVybiBUUlVFOwp9Ci8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgdm9pZCBmaW5kTWF4TWluUGVyY2VudGlsZShGSUJJVE1BUCAqWSwgZmxvYXQgbWluUHJjdCwgZmxvYXQgKm1pbkx1bSwgZmxvYXQgbWF4UHJjdCwgZmxvYXQgKm1heEx1bSkgewoJaW50IHgsIHk7CglpbnQgd2lkdGggPSBGcmVlSW1hZ2VfR2V0V2lkdGgoWSk7CglpbnQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChZKTsKCWludCBwaXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChZKTsKCglzdGQ6OnZlY3RvcjxmbG9hdD4gdlkod2lkdGggKiBoZWlnaHQpOwoKCUJZVEUgKmJpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoWSk7Cglmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCWZsb2F0ICpwaXhlbCA9IChmbG9hdCopYml0czsKCQlmb3IoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCWlmKHBpeGVsW3hdICE9IDApIHsKCQkJCXZZLnB1c2hfYmFjayhwaXhlbFt4XSk7CgkJCX0KCQl9CgkJYml0cyArPSBwaXRjaDsKCX0KCglzdGQ6OnNvcnQodlkuYmVnaW4oKSwgdlkuZW5kKCkpOwoJCgkqbWluTHVtID0gdlkuYXQoIGludChtaW5QcmN0ICogdlkuc2l6ZSgpKSApOwoJKm1heEx1bSA9IHZZLmF0KCBpbnQobWF4UHJjdCAqIHZZLnNpemUoKSkgKTsKfQoKLyoqCkNsaXBwaW5nIGZ1bmN0aW9uPGJyPgpSZW1vdmUgYW55IGV4dHJlbWVseSBicmlnaHQgYW5kL29yIGV4dHJlbWVseSBkYXJrIHBpeGVscyAKYW5kIG5vcm1hbGl6ZSBiZXR3ZWVuIDAgYW5kIDEuIApAcGFyYW0gWSBJbnB1dC9PdXRwdXQgaW1hZ2UKQHBhcmFtIG1pblByY3QgTWluaW11bSBwZXJjZW50aWxlCkBwYXJhbSBtYXhQcmN0IE1heGltdW0gcGVyY2VudGlsZQoqLwp2b2lkIApOb3JtYWxpemVZKEZJQklUTUFQICpZLCBmbG9hdCBtaW5QcmN0LCBmbG9hdCBtYXhQcmN0KSB7CglpbnQgeCwgeTsKCWZsb2F0IG1heEx1bSwgbWluTHVtOwoKCWlmKG1pblByY3QgPiBtYXhQcmN0KSB7CgkJLy8gc3dhcCB2YWx1ZXMKCQlmbG9hdCB0ID0gbWluUHJjdDsgbWluUHJjdCA9IG1heFByY3Q7IG1heFByY3QgPSB0OwoJfQoJaWYobWluUHJjdCA8IDApIG1pblByY3QgPSAwOwoJaWYobWF4UHJjdCA+IDEpIG1heFByY3QgPSAxOwoKCWludCB3aWR0aCA9IEZyZWVJbWFnZV9HZXRXaWR0aChZKTsKCWludCBoZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KFkpOwoJaW50IHBpdGNoID0gRnJlZUltYWdlX0dldFBpdGNoKFkpOwoKCS8vIGZpbmQgbWF4ICYgbWluIGx1bWluYW5jZSB2YWx1ZXMKCWlmKChtaW5QcmN0ID4gMCkgfHwgKG1heFByY3QgPCAxKSkgewoJCW1heEx1bSA9IDAsIG1pbkx1bSA9IDA7CgkJZmluZE1heE1pblBlcmNlbnRpbGUoWSwgbWluUHJjdCwgJm1pbkx1bSwgbWF4UHJjdCwgJm1heEx1bSk7Cgl9IGVsc2UgewoJCW1heEx1bSA9IC0xZTIwRiwgbWluTHVtID0gMWUyMEY7CgkJQllURSAqYml0cyA9IChCWVRFKilGcmVlSW1hZ2VfR2V0Qml0cyhZKTsKCQlmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQljb25zdCBmbG9hdCAqcGl4ZWwgPSAoZmxvYXQqKWJpdHM7CgkJCWZvcih4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCWNvbnN0IGZsb2F0IHZhbHVlID0gcGl4ZWxbeF07CgkJCQltYXhMdW0gPSAobWF4THVtIDwgdmFsdWUpID8gdmFsdWUgOiBtYXhMdW07CS8vIG1heCBMdW1pbmFuY2UgaW4gdGhlIHNjZW5lCgkJCQltaW5MdW0gPSAobWluTHVtIDwgdmFsdWUpID8gbWluTHVtIDogdmFsdWU7CS8vIG1pbiBMdW1pbmFuY2UgaW4gdGhlIHNjZW5lCgkJCX0KCQkJLy8gbmV4dCBsaW5lCgkJCWJpdHMgKz0gcGl0Y2g7CgkJfQoJfQoJaWYobWF4THVtID09IG1pbkx1bSkgcmV0dXJuOwoKCS8vIG5vcm1hbGl6ZSB0byByYW5nZSAwLi4xIAoJY29uc3QgZmxvYXQgZGl2aWRlciA9IG1heEx1bSAtIG1pbkx1bTsKCUJZVEUgKmJpdHMgPSAoQllURSopRnJlZUltYWdlX0dldEJpdHMoWSk7Cglmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCWZsb2F0ICpwaXhlbCA9IChmbG9hdCopYml0czsKCQlmb3IoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCXBpeGVsW3hdID0gKHBpeGVsW3hdIC0gbWluTHVtKSAvIGRpdmlkZXI7CgkJCWlmKHBpeGVsW3hdIDw9IDApIHBpeGVsW3hdID0gRVBTSUxPTjsKCQkJaWYocGl4ZWxbeF0gPiAxKSBwaXhlbFt4XSA9IDE7CgkJfQoJCS8vIG5leHQgbGluZQoJCWJpdHMgKz0gcGl0Y2g7Cgl9Cn0K