Li4gTWFjcm9zL0Fzc2VydHMvL0JPT1NUX01QTF9BU1NFUlRfTVNHCgpCT09TVF9NUExfQVNTRVJUX01TRwo9PT09PT09PT09PT09PT09PT09PQoKU3lub3BzaXMKLS0tLS0tLS0KCi4uIHBhcnNlZC1saXRlcmFsOjoKICAgIAogICAgI2RlZmluZSBCT09TVF9NUExfQVNTRVJUX01TRyggY29uZGl0aW9uLCBtZXNzYWdlLCB0eXBlcyApIFxcCiAgICAgICAgfHVuc3BlY2lmaWVkLXRva2VuLXNlcXwgXFwKICAgIC9cKlwqLwoKCkRlc2NyaXB0aW9uCi0tLS0tLS0tLS0tCgpHZW5lcmF0ZXMgYSBjb21waWxhdGlvbiBlcnJvciB3aXRoIGFuIGVtYmVkZGVkIGN1c3RvbSBtZXNzYWdlIHdoZW4gdGhlIGNvbmRpdGlvbiAKZG9lc24ndCBob2xkLgoKCkhlYWRlcgotLS0tLS0KCi4uIHBhcnNlZC1saXRlcmFsOjoKICAgIAogICAgI2luY2x1ZGUgPGJvb3N0L21wbC9hc3NlcnQuaHBwPgoKClBhcmFtZXRlcnMKLS0tLS0tLS0tLQoKKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBQYXJhbWV0ZXIgICAgIHwgUmVxdWlyZW1lbnQgICAgICAgICAgICAgICAgICAgICAgIHwgRGVzY3JpcHRpb24gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKz09PT09PT09PT09PT09PSs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSs9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSsKfCBgYGNvbmRpdGlvbmBgIHwgQW4gaW50ZWdyYWwgY29uc3RhbnQgZXhwcmVzc2lvbiAgIHwgQSBjb25kaXRpb24gdG8gYmUgYXNzZXJ0ZWQuICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBgYG1lc3NhZ2VgYCAgIHwgQSBsZWdhbCBpZGVudGlmaWVyIHRva2VuICAgICAgICAgIHwgQSBjdXN0b20gbWVzc2FnZSBpbiBhIGZvcm0gb2YgYSBsZWdhbCBDKysgICAgIHwKfCAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgaWRlbnRpZmllciB0b2tlbi4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKfCBgYHR5cGVzYGAgICAgIHwgQSBsZWdhbCBmdW5jdGlvbiBwYXJhbWV0ZXIgbGlzdCAgIHwgQSBwYXJlbnRoaXplZCBsaXN0IG9mIHR5cGVzIHRvIGJlIGRpc3BsYXllZCAgIHwKfCAgICAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgaW4gdGhlIGVycm9yIG1lc3NhZ2UuICAgICAgICAgICAgICAgICAgICAgICAgIHwKKy0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSsKCgpFeHByZXNzaW9uIHNlbWFudGljcwotLS0tLS0tLS0tLS0tLS0tLS0tLQoKRm9yIGFueSBpbnRlZ3JhbCBjb25zdGFudCBleHByZXNzaW9uIGBgZXhwcmBgLCBsZWdhbCBDKysgaWRlbnRpZmllciBgYG1lc3NhZ2VgYCwgYW5kIAphcmJpdHJhcnkgdHlwZXMgYGB0MWBgLCBgYHQyYGAsLi4uIGBgdG5gYDoKCgouLiBwYXJzZWQtbGl0ZXJhbDo6CgogICAgQk9PU1RfTVBMX0FTU0VSVF9NU0coIGV4cHIsIG1lc3NhZ2UsICh0MSwgdDIsLi4uIHRuKSApOwoKOlJldHVybiB0eXBlOgogICAgTm9uZS4KCjpQcmVjb25kaXRpb246CiAgICBgYHQxYGAsIGBgdDJgYCwuLi4gYGB0bmBgIGFyZSBub24tYGB2b2lkYGAuIAoKOlNlbWFudGljczoKICAgIEdlbmVyYXRlcyBhIGNvbXBpbGF0aW9uIGVycm9yIGlmIGBgZXhwciAhPSB0cnVlYGAsIG90aGVyd2lzZQogICAgaGFzIG5vIGVmZmVjdC4gCiAgICAKICAgIFdoZW4gcG9zc2libGUgd2l0aGluIHRoZSBjb21waWxlcidzIGRpYWdub3N0aWMgY2FwYWJpbGl0aWVzLAogICAgdGhlIGVycm9yIG1lc3NhZ2Ugd2lsbCBpbmNsdWRlIHRoZSBgYG1lc3NhZ2VgYCBpZGVudGlmaWVyIGFuZCB0aGUgcGFyZW50aGl6ZWQgCiAgICBsaXN0IG9mIGBgdDFgYCwgYGB0MmBgLC4uLiBgYHRuYGAgdHlwZXMsIGFuZCBoYXZlIGEgZ2VuZXJhbCBmb3JtIG9mOgoKICAgIC4uIHBhcnNlZC1saXRlcmFsOjoKICAgIAogICAgICAgIHwuLi58IFwqXCpcKlwqXCpcKlwqXCpcKlwqXCpcKiggfC4uLnw6Om1lc3NhZ2UgKVwqXCpcKlwqXCpcKlwqXCpcKlwqXCpcKikodDEsIHQyLC4uLiB0bikgfC4uLnwKCgouLiBwYXJzZWQtbGl0ZXJhbDo6CgogICAgQk9PU1RfTVBMX0FTU0VSVF9NU0coIGV4cHIsIG1lc3NhZ2UsICh0eXBlczx0MSwgdDIsLi4uIHRuPikgKTsKCjpSZXR1cm4gdHlwZToKICAgIE5vbmUuCgo6UHJlY29uZGl0aW9uOgogICAgTm9uZS4KCjpTZW1hbnRpY3M6CiAgICBHZW5lcmF0ZXMgYSBjb21waWxhdGlvbiBlcnJvciBpZiBgYGV4cHIgIT0gdHJ1ZWBgLCBvdGhlcndpc2UKICAgIGhhcyBubyBlZmZlY3QuIAoKICAgIFdoZW4gcG9zc2libGUgd2l0aGluIHRoZSBjb21waWxlcidzIGRpYWdub3N0aWNzIGNhcGFiaWxpdGllcywKICAgIHRoZSBlcnJvciBtZXNzYWdlIHdpbGwgaW5jbHVkZSB0aGUgYGBtZXNzYWdlYGAgaWRlbnRpZmllciBhbmQgdGhlIGxpc3Qgb2YgCiAgICBgYHQxYGAsIGBgdDJgYCwuLi4gYGB0bmBgIHR5cGVzLCBhbmQgaGF2ZSBhIGdlbmVyYWwgZm9ybSBvZjoKCiAgICAuLiBwYXJzZWQtbGl0ZXJhbDo6CiAgICAKICAgICAgICB8Li4ufCBcKlwqXCpcKlwqXCpcKlwqXCpcKlwqXCooIHwuLi58OjptZXNzYWdlIClcKlwqXCpcKlwqXCpcKlwqXCpcKlwqXCopKHR5cGVzPHQxLCB0MiwuLi4gdG4+KSB8Li4ufAoKCkV4YW1wbGUKLS0tLS0tLQoKOjoKICAgIAogICAgdGVtcGxhdGU8IHR5cGVuYW1lIFQgPiBzdHJ1Y3QgbXkKICAgIHsKICAgICAgICAvLyAuLi4KICAgICAgICBCT09TVF9NUExfQVNTRVJUX01TRyggCiAgICAgICAgICAgICAgaXNfaW50ZWdyYWw8VD46OnZhbHVlCiAgICAgICAgICAgICwgTk9OX0lOVEVHUkFMX1RZUEVTX0FSRV9OT1RfQUxMT1dFRAogICAgICAgICAgICAsIChUKQogICAgICAgICAgICApOwogICAgfTsKICAgIAogICAgbXk8dm9pZCo+IHRlc3Q7CgogICAgLy8gSW4gaW5zdGFudGlhdGlvbiBvZiBgbXk8dm9pZCo+JzoKICAgIC8vICAgaW5zdGFudGlhdGVkIGZyb20gaGVyZQogICAgLy8gY29udmVyc2lvbiBmcm9tIGAKICAgIC8vICAgbXBsXzo6ZmFpbGVkKioqKioqKioqKioqKG15PHZvaWQqPjo6CiAgICAvLyAgIE5PTl9JTlRFR1JBTF9UWVBFU19BUkVfTk9UX0FMTE9XRUQ6OioqKioqKioqKioqKikodm9pZCopCiAgICAvLyAgICcgdG8gbm9uLXNjYWxhciB0eXBlIGBtcGxfOjphc3NlcnQ8ZmFsc2U+JyByZXF1ZXN0ZWQKCgpTZWUgYWxzbwotLS0tLS0tLQoKfEFzc2VydHN8LCB8Qk9PU1RfTVBMX0FTU0VSVHwsIHxCT09TVF9NUExfQVNTRVJUX05PVHwsIHxCT09TVF9NUExfQVNTRVJUX1JFTEFUSU9OfAoKCi4uIGNvcHlyaWdodDo6IENvcHlyaWdodCCpICAyMDAxLTIwMDkgQWxla3NleSBHdXJ0b3ZveSBhbmQgRGF2aWQgQWJyYWhhbXMKICAgRGlzdHJpYnV0ZWQgdW5kZXIgdGhlIEJvb3N0IFNvZnR3YXJlIExpY2Vuc2UsIFZlcnNpb24gMS4wLiAoU2VlIGFjY29tcGFueWluZwogICBmaWxlIExJQ0VOU0VfMV8wLnR4dCBvciBjb3B5IGF0IGh0dHA6Ly93d3cuYm9vc3Qub3JnL0xJQ0VOU0VfMV8wLnR4dCkK