ZGlmZiAtLWdpdCBhL3NlY3VyZS9zaW11bF9lZnVuL3NpbXVsX2VmdW4uYyBiL3NlY3VyZS9zaW11bF9lZnVuL3NpbXVsX2VmdW4uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NGUwYjc4Ci0tLSAvZGV2L251bGwKKysrIGIvc2VjdXJlL3NpbXVsX2VmdW4vc2ltdWxfZWZ1bi5jCkBAIC0wLDAgKzEsMjAxNiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHNpbXVsX2VmdW4uYyAtLSBzaW11bCBlZnVuJ3MKKy8vCisvLyAkSWQ6IHNpbXVsX2VmdW4uYyA3NDA4IDIwMTAtMDItMDYgMDA6Mjc6MjVaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJpY3RfdHlwZXMsc2F2ZV90eXBlcyxydHRfY2hlY2tzCisjcHJhZ21hIG5vX2Nsb25lLG5vX3NoYWRvdyxub19pbmhlcml0CisjcHJhZ21hIHBlZGFudGljLHJhbmdlX2NoZWNrLHdhcm5fZGVwcmVjYXRlZAorI3ByYWdtYSB3YXJuX2VtcHR5X2Nhc3RzLHdhcm5fbWlzc2luZ19yZXR1cm4sd2Fybl9mdW5jdGlvbl9pbmNvbnNpc3RlbnQKKworLy8gQWJzb2x1dGUgUGZhZGUgZXJmb3JkZXJsaWNoIC0genVtIFplaXRwdW5rdCwgd28gZGVyIE1hc3RlciBnZWxhZGVuCisvLyB3aXJkLCBzaW5kIG5vY2gga2VpbmUgSW5jbHVkZS1QZmFkZSBkYSAuLi4KKworI2RlZmluZSBTTk9PUExPR0ZJTEUgIlNOT09QIgorI2RlZmluZSBBU05PT1BMT0dGSUxFICJBUkNIL1NOT09QIgorCisjaW5jbHVkZSAiL3NlY3VyZS9jb25maWcuaCIKKyNpbmNsdWRlICIvc2VjdXJlL3dpemxldmVscy5oIgorI2luY2x1ZGUgIi9zeXMvc25vb3BpbmcuaCIKKyNpbmNsdWRlICIvc3lzL2xhbmd1YWdlLmgiCisjaW5jbHVkZSAiL3N5cy90aGluZy9wcm9wZXJ0aWVzLmgiCisjaW5jbHVkZSAiL3N5cy93aXpsaXN0LmgiCisjaW5jbHVkZSAiL3N5cy9lcnEuaCIKKyNpbmNsdWRlICIvc3lzL2xwY3R5cGVzLmgiCisjaW5jbHVkZSAiL3N5cy9kYWVtb24uaCIKKyNpbmNsdWRlICIvc3lzL3BsYXllci9iYXNlLmgiCisjaW5jbHVkZSAiL3N5cy90aGluZy9kZXNjcmlwdGlvbi5oIgorI2luY2x1ZGUgIi9zeXMvY29udGFpbmVyLmgiCisjaW5jbHVkZSAiL3N5cy9kZWZpbmVzLmgiCisjaW5jbHVkZSAiL3N5cy90ZWxuZXQuaCIKKyNpbmNsdWRlICIvc3lzL29iamVjdGluZm8uaCIKKyNpbmNsdWRlICIvc3lzL2ZpbGVzLmgiCisjaW5jbHVkZSAiL3N5cy9zdHJpbmdzLmgiCisjaW5jbHVkZSAiL3N5cy90aW1lLmgiCisjaW5jbHVkZSAiL3N5cy9scGN0eXBlcy5oIgorI2luY2x1ZGUgIi9zeXMvbm90aWZ5X2ZhaWwuaCIKKyNpbmNsdWRlICIvc3lzL3Rscy5oIgorI2luY2x1ZGUgIi9zeXMvaW5wdXRfdG8uaCIKKyNpbmNsdWRlICIvc3lzL29iamVjdF9pbmZvLmgiCisKKy8qIGZ1bmN0aW9uIHByb3RvdHlwZXMKKyAqLworc3RyaW5nIGR0aW1lKGludCB3YW5uKTsKK3ZhcmFyZ3MgaW50IGxvZ19maWxlKHN0cmluZyBmaWxlLCBzdHJpbmcgdHh0LCBpbnQgc2l6ZV90b19icmVhayk7CitpbnQgcXVlcnlfd2l6X2xldmVsKG1peGVkIHBsYXllcik7Citub21hc2sgdmFyYXJncyBpbnQgc25vb3Aob2JqZWN0IG1lLCBvYmplY3QgeW91KTsKK3ZhcmFyZ3Mgc3RyaW5nIGNvdW50cnkobWl4ZWQgaXAsIHN0cmluZyBudW0pOworaW50IHF1ZXJ5X3dpel9ncnAobWl4ZWQgd2l6KTsKK3B1YmxpYyB2YXJhcmdzIG9iamVjdCBkZWVwX3ByZXNlbnQobWl4ZWQgd2hhdCwgb2JqZWN0IG9iKTsKK25vbWFzayBpbnQgc2VjdXJlX2xldmVsKCk7Citub21hc2sgc3RyaW5nIHNlY3VyZV9ldWlkKCk7CitwdWJsaWMgbm9tYXNrIGludCBwcm9jZXNzX2NhbGwoKTsKK25vbWFzayBtaXhlZCBfX2NyZWF0ZV9wbGF5ZXJfZHVtbXkoc3RyaW5nIG5hbWUpOwordmFyYXJncyBzdHJpbmcgcmVwbGFjZV9wZXJzb25hbChzdHJpbmcgc3RyLCBtaXhlZCAqb2JzLCBpbnQgY2Fwcyk7CisKKworLy9yZXBsYWNlbWVudHMgZm9yIGRyb3BwZWQgZWZ1bnMgaW4gTEQKKyNpZiAhX19FRlVOX0RFRklORURfXyhleHRyYWN0KQordmFyYXJncyBzdHJpbmcgZXh0cmFjdChzdHJpbmcgc3RyLCBpbnQgZnJvbSwgaW50IHRvKTsKKyNlbmRpZgorI2lmICFfX0VGVU5fREVGSU5FRF9fKHNsaWNlX2FycmF5KQordmFyYXJncyBtaXhlZCBzbGljZV9hcnJheShtaXhlZCBhcnJheSwgaW50IGZyb20sIGludCB0byk7CisjZW5kaWYKKyNpZiAhX19FRlVOX0RFRklORURfXyhtZW1iZXJfYXJyYXkpCitpbnQgbWVtYmVyX2FycmF5KG1peGVkIGl0ZW0sIG1peGVkIGFycmF5c3RyaW5nKTsKKyNlbmRpZgorCisvLyBJbmNsdWRlIHRoZSBkaWZmZXJlbnQgc3ViICdtb2R1bGVzJyBvZiB0aGUgc2ltdWxfZWZ1bgorI2luY2x1ZGUgX19ESVJfXyJkZWJ1Z19pbmZvLmMiCisjaW5jbHVkZSBfX0RJUl9fImVuYWJsZV9jb21tYW5kcy5jIgorI2luY2x1ZGUgX19ESVJfXyJoYXNoLmMiCisjaW5jbHVkZSBfX0RJUl9fIm9iamVjdF9pbmZvLmMiCisjaW5jbHVkZSBfX0RJUl9fInF1ZXJ5X2VkaXRpbmcuYyIKKyNpbmNsdWRlIF9fRElSX18icXVlcnlfaWRsZS5jIgorI2luY2x1ZGUgX19ESVJfXyJxdWVyeV9pbnB1dF9wZW5kaW5nLmMiCisjaW5jbHVkZSBfX0RJUl9fInF1ZXJ5X2lwX25hbWUuYyIKKyNpbmNsdWRlIF9fRElSX18icXVlcnlfbGltaXRzLmMiCisjaW5jbHVkZSBfX0RJUl9fInF1ZXJ5X2xvYWRfYXZlcmFnZS5jIgorI2luY2x1ZGUgX19ESVJfXyJxdWVyeV9tdWRfcG9ydC5jIgorI2luY2x1ZGUgX19ESVJfXyJxdWVyeV9vbmNlX2ludGVyYWN0aXZlLmMiCisjaW5jbHVkZSBfX0RJUl9fInF1ZXJ5X3Nub29wLmMiCisjaW5jbHVkZSBfX0RJUl9fInNldF9oZWFydF9iZWF0LmMiCisjaWYgX19CT09UX1RJTUVfXyA8IDE0NTYyNjE4NTkKKyNpbmNsdWRlIF9fRElSX18ic2V0X3Byb21wdC5jIgorI2VuZGlmCisjaW5jbHVkZSBfX0RJUl9fInNoYWRvdy5jIgorI2luY2x1ZGUgX19ESVJfXyJsaXZpbmdzLmMiCisjaW5jbHVkZSBfX0RJUl9fImNvbW0uYyIKKworI2RlZmluZSBUTyAgICAgICAgZWZ1bjo6dGhpc19vYmplY3QoKQorI2RlZmluZSBUSSAgICAgICAgZWZ1bjo6dGhpc19pbnRlcmFjdGl2ZSgpCisjZGVmaW5lIFRQICAgICAgICBlZnVuOjp0aGlzX3BsYXllcigpCisjZGVmaW5lIFBPICAgICAgICBlZnVuOjpwcmV2aW91c19vYmplY3QoMCkKKyNkZWZpbmUgTEVWRUwoeCkgcXVlcnlfd2l6X2xldmVsKHgpCisjZGVmaW5lIE5BTUUoeCkgIGNhcGl0YWxpemUoZ2V0dWlkKHgpKQorCisjZGVmaW5lIERFQlVHKHgpIGlmIChmaW5kX3BsYXllcigiemVzc3RyYSIpKSBcCisgIHRlbGxfb2JqZWN0KGZpbmRfcGxheWVyKCJ6ZXNzdHJhIikseCkKKworbWl4ZWQgZHRpbWVfY2FjaGUgPSAoey0xLCIifSk7CisKKyNpZmRlZiBJT1NUQVRTCitzdHJ1Y3QgaW9zdGF0X3MgeworICBzdHJpbmcgb25hbWU7CisgIGludCB0aW1lOworICBpbnQgc2l6ZTsKK307CittaXhlZCBzYXZlb19zdGF0ID0gKHsgMCxhbGxvY2F0ZSgyMDAsIDApIH0pOworbWl4ZWQgcmVzdG9yZW9fc3RhdCA9ICh7IDAsYWxsb2NhdGUoMjAwLDApIH0pOworLy9taXhlZCB3cml0ZWZpbGVfc3RhdCA9ICh7IDAsYWxsb2NhdGUoMTAwLCg8aW9zdGF0X3M+KSkgfSk7CisvL21peGVkIHJlYWRmaWxlX3N0YXQgPSAoeyAwLGFsbG9jYXRlKDEwMCwoPGlvc3RhdF9zPikpIH0pOworLy9taXhlZCBsb2dfc3RhdCA9ICh7IDAsYWxsb2NhdGUoMTAwLCg8aW9zdGF0X3M+KSkgfSk7CisKK21peGVkIF9fX2lvc3RhdHMoaW50IHR5cGUpIHsKKyAgc3dpdGNoKHR5cGUpIHsKKyAgICBjYXNlIDE6CisgICAgICByZXR1cm4gc2F2ZW9fc3RhdDsKKyAgICBjYXNlIDI6CisgICAgICByZXR1cm4gcmVzdG9yZW9fc3RhdDsKKy8qICAgIGNhc2UgMzoKKyAgICAgIHJldHVybiB3cml0ZWZpbGVfc3RhdDsKKyAgICBjYXNlIDQ6CisgICAgICByZXR1cm4gcmVhZGZpbGVfc3RhdDsKKyAgICBjYXNlIDU6CisgICAgICByZXR1cm4gbG9nX3N0YXQ7CisgICAgICAqLworICB9CisgIHJldHVybiAwOworfQorI2VuZGlmCisKKy8vIE5pY2h0IGplZGVyIE1hZ2llciBtdXNzIGRpZSBzaW11bF9lZnVuIGVudHNvcmdlbiBrb2VubmVuLgorc3RyaW5nIE5vdGlmeURlc3RydWN0KG9iamVjdCBjYWxsZXIpIHsKKyAgICBpZiggKGNhbGxlciE9dGhpc19vYmplY3QoKSAmJiAhQVJDSF9TRUNVUklUWSkgfHwgcHJvY2Vzc19jYWxsKCkgKSB7CisgICAgICByZXR1cm4gIkR1IGRhcmZzdCBkYXMgc2ltdWxfZWZ1biBPYmpla3QgbmljaHQgemVyc3RvZXJlbiFcbiI7CisgICAgfQorICAgIHJldHVybiAwOworfQorCitwdWJsaWMgbm9tYXNrIHZvaWQgcmVtb3ZlX2ludGVyYWN0aXZlKCBvYmplY3Qgb2IgKQoreworICAgIGlmICggb2JqZWN0cChvYikgJiYgcHJldmlvdXNfb2JqZWN0KCkKKyAgICAgICAgJiYgb2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpWzAuLjddICE9ICIvc2VjdXJlLyIKKyAgICAgICAgJiYgKChwcmV2aW91c19vYmplY3QoKSAhPSBvYgorICAgICAgICAgICAgICYmIChvYiAhPSB0aGlzX3BsYXllcigpIHx8IG9iICE9IHRoaXNfaW50ZXJhY3RpdmUoKSkpCisgICAgICAgICAgICB8fCAocHJldmlvdXNfb2JqZWN0KCkgPT0gb2IKKyAgICAgICAgICAgICAgICYmICh0aGlzX3BsYXllcigpICYmIHRoaXNfcGxheWVyKCkgIT0gb2IKKyAgICAgICAgICAgICAgICAgICB8fCB0aGlzX2ludGVyYWN0aXZlKCkgJiYgdGhpc19pbnRlcmFjdGl2ZSgpICE9IG9iKSkgKSApCisKKyAgICAgICBsb2dfZmlsZSggIlBMQVlFUkRFU1QiLAorICAgICAgICAgICAgICAgIHNwcmludGYoICIlczogJU8gYXVzZ2Vsb2dndCB2b24gUE8gJU8sIFRJICVPLCBUUCAlT1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGR0aW1lKHRpbWUoKSksIG9iLCBwcmV2aW91c19vYmplY3QoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfaW50ZXJhY3RpdmUoKSwgdGhpc19wbGF5ZXIoKSApICk7CisKKyAgICBlZnVuOjpyZW1vdmVfaW50ZXJhY3RpdmUob2IpOworfQorCisKK3ZvaWQgX19fdXBkbWFzdGVyKCkKK3sKKyAgICBvYmplY3Qgb2I7CisKKyAgICAvL3NvbGx0ZSBuaWNodCBqZWRlciBkdWVyZmVuLgorICAgIGlmIChwcm9jZXNzX2NhbGwoKSB8fCAhQVJDSF9TRUNVUklUWSkKKyAgICAgIHJhaXNlX2Vycm9yKCJJbGxlZ2FsIHVzZSBvZiBfX191cGRtYXN0ZXIoKSEiKTsKKworICAgIHdyaXRlKCJSZW1vdmluZyBvbGQgbWFzdGVyIC4uLiAiKTsKKyAgICBmb3JlYWNoKHN0cmluZyBmaWxlOiAKKyAgICAgICAgZ2V0X2RpcigiL3NlY3VyZS9tYXN0ZXIvKi5jIixHRVRESVJfTkFNRVN8R0VURElSX1VOU09SVEVEfEdFVERJUl9QQVRIKSkgeworICAgICAgaWYgKG9iID0gZmluZF9vYmplY3QoZmlsZSkpCisgICAgICAgZWZ1bjo6ZGVzdHJ1Y3Qob2IpOworICAgIH0KKyAgICBlZnVuOjpkZXN0cnVjdChlZnVuOjpmaW5kX29iamVjdCgiL3NlY3VyZS9tYXN0ZXIiKSk7CisgICAgd3JpdGUoImRvbmUuXG5Mb2FkaW5nIGFnYWluIC4uLiAiKTsKKyAgICBsb2FkX29iamVjdCgiL3NlY3VyZS9tYXN0ZXIiKTsKKworICAgIHdyaXRlKCJkb25lLlxuIik7Cit9CisKK3ZhcmFyZ3Mgc3RyaW5nIGNvdW50cnkobWl4ZWQgaXAsIHN0cmluZyBudW0pIHsKKyAgbWl4ZWQgcmV0OworCisgIGlmKHJldCA9IChzdHJpbmcpIi9wL2RhZW1vbi9pcGxvb2t1cCItPmNvdW50cnkobnVtIHx8IGlwKSkgeworICAgIHJldHVybiByZXQ7CisgIH0gZWxzZSByZXR1cm4gIj8/PyI7Cit9CisKKworLy8gKiBTbm9vcGVuIHVuZCB3YXMgZGF6dWdlaG9lcnQKK3N0YXRpYyBvYmplY3QgZmluZF9zbm9vcGVkKG9iamVjdCB3aG8pCit7CisgIG9iamVjdCAqdTsKKyAgaW50IGk7CisKKyAgZm9yIChpPXNpemVvZih1PXVzZXJzKCkpLTE7aT49MDtpLS0pCisgICAgaWYgKHdobz09ZWZ1bjo6aW50ZXJhY3RpdmVfaW5mbyh1W2ldLCBJSV9TTk9PUF9ORVhUKSkKKyAgICAgIHJldHVybiB1W2ldOworICByZXR1cm4gMDsKK30KKworcHJpdmF0ZSBzdHJpbmcgTGN1dChzdHJpbmcgc3RyKSB7CisgIHJldHVybiBzdHJbNS4uMTFdK3N0clsxOC4uXTsKK30KKworbm9tYXNrIHZhcmFyZ3MgaW50IHNub29wKCBvYmplY3QgbWUsIG9iamVjdCB5b3UgKQoreworICAgIGludCByZXQ7CisgICAgb2JqZWN0IHNub29wZXIwLCBzbm9vcGVyLCBzbm9vcGVyMiwgc25vb3BlcjM7CisKKyAgICBpZiggIW9iamVjdHAobWUpIHx8IG1lID09IHlvdSB8fCAhUE8gKQorICAgICAgIHJldHVybiAwOworCisgICAgc25vb3BlcjAgPSBmaW5kX3Nub29wZWQobWUpOworCisgICAgIGlmKHlvdSl7CisgICAgICAgIGlmICggUE8gIT0gbWUgJiYgcXVlcnlfd2l6X2dycChtZSkgPj0gcXVlcnlfd2l6X2dycChnZXRldWlkKFBPKSkgKQorICAgICAgICAgICAgcmV0dXJuIDA7CisKKyAgICAgICAgaWYgKCBxdWVyeV93aXpfZ3JwKG1lKSA8PSBxdWVyeV93aXpfZ3JwKHlvdSkgJiYKKyAgICAgICAgICAgICAhKHlvdS0+UXVlcnlBbGxvd1Nub29wKG1lKSkgKQorICAgICAgICAgICAgaWYgKCAhSVNfREVQVVRZKG1lKSB8fCBJU19BUkNIKHlvdSkgKQorICAgICAgICAgICAgICAgcmV0dXJuIDA7CisKKyAgICAgICAgaWYgKCAoc25vb3BlciA9IGVmdW46OmludGVyYWN0aXZlX2luZm8oeW91LCBJSV9TTk9PUF9ORVhUKSkgJiYKKyAgICAgICAgICAgICBxdWVyeV93aXpfZ3JwKHNub29wZXIpID49IHF1ZXJ5X3dpel9ncnAobWUpICl7CisgICAgICAgICAgICBpZiAoIChpbnQpc25vb3Blci0+UXVlcnlQcm9wKFBfU05PT1BGTEFHUykgJiBTRl9MT0NLRUQgKQorICAgICAgICAgICAgICAgcmV0dXJuIDA7CisKKyAgICAgICAgICAgIHRlbGxfb2JqZWN0KCBzbm9vcGVyLCBzcHJpbnRmKCAiJXMgc25vb3BlZCBqZXR6dCAlcy5cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZS0+bmFtZShXRVIpLCB5b3UtPm5hbWUoV0VSKSApICk7CisKKyAgICAgICAgICAgIHNub29wZXIyID0gbWU7CisKKyAgICAgICAgICAgIHdoaWxlICggc25vb3BlcjMgPSBpbnRlcmFjdGl2ZV9pbmZvKHNub29wZXIyLCBJSV9TTk9PUF9ORVhUKSApeworICAgICAgICAgICAgICAgdGVsbF9vYmplY3QoIHNub29wZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCAiJXMgd2lyZCBzZWluZXJzZWl0cyB2b24gJXMgZ2Vzbm9vcGVkLlxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAsc25vb3BlcjItPm5hbWUoV0VSKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25vb3BlcjMtPm5hbWUoV0VNKSApICk7CisgICAgICAgICAgICAgICBzbm9vcGVyMiA9IHNub29wZXIzOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBlZnVuOjpzbm9vcCggc25vb3Blciwgc25vb3BlcjIgKTsKKworICAgICAgICAgICAgaWYgKCBlZnVuOjppbnRlcmFjdGl2ZV9pbmZvKHNub29wZXIyLCBJSV9TTk9PUF9ORVhUKSAhPSBzbm9vcGVyICkKKyAgICAgICAgICAgICAgIHRlbGxfb2JqZWN0KCBzbm9vcGVyLCBzcHJpbnRmKCAiRHUga2FubnN0ICVzIG5pY2h0IHNub29wZW4uXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25vb3BlcjItPm5hbWUoV0VOKSApICk7CisgICAgICAgICAgICBlbHNleworICAgICAgICAgICAgICAgdGVsbF9vYmplY3QoIHNub29wZXIsIHNwcmludGYoICJEdSBzbm9vcHN0IGpldHp0ICVzLlxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNub29wZXIyLT5uYW1lKFdFTikgKSApOworICAgICAgICAgICAgICAgaWYgKCAhSVNfREVQVVRZKHNub29wZXIpICl7CisgICAgICAgICAgICAgICAgICAgbG9nX2ZpbGUoIFNOT09QTE9HRklMRSwgc3ByaW50ZigiJXM6ICVPICVPICVPXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdGltZSh0aW1lKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm9vcGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm9vcGVyMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQoc25vb3BlcjIpICksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTAwMDAwICk7CisgICAgICAgICAgICAgICAgICAgaWYgKHNub29wZXIwKQorICAgICAgICAgICAgICAgICAgICAgIENITUFTVEVSLT5zZW5kKCAiU25vb3AiLCBzbm9vcGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZiggIiVzICpPRkYqICVzICglTykiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKGdldHVpZChzbm9vcGVyKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKHNub29wZXIwKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50KHNub29wZXIwKSApICk7CisKKyAgICAgICAgICAgICAgICAgICBDSE1BU1RFUi0+c2VuZCggIlNub29wIiwgc25vb3BlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoIiVzIC0+ICVzICglTykiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKHNub29wZXIpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKGdldHVpZChzbm9vcGVyMikpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50KHNub29wZXIyKSkpOworICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgZWxzZXsKKyAgICAgICAgICAgICAgICAgICBsb2dfZmlsZSggQVNOT09QTE9HRklMRSwgc3ByaW50ZiggIiVzOiAlTyAlTyAlT1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdGltZSh0aW1lKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNub29wZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25vb3BlcjIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQoc25vb3BlcjIpICkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAsMTAwMDAwICk7CisgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICAgICAgaWYgKHNub29wZXIpCisgICAgICAgICAgICAgICBpZiAoICFtZS0+UXVlcnlQcm9wKFBfU05PT1BGTEFHUykgJiBTRl9MT0NLRUQgKXsKKyAgICAgICAgICAgICAgICAgICBwcmludGYoICIlcyB3aXJkIGJlcmVpdHMgdm9uICVzIGdlc25vb3BlZC4gQmVudXR6ZSBkYXMgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAiXCJmXCItRmxhZywgd2VubiBkdSBkZW5ub2NoIHNub29wZW4gd2lsbHN0LlxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgeW91LT5uYW1lKFdFUiksIHNub29wZXItPm5hbWUoV0VNKSApOworICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgICAgfQorCisgICAgICAgIHJldCA9IGVmdW46OnNub29wKCBtZSwgeW91ICk7CisKKyAgICAgICAgaWYgKCAhSVNfREVQVVRZKG1lKSAmJiBlZnVuOjppbnRlcmFjdGl2ZV9pbmZvKHlvdSwgSUlfU05PT1BfTkVYVCkgPT0gbWUpeworICAgICAgICAgICAgbG9nX2ZpbGUoIFNOT09QTE9HRklMRSwgc3ByaW50ZiggIiVzOiAlTyAlTyAlT1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGN1dChkdGltZSh0aW1lKCkpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWUsIHlvdSwgZW52aXJvbm1lbnQoeW91KSApLAorICAgICAgICAgICAgICAgICAgICAgMTAwMDAwICk7CisKKyAgICAgICAgICAgIGlmIChzbm9vcGVyMCkKKyAgICAgICAgICAgICAgIENITUFTVEVSLT5zZW5kKCAiU25vb3AiLCBtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZiggIiVzICpPRkYqICVzICglTykuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKGdldHVpZChtZSkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKHNub29wZXIwKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQoc25vb3BlcjApICkgKTsKKworICAgICAgICAgICAgQ0hNQVNURVItPnNlbmQoICJTbm9vcCIsIG1lLCBzcHJpbnRmKCAiJXMgLT4gJXMgKCVPKS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShnZXR1aWQobWUpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKHlvdSkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQoeW91KSApICk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZXsKKyAgICAgICAgICAgIGlmICggZWZ1bjo6aW50ZXJhY3RpdmVfaW5mbyh5b3UsIElJX1NOT09QX05FWFQpID09IG1lICl7CisgICAgICAgICAgICAgICBsb2dfZmlsZSggQVNOT09QTE9HRklMRSwgc3ByaW50ZiggIiVzOiAlTyAlTyAlT1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExjdXQoZHRpbWUodGltZSgpKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZSwgeW91LCBlbnZpcm9ubWVudCh5b3UpICksCisgICAgICAgICAgICAgICAgICAgICAgICAxMDAwMDAgKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICggcmV0ICYmIHF1ZXJ5X3dpel9ncnAobWUpIDw9IHF1ZXJ5X3dpel9ncnAoeW91KSAmJgorICAgICAgICAgICAgICFJU19ERVBVVFkobWUpICkKKyAgICAgICAgICAgIHRlbGxfb2JqZWN0KCB5b3UsICIqKiogIiArIE5BTUUobWUpICsgIiBzbm9vcHQgRGljaCFcbiIgKTsKKworICAgICAgICByZXR1cm4gcmV0OworICAgICB9CisgICAgIGVsc2UgeworICAgICAgICBpZiAoIChtZSA9PSBQTyB8fAorICAgICAgICAgICAgICBxdWVyeV93aXpfZ3JwKGdldGV1aWQoUE8pKSA+IHF1ZXJ5X3dpel9ncnAobWUpIHx8CisgICAgICAgICAgICAgIChxdWVyeV93aXpfZ3JwKGdldGV1aWQoUE8pKSA9PSBxdWVyeV93aXpfZ3JwKG1lKSAmJgorICAgICAgICAgICAgICBlZnVuOjppbnRlcmFjdGl2ZV9pbmZvKFBPLCBJSV9TTk9PUF9ORVhUKSA9PSBtZSkpICYmIHNub29wZXIwICl7CisgICAgICAgICAgICBpZiAoICFJU19ERVBVVFkobWUpICl7CisgICAgICAgICAgICAgICBsb2dfZmlsZSggU05PT1BMT0dGSUxFLCBzcHJpbnRmKCAiJXM6ICVPICVPICVPICpPRkYqXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMY3V0KGR0aW1lKHRpbWUoKSkpLCBtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25vb3BlcjAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50KHNub29wZXIwKSApLAorICAgICAgICAgICAgICAgICAgICAgICAgMTAwMDAwICk7CisKKyAgICAgICAgICAgICAgICBDSE1BU1RFUi0+c2VuZCggIlNub29wIiwgbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCAiJXMgKk9GRiogJXMgKCVPKS4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKGdldHVpZChtZSkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKGdldHVpZChzbm9vcGVyMCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudChzbm9vcGVyMCkgKSApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZXsKKyAgICAgICAgICAgICAgIGxvZ19maWxlKCBBU05PT1BMT0dGSUxFLCBzcHJpbnRmKCAiJXM6ICVPICVPICVPICpPRkYqXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTGN1dChkdGltZSh0aW1lKCkpKSwgbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm9vcGVyMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50KHNub29wZXIwKSApLAorICAgICAgICAgICAgICAgICAgICAgICAgMTAwMDAwICk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiBlZnVuOjpzbm9vcChtZSk7CisgICAgICAgIH0KKyAgICAgfQorICAgICByZXR1cm4gMDsKK30KKworCisKKy8vICogRW11bGF0aW9uIGRlcyAnYWx0ZW4nIGV4cGxvZGUgZHVyY2ggZGFzIG5ldWUKK3N0cmluZyAqb2xkX2V4cGxvZGUoc3RyaW5nIHN0ciwgc3RyaW5nIGRlbCkgeworICBpbnQgcywgdDsKKyAgc3RyaW5nICpzdHJzOworCisgIGlmICghc3RyaW5ncChzdHIpKSB7CisgICAgICBzZXRfdGhpc19vYmplY3QocHJldmlvdXNfb2JqZWN0KCkpOworICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICJJbnZhbGlkIGFyZ3VtZW50IDEgdG8gb2xkX2V4cGxvZGUoKSEgRXhwZWN0ZWQgPHN0cmluZz4sIGdvdDogIgorICAgICAgICAgIiUuMzBPXG4iLHN0cikpOworICB9CisgIGlmICghc3RyaW5ncChkZWwpKSB7CisgICAgICBzZXRfdGhpc19vYmplY3QocHJldmlvdXNfb2JqZWN0KCkpOworICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICJJbnZhbGlkIGFyZ3VtZW50IDIgdG8gb2xkX2V4cGxvZGUoKSEgRXhwZWN0ZWQgPHN0cmluZz4sIGdvdDogIgorICAgICAgICAgIiUuMzBPXG4iLGRlbCkpOworICB9CisgIGlmKGRlbCA9PSAiIikKKyAgICByZXR1cm4gKHtzdHJ9KTsKKyAgc3Rycz1lZnVuOjpleHBsb2RlKHN0ciwgZGVsKTsKKyAgdD1zaXplb2Yoc3RycyktMTsKKyAgd2hpbGUoczw9dCAmJiBzdHJzW3MrK10gPT0gIiIpO3MtLTsKKyAgd2hpbGUodD49MCAmJiBzdHJzW3QtLV0gPT0gIiIpO3QrKzsKKyAgaWYoczw9dCkKKyAgICByZXR1cm4gc3Ryc1tzLi50XTsKKyAgcmV0dXJuICh7fSk7Cit9CisKK2ludCBmaWxlX3RpbWUoc3RyaW5nIHBhdGgpIHsKKyAgbWl4ZWQgKnY7CisKKyAgc2V0X3RoaXNfb2JqZWN0KHByZXZpb3VzX29iamVjdCgpKTsKKyAgaWYgKHNpemVvZih2PWdldF9kaXIocGF0aCxHRVRESVJfREFURVMpKSkgcmV0dXJuIHZbMF07CisgIHJldHVybigwKTsgLy9zb25zdAorfQorCisvLyAqIEJlaSA1MGsgR3JvZXNzZSBMb2ctRmlsZSByb3RpZXJlbgordmFyYXJncyBpbnQgbG9nX2ZpbGUoc3RyaW5nIGZpbGUsIHN0cmluZyB0eHQsIGludCBzaXplX3RvX2JyZWFrKSB7CisgIG1peGVkICpzdDsKKworICBmaWxlPSIvbG9nLyIrZmlsZTsKKyAgZmlsZT1pbXBsb2RlKChlZnVuOjpleHBsb2RlKGZpbGUsIi8iKS0oeyIuLiJ9KSksIi8iKTsKKy8vICB0ZWxsX29iamVjdChmaW5kX3BsYXllcigiam9mIiksc3ByaW50ZigiTE9HIEZJTEU6ICVPIC0+ICVPXG4iLHByZXZpb3VzX29iamVjdCgpLGZpbGUpKTsKKyAgaWYgKCFmdW5jYWxsKGJpbmRfbGFtYmRhKCMnZWZ1bjo6Y2FsbF9vdGhlcixQTyksInNlY3VyZS9tYXN0ZXIiLC8vJykKKyAgICAgICAgICAgICAgInZhbGlkX3dyaXRlIixmaWxlLGdldGV1aWQoUE8pLCJsb2dfZmlsZSIsUE8pKQorICAgICAgcmV0dXJuIDA7CisgIGlmICggc2l6ZV90b19icmVhayA+PSAwICYgKAorICAgICAgc2l6ZW9mKHN0ID0gZ2V0X2RpcihmaWxlLDIpICkgJiYgc3RbMF0gPj0gKHNpemVfdG9fYnJlYWt8TUFYX0xPR19TSVpFKSkpCisgICAgICBjYXRjaChyZW5hbWUoZmlsZSwgZmlsZSArICIub2xkIik7cHVibGlzaCk7IC8qIE5vIHBhbmljIGlmIGZhaWx1cmUgKi8KKyAgcmV0dXJuKHdyaXRlX2ZpbGUoZmlsZSx0eHQpKTsKK30KKworLy8gKiBNYWdpZXItTGV2ZWwgYWJmcmFnZW4KK2ludCBxdWVyeV93aXpfbGV2ZWwobWl4ZWQgcGxheWVyKSB7CisgIHJldHVybiAoaW50KSIvc2VjdXJlL21hc3RlciItPnF1ZXJ5X3dpel9sZXZlbChwbGF5ZXIpOworfQorCisjaWZkZWYgX19BTElTVFNfXworLy8gKiBFbGVtZW50IGF1cyBBbGlzdCBsb2VzY2hlbiAoYnkga2V5KQorbWl4ZWQgKnJlbW92ZV9hbGlzdChtaXhlZCBrZXksbWl4ZWQgKmFsaXN0KQoreworICBpbnQgaSxqOworCisgIGlmICghcG9pbnRlcnAoYWxpc3QpIHx8ICFzaXplb2YoYWxpc3QpKQorICAgIHJldHVybiBhbGlzdDsKKyAgaWYgKCFwb2ludGVycChhbGlzdFswXSkpCisgIHsKKyAgICBpZiAoKGk9YXNzb2Moa2V5LGFsaXN0KSk8MCkKKyAgICAgIHJldHVybiBhbGlzdDsKKyAgICByZXR1cm4gYWxpc3RbMC4uaS0xXSthbGlzdFtpKzEuLl07CisgIH0KKyAgaSA9IGFzc29jKGtleSxhbGlzdFswXSk7CisgIGlmICgoaT1hc3NvYyhrZXksYWxpc3RbMF0pKTwwKQorICAgIHJldHVybiBhbGlzdDsKKyAgYWxpc3Q9YWxpc3RbMC4uXTsKKyAgZm9yIChqPXNpemVvZihhbGlzdCktMTtqPj0wO2otLSkKKyAgICBhbGlzdFtqXT1hbGlzdFtqXVswLi5pLTFdK2FsaXN0W2pdW2krMS4uXTsKKyAgcmV0dXJuIGFsaXN0OworfQorCisvLyAqIEVsZW1lbnQgYXVzIEFsaXN0IGxvZXNjaGVuIChieSBwb3MpCittaXhlZCAqZXhjbHVkZV9hbGlzdChpbnQgaSxtaXhlZCAqYWxpc3QpCit7CisgIGludCBqOworICBpZiAoIXBvaW50ZXJwKGFsaXN0KSB8fCAhc2l6ZW9mKGFsaXN0KSB8fCBpPDApCisgICAgcmV0dXJuIGFsaXN0OworICBpZiAoIXBvaW50ZXJwKGFsaXN0WzBdKSkKKyAgICByZXR1cm4gYWxpc3RbMC4uaS0xXSthbGlzdFtpKzEuLl07CisgIGFsaXN0PWFsaXN0WzAuLl07IC8qIENyZWF0ZSBQSFlTSUNBTCBjb3B5IG9mIGFsaXN0ICovCisgIGZvciAoaj1zaXplb2YoYWxpc3QpLTE7aj49MDtqLS0pCisgICAgYWxpc3Rbal09YWxpc3Rbal1bMC4uaS0xXSthbGlzdFtqXVtpKzEuLl07CisgIHJldHVybiBhbGlzdDsgLyogb3JkZXJfYWxpc3QgaXMgTk9UIG5lY2Vzc2FyeSAtIHNlZSAvZG9jL0xQQy9hbGlzdCAqLworfQorI2VuZGlmIC8vIF9fQUxJU1RTX18KKworLy8gKiBHZXJtYW4gdmVyc2lvbiBvZiBjdGltZSgpCisjZGVmaW5lIFRBR0UgKHsiU29uIiwiTW9uIiwiRGllIiwiTWl0IiwiRG9uIiwiRnJlIiwiU2FtIn0pCisjZGVmaW5lIE1PTkFURSAoeyJKYW4iLCJGZWIiLCJNYXIiLCJBcHIiLCJNYWkiLCJKdW4iLCJKdWwiLCJBdWciLFwKKyAgICAgICAgICAgICAgICAgIlNlcCIsIk9rdCIsIk5vdiIsIkRleiJ9KQorc3RyaW5nIGR0aW1lKGludCB3YW5uKSB7CisgIAorICBpZiAod2FubiA9PSBkdGltZV9jYWNoZVswXSkKKyAgICByZXR1cm4oZHRpbWVfY2FjaGVbMV0pOworCisgIGludCAqbHQgPSBsb2NhbHRpbWUod2Fubik7CisgIHJldHVybiBzcHJpbnRmKCIlcywgJTJkLiAlcyAlZCwgJTAyZDolMDJkOiUwMmQiLAorICAgICAgVEFHRVtsdFtUTV9XREFZXV0sIGx0W1RNX01EQVldLCBNT05BVEVbbHRbVE1fTU9OXV0sIAorICAgICAgbHRbVE1fWUVBUl0sbHRbVE1fSE9VUl0sIGx0W1RNX01JTl0sIGx0W1RNX1NFQ10pOworfQorCisvLyB3ZW5uIHN0cmZ0aW1lIGltIERyaXZlciBuaWNodCBleGlzdGllcnQsIGlzdCBkaWVzIGhpZXIgZWluIEFsaWFzIGF1ZiBkdGltZSgpLAorLy8gendhciBzdGltbXQgZGFzIEZvcm1hdCBkYW5uIG5pY2h0LCBhYmVyIGRpZSBNdWRsaWIgYnVnZ3QgbmljaHQgdW5kIHNjaHJlaWJ0CisvLyBlaW4gb3JkZW50bGljaGVzIERhdHVtL1VocnplaXQuCisjaWYgIV9fRUZVTl9ERUZJTkVEX18oc3RyZnRpbWUpCit2YXJhcmdzIHN0cmluZyBzdHJmdGltZShtaXhlZCBmbXQsIGludCBjbG9jaywgaW50IGxvY2FsaXplZCkgeworICBpZiAoaW50cChjbG9jaykgJiYgY2xvY2sgPj0gMCkKKyAgICByZXR1cm4gZHRpbWUoY2xvY2spOworICBlbHNlIGlmIChpbnRwKGZtdCkgJiYgZm10ID49IDApCisgICAgcmV0dXJuIGR0aW1lKGZtdCk7CisgIAorICByZXR1cm4gZHRpbWUodGltZSgpKTsKK30KKyNlbmRpZiAvLyFfX0VGVU5fREVGSU5FRF9fKHN0cmZ0aW1lKQorCisvLyAqIFNodXRkb3duIG1pdCB6dXNhZXR6bGljaGVtIGxvZ2dpbmcKK25vbWFzayBpbnQgc2h1dGRvd24oc3RyaW5nIHJlYXNvbikKK3sKKyAgc3RyaW5nIG5hbWU7CisgIHN0cmluZyBvYm5hbWU7CisgIHN0cmluZyBvdXRwdXQ7CisKKyAgaWYgKCFyZWFzb24pCisgICAgcmV0dXJuIDA7CisgIGlmICggIUFSQ0hfU0VDVVJJVFkgJiYgZ2V0dWlkKHByZXZpb3VzX29iamVjdCgpKSE9Uk9PVElEICYmCisgICAgICAgICAgb2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpIT0iL29iai9zaHV0IiApCisgIHsKKyAgICB3cml0ZSgiWW91IGhhdmUgbm8gcGVybWlzc2lvbiB0byBzaHV0IGRvd24gdGhlIGdhbWVkcml2ZXIhXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBpZiAoKHRoaXNfaW50ZXJhY3RpdmUoKSkmJihuYW1lPWdldHVpZCh0aGlzX2ludGVyYWN0aXZlKCkpKSkKKyAgeworICAgIG5hbWU9Y2FwaXRhbGl6ZShuYW1lKTsKKyAgICBmaWx0ZXIodXNlcnMoKSwjJ3RlbGxfb2JqZWN0LC8vJworICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShuYW1lKSsiIGZhZWhydCBkYXMgU3BpZWwgaGVydW50ZXIhXG4iKTsKKyAgfQorICBlbHNlCisgICAgbmFtZT0iQU5PTllNT1VTIjsKKyAgaWYgKHByZXZpb3VzX29iamVjdCgpKSBvYm5hbWU9Y2FwaXRhbGl6ZShnZXR1aWQocHJldmlvdXNfb2JqZWN0KCkpKTsKKyAgb3V0cHV0PW5hbWU7CisgIGlmIChvYm5hbWUgJiYgbmFtZSE9b2JuYW1lKSBvdXRwdXQ9b3V0cHV0KyIgKCIrb2JuYW1lKyIpIjsKKyAgaWYgKHByZXZpb3VzX29iamVjdCgpJiZvYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSk9PSIvb2JqL3NodXQiKXsKKyAgICBvdXRwdXQrPSIgZmFlaHJ0IGRhcyBTcGllbCB2aWEgQXJtYWdlZGRvbiBoZXJ1bnRlci5cbiI7CisgICAgb3V0cHV0PWR0aW1lKHRpbWUoKSkrIjogIitvdXRwdXQ7CisgICAgbG9nX2ZpbGUoIkdBTUVfTE9HIixvdXRwdXQrIlxuIiwtMSk7CisgICAgZWZ1bjo6c2h1dGRvd24oKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBvdXRwdXQ9Y3RpbWUodGltZSgpKSsiOiAiK291dHB1dCsiIGZhZWhydCBkYXMgU3BpZWwgaGVydW50ZXIuXG4iOworICBvdXRwdXQrPSIgICAgR3J1bmQ6ICIrcmVhc29uOworICBsb2dfZmlsZSgiR0FNRV9MT0ciLG91dHB1dCsiXG4iLC0xKTsKKyAgZWZ1bjo6c2h1dGRvd24oKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vICogbG93ZXJjaGFyCisKK2ludCBsb3dlcmNoYXIoaW50IGNoYXIpIHsKKyAgaWYgKGNoYXI8J0EnIHx8IGNoYXI+J1onKSByZXR1cm4gY2hhcjsKKyAgcmV0dXJuIGNoYXIrMzI7Cit9CisKKy8vICogdXBwZXJzdHJpbmcKKworc3RyaW5nIHVwcGVyc3RyaW5nKHN0cmluZyBzKQoreworI2lmIF9fRUZVTl9ERUZJTkVEX18odXBwZXJfY2FzZSkKKyAgcmV0dXJuKHVwcGVyX2Nhc2UocykpOworI2Vsc2UKKyAgaW50IGk7CisgIGlmICghc3RyaW5ncChzKSkgcmV0dXJuIDA7CisgIGZvciAoaT1zaXplb2YocyktMTtpPj0wO2ktLSkgc1tpXT0oKHNbaV08J2EnfHxzW2ldPid6Jyk/c1tpXTpzW2ldLTMyKTsKKyAgcmV0dXJuIHM7CisjZW5kaWYKK30KKworLy8gKiBsb3dlcnN0cmluZworCitzdHJpbmcgbG93ZXJzdHJpbmcoc3RyaW5nIHMpCit7CisgIGlmICghc3RyaW5ncChzKSkgcmV0dXJuIDA7CisgIHJldHVybiBsb3dlcl9jYXNlKHMpOworfQorCisKKy8vICogR0QgdmVyc2lvbgorc3RyaW5nIHZlcnNpb24oKQoreworICByZXR1cm4gX19WRVJTSU9OX187Cit9CisKKy8vICogYnJlYWtfc3RyaW5nCisvLyBzdHJldGNoKCkgLS0gc3RyZXRjaCBhIGxpbmUgdG8gZmlsbCBhIGdpdmVuIHdpZHRoIAorcHJpdmF0ZSBzdHJpbmcgc3RyZXRjaChzdHJpbmcgcywgaW50IHdpZHRoKSB7CisgIGludCBsZW49c2l6ZW9mKHMpOworICBpZiAobGVuPT13aWR0aCkgcmV0dXJuIHM7CisKKyAgLy8gcmVpbmUgTGVlcnplaWxlbiwgZGlyZWt0IHp1cnVlY2tnZWJlbgorICBzdHJpbmcgdHJpbW1lZD10cmltKHMsVFJJTV9MRUZULCIgIik7CisgIGlmICh0cmltbWVkPT0iIikgcmV0dXJuIHM7IAorICBpbnQgc3RhcnRfc3BhY2VzID0gbGVuIC0gc2l6ZW9mKHRyaW1tZWQpOworCisgIHN0cmluZyogd29yZHMgPSBleHBsb2RlKHRyaW1tZWQsICIgIik7CisgIC8vIGRlciBsZXR6dGUga3JpZWd0IGtlaW5lIFNwYWNlcworICBpbnQgd29yZF9jb3VudD1zaXplb2Yod29yZHMpIC0gMTsKKyAgLy8gd2VubiBaZWlsZSBudXIgYXVzIGVpbmVtIFdvcnQsIHdpcmQgZGFzIFdvcnQgenVydWVja2dlZ2ViZW4KKyAgaWYgKCF3b3JkX2NvdW50KQorICAgIHJldHVybiAiICIqc3RhcnRfc3BhY2VzICsgd29yZHNbMF07CisKKyAgaW50IHNwYWNlX2NvdW50ID0gd2lkdGggLSBsZW47CisKKyAgaW50IHNwYWNlX3Blcl93b3JkPSh3b3JkX2NvdW50K3NwYWNlX2NvdW50KSAvIHdvcmRfY291bnQ7CisgIC8vIEFuei5Xb2VydGVyIG1pdCBadXNhdHotU3BhY2UKKyAgaW50IHJlc3Q9KHdvcmRfY291bnQrc3BhY2VfY291bnQpICUgd29yZF9jb3VudDsgCisgIC8vIFJlc3QtU3BhY2VzIFZlcnRlaWxlbgorICBmb3JlYWNoIChpbnQgcG9zIDogcmVzdCkgd29yZHNbcG9zXSs9IiAiOworICByZXR1cm4gKCIgIipzdGFydF9zcGFjZXMpICsgaW1wbG9kZSggd29yZHMsICIgIipzcGFjZV9wZXJfd29yZCApOworfQorCisvLyBhdXMgR2VzY2h3aW5kaWdrZWl0c2dydWVuZGVuIGhhdCBkZXIgQmxvY2tzYXR6IGZ1ZXIgYnJlYWtfc3RyaW5nIGVpbmUKKy8vIGVpZ2VuZSBGdW5rdGlvbiBiZWtvbW1lbjoKK3ByaXZhdGUgdmFyYXJncyBzdHJpbmcgYmxvY2tfc3RyaW5nKHN0cmluZyBzLCBpbnQgd2lkdGgsIGludCBmbGFncykgeworICAvLyB3ZW5uIEJTX0xFQVZFX01ZX0xGUywgYWJlciBrZWluIEJTX05PX1BBUklOREVOVCwgZGFubiB3ZXJkZW4gWmVpbGVuIG1pdAorICAvLyBlaW5lbSBMZWVyemVpY2hlbiBiZWdvbm5lbi4KKyAgLy8gQlRXOiBXZW5uICFCU19MRUFWRV9NWV9MRlMsIGhhdCBkZXIgQXVmcnVmZXIgYmVyZWl0cyBhbGxlIFxuIGR1cmNoICIgIgorICAvLyBlcnNldHp0LgorICBpZiAoIChmbGFncyAmIEJTX0xFQVZFX01ZX0xGUykKKyAgICAgICYmICEoZmxhZ3MgJiBCU19OT19QQVJJTkRFTlQpKQorICB7CisgICAgICBzID0gIiAiK3JlZ3JlcGxhY2UocywiXG4iLCJcbiAiLDEpOworICB9CisKKyAgLy8gc3ByaW50ZiBmdWVsbHQgZGllIGxldHp0ZSBaZWlsZSBhdWYgZGllIEZlbGRicmVpdGUgKGhpZXIgYWxzbworICAvLyBaZWlsZW5icmVpdGUpIG1pdCBGdWVsbHplaWNoZW4gYXVmLCB3ZW5uIHNpZSBOSUNIVCBtaXQgXG4gdW1nZWJyb2NoZW4KKyAgLy8gaXN0LiBFcyB3aXJkIGFuIGRpZSBsZXR6dGUgWmVpbGUgYWJlciBrZWluIFplaWxlbnVtYnJ1Y2ggYW5nZWhhZW5ndC4KKyAgLy8gRWlnZW50bGljaCBpc3QgZGFzIEF1ZmZ1ZWxsZW4gZG9vZiwgYWJlciB2ZXJtdXRsaWNoIGlzdCBlcyB1bm5vZXRpZywgZXMKKyAgLy8gd2llZGVyIHJ1ZWNrZ2FlbmdpZyB6dSBtYWNoZW4uCisgIHMgPSBzcHJpbnRmKCAiJS0qPXMiLCB3aWR0aCwgcyk7CisKKyAgc3RyaW5nICp0bXA9ZXhwbG9kZShzLCAiXG4iKTsKKyAgLy8gTnVyIHdlbm4gcyBtZWhyemVpbGlnIGlzdCwgQmxvY2tzYXR6IGRyYXVzIG1hY2hlbi4gRGllIGxldHp0ZSBaZWlsZSB3aXJkCisgIC8vIG5hdHVlcmxpY2ggbmljaHQgZ2VkZWhudC4gU2llIGlzdCBkYWZ1ZXIgc2Nob24gdm9uIHNwcmludGYoKSBhdWZnZWZ1ZWxsdAorICAvLyB3b3JkZW4uIEJUVzogRGllIGxldHp0ZSBaZWlsZSBlbmRldCB1LlUuIG5vY2ggbmljaHQgbWl0IGVpbmVtIFxuIChiencuCisgIC8vIG51ciBkYW5uLCB3ZW5uIEJTX0xFQVZFX01ZX0xGUyB1bmQgZGVyIHVlYmVyZ2ViZW5lIFRleHQgc2Nob24gbmVuIFxuIGFtCisgIC8vIEVuZGUgZGVyIGxldHp0ZW4gWmVpbGUgaGF0KSwgZGFzIG1hY2h0IGRlciBBdWZydWZlci4uLgorICBpZiAoc2l6ZW9mKHRtcCkgPiAxKQorICAgIHJldHVybiBpbXBsb2RlKCBtYXAoIHRtcFswLi48Ml0sICMnc3RyZXRjaC8qJyovLCB3aWR0aCApLCAiXG4iICkgCisgICAgICArICJcbiIgKyB0bXBbPDFdOworCisgIHJldHVybiBzOworfQorCitwdWJsaWMgdmFyYXJncyBzdHJpbmcgYnJlYWtfc3RyaW5nKHN0cmluZyBzLCBpbnQgdywgbWl4ZWQgaW5kZW50LCBpbnQgZmxhZ3MpCit7CisgICAgaWYgKCAhcyB8fCBzID09ICIiICkgcmV0dXJuICIiOworCisgICAgaWYgKCAhdyApIHc9Nzg7CisKKyAgICBpZiggaW50cChpbmRlbnQpICkKKyAgICAgICBpbmRlbnQgPSBpbmRlbnQgPyAiICIqaW5kZW50IDogIiI7CisKKyAgICBpbnQgaW5kZW50bGVuPXN0cmluZ3AoaW5kZW50KSA/IHNpemVvZihpbmRlbnQpIDogMDsKKworICAgIGlmIChpbmRlbnRsZW4+dykgeworICAgICAgc2V0X3RoaXNfb2JqZWN0KHByZXZpb3VzX29iamVjdCgpKTsKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoImJyZWFrX3N0cmluZzogaW5kZW50IGxvbmdlciAlZCB0aGFuIHdpZHRoICVkXG4iLAorICAgICAgICAgICAgICAgICAgaW5kZW50bGVuLHcpKTsKKyAgICAgIC8vIHc9KChpbmRlbnRsZW4vdykrMSkqdzsKKyAgICB9CisKKyAgICBpZiAoIShmbGFncyAmIEJTX0xFQVZFX01ZX0xGUykpIAorICAgICAgcz1yZWdyZXBsYWNlKCBzLCAiXG4iLCAiICIsIDEgKTsKKworICAgIGlmICggZmxhZ3MgJiBCU19TSU5HTEVfU1BBQ0UgKQorICAgICAgIHMgPSByZWdyZXBsYWNlKCBzLCAiKF58XG58ICkgICoiLCAiXFwxIiwgMSApOworIAorICAgIHN0cmluZyBwcmVmaXg9IiI7CisgICAgaWYgKGluZGVudGxlbiAmJiBmbGFncyAmIEJTX1BSRVBFTkRfSU5ERU5UKSB7CisgICAgICBpZiAoaW5kZW50bGVuK3NpemVvZihzKSA+IHcgfHwgCisgICAgICAgICAoZmxhZ3MgJiBCU19MRUFWRV9NWV9MRlMpICYmIHN0cnN0cihzLCJcbiIpPi0xKSB7CisgICAgICAgcHJlZml4PWluZGVudCsiXG4iOworICAgICAgIGluZGVudD0oZmxhZ3MgJiBCU19OT19QQVJJTkRFTlQpID8gIiIgOiAiICI7CisgICAgICAgaW5kZW50bGVuPXNpemVvZihpbmRlbnQpOworICAgICAgfQorICAgIH0KKworICAgIGlmICggZmxhZ3MgJiBCU19CTE9DSyApIHsKKyAgICAgIC8qCisgICAgICAgICAgIHMgPSBpbXBsb2RlKCBtYXAoIGV4cGxvZGUoIHMsICJcbiIgKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjJ2Jsb2NrX3N0cmluZywgdywgaW5kZW50bGVuLCBmbGFncyksCisgICAgICAgICAgICAgICAgICAgICAgIiIgKTsKKyAgICAgICovCisgICAgICBzID0gYmxvY2tfc3RyaW5nKCBzICwgdyAtIGluZGVudGxlbiwgZmxhZ3MgKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICBzID0gc3ByaW50ZigiJS0xLio9cyIsdy1pbmRlbnRsZW4scyk7CisgICAgfQorICAgIGlmICggc1s8MV0gIT0gJ1xuJyApIHMgKz0gIlxuIjsKKworICAgIGlmICggIWluZGVudGxlbiApIHJldHVybiBwcmVmaXggKyBzOworICAgIAorICAgIHN0cmluZyBpbmRlbnQyID0gKCBmbGFncyAmIEJTX0lOREVOVF9PTkNFICkgPyAoIiAiKmluZGVudGxlbikgOmluZGVudDsKKyAgICAgIAorICAgIHJldHVybiBwcmVmaXggKyBpbmRlbnQgKyAKKyAgICAgIHJlZ3JlcGxhY2UoIHNbMC4uPDJdLCAiXG4iLCAiXG4iK2luZGVudDIsIDEgKSArICJcbiI7CisgICAgICAvKgorICAgICAgIHN0cmluZyAqYnVmOworCisgICAgICAgYnVmID0gZXhwbG9kZSggcywgIlxuIiApOworICAgICAgIHJldHVybiBwcmVmaXggKyBpbmRlbnQgKyBpbXBsb2RlKCBidWZbMC4uPDJdLCAiXG4iK2luZGVudDIgKSArIGJ1Zls8MV0gKyAiXG4iOworICAgICAgKi8KK30KKworLy8gKiBFbGVtZW50ZSBhdXMgbWFwcGluZyBsb2VzY2hlbiAtIG1hcHBpbmcgdm9yaGVyIGtvcGllcmVuCisKK21hcHBpbmcgbV9jb3B5X2RlbGV0ZShtYXBwaW5nIG0sIG1peGVkIGtleSkgeworICByZXR1cm4gbV9kZWxldGUoY29weShtKSwga2V5KTsKK30KKworLy8gKiB0aW1lcworaW50IGxhc3RfcmVib290X3RpbWUoKQoreworICByZXR1cm4gX19CT09UX1RJTUVfXzsKK30KKworaW50IGZpcnN0X2Jvb3RfdGltZSgpCit7CisgIHJldHVybiA3MDE1MTc2MDA7Cit9CisKK2ludCBleGlzdF9kYXlzKCkKK3sKKyAgcmV0dXJuICgoKHRpbWUoKS1maXJzdF9ib290X3RpbWUoKSkvODY0MCkrNSkvMTA7Cit9CisKKy8vICogdXB0aW1lIDopCitzdHJpbmcgdXB0aW1lKCkKK3sKKyAgaW50IHQ7CisgIGludCB0bXA7CisgIHN0cmluZyBzOworCisgIHQ9dGltZSgpLV9fQk9PVF9USU1FX187CisgIHM9IiI7CisgIGlmICh0Pj04NjQwMCkKKyAgICBzKz1zcHJpbnRmKCIlZCBUYWclcywgIix0bXA9dC84NjQwMCwodG1wPT0xPyIiOiJlIikpOworICBpZiAodD49MzYwMCkKKyAgICBzKz1zcHJpbnRmKCIlZCBTdHVuZGUlcywgIix0bXA9KHQ9dCU4NjQwMCkvMzYwMCwodG1wPT0xPyIiOiJuIikpOworICBpZiAodD42MCkKKyAgICBzKz1zcHJpbnRmKCIlZCBNaW51dGUlcyB1bmQgIix0bXA9KHQ9dCUzNjAwKS82MCwodG1wPT0xPyIiOiJuIikpOworICByZXR1cm4gcytzcHJpbnRmKCIlZCBTZWt1bmRlJXMiLHQ9dCU2MCwodD09MT8iIjoibiIpKTsKK30KKworLy8gKiBXYXMgdHVuIGJlaSAnZGFuZ2xpbmcnIGxmdW4tY2xvc3VyZXMgPwordm9pZCBkYW5nbGluZ19sZnVuX2Nsb3N1cmUoKSB7CisgIHJhaXNlX2Vycm9yKCJkYW5nbGluZyBsZnVuIGNsb3N1cmVcbiIpOworfQorCisvLyAqIFNwZXJyZW4gYXVzc2VyIGZ1ZXIgbWFzdGVyL3NpbXVsX2VmdW4KKworI2lmIF9fRUZVTl9ERUZJTkVEX18oc2V0X2Vudmlyb25tZW50KQorbm9tYXNrIHZvaWQgc2V0X2Vudmlyb25tZW50KG9iamVjdCBvMSwgb2JqZWN0IG8yKSB7CisgIHJhaXNlX2Vycm9yKCJBdmFpbGFibGUgb25seSBmb3Igcm9vdFxuIik7Cit9CisjZW5kaWYKKworbm9tYXNrIHZvaWQgc2V0X3RoaXNfcGxheWVyKG9iamVjdCBwbCkgeworICByYWlzZV9lcnJvcigiQXZhaWxhYmxlIG9ubHkgZm9yIHJvb3RcbiIpOworfQorCisjaWYgX19FRlVOX0RFRklORURfXyhleHBvcnRfdWlkKQorbm9tYXNrIHZvaWQgZXhwb3J0X3VpZChvYmplY3Qgb2IpIHsKKyAgcmFpc2VfZXJyb3IoIkF2YWlsYWJsZSBvbmx5IGZvciByb290XG4iKTsKK30KKyNlbmRpZgorCisvLyAqIEpldHp0IGF1Y2ggY2xvc3VyZXMKK2ludCBwcm9jZXNzX2ZsYWc7CisKK3B1YmxpYyBub21hc2sgaW50IHByb2Nlc3NfY2FsbCgpCit7CisgIGlmIChwcm9jZXNzX2ZsYWc+MCkKKyAgICByZXR1cm4gcHJvY2Vzc19mbGFnOworICBlbHNlIHJldHVybigwKTsKK30KKworcHJpdmF0ZSBub21hc2sgc3RyaW5nIF9wcm9jZXNzX3N0cmluZyhzdHJpbmcgc3RyLG9iamVjdCBwbykgeworICAgICAgICAgICAgICBzZXRfdGhpc19vYmplY3QocG8pOworICAgICAgICAgICAgICByZXR1cm4oZWZ1bjo6cHJvY2Vzc19zdHJpbmcoc3RyKSk7Cit9CisKK25vbWFzayBzdHJpbmcgcHJvY2Vzc19zdHJpbmcoIG1peGVkIHN0ciApCit7CisgIHN0cmluZyB0bXAsIGVycjsKKyAgaW50IGZsYWc7IAorCisgIGlmICggY2xvc3VyZXAoc3RyKSApIHsKKyAgICAgIHNldF90aGlzX29iamVjdCggcHJldmlvdXNfb2JqZWN0KCkgKTsKKyAgICAgIHJldHVybiBmdW5jYWxsKHN0cik7CisgIH0KKyAgZWxzZSBpZiAoc3RyPT0wKQorICAgICAgcmV0dXJuKChzdHJpbmcpc3RyKTsKKyAgZWxzZSBpZiAoICFzdHJpbmdwKHN0cikgKSB7CisgICAgICByZXR1cm4gdG9fc3RyaW5nKHN0cik7CisgIH0KKworICBpZiAoICEoZmxhZyA9IHByb2Nlc3NfZmxhZyA+IHRpbWUoKSAtIDYwKSkgICAgICAgICAgICAgICAgICAgICAKKyAgICAgIHByb2Nlc3NfZmxhZz10aW1lKCk7CisKKyAgZXJyID0gY2F0Y2godG1wID0gZnVuY2FsbCgjJ19wcm9jZXNzX3N0cmluZyxzdHIscHJldmlvdXNfb2JqZWN0KCkpOyBwdWJsaXNoKTsKKworICBpZiAoICFmbGFnICkKKyAgICBwcm9jZXNzX2ZsYWc9MDsKKworICBpZiAoZXJyKSB7CisgICAgLy8gVmVyYXJiZWl0dW5nIGFiYnJlY2hlbgorICAgIHNldF90aGlzX29iamVjdChwcmV2aW91c19vYmplY3QoKSk7CisgICAgcmFpc2VfZXJyb3IoZXJyKTsKKyAgfQorICByZXR1cm4gdG1wOworfQorCisvLyAnbWtkaXIgLXAnIC0gZXJ6ZXVndCBlaW5lIGtvbXBsZXR0ZSBIaWVyYXJjaGllIHZvbiBWZXJ6ZWljaG5pc3Nlbi4KKy8vIHdlbm4gZGFzIFZlcnplaWNobmlzIGFuZ2VsZWd0IHd1cmRlIG9kZXIgc2Nob24gZXhpc3RpZXJ0LCB3aXJkIDEKKy8vIHp1cnVlY2tnZWxpZWZlcnQsIHNvbnN0IDAuCisvLyBXaXJmdCBlaW5lbiBGZWhsZXIsIHdlbm4gZGFzIGFuZ2ViZW5lIFZlcnplaWNobmlzIG5pY2h0IGFic29sdXQgaXN0IQorcHVibGljIGludCBta2RpcnAoc3RyaW5nIGRpcikgeworICAvLyB3ZW5uIGVzIG51ciBrZWluZW4gZnVlaHJlbmRlbiAvIGdpYnQsIGlzdCBkYXMgZWluIEZlaGxlci4KKyAgaWYgKHN0cnN0cihkaXIsICIvIikgIT0gMCkKKyAgICByYWlzZV9lcnJvcigibWtkaXJwKCk6IFBmYWQgaXN0IG5pY2h0IGFic29sdXRlLlxuIik7CisgIC8vIGN1dCBvZmYgdHJhaWxpbmcgLy4uLgorICBpZiAoZGlyWzwxXT09Jy8nKQorICAgICAgZGlyID0gZGlyWzAuLjwyXTsKKworICBpbnQgZnN0YXQgPSBmaWxlX3NpemUoZGlyKTsKKyAgLy8gd2VubiBlcyBzY2hvbiBleGlzdGllcnQsIHR1biB3aXIgZWluZmFjaCBzbywgYWxzIGhhZXR0ZW4gd2lyIGVzIGFuZ2VsZWd0LgorICBpZiAoZnN0YXQgPT0gRlNJWkVfRElSKQorICAgIHJldHVybiAxOworICAvLyB3ZW5uIHNjaG9uIG5lIERhdGVpIGV4aXN0aWVydCwgZ2VodCBlcyBuaWNodC4KKyAgaWYgKGZzdGF0ICE9IEZTSVpFX05PRklMRSkKKyAgICByZXR1cm4gMDsKKyAgLy8gd2VubiBlcyBudXIgZWluZW4gLyBnaWJ0IChkZW4gZnVlaHJlbmRlbiksIGRhbm4gaXN0IGVzIGVpbgorICAvLyB0b3BsZXZlbC12ZXJ6ZWljaG5pcywgd2FzIGRpcmVrdCBhbmdlbGVndCB3aXJkLgorICBpZiAoc3RycnN0cihkaXIsIi8iKT09MCkgeworICAgIHJldHVybiBmdW5jYWxsKGJpbmRfbGFtYmRhKCMnZWZ1bjo6bWtkaXIsIHByZXZpb3VzX29iamVjdCgpKSwgZGlyKTsKKyAgfQorCisgIC8vIG1rZGlyKCkgbmljaHQgZGlyZWt0IHJ1ZmVuLCBzb25kZXJuIHZvcmhlciBhbHMgY2xvc3VyZSBhbnMgYXVmcnVmZW5kZQorICAvLyBPYmpla3QgYmluZGVuLiBTb25zdCBsYWV1ZnQgZGllIFJlY2h0ZXBydWVmdW5nIGluIHZhbGlkX3dyaXRlKCkgaW0gTWFzdGVyCisgIC8vIHVudGVyIGRlciBBbm5haG1lLCBkYXNzIGRpZSBzaW11bF9lZnVuLmMgbWl0IGlocmVyIHJvb3QgaWQgd2FzIHdpbGwuCisKKyAgLy8gamV0enQgcmVrdXJzaXYgZGllIFZlcnplaWNobmlzaGllcmFyY2hpZSBhbmxlZ2VuLiBXZW5uIGRhcyBlcmZvbGdyZWljaAorICAvLyBpc3QsIGRhbm4ga29lbm5lbiB3aXIgamV0enQgbWl0IG1rZGlyIGRhcyB0aWVmc3RlIFZlcnplaWNobmlzIGFubGVnZW4KKyAgaWYgKG1rZGlycChkaXJbMC4uc3RycnN0cihkaXIsIi8iKS0xXSkgPT0gMSkKKyAgICByZXR1cm4gZnVuY2FsbChiaW5kX2xhbWJkYSgjJ2VmdW46Om1rZGlyLCBwcmV2aW91c19vYmplY3QoKSksIGRpcik7Cit9CisKKworLy8gKiBQcm9wZXJ0aWVzIGdnZnMuIG1pdHNwZWljaGVybgorbWl4ZWQgc2F2ZV9vYmplY3QobWl4ZWQgbmFtZSkKK3sKKyAgbWFwcGluZyBwcm9wZXJ0aWVzOworICBtYXBwaW5nIHNhdmU7CisgIG1peGVkIGluZGV4LCByZXM7CisgIGludCBpOworCisgIC8vIG51ciBTdHJpbmdzIHVuZCAwIHp1bGFzc2VuCisgIGlmICgoIXN0cmluZ3AobmFtZSkgfHwgIXNpemVvZihuYW1lKSkgJiYgCisgICAgICAoIWludHAobmFtZSkgfHwgbmFtZSE9MCkpIHsKKyAgICAgIHNldF90aGlzX29iamVjdChwcmV2aW91c19vYmplY3QoKSk7CisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgIk9ubHkgbm9uLWVtcHR5IHN0cmluZ3MgYW5kIDAgbWF5IGJlIHVzZWQgYXMgZmlsZW5hbWUgaW4gIgorICAgICAgICAgInNlZnVuOjpzYXZlX29iamVjdCgpISBBcmd1bWVudCB3YXMgJU9cbiIsbmFtZSkpOworICB9CisKKyAgc2F2ZSA9IG1fYWxsb2NhdGUoMCwgMik7CisgIHByb3BlcnRpZXMgPSAobWFwcGluZylwcmV2aW91c19vYmplY3QoKS0+UXVlcnlQcm9wZXJ0aWVzKCk7CisKKyAgaWYobWFwcGluZ3AocHJvcGVydGllcykpCisgIHsKKyAgICAvLyBkZWxldGUgYWxsIGVudHJpZXMgaW4gbWFwcGluZyBwcm9wZXJ0aWVzIHdpdGhvdXQgU0FWRSBmbGFnIQorICAgIGluZGV4ID0gbV9pbmRpY2VzKHByb3BlcnRpZXMpOworICAgIGZvcihpID0gc2l6ZW9mKGluZGV4KS0xOyBpPj0wO2ktLSkKKyAgICB7CisgICAgICBpZihwcm9wZXJ0aWVzW2luZGV4W2ldLCBGX01PREVdICYgU0FWRSkKKyAgICAgIHsKKyAgICAgICBzYXZlW2luZGV4W2ldXSA9IHByb3BlcnRpZXNbaW5kZXhbaV1dOworICAgICAgIHNhdmVbaW5kZXhbaV0sIEZfTU9ERV0gPQorICAgICAgIHByb3BlcnRpZXNbaW5kZXhbaV0sIEZfTU9ERV0gJgorICAgICAgICAgICAgICAgICAgICAofihTRVRNTk9URk9VTkR8UVVFUllNTk9URk9VTkR8UVVFUllDQUNIRUR8U0VUQ0FDSEVEKSk7CisgICAgICB9CisgICAgfQorICB9CisgIGVsc2Ugc2F2ZSA9IChbXSk7CisKKyAgLy8gc2F2ZSBvYmplY3QhCisgIHByZXZpb3VzX29iamVjdCgpLT5fc2V0X3NhdmVfZGF0YShzYXZlKTsKKyAgLy8gZm9ybWF0OiB3aWUgZGVmaW5pZXJ0IGluIGNvbmZpZy5oCisgIGlmIChzdHJpbmdwKG5hbWUpKQorICAgIHJlcyA9IGZ1bmNhbGwoYmluZF9sYW1iZGEoIydlZnVuOjpzYXZlX29iamVjdCwgcHJldmlvdXNfb2JqZWN0KCkpLCBuYW1lLAorICAgICAgIF9fTElCX19TQVZFX0ZPUk1BVF9WRVJTSU9OX18pOworICBlbHNlCisgICAgcmVzID0gZnVuY2FsbChiaW5kX2xhbWJkYSgjJ2VmdW46OnNhdmVfb2JqZWN0LCBwcmV2aW91c19vYmplY3QoKSksCisgICAgICAgX19MSUJfX1NBVkVfRk9STUFUX1ZFUlNJT05fXyk7CisgIHByZXZpb3VzX29iamVjdCgpLT5fc2V0X3NhdmVfZGF0YSgwKTsKKworI2lmZGVmIElPU1RBVFMKKyAgLy8gU3RhdHMuLi4KKyAgc3RydWN0IGlvc3RhdF9zIHN0YXQgPSAoPGlvc3RhdF9zPik7CisgIHN0YXQtPm9uYW1lID0gb2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpOworICBzdGF0LT50aW1lID0gdGltZSgpOworICAvL3N0YXQtPnNpemUgPSAoaW50KW9iamVjdF9pbmZvKHByZXZpb3VzX29iamVjdCgpLE9JTkZPX01FTU9SWSwKKyAgLy8gICAgT0lNX1RPVEFMX0RBVEFfU0laRSk7CisgIGlmIChzdHJpbmdwKG5hbWUpKQorICAgICAgc3RhdC0+c2l6ZSA9IGZpbGVfc2l6ZShuYW1lICsgIi5vIik7CisgIGVsc2UKKyAgICAgIHN0YXQtPnNpemVvZihyZXMpOworICAvL2RlYnVnX21lc3NhZ2UoInNhdmVvOiAiK3NhdmVvX3N0YXRbMF0rIlxuIik7CisgIHNhdmVvX3N0YXRbMV1bc2F2ZW9fc3RhdFswXV0gPSBzdGF0OworICBzYXZlb19zdGF0WzBdID0gKHNhdmVvX3N0YXRbMF0gKyAxKSAlIHNpemVvZihzYXZlb19zdGF0WzFdKTsKKyAgLy9kZWJ1Z19tZXNzYWdlKCJzYXZlbyAyOiAiK3NhdmVvX3N0YXRbMF0rIlxuIik7CisjZW5kaWYKKworICByZXR1cm4gcmVzOworfQorCisvLyAqIEF1Y2ggUHJvcGVydGllcyBsYWRlbgoraW50IHJlc3RvcmVfb2JqZWN0KHN0cmluZyBuYW1lKQoreworICBpbnQgcmVzdWx0OworICBtaXhlZCBpbmRleDsKKyAgbWl4ZWQgc2F2ZTsKKyAgbWFwcGluZyBwcm9wZXJ0aWVzOworICBpbnQgaTsKKyAgY2xvc3VyZSBjbDsKKworICAvLyBnZXQgYWN0dWFsIHByb3BlcnR5IHNldHRpbmdzIChieSBjcmVhdGUoKSkKKyAgcHJvcGVydGllcyA9IChtYXBwaW5nKXByZXZpb3VzX29iamVjdCgpLT5RdWVyeVByb3BlcnRpZXMoKTsKKworLy8gIERFQlVHKHNwcmludGYoIlJFU1RPUkUgJU9cbiIsbmFtZSkpOworICAvLyByZXN0b3JlIG9iamVjdAorICByZXN1bHQ9ZnVuY2FsbChiaW5kX2xhbWJkYSgjJ2VmdW46OnJlc3RvcmVfb2JqZWN0LCBwcmV2aW91c19vYmplY3QoKSksIG5hbWUpOworICAvLycpKQorICAvL19nZXRfc2F2ZV9kYXRhIGxpZWZlcnQgdGF0c2FlY2hsaWNoIG1peGVkIHp1cnVlY2ssIHdlbm4gZGFzIGF1Y2ggaW1tZXIgZWluIAorICAvL21hcHBpbmcgc2VpbiBzb2xsdGUuCisgIHNhdmUgPSAobWl4ZWQpcHJldmlvdXNfb2JqZWN0KCktPl9nZXRfc2F2ZV9kYXRhKCk7CisgIGlmKG1hcHBpbmdwKHNhdmUpKQorICB7CisgICAgaW5kZXggPSBtX2luZGljZXMoc2F2ZSk7CisgICAgZm9yKGkgPSBzaXplb2YoaW5kZXgpLTE7IGk+PTA7IGktLSkKKyAgICB7CisgICAgICBwcm9wZXJ0aWVzW2luZGV4W2ldXSA9IHNhdmVbaW5kZXhbaV1dOworICAgICAgcHJvcGVydGllc1tpbmRleFtpXSwgRl9NT0RFXSA9IHNhdmVbaW5kZXhbaV0sIEZfTU9ERV0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmfihTRVRDQUNIRUR8UVVFUllDQUNIRUQpOworICAgIH0KKyAgfQorICBlbHNlIHByb3BlcnRpZXMgPSAoW10pOworCisgIC8vIHJlc3RvcmUgcHJvcGVydGllcworICBmdW5jYWxsKAorICAgICAgICAgIGJpbmRfbGFtYmRhKAorICAgICAgICAgICAgICAgICAgICAgdW5ib3VuZF9sYW1iZGEoKHsnYXJnfSksIC8vJ30pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHsjJ2NhbGxfb3RoZXIsKHsjJ3RoaXNfb2JqZWN0fSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNldFByb3BlcnRpZXMiLCdhcmd9KSksLy8nKQorICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNfb2JqZWN0KCkpLHByb3BlcnRpZXMpOworICBwcmV2aW91c19vYmplY3QoKS0+X3NldF9zYXZlX2RhdGEoMCk7CisKKyNpZmRlZiBJT1NUQVRTCisgIC8vIFN0YXRzLi4uCisgIC8vZGVidWdfbWVzc2FnZSgicmVzdG9yZW86ICIrcmVzdG9yZW9fc3RhdFswXSsiXG4iKTsKKyAgc3RydWN0IGlvc3RhdF9zIHN0YXQgPSAoPGlvc3RhdF9zPik7CisgIHN0YXQtPm9uYW1lID0gb2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpOworICBzdGF0LT50aW1lID0gdGltZSgpOworICAvL3N0YXQtPnNpemUgPSAoaW50KW9iamVjdF9pbmZvKHByZXZpb3VzX29iamVjdCgpLE9JTkZPX01FTU9SWSwKKyAgLy8gICAgT0lNX1RPVEFMX0RBVEFfU0laRSk7CisgIHN0YXQtPnNpemUgPSBmaWxlX3NpemUobmFtZSArICIubyIpOworICByZXN0b3Jlb19zdGF0WzFdW3Jlc3RvcmVvX3N0YXRbMF1dID0gc3RhdDsKKworICByZXN0b3Jlb19zdGF0WzBdID0gKHJlc3RvcmVvX3N0YXRbMF0gKyAxKSAlIHNpemVvZihyZXN0b3Jlb19zdGF0WzFdKTsKKyNlbmRpZgorCisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vICogSEIgZWluZXMgT2JqZWt0ZXMgZWluL2F1c3NjaGFsdGVuCitpbnQgc2V0X29iamVjdF9oZWFydF9iZWF0KG9iamVjdCBvYiwgaW50IGZsYWcpCit7CisgIGlmIChvYmplY3RwKG9iKSkKKyAgICByZXR1cm4gZnVuY2FsbChiaW5kX2xhbWJkYSgjJ2VmdW46OmNvbmZpZ3VyZV9vYmplY3Qsb2IpLCBvYiwgT0NfSEVBUlRfQkVBVCwgZmxhZyk7Cit9CisKKy8vICogTWFnaWVybGV2ZWxncnVwcGVuIGVybWl0dGVsbgoraW50IHF1ZXJ5X3dpel9ncnAobWl4ZWQgd2l6KQoreworICBpbnQgbGV2OworCisgIGxldj1xdWVyeV93aXpfbGV2ZWwod2l6KTsKKyAgaWYgKGxldjxTRUVSX0xWTCkgcmV0dXJuIDA7CisgIGlmIChsZXY+PUdPRF9MVkwpIHJldHVybiBsZXY7CisgIGlmIChsZXY+PUFSQ0hfTFZMKSByZXR1cm4gQVJDSF9HUlA7CisgIGlmIChsZXY+PUVMREVSX0xWTCkgcmV0dXJuIEVMREVSX0dSUDsKKyAgaWYgKGxldj49TE9SRF9MVkwpIHJldHVybiBMT1JEX0dSUDsKKyAgaWYgKGxldj49U1BFQ0lBTF9MVkwpIHJldHVybiBTUEVDSUFMX0dSUDsKKyAgaWYgKGxldj49RE9NQUlOTUVNQkVSX0xWTCkgcmV0dXJuIERPTUFJTk1FTUJFUl9HUlA7CisgIGlmIChsZXY+PVdJWkFSRF9MVkwpIHJldHVybiBXSVpBUkRfR1JQOworICBpZiAobGV2Pj1MRUFSTkVSX0xWTCkgcmV0dXJuIExFQVJORVJfR1JQOworICByZXR1cm4gU0VFUl9HUlA7Cit9CisKK21peGVkICp3aXpsaXN0X2luZm8oKQoreworICBpZiAoQVJDSF9TRUNVUklUWSB8fCAhZXh0ZXJuX2NhbGwoKSkKKyAgICAgICAgICAgIHJldHVybiBlZnVuOjp3aXpsaXN0X2luZm8oKTsKKyAgcmV0dXJuIDA7Cit9CisKKy8vICogd2l6bGlzdCBhdXNnZWJlbgordmFyYXJncyB2b2lkIHdpemxpc3Qoc3RyaW5nIG5hbWUsIGludCBzb3J0a2V5ICkgeworCisgIGlmICghbmFtZSkKKyAgeworICAgIGlmICh0aGlzX3BsYXllcigpKQorICAgICAgbmFtZSA9IGdldHVpZCh0aGlzX3BsYXllcigpKTsKKyAgICBpZiAoIW5hbWUpCisgICAgICByZXR1cm47CisgIH0KKworICAvLyBTY2hsdWVzc2VsIGRhcmYgbnVyIGluIGVpbmVtIGd1ZWx0aWdlbiBCZXJlaWNoIHNlaW4KKyAgaWYgKHNvcnRrZXk8V0xfTkFNRSB8fCBzb3J0a2V5Pj1XTF9TSVpFKSBzb3J0a2V5PVdMX0NPU1Q7CisKKyAgbWl4ZWQqKiB3bCA9IGVmdW46Ondpemxpc3RfaW5mbygpOworICAvLyBuYWNoIDxzb3J0a2V5PiBzb3J0aWVyZW4KKyAgd2wgPSBzb3J0X2FycmF5KHdsLCBmdW5jdGlvbiBpbnQgKG1peGVkIGEsIG1peGVkIGIpCisgICAgICB7cmV0dXJuIGFbc29ydGtleV0gPCBiW3NvcnRrZXldOyB9ICk7CisKKyAgLy8gU3VtbWUgdWViZXIgYWxsZSBLb21tYW5kb3MgZXJtaXR0ZWxuLgorICBpbnQgdG90YWxfY21kLCBpOworICBpbnQgcG9zPS0xOworICBmb3JlYWNoKG1peGVkIGVudHJ5IDogd2wpCisgIHsKKyAgICB0b3RhbF9jbWQgKz0gZW50cnlbV0xfQ09NTUFORFNdOworICAgIGlmIChlbnRyeVtXTF9OQU1FXSA9PSBuYW1lKQorICAgICAgcG9zID0gaTsKKyAgICArK2k7CisgIH0KKworICBpZiAocG9zIDwgMCAmJiBuYW1lICE9ICJBTEwiICYmIG5hbWUgIT0gIlRPUDEwMCIpCisgICAgcmV0dXJuOworCisgIGlmIChuYW1lID09ICJUT1AxMDAiKQorICB7CisgICAgaWYgKHNpemVvZih3bCkgPiAxMDApCisgICAgICB3bCA9IHdsWzAuLjEwMF07CisgICAgZWxzZQorICAgICAgd2wgPSB3bDsKKyAgfQorICAvLyB1bSBuYW1lIGhlcnVtIHNjaG5laWRlbgorICBlbHNlIGlmIChuYW1lICE9ICJBTEwiKQorICB7CisgICAgaWYgKHNpemVvZih3bCkgPD0gMjEpCisgICAgICB3bCA9IHdsOworICAgIGVsc2UgaWYgKHBvcyArIDEwIDwgc2l6ZW9mKHdsKSAmJiBwb3MgLSAxMCA+IDApCisgICAgICB3bCA9IHdsW3Bvcy0xMC4ucG9zKzEwXTsKKyAgICBlbHNlIGlmIChwb3MgPD0yMSkKKyAgICAgIHdsID0gd2xbMC4uMjBdOworICAgIGVsc2UgaWYgKHBvcyA+PSBzaXplb2Yod2wpIC0gMjEpCisgICAgICB3bCA9IHdsWzwyMS4uXTsKKyAgICBlbHNlCisgICAgICB3bCA9IHdsOworICB9CisKKyAgd3JpdGUoIlxuV2l6YXJkIHRvcCBzY29yZSBsaXN0XG5cbiIpOworICBpZiAodG90YWxfY21kID09IDApCisgICAgdG90YWxfY21kID0gMTsKKyAgcHJpbnRmKCIlLTIwcyAlLTZzICUtM3MgJS0xN3MgJS02cyAlLTZzICUtNnNcbiIsCisgICAgICAgICAiRVVJRCIsICJjbWRzIiwgIiUiLCAiQ29zdHMiLCAiSEIiLCAiQXJyYXlzIiwiTWFwcC4iKTsKKyAgZm9yZWFjaChtaXhlZCBlOiB3bCkKKyAgeworICAgIHByaW50ZigiJS06MjBzICU6NmQgJToyZCUlIFslOjZkaywlOjZkR10gJTo2ZCAlOjZkICU6NmRcbiIsCisgICAgICAgICAgZVtXTF9OQU1FXSwgZVtXTF9DT01NQU5EU10sIGVbV0xfQ09NTUFORFNdICogMTAwIC8gdG90YWxfY21kLAorICAgICAgICAgIGVbV0xfQ09TVF0gLyAxMDAwLCBlW1dMX1RPVEFMX0dJR0FDT1NUXSwKKyAgICAgICAgICBlW1dMX0hFQVJUX0JFQVRTXSwgZVtXTF9BUlJBWV9UT1RBTF0sIGVbV0xfTUFQUElOR19UT1RBTF0KKyAgICAgICAgICApOworICB9CisgIHByaW50ZigiXG5Ub3RhbCAgICAgICAgICU3ZCAgICAgICAgICglZClcblxuIiwgdG90YWxfY21kLCBzaXplb2Yod2wpKTsKK30KKworCisvLyBBYiBoaWVyIGZvbGdlbiBIaWxmc2Z1bmt0aW9uZW4gZnVlciBjYWxsX291dCgpIGJ6dy4gZnVlciBkZXJlbiBCZWdyZW56dW5nCisKKy8vIGVybWl0dGVsdCBkYXMgT2JqZWt0IGRlcyBDYWxsb3V0cy4KK3ByaXZhdGUgb2JqZWN0IF9jYWxsX291dF9vYmooIG1peGVkIGNhbGxfb3V0ICkgeworICAgIHJldHVybiBwb2ludGVycChjYWxsX291dCkgPyBjYWxsX291dFswXSA6IDA7Cit9CisKK3ByaXZhdGUgdm9pZCBfc2FtZV9vYmplY3QoIG9iamVjdCBvYiwgbWFwcGluZyBtICkgeworICAvLyBpc3QgbmljaHQgc28gYmxvZWQsIHdpZSBlcyBhdXNzaWVodCwgcy4gbmFjaGZvbGdlZGUgVmVyd2VuZHVuZyB2b24gbQorICBpZiAoIG1bb2JdICkKKyAgICBtW29iXSArPSAoeyBvYiB9KTsKKyAgZWxzZQorICAgIG1bb2JdID0gKHsgb2IgfSk7IAorfQorCisvLyBhbGxlIE9iamVrdGUgaW0gTWFwcGluZyBtIHp1c2FtbWVuZmFzc2VuLCBkaWUgZGVuIGdsZWljaGVuIExvYWRuYW1lIChOYW1lIGRlcgorLy8gQmx1ZXByaW50KSBoYWJlbiwgYWxzbyBhbGxlIENsb25lcyBkZXIgQlAsIGRpZSBDYWxsb3V0cyBsYXVmZW4gaGFiZW4uCisvLyBPYmpla3RlIHdlcmRlbiBhdWNoIG1laHJmYWNoIGVyZmFzc3QsIGplIG5hY2ggQW56YWhsIGlocmVyIENhbGxvdXRzLgorcHJpdmF0ZSB2b2lkIF9zYW1lX3BhdGgoIG9iamVjdCBrZXksIG9iamVjdCAqb2JzLCBtYXBwaW5nIG0gKSB7CisgIHN0cmluZyBwYXRoOworICBpZiAoIW9iamVjdHAoa2V5KSB8fCAhcG9pbnRlcnAob2JzKSkgcmV0dXJuOworCisgIHBhdGggPSBsb2FkX25hbWUoa2V5KTsKKworICBpZiAoIG1bcGF0aF0gKQorICAgIG1bcGF0aF0gKz0gb2JzOworICBlbHNlCisgICAgbVtwYXRoXSA9IG9iczsKK30KKworLy8ga2V5IGthbm4gb2JqZWN0IG9kZXIgc3RyaW5nIHNlaW4uCitwcml2YXRlIGludCBfdG9vX21hbnkoIG1peGVkIGtleSwgbWFwcGluZyBtLCBpbnQgaSApIHsKKyAgICByZXR1cm4gc2l6ZW9mKG1ba2V5XSkgPj0gaTsKK30KKworLy8gYWxsZSBPYmpla3RlIGluIG9icyB6ZXJzdG9lcmVuIHVuZCBGZWhsZXJtZWxkdW5nIGF1c2dlYmVuLiBBQ0hUVU5HOiBEaWUKKy8vIE9iamVrdGUgd2VyZGVuIGlkUiB6dSBlaW5lciBCUCBnZWhvZXJlbiwgbXVlc3NlbiBhYmVyIG5pY2h0ISBJbiBkZW0gRmFsbAorLy8gd2lyZCBhdWYgZGVyIEViZW5lIGFiZXIgbnVyIGVpbiBPYmpla3QgaW4gZGVyIEZlaGxlcm1lbGR1bmcgZXJ3YWVobnQuCitwcml2YXRlIHZvaWQgX2Rlc3Ryb3koIG1peGVkIGtleSwgb2JqZWN0ICpvYnMsIHN0cmluZyB0ZXh0LCBpbnQgdWlkICkgeworICAgIGlmICghcG9pbnRlcnAob2JzKSkgcmV0dXJuOworICAgIC8vIEFycmF5IG1pdCB1bmlxdWUgRWludHJhZWdlIGVyemV1Z2VuLgorICAgIG9icyA9IG1faW5kaWNlcyggbWttYXBwaW5nKG9icykgKTsKKyAgICAvLyBGZWhsZXJtZWxkdW5nIGF1ZiBkZXIgRWJlbmUgYXVzZ2ViZW4sIGltIGNhdGNoKCkgbWl0IHB1Ymxpc2gsIGRhbWl0IGVzCisgICAgLy8gYXVmIGRlciBFYmVuZSBkaXJla3Qgc2Nyb2xsdCwgZGVyIGJhY2t0cmFjZSB2ZXJmdWVnYmFyIGlzdCAoaW0KKyAgICAvLyBnZWdlbnNhdHogenVyIExvZXN1bmcgbWl0dGVscyBDYWxsb3V0KSwgZGllIEF1c2Z1ZWhydW5nIGFiZXIgd2VpdGVyCisgICAgLy8gbGFldWZ0LgorICAgIGNhdGNoKCBlZnVuOjpyYWlzZV9lcnJvciggICAgICAgICAgIAorICAgICAgICAgc3ByaW50ZiggdGV4dCwgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgIHVpZCA/IChzdHJpbmcpbWFzdGVyKCktPmNyZWF0b3JfZmlsZShrZXkpIDoga2V5LCAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgc2l6ZW9mKG9icyksIG9iamVjdF9uYW1lKG9ic1s8MV0pICkgKTtwdWJsaXNoKTsKKyAgICAvLyBVbmQgd2VnIG1pdCBkZW0gS3JhbS4uLgorICAgIGZpbHRlciggb2JzLCAjJ2VmdW46OmRlc3RydWN0LyonKi8gKTsKK30KKworLy8gQWxsZSBPYmpla3QgZWluZXIgVUlEIGltIE1hcHBpbmcgbSBtaXQgVUlEIGFscyBLRXlzIHp1c2FtbWVuZmFzc2VuLiBPYmpla3QKKy8vIHNpbmQgZGFiZWkgbmljaHQgdW5pcXVlLgorcHJpdmF0ZSB2b2lkIF9zYW1lX3VpZCggc3RyaW5nIGtleSwgb2JqZWN0ICpvYnMsIG1hcHBpbmcgbSwgY2xvc3VyZSBjZiApIHsKKyAgc3RyaW5nIHVpZDsKKworICBpZiAoICFwb2ludGVycChvYnMpIHx8ICFzaXplb2Yob2JzKSApCisgICAgcmV0dXJuOworCisgIHVpZCA9IGZ1bmNhbGwoIGNmLCBrZXkgKTsKKworICBpZiAoIG1bdWlkXSApCisgICAgbVt1aWRdICs9IG9iczsgLy8gb2JzIGlzdCBuZW4gQXJyYXkKKyAgZWxzZQorICAgIG1bdWlkXSA9IG9iczsKK30KKworcHJpdmF0ZSBpbnQgX2xvZ19jYWxsX291dChtaXhlZCBjbykKK3sKKyAgbG9nX2ZpbGUoIlRPT19NQU5ZX0NBTExPVVRTIiwKKyAgICAgIHNwcmludGYoIiVzOjolTyAoJWQpXG4iLG9iamVjdF9uYW1lKGNvWzBdKSxjb1sxXSxjb1syXSksCisgICAgICAyMDAwMDApOworICByZXR1cm4gMDsKK30KKworcHJpdmF0ZSBpbnQgbGFzdF9jYWxsb3V0X2xvZz0wOworCitub21hc2sgdmFyYXJncyB2b2lkIGNhbGxfb3V0KCB2YXJhcmdzIG1peGVkICphcmdzICkKK3sKKyAgICBtaXhlZCB0bXAsICpjYWxsX291dHM7CisKKyAgICAvLyBCZWkgPjYwMCBDYWxsb3V0cyBhbGxlIE9iamVrdGUga2lsbGVuLCBkaWUgbWVociBhbHMgMzAgQ2FsbG91dHMgbGF1ZmVuCisgICAgLy8gaGFiZW4uCisgICAgaWYgKCBlZnVuOjpkcml2ZXJfaW5mbyhESV9OVU1fQ0FMTE9VVFMpID4gNjAwCisgICAgICAgICYmIGdldGV1aWQocHJldmlvdXNfb2JqZWN0KCkpICE9IFJPT1RJRCApCisgICAgeworICAgICAgIC8vIExvZyBlcnpldWdlbi4uLgorICAgICAgIGlmIChsYXN0X2NhbGxvdXRfbG9nIDwKKyAgICAgICAgICAgZWZ1bjo6ZHJpdmVyX2luZm8oRElfTlVNX0hFQVJUQkVBVF9UT1RBTF9DWUNMRVMpIC0gMTAKKyAgICAgICAgICAgJiYgZ2V0X2V2YWxfY29zdCgpID4gMjAwMDAwKQorICAgICAgIHsKKyAgICAgICAgIGxhc3RfY2FsbG91dF9sb2cgPSBlZnVuOjpkcml2ZXJfaW5mbyhESV9OVU1fSEVBUlRCRUFUX1RPVEFMX0NZQ0xFUyk7CisgICAgICAgICBsb2dfZmlsZSgiVE9PX01BTllfQ0FMTE9VVFMiLAorICAgICAgICAgICAgIHNwcmludGYoIlxuJXM6ICMjIyMjIyMjIyMjIyBUb28gbWFueSBjYWxsb3V0czogJWQgIyMjIyMjIyMjIyMjIyNcbiIsCisgICAgICAgICAgICAgICAgICAgICBzdHJmdGltZSgiJXklbSVkLSVIJU0lUyIpLAorICAgICAgICAgICAgICAgICAgICAgZWZ1bjo6ZHJpdmVyX2luZm8oRElfTlVNX0NBTExPVVRTKSkpOworICAgICAgICAgZmlsdGVyKGVmdW46OmNhbGxfb3V0X2luZm8oKSwgIydfbG9nX2NhbGxfb3V0KTsKKyAgICAgICB9CisgICAgICAgLy8gT2JqZWt0ZSBhbGxlciBDYWxsb3V0cyBlcm1pdHRlbG4KKyAgICAgICBjYWxsX291dHMgPSBtYXAoIGVmdW46OmNhbGxfb3V0X2luZm8oKSwgIydfY2FsbF9vdXRfb2JqICk7CisgICAgICAgbWFwcGluZyBvYmplY3RtYXAgPSAoW10pOworICAgICAgIGZpbHRlciggY2FsbF9vdXRzLCAjJ19zYW1lX29iamVjdCwgJm9iamVjdG1hcCApOworICAgICAgIC8vIE1hc3RlciBuaWNodCBncmlsbGVuLi4uCisgICAgICAgZWZ1bjo6bV9kZWxldGUoIG9iamVjdG1hcCwgbWFzdGVyKDEpICk7CisgICAgICAgLy8gYWxsZSBPYmpla3RlIHJhdXNzdWNoZW4sIGRpZSB6dXZpZWxlIGhhYmVuLi4uCisgICAgICAgbWFwcGluZyByZXMgPSBmaWx0ZXJfaW5kaWNlcyggb2JqZWN0bWFwLCAjJ190b29fbWFueSwgb2JqZWN0bWFwLCAyOSApOworICAgICAgIC8vIHVuZCB1ZWJlciBhbGxlIEtleXMgZ2VoZW4sIGFuIF9kZXN0cm95KCkgd2VyZGVuIEtleSB1bmQgQXJyYXkgbWl0CisgICAgICAgLy8gT2JqZWt0ZW4gdWViZXJnZWJlbiAoaW4gZGllc2VtIEZhbGwgc2luZCBLZXlzIHVuZCBBcnJheSBtaXQKKyAgICAgICAvLyBPYmpla3RlbiBqZXdlaWxzIGRhcyBnbGVpY2hlIE9iamVrdCkuCisgICAgICAgaWYgKCBzaXplb2YocmVzKSApICAgICAgIAorICAgICAgICAgICB3YWxrX21hcHBpbmcocmVzLCAjJ19kZXN0cm95LCAiQ0FMTF9PVVQgb3ZlcmZsb3cgYnkgc2luZ2xlICIgICAgICAgICAgICAgCisgICAgICAgICAgICAgICJvYmplY3QgWyVPXS4gRGVzdHJ1Y3RlZCAlZCBvYmplY3RzLiBbJXNdXG4iLCAwICk7CisKKyAgICAgICAvLyBCZWkgKGF1Y2ggbmFjaCBkZW0gZXJzdGVuIEF1ZnJhZXVtZW4gbm9jaCkgPjgwMCBDYWxsb3V0cyBhbGxlCisgICAgICAgLy8gT2JqZWt0ZSBraWxsZW4sIGRpZSBtZWhyIGFscyA1MCBDYWxsb3V0cyBsYXVmZW4gaGFiZW4gLSB1bmQKKyAgICAgICAvLyBkaWVzbWFsIHphZWhsZW4gQ2xvbmVzIG5pY2h0IGVpZ2Vuc3RhZW5kaWchIEQuaC4gZXMgd2VyZGVuIGFsbGUKKyAgICAgICAvLyBDbG9uZXMgZWluZXIgQlAgZ2VraWxsdCwgZGllIENhbGxvdXRzIGxhdWZlbiBoYWJlbiwgZmFsbHMgYWxsZQorICAgICAgIC8vIGRpZXNlIE9iamVrdGUgX3p1c2FtbWVuXyBtZWhyIGFscyA1MCBDYWxsb3V0cyBoYWJlbiEKKyAgICAgICBpZiAoIGVmdW46OmRyaXZlcl9pbmZvKERJX05VTV9DQUxMT1VUUykgPiA4MDAgKSB7CisgICAgICAgICAgIC8vIHplcnN0b2VydGUgT2JqZWt0ZSB2b24gZGVyIGxldHp0ZW4gQWt0aW9uIHNpbmQgaW4gb2JqZWN0bWFwIG5pY2h0CisgICAgICAgICAgIC8vIG1laHIgZHJpbiwgZGEgc2llIGRvcnQgYWxzIEtleXMgdmVyd2VuZGV0IHd1cmRlbi4KKyAgICAgICAgICAgbWFwcGluZyBwYXRobWFwPShbXSk7CisgICAgICAgICAgIC8vIGFsbGUgT2JqZWt0IGVpbmVyIEJQIGluIHJlcyBzb3J0aWVyZW4sIEJQLU5hbWUgYWxzIEtleSwgQXJyYXlzCisgICAgICAgICAgIC8vIHZvbiBPYmpla3RlbiBhbHMgV2VydGUuCisgICAgICAgICAgIHdhbGtfbWFwcGluZyggb2JqZWN0bWFwLCAjJ19zYW1lX3BhdGgsICZwYXRobWFwKTsKKyAgICAgICAgICAgLy8gYWxsZSBCUHMgKHVuZCBpaHJlIE9iamVrdGUpIHJhdXNzdWNoZW4sIGRpZSB6dXZpZWxlIGhhYmVuLi4uCisgICAgICAgICAgIHJlcyA9IGZpbHRlcl9pbmRpY2VzKCBwYXRobWFwLCAjJ190b29fbWFueS8qJyovLCBwYXRobWFwLCA1MCApOworICAgICAgICAgICAvLyB1bmQgdWViZXIgYWxsZSBLZXlzIGdlaGVuLCBhbiBfZGVzdHJveSgpIHdlcmRlbiBkaWUgQ2xvbmVzCisgICAgICAgICAgIC8vIHVlYmVyZ2ViZW4sIGRpZSBDYWxsb3V0cyBoYWJlbi4KKyAgICAgICAgICAgaWYgKCBzaXplb2YocmVzKSApCisgICAgICAgICAgICAgIHdhbGtfbWFwcGluZyggcmVzLCAjJ19kZXN0cm95LyonKi8sICJDQUxMX09VVCBvdmVyZmxvdyBieSBmaWxlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICInJXMnLiBEZXN0cnVjdGVkICVkIG9iamVjdHMuIFslc11cbiIsIDAgKTsKKworICAgICAgICAgICAvLyBXZW5uIGJlaWRlIEF1ZnJhZXVtYXJiZWl0ZW4gbmljaHRzIGdlYnJhY2h0IGhhYmVuIHVuZCBpbW1lcgorICAgICAgICAgICAvLyBub2NoID4xMDAwIENhbGxvdXRzIGxhdWZlbiwgd2VyZGVuIGRpZXNtYWwgYWxsZSBDYWxsb3V0cworICAgICAgICAgICAvLyBlaW5lciBVSUQgenVzYW1tZW5nZXphZWhsdC4KKyAgICAgICAgICAgLy8gQWxsZSBPYmpla3RlIGVpbmVyIFVJRCwgZGllIGVzIGluIFN1bW1lIGFsbGVyIGlocmVyIE9iamVrdCBtaXQKKyAgICAgICAgICAgLy8gQ2FsbG91dHMgYXVmIG1laHIgYWxzIDEwMCBDYWxsb3V0cyBicmluZ3QsIHdlcmRlbiBnZXJvZXN0ZXQuCisgICAgICAgICAgIGlmIChlZnVuOjpkcml2ZXJfaW5mbyhESV9OVU1fQ0FMTE9VVFMpID4gMTAwMCkKKyAgICAgICAgICAgeworICAgICAgICAgICAgICAvLyBkYXMgbmFjaCBCUC1OYW1lbiB2b3JnZWZpbHRlcnRlIE1hcHBpbmcgamV0enQgbmFjaCBVSURzCisgICAgICAgICAgICAgIC8vIHp1c2FtbWVuc29ydGllcmVuLiBaZXJzdG9lcnRlIENsb25lcyBmaWx0ZXIgX3NhbWVfdWlkKCkKKyAgICAgICAgICAgICAgLy8gcmF1cy4KKyAgICAgICAgICAgICAgbWFwcGluZyB1aWRtYXA9KFtdKTsKKyAgICAgICAgICAgICAgd2Fsa19tYXBwaW5nKCBwYXRobWFwLCAjJ19zYW1lX3VpZCwgJnVpZG1hcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHN5bWJvbF9mdW5jdGlvbiggImNyZWF0b3JfZmlsZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiL3NlY3VyZS9tYXN0ZXIiICkgKTsKKyAgICAgICAgICAgICAgLy8gSW4gcmVzIG51biBVSURzIGFscyBLZXlzIHVuZCBBcnJheXMgdm9uIE9iamVrdGVuIGFscyBXZXJ0ZS4KKyAgICAgICAgICAgICAgLy8gRGllIHJhdXNmaWx0ZXJuLCBkaWUgbWVociBhbHMgMTAwIE9iamVrdGUgKG5vbi11bmlxdWUsIGQuaC4KKyAgICAgICAgICAgICAgLy8gMTAwIENhbGxvdXRzISkgaGFiZW4uCisgICAgICAgICAgICAgIHJlcyA9IGZpbHRlcl9pbmRpY2VzKCB1aWRtYXAsICMnX3Rvb19tYW55LCB1aWRtYXAsIDEwMCApOworICAgICAgICAgICAgICAvLyB1bmQgZXJuZXV0IHVlYmVyIGRpZSBLZXlzIGxhdWZlbiB1bmQgamV3ZWlscyBkaWUgQXJyYXlzIG1pdAorICAgICAgICAgICAgICAvLyBkZW4gT2JqZWt0ZW4genVyIFplcnN0b2VydW5nIGFuIF9kZXN0cm95KCkuLi4KKyAgICAgICAgICAgICAgaWYgKCBzaXplb2YocmVzKSApCisgICAgICAgICAgICAgICAgICB3YWxrX21hcHBpbmcoIHJlcywgIydfZGVzdHJveSwgIkNBTExfT1VUIG92ZXJmbG93IGJ5ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVSUQgJyVzJy4gRGVzdHJ1Y3RlZCAlZCBvYmplY3RzLiBbJXNdXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSApOworICAgICAgICAgICB9CisgICAgICAgfQorICAgIH0KKworICAgIC8vIEZhbGxzIGRhcyBhdWZydWZlbmRlIE9iamVrdCB6ZXJzdG9lcnQgd3VyZGUgYmVpbSBBdWZyYWV1bWVuCisgICAgaWYgKCAhcHJldmlvdXNfb2JqZWN0KCkgKQorICAgICAgIHJldHVybjsKKworICAgIHNldF90aGlzX29iamVjdCggcHJldmlvdXNfb2JqZWN0KCkgKTsKKyAgICBhcHBseSggIydlZnVuOjpjYWxsX291dCwgYXJncyApOworICAgIHJldHVybjsKK30KKworbWl4ZWQgY2FsbF9vdXRfaW5mbygpIHsKKyAgCisgIG9iamVjdCBwbyA9IHByZXZpb3VzX29iamVjdCgpOworICBtaXhlZCBjb2kgPSBlZnVuOjpjYWxsX291dF9pbmZvKCk7CisKKyAgLy8gdW5nZWZpbHRlcnRlbiBPdXRwdXQgbnVyIGZ1ZXIgYmVzdGltbXRlIE9iamVrdGUsIE9iamVrdGUgaW4gL3N0ZCBvZGVyCisgIC8vIC9vYmogaGFiZW4gZGllIEJhY2tib25lSUQuCisgIGlmIChxdWVyeV93aXpfbGV2ZWwoZ2V0dWlkKHBvKSkgPj0gQVJDSF9MVkwKKyAgICAgICB8fCAoc3RyaW5nKW1hc3RlcigpLT5jcmVhdG9yX2ZpbGUobG9hZF9uYW1lKHBvKSkgPT0gQkFDS0JPTkVJRCApIHsKKyAgICAgIHJldHVybiBjb2k7CisgIH0KKyAgZWxzZSB7CisgICAgICByZXR1cm4gZmlsdGVyKGNvaSwgZnVuY3Rpb24gbWl4ZWQgKG1peGVkIGFycikgeworICAgICAgICAgICAgICBpZiAocG9pbnRlcnAoYXJyKSAmJiBhcnJbMF09PXBvKQorICAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgICAgZWxzZSByZXR1cm4gMDsgfSk7CisgIH0KK30KKworLy8gKiBadSBlaW5lciBjbG9zdXJlIGRhcyBPYmpla3QsIGFuIGRhcyBzaWUgZ2VidW5kZW4gaXN0LCBzdWNoZW4KKy8vIE5JQ0hUIGRhcyBPYmpla3QsIHdhcyBnZ2YuIGRpZSBsZnVuIGRlZmluaWVydCEKK21peGVkIHF1ZXJ5X2Nsb3N1cmVfb2JqZWN0KGNsb3N1cmUgYykgeworICByZXR1cm4KKyAgICBDTE9TVVJFX0lTX1VOQk9VTkRfTEFNQkRBKGdldF90eXBlX2luZm8oYywgMSkpID8KKyAgICAgIDAgOgorICAodG9fb2JqZWN0KGMpIHx8IC0xKTsKK30KKworLy8gKiBXaXIgd29sbGVuIG51ciBFSU4gQXJndW1lbnQgLi4uIGF1c3NlcmRlbSBjaGVja3MgZnVlciBkZW4gTmV0enRvdGVucmF1bQordmFyYXJncyB2b2lkIG1vdmVfb2JqZWN0KG1peGVkIHdoYXQsIG1peGVkIHdoZXJlKQoreworICBvYmplY3QgcG8sdG1wOworCisgIHBvPXByZXZpb3VzX29iamVjdCgpOworICBpZiAoIXdoZXJlKQorICB7CisgICAgd2hlcmU9d2hhdDsKKyAgICB3aGF0PXBvOworICB9CisgIGlmICgoKHN0cmluZ3Aod2hlcmUpICYmIHdoZXJlPT1ORVRERUFEX1JPT00gKSB8fAorICAgICAgIChvYmplY3RwKHdoZXJlKSAmJiB3aGVyZT09ZmluZF9vYmplY3QoTkVUREVBRF9ST09NKSkpICYmCisgICAgICAgb2JqZWN0cCh3aGF0KSAmJiBvYmplY3RfbmFtZSh3aGF0KSE9Ii9vYmovc3BlcnJlciIpCisgIHsKKyAgICBpZiAoIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUod2hhdCkpCisgICAgeworICAgICAgd2hhdC0+cmVtb3ZlKCk7CisgICAgICBpZiAod2hhdCkgZGVzdHJ1Y3Qod2hhdCk7CisgICAgICByZXR1cm47CisgICAgfQorICAgIGlmIChsaXZpbmcod2hhdCkgfHwgaW50ZXJhY3RpdmUod2hhdCkpCisgICAgeworICAgICAgbG9nX2ZpbGUoIk5ERUFEMiIsc3ByaW50ZigiVFJZRUQgVE8gTU9WRSBUTyBORVRERUFEOiAlT1xuIix3aGF0KSk7CisgICAgICByZXR1cm47CisgICAgfQorICAgIHNldF9vYmplY3RfaGVhcnRfYmVhdCh3aGF0LDApOworICB9CisgIHRtcD13aGF0OworICB3aGlsZSAodG1wPWVudmlyb25tZW50KHRtcCkpCisgICAgICAvLyBKYS4gTWFuIHJ1ZnQgZGllIF9zZXRfeHh4KCktRnVua3Rpb25lbiBlaWdlbnRsaWNoIG5pY2h0IGRpcmVrdCBhdWYuCisgICAgICAvLyBBYmVyIGRhcyBMaWNodHN5c3RlbSBpc3Qgc2Nob24gKnNvKiByZWNoZW5pbnRlbnNpdiB1bmQgZ2VyYWRlIGRlcgorICAgICAgLy8gUF9MQVNUX0NPTlRFTlRfQ0hBTkdFLUNhY2hlIHdpcmQgKnNvKiBvZnQgYmVub2V0aWd0LCBkYXNzIGVzIG1pcgorICAgICAgLy8gZGEgdW0gamVkZXMgYmlzc2NoZW4gUmVjaGVuemVpdCBnZWh0LgorICAgICAgLy8gRGVyIFp3ZWNrIGhlaWxpZ3QgamEgYmVrYW5udGxpY2ggZGllIE1pdHRlbC4gOy0pCisgICAgICAvLworICAgICAgLy8gVGlhbWFrCisgICAgdG1wLT5fc2V0X2xhc3RfY29udGVudF9jaGFuZ2UoKTsKKyAgZnVuY2FsbChiaW5kX2xhbWJkYSgjJ2VmdW46Om1vdmVfb2JqZWN0LHBvKSx3aGF0LHdoZXJlKTsKKyAgaWYgKHRtcD13aGF0KQorICAgIHdoaWxlICh0bXA9ZW52aXJvbm1lbnQodG1wKSkKKyAgICAgIHRtcC0+X3NldF9sYXN0X2NvbnRlbnRfY2hhbmdlKCk7Cit9CisKKwordm9pZCBzdGFydF9zaW11bF9lZnVuKCkgeworICBtaXhlZCAqaW5mbzsKKworICAvLyBGYWxscyBub2NoIG5pY2h0IGdldGFuLCBleHRyYV93aXppbmZvIGluaXRpYWxpc2llcmVuCisgIGlmICggIXBvaW50ZXJwKGluZm8gPSBnZXRfZXh0cmFfd2l6aW5mbygwKSkgKQorICAgIHNldF9leHRyYV93aXppbmZvKDAsIGluZm8gPSBhbGxvY2F0ZShCQUNLQk9ORV9XSVpJTkZPX1NJWkUpKTsKKworICBJbml0TGl2aW5nRGF0YShpbmZvKTsKKworICBzZXRfbmV4dF9yZXNldCgxMCk7IC8vIGRpcmVrdCBtYWwgYXVmcmFldW1lbgorfQorCitwcm90ZWN0ZWQgdm9pZCByZXNldCgpIHsKKyAgc2V0X25leHRfcmVzZXQoNzIwMCk7CisgIENsZWFuTGl2aW5nRGF0YSgpOworfQorCisjaWYgIV9fRUZVTl9ERUZJTkVEX18oYWJzb2x1dGVfaGJfY291bnQpCitpbnQgYWJzb2x1dGVfaGJfY291bnQoKSB7CisgIHJldHVybiBlZnVuOjpkcml2ZXJfaW5mbyhESV9OVU1fSEVBUlRCRUFUX1RPVEFMX0NZQ0xFUyk7Cit9CisjZW5kaWYKKwordm9pZCBfX3NldF9lbnZpcm9ubWVudChvYmplY3Qgb2IsIG1peGVkIHRhcmdldCkKK3sKKyAgc3RyaW5nIHBhdGg7CisgIG9iamVjdCBvYmo7CisKKyAgaWYgKCFvYmplY3RwKG9iKSkKKyAgICByZXR1cm47CisgIGlmICghSVNfQVJDSChnZXRldWlkKHByZXZpb3VzX29iamVjdCgpKSkgfHwgIUFSQ0hfU0VDVVJJVFkgKQorICAgIHJldHVybjsKKyAgaWYgKG9iamVjdHAodGFyZ2V0KSkKKyAgeworICAgIGVmdW46OnNldF9lbnZpcm9ubWVudChvYix0YXJnZXQpOworICAgIHJldHVybjsKKyAgfQorICBwYXRoPShzdHJpbmcpTUFTVEVSLT5fZ2V0X3BhdGgodGFyZ2V0LHRoaXNfaW50ZXJhY3RpdmUoKSk7CisgIGlmIChzdHJpbmdwKHBhdGgpICYmIGZpbGVfc2l6ZShwYXRoKyIuYyIpPj0wICYmCisgICAgICAhY2F0Y2gobG9hZF9vYmplY3QocGF0aCk7cHVibGlzaCkgKQorICB7CisgICAgb2JqPWZpbmRfb2JqZWN0KHBhdGgpOworICAgIGVmdW46OnNldF9lbnZpcm9ubWVudChvYixvYmopOworICAgIHJldHVybjsKKyAgfQorfQorCit2b2lkIF9kdW1wX3dpemxpc3Qoc3RyaW5nIGZpbGUsIGludCBzb3J0YnkpIHsKKyAgaW50IGk7CisgIG1peGVkICphOworCisgIGlmICghTE9SRF9TRUNVUklUWSkKKyAgICByZXR1cm47CisgIGlmICghbWFzdGVyKCktPnZhbGlkX3dyaXRlKGZpbGUsZ2V0ZXVpZChwcmV2aW91c19vYmplY3QoKSksIndyaXRlX2ZpbGUiKSkKKyAgeworICAgIHdyaXRlKCJOTyBXUklURSBQRVJNSVNTSU9OXG4iKTsKKyAgICByZXR1cm47CisgIH0KKyAgYSA9IHdpemxpc3RfaW5mbygpOworICBhID0gc29ydF9hcnJheShhLCBsYW1iZGEoICh7J2EsJ2J9KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICh7Iyc8LAorICAgICAgICAgICAgICAgICAgICAgICAgICAoeyMnWywnYSxzb3J0Ynl9KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKHsjJ1ssJ2Isc29ydGJ5fSkKKyAgICAgICAgICAgICAgICAgICAgICAgICB9KSkpOworICBybShmaWxlKTsKKyAgZm9yIChpPXNpemVvZihhKS0xO2k+PTA7aS0tKQorICAgIHdyaXRlX2ZpbGUoZmlsZSxzcHJpbnRmKCIlLTExczogZXZhbD0lLThkIGNtZHM9JS02ZCBIQnM9JS01ZCBhcnJheT0lLTVkIG1hcHBpbmc9JS03ZFxuIiwKKyAgICAgIGFbaV1bV0xfTkFNRV0sYVtpXVtXTF9UT1RBTF9DT1NUXSxhW2ldW1dMX0NPTU1BTkRTXSxhW2ldW1dMX0hFQVJUX0JFQVRTXSwKKyAgICAgIGFbaV1bV0xfQVJSQVlfVE9UQUxdLGFbaV1bV0xfQ0FMTF9PVVRdKSk7Cit9CisKK3B1YmxpYyB2YXJhcmdzIG9iamVjdCBkZWVwX3ByZXNlbnQobWl4ZWQgd2hhdCwgb2JqZWN0IG9iKSB7CisKKyAgaWYoIW9iamVjdHAob2IpKQorICAgIG9iPXByZXZpb3VzX29iamVjdCgpOworICAvLyBXZW5uIGVpbiBPYmpla3QgZ2VzdWNodCB3aXJkOiBBbGxlIEVudnMgZGllc2VzIE9iamVrdHMgZXJtaXR0ZWxuIHVuZAorICAvLyBzY2hhdWVuLCBvYiBpbiBkaWVzZW4gb2Igdm9ya29tbXQuIERhbm4gaXN0IHdoYXQgaW4gb2IgZW50aGFsdGVuLgorICBpZihvYmplY3RwKHdoYXQpKSB7CisgICAgb2JqZWN0ICplbnZzPWFsbF9lbnZpcm9ubWVudCh3aGF0KTsKKyAgICAvLyB3ZW5uIG9iIGtlaW4gRW52aXJvbm1lbnQgaGF0LCBpc3QgZXMgb2ZmZW5zaWNodGxpY2ggbmljaHQgaW4gd2hhdAorICAgIC8vIGVudGhhbHRlbi4KKyAgICBpZiAoIXBvaW50ZXJwKGVudnMpKSByZXR1cm4gMDsKKyAgICBpZiAobWVtYmVyKGVudnMsIG9iKSAhPSAtMSkgcmV0dXJuIHdoYXQ7CisgIH0KKyAgLy8gc29uc3Qgd2lyZHMgdGV1cmVyLCB1ZWJlciBhbGxlIE9iamVrdGUgaW0gKGRlZXApIEludiBsYXVmZW4gdW5kIHBlciBpZCgpCisgIC8vIHRlc3Rlbi4gRGFiZWkgbXVzcyBhYmVyIGRpZSBnZXd1ZW5zY2h0ZSBOci4gKCJmbGFzY2hlIDMiKSBhYmdlc2Nobml0dGVuCisgIC8vIHdlcmRlbiB1bmQgc2VsYmVyIGdlemFlaGx0IHdlcmRlbiwgd2VsY2hlIGRhcyBlbnRzcHJlY2hlbmRlIE9iamVrdCBpc3QuCisgIGVsc2UgaWYgKHN0cmluZ3Aod2hhdCkpIHsKKyAgICAgIGludCBjbnQ7CisgICAgICBzdHJpbmcgbmV3d2hhdDsKKyAgICAgIGlmKHNzY2FuZih3aGF0LCIlcyAlZCIsbmV3d2hhdCxjbnQpIT0yKQorICAgICAgIGNudD0xOworICAgICAgZWxzZQorICAgICAgIHdoYXQ9bmV3d2hhdDsKKyAgICAgIGZvcmVhY2gob2JqZWN0IGludm9iOiBkZWVwX2ludmVudG9yeShvYikpIHsKKyAgICAgICBpZiAoaW52b2ItPmlkKHdoYXQpICYmICEtLWNudCkKKyAgICAgICAgICAgcmV0dXJuIGludm9iOworICAgICAgfQorICB9CisgIGVsc2UgeworICAgIHNldF90aGlzX29iamVjdChwcmV2aW91c19vYmplY3QoKSk7CisgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiV3JvbmcgYXJndW1lbnQgMSB0byBkZWVwX3ByZXNlbnQoKS4gIgorICAgICAgICAgIkV4cGVjdGVkIFwib2JqZWN0XCIgb3IgXCJzdHJpbmdcIiwgZ290ICUuNTBPLlxuIiwKKyAgICAgICAgIHdoYXQpKTsKKyAgfQorICByZXR1cm4gMDsKK30KKworbWFwcGluZyBkdW1wX2lwX21hcHBpbmcoKQoreworICByZXR1cm4gMDsKK30KKworbm9tYXNrIHZvaWQgc3dhcChvYmplY3Qgb2JqKQoreworICB3cml0ZSgiWW91ciBhcmUgbm90IGFsbG93ZWQgdG8gc3dhcCBvYmplY3RzIGJ5IGhhbmQhXG4iKTsKKyAgcmV0dXJuOworfQorCitub21hc2sgdmFyYXJncyB2b2lkIGdhcmJhZ2VfY29sbGVjdGlvbihzdHJpbmcgc3RyKQoreworICBpZihwcmV2aW91c19vYmplY3QoKT09MCB8fCAhSVNfQVJDSChnZXRldWlkKHByZXZpb3VzX29iamVjdCgpKSkgCisgICAgICB8fCAhQVJDSF9TRUNVUklUWSkKKyAgeworICAgIHdyaXRlKCJDYWxsIEdDIG5vdyBhbmQgdGhlIG11ZCB3aWxsIGNyYXNoIGluIDUtNiBob3Vycy4gRE9OVCBETyBJVCFcbiIpOworICAgIHJldHVybjsKKyAgfQorICBlbHNlIGlmIChzdHJpbmdwKHN0cikpCisgIHsKKyAgICByZXR1cm4gZWZ1bjo6Z2FyYmFnZV9jb2xsZWN0aW9uKHN0cik7CisgIH0KKyAgZWxzZSAKKyAgICByZXR1cm4gZWZ1bjo6Z2FyYmFnZV9jb2xsZWN0aW9uKCk7Cit9CisKK3ZhcmFyZ3Mgdm9pZCBub3RpZnlfZmFpbChtaXhlZCBuZiwgaW50IHByaW8pIHsKKyAgb2JqZWN0IHBvLG9sZG87CisgIGludCBvbGRwcmlvOworICAKKyAgaWYgKCFQTCB8fCAhb2JqZWN0cChwbz1wcmV2aW91c19vYmplY3QoKSkpIHJldHVybjsKKyAgaWYgKCFzdHJpbmdwKG5mKSAmJiAhY2xvc3VyZXAobmYpKSB7CisgICAgICBzZXRfdGhpc19vYmplY3QocG8pOworICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICJPbmx5IHN0cmluZ3MgYW5kIGNsb3N1cmVzIGFsbG93ZWQgZm9yIG5vdGlmeV9mYWlsISAiCisgICAgICAgICAiQXJndW1lbnQgd2FzOiAlLjUwTy4uLlxuIixuZikpOworICB9CisKKyAgLy8gZmFsbHMgZWluIE9iamVrdCBiZXJlaXRzIG5lbiBub3RpZnlfZmFpbCgpIHNldHp0ZSwgUHJpb3JpdGFldGVuIGFic2NoYWV0emVuCisgIC8vIHVuZCB2ZXJnbGVpY2hlbi4KKyAgaWYgKG9iamVjdHAob2xkbz1xdWVyeV9ub3RpZnlfZmFpbCgxKSkgJiYgcG8hPW9sZG8pIHsKKyAgICBpZiAoIXByaW8pIHsgICAgICAgCisgICAgICAvL1ByaW9yaXRhZXQgZGllc2VzIG5vdGlmeV9mYWlsKCkgJ2Fic2NoYWV0emVuJworICAgICAgaWYgKHBvPT1QTCkgLy8gU3BpZWxlci1pbnRlcm5lIChzb3VsLWNtZHMpCisgICAgICAgIHByaW89TkZfTkxfT1dOOworICAgICAgZWxzZSBpZiAobGl2aW5nKHBvKSkKKyAgICAgICAgcHJpbz1ORl9OTF9MSVZJTkc7CisgICAgICBlbHNlIGlmICgoaW50KXBvLT5Jc1Jvb20oKSkKKyAgICAgICAgcHJpbz1ORl9OTF9ST09NOworICAgICAgZWxzZQorICAgICAgICBwcmlvPU5GX05MX1RISU5HOworICAgIH0KKyAgICAvL1ByaW9yaXRhZXQgZGVzIGFsdGVuIFNldHplcnMgYWJzY2hhZXR6ZW4KKyAgICBpZiAob2xkbz09UEwpCisgICAgICBvbGRwcmlvPU5GX05MX09XTjsKKyAgICBlbHNlIGlmIChsaXZpbmcob2xkbykpCisgICAgICBvbGRwcmlvPU5GX05MX0xJVklORzsKKyAgICBlbHNlIGlmICgoaW50KW9sZG8tPklzUm9vbSgpKQorICAgICAgb2xkcHJpbz1ORl9OTF9ST09NOworICAgIGVsc2UKKyAgICAgIG9sZHByaW89TkZfTkxfVEhJTkc7CisgIH0KKyAgZWxzZSAvLyB3ZW5uIGVzIG5vY2gga2VpbiBOb3RpZnlfZmFpbCBnaWJ0OgorICAgIG9sZHByaW89TkZfTkxfTk9ORTsKKworICAvL3ZlcmdsZWljaGVuIHVuZCBnZ2YuIHNldHplbgorICBpZiAocHJpbyA+PSBvbGRwcmlvKSB7IAorICAgIHNldF90aGlzX29iamVjdChwbyk7CisgICAgZWZ1bjo6bm90aWZ5X2ZhaWwobmYpOworICB9CisKKyAgcmV0dXJuOworfQorCit2b2lkIF9ub3RpZnlfZmFpbChzdHJpbmcgc3RyKQoreworICAvL3F1ZXJ5X25vdGlmeV9mYWlsKCkgYmVudXR6ZW4sIHVtIGRhcyBPYmpla3QKKyAgLy9kZXMgbGV0enRlbiBub3RpZnlfZmFpbCgpIHp1IGVybWl0dGVsbgorICBvYmplY3QgbzsKKyAgaWYgKChvPXF1ZXJ5X25vdGlmeV9mYWlsKDEpKSAmJiBvIT1wcmV2aW91c19vYmplY3QoKSkKKyAgICByZXR1cm47CisgIC8vbm9jaCBrZWluIG5vdGlmeV9mYWlsKCkgZnVlciBkaWVzZXMgS29tbWFuZG8gZ2VzZXR6dCwgYXVmIGdlaHRzLgorICBzZXRfdGhpc19vYmplY3QocHJldmlvdXNfb2JqZWN0KCkpOworICBlZnVuOjpub3RpZnlfZmFpbChzdHIpOworICByZXR1cm47Cit9CisKK3N0cmluZyB0aW1lMnN0cmluZyggc3RyaW5nIGZvcm1hdCwgaW50IHplaXQgKQoreworICBpbnQgaSxjaCxtYXh1bml0LGR1bW15OworICBzdHJpbmcgKnBhcnRzLCBmbXQ7CisKKyAgaW50IHNlY3MgPSB6ZWl0OworICBpbnQgbWlucyA9ICh6ZWl0LzYwKTsKKyAgaW50IGhvdXJzID0gKHplaXQvMzYwMCk7CisgIGludCBkYXlzID0gKHplaXQvODY0MDApOworICBpbnQgd2Vla3MgPSAgKHplaXQvNjA0ODAwKTsKKyAgaW50IG1vbnRocyA9ICh6ZWl0LzI0MTkyMDApOworICBpbnQgYWJiciA9IDA7CisKKyAgcGFydHMgPSByZWdleHBsb2RlKCBmb3JtYXQsICJcKCVcKC18XClbMC05XSpbbndkaG1zeE5XREhNU1hdXCl8XCglJVwpIiApOworCisgIGZvciggaT0xOyBpPHNpemVvZihwYXJ0cyk7IGkrPTIgKQorICB7CisgICAgY2ggPSBwYXJ0c1tpXVs8MV07CisgICAgc3dpdGNoKCBwYXJ0c1tpXVs8MV0gKQorICAgIHsKKyAgICBjYXNlICd4JzogY2FzZSAnWCc6CisgICAgICAgYWJiciA9IHNzY2FuZiggcGFydHNbaV0sICIlJSVkIiwgZHVtbXkgKSAmJiBkdW1teT09MDsKKyAgICAgICAvLyBOTyBicmVhayAhCisgICAgY2FzZSAnbic6IGNhc2UgJ04nOgorICAgICAgIG1heHVuaXQgfD0gMzE7CisgICAgICAgYnJlYWs7CisgICAgY2FzZSAndyc6IGNhc2UgJ1cnOgorICAgICAgIG1heHVuaXQgfD0gMTU7CisgICAgICAgYnJlYWs7CisgICAgY2FzZSAnZCc6IGNhc2UgJ0QnOgorICAgICAgIG1heHVuaXQgfD0gNzsKKyAgICAgICBicmVhazsKKyAgICBjYXNlICdoJzogY2FzZSAnSCc6CisgICAgICAgbWF4dW5pdCB8PSAzOworICAgICAgIGJyZWFrOworICAgIGNhc2UgJ20nOiBjYXNlICdNJzoKKyAgICAgICBtYXh1bml0IHw9IDE7CisgICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIGlmKCBtYXh1bml0ICYgMTYgKSB3ZWVrcyAlPSA0OworICBpZiggbWF4dW5pdCAmIDggKSBkYXlzICU9IDc7CisgIGlmKCBtYXh1bml0ICYgNCApIGhvdXJzICU9IDI0OworICBpZiggbWF4dW5pdCAmIDIgKSBtaW5zICU9IDYwOworICBpZiggbWF4dW5pdCApIHNlY3MgJT0gNjA7CisKKyAgZm9yKCBpPTE7IGk8c2l6ZW9mKHBhcnRzKTsgaSs9MiApCisgIHsKKyAgICBmbXQgPSBwYXJ0c1tpXVswLi48Ml07CisgICAgY2ggPSBwYXJ0c1tpXVs8MV07CisgICAgaWYoIGNoPT0neCcgKQorICAgIHsKKyAgICAgIGlmIChtb250aHMgPiAwKSBjaD0nbic7CisgICAgICBlbHNlIGlmKCB3ZWVrcz4wICkgY2g9J3cnOworICAgICAgZWxzZSBpZiggZGF5cz4wICkgY2g9J2QnOworICAgICAgZWxzZSBpZiggaG91cnM+MCApIGNoPSdoJzsgCisgICAgICBlbHNlIGlmKG1pbnMgPiAwKSBjaCA9ICdtJzsKKyAgICAgIGVsc2UgY2ggPSAncyc7CisgICAgfQorICAgIGVsc2UgaWYoIGNoPT0nWCcgKQorICAgIHsKKyAgICAgIGlmIChtb250aHMgPiAwKSBjaD0nTic7CisgICAgICBlbHNlIGlmKCB3ZWVrcz4wICkgY2g9J1cnOworICAgICAgZWxzZSBpZiggZGF5cz4wICkgY2g9J0QnOworICAgICAgZWxzZSBpZiggaG91cnM+MCApIGNoPSdIJzsgCisgICAgICBlbHNlIGlmKG1pbnMgPiAwKSBjaCA9ICdNJzsKKyAgICAgIGVsc2UgY2ggPSAnUyc7CisgICAgfQorICAgIAorICAgIHN3aXRjaCggY2ggKQorICAgIHsKKyAgICAgIGNhc2UgJ24nOiBwYXJ0c1tpXSA9IHNwcmludGYoIGZtdCsiZCIsIG1vbnRocyApOyBicmVhazsKKyAgICAgIGNhc2UgJ3cnOiBwYXJ0c1tpXSA9IHNwcmludGYoIGZtdCsiZCIsIHdlZWtzICk7IGJyZWFrOworICAgICAgY2FzZSAnZCc6IHBhcnRzW2ldID0gc3ByaW50ZiggZm10KyJkIiwgZGF5cyApOyBicmVhazsKKyAgICAgIGNhc2UgJ2gnOiBwYXJ0c1tpXSA9IHNwcmludGYoIGZtdCsiZCIsIGhvdXJzICk7IGJyZWFrOworICAgICAgY2FzZSAnbSc6IHBhcnRzW2ldID0gc3ByaW50ZiggZm10KyJkIiwgbWlucyApOyBicmVhazsKKyAgICAgIGNhc2UgJ3MnOiBwYXJ0c1tpXSA9IHNwcmludGYoIGZtdCsiZCIsIHNlY3MgKTsgYnJlYWs7CisgICAgICBjYXNlICdOJzoKKyAgICAgICBpZihhYmJyKSBwYXJ0c1tpXSA9ICJNIjsKKyAgICAgICBlbHNlIHBhcnRzW2ldID0gc3ByaW50ZiggZm10KyJzIiwgKG1vbnRocz09MSkgPyAiTW9uYXQiIDogIk1vbmF0ZSIgKTsKKyAgICAgICBicmVhazsKKyAgICAgIGNhc2UgJ1cnOgorICAgICAgIGlmKGFiYnIpIHBhcnRzW2ldID0gInciOyBlbHNlCisgICAgICAgcGFydHNbaV0gPSBzcHJpbnRmKCBmbXQrInMiLCAod2Vla3M9PTEpID8gIldvY2hlIiA6ICJXb2NoZW4iICk7CisgICAgICAgYnJlYWs7CisgICAgICBjYXNlICdEJzoKKyAgICAgICBpZihhYmJyKSBwYXJ0c1tpXSA9ICJkIjsgZWxzZQorICAgICAgIHBhcnRzW2ldID0gc3ByaW50ZiggZm10KyJzIiwgKGRheXM9PTEpID8gIlRhZyIgOiAiVGFnZSIgKTsKKyAgICAgICBicmVhazsKKyAgICAgIGNhc2UgJ0gnOgorICAgICAgIGlmKGFiYnIpIHBhcnRzW2ldID0gImgiOyBlbHNlCisgICAgICAgcGFydHNbaV0gPSBzcHJpbnRmKCBmbXQrInMiLCAoaG91cnM9PTEpID8gIlN0dW5kZSIgOiAiU3R1bmRlbiIgKTsKKyAgICAgICBicmVhazsKKyAgICAgIGNhc2UgJ00nOgorICAgICAgIGlmKGFiYnIpIHBhcnRzW2ldID0gIm0iOyBlbHNlCisgICAgICAgcGFydHNbaV0gPSBzcHJpbnRmKCBmbXQrInMiLCAobWlucz09MSkgPyAiTWludXRlIiA6ICJNaW51dGVuIiApOworICAgICAgIGJyZWFrOworICAgICAgY2FzZSAnUyc6CisgICAgICAgaWYoYWJicikgcGFydHNbaV0gPSAicyI7IGVsc2UKKyAgICAgICBwYXJ0c1tpXSA9IHNwcmludGYoIGZtdCsicyIsIChzZWNzPT0xKSA/ICJTZWt1bmRlIiA6ICJTZWt1bmRlbiIgKTsKKyAgICAgICBicmVhazsKKyAgICAgIGNhc2UgJyUnOgorICAgICAgIHBhcnRzW2ldID0gIiUiOworICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gaW1wbG9kZSggcGFydHMsICIiICk7Cit9CisKK25vbWFzayBtaXhlZCBfX2NyZWF0ZV9wbGF5ZXJfZHVtbXkoc3RyaW5nIG5hbWUpCit7CisgIHN0cmluZyBlcnI7CisgIG9iamVjdCBvYjsKKyAgbWl4ZWQgbTsKKyAgLy9oYXQgbmVuIFNjaGVyemtla3MgZGllIEJsdWVwcmludCBiZXdlZ3Q/CisgIGlmICgob2I9ZmluZF9vYmplY3QoIi9zZWN1cmUvbG9naW4iKSkgJiYgZW52aXJvbm1lbnQob2IpKQorICAgICAgY2F0Y2goZGVzdHJ1Y3Qob2IpO3B1Ymxpc2gpOworICBlcnIgPSBjYXRjaChvYiA9IGNsb25lX29iamVjdCgic2VjdXJlL2xvZ2luIik7cHVibGlzaCk7CisgIGlmIChlcnIpCisgIHsKKyAgICB3cml0ZSgiRmVobGVyIGJlaW0gTGFkZW4gdm9uIC9zZWN1cmUvbG9naW4uY1xuIitlcnIrIlxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKG9iamVjdHAobT0obWl4ZWQpb2ItPm5ld19sb2dvbihuYW1lKSkpIG5ldGRlYWRbbmFtZV09bTsKKyAgcmV0dXJuIG07Cit9CisKK25vbWFzayBpbnQgc2VjdXJlX2xldmVsKCkKK3sKKyAgaW50ICpsZXZlbDsKKyAgLy9rZXR0ZSBkZXIgQ2FsbGVyIGR1cmNobGF1ZmVuLCBkZW4gbmllZHJpZ3N0ZW4gTGV2ZWwgaW4gZGVyIEtldHRlCisgIC8venVydWVja2dlYmVuLiBaZXJzdG9lcnRlIE9iamVrdGUgKFNlbGJzdHplcnN0b2VyZXIpIGZ1ZWhyZW4genVyIFJ1ZWNrZ2FiZQorICAvL3ZvbiAwLgorICAvL2NhbGxlcl9zdGFjaygxKSBmdWVndCBkZW0gUnVlY2tnYWJlYXJyYXkgdGhpc19pbnRlcmFjdGl2ZSgpIGhpbnp1IGJ6dy4gMCwKKyAgLy93ZW5uIGVzIGtlaW5lbiBJbnRlcmFjdGl2ZSBnaWJ0LiBEaWUgMCBmdWVocnQgZGFubiB3aWUgYmVpIHplcnN0b2VydGVuCisgIC8vT2JqZWt0ZW4genVyIFJ1ZWNrZ2FiZSB2b24gMCwgd2FzIGdld3VlbnNjaHQgaXN0LCBkYSBlcyBoaWVyIGVpbmVuCisgIC8vSU50ZXJhY3RpdmUgZ2ViZW4gbXVzcy4KKyAgbGV2ZWw9bWFwKGNhbGxlcl9zdGFjaygxKSxmdW5jdGlvbiBpbnQgKG9iamVjdCBjYWxsZXIpCisgICAgICB7aWYgKG9iamVjdHAoY2FsbGVyKSkKKyAgICAgICByZXR1cm4ocXVlcnlfd2l6X2xldmVsKGdldGV1aWQoY2FsbGVyKSkpOworICAgICAgIHJldHVybigwKTsgLy8ga2VpbiBPYmpla3QgZGEsIDAuCisgICAgICB9ICk7CisgIHJldHVybihtaW4obGV2ZWwpKTsgLy9kZW4ga2xlaW5zdGVuIFdlcnQgaW0gQXJyYXkgenVydWVja2dlYmVuIChnZ2YuIDApCit9CisKK25vbWFzayBzdHJpbmcgc2VjdXJlX2V1aWQoKQoreworICBzdHJpbmcgZXVpZDsKKworICBpZiAoIXRoaXNfaW50ZXJhY3RpdmUoKSkgLy8gRXMgbXVzcyBlaW5lbiBpbnRlcmFjdGl2ZSBnZWJlbgorICAgICByZXR1cm4gMDsKKyAgZXVpZD1nZXRldWlkKHRoaXNfaW50ZXJhY3RpdmUoKSk7CisgIC8vIHVlYmVyIGFsbGUgQ2FsbGVyIGl0ZXJpZXJlbi4gV2VubiBlaW5lcyBkYXZvbiBlaW5lIGFuZGVyZSBldWlkIGhhdCBhbHMKKyAgLy8gZGVyIEludGVyYWN0aXZlIHVuZCBkaWVzZSBuaWNodCBkaWUgUk9PVElEIGlzdCwgd2lyZCAwIHp1cnVlY2tnZWJlbi4KKyAgLy8gRWJlbnNvLCBmYWxscyBlaW4gU2VsYnN0emVyc3RvZXJlciBpcmdlbmR3byBpbiBkZXIgS2V0dGUgaXN0LgorICBmb3JlYWNoKG9iamVjdCBjYWxsZXI6IGNhbGxlcl9zdGFjaygpKSB7CisgICAgICBpZiAoIW9iamVjdHAoY2FsbGVyKSB8fAorICAgICAgIChnZXRldWlkKGNhbGxlcikhPWV1aWQgJiYgZ2V0ZXVpZChjYWxsZXIpIT1ST09USUQpKQorICAgICAgICAgcmV0dXJuIDA7CisgIH0KKyAgcmV0dXJuIGV1aWQ7IC8vICdzaWNoZXJlJyBldWlkIHp1cnVlY2tnZWJlbgorfQorCisvLyBJTlBVVF9QUk9NUFQgdW5kIG5lbiBMZWVycHJvbXB0IGhpbnp1ZnVlZ2VuLCB3ZW5uIGtlaW5zIHVlYmVyZ2ViZW4gd2lyZC4KKy8vIERhcyBzb2xsIGRhenUgZGllbmVuLCBkYXNzIGFsbGUgZ2dmLiBlaW4gRU9SIGFtIFByb21wdGVuZGUga3JpZWdlbi4uLgorLy8jaWYgX19CT09UX1RJTUVfXyA8IDEzNjAwMTcyMTMKK3ZhcmFyZ3Mgdm9pZCBpbnB1dF90byggbWl4ZWQgZnVuLCBpbnQgZmxhZ3MsIHZhcmFyZ3MgbWl4ZWQgKmFyZ3MgKQoreworICAgIG1peGVkICphcnI7CisgICAgaW50IGk7CisKKyAgICBpZiAoICF0aGlzX3BsYXllcigpIHx8ICFwcmV2aW91c19vYmplY3QoKSApCisgICAgICAgcmV0dXJuOworCisgICAgLy8gVE9ETzogaW5wdXRfdG8oLi4uLElOUFVUX1BST01QVCwgIiIsIC4uLiksIHdlbm4ga2VpbiBJTlBVVF9QUk9NUFQKKyAgICAvLyB2b3Jrb21tdC4uLgorICAgIGlmICggZmxhZ3MmSU5QVVRfUFJPTVBUICkgeyAgICAKKyAgICAgICAgYXJyID0gKHsgZnVuLCBmbGFncyB9KSArIGFyZ3M7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvLyBnZ2YuIGVpbiBJTlBVVF9QUk9NUFQgaGluenVmdWVnZW4gdW5kIG5lbiBMZWVyc3RyaW5nIGFscyBQcm9tcHQuCisgICAgICAgIGZsYWdzIHw9IElOUFVUX1BST01QVDsKKyAgICAgICAgYXJyID0gKHsgZnVuLCBmbGFncywgIiIgfSkgKyBhcmdzOworICAgIH0KKworICAgIC8vIEFycmF5cyBnZWdlbiBmbGF0dGVuIHF1b3Rlbi4KKyAgICBmb3IgKCBpID0gc2l6ZW9mKGFycikgLSAxOyBpID4gMTsgaS0tICkKKyAgICAgICBpZiAoIHBvaW50ZXJwKGFycltpXSkgKQorICAgICAgICAgICBhcnJbaV0gPSBxdW90ZShhcnJbaV0pOworCisgICAgYXBwbHkoIGJpbmRfbGFtYmRhKCB1bmJvdW5kX2xhbWJkYSggKHt9KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoeyAjJ2VmdW46OmlucHV0X3RvLyonKi8gfSkgKyBhcnIgKSwKKyAgICAgICAgICAgICAgICAgICAgICAgcHJldmlvdXNfb2JqZWN0KCkgKSApOworfQorLy8jZW5kaWYKKworbm9tYXNrIGludCBzZXRfbGlnaHQoaW50IGkpCisvLyBlcmhvZWh0IGRhcyBMaWNodGxldmVsIGVpbmVzIE9iamVrdHMgdW0gaQorLy8gcmVzdWx0OiBkYXMgTGljaHRsZXZlbCBpbm5lcmhhbGIgZGVzIE9iamVrdHMKK3sKKyAgICBvYmplY3Qgb2IsICppbnY7CisgICAgaW50IGxhbGwsIGxpZ2h0LCBkYXJrLCB0bXA7CisKKyAgICBpZiAoIShvYj1wcmV2aW91c19vYmplY3QoKSkpIHJldHVybiAwOyAvLyBvaG5lIGRhcyBnZWh0cyBuaWNodC4KKworICAgIC8vIGF1cyBrb21wYXRpYmlsaXRhZXRzZ3J1ZW5kZW4ga2FubiBtYW4gYXVjaCBkZW4gTGljaHRsZXZlbCBub2NoIHNldHplbgorICAgIGlmIChpIT0wKSBvYi0+U2V0UHJvcChQX0xJR0hULCBvYi0+UXVlcnlQcm9wKFBfTElHSFQpK2kpOworCisgICAgLy8gTGljaHRiZXJlY2hudW5nIGZpbmRldCBlaWdlbnRsaWNoIGluIGRlciBNdWRsaWIgc3RhdHQuCisgICAgcmV0dXJuIChpbnQpb2ItPlF1ZXJ5UHJvcChQX0lOVF9MSUdIVCk7Cit9CisKKworcHVibGljIHN0cmluZyBpc28yYXNjaWkoIHN0cmluZyBzdHIgKQoreworICAgIGlmICggIXN0cmluZ3Aoc3RyKSB8fCAhc2l6ZW9mKHN0cikgKQorICAgICAgIHJldHVybiAiIjsKKworICAgIHN0ciA9IHJlZ3JlcGxhY2UoIHN0ciwgIuQiLCAiYWUiLCAxICk7CisgICAgc3RyID0gcmVncmVwbGFjZSggc3RyLCAi9iIsICJvZSIsIDEgKTsKKyAgICBzdHIgPSByZWdyZXBsYWNlKCBzdHIsICL8IiwgInVlIiwgMSApOworICAgIHN0ciA9IHJlZ3JlcGxhY2UoIHN0ciwgIsQiLCAiQWUiLCAxICk7CisgICAgc3RyID0gcmVncmVwbGFjZSggc3RyLCAi1iIsICJPZSIsIDEgKTsKKyAgICBzdHIgPSByZWdyZXBsYWNlKCBzdHIsICLcIiwgIlVlIiwgMSApOworICAgIHN0ciA9IHJlZ3JlcGxhY2UoIHN0ciwgIt8iLCAic3MiLCAxICk7CisgICAgc3RyID0gcmVncmVwbGFjZSggc3RyLCAiW14gLX5dIiwgIj8iLCAxICk7CisKKyAgICByZXR1cm4gc3RyOworfQorCisKK3B1YmxpYyB2YXJhcmdzIHN0cmluZyBDb3VudFVwKCBzdHJpbmcgKnMsIHN0cmluZyBzZXAsIHN0cmluZyBsYXN0c2VwICkKK3sKKyAgICBzdHJpbmcgcmV0OworCisgICAgaWYgKCAhcG9pbnRlcnAocykgKQorICAgICAgIHJldHVybiAiIjsKKyAgICAKKyAgICBpZiAoIXNlcCkgc2VwID0gIiwgIjsKKyAgICBpZiAoIWxhc3RzZXApIGxhc3RzZXAgPSAiIHVuZCAiOworCisgICAgc3dpdGNoIChzaXplb2YocykpICB7CisgICAgICAgY2FzZSAwOiByZXQ9IiI7IGJyZWFrOworICAgICAgIGNhc2UgMTogcmV0PXNbMF07IGJyZWFrOworICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgIHJldCA9IGltcGxvZGUoc1swLi48Ml0sIHNlcCk7CisgICAgICAgICAgICAgIHJldCArPSBsYXN0c2VwICsgc1s8MV07CisgICAgfQorICAgIHJldHVybiByZXQ7Cit9CisKK25vbWFzayB2YXJhcmdzIGludCBxdWVyeV9uZXh0X3Jlc2V0KG9iamVjdCBvYikgeworCisgICAgLy8gVHlwcHJ1ZWZ1bmc6IGV0d2FzIGFuZGVyZXMgYWxzIE9iamVrdGUgb2RlciAwIHNvbGxlbiBGZWhsZXIgc2Vpbi4KKyAgICBpZiAob2IgJiYgIW9iamVjdHAob2IpKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiQmFkIGFyZyAxIHRvIHF1ZXJ5X25leHRfcmVzZXQoKTogZ290ICUuMjBPLCAiCisgICAgICAgICAgICJleHBlY3RlZCBvYmplY3QuXG4iLG9iKSk7CisKKyAgICAvLyBEZWZhdWx0b2JqZWt0IFBPLCB3ZW5uIDAgdWViZXJnZWJlbi4KKyAgICBpZiAoICFvYmplY3RwKG9iKSApCisgICAgICBvYiA9IHByZXZpb3VzX29iamVjdCgpOworCisgICAgcmV0dXJuIGVmdW46Om9iamVjdF9pbmZvKG9iLCBPSV9ORVhUX1JFU0VUX1RJTUUpOworfQorCisKKyNpZiAhX19FRlVOX0RFRklORURfXyhjb3B5X2ZpbGUpCisjZGVmaW5lIE1BWExFTiA1MDAwMAorbm9tYXNrIGludCBjb3B5X2ZpbGUoc3RyaW5nIHNvdXJjZSwgc3RyaW5nIGRlc3QpCit7CisKKyAgaW50IHB0cjsKKyAgc3RyaW5nIGJ5dGVzOworCisgIHNldF90aGlzX29iamVjdChwcmV2aW91c19vYmplY3QoKSk7CisgIGlmICghc2l6ZW9mKHNvdXJjZSl8fCFzaXplb2YoZGVzdCl8fHNvdXJjZT09ZGVzdHx8KGZpbGVfc2l6ZShzb3VyY2UpPT0tMSl8fAorICAgICAgKCFjYWxsX290aGVyKG1hc3RlcigpLCJ2YWxpZF9yZWFkIixzb3VyY2UsCisgICAgICAgICAgICAgICAgICAgZ2V0dWlkKHRoaXNfaW50ZXJhY3RpdmUoKXx8CisgICAgICAgICAgICAgICAgIHByZXZpb3VzX29iamVjdCgpKSwicmVhZF9maWxlIixwcmV2aW91c19vYmplY3QoKSkpfHwKKyAgICAgICghY2FsbF9vdGhlcihtYXN0ZXIoKSwidmFsaWRfcmVhZCIsc291cmNlLAorICAgICAgICAgICAgICAgICAgIGdldHVpZCh0aGlzX2ludGVyYWN0aXZlKCl8fAorICAgICAgICAgICAgICAgICBwcmV2aW91c19vYmplY3QoKSksIndyaXRlX2ZpbGUiLHByZXZpb3VzX29iamVjdCgpKSkpCisgICAgcmV0dXJuIDE7CisgIHN3aXRjaCAoZmlsZV9zaXplKGRlc3QpKQorICB7CisgIGNhc2UgLTE6CisgICAgYnJlYWs7CisgIGNhc2UgLTI6CisgICAgaWYgKGRlc3RbPDFdIT0nLycpIGRlc3QrPSIvIjsKKyAgICBkZXN0Kz1lZnVuOjpleHBsb2RlKHNvdXJjZSwiLyIpWzwxXTsKKyAgICBpZiAoZmlsZV9zaXplKGRlc3QpPT0tMikgcmV0dXJuIDE7CisgICAgaWYgKGZpbGVfc2l6ZShkZXN0KSE9LTEpIGJyZWFrOworICBkZWZhdWx0OgorICAgIGlmICghcm0oZGVzdCkpIHJldHVybiAxOworICAgIGJyZWFrOworICB9CisgIGRvCisgIHsKKyAgICBieXRlcyA9IHJlYWRfYnl0ZXMoc291cmNlLCBwdHIsIE1BWExFTik7IHB0ciArPSBNQVhMRU47CisgICAgaWYgKCFieXRlcykgYnl0ZXM9IiI7CisgICAgd3JpdGVfZmlsZShkZXN0LCBieXRlcyk7CisgIH0KKyAgd2hpbGUoc2l6ZW9mKGJ5dGVzKSA9PSBNQVhMRU4pOworICByZXR1cm4gMDsKK30KKyNlbmRpZiAvLyFfX0VGVU5fREVGSU5FRF9fKGNvcHlfZmlsZSkKKworCisvLyAjIyMgRXJzYXR6YXVmbG9lc3VuZyBpbiBTdHJpbmdzICMjIwordmFyYXJncyBzdHJpbmcgcmVwbGFjZV9wZXJzb25hbChzdHJpbmcgc3RyLCBtaXhlZCAqb2JzLCBpbnQgY2FwcykgeworICBpbnQgaTsKKyAgc3RyaW5nICpwYXJ0czsKKworICBwYXJ0cyA9IHJlZ2V4cGxvZGUoc3RyLCAiQFdFW0EtU1VdKlswLTldIik7CisgIGkgPSBzaXplb2YocGFydHMpOworCisgIGlmIChpPjEpIHsKKyAgICBpbnQgaiwgdDsKKyAgICBjbG9zdXJlICpuYW1lX2NsczsKKworICAgIHQgPSBqID0gc2l6ZW9mKG9icyk7CisKKyAgICBuYW1lX2NscyAgPSAgYWxsb2NhdGUoaik7CisgICAgd2hpbGUgKGotLSkKKyAgICAgIGlmIChvYmplY3RwKG9ic1tqXSkpCisgICAgICAgIG5hbWVfY2xzW2pdID0gc3ltYm9sX2Z1bmN0aW9uKCJuYW1lIiwgb2JzW2pdKTsKKyAgICAgIGVsc2UgaWYgKHN0cmluZ3Aob2JzW2pdKSkKKyAgICAgICAgbmFtZV9jbHNbal0gPSBvYnNbal07CisKKyAgICB3aGlsZSAoKGktPSAyKT4wKSB7CisgICAgICBpbnQgb2JfbnI7CisgICAgICAvLyB6dSBlcnNldHplbmRlcyBUb2tlbiBpbiBGYWxsIHVuZCBPYmpla3RpbmRleCBhdWZzcGFsdGVuCisgICAgICBvYl9uciA9IHBhcnRzW2ldWzwxXS0nMSc7CisgICAgICBpZiAob2JfbnI8MCB8fCBvYl9ucj49dCkgeworICAgICAgICBzZXRfdGhpc19vYmplY3QocHJldmlvdXNfb2JqZWN0KCkpOworICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJyZXBsYWNlX3BlcnNvbmFsOiB1c2luZyB3cm9uZyBvYmplY3QgaW5kZXggJWRcbiIsCisgICAgICAgICAgICAgICAgICAgIG9iX25yKSk7CisgICAgICAgIHJldHVybiBpbXBsb2RlKHBhcnRzLCAiIik7CisgICAgICB9CisKKyAgICAgIC8vIGNhc3VzIGthbm4gbWFuIHNjaG9uIGhpZXIgZW50c2NoZWlkZW4KKyAgICAgIGludCBjYXN1czsKKyAgICAgIHN0cmluZyBwYXJ0ID0gcGFydHNbaV07CisgICAgICBzd2l0Y2ggKHBhcnRbM10pIHsKKyAgICAgICAgY2FzZSAnUic6IGNhc3VzID0gV0VSOyAgICBicmVhazsKKyAgICAgICAgY2FzZSAnUyc6IGNhc3VzID0gV0VTU0VOOyBicmVhazsKKyAgICAgICAgY2FzZSAnTSc6IGNhc3VzID0gV0VNOyAgICBicmVhazsKKyAgICAgICAgY2FzZSAnTic6IGNhc3VzID0gV0VOOyAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDogIGNvbnRpbnVlOyAvLyBwYXNzdCBzY2hvbiBqZXR6dCBuaWNodCBpbiBkYXMgSGF1cHRtdXN0ZXIKKyAgICAgIH0KKworICAgICAgLy8gdW5kIGpldHp0IGRpZSBlaW56ZWxuZW4gS2V5d29yZHMgb2huZSBmdWVocmVuZGVzICJAV0UiLCBiZWVuZGVuZGUgSWQKKyAgICAgIG1peGVkIHRtcDsKKyAgICAgIHN3aXRjaCAocGFydFszLi48Ml0pIHsKKyAgICAgICAgY2FzZSAiUiI6IGNhc2UgIlNTRU4iOiBjYXNlICJNIjogY2FzZSAiTiI6ICAgICAgICAgICAgICAgLy8gTmFtZQorICAgICAgICAgIHBhcnRzW2ldID0gZnVuY2FsbChuYW1lX2Nsc1tvYl9ucl0sIGNhc3VzLCAxKTsgIGJyZWFrOworICAgICAgICBjYXNlICJSVSI6IGNhc2UgIlNTRU5VIjogY2FzZSAiTVUiOiBjYXNlICJOVSI6ICAgICAgICAgICAvLyB1bmJlc3RpbW10CisgICAgICAgICAgcGFydHNbaV0gPSBmdW5jYWxsKG5hbWVfY2xzW29iX25yXSwgY2FzdXMpOyAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgIlJRUCI6IGNhc2UgIlNTRU5RUCI6IGNhc2UgIk1RUCI6IGNhc2UgIk5RUCI6ICAgICAgIC8vIFByb25vdW4KKyAgICAgICAgICBpZiAob2JqZWN0cCh0bXAgPSBvYnNbb2JfbnJdKSkKKyAgICAgICAgICAgIHBhcnRzW2ldID0gKHN0cmluZyl0bXAtPlF1ZXJ5UHJvbm91bihjYXN1cyk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgIlJRQSI6IGNhc2UgIlNTRU5RQSI6IGNhc2UgIk1RQSI6IGNhc2UgIk5RQSI6ICAgICAgIC8vIEFydGljbGUKKyAgICAgICAgICBpZiAob2JqZWN0cCh0bXAgPSBvYnNbb2JfbnJdKSkKKyAgICAgICAgICAgIHRtcCA9IChzdHJpbmcpdG1wLT5RdWVyeUFydGljbGUoY2FzdXMsIDEsIDEpOworICAgICAgICAgIGlmIChzdHJpbmdwKHRtcCkgJiYgISh0bXBbPDFdXicgJykpIAorICAgICAgICAgICAgdG1wID0gdG1wWzAuLjwyXTsgICAgICAgICAgICAgICAgLy8gRXh0cmEtU3BhY2Ugd2llZGVyIGxvZXNjaGVuCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgIlJRUFBNUyI6IGNhc2UgIlNTRU5RUFBNUyI6IGNhc2UgIk1RUFBNUyI6IGNhc2UgIk5RUFBNUyI6CisgICAgICAgICAgaWYgKG9iamVjdHAodG1wID0gb2JzW29iX25yXSkpCisgICAgICAgICAgICBwYXJ0c1tpXSA9IChzdHJpbmcpdG1wLT5RdWVyeVBvc3NQcm9ub3VuKE1BTEUsIGNhc3VzLCBTSU5HVUxBUik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgIlJRUFBGUyI6IGNhc2UgIlNTRU5RUFBGUyI6IGNhc2UgIk1RUFBGUyI6IGNhc2UgIk5RUFBGUyI6CisgICAgICAgICAgaWYgKG9iamVjdHAodG1wID0gb2JzW29iX25yXSkpCisgICAgICAgICAgICBwYXJ0c1tpXSA9IChzdHJpbmcpdG1wLT5RdWVyeVBvc3NQcm9ub3VuKEZFTUFMRSwgY2FzdXMsIFNJTkdVTEFSKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAiUlFQUE5TIjogY2FzZSAiU1NFTlFQUE5TIjogY2FzZSAiTVFQUE5TIjogY2FzZSAiTlFQUE5TIjoKKyAgICAgICAgICBpZiAob2JqZWN0cCh0bXAgPSBvYnNbb2JfbnJdKSkKKyAgICAgICAgICAgIHBhcnRzW2ldID0gKHN0cmluZyl0bXAtPlF1ZXJ5UG9zc1Byb25vdW4oTkVVVEVSLCBjYXN1cywgU0lOR1VMQVIpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICJSUVBQTVAiOiBjYXNlICJTU0VOUVBQTVAiOiBjYXNlICJNUVBQTVAiOiBjYXNlICJOUVBQTVAiOgorICAgICAgICAgIGlmIChvYmplY3RwKHRtcCA9IG9ic1tvYl9ucl0pKQorICAgICAgICAgICAgcGFydHNbaV0gPSAoc3RyaW5nKXRtcC0+UXVlcnlQb3NzUHJvbm91bihNQUxFLCBjYXN1cywgUExVUkFMKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAiUlFQUEZQIjogY2FzZSAiU1NFTlFQUEZQIjogY2FzZSAiTVFQUEZQIjogY2FzZSAiTlFQUEZQIjoKKyAgICAgICAgICBpZiAob2JqZWN0cCh0bXAgPSBvYnNbb2JfbnJdKSkKKyAgICAgICAgICAgIHBhcnRzW2ldID0gKHN0cmluZyl0bXAtPlF1ZXJ5UG9zc1Byb25vdW4oRkVNQUxFLCBjYXN1cywgUExVUkFMKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAiUlFQUE5QIjogY2FzZSAiU1NFTlFQUE5QIjogY2FzZSAiTVFQUE5QIjogY2FzZSAiTlFQUE5QIjoKKyAgICAgICAgICBpZiAob2JqZWN0cCh0bXAgPSBvYnNbb2JfbnJdKSkKKyAgICAgICAgICAgIHBhcnRzW2ldID0gKHN0cmluZyl0bXAtPlF1ZXJ5UG9zc1Byb25vdW4oTkVVVEVSLCBjYXN1cywgUExVUkFMKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIAorICAgICAgLy8gd2VubiB0bXAgZWluIFN0cmluZyB3YXIsIHdlaXNlbiB3aXIgZXMgaGllciBwYXVzY2hhbCB6dQorICAgICAgaWYgKHN0cmluZ3AodG1wKSkKKyAgICAgICAgcGFydHNbaV0gPSB0bXA7CisKKyAgICAgIC8vIGF1ZiBXdW5zY2ggd2lyZCBuYWNoIFNhdHplbmRlbiBncm9zcyBnZXNjaHJpZWJlbgorICAgICAgaWYgKGNhcHMpCisgICAgICAgIHN3aXRjaCAocGFydHNbaS0xXVs8Mi4uXSkgeworICAgICAgICAgIGNhc2UgIi4gIjogIGNhc2UgIiEgIjogIGNhc2UgIj8gIjoKKyAgICAgICAgICBjYXNlICIuIjogICBjYXNlICIhIjogICBjYXNlICI/IjoKKyAgICAgICAgICBjYXNlICIuXG4iOiBjYXNlICIhXG4iOiBjYXNlICI/XG4iOgorICAgICAgICAgIGNhc2UgIlwiICI6IGNhc2UgIlwiXG4iOgorICAgICAgICAgICAgcGFydHNbaV0gPSBjYXBpdGFsaXplKHBhcnRzW2ldKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBpbXBsb2RlKHBhcnRzLCAiIik7CisgIH0KKyAgcmV0dXJuIHN0cjsKK30KKworCisvL3JlcGxhY2VtZW50cyBmb3IgZHJvcHBlZCBlZnVucyBpbiBMRAorI2lmICFfX0VGVU5fREVGSU5FRF9fKGV4dHJhY3QpCitkZXByZWNhdGVkIHZhcmFyZ3Mgc3RyaW5nIGV4dHJhY3Qoc3RyaW5nIHN0ciwgaW50IGZyb20sIGludCB0bykgeworCisgIGlmKCFzdHJpbmdwKHN0cikpIHsKKyAgICBzZXRfdGhpc19vYmplY3QocHJldmlvdXNfb2JqZWN0KCkpOworICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIkJhZCBhcmd1bWVudCAxIHRvIGV4dHJhY3QoKTogJU8iLHN0cikpOworICB9CisgIGlmIChpbnRwKGZyb20pICYmIGludHAodG8pKSB7CisgICAgaWYgKGZyb20+PTAgJiYgdG8+PTApCisgICAgICByZXR1cm4oc3RyW2Zyb20gLi4gdG9dKTsKKyAgICBlbHNlIGlmIChmcm9tPj0wICYmIHRvPDApCisgICAgICByZXR1cm4oc3RyW2Zyb20gLi4gPGFicyh0byldKTsKKyAgICBlbHNlIGlmIChmcm9tPDAgJiYgdG8+PTApCisgICAgICByZXR1cm4oc3RyWzxhYnMoZnJvbSkgLi4gdG9dKTsKKyAgICBlbHNlCisgICAgICByZXR1cm4oc3RyWzxhYnMoZnJvbSkgLi4gPGFicyh0byldKTsKKyAgfQorICBlbHNlIGlmIChpbnRwKGZyb20pKSB7CisgICAgaWYgKGZyb20+PTApCisgICAgICByZXR1cm4oc3RyW2Zyb20gLi4gXSk7CisgICAgZWxzZQorICAgICAgcmV0dXJuKHN0cls8YWJzKGZyb20pIC4uIF0pOworICB9CisgIGVsc2UgeworICAgIHJldHVybihzdHIpOworICB9Cit9CisjZW5kaWYgLy8gIV9fRUZVTl9ERUZJTkVEX18oZXh0cmFjdCkKKworI2lmICFfX0VGVU5fREVGSU5FRF9fKHNsaWNlX2FycmF5KQorZGVwcmVjYXRlZCB2YXJhcmdzIG1peGVkIHNsaWNlX2FycmF5KG1peGVkIGFycmF5LCBpbnQgZnJvbSwgaW50IHRvKSB7CisKKyAgaWYoIXBvaW50ZXJwKGFycmF5KSkgeworICAgIHNldF90aGlzX29iamVjdChwcmV2aW91c19vYmplY3QoKSk7CisgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiQmFkIGFyZ3VtZW50IDEgdG8gc2xpY2VfYXJyYXkoKTogJU8iLGFycmF5KSk7CisgIH0KKyAgaWYgKGludHAoZnJvbSkgJiYgaW50cCh0bykpIHsKKyAgICBpZiAoZnJvbT49MCAmJiB0bz49MCkKKyAgICAgIHJldHVybihhcnJheVtmcm9tIC4uIHRvXSk7CisgICAgZWxzZSBpZiAoZnJvbT49MCAmJiB0bzwwKQorICAgICAgcmV0dXJuKGFycmF5W2Zyb20gLi4gPGFicyh0byldKTsKKyAgICBlbHNlIGlmIChmcm9tPDAgJiYgdG8+PTApCisgICAgICByZXR1cm4oYXJyYXlbPGFicyhmcm9tKSAuLiB0b10pOworICAgIGVsc2UKKyAgICAgIHJldHVybihhcnJheVs8YWJzKGZyb20pIC4uIDxhYnModG8pXSk7CisgIH0KKyAgZWxzZSBpZiAoaW50cChmcm9tKSkgeworICAgIGlmIChmcm9tPj0wKQorICAgICAgcmV0dXJuKGFycmF5W2Zyb20gLi4gXSk7CisgICAgZWxzZQorICAgICAgcmV0dXJuKGFycmF5WzxhYnMoZnJvbSkgLi4gXSk7CisgIH0KKyAgZWxzZSB7CisgICAgcmV0dXJuKGFycmF5KTsKKyAgfQorfQorI2VuZGlmIC8vICFfX0VGVU5fREVGSU5FRF9fKHNsaWNlX2FycmF5KQorCisjaWYgIV9fRUZVTl9ERUZJTkVEX18obWVtYmVyX2FycmF5KQorZGVwcmVjYXRlZCBpbnQgbWVtYmVyX2FycmF5KG1peGVkIGl0ZW0sIG1peGVkIGFycmF5c3RyaW5nKSB7CisKKyAgaWYgKHBvaW50ZXJwKGFycmF5c3RyaW5nKSkgeworICAgIHJldHVybihlZnVuOjptZW1iZXIoYXJyYXlzdHJpbmcsaXRlbSkpOworICB9CisgIGVsc2UgaWYgKHN0cmluZ3AoYXJyYXlzdHJpbmcpKSB7CisgICAgcmV0dXJuKGVmdW46Om1lbWJlcihhcnJheXN0cmluZyx0b19pbnQoaXRlbSkpKTsKKyAgfQorICBlbHNlIHsKKyAgICBzZXRfdGhpc19vYmplY3QocHJldmlvdXNfb2JqZWN0KCkpOworICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIkJhZCBhcmd1bWVudCAxIHRvIG1lbWJlcl9hcnJheSgpOiAlTyIsYXJyYXlzdHJpbmcpKTsKKyAgfQorfQorI2VuZGlmIC8vICFfX0VGVU5fREVGSU5FRF9fKG1lbWJlcl9hcnJheSkKKworLy8gVGhlIGRpZ2l0IGF0IHRoZSBpJ3RoIHBvc2l0aW9uIGlzIHRoZSBudW1iZXIgb2YgYml0cyBzZXQgaW4gJ2knLgorc3RyaW5nIGNvdW50X3RhYmxlID0KKyAgICAiMDExMjEyMjMxMjIzMjMzNDEyMjMyMzM0MjMzNDM0NDUxMjIzMjMzNDIzMzQzNDQ1MjMzNDM0NDUzNDQ1NDU1NiI7CitpbnQgYnJva2VuX2NvdW50X2JpdHMoIHN0cmluZyBzICkgeworICAgIGludCBpLCByZXM7CisgICAgaWYoICFzdHJpbmdwKHMpIHx8ICEoaT1zaXplb2YocykpICkgcmV0dXJuIDA7CisgICAgZm9yKCA7IGktLT4wOyApIHsKKyAgICAgICAgLy8gV2UgYXJlIGNvdW50aW5nIDYgYml0cyBhdCBhIHRpbWUgdXNpbmcgYSBwcmVjb21waWxlZCB0YWJsZS4KKyAgICAgICAgcmVzICs9IGNvdW50X3RhYmxlWyhzW2ldLScgJykmNjNdLScwJzsKKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworI2lmICFfX0VGVU5fREVGSU5FRF9fKGNvdW50X2JpdHMpCitpbnQgY291bnRfYml0cyggc3RyaW5nIHMgKSB7CisgICAgcmV0dXJuKGJyb2tlbl9jb3VudF9iaXRzKHMpKTsKK30KKyNlbmRpZgorCisKKy8vICogVGVpbGUgYXVzIGVpbmVtIEFycmF5IGVudGZlcm5lbiAqKiogT0JTT0xFVEUKK2RlcHJlY2F0ZWQgbWl4ZWQgKmV4Y2x1ZGVfYXJyYXkobWl4ZWQgKmFycixpbnQgZnJvbSxpbnQgdG8pCit7CisgIGlmICh0bzxmcm9tKQorICAgIHRvID0gZnJvbTsKKyAgcmV0dXJuIGFyclswLi5mcm9tLTFdK2Fyclt0bysxLi5dOworfQorCg==