Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBEaXNwbGF5IHJvdXRpbmVzCi8vCi8vIERlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gYnkKLy8gLSBIZXJ26SBEcm9sb24gKGRyb2xvbkBpbmZvbmllLmZyKQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgoKCi8qKgpAYnJpZWYgQ29tcG9zaXRlIGEgZm9yZWdyb3VuZCBpbWFnZSBhZ2FpbnN0IGEgYmFja2dyb3VuZCBjb2xvciBvciBhIGJhY2tncm91bmQgaW1hZ2UuCgpUaGUgZXF1YXRpb24gZm9yIGNvbXB1dGluZyBhIGNvbXBvc2l0ZWQgc2FtcGxlIHZhbHVlIGlzOjxicj4Kb3V0cHV0ID0gYWxwaGEgKiBmb3JlZ3JvdW5kICsgKDEtYWxwaGEpICogYmFja2dyb3VuZDxicj4Kd2hlcmUgYWxwaGEgYW5kIHRoZSBpbnB1dCBhbmQgb3V0cHV0IHNhbXBsZSB2YWx1ZXMgYXJlIGV4cHJlc3NlZCBhcyBmcmFjdGlvbnMgaW4gdGhlIHJhbmdlIDAgdG8gMS4gCkZvciBjb2xvdXIgaW1hZ2VzLCB0aGUgY29tcHV0YXRpb24gaXMgZG9uZSBzZXBhcmF0ZWx5IGZvciBSLCBHLCBhbmQgQiBzYW1wbGVzLgoKQHBhcmFtIGZnIEZvcmVncm91bmQgaW1hZ2UKQHBhcmFtIHVzZUZpbGVCa2cgSWYgVFJVRSBhbmQgYSBmaWxlIGJhY2tncm91bmQgaXMgcHJlc2VudCwgdXNlIGl0IGFzIHRoZSBiYWNrZ3JvdW5kIGNvbG9yCkBwYXJhbSBhcHBCa0NvbG9yIElmIG5vdCBlcXVhbCB0byBOVUxMLCBhbmQgdXNlRmlsZUJrZyBpcyBGQUxTRSwgdXNlIHRoaXMgY29sb3IgYXMgdGhlIGJhY2tncm91bmQgY29sb3IKQHBhcmFtIGJnIElmIG5vdCBlcXVhbCB0byBOVUxMIGFuZCB1c2VGaWxlQmtnIGlzIEZBTFNFIGFuZCBhcHBCa0NvbG9yIGlzIE5VTEwsIHVzZSB0aGlzIGFzIHRoZSBiYWNrZ3JvdW5kIGltYWdlCkByZXR1cm4gUmV0dXJucyB0aGUgY29tcG9zaXRlIGltYWdlIGlmIHN1Y2Nlc3NmdWwsIHJldHVybnMgTlVMTCBvdGhlcndpc2UKQHNlZSBGcmVlSW1hZ2VfSXNUcmFuc3BhcmVudCwgRnJlZUltYWdlX0hhc0JhY2tncm91bmRDb2xvcgoqLwpGSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpGcmVlSW1hZ2VfQ29tcG9zaXRlKEZJQklUTUFQICpmZywgQk9PTCB1c2VGaWxlQmtnLCBSR0JRVUFEICphcHBCa0NvbG9yLCBGSUJJVE1BUCAqYmcpIHsKCWlmKCFGcmVlSW1hZ2VfSGFzUGl4ZWxzKGZnKSkgcmV0dXJuIE5VTEw7CgoJaW50IHdpZHRoICA9IEZyZWVJbWFnZV9HZXRXaWR0aChmZyk7CglpbnQgaGVpZ2h0ID0gRnJlZUltYWdlX0dldEhlaWdodChmZyk7CglpbnQgYnBwICAgID0gRnJlZUltYWdlX0dldEJQUChmZyk7CgoJaWYoKGJwcCAhPSA4KSAmJiAoYnBwICE9IDMyKSkKCQlyZXR1cm4gTlVMTDsKCglpZihiZykgewoJCWludCBiZ193aWR0aCAgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoYmcpOwoJCWludCBiZ19oZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGJnKTsKCQlpbnQgYmdfYnBwICAgID0gRnJlZUltYWdlX0dldEJQUChiZyk7CgkJaWYoKGJnX3dpZHRoICE9IHdpZHRoKSB8fCAoYmdfaGVpZ2h0ICE9IGhlaWdodCkgfHwgKGJnX2JwcCAhPSAyNCkpCgkJCXJldHVybiBOVUxMOwoJfQoKCWludCBieXRlc3BwID0gKGJwcCA9PSA4KSA/IDEgOiA0OwoKCQoJaW50IHgsIHksIGM7CglCWVRFIGFscGhhID0gMCwgbm90X2FscGhhOwoJQllURSBpbmRleDsKCVJHQlFVQUQgZmdjOwkvLyBmb3JlZ3JvdW5kIGNvbG9yCglSR0JRVUFEIGJrYzsJLy8gYmFja2dyb3VuZCBjb2xvcgoKCW1lbXNldCgmZmdjLCAwLCBzaXplb2YoUkdCUVVBRCkpOwoJbWVtc2V0KCZia2MsIDAsIHNpemVvZihSR0JRVUFEKSk7CgoJLy8gYWxsb2NhdGUgdGhlIGNvbXBvc2l0ZSBpbWFnZQoJRklCSVRNQVAgKmNvbXBvc2l0ZSA9IEZyZWVJbWFnZV9BbGxvY2F0ZSh3aWR0aCwgaGVpZ2h0LCAyNCwgRklfUkdCQV9SRURfTUFTSywgRklfUkdCQV9HUkVFTl9NQVNLLCBGSV9SR0JBX0JMVUVfTUFTSyk7CglpZighY29tcG9zaXRlKSByZXR1cm4gTlVMTDsKCgkvLyBnZXQgdGhlIHBhbGV0dGUKCVJHQlFVQUQgKnBhbCA9IEZyZWVJbWFnZV9HZXRQYWxldHRlKGZnKTsKCgkvLyByZXRyaWV2ZSB0aGUgYWxwaGEgdGFibGUgZnJvbSB0aGUgZm9yZWdyb3VuZCBpbWFnZQoJQk9PTCBiSXNUcmFuc3BhcmVudCA9IEZyZWVJbWFnZV9Jc1RyYW5zcGFyZW50KGZnKTsKCUJZVEUgKnRybnMgPSBGcmVlSW1hZ2VfR2V0VHJhbnNwYXJlbmN5VGFibGUoZmcpOwoKCS8vIHJldHJpZXZlIHRoZSBiYWNrZ3JvdW5kIGNvbG9yIGZyb20gdGhlIGZvcmVncm91bmQgaW1hZ2UKCUJPT0wgYkhhc0JrQ29sb3IgPSBGQUxTRTsKCglpZih1c2VGaWxlQmtnICYmIEZyZWVJbWFnZV9IYXNCYWNrZ3JvdW5kQ29sb3IoZmcpKSB7CgkJRnJlZUltYWdlX0dldEJhY2tncm91bmRDb2xvcihmZywgJmJrYyk7CgkJYkhhc0JrQ29sb3IgPSBUUlVFOwoJfSBlbHNlIHsKCQkvLyBubyBmaWxlIGJhY2tncm91bmQgY29sb3IKCQkvLyB1c2UgYXBwbGljYXRpb24gYmFja2dyb3VuZCBjb2xvciA/CgkJaWYoYXBwQmtDb2xvcikgewoJCQltZW1jcHkoJmJrYywgYXBwQmtDb2xvciwgc2l6ZW9mKFJHQlFVQUQpKTsKCQkJYkhhc0JrQ29sb3IgPSBUUlVFOwoJCX0KCQkvLyB1c2UgYmFja2dyb3VuZCBpbWFnZSA/CgkJZWxzZSBpZihiZykgewoJCQliSGFzQmtDb2xvciA9IEZBTFNFOwoJCX0KCX0KCglmb3IoeSA9IDA7IHkgPCBoZWlnaHQ7IHkrKykgewoJCS8vIGZvcmVncm91bmQKCQlCWVRFICpmZ19iaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGZnLCB5KTsKCQkvLyBiYWNrZ3JvdW5kCgkJQllURSAqYmdfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShiZywgeSk7CgkJLy8gY29tcG9zaXRlIGltYWdlCgkJQllURSAqY3BfYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShjb21wb3NpdGUsIHkpOwoKCQlmb3IoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSB7CgoJCQkvLyBmb3JlZ3JvdW5kIGNvbG9yICsgYWxwaGEKCgkJCWlmKGJwcCA9PSA4KSB7CgkJCQkvLyBnZXQgdGhlIGZvcmVncm91bmQgY29sb3IKCQkJCWluZGV4ID0gZmdfYml0c1swXTsKCQkJCW1lbWNweSgmZmdjLCAmcGFsW2luZGV4XSwgc2l6ZW9mKFJHQlFVQUQpKTsKCQkJCS8vIGdldCB0aGUgYWxwaGEKCQkJCWlmKGJJc1RyYW5zcGFyZW50KSB7CgkJCQkJYWxwaGEgPSB0cm5zW2luZGV4XTsKCQkJCX0gZWxzZSB7CgkJCQkJYWxwaGEgPSAyNTU7CgkJCQl9CgkJCX0KCQkJZWxzZSBpZihicHAgPT0gMzIpIHsKCQkJCS8vIGdldCB0aGUgZm9yZWdyb3VuZCBjb2xvcgoJCQkJZmdjLnJnYkJsdWUgID0gZmdfYml0c1tGSV9SR0JBX0JMVUVdOwoJCQkJZmdjLnJnYkdyZWVuID0gZmdfYml0c1tGSV9SR0JBX0dSRUVOXTsKCQkJCWZnYy5yZ2JSZWQgICA9IGZnX2JpdHNbRklfUkdCQV9SRURdOwoJCQkJLy8gZ2V0IHRoZSBhbHBoYQoJCQkJYWxwaGEgPSBmZ19iaXRzW0ZJX1JHQkFfQUxQSEFdOwoJCQl9CgoJCQkvLyBiYWNrZ3JvdW5kIGNvbG9yCgoJCQlpZighYkhhc0JrQ29sb3IpIHsKCQkJCWlmKGJnKSB7CgkJCQkJLy8gZ2V0IHRoZSBiYWNrZ3JvdW5kIGNvbG9yIGZyb20gdGhlIGJhY2tncm91bmQgaW1hZ2UKCQkJCQlia2MucmdiQmx1ZSAgPSBiZ19iaXRzW0ZJX1JHQkFfQkxVRV07CgkJCQkJYmtjLnJnYkdyZWVuID0gYmdfYml0c1tGSV9SR0JBX0dSRUVOXTsKCQkJCQlia2MucmdiUmVkICAgPSBiZ19iaXRzW0ZJX1JHQkFfUkVEXTsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCS8vIHVzZSBhIGNoZWNrZXJib2FyZCBwYXR0ZXJuCgkJCQkJYyA9ICgoKHkgJiAweDgpID09IDApIF4gKCh4ICYgMHg4KSA9PSAwKSkgKiAxOTI7CgkJCQkJYyA9IGMgPyBjIDogMjU1OwoJCQkJCWJrYy5yZ2JCbHVlICA9IChCWVRFKWM7CgkJCQkJYmtjLnJnYkdyZWVuID0gKEJZVEUpYzsKCQkJCQlia2MucmdiUmVkICAgPSAoQllURSljOwoJCQkJfQoJCQl9CgoJCQkvLyBjb21wb3NpdGlvbgoKCQkJaWYoYWxwaGEgPT0gMCkgewoJCQkJLy8gb3V0cHV0ID0gYmFja2dyb3VuZAoJCQkJY3BfYml0c1tGSV9SR0JBX0JMVUVdID0gYmtjLnJnYkJsdWU7CgkJCQljcF9iaXRzW0ZJX1JHQkFfR1JFRU5dID0gYmtjLnJnYkdyZWVuOwoJCQkJY3BfYml0c1tGSV9SR0JBX1JFRF0gPSBia2MucmdiUmVkOwoJCQl9CgkJCWVsc2UgaWYoYWxwaGEgPT0gMjU1KSB7CgkJCQkvLyBvdXRwdXQgPSBmb3JlZ3JvdW5kCgkJCQljcF9iaXRzW0ZJX1JHQkFfQkxVRV0gPSBmZ2MucmdiQmx1ZTsKCQkJCWNwX2JpdHNbRklfUkdCQV9HUkVFTl0gPSBmZ2MucmdiR3JlZW47CgkJCQljcF9iaXRzW0ZJX1JHQkFfUkVEXSA9IGZnYy5yZ2JSZWQ7CgkJCX0KCQkJZWxzZSB7CgkJCQkvLyBvdXRwdXQgPSBhbHBoYSAqIGZvcmVncm91bmQgKyAoMS1hbHBoYSkgKiBiYWNrZ3JvdW5kCgkJCQlub3RfYWxwaGEgPSAoQllURSl+YWxwaGE7CgkJCQljcF9iaXRzW0ZJX1JHQkFfQkxVRV0gPSAoQllURSkoKGFscGhhICogKFdPUkQpZmdjLnJnYkJsdWUgICsgbm90X2FscGhhICogKFdPUkQpYmtjLnJnYkJsdWUpID4+IDgpOwoJCQkJY3BfYml0c1tGSV9SR0JBX0dSRUVOXSA9IChCWVRFKSgoYWxwaGEgKiAoV09SRClmZ2MucmdiR3JlZW4gKyBub3RfYWxwaGEgKiAoV09SRClia2MucmdiR3JlZW4pID4+IDgpOwoJCQkJY3BfYml0c1tGSV9SR0JBX1JFRF0gPSAoQllURSkoKGFscGhhICogKFdPUkQpZmdjLnJnYlJlZCAgICsgbm90X2FscGhhICogKFdPUkQpYmtjLnJnYlJlZCkgPj4gOCk7CgkJCX0KCgkJCWZnX2JpdHMgKz0gYnl0ZXNwcDsKCQkJYmdfYml0cyArPSAzOwoJCQljcF9iaXRzICs9IDM7CgkJfQoJfQoKCS8vIGNvcHkgbWV0YWRhdGEgZnJvbSBzcmMgdG8gZHN0CglGcmVlSW1hZ2VfQ2xvbmVNZXRhZGF0YShjb21wb3NpdGUsIGZnKTsKCQoJcmV0dXJuIGNvbXBvc2l0ZTsJCn0KCi8qKgpQcmUtbXVsdGlwbGllcyBhIDMyLWJpdCBpbWFnZSdzIHJlZC0sIGdyZWVuLSBhbmQgYmx1ZSBjaGFubmVscyB3aXRoIGl0J3MgYWxwaGEgY2hhbm5lbCAKZm9yIHRvIGJlIHVzZWQgd2l0aCBlLmcuIHRoZSBXaW5kb3dzIEdESSBmdW5jdGlvbiBBbHBoYUJsZW5kKCkuIApUaGUgdHJhbnNmb3JtYXRpb24gY2hhbmdlcyB0aGUgcmVkLSwgZ3JlZW4tIGFuZCBibHVlIGNoYW5uZWxzIGFjY29yZGluZyB0byB0aGUgZm9sbG93aW5nIGVxdWF0aW9uOiAgCmNoYW5uZWwoeCwgeSkgPSBjaGFubmVsKHgsIHkpICogYWxwaGFfY2hhbm5lbCh4LCB5KSAvIDI1NSAgCkBwYXJhbSBkaWIgSW5wdXQvT3V0cHV0IGRpYiB0byBiZSBwcmVtdWx0aXBsaWVkCkByZXR1cm4gUmV0dXJucyBUUlVFIG9uIHN1Y2Nlc3MsIEZBTFNFIG90aGVyd2lzZSAoZS5nLiB3aGVuIHRoZSBiaXRkZXB0aCBvZiB0aGUgc291cmNlIGRpYiBjYW5ub3QgYmUgaGFuZGxlZCkuIAoqLwpCT09MIERMTF9DQUxMQ09OViAKRnJlZUltYWdlX1ByZU11bHRpcGx5V2l0aEFscGhhKEZJQklUTUFQICpkaWIpIHsKCWlmICghRnJlZUltYWdlX0hhc1BpeGVscyhkaWIpKSByZXR1cm4gRkFMU0U7CgkKCWlmICgoRnJlZUltYWdlX0dldEJQUChkaWIpICE9IDMyKSB8fCAoRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpICE9IEZJVF9CSVRNQVApKSB7CgkJcmV0dXJuIEZBTFNFOwoJfQoKCWludCB3aWR0aCA9IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpOwoJaW50IGhlaWdodCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKTsKCglmb3IoaW50IHkgPSAwOyB5IDwgaGVpZ2h0OyB5KyspIHsKCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgeSk7CgkJZm9yIChpbnQgeCA9IDA7IHggPCB3aWR0aDsgeCsrLCBiaXRzICs9IDQpIHsKCQkJY29uc3QgQllURSBhbHBoYSA9IGJpdHNbRklfUkdCQV9BTFBIQV07CgkJCS8vIHNsaWdodGx5IGZhc3RlcjogY2FyZSBmb3IgdHdvIHNwZWNpYWwgY2FzZXMKCQkJaWYoYWxwaGEgPT0gMHgwMCkgewoJCQkJLy8gc3BlY2lhbCBjYXNlIGZvciBhbHBoYSA9PSAweDAwCgkJCQkvLyBjb2xvciAqIDB4MDAgLyAweEZGID0gMHgwMAoJCQkJYml0c1tGSV9SR0JBX0JMVUVdID0gMHgwMDsKCQkJCWJpdHNbRklfUkdCQV9HUkVFTl0gPSAweDAwOwoJCQkJYml0c1tGSV9SR0JBX1JFRF0gPSAweDAwOwoJCQl9IGVsc2UgaWYoYWxwaGEgPT0gMHhGRikgewoJCQkJLy8gbm90aGluZyB0byBkbyBmb3IgYWxwaGEgPT0gMHhGRgoJCQkJLy8gY29sb3IgKiAweEZGIC8gMHhGRiA9IGNvbG9yCgkJCQljb250aW51ZTsKCQkJfSBlbHNlIHsKCQkJCWJpdHNbRklfUkdCQV9CTFVFXSA9IChCWVRFKSggKGFscGhhICogKFdPUkQpYml0c1tGSV9SR0JBX0JMVUVdICsgMTI3KSAvIDI1NSApOwoJCQkJYml0c1tGSV9SR0JBX0dSRUVOXSA9IChCWVRFKSggKGFscGhhICogKFdPUkQpYml0c1tGSV9SR0JBX0dSRUVOXSArIDEyNykgLyAyNTUgKTsKCQkJCWJpdHNbRklfUkdCQV9SRURdID0gKEJZVEUpKCAoYWxwaGEgKiAoV09SRCliaXRzW0ZJX1JHQkFfUkVEXSArIDEyNykgLyAyNTUgKTsKCQkJfQoJCX0KCX0KCXJldHVybiBUUlVFOwp9Cgo=