ZGlmZiAtLWdpdCBhL2Qvc2VoZXIvaGFldXNlci9tb2ViZWwvc2NobHVlc3NlbGJyZXR0LmMgYi9kL3NlaGVyL2hhZXVzZXIvbW9lYmVsL3NjaGx1ZXNzZWxicmV0dC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkzYmFjZTYKLS0tIC9kZXYvbnVsbAorKysgYi9kL3NlaGVyL2hhZXVzZXIvbW9lYmVsL3NjaGx1ZXNzZWxicmV0dC5jCkBAIC0wLDAgKzEsNjc5IEBACisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8gTmFtZSBkZXMgT2JqZWN0czogICAgU2NobHVlc3NlbGJyZXR0CisvLyBMZXR6dGUgQWVuZGVydW5nOiAgICAwMi4wNi4yMDAxCisvLyBPcmlnaW5hbDogICAgICAgICAgICBTd2lmdAorLy8gTmV1ZSBWZXJzaW9uOiAgICAgICAgU2VsZXZlbgorLy8g3GJlcm5vbW1lbjogICAgICAgICAgMjMuMDEuMjAwNgorLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8qIENoYW5nZWxvZworICAgKiAyMS4wNi4yMDA3LCBaZXNzdHJhCisgICAgIGltIGluaGVyaXQgYWJzLiBQZmFkIGR1cmNoIExBREVOKHgpIGVyc2V0enQuCisgICAqIDAxLjA3LjIwMDcsIFplc3N0cmEKKyAgICAgR2V0T3duZXIoKSBkZWZpbmllcnQuCisgICAqIDExLjA1LjIwMTUsIEFyYXRob3JuCisgICAgIHdlaXRyYWV1bWlnIHVlYmVyYXJiZWl0ZXQgenVyIEJlaGVidW5nIHZvbiBGZWhsZnVua3Rpb25lbgorKi8KKyNwcmFnbWEgc3Ryb25nX3R5cGVzLCBydHRfY2hlY2tzCisKKyNpbmNsdWRlICIvZC9zZWhlci9oYWV1c2VyL21vZWJlbC9zY2hyYW5rbGFkZW4uaCIKKyNpbmNsdWRlIDxhbnNpLmg+Citpbmhlcml0ICBMQURFTigic3dpZnRfc3RkX2NvbnRhaW5lciIpOworCisjZGVmaW5lIFZFUlNJT05fT0JKICIzIgorLy8gWnVyIEluZGl6aWVydW5nIGRlcyBNYXBwaW5ncyA8aGFrZW4+CisjZGVmaW5lIEhPT0tfT0IgICAgMAorI2RlZmluZSBIT09LX0xBQkVMIDEKKworcHJpdmF0ZSB2YXJhcmdzIHN0cmluZyBLZXlEZXNjcmlwdGlvbihpbnQga2V5bnVtKTsKK3ByaXZhdGUgaW50IElzVmFsaWRLZXkob2JqZWN0IG9iKTsKK3ByaXZhdGUgaW50IEdldE5leHRGcmVlU2xvdCgpOworcHJpdmF0ZSBvYmplY3QgR2V0S2V5Rm9yTGFiZWwoc3RyaW5nIGxhYmVsKTsKK3ByaXZhdGUgaW50IEdldEhvb2tOdW1iZXJGb3JLZXkob2JqZWN0IG9iKTsKK3ByaXZhdGUgdm9pZCBDb25zb2xpZGF0ZUludmVudG9yeSgpOworCisvLyBTdHJ1a3R1cjogKFsgaGFrZW5fbnIgOiBvYmpla3Q7IGJlc2NocmlmdHVuZyBdKQorcHJpdmF0ZSBtYXBwaW5nIGhha2VuPShbOjJdKTsKK3ByaXZhdGUgaW50IGhvb2tsaXN0X2xvbmcgPSAwOworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CisgIGlmICghY2xvbmVwKFRPKSkgeworICAgIHNldF9uZXh0X3Jlc2V0KC0xKTsKKyAgICByZXR1cm47CisgIH0KKyAgOjpjcmVhdGUoKTsKKyAgCisgIGZvcmVhY2goaW50IGk6IDEuLjE2KSB7CisgICAgbV9hZGQoaGFrZW4sIGkpOworICB9CisKKyAgLy8gREVCVUchIFNvbnN0IGZ1bmt0aW9uaWVydCdzIGF1c3NlcmhhbGIgdm9uIFNlaGVyaGFldXNlcm4gbmljaHQuCisgIFNldFByb3AoInRlc3QiLDEpOworICBTZXRQcm9wKFBfU0hPUlQsICJFaW4gU2NobHVlc3NlbGJyZXR0Iik7CisgIFNldChQX0xPTkcsIGZ1bmN0aW9uIHN0cmluZyAoKSB7CisgICAgc3RyaW5nIHRleHQgPSBCUygKKyAgICAgICJFaW4ga2xlaW5lcyBCcmV0dCBhdXMgSG9seiwgYW4gZGVtIGluIDIgUmVpaGVuIGplIDggSGFrZW4gYmVmZXN0aWd0ICIKKyAgICAgICJzaW5kLCBhbiBkaWUgbWFuIGluc2dlc2FtdCAxNiBTY2hsdWVzc2VsIGhhZW5nZW4ga2Fubi4gVW0gZGllICIKKyAgICAgICJVZWJlcnNpY2h0IG5pY2h0IHp1IHZlcmxpZXJlbiwgYmVmaW5kZXQgc2ljaCB1ZWJlciBqZWRlbSBkZXIgSGFrZW4gIgorICAgICAgImVpbiBrbGVpbmVzIFNjaGlsZGNoZW4gYXVzIFNjaGllZmVyLCBkYXMgc2ljaCBiZXNjaHJpZnRlbiBsYWVzc3QuICIKKyAgICAgICJBdWYgZGllc2UgV2Vpc2UgZ2VodCBkZXIgU2lubiB1bmQgWndlY2sgZGVzIFNjaGx1ZXNzZWxzLCBkZXIgYW4gIgorICAgICAgImRpZXNlbSBIYWtlbiBydWh0LCBuaWNodCB2ZXJsb3Jlbi4gUHJha3Rpc2NoZXJ3ZWlzZSBoYWVuZ3QgYW4gZWluZXIgIgorICAgICAgIlNjaG51ciBlaW4gU3R1ZWNrIEtyZWlkZSB2b24gZGVtIEJyZXR0IGhlcmFiLCBtaXQgZGVtIER1IGRpZSAiCisgICAgICAiU2NoaWxkY2hlbiBiZXNjaHJpZnRlbiBrYW5uc3QuIik7CisgICAgdGV4dCArPSBLZXlEZXNjcmlwdGlvbigwKTsKKyAgICByZXR1cm4gdGV4dDsgCisgIH0sIEZfUVVFUllfTUVUSE9EKTsKKworICBBZGRJZCgoeyJzY2hsdWVzc2VsYnJldHQiLCJicmV0dCJ9KSk7CisgIFNldFByb3AoImNudF92ZXJzaW9uX29iaiIsIFZFUlNJT05fT0JKKTsKKyAgU2V0UHJvcChQX0NOVF9TVEFUVVMsIDApOworICBTZXRQcm9wKFBfTkFNRSwgIlNjaGx1ZXNzZWxicmV0dCIpOworICBTZXRQcm9wKFBfR0VOREVSLCBORVVURVIpOworICBTZXRQcm9wKFBfV0VJR0hULCAxMDAwKTsgICAgICAgICAvLyBHZXdpY2h0IDEgS2cKKyAgU2V0UHJvcChQX01BWF9XRUlHSFQsIDEwMDAwMDApOyAgLy8gRXMgcGFzc2VuIGZ1ZXIgMTAwMCBrZyBTYWNoZW4gcmVpbi4KKyAgU2V0UHJvcChQX1dFSUdIVF9QRVJDRU5ULCAxMDApOyAgLy8gRGFmdWVyIG1hY2h0IGVyIGF1Y2ggbml4IGxlaWNodGVyIDopCisgIFNldFByb3AoUF9NQVhfT0JKRUNUUywgMTYpOworICAvLyBNYW4gc29sbCBuaWNodHMgdWViZXIgZGVuIG5vcm1hbGVuIE1lY2hhbmlzbXVzIHJlaW5zdGVja2VuIG9kZXIgCisgIC8vIHJhdXNuZWhtZW4ga29lbm5lbi4gV2lyZCB2b24gcHV0X2FuZF9nZXQuYyBnZXBydWVmdC4KKyAgU2V0UHJvcChQX0NPTlRBSU5FUiwgMCk7CisgIFNldFByb3AoUF9OT0lOU0VSVF9NU0csIEJTKCJBbiBkYXMgU2NobHVlc3NlbGJyZXR0IGthbm5zdCBEdSBudXIgIgorICAgICJTY2hsdWVzc2VsIGhhZW5nZW4uXG5TeW50YXg6ICdoYWVuZ2UgPHNjaGx1ZXNzZWw+IGFuIGJyZXR0Jy4iKSk7CisgIFNldFByb3AoUF9OT0dFVCwgIkRhcyBnZWh0IG5pY2h0LiAiK05hbWUoV0VSLDEpKworICAgICIgbGFlc3N0IHNpY2ggbmljaHQgYmV3ZWdlbi5cbiIpOworICBTZXRQcm9wKFBfTUFURVJJQUwsICh7TUFUX09BSywgTUFUX01JU0NfTUFHSUN9KSApOworICBTZXRQcm9wKFBfSU5GTywgIlZlcnN1Y2gncyBtYWwgbWl0OiBcInNrb21tYW5kb3Mgc2NobHVlc3NlbGJyZXR0XCIuXG4iKTsKKworICBBRCgoeyJob2x6In0pLCBCUygiRWNodGUsIHJvYnVzdGUgRWljaGUuIikpOworCisgIFJlbW92ZUNtZCgoeyJzY2hsaWVzc2UiLCJzY2hsaWVzcyIsIm9lZmZuZSJ9KSk7CisKKyAgQWRkQ21kKCh7InVudCIsICJ1bnRlcnN1Y2hlIiwgImJldHJhY2h0ZSIsICJiZXRyYWNodCIsICJiZXRyIiwKKyAgICAgICAgICAgInNjaGF1ZSIsICJzY2hhdSJ9KSwgInVudF9oYWtlbiIpOworICBBZGRDbWQoKHsiaGFlbmciLCAiaGFlbmdlIn0pLCAic2NobHVlc3NlbF9hbl9oYWtlbl9oYWVuZ2VuIik7CisgIEFkZENtZCgoeyJuaW1tIn0pLCAic2NobHVlc3NlbF92b25faGFrZW5fbmVobWVuIik7CisgIEFkZENtZCgic2Jlc2NocmlmdGUiLCAiY21kX2Jlc2NocmlmdGVuIik7CisgIEFkZENtZCgic2xpc3RlIiwgImNtZF9zbGlzdGUiKTsKK30KKworLyoqKioqIEtPTU1BTkRPRlVOS1RJT05FTiAqKioqKi8KKworLy8gS29uZmlndXJhdGlvbiBkZXIgU2NobHVlc3NlbGxpc3RlLCBlbnR3ZWRlciAiYWxsZSIgYW56ZWlnZW4gb2RlciBudXIgZGllCisvLyBiZWxlZ3RlbiBIYWtlbi4KK3N0YXRpYyBpbnQgY21kX3NsaXN0ZShzdHJpbmcgc3RyKSB7CisgIG5vdGlmeV9mYWlsKCJTeW50YXg6ICdzbGlzdGUgYWxsZXxiZWxlZ3RlJy5cbiIpOworICBpZiAoICFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpICkKKyAgICByZXR1cm4gMDsKKworICBpZiAoIHN0ciA9PSAiYWxsZSIgKSB7CisgICAgaWYgKCAhaG9va2xpc3RfbG9uZyApIHsKKyAgICAgIHRlbGxfb2JqZWN0KFRQLCBCUygiT2ssIGVzIHdlcmRlbiBqZXR6dCBpbW1lciBhbGxlIEhha2VuICIKKyAgICAgICAgImF1ZmdlbGlzdGV0LiIpKTsKKyAgICAgIGhvb2tsaXN0X2xvbmcgPSAxOworICAgIH0KKyAgICBlbHNlIAorICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJEaWUgRWluc3RlbGx1bmcgd2FyIHNjaG9uICdhbGxlJy4iKSk7CisgIH0KKyAgZWxzZSBpZiAoIHN0ciA9PSAiYmVsZWd0ZSIgKSB7CisgICAgaWYgKCBob29rbGlzdF9sb25nICkgeworICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJPaywgZXMgd2VyZGVuIGpldHp0IG51ciBkaWUgYmVsZWd0ZW4gSGFrZW4gIgorICAgICAgICAiYXVmZ2VsaXN0ZXQuIikpOworICAgICAgaG9va2xpc3RfbG9uZyA9MDsKKyAgICB9CisgICAgZWxzZSAKKyAgICAgIHRlbGxfb2JqZWN0KFRQLCBCUygiRGllIEVpbnN0ZWxsdW5nIHdhciBzY2hvbiAnYmVsZWd0ZScuIikpOworICB9CisgIGVsc2UgCisgICAgcmV0dXJuIDA7CisgIHJldHVybiAxOworfQorCisvLyBIYWtlbiB1bnRlcnN1Y2hlbi4gT2huZSBBbmdhYmUgZGVyIE51bW1lciB3ZXJkZW4gYWxsZSBhdXNnZWdlYmVuLAorLy8gYW5zb25zdGVuIGRlciBnZXd1ZW5zY2h0ZSwgc29mZXJuIGVzIGRpZXNlbiBnaWJ0Lgorc3RhdGljIGludCB1bnRfaGFrZW4oc3RyaW5nIHN0cikgeworICBpZiAoICFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpIHx8IHN0cnN0cihzdHIsICJoYWtlbiIpID09IC0xICkKKyAgICByZXR1cm4gMDsKKyAgCisgIGludCBoYWtlbm5yOworICBpZiAoIHNzY2FuZihzdHIsICJoYWtlbiAlZCIsIGhha2VubnIpICE9IDEgKSB7CisgICAgc3RyaW5nIGRldCA9IEtleURlc2NyaXB0aW9uKGhha2VubnIpOworICAgIHRlbGxfb2JqZWN0KFRQLCBzaXplb2YoZGV0KSA/IGRldCA6ICJEaWUgSGFrZW4gc2luZCBhbGxlIGxlZXIuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIG5vdGlmeV9mYWlsKCJXZWxjaGVuIEhha2VuIG1vZWNodGVzdCBEdSB1bnRlcnN1Y2hlbj8gRXMgZ2lidCBudXIgZGllICIKKyAgICAiSGFrZW4gMSBiaXMgMTYuXG4iKTsKKyAgaWYoIGhha2VubnI8MSB8fCBoYWtlbm5yID4gMTYgKQorICAgIHJldHVybiAwOworCisvLyAgYXVzZ2FiZV9oYWtlbihoYWtlbm5yKTsKKyAgdGVsbF9vYmplY3QoVFAsIEtleURlc2NyaXB0aW9uKGhha2VubnIpKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vIFNjaGx1ZXNzZWwgYXVmaGFlbmdlbi4KK3N0YXRpYyBpbnQgc2NobHVlc3NlbF9hbl9oYWtlbl9oYWVuZ2VuKHN0cmluZyBzdHIpIHsKKyAgbm90aWZ5X2ZhaWwoIldhcyB3aWxsc3QgRHUgd29yYW4gaGFlbmdlbj9cbiIpOworICBpZighc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSkKKyAgICByZXR1cm4gMDsKKyAgCisgIG5vdGlmeV9mYWlsKCJEYXMgZGFyZnN0IER1IG5pY2h0LlxuIik7CisgIGlmKCFlcmxhdWJ0KCkpCisgICAgcmV0dXJuIDA7CisKKyAgc3RyaW5nIHdhcywgd29yYW47CisgIG5vdGlmeV9mYWlsKCJGb2xnZW5kZSBTeW50YXggdmVyc3RlaHQgRGVpbiBTY2hsdWVzc2VsYnJldHQ6XG4iCisgICAgIiAgXCJoYWVuZ2UgPHNjaGx1ZXNzZWxuYW1lPiBhbiBoYWtlbiBbbnJdXCIgb2RlclxuIgorICAgICIgIFwiaGFlbmdlIDxzY2hsdWVzc2VsbmFtZT4gYW4gW3NjaGx1ZXNzZWxdYnJldHRcIi5cbiIpOworICBpZiAoIHNzY2FuZihzdHIsICIlcyBhbiAlcyIsIHdhcywgd29yYW4pICE9IDIgKQorICAgIHJldHVybiAwOworCisgIG5vdGlmeV9mYWlsKCJXYXMgbW9lY2h0ZXN0IER1IGFuIGRhcyBTY2hsdWVzc2VsYnJldHQgaGFlbmdlbj9cbiIpOworICBpZiAoICFzdHJpbmdwKHdhcykgKSAKKyAgICByZXR1cm4gMDsKKworICBub3RpZnlfZmFpbCgiV29yYW4gd2lsbHN0IER1IGRhcyBkZW5uIGhhZW5nZW4/XG4iKTsKKyAgaWYgKCBzdHJzdHIod29yYW4sICJoYWtlbiIsIDApPT0tMSAmJiAhaWQod29yYW4pICkKKyAgICByZXR1cm4gMDsKKworICAvLyBUZXN0LCBvYiBlcyBPYmpla3RlIGRpZXNlcyBOYW1lbnMgZ2lidC4KKyAgb2JqZWN0ICpvYnMgPSBUUC0+ZmluZF9vYnMod2FzLCBQVVRfR0VUX05PTkUpOworICAvLyBBdXMgZGVyIExpc3RlIGRlciBnZWZ1bmRlbmVuIE9iamVrdGUgYWxsZSByYXVzZmlsdGVybiwgZGllIGtlaW5lCisgIC8vIFNjaGx1ZXNzZWwgc2luZC4gQWxzIFNjaGx1ZXNzZWwgZ2VsdGVuIGhpZXIgYWxsZSBPYmpla3RlLCBkaWUgZGllCisgIC8vIElEICJzY2hsdWVzc2VsIiBoYWJlbiBvZGVyIGRpZSBtaXR0ZWxzIFF1ZXJ5RG9vcktleSgpIGVpbmVyIGJlc3RpbW10ZW4KKyAgLy8gVHVlciB6dWdlb3JkbmV0IHNpbmQuCisgIG9icyA9IGZpbHRlcihvYnMsICMnSXNWYWxpZEtleSk7CisgIG5vdGlmeV9mYWlsKCJLZWluZShuKSBTY2hsdWVzc2VsIG1pdCBkZW0gTmFtZW4gZ2VmdW5kZW4uXG4iKTsKKyAgaWYgKCAhc2l6ZW9mKG9icykgKQorICAgIHJldHVybiAwOworCisgIGludCBuciA9IEdldE5leHRGcmVlU2xvdCgpOworICBub3RpZnlfZmFpbCgiQW0gU2NobHVlc3NlbGJyZXR0IGlzdCBrZWluIEhha2VuIG1laHIgZnJlaS5cbiIpOworICBpZiAoICFuciApCisgICAgcmV0dXJuIDA7CisKKyAgLy8gV2VubiBudXIgZWluIFNjaGx1ZXNzZWwgZ2VmdW5kZW4gd3VyZGUsIHdpcmQgZ2VuYXVlciBnZXNjaGF1dCwgb2IKKyAgLy8gZGVyIFNwaWVsZXIgZ2VzYWd0IGhhdCwgd28gZGVyIGhpbnNvbGwuCisgIGlmICggc2l6ZW9mKG9icykgPT0gMSApIHsKKyAgICBpZiAoIHdvcmFuICE9ICJoYWtlbiIgfHwgIWlkKHdvcmFuKSApCisgICAgICBzc2NhbmYod29yYW4sICJoYWtlbiAlZCIsIG5yKTsKKyAgfQorCisgIG5vdGlmeV9mYWlsKCJFcyBnaWJ0IG51ciBkaWUgSGFrZW4gMSBiaXMgMTYuXG4iKTsKKyAgaWYgKCBuciA8IDEgfHwgbnIgPiAxNiApCisgICAgcmV0dXJuIDA7CisKKyAgbm90aWZ5X2ZhaWwoIkRlciBIYWtlbiBpc3QgbmljaHQgbWVociBmcmVpLlxuIik7CisgIGlmICggb2JqZWN0cChoYWtlbltucixIT09LX09CXSkgKQorICAgIHJldHVybiAwOworCisgIC8vIEFsbGUgZ2VmdW5kZW5lbiBTY2hsdWVzc2Vsb2JqZWt0ZSBhbnMgQnJldHQgaGFlbmdlbi4KKyAgZm9yZWFjaCggb2JqZWN0IGtleSA6IG9icyApIHsKKyAgICBzd2l0Y2ggKGtleS0+bW92ZShNRSwgTV9QVVQpKSB7CisgICAgICAvLyBEaWUgS2FwYXppdGFldCBpc3QgdWViZXIgUF9NQVhfT0JKRUNUUyBiZWdyZW56dC4gQWxsZQorICAgICAgLy8gU2NobGVpZmVuZHVyY2hsYWV1ZmUsIGRpZSBkaWUgS2FwYXppdGFldHNncmVuemUgZXJyZWljaGVuLCBsYW5kZW4KKyAgICAgIC8vIGluIGRlZmF1bHQgdW5kIGJlZW5kZW4gZGFtaXQgZGllIFNjaGxlaWZlLiBEYWhlciBtdWVzc2VuIHNpZSAKKyAgICAgIC8vIG5pY2h0IGdlc29uZGVydCBiZWhhbmRlbHQgd2VyZGVuLgorICAgICAgY2FzZSBNT1ZFX09LIDoKKyAgICAgICAgLy8gRmFsbHMgZGFzIEJyZXR0IHZvbGwgc2VpbiBzb2xsdGUsIGFiZXIgZmFlbHNjaGxpY2hlcndlaXNlIAorICAgICAgICAvLyBkZW5ub2NoIGVpbiB3ZWl0ZXJlciBTY2hsdWVzc2VsIGhpbmVpbmJld2VndCB3dXJkZSwgaXN0IG5yPT0wLAorICAgICAgICAvLyB1bmQgZXMgd2lyZCBlaW4gRmVobGVyIGF1c2dlbG9lc3QsIGRhbWl0IG5pY2h0IGhpbnRlcmhlciBlaW4KKyAgICAgICAgLy8gU2NobHVlc3NlbCBhbiBIYWtlbiAwIGhhZW5ndC4KKyAgICAgICAgaWYgKCAhbnIgKSB7CisgICAgICAgICAgcmFpc2VfZXJyb3IoIkZlaGxlcjogSGFrZW4gMCBkYXJmIG5pY2h0IGJlbGVndCB3ZXJkZW4uIik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJEdSBoYWVuZ3N0ICIrb2JzWzBdLT5uYW1lKFdFTiwxKSsiIGFuIEhha2VuICIrCisgICAgICAgICAgbnIrIi4iKSk7CisgICAgICAgIC8vIE51ciB3ZW5uIGVpbiBTY2hsdWVzc2VsIGVyZm9sZ3JlaWNoIGRyYW5nZWhhZW5ndCB3dXJkZSwgd2lyZCBlcgorICAgICAgICAvLyBpbiBkaWUgTGlzdGUgZWluZ2V0cmFnZW4uIEV0d2FpZ2UgQmVzY2hyaWZ0dW5nZW4gYmxlaWJlbiBiZXN0ZWhlbiwKKyAgICAgICAgaGFrZW5bbnIsIEhPT0tfT0JdID0ga2V5OworICAgICAgICAvLyB1bmQgbnVyIGRhbm4gd2lyZCBkZXIgbmFlY2hzdGUgU2xvdCBwcm9iaWVydC4gV2VubiBudXIgZWluIAorICAgICAgICAvLyBTY2hsdWVzc2VsIHZlcmFyYmVpdGV0IHdpcmQsIGlzdCBkYXMgaGllciB1bnNjaGFlZGxpY2gsIHdlaWwgZXMgCisgICAgICAgIC8vIG5pY2h0IG5vY2htYWwgYXVzZ2V3ZXJ0ZXQgd2lyZC4KKyAgICAgICAgbnIgPSBHZXROZXh0RnJlZVNsb3QoKTsKKyAgICAgICAgLy8gU2NobHVlc3NlbCB3dXJkZSB2ZXJhcmJlaXRldCB1bmQgTWVsZHVuZyBhdXNnZWdlYmVuCisgICAgICAgIG9icyAtPSAoe2tleX0pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgTUVfQ0FOVF9MRUFWRV9FTlYgOgorICAgICAgY2FzZSBNRV9DQU5UX0JFX0lOU0VSVEVEIDoKKyAgICAgIGNhc2UgTUVfQ0FOVF9CRV9EUk9QUEVEIDoKKyAgICAgICAgLy8gU2NobHVlc3NlbCB3dXJkZSBuaWNodCBlcmZvbGdyZWljaCBkcmFuZ2VoYWVuZ3QuCisgICAgICAgIHRlbGxfb2JqZWN0KFRQLCBCUyhrZXktPk5hbWUoV0VSLDEpKyIgd2VpZ2VydCBzaWNoLCBhbnMgIgorICAgICAgICAgICJTY2hsdWVzc2VsYnJldHQgZ2VoYWVuZ3QgenUgd2VyZGVuLiIpKTsKKyAgICAgICAgLy8gTWVsZHVuZyB3dXJkZSBhdXNnZWdlYmVuLCBuaWNodHMgd2VpdGVyIHp1IHR1bi4KKyAgICAgICAgb2JzIC09ICh7a2V5fSk7CisgICAgICAgIGJyZWFrOworICAgICAgLy8gVE9PX01BTllfT0JKRUNUUyB3aXJkIG5pY2h0IGhpZXIgYmVoYW5kZWx0LCBzb25kZXJuIHdlaXRlciB1bnRlbiwKKyAgICAgIC8vIHVtIGVpbmUgQXVmbGlzdHVuZyBkZXIgU2NobHVlc3NlbG5hbWVuIGF1c2dlYmVuIHp1IGtvZW5uZW4sIHN0YXR0CisgICAgICAvLyBlaW5lIFplaWxlIHBybyBTY2hsdWVzc2VsLiBEaWUgYW5kZXJlbiBSdWVja2dhYmV3ZXJ0ZSB2b24gbW92ZSgpIAorICAgICAgLy8gc2luZCBiZWkgZGllc2VyIEFydCBkZXIgQmV3ZWd1bmcgbmljaHQgenUgZXJ3YXJ0ZW4uCisgICAgICBkZWZhdWx0OiBicmVhazsKKyAgICB9CisgIH0KKyAgLy8gRnVlciBhbGxlIHVlYnJpZ2VuIHdhciB3b2hsIFRPT19NQU5ZX09CSkVDVFMgZGVyIFJ1ZWNrZ2FiZXdlcnQsIGRlbm4KKyAgLy8gZGFzIFNjaGx1ZXNzZWxicmV0dCBlcmxhdWJ0IG51ciBQX01BWF9PQkpFQ1RTID0gMTYuCisgIGlmICggc2l6ZW9mKG9icykgKSB7CisgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJGdWVyICIrQ291bnRVcChvYnMtPm5hbWUoV0VOKSkrIiBpc3QgbGVpZGVyIGtlaW4gIgorICAgICAgIkhha2VuIG1laHIgYW0gU2NobHVlc3NlbGJyZXR0IGZyZWkuIikpOworICB9CisgIHJldHVybiAxOworfQorCisvLyBTY2hsdWVzc2VsIGFibmVobWVuCitzdGF0aWMgaW50IHNjaGx1ZXNzZWxfdm9uX2hha2VuX25laG1lbihzdHJpbmcgc3RyKSB7CisgIGlmKCAhc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSApIAorICAgIHJldHVybiAwOworCisgIHN0cmluZyB3YXMsIHdvcmF1czsKKyAgaWYgKCBzc2NhbmYoc3RyLCAiJXMgYXVzICVzIiwgd2FzLCB3b3JhdXMpICE9IDIgJiYgCisgICAgICAgc3NjYW5mKHN0ciwgIiVzIHZvbiAlcyIsIHdhcywgd29yYXVzKSAhPSAyICkKKyAgICByZXR1cm4gMDsKKworICBub3RpZnlfZmFpbCgiRGFzIGRhcmZzdCBEdSBuaWNodCFcbiIpOworICBpZighZXJsYXVidCgpKSAKKyAgICByZXR1cm4gMDsKKyAKKyAgbm90aWZ5X2ZhaWwoIldvcmF1cyB3aWxsc3QgRHUgZGFzIGRlbm4gbmVobWVuP1xuIik7CisgIGlmICggIWlkKHdvcmF1cykgJiYgc3Ryc3RyKHdvcmF1cywgImhha2VuIiwgMCkgPT0gLTEgKSAKKyAgICByZXR1cm4gMDsKKworICBub3RpZnlfZmFpbCgiV2FzIHdpbGxzdCBEdSBkZW5uIHZvbSBTY2hsdWVzc2VsYnJldHQgbmVobWVuP1xuIik7CisgIGlmKCAhc3RyaW5ncCh3YXMpICkgCisgICAgcmV0dXJuIDA7CisgIAorICBub3RpZnlfZmFpbCgiRGFzIFNjaGx1ZXNzZWxicmV0dCBpc3QgZG9jaCBhYmVyIGxlZXIuXG4iKTsKKyAgaWYgKCAhc2l6ZW9mKGFsbF9pbnZlbnRvcnkoTUUpKSApCisgICAgcmV0dXJuIDA7CisKKyAgaW50IGhha2VubnI7CisgIG9iamVjdCAqa2V5cyA9ICh7fSk7CisgIC8vIEVzIG11ZXNzZW4gYXVjaCBTY2hsdWVzc2VsIHZvbiBiZXN0aW1tdGVuIEhha2VuIGFiZ2Vub21tZW4KKyAgLy8gd2VyZGVuIGtvZW5uZW4sIG5pY2h0IG51ciBqZXdlaWxzIGRlciBlcnN0ZSBtaXQgZGVyIGFuZ2VnZWJlbmVuIElELgorICAvLyBEaWVzIGhhdCBhdWNoIFByaW8gZ2VnZW51ZWJlciBkZXIgYWxsZ2VtZWluZW4gQmVncmlmZnNzdWNoZSBtaXQKKyAgLy8gZmluZF9vYnMoKS4KKyAgaWYgKCBzc2NhbmYod29yYXVzLCAiaGFrZW4gJWQiLCBoYWtlbm5yKSA9PSAxICkgeworICAgIG5vdGlmeV9mYWlsKCJFcyBnaWJ0IG51ciBkaWUgSGFrZW4gMSBiaXMgMTYuXG4iKTsKKyAgICBpZiAoIGhha2VubnIgPCAxIHx8IGhha2VubnIgPiAxNiApIAorICAgICAgcmV0dXJuIDA7CisgICAgbm90aWZ5X2ZhaWwoIkFuIGRpZXNlbSBIYWtlbiBoYWVuZ3QgYWJlciBkb2NoIGtlaW4gU2NobHVlc3NlbC5cbiIpOworICAgIGlmICggIW9iamVjdHAoaGFrZW5baGFrZW5ucixIT09LX09CXSkgKQorICAgICAgcmV0dXJuIDA7CisgICAgCisgICAga2V5cyArPSAoeyBoYWtlbltoYWtlbm5yLEhPT0tfT0JdIH0pOworICB9CisKKyAgLy8gS2VpbmVyIGdlZnVuZGVuPyBWaWVsbGVpY2h0IGlzdCBqYSBlaW5lciBtaXQgZWluZXIgYmVzdGltbXRlbiAKKyAgLy8gQmVzY2hyaWZ0dW5nIGdlbWVpbnQ/CisgIGlmICggIXNpemVvZihrZXlzKSApIHsKKyAgICAvLyBTY2hsdWVzc2VsIG1pdCBkZW0gYW5nZWdlYmVuZW4gTmFtZW4gc3VjaGVuCisgICAga2V5cyA9IFRQLT5maW5kX29icyh3YXMrIiBpbiBicmV0dCBpbiByYXVtIik7CisgICAgLy8gSGFrZW5udW1tZXIgZXJtaXR0ZWxuLCB3ZW5uIGVpbmUgQmVzY2hyaWZ0dW5nIGFuZ2VnZWJlbiB3dXJkZS4KKyAgICBzdHJpbmcgd2FudGVkX2Rlc2M7CisgICAgc3NjYW5mKHdhcywgInNjaGx1ZXNzZWwgZnVlciAlcyIsIHdhbnRlZF9kZXNjKTsKKyAgICBvYmplY3Qgd2FudGVkX2tleSA9IEdldEtleUZvckxhYmVsKHdhbnRlZF9kZXNjKTsKKyAgICBpZiAoIG9iamVjdHAod2FudGVkX2tleSkgKQorICAgICAga2V5cyArPSAoe3dhbnRlZF9rZXl9KTsKKyAgfQorICAvLyBJbW1lciBub2NoIG5peCBnZWZ1bmRlbj8gRGFubiBtdXNzIHNpY2ggZGVyIFNwaWVsZXIgd2FzIGFuZGVyZXMgCisgIC8vIGVpbmZhbGxlbiBsYXNzZW4uCisgIG5vdGlmeV9mYWlsKCJBbSBTY2hsdWVzc2VsYnJldHQgaGFlbmd0IGtlaW4gc29sY2hlciBTY2hsdWVzc2VsLlxuIik7CisgIGlmICggIXNpemVvZihrZXlzKSApCisgICAgcmV0dXJuIDA7CisKKyAgLy8gQWxsZSBnZWZ1bmRlbmVuIFNjaGx1ZXNzZWwgdmVyYXJiZWl0ZW4uIEFsbGUsIGRpZSBuaWNodCBiZXdlZ3Qgd2VyZGVuCisgIC8vIGtvZW5uZW4sIHZlcmJsZWliZW4gaW4gZGVyIExpc3RlLgorICBmb3JlYWNoKCBvYmplY3Qga2V5IDoga2V5cyApIHsKKyAgICBpbnQgY3VycmVudF9ob29rID0gR2V0SG9va051bWJlckZvcktleShrZXkpOworICAgIGlmICgga2V5LT5tb3ZlKFRQLE1fR0VUKSA9PSBNT1ZFX09LICkgeworICAgICAga2V5cyAtPSAoeyBrZXkgfSk7CisgICAgICB0ZWxsX29iamVjdChUUCwgQlMoIkR1IG5pbW1zdCAiK2tleS0+bmFtZShXRU4sMSkrIiB2b24gSGFrZW4gIisKKyAgICAgICAgY3VycmVudF9ob29rKyIgYWIuIikpOworICAgICAgLy8gU2NobHVlc3NlbCBhdXN0cmFnZW47IGJlc3RlaGVuZGUgQmVzY2hyaWZ0dW5nZW4gYmxlaWJlbiBlcmhhbHRlbgorICAgICAgaGFrZW5bY3VycmVudF9ob29rLCBIT09LX09CXSA9IDA7CisgICAgfQorICB9CisgIC8vIFZvbiBhbGxlbiBuaWNodCB2b20gSGFrZW4gZ2Vub21tZW5lbiBTY2hsdWVzc2VsbiBkaWUgTmFtZW4gZXJtaXR0ZWxuCisgIC8vIHVuZCBhdWZsaXN0ZW4uCisgIGlmICggc2l6ZW9mKGtleXMpICkgeworICAgIHRlbGxfb2JqZWN0KFRQLCBCUyhjYXBpdGFsaXplKENvdW50VXAoa2V5cy0+bmFtZShXRVIsMSkpKSsiICIrCisgICAgICAoc2l6ZW9mKGtleXMpPT0xPyJrb25udGUiOiJrb25udGVuIikrIiBuaWNodCB2b20gU2NobHVlc3NlbGJyZXR0ICIKKyAgICAgICJhYmdlbm9tbWVuIHdlcmRlbi4iKSk7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKKy8vIFZlcmZ1ZWdiYXJlIEtvbW1hbmRvcyBhdWZsaXN0ZW4uCit2YXJhcmdzIGludCBza29tbWFuZG9zKHN0cmluZyBzdHIpIHsKKyAgbm90aWZ5X2ZhaWwoICJGZWhsZXI6IERpZXNlciBCZWZlaGwgYmVub2V0aWd0IGVpbmUgZ3VlbHRpZ2UgT2JqZWt0LUlkIGFscyAiCisgICAgKyJQYXJhbWV0ZXIuXG5CZWlzcGllbDogc2tvbW1hbmRvcyBbc2NobHVlc3NlbF1icmV0dFxuIik7CisgIAorICBpZiggIWlkKHN0cikgKSByZXR1cm4gMDsKKworICB3cml0ZSgKKyAgICAiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIKKyAgICAiPT09PT09PT09PVxuIgorICAgICJBa3R1ZWxsZSBWZXJzaW9uOiAiK1F1ZXJ5UHJvcCgiY250X3ZlcnNpb25fc3RkIikrCisgICAgICBRdWVyeVByb3AoImNudF92ZXJzaW9uX29iaiIpKyJcbiIrCisgICAgQlMoTmFtZShXRVIsMSkrIiBrYW5uIG51ciBpbiBkaWVzZW0gU2VoZXJoYXVzIHZlcndlbmRldCB3ZXJkZW4sICIKKyAgICAiZGEgIitRdWVyeVByb25vdW4oV0VSKSsiIHNwZXppZWxsIGRhZnVlciBnZWthdWZ0IHd1cmRlLiAiKworICAgIENBUChRdWVyeVByb25vdW4oV0VSKSkrIiB2ZXJmdWVndCB1ZWJlciBmb2xnZW5kZSBLb21tYW5kb3M6IikrCisgICAgIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iCisgICAgIi0tLS0tLS1cbiIKKyAgICAic2VybGF1YmUgW3NjaGx1ZXNzZWxdYnJldHQgW3NwaWVsZXJuYW1lfFwiaGF1c2ZyZXVuZGVcInxcInp3ZWl0aWVzXCJdXG4iCisgICAgIiAgRXJsYXVidCBQZXJzb25lbiwgIituYW1lKFdFTiwxKSsiIG1pdHp1YmVudXR6ZW4uXG4iCisgICAgIiAgc2VybGF1YmUgb2huZSBBbmdhYmUgZWluZXMgQXJndW1lbnRzIGxpc3RldCBhbGxlIFBlcnNvbmVuIG1pdCBadWdyaWZmICIKKyAgICAgICJhdWZcbiAgIituYW1lKFdFTiwxKSsiIGF1Zi5cblxuIgorICAgICJ2ZXJzY2hpZWJlIFtzY2hsdWVzc2VsXWJyZXR0IG5hY2ggW2F1c2dhbmddXG4iCisgICAgIiAgRGFtaXQga2FubnN0IER1ICIrbmFtZShXRU4sMSkrIiBpbm5lcmhhbGIgRGVpbmVzIFNlaGVyaGF1c2VzICIKKyAgICAidmVyc2NoaWViZW4uXG5cbiIKKyAgICAic3ZlcnN0ZWNrZSBbc2NobHVlc3NlbF1icmV0dFxuIgorICAgICIgIERhbWl0IG1hY2hzdCBEdSAiK25hbWUoV0VOLDEpKyIgdW5zaWNodGJhci5cbiIKKyAgICAic2hvbGUgW3NjaGx1ZXNzZWxdYnJldHQgaGVydm9yXG4iCisgICAgIiAgRGFtaXQgbWFjaHN0IER1ICIrbmFtZShXRU4sMSkrIiB3aWVkZXIgc2ljaHRiYXIuXG4iCisgICAgInplcnRydWVtbWVyIFtzY2hsdWVzc2VsXWJyZXR0XG4iCisgICAgIiAgRGFtaXQgemVyc3RvZXJzdCBEdSBkYXMgU2NobHVlc3NlbGJyZXR0LlxuIgorICAgICJzYmVzY2hyaWZ0ZSBoYWtlbiA8bnI+IG1pdCA8dGV4dD58bmljaHRzXG4iCisgICAgIiAgRWluZSBCZXNjaHJpZnR1bmcgYW4gZWluZW0gSGFrZW4gYW5icmluZ2VuIG9kZXIgbG9lc2NoZW4uXG4iCisgICAgInNsaXN0ZSBsYW5nfGt1cnpcbiIKKyAgICAiICBTY2hsdWVzc2VsYW56ZWlnZSBrb25maWd1cmllcmVuOiBhbGxlIG9kZXIgbnVyIGJlbGVndGUgYXVmbGlzdGVuLlxuIgorICAgICJoYWVuZ2UgPHNjaGx1ZXNzZWxuYW1lPiBhbiBoYWtlbiBbbnJdXG4iCisgICAgImhhZW5nZSA8c2NobHVlc3NlbG5hbWU+IGFuIFtzY2hsdWVzc2VsXWJyZXR0XG4iCisgICAgIiAgRGFtaXQgaGFlbmdzdCBEdSBlaW5lbiBTY2hsdWVzc2VsIGFuIGRhcyBCcmV0dC5cbiIKKyAgICAibmltbSBzY2hsdWVzc2VsIHZvbiBoYWtlbiA8bnI+XG4iCisgICAgIm5pbW0gPHNjaGx1ZXNzZWxuYW1lPiB2b24gW3NjaGx1ZXNzZWxdYnJldHRcbiIKKyAgICAibmltbSBzY2hsdWVzc2VsIGZ1ZXIgPGJlc2NocmlmdHVuZz4gdm9uIFtzY2hsdWVzc2VsXWJyZXR0LlxuIgorICAgICIgIERhbWl0IG5pbW1zdCBEdSBlaW5lbiBTY2hsdWVzc2VsIHZvbSBTY2hsdWVzc2VsYnJldHQuXG4iCisgICAgIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iCisgICAgIj09PT09PT09PT1cbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBlcmxhdWJuaXNfbGlzdGUoKQoreworICBpZiggUXVlcnlIYXVzYmVzaXR6ZXIoKSAhPSBRdWVyeVRQKCkgJiYgIVF1ZXJ5UHJvcCgidGVzdCIpICkKKyAgeworICAgIHRlbGxfb2JqZWN0KFRQLCBCUygiTnVyICIrUXVlcnlIYXVzYmVzaXR6ZXIoKSsiIGRhcmYgQmVyZWNodGlndW5nZW4gIgorICAgICAgK25hbWUoV0VTU0VOLDEpKyIgYWJmcmFnZW4hIikpOworICAgIHJldHVybiAxOworICB9CisgIAorICBzdHJpbmcgKnN0cnM7CisgIHN0cmluZyBzdHIgPSAKKyAgICAiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIKKyAgICAiPT09PT09PT09PVxuIjsKKyAgaWYgKCBoYXVzZXJsYXVibmlzICkgeworICAgIHN0cnMgPSBTSFZFUldBTFRFUi0+SGF1c1Byb3AoTE9XRVIoUXVlcnlIYXVzYmVzaXR6ZXIoKSksIDIpOworICAgIHN0ciArPSAiRm9sZ2VuZGUgRnJldW5kZSBEZWluZXMgSGF1c2VzIGR1ZXJmZW4gIituYW1lKFdFTiwxKSsKKyAgICAgICIgbWl0YmVudXR6ZW46XG4iOworICAgIGlmKHNpemVvZihzdHJzKSkgeworICAgICAgc3RyICs9IEJTKENvdW50VXAoc3RycykpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIHN0ciArPSBCUygiRHUgaGFzdCBrZWluZXIgUGVyc29uIFp1Z3JpZmYgYXVmIERlaW4gSGF1cyBnZXdhZWhydC4uLiIpOworICAgIH0KKyAgfQorICBlbHNlIHsKKyAgICBzdHIrPSBCUygiRGllIEZyZXVuZGUgRGVpbmVzIEhhdXNlcyBkdWVyZmVuICIrbmFtZShXRU4sMSkrCisgICAgICAiIG5pY2h0IG1pdGJlbnV0emVuLiIpOworICB9CisKKyAgc3RyICs9IAorICAgICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIgorICAgICItLS0tLS0tLS0tXG4iOworCisgIGlmKCB6d2VpdGllZXJsYXVibmlzIT0iIiApIHsKKyAgICBpZiggendlaXRpZWVybGF1Ym5pcz09Z2V0ZXVpZChUUCkgKQorICAgICAgc3RyICs9IEJTKCJBbGxlIERlaW5lIFp3ZWl0aWVzIGR1ZXJmZW4gIituYW1lKFdFTiwxKSsiIG1pdGJlbnV0emVuLiIpOworICAgIGVsc2UKKyAgICAgIHN0ciArPSBCUygiQWxsZSBad2VpdGllcyB2b24gIitDQVAoendlaXRpZWVybGF1Ym5pcykrIiBkdWVyZmVuICIKKyAgICAgICAgK25hbWUoV0VOLDEpKyIgbWl0YmVudXR6ZW4uIik7CisgICAgc3RyICs9CisgICAgICAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIKKyAgICAgICItLS0tLS0tLS0tXG4iOworICB9CisgIAorICBzdHJzPVF1ZXJ5UHJvcCgiY250X2VybGF1Ym5pcyIpOworCisgIGlmKHNpemVvZihzdHJzKSkgeworICAgIHN0ciArPSBCUygiRm9sZ2VuZGUgc29uc3RpZ2UgUGVyc29uZW4gZHVlcmZlbiAiK25hbWUoV0VOLDEpKworICAgICAgIiBtaXRiZW51dHplbjoiKTsKKyAgICBzdHIgKz0gQ291bnRVcChzdHJzKTsKKyAgfQorICBlbHNlIHsKKyAgICBzdHIgKz0gQlMoIkVzIGdpYnQga2VpbmUgc29uc3RpZ2VuIFBlcnNvbmVuLCBkaWUgIituYW1lKFdFTiwxKSsKKyAgICAgICIgbWl0YmVudXR6ZW4gZHVlcmZlbi4iKTsKKyAgfQorICBzdHIgKz0KKyAgICAiPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSIKKyAgICAiPT09PT09PT09PVxuIjsKKyAgCisgIHJldHVybiAxOworfQorCisvLyBIYWtlbiBiZXNjaHJpZnRlbi4KK3N0YXRpYyBpbnQgY21kX2Jlc2NocmlmdGVuKHN0cmluZyBzdHIpIHsKKyAgc3RyaW5nIG5mbSA9ICJTeW50YXg6IHNiZXNjaHJpZnRlIGhha2VuIDxoYWtlbm51bW1lcj4gbWl0ICIKKyAgICAiPHRleHQ+fG5pY2h0c1xuIgorICAgICJGdWVyIDx0ZXh0PiBrYW5uc3QgRHUgZWluZW4gYmVsaWViaWdlbiBUZXh0IG1pdCBiaXMgenUgMzAgWmVpY2hlbiAiCisgICAgImFuZ2ViZW4sXG4iCisgICAgIiduaWNodHMnIGxvZXNjaHQgZGllIEJlc2NocmlmdHVuZyBlaW5lcyBTY2hpbGRlcy5cbiI7CisKKyAgbm90aWZ5X2ZhaWwoIkRhcyBkYXJmc3QgRHUgbmljaHQhXG4iKTsKKyAgaWYoIWVybGF1YnQoKSkgCisgICAgcmV0dXJuIDA7CisgIAorICBzdHJpbmcgdGV4dDsKKyAgaW50IGhucjsKKyAgc3RyID0gVFAtPl91bnBhcnNlZF9hcmdzKDApOworICBub3RpZnlfZmFpbChuZm0pOworICBpZiAoICFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpICkgCisgICAgcmV0dXJuIDA7CisgIGlmICggc3NjYW5mKHN0ciwiaGFrZW4gJWQgbWl0ICVzIiwgaG5yLCB0ZXh0KSE9MiApCisgICAgcmV0dXJuIDA7CisKKyAgbm90aWZ5X2ZhaWwoIldlbGNoZW4gSGFrZW4gbW9lY2h0ZXN0IER1IGJlc2NocmlmdGVuP1xuIituZm0pOworICBpZighaG5yKSAKKyAgICByZXR1cm4gMDsKKyAgCisgIG5vdGlmeV9mYWlsKCJFcyBnaWJ0IG51ciBkaWUgSGFrZW4gMSBiaXMgMTYuXG4iKTsKKyAgaWYgKCBobnIgPCAxIHx8IGhuciA+IDE2ICkgCisgICAgcmV0dXJuIDA7CisKKyAgbm90aWZ5X2ZhaWwoIldvbWl0IG1vZWNodGVzdCBEdSBkZW4gSGFrZW4gYmVzY2hyaWZ0ZW4/XG4iK25mbSk7CisgIGlmKCAhc3RyaW5ncCh0ZXh0KSB8fCAhc2l6ZW9mKHRleHQpICkKKyAgICByZXR1cm4gMDsKKworICBub3RpZnlfZmFpbCgiRGVyIFRleHQgc29sbHRlIG5pY2h0IGxhZW5nZXIgYWxzIDMwIFplaWNoZW4gc2Vpbi5cbiIpOworICBpZihzaXplb2YodGV4dCkgPiAzMCkgCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCBsb3dlcl9jYXNlKHRleHQpID09ICJuaWNodHMiICkgeworICAgIGlmICggc3RyaW5ncChoYWtlbltobnIsSE9PS19MQUJFTF0pICkgeworICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJTb3JnZmFlbHRpZyB3aXNjaHN0IER1IGRpZSBCZXNjaHJpZnR1bmcgZGVzICIKKyAgICAgICAgIkhha2VucyAiK2hucisiIHdlZy4iKSk7CisgICAgICBoYWtlbltobnIsSE9PS19MQUJFTF09MDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICB0ZWxsX29iamVjdChUUCwgQlMoIkR1IG11c3N0IERpY2ggZ2VpcnJ0IGhhYmVuLiBIYWtlbiAiK2hucisiIGlzdCAiCisgICAgICAgICJnYXIgbmljaHQgYmVzY2hyaWZ0ZXQuIikpOworICAgIH0KKyAgfQorICBlbHNlIGlmICggbG93ZXJfY2FzZSh0ZXh0KSA9PSAic2NobHVlc3NlbCIgKSB7CisgICAgdGVsbF9vYmplY3QoVFAsIEJTKAorICAgICAgIkR1IHNvbGx0ZXN0IERpciBldHdhcyBBdXNzYWdla3JhZWZ0aWdlcmVzIGVpbmZhbGxlbiBsYXNzZW4uIikpOworICB9CisgIGVsc2UgeworICAgIHRlbGxfb2JqZWN0KFRQLCBCUygiRHUgYmVzY2hyaWZ0ZXN0IGRhcyBTY2hpbGRjaGVuIHVlYmVyIEhha2VuICIraG5yKworICAgICAgIiBtaXQgIit0ZXh0KyIuIikpOworICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCgpLCBCUygKKyAgICAgIFRQLT5OYW1lKFdFUikrIiBzY2hyZWlidCBldHdhcyBhbnMgU2NobHVlc3NlbGJyZXR0LiIpLCAoe1RQfSkpOworICAgIGhha2VuW2hucixIT09LX0xBQkVMXSA9IHRleHQ7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKKy8qKioqKiBISUxGU0ZVTktUSU9ORU4gKioqKiovCisKKy8vIEJlc2NocmVpYnVuZyBlaW5lcyBIYWtlbnMgZXJ6ZXVnZW4uIFdlbm4gPGtleW51bT4gYW5nZWdlYmVuIHdpcmQsIAorLy8gd2lyZCBudXIgZGVyIGdlc3VjaHRlIEhha2VuIGFuZ2V6ZWlndCwgZWdhbCBvYiBsZWVyIG9kZXIgbmljaHQuIAorLy8gQW5zb25zdGVuIHdlcmRlbiBkaWUgYmVsZWd0ZW4gSGFrZW4gYW5nZXplaWd0LCBhdXNzZXIgd2VubiAKKy8vIDxob29rbGlzdF9sb25nPiBnZXNldHp0IGlzdC4gRGFubiB3ZXJkZW4gYWxsZSBIYWtlbiBhdWZnZWxpc3RldC4KK3ByaXZhdGUgdmFyYXJncyBzdHJpbmcgS2V5RGVzY3JpcHRpb24oaW50IGtleW51bSkgeworICBzdHJpbmcgZGVzYz0iIjsKKyAgbWFwcGluZyBrZXlsaXN0PShbOjJdKTsKKworICAvLyBMaXN0ZSBkZXJIYWtlbiBhdWYgZGVuL2RpZSBnZXN1Y2h0ZW4gZWluc2NocmFlbmtlbi4KKyAgLy8gTnVyIGVpbiBIYWtlbiBzb2xsIGFuZ2VzY2hhdXQgd2VyZGVuLiBEaWVzIGhhdCBpbW1lciBQcmlvcml0YWV0LAorICAvLyBkLmguIGF1Y2ggYmVpIDxzbGlzdGUgYWxsZT4gd2lyZCBudXIgZWluIEhha2VuIGdlbGlzdGV0LgorICBpZiAoIGtleW51bSApIHsKKyAgICBtX2FkZChrZXlsaXN0LCBrZXludW0sIG1fZW50cnkoaGFrZW4sIGtleW51bSkuLi4pOworICB9CisgIC8vIFdlbm4gPHNsaXN0ZSBhbGxlPiBnZXNldHp0IGlzdCwgYWxsZSBhdXNnZWJlbi4KKyAgZWxzZSBpZiAoIGhvb2tsaXN0X2xvbmcgKSB7CisgICAga2V5bGlzdCA9IGhha2VuOworICB9CisgIC8vIEFuc29uc3RlciBudXIgZGllIGJlbGVndGVuLgorICBlbHNlIHsKKyAgICBrZXlsaXN0ID0gZmlsdGVyKGhha2VuLCAKKyAgICAgIGZ1bmN0aW9uIGludCAoaW50IG51bSwgPHN0cmluZ3xvYmplY3Q+KiB2YWx1ZXMpIHsKKyAgICAgICAgcmV0dXJuIG9iamVjdHAodmFsdWVzWzBdKTsKKyAgICAgIH0pOworICB9CisKKyAgLy8gVWViZXIgZGFzIE1hcHBpbmcgbWl0IGRlbiBzZWxla3RpZXJ0ZW4gSGFrZW4gbGF1ZmVuIHVuZCBBdXNnYWJlbgorICAvLyBlcnpldWdlbi4KKyAgZm9yZWFjaChpbnQgbnVtIDogMS4uMTYpIHsKKyAgICAvLyBIaWVyIHdpcmQgZGVyIGFrdHVlbGxlIFdlcnQgdWViZXJzcHJ1bmdlbiwgd2VubiBlciBuaWNodCBlbnRoYWx0ZW4gCisgICAgLy8gaXN0LCBkYSBkaWUgWnV3ZWlzdW5nIGluIDxrZXk+IHVuZCA8a2V5ZGVzYz4gYXVjaCBkYW5uIGVpbmUgMCBlcmdlYmVuCisgICAgLy8gd3VlcmRlLCB1bmQgc29taXQgS2V5cyBtaXQgbGVlcmVuIFZhbHVlcyBuaWNodCB2b24gbmljaHQgZXhpc3RpZXJlbmRlbgorICAgIC8vIEtleXMgenUgdW50ZXJzY2hlaWRlbiB3YWVyZW4uCisgICAgaWYgKCBtZW1iZXIobV9pbmRpY2VzKGtleWxpc3QpLCBudW0pID09IC0xICkKKyAgICAgIGNvbnRpbnVlOworICAgIHN0cmluZyBrZXlkZXNjID0ga2V5bGlzdFtudW0sIEhPT0tfTEFCRUxdOworICAgIG9iamVjdCBrZXkgPSBrZXlsaXN0W251bSwgSE9PS19PQl07CisgICAgZGVzYyArPSAiSGFrZW4gIiArIG51bSArIChzdHJpbmdwKGtleWRlc2MpPyIgWyIra2V5ZGVzYysiXTogIiA6ICI6ICIpOworICAgIGRlc2MgKz0gKG9iamVjdHAoa2V5KSA/IGtleS0+c2hvcnQoKSA6ICJsZWVyXG4iKTsKKyAgfQorICByZXR1cm4gZGVzYzsKK30KKworLy8gUnVlY2tnYWJld2VydDogMSwgd2VubiBlcyBzaWNoIHVtIGVpbiBTY2hsdWVzc2Vsb2JqZWt0IGhhbmRlbHQsIHNvbnN0IDAuCisvLyBTY2hsdWVzc2VsIHdlcmRlbiBhbmhhbmQgZGVyIElEICJzY2hsdWVzc2VsIiBlcmthbm50IG9kZXIgZGFyYW4sIGRhc3MKKy8vIFF1ZXJ5RG9vcktleSgpIGVpbmVuIFdlcnQgenVydWVja2dpYnQsIGQuaC4gZGFzcyBkaWVzZXMgT2JqZWt0IGVpbmUKKy8vIFN0YW5kYXJkLURvb3JtYXN0ZXItVHVlciBvZWZmbmV0LgorcHJpdmF0ZSBpbnQgSXNWYWxpZEtleShvYmplY3Qgb2IpIHsKKyAgcmV0dXJuIChvYmplY3RwKG9iKSAmJiAob2ItPmlkKCJzY2hsdWVzc2VsIikgfHwgb2ItPlF1ZXJ5RG9vcktleSgpIT0wKSk7Cit9CisKKy8vIEdpYnQgZGllIE51bW1lciBkZXMgbmFlY2hzdGVuIGZyZWllbiBIYWtlbnMgenVydWVjayBvZGVyIDAsIHdlbm4KKy8vIGtlaW5lciBmcmVpIGlzdC4gRGEgTWFwcGluZ3MgbmljaHQgc29ydGllcnQgc2luZCwgbXVzcyB2b24gMS0xNiBudW1lcmlzY2gKKy8vIGl0ZXJpZXJ0IHdlcmRlbiwgZGFtaXQgaW1tZXIgZGVyIGVyc3RlIGZyZWllIEhha2VuIGdlZnVuZGVuIHdpcmQgdW5kIG5pY2h0IAorLy8gaXJnZW5kZWluZXIuCisvLyBSdWVja2dhYmV3ZXJ0OiBIYWtlbm51bW1lciB2b24gMS0xNiBvZGVyIDAsIHdlbm4ga2VpbiBIYWtlbiBmcmVpIGlzdC4KK3ByaXZhdGUgaW50IEdldE5leHRGcmVlU2xvdCgpIHsKKyAgaW50IHNsb3Q7CisgIGZvcmVhY2goaW50IGkgOiAxLi4xNikgeworICAgIGlmICggIW9iamVjdHAoaGFrZW5baSxIT09LX09CXSkgKSB7CisgICAgICBzbG90ID0gaTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgfQorICByZXR1cm4gc2xvdDsKK30KKworLy8gR2lidCB6dSBlaW5lciBTY2hpbGQtQmVzY2hyaWZ0dW5nIGRpZSB6dWdlaG9lcmlnZSBIYWtlbnBvc2l0aW9uIGF1cy4KKy8vIEVzIHdpcmQgZGllIGtsZWluZ2VzY2hyaWViZW5lIFZhcmlhbnRlIGdlc3VjaHQsIHNvIGRhc3MgU3BpZWxlciB6d2FyCisvLyBHcm9zc3NjaHJlaWJ1bmcgaW4gZGVuIEJlc2NocmlmdHVuZ2VuIHZlcndlbmRlbiBrb2VubmVuLCBkaWVzZSBhYmVyCisvLyBuaWNodCBiZXJ1ZWNrc2ljaHRpZ3Qgd2lyZC4gQW5zb25zdGVuIGtvZW5udGUgZXMgenUgU2Nod2llcmlna2VpdGVuIG1pdAorLy8gRG9wcGx1bmdlbiB3aWUgIlZlc3JheSIgdW5kICJ2ZXNyYXkiIGtvbW1lbi4KKy8vIFJ1ZWNrZ2FiZXdlcnQ6IEhha2VubnVtbWVyIHZvbiAxLTE2IG9kZXIgMCwgd2VubiBkZXIgVGV4dCBuaWNodCBnZWZ1bmRlbgorLy8gd3VyZGUuCitwcml2YXRlIG9iamVjdCBHZXRLZXlGb3JMYWJlbChzdHJpbmcgbGFiZWwpIHsKKyAgaWYgKCBsYWJlbCApIAorICAgIGxhYmVsID0gbG93ZXJfY2FzZShsYWJlbCk7CisgIGZvcmVhY2goaW50IGk6IDEuLjE2KSB7CisgICAgaWYgKCBoYWtlbltpLCBIT09LX0xBQkVMXSAmJiBsYWJlbCAmJgorICAgICAgICAgbG93ZXJfY2FzZShoYWtlbltpLEhPT0tfTEFCRUxdKSA9PSBsYWJlbCApCisgICAgICByZXR1cm4gaGFrZW5baSxIT09LX09CXTsKKyAgfQorICByZXR1cm4gMDsKK30KKworLy8gR2lidCB6dSBkZW0gdWViZXJnZWJlbmVuIE9iamVrdCBkaWUgTnVtbWVyIGRlcyBIYWtlbnMgenVydWVjaywgYW4gZGVtCisvLyBlcyBoYWVuZ3QuCitwcml2YXRlIGludCBHZXRIb29rTnVtYmVyRm9yS2V5KG9iamVjdCBvYikgeworICBmb3JlYWNoKGludCBudW0sIG9iamVjdCBrZXkgOiBoYWtlbikgeworICAgIGlmICgga2V5ID09IG9iICkKKyAgICAgIHJldHVybiBudW07CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKy8vIEJlcmVpbmlndCBEYXRlbnN0cnVrdHVyIGluIDxoYWtlbj4gdW5kIGRhcyBJbnZlbnRhciBkZXMgQnJldHRlcywgaW5kZW0KKy8vIGEpIGdlcHJ1ZWZ0IHdpcmQsIG9iIGFsbGUgaW4gPGhha2VuPiBlaW5nZXRyYWdlbmVuIE9iamVrdGUgc2ljaCBhdWNoIGltIAorLy8gICAgQnJldHQgYmVmaW5kZW4gdW5kCisvLyBiKSBnZXBydWVmdCB3aXJkLCBvYiBhbGxlIGltIEludmVudGFyIGJlZmluZGxpY2hlbiBPYmpla3RlIGF1Y2gga29ycmVrdCBpbiAKKy8vICAgIDxoYWtlbj4gZWluZ2V0cmFnZW4gc2luZC4KKy8vIFVlYmVyemFlaGxpZ2UgT2JqZWt0ZSB3ZXJkZW4gcmF1c2dld29yZmVuLgorcHJpdmF0ZSB2b2lkIENvbnNvbGlkYXRlSW52ZW50b3J5KCkgeworICBmb3JlYWNoKGludCBpLCBvYmplY3Qgb2IgOiBoYWtlbikgeworICAgIC8vIE9iamVrdCBleGlzdGllcnQsIGlzdCBhYmVyIG5pY2h0IGltIFNjaGx1ZXNzZWxicmV0dD8gRGFubiBhdXN0cmFnZW4uCisgICAgaWYgKG9iamVjdHAob2IpICYmIGVudmlyb25tZW50KG9iKSAhPSBNRSkgeworICAgICAgbV9kZWxldGUoaGFrZW4sIGkpOworICAgICAgLy8gV2lyZCBhdWNoIHZvbSByZXNldCgpIGF1cyBnZXJ1ZmVuLCBkYW5uIGlzdCBUUCA9PSAwLgorICAgICAgaWYgKCBvYmplY3RwKFRQKSApCisgICAgICAgIHRlbGxfb2JqZWN0KFRQLCBCUygiSG9wcGxhISAiK29iLT5OYW1lKFdFUiwxKSsiIHNjaGVpbnQgdm9tICIKKyAgICAgICAgICAiU2NobHVlc3NlbGJyZXR0IHZlcnNjaHd1bmRlbiB6dSBzZWluISIpKTsKKyAgICB9CisgIH0KKyAgb2JqZWN0ICpyZXN0ZXJhbXBlID0gYWxsX2ludmVudG9yeShNRSkgLSBtX3ZhbHVlcyhoYWtlbiwgSE9PS19PQik7CisgIGlmIChzaXplb2YocmVzdGVyYW1wZSkpIHsKKyAgICByZXN0ZXJhbXBlLT5tb3ZlKGVudmlyb25tZW50KCksTV9QVVQpOworICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCgpLCBCUygiUGxvZXR6bGljaCBmYWVsbHQgZXR3YXMgdm9tICIKKyAgICAgICJTY2hsdWVzc2VsYnJldHQgenUgQm9kZW4sIGRhcyBEdSB6dXZvciBnYXIgbmljaHQgZ2VzZWhlbiBoYXR0ZXN0LiIpKTsKKyAgfQorfQorCitzdHJpbmcgc2hvcnQoKSB7CisgIHN0cmluZyBzaD1RdWVyeVByb3AoUF9TSE9SVCk7CisKKyAgLy8gVW5zaWNodGJhcj8gRGFubiBnaWJ0cyBuaWNodHMgenUgc2VoZW4gLi4uCisgIGlmICggUXVlcnlQcm9wKFBfSU5WSVMpIHx8ICFzaCApCisgICAgcmV0dXJuIDA7CisgIGlmICggUXVlcnlQcm9wKCJ2ZXJzdGVja3QiKSA9PSAxICkgCisgICAgc2ggPSAiIjsKKyAgZWxzZSAKKyAgICBzaCArPSAiLiI7CisKKyAgcmV0dXJuIHByb2Nlc3Nfc3RyaW5nKHNoKSsiXG4iOworfQorCisvLyBJbSBSZXNldCB2b3JzaWNodHNoYWxiZXIgYXVjaCBtYWwgYXVmcmFldW1lbi4KK3ZvaWQgcmVzZXQoKSB7CisgIENvbnNvbGlkYXRlSW52ZW50b3J5KCk7CisgIHJldHVybiA6OnJlc2V0KCk7Cit9CisKK3ZhcmFyZ3MgaW50IFByZXZlbnRJbnNlcnQob2JqZWN0IG9iKSB7CisgIC8vIEtlaW4gU2NobHVlc3NlbD8gSGF0IGluIGRpZXNlbSBDb250YWluZXIgbml4IHZlcmxvcmVuIQorICBpZiggIUlzVmFsaWRLZXkob2IgKSkgeworICAgIHJldHVybiAxOworICB9CisgIENvbnNvbGlkYXRlSW52ZW50b3J5KCk7CisgIHJldHVybiA6OlByZXZlbnRJbnNlcnQob2IpOworfQorCisvLyBXZW5uIGVpbiBTY2hsdWVzc2VsIHNpY2ggYXVmbG9lc3QsIG11c3MgZGllIExpc3RlIGFiZ2VnbGljaGVuIHdlcmRlbi4KK3ZvaWQgTm90aWZ5UmVtb3ZlKG9iamVjdCBvYikgeworICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoTUUpLCBCUygiSG9wcGxhISAiK29iLT5OYW1lKFdFUiwxKSsiIGhhdCBzaWNoICIKKyAgICAiZ2VyYWRlIGluIFdvaGxnZWZhbGxlbiBhdWZnZWxvZXN0LiIpKTsKKyAgLy8gRGFzIE9iamVrdCA8b2I+IHplcnN0b2VydCBzaWNoIGVyc3QgbmFjaCBkZW0gQXVmcnVmIGRpZXNlciBGdW5rdGlvbiwKKyAgLy8gZGFoZXIgcGVyIGNhbGxfb3V0KCkgYXVmcmFldW1lbi4KKyAgY2FsbF9vdXQoIydDb25zb2xpZGF0ZUludmVudG9yeSwgMSk7Cit9CisKKy8vIFplc3N0cmEsIDEuNy4wNywgZnVlcnMgSG9lcnJvaHIKKy8vIERhcmYgaWNoIGRhIEFyYXRob3JuIGVpbnRyYWdlbj8gOy0pCitzdHJpbmcgR2V0T3duZXIoKSB7CisgIHJldHVybiAic2VsZXZlbiI7Cit9CisK