ZGlmZiAtLWdpdCBhL3NlY3VyZS9rcmF1dG1hc3Rlci5jIGIvc2VjdXJlL2tyYXV0bWFzdGVyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGQwYWIwNgotLS0gL2Rldi9udWxsCisrKyBiL3NlY3VyZS9rcmF1dG1hc3Rlci5jCkBAIC0wLDAgKzEsMTI4OSBAQAorI3ByYWdtYSBzdHJvbmdfdHlwZXMsIHNhdmVfdHlwZXMsIHJ0dF9jaGVja3MKKyNwcmFnbWEgbm9faW5oZXJpdCwgbm9fY2xvbmUsIG5vX3NoYWRvdworCisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxpdGVtcy9rcmFldXRlci9rcmFldXRlci5oPgorI2luY2x1ZGUgPGl0ZW1zL2tyYWV1dGVyL3RyYW5rYXR0cmlidXRlLmg+CisjaW5jbHVkZSA8bGl2aW5nL2NvbW0uaD4KKworCisjaWZuZGVmIEJTCisjZGVmaW5lIEJTKHgpICAgICAgICAgICAgIGJyZWFrX3N0cmluZyh4LCA3OCkKKyNlbmRpZgorCisvLyBXZWl0ZXIgdW50ZW4gYmVpbSBQYXJzZW4gZGVzIERhdGVuZmlsZXMgd2VyZGVuIFNldFByb3AoKSB1bmQgTmFtZSgpCisvLyB2ZXJ3ZW5kZXQsIGRhaGVyIGVyYmVuIHdpciB0aGluZy4KK2luaGVyaXQgIi9zdGQvc2VjdXJlX3RoaW5nIjsKKworLy8gTGlzdGUgYWxsZXIgbW9lZ2xpY2hlbiBadXRhdGVuLCBnZW1hcHB0IHVlYmVyIGVpbmVuIGtleQorLy8gQU46IGlycml0aWVyZW5kZXIgTmFtZSwgZGVubiBlcyBzaW5kIG5pY2h0IGRpcmVrdCBkaWUgWnV0YXRlbiBlbnRoYWx0ZW4KKy8vIHNvbmRlcm4gZGllIHVlYmVyIGVpbmVuIEtleSBpZGVudGlmaXppZXJ0ZW4gS3JhZXV0ZXJncnVwcGVuLCBkaWUgZGllCisvLyBXaXJrdW5nZW4vRnVua3Rpb25lbiBmZXN0bGVnZW4uCisvLyBGb3JtYXQ6CisvLyAoWyBrZXkgOiAoeyBhdHRyX3BvcywgYXR0cl9uZWcxLCBhdHRyX25lZzIsIEhhbHRiYXJrLiwgV2lya2RhdWVyLCAKKy8vICAgICAgICAgICAgIFVudGVyc3R1ZXR6dW5nLCBTdG9lcnVuZywgSGFldWZpZ2tlaXQgIH0pIF0pCisvLyBCZWlzcGllbDogWyggImE3Ijooeyh7Miw0MDB9KSwoezExLDE1MH0pLDAsMTcyODAwLDAsKHsibioifSksMCwxfSkgXSkKKy8vIEhVOiBXYXIgZWluIE1hcHBpbmcsIGJsZWlidCBlaW4gTWFwcGluZywgdW5kIG5ldTogRGllIEVpbnRyYWVnZSB3ZXJkZW4gCisvLyBhdWNoIE1hcHBpbmdzIQorcHJpdmF0ZSBtYXBwaW5nIGluZ3JlZGllbnRzOworCisvLyBNYXBwaW5nIHZvbiBpZCB6dW0gS2V5IGRlciBadXRhdGVuIGltIGluZ3JlZGllbnRzLW1hcHBpbmc6IGlkMmtleVtpZF09a2V5CisvLyBEaWUgYmVpZGVuIExpc3RlbiB3ZXJkZW4gYmVub2V0aWd0LCB1bSB6dSBkZW4gS3JhdXQtSURzIGRpZSBqZXdlaWxpZ2VuCisvLyBLZXlzIHp1IGZpbmRlbi4KKy8vIEhVOiBLRUlOIE1BUFBJTkcuIEVpbiBBcnJheSB2b24gU3RyaW5ncy4gQWJlciBkYXMgZ2VodCBuYXR1ZXJsaWNoLgorcHJpdmF0ZSBzdHJpbmcgKmlkMmtleTsKKworLy8gTWFwcGluZyB2b24ga2V5IHp1IEtyYWV1dGVyLUlEIGRlciBadXRhdGVuLgorcHJpdmF0ZSBtYXBwaW5nIGtleTJpZDsKKworLy8gRWlnZW5zY2hhZnRlbiBkZXIgS3JhZXV0ZXI6CisvLyBrcmF1dHByb3BzW2lkXT0oe0lELCBEZW1vbiwgR2VuZGVyLCBOYW1lLCBBZGpla3RpdihlKSwgUF9MT05HLCBSYXVtZGV0YWlsfSkKKy8vIGtyYXV0cHJvcHNbMF0gPSAwOyBJRCAwIGRhcmYgbmljaHQgZXhpc3RpZXJlbgorcHJpdmF0ZSBtaXhlZCAqa3JhdXRwcm9wczsKKworLy8gaGllciB3aXJkIGdlc3BlaWNoZXJ0IHdlbGNoZSBWZXJzaW9uIGVpbmVyIFp1dGF0IGZ1ZXIgZWluZW4gU3BpZWxlciBpc3QuCisvLyBBTi9UT0RPOiBXZW5uIGRhcyBmdWVyIE5pY2h0c2VoZXIgbnV0emJhciBzZWluIHNvbGwsIHNvbGx0ZSBoaWVyIGJlc3NlcgorLy8gbWl0IGdldHV1aWQoKSBnZWFyYmVpdGV0IHdlcmRlbiwgc3RhdHQgZ2V0dWlkKCkgenUgdmVyd2VuZGVuLgorLy8gcGxheWVyIGVudGhhZWx0IGZ1ZXIgamVkZSBTcGllbGVyLVVJRCBlaW5lbiBCaXRzdHJpbmcuIEdlc2V0enRlcyBCaXQKKy8vIGJlZGV1dGV0LCBkYXNzIGRlciBTcGllbGVyIHVlYmVyIGRhcyBLcmF1dCBtaXQgZGllc2VyIElEIGV0d2FzIHVlYmVyCisvLyBkaWUgVmVyd2VuZHVuZyB1bmQgV2lya3VuZyB3ZWlzcy4gRXMgZ2lidCBqZWRvY2ggbm9jaCBrZWluZSBMZXJubW9lZ2xpY2gtCisvLyBrZWl0IHVuZCBJTlNCRVNPTkRFUkUga2VpbmUgRnVua3Rpb25hbGl0YWV0IGltIE1hc3RlciwgdWViZXIgZGllIG1hbiAKKy8vIGRpZSBCaXRzIHNldHplbiBrb2VubnRlLgorcHJpdmF0ZSBtYXBwaW5nIHBsYXllcjsKKworLy8gdmVyc3R1ZW1tZWx0ZXMgbWFwcGluZyBmdWVyIGRlbiBWQyBpbiBzZXJ2aWNlIChTYXZlLUR1bW15KQorcHJpdmF0ZSBtYXBwaW5nIG1hcF9sZGZpZWQ7CisKKy8vIHJvb21zIGVudGhhZWx0IGRpZSBUZWlsZWludHJhZWdlIGRlcyBtYXBfbGRmaWVkIG1hcHBpbmcgdm9tIFZDCitwcml2YXRlIG1hcHBpbmcgcm9vbXM7CisKKy8vIEVudGhhZWx0IERhdGVuIHp1IGRlbiBSYWV1bWVuLCBpbiBkZW5lbiBkYXMgVHJvY2tuZW4gdm9uIEtyYWV1dGVybgorLy8gbW9lZ2xpY2ggaXN0LgorcHJpdmF0ZSBtYXBwaW5nIGRyeWluZ19kYXRhID0gKFs6NF0pOworCitzdHJpbmcgYnVpbGRfcGxhbnRuYW1lKG1peGVkICpwcm9wcyk7CisKKy8vIHN0cnVjdC1UZW1wbGF0IGZ1ZXIgVHJhbmthdHRyaWJ1dGUKKy8vIEZ1ZXIgZGFzIFNRTC1Mb2cgTVVTUyBkaWUgUmVpaGVuZm9sZ2UgZGVyIFRyYW5rYXR0cmlidXRlIGhpZXIgZ2VuYXUgZGllCisvLyBzZWluLCB3aWUgZGllIFNwYWx0ZW4gaW4gZGVyIFRhYmVsbGUuCisvKiBDdXJyZW50bHkgbm90IHVzZWQuCitzdHJ1Y3QgdHJhbmtfYXR0cmliX3MgeworICAgIGludCBjYXI7CisgICAgaW50IGRhOworICAgIGludCBkbTsKKyAgICBpbnQgZHU7CisgICAgaW50IGRuOworICAgIGludCBmbHQ7CisgICAgaW50IGZybzsKKyAgICBpbnQgaEk7CisgICAgaW50IGhQOworICAgIGludCBoSzsKKyAgICBpbnQgaEw7CisgICAgaW50IHBhOworICAgIGludCBwbTsKKyAgICBpbnQgcHU7CisgICAgaW50IHNzOworICAgIGludCBzcDsKKyAgICBpbnQgc2Q7Cit9OworKi8KKworI2RlZmluZSBhbGxvd2VkKCkgKCFwcm9jZXNzX2NhbGwoKSAmJiBcCisgICAgICAgIElTX0FSQ0goUlBMKSAmJiBJU19BUkNIKHRoaXNfaW50ZXJhY3RpdmUoKSkgKQorCisjZGVmaW5lIFBPVElPTkZJTEVTICh7IFRSQU5LSVRFTSB9KQorCisvLyBlaWdlbnNjaGFmdGVuIGltIGtyYXV0cHJvcHMtYXJyYXkKKyNkZWZpbmUgUFJPUF9JRCAgICAgICAgICAgSU5HUkVESUVOVF9JRAorI2RlZmluZSBQUk9QX0RFTU9OICAgICAgICBJTkdSRURJRU5UX0RFTU9OCisjZGVmaW5lIFBST1BfR0VOREVSICAgICAgIElOR1JFRElFTlRfR0VOREVSCisjZGVmaW5lIFBST1BfTkFNRSAgICAgICAgIElOR1JFRElFTlRfTkFNRQorI2RlZmluZSBQUk9QX0FESiAgICAgICAgICBJTkdSRURJRU5UX0FESgorI2RlZmluZSBQUk9QX0xPTkcgICAgICAgICBJTkdSRURJRU5UX0xPTkcKKyNkZWZpbmUgUFJPUF9ST09NREVUQUlMICAgSU5HUkVESUVOVF9ST09NREVUQUlMCisKKy8vIEFUVFJfIGlzIGltbWVyIGVpbiBhcnJheSAoeyBhdHRyaWJ1dCwgYWJpbGl0eSB9KQorI2RlZmluZSBBVFRSX0FSUl9BVFRSSUIgICAgICAwCisjZGVmaW5lIEFUVFJfQVJSX0FCSUxJVFkgICAgIDEKKworLy8gbWF4aW1hbCBlcmxhdWJ0ZXIgV2VydCBmdWVyIGVpbmUgRWlnZW5zY2hhZnQKKyNkZWZpbmUgTUFYX0FUVFJfQUJJTElUWSAgICAgIDk5OQorCit2b2lkIGRlYnVnKHN0cmluZyBzdHIpCit7CisgIC8vd3JpdGUoImRlYnVnOiAiK3N0cisiXG4iKTsKKyAgaWYgKHRoaXNfcGxheWVyKCkgJiYgSVNfQVJDSCh0aGlzX3BsYXllcigpKSkKKyAgICB0aGlzX3BsYXllcigpLT5SZWNlaXZlTXNnKHN0ciw1MzY4NzA5MTIpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICAgc2V0ZXVpZChnZXR1aWQoKSk7CisgICAvLyBBTi9UT0RPOiBWYXJpYWJsZW4gb2JlbiBkaXJla3QgaW5pdGlhbGlzaWVyZW4uIFBydWVmZW4sIG9iIGRhdm9uCisgICAvLyBpcmdlbmR3YXMgbm9zYXZlIHNlaW4ga2Fubi4KKyAgIGlmICghcmVzdG9yZV9vYmplY3QoX19ESVJfXyIvQVJDSC9rcmF1dG1hc3RlciIpKQorICAgeworICAgICAgaW5ncmVkaWVudHM9KFtdKTsKKyAgICAgIGlkMmtleT0oe30pOworICAgICAga2V5MmlkPShbXSk7CisgICAgICBrcmF1dHByb3BzPSh7fSk7CisgICAgICBwbGF5ZXI9KFtdKTsKKyAgICAgIG1hcF9sZGZpZWQ9KFtdKTsKKyAgICAgIHJvb21zPShbXSk7CisgICB9CisgICBpZiAoc2xfb3BlbigiL2xvZy9BUkNIL2tyYXV0dHJhbmsuc3FsaXRlIikgIT0gMSkKKyAgIHsKKyAgICAgcmFpc2VfZXJyb3IoIkRhdGVuYmFuayBrb25udGUgbmljaHQgZ2VvZWZmbmV0IHdlcmRlbi5cbiIpOworICAgfQorICAgc2xfZXhlYygiQ1JFQVRFIFRBQkxFIElGIE5PVCBFWElTVFMgdHJhZW5rZShpZCBJTlRFR0VSIFBSSU1BUlkgS0VZLCAiCisgICAgICAgICAgICJ1aWQgVEVYVCBOT1QgTlVMTCwgcm5kIElOVEVHRVIsICIKKyAgICAgICAgICAgInRpbWUgSU5URUdFUiBERUZBVUxUIENVUlJFTlRfVElNRVNUQU1QLCAiCisgICAgICAgICAgICJyZWNlaXBlIFRFWFQgTk9UIE5VTEwsICIKKyAgICAgICAgICAgInF1YWxpdHkgVEVYVCBOT1QgTlVMTCwgIgorICAgICAgICAgICAiY2FyIElOVEVHRVIsICIKKyAgICAgICAgICAgImRhIElOVEVHRVIsICIKKyAgICAgICAgICAgImRtIElOVEVHRVIsICIKKyAgICAgICAgICAgImR1IElOVEVHRVIsICIKKyAgICAgICAgICAgImRuIElOVEVHRVIsICIKKyAgICAgICAgICAgImZsdCBJTlRFR0VSLCAiCisgICAgICAgICAgICJmcm8gSU5URUdFUiwgIgorICAgICAgICAgICAiaEkgSU5URUdFUiwgIgorICAgICAgICAgICAiaFAgSU5URUdFUiwgIgorICAgICAgICAgICAiaEsgSU5URUdFUiwgIgorICAgICAgICAgICAiaEwgSU5URUdFUiwgIgorICAgICAgICAgICAicGEgSU5URUdFUiwgIgorICAgICAgICAgICAicG0gSU5URUdFUiwgIgorICAgICAgICAgICAicHUgSU5URUdFUiwgIgorICAgICAgICAgICAic3MgSU5URUdFUiwgIgorICAgICAgICAgICAic3AgSU5URUdFUiwgIgorICAgICAgICAgICAic2QgSU5URUdFUik7IgorICAgICAgICAgICApOworICAgc2xfZXhlYygiQ1JFQVRFIElOREVYIElGIE5PVCBFWElTVFMgaWR4X3VpZCBPTiB0cmFlbmtlKHVpZCk7Iik7CisgICBzbF9leGVjKCJDUkVBVEUgSU5ERVggSUYgTk9UIEVYSVNUUyBpZHhfcmVjZWlwZSBPTiB0cmFlbmtlKHJlY2VpcGUpOyIpOworICAgc2xfZXhlYygiQ1JFQVRFIFRBQkxFIElGIE5PVCBFWElTVFMgcm9oZGF0ZW4oaWQgSU5URUdFUiBQUklNQVJZIEtFWSwgIgorICAgICAgICAgICAidWlkIFRFWFQgTk9UIE5VTEwsIHJuZCBJTlRFR0VSLCAiCisgICAgICAgICAgICJ0aW1lIElOVEVHRVIgREVGQVVMVCBDVVJSRU5UX1RJTUVTVEFNUCwgIgorICAgICAgICAgICAicmVjZWlwZSBURVhUIE5PVCBOVUxMLCAiCisgICAgICAgICAgICJxdWFsaXR5IFRFWFQgTk9UIE5VTEwsICIKKyAgICAgICAgICAgImNhciBJTlRFR0VSLCAiCisgICAgICAgICAgICJkYSBJTlRFR0VSLCAiCisgICAgICAgICAgICJkbSBJTlRFR0VSLCAiCisgICAgICAgICAgICJkdSBJTlRFR0VSLCAiCisgICAgICAgICAgICJkbiBJTlRFR0VSLCAiCisgICAgICAgICAgICJmbHQgSU5URUdFUiwgIgorICAgICAgICAgICAiZnJvIElOVEVHRVIsICIKKyAgICAgICAgICAgImhJIElOVEVHRVIsICIKKyAgICAgICAgICAgImhQIElOVEVHRVIsICIKKyAgICAgICAgICAgImhLIElOVEVHRVIsICIKKyAgICAgICAgICAgImhMIElOVEVHRVIsICIKKyAgICAgICAgICAgInBhIElOVEVHRVIsICIKKyAgICAgICAgICAgInBtIElOVEVHRVIsICIKKyAgICAgICAgICAgInB1IElOVEVHRVIsICIKKyAgICAgICAgICAgInNzIElOVEVHRVIsICIKKyAgICAgICAgICAgInNwIElOVEVHRVIsICIKKyAgICAgICAgICAgInNkIElOVEVHRVIpOyIKKyAgICAgICAgICAgKTsKKyAgIHNsX2V4ZWMoIkNSRUFURSBJTkRFWCBJRiBOT1QgRVhJU1RTIGlkeF91aWRfciBPTiByb2hkYXRlbih1aWQpOyIpOworfQorCitwdWJsaWMgc3RyaW5nIFF1ZXJ5UGxhbnRGaWxlKGludCBpZCkKK3sKKyAgaWYgKG1lbWJlcihrcmF1dHByb3BzLCBpZCkpCisgICAgcmV0dXJuIGJ1aWxkX3BsYW50bmFtZShrcmF1dHByb3BzW2lkXSk7CisgIHJldHVybiAwOworfQorCisvLyBBTjogRnVua3Rpb24gZXJtaXR0ZWx0LCBvYiBlaW4gU3BpZWxlciBwbCBkYXMgS3JhdXQgbWl0IGRlciBJRCBpZAorLy8gdmVyd2VuZGVuIGthbm4uIExhdXQgS29tbWVudGFyIHVudGVuIG11c3MgbWFuIGRhZnVlciB3b2hsIHdhcyB1ZWJlciBkYXMKKy8vIEtyYXV0IGdlbGVybnQgaGFiZW4sIHZvbiB3ZW0gaXN0IG1pciBnZXJhZGUgbm9jaCBuaWNodCBrbGFyLgorLy8gQU4vVE9ETzogRXMgaXN0IGJpc2hlciBrZWluZSBGdW5rdGlvbmFsaXRhZXQgdm9yaGFuZGVuLCB1bSBkaWUgSURzIGZ1ZXIKKy8vIGRlbiBTcGllbGVyIGZyZWl6dXNjaGFsdGVuLiBEaWUgRnVua3Rpb25zd2Vpc2UgbXVzcyBhdXMgZGVtIEJlaXNwaWVsY29kZQorLy8gdW50ZW4gZnVlciBkYXMgTGVhcm4tT24tRGVtYW5kIGFiZ2VsZXNlbiB3ZXJkZW4uCitub21hc2sgaW50IENhblVzZUluZ3JlZGllbnQob2JqZWN0IHBsLCBpbnQgaWQpCit7CisgIC8vIEljaCBtYWNoIG1hbCBkZW4gaGFydGVuIFdlZy4gLS0gSHVtbmkKKyAgcmV0dXJuIDE7CisgIC8vIEJpdHN0cmluZyBkZXMgU3BpZWxlcnMgYXVzIGRlciBMaXN0ZSBhdXNsZXNlbi4KKyAgIHN0cmluZyBzdHI9cGxheWVyW2dldHVpZChwbCldOworICAgaWYgKCFzdHJpbmdwKHN0cikpIHN0cj0iIjsKKyAgIGlmICh0ZXN0X2JpdChzdHIsIGlkKSkKKyAgICAgIHJldHVybiAxOyAvLyBtYWtlIHRoZSBjb21tb24gY2FzZSBmYXN0CisgICBlbHNlIHsKKyAgICAgLy8gbGV0enRlbmVuZGVzIGhhYmUgaWNoIG1pY2ggZW50c2NobG9zc2VuIGVpbnp1YmF1ZW4sIGRhcyBtYW4gbnVyIGRpZQorICAgICAvLyBLcmFldXRlciB2ZXJ3ZW5kZW4ga2FubiwgdWViZXIgZGllIG1hbiBzY2hvbm1hbCBldHdhcyBnZWxlc2VuL2dlbGVybnQKKyAgICAgLy8gaGF0LCBhdXMgZGllc2VtIEdydW5kLCBpc3QgZm9sZ2VuZGVyIEJsb2NrIGF1c2tvbW1lbnRpZXJ0LgorICAgICAvLyBEaWVzZXIgQmxvY2sgYmVkZXV0ZXQgcXVhc2kgZWluICJhdXRvIGxlYXJuaW5nIG9uIGRlbWFuZCIgZC5oLgorICAgICAvLyB3aXJkIGVpbiBLcmF1dCB2ZXJ3ZW5kZXQgd2lyZCBnZXBydWVmdCBvYiBmdWVyIGRpZXNlIEdydXBwZSBiZXJlaXRzCisgICAgIC8vIGVpbmUgSUQgZnJlaWdlc2NoYWx0ZXQgd3VyZGUgLSBhbnNvbnN0ZW4gd2lyZCBlaW5lIGZyZWlnZXNjaGFsdGV0LgorICAgICAvKgorICAgICAgICAgLy8gcHJ1ZWZlbiBvYiBmdWVyIGRlbiBLZXkgYmVyZWl0cyBlaW4gQml0IGdlc2V0enQgaXN0LCBnZ2YuIHNldHplbgorICAgICAgICAgaWYgKGlkPj1zaXplb2YoaWQya2V5KSkgcmV0dXJuIDA7IC8vIGlsbGVnYWxlIElkCisgICAgICAgICBpbnQgaWRsaXN0PWtleTJpZFtpZDJrZXlbaWRdXTsKKyAgICAgICAgIGludCBpOworICAgICAgICAgZm9yIChpPXNpemVvZihpZGxpc3QpLTE7IGk+PTA7IGktLSkgeworICAgICAgICAgICBpZiAodGVzdF9iaXQoc3RyLCBpZGxpc3RbaV0pKSByZXR1cm4gMDsgLy8gS2V5IGJlcmVpdHMgdm9yaGFuZGVuCisgICAgICAgICB9CisgICAgICAgICAvLyBadWZhZWxsaWcgZWluIEJpdCBmdWVyIGRlbiBLZXkgc2V0emVuCisgICAgICAgICBpPXJhbmRvbShzaXplb2YoaWRsaXN0KSk7CisgICAgICAgICBwbGF5ZXJbZ2V0dWlkKHBsKV09c2V0X2JpdChzdHIsIGlkbGlzdFtpXSk7CisgICAgICAgICBzYXZlX29iamVjdChvYmplY3RfbmFtZSgpKTsKKyAgICAgICAgIHJldHVybiAoaT09aWQpOworICAgICAqLworICAgICByZXR1cm4gMDsKKyAgIH0KK30KKworLy8gRGllc2UgRnVua3Rpb24gd2lyZCB2b20gTWV0emVsb3Jha2VsIGF1ZmdlcnVmZW4sIHVtIGRpZSBCZWxvaG51bmdlbiB6dQorLy8gZXJ6ZXVnZW4sIGRpZSBtYW4gZG9ydCBmdWVyIGVyZm9sZ3JlaWNoIGFic29sdmllcnRlIE1ldHplbGF1ZnRyYWVnZSBlcmhhZWx0CisjZGVmaW5lIEFMTE9XRURfQ0FMTEVSICh7ICIvZC9lYmVuZS9hcmF0aG9ybi9vcmFrZWwvc2VjdXJlL3NjaGFtYW5lIiB9KQorb2JqZWN0IGdldF9wbGFudF9ieV9jYXRlZ29yeShpbnQgbnBjX2NsYXNzKQoreworICBpZiAoIG1lbWJlcihBTExPV0VEX0NBTExFUiwgbG9hZF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSk8MCApCisgICAgcmFpc2VfZXJyb3IoInVuYXV0aG9yaXNlZCBjYWxsIHRvIGdldF9wbGFudF9ieV9jYXRlZ29yeSgpXG4iKTsKKworICAvLyBVZWJlcmdlYmVuZSBOUEMtS2xhc3NlIGluIEtyYXV0LUthdGVnb3JpZSB1bXNldHplbi4KKyAgLy8gS2F0ZWdvcmllIDcgd2lyZCBhbHMgNy05IGludGVycHJldGllcnQgKHNpZWhlIHVudGVuKS4KKyAgaW50IGNhdGVnb3J5OworICBzd2l0Y2gobnBjX2NsYXNzKSB7CisgICAgY2FzZSAxOiBjYXNlIDI6ICAgICAgICAgY2F0ZWdvcnk9NDsgYnJlYWs7CisgICAgY2FzZSAzOiBjYXNlIDQ6ICAgICAgICAgY2F0ZWdvcnk9NTsgYnJlYWs7CisgICAgY2FzZSA1OiBjYXNlIDY6IGNhc2UgNzogY2F0ZWdvcnk9NjsgYnJlYWs7CisgICAgZGVmYXVsdDogICAgICAgICAgICAgICAgY2F0ZWdvcnk9NzsgYnJlYWs7CisgIH0KKworICAvLyBBbGxlIEtyYWV1dGVyIGRlciBlcm1pdHRlbHRlbiBLYXRlZ29yaWUgcmF1c3N1Y2hlbi4gQmVpIEthdGVnb3JpZSA3CisgIC8vIHdlcmRlbiBhdWNoIGFsbGUgYXVzIDggdW5kIDkgZGF6dWdlbm9tbWVuLgorICBpbnQgKmVsaWdpYmxlX3BsYW50X2lkcz0oe30pOworICBmb3JlYWNoKCBzdHJpbmcgZ3JwLCBtYXBwaW5nIGdycGRhdGEgOiBpbmdyZWRpZW50cyApIHsKKyAgICBpZiAoIGNhdGVnb3J5ID09IDcgJiYgZ3JwZGF0YVtUX0FCVU5EQU5DRV0+PTcgfHwgCisgICAgICAgICAgY2F0ZWdvcnkgPT0gZ3JwZGF0YVtUX0FCVU5EQU5DRV0gKQorICAgICAgZWxpZ2libGVfcGxhbnRfaWRzICs9IGtleTJpZFtncnBdOworICB9CisKKyAgLy8gS3JhdXRuYW1lbiB6dSBkZW4gS3JhdXQtSURzIGVybWl0dGVsbi4KKyAgc3RyaW5nICpwbGFudGZpbGVzPW1hcChlbGlnaWJsZV9wbGFudF9pZHMsIGZ1bmN0aW9uIHN0cmluZyAoaW50IHBsYW50aWQpIHsKKyAgICByZXR1cm4gYnVpbGRfcGxhbnRuYW1lKGtyYXV0cHJvcHNbcGxhbnRpZF0pO30pOworCisgIC8vIEVpbiBLcmF1dCB6dWZhZWxsaWcgYXVzd2FlaGxlbiwgY2xvbmVuIHVuZCBkYXMgT2JqZWt0IHp1cnVlY2tnZWJlbi4KKyAgb2JqZWN0IHBsYW50PWNsb25lX29iamVjdChQTEFOVERJUitwbGFudGZpbGVzW3JhbmRvbShzaXplb2YocGxhbnRmaWxlcykpXSk7CisgIHBsYW50LT5EcnlQbGFudCg4MCtyYW5kb20oMTEpKTsKKyAgLy8gQXVmc2NocmVpYmVuLCB3ZXIgd2VsY2hlcyBLcmF1dCBtaXQgd2VsY2hlciBRdWFsaXRhZXQgcmF1c2Jla29tbXQuCisgIGxvZ19maWxlKCJBUkNIL3BsYW50X2J5X2NhdGVnb3J5IiwKKyAgICBzcHJpbnRmKCIlcyAlLTEycyAlLXMgUXVhbCAlZCBLYXQgJWQgQ2xhc3MgJWRcbiIsIAorICAgICAgc3RyZnRpbWUoIiV4ICVYIix0aW1lKCkpLCBnZXR1aWQoUEwpLAorICAgICAgb2JqZWN0X25hbWUocGxhbnQpW3NpemVvZihQTEFOVERJUikuLl0sCisgICAgICBwbGFudC0+UXVlcnlQcm9wKFBfUVVBTElUWSksIGNhdGVnb3J5LCBucGNfY2xhc3MpKTsKKy8vIHNwcmludGYoIiUyNHM6IGNhbGwgZnJvbSAlTywgcGxheWVyOiAlcyAoUEw6ICVPKSwga2F0ZWdvcnk6ICVkXG4iLCBjdGltZSgpLAorLy8gcHJldmlvdXNfb2JqZWN0KCksIGdldHVpZChwbGF5ZXIpLCBQTCwga2F0ZWdvcnkpKQorICByZXR1cm4gcGxhbnQ7Cit9CisKK3ByaXZhdGUgbm9zYXZlIG9iamVjdCBzaW11bF9lZnVuLCBwbGFudHZjOworCisvLyBmdWVyIFNJTVVMX0VGVU5fRklMRQorI2luY2x1ZGUgPGNvbmZpZy5oPgorCisvLyBBTi9UT0RPOiBLbGFlcmVuLCB3YXJ1bSBoaWVyIGVpbmUgZWlnZW5lIEZ1bmt0aW9uIGdldF9jbG9uZXIoKSBleGlzdGllcnQsCisvLyB3byBkb2NoIGRlciBLcmFldXRlci1WQyBzY2hvbiBlaW5lIGhhdC4KK25vbWFzayBwcml2YXRlIHN0cmluZyBnZXRfY2xvbmVyKCkKK3sKKyAgIGludCBpOworICAgb2JqZWN0IHBvOworICAgaWYgKCFzaW11bF9lZnVuKSB7CisgICAgICBpZiAoIShzaW11bF9lZnVuPWZpbmRfb2JqZWN0KFNJTVVMX0VGVU5fRklMRSkpKQorICAgICAgICAgc2ltdWxfZWZ1bj1maW5kX29iamVjdChTUEFSRV9TSU1VTF9FRlVOX0ZJTEUpOworICAgfQorICAgLy8gd2VubiBzaWUgamV0enQgbmljaHQgZXhpc3RpZXJ0IC0gYXVjaCBndXQsIGRhbm4gZ2lidCBlcyBoYWx0IGtlaW5lCisgICAvLyBzZWZ1bnMuCisKKyAgIGlmICghcGxhbnR2YykgcGxhbnR2Yz1maW5kX29iamVjdChLUkFFVVRFUlZDKTsKKyAgIAorICAgZm9yIChpPTA7IHBvPXByZXZpb3VzX29iamVjdChpKTsgaSsrKSB7CisgICAgICBpZiAocG89PW1hc3RlcigpIHx8IHBvPT1zaW11bF9lZnVuIHx8IHBvPT1NRSB8fAorICAgICAgICAgIHBvPT1wcmV2aW91c19vYmplY3QoKSB8fCBwbz09cGxhbnR2YykKKyAgICAgICAgIGNvbnRpbnVlOworICAgICAgZWxzZSByZXR1cm4gb2JqZWN0X25hbWUocG8pOworICAgfQorICAgcmV0dXJuIDA7Cit9CisKKy8vIEFOOiAKK25vbWFzayBzdHJpbmcgQ2hlY2tQbGFudChpbnQgaWQpCit7CisgICBpZiAoaWQ8PTAgfHwgaWQ+PXNpemVvZihpZDJrZXkpKSByZXR1cm4gMDsKKyAgIGlmICghc3RyaW5ncChpZDJrZXlbaWRdKSkgcmV0dXJuIDA7CisgICByZXR1cm4gZ2V0X2Nsb25lcigpOworfQorCisvLyB1ZWJlciBkaWVzZSBGdW5rdGlvbiBrYW5uIGRpZSBMaXN0ZSBkZXIgSWQncyB1cGRhdGV0IHdlcmRlbgorLy8gZXMgd2lyZCA8ZmlsZW5hbWU+IGVpbmdlbGVzZW4gdW5kIGR1cmNoZ2VwYXJzdC4KKy8vIERpZXNlIERhdGVpIG11c3MgaW4gamVkZXIgWmVpbGUgZm9sZ2VuZGVzIEZvcm1hdCBlaW5oYWx0ZW4gdW5kIGRhcmYga2VpbmUKKy8vIGxlZXJ6ZWlsZW4gZW50aGFsdGVuISA+IElkLGtleSxHZW5kZXIsTmFtZSxBZGpla3RpdgorLy8gQU46IERhcyBpc3QgUXVhdHNjaC4gRGFzIEZvcm1hdCBtdXNzIHNvIGF1c3NlaGVuOgorLy8gU3RyaW5nLUlEO0tyYXV0LUlEO2RlbW9uO2dlbmRlcjtQX05BTUU7YWRqZWt0aXY7UF9MT05HO3Jvb21kZXRhaWw7CisvLyBIVTogRGllc2UgRnVua3Rpb24gbGFzcyBpY2ggc28uIEhhcmhhci4KKy8vIFVwZGF0ZTogTmEgZ3V0LiBGYXN0Lgorbm9tYXNrIHByaXZhdGUgaW50IExvYWRJZExpc3Qoc3RyaW5nIGZpbGVuYW1lKQoreworICAgaW50IGksIGlkLCBzaSwgZGVtb247CisgICBzdHJpbmcgKmxpbmVzLCBmaWxlOworICAgbWl4ZWQgKmRhdGE7CisgICBmaWxlPXJlYWRfZmlsZShmaWxlbmFtZSk7CisgICBpZiAoIXN0cmluZ3AoZmlsZSkpIHJhaXNlX2Vycm9yKCJNaXNzaW5nIEZpbGU6ICIrZmlsZW5hbWUrIlxuIik7CisgICBsaW5lcz1leHBsb2RlKHJlYWRfZmlsZShmaWxlbmFtZSksICJcbiIpOworICAgc2k9c2l6ZW9mKGxpbmVzKS0xOworICAgLy8gQU4vVE9ETzogV2FydW0gdmVyd2VuZGV0IG1hbiBoaWVyIG5pY2h0IGF1Y2ggZWluZmFjaCBleHBsb2RlKCk/CisgICAvLyBXZW5uICIjI2VuZGUjIyIgYWxzIFRyZW5uemVpY2hlbiBlbnRoYWx0ZW4gaXN0LCBsaWVmZXJ0IGV4cGxvZGUoKQorICAgLy8gYWxzIGxldHp0ZW4gRWludHJhZyBlaW5lbiBMZWVyc3RyaW5nLCBkYXJhdWYga2FubiBtYW4gcHJ1ZWZlbi4KKyAgIC8vIEFsbGVyZGluZ3MgbXVlc3N0ZSBkYXMgdm9yIGRlbSBleHBsb2RlKCkgenVyIFplaWxlbnRyZW5udW5nIHBhc3NpZXJlbi4KKyAgIGZvciAoIDtzaT49MDsgc2ktLSkgCisgICB7CisgICAgIHN0cmluZyBsaWxpPWxpbmVzW3NpXTsKKyAgICAgaWYgKHN0cnN0cihsaW5lc1tzaV0sIiMjZW5kZSMjIik+PTApIGJyZWFrOworICAgfQorICAgc2ktLTsKKyAgIGlmIChzaTwwKSByYWlzZV9lcnJvcigiIyNlbmRlIyMgbm90IGZvdW5kIGluIGlkLWxpc3QuXG4iKTsKKyAgIGlkMmtleT1hbGxvY2F0ZShzaSsyKTsKKyAgIGtyYXV0cHJvcHM9YWxsb2NhdGUoc2krMik7CisgICAvLyBBTjogRnVlciBkYXMgQXVzbGVzZW4gZGVyIFdlcnRlIGF1cyBkZW0gQXJyYXkgImRhdGEiIG11ZXNzZW4gZGllIAorICAgLy8gSW5kaXppZXJ1bmdzLURlZmluZXMgamV3ZWlscyArMSB2ZXJ3ZW5kZXQgd2VyZGVuLCB3ZWlsIGltIERhdGVuZmlsZQorICAgLy8gc2NobGF1ZXJ3ZWlzZSBlaW4gRGF0ZW5mZWxkICp2b3JuZSogYW5nZWZ1ZWd0IHd1cmRlLgorICAgLy8gQU4vVE9ETzogdmllbGxlaWNodCBzb2xsdGUgbWFuIGJlc3NlciBFbGVtZW50IDAgenVlcnN0IGF1c2xlc2VuIHVuZAorICAgLy8gZGFubiBkYXMgQXJyYXkgYXJyIHVtIGVpbiBFbGVtZW50IGt1ZXJ6ZW46IGFyciA9IGFyclsxLi5dOworICAgZm9yIChpPXNpOyBpPj0wOyBpLS0pIHsKKyAgICAgIGRhdGE9ZXhwbG9kZShsaW5lc1tpXSwgIjsiKTsKKyAgICAgIGlmIChzaXplb2YoZGF0YSkhPTgpIHJhaXNlX2Vycm9yKCJXcm9uZyBpZC1saXN0IGZvcm1hdCBpbiBsaW5lICIrKGkrMSkrIlxuIik7CisgICAgICBpZD10b19pbnQoZGF0YVtQUk9QX0lEKzFdKTsKKyAgICAgIGRhdGFbUFJPUF9JRCsxXT1pZDsKKyAgICAgIGlmIChpZD5zaSsxKSByYWlzZV9lcnJvcihzcHJpbnRmKCJMaW5lICVkOiBpZCAlZCBncmVhdGVyIHRoYW4gYXJyYXkgc2l6ZSAlZC5cbiIsIGksIGlkLCBzaSkpOworICAgICAgaWQya2V5W2lkXT1kYXRhWzBdOworICAgICAgLy8gQU46IEljaCBzZWhlIG5vY2ggbmljaHQgc28gZ2Fueiwgd2FydW0gbWFuIHZvbiBkZW0gRGF0ZW5mZWxkCisgICAgICAvLyBQUk9QX0RFTU9OIG51ciBkYXMgbGV0enRlIFplaWNoZW4gYWxzIExpdGVyYWwgcHJ1ZWZlbiBzb2xsdGUuCisgICAgICAvLyBLb21wbGV0dCBnZWh0IGRvY2ggZ2VuYXVzb2d1dD8KKyAgICAgIHN3aXRjaChkYXRhW1BST1BfREVNT04rMV1bPDFdKSB7CisgICAgICAgIGNhc2UgJ1InOiBkYXRhW1BST1BfREVNT04rMV09UkFXOyBicmVhazsKKyAgICAgICAgY2FzZSAnMCc6IGRhdGFbUFJPUF9ERU1PTisxXT0wOyAgIGJyZWFrOworICAgICAgICBjYXNlICcxJzogZGF0YVtQUk9QX0RFTU9OKzFdPTE7ICAgYnJlYWs7CisgICAgICAgIGNhc2UgJzInOiBkYXRhW1BST1BfREVNT04rMV09MjsgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDogcmFpc2VfZXJyb3IoIlVua25vd24gZGVtb25mb3JtYXQgJyIrZGF0YVtQUk9QX0RFTU9OKzFdKworICAgICAgICAgICAgICAgICAgICInIGluIGlkbGlzdCBsaW5lICIrKGkrMSkrIlxuIik7CisgICAgICB9CisgICAgICBzd2l0Y2goZGF0YVtQUk9QX0dFTkRFUisxXVs8MV0pIHsKKyAgICAgICAgY2FzZSAnTic6IGRhdGFbUFJPUF9HRU5ERVIrMV09TkVVVEVSOyBicmVhazsKKyAgICAgICAgY2FzZSAnRic6IGRhdGFbUFJPUF9HRU5ERVIrMV09RkVNQUxFOyBicmVhazsKKyAgICAgICAgY2FzZSAnTSc6IGRhdGFbUFJPUF9HRU5ERVIrMV09TUFMRTsgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDogcmFpc2VfZXJyb3IoIlVua25vd24gZ2VuZGVyZm9ybWF0ICciK2RhdGFbUFJPUF9HRU5ERVIrMV0rCisgICAgICAgICAgICAgICAgICAgIicgaW4gaWRsaXN0IGxpbmUgIisoaSsxKSsiXG4iKTsKKyAgICAgIH0KKyAgICAgIFNldFByb3AoUF9HRU5ERVIsIGRhdGFbUFJPUF9HRU5ERVIrMV0pOworICAgICAgU2V0UHJvcChQX05BTUUsIGRhdGFbUFJPUF9OQU1FKzFdKTsKKyAgICAgIC8vIEFOL1RPRE86IGRhdGFbUFJPUF9BREpdIG11c3MgbWFuIG5pY2h0IHVuYmVkaW5ndCB2b3JoZXIgYXVmIDAgc2V0emVuCisgICAgICBpZiAoIXNpemVvZihkYXRhW1BST1BfQURKKzFdKSkgZGF0YVtQUk9QX0FESisxXT0wOworICAgICAgaWYgKGRhdGFbUFJPUF9BREorMV0pCisgICAgICAgICBTZXRQcm9wKFBfTkFNRV9BREosICh7Imdhbnogbm9ybWFsIiwgZGF0YVtQUk9QX0FESisxXX0pKTsKKyAgICAgIGVsc2UgU2V0UHJvcChQX05BTUVfQURKLCAiZ2FueiBub3JtYWwiKTsKKyAgICAgIFNldFByb3AoUF9BUlRJQ0xFLCBkYXRhW1BST1BfREVNT04rMV0hPVJBVyk7CisgICAgICBkZW1vbj0oZGF0YVtQUk9QX0RFTU9OKzFdPT1SQVcgPyAwIDogZGF0YVtQUk9QX0RFTU9OKzFdKTsKKyAgICAgIC8vIEFOOiBXZW5uIGtlaW5lIExhbmdiZXNjaHJlaWJ1bmcgaGludGVybGVndCB3dXJkZSwgd2lyZCBkZXIgTmFtZQorICAgICAgLy8gZGVzIEtyYXV0ZXMgYWxzIHNvbGNoZSB2ZXJ3ZW5kZXQuIEViZW5zbyBmdWVyIGRhcyBSYXVtZGV0YWlsLCBkYXMKKyAgICAgIC8vIGJlaW0gQmV0cmFjaHRlbiBkZXMgS3JhdXRlcyBpbSBSYXVtIGF1c2dlZ2ViZW4gd2lyZC4KKyAgICAgIGlmICghc2l6ZW9mKGRhdGFbUFJPUF9MT05HKzFdKSkgeworICAgICAgICAgZGF0YVtQUk9QX0xPTkcrMV0gPSBOYW1lKFdFUiwgZGVtb24pKyIuXG4iOworICAgICAgfQorICAgICAgZWxzZSBkYXRhW1BST1BfTE9ORysxXSA9IEJTKGRhdGFbUFJPUF9MT05HKzFdKTsKKy8vIEh1bW5pOiBPZmZlbmJhciBrb21tZW4gYW0gWmVpbGVuZW5kZSBtYW5jaG1hbCBaZWljaGVuIGRhenUuIEljaCBnZWhlIGRhdm9uCisvLyBhdXMsIGRhc3Mga2VpbmUgQmVzY2hyZWlidW5nIGt1ZXJ6ZXIgYWxzIDIgWmVpY2hlbiBpc3QuCisgICAgICBpZiAoc2l6ZW9mKGRhdGFbUFJPUF9ST09NREVUQUlMKzFdKTwyKSB7CisgICAgICAgICBkYXRhW1BST1BfUk9PTURFVEFJTCsxXSA9IE5hbWUoV0VSLCBkZW1vbikrIi5cbiI7CisgICAgICB9CisgICAgICBlbHNlIGRhdGFbUFJPUF9ST09NREVUQUlMKzFdID0gQlMoZGF0YVtQUk9QX1JPT01ERVRBSUwrMV0pOworICAgICAga3JhdXRwcm9wc1tpZF09ZGF0YVsxLi5dOworICAgfQorICAgU2V0UHJvcChQX05BTUUsIDApOworICAgU2V0UHJvcChQX05BTUVfQURKLCAiIik7CisgICAKKyAgIC8vIGtleTJpZC1DYWNoZSBuZXUgYXVmYmF1ZW4uCisgICBrZXkyaWQ9KFtdKTsKKyAgIGZvciAoaT1zaXplb2YoaWQya2V5KS0xOyBpPj0wOyBpLS0pIHsKKyAgICAgIGlmIChtZW1iZXIoa2V5MmlkLCBpZDJrZXlbaV0pKQorICAgICAgICAga2V5MmlkW2lkMmtleVtpXV0rPSh7IGkgfSk7CisgICAgICBlbHNlIGtleTJpZFtpZDJrZXlbaV1dPSh7IGkgfSk7CisgICB9CisgICByZXR1cm4gMTsKK30KKworLy8gSGlsZnNmdW5rdGlvbiB3aXJkIHp1bSBlaW5wYXJzZW4gYmVu9nRpZ3QKKy8vIHdhbmRlbHQgei5CLiBkZW4gc3RyaW5nIHZvbiAiaCA1MDAiIGluICh7IDMsIDUwMCB9KSB1bQorcHJpdmF0ZSBub21hc2sgPHN0cmluZ3xpbnQ+KiBidWlsZEF0dHJBcnIoc3RyaW5nIGF0dHIpCit7CisgICBpZiAoIWF0dHIpIHJldHVybiAwOworICAgYXR0cj10cmltKGF0dHIpOworICAgPHN0cmluZ3xpbnQ+KiByZXM9ZXhwbG9kZShhdHRyLCAiICIpLSh7IiJ9KTsKKyAgIC8vZGVidWcoc3ByaW50ZigiIGJ1aWxkIEF0dHIgJU8iLHJlcykpOworICAgaWYgKHNpemVvZihyZXMpIT0yKSByYWlzZV9lcnJvcigiV3JvbmcgYXR0cmliIGZvcm1hdCFcbiIpOworICAgLy9kZWJ1ZyhzcHJpbnRmKCIlTyIsVF9LUkFVVF9NQVApKTsKKyAgIHJldHVybiAoe1RfS1JBVVRfTUFQW3Jlc1swXV0sKGludClyZXNbMV19KTsKK30KKworLy8gQU46IEhpbGZzZnVua3Rpb24genVtIEVpbmxlc2VuIGRlciBUcmFlbmtlbGlzdGUuCitub21hc2sgcHJpdmF0ZSB2b2lkIExvYWRJbmRleChzdHJpbmcgZmlsZW5hbWUpCit7CisgICBpbnQgaSwgaiwgc2k7CisgICBzdHJpbmcgKmxpbmVzLCBmaWxlOworICAgbWl4ZWQgICpkYXRhOworCisgICBmaWxlPXJlYWRfZmlsZShmaWxlbmFtZSk7CisgICBpZiAoIXN0cmluZ3AoZmlsZSkpIHJhaXNlX2Vycm9yKCJNaXNzaW5nIEZpbGU6ICIrZmlsZW5hbWUrIlxuIik7CisgICAKKyAgIC8vIEFOL1RPRE86IEF1Y2ggaGllciB3YWVyZSB3aWVkZXIgZGllIFZlcndlbmR1bmcgdm9uIGV4cGxvZGUoKSB6dQorICAgLy8gZXJ3YWVnZW4uCisgICBsaW5lcz1leHBsb2RlKGZpbGUsICJcbiIpLSh7IiJ9KTsKKyAgIHNpPXNpemVvZihsaW5lcyk7CisgICBmb3IgKGk9MDsgaTxzaTsgaSsrKSBpZiAobGluZXNbaV09PSIjI3N0YXJ0IyMiKSBicmVhazsKKyAgIGkrKzsKKyAgIGlmIChpPj1zaSkgcmFpc2VfZXJyb3IoIm1pc3NpbmcgIyNzdGFydCMjIGluIEluZGV4LlxuIik7CisgICBpbmdyZWRpZW50cz0oW10pOworICAgZm9yICg7IGk8c2k7IGkrKykgeyAvLyBhbGxlIHplaWxlbiBkdXJjaGxhdWZlbi4uLgorICAgICAvLyBBTi9UT0RPOiBUYWJ1bGF0b3JlbiBhbHMgVHJlbm56ZWljaGVuIGZpbmRlIGljaCBpcmdlbmR3aWUgYmxvZWQuCisgICAgIC8vIEhVOiBEYXJ1bSBudW4gU2VtaWtvbG9ucworICAgICAvLyBkZWJ1ZygiWmVpbGUgIitsaW5lc1tpXSk7CisgICAgIGRhdGE9b2xkX2V4cGxvZGUobGluZXNbaV0sICI7Iik7IC8vIGFuIFNlbWlrb2xvbnMgdHJlbm5lbi4uLgorICAgICAvLyBkZWJ1ZyhzcHJpbnRmKCIlTyIsZGF0YSkpOworICAgICBpZiAoc2l6ZW9mKGRhdGEpIT05KSAKKyAgICAgICB7CisgICAgICAgICAvL2RlYnVnKHNwcmludGYoIiVPIixkYXRhKSk7CisgICAgICAgICByYWlzZV9lcnJvcigiV3JvbmcgaW5kZXhsaXN0IGZvcm1hdCBpbiBsaW5lICIrKGkrMSkrIlxuIik7CisgICAgICAgfQorICAgICBmb3IgKGo9ODsgaj49MDsgai0tKSB7CisgICAgICAgLy8gQU4vVE9ETzogaWYoZGF0YVtqXT09IiIgfHwgZGF0YVtqXT09Ii0iKSBkYXRhW2pdPTA7CisgICAgICAgLy8gZXMgc2luZCBvaG5laGluIHVlYmVyYWxsIFN0cmluZ3MgZW50aGFsdGVuLgorICAgICAgIC8vIFdpciBtYWNoZW4gYXVzICItIiBvZGVyICIwIiBlaW5lIGVjaHRlIGludC1OdWxsLgorICAgICAgIGlmIChzaXplb2YoZGF0YVtqXSk9PTAgfHwgZGF0YVtqXVswXT09Jy0nKSBkYXRhW2pdPTA7CisgICAgIH0KKyAgICAgLy8gSFU6IEFiIGhpZXIgYmF1IGljaCBtYWwgbmV1LiBEZW4gUmVzdCBwYWNrIGljaCBhdXNrb21tZW50aWVydCBkYXJ1bnRlciwgd2VubiBqZW1hbmQgZGVuIGFsdGVuIENvZGUKKyAgICAgLy8gbmFjaHNjaGF1ZW4gd2lsbC4KKyAgICAgLy8gSWNoIHdpbGwgZWluIE1hcHBpbmcgdm9uIGRpZXNlciBLcmFldXRlcmdydXBwZS4KKyAgICAgbWFwcGluZyBtaz0oW10pOworICAgICAvLyBEaWVzZXMgTWFwcGluZyBzb2xsIGRpZSBFaW50cmFlZ2UgbnVuIGVudGhhbHRlbi4KKyAgICAgbWtbVF9FRkZFQ1RfRFVSQVRJT05dPXRvX2ludChkYXRhWzVdKTsKKyAgICAgbWtbVF9BQlVOREFOQ0VdPXRvX2ludChkYXRhWzhdKTsKKyAgICAgLy8gcG9zaXRpdmUgRWZmZWt0ZSBhdWZ0ZWlsZW4KKyAgICAgLy9kZWJ1ZyhzcHJpbnRmKCJWb3Jwb3NpcyAlTyAtICVPIixtayxkYXRhKSk7CisgICAgIGlmIChzdHJpbmdwKGRhdGFbMV0pKQorICAgICAgIHsKKyAgICAgICAgIHN0cmluZyogcG9zaXM9ZXhwbG9kZShkYXRhWzFdLCIsIik7CisgICAgICAgICAvL2RlYnVnKHNwcmludGYoIiVPIC0gJU8iLG1rLHBvc2lzKSk7CisgICAgICAgICBmb3JlYWNoIChzdHJpbmcgcTpwb3NpcykgeworICAgICAgICAgICAvL2RlYnVnKHEpOworICAgICAgICAgICA8c3RyaW5nfGludD4qIGFycj1idWlsZEF0dHJBcnIocSk7CisgICAgICAgICAgIC8vZGVidWcoc3ByaW50ZigiJU8iLGFycikpOworICAgICAgICAgICBta1thcnJbMF1dPW1rW2FyclswXV0rYXJyWzFdOworICAgICAgICAgfQorICAgICAgIH0KKyAgICAgLy9kZWJ1ZyhzcHJpbnRmKCIlTyIsbWspKTsKKyAgICAgLy8gRXJzdGVyIE5lZ2F0aXZlciBFZmZla3QKKyAgICAgaWYgKGRhdGFbMl0hPTApCisgICAgICAgeworICAgICAgICAgPHN0cmluZ3xpbnQ+KiBhcnI9YnVpbGRBdHRyQXJyKGRhdGFbMl0pOworICAgICAgICAgbWtbYXJyWzBdXT1ta1thcnJbMF1dLWFyclsxXTsKKyAgICAgICB9CisgICAgIC8vZGVidWcoc3ByaW50Zigidm9ybmVnICVPIixtaykpOworICAgICAvLyBaZWl0ZXIgbmVnYXRpdmVyIEVmZmVrdAorICAgICBpZiAoZGF0YVszXSE9MCkKKyAgICAgICB7CisgICAgICAgICA8c3RyaW5nfGludD4qIGFycj1idWlsZEF0dHJBcnIoZGF0YVszXSk7CisgICAgICAgICBta1thcnJbMF1dPW1rW2FyclswXV0tYXJyWzFdOworICAgICAgIH0KKyAgICAgLy8gSGFsdGJhcmtlaXQgd2lyZCB1bWdlcmVjaG5ldAorICAgICBzdHJpbmcqIHN0aT1leHBsb2RlKGRhdGFbNF0sIiAiKS0oeyIifSk7CisgICAgIC8vZGVidWcoImhhbHRiYXIgIitzdGlbMF0pOworICAgICBzdHJpbmcgc3R0PXRyaW0oc3RpWzBdKTsKKyAgICAgaW50IGR1cjsKKyAgICAgaWYgKHN0dFs8MS4uXT09ImQiKSAvLyBUYWdlCisgICAgICAgeworICAgICAgICAgLy9kZWJ1ZygiVGFnZSIpOworICAgICAgICAgLy8gRGVyIGVyc3RlIFRlaWwgaXN0IGRpZSBEYXVlciBpbiBUYWdlbi4KKyAgICAgICAgIGR1cj10b19pbnQoc3RpWzBdWy4uPDJdKTsKKyAgICAgICAgIGR1cj1kdXIqMjQqNjAqNjA7IC8vIFNla3VuZGVuCisgICAgICAgICBta1tUX0VYUElSRV09ZHVyOworICAgICAgIH0KKyAgICAgaWYgKHN0dFs8MS4uXT09ImgiKSAvLyBTdHVuZGVuCisgICAgICAgeworICAgICAgICAgLy9kZWJ1ZygiU3R1bmRlbiIpOworICAgICAgICAgLy8gU29uc3QgaXN0IGVzIGhhbHQgZGllIERhdWVyIGluIFN0dW5kZW4uCisgICAgICAgICBkdXI9dG9faW50KHN0aVswXVsuLjwyXSk7CisgICAgICAgICBkdXI9ZHVyKjYwKjYwOworICAgICAgICAgbWtbVF9FWFBJUkVdPWR1cjsKKyAgICAgICB9CisgICAgIC8vZGVidWcoImVyZ2lidCAiK2R1cik7CisgICAgIC8vIE51biBkaWUgbHVzdGlnZW4gVW50ZXJzdHVldHp1bmdlbi4gRGF6dSBiZW51dHplbiB3aXIgdW5zZXJlbiBsdXN0aWdlbiBHbHVlY2tzaGFzZW4uCisgICAgIC8vIFVuZCBlaW4gUmVoLgorICAgICBzdHJpbmcqIGdsdWVja3NoYXNlOworICAgICBzdHJpbmcgcmVoOworICAgICAvLyBBbGxlIExlZXJ6ZWljaGVuIHJhdXMhCisgICAgIC8vZGVidWcoIlJlaGUiKTsKKyAgICAgLy9kZWJ1ZyhzcHJpbnRmKCJEYXRhOiAlTyIsZGF0YSkpOworICAgICBpZiAoc3RyaW5ncChkYXRhWzZdKSkKKyAgICAgICB7CisgICAgICAgICByZWg9KGV4cGxvZGUoZGF0YVs2XSwiICIpLSh7IiJ9KSlbMF07CisgICAgIAorICAgICAgICAgZ2x1ZWNrc2hhc2U9ZXhwbG9kZShyZWgsIiwiKS0oe30pOworICAgICAgICAgbWtbVF9TVVBQT1JURVJdPWdsdWVja3NoYXNlOworICAgICAgIH0KKyAgICAgZWxzZQorICAgICAgIHsKKyAgICAgICAgIG1rW1RfU1VQUE9SVEVSXT0wOworICAgICAgIH0KKyAgICAgLy8gTnVuIG1hY2hlbiB3aXIgZ2VuYXVzbyBkaWUgQmxvY2thZGVuLgorICAgICAvLyBEYXMgdG9sbGUgaXN0OiBSZWggdW5kIEdsdWVja3NoYXNlIGtvZW5uZW4gd2lyIHdpZWRlcnZlcndlbmRlbiEgRGFzIGZyZXV0LgorICAgICBpZiAoc3RyaW5ncChkYXRhWzddKSkKKyAgICAgICB7CisgICAgICAgICByZWg9KGV4cGxvZGUoZGF0YVs3XSwiICIpLSh7IiJ9KSlbMF07CisgICAgICAgICBnbHVlY2tzaGFzZT1leHBsb2RlKHJlaCwiLCIpLSh7fSk7CisgICAgICAgICBta1tUX0JMT0NLSU5HXT1nbHVlY2tzaGFzZTsKKyAgICAgICB9CisgICAgIGVsc2UKKyAgICAgICB7CisgICAgICAgICBta1tUX0JMT0NLSU5HXT0wOworICAgICAgIH0KKyAgICAgaW5ncmVkaWVudHNbdHJpbShkYXRhWzBdKV09bWs7CisgICB9CisgICAvL2RlYnVnKCJXdWZmIik7CisgICAvL2RlYnVnKHNwcmludGYoIiVPIixpbmdyZWRpZW50cykpOworfQorCitub21hc2sgcHJpdmF0ZSB2b2lkIHNhdmUoKQoreworICBzYXZlX29iamVjdChfX0RJUl9fIi9BUkNIL2tyYXV0bWFzdGVyIik7Cit9CisKKy8vIEFOOiBlcnpldWd0IGF1cyBOYW1lbiArIEFkamVrdGl2IGRlciBQZmxhbnplbmRhdGVuIGRlbiBPYmpla3RuYW1lbiwKKy8vIHouQi4gd2FsZHJlYmVfZ2VtZWluIG9kZXIgYWNrZXJrbGVlX2dlbGIsIHdvYmVpIEJpbmRlc3RyaWNoZSBhdWNoCisvLyBkdXJjaCBVbnRlcnN0cmljaGUgZXJzZXR6dCB3ZXJkZW4gKGFja2VyX3JldHRpY2gpLgorc3RyaW5nIGJ1aWxkX3BsYW50bmFtZShtaXhlZCAqcHJvcHMpCit7CisgICBzdHJpbmcga2V5OworICAgLy8gQU4vVE9ETzogZXJzdCBQUk9QX05BTUUgaW4ga2V5IHNjaHJlaWJlbiwgZGFubiBnZ2YuIFBST1BfQURKIGRhenUKKyAgIGlmIChzaXplb2YocHJvcHNbUFJPUF9BREpdKT4wKQorICAgICAga2V5PWxvd2Vyc3RyaW5nKHByb3BzW1BST1BfTkFNRV0rIl8iK3Byb3BzW1BST1BfQURKXSk7CisgICBlbHNlIGtleT1sb3dlcnN0cmluZyhwcm9wc1tQUk9QX05BTUVdKTsKKyAgIC8vIEFOL1RPRE86IGVyc2V0emVuIGR1cmNoIHJlZ3JlcGxhY2UoKTsKKyAgIGtleT1pbXBsb2RlKG9sZF9leHBsb2RlKGtleSwgIiAiKSwgIl8iKTsKKyAgIGtleT1pbXBsb2RlKG9sZF9leHBsb2RlKGtleSwgIi0iKSwgIl8iKTsKKyAgIHJldHVybiBrZXk7Cit9CisKK3B1YmxpYyB2b2lkIFVwZGF0ZVZDKCkKK3sKKyAgS1JBRVVURVJWQy0+dXBkYXRlKG1hcF9sZGZpZWQpOworfQorCisvLyBBTjogRGF0ZW4gbmV1IHBhcnNlbgorLy8gTmFjaCBkZW0gU2NocmVpYmVuIGRlcyBTYXZlZmlsZXMgbWl0dGVscyBzYXZlKCkgd2lyZCBhdWNoIGRhcworLy8gS3JhZXV0ZXItSGVhZGVyZmlsZSB2b20gS3JhZXV0ZXItVkMgbmV1IGdlc2NocmllYmVuLgoraW50IF9yZWZyZXNoKCkKK3sKKyAgIGludCBpOworICAgc3RyaW5nIGtleTsKKyAgIGlmIChleHRlcm5fY2FsbCgpICYmICFhbGxvd2VkKCkpCisgICAgIHJldHVybiAwOworICAgCisgICBMb2FkSWRMaXN0KF9fRElSX18iQVJDSC9rcmFldXRlcmxpc3RlLmR1bXAiKTsKKyAgIExvYWRJbmRleChfX0RJUl9fIkFSQ0gva3JhZXV0ZXJpbmRleC5kdW1wIik7CisgICBtYXBfbGRmaWVkPShbXSk7CisgICBmb3IgKGk9c2l6ZW9mKGtyYXV0cHJvcHMpLTE7IGk+PTA7IGktLSkKKyAgIHsKKyAgICAgIGlmIChzaXplb2Yoa3JhdXRwcm9wc1tpXSk8PVBST1BfUk9PTURFVEFJTCkgY29udGludWU7CisgICAgICBrZXkgPSBidWlsZF9wbGFudG5hbWUoa3JhdXRwcm9wc1tpXSk7CisgICAgICBtYXBfbGRmaWVkW2tleV09KHsga3JhdXRwcm9wc1tpXSwgcm9vbXNba2V5XXx8KFtdKSB9KTsKKyAgIH0KKyAgIHNhdmUoKTsKKyAgIFVwZGF0ZVZDKCk7CisgICAKKyAgIC8vIFVwZGF0ZSBIZWFkZXJmaWxlIG1pdCBLcmFldXRlcmxpc3RlCisgICBzdHJpbmcgKmtleXMgPSBzb3J0X2FycmF5KG1faW5kaWNlcyhtYXBfbGRmaWVkKSwgIyc8KTsKKyAgIHN0cmluZyBoZWFkZXJmaWxlID0KKyAgICAgIi8vIEF1dG9tYXRpc2NoIGdlbmVyaWVydGVzIEZpbGUsIG5pY2h0IHZvbiBIYW5kIGVkaXRpZXJlbiFcbiIKKyAgICAgIi8vIEVyemV1Z2VuZGVzIEZpbGU6ICIrb2JqZWN0X25hbWUoKSsiXG5cbiIKKyAgICAgIiNkZWZpbmUgUExBTlRDT1VOVCAiK3RvX3N0cmluZyhzaXplb2Yoa2V5cykpKyJcblxuIgorICAgICArIiNkZWZpbmUgUExBTlQoeCkgXCIvaXRlbXMva3JhZXV0ZXIvXCIreFxuXG4iOworICAgZm9yZWFjaChrZXk6IGtleXMpCisgICB7CisgICAgIGhlYWRlcmZpbGUgKz0gc3ByaW50ZigiI2RlZmluZSAlLTMwcyBQTEFOVChcIiVzXCIpXG4iLAorICAgICAgICAgICAgICAgICAgICAgdXBwZXJzdHJpbmcoa2V5KSwga2V5KTsKKyAgIH0KKyAgIHdyaXRlX2ZpbGUoS1JBRVVURVJMSVNURSwgaGVhZGVyZmlsZSwgMSk7CisKKyAgIHdyaXRlKCJJbnB1dGZpbGVzIHBhcnNlZC4gU2F2ZSAmIEhlYWRlcmZpbGVzIHVwZGF0ZWQhXG4iKTsKKyAgIHJldHVybiAxOworfQorCitpbnQgX2Nsb25lcGxhbnQoc3RyaW5nIHN0cikKK3sKKyAgaWYgKGFsbG93ZWQoKSkKKyAgeworICAgIGlmICh0b19zdHJpbmcodG9faW50KHN0cikpID09IHN0cikKKyAgICAgIHN0ciA9IFF1ZXJ5UGxhbnRGaWxlKHRvX2ludChzdHIpKTsKKyAgICBjbG9uZV9vYmplY3QoUExBTlRESVIrc3RyKS0+bW92ZSh0aGlzX3BsYXllcigpLCBNX05PQ0hFQ0spOworICAgIHdyaXRlKCJLcmF1dCAiICsgc3RyICsgIiBnZWNsb250LlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKyNkZWZpbmUgTUFYX1JPT01TIDEwICAvKiBrZWluIEtyYXV0IGlzdCBpbiBtZWhyIGFscyAxMCBSYWV1bWVuICovCisvLyBBTjogQXVzZ2FiZSBkZXIgS2F0ZWdvcmllbmxpc3RlIHVlYmVyIGRhcyBQbGFudHRvb2wuCitpbnQgX3Nob3dwbGFudChzdHJpbmcgc3RyKQoreworICAgaW50IGksIHNpLCBrYXQsIHNlY3VyZTsKKyAgIHN0cmluZyAqbGlzdCwga2V5OworICAgbWl4ZWQgKnJlcywgKmFycjsKKyAgIG1hcHBpbmcgcHJvcHM7CisKKyAgIHNlY3VyZT1hbGxvd2VkKCk7CisgICBub3RpZnlfZmFpbCgiRXMgZ2lidCBmb2xnZW5kZSBLcmFldXRlcmthdGVnb3JpZW46XG4iCisgICAgKyIgMCAtIGhhZXVmaWcgdW5kIGFuIHZpZWxlbiBTdGVsbGVuIGltIE11ZCBhbnp1ZmluZGVuXG4iCisgICAgKyIgMSAtIGV0d2FzIHNlbHRlbmVyIHp1IGZpbmRlbiwgYWJlciBpbW1lciBub2NoIGxlaWNodFxuIgorICAgICsiIDIgLSBhbiB3ZW5pZ2VuIGd1dCB2ZXJzdGVja3RlbiBTdGVsbGVuIGluIGFiZ2VsZWdlbmVuIEdlYmlldGVuXG4iCisgICAgKyIgMyAtIGRpdG8sIGplZG9jaCBtdXNzIGRhcyBLcmF1dCBkdXJjaCBlaW5lbiBOUEMgKFhQID49IDUwMDAwMCkgYmV3YWNodCBzZWluLlxuIgorICAgICsiIDQgLSBhZXVzc2Vyc3Qgc2VsdGVuIHVuZCBYUCA+PSAxIG1pb1xuIgorICAgICsiIDUgLSBhZXVzc2Vyc3Qgc2VsdGVuIHVuZCBYUCA+PSAyIG1pb1xuIgorICAgICsiIDYgLSBhZXVzc2Vyc3Qgc2VsdGVuIHVuZCBOUEMgYnJpbmd0ID49IDUgIFN0dXBzZVxuIgorICAgICsiIDcgLSBhZXVzc2Vyc3Qgc2VsdGVuIHVuZCBOUEMgYnJpbmd0ID49IDEwIFN0dXBzZVxuIgorICAgICsiIDggLSBhZXVzc2Vyc3Qgc2VsdGVuIHVuZCBOUEMgYnJpbmd0ID49IDIwIFN0dXBzZVxuIgorICAgICsiIDkgLSBhZXVzc2Vyc3Qgc2VsdGVuIHVuZCBOUEMgYnJpbmd0ID49IDUwIFN0dXBzZVxuIgorICAgICsiXG5TeW50YXg6IHNob3dwbGFudCA8a2F0ZWdvcmllPi5cbiIpOworICAga2F0PXRvX2ludChzdHIpOworICAgaWYgKGthdDwwIHx8IGthdD45KSByZXR1cm4gMDsKKyAgIGlmICh0b19zdHJpbmcoa2F0KSE9c3RyKSByZXR1cm4gMDsKKyAgIGxpc3Q9bV9pbmRpY2VzKG1hcF9sZGZpZWQpOworICAgLy8gQU46ICpncnVtbWVsKgorICAgLy8gcmVzID0gYWxsb2NhdGUoTUFYX1JPT01TLCAoe30pKTsKKyAgIHJlcz1tYXAoYWxsb2NhdGUoTUFYX1JPT01TKSwgIydhbGxvY2F0ZSk7IC8vICh7ICh7fSkgLi4uICh7fSkgfSkKKyAgIGZvciAoaT1zaXplb2YobGlzdCktMTsgaT49MDsgaS0tKSB7CisgICAgICBhcnI9bWFwX2xkZmllZFtsaXN0W2ldXTsKKyAgICAgIGlmIChzaXplb2YoYXJyKSE9MikgcmFpc2VfZXJyb3IoIldyb25nIG1hcF9sZGZpZWQtRm9ybWF0IGJ5ICIrbGlzdFtpXSsiXG4iKTsKKyAgICAgIGtleT1pZDJrZXlbYXJyWzBdW1BST1BfSURdXTsKKyAgICAgIGlmICgha2V5KSByYWlzZV9lcnJvcigiTWlzc2luZyBLZXkgZm9yIGlkICIrYXJyWzBdW1BST1BfSURdKyJcbiIpOworICAgICAgcHJvcHM9aW5ncmVkaWVudHNba2V5XTsKKyAgICAgIC8vaWYgKCFwb2ludGVycChwcm9wcykpIGNvbnRpbnVlOyAvLyBub2NoIG5pY2h0IGVpbmdldHJhZ2VuCisgICAgICAvL2lmIChzaXplb2YocHJvcHMpIT04KQorICAgICAgLy8gcHJpbnRmKCJXYXJuaW5nOiBXcm9uZyBpbmdyZWRpZW50LWNvbnRlbnQgYnkgIitrZXkrIlxuIik7CisgICAgICAvL2RlYnVnKHNwcmludGYoIiVPIixwcm9wcykpOworICAgICAgaWYgKHByb3BzPT0wKQorICAgICAgeworICAgICAgICBkZWJ1ZygiRmFsc2NoZXIgS2V5OiAiK2tleSk7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIGlmIChwcm9wc1tUX0FCVU5EQU5DRV09PWthdCkKKyAgICAgICAgeworICAgICAgICAgIHNpPXNpemVvZihhcnJbMV0pOworICAgICAgICAgIGlmIChzaTxNQVhfUk9PTVMpIHsKKyAgICAgICAgICAgIGlmIChzdHJpbmdwKGFyclswXVtQUk9QX0FESl0pKSB7CisgICAgICAgICAgICAgIFNldFByb3AoUF9BUlRJQ0xFLCAwKTsKKyAgICAgICAgICAgICAgU2V0UHJvcChQX05BTUUsIGFyclswXVtQUk9QX05BTUVdKTsKKyAgICAgICAgICAgICAgU2V0UHJvcChQX05BTUVfQURKLCBhcnJbMF1bUFJPUF9BREpdKTsKKyAgICAgICAgICAgICAgU2V0UHJvcChQX0dFTkRFUiwgYXJyWzBdW1BST1BfR0VOREVSXSk7CisgICAgICAgICAgICAgIGtleT1OYW1lKFdFUik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGtleT1hcnJbMF1bUFJPUF9OQU1FXTsKKyAgICAgICAgICAgIGlmIChzZWN1cmUpCisgICAgICAgICAgICAgIHJlc1tzaV0rPSh7IHNwcmludGYoIiUzZCAlLTQwczogJWRcbiIsIGFyclswXVtQUk9QX0lEXSwga2V5LCBzaSkgfSk7CisgICAgICAgICAgICBlbHNlIHJlc1tzaV0rPSh7IHNwcmludGYoIiUtNDBzOiAlZFxuIiwga2V5LCBzaSkgfSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICB9CisgICB9CisgICBmb3IgKGk9MDsgaTxNQVhfUk9PTVM7IGkrKykgeworICAgICAgc29ydF9hcnJheShyZXNbaV0sICMnPik7CisgICAgICBmaWx0ZXIocmVzW2ldLCAjJ3dyaXRlKTsKKyAgIH0KKyAgIHJldHVybiAxOworfQorCisvLyBBTjogQXVzZ2FiZSBkZXIgUmFldW1lLCBpbiBkZW5lbiBkaWUgS3JhZXV0ZXIgenUgZmluZGVuIHNpbmQuCisvLyBhbmdlc3RldWVydCB1ZWJlciBkYXMgUGxhbnR0b29sLgoraW50IF9zaG93cm9vbXMoc3RyaW5nIHN0cikKK3sKKyAgIGludCBpLCBqLCBpZDsKKyAgIHN0cmluZyAqbGlzdCwgZHVtbXk7CisgICBtaXhlZCAqYXJyOworICAgaWYgKCFhbGxvd2VkKCkpIHJldHVybiAwOworICAgbm90aWZ5X2ZhaWwoIlN5bnRheDogc2hvd3Jvb21zIDxpZD4gb2RlciBzaG93cm9vbXMgYWxsXG4iKTsKKyAgIGlmIChzdHIhPSJhbGwiKSB7CisgICAgIGlkPXRvX2ludChzdHIpOworICAgICBpZiAodG9fc3RyaW5nKGlkKSE9c3RyKSByZXR1cm4gMDsKKyAgIH0KKyAgIGVsc2UgaWQ9LTE7CisgICBsaXN0PW1faW5kaWNlcyhtYXBfbGRmaWVkKTsKKyAgIGZvciAoaT1zaXplb2YobGlzdCktMTsgaT49MDsgaS0tKSB7CisgICAgICBhcnI9bWFwX2xkZmllZFtsaXN0W2ldXTsKKyAgICAgIGlmIChzaXplb2YoYXJyKSE9MikgcmFpc2VfZXJyb3IoIldyb25nIG1hcF9sZGZpZWQtRm9ybWF0IGJ5ICIrbGlzdFtpXSsiXG4iKTsKKyAgICAgIGlmIChhcnJbMF1bUFJPUF9JRF09PWlkIHx8IGlkPDApIHsKKyAgICAgICAgIGlmICghc2l6ZW9mKG1faW5kaWNlcyhhcnJbMV0pKSkgeworICAgICAgICAgICAgaWYgKGlkPj0wKSB3cml0ZSgiRnVlciBkaWVzZSBJZCBzaW5kIGtlaW5lIFJhZXVtZSBlaW5nZXRyYWdlbi5cbiIpOworICAgICAgICAgfQorICAgICAgICAgZWxzZSBpZiAoaWQ+PTApIHsKKyAgICAgICAgICAgIHdyaXRlKCJGb2xnZW5kZSBSYWV1bWUgc2luZCBmdWVyICIrYXJyWzBdW1BST1BfSURdKyIgZWluZ2V0cmFnZW4uXG4iKTsKKyAgICAgICAgICAgIGZpbHRlcihtYXAobV9pbmRpY2VzKGFyclsxXSksICMnKywgIlxuIiksICMnd3JpdGUpOworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgICB9CisgICAgICAgICBlbHNlIGZpbHRlcihtYXAobV9pbmRpY2VzKGFyclsxXSksICMnKywgIjogIithcnJbMF1bUFJPUF9JRF0rIiwgIithcnJbMF1bUFJPUF9OQU1FXSsiXG4iKSwgIyd3cml0ZSk7CisgICAgICAgICBpZiAoaWQ+PTApIHJldHVybiAxOworICAgICAgfQorICAgfQorICAgd3JpdGUoIkZ1ZXIgZGllc2UgSWQgc2luZCBiaXNoZXIga2VpbmUgS3JhZXV0ZXIgZWluZ2V0cmFnZW4uXG4iKTsKKyAgIHJldHVybiAxOworfQorCisvLyBOdXR6dW5nIGRlciBLcmFldXRlciBpbiAgR2ViaWV0ZW4gbGllZmVydCBudXIgZGFubiBndWVsdGlnZSBLcmFldXRlciwKKy8vIHdlbm4gZGVyIFJhdW0gZWluZ2V0cmFnZW4gaXN0LgoraW50IF9hZGRyb29tKHN0cmluZyBzdHIpCit7CisgICBpbnQgaWQsIGk7CisgICBzdHJpbmcgKmxpc3QsIHZjOworCisgICBpZiAoIWFsbG93ZWQoKSkgeworICAgICAgd3JpdGUoIkZ1ZXIgZGFzIEVpbnRyYWdlbiBkZXIgUmFldW1lIHdlbmRlIERpY2ggZG9jaCBiaXR0ZSAiCisgICAgICAgICAgICAiYW4gZWluZW4gRU0uXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgfQorICAgbm90aWZ5X2ZhaWwoIlN5bnRheDogYWRkcm9vbSA8a3JhdXRudW1tZXI+IDxmaWxlbmFtZT5cbiIpOworICAgc3RyPVBMLT5fdW5wYXJzZWRfYXJncygpOworICAgaWYgKCFzdHIgfHwgc3NjYW5mKHN0ciwgIiVkICVzIiwgaWQsIHN0cikhPTIpIHJldHVybiAwOworICAgaWYgKHN0cj09ImhpZXIiIHx8IHN0cj09ImhlcmUiKQorICAgeworICAgICBpZiAoIXRoaXNfcGxheWVyKCkpCisgICAgIHsKKyAgICAgICBub3RpZnlfZmFpbCgiS2VpbiBTcGllbGVyb2JqZWt0LCBrYW5uICIKKyAgICAgICAgICAgIlJhdW0gbmljaHQgaWRlbnRpZml6aWVyZW4uXG4iKTsKKyAgICAgICByZXR1cm4gMDsKKyAgICAgfQorICAgICBzdHI9dG9fc3RyaW5nKGVudmlyb25tZW50KHRoaXNfcGxheWVyKCkpKTsKKyAgIH0KKyAgIGlmIChzdHJbPDIuLl09PSIuYyIpIHN0cj1zdHJbMC4uPDNdOyAvLyAuYyBhYnNjaG5laWRlbgorICAgaWYgKGZpbGVfc2l6ZShzdHIrIi5jIik8PTApIHsKKyAgICAgIGxpc3Q9ZXhwbG9kZShzdHIsICIvIik7CisgICAgICB2Yz1pbXBsb2RlKGxpc3RbMC4uPDJdLCAiLyIpKyIvdmlydHVhbF9jb21waWxlci5jIjsKKyAgICAgIGlmIChmaWxlX3NpemUodmMpPD0wIHx8ICFjYWxsX290aGVyKHZjLCAiVmFsaWRhdGUiLCBsaXN0WzwxXSkpIHsKKyAgICAgICAgIHdyaXRlKCJObyBzdWNoIGZpbGUgXCIiK3N0cisiXCIuXG4iKTsKKyAgICAgICAgIHJldHVybiAxOworICAgICAgfQorICAgfQorICAgaWYgKGlkPD0wIHx8IGlkPj1zaXplb2YoaWQya2V5KSkgeworICAgICAgd3JpdGUoIklsbGVnYWwgcGxhbnRpZCAiK2lkKyIuXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgfQorICAgbGlzdD1tX2luZGljZXMobWFwX2xkZmllZCk7CisgICBmb3IgKGk9c2l6ZW9mKGxpc3QpLTE7IGk+PTA7IGktLSkgeworICAgICAgaWYgKG1hcF9sZGZpZWRbbGlzdFtpXV1bMF1bUFJPUF9JRF09PWlkKSB7CisgICAgICAgICBpZiAoIW1lbWJlcihtYXBfbGRmaWVkW2xpc3RbaV1dWzFdLCBzdHIpKSB7CisgICAgICAgICAgICBtYXBfbGRmaWVkW2xpc3RbaV1dWzFdKz0oWyBzdHIgXSk7CisgICAgICAgICAgICByb29tc1tsaXN0W2ldXT0ocm9vbXNbbGlzdFtpXV18fChbXSkpKyhbIHN0ciBdKTsKKyAgICAgICAgICAgIHdyaXRlKCJSYXVtIEVyZm9sZ3JlaWNoIGVpbmdldHJhZ2VuIVxuIik7CisgICAgICAgICB9CisgICAgICAgICBlbHNlIHdyaXRlKCJSYXVtIGJlcmVpdHMgZWluZ2V0cmFnZW4uXG4iKTsKKyAgICAgICAgIHNhdmUoKTsKKyAgICAgICAgIF9yZWZyZXNoKCk7CisgICAgICAgICByZXR1cm4gMTsKKyAgICAgIH0KKyAgIH0KKyAgIHdyaXRlKCJLcmF1dCBtaXQgaWQgIitpZCsiIG5pY2h0IGdlZnVuZGVuLlxuIik7CisgICByZXR1cm4gMTsKK30KKworaW50IF9kZWxyb29tKHN0cmluZyBzdHIpCit7CisgICBpbnQgaSwgZG9uZTsKKyAgIHN0cmluZyAqbGlzdDsKKworICAgaWYgKCFhbGxvd2VkKCkpIHsKKyAgICAgIHdyaXRlKCJGdWVyIGRhcyBMb2VzY2hlbiB2b24gUmFldW1lbiB3ZW5kZSBEaWNoIGRvY2ggYml0dGUgIgorICAgICAgICAgICAgImFuIGVpbmVuIEVNLlxuIik7CisgICAgICByZXR1cm4gMTsKKyAgIH0KKyAgIG5vdGlmeV9mYWlsKCJTeW50YXg6IGRlbHJvb20gPGZpbGVuYW1lPi5cbiIpOworICAgc3RyPVBMLT5fdW5wYXJzZWRfYXJncygpOworICAgaWYgKCFzdHIpIHJldHVybiAwOworICAgaWYgKHN0cls8Mi4uXT09Ii5jIikgc3RyPXN0clswLi48M107CisgICBsaXN0PW1faW5kaWNlcyhtYXBfbGRmaWVkKTsgZG9uZT0wOworICAgZm9yIChpPXNpemVvZihsaXN0KS0xOyBpPj0wOyBpLS0pCisgICB7CisgICAgICBpZiAobWVtYmVyKG1hcF9sZGZpZWRbbGlzdFtpXV1bMV0sIHN0cikpIHsKKyAgICAgICAgIG1fZGVsZXRlKG1hcF9sZGZpZWRbbGlzdFtpXV1bMV0sIHN0cik7CisgICAgICAgICBtX2RlbGV0ZShyb29tc1tsaXN0W2ldXSwgc3RyKTsKKyAgICAgICAgIHdyaXRlKCJSYXVtIGJlaSBpZCAiK21hcF9sZGZpZWRbbGlzdFtpXV1bMF1bUFJPUF9JRF0KKyAgICAgICAgICAgICAgICsiIGF1c2dldHJhZ2VuLlxuIik7CisgICAgICAgICBkb25lPTE7CisgICAgICB9CisgICB9CisgICBpZiAoIWRvbmUpIHsKKyAgICAgIGlmIChmaWxlX3NpemUoc3RyKyIuYyIpPDApCisgICAgICAgICB3cml0ZSgiTm8gc3VjaCBmaWxlIFwiIitzdHIrIlwiLlxuIik7CisgICAgICBlbHNlIHdyaXRlKCJGdWVyICIrc3RyKyIgc2luZCBrZWluZSBLcmFldXRlciBlaW5nZXRyYWdlbiFcbiIpOworICAgfQorICAgZWxzZSB7CisgICAgICBzYXZlKCk7CisgICAgICBfcmVmcmVzaCgpOworICAgfQorICAgcmV0dXJuIDE7Cit9CisKKy8vIFZlcmFubGFzc3QgZGVuIEtyYWV1dGVyLVZDLCBlaW5lIHBoeXMuIERhdGVpIGF1cyBkZW4gS3JhZXV0ZXJkYXRlbiBlaW5lcworLy8gS3JhdXRlcyB6dSBlcnpldWdlbiwgZmFsbHMgbWFuIGRpZXNlIGF1c2Jlc2NocmVpYmVuIHdpbGwuCitpbnQgX2NyZWF0ZWZpbGUoc3RyaW5nIHN0cikKK3sKKyAgaW50IGlkOworICBpZiAoIWFsbG93ZWQoKSkgeworICAgIHdyaXRlKCJEaWVzZSBGdW5rdGlvbiB3dXJkZSBmdWVyIERpY2ggbmljaHQgZnJlaWdlZ2ViZW4hXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZD10b19pbnQoc3RyKTsKKyAgaWYgKHRvX3N0cmluZyhpZCkhPXN0ciB8fCBpZDw9MCB8fCBpZD49c2l6ZW9mKGlkMmtleSkpIHsKKyAgICB3cml0ZSgiSWxsZWdhbCBwbGFudGlkICciK3N0cisiJy5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIG5vdGlmeV9mYWlsKCJVbmtub3duIEZ1bmN0aW9uIGltIGtyYWV1dGVyVkM6IF9jcmVhdGVmaWxlKClcbiIpOworICByZXR1cm4gY2FsbF9vdGhlcihLUkFFVVRFUlZDLCAiX2NyZWF0ZWZpbGUiLCBidWlsZF9wbGFudG5hbWUoa3JhdXRwcm9wc1tpZF0pKTsKK30KKworLy8gQU46IEhpbGZzZnVua3Rpb25lbiwgZGVyemVpdCBlYmVuZmFsbHMgZGVha3RpdmllcnQuCisvLyBpID0gMC4uNywgUG9zaXRpb24gZGVzIEtyYXV0ZXMsIGZ1ZXIgZGFzIGRlciBBdWZydWYgZXJmb2xndCwgaW4gZGVyIAorLy8gTGlzdGUgZGVyIGluIGRlbiBLZXNzZWwgZWluZnVlbGx0ZW4gS3JhZXV0ZXIuCisvLyBrZXlMc3QgaXN0IGRpZSBMaXN0ZSBkZXIgS3JhZXV0ZXJncnVwcGVuLCBkZXIgZGllIEtyYWV1dGVyIHp1Z2VvcmRuZXQKKy8vIHNpbmQuCisvLyBBbiBkaWVzZXIgU3RlbGxlIGthbm4gYWxzbyBkaWUgV2lya3VuZyB2b24gS3JhZXV0ZXJncnVwcGVuIGFiZ2VoYWVuZ3QKKy8vIHdlcmRlbi4gVW5rbGFyIGlzdCBtaXIgYWt0dWVsbCBudXIsIHdhcnVtIGRpZXNlIEZ1bmt0aW9uIGRlbiBQYXJhbWV0ZXIKKy8vICJpIiBiZW5vZXRpZ2VuIHd1ZXJkZS4KKy8vIElkZWU6IEVzIHNvbGwgZGllIEVudHNjaGVpZHVuZyBkYXZvbiBhYmhhZW5naWcgZ2VtYWNodCB3ZXJkZW4ga29lbm5lbiwKKy8vIHdpZSBkaWUgR2VzYW10a29tYmluYXRpb24gYXVzc2llaHQsIHVuZCB6dXNhZXR6bGljaCBkYXZvbiwgYXVzIHdlbGNoZXIKKy8vIEdydXBwZSBkYXMgZWluemVsbmUgS3JhdXQgc3RhbW10Lgorbm9tYXNrIHByaXZhdGUgaW50IElzQmxvY2tlZChpbnQgaSwgc3RyaW5nICprZXlMc3QpCit7CisgIHJldHVybiAwOworfQorCisvLyBBTjogRGllc2UgRnVua3Rpb24gbXVlc3N0ZSBuYWNoIGRlbSBDb2RlIGluIG1ha2VfcG90aW9uKCkgenUgdXJ0ZWlsZW4KKy8vIDAgb2RlciAxIHp1cnVlY2tnZWJlbiwgZGFubiB3aXJkIGRlciBFaWdlbnNjaGFmdHN3ZXJ0IGRlciBLcmFldXRlcmdydXBwZQorLy8gdW0gZGVuIEZha3RvciAxLjUgdmVyc3RhZXJrdC4KK25vbWFzayBwcml2YXRlIGludCBJc0Jvb3N0ZWQoaW50IGksIHN0cmluZyAqa2V5THN0KQoreworICByZXR1cm4gMDsKK30KKworI2RlZmluZSBQUk5HICIvc3RkL3V0aWwvcmFuZC1nbGZzciIKKy8vIEluZGl2aWR1ZWxsZSBCb25pL01hbGkgZnVlciBTcGllbGVyLiBwbG9mZnNldCBzb2xsIHZpYSBSZWZlcmVueiB1ZWJlcmdlYmVuCisvLyB3ZXJkZW4gdW5kIHdpcmQgdm9uIGRlciBGdW5rdGlvbiBnZXNldHp0LgoraW50IGNhbGN1bGF0ZV9tb2QoaW50IGtyYXV0aW5kZXgsIHN0cmluZyBwbG5hbWUsIGludCBwbG9mZnNldCkKK3sKKyAgLy8gU3RhcnRvZmZzZXQgenVmYWVsbGlnIGVybWl0dGVsdCwgYWJlciBpbW1lciBnbGVpY2gKKyAgLy8gZnVlciBqZWRlbiBTcGllbGVybmFtZW4KKyAgUFJORy0+SW5pdFdpdGhVVUlEKHBsbmFtZSk7CisgIHBsb2Zmc2V0ID0gUFJORy0+cmFuZG9tKDE2KTsKKyAgLy8gSmVkZXMgS3JhdXQgaGF0IGF1Y2ggZWluZW4gaU9mZnNldCAoZGVyIGtvbnN0YW50IGJsZWlidCB1bmQgc2ljaCBuaWNodAorICAvLyBhZW5kZXJ0KS4gRGVyIHdpcmQgYXVjaCBhZGRpZXJ0LiBCZWkgVWViZXJzY2hyZWl0ZW4gdm9uIDMwIHdpcmQgbmFjaCAwCisgIC8vIGdld3JhcHB0LgorICAvLyBEZXIgT2Zmc2V0IGlzdCBkYW5uIChzcGllbGVyb2Zmc2V0ICsga3JhdXRpbmRleCkgJSAxNiwgZC5oLiBhbGxlIE1vZGlmaWthdG9yZW4gd2VyZGVuCisgIC8vIGRlciBSZWloZSBuYWNoIGR1cmNobGF1ZmVuLiBTbyBrcmllZ3QgamVkZXIgU3BpZWxlciAtIGZhc3QgZWdhbCwgYmVpIHdlbGNoZW0KKyAgLy8gT2Zmc2V0IGVyIHN0YXJ0ZXQgLSBhdWNoIGRlciBSZWloZSBuYWNoIGFsbGUgQm9uaStNYWxpLgorICBpbnQgb2Zmc2V0ID0gKChwbG9mZnNldCArIGtyYXV0aW5kZXgpICUgMTYpICogMjsKKyAgLy8gQW0gRW5kZSB3aXJkIGRhcyBnYW56ZSBub2NoIG5hY2ggODUgYmlzIDExNSB2ZXJsZWd0LgorICByZXR1cm4gb2Zmc2V0ICsgODU7Cit9CisKKyNkZWZpbmUgWldFSVRJRVMgIi9zZWN1cmUvendlaXRpZXMiCisKK21hcHBpbmcgY2FsY3VsYXRlX3BvdGlvbihpbnQqIHBsYW50aWRzLCBpbnQqIHF1YWxpdGllcywgc3RyaW5nIGZhbWlsaWUpCit7CisgIC8vIE1hbiBzb2xsdGUgb2huZSBkaWUgS3JhZXV0ZXIgbmljaHQgc28gZWluZmFjaCBXaXJrdW5nZW4gYmVsaWViaWcKKyAgLy8gYmVyZWNobmVuIGtvZW5uZW4uCisgIGlmIChleHRlcm5fY2FsbCgpICYmICFBUkNIX1NFQ1VSSVRZKQorICAgIHJldHVybiAwOworCisgIC8vIEhpZXIgc3BlaWNoZXJuIHdpciB1bnNlciBFcmdlYm5pcyBiencuIHVuc2VyIFp3aXNjaGVuZXJnZWJuaXMuCisgIG1hcHBpbmcgYXR0cmliOworICAvLyBIaWVyIHNwZWljaGVybiB3aXIgZGllIFdpcmtncnVwcGVuLCBkaWUgYXVzIGRlbiBQbGFudHMgZ2V6b2dlbiB3ZXJkZW4uCisgIG1hcHBpbmcqIHdpcmt1bmdlbj0oe30pOworICAvLyBIaWVyIHNwZWljaGVybiB3aXIgZ2xlaWNoIHNjaG9uIGJlaW0gRXJ6ZXVnZW4gZGllIHdpY2h0aWdzdGVuIEJsb2NrYWRlbi4KKyAgc3RyaW5nKiB1bnRlcnN0dWV0enVuZ2VuPSh7fSk7CisgIHN0cmluZyogYmxvY2thZGVuPSh7fSk7CisgIGludCB6dWZhbGw7CisgIC8vIERpZSBTb3J0aWVydW5nIG5hY2ggUGxhbnRJRCBpc3QgbnVyIGZ1ZXIgZGFzIFRyYW5rbG9nIHdpY2h0aWcuCisgIHBsYW50aWRzID0gc29ydF9hcnJheShwbGFudGlkcywgIyc8PSk7CisKKyAgLy8gUEFTUyAxOiBQZmxhbnplbiBkdXJjaCBXaXJrdW5nZW4gZXJzZXR6ZW4sIGRhYmVpIFVudGVyc3R1ZXR6ZXIKKyAgLy8gdW5kIEJsb2NrZXIgbWVya2VuLgorICBmb3JlYWNoIChpbnQgaWQsIGludCBxdWFsIDogbWttYXBwaW5nKHBsYW50aWRzLHF1YWxpdGllcykpCisgICAgeworICAgICAgLy9kZWJ1ZyhzcHJpbnRmKCJHZWhlIGR1cmNoIFBsYW50OiAlZCIsaWQpKTsKKyAgICAgIHN0cmluZyBrZXk9aWQya2V5W2lkXTsKKyAgICAgIC8vIFdpcmt1bmdlbiBkaWVzZXMgS3JhdXRzIGtvcGllcmVuCisgICAgICBtYXBwaW5nIGluZz1jb3B5KGluZ3JlZGllbnRzW2tleV0pOworICAgICAgLy9kZWJ1ZyhzcHJpbnRmKCIlTyIsaW5nKSk7CisgICAgICAvLyBadSBkZW4gV2lya3VuZ2VuIG5vY2ggZGVuIEtleSBoaW56dWZ1ZWdlbi4KKyAgICAgIGluZ1sia2V5Il09a2V5OworICAgICAgLy8gRGllIFF1YWxpdGFldCBkZXMgS3JhdXRlcyB3aXJkIG5vY2ggbWl0IGRlbSBzcGllbGVyaW5kaXZpZHVlbGxlbgorICAgICAgLy8gTW9kaWZpa2F0b3Igc2thbGllcnQuCisgICAgICBpbmdbInF1YWxpdHkiXT0ocXVhbCAqIGNhbGN1bGF0ZV9tb2QoaWQsIGZhbWlsaWUsICZ6dWZhbGwpKSAvIDEwMDsKKyAgICAgIHdpcmt1bmdlbis9KHtpbmd9KTsKKyAgICAgIGlmIChwb2ludGVycChpbmdbVF9TVVBQT1JURVJdKSkKKyAgICAgICAgeworICAgICAgICAgIGZvcmVhY2ggKHN0cmluZyBwaTppbmdbVF9TVVBQT1JURVJdKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICB1bnRlcnN0dWV0enVuZ2VuKz0oe3BpfSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIGlmIChwb2ludGVycChpbmdbVF9CTE9DS0lOR10pKQorICAgICAgICB7CisgICAgICAgICAgZm9yZWFjaCAoc3RyaW5nIHBpOmluZ1tUX0JMT0NLSU5HXSkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgYmxvY2thZGVuKz0oe3BpfSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIGRlYnVnKHNwcmludGYoIktyYXV0ICVzIGVyZ2lidCBXZXJ0ZSAlTy4iLGtleSx3aXJrdW5nZW4pKTsKKyAgICB9CisgIC8vIFBBU1MgMjogSmV0enQgZGllIFVudGVyc3R1ZXR6dW5nZW4gYXVzd2VydGVuCisgIGZvcmVhY2ggKG1hcHBpbmcgbWFyOndpcmt1bmdlbikKKyAgICB7CisgICAgICBmb3JlYWNoIChzdHJpbmcgcGk6dW50ZXJzdHVldHp1bmdlbikKKyAgICAgICAgeworICAgICAgICAgIC8vIEhhYmVuIHdpciBlaW5lIFVudGVyc3R1ZXR6dW5nPworICAgICAgICAgIGlmIChtYXJbImtleSJdPT1waSB8fCAoKHBpWzFdPT0nKicpICYmIChwaVswXT09bWFyWyJrZXkiXVswXSkpKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICBkZWJ1ZyAoc3ByaW50ZigibWFyPSVPLCBwaT0lTyIsbWFyLHBpKSk7CisgICAgICAgICAgICAgIC8vIEFMTEUgWkFITEVOIG1hbCAxLjUgbmVobWVuLiBNaXIgaXN0IGtsYXIsIGRhc3MgZGFzIG51biBhdWNoCisgICAgICAgICAgICAgIC8vIG1pdCBpcmdlbmR3ZWxjaGVuIEhhZXVmaWdrZWl0ZW4gcGFzc2llcnQsIGFiZXIgbWFsIGVocmxpY2gsCisgICAgICAgICAgICAgIC8vIGRhcyBpc3QgenVyIEJlcmVjaG51bmcgZWdhbC4KKyAgICAgICAgICAgICAgZm9yZWFjaCAoc3RyaW5nIGtrLCBtaXhlZCB2YWwgOiAmbWFyKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIGlmIChpbnRwKHZhbCkpCisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICB2YWw9MTUqdmFsLzEwOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAvLyBQQVNTIDM6IEpldHp0IGRpZSBCbG9ja2FkZW4gYXVzd2VydGVuCisgIGZvcmVhY2ggKG1hcHBpbmcgbWFyOndpcmt1bmdlbikKKyAgICB7CisgICAgICBmb3JlYWNoIChzdHJpbmcgcGk6YmxvY2thZGVuKQorICAgICAgICB7CisgICAgICAgICAgLy8gSGFiZW4gd2lyIGVpbmUgQmxvY2thZGU/CisgICAgICAgICAgaWYgKG1hclsia2V5Il09PXBpIHx8ICgocGlbMV09PScqJykgJiYgKHBpWzBdPT1tYXJbImtleSJdWzBdKSkpCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIGRlYnVnIChzcHJpbnRmKCJtYXI9JU8sIHBpPSVPIixtYXIscGkpKTsKKyAgICAgICAgICAgICAgLy8gSGllciB3ZXJkZW4gYWxsZSBaYWhsZW4gYXVmIE51bGwgZ2VzZXR6dC4KKyAgICAgICAgICAgICAgZm9yZWFjaCAoc3RyaW5nIGtrLCBtaXhlZCB2YWwgOiAmbWFyKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgIGlmIChpbnRwKHZhbCkpCisgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICB2YWw9MDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAvLyBQQVNTIDMuNTogUXVhbGl0YWV0IGRlciBLcmFldXRlciBza2FsaWVyZW4uCisgIGZvcmVhY2ggKG1hcHBpbmcgbWFyOndpcmt1bmdlbikKKyAgICB7CisgICAgICBmb3JlYWNoIChzdHJpbmcga2ssIG1peGVkIHZhbCA6ICZtYXIpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoaW50cCh2YWwpICYmIGtrIT0icXVhbGl0eSIpCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIHZhbD12YWwqbWFyWyJxdWFsaXR5Il0vMTAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgIC8vIFBBU1MgNDogTnVuIGFkZGllcmVuIHdpciBhbGxlcyBhdWYgaW4gZGFzIE1hcHBpbmcgYXR0cmliLgorICBhdHRyaWI9KFtdKTsKKyAgZm9yZWFjaCAobWFwcGluZyBtYXI6d2lya3VuZ2VuKQorICAgIHsKKyAgICAgIGZvcmVhY2ggKHN0cmluZyBrazptYXIpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoaW50cChtYXJba2tdKSkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgYXR0cmliW2trXT1hdHRyaWJba2tdK21hcltra107CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgLy8gRGllIFdpcmt1bmdzZGF1ZXIgaXN0IGRlciBEdXJjaHNjaG5pdHQgZGVyIFdpcmt1bmdzZGF1ZXJuCisgIGF0dHJpYltUX0VGRkVDVF9EVVJBVElPTl0gLz0gc2l6ZW9mKHBsYW50aWRzKTsKKyAgZGVidWcoc3ByaW50ZigiRHVyYXRpb246ICVkXG4iLGF0dHJpYltUX0VGRkVDVF9EVVJBVElPTl0pKTsKKworICAvLyBEaWUgSGFsdGJhcmtlaXQgZGVzIFRyYW5rcyBpc3QgZGllIEhhbHRiYXJrZWl0IGRlcyBrbGVpbnN0ZW4gS3JhdXRlcy4KKyAgaW50IGR1cj0xMDAwMDAwMDsKKyAgZm9yZWFjaCAobWFwcGluZyBtYXI6d2lya3VuZ2VuKQorICAgIHsKKyAgICAgIGlmIChtYXJbVF9FWFBJUkVdPjAgJiYgZHVyPm1hcltUX0VYUElSRV0pCisgICAgICAgIHsKKyAgICAgICAgICBkdXI9bWFyW1RfRVhQSVJFXTsKKyAgICAgICAgfQorICAgIH0KKyAgaWYgKGR1cj09MTAwMDAwMDApCisgICAgeworICAgICAgZHVyPTA7CisgICAgfQorICBhdHRyaWJbVF9FWFBJUkVdPWR1cjsKKyAgZGVidWcoc3ByaW50ZigiRXhwaXJlOiAlZFxuIixkdXIpKTsKKworICBpbnQgbWF4aW11bT0wOworICAvLyBFZmZla3RlIHJhdXNyZWNobmVuLCBkaWUgbmljaHQgbWF4aW1hbCBzaW5kCisgIGZvcmVhY2ggKHN0cmluZyBraywgbWl4ZWQgdmFsOmF0dHJpYikKKyAgeworICAgIGlmIChtZW1iZXIoVF9LUkFVVF9FRkZFQ1RTLGtrKT49MCkKKyAgICB7CisgICAgICBpZiAodmFsPjAgJiYgbWF4aW11bTx2YWwpCisgICAgICB7CisgICAgICAgIG1heGltdW09dmFsOworICAgICAgfQorICAgIH0KKyAgfQorICAvLyBMb2dlaW50cmFnIGVyc3RlbGxlbi4KKyAgc2xfZXhlYygiSU5TRVJUIElOVE8gcm9oZGF0ZW4odWlkLCBybmQsIHJlY2VpcGUsIHF1YWxpdHksIGNhciwgZGEsIGRtLCBkdSwgIgorICAgICAgICAgICJkbiwgZmx0LCBmcm8sIGhJLCBoUCwgaEssIGhMLCBwYSwgcG0sIHB1LCBzcywgc3AsIHNkKSAiCisgICAgICAgICAgIlZBTFVFUyg/MSw/Miw/Myw/NCw/NSw/Niw/Nyw/OCw/OSw/MTAsPzExLCA/MTIsID8xMywgPzE0LCAiCisgICAgICAgICAgIj8xNSwgPzE2LCA/MTcsID8xOCwgPzE5LCA/MjAsID8yMSk7IiwKKyAgICAgICAgICB0aGlzX3BsYXllcigpID8gZ2V0dWlkKHRoaXNfcGxheWVyKCkpIDogIjx1bmtub3duPiIsCisgICAgICAgICAgenVmYWxsLAorICAgICAgICAgIGltcGxvZGUobWFwKHBsYW50aWRzLCAjJ3RvX3N0cmluZyksICIsICIpLAorICAgICAgICAgIGltcGxvZGUobWFwKHF1YWxpdGllcywgIyd0b19zdHJpbmcpLCAiLCAiKSwKKyAgICAgICAgICBhdHRyaWJbVF9DQVJSWV0sIGF0dHJpYltUX0RBTUFHRV9BTklNQUxTXSwKKyAgICAgICAgICBhdHRyaWJbVF9EQU1BR0VfTUFHSUNdLCBhdHRyaWJbVF9EQU1BR0VfVU5ERUFEXSwKKyAgICAgICAgICBhdHRyaWJbVF9FRkZFQ1RfRFVSQVRJT05dLCBhdHRyaWJbVF9GTEVFX1RQT1JUXSwKKyAgICAgICAgICBhdHRyaWJbVF9GUk9HXSwgYXR0cmliW1RfSEVBTF9ESVNFQVNFXSwKKyAgICAgICAgICBhdHRyaWJbVF9IRUFMX1BPSVNPTl0sIGF0dHJpYltUX0hFQUxfU1BdLAorICAgICAgICAgIGF0dHJpYltUX0hFQUxfTFBdLCBhdHRyaWJbVF9QUk9URUNUSU9OX0FOSU1BTFNdLAorICAgICAgICAgIGF0dHJpYltUX1BST1RFQ1RJT05fTUFHSUNdLCBhdHRyaWJbVF9QUk9URUNUSU9OX1VOREVBRF0sCisgICAgICAgICAgYXR0cmliW1RfU0FfU1BFRURdLCBhdHRyaWJbVF9TQV9TUEVMTF9QRU5FVFJBVElPTl0sCisgICAgICAgICAgYXR0cmliW1RfU0FfRFVSQVRJT05dKTsKKworICAvLyBNYXhpbWFsIHp3ZWkgcG9zaXRpdmUgRWZmZWt0ZS4KKyAgaW50IGN0ZWZmPTA7CisgIGZvcmVhY2ggKHN0cmluZyBraywgbWl4ZWQgdmFsIDogJmF0dHJpYikKKyAgeworICAgICAgaWYgKG1lbWJlcihUX0tSQVVUX0VGRkVDVFMsa2spPj0wKQorICAgICAgeworICAgICAgICAvLyBOdXIgZGllIDIgc3RhZXJrc3RlbiBwb3NpdGl2ZW4gV2lya3VuZ2VuIGJsZWliZW4gdWViZXIgKGRhenUKKyAgICAgICAgLy8gbXVlc3NlbiBzaWUgd2lya2xpY2ggZGVuIGdsZWljaGVuIFphaGxlbndlcnQgaGFiZW4sIGthbm4gYmVpCisgICAgICAgIC8vIEhlaWx1bmdlbiB2b3Jrb21tZW4sIHNvbnN0IGVoZXIgdW53YWhyc2NoZWlubGljaCkuCisgICAgICAgIGlmICh2YWw+MCAmJiBtYXhpbXVtPnZhbCkKKyAgICAgICAgeworICAgICAgICAgIHZhbD0wOworICAgICAgICB9CisgICAgICAgIC8vIFRocmVzaG9sZHMuIFp1IHp1IGdyb3NzZSBXaXJrdW5nZW4gaGFiZW4gZGllIEdyZW56ZSBhbHMKKyAgICAgICAgLy8gQXVzd2lya3VuZy4gTmVnYXRpdmUgV2lya3VuZ2VuLCBkaWUgLVRfTUlOSU1VTV9USFJFU0hPTEQgbmljaHQKKyAgICAgICAgLy8gdWViZXJzY2hyZWliZW4sIGZhbGxlbiB3ZWcuIEJlaSBkZW4gcG9zaXRpdmVuIGJsZWlidCBqYSBvaG5laGluIG51cgorICAgICAgICAvLyBkaWUgc3RhZXJrc3RlIFdpcmt1bmcgdWViZXIsIGRhIGdpYnQgZXMgZXJzdG1hbCBrZWluZQorICAgICAgICAvLyBNaW5kZXN0Z3JvZXNzZSBtZWhyLgorICAgICAgICBpZiAodmFsPlRfTUFYSU1VTV9USFJFU0hPTEQpCisgICAgICAgIHsKKyAgICAgICAgICB2YWw9VF9NQVhJTVVNX1RIUkVTSE9MRDsKKyAgICAgICAgfQorICAgICAgICBpZiAodmFsIDwgMCAmJiB2YWwgPiAtVF9NSU5JTVVNX1RIUkVTSE9MRCkKKyAgICAgICAgeworICAgICAgICAgIHZhbD0wOworICAgICAgICB9CisgICAgICAgIGlmIChtYXhpbXVtPT12YWwgJiYgdmFsPjApCisgICAgICAgIHsKKyAgICAgICAgICBjdGVmZisrOworICAgICAgICAgIC8vIFZvZWxsaWcgd2lsbGt1ZXJsaWNoLCB3YXMgaGllciBnZXRyb2ZmZW4gd2lyZC4gT2IgcmVwcm9kdXppZXJiYXIsCisgICAgICAgICAgLy8gdmVybXV0bGljaCBqYSwgYWJlciBoYWVuZ3QgbWl0IGRlciBNYXBwaW5nc3RydWt0dXIgenVzYW1tZW4uCisgICAgICAgICAgLy8gSGFyaGFyLgorICAgICAgICAgIGlmIChjdGVmZj4yKQorICAgICAgICAgIHsKKyAgICAgICAgICAgIHZhbD0wOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgfQorICB9CisgIGRlYnVnKHNwcmludGYoIiBUUkFOS0VSR0VCTklTOiAlTyIsYXR0cmliKSk7CisgIC8vIExvZ2VpbnRyYWcgZXJzdGVsbGVuLgorICBzbF9leGVjKCJJTlNFUlQgSU5UTyB0cmFlbmtlKHVpZCwgcm5kLCByZWNlaXBlLCBxdWFsaXR5LCBjYXIsIGRhLCBkbSwgZHUsICIKKyAgICAgICAgICAiZG4sIGZsdCwgZnJvLCBoSSwgaFAsIGhLLCBoTCwgcGEsIHBtLCBwdSwgc3MsIHNwLCBzZCkgIgorICAgICAgICAgICJWQUxVRVMoPzEsPzIsPzMsPzQsPzUsPzYsPzcsPzgsPzksPzEwLD8xMSwgPzEyLCA/MTMsID8xNCwgIgorICAgICAgICAgICI/MTUsID8xNiwgPzE3LCA/MTgsID8xOSwgPzIwLCA/MjEpOyIsCisgICAgICAgICAgdGhpc19wbGF5ZXIoKSA/IGdldHVpZCh0aGlzX3BsYXllcigpKSA6ICI8dW5rbm93bj4iLAorICAgICAgICAgIHp1ZmFsbCwKKyAgICAgICAgICBpbXBsb2RlKG1hcChwbGFudGlkcywgIyd0b19zdHJpbmcpLCAiLCAiKSwKKyAgICAgICAgICBpbXBsb2RlKG1hcChxdWFsaXRpZXMsICMndG9fc3RyaW5nKSwgIiwgIiksCisgICAgICAgICAgYXR0cmliW1RfQ0FSUlldLCBhdHRyaWJbVF9EQU1BR0VfQU5JTUFMU10sCisgICAgICAgICAgYXR0cmliW1RfREFNQUdFX01BR0lDXSwgYXR0cmliW1RfREFNQUdFX1VOREVBRF0sCisgICAgICAgICAgYXR0cmliW1RfRUZGRUNUX0RVUkFUSU9OXSwgYXR0cmliW1RfRkxFRV9UUE9SVF0sCisgICAgICAgICAgYXR0cmliW1RfRlJPR10sIGF0dHJpYltUX0hFQUxfRElTRUFTRV0sCisgICAgICAgICAgYXR0cmliW1RfSEVBTF9QT0lTT05dLCBhdHRyaWJbVF9IRUFMX1NQXSwKKyAgICAgICAgICBhdHRyaWJbVF9IRUFMX0xQXSwgYXR0cmliW1RfUFJPVEVDVElPTl9BTklNQUxTXSwKKyAgICAgICAgICBhdHRyaWJbVF9QUk9URUNUSU9OX01BR0lDXSwgYXR0cmliW1RfUFJPVEVDVElPTl9VTkRFQURdLAorICAgICAgICAgIGF0dHJpYltUX1NBX1NQRUVEXSwgYXR0cmliW1RfU0FfU1BFTExfUEVORVRSQVRJT05dLAorICAgICAgICAgIGF0dHJpYltUX1NBX0RVUkFUSU9OXSk7CisKKyAgcmV0dXJuIGF0dHJpYjsKK30KKworbWFwcGluZyBtYWtlX3BvdGlvbihvYmplY3QqIHBsYW50cykKK3sKKyAgLy8gLT4gbWFwcHQgbmljaHQtT2JqZWt0IHp1IDAsIGFiZXIgMCBpc3QgYXVjaCBuZSBndWVsdGlnZSBQbGFudElELiBEYWhlcgorICAvLyBt/HNzZW4gemVyc3RvZXJ0ZW4gT2JqZWt0ZSB2b3JoZXIgcmF1cy4KKyAgLy8gVE9ETzogZHJhdWYgdmVybGFzc2VuLCBkYXNzIG51ciBpbnRha3RlIE9iamVrdCBlbnRoYWx0ZW4gc2luZD8KKyAgaWYgKG1lbWJlcihwbGFudHMsIDApID49IDApCisgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigibWFrZV9wb3Rpb24oKSBnb3QgaW52YWxpZCBvYmplY3QgaW4gcGxhbnQgYXJyYXkgIgorICAgICAgICAgICAgICAgICAgICAgICAgIiUuNTBPXG4iLHBsYW50cykpOworCisgIGludCogcGxhbnRpZHMgPSAoaW50KilwbGFudHMtPlF1ZXJ5UGxhbnRJZCgpOworICBpbnQqIHF1YWxpdGllcyA9IChpbnQqKXBsYW50cy0+UXVlcnlQcm9wKFBfUVVBTElUWSk7CisKKyAgcmV0dXJuIGNhbGN1bGF0ZV9wb3Rpb24ocGxhbnRpZHMsIHF1YWxpdGllcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgWldFSVRJRVMtPlF1ZXJ5RmFtaWxpZSh0aGlzX3BsYXllcigpKSk7Cit9CisKKy8vIEFOOiBTdWNodCBhbGxlIFBmbGFuemVuIHJhdXMsIGluIGRlcmVuIE5hbWVuIGRlciBTdWNoYmVncmlmZiAic3RyIgorLy8gdm9ya29tbXQgdW5kIGxpc3RldCBkaWVzZSBhdWYuIExhZXVmdCBhbGxlcmRpbmdzIG1vbWVudGFuIG5vY2ggaW4gZWluZW4KKy8vIEZlaGxlciAiaW5kZXggb3V0IG9mIGJvdW5kcyIsIGFiZXIgbWFuIG11ZXNzdGUgaGllciAoVE9ETykgc293aWVzbyBtYWwKKy8vIHZvbiBleHBsb2RlKCkgYXVmIHN0cnN0cigpIHVtYmF1ZW4sIGRlbmtlIGljaC4KK3N0cmluZyBfZmluZHBsYW50KHN0cmluZyBzdHIpIHsKKyAgaW50IGksIGs7CisgIHN0cmluZyAqaW5kLCAqdG1wOworCisgIGlmKCFzdHIpIHJldHVybiAiIjsKKyAgd3JpdGUoIlN1Y2hlIG5hY2ggJyIrc3RyKyInOlxuXG4iKTsKKyAgaW5kID0gbV9pbmRpY2VzKG1hcF9sZGZpZWQpOworICBmb3IoaT0wO2k8c2l6ZW9mKGluZCk7aSsrKSB7CisgICAgdG1wID0gbWFwX2xkZmllZFtpbmRbaV1dWzBdOworICAgIGlmKCBzdHJpbmdwKHRtcFszXSkgJiYgCisgICAgICAgIG9sZF9leHBsb2RlKGxvd2VyX2Nhc2UodG1wWzNdKSxzdHIpWzBdICE9IGxvd2VyX2Nhc2UodG1wWzNdKSAKKyAgICAgICAgfHwKKyAgICAgICAgc3RyaW5ncCh0bXBbNF0pICYmIAorICAgICAgICBvbGRfZXhwbG9kZShsb3dlcl9jYXNlKHRtcFs0XSksc3RyKVswXSAhPSBsb3dlcl9jYXNlKHRtcFs0XSkpCisgICAgICB3cml0ZSgiIC0gICIrdG1wWzNdKworICAgICAgICAgIChzdHJpbmdwKHRtcFs0XSk/IiAoIit0bXBbNF0rIikiOiIiKSsiICAgICAgIC0gIit0bXBbMF0rIlxuIik7CisgIH0KKworICByZXR1cm4gIiI7Cit9CisKKy8vIEFOOiBGdW5rdGlvbiBsaWVmZXJ0IGRhcyBFcmdlYm5pc2FycmF5IGF1cyBtYWtlX3BvdGlvbigpIGZ1ZXIgZWluZSBMaXN0ZQorLy8gdm9uIEtyYWV1dGVybiwgZGllIGFscyAiLCAiLWdldHJlbm50ZSBLcmF1dC1JRHMgdWViZXJnZWJlbiB3ZXJkZW4gbXVlc3Nlbi4KK21peGVkIF9jaGVja1RyYW5rKHN0cmluZyBzdHIpCit7CisgIGlmIChleHRlcm5fY2FsbCgpICYmICFhbGxvd2VkKCkpCisgICAgcmV0dXJuIDA7CisKKyAgc3RyaW5nICppbmQsICphcmdzLCBuYW1lOworICBvYmplY3QgKm9ianM7CisgIGludCBrLCBsOworCisgIG9ianMgPSAoe30pOworICBpZighc3RyKSByZXR1cm4gIktlaW5lIEtyYWV1dGVyIHVlYmVyZ2ViZW4hIjsKKyAgaW5kID0gb2xkX2V4cGxvZGUoc3RyLCIsIik7CisvLyAgaW5kID0gKHsiMTgwIiwiMTEiLCI1MyJ9KTsKKyAgZm9yKGludCBpPTA7aTxzaXplb2YoaW5kKTtpKyspCisgIHsKKyAgICBuYW1lID0gYnVpbGRfcGxhbnRuYW1lKGtyYXV0cHJvcHNbdG9faW50KGluZFtpXSldKTsKKyAgICB3cml0ZSgiSW5wdXQ6ICciK25hbWUrIicgKCIraW5kW2ldKyIpXG4iKTsKKyAgICBvYmpzICs9ICh7Y2xvbmVfb2JqZWN0KFBMQU5URElSK25hbWUpfSk7CisgIH0KKyAgbWFwcGluZyByYWd0ZXN0ID0gbWFrZV9wb3Rpb24ob2Jqcyk7CisgIG9ianMtPnJlbW92ZSgpOworLyogIG5hbWU9IiI7CisgIGZvcihpbnQgaT0wO2k8c2l6ZW9mKHJhZ3Rlc3QpO2krKykKKyAgICAgICBuYW1lID0gbmFtZSArIHJhZ3Rlc3RbaV0rIiwiOworICB3cml0ZSgiUmVzdWx0OiAoeyAiK25hbWUrIiB9KVxuIik7Ki8KKyAgcmV0dXJuIHNwcmludGYoIiVPXG4iLHJhZ3Rlc3QpOworfQorCisjZGVmaW5lIFFVQUxfQkFTRSAgMAorI2RlZmluZSBRVUFMX1JORCAgIDEKKyNkZWZpbmUgREVMQVlfQkFTRSAyCisjZGVmaW5lIERFTEFZX1JORCAgMworCisjZGVmaW5lIEFMTE9XRURfRFJJRVIgIi9pdGVtcy9rcmFldXRlci90cm9ja25lciIKKworLy8gTGllZmVydCBkaWUgVHJvY2tudW5nc2RhdGVuIGVpbmVzIFJhdW1lcyBhdXMsIG1pdCBkZW5lbiBkZXIgS3JhZXV0ZXItCisvLyB0cm9ja25lciBkYW5uIGRhcyBLcmF1dCBiZWFyYmVpdGVuIGthbm4uCitpbnQgKlF1ZXJ5RHJ5aW5nRGF0YSgpIHsKKyAgLy8gRXMgbXVzcyBhbGxlcmRpbmdzIGRhcyBhdWZydWZlbmRlIE9iamVrdCBlaW4gVHJvY2tuZXItQ2xvbmUgc2VpbiwgCisgIC8vIGRlciBpbiBlaW5lbSBkZXIgenVnZWxhc3NlbmVuIFJhZXVtZSBzdGVoZW4gbXVzcy4KKyAgLy8gV2VubiBkYXMgbmljaHQgZGVyIEZhbGwgaXN0LCB3aXJkIGRlciBUcm9ja25lciBkYXMgbGVlcmUgQXJyYXksIGRhcyAKKyAgLy8genVydWVja2dlZ2ViZW4gd2lyZCwgYWxzIEluZGl6IHdlcnRlbiwgZGFzcyBlciBpbSBmYWxzY2hlbiBSYXVtIHN0ZWh0LgorICBpZiAoIG9iamVjdHAocHJldmlvdXNfb2JqZWN0KCkpICYmCisgICAgICAgbG9hZF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSA9PSBBTExPV0VEX0RSSUVSICYmCisgICAgICAgbWVtYmVyKGRyeWluZ19kYXRhLCBsb2FkX25hbWUoZW52aXJvbm1lbnQocHJldmlvdXNfb2JqZWN0KCkpKSkgJiYKKyAgICAgICBjbG9uZXAocHJldmlvdXNfb2JqZWN0KCkpICkKKyAgeworICAgIC8vIFJhdW0gZXJtaXR0ZWxuLCBEZWxheS9RdWFsaSBlcnJlY2huZW4sIEVyZ2VibmlzYXJyYXkgenVydWVja2dlYmVuLgorICAgIHN0cmluZyB3aGVyZSA9IGxvYWRfbmFtZShlbnZpcm9ubWVudChwcmV2aW91c19vYmplY3QoKSkpOworICAgIGludCBkZWxheSA9IGRyeWluZ19kYXRhW3doZXJlLERFTEFZX0JBU0VdKworICAgICAgICAgICAgICAgIHJhbmRvbShkcnlpbmdfZGF0YVt3aGVyZSxERUxBWV9STkRdKTsKKyAgICBpbnQgcXVhbCAgPSBkcnlpbmdfZGF0YVt3aGVyZSxRVUFMX0JBU0VdKworICAgICAgICAgICAgICAgIHJhbmRvbShkcnlpbmdfZGF0YVt3aGVyZSxRVUFMX1JORF0pOworICAgIHJldHVybiAoeyBkZWxheSwgcXVhbCB9KTsKKyAgfQorICByZXR1cm4gKHt9KTsKK30KKworLy8gTW9kaWZpemllcmVuIGRlciBUcm9ja251bmdzZGF0ZW4uCisvLyA8cm9vbT4gbXVzcyBkZXIgdm9sbGUgRGF0ZWluYW1lIGRlcyBSYXVtZXMgc2Vpbiwgb2huZSAuYyBhbSBFbmRlLgorLy8gPHZhbHVlcz4gZW50aGFlbHQgZGllIHZpZXIgUGFyYW1ldGVyIHp1IGRlbSBSYXVtIGluIGZvbGdlbmRlciBSZWloZW5mb2xnZToKKy8vICh7IFF1YWxpLUJhc2lzLCBRdWFsaS1adWZhbGxzYW50ZWlsLCBEZWxheS1CYXNpcywgRGVsYXktWnVmYWxsc2FudGVpbCB9KQorLy8gV2VubiA8dmFsdWVzPiBuaWNodCBhbmdlYmVuIHdpcmQgb2RlciAwIGlzdCwgd2VyZGVuIGRpZSBEYXRlbiB6dSA8cm9vbT4KKy8vIGdlbG9lc2NodC4KK2ludHxtYXBwaW5nIFNldERyeWluZ0RhdGEoc3RyaW5nIHJvb20sIGludCogdmFsdWVzKSAKK3sKKyAgLy8ga2VpbmUgWnVncmlmZnNyZWNodGUKKyAgaWYgKCAhYWxsb3dlZCgpICkKKyAgICByZXR1cm4gLTE7CisgIAorICAvLyA8dmFsdWVzPiB3dXJkZSBuaWNodCB1ZWJlcmdlYmVuPyBEYW5uIERhdGVuIGxvZXNjaGVuLgorICBpZiAoICF2YWx1ZXMgKSAKKyAgeworICAgIG1fZGVsZXRlKGRyeWluZ19kYXRhLCByb29tKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIC8vIEFuc29uc3RlbiBtdWVzc2VuIDQgSW50ZWdlci1XZXJ0ZSBhbHMgPHZhbHVlcz4gdWViZXJnZWJlbiB3ZXJkZW4uCisgIGlmICggc2l6ZW9mKHZhbHVlcykgIT0gNCApIAorICAgIHJldHVybiAtMjsKKworICBpZiAoIHJvb21bPDIuLjwxXSA9PSAiLmMiICkKKyAgICByb29tID0gcm9vbVsuLjwzXTsKKworICAvLyBVZWJlcmdlYmVuZSBEYXRlbiBhZW5kZXJuIGRpcmVrdCBkYXMgTWFwcGluZyBkZXIgVHJvY2tudW5nc2RhdGVuLgorICBtX2FkZChkcnlpbmdfZGF0YSwgcm9vbSwgdmFsdWVzLi4uKTsKKyAgc2F2ZSgpOworICByZXR1cm4gKFsgcm9vbSA6IGRyeWluZ19kYXRhW3Jvb20sMF07IGRyeWluZ19kYXRhW3Jvb20sMV07IAorICAgICAgICAgICAgICAgICAgIGRyeWluZ19kYXRhW3Jvb20sMl07IGRyeWluZ19kYXRhW3Jvb20sM11dKTsKK30KKwordmFyYXJncyBtYXBwaW5nIFF1ZXJ5RHJ5aW5nKCkKK3sKKyAgcmV0dXJuIChhbGxvd2VkKCkgPyBkcnlpbmdfZGF0YSA6IChbXSkgKTsKK30KKwordmFyYXJncyBpbnQgcmVtb3ZlKGludCBzaWxlbnQpIAoreworICBzYXZlKCk7CisgIHJldHVybiA6OnJlbW92ZShzaWxlbnQpOworfQorCisvKgorI2RlZmluZSBEUllJTkdEQVRBICIvc2VjdXJlL0FSQ0gva3JhZXV0ZXJ0cm9ja251bmdzZGF0ZW4iCisKK3ByaXZhdGUgdm9pZCBSZWFkRHJ5aW5nRGF0YSgpIAoreworICBtaXhlZCBkYXRhID0gZXhwbG9kZShyZWFkX2ZpbGUoRFJZSU5HREFUQSksICJcbiIpLSh7IiJ9KTsKKyAgZm9yZWFjaChzdHJpbmcgbGluZSA6IGRhdGEpIAorICB7CisgICAgaWYgKCBsaW5lWzBdID09ICcjJyApCisgICAgICBjb250aW51ZTsKKyAgICBzdHJpbmcgKmZpZWxkcyA9IGV4cGxvZGUobGluZSwiOyIpOworICAgIGZpZWxkc1sxLi5dID0gbWFwKGZpZWxkc1sxLi5dLCAjJ3RvX2ludCk7CisgICAgbV9hZGQodG1wX2RyeWluZ19kYXRhLCBmaWVsZHMuLi4pOworICB9Cit9Ki8KKwo=