ZGlmZiAtLWdpdCBhL3NlY3VyZS9tYXRlcmlhbGRiLmMgYi9zZWN1cmUvbWF0ZXJpYWxkYi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdmNzFiYzQKLS0tIC9kZXYvbnVsbAorKysgYi9zZWN1cmUvbWF0ZXJpYWxkYi5jCkBAIC0wLDAgKzEsOTM2IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gLSBQcm90b3R5cGVuIHVuZCBQcm9wZXJ0aWVzIGluIHRoaW5nL21hdGVyaWFsLmgKKy8vIC0gTGlzdGUgaW4gbWF0ZXJpYWxzLmgKKy8vCisvLyBUT0RPOiBwcm9wZXJ0aWVzLmggdW0gbWF0ZXJpYWxzLmggZXJ3ZWl0ZXJuCisvLworLy8gLSBpbXBsaXppdGUgR3J1cHBlbnp1b3JkbnVuZyBlbnRmZXJuZW4sIGRhIGpldHp0IGV4cGxpeml0IGluCisvLyAgIERlZmluaXRpb25zZGF0ZWllbiB2b3JoYW5kZW4KKy8vIC0gTWF0ZXJpYWxkb2t1IHVlYmVyYXJiZWl0ZW4sIGRhYmVpIEhpbndlaXMgYXVmIG5pY2h0IG1laHIgaW1wbGl6aXRlCisvLyAgIEdydXBwZW56dW9yZG51bmcKKy8vIC9wL2RhZW1vbi9tYXRlcmlhbGRiLmMgLS0gTWF0ZXJpYWxkYXRlbmJhbmsKKy8vCisvLyAkSWQ6IG1hdGVyaWFsZGIuYyA4NzU1IDIwMTQtMDQtMjYgMTM6MTM6NDBaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBub19pbmhlcml0CisjcHJhZ21hIG5vX3NoYWRvdworI3ByYWdtYSBwZWRhbnRpYworCisvLyBEaWUgUHJvcGVydHlkZWZpbml0aW9uIHJlaW5ob2xlbgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKy8vIE1hdGVyaWFsbGlzdGUgbmljaHQgbWl0IHJlaW56aWVoZW4KKyNkZWZpbmUgX1NLSVBfTUFURVJJQUxTXworI2luY2x1ZGUgPHRoaW5nL21hdGVyaWFsLmg+CisjaW5jbHVkZSA8cGxheWVyL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8cnRsaW1pdHMuaD4KKworLy8gQmFzaXN2ZXJ6ZWljaG5pcyBkZXIgTWF0ZXJpYWxpZW4KKyNkZWZpbmUgTUFUX0RJUiAiL2RvYy9tYXRlcmlhbHMiCisKKy8vIEF1c2dhYmV2ZXJ6ZWljaG5pcyBmdWVyIERva3UKKyNkZWZpbmUgRE9DX0RJUih4KSAoIi9kb2MvbWF0ZXJpYWxzLyIreCkKKworLy8gRGF0ZWluYW1lIGRlcyBIZWFkZXJzIG1pdCBNYXRlcmlhbGRlZmluaXRpb25lbgorI2RlZmluZSBIRUFERVJGSUxFICIvc3lzL21hdGVyaWFscy5oIgorCisvLyBTYXZlZmlsZS4KKyNkZWZpbmUgU0FWRUZJTEUgRE9DX0RJUigibWF0ZXJpYWxkYiIpCisKKy8vIFJlaW4gaW50ZXJuIHZlcndlbmRldGUgTmFtZW4KKyNkZWZpbmUgUF9SRUNPQyAicmVjb2duaXphYmlsaXR5IgorI2RlZmluZSBQX0lEICAgICJpZCIKKyNkZWZpbmUgUF9ERUZTVFIgImRlZnN0ciIKKyNkZWZpbmUgUF9NRU1CRVJTICJtZW1iZXJzIgorI2RlZmluZSBQX01HX0ZSQUNUSU9OUyAibWdfZnJhY3Rpb25zIgorCisjZGVmaW5lIExPR19FUlJPUih4KSBpZihmaW5kX3BsYXllcigicmFzY2hhdWEiKSYmZmluZF9wbGF5ZXIoInJhc2NoYXVhIiktPlF1ZXJ5UHJvcCgibWRiLWRlYnVnIikpdGVsbF9vYmplY3QoZmluZF9wbGF5ZXIoInJhc2NoYXVhIiksIk1EQi1FcnJvcjoiK3gpCisjZGVmaW5lIExPR19XQVJOKHgpIGlmKGZpbmRfcGxheWVyKCJyYXNjaGF1YSIpJiZmaW5kX3BsYXllcigicmFzY2hhdWEiKS0+UXVlcnlQcm9wKCJtZGItZGVidWciKSl0ZWxsX29iamVjdChmaW5kX3BsYXllcigicmFzY2hhdWEiKSwiTURCLVdhcm46Iit4KQorCisvLyBQcm90b3R5cGVzOgorLy8gKExpZWZlcnQgZGVuIEFudGVpbCBkZXIgTWF0ZXJpYWxncnVwcGUgZ3JwIGFuIG1hdHMpCitpbnQgTWF0ZXJpYWxHcm91cChtYXBwaW5nIG1hdHMsIHN0cmluZyBncnApOworLy8gS29udmVydGllcnQgZWluZSBMaXN0ZSB2b24gTWF0ZXJpYWxpZW4genUgaWhyZW4gTmFtZW4sIGRhYmVpIHdpcmQgZGllCisvLyBFcmtlbm51bmdzZmFlaGlna2VpdCBiZXJ1ZWNrc2ljaHRpZ3QgdW5kIGV2dGwuIGZhbHNjaCBlcmthbm50Cit2YXJhcmdzIHN0cmluZyBDb252TWF0ZXJpYWxMaXN0KG1peGVkIG1hdHMsIGludCBjYXN1cywgbWl4ZWQgaWRpbmYpOwordmFyYXJncyBzdHJpbmcgTWF0ZXJpYWxOYW1lKHN0cmluZyBtYXQsIGludCBjYXN1cywgbWl4ZWQgaWRpbmYpOworLy8gR2lidCBkZW4gTmFtZW4gZWluZXIgTWF0ZXJpYWxncnVwcGUgenVydWVjaworc3RyaW5nIEdyb3VwTmFtZShzdHJpbmcgZ3JwKTsKKy8vIEdpYnQgYWxsZSBNYXRlcmlhbGllbiB6dXJ1ZWNrCitzdHJpbmcgKkFsbE1hdGVyaWFscygpOworLy8gR2lidCBhbGxlIEdydXBwZW4genVydWVjaworc3RyaW5nICpBbGxHcm91cHMoKTsKKy8vIEdpYnQgYWxsZSBHcnVwcGVuIHp1cnVlY2ssIGluIGRlbmVuIG1hdCBlbnRoYWx0ZW4gaXN0CitzdHJpbmcgKkdldE1hdE1lbWJlcnNoaXAoc3RyaW5nIG1hdCk7CisvLyBHaWJ0IGFsbGUgTWF0ZXJpYWxpZW4genVydWVjaywgZGllIGluIGdycCBlbnRoYWx0ZW4gc2luZAorc3RyaW5nICpHZXRHcm91cE1lbWJlcnMoc3RyaW5nIGdycCk7CisvLyBFcm5ldWVydCBkaWUgTWF0ZXJpYWxpZW4gZHVyY2ggU2Nhbm5lbiBkZXMgTWF0ZXJpYWx2ZXJ6ZWljaG5pc3Nlcwordm9pZCBVcGRhdGUoKTsKKy8vIGdlbmVyaWVydCBIZWFkZXJmaWxlIGF1cyBkZW4gRGF0ZW4KK3ZhcmFyZ3Mgdm9pZCBHZW5IZWFkZXJGaWxlKHN0cmluZyBmbik7CisKK21hcHBpbmcgbWF0ZXJpYWxzOworbWFwcGluZyBtYXRlcmlhbF9ncm91cHM7Citwcml2YXRlIHN0YXR1cyBpbml0aWFsaXplZDsKK21hcHBpbmcgb2xkX21hdF9rZXlzOyAgICAgLy8gQWx0ZXIgTWF0ZXJpYWxrZXkgLT4gbmV1ZXIgS2V5IChLb21wYXRpYmlsaXRhZXQpCitub3NhdmUgbWFwcGluZyBuZXdfbWF0ZXJpYWxzOyAgICAgICAvLyBNYXRlcmlhbGllbiB3YWVocmVuZCBkZXMgU2Nhbm5lbnMKK25vc2F2ZSBtYXBwaW5nIG5ld19tYXRlcmlhbF9ncm91cHM7IC8vIE1hdGVyaWFsZ3J1cHBlbiB3YWVocmVuZCBkZXMgU2Nhbm5lbnMKK3ByaXZhdGUgbm9zYXZlIHN0YXR1cyBpc1NjYW5uaW5nOworcHJpdmF0ZSBub3NhdmUgaW50IHVwZGF0ZVRpY2tzOworCit2b2lkIGNyZWF0ZSgpIHsKKyAgc2V0ZXVpZChnZXR1aWQoKSk7CisgIC8vIFNhdmVmaWxlIGVpbmxlc2VuLCBmYWxscyBtb2VnbGljaCwgZGFtaXQgZGllIERCIGRpcmVrdCBpbml0aWFsaXNlcnQgaXN0LAorICAvLyB3ZW5uIGF1Y2ggZ2dmLiBtaXQgYWx0ZW4gRGF0ZW4uCisgIHJlc3RvcmVfb2JqZWN0KFNBVkVGSUxFKTsKKyAgaWYgKGluaXRpYWxpemVkKSB7CisgICAgLy8gZmFsbHMgZXJmb2xncmVpY2gsIGRpcmVrdCBIZWFkZXIgZnVlciBkaWUgTXVkbGliIHNjaHJlaWJlbgorICAgIEdlbkhlYWRlckZpbGUoKTsKKyAgfQorICAvLyBqZXR6dCBVcGRhdGUgZGVyIERhdGVuIGR1cmNoZnVlaHJlbi4KKyAgVXBkYXRlKCk7Cit9CisKKy8vPT09PT09PT09PT09PT09PT09PT0gVW13YW5kZWxuIGRlciBTdHJpbmdzIGF1cyBkZXIgdGhpbmcvbWF0ZXJpYWwuaAorcHJpdmF0ZSBzdHJpbmcgZ2V0TWF0SWQoc3RyaW5nIGtleSkgeworICAvLyBBbHRlIEJlemVpY2huZXIgdW13YW5kZWxuCisgIGlmICghbWVtYmVyKG1hdGVyaWFscywga2V5KSkKKyAgICBrZXkgPSBvbGRfbWF0X2tleXNba2V5XTsKKyAgcmV0dXJuIGtleTsKK30KK3ByaXZhdGUgc3RyaW5nIGdldE1hdEdyb3VwSWQoc3RyaW5nIGtleSkgeworICAvLyBBbHRlIEJlemVpY2huZXIgdW13YW5kZWxuCisgIGlmICghbWVtYmVyKG1hdGVyaWFsX2dyb3Vwcywga2V5KSkKKyAgICBrZXkgPSAiTUFUR1JPVVBfIit1cHBlcnN0cmluZyhrZXlbMy4uXSk7CisgIHJldHVybiBrZXk7Cit9Citwcml2YXRlIHN0cmluZyBtYXRLZXkyRGVmc3RyKHN0cmluZyBrZXksIG1hcHBpbmcgbWF0cykgeworICBzdHJpbmcgaWQ7CisgIGlmIChtZW1iZXIobWF0c1trZXldLCBQX0RFRlNUUikpCisgICAgaWQgPSBtYXRzW2tleV1bUF9ERUZTVFJdOworICBlbHNlCisgICAgaWQgPSBrZXk7CisgIHJldHVybiBpZDsKK30KK3ByaXZhdGUgc3RyaW5nIGdyb3VwS2V5MkRlZnN0cihzdHJpbmcga2V5KSB7CisgIGlmIChzaXplb2Yoa2V5KSA+IDkpCisgICAga2V5ID0gIm1nXyIrbG93ZXJzdHJpbmcoa2V5WzkuLl0pOworICBlbHNlCisgICAga2V5ID0gIiI7CisgIHJldHVybiBrZXk7Cit9CisKKy8vPT09PT09PT09PT09PT09PT09PT0gU2Nobml0dHN0ZWxsZW5mdW5rdGlvbmVuIHp1ciBWZXJ3ZW5kdW5nIGRlciBEQgordmFyYXJncyBzdHJpbmcgTWF0ZXJpYWxOYW1lKHN0cmluZyBtYXQsIGludCBjYXN1cywgbWl4ZWQgaWRpbmYpIHsKKyAgaWYgKGluaXRpYWxpemVkKSB7CisgICAgc3RyaW5nICpuYW1lczsKKyAgICBtYXBwaW5nIHByb3BzOworICAgIG1peGVkICpkaWY7CisgICAgLy8gQW5wYXNzZW4gZGVyIE1hdGVyaWFsaWQKKyAgICBtYXQgPSBnZXRNYXRJZChtYXQpOworCisgICAgaWYgKCFtYXBwaW5ncChwcm9wcz1tYXRlcmlhbHNbbWF0XSkpCisgICAgICBwcm9wcz0oW10pOworCisgICAgLy8gSmUgbmFjaCBLb2VubmVuIGRlcyBTcGllbGVycyBrYW5uIG1hbiBkYXMgZXhha3RlIE1hdGVyaWFsCisgICAgLy8gbWVociBvZGVyIHdlbmlnZXIgZ3V0IGVya2VubmVuOgorICAgIGlmIChwb2ludGVycChkaWY9cHJvcHNbUF9SRUNPQ10pCismJiAoIWludHAoaWRpbmYpfHxpZGluZjwxMDApICkgeyAvLyAxMDA9ZXhha3RlIEVya2VubnVuZworICAgICAgaW50IGksIG4sIHJlY3ZhbDsKKyAgICAgIG1peGVkICpncnBzLCB0bXAsIHg7CisKKyAgICAgIHJlY3ZhbD0wOworICAgICAgZ3Jwcz1wcm9wc1tQX01HX0ZSQUNUSU9OU107CisgICAgICBpZiAoIXBvaW50ZXJwKGlkaW5mKSkKKyAgICAgICAgaWRpbmY9KHtpZGluZn0pOworCisgICAgICAvLyBadW5hZWNoc3QgZGllIEZhZWhpZ2tlaXQgZGVzIFNwaWVsZXJzIChkYSBrb2VubmVuIG5vY2gKKyAgICAgIC8vIEdpbGRlbmZhZWhpZ2tlaXRlbiBoaW56dSBrb21tZW4pIGVybWl0dGVsbiwgZGllc2VzCisgICAgICAvLyBNYXRlcmlhbCB6dSBlcmtlbm5lbjoKKyAgICAgIGk9c2l6ZW9mKGlkaW5mKTsKKyAgICAgIHdoaWxlKGktLSkgeworICAgICAgICB0bXA9aWRpbmZbaV07CisgICAgICAgIGlmIChvYmplY3RwKHRtcCkpIC8vIERpZXNlIFByb3BlcnR5IGlzdCBoYXVwdHNhZWNobGljaCBmdWVyIFJhc3NlbjoKKyAgICAgICAgICB0bXA9dG1wLT5RdWVyeVByb3AoUF9NQVRFUklBTF9LTk9XTEVER0UpOworICAgICAgICBpZiAoaW50cCh0bXApKSB7CisgICAgICAgICAgcmVjdmFsKz10bXA7IC8vIEFsbGdlbWVpbmUgRXJrZW5udW5nc2ZhZWhpZ2tlaXQKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2xvc3VyZXAodG1wKSAmJiBpbnRwKHg9ZnVuY2FsbCh0bXAsbWF0LGdycHMpKSkgeworICAgICAgICAgIHJlY3ZhbCs9eDsKKyAgICAgICAgICBicmVhazsgLy8gQ2xvc3VyZXMga29lbm5lbiBpbW1lciBudWV0emxpY2ggc2VpbiA6KQorICAgICAgICB9CisgICAgICAgIGlmIChtYXBwaW5ncCh0bXApKSB7CisgICAgICAgICAgaW50IGo7CisgICAgICAgICAgaWYgKCh4PXRtcFttYXRdKSAmJiBpbnRwKHgpKXsKKyAgICAgICAgICAgIC8vIEVya2VubnVuZyB2b24gc3BlemllbGwgZGllc2VtIE1hdGVyaWFsCisgICAgICAgICAgICByZWN2YWwrPXg7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICB9CisgICAgICAgICAgLy8gRXJrZW5udW5nIHZvbiBHcnVwcGVuCisgICAgICAgICAgaj1zaXplb2YoZ3Jwcyk7CisgICAgICAgICAgd2hpbGUoai0tKQorICAgICAgICAgICAgaWYoKHg9dG1wW2dycHNbal1dKSAmJiBpbnRwKHgpKQorICAgICAgICAgICAgICByZWN2YWwrPXg7CisgICAgICAgICAgaWYgKHBvaW50ZXJwKHRtcD10bXBbTUFURVJJQUxfU1lNTUVUUklDX1JFQ09HTklaQUJJTElUWV0pKSB7CisgICAgICAgICAgICBmb3IgKGo9c2l6ZW9mKHRtcCktMjtqPj0wO2otPTIpIHsKKyAgICAgICAgICAgICAgaWYgKCFpbnRwKHg9dG1wW2orMV0pKQorICAgICAgICAgICAgICAgIHJhaXNlX2Vycm9yKCJtYXRlcmlhbGRiOiBpbGxlZ2FsIHN5bS5yZWNvYy4gZm9ybWF0XG4iKTsKKyAgICAgICAgICAgICAgaWYgKHByb3BzW3RtcFtqXV0pCisgICAgICAgICAgICAgICAgcmVjdmFsKz14OworICAgICAgICAgICAgICBlbHNlIC8vIGJlaSBwYXNzZW5kZW4gR3J1cHBlbiArLCBiZWkgYW5kZXJlbiAtCisgICAgICAgICAgICAgICAgcmVjdmFsLT14OworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorCisgICAgICAvLyBKZXR6dCB3aXJkIGVybWl0dGVsdCwgb2IgdmllbGxlaWNodCBlaW5lIHVuZ2VuYXVlcmUKKyAgICAgIC8vIEJlc2NocmVpYnVuZyBnZWdlYmVuIHdlcmRlbiBzb2xsOgorICAgICAgeD1kaWZbMF07CisgICAgICBuID0gc2l6ZW9mKGRpZiktMTsKKyAgICAgIGZvciAoaT0yO2k8PW47aSs9MikgeworICAgICAgICBpZiAocmVjdmFsPj1kaWZbaS0xXSkKKyAgICAgICAgICB4PWRpZltpXTsKKyAgICAgIH0KKyAgICAgIC8vIFdlbm4gZGllIEZhZWhpZ2tlaXRlbiBkZXMgU3BpZWxlcnMgbmljaHQgZnVlciBkZW4gZWNodGVuIEtsYXJuYW1lbgorICAgICAgLy8gYXVzcmVpY2hlbiwgZ2liIGRpZSBBbHRlcm5hdGl2ZSB6dXJ1ZWNrOgorICAgICAgaWYgKHghPW1hdCkKKyAgICAgICAgcmV0dXJuIE1hdGVyaWFsTmFtZSh4LCBjYXN1cywgMTAwKTsKKyAgICB9CisKKyAgICBpZiAoIXBvaW50ZXJwKG5hbWVzPXByb3BzW1BfTkFNRV0pIHx8IHNpemVvZihuYW1lcyk8NCkKKyAgICAgIG5hbWVzPSh7InVuYmVrYW5udGVzIE1hdGVyaWFsIiwgInVuYmVrYW5udGVuIE1hdGVyaWFscyIsCisgICAgICAgICAgICAgICJ1bmJla2FubnRlbSBNYXRlcmlhbCIsICJ1bmJla2FubnRlbiBNYXRlcmlhbCJ9KTsKKyAgICBpZiAoY2FzdXM8MCB8fCBjYXN1cz4zKQorICAgICAgY2FzdXM9MDsKKyAgICByZXR1cm4gbmFtZXNbY2FzdXNdOworICB9Cit9CisKK3ZhcmFyZ3Mgc3RyaW5nIENvbnZNYXRlcmlhbExpc3QobWl4ZWQgbWF0cywgaW50IGNhc3VzLCBtaXhlZCBpZGluZikgeworICBpZiAoaW5pdGlhbGl6ZWQpIHsKKyAgICBzdHJpbmcgKm1zLG1sOworICAgIGludCBpOworCisgICAgbWw9IiI7CisgICAgaWYgKG1hcHBpbmdwKG1hdHMpKQorICAgICAgbXM9bV9pbmRpY2VzKG1hdHMpOworICAgIGVsc2UgaWYgKHN0cmluZ3AobWF0cykpCisgICAgICBtcz0oe21hdHN9KTsKKyAgICBlbHNlIGlmIChwb2ludGVycChtYXRzKSkKKyAgICAgIG1zPW1hdHM7CisgICAgZWxzZQorICAgICAgbXM9KHt9KTsKKyAgICBpPXNpemVvZihtcyk7CisgICAgd2hpbGUoaSkgeworICAgICAgbWwrPU1hdGVyaWFsTmFtZShtc1stLWldLGNhc3VzLGlkaW5mKTsKKyAgICAgIGlmIChpKQorICAgICAgICBtbCs9KChpPjEpPyIsICI6IiB1bmQgIik7CisgICAgfQorICAgIHJldHVybiBtbDsKKyAgfQorfQorCitpbnQgTWF0ZXJpYWxHcm91cChtYXBwaW5nIG1hdHMsIHN0cmluZyBncnApIHsKKyAgIGlmIChpbml0aWFsaXplZCkgeworICAgICBzdHJpbmcgKm1zOworICAgICBpbnQgaSxyZXM7CisKKyAgICAgcmVzPTA7CisgICAgIGlmICghbWFwcGluZ3AobWF0cykgfHwgIXN0cmluZ3AoZ3JwKSkKKyAgICAgICByZXR1cm4gcmVzOworICAgICBtcz1tX2luZGljZXMobWF0cyk7CisgICAgIGk9c2l6ZW9mKG1zKTsKKyAgICAgd2hpbGUoaS0tKSB7CisgICAgICAgc3RyaW5nIG1hdDsKKyAgICAgICBtYXBwaW5nIHByb3BzOworICAgICAgIG1hdD1tc1tpXTsKKyAgICAgICBpZiAobWFwcGluZ3AocHJvcHM9bWF0ZXJpYWxzW2dldE1hdElkKG1hdCldKSkKKyAgICAgICAgIHJlcys9KG1hdHNbbWF0XSpwcm9wc1tQX01HX0ZSQUNUSU9OU11bZ2V0TWF0R3JvdXBJZChncnApXSkvMTAwOworICAgICB9CisgICAgIGlmIChyZXM8LTEwMCkgLy8gVmllbGxlaWNodCBub2NoIEFudGltYXRlcmllIHp1bGFzc2VuCisgICAgICAgcmVzPS0xMDA7ICAgLy8gKG5vY2ggbmljaHQgc2ljaGVyIG9iIGRhcyBzbyBibGVpYmVuIHdpcmQgb2RlciAwIHNlaW4gd2lyZCkKKyAgICAgaWYgKHJlcz4xMDApCisgICAgICAgcmVzPTEwMDsKKyAgICAgcmV0dXJuIHJlczsKKyAgIH0KK30KKworc3RyaW5nICpBbGxNYXRlcmlhbHMoKSB7CisgIGlmIChpbml0aWFsaXplZCkgeworICAgIC8vIEF1cyBLb21wYXRpYmlsaXRhZXRzZ3J1ZW5kZW4gZGllIGFsdGVuIFNjaGx1ZXNzZWwgKCNkZWZpbmUtU3RyaW5nKQorICAgIC8vIHp1cnVlY2tnZWJlbgorICAgIHJldHVybiBtX2luZGljZXMob2xkX21hdF9rZXlzKTsKKyAgfQorICByZXR1cm4gMDsKK30KKworc3RyaW5nICpBbGxHcm91cHMoKSB7CisgIGlmIChpbml0aWFsaXplZCkgeworICAgIC8vIEF1cyBLb21wYXRpYmlsaXRhZXRzZ3J1ZW5kZW4gZGllIGFsdGVuIFNjaGx1ZXNzZWwgKCNkZWZpbmUtU3RyaW5nKQorICAgIC8vIHp1cnVlY2tnZWJlbgorICAgIHJldHVybiBtYXAobV9pbmRpY2VzKG1hdGVyaWFsX2dyb3VwcyksICMnZ3JvdXBLZXkyRGVmc3RyKTsKKyAgfQorICByZXR1cm4gMDsKK30KKworc3RyaW5nICpHZXRNYXRNZW1iZXJzaGlwKHN0cmluZyBtYXQpIHsKKyAgaWYgKGluaXRpYWxpemVkKSB7CisgICAgbWFwcGluZyBwcm9wczsKKyAgICAvLyBBbnBhc3NlbiBkZXIgTWF0ZXJpYWxpZAorICAgIG1hdCA9IGdldE1hdElkKG1hdCk7CisKKyAgICBpZiAoIW1hcHBpbmdwKHByb3BzPW1hdGVyaWFsc1ttYXRdKSkKKyAgICAgIHJldHVybiAoe30pOworICAgIHJldHVybiBtYXAobV9pbmRpY2VzKHByb3BzW1BfTUdfRlJBQ1RJT05TXSksICMnZ3JvdXBLZXkyRGVmc3RyKTsKKyAgfQorICByZXR1cm4gMDsKK30KKworc3RyaW5nICpHZXRHcm91cE1lbWJlcnMoc3RyaW5nIGdycCkgeworICBpZiAoaW5pdGlhbGl6ZWQpIHsKKyAgICBzdHJpbmcgKm1hdHM7CisgICAgLy8gQW5wYXNzZW4gZGVyIE1hdGVyaWFsaWQKKyAgICBncnAgPSBnZXRNYXRHcm91cElkKGdycCk7CisgICAgaWYgKCFtZW1iZXIobWF0ZXJpYWxfZ3JvdXBzLCBncnApIHx8CisJIXBvaW50ZXJwKG1hdHM9bWF0ZXJpYWxfZ3JvdXBzW2dycF1bUF9NRU1CRVJTXSkpCisgICAgICByZXR1cm4gKHt9KTsKKyAgICByZXR1cm4gbWFwKG1hdHMsICMnbWF0S2V5MkRlZnN0ciwgbWF0ZXJpYWxzKTsKKyAgfQorICByZXR1cm4gMDsKK30KKworc3RyaW5nIEdyb3VwTmFtZShzdHJpbmcgZ3JwKSB7CisgIGlmIChpbml0aWFsaXplZCkgeworICAgIGlmIChtZW1iZXIobWF0ZXJpYWxfZ3JvdXBzLCBnZXRNYXRHcm91cElkKGdycCkpKQorICAgICAgcmV0dXJuIG1hdGVyaWFsX2dyb3Vwc1tnZXRNYXRHcm91cElkKGdycCldW1BfTkFNRV07CisgICAgZWxzZQorICAgICAgcmV0dXJuICJVbmJla2FubnRlcyI7CisgIH0KK30KKworc3RyaW5nIEdyb3VwRGVzY3JpcHRpb24oc3RyaW5nIGdycCkgeworICBpZiAoaW5pdGlhbGl6ZWQpIHsKKyAgICBpZiAobWVtYmVyKG1hdGVyaWFsX2dyb3VwcywgZ2V0TWF0R3JvdXBJZChncnApKSkKKyAgICAgIHJldHVybiBtYXRlcmlhbF9ncm91cHNbZ2V0TWF0R3JvdXBJZChncnApXVtQX0RFU0NSSVBUSU9OXTsKKyAgICBlbHNlCisgICAgICByZXR1cm4gIkdydXBwZSB1bmJla2FubnQiOworICB9Cit9CisKKy8vPT09PT09PT09PT09PT09PT09PT0gR2VuZXJpZXJlbiB2b24gSGVhZGVyZmlsZSB1bmQgTWFucGFnZXMKK3ByaXZhdGUgc3RyaW5nICpnZXRfb3JkZXJlZF9ncm91cHMoKQoreworICByZXR1cm4gKHsiTUFUR1JPVVBfV09PRCIsICJNQVRHUk9VUF9KRVdFTCIsICJNQVRHUk9VUF9TVE9ORSIsICJNQVRHUk9VUF9NQUdORVRJQyIsCisgICAgICAgICAgICJNQVRHUk9VUF9NRVRBTCIsICJNQVRHUk9VUF9EUlVHIiwgIk1BVEdST1VQX0hFUkJBTCIsICJNQVRHUk9VUF9GTEVYSUJMRSIsCisgICAgICAgICAgICJNQVRHUk9VUF9CSU8iLCAiTUFUR1JPVVBfQUNJRElDIiwgIk1BVEdST1VQX0JBU0lDIiwgIk1BVEdST1VQX1BPSVNPTk9VUyIsCisgICAgICAgICAgICJNQVRHUk9VUF9FWFBMT1NJVkUiLCAiTUFUR1JPVVBfSU5GTEFNTUFCTEUiLAorICAgICAgICAgICAiTUFUR1JPVVBfRUxFTUVOVEFMIiwgIk1BVEdST1VQX0VMRUNUUklDQUwiLCAiTUFUR1JPVVBfTUFHSUMiLAorICAgICAgICAgICAiTUFUR1JPVVBfSE9MWSIsICJNQVRHUk9VUF9VTkhPTFkiLCAiTUFUR1JPVVBfSU5WSVMiLAorICAgICAgICAgICAiTUFUR1JPVVBfU09MSUQiLCAiTUFUR1JPVVBfRkxVSUQiLCAiTUFUR1JPVVBfR0FTIn0pOworfQorcHJpdmF0ZSBzdHJpbmcgZ2VuX21hdGVyaWFsX2hfaGVhZCgpCit7CisgIHJldHVybgorICAgICIvLyBNb3JnZW5HcmF1ZW4gTVVEbGliXG4vL1xuIgorICAgICIvLyBtYXRlcmlhbHMuaCAtLSBtYXRlcmlhbCBkZWZpbml0aW9uc1xuLy9cbiIKKyAgICAiLy8gVGhpcyBmaWxlIGlzIGdlbmVyYXRlZCBieSAvc2VjdXJlL21hdGVyaWFsZGIuY1xuLy9cbiIKKyAgICAiLy8gRE8gTk9UIEVESVQhXG4vL1xuIgorICAgICIvLyAkSWQ6IG1hdGVyaWFsZGIuYyA4NzU1IDIwMTQtMDQtMjYgMTM6MTM6NDBaIFplc3N0cmEgJFxuXG4iCisgICAgIiNpZm5kZWYgX19NQVRFUklBTFNfSF9fXG4iCisgICAgIiNkZWZpbmUgX19NQVRFUklBTFNfSF9fXG5cbiI7Cit9Citwcml2YXRlIHN0cmluZyBnZW5fbWF0ZXJpYWxfaF9tYXRlcmlhbChzdHJpbmcgbWF0LCBzdHJpbmcgbGFzdF9ncnApCit7CisgIG1hdCA9IG9sZF9tYXRfa2V5c1ttYXRdOworICByZXR1cm4gc3ByaW50ZigiI2RlZmluZSAlLTI0c1wiJS0yMHMgLy8gJXNcbiIsIG1hdCwKKyAgICAgICAgICAgICAgICAobWVtYmVyKG1hdGVyaWFsc1ttYXRdLCBQX0RFRlNUUik/bWF0ZXJpYWxzW21hdF1bUF9ERUZTVFJdOm1hdCkrIlwiIiwKKyAgICAgICAgICAgICAgICBtYXRlcmlhbHNbbWF0XVtQX0RFU0NSSVBUSU9OXXx8bWF0ZXJpYWxzW21hdF1bUF9OQU1FXVtXRVJdKTsKK30KK3ByaXZhdGUgc3RyaW5nIGdlbl9tYXRlcmlhbF9oX21hdGVyaWFsc19ncnAoc3RyaW5nIGdycCwgc3RyaW5nICpsZWZ0KQoreworICBzdHJpbmcgdHh0LCAqbWF0czsKKyAgdHh0ID0gc3ByaW50ZigiXG4vLyBHcnVwcGU6ICVzXG4iLCBHcm91cE5hbWUoZ3JwKSk7CisgIG1hdHMgPSBHZXRHcm91cE1lbWJlcnMoZ3JwKSAtIChHZXRHcm91cE1lbWJlcnMoZ3JwKSAtIGxlZnQpOworICB0eHQgKz0gc3ByaW50ZigiJUBzIiwgbWFwKHNvcnRfYXJyYXkobWF0cywgIyc+KSwgIydnZW5fbWF0ZXJpYWxfaF9tYXRlcmlhbCkpOworICBsZWZ0IC09IEdldEdyb3VwTWVtYmVycyhncnApOworICByZXR1cm4gdHh0OworfQorcHJpdmF0ZSBzdHJpbmcgZ2VuX21hdGVyaWFsX2hfbWF0ZXJpYWxzKCkKK3sKKyAgc3RyaW5nIHR4dCwgbGFzdF9ncnA7CisgIHN0cmluZyAqZ3JwcywgKm1hdHM7CisgIHR4dCA9ICIvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogTWF0ZXJpYWxpZW4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4iOworICAvLyBHcnVwcGVud2Vpc2Ugb3JkbmVuCisgIGdycHMgPSBnZXRfb3JkZXJlZF9ncm91cHMoKTsKKyAgbWF0cyA9IEFsbE1hdGVyaWFscygpOworICB0eHQgKz0gc3ByaW50ZigiJUBzIiwgbWFwKGdycHMsICMnZ2VuX21hdGVyaWFsX2hfbWF0ZXJpYWxzX2dycCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbWF0cykpOworICAvLyDcYnJpZ2dlYmxpZW5lIE1hdGVyaWFsaWVuIGF1c2dlYmVuCisgIHR4dCArPSAiLy8gc29uc3RpZ2UgTWF0ZXJpYWxpZW46XG4iOworICB0eHQgKz0gc3ByaW50ZigiJUBzIiwgbWFwKG1hdHMsICMnZ2VuX21hdGVyaWFsX2hfbWF0ZXJpYWwpKTsKKyAgcmV0dXJuIHR4dDsKK30KK3ByaXZhdGUgc3RyaW5nIGdlbl9tYXRlcmlhbF9oX2dyb3VwKHN0cmluZyBncnApCit7CisgIHJldHVybiBzcHJpbnRmKCIjZGVmaW5lICUtMjdzXCIlLTE4cyAvLyAlc1xuIiwKKyAgICAgICAgICAgICAgICAgZ3JwLCBncm91cEtleTJEZWZzdHIoZ3JwKSsiXCIiLCBHcm91cE5hbWUoZ3JwKSk7Cit9Citwcml2YXRlIHN0cmluZyBnZW5fbWF0ZXJpYWxfaF9ncm91cHMoKQoreworICBzdHJpbmcgdHh0OworICB0eHQgPSAiXG4vLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqIE1hdGVyaWFsZ3J1cHBlbiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cbiIKKyAgICAiI2lmbmRlZiBfSVNfTUFURVJJQUxEQl9cbiI7CisgIHR4dCArPSBzcHJpbnRmKCIlQHNcbiIsIG1hcChzb3J0X2FycmF5KG1faW5kaWNlcyhtYXRlcmlhbF9ncm91cHMpLCAjJz4pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIydnZW5fbWF0ZXJpYWxfaF9ncm91cCkpOworICB0eHQgKz0gIlxuI2VuZGlmIC8vIF9JU19NQVRFUklBTERCX1xuIjsKKyAgcmV0dXJuIHR4dDsKK30KK3ByaXZhdGUgc3RyaW5nIGdlbl9tYXRlcmlhbF9oX2Zvb3QoKQoreworICByZXR1cm4KKyAgICAiI2VuZGlmIC8vIF9fVEhJTkdfTUFURVJJQUxfSF9fXG4iOworfQorcHJpdmF0ZSBpbnQgZHVtcF9tYXRlcmlhbF9oKHN0cmluZyBmbikKK3sKKyAgcmV0dXJuICh3cml0ZV9maWxlKGZuLCBnZW5fbWF0ZXJpYWxfaF9oZWFkKCkpICYmCisgICAgICAgICAgd3JpdGVfZmlsZShmbiwgZ2VuX21hdGVyaWFsX2hfbWF0ZXJpYWxzKCkpICYmCisgICAgICAgICAgd3JpdGVfZmlsZShmbiwgZ2VuX21hdGVyaWFsX2hfZ3JvdXBzKCkpICYmCisgICAgICAgICAgd3JpdGVfZmlsZShmbiwgZ2VuX21hdGVyaWFsX2hfZm9vdCgpKSk7Cit9Citwcml2YXRlIHN0cmluZyBnZW5fbWF0ZXJpYWxfbGlzdF9tYXRlcmlhbChzdHJpbmcgbWF0KQoreworICBtYXQgPSBvbGRfbWF0X2tleXNbbWF0XTsKKyAgcmV0dXJuIHNwcmludGYoIiAgJS0yOHMlPS00NXNcbiIsIG1hdCwKKyAgICAgICAgICAgICAgICAgbWF0ZXJpYWxzW21hdF1bUF9ERVNDUklQVElPTl18fG1hdGVyaWFsc1ttYXRdW1BfTkFNRV1bV0VSXSk7Cit9Citwcml2YXRlIHN0cmluZyBnZW5fbWF0ZXJpYWxfbGlzdF9tYXRlcmlhbHNfZ3JwKHN0cmluZyBncnAsIHN0cmluZyAqbGVmdCkKK3sKKyAgc3RyaW5nIHR4dCwgKm1hdHM7CisgIHR4dCA9IHNwcmludGYoIiVzOlxuIiwgY2FwaXRhbGl6ZShHcm91cE5hbWUoZ3JwKSkpOworICBtYXRzID0gc29ydF9hcnJheShHZXRHcm91cE1lbWJlcnMoZ3JwKSAtIChHZXRHcm91cE1lbWJlcnMoZ3JwKSAtIGxlZnQpLCAjJz4pOworICB0eHQgKz0gc3ByaW50ZigiJUBzXG4iLCBtYXAobWF0cywgIydnZW5fbWF0ZXJpYWxfbGlzdF9tYXRlcmlhbCkpOworICBsZWZ0IC09IEdldEdyb3VwTWVtYmVycyhncnApOworICByZXR1cm4gdHh0OworfQorcHJpdmF0ZSB2b2lkIGR1bXBfbWF0ZXJpYWwoc3RyaW5nIGZuKQoreworICBzdHJpbmcgdHh0OworICBzdHJpbmcgKmdycHMsICptYXRzOworICAvLyBHcnVwcGVud2Vpc2Ugb3JkbmVuCisgIGdycHMgPSBnZXRfb3JkZXJlZF9ncm91cHMoKTsKKyAgbWF0cyA9IEFsbE1hdGVyaWFscygpOworICB0eHQgPSBzcHJpbnRmKCIlQHMiLCBtYXAoZ3JwcywgIydnZW5fbWF0ZXJpYWxfbGlzdF9tYXRlcmlhbHNfZ3JwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1hdHMpKTsKKyAgLy8g3GJyaWdnZWJsaWVuZSBNYXRlcmlhbGllbiBhdXNnZWJlbgorICB0eHQgKz0gInNvbnN0aWdlIE1hdGVyaWFsaWVuOlxuIjsKKyAgdHh0ICs9IHNwcmludGYoIiVAcyIsIG1hcChtYXRzLCAjJ2dlbl9tYXRlcmlhbF9saXN0X21hdGVyaWFsKSk7CisgIHdyaXRlX2ZpbGUoZm4sIHR4dCkgfHwKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJLb25udGUgTGlzdGUgbmljaHQgd2VpdGVyIGluIERhdGVpICVzIHNjaHJlaWJlbiwiCisgICAgICAgICAgICAgICAgICAgICAgICAiIEFiYnJ1Y2hcbiIsIGZuKSk7Cit9Citwcml2YXRlIHZvaWQgZHVtcF9ncm91cChzdHJpbmcgZ3JwLCBzdHJpbmcgZm4pCit7CisgIC8vIHVwcGVyc3RyaW5nIGxhbmdzYW1lIHNpbXVsX2VmdW4sIHdhcnVtPworICB3cml0ZV9maWxlKGZuLCBzcHJpbnRmKCIgICUtMjhzJT0tNDhzXG4iLCAoZ3JwKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBHcm91cE5hbWUoZ3JwKSkpIHx8CisgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiS29ubnRlIExpc3RlIG5pY2h0IHdlaXRlciBpbiBEYXRlaSAlcyBzY2hyZWliZW4sIgorICAgICAgICAgICAgICAgICAgICAgICAgIiBBYmJydWNoXG4iLCBmbikpOworfQorcHJpdmF0ZSBzdHJpbmcgZ2VuX2RvY19mb290KHN0cmluZyBvdGhlcikKK3sKKyAgcmV0dXJuIHNwcmludGYoIlxuU0lFSEUgQVVDSDpcbiIKKyAgICAgICAgICAgICAgICAgIiAgICAgS29uemVwdGU6ICAgIG1hdGVyaWFsLCBtYXRlcmlhbGVya2VubnVuZ1xuIgorICAgICAgICAgICAgICAgICAiICAgICBHcnVuZGxlZ2VuZDogUF9NQVRFUklBTCwgL3N5cy9tYXRlcmlhbHMuaCwgL3N5cy90aGluZy9tYXRlcmlhbC5oXG4iCisgICAgICAgICAgICAgICAgICIgICAgIE1ldGhvZGVuOiAgICBRdWVyeU1hdGVyaWFsKCksIFF1ZXJ5TWF0ZXJpYWxHcm91cCgpLCBNYXRlcmlhbExpc3QoKSxcbiIKKyAgICAgICAgICAgICAgICAgIiAgICAgTGlzdGVuOiAgICAgIEFsbE1hdGVyaWFscygpLCBBbGxHcm91cHMoKVxuIgorICAgICAgICAgICAgICAgICAiICAgICAgICAgICAgICAgICAgJXNcbiIKKyAgICAgICAgICAgICAgICAgIiAgICAgTWFzdGVyOiAgICAgIENvbnZNYXRlcmlhbExpc3QoKSwgTWF0ZXJpYWxHcm91cCgpLFxuIgorICAgICAgICAgICAgICAgICAiICAgICAgICAgICAgICAgICAgR3JvdXBOYW1lKCksIE1hdGVyaWFsTmFtZSgpLFxuIgorICAgICAgICAgICAgICAgICAiICAgICAgICAgICAgICAgICAgR2V0R3JvdXBNZW1iZXJzKCksIEdldE1hdE1lbWJlcnNoaXAoKVxuIgorICAgICAgICAgICAgICAgICAiICAgICBTb25zdGlnZXM6ICAgUF9NQVRFUklBTF9LTk9XTEVER0VcblxuIgorICAgICAgICAgICAgICAgICAiJXMgZ2VuZXJpZXJ0IGF1cyAvc2VjdXJlL21hdGVyaWFsZGJcbiIsIG90aGVyLCBkdGltZSh0aW1lKCkpKTsKK30KKworLyogR2VuTWF0TGlzdAorICoKKyAqIEdlbmVyaWVydCBEYXRlaSBtaXQgcmVnaXN0cmllcnRlbiBNYXRlcmlhbGllbiBmdWVyIGRpZSBEb2t1bWVudGF0aW9uLAorICovCit2YXJhcmdzIHZvaWQgR2VuTWF0TGlzdChzdHJpbmcgZm4pCit7CisgIGlmIChpbml0aWFsaXplZCkgeworICAgIHN0cmluZyB0eHQ7CisgICAgaWYgKCFzdHJpbmdwKGZuKSB8fCAhc2l6ZW9mKGZuKSkKKyAgICAgIGZuID0gRE9DX0RJUigibWF0ZXJpYWxsaXN0ZSIpOworICAgIGlmIChmaWxlX3NpemUoZm4pID49IDApIHsKKyAgICAgIHByaW50ZigiRGF0ZWkgJXMgZXhpc3RpZXJ0IGJlcmVpdHMsIGxvZXNjaGUgc2llXG4iLCBmbik7CisgICAgICBybShmbik7CisgICAgfQorICAgIGlmICh3cml0ZV9maWxlKGZuLCAiTWF0ZXJpYWwgTGlzdGVcbj09PT09PT09PT09PT09XG5cbiIpKSB7CisgICAgICBkdW1wX21hdGVyaWFsKGZuKTsKKyAgICAgIHdyaXRlX2ZpbGUoZm4sIGdlbl9kb2NfZm9vdCgibWF0ZXJpYWxncnVwcGVuIikpOworICAgICAgcHJpbnRmKCJNYXRlcmlhbGxpc3RlIGVyZm9sZ3JlaWNoIGluIERhdGVpICVzIGdlc2NocmllYmVuXG4iLCBmbik7CisgICAgfSBlbHNlCisgICAgICBwcmludGYoIktvbm50ZSBMaXN0ZSBuaWNodCBpbiBEYXRlaSAlcyBzY2hyZWliZW4sIEFiYnJ1Y2hcbiIsIGZuKTsKKyAgfQorfQorCisvKiBHZW5NYXRHcm91cExpc3QKKyAqCisgKiBHZW5lcmllcnQgRGF0ZWkgbWl0IHJlZ2lzdHJpZXJ0ZW4gTWF0ZXJpYWxncnVwcGVuIGZ1ZXIgZGllIERva3VtZW50YXRpb24sCisgKi8KK3ZhcmFyZ3Mgdm9pZCBHZW5NYXRHcm91cExpc3Qoc3RyaW5nIGZuKQoreworICBpZiAoaW5pdGlhbGl6ZWQpIHsKKyAgICBzdHJpbmcgdHh0OworICAgIGlmICghc3RyaW5ncChmbikgfHwgIXNpemVvZihmbikpCisgICAgICBmbiA9IERPQ19ESVIoIm1hdGVyaWFsZ3J1cHBlbiIpOworICAgIGlmIChmaWxlX3NpemUoZm4pID49IDApIHsKKyAgICAgIHByaW50ZigiRGF0ZWkgJXMgZXhpc3RpZXJ0IGJlcmVpdHMsIGxvZXNjaGUgc2llXG4iLCBmbik7CisgICAgICBybShmbik7CisgICAgfQorICAgIGlmICh3cml0ZV9maWxlKGZuLCAiTWF0ZXJpYWxncnVwcGVuXG49PT09PT09PT09PT09PT1cbiIpKSB7CisgICAgICBtYXAoc29ydF9hcnJheShtX2luZGljZXMobWF0ZXJpYWxfZ3JvdXBzKSwgIyc+KSwgIydkdW1wX2dyb3VwLCBmbik7CisgICAgICB3cml0ZV9maWxlKGZuLCBnZW5fZG9jX2Zvb3QoIm1hdGVyaWFsbGlzdGUiKSk7CisgICAgICBwcmludGYoIk1hdGVyaWFsbGlzdGUgZXJmb2xncmVpY2ggaW4gRGF0ZWkgJXMgZ2VzY2hyaWViZW5cbiIsIGZuKTsKKyAgICB9IGVsc2UKKyAgICAgIHByaW50ZigiS29ubnRlIExpc3RlIG5pY2h0IGluIERhdGVpICVzIHNjaHJlaWJlbiwgQWJicnVjaFxuIiwgZm4pOworICB9Cit9CisKKy8qIEdlbkhlYWRlckZpbGUKKyAqCisgKiBHZW5lcmllcnQgSGVhZGVyZmlsZSBtaXQgRGVmaW5pdGlvbmVuIGRlciBtb2VnbGljaGVuIE1hdGVyaWFsaWVuIHVuZAorICogR3J1cHBlbgorICovCit2YXJhcmdzIHZvaWQgR2VuSGVhZGVyRmlsZShzdHJpbmcgZm4pCit7CisgIGlmIChpbml0aWFsaXplZCkgeworICAgIHN0cmluZyB0eHQ7CisgICAgaWYgKCFzdHJpbmdwKGZuKSB8fCAhc2l6ZW9mKGZuKSkKKyAgICAgIGZuID0gSEVBREVSRklMRTsKKyAgICBpZiAoZmlsZV9zaXplKGZuKSA+PSAwKSB7CisgICAgICBwcmludGYoIkRhdGVpICVzIGV4aXN0aWVydCBiZXJlaXRzLCBsb2VzY2hlIHNpZVxuIiwgZm4pOworICAgICAgcm0oZm4pOworICAgIH0KKyAgICBpZiAoZHVtcF9tYXRlcmlhbF9oKGZuKSkKKyAgICAgIHByaW50ZigiSGVhZGVyZGF0ZWkgZXJmb2xncmVpY2ggaW4gJXMgZ2VzY2hyaWViZW5cbiIsIGZuKTsKKyAgICBlbHNlCisgICAgICBwcmludGYoIktvbm50ZSBIZWFkZXJkYXRlaSBuaWNodCBpbiBEYXRlaSAlcyBzY2hyZWliZW4sIEFiYnJ1Y2hcbiIsIGZuKTsKKyAgfQorfQorCisvLz09PT09PT09PT09PT09PT09PT09IFBydWVmLSB1bmQgSGlsZnNmdW5rdGlvbmVuIGZ1ZXIgTWF0ZXJpYWxpZW4KK3ByaXZhdGUgdm9pZCB1cGRhdGVHcm91cE1lbWJlcnMobWFwcGluZyBncm91cHMsIHN0cmluZyBtYXRfaWQsIG1hcHBpbmcgbWF0KSB7CisgIG1peGVkICphZGRncnBzOyAvLyBBcnJheSB6dW0gQWJsZWl0ZW4gdm9uIEdydXBwZW56dWdlaG9lcmlna2VpdGVuCisgIHN0cmluZyAqaDsKKyAgaW50IGksIHZhbDsKKyAgbWFwcGluZyBmcmFjdGlvbnM7IC8vIE1hcHBpbmcgbWl0IEFudGVpbGVuIGFuIEdydXBwZW4KKyAgZnJhY3Rpb25zID0gbWF0W1BfTUdfRlJBQ1RJT05TXTsKKyAgaWYgKCFtYXBwaW5ncChmcmFjdGlvbnMpKQorICAgIGZyYWN0aW9ucyA9IChbXSk7CisgIGFkZGdycHM9KHsgLy8gUmVpaGVuZm9sZ2Ugd2lyZCBydWVja3dhZXJ0cyBhYmdlYXJiZWl0ZXQKKyAgICAvLyBBYmxlaXR1bmdlbiBzaW5kIHouVC4gYWJlbnRldWVybGljaCBnZXdlc2VuLCBtYWwgb3JkZW50bGljaAorICAgIC8vIGF1c21pc3Rlbi4gRGllIFp1Z2Vob2VyaWdrZWl0IGdlaG9lcnQgZXhwbGl6aXQgaW4gZGllCisgICAgLy8gTWF0ZXJpYWxkZWZpbml0aW9uCisgICAgLy8gR2FzZSBzaWVodCBtYW4gbm9ybWFsZXJ3ZWlzZSBuaWNodDoKKyAgICAoeyJNQVRHUk9VUF9JTlZJUyIsICJNQVRHUk9VUF9HQVMifSksCisgICAgLy8gTWluZXJhbGllbiBzaW5kIGF1Y2ggU3RlaW5lCisgICAgKHsiTUFUR1JPVVBfU1RPTkUiLCJNQVRHUk9VUF9NSU5FUkFMIn0pLAorICAgIC8vIEVkZWxtZXRhbGxlIHNpbmQgTWV0YWxsZToKKyAgICAoeyJNQVRHUk9VUF9NRVRBTCIsIk1BVEdST1VQX1BSRUNJT1VTX01FVEFMIn0pLAorICAgIC8vIExlYmV3ZXNlbiB1bmQgZGVyZW4gVWViZXJyZXN0ZSwgUGFpZXJlIHVuZCBTdG9mZmUgc2luZCBiaW9sb2dpc2NoCisgICAgKHsiTUFUR1JPVVBfQklPIiwiTUFUR1JPVVBfTElWSU5HIiwiTUFUR1JPVVBfREVBRCIsCisgICAgICAiTUFUR1JPVVBfUEFQRVIifSksCisgICAgLy8gSG9seiBpc3QgcGZsYW56bGljaDoKKyAgICAoeyJNQVRHUk9VUF9IRVJCQUwiLCAiTUFUR1JPVVBfV09PRCJ9KSwKKyAgICAvLyBIb2x6IGlzdCBtZWlzdGVucyB0b3Q6CisgICAgKHsiTUFUR1JPVVBfREVBRCIsIk1BVEdST1VQX1dPT0QifSksCisgICAgLy8gSG9seiwgUGFwaWVyIHVuZCBTdG9mZmUgYnJlbm5lbjoKKyAgICAoeyJNQVRHUk9VUF9JTkZMQU1NQUJMRSIsIk1BVEdST1VQX1dPT0QiLCJNQVRHUk9VUF9QQVBFUiJ9KSwKKyAgICAvLyBMYXViaG9lbHplciwgTmFkZWxob2VsemVyIHVuZCBUcm9wZW5ob2VsemVyIHNpbmQgSG9segorICAgICh7Ik1BVEdST1VQX1dPT0QiLCJNQVRHUk9VUF9UUk9QSUNBTF9XT09EIiwiTUFUR1JPVVBfREVDSURVT1VTX1dPT0QiLAorICAgICAgIk1BVEdST1VQX0NPTklGRVJfV09PRCJ9KSwKKyAgICAvLyBFeHBsb3NpdmUgRGluZ2Ugc2luZCBpbW1lciBlbnR6dWVuZGxpY2g6CisgICAgKHsiTUFUR1JPVVBfSU5GTEFNTUFCTEUiLCJNQVRHUk9VUF9FWFBMT1NJVkUifSkKKyAgfSk7CisgIGk9c2l6ZW9mKGFkZGdycHMpOworICB3aGlsZShpLS0pIHsKKyAgICBpbnQgajsKKyAgICBoPWFkZGdycHNbaV07CisgICAgaWYgKG1lbWJlcihmcmFjdGlvbnMsaFswXSkpIC8vIEV4aXN0aWVydCBzY2hvbiBlaWdlbmVyIEVpbnRyYWc/CisgICAgICBjb250aW51ZTsgLy8gQXV0b21hdGlzY2hlIEVpbnRyYWd1bmcgdW5ub2V0aWcKKyAgICB2YWw9MDsKKyAgICBmb3IgKGo9c2l6ZW9mKGgpLTE7aj49MTtqLS0pCisgICAgICB2YWwrPWZyYWN0aW9uc1toW2pdXTsKKyAgICBpZiAoIXZhbCkKKyAgICAgIGNvbnRpbnVlOworICAgIGlmICh2YWw+MTAwKQorICAgICAgdmFsPTEwMDsKKyAgICBlbHNlIGlmICh2YWw8LTEwMCkKKyAgICAgIHZhbD0tMTAwOworICAgIGZyYWN0aW9uc1toWzBdXT12YWw7CisgIH0KKyAgaWYgKGZyYWN0aW9uc1siTUFUR1JPVVBfTElWSU5HIl0pIC8vIEltIEZhbGxlIHZvbiBsZWJlbmRlbSBIb2x6LCB0b3QgbG9lc2NoZW4KKyAgICBtX2RlbGV0ZShmcmFjdGlvbnMsIk1BVEdST1VQX0RFQUQiKTsKKyAgLy8gQWxsZXMsIHdhcyBuaWNodCBhbHMgZ2FzZm9lcm1pbmcsIGZsdWVzc2lnIG9kZXIgZmVzdCBlaW5nZW9yZG5ldCBpc3QsIGlzdAorICAvLyBzb25zdHdhczoKKyAgaWYgKCFtZW1iZXIoZnJhY3Rpb25zLCAiTUFUR1JPVVBfRkxVSUQiKQorICAgICAgJiYgIW1lbWJlcihmcmFjdGlvbnMsICJNQVRHUk9VUF9HQVMiKQorICAgICAgJiYgIW1lbWJlcihmcmFjdGlvbnMsICJNQVRHUk9VUF9TT0xJRCIpKQorICAgIGZyYWN0aW9uc1siTUFUR1JPVVBfTUlTQyJdPTEwMDsKKyAgLy8gTWF0ZXJpYWxpZW4gYWxzIE1pdGdsaWVkZXIgaW4gZGllIEdydXBwZW4gZWludHJhZ2VuCisgIGFkZGdycHM9bV9pbmRpY2VzKGZyYWN0aW9ucyk7CisgIGk9c2l6ZW9mKGFkZGdycHMpOworICB3aGlsZShpLS0pIHsKKyAgICBtaXhlZCBpbmQ7CisgICAgaW5kPWFkZGdycHNbaV07CisgICAgaWYgKCFmcmFjdGlvbnNbaW5kXSB8fCAhbWVtYmVyKGdyb3VwcywgaW5kKSkgeworICAgICAgLy8gVW5iZWthbm50ZSBHcnVwcGUgdW5kIEdydXBwZSBvaG5lIEFudGVpbCBhdXMgTWFwcGluZyBsb2VzY2hlbgorICAgICAgbV9kZWxldGUoZnJhY3Rpb25zLGluZCk7CisgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgaWYgKCFwb2ludGVycChoPWdyb3Vwc1tpbmRdW1BfTUVNQkVSU10pKQorICAgICAgaD0oe30pOworICAgIGgrPSh7bWF0X2lkfSk7CisgICAgZ3JvdXBzW2luZF1bUF9NRU1CRVJTXT1oOworICB9CisgIG1hdFtQX01HX0ZSQUNUSU9OU10gPSBmcmFjdGlvbnM7Cit9CisKKy8vPT09PT09PT09PT09PT09PT09PT0gRWlubGVzZW4gZGVyIE1hcHBpbmdzIGF1cyBEYXRlaWVuCisKKyNkZWZpbmUgTURFU0NfRVJST1IoeCwgeSkgTE9HX0VSUk9SKHNwcmludGYoIk1hdGVyaWFsYmVzY2hyZWlidW5nICclcyc6ICVzXG4iLCB4LCB5KSkKKyNkZWZpbmUgTURFU0NfV0FSTih4LCB5KSAvL0xPR19XQVJOKHNwcmludGYoIk1hdGVyaWFsYmVzY2hyZWlidW5nICclcyc6ICVzXG4iLCB4LCB5KSkKKworcHJpdmF0ZSBtYXBwaW5nIGdldERlc2NQYXJ0cyhzdHJpbmcgcykgeworICBzdHJpbmcqIGxpbmVzOworICBzdHJpbmcga2V5LCB2YWw7CisgIGludCBpLCBuOworICBtYXBwaW5nIG07CisgIG0gPSAoW10pOworICB2YWwgPSAiIjsKKyAgbGluZXMgPSBleHBsb2RlKHMsICJcbiIpOworICBuID0gc2l6ZW9mKGxpbmVzKTsKKyAgaWYgKG4gPiAwKSB7CisgICAgd2hpbGUgKGkgPCBuKSB7CisgICAgICBpZiAoc3NjYW5mKGxpbmVzW2ldLCAiJXM6Iiwga2V5KSkgeworICAgICAgICBzdGF0dXMgbXVsdGlsaW5lOworICAgICAgICBtdWx0aWxpbmUgPSAwOworICAgICAgICAvLyBTY2hsdWVzc2VsIGdlZnVuZGVuLCBXZXJ0IGF1c2xlc2VuCisgICAgICAgIHdoaWxlICggKCsraSA8IG4pICYmIHNpemVvZihsaW5lc1tpXSkpIHsKKyAgICAgICAgICAvLyBNZWhyemVpbGlnZSBXZXJ0ZSBtaXQgbmV3bGluZSB2ZXJrZXR0ZW4KKyAgICAgICAgICBpZiAobXVsdGlsaW5lKSB7CisgICAgICAgICAgICB2YWwgKz0gIlxuIjsKKyAgICAgICAgICB9CisgICAgICAgICAgdmFsICs9IGxpbmVzW2ldOworICAgICAgICAgIG11bHRpbGluZSA9IDE7CisgICAgICAgIH0KKyAgICAgICAgbSArPSAoW2tleTp2YWxdKTsKKyAgICAgICAgdmFsID0gIiI7CisgICAgICB9CisgICAgICBpKys7CisgICAgfQorICB9CisgIHJldHVybiBtOworfQorcHJpdmF0ZSB2YXJhcmdzIGludCBpc0ZpbGUoc3RyaW5nIGZuLCBzdHJpbmcgcGF0aCkgeworICBpZiAoc3RyaW5ncChwYXRoKSAmJiBzaXplb2YocGF0aCkpCisgICAgZm4gPSBwYXRoKyIvIitmbjsKKyAgcmV0dXJuIChmaWxlX3NpemUoZm4pID49IDApOworfQorCitwcml2YXRlIHZhcmFyZ3MgbWl4ZWQgcmVhZEdyb3VwRGVzYyhzdHJpbmcgaWQpIHsKKyAgbWl4ZWQgbTsKKyAgc3RyaW5nIGZuOworICBmbiA9IE1BVF9ESVIrIi9ncm91cHMvIitpZDsKKyAgaWYgKGZpbGVfc2l6ZShmbikgPiAwKSB7CisgICAgbWFwcGluZyBwYXJ0czsKKyAgICBzdHJpbmcgZGVzYzsKKyAgICBwYXJ0cyA9IGdldERlc2NQYXJ0cyhyZWFkX2ZpbGUoZm4pKTsKKyAgICBtID0gKFtQX05BTUU6cGFydHNbIk5hbWUiXSwKKyAgICAgICAgICBQX01FTUJFUlM6KHt9KV0pOworICAgIGlmIChtZW1iZXIocGFydHMsIkJlc2NocmVpYnVuZyIpKQorICAgICAgbSArPSAoW1BfREVTQ1JJUFRJT046cGFydHNbIkJlc2NocmVpYnVuZyJdXSk7CisgICAgaWYgKHBhcnRzWyJHcnVwcGVuaWQiXSAhPSBpZCkKKyAgICAgIExPR19XQVJOKHNwcmludGYoIlVuc3RpbW1pZ2tlaXQgR3J1cHBlbmlkIGJlaSAnJXMnXG4iLCBpZCkpOworICB9IGVsc2UgeworICAgIExPR19FUlJPUihzcHJpbnRmKCJLYW5uIEdydXBwZW5iZXNjaHJlaWJ1bmcgJXMgbmljaHQgbGFkZW5cbiIsIGZuKSk7CisgIH0KKyAgcmV0dXJuIG07Cit9CisKK3ByaXZhdGUgbWFwcGluZyBjb252TWF0SWQoc3RyaW5nIHMpIHsKKyAgbWFwcGluZyBtOworICBzdHJpbmcqIHBhcnRzOworICBwYXJ0cyA9IGV4cGxvZGUocywgIlwiIik7CisgIGlmIChzaXplb2YocGFydHMpKSB7CisgICAgaW50IGVuZGU7CisgICAgZW5kZSA9IHN0cnN0cihwYXJ0c1swXSwiICIpLTE7CisgICAgaWYgKGVuZGUgPCAwKQorICAgICAgZW5kZSA9IHNpemVvZihwYXJ0c1swXSk7CisgICAgbSA9IChbUF9JRDpwYXJ0c1swXVswLi5lbmRlXV0pOworICAgIGlmIChzaXplb2YocGFydHMpID4gMSkKKyAgICAgIG0gKz0gKFtQX0RFRlNUUjpwYXJ0c1sxXV0pOworICB9CisgIHJldHVybiBtOworfQorcHJpdmF0ZSBzdHJpbmcqIGNvbnZNYXROYW1lcyhzdHJpbmcgcykgeworICBzdHJpbmcqIG5hbWVzOworICBuYW1lcyA9IGZpbHRlcihleHBsb2RlKHMsICJcIiIpLAorICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGEoICh7J3h9KSwgKHsjJz4sICh7IydzaXplb2YsICd4fSksIDF9KSApKTsKKyAgaWYgKHNpemVvZihuYW1lcyk8MSkKKyAgICBuYW1lcz0wOworICBlbHNlIHsKKyAgICBpZiAoc2l6ZW9mKG5hbWVzKTwyKQorICAgICAgbmFtZXMrPSh7bmFtZXNbMF0rInMifSk7CisgICAgaWYgKHNpemVvZihuYW1lcyk8MykKKyAgICAgIG5hbWVzKz0oe25hbWVzWzBdfSk7CisgICAgaWYgKHNpemVvZihuYW1lcyk8NCkKKyAgICAgIG5hbWVzKz0oe25hbWVzWzBdfSk7CisgIH0KKyAgcmV0dXJuIG5hbWVzOworfQorcHJpdmF0ZSBpbnQgY29udk1hdEdlbmRlcihzdHJpbmcgcykgeworICBpbnQgZ2VuZGVyOworICBzID0gbG93ZXJzdHJpbmcocyk7CisgIC8vIEVpbiBCdWNoc3RhYmUgcmVpY2h0IHp1ciBCZXN0aW1tdW5nLiBXZW5uIG51ciB3ZWlibGljaHxmZW1hbGUKKyAgLy8gYnp3LiBtYWVubmxpY2h8bWFsZSB2ZXJ3ZW5kZXQgd2lyZC4gRGFiZWkgaXN0IGRhbm4gYWxsZXJkaW5ncyBkaWUKKyAgLy8gUmVpaGVuZm9sZ2UgZGVyIEF1c3dlcnR1bmcgd2ljaHRpZywgZGFtaXQgZGFzIG0gYmVpIE1BTEUgbmljaHQgbWVociBiZWkKKyAgLy8gZmVtYWxlIHBhc3N0LgorICBpZiAoc2l6ZW9mKHJlZ2V4cCggKHtzfSksICJmfHciKSkpIHsKKyAgICBnZW5kZXIgPSBGRU1BTEU7CisgIH0gZWxzZSBpZiAoc2l6ZW9mKHJlZ2V4cCggKHtzfSksICJtIikpKSB7CisgICAgZ2VuZGVyID0gTUFMRTsKKyAgfSBlbHNlIHsKKyAgICBnZW5kZXIgPSBORVVURVI7CisgIH0KKyAgcmV0dXJuIGdlbmRlcjsKK30KK3ByaXZhdGUgc3RyaW5nIGNvbnZNYXREZXNjKHN0cmluZyBzKSB7CisgIGlmIChzaXplb2YocmVnZXhwKCAoe3N9KSwgIi0gbmljaHQgdm9yaGFuZGVuIC0iKSkpIHsKKyAgICBzID0gMDsKKyAgfSBlbHNlIHsKKyAgICAvLyBNZWhyemVpbGlnZSBCZXNjaHJlaWJ1bmdlbiB6dSBlaW5lciBaZWlsZSB6dXNhbW1lbmZhc3NlbgorICAgIHMgPSBpbXBsb2RlKGV4cGxvZGUocywgIlxuIiksICIgIik7CisgIH0KKyAgcmV0dXJuIHM7Cit9Citwcml2YXRlIHZvaWQgYWRkUmVjb2NMaW5lKHN0cmluZyBzLCBtaXhlZCogcikgeworICAvLyBEaWUgd2VpdGVyZSBCZXdlcnR1bmcgZGVyIFNjaHdpZXJpZ2tlaXQga2FubiBlcnN0IHZvcmdlbm9tbWVuIHdlcmRlbiwKKyAgLy8gd2VubiBhbGxlIE1hdGVyaWFsaWVuIGJla2FubnQgc2luZCB1bmQgcGFzc2llcnQgc3BhZXRlci4gWnVlcnN0IHdlcmRlbgorICAvLyBudXIgZGllIEVsZW1lbnRlIGRlcyBBcnJheXMga29udmVydGllcnQgdW5kIGVpbmdldHJhZ2VuCisgIHN0cmluZyBtYXQ7CisgIGludCB2YWw7CisgIGlmIChzc2NhbmYocywgIiVzOiVkIiwgbWF0LCB2YWwpKSB7CisgICAgciArPSAoe21hdCx2YWx9KTsKKyAgfSBlbHNlIGlmIChzc2NhbmYocywgIiVkIiwgdmFsKSkgeworICAgIHIgKz0gKHt2YWx9KTsKKyAgfSBlbHNlIHsKKyAgICByICs9ICh7c30pOworICB9Cit9Citwcml2YXRlIG1peGVkIGNvbnZNYXRSZWMoc3RyaW5nIHMpIHsKKyAgbWl4ZWQgZGlmZmljdWx0aWVzOworICBpZiAoc2l6ZW9mKHJlZ2V4cCggKHtzfSksICItIGtlaW5lIEVpbnNjaHJhZW5rdW5nIC0iKSkpIHsKKyAgICBkaWZmaWN1bHRpZXMgPSAwOworICB9IGVsc2UgeworICAgIGRpZmZpY3VsdGllcyA9ICh7fSk7CisgICAgLy8gSmVkZSBaZWlsZSBlbnRoYWVsdCBlaW5lIEJlZGluZ3VuZworICAgIG1hcChleHBsb2RlKHMsICJcbiIpLCAjJ2FkZFJlY29jTGluZSwgJmRpZmZpY3VsdGllcyk7CisgIH0KKyAgcmV0dXJuIGRpZmZpY3VsdGllczsKK30KK3ByaXZhdGUgdm9pZCBhZGRHcm91cExpbmUoc3RyaW5nIHMsIG1hcHBpbmcgZykgeworICAvLyBEaWUgd2VpdGVyZSBCZXdlcnR1bmcgZGVyIFp1Z2Vob2VyaWdrZWl0IHBhc3NpZXJ0IHNwYWV0ZXIuCisgIHN0cmluZyBncnA7CisgIGludCB2YWw7CisgIGlmIChzc2NhbmYocywgIiVzOiVkIiwgZ3JwLCB2YWwpKSB7CisgICAgZyArPSAoW2dycDp2YWxdKTsKKyAgfSBlbHNlIHsKKyAgICBnICs9IChbZ3JwOjEwMF0pOworICB9Cit9Citwcml2YXRlIG1hcHBpbmcgY29udk1hdEdyb3VwcyhzdHJpbmcgcykgeworICBtYXBwaW5nIGdyb3VwczsKKyAgaWYgKCFzaXplb2YocmVnZXhwKCAoe3N9KSwgIi0ga2VpbmUgLSIpKSkgeworICAgIGdyb3VwcyA9IChbXSk7CisgICAgLy8gSmVkZSBaZWlsZSBlbnRoYWVsdCBlaW5lIEJlZGluZ3VuZworICAgIG1hcChleHBsb2RlKHMsICJcbiIpLCAjJ2FkZEdyb3VwTGluZSwgZ3JvdXBzKTsKKyAgfQorICByZXR1cm4gZ3JvdXBzOworfQorcHJpdmF0ZSBtYXBwaW5nIGNvbnZNYXRlcmlhbERlc2Moc3RyaW5nIGlkLCBtYXBwaW5nIGRlc2MpIHsKKyAgLyogU3RydWt0dXIgTWF0ZXJpYWxtYXBwaW5nOgorICAgICBQX0dFTkRFUiwKKyAgICAgUF9OQU1FOih7bmFtZV9ub20sIG5hbWVfZ2VuLCBuYW1lX2RhdGl2LCBuYW1lX2Fra3VzYXRpdn0pLAorICAgICAoUF9SRUNPQzooe21hdDEsZmFlaGlna2VpdDEsbWF0MixmYWVoaWdrZWl0MiwuLi59KSwpCisgICAgIChQX0RFRlNUUjogYmVpIGJlZGFyZiksCisgICAgIFBfREVTQ1JJUFRJT04sCisgICAgIChncnVwcDE6YW50ZWlsMSwKKyAgICAgZ3J1cHBlMjphbnRlaWwyLAorICAgICAuLi4pCisgICovCisgIG1hcHBpbmcgbTsKKyAgbWl4ZWQgdmFsLCB2YWwyOworICBtID0gKFtdKTsKKyAgLy8gRGVyIHN0cmluZyBmdWVyIGRhcyAjZGVmaW5lIHp1ZXJzdDoKKyAgdmFsID0gY29udk1hdElkKGRlc2NbIk1hdGVyaWFsaWQiXSk7CisgIGlmIChtYXBwaW5ncCh2YWwpKSB7CisgICAgaWYgKHZhbFtQX0lEXSAhPSBpZCkKKyAgICAgIExPR19XQVJOKHNwcmludGYoIlVuc3RpbW1pZ2tlaXQgTWF0ZXJpYWxpZCBiZWkgJyVzJzolT1xuIiwgaWQsIHZhbFtQX0lEXSkpOworICAgIGlmIChtZW1iZXIodmFsLCBQX0RFRlNUUikpIHsKKyAgICAgIG0gKz0gKFtQX0RFRlNUUjp2YWxbUF9ERUZTVFJdXSk7CisgICAgfSBlbHNlIHsKKyAgICAgIC8vIFdlbm4ga2VpbiBTdHJpbmcgZnVlcnMgI2RlZmluZSBhbmdlZ2ViZW4gd3VyZGUsIGRhbm4gZGlyZWt0IElEIHZlcndlbmRlbgorICAgICAgLy9tICs9IChbUF9ERUZTVFI6bG93ZXJzdHJpbmcoaWQpWzQuLl1dKTsKKyAgICB9CisgIH0KKyAgLy8gRGllIE5hbWVuCisgIGlmICh2YWwgPSBjb252TWF0TmFtZXMoZGVzY1siTmFtZSJdKSkgeworICAgIG0gKz0gKFtQX05BTUU6dmFsXSk7CisgIH0gZWxzZSB7CisgICAgTURFU0NfV0FSTihpZCwgImtlaW5lIE5hbWVuIik7CisgICAgbSArPSAoW1BfTkFNRTooeyIiLCAiIiwgIiIsICIifSldKTsKKyAgfQorICAvLyBEYXMgR2VzY2hsZWNodCwgc3RhbmRhcmQgaXN0IE5FVVRFUgorICBtICs9IChbUF9HRU5ERVI6Y29udk1hdEdlbmRlcihkZXNjWyJHZXNjaGxlY2h0Il0pIF0pOworICAvLyBEaWUgQmVzY2hyZWlidW5nCisgIHZhbCA9IGNvbnZNYXREZXNjKGRlc2NbIkJlc2NocmVpYnVuZyJdKTsKKyAgaWYgKHNpemVvZih2YWwpKSB7CisgICAgbSArPSAoW1BfREVTQ1JJUFRJT046dmFsXSk7CisgIH0gZWxzZSB7CisgICAgTURFU0NfV0FSTihpZCwgImtlaW5lIEJlc2NocmVpYnVuZyIpOworICB9CisgIC8vIERpZSBFcmtlbm5iYXJrZWl0CisgIHZhbCA9IGNvbnZNYXRSZWMoZGVzY1siRXJrZW5uYmFya2VpdCJdKTsKKyAgaWYgKHNpemVvZih2YWwpKSB7CisgICAgbSArPSAoW1BfUkVDT0M6dmFsXSk7CisgIH0KKyAgLy8gdW5kIHp1bSBTY2hsdXNzIGRpZSBHcnVwcGVuenVnZWhvZXJpZ2tlaXQKKyAgdmFsID0gY29udk1hdEdyb3VwcyhkZXNjWyJHcnVwcGVuenVnZWhvZXJpZ2tlaXQiXSk7CisgIGlmIChtYXBwaW5ncCh2YWwpICYmIHNpemVvZih2YWwpKSB7CisgICAgbSArPSAoW1BfTUdfRlJBQ1RJT05TOnZhbF0pOworICB9CisgIHJldHVybiBtOworfQorcHJpdmF0ZSB2YXJhcmdzIG1peGVkIHJlYWRNYXRlcmlhbERlc2Moc3RyaW5nIGlkKSB7CisgIG1peGVkIG07CisgIHN0cmluZyBmbjsKKyAgZm4gPSBNQVRfRElSKyIvbWF0ZXJpYWxzLyIraWQ7CisgIGlmIChmaWxlX3NpemUoZm4pID4gMCkgeworICAgIG1hcHBpbmcgcGFydHM7CisgICAgc3RyaW5nIGRlc2M7CisgICAgcGFydHMgPSBnZXREZXNjUGFydHMocmVhZF9maWxlKGZuKSk7CisgICAgbSA9IGNvbnZNYXRlcmlhbERlc2MoaWQsIHBhcnRzKTsKKyAgfSBlbHNlIHsKKyAgICBMT0dfRVJST1Ioc3ByaW50ZigiTURCOkthbm4gTWF0ZXJpYWxiZXNjaHJlaWJ1bmcgJXMgbmljaHQgbGFkZW5cbiIsIGZuKSk7CisgIH0KKyAgcmV0dXJuIG07Cit9CisKK3B1YmxpYyBpbnQgR2V0VXBkYXRlVGlja3MoKSB7CisgIHJldHVybiB1cGRhdGVUaWNrczsKK30KKworcHJpdmF0ZSB2b2lkIHNjYW5GaW5pc2hlZCgpIHsKKyAgaXNTY2FubmluZyA9IDA7CisgIGluaXRpYWxpemVkID0gMTsKKyAgLy8gTWFwcGluZ3MgdW1rb3BpZXJlbgorICBtYXRlcmlhbHMgPSBuZXdfbWF0ZXJpYWxzOworICBtYXRlcmlhbF9ncm91cHMgPSBuZXdfbWF0ZXJpYWxfZ3JvdXBzOworICAvLyBMZXR6dGVyIFNjaHJpdHQ6IE1hcHBpbmcgbWl0IGFsdGVuIFNjaGx1ZXNzZWxuIGFubGVnZW4KKyAgb2xkX21hdF9rZXlzID0gbWttYXBwaW5nKG1hcChtX2luZGljZXMobWF0ZXJpYWxzKSwgIydtYXRLZXkyRGVmc3RyLCBtYXRlcmlhbHMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgbV9pbmRpY2VzKG1hdGVyaWFscykpOworICAvLyBHZW5lcmllcmVuIGRlciBEb2t1IHVuZCBkZXMgTWF0ZXJpYWxoZWFkZXJzCisgIEdlbkhlYWRlckZpbGUoKTsKKyAgR2VuTWF0TGlzdCgpOworICBHZW5NYXRHcm91cExpc3QoKTsKKyAgLy8gU2F2ZWZpbGUgc2NocmVpYmVuCisgIHNhdmVfb2JqZWN0KFNBVkVGSUxFKTsKK30KKworcHVibGljIGludCBJc1NjYW5uaW5nKCkgeworICByZXR1cm4gaXNTY2FubmluZzsKK30KKworcHJpdmF0ZSB2YXJhcmdzIHZvaWQgZG9TY2FuTWF0ZXJpYWxzKHN0cmluZyogbWF0cywgaW50IGksIGludCBzdGVwKSB7CisgIGludCB0aWNrcywgc3RhcnQ7CisgIHN0cmluZyBtYXRpZDsKKyAgc3RhcnQgPSBnZXRfZXZhbF9jb3N0KCk7CisgIGlmIChzdGVwIDwgMikgeworICAgIHdoaWxlICggKGkgPCBzaXplb2YobWF0cykpICYmCisgICAgICAgICAgICAoKHN0YXJ0IC0gZ2V0X2V2YWxfY29zdCgpKSA8IHF1ZXJ5X2xpbWl0cygpW0xJTUlUX0VWQUxdLzMgKSApIHsKKyAgICAgIG1hdGlkID0gbWF0c1tpXTsKKyAgICAgIHN3aXRjaCAoc3RlcCkgeworICAgICAgY2FzZSAwOgorICAgICAgICAvLyBFcnN0ZXIgU2Nocml0dDogRWlubGVzZW4gZGVyIERhdGVpZW4KKyAgICAgICAgbmV3X21hdGVyaWFsc1ttYXRpZF0gPSByZWFkTWF0ZXJpYWxEZXNjKG1hdGlkKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDE6CisgICAgICAgIC8vIFp3ZWl0ZXIgU2Nocml0dDogQmVhcmJlaXRlbiBkZXIgRXJrZW5udW5nIHVuZCBHcnVwcGVuenVnZWhvZXJpZ2tlaXQKKyAgICAgICAgdXBkYXRlR3JvdXBNZW1iZXJzKG5ld19tYXRlcmlhbF9ncm91cHMsIG1hdGlkLCBuZXdfbWF0ZXJpYWxzW21hdGlkXSk7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBpKys7CisgICAgfQorICB9CisgIGlmIChpIDwgc2l6ZW9mKG1hdHMpKSB7CisgICAgY2F0Y2gocmFpc2VfZXJyb3Ioc3ByaW50ZigiTWF0ZXJpYWxEQjogSW5pdGlhbGlzaWVydW5nIG5vY2ggbmljaHQgYmVlbmRldCwiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGZlaGxlbmRlIE1hdGVyaWFsYmVzY2hyZWlidW5nZW4gbW9lZ2xpY2giCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIChQaGFzZSAlZDolZC8lZClcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGVwLCBpLCBzaXplb2YobWF0cykpKTtwdWJsaXNoKTsKKyAgICBjYWxsX291dCgjJ2RvU2Nhbk1hdGVyaWFscywgMiwgbWF0cywgaSwgc3RlcCk7CisgIH0gZWxzZSB7CisgICAgLy8gWndlaXRlIFN0dWZlIGF1c2xvZXNlbiBvZGVyIGJlZW5kZW4KKyAgICBpZiAoc3RlcCA8IDEpIHsKKyAgICAgIGlmICgoc3RhcnQgLSBnZXRfZXZhbF9jb3N0KCkpIDwgcXVlcnlfbGltaXRzKClbTElNSVRfRVZBTF0vMiApCisgICAgICAgICAgZG9TY2FuTWF0ZXJpYWxzKG1hdHMsIDAsIHN0ZXArMSk7CisgICAgICBlbHNlCisgICAgICAgICAgY2FsbF9vdXQoIydkb1NjYW5NYXRlcmlhbHMsIDIsIG1hdHMsIDAsIHN0ZXArMSk7CisgICAgfQorICAgIGVsc2UKKyAgICAgIHNjYW5GaW5pc2hlZCgpOworICB9CisgIHVwZGF0ZVRpY2tzICs9IHN0YXJ0IC0gZ2V0X2V2YWxfY29zdCgpOworfQorCitwcml2YXRlIG1hcHBpbmcgU2Nhbkdyb3VwcygpIHsKKyAgbWFwcGluZyBncm91cHM7CisgIHN0cmluZyogZ3JwZmlsZXM7CisgIGdyb3VwcyA9IChbXSk7CisgIGdycGZpbGVzID0gZmlsdGVyKGdldF9kaXIoTUFUX0RJUisiL2dyb3Vwcy9NQVRHUk9VUF8qIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICMnaXNGaWxlLCBNQVRfRElSKyIvZ3JvdXBzIik7CisgIGdyb3VwcyA9IG1rbWFwcGluZyhncnBmaWxlcywgbWFwKGdycGZpbGVzLCAjJ3JlYWRHcm91cERlc2MsIDEpKTsKKyAgcmV0dXJuIGdyb3VwczsKK30KKworcHJpdmF0ZSB2b2lkIFNjYW5NYXRlcmlhbHMoKSB7CisgIHN0cmluZyAqbWF0ZmlsZXM7CisgIG1hdGZpbGVzID0gZmlsdGVyKGdldF9kaXIoTUFUX0RJUisiL21hdGVyaWFscy9NQVRfKiIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAjJ2lzRmlsZSwgTUFUX0RJUisiL21hdGVyaWFscyIpOworICBkb1NjYW5NYXRlcmlhbHMobWF0ZmlsZXMpOworfQorCit2b2lkIFVwZGF0ZSgpIHsKKyAgaW50IHN0YXJ0OworICB1cGRhdGVUaWNrcyA9IDA7CisgIHN0YXJ0ID0gZ2V0X2V2YWxfY29zdCgpOworICBpZiAoIWlzU2Nhbm5pbmcpIHsKKyAgICBpZiAoc2l6ZW9mKGdldF9kaXIoTUFUX0RJUikpKSB7CisgICAgICBpc1NjYW5uaW5nID0gMTsKKyAgICAgIG5ld19tYXRlcmlhbF9ncm91cHMgPSBTY2FuR3JvdXBzKCk7CisgICAgICBuZXdfbWF0ZXJpYWxzID0gKFtdKTsKKyAgICAgIHVwZGF0ZVRpY2tzID0gc3RhcnQgLSBnZXRfZXZhbF9jb3N0KCk7CisgICAgICBTY2FuTWF0ZXJpYWxzKCk7CisgICAgfSBlbHNlIHsKKyAgICAgIExPR19FUlJPUigiS2FubiBNYXRlcmlhbHZlcnplaWNobmlzIG5pY2h0IGZpbmRlbiwga2VpbmUgTWF0ZXJpYWxpZW4gYW5nZWxlZ3QhXG4iKTsKKyAgICB9CisgIH0KK30K