Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBJQ08gTG9hZGVyIGFuZCBXcml0ZXIKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEZsb3JpcyB2YW4gZGVuIEJlcmcgKGZsdmRiZXJnQHd4cy5ubCkKLy8gLSBIZXJ26SBEcm9sb24gKGRyb2xvbkBpbmZvbmllLmZyKQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIENvbnN0YW50cyArIGhlYWRlcnMKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKI2lmZGVmIF9XSU4zMgojcHJhZ21hIHBhY2socHVzaCwgMSkKI2Vsc2UKI3ByYWdtYSBwYWNrKDEpCiNlbmRpZgoKLy8gVGhlc2UgbmV4dCB0d28gc3RydWN0cyByZXByZXNlbnQgaG93IHRoZSBpY29uIGluZm9ybWF0aW9uIGlzIHN0b3JlZAovLyBpbiBhbiBJQ08gZmlsZS4KCnR5cGVkZWYgc3RydWN0IHRhZ0lDT05IRUFERVIgewoJV09SRAkJCWlkUmVzZXJ2ZWQ7ICAgLy8gcmVzZXJ2ZWQKCVdPUkQJCQlpZFR5cGU7ICAgICAgIC8vIHJlc291cmNlIHR5cGUgKDEgZm9yIGljb25zKQoJV09SRAkJCWlkQ291bnQ7ICAgICAgLy8gaG93IG1hbnkgaW1hZ2VzPwp9IElDT05IRUFERVI7Cgp0eXBlZGVmIHN0cnVjdCB0YWdJQ09ORElSRUNUT1JZRU5UUlkgewoJQllURQliV2lkdGg7ICAgICAgICAgICAgICAgLy8gd2lkdGggb2YgdGhlIGltYWdlCglCWVRFCWJIZWlnaHQ7ICAgICAgICAgICAgICAvLyBoZWlnaHQgb2YgdGhlIGltYWdlICh0aW1lcyAyKQoJQllURQliQ29sb3JDb3VudDsgICAgICAgICAgLy8gbnVtYmVyIG9mIGNvbG9ycyBpbiBpbWFnZSAoMCBpZiA+PThicHApCglCWVRFCWJSZXNlcnZlZDsgICAgICAgICAgICAvLyByZXNlcnZlZAoJV09SRAl3UGxhbmVzOyAgICAgICAgICAgICAgLy8gY29sb3IgUGxhbmVzCglXT1JECXdCaXRDb3VudDsgICAgICAgICAgICAvLyBiaXRzIHBlciBwaXhlbAoJRFdPUkQJZHdCeXRlc0luUmVzOyAgICAgICAgIC8vIGhvdyBtYW55IGJ5dGVzIGluIHRoaXMgcmVzb3VyY2U/CglEV09SRAlkd0ltYWdlT2Zmc2V0OyAgICAgICAgLy8gd2hlcmUgaW4gdGhlIGZpbGUgaXMgdGhpcyBpbWFnZQp9IElDT05ESVJFTlRSWTsKCiNpZmRlZiBfV0lOMzIKI3ByYWdtYSBwYWNrKHBvcCkKI2Vsc2UKI3ByYWdtYSBwYWNrKCkKI2VuZGlmCgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFN0YXRpYyBoZWxwZXJzCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8qKiAgSG93IHdpZGUsIGluIGJ5dGVzLCB3b3VsZCB0aGlzIG1hbnkgYml0cyBiZSwgRFdPUkQgYWxpZ25lZCA/CiovCnN0YXRpYyBpbnQgCldpZHRoQnl0ZXMoaW50IGJpdHMpIHsKCXJldHVybiAoKCgoYml0cykgKyAzMSk+PjUpPDwyKTsKfQoKLyoqIENhbGN1bGF0ZXMgdGhlIHNpemUgb2YgYSBzaW5nbGUgaWNvbiBpbWFnZQpAcmV0dXJuIFJldHVybnMgdGhlIHNpemUgZm9yIHRoYXQgaW1hZ2UKKi8Kc3RhdGljIERXT1JEIApDYWxjdWxhdGVJbWFnZVNpemUoRklCSVRNQVAqIGljb25fZGliKSB7CglEV09SRCBkd051bUJ5dGVzID0gMDsKCgl1bnNpZ25lZCBjb2xvcnMJCT0gRnJlZUltYWdlX0dldENvbG9yc1VzZWQoaWNvbl9kaWIpOwoJdW5zaWduZWQgd2lkdGgJCT0gRnJlZUltYWdlX0dldFdpZHRoKGljb25fZGliKTsKCXVuc2lnbmVkIGhlaWdodAkJPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGljb25fZGliKTsKCXVuc2lnbmVkIHBpdGNoCQk9IEZyZWVJbWFnZV9HZXRQaXRjaChpY29uX2RpYik7CgoJZHdOdW1CeXRlcyA9IHNpemVvZiggQklUTUFQSU5GT0hFQURFUiApOwkvLyBoZWFkZXIKCWR3TnVtQnl0ZXMgKz0gY29sb3JzICogc2l6ZW9mKFJHQlFVQUQpOwkJLy8gcGFsZXR0ZQoJZHdOdW1CeXRlcyArPSBoZWlnaHQgKiBwaXRjaDsJCQkJLy8gWE9SIG1hc2sKCWR3TnVtQnl0ZXMgKz0gaGVpZ2h0ICogV2lkdGhCeXRlcyh3aWR0aCk7CS8vIEFORCBtYXNrCgoJcmV0dXJuIGR3TnVtQnl0ZXM7Cn0KCi8qKiBDYWxjdWxhdGVzIHRoZSBmaWxlIG9mZnNldCBmb3IgYW4gaWNvbiBpbWFnZQpAcmV0dXJuIFJldHVybnMgdGhlIGZpbGUgb2Zmc2V0IGZvciB0aGF0IGltYWdlCiovCnN0YXRpYyBEV09SRCAKQ2FsY3VsYXRlSW1hZ2VPZmZzZXQoc3RkOjp2ZWN0b3I8RklCSVRNQVAqPiYgdlBhZ2VzLCBpbnQgbkluZGV4ICkgewoJRFdPUkQJZHdTaXplOwoKICAgIC8vIGNhbGN1bGF0ZSB0aGUgSUNPIGhlYWRlciBzaXplCiAgICBkd1NpemUgPSBzaXplb2YoSUNPTkhFQURFUik7IAogICAgLy8gYWRkIHRoZSBJQ09ORElSRU5UUlkncwogICAgZHdTaXplICs9IChEV09SRCkoIHZQYWdlcy5zaXplKCkgKiBzaXplb2YoSUNPTkRJUkVOVFJZKSApOwogICAgLy8gYWRkIHRoZSBzaXplcyBvZiB0aGUgcHJldmlvdXMgaW1hZ2VzCiAgICBmb3IoaW50IGsgPSAwOyBrIDwgbkluZGV4OyBrKyspIHsKCQlGSUJJVE1BUCAqaWNvbl9kaWIgPSAoRklCSVRNQVAqKXZQYWdlc1trXTsKCQlkd1NpemUgKz0gQ2FsY3VsYXRlSW1hZ2VTaXplKGljb25fZGliKTsKCX0KCiAgICByZXR1cm4gZHdTaXplOwp9CgojaWZkZWYgRlJFRUlNQUdFX0JJR0VORElBTgpzdGF0aWMgdm9pZApTd2FwSW5mb0hlYWRlcihCSVRNQVBJTkZPSEVBREVSICpoZWFkZXIpIHsKCVN3YXBMb25nKCZoZWFkZXItPmJpU2l6ZSk7CglTd2FwTG9uZygoRFdPUkQgKikmaGVhZGVyLT5iaVdpZHRoKTsKCVN3YXBMb25nKChEV09SRCAqKSZoZWFkZXItPmJpSGVpZ2h0KTsKCVN3YXBTaG9ydCgmaGVhZGVyLT5iaVBsYW5lcyk7CglTd2FwU2hvcnQoJmhlYWRlci0+YmlCaXRDb3VudCk7CglTd2FwTG9uZygmaGVhZGVyLT5iaUNvbXByZXNzaW9uKTsKCVN3YXBMb25nKCZoZWFkZXItPmJpU2l6ZUltYWdlKTsKCVN3YXBMb25nKChEV09SRCAqKSZoZWFkZXItPmJpWFBlbHNQZXJNZXRlcik7CglTd2FwTG9uZygoRFdPUkQgKikmaGVhZGVyLT5iaVlQZWxzUGVyTWV0ZXIpOwoJU3dhcExvbmcoJmhlYWRlci0+YmlDbHJVc2VkKTsKCVN3YXBMb25nKCZoZWFkZXItPmJpQ2xySW1wb3J0YW50KTsKfQoKc3RhdGljIHZvaWQKU3dhcEljb25IZWFkZXIoSUNPTkhFQURFUiAqaGVhZGVyKSB7CglTd2FwU2hvcnQoJmhlYWRlci0+aWRSZXNlcnZlZCk7CglTd2FwU2hvcnQoJmhlYWRlci0+aWRUeXBlKTsKCVN3YXBTaG9ydCgmaGVhZGVyLT5pZENvdW50KTsKfQoKc3RhdGljIHZvaWQKU3dhcEljb25EaXJFbnRyaWVzKElDT05ESVJFTlRSWSAqZW50LCBpbnQgbnVtKSB7Cgl3aGlsZShudW0pIHsKCQlTd2FwU2hvcnQoJmVudC0+d1BsYW5lcyk7CgkJU3dhcFNob3J0KCZlbnQtPndCaXRDb3VudCk7CgkJU3dhcExvbmcoJmVudC0+ZHdCeXRlc0luUmVzKTsKCQlTd2FwTG9uZygmZW50LT5kd0ltYWdlT2Zmc2V0KTsKCQludW0tLTsKCQllbnQrKzsKCX0KfQojZW5kaWYKCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8gUGx1Z2luIEludGVyZmFjZQovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpzdGF0aWMgaW50IHNfZm9ybWF0X2lkOwoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQbHVnaW4gSW1wbGVtZW50YXRpb24KLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKRm9ybWF0KCkgewoJcmV0dXJuICJJQ08iOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpEZXNjcmlwdGlvbigpIHsKCXJldHVybiAiV2luZG93cyBJY29uIjsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKRXh0ZW5zaW9uKCkgewoJcmV0dXJuICJpY28iOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpSZWdFeHByKCkgewoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WCk1pbWVUeXBlKCkgewoJcmV0dXJuICJpbWFnZS94LWljb24iOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKVmFsaWRhdGUoRnJlZUltYWdlSU8gKmlvLCBmaV9oYW5kbGUgaGFuZGxlKSB7CglJQ09OSEVBREVSIGljb25faGVhZGVyOwoKCWlvLT5yZWFkX3Byb2MoJmljb25faGVhZGVyLCBzaXplb2YoSUNPTkhFQURFUiksIDEsIGhhbmRsZSk7CiNpZmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCglTd2FwSWNvbkhlYWRlcigmaWNvbl9oZWFkZXIpOwojZW5kaWYKCglyZXR1cm4gKChpY29uX2hlYWRlci5pZFJlc2VydmVkID09IDApICYmIChpY29uX2hlYWRlci5pZFR5cGUgPT0gMSkgJiYgKGljb25faGVhZGVyLmlkQ291bnQgPiAwKSk7Cn0KCnN0YXRpYyBCT09MIERMTF9DQUxMQ09OVgpTdXBwb3J0c0V4cG9ydERlcHRoKGludCBkZXB0aCkgewoJcmV0dXJuICgKCQkJKGRlcHRoID09IDEpIHx8CgkJCShkZXB0aCA9PSA0KSB8fAoJCQkoZGVwdGggPT0gOCkgfHwKCQkJKGRlcHRoID09IDE2KSB8fAoJCQkoZGVwdGggPT0gMjQpIHx8CgkJCShkZXB0aCA9PSAzMikKCQkpOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYgClN1cHBvcnRzRXhwb3J0VHlwZShGUkVFX0lNQUdFX1RZUEUgdHlwZSkgewoJcmV0dXJuICh0eXBlID09IEZJVF9CSVRNQVApID8gVFJVRSA6IEZBTFNFOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgdm9pZCAqIERMTF9DQUxMQ09OVgpPcGVuKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgQk9PTCByZWFkKSB7CglJQ09OSEVBREVSICpscElIID0gTlVMTDsKCgkvLyBBbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBoZWFkZXIgc3RydWN0dXJlCglpZigobHBJSCA9IChJQ09OSEVBREVSKiltYWxsb2MoIHNpemVvZihJQ09OSEVBREVSKSApKSA9PSBOVUxMKSAKCQlyZXR1cm4gTlVMTDsKCglpZiAocmVhZCkgewoJCS8vIFJlYWQgaW4gdGhlIGhlYWRlcgoJCWlvLT5yZWFkX3Byb2MobHBJSCwgMSwgc2l6ZW9mKElDT05IRUFERVIpLCBoYW5kbGUpOwojaWZkZWYgRlJFRUlNQUdFX0JJR0VORElBTgoJU3dhcEljb25IZWFkZXIobHBJSCk7CiNlbmRpZgoKCQlpZighKGxwSUgtPmlkUmVzZXJ2ZWQgPT0gMCkgfHwgIShscElILT5pZFR5cGUgPT0gMSkpIHsKCQkJLy8gTm90IGFuIElDTyBmaWxlCgkJCWZyZWUobHBJSCk7CgkJCXJldHVybiBOVUxMOwoJCX0KCX0KCWVsc2UgewoJCS8vIEZpbGwgdGhlIGhlYWRlcgoJCWxwSUgtPmlkUmVzZXJ2ZWQgPSAwOwoJCWxwSUgtPmlkVHlwZSA9IDE7CgkJbHBJSC0+aWRDb3VudCA9IDA7Cgl9CglyZXR1cm4gbHBJSDsKfQoKc3RhdGljIHZvaWQgRExMX0NBTExDT05WCkNsb3NlKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgdm9pZCAqZGF0YSkgewoJLy8gZnJlZSB0aGUgaGVhZGVyIHN0cnVjdHVyZQoJSUNPTkhFQURFUiAqbHBJSCA9IChJQ09OSEVBREVSKilkYXRhOwoJZnJlZShscElIKTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKc3RhdGljIGludCBETExfQ0FMTENPTlYKUGFnZUNvdW50KEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgdm9pZCAqZGF0YSkgewoJSUNPTkhFQURFUiAqbHBJSCA9IChJQ09OSEVBREVSKilkYXRhOwoKCWlmKGxwSUgpIHsKCQlyZXR1cm4gbHBJSC0+aWRDb3VudDsKCX0KCXJldHVybiAxOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgRklCSVRNQVAgKiBETExfQ0FMTENPTlYKTG9hZChGcmVlSW1hZ2VJTyAqaW8sIGZpX2hhbmRsZSBoYW5kbGUsIGludCBwYWdlLCBpbnQgZmxhZ3MsIHZvaWQgKmRhdGEpIHsKCWlmIChwYWdlID09IC0xKQoJCXBhZ2UgPSAwOwoKCWlmIChoYW5kbGUgIT0gTlVMTCkgewoJCUZJQklUTUFQICpkaWIgPSBOVUxMOwoKCQkvLyBnZXQgdGhlIGljb24gaGVhZGVyCgkJSUNPTkhFQURFUiAqaWNvbl9oZWFkZXIgPSAoSUNPTkhFQURFUiopZGF0YTsKCgkJaWYgKGljb25faGVhZGVyKSB7CgkJCS8vIGxvYWQgdGhlIGljb24gZGVzY3JpcHRpb25zCgkJCUlDT05ESVJFTlRSWSAqaWNvbl9saXN0ID0gKElDT05ESVJFTlRSWSopbWFsbG9jKGljb25faGVhZGVyLT5pZENvdW50ICogc2l6ZW9mKElDT05ESVJFTlRSWSkpOwoJCQlpby0+c2Vla19wcm9jKGhhbmRsZSwgc2l6ZW9mKElDT05IRUFERVIpLCBTRUVLX1NFVCk7CgkJCWlvLT5yZWFkX3Byb2MoaWNvbl9saXN0LCBpY29uX2hlYWRlci0+aWRDb3VudCAqIHNpemVvZihJQ09ORElSRU5UUlkpLCAxLCBoYW5kbGUpOwojaWZkZWYgRlJFRUlNQUdFX0JJR0VORElBTgoJCQlTd2FwSWNvbkRpckVudHJpZXMoaWNvbl9saXN0LCBpY29uX2hlYWRlci0+aWRDb3VudCk7CiNlbmRpZgoKCQkJLy8gbG9hZCB0aGUgcmVxdWVzdGVkIGljb24KCQkJaWYgKHBhZ2UgPCBpY29uX2hlYWRlci0+aWRDb3VudCkgewoJCQkJLy8gc2VlayB0byB0aGUgc3RhcnQgb2YgdGhlIGJpdG1hcCBkYXRhIGZvciB0aGUgaWNvbgoJCQkJaW8tPnNlZWtfcHJvYyhoYW5kbGUsIDAsIFNFRUtfU0VUKTsKCQkJCWlvLT5zZWVrX3Byb2MoaGFuZGxlLCBpY29uX2xpc3RbcGFnZV0uZHdJbWFnZU9mZnNldCwgU0VFS19DVVIpOwoKCQkJCS8vIFZpc3RhIGljb24gc3VwcG9ydAoJCQkJaWYoKGljb25fbGlzdFtwYWdlXS5iV2lkdGggPT0gMCkgJiYgKGljb25fbGlzdFtwYWdlXS5iSGVpZ2h0ID09IDApKSB7CgkJCQkJZGliID0gRnJlZUltYWdlX0xvYWRGcm9tSGFuZGxlKEZJRl9QTkcsIGlvLCBoYW5kbGUsIDApOwoJCQkJCWZyZWUoaWNvbl9saXN0KTsKCQkJCQlyZXR1cm4gZGliOwoJCQkJfQoKCQkJCWZyZWUoaWNvbl9saXN0KTsKCgkJCQkvLyBsb2FkIHRoZSBCSVRNQVBJTkZPSEVBREVSCgkJCQlCSVRNQVBJTkZPSEVBREVSIGJtaWg7CgkJCQlpby0+cmVhZF9wcm9jKCZibWloLCBzaXplb2YoQklUTUFQSU5GT0hFQURFUiksIDEsIGhhbmRsZSk7CiNpZmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCgkJCQlTd2FwSW5mb0hlYWRlcigmYm1paCk7CiNlbmRpZgoKCQkJCS8vIGFsbG9jYXRlIHRoZSBiaXRtYXAKCQkJCWludCB3aWR0aCAgPSBibWloLmJpV2lkdGg7CgkJCQlpbnQgaGVpZ2h0ID0gYm1paC5iaUhlaWdodCAvIDI7IC8vIGhlaWdodCA9PSB4b3IgKyBhbmQgbWFzawoJCQkJaW50IGJpdF9jb3VudCA9IGJtaWguYmlCaXRDb3VudDsKCQkJCWludCBsaW5lICAgPSBDYWxjdWxhdGVMaW5lKHdpZHRoLCBiaXRfY291bnQpOwoJCQkJaW50IHBpdGNoICA9IENhbGN1bGF0ZVBpdGNoKGxpbmUpOwoKCQkJCS8vIGFsbG9jYXRlIG1lbW9yeSBmb3Igb25lIGljb24KCgkJCQlkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGUod2lkdGgsIGhlaWdodCwgYml0X2NvdW50KTsKCgkJCQlpZiAoZGliID09IE5VTEwpIHsKCQkJCQlyZXR1cm4gTlVMTDsKCQkJCX0KCgkJCQlpZiggYm1paC5iaUJpdENvdW50IDw9IDggKSB7CgkJCQkJLy8gcmVhZCB0aGUgcGFsZXR0ZSBkYXRhCgkJCQkJaW8tPnJlYWRfcHJvYyhGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpLCBDYWxjdWxhdGVVc2VkUGFsZXR0ZUVudHJpZXMoYml0X2NvdW50KSAqIHNpemVvZihSR0JRVUFEKSwgMSwgaGFuZGxlKTsKI2lmIEZSRUVJTUFHRV9DT0xPUk9SREVSID09IEZSRUVJTUFHRV9DT0xPUk9SREVSX1JHQgoJCQkJCVJHQlFVQUQgKnBhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGRpYik7CgkJCQkJZm9yKGludCBpID0gMDsgaSA8IENhbGN1bGF0ZVVzZWRQYWxldHRlRW50cmllcyhiaXRfY291bnQpOyBpKyspIHsKCQkJCQkJSU5QTEFDRVNXQVAocGFsW2ldLnJnYlJlZCwgcGFsW2ldLnJnYkJsdWUpOwoJCQkJCX0KI2VuZGlmCgkJCQl9CgoJCQkJLy8gcmVhZCB0aGUgaWNvbgoJCQkJaW8tPnJlYWRfcHJvYyhGcmVlSW1hZ2VfR2V0Qml0cyhkaWIpLCBoZWlnaHQgKiBwaXRjaCwgMSwgaGFuZGxlKTsKCiNpZmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCgkJCQlpZiAoYml0X2NvdW50ID09IDE2KSB7CgkJCQkJZm9yKGludCB5ID0gMDsgeSA8IGhlaWdodDsgeSsrKSB7CgkJCQkJCVdPUkQgKnBpeGVsID0gKFdPUkQgKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCQkJCQkJZm9yKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCVN3YXBTaG9ydChwaXhlbCk7CgkJCQkJCQlwaXhlbCsrOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQojZW5kaWYKI2lmIEZSRUVJTUFHRV9DT0xPUk9SREVSID09IEZSRUVJTUFHRV9DT0xPUk9SREVSX1JHQgoJCQkJaWYgKGJpdF9jb3VudCA9PSAyNCB8fCBiaXRfY291bnQgPT0gMzIpIHsKCQkJCQlmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJQllURSAqcGl4ZWwgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCQkJCQkJZm9yKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCUlOUExBQ0VTV0FQKHBpeGVsWzBdLCBwaXhlbFsyXSk7CgkJCQkJCQlwaXhlbCArPSAoYml0X2NvdW50Pj4zKTsKCQkJCQkJfQoJCQkJCX0KCQkJCX0KI2VuZGlmCgkJCQkvLyBiaXRtYXAgaGFzIGJlZW4gbG9hZGVkIHN1Y2Nlc3NmdWxseSEKCgkJCQkvLyBjb252ZXJ0IHRvIDMyYnBwIGFuZCBnZW5lcmF0ZSBhbiBhbHBoYSBjaGFubmVsCgkJCQlpZigoZmxhZ3MgJiBJQ09fTUFLRUFMUEhBKSA9PSBJQ09fTUFLRUFMUEhBKSB7CgkJCQkJRklCSVRNQVAgKmRpYjMyID0gRnJlZUltYWdlX0NvbnZlcnRUbzMyQml0cyhkaWIpOwoJCQkJCUZyZWVJbWFnZV9VbmxvYWQoZGliKTsKCgkJCQkJaWYgKGRpYjMyID09IE5VTEwpIHsKCQkJCQkJcmV0dXJuIE5VTEw7CgkJCQkJfQoKCQkJCQlpbnQgd2lkdGhfYW5kCT0gV2lkdGhCeXRlcyh3aWR0aCk7CgkJCQkJQllURSAqbGluZV9hbmQJPSAoQllURSAqKW1hbGxvYyh3aWR0aF9hbmQpOwoKCQkJCQlpZiggbGluZV9hbmQgPT0gTlVMTCApIHsKCQkJCQkJRnJlZUltYWdlX1VubG9hZChkaWIzMik7CgkJCQkJCXJldHVybiBOVUxMOwoJCQkJCX0KCgkJCQkJLy9sb29wIHRocm91Z2ggZWFjaCBsaW5lIG9mIHRoZSBBTkQtbWFzayBnZW5lcmF0aW5nIHRoZSBhbHBoYSBjaGFubmVsLCBpbnZlcnQgWE9SLW1hc2sKCQkJCQlmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJUkdCUVVBRCAqcXVhZCA9IChSR0JRVUFEICopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYjMyLCB5KTsKCQkJCQkJaW8tPnJlYWRfcHJvYyhsaW5lX2FuZCwgd2lkdGhfYW5kLCAxLCBoYW5kbGUpOwoJCQkJCQlmb3IoaW50IHggPSAwOyB4IDwgd2lkdGg7IHgrKykgewoJCQkJCQkJcXVhZC0+cmdiUmVzZXJ2ZWQgPSAobGluZV9hbmRbeD4+M10gJiAoMHg4MCA+PiAoeCAmIDB4MDcpKSkgIT0gMCA/IDAgOiAweEZGOwoJCQkJCQkJaWYoIHF1YWQtPnJnYlJlc2VydmVkID09IDAgKSB7CgkJCQkJCQkJcXVhZC0+cmdiQmx1ZSBePSAweEZGOwoJCQkJCQkJCXF1YWQtPnJnYkdyZWVuIF49IDB4RkY7CgkJCQkJCQkJcXVhZC0+cmdiUmVkIF49IDB4RkY7CgkJCQkJCQl9CgkJCQkJCQlxdWFkKys7CgkJCQkJCX0KCQkJCQl9CgkJCQkJZnJlZShsaW5lX2FuZCk7CgoJCQkJCXJldHVybiBkaWIzMjsKCQkJCX0KCgkJCQlyZXR1cm4gKEZJQklUTUFQICopZGliOwoKCQkJfSBlbHNlIHsKCQkJCWZyZWUoaWNvbl9saXN0KTsKCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhzX2Zvcm1hdF9pZCwgIlBhZ2UgZG9lc24ndCBleGlzdCIpOwoJCQl9CgkJfSBlbHNlIHsKCQkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCAiRmlsZSBpcyBub3QgYW4gSUNPIGZpbGUiKTsKCQl9Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBCT09MIERMTF9DQUxMQ09OVgpTYXZlKEZyZWVJbWFnZUlPICppbywgRklCSVRNQVAgKmRpYiwgZmlfaGFuZGxlIGhhbmRsZSwgaW50IHBhZ2UsIGludCBmbGFncywgdm9pZCAqZGF0YSkgewoJaW50IGs7CgoJaWYoZGliKSB7CgkJLy8gY2hlY2sgZm9ybWF0IGxpbWl0cwoJCWludCB3ID0gRnJlZUltYWdlX0dldFdpZHRoKGRpYik7CgkJaW50IGggPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7CgkJaWYoKHcgPCAxNikgfHwgKHcgPiAxMjgpIHx8IChoIDwgMTYpIHx8IChoID4gMTI4KSkgewoJCQlGcmVlSW1hZ2VfT3V0cHV0TWVzc2FnZVByb2Moc19mb3JtYXRfaWQsICJVbnN1cHBvcnRlZCBpY29uIHNpemUiKTsKCQkJcmV0dXJuIEZBTFNFOwoJCX0KCX0gZWxzZSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWlmIChwYWdlID09IC0xKQoJCXBhZ2UgPSAwOwoKCS8vIGdldCB0aGUgaWNvbiBoZWFkZXIKCUlDT05IRUFERVIgKmljb25faGVhZGVyID0gKElDT05IRUFERVIqKWRhdGE7CgoJaWYoaWNvbl9oZWFkZXIpIHsKCgkJc3RkOjp2ZWN0b3I8RklCSVRNQVAqPiB2UGFnZXM7CgkJRklCSVRNQVAgICppY29uX2RpYiA9IE5VTEw7CgoJCS8vIGxvYWQgYWxsIGljb25zCgkJZm9yKGsgPSAwOyBrIDwgaWNvbl9oZWFkZXItPmlkQ291bnQ7IGsrKykgewoJCQlpY29uX2RpYiA9IExvYWQoaW8sIGhhbmRsZSwgaywgZmxhZ3MsIGRhdGEpOwoJCQl2UGFnZXMucHVzaF9iYWNrKGljb25fZGliKTsKCQl9CgoJCS8vIGFkZCB0aGUgcGFnZQoJCWljb25fZGliID0gRnJlZUltYWdlX0Nsb25lKGRpYik7CgkJdlBhZ2VzLnB1c2hfYmFjayhpY29uX2RpYik7CgkJaWNvbl9oZWFkZXItPmlkQ291bnQrKzsKCgkJLy8gd3JpdGUgdGhlIGhlYWRlcgoJCWlvLT5zZWVrX3Byb2MoaGFuZGxlLCAwLCBTRUVLX1NFVCk7CiNpZmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCgkJU3dhcEljb25IZWFkZXIoaWNvbl9oZWFkZXIpOwojZW5kaWYKCQlpby0+d3JpdGVfcHJvYyhpY29uX2hlYWRlciwgc2l6ZW9mKElDT05IRUFERVIpLCAxLCBoYW5kbGUpOwojaWZkZWYgRlJFRUlNQUdFX0JJR0VORElBTgoJCVN3YXBJY29uSGVhZGVyKGljb25faGVhZGVyKTsKI2VuZGlmCgoJCS8vIHdyaXRlIGFsbCBpY29ucwoJCS8vIC4uLgoKCQkvLyBzYXZlIHRoZSBpY29uIGRlc2NyaXB0aW9ucwoJCUlDT05ESVJFTlRSWSAqaWNvbl9saXN0ID0gKElDT05ESVJFTlRSWSAqKW1hbGxvYyhpY29uX2hlYWRlci0+aWRDb3VudCAqIHNpemVvZihJQ09ORElSRU5UUlkpKTsKCQltZW1zZXQoaWNvbl9saXN0LCAwLCBpY29uX2hlYWRlci0+aWRDb3VudCAqIHNpemVvZihJQ09ORElSRU5UUlkpKTsKCQlCSVRNQVBJTkZPSEVBREVSICpibWloOwoJCWZvcihrID0gMDsgayA8IGljb25faGVhZGVyLT5pZENvdW50OyBrKyspIHsKCQkJaWNvbl9kaWIgPSAoRklCSVRNQVAqKXZQYWdlc1trXTsKCgkJCS8vIGNvbnZlcnQgaW50ZXJuYWwgZm9ybWF0IHRvIElDT05ESVJFTlRSWQoJCQlibWloID0gRnJlZUltYWdlX0dldEluZm9IZWFkZXIoaWNvbl9kaWIpOwoJCQlpY29uX2xpc3Rba10uYldpZHRoCQkJPSAoQllURSlibWloLT5iaVdpZHRoOwoJCQlpY29uX2xpc3Rba10uYkhlaWdodAkJPSAoQllURSlibWloLT5iaUhlaWdodDsKCQkJaWNvbl9saXN0W2tdLmJSZXNlcnZlZAkJPSAwOwoJCQlpY29uX2xpc3Rba10ud1BsYW5lcwkJPSBibWloLT5iaVBsYW5lczsKCQkJaWNvbl9saXN0W2tdLndCaXRDb3VudAkJPSBibWloLT5iaUJpdENvdW50OwoJCQlpZiggKGljb25fbGlzdFtrXS53UGxhbmVzICogaWNvbl9saXN0W2tdLndCaXRDb3VudCkgPj0gOCApIHsKCQkJCWljb25fbGlzdFtrXS5iQ29sb3JDb3VudCA9IDA7CgkJCX0gZWxzZSB7CgkJCQlpY29uX2xpc3Rba10uYkNvbG9yQ291bnQgPSAoQllURSkoMSA8PCAoaWNvbl9saXN0W2tdLndQbGFuZXMgKiBpY29uX2xpc3Rba10ud0JpdENvdW50KSk7CgkJCX0KCQkJaWNvbl9saXN0W2tdLmR3Qnl0ZXNJblJlcwk9IENhbGN1bGF0ZUltYWdlU2l6ZShpY29uX2RpYik7CgkJCWljb25fbGlzdFtrXS5kd0ltYWdlT2Zmc2V0ID0gQ2FsY3VsYXRlSW1hZ2VPZmZzZXQodlBhZ2VzLCBrKTsKCQl9CiNpZmRlZiBGUkVFSU1BR0VfQklHRU5ESUFOCgkJU3dhcEljb25EaXJFbnRyaWVzKGljb25fbGlzdCwgaWNvbl9oZWFkZXItPmlkQ291bnQpOwojZW5kaWYKCQlpby0+d3JpdGVfcHJvYyhpY29uX2xpc3QsIHNpemVvZihJQ09ORElSRU5UUlkpICogaWNvbl9oZWFkZXItPmlkQ291bnQsIDEsIGhhbmRsZSk7CgkJZnJlZShpY29uX2xpc3QpOwoKCQkvLyB3cml0ZSB0aGUgaW1hZ2UgYml0cyBmb3IgZWFjaCBpbWFnZQoJCWZvcihrID0gMDsgayA8IGljb25faGVhZGVyLT5pZENvdW50OyBrKyspIHsKCQkJaWNvbl9kaWIgPSAoRklCSVRNQVAqKXZQYWdlc1trXTsKCgkJCS8vIHdyaXRlIHRoZSBCSVRNQVBJTkZPSEVBREVSCgkJCWJtaWggPSBGcmVlSW1hZ2VfR2V0SW5mb0hlYWRlcihpY29uX2RpYik7CgkJCWJtaWgtPmJpSGVpZ2h0ICo9IDI7CS8vIGhlaWdodCA9PSB4b3IgKyBhbmQgbWFzawojaWZkZWYgRlJFRUlNQUdFX0JJR0VORElBTgoJCQlTd2FwSW5mb0hlYWRlcihibWloKTsKI2VuZGlmCgkJCWlvLT53cml0ZV9wcm9jKGJtaWgsIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSwgMSwgaGFuZGxlKTsKI2lmZGVmIEZSRUVJTUFHRV9CSUdFTkRJQU4KCQkJU3dhcEluZm9IZWFkZXIoYm1paCk7CiNlbmRpZgoJCQlibWloLT5iaUhlaWdodCAvPSAyOwoKCQkJLy8gd3JpdGUgdGhlIHBhbGV0dGUgZGF0YQoJCQlpZiAoRnJlZUltYWdlX0dldFBhbGV0dGUoaWNvbl9kaWIpICE9IE5VTEwpIHsKCQkJCVJHQlFVQUQgKnBhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGljb25fZGliKTsKCQkJCUZJTEVfQkdSQSBiZ3JhOwoJCQkJZm9yKHVuc2lnbmVkIGkgPSAwOyBpIDwgRnJlZUltYWdlX0dldENvbG9yc1VzZWQoaWNvbl9kaWIpOyBpKyspIHsKCQkJCQliZ3JhLmIgPSBwYWxbaV0ucmdiQmx1ZTsKCQkJCQliZ3JhLmcgPSBwYWxbaV0ucmdiR3JlZW47CgkJCQkJYmdyYS5yID0gcGFsW2ldLnJnYlJlZDsKCQkJCQliZ3JhLmEgPSBwYWxbaV0ucmdiUmVzZXJ2ZWQ7CgkJCQkJaW8tPndyaXRlX3Byb2MoJmJncmEsIHNpemVvZihGSUxFX0JHUkEpLCAxLCBoYW5kbGUpOwoJCQkJfQoJCQl9CgoJCQkvLyB3cml0ZSB0aGUgYml0cwoJCQlpbnQgd2lkdGgJCT0gYm1paC0+YmlXaWR0aDsKCQkJaW50IGhlaWdodAkJPSBibWloLT5iaUhlaWdodDsKCQkJaW50IGJpdF9jb3VudAk9IGJtaWgtPmJpQml0Q291bnQ7CgkJCWludCBsaW5lCQk9IENhbGN1bGF0ZUxpbmUod2lkdGgsIGJpdF9jb3VudCk7CgkJCWludCBwaXRjaAkJPSBDYWxjdWxhdGVQaXRjaChsaW5lKTsKCQkJaW50IHNpemVfeG9yCT0gaGVpZ2h0ICogcGl0Y2g7CgkJCWludCBzaXplX2FuZAk9IGhlaWdodCAqIFdpZHRoQnl0ZXMod2lkdGgpOwoKCQkJLy8gWE9SIG1hc2sKI2lmZGVmIEZSRUVJTUFHRV9CSUdFTkRJQU4KCQkJaWYgKGJpdF9jb3VudCA9PSAxNikgewoJCQkJV09SRCBwaXhlbDsKCQkJCWZvcihpbnQgeSA9IDA7IHkgPCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGljb25fZGliKTsgeSsrKSB7CgkJCQkJQllURSAqbGluZSA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShpY29uX2RpYiwgeSk7CgkJCQkJZm9yKGludCB4ID0gMDsgeCA8IEZyZWVJbWFnZV9HZXRXaWR0aChpY29uX2RpYik7IHgrKykgewoJCQkJCQlwaXhlbCA9ICgoV09SRCAqKWxpbmUpW3hdOwoJCQkJCQlTd2FwU2hvcnQoJnBpeGVsKTsKCQkJCQkJaWYgKGlvLT53cml0ZV9wcm9jKCZwaXhlbCwgc2l6ZW9mKFdPUkQpLCAxLCBoYW5kbGUpICE9IDEpCgkJCQkJCQlyZXR1cm4gRkFMU0U7CgkJCQkJfQoJCQkJfQoJCQl9IGVsc2UKI2VuZGlmCiNpZiBGUkVFSU1BR0VfQ09MT1JPUkRFUiA9PSBGUkVFSU1BR0VfQ09MT1JPUkRFUl9SR0IKCQkJaWYgKGJpdF9jb3VudCA9PSAyNCkgewoJCQkJRklMRV9CR1IgYmdyOwoJCQkJZm9yKGludCB5ID0gMDsgeSA8IEZyZWVJbWFnZV9HZXRIZWlnaHQoaWNvbl9kaWIpOyB5KyspIHsKCQkJCQlCWVRFICpsaW5lID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGljb25fZGliLCB5KTsKCQkJCQlmb3IoaW50IHggPSAwOyB4IDwgRnJlZUltYWdlX0dldFdpZHRoKGljb25fZGliKTsgeCsrKSB7CgkJCQkJCVJHQlRSSVBMRSAqdHJpcGxlID0gKChSR0JUUklQTEUgKilsaW5lKSt4OwoJCQkJCQliZ3IuYiA9IHRyaXBsZS0+cmdidEJsdWU7CgkJCQkJCWJnci5nID0gdHJpcGxlLT5yZ2J0R3JlZW47CgkJCQkJCWJnci5yID0gdHJpcGxlLT5yZ2J0UmVkOwoJCQkJCQlpZiAoaW8tPndyaXRlX3Byb2MoJmJnciwgc2l6ZW9mKEZJTEVfQkdSKSwgMSwgaGFuZGxlKSAhPSAxKQoJCQkJCQkJcmV0dXJuIEZBTFNFOwoJCQkJCX0KCQkJCX0KCQkJfSBlbHNlIGlmIChiaXRfY291bnQgPT0gMzIpIHsKCQkJCUZJTEVfQkdSQSBiZ3JhOwoJCQkJZm9yKGludCB5ID0gMDsgeSA8IEZyZWVJbWFnZV9HZXRIZWlnaHQoaWNvbl9kaWIpOyB5KyspIHsKCQkJCQlCWVRFICpsaW5lID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGljb25fZGliLCB5KTsKCQkJCQlmb3IoaW50IHggPSAwOyB4IDwgRnJlZUltYWdlX0dldFdpZHRoKGljb25fZGliKTsgeCsrKSB7CgkJCQkJCVJHQlFVQUQgKnF1YWQgPSAoKFJHQlFVQUQgKilsaW5lKSt4OwoJCQkJCQliZ3JhLmIgPSBxdWFkLT5yZ2JCbHVlOwoJCQkJCQliZ3JhLmcgPSBxdWFkLT5yZ2JHcmVlbjsKCQkJCQkJYmdyYS5yID0gcXVhZC0+cmdiUmVkOwoJCQkJCQliZ3JhLmEgPSBxdWFkLT5yZ2JSZXNlcnZlZDsKCQkJCQkJaWYgKGlvLT53cml0ZV9wcm9jKCZiZ3JhLCBzaXplb2YoRklMRV9CR1JBKSwgMSwgaGFuZGxlKSAhPSAxKQoJCQkJCQkJcmV0dXJuIEZBTFNFOwoJCQkJCX0KCQkJCX0KCQkJfSBlbHNlCiNlbmRpZgojaWYgZGVmaW5lZChGUkVFSU1BR0VfQklHRU5ESUFOKSB8fCBGUkVFSU1BR0VfQ09MT1JPUkRFUiA9PSBGUkVFSU1BR0VfQ09MT1JPUkRFUl9SR0IKCQkJewojZW5kaWYKCQkJCUJZVEUgKnhvcl9tYXNrID0gRnJlZUltYWdlX0dldEJpdHMoaWNvbl9kaWIpOwoJCQkJaW8tPndyaXRlX3Byb2MoeG9yX21hc2ssIHNpemVfeG9yLCAxLCBoYW5kbGUpOwojaWYgZGVmaW5lZChGUkVFSU1BR0VfQklHRU5ESUFOKSB8fCBGUkVFSU1BR0VfQ09MT1JPUkRFUiA9PSBGUkVFSU1BR0VfQ09MT1JPUkRFUl9SR0IKCQkJfQojZW5kaWYKCQkJLy8gQU5EIG1hc2sKCQkJQllURSAqYW5kX21hc2sgPSAoQllURSopbWFsbG9jKHNpemVfYW5kKTsKCgkJCWlmKEZyZWVJbWFnZV9Jc1RyYW5zcGFyZW50KGRpYikpIHsKCgkJCQlpZihiaXRfY291bnQgPT0gMzIpIHsKCQkJCQkvLyBjcmVhdGUgdGhlIEFORCBtYXNrIGZyb20gdGhlIGFscGhhIGNoYW5uZWwKCgkJCQkJaW50IHdpZHRoX2FuZCAgPSBXaWR0aEJ5dGVzKHdpZHRoKTsKCQkJCQlCWVRFICphbmRfYml0cyA9IGFuZF9tYXNrOwoKCQkJCQkvLyBjbGVhciB0aGUgbWFzawoJCQkJCW1lbXNldChhbmRfbWFzaywgMCwgc2l6ZV9hbmQpOwoKCQkJCQlmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJUkdCUVVBRCAqYml0cyA9IChSR0JRVUFEKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCB5KTsKCgkJCQkJCWZvcihpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQlpZihiaXRzW3hdLnJnYlJlc2VydmVkICE9IDB4RkYpIHsKCQkJCQkJCQkvLyBzZXQgYW55IHRyYW5zcGFyZW50IGNvbG9yIHRvIGZ1bGwgdHJhbnNwYXJlbmN5CgkJCQkJCQkJYW5kX2JpdHNbeCA+PiAzXSB8PSAoMHg4MCA+PiAoeCAmIDB4NykpOyAKCQkJCQkJCX0KCQkJCQkJfQoKCQkJCQkJYW5kX2JpdHMgKz0gd2lkdGhfYW5kOwoJCQkJCX0KCQkJCX0gCgkJCQllbHNlIGlmKGJpdF9jb3VudCA8PSA4KSB7CgkJCQkJLy8gY3JlYXRlIHRoZSBBTkQgbWFzayBmcm9tIHRoZSB0cmFuc3BhcmVuY3kgdGFibGUKCgkJCQkJQllURSAqdHJucyA9IEZyZWVJbWFnZV9HZXRUcmFuc3BhcmVuY3lUYWJsZShkaWIpOwoKCQkJCQlpbnQgd2lkdGhfYW5kICA9IFdpZHRoQnl0ZXMod2lkdGgpOwoJCQkJCUJZVEUgKmFuZF9iaXRzID0gYW5kX21hc2s7CgoJCQkJCS8vIGNsZWFyIHRoZSBtYXNrCgkJCQkJbWVtc2V0KGFuZF9tYXNrLCAwLCBzaXplX2FuZCk7CgoJCQkJCXN3aXRjaChGcmVlSW1hZ2VfR2V0QlBQKGRpYikpIHsKCQkJCQkJY2FzZSAxOgoJCQkJCQl7CgkJCQkJCQlmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQlCWVRFICpiaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHkpOwoJCQkJCQkJCWZvcihpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJCS8vIGdldCBwaXhlbCBhdCAoeCwgeSkKCQkJCQkJCQkJQllURSBpbmRleCA9IChiaXRzW3ggPj4gM10gJiAoMHg4MCA+PiAoeCAmIDB4MDcpKSkgIT0gMDsKCQkJCQkJCQkJaWYodHJuc1tpbmRleF0gIT0gMHhGRikgewoJCQkJCQkJCQkJLy8gc2V0IGFueSB0cmFuc3BhcmVudCBjb2xvciB0byBmdWxsIHRyYW5zcGFyZW5jeQoJCQkJCQkJCQkJYW5kX2JpdHNbeCA+PiAzXSB8PSAoMHg4MCA+PiAoeCAmIDB4NykpOyAKCQkJCQkJCQkJfQoJCQkJCQkJCX0KCQkJCQkJCQlhbmRfYml0cyArPSB3aWR0aF9hbmQ7CgkJCQkJCQl9CgkJCQkJCX0KCQkJCQkJYnJlYWs7CgoJCQkJCQljYXNlIDQ6CgkJCQkJCXsKCQkJCQkJCWZvcihpbnQgeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCQkJCQkJCUJZVEUgKmJpdHMgPSAoQllURSopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgeSk7CgkJCQkJCQkJZm9yKGludCB4ID0gMDsgeCA8IHdpZHRoOyB4KyspIHsKCQkJCQkJCQkJLy8gZ2V0IHBpeGVsIGF0ICh4LCB5KQoJCQkJCQkJCQlCWVRFIHNoaWZ0ID0gKEJZVEUpKCgxIC0geCAlIDIpIDw8IDIpOwoJCQkJCQkJCQlCWVRFIGluZGV4ID0gKGJpdHNbeCA+PiAxXSAmICgweDBGIDw8IHNoaWZ0KSkgPj4gc2hpZnQ7CgkJCQkJCQkJCWlmKHRybnNbaW5kZXhdICE9IDB4RkYpIHsKCQkJCQkJCQkJCS8vIHNldCBhbnkgdHJhbnNwYXJlbnQgY29sb3IgdG8gZnVsbCB0cmFuc3BhcmVuY3kKCQkJCQkJCQkJCWFuZF9iaXRzW3ggPj4gM10gfD0gKDB4ODAgPj4gKHggJiAweDcpKTsgCgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQkJYW5kX2JpdHMgKz0gd2lkdGhfYW5kOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWJyZWFrOwoKCQkJCQkJY2FzZSA4OgoJCQkJCQl7CgkJCQkJCQlmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQkJCQkJCQlCWVRFICpiaXRzID0gKEJZVEUqKUZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIHkpOwoJCQkJCQkJCWZvcihpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgkJCQkJCQkJCS8vIGdldCBwaXhlbCBhdCAoeCwgeSkKCQkJCQkJCQkJQllURSBpbmRleCA9IGJpdHNbeF07CgkJCQkJCQkJCWlmKHRybnNbaW5kZXhdICE9IDB4RkYpIHsKCQkJCQkJCQkJCS8vIHNldCBhbnkgdHJhbnNwYXJlbnQgY29sb3IgdG8gZnVsbCB0cmFuc3BhcmVuY3kKCQkJCQkJCQkJCWFuZF9iaXRzW3ggPj4gM10gfD0gKDB4ODAgPj4gKHggJiAweDcpKTsgCgkJCQkJCQkJCX0KCQkJCQkJCQl9CgkJCQkJCQkJYW5kX2JpdHMgKz0gd2lkdGhfYW5kOwoJCQkJCQkJfQoJCQkJCQl9CgkJCQkJCWJyZWFrOwoKCQkJCQl9CgkJCQl9CgkJCX0KCQkJZWxzZSB7CgkJCQkvLyBlbXB0eSBBTkQgbWFzawoJCQkJbWVtc2V0KGFuZF9tYXNrLCAwLCBzaXplX2FuZCk7CgkJCX0KCgkJCWlvLT53cml0ZV9wcm9jKGFuZF9tYXNrLCBzaXplX2FuZCwgMSwgaGFuZGxlKTsKCQkJZnJlZShhbmRfbWFzayk7CgoJCX0KCgkJLy8gZnJlZSB0aGUgdmVjdG9yIGNsYXNzCgkJZm9yKGsgPSAwOyBrIDwgaWNvbl9oZWFkZXItPmlkQ291bnQ7IGsrKykgewoJCQlpY29uX2RpYiA9IChGSUJJVE1BUCopdlBhZ2VzW2tdOwoJCQlGcmVlSW1hZ2VfVW5sb2FkKGljb25fZGliKTsKCQl9CgoJCXJldHVybiBUUlVFOwoJfQoKCXJldHVybiBGQUxTRTsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyAgIEluaXQKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKdm9pZCBETExfQ0FMTENPTlYKSW5pdElDTyhQbHVnaW4gKnBsdWdpbiwgaW50IGZvcm1hdF9pZCkgewoJc19mb3JtYXRfaWQgPSBmb3JtYXRfaWQ7CgoJcGx1Z2luLT5mb3JtYXRfcHJvYyA9IEZvcm1hdDsKCXBsdWdpbi0+ZGVzY3JpcHRpb25fcHJvYyA9IERlc2NyaXB0aW9uOwoJcGx1Z2luLT5leHRlbnNpb25fcHJvYyA9IEV4dGVuc2lvbjsKCXBsdWdpbi0+cmVnZXhwcl9wcm9jID0gUmVnRXhwcjsKCXBsdWdpbi0+b3Blbl9wcm9jID0gT3BlbjsKCXBsdWdpbi0+Y2xvc2VfcHJvYyA9IENsb3NlOwoJcGx1Z2luLT5wYWdlY291bnRfcHJvYyA9IFBhZ2VDb3VudDsKCXBsdWdpbi0+cGFnZWNhcGFiaWxpdHlfcHJvYyA9IE5VTEw7CglwbHVnaW4tPmxvYWRfcHJvYyA9IExvYWQ7CglwbHVnaW4tPnNhdmVfcHJvYyA9IFNhdmU7CglwbHVnaW4tPnZhbGlkYXRlX3Byb2MgPSBWYWxpZGF0ZTsKCXBsdWdpbi0+bWltZV9wcm9jID0gTWltZVR5cGU7CglwbHVnaW4tPnN1cHBvcnRzX2V4cG9ydF9icHBfcHJvYyA9IFN1cHBvcnRzRXhwb3J0RGVwdGg7CglwbHVnaW4tPnN1cHBvcnRzX2V4cG9ydF90eXBlX3Byb2MgPSBTdXBwb3J0c0V4cG9ydFR5cGU7CglwbHVnaW4tPnN1cHBvcnRzX2ljY19wcm9maWxlc19wcm9jID0gTlVMTDsKfQo=