Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBIZWxwZXIgY2xhc3MgZm9yIHJhdGlvbmFsIG51bWJlcnMKLy8KLy8gRGVzaWduIGFuZCBpbXBsZW1lbnRhdGlvbiBieQovLyAtIEhlcnbpIERyb2xvbiA8ZHJvbG9uQGluZm9uaWUuZnI+Ci8vCi8vIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZyZWVJbWFnZSAzCi8vCi8vIENPVkVSRUQgQ09ERSBJUyBQUk9WSURFRCBVTkRFUiBUSElTIExJQ0VOU0UgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5UWQovLyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgV0FSUkFOVElFUwovLyBUSEFUIFRIRSBDT1ZFUkVEIENPREUgSVMgRlJFRSBPRiBERUZFQ1RTLCBNRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLy8gT1IgTk9OLUlORlJJTkdJTkcuIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIENPVkVSRUQKLy8gQ09ERSBJUyBXSVRIIFlPVS4gU0hPVUxEIEFOWSBDT1ZFUkVEIENPREUgUFJPVkUgREVGRUNUSVZFIElOIEFOWSBSRVNQRUNULCBZT1UgKE5PVAovLyBUSEUgSU5JVElBTCBERVZFTE9QRVIgT1IgQU5ZIE9USEVSIENPTlRSSUJVVE9SKSBBU1NVTUUgVEhFIENPU1QgT0YgQU5ZIE5FQ0VTU0FSWQovLyBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLiBUSElTIERJU0NMQUlNRVIgT0YgV0FSUkFOVFkgQ09OU1RJVFVURVMgQU4gRVNTRU5USUFMCi8vIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIENPVkVSRUQgQ09ERSBJUyBBVVRIT1JJWkVEIEhFUkVVTkRFUiBFWENFUFQgVU5ERVIKLy8gVEhJUyBESVNDTEFJTUVSLgovLwovLyBVc2UgYXQgeW91ciBvd24gcmlzayEKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2luY2x1ZGUgIkZyZWVJbWFnZS5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCiNpbmNsdWRlICJGSVJhdGlvbmFsLmgiCgojaW5jbHVkZSA8Y21hdGg+CgovLy8gSW5pdGlhbGl6ZSBhbmQgbm9ybWFsaXplIGEgcmF0aW9uYWwgbnVtYmVyCnZvaWQgRklSYXRpb25hbDo6aW5pdGlhbGl6ZShMT05HIG4sIExPTkcgZCkgewoJaWYoZCkgewoJCV9udW1lcmF0b3IgPSBuOwoJCV9kZW5vbWluYXRvciA9IGQ7CgkJLy8gbm9ybWFsaXplIHJhdGlvbmFsCgkJbm9ybWFsaXplKCk7Cgl9IGVsc2UgewoJCV9udW1lcmF0b3IgPSAwOwoJCV9kZW5vbWluYXRvciA9IDA7Cgl9Cn0KCi8vLyBEZWZhdWx0IGNvbnN0cnVjdG9yCkZJUmF0aW9uYWw6OkZJUmF0aW9uYWwoKSB7CglfbnVtZXJhdG9yID0gMDsKCV9kZW5vbWluYXRvciA9IDA7Cn0KCi8vLyBDb25zdHJ1Y3RvciB3aXRoIGxvbmdzCkZJUmF0aW9uYWw6OkZJUmF0aW9uYWwoTE9ORyBuLCBMT05HIGQpIHsKCWluaXRpYWxpemUobiwgZCk7Cn0KCi8vLyBDb25zdHJ1Y3RvciB3aXRoIEZJVEFHCkZJUmF0aW9uYWw6OkZJUmF0aW9uYWwoY29uc3QgRklUQUcgKnRhZykgewoJc3dpdGNoKEZyZWVJbWFnZV9HZXRUYWdUeXBlKChGSVRBRyopdGFnKSkgewoJCWNhc2UgRklEVF9SQVRJT05BTDoJCS8vIDY0LWJpdCB1bnNpZ25lZCBmcmFjdGlvbiAKCQl7CgkJCURXT1JEICpwdmFsdWUgPSAoRFdPUkQqKUZyZWVJbWFnZV9HZXRUYWdWYWx1ZSgoRklUQUcqKXRhZyk7CgkJCWluaXRpYWxpemUoKExPTkcpcHZhbHVlWzBdLCAoTE9ORylwdmFsdWVbMV0pOwoJCQlicmVhazsKCQl9CgoJCWNhc2UgRklEVF9TUkFUSU9OQUw6CS8vIDY0LWJpdCBzaWduZWQgZnJhY3Rpb24gCgkJewoJCQlMT05HICpwdmFsdWUgPSAoTE9ORyopRnJlZUltYWdlX0dldFRhZ1ZhbHVlKChGSVRBRyopdGFnKTsKCQkJaW5pdGlhbGl6ZSgoTE9ORylwdmFsdWVbMF0sIChMT05HKXB2YWx1ZVsxXSk7CgkJCWJyZWFrOwoJCX0KCX0KfQoKRklSYXRpb25hbDo6RklSYXRpb25hbChmbG9hdCB2YWx1ZSkgewoJaWYgKHZhbHVlID09IChmbG9hdCkoKExPTkcpdmFsdWUpKSB7CgkgICBfbnVtZXJhdG9yID0gKExPTkcpdmFsdWU7CgkgICBfZGVub21pbmF0b3IgPSAxTDsKCX0gZWxzZSB7CgkJaW50IGssIGNvdW50OwoJCUxPTkcgbls0XTsKCgkJZmxvYXQgeCA9IGZhYnModmFsdWUpOwoJCWludCBzaWduID0gKHZhbHVlID4gMCkgPyAxIDogLTE7CgoJCS8vIG1ha2UgYSBjb250aW51ZWQtZnJhY3Rpb24gZXhwYW5zaW9uIG9mIHgKCQljb3VudCA9IC0xOwoJCWZvcihrID0gMDsgayA8IDQ7IGsrKykgewogICAgICAgICAgICAgICAgICBuW2tdID0gKExPTkcpc3RkOjpmbG9vcih4KTsKICAgICAgICAgICAgICAgICAgY291bnQrKzsKICAgICAgICAgICAgICAgICAgeCAtPSAoZmxvYXQpbltrXTsKICAgICAgICAgICAgICAgICAgaWYgKHggPT0gMCkgYnJlYWs7CiAgICAgICAgICAgICAgICAgIHggPSAxIC8geDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIGNvbXB1dGUgdGhlIHJhdGlvbmFsCgkJX251bWVyYXRvciA9IDE7CgkJX2Rlbm9taW5hdG9yID0gbltjb3VudF07CgoJCWZvcihpbnQgaSA9IGNvdW50IC0gMTsgaSA+PSAwOyBpLS0pIHsKCQkJaWYobltpXSA9PSAwKSBicmVhazsKCQkJTE9ORyBfbnVtID0gKG5baV0gKiBfbnVtZXJhdG9yICsgX2Rlbm9taW5hdG9yKTsKCQkJTE9ORyBfZGVuID0gX251bWVyYXRvcjsKCQkJX251bWVyYXRvciA9IF9udW07CgkJCV9kZW5vbWluYXRvciA9IF9kZW47CgkJfQoJCV9udW1lcmF0b3IgKj0gc2lnbjsKCX0KfQoKLy8vIENvcHkgY29uc3RydWN0b3IKRklSYXRpb25hbDo6RklSYXRpb25hbCAoY29uc3QgRklSYXRpb25hbCYgcikgewoJaW5pdGlhbGl6ZShyLl9udW1lcmF0b3IsIHIuX2Rlbm9taW5hdG9yKTsKfQoKLy8vIERlc3RydWN0b3IKRklSYXRpb25hbDo6fkZJUmF0aW9uYWwoKSB7Cn0KCi8vLyBBc3NpZ25lbWVudCBvcGVyYXRvcgpGSVJhdGlvbmFsJiBGSVJhdGlvbmFsOjpvcGVyYXRvcj0oRklSYXRpb25hbCYgcikgewoJaWYodGhpcyAhPSAmcikgewoJCWluaXRpYWxpemUoci5fbnVtZXJhdG9yLCByLl9kZW5vbWluYXRvcik7Cgl9CglyZXR1cm4gKnRoaXM7Cn0KCi8vLyBHZXQgdGhlIG51bWVyYXRvcgpMT05HIEZJUmF0aW9uYWw6OmdldE51bWVyYXRvcigpIHsKCXJldHVybiBfbnVtZXJhdG9yOwp9CgovLy8gR2V0IHRoZSBkZW5vbWluYXRvcgpMT05HIEZJUmF0aW9uYWw6OmdldERlbm9taW5hdG9yKCkgewoJcmV0dXJuIF9kZW5vbWluYXRvcjsKfQoKLy8vIENhbGN1bGF0ZSBHQ0QKTE9ORyBGSVJhdGlvbmFsOjpnY2QoTE9ORyBhLCBMT05HIGIpIHsKCUxPTkcgdGVtcDsKCXdoaWxlIChiKSB7CQkvLyBXaGlsZSBub24temVybyB2YWx1ZQoJCXRlbXAgPSBiOwkvLyBTYXZlIGN1cnJlbnQgdmFsdWUKCQliID0gYSAlIGI7CS8vIEFzc2lnbiByZW1haW5kZXIgb2YgZGl2aXNpb24KCQlhID0gdGVtcDsJLy8gQ29weSBvbGQgdmFsdWUKCX0KCXJldHVybiBhOwkJLy8gUmV0dXJuIEdDRCBvZiBudW1iZXJzCn0KCi8vLyBOb3JtYWxpemUgbnVtZXJhdG9yIC8gZGVub21pbmF0b3IgCnZvaWQgRklSYXRpb25hbDo6bm9ybWFsaXplKCkgewoJaWYgKF9udW1lcmF0b3IgIT0gMSAmJiBfZGVub21pbmF0b3IgIT0gMSkgewkvLyBJcyB0aGVyZSBzb21ldGhpbmcgdG8gZG8/CgkJIC8vIENhbGN1bGF0ZSBHQ0QKCQlMT05HIGNvbW1vbiA9IGdjZChfbnVtZXJhdG9yLCBfZGVub21pbmF0b3IpOwoJCWlmIChjb21tb24gIT0gMSkgeyAvLyBJZiBHQ0QgaXMgbm90IG9uZQkJCQoJCQlfbnVtZXJhdG9yIC89IGNvbW1vbjsJLy8gQ2FsY3VsYXRlIG5ldyBudW1lcmF0b3IKCQkJX2Rlbm9taW5hdG9yIC89IGNvbW1vbjsJLy8gQ2FsY3VsYXRlIG5ldyBkZW5vbWluYXRvcgoJCX0KCX0KCWlmKF9kZW5vbWluYXRvciA8IDApIHsJLy8gSWYgc2lnbiBpcyBpbiBkZW5vbWluYXRvcgoJCV9udW1lcmF0b3IgKj0gLTE7CS8vIE11bHRpcGx5IG51bSBhbmQgZGVuIGJ5IC0xCgkJX2Rlbm9taW5hdG9yICo9IC0xOwkvLyBUbyBrZWVwIHNpZ24gaW4gbnVtZXJhdG9yCgl9Cn0KCi8vLyBDaGVja3MgaWYgdGhpcyByYXRpb25hbCBudW1iZXIgaXMgYW4gSW50ZWdlciwgZWl0aGVyIHBvc2l0aXZlIG9yIG5lZ2F0aXZlCkJPT0wgRklSYXRpb25hbDo6aXNJbnRlZ2VyKCkgewoJaWYoX2Rlbm9taW5hdG9yID09IDEgfHwgKF9kZW5vbWluYXRvciAhPSAwICYmIChfbnVtZXJhdG9yICUgX2Rlbm9taW5hdG9yID09IDApKSB8fCAoX2Rlbm9taW5hdG9yID09IDAgJiYgX251bWVyYXRvciA9PSAwKSkKCQlyZXR1cm4gVFJVRTsKCXJldHVybiBGQUxTRTsKfQoKLy8vIENvbnZlcnQgYXMgIm51bWVyYXRvci9kZW5vbWluYXRvciIKc3RkOjpzdHJpbmcgRklSYXRpb25hbDo6dG9TdHJpbmcoKSB7CglzdGQ6Om9zdHJpbmdzdHJlYW0gczsKCWlmKGlzSW50ZWdlcigpKSB7CgkJcyA8PCBpbnRWYWx1ZSgpOwoJfSBlbHNlIHsKCQlzIDw8IF9udW1lcmF0b3IgPDwgIi8iIDw8IF9kZW5vbWluYXRvcjsKCX0KCXJldHVybiBzLnN0cigpOwp9CgoK