LyogQm9vc3QgaW50ZXJ2YWwvYXJpdGguaHBwIHRlbXBsYXRlIGltcGxlbWVudGF0aW9uIGZpbGUKICoKICogQ29weXJpZ2h0IDIwMDAgSmVucyBNYXVyZXIKICogQ29weXJpZ2h0IDIwMDItMjAwMyBIZXJ26SBCcvZubmltYW5uLCBHdWlsbGF1bWUgTWVscXVpb25kLCBTeWx2YWluIFBpb24KICoKICogRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJvb3N0IFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4wLgogKiAoU2VlIGFjY29tcGFueWluZyBmaWxlIExJQ0VOU0VfMV8wLnR4dCBvcgogKiBjb3B5IGF0IGh0dHA6Ly93d3cuYm9vc3Qub3JnL0xJQ0VOU0VfMV8wLnR4dCkKICovCgojaWZuZGVmIEJPT1NUX05VTUVSSUNfSU5URVJWQUxfQVJJVEhfSFBQCiNkZWZpbmUgQk9PU1RfTlVNRVJJQ19JTlRFUlZBTF9BUklUSF9IUFAKCiNpbmNsdWRlIDxib29zdC9jb25maWcuaHBwPgojaW5jbHVkZSA8Ym9vc3QvbnVtZXJpYy9pbnRlcnZhbC9pbnRlcnZhbC5ocHA+CiNpbmNsdWRlIDxib29zdC9udW1lcmljL2ludGVydmFsL2RldGFpbC9idWdzLmhwcD4KI2luY2x1ZGUgPGJvb3N0L251bWVyaWMvaW50ZXJ2YWwvZGV0YWlsL3Rlc3RfaW5wdXQuaHBwPgojaW5jbHVkZSA8Ym9vc3QvbnVtZXJpYy9pbnRlcnZhbC9kZXRhaWwvZGl2aXNpb24uaHBwPgojaW5jbHVkZSA8YWxnb3JpdGhtPgoKbmFtZXNwYWNlIGJvb3N0IHsKbmFtZXNwYWNlIG51bWVyaWMgewoKLyoKICogQmFzaWMgYXJpdGhtZXRpYyBvcGVyYXRvcnMKICovCgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgb3BlcmF0b3IrKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCkKewogIHJldHVybiB4Owp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBvcGVyYXRvci0oY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4KQp7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgpKQogICAgcmV0dXJuIGludGVydmFsPFQsIFBvbGljaWVzPjo6ZW1wdHkoKTsKICByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+KC14LnVwcGVyKCksIC14Lmxvd2VyKCksIHRydWUpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+OjpvcGVyYXRvcis9KGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgcikKewogIGlmIChpbnRlcnZhbF9saWI6OmRldGFpbDo6dGVzdF9pbnB1dCgqdGhpcywgcikpCiAgICBzZXRfZW1wdHkoKTsKICBlbHNlIHsKICAgIHR5cGVuYW1lIFBvbGljaWVzOjpyb3VuZGluZyBybmQ7CiAgICBzZXQocm5kLmFkZF9kb3duKGxvdywgci5sb3cpLCBybmQuYWRkX3VwKHVwLCByLnVwKSk7CiAgfQogIHJldHVybiAqdGhpczsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4mIGludGVydmFsPFQsIFBvbGljaWVzPjo6b3BlcmF0b3IrPShjb25zdCBUJiByKQp7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KCp0aGlzLCByKSkKICAgIHNldF9lbXB0eSgpOwogIGVsc2UgewogICAgdHlwZW5hbWUgUG9saWNpZXM6OnJvdW5kaW5nIHJuZDsKICAgIHNldChybmQuYWRkX2Rvd24obG93LCByKSwgcm5kLmFkZF91cCh1cCwgcikpOwogIH0KICByZXR1cm4gKnRoaXM7Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiBpbnRlcnZhbDxULCBQb2xpY2llcz46Om9wZXJhdG9yLT0oY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiByKQp7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KCp0aGlzLCByKSkKICAgIHNldF9lbXB0eSgpOwogIGVsc2UgewogICAgdHlwZW5hbWUgUG9saWNpZXM6OnJvdW5kaW5nIHJuZDsKICAgIHNldChybmQuc3ViX2Rvd24obG93LCByLnVwKSwgcm5kLnN1Yl91cCh1cCwgci5sb3cpKTsKICB9CiAgcmV0dXJuICp0aGlzOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiYgaW50ZXJ2YWw8VCwgUG9saWNpZXM+OjpvcGVyYXRvci09KGNvbnN0IFQmIHIpCnsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoKnRoaXMsIHIpKQogICAgc2V0X2VtcHR5KCk7CiAgZWxzZSB7CiAgICB0eXBlbmFtZSBQb2xpY2llczo6cm91bmRpbmcgcm5kOwogICAgc2V0KHJuZC5zdWJfZG93bihsb3csIHIpLCBybmQuc3ViX3VwKHVwLCByKSk7CiAgfQogIHJldHVybiAqdGhpczsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4mIGludGVydmFsPFQsIFBvbGljaWVzPjo6b3BlcmF0b3IqPShjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHIpCnsKICByZXR1cm4gKnRoaXMgPSAqdGhpcyAqIHI7Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiBpbnRlcnZhbDxULCBQb2xpY2llcz46Om9wZXJhdG9yKj0oY29uc3QgVCYgcikKewogIHJldHVybiAqdGhpcyA9IHIgKiAqdGhpczsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4mIGludGVydmFsPFQsIFBvbGljaWVzPjo6b3BlcmF0b3IvPShjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHIpCnsKICByZXR1cm4gKnRoaXMgPSAqdGhpcyAvIHI7Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiBpbnRlcnZhbDxULCBQb2xpY2llcz46Om9wZXJhdG9yLz0oY29uc3QgVCYgcikKewogIHJldHVybiAqdGhpcyA9ICp0aGlzIC8gcjsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gb3BlcmF0b3IrKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHkpCnsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCwgeSkpCiAgICByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+OjplbXB0eSgpOwogIHR5cGVuYW1lIFBvbGljaWVzOjpyb3VuZGluZyBybmQ7CiAgcmV0dXJuIGludGVydmFsPFQsUG9saWNpZXM+KHJuZC5hZGRfZG93bih4Lmxvd2VyKCksIHkubG93ZXIoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJuZC5hZGRfdXAgICh4LnVwcGVyKCksIHkudXBwZXIoKSksIHRydWUpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBvcGVyYXRvcisoY29uc3QgVCYgeCwgY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB5KQp7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgsIHkpKQogICAgcmV0dXJuIGludGVydmFsPFQsIFBvbGljaWVzPjo6ZW1wdHkoKTsKICB0eXBlbmFtZSBQb2xpY2llczo6cm91bmRpbmcgcm5kOwogIHJldHVybiBpbnRlcnZhbDxULFBvbGljaWVzPihybmQuYWRkX2Rvd24oeCwgeS5sb3dlcigpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm5kLmFkZF91cCAgKHgsIHkudXBwZXIoKSksIHRydWUpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBvcGVyYXRvcisoY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4LCBjb25zdCBUJiB5KQp7IHJldHVybiB5ICsgeDsgfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gb3BlcmF0b3ItKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHkpCnsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCwgeSkpCiAgICByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+OjplbXB0eSgpOwogIHR5cGVuYW1lIFBvbGljaWVzOjpyb3VuZGluZyBybmQ7CiAgcmV0dXJuIGludGVydmFsPFQsUG9saWNpZXM+KHJuZC5zdWJfZG93bih4Lmxvd2VyKCksIHkudXBwZXIoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJuZC5zdWJfdXAgICh4LnVwcGVyKCksIHkubG93ZXIoKSksIHRydWUpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBvcGVyYXRvci0oY29uc3QgVCYgeCwgY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB5KQp7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgsIHkpKQogICAgcmV0dXJuIGludGVydmFsPFQsIFBvbGljaWVzPjo6ZW1wdHkoKTsKICB0eXBlbmFtZSBQb2xpY2llczo6cm91bmRpbmcgcm5kOwogIHJldHVybiBpbnRlcnZhbDxULFBvbGljaWVzPihybmQuc3ViX2Rvd24oeCwgeS51cHBlcigpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm5kLnN1Yl91cCAgKHgsIHkubG93ZXIoKSksIHRydWUpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBvcGVyYXRvci0oY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4LCBjb25zdCBUJiB5KQp7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgsIHkpKQogICAgcmV0dXJuIGludGVydmFsPFQsIFBvbGljaWVzPjo6ZW1wdHkoKTsKICB0eXBlbmFtZSBQb2xpY2llczo6cm91bmRpbmcgcm5kOwogIHJldHVybiBpbnRlcnZhbDxULFBvbGljaWVzPihybmQuc3ViX2Rvd24oeC5sb3dlcigpLCB5KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcm5kLnN1Yl91cCAgKHgudXBwZXIoKSwgeSksIHRydWUpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBvcGVyYXRvciooY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeSkKewogIEJPT1NUX1VTSU5HX1NURF9NSU4oKTsKICBCT09TVF9VU0lOR19TVERfTUFYKCk7CiAgdHlwZWRlZiBpbnRlcnZhbDxULCBQb2xpY2llcz4gSTsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCwgeSkpCiAgICByZXR1cm4gSTo6ZW1wdHkoKTsKICB0eXBlbmFtZSBQb2xpY2llczo6cm91bmRpbmcgcm5kOwogIGNvbnN0IFQmIHhsID0geC5sb3dlcigpOwogIGNvbnN0IFQmIHh1ID0geC51cHBlcigpOwogIGNvbnN0IFQmIHlsID0geS5sb3dlcigpOwogIGNvbnN0IFQmIHl1ID0geS51cHBlcigpOwoKICBpZiAoaW50ZXJ2YWxfbGliOjp1c2VyOjppc19uZWcoeGwpKQogICAgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfcG9zKHh1KSkKICAgICAgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfbmVnKHlsKSkKICAgICAgICBpZiAoaW50ZXJ2YWxfbGliOjp1c2VyOjppc19wb3MoeXUpKSAvLyBNICogTQogICAgICAgICAgcmV0dXJuIEkobWluIEJPT1NUX1BSRVZFTlRfTUFDUk9fU1VCU1RJVFVUSU9OKHJuZC5tdWxfZG93bih4bCwgeXUpLCBybmQubXVsX2Rvd24oeHUsIHlsKSksCiAgICAgICAgICAgICAgICAgICBtYXggQk9PU1RfUFJFVkVOVF9NQUNST19TVUJTVElUVVRJT04ocm5kLm11bF91cCAgKHhsLCB5bCksIHJuZC5tdWxfdXAgICh4dSwgeXUpKSwgdHJ1ZSk7CiAgICAgICAgZWxzZSAgICAgICAgICAgICAgICAgICAgLy8gTSAqIE4KICAgICAgICAgIHJldHVybiBJKHJuZC5tdWxfZG93bih4dSwgeWwpLCBybmQubXVsX3VwKHhsLCB5bCksIHRydWUpOwogICAgICBlbHNlCiAgICAgICAgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfcG9zKHl1KSkgLy8gTSAqIFAKICAgICAgICAgIHJldHVybiBJKHJuZC5tdWxfZG93bih4bCwgeXUpLCBybmQubXVsX3VwKHh1LCB5dSksIHRydWUpOwogICAgICAgIGVsc2UgICAgICAgICAgICAgICAgICAgIC8vIE0gKiBaCiAgICAgICAgICByZXR1cm4gSShzdGF0aWNfY2FzdDxUPigwKSwgc3RhdGljX2Nhc3Q8VD4oMCksIHRydWUpOwogICAgZWxzZQogICAgICBpZiAoaW50ZXJ2YWxfbGliOjp1c2VyOjppc19uZWcoeWwpKQogICAgICAgIGlmIChpbnRlcnZhbF9saWI6OnVzZXI6OmlzX3Bvcyh5dSkpIC8vIE4gKiBNCiAgICAgICAgICByZXR1cm4gSShybmQubXVsX2Rvd24oeGwsIHl1KSwgcm5kLm11bF91cCh4bCwgeWwpLCB0cnVlKTsKICAgICAgICBlbHNlICAgICAgICAgICAgICAgICAgICAvLyBOICogTgogICAgICAgICAgcmV0dXJuIEkocm5kLm11bF9kb3duKHh1LCB5dSksIHJuZC5tdWxfdXAoeGwsIHlsKSwgdHJ1ZSk7CiAgICAgIGVsc2UKICAgICAgICBpZiAoaW50ZXJ2YWxfbGliOjp1c2VyOjppc19wb3MoeXUpKSAvLyBOICogUAogICAgICAgICAgcmV0dXJuIEkocm5kLm11bF9kb3duKHhsLCB5dSksIHJuZC5tdWxfdXAoeHUsIHlsKSwgdHJ1ZSk7CiAgICAgICAgZWxzZSAgICAgICAgICAgICAgICAgICAgLy8gTiAqIFoKICAgICAgICAgIHJldHVybiBJKHN0YXRpY19jYXN0PFQ+KDApLCBzdGF0aWNfY2FzdDxUPigwKSwgdHJ1ZSk7CiAgZWxzZQogICAgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfcG9zKHh1KSkKICAgICAgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfbmVnKHlsKSkKICAgICAgICBpZiAoaW50ZXJ2YWxfbGliOjp1c2VyOjppc19wb3MoeXUpKSAvLyBQICogTQogICAgICAgICAgcmV0dXJuIEkocm5kLm11bF9kb3duKHh1LCB5bCksIHJuZC5tdWxfdXAoeHUsIHl1KSwgdHJ1ZSk7CiAgICAgICAgZWxzZSAgICAgICAgICAgICAgICAgICAgLy8gUCAqIE4KICAgICAgICAgIHJldHVybiBJKHJuZC5tdWxfZG93bih4dSwgeWwpLCBybmQubXVsX3VwKHhsLCB5dSksIHRydWUpOwogICAgICBlbHNlCiAgICAgICAgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfcG9zKHl1KSkgLy8gUCAqIFAKICAgICAgICAgIHJldHVybiBJKHJuZC5tdWxfZG93bih4bCwgeWwpLCBybmQubXVsX3VwKHh1LCB5dSksIHRydWUpOwogICAgICAgIGVsc2UgICAgICAgICAgICAgICAgICAgIC8vIFAgKiBaCiAgICAgICAgICByZXR1cm4gSShzdGF0aWNfY2FzdDxUPigwKSwgc3RhdGljX2Nhc3Q8VD4oMCksIHRydWUpOwogICAgZWxzZSAgICAgICAgICAgICAgICAgICAgICAgIC8vIFogKiA/CiAgICAgIHJldHVybiBJKHN0YXRpY19jYXN0PFQ+KDApLCBzdGF0aWNfY2FzdDxUPigwKSwgdHJ1ZSk7Cn0KCnRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIFBvbGljaWVzPiBpbmxpbmUKaW50ZXJ2YWw8VCwgUG9saWNpZXM+IG9wZXJhdG9yKihjb25zdCBUJiB4LCBjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHkpCnsgCiAgdHlwZWRlZiBpbnRlcnZhbDxULCBQb2xpY2llcz4gSTsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCwgeSkpCiAgICByZXR1cm4gSTo6ZW1wdHkoKTsKICB0eXBlbmFtZSBQb2xpY2llczo6cm91bmRpbmcgcm5kOwogIGNvbnN0IFQmIHlsID0geS5sb3dlcigpOwogIGNvbnN0IFQmIHl1ID0geS51cHBlcigpOwogIC8vIHggaXMgc3VwcG9zZWQgbm90IHRvIGJlIGluZmluaXRlCiAgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfbmVnKHgpKQogICAgcmV0dXJuIEkocm5kLm11bF9kb3duKHgsIHl1KSwgcm5kLm11bF91cCh4LCB5bCksIHRydWUpOwogIGVsc2UgaWYgKGludGVydmFsX2xpYjo6dXNlcjo6aXNfemVybyh4KSkKICAgIHJldHVybiBJKHN0YXRpY19jYXN0PFQ+KDApLCBzdGF0aWNfY2FzdDxUPigwKSwgdHJ1ZSk7CiAgZWxzZQogICAgcmV0dXJuIEkocm5kLm11bF9kb3duKHgsIHlsKSwgcm5kLm11bF91cCh4LCB5dSksIHRydWUpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBvcGVyYXRvciooY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4LCBjb25zdCBUJiB5KQp7IHJldHVybiB5ICogeDsgfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gb3BlcmF0b3IvKGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnRlcnZhbDxULCBQb2xpY2llcz4mIHkpCnsKICBpZiAoaW50ZXJ2YWxfbGliOjpkZXRhaWw6OnRlc3RfaW5wdXQoeCwgeSkpCiAgICByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+OjplbXB0eSgpOwogIGlmICh6ZXJvX2luKHkpKQogICAgaWYgKCFpbnRlcnZhbF9saWI6OnVzZXI6OmlzX3plcm8oeS5sb3dlcigpKSkKICAgICAgaWYgKCFpbnRlcnZhbF9saWI6OnVzZXI6OmlzX3plcm8oeS51cHBlcigpKSkKICAgICAgICByZXR1cm4gaW50ZXJ2YWxfbGliOjpkZXRhaWw6OmRpdl96ZXJvKHgpOwogICAgICBlbHNlCiAgICAgICAgcmV0dXJuIGludGVydmFsX2xpYjo6ZGV0YWlsOjpkaXZfbmVnYXRpdmUoeCwgeS5sb3dlcigpKTsKICAgIGVsc2UKICAgICAgaWYgKCFpbnRlcnZhbF9saWI6OnVzZXI6OmlzX3plcm8oeS51cHBlcigpKSkKICAgICAgICByZXR1cm4gaW50ZXJ2YWxfbGliOjpkZXRhaWw6OmRpdl9wb3NpdGl2ZSh4LCB5LnVwcGVyKCkpOwogICAgICBlbHNlCiAgICAgICAgcmV0dXJuIGludGVydmFsPFQsIFBvbGljaWVzPjo6ZW1wdHkoKTsKICBlbHNlCiAgICByZXR1cm4gaW50ZXJ2YWxfbGliOjpkZXRhaWw6OmRpdl9ub25femVybyh4LCB5KTsKfQoKdGVtcGxhdGU8Y2xhc3MgVCwgY2xhc3MgUG9saWNpZXM+IGlubGluZQppbnRlcnZhbDxULCBQb2xpY2llcz4gb3BlcmF0b3IvKGNvbnN0IFQmIHgsIGNvbnN0IGludGVydmFsPFQsIFBvbGljaWVzPiYgeSkKewogIGlmIChpbnRlcnZhbF9saWI6OmRldGFpbDo6dGVzdF9pbnB1dCh4LCB5KSkKICAgIHJldHVybiBpbnRlcnZhbDxULCBQb2xpY2llcz46OmVtcHR5KCk7CiAgaWYgKHplcm9faW4oeSkpCiAgICBpZiAoIWludGVydmFsX2xpYjo6dXNlcjo6aXNfemVybyh5Lmxvd2VyKCkpKQogICAgICBpZiAoIWludGVydmFsX2xpYjo6dXNlcjo6aXNfemVybyh5LnVwcGVyKCkpKQogICAgICAgIHJldHVybiBpbnRlcnZhbF9saWI6OmRldGFpbDo6ZGl2X3plcm88VCwgUG9saWNpZXM+KHgpOwogICAgICBlbHNlCiAgICAgICAgcmV0dXJuIGludGVydmFsX2xpYjo6ZGV0YWlsOjpkaXZfbmVnYXRpdmU8VCwgUG9saWNpZXM+KHgsIHkubG93ZXIoKSk7CiAgICBlbHNlCiAgICAgIGlmICghaW50ZXJ2YWxfbGliOjp1c2VyOjppc196ZXJvKHkudXBwZXIoKSkpCiAgICAgICAgcmV0dXJuIGludGVydmFsX2xpYjo6ZGV0YWlsOjpkaXZfcG9zaXRpdmU8VCwgUG9saWNpZXM+KHgsIHkudXBwZXIoKSk7CiAgICAgIGVsc2UKICAgICAgICByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+OjplbXB0eSgpOwogIGVsc2UKICAgIHJldHVybiBpbnRlcnZhbF9saWI6OmRldGFpbDo6ZGl2X25vbl96ZXJvKHgsIHkpOwp9Cgp0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBQb2xpY2llcz4gaW5saW5lCmludGVydmFsPFQsIFBvbGljaWVzPiBvcGVyYXRvci8oY29uc3QgaW50ZXJ2YWw8VCwgUG9saWNpZXM+JiB4LCBjb25zdCBUJiB5KQp7CiAgaWYgKGludGVydmFsX2xpYjo6ZGV0YWlsOjp0ZXN0X2lucHV0KHgsIHkpIHx8IGludGVydmFsX2xpYjo6dXNlcjo6aXNfemVybyh5KSkKICAgIHJldHVybiBpbnRlcnZhbDxULCBQb2xpY2llcz46OmVtcHR5KCk7CiAgdHlwZW5hbWUgUG9saWNpZXM6OnJvdW5kaW5nIHJuZDsKICBjb25zdCBUJiB4bCA9IHgubG93ZXIoKTsKICBjb25zdCBUJiB4dSA9IHgudXBwZXIoKTsKICBpZiAoaW50ZXJ2YWxfbGliOjp1c2VyOjppc19uZWcoeSkpCiAgICByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+KHJuZC5kaXZfZG93bih4dSwgeSksIHJuZC5kaXZfdXAoeGwsIHkpLCB0cnVlKTsKICBlbHNlCiAgICByZXR1cm4gaW50ZXJ2YWw8VCwgUG9saWNpZXM+KHJuZC5kaXZfZG93bih4bCwgeSksIHJuZC5kaXZfdXAoeHUsIHkpLCB0cnVlKTsKfQoKfSAvLyBuYW1lc3BhY2UgbnVtZXJpYwp9IC8vIG5hbWVzcGFjZSBib29zdAoKI2VuZGlmIC8vIEJPT1NUX05VTUVSSUNfSU5URVJWQUxfQVJJVEhfSFBQCg==