ZGlmZiAtLWdpdCBhL3N0ZC8ucmVhZG1lIGIvc3RkLy5yZWFkbWUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDg5YzgwMwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC8ucmVhZG1lCkBAIC0wLDAgKzEsMjQgQEAKK0hpZXIgZmluZGVzdCBkdSB2b3IgYWxsZW0gYWJzdHJha3RlIEJhc2lza2xhc3NlbiBmdWVyIGFsbGUgT2JqZWt0ZS4KKworYXJtb3VyWy5jXSAgICAgIC0gZGllIEJhc2lza2xhc3NlIGZ1ZXIgUnVlc3R1bmdlbgorY2xvdGhpbmdbLmNdICAgIC0gZGllIEJhc2lza2xhc3NlIGZ1ZXIgKEJlKUtsZWlkdW5nCitjb250YWluZXJbLmNdICAgLSBjb250YWluZXItQmFzaXNvYmpla3QKK2NvcnBzZS5jICAgICAgICAtIGRpZSBMZWljaGUgdm9uIFNwaWVsZXJuIHVuZCBOUENzCitnaWxkZS5jICAgICAgICAgLSBCYXNpc2tsYXNzZSBmdWVyIGRpZSBGaWxpYWxlbiBkZXIgQURWLUdpbGRlCitpbnBjWy5jXSAgICAgICAgLSBCYXNpc2tsYXNzZSBmdWVyIGludGVsbGlnZW50ZW4gTlBDIFtJTiBFTlRXSUNLTFVOR10KK2xhZGVuLmMgICAgICAgICAtIEJhc2lza2xhc3NlIGZ1ZXIgZGVuIExhZGVuCitsaXZpbmcgICAgICAgICAgLSBCYXNpc2tsYXNzZW4gZnVlciBMZWJld2VzZW4KK25wY1suY10gICAgICAgICAtIEJhc2lza2xhc3NlIGZ1ZXIgTm9uLVBsYXllci1DaGFyYWN0ZXJzCitwbGF5ZXIgICAgICAgICAgLSBCYXNpcyBmdWVyIFNwaWVsZXJvYmpla3RlLCBzaWVoZSBzaGVsbHMKK3B1Yi5jICAgICAgICAgICAtIEJhc2lza2xhc3NlIGZ1ZXIgS25laXBlbgorcm9vbVsuY10gICAgICAgIC0gZGF2b24gbGVpdGVuIHNpY2ggYWxsZSBSYWV1bWUgYWIKK3NoZWxscyAgICAgICAgICAtIGRhIHN0ZWhlbiBkaWUgUGxheWVyLU9iamVrdGUgZHJpbgorc3RvcmUuYyAgICAgICAgIC0gQmFzaXNrbGFzc2UgZnVlciBMYWdlcnJhZXVtZSAtIHBhc3N0IHp1IExhZGVuLmMKK3RoaW5nWy5jXSAgICAgICAtIEJhc2lza2xhc3NlIGZ1ZXIgQUxMRVMgT2JqZWt0ZQordW5pdC5jICAgICAgICAgIC0gS2xhc3NlIGZ1ZXIgTWVocmZhY2gtT2JqZWt0ZSB3aWUgZGFzIEdlbGQKK3dlYXBvblsuY10gICAgICAtIEJhc2lza2xhc3NlIGZ1ZXIgV2FmZmVuCisKK0JpdHRlIE9iamVrdCBoaWVyIG5pY2h0IG1pdCAndXBkIC1sJywgJ3hsb2FkJyBvLmFlLiBsYWRlbiEgWnVtICJOZXVsYWRlbiIgbnVyCitkaWUgQmx1ZXByaW50IGRlc3RydWN0ZW4gKHouQi4gcGVyIHVwZCksIHNpZSB3ZXJkZW4gYXV0b21hdGlzY2ggYmVpIEJlZGFyZgorbmV1Z2VsYWRlbi4KKwpkaWZmIC0tZ2l0IGEvc3RkL2FybW91ci5jIGIvc3RkL2FybW91ci5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmUwZjRiOGYKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvYXJtb3VyLmMKQEAgLTAsMCArMSw1MyBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGFybW91ci5jIC0tIGFybW91ciBzdGFuZGFyZCBvYmplY3QKKy8vCisvLyAkSWQ6IGFybW91ci5jIDc4MDQgMjAxMS0wNy0xMCAyMDozNzo1MlogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC90aGluZy9wcm9wZXJ0aWVzIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvY29tbWFuZHMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9yZXN0cmljdGlvbnMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9saWdodCI7Citpbmhlcml0ICIvc3RkL2FybW91ci9kZXNjcmlwdGlvbiI7Citpbmhlcml0ICIvc3RkL2Nsb3RoaW5nL21vdmluZyI7Citpbmhlcml0ICIvc3RkL2FybW91ci93ZWFyIjsKK2luaGVyaXQgIi9zdGQvYXJtb3VyL2NvbWJhdCI7Citpbmhlcml0ICIvc3RkL3RoaW5nL2xhbmd1YWdlIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvZW52Y2hrIjsKKworLy8jZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CisgIHByb3BlcnRpZXM6OmNyZWF0ZSgpOworICBjb21tYW5kczo6Y3JlYXRlKCk7CisgIGxpZ2h0OjpjcmVhdGUoKTsKKyAgcmVzdHJpY3Rpb25zOjpjcmVhdGUoKTsKKyAgZGVzY3JpcHRpb246OmNyZWF0ZSgpOworICB3ZWFyOjpjcmVhdGUoKTsKKyAgY29tYmF0OjpjcmVhdGUoKTsKKyAgZW52Y2hrOjpjcmVhdGUoKTsKKyAgQWRkSWQoIkRpbmciKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKKy8vIFp1bSBVZWJlcnNjaHJlaWJlbiwgZGFtaXQgZXMgbmljaHQgYnVnZ3QsIHdlbm4gZGllIExldXRlIGluIGlocmVuIE9iamVrdGVuICh3aWUKKy8vIGdld3VlbnNjaHQpIDo6cmVzZXQoKSBydWZlbi4KK3ZvaWQgcmVzZXQoKSB7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9hcm1vdXIvY29tYmF0LmMgYi9zdGQvYXJtb3VyL2NvbWJhdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2ODgxMzEKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvYXJtb3VyL2NvbWJhdC5jCkBAIC0wLDAgKzEsMjI4IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gYXJtb3VyL2NvbWJhdC5jIC0tIGFybW91ciBzdGFuZGFyZCBvYmplY3QKKy8vCisvLyAkSWQ6IGNvbWJhdC5jIDkwOTIgMjAxNS0wMS0xOSAyMzo1Nzo1MFogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx0aGluZy9jb21tYW5kcy5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorCisKKy8vIEdsb2JhbGUgVmFyaWFibGVuCitwcml2YXRlIG5vc2F2ZSBjbG9zdXJlIGRlZmVuZF9jbDsKK3ByaXZhdGUgbm9zYXZlIG1hcHBpbmcgcmVzaXN0YW5jZV9zdHJlbmd0aHM9KFtdKTsKKwordm9pZCBjcmVhdGUoKSB7CisgICAgLy8gRWluaWdlIEdydW5kd2VydGUgc2V0emVuCisgICAgU2V0KFBfQVJNT1VSX1RZUEUsIEFUX0lMTEVHQUwsIEZfVkFMVUUpOworICAgIFNldChQX0xBU1RfVVNFLHRpbWUoKSxGX1ZBTFVFKTsKK30KKworLy8gRGllIEZ1bmt0aW9uLCBkaWUgZGVuIFNjaHV0endlcnQgYmVyZWNobmV0LCBkZW4gZGllIFJ1ZXN0dW5nIGJpZXRldAoraW50IFF1ZXJ5RGVmZW5kKHN0cmluZ3xzdHJpbmcqIGRhbV90eXBlLCBpbnR8bWFwcGluZyBzcGVsbCwgb2JqZWN0IGVuZW15KQoreworICAgIGludCAgICAgcHJvdDsKKyAgICBtaXhlZCAgIGRlZl9mdW5jOworICAgIG9iamVjdCAgcGw7CisgICAgLy8gWnVtIENhY2hlbiB2b24gc3BlbGxbRUlORk9fREVGRU5EXSwgaGFldWZpZ2VzIExvb2t1cCBhdXMgZGVtIE1hcHBpbmcKKyAgICAvLyBrb2VubnRlIHVubm9ldGlnIFplaXQga29zdGVuLgorICAgIG1hcHBpbmcgZWluZm87CisKKyAgICAvLyBBVF9NSVNDLVJ1ZXR1bmdlbiBzY2h1ZXR6ZW4gbm9ybWFsZXJ3ZWlzZSBnYXIgbmljaHQuLi4KKyAgICBpZiAoUXVlcnlQcm9wKFBfQVJNT1VSX1RZUEUpPT1BVF9NSVNDKSB7CisgICAgICAgIC8vIGVzIHNlaSBkZW5uLCBzaWUgaGFiZW4gZWluZSBzcGV6aWVsbGUgRGVmZW5kRnVuYworICAgICAgICBpZiAoIWNsb3N1cmVwKGRlZmVuZF9jbCkpIHJldHVybigwKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8vIGFuc29uc3RlbiBSdWVzdHVuZ3NzY2h1dHogZXJtaXR0ZWxuIHVuZCBpbiBFSU5GT19ERUZFTkQgdmVybWVya2VuLgorICAgICAgICAvLyAoQmVpZGVzIGZ1ZXIgQVRfTUlTQyBpbiBqZWRlbSBGYWxsIHVubm9ldGlnKQorCisgICAgICAgIC8vIFJ1ZXN0dW5nZW4gc2NodWV0emVuIG51ciBnZWdlbiBwaHlzaWthbGlzY2hlbiBTY2hhZGVuCisgICAgICAgIGlmICgoIXNwZWxsIHx8IChtYXBwaW5ncChzcGVsbCkgJiYgc3BlbGxbU1BfUEhZU0lDQUxfQVRUQUNLXSkpCisgICAgICAgICAgICAmJiBzaXplb2YoZmlsdGVyKGRhbV90eXBlLFBIWVNJQ0FMX0RBTUFHRV9UWVBFUykpKQorICAgICAgICB7IAorICAgICAgICAgIC8vIFNjaHV0eiBiZXN0aW1tZW4sIE1pbmltdW0gMSwgYWJlciBudXIgd2VubiBQX0FDID4gMAorICAgICAgICAgIGludCBwYWMgPSBRdWVyeVByb3AoUF9BQyk7CisgICAgICAgICAgaWYgKHBhYyA+IDApCisgICAgICAgICAgICBwcm90ID0gKHBhYy80ICsgcmFuZG9tKHBhYyozLzQgKyAxKSkgfHwgMSA7CisgICAgICAgICAgb2JqZWN0IHN0YXQgPSBmaW5kX29iamVjdCgiL2QvZXJ6bWFnaWVyL3plc3N0cmEvcGFjc3RhdCIpOworICAgICAgICAgIGlmIChzdGF0KQorICAgICAgICAgICAgc3RhdC0+YWNzdGF0KFF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKSxwcm90LAorICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbShwYWMpKzEpOworCisgICAgICAgICAgLy8gcnVlc3R1bmdzY2h1dHogYW4gZGVmZW5kZnVuYyB3ZWl0ZXJtZWxkZW4KKyAgICAgICAgICBpZiAobWFwcGluZ3Aoc3BlbGwpICYmCisgICAgICAgICAgICAgIG1hcHBpbmdwKGVpbmZvPXNwZWxsW0VJTkZPX0RFRkVORF0pKSB7CisgICAgICAgICAgICAgIC8vIFNjaHV0eiBkLiBha3QuIFJ1ZXN0dW5nIHZlcm1lcmtlbi4KKyAgICAgICAgICAgICAgZWluZm9bREVGRU5EX0NVUl9BUk1PVVJfUFJPVF09cHJvdDsKKyAgICAgICAgICAgICAgLy8gZGF0ZW4gZGVyIFJ1ZXN0dW5nIHZlcm1lcmtlbi4KKyAgICAgICAgICAgICAgaWYgKG1hcHBpbmdwKGVpbmZvW0RFRkVORF9BUk1PVVJTXSkpIHsKKyAgICAgICAgICAgICAgICBlaW5mb1tERUZFTkRfQVJNT1VSU11bTUUsREVGX0FSTU9VUl9QUk9UXT1wcm90OworICAgICAgICAgICAgICB9CisgICAgICAgICAgfSAvLyBlbmRlIHZvbSBpZiAobWFwcGluZyhzcGVsbCkgLi4uKQorICAgICAgICB9IC8vIGVuZGUgdm9tIGlmIChwaHlzIFNjaGFkZW4pCisKKyAgICB9IC8vIGVuZGUgdm9tIGVsc2UgKHdlbm4ga2VpbiBBVF9NSVNDKSAKKworICAgIC8vIElzdCBlaW5lIERlZmVuZEZ1bmMgZ2VzZXR6dCwgd2lyZCBkaWVzZSBhdXNnZXdlcnRldAorICAgIGlmIChjbG9zdXJlcChkZWZlbmRfY2wpKSB7CisgICAgICAgIGlmICghb2JqZWN0cChnZXRfdHlwZV9pbmZvKGRlZmVuZF9jbCwyKSkpIHsKKyAgICAgICAgICAgIC8vIENsb3N1cmUgZ2VzZXR6dCwgYWJlciBuaWNodCBndWVsdGlnLCBzY2hhdWVuLCBvYiB3aXIgc2llIG5ldQorICAgICAgICAgICAgLy8gZXJzdGVsbGVuIGtvZW5uZW4uCisgICAgICAgICAgICBpZiAob2JqZWN0cChkZWZfZnVuYz1RdWVyeVByb3AoUF9ERUZFTkRfRlVOQykpKSB7CisgICAgICAgICAgICAgICAgZGVmZW5kX2NsPXN5bWJvbF9mdW5jdGlvbigiRGVmZW5kRnVuYyIsZGVmX2Z1bmMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLy8gc29uc3QgbG9lc2NoZW4sIHVtIHNwYWV0ZXIgZGllc2VuIFp3ZWlnIGdhbnogenUgc3BhcmVuLgorICAgICAgICAgICAgZWxzZSBkZWZlbmRfY2w9MDsKKyAgICAgICAgfQorICAgICAgICAvLyBCVFc6IEVzIGlzdCBvaywgd2VubiBkZWZlbmRfY2wgamV0enQgMCBpc3QsIGRhbm4gbGllZmVydCBmdW5jYWxsKCkKKyAgICAgICAgLy8gYXVjaCAwLgorICAgICAgICAvLyBCZWkgTmV0enRvdGVuIGtlaW5lICh6dXJ1ZWNrc2NobGFnZW5kZSkgRGVmZW5kRnVuYworICAgICAgICBpZiAob2JqZWN0cChwbD1RdWVyeVByb3AoUF9XT1JOKSkgJiYgKCFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHBsKSB8fAorICAgICAgICAgICAgICAgIGludGVyYWN0aXZlKHBsKSkgKSB7CisgICAgICAgICAgLy8gRGVyIFJ1ZWNrZ2FiZXdlcnQgZGVyIERlZmVuZEZ1bmMgd2lyZCB6dW0gU2NodXR6IGFkZGllcnQKKyAgICAgICAgICBwcm90ICs9IGZ1bmNhbGwoZGVmZW5kX2NsLCBkYW1fdHlwZSwgc3BlbGwsIGVuZW15KTsKKyAgICAgICAgICAvLyBsZWlkZXIga2FubiBkaWUgRGVmZW5kRnVuYyBqZXR6dCBhdWNoIG5vY2ggZGFzIE9iamVrdCB6ZXJzdG9lcnQKKyAgICAgICAgICAvLyBoYWJlbi4uLgorICAgICAgICAgIGlmICghb2JqZWN0cCh0aGlzX29iamVjdCgpKSkKKyAgICAgICAgICAgIHJldHVybiBwcm90OworICAgICAgICB9CisgICAgfQorCisgICAgLy8gWmVpdHB1bmt0IGRlciBsZXR6dGVuIEJlbnV0enVuZyBhdXNnZWJlbgorICAgIFNldFByb3AoUF9MQVNUX1VTRSx0aW1lKCkpOworCisgICAgLy8gQmVyZWNobmV0ZW4gU2NodXR6IHp1cnVlY2tnZWJlbgorICAgIHJldHVybiBwcm90OworfQorCisvLyBFcyBkdWVyZmVuIG51ciAibGVnYWxlIiBSdWVzdHVuZ3N0eXBlbiBnZXNldHp0IHdlcmRlbiwgYW5zb25zdGVuCisvLyB3aXJkIEFUX0lMTEVHQUwgZ2VzZXR6dC4KK3N0YXRpYyBtaXhlZCBfc2V0X2FybW91cl90eXBlKG1peGVkIHR5cGUgKSB7CisgICAgaWYgKCFDT01CQVRfTUFTVEVSLT52YWxpZF9hcm1vdXJfdHlwZSh0eXBlKSkKKyAgICB7CisgICAgICAgIFNldChQX0FSTU9VUl9UWVBFLCAodHlwZT1BVF9JTExFR0FMKSwgRl9WQUxVRSk7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICAgIFNldChQX0FSTU9VUl9UWVBFLCB0eXBlKTsKKyAgICB9CisgICAgQWRkSWQodHlwZSk7CisKKyAgICByZXNpc3RhbmNlX3N0cmVuZ3Rocz0oW10pOworICAgIHJldHVybiB0eXBlOworfQorCisKKy8vIFdpcmQgZXR3YXMgYW4gUF9ERUZFTkRfRlVOQyBnZWFlbmRlcnQsIG11c3MgZGllIHp1Z2Vob2VyaWdlIGNsb3N1cmUKKy8vIG5ldSBlcnN0ZWxsdCB3ZXJkZW4uCitzdGF0aWMgb2JqZWN0IF9zZXRfZGVmZW5kX2Z1bmMob2JqZWN0IGFyZykgeworICBpZiAob2JqZWN0cChhcmcpICYmCisgICAgICBjbG9zdXJlcChkZWZlbmRfY2w9c3ltYm9sX2Z1bmN0aW9uKCJEZWZlbmRGdW5jIixhcmcpKSkgeyAgCisgICAgcmV0dXJuIFNldChQX0RFRkVORF9GVU5DLCBhcmcsIEZfVkFMVUUpOworICB9CisgIGRlZmVuZF9jbD0wOworICByZXR1cm4oU2V0KFBfREVGRU5EX0ZVTkMsIDAsIEZfVkFMVUUpKTsKK30KKworLy8gQXVjaCBSdWVzdHVuZ2VuIGtvZW5uZW4gZWluZW4gU2NoYWRlbnN0eXAgaGFiZW4uIERpZXNlciBrYW5uIGFscyBzdHJpbmcKKy8vIG9kZXIgYXJyYXkgYW5nZWdlYmVuIHdlcmRlbiwgd2lyZCBhYmVyIGludGVybiBhdWYgamVkZW4gRmFsbCBhbHMKKy8vIGFycmF5IGdlc3BlaWNoZXJ0Lgorc3RhdGljIG1peGVkIF9zZXRfZGFtX3R5cGUobWl4ZWQgYXJnKSB7CisgICAgaWYgKHBvaW50ZXJwKGFyZykpCisgICAgeworICAgICAgICByZXR1cm4gU2V0KFBfREFNX1RZUEUsIGFyZywgRl9WQUxVRSk7CisgICAgfQorICAgIGVsc2UgaWYgKHN0cmluZ3AoYXJnKSkKKyAgICB7CisgICAgICAgIHJldHVybiBTZXQoUF9EQU1fVFlQRSwgKHsgYXJnIH0pLCBGX1ZBTFVFKTsKKyAgICB9CisgICAgcmV0dXJuIFF1ZXJ5KFBfREFNX1RZUEUsIEZfVkFMVUUpOworfQorCisvLyBSdWVzdHVuZ2VuIGtvZW5uZW4gUmVzaXN0ZW56ZW4gc2V0emVuLiBEaWVzZSB3ZXJkZW4gamVkb2NoIG5pY2h0IHdpZQorLy8gIm5vcm1hbGUiIFJlc2lzdGVuemVuIGdlc2V0enQsIHNvbmRlcm4gYWxzIFByb3plbnR3ZXJ0ZSBkZXIgZnVlciBkaWVzZW4KKy8vIFR5cCBtYXhpbWFsIHp1bGFlc2lnZW4gUmVzaXN0ZW56LiBEaWUgQWVuZGVydW5nIGRlciBSZXNpc3RlbnplbiBkYXJmCisvLyBudXIgZHVyY2ggZGllIFJ1ZXN0dW5nIHNlbGJzdCBlcmZvbGdlbi4KKy8vIEJlaXNwaWVsOiAoW0RUX0ZJUkU6IDEwMCwgRFRfV0FURVI6IC0xNTBdKQorLy8gbWF4LiBGZXVlcnJlc2lzdGVueiwgMS41ZmFjaGUgQW5mYWVsbGlna2VpdAorc3RhdGljIG1peGVkIF9zZXRfcmVzaXN0YW5jZV9zdHJlbmd0aHMobWl4ZWQgcmVzbWFwKSB7CisgICAgZmxvYXQgIG1heF9yZXM7CisgICAgb2JqZWN0IHdvcm5fYnk7CisKKyAgICAvLyBFcyBkdWVyZmVuIG51ciBtYXBwaW5ncyBhbmdlZ2ViZW4gd2VyZGVuCisgICAgaWYgKCFtYXBwaW5ncChyZXNtYXApKQorICAgIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8vIGRpZSBNYXh3ZXJ0ZSBtdWVzc2VuIGpld2VpbHMgZHVyY2ggLTEwMCBnZXRlaWx0IHNlaW4sIGRhIGhpbnRlcmhlcgorICAgIC8vIG1pdCBkZXIgUHJvemVudHphaGwgbXVsdGlwbGl6aWVydCB3aXJkIHVuZCBkaWUgYW5nYWJlIGRlciBWb3J6ZWljaGVuCisgICAgLy8gaGllciB1bWdla2VocnQgd2llIGJlaSBkZW4gIm5vcm1hbGVuIiBSZXNpc3RlbnplbiBpc3QuIERlcgorICAgIC8vIE1heGltYWx3ZXJ0IGlzdCB2b20gUnVlc3R1bmdzdHlwIGFiaGFlbmdpZy4KKyAgICBzd2l0Y2ggKFF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKSkKKyAgICB7CisgICAgICAgIGNhc2UgQVRfQ0xPQUsgIDoKKyAgICAgICAgY2FzZSBBVF9SSU5HICAgOgorICAgICAgICBjYXNlIEFUX0FNVUxFVCA6IG1heF9yZXM9LTAuMDAxMDsKKyAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBBVF9TSElFTEQgOgorICAgICAgICBjYXNlIEFUX0FSTU9VUiA6IG1heF9yZXM9LTAuMDAxNTsKKyAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdCAgICAgICAgOiBtYXhfcmVzPS0wLjAwMDU7CisgICAgfQorCisgICAgLy8gUmVzaXN0ZW56LU1hcHBpbmcgYWt0dWFsaXNpZXJlbgorICAgIHJlc2lzdGFuY2Vfc3RyZW5ndGhzPShbXSk7CisgICAgZm9yZWFjaChzdHJpbmcgZGFtdHlwZSwgaW50IHJlczogcmVzbWFwKQorICAgIHsKKyAgICAgICAgaWYgKCFpbnRwKHJlcykpIHJlcz10b19pbnQocmVzKTsKKyAgICAgICAgLy8gTWVociBhbHMgMTAwIFByb3plbnQgaXN0IG5pY2h0IGVybGF1YnQKKyAgICAgICAgaWYgKHJlcz4xMDApCisgICAgICAgIHsKKyAgICAgICAgICAgIHJlcz0xMDA7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAocmVzPDApCisgICAgICAgIHsKKyAgICAgICAgICAgICByZXM9KHJlcy80KSo1OworICAgICAgICAgICAgIC8vIE1hbiBrYW5uIGF1Y2ggbmljaHQgYmVsaWViaWcgbmVnYXRpdiB3ZXJkZW4KKyAgICAgICAgICAgICBpZiAocmVzPC0xMDAwKQorICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgcmVzPS0xMDAwOworICAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvLyBEZXIgUmVzaXN0ZW56d2VydCBiZXJlY2huZXQgc2ljaCBhdXMgZGVtIFByb2R1a3QgZGVzCisgICAgICAgIC8vIE1heGltYWx3ZXJ0ZXMgdW5kIGRlciBQcm96ZW50emFobAorICAgICAgICByZXNpc3RhbmNlX3N0cmVuZ3Roc1tkYW10eXBlXT1yZXMqbWF4X3JlczsKKyAgICB9CisKKyAgICAvLyBXZXJkZW4gZGllIFJlc2lzdGVuemVuIGJlaSBlaW5lciBnZXRyYWdlbmVuIFJ1ZXN0dW5nIGdlYWVuZGVydCwKKyAgICAvLyBtdXNzIGRlciBUcmFlZ2VyIGRhdm9uIG5hdHVlcmxpY2ggYmVlaW5mbHVzc3Qgd2VyZGVuLgorICAgIGlmIChvYmplY3RwKHdvcm5fYnk9UXVlcnlQcm9wKFBfV09STikpKQorICAgIHsKKyAgICAgICAgd29ybl9ieS0+QWRkUmVzaXN0YW5jZU1vZGlmaWVyKHJlc2lzdGFuY2Vfc3RyZW5ndGhzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlQcm9wKFBfQVJNT1VSX1RZUEUpKTsKKyAgICB9CisgICByZXR1cm4gcmVzaXN0YW5jZV9zdHJlbmd0aHM7Cit9CisKKy8vIEJlaSBlaW5lbSBRdWVyeVByb3AoUF9SRVNJU1RBTkNFX1NUUkVOR1RIUykgc29sbCBkYXMgYWt0dWVsbGUKKy8vIFJlc2lzdGVuemVuLU1hcHBpbmcgenVydWVja2dlZ2ViZW4gd2VyZGVuCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfcmVzaXN0YW5jZV9zdHJlbmd0aHMoKSB7CisgIHJldHVybiAocmVzaXN0YW5jZV9zdHJlbmd0aHN8fChbXSkpOworfQorCmRpZmYgLS1naXQgYS9zdGQvYXJtb3VyL2NvbnRhaW5lcl9kZXNjcmlwdGlvbi5jIGIvc3RkL2FybW91ci9jb250YWluZXJfZGVzY3JpcHRpb24uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iMWU3M2FkCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2FybW91ci9jb250YWluZXJfZGVzY3JpcHRpb24uYwpAQCAtMCwwICsxLDY3IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gYXJtb3VyL2NvbnRhaW5lcl9kZXNjcmlwdGlvbi5jIC0tIGFybW91cl9jb250YWluZXIgZGVzY3JpcHRpb24gaGFuZGxpbmcKKy8vCisvLyAkSWQ6IGNvbnRhaW5lcl9kZXNjcmlwdGlvbi5jIDYzMDYgMjAwNy0wNS0yMCAxMTozMjowM1ogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKworaW5oZXJpdCAiL3N0ZC9jbG90aGluZy9jb250YWluZXJfZGVzY3JpcHRpb24iOworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8dGhpbmcvbGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxjb250YWluZXIuaD4KKyNpbmNsdWRlIDxjb21iYXQuaD4KKyNpbmNsdWRlIDx0aGluZy9tYXRlcmlhbC5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvYmFzZS5oPgorCitzdHJpbmcgZGFtX2Rlc2NyKCkgeyAgIAorICAgIHN0cmluZyByZTsKKyAgICBtaXhlZCBkZXNjOworICAgIGludCBtYXhpbXVtLGRhbSxwb3M7CisKKyAgICBpZiAoIVF1ZXJ5UHJvcChQX05BTUUpIHx8ICFRdWVyeVByb3AoUF9EQU1BR0VEKSB8fCAhUXVlcnlQcm9wKFBfU0hPUlQpIHx8CisgICAgICAgICEoZGVzYz1RdWVyeVByb3AoUF9EQU1fREVTQykpIHx8ICghc3RyaW5ncChkZXNjKSAmJiAhcG9pbnRlcnAoZGVzYykpKQorICAgICAgICByZXR1cm4gIiI7CisgICAgcmUgPSBjYXBpdGFsaXplKG5hbWUoV0VSLDIpKSsiICI7CisgICAgbWF4aW11bSA9IFF1ZXJ5UHJvcChQX0FDKSsoZGFtPVF1ZXJ5UHJvcChQX0RBTUFHRUQpKTsKKyAgICBpZiAoc3RyaW5ncChkZXNjKSkKKyAgICAgICAgcmV0dXJuIChkYW0+KG1heGltdW0vMikpPyhyZStkZXNjKyIuXG4iKToiIjsKKyAgICBwb3MgPSAoc2l6ZW9mKGRlc2MpKmRhbS9tYXhpbXVtKTsKKyAgICBpZiAoc3RyaW5ncChkZXNjW3Bvc10pKQorICAgICAgICByZXR1cm4gKHJlK2Rlc2NbcG9zXSsiLlxuIik7CisgICAgcmV0dXJuICIiOworfQorCittYXBwaW5nIF9xdWVyeV9tYXRlcmlhbCgpIHsKKyAgbWl4ZWQgcmVzLGF0OworCisgIGlmIChtYXBwaW5ncChyZXM9UXVlcnkoUF9NQVRFUklBTCkpKQorICAgIHJldHVybiByZXM7CisgIGF0PVF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKTsKKyAgc3dpdGNoKGF0KSB7CisgICAgY2FzZSBBVF9BUk1PVVI6CisgICAgY2FzZSBBVF9IRUxNRVQ6CisgICAgY2FzZSBBVF9SSU5HOgorICAgIGNhc2UgQVRfQU1VTEVUOgorICAgIGNhc2UgQVRfU0hJRUxEOgorICAgIHJldHVybiAoW01BVF9NSVNDX01FVEFMOjEwMF0pOworICAgIGNhc2UgQVRfQ0xPQUs6CisgICAgY2FzZSBBVF9UUk9VU0VSUzoKKyAgICByZXR1cm4gKFtNQVRfQ0xPVEg6MTAwXSk7CisgICAgY2FzZSBBVF9HTE9WRToKKyAgICBjYXNlIEFUX0JPT1Q6CisgICAgcmV0dXJuIChbTUFUX0xFQVRIRVI6MTAwXSk7CisgIH0KKyAgcmV0dXJuIChbTUFUX0xFQVRIRVI6MTAwXSk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9hcm1vdXIvZGVzY3JpcHRpb24uYyBiL3N0ZC9hcm1vdXIvZGVzY3JpcHRpb24uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yZTI2Mjk0Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2FybW91ci9kZXNjcmlwdGlvbi5jCkBAIC0wLDAgKzEsNjIgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBhcm1vdXIvZGVzY3JpcHRpb24uYyAtLSBhcm1vdXIgZGVzY3JpcHRpb24gaGFuZGxpbmcKKy8vCisvLyAkSWQ6IGRlc2NyaXB0aW9uLmMgNjMwNiAyMDA3LTA1LTIwIDExOjMyOjAzWiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCitpbmhlcml0ICIvc3RkL2Nsb3RoaW5nL2Rlc2NyaXB0aW9uIjsKKworLy8jZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCitzdHJpbmcgZGFtX2Rlc2NyKCkKK3sgICBzdHJpbmcgcmU7CisgICAgbWl4ZWQgZGVzYzsKKyAgICBpbnQgbWF4aW11bSxkYW0scG9zOworCisgICAgaWYgKCFRdWVyeVByb3AoUF9OQU1FKSB8fCAhUXVlcnlQcm9wKFBfREFNQUdFRCkgfHwgIVF1ZXJ5UHJvcChQX1NIT1JUKSB8fAorICAgICAgICAhKGRlc2M9UXVlcnlQcm9wKFBfREFNX0RFU0MpKSB8fCAoIXN0cmluZ3AoZGVzYykgJiYgIXBvaW50ZXJwKGRlc2MpKSkKKyAgICAgICAgcmV0dXJuICIiOworICAgIHJlID0gY2FwaXRhbGl6ZShuYW1lKFdFUiwyKSkrIiAiOworICAgIG1heGltdW0gPSBRdWVyeVByb3AoUF9BQykrKGRhbT1RdWVyeVByb3AoUF9EQU1BR0VEKSk7CisgICAgaWYgKHN0cmluZ3AoZGVzYykpCisgICAgICAgIHJldHVybiAoZGFtPihtYXhpbXVtLzIpKT8ocmUrZGVzYysiLlxuIik6IiI7CisgICAgaWYgKG1heGltdW09PWRhbSkKKyAgICAgICAgcG9zPXNpemVvZihkZXNjKS0xOworICAgIGVsc2UKKyAgICAgICAgcG9zID0gKHNpemVvZihkZXNjKSpkYW0vbWF4aW11bSk7CisgICAgaWYgKHN0cmluZ3AoZGVzY1twb3NdKSkKKyAgICAgICAgcmV0dXJuIChyZStkZXNjW3Bvc10rIi5cbiIpOworICAgIHJldHVybiAiIjsKK30KKworCittYXBwaW5nIF9xdWVyeV9tYXRlcmlhbCgpIHsKKyAgbWl4ZWQgcmVzLGF0OworCisgIGlmIChtYXBwaW5ncChyZXM9UXVlcnkoUF9NQVRFUklBTCkpKQorICAgIHJldHVybiByZXM7CisgIGF0PVF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKTsKKyAgc3dpdGNoKGF0KSB7CisgICAgY2FzZSBBVF9BUk1PVVI6CisgICAgY2FzZSBBVF9IRUxNRVQ6CisgICAgY2FzZSBBVF9SSU5HOgorICAgIGNhc2UgQVRfQU1VTEVUOgorICAgIGNhc2UgQVRfU0hJRUxEOgorICAgIHJldHVybiAoW01BVF9NSVNDX01FVEFMOjEwMF0pOworICAgIGNhc2UgQVRfQ0xPQUs6CisgICAgY2FzZSBBVF9UUk9VU0VSUzoKKyAgICByZXR1cm4gKFtNQVRfQ0xPVEg6MTAwXSk7CisgICAgY2FzZSBBVF9HTE9WRToKKyAgICBjYXNlIEFUX0JPT1Q6CisgICAgcmV0dXJuIChbTUFUX0xFQVRIRVI6MTAwXSk7CisgIH0KKyAgcmV0dXJuIChbTUFUX0xFQVRIRVI6MTAwXSk7Cit9CmRpZmYgLS1naXQgYS9zdGQvYXJtb3VyL21vdmluZy5jIGIvc3RkL2FybW91ci9tb3ZpbmcuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZTU5OGE4Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2FybW91ci9tb3ZpbmcuYwpAQCAtMCwwICsxLDE4IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gYXJtb3VyL21vdmluZy5jIC0tIGFybW91ciBtb3Zpbmcgb2JqZWN0CisvLworLy8gJElkOiBtb3ZpbmcuYyA2MzA2IDIwMDctMDUtMjAgMTE6MzI6MDNaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisKKy8vIERpZXMgbXVzcyBlaWdlbnRsaWNoIG5peCB1ZWJlciBjbG90aGluZy9tb3ZpbmcgaGluYXVzZ2VoZW5kZXMga29lbm5lbi4KKy8vIERpZSBSdWVzdHVuZ2VuIGVyYmVuIGF1Y2ggYWxsZSBkaXJla3QgY2xvdGhpbmcvbW92aW5nLCBkaWVzZXMgRmlsZQorLy8gZXhpc3RpZXJ0IGVpZ2VudGxpY2ggbnVyIGZ1ZXIgZGVuIEZhbGwsIGRhc3MgTGV1dGUgYXVzc2VyaGFsYiB2b24gL3N0ZCB2b24KKy8vIGFybW91ci9tb3ZpbmcgZXJiZW4uCitpbmhlcml0ICIvc3RkL2Nsb3RoaW5nL21vdmluZyI7CisKZGlmZiAtLWdpdCBhL3N0ZC9hcm1vdXIvd2Vhci5jIGIvc3RkL2FybW91ci93ZWFyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmVmODdjNQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9hcm1vdXIvd2Vhci5jCkBAIC0wLDAgKzEsMjYwIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gYXJtb3VyL3dlYXIuYyAtLSBhcm1vdXIgc3RhbmRhcmQgb2JqZWN0CisvLworLy8gJElkOiBjb21iYXQuYyA2MjQzIDIwMDctMDMtMTUgMjE6MTA6MjFaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisKK2luaGVyaXQgIi9zdGQvY2xvdGhpbmcvd2VhciI7CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGl2aW5nL2NvbWJhdC5oPgorI2luY2x1ZGUgPGxpdmluZy9hdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8YXJtb3VyLmg+CisKKy8vIFVlYmVybmltbXQgdmllbGUgd2VzZW50bGljaGUgRWlnZW5zY2hhZnRlbiBhdXMgZGVyIEtsZWlkdW5nLCBkYWhlciB3ZXJkZW4KKy8vIGhpZXIgYXVjaCBudXIgZGl2LiBGdW5rdGlvbmVuIHVlYmVyc2NocmllYmVuLCBkaWUgc2ljaCBsZWljaHQKKy8vIHVudGVyc2NoaWVkbGljaCB6dXIgS2xlaWR1bmcgdmVyaGFsdGVuLgorCisvLyBHbG9iYWxlIFZhcmlhYmxlbgorcHJpdmF0ZSBub3NhdmUgaW50ICAgICBsb2dnZWQ7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIHsKKyAgOjpjcmVhdGUoKTsKKyAgLy8gUF9EQU1BR0VEIGxhZXNzdCBzaWNoIHp3YXIgKG5vY2gpIHZvbiBhdXNzZW4gc2V0emVuLCBhYmVyIGJpdHRlIG51ciB1ZWJlcgorICAvLyBkaWUgaGllciBkZWZpbmllcnRlIFNldG1ldGhvZGUuCisgIC8vIFRPRE86IERpcmVrdGVzIFNldHplbiB2b24gUF9EQU1BR0VEIGVudGZlcm5lbi4KKyAgU2V0KFBfREFNQUdFRCwgUFJPVEVDVEVELCBGX01PREVfQVMpOworfQorCisvKiBXZW5uIGVpbmUgUnVlc3R1bmcgdm9tIGdsZWljaGVuIFR5cCBpbSBBcnJheSBpc3QsIGdlYmUgZGllc2UgenVydWVjay4gKi8KK3ByaXZhdGUgb2JqZWN0IFRlc3RUeXBlKG9iamVjdCAqYXJtb3VycykgeworICAgIG1peGVkIHR5cGU7CisKKyAgICAvLyBEZW4gZWlnZW5lbiBUeXAgZmVzdHN0ZWxsZW4KKyAgICB0eXBlID0gUXVlcnlQcm9wKFBfQVJNT1VSX1RZUEUpOworCisgICAgLy8gWmVyc3RvZXJ0ZSBPYmpla3RlIGF1c3NvcnRpZXJlbgorICAgIGFybW91cnMtPSh7MH0pOworCisgICAgZm9yZWFjaChvYmplY3QgYXJtb3VyOiBhcm1vdXJzKQorICAgIHsKKyAgICAgIGlmICh0eXBlPT0oYXJtb3VyLT5RdWVyeVByb3AoUF9BUk1PVVJfVFlQRSkpKQorICAgICAgICB7CisgICAgICAgICAgICAvLyBSdWVzdHVuZyB2b20gZ2xlaWNoZW4gVHlwIGdlZnVuZGVuIC0+IHp1cnVlY2tnZWJlbgorICAgICAgICAgICAgcmV0dXJuIGFybW91cjsKKyAgICAgICAgfQorICAgIH0KKyAgICAvLyBLZWluZSBSdWVzdHVuZyB2b20gZ2xlaWNoZW4gVHlwIGdlZnVuZGVuLCBhbHNvIDAgenVydWVja2dlYmVuCisgICAgcmV0dXJuIDA7Cit9CisKKy8vIGxpZWZlcnQgMSB6dXJ1ZWNrLCB3ZW5uIGRlciBTcGllbGVyIGRpZSBydWVzdHVuZyBhbnppZWhlbiBkYXJmLCAwIHNvbnN0LgorcHJvdGVjdGVkIGludCBfY2hlY2tfd2Vhcl9yZXN0cmljdGlvbnMoaW50IHNpbGVudCwgaW50IGFsbCkgeworICBtaXhlZCAgIHR5cGUscmVzOworICBvYmplY3QgICphcm1vdXJzOworCisgIHR5cGUgPSBRdWVyeVByb3AoUF9BUk1PVVJfVFlQRSk7CisKKyAgLy8gRGFzIERvV2VhcigpIGRlciBLbGVpZHVuZyBwcnVlZnQgYXVmIGdlbnVlZ2VuZCBmcmVpZSBIYWVuZGUsCisgIC8vIHBydWVmdCBhYmVyIGRlbiBGYWxsIG5pY2h0IGFiLCBvYiBtYW4gaGllciBlaW4gU2NoaWxkIGhhdCwgd2FzIGxhdXQgUHJvcAorICAvLyB3ZW5pZ2VyIGFscyBlaW5lIEhhbmQgYmVsZWd0LiBEYWhlciBoaWVyIG5hY2hob2xlbiB1bmQga29ycmlnaWVyZW4uIFVuZAorICAvLyBkaXJla3QgbWFsIGxvZ2dlbiwgZGFtaXQgZGFzIGdlZml4dCB3aXJkLgorICBpZiAoICh0eXBlPT1BVF9TSElFTEQpICYmIFF1ZXJ5UHJvcChQX05SX0hBTkRTKTwxICkgeworICAgIFNldFByb3AoUF9OUl9IQU5EUywxKTsKKyAgICBsb2dfZmlsZSgiSU5WQUxJRF9TSElFTEQiLAorCXNwcmludGYoIkZpeG1lOiBBVF9TSElFTEQgaXRlbSB3aXRob3V0IHZhbGlkIFBfTlJfSEFORFM6ICVPXG4iLAorCSAgb2JqZWN0X25hbWUoKSkpOworICB9CisKKyAgYXJtb3Vycz0ob2JqZWN0KilQTC0+UXVlcnlQcm9wKFBfQVJNT1VSUykgLSAoezB9KTsKKworICAvLyBWb24gamVkZW0gUnVlc3R1bmdzdHlwIGF1c3NlciBBVF9NSVNDIGthbm4gbWFuIGltbWVyIG51ciBlaW4KKyAgLy8gVGVpbCB0cmFnZW4KKyAgaWYgKCAodHlwZSE9QVRfTUlTQykgJiYgKHJlcz1UZXN0VHlwZShhcm1vdXJzKSkgJiYgb2JqZWN0cChyZXMpKSB7CisgICAgbXNnKGJyZWFrX3N0cmluZyhzcHJpbnRmKAorCSAgIkR1IHRyYWVnc3QgYmVyZWl0cyAlcyBhbHMgU2NodXR6IGRlciBTb3J0ZSAlcy4iLAorCSAgcmVzLT5uYW1lKFdFTiwxKSwgdHlwZSksNzgsCisJICAoYWxsPyhOYW1lKFdFUikrIjogIik6MCkpLCBhbGwpOworICAgIHJldHVybigtMSk7CisgIH0KKworICAvLyBSdWVzdHVuZ2VuIHZvbSBUeXAgQVRfSUxMRUdBTCBvZGVyIHNvbGNoZSBtaXQgZWluZW0gZnVlciBpaHJlbgorICAvLyBSdWVzdHVuZ3N0eXAgenUgaG9oZW4gU2NodXR6d2VydCBrb2VubmVuIG5pY2h0IGFuZ2V6b2dlbiB3ZXJkZW4KKyAgaWYgKCAodHlwZT09QVRfSUxMRUdBTCkgfHwgKFF1ZXJ5UHJvcChQX0FDKT5WQUxJRF9BUk1PVVJfQ0xBU1NbdHlwZV0pKSB7CisgICAgd3JpdGUoIlVuZ3VlbHRpZ2VyIFJ1ZXN0dW5nc3R5cCwgYml0dGUgRXJ6bWFnaWVyIHZlcnN0YWVuZGlnZW4uXG4iKTsKKyAgICAgICAgIi9wL2RhZW1vbi9ydWVzdHVuZ2VuIi0+UmVnaXN0ZXJBcm1vdXIoKTsgICAgICAKKyAgICByZXR1cm4oLTIpOworICB9CisKKyAgLy8gUnVlc3R1bmdlbiwgZGllIGVpbiBvZGVyIG1laHJlcmUgQXR0cmlidXQgdmVyYWVuZGVybiB1bmQgZ2VnZW4KKyAgLy8gZGFzIGdlc2V0enRlIExpbWl0IHZlcnN0b3NzZW4sIGhhYmVuIGtlaW5lIFdpcmt1bmcgYmV6dWVnbGljaCBkZXIKKyAgLy8gQXR0cmlidXRlLiBEaWVzIGdpYnQgYWJlciBudXIgbmUgTWVsZHVuZyBhdXMsIGFuZ2V6b2dlbiB3ZXJkZW4gZGFyZiBzaWUKKyAgLy8gdHJvdHpkZW0uCisgIGlmIChtYXBwaW5ncChyZXM9UXVlcnlQcm9wKFBfTV9BVFRSX01PRCkpICYmIFBMLT5UZXN0TGltaXRWaW9sYXRpb24ocmVzKSApIHsKKyAgICB3cml0ZShicmVha19zdHJpbmcoc3ByaW50ZigKKyAgICAgICAgICAiSXJnZW5kZXR3YXMgYW4gRGVpbmVyIEF1c3J1ZXN0dW5nIHZlcmhpbmRlcnQsIGRhc3MgRHUgRGljaCBtaXQgIgorICAgICAgICAgICIlcyBzbyByaWNodGlnIHdvaGwgZnVlaGxzdC4iLG5hbWUoV0VNLDEpKSw3OCwKKyAgICAgICAgICAoYWxsPyhOYW1lKFdFUikrIjogIik6MCkpKTsKKyAgfQorCisgIC8vIGRhbm4gbWFsIGF1cyBkZXIgS2xlaWR1bmcgZ2VlcmJ0ZSBQcnVlZnVuZ2VuIGF1c2Z1ZWhyZW4gdW5kIEVyZ2VibmlzCisgIC8vIGxpZWZlcm4uCisgIHJldHVybiA6Ol9jaGVja193ZWFyX3Jlc3RyaWN0aW9ucyhzaWxlbnQsYWxsKTsKK30KKworcHJvdGVjdGVkIHZvaWQgX2luZm9ybXdlYXIoaW50IHNpbGVudCwgaW50IGFsbCkgeworCisgIC8vIFJ1ZXN0dW5nZW4ga29lbm5lbiBSZXNpc3RlbnplbiBiZWVpbmZsdXNzZW4KKyAgUEwtPkFkZFJlc2lzdGFuY2VNb2RpZmllcihRdWVyeVByb3AoUF9SRVNJU1RBTkNFX1NUUkVOR1RIUyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlQcm9wKFBfQVJNT1VSX1RZUEUpKTsKKworICAvLyBSdWVzdHVuZ2VuIGtvZW5uZW4gQXR0cmlidXRlIGFlbmRlcm4vYmxvY2tpZXJlbi4gQWxzbyBtdWVzc2VuIGRpZXNlCisgIC8vIG5hY2ggZGVtIEFuemllaGVuIGFrdHVhbGlzaWVydCB3ZXJkZW4KKyAgUEwtPnJlZ2lzdGVyX21vZGlmaWVyKE1FKTsKKyAgUEwtPlVwZGF0ZUF0dHJpYnV0ZXMoKTsKKworICAvLyBQX1RPVEFMX0FDIGltIFRyYWVnZXIgdXBkYXRlbiAoZnVlciBRdWVyeSgpcykKKyAgUEwtPlF1ZXJ5UHJvcChQX1RPVEFMX0FDKTsKKworICAvLyBBbGxlIFJ1ZXN0dW5nZW4gd2VyZGVuIGltIGF3bWFzdGVyIHJlZ2lzdHJpZXJ0LCBzb2JhbGQgc2llIHZvbgorICAvLyBlaW5lbSBTcGllbGVyIGdlenVlY2t0IHdlcmRlbgorICBpZiAoIWxvZ2dlZCAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKFBMKSkgeworICAgIGNhbGxfb3RoZXIoIi9zZWN1cmUvYXdtYXN0ZXIiLCJSZWdpc3RlckFybW91ciIsTUUpOworICAgIGxvZ2dlZD0xOworICB9CisgIC8vIG5vY2ggZGFzIGF1cyBkZXIgS2xlaWR1bmcgcnVmZW4sIGRhbWl0IGRpZSBBbnppZWhtZWxkdW5nZW4gYXVjaCBrb21tZW4uCisgIC8vIGF1c3NlcmRlbSBsYWV1ZnQgZGFzIEFuc3Rvc3NlcyB2b24gSW5mb3JtV2VhcigpIHZvbiBkb3J0LgorICA6Ol9pbmZvcm13ZWFyKHNpbGVudCxhbGwpOworfQorCisKK3Byb3RlY3RlZCBpbnQgX2NoZWNrX3Vud2Vhcl9yZXN0cmljdGlvbnMob2JqZWN0IHdvcm5fYnksIGludCBzaWxlbnQsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYWxsKSB7CisgIC8vIGxpZWZlcnQgPj0wIHp1cmVjaywgd2VubiBkaWUgS2xlaWR1bmcvUnVlc3R1bmcgYXVzZ2V6b2dlbiB3ZXJkZW4ga2FubiwgCisgIC8vIDwwIHNvbnN0LgorCisgIC8vIFNjaGlsZGUgYmVsZWdlbiAobWluZGVzdGVucykgZWluZSBIYW5kLiBIbmdsLiBXZW5uIG1hbiBkaWVzZW4gYmxvZWRlbgorICAvLyBDaGVjayBuaWNodCBtYWNoZW4gbXVlc3N0ZSwga29lbm50ZSBtYW4gc2ljaCBkaWUgZ2FuemUgRnVua3Rpb24gc3BhcmVuLgorICAvLyBIbXBmZ3JtcGZsLiBBY2hqYSwgcmFpc2VfZXJyb3IoKSwgd2VpbCBkYXMgZWlnZW50bGljaCBqYSBuaWNodCB2b3Jrb21tZW4KKyAgLy8gc29sbHRlIHVuZCBnZWZpeHQgd2VyZGVuIHNvbGwuIERhcyBnZWh0IG5hZW1saWNoIG51ciwgd2VubiBqZW1hbmQgZGllc2UKKyAgLy8gUHJvcCBnZWFlbmRlcnQsIHdhZWhyZW5kIGRlciBTcGllbGVyIGRhcyBTY2hpbGQgZ2V0cmFnZW4gaGF0dGUuCisgIGlmICggKFF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKT09QVRfU0hJRUxEKSAmJiAKKyAgICAgIFF1ZXJ5UHJvcChQX05SX0hBTkRTKTwxICkgeworICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIkZpeG1lOiBBVF9TSElFTEQgYmVpbSBBdXN6aWVoZW4gb2huZSBQX05SX0hBTkRTOiAlTyIsCisJICBvYmplY3RfbmFtZSgpKSk7CisgIH0KKyAgCisgIC8vIEF1c3ppZWhjaGVjayBkZXIgS2xlaWR1bmcgbWFjaGVuCisgIHJldHVybiA6Ol9jaGVja191bndlYXJfcmVzdHJpY3Rpb25zKHdvcm5fYnksc2lsZW50LGFsbCk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIF9pbmZvcm11bndlYXIob2JqZWN0IHdvcm5fYnksIGludCBzaWxlbnQsIGludCBhbGwpIHsKKyAgbWl4ZWQgcmVzOworICAvLyBHZXNldHp0ZSBSZXNpc3RlbnplbiBsb2VzY2hlbgorICB3b3JuX2J5LT5SZW1vdmVSZXNpc3RhbmNlTW9kaWZpZXIocmVzPVF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKSk7CisgIAorICAvLyBSdWVzdHVuZ2VuIGtvZW5uZW4gQXR0cmlidXRlIGFlbmRlcm4vYmxvY2tpZXJlbi4gQWxzbyBtdWVzc2VuIGRpZXNlCisgIC8vIG5hY2ggZGVtIEF1c3ppZWhlbiBha3R1YWxpc2llcnQgd2VyZGVuCisgIHdvcm5fYnktPmRlcmVnaXN0ZXJfbW9kaWZpZXJzKE1FKTsKKyAgd29ybl9ieS0+VXBkYXRlQXR0cmlidXRlcygpOworCisgIC8vIFBfVE9UQUxfQUMgaW0gVHJhZWdlciB1cGRhdGVuCisgIHdvcm5fYnktPlF1ZXJ5UHJvcChQX1RPVEFMX0FDKTsKKworICAvLyBkaWUgZ2VlcmJ0ZSBGdW5rdGlvbiBhdXMgZGVyIEtsZWluZHVuZyBnaWJ0IG5vY2ggbWVsZHVuZ2VuIGF1cyB1bmQgcnVmdAorICAvLyBJbmZvcm11bndlYXIoKS4KKyAgOjpfaW5mb3JtdW53ZWFyKHdvcm5fYnksc2lsZW50LGFsbCk7Cit9CisKKy8vIEZ1bmt0aW9uLCBkaWUgZGFzICJ0cmFnZSIvInppZWhlICogYW4iLUtvbW1hbmRvIGF1c3dlcnRldAordmFyYXJncyBpbnQgZG9fd2VhcihzdHJpbmcgc3RyLCBpbnQgc2lsZW50KSB7ICAKKyAgaW50IGFsbDsgIAorCisgIC8vIEhhdCBkZXIgU3BpZWxlciAidHJhZ2UgYWxsZXMiIGVpbmdlZ2ViZW4/CisgIGFsbD0oc3RyPT0iYWxsZXMiIHx8IHN0cj09ImFsbGUgcnVlc3R1bmdlbiIpOworICAKKyAgcmV0dXJuKF9kb193ZWFyKHN0cixzaWxlbnQsYWxsKSk7Cit9CisKKy8vIERpZSBGdW5rdGlvbiwgZGllIGRhcyAiemllaGUgKiBhdXMiLUtvbW1hbmRvIGF1c3dlcnRldAordmFyYXJncyBpbnQgZG9fdW53ZWFyKHN0cmluZyBzdHIsIGludCBzaWxlbnQpIHsKKyAgaW50IGFsbDsKKworICBhbGw9KHN0cj09ImFsbGVzIiB8fCBzdHI9PSJhbGxlIHJ1ZXN0dW5nZW4iKTsKKyAgcmV0dXJuKF9kb191bndlYXIoc3RyLHNpbGVudCxhbGwpKTsKK30KKworCisvLyBPYmpla3RlLCBkaWUgZGllIEJlc2NoYWVkaWd1bmcgZWluZXIgUnVlc3R1bmcgZHVyY2ggZGlyZWt0ZXMgU2V0emVuIHZvbgorLy8gUF9EQU1BR0VEIGR1cmNoZnVlaHJlbiwgd2VyZGVuIGltIGF3bWFzdGVyIGdlbG9nZ3QKK3N0YXRpYyBtaXhlZCBfc2V0X2l0ZW1fZGFtYWdlZChtaXhlZCBhcmcpIHsKKyAgICBpZiAoYXJnICYmICFpbnRwKGFyZykpCisgICAgeworICAgICAgICByZXR1cm4gUXVlcnkoUF9EQU1BR0VELCBGX1ZBTFVFKTsKKyAgICB9CisKKyAgICBpZiAocHJldmlvdXNfb2JqZWN0KDEpKQorICAgICAgY2FsbF9vdGhlcigiL3NlY3VyZS9hd21hc3RlciIsIlJlZ2lzdGVyRGFtYWdlciIsCisgICAgICAgICAgICBwcmV2aW91c19vYmplY3QoMSksUXVlcnlQcm9wKFBfREFNQUdFRCksYXJnKTsgCisKKyAgICByZXR1cm4gU2V0KFBfREFNQUdFRCwgYXJnLCBGX1ZBTFVFKTsKK30KKworLy8gV2lsbCBtYW4gZWluZSBSdWVzdHVuZyBiZXNjaGFlZGlnZW4gb2RlciByZXBhcmllcmVuLCBzbyBtYWNodCBtYW4gZGFzCisvLyBhbSBiZXN0ZW4gdWViZXIgZGllIEZ1bmt0aW9uIERhbWFnZShhcmd1bWVudCkuIFBvc2l0aXZlIEFyZ3VtZW50ZQorLy8gYmVkZXV0ZW4gZWluZSBCZXNjaGFlZGlndW5nLCBuZWdhdGl2ZSBlaW5lIFJlcGFyYXR1ci4gRGVyIFJ1ZWNrZ2FiZXdlcnQKKy8vIGlzdCBkaWUgd2lya2xpY2ggZHVyY2hnZWZ1ZWhydGUgQWVuZGVydW5nIGRlcyBCZXNjaGFlZGlndW5nc3dlcnRlcworaW50IERhbWFnZShpbnQgbmV3X2RhbSkgeyAgIAorICBpbnQgICAgYWMsbWF4aW11bSxvbGRfZGFtOworICBvYmplY3QgdzsKKworICBpZiAoIW5ld19kYW0gfHwgIWludHAobmV3X2RhbSkpIHsgICAgICAKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIGlmICggKGFjPVF1ZXJ5UHJvcChQX0FDKSk8PTAgJiYgKG5ld19kYW0+MCkgKSB7CisgICAgLy8gU29uc3Qgd3VlcmRlIEJlc2NoYWVkaWd1bmcgenVyIFJlcGFyYXR1ciBmdWVocmVuCisgICAgcmV0dXJuIDA7CisgIH0KKworICAvLyBNaW4tQUMgdW5kIE1BWF9BQyBiZWFjaHRlbgorICBpZiAoKGFjLW5ld19kYW0pIDwgTUlOX0FSTU9VUl9DTEFTUykgeyAgICAgIAorICAgIG5ld19kYW0gPSBhYy1NSU5fQVJNT1VSX0NMQVNTOworICB9CisgIGVsc2UgaWYgKChhYy1uZXdfZGFtKSA+CisgICAgKG1heGltdW09VkFMSURfQVJNT1VSX0NMQVNTW1F1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKV0pKSB7ICAgICAgCisgICAgbmV3X2RhbSA9IGFjLW1heGltdW07CisgIH0KKworICAvLyBOaWUgbWVociBhbHMgMTAwJSByZXBhcmllcmVuCisgIGlmICggKChvbGRfZGFtPVF1ZXJ5UHJvcChQX0RBTUFHRUQpKTwtbmV3X2RhbSkgJiYgKG5ld19kYW08MCkgKSB7CisgICAgbmV3X2RhbT0tb2xkX2RhbTsKKyAgfQorCisgIC8vIEFlbmRlcnVuZ2VuIGFuIGRlciBSdWVzdHVuZ3NrbGFzc2UgdW5kIGRlbSBCZXNjaGFlZGlndW5nc3dlcnQKKyAgLy8gZHVyY2hmdWVocmVuCisgIFNldFByb3AoUF9BQywoYWMtbmV3X2RhbSkpOworICAvLyBlaWdlbmUgU2V0LU1ldGhvZGUgdW1nZWhlbgorICBTZXQoUF9EQU1BR0VELChvbGRfZGFtK25ld19kYW0pLEZfVkFMVUUpOworCisgIC8vIFBfVE9UQUxfQUMgaW0gVHJhZWdlciB1cGRhdGVuLCB3ZW5uIHZvcmhhbmRlbgorICBpZiAob2JqZWN0cCh3PVF1ZXJ5UHJvcChQX1dPUk4pKSkKKyAgICB3LT5RdWVyeVByb3AoUF9UT1RBTF9BQyk7CisKKyAgLy8gUnVlY2tnYWJld2VydDogRHVyY2hnZWZ1ZWhydGUgQWVuZGVydW5nIGFuIFBfREFNQUdFCisgIHJldHVybiBuZXdfZGFtOworfQorCitwdWJsaWMgc3RhdHVzIElzQXJtb3VyKCkge3JldHVybiAxO30KK3B1YmxpYyBzdGF0dXMgSXNDbG90aGluZygpIHtyZXR1cm4gMDt9CisKZGlmZiAtLWdpdCBhL3N0ZC9hcm1vdXJIRy5jIGIvc3RkL2FybW91ckhHLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzUyZTc1YwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9hcm1vdXJIRy5jCkBAIC0wLDAgKzEsNTkgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBhcm1vdXJIRy5jIC0tIGFybW91ciBzdGFuZGFyZCBvYmplY3QgZm9yIGhhdHMgYW5kIGdsYXNzZXMKKy8vCisvLyAkSWQ6IGFybW91ckhHLmMgNzgwNCAyMDExLTA3LTEwIDIwOjM3OjUyWiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCitpbmhlcml0ICIvc3RkL2FybW91ciI7CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvY29tbWFuZHMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorCitpbnQgc2V0emVuKHN0cmluZyBzKTsKKwordm9pZCBjcmVhdGUoKSB7CisgICAgOjpjcmVhdGUoKTsKKyAgICBBZGRDbWQoKHsic2V0eiIsInNldHplIn0pLCJzZXR6ZW4iKTsKK30KKwordmFyYXJncyB2b2lkIGRvV2Vhck1lc3NhZ2UoIGludCBhbGwgKSB7CisgIGlmKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKFBMKSApIHsKKyAgICB3cml0ZSggIkR1IHNldHp0ICIgKyBuYW1lKFdFTiwxKSArICIgYXVmLlxuIiApOworICB9CisgIGlmIChvYmplY3RwKGVudmlyb25tZW50KCkpICYmIG9iamVjdHAoZW52aXJvbm1lbnQoZW52aXJvbm1lbnQoKSkpKQorICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSwKKwljYXBpdGFsaXplKChzdHJpbmcpUEwtPm5hbWUoV0VSKSkgKyAiIHNldHp0ICIgKyBuYW1lKFdFTiwwKSArIAorCSIgYXVmLlxuIik7Cit9CisKK3ZhcmFyZ3Mgdm9pZCBkb1Vud2Vhck1lc3NhZ2UoIG9iamVjdCB3b3JuX2J5LCBpbnQgYWxsICkgeworICBpZiggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh3b3JuX2J5KSApIHsKKyAgICB0ZWxsX29iamVjdCh3b3JuX2J5LCAgIkR1IHNldHp0ICIgKyBuYW1lKFdFTiwxKSArICIgYWIuXG4iICk7CisgIH0KKyAgdGVsbF9yb29tKGVudmlyb25tZW50KHdvcm5fYnkpLCAKKwkgICAgKGNhcGl0YWxpemUoKHN0cmluZyl3b3JuX2J5LT5uYW1lKFdFUikpKSArICIgc2V0enQgIiArCisJICAgIG5hbWUoV0VOLDApICsgIiBhYi5cbiIsICh7d29ybl9ieX0pKTsKK30KKworaW50IHNldHplbihzdHJpbmcgc3RyKSB7CisgIHN0cmluZyBvYjsKKworICBpZighc3RyKQorICAgIHJldHVybiAwOworICBpZihzc2NhbmYoc3RyLCAiJXMgYXVmIiwgb2IpPT0xICkKKyAgICByZXR1cm4gX2RvX3dlYXIob2IsIDAsIDApOworICBpZihzc2NhbmYoc3RyLCAiJXMgYWIiLCBvYik9PTEgKQorICAgIHJldHVybiBfZG9fdW53ZWFyKG9iLCAwLCAwKTsKKyAgcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9hcm1vdXJfY29udGFpbmVyLmMgYi9zdGQvYXJtb3VyX2NvbnRhaW5lci5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdlYTIyZDIKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvYXJtb3VyX2NvbnRhaW5lci5jCkBAIC0wLDAgKzEsNTQgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vLAorLy8gYXJtb3VyX2NvbnRhaW5lci5jIC0tIFJ1ZXN0dW5nLCBpbiBkaWUgbWFuIHdhcyByZWluc3RlY2tlbiBrYW5uCisvLworLy8gJElkOiBhcm1vdXJfY29udGFpbmVyLmMgNzgwNCAyMDExLTA3LTEwIDIwOjM3OjUyWiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCitpbmhlcml0ICIvc3RkL3RoaW5nL3Byb3BlcnRpZXMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9jb21tYW5kcyI7Citpbmhlcml0ICIvc3RkL3RoaW5nL2xhbmd1YWdlIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvZW52Y2hrIjsKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL2xpZ2h0IjsKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL3Jlc3RyaWN0aW9ucyI7Citpbmhlcml0ICIvc3RkL2NvbnRhaW5lci9pbnZlbnRvcnkiOworaW5oZXJpdCAiL3N0ZC9jb250YWluZXIvaXRlbXMiOworaW5oZXJpdCAiL3N0ZC9jbG90aGluZy9tb3ZpbmciOworaW5oZXJpdCAiL3N0ZC9hcm1vdXIvd2VhciI7Citpbmhlcml0ICIvc3RkL2FybW91ci9jb21iYXQiOworaW5oZXJpdCAiL3N0ZC9hcm1vdXIvY29udGFpbmVyX2Rlc2NyaXB0aW9uIjsKKworLy8jZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8Y29udGFpbmVyLmg+CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIHsKKyAgcHJvcGVydGllczo6Y3JlYXRlKCk7CisgIGNvbW1hbmRzOjpjcmVhdGUoKTsKKyAgbGlnaHQ6OmNyZWF0ZSgpOworICBjb250YWluZXJfZGVzY3JpcHRpb246OmNyZWF0ZSgpOworICByZXN0cmljdGlvbnM6OmNyZWF0ZSgpOworICBpdGVtczo6Y3JlYXRlKCk7CisgIHdlYXI6OmNyZWF0ZSgpOworICBjb21iYXQ6OmNyZWF0ZSgpOworICBlbnZjaGs6OmNyZWF0ZSgpOworICBTZXRQcm9wKFBfQ09OVEFJTkVSLDEpOworICBTZXRQcm9wKFBfUFJFUE9TSVRJT04sICJpbiIpOworICBTZXRQcm9wKFBfU09VUkNFX1BSRVBPU0lUSU9OLCAiYXVzIik7CisgIFNldFByb3AoUF9ERVNUX1BSRVBPU0lUSU9OLCAiaW4iKTsKKyAgQWRkSWQoIkRpbmciKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3ZvaWQgcmVzZXQoKSAgeworICBpdGVtczo6cmVzZXQoKTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2Nsb3RoaW5nLmMgYi9zdGQvY2xvdGhpbmcuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDI1OTg0Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2Nsb3RoaW5nLmMKQEAgLTAsMCArMSw1NCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGFybW91ci5jIC0tIGFybW91ciBzdGFuZGFyZCBvYmplY3QKKy8vCisvLyAkSWQ6IGFybW91ci5jLHYgMy44IDIwMDMvMDgvMjUgMDk6MzY6MDQgUmlrdXMgRXhwICQKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL3RoaW5nL3Byb3BlcnRpZXMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9jb21tYW5kcyI7Citpbmhlcml0ICIvc3RkL3RoaW5nL3Jlc3RyaWN0aW9ucyI7Citpbmhlcml0ICIvc3RkL3RoaW5nL2xpZ2h0IjsKK2luaGVyaXQgIi9zdGQvY2xvdGhpbmcvZGVzY3JpcHRpb24iOworaW5oZXJpdCAiL3N0ZC9jbG90aGluZy9tb3ZpbmciOworaW5oZXJpdCAiL3N0ZC9jbG90aGluZy93ZWFyIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvbGFuZ3VhZ2UiOworaW5oZXJpdCAiL3N0ZC90aGluZy9lbnZjaGsiOworCisvLyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxjb25maWcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxjb21iYXQuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIHByb3BlcnRpZXM6OmNyZWF0ZSgpOworICBjb21tYW5kczo6Y3JlYXRlKCk7CisgIGxpZ2h0OjpjcmVhdGUoKTsKKyAgcmVzdHJpY3Rpb25zOjpjcmVhdGUoKTsKKyAgZGVzY3JpcHRpb246OmNyZWF0ZSgpOworICB3ZWFyOjpjcmVhdGUoKTsKKyAgZW52Y2hrOjpjcmVhdGUoKTsKKyAgQWRkSWQoIkRpbmciKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKKy8vIHp1bSBVZWJlcnNjaHJlaWJlbiwgZGFtaXQgZXMgbmljaHQgYnVnZ3QsIHdlbm4gTGV1dGUgKHdpZSBnZXd1ZW5zY2h0KSBpbiAKKy8vIGlocmVuIE9iamVrdGVuIDo6cmVzZXQoKSBhdWZydWZlbi4KK3ZvaWQgcmVzZXQoKSB7Cit9CisKK2ludCBJc0Nsb3RoaW5nKCkge3JldHVybiAxO30KKwpkaWZmIC0tZ2l0IGEvc3RkL2Nsb3RoaW5nL2NvbnRhaW5lcl9kZXNjcmlwdGlvbi5jIGIvc3RkL2Nsb3RoaW5nL2NvbnRhaW5lcl9kZXNjcmlwdGlvbi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY3OTQyYmMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvY2xvdGhpbmcvY29udGFpbmVyX2Rlc2NyaXB0aW9uLmMKQEAgLTAsMCArMSwxMzcgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBjbG90aGluZy9jb250YWluZXJfZGVzY3JpcHRpb24uYyAtLSBjbG90aGluZ19jb250YWluZXIgZGVzY3JpcHRpb24gaGFuZGxpbmcKKy8vCisvLyAkSWQ6IGNvbnRhaW5lcl9kZXNjcmlwdGlvbi5jIDYxOTggMjAwNy0wMi0xMyAyMzozOTo0M1ogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworaW5oZXJpdCAiL3N0ZC90aGluZy9kZXNjcmlwdGlvbiI7CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKyNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgorI2luY2x1ZGUgPGNvbnRhaW5lci5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPHRoaW5nL21hdGVyaWFsLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPHBsYXllci9iYXNlLmg+CisKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgOjpjcmVhdGUoKTsKKyAgU2V0UHJvcChQX1RSQU5TUEFSRU5ULCAxKTsKKyAgQWRkSWQoIkNvbnRhaW5lciIpOworfQorCitzdHJpbmcgZGFtX2Rlc2NyKCkKK3sgICBzdHJpbmcgcmU7CisgICAgbWl4ZWQgZGVzYzsKKyAgICBpbnQgbWF4aW11bSxkYW0scG9zOworCisgICAgaWYgKCFRdWVyeVByb3AoUF9OQU1FKSB8fCAhUXVlcnlQcm9wKFBfREFNQUdFRCkgfHwgIVF1ZXJ5UHJvcChQX1NIT1JUKSB8fAorICAgICAgICAhKGRlc2M9UXVlcnlQcm9wKFBfREFNX0RFU0MpKSB8fCAoIXN0cmluZ3AoZGVzYykgJiYgIXBvaW50ZXJwKGRlc2MpKSkKKyAgICAgICAgcmV0dXJuICIiOworICAgIHJlID0gY2FwaXRhbGl6ZShuYW1lKFdFUiwyKSkrIiAiOworICAgIG1heGltdW0gPSBRdWVyeVByb3AoUF9BQykrKGRhbT1RdWVyeVByb3AoUF9EQU1BR0VEKSk7CisgICAgaWYgKHN0cmluZ3AoZGVzYykpCisgICAgICAgIHJldHVybiAoZGFtPihtYXhpbXVtLzIpKT8ocmUrZGVzYysiLlxuIik6IiI7CisgICAgcG9zID0gKHNpemVvZihkZXNjKSpkYW0vbWF4aW11bSk7CisgICAgaWYgKHN0cmluZ3AoZGVzY1twb3NdKSkKKyAgICAgICAgcmV0dXJuIChyZStkZXNjW3Bvc10rIi5cbiIpOworICAgIHJldHVybiAiIjsKK30KKworc3RyaW5nIHNob3J0KCkKK3sgICBzdHJpbmcgczsKKyAgICBpZighKHM9cHJvY2Vzc19zdHJpbmcoUXVlcnlQcm9wKFBfU0hPUlQpKSkpCisgICAgICAgIHJldHVybiAwOworICAgIHJldHVybiBzKyhRdWVyeVByb3AoUF9XT1JOKT8iIChhbmdlem9nZW4pLlxuIjoiLlxuIik7Cit9CisKK3ZhcmFyZ3Mgc3RyaW5nIGxvbmcoaW50IG1vZGUpCit7ICAgc3RyaW5nIGRlc2NyLCBpbnZfZGVzY3I7CisKKyAgICBkZXNjcj0ocHJvY2Vzc19zdHJpbmcoUXVlcnlQcm9wKFBfTE9ORyl8fCIiKSArIChkYW1fZGVzY3IoKXx8IiIpKTsKKyAgICBpZiAoIVF1ZXJ5UHJvcChQX1RSQU5TUEFSRU5UKSkKKyAgICAgIHJldHVybiBkZXNjcjsKKworICAgIGludl9kZXNjciA9IG1ha2VfaW52bGlzdChQTCwgYWxsX2ludmVudG9yeShNRSksIG1vZGUgKTsKKyAgICBpZiAoIGludl9kZXNjciAhPSAiIiApCisgICAgICAgIGRlc2NyICs9IGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpICsgIiBlbnRoYWVsdDpcbiIgKyBpbnZfZGVzY3I7CisgICAgcmV0dXJuIGRlc2NyOworfQorCittYXBwaW5nIF9xdWVyeV9tYXRlcmlhbCgpIHsKKyAgbWl4ZWQgcmVzLGF0OworCisgIGlmIChtYXBwaW5ncChyZXM9UXVlcnkoUF9NQVRFUklBTCkpKQorICAgIHJldHVybiByZXM7CisgIGF0PVF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKTsKKyAgc3dpdGNoKGF0KSB7CisgICAgY2FzZSBBVF9BUk1PVVI6CisgICAgY2FzZSBBVF9IRUxNRVQ6CisgICAgY2FzZSBBVF9SSU5HOgorICAgIGNhc2UgQVRfQU1VTEVUOgorICAgIGNhc2UgQVRfU0hJRUxEOgorICAgIHJldHVybiAoW01BVF9NSVNDX01FVEFMOjEwMF0pOworICAgIGNhc2UgQVRfQ0xPQUs6CisgICAgY2FzZSBBVF9UUk9VU0VSUzoKKyAgICByZXR1cm4gKFtNQVRfQ0xPVEg6MTAwXSk7CisgICAgY2FzZSBBVF9HTE9WRToKKyAgICBjYXNlIEFUX0JPT1Q6CisgICAgcmV0dXJuIChbTUFUX0NMT1RIOjEwMF0pOworICB9CisgIHJldHVybiAoW01BVF9DTE9USDoxMDBdKTsKK30KKworLy8gZmxhZ3M6IDEgLSB3aXphcmQsIDIgLSBkb24ndCBjb2xsZWN0IGVxdWFsIG9iamVjdHMgJworLy8gZmxhZ3M6IDQgLSBkb24ndCBhcHBlbmQgaW5mb3MgZm9yIHdpemFyZHMKK3ByaXZhdGUgdm9pZCBzdHJpbmdlbml6ZShtaXhlZCBvYmosIGludCBmbGFncywgbWl4ZWQgb2JqcywgbWl4ZWQgaW5mbykKK3sKKyAgc3RyaW5nIGlkLCB0bXA7CisgIGludCBpZHg7CisgIHRtcCA9IGNhcGl0YWxpemUob2JqLT5zaG9ydCgpfHwiIilbMC4uPDJdCisgICAgICArICghKGZsYWdzICYgNCkgJiYgKGZsYWdzICYgMSkgPyAiIFsiK29iamVjdF9uYW1lKG9iaikrIl0iIDogIiIpOworICBpZihmbGFncyAmIDMgfHwgbGl2aW5nKG9iaikpIGlkID0gb2JqZWN0X25hbWUob2JqKTsKKyAgZWxzZQorICAgIGlkID0gZXhwbG9kZShvYmplY3RfbmFtZShvYmopLCAiIyIpWzBdICsgdG1wOworICBpZigoaWR4ID0gbWVtYmVyKG9ianMsIGlkKSkgPT0gLTEpCisgIHsKKyAgICBvYmpzICs9ICh7IGlkIH0pOworICAgIGluZm8gKz0gKHsgKHsgdG1wLCAxLCBvYmp9KSB9KTsKKyAgfQorICBlbHNlCisgICAgaW5mb1tpZHhdWzFdKys7Cit9CisKK3ByaXZhdGUgc3RyaW5nIGNvbGxlY3QobWl4ZWQgb2JqKQoreworICBpZighc2l6ZW9mKG9ialswXSkpIHJldHVybiAwOworICByZXR1cm4gb2JqWzBdICsgKG9ialsxXSA+IDEgPyAiICgiK29ialsxXSsiKSIgOiAiIik7Cit9CisKKy8vIGZsYWdzOiAxIC0gcmV0dXJuIGFycmF5LCAyIC0gZG9uJ3QgY29sbGVjdCBlcXVhbCBvYmplY3RzICcKKy8vIGZsYWdzOiA0IC0gZG9uJ3QgYXBwZW5kIGluZm9zIGZvciB3aXphcmRzCit2YXJhcmdzIG1peGVkIG1ha2VfaW52bGlzdChvYmplY3Qgdmlld2VyLCBtaXhlZCBpbnYsIGludCBmbGFncykKK3sKKyAgaW50IGlzd2l6OworICBtaXhlZCBvYmpzLCBpbmZvOworICBzdHJpbmcgZGVzY3I7CisKKyAgaXN3aXogPSBJU19MRUFSTkVSKCB2aWV3ZXIgKSAmJiB2aWV3ZXItPlF1ZXJ5UHJvcChQX1dBTlRTX1RPX0xFQVJOKTsKKyAgZGVzY3IgPSAiIjsgb2JqcyA9ICh7fSk7IGluZm8gPSAoe30pOworICBtYXAoaW52LCAjJ3N0cmluZ2VuaXplLyonKi8sIGlzd2l6IHwgKGZsYWdzICYgMikgfCAoZmxhZ3MgJiA0KSwgJm9ianMsICZpbmZvKTsKKyAgaWYoZmxhZ3MgJiAxKSByZXR1cm4gaW5mbzsKKyAgaW52ID0gbWFwKGluZm8sICMnY29sbGVjdC8qJyovKSAtICh7IDAgfSk7CisgIGlmKCFzaXplb2YoaW52KSkgcmV0dXJuICIiOworICByZXR1cm4gc3ByaW50ZigiJSIrKHNpemVvZihpbnYpID4gNiA/ICIjIiA6ICI9IikrIi03OHMiLAorICAgICAgICAgICAgICAgICBpbXBsb2RlKGludiwgIlxuIikpICsgIlxuIjsKK30KZGlmZiAtLWdpdCBhL3N0ZC9jbG90aGluZy9kZXNjcmlwdGlvbi5jIGIvc3RkL2Nsb3RoaW5nL2Rlc2NyaXB0aW9uLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmEyMjZmZAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9jbG90aGluZy9kZXNjcmlwdGlvbi5jCkBAIC0wLDAgKzEsNTggQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBhcm1vdXIvZGVzY3JpcHRpb24uYyAtLSBhcm1vdXIgZGVzY3JpcHRpb24gaGFuZGxpbmcKKy8vCisvLyAkSWQ6IGRlc2NyaXB0aW9uLmMsdiAxLjcgMjAwMi8wOC8xOSAxNDoyMTowNCBSaWt1cyBFeHAgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIHdhcm5fZW1wdHlfY2FzdHMKKworaW5oZXJpdCAiL3N0ZC90aGluZy9kZXNjcmlwdGlvbiI7CisKKy8vI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKworc3RyaW5nIGRhbV9kZXNjcigpIHsKKyAgcmV0dXJuICIiOworfQorCitzdHJpbmcgc2hvcnQoKQoreyAgIHN0cmluZyBzOworICAgIGlmKCEocz1wcm9jZXNzX3N0cmluZyhRdWVyeVByb3AoUF9TSE9SVCkpKSkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgcmV0dXJuIHMrKFF1ZXJ5UHJvcChQX1dPUk4pPyIgKGFuZ2V6b2dlbikuXG4iOiIuXG4iKTsKK30KKwordmFyYXJncyBzdHJpbmcgbG9uZygpCit7ICAgCisgICAgcmV0dXJuIChwcm9jZXNzX3N0cmluZyhRdWVyeVByb3AoUF9MT05HKXx8IiIpICsgKGRhbV9kZXNjcigpfHwiIikpOworfQorCittYXBwaW5nIF9xdWVyeV9tYXRlcmlhbCgpIHsKKyAgbWl4ZWQgcmVzLGF0OworCisgIGlmIChtYXBwaW5ncChyZXM9UXVlcnkoUF9NQVRFUklBTCkpKQorICAgcmV0dXJuIHJlczsKKyAgYXQ9UXVlcnlQcm9wKFBfQVJNT1VSX1RZUEUpOworICBzd2l0Y2goYXQpIHsKKyAgICBjYXNlIEFUX0FSTU9VUjoKKyAgICBjYXNlIEFUX0hFTE1FVDoKKyAgICBjYXNlIEFUX1JJTkc6CisgICAgY2FzZSBBVF9BTVVMRVQ6CisgICAgY2FzZSBBVF9TSElFTEQ6CisgICAgcmV0dXJuIChbTUFUX01JU0NfTUVUQUw6MTAwXSk7CisgICAgY2FzZSBBVF9DTE9BSzoKKyAgICBjYXNlIEFUX1RST1VTRVJTOgorICAgIHJldHVybiAoW01BVF9DTE9USDoxMDBdKTsKKyAgICBjYXNlIEFUX0dMT1ZFOgorICAgIGNhc2UgQVRfQk9PVDoKKyAgICByZXR1cm4gKFtNQVRfTEVBVEhFUjoxMDBdKTsKKyAgfQorICByZXR1cm4gKFtNQVRfQ0xPVEg6MTAwXSk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9jbG90aGluZy9tb3ZpbmcuYyBiL3N0ZC9jbG90aGluZy9tb3ZpbmcuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYTJlMDVmCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2Nsb3RoaW5nL21vdmluZy5jCkBAIC0wLDAgKzEsNDYgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBhcm1vdXIvbW92aW5nLmMgLS0gYXJtb3VyIG1vdmluZyBvYmplY3QKKy8vCisvLyAkSWQ6IG1vdmluZy5jLHYgMy4zIDE5OTgvMDMvMDIgMDg6MzQ6NTcgUGFyYWNlbHN1cyBFeHAgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisKK2luaGVyaXQgIi9zdGQvdGhpbmcvbW92aW5nIjsKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMgMQorCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8Y2xvdGhpbmcuaD4KKworLyogQmVrbGVpZHVuZyBtdXNzIHZvciBCZXdlZ3VuZyB1bmQgWmVyc3RvZXJ1bmcgYXVzZ2V6b2dlbiB3ZXJkZW4gKi8KKwordmFyYXJncyBpbnQgbW92ZShtaXhlZCBkZXN0LCBpbnQgbWV0aG9kICkgeworICAvLyBnZ2YuIEF1c3ppZWhlbgorICBpZiAob2JqZWN0cChRdWVyeVByb3AoUF9XT1JOKSkpCisgICAgRG9VbndlYXIobWV0aG9kICYgKE1fU0lMRU5UfE1fTk9DSEVDSykpOworCisgIGlmICgobWV0aG9kJk1fTk9DSEVDSykgfHwgKCEob2JqZWN0KVF1ZXJ5UHJvcChQX1dPUk4pKSkKKyAgICByZXR1cm4gOjptb3ZlKGRlc3QsIG1ldGhvZCk7CisKKyAgcmV0dXJuIE1FX0NBTlRfQkVfRFJPUFBFRDsKK30KKwordmFyYXJncyBpbnQgcmVtb3ZlKGludCBzaWxlbnQpIHsKKyAgLy8gZ2dmLiBBdXN6aWVoZW4KKyAgaWYgKG9iamVjdHAoUXVlcnlQcm9wKFBfV09STikpKQorICAgIERvVW53ZWFyKE1fU0lMRU5UfE1fTk9DSEVDSyk7CisKKyAgaWYgKCEob2JqZWN0KVF1ZXJ5UHJvcChQX1dPUk4pKQorICAgIHJldHVybiA6OnJlbW92ZShzaWxlbnQpOworICAvLyBBdXN6aWVoZW4gaGF0IGlyZ2VuZHdpZSBuaWNodCBnZWtsYXBwdC4gOi0oCisgIHJldHVybiAwOworfQorCmRpZmYgLS1naXQgYS9zdGQvY2xvdGhpbmcvd2Vhci5jIGIvc3RkL2Nsb3RoaW5nL3dlYXIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kY2RlNGJkCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2Nsb3RoaW5nL3dlYXIuYwpAQCAtMCwwICsxLDU5NCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGNsb3RoaW5nL3dlYXIuYyAtLSBGdW5rdGlvbmVuIHJ1bmQgdW1zIEFuemllaGVuL1RyYWdlbiB2b24gS2xlaWR1bmcuCisvLworLy8gJElkOiBjb21iYXQuYyA2MjQzIDIwMDctMDMtMTUgMjE6MTA6MjFaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8dGhpbmcvY29tbWFuZHMuaD4KKyNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPGxpdmluZy9jbG90aGluZy5oPgorI2luY2x1ZGUgPGNsb3RoaW5nLmg+CisjaW5jbHVkZSA8bGl2aW5nL2NvbWJhdC5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKworLy8gR2xvYmFsZSBWYXJpYWJsZW4KK25vc2F2ZSBpbnQgIGZsYXcsIGZ0aW1lOworCit2b2lkIGNyZWF0ZSgpCit7CisgIC8vIEVpbmlnZSBQcm9wZXJ0aWVzIHNvbGx0ZW4gbmljaHQgdm9uIGF1c3NlbiBnZXNldHp0IHdlcmRlbiBrb2VubmVuCisgIFNldChQX1dPUk4sIFBST1RFQ1RFRCwgRl9NT0RFKTsKKyAgU2V0KFBfTEFTVF9VU0UsIFBST1RFQ1RFRCwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfUkVTVFJJQ1RJT05TLChbXSksRl9WQUxVRSk7CisKKyAgLy8gQmVrbGVpZHVuZyBiZW5vZXRpZ3QgS29tbWFuZG9zLCBtaXQgZGVuZW4gbWFuIHNpZSBhbi0gdW5kCisgIC8vIGF1c3ppZWhlbiBrYW5uCisgIEFkZENtZCggKHsiemllaCIsInppZWhlIn0pLCJ6aWVoZSIgKTsKKyAgQWRkQ21kKCAoeyJ0cmFnIiwidHJhZ2UifSksImRvX3dlYXIiICk7Cit9CisKKy8vIGFrdHVlbGxlcyBMZWJld2VzZW4sIHdhcyBkaWVzZSBLbGVpZHVuZyAob2RlciBhdWNoIFJ1ZXN0dW5nKSB6dXIgWmVpdAorLy8gdHJhZWd0LgorcHVibGljIG9iamVjdCBRdWVyeVVzZXIoKQoreworICByZXR1cm4gUXVlcnlQcm9wKFBfV09STik7Cit9CisKKworLy8gQXVzZ2FiZSB2b24gTWVsZHVuZ2VuIHVlYmVyIHdyaXRlKCkgb2RlciBfbm90aWZ5X2ZhaWwoKSwgamUgbmFjaGRlbSwgb2IgZGVyCisvLyBTcGllbGVyIGFsbGVzIGFuemllaHQgb2RlciB3YXMgYmVzdGltbXRlcy4KK3Byb3RlY3RlZCB2b2lkIG1zZyhzdHJpbmcgc3RyLCBtaXhlZCBmbCkgeworICBpZiAoIXN0cmluZ3Aoc3RyKSkgeworICAgIHJldHVybjsKKyAgfQorICBpZiAoZmwpIHsKKyAgICB3cml0ZShzdHIpOworICB9CisgIGVsc2UgeworICAgIF9ub3RpZnlfZmFpbChzdHIpOworICB9Cit9CisKKy8qCisgKiBBdXNnYWJlIGVpbmVyIE1lbGR1bmcgYmVpbSBBbnppZWhlbiBnZWh0IG51ciBhbiBTcGllbGVyLCBuaWNodCBhbiBOUEMuCisgKiBEaWUgVW1nZWJ1bmcgYmVrb21tdCBpbW1lciBlaW5lIE1lbGR1bmcuCisgKi8KK3ZhcmFyZ3Mgdm9pZCBkb1dlYXJNZXNzYWdlKGludCBhbGwpIHsKKyAgc3RyaW5nICpzdHIsczE7CisgIG1peGVkIHdlYXJtc2c7CisKKyAgaWYod2Vhcm1zZz1RdWVyeVByb3AoUF9XRUFSX01TRykpIHsgLy8gSXN0IGVpbmUgV2Vhck1zZyBnZXNldHp0PworICAgIGlmKGNsb3N1cmVwKHdlYXJtc2cpKSB7IC8vIEV2dGwuIGdhciBhbHMgZXh0cmEgRmt0Lj8KKworICAgICAgc3RyID0gZnVuY2FsbCh3ZWFybXNnLCBQTCk7CisgICAgICBpZihpbnRlcmFjdGl2ZShQTCkpIHsKKyAgICAgICAgIC8vIEltIEZhbGxlLCBkYXNzIGFsbCBnZXNldHp0IGlzdCwgd2lyZCBhbHMgSW5kZW50IGRlciBOYW1lIGRlcworICAgICAgICAgLy8gYW5nZXpvZ2VuZW4gT2JqZWt0ZXMgZ2VzZXR6dC4gKHRyYWcgYWxsZXMpCisgICAgICAgICB3cml0ZShicmVha19zdHJpbmcoc3RyWzBdLDc4LAorICAgICAgICAgICAgICAgIChhbGw/KE5hbWUoV0VSKSsiOiAiKTowKSwgQlNfTEVBVkVfTVlfTEZTKSk7CisgICAgICB9CisgICAgICAvLyhaZXNzdHJhKTogc2F5KCkgaXN0IGhpZXIgYmxvZWQsIHdlaWwgZXMgYW4gZGFzIEVudiB2b20gdGhpc19wbGF5ZXIoKQorICAgICAgLy9hdXNnaWJ0LCBzb2Zlcm4gZGVyIGV4aXN0aWVydC4gU28ga29lbm5lbiBTcGllbGVyIGRpZSBtZWxkdW5nIGtyaWVnZW4sCisgICAgICAvL29id29obCBkaWUgbGFlbmdzdCB3b2FuZGVycyBzaW5kICh6LkIuIFNlcXVlbnplbikKKyAgICAgIC8vRGFoZXIgbnVuIEF1c2dhYmUgYW4gZGFzIEVudiB2b20gRW52ICh3ZW5uIGRhcyBrZWluIFJhdW0gc2VpbiBzb2xsdGUsCisgICAgICAvL3dhcyBkdXJjaGF1cyBzZWluIGtvZW5udGUsIG1hY2h0IHRlbGxfcm9vbSgpIG5peCkuIAorICAgICAgaWYgKCBvYmplY3RwKGVudmlyb25tZW50KCkpICYmIG9iamVjdHAoZW52aXJvbm1lbnQoZW52aXJvbm1lbnQoKSkpICkKKyAgICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW52aXJvbm1lbnQoKSksCisgICAgICAgICAgICBicmVha19zdHJpbmcoc3RyWzFdLCA3OCwgMCwgQlNfTEVBVkVfTVlfTEZTKSwoe1BMfSkgKTsKKworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBlbHNlIGlmKGludGVyYWN0aXZlKFBMKSkgeworICAgICAgczEgPSByZXBsYWNlX3BlcnNvbmFsKHNwcmludGYod2Vhcm1zZ1swXSwiQFdFTjIiKSwgKHtQTCxNRX0pLCAxKTsKKworICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKHMxLDc4LChhbGw/KE5hbWUoV0VSKSsiOiAiKTowKSwgQlNfTEVBVkVfTVlfTEZTKSk7CisgICAgfQorCisgICAgczEgPSByZXBsYWNlX3BlcnNvbmFsKHNwcmludGYod2Vhcm1zZ1sxXSwiQFdFUjEiLCJAV0VOVTIiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoe1BMLCBNRX0pLCAxKTsKKyAKKyAgICBpZiAoIG9iamVjdHAoZW52aXJvbm1lbnQoKSkgJiYgb2JqZWN0cChlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSkgKQorICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW52aXJvbm1lbnQoKSksCisgICAgICAgICAgICBicmVha19zdHJpbmcoczEsIDc4LCAwLCBCU19MRUFWRV9NWV9MRlMpLCh7IFBMIH0pICk7CisKKyAgICByZXR1cm47CisgIH0KKyAgLyoKKyAgICogS2VpbmUgV2Vhck1zZyBnZXNldHp0LiBBdXNnYWJlIGRlciBEZWZhdWx0LU1lbGR1bmdlbi4KKyAgICovCisgIGVsc2UgaWYoaW50ZXJhY3RpdmUoUEwpKSB7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJEdSB6aWVoc3QgIiArIG5hbWUoV0VOLDEpICsgIiBhbi4iLDc4LAorICAgICAoYWxsPyhOYW1lKFdFUikrIjogIik6MCkpKTsKKyAgfQorICBpZiAoIG9iamVjdHAoZW52aXJvbm1lbnQoKSkgJiYgb2JqZWN0cChlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSkgKQorICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVudmlyb25tZW50KCkpLGJyZWFrX3N0cmluZyhQTC0+TmFtZShXRVIpCisgICAgICAgICAgICArICIgemllaHQgIiArIG5hbWUoV0VOLDApICsiIGFuLiIsNzgpLCAoe1BMfSkpOworfQorCisvKgorICogQXVzZ2FiZSBlaW5lciBNZWxkdW5nIGJlaW0gQXVzemllaGVuIGdlaHQgbnVyIGFuIFNwaWVsZXIsIG5pY2h0IGFuIE5QQy4KKyAqIERpZSBVbWdlYnVuZyBiZWtvbW10IG5hdHVlcmxpY2ggaW1tZXIgZWluZSBNZWxkdW5nLgorICovCit2b2lkIGRvVW53ZWFyTWVzc2FnZShvYmplY3Qgd29ybl9ieSwgaW50IGFsbCkKK3sKKyAgc3RyaW5nICpzdHIsczE7CisgIG1peGVkIG1zZzsKKworICBpZighb2JqZWN0cCh3b3JuX2J5KSkgeyAvLyBOYSBodWNoLCBnYXIgbmljaHQgYW5nZXpvZ2VuPyBBYmJydWNoLgorICAgIHJldHVybjsKKyAgfQorCisgIGlmKG1zZz1RdWVyeVByb3AoUF9VTldFQVJfTVNHKSkgeyAvLyBJc3QgZWluZSBVbndlYXJNc2cgZ2VzZXR6dD8KKyAgICBpZihjbG9zdXJlcChtc2cpKSB7IC8vIE9obyEgR2FyIGdsZWljaCBhbHMgRmt0Lj8KKworICAgICAgc3RyID0gZnVuY2FsbChtc2csIHdvcm5fYnkpOworICAgICAgaWYoaW50ZXJhY3RpdmUod29ybl9ieSkpIHsKKyAgICAgICAgIHRlbGxfb2JqZWN0KHdvcm5fYnksYnJlYWtfc3RyaW5nKHN0clswXSwgNzgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoYWxsPyhOYW1lKFdFUikrIjogIik6MCksQlNfTEVBVkVfTVlfTEZTKSk7CisgICAgICB9CisKKyAgICAgIC8vKFplc3N0cmEpOiBzYXkoKSBpc3QgaGllciBibG9lZCwgd2VpbCBlcyBhbiBkYXMgRW52IHZvbSB0aGlzX3BsYXllcigpCisgICAgICAvL2F1c2dpYnQsIHNvZmVybiBkZXIgZXhpc3RpZXJ0LiBTbyBrb2VubmVuIFNwaWVsZXIgZGllIG1lbGR1bmcga3JpZWdlbiwKKyAgICAgIC8vb2J3b2hsIGRpZSBsYWVuZ3N0IHdvYW5kZXJzIHNpbmQgKHouQi4gU2VxdWVuemVuKQorICAgICAgLy9EYWhlciBudW4gQXVzZ2FiZSBhbiBkYXMgRW52IHZvbSB3b3JuX2J5ICh3ZW5uIGRhcyBrZWluIFJhdW0gc2VpbiBzb2xsdGUsCisgICAgICAvL21hY2h0IHRlbGxfcm9vbSgpIG5peCkuIAorICAgICAgaWYgKCBvYmplY3RwKGVudmlyb25tZW50KHdvcm5fYnkpKSApCisgICAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KHdvcm5fYnkpLAorICAgICAgICAgICAgICBicmVha19zdHJpbmcoc3RyWzFdLDc4LCAwLCBCU19MRUFWRV9NWV9MRlMpLCh7IHdvcm5fYnkgfSkgKTsKKyAgICAgIAorICAgICAgcmV0dXJuOworICAgIH0KKyAgICBlbHNlIGlmKGludGVyYWN0aXZlKHdvcm5fYnkpKSB7CisgICAgICBzMSA9IHJlcGxhY2VfcGVyc29uYWwoc3ByaW50Zihtc2dbMF0sIkBXRU4yIiksCisgICAgICAgICAgICAgICAgICAgICAgKHt3b3JuX2J5LE1FfSksIDEpOworCisgICAgICB0ZWxsX29iamVjdCh3b3JuX2J5LGJyZWFrX3N0cmluZyhzMSw3OCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChhbGw/KE5hbWUoV0VSKSsiOiAiKTowKSwgQlNfTEVBVkVfTVlfTEZTKSk7CisgICAgfQorCisgICAgczEgPSByZXBsYWNlX3BlcnNvbmFsKHNwcmludGYobXNnWzFdLCJAV0VSMSIsIkBXRU5VMiIpLAorICAgICAgICAgICAgICAgICAgICAoe3dvcm5fYnksIE1FIH0pLCAxKTsKKworICAgIGlmICggb2JqZWN0cChlbnZpcm9ubWVudCh3b3JuX2J5KSkgKQorICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW52aXJvbm1lbnQoKSksCisgICAgICAgICAgICBicmVha19zdHJpbmcoczEsNzgsIDAsIEJTX0xFQVZFX01ZX0xGUyksKHsgd29ybl9ieSB9KSApOworICAgIHJldHVybjsKKyAgfQorICAvKgorICAgKiBLZWluZSBVbndlYXJNc2cgZ2VzZXR6dC4gQXVzZ2FiZSBkZXIgRGVmYXVsdC1NZWxkdW5nZW4uCisgICAqLworICBlbHNlIGlmKGludGVyYWN0aXZlKHdvcm5fYnkpKSB7CisgICAgdGVsbF9vYmplY3Qod29ybl9ieSxicmVha19zdHJpbmcoIkR1IHppZWhzdCAiICsgbmFtZShXRU4sMSkgKyAiIGF1cy4iLDc4LAorICAgICAoYWxsPyhOYW1lKFdFUikrIjogIik6MCkpKTsKKyAgfQorICBpZiAoIG9iamVjdHAoZW52aXJvbm1lbnQod29ybl9ieSkpICkKKyAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCh3b3JuX2J5KSwgYnJlYWtfc3RyaW5nKHdvcm5fYnktPk5hbWUoV0VSKQorICAgICAgICAgICAgKyAiIHppZWh0ICIgKyBuYW1lKFdFTiwwKSArICIgYXVzLiIsNzgpLCAoeyB3b3JuX2J5IH0pICk7Cit9CisKKy8vIERpZXNlIEZ1bmt0aW9uIHdpcmQgYXVmZ2VydWZlbiwgd2VubiBkaWUgUnVlc3R1bmcgd2lya2xpY2ggYW5nZXpvZ2VuCisvLyB3aXJkCitwcm90ZWN0ZWQgdm9pZCBJbmZvcm1XZWFyKG9iamVjdCBwbCwgaW50IHNpbGVudCwgaW50IGFsbCkgeworICAgIHJldHVybjsKK30KKworLy8gRGllc2UgRnVua3Rpb24gd2lyZCBhdWZnZXJ1ZmVuLCB3ZW5uIGRpZSBSdWVzdHVuZyB3aXJrbGljaCBhdXNnZXpvZ2VuCisvLyB3aXJkCitwcm90ZWN0ZWQgdm9pZCBJbmZvcm1VbndlYXIob2JqZWN0IHBsLCBpbnQgc2lsZW50LCBpbnQgYWxsKSB7CisgICAgcmV0dXJuOworfQorCisvLyBsaWVmZXJ0IFdlcnRlIDwwIHp1cnVlY2ssIHdlbm4gZGVyIFNwaWVsZXIgZGllIEtsZWlkdW5nIF9uaWNodF8gCisvLyBhbnppZWhlbiBkYXJmLgorLy8gSGllcmJlaSBzdGVodCAtMSBkYWZ1ZXIsIGRhc3MgZGVyIEF1ZnJ1ZmVyIHJldHVybiAwIG1hY2hlbiBzb2xsdGUsCisvLyA8PSAtMiBzb2xsdGUgenVyIGVpbmVtIHJldHVybiAhYWxsIGZ1ZWhyZW4uCitwcm90ZWN0ZWQgaW50IF9jaGVja193ZWFyX3Jlc3RyaWN0aW9ucyhpbnQgc2lsZW50LCBpbnQgYWxsKSB7CisgIG1peGVkICAgdHlwZSxyZXM7CisgIG9iamVjdCAgKmFybW91cnM7CisKKyAgLy8gTWFuIGthbm4gbnVyIEtyYW0gYW56aWVoZW4sIGRpZSBtYW4gYmVpIHNpY2ggdHJhZWd0CisgIGlmIChlbnZpcm9ubWVudCgpIT1QTCkgeyAgICAgICAgICAgIAorICAgIG1zZyhicmVha19zdHJpbmcoIkR1IG11c3N0ICIrbmFtZShXRU4sMSkrIiBlcnN0IG5laG1lbiEiLDc4LAorICAgICAgICAgICAgKGFsbD8oTmFtZShXRVIpKyI6ICIpOjApKSwgYWxsKTsKKyAgICByZXR1cm4oLTEpOworICB9CisKKyAgLy8gRWluZSBnZXRyYWdlbmUgUnVlc3R1bmcga2FubiBtYW4gbmljaHQgbm9jaG1hbCBhbnppZWhlbgorICBpZiAoUXVlcnlQcm9wKFBfV09STikpIHsKKyAgICBtc2coYnJlYWtfc3RyaW5nKCJEdSB0cmFlZ3N0ICIrbmFtZShXRU4sMSkrIiBiZXJlaXRzLiIsNzgsCisgICAgICAgICAgKGFsbD8oTmFtZShXRVIpKyI6ICIpOjApKSwgYWxsKTsKKyAgICByZXR1cm4oLTEpOworICB9CisKKyAgLy8gRGllc2UgRnVua3Rpb24gdmVyc3VjaHQgaW1tZXIsIFRQIGFuenV6aWVoZW4gKCphcmdzKikuIEVzIGdpYnQgYWJlciB2aWVsZQorICAvLyBNYWdpZXIsIGRpZSBvaG5lIFRQIG9kZXIgbWl0IGRlbSBmYWxzY2hlbiBUUCBhbnppZWhlbiB3b2xsZW4uIERhaGVyIG1hbAorICAvLyBwcnVlZmVuIHVuZCBnZ2YuIEZlaGxlciBhdXNsb2VzZW4uCisgIGlmICghdGhpc19wbGF5ZXIoKSkKKyAgICAgIHJhaXNlX2Vycm9yKCJLZWluIHRoaXNfcGxheWVyKCkgZXhpc3RlbnQgYmVpbSBBbnppZWhlbiFcbiIpOworICBlbHNlIGlmICh0aGlzX3BsYXllcigpICE9IGVudmlyb25tZW50KCkpCisgICAgICByYWlzZV9lcnJvcigiTWVpbmUgVW1nZWJ1bmcgYmVpbSBBbnppZWhlbiBpc3QgbmljaHQgdGhpc19wbGF5ZXIoKSFcbiIpOworCisgIC8vIFVlYmVyIFBfUkVTVFJJQ1RJT05TIGthbm4gbWFuIGVpbmlnZSBSZXN0cmlrdGlvbmVuIGRlZmluaWVyZW4sIG9obmUKKyAgLy8gZ2xlaWNoIGF1ZiBlaW5lIFdlYXJGdW5jIHp1cnVlY2tncmVpZmVuIHp1IG11ZXNzZW4uCisgIC8vIERpZSBBdXN3ZXJ0dW5nIGVyZm9sZ3QgdWViZXIgZGVuIFJlc3RyaWN0aW9uQ2hlY2tlcgorICBpZiAoKHJlcz1RdWVyeVByb3AoUF9SRVNUUklDVElPTlMpKSAmJiBtYXBwaW5ncChyZXMpICYmCisgICAgICAocmVzPShzdHJpbmcpIi9zdGQvcmVzdHJpY3Rpb25fY2hlY2tlciItPmNoZWNrX3Jlc3RyaWN0aW9ucyhQTCxyZXMpKQorICAgICAgJiYgc3RyaW5ncChyZXMpKSB7ICAKKyAgICBtc2coYnJlYWtfc3RyaW5nKHJlcyw3OCwoYWxsPyhOYW1lKFdFUikrIjogIik6MCkpLGFsbCk7CisgICAgcmV0dXJuKC0xKTsKKyAgfQorCisgIC8vIElzdCBlaW5lIFdlYXJGdW5jIGdlc2V0enQsIHdpcmQgZGllc2UgYXVmZ2VydWZlbi4KKyAgaWYgKG9iamVjdHAocmVzPVF1ZXJ5UHJvcChQX1dFQVJfRlVOQykpICYmIAorICAgICAgIShyZXMtPldlYXJGdW5jKE1FLCBzaWxlbnQsIGVudmlyb25tZW50KCkpKSkgeworICAgIC8vIEVpbmUgTWVsZHVuZyBtdXNzIHZvbiBkZXIgV2VhckZ1bmMgYXVzZ2VnZWJlbiB3ZXJkZW4KKyAgICByZXR1cm4oLTIpOworICB9CisKKyAgLy8gc2NoZWluYmFyIGRhcmYgbWFuIGRhcyBoaWVyIGFuemllaGVuLiA7LSkKKyAgcmV0dXJuIDA7Cit9CisKK3Byb3RlY3RlZCB2b2lkIF9pbmZvcm13ZWFyKGludCBzaWxlbnQsIGludCBhbGwpIHsKKworICAvLyBFaW5lIE1lbGR1bmcgYXVzZ2ViZW4sIHdlbm4gZGFzIHNpbGVudC1GbGFnIG5pY2h0IGdlc2V0enQgaXN0CisgIGlmICghc2lsZW50KSB7CisgICAgZG9XZWFyTWVzc2FnZShhbGwpOworICB9CisKKyAgLy8gSW5mb3JtLUZ1bmt0aW9uIGF1ZnJ1ZmVuCisgIEluZm9ybVdlYXIoUEwsIHNpbGVudCwgYWxsKTsKK30KKworLy8gRGllIEZ1bmt0aW9uLCBkaWUgZGFzIGVpZ2VudGxpY2hlIEFuemllaGVuIGR1cmNoZnVlaHJ0Cit2YXJhcmdzIGludCBEb1dlYXIoaW50IHNpbGVudCwgaW50IGFsbCkgeworICBpbnQgbmg7CisKKyAgLy8gQmVkaW5ndW5nZW4gcHJ1ZWZlbiwgX2NoZWNrX3Jlc3RyaWN0aW9ucygpIGdpYnQgZGllIG5vdHdlbmRpZ2VuIE1lbGR1bmdlbgorICAvLyBhbiBkZW4gU3BpZWxlciBhdXMuCisgIGludCByZXMgPSBfY2hlY2tfd2Vhcl9yZXN0cmljdGlvbnMoc2lsZW50LCBhbGwpOworICBpZiAocmVzID09IC0xKQorICAgIHJldHVybigwKTsKKyAgZWxzZSBpZiAocmVzIDw9IC0yKQorICAgIHJldHVybighYWxsKTsKKworICAvLyBEZXIgQ2hlY2sgYXVmIGZyZWllIEhhZW5kZSBtdXNzIG5hY2ggYWxsZW4gYW5kZXJlbiBDaGVja3MgYXVzIEtsZWlkdW5nCisgIC8vIHVuZCBSdWVzdHVuZyBlcmZvbGdlbiB1bmQgaXN0IGltIFByaW56aXAgaWRlbnRpc2NoIGZ1ZXIgYmVpZGUuIERhaGVyIHdpcmQKKyAgLy8gZGVyIGhpZXIgaW4gZGllc2VyIEZ1bmt0aW9uIGdlbWFjaHQuCisgIC8vIFNvbGwgZGFzIE9iamVrdCBIYWVuZGUgImJlbnV0emVuIj8gU3RlaHQgZGEgYXVjaCB3aXJrbGljaCBlaW4KKyAgLy8gSW50ZWdlci1XZXJ0IGRyaW4/IGljaCBtYWNoIGRhIGpldHp0IGVpbiByYWlzZV9lcnJvcigpLCBkYXMgc29sbAorICAvLyBzY2hsaWVzc2xpY2ggZ2VmaXh0IHdlcmRlbi4gQXVzc2VyZGVtIHNwYXJ0IGVzIG5lbiBXb3JrYXJvdW5kIGJlaW0KKyAgLy8gQXVzemllaGVuLgorICBpZiAoIWludHAobmg9UXVlcnlQcm9wKFBfTlJfSEFORFMpKSkgeworICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIkludmFsaWQgUF9OUl9IQU5EUyBpbiAlTyIsb2JqZWN0X25hbWUoKSkpOworICB9CisgIC8vIFdlbm4gSGFlbmRlIGJlbnV0enQgd2VyZGVuIHNvbGxlbiwgbXVzcyBuYXR1ZXJsaWNoIGF1Y2ggZ2V0ZXN0ZXQKKyAgLy8gd2VyZGVuLCBvYiBkYXMgdWViZXJoYXVwdCBnZWh0CisgIGlmIChuaD4wKSB7CisgICAgaWYgKCEoUEwtPlVzZUhhbmRzKE1FLCBuaCkpKSB7CisgICAgICAvLyBTY2hhZGUsIG5pY2h0IGdlbnVnIEhhZW5kZSBmcmVpIC0+IE1lbGR1bmcgYXVzZ2ViZW4KKyAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygiRHUgaGFzdCBrZWluZSBIYW5kIG1laHIgZnJlaS4iLDc4LAorICAgICAgICAgICAgKGFsbD8oTmFtZShXRVIpKyI6ICIpOjApKSk7CisgICAgICByZXR1cm4oIWFsbCk7CisgICAgfQorICB9CisKKyAgLy8gT0ssIGRpZSBSdWVzdHVuZyBrYW5uIGFuZ2V6b2dlbiB3ZXJkZW4uCisgIC8vIEJlaGluZGVydW5nIGJlaW0gV2VjaHNlbCBudXIgZnVlciBTcGllbGVyCisgIGlmIChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKFBMKSkKKyAgLy8gV2VubiBkYXMgR2FuemUgLCx3aXJrbGljaCcnIGVpbmUgS2xlaWR1bmcvUnVlc3R1bmcgaXN0IHVuZCBrZWluIFNNUworICAvLyBvZGVyIGFlaG5saWNoZXMuLi4KKyAgaWYgKCFRdWVyeVByb3AoUF9XRUFQT05fVFlQRSkpIHsKKyAgICAvLyBBa3Rpb24gbm9jaCBzZXR6ZW4sIFNwaWVsZXIgaGF0IGphIHdhcyBhbmdlem9nZW4KKyAgICBQTC0+U2V0UHJvcChQX0xBU1RfV0VBUl9BQ1RJT04sKHtXQV9XRUFSLHRpbWUoKX0pKTsKKyAgICAvLyBJbSBLYW1wZiB2ZXJsaWVydCBkZXIgU3BpZWxlciBkdXJjaCBLbGVpZHVuZ3N3ZWNoc2VsIGVpbmUgUnVuZGUuCisgICAgaWYgKFBMLT5JbkZpZ2h0KCkpIHsKKyAgICAgIFBMLT5TZXRQcm9wKFBfQVRUQUNLX0JVU1ksMSk7CisgICAgfQorICB9CisgIC8vIEVpbnRyYWdlbiBpbiBQX0NMT1RISU5HL1BfQVJNT1VSUworICBQTC0+V2Vhcih0aGlzX29iamVjdCgpKTsKKworICBQTC0+U2V0UHJvcChQX0VRVUlQX1RJTUUsdGltZSgpKTsKKyAgU2V0UHJvcChQX1dPUk4sIFBMKTsKKyAgU2V0UHJvcChQX0VRVUlQX1RJTUUsdGltZSgpKTsKKworICAvLyBnZ2YuIGFuZGVyZSBPYmpla3RlIGluZm9ybWllcmVuIGV0Yy4KKyAgX2luZm9ybXdlYXIoc2lsZW50LCBhbGwpOworCisgIC8vIEZlcnRpZyBtaXQgZGVtIEFuemllaGVuLiBWb3JnYW5nIGJlZW5kZW4gYnp3LiBtaXQgYW5kZXJlbgorICAvLyBSdWVzdHVuZ2VuIGZvcnRmYWhyZW4KKyAgcmV0dXJuICFhbGw7Cit9CisKKworLy8gbGllZmVydCAwIHp1cmVjaywgd2VubiBkaWUgS2xlaWR1bmcvUnVlc3R1bmcgYXVzZ2V6b2dlbiB3ZXJkZW4ga2FubgorLy8gYmVpIE1fTk9DSEVDSyBpc3QgZGFzIEF1c3ppZWhlbiBpbW1lciBlcmxhdWJ0LCBhbGxlcmRpbmdzIHdpcmQKKy8vIFBfUkVNT1ZFX0ZVTkMgYXVjaCBkYW5uIGdlcnVmZW4gKHdlbm4gYXVjaCBpZ25vcmllcnQpLgorLy8gPDAgdmVyYmlldGV0IGRhcyBBdXN6aWVoZW4KK3Byb3RlY3RlZCBpbnQgX2NoZWNrX3Vud2Vhcl9yZXN0cmljdGlvbnMob2JqZWN0IHdvcm5fYnksIGludCBzaWxlbnQsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYWxsKQoreworICAvLyBOaWNodCBnZXRyYWdlbmUgUnVlc3R1bmdlbiBrYW5uIG1hbiBhdWNoIG5pY2h0IGF1c3ppZWhlbgorICBpZiAoIW9iamVjdHAod29ybl9ieSkpIHsKKyAgICAgIHJldHVybigtMik7CisgIH0KKworICAvLyBJc3QgZWluZSBSZW1vdmVGdW5jIGdlc2V0enQsIHdpcmQgZGllc2UgYXVmZ2VydWZlbgorICAvLyBJbSBGYWxsZSB2b24gTV9OT0NIRUNLIHdpcmQgZGFzIEVyZ2VibmlzIGFsbGVyZGluZ3MgaWdub3JpZXJ0LgorICBtaXhlZCByZXM9UXVlcnlQcm9wKFBfUkVNT1ZFX0ZVTkMpOworICBpZiAob2JqZWN0cChyZXMpCisgICAgICAmJiAhcmVzLT5SZW1vdmVGdW5jKE1FLHNpbGVudCx3b3JuX2J5KQorICAgICAgJiYgIShzaWxlbnQgJiBNX05PQ0hFQ0spCisgICAgICApCisgIHsKKyAgICAgIC8vIEVpbmUgTWVsZHVuZyBtdXNzIHZvbiBkZXIgUmVtb3ZlRnVuYyBhdXNnZWdlYmVuIHdlcmRlbgorICAgICAgcmV0dXJuKC0yKTsKKyAgfQorCisgIC8vIGdlbmVyZWxsIGhlYnQgTV9OT0NIRUNLIGRpZSBSZXN0cmlrdGlvbmVuIGF1ZiAtIHNvbnN0IGtvbW10IGVzIHp1CisgIC8vIG1hc3NpdmVuIElua29uc2lzdGVuemVuIGJlaW0gQmV3ZWdlbiBtaXQgTV9OT0NIRUNLLgorICBpZiAoc2lsZW50ICYgTV9OT0NIRUNLKQorICAgIHJldHVybiAxOworCisgIC8vIEVpbmUgdmVyZmx1Y2h0ZSBSdWVzdHVuZyBrYW5uIG1hbiBuYXR1ZXJsaWNoIG5pY2h0IGF1c3ppZWhlbgorICByZXM9UXVlcnlQcm9wKFBfQ1VSU0VEKTsKKyAgaWYgKHJlcyApIHsKKyAgICBpZiAoc3RyaW5ncChyZXMpKSB7CisgICAgICAvLyBTdGFuZCBpbiBQX0NVUlNFRCBlaW4gU3RyaW5nPyBEYW5uIGRpZXNlbiBhdXNnZWJlbgorICAgICAgdGVsbF9vYmplY3Qod29ybl9ieSwgICAgICAKKyAgICAgICAgICAocmVzWzwxXT09J1xuJyA/IHJlcyA6IGJyZWFrX3N0cmluZyhyZXMsNzgsCisgICAgICAgICAgICAoYWxsPyhOYW1lKFdFUikrIjogIik6MCkpKSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgLy8gU29uc3QgZWluZSBTdGFuZGFyZC1NZWxkdW5nIGF1c2dlYmVuCisgICAgICB0ZWxsX29iamVjdCh3b3JuX2J5LGJyZWFrX3N0cmluZygKKyAgICAgICAgICAiRHUga2FubnN0ICIgKyBuYW1lKFdFTikgKyAiIG5pY2h0IGF1c3ppZWhlbiwgIiArIFF1ZXJ5UHJvbm91bihXRVIpCisgICAgICAgICAgKyAiIGlzdCB2ZXJmbHVjaHQgd29yZGVuLlxuIiw3OCwoYWxsPyhOYW1lKFdFUikrIjogIik6MCkpKTsKKyAgICB9CisgICAgcmV0dXJuKC0yKTsKKyAgfQorCisgIC8vIEF1c3ppZWhlbiBtb2VnbGljaAorICByZXR1cm4oMSk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIF9pbmZvcm11bndlYXIob2JqZWN0IHdvcm5fYnksIGludCBzaWxlbnQsIGludCBhbGwpIHsKKworICAvLyBJbmZvcm0tRnVua3Rpb24gYXVmcnVmZW4KKyAgSW5mb3JtVW53ZWFyKHdvcm5fYnksIHNpbGVudCwgYWxsKTsKKworICAvLyBNZWxkdW5nIGF1c2dlYmVuLCB3ZW5uIGRhcyBzaWxlbnQtRmxhZyBuaWNodCBnZXNldHp0IGlzdAorICBpZiAoIShzaWxlbnQmTV9TSUxFTlQpKSB7CisgICAgZG9VbndlYXJNZXNzYWdlKCB3b3JuX2J5LCBhbGwgKTsKKyAgfQorfQorCisvLyBEaWUgRnVua3Rpb24sIGRpZSBkYXMgZWlnZW50bGljaGUgQXVzemllaGVuIGR1cmNoZnVlaHJ0CisvLyBoaWVyIHN0ZWh0IG51ciBkcmluLCB3YXMgYXVmIGplZGVuIEZhbGwgZnVlciBLbGVpZHVuZ2VuIHVuZCBSdWVzdHVuZ2VuCisvLyBnbGVpY2ggaXN0LCBkYW1pdCBtYW4gYmVpIFJ1ZXN0dW5nZW4gZGllc2UgRnVua3Rpb24gbmljaHQgdWViZXJzY2hyZWliZW4KKy8vIG11c3MuCit2YXJhcmdzIGludCBEb1Vud2VhcihpbnQgc2lsZW50LCBpbnQgYWxsKSB7CisgIG9iamVjdCB3b3JuX2J5OworICBpbnQgbmg7CisKKyAgLy8gRGFzIEZsYWcgInNpbGVudCIgd2lyZCBpbiBkZXIgUmVtb3ZlRnVuYygpIGV0d2FzIGFuZGVycyBiZWhhbmRlbHQKKyAgLy8gYWxzIHVlYmVyYWxsIGFuZGVycy4gRGVzaGFsYiB3aXJkIE1fU0lMRU5UIGdlc2V0enQsIHNvZmVybiAic2lsZW50IgorICAvLyBfaXJnZW5kZWluZW5fIFdlcnQgYXVzc2VyIE1fTk9DSEVDSyBoYXR0ZS4KKyAgaWYgKCBzaWxlbnQgJiB+TV9OT0NIRUNLICkKKyAgICAgIHNpbGVudCB8PSBNX1NJTEVOVDsKKworICAvLyBTdGFuZGFyZC1Ob3RmaXlmYWlsIHNldHplbi4KKyAgaWYgKGFsbCkKKyAgICBub3RpZnlfZmFpbCgiQWxsZXMgYXVzZ2V6b2dlbiwgd2FzIGdpbmcuXG4iKTsKKworICAvLyBIYXQgZGFzIE9iamVrdCBIYWVuZGUgImJlbnV0enQiPyBTdGVodCBkYSBhdWNoIHdpcmtsaWNoIGVpbgorICAvLyBJbnRlZ2VyLVdlcnQgZHJpbj8gV2VubiBuaWNodCwgbWFjaCBpY2ggbmVuIHJhaXNlX2Vycm9yKCksIGRhcyBkdWVyZnRlCisgIC8vIGVpZ2VudGxpY2ggZ2FyIG5pY2h0IHBhc3NpZXJlbi4gUHJ1ZWZ1bmcgbWFsIGFtIEFuZmFuZyBtYWNoZW4sIGJldm9yCisgIC8vIGlyZ2VuZHdhcyBhbmRlcmVzIChSZW1vdmVGdW5jKCkpIHBhc3NpZXJ0IGlzdC4KKyAgaWYgKCFpbnRwKG5oPVF1ZXJ5UHJvcChQX05SX0hBTkRTKSkpIHsKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJJbnZhbGlkIFBfTlJfSEFORFMgaW4gJU8iLG9iamVjdF9uYW1lKCkpKTsKKyAgfQorCisgIHdvcm5fYnk9UXVlcnlQcm9wKFBfV09STik7CisgIC8vIGRhcmYgYXVzZ2V6b2dlbiB3ZXJkZW4/IFdlbm4gbmljaHQsIEVuZGUuCisgIGludCByZXMgPSBfY2hlY2tfdW53ZWFyX3Jlc3RyaWN0aW9ucyh3b3JuX2J5LHNpbGVudCxhbGwpOworICBpZiAocmVzIDwgMCkKKyAgICByZXR1cm4oIWFsbCk7CisKKyAgLy8gT0ssIGFsbGVzIGtsYXIsIGRpZSBSdWVzdHVuZyB3aXJkIGF1c2dlem9nZW4KKyAgd29ybl9ieS0+VW53ZWFyKE1FKTsKKworICAvLyBCZW51dHp0ZSBIYWVuZGUgd2llZGVyIGZyZWlnZWJlbgorICBpZiAobmg+MCkgeworICAgIHdvcm5fYnktPkZyZWVIYW5kcyhNRSk7CisgIH0KKworICB3b3JuX2J5LT5TZXRQcm9wKFBfRVFVSVBfVElNRSwgdGltZSgpKTsKKyAgU2V0UHJvcChQX1dPUk4sIDApOworCisgIC8vIEZsYWcgbm9jaCBzZXR6ZW4sIFNwaWVsZXIgaGF0IGphIHdhcyBhdXNnZXpvZ2VuCisgIC8vIEFiZXIgbnVyIHdlbm5zIGF1Y2ggZGVyIFNwaWVsZXIgc2VsYnN0IGlzdC4KKyAgLy8gdW5kIHdlbm4gZGFzIHdpcmtsaWNoIGVpbmUgUnVlc3R1bmcgdW5kIGtlaW4gU01TIG8uYWUuIGlzdC4KKyAgaWYgKFBMICYmIFBMPT13b3JuX2J5ICYmICFRdWVyeVByb3AoUF9XRUFQT05fVFlQRSkpIHsKKyAgICAvL0JlaGluZGVydW5nIGJlaW0gV2VjaHNlbCBudXIgZnVlciBTcGllbGVyCisgICAgaWYgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoUEwpKSB7CisgICAgICBQTC0+U2V0UHJvcChQX0xBU1RfV0VBUl9BQ1RJT04sKHtXQV9VTldFQVIsdGltZSgpfSkpOworICAgICAgaWYgKFBMLT5JbkZpZ2h0KCkpIHsgCisgICAgICAgIFBMLT5TZXRQcm9wKFBfQVRUQUNLX0JVU1ksMSk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gb2ssIG51biBub2NoIGFuZGVyZSBPYmpla3RlIGluZm9ybWllcmVuLgorICBfaW5mb3JtdW53ZWFyKHdvcm5fYnksc2lsZW50LGFsbCk7CisKKyAgLy8gRmVydGlnIG1pdCBkZW0gQW56aWVoZW4uIFZvcmdhbmcgYmVlbmRlbiBiencuIG1pdCBhbmRlcmVuCisgIC8vIFJ1ZXN0dW5nZW4gZm9ydGZhaHJlbgorICByZXR1cm4gIWFsbDsKK30KKworcHJvdGVjdGVkIGludCBfZG9fd2VhcihzdHJpbmcgc3RyLCBpbnQgc2lsZW50LCBpbnQgYWxsKSB7CisgIGludCAqbGFzdDsKKworICAvLyBTdGFuZGFyZC1Ob3RmaXktRmFpbCBzZXR6ZW4uCisgIGlmIChhbGwpCisgICAgbm90aWZ5X2ZhaWwoIkFsbGVzIGFuZ2V6b2dlbiwgd2FzIGdpbmcuXG4iKTsKKworICAvLyBJc3QgZGllc2UgUnVlc3R1bmcgdWViZXJoYXVwdCBnZW1laW50PyBCZWkgInRyYWdlIGFsbGVzIiBpc3QgZGllcworICAvLyBuYXR1ZXJsaWNoIGltbWVyIGRlciBGYWxsCisgIGlmICghc3RyIHx8ICghYWxsICYmICFpZChzdHIpKSkgeworICAgICAgcmV0dXJuIDA7CisgIH0KKworICAvLyBWaWVsbGVpY2h0IGRhcmYgZGVyIFNwaWVsZXIgamEgZ2FyIG5peCBtZWhyIGFuemllaGVuLgorICBpZiAoKG9iamVjdClQTC0+SW5GaWdodCgpKSB7ICAgICAgICAKKyAgICBsYXN0PShpbnQqKVBMLT5RdWVyeVByb3AoUF9MQVNUX1dFQVJfQUNUSU9OKTsKKyAgICAgIGlmIChwb2ludGVycChsYXN0KSAmJiAobGFzdFswXT09V0FfVU5XRUFSKSAmJiAoKHRpbWUoKS1sYXN0WzFdKTwyKSkgeworICAgICAgICBub3RpZnlfZmFpbCgiRHUgaGFzdCBkb2NoIGdlcmFkZSBlcnN0IGV0d2FzIGF1c2dlem9nZW4hXG4iCisgICAgICAgICAgICAiU28gc2NobmVsbCBiaXN0IER1IG5pY2h0IVxuIik7ICAgICAgICAKKyAgICAgICAgcmV0dXJuIDA7ICAgICAgICAKKyAgICAgIH0KKyAgfQorCisgIC8vIEF1ZiB6dW0gZWlnZW50bGljaGVuIEFuemllaGVuCisgIHJldHVybiBEb1dlYXIoc2lsZW50LCBhbGwpOworCit9CisKKy8vIEZ1bmt0aW9uLCBkaWUgZGFzICJ0cmFnZSIvInppZWhlICogYW4iLUtvbW1hbmRvIGF1c3dlcnRldAordmFyYXJncyBpbnQgZG9fd2VhcihzdHJpbmcgc3RyLCBpbnQgc2lsZW50KSB7ICAKKyAgaW50IGFsbDsgIAorCisgIC8vIEhhdCBkZXIgU3BpZWxlciAidHJhZ2UgYWxsZXMiIGVpbmdlZ2ViZW4/CisgIGFsbD0oc3RyPT0iYWxsZXMiIHx8IHN0cj09ImFsbGUga2xlaWR1bmciIHx8IHN0cj09ImFsbGUgYmVrbGVpZHVuZyIpOworICAKKyAgcmV0dXJuKF9kb193ZWFyKHN0cixzaWxlbnQsYWxsKSk7Cit9CisKK3Byb3RlY3RlZCBpbnQgX2RvX3Vud2VhcihzdHJpbmcgc3RyLCBpbnQgc2lsZW50LCBpbnQgYWxsKSB7CisgIGludCAqIGxhc3Q7CisKKyAgLy8gSXN0IGRpZXNlIFJ1ZXN0dW5nIHVlYmVyaGF1cHQgZ2VtZWludD8gVW5kIGhhdCBkaWVzZXIgU3BpZWxlciBzaWUKKyAgLy8gYXVjaCB3aXJrbGljaCBhbj8KKyAgaWYgKCFzdHJpbmdwKHN0cikgfHwgKCFhbGwgJiYgIWlkKHN0cikpKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICBpZiAoIVF1ZXJ5UHJvcChQX1dPUk4pKSB7IAorICAgIGlmIChhbGwpIHsgIAorICAgICAgbm90aWZ5X2ZhaWwoIkFsbGVzIGF1c2dlem9nZW4sIHdhcyBnaW5nLlxuIik7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgaWYgKCFRdWVyeShQX0FSVElDTEUpIHx8IFF1ZXJ5UHJvcChQX1BMVVJBTCkpIHsKKyAgICAgIG5vdGlmeV9mYWlsKCBicmVha19zdHJpbmcoCisgICAgICAgICAgICAiRHUgdHJhZWdzdCBrIituYW1lKFdFTiwwKSsiLiIsNzgpICk7CisgICAgfQorICAgIGVsc2UgeyAgICAKKyAgICAgIG5vdGlmeV9mYWlsKCBicmVha19zdHJpbmcoCisgICAgICAgICAgICJEdSB0cmFlZ3N0ICIrbmFtZShXRU4sMSkrIiBuaWNodC4iLDc4KSApOyAgCisgICAgfQorICAgIHJldHVybiAwOworICB9CisKKyAgLy8gVmllbGxlaWNodCBkYXJmIGRlciBTcGllbGVyIGphIGdhciBuaWNodHMgbWVociBhdXN6aWVoZW4uCisgIGlmICgob2JqZWN0KVBMLT5JbkZpZ2h0KCkpIHsKKyAgICBsYXN0PShpbnQqKVBMLT5RdWVyeVByb3AoUF9MQVNUX1dFQVJfQUNUSU9OKTsKKyAgICBpZiAocG9pbnRlcnAobGFzdCkgJiYgKGxhc3RbMF09PVdBX1dFQVIpICYmICgodGltZSgpLWxhc3RbMV0pPDIpKSB7CisgICAgICBub3RpZnlfZmFpbCgiRHUgaGFzdCBkb2NoIGdlcmFkZSBlcnN0IGV0d2FzIGFuZ2V6b2dlbiFcbiIgICAgICAgICAgICAgIAorICAgICAgICAgICJTbyBzY2huZWxsIGJpc3QgRHUgbmljaHQhXG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgfQorICAvLyBBdWYgenVtIGVpZ2VudGxpY2hlbiBBdXN6aWVoZW4KKyAgcmV0dXJuIERvVW53ZWFyKHNpbGVudCwgYWxsKTsKK30KKworLy8gRGllIEZ1bmt0aW9uLCBkaWUgZGFzICJ6aWVoZSAqIGF1cyItS29tbWFuZG8gYXVzd2VydGV0Cit2YXJhcmdzIGludCBkb191bndlYXIoc3RyaW5nIHN0ciwgaW50IHNpbGVudCkgeworICBpbnQgYWxsOworCisgIGFsbD0oc3RyPT0iYWxsZXMiIHx8IHN0cj09ImFsbGUga2xlaWR1bmciIHx8IHN0cj09ImFsbGUgYmVrbGVpZHVuZyIpOworCisgIHJldHVybihfZG9fdW53ZWFyKHN0cixzaWxlbnQsYWxsKSk7Cit9CisKKy8vIEZ1bmt0aW9uLCBkaWUgZGFzICJ6aWVoZSItS29tbWFuZG8gYXVzd2VydGV0CitpbnQgemllaGUoc3RyaW5nIHN0cikgeyAgIAorICBzdHJpbmcgb2I7CisKKyAgLy8gVWViZXJnZWJlbmVzIEFyZ3VtZW50IHBydWVmZW4KKyAgaWYgKCFzdHJpbmdwKHN0cikpIHsKKyAgICByZXR1cm4gMDsgIAorICB9CisKKyAgLy8gSXN0IEFOemllaGVuIGdlbWVpbnQ/CisgIGlmIChzc2NhbmYoc3RyLCAiJXMgYW4iLCBvYik9PTEpIHsKKyAgICAgIHJldHVybiBkb193ZWFyKG9iICk7CisgIH0KKworICAvLyBPZGVyIGlzdCBBVVN6aWVoZW4gZ2VtZWludD8KKyAgaWYgKHNzY2FuZihzdHIsICIlcyBhdXMiLCBvYik9PTEgKSB7IAorICAgICAgcmV0dXJuIGRvX3Vud2VhcihvYik7CisgIH0KKworICAvLyBPaywgZXMgZ2VodCB3b2hsIHdlZGVyIHVtcyBhbi0gbm9jaCB1bXMgYXVzemllaGVuCisgIHJldHVybiAwOworfQorCisKKy8vIEJlc2NoYWVkaWdlbiBkZXMgS2xlaWR1bmdzc3R1ZWNrcworCisvLyBEaXJla3RlcyBCZXNjaGFlZGlnZW4gZGVyIEtsZWlkdW5nIGR1cmNoIFNldHplbiBkZXIgUHJvcCBnaWJ0cyBuaWNodC4gOy0pCisvLyBEYXMgZ2VodCBhdXMgS29tcGF0aWJpbGl0YWV0Z3J1ZW5kZW4gYmVpIFJ1ZXN0dW5nZW4sIGFiZXIgbmljaHQgbWVociBiZWkKKy8vIEtsZWlkdW5nLiBQdW5rdC4KK3N0YXRpYyBtaXhlZCBfc2V0X2l0ZW1fZGFtYWdlZChtaXhlZCBhcmcpIHsKKyAgcmV0dXJuKFF1ZXJ5UHJvcChQX0RBTUFHRUQpKTsKK30KKworLy8gV2lsbCBtYW4gZWluZSBLbGVpZHVuZyBiZXNjaGFlZGlnZW4gb2RlciByZXBhcmllcmVuLCBzbyBtYWNodCBtYW4gZGFzCisvLyBhbSBiZXN0ZW4gdWViZXIgZGllIEZ1bmt0aW9uIERhbWFnZShhcmd1bWVudCkuIFBvc2l0aXZlIEFyZ3VtZW50ZQorLy8gYmVkZXV0ZW4gZWluZSBCZXNjaGFlZGlndW5nLCBuZWdhdGl2ZSBlaW5lIFJlcGFyYXR1ci4gRGVyIFJ1ZWNrZ2FiZXdlcnQKKy8vIGlzdCBkaWUgd2lya2xpY2ggZHVyY2hnZWZ1ZWhydGUgQWVuZGVydW5nIGRlcyBCZXNjaGFlZGlndW5nc3dlcnRlcworaW50IERhbWFnZShpbnQgbmV3X2RhbSkgeworICByZXR1cm4gMDsKK30KKworLy8gV2lyZCBkaWUgS2xlaWR1bmcgZWluZXIgQmVsYXN0dW5nIGF1c2dlc2V0enQgKGJlaSBSdWVzdHVuZ2VuIHouQi4gYmVpIGVpbmVtCisvLyBBbmdyaWZmIGVpbmVzIEdlZ25lcnMpLCBkYW5uIHdpcmQgVGFrZUZsYXcoKSBhdWZnZXJ1ZmVuLiBCZWkgS2xlaWR1bmdlbgorLy8ga29lbm50ZSBtYW4gamEgcGVyIFBfU0VOU0lUSVZFIGFyYmVpdGVuIG9kZXIgZWluIE1hZ2llciBydWZ0IGJlaSBBa3Rpb25lbgorLy8gVGFrZUZsYXcoKSBhdWYuCit2YXJhcmdzIHZvaWQgVGFrZUZsYXcobWl4ZWQgZGFtX3R5cGVzLG1hcHBpbmcgZWluZm9zKSB7ICAgCisgIGludCBxdWFsaXR5OworCisgIC8vIElzdCBkZXIgUnVlc3R1bmcgZWluZSBRdWFsaXRhZXQgZ2VzZXR6dCB3b3JkZW4sIHNvIGthbm4gZXMgenUgZWluZXIKKyAgLy8gYWxsbWFlaGxpY2hlbiBCZXNjaGFlZGlndW5nIGRlciBSdWVzdHVuZyBrb21tZW4uIEltIGlmKCkgZmxhdyBnbGVpY2gKKyAgLy8gaG9jaHphZWhsZW4uCisgIGlmICgocXVhbGl0eT1RdWVyeVByb3AoUF9RVUFMSVRZKSkgJiYgISgoKytmbGF3KSAlIHF1YWxpdHkpKSB7ICAgICAgCisgICAgRGFtYWdlKDEpOworICB9CisKKyAgLy8gWmVpdHB1bmt0IGRlcyBlcnN0ZW4gQXVmcnVmZXMgZmVzdGhhbHRlbgorICBpZiAoIWZ0aW1lKSAgIAorICAgIGZ0aW1lPXRpbWUoKTsKK30KKworLy8gRGllIEZsYXctRGF0ZW4ga29lbm5lbiBuYXR1ZXJsaWNoIGF1Y2ggYWJnZXJ1ZmVuIHdlcmRlbgorbWl4ZWQgKlF1ZXJ5RmxhdygpIHsKKyAgcmV0dXJuICh7ZmxhdyxmdGltZSxkdGltZShmdGltZSl9KTsKK30KKworcHVibGljIHN0YXR1cyBJc0Nsb3RoaW5nKCkge3JldHVybiAxO30KKwpkaWZmIC0tZ2l0IGEvc3RkL2Nsb3RoaW5nSEcuYyBiL3N0ZC9jbG90aGluZ0hHLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmJkMjY1YQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9jbG90aGluZ0hHLmMKQEAgLTAsMCArMSw1OSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGFybW91ckhHLmMgLS0gYXJtb3VyIHN0YW5kYXJkIG9iamVjdCBmb3IgaGF0cyBhbmQgZ2xhc3NlcworLy8KKy8vICRJZDogYXJtb3VySEcuYyx2IDEuNCAyMDAyLzA4LzE5IDE0OjIxOjMxIFJpa3VzIEV4cCAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworaW5oZXJpdCAiL3N0ZC9jbG90aGluZyI7CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvY29tbWFuZHMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorCitpbnQgc2V0emVuKHN0cmluZyBzKTsKKwordm9pZCBjcmVhdGUoKSB7CisgICAgOjpjcmVhdGUoKTsKKyAgICBBZGRDbWQoKHsic2V0eiIsInNldHplIn0pLCJzZXR6ZW4iKTsKK30KKwordmFyYXJncyB2b2lkIGRvV2Vhck1lc3NhZ2UoIGludCBhbGwgKSB7CisgIGlmKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKFBMKSApIHsKKyAgICB3cml0ZSggIkR1IHNldHp0ICIgKyBuYW1lKFdFTiwxKSArICIgYXVmLlxuIiApOworICB9CisgIGlmIChvYmplY3RwKGVudmlyb25tZW50KCkpICYmIG9iamVjdHAoZW52aXJvbm1lbnQoZW52aXJvbm1lbnQoKSkpKQorICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSwKKwljYXBpdGFsaXplKChzdHJpbmcpUEwtPm5hbWUoV0VSKSkgKyAiIHNldHp0ICIgKyBuYW1lKFdFTiwwKSArIAorCSIgYXVmLlxuIik7Cit9CisKK3ZhcmFyZ3Mgdm9pZCBkb1Vud2Vhck1lc3NhZ2UoIG9iamVjdCB3b3JuX2J5LCBpbnQgYWxsICkgeworICBpZiggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh3b3JuX2J5KSApIHsKKyAgICB0ZWxsX29iamVjdCh3b3JuX2J5LCAgIkR1IHNldHp0ICIgKyBuYW1lKFdFTiwxKSArICIgYWIuXG4iICk7CisgIH0KKyAgdGVsbF9yb29tKGVudmlyb25tZW50KHdvcm5fYnkpLCAKKwkgICAgKGNhcGl0YWxpemUoKHN0cmluZyl3b3JuX2J5LT5uYW1lKFdFUikpKSArICIgc2V0enQgIiArCisJICAgIG5hbWUoV0VOLDApICsgIiBhYi5cbiIsICh7d29ybl9ieX0pKTsKK30KKworaW50IHNldHplbihzdHJpbmcgc3RyKSB7CisgIHN0cmluZyBvYjsKKworICBpZighc3RyKQorICAgIHJldHVybiAwOworICBpZihzc2NhbmYoc3RyLCAiJXMgYXVmIiwgb2IpPT0xICkKKyAgICByZXR1cm4gX2RvX3dlYXIob2IsIDAsIDApOworICBpZihzc2NhbmYoc3RyLCAiJXMgYWIiLCBvYik9PTEgKQorICAgIHJldHVybiBfZG9fdW53ZWFyKG9iLCAwLCAwKTsKKyAgcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9jbG90aGluZ19jb250YWluZXIuYyBiL3N0ZC9jbG90aGluZ19jb250YWluZXIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lYzkzYjkyCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2Nsb3RoaW5nX2NvbnRhaW5lci5jCkBAIC0wLDAgKzEsNTQgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vLAorLy8gY2xvdGhpbmdfY29udGFpbmVyLmMgLS0gS2xlaWR1bmcsIGluIGRpZSBtYW4gd2FzIHJlaW5zdGVja2VuIGthbm4KKy8vCisvLyAkSWQ6IGNsb3RoaW5nX2NvbnRhaW5lci5jLHYgMS4zIDIwMDMvMDgvMDcgMDc6MjU6NDMgUmlrdXMgRXhwICQKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCitpbmhlcml0ICIvc3RkL3RoaW5nL3Byb3BlcnRpZXMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9jb21tYW5kcyI7Citpbmhlcml0ICIvc3RkL3RoaW5nL2xhbmd1YWdlIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvZW52Y2hrIjsKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL2xpZ2h0IjsKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL3Jlc3RyaWN0aW9ucyI7Citpbmhlcml0ICIvc3RkL2NvbnRhaW5lci9pbnZlbnRvcnkiOworaW5oZXJpdCAiL3N0ZC9jb250YWluZXIvaXRlbXMiOworaW5oZXJpdCAiL3N0ZC9jbG90aGluZy9tb3ZpbmciOworaW5oZXJpdCAiL3N0ZC9jbG90aGluZy93ZWFyIjsKK2luaGVyaXQgIi9zdGQvY2xvdGhpbmcvY29udGFpbmVyX2Rlc2NyaXB0aW9uIjsKKworLy8jZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8Y29udGFpbmVyLmg+CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIHsKKyAgcHJvcGVydGllczo6Y3JlYXRlKCk7CisgIGNvbW1hbmRzOjpjcmVhdGUoKTsKKyAgbGlnaHQ6OmNyZWF0ZSgpOworICBjb250YWluZXJfZGVzY3JpcHRpb246OmNyZWF0ZSgpOworICByZXN0cmljdGlvbnM6OmNyZWF0ZSgpOworICBpdGVtczo6Y3JlYXRlKCk7CisgIHdlYXI6OmNyZWF0ZSgpOworICBlbnZjaGs6OmNyZWF0ZSgpOworICBTZXRQcm9wKFBfQ09OVEFJTkVSLDEpOworICBTZXRQcm9wKFBfUFJFUE9TSVRJT04sICJpbiIpOworICBTZXRQcm9wKFBfU09VUkNFX1BSRVBPU0lUSU9OLCAiYXVzIik7CisgIFNldFByb3AoUF9ERVNUX1BSRVBPU0lUSU9OLCAiaW4iKTsKKyAgQWRkSWQoIkRpbmciKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3ZvaWQgcmVzZXQoKSAgeworICBpdGVtczo6cmVzZXQoKTsKK30KKworaW50IElzQ2xvdGhpbmcoKSB7cmV0dXJuIDE7fQorCmRpZmYgLS1naXQgYS9zdGQvY29udGFpbmVyLmMgYi9zdGQvY29udGFpbmVyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTc3YzdmYQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9jb250YWluZXIuYwpAQCAtMCwwICsxLDY3IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gY29udGFpbmVyLmMgLS0gY29udGFpbmVyIHN0YW5kYXJkIG9iamVjdAorLy8KKy8vICRJZDogY29udGFpbmVyLmMgNzgwNCAyMDExLTA3LTEwIDIwOjM3OjUyWiBaZXNzdHJhICQKKworLy8gVGhlIG1vc3QgZ2VuZXJhbCBvYmplY3QgY2xhc3MuIEl0IGRlZmluZXMgdGhlIHJlYWxseSBiYXNpYyBmdW5jdGlvbnMuCisvLworLy8gVGhpcyBvYmplY3Qgc2hvdWxkIHVuZGVyc3RhbmQgdGhlIHByb3BlcnRpZXMgc2hvcnQsIGxvbmcsIGluZm8sIHJlYWRfbXNnLAorLy8gdmFsdWUsIHdlaWdodC4KKy8vCisvLyB3ZWlnaHQgaXMgZ2l2ZW4gaW4gZ3JhbXMsIDEga2lsb2dyYW0gKGtnKSA9IDEwMDAgZ3JhbXMgKGcpID0gMSBvbGQgd2VpZ2h0CisvLyB1bml0CisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworaW5oZXJpdCAiL3N0ZC90aGluZy9wcm9wZXJ0aWVzIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvbW92aW5nIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvY29tbWFuZHMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9sYW5ndWFnZSI7Citpbmhlcml0ICIvc3RkL2NvbnRhaW5lci9kZXNjcmlwdGlvbiI7Citpbmhlcml0ICIvc3RkL2NvbnRhaW5lci9saWdodCI7Citpbmhlcml0ICIvc3RkL2NvbnRhaW5lci9yZXN0cmljdGlvbnMiOworaW5oZXJpdCAiL3N0ZC9jb250YWluZXIvaW52ZW50b3J5IjsKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL2l0ZW1zIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvZW52Y2hrIjsKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIHByb3BlcnRpZXM6OmNyZWF0ZSgpOworICBjb21tYW5kczo6Y3JlYXRlKCk7CisgIGxpZ2h0OjpjcmVhdGUoKTsKKyAgZGVzY3JpcHRpb246OmNyZWF0ZSgpOworICByZXN0cmljdGlvbnM6OmNyZWF0ZSgpOworICBpdGVtczo6Y3JlYXRlKCk7CisgIGVudmNoazo6Y3JlYXRlKCk7CisgIFNldFByb3AoUF9DT05UQUlORVIsMSk7CisgIFNldFByb3AoUF9QUkVQT1NJVElPTiwgImluIik7CisgIFNldFByb3AoUF9TT1VSQ0VfUFJFUE9TSVRJT04sICJhdXMiKTsKKyAgU2V0UHJvcChQX0RFU1RfUFJFUE9TSVRJT04sICJpbiIpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKworLyoKK3ZvaWQgaW5pdCgpIAoreworICBjb21tYW5kczo6aW5pdCgpOworICBkZXNjcmlwdGlvbjo6aW5pdCgpOworfQorKi8KKwordm9pZCByZXNldCgpCit7CisgIGl0ZW1zOjpyZXNldCgpOworfQorCmRpZmYgLS1naXQgYS9zdGQvY29udGFpbmVyL2Rlc2NyaXB0aW9uLmMgYi9zdGQvY29udGFpbmVyL2Rlc2NyaXB0aW9uLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzRmN2I1YwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9jb250YWluZXIvZGVzY3JpcHRpb24uYwpAQCAtMCwwICsxLDEwMyBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGNvbnRhaW5lci9kZXNjcmlwdGlvbi5jIC0tIHN0YW5kYXJkIGRlc2NyaXB0aW9uIGZvciBjb250YWluZXJzCisvLworLy8gJElkOiBkZXNjcmlwdGlvbi5jIDg3NTUgMjAxNC0wNC0yNiAxMzoxMzo0MFogWmVzc3RyYSAkCisKK2luaGVyaXQgIi9zdGQvdGhpbmcvZGVzY3JpcHRpb24iOworCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxjb250YWluZXIuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorCisKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgOjpjcmVhdGUoKTsKKyAgU2V0UHJvcChQX1RSQU5TUEFSRU5ULCAxKTsKKyAgQWRkSWQoIkNvbnRhaW5lciIpOworfQorCit2YXJhcmdzIHN0cmluZyBsb25nKGludCBtb2RlKSB7CisgIHN0cmluZyBkZXNjciwgaW52X2Rlc2NyOworCisgIGRlc2NyID0gcHJvY2Vzc19zdHJpbmcoUXVlcnlQcm9wKFBfTE9ORykpOworICBpZighUXVlcnlQcm9wKFBfVFJBTlNQQVJFTlQpKSByZXR1cm4gZGVzY3I7CisKKyAgaW52X2Rlc2NyID0gbWFrZV9pbnZsaXN0KFBMLCBhbGxfaW52ZW50b3J5KE1FKSwgbW9kZSApOworICBpZiAoIGludl9kZXNjciAhPSAiIiApCisgICAgZGVzY3IgKz0gY2FwaXRhbGl6ZShRdWVyeVByb25vdW4oV0VSKSkgKyAiIGVudGhhZWx0OlxuIiArIGludl9kZXNjcjsKKyAgcmV0dXJuIGRlc2NyOworfQorCisvLyBmbGFnczogMSAtIHdpemFyZCwgMiAtIGRvbid0IGNvbGxlY3QgZXF1YWwgb2JqZWN0cyAnCisvLyBmbGFnczogNCAtIGRvbid0IGFwcGVuZCBpbmZvcyBmb3Igd2l6YXJkcworcHJpdmF0ZSB2b2lkIHN0cmluZ2VuaXplKG1peGVkIG9iaiwgaW50IGZsYWdzLCBtaXhlZCBvYmpzLCBtaXhlZCBpbmZvKQoreworICBzdHJpbmcgaWQsIHRtcDsKKyAgaW50IGlkeDsKKyAgCisgIGlmICggKCEoZmxhZ3MgJiA0KSAmJiAoZmxhZ3MgJiAxKSkpIHsKKyAgICAvL3dlbm4gTWFnaWVyIHVuZCBNYWdpZXJpbmZvcyBhbmdlaGFlbmd0IHdlcmRlbiBzb2xsZW46CisgICAgdG1wID0gY2FwaXRhbGl6ZShvYmotPnNob3J0KCl8fCIiKVswLi48Ml0KKyAgICAgICAgKyAiIFsiK29iamVjdF9uYW1lKG9iaikrIl0iOworICB9CisgIGVsc2UgaWYgKG9iai0+UXVlcnlQcm9wKFBfSU5WSVMpKSB7CisgICAgLy9rZWluZSBBdXNnYWJlIGJ6dy4gbGVlcmVyIFN0cmluZywgd2lyZCBkYW5uIHZvbiBjb2xsZWN0IHJhdXNnZXNjaG1pc3NlbgorICAgIHRtcD0iIjsKKyAgfQorICBlbHNlIHsKKyAgICAvL1NwaWVsZXIsIE1hZ2llciBvaG5lIFBfV0FOVFNfVE9fTEVBUk4gZXRjLgorICAgIHRtcCA9IGNhcGl0YWxpemUob2JqLT5zaG9ydCgpfHwiIilbMC4uPDJdOworICB9CisgIC8vd2VubiB3aXphcmQgdW5kICdkb250IGNvbGxlY3QgZXF1YWwgb2JqZWN0cyc6IGlkIGlzdCBvYmplY3RfbmFtZSgpCisgIGlmKGZsYWdzICYgMyB8fCBsaXZpbmcob2JqKSkgCisgICAgaWQgPSBvYmplY3RfbmFtZShvYmopOworICAvL3NvbnN0IG5laG1lbiB3aXIgZGVuIE5hbWVuIGRlciBCbHVlcHJpbnQgLT56dXNhbW1lbmZhc3NlbiBkZXIgT2JqZWt0ZQorICBlbHNlCisgICAgaWQgPSBCTFVFX05BTUUob2JqKSArIHRtcDsKKyAgLy8gQW56YWhsIGRlcyBqZXdlaWxpZ2VuIE9iamVrdHMgKGFuaGFuZCB2b24gaWQpIHphZWhsZW4uCisgIGlmKChpZHggPSBtZW1iZXIob2JqcywgaWQpKSA9PSAtMSkKKyAgeworICAgIG9ianMgKz0gKHsgaWQgfSk7CisgICAgaW5mbyArPSAoeyAoeyB0bXAsIDEsIG9ian0pIH0pOworICB9CisgIGVsc2UKKyAgICBpbmZvW2lkeF1bMV0rKzsKK30KKworcHJpdmF0ZSBzdHJpbmcgY29sbGVjdChtaXhlZCBvYmopCit7CisgIC8vYmVrb21tdCBlaW4gQXJyYXkgKHtuYW1lLGFuemFobCxvYmpla3R9KQorICAvL09iamVrdGUgb2huZSBOYW1lbiAoUF9TSE9SVD09MCBvZGVyIFBfSU5WSVMpIHdlZ3dlcmZlbgorICBpZighc2l6ZW9mKG9ialswXSkpIHJldHVybiAwOworICAvLyBPYmpla3RuYW1lICsgKEFuemFobCkgenVydWVja2dlYmVuLgorICByZXR1cm4gb2JqWzBdICsgKG9ialsxXSA+IDEgPyAiICgiK29ialsxXSsiKSIgOiAiIik7Cit9CisKKy8vIGZsYWdzOiAxIC0gcmV0dXJuIGFycmF5LCAyIC0gZG9uJ3QgY29sbGVjdCBlcXVhbCBvYmplY3RzICcKKy8vIGZsYWdzOiA0IC0gZG9uJ3QgYXBwZW5kIGluZm9zIGZvciB3aXphcmRzCit2YXJhcmdzIG1peGVkIG1ha2VfaW52bGlzdChvYmplY3Qgdmlld2VyLCBtaXhlZCBpbnYsIGludCBmbGFncykKK3sKKyAgaW50IGlzd2l6OworICBtaXhlZCBvYmpzLCBpbmZvOworCisgIGlzd2l6ID0gSVNfTEVBUk5FUiggdmlld2VyICkgJiYgdmlld2VyLT5RdWVyeVByb3AoUF9XQU5UU19UT19MRUFSTik7CisgIG9ianMgPSAoe30pOyBpbmZvID0gKHt9KTsKKyAgbWFwKGludiwgIydzdHJpbmdlbml6ZS8qJyovLCBpc3dpeiB8IChmbGFncyAmIDIpIHwgKGZsYWdzICYgNCksICZvYmpzLCAmaW5mbyk7CisgIGlmKGZsYWdzICYgMSkgcmV0dXJuIGluZm87CisgIGludiA9IG1hcChpbmZvLCAjJ2NvbGxlY3QvKicqLykgLSAoeyAwIH0pOworICBpZighc2l6ZW9mKGludikpIHJldHVybiAiIjsKKyAgcmV0dXJuIHNwcmludGYoIiUiKyhzaXplb2YoaW52KSA+IDYgPyAiIyIgOiAiPSIpKyItNzhzIiwKKyAgICAgICAgICAgICAgICAgaW1wbG9kZShpbnYsICJcbiIpKSArICJcbiI7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9jb250YWluZXIvaW52ZW50b3J5LmMgYi9zdGQvY29udGFpbmVyL2ludmVudG9yeS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBhMDU3YjcKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvY29udGFpbmVyL2ludmVudG9yeS5jCkBAIC0wLDAgKzEsMTI4IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gY29udGFpbmVyL2ludmVudG9yeS5jIC0tIFVtZ2FuZyBtaXQgYmVzb25kZXJlbiBPYmpla3RlbiBpbSBJbnZlbnRvcnkKKy8vCisvLyAkSWQ6IGludmVudG9yeS5jIDYzNzkgMjAwNy0wNy0yMCAyMjozMjowMlogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKy8vI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8dGhpbmcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8c2Vuc2l0aXZlLmg+CisKKyNkZWZpbmUgTUUgdGhpc19vYmplY3QoKQorCit2b2lkIFJlbW92ZVNlbnNpdGl2ZU9iamVjdEZyb21MaXN0KG9iamVjdCBvYiwgc3RyaW5nIGxpc3QpIHsKKyAgbWl4ZWQgYSxiLGM7CisgIGludCBpLGY7CisKKyAgaWYgKCFwb2ludGVycChhPVF1ZXJ5UHJvcChTRU5TX1BST1BfUFJFRklYK2xpc3QpKSkKKyAgICByZXR1cm47CisgIGY9MTsKKyAgZm9yIChpPXNpemVvZihhKS0xO2k+PTA7aS0tKQorICAgIGlmICghcG9pbnRlcnAoYj1hW2ldKSB8fAorCSFzaXplb2YoYikgfHwKKwkhb2JqZWN0cChjPWJbMF0pIHx8CisJZW52aXJvbm1lbnQoYykhPU1FIHx8CisJYz09b2IpCisgICAgICBhW2ldPWY9MDsKKyAgaWYgKGYpCisgICAgcmV0dXJuOworICBhLT0oezB9KTsKKyAgaWYgKCFzaXplb2YoYSkpCisgICAgYT0wOworICBTZXRQcm9wKFNFTlNfUFJPUF9QUkVGSVgrbGlzdCxhKTsKK30KKwordm9pZCBSZW1vdmVTZW5zaXRpdmVPYmplY3Qob2JqZWN0IG9iKSB7CisgIFJlbW92ZVNlbnNpdGl2ZU9iamVjdEZyb21MaXN0KG9iLFNFTlNJVElWRV9JTlZFTlRPUlkpOworICBSZW1vdmVTZW5zaXRpdmVPYmplY3RGcm9tTGlzdChvYixTRU5TSVRJVkVfSU5WRU5UT1JZX1RSSUdHRVIpOworfQorCit2YXJhcmdzIHZvaWQgSW5zZXJ0U2Vuc2l0aXZlT2JqZWN0VG9MaXN0KG9iamVjdCBvYiwgc3RyaW5nIGxpc3QsIHN0cmluZyBrZXksCisJCQkJCSBpbnQgdGhyZXNob2xkLCBtaXhlZCAqb3B0KSB7CisgIG1peGVkIGE7CisgIGludCBpOworICAKKyAgaWYgKCFwb2ludGVycChhPVF1ZXJ5UHJvcChTRU5TX1BST1BfUFJFRklYK2xpc3QpKSkKKyAgICBhPSh7fSk7CisgIGZvciAoaT1zaXplb2YoYSktMTtpPj0wO2ktLSkKKyAgICBpZiAoYVtpXVtTRU5TX09CSkVDVF09PW9iICYmIGFbaV1bU0VOU19LRVldPT1rZXkpCisgICAgICByZXR1cm47CisgIGErPSh7KHtvYixzeW1ib2xfZnVuY3Rpb24oU0VOU19UUklHR0VSX1BSRUZJWCtsaXN0LG9iKSwKKyAgICAgICAgIGtleSx0aHJlc2hvbGQsb3B0fSl9KTsKKyAgU2V0UHJvcChTRU5TX1BST1BfUFJFRklYK2xpc3QsYSk7Cit9CisKK3ZvaWQgSW5zZXJ0U2Vuc2l0aXZlT2JqZWN0KG9iamVjdCBvYiwgbWl4ZWQgYXJnKSB7CisgIGludCBpOworICBtaXhlZCB4OworICBtYXBwaW5nIG1hcF9sZGZpZWQ7CisgIAorICBpZiAoIXBvaW50ZXJwKGFyZykpCisgICAgcmV0dXJuOworICBmb3IgKGk9c2l6ZW9mKGFyZyktMTtpPj0wO2ktLSkKKyAgICBpZiAocG9pbnRlcnAoeD1hcmdbaV0pICYmCisJc2l6ZW9mKHgpPj0zICYmCisJc3RyaW5ncCh4WzBdKSAmJgorCXN0cmluZ3AoeFsxXSkgJiYKKwlpbnRwKHhbMl0pKSB7CisgICAgICBJbnNlcnRTZW5zaXRpdmVPYmplY3RUb0xpc3Qob2IseFswXSx4WzFdLHhbMl0seFszLi5dKTsKKyAgICAgIGNhbGxfb3RoZXIoTUUsU0VOU19JTlNFUlRfUFJFRklYK3hbMF0sb2IseFsxXSx4WzJdLHhbMy4uXSk7CisgICAgfQorfQorCit2YXJhcmdzIHZvaWQgaW5zZXJ0X3NlbnNpdGl2ZV9pbnYob2JqZWN0IG9iLCBzdHJpbmcga2V5LAorCQkJCSBpbnQgdGhyZXNob2xkLCBtaXhlZCAqb3B0KSB7CisgIC8vIERpZXNlIEZ1bmt0aW9uIHN1Y2h0LCBvYiBiZWltIEhpbnp1ZnVlZ2VuIGVpbmVzIHNlbnNpdGl2ZW4gT2JqZWt0cworICAvLyBzY2hvbiBlaW4gT2JqZWt0IGRhIGlzdCwgZGFzcyBkaWVzZXMgYXVzbG9lc3QuCisgIC8vIHouQi4gKGR5bmFtaXQsIGZldWVyLCAxMDAsIG9wdF9keW5hbWl0KSBzb3JndCBmdWVyCisgIC8vIGR5bmFtaXQtPnRyaWdnZXJfc2Vuc2l0aXZlX2ludihmYWNrZWwsZmV1ZXIsMTIwLG9wdF9mYWNrZWwsb3B0X2R5bmFtaXQpCisgIC8vIHdlbm4gZWluZSBGYWNrZWwgdm9yaGVyIG1pdCBXZXJ0IDEyMCBlaW5nZXRyYWdlbiB3YXIuCisgIG1peGVkIGEseDsKKyAgaW50IGk7CisgIAorICBpZiAoIXBvaW50ZXJwKGE9UXVlcnlQcm9wKFBfU0VOU0lUSVZFX0lOVkVOVE9SWV9UUklHR0VSKSkgfHwKKyAgICAgICFvYmplY3RwKG9iKSkKKyAgICByZXR1cm47CisgIGZvciAoaT1zaXplb2YoYSktMTtpPj0wO2ktLSkKKyAgICBpZiAocG9pbnRlcnAoeD1hW2ldKSAmJgorCXhbU0VOU19LRVldPT1rZXkgJiYKKwl4W1NFTlNfVEhSRVNIT0xEXT50aHJlc2hvbGQgJiYgLy8gSXN0IGRlciBBdXNsb2VzZXIgZ3Jvc3MgZ2VudWc/CisJb2JqZWN0cCh4W1NFTlNfT0JKRUNUXSkgJiYKKwllbnZpcm9ubWVudCh4W1NFTlNfT0JKRUNUXSk9PWVudmlyb25tZW50KG9iKSkKKyAgICAgIG9iLT50cmlnZ2VyX3NlbnNpdGl2ZV9pbnYoeFtTRU5TX09CSkVDVF0seFtTRU5TX0tFWV0seFtTRU5TX1RIUkVTSE9MRF0sCisJCQkJeFtTRU5TX09QVF0sb3B0KTsKKyAgLy8gWnVlcnN0IFRyaWdnZXItT3B0aW9uZW4sIGRhbm4gT3B0aW9uZW4gZGVzIHNlbnNpdGl2ZW4gT2JqZWt0cworfQorCit2YXJhcmdzIHZvaWQgaW5zZXJ0X3NlbnNpdGl2ZV9pbnZfdHJpZ2dlcihvYmplY3Qgb2IsIHN0cmluZyBrZXksCisJCQkJCSBpbnQgdGhyZXNob2xkLCBtaXhlZCAqb3B0KSB7CisgIC8vIERpZXNlIEZ1bmt0aW9uIHN1Y2h0LCBvYiBlaW4gc2Vuc2l0aXZlcyBPYmpla3QgaW0gSW52ZW50b3J5IGlzdCwKKyAgLy8gZGFzIGR1cmNoIGRpZXNlcyBPYmpla3QgYXVzZ2Vsb2VzdCB3aXJkLgorICAvLyB6LkIuIChmYWNrZWwsIGZldWVyLCAxMjAsIG9wdF9mYWNrZWwpIHNvcmd0IGZ1ZXIKKyAgLy8gZHluYW1pdC0+dHJpZ2dlcl9zZW5zaXRpdmVfaW52KGZhY2tlbCxmZXVlciwxMjAsb3B0X2ZhY2tlbCxvcHRfZHluYW1pdCkKKyAgLy8gd2VubiBEeW5hbWl0IG1pdCBXZXJ0PDEyMCBlaW5nZXRyYWdlbiB3YXIKKyAgbWl4ZWQgYSx4OworICBpbnQgaTsKKyAgCisgIGlmICghcG9pbnRlcnAoYT1RdWVyeVByb3AoUF9TRU5TSVRJVkVfSU5WRU5UT1JZKSkgfHwKKyAgICAgICFvYmplY3RwKG9iKSkKKyAgICByZXR1cm47CisgIGZvciAoaT1zaXplb2YoYSktMTtpPj0wO2ktLSkKKyAgICBpZiAocG9pbnRlcnAoeD1hW2ldKSAmJgorCXhbU0VOU19LRVldPT1rZXkgJiYKKwl4W1NFTlNfVEhSRVNIT0xEXTx0aHJlc2hvbGQgJiYgLy8gQXVzbG9lc2VyIGdyb3NzIGdlbnVnPworCW9iamVjdHAoeFtTRU5TX09CSkVDVF0pICYmCisJZW52aXJvbm1lbnQoeFtTRU5TX09CSkVDVF0pPT1lbnZpcm9ubWVudChvYikgJiYKKwljbG9zdXJlcCh4W1NFTlNfQ0xPU1VSRV0pKQorICAgICAgZnVuY2FsbCh4W1NFTlNfQ0xPU1VSRV0sCisJICAgICAgb2Isa2V5LHRocmVzaG9sZCxvcHQseFtTRU5TX09QVF0pOworICAvLyBadWVyc3QgVHJpZ2dlci1PcHRpb25lbiwgZGFubiBPcHRpb25lbiBkZXMgc2Vuc2l0aXZlbiBPYmpla3RzCit9CmRpZmYgLS1naXQgYS9zdGQvY29udGFpbmVyL2l0ZW1zLmMgYi9zdGQvY29udGFpbmVyL2l0ZW1zLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTk2MWJmZQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9jb250YWluZXIvaXRlbXMuYwpAQCAtMCwwICsxLDI1NiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGNvbnRhaW5lci9pdGVtcy5jIC0tIGNyZWF0aW5nIGV4dHJhIGl0ZW1zIGluIHJvb20KKy8vCisvLyAkSWQ6IGl0ZW1zLmMgODgxMSAyMDE0LTA1LTA5IDE3OjMwOjM3WiBaZXNzdHJhICQKKworLy8gZXh0cmEgaXRlbXMgaGFuZGxpbmcKKy8vCisvLwlBZGRJdGVtKHN0cmluZyBmaWxlbmFtZSwgaW50IHJlZnJlc2gpCisvLwkgIENsb25lcyBhbiBpdGVtIGFuZCBwdXRzIGl0IGludG8gdGhlIHJvb20uIDxyZWZyZXNoPiBtYXkgYmUKKy8vCSAgb24gb2YgdGhlIGZvbGxvd2luZzoKKy8vCSAgUkVGUkVTSF9OT05FOiBObyByZWZyZXNoIGRvbmUgdW50aWwgcmVib290LgorLy8JICBSRUZSRVNIX0RFU1RSVUNUOiBSZWZyZXNoIG9uIHJlc2V0IGlmIGl0ZW0gd2FzIGRlc3RydWN0ZWQuCisvLwkgIFJFRlJFU0hfUkVNT1ZFOiBSZWZyZXNoIG9uIHJlc2V0IGlmIGl0ZW0gd2FzIHJlbW92ZWQgZnJvbSByb29tLgorLy8JICBSRUZSRVNIX0FMV0FZUzogQ3JlYXRlIGEgbmV3IGNsb25lIG9uIGV2ZXJ5IHJlc2V0LgorLy8KKy8vIFRoZSBjb21tYW5kcyBhcmUgaW1wbGVtZW50ZWQgYXMgcHJvcGVydGllcyBQX0lURU1TIGFzIG1hcHBpbmcuIFRoZXkgYXJlIAorLy8gc3RvcmVkIGxvY2FsbHkgKF9zZXRfeHgpIGFzIG1hcHBpbmcgdG8gc3BlZWQgdXAgdGhlIHJvdXRpbmVzIAorLy8gaW4gdGhpcyBtb2R1bGUuCisvLyAKKy8vIEZvcm1hdCBvZiBrZXkgYW5kIGRhdGEgaW4gdGhlIFBfSVRFTVMgbWFwcGluZzoKKy8vCisvLyAoWyBrZXkxIDogcmVmcmVzaDE7IG9icDE7IGFycjEsIC4uLiwga2V5biA6IHJlZnJlc2huOyBvYnBuOyBhcnJuIF0pCisKKyNpbmNsdWRlIDxzeXNfZGVidWcuaD4KKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cm9vbXMuaD4KKyNpbmNsdWRlIDxjb250YWluZXIuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPGRhZW1vbi5oPgorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreyAKKyAgICBTZXQoIFBfSVRFTVMsICh7fSkgKTsKKyAgICBTZXQoIFBfSVRFTVMsIFNFQ1VSRUQsIEZfTU9ERV9BUyApOworICAgIAorICAgIE9CSkVDVEQtPlF1ZXJ5T2JqZWN0KCk7ICAvLyBxdWVyeWluZyBnZW5lcmFsIG9iamVjdHMKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKKy8qIEtyYW0genVtIEF1ZnJhZXVtZW4gdm9uIG11bHRpcGxlbiBnbGVpY2hlbiBJdGVtcyBpbSBDb250YWluZXIuICovCitwcml2YXRlIG9iamVjdCByZW1vdmVhYmxlX29iKCBvYmplY3Qgb2IgKQoreworICAgIGlmICggIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob2IpICYmICFsaXZpbmcob2IpICkKKyAgICAgICAgcmV0dXJuIG9iOworCisgICAgcmV0dXJuIDA7Cit9CisKK3Byb3RlY3RlZCB2YXJhcmdzIHZvaWQgcmVtb3ZlX211bHRpcGxlKGludCBsaW1pdCwgbWl4ZWQgZnVuKQoreworICAgIG9iamVjdCAqaW5oID0gYWxsX2ludmVudG9yeSh0aGlzX29iamVjdCgpKSAtICh7MH0pOworCisgICAgaW5oID0gZmlsdGVyKCBpbmgsICMncmVtb3ZlYWJsZV9vYiApOworICAgIGZvcmVhY2gobWl4ZWQgaXRlbSA6IFF1ZXJ5UHJvcChQX0lURU1TKSkKKyAgICAgIGluaCAtPSAoeyBpdGVtWzBdIH0pOworIAorICAgIGlmICghc3RyaW5ncChmdW4pICYmICFjbG9zdXJlcChmdW4pKQorICAgICAgZnVuID0gImRlc2NyaXB0aW9uX2lkIjsKKyAgICBpbmggPSB1bmlxdWVfYXJyYXkoaW5oLCBmdW4sIDApOworICAgIGZvcmVhY2gobWl4ZWQgYXJyOiBpbmgpCisgICAgeworICAgICAgaWYgKHNpemVvZihhcnIpIDw9IGxpbWl0KQorICAgICAgICBjb250aW51ZTsKKyAgICAgIGNhdGNoKGNhbGxfb3RoZXIoYXJyW2xpbWl0IC4uXSwgInJlbW92ZSIpOyBwdWJsaXNoKTsKKyAgICB9Cit9CisKKworLyogSXRlbSBoYW5kbGluZyAqLworcHVibGljIHZhcmFyZ3Mgb2JqZWN0IEFkZEl0ZW0oIG1peGVkIGZpbGVuYW1lLCBpbnQgcmVmcmVzaCwgbWl4ZWQgcHJvcHMgKSAKK3sKKyAgICBzdHJpbmcgZmlsZTsKKyAgICBvYmplY3Qgb2I7CisgICAgaW50IGk7CisKKyAgICBpZiggcG9pbnRlcnAoZmlsZW5hbWUpICkgeworICAgICAgICBmb3IoIGkgPSBzaXplb2YoZmlsZW5hbWUpOyBpLS07ICkKKyAgICAgICAgICAgIGZpbGVuYW1lW2ldID0gKHN0cmluZyltYXN0ZXIoKS0+X2dldF9wYXRoKCBmaWxlbmFtZVtpXSwgIj8iICk7CisgICAgICAgIAorICAgICAgICBmaWxlID0gZmlsZW5hbWVbcmFuZG9tKCBzaXplb2YoZmlsZW5hbWUpICldOworICAgIH0KKyAgICBlbHNlIAorICAgICAgICBmaWxlID0gZmlsZW5hbWUgPSAoc3RyaW5nKW1hc3RlcigpLT5fZ2V0X3BhdGgoIGZpbGVuYW1lLCAiPyIgKTsKKyAgICAKKyAgICBpZiAoIHByb3BzID09IDEgKQorICAgICAgICBjYXRjaChvYiA9IGxvYWRfb2JqZWN0KCBmaWxlKTsgcHVibGlzaCk7CisgICAgZWxzZQorCWNhdGNoKG9iID0gY2xvbmVfb2JqZWN0KGZpbGUpOyBwdWJsaXNoKTsKKyAgICAKKyAgICBpZiAob2JqZWN0cChvYikpIHsKKyAgICAgIG9iLT5tb3ZlKCB0aGlzX29iamVjdCgpLCBNX05PQ0hFQ0t8TV9OT19BVFRBQ0sgKTsKKyAgICAgIC8vIG1pdCBBYnNpY2h0IGtlaW5lIFBydWVmdW5nIGF1ZnMgTW92ZSwgd2VubnMgbmljaHQgZ2VodCwgc29sbHMgMnMKKyAgICAgIC8vIHNwYWV0ZXIgYXVmIGRlciBFYmVuZSBidWdnZW4sIHdlaWwgcHJha3Rpc2NoIG5pZW1hbmQgaW0gY3JlYXRlKCkgZGFzCisgICAgICAvLyBFcmdlYm5pcyB2b20gQWRkSXRlbSgpIHBydWVmdC4KKyAgICB9CisKKyAgICAvLyBJbiBQX0lURU1TIHZlcm1lcmtlbiwgZXMgc2VpIGRlbm4sIFJFRlJFU0hfTk9ORSBpc3QgZ2VnZWJlbiwgaW4gZGVtCisgICAgLy8gRmFsbCBpc3QgZGllIFNwZWljaGVydW5nIHZvZWxsaWcgdW5ub2V0aWcuCisgICAgLy8gVE9ETzogUHJ1ZWZlbiwgb2IgZGFzIHdpcmtsaWNoIHByb2JsZW1sb3MgZ2VodC4gQmlzIGRhaGluIHdlcmRlbiBhdWNoCisgICAgLy8gVE9ETzo6UkVGUkVTSF9OT05FLUl0ZW1zIHZlcm1lcmt0LiAocy4gY2xlYW5fdXAoKSBpbiAvc3RkL3Jvb20uYykKKyAgICAvL2lmICghKHJlZnJlc2ggJiBSRUZSRVNIX05PTkUpKSB7CisgICAgICBTZXRQcm9wKCBQX0lURU1TLCBRdWVyeVByb3AoUF9JVEVNUykgKworICAgICAgICAgICAgICh7ICh7IG9iLCAgICAgICAgLy8gUklURU1fT0JKRUNUCisgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsICAvLyBSSVRFTV9GSUxFCisgICAgICAgICAgICAgICAgICAgcmVmcmVzaCAgICAvLyBSSVRFTV9SRUZSRVNICisgICAgICAgICAgICAgICAgICAgICAgIH0pICsKKyAgICAgICAgICAgICAgICAgICAgKChtYXBwaW5ncChwcm9wcykgfHwgcHJvcHMgPT0gMSkgPyAoeyBwcm9wcyB9KSA6ICh7fSkpIH0pICk7CisgICAgLy99CisKKyAgICBpZiAoIG9iICYmIG1hcHBpbmdwKHByb3BzKSApIAorICAgICAgICB3YWxrX21hcHBpbmcoIHByb3BzLCBzeW1ib2xfZnVuY3Rpb24oICJTZXRQcm9wIiwgb2IgKSApOworICAgIAorICAgIHJldHVybiBvYjsKK30KKworCitwcml2YXRlIHZvaWQgcmlfcmVtX29iKCBvYmplY3Qgb2IgKQoreworICAgIG9iamVjdCAqaW52OworICAgIGludCBpOworICAKKyAgICBpZiAoIG9iamVjdHAob2IpICYmIHByZXNlbnQob2IsIHRoaXNfb2JqZWN0KCkpICkgeworICAgICAgICBpbnYgPSBkZWVwX2ludmVudG9yeShvYik7CisgICAgICAgIAorICAgICAgICBmb3IgKCBpID0gc2l6ZW9mKGludik7IGktLTsgKQorICAgICAgICAgICAgaWYgKCBpbnZbaV0gKSB7CisgICAgICAgICAgICAgICAgaW52W2ldLT5yZW1vdmUoMSk7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgaWYgKCBpbnZbaV0gKQorICAgICAgICAgICAgICAgICAgICBkZXN0cnVjdChpbnZbaV0pOworICAgICAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgb2ItPnJlbW92ZSgxKTsKKyAgICAgICAgCisgICAgICAgIGlmICggb2IgKQorICAgICAgICAgICAgZGVzdHJ1Y3Qob2IpOworICAgIH0KK30KKworCitwcml2YXRlIGludCByaV9maWx0ZXIoIG1peGVkICpyaXRlbSwgbWl4ZWQgZmlsZSApCit7CisgICAgb2JqZWN0IG9iLCAqaW52OworICAgIGludCBpOworICAKKyAgICBvYiA9IHJpdGVtW1JJVEVNX09CSkVDVF07CisgIAorICAgIGlmICggc3RyaW5ncChmaWxlKSAmJiByaXRlbVtSSVRFTV9GSUxFXSA9PSBmaWxlICkKKyAgICAgICAgcmV0dXJuIHJpX3JlbV9vYihvYiksIDA7CisgICAgZWxzZSBpZiAoIHBvaW50ZXJwKHJpdGVtW1JJVEVNX0ZJTEVdKSAmJiBwb2ludGVycChmaWxlKSAmJgorICAgICAgICAgICAgICBzaXplb2YoZmlsZSAmIHJpdGVtW1JJVEVNX0ZJTEVdKSA9PSBzaXplb2Yocml0ZW1bUklURU1fRklMRV0pICkKKyAgICAgICAgcmV0dXJuIHJpX3JlbV9vYihvYiksIDA7CisKKyAgICByZXR1cm4gMTsKK30KKworCitwdWJsaWMgdm9pZCBSZW1vdmVJdGVtKCBtaXhlZCBmaWxlbmFtZSApCit7CisgICAgbWl4ZWQgKml0ZW1zOworICAgIGludCBpOworCisgICAgaWYgKCAhcG9pbnRlcnAoaXRlbXMgPSBRdWVyeVByb3AoUF9JVEVNUykpIHx8ICFzaXplb2YoaXRlbXMpICkKKyAgICAgICAgcmV0dXJuOworCisgICAgaWYgKCBwb2ludGVycChmaWxlbmFtZSkgKQorICAgICAgICBmb3IgKCBpID0gc2l6ZW9mKGZpbGVuYW1lKTsgaS0tOyApCisgICAgICAgICAgICBmaWxlbmFtZVtpXSA9IChzdHJpbmcpbWFzdGVyKCktPl9nZXRfcGF0aCggZmlsZW5hbWVbaV0sICI/IiApOworICAgIGVsc2UKKyAgICAgICAgZmlsZW5hbWUgPSAoc3RyaW5nKW1hc3RlcigpLT5fZ2V0X3BhdGgoIGZpbGVuYW1lLCAiPyIgKTsKKyAgCisgICAgU2V0UHJvcCggUF9JVEVNUywgZmlsdGVyKCBpdGVtcywgIydyaV9maWx0ZXIvKicqLywgZmlsZW5hbWUgKSApOworfQorCisKK3ByaXZhdGUgbWl4ZWQgX2RvX3JlZnJlc2goIG1peGVkIGl0ZW0gKQoreworICAgIHN0cmluZyBmaWxlOworICAgIG9iamVjdCBvYjsKKworICAgIGlmICggIXBvaW50ZXJwKGl0ZW0pIHx8IGl0ZW1bUklURU1fUkVGUkVTSF0gPT0gUkVGUkVTSF9OT05FICkKKyAgICAgICAgcmV0dXJuIGl0ZW07CisKKyAgICBpZiAoIHBvaW50ZXJwKGl0ZW1bUklURU1fRklMRV0pICkgCisgICAgICAgIGZpbGUgPSBpdGVtW1JJVEVNX0ZJTEVdW3JhbmRvbSggc2l6ZW9mKGl0ZW1bUklURU1fRklMRV0pICldOworICAgIGVsc2UKKyAgICAgICAgZmlsZSA9IGl0ZW1bUklURU1fRklMRV07CisKKyAgICBzd2l0Y2goIGl0ZW1bUklURU1fUkVGUkVTSF0gKXsKKyAgICBjYXNlIFJFRlJFU0hfTU9WRV9IT01FOgorICAgICAgICBpZiAoIG9iamVjdHAoaXRlbVtSSVRFTV9PQkpFQ1RdKSAmJgorICAgICAgICAgICAgIGVudmlyb25tZW50KGl0ZW1bUklURU1fT0JKRUNUXSkgIT0gTUUgKSB7CisgICAgICAgICAgICBpdGVtW1JJVEVNX09CSkVDVF0tPm1vdmUoIE1FLCBNX0dPfE1fTk9fQVRUQUNLICk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAvLyBmYWxsIHRocm91Z2gKKyAgICBjYXNlIFJFRlJFU0hfREVTVFJVQ1Q6CisgICAgICAgIGlmICggb2JqZWN0cChpdGVtW1JJVEVNX09CSkVDVF0pICkgCisgICAgICAgICAgICBicmVhazsgLy8gZWxzZSBGQUxMIFRIUk9VR0gKKyAgICAgICAgCisgICAgY2FzZSBSRUZSRVNIX1JFTU9WRToKKyAgICAgICAgaWYgKCBvYmplY3RwKGl0ZW1bUklURU1fT0JKRUNUXSkgJiYKKyAgICAgICAgICAgICBlbnZpcm9ubWVudChpdGVtW1JJVEVNX09CSkVDVF0pID09IE1FICkKKyAgICAgICAgICAgIGJyZWFrOyAvLyBlbHNlIEZBTEwgVEhST1VHSAorICAgICAgICAKKyAgICBkZWZhdWx0OgorICAgICAgICBpZiAoIHNpemVvZihpdGVtKSA+IFJJVEVNX1BST1BTICYmIGl0ZW1bUklURU1fUFJPUFNdID09IDEgKSB7CisgICAgICAgICAgICBvYiA9IGxvYWRfb2JqZWN0KGZpbGUpOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIG9iID0gY2xvbmVfb2JqZWN0KGZpbGUpOworCisgICAgICAgIG9iLT5tb3ZlKCBNRSwgTV9OT0NIRUNLfE1fTk9fQVRUQUNLICk7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgICAKKyAgICBpZiAoIG9iICl7CisgICAgICAgIGl0ZW1bUklURU1fT0JKRUNUXSA9IG9iOworICAgICAgICAKKyAgICAgICAgaWYgKCBzaXplb2YoaXRlbSkgPiBSSVRFTV9QUk9QUyAmJiBtYXBwaW5ncChpdGVtW1JJVEVNX1BST1BTXSkgKQorICAgICAgICAgICAgd2Fsa19tYXBwaW5nKCBpdGVtW1JJVEVNX1BST1BTXSwgc3ltYm9sX2Z1bmN0aW9uKCAiU2V0UHJvcCIsIG9iICkgKTsKKyAgICB9CisgICAgCisgICAgcmV0dXJuIGl0ZW07Cit9CisKKworLy8gcmVzZXQgaGFuZGxpbmc6IGNoZWNrIGhvdyB0aGUgaXRlbXMgc2hvdWxkIGJlIHJlZnJlc2hlZC4KK3ZvaWQgcmVzZXQoKSAKK3sKKyAgICBtaXhlZCAqaXRlbXM7CisKKyAgICBpZiAoICFwb2ludGVycChpdGVtcyA9IFF1ZXJ5UHJvcChQX0lURU1TKSkgKXsKKyAgICAgICAgU2V0UHJvcCggUF9JVEVNUywgKHt9KSApOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIAorICAgIFNldFByb3AoIFBfSVRFTVMsIG1hcCggaXRlbXMsICMnX2RvX3JlZnJlc2gvKicqLyApIC0gKHswfSkgKTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2NvbnRhaW5lci9saWdodC5jIGIvc3RkL2NvbnRhaW5lci9saWdodC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzNTQwMGYKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvY29udGFpbmVyL2xpZ2h0LmMKQEAgLTAsMCArMSwxNDkgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBjb250YWluZXIvbGlnaHQuYyAtLSBMaWNodHN5c3RlbSBmdWVyIENvbnRhaW5lcgorLy8KKy8vICRJZDogZGVzY3JpcHRpb24uYyA2OTg2IDIwMDgtMDgtMjIgMjE6MzI6MTVaIFplc3N0cmEgJAorCitpbmhlcml0ICIvc3RkL3RoaW5nL2xpZ2h0IjsKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcyxydHRfY2hlY2tzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxjb250YWluZXIuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisKKy8vIEJUVzogX3F1ZXJ5X2xhc3RfY29udGVudF9jaGFuZ2UoKSBzb2xsdGUgYmxvc3MgbmllIGF1Y2ggLTEgZnVlcgorLy8gdW5pbml0aWFsaXNpZXJ0IHp1cnVlY2tsaWVmZXJuLi4uCitwcml2YXRlIG5vc2F2ZSBpbnQgbGFzdF9saWdodF9jYWxjID0gLTE7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIDo6Y3JlYXRlKCk7CisgIC8vIHdpZXZpZWwgTGljaHQgc2NobHVja3QgZGVyIENvbnRhaW5lciBfbXVzc18gPiAwIHNlaW4hCisgIFNldFByb3AoUF9MSUdIVF9UUkFOU1BBUkVOQ1ksIDIpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7c2V0X25leHRfcmVzZXQoLTEpO30KKworCitzdGF0aWMgbWl4ZWQgX3F1ZXJ5X2xpZ2h0X3RyYW5zcGFyZW5jeSgpCit7CisgICBpZiAoUXVlcnlQcm9wKFBfVFJBTlNQQVJFTlQpKQorICAgICByZXR1cm4gUXVlcnkoUF9MSUdIVF9UUkFOU1BBUkVOQ1ksRl9WQUxVRSk7CisgICByZXR1cm4gOTk5OworfQorCitwdWJsaWMgaW50IGFkZF9saWdodF9zb3VyY2VzKGludCAqIHNvdXJjZXMpIHsKKyAgZmxvYXQgbGlnaHQgPSAwLjA7CisgIC8vcHJpbnRmKCJhbHMoJU8pOiAlT1xuIix0aGlzX29iamVjdCgpLHNvdXJjZXMpOworICAvLyBBbGxlIExpY2h0bGV2ZWwgd2VyZGVuIGFscyBFeHBvbmVudCB2b24gZSBhdWZnZWZhc3N0IHVuZCBkaWUgU3VtbWUgZGllc2VyCisgIC8vIFBvdGVuemVuIGdlYmlsZGV0LgorICBmb3JlYWNoKGludCBsIDogc291cmNlcykgeworICAgICBpZiAobCA+IDApCisgICAgICAgbGlnaHQgKz0gZXhwKGwpOworICAgICBlbHNlIGlmIChsIDwgMCkKKyAgICAgICBsaWdodCAtPSBleHAoYWJzKGwpKTsKKyAgICAgLy8gbD09MCBtdXNzIGlnbm9yaWVydCB3ZXJkZW4KKyAgfQorICAvLyBhbnNjaGxpZXNzZW5kIHdpcmQgYXVzIGRpZXNlciBTdW1tZSBkZXIgbmF0dWVybGljaGUgTG9nYXJpdGhtdXMKKyAgLy8gYmVyZWNobmV0LgorICAvLyBhdWYgZGllc2UgV2Vpc2UgaGFiZW4gaG9laGVyZSBMaWNodGxldmVsIHVlYmVycHJvcG9ydGlvbmFsIHZpZWwgRWluZmx1c3MKKyAgLy8gYXVmIGRpZSBIZWxsaWdrZWl0IGltIFJhdW0sIGtsZWluZSBMaWNodGxldmVsIGZhbGxlbiBhYmVyIG5pY2h0IGtvbXBsZXR0CisgIC8vIHJhdXMuCisgIGlmIChsaWdodCA+IDApIHsKKyAgICAgIGxpZ2h0ID0gbG9nKGxpZ2h0KTsKKyAgfQorICBlbHNlIGlmIChsaWdodCA8IDApIHsKKyAgICAgIGxpZ2h0ID0gLWxvZyhhYnMobGlnaHQpKTsKKyAgfQorCisgIC8vcHJpbnRmKCJhbHMoKTogJU9cbiIsbGlnaHQpOworICAvLyBydW5kZW4gdW5kIGFscyBpbnQgenVydWVja2dlYmVuLgorICBpZiAobGlnaHQgPj0gMCkKKyAgICByZXR1cm4gdG9faW50KGxpZ2h0KzAuNSk7CisgIC8vZWxzZQorICByZXR1cm4gdG9faW50KGxpZ2h0LTAuNSk7Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X3RvdGFsX2xpZ2h0KCkKK3sKKyAgaW50IHRvdGFsbGlnaHQ7CisKKyAgaWYgKCBfcXVlcnlfbGFzdF9jb250ZW50X2NoYW5nZSgpID09IGxhc3RfbGlnaHRfY2FsYyApCisgICAgcmV0dXJuIFF1ZXJ5KFBfVE9UQUxfTElHSFQpOworCisgIC8vIGVpZ2VuZXMgUF9MSUdIVCB1bmQgUF9UT1RBTF9MSUdIVCBkZXIgZW50aGFsdGVuZW4gT2JqZWt0ZSB2ZXJyZWNobmVuCisgIGludCBpbnRsaWdodCA9IGFkZF9saWdodF9zb3VyY2VzKAorICAgICAgYWxsX2ludmVudG9yeSgpLT5RdWVyeVByb3AoUF9UT1RBTF9MSUdIVCkgKyAoe1F1ZXJ5UHJvcChQX0xJR0hUKX0pKTsKKyAgLy8gUF9JTlRfTElHSFQgKGdlcnVuZGV0KSBhYnNwZWljaGVybgorICBTZXQoUF9JTlRfTElHSFQsIGludGxpZ2h0LCBGX1ZBTFVFKTsKKworICAvLyBMaWNodCBuYWNoIGF1c3NlbiBtdXNzIENvbnRhaW5lcnRyYW5zcGFyZW56IGJlcnVlY2tzaWNodGlnZW4uCisgIGlmIChpbnRsaWdodCA+IDApIHsKKyAgICB0b3RhbGxpZ2h0ID0gaW50bGlnaHQgLSBRdWVyeVByb3AoUF9MSUdIVF9UUkFOU1BBUkVOQ1kpOworICAgIGlmICh0b3RhbGxpZ2h0IDwgMCkKKyAgICAgIHRvdGFsbGlnaHQgPSAwOworICB9CisgIGVsc2UgeworICAgIHRvdGFsbGlnaHQgPSBpbnRsaWdodCArIFF1ZXJ5UHJvcChQX0xJR0hUX1RSQU5TUEFSRU5DWSk7CisgICAgaWYgKHRvdGFsbGlnaHQgPiAwKQorICAgICAgdG90YWxsaWdodCA9IDA7CisgIH0KKyAgLy9wcmludGYoIl9xdWVyeV90b3RhbF9saWdodCglTyk6ICVPXG4iLHRoaXNfb2JqZWN0KCksdG90YWxsaWdodCk7CisKKyAgbGFzdF9saWdodF9jYWxjID0gX3F1ZXJ5X2xhc3RfY29udGVudF9jaGFuZ2UoKTsKKworICAvLyBSdW5kZW4gdW5kIEtvbnZlcnNpb24gbmFjaCBpbnQgbmljaHQgdmVyZ2Vzc2VuLi4uCisgIGlmICh0b3RhbGxpZ2h0ID4gMCkKKyAgICByZXR1cm4gU2V0UHJvcChQX1RPVEFMX0xJR0hULCB0b19pbnQodG90YWxsaWdodCArIDAuNSkpOworICAvL2Vsc2UKKyAgcmV0dXJuIFNldFByb3AoUF9UT1RBTF9MSUdIVCwgdG9faW50KHRvdGFsbGlnaHQgLSAwLjUpKTsKK30KKworc3RhdGljIGludCBfcXVlcnlfaW50X2xpZ2h0KCkKK3sKKyAgIGludCBpbnRsaWdodCwgZW52bGlnaHQ7CisKKyAgIGlmICggX3F1ZXJ5X2xhc3RfY29udGVudF9jaGFuZ2UoKSAhPSBsYXN0X2xpZ2h0X2NhbGMgKQorICAgICAgIF9xdWVyeV90b3RhbF9saWdodCgpOworCisgICAvLyBQX0lOVF9MSUdIVCBkZXMgZW52aXJvbm1lbnRzIGthbm4gc2ljaCBuYXR1ZXJsaWNoIGFlbmRlcm4gX29obmVfIGRhcworICAgLy8gZXR3YXMgYW4gZWluZW0gY29udGFpbmVyIGdlYWVuZGVydCB3aXJkLiBEYWhlciBBdXN3ZXJ0dW5nIGplZGVzIG1hbAorICAgLy8gbmV1IGFrdHVhbGlzaWVyZW4uCisgICBpZiAoIWVudmlyb25tZW50KCkKKyAgICAgICB8fCAhKGVudmxpZ2h0PShpbnQpZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfSU5UX0xJR0hUKSkpCisgICAgICByZXR1cm4gUXVlcnkoUF9JTlRfTElHSFQsIEZfVkFMVUUpOworICAgZWxzZSB7CisgICAgICBpbnRsaWdodCA9IFF1ZXJ5KFBfSU5UX0xJR0hULCBGX1ZBTFVFKTsKKyAgICAgIGludCB0cmFuc3BhcmVuY3kgPSBRdWVyeVByb3AoUF9MSUdIVF9UUkFOU1BBUkVOQ1kpOworCisgICAgICAvLyBiZWkgZWluZW0gdHJhbnNwYXJlbnRlbSBDb250YWluZXIga2FubiBuYXR1ZXJsaWNoIGRhcyBMaWNodCBkZXMKKyAgICAgIC8vIGVudmlyb25tZW50cyBkZW4gQ29udGFpbmVyIGF1Y2ggYXVzbGV1Y2h0ZW4uLi4uCisgICAgICAvLyAoQW5tZXJrdW5nOiBpbiBkZW0gTGljaHQgdm9uIGRyYXVzc2VuIGlzdCB1bnNlciBMaWNodGFudGVpbAorICAgICAgLy8gbmF0dWVybGljaCBhdWNoIGRyaW4sIGdlZGFlbXBmdCB1bSBkaWUgVHJhbnNwYXJlbnogKHJhdXMgdW5kIHJlaW4pLgorICAgICAgLy8gSWNoIHZlcm5hY2hsYWVzc2lnZSBkYXMuKQorICAgICAgaWYgKGFicyhlbnZsaWdodCkgPiB0cmFuc3BhcmVuY3kpIHsKKyAgICAgICAgaWYgKGVudmxpZ2h0ID4gMCkKKyAgICAgICAgICAgIGVudmxpZ2h0IC09IHRyYW5zcGFyZW5jeTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgZW52bGlnaHQgKz0gdHJhbnNwYXJlbmN5OworICAgICAgICAvLyBqZXR6dCBMaWNodCB2b24gYXVzc2VuIHVuZCBpbm5lbiB2ZXJyZWNobmVuCisgICAgICAgIGludGxpZ2h0ID0gYWRkX2xpZ2h0X3NvdXJjZXMoKHtpbnRsaWdodCwgZW52bGlnaHR9KSk7CisgICAgICB9CisgICAgICAvLyBlbHNlOiBudXIgUF9JTlRfTElHSFQsIExpY2h0IGRlcyBFbnZpcm9ubWVudHMga2VpbmUgQmVkZXV0dW5nCisgICB9CisgICByZXR1cm4gaW50bGlnaHQ7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9saWdodChpbnQgbGlnaHQpCit7CisgIGxhc3RfbGlnaHRfY2FsYz0tMTsKKworICByZXR1cm4gOjpfc2V0X2xpZ2h0KGxpZ2h0KTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2NvbnRhaW5lci9tb25leWhhbmRsZXIuYyBiL3N0ZC9jb250YWluZXIvbW9uZXloYW5kbGVyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWUyNTQ1MwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9jb250YWluZXIvbW9uZXloYW5kbGVyLmMKQEAgLTAsMCArMSw1MyBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGNvbnRhaW5lci9tb25leWhhbmRsZXIuYyAtLSBtb25leSBoYW5kbGVyIGZvciBjb250YWluZXIKKy8vCisvLyAkSWQ6IG1vbmV5aGFuZGxlci5jIDY3MzggMjAwOC0wMi0xOSAxODo0NjoxNFogSHVtbmkgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxtb25leS5oPgorCitwdWJsaWMgaW50IEFkZE1vbmV5KCBpbnQgYW1vdW50ICkKK3sKKyAgb2JqZWN0IG9iOworICBpbnQgcmV0OworCisgIGlmICggIWFtb3VudCApCisgICAgcmV0dXJuIDE7CisgICAgCisgIG9iID0gY2xvbmVfb2JqZWN0KCBHRUxEICk7CisgIG9iLT5TZXRQcm9wKCBQX0FNT1VOVCwgYW1vdW50ICk7CisKKyAgcmV0PW9iLT5tb3ZlKCB0aGlzX29iamVjdCgpLCBNX1BVVHxNX01PVkVfQUxMICk7CisgIC8vIEJlaSBmZWhsZXJoYWZ0ZW0gbW92ZSBnZ2YuIHdpZWRlciB6ZXJzdG9lcmVuLgorICBpZiAoKHJldCAhPSBNT1ZFX09LKQorICAgICAgJiYgb2IpCisgIHsKKyAgICBvYi0+cmVtb3ZlKDEpOworICB9CisgIHJldHVybiByZXQ7Cit9CisKK3B1YmxpYyBpbnQgUXVlcnlNb25leSgpCit7CisgIG9iamVjdCBtb25leTsKKyAgaW50IGdlbGQ7CisKKyAgaWYgKCBtb25leSA9IHByZXNlbnRfY2xvbmUoR0VMRCwgdGhpc19vYmplY3QoKSkgKQorICAgIGdlbGQgPSBtb25leS0+UXVlcnlQcm9wKFBfQU1PVU5UKTsKKworICBpZiAoIG1vbmV5ID0gcHJlc2VudChHRUxEQk9FUlNFX01JVF9HRUxELCB0aGlzX29iamVjdCgpKSApCisgICAgZ2VsZCArPSBtb25leS0+UXVlcnlQcm9wKFBfQU1PVU5UKTsKKworICByZXR1cm4gZ2VsZDsKK30KZGlmZiAtLWdpdCBhL3N0ZC9jb250YWluZXIvcmVzdHJpY3Rpb25zLmMgYi9zdGQvY29udGFpbmVyL3Jlc3RyaWN0aW9ucy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNkYTVjOWQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvY29udGFpbmVyL3Jlc3RyaWN0aW9ucy5jCkBAIC0wLDAgKzEsNDgwIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gY29udGFpbmVyL3Jlc3RyaWN0aW9ucy5jIC0tIGNvbnRhaW5lciByZXN0cmljdGlvbnMKKy8vCisvLyAkSWQ6IHJlc3RyaWN0aW9ucy5jIDkwMjAgMjAxNS0wMS0xMCAyMTo0OTo0MVogWmVzc3RyYSAkCisKKy8vIFRoaXMgaXMgYSBzaW1wbGUgY29udGFpbmVyIHRvIHB1dCBvYmplY3RzIGluLiBJdCBkZWZpbmVzIGFsbCBmdW5jdGlvbnMKKy8vIHdoaWNoIGFyZSBuZWNlc3NhcnkgdG8gZGVzY3JpYmUgYW4gb2JqZWN0IHdoaWNoIGNhbiBiZSBmaWxsZWQgd2l0aAorLy8gb3RoZXIgdGhpbmdzLgorLy8KKy8vIEl0IHdpbGwgc3VwcG9ydCByZXN0cmljdGlvbnMgZm9yIHZvbHVtZSwgd2VpZ2h0IGV0Yy4KKy8vCisvLyBUaGUgZm9sbG93aW5nIHByb3BlcnRpZXMgYXJlIGRlZmluZWQ6CisvLyBQX01BWF9XRUlHSFQgLSBtYXhpbXVtIHdlaWdodCB3aGljaCBjb250YWluZXIgY2FuIGNhcnJ5CisvLyBQX1RPVEFMX1dFSUdIVCAtIHRvdGFsIHdlaWdodCwgd2l0aCBjb250ZW50cy4KKy8vIFBfV0VJR0hUIC0gdGhlIHdlaWdodCBvZiB0aGUgY29udGFpbmVyIHdpdGhvdXQgY29udGVudHMKKy8vCisvLyBGdW5jdGlvbnMgZm9yIG1hbmlwdWxhdGlvbiBvZiB3ZWlnaHQKKy8vIE1heUFkZFdlaWdodCh3ZWlnaHQpIC0gQ2FuIDx3ZWlnaHQ+IGJlIGluc2VydGVkPworLy8gQWRkV2VpZ2h0KHdlaWdodCkgLSBBZGQgYW4gYW1vdW50IG9mIDx3ZWlnaHQ+CisvLworLy8gSU1QT1JUQU5UOiB1bml0IGVxdWFscyAxIGdyYW0KKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworLy8jcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlICIvc3lzL3RoaW5nL3Byb3BlcnRpZXMuaCIKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisKKy8vIGxvY2FsIHByb3BlcnRpZXMgcHJvdG90eXBlcworc3RhdGljIGludCBfcXVlcnlfdG90YWxfd2VpZ2h0KCk7CisKKworcHJpdmF0ZSBub3NhdmUgaW50IExhc3RXZWlnaHRDYWxjLCBjb250ZW50cywgTGFzdE9iamVjdENvdW50LCBvYmpjb3VudDsKK3ByaXZhdGUgbm9zYXZlIGludCBsYXN0X2NvbnRlbnRfY2hhbmdlOworCisKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgICBTZXQoIFBfV0VJR0hUX1BFUkNFTlQsIDUwICk7CisgICAgU2V0KCBQX1RPVEFMX1dFSUdIVCwgTk9TRVRNRVRIT0QsIEZfU0VUX01FVEhPRCApOworICAgIFNldCggUF9UT1RBTF9XRUlHSFQsIFBST1RFQ1RFRCwgRl9NT0RFICk7CisgICAgU2V0KCBQX01BWF9PQkpFQ1RTLCAxMDAgKTsKKyAgICBTZXQoIFBfVE9UQUxfT0JKRUNUUywgTk9TRVRNRVRIT0QsIEZfU0VUX01FVEhPRCApOworICAgIFNldCggUF9UT1RBTF9PQkpFQ1RTLCBQUk9URUNURUQsIEZfTU9ERSApOworICAgIExhc3RXZWlnaHRDYWxjID0gLTE7CisgICAgTGFzdE9iamVjdENvdW50ID0gLTE7Cit9CisKKworc3RhdGljIGludCBfcXVlcnlfbGFzdF9jb250ZW50X2NoYW5nZSgpCit7CisgICAgcmV0dXJuIGxhc3RfY29udGVudF9jaGFuZ2U7Cit9CisKKworLy8gYWJzaWNodGxpY2ggcHVibGljLCBkYSBlcyB2b24gZGVyIHNpbXVsX2VmdW4uYyAqZGlyZWt0KiBhdWZnZXJ1ZmVuCisvLyB3aXJkIGF1cyBQZXJmb3JtYW5jZWdydWVuZGVuIQorcHVibGljIHZhcmFyZ3MgaW50IF9zZXRfbGFzdF9jb250ZW50X2NoYW5nZSggbWl4ZWQgd2VydCApCit7CisgICAgLy8gRGVyIHVlYmVyZ2ViZW5lIFdlcnQgaXN0IHVuZXJoZWJsaWNoLiBEaWUgUHJvcGVydHkKKyAgICAvLyBQX0xBU1RfQ09OVEVOVF9DSEFOR0Ugd2lyZCBzbyBvZGVyIHNvIGJlaSBqZWRlbSBTZXRQcm9wKCktCisgICAgLy8gQXVmcnVmIHVtIGVpbnMgZXJob2VodCwgdW0gZGVyIDJzLSJVbnNjaGFlcmZlIiB2b24gdGltZSgpCisgICAgLy8gYXVzIGRlbSBXZWcgenUgZ2VoZW4uCisgICAgcmV0dXJuICsrbGFzdF9jb250ZW50X2NoYW5nZTsKK30KKworCitpbnQgcXVlcnlfd2VpZ2h0X2NvbnRlbnRzKCkKK3sKKyAgICBvYmplY3QgKm9ianM7CisgICAgaW50IHcsIHcyLCBpOworCisgICAgaWYgKCBsYXN0X2NvbnRlbnRfY2hhbmdlID09IExhc3RXZWlnaHRDYWxjICkKKyAgICAgICAgcmV0dXJuIGNvbnRlbnRzOworICAgIAorICAgIHcgPSAwOworICAgIG9ianMgPSBhbGxfaW52ZW50b3J5KHRoaXNfb2JqZWN0KCkpOworICAgIGkgPSBzaXplb2Yob2Jqcyk7CisgICAgCisgICAgd2hpbGUgKCBpLS0gKXsKKyAgICAgICAgaWYgKCAhKHcyID0gKGludClvYmpzW2ldLT5RdWVyeVByb3AoUF9UT1RBTF9XRUlHSFQpKSApCisgICAgICAgICAgICB3MiA9IChpbnQpb2Jqc1tpXS0+UXVlcnlQcm9wKFBfV0VJR0hUKTsKKyAgICAgICAgdyArPSB3MjsKKyAgICB9CisgICAgCisgICAgTGFzdFdlaWdodENhbGMgPSBsYXN0X2NvbnRlbnRfY2hhbmdlOworICAgIHJldHVybiBjb250ZW50cyA9IHc7Cit9CisKKworc3RhdGljIGludCBfcXVlcnlfdG90YWxfb2JqZWN0cygpCit7CisgIGlmICggbGFzdF9jb250ZW50X2NoYW5nZSA9PSBMYXN0T2JqZWN0Q291bnQgKQorICAgICAgcmV0dXJuIG9iamNvdW50OworCisgIG9iamNvdW50ID0gc2l6ZW9mKCBmaWx0ZXJfb2JqZWN0cyggYWxsX2ludmVudG9yeSgpLCAic2hvcnQiICkgKTsKKyAgTGFzdE9iamVjdENvdW50ID0gbGFzdF9jb250ZW50X2NoYW5nZTsKKyAgcmV0dXJuIG9iamNvdW50OworfQorCisKKy8vIGRpZXNlIEZ1bmt0aW9uIHNvbGx0ZSB2b24gUmFldW1lbiBuYXR1ZXJsaWNoIHVlYmVyc2NocmllYmVuIHdlcmRlbi4uLgoraW50IE1heUFkZE9iamVjdCggb2JqZWN0IG9iICkKK3sKKyAgICBpZiAob2IpIHsKKyAgICAgICAgaWYgKCAhb2ItPnNob3J0KCkgKQorICAgICAgICAgICAgcmV0dXJuIDE7IC8vIGludmlzLU9iamVrdGUgZHVlcmZlbiBpbW1lcgorICAgICAgICAKKyAgICAgICAgaWYgKCBvYiA9PSBNRSB8fCBlbnZpcm9ubWVudChvYikgPT0gTUUpCisgICAgICAgICAgICByZXR1cm4gMTsgLy8gb2JqZWt0IGlzdCBzY2hvbiBkcmluCisgICAgfQorICAgIAorICAgIHJldHVybiAoUXVlcnlQcm9wKFBfVE9UQUxfT0JKRUNUUykgPCBRdWVyeVByb3AoUF9NQVhfT0JKRUNUUykpOworfQorCisKKyNkZWZpbmUgRU5WIGVudmlyb25tZW50CisjZGVmaW5lIFBPIHByZXZpb3VzX29iamVjdCgpCisKK2ludCBNYXlBZGRXZWlnaHQoIGludCB3ICkKK3sKKyAgICBpbnQgbncsIGF3OworCisgICAgLy8gd2FzIG5peCB3aWVndCwgcGFzc3QKKyAgICBpZiAoIHcgPD0gMCApCisgICAgICAgIHJldHVybiAwOworCisgICAgbncgPSB3OyAvLyBHZXdpY2h0IGltIG5ldWVuIENvbnRhaW5lcgorICAgIGF3ID0gMDsgLy8gR2V3aWNodCBmdWVyIGRhcyBlbnYoKQorCisgICAgLy8gVm9uIFJhdW0gaW4gQmVoYWVsdGVyIGltIFNwaWVsZXI6IENvbnRhaW5lciBzaWVodCB2b2xsZXMgR2V3aWNodCAobnc9dyksCisgICAgLy8gQ2hlY2sgaW0gZW52KCkgKFNwaWVsZXIpIG1pdCByZWR1emllcnRlbSBHZXdpY2h0LgorICAgIGlmICggRU5WKCkgJiYgUE8gJiYgRU5WKFBPKSAhPSBFTlYoKSApCisgICAgICAgIGF3ID0gUXVlcnlQcm9wKFBfV0VJR0hUX1BFUkNFTlQpICogdyAvIDEwMCB8fCAxOworCisgICAgaWYgKCBQTyAmJiBFTlYoUE8pICYmIEVOVihFTlYoUE8pKSApeworICAgICAgICAvLyBXZW5uIGRhcyBPYmpla3QgZWluIGVudigpIGhvY2hiZXdlZ3Qgd2lyZCwgd2lyZCBkYXMgR2V3aWNodCBpbSBhbHRlbgorICAgICAgICAvLyBDb250YWluZXIgYWJnZXpvZ2VuLiBXZWl0ZXJlciBDaGVjayBpbSBlbnYoKSBpc3QgdW5ub2V0aWcgKGF3PTApLgorICAgICAgICBpZiAoIEVOVihFTlYoUE8pKSA9PSBNRSApCisgICAgICAgICAgICBudyA9IHcgLSAoaW50KUVOVihQTyktPlF1ZXJ5UHJvcChQX1dFSUdIVF9QRVJDRU5UKSAqIHcgLyAxMDA7CisgICAgICAgIC8vIEVpbmUgRWJlbmUgdGllZmVyIGJld2VnZW46IFRlc3QgaW0gbmV1ZW4gQ29udGFpbmVyIG1pdCB1bnZlcmFlbmRlcnRlbQorICAgICAgICAvLyBHZXdpY2h0OyBDaGVjayBpbSBlbnYoKSBtaXQgdW0gR2V3aWNodHNyZWR1a3Rpb24gdmVycmluZ2VydGVtIEdld2ljaHQKKyAgICAgICAgZWxzZSBpZiAoIHByZXNlbnQoIE1FLCBFTlYoUE8pICkgKQorICAgICAgICAgICAgYXcgPSBRdWVyeVByb3AoUF9XRUlHSFRfUEVSQ0VOVCkgKiB3IC8gMTAwIC0gdzsKKyAgICAgICAgLy8gQXVmIGRlcnNlbGJlbiBFYmVuZSB2ZXJzY2hpZWJlbiAodm9uIFBha2V0IGluIEJldXRlbCk6CisgICAgICAgIC8vIE5ldWVyIENvbnRhaW5lciBzaWVodCB2b2xsZXMgR2V3aWNodCAobnc9dyksIENoZWNrIGltIGVudigpIG1pdAorICAgICAgICAvLyBEaWZmZXJlbnogYXVzIEdld2ljaHQgaW4gQ29udGFpbmVyMSB1bmQgaW4gQ29udGFpbmVyMi4KKyAgICAgICAgZWxzZSBpZiAoIEVOVihFTlYoRU5WKFBPKSkpICYmIEVOVigpID09IEVOVihFTlYoUE8pKSApCisgICAgICAgICAgICBhdyA9IFF1ZXJ5UHJvcChQX1dFSUdIVF9QRVJDRU5UKSAqIHcgLyAxMDAKKyAgICAgICAgICAgICAgICAtICgoaW50KUVOVihQTyktPlF1ZXJ5UHJvcChQX1dFSUdIVF9QRVJDRU5UKSAqIHcgLyAxMDAgfHwgMSk7CisgICAgfQorCisgICAgaWYgKCBxdWVyeV93ZWlnaHRfY29udGVudHMoKSArIG53ID4gUXVlcnlQcm9wKFBfTUFYX1dFSUdIVCkgKQorICAgICAgICAvLyBDb250YWluZXIga2FubiBHZXdpY2h0IG5pY2h0IG1laHIgYXVmbmVobWVuCisgICAgICAgIHJldHVybiAtMTsKKyAgICAKKyAgICBpZiAoIGF3ICYmIEVOVigpLT5NYXlBZGRXZWlnaHQoYXcpIDwgMCApCisgICAgICAgIC8vIFVtZ2VidW5nIGRlcyBDb250YWluZXJzIGthbm4gR2V3aWNodCBuaWNodCBtZWhyIGF1Zm5laG1lbgorICAgICAgICByZXR1cm4gLTI7CisgICAgCisgICAgcmV0dXJuIDA7Cit9CisKKworLyogUmVkZWZpbmUgUHJldmVudEluc2VydCgpIHRvIHByZXZlbnQgaW5zZXJ0aW5nIG9mIHNwZWNpYWwgb2JqZWN0cy4gSWYKKyAqIGEgdmFsdWUgZ3JlYXRlciAwIGlzIHJldHVybmVkIHRoZSBvYmplY3Qgb2IgY2FuJ3QgYmUgaW5zZXJ0ZWQgaW4gdGhlCisgKiBjb250YWluZXIuCisgKi8KK3B1YmxpYyBpbnQgUHJldmVudEluc2VydCggb2JqZWN0IG9iICkgeyByZXR1cm4gMDsgfQorcHVibGljIGludCBQcmV2ZW50TGVhdmUoIG9iamVjdCBvYiwgbWl4ZWQgZGVzdCApIHsgcmV0dXJuIDA7IH0KK3B1YmxpYyBpbnQgUHJldmVudEluc2VydExpdmluZyggb2JqZWN0IG9iICkgeyByZXR1cm4gMDsgfQorcHVibGljIGludCBQcmV2ZW50TGVhdmVMaXZpbmcoIG9iamVjdCBvYiwgbWl4ZWQgZGVzdCApIHsgcmV0dXJuIDA7IH0KK3B1YmxpYyB2b2lkIE5vdGlmeUluc2VydChvYmplY3Qgb2IsIG9iamVjdCBvbGRlbnYpIHsgfQorCisvLyAqKioqIGxvY2FsIHByb3BlcnR5IG1ldGhvZHMKK3N0YXRpYyBpbnQgX3F1ZXJ5X3RvdGFsX3dlaWdodCgpIAoreyAKKyAgICByZXR1cm4gUXVlcnlQcm9wKFBfV0VJR0hUKSArCisgICAgICAgIChRdWVyeVByb3AoUF9XRUlHSFRfUEVSQ0VOVCkgKiBxdWVyeV93ZWlnaHRfY29udGVudHMoKSAvIDEwMCk7IAorfQorCisKKy8vIEhpbGZzZnVua3Rpb24KK3N0YXRpYyBpbnQgX2JlaGFsdGVuKCBvYmplY3Qgb2IsIHN0cmluZyB1aWQgKQoreworICAgIHJldHVybiAoc3RyaW5nKW9iLT5RdWVyeVByb3AoUF9LRUVQX09OX1NFTEwpID09IHVpZDsKK30KKworCisvKgorICoKKyAqIGdldCBhIGxpc3Qgb2YgYWxsIGNvbnRhaW5lZCBvYmplY3RzIG1hdGNoaW5nIGEgY29tcGxleCBkZXNjcmlwdGlvbgorICoKKyAqLworCisjZGVmaW5lIFBPU19JTlZFUlMgICAweDAxICAvKiBudXIgenVyIGZ1bmt0aW9uc2ludGVybmVuIFZlcndlbmR1bmcgKi8KKyNkZWZpbmUgUE9TX0xFVFpURVMgIDB4MDIgIC8qIG51ciB6dXIgZnVua3Rpb25zaW50ZXJuZW4gVmVyd2VuZHVuZyAqLworCitvYmplY3QgKnByZXNlbnRfb2JqZWN0cyggc3RyaW5nIGNvbXBsZXhfZGVzYyApCit7CisgICAgaW50IGk7ICAgICAgICAgIC8vIFphZWhsZXJ2YXJpYWJsZQorICAgIGludCBtZXRoOyAgICAgICAvLyAweDAxID0gaW52ZXJzPywgIDB4MDIgPSBsZXR6dGVzPworICAgIG9iamVjdCBvYjsgICAgICAvLyBlaW56ZWxuZXMgdGVtcG9yYWVyZXMgT2JqZWt0CisgICAgb2JqZWN0ICpvYnM7ICAgIC8vIGxpc3RlIGRlciBhdXNnZXdhZWhsdGVuIE9iamVrdGUKKyAgICBvYmplY3QgKmVyZzsgICAgLy8genVtIHNhbW1lbG4gYmlzIGVzIG5hY2hoZXIgenVydWVja2dlZ2ViZW4gd2lyZC4uLgorICAgIHN0cmluZyAqc3RybHN0OyAvLyBsaXN0ZSBhbGxlciBHcnVwcGVuIGRpZSBtaXQgQU5EIHZlcmtudWVwZnQgc2luZAorICAgIG9iamVjdCBoYXVmZW47CisKKyAgICBzdHJsc3QgPSBhbGxvY2F0ZSgyKTsKKyAgICAKKyAgICBpZiAoIHNzY2FuZiggY29tcGxleF9kZXNjLCAiJXMgYXVzc2VyICVzIiwgc3RybHN0WzBdLCBzdHJsc3RbMV0pID09IDIgKXsKKyAgICAgICAgZXJnID0gcHJlc2VudF9vYmplY3RzKCBzdHJsc3RbMF0gKTsKKyAgICAgICAgb2JzID0gcHJlc2VudF9vYmplY3RzKCBzdHJsc3RbMV0gKTsKKyAgICAgICAgcmV0dXJuIGVyZy1vYnM7CisgICAgfQorICAgIAorICAgc3RybHN0ID0gZXhwbG9kZSggY29tcGxleF9kZXNjLCAiIHVuZCAiICk7CisgICBlcmcgPSAoe30pOworICAgCisgICBmb3IgKCBpID0gc2l6ZW9mKHN0cmxzdCk7IGktLTsgKQorICAgeworICAgICAgIGNvbXBsZXhfZGVzYyA9IHN0cmxzdFtpXTsKKyAgICAgICAvLyBhdWYgbGV0enRlL2xldHp0ZXMvbGV0enRlbiBwcnVlZmVuLi4uCisgICAgICAgaWYgKCBjb21wbGV4X2Rlc2NbMC4uNV0gPT0gImxldHp0ZSIgKXsKKyAgICAgICAgICAgc3dpdGNoKCBjb21wbGV4X2Rlc2NbNi4uNl0gKXsKKyAgICAgICAgICAgY2FzZSAiICI6CisgICAgICAgICAgICAgICBtZXRoIHw9IFBPU19MRVRaVEVTOworICAgICAgICAgICAgICAgY29tcGxleF9kZXNjID0gY29tcGxleF9kZXNjWzcuLl07CisgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgY2FzZSAicyI6CisgICAgICAgICAgIGNhc2UgIm4iOgorICAgICAgICAgICBjYXNlICJtIjoKKyAgICAgICAgICAgY2FzZSAiciI6CisgICAgICAgICAgICAgICBpZiAoIGNvbXBsZXhfZGVzY1s3Li43XSAhPSAiICIgKQorICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgbWV0aCB8PSBQT1NfTEVUWlRFUzsKKyAgICAgICAgICAgICAgIGNvbXBsZXhfZGVzYyA9IGNvbXBsZXhfZGVzY1s4Li5dOworICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgIH0KKyAgICAgICB9CisKKyAgICAgICAvLyBhdWYgdmVybmVpbnVuZyBwcnVlZmVuCisgICAgICAgaWYgKCBjb21wbGV4X2Rlc2NbMC4uNV0gPT0gIm5pY2h0ICIgKXsKKyAgICAgICAgICAgbWV0aCB8PSBQT1NfSU5WRVJTOworICAgICAgICAgICBjb21wbGV4X2Rlc2MgPSBjb21wbGV4X2Rlc2NbNi4uXTsKKyAgICAgICB9CisKKyAgICAgICBvYnM9KHt9KTsKKyAgICAgICAvLyBudW4gbmFjaCBNYWluLUlkcyAoR3J1cHBlbikgc3VjaGVuLi4uCisgICAgICAgaWYgKCBtZXRoICYgUE9TX0xFVFpURVMgKQorICAgICAgIHsgLy8gZ2VodCBlcyBudXIgdW0gZGVuIGxldHp0ZW4gR2VnZW5zdGFuZD8KKyAgICAgICAgICAgc3dpdGNoKCBjb21wbGV4X2Rlc2MgKXsKKyAgICAgICAgICAgY2FzZSAid2FmZmUiOgorICAgICAgICAgICAgICAgb2JzID0gZmlsdGVyX29iamVjdHMoIGFsbF9pbnZlbnRvcnkoKSwgIlF1ZXJ5UHJvcCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUF9XRUFQT05fVFlQRSApOworICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAKKyAgICAgICAgICAgY2FzZSAicnVlc3R1bmciOgorICAgICAgICAgICAgICAgb2JzID0gZmlsdGVyX29iamVjdHMoIGFsbF9pbnZlbnRvcnkoKSwgIlF1ZXJ5UHJvcCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUF9BUk1PVVJfVFlQRSApOworICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgCisgICAgICAgICAgIGNhc2UgImtsZWlkdW5nIjoKKyAgICAgICAgICAgICAgIG9icyA9IGZpbHRlcl9vYmplY3RzKCBhbGxfaW52ZW50b3J5KCksICJJc0Nsb3RoaW5nIik7CisgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgIAorICAgICAgICAgICBjYXNlICJ2ZXJzY2hpZWRlbmVtIjoKKyAgICAgICAgICAgY2FzZSAidmVyc2NoaWVkZW5lcyI6CisgICAgICAgICAgICAgICBvYnMgPSBhbGxfaW52ZW50b3J5KCk7CisgICAgICAgICAgICAgICBvYnMgLT0gZmlsdGVyX29iamVjdHMoIG9icywgIlF1ZXJ5UHJvcCIsIFBfV0VBUE9OX1RZUEUgKTsKKyAgICAgICAgICAgICAgIG9icyAtPSBmaWx0ZXJfb2JqZWN0cyggb2JzLCAiUXVlcnlQcm9wIiwgUF9BUk1PVVJfVFlQRSApOworICAgICAgICAgICAgICAgb2JzIC09IGZpbHRlcl9vYmplY3RzKCBvYnMsICJJc0Nsb3RoaW5nIik7CisgICAgICAgICAgICAgICBvYnMgLT0gZmlsdGVyKCBvYnMsICMnbGl2aW5nLyonKi8gKTsKKyAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAKKyAgICAgICAgICAgY2FzZSAiZWlnZW5lcyI6CisgICAgICAgICAgIGNhc2UgIm1laW5zIjoKKyAgICAgICAgICAgICAgIGlmIChvYmplY3RwKGhhdWZlbj1wcmVzZW50KCJcbmhhdWZlbiAiKworICAgICAgICAgICAgICAgICAgICAgdGhpc19wbGF5ZXIoKS0+bmFtZShXRU0pKSkpIHsKKyAgICAgICAgICAgICAgICAgIG9icyA9IGFsbF9pbnZlbnRvcnkoaGF1ZmVuKTsKKyAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgIC8vIGtlaW4gYnJlYWs7LCBGYWxsLXRocm91Z2ghCisgICAgICAgICAgIGNhc2UgImJlaGFsdGVuZW0iOgorICAgICAgICAgICBjYXNlICJiZWhhbHRlbmVzIjoKKyAgICAgICAgICAgICAgIG9icyArPSBmaWx0ZXIoIGFsbF9pbnZlbnRvcnkoKSwgIl9iZWhhbHRlbiIsIE1FLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXR1aWQodGhpc19wbGF5ZXIoKSB8fCBwcmV2aW91c19vYmplY3QoKSkgKTsKKworICAgICAgICAgICAgICAgb2JzICs9IChRdWVyeVByb3AoUF9BUk1PVVJTKSB8fCAoe30pKQorICAgICAgICAgICAgICAgICAgICsgKHsgUXVlcnlQcm9wKFBfV0VBUE9OKSB9KSAtICh7IDAgfSk7CisgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgIGNhc2UgImdlZ2Vuc3RhbmQiOgorICAgICAgICAgICAgICAgb2JzID0gYWxsX2ludmVudG9yeSgpIC0KKyAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIGFsbF9pbnZlbnRvcnkoKSwgIydsaXZpbmcvKicqLyApOworICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAKKyAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgIG9icyA9IGZpbHRlcl9vYmplY3RzKCBhbGxfaW52ZW50b3J5KCksICJpZCIsIGNvbXBsZXhfZGVzYyApOworICAgICAgICAgICB9CisKKyAgICAgICAgICAgLy8gdW5zaWNodGJhcmUgb2JqZWt0ZSBlbnRmZXJuZW4KKyAgICAgICAgICAgb2JzID0gZmlsdGVyX29iamVjdHMoIG9icywgInNob3J0IiApOworCisgICAgICAgICAgIC8vIGxldHp0ZW4gR2VnZW5zdGFuZCByYXVzc3VjaGVuCisgICAgICAgICAgIG9icyA9IG9ic1swLi4wXTsgCisgICAgICAgfSAvLyBpZiAobGV0enRlciBHZWdlbnN0YW5kKQorICAgICAgIGVsc2UKKyAgICAgICB7IC8vIGdhbnplIEdydXBwZW4gdW5kIG5pY2h0IG51ciBkYXMgbGV0enRlIE9iamVrdAorICAgICAgICAgICBzd2l0Y2ggKCBjb21wbGV4X2Rlc2MgKQorICAgICAgICAgICB7CisgICAgICAgICAgIGNhc2UgImFsbGVtIjoKKyAgICAgICAgICAgY2FzZSAiYWxsZXMiOgorICAgICAgICAgICBjYXNlICJqZWRlbiBnZWdlbnN0YW5kIjoKKyAgICAgICAgICAgY2FzZSAiamVkZW0gZ2VnZW5zdGFuZCI6CisgICAgICAgICAgIGNhc2UgImdlZ2Vuc3RhZW5kZSI6CisgICAgICAgICAgIGNhc2UgImFsbGUgZ2VnZW5zdGFlbmRlIjoKKyAgICAgICAgICAgY2FzZSAiYWxsZW4gZ2VnZW5zdGFlbmRlbiI6CisgICAgICAgICAgICAgICBpZiAoIG1ldGggJiBQT1NfSU5WRVJTICkKKyAgICAgICAgICAgICAgICAgICBjb250aW51ZTsgLy8gYWxsZXMgbmljaHQgPSBuaWNodHMgOikKKyAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgb2JzID0gYWxsX2ludmVudG9yeSgpIC0KKyAgICAgICAgICAgICAgICAgICBmaWx0ZXIoIGFsbF9pbnZlbnRvcnkoKSwgIydsaXZpbmcvKicqLyApOworICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAKKyAgICAgICAgICAgY2FzZSAid2FmZmVuIjoKKyAgICAgICAgICAgY2FzZSAiamVkZSB3YWZmZSI6CisgICAgICAgICAgIGNhc2UgImplZGVyIHdhZmZlIjoKKyAgICAgICAgICAgY2FzZSAiYWxsZSB3YWZmZW4iOgorICAgICAgICAgICBjYXNlICJhbGxlbiB3YWZmZW4iOgorICAgICAgICAgICAgICAgb2JzID0gZmlsdGVyX29iamVjdHMoIGFsbF9pbnZlbnRvcnkoKSwgIlF1ZXJ5UHJvcCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUF9XRUFQT05fVFlQRSApOworICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAKKyAgICAgICAgICAgY2FzZSAicnVlc3R1bmdlbiI6CisgICAgICAgICAgIGNhc2UgImplZGUgcnVlc3R1bmciOgorICAgICAgICAgICBjYXNlICJqZWRlciBydWVzdHVuZyI6CisgICAgICAgICAgIGNhc2UgImFsbGUgcnVlc3R1bmdlbiI6CisgICAgICAgICAgIGNhc2UgImFsbGVuIHJ1ZXN0dW5nZW4iOgorICAgICAgICAgICAgICAgb2JzID0gZmlsdGVyX29iamVjdHMoIGFsbF9pbnZlbnRvcnkoKSwgIlF1ZXJ5UHJvcCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUF9BUk1PVVJfVFlQRSApOworICAgICAgICAgICAgICAgYnJlYWs7CisgCisgICAgICAgICAgIGNhc2UgImtsZWlkdW5nIjoKKyAgICAgICAgICAgY2FzZSAiamVkZSBrbGVpZHVuZyI6CisgICAgICAgICAgIGNhc2UgImplZGVyIGtsZWlkdW5nIjoKKyAgICAgICAgICAgY2FzZSAiYWxsZSBrbGVpZHVuZyI6CisgICAgICAgICAgIGNhc2UgImFsbGVuIGtsZWlkdW5nIjoKKyAgICAgICAgICAgICAgIG9icyA9IGZpbHRlcl9vYmplY3RzKCBhbGxfaW52ZW50b3J5KCksICJJc0Nsb3RoaW5nIik7CisgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgCisgICAgICAgICAgIGNhc2UgImdlZ2Vuc3RhbmQiOgorICAgICAgICAgICAgICAgb2JzID0gZmlsdGVyX29iamVjdHMoIGFsbF9pbnZlbnRvcnkoKSAtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKCBhbGxfaW52ZW50b3J5KCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjJ2xpdmluZy8qJyovICksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInNob3J0IiApWzAuLjBdOworICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAKKyAgICAgICAgICAgY2FzZSAidmVyc2NoaWVkZW5lbSI6CisgICAgICAgICAgIGNhc2UgInZlcnNjaGllZGVuZXMiOgorICAgICAgICAgICAgICAgb2JzID0gYWxsX2ludmVudG9yeSgpOworICAgICAgICAgICAgICAgb2JzIC09IGZpbHRlcl9vYmplY3RzKCBvYnMsICJRdWVyeVByb3AiLCBQX1dFQVBPTl9UWVBFICk7CisgICAgICAgICAgICAgICBvYnMgLT0gZmlsdGVyX29iamVjdHMoIG9icywgIlF1ZXJ5UHJvcCIsIFBfQVJNT1VSX1RZUEUgKTsKKyAgICAgICAgICAgICAgIG9icyAtPSBmaWx0ZXJfb2JqZWN0cyggb2JzLCAiSXNDbG90aGluZyIpOworICAgICAgICAgICAgICAgb2JzIC09IGZpbHRlciggb2JzLCAjJ2xpdmluZy8qJyovICk7CisgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAKKyAgICAgICAgICAgY2FzZSAiZWlnZW5lcyI6CisgICAgICAgICAgIGNhc2UgImVpZ2VuZW0iOgorICAgICAgICAgICBjYXNlICJlaWdlbmVuIjoKKyAgICAgICAgICAgY2FzZSAibWVpbnMiOgorICAgICAgICAgICBjYXNlICJhbGxlcyBlaWdlbmUiOgorICAgICAgICAgICAgICAgaWYgKG9iamVjdHAoaGF1ZmVuPXByZXNlbnQoIlxuaGF1ZmVuICIrCisgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfcGxheWVyKCktPm5hbWUoV0VNKSkpKSB7CisgICAgICAgICAgICAgICAgICBvYnMgPSBhbGxfaW52ZW50b3J5KGhhdWZlbik7CisgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAvLyBrZWluIGJyZWFrOywgRmFsbC10aHJvdWdoIQorICAgICAgICAgICBjYXNlICJiZWhhbHRlbmVtIjoKKyAgICAgICAgICAgY2FzZSAiYmVoYWx0ZW5lbiI6CisgICAgICAgICAgIGNhc2UgImJlaGFsdGVuZXMiOgorICAgICAgICAgICBjYXNlICJhbGxlcyBiZWhhbHRlbmUiOgorICAgICAgICAgICAgICAgb2JzICs9IGZpbHRlciggYWxsX2ludmVudG9yeSgpLCAiX2JlaGFsdGVuIiwgTUUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldHVpZCh0aGlzX3BsYXllcigpIHx8IHByZXZpb3VzX29iamVjdCgpKSApOworCisgICAgICAgICAgICAgICBvYnMgKz0gKFF1ZXJ5UHJvcChQX0FSTU9VUlMpIHx8ICh7fSkpCisgICAgICAgICAgICAgICAgICAgKyAoeyBRdWVyeVByb3AoUF9XRUFQT04pIH0pIC0gKHsgMCB9KTsKKyAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgIGlmICggY29tcGxleF9kZXNjWzAuLjNdID09ICJqZWRlIiB8fAorICAgICAgICAgICAgICAgICAgICBjb21wbGV4X2Rlc2NbMC4uNF0gPT0gImFsbGUgIikKKyAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICBpZiAoIGNvbXBsZXhfZGVzY1s0Li40XSA9PSAiICIgKQorICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgb2JzID0gZmlsdGVyX29iamVjdHMoIGFsbF9pbnZlbnRvcnkoKSwgImlkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBsZXhfZGVzY1s1Li5dICk7CisgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2goIGNvbXBsZXhfZGVzY1s0Li41XSApCisgICAgICAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAibSAiOgorICAgICAgICAgICAgICAgICAgICAgICBjYXNlICJyICI6CisgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgIm4gIjoKKyAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAicyAiOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzID0gZmlsdGVyX29iamVjdHMoIGFsbF9pbnZlbnRvcnkoKSwgImlkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wbGV4X2Rlc2NbNi4uXSApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG9icyA9IDA7CisgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9icykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgLy8gRGVyIE5vcm1hbGZhbGw6IGVpbnplbG5lIElELi4uCisgICAgICAgICAgICAgICBvYiA9IHByZXNlbnQoIGNvbXBsZXhfZGVzYywgTUUgKTsKKyAgICAgICAgICAgICAgIC8vIEFjaHR1bmc6IGRpZXNlciBUZWlsIHNldHp0IGRhcyBmb3IoKSBmb3J0IChjb250aW51ZSkgdW5kCisgICAgICAgICAgICAgICAvLyB1bWdlaHQgZGFiZWkgZGllIFBydWVmdW5nIGF1ZiBTaWNodGJhcmtlaXQgbmFjaCBkZW0gRW5kZSB2b20KKyAgICAgICAgICAgICAgIC8vIHN3aXRjaCgpLiBBdXMgZGllc2VtIEdydW5kZSBtdXNzIGhpZXIgc2VsYmVyIGdlcHJ1ZWZ0CisgICAgICAgICAgICAgICAvLyB3ZXJkZW4uCisgICAgICAgICAgICAgICBpZiAoIG1ldGggJiBQT1NfSU5WRVJTICkKKyAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICBpZiAoIG9iICYmIG9iICE9IE1FICkKKyAgICAgICAgICAgICAgICAgICAgICAgZXJnICs9IChmaWx0ZXJfb2JqZWN0cyggYWxsX2ludmVudG9yeSgpLCAic2hvcnQiICkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtICh7IG9iIH0pICk7CisgICAgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICAgICBlcmcgKz0gZmlsdGVyX29iamVjdHMoIGFsbF9pbnZlbnRvcnkoKSwgInNob3J0IiApOworICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgZWxzZSBpZiAoIG9iICYmIG9iICE9IE1FICYmICFvYi0+UXVlcnlQcm9wKFBfSU5WSVMpICkKKyAgICAgICAgICAgICAgICAgICBlcmcgKz0gKHsgb2IgfSk7ICAgLy9Ob3JtYWxmYWxsOiBlaW56ZWxuZSBJRAorCisgICAgICAgICAgICAgICBjb250aW51ZTsKKworICAgICAgICAgICB9ICAvLyBzd2l0Y2gKKyAgICAgICAgICAgLy8gdW5zaWNodGJhcmUgb2JqZWt0ZSBlbnRmZXJuZW4KKyAgICAgICAgICAgb2JzID0gZmlsdGVyX29iamVjdHMoIG9icywgInNob3J0IiApOyAKKyAgICAgICB9IC8vIGVsc2UKKworICAgICAgIGlmICggbWV0aCAmIFBPU19JTlZFUlMgKQorICAgICAgICAgICBlcmcgKz0gKCBmaWx0ZXJfb2JqZWN0cyggYWxsX2ludmVudG9yeSgpLCAic2hvcnQiICkgLSBvYnMgKTsKKyAgICAgICBlbHNlCisgICAgICAgICAgIGVyZyArPSBvYnM7CisgICB9IC8vIGZvcgorICAgcmV0dXJuIGVyZzsKK30KKworLyoKKyAqIHJldHVybnMgYSBsaXN0IG9mIGFsbCBmb3VuZCBvYmplY3RzIGluc2lkZSBpdHNlbGYKKyAqIG1heSBjYWxsIHNhbWUgZnVuY3Rpb24gaW4gb2JqZWN0cyBpbnNpZGUKKyAqCisgKiBGdW5rdGlvbiB3aXJkIG5pY2h0IG1laHIgdm9uIHB1dF9hbmRfZ2V0IGF1ZmdlcnVmZW4sIHN0YXR0ZGVzc2VuIHdpcmQKKyAqIGRpcmVrdCBwcmVzZW50X29iamVjdHMgYmVudXR6dCEKKyAqLyAKK29iamVjdCAqbG9jYXRlX29iamVjdHMoIHN0cmluZyBjb21wbGV4X2Rlc2MsIGludCBpbmZvICkgeworICAgIHN0cmluZyB3YXMsIHdvOworCisgICAgaWYgKCBzc2NhbmYoIGNvbXBsZXhfZGVzYywgIiVzIGluICVzIiwgd2FzLCB3byApID09IDIgKXsKKyAgICAgIG9iamVjdCAqZm91bmRfb2JzID0gKHt9KTsKKyAgICAgIGZvcmVhY2gob2JqZWN0IGludm9iOiBwcmVzZW50X29iamVjdHMod28pKSB7CisgICAgICAgIC8vIHx8ICh7fSkgd2VpbCBpbnZvYiBlaW4gT2JqZWt0IG9obmUgbG9jYXRlX29iamVjdHMoKSBzZWluIGtvZW5udGUuCisgICAgICAgIGZvdW5kX29icyArPSAob2JqZWN0ICopaW52b2ItPmxvY2F0ZV9vYmplY3RzKCB3YXMsIGluZm8pIHx8ICh7fSk7CisgICAgICB9CisgICAgICByZXR1cm4gZm91bmRfb2JzOworICAgIH0KKyAgICAvLyBrZWluICJpbiIgZ2VmdW5kZW4KKyAgICByZXR1cm4gcHJlc2VudF9vYmplY3RzKCBjb21wbGV4X2Rlc2MgKTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2NvcnBzZS5jIGIvc3RkL2NvcnBzZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhlNGQ4YWUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvY29ycHNlLmMKQEAgLTAsMCArMSw3MjcgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIgICAgICAgICAgICAgICAKKy8vCisvLyBjb3Jwc2UuYyAtLSBjb3Jwc2Ugc3RhbmRhcmQgb2JqZWN0CisvLworLy8gJElkOiBjb3Jwc2UuYyA5MzkxIDIwMTUtMTItMDcgMjI6Mjg6NTNaIEFyYXRob3JuICQKKworLy8gQSBjb3Jwc2UuCisvLyAKKy8vIEVrZWx0ZXh0ZSBieSBCb2luZworLy8KKy8vIFRoaXMgaXMgYSBkZWNheWluZyBjb3Jwc2UuIEl0IGlzIGNyZWF0ZWQgYXV0b21hdGljYWxseQorLy8gd2hlbiBhIHBsYXllciBvciBtb25zdGVyIGRpZXMuCisvLworLy8gRXJ3ZWl0ZXJ1bmcgUmFzY2hhdWE6CisvLyAtIEtvcGllcmVuIHZvbiBQX0NMQVNTCisvLyAtIFRlaWx3ZWlzZXMgYXVmZXNzZW4KKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgcGVkYW50aWMKKworLy8jZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCitpbmhlcml0ICJzdGQvY29udGFpbmVyIjsKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxsaXZpbmcvbGlmZS5oPgorI2luY2x1ZGUgIi9zZWN1cmUvc2NvcmVtYXN0ZXIuaCIKKworI2RlZmluZSBDT1JQU0VfT0JKICIvc3RkL2NvcnBzZS5jIgorI2RlZmluZSBQSUxFX09CSiAiL3N0ZC9waWxlLmMiCisKK25vc2F2ZSBpbnQgX2RlY2F5ID0gNDsKK25vc2F2ZSBzdHJpbmcgX25hbWUgPSAiVW5iZWthbm50IjsKK25vc2F2ZSBvYmplY3QgbW9lcmRlcjsKK3ByaXZhdGUgbm9zYXZlIGludCBnZXNwb3R0ZXQgPSAwOworbm9zYXZlIGludCBuYWhydW5nX2dlc2FtdCA9IDE7Citub3NhdmUgaW50IG5haHJ1bmdfYWt0dWVsbCA9IDE7CisvLyBTcGllbGVybGVpY2hlPworcHJpdmF0ZSBub3NhdmUgc3RhdHVzIHNwaWVsZXJsZWljaGU7CisKK3ZvaWQgSWRlbnRpZnkoIG9iamVjdCBvYiApOwordm9pZCBkb19kZWNheSgpOworaW50IFF1ZXJ5RGVjYXkoKTsKK3N0YXRpYyBpbnQgbWFtcGYoIHN0cmluZyBzdHIgKTsKK3N0YXRpYyBpbnQgc3BvdHQoc3RyaW5nIHN0cik7Cit2b2lkIENoYW5uZWxNZXNzYWdlSmVlciggbWl4ZWQgc2VuZGVyLCBzdHJpbmcgdGV4dCwgaW50IGZsYWcgKTsKK29iamVjdCBfY2hhbm5lbCggb2JqZWN0IG9iICk7Cit2b2lkIHRyYW5zZm9ybV9pbnRvX3BpbGUoKTsKKwordm9pZCBjcmVhdGUoKQoreworICBpZiAob2JqZWN0X25hbWUoTUUpID09IF9fRklMRV9fWzAuLjwzXSkgeworICAgIHNldF9uZXh0X3Jlc2V0KC0xKTsKKyAgfQorICA6OmNyZWF0ZSgpOworICBpZiggY2xvbmVwKHRoaXNfb2JqZWN0KCkpICkKKyAgeworICAgIEFkZElkKCh7ICJsZWljaGUiLCJcbmxlaWNoZSIsInJlc3QiLCJ1ZWJlcnJlc3QifSkpOworICAgIFNldFByb3AoIFBfR0VOREVSLCBGRU1BTEUgKTsKKyAgICBTZXRQcm9wKCBQX05BTUUsICJMZWljaGUiICk7CisgICAgU2V0UHJvcCggUF9NQVRFUklBTCwgKFsgTUFUX01JU0NfREVBRDogMTAwIF0pICk7CisgICAgU2V0UHJvcCggUF9DT1JQU0VfREVDQVlfVElNRSwgMzAgKTsKKyAgICBTZXRQcm9wKFBfTk9fU0NPUkUsMSk7CisgICAgQWRkQ21kKCh7ImlzcyIsInZlcnNwZWlzZSJ9KSwibWFtcGYiKTsKKyAgICBBZGRDbWQoInNwb3R0ZSIsInNwb3R0Iik7CisgICAgU2V0UHJvcChQX0FSVElDTEUsIDEpOworICB9CisgIGVsc2UKKyAgICBTZXRQcm9wKCBQX0FSVElDTEUsIDAgKTsKK30KKworLyogRGFtaXQgZGllIExlaWNoZSBuaWNodCB2b2xsIHdpcmQuLi4gKi8KK2ludCBNYXlBZGRXZWlnaHQoIGludCB3ZWlnaHQgKSB7IHJldHVybiAwOyB9CitpbnQgTWF5QWRkT2JqZWN0KCBvYmplY3Qgb2IgKSB7IHJldHVybiAxOyB9CisKKworLyogSHVtbmksIDIwMDQtMDYtMTY6IEVudHN0YXRpY3QgKi8KK3N0cmluZyBfcXVlcnlfbGVpY2hlbl9uYW1lKCkKK3sgICByZXR1cm4gX25hbWU7ICAgfQorCisvKiBVZWJlcm5laG1lIGRlbiBOYW1lbiB2b24gb2IgKi8KK3ZvaWQgSWRlbnRpZnkoIG9iamVjdCBvYiApCit7CisgICAgY2xvc3VyZSBjbDsKKyAgICBpbnQgaTsKKyAgICBzdHJpbmcgaW5mbzsKKworICAgIHNwaWVsZXJsZWljaGUgPSBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iKTsKKyAgICBjbD1zeW1ib2xfZnVuY3Rpb24oIlF1ZXJ5UHJvcCIsIG9iKTsKKyAgICBfbmFtZSA9IChzdHJpbmcpIG9iLT5uYW1lKFdFU1NFTiwwKTsKKyAgICBTZXRQcm9wKCBQX1NIT1JULCAiRGllIExlaWNoZSAiKyBfbmFtZSApOworICAgIFNldFByb3AoIFBfTE9ORywgIkR1IHNpZWhzdCBkaWUgc3RlcmJsaWNoZW4gVWViZXJyZXN0ZSAiKyBfbmFtZSArICIuXG4iICk7CisgICAgX2RlY2F5ID0gNDsKKyAgICBTZXRQcm9wKCBQX09SSUdfTkFNRSwgdG9fc3RyaW5nKG9iLT5uYW1lKFJBVykpICAgICAgKTsKKyAgICBTZXRQcm9wKCBQX1BJTEVfTkFNRSwgdG9fc3RyaW5nKG9iLT5uYW1lKFdFTSkpICAgICAgKTsKKyAgICBBZGRJZCggIlxubGVpY2hlICIrIFF1ZXJ5UHJvcChQX1BJTEVfTkFNRSkgICAgICAgICAgKTsKKyAgICBTZXRQcm9wKCBQX0tJTExFUiwgICAgICAgIChvYmplY3QpICAgZnVuY2FsbChjbCwgUF9LSUxMRVIpICAgICAgICApOworICAgIFNldFByb3AoIFBfQVRUUklCVVRFUywgICAgKG1hcHBpbmcpICBmdW5jYWxsKGNsLCBQX0FUVFJJQlVURVMpICAgICk7CisgICAgU2V0UHJvcCggUF9MQVNUX0RBTVRZUEVTLCAoc3RyaW5nICopIGZ1bmNhbGwoY2wsIFBfTEFTVF9EQU1UWVBFUykgKTsKKyAgICBTZXRQcm9wKCBQX1hQLCAgICAgdG9faW50KGZ1bmNhbGwoY2wsIFBfWFApKSAgICAgICAgKTsKKyAgICBTZXRQcm9wKCBQX1NJWkUsICAgdG9faW50KGZ1bmNhbGwoY2wsIFBfU0laRSkpICAgICAgKTsKKyAgICBTZXRQcm9wKCBQX0xFVkVMLCAgdG9faW50KGZ1bmNhbGwoY2wsIFBfTEVWRUwpKSAgICAgKTsKKyAgICBTZXRQcm9wKCBQX01BWF9IUCwgdG9faW50KGZ1bmNhbGwoY2wsIFBfTUFYX0hQKSkgICAgKTsKKyAgICBTZXRQcm9wKCBQX1JBQ0UsICAgdG9fc3RyaW5nKGZ1bmNhbGwoY2wsIFBfUkFDRSkpICAgKTsKKyAgICBTZXRQcm9wKCBQX0NMQVNTLCAgKHN0cmluZyAqKShmdW5jYWxsKGNsLCBQX0NMQVNTKSkgKTsKKyAgICBTZXRQcm9wKCBQX0hBTkRTLCAgKG1peGVkICopIGZ1bmNhbGwoY2wsIFBfSEFORFMpICAgKTsKKyAgICBTZXRQcm9wKCBQX1dFSUdIVCwgKG1peGVkICopIGZ1bmNhbGwoY2wsIFBfV0VJR0hUKSAgKTsKKyAgICBTZXRQcm9wKCBQX0FMSUdOLCAgdG9faW50KGZ1bmNhbGwoY2wsIFBfQUxJR04pKSAgICAgKTsKKyAgICBTZXRQcm9wKCBQX09SSUdfRklMRV9OQU1FLCBvYmplY3RfbmFtZShvYikgICAgICAgICAgKTsKKyAgICBTZXRQcm9wKCBQX0hFQUwsICAgdG9faW50KGZ1bmNhbGwoY2wsIFBfSEVBTCkpICAgICAgKTsKKyAgICAKKyAgICAvLyBTYWV0dGlndW5nIGRlciBMZWljaGUgYmVyZWNobmVuCisgICAgLy8gUF9XRUlHSFQgdW5kIFBfU0laRSB3ZXJkZW4gdmVyd2VuZGV0LCBNaXR0ZWwgYmlsZGVuCisgICAgLy8gRWluIFNhZXR0aWd1bmdzcHVua3QgZnVlciAoa29uc2VydmF0aXZlIFJlY2hudW5nKToKKyAgICAvLyAgICAgICAgICAgNSBrZworICAgIC8vICAgICAgICAgIDEyIGNtCisgICAgLy8gQmVpc3BpZWxlOgorICAgIC8vICAgICAgICAgIE1lbnNjaCwgMS44MCBtIGdyb3NzLCA3NSBrZyBzY2h3ZXI6CisgICAgLy8gICAgICAgICAgMTgwLzEyICsgNzUvNSA9IDE1ICsgMTUgPSAzMAorICAgIC8vICAgICAgICAgIEt1aCwgMS41MCBtIGdyb3NzLCA1MDAga2cgc2Nod2VyOgorICAgIC8vICAgICAgICAgIDE1MC8xMiArIDUwMC81ID0gMTIgKyAxMDAgPSAxMTIKKyAgICAvLyAgICAgICAgICBEcmFjaGUsIDUgbSBncm9zcywgMTUwMCBrZyBzY2h3ZXI6CisgICAgLy8gICAgICAgICAgNTAwLzEyICsgMTUwMC81ID0gNDEgKyAzMDAgPSAzNDEKKyAgICBuYWhydW5nX2dlc2FtdCA9IFF1ZXJ5UHJvcChQX1dFSUdIVCkvNTAwMCArIFF1ZXJ5UHJvcChQX1NJWkUpLzEyOworICAgIGlmIChuYWhydW5nX2dlc2FtdCA8PSAwKQorICAgICAgbmFocnVuZ19nZXNhbXQgPSAxOworICAgIG5haHJ1bmdfYWt0dWVsbCA9IG5haHJ1bmdfZ2VzYW10OworCisgICAgaWYgKCBpbnRwKGkgPSBmdW5jYWxsKGNsLCBQX0NPUlBTRV9ERUNBWV9USU1FKSkgJiYgaSA+IDIgKQorICAgICAgICBTZXRQcm9wKCBQX0NPUlBTRV9ERUNBWV9USU1FLCBpICk7CisKKyAgICBjYWxsX291dCggImRvX2RlY2F5IiwgUXVlcnlQcm9wKFBfQ09SUFNFX0RFQ0FZX1RJTUUpICk7CisKKyAgICBpZiAoICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iKSApCisgICAgICAgIG1vZXJkZXIgPSAob2JqZWN0KSAiL3N0ZC9jb3Jwc2UiLT5fY2hhbm5lbChvYik7Cit9CisKK3B1YmxpYyBpbnQgSXNQbGF5ZXJDb3Jwc2UoKSB7IHJldHVybiBzcGllbGVybGVpY2hlOyB9CisKK3B1YmxpYyBzdHJpbmcgUXVlcnlIZWFsSW5mbygpCit7CisgIHN0cmluZyBpbmZvID0gIlNvbGx0ZXN0IER1IGF1ZiBkaWUgYWJlcndpdHppZ2UgSWRlZSB2ZXJmYWxsZW4sIGRpZXNlICIKKyAgICAiTGVpY2hlIHp1IGVzc2VuLCAiOworICBzd2l0Y2goIFF1ZXJ5UHJvcChQX0hFQUwpICkKKyAgeworICAgIGNhc2UgLV9fSU5UX01BWF9fLi4tMTAwOgorICAgICAgaW5mbyArPSAid2lyZCBEaXIgZGFzIGVyaGVibGljaGVuIFNjaGFkZW4genVmdWVnZW4uIjsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgLTk5Li4tMTE6CisgICAgICBpbmZvICs9ICJpc3QgZGFzIGF1c2dlc3Byb2NoZW4gdW5nZXN1bmQgZnVlciBEaWNoLiI7CisgICAgICBicmVhazsKKyAgICBjYXNlIC0xMC4uLTE6CisgICAgICBpbmZvICs9ICJ3aXJkIERpciBzaWNoZXIgZWluIHdlbmlnIHVlYmVsIHdlcmRlbi4iOworICAgICAgYnJlYWs7CisgICAgY2FzZSAwLi41OgorICAgICAgaW5mbyArPSAid2lyZCBEaXIgbmljaHRzIHNjaGxpbW1lcyBwYXNzaWVyZW4uIjsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgNi4uX19JTlRfTUFYX186CisgICAgICBpbmZvICs9ICJrb2VubnRlc3QgRHUgc29nYXIgZWluIHdlbmlnIGdlaGVpbHQgd2VyZGVuLiI7CisgICAgICBicmVhazsKKyAgfQorICByZXR1cm4gaW5mbzsKK30KKworcHJpdmF0ZSBzdHJpbmcga25hYmJlcl90ZXh0KCkKK3sKKyAgc3RyaW5nIHR4dDsKKyAgc3dpdGNoIChuYWhydW5nX2FrdHVlbGwgKiA0IC8gbmFocnVuZ19nZXNhbXQpIHsKKyAgY2FzZSA0OgorICAgIC8vIExlaWNoZSBub2NoIGtvbXBsZXR0CisgICAgdHh0ID0gIiI7CisgICAgYnJlYWs7CisgIGNhc2UgMzoKKyAgICAvLyBub2NoIG1heGltYWwgOTklCisgICAgdHh0ID0gIiBtaXQgS25hYmJlcnNwdXJlbiB1ZWJlcnNhZXRlIjsKKyAgICBicmVhazsKKyAgY2FzZSAyOgorICAgIC8vIG5vY2ggbWF4aW1hbCA3NCUKKyAgICB0eHQgPSAiIGFuZ2VmcmVzc2VuZSI7CisgICAgYnJlYWs7CisgIGNhc2UgMToKKyAgICAvLyBub2NoIG1heGltYWwgNDklCisgICAgdHh0ID0gIiBzY2hvbiBoYWxiIGF1ZmdlZnV0dGVydGUiOworICAgIGJyZWFrOworICBkZWZhdWx0OgorICAgIC8vIG5vY2ggbWF4aW1hbCAyNCUKKyAgICB0eHQgPSAiIHRvdGFsIGFiZ2VuYWd0ZSI7CisgICAgYnJlYWs7CisgIH0KKyAgcmV0dXJuIHR4dDsKK30KKworc3RhdGljIHN0cmluZyBfcXVlcnlfc2hvcnQoKQoreworICBzdHJpbmcgdHh0OworICBzd2l0Y2goX2RlY2F5KSB7CisgIGNhc2UgNDoKKyAgICB0eHQgPSAiRGllIitrbmFiYmVyX3RleHQoKSsiIExlaWNoZSAiOworICAgIGJyZWFrOworICBjYXNlIDM6CisgICAgdHh0ID0gIkRpZSBiZXJlaXRzIHppZW1saWNoIHN0aW5rZW5kZSIra25hYmJlcl90ZXh0KCkrIiBMZWljaGUgIjsKKyAgICBicmVhazsKKyAgY2FzZSAyOgorICAgIHR4dCA9ICJEaWUgc2NoaW1tZWxuZGUgdW5kIGhhbGJ2ZXJ3ZXN0ZSIra25hYmJlcl90ZXh0KCkrIiBMZWljaGUgIjsKKyAgICBicmVhazsKKyAgY2FzZSAxOgorICAgIHR4dCA9ICJEaWUgdmVyZmF1bHRlbiIrKHNpemVvZihrbmFiYmVyX3RleHQoKSkgPworICAgICAgICAgICAgICAgICAgICAgICAgICAgICJuIjoiIikrIiBFaW56ZWx0ZWlsZSAiOworICAgIGJyZWFrOworICB9CisgIHR4dCArPSBfbmFtZTsKKyAgcmV0dXJuIHR4dDsKK30KKwordm9pZCBkb19kZWNheSgpCit7CisgICAgX2RlY2F5IC09IDE7CisgICAgCisgICAgaWYgKCBfZGVjYXkgPiAwICkgCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoIChfZGVjYXkgPT0gMikgJiYgKFF1ZXJ5UHJvcCggUF9IRUFMICkgPj0gLTQpICkKKyAgICAgICAgICAgIFNldFByb3AoIFBfSEVBTCwgLTQgKTsKKyAgICAgICAgICAgIGNhbGxfb3V0KCAiZG9fZGVjYXkiLCBRdWVyeVByb3AoUF9DT1JQU0VfREVDQVlfVElNRSkgKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgCisgICAgdHJhbnNmb3JtX2ludG9fcGlsZSgpOworICAgIHJlbW92ZSgpOworfQorCisvKiBIYWVoPyBEYXMgbW92ZSBpbnMgZW52IG1hY2h0IGRlciBNYXN0ZXIgaW0gcHJlcGFyZV9kZXN0cnVjdCgpIGRvY2ggZWg/ICovCisvKgordmFyYXJncyBpbnQgcmVtb3ZlKCkKK3sKKyAgICAvLyB1bml0cyBiZWtvbW1lbiBlaW5lIENoYW5jZSB6dXIgVmVyZWluaWd1bmcuLi4KKyAgICBmaWx0ZXJfb2JqZWN0cyggYWxsX2ludmVudG9yeShNRSksICJtb3ZlIiwgZW52aXJvbm1lbnQoTUUpLCBNX1NJTEVOVCApOworICAgIHJldHVybiA6OnJlbW92ZSgpOworfQorKi8KKworaW50IFF1ZXJ5RGVjYXkoKSB7IHJldHVybiBfZGVjYXk7IH0KKworc3RhdGljIGludCAqIF9xdWVyeV9uYWhydW5nKCkKK3sgICByZXR1cm4gKHtuYWhydW5nX2FrdHVlbGwsIG5haHJ1bmdfZ2VzYW10fSk7ICAgfQorCitwcml2YXRlIHN0cmluZyBtYW1wZl9oZWlsdW5nKGludCB3aWV2aWVsKQoreworICBpbnQgaGVhbDsKKyAgc3RyaW5nIG1zZzsKKyAgaGVhbCA9IFF1ZXJ5UHJvcChQX0hFQUwpOworICAvLyBBbnRlaWwgYW4gR2VzYW10aGVpbHVuZyBhdXNyZWNobmVuCisgIGhlYWwgPSBoZWFsICogd2lldmllbCAvIG5haHJ1bmdfZ2VzYW10OworICBpZiAoICggaGVhbCApIDwgMCApIHsKKyAgICAvLyAKKyAgICB0aGlzX3BsYXllcigpLT5kb19kYW1hZ2UoIHJhbmRvbSgtaGVhbCksIHRoaXNfb2JqZWN0KCkgKTsKKyAgICBtc2cgPSAiQnVhaCwgZGllc2UgTGVpY2hlIHdhciB6d2VpZmVsbG9zIG5pY2h0IGJlc29uZGVycyBnZXN1bmQuXG4iOworICB9IGVsc2UgeworICAgIHRoaXNfcGxheWVyKCktPmhlYWxfc2VsZiggcmFuZG9tKGhlYWwpICk7CisgICAgbXNnID0gIkhtbW0sIGxlY2tlciFcbiI7CisgIH0KKyAgcmV0dXJuIG1zZzsKK30KKworc3RhdGljIGludCBtYW1wZiggc3RyaW5nIHN0ciApCit7CisgICAgaW50IGdlZ2Vzc2VuOworCisgICAgX25vdGlmeV9mYWlsKCJXYXMgbW9lY2h0ZXN0IER1IGVzc2VuP1xuIik7CisgICAgCisgICAgaWYgKCAhc3RyIHx8ICFpZChzdHIpICkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBpZiAodGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfR0hPU1QpKQorICAgIHsKKwlfbm90aWZ5X2ZhaWwoIkRhcyB3dWVyZGUgZHVyY2ggRGljaCBoaW5kdXJjaCBmYWxsZW4uXG4iKTsKKwlyZXR1cm4gMDsKKyAgICB9CisKKyAgICAvLyBEYXMgZm9sZ2VuZGUgaXN0IG5pY2h0IGdhbnogc2F1YmVyLCBkYSBkaWUgU3RhZXJrZSBiZWkgZWF0X2Zvb2QgbmljaHQKKyAgICAvLyB1bmJlZGluZ3QgZGVtIFNhZXR0aWd1bmdzd2VydCBlbnRzcHJlY2hlbiBtdXNzICh3ZWdlbiBGT09EX1ZBTFVFKS4KKyAgICBnZWdlc3NlbiA9IChpbnQpIHRoaXNfcGxheWVyKCktPlF1ZXJ5UHJvcChQX01BWF9GT09EKSAtCisgICAgICAoaW50KSB0aGlzX3BsYXllcigpLT5RdWVyeVByb3AoUF9GT09EKTsKKyAgICBpZiAoZ2VnZXNzZW4gPD0gMCkgeworICAgICAgLy8gU3BpZWxlciBpc3QgcHJvcHBlbnZvbGwsIE1lbGR1bmcgYXVzZ2ViZW4KKyAgICAgIGdlZ2Vzc2VuID0gMDsKKyAgICAgIHdyaXRlKCJEdSBiZWtvbW1zdCB2b24gZGVyIExlaWNoZSBuaWNodCBlaW5lbiBCaXNzZW4gbWVociBydW50ZXIuXG4iKTsKKyAgICB9IGVsc2UgaWYgKGdlZ2Vzc2VuID49IG5haHJ1bmdfYWt0dWVsbCkgeworICAgICAgLy8gc3BpZWxlciBrYW5uIGRpZSBnZXNhbXRlIExlaWNoZSBlc3NlbiwgYWxzbyBlbnRmZXJuZW4uCisgICAgICB0aGlzX3BsYXllcigpLT5lYXRfZm9vZChuYWhydW5nX2FrdHVlbGwpOworICAgICAgLy8gVmVyZGFtbXQuIGVhdF9mb29kKCkga2FubiBUUCB1bWdlYnJhY2h0IGhhYmVuIHVuZCBpbSBGYWxsZSBlaW5lcyBOUEMKKyAgICAgIC8vIGlzdCBkZXIgZGFubiB3ZWcuCisgICAgICBpZiAob2JqZWN0cCh0aGlzX3BsYXllcigpKSkgeworCXdyaXRlKG1hbXBmX2hlaWx1bmcobmFocnVuZ19ha3R1ZWxsKSk7CisJc2F5KCBzcHJpbnRmKCIlcyB3aXJkIHZvbiAlcyB2b2xsIEhpbmdlYnVuZyB2ZXJzcGVpc3QuXG4iLAorICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUobmFtZShXRVIpKSwKKyAgICAgICAgICAgICAgICAgICAoc3RyaW5nKSB0aGlzX3BsYXllcigpLT5uYW1lKFdFTSkpICk7CisgICAgICB9CisgICAgICB0cmFuc2Zvcm1faW50b19waWxlKCk7CisgICAgICByZW1vdmUoKTsKKyAgICB9IGVsc2UgeworICAgICAgLy8gQXVjaCB0ZWlsd2Vpc2UgVmVyc3BlaXN1bmcgaXN0IG1vZWdsaWNoLCBuYWhydW5nX2FrdHVlbGwgYW5wYXNzZW4KKyAgICAgIHRoaXNfcGxheWVyKCktPmVhdF9mb29kKGdlZ2Vzc2VuKTsKKyAgICAgIGlmIChvYmplY3RwKHRoaXNfcGxheWVyKCkpKSB7CisJd3JpdGUobWFtcGZfaGVpbHVuZyhnZWdlc3NlbikrIkxlaWRlciBiaXN0IER1IG5pY2h0IGluIGRlciBMYWdlLCIKKyAgICAgICAgICAgICAgICIgYWxsZXMgYXVmenVlc3Nlbi5cbiIpOworICAgICAgc2F5KCBzcHJpbnRmKCIlcyBrbmFiYmVydCBhbiAlcyBoZXJ1bS5cbiIsCisgICAgICAgICAgICAgICAgICAgKHN0cmluZykgdGhpc19wbGF5ZXIoKS0+bmFtZSgpLAorICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUobmFtZShXRU0pKSApICk7CisgICAgICB9CisgICAgICBuYWhydW5nX2FrdHVlbGwgLT0gZ2VnZXNzZW47CisgICAgfQorICAgIHJldHVybiAxOworfQorCisKK3N0YXRpYyBpbnQgc3BvdHQoIHN0cmluZyBzdHIgKQoreworICAgIGlmICggIXN0ciApCisgICAgICAgIHJldHVybiBfbm90aWZ5X2ZhaWwoICJTeW50YXg6IHNwb3R0ZSA8dGV4dD5cbiIgKSwgMDsKKyAgICAKKyAgICBpZiAoICFvYmplY3RwKG1vZXJkZXIpICkKKyAgICAgICAgcmV0dXJuIF9ub3RpZnlfZmFpbCggIkRpZXNlcyBPcGZlciBpc3QgZGVuIFNwb3R0IG5pY2h0IHdlcnQuXG4iICksIDA7CisgICAgCisgICAgaWYgKCBQTCAhPSBtb2VyZGVyICkKKyAgICAgICAgcmV0dXJuIF9ub3RpZnlfZmFpbCggIkR1IGthbm5zdCBudXIgRGVpbmUgZWlnZW5lbiBPcGZlciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsidmVyc3BvdHRlbiFcbiIgKSwgMDsKKworICAgIGlmICggZ2VzcG90dGV0ICkKKyAgICAgICAgcmV0dXJuIF9ub3RpZnlfZmFpbCggIkR1IGthbm5zdCBEZWluIE9wZmVyIG51ciBlaW5tYWwgdmVyc3BvdHRlbiFcbiIgKQorICAgICAgICAgICAgLCAwOworCisgICAgaWYgKCBfZGVjYXkgPCA0ICkKKyAgICAgICAgcmV0dXJuIF9ub3RpZnlfZmFpbCggIkRhIHNvbGx0ZXN0IER1IHNjaG9uIGV0d2FzIHNwb250YW5lciBzZWluLlxuIiApCisgICAgICAgICAgICAsIDA7CisKKyAgICBzdHIgPSAoc3RyaW5nKSBQTC0+X3VucGFyc2VkX2FyZ3MoKTsKKyAgICAKKyAgICBzd2l0Y2ggKCBzdHJbMF0gKQorICAgICAgICB7CisgICAgICAgIGNhc2UgJzonOgorICAgICAgICAgICAgIi9zdGQvY29ycHNlIi0+Q2hhbm5lbE1lc3NhZ2VKZWVyKCBQTCwgc3RyWzEuLl0sIE1TR19FTU9URSApOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgCisgICAgICAgIGNhc2UgJzsnOgorICAgICAgICAgICAgIi9zdGQvY29ycHNlIi0+Q2hhbm5lbE1lc3NhZ2VKZWVyKCBQTCwgc3RyWzEuLl0sIE1TR19HRU1PVEUgKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIAorICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgIi9zdGQvY29ycHNlIi0+Q2hhbm5lbE1lc3NhZ2VKZWVyKCBQTCwgc3RyLCBNU0dfU0FZICk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAKKyAgZ2VzcG90dGV0ID0gMTsKKyAgd3JpdGUoICJEdSB2ZXJzcG90dGVzdCBEZWluIHRvdGVzIE9wZmVyLlxuIiApOworICAKKyAgcmV0dXJuIDE7Cit9CisKKwordm9pZCBDaGFubmVsTWVzc2FnZUplZXIoIG1peGVkIHNlbmRlciwgc3RyaW5nIHRleHQsIGludCBmbGFnICkKK3sKKyAgaWYgKG1lbWJlcihpbmhlcml0X2xpc3QocHJldmlvdXNfb2JqZWN0KCkpLENPUlBTRV9PQkopPi0xKQorICAgICAgQ0hNQVNURVItPnNlbmQoICJNb2VyZGVyIiwgc2VuZGVyLCB0ZXh0LCBmbGFnICk7Cit9CisKKworLy8gX2NoYW5uZWwoKSAtLQorI2RlZmluZSBLSUxMX01FU1NBR0VTIFwKKyJKZXR6dCBoYXQgbWljaCBkb2NoIGdsYXR0ICVzIGVyd2lzY2h0IDooIiwgXAorIldpZSBzb2xsIGRhcyBub2NoIGVuZGVuLCAlcz8iLCBcCisiVW5nbGF1YmxpY2gsIHdpZSBoYXQgJXMgZGFzIGdlc2NoYWZmdD8iLCBcCisiUkFDSEUhIEJyaW5ndCAlcyB1bSEiLCBcCisiJXMgaXN0IHN0YWVya2VyIGFscyBpY2ggZGFjaHRlLiIsIFwKKyJXZW5uIGljaCBEaWNoIGVyd2lzY2hlLCAlcyEiLCBcCisiJXMgaGF0IG1pY2ggZXJtb3JkZXQhIiwgXAorIldlbGNoZSBTY2htYWNoISAlcyBoYXQgbWljaCBiZXNpZWd0LiIsIFwKKyJIdWV0ZXQgRXVjaCB2b3IgJXMhIiwgXAorIldhcnVtIGhhdCBtaXIgbmllbWFuZCBnZWdlbiAlcyBnZWhvbGZlbj8iLCBcCisiJXMsIER1IE1vbnN0ZXJzY2hhZW5kZXIhIiwgXAorIk1vbnN0ZXIgYWxsZXIgUmVnaW9uZW4sIHZlcmVpbmlndCBFdWNoIGdlZ2VuICVzISIsIFwKKyJEYW5rZSwgJXMsIER1IGhhc3QgbWljaCB2b24gZGllc2VyIHNjaHJlY2tsaWNoZW4sICIgXAorInN0ZXJibGljaGVuIEh1ZWxsZSBiZWZyZWl0LiIsIFwKKyIlcz8gSWNoIGJpbiBkYW5uIGpldHp0IHdlZy4iLCBcCisiTWFjaHQgRXVjaCBrZWluZSBNdWVoZSwgJXMgaGF0IG1pY2ggbWFsIGt1cnogenUgIiBcCisiR2V2YXR0ZXIgVG9kIGdlc2NoaWNrdC4iLCBcCisiT2ggbmVpbiwgJXMgaGF0IG1pY2ggc2Nob24gd2llZGVyIGthbHRnZW1hY2h0ISIsIFwKKyJTaGVyaWZmISBWZXJoYWZ0ZSAlcyEiLCBcCisiSGlsZmUhIERpZWJlISBNb2VyZGVyISBIYWxzYWJzY2huZWlkZXIhICVzISIsIFwKKyJXaWVkZXIgbWFsIGFuICVzIGdlc3RvcmJlbiwgZmluZCBpY2ggYWxiZXJuISIsIFwKKyIlcywgcHJvYmllciBkYXMgYmVpIEFubmUhIiwgXAorIlVuZCB3aWVkZXIgZWluIERyaXR0ZWwgRXJmYWhydW5nIHdlZyB3ZWdlbiAlcy4uLiIsIFwKKyJPaCB3YWVyIGljaCBkb2NoIGVpbiBTcGllbGVyLCBkYW5uIGR1ZXJmdGUgbWljaCAiXAorIiVzIG5pY2h0IG1laHIgdG9ldGVuISIsIFwKKyJXZW5uIER1IGRhcyBub2NoIG9lZnRlciBtYWNoc3QsICVzLCBkYW5uIHNwaWVsZSAiXAorImljaCBoaWVyIG5pY2h0IG1laHIhIiwgXAorIiVzLCB3aWVzbyByZWRldCBkZXIgS2VybCBoaWVyIGluIEdyb3NzYnVjaHN0YWJlbiAiXAorInp1IG1pcj8gQ0FQUy1MT0NLIGthcHV0dD8iLCBcCisiJXMgaXN0IHNjaHVsZCEiLFwKKyJTbyBzY2hhZmYgaWNoJ3Mgd29obCBuaWUsIFNlaGVyIHp1IHdlcmRlbiwgJXMgOigiLFwKKyJNdXNzdGUgZGFzIFdJUktMSUNIIHNlaW4sICVzPyIsXAorIld1ZW5zY2h0IG1pciBuZSBrdXJ6ZSBUb2Rlc3NlcXVlbnosIGljaCBoYWIgc2llICJcCisiJXMgenUgdmVyZGFua2VuLi4uIixcCisiTmFlY2hzdGVzIE1hbCBicmluZyBtaXIgbGllYmVyIFBvc3Qgc3RhdHQgbWljaCAiXAorInp1IGVybW9yZGVuLCAlcyEiLFwKKyIlcywgd2llc28gc2FndCBkZXIgVHlwOiBLT01NIE1JVCBNSVIsIFNURVJCTElDSEVSPyIsXAorIkljaCBnbGF1YiwgamV0enQga2VubmUgaWNoIEFMTEUgVG9kZXNzZXF1ZW56ZW4sICVzISIsXAorIldhcywgJXMgaGF0IG1pciBXSUUgVklFTEUgTGViZW5zcHVua3RlIGFiZ2V6b2dlbj8/PyIsXAorIlZlcmRhbW10LCAlcyB3b2xsdGUgbmljaHQgc3RlcmJlbi4uLiIsXAorIlRvZCBkZW4gTW9uc3RlcnNjaGFlbmRlcm4hIFN0cmFmdCAlcyEiLFwKKyJOYWVjaHN0ZXMgTWFsIHdlcmRlIElDSCBzaWVnZW4sICVzISIsXAorIkZpbmRlc3QgRHUgZGFzIGZhaXIsICVzPyIsXAorIkRhcyB3YXIgZWluIGdlbWVpbmVyIFRpZWZzY2hsYWcsICVzISIsXAorIldlbm4gaWNoIG1hbCBncm9zcyBiaW4sIHphaGwgaWNoIERpciBkYXMgYWxsZXMgIlwKKyJoZWltLCAlcyEiLFwKKyJBTEFBQUFBQVJNISAlcyBJU1QgQVVTR0VCUk9DSEVOISIsXAorIkVpbiBLb2VuaWdyZWljaCBmdWVyIGRlbiwgZGVyIG1pciBkZW4gS29wZiB2b24gIlwKKyIlcyBicmluZ3QhIixcCisiU3VjaGUgS2lsbGVyLCB6YWhsZSBndXQsIFppZWxwZXJzb24gJXMuIixcCisiRGFzIHNhZyBpY2ggYWxsZXMgQm9pbmcsICVzISIsXAorIkRhcyBzYWcgaWNoIGFsbGVzIFJ1bWF0YSwgJXMhIixcCisiRGFzIHNhZyBpY2ggYWxsZXMgSm9mLCAlcyEiLFwKKyJEYXMgc2FnIGljaCBhbGxlcyBkZW0gU2hlcmlmZiwgJXMhIixcCisiS29tbSBEdSBtaXIgbnVyIHdpZWRlciwgJXMhIixcCisiSWNoIGZvcmRlcmUgUmV2YW5jaGUsICVzISIsXAorIlNoZXJpZmYhIFVudGVybmltbSB3YXMgZ2VnZW4gJXMhIixcCisiJXMsIHdlciBoYXQgRElDSCBkZW5uIGVpbmdlbGFkZW4/IixcCisiTkFFQ0hTVEVTIE1BTCBORUhNIElDSCBESUNIIEFVQ0ggTUlULCAlcyEiLFwKKyJIYWV0dGVuIHdpciBkYXMgbmljaHQgYXVzZGlza3V0aWVyZW4ga29lbm5lbiwgJXM/IixcCisiRGljaCBtZXJrIGljaCBtaXIsICVzISIsXAorIk5hIHByaW1hLCBzY2hvbiB3aWVkZXIgZGllc2VyIGR1bmtsZSBUeXAhIFVuZCAiXAorImFsbGVzIG51ciB3ZWdlbiAlcy4iLFwKKyJIYWxsbz8gSGF0IGplbWFuZCBtZWluZW4gS29lcnBlciBnZXNlaGVuPyBNdWVzc3RlICJcCisiaXJnZW5kd28gYmVpICVzIGxpZWdlbiEiLFwKKyIlcywgd2FlciBqZXR6dCBuaWNodCBlaWdlbnRsaWNoIFZvcmxlc3VuZz8iLFwKKyJMZXJuIGxpZWJlciwgc3RhdHQgdW5zY2h1bGRpZ2UgTW9uc3RlciB6dSBlciJcCisibW9yZGVuLCAlcyEiLFwKKyJPaG5lIGRpZXNlcyBMYWcgaGFldHRlIG1pY2ggJXMgbmljaHQgdW1nZWJyYWNodCEiLFwKKyJJbiBzcGFldGVzdGVucyBlaW5lciBTdHVuZGUga29tbWUgaWNoIHdpZWRlciwgJXMhIixcCisiTmEgd2FydGUgJXMsIGJlaW0gbmFlY2hzdGVuIE1hbCB0cmV0ZSBpY2ggRGlyICJcCisia3JhZWZ0aWcgaW4gZGVuIEdlZGFuLUJlcmVpY2ghIixcCisiU0NISUVCVU5HLCBkZXIgbGV0enRlIFNjaGxhZyB2b24gJXMgd2FyIG5pY2h0ICJcCisicmVnZWxnZXJlY2h0ISIsXAorIkxpZWJlciBlaW5lIEgyTy1WZXJnaWZ0dW5nLCBhbHMgdm9uICVzIGVybW9yZGV0ICJcCisienUgd2VyZGVuISIsXAorIkRpZSBFaHJlIHdlcmQgaWNoICVzIG5pY2h0IGFudHVuLCB1bmQgaGllciAiXAorImhlcnVtcG9zYXVuZW4sIHdlciBtaWNoIHVtZ2VuaWV0ZXQgaGF0ISIsXAorIklzIG1pciBkb2NoIGVnYWwgJXMsIGljaCBnbGF1YmUgYW4gIlwKKyJkaWUgV2llZGVyZ2VidXJ0ISIsXAorIkFiZXIgdm9yc2ljaHQsICVzIGlzY2gga3V1dWwgbWFlbiEiLFwKKyJPaywgJXMsIER1IHdpcnN0IHZvbiBtZWluZXIgRXJ3YXJ0ZWxpc3RlIGdlc3RyaWNoZW4hIixcCisiRGFzIG5hZWNoc3RlIE1hbCBzaWVodCBtYW4gdW5zZXJlIGJlaWRlbiBOYW1lbiBhdWYgW1RvZDpdLCAlcyEiLFwKKyJNYWdpZXIgenUgbWlyLCBoaWVyIGlzdCBlaW4gQnVnOiAlcyBpc3QgaW1tZXIgbm9jaCBuaWNodCB0b3QhIixcCisiTW9yZ2VuIGZydWVoIHVtIGhhbGIgc2VjaHMgaW4gZGVyIEFyZW5hLCAlcyEgSWNoIGhhYiBkaWUgV2FobCBkZXIgV2FmZmVuLiIsXAorIiVzIGlzdCBzY2hsaW1tZXIgYWxzIGRhcyBNZW5zYWVzc2VuLiBBYnNvbHV0IHRvZWRsaWNoLiIsXAorIk1pc3QsIG1laW5lIFZvcnNpY2h0IGhhdCB2ZXJzYWd0ISBVbmQgZGFzIGJlaSAlcyEiLFwKKyIlcywgZGllIEh5ZHJhIGlzdCBtaXIgbGllYmVyLi4uIixcCisiU28sIG1laW5lIElnbm9yaWVyZWxpc3RlIGlzdCBzY2hvbiB3aWVkZXIgdW0gZWluZW4gTmFtZW4gbGFlbmdlciwgJXMuIgorCisjZGVmaW5lIEtJTExfTUVTU0FHRVMyIFwKKyJGZWllcmFiZW5kISBEYW5rZSwgJXMhIixcCisiVG9sbCEgR0VOQVUgZGFzIGhhYiBpY2ggamV0enQgZ2VicmF1Y2h0ISBTdXBlciwgJXMhIDooIixcCisiU2Nob24gd2llZGVyIGVpbiBUYWcgdmVyc2F1dCB3ZWdlbiAlcyEiLFwKKyJJaHIgc2FndCwgSUNIIHNlaSBlaW4gTW9uc3Rlcj8gSWhyIGtlbm50ICVzIG5pY2h0ISEhIixcCisiU3BlcnJ0ICVzIG1hbCBpbidzIFBvbGFyZ2ViaWV0ISBHYWViZSBlaW4gZ3V0ZXMgVW50aWVyIGFiLi4uIixcCisiRnJlaWhlaXQgZnVlciBOaWNodC1TcGllbGVyISBWZXJuaWNodGV0ICVzISIsXAorIk1lcmxpbiwgbWFjaCAlcyB6dW0gTWFnaWVyISIsXAorIiVzIGlzdCBOSUNIVCB6dSBtZWluZXIgQmVlcmRpZ3VuZyBlaW5nZWxhZGVuISIsXAorIkljaCBoYWIga2VpbmUgQW5nc3Qgdm9yIERpciwgJXMhIixcCisiJXMgaXN0IGRvb2YgdW5kIHN0aW5rdCEiLFwKKyJNb2VnZXN0IER1IGltIExhZyB2ZXJyb3R0ZW4sICVzISIsXAorIiVzIHdpcmQgZ2xlaWNoIGRhcyBTcGllbCB2ZXJsYXNzZW4sIHVtIG1laW5lciBSYWNoZSB6dSBlbnRnZWhlbiEiLFwKKyJEZXIgVG9kZXN0YWcgdm9uICVzIHdpcmQgZnVlciBtaWNoIGVpbiBGZWllcnRhZyBzZWluISIsXAorIiVzIGlzdCBlaW4gTWV0emVsc2tyaXB0LCBpY2ggaGFiJ3MgZ2VuYXUgZ2VzZWhlbiEiLCBcCisiV2FlciBpY2ggVGFuamlhbiwgaGFldHRlc3QgRHUgZGFzIG5pY2h0IGdlc2NoYWZmdCwgJXMhIiwgXAorIkRhcyBuYWVjaHN0ZSBNYWwga29tbWUgaWNoIGFscyBLYWVtcGZlciB3aWVkZXIsICVzISIsIFwKKyJJY2ggbGFzcycgbWljaCBhdWZ3ZXJ0ZW4gdW5kIHdlcmRlIFphdWJlcmVyLCAlcyEiLCBcCisiR2lsZGVuYmFsYW5jZSEgJXMgaXN0IHZpZWwgenUgc3RhcmshIiwgXAorIkpldHp0IGlzdCBtaXIgZGFzIEtsZWluZ2VsZCB6dW0gVGFua2VuIGF1c2dlZ2FuZ2VuLCAlcy4uLiIsIFwKKyIlcyBoYXQgZWluIFphcC1Ub29sISIsIFwKKyIlcywgRHUgPHplbnNpZXJ0PiEiLCBcCisiJXMsIGRhcyBpc3QgZG9jaCBIdWxsZXBhbnouIChjKSBDYXR3ZWF6bGUiLCBcCisiQmFsZCBiaW4gaWNoIFN1cGVyU2VoZXIsICVzISIsIFwKKyJNaXQgRGlyICdwaWVsIGljaCBuaWNoJyBtZWhyLCAlcywgRHUgaGFzdCBpbiBtZWluIEZvZXJtc3NlbiBkZXBpbmtlbHQhIiwgXAorIlZlcmRhbW10LCAlcyBtdXNzIG1pciBkZW4gRmVlbnJpbmcgZ2VrbGF1dCBoYWJlbi4uLiIsIFwKKyJOaWUgaXN0IGVpbiBLbGVyaWtlciBpbiBkZXIgTmFlaGUsIHdlbm4gbWFuIGlobiBicmF1Y2h0LCAlcy4uLiIsIFwKKyJNZW5ubywgJXMsIHdvIHdhciBoaWVyIG5vY2ggbWFsIGRpZSBIZWlsc3RlbGxlPyIsIFwKKyJIb2ZmZW50bGljaCB3ZXJkZSBpY2ggbmFlY2hzdGVzIE1hbCBhbHMgS3VoIHdpZWRlcmdlYm9yZW4sICVzLi4uIiwgXAorIldlbm4gRHUgc29uc3Qgbm9jaCBQcm9ibGVtZSBoYXN0LCAlcywgZ2VoJyB6dSBNYXJ2aW4gdW5kIHJlZCcgIiBcCisibWl0IGlobSBkYXJ1ZWJlci4iLCBcCisiRHUsICVzLCBHZXdhbHQgaXN0IGtlaW5lIExvZXN1bmcsIGxhc3MgdW5zIGRhcnVlYmVyIGRpc2t1dGllcmVuLiIsIFwKKyJEYXMgbmFlY2hzdGUgTWFsIHplaWcnIGljaCBEaXIgbWVpbmUgTWF0ZXRlZXNhbW1sdW5nLCAlcy4iLCBcCisiJXMgZXVudCBkb211bSEiLCBcCisiJXMsIGlzdCBlcyBzbyBrYWx0IGhpZXIgb2RlciBiaW4gaWNoIGRhcz8iLCBcCisiSWNoIHdhciBzY2hvbiB3aWVkZXIgenVyIGZhbHNjaGVuIFplaXQgYW0gZmFsc2NoZW4gT3J0LCAlcy4uLiIsIFwKKyJEYW5rZSwgJXMuIEltIE5hbWVuIGRlcyBNb25kZXMgd2VyZGUgaWNoIERpY2ggYmVzdHJhZmVuISIsIFwKKyJEYXMgd2FyIG1hbCB3aWVkZXIgZWluIFNjaHVzcyBpbiBkZW4gT2ZlbiwgJXMuLi4iLCBcCisiS2FubnN0IER1IGRhcyBtaXQgRGVpbmVtIEdld2lzc2VuIHZlcmVpbmJhcmVuLCAlcz8iLCBcCisiVW5kIEthbmRyaSBzcHJhY2g6IE1laW4gaXN0IGRpZSBSYWNoZSwgJXMhIiwgXAorIiVzLCBEdSBoYWV0dGVzdCBtZWluZSBMZWljaGUgbmljaHQgYXVjaCBub2NoIHNjaGFlbmRlbiBtdWVzc2VuLi4uIiwgXAorIiVzLCBpY2gga2FubiBzbyBuaWNodCBhcmJlaXRlbiEiLCBcCisiJXMsIGljaCBnZWInIERpciBtYWwgMiBNdWVuemVuLCBkYW5uIGthbm5zdCBEdSBEZWluZSBTb3JnZW4gIiBcCisiamVtYW5kIGFuZGVyZW0gZXJ6YWVobGVuLi4uIiwgXAorIk1hbmNobWFsIHZlcnNwZWlzdCBEdSBkZW4gQmFlciwgJXMsIG1hbmNobWFsIHZlcnNwZWlzdCAiIFwKKyJkZXIgQmFlciBEaWNoLi4uIiwgXAorIkRhcyBuYWVjaHN0ZSBNYWwgYmV0cml0dHN0IF9EdV8gZGllIFdlbHQgZGVzIFNjaG1lcnplcywgJXMhIiwgXAorIldlbm4gaWNoIHdpZWRlcmtvbW1lLCAlcywgd2VyZGUgaWNoIGVyc3QgRGljaCB0b2V0ZW4sIGRhbm4gIiBcCisiRGVpbmVuIFBhcnRuZXIsIGRhbm4gRGVpbmUgQnJ1ZWRlciB1bmQgU2Nod2VzdGVybiB1bmQgamVkZW4gIiBcCisiZGVyIERpY2gga2VubnQhIiwgXAorIk9oIG5laW4sICVzISBTY2hvbiB3aWVkZXIgZGllc2UgZXdpZyBsYW5nZSBUb2Rlc3NlcXVlbnogbWl0IGRlciAiIFwKKyJEcmFjaGVuc2NodWxlISIsIFwKKyIlcywgd28gYmVrb21tZSBpY2ggamV0enQgZWluZW4gbmV1ZW4gS29lcnBlciBoZXI/IiwgXAorIkxhc3MgRGlyIG1laW5lIExlaWNoZSBzY2htZWNrZW4sICVzLiIsIFwKKyJIYWVoPyIsIFwKKyJKYSwgYWJlciB3aWVzbyBkYXMgZGVubj8gT2NoIG1lbm5vLCAlcyEiLCBcCisiU28gZWluIE1pc3QsICVzLCBpY2ggaGF0dGUgJ25lbiBEaXNjb25uZWN0Li4uIiwgXAorIip3aW5rZXdpbmtlKiwgJXMhIiwgXAorIkhldXRlIGlzdCBuaWNodCBhbGxlIFRhZ2UsIGljaCBrb21tJyB3aWVkZXIsIGtlaW5lIEZyYWdlLiIsIFwKKyJMYXNzIGRhcywgJXMhIiwgXAorIk5pZW1hbmQhIE5pZW1hbmQgbmVubnQgbWljaCBlaW5lIGZlaWdlIFNhdSwgJXMhIiwgXAorIkRhIGhhYicgaWNoIGpldHp0IHdvaGwgdmVybG9yZW4sICVzLi4uIiwgXAorIiVzLCBpY2gga2FubiBuaWNodCBtZXR6ZWxuLCBpY2gga2FubiBudXIgc3RlcmJlbi4uLiIsIFwKKyJIYXR0ZXN0IER1IHVlYmVyaGF1cHQgZWluZW4gVGVybWluLCAlcz8iLCBcCisiRHUgd2Fyc3QgZ2FyIG5pY2h0IGFuIGRlciBSZWloZSwgJXMhIiwgXAorIkFldHNjaCwgJXMsIGRlciBLaWxsIHphZWhsdCBuaWNodCEiLCBcCisiSmV0enQgbm9jaCBtYWwgbWl0IEdlZnVlaGwsICVzLiIsIFwKKyJUc2NodWVzcyBlcnN0bWFsLCAlcy4iLCBcCisiSWNoIHdlaXNzIG5pY2h0IG9iIER1IGVzIGdlbWVya3QgaGFzdCwgJXMsIGFiZXIgIiBcCisiaWNoIGJpbiBzY2hvbiB0b3QuLi4iLCBcCisiJXMsIGljaCBoYWV0dGUgbmljaHQgZ2VkYWNodCwgZGFzcyBpY2ggbm9jaCBtYWwgc3RlcmJlICIgXAorImJldm9yIFRhcmFtaXMgYW5nZXNjaGxvc3NlbiB3aXJkLi4uIiwgXAorIkljaCB3b2xsdGUgc293aWVzbyBncmFkZSBnZWhlbiwgJXMuIiwgXAorIlNoaXQgaGFwcGVucywgJXMuIiwgXAorIkRhenUgZmFlbGx0IG1pciBqZXR6dCBuaXggbWVociBlaW4sICVzLiIKKworI2RlZmluZSBLSUxMX01FU1NBR0VTMyBcCisiV2FzIGhlaXNzdCBkZW5uIFwiRGVpbiBUZWRkeSBrbnVkZGVsdCBEaWNoIGVpbiBsZXR6dGVzIE1hbFwiLCAlcz8iLCBcCisiSWNoIGJpbiBiZWVpbmRydWNrdCwgJXMuIiwgXAorIk9rLCBEZWluIEdlc2ljaHQgbWVya2UgaWNoIG1pciwgJXMhIiwgXAorIkthdW0gZGEsIGhhdXQgbWljaCAlcyBzY2hvbiB3aWVkZXIgdG90Li4uICpncnVtbWVsKiIsIFwKKyJJY2ggd2VyZGUgRGljaCB2ZXJmb2xnZW4sICVzISBJY2ggd2VyZGUgaW4gRGVpbmUgVHJhZXVtZSBlaW5kcmluZ2VuICIgXAorInVuZCBEaWNoIGluIGRlbiBXYWhuc2lubiB0cmVpYmVuISBEdSB3aXJzdCBkaWVzZW4gVGFnIG5vY2ggdmVyZmx1Y2hlbiEiLCBcCisiSWNoIGdlaCBqYSBzY2hvbiwgJXMuIiwgXAorIkF1ZiBkZW4gZXJzdGVuIEJsaWNrIHNpZWh0ICVzIGdhciBuaWNodCBzbyBnZWZhZWhybGljaCBhdXMuIiwgXAorIlZvbiAlcyBiZXNpZWd0IC0gd2llIHBlaW5saWNoLiIsIFwKKyJNaXN0LiBFaW5tYWwgbmljaHQgYXVmZ2VwYXNzdCwgc2Nob24gd2lyZCBtYW4gdm9uICVzIGVybW9yZGV0LiIsIFwKKyJEYXMgd2FyIGVpbiBHbHVlY2tzdHJlZmZlciwgJXMhIiwgXAorIkhhaCwgZGFzIGlzdCBkb2NoIG51ciBlaW5lIEZsZWlzY2h3dW5kZSEgR2lic3QgRHUgZXR3YSBzY2hvbiBhdWYsICVzPyIsIFwKKyIlcyBtYWNodCBnZXJhZGUgZWluZSBkZXN0cnVrdGl2ZSBQaGFzZSBkdXJjaC4iLCBcCisiWnVtIEdsdWVjayBpc3QgZGFzIGphIG51ciBlaW4gU3BpZWwsICVzLiBTb25zdCB3YWVyZSBpY2ggamV0enQgd2lya2xpY2ggIiBcCisiYm9lc2UuIiwgXAorIkJlZ3JhYmUgbWljaCB3ZW5pZ3N0ZW5zIGFuc3RhZW5kaWcsICVzLiIsIFwKKyJIbSwgZGllIEZsYXRyYXRlIGJyYXVjaCcgaWNoIGRhbm4gd29obCBkb2NoIG5pY2h0LCAlcy4iLCBcCisiTmEgd2FydGUsICVzISBadXIgU3RyYWZlIHdlcmRlIGljaCBnbGVpY2ggZGFzIE11ZCBjcmFzaGVuISIsIFwKKyJJY2ggc29sbHRlIG5pY2h0IG1laHIgc292aWVsIG11ZGRlbi4gRGFubiBtdWVzc3RlIGljaCBtaWNoIGF1Y2ggbmljaHQgbWVociAiIFwKKyJ1ZWJlciAlcyBhZXJnZXJuLiIsIFwKKyJBdWYgYW0gQm9kZW4gTGllZ2VuZGUgZWluenVzY2hsYWdlbiEgU2NoYWVtIERpY2gsICVzISIsIFwKKyJFaW5pZ2VuIHdpciB1bnMgYXVmIHVuZW50c2NoaWVkZW4sICVzPyIsIFwKKyJJY2ggc2FndGUgZG9jaCBcIkljaCBlcmdlYmUgbWljaCFcIiwgJXMuIiwgXAorIkFlaCwgJXMsIGtvZW5udGUgZGFzIHVudGVyIHVucyBibGVpYmVuPyBJY2ggaGFiZSBzY2hsaWVzc2xpY2ggZWluZW4gIiBcCisiUnVmIHp1IHZlcmxpZXJlbi4uLiIsIFwKKyJEdSBiaXN0IHZpZWxsZWljaHQgc3RhZXJrZXIsICVzLCBhYmVyIGRhZnVlciBiaW4gaWNoIHNjaG9lbmVyLiIsIFwKKyJEaWUgUmVjaG51bmcgZnVlciBkaWUgQmVoYW5kbHVuZyBtZWluZXIgTWluZGVyd2VydGlna2VpdHNrb21wbGV4ZSBnZWh0ICIgXAorImFuICVzLiIsIFwKKyJBYiB1bmQgenUgbXVzcyBtYW4gJXMgamEgZ2V3aW5uZW4gbGFzc2VuLCBzb25zdCBnaWJ0IGVzIHdpZWRlciBUcmFlbmVuLiIsIFwKKyJCaXMgZWJlbiB3YXIgbWlyICVzIG5vY2ggc3ltcGF0aGlzY2guIiwgXAorIkdlaHQncyBEaXIgamV0enQgYmVzc2VyLCAlcz8iLCBcCisiTWFjaHQga2FwdXR0LCB3YXMgbWljaCBrYXB1dHQgbWFjaHQhIFRvZXRldCAlcyEiLCBcCisiQmVpbSBuYWVjaHN0ZW4gTWFsIG1hY2gnIGljaCBlcyBEaXIgbmljaHQgbWVociBzbyBlaW5mYWNoLCAlcyEiLCBcCisiV2Vpc3N0IER1LCAlcywgaWNoIGhhYmUgbnVyIHZlcmxvcmVuLCB3ZWlsIER1Li4uIGFlaCwgd2VpbCBpY2guLi4gIiBcCisiYWVoLi4uIHdlaWwgRHUgZ2V3b25uZW4gaGFzdC4iLCBcCisiSm8sIGltbWVyIGZlc3RlIGRydWZmLCAlcy4gSXN0IGphIG51ciBlaW4gZHVtbWVyIE5QQy4gKmdydW1tZWwqIiwgXAorIkljaCBtdXNzIHNhZ2VuLCAlcyBrYW5uIGZlc3RlIHNjaGxhZ2VuLiIsIFwKKyJBbHNvICVzISBLb21tc3QgaGllciByZWluLCBoYXVzdCBtaWNoIHVtIHVuZCB0dXN0IGRhbm4gc28sIGFscyBzZWkgbmljaHRzICIgXAorImdld2VzZW4uLi4iLCBcCisiSW4gd2VsY2hlciBHaWxkZSBrb25udGUgbWFuIG5vY2htYWwgXCJiZWZyaWVkZVwiIGxlcm5lbiwgJXM/IiwgXAorIlRqYSwgJXMsIGF1cyBkaWVzZW0gS2FtcGYgYmlzdCBEdSB3b2hsIG51ciBhbHMgVm9ybGV0enRlciBoZXJ2b3JnZWdhbmdlbiIgXAorIi4uLiIsIFwKKyJWb3JzaWNodCwgJXMgZ3JlaWZ0IGltbWVyIHZvbiBoaW50ZW4gYW4hIiwgXAorIldhcyBtZWludCAlcyBtaXQgXCJTcGFycmluZ3NwYXJ0bmVyXCI/IiwgXAorIkljaCBoYWJlIG1pciBiZWkgRGlyIG51ciBkZXNoYWxiIGtlaW5lIE11ZWhlIGdlZ2ViZW4sICVzLCB3ZWlsIER1IGVoIG5pY2h0ICIgXAorInN0dXBzdC4iLCBcCisiSHVjaCwgaWNoIGJpbiBqYSBzY2hvbiB3aWVkZXIgYXVmIC1Nb2VyZGVyISIsIFwKKyJJY2ggc3B1Y2snIERpciBpbidzIEF1Z2UgdW5kIGJsZW5kZSBEaWNoLCAlcyEiLCBcCisiSHVjaCwgd28gc2VpZCBpaHIgYWxsZSBoaW4/IiwgXAorIldlciB3YXIgZGFzPyIsIFwKKyJNb2VnZXN0IER1IGluIGludGVyZXNzYW50ZW4gWmVpdGVuIGxlYmVuLCAlcy4iLCBcCisiSWNoIHNlaGUgd2FzLCB3YXMgRHUgbmljaHQgc2llaHN0LCAlcywgdW5kIGVzIGlzdC4uLiBzY2h3YXJ6LiIsIFwKKyJIZXkgTWFlZGVscyEgUmF0ZXQsIHdlbiBpY2ggZ2VyYWRlIGdldHJvZmZlbiBoYWJlISIsIFwKKyIlcz8iLCBcCisiTm9jaCBlaW5tYWwgc293YXMsICVzLCB1bmQgaWNoIGxhc3NlIERlaW5lIEdpbGRlIGFid2VydGVuLiBJY2gga2FubiBkYXMhIiwgXAorIldhcyBiZWRldXRldCAnSmVtYW5kIGJlc2Nod29lcnQgRGVpbiBCaWxkIGhlcmF1Zi4nPyBXYXJzdCBEdSBkYXMsICVzPyIKKworcHJpdmF0ZSBzdHJpbmcgKm1vZXJkZXJfbXNncyA9ICh7S0lMTF9NRVNTQUdFUywgS0lMTF9NRVNTQUdFUzIsIEtJTExfTUVTU0FHRVMzLAorIlN0ZXJiZW4gaXN0IHNjaG9lbiwgU3RlcmJlbiBpc3QgdG9sbCAtIEFjaCB3YWVyIGljaCB3aWUgZWluIEthZW1wZmVyIHZvbGwhIiwKKyJMYXVzY2hpZ2UgTmFjaHQgLSBpY2ggZ2VoIG1pciBkaWUgU3Rlcm5lIGFuc2NoYXVlbi4gQmlzIHNwYWV0ZXIhIiwKKyJFY2h0ICVzLCBkYXMgd2FyIDA4MTUsIGtlaW5lIEtyZWF0aXZpdGFldCBiZWltIFRvZXRlbiEiLAorIiVzLCBEdSBrYW5uc3QgamEgZ2FyIG5pLi4uIFZlcmRhbW10ISIsCisiS2FlbXBmZXIsIFphdWJlcmVyLCBUYW5qaWFuLCBhbGxlcyBMdXNjaGVuISBJY2ggd2VyZGUgQWJlbnRldXJlciwgZGEgaXN0ICIKKyAgICAid2VuaWdzdGVucyBUaHJpbGwhIiwgCisiVG9ldGVuLCBUb2V0ZW4sIFRvZXRlbi4gSXN0IGRhcyBhbGxlcywgd2FzIER1IGthbm5zdCwgJXM/IiwKKyJBY2ggZ2VoIGRvY2ggQmx1ZW1jaGVuIHBmbHVlY2tlbiAlcyEiLCAKKyJNZWluIFRvZCB3YXIgS0VJTiBGUCAlcy4uLiBIQSEiLAorIkxhcnMgZ2lidCBtaXIgbmVuIFdoaXNreSwgd2VubiBpY2gga29tbWUuIFVuZCBEaXI/IiwKKyJHZWggbGVybmVuLCBEZXBwISIsCisiQXVmIGRlciBuYWVjaHN0ZW4gTXVkLVBhcnR5IGhhdXQgRGljaCBtZWluIE1hZ2llciB6dXJ1ZWNrISIsCisiTGFzcyBndXQgc2VpbiwgdGF0IGVoIG5pY2h0IHdlaCEiLCAKKyJJY2ggbGFzcyBEaWNoIHZvbiBab29rIGFiaGFlbmdlbiwgJXMhIiwKKyJLb2VubmVuIHdpciBuYWVjaHN0ZXMgTWFsIG5pY2h0IGxpZWJlciBlaW5lbiB0cmlua2VuIGdlaGVuLCAlcz8iLAorIlZlcmRhbW10LCBtZWluZSBuZXVlIEdpbGRlIGlzdCBqYSBub2NoIGdhciBuaWNodCBhbmdlc2NobG9zc2VuISIsCisiWW9ob2hvIHVuZCBuZSBCdWRkZWwgdm9sbCBSdW0hIiwKKyJCZWltIEthcnRlbnNwaWVsIGhhZXR0ZXN0IER1IGtlaW5lIENoYW5jZSBnZWhhYnQgJXMhIiwKKyIlcywgRHUgaGFzdCBlY2h0IGtlaW5lIEFobnVuZyB2b24gc3RpbHZvbGxlbSBNZXR6ZWxuLi4uIiwKKyJXYXMgbXVzcyBpY2ggbm9jaCB0dW4gZnVlciBEZWluZW4gQXVmc3RpZWcsICVzPyAqc2V1ZnoqIiwKKyJFSy1Qb3NlciEiLAorIkxlaXN0dW5nIGlzdCB3YXMgYW5kZXJlcywgJXMhIiwKKyJMYXNzIG1pY2ggbGVlZWVlZWIuLi4gQXJycnJnZ2dnaCEiLAorIkhhc3QgRHUgc29uc3Qgbml4IGluIGRlciBEcmFjaGVuc2NodWxlIGdlbGVybnQsICVzPyIsCisiVW5kIHdlciBrdWVtbWVydCBzaWNoIGpldHp0IHVtIG1laW5lIEhhdXN0aWVyZSwgJXM/IiwKKyJJY2ggbXVzc3RlIHN0ZXJiZW4sIER1IHdpbGxzdCBtaWNoIG51ciBiZWVyYmVuLiBJY2ggZ2VoZSAiCisgICAgIm1pdCBTdGlsLCBEdSBmaW5kZXN0IG5pY2h0IHZpZWwuIiwKKyJJY2ggaGFiZSBudW4gbWVociBUb2RlIGFscyBEdSwgJXMuIFRvcHAgbWljaCwgd2VubiBEdSBrYW5uc3QhIiwKKyJPaywgZGFubiBnZWggaWNoIGhhbHQgV09XIHNwaWVsZW4uIiwKKyJUb2xsLCBmcmV1dCBzaWNoIGRlciBOYWVjaHN0ZS4gV2llZGVyIG5lIFRvZGVzZm9sZ2UsICVzLiIsCisiRHUgZ3Vja3Rlc3Qgc28gdHJhdXJpZywgJXMsIGljaCBtYWNodGUgRGlyIG1laW5lbiBUb2QgenVtIEdlc2NoZW5rLiAiCisgICAgIlNvbGxzdCBqYSBhdWNoIG1hbCAnbiBFcmZvbGdzZXJsZWJuaXMgaGFiZW4hIiwKKyJOdW4gcmVpY2hlIGljaCBkZW4gbGV0enRlbiBCZWNoZXIsIHRyaW5rZSBkZW4gV2VpbiwgZXJrZW5uZSBEZWluIFNlaW4uIiwKKyIlcyBoYXQgbmljaHQgZWlubWFsIGdldHJvZmZlbi4gSWNoIGhhYmUgbWljaCB3b3J0d29lcnRsaWNoIHRvdGdlbGFjaHQuIiwKKyJMYXNzIG1pY2ggbmFjaGRlbmtlbiwgJXMuIEljaCBzdGFyYiBmdWVyIG5lbiBFSz8iLAorIkljaCBrYW5uIG5pY2h0IGdsYXViZW4sIGRhc3MgZGFzIGdlcmFkZSBwYXNzaWVydCBpc3QhIiwKKyJEdSBTdWVuZGVyLiBEdSBzb2xsc3QgX25pY2h0XyB0b2V0ZW4hIiwKKyIlcywgbWVpbiBUZXN0YW1lbnQgc3RlY2t0IGltIHJlY2h0ZW4gU2NodWghIiwKKyJTdGVyYmVuIHVuZCBzdGVyYmVuIGxhc3NlbiwgbWVpbiBGcmV1bmQuIFdpciBzZWhlbiB1bnMgd2llZGVyISIsCisiVW5kIGljaCBzYWcgbm9jaCwgJXMuLi4gRGFzIGlzdCBLRUlORSBTY2h3ZXJ0c2NoZWlkZS4uLiBBYmVyIER1IG11c3N0ICIKKyAgImphIGFsbGVzIHNlbGJzdCBhdXNwcm9iaWVyZW4uIiwKKyJTb2xsIGRhcyBqZXR6dCBhbGxlcyBnZXdlc2VuIHNlaW4sICVzPyIsCisiSW4gbWVpbmVtIENvZGUgaXN0IGVpbiBGZWhsZXIgdW5kIGdsZWljaCBnaWJ0J3MgJ25lbiBDcmFzaC4iLAorIkFjaCwgYXVjaCBlZ2FsLCAlcy4gSXN0IGVoIGdsZWljaCBTY2hpY2h0d2VjaHNlbC4iLAorIkpvZnZlcmRhbW10Li4uIHdhcnN0IER1IGd1dCwgJXMhIiwKKyJEdWVsbGUgdm9uIEtpbGxlcm4gZW5kZW4gbWVpc3QgZnVlciBlaW5lbiB0b2VkbGljaCB1bmQgZGFzIHdpcnN0ICIKKyAgIkR1IHMuLi4gQXJnaCEiLAorIkJpc3QgRHUgc2ljaGVyLCBkYXNzIER1IGRlbiBFSyBiZWtvbW1lbiBoYXN0LCAlcz8iLAorIkRhbmtlICVzISBXZWlzc3QgRHUsIGljaCBoYXR0ZSBtaXQgWm9vayBnZXdldHRldCwgd2VyIG1pY2ggIgorICAidG9ldGV0LiBVbmQgaWNoIGhhYmUgZWluZSBXaWVkZXJnZWJ1cnQgZ2V3b25uZW4hIiwKKyJOdW4gYmluIGljaCBzaWNoZXIgdm9yIERpciwgJXMhIiwKKyJJY2ggbWFjaGUgamV0enQgVXJsYXViIHVuZCBoYWJlIFpvb2sgZ2ViZXRlbiwgbWVpbmVuIFJlc2V0ICIKKyAgInVtIGVpbmVuIE1vbmF0IHp1IHZlcnNjaGllYmVuLiBHbHVlY2tsaWNoLCAlcz8iLAorfSk7CisKKworaW50IF9xdWVyeV9rbWEoKSB7IHJldHVybiBzaXplb2YobW9lcmRlcl9tc2dzKTsgfQorCisKK29iamVjdCBfY2hhbm5lbCggb2JqZWN0IG9iICkKK3sKKyAgaW50IG1fRk1NLCBtX0hQLCBtX1dDLCBtX0FDLCBzX0hQLCBzX1dDLCBzX0FDOworICBzdHJpbmcgbXNnOworICBvYmplY3QgcnVlY2s7CisKKyAgaWYgKG1lbWJlcihpbmhlcml0X2xpc3QocHJldmlvdXNfb2JqZWN0KCkpLENPUlBTRV9PQkopPi0xKQorICAgICAgeworICAgICAgICAgIHN0cmluZyBraWxsZXI7CisgICAgICAgICAgaW50IGksIHgsIHksIHosIG5yOworICAgICAgICAgIGNsb3N1cmUgbV9xLCBzX3E7CisgICAgCisgICAgICAgICAgd2hpbGUoIHByZXZpb3VzX29iamVjdChpKSAmJgorICAgICAgICAgICAgICAgICAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShwcmV2aW91c19vYmplY3QoaSkpICkKKyAgICAgICAgICAgICAgaSsrOworICAgICAgICAgIAorICAgICAgICAgIGlmKCAhcHJldmlvdXNfb2JqZWN0KGkpIHx8IElTX0xFQVJORVIocHJldmlvdXNfb2JqZWN0KGkpKSApCisgICAgICAgICAgICAgIHJldHVybiBydWVjazsKKworICAgICAgICAgIGtpbGxlciA9IChzdHJpbmcpIHByZXZpb3VzX29iamVjdChpKS0+bmFtZSgpOworICAgICAgICAgIAorICAgICAgICAgIGlmICggbG93ZXJfY2FzZShraWxsZXIpICE9IGdldHVpZChwcmV2aW91c19vYmplY3QoaSkpICkKKyAgICAgICAgICAgICAga2lsbGVyID0gY2FwaXRhbGl6ZShnZXR1aWQocHJldmlvdXNfb2JqZWN0KGkpKSk7CisgICAgICAgICAgCisgICAgICAgICAgbV9xID0gc3ltYm9sX2Z1bmN0aW9uKCAiUXVlcnlQcm9wIiwgb2IgKTsgLy8gTW9uc3RlcgorICAgICAgICAgIHNfcSA9IHN5bWJvbF9mdW5jdGlvbiggIlF1ZXJ5UHJvcCIsIHByZXZpb3VzX29iamVjdChpKSApOyAvLyBTcGllbGVyCisgICAgICAgICAgCisgICAgICAgICAgaWYgKCAobV9GTU0gPSAoaW50KSBmdW5jYWxsKCBtX3EsIFBfRk9SQ0VfTVVSREVSX01TRyApKSA+PSAwICkKKyAgICAgICAgICAgICAgaWYgKCAob2JqZWN0X25hbWUob2IpID09ICIvb2JqL3NodXQiKSB8fAorICAgICAgICAgICAgICAgICAgIChtX0ZNTSA+IDApIHx8CisgICAgICAgICAgICAgICAgICAgKG5yID0gKHJhbmRvbSgxMDApID49IDk5KSA/IDEgOiAwICkgfHwgCisgICAgICAgICAgICAgICAgICAgKG5yID0gKCh4ID0gKG1fSFAgPSAoaW50KSBmdW5jYWxsKCBtX3EsIFBfTUFYX0hQICkpICogCisgICAgICAgICAgICAgICAgICAgICAgICAgICAoKG1fV0MgPSAoaW50KSBmdW5jYWxsKCBtX3EsIFBfVE9UQUxfV0MgKSkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgIChtX0FDID0gKGludCkgZnVuY2FsbCggbV9xLCBQX1RPVEFMX0FDICkpKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgPiAyMDAwMDApID8gMiA6IDApIHx8CisgICAgICAgICAgICAgICAgICAgKG5yID0gKCgoeSA9IG1fSFAgKiAobV9XQyArIG1fQUMpKSA+CisgICAgICAgICAgICAgICAgICAgICAgICAgICAoeiA9IDUgKiAoc19IUCA9IChpbnQpIGZ1bmNhbGwoIHNfcSwgUF9NQVhfSFAgKSkgKgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoc19XQyA9IChpbnQpIGZ1bmNhbGwoIHNfcSwgUF9UT1RBTF9XQyApKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzX0FDID0gKGludCkgZnVuY2FsbCggc19xLCBQX1RPVEFMX0FDICkpKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgID8gMyA6IDApKSkKKyAgICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgICBTZXRQcm9wKCBQX05BTUUsICJHZWlzdCAiKyhzdHJpbmcpIG9iLT5uYW1lKFdFU1NFTiwgMCkgKTsKKworICAgICAgICAgICAgICAgICAgICAgIGlmKCAhKG1zZyA9IChzdHJpbmcpIG9iLT5RdWVyeVByb3AoUF9NVVJERVJfTVNHKSkgKQorICAgICAgICAgICAgICAgICAgICAgICAgICBtc2cgPSBtb2VyZGVyX21zZ3NbcmFuZG9tKHNpemVvZihtb2VyZGVyX21zZ3MpKV07IAorCisJCSAgICAgIGlmICggc3RyaW5ncChtc2cpICkKKwkJCSAgbXNnID0gc3ByaW50ZiggbXNnLCBraWxsZXIgfHwgIk1vZXJkZXIiICk7CisKKyAgICAgICAgICAgICAgICAgICAgICBDSE1BU1RFUi0+c2VuZCggIk1vZXJkZXIiLCB0aGlzX29iamVjdCgpLCBmdW5jYWxsKG1zZykgKTsKKworICAgICAgICAgICAgICAgICAgICAgIHJ1ZWNrID0gcHJldmlvdXNfb2JqZWN0KGkpOworICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgIAorICAgICAgICAgIGxvZ19maWxlKCAibW9lcmRlci5sb2ciLAorICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCAiTU9OKCVPKSBDT05EKCVkKSBOUEMoJWQpLCBESUZGKCVkLCVkKVxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2IsIG5yLCB4LCB5LCB6KSApOworICAgICAgfQorCisgIHJldHVybiBydWVjazsKK30KKwordm9pZCB0cmFuc2Zvcm1faW50b19waWxlKCkgeworCWlmKCBlbnZpcm9ubWVudCgpLT5RdWVyeVByb3AoUF9QUkVWRU5UX1BJTEUpICkgcmV0dXJuOworCW9iamVjdCogaW52ID0gYWxsX2ludmVudG9yeSgpOworCWlmKCBzaXplb2YoaW52KTwyICkgcmV0dXJuOworCW9iamVjdCBwID0gY2xvbmVfb2JqZWN0KFBJTEVfT0JKKTsKKwlmaWx0ZXJfb2JqZWN0cyggaW52LCAibW92ZSIsIHAsIE1fU0lMRU5UIHwgTV9OT0NIRUNLICk7CisJcC0+bW92ZSggZW52aXJvbm1lbnQoKSwgTV9TSUxFTlQgfCBNX05PQ0hFQ0sgKTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9kZWZfd29ya3Jvb20uYyBiL3N0ZC9kZWZfd29ya3Jvb20uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMjAzNGZhCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2RlZl93b3Jrcm9vbS5jCkBAIC0wLDAgKzEsNDYgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBkZWZfd29ya3Jvb20uYyAtLSBzdGFuZGFyZCB3b3Jrcm9vbSBmb3IgbmV3IHdpemFyZHMKKy8vCisvLyAkSWQ6IGRlZl93b3Jrcm9vbS5jIDc0MjMgMjAxMC0wMi0wNyAyMjo1NjozOFogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzLHNhdmVfdHlwZXMscnR0X2NoZWNrcworI3ByYWdtYSBwZWRhbnRpYywgcmFuZ2VfY2hlY2sKKworaW5oZXJpdCAic3RkL3Jvb20iOworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCit2b2lkIGNyZWF0ZSgpCit7CisgIHN0cmluZyBXSVpOQU1FOworCisgIDo6Y3JlYXRlKCk7CisgIFdJWk5BTUUgPSBjYXBpdGFsaXplKGdldHVpZCh0aGlzX29iamVjdCgpKSk7CisKKyAgU2V0UHJvcCggUF9MSUdIVCwgMSApOworICBTZXRQcm9wKCBQX0lOVF9TSE9SVCwgIkRlciBBcmJlaXRzcmF1bSB2b24gIitXSVpOQU1FICk7CisgIFNldFByb3AoIFBfSU5UX0xPTkcsCisgICAiRGllc2VzIGlzdCBkZXIgQXJiZWl0c3JhdW0gdm9uICIrV0laTkFNRSsiLiBFcyBsaWVnZW4gdm9sbGdlc2NocmllYmVuZVxuIgorICArIlpldHRlbCBhdWYgZGVtIEJvZGVuLCBkaWUgV2FlbmRlIHNpbmQgbWl0IEtyZWlkZXplaWNoZW4genVnZWtyaXR6ZWx0LlxuIgorICArIk1hbiBtZXJrdCwgZGFzcyBkaWVzZXIgUmF1bSBkYWZ1ZXIgZGEgaXN0LCBkYXNzICIrV0laTkFNRSsiIGZ1ZXIgc2ljaFxuIgorICArInVuZ2VzdG9lcnQgYXJiZWl0ZW4ga2Fubi4gRWluIG1hZ2lzY2hlcyBQb3J0YWwgZnVlaHJ0IGluIGRpZSBXZWx0XG4iCisgICsiZGVyIFN0ZXJibGljaGVuLlxuIgorCSAgKTsKKyAgU2V0UHJvcChQX0lORE9PUlMsMSk7CisgIEFkZERldGFpbCggKHsgInBvcnRhbCIsICJwb3J0YWxlIiB9KSwgCisJICAgICJEYXMgUG9ydGFsIGZ1ZWhydCBpbiBkaWUgQWJlbnRldXJlci1naWxkZS5cbiIgKTsKKyAgQWRkRGV0YWlsKCAoeyAicmF1bSIsICJhcmJlaXRzcmF1bSIgfSksCisJICAgICAiRHUgYmVmaW5kZXN0IERpY2ggbWl0dGVuZHJpbi5cbiIgKTsKKyAgQWRkRGV0YWlsKCAiemV0dGVsIiwKKwkgICAgICJEaWUgWmV0dGVsIHNpbmQgbWl0IHVubGVzZXJsaWNoZW4gWmVpY2hlbiB2b2xsZ2VzY2hyaWViZW4uXG4iICk7CisgIEFkZERldGFpbCggKHsgImJvZGVuIiwgImZ1c3Nib2RlbiIgfSksCisJICAgICAiRGVyIEZ1c3Nib2RlbiBpc3QgYmVkZWNrdCBtaXQgdm9sbGdlc2NocmllYmVuZW4gWmV0dGVsbi5cbiIgKTsKKyAgQWRkRGV0YWlsKCAoeyAid2FuZCIsICJ3YWVuZGUiIH0pLAorCSAgICAgIkFuIGRlbiBXYWVuZGVuIGJlZmluZGVuIHNpY2ggS3JlaWRlemVpY2hlbi5cbiIgKTsKKyAgQWRkRGV0YWlsKCAoeyAia3JlaWRlIiwgImtyZWlkZXplaWNoZW4iLCAiemVpY2hlbiIgfSksCisJICAgICJEaWUgWmVpY2hlbiBlcmdlYmVuIG51ciBmdWVyICIgKyBXSVpOQU1FICsgIiBlaW5lbiBTaW5uLlxuIiApOworICBBZGREZXRhaWwoICJwb3J0YWwiLAorCSAgICAgIkRhcyBQb3J0YWwgZnVlaHJ0IGluIGRpZSBXZWx0IGRlciBTdGVyYmxpY2hlbi5cbiIgKTsKKyAgQWRkRXhpdCgiZ2lsZGUiLCJpbiBkaWUgR2lsZGUjL2dpbGRlbi9hYmVudGV1cmVyIik7Cit9CmRpZmYgLS1naXQgYS9zdGQvZm9vZC5jIGIvc3RkL2Zvb2QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43Yjc1OTIxCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2Zvb2QuYwpAQCAtMCwwICsxLDczMiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIC9zdGQvZm9vZC5jICAtIFN0YW5kYXJkb2JqZWt0IGZ1ZXIgTGViZW5zbWl0dGVsCisvLworLy8gJElkOiBmb29kLmMgODI0OCAyMDEyLTExLTIzIDIxOjI4OjA0WiBaZXNzdHJhICQKKyNwcmFnbWEgc3RyaWN0X3R5cGVzLHNhdmVfdHlwZXMscnR0X2NoZWNrcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYyxyYW5nZV9jaGVjaworCitpbmhlcml0ICIvc3RkL3RoaW5nIjsKKworI2luY2x1ZGUgPGZvb2QuaD4KKyNpbmNsdWRlIDxsaXZpbmcvbGlmZS5oPgorI2luY2x1ZGUgPGJyZWFrX3N0cmluZy5oPgorCisvLyBTdGFuZGFyZC1JRHMgdW5kIC1BZGpla3RpdmUgbXVlc3NlbiBnZXNpY2hlcnQgd2VyZGVuCisjZGVmaW5lICBJRF9CQUNLVVAgICAgICAgInN0ZF9mb29kX2lkX2JhY2t1cCIKKyNkZWZpbmUgIEFESl9CQUNLVVAgICAgICAic3RkX2Zvb2RfYWRqX2JhY2t1cCIKKworLy8gWmVpdHB1bmt0LCBhbiBkZW0gZGllIFNwZWlzZSB2ZXJkb3JiZW4gaXN0Citwcml2YXRlIG5vc2F2ZSBpbnQgdGltZV9nb25lX2JhZDsKKworLy8gWmVpdHB1bmt0LCBhbiBkZW0gZGllIFNwZWlzZSB2ZXJkZXJiZW4gZGFyZgorLy8gd2lyZCBpbW1lciBlcnN0IGdlc2V0enQsIHdlbm4gZWluIFNwaWVsZXIgaGllcm1pdCBpbiBCZXJ1ZWhydW5nIGtvbW10Citwcml2YXRlIG5vc2F2ZSBpbnQgdGltZV90b2dvX2JhZDsKKworLy8gWmVpdHB1bmt0LCBhbiBkZW0gZGllIFNwZWlzZSB6ZXJzdG9lcnQgd2VyZGVuIGRhcmYKKy8vIHdpcmQgaW1tZXIgZXJzdCBnZXNldHp0LCB3ZW5uIGVpbiBTcGllbGVyIGhpZXJtaXQgaW4gQmVydWVocnVuZyBrb21tdAorcHJpdmF0ZSBub3NhdmUgaW50IHRpbWVfdG9fcmVtb3ZlOworCisvLyBaZWl0cHVua3QsIGFiIGRlbSBkaWUgU3BlaXNlIG1pdCBlaW5lbSBTcGllbGVyIGluIEJlcnVlaHJ1bmcga2FtCisvLyBiZWkgZXdpZyBoYWx0YmFyZW4gU3BlaXNlbiBpc3Qgc2llIGltbWVyIDA7Citwcml2YXRlIG5vc2F2ZSBpbnQgc3RhcnRfbGlmZSA9IDA7CisKKy8vIERhdWVyIGRlcyBlcnN0ZW4gUmVzZXRzCitwcml2YXRlIG5vc2F2ZSBpbnQgZmlyc3RfcmVzZXRfbGVuZ3RoID0gMDsKKworLy8gV2VydGV0IFByb3BlcnRpZXMgYXVzIChFcnNldHp1bmdlbiB3ZXJkZW4gZHVyY2hnZWZ1ZWhydCkKK3Byb3RlY3RlZCBtaXhlZCBldmFsX3Byb3BlcnR5KHN0cmluZyB2YWwsb2JqZWN0IGNvbnN1bWVyKSB7CisgIG1peGVkIHdoYXQgPSBRdWVyeVByb3AodmFsKTsKKyAgaWYgKHN0cmluZ3Aod2hhdCkpIHsKKyAgICB3aGF0PWNhcGl0YWxpemUocmVwbGFjZV9wZXJzb25hbCh3aGF0LCh7dGhpc19vYmplY3QoKSxjb25zdW1lcn0pLDEpKTsKKyAgfQorICByZXR1cm4gYnJlYWtfc3RyaW5nKHdoYXQsNzgsIiIsQlNfTEVBVkVfTVlfTEZTKTsKK30KKworLy8gd2lyZCBudXIgdmVyd2VuZGV0LCB3ZW5uIGRlciBnZXNldHp0ZSBSZXNldCBlaW4gVGltZXJlbmRlIGRhcnN0ZWxsdCwKKy8vIHVtIHp1IGdhcmFudGllcmVuLCBkYXNzIGRlciBuaWNodCBhYmdlc3RlbGx0IHdpcmQuCisvLyBadWdlZ2ViZW5lbmVybWFzc2VuIGtlaW5lIHNjaG9lbmVyIEhhY2sgOi0vCitwcml2YXRlIHZvaWQgbXlfc2V0X25leHRfcmVzZXQoaW50IHplaXQpIHsKKyAgc2V0X25leHRfcmVzZXQoemVpdCk7CisgIC8vIERhbWl0IGRlciBSZXNldCBhdWNoIHdpcmtsaWNoIGF1c2dlZnVlaHJ0IHdpcmQgLi4uCisgIGNhbGxfb3V0KCMnaWQsMSk7Cit9CisKKy8vIEF1c2dhYmUgdm9uIE1lbGR1bmdlbiBhbiBCZXNpdHplciBvZGVyIFJhdW0KK3Byb3RlY3RlZCB2b2lkIG1lc3NhZ2Uoc3RyaW5nIHByb3ApIHsKKyAgb2JqZWN0IGVudiA9IGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpOworICBpZiAob2JqZWN0cChlbnYpKSB7CisgICAgaWYgKGludGVyYWN0aXZlKGVudikpIHsKKyAgICAgIHRlbGxfb2JqZWN0KGVudiwKKyAgICAgICAgYnJlYWtfc3RyaW5nKGV2YWxfcHJvcGVydHkocHJvcCxlbnYpLDc4LCIiLEJTX0xFQVZFX01ZX0xGUykpOworICAgIH0KKyAgICBlbHNlIGlmKCFsaXZpbmcoZW52KSkgeworICAgICAgdGVsbF9yb29tKGVudiwKKyAgICAgICAgYnJlYWtfc3RyaW5nKGV2YWxfcHJvcGVydHkocHJvcCwwKSw3OCwiIixCU19MRUFWRV9NWV9MRlMpKTsKKyAgICB9CisgIH0KK30KKworLy8gRmxhZywgb2IgZGllIFNwZWlzZSB2ZXJkb3JiZW4gaXN0CitwdWJsaWMgaW50IGlzX2JhZCgpIHsKKyAgcmV0dXJuIHRpbWVfZ29uZV9iYWQgPiAwOworfQorCisvLyBBbnphaGwgZGVyIFNla3VuZGVuLCBkaWUgZGFzIExlYmVuc21pdHRlbCBiZXJlaXRzIGhpbnRlciBzaWNoIGhhdCwKKy8vIHNlaXQgZXMgbWl0IGVpbmVtIFNwaWVsZXIgaW4gQmVydWVocnVuZyBrYW0KK3B1YmxpYyBpbnQgZ2V0X2N1cnJlbnRfbGlmZXRpbWUoKSB7CisgIGlmICghc3RhcnRfbGlmZSkgcmV0dXJuIDA7CisgIHJldHVybiB0aW1lKCkgLSBzdGFydF9saWZlOworfQorCisvLyBCZXJlY2huZXQgZGVuIFdlcnQgZGVyIFNwZWlzZSBrb3JyZWt0CitpbnQgX3F1ZXJ5X3ZhbHVlKCkgeworICBpbnQgcmVzdWx0ID0gMDsKKyAgaWYgKCFpc19iYWQoKSkgeworICAgIHJlc3VsdCArPSB0b19pbnQoUXVlcnlQcm9wKFBfUE9SVElPTlMpKlF1ZXJ5KFBfVkFMVUUsRl9WQUxVRSkpOworICB9CisgIGlmIChtYXBwaW5ncChRdWVyeVByb3AoUF9FTVBUWV9QUk9QUykpKSB7CisgICAgcmVzdWx0ICs9IFF1ZXJ5UHJvcChQX0VNUFRZX1BST1BTKVtQX1ZBTFVFXTsKKyAgfQorICByZXR1cm4gcmVzdWx0OworfQorCisvLyBCZXJlY2huZXQgZGVuIFdlcnQgZGVyIFNwZWlzZSBrb3JyZWt0CitpbnQgX3F1ZXJ5X3dlaWdodCgpIHsKKyAgaW50IHJlc3VsdCA9IHRvX2ludChRdWVyeVByb3AoUF9QT1JUSU9OUykqUXVlcnkoUF9XRUlHSFQsRl9WQUxVRSkpOworICBpZiAobWFwcGluZ3AoUXVlcnlQcm9wKFBfRU1QVFlfUFJPUFMpKSkgeworICAgIHJlc3VsdCArPSBRdWVyeVByb3AoUF9FTVBUWV9QUk9QUylbUF9XRUlHSFRdOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIERhdWVyIGRlcyBlcnN0ZW4gUmVzZXRzIHdpcmQgd2llZGVyIGhpbnp1Z2VyZWNobmV0CisvLyBkYW1pdCB3aXJkIGJlaSBOaWNodHNldHplbiBkZXIgUHJvcCBkZXIgU3RhbmRhcmQgZ2VsaWVmZXJ0CitpbnQgX3F1ZXJ5X3N0ZF9mb29kX2xpZmV0aW1lKCkgeworICByZXR1cm4gUXVlcnkoUF9MSUZFVElNRSxGX1ZBTFVFKSsoZmlyc3RfcmVzZXRfbGVuZ3RoKTsKK30KKworLy8gU2V0dGVyIGZ1ZXIgZGllIExpZmV0aW1lLCBkYW1pdCBkaWUgUmVzZXR0aW1lIGltbWVyIG1pdGtvcnJpZ2llcnQgd2lyZAorLy8gdW5kIERhdWVyIGRlcyBlcnN0ZW4gUmVzZXRzIGFiZ2V6b2dlbiB3ZXJkZW4sIGRhIGRpZSBhbHMgU3RhbmRhcmQgaW1tZXIKKy8vIGRhenVrb21tZW4KK3Byb3RlY3RlZCB2b2lkIHNldF9zdGRfZm9vZF9saWZldGltZShpbnQgdmFsKSB7CisgIGlmICh2YWwgPiAwKSB7CisgICAgaWYgKCF0aW1lX3RvZ29fYmFkICYmICFpc19iYWQoKSkgeworICAgICAgU2V0KFBfTElGRVRJTUUsdmFsLShmaXJzdF9yZXNldF9sZW5ndGgpLEZfVkFMVUUpOworICAgICAgLy8gQW56YWhsIGRlciBSZXNldHMgcmljaHRldCBzaWNoIG5hY2ggZGVtIE1pdHRlbHdlcnQKKyAgICAgIFNldChQX1JFU0VUX0xJRkVUSU1FLHRvX2ludCgodmFsLShmaXJzdF9yZXNldF9sZW5ndGgpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgLyhfX1JFU0VUX1RJTUVfXyowLjc1KSkrMSxGX1ZBTFVFKTsKKyAgICAgIHNldF9uZXh0X3Jlc2V0KHZhbCk7CisgICAgfQorICB9CisgIGVsc2UgeworICAgIHdyaXRlKCJEYSBpc3Qgd2FzIHNjaGllZiBnZWxhdWZlbiEgU3ByaWNoIG1hbCBtaXQgZWluZW0gTWFnaWVyLlxuIik7CisgICAgcmFpc2VfZXJyb3IoInNldHRpbmcgUF9MSUZFVElNRSB0byBpbnZhbGlkIGludCB2YWx1ZTogIisKKyAgICAgIHRvX3N0cmluZyh2YWwpKyJcbiIpOworICB9Cit9CisKKy8vIEFuemFobCBkZXIgUmVzZXRzIGFscyBMZWJlbnN6ZWl0Cit2b2lkIF9zZXRfc3RkX2Zvb2RfbGlmZXRpbWVfcmVzZXQoaW50IHZhbHVlKSB7CisgIGlmICh2YWx1ZSA8IDEpIHZhbHVlID0gMTsKKworICBTZXQoUF9SRVNFVF9MSUZFVElNRSx2YWx1ZSxGX1ZBTFVFKTsKKyAgLy8gcGVyIFp1ZmFsbCBkaWUgTGFlbmdlIGRlciBlaW56ZWxuZW4gUmVzZXRzIGJlcmVjaG5lbgorICBpbnQgbGVuZ3RoID0gZmlyc3RfcmVzZXRfbGVuZ3RoOworICBmb3JlYWNoKGludCBpOiB2YWx1ZSkgeworICAgIGxlbmd0aCArPSB0b19pbnQoKF9fUkVTRVRfVElNRV9fICsgcmFuZG9tKF9fUkVTRVRfVElNRV9fKSkgLyAyKTsKKyAgfQorICBzZXRfc3RkX2Zvb2RfbGlmZXRpbWUobGVuZ3RoKTsKK30KKworLy8gRmxhZywgb2IgU3BlaXNlICJlc3NiYXIiIGlzdAorcHVibGljIGludCBpc19lYXRhYmxlKCkgeworICByZXR1cm4gUXVlcnlQcm9wKFBfRk9PRCkgPiAwOworfQorCisvLyBGbGFnLCBvYiBTcGVpc2UgInRyaW5rYmFyIiBpc3QKK3B1YmxpYyBpbnQgaXNfZHJpbmthYmxlKCkgeworICByZXR1cm4gUXVlcnlQcm9wKFBfRk9PRCkgPT0gMCAmJiBRdWVyeVByb3AoUF9EUklOSykgPiAwOworfQorCisvLyBGbGFnLCBvYiBub2NoIFBvcnRpb25lbiBkZXIgU3BlaXNlIHZvcmhhbmRlbiBzaW5kCitwdWJsaWMgaW50IGlzX25vdF9lbXB0eSgpIHsKKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX1BPUlRJT05TKSA+IDA7Cit9CisKKy8vIE1hY2h0IGVpbmUgU3BlaXNlIGxlZXIgYnp3LiB6ZXJzdG9lcnQgc2llLgorLy8gTXVzcyBiZWltIFVlYmVyc2NocmVpYmVuIGltbWVyIGFscyBsZXR6dGVzIGF1ZmdlcnVmZW4gd2VyZGVuLgorLy8gRGllc2UgTWV0aG9kZSB3aXJkIGF1ZmdlcnVmZW4sIHdlbm4gZWluIEJlaGFlbHRlciBsZWVyZ2VmdXR0ZXJ0IHdpcmQKKy8vIG9kZXIgZGVyIEluaGFsdCB6ZXJzdG9lcnQgd2VyZGVuIHNvbGwKKy8vIFJ1ZWNrZ2FiZXdlcnQ6IEVyZ2VibmlzIHZvbiByZW1vdmUoKSBiencuIDAsIHdlbm4gT2JqZWt0IG5pY2h0CisvLyAgICAgICAgICAgICAgICB6ZXJzdG9lcnQgd2VyZGVuIG11c3MKKy8vIEJlaW0gQXVmcnVmIGJpdHRlIElNTUVSIGRhcyBFcmdlYm5pcyBwcnVlZmVuLCBkYW1pdCBrZWluZSBBdWZydWZlIGFuCisvLyBnZWxvZXNjaHRlbiBPYmpla3RlbiBwYXNzaWVyZW4hIGlmIChtYWtlX2VtcHR5KCkpIHJldHVybiAuLi47CitwdWJsaWMgaW50IG1ha2VfZW1wdHkoKSB7CisgIG1peGVkIHByb3BzID0gUXVlcnlQcm9wKFBfRU1QVFlfUFJPUFMpOworICBpZiAobWFwcGluZ3AocHJvcHMpKSB7CisgICAgZm9yZWFjaChzdHJpbmcga2V5Om1faW5kaWNlcyhwcm9wcykpIHsKKyAgICAgIGlmIChrZXkgPT0gUF9JRFMpIHsKKyAgICAgICAgUmVtb3ZlSWQoUXVlcnlQcm9wKFBfSURTKSk7CisgICAgICAgIEFkZElkKFF1ZXJ5UHJvcChJRF9CQUNLVVApKTsKKyAgICAgICAgQWRkSWQocHJvcHNba2V5XSk7CisgICAgICB9CisgICAgICBlbHNlIGlmIChrZXkgPT0gUF9BREpFQ1RJVkVTKSB7CisgICAgICAgIFJlbW92ZUlkKFF1ZXJ5UHJvcChQX0FESkVDVElWRVMpKTsKKyAgICAgICAgQWRkQWRqZWN0aXZlKFF1ZXJ5UHJvcChBREpfQkFDS1VQKSk7CisgICAgICAgIEFkZEFkamVjdGl2ZShwcm9wc1trZXldKTsKKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICBTZXRQcm9wKGtleSxwcm9wc1trZXldKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBTaWNoZXJoZWl0c2hhbGJlciA6LSkKKyAgICBTZXRQcm9wKFBfUE9SVElPTlMsMCk7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgZWxzZSB7CisgICAgcmV0dXJuIHJlbW92ZSgxKTsKKyAgfQorfQorCisvLyB3aXJkIGF1ZmdlcnVmZW4sIHdlbm4gZGllIFNwZWlzZSBzY2hsZWNodCB3YXIgdW5kIGRlciBSZW1vdmV0aW1lcgorLy8gYWJnZWxhdWZlbiBpc3QKKy8vIFplcnN0b2VydCBkaWUgU3BlaXNlIG9kZXIgZGVuIEluaGFsdCBlaW5lcyBCZWhhZWx0ZXJzCisvLyBSdWVja2dhYmV3ZXJ0OiBFcmdlYm5pcyB2b24gcmVtb3ZlKCkgYnp3LiAwLCB3ZW5uIE9iamVrdCBuaWNodAorLy8gICAgICAgICAgICAgICAgemVyc3RvZXJ0IHdlcmRlbiBtdXNzCitwdWJsaWMgaW50IG1ha2VfZGVzdHJveSgpIHsKKyAgbWVzc2FnZShQX1JFTU9WRV9NU0cpOworICBzZXRfbmV4dF9yZXNldCgtMSk7CisgIHJldHVybiBtYWtlX2VtcHR5KCk7IC8vIExlZXJtYWNoZW4gb2RlciB6ZXJzdG9lcmVuCit9CisKKy8vIExhZXNzdCBkaWUgU3BlaXNlIHNjaGxlY2h0IHdlcmRlbiAobWl0IE1lbGR1bmdlbikKKy8vIG11c3MgYmVpbSBVZWJlcnNjaHJlaWJlbiBpbW1lciBtaXQgYXVmZ2VydWZlbiB3ZXJkZW4KKy8vIFJ1ZWNrZ2FiZXdlcnQ6IEVyZ2VibmlzIHZvbiByZW1vdmUoKSBiencuIDAsIHdlbm4gT2JqZWt0IG5pY2h0CisvLyAgICAgICAgICAgICAgICB6ZXJzdG9lcnQgd2VyZGVuIG11c3MKKy8vIEJlaW0gQXVmcnVmIGJpdHRlIElNTUVSIGRhcyBFcmdlYm5pcyBwcnVlZmVuLCBkYW1pdCBrZWluZSBBdWZydWZlIGFuCisvLyBnZWxvZXNjaHRlbiBPYmpla3RlbiBwYXNzaWVyZW4hIGlmIChtYWtlX2JhZCgpKSByZXR1cm4gLi4uOworcHVibGljIGludCBtYWtlX2JhZCgpIHsKKyAgdGltZV9nb25lX2JhZCA9IHRpbWUoKTsKKyAgaWYgKGlzX25vdF9lbXB0eSgpKSB7CisgICAgbWVzc2FnZShQX0JBRF9NU0cpOworICB9CisgIGlmIChRdWVyeVByb3AoUF9ERVNUUk9ZX0JBRCkgPT0gREVTVFJPWV9CQUQgJiYgIVF1ZXJ5UHJvcChQX0VNUFRZX1BST1BTKSkgeworICAgIHJldHVybiByZW1vdmUoMSk7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKy8vIFN0YXJ0ZXQgZGVuIFRpbWVyIHp1bSBTY2hsZWNodHdlcmRlbiBkZXIgU3BlaXNlCitwdWJsaWMgdm9pZCBzdGFydF9saWZldGltZSgpIHsKKyAgLy8gVGVzdCwgb2IgTGViZW5zbWl0dGVsIHNjaGxlY2h0IHdlcmRlbiBkYXJmCisgIGlmICghUXVlcnlQcm9wKFBfTk9fQkFEKSAmJiAhdGltZV90b2dvX2JhZCkgeworICAgIHN0YXJ0X2xpZmUgPSB0aW1lKCk7CisgICAgaW50IHplaXQgPSBRdWVyeVByb3AoUF9MSUZFVElNRSk7CisgICAgIC8vIFplaXRwdW5rdCBkZXMgU2NobGVjaHR3ZXJkZW5zCisgICAgdGltZV90b2dvX2JhZCA9IHN0YXJ0X2xpZmUgKyB6ZWl0OworICAgIC8vIFplaXRwdW5rdCBkZXMgWmVyc3RvZXJlbnMKKyAgICB0aW1lX3RvX3JlbW92ZSA9IHRpbWVfdG9nb19iYWQgKyBRdWVyeVByb3AoUF9ERVNUUk9ZX0JBRCk7CisgICAgbXlfc2V0X25leHRfcmVzZXQoemVpdCk7CisgIH0KK30KKworLy8gUmVzZXQgd2lyZCBpbiAyIFNpdHVhdGlvbmVuIGF1ZmdlcnVmZW46CisvLyAxLiBUaW1lciB6dW0gc2NobGVjaHQgd2VyZGVuIGlzdCBhYmdlbGF1ZmVuLCBkYXMgRnV0dGVyIG11c3MgYWxzbworLy8gICAgc2NobGVjaHQgd2VyZGVuIHVuZCBldnRsLiBkZXIgVGltZXIgenVtIFplcnN0b2VyZW4gZ2VzdGFydGV0IHdlcmRlbgorLy8gMi4gVGltZXIgenVtIFplcnN0b2VyZW4gaXN0IGFiZ2VsYXVmZW4sIGFsc28gd2lyZCBGdXR0ZXIgemVyc3RvZXJ0LgorLy8gV2lyZCBkZXIgUmVzZXQgYXVzIGlyZ2VuZGVpbmVtIEdydW5kIHp1IGZhbHNjaGVuIFplaXRlbiBhdWZnZXJ1ZmVuLAorLy8gd2lyZCBkZXIgbmFlY2hzdGUgUmVzZXQga29ycmVrdCBpbml0aWFsaXNpZXJ0Lgordm9pZCByZXNldCgpIHsKKyAgLy8gd2VubiBrZWluIGVudiwgQWJicnVjaCB1bmQgcmVzZXQgYWJzY2hhbHRlbi4KKyAgaWYgKCFlbnZpcm9ubWVudCgpKSB7CisgICAgICBzZXRfbmV4dF9yZXNldCgtMSk7CisgICAgICByZXR1cm47CisgIH0KKworICAvLyBUZXN0LCBvYiBMZWJlbnNtaXR0ZWwgc2NobGVjaHQgd2VyZGVuIGRhcmYKKyAgaWYgKCFRdWVyeVByb3AoUF9OT19CQUQpKSB7CisgICAgaWYgKCFpc19iYWQoKSkgeworICAgICAgLy8gVGVzdCwgb2IgVGltZXIgbGFldWZ0CisgICAgICBpZiAodGltZV90b2dvX2JhZCkgeworICAgICAgICAvLyBQcnVlZmVuLCBvYiBkZXIgUmVzZXQgc28gaW4gZXR3YSB6dXIgcmljaHRpZ2VuIFplaXQgYXVmZ2VydWZlbiB3dXJkZQorICAgICAgICAvLyAxMCUgQWJ3ZWljaHVuZyBzaW5kIGVybGF1YnQKKyAgICAgICAgaW50IGRpZmYgPSB0aW1lKCkgLSB0aW1lX3RvZ29fYmFkOworICAgICAgICBpbnQgc3RkID0gdG9faW50KFF1ZXJ5UHJvcChQX0xJRkVUSU1FKS8xMCk7CisgICAgICAgIGlmIChhYnMoZGlmZikgPCBzdGQgfHwgZGlmZiA+IDApIHsKKyAgICAgICAgICBpZiAobWFrZV9iYWQoKSkgcmV0dXJuOworICAgICAgICAgIC8vIFJlc2V0IHp1bSBaZXJzdG9lcmVuIHZvcmJlcmVpdGVuCisgICAgICAgICAgaWYgKFF1ZXJ5UHJvcChQX0RFU1RST1lfQkFEKSA+IDApIHsKKyAgICAgICAgICAgIG15X3NldF9uZXh0X3Jlc2V0KHRpbWVfdG9fcmVtb3ZlIC0gdGltZSgpKTsKKyAgICAgICAgICB9CisgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBzZXRfbmV4dF9yZXNldCgtMSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgIC8vIFJlc2V0IG5vY2htYWwgenVtIEFibGF1ZiBkZXIgRnJpc3QKKyAgICAgICAgICBteV9zZXRfbmV4dF9yZXNldChhYnMoZGlmZikpOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIGVsc2UgaWYgKHRpbWVfdG9fcmVtb3ZlICYmIFF1ZXJ5UHJvcChQX0RFU1RST1lfQkFEKSA+IDApIHsKKyAgICAgIC8vIHdpciBzaW5kIGltIFJlc2V0IG5hY2ggZGVtIFNjaGxlY2h0d2VyZGVuCisgICAgICBpbnQgZGlmZiA9IHRpbWUoKSAtIHRpbWVfdG9fcmVtb3ZlOworICAgICAgaW50IHN0ZCA9IHRvX2ludCgoUXVlcnlQcm9wKFBfTElGRVRJTUUpK1F1ZXJ5UHJvcChQX0RFU1RST1lfQkFEKSkvMTApOworICAgICAgLy8gUHJ1ZWZlbiwgb2IgZGVyIFJlc2V0IHNvIGluIGV0d2EgenVyIHJpY2h0aWdlbiBaZWl0IGF1ZmdlcnVmZW4gd3VyZGUKKyAgICAgIC8vIDEwJSBBYndlaWNodW5nIHNpbmQgZXJsYXVidAorICAgICAgaWYgKGFicyhkaWZmKSA8IHN0ZCB8fCBkaWZmID4gMCkgeworICAgICAgICBpZiAobWFrZV9kZXN0cm95KCkpIHJldHVybjsgLy8gTGVlcm1hY2hlbiBvZGVyIHplcnN0b2VyZW4KKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICAvLyBSZXNldCBub2NobWFsIHp1bSBBYmxhdWYgZGVyIEZyaXN0CisgICAgICAgIG15X3NldF9uZXh0X3Jlc2V0KGFicyhkaWZmKSk7CisgICAgICB9CisgICAgfQorICB9IC8vIGlmIChQX05PX0JBRCkKKworICA6OnJlc2V0KCk7Cit9CisKK3ByaXZhdGUgaW50IHNhZmV0eV9jaGVjaygpIHsKKyAgLy8gRGFtaXQgZWluIFNwaWVsZXIgYXVjaCBnYWFhYW56IHNpY2hlciBuaWNodCBTcGVpc2VuIGF1c3NlcmhhbGIgZGVyIAorICAvLyBQX0xJRkVUSU1FIG51dHplbiBrYW5uIC4uLgorICBpZiAodGltZV90b2dvX2JhZCAmJiAhaXNfYmFkKCkgJiYgdGltZSgpID4gdGltZV90b2dvX2JhZCkgeworICAgIGlmIChtYWtlX2JhZCgpKSByZXR1cm4gMDsKKyAgICAvLyBSZXNldCB6dW0gWmVyc3RvZXJlbiB2b3JiZXJlaXRlbgorICAgIGlmIChRdWVyeVByb3AoUF9ERVNUUk9ZX0JBRCkgPiAwKSB7CisgICAgICBteV9zZXRfbmV4dF9yZXNldCh0aW1lX3RvX3JlbW92ZSAtIHRpbWUoKSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgc2V0X25leHRfcmVzZXQoLTEpOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorICBlbHNlIGlmICh0aW1lX3RvX3JlbW92ZSAmJiB0aW1lKCkgPiB0aW1lX3RvX3JlbW92ZQorICAgICAgJiYgUXVlcnlQcm9wKFBfREVTVFJPWV9CQUQpID4gMCkgeworICAgIG1ha2VfZGVzdHJveSgpOyAvLyBMZWVybWFjaGVuIG9kZXIgemVyc3RvZXJlbgorICAgIHJldHVybiAwOworICB9CisgIHJldHVybiAxOworfQorCisvLyBQcnVlZnVuZyB6dW0gU3RhcnRlbiBhdXNnZWxhZ2VydCwgZGEgZGFzIGltIGluaXQgdW5kIGluCisvLyBOb3RpZnlNb3ZlIGdlYnJhdWNodCB3aXJkCitwcml2YXRlIHZvaWQgY2hlY2tfc3RhcnRfdGltZXIob2JqZWN0IG9sZGVudikgeworICAvLyBUZXN0LCBvYiBMZWJlbnNtaXR0ZWwgc2NobGVjaHQgd2VyZGVuIGthbm4KKyAgaWYgKCFRdWVyeVByb3AoUF9OT19CQUQpICYmICF0aW1lX3RvZ29fYmFkKSB7CisgICAgLy8gV2VubiB3aXIgaXJnZW5kd2llIGluIGVpbmVtIFNwaWVsZXIgc3RlY2tlbiBvZGVyIGVpbiBTcGllbGVyIGluIGRlcgorICAgIC8vIFVtZ2VidW5nIGlzdCBvZGVyIGRhcyBGdXR0ZXIgbWVocmZhY2ggYmV3ZWd0IHd1cmRlCisgICAgaWYgKHNpemVvZihmaWx0ZXIoYWxsX2Vudmlyb25tZW50KCksIydxdWVyeV9vbmNlX2ludGVyYWN0aXZlKSkKKyAgICAgICAgfHwgc2l6ZW9mKGZpbHRlcihhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpLCMncXVlcnlfb25jZV9pbnRlcmFjdGl2ZSkpCisgICAgICAgIHx8IG9iamVjdHAob2xkZW52KSkgeworICAgICAgc3RhcnRfbGlmZXRpbWUoKTsKKyAgICB9CisgIH0KKyAgZWxzZSB7CisgICAgLy8gRGFtaXQgZWluIFNwaWVsZXIgYXVjaCBnYWFhYW56IHNpY2hlciBuaWNodCBTcGVpc2VuIGF1c3NlcmhhbGIKKyAgICAvLyBkZXIgUF9MSUZFVElNRSBudXR6ZW4ga2FubiAuLi4KKyAgICBzYWZldHlfY2hlY2soKTsKKyAgfQorfQorCisvLyBoaWVyIHdpcmQgZ2VwcnVlZnQsIG9iIGRhcyBGdXR0ZXIgZGVtIFNwaWVsZXIgenVnYWVuZ2xpY2ggaXN0Lgordm9pZCBpbml0KCkgeworICA6OmluaXQoKTsKKyAgY2hlY2tfc3RhcnRfdGltZXIoZW52aXJvbm1lbnQoKSk7Cit9CisKKy8vIGhpZXIgd2lyZCBnZXBydWVmdCwgb2IgZGFzIEZ1dHRlciBkZW0gU3BpZWxlciB6dWdhZW5nbGljaCBpc3QuCisvLyBkYXMgaXN0IHNpY2hlcmVyIGFscyBudXIgaW0gaW5pdCgpCitwcm90ZWN0ZWQgdm9pZCBOb3RpZnlNb3ZlKG9iamVjdCBkZXN0LCBvYmplY3Qgb2xkZW52LCBpbnQgbWV0aG9kKSB7CisgIDo6Tm90aWZ5TW92ZShkZXN0LCBvbGRlbnYsIG1ldGhvZCk7CisgIGNoZWNrX3N0YXJ0X3RpbWVyKG9sZGVudik7Cit9CisKK3ZvaWQgY3JlYXRlKCkgeworICAvLyBTaWNoZXJoZWl0c2hhbGJlciwKKyAgLy8gZmFsbHMgamVtYW5kIGRpZSBCbHVlcHJpbnQgbWl0IFByb3BzIGluaXRpYWxpc2llcmVuIHdpbGwKKyAgOjpjcmVhdGUoKTsKKyAgU2V0KFBfTElGRVRJTUUsICMnc2V0X3N0ZF9mb29kX2xpZmV0aW1lLCBGX1NFVF9NRVRIT0QpOworICBTZXQoUF9MSUZFVElNRSwgUFJPVEVDVEVELCBGX01PREVfQVMpOworCisgIHRpbWVfdG9nb19iYWQgPSAwOworICB0aW1lX3RvX3JlbW92ZSA9IDA7CisgIHRpbWVfZ29uZV9iYWQgPSAwOworCisgIC8vIFN0YW5kYXJkbGF1ZnplaXQgMSBSZXNldAorICBmaXJzdF9yZXNldF9sZW5ndGggPSB0b19pbnQoKF9fUkVTRVRfVElNRV9fICsgcmFuZG9tKF9fUkVTRVRfVElNRV9fKSkgLyAyKTsKKyAgLy8gUmVzZXQgd2lyZCBlcnN0bWFsIGFiZ2VzY2hhbHRldCwgZGFzIHdpcmQgaW0gTm90aWZ5TW92ZSBnZXBydWVmdAorICBzZXRfbmV4dF9yZXNldCgtMSk7CisKKyAgU2V0UHJvcChQX1NIT1JULCJFaW4gTGViZW5zbWl0dGVsIik7CisgIFNldFByb3AoUF9MT05HLCJEYXMgaXN0IGVpbiBMZWJlbnNtaXR0ZWwuXG4iKTsKKyAgU2V0UHJvcChQX05BTUUsIkxlYmVuc21pdHRlbCIpOworICBTZXRQcm9wKFBfTUFURVJJQUwsIE1BVF9NSVNDX0ZPT0QpOworICBTZXRQcm9wKFBfR0VOREVSLE5FVVRFUik7CisgIFNldFByb3AoUF9XRUlHSFQsNTApOworICBTZXRQcm9wKFBfVkFMVUUsMTApOworICBTZXRQcm9wKFBfUE9SVElPTlMsMSk7IC8vIGVpbm1hbCBBYmJlaXNzZW4KKyAgU2V0UHJvcChQX0RFU1RST1lfQkFELERFU1RST1lfQkFEKTsgLy8gWmVyc3RvZXJlbiBiZWltIFNjaGxlY2h0d2VyZGVuCisgIFNldFByb3AoUF9ESVNUUklCVVRJT04sSERfU1RBTkRBUkQpOyAvLyBIZWlsdW5nIHBlciBTdGFuZGFyZHZlcnRlaWx1bmcgKDUvaGIpCisKKyAgU2V0UHJvcChQX0NPTlNVTUVfTVNHLCJAV0VSMiBrb25zdW1pZXJ0IEBXRU4xLiIpOworICBTZXRQcm9wKFBfRUFURVJfTVNHLCJEdSBrb25zdW1pZXJzdCBAV0VOMS4iKTsKKyAgU2V0UHJvcChQX0VNUFRZX01TRywiQFdFUjEgaXN0IGJlcmVpdHMgbGVlci4iKTsKKyAgU2V0UHJvcChQX05PRk9PRF9NU0csIkBXRU4xIGthbm4gbWFuIG5pY2h0IGVzc2VuISIpOworICBTZXRQcm9wKFBfTk9EUklOS19NU0csIkBXRU4xIGthbm4gbWFuIG5pY2h0IHRyaW5rZW4hIik7CisgIFNldFByb3AoUF9CQURfTVNHLCJAV0VSMSB2ZXJkaXJidC4iKTsKKyAgU2V0UHJvcChQX0ZPT0RfRlVMTF9NU0csIkR1IGJpc3QgenUgc2F0dCwgZGFzIHNjaGFmZnN0IER1IG5pY2h0IG1laHIuIik7CisgIFNldFByb3AoUF9EUklOS19GVUxMX01TRywiU28gdmllbCBrYW5uc3QgRHUgaW0gTW9tZW50IG5pY2h0IHRyaW5rZW4uIik7CisgIFNldFByb3AoUF9BTENfRlVMTF9NU0csIlNvdmllbCBBbGtvaG9sIHZlcnRyYWVnc3QgRHUgbmljaHQgbWVoci4iKTsKKyAgU2V0UHJvcChQX0VOVl9NU0csIlZpZWxsZWljaHQgc29sbHRlc3QgRHUgQFdFTjEgdm9yaGVyIG5laG1lbi4iKTsKKyAgU2V0UHJvcChQX1JFTU9WRV9NU0csIkBXRVIxIHplcmZhZWxsdCB6dSBTdGF1Yi4iKTsKKworICAvLyBTaWNoZXJuIGRlciBTdGFuZGFyZHMKKyAgU2V0UHJvcChJRF9CQUNLVVAsUXVlcnlQcm9wKFBfSURTKSk7CisgIFNldFByb3AoQURKX0JBQ0tVUCxRdWVyeVByb3AoUF9BREpFQ1RJVkVTKSk7CisKKyAgQWRkSWQoKHsibGViZW5zbWl0dGVsIiwibmFocnVuZyIsIlxuZm9vZCJ9KSk7CisKKyAgQWRkQ21kKCh7ImlzcyIsImVzc2UifSksImNtZF9lYXQiKTsKKyAgQWRkQ21kKCh7InRyaW5rIiwidHJpbmtlIn0pLCJjbWRfZHJpbmsiKTsKK30KKworLy8gQWVuZGVydCBXZXJ0ZSBkZXIgU3BlaXNlLCB3ZW5uIHNpZSB2ZXJnYW1tZWx0IGlzdCB1bmQga29uc3VtaWVydCB3aXJkCitwcm90ZWN0ZWQgdm9pZCBjb25zdW1lX2JhZChtYXBwaW5nIGVudHJ5X2luZm8pIHsKKyAgZW50cnlfaW5mb1tQX0hQXSA9IDA7CisgIGVudHJ5X2luZm9bUF9TUF0gPSAwOworICBlbnRyeV9pbmZvW0hfRUZGRUNUU10gPSAoW1BfUE9JU09OOjFdKTsKK30KKworLy8gU3RlbGx0IE1hcHBpbmcgenVtIEtvbnN1bWllcmVuIHp1c2FtbWVuIHVuZCBrb25zdW1pZXJ0LgorLy8ga2FubiBtaXQgdGVzdG9ubHk9MSBhdWZnZXJ1ZmVuIHdlcmRlbiwgdW0genUgcHJ1ZWZlbiwgb2Iga29uc3VtaWVyZW4ga2xhcHB0CisvLyBHaWJ0IGRhcyBFcmdlYm5pcyB2b24gbGl2aW5nLT5jb25zdW1lKCkgenVydWVjazoKKy8vID4wIC0+IGVyZm9sZ3JlaWNoIGtvbnN1bWllcnQKKy8vIDwwIC0+IG5pY2h0IGtvbnN1bWllcnQgKHNpZWhlIEhpbGZlIHp1IGNvbnN1bWUpCitwcm90ZWN0ZWQgdmFyYXJncyBpbnQgdHJ5X2NvbnN1bWUob2JqZWN0IGNvbnN1bWVyLCBpbnQgdGVzdG9ubHkpIHsKKyAgbWFwcGluZyBlbnRyeV9pbmZvID0gKFtQX0ZPT0Q6UXVlcnlQcm9wKFBfRk9PRCksCisgICAgICAgICAgICAgICAgICAgICAgICBQX0RSSU5LOlF1ZXJ5UHJvcChQX0RSSU5LKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFBfSFA6UXVlcnlQcm9wKFBfSFApLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgUF9TUDpRdWVyeVByb3AoUF9TUCksCisgICAgICAgICAgICAgICAgICAgICAgIFBfUE9JU09OOlF1ZXJ5UHJvcChQX1BPSVNPTiksCisgICAgICAgICAgICAgICAgICAgICAgUF9BTENPSE9MOlF1ZXJ5UHJvcChQX0FMQ09IT0wpLAorICAgICAgICAgICAgICAgICBIX0RJU1RSSUJVVElPTjpRdWVyeVByb3AoUF9ESVNUUklCVVRJT04pXSk7CisKKyAgaWYgKGlzX2JhZCgpKSBjb25zdW1lX2JhZChlbnRyeV9pbmZvKTsKKworICBpbnQgcmVzdWx0ID0gKGludCljb25zdW1lci0+Y29uc3VtZShlbnRyeV9pbmZvLCB0ZXN0b25seSk7CisgIGlmICghcmVzdWx0KSB7CisgICAgdGVsbF9vYmplY3QoY29uc3VtZXIsCisgICAgICAiRGEgaXN0IHdhcyBzY2hpZWYgZ2VsYXVmZW4hIFNwcmljaCBtYWwgbWl0IGVpbmVtIE1hZ2llci5cbiIpOworICAgIHJhaXNlX2Vycm9yKCJsaXZpbmctPmNvbnN1bWUoKSBtaXQgZmFsc2NoZW4gUGFyYW1ldGVybiBhdWZnZXJ1ZmVuOlxuIisKKyAgICAgIHNwcmludGYoIiVPXG4iLGVudHJ5X2luZm8pKTsKKyAgfQorCisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIEtvbnN1bWllcmVuIHdhciBlcmZvbGdyZWljaAorLy8gSGllciBrYW5uIG1hbiBiZWltIFVlYmVyc2NocmVpYmVuIG5vY2ggenVzYWV0emxpY2hlIFNhY2hlbiBtYWNoZW4KKy8vIFBfUE9SVElPTlMgaXN0IGJlcmVpdHMgcnVudGVyZ2V6YWVobHQsIFNwZWlzZSBpc3QgYWJlciBub2NoIG5pY2h0IGxlZXIhCisvLyBtYWtlX2VtcHR5KCkgd2lyZCBhbHNvIGV2ZW50dWVsbCBub2NoIGRhbmFjaCBhdWZnZXJ1ZmVuCisvLyBlbnRzcHJpY2h0IGFsdGVyIEZ1bmMgQmVpbUVzc2VuKCkKK3Byb3RlY3RlZCB2b2lkIHN1Y2Nlc3NfY29uc3VtZShvYmplY3QgY29uc3VtZXIpIHsKKyAgdGVsbF9yb29tKGVudmlyb25tZW50KGNvbnN1bWVyKSxldmFsX3Byb3BlcnR5KFBfQ09OU1VNRV9NU0csY29uc3VtZXIpLCh7Y29uc3VtZXJ9KSk7CisgIHRlbGxfb2JqZWN0KGNvbnN1bWVyLGV2YWxfcHJvcGVydHkoUF9FQVRFUl9NU0csY29uc3VtZXIpKTsKK30KKworLy8gS29uc3VtaWVyZW4gd2FyIG5pY2h0IGVyZm9sZ3JlaWNoCisvLyBIaWVyIGthbm4gbWFuIGJlaW0gVWViZXJzY2hyZWliZW4gbm9jaCB6dXNhZXR6bGljaGUgU2FjaGVuIG1hY2hlbgorLy8gaW4gcmVhc29uIHdpcmQgZGVyIEdydW5kIGRlcyBGZWhsc2NobGFnZW5zIHVlYmVyZ2ViZW4gKHNpZWhlICdtYW4gY29uc3VtZScpCitwcm90ZWN0ZWQgdm9pZCBmYWlsZWRfY29uc3VtZShvYmplY3QgY29uc3VtZXIsIGludCByZWFzb24pIHsKKyAgaWYgKHJlYXNvbiAmIEhDX01BWF9GT09EX1JFQUNIRUQpCisgICAgdGVsbF9vYmplY3QoY29uc3VtZXIsZXZhbF9wcm9wZXJ0eShQX0ZPT0RfRlVMTF9NU0csY29uc3VtZXIpKTsKKyAgZWxzZSBpZiAocmVhc29uICYgSENfTUFYX0RSSU5LX1JFQUNIRUQpCisgICAgdGVsbF9vYmplY3QoY29uc3VtZXIsZXZhbF9wcm9wZXJ0eShQX0RSSU5LX0ZVTExfTVNHLGNvbnN1bWVyKSk7CisgIGVsc2UgaWYgKHJlYXNvbiAmIEhDX01BWF9BTENPSE9MX1JFQUNIRUQpCisgICAgdGVsbF9vYmplY3QoY29uc3VtZXIsZXZhbF9wcm9wZXJ0eShQX0FMQ19GVUxMX01TRyxjb25zdW1lcikpOworfQorCisvLyBLb25zdW1pZXJ0IGRpZSBTcGVpc2UKKy8vIEdpYnQgZGFzIEVyZ2VibmlzIHZvbiBsaXZpbmctPmNvbnN1bWUoKSB6dXJ1ZWNrOgorLy8gPjAgLT4gZXJmb2xncmVpY2gga29uc3VtaWVydAorLy8gPDAgLT4gbmljaHQga29uc3VtaWVydCAoc2llaGUgSGlsZmUgenUgY29uc3VtZSkKK3Byb3RlY3RlZCBpbnQgY29uc3VtZShvYmplY3QgY29uc3VtZXIpIHsKKyAgaWYgKCFvYmplY3RwKGNvbnN1bWVyKSB8fCAhbGl2aW5nKGNvbnN1bWVyKSkgeworICAgIHJhaXNlX2Vycm9yKCJhcmd1bWVudCBwbCBub3QgYSBsaXZpbmc6XG4iKworICAgICAgc3ByaW50ZigiJU9cbiIsY29uc3VtZXIpKTsKKyAgfQorICAvLyBkYW1pdCBhYmdlbGF1ZmVuZSBTcGVpc2VuIGF1Y2ggd2lya2xpY2ggYWJnZWxhdWZlbiBzaW5kCisgIGlmICghc2FmZXR5X2NoZWNrKCkpIHJldHVybiAwOworCisgIGlmICghaXNfbm90X2VtcHR5KCkpIHsKKyAgICBub3RpZnlfZmFpbChldmFsX3Byb3BlcnR5KFBfRU1QVFlfTVNHLGNvbnN1bWVyKSk7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaW50IHJlc3VsdCA9IHRyeV9jb25zdW1lKGNvbnN1bWVyKTsKKyAgaWYgKHJlc3VsdCA+IDApIHsKKyAgICBTZXRQcm9wKFBfUE9SVElPTlMsUXVlcnlQcm9wKFBfUE9SVElPTlMpLTEpOworICAgIHN1Y2Nlc3NfY29uc3VtZShjb25zdW1lcik7CisgICAgaWYgKCFpc19ub3RfZW1wdHkoKSkgbWFrZV9lbXB0eSgpOworICB9CisgIGVsc2UgaWYgKHJlc3VsdCA8IDApIHsKKyAgICBmYWlsZWRfY29uc3VtZShjb25zdW1lcixyZXN1bHQpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKKy8vIEZ1dHRlcm4KK2ludCBjbWRfZWF0KHN0cmluZyBzdHIpIHsKKyAgbm90aWZ5X2ZhaWwoIldBUyBtb2VjaHRlc3QgRHUgZXNzZW4/XG4iKTsKKyAgaWYgKCFzdHIgfHwgIWlkKHN0cikpIHJldHVybiAwOworICBvYmplY3QgZW52ID0gZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSk7CisgIGlmIChlbnYgIT0gdGhpc19wbGF5ZXIoKSAmJiBRdWVyeVByb3AoUF9FTlZfTVNHKSkgeworICAgIG5vdGlmeV9mYWlsKGV2YWxfcHJvcGVydHkoUF9FTlZfTVNHLGVudikpOworICAgIHJldHVybiAwOworICB9CisKKyAgaWYgKCFpc19lYXRhYmxlKCkgJiYgIWlzX2RyaW5rYWJsZSgpKSB7CisgICAgd3JpdGUoIk1pdCBkaWVzZW0gRnV0dGVyIHN0aW1tdCB3YXMgbmljaHQhIgorICAgICAgIiBTcHJpY2ggbWFsIG1pdCBlaW5lbSBNYWdpZXIuXG4iKTsKKyAgICByYWlzZV9lcnJvcigiRm9vZCBvaG5lIFdlcnRlLlxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKworICBpZiAoIWlzX2VhdGFibGUoKSkgeworICAgIG5vdGlmeV9mYWlsKGV2YWxfcHJvcGVydHkoUF9OT0ZPT0RfTVNHLGVudikpOworICAgIHJldHVybiAwOworICB9CisKKyAgcmV0dXJuIGNvbnN1bWUodGhpc19wbGF5ZXIoKSk7Cit9CisKKy8vIFRyaW5rZW4KK2ludCBjbWRfZHJpbmsoc3RyaW5nIHN0cikgeworICBub3RpZnlfZmFpbCgiV0FTIG1vZWNodGVzdCBEdSB0cmlua2VuP1xuIik7CisgIGlmICghc3RyIHx8ICFpZChzdHIpKSByZXR1cm4gMDsKKyAgb2JqZWN0IGVudiA9IGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpOworICBpZiAoZW52ICE9IHRoaXNfcGxheWVyKCkgJiYgUXVlcnlQcm9wKFBfRU5WX01TRykpIHsKKyAgICBub3RpZnlfZmFpbChldmFsX3Byb3BlcnR5KFBfRU5WX01TRyxlbnYpKTsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIGlmICghaXNfZWF0YWJsZSgpICYmICFpc19kcmlua2FibGUoKSkgeworICAgIHdyaXRlKCJNaXQgZGllc2VtIEZ1dHRlciBzdGltbXQgd2FzIG5pY2h0ISIKKyAgICAgICIgU3ByaWNoIG1hbCBtaXQgZWluZW0gTWFnaWVyLlxuIik7CisgICAgcmFpc2VfZXJyb3IoIkZvb2Qgb2huZSBXZXJ0ZS5cbiIpOworICAgIHJldHVybiAwOworICB9CisKKyAgaWYgKCFpc19kcmlua2FibGUoKSkgeworICAgIG5vdGlmeV9mYWlsKGV2YWxfcHJvcGVydHkoUF9OT0RSSU5LX01TRyxlbnYpKTsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHJldHVybiBjb25zdW1lKHRoaXNfcGxheWVyKCkpOworfQorCisvLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKy8vIEtvbXBhdGliaWxpdGFldHNjb2RlCisvLyB1bSBldmVudHVlbGwgdmVyZ2Vzc2VuZXMgRm9vZCBvZGVyIFp1Z3JpZmYgdm9uIGF1c3NlbiBhdWYgYWx0ZXMgRm9vZAorLy8gbWl0enViZWtvbW1lbgorCitub3NhdmUgZGVwcmVjYXRlZCBpbnQgYWxjLCBhbGNfcHAsIGZvb2QsIGZvb2RfcHAsIGhlYWwsIHAsIHNvZnQsIHNvZnRfcHAsIGM7CisKK2RlcHJlY2F0ZWQgaW50IGVhdF90aGlzKCBzdHJpbmcgc3RyICkgeworICByZXR1cm4gY21kX2VhdChzdHIpOworfQorCitkZXByZWNhdGVkIGludCBkcmlua190aGlzKHN0cmluZyBzdHIpIHsKKyAgcmV0dXJuIGNtZF9kcmluayhzdHIpOworfQorCitkZXByZWNhdGVkIHZvaWQgTWFrZURyaW5rKCkgeworICBTZXRQcm9wKFBfRFJJTkssMSk7CisgIFNldFByb3AoUF9GT09ELDApOworfQorCitkZXByZWNhdGVkIG1peGVkIF9xdWVyeV9vbGRfaXNfZm9vZCgpIHsKKyAgcmV0dXJuIGlzX2VhdGFibGUoKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfb2xkX2lzX2Zvb2QobWl4ZWQgdmFsdWUpIHsKKyAgU2V0UHJvcChQX0RSSU5LLDApOworICBTZXRQcm9wKFBfRk9PRCx2YWx1ZSk7Cit9CisKK2RlcHJlY2F0ZWQgbWl4ZWQgX3F1ZXJ5X29sZF9pc19kcmluaygpIHsKKyAgcmV0dXJuIGlzX2RyaW5rYWJsZSgpOworfQorCitkZXByZWNhdGVkIHZvaWQgX3NldF9vbGRfaXNfZHJpbmsobWl4ZWQgdmFsdWUpIHsKKyAgU2V0UHJvcChQX0RSSU5LLHZhbHVlKTsKKyAgU2V0UHJvcChQX0ZPT0QsMCk7Cit9CisKK2RlcHJlY2F0ZWQgbWl4ZWQgX3F1ZXJ5X29sZF9pc19mdWxsKCkgeworICByZXR1cm4gaXNfbm90X2VtcHR5KCk7Cit9CisKK2RlcHJlY2F0ZWQgdm9pZCBfc2V0X29sZF9pc19mdWxsKG1peGVkIHZhbHVlKSB7CisgIFNldFByb3AoUF9QT1JUSU9OUyx2YWx1ZSk7Cit9CisKK2RlcHJlY2F0ZWQgbWl4ZWQgX3F1ZXJ5X29sZF9hbGMoKSB7CisgIHJldHVybiBRdWVyeVByb3AoUF9BTENPSE9MKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfb2xkX2FsYyhtaXhlZCB2YWx1ZSkgeworICBTZXRQcm9wKFBfQUxDT0hPTCx2YWx1ZSk7Cit9CisKK2RlcHJlY2F0ZWQgbWl4ZWQgX3F1ZXJ5X29sZF93YXRlcigpIHsKKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX0RSSU5LKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfb2xkX3dhdGVyKG1peGVkIHZhbHVlKSB7CisgIFNldFByb3AoUF9EUklOSyx2YWx1ZSk7Cit9CisKK2RlcHJlY2F0ZWQgbWl4ZWQgX3F1ZXJ5X29sZF9mb29kX3NpemUoKSB7CisgIHJldHVybiBRdWVyeVByb3AoUF9GT09EKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfb2xkX2Zvb2Rfc2l6ZShtaXhlZCB2YWx1ZSkgeworICBTZXRQcm9wKFBfRk9PRCx2YWx1ZSk7Cit9CisKK2RlcHJlY2F0ZWQgbWl4ZWQgX3F1ZXJ5X29sZF9wb3Rpb24oKSB7CisgIHJldHVybiBRdWVyeVByb3AoUF9QT1JUSU9OUyk7Cit9CisKK2RlcHJlY2F0ZWQgdm9pZCBfc2V0X29sZF9wb3Rpb24obWl4ZWQgdmFsdWUpIHsKKyAgU2V0UHJvcChQX1BPUlRJT05TLHZhbHVlKTsKK30KKworZGVwcmVjYXRlZCBtaXhlZCBfcXVlcnlfb2xkX2hlYWxfaHAoKSB7CisgIHJldHVybiBRdWVyeVByb3AoUF9IUCk7Cit9CisKK2RlcHJlY2F0ZWQgdm9pZCBfc2V0X29sZF9oZWFsX2hwKG1peGVkIHZhbHVlKSB7CisgIFNldFByb3AoUF9IUCx2YWx1ZSk7Cit9CisKK2RlcHJlY2F0ZWQgbWl4ZWQgX3F1ZXJ5X29sZF9oZWFsX3NwKCkgeworICByZXR1cm4gUXVlcnlQcm9wKFBfU1ApOworfQorCitkZXByZWNhdGVkIHZvaWQgX3NldF9vbGRfaGVhbF9zcChtaXhlZCB2YWx1ZSkgeworICBTZXRQcm9wKFBfU1AsdmFsdWUpOworfQorCitkZXByZWNhdGVkIG1peGVkIF9xdWVyeV9vbGRfYmFkKCkgeworICByZXR1cm4gaXNfYmFkKCk7Cit9CisKK2RlcHJlY2F0ZWQgdm9pZCBfc2V0X29sZF9iYWQobWl4ZWQgdmFsdWUpIHsKKyAgcmV0dXJuOworfQorCitkZXByZWNhdGVkIG1peGVkIF9xdWVyeV9vbGRfbWVzcygpIHsKKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX0NPTlNVTUVfTVNHKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfb2xkX21lc3MobWl4ZWQgdmFsdWUpIHsKKyAgU2V0UHJvcChQX0NPTlNVTUVfTVNHLHZhbHVlKTsKK30KKworZGVwcmVjYXRlZCBtaXhlZCBfcXVlcnlfb2xkX2VhdGVyKCkgeworICByZXR1cm4gUXVlcnlQcm9wKFBfRUFURVJfTVNHKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfb2xkX2VhdGVyKG1peGVkIHZhbHVlKSB7CisgIFNldFByb3AoUF9FQVRFUl9NU0csdmFsdWUpOworfQorCitkZXByZWNhdGVkIG1peGVkIF9xdWVyeV9vbGRfcG9pc29uKCkgeworICByZXR1cm4gUXVlcnlQcm9wKFBfUE9JU09OKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfb2xkX3BvaXNvbihtaXhlZCB2YWx1ZSkgeworICBTZXRQcm9wKFBfUE9JU09OLHZhbHVlKTsKK30KKworLy8gaW50ZXJuZSBNZXRob2RlCitwcml2YXRlIG1peGVkIGdldF9vbGRfZW1wdHkoc3RyaW5nIHByb3ApIHsKKyAgbWl4ZWQgcHJvcHMgPSBRdWVyeVByb3AoUF9FTVBUWV9QUk9QUyk7CisgIGlmIChtYXBwaW5ncChwcm9wcykpIHJldHVybiBwcm9wc1twcm9wXTsKKyAgcmV0dXJuIDA7Cit9CisvLyBpbnRlcm5lIE1ldGhvZGUKK3ByaXZhdGUgdm9pZCBzZXRfb2xkX2VtcHR5KHN0cmluZyBwcm9wLCBtaXhlZCB2YWx1ZSkgeworICBtaXhlZCBwcm9wcyA9IFF1ZXJ5UHJvcChQX0VNUFRZX1BST1BTKTsKKyAgaWYgKCFtYXBwaW5ncChwcm9wcykpIHByb3BzID0gKFtwcm9wOnZhbHVlXSk7CisgIGVsc2UgcHJvcHNbcHJvcF0gPSB2YWx1ZTsKKyAgU2V0UHJvcChQX0VNUFRZX1BST1BTLHByb3BzKTsKK30KKworZGVwcmVjYXRlZCBtaXhlZCBfcXVlcnlfb2xkX2VtcHR5X2NvbigpIHsKKyAgcmV0dXJuIGdldF9vbGRfZW1wdHkoUF9TSE9SVCk7Cit9CisKK2RlcHJlY2F0ZWQgdm9pZCBfc2V0X29sZF9lbXB0eV9jb24obWl4ZWQgdmFsdWUpIHsKKyAgc2V0X29sZF9lbXB0eShQX1NIT1JULHZhbHVlKTsKK30KKworZGVwcmVjYXRlZCBtaXhlZCBfcXVlcnlfb2xkX2VtcHR5X2dlbmRlcigpIHsKKyAgcmV0dXJuIGdldF9vbGRfZW1wdHkoUF9HRU5ERVIpOworfQorCitkZXByZWNhdGVkIHZvaWQgX3NldF9vbGRfZW1wdHlfZ2VuZGVyKG1peGVkIHZhbHVlKSB7CisgIHNldF9vbGRfZW1wdHkoUF9HRU5ERVIsdmFsdWUpOworfQorCitkZXByZWNhdGVkIG1peGVkIF9xdWVyeV9vbGRfZW1wdHlfaWQoKSB7CisgIHJldHVybiBnZXRfb2xkX2VtcHR5KFBfSURTKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfb2xkX2VtcHR5X2lkKG1peGVkIHZhbHVlKSB7CisgIHNldF9vbGRfZW1wdHkoUF9JRFMsdmFsdWUpOworfQorCitkZXByZWNhdGVkIG1peGVkIF9xdWVyeV9vbGRfZW1wdHlfbG9uZygpIHsKKyAgcmV0dXJuIGdldF9vbGRfZW1wdHkoUF9MT05HKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfb2xkX2VtcHR5X2xvbmcobWl4ZWQgdmFsdWUpIHsKKyAgc2V0X29sZF9lbXB0eShQX0xPTkcsdmFsdWUpOworfQorCitkZXByZWNhdGVkIG1peGVkIF9xdWVyeV9vbGRfbm9fY29uKCkgeworICByZXR1cm4gbWFwcGluZ3AoUXVlcnlQcm9wKFBfRU1QVFlfUFJPUFMpKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfb2xkX25vX2NvbihtaXhlZCB2YWx1ZSkgeworICBpZiAodmFsdWUpIFNldFByb3AoUF9FTVBUWV9QUk9QUywoW10pKTsKKyAgZWxzZSBTZXRQcm9wKFBfRU1QVFlfUFJPUFMsMCk7Cit9CisKKy8vIE11cGZlbAorZGVwcmVjYXRlZCBpbnQgRXNzYmFyKCkgeworICByZXR1cm4gMTsKK30KKworZGVwcmVjYXRlZCBtaXhlZCBfcXVlcnlfZm9vZF9pbmZvKCkgeworICByZXR1cm4gKFtdKTsKK30KKworZGVwcmVjYXRlZCB2b2lkIF9zZXRfZm9vZF9pbmZvKG1peGVkIHZhbHVlKSB7CisgIHJldHVybjsKK30KKworLy8gVHJveQorZGVwcmVjYXRlZCB2b2lkIGZvb2RfZGVjYXkoKSB7CisgIHJldHVybjsKK30KKworZGVwcmVjYXRlZCBpbnQgZWF0X21lKHN0cmluZyBzdHIpIHsKKyAgcmV0dXJuIDA7Cit9CmRpZmYgLS1naXQgYS9zdGQvZ2lsZGUuYyBiL3N0ZC9naWxkZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZmYjg0Y2YKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvZ2lsZGUuYwpAQCAtMCwwICsxLDM4MCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGdpbGRlLmMgLS0gU3RhbmRhcmRnaWxkZQorLy8KKy8vICRJZDogZ2lsZGUuYyA4Mzg4IDIwMTMtMDItMTYgMTc6Mjg6MzFaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL3Jvb20iOworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxyb29tcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPGV4cGxvcmF0aW9uLmg+CisjaW5jbHVkZSA8YW5zaS5oPgorI2luY2x1ZGUgIi9zZWN1cmUvcXVlc3RtYXN0ZXIuaCIKKyNpbmNsdWRlICIvc2VjdXJlL2xlcG1hc3Rlci5oIgorI2luY2x1ZGUgIi9zZWN1cmUvY29uZmlnLmgiCisjaW5jbHVkZSA8ZXZlbnRzLmg+CisKKyNkZWZpbmUga29zdGVuXzAgXAorICAoWzA6ICAgICAgICAgICAgICAgICJCaXMgRHUgRGljaCBkYXMgbmFlY2hzdGUgTWFsIGhpZXIgYmxpY2tlbiBsYWVzc3QsIHNvbGx0ZXN0IER1IGVpbmUgTWVuZ2UgU3R1ZmVucHVua3RlIHNhbW1lbG4uIFNvbnN0IHdpcmQgZGFzIG5peCEiLFwKKyAgICAiemF1YmVyZXIiOiAgICAgICAiSmV0enQgZmFuZyBoaWVyIGphIG5pY2h0IGFuIHp1IGphbW1lcm4uIER1IGhhc3QgZG9jaCBncmFkZSBlcnN0IGVyaG9laHQuIEZ1ZXIgZGllIG5hZWNoc3RlIFN0dWZlIG11c3N0IER1IGVyc3RtYWwgTGVpc3R1bmcgemVpZ2VuISIsXAorICAgICJrYWVtcGZlciI6ICAgICAgICJIYXQgZ3JhZGUgZXJzdCBlcmhvZWh0IHVuZCBmYWVuZ3Qgc2Nob24gYW4genUgamFtbWVybiB3aWUgZWluIGFsdGVyc3NjaHdhY2hlciBaYXViZXJlci4gTmltbSBnZWZhZWxsaWdzdCBIYWx0dW5nIGFuISIsXAorICAgICJrbGVydXMiOiAgICAgICAgICJXZXIgaGF0IERpciBkZW5uIGRhcyBHZWhpcm4gZ2VsYWV1dGVydD8gWmVpZyBlcnN0bWFsIHdhcyB2b24gRGVpbmVtIEtvZW5uZW4sIGJldm9yIER1IHNjaG9uIHdpZWRlciBlcmhvZWhlbiB3aWxsc3QhIixcCisgICAgImNoYW9zIjogICAgICAgICAgIlNvIGNoYW90aXNjaCBrYW5uc3QgRHUgZG9jaCBuaWNodCBzZWluIHp1IGdsYXViZW4sIGRhc3MgRHUgc2Nob24gd2llZGVyIGVyaG9laGVuIGthbm5zdCEiLFwKKyAgICAia2FyYXRlIjogICAgICAgICAiUnVoIERlaW5lIEtub2NoZW4gZXJzdG1hbCBlaW4gYmlzc2NoZW4gYXVzLiBCaXMgenVyIG5hZWNoc3RlbiBTdHVmZSB3ZXJkZW4gc2llIG5vY2ggZ2VudWcgbGVpZGVuIG11ZXNzZW4hIixcCisgICAgImthdHplbmtyaWVnZXIiOiAgIkRhIGhpbGZ0IGtlaW4gTWF1bnplbiB1bmQga2VpbiBTY2hudXJyZW4uIER1IGhhc3QgZ3JhZGUgZXJzdCBlcmhvZWh0IHVuZCBkYWJlaSBibGVpYnQgZGFzISIsXAorICAgICJ0YW5qaWFuIjogICAgICAgICJKZXR6dCBzY2hyZWkgbmljaHQgZ2xlaWNoIG5hY2ggU2lhbWlsLiBEdSBtdXNzdCBub2NoIGVpbmUgTWVuZ2UgbGVpc3RlbiBiaXMgenVyIG5hZWNoc3RlbiBTdHVmZSEiLFwKKyAgICAiYmllcnNjaHVldHRsZXIiOiAiRHUgaGFzdCBkYXMgQmllciBhdWYgRGVpbmVuIGxldHp0ZW4gRXJmb2xnIG5vY2ggbmljaHQgZWlubWFsIGF1c2dldHJ1bmtlbi4gV2VyZCBqZXR6dCBqYSBuaWNodCBncm9lc3NlbndhaG5zaW5uaWchIixcCisgICAgIndlcndvZWxmZSIgOiAgICAgIlVuZCB3ZW5uIER1IG5vY2ggc28gZ3JpbW1pZyBndWNrc3QgdW5kIGRlbiBNb25kIGFuaGV1bHN0LiBEdSBoYXN0IGdlcmFkZSBlcnN0IGVyaG9laHQuIE51biBtdXNzdCBEdSBlcnN0bWFsIHdpZWRlciBldHdhcyB0dW4hIixcCisgIF0pCisjZGVmaW5lIGtvc3Rlbl8yMCBcCisgIChbMDogICAgICAgICAgICAgICAgIkRhIGxpZWd0IGFiZXIgbm9jaCBlaW4gd2VpdGVyIFdlZyB2b3IgRGlyLiBBYmVyIER1IHNjaGFmZnN0IGVzIGdhbnogc2ljaGVyISIsXAorICAgICJ6YXViZXJlciI6ICAgICAgICJEdSBrYW5uc3QgendhciB6YXViZXJuLCBhYmVyIG5pY2h0IGhleGVuLiBGdWVyIGRpZSBuYWVjaHN0ZSBTdHVmZSBtdXNzdCBEdSBzY2hvbiBub2NoIGVpbmlnZXMgdHVuISIsXAorICAgICJrYWVtcGZlciI6ICAgICAgICJPaCB3ZWgsIGRhIGhhc3QgRHUgYWJlciBub2NoIG5lIE1lbmdlIHZvciBEaXIuIEJlaXNzIGRpZSBaYWVobmUgenVzYW1tZW4gdW5kIGxvcyBnZWh0cyEiLFwKKyAgICAia2xlcnVzIjogICAgICAgICAiRHUgd2lyc3QgYmVzdGltbXQgbm9jaCBlaW5pZ2UgSGVpbHRyYWVua2UgYnJhdWNoZW4gYmlzIHp1ciBuYWVjaHN0ZW4gU3R1ZmUhIixcCisgICAgImNoYW9zIjogICAgICAgICAgIkhhc3QgRHUgdmVyc3VjaHQgRGVpbiBDaGFvcyB6dSBiZXNlaXRpZ2VuLCBvZGVyIHdhcyBoYXN0IER1IGdlbWFjaHQ/IFNlaHIgd2VpdCBnZWtvbW1lbiBiaXN0ZSBqZWRlbmZhbGxzIG5vY2ggbmljaHQuIE11c3N0IERpY2ggc2Nob24gZWluIGJpc3NjaGVuIGFuc3RyZW5nZW4hIixcCisgICAgImthcmF0ZSI6ICAgICAgICAgIkdhbnogc2Nob2VuIGFuc3RyZW5nZW5kIGltbWVyIG51ciBtaXQgSGFuZCB1bmQgRnVzcyB6dSBtZXR6ZWxuLCBvZGVyPyBBYmVyIGVzIGhhdCBEaWNoIHNjaG9uIGV0d2FzIG5hZWhlciBhbiBkaWUgbmFlY2hzdGUgU3R1ZmUgcmFuZ2VicmFjaHQhIixcCisgICAgImthdHplbmtyaWVnZXIiOiAgIkJpc3NjaGVuIHdlbmlnZXIgRmVsbHBmbGVnZSBiZXRyZWliZW4sIHVuZCBlaW4gYmlzc2NoZW4gbWVociBTdHVmZW5wdW5rdGUgc2FtbWVsbi4gRHUgaGFzdCBuYWVtbGljaCBub2NoIGVpbiBndXRlcyBTdHVlY2sgdm9yIERpciEiLFwKKyAgICAidGFuamlhbiI6ICAgICAgICAiRHUgaGFzdCBub2NoIG5lIE1lbmdlIHp1IHR1biBiaXMgenVyIG5hZWNoc3RlbiBTdHVmZS4gU3RlcmIgbmljaHQgc28gb2Z0LCBhYmVyIHNvd2FzIHR1biBUYW5qaWFuIGphIGVoIG5pY2h0ISIsXAorICAgICJiaWVyc2NodWV0dGxlciI6ICJCaWVyIHRyaW5rZW4gYWxsZWluZSB3aXJkIERpY2ggbmljaHQgd2VpdGVyIGJyaW5nZW4sIG9id29obCBEdSBzY2hvbiBlaW4gU3R1ZWNrIHdlaXQgZ2Vrb21tZW4gYmlzdCEiLFwKKyAgICAid2Vyd29lbGZlIiA6ICAgICAiU3RhZXJrZSBEZWluZSBXaWxsZW5za3JhZnQuIER1IGhhc3Qgbm9jaCBlaW5pZ2VzIHZvciBEaXIhIixcCisgIF0pCisjZGVmaW5lIGtvc3Rlbl80MCBcCisgIChbMDogICAgICAgICAgICAgICAgIkFsc28gZGllIEhhZWxmdGUgaGFzdCBEdSBzY2hvbiB1bmdlZmFlaHIgZ2VzY2hhZmZ0LiBBYmVyIHJ1aCBEaWNoIGpldHp0IGphIG5pY2h0IGRhcmF1ZiBhdXMuIFNpZWggbWFsIHp1LCBkYXNzIER1IGRpZSB6d2VpdGUgSGFlbGZ0ZSB6dXIgbmFlY2hzdGVuIFN0dWZlIGF1Y2ggbm9jaCBzY2hhZmZzdC4gQXVmIGVpbmVtIEJlaW4ga2FubiBtYW4gc2NobGllc3NsaWNoIG5pY2h0IGxhbmdlIHN0ZWhuISIsXAorICAgICJ6YXViZXJlciI6ICAgICAgICJUZWlsZSBMbHlzdHJhdGhlIG1pdCBIaWxmZS4gT2NoIHNjaGFkZSBzY2hlaW50IG5pY2h0IHp1IGZ1bmt0aW9uaWVyZW4sIGRhbm4gbXVzc3QgRHUgZWJlbiBzZWxiZXIgbm9jaCBuZSBNZW5nZSBTdHVmZW5wdW5rdGUgc2FtbWVsbiEiLFwKKyAgICAia2FlbXBmZXIiOiAgICAgICAiS2FlbXBmZXIgc2NobmVsbCBhbiBkaWUgV2FmZmVuISBEaWUgSGFlbGZ0ZSBoYXN0IER1IHVuZ2VmYWVociBnZXNjaGFmZnQsIGFiZXIgZXMgZ2lidCBub2NoIHZpZWwgenUgdHVuISIsXAorICAgICJrbGVydXMiOiAgICAgICAgICJCZWlsZSBEaWNoISBEYXMgQm9lc2Ugc2l0enQgRGlyIGltIE5hY2tlbiB1bmQgRHUgaGFzdCBub2NoIHVuZ2VmYWVociBkaWUgSGFlbGZ0ZSB2b3IgRGlyISIsXAorICAgICJjaGFvcyI6ICAgICAgICAgICJTY2huYXBwIERpciBEZWluZW4gRGFlbW9uIHVuZCB0ZWlsIERpciBkaWUgendlaXRlIEhhZWxmdGUgZGVyIEFyYmVpdCBtaXQgaWhtISIsXAorICAgICJrYXJhdGUiOiAgICAgICAgICJEdSBzY2hlaW5zdCBlaW5nZXNlaGVuIHp1IGhhYmVuLCBkYXNzIGhpcm5sb3NlcyBEcmF1ZmhhdWVuIG5peCBudXR6dC4gRGllIEhhZWxmdGUgaGFzdGUgdW5nZWZhZWhyIHNjaG9uIGdlc2NoYWZmdCEiLFwKKyAgICAia2F0emVua3JpZWdlciI6ICAiU28gdW5nZWZhZWhyIGJpcyB6dXIgSGFlbGZ0ZSBoYXN0IER1IERpY2ggc2Nob24gYW4gZGllIG5ldWUgU3R1ZmUgaGVyYW5nZXNjaGxpY2hlbiEiLFwKKyAgICAidGFuamlhbiI6ICAgICAgICAiTWFuIGthbm4gZGVuIFdlcnQgendpc2NoZW4gZGVuIGJlaWRlbiBTdHVmZW4gZHVyY2hhdXMgYWxzIGF1c2dld29nZW4gYmV6ZWljaG5lbi4gVHJvdHpkZW0gaGFzdCBEdSBub2NoIGVpbiBTdHVlY2sgZGVzIFdlZ2VzIHZvciBEaXIhIixcCisgICAgImJpZXJzY2h1ZXR0bGVyIjogIldhciBkYXMgRmFzcyBudSBoYWxiIHZvbGwgb2RlciBoYWxiIGxlZXI/IEplZGVuZmFsbHMgYmlzdGUgdW5nZWZhZWhyIGJlaSBkZXIgSGFlbGZ0ZSBhbmdla29tbWVuISIsXAorICAgICJ3ZXJ3b2VsZmUiIDogICAgICJOb2NoIGVpbmlnZSBHZWduZXIgd2VyZGVuIHNpY2ggdm9yIERpciBmdWVyY2h0ZW4gbXVlc3Nlbiwgb2J3b2hsIER1IHNjaG9uIHZpZWwgZ2VzY2hhZmZ0IGhhc3QhIixcCisgIF0pCisjZGVmaW5lIGtvc3Rlbl82MCBcCisgIChbMDogICAgICAgICAgICAgICAgIkFsc28gZWluIGJpc3NjaGVuIHdhcyBtdXNzdCBEdSBub2NoIHR1biwgYWJlciBlcyBzaWVodCBzY2hvbiB6aWVtbGljaCBndXQgYXVzISIsXAorICAgICJ6YXViZXJlciI6ICAgICAgICJFaW4gYmlzc2NoZW4gV2lsbGUgdW5kIE1hZ2llIHVuZCBEdSBzY2hhZmZzdCBlcyB3aWVkZXIgZWluIFN0dWVjayBuYWVoZXIgYW4gZGllIG5ldWUgU3R1ZmUgaGVyYW56dWtvbW1lbiEiLFwKKyAgICAia2FlbXBmZXIiOiAgICAgICAiU3RhZXJrZSBEZWluZW4gS2FtcGZ3aWxsZW4uIERpZSBncm9lc3N0ZW4gQW5zdHJlbmd1bmdlbiBoYXN0IER1IHNjaG9uIGhpbnRlciBEaXIhIixcCisgICAgImtsZXJ1cyI6ICAgICAgICAgIlNvIG5haCBhbSBaaWVsIHdpcnN0IER1IGRvY2ggbmljaHQgYXVmZ2ViZW4gd29sbGVuLiBIb2wgRGlyIG5vY2ggZWluIGJpc3NjaGVuIGdvZXR0bGljaGUgVW50ZXJzdHVldHp1bmcgdW5kIHdlaXRlciBnZWh0cyEiLFwKKyAgICAiY2hhb3MiOiAgICAgICAgICAiQ2hhb3Rpc2NoIHNlaW4gYWxsZWluZSBoaWxmdCBuaWNodC4gRWluIGJpc3NjaGVuIHdhcyBtdXNzdCBEdSBzY2hvbiBub2NoIHR1biEiLFwKKyAgICAia2FyYXRlIjogICAgICAgICAiRGllIEhhbmRrYW50ZW4gZ2VzY2hhZXJmdCwgZGVuIEdpIGZlc3QgenVnZWJ1bmRlbi4gQmFsZCBoYXN0IER1IGVzIGdlc2NoYWZmdCEiLFwKKyAgICAia2F0emVua3JpZWdlciI6ICAiQXVmIFNhbXRwZm90ZW4gc2NobGVpY2hzdCBEdSBtaXQgZ3Jvc3NlbiBTY2hyaXR0ZW4gYW5zIFppZWwgaGVyYW4uIEFiZXIgZWluIGJpc3NjaGVuIGZlaGx0IG5vY2ghIixcCisgICAgInRhbmppYW4iOiAgICAgICAgIkVpbmUgUXVlc3QgaGllciwgZWluIHBhYXIgTW9uc3RlciBkYS4gQWJlciBpbW1lciBzY2hvZW4gYXVzZ2VnbGljaGVuIGJsZWliZW4sIGRhbm4ga2xhcHB0cyBhdWNoIHdlaXRlcmhpbiEiLFwKKyAgICAiYmllcnNjaHVldHRsZXIiOiAiTm9jaCBlaW4gcGFhciBrcmFlZnRpZ2UgU2NobHVja2UgdW5kIER1IGhhc3QgZXMgZmFzdCBnZXNjaGFmZnQhIixcCisgICAgIndlcndvZWxmZSIgOiAgICAgIlZlcmxhc3MgRGVpbiBSdWRlbCB1bmQgemllaCBoaW5hdXMgaW5zIEFiZW50ZXVlci4gRGFubiB3aXJzdCBEdSBiYWxkIHNpZWdyZWljaCBoZWlta2VocmVuISIsXAorICBdKQorI2RlZmluZSBrb3N0ZW5fODAgXAorICAoWzA6ICAgICAgICAgICAgICAgICJIdWNoIG5hIHNvd2FzLCBEdSBoYXN0IGRpZSBuYWVjaHN0ZSBTdHVmZSBqYSBzY2hvbiBmYXN0IGVycmVpY2h0LiBOYSBhbHNvISBEZXIgUmVzdCBpc3QgamEgd2lya2xpY2ggbnVyIG5vY2ggS2xlaW5rcmFtISIsXAorICAgICJ6YXViZXJlciI6ICAgICAgICJEaWUgcGFhciBmZWhsZW5kZW4gUHVlbmt0Y2hlbiBoYXN0ZSBEaXIgZG9jaCByYXNjaCB6dXNhbW1lbmdlemF1YmVydCEiLFwKKyAgICAia2FlbXBmZXIiOiAgICAgICAiRGFzIGZlaGxlbmRlIGJpc3NjaGVuIG1hY2hzdCBEdSBhbHMgZ25hZGVubG9zIGd1dGVyIEthZW1wZmVyIGRvY2ggbWl0IExpbmtzLiBKZXR6dCBoYWx0IERpY2ggYWJlciBtYWwgcmFuLiBPZGVyIHdpbGxzdCBEdSBEaWNoIGF1ZiBkZW0gbGV0enRlbiBTdHVlY2sgbm9jaCB2b24gc28gZWluZW0gbHVzY2hpZ2VuIFphdWJlcmVyIHVlYmVycnVuZGVuIGxhc3Nlbj8iLFwKKyAgICAia2xlcnVzIjogICAgICAgICAiQmVpIFNhcGhpbmEsIEthbmRyaSB1bmQgTGVtYm9sZCwgRHUgYmlzdCBmYXN0IGJlaSBkZXIgbmFlY2hzdGVuIFN0dWZlIGFuZ2Vrb21tZW4hIixcCisgICAgImNoYW9zIjogICAgICAgICAgIkJvZXNlIHdhZWhydCBhbSBsYWVuZ3N0ZW4uIEZhc3QgaGFzdCBEdSBlcyBnZXNjaGFmZnQhIixcCisgICAgImthcmF0ZSI6ICAgICAgICAgIlNvIHZpZWxlIGJsYXVlIEZsZWNrZW4gd2llIER1IGFuIEFybWVuIHVuZCBCZWluZW4gaGFzdCwga2FubiBkaWUgbmFlY2hzdGUgU3R1ZmUgbmljaHQgbWVociB3ZWl0IHNlaW4hIixcCisgICAgImthdHplbmtyaWVnZXIiOiAgIlBhc3MgYmxvc3MgYXVmLCBkYXNzIERpY2ggYXVmIGRlbiBsZXR6dGVuIFplbnRpbWV0ZXJuIG5pY2h0IG5vY2ggZWluIEh1bmQgZXJ3aXNjaHQhIixcCisgICAgInRhbmppYW4iOiAgICAgICAgIlNpYW1pbCB3aXJkIHN0b2x6IGF1ZiBEaWNoIHNlaW4uIER1IGhhc3QgRGljaCBnZWdlbiBHdXQgdW5kIEJvZXNlIGR1cmNoZ2VzZXR6dCB1bmQgZGFzIFppZWwgZmFzdCBlcnJlaWNodCEiLFwKKyAgICAiYmllcnNjaHVldHRsZXIiOiAiTGFuZ2UgbXVzc3QgRHUgbmljaHQgbWVociB3YXJ0ZW4uIEthbm5zdCBydWhpZyBzY2hvbiBtYWwgZWluIGZyaXNjaGVzIEJpZXIgaW4gQXVmdHJhZyBnZWJlbiEiLFwKKyAgICAid2Vyd29lbGZlIiA6ICAgICAiTm9jaCBlaW4gbGV0enRlcyBNYWwgZGllIGZ1ZXJjaHRlcmxpY2hlbiBLcmFsbGVuIHNjaGFlcmZlbiwgZGFubiBoYXN0IER1IERlaW5lbiBuZXVlbiBMZXZlbCBlcnJlaWNodCEiLFwKKyAgXSkKKwordm9pZCBjcmVhdGUoKQoreworICBpZiAob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bMC4uPDNdKSB7CisgICAgICBzZXRfbmV4dF9yZXNldCgtMSk7CisgICAgICByZXR1cm47CisgIH0KKyAgcm9vbTo6Y3JlYXRlKCk7CisKKyAgQWRkQ21kKCJrb3N0ZW4iLCJrb3N0ZW4iKTsKKyAgQWRkQ21kKCJsaXN0ZSIsImxpc3RlIik7CisgIEFkZENtZCgiZXJob2VoZSIsImFkdmFuY2UiKTsKKyAgQWRkQ21kKCh7InRyZWZmIn0pLCAiR290b01hZ2llclRyZWZmIik7CisgfQorCit2b2lkIGluaXQoKQoreworICBpbnQgbHZsOworICByb29tOjppbml0KCk7CisKKyAgaWYgKFBMICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoUEwpCisgICAgICAmJiAobHZsPVBMLT5RdWVyeVByb3AoUF9MRVZFTCkpIDw9IDYKKyAgICAgICYmIExFUE1BU1RFUi0+UXVlcnlMZXZlbChQTC0+UXVlcnlQcm9wKFBfTEVQKSkgPiBsdmwpCisgIHsKKyAgICB0ZWxsX29iamVjdChQTCwKKyAgICAgICJcbkR1IGtvZW5udGVzdCBEZWluZSBTdHVmZSBtaXQgXCJlcmhvZWhlIHNwaWVsZXJcIiBoaWVyIGluIGRlciBHaWxkZSAiCisgICAgICAiZXJob2VoZW4uXG5cbiIpOworICB9Cit9CisKK3N0cmluZyB6ZWlnZV9yZWJvb3QoKQoreworICBzdHJpbmcgc3RyOworICBpbnQgdCx0MjsKKworICB0PXRpbWUoKS1sYXN0X3JlYm9vdF90aW1lKCk7CisgIHQyPXQ7CisgIHN0cj0iU2VpdCBkZW0gbGV0enRlbiBTaHV0ZG93biBzaW5kICIrdCsiIFNla3VuZGVuIHZlcmdhbmdlbi5cbiI7CisgIGlmICh0PDYwKSByZXR1cm4gc3RyOworICBzdHIrPSJEYXMgc2luZCAiOworICBpZiAodD49ODY0MDApCisgIHsKKyAgICBzdHIrPXQvODY0MDArIiBUYWciOworICAgIGlmICh0Pj04NjQwMCoyKQorICAgICAgc3RyKz0iZSI7CisgICAgc3RyKz0iLCAiOworICAgIHQyPXQyJTg2NDAwOworICB9CisgIGlmICh0Pj0zNjAwKQorICB7CisgICAgc3RyKz10Mi8zNjAwKyIgU3R1bmRlIjsKKyAgICBpZiAodDIvMzYwMCE9MSkKKyAgICAgIHN0cis9Im4iOworICAgIHN0cis9IiwgIjsKKyAgICB0Mj10MiUzNjAwOworICB9CisgIGlmICh0Pj02MCkKKyAgeworICAgIHN0cis9dDIvNjArIiBNaW51dGUiOworICAgIGlmICh0Mi82MCE9MSkKKyAgICAgIHN0cis9Im4iOworICAgIHN0cis9IiB1bmQgIjsKKyAgICB0Mj10MiU2MDsKKyAgfQorICBzdHIrPXQyKyIgU2VrdW5kZSI7CisgIGlmICh0MiE9MSkKKyAgICBzdHIrPSJuIjsKKyAgc3RyKz0iLlxuIjsKKyAgcmV0dXJuIHN0cjsKK30KKworaW50IHNlZXJfY29uZChpbnQgc2lsZW50KQoreworICBpbnQgY29uZDsKKworICBjb25kPUxFUE1BU1RFUi0+UXVlcnlSZWFkeUZvcldpeih0aGlzX3BsYXllcigpKTsKKworICBpZiAoIXNpbGVudCkKKyAgICB3cml0ZShicmVha19zdHJpbmcoTEVQTUFTVEVSLT5RdWVyeVJlYWR5Rm9yV2l6VGV4dCh0aGlzX3BsYXllcigpKSwKKyAgICAgICAgICA3OCwgMCwgMSkpOworCisgIHJldHVybiBjb25kOworfQorCit2YXJhcmdzIGludCBrb3N0ZW4oc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nIHRtcDsKKworICBpbnQgbGVwID0gUEwtPlF1ZXJ5UHJvcChQX0xFUCk7CisgIGludCBsdmwgPSBQTC0+UXVlcnlQcm9wKFBfTEVWRUwpOworICBpbnQgZGlmZiA9IExFUE1BU1RFUi0+UXVlcnlOZXh0TGV2ZWxMRVAobHZsLCBsZXApOworCisgIHN3aXRjaCAoIGRpZmYgKSB7CisgICAgY2FzZSAxMDEuLl9fSU5UX01BWF9fOgorICAgICAgLy8gRmFsbHMgbWFsIExFUHMgYWJoYW5kZW5nZWtvbW1lbiBzaW5kLi4uCisgICAgICB0bXAgPSAiV2llIGJpc3QgRHUgdWViZXJoYXVwdCBhbiBEZWluZW4gTGV2ZWwgZ2Vrb21tZW4/XG4iCisgICAgICAiU2VpIGZyb2gsIGRhc3MgRHUgbmljaHQgd2llZGVyIGFiZ2VzdHVmdCB3aXJzdC4iOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlIDgxLi4xMDA6CisgICAgICB0bXA9a29zdGVuXzBbUEwtPlF1ZXJ5UHJvcChQX0dVSUxEKV0gfHwga29zdGVuXzBbMF07CisgICAgICBicmVhazsKKworICAgIGNhc2UgNjEuLjgwOgorICAgICAgdG1wPWtvc3Rlbl8yMFtQTC0+UXVlcnlQcm9wKFBfR1VJTEQpXSB8fCBrb3N0ZW5fMjBbMF07CisgICAgICBicmVhazsKKworICAgIGNhc2UgNDEuLjYwOgorICAgICAgdG1wPWtvc3Rlbl80MFtQTC0+UXVlcnlQcm9wKFBfR1VJTEQpXSB8fCBrb3N0ZW5fNDBbMF07CisgICAgICBicmVhazsKKworICAgIGNhc2UgMjEuLjQwOgorICAgICAgdG1wPWtvc3Rlbl82MFtQTC0+UXVlcnlQcm9wKFBfR1VJTEQpXSB8fCBrb3N0ZW5fNjBbMF07CisgICAgICBicmVhazsKKworICAgIGNhc2UgMS4uMjA6CisgICAgICB0bXA9a29zdGVuXzgwW1BMLT5RdWVyeVByb3AoUF9HVUlMRCldIHx8IGtvc3Rlbl84MFswXTsKKyAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDoKKyAgICAgIGlmICggbHZsIDwgOSApCisgICAgICAgIHRtcCA9ICJQcm9iaWVyIG1hbCBkZW4gQmVmZWhsICdlcmhvZWhlJy4iOworICAgICAgZWxzZQorICAgICAgICB0bXAgPSAiRGVuIEJlZmVobCAnZXJob2VoZScga2VubnN0IER1IGFiZXIsIGphPyI7CisgICAgICBicmVhazsKKyAgfQorCisgIHdyaXRlKCBicmVha19zdHJpbmcoIHRtcCwgNzgsIDAsIEJTX0xFQVZFX01ZX0xGUyApICk7CisKKyAgaWYgKCFJU19TRUVSKHRoaXNfcGxheWVyKCkpIAorICAgICAgJiYgKCAoc3RyID09ICJsYW5nIikgfHwKKyAgICAgICAgKHRoaXNfcGxheWVyKCktPlF1ZXJ5UHJvcChQX0xFVkVMKSA+IDEyICYmIHN0ciAhPSAia3VyeiIpKSkgeworICAgIHNlZXJfY29uZCgwKTsKKyAgICB3cml0ZSAoYnJlYWtfc3RyaW5nKCJcbk1pdCAna29zdGVuIGt1cnonIGthbm5zdCBEdSBkaWUgQW5nYWJlIGRlciAiCisgICAgICAgICAgIlNlaGVyLUFuZm9yZGVydW5nZW4gdW50ZXJkcnVlY2tlbi4iLCA3OCwwLDEpKTsKKyAgfQorCisgIHJldHVybiAxOworfQorCisvLyBlcm1pdHRlbHQgR2lsZGVudGl0ZWwgenVtIExldmVsIDxsZXY+LgorLy8gRGVyIGxldHp0ZSB2ZXJmdWVnYmFyZSBHaWxkZW50aXRlbCB3aXJkIG51ciBmdWVyIFNlaGVyIHZlcmdlYmVuLgorLy8gVE9ETzogbWl0IGRlbSBlbnRzcHJlY2hlbmRlbiBDb2RlIGF1cyBnaWxkZW5fb2IuYyB2ZXJlaW5pZ2VuPworc3RyaW5nIGdldF9uZXdfdGl0bGUoaW50IGxldiwgb2JqZWN0IHBsKQoreworICBtYXBwaW5nIHRpdGxlczsKKworICBpZiAoIXBsKSByZXR1cm4gMDsKKworICBpZiAobGV2PDApIGxldj0wOworCisgIGlmIChwbC0+UXVlcnlQcm9wKFBfR0VOREVSKSA9PSBNQUxFKQorICAgIHRpdGxlcz0obWFwcGluZylRdWVyeVByb3AoUF9HVUlMRF9NQUxFX1RJVExFUyk7CisgIGVsc2UKKyAgICB0aXRsZXM9KG1hcHBpbmcpUXVlcnlQcm9wKFBfR1VJTERfRkVNQUxFX1RJVExFUyk7CisKKyAgaWYgKCFtYXBwaW5ncCh0aXRsZXMpIHx8ICFzaXplb2YodGl0bGVzKSkgcmV0dXJuIDA7CisKKyAgaW50IG1heGxldmVsID0gbWF4KG1faW5kaWNlcyh0aXRsZXMpKTsKKworICAvLyBMZXZlbCBiZWdyZW56ZW4uIE1heC1MZXZlbCBmdWVyIFNlaGVyLgorICBpZiAobGV2ID49IG1heGxldmVsKQorICAgIGxldiA9IElTX1NFRVIocGwpID8gbWF4bGV2ZWwgOiBtYXhsZXZlbC0xOworCisgIHJldHVybiB0aXRsZXNbbGV2XTsKK30KKworLy8gdmVyc3VjaHQgZGFzIFNwaWVsZXJsZXZlbCB6dSBlcmhvZWhlbi4gTWFjaHQgbmljaHQgZGVuIGdhbnplbiBLcmFtcworLy8gZHJ1bXJ1bSwgZGVuIGFkdmFuY2UoKSBhdXMgaHlzdGVyaXNjaGVuIEdydWVuZGVuIHR1dC4KK2ludCB0cnlfcGxheWVyX2FkdmFuY2Uob2JqZWN0IHBsKSB7CisKKyAgaWYgKFBMLT5RdWVyeVByb3AoUF9LSUxMUyk+MCkKKyAgICByZXR1cm4gLTE7CisKKyAgaW50IGxldmVsID0gcGwtPlF1ZXJ5UHJvcCggUF9MRVZFTCApOworICBpZiAobGV2ZWwgPT0gLTEpIGxldmVsID0gMDsKKworICBpZiAoTEVQTUFTVEVSLT5RdWVyeU5leHRMZXZlbExFUChsZXZlbCwgcGwtPlF1ZXJ5UHJvcChQX0xFUCkpID4gMCkKKyAgICAgIHJldHVybiAwOworICBlbHNlCisgICAgICArK2xldmVsOworCisgIHBsLT5TZXRQcm9wKCBQX0xFVkVMLCBsZXZlbCApOworCisgIC8vIEF1ZnN0aWVncy1FdmVudCBhdXNsb2VzZW4KKyAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoRVZUX0xJQl9BRFZBTkNFLCAoWworICAgICAgICBFX09CSkVDVDogUEwsIEVfUExOQU1FOiBnZXR1aWQoUEwpLAorICAgICAgICBFX0VOVklST05NRU5UOiBlbnZpcm9ubWVudChQTCksCisgICAgICAgIEVfR1VJTEROQU1FOiBQTC0+UXVlcnlQcm9wKFBfR1VJTEQpLAorICAgICAgICBQX0xFVkVMOiBQTC0+UXVlcnlQcm9wKFBfTEVWRUwpLAorICAgICAgICBdKSApOworCisgIC8vIEZhbGxzIGRpZSBrb25rcmV0ZSBHaWxkZSBkZXMgU3BpZWxlcm4gaXJnZWR3YXMgbWl0IGRlbSBUaXRlbCBpbgorICAvLyBBQmhhZW5naWdrZWl0IGRlcyBTcGllbGVybGV2ZWxzIHR1biB3aWxsLiBBdXNuYWhtc3dlaXNlIHBlciBjYWxsX290aGVyLAorICAvLyBkaWUgRnVua3Rpb24ga29tbXQgZWlnZW50bGljaCBhdXMgL3N0ZC9naWxkZW5fb2IuYy4KKyAgc3RyaW5nIGduYW1lPShzdHJpbmcpcGwtPlF1ZXJ5UHJvcChQX0dVSUxEKTsKKyAgKEdVSUxEX0RJUisiLyIrZ25hbWUpLT5hZGp1c3RfdGl0bGUocGwpOworCisgIHJldHVybiAxOworfQorCisvLyAiZXJob2VoZSItS29tbWFuZG8uCisvLyBlcmhvZWh0IGRhcyBTcGllbGVybGV2ZWwsIGZhbGxzIG1vZWdsaWNoLiBTZXR6dCBkZW4gcGFzc2VuZGVuCisvLyBBYmVudGV1cmVyZ2lsZGVudGl0ZWwuCitpbnQgYWR2YW5jZShzdHJpbmcgYXJnKQoreworCisgIGlmIChhcmcgJiYKKyAgICAgIGFyZyAhPSAic3R1ZmUiICYmIGFyZyAhPSAic3BpZWxlcnN0dWZlIiAmJiBhcmcgIT0gInNwaWVsZXIiCisgICAgICAmJiBhcmcgIT0gInNwaWVsZXJsZXZlbCIpCisgICAgcmV0dXJuIDA7CisKKyAgaW50IHJlcyA9IHRyeV9wbGF5ZXJfYWR2YW5jZShQTCk7CisKKyAgaWYgKCFyZXMpCisgICAgcmV0dXJuIGtvc3Rlbigia3VyeiIpOworICBlbHNlIGlmIChyZXMgPCAwKSB7CisgICAgbm90aWZ5X2ZhaWwoYnJlYWtfc3RyaW5nKAorICAgICAgICAiRHUgaGFzdCBlaW5lbiBNaXRzcGllbGVyIHVtZ2VicmFjaHQhXG4iKworICAgICAgICAiSW4gZGllc2VtIEZhbGwga2FubnN0IER1IERlaW5lIFN0dWZlIG5pY2h0IGVyaG9laGVuLlxuIisKKyAgICAgICAgIkJpdHRlIHdlbmRlIERpY2ggYW4gZGVuIFNoZXJpZmYgKG9kZXIgZWluZW4gRXJ6bWFnaWVyKSB1bmQgYnJpbmcgIgorICAgICAgICAiZGFzIGluIE9yZG51bmcuXG4iLDc4LEJTX0xFQVZFX01ZX0xGUykpOworICAgIHNheShicmVha19zdHJpbmcoUEwtPk5hbWUoV0VSKSAKKyAgICAgICAgICArICIgaGF0IHNvZWJlbiBhdWYgc2NobWVyemxpY2hlIFdlaXNlIGVyZmFocmVuIG11ZXNzZW4sIGRhc3MgIgorICAgICAgICAgICJlcyB3aXJrbGljaCBuaWNodCBmb2VyZGVybGljaCBpc3QsIE1pdHNwaWVsZXIgdW16dWJyaW5nZW4uXG4iLAorICAgICAgICAgIDc4KSwgUEwpOworICAgIHJldHVybiAwOworICB9CisKKyAgc3RyaW5nIG5hbWVfb2ZfcGxheWVyID0gUEwtPm5hbWUoV0VSKTsKKyAgaW50IGxldmVsID0gUEwtPlF1ZXJ5UHJvcChQX0xFVkVMKTsKKyAgc2F5KCBuYW1lX29mX3BsYXllciArICIgaGF0IGpldHp0IFN0dWZlICIgKyBsZXZlbCArICIgZXJyZWljaHQuXG4iKTsKKworICBzdHJpbmcgdGl0bGUgPSBQTC0+UXVlcnlQcm9wKFBfVElUTEUpOworCisgIHN3aXRjaChyYW5kb20oMykpIHsKKyAgICBjYXNlIDA6CisgICAgICB3cml0ZSgiRHUgYmlzdCBqZXR6dCAiICsgbmFtZV9vZl9wbGF5ZXIgKyAiICIgKyB0aXRsZSArCisgICAgICAgICIgKFN0dWZlICIgKyBsZXZlbCArICIpLlxuIik7CisgICAgICBicmVhazsKKworICAgIGNhc2UgMToKKyAgICAgIHdyaXRlKCJHdXQgZ2VtYWNodCwgIiArIG5hbWVfb2ZfcGxheWVyICsgIiAiICsgdGl0bGUgKworICAgICAgICAiIChTdHVmZSAiICsgbGV2ZWwgKyAiKS5cbiIpOworICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OgorICAgICAgd3JpdGUoIldpbGxrb21tZW4gYXVmIERlaW5lciBuZXVlbiBTdHVmZS5cbiIgKworICAgICAgICAiRHUgYmlzdCBqZXR6dCAiICsgbmFtZV9vZl9wbGF5ZXIrIiAiKyB0aXRsZSArCisgICAgICAgICIgKFN0dWZlICIgKyBsZXZlbCArICIpLlxuIik7CisgICAgICBicmVhazsKKyAgfQorCisgIHJldHVybiAxOworfQorCisvLyBTcGllbGVya29tbWFuZG8gZnVlciBBYmVudGV1cmVybGlzdGUKK3ZhcmFyZ3MgaW50IGxpc3RlKG1peGVkIHBsKQoreworICBzdHJpbmcgc3RyOyAKKyAgaWYgKCF0aGlzX3BsYXllcigpKSByZXR1cm4gMDsKKworICBpZighb2JqZWN0cChwbCkpCisgICAgaWYoc3RyaW5ncChwbCkpCisgICAgICBwbD1maW5kX3BsYXllcihwbCl8fGZpbmRfbmV0ZGVhZChwbCk7CisgIGlmKCFvYmplY3RwKHBsKSkKKyAgICBwbD1QTDsKKyAgaWYgKHBsICE9IHRoaXNfcGxheWVyKCkpIHsKKyAgICB3cml0ZSAoIkR1IGthbm5zdCBEaXIgbnVyIERlaW5lIGVpZ2VuZW4gQWJlbnRldWVyIGFuc2VoZW4uXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIHN0ciA9IFFNLT5saXN0ZShwbCk7CisKKyAgdGhpc19wbGF5ZXIoKS0+TW9yZSggc3RyLCAwICk7CisgIHJldHVybiAxOworfQorCitpbnQgR290b01hZ2llclRyZWZmKCkKK3sKKyAgaWYoSVNfTEVBUk5FUih0aGlzX3BsYXllcigpKSkKKyAgeworICAgIHdyaXRlKCJFaW4gWmF1YmVyc3BydWNoIHppZWh0IHZvciBEZWluZW0gZ2Vpc3RpZ2VuIEF1Z2Ugdm9yYmVpIHVuZCBEdVxuIgorICAgICJzcHJpY2hzdCBpaG4gbmFjaC5cbiIpOworICAgIHNheShQTC0+bmFtZSgpKyIgbXVybWVsdCBlaW5lbiBnZWhlaW1lbiBaYXViZXJzcHJ1Y2ggdW5kIHNjaHdlYnQgbGFuZ3NhbVxuIgorICAgICJ6dXIgRGVja2UgaGluYXVmIHVuZCB2ZXJzY2h3aW5kZXQgZHVyY2ggZGllIFdhbmQuXG4iKTsKKyAgICB3cml0ZSgiRHUgc2Nod2Vic3QgbGFuZ3NhbSB6dXIgRGVja2UgaGluYXVmIHVuZCBhbHMgb2IgZGllc2UgbmljaHQgZGFcbiIKKyAgICAid2FlcmUgbWl0dGVuIGhpbmR1cmNoIGluIGRlbiBNYWdpZXJ0cmVmZi5cbiIpOworICAgIHJldHVybiAoUEwtPm1vdmUoIi9zZWN1cmUvbWVybGluIiwgTV9UUE9SVCB8IE1fU0lMRU5UICkgPj0gMCk7CisgIH0KKyAgd3JpdGUoIkR1IHNwcmluZ3N0IHp1ciBEZWNrZSBoaW5hdWYgdW5kIG5peCBwYXNzaWVydC5cbiIpOworICByZXR1cm4gMTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2dpbGRlbl9vYi5jIGIvc3RkL2dpbGRlbl9vYi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjY4MDVhY2MKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvZ2lsZGVuX29iLmMKQEAgLTAsMCArMSw0NjIgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBnaWxkZW5fb2IuYyAtLSBCYXNpc2Z1bmt0aW9uZW4gZWluZXIgR2lsZGUKKy8vCisvLyAkSWQ6IGdpbGRlbl9vYi5jIDg0MzMgMjAxMy0wMi0yNCAxMzo0Nzo1OVogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIG5vX3NoYWRvdworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL3Jlc3RyaWN0aW9uX2NoZWNrZXIiOworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxhdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvZmFvLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisKK3ZvaWQgY3JlYXRlKCkgeworICAgIC8vIFBfR1VJTERfU0tJTExTIHNvbGx0ZSBuaWNodCBkaXJla3Qgdm9uIGF1c3NlbiBtYW5pcHVsaWVydCB3ZXJkZW4uLi4KKyAgICBTZXRQcm9wKFBfR1VJTERfU0tJTExTLChbXSkpOworICAgIFNldChQX0dVSUxEX1NLSUxMUyxQUk9URUNURUQsRl9NT0RFX0FTKTsKK30KKworbWFwcGluZyBfcXVlcnlfZ3VpbGRfc2tpbGxzKCkgeworICAgIC8vIGVpbmUgS29waWUgenVydWVja2xpZWZlcm4sIHVtIHZlcnNlaGVudGxpY2hlIEFlbmRlcnVuZ2VuIGRlcworICAgIC8vIE9yaWdpbmFsbWFwcGluZ3MgaW4gZGVyIEdpbGRlIHp1IHZlcm1laWRlbi4KKyAgICAvLyBEYXJmIG5pY2h0IG9obmUgd2VpdGVyZXMgZW50ZmVybnQgd2VyZGVuLCBkYSBlcyBoaWVyIGltIEZpbGUgQ29kZSBnaWJ0LAorICAgIC8vIGRlciBzaWNoIGF1ZiBkaWUgS29waWUgdmVybGFlc3N0LgorICAgIHJldHVybihkZWVwX2NvcHkoUXVlcnkoUF9HVUlMRF9TS0lMTFMpKSk7Cit9CisKK3N0cmluZyBHdWlsZE5hbWUoKSB7CisgIC8vR2lsZGVuIG11ZXNzZW4gQmx1ZXByaW50cyBzZWluLCBzby4gOy0pCisgIHJldHVybiBvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKVs4Li5dOworfQorCit2YXJhcmdzIGludAorSXNHdWlsZE1lbWJlcihvYmplY3QgcGwpIHsKKyAgc3RyaW5nIHBsZzsKKworICBpZiAoIXBsICYmICEocGw9dGhpc19wbGF5ZXIoKSkpCisgICAgcmV0dXJuIDA7CisgIGlmICghKHBsZz0oc3RyaW5nKXBsLT5RdWVyeVByb3AoUF9HVUlMRCkpKQorICAgIHJldHVybiAwOworICBpZiAoR3VpbGROYW1lKCkhPXBsZykgeworICAgIF9ub3RpZnlfZmFpbCgiRHUgZ2Vob2Vyc3QgZGllc2VyIEdpbGRlIG5pY2h0IGFuIVxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK2ludCBjaGVja19jb25kKG1peGVkIGNvbmQpIHsKKyAgc3RyaW5nIHJlczsKKworICBpZiAoaW50cChjb25kKSkgeworICAgIF9ub3RpZnlfZmFpbCgiRGlyIGZlaGx0IG5vY2ggZGllIG5vZXRpZ2UgRXJmYWhydW5nLiAiKworICAgICAgICAgICAgICAgICJLb21tIHNwYWV0ZXIgd2llZGVyLlxuIik7CisgICAgcmV0dXJuICh0aGlzX3BsYXllcigpLT5RdWVyeVByb3AoUF9YUCk+PWNvbmQpOworICB9CisgIGlmIChtYXBwaW5ncChjb25kKSkgeworICAgIHJlcz1jaGVja19yZXN0cmljdGlvbnModGhpc19wbGF5ZXIoKSxjb25kKTsKKyAgICBpZiAoIXN0cmluZ3AocmVzKSkgcmV0dXJuIDE7CisgICAgX25vdGlmeV9mYWlsKHJlcyk7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK2ludCBjYW5fYWR2YW5jZSgpIHsKKyAgaW50IGx2OworICBtYXBwaW5nIGx2czsKKworICBpZiAoIShsdj0oaW50KXRoaXNfcGxheWVyKCktPlF1ZXJ5UHJvcChQX0dVSUxEX0xFVkVMKSkpIHJldHVybiAxOworICBpZiAoIShsdnM9UXVlcnlQcm9wKFBfR1VJTERfTEVWRUxTKSkpIHJldHVybiAwOworICByZXR1cm4gY2hlY2tfY29uZChsdnNbbHYrMV0pOyAvLyBCZWRpbmd1bmcgZnVlciBuYWVjaHN0ZW4gTGV2ZWwgdGVzdGVuLgorfQorCit2b2lkIGFkanVzdF90aXRsZShvYmplY3QgcGwpIHsKKyAgaW50IGx2OworICBtaXhlZCB0aTsKKworCisgIGlmICghcGwgfHwKKyAgICAgICEobHY9KGludClwbC0+UXVlcnlQcm9wKFBfR1VJTERfTEVWRUwpKSkKKyAgICByZXR1cm47CisgIHN3aXRjaCgoaW50KXBsLT5RdWVyeVByb3AoUF9HRU5ERVIpKSB7CisgIGNhc2UgTUFMRToKKyAgICB0aT1RdWVyeVByb3AoUF9HVUlMRF9NQUxFX1RJVExFUyk7CisgICAgYnJlYWs7CisgIGNhc2UgRkVNQUxFOgorICAgIHRpPVF1ZXJ5UHJvcChQX0dVSUxEX0ZFTUFMRV9USVRMRVMpOworICAgIGJyZWFrOworICBkZWZhdWx0OgorICAgIHJldHVybjsKKyAgfQorICBpZiAobWFwcGluZ3AodGkpKQorICAgIHRpPXRpW2x2XTsKKyAgaWYgKHN0cmluZ3AodGkpKQorICAgIHBsLT5TZXRQcm9wKFBfR1VJTERfVElUTEUsdGkpOworICAKKyAgLy8gU3BpZWxlcnRpdGVsIG51bGxlbiwgZGFtaXQgZGVyIEdpbGRlbnRpdGVsIGFuZ2V6ZWlndCB3aXJkLgorICBpZiAoIUlTX1NFRVIocGwpICYmICFGQU9fSEFTX1RJVExFX0dJRlQocGwpKQorICAgICAgcGwtPlNldFByb3AoUF9USVRMRSwwKTsKK30KKwordm9pZCBkb19hZHZhbmNlKCkgeworICBpbnQgbHY7CisKKyAgbHY9dGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfR1VJTERfTEVWRUwpKzE7CisgIGlmIChsdjwxKSBsdj0xOworICB0aGlzX3BsYXllcigpLT5TZXRQcm9wKFBfR1VJTERfTEVWRUwsbHYpOworICBhZGp1c3RfdGl0bGUodGhpc19wbGF5ZXIoKSk7Cit9CisKK2ludCB0cnlfYWR2YW5jZSgpIHsKKyAgaWYgKGNhbl9hZHZhbmNlKCkpIHsKKyAgICBpZiAoSXNHdWlsZE1lbWJlcih0aGlzX3BsYXllcigpKSkKKyAgICAgIGRvX2FkdmFuY2UoKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworaW50IGJlaXRyZXRlbigpIHsKKyAgc3RyaW5nIHJlczsKKyAgaW50IGVyZzsKKworICBpZiAocmVzPWNoZWNrX3Jlc3RyaWN0aW9ucyh0aGlzX3BsYXllcigpLFF1ZXJ5UHJvcChQX0dVSUxEX1JFU1RSSUNUSU9OUykpKSB7CisgICAgLy8gV2VyZGVuIGRpZSBCZWl0cml0dHNiZWRpbmd1bmdlbiBlcmZ1ZWxsdD8KKyAgICBwcmludGYoIkR1IGthbm5zdCBkaWVzZXIgR2lsZGUgbmljaHQgYmVpdHJldGVuLlxuR3J1bmQ6ICVzIixyZXMpOworICAgIHJldHVybiAtMzsKKyAgfQorICBpZiAoZXJnPShpbnQpR1VJTERNQVNURVItPmJlaXRyZXRlbigpKSB7CisgICAgaWYgKGVyZzwwKQorICAgICAgcmV0dXJuIGVyZzsKKyAgICBpZiAoISh0aGlzX3BsYXllcigpLT5RdWVyeVByb3AoUF9HVUlMRF9MRVZFTCkpKQorICAgICAgdHJ5X2FkdmFuY2UoKTsgLy8gTGV2ZWwgMSB3aXJkIHNvZm9ydCB2ZXJnZWJlbgorICAgIHJldHVybiAxOworICB9CisgIHJldHVybiAwOworfQorCit2YXJhcmdzIGludCBhdXN0cmV0ZW4oaW50IGxvc3MpIHsKKyAgICByZXR1cm4gKGludClHVUlMRE1BU1RFUi0+YXVzdHJldGVuKGxvc3MpOworfQorCitpbnQgYmVpX29kZXJfYXVzX3RyZXRlbihzdHJpbmcgc3RyKSB7CisgIGlmICghc3RyKSByZXR1cm4gMDsKKyAgaWYgKHNpemVvZihyZWdleHAoKHtsb3dlcl9jYXNlKHN0cil9KSwKKyAgICAgICAgICAgICAgICAgICAgIlxcPGF1c1xcPi4qZ2lsZGVcXD4uKlxcPGF1c1xcPiIpKSkKKyAgICByZXR1cm4gYXVzdHJldGVuKCk7CisgIGlmIChzaXplb2YocmVnZXhwKCh7bG93ZXJfY2FzZShzdHIpfSksCisgICAgICAgICAgICAgICAgICAgICAiKGdpbGRlXFw+LipcXDxiZWlcXD58XFw8aW5cXD4uKmdpbGRlXFw+LipcXDxlaW5cXD4pIikpKQorICAgIHJldHVybiBiZWl0cmV0ZW4oKTsKKyAgcmV0dXJuIDA7Cit9CisKK3ZhcmFyZ3MgaW50CitBZGRTa2lsbChzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2tpKSB7CisgIG1hcHBpbmcgc2tpbGxzOworCisgIGlmICghc25hbWUpCisgICAgcmV0dXJuIDA7CisKKyAgLy8gcGVyIFF1ZXJ5KCkgYWJmcmFnZW4sIGhpZXIgaXN0IGtlaW5lIEtvcGllIG5vZXRpZy4KKyAgaWYgKCFtYXBwaW5ncChza2lsbHM9UXVlcnkoUF9HVUlMRF9TS0lMTFMpKSkgeworICAgIHNraWxscz0oW10pOworICAgIFNldFByb3AoUF9HVUlMRF9TS0lMTFMsc2tpbGxzKTsKKyAgfQorICAKKyAgaWYgKCFtYXBwaW5ncChza2kpKQorICAgICAgc2tpPShbXSk7CisgIGVsc2UKKyAgICAgIC8vWnVyIFNpY2hlcmhlaXQgS29waWUgZXJzdGVsbGVuLCB3ZXIgd2Vpc3MsIHdhcyBkZXIgRWludHJhZ2VuZGUgbm9jaAorICAgICAgLy9taXQgc2VpbmVtIE1hcHBpbmcgbWFjaHQuLi4KKyAgICAgIHNraT1kZWVwX2NvcHkoc2tpKTsKKworICBpZiAoIXN0cmluZ3Aoc2tpW1NJX1NLSUxMRlVOQ10pKQorICAgIC8vIFdlbm4ga2VpbmUgRnVua3Rpb24gYW5nZWdlYmVuIGlzdCwgRnVua3Rpb25zbmFtZT1Ta2lsbG5hbWUKKyAgICBza2lbU0lfU0tJTExGVU5DXT1zbmFtZTsKKworICAvLyBHaWxkZW4tT2Zmc2V0cyBhZGRpZXJlbgorICBza2k9QWRkU2tpbGxNYXBwaW5ncyhRdWVyeVByb3AoUF9HTE9CQUxfU0tJTExQUk9QUyksc2tpKTsKKworICAvLyBTa2lsbCBzZXR6ZW4uCisgIHNraWxsc1tzbmFtZV09c2tpOworICAvL1NldFByb3AoKSB1bm5vZXRpZywgZGEgb2JlbiBwZXIgUXVlcnkoKSBkYXMgT3JpZ2luYWxtYXBwaW5nIGVyaGFsdGVuCisgIC8vd3VyZGUuCisgIC8vU2V0UHJvcChQX0dVSUxEX1NLSUxMUyxza2lsbHMpOworICByZXR1cm4gMTsKK30KKworCit2YXJhcmdzIGludAorQWRkU3BlbGwoc3RyaW5nIHZlcmIsIG1hcHBpbmcgc2tpKSB7CisgIG1hcHBpbmcgc2tpbGxzOworCisgIGlmICghdmVyYikKKyAgICAgIHJldHVybiAwOworICBpZiAoIW1hcHBpbmdwKHNraSkpCisgICAgICBza2k9KFtdKTsKKworICBpZiAoIXN0cmluZ3Aoc2tpW1NJX1NQRUxMQk9PS10pICYmCisgICAgICAhc3RyaW5ncChza2lbU0lfU1BFTExCT09LXT1RdWVyeVByb3AoUF9HVUlMRF9ERUZBVUxUX1NQRUxMQk9PSykpKQorICAgIC8vIFdlbm4ga2VpbiBTcGVsbGJvb2sgYW5nZWdlYmVuIGlzdCBtdXNzIGVpbgorICAgIC8vIERlZmF1bHQtU3BlbGxib29rIGFuZ2VnZWJlbiBzZWluLCBzb25zdCBGZWhsZXIKKyAgICByZXR1cm4gMDsKKyAgaWYgKGZpbGVfc2l6ZShTUEVMTEJPT0tfRElSK3NraVtTSV9TUEVMTEJPT0tdKyIuYyIpPDApCisgICAgcmV0dXJuIDA7IC8vIFNwZWxsYm9vayBzb2xsdGUgYXVjaCBleGlzdGllcmVuLi4uCisKKyAgcmV0dXJuIEFkZFNraWxsKGxvd2VyX2Nhc2UodmVyYiksc2tpKTsKK30KKworbWFwcGluZyBRdWVyeVNraWxsKHN0cmluZyBza2lsbCkgeworICBtYXBwaW5nIHNraTsKKworICAvLyBBYmZyYWdlIHBlciBRdWVyeSgpLCBkYSB2aWVsbGVpY2h0IG51ciBlaW4gU2tpbGwgZ2V3dWVuc2NodAorICAvLyB3aXJkIHVuZCBkYWhlciBkaWUga29tcGxldHRlIEtvcGllIGRlcyBTcGVsbG1hcHBpbmdzIGluIGRlciBRdWVyeS1NZXRob2RlCisgIC8vIHVubm9ldGlnIGlzdC4KKyAgaWYgKCFza2lsbAorICAgICAgfHwgIShza2k9UXVlcnkoUF9HVUlMRF9TS0lMTFMsIEZfVkFMVUUpKQorICAgICAgfHwgIShza2k9c2tpW3NraWxsXSkpIC8vIEdpbGRlbnNwZXppZmlzY2hlIFNraWxsZWlnZW5zY2hhZnRlbgorICAgIHJldHVybiAwOworICAvLyBoaWVyIGFiZXIgZGFubiBuYXR1ZXJsaWNoIGVpbmUgS29waWUgZXJzdGVsbGVuLiA7LSkKKyAgcmV0dXJuKGRlZXBfY29weShza2kpKTsKK30KKworbWFwcGluZyBRdWVyeVNwZWxsKHN0cmluZyBzcGVsbCkgeworICBtYXBwaW5nIHNraSxza2kyOworICBzdHJpbmcgc3BlbGxib29rLHNmdW5jOworCisgIC8vIFF1ZXJ5U2tpbGwoKSBoaWVyIHVuZCBRdWVyeVNwZWxsKCkgaW0gU3BlbGxib29rIGxpZWZlcm4gS29waWVuIGRlcgorICAvLyBTa2lsbG1hcHBpbmdzIHp1cnVlY2ssIEtvcGllcmVuIGhpZXIgZGFoZXIgdW5ub2V0aWcuCisgIGlmICghc3BlbGwKKyAgICAgIHx8ICEoc2tpPVF1ZXJ5U2tpbGwoc3BlbGwpKQorICAgICAgfHwgIShzcGVsbGJvb2s9c2tpW1NJX1NQRUxMQk9PS10pKQorICAgIHJldHVybiAwOworICBpZiAoIShzZnVuYz1za2lbU0lfU0tJTExGVU5DXSkpCisgICAgc2Z1bmM9c3BlbGw7CisgIHNwZWxsYm9vaz1TUEVMTEJPT0tfRElSK3NwZWxsYm9vazsKKyAgaWYgKCEoc2tpMj0obWFwcGluZykoc3BlbGxib29rLT5RdWVyeVNwZWxsKHNmdW5jKSkpKQorICAgIHJldHVybiAwOworICByZXR1cm4gQWRkU2tpbGxNYXBwaW5ncyhza2kyLHNraSk7IC8vIFJlaWhlbmZvbGdlIHdpY2h0aWchCisgIC8vIERpZSBHaWxkZSBrYW5uIFNwZWxsZWlnZW5zY2hhZnRlbiBuZXUgZGVmaW5pZXJlbiEKK30KKwordmFyYXJncyBpbnQKK1VzZVNwZWxsKG9iamVjdCBjYXN0ZXIsIHN0cmluZyBzcGVsbCwgbWFwcGluZyBzaW5mbykgeworICBtYXBwaW5nIHNraTsKKyAgc3RyaW5nIHNwZWxsYm9vazsKKworICBpZiAoIWNhc3RlcgorICAgICAgfHwgIXNwZWxsCisgICAgICB8fCAhKHNraT1RdWVyeVNraWxsKHNwZWxsKSkgLy8gRXhpc3RpZXJ0IGRpZXNlciBTcGVsbCBpbiBkaWVzZXIgR2lsZGU/CisgICAgICB8fCAhKHNwZWxsYm9vaz1za2lbU0lfU1BFTExCT09LXSkpIC8vIFNwZWxsYm9vayBtdXNzIGJla2FubnQgc2VpbgorICAgIHJldHVybiAwOworICBpZiAoc2luZm8pCisgICAgc2tpKz1zaW5mbzsKKyAgc3BlbGxib29rPVNQRUxMQk9PS19ESVIrc3BlbGxib29rOworICAvLyBwcmludGYoIiVPICVPICVPICVPXG4iLHNwZWxsYm9vayxjYXN0ZXIsc3BlbGwsc2tpKTsKKyAgcmV0dXJuIChpbnQpc3BlbGxib29rLT5Vc2VTcGVsbChjYXN0ZXIsc3BlbGwsc2tpKTsKK30KKworc3RhdGljIGludAorSW5pdGlhbFNraWxsQWJpbGl0eShtYXBwaW5nIHNraSwgb2JqZWN0IHBsKSB7CisgIGlmICghc2tpIHx8ICFwbCkgcmV0dXJuIDA7CisgIHJldHVybiAoMzAwKkdldE9mZnNldChTSV9TS0lMTExFQVJOLHNraSxwbCkrCisgICAgICAgICAgKDIwMCooaW50KXBsLT5RdWVyeUF0dHJpYnV0ZShBX0lOVCkqCisgICAgICAgICAgIEdldEZhY3RvcihTSV9TS0lMTExFQVJOLHNraSxwbCkpLzEwMCk7Cit9CisKK2ludAorU2tpbGxMaXN0ZShpbnQgd2hhdCkgeworICBpbnQgcmVzOworICAvLyBRdWVyeW1ldGhvZGUgZXJzdGVsbHQgS29waWUgKHdpY2h0aWchKQorICBtYXBwaW5nIGFsbHNraWxscz1RdWVyeVByb3AoUF9HVUlMRF9TS0lMTFMpOworICBzdHJpbmcgKnNraWxscz0oe30pOworICBzdHJpbmcgKnNwZWxscz0oe30pOworCisgIGlmICghbWFwcGluZ3AoYWxsc2tpbGxzKSB8fCAhc2l6ZW9mKGFsbHNraWxscykpCisgICAgcmV0dXJuIDA7CisKKyAgZm9yZWFjaChzdHJpbmcgcywgbWFwcGluZyBzZGF0YTogJmFsbHNraWxscykgeworICAgIC8vIExlcm5sZXZlbCBlcm1pdHRlbG4gdW5kIHNwZWljaGVybi4KKyAgICBtYXBwaW5nIHRtcD1RdWVyeVNwZWxsKHMpOworICAgIC8vIHdlbm4gbml4IGdlZnVuZGVuLCBkYW5uIGlzdCBlcyBlaW4gU2tpbGwsIHNvbnN0IGVpbiBTcGVsbC4KKyAgICBpZiAodG1wKSB7CisgICAgICBzcGVsbHMgKz0gKHtzfSk7CisgICAgICAvLyBkYXMgU3BlbGxib29rIGhhdCBpbSBad2VpZmVsIGRhcyBTSV9TS0lMTElORk8KKyAgICAgIHNkYXRhW1NJX1NLSUxMSU5GT10gPSB0bXBbU0lfU0tJTExJTkZPXTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAvLyBTSV9TS0lMTElORk8gc3RlaHQgaW4gZGllc2VtIEZhbGwgc2Nob24gaW4gc2RhdGEuLi4KKyAgICAgIHRtcCA9IFF1ZXJ5U2tpbGwocyk7CisgICAgICBza2lsbHMgKz0gKHtzfSk7CisgICAgfQorICAgIC8vIGd1Y2tlbiwgb2JzIG5lbiBMZXJubGV2ZWwgZ2lidCB1bmQgZWluZmFjaCBpbiBzZGF0YSBzY2hyZWliZW4KKyAgICBpZiAoICh0bXA9dG1wW1NJX1NLSUxMUkVTVFJfTEVBUk5dKSApCisgICAgICBzZGF0YVsiX3Jlc3RyX2xldmVsIl0gPSB0bXBbUF9MRVZFTF07CisgIH0KKworICAvLyBqZXR6dCBzb3J0aWVyZW4uCisgIGNsb3N1cmUgY2wgPSBmdW5jdGlvbiBpbnQgKHN0cmluZyBhLCBzdHJpbmcgYikKKyAgICB7IHJldHVybiBhbGxza2lsbHNbYV1bIl9yZXN0cl9sZXZlbCJdID4gYWxsc2tpbGxzW2JdWyJfcmVzdHJfbGV2ZWwiXTsgfTsKKyAgaWYgKHdoYXQgJiAweDAxKQorICAgIHNwZWxscyA9IHNvcnRfYXJyYXkoc3BlbGxzLCBjbCk7CisgIGlmICh3aGF0ICYgMHgwMikKKyAgICBza2lsbHMgPSBzb3J0X2FycmF5KHNraWxscywgY2wpOworCisgIC8vIHVuZCBhdXNnZWJlbgorICBjbCA9IGZ1bmN0aW9uIHZvaWQgKHN0cmluZyAqbGlzdCkKKyAgICB7CisgICAgICBzdHJpbmcgdG1wPSIiOworICAgICAgaW50IGx2bDsKKyAgICAgIGZvcmVhY2goc3RyaW5nIHNwOiBsaXN0KSB7CisgICAgICAgIGx2bCA9IGFsbHNraWxsc1tzcF1bIl9yZXN0cl9sZXZlbCJdOworICAgICAgICBpZiAobHZsPjApCisgICAgICAgICAgdG1wICs9IHNwcmludGYoIiUtMjBzICVkXG4iLHNwLGx2bCk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICB0bXAgKz0gc3ByaW50ZigiJS0yMHNcbiIsc3ApOworICAgICAgICBpZiAoYWxsc2tpbGxzW3NwXVtTSV9TS0lMTElORk9dKQorICAgICAgICAgIHRtcCArPSBicmVha19zdHJpbmcoYWxsc2tpbGxzW3NwXVtTSV9TS0lMTElORk9dLCA3OCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgIik7CisgICAgICB9CisgICAgICB0ZWxsX29iamVjdChQTCwgdG1wKTsKKyAgICB9OworCisgIGlmICgod2hhdCAmIDB4MDEpICYmIHNpemVvZihzcGVsbHMpKSB7CisgICAgcmVzID0gMTsKKyAgICB0ZWxsX29iamVjdChQTCxzcHJpbnRmKAorICAgICAgICAiRHUga2FubnN0IHZlcnN1Y2hlbiwgZm9sZ2VuZGUgWmF1YmVyc3BydWVjaGUgenUgbGVybmVuOlxuIgorICAgICAgICAiJS0yMHMgJS0zc1xuIiwiWmF1YmVyc3BydWNoIiwiU3BpZWxlcnN0dWZlIikpOworICAgIGZ1bmNhbGwoY2wsIHNwZWxscyk7CisgICAgdGVsbF9vYmplY3QoUEwsYnJlYWtfc3RyaW5nKAorICAgICAgICJEdSBrYW5uc3QgZWluZW4gWmF1YmVyc3BydWNoIG1pdCBkZW0gS29tbWFuZG8gXCJsZXJuZVwiLCBnZWZvbGd0ICIKKyAgICAgICAidm9tIFphdWJlcnNwcnVjaG5hbWVuIGxlcm5lbi4iLDc4KSk7CisgIH0KKyAgaWYgKCh3aGF0ICYgMHgwMikgJiYgc2l6ZW9mKHNraWxscykpIHsKKyAgICByZXMgPSAxOworICAgIHRlbGxfb2JqZWN0KFBMLHNwcmludGYoCisgICAgICAgICJEdSBrYW5uc3QgdmVyc3VjaGVuLCBmb2xnZW5kZSBGYWVoaWdrZWl0ZW4genUgZXJ3ZXJiZW46XG4iCisgICAgICAgICIlLTIwcyAlLTNzXG4iLCJGYWVoaWdrZWl0IiwiU3BpZWxlcnN0dWZlIikpOworICAgIGZ1bmNhbGwoY2wsIHNraWxscyk7CisgIH0KKworICByZXR1cm4gcmVzOworfQorCit2YXJhcmdzIGludAorTGVhcm5TcGVsbChzdHJpbmcgc3BlbGwsb2JqZWN0IHBsKSB7CisgIG1hcHBpbmcgc2tpLHJlc3RyOworICBzdHJpbmcgcmVzOworICBtaXhlZCBsZWFybl9pbml0ZnVuYzsKKyAgaW50IGFiaWwsZGlmZjsKKworICAvLyBXZW5uIGtlaW4gcGwgZ2VzZXR6dCBpc3QsIG5laG1lbiB3aXIgdGhpc19wbGF5ZXIoKSwgZGFzIGlzdCBkZXIKKyAgLy8gTm9ybWFsZmFsbC4KKyAgaWYgKCFwbCkKKwkgIHBsPXRoaXNfcGxheWVyKCk7CisgIGlmICghSXNHdWlsZE1lbWJlcihwbCkpIHsKKyAgICBfbm90aWZ5X2ZhaWwoIkR1IGdlaG9lcnN0IGRpZXNlciBHaWxkZSBuaWNodCBhbiFcbiIpOworICAgIHJldHVybiAwOworICB9CisgIF9ub3RpZnlfZmFpbCgiV2FzIG1vZWNodGVzdCBEdSBsZXJuZW4/XG4iKTsKKyAgaWYgKCFzcGVsbCkKKyAgICByZXR1cm4gU2tpbGxMaXN0ZSgweDAxKTsKKyAgc3BlbGw9bG93ZXJfY2FzZShzcGVsbCk7CisgIGlmICghKHNraT1RdWVyeVNwZWxsKHNwZWxsKSkpCisgICAgcmV0dXJuIDA7CisgIGlmIChwbC0+UXVlcnlTa2lsbChzcGVsbCkpIHsKKyAgICBfbm90aWZ5X2ZhaWwoIkR1IGthbm5zdCBkaWVzZW4gU3BydWNoIGRvY2ggc2Nob24hXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBpZiAoKHJlc3RyPXNraVtTSV9TS0lMTFJFU1RSX0xFQVJOXSkKKyAgICAgICYmIChyZXM9Y2hlY2tfcmVzdHJpY3Rpb25zKHBsLHJlc3RyKSkpIHsKKyAgICBwcmludGYoIkR1IGthbm5zdCBkaWVzZW4gU3BydWNoIG5vY2ggbmljaHQgbGVybmVuLlxuR3J1bmQ6ICVzIixyZXMpOworICAgIHJldHVybiAxOworICB9CisgIGFiaWw9SW5pdGlhbFNraWxsQWJpbGl0eShza2kscGwpOworICBpZiAoYWJpbDwxKSBhYmlsPTE7CisgIGlmIChhYmlsPjc1MDApIGFiaWw9NzUwMDsKKyAgd3JpdGUoIkR1IGxlcm5zdCBlaW5lbiBuZXVlbiBaYXViZXJzcHJ1Y2guXG4iKTsKKyAgaWYgKCEoZGlmZj1HZXRGVmFsdWVPKFNJX0RJRkZJQ1VMVFksc2tpLHBsKSkpCisgICAgZGlmZj1HZXRGVmFsdWVPKFNJX1NQRUxMQ09TVCxza2kscGwpOworICBwbC0+TW9kaWZ5U2tpbGwoc3BlbGwsYWJpbCxkaWZmKTsKKyAgcmV0dXJuIDE7Cit9CisKK2ludAorTGVhcm5Ta2lsbChzdHJpbmcgc2tpbGwpIHsKKyAgbWFwcGluZyBza2kscmVzdHI7CisgIG9iamVjdCBwbDsKKyAgc3RyaW5nIHJlczsKKyAgbWl4ZWQgbGVhcm5faW5pdGZ1bmM7CisgIGludCBhYmlsLGRpZmY7CisKKyAgaWYgKCFJc0d1aWxkTWVtYmVyKHBsPXRoaXNfcGxheWVyKCkpKSB7CisgICAgX25vdGlmeV9mYWlsKCJEdSBnZWhvZXJzdCBkaWVzZXIgR2lsZGUgbmljaHQgYW4hXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBfbm90aWZ5X2ZhaWwoIldhcyBtb2VjaHRlc3QgRHUgbGVybmVuP1xuIik7CisgIGlmICghc2tpbGwpCisgICAgcmV0dXJuIFNraWxsTGlzdGUoMHgwMik7CisgIHNraWxsPWNhcGl0YWxpemUoc2tpbGwpOworICBpZiAoIShza2k9UXVlcnlTa2lsbChza2lsbCkpKQorICAgIHJldHVybiAwOworICBpZiAocGwtPlF1ZXJ5U2tpbGwoc2tpbGwpKSB7CisgICAgX25vdGlmeV9mYWlsKCJEdSBoYXN0IGRpZXNlIEZhZWhpZ2tlaXQgZG9jaCBzY2hvbiFcbiIpOworICAgIHJldHVybiAwOworICB9CisgIGlmICgocmVzdHI9c2tpW1NJX1NLSUxMUkVTVFJfTEVBUk5dKQorICAgICAgJiYgKHJlcz1jaGVja19yZXN0cmljdGlvbnMocGwscmVzdHIpKSkgeworICAgIHByaW50ZigiRHUga2FubnN0IGRpZXNlIEZhZWhpZ2tlaXQgbm9jaCBuaWNodCBlcndlcmJlbi5cbkdydW5kOiAlcyIscmVzKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBhYmlsPUluaXRpYWxTa2lsbEFiaWxpdHkoc2tpLHBsKTsKKyAgaWYgKCFhYmlsKSBhYmlsPTE7CisgIGlmIChhYmlsPk1BWF9BQklMSVRZKSBhYmlsPU1BWF9BQklMSVRZOworICBpZiAoYWJpbDwtTUFYX0FCSUxJVFkpIGFiaWw9LU1BWF9BQklMSVRZOworICB3cml0ZSgiRHUgZXJ3aXJic3QgZWluZSBuZXVlIEZhZWhpZ2tlaXQuXG4iKTsKKyAgZGlmZj1HZXRGVmFsdWVPKFNJX0RJRkZJQ1VMVFksc2tpLHBsKTsKKyAgcGwtPk1vZGlmeVNraWxsKHNraWxsLGFiaWwsZGlmZik7CisgIHJldHVybiAxOworfQorCitpbnQgR3VpbGRSYXRpbmcob2JqZWN0IHBsKQoreworICBtYXBwaW5nIHNraTsKKyAgc3RyaW5nICpzazsKKyAgaW50IGksIGNudCwgc3VtOworICBjbG9zdXJlIHFzYTsKKyAgCisgIGlmICghSXNHdWlsZE1lbWJlcihwbCl8fCFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHBsKSkKKyAgICByZXR1cm4gMDsKKworICBpZiAoIShza2kgPSBRdWVyeVByb3AoUF9HVUlMRF9TS0lMTFMpKSB8fAorICAgICAgIShxc2EgPSBzeW1ib2xfZnVuY3Rpb24oIlF1ZXJ5U2tpbGxBYmlsaXR5IixwbCkpKQorICAgIHJldHVybiAwOworCisgIHNrID0gbV9pbmRpY2VzKHNraSk7CisgIGNudCA9IHNpemVvZihza2kpOworICAKKyAgZm9yIChpPWNudC0xLCBzdW09MDsgaT49MDsgaS0tKQorICAgIHN1bSArPSBmdW5jYWxsKHFzYSwgc2tbaV0pOworCisgIHN1bSA9IHN1bS9jbnQ7CisgIGlmIChzdW0gPCAwKQorICAgIHN1bSA9IDA7CisgIGVsc2UgaWYgKHN1bSA+IE1BWF9BQklMSVRZKQorICAgIHN1bSA9IE1BWF9BQklMSVRZOworICAKKyAgcmV0dXJuIChpbnQpcGwtPlNldFByb3AoUF9HVUlMRF9SQVRJTkcsIHN1bSk7Cit9CisKKy8vIFdpcmQgdm9uIC9zdGQvcGxheWVyL3F1ZXN0LmMgYXVmZ2VydWZlbiwgd2VubiBRdWVzdCBnZWxvZXN0LgorLy8gKEplZGVzIG1hbCAtIG5pY2h0IG51ciBiZWltIGVyc3RlbiBtYWwuKQorLy8gSXN0IHp1bSBzZWxic3QtdWViZXJzY2hyZWliZW4gZ2VkYWNodCwgc29sbHRlIGFiZXIgZGVmaW5pZXJ0IHNlaW4uCit2b2lkIE5vdGlmeUdpdmVRdWVzdChvYmplY3QgcGwsIHN0cmluZyBrZXkpeyAgfQorCmRpZmYgLS1naXQgYS9zdGQvZ2lsZGVuX3Jvb20uYyBiL3N0ZC9naWxkZW5fcm9vbS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjc2M2RlNTkKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvZ2lsZGVuX3Jvb20uYwpAQCAtMCwwICsxLDMzIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gZ2lsZGVuX3Jvb20uYyAtLSBHaWxkZW5nZWJhZXVkZQorLy8KKy8vICRJZDogZ2lsZGVuX3Jvb20uYyA2MzgwIDIwMDctMDctMjAgMjI6MzI6MzhaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisvLyAjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworaW5oZXJpdCAiL3N0ZC9naWxkZSI7Citpbmhlcml0ICIvc3RkL2dpbGRlbl9vYiI7CisKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8YXR0cmlidXRlcy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKwordm9pZCBjcmVhdGUoKSB7CisgIGdpbGRlOjpjcmVhdGUoKTsKKyAgZ2lsZGVuX29iOjpjcmVhdGUoKTsKKyAgQWRkQ21kKCh7InRyaXR0IiwidHJldGUifSksImJlaV9vZGVyX2F1c190cmV0ZW4iKTsKKyAgQWRkQ21kKCh7Imxlcm4iLCJsZXJuZSJ9KSwiTGVhcm5TcGVsbCIpOworfQorCitpbnQgYWR2YW5jZShzdHJpbmcgYXJnKSB7CisgIGludCByMSxyMjsKKworICByMT1naWxkZTo6YWR2YW5jZShhcmcpOworICByMj1naWxkZW5fb2I6OnRyeV9hZHZhbmNlKCk7CisgIHJldHVybiAocjF8fHIyKTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9ob29rX2NvbnN1bWVyLmMgYi9zdGQvaG9va19jb25zdW1lci5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFkYTAzYjMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvaG9va19jb25zdW1lci5jCkBAIC0wLDAgKzEsMTkgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWINCisvLw0KKy8vIC9zdGQvaG9va19jb25zdW1lci5jICAtIHVzZWQgdG8gY29udGFpbiBzb21lIHRlbXBsYXRlIGZvciBob29rIGNvbnN1bWVycywNCisvLyAgICAgICAgICAgICAgICAgICAgICAgICBub3QgbmVlZGVkIGFueW1vcmUuDQorLy8NCisNCisjcHJhZ21hIHN0cm9uZ190eXBlcw0KKyNwcmFnbWEgc2F2ZV90eXBlcw0KKyNwcmFnbWEgbm9fY2xvbmUNCisjcHJhZ21hIHBlZGFudGljDQorI3ByYWdtYSByYW5nZV9jaGVjaw0KKw0KKyNpbmNsdWRlIDxob29rLmg+DQorDQorZGVwcmVjYXRlZCBtaXhlZCBIb29rQ2FsbGJhY2sob2JqZWN0IGhvb2tTb3VyY2UsIGludCBob29raWQsIG1peGVkIGhvb2tEYXRhKQ0KK3sNCisgIHJldHVybiAoe0hfTk9fTU9ELGhvb2tEYXRhfSk7DQorfQ0KKw0KZGlmZiAtLWdpdCBhL3N0ZC9ob29rX3Byb3ZpZGVyLmMgYi9zdGQvaG9va19wcm92aWRlci5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAwYjhjYTMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvaG9va19wcm92aWRlci5jCkBAIC0wLDAgKzEsNDkzIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gL3N0ZC9ob29rX3Byb3ZpZGVyLmMgIC0gSG9va3N5c3RlbQorLy8KKy8vICRJZDogaG9va19wcm92aWRlci5jIDk0NTMgMjAxNi0wMi0wNCAyMToyMjo1NFogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxob29rLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKy8vIGdldCB0aGUgb2JqZWN0IGZ1ciBjbG9zdXJlIDxjbD4gKHdoZXJlIHRoZSBjb2RlIGlzISkKKyNkZWZpbmUgR0VUX09CSkVDVChjbCkgZ2V0X3R5cGVfaW5mbyhjbCwyKQorCisvLyBTdHJ1Y3QgZGVzY3JpYmluZyBvbmUgaG9vayBjb25zdW1lci4gPGNsPiB3aWxsIGJlIGNhbGxlZCB3aGVuIHRoZSBob29rIGlzCisvLyB0cmlnZ2VyZWQuIFRoZSBsb3dlciA8cHJpbz4sIHRoZSBlYXJsaWVyIHRoZSBjb25zdW1lciB3aWxsIGJlIGNhbGxlZC4KKy8vIDx0eXBlPiBpcyBhIGNvbnN1bWVydHlwZSwgZS5nLiBzdXJ2ZXlvciwgbGlzdGVuZXIgZXRjLiAoc2VlIGhvb2suaCkKK3N0cnVjdCBob29rX2VudHJ5X3MgeworICBjbG9zdXJlIGNsOworICBpbnQgcHJpbzsKKyAgaW50IGVuZHRpbWU7CisgIGludCB0eXBlOworfTsKKworLy8gU3RydWN0IGhvbGRpbmcgdGhlIGNvbnN1bWVycyBvZiBvbmUgc3BlY2lmaWMgaG9vay4KKy8vIHRoZSB2YWx1ZSBhcnJheXMgYXJlIGd1YXJlbnRlZWQgdG8gZXhpc3QsIGJ1dCBtYXkgYmUgZW1wdHkuCitzdHJ1Y3QgaG9va19zIHsKKyAgc3RydWN0IGhvb2tfZW50cnlfcyAqc3VydmV5b3JzOworICBzdHJ1Y3QgaG9va19lbnRyeV9zICpobW9kczsKKyAgc3RydWN0IGhvb2tfZW50cnlfcyAqZG1vZHM7CisgIHN0cnVjdCBob29rX2VudHJ5X3MgKmxpc3RlbmVyczsKK307CisKKy8qIGhvb2sgbWFwcGluZworICAgdGhlIGxpc3Qgb2YgYWxsIG9mZmVyZWQgaG9va3MgaW4gdGhlIGZvbGxvd2luZyBzdHJ1Y3R1cmU6CisgICAoW2hvb2tpZDogKDxob29rX3M+KSwgLi4uCisgICApXQorKi8KK3ByaXZhdGUgbm9zYXZlIG1hcHBpbmcgaG9va01hcHBpbmc9KFtdKTsKKworcHJvdGVjdGVkIHZvaWQgQ2xlYW5Ib29rTWFwcGluZyhpbnQgKmhvb2tpZHMpOworCisvLyBEZWJ1Z2dpbmcgLSBnZ2YuIHVlYmVyc2NocmVpYmVuCitwcm90ZWN0ZWQgaW50IGhfZGJnKCkge3JldHVybiAwO30KKwordm9pZCBIb29rVGVzdE9mZmVyKGludCBpZCwgaW50IHN0YXQpeworICBpZihoX2RiZygpKSB7CisgICAgICBvZmZlckhvb2soaWQsc3RhdCk7CisgIH0KK30KKwordm9pZCBIb29rVGVzdFRyaWdnZXIoaW50IGlkLCBtaXhlZCBkYXRhKXsKKyAgaWYoaF9kYmcoKSkgeworICAgICAgSG9va0Zsb3coaWQsZGF0YSk7CisgIH0KK30KKworLy8gTk9URTogaWYgeW91IGhhdmUgdGhlIGNsb3N1cmUsIHlvdSBjYW4gY2FsbCB0aGUgbGZ1biwgZXZlbiBpZiBpdCBpcworLy8gcHJpdmF0ZS4gVGhlcmVmb3JlIGFjY2VzcyB0byB0aGlzIGRhdGEgc2hvdWxkIGJlIHJlc3RyaWN0ZWQgdG8KKy8vIHRoaXNfb2JqZWN0KCkuCisvLyBUaGVzZSB0d28gZnVuY3Rpb25zIHNob3VsZCBiZSB1c2VkIGZvciBkZWJ1Z2dpbmcgcHVycG9zZXMuCitwcm90ZWN0ZWQgbWFwcGluZyBIQ29weUhvb2tNYXBwaW5nKCl7CisgIHJldHVybiBkZWVwX2NvcHkoaG9va01hcHBpbmcpOworfQorCitwcm90ZWN0ZWQgbWFwcGluZyBIQ29weUhvb2tDb25zdW1lcnMoaW50IGhvb2tpZCl7CisgIGlmKG1lbWJlcihob29rTWFwcGluZyxob29raWQpKSB7CisgICAgICBDbGVhbkhvb2tNYXBwaW5nKCh7aG9va2lkfSkpOworICAgICAgcmV0dXJuIGRlZXBfY29weShob29rTWFwcGluZ1tob29raWRdKTsKKyAgfQorICByZXR1cm4gMDsKK30KKworLy8gR2dmLiB6dW0gVWViZXJzY2hyZWliZW4uCitpbnQgSENvbnN1bWVyVHlwZUlzQWxsb3dlZChpbnQgdHlwZSwgb2JqZWN0IGNvbnN1bWVyKXsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBIUHJpb3JpdHlJc0FsbG93ZWQoaW50IHByaW8sIG9iamVjdCBjb25zdW1lcil7CisgIHJldHVybiAxOworfQorCisvLyBjbGVhbiBpbnRlcm5hbCBob29rIGRhdGEgc3RydWN0dXJlcyBvZiBzdGFsZSBob29rIGNvbnN1bWVycy4KK3Byb3RlY3RlZCB2b2lkIENsZWFuSG9va01hcHBpbmcoaW50ICpob29raWRzKXsKKyAgLy8gaG9va3MgZW50aGFlbHQgZGllIGF1Znp1cmFldW1lbmRlbiBIb29rcy4gV2VubiBrZWluIEFycmF5IC0+IGFsbGUgSG9va3MKKyAgaWYgKCFwb2ludGVycChob29raWRzKSkKKyAgICBob29raWRzPW1faW5kaWNlcyhob29rTWFwcGluZyk7CisKKyAgZm9yZWFjaChpbnQgaG9va2lkIDogaG9va2lkcykgeyAvLyBhbGxlIEhvb2tzCisgICAgc3RydWN0IGhvb2tfcyBob29rcyA9IGhvb2tNYXBwaW5nW2hvb2tpZF07CisgICAgaWYgKCFzdHJ1Y3RwKGhvb2tzKSkKKyAgICAgIGNvbnRpbnVlOworICAgIC8vIHVlYmVyIGFsbGUgQ29uc3VtZXJ0eXBlbiBsYXVmZW4KKyAgICBmb3JlYWNoIChzdHJpbmcgY29uc3VtZXJ0eXBlOiBIX0NPTlNVTUVSTkFNRVMpCisgICAgeworICAgICAgLy8gWWVhaCAtIGNvbXB1dGUgc3RydWN0IGxvb2t1cCBhdCBydW50aW1lLi4uIDstKQorICAgICAgc3RydWN0IGhvb2tfZW50cnlfcyAqY29uc3VtZXJzID0gaG9va3MtPihjb25zdW1lcnR5cGUpOworICAgICAgLy8gSG9va2VpbnRyYWVnZSAvIENvbnN1bWVyCisgICAgICBmb3JlYWNoKHN0cnVjdCBob29rX2VudHJ5X3MgaCA6ICZjb25zdW1lcnMpIHsKKyAgICAgICAgLy8gYWxsZSBhYmdlbGF1ZmVuZW4gRWludHJhZWdlIG9kZXIgc29sY2hlIG1pdCB6ZXJzdG9lcnRlbiBPYmpla3RlbgorICAgICAgICAvLyBudWxsZW4KKyAgICAgICAgaWYgKCFoLT5jbCB8fCBoLT5lbmR0aW1lIDwgdGltZSgpICkKKyAgICAgICAgICAgIGggPSAwOworICAgICAgfQorICAgICAgLy8gMCBub2NoIHJhdXN3ZXJmZW4uCisgICAgICBob29rcy0+KGNvbnN1bWVydHlwZSkgLT0gKHswfSk7CisgICAgfQorICB9Cit9CisKK3Byb3RlY3RlZCB2b2lkIG9mZmVySG9vayhpbnQgaG9va2lkLCBpbnQgb2ZmZXJzdGF0ZSkKK3sKKyAgSF9ETVNHKHNwcmludGYoIm9mZmVySG9vayBob29raWQgJWQgb2ZmZXJzdGF0ZSAlZFxuIixob29raWQsb2ZmZXJzdGF0ZSkpOworICBpZiAoaG9va2lkPjApCisgIHsKKyAgICAgIGlmIChvZmZlcnN0YXRlKSB7CisgICAgICAgICAgaWYgKCFtZW1iZXIoaG9va01hcHBpbmcsaG9va2lkKSkgeworICAgICAgICAgICAgICBzdHJ1Y3QgaG9va19zIGhvb2sgPSAoPGhvb2tfcz4KKyAgICAgICAgICAgICAgICAgIHN1cnZleW9yczogKHt9KSwKKyAgICAgICAgICAgICAgICAgIGhtb2RzOiAoe30pLAorICAgICAgICAgICAgICAgICAgZG1vZHM6ICh7fSksCisgICAgICAgICAgICAgICAgICBsaXN0ZW5lcnM6ICh7fSkgKTsKKyAgICAgICAgICAgICAgaG9va01hcHBpbmdbaG9va2lkXSA9IGhvb2s7CisgICAgICAgICAgfQorICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgICAgaWYgKG1lbWJlcihob29rTWFwcGluZyxob29raWQpKSB7CisgICAgICAgICAgICBtX2RlbGV0ZShob29rTWFwcGluZyxob29raWQpOworICAgICAgICAgIH0KKyAgICAgIH0KKyAgfQorICBIX0RNU0coc3ByaW50ZigiICByZXN1bHQgJU9cbiIsaG9va01hcHBpbmcpKTsKK30KKworLy8gaG9va0NvbnN1bWVySW5mbygpIGxpZWZlcnQgQXJyYXkgdm9uIGhvb2tfZW50cnlfcyB6dXJ1ZWNrLiBELmguIGJlaSBBYmZyYWdlCisvLyB2b24gT2JqZWt0ZW4gYWxsZSBDbG9zdXJlcyBkaWVzZXMgT2JqZWt0cyB1bmQgamVkZSBkYXZvbiBlcnpldWd0IGVpbgorLy8gRWxlbWVudCBob29rX2VudHJ5X3MgaW0gRXJnZWJuaXNhcnJheS4gQmVpIEFiZnJhZ2Ugdm9uIENsb3N1cmVzIGhhdCBkYXMKKy8vIEFycmF5IGltbWVyIGdlbmF1IDEgb2RlciBrZWluIEVsZW1lbnQuCisvLyBXQVJOSU5HOiB3aG9ldmVyIGhhcyBhIGhvb2tfZW50cnlfcyBjYW4gY2hhbmdlL2RlbGV0ZSB0aGUgaG9vayEKKy8vICAgICAgICAgIE5FVkVSIHJldHVybiB0aGUgb3JpZ2luYWwgdG8gYW4gZXh0ZXJuYWwgY2FsbGVyIQorLy8gTk9URTogd2hvZXZlciBoYXMgdGhlIGNsIGZyb20gaG9va19lbnRyeV9zIGNhbiBjYWxsIGl0LCBldmVuIGlmIHRoZSBsZnVuCisvLyAgICAgICBpcyBwcml2YXRlIChhbmQgdGhpcyBvYmplY3QgdGhlIG9ubHkgb25lIGtub3dpbmcgaXQpLgorcHJvdGVjdGVkIG1peGVkICogaG9va0NvbnN1bWVySW5mbyhpbnQgaG9va2lkLCBvYmplY3R8Y2xvc3VyZSBjb25zdW1lcikKK3sKKyAgY2xvc3VyZSBmaWx0ZXJfY2w7CisKKyAgaWYgKCFtZW1iZXIoaG9va01hcHBpbmcsaG9va2lkKSkKKyAgICByZXR1cm4gKHt9KTsKKworICAvLyBDbG9zdXJlIHp1bSBGaWx0ZXJuIGJlc3RpbW1lbiAtIGplIG5hY2hkZW0sIHdhcyBnZXN1Y2h0IHdpcmQuCisgIGlmIChjbG9zdXJlcChjb25zdW1lcikpCisgIHsKKyAgICBmaWx0ZXJfY2wgPSBmdW5jdGlvbiBpbnQgKHN0cnVjdCBob29rX2VudHJ5X3MgaCkKKyAgICAgICAgICAgICAgICB7IHJldHVybiBoLT5jbCA9PSBjb25zdW1lcgorICAgICAgICAgICAgICAgICAgICAgICAgICYmIGgtPmVuZHRpbWUgPj0gdGltZSgpOyB9OworICB9CisgIGVsc2UgaWYgKG9iamVjdHAoY29uc3VtZXIpKQorICB7CisgICAgZmlsdGVyX2NsID0gZnVuY3Rpb24gaW50IChzdHJ1Y3QgaG9va19lbnRyeV9zIGgpCisgICAgICAgICAgICAgICAgeyByZXR1cm4gR0VUX09CSkVDVChoLT5jbCkgPT0gY29uc3VtZXIKKyAgICAgICAgICAgICAgICAgICAgICAgICAmJiBoLT5lbmR0aW1lID49IHRpbWUoKTsgfTsKKyAgfQorICBlbHNlCisgIHsKKyAgICByZXR1cm4gKHt9KTsKKyAgfQorCisgIHN0cnVjdCBob29rX3MgaG9vayA9IGhvb2tNYXBwaW5nW2hvb2tpZF07CisgIHN0cnVjdCBob29rX2VudHJ5X3MgKnJlc3VsdCA9ICh7fSk7CisgIGZvcmVhY2ggKHN0cmluZyBjb25zdW1lcnR5cGU6IEhfQ09OU1VNRVJOQU1FUyApCisgIHsKKyAgICByZXN1bHQgKz0gZmlsdGVyKGhvb2stPihjb25zdW1lcnR5cGUpLCBmaWx0ZXJfY2wpOworICB9CisgIHJldHVybiByZXN1bHQ7Cit9CisKK2ludCBISXNIb29rQ29uc3VtZXIoaW50IGhvb2tpZCwgbWl4ZWQgY29uc3VtZXIpIHsKKyAgcmV0dXJuIHNpemVvZihob29rQ29uc3VtZXJJbmZvKGhvb2tpZCxjb25zdW1lcikpICE9IDA7Cit9CisKK2ludCogSExpc3RIb29rcygpIHsKKyAgcmV0dXJuIG1faW5kaWNlcyhob29rTWFwcGluZyk7Cit9CisKK2ludCBIVW5yZWdpc3RlckZyb21Ib29rKGludCBob29raWQsIG1peGVkIGNvbnN1bWVyKSB7CisKKyAgSF9ETVNHKHNwcmludGYoIkhVbnJlZ2lzdGVyRnJvbUhvb2sgaG9va2lkICVkIGNvbnN1bWVyICVPXG4iLGhvb2tpZCxjb25zdW1lcikpOworICBpZiAob2JqZWN0cChjb25zdW1lcikpCisgICAgY29uc3VtZXIgPSBzeW1ib2xfZnVuY3Rpb24oIkhvb2tDYWxsYmFjayIsIGNvbnN1bWVyKTsKKyAgaWYgKCFjbG9zdXJlcChjb25zdW1lcikpCisgICAgcmV0dXJuIDA7CisKKyAgc3RydWN0IGhvb2tfZW50cnlfcyAqaW5mbyA9IGhvb2tDb25zdW1lckluZm8oaG9va2lkLGNvbnN1bWVyKTsKKworICAvLyBpdCBzaG91bGQgbmV2ZXIgaGFwcGVuIHRoYXQgYSBjbG9zdXJlIGlzIHJlZ2lzdGVyZWQgbW9yZSB0aGFuIG9uY2UsIGkuZS4KKyAgLy8gdGhlIHJlc3VsdCBjb250YWlucyBtb3JlIHRoYW4gb25lIGVsZW1lbnQuCisgIGlmIChzaXplb2YoaW5mbykpIHsKKyAgICAgIHN0cnVjdCBob29rX2VudHJ5X3MgaCA9IGluZm9bMF07CisgICAgICBoLT5jbCA9IDA7CisgICAgICBIX0RNU0coc3ByaW50ZigiICByZXN1bHQgJU9cbiIsIGhvb2tNYXBwaW5nKSk7CisgICAgICAvLyB0aGUgbm93IGludmFsaWQgaCB3aWxsIGJlIGNsZWFuZWQgdXAgbGF0ZXIuCisgICAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworLy8gc3VydmV5b3JzIGFyZSBhc2tlZCBmb3IgcmVnaXN0cmF0aW9uIHBlcm1pdHRhbmNlCitwcm90ZWN0ZWQgaW50IGFza1N1cnZleW9yc0ZvclJlZ2lzdHJhdGlvbkFsbG93YW5jZSgKKyAgICAgICAgICAgICAgICAgIHN0cnVjdCBob29rX2VudHJ5X3MgKnN1cnZleW9ycywgb2JqZWN0IGNvbnN1bWVyLGludCBob29raWQsCisgICAgICAgICAgICAgICAgICBpbnQgaG9va3ByaW8saW50IGNvbnN1bWVydHlwZSkKK3sKKyAgSF9ETVNHKHNwcmludGYoImFza1N1cnZleW9yc0ZvclJlZ2lzdHJhdGlvbkFsbG93YW5jZSBzdXJ2ZXlvcnMgJU8sICIKKyAgICAgICAgImNvbnN1bWVyICVPLCBob29raWQgJWQsIGhvb2twcmlvICVkLCBjb25zdW1lcnR5cGUgJWRcbiIsCisgICAgICAgIHN1cnZleW9ycyxjb25zdW1lcixob29raWQsaG9va3ByaW8sY29uc3VtZXJ0eXBlKSk7CisKKyAgZm9yZWFjaChzdHJ1Y3QgaG9va19lbnRyeV9zIHN1cnZleW9yIDogc3VydmV5b3JzKSB7CisgICAgaWYgKGNsb3N1cmVwKHN1cnZleW9yLT5jbCkgJiYgc3VydmV5b3ItPmVuZHRpbWUgPj0gdGltZSgpKQorICAgIHsKKyAgICAgIC8vIHN1cnZleW9yIGhvb2sgZ3VlbHRpZy4KKyAgICAgIG9iamVjdCBzb2IgPSBHRVRfT0JKRUNUKHN1cnZleW9yLT5jbCk7CisgICAgICBpZiAoIXNvYi0+SG9va1JlZ2lzdHJhdGlvbkNhbGxiYWNrKGNvbnN1bWVyLCBob29raWQsCisgICAgICAgICAgICAgICAgICAgICAgICB0aGlzX29iamVjdCgpLCBob29rcHJpbywgY29uc3VtZXJ0eXBlKSkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICB9CisgIHJldHVybiAxOworfQorCitpbnQgSFJlZ2lzdGVyVG9Ib29rKGludCBob29raWQsIG1peGVkIGNvbnN1bWVyLCBpbnQgaG9va3ByaW8sCisgICAgICAgICAgICAgICAgICAgICAgIGludCBjb25zdW1lcnR5cGUsIGludCB0aW1lSW5TZWNvbmRzKSB7CisgIGludCByZXQsIHJlZ3RpbWU7CisKKyAgaWYgKCFjbG9zdXJlcChjb25zdW1lcikgJiYgIW9iamVjdHAoY29uc3VtZXIpKQorICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIldyb25nIGFyZ3VtZW50ICUuNTBPIHRvIEhSZWdpc3RlclRvSG9vaygpOiBjb25zdW1lciAiCisgICAgICAgICAgIm11c3QgYmUgY2xvc3VyZSBvciBvYmplY3QuXG4iLGNvbnN1bWVyKSk7CisKKyAgaWYgKCFtZW1iZXIoaG9va01hcHBpbmcsIGhvb2tpZCkpCisgICAgcmV0dXJuIC0xOworCisgIGlmIChvYmplY3RwKGNvbnN1bWVyKSkgeworICAgIGNvbnN1bWVyID0gc3ltYm9sX2Z1bmN0aW9uKCJIb29rQ2FsbGJhY2siLCBjb25zdW1lcik7CisgICAgaWYgKCFjbG9zdXJlcChjb25zdW1lcikpCisgICAgICByZXR1cm4gLTI7CisgIH0KKworICBpZiAodGltZUluU2Vjb25kcyA+IDApIHsKKyAgICAgIHJlZ3RpbWU9dGltZSgpICsgdGltZUluU2Vjb25kczsKKyAgfQorICBlbHNlIHsKKyAgICAgIHJlZ3RpbWU9X19JTlRfTUFYX187CisgIH0KKworICBIX0RNU0coc3ByaW50ZigiSFJlZ2lzdGVyVG9Ib29rIGhvb2tpZCAlZCBjb25zdW1lciAlT1xuIGhvb2twcmlvICVkICIKKyAgICAgICAgImNvbnN1bWVydHlwZSAlZFxuIixob29raWQsY29uc3VtZXIsaG9va3ByaW8sY29uc3VtZXJ0eXBlKSk7CisKKyAgQ2xlYW5Ib29rTWFwcGluZygoe2hvb2tpZH0pKTsgLy8gZW50ZmVybnQgdW5ndWVsdGlnZS9hYmdlbGF1ZmVuZSBFaW50cmFlZ2UKKworICAvLyBudXIgZWlubWFsIHBybyBjbG9zdXJlIHJlZ2lzdHJpZXJlbiEKKyAgaWYgKEhJc0hvb2tDb25zdW1lcihob29raWQsIGNvbnN1bWVyKSkKKyAgICByZXR1cm4gLTM7CisKKyAgLy8gQ29uc3VtZXJ0eXAgZXJsYXVidD8KKyAgaWYgKEhfQ09OU1VNRVJDSEVDSyhjb25zdW1lcnR5cGUpID09IC0xCisgICAgICB8fCAhSENvbnN1bWVyVHlwZUlzQWxsb3dlZChjb25zdW1lcnR5cGUsR0VUX09CSkVDVChjb25zdW1lcikpKQorICAgIHJldHVybiAtNDsKKworICAvLyBQcmlvcml0YWV0IGVybGF1YnQ/CisgIGlmIChIX0hPT0tfVkFMSURQUklPKGhvb2twcmlvKSA9PSAtMQorICAgICAgfHwgIUhQcmlvcml0eUlzQWxsb3dlZChob29rcHJpbywgR0VUX09CSkVDVChjb25zdW1lcikpKQorICAgIHJldHVybiAtNTsKKworICBzdHJ1Y3QgaG9va19zIGhvb2sgPSBob29rTWFwcGluZ1tob29raWRdOworCisgIC8vIFVuZCBzdXJ2ZXlvcnMgZXJsYXViZW4gZGllIFJlZ2lzdGllcnVuZz8KKyAgaWYgKCFhc2tTdXJ2ZXlvcnNGb3JSZWdpc3RyYXRpb25BbGxvd2FuY2UoaG9vay0+c3VydmV5b3JzLAorICAgICAgICAgICAgICAgICAgICBHRVRfT0JKRUNUKGNvbnN1bWVyKSxob29raWQsCisgICAgICAgICAgICAgICAgICAgIGhvb2twcmlvLGNvbnN1bWVydHlwZSkpCisgICAgcmV0dXJuIC02OworCisgIHN0cmluZyBjdHlwZW5hbWUgPSBIX0NPTlNVTUVSTkFNRVNbY29uc3VtZXJ0eXBlXTsKKworICAvLyBnZXQgdGhlIGNvbnN1bWVyIGFycmF5CisgIHN0cnVjdCBob29rX2VudHJ5X3MgKmNvbnN1bWVycyA9IGhvb2stPihjdHlwZW5hbWUpOworCisgIC8vIGFzc2VtYmxlIG5ldyBob29rIGNvbnN1bWVyIHN0cnVjdAorICBzdHJ1Y3QgaG9va19lbnRyeV9zIG5ld2NvbnN1bWVyID0gKDxob29rX2VudHJ5X3M+CisgICAgICAgICAgICAgICAgICAgICAgY2wgOiBjb25zdW1lciwKKyAgICAgICAgICAgICAgICAgICAgICBwcmlvIDogaG9va3ByaW8sCisgICAgICAgICAgICAgICAgICAgICAgZW5kdGltZSA6IHJlZ3RpbWUsCisgICAgICAgICAgICAgICAgICAgICAgdHlwZSA6IGNvbnN1bWVydHlwZSApOworCisgIC8vIGNvbnN1bWVycyBlbnRoYWVsdCBkaWUgSG9va2VpbnRyYWVnZQorICBpZiAoc2l6ZW9mKGNvbnN1bWVycykgPCBNQVhfSE9PS19DT1VOVFNbY29uc3VtZXJ0eXBlXSkgeworICAgIC8vIG1heC4gQW56YWhsIGFuIEVpbnRyYWVnZW4gZnVlciBkaWVzZW4gVHlwIG5vY2ggbmljaHQKKyAgICAvLyBlcnJlaWNodCwgZGlyZWt0IGFuaGFlbmdlbi4KKyAgICBjb25zdW1lcnMgKz0gKHsgbmV3Y29uc3VtZXIgfSk7CisgICAgaG9vay0+KGN0eXBlbmFtZSkgPSBjb25zdW1lcnM7CisgICAgcmV0PTE7CisgIH0KKyAgZWxzZSB7CisgICAgLy8gZ2lidCBlcyBlaW5lbiBFaW50cmFnIG1pdCBob2VoZXJlbSBQcmlvd2VydCAobmllZHJpZ2VyZQorICAgIC8vIFByaW9yaXRhZXQpLCBkZW4gbWFuIGVyc2V0emVuIGtvZW5udGU/CisgICAgLy8gRGFzIEFycmF5IGlzdCBzb3J0aWVydCwgbWl0IGhvZWNoc3RlbiBQcmlvd2VydGVuIGFtCisgICAgLy8gRW5kZS4gRXJzZXR6dCB3ZXJkZW4gc29sbCBkZXIgRWludHJhZyBtaXQgZGVtIGhvZWNoc3RlbgorICAgIC8vIFphaGxlbndlcnQsIGZhbGxzIGRlciBuZXVlIEVpbnRyYWcgZWluZW4gbmllZHJpZ2VyZW4gV2VydAorICAgIC8vIGhhdCwgZC5oLiBlcyBtdXNzIG51ciBlciBsZXR6dGUgQ29uc3VtZXIgaW0gQXJyYXkgZ2VwcnVlZnQgd2VyZGVuLgorICAgIC8vIFBydWVmdW5nIGF1ZiBDbG9zdXJlZXhpc3RlbnosIGZhbGxzIGRlciBTdXJ2ZXlvciBPYmpla3RlCisgICAgLy8gemVyc3RvZXJ0IChoYXQpLi4uCisgICAgc3RydWN0IGhvb2tfZW50cnlfcyBvaCA9IGNvbnN1bWVyc1s8MV07CisgICAgaWYgKCFvaC0+Y2wgfHwgb2gtPnByaW8gPiBuZXdjb25zdW1lci0+cHJpbykgeworICAgICAgLy8gRm91bmQgc3VwZXJzZWVkYWJsZSBlbnRyeSAtIHJlcGxhY2UgaXQsIGJ1dCBpbmZvcm0gdGhlIG9iamVjdC4KKyAgICAgIEhfRE1TRygiRm91bmQgc3VwZXJzZWVkYWJsZSBlbnRyeVxuIik7CisgICAgICBjb25zdW1lcnNbPDFdID0gbmV3Y29uc3VtZXI7CisgICAgICBHRVRfT0JKRUNUKG9oLT5jbCktPnN1cGVyc2VlZGVkSG9vayhob29raWQsIHRoaXNfb2JqZWN0KCkpOworICAgICAgcmV0ID0gMTsKKyAgICAgIC8vIG5pY2h0IG5vZXRpZywgY29uc3VtZXJzIHdpZWRlciBpbiBzZWluIGhvb2tfcyB6dSBoYWVubmdlbiB3ZWdlbiBBcnJheQorICAgICAgLy8gLT4gUmVmZXJlbnoKKyAgICB9CisgIH0KKworICAvLyB3ZW5uIGVpbiBFaW50cmFnIGhpbnp1Z2VmdWVndCB3dXJkZSwgbXVzcyBuZXUgc29ydGllcnQgd2VyZGVuCisgIGlmIChyZXQpIHsKKyAgICBob29rLT4oY3R5cGVuYW1lKSA9IHNvcnRfYXJyYXkoY29uc3VtZXJzLAorICAgICAgICBmdW5jdGlvbiBpbnQgKHN0cnVjdCBob29rX2VudHJ5X3MgYSwgc3RydWN0IGhvb2tfZW50cnlfcyBiKSB7CisgICAgICAgICAgICByZXR1cm4gYS0+cHJpbyA+IGItPnByaW87IH0gKTsKKyAgfQorCisgIEhfRE1TRyhzcHJpbnRmKCIgIHJlc3VsdCAlT1xuIixob29rTWFwcGluZykpOworCisgIC8vIC03LCB3ZW5uIGtlaW4gRWludHJhZyBtZWhyIGZyZWkgLyB6dXZpZWxlIEhvb2tzCisgIHJldHVybiAocmV0ID4gMCA/IDEgOiAtNyk7Cit9CisKKy8vIENvbnZlbmllbmNlcyB3cmFwcGVyIGZvciBzaW1wbGUgbGlzdGVuZXIgaG9va3MKK2ludCBIUmVnaXN0ZXJMaXN0ZW5lcihpbnQgaG9va2lkLCBtaXhlZCBjb25zdW1lcikKK3sKKyAgcmV0dXJuIEhSZWdpc3RlclRvSG9vayhob29raWQsIGNvbnN1bWVyLCBIX0hPT0tfT1RIRVJQUklPKDIpLCBIX0xJU1RFTkVSLCAwKTsKK30KKworLy8gQ252ZW5pZW5jZXMgd3JhcHBlciBmb3Igc2ltcGxlIG1vZGlmaWNhdG9yIGhvb2tzCitpbnQgSFJlZ2lzdGVyTW9kaWZpZXIoaW50IGhvb2tpZCwgbWl4ZWQgY29uc3VtZXIpCit7CisgIHJldHVybiBIUmVnaXN0ZXJUb0hvb2soaG9va2lkLCBjb25zdW1lciwgSF9IT09LX09USEVSUFJJTygyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBIX0hPT0tfTU9ESUZJQ0FUT1IsIDApOworfQorCisvLyBzdXJ2ZXlvcnMgYXJlIGFza2VkIGZvciBjYW5jZWxsYXRpb24gcGVybWl0dGFuY2UKK3Byb3RlY3RlZCBpbnQgYXNrU3VydmV5b3JzRm9yQ2FuY2VsQWxsb3dhbmNlKG1peGVkIHN1cnZleW9ycywKKyAgb2JqZWN0IG1vZGlmaXlpbmdPYixtaXhlZCBkYXRhLGludCBob29raWQsaW50IHByaW8sb2JqZWN0IGhvb2tPYil7CisKKyAgZm9yZWFjaChzdHJ1Y3QgaG9va19lbnRyeV9zIHN1cnZleW9yIDogc3VydmV5b3JzKSB7CisgICAgaWYgKGNsb3N1cmVwKHN1cnZleW9yLT5jbCkgJiYgc3VydmV5b3ItPmVuZHRpbWUgPj0gdGltZSgpKQorICAgIHsKKyAgICAgIC8vIHN1cnZleW9yIGhvb2sgZ3VlbHRpZy4KKyAgICAgIG9iamVjdCBzb2IgPSBHRVRfT0JKRUNUKHN1cnZleW9yLT5jbCk7CisgICAgICBpZiAoIXNvYi0+SG9va0NhbmNlbEFsbG93YW5jZUNhbGxiYWNrKG1vZGlmaXlpbmdPYiwgaG9va2lkLAorICAgICAgICAgICAgICAgICAgICAgICAgaG9va09iLCBwcmlvLCBkYXRhKSkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICB9CisgIHJldHVybiAxOworfQorCisvLyBzdXJ2ZXlvcnMgYXJlIGFza2VkIGZvciBkYXRhIGNoYW5nZSBwZXJtaXR0YW5jZQorcHJvdGVjdGVkIGludCBhc2tTdXJ2ZXlvcnNGb3JNb2RpZmljYXRpb25BbGxvd2FuY2UobWl4ZWQgc3VydmV5b3JzLAorICBvYmplY3QgbW9kaWZpeWluZ09iLG1peGVkIGRhdGEsaW50IGhvb2tpZCxpbnQgcHJpbyxvYmplY3QgaG9va09iKXsKKworICBmb3JlYWNoKHN0cnVjdCBob29rX2VudHJ5X3Mgc3VydmV5b3IgOiBzdXJ2ZXlvcnMpIHsKKyAgICBpZiAoY2xvc3VyZXAoc3VydmV5b3ItPmNsKSAmJiBzdXJ2ZXlvci0+ZW5kdGltZSA+PSB0aW1lKCkpCisgICAgeworICAgICAgLy8gc3VydmV5b3IgaG9vayBndWVsdGlnLgorICAgICAgb2JqZWN0IHNvYiA9IEdFVF9PQkpFQ1Qoc3VydmV5b3ItPmNsKTsKKyAgICAgIGlmICghc29iLT5Ib29rTW9kaWZpY2F0aW9uQWxsb3dhbmNlQ2FsbGJhY2sobW9kaWZpeWluZ09iLAorICAgICAgICAgICAgICAgICAgICAgICAgaG9va2lkLCBob29rT2IsIHByaW8sIGRhdGEpKQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3Byb3RlY3RlZCBtaXhlZCBIb29rRmxvdyhpbnQgaG9va2lkLCBtaXhlZCBob29rZGF0YSl7CisgIG1peGVkIHRtcCwgcmV0OworCisgIHJldD0oe0hfTk9fTU9ELGhvb2tkYXRhfSk7CisKKyAgSF9ETVNHKHNwcmludGYoIkhvb2tGbG93IGhvb2tpZCAlZCBob29rZGF0YSAlT1xuIixob29raWQsaG9va2RhdGEpKTsKKworICBpZiAoIW1lbWJlcihob29rTWFwcGluZywgaG9va2lkKSkKKyAgICByZXR1cm4gcmV0OworCisgIHN0cnVjdCBob29rX3MgaG9vayA9IGhvb2tNYXBwaW5nW2hvb2tpZF07CisKKyAgLy8gbm90aWZ5IHN1cnZleW9ycworICBmb3JlYWNoKHN0cnVjdCBob29rX2VudHJ5X3MgaCA6IGhvb2stPnN1cnZleW9ycykgeworICAgIGlmIChjbG9zdXJlcChoLT5jbCkgJiYgaC0+ZW5kdGltZSA+PSB0aW1lKCkpCisgICAgeworICAgICAgLy8gSG9vayBndWVsdGlnCisgICAgICB0bXAgPSBmdW5jYWxsKGgtPmNsLCB0aGlzX29iamVjdCgpLCBob29raWQsIHJldFtIX1JFVERBVEFdKTsKKyAgICAgIGlmKHRtcFtIX1JFVENPREVdPT1IX0NBTkNFTExFRCkgeworICAgICAgICByZXRbSF9SRVRDT0RFXT1IX0NBTkNFTExFRDsKKyAgICAgICAgcmV0dXJuIHJldDsgIC8vIHVuZCB3ZWcuLi4KKyAgICAgIH0KKyAgICAgIGVsc2UgaWYodG1wW0hfUkVUQ09ERV09PUhfQUxURVJFRCl7CisgICAgICAgIHJldFtIX1JFVENPREVdPUhfQUxURVJFRDsKKyAgICAgICAgcmV0W0hfUkVUREFUQV09dG1wW0hfUkVUREFUQV07CisgICAgICB9CisgICAgfQorICAgIC8vIHVuZ3VlbHRpZ2UvYWJnZWxhdWZlbmUgRWludHJhZWdlIC0+IEF1ZnJhZXVtZW4sIGFiZXIgbmljaHQgamV0enQuCisgICAgZWxzZSBpZiAoZmluZF9jYWxsX291dCgjJ0NsZWFuSG9va01hcHBpbmcpID09IC0xKSB7CisgICAgICBjYWxsX291dCgjJ0NsZWFuSG9va01hcHBpbmcsIDAsICh7aG9va2lkfSkpOworICAgIH0KKyAgfSAvLyBzdXJ2ZXlvcnMgZmVydGlnCisKKyAgLy8gbm90aWZ5IGhtb2RzCisgIGZvcmVhY2goc3RydWN0IGhvb2tfZW50cnlfcyBoIDogaG9vay0+aG1vZHMpIHsKKyAgICBpZiAoY2xvc3VyZXAoaC0+Y2wpICYmIGgtPmVuZHRpbWUgPj0gdGltZSgpKQorICAgIHsKKyAgICAgIC8vIEhvb2sgZ3VlbHRpZworICAgICAgdG1wID0gZnVuY2FsbChoLT5jbCwgdGhpc19vYmplY3QoKSwgaG9va2lkLCByZXRbSF9SRVREQVRBXSk7CisgICAgICBpZih0bXBbSF9SRVRDT0RFXT09SF9DQU5DRUxMRUQpIHsKKyAgICAgICAgLy8gYXNrIGFsbG93YW5jZSBpbiBzdXJ2ZXlvcnMKKyAgICAgICAgaWYoaC0+Y2wgJiYKKyAgICAgICAgICAgYXNrU3VydmV5b3JzRm9yQ2FuY2VsQWxsb3dhbmNlKGhvb2stPnN1cnZleW9ycywKKyAgICAgICAgICAgICAgR0VUX09CSkVDVChoLT5jbCksIGhvb2tkYXRhLCBob29raWQsCisgICAgICAgICAgICAgIGgtPnByaW8sIHRoaXNfb2JqZWN0KCkpKQorICAgICAgICB7CisgICAgICAgICAgICByZXRbSF9SRVRDT0RFXSA9IEhfQ0FOQ0VMTEVEOworICAgICAgICAgICAgcmV0dXJuIHJldDsgLy8gdW5kIHJhdXMuLi4KKyAgICAgICAgfQorICAgICAgfQorICAgICAgZWxzZSBpZih0bXBbSF9SRVRDT0RFXT09SF9BTFRFUkVEKSB7CisgICAgICAgIC8vIGFzayBhbGxvd2FuY2UgaW4gc3VydmV5b3JzCisgICAgICAgIGlmKGgtPmNsICYmCisgICAgICAgICAgIGFza1N1cnZleW9yc0Zvck1vZGlmaWNhdGlvbkFsbG93YW5jZShob29rLT5zdXJ2ZXlvcnMsCisgICAgICAgICAgICAgIEdFVF9PQkpFQ1QoaC0+Y2wpLGhvb2tkYXRhLCBob29raWQsCisgICAgICAgICAgICAgIGgtPnByaW8sdGhpc19vYmplY3QoKSkpCisgICAgICAgIHsKKyAgICAgICAgICAgIHJldFtIX1JFVENPREVdID0gSF9BTFRFUkVEOworICAgICAgICAgICAgcmV0W0hfUkVUREFUQV0gPSB0bXBbSF9SRVREQVRBXTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICAvLyB1bmd1ZWx0aWdlL2FiZ2VsYXVmZW5lIEVpbnRyYWVnZSAtPiBBdWZyYWV1bWVuLCBhYmVyIG5pY2h0IGpldHp0LgorICAgIGVsc2UgaWYgKGZpbmRfY2FsbF9vdXQoIydDbGVhbkhvb2tNYXBwaW5nKSA9PSAtMSkgeworICAgICAgY2FsbF9vdXQoIydDbGVhbkhvb2tNYXBwaW5nLCAwLCAoe2hvb2tpZH0pKTsKKyAgICB9CisgIH0gLy8gaG1vZHMgZmVydGlnCisKKyAgLy8gbm90aWZ5IGRtb2RzCisgIGZvcmVhY2goc3RydWN0IGhvb2tfZW50cnlfcyBoIDogaG9vay0+ZG1vZHMpIHsKKyAgICBpZiAoY2xvc3VyZXAoaC0+Y2wpICYmIGgtPmVuZHRpbWUgPj0gdGltZSgpKQorICAgIHsKKyAgICAgIC8vIEhvb2sgZ3VlbHRpZworICAgICAgdG1wID0gZnVuY2FsbChoLT5jbCwgdGhpc19vYmplY3QoKSwgaG9va2lkLCByZXRbSF9SRVREQVRBXSk7CisgICAgICBpZih0bXBbSF9SRVRDT0RFXT09SF9BTFRFUkVEKSB7CisgICAgICAgIC8vIGFzayBhbGxvd2FuY2UgaW4gc3VydmV5b3JzCisgICAgICAgIGlmIChoLT5jbCAmJgorICAgICAgICAgICAgYXNrU3VydmV5b3JzRm9yTW9kaWZpY2F0aW9uQWxsb3dhbmNlKGhvb2stPnN1cnZleW9ycywKKyAgICAgICAgICAgICAgR0VUX09CSkVDVChoLT5jbCksaG9va2RhdGEsIGhvb2tpZCwKKyAgICAgICAgICAgICAgaC0+cHJpbyx0aGlzX29iamVjdCgpKSkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0W0hfUkVUQ09ERV0gPSBIX0FMVEVSRUQ7CisgICAgICAgICAgICByZXRbSF9SRVREQVRBXSA9IHRtcFtIX1JFVERBVEFdOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIC8vIHVuZ3VlbHRpZ2UvYWJnZWxhdWZlbmUgRWludHJhZWdlIC0+IEF1ZnJhZXVtZW4sIGFiZXIgbmljaHQgamV0enQuCisgICAgZWxzZSBpZiAoZmluZF9jYWxsX291dCgjJ0NsZWFuSG9va01hcHBpbmcpID09IC0xKSB7CisgICAgICBjYWxsX291dCgjJ0NsZWFuSG9va01hcHBpbmcsIDAsICh7aG9va2lkfSkpOworICAgIH0KKyAgfSAvLyBkbW9kcyBmZXJ0aWcKKworICAvLyBub3RpZnkgbGlzdGVuZXIKKyAgZm9yZWFjaChzdHJ1Y3QgaG9va19lbnRyeV9zIGggOiBob29rLT5saXN0ZW5lcnMpIHsKKyAgICBpZiAoY2xvc3VyZXAoaC0+Y2wpICYmIGgtPmVuZHRpbWUgPj0gdGltZSgpKQorICAgIHsKKyAgICAgIC8vIEhvb2sgZ3VlbHRpZworICAgICAgZnVuY2FsbChoLT5jbCwgdGhpc19vYmplY3QoKSwgaG9va2lkLCByZXRbSF9SRVREQVRBXSk7CisgICAgfQorICAgIC8vIHVuZ3VlbHRpZ2UvYWJnZWxhdWZlbmUgRWludHJhZWdlIC0+IEF1ZnJhZXVtZW4sIGFiZXIgbmljaHQgamV0enQuCisgICAgZWxzZSBpZiAoZmluZF9jYWxsX291dCgjJ0NsZWFuSG9va01hcHBpbmcpID09IC0xKSB7CisgICAgICBjYWxsX291dCgjJ0NsZWFuSG9va01hcHBpbmcsIDAsICh7aG9va2lkfSkpOworICAgIH0KKyAgfSAvLyBsaXN0ZW5lciBmZXJ0aWcKKworICByZXR1cm4gcmV0OworfQorCmRpZmYgLS1naXQgYS9zdGQvaG9va19zdXJ2ZXlvci5jIGIvc3RkL2hvb2tfc3VydmV5b3IuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYWZiMTkzCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2hvb2tfc3VydmV5b3IuYwpAQCAtMCwwICsxLDQxIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gL3N0ZC9ob29rX3N1cnZleW9yLmMgIC0gQmFzaXNrbGFzc2UgZnVlciBTdXJ2ZXlvci1Ib29rcworLy8KKworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCisjaW5jbHVkZSA8aG9vay5oPgorCisvLyBvdmVycmlkZSBhcyB3aXNoZWQgYW5kIG5lZWRlZAorCitpbnQgSG9va1JlZ2lzdHJhdGlvbkNhbGxiYWNrKG9iamVjdCByZWdpc3RyaW5nT2JqZWN0LCBpbnQgaG9va2lkLAorICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0IGhvb2tTb3VyY2UsIGludCByZWdpc3RyaW5nT2JqZWN0c1ByaW9yaXR5LAorICAgICAgICAgICAgICAgICAgICAgICAgaW50IHJlZ2lzdHJpbmdPYmplY3RzVHlwZSkKK3sKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBIb29rQ2FuY2VsQWxsb3dhbmNlQ2FsbGJhY2sob2JqZWN0IGNhbmNlbGxpbmdPYmplY3QsIGludCBob29raWQsCisgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QgaG9va1NvdXJjZSwgaW50IGNhbmNlbGxpbmdPYmplY3RzUHJpb3JpdHksCisgICAgICAgICAgICAgICAgICAgICAgICBtaXhlZCBob29rRGF0YSkKK3sKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBIb29rTW9kaWZpY2F0aW9uQWxsb3dhbmNlQ2FsbGJhY2sob2JqZWN0IG1vZGlmeWluZ09iamVjdCwgaW50IGhvb2tpZCwKKyAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdCBob29rU291cmNlLCBpbnQgbW9kaWZ5aW5nT2JqZWN0c1ByaW9yaXR5LAorICAgICAgICAgICAgICAgICAgICAgICAgbWl4ZWQgaG9va0RhdGEpCit7CisgIHJldHVybiAxOworfQorCittaXhlZCBIb29rQ2FsbGJhY2sob2JqZWN0IGhvb2tTb3VyY2UsIGludCBob29raWQsIG1peGVkIGhvb2tEYXRhKQoreworICByZXR1cm4gKHtIX05PX01PRCxob29rRGF0YX0pOworfQorCmRpZmYgLS1naXQgYS9zdGQvaW5wYy5jIGIvc3RkL2lucGMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42M2VkZDY3Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2lucGMuYwpAQCAtMCwwICsxLDYyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gaW5wYy5jIC0tIEludGVsbGlnZW50ZXIgTlBDCisvLworLy8gJElkOiBpbnBjLmMgNjU3MSAyMDA3LTEwLTIxIDE0OjQxOjEwWiBaZXNzdHJhICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC9ucGMiOworaW5oZXJpdCAiL3N0ZC9pbnBjL25vYmFuayI7Citpbmhlcml0ICIvc3RkL2lucGMvc2VsZWN0IjsKK2luaGVyaXQgIi9zdGQvaW5wYy9ib296aW5nIjsKK2luaGVyaXQgIi9zdGQvaW5wYy9pdGVtcyI7Citpbmhlcml0ICIvc3RkL2lucGMvZXZhbCI7CisKKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxpbnBjLmg+CisjZGVmaW5lIE1FIHRoaXNfb2JqZWN0KCkKKyNkZWZpbmUgRU5WIGVudmlyb25tZW50KCkKKyNkZWZpbmUgVFAgdGhpc19wbGF5ZXIoKQorCisjcHJhZ21hIHN0cm9uZ190eXBlcworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CisgIG5wYzo6Y3JlYXRlKCk7CisgIGl0ZW1zOjpjcmVhdGUoKTsKKyAgYWRkX3NlbGVjdF9jb21tYW5kcygpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKwordm9pZCByZXNldCgpIHsKKyAgbnBjOjpyZXNldCgpOworICBpdGVtczo6cmVzZXQoKTsKK30KKwordm9pZCBpbml0KCkgeworICBucGM6OmluaXQoKTsKKyAgaWYgKFRQICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoVFApKQorICAgIFNldFByb3AoUF9JTlBDX0xBU1RfUExBWUVSX0NPTlRBQ1QsdGltZSgpKTsKK30KKwordmFyYXJncyBpbnQgbW92ZShtaXhlZCBkZXN0LCBpbnQgbWV0aCwgc3RyaW5nIGRpciwgc3RyaW5nIHRpbiwgc3RyaW5nIHRvdXQpIHsKKyAgaW50IHJlczsKKyAgb2JqZWN0IGVudjsKKworICBlbnY9RU5WOworICBpZiAoIShtZXRoJk1fTk9DSEVDSykKKyAgICAgICYmICFFTlYKKyAgICAgICYmIFF1ZXJ5UHJvcChQX0lOUENfV0FMS19NT0RFKQorICAgICAgJiYgIW1heV9lbnRlcl9yb29tKGRlc3QpKQorICAgIHJldHVybiBNRV9DQU5UX1RQT1JUX0lOOworICByZXM9Ojptb3ZlKGRlc3QsbWV0aCxkaXIsdGluLHRvdXQpOworICBpZiAoZW52IT1FTlYpCisgICAgU2V0UHJvcChQX0lOUENfTEFTVF9FTlZJUk9OTUVOVCxFTlYpOworICByZXR1cm4gcmVzOworfQpkaWZmIC0tZ2l0IGEvc3RkL2lucGMvLnJlYWRtZSBiL3N0ZC9pbnBjLy5yZWFkbWUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDZjMWYxNAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9pbnBjLy5yZWFkbWUKQEAgLTAsMCArMSwxMSBAQAorCitJTlBDOiBJbnRlbGxpZ2VudGVyIE5QQworKioqIElOIEVOVFdJQ0tMVU5HIC0gQkVOVVRaVU5HIEFVRiBFSUdFTkUgR0VGQUhSICoqKgorCitub2Jhbms6ICAgTW9uZXloYW5kbGVyK0JlaGFuZGx1bmcgdm9uIEJhbmt6d2VpdGllcword2Fsa2luZzogIExhdWZtb25zdGVyLCBhdXRvbWF0aXNjaGUgUm91dGVuc3VjaGUKK2Jvb3ppbmc6ICBPcHRpbWFsZSBTYWV1ZmVyZWkKK3NlbGVjdDogICBBdXN3YWhsIGd1dGVyIE9iamVrdGUgKGJlc3RlIFdhZmZlL1J1ZXN0dW5nLi4uKQorZXZhbC5jOiAgIEdlZ25lciBlaW5zY2hhZXR6ZW4KK2l0ZW1zLmM6ICBXYWZmZW4sIFJ1ZXN0dW5nZW4gZWluZmFjaCBlaW5mdWVnZW4sIGF1dG9tYXRpc2NoIGltIFJlc2V0IHp1ZWNrZW4KKwpkaWZmIC0tZ2l0IGEvc3RkL2lucGMvYm9vemluZy5jIGIvc3RkL2lucGMvYm9vemluZy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRmMjRmNTIKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvaW5wYy9ib296aW5nLmMKQEAgLTAsMCArMSw2MiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGlucGMvYm9vemluZy5jIC0tIEludGVsbGlnZW50ZXMgU2F1ZmVuCisvLworLy8gJElkOiBib296aW5nLmMgODM5NiAyMDEzLTAyLTE4IDIxOjU2OjM3WiBaZXNzdHJhICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy5oPgorI2luY2x1ZGUgPGxpdmluZy5oPgorI2luY2x1ZGUgPGlucGMuaD4KKyNpbmNsdWRlIDxjb250YWluZXIvbW9uZXloYW5kbGVyLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCisjZGVmaW5lIERSSU5LX0lEUyAxCisjZGVmaW5lIERSSU5LX0NPU1QgMgorI2RlZmluZSBEUklOS19IRUFMIDMKKyNkZWZpbmUgRFJJTktfQUxDIDQKKyNkZWZpbmUgRFJJTktfU0FUIDUKKworaW50IERyaW5rKCkgeworICBtaXhlZCBkcmlua3M7CisgIG9iamVjdCBlbnY7CisgIGludCBpLG1heCxtb24saGRpZmY7CisgCisgIGlmICgobW9uPVF1ZXJ5TW9uZXkoKSk8PTAKKyAgICAgIHx8ICEoZW52PWVudmlyb25tZW50KCkpCisgICAgICB8fCAhcG9pbnRlcnAoZHJpbmtzPWVudi0+cXVlcnlfZHJpbmsoKSkKKyAgICAgIHx8IChoZGlmZj1RdWVyeVByb3AoUF9NQVhfSFApLVF1ZXJ5UHJvcChQX0hQKSk8PTApCisgICAgcmV0dXJuIDA7CisgIG1heD0tMTsKKyAgZm9yIChpPXNpemVvZihkcmlua3MpLTE7aT49MDtpLS0pIHsKKyAgICBpZiAoZHJpbmtzW2ldW0RSSU5LX0NPU1RdPm1vbgorICAgICAgICB8fCAoKGRyaW5rc1tpXVtEUklOS19BTENdPjApICYmCisJICAgICgoZHJpbmtzW2ldW0RSSU5LX0FMQ10rUXVlcnlQcm9wKFBfQUxDT0hPTCkpCisJICAgICA+ICgxMDAtUXVlcnlQcm9wKFBfSV9IQVRFX0FMQ09IT0wpKSkpCisgICAgICAgIHx8IGRyaW5rc1tpXVtEUklOS19TQVRdK1F1ZXJ5UHJvcChQX0RSSU5LKT4xMDAKKyAgICAgICAgfHwgZHJpbmtzW2ldW0RSSU5LX0hFQUxdPD0wKQorICAgICAgY29udGludWU7CisgICAgaWYgKG1heDwwCisgICAgICAgIHx8IChkcmlua3NbaV1bRFJJTktfSEVBTF0+ZHJpbmtzW21heF1bRFJJTktfSEVBTF0gJiYKKyAgICAgICAgICAgIGRyaW5rc1ttYXhdW0RSSU5LX0hFQUxdPGhkaWZmKQorICAgICAgICB8fCAoZHJpbmtzW2ldW0RSSU5LX0hFQUxdPj1oZGlmZiAmJgorICAgICAgICAgICAgZHJpbmtzW2ldW0RSSU5LX0NPU1RdPGRyaW5rc1ttYXhdW0RSSU5LX0NPU1RdKSkKKyAgICAgIG1heD1pOworICB9CisgIGlmIChtYXg8MCkgcmV0dXJuIDA7CisgIGNvbW1hbmQoImJlc3RlbGwgIitkcmlua3NbbWF4XVtEUklOS19JRFNdWzBdKTsKKyAgcmV0dXJuIDE7Cit9CisKK3ZvaWQgRHJpbmtMb29wKCkgeworICB3aGlsZSAocmVtb3ZlX2NhbGxfb3V0KCJEcmlua0xvb3AiKT49MCk7CisgIGlmICghRHJpbmsoKSkKKyAgICByZXR1cm47CisgIGNhbGxfb3V0KCJEcmlua0xvb3AiLDApOworfQorCmRpZmYgLS1naXQgYS9zdGQvaW5wYy9ldmFsLmMgYi9zdGQvaW5wYy9ldmFsLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjc1NTU3NgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9pbnBjL2V2YWwuYwpAQCAtMCwwICsxLDE4OSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGlucGMvZXZhbC5jIC0tIEVpbnNjaGFldHplbiB2b24gR2VnbmVybgorLy8KKy8vICRJZDogZXZhbC5jIDYzNzEgMjAwNy0wNy0xNyAyMjo0Njo1MFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxpdmluZy5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx0aGluZy5oPgorI2luY2x1ZGUgPGlucGMuaD4KKwordmFyYXJncyB2b2lkIFNldEV2YWxGYWN0b3IobWl4ZWQgd2hhdCwgaW50IGZhYywgaW50IG9mZikgeworICBtYXBwaW5nIG9mZnMsZmFjczsKKworICBpZiAoIW1hcHBpbmdwKGZhY3M9UXVlcnlQcm9wKFBfRVZBTF9GQUNUT1JTKSkpIGZhY3M9KFtdKTsKKyAgaWYgKCFtYXBwaW5ncChvZmZzPVF1ZXJ5UHJvcChQX0VWQUxfT0ZGU0VUUykpKSBvZmZzPShbXSk7CisgIGZhY3Nbd2hhdF09ZmFjOworICBvZmZzW3doYXRdPW9mZjsKKyAgU2V0UHJvcChQX0VWQUxfRkFDVE9SUyxmYWNzKTsKKyAgU2V0UHJvcChQX0VWQUxfT0ZGU0VUUyxvZmZzKTsKK30KKwordm9pZCBTZXREZWZhdWx0RXZhbEZhY3RvcnMoKSB7CisgIFNldEV2YWxGYWN0b3IoUF9IUCwxNTAsLTYwKTsKKyAgU2V0RXZhbEZhY3RvcihQX1RPVEFMX1dDLDI1MCwwKTsKKyAgU2V0RXZhbEZhY3RvcihQX1RPVEFMX0FDLDEwMDAsLTUwKTsKKyAgU2V0RXZhbEZhY3RvcigiYWJlbnRldXJlcl9wZmVpbCIsMywwKTsKKyAgU2V0RXZhbEZhY3RvcigiYWJlbnRldXJlcl9mZXVlcmJhbGwiLDgsMCk7Cit9CisKK3ZhcmFyZ3MgaW50Cittb2RpZnlfZXZhbChvYmplY3Qgb2IsIG1peGVkIHdoYXQsIG1hcHBpbmcgZmFjLCBtYXBwaW5nIG9mZiwgaW50IHZhbCkgeworICBpZiAoIXZhbCkgdmFsPVF1ZXJ5UHJvcCh3aGF0KTsKKyAgdmFsLT1vZmZbd2hhdF07CisgIGlmICh2YWw8MCkgdmFsPTA7CisgIHZhbD0odmFsKmZhY1t3aGF0XSkvMTAwMDA7CisgIGlmICh2YWw+MjAwKSB2YWw9MjAwOworICByZXR1cm4gdmFsOworfQorCit2YXJhcmdzIGludCBldmFsX2VuZW15KG9iamVjdCBlbmVteSwgbWFwcGluZyBmYWMsIG1hcHBpbmcgb2ZmKSB7CisgIGludCByZXM7CisgIHN0cmluZyBnaWxkZTsKKyAgCisgIGlmICghb2JqZWN0cChlbmVteSkpIHJldHVybiAwOworICBpZiAoIW1hcHBpbmdwKGZhYykpIGZhYz1RdWVyeVByb3AoUF9FVkFMX0ZBQ1RPUlMpOworICBpZiAoIW1hcHBpbmdwKGZhYykpIGZhYz0oW10pOworICBpZiAoIW1hcHBpbmdwKG9mZikpIG9mZj1RdWVyeVByb3AoUF9FVkFMX09GRlNFVFMpOworICBpZiAoIW1hcHBpbmdwKG9mZikpIG9mZj0oW10pOworCisgIHJlcz0wOworICByZXMrPW1vZGlmeV9ldmFsKGVuZW15LFBfVE9UQUxfV0MsZmFjLG9mZik7CisgIHJlcys9bW9kaWZ5X2V2YWwoZW5lbXksUF9UT1RBTF9BQyxmYWMsb2ZmKTsKKyAgcmVzKz1tb2RpZnlfZXZhbChlbmVteSxQX0hQLGZhYyxvZmYpOworICBpZiAoc3RyaW5ncChnaWxkZT1lbmVteS0+UXVlcnlQcm9wKFBfR1VJTEQpKSkKKyAgICByZXMrPWNhbGxfb3RoZXIodGhpc19vYmplY3QoKSwiZXZhbF9ndWlsZF8iK2dpbGRlLGVuZW15LGZhYyxvZmYsZ2lsZGUpOworICBpZiAocmVzPDApIHJlcz0wOworICBpZiAocmVzPjEwMDApIHJlcz0xMDAwOworICByZXR1cm4gcmVzOworfQorCit2YXJhcmdzIG1peGVkICpldmFsX2VuZW1pZXMobWFwcGluZyBmYWMsIG1hcHBpbmcgb2ZmLCBvYmplY3QgKmhlcmUpIHsKKyAgaW50IGksc3o7CisgIG1peGVkICpyZXM7CisKKyAgcmVzPSh7fSk7CisgIGlmICghaGVyZSkKKyAgICBoZXJlPVByZXNlbnRFbmVtaWVzKCk7CisgIGlmICghcG9pbnRlcnAoaGVyZSkgfHwgIShzej1zaXplb2YoaGVyZSkpKQorICAgIHJldHVybiByZXM7CisgIGlmICghbWFwcGluZ3AoZmFjKSkgZmFjPVF1ZXJ5UHJvcChQX0VWQUxfRkFDVE9SUyk7CisgIGlmICghbWFwcGluZ3AoZmFjKSkgZmFjPShbXSk7CisgIGlmICghbWFwcGluZ3Aob2ZmKSkgb2ZmPVF1ZXJ5UHJvcChQX0VWQUxfT0ZGU0VUUyk7CisgIGlmICghbWFwcGluZ3Aob2ZmKSkgb2ZmPShbXSk7CisKKyAgZm9yIChpPXN6LTE7aT49MDtpLS0pCisgICAgcmVzKz0oeyh7aGVyZVtpXSxldmFsX2VuZW15KGhlcmVbaV0sZmFjLG9mZil9KX0pOworICByZXR1cm4gcmVzOworfQorCit2YXJhcmdzIGludCBzdW1fZXZhbF9lbmVtaWVzKG1hcHBpbmcgZmFjLCBtYXBwaW5nIG9mZiwgb2JqZWN0ICpoZXJlKSB7CisgIGludCByZXMsaTsKKyAgbWl4ZWQgKmV2YWxzLHgseTsKKworICByZXM9MDsKKyAgaWYgKCFwb2ludGVycChldmFscz1ldmFsX2VuZW1pZXMoZmFjLG9mZixoZXJlKSkpCisgICAgcmV0dXJuIHJlczsKKyAgZm9yIChpPXNpemVvZihldmFscyktMTtpPj0wO2ktLSkKKyAgICBpZiAocG9pbnRlcnAoeD1ldmFsc1tpXSkgJiYgc2l6ZW9mKHgpPj0yICYmIGludHAoeT14WzFdKSkKKyAgICAgIHJlcys9eTsKKyAgcmV0dXJuIHJlczsKK30KKwordmFyYXJncyBvYmplY3QgKm1pbmltaXplX3Byb3BfZmlsdChvYmplY3QgKmhlcmUsIG1peGVkIHByb3ApIHsKKyAgb2JqZWN0ICpvYnMsb2I7CisgIGludCBpLG1ocCxocCxzejsKKyAgCisgIG9icz0wOworICBpZiAoIXBvaW50ZXJwKGhlcmUpKQorICAgIGhlcmU9UHJlc2VudEVuZW1pZXMoKTsKKyAgaWYgKCFwcm9wKQorICAgIHByb3A9UF9IUDsKKyAgZm9yIChpPXNpemVvZihoZXJlKS0xO2k+PTA7aS0tKSB7CisgICAgaWYgKG9iamVjdHAob2I9aGVyZVtpXSkpIHsKKyAgICAgIGhwPW9iLT5RdWVyeVByb3AocHJvcCk7CisgICAgICBpZiAoIXBvaW50ZXJwKG9icykgfHwgaHA8bWhwKSB7CisJb2JzPSh7b2J9KTsKKwltaHA9aHA7CisgICAgICB9IGVsc2UgaWYgKGhwPT1taHApIHsKKwlvYnMrPSh7b2J9KTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgaWYgKCFwb2ludGVycChvYnMpKQorICAgIG9icz0oe30pOworICByZXR1cm4gb2JzOworfQorCit2YXJhcmdzIG9iamVjdCAqbWF4aW1pemVfcHJvcF9maWx0KG9iamVjdCAqaGVyZSwgbWl4ZWQgcHJvcCkgeworICBvYmplY3QgKm9icyxvYjsKKyAgaW50IGksbXdjLHdjLHN6OworICAKKyAgb2JzPTA7CisgIGlmICghcG9pbnRlcnAoaGVyZSkpCisgICAgaGVyZT1QcmVzZW50RW5lbWllcygpOworICBpZiAoIXByb3ApCisgICAgcHJvcD1QX1RPVEFMX1dDOworICBmb3IgKGk9c2l6ZW9mKGhlcmUpLTE7aT49MDtpLS0pIHsKKyAgICBpZiAob2JqZWN0cChvYj1oZXJlW2ldKSkgeworICAgICAgd2M9b2ItPlF1ZXJ5UHJvcChwcm9wKTsKKyAgICAgIGlmICghcG9pbnRlcnAob2JzKSB8fCB3Yzxtd2MpIHsKKwlvYnM9KHtvYn0pOworCW13Yz13YzsKKyAgICAgIH0gZWxzZSBpZiAod2M9PW13YykgeworCW9icys9KHtvYn0pOworICAgICAgfQorICAgIH0KKyAgfQorICBpZiAoIXBvaW50ZXJwKG9icykpCisgICAgb2JzPSh7fSk7CisgIHJldHVybiBvYnM7Cit9CisKK3ZhcmFyZ3Mgb2JqZWN0ICpwbGF5ZXJfZmlsdChvYmplY3QgKmhlcmUpIHsKKyAgb2JqZWN0ICpvYnMsb2I7CisgIGludCBpOworICAKKyAgb2JzPSh7fSk7CisgIGlmICghcG9pbnRlcnAoaGVyZSkpCisgICAgaGVyZT1QcmVzZW50RW5lbWllcygpOworICBmb3IgKGk9c2l6ZW9mKGhlcmUpLTE7aT49MDtpLS0pCisgICAgaWYgKG9iamVjdHAob2I9aGVyZVtpXSkgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvYikpCisgICAgICBvYnMrPSh7b2J9KTsKKyAgcmV0dXJuIG9iczsKK30KKwordmFyYXJncyBvYmplY3Qgc2VsZWN0X2VuZW15X21pbl9wcm9wKG9iamVjdCAqaGVyZSwgbWl4ZWQgcHJvcCkgeworICBvYmplY3QgKm9iczsKKyAgaW50IHN6OworCisgIGlmIChwb2ludGVycChvYnM9bWluaW1pemVfcHJvcF9maWx0KGhlcmUscHJvcCkpICYmIChzej1zaXplb2Yob2JzKSkpCisgICAgcmV0dXJuIG9ic1tyYW5kb20oc3opXTsKKyAgcmV0dXJuIDA7Cit9CisKK3ZhcmFyZ3Mgb2JqZWN0IHNlbGVjdF9lbmVteV9tYXhfcHJvcChvYmplY3QgKmhlcmUsIG1peGVkIHByb3ApIHsKKyAgb2JqZWN0ICpvYnM7CisgIGludCBzejsKKworICBpZiAocG9pbnRlcnAob2JzPW1heGltaXplX3Byb3BfZmlsdChoZXJlLHByb3ApKSAmJiAoc3o9c2l6ZW9mKG9icykpKQorICAgIHJldHVybiBvYnNbcmFuZG9tKHN6KV07CisgIHJldHVybiAwOworfQorCit2YXJhcmdzIG9iamVjdCBzZWxlY3RfcGxheWVyX21pbl9wcm9wKG9iamVjdCAqaGVyZSwgbWl4ZWQgcHJvcCkgeworICByZXR1cm4gc2VsZWN0X2VuZW15X21pbl9wcm9wKHBsYXllcl9maWx0KGhlcmUpLHByb3ApOworfQorCit2YXJhcmdzIG9iamVjdCBzZWxlY3RfcGxheWVyX21heF9wcm9wKG9iamVjdCAqaGVyZSwgbWl4ZWQgcHJvcCkgeworICByZXR1cm4gc2VsZWN0X2VuZW15X21heF9wcm9wKHBsYXllcl9maWx0KGhlcmUpLHByb3ApOworfQpkaWZmIC0tZ2l0IGEvc3RkL2lucGMvaXRlbXMuYyBiL3N0ZC9pbnBjL2l0ZW1zLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmFmZGQwNAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9pbnBjL2l0ZW1zLmMKQEAgLTAsMCArMSw3OCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGlucGMvaXRlbXMuYyAtLSBEaWUgcmljaHRpZ2UgQXVzcnVlc3R1bmcgdHJhZ2VuCisvLworLy8gJElkOiBpdGVtcy5jIDY1NzEgMjAwNy0xMC0yMSAxNDo0MToxMFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx0aGluZy5oPgorI2luY2x1ZGUgPGlucGMuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIHsKKyAgU2V0UHJvcChQX0lURU1TLCh7MH0pKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3ZvaWQgQWRkV2VhcG9uKHN0cmluZyBubSwgc3RyaW5nIHBhdGgpIHsKKyAgb2JqZWN0IG9iOworICBtaXhlZCAqaXQ7CisgIAorICBpZiAoIXBhdGggfHwgIW5tKSByZXR1cm47CisgIGlmIChvYj1jbG9uZV9vYmplY3QocGF0aCkpIHsKKyAgICBvYi0+bW92ZSh0aGlzX29iamVjdCgpLE1fTk9DSEVDSyk7CisgICAgY29tbWFuZCgienVlY2tlICIrbm0pOworICB9CisgIGl0PVF1ZXJ5UHJvcChQX0lURU1TKTsKKyAgaWYgKCFwb2ludGVycChpdCkgfHwgIXNpemVvZihpdCkpIGl0PSh7MH0pOworICBpdFswXT0oe29iLHBhdGgsbm19KTsKKyAgU2V0UHJvcChQX0lURU1TLGl0KTsKK30KKwordm9pZCBBZGRBcm1vdXIoc3RyaW5nIG5tLCBzdHJpbmcgcGF0aCkgeworICBvYmplY3Qgb2I7CisgIG1peGVkICppdDsKKyAgCisgIGlmICghcGF0aCB8fCAhbm0pIHJldHVybjsKKyAgaWYgKG9iPWNsb25lX29iamVjdChwYXRoKSkgeworICAgIG9iLT5tb3ZlKHRoaXNfb2JqZWN0KCksTV9OT0NIRUNLKTsKKyAgICBjb21tYW5kKCJ6aWVoICIrbm0rIiBhbiIpOworICB9CisgIGl0PVF1ZXJ5UHJvcChQX0lURU1TKTsKKyAgaWYgKCFwb2ludGVycChpdCkgfHwgIXNpemVvZihpdCkpIGl0PSh7MH0pOworICBpdCs9KHtvYixwYXRoLG5tfSk7CisgIFNldFByb3AoUF9JVEVNUyxpdCk7Cit9CisKK3ZvaWQgcmVzZXQoKSB7CisgIG1peGVkICppdCx4OworICBpbnQgaTsKKyAgb2JqZWN0IG9iOworICAKKyAgaWYgKCFwb2ludGVycChpdD1RdWVyeVByb3AoUF9JVEVNUykpKSByZXR1cm47CisgIGZvciAoaT1zaXplb2YoaXQpLTE7aT49MDtpLS0pIHsKKyAgICB4PWl0W2ldOworICAgIGlmICghcG9pbnRlcnAoeCkgfHwgc2l6ZW9mKHgpPDMpIGNvbnRpbnVlOworICAgIGlmICghb2JqZWN0cCh4WzBdKSkgeworICAgICAgaWYgKG9iPWNsb25lX29iamVjdCh4WzFdKSkKKwlvYi0+bW92ZSh0aGlzX29iamVjdCgpLE1fTk9DSEVDSyk7CisgICAgICB4WzBdPW9iOworICAgIH0KKyAgICBpZiAob2JqZWN0cCh4WzBdKSkgeworICAgICAgaWYgKGkpCisJY29tbWFuZCgiemllaCAiK3hbMl0rIiBhbiIpOworICAgICAgZWxzZQorCWNvbW1hbmQoInp1ZWNrZSAiK3hbMl0pOworICAgIH0KKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3RkL2lucGMvbm9iYW5rLmMgYi9zdGQvaW5wYy9ub2JhbmsuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42ZjA0YWVmCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2lucGMvbm9iYW5rLmMKQEAgLTAsMCArMSwxMDAgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBpbnBjL25vYmFuay5jIC0tIE5pZWRlciBtaXQgQmFua3p3ZWl0aWVzIQorLy8KKy8vICRJZDogbm9iYW5rLmMgODk2NiAyMDE0LTExLTE5IDIxOjQxOjEyWiBaZXNzdHJhICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC9saXZpbmcvbW9uZXloYW5kbGVyIjsKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxhdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8bW9uZXkuaD4KKyNkZWZpbmUgTUUgdGhpc19vYmplY3QoKQorCitpbnQgRGVlcFF1ZXJ5TW9uZXkob2JqZWN0IG9iKSB7CisgIGludCByZXMsaTsKKyAgb2JqZWN0ICpvYnM7CisgIAorICBpZiAoIW9iKSByZXR1cm4gMDsKKyAgcmVzPTA7b2JzPWRlZXBfaW52ZW50b3J5KG9iKTsKKyAgZm9yIChpPXNpemVvZihvYnMpLTE7aT49MDtpLS0pCisgICAgaWYgKChvYj1vYnNbaV0pICYmIGxvYWRfbmFtZShvYik9PUdFTEQpCisgICAgICByZXMrPW9iLT5RdWVyeVByb3AoUF9BTU9VTlQpOworICByZXR1cm4gcmVzOworfQorCitpbnQgaXNfYmFuayhvYmplY3Qgb2IpIHsKKyAgaW50ICpzdGF0cyxnZWxkOworICAKKyAgaWYgKCFvYiB8fCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvYikpIHJldHVybiAwOworICBzdGF0cz0oe29iLT5RdWVyeUF0dHJpYnV0ZShBX1NUUiksCisJICBvYi0+UXVlcnlBdHRyaWJ1dGUoQV9JTlQpLAorCSAgb2ItPlF1ZXJ5QXR0cmlidXRlKEFfREVYKSwKKwkgIG9iLT5RdWVyeUF0dHJpYnV0ZShBX0NPTiksCisJICAwfSk7CisgIHN0YXRzWzRdPXN0YXRzWzFdK3N0YXRzWzJdK3N0YXRzWzNdOworICBnZWxkPURlZXBRdWVyeU1vbmV5KG9iKTsKKyAgCisgIGlmIChzdGF0c1swXT49MTAKKyAgICAgICYmIHN0YXRzWzRdPHN0YXRzWzBdCisgICAgICAmJiBnZWxkPjUwMDAKKyAgICAgICYmIG9iLT5RdWVyeVByb3AoUF9YUCk8MzAwMDAwCisgICAgICAmJiBvYi0+UXVlcnlQcm9wKFBfUVApPDMwMCkKKyAgICByZXR1cm4gZ2VsZDsKKyAgcmV0dXJuIDA7Cit9CisKK2ludCBEZWVwVHJhbnNmZXJNb25leShvYmplY3QgcGwsIGludCBhbW91bnQpIHsKKyAgb2JqZWN0ICpvYnMsb2I7CisgIGludCBhY3QsdHJhbnMsaTsKKyAgCisgIGlmICghcGwgfHwgYW1vdW50PD0wKQorICAgIHJldHVybiAwOworICBpZiAocGwtPlF1ZXJ5TW9uZXkoKT49YW1vdW50KSB7CisgICAgcGwtPkFkZE1vbmV5KC0xKmFtb3VudCk7CisgICAgdHJhbnM9YW1vdW50OworICB9IGVsc2UgeworICAgIG9icz1kZWVwX2ludmVudG9yeShwbCk7dHJhbnM9MDsKKyAgICBmb3IgKGk9c2l6ZW9mKG9icyktMTtpPj0wO2ktLSkgeworICAgICAgaWYgKChvYj1vYnNbaV0pICYmIGxvYWRfbmFtZShvYik9PUdFTEQpIHsKKwlhY3Q9b2ItPlF1ZXJ5UHJvcChQX0FNT1VOVCk7CisJaWYgKGFjdDw9MCkgY29udGludWU7CisJaWYgKGFjdD49YW1vdW50KSB7IC8vIG1laHIgR2VsZCBhbHMgYmVub2V0aWd0PworCSAgb2ItPlNldFByb3AoUF9BTU9VTlQsYWN0LWFtb3VudCk7IC8vIGFiemllaGVuCisJICB0cmFucys9YW1vdW50OyAKKwkgIGFtb3VudD0wOyAvLyBuaWNodHMgbWVociBiZW5vZXRpZ3QKKwkgIGJyZWFrOyAgICAvLyBhbHNvIGF1Y2ggZW5kZQorCX0KKwlhbW91bnQtPWFjdDsKKwl0cmFucys9YWN0OworCW9iLT5yZW1vdmUoKTsgLy8gYWJ6aWVoZW4gd2FzIGRhIGlzdAorICAgICAgfQorICAgIH0KKyAgfQorICBsb2dfZmlsZSgic3RvbGVuX21vbmV5IiwKKwkgICBzcHJpbnRmKCIlcyAlTzogJU8gKCVPKVxuIixjdGltZSh0aW1lKCkpWzQuLjE1XSxwbCx0cmFucyxNRSkpOworICBBZGRNb25leSh0cmFucyk7CisgIHJldHVybiB0cmFuczsKK30KKwordmFyYXJncyBpbnQgVGVzdEFuZFRyYW5zZmVyKG9iamVjdCBvYiwgaW50IHRyYW5zLCBzdHJpbmcgbXNnKSB7CisgIGludCBnZWxkLGFienVnOworCisgIGlmICgoZ2VsZD1pc19iYW5rKG9iKSk8PTApIHJldHVybiAwOworICBpZiAodHJhbnM8MCkKKyAgICBhYnp1Zz0oZ2VsZCp0cmFucykvLTEwMDsgLy8gUHJvemVudHNhdHoKKyAgZWxzZQorICAgIGFienVnPXRyYW5zOyAgICAgICAgICAgICAvLyBmZXN0ZXIgQWJ6dWcKKyAgaWYgKGFienVnPmdlbGQpIGFienVnPWdlbGQ7CisgIGlmIChhYnp1Zzw9MCkgcmV0dXJuIDA7CisgIGFienVnPURlZXBUcmFuc2Zlck1vbmV5KG9iLGFienVnKTsKKyAgaWYgKGFienVnPD0wKSByZXR1cm4gMDsgIAorICBpZiAobXNnICYmIG9iKQorICAgIHRlbGxfb2JqZWN0KG9iLHNwcmludGYobXNnLGFienVnKSk7CisgIHJldHVybiBhYnp1ZzsKK30KZGlmZiAtLWdpdCBhL3N0ZC9pbnBjL3NlbGVjdC5jIGIvc3RkL2lucGMvc2VsZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDczZWJlZAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9pbnBjL3NlbGVjdC5jCkBAIC0wLDAgKzEsMzM3IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gaW5wYy9zZWxlY3QuYyAtLSBCZXN0ZSBBdXNydWVzdHVuZyBzdWNoZW4KKy8vCisvLyAkSWQ6IHNlbGVjdC5jIDY5OTggMjAwOC0wOC0yNCAxNzoxNzo0NlogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx0aGluZy5oPgorI2luY2x1ZGUgPGxpdmluZy5oPgorI2luY2x1ZGUgPGlucGMuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKworI2RlZmluZSBNRSB0aGlzX29iamVjdCgpCisKK21hcHBpbmcgc2Nhbl9vYmplY3RzKG1peGVkIHNyYykgeworICAvLyBFcm1pdHRlbHQgenUgamVkZW0gVHlwIChXYWZmZSwgUnVlc3R1bmdzdHlwLi4uKSBhbGxlIE9iamVrdGUgZGllc2VuIFR5cHMKKyAgLy8gR2VzdWNodCB3aXJkOiAtIEltIEludmVudG9yeSwgZmFsbHMgT2JqZWt0IGFuZ2VnZWJlbgorICAvLyAgICAgICAgICAgICAgIC0gSW0gQXJyYXksIGZhbGxzIEFycmF5IGFuZ2VnZWJlbgorICBvYmplY3QgKm9iczsKKyAgbWFwcGluZyByZXM7CisgIG1peGVkIHg7CisgIGludCBpLGNvc3QsY29zdF9saW1pdDsKKworICBpZiAobWFwcGluZ3Aoc3JjKSkKKyAgICByZXR1cm4gc3JjOworICByZXM9KFtdKTsKKyAgaWYgKG9iamVjdHAoc3JjKSkKKyAgICBzcmM9YWxsX2ludmVudG9yeShzcmMpOworICBpZiAoIXBvaW50ZXJwKHNyYykpCisgICAgc3JjPSh7c3JjfSk7CisgIAorICBjb3N0X2xpbWl0ID0gZ2V0X2V2YWxfY29zdCgpLzM7CisgIGZvcmVhY2gob2JqZWN0IG9iOiBzcmMpCisgIHsKKyAgICBpZiAoIChjb3N0PWdldF9ldmFsX2Nvc3QoKSkgPCBjb3N0X2xpbWl0ICkKKyAgICB7CisgICAgICBsb2dfZmlsZSgicm9jaHVzL3JhZXViZXJfZXZhbCIsCisgICAgICAgIGN0aW1lKCkrInNlbGVjdDo6c2Nhbl9vYmplY3RzKCkuIFJlc3QgIit0b19zdHJpbmcoY29zdCkrCisgICAgICAgICIsIGk9Iit0b19zdHJpbmcoaSkrIiwgU2l6ZSAiK3RvX3N0cmluZyhzaXplb2Yoc3JjKSkrIi5cbiIpOworICAgICAgcmV0dXJuIHJlczsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICBpZiAoIW9iamVjdHAob2IpKQorICAgICAgY29udGludWU7CisgICAgaWYgKHg9b2ItPlF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKSkKKyAgICAgIDsKKyAgICBlbHNlIGlmIChvYi0+UXVlcnlQcm9wKFBfV0VBUE9OX1RZUEUpKQorICAgICAgeD1PVF9XRUFQT047CisgICAgZWxzZSBpZiAob2ItPlF1ZXJ5UHJvcChQX0NPTUJBVENNRFMpKQorICAgICAgeD1PVF9DT01CQVRfT0JKRUNUOworICAgIGVsc2UKKyAgICAgIHg9T1RfTUlTQzsKKyAgICBpZiAoIXBvaW50ZXJwKG9icz1yZXNbeF0pKQorICAgICAgb2JzPSh7fSk7CisgICAgb2JzKz0oe29ifSk7CisgICAgcmVzW3hdPW9iczsKKyAgfQorICByZXR1cm4gcmVzOworfQorCittaXhlZCAqZmluZF9vYmplY3RfYnlfdHlwZShtaXhlZCBmcm9tLCBtaXhlZCB0eXApIHsKKyAgLy8gRmluZGV0IGFsbCBPYmpla3RlIGVpbmVzIFR5cHMsIHouQi4gYWxsZSBXYWZmZW4gaW0gTW9uc3RlcgorICAvLyA8ZnJvbT4ga2FubiBhdWNoIGVpbiBNYXBwaW5nIHNlaW4sIGRhcyBzY2hvbiBkaWUgbWl0IHNjYW5fb2JqZWN0cworICAvLyBlcnN0ZWxsdCBLbGFzc2lmaWthdGlvbiBlbnRoYWVsdCwgZGFtaXQgZGllc2UgbmljaHQgbWVocmZhY2gKKyAgLy8gZXJzdGVsbHQgd2VyZGVuIG11c3MuCisgIG1peGVkIHJlczsKKworICBpZiAoIW1hcHBpbmdwKGZyb20pKQorICAgIGZyb209c2Nhbl9vYmplY3RzKGZyb20pOworICBpZiAoIW1hcHBpbmdwKGZyb20pIHx8CisgICAgICAhcG9pbnRlcnAocmVzPWZyb21bdHlwXSkpCisgICAgcmV0dXJuICh7fSk7CisgIHJldHVybiByZXM7Cit9CisKK2ludCBldmFsX3dlYXBvbihvYmplY3Qgb2IpIHsKKyAgcmV0dXJuIG9iLT5RdWVyeVByb3AoUF9XQyk7Cit9CisKK29iamVjdCBmaW5kX2Jlc3Rfd2VhcG9uKG1peGVkIGZyb20pIHsKKyAgLy8gRmluZGV0IGRpZSBiZXN0ZSBXYWZmZQorICBpbnQgaSx3Yyxid2MsY29zdCxjb3N0X2xpbWl0OworICBvYmplY3QgKnJlcyxib2I7CisKKyAgaWYgKCFwb2ludGVycChyZXM9ZmluZF9vYmplY3RfYnlfdHlwZShmcm9tLCBPVF9XRUFQT04pKSkKKyAgICByZXR1cm4gMDsKKyAgYndjPS0xO2JvYj0wOworICAKKyAgY29zdF9saW1pdCA9IGdldF9ldmFsX2Nvc3QoKS8zOworICBmb3IgKGk9c2l6ZW9mKHJlcyk7aS0tOykKKyAgZm9yZWFjaChvYmplY3Qgb2I6IHJlcykKKyAgeworICAgIGlmICghb2JqZWN0cChvYikpIGNvbnRpbnVlOworICAgIHdjPWV2YWxfd2VhcG9uKG9iKTsKKyAgICBpZiAod2M+YndjKQorICAgIHsKKyAgICAgIGJvYj1vYjsKKyAgICAgIGJ3Yz13YzsKKyAgICB9CisgICAgCisgICAgaWYgKCAoY29zdD1nZXRfZXZhbF9jb3N0KCkpIDwgY29zdF9saW1pdCApCisgICAgeworICAgICAgbG9nX2ZpbGUoInJvY2h1cy9yYWV1YmVyX2V2YWwiLAorICAgICAgICAiQnJlYWsgaW4gc2VsZWN0OjpmaW5kX2Jlc3Rfd2VhcG9uKCkuIFJlc3QtVGlja3MgIit0b19zdHJpbmcoY29zdCkrCisgICAgICAgICIsIGkgPSAiK3RvX3N0cmluZyhpKSsiLCBTaXplICIrdG9fc3RyaW5nKHNpemVvZihyZXMpKSsiLlxuIik7CisgICAgICByZXR1cm4gYm9iOyAvLyB6dXJ1ZWNrZ2ViZW4sIHdhcyBiaXNoZXIgZHJpbnN0ZWh0LgorICAgICAgYnJlYWs7CisgICAgfSAKKyAgfQorICByZXR1cm4gYm9iOworfQorCit2YXJhcmdzIGludCB3aWVsZF9iZXN0X3dlYXBvbihtaXhlZCBmcm9tKSB7CisgIC8vIFp1ZWNrdCBkaWUgYmVzdGUgV2FmZmUuCisgIC8vIFNvbGx0ZSBtaXQgY29tbWFuZCgienVlY2tlX2Jlc3RlX3dhZmZlIikgYXVmZ2VydWZlbiB3ZXJkZW4sCisgIC8vIGRhbWl0IHRoaXNfcGxheWVyKCkgcmljaHRpZyBnZXNldHp0IHdpcmQuCisgIG9iamVjdCBvYixvbGQ7CisKKyAgLy8gRWluaWdlIE5QQyBtb2VnZW4ga2VpbmUgV2FmZmVuLiBadW0gQmVpc3BpZWwgS2FyYXRlLUdpbGRlbi1OUEMKKyAgLy8gRHVyY2ggU2V0emVuIHZvbiBJTlBDX0RPTlRfV0lFTERfV0VBUE9OUyBrYW5uIG1hbiBkYXMgWnVlY2tlbiB2ZXJoaW5kZXJuCisgIGlmKFF1ZXJ5UHJvcChJTlBDX0RPTlRfV0lFTERfV0VBUE9OUykpIHJldHVybiAwOworCisgIGlmICghZnJvbSkKKyAgICBmcm9tPU1FOworICAKKyAgaWYgKCFvYmplY3RwKG9iPWZpbmRfYmVzdF93ZWFwb24oZnJvbSkpKQorICAgIHJldHVybiAwOworICBpZiAob2JqZWN0cChvbGQ9UXVlcnlQcm9wKFBfV0VBUE9OKSkgJiYgb2xkIT1vYikgeworICAgIG9sZC0+UmVtb3ZlSWQoSU5QQ19CRVNUX1dFQVBPTl9JRCk7CisgICAgb2xkLT5Eb1Vud2llbGQoKTsKKyAgfQorICBpZiAoIW9iLT5pZChJTlBDX0JFU1RfV0VBUE9OX0lEKSkKKyAgICBvYi0+QWRkSWQoSU5QQ19CRVNUX1dFQVBPTl9JRCk7CisKKyAgcmV0dXJuIG9iLT5Eb1dpZWxkKCk7Cit9CisKK2ludCBldmFsX2FybW91cihvYmplY3Qgb2IpIHsKKyAgcmV0dXJuIG9iLT5RdWVyeVByb3AoUF9BQyk7Cit9CisKK29iamVjdCBmaW5kX2Jlc3RfYXJtb3VyKG1peGVkIGZyb20sIG1peGVkIHR5cCkgeworICAvLyBGaW5kZXQgZGllIGJlc3RlIFJ1ZXN0dW5nIGVpbmVzIFR5cHMKKyAgaW50IGksYWMsYmFjOworICBvYmplY3QgKnJlcyxib2I7CisgIAorICBpZiAoIXBvaW50ZXJwKHJlcz1maW5kX29iamVjdF9ieV90eXBlKGZyb20sIHR5cCkpKQorICAgIHJldHVybiAwOworICBiYWM9LTE7CisgIGJvYj0wOworICBmb3JlYWNoKG9iamVjdCBvYjogcmVzKQorICB7CisgICAgaWYgKCFvYmplY3RwKG9iKSkgY29udGludWU7CisgICAgYWM9ZXZhbF9hcm1vdXIob2IpOworICAgIGlmIChhYz5iYWMpIAorICAgIHsKKyAgICAgIGJvYj1vYjsKKyAgICAgIGJhYz1hYzsKKyAgICB9CisgIH0KKyAgcmV0dXJuIGJvYjsKK30KKworb2JqZWN0ICpmaW5kX2Jlc3RfYXJtb3VycyhtaXhlZCBmcm9tKSB7CisgIC8vIEZpbmRldCBkaWUgYmVzdGVuIFJ1ZXN0dW5nZW4sIGRpZSBnbGVpY2h6ZWl0aWcgZ2V0cmFnZW4gd2VyZGVuIGtvZW5uZW4KKyAgbWFwcGluZyBvbDsKKyAgb2JqZWN0ICpyZXMsb2I7CisgIG1peGVkICp0eXBlczsKKyAgaW50IGk7CisgIAorICBpZiAoIW1hcHBpbmdwKG9sPXNjYW5fb2JqZWN0cyhmcm9tKSkpCisgICAgcmV0dXJuICh7fSk7CisgIGlmICghcG9pbnRlcnAocmVzPW9sW0FUX01JU0NdKSkKKyAgICByZXM9KHt9KTsKKyAgdHlwZXM9bV9pbmRpY2VzKG9sKTsKKyAgZm9yZWFjaChvYmplY3QgdHlwOiB0eXBlcykKKyAgeyAKKyAgICBpZiAoVkFMSURfQVJNT1VSX0NMQVNTW3R5cF0pIC8vIGFuZGVyZXIgQXJtb3VyLVR5cCBhdXNzZXIgQVRfTUlTQz8KKyAgICB7CisgICAgICBvYj1maW5kX2Jlc3RfYXJtb3VyKGZyb20sdHlwKTsKKyAgICAgIGlmIChvYmplY3RwKG9iKSkKKwlyZXMrPSh7b2J9KTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIHJlczsKK30KKwordmFyYXJncyBpbnQgd2Vhcl9iZXN0X2FybW91cnMobWl4ZWQgZnJvbSkgeworICAvLyBEaWUgYmVzdGVuIFJ1ZXN0dW5nZW4gd2VyZGVuIGFuZ2V6b2dlbgorICAvLyBTb2xsdGUgbWl0IGNvbW1hbmQoInRyYWdlX2Jlc3RlX3J1ZXN0dW5nZW4iKSBhdWZnZXJ1ZmVuIHdlcmRlbiwKKyAgLy8gZGFtaXQgdGhpc19wbGF5ZXIoKSByaWNodGlnIGdlc2V0enQgd2lyZC4KKyAgb2JqZWN0ICpuYSwqb2EsKmRpZmY7CisgIGludCBpLGNvc3QsY29zdF9saW1pdDsKKyAgCisgIGlmICghZnJvbSkKKyAgICBmcm9tPU1FOworICBpZiAoIXBvaW50ZXJwKG5hPWZpbmRfYmVzdF9hcm1vdXJzKGZyb20pKSkKKyAgICByZXR1cm4gMDsKKyAgaWYgKCFwb2ludGVycChvYT1RdWVyeVByb3AoUF9BUk1PVVJTKSkpCisgICAgb2E9KHt9KTsKKyAgZGlmZj1vYS1uYTsKKyAgY29zdF9saW1pdCA9IGdldF9ldmFsX2Nvc3QoKS8zOworICBmb3JlYWNoKG9iamVjdCBkaTogZGlmZikKKyAgeworICAgIGRpLT5SZW1vdmVJZChJTlBDX0JFU1RfU0hJRUxEX0lEKTsKKyAgICBkaS0+RG9VbndlYXIoKTsKKyAgICBpZiAoIChjb3N0PWdldF9ldmFsX2Nvc3QoKSkgPCBjb3N0X2xpbWl0ICkKKyAgICB7CisgICAgICBsb2dfZmlsZSgicm9jaHVzL3JhZXViZXJfZXZhbCIsCisgICAgICAgIGN0aW1lKCkrIkJyZWFrIDEgaW4gc2VsZWN0Ojp3ZWFyX2Jlc3RfYXJtb3VycygpLiBSZXN0ICIrCisJdG9fc3RyaW5nKGNvc3QpKyIsIGk9Iit0b19zdHJpbmcoaSkrIiwgU2l6ZSAiKworCXRvX3N0cmluZyhzaXplb2YoZGlmZikpKyIuXG4iKTsKKyAgICAgIHJldHVybiAxOyAvLyB6dXJ1ZWNrZ2ViZW4sIHdhcyBiaXNoZXIgZHJpbnN0ZWh0LgorICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIGRpZmY9bmEtb2E7CisgIGNvc3RfbGltaXQgPSBnZXRfZXZhbF9jb3N0KCkvMzsKKyAgZm9yZWFjaChvYmplY3QgZGk6IGRpZmYpCisgIHsKKyAgICBpZiAoIGRpLT5RdWVyeVByb3AoUF9BUk1PVVJfVFlQRSk9PUFUX1NISUVMRAorICAgICAgICAgJiYgIWRpLT5pZChJTlBDX0JFU1RfU0hJRUxEX0lEKSkKKyAgICAgZGktPkFkZElkKElOUENfQkVTVF9TSElFTERfSUQpOworICAgICBkaS0+ZG9fd2VhcigiYWxsZXMiKTsKKyAgICAgaWYgKCAoY29zdD1nZXRfZXZhbF9jb3N0KCkpIDwgY29zdF9saW1pdCApCisgICAgIHsKKyAgICAgICBsb2dfZmlsZSgicm9jaHVzL3JhZXViZXJfZXZhbCIsCisgICAgICAgICBjdGltZSgpKyJCcmVhayAyIGluIHNlbGVjdDo6d2Vhcl9iZXN0X2FybW91cnMoKS4gUmVzdCAiKworCSB0b19zdHJpbmcoY29zdCkrIiwgaT0iK3RvX3N0cmluZyhpKSsiLCBTaXplICIrCisJIHRvX3N0cmluZyhzaXplb2YoZGlmZikpKyIuXG4iKTsKKyAgICAgIHJldHVybiAxOyAvLyB6dXJ1ZWNrZ2ViZW4sIHdhcyBiaXNoZXIgZHJpbnN0ZWh0LgorICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIHJldHVybiAxOworfQorCitpbnQgZXZhbF9jb21iYXRfb2JqZWN0KG9iamVjdCBvYiwgbWFwcGluZyB2YWxzLCBvYmplY3QgZW5lbXkpIHsKKyAgcmV0dXJuIDA7Cit9CisKK3ZhcmFyZ3Mgc3RyaW5nCitmaW5kX2Jlc3RfY29tYmF0X2NvbW1hbmQobWl4ZWQgZnJvbSwgb2JqZWN0IGVuZW15LCBtYXBwaW5nIHByZWYpIHsKKyAgLy8gU3VjaHQgZGVuIGd1ZW5zdGlnc3RlbiBCZWZlaGwgenVyIEJlbnV0enVuZyBlaW5lciBTb25kZXJ3YWZmZSBoZXJhdXMKKyAgb2JqZWN0ICpvYnM7CisgIG1peGVkICppbmQseSx2dWw7CisgIG1hcHBpbmcgeDsKKyAgc3RyaW5nIGJlc3Q7CisgIGludCBpLGosbWF4LHZhbCxtaHA7CisgIAorICBpZiAoIWZyb20pCisgICAgZnJvbT1NRTsKKyAgaWYgKCFlbmVteSkKKyAgICBlbmVteT1TZWxlY3RFbmVteSgpOworICBpZiAoIW1hcHBpbmdwKHByZWYpKSAvLyBiZXZvcnp1Z3RlIEVpZ2Vuc2NoYWZ0ZW4KKyAgICBwcmVmPShbQ19NSU46NSwKKwkgICBDX0FWRzoxMCwKKwkgICBDX01BWDoyLAorCSAgIENfSEVBTDoxMAorCSAgIF0pOworICBiZXN0PTA7bWF4PS0xOworICBpZiAoIXBvaW50ZXJwKG9icz1maW5kX29iamVjdF9ieV90eXBlKGZyb20sT1RfQ09NQkFUX09CSkVDVCkpKQorICAgIHJldHVybiBiZXN0OworICBtaHA9UXVlcnlQcm9wKFBfTUFYX0hQKS1RdWVyeVByb3AoUF9IUCk7CisgIGlmIChvYmplY3RwKGVuZW15KSkKKyAgICB2dWw9ZW5lbXktPlF1ZXJ5UHJvcChQX1JFU0lTVEFOQ0VfU1RSRU5HVEhTKTsKKyAgaWYgKG1ocDwwKSBtaHA9MDsKKyAgZm9yZWFjaChvYmplY3Qgb2I6IG9icykKKyAgeworICAgIGlmICghb2JqZWN0cChvYikpIAorICAgICAgY29udGludWU7CisgICAgaWYgKCFtYXBwaW5ncCh4PW9iLT5RdWVyeVByb3AoUF9DT01CQVRDTURTKSkpCisgICAgICBjb250aW51ZTsKKyAgICBpbmQ9bV9pbmRpY2VzKHgpOworICAgIGZvciAoaj1zaXplb2YoaW5kKS0xO2o+PTA7ai0tKQorICAgIHsKKyAgICAgIGlmICghc3RyaW5ncChpbmRbal0pKSBjb250aW51ZTsKKyAgICAgIHk9eFtpbmRbal1dOworICAgICAgaWYgKG1hcHBpbmdwKHkpKSAKKyAgICAgIHsKKwlpZiAodmFsPXlbQ19IRUFMXSkgCisJeworCSAgaWYgKHZhbD5taHApIHZhbD1taHA7IC8vIE51ciBNT0VHTElDSEUgSGVpbHVuZyBiZXJ1ZWNrc2ljaHRpZ2VuCisJICB2YWwqPXByZWZbQ19IRUFMXTsKKwl9IAorCWVsc2UgCisJeworCSAgdmFsPXlbQ19NSU5dKnByZWZbQ19NSU5dCisJICAgICsgeVtDX0FWR10qcHJlZltDX0FWR10KKwkgICAgKyB5W0NfTUFYXSpwcmVmW0NfTUFYXTsKKwkgIC8vIGF1c2tvbW1lbnRpZXJ0LCBkYSBldmFsX3Jlc2lzdGFuY2UoKSBiaXNoZXIgbmljaHQgaW1wbGVtZW50aWVydAorCSAgLy8gaXN0LiBaZXNzdHJhLCAwNi4wOC4yMDA3CisJICAvL2lmICh5W0NfRFRZUEVTXSAmJiB2dWwpIC8vIFZ1bG5lcmFiaWxpdHkgZGVzIEdlZ25lcnMgYmVkZW5rZW4uLi4KKwkgIC8vICB2YWw9KGludCkoKChmbG9hdCl2YWwpKigxLjArZXZhbF9yZXNpc3RhbmNlKHlbQ19EVFlQRVNdLHZ1bCkpKTsKKwl9CisgICAgICB9IAorICAgICAgZWxzZSAKKyAgICAgIHsKKwl2YWw9MTsKKyAgICAgIH0KKyAgICAgIHZhbCs9ZXZhbF9jb21iYXRfb2JqZWN0KG9ic1tpXSx5LGVuZW15KTsKKyAgICAgIGlmICh2YWw8bWF4KSBjb250aW51ZTsKKyAgICAgIG1heD12YWw7CisgICAgICBpZiAobWFwcGluZ3AoeSkgJiYgeVtDX0hFQUxdPjApCisgICAgICAgIGJlc3Q9c3ByaW50ZihpbmRbal0sbmFtZShSQVcpKTsgLy8gSGVpbHVuZyBhdWYgc2ljaCBzZWxic3QKKyAgICAgIGVsc2UgaWYgKG9iamVjdHAoZW5lbXkpKQorICAgICAgICBiZXN0PXNwcmludGYoaW5kW2pdLGVuZW15LT5uYW1lKFJBVykpOyAvLyBTY2hhZGVuIGF1ZiBHZWduZXIKKyAgICB9CisgIH0KKworICByZXR1cm4gYmVzdDsKK30KKwordmFyYXJncyBpbnQgdXNlX2Jlc3RfY29tYmF0X2NvbW1hbmQobWl4ZWQgZW5lbXksIG1peGVkIGZyb20sIG1hcHBpbmcgcHJlZikgeworICAvLyBGdWVocnQgbW9lZ2xpY2hzdCBndXRlbiBLYW1wZmVpbnNhdHogbWl0IGVpbmVyIFNvbmRlcndhZmZlIGF1cworICBzdHJpbmcgc3RyOworICAgIAorICBpZiAoc3RyaW5ncChlbmVteSkgJiYgZW52aXJvbm1lbnQoKSkKKyAgICBlbmVteT1wcmVzZW50KGVuZW15LGVudmlyb25tZW50KCkpOworICBpZiAoc3RyPWZpbmRfYmVzdF9jb21iYXRfY29tbWFuZChmcm9tLGVuZW15LHByZWYpKQorICAgIHJldHVybiBjb21tYW5kKHN0cik7CisgIHJldHVybiAwOworfQorCit2b2lkIGFkZF9zZWxlY3RfY29tbWFuZHMoKSB7CisgIGFkZF9hY3Rpb24oIndpZWxkX2Jlc3Rfd2VhcG9uIiwienVlY2tlX2Jlc3RlX3dhZmZlIik7CisgIGFkZF9hY3Rpb24oIndlYXJfYmVzdF9hcm1vdXJzIiwidHJhZ2VfYmVzdGVfcnVlc3R1bmdlbiIpOworICBhZGRfYWN0aW9uKCJ1c2VfYmVzdF9jb21iYXRfY29tbWFuZCIsImJlbnV0emVfYmVzdGVfc29uZGVyd2FmZmUiKTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9pbnBjL3dhbGtpbmcuYyBiL3N0ZC9pbnBjL3dhbGtpbmcuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMjRhYWU2Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2lucGMvd2Fsa2luZy5jCkBAIC0wLDAgKzEsMTMwIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gaW5wYy93YWxraW5nLmMgLS0gSW50ZWxsaWdlbnQgaGVydW1sYXVmZW4KKy8vCisvLyAkSWQ6IHdhbGtpbmcuYyA4NzU1IDIwMTQtMDQtMjYgMTM6MTM6NDBaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx0aGluZy5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8aW5wYy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKworI2RlZmluZSBNRSB0aGlzX29iamVjdCgpCisjZGVmaW5lIEVOViBlbnZpcm9ubWVudCgpCisKK2ludCBfc2V0X2lucGNfd2Fsa19kZWxheShpbnQgZGVsKSB7CisgIGlmIChkZWwgJiYgZGVsPDUpIGRlbD01OworICByZXR1cm4gU2V0KFBfSU5QQ19XQUxLX0RFTEFZUyxkZWwpOworfQorCittaXhlZCBfcXVlcnlfaW5wY19ob21lKCkgeworICBtaXhlZCByZXM7CisKKyAgcmVzPVF1ZXJ5KFBfSU5QQ19IT01FKTsKKyAgaWYgKCFyZXMpIHJldHVybiAiL3Jvb20vdm9pZCI7CisgIHJldHVybiByZXM7Cit9CisKK2ludCBhcmVhX2NoZWNrKHN0cmluZyBmbikgeworICBtaXhlZCBhcmVhOworICBzdHJpbmcgKndvcmRzOworICBpbnQgaTsKKworICBpZiAoIShhcmVhPVF1ZXJ5UHJvcChQX0lOUENfV0FMS19BUkVBKSkpCisgICAgcmV0dXJuIDE7IC8vIEtlaW5lIEJlc2NocmFlbmt1bmcgaW0gR2ViaWV0PworICBpZiAobWFwcGluZ3AoYXJlYSkpIHsKKyAgICBpZiAoYXJlYVtmbl0pCisgICAgICByZXR1cm4gMTsgLy8gRXhwbGl6aXQgZXJsYXVidGVyIFJhdW0KKyAgICB3b3Jkcz1vbGRfZXhwbG9kZShmbiwiLyIpOworICAgIGZvciAoaT1zaXplb2Yod29yZHMpLTI7aT49MDtpLS0pCisgICAgICBpZiAoYXJlYVtpbXBsb2RlKHdvcmRzWzAuLmldLCIvIildKQorCXJldHVybiAxOyAvLyBFcmxhdWJ0ZXMgR2ViaWV0CisgICAgcmV0dXJuIDA7IC8vIE5pY2h0IGVybGF1YnRlcyBHZWJpZXQKKyAgfQorICBpZiAocG9pbnRlcnAoYXJlYSkpIHsKKyAgICBmb3IgKGk9c2l6ZW9mKGFyZWEpLTE7aT49MDtpLS0pCisgICAgICBpZiAoZm5bMC4uKHNpemVvZihhcmVhW2ldKS0xKV09PWFyZWFbaV0pCisJcmV0dXJuIDE7IC8vIEVybGF1YnRlcyBHZWJpZXQKKyAgICByZXR1cm4gMDsgLy8gTmljaHQgZXJsYXVidGVzIEdlYmlldAorICB9CisgIHJldHVybiAxOworfQorCitpbnQgbWF5X2VudGVyX3Jvb20obWl4ZWQgcm9vbSkgeworICBpbnQgZmxhZ3M7CisgIHN0cmluZyBmbjsKKyAgb2JqZWN0IG9iOworICAKKyAgaWYgKG9iamVjdHAocm9vbSkpIHsKKyAgICBmbj1vYmplY3RfbmFtZShyb29tKTsKKyAgICBvYj1yb29tOworICB9IGVsc2UgaWYgKHN0cmluZ3Aocm9vbSkpIHsKKyAgICBmbj1yb29tOworICAgIG9iPWZpbmRfb2JqZWN0KHJvb20pOworICB9IGVsc2UKKyAgICByZXR1cm4gMTsgLy8gRGFubiBzb2xsdGUgbW92ZSBzY2hvbiBuZW4gRmVobGVyIG1hY2hlbgorICBpZiAoZm49PSIvcm9vbS92b2lkIikgLy8gVm9pZCBkYXJmIElNTUVSIGJldHJldGVuIHdlcmRlbgorICAgIHJldHVybiAxOworICBmbGFncz1RdWVyeVByb3AoUF9JTlBDX1dBTEtfRkxBR1MpOworICBpZiAoIShmbGFncyAmIFdGX01BWV9MT0FEKQorICAgICAgJiYgIW9iamVjdHAob2IpKQorICAgIHJldHVybiAwOyAvLyBEYXJmIG5pY2h0IGluIG5pY2h0IGdlbGFkZW5lIFJhZXVtZSBmb2xnZW4uCisgIGlmICghKGZsYWdzICYgV0ZfTUFZX1dBTEtfQkFDSykKKyAgICAgICYmIG9iPT1RdWVyeVByb3AoUF9JTlBDX0xBU1RfRU5WSVJPTk1FTlQpKQorICAgIHJldHVybiAwOyAvLyBEYXJmIG5pY2h0IGluIGRlbiB2b3JoZXJpZ2VuIFJhdW0KKyAgcmV0dXJuIGFyZWFfY2hlY2soZm4pOworfQorCitpbnQgd2Fsa19yYW5kb20oKSB7CisgIHN0cmluZyAqZXgsKmV4MjsKKyAgb2JqZWN0IGVudjsKKyAgaW50IGkscixmbGFnczsKKyAgCisgIGlmICghb2JqZWN0cChlbnY9RU5WKSkKKyAgICByZXR1cm4gMDsKKyAgZXg9bV9pbmRpY2VzKEVOVi0+UXVlcnlQcm9wKFBfRVhJVFMpKTsKKyAgZmxhZ3M9UXVlcnlQcm9wKFBfQ0FOX0ZMQUdTKTsKKyAgaWYgKGZsYWdzICYgV0ZfTUFZX1VTRV9TUEVDSUFMKQorICAgIGV4Kz1tX2luZGljZXMoRU5WLT5RdWVyeVByb3AoUF9TUEVDSUFMX0VYSVRTKSk7CisgIGV4Mj1leFswLi5dOworICB3aGlsZSAoaT1zaXplb2YoZXgpKSB7CisgICAgcj1yYW5kb20oaSk7CisgICAgY29tbWFuZChleFtyXSk7CisgICAgaWYgKEVOViE9ZW52KQorICAgICAgcmV0dXJuIDE7CisgICAgZXgtPSh7ZXhbcl19KTsKKyAgfQorICBpZiAoIShmbGFncyAmIFdGX01BWV9XQUxLX0JBQ0spKSB7CisgICAgU2V0UHJvcChQX0lOUENfTEFTVF9FTlZJUk9OTUVOVCwwKTsvL0RpcnR5IEhhY2ssIHVtIFNhY2tnYXNzZW4genUgdmVybGFzc2VuCisgICAgZXg9ZXgyOworICAgIHdoaWxlIChpPXNpemVvZihleCkpIHsKKyAgICAgIHI9cmFuZG9tKGkpOworICAgICAgY29tbWFuZChleFtyXSk7CisgICAgICBpZiAoRU5WIT1lbnYpCisJcmV0dXJuIDE7CisgICAgICBleC09KHtleFtyXX0pOworICAgIH0KKyAgfQorICByZXR1cm4gbW92ZShRdWVyeVByb3AoUF9JTlBDX0hPTUUpLE1fVFBPUlQpOworfQorCitpbnQgd2Fsa19yb3V0ZSgpIHsKK30KKworaW50IHdhbGtfdG8oKSB7Cit9CisKK2ludCB3YWxrX2ZvbGxvdygpIHsKK30KKworaW50IHdhbGtfZmxlZSgpIHsKK30KZGlmZiAtLWdpdCBhL3N0ZC9pdGVtcy9maXNoaW5nL2FuZ2VsLmMgYi9zdGQvaXRlbXMvZmlzaGluZy9hbmdlbC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFiNTcwOWYKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvaXRlbXMvZmlzaGluZy9hbmdlbC5jCkBAIC0wLDAgKzEsNTEwIEBACisvKgorICBadXNhbW1lbmZhc3N1bmcgQmVkaW5ndW5nZW46CisgIC0gQW5nZWwgYXVzd2VyZmVuCisgICAgICAtIEhha2VuIG11c3MgZHJhbiBzZWluCisgICAgICAtIEhha2VuIG11c3MgS29lZGVyIGhhYmVuCisgICAgICAtIGRhcmYgbnVyIGVpbiBIYWtlbiBkcmluIHNlaW4sIHNvbnN0IG5peCwgdW5kIGdlbmF1IGVpbiBIYWtlbgorICAgICAgLSBBbmdlbCBpbSBJbnZlbnRhcgorICAgICAgLSBBbmdlbCBkYXJmIG5pY2h0IHNjaG9uIGF1c2dld29yZmVuIHNlaW4KKyAgICAgIC0gcGFzc2VuZGVzIEdld2Flc3NlciBpbSBSYXVtCisgICAgICAtIE1vdmUtSG9vayBtdXNzIGtvcnJla3QgcmVnaXN0cmllcmJhciBzZWluCisgIC0gQW5nZWwgZWluaG9sZW4KKyAgICAgIC0gQW5nZWwtQ2FsbG91dCBtdXNzIHVlYmVyaGF1cHQgZXJzdG1hbCBsYXVmZW4KKyAgLSBXYWVocmVuZCBkZXMgQW5nZWxucworICAgICAgLSBiZXdlZ2VuIGJlZW5kZXQgZGFzIEFuZ2VsbgorICAgICAgLSBBdXNsb2dnZW4gYmVlbmRldCBkYXMgQW5nZWxuCisgICAgICAtIEVuZGUgYmVlbmRldCBkYXMgQW5nZWxuCisgICAgICAtIG5pY2h0cyByYXVzbmVobWVuCisgICAgICAtIG5pY2h0cyByZWludHVuLCBhdXNzZXIgRmlzY2ggYW0gRW5kZSBkZXIgV2FydGV6ZWl0CisgICAgICAtIExhbmdiZXNjaHJlaWJ1bmcgemVpZ3QgImF1c2dld29yZmVuIiwgS29lZGVyIHVuZCBnZWZhbmdlbmVuIEZpc2NoIGFuCisgIC0gRmlzY2ggZmFuZ2VuIChjYWxsX291dCB6dWVuZGUpCisgICAgICAtIEdld2Flc3NlciBwYXNzdCAoaW1tZXIgbm9jaCkKKyAgICAgIC0gRmlzY2ggcGFzc3Qgbm9jaCBpbiBkaWUgQW5nZWwgcmVpbgorICAtIEhha2VuIGRyYW5oYWVuZ2VuCisgICAgICAtIEhha2VuIGltIEludgorICAgICAgLSBIYWtlbiBtdXNzICJlY2h0ZXIiIEFuZ2VsaGFrZW4gc2VpbgorICAgICAgLSBBbmdlbCBpbSBJbnYKKyAgICAgIC0gS29lZGVyIGFtIEhha2VuCisgICAgICAtIG5vY2gga2VpbiBhbmRlcmVyIEtvZWRlciBkcmFuCisgICAgICAtIEFuZ2VsIGlzdCBuaWNodCBhdXNnZXdvcmZlbgorICAtIGdlbmVyZWxsCisgICAgICAtIG51ciBIYWtlbiBkcmFuc3RlY2tlbiwgbml4IGFuZGVyZXMgcmVpbnR1bgorICAgICAgLSByZWludHVuIG51ciBtaXQgU3ludGF4ICJoYWVuZ2UiIGV0Yy4gKGRhbWl0IHNpbmQgRmlzY2hlIGF1c3NlbiB2b3IsCisgICAgICAgIHdlaWwgZGllIFN5bnRheCBhdWYgSGFrZW4gcHJ1ZWZ0KQorICAgICAgICAoZ2dmLiBpc3QgZGFubiBkYXMgUHJldmVudEluc2VydCgpIHp1IHZlcmVpbmZhY2hlbikKKyAqLworCisjcHJhZ21hIHN0cm9uZ190eXBlcywgc2F2ZV90eXBlcywgcnR0X2NoZWNrcworI3ByYWdtYSBub19jbG9uZSwgbm9fc2hhZG93CisKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyIjsKK2luaGVyaXQgIi9zdGQvaG9va19jb25zdW1lciI7CisKKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8aG9vay5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGl0ZW1zL2Zpc2hpbmcvZmlzaGluZy5oPgorI2luY2x1ZGUgPGl0ZW1zL2Zpc2hpbmcvYXF1YXJpdW0uaD4KKworI2RlZmluZSBUUCB0aGlzX3BsYXllcigpCisjZGVmaW5lIE1FIHRoaXNfb2JqZWN0KCkKKyNkZWZpbmUgQlMoeCkgYnJlYWtfc3RyaW5nKHgsIDc4KQorCisjZGVmaW5lIE1JTl9ERUxBWSAgICAgICA4MCAgIC8vIE1pbmRlc3RkZWxheSBiaXMgRmlzY2ggYmVpc3N0IQorI2RlZmluZSBTVERfREVMQVlfUExVUyAgNjAgICAvLyAgKy8tIDYwIHNla3VuZGVuIFRvbGVyYW50CisjZGVmaW5lIE1BWF9GSVNIX0JPTlVTICA2MCAgIC8vIG1heC4gV2FydGV6ZWl0dmVya3Vlcnp1bmcgZHVyY2ggUF9GSVNICisjZGVmaW5lIFdST05HV0FURVIgICAgICA2MCAgIC8vIDEtMiBtaW4sIGZhbGxzIEFuZ2VsIG5pY2h0IGdlZWlnbmV0CisjZGVmaW5lIFdST05HV09STSAgICAgICA2MCAgIC8vIDEtMiBtaW4sIGZhbGxzIEtvZWRlciBuaWNodCBnZWVpZ25ldAorCisjZGVmaW5lIEtPRURFUl9MT1NUICAgICAxMAorLy8gVmVybHVzdHdhaHJzY2guIGZ1ZXIgS29lZGVyIGZhbGxzIEZpc2NoIHp1IHNjaHdlcgorCitwcml2YXRlIG9iamVjdCByb29tLCBjdXJyZW50X3VzZXI7Citwcml2YXRlIGludCBhY3RpdmUsIGFjdGltZTsKK3ByaXZhdGUgbWFwcGluZyBhcXVhcml1bSA9IFNUREZJU0hMSVNUOworCitub21hc2sgdmFyYXJncyB2b2lkIFN0b3BGaXNoaW5nKHN0cmluZyBtc2dfbWUsIHN0cmluZyBtc2dfcm9vbSk7CitpbnQgSXNGaXNoaW5nKCk7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIHsKKyAgOjpjcmVhdGUoKTsKKyAgCisgIFNldFByb3AoUF9TSE9SVCwgIkVpbmUgQW5nZWwiKTsKKyAgU2V0UHJvcChQX0xPTkcsICJFaW5lIG5hZ2VsbmV1ZSBBbmdlbC5cbiIpOworICBTZXRQcm9wKFBfTkFNRSwgIkFuZ2VsIik7CisgIEFkZElkKCh7ImFuZ2VsIiwgInJ1dGUiLCBBTkdFTF9JRH0pKTsKKworICBTZXRQcm9wKFBfR0VOREVSLCBGRU1BTEUpOworICBTZXRQcm9wKFBfTUFURVJJQUwsKFtNQVRfTUlTQ19XT09EOjkwLE1BVF9XT09MOjEwXSkpOworICBTZXRQcm9wKFBfVFJBTlNQQVJFTlQsMSk7CisgIFNldFByb3AoUF9XRUlHSFQsMjAwKTsKKyAgU2V0UHJvcChQX01BWF9XRUlHSFQsIDEwMDAwKTsKKyAgU2V0UHJvcChQX1dBVEVSLCBXX1VTRVIpOyAgICAgLy9tdXNzIChtZWhyZXJlKSBGbGFncyBnZXNldHp0IGhhYmVuIQorICBTZXRQcm9wKFBfU09VUkNFX1BSRVBPU0lUSU9OLCAidm9uIik7CisgIFNldFByb3AoUF9OUl9IQU5EUywgMik7IAorCisgIFNldChQX05PRFJPUCwgZnVuY3Rpb24gc3RyaW5nICgpIHsKKyAgICByZXR1cm4gKElzRmlzaGluZygpPyJEdSBzb2xsdGVzdCBkaWUgQW5nZWwgbmljaHQgZmFsbGVubGFzc2VuLCBzb2xhbmdlICIKKyAgICAgICJEdSBhbmdlbHN0LlxuIjowKTsKKyAgfSwgRl9RVUVSWV9NRVRIT0QpOworCisgIEFkZENtZCgoeyJhbmdlbCIsImFuZ2xlIn0pLCJhbmdlbCIpOworICBBZGRDbWQoImhvbGV8aG9sJkBJRCZlaW4iLCAic3RvcGl0IiwgIldhcyB3aWxsc3QgRHUgKGVpbilob2xlbj98IgorICAgICJXaWxsc3QgRHUgQFdFTjIgZWluaG9sZW4/Iik7CisgIEFkZENtZCgiaGFlbmdlfGhhZW5nfGJlZmVzdGlnZSZAUFJFU0VOVCZASUQiLCAibW92ZV9pbiIsCisgICAgIldhcyB3aWxsc3QgRHUgd29yYW4gQHZlcmJlbj98IgorICAgICJXb3JhbiB3aWxsc3QgRHUgQFdFTjIgZGVubiBAdmVyYmVuPyIpOworCisgIEFkZENtZCgiYXRlbGwiLCJ0ZWxsX3N0YXQiKTsKKyAgQWRkQ21kKCJhbmdlbHRlc3QiLCJxYW5nZWwiKTsKK30KKyAKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorICAgICAKK3N0YXRpYyBpbnQgc3RvcGl0KHN0cmluZyBzdHIpIHsKKyAgaWYoIGZpbmRfY2FsbF9vdXQoImRvX2FuZ2VsIik9PS0xICkKKyAgICB0ZWxsX29iamVjdChUUCwgIkR1IGFuZ2Vsc3QgbmljaHQhXG5UUCwgIik7CisgIGVsc2UgCisgICAgU3RvcEZpc2hpbmcoKTsKKyAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3Mgc3RyaW5nIGxvbmcoaW50IG1vZGUpIHsKKyAgc3RyaW5nIGRlc2NyID0gUXVlcnlQcm9wKFBfTE9ORyk7CisgIGlmKCFRdWVyeVByb3AoUF9UUkFOU1BBUkVOVCkpIAorICAgIHJldHVybiBkZXNjcjsKKworICBpZiAoIGZpbmRfY2FsbF9vdXQoImRvX2FuZ2VsIikhPS0xICkKKyAgICBkZXNjciArPSBjYXBpdGFsaXplKFF1ZXJ5UHJvbm91bihXRVIpKSAgKyAiIGlzdCBhdXNnZXdvcmZlbi5cbiI7CisKKyAgb2JqZWN0ICppbnYgPSBhbGxfaW52ZW50b3J5KE1FKTsKKyAgc3RyaW5nIGludl9kZXNjciA9IG1ha2VfaW52bGlzdChUUCwgaW52KTsKKyAgaWYgKCBpbnZfZGVzY3IgIT0gIiIgKQorICAgIGRlc2NyICs9ICJBbiAiK1F1ZXJ5UHJvbm91bihXRU0pICsgIiBoYWVuZyIrKHNpemVvZihpbnYpPjE/ImVuIjoidCIpKworICAgICI6XG4iICsgaW52X2Rlc2NyOworICAKKyAgcmV0dXJuIGRlc2NyOworfQorCisvKmludCB0ZWxsX3N0YXQoKQoreworICBpbnQgbjsKKyAgCisgIGlmKCFJU19XSVpBUkQoVFApKQorICAgIHJldHVybiAwOworICBpZighYWN0aXZlKXsgCisgICAgd3JpdGUoIkR1IGFuZ2Vsc3QgbmljaHRcbiIpOyByZXR1cm4gMTsgCisgIH0KKyAgbj1maW5kX2NhbGxfb3V0KCJkb19hbmdlbCIpOworICBpZihhY3RpdmUpCisgICAgd3JpdGUoCisgICAgICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iCisgICAgICsiRGVyIEZpc2NoIGJlaXNzdCBpbiAiK24rIiBzZWMhXG4iCisgICAgICsiQmVzdGFuZHN3ZXJ0IGRlcyBSYXVtZXM6ICIrcm9vbS0+UXVlcnlQcm9wKFBfRklTSCkKKyAgICAgKyIgPSAiKyhyb29tLT5RdWVyeVByb3AoUF9GSVNIKSsxMDApKyIlLlxuIgorICAgICArIkJlc3RhbmRzd2VydCBkZXMgS29lZGVyczogIitrb2VkZXItPlF1ZXJ5UHJvcChQX0ZJU0gpCisgICAgICsiID0gIisoMTAwK2tvZWRlci0+UXVlcnlQcm9wKFBfRklTSCkpKyIlLlxuIgorICAgICArIkdlc2FtdDoiK2Jlc3RhbmQrIiA9ICIrKGJlc3RhbmQrMTAwKSsiJS5cbiIpOworICBpZighKFF1ZXJ5UHJvcChQX1dBVEVSKSZyb29tLT5RdWVyeVByb3AoUF9XQVRFUikpKQorICAgIHdyaXRlKCJEaWUgQW5nZWwgcGFzc3QgbmljaHQgenVtIEdld2Flc3NlcnR5cGVuLlxuIik7CisgIGVsc2UKKyAgICB3cml0ZSgiRGllIEFuZ2VsIHBhc3N0IHp1bSBHZXdhZXNzZXJ0eXBlbi5cbiIpOworICBpZighKHJvb20tPlF1ZXJ5UHJvcChQX1dBVEVSKSZrb2VkZXItPlF1ZXJ5UHJvcChQX1dBVEVSKSkpCisgICAgd3JpdGUoIkRlciBLb2VkZXIgcGFzc3QgbmljaHQgenVtIEdld2Flc3NlcnR5cGVuLlxuIik7CisgIGVsc2UKKyAgICB3cml0ZSgiRGVyIEtvZWRlciBwYXNzdCB6dW0gR2V3YWVzc2VydHlwZW4uXG4iKTsKKyAgd3JpdGUoIiA9PiBEZWxheT0iK2RlbGF5KyIuXG4iCisgICAgKyItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iCispOworICByZXR1cm4gMTsKK30qLworCitzdGF0aWMgaW50IG1vdmVfaW4oc3RyaW5nIHN0ciwgbWl4ZWQgKnBhcmFtKSB7CisgIG9iamVjdCBoYWtlbiA9IHBhcmFtWzBdOworICAvLyBwYXJhbVsxXSBzaW5kIHdpciBzZWxic3QsIGRhaGVyIGFiIGhpZXIgTUUgdmVyd2VuZGV0LgorCisgIGlmICggZmluZF9jYWxsX291dCgiZG9fYW5nZWwiKSE9LTEgKSB7IC8vIGFuZ2VsdCBub2NoIG5pY2h0PworICAgIHRlbGxfb2JqZWN0KFRQLCBCUyhOYW1lKFdFUiwxKSsiIGlzdCBiZXJlaXRzIGF1c2dld29yZmVuLCBkYSBoYWVuZ3N0ICIKKyAgICAgICJEdSBqZXR6dCBiZXNzZXIgbmljaHRzIG1laHIgZHJhbiwgZGFzIHZlcnRyZWlidCBudXIgZGllIEZpc2NoZS4iKSk7CisgIH0KKyAgZWxzZSBpZiAoICFoYWtlbi0+aWQoSEFLRU5fSUQpICkgeyAvLyBlY2h0ZXIgQW5nZWxoYWtlbj8KKyAgICB0ZWxsX29iamVjdChUUCwgQlMoaGFrZW4tPk5hbWUoV0VSLDEpKyIgaXN0IGtlaW4gQW5nZWxoYWtlbiwgIisKKyAgICAgIGhha2VuLT5RdWVyeUFydGljbGUoV0VOLCAxLCAxKSsia2FubnN0IER1IG5pY2h0IGFuICIrbmFtZShXRU4sMSkrCisgICAgICAiIGhhZW5nZW4uIikpOworICB9CisgIGVsc2UgaWYgKCBlbnZpcm9ubWVudChoYWtlbikgIT0gVFAgKSB7IC8vIEhha2VuIGltIEludj8KKyAgICB0ZWxsX29iamVjdChUUCwgQlMoIldpZSBlciBkYSBzbyBhdWYgZGVtIEJvZGVuIGxpZWd0LCBzY2hhZmZzdCBEdSBlcyAiCisgICAgICAiZWluZmFjaCBuaWNodCwgIitoYWtlbi0+bmFtZShXRU4sMSkrIiB2ZXJudWVuZnRpZyBhbiAiK25hbWUoV0VNLDEpKworICAgICAgIiB6dSBiZWZlc3RpZ2VuLiIpKTsKKyAgfQorICBlbHNlIGlmICggZW52aXJvbm1lbnQoTUUpICE9IFRQICkgeyAvLyBBbmdlbCBpbSBJbnY/CisgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJFcyBzdGVsbHQgc2ljaCB2aWVsIGZ1bW1lbGlnZXIgaGVyYXVzIGFscyBnZWRhY2h0LCAiKworICAgICAgaGFrZW4tPm5hbWUoV0VOLDEpKyIgYW4gIituYW1lKFdFTSwxKSsiIHp1IGJlZmVzdGlnZW4sIHNvbGFuZ2UgIisKKyAgICAgIFF1ZXJ5UHJvbm91bihXRVIpKyIgYXVmIGRlbSBCb2RlbiBoZXJ1bWxpZWd0LiIpKTsKKyAgfQorICBlbHNlIGlmICggcHJlc2VudChIQUtFTl9JRCwgTUUpICkgeyAvLyBhbmRlcmVyIEhha2VuIHNjaG9uIGRyYW4/CisgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJBbiAiK25hbWUoV0VNLDEpKyIgaGFlbmd0IGJlcmVpdHMgZWluIEFuZ2VsaGFrZW4uIikpOworICB9CisgIGVsc2UgaWYgKCAhaGFrZW4tPlF1ZXJ5S29lZGVyKCkgKSB7IC8vIEtvZWRlciBhbSBIYWtlbj8KKyAgICB0ZWxsX29iamVjdChUUCwgQlMoIkR1IHdpbGxzdCAiK2hha2VuLT5uYW1lKFdFTiwxKSsiIGdlcmFkZSBhbiAiKworICAgICAgbmFtZShXRU4sMSkrIiBoYWVuZ2VuLCBhbHMgRGlyIGF1ZmZhZWxsdCwgZGFzcyBEdSBiZWluYWhlIGRlbiBLb2VkZXIgIgorICAgICAgInZlcmdlc3NlbiBoYWV0dGVzdC4iKSk7CisgIH0KKyAgZWxzZSB7IC8vIGRhbm4gZGFyZiBkZXIgSGFrZW4gcmFuZ2VoYWVuZ3Qgd2VyZGVuLgorICAgIGlmICggaGFrZW4tPm1vdmUoTUUsIE1fUFVUKSA9PSBNT1ZFX09LICkgeworICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJEdSBoYWVuZ3N0ICIraGFrZW4tPm5hbWUoV0VOLDEpKyIgYW4gIisKKyAgICAgICAgbmFtZShXRU4sMSkrIi4iKSk7CisgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoVFApLCBCUyhUUC0+TmFtZShXRVIpKyIgaGFlbmd0IGV0d2FzIG1ldGFsbGlzY2ggIgorICAgICAgICAiR2xhZW56ZW5kZXMgYW4gIituYW1lKFdFTikrIiwgdmVybXV0bGljaCBlaW5lbiBBbmdlbGhha2VuLiIpLCAKKyAgICAgICAgKHtUUH0pKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICB0ZWxsX29iamVjdChUUCwgQlMoaGFrZW4tPk5hbWUoV0VSLDEpKyIgbGFlc3N0IHNpY2ggbmljaHQgYW4gIisKKyAgICAgICAgbmFtZShXRU0sMSkrIiBiZWZlc3RpZ2VuLiIpKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgcWFuZ2VsKCkgeworICBpZihJU19XSVpBUkQoVFApKSB7CisgICAgY2FsbF9vdXQoImRvX2FuZ2VsIiwxKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworc3RhdGljIGludCBhbmdlbChzdHJpbmcgc3RyKSB7CisgIG9iamVjdCBoYWtlbiA9IHByZXNlbnQoSEFLRU5fSUQsTUUpOworICBpZiAoIGVudmlyb25tZW50KE1FKSAhPSBUUCApIHsKKyAgICB0ZWxsX29iamVjdChUUCwgQlMoIkRhZnVlciBtdXNzdCBEdSBkaWUgQW5nZWwgaW4gZGllIEhhbmQgbmVobWVuLiIpKTsKKyAgfQorICBlbHNlIGlmICggZmluZF9jYWxsX291dCgiZG9fYW5nZWwiKSE9LTEgKSB7CisgICAgdGVsbF9vYmplY3QoVFAsICJEYXMgdHVzdCBEdSBkb2NoIHNjaG9uLlxuIik7CisgIH0KKyAgZWxzZSBpZighb2JqZWN0cChoYWtlbikpIHsKKyAgICB0ZWxsX29iamVjdChUUCwgIldpZSBzb2xsIGRhcyBnZWhlbj8gRHUgaGFzdCBqYSBuaWNodG1hbCBlaW5lbiBIYWtlbiAiCisgICAgICAiYW4gZGVyIEFuZ2VsIVxuIik7CisgIH0KKyAgZWxzZSBpZighaGFrZW4tPlF1ZXJ5S29lZGVyKCkpIHsKKyAgICB0ZWxsX29iamVjdChUUCwgYnJlYWtfc3RyaW5nKCJPaG5lIEtvZWRlciBhbSBIYWtlbiB3aXJkIHNpY2gga2VpbiAiCisgICAgICAiRmlzY2ggZGVyIFdlbHQgZnVlciBEZWluZSBBbmdlbCBpbnRlcmVzc2llcmVuLiIsNzgpKTsKKyAgfQorICBlbHNlIGlmKHByZXNlbnQoRklTQ0hfSUQsTUUpKSB7CisgICAgdGVsbF9vYmplY3QoVFAsICJOaW1tIGVyc3QgbWFsIGRpZSBCZXV0ZSB2b24gZGVyIEFuZ2VsLCBkaWUgbm9jaCBkYXJhbiAiCisgICAgICAiemFwcGVsdCFcbiIpOworICB9CisgIGVsc2UgaWYgKCAhVFAtPlVzZUhhbmRzKE1FLCBRdWVyeVByb3AoUF9OUl9IQU5EUykpICkgeyAvLyBmcmVpZSBIYWVuZGU/CisgICAgdGVsbF9vYmplY3QoVFAsIEJTKCJEdSBtdXNzdCBzY2hvbiBiZWlkZSBIYWVuZGUgZnJlaSBoYWJlbiwgdW0gZGllICIKKyAgICAgICJBbmdlbCBzaWNoZXIgZmVzdGhhbHRlbiB6dSBrb2VubmVuLiIpKTsKKyAgfQorICBlbHNlIHsKKyAgICAvLyBSYXVtIGZlc3RoYWx0ZW4sIGluIGRlbSBnZWFuZ2VsdCB3aXJkLgorICAgIHJvb20gPSBlbnZpcm9ubWVudChUUCk7CisgICAgLy8gR2V3YWVzc2VydHlwIGFiZnJhZ2VuCisgICAgYWN0aXZlID0gcm9vbS0+UXVlcnlQcm9wKFBfV0FURVIpOworICAgIC8vIEtlaW4gV2Fzc2VyIHZvcmhhbmRlbiwgb2RlciBuaWNodC1iZWZpc2NoYmFyZXIgU29uZGVydHlwPworICAgIGlmKCAoIWFjdGl2ZSkgfHwgKGFjdGl2ZSAmIFdfT1RIRVIpICkgeworICAgICAgdGVsbF9vYmplY3QoVFAsICJEdSBrYW5uc3QgaGllciBuaWNodCBhbmdlbG4uXG4iKTsKKyAgICAgIFRQLT5GcmVlSGFuZHMoTUUpOworICAgIH0KKyAgICAvLyB0b3RlcyBHZXdhZXNzZXIgZXJ3aXNjaHQKKyAgICBlbHNlIGlmICggYWN0aXZlICYgV19ERUFEICkgeworICAgICAgd3JpdGUoIkluIGRlbSBHZXdhZXNzZXIgaGllciBnaWJ0IGVzIGtlaW5lIEZpc2NoZS5cbiIpOworICAgICAgVFAtPkZyZWVIYW5kcyhNRSk7CisgICAgfQorICAgIC8vIEpldHp0IGFiZXI6IGVzIGdpYnQgRmlzY2gsIEJhYnkuIDstKQorICAgIGVsc2UgeworICAgICAgaW50IGRlbGF5ID0gTUlOX0RFTEFZOyAvLyA4MCBTZWt1bmRlbi4KKyAgICAgIC8vIEZpc2NoYmVzdGFuZCBlcm1pdHRlbG4gYXVzIFJhdW0tIHVuZCBLb2VkZXJwYXJhbWV0ZXJuCisgICAgICBpbnQgYm9udXMgPSByb29tLT5RdWVyeVByb3AoUF9GSVNIKSArIGhha2VuLT5RdWVyeVByb3AoUF9GSVNIKTsKKyAgICAgIC8vIElzdCBrZWluIEJvbnVzLCBzb25kZXJuIGVpbiBNYWx1cyByYXVzZ2Vrb21tZW4/CisgICAgICBpZiAoIGJvbnVzIDwgMCApIHsKKyAgICAgICAgLy8gRGFubiBiZWdyZW56ZW4gYXVmIDUgTWluLgorICAgICAgICBpZiAoIGJvbnVzIDwgLTMwMCApCisgICAgICAgICAgYm9udXMgPSAtMzAwOworICAgICAgICAvLyBXYXJ0ZXplaXQgZXJob2VoZW4uCisgICAgICAgIGRlbGF5ICs9IHJhbmRvbSgtYm9udXMpOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIC8vIEJvbnVzIGRlY2tlbG4gYXVmIE1heC1XZXJ0ICg2MCBTZWt1bmRlbikKKyAgICAgICAgaWYgKCBib251cyA+IE1BWF9GSVNIX0JPTlVTICkgeworICAgICAgICAgIGJvbnVzID0gTUFYX0ZJU0hfQk9OVVM7CisgICAgICAgIH0KKyAgICAgICAgLy8gRGVsYXkgcmVkdXppZXJlbiAobWluaW1hbCAyMCBTZWt1bmRlbikKKyAgICAgICAgZGVsYXkgLT0gcmFuZG9tKGJvbnVzKTsKKyAgICAgIH0KKyAgCisgICAgICAvLyBwYXNzdCBkYXMgR2V3YWVzc2VyIHp1ciBBbmdlbC96dW0gS29lZGVyID8KKyAgICAgIGlmKCAhKFF1ZXJ5UHJvcChQX1dBVEVSKSAmIHJvb20tPlF1ZXJ5UHJvcChQX1dBVEVSKSkgKQorICAgICAgICBkZWxheSArPSBXUk9OR1dBVEVSICsgcmFuZG9tKFdST05HV0FURVIpOworICAgICAgaWYoICEocm9vbS0+UXVlcnlQcm9wKFBfV0FURVIpICYgaGFrZW4tPlF1ZXJ5UHJvcChQX1dBVEVSKSkgJiYKKyAgICAgICAgICByb29tLT5RdWVyeVByb3AoUF9XQVRFUikgIT0gV19VU0VSICkKKyAgICAgICAgZGVsYXkgKz0gV1JPTkdXT1JNICsgcmFuZG9tKFdST05HV09STSk7CisKKyAgICAgIGludCBob29rID0gVFAtPkhSZWdpc3RlclRvSG9vayhIX0hPT0tfTU9WRSwgTUUsIEhfSE9PS19PVEhFUlBSSU8oMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSF9MSVNURU5FUiwgMCk7CisgICAgICBpZiAoIGhvb2sgIT0gMSApIHsKKyAgICAgICAgYWN0aXZlID0gMDsKKyAgICAgICAgcm9vbSA9IDA7CisgICAgICAgIFRQLT5GcmVlSGFuZHMoTUUpOworICAgICAgICB0ZWxsX29iamVjdChUUCwgQlMoCisgICAgICAgICAgIkR1IHNjaGxldWRlcnN0IGRpZSBBbmdlbCBtaXQgU2Nod3VuZyBpbiBSaWNodHVuZyBXYXNzZXIsIGFiZXIgZGVyICIKKyAgICAgICAgICAiSGFrZW4gdmVyZmFlbmd0IHNpY2ggaW4gRGVpbmVuIFNhY2hlbiB1bmQgcGlla3N0IERpciBpbiBkZW4gIgorICAgICAgICAgICJBbGxlcndlcnRlc3Rlbi4gRGFzIHZlcnN1Y2hzdCBEdSBiZXNzZXIgbm9jaCBlaW5tYWwgYW5kZXJzLiIpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KFRQKSwgQlMoCisgICAgICAgICAgVFAtPk5hbWUoKSsiIHNjaGxldWRlcnQgZWluZSBBbmdlbCBpbiBSaWNodHVuZyBXYXNzZXIsIGlzdCBkYWJlaSAiCisgICAgICAgICAgImFiZXIgc28gdW5nZXNjaGlja3QsIGRhc3Mgc2ljaCBkZXIgSGFrZW4gdmVyZmFlbmd0LiIpLCAoe1RQfSkpOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIC8vIEFsbGUgQmVkaW5ndW5nZW4gZXJmdWVsbHQ6IAorICAgICAgICAvLyAtIEFuZ2VsIGluIGRlciBIYW5kLgorICAgICAgICAvLyAtIEdld2Flc3NlciBzdGltbXQuCisgICAgICAgIC8vIC0gSGFrZW4gbWl0IEtvZWRlciBpc3QgZHJhbi4KKyAgICAgICAgLy8gLSBhbHRlIEJldXRlIHd1cmRlIGFiZ2Vub21tZW4uCisgICAgICAgIC8vIC0gTW92ZS1Ib29rIGdlc2V0enQsIHVtIEFiYnJ1Y2ggYXVzbG9lc2VuIHp1IGtvZW5uZW4uCisgICAgICAgIGFjdGltZSA9IHRpbWUoKTsKKyAgICAgICAgY3VycmVudF91c2VyID0gVFA7CisgICAgICAgIHRlbGxfb2JqZWN0KFRQLCAiRHUgd2lyZnN0IGRpZSBBbmdlbCBhdXMuXG4iKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KFRQKSwgVFAtPk5hbWUoKSsiIHdpcmZ0IGVpbmUgQW5nZWwgYXVzLlxuIiwgCisgICAgICAgICAgKHtUUH0pKTsKKyAgICAgICAgY2FsbF9vdXQoImRvX2FuZ2VsIiwgZGVsYXkpOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gMTsKK30KKworcHJpdmF0ZSBvYmplY3QgR2V0RmlzaChvYmplY3Qgcm9vbSkgeworICBpbnQgd3R5cGUgPSByb29tLT5RdWVyeVByb3AoUF9XQVRFUik7CisgIHN0cmluZyAqZmlzY2hlOworICAKKyAgLy8gV2VubiBHZXRBcXVhcml1bSgpIGJlaSBXX1VTRVIgbmljaHRzIHp1cnVlY2tsaWVmZXJ0LCBnZWh0IGRlciBBbmdsZXIKKyAgLy8gbGVlciBhdXMuIEVzIGthbm4ga2VpbiBGaXNjaCBhdXMgZGVyIFN0ZC1MaXN0ZSBnZW5vbW1lbiB3ZXJkZW4sIHdlaWwKKyAgLy8gZGVyIEdld2Flc3NlcnR5cCBqYSBwZXIgRGVmaW5pdGlvbiBiZW51dHplcmRlZmluaWVydCBpc3QuCisgIGlmICggd3R5cGUgPT0gV19VU0VSICkKKyAgICBmaXNjaGUgPSByb29tLT5HZXRBcXVhcml1bShNRSl8fCh7fSk7CisgIGVsc2UgCisgICAgZmlzY2hlID0gYXF1YXJpdW1bd3R5cGVdOworCisgIHN0cmluZyBiZXV0ZSA9IGZpc2NoZVtyYW5kb20oc2l6ZW9mKGZpc2NoZSkpXTsKKworICBpZiAoICFiZXV0ZSApCisgICAgcmV0dXJuIDA7CisgIC8vIEdldEFxdWFyaXVtKCkgbGllZmVydCB2b2xsZSBQZmFkZSwgU1RERklTSExJU1QgbnVyIERhdGVpbmFtZW4gcmVsYXRpdgorICAvLyB6dSBGSVNIKCkKKyAgZWxzZSBpZiAoIHd0eXBlID09IFdfVVNFUiApCisgICAgcmV0dXJuIGNsb25lX29iamVjdChiZXV0ZSk7CisgIGVsc2UKKyAgICByZXR1cm4gY2xvbmVfb2JqZWN0KEZJU0goYmV1dGUpKTsKK30KKworc3RhdGljIHZvaWQgZG9fYW5nZWwoKSB7CisgIG9iamVjdCBoYWtlbiA9IHByZXNlbnQoSEFLRU5fSUQsIE1FKTsKKyAgb2JqZWN0IHJvb20gID0gZW52aXJvbm1lbnQoVFApOworICBvYmplY3QgZmlzY2g7CisKKyAgc3RyaW5nIG1zZ19zZWxmLCBtc2dfb3RoZXI7CisgIGlmICggbWVtYmVyKFRQLT5RdWVyeVByb3AoUF9IQU5EU19VU0VEX0JZKSwgTUUpPT0tMSApIHsKKyAgICB0ZWxsX29iamVjdChUUCwgQlMoIldhZWhyZW5kIER1IHZlcnRyYWV1bXQgdm9yIERpY2ggaGluZ2VhbmdlbHQgaGFzdCwgIgorICAgICAgImhhdCBzaWNoIERlaW4gR3JpZmYgYW4gZGVyIEFuZ2VsIHdvaGwgZ2Vsb2NrZXJ0LCBzbyBkYXNzIGRlciAiCisgICAgICAiRmlzY2gsIGRlciBnZXJhZGUgYW5iZWlzc2VuIHdvbGx0ZSwgc2llIERpciBiZWluYWhlIGVudHJpc3NlbiAiCisgICAgICAiaGFldHRlLiIpKTsKKyAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoVFApLCBCUyhUUC0+TmFtZShXRVIpKyIgaGF0IHNpY2ggZ2VyYWRlICIKKyAgICAgICJ6aWVtbGljaCBlcnNjaHJlY2t0LCBhbHMgIitUUC0+UXVlcnlQcm9ub3VuKFdFTSkrIiBiZWluYWhlICIrCisgICAgICBUUC0+UVBQKE1FLCBXRU4sIFNJTkdVTEFSKSsiICIrTmFtZShSQVcpKyIgZW50cmlzc2VuIHdvcmRlbiB3YWVyZS4iKSwKKyAgICAgICh7VFB9KSk7CisgICAgaWYgKCAhcmFuZG9tKDMpICYmIGhha2VuLT5Lb2VkZXJHZWZyZXNzZW4oKSApCisgICAgICB0ZWxsX29iamVjdChUUCwgQlMoIkRlciBLb2VkZXIgaXN0IGplZGVuZmFsbHMgZnV0c2NoLiIpKTsKKyAgICByZXR1cm47CisgIH0KKworICBpZiAoICFvYmplY3RwKGhha2VuKSApIHsKKyAgICBtc2dfc2VsZiA9ICJIdWNoLCBhbnNjaGVpbmVuZCBoYXQgc2ljaCBpbiBlaW5lbSB1bmJlb2JhY2h0ZXRlbiAiCisgICAgICAiTW9tZW50IGRlciBBbmdlbGhha2VuIHZvbiBkZXIgQW5nZWxzY2hudXIgZ2Vsb2VzdC4gV2FyIGRlciBLbm90ZW4gIgorICAgICAgImRvY2ggbmljaHQgZ3V0IGdlbnVnIGdlc2ljaGVydD8iOworICAgIG1zZ19vdGhlciA9IFRQLT5OYW1lKCkrIiB6aWVodCB1bmdsYWV1YmlnIGVpbmUgbGVlcmUgQW5nZWxzY2hudXIgYXVzICIKKyAgICAgICJkZW0gV2Fzc2VyLiI7CisgIH0KKyAgZWxzZSBpZiAoICFvYmplY3RwKGZpc2NoPUdldEZpc2gocm9vbSkpIHx8IAorICAgICAgICAgICAgYWN0aXZlICE9IHJvb20tPlF1ZXJ5UHJvcChQX1dBVEVSKSApCisgIHsKKyAgICBtc2dfc2VsZiA9ICJBbnNjaGVpbmVuZCBnaWJ0IGVzIGhpZXIgZG9jaCBrZWluZSBGaXNjaGUuIER1IGdpYnN0ICIKKyAgICAgICJhdWYgdW5kIGhvbHN0ICIrbmFtZShXRU4sMSkrIiB3aWVkZXIgZWluLiI7CisgICAgLy8gTGVha2VuIHZvbiBGaXNjaG9iamVrdGVuIHZlcmhpbmRlcm4uCisgICAgaWYgKG9iamVjdHAoZmlzY2gpKQorICAgICAgZmlzY2gtPnJlbW92ZSgpOworICB9CisgIGVsc2UgaWYgKCBmaXNjaC0+bW92ZShNRSkgIT0gTU9WRV9PSyApIHsKKyAgICBtc2dfc2VsZiA9IGZpc2NoLT5OYW1lKFdFUikrIiBiaXNzIGFuLCB3YXIgYWJlciB6dSBzY2h3ZXIgZnVlciAiCisgICAgICAiRGljaCAob2RlciBEZWluZSBBbmdlbCkuICIrY2FwaXRhbGl6ZShmaXNjaC0+UXVlcnlQcm9ub3VuKFdFUikpKworICAgICAgIiBlbnRnbGVpdGV0IERpciB1bmQgcGx1bXBzdCB6dXJ1ZWNrIGlucyBXYXNzZXIhIjsKKyAgICAKKyAgICBpZiggIShmaXNjaC0+UXVlcnlQcm9wKFBfRklTSCkgJiBGX05PVEhVTkdSWSkgKSB7CisgICAgICBoYWtlbi0+S29lZGVyR2VmcmVzc2VuKCk7CisgICAgICBpZighcmFuZG9tKEtPRURFUl9MT1NUKSkgeworICAgICAgICBtc2dfc2VsZiArPSAiIERlaW4gSGFrZW4gaXN0IGRhYmVpIGxlaWRlciBhYmdlcmlzc2VuISI7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChUUCksIEJTKE5hbWUoV0VSLDEpKyIgdm9uICIrVFAtPk5hbWUoV0VNKSsKKyAgICAgICAgICAiIHdhY2tlbHRlIHNlaHIgc3RhcmsuIiksICh7VFB9KSk7CisgICAgICAgIGhha2VuLT5yZW1vdmUoKTsKKyAgICAgIH0KKyAgICB9CisgICAgZmlzY2gtPnJlbW92ZSgxKTsKKyAgfQorICBlbHNlIHsKKyAgICBoYWtlbi0+S29lZGVyR2VmcmVzc2VuKCk7CisgIH0KKyAgU3RvcEZpc2hpbmcobXNnX3NlbGYsIG1zZ19vdGhlcik7Cit9CisKK3ZhcmFyZ3MgaW50IHJlbW92ZShpbnQgc2lsZW50KSB7CisgIGlmICggZmluZF9jYWxsX291dCgiZG9fYW5nZWwiKSE9LTEgKQorICAgIFN0b3BGaXNoaW5nKE5hbWUoV0VSLDEpKyIgbG9lc3Qgc2ljaCBwbG9ldHpsaWNoIGltIE5pY2h0cyBhdWYuIik7CisgIHJldHVybiA6OnJlbW92ZShzaWxlbnQpOworfQorCisvLyBKZW1hbmQgbWFjaHQgImVuZGUiIHdhZWhyZW5kIGVyIGFuZ2VsdD8KK3Byb3RlY3RlZCB2b2lkIE5vdGlmeU1vdmUob2JqZWN0IGRlc3QsIG9iamVjdCBvbGRlbnYsIGludCBtZXRob2QpIHsKKyAgaWYgKCBmaW5kX2NhbGxfb3V0KCJkb19hbmdlbCIpIT0tMSAmJiBvbGRlbnYgPT0gY3VycmVudF91c2VyICYmIAorICAgICAgIGRlc3QtPklzUm9vbSgpICkgeworICAgIFN0b3BGaXNoaW5nKCJEdSBob2xzdCBkaWUgQW5nZWwgZWluIHVuZCBsZWdzdCBzaWUgYmVpc2VpdGUuIik7CisgIH0KKyAgcmV0dXJuIDo6Tm90aWZ5TW92ZShkZXN0LCBvbGRlbnYsIG1ldGhvZCk7Cit9CisKKy8vIFNwaWVsZXIgbG9nZ3Qgd2FlaHJlbmQgZGVzIEFuZ2VsbnMgYXVzPyBEYW5uIGFuZ2VsbiBlaW5zdGVsbGVuLgordm9pZCBCZWNvbWVzTmV0RGVhZChvYmplY3QgcGwpIHsKKyAgaWYgKCBmaW5kX2NhbGxfb3V0KCJkb19hbmdlbCIpIT0tMSAmJiBwbCA9PSBjdXJyZW50X3VzZXIgKSB7CisgICAgU3RvcEZpc2hpbmcoIkFuZ2VsbiBpc3Qgc28gZWluZSBiZXJ1aGlnZW5kZSBGcmVpemVpdGJlc2NoYWVmdGlndW5nISAiCisgICAgICAiQmV2b3IgRHUgbWl0IGRlciBBbmdlbCBpbiBkZXIgSGFuZCBlaW5zY2hsYWVmdCwgaG9sc3QgRHUgc2llICIKKyAgICAgICJsaWViZXIgc2NobmVsbCBlaW4uIiwgcGwtPk5hbWUoKSsiIGhvbHQgc2NobmVsbCBub2NoIGRpZSBBbmdlbCBlaW4sICIKKyAgICAgICJiZXZvciAiK3BsLT5RdWVyeVByb25vdW4oV0VSKSsiIGVpbnNjaGxhZWZ0LiIpOworICB9Cit9CisKK2ludCBQcmV2ZW50SW5zZXJ0KG9iamVjdCBvYikgeworICAvLyBGdW5rdGlvbiB3aXJkIGF1cyBlaW5lciBTcGllbGVyZWluZ2FiZSBoZXJhdXMgZ2VydWZlbgorICAvLyBJY2ggbmVobWUgaGllciBuaWNodCBUUCwgd2VpbCBkZXIgY2FsbF9vdXQoImRvX2FuZ2VsIikgZGllCisgIC8vIGdlZmFuZ2VuZW4gRmlzY2hlIHBlciBtb3ZlKCkgaW4gZGllIEFuZ2VsIGJld2VndDogQmVpIGNhbGxfb3V0KClzIHdpcmQKKyAgLy8gVFAgZHVyY2ggZGllIEtldHRlIHdlaXRlcmdlcmVpY2h0LCBzbyBkYXNzIGRhbm4gaGllciBrZWluZSAKKyAgLy8gVW50ZXJzY2hlaWR1bmcgendpc2NoZW4gU3BpZWxlcmVpbmdhYmUgdW5kIGNhbGxfb3V0KCkgbW9lZ2xpY2ggd2FlcmUuCisgIFNldFByb3AoUF9OT0lOU0VSVF9NU0csIDApOworICBpZiAoIHN0cmluZ3AocXVlcnlfdmVyYigpKSAmJgorICAgICAgIG1lbWJlcigoeyJoYWVuZ2UiLCJoYWVuZyIsImJlZmVzdGlnZSJ9KSwgcXVlcnlfdmVyYigpKSA9PSAtMSApIHsKKyAgICBTZXRQcm9wKFBfTk9JTlNFUlRfTVNHLCBCUyhOYW1lKFdFUiwxKSsiIGlzdCBudXIgZGFmdWVyIGdlZWlnbmV0LCAiCisgICAgICAiQW5nZWxoYWtlbiBkYXJhbnp1aGFlbmdlbi4iKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYoIG9iLT5pZChGSVNDSF9JRCkgKSB7CisgICAgd3JpdGUoIkV0d2FzIHphcHBlbHQgYW4gRGVpbmVyIEFuZ2VsLlxuIik7CisgIH0KKyAgcmV0dXJuIDo6UHJldmVudEluc2VydChvYik7Cit9CisKKy8vIFdlbm4gZ2VhbmdlbHQgd2lyZCwgbmltbXQgaGllciBuaWVtYW5kIHdhcyByYXVzLgorcHVibGljIGludCBQcmV2ZW50TGVhdmUob2JqZWN0IG9iLCBtaXhlZCBkZXN0KSB7CisgIFNldFByb3AoUF9OT0xFQVZFX01TRywgMCk7CisgIGlmICggZmluZF9jYWxsX291dCgiZG9fYW5nZWwiKSE9LTEgKSB7CisgICAgaWYgKCBvYmplY3RwKFRQKSAmJiBvYi0+aWQoSEFLRU5fSUQpICkKKyAgICAgIFNldFByb3AoUF9OT0xFQVZFX01TRywgQlMoIkRlciBIYWtlbiBpc3QgZ2VyYWRlIHVudGVyIFdhc3Nlci4gRXMgIgorICAgICAgICAid2FlcmUga29udHJhcHJvZHVrdGl2LCBpaG4gYXVzZ2VyZWNobmV0IGpldHp0IGFienVuZWhtZW4uIikpOworICAgIHJldHVybiAxOworICB9CisgIHJldHVybiA6OlByZXZlbnRMZWF2ZShvYiwgZGVzdCk7Cit9CisKKy8vIEJlZW5kZXQgZGFzIEFuZ2VsbiwgaW5kZW0gQWt0aXYtRmxhZyBnZWxvZXNjaHQsIEhvb2sgZGVyZWdpc3RyaWVydAorLy8gdW5kIGNhbGxfb3V0KCkgZ2Vsb2VzY2h0IHdpcmQuIFp1c2FldHpsaWNoIHdlcmRlbiBkaWUgYWxzIEFyZ3VtZW50IHVlYmVyLQorLy8gZ2ViZW5lbiBNZWxkdW5nZW4gYXVzZ2VnZWJlbiwgb2RlciBwYXNzZW5kZSBnZW5lcmlzY2hlIHZlcndlbmRldC4KK25vbWFzayB2YXJhcmdzIHZvaWQgU3RvcEZpc2hpbmcoc3RyaW5nIG1zZ19tZSwgc3RyaW5nIG1zZ19yb29tKSB7CisgIGFjdGl2ZSA9IDA7CisgIHdoaWxlKHJlbW92ZV9jYWxsX291dCgiZG9fYW5nZWwiKSE9LTEpOworICBvYmplY3QgZW52ID0gZW52aXJvbm1lbnQoTUUpOworICBpZiAoIG9iamVjdHAoZW52KSAmJiBlbnYgPT0gY3VycmVudF91c2VyICkgeworICAgIGVudi0+RnJlZUhhbmRzKE1FKTsKKyAgICBjdXJyZW50X3VzZXIgPSAwOworICAgIGVudi0+SFVucmVnaXN0ZXJGcm9tSG9vayhIX0hPT0tfTU9WRSwgTUUpOworICAgIHRlbGxfb2JqZWN0KGVudiwgQlMobXNnX21lfHwiRHUgaG9sc3QgRGVpbmUgQW5nZWwgd2llZGVyIGVpbi4iKSk7CisgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVudiksIEJTKG1zZ19yb29tfHwKKyAgICAgIGVudi0+TmFtZShXRVIpKyIgaG9sdCAiK2Vudi0+UXVlcnlQb3NzUHJvbm91bihNRSxXRU4sU0lOR1VMQVIpKyIgIisKKyAgICAgIG5hbWUoUkFXKSsiIGVpbi4iKSwgKHtlbnZ9KSk7CisgIH0KK30KKworLy8gRGllc2UgTWV0aG9kZSB3aXJkIGluIGplZGVtIEhvb2stS29uc3VtZW50ZW4gZWluZXMgSG9vay1Qcm92aWRlcnMKKy8vIGF1ZmdlcnVmZW4sIHNvbGFuZ2UgZGllIFZlcmFyYmVpdHVuZyBuaWNodCB2b3JoZXIgYWJnZWJyb2NoZW4gd3VyZGUuCisvLyBEYW5uIGplZG9jaCB3dXJkZSBhdWNoIGRpZSBBa3Rpb24gKEJld2VndW5nKSBuaWNodCBhdXNnZWZ1ZWhydCwgZC5oLgorLy8gc29sYW5nZSBoaWVyIGtlaW4gRXZlbnQgYW5rb21tdCwgd3VyZGUga2VpbmUgQmV3ZWd1bmcgYXVzZ2VmdWVocnQgdW5kIAorLy8gZGFzIEFuZ2VsbiBrYW5uIHdlaXRlcmxhdWZlbi4KK21peGVkIEhvb2tDYWxsYmFjayhvYmplY3QgaG9va1NvdXJjZSwgaW50IGhvb2tpZCwgbWl4ZWQgaG9va0RhdGEpIHsKKyAgaWYgKCBob29raWQgPT0gSF9IT09LX01PVkUgJiYgaG9va1NvdXJjZSA9PSBjdXJyZW50X3VzZXIgKSB7CisgICAgU3RvcEZpc2hpbmcoIkRlaW5lIEFuZ2Vsc2NobnVyIGlzdCB6dSBrdXJ6LCB1bSBkYW1pdCBydW1sYXVmZW4genUgIgorICAgICAgImtvZW5uZW4uIER1IGhvbHN0IGRpZSBBbmdlbCB3aWVkZXIgZWluLiIpOworICB9CisgIHJldHVybiAoe0hfTk9fTU9ELCBob29rRGF0YX0pOworfQorCisvLyBXaXJkIGdlcnVmZW4sIHdlbm4gZGVyIEtvbnN1bWVudCB2b24gZWluZW0gYW5kZXJlbiBtaXQgaG9laGVyZXIgUHJpb3JpdGFldAorLy8gdmVyZHJhZW5ndCB3dXJkZS4KK3ZvaWQgc3VwZXJzZWVkZWRIb29rKGludCBob29raWQsIG9iamVjdCBob29rU291cmNlKSB7CisgIGlmICggaG9va2lkID09IEhfSE9PS19NT1ZFICYmIGhvb2tTb3VyY2UgPT0gY3VycmVudF91c2VyICkgeworICAgIFN0b3BGaXNoaW5nKCJJcmdlbmRldHdhcyBpc3QgZ2VyYWRlIHBhc3NpZXJ0LCBkYXMgYWxsZSBGaXNjaGUgIgorICAgICAgInZlcnRyaWViZW4gaGF0LiBEdSBzaWVoc3Qgc2llIHVudGVyIGRlciBXYXNzZXJvYmVyZmxhZWNoZSBkYXZvbiIKKyAgICAgICJmbGl0emVuLiBFcm51ZWNodGVydCBob2xzdCBEdSBEZWluZSBBbmdlbCB3aWVkZXIgZWluLiIpOworICB9Cit9CisKKy8vIEFuZ2VsenVzdGFuZCBhYmZyYWdlbi4KK2ludCBJc0Zpc2hpbmcoKSB7CisgIHJldHVybiAoZmluZF9jYWxsX291dCgiZG9fYW5nZWwiKSE9LTEpOworfQorCisvLyBHZXdhZXNzZXJ0eXAgYWJmcmFnZW4sIGluIGRlbSBnZXJhZGUgZ2VhbmdlbHQgd2lyZC4KK2ludCBxdWVyeV9hY3RpdmUoKSB7CisgIHJldHVybiBhY3RpdmU7Cit9CmRpZmYgLS1naXQgYS9zdGQvaXRlbXMvZmlzaGluZy9maXNoLmMgYi9zdGQvaXRlbXMvZmlzaGluZy9maXNoLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDIwOWIzNQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9pdGVtcy9maXNoaW5nL2Zpc2guYwpAQCAtMCwwICsxLDIyMiBAQAorLy9SZXZpc2lvbiAxLjE6IFF1ZXJ5UXVhbGl0eSgpIGFkZGVkLCBzb2xsdGUgYWJlciBub2NoIHZlcmJlc3NlcnQgd2VyZGVuIQorLyoKK0xldHp0ZSBBZW5kZXJ1bmc6IFZhbmlvbiwgMjYuMDUuMDIKKyAgICAgICAgICAgICAgICAgIC0gRGllIEZpc2NoZSBoYWJlbiBqZXR6dCB3aWVkZXIgZWluZW4gV2VydC4gRGVyIFByZWlzIHdpcmQgCisgICAgICAgICAgICAgICAgICAgIHZvbiBlaW5lbSBNYXN0ZXIga29udHJvbGxpZXJ0LiBKZSBtZWhyIEZpc2NoIGVpbiBTcGllbGVyCisgICAgICAgICAgICAgICAgICAgIGFuZ2VsdCwgZGVzdG8gYmlsbGlnZXIgd2lyZCBkZXIgRmlzY2guCisgICAgICAgICAgICAgICAgICAtIEdyb3NzLUtsZWluc2NocmVpYnVuZyBiZWltIGVzc2VuIGtvcnJpZ2llcnQuCisqLworCisjcHJhZ21hIHN0cm9uZ190eXBlcywgc2F2ZV90eXBlcywgcnR0X2NoZWNrcworI3ByYWdtYSBub19jbG9uZSwgbm9fc2hhZG93CisKK2luaGVyaXQgIi9zdGQvdGhpbmciOworCisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPGl0ZW1zL2Zpc2hpbmcvZmlzaGluZy5oPgorCisjZGVmaW5lIFRQIHRoaXNfcGxheWVyKCkKKyNkZWZpbmUgQlMoeCkgYnJlYWtfc3RyaW5nKHgsIDc4KQorCitwcml2YXRlIHN0cmluZyBlYXRtZXNzYWdlOworc3RyaW5nIGNvcnBzZW9iamVjdCA9ICIvaXRlbXMvZmlzaGluZy9ncmFldGVuIjsKK3N0YXRpYyBpbnQgcHJpY2VfbW9kaWZpZXI7CisKKyNkZWZpbmUgREVDQVlTVEFSVCAgIDYwMCAgLy8gYmVnaW5udCBuYWNoIDEwIG1pbiB6dSBmYXVsZW4KKyNkZWZpbmUgREVDQVlTVEVQICAgIDEyMCAgLy8gYWxsZSAyIE1pbnV0ZW4gd2lyZCBlciBzY2hsZWNodGVyCisjZGVmaW5lIE1BWFFVQUxJVFkgICAgIDQgIC8vIG5hY2ggNCBEZWNheXMgaXN0IGVyIGdpZnRpZworI2RlZmluZSBLSUxMRkFDVE9SICAgICA1ICAvLyByZWR1Y2VfaGl0X3BvaW50cyhTVEVQUypLSUxMRkFDVE9SKQorI2RlZmluZSBIRUFMRkFDVE9SICAgIDMyICAvLyA4MDAgZyA9IDI1IExQCisjZGVmaW5lIE1BWEhFQUwgICAgICAgNDAgIC8vIEtlaW4gRmlzY2ggYnJpbmd0IG1laHIgYWxzIDQwIExQCisjZGVmaW5lIE1JTkhFQUwgICAgICAgIDAgIC8vIG9kZXIgd2VuaWdlciBhbHMgMAorI2RlZmluZSBGT09ESEVBTEZBQ1RPUiAzICAvLyBMUD1MUCArIDEvMyBkZXMgR2V3aWNodHMKKwordm9pZCBTZXRFYXRNZXNzYWdlKHN0cmluZyBzdHIpOwordm9pZCBTZXRDb3Jwc2VPYmplY3Qoc3RyaW5nIHN0cik7CitpbnQgUXVlcnlRdWFsaXR5KCk7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIHsKKyAgOjpjcmVhdGUoKTsKKyAgLy8gUmVzZXQga3VyeiBuYWNoIEVycmVpY2hlbiBkZXMgbWF4LiBHYW1tZWx6dXN0YW5kcywgZGFubiB6ZXJzdG9lcmVuLgorICBzZXRfbmV4dF9yZXNldChERUNBWVNUQVJUKyhNQVhRVUFMSVRZKzEpKkRFQ0FZU1RFUCk7CisgIEFkZElkKCh7RklTQ0hfSUQgLCJmaXNjaCJ9KSk7CisgIFNldFByb3AoUF9OQU1FLCAiRmlzY2giICk7CisgIFNldFByb3AoUF9HRU5ERVIgLCBNQUxFKTsKKyAgU2V0UHJvcChQX1NIT1JULCAiRWluIEZpc2NoIiApOworICBTZXRQcm9wKFBfTE9ORywgIkVpbiBzdGlua25vcm1hbGVyIEZpc2NoLlxuIik7CisgIFNldFByb3AoUF9NQVRFUklBTCwgTUFUX01JU0NfRk9PRCk7CisgIFNldFByb3AoUF9OT0JVWSwxKTsKKyAgU2V0UHJvcChQX1dFSUdIVCwgNTAwKTsKKyAgQWRkQ21kKCJpc3MmQElEIiwgImVhdGl0IiwgIldhcyB3aWxsc3QgRHUgZXNzZW4/Iik7CisKKyAgLy8gVmFuaW9uLCAyNi4wNS4wMjogRGVyIFByZWlzIHdpcmQgZXJzdCBuYWNoIGRlbSBjcmVhdGUoKSBnZWhvbHQsIAorICAvLyBkYSBkYXMgR2V3aWNodCBkYW5uIHNjaG9uIGdlc2V0enQgd2VyZGVuIG11c3MuCisgIGNhbGxfb3V0KCJHZXRQcmljZU1vZGlmaWVyIiwwKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKKy8vIFdlcnQgZGVzIEZpc2NoZXMgaXN0IGFiaGFlbmdpZyB2b20gcHJpY2VfbW9kaWZpZXIgdW5kIHZvbiBQX1ZBTFVFCitzdGF0aWMgaW50IF9xdWVyeV92YWx1ZSgpIHsKKyAgaW50IHZhbHVlOworCisgIC8vIE1pbmltYWxwcmVpcyBpc3QgaW1tZXIgMSBNdWVuemUuIERhbWl0IG1hbiBpaG4gbG9zd2lyZC4KKyAgaWYoIXByaWNlX21vZGlmaWVyKSAKKyAgICByZXR1cm4gMTsKKworICB2YWx1ZSA9IFF1ZXJ5KFBfVkFMVUUsIEZfVkFMVUUpOworCisgIGlmKCF2YWx1ZSkKKyAgICByZXR1cm4gMDsgCisKKyAgcmV0dXJuICh2YWx1ZSpwcmljZV9tb2RpZmllcikvMTAwIDsKK30KKworLypFaW5nZWJhdXQgdm9uIFZhbmlvbiwgMjYuMDUuMDIKKyAgRGllIEZ1bmt0aW9uIGhvbHQgZGVuIHByaWNlX21vZGlmaWVyIGF1cyBkZW0gRmlzaC1NYXN0ZXIuCisgIEhpZXJiZWkgd2lyZCBlaW4gV2VydCB6d2lzY2hlbiAwIHVuZCAxMDAgenVydWVja2dlZ2ViZW4sIGRlciAKKyAgZGVuIFByb3plbnRzYXR6IGRlcyBXZXJ0ZXMgdm9uIFBfVkFMVUUgYW5naWJ0LiA1MCBiZWRldXRldCwgZGFzcworICBkZXIgRmlzY2ggNTAlIHNlaW5lcyBNYXhpbWFsd2VydGVzIGhhdC4gKi8KKworI2RlZmluZSBGSVNITUFTVEVSICJwL2RhZW1vbi9maXNobWFzdGVyIgorCit2b2lkIEdldFByaWNlTW9kaWZpZXIoKSB7CisgIGlmICghdGhpc19wbGF5ZXIoKSkgcmV0dXJuOworCisgIC8vIEpldHp0IHdpcmQgZGVyIFByZWlzIGZ1ZXIgZGVuIEZpc2NoIGJlc3RpbW10LgorICBwcmljZV9tb2RpZmllciA9IEZJU0hNQVNURVItPlByaWNlT2ZGaXNoKFRQLCBNRSk7CisgIHJldHVybjsKK30KKwordm9pZCBTZXRFYXRNZXNzYWdlKHN0cmluZyBzdHIpIHsKKyAgZWF0bWVzc2FnZT1zdHI7Cit9CisKK3ZvaWQgU2V0Q29ycHNlT2JqZWN0KHN0cmluZyBzdHIpIHsKKyAgY29ycHNlb2JqZWN0PXN0cjsKK30KKworaW50IF9zZXRfd2VpZ2h0KGludCBncmFtbSkgeworICBpbnQgdG1wID0gZ3JhbW0vMiArIHJhbmRvbShncmFtbS8yKTsgLy8gIm5hdC4gU2Nod2Fua3VuZ2VuIiBuYWNoYmlsZGVuCisgIFNldChQX1dFSUdIVCwgdG1wLCBGX1ZBTFVFKTsKKyAgU2V0UHJvcChQX1ZBTFVFLCB0bXAvNCk7IC8vIEltIG5vcm1hbGVuIExhZGVuIG51ciAxLzQgR2V3aWNodCBpbiBNdWVuemVuCisgIHJldHVybiB0bXA7Cit9CisKK3ZvaWQgaW5pdCgpIHsKKyAgOjppbml0KCk7CisgIGlmKCBRdWVyeVByb3AoUF9GSVNIKSZGX1JFUExBQ0UgKSB7CisgICAgaWYocXVlcnlfb25jZV9pbnRlcmFjdGl2ZShlbnZpcm9ubWVudChNRSkpKSB7CisgICAgICBjYWxsX291dCgiUmVwbGFjZUZpc2giLDApOworICAgIH0KKyAgfQorICByZXR1cm47Cit9CisgCit2YXJhcmdzIHN0cmluZyBsb25nKGludCBtb2RlKSB7CisgIHN0cmluZyBwcm9uID0gY2FwaXRhbGl6ZShRdWVyeVByb25vdW4oV0VSKSk7CisgIHN0cmluZyB0eHQgPSBRdWVyeVByb3AoUF9MT05HKTsKKyAKKyAgc3dpdGNoKFF1ZXJ5UXVhbGl0eSgpKSB7CisgICAgY2FzZSA0OiAgdHh0ICs9IHByb24rIiBpc3QgZmFuZ2ZyaXNjaC5cbiI7ICAgICAgICAgICAgYnJlYWs7CisgICAgY2FzZSAzOiAgdHh0ICs9IHByb24rIiBpc3Qgbm9jaCByZWNodCBmcmlzY2guXG4iOyAgICAgYnJlYWs7CisgICAgY2FzZSAyOiAgdHh0ICs9IHByb24rIiBpc3Qgc2Nob24gZXR3YXMgcnVuemxpZy5cbiI7ICAgYnJlYWs7CisgICAgY2FzZSAxOiAgdHh0ICs9IHByb24rIiBzaWVodCBzY2hvbiByZWNodCBhbHQgYXVzLlxuIjsgYnJlYWs7CisgICAgY2FzZSAwOiAgdHh0ICs9IHByb24rIiBpc3QgbmljaHQgbWVociBnZW5pZXNzYmFyIVxuIjsgYnJlYWs7CisgICAgY2FzZSAtMTogdHh0ICs9IHByb24rIiBpc3QgdmVyZ2FtbWVsdC5cbiI7ICAgICAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIHR4dCArPSAocHJvbisiIHN0aW5rdCB3aWRlcmxpY2ggdW5kIGlzdCBiZXJlaXRzIHZvbGxlciBNYWRlbiFcbiIrcHJvbisKKyAgICAgICAgIiB6ZXJmYWVsbHQgbm9jaCB3YWVocmVuZCBEdSAiK1F1ZXJ5UHJvbm91bihXRU4pKyIgYmV0cmFjaHRlc3QuXG4iKTsKKyAgICAgIHJlbW92ZSgpOworICAgICAgYnJlYWs7CisgIH0KKyAgcmV0dXJuKHR4dCk7Cit9CisKK2ludCBfcXVlcnlfZmlzaF9hZ2UoKSB7CisgIHJldHVybiAodGltZSgpLVF1ZXJ5UHJvcChQX0NMT05FX1RJTUUpKTsKK30KKworc3RhdGljIGludCBlYXRpdChzdHJpbmcgc3RyKSB7CisgIHN0cmluZyBtc2dfb3RoZXIgPSBUUC0+TmFtZSgpKyIgaXNzdCAiK25hbWUoV0VOKSsiLiI7CisKKyAgaWYgKCAhZWF0bWVzc2FnZSApCisgICAgZWF0bWVzc2FnZSA9ICJEdSBpc3N0ICIrbmFtZShXRU4sMSkrIiBhdWYuIjsKKworICBpZiAoIHN0cmluZ3AoY29ycHNlb2JqZWN0KSApIHsKKyAgICBvYmplY3QgbXVlbGw9Y2xvbmVfb2JqZWN0KGNvcnBzZW9iamVjdCk7CisgICAgaWYgKCBtdWVsbC0+bW92ZShUUCwgTV9HRVQpICE9IE1PVkVfT0sgKSB7CisgICAgICBtdWVsbC0+bW92ZShlbnZpcm9ubWVudChUUCksIE1fR0VUKTsKKyAgICB9CisgIH0KKyAgCisgIC8vIEhlaWx1bmcgYmVyZWNobmVuLgorICAvLyBIZWlsd2VydCBydW50ZXJza2FsaWVyZW4gbWl0IFF1YWxpdGFldCwgd2VubiBkYXMgTWluZGVzdGFsdGVyIGVycmVpY2h0CisgIC8vIGlzdCwgYWJlciBudXIsIHdlbm4gZGVyIEZpc2NoIGF1Y2ggdmVyZ2FtbWVsbiBrYW5uLgorICBpbnQgaGVhbGluZyA9IFF1ZXJ5UHJvcChQX1dFSUdIVCkvSEVBTEZBQ1RPUjsKKyAgaW50IGFnZSA9IFF1ZXJ5UHJvcChQX0ZJU0hfQUdFKTsKKyAgaWYgKCBhZ2UgPiBERUNBWVNUQVJUICYmICEoUXVlcnlQcm9wKFBfRklTSCkmRl9OT1JPVFRFTikpIHsKKyAgICBoZWFsaW5nID0gaGVhbGluZyAqIChRdWVyeVF1YWxpdHkoKSoyNSkvMTAwOworICB9CisgIGlmICggaGVhbGluZyA+IE1BWEhFQUwgKQorICAgIGhlYWxpbmcgPSBNQVhIRUFMOworICBlbHNlIGlmICggaGVhbGluZyA8IE1JTkhFQUwgKQorICAgIGhlYWxpbmcgPSBNSU5IRUFMOworCisgIGlmKCBhZ2UgPiBERUNBWVNUQVJUICsgTUFYUVVBTElUWSpERUNBWVNURVApIHsKKyAgICB0ZWxsX29iamVjdChUUCwgQlMoZWF0bWVzc2FnZSArICIgRGlyIHdpcmQgc3BlaXVlYmVsLCBkZXIgRmlzY2ggd2FyICIKKyAgICAgICJ6dSBhbHQhIikpOworICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChUUCksIEJTKG1zZ19vdGhlciArIFRQLT5RdWVyeVByb25vdW4oV0VSKSsKKyAgICAgICIgdmVyZHJlaHQgYW5nZWVrZWx0IGRpZSBBdWdlbi4iKSwgKHtUUH0pKTsKKyAgICBUUC0+cmVkdWNlX2hpdF9wb2ludHMoICgoYWdlLURFQ0FZU1RBUlQpL0RFQ0FZU1RFUCkqS0lMTEZBQ1RPUiApOworICAgIHJlbW92ZSgpOworICB9CisgIGVsc2UgeworICAgIGlmICggVFAtPmVhdF9mb29kKGhlYWxpbmcqRk9PREhFQUxGQUNUT1IpICkgeworICAgICAgdGVsbF9vYmplY3QoVFAsIEJTKGVhdG1lc3NhZ2UpKTsKKyAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChUUCksIEJTKG1zZ19vdGhlciksICh7VFB9KSk7CisgICAgICBpZiAoICEoUXVlcnlQcm9wKFBfRklTSCkmRl9OT0hFQUwpICkKKyAgICAgICAgVFAtPmJ1ZmZlcl9ocChoZWFsaW5nLDUpOworICAgICAgcmVtb3ZlKCk7CisgICAgfQorICB9CisgIHJldHVybiAxOworfQorCisvLyBRdWFsaXRhZXQgZGVzIEZpc2NoZXMgZXJtaXR0ZWxuLiBSdWVja2dhYmV3ZXJ0OiA0LCAzLCAyLCAxLCAwLCAtMSAuLi4KK2ludCBRdWVyeVF1YWxpdHkoKSB7CisgIC8vIEFsdGVyIGluIFNla3VuZGVuIHVlYmVyIGRlciBHcmVuemUsIGFiIGRlciBkZXIgRmlzY2ggYW5mYWVuZ3QgenUgZ2FtbWVsbgorICBpbnQgYWdlID0gUXVlcnlQcm9wKFBfRklTSF9BR0UpLURFQ0FZU1RBUlQ7CisgIC8vIFdlbm4gZGllIEdyZW56ZSBub2NoIG5pY2h0IGVycmVpY2h0IGlzdCwgb2RlciBkZXIgRmlzY2ggZ2VuZXJlbGwgbmljaHQKKyAgLy8gZ2FtbWVsdCAoRl9OT1JPVFRFTiksIGRhbm4gaXN0IGRhcyBBbHRlciAwIHVuZCBkaWUgUXVhbGl0YWV0IG1heC4KKyAgaWYgKCBhZ2U8MCB8fCBRdWVyeVByb3AoUF9GSVNIKSAmIEZfTk9ST1RURU4gKSAKKyAgICBhZ2UgPSAwOworCisgIC8vIFF1YWxpdGFldCBpbiBERUNBWVNURVAtU3R1ZmVuIHJlZHV6aWVyZW4gKDYwIHMgcHJvIEdhbW1lbHN0dWZlKQorICByZXR1cm4gTUFYUVVBTElUWS0oYWdlL0RFQ0FZU1RFUCk7Cit9CisKK3ZvaWQgcmVzZXQoKSB7CisgIGlmIChjbG9uZXAoTUUpKSB7CisgICAgc3RyaW5nIG1zZyA9IEJTKE5hbWUoKSsiIGlzdCB2ZXJnYW1tZWx0IHVuZCB6ZXJmYWVsbHQuIikgOworICAgIGlmICggaW50ZXJhY3RpdmUoZW52aXJvbm1lbnQoKSkgKSB7CisgICAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBtc2cpOworICAgIH0KKyAgICBlbHNlIGlmICggZW52aXJvbm1lbnQoKS0+SXNSb29tKCkgKSB7CisgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoKSwgbXNnKTsKKyAgICB9CisgICAgaWYgKCBzdHJpbmdwKGNvcnBzZW9iamVjdCkgKSB7CisgICAgICBvYmplY3QgbXVlbGw9Y2xvbmVfb2JqZWN0KGNvcnBzZW9iamVjdCk7CisgICAgICBpZiAoIG11ZWxsLT5tb3ZlKGVudmlyb25tZW50KCksIE1fR0VUKSAhPSBNT1ZFX09LICkgeworICAgICAgICBtdWVsbC0+bW92ZShlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSwgTV9HRVQpOworICAgICAgfQorICAgIH0KKyAgICBjYWxsX291dCgicmVtb3ZlIiwwKTsKKyAgICByZXR1cm47IAorICB9CisgIHJldHVybiA6OnJlc2V0KCk7Cit9CmRpZmYgLS1naXQgYS9zdGQvaXRlbXMvZmlzaGluZy9oYWtlbi5jIGIvc3RkL2l0ZW1zL2Zpc2hpbmcvaGFrZW4uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NmI5MWY0Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2l0ZW1zL2Zpc2hpbmcvaGFrZW4uYwpAQCAtMCwwICsxLDE1NyBAQAorI3ByYWdtYSBzdHJvbmdfdHlwZXMsIHNhdmVfdHlwZXMsIHJ0dF9jaGVja3MKKyNwcmFnbWEgbm9fc2hhZG93LCBub19jbG9uZQorCitpbmhlcml0ICIvc3RkL3RoaW5nIjsKKworI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGl0ZW1zL2Zpc2hpbmcvZmlzaGluZy5oPgorI2luY2x1ZGUgPGl0ZW1zL2ZsYXNjaGUuaD4KKyNpbmNsdWRlIDx1bml0Lmg+CisKKyNkZWZpbmUgVFAgdGhpc19wbGF5ZXIoKQorI2RlZmluZSBNRSB0aGlzX29iamVjdCgpCisKK2ludCBRdWVyeUtvZWRlcigpOworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CisgIDo6Y3JlYXRlKCk7CisKKyAgQWRkSWQoKHtIQUtFTl9JRCwiaGFrZW4iLCJhbmdlbGhha2VuIn0pKTsKKyAgU2V0UHJvcChQX05BTUUsICJIYWtlbiIpOworICBTZXRQcm9wKFBfR0VOREVSLCBNQUxFKTsKKyAgU2V0UHJvcChQX0FSVElDTEUsIDEpOworICBTZXRQcm9wKFBfV0VJR0hULCA1KTsKKyAgU2V0UHJvcChQX1NIT1JULCAiRWluIEFuZ2VsaGFrZW4iKTsKKyAgU2V0UHJvcChQX0xPTkcsICJFaW4gQW5nZWxoYWtlbiBhdXMgTWV0YWxsLlxuIik7CisgIFNldFByb3AoUF9MT05HX0VNUFRZLCJWaWVsbGVpY2h0IGthbm5zdCBEdSBldHdhcyBkYW1pdCBhdWZzcGllc3Nlbj9cbiIpOworCisgIC8vIExhbmctIHVuZCBLdXJ6YmVzY2hyZWlidW5nZW4gcmVhZ2llcmVuIGF1ZiBlaW5lbiBldnRsLiB2b3JoYW5kZW5lbiAKKyAgLy8gS29lZGVyLCBhbGxlcmRpbmdzIG51ciBhdWYgZWluIHRhdHNhZWNobGljaCBleGlzdGllcmVuZGVzIEtvZWRlci1PYmpla3QsCisgIC8vIG5pY2h0IGF1ZiBlaW5lbiBwZXIgdWViZXJzY2hyaWViZW5lbSBRdWVyeUtvZWRlcigpIHZvcmdldGFldXNjaHRlbgorICAvLyBLb2VkZXIsIHdpZSBlcyBkZXIgU3BlemlhbGhha2VuIHR1dC4KKyAgU2V0KFBfU0hPUlQsIGZ1bmN0aW9uIHN0cmluZyAoKSB7CisgICAgb2JqZWN0IGtvZWRlciA9IHByZXNlbnQoV1VSTV9JRCwgTUUpOworICAgIHJldHVybiBRdWVyeShQX1NIT1JULEZfVkFMVUUpKworICAgICAgKG9iamVjdHAoa29lZGVyKT8iIG1pdCAiK2tvZWRlci0+bmFtZShXRU0pOiIiKTsKKyAgfSwgRl9RVUVSWV9NRVRIT0QpOworICBTZXQoUF9MT05HLCBmdW5jdGlvbiBzdHJpbmcgKCkgeyAKKyAgICBvYmplY3Qga29lZGVyID0gcHJlc2VudChXVVJNX0lELCBNRSk7CisgICAgcmV0dXJuIFF1ZXJ5KFBfTE9ORyxGX1ZBTFVFKSArIChvYmplY3RwKGtvZWRlcik/CisgICAgICBrb2VkZXItPk5hbWUoV0VSKSsiIGhhZW5ndCBkYXJhbi5cbiI6UXVlcnlQcm9wKFBfTE9OR19FTVBUWSkpOworICB9LCBGX1FVRVJZX01FVEhPRCk7CisKKyAgLy8gUF9GSVNIIHVuZCBQX1dBVEVSIGxpZWZlcm4gZGllIERhdGVuIGVpbmVzIGV2dGwuIHZvcmhhbmRlbmVuIEtvZWRlcnMKKyAgLy8gV2VubiBrZWluIEtvZWRlciBkcmFuaGFlbmd0LCB3ZXJkZW4gUF9XQVRFUiB1bmQgUF9GSVNIIGRlcyBIYWtlbnMKKyAgLy8genVydWVja2dlZ2ViZW4sIGZhbGxzIGVzIHNpY2ggdW0gZWluZW4gRmFrZS1Lb2VkZXIgaGFuZGVsdCB3aWUgYmVpbQorICAvLyBTcGV6aWFsaGFrZW47IGluIGRpZXNlbSBGYWxsIGhhdCBkZXIgSGFrZW4gc2VsYnN0IGRpZSBQcm9wZXJ0aWVzIAorICAvLyBnZXNldHp0LgorICBTZXQoUF9GSVNILCBmdW5jdGlvbiBpbnQgKCkgeworICAgIG9iamVjdCBrb2VkZXIgPSBwcmVzZW50KFdVUk1fSUQsIE1FKTsKKyAgICByZXR1cm4gKG9iamVjdHAoa29lZGVyKT9rb2VkZXItPlF1ZXJ5UHJvcChQX0ZJU0gpOlF1ZXJ5KFBfRklTSCkpOworICB9LCBGX1FVRVJZX01FVEhPRCk7CisgIFNldChQX1dBVEVSLCBmdW5jdGlvbiBpbnQgKCkgeworICAgIG9iamVjdCBrb2VkZXIgPSBwcmVzZW50KFdVUk1fSUQsIE1FKTsKKyAgICByZXR1cm4gKG9iamVjdHAoa29lZGVyKT9rb2VkZXItPlF1ZXJ5UHJvcChQX1dBVEVSKTpRdWVyeShQX1dBVEVSKSk7CisgIH0sIEZfUVVFUllfTUVUSE9EKTsKKworICBTZXRQcm9wKFBfTUFURVJJQUwsKFtNQVRfU1RFRUw6MTAwXSkpOworCisgIEFkZENtZCgoeyJzcGllc3MiLCJzcGllc3NlIn0pLCJzcGllc3NhdWYiKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3N0YXRpYyBpbnQgc3BpZXNzYXVmKHN0cmluZyBzdHIpIHsKKyAgc3RyaW5nIGhha2VuLHd1cm1uYW1lLCpzdWJzdHI7CisgIG9iamVjdCB3dXJtOworICBpbnQgYW1vdW50OworCisgIG5vdGlmeV9mYWlsKCJXYXMgd2lsbHN0IER1IGRlbm4gYXVmc3BpZXNzZW4/XG4iKTsKKyAgaWYgKCFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpKSAKKyAgICByZXR1cm4gMDsKKyAgCisgIGlmKCBzc2NhbmYoc3RyLCAiJXMgYXVmJXMiLCB3dXJtbmFtZSwgaGFrZW4pICE9IDIgKQorICAgIHJldHVybiAwOworCisgIGhha2VuID0gdHJpbShoYWtlbik7CisKKyAgbm90aWZ5X2ZhaWwoIlNvIGV0d2FzIGhhc3QgRHUgbmljaHQgYmVpIERpci5cbiIpOworICBpZiAoICFvYmplY3RwKHd1cm09cHJlc2VudCh3dXJtbmFtZSxUUCkpICkKKyAgICByZXR1cm4gMDsKKworICBub3RpZnlfZmFpbCgiRGFzIGthbm5zdCBEdSBuaWNodCBhdWZzcGllc3Nlbi5cbiIpOworICBpZiggIXd1cm0tPmlkKFdVUk1fSUQpICkKKyAgICByZXR1cm4gMDsKKworICBub3RpZnlfZmFpbCgiV29yYXVmIHdpbGxzdCBEdSAiK3d1cm0tPm5hbWUoV0VOLDEpKyIgZGVubiBzcGllc3Nlbj9cbiIpOworICBpZiAoIGhha2VuIT0iIiAmJiAhaWQoaGFrZW4pICkKKyAgICByZXR1cm4gMDsKKworICBub3RpZnlfZmFpbChicmVha19zdHJpbmcoIkRhenUgc29sbHRlc3QgRHUgIituYW1lKFdFTiwxKSsiIGVyc3QgZWlubWFsICIKKyAgICAiYmVpIERpciBoYWJlbi4iLDc4KSk7CisgIGlmICggZW52aXJvbm1lbnQoTUUpICE9IFRQICkKKyAgICByZXR1cm4gMDsKKworICBub3RpZnlfZmFpbCgiQW4gZGVtIEhha2VuIGhhZW5ndCBzY2hvbiBlaW4gS29lZGVyLlxuIik7CisgIGlmICggUXVlcnlLb2VkZXIoKSApCisgICAgcmV0dXJuIDA7CisKKyAgLy8gSGFrZW4gdW5kIEtvZWRlciBzaW5kIGltIEludmVudGFyIHVuZCBmdWVobGVuIHNpY2ggdm9uIGRlciBTeW50YXgKKyAgLy8gYW5nZXNwcm9jaGVuLgorICBpZiggd3VybS0+SXNVbml0KCkgKSB7CisgICAgLy8gRGFzIFF1ZXJ5UHJvcCgpIGlzdCBuaWNodCB1bm5vZXRpZy4gQmVpIGRlciBBYmZyYWdlIHZvbiBVX1JFUSB3aXJkCisgICAgLy8gVV9SRVEgZ2VudWxsdCwgd2VubiBkYXMgYWt0dWVsbGUgcXVlcnlfdmVyYigpICE9IGRlbSBsZXR6dGVuIGlzdC4KKyAgICAvLyBCZWkgZGVyIGVyc3RlbiBBYmZyYWdlIHd1ZXJkZSBhbHNvIGRhcyBoaWVyIGdlc2V0enRlIFVfUkVRIHdpZWRlcgorICAgIC8vIGdlbG9lc2NodC4gRGFoZXIgbXVzcyBkYXMgamV0enQgaGllciBhbHMgZXJzdGVzIGVpbm1hbCBhYmdlZnJhZ3QKKyAgICAvLyB3ZXJkZW4uLi4KKyAgICB3dXJtLT5RdWVyeVByb3AoVV9SRVEpOworICAgIHd1cm0tPlNldFByb3AoVV9SRVEsMSk7CisgIH0KKyAgdGVsbF9vYmplY3QoVFAsIGJyZWFrX3N0cmluZygKKyAgICAiRHUgc3BpZXNzdCAiK3d1cm0tPm5hbWUoV0VOLDEpKyIgYXVmICIrbmFtZShXRU4sMSkrIi4iLDc4KSk7CisgIHRlbGxfcm9vbShlbnZpcm9ubWVudChUUCksIGJyZWFrX3N0cmluZygKKyAgICBUUC0+TmFtZShXRVIpKyIgc3BpZXNzdCAiK3d1cm0tPm5hbWUoV0VOKSsiIGF1ZiAiK25hbWUoV0VOKSsiLiIsNzgpLAorICAgICh7VFB9KSk7CisgIC8vIE1fR0VULCBkYW1pdCBhdWNoIFBfTk9EUk9QLUtvZWRlciBhdWZnZXNwaWVzc3Qgd2VyZGVuIGtvZW5uZW4uCisgIGlmICggd3VybS0+bW92ZShNRSxNX0dFVCkgIT0gTU9WRV9PSykgeworICAgIHRlbGxfb2JqZWN0KFRQLCBicmVha19zdHJpbmcoCisgICAgICAiVmVyZGFtbXQhIEpldHp0IGhhc3QgRHUgRGlyIGZhc3QgaW4gZGVuIEZpbmdlciBnZXN0b2NoZW4hICIrCisgICAgICB3dXJtLT5OYW1lKFdFTiwxKSsiIGhhc3QgRHUgZGFiZWkgbmF0dWVybGljaCB2ZXJmZWhsdC4iLCA3OCkpOworICB9CisgIHJldHVybiAxOworfQorCitpbnQgUXVlcnlLb2VkZXIoKXsgCisgIHJldHVybiBvYmplY3RwKHByZXNlbnQoV1VSTV9JRCwgTUUpKTsKK30KKworb2JqZWN0IFF1ZXJ5S29lZGVyT2JqZWN0KCkgeworICByZXR1cm4gcHJlc2VudChXVVJNX0lELE1FKTsKK30KKworaW50IE1heUFkZE9iamVjdChvYmplY3Qgb2IpIHsKKyAgcmV0dXJuIChvYmplY3RwKG9iKSAmJiBvYi0+aWQoV1VSTV9JRCkgJiYgc2l6ZW9mKGFsbF9pbnZlbnRvcnkoTUUpKTw9MSk7IAorfQorCitpbnQgX3F1ZXJ5X3RvdGFsX3dlaWdodCgpIHsKKyAgaW50IHR3OworICBmb3JlYWNoKGludCB3OiBhbGxfaW52ZW50b3J5KE1FKSsoe01FfSkpCisgICAgdHcgKz0gdy0+UXVlcnlQcm9wKFBfV0VJR0hUKTsKKyAgcmV0dXJuIHR3OworfQorCit2YXJhcmdzIGludCByZW1vdmUoaW50IHNpbCkgeworICBhbGxfaW52ZW50b3J5KE1FKS0+cmVtb3ZlKCk7IC8vIGZ1bmt0aW9uaWVydCBhdWNoIG1pdCBsZWVyZW4gQXJyYXlzCisgIHJldHVybiA6OnJlbW92ZShzaWwpOworfQorCitpbnQgS29lZGVyR2VmcmVzc2VuKCkgeworICAvLyBOaWNodCBRdWVyeUtvZWRlcigpIHBydWVmZW4sIGRhIGRhcyBiZWkgU3BlemlhbGhha2VuIGltbWVyIDEgaXN0LgorICBvYmplY3Qga29lZGVyID0gcHJlc2VudChXVVJNX0lELCBNRSk7CisgIGlmICggb2JqZWN0cChrb2VkZXIpICkKKyAgICByZXR1cm4ga29lZGVyLT5yZW1vdmUoKTsKKyAgcmV0dXJuIC0xOworfQpkaWZmIC0tZ2l0IGEvc3RkL2l0ZW1zL2Zpc2hpbmcva29lZGVyLmMgYi9zdGQvaXRlbXMvZmlzaGluZy9rb2VkZXIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNjMzMTdiCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2l0ZW1zL2Zpc2hpbmcva29lZGVyLmMKQEAgLTAsMCArMSwyOCBAQAorI3ByYWdtYSBzdHJvbmdfdHlwZXMsIHNhdmVfdHlwZXMsIHJ0dF9jaGVja3MKKyNwcmFnbWEgbm9fY2xvbmUsIG5vX3NoYWRvdworCitpbmhlcml0ICIvc3RkL3RoaW5nIjsKKworI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGl0ZW1zL2Zpc2hpbmcvZmlzaGluZy5oPgorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKXsKKyAgOjpjcmVhdGUoKTsKKyAgQWRkSWQoKHtXVVJNX0lELCJrb2VkZXIiLCAid3VybSIsInJlZ2Vud3VybSJ9KSk7CisgIFNldFByb3AoUF9OQU1FLCAiV3VybSIpOworICBTZXRQcm9wKFBfR0VOREVSICwgTUFMRSk7CisgIFNldFByb3AoUF9BUlRJQ0xFLCAxKTsKKyAgU2V0UHJvcChQX0ZJU0gsIDApOworICBTZXRQcm9wKFBfV0FURVIsIDApOworICBTZXRQcm9wKFBfU0hPUlQsICJFaW4ga2xlaW5lciBXdXJtIik7CisgIFNldFByb3AoUF9MT05HLCAiRWluIGtsZWluZXIgUmVnZW53dXJtLlxuIik7CisgIFNldFByb3AoUF9NQVRFUklBTCwgTUFUX01JU0NfTElWSU5HKTsKKyAgU2V0UHJvcChQX1ZBTFVFLCAxKTsKKyAgU2V0UHJvcChQX1dFSUdIVCwgNSk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCmRpZmYgLS1naXQgYS9zdGQvaXRlbXMvZmxhc2NoZS5jIGIvc3RkL2l0ZW1zL2ZsYXNjaGUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40MzczNWZlCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2l0ZW1zL2ZsYXNjaGUuYwpAQCAtMCwwICsxLDMzMyBAQAorLypPQkoqLworLyogMjAxMy1NYWktMjMsIEFyYXRob3JuCisgICBVbWZhc3NlbmQgdWViZXJhcmJlaXRldDsgc2V0dXAoKSwgaW5pdCgpIHVuZCBSZXBsYWNlV2Fzc2VyKCkgZW50c29yZ3QsCisgICBQX1dFSUdIVCB1bmQgUF9MT05HIGR5bmFtaXNjaCBnZWJhdXQsIHNvIGRhc3MgZGFzIHN0YWVuZGlnZSBVbXNldHplbgorICAgZGVyIFByb3BlcnRpZXMgbWl0dGVscyBzZXR1cCgpIG5hY2ggamVkZW0gRnVlbGxlbi9MZWVyZW4gZW50ZmFlbGx0LgorICovCisKKy8qIExldHp0ZSBBZW5kZXJ1bmc6IDQuNS4yMDA0LCBBcmF0aG9ybi4KKyAgIFplaWxlIDE0OTogY29udF9vYmotPnJlbW92ZSgpIGVpbmdlZnVlZ3QsIGRhbWl0IGRhcyBnZWNsb250ZSBPYmpla3QKKyAgIG5hY2ggZGVtIEFiZnJhZ2VuIHNlaW5lcyBOYW1lbnMgd2llZGVyIGVudGZlcm50IHdpcmQuCisgICBVcGRhdGUgNi42LjIwMDQsIEFyYXRob3JuLiBIYWJlIHVtIGVpbiBkZXN0cnVjdCgpIGVyZ2Flbnp0LCB3ZWlsIGRhcworICAgdHJvdHogcmVtb3ZlKCkgaGFydG5hZWNraWcgd2VpdGVyZ2VidWdndCBoYXQuICpmbHVjaCoKKyAqLworCisvKiBWZXJzaW9uIDEuMyBieSBGcmFnZ2xlICgxNy4xLjE5OTUpICovCisKKyAvLyBQcmV2ZW50SW5zZXJ0OiB2ZXJoaW5kZXJ0IEZ1ZWxsZW4gd2llIHN0ZC9jb250YWluZXIKKy8qIFZlcnNpb24gMS4yIGJ5IEZyYWdnbGUgKDE3LjEuMTk5NSkgKi8KKworIC8vIEZsYXNjaGUga2FubiBudW4gbWl0dGVscyBlbnZpcm9ubWVudChUUCktPkdldExpcXVpZCgpCisgLy8gZXR3YXMgYW5kZXJlcyBhbHMgV2Fzc2VyIGVudGhhbHRlbiwgc29mZXJuCisgLy8gZW52aXJvbm1lbnQoVFApLT5RdWVyeVByb3AoUF9XQVRFUik9PVdfT1RIRVIKKyAvLyBCVUc6IGF1Y2ggMWwgTWV0aGFuIHdpZWd0IDEgS2csIGFlbmRlcmUgaWNoIHNwYWV0ZXIKKworLyogVmVyc2lvbiAxLjEgYnkgRnJhZ2dsZSAoMTcuMS4xOTk1KSAqLworI3ByYWdtYSBzdHJvbmdfdHlwZXMscnR0X2NoZWNrcworI3ByYWdtYSBub19jbG9uZQorCitpbmhlcml0ICIvc3RkL3RoaW5nIjsKKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxpdGVtcy9mbGFzY2hlLmg+CisjaW5jbHVkZSA8aXRlbXMvZmlzaGluZy9maXNoaW5nLmg+CisKKyNkZWZpbmUgREVGQVVMVF9MSVEgIldhc3NlciIKKyNkZWZpbmUgVFAgdGhpc19wbGF5ZXIoKQorCitwcml2YXRlIHN0cmluZyBjb19maWxlbmFtZTsKK3B1YmxpYyBzdHJpbmcgbGlxdWlkX25hbWU9REVGQVVMVF9MSVE7CisKK3N0cmluZyBkeW5hbWljX2xvbmcoKTsKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkgeworICA6OmNyZWF0ZSgpOworCisgIEFkZElkKCh7Indhc3NlcmJlaGFlbHRlciIsImJlaGFlbHRlciIsIlxud2F0ZXJfc291cmNlIn0pKTsKKyAgU2V0UHJvcChQX05BTUUsICJXYXNzZXJiZWhhZWx0ZXIiKTsKKyAgU2V0UHJvcChQX0dFTkRFUiAsIE1BTEUpOworICBTZXRQcm9wKFBfQVJUSUNMRSwgMSk7CisgIFNldFByb3AoUF9TSE9SVCwgIkVpbiBTdGFuZGFyZC1XYXNzZXJiZWhhZWx0ZXIiKTsKKyAgU2V0UHJvcChQX0xPTkcsIm5vbmUiKTsKKyAgU2V0KFBfTE9ORywgIydkeW5hbWljX2xvbmcsIEZfUVVFUllfTUVUSE9EKTsKKyAgU2V0UHJvcChQX0xPTkdfRU1QVFksIiIpOyAvLyBCZXNjaHJlaWJ1bmcgZnVlciBsZWVyZW4gWnVzdGFuZAorICBTZXRQcm9wKFBfTE9OR19GVUxMLCIiKTsgIC8vIEJlc2NocmVpYnVuZyBmdWVyIGdlZnVlbGx0ZW4gWnVzYW5kCisgIFNldFByb3AoUF9MSVFVSUQsMTAwMCk7ICAgLy8gRnVlbGxtZW5nZSA9IDEgTGl0ZXIKKyAgU2V0UHJvcChQX1dBVEVSLDApOyAgICAgICAvLyBGbGFzY2hlIGlzdCBkZWZhdWx0bWFlc3NpZyBsZWVyIQorICBTZXRQcm9wKFBfVkFMVUUsMTApOworCisgIC8vIFBfV0VJR0hUIGF1ZiBMZWVyZ2V3aWNodCBkZXIgRmxhc2NoZSBzZXR6ZW4sIFF1ZXJ5TWV0aG9kZSBsaWVmZXJ0CisgIC8vIGRpZSBTdW1tZSBhdXMgTGVlcmdld2ljaHQrRnVlbGx1bmcgenVydWVjayAoRGljaHRlID0gMSkuCisgIFNldFByb3AoUF9XRUlHSFQsMjApOworICBTZXQoUF9XRUlHSFQsIGZ1bmN0aW9uIGludCAoKSB7CisgICAgIHJldHVybiAoIFF1ZXJ5KFBfV0VJR0hULEZfVkFMVUUpKworICAgICAgICAgICAgICAoUXVlcnlQcm9wKFBfV0FURVIpP1F1ZXJ5UHJvcChQX0xJUVVJRCk6MCkgKTsKKyAgICAgfSwgRl9RVUVSWV9NRVRIT0QpOworCisgIEFkZENtZCgoeyJmdWVsbCIsImZ1ZWxsZSJ9KSwiY21kX2Z1ZWxsZSIpOworICBBZGRDbWQoKHsibGVlcmUiLCAiZW50bGVlcmUifSksImNtZF9sZWVyZSIpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKworLy8gQmVoYWVsdGVyIGlzdCBnZWZ1ZWxsdCwgZGFubiBpc3QgZGllIExhbmdiZXNjaHJlaWJ1bmcgZW50d2VkZXIgZGllIAorLy8gUF9MT05HX0ZVTEwsIGZhbGxzIGFuZ2VnYmVuLCBvZGVyIGRpZSBQX0xPTkcgKyBCZXNjaHJlaWJ1bmcgZGVyIEZ1ZWxsdW5nLgorLy8gR2VuYXVzbywgd2VubiBzaWUgbGVlciBpc3QuCitzdHJpbmcgZHluYW1pY19sb25nKCkgeworICBzdHJpbmcgbD1RdWVyeShQX0xPTkcsRl9WQUxVRSk7CisgIGlmICggUXVlcnlQcm9wKFBfV0FURVIpICkgeworICAgIHN0cmluZyBsZiA9IFF1ZXJ5UHJvcChQX0xPTkdfRlVMTCk7CisgICAgaWYgKCBzdHJpbmdwKGxmKSAmJiBzaXplb2YobGYpICkKKyAgICAgIGw9bGY7CisgICAgZWxzZQorICAgICAgbCs9Y2FwaXRhbGl6ZShRdWVyeVByb25vdW4oV0VSKSkrIiBlbnRoYWVsdCAiK2xpcXVpZF9uYW1lKyIuXG4iOworICAgIC8vIEZhbGxzIGRpZSBGbGFzY2hlIG1pdCBldHdhcyBhbmRlcmVtIGFscyBXYXNzZXIgZ2VmdWVsbHQgd2lyZCwgZGllCisgICAgLy8gTGFuZ2Jlc2NocmVpYnVuZyBmdWVyICJ2b2xsZSBGbGFzY2hlIiAoUF9MT05HX0ZVTEwpIGFiZXIgbnVyIGZ1ZXIKKyAgICAvLyBXYXNzZXIgYXVzZ2VsZWd0IGlzdCwgd2lyZCAiV2Fzc2VyIiBkdXJjaCBkZW4gSW5oYWx0IHZvbiBsaXF1aWRfbmFtZQorICAgIC8vIGVyc2V0enQuCisgICAgaWYgKCBsaXF1aWRfbmFtZSAhPSBERUZBVUxUX0xJUSApCisgICAgICBsPXJlZ3JlcGxhY2UobCwgREVGQVVMVF9MSVEsIGxpcXVpZF9uYW1lLCAxKTsKKyAgfSBlbHNlIHsKKyAgICBzdHJpbmcgbGUgPSBRdWVyeVByb3AoUF9MT05HX0VNUFRZKTsKKyAgICBpZiAoIHN0cmluZ3AobGUpICYmIHNpemVvZihsZSkgKQorICAgICAgbD1sZTsKKyAgICBlbHNlCisgICAgICBsKz1jYXBpdGFsaXplKFF1ZXJ5UHJvbm91bihXRVIpKSsiIGlzdCBsZWVyLlxuIjsKKyAgfQorICByZXR1cm4gbDsKK30KKworLy8gWnVtIFVlYmVyc2NocmVpYmVuISBQcmV2ZW50SW5zZXJ0KG9iamVjdCBvYil7cmV0dXJuIDA7fSB6LkIuCisvLyBtYWNodCBkaWUgRmxhc2NoZSBnYXNkaWNodC4KKy8vIE9kZXIgbWFuIGthbm4gZGllIEZsYXNjaGUgdmVyc2NobGllc3NiYXIgbWFjaGVuLgoraW50IFByZXZlbnRJbnNlcnQob2JqZWN0IG9iaikKK3sKKyAgaWYob2JqLT5pZCgiZ2FzIikpIHsgLy9kZWZhdWx0OiBOSUNIVCBHYXNkaWNodCEKKyAgICB3cml0ZShvYmotPk5hbWUoV0VSLDEpKyIgZW50d2VpY2h0IHNvZm9ydCB3aWVkZXIhXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworLy8gVHJhbnNmZXJpZXJ0IGRlbiBJbmhhbHQgZGVyIEZsYXNjaGUgYW4gPGRlc3Q+Citwcm90ZWN0ZWQgaW50IHRyYW5zZmVyX3RvKG9iamVjdCBkZXN0KQoreworICBpbnQgd2F0ZXI9UXVlcnlQcm9wKFBfV0FURVIpOworICBpZiAoIXdhdGVyKQorICB7CisgICAgd3JpdGUoTmFtZShXRVIsMSkgKyAiIGlzdCBzY2hvbiBsZWVyIVxuIik7CisgICAgcmV0dXJuIDA7ICAgLy8gV2FyIHNjaG9uIGxlZXIhCisgIH0KKyAgaW50IGNvbnRlbnRzPVF1ZXJ5UHJvcChQX0xJUVVJRCk7CisKKyAgaWYgKCB3YXRlciZXX09USEVSICkKKyAgeworICAgIGRlc3QtPlB1dExpcXVpZChjb19maWxlbmFtZSk7CisgIH0KKyAgZWxzZQorICB7CisgICAgZGVzdC0+QWRkV2F0ZXIoY29udGVudHMpOworICB9CisgIFNldFByb3AoUF9XQVRFUiwwKTsKKyAgUmVtb3ZlSWQobG93ZXJfY2FzZShsaXF1aWRfbmFtZSkpOworICBsaXF1aWRfbmFtZT1ERUZBVUxUX0xJUTsKKyAgcmV0dXJuIGNvbnRlbnRzOyAvL2dpYiBkaWUgbWwgYW4gVW1nZWJ1bmcgYWIgOikKK30KKworLy8gRW50bGVlcnQgZGllIEZsYXNjaGUgaW5zIEVudmlyb25tZW50IGRlciBGbGFzY2hlLCBhbGxlcmRpbmdzIG5pY2h0LCB3ZW5uCisvLyBkaWVzIGVpbiBMZWJld2VzZW4gaXN0LCBkYW5uIHdpcmQgZGFzIEVudmlyb25tZW50IHZvbiBkZW0gZ2Vub21tZW4uCisvLyBUT0RPOiBFaW5lIEZsYXNjaGUgaW4gZWluZW0gUGFrZXQgbGVlcmVuIHd1cmRlIGRhbm4gaW4gZGFzIHBha2V0IGVudGxlZXJlbi4KKy8vIERhcyB3YWVyZSBhbiBzaWNoIHNvZ2FyIHJpY2h0aWcuLi4gTnVyOiBnZXdvbGx0PyBBbHRlcm5hdGl2ZSBrb2VubmVuIHdpcgorLy8gYXVjaCBkYXMgYWV1c3NlcnN0ZSBFbnZpcm9ubWVudCBuZWhtZW4sIHdhcyBuaWNodCBsZWJ0LgorcHVibGljIGludCBlbXB0eSgpCit7CisgIGlmIChlbnZpcm9ubWVudCgpKQorICB7CisgICAgLy8gRW52aXJvbm1lbnQgZGVzIEJlbnV0emVycyBmaW5kZW4uCisgICAgb2JqZWN0IGVudiA9IGVudmlyb25tZW50KCk7CisgICAgd2hpbGUgKGxpdmluZyhlbnYpKQorICAgICAgZW52PWVudmlyb25tZW50KGVudik7CisgICAgcmV0dXJuIHRyYW5zZmVyX3RvKGVudik7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKy8vIEZ1ZWxsdCBkaWUgRmxhc2NoZSBhdXMgPHNyYz4KK3Byb3RlY3RlZCBpbnQgZmlsbF9ib3R0bGUob2JqZWN0IHNyYykKK3sKKyAgaW50IGxpcXVpZHR5cGUgPSBzcmMtPlF1ZXJ5UHJvcChQX1dBVEVSKTsKKyAgaWYobGlxdWlkdHlwZSkKKyAgeworICAgIGlmKFF1ZXJ5UHJvcChQX1dBVEVSKSkgeworICAgICAgd3JpdGUoTmFtZShXRVIsMSkrIiBpc3QgYmVyZWl0cyB2b2xsIVxuIik7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgLy8gV2Fzc2VyIHZvbiBVbWdlYnVuZyBhYnppZWhlbiEKKyAgICAvLyBNYW4ga2FubiBhbHMgTWFnaWVyIGRpZSBGdW5rdGlvbiBBZGRXYXRlcihpbnQgbikgZGF6dSBiZW51ZXR6dGVuLAorICAgIC8vIGJlaXNwaWVsc3dlaXNlIGVpbmUgUGZ1ZXR6ZSB6dSBsZWVyZW4sIC4uLgorICAgIHNyYy0+QWRkV2F0ZXIoLVF1ZXJ5UHJvcChQX0xJUVVJRCkpOworICAgIG9iamVjdCBjb250X29iajsKKyAgICBpZihsaXF1aWR0eXBlJldfT1RIRVIpCisgICAgeworICAgICAgLy8gTWl0dGVscyBHZXRMaXF1aWQoKSBrYW5uIGRpZSBGbGFzY2hlIG1pdCB3YXMgYW5kZXJlbSBhbHMgV2Fzc2VyCisgICAgICAvLyBnZWZ1ZWxsdCB3ZXJkZW4uCisgICAgICBjb19maWxlbmFtZT1zcmMtPkdldExpcXVpZCgpOworICAgICAgaWYgKGNvX2ZpbGVuYW1lKQorICAgICAgeworICAgICAgICBjb250X29iaj1jbG9uZV9vYmplY3QoY29fZmlsZW5hbWUpOworICAgICAgICBpZihQcmV2ZW50SW5zZXJ0KGNvbnRfb2JqKSkKKyAgICAgICAgeworICAgICAgICAgIC8vIEhpZXIgcGFzc2llcnQgZWlnZW50bGljaCBkYXMgZ2xlaWNoZSB3aWUgbmFjaCBkZW0gaWZibG9jaywgYWJlcgorICAgICAgICAgIC8vIGF1Y2ggbm9jaCBGdW5rdGlvbiBiZWVuZGVuLgorICAgICAgICAgIC8vIFRPRE86IFJ1ZWNrZ2FlbmlnIG1hY2hlbiB2b24gQWRkV2F0ZXIoKT8KKyAgICAgICAgICAvLyBUT0RPOiBEaWUgTWVsZHVuZyBhdXMgZGVtIFByZXZlbnRJbnNlcnQoKSBtdWVzc3RlIGVpZ2VudGxpY2gKKyAgICAgICAgICAvLyBfdm9yaGVyXyBub2NoIG1pdCBlaW5lciBCZWZ1ZWxsbWVsZHVuZyBiZWdsZWl0ZXQgd2VyZGVuLgorICAgICAgICAgIGNvbnRfb2JqLT5yZW1vdmUoMSk7CisgICAgICAgICAgaWYgKCBvYmplY3RwKGNvbnRfb2JqKSApCisgICAgICAgICAgICBjb250X29iai0+bW92ZSgiL3Jvb20vbXVlbGxyYXVtIixNX1BVVCk7CisgICAgICAgICAgY29udF9vYmo9MDsKKyAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgbGlxdWlkX25hbWU9Y29udF9vYmotPm5hbWUoV0VOKTsKKyAgICAgICAgLy8gSW4gamVkZW0gRmFsbCB3aXJkIGRhcyBPYmpla3Qgd2llZGVyIHplcnN0b2VydCAtIGVzIHd1cmRlIG51ciBmdWVyCisgICAgICAgIC8vIGRhcyBFcm1pdHRlbG4gZGVzIGxpcXVpZF9uYW1lIGJlbnV0enQuLi4gV2VpYS4KKyAgICAgICAgaWYgKCBjb250X29iaiApIGNvbnRfb2JqLT5yZW1vdmUoKTsKKyAgICAgICAgaWYgKCBjb250X29iaiApIGNvbnRfb2JqLT5tb3ZlKCIvcm9vbS9tdWVsbHJhdW0iLE1fUFVUKTsKKyAgICAgIH0KKyAgICB9CisgICAgU2V0UHJvcChQX1dBVEVSLGxpcXVpZHR5cGUpOworICAgIEFkZElkKGxvd2VyX2Nhc2UobGlxdWlkX25hbWUpKTsKKyAgICAvL3dpZSBwcmFrdGlzY2gsIDEgbWwgPT0gMSBnIDopIC8vIEFiZXIgbnVyIGZ1ZXIgV2Fzc2VyLCBkdSBWT0dFTCEgOi18CisgICAgcmV0dXJuIDE7CisgIH0KKyAgZWxzZSB7CisgICAgd3JpdGUoIkR1IGZpbmRlc3QgaGllciBuaWNodHMsIHdhcyBEdSBpbiAiK25hbWUoV0VOLDEpKworICAgICAgIiBmdWVsbGVuIGtvZW5udGVzdCFcbiIpOworICAgIHJldHVybiAwOworICB9CisgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50IGNtZF9sZWVyZShzdHJpbmcgc3RyKQoreworICBvYmplY3QgZGVzdDsKKyAgbm90aWZ5X2ZhaWwoIldhcyB3aWxsc3QgRHUgZGVubiAod28gaGluZWluKSBsZWVyZW4/XG4iKTsKKyAgaWYgKCFzdHIpCisgICAgcmV0dXJuIDA7CisKKyAgc3RyaW5nIHN0cmJvdHRsZSxzdHJvYmo7CisgIC8vIGxlZXJlIGZsYXNjaGUKKyAgaWYgKGlkKHN0cikpCisgIHsKKyAgICAvL05PT1AKKyAgfQorICAvLyBsZWVyZSBmbGFzY2hlIGluIHh4eAorICBlbHNlIGlmIChzc2NhbmYoc3RyLCIlcyBpbiAlcyIsc3RyYm90dGxlLHN0cm9iaik9PTIpCisgIHsKKyAgICBpZiAoIWlkKHN0cmJvdHRsZSkpCisgICAgICByZXR1cm4gMDsKKyAgICBkZXN0ID0gcHJlc2VudChzdHJvYmosIGVudmlyb25tZW50KHRoaXNfcGxheWVyKCkpKQorICAgICAgICAgICB8fCBwcmVzZW50KHN0cm9iaiwgdGhpc19wbGF5ZXIoKSk7CisgICAgaWYgKCFkZXN0KQorICAgICAgcmV0dXJuIDA7CisgIH0KKyAgZWxzZQorICAgIHJldHVybiAwOworICAvLyBTeW50YXhwcnVlZnVuZyBmZXJ0aWcuCisKKyAgaWYoIVF1ZXJ5UHJvcChQX1dBVEVSKSkKKyAgeworICAgIHdyaXRlKCJEYSBpc3Qga2VpbiAiK2xpcXVpZF9uYW1lKyIgZHJpbiFcbiIpOworICAgIHJldHVybiAxOworICB9CisKKyAgaWYgKGRlc3QpCisgIHsKKyAgICB3cml0ZShicmVha19zdHJpbmcoIkR1IGxlZXJzdCAiK25hbWUoV0VOLDEpKyAiIGluICIKKyAgICAgICAgICArIGRlc3QtPm5hbWUoV0VOKSArICIuIiw3OCkpOworICAgIHNheShicmVha19zdHJpbmcoVFAtPm5hbWUoKSsiIGxlZXJ0ICIrbmFtZShXRU4sMCkKKyAgICAgICAgICArICIgaW4gIiArIGRlc3QtPm5hbWUoV0VOKSArICIuIiw3OCksVFApOworICAgIHRyYW5zZmVyX3RvKGRlc3QpOworICAgIHJldHVybiAxOworICB9CisgIHdyaXRlKGJyZWFrX3N0cmluZygiRHUgbGVlcnN0ICIrbmFtZShXRU4sMSkrIi4iLDc4KSk7CisgIHNheShicmVha19zdHJpbmcoVFAtPm5hbWUoKSsiIGxlZXJ0ICIrbmFtZShXRU4sMCkrIi4iLDc4KSxUUCk7CisgIGVtcHR5KCk7CisgIHJldHVybiAxOworfQorCitwdWJsaWMgaW50IGNtZF9mdWVsbGUoc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nIHN0cmJvdHRsZSxzdHJvYmo7CisKKyAgbm90aWZ5X2ZhaWwoIldhcyB3aWxsc3QgRHUgZGVubiAod29taXQpIGZ1ZWxsZW4/XG4iKTsKKyAgaWYoIXN0cikKKyAgICByZXR1cm4gMDsKKworICAvLyBmdWVsbGUgZmxhc2NoZQorICBpZiAoaWQoc3RyKSkKKyAgeworICAgIGlmIChmaWxsX2JvdHRsZShlbnZpcm9ubWVudCh0aGlzX3BsYXllcigpKSkpCisgICAgeworICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJEdSBmdWVsbHN0IGV0d2FzICIrbGlxdWlkX25hbWUrIiBpbiAiCisgICAgICAgICAgICArbmFtZShXRU4sMSkrIi4iLDc4KSk7CisgICAgICBzYXkoYnJlYWtfc3RyaW5nKFRQLT5OYW1lKFdFUikrIiBmdWVsbHQgZXR3YXMgIgorICAgICAgICAgICAgK2xpcXVpZF9uYW1lKyIgaW4gIituYW1lKFdFTikrIi4iLDc4KSwgVFApOworICAgIH0KKyAgICByZXR1cm4gMTsKKyAgfQorICAvLyBmdWVsbGUgZmxhc2NoZSBhdXMgeHh4CisgIC8vIGZ1ZWxsZSBmbGFzY2hlIG1pdCB4eHgKKyAgLy8gZnVlbGxlIHh4eCBpbiBmbGFzY2hlCisgIC8vIGZ1ZWxsZSBmbGFzY2hlIGluIHh4eAorICAvLyBmdWVsbGUgeHh4IGF1cyBmbGFzY2hlCisgIC8vIGZ1ZWxsZSB4eHggbWl0IGZsYXNjaGUKKyAgZWxzZSBpZiAoc3NjYW5mKHN0ciwiJXMgaW4gJXMiLHN0cm9iaixzdHJib3R0bGUpPT0yCisgICAgICAgICAgIHx8IHNzY2FuZihzdHIsIiVzIG1pdCAlcyIsc3RyYm90dGxlLHN0cm9iaik9PTIKKyAgICAgICAgICAgfHwgc3NjYW5mKHN0ciwiJXMgYXVzICVzIixzdHJib3R0bGUsc3Ryb2JqKT09MikKKyAgeworICAgIG9iamVjdCBvYmo7CisgICAgLy8gRmxhc2NoZSBiZWZ1ZWxsZW4/CisgICAgaWYgKGlkKHN0cmJvdHRsZSkKKyAgICAgICAgJiYgKCBvYmo9cHJlc2VudChzdHJvYmosIGVudmlyb25tZW50KHRoaXNfcGxheWVyKCkpKSAKKyAgICAgICAgICAgICAgICAgfHwgcHJlc2VudChzdHJvYmosIHRoaXNfcGxheWVyKCkpICkKKyAgICAgICApCisgICAgeworICAgICAgaWYgKGZpbGxfYm90dGxlKG9iaikpCisgICAgICB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygKKyAgICAgICAgICAgICAgIkR1IGZ1ZWxsc3QgZXR3YXMgIitsaXF1aWRfbmFtZSsiIGF1cyAiICsgb2JqLT5uYW1lKFdFTSwxKSAKKyAgICAgICAgICAgICAgKyAiIGluICIrbmFtZShXRU4sMSkrIi4iLDc4KSk7CisgICAgICAgIHNheShicmVha19zdHJpbmcoVFAtPk5hbWUoV0VSKSsiIGZ1ZWxsdCBldHdhcyAiK2xpcXVpZF9uYW1lKyAiIGF1cyAiIAorICAgICAgICAgICAgICArIG9iai0+bmFtZShXRU0sMSkgKyAiIGluICIrbmFtZShXRU4pKyIuIiw3OCksIFRQKTsKKyAgICAgIH0KKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICAvLyBhbmRlcmVzIEdlZmFlc3MgYmVmdWVsbGVuPworICAgIGVsc2UgaWYgKGlkKHN0cm9iaikKKyAgICAgICAgJiYgKCBvYmo9cHJlc2VudChzdHJib3R0bGUsIGVudmlyb25tZW50KHRoaXNfcGxheWVyKCkpKSAKKyAgICAgICAgICAgICAgICAgfHwgcHJlc2VudChzdHJib3R0bGUsIHRoaXNfcGxheWVyKCkpICkKKyAgICAgICApCisgICAgeworICAgICAgaWYgKHRyYW5zZmVyX3RvKG9iaikpCisgICAgICB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygKKyAgICAgICAgICAgICAgIkR1IGZ1ZWxsc3QgZXR3YXMgIitsaXF1aWRfbmFtZSsiIGF1cyAiICsgbmFtZShXRU0sMSkKKyAgICAgICAgICAgICAgKyAiIGluICIrb2JqLT5uYW1lKFdFTiwxKSsiLiIsNzgpKTsKKyAgICAgICAgc2F5KGJyZWFrX3N0cmluZyhUUC0+TmFtZShXRVIpKyIgZnVlbGx0IGV0d2FzICIrbGlxdWlkX25hbWUrICIgYXVzICIgCisgICAgICAgICAgICAgICsgbmFtZShXRU0sMSkgKyAiIGluICIrb2JqLT5uYW1lKFdFTikrIi4iLDc4KSwgVFApOworICAgICAgfQorICAgICAgcmV0dXJuIDE7CisgICAgfQorICB9CisgIC8vIFN5bnRheCBwYXNzdCBuaWNodC4KKyAgcmV0dXJuIDA7Cit9CisKK2ludCBJc0JvdHRsZSgpIHsKKyAgIHJldHVybiAxOworfQorCmRpZmYgLS1naXQgYS9zdGQvaXRlbXMva3JhZXV0ZXIva3JhdXQuYyBiL3N0ZC9pdGVtcy9rcmFldXRlci9rcmF1dC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJjZTUwNDUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvaXRlbXMva3JhZXV0ZXIva3JhdXQuYwpAQCAtMCwwICsxLDE5NSBAQAorLy8gKGMpIFNlcHRlbWJlciAyMDAwIGJ5IFBhZHJlaWMgKFBhZHJlaWNAbWcubXVkLmRlKQorCisjcHJhZ21hIHN0cm9uZ190eXBlcywgc2F2ZV90eXBlcywgcnR0X2NoZWNrcworCitpbmhlcml0ICIvc3RkL3RoaW5nIjsKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxpdGVtcy9rcmFldXRlci9rcmFldXRlci5oPgorCisjZGVmaW5lIFBMQU5UX0xJRkVUSU1FICAoMjQqMzYwMCkKKyNkZWZpbmUgRlJFU0hfVElNRSAgICAgICg2KjM2MDApCisvLyBEaWUgcGxhbnRJRCB3aXJkIGZ1ZXIgdW5ndWVsdGlnIGVyc2NoYWZmZW5lIEtyYWV1dGVyIGF1ZiAtMSBnZXNldHp0LgorI2RlZmluZSBEUklFRF9QTEFOVCAgICAgLTEKKworcHJpdmF0ZSBpbnQgYWdlPXRpbWUoKTsKKy8vIGVudGhhZWx0IGRpZSBOdW1tZXIgZGVzIEtyYXV0cworcHJpdmF0ZSBpbnQgcGxhbnRJZDsKKy8vIGVudGhhZWx0IGRlbiBQZmFkIGRlcyBjbG9uZW5kZW4gT2JqZWt0cworcHJpdmF0ZSBzdHJpbmcgY2xvbmVyOworLy8gUXVhbGl0YWV0IGRlcyBLcmF1dGVzLgorcHJpdmF0ZSBpbnQgcXVhbGl0eT0xMDA7CisKKy8vIEZpbGUga2FubiBlaW4gbmFtZSBzZWluLCBkZXNzZW4gRWlnZW5zY2hhZnRlbiBkZXIgVkMga29uZmlndXJpZXJlbiBzZWluCisvLyBvZGVyIDAsIHdlbm4gZXIgc2VsYmVyIGVybWl0dGVsbiBzb2xsLCB3YXMgZnVlciBlaW4gRmlsZSBlciBnZXJhZGUgZXJ6ZXVndAorLy8gaGF0LgorLy8gU3ByaWNoOiByZWFsIGV4aXN0aWVyZW5kZSBGaWxlcyBhdWYgZGVyIFBsYXR0ZSBtdWVzc2VuIGRhIGlocmVuIE5hbWVuCisvLyBhbmdlYmVuLCBTdGFuZGFyZGZhbGwgaXN0IGFiZXIsIGRhc3MgbWFuIDAgYW5naWJ0IHVuZCBkZXIgVkMgd2Vpc3MsIHdhcyBlcgorLy8gZ2VyYWRlIGVyemV1Z3QgaGF0Lgordm9pZCBjdXN0b21pemVNZShzdHJpbmcgZmlsZSkKK3sKKyAgaWYgKHN0cmluZ3AoZmlsZSkpIAorICAgIGZpbGU9ZXhwbG9kZShmaWxlLCAiLyIpWzwxXTsKKyAgS1JBRVVURVJWQy0+Q3VzdG9taXplT2JqZWN0KGZpbGUpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBpZiAob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bMC4uPDNdKQorICB7CisgICAgc2V0X25leHRfcmVzZXQoLTEpOworICAgIHJldHVybjsKKyAgfQorICA6OmNyZWF0ZSgpOworIAorICBTZXQoUF9RVUFMSVRZLCBmdW5jdGlvbiBpbnQgKCkgeyByZXR1cm4gcXVhbGl0eTsgfSwgRl9RVUVSWV9NRVRIT0QpOworICBTZXRQcm9wKFBfV0VJR0hULCAxMjApOworICBTZXRQcm9wKFBfVkFMVUUsIDcwKTsKKyAgU2V0UHJvcChQX01BVEVSSUFMLCBNQVRfTUlTQ19QTEFOVCk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpCit7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKworcHVibGljIHN0cmluZyBzaG9ydCgpCit7CisgIHN0cmluZyBzdHI9UXVlcnlQcm9wKFBfU0hPUlQpOworICBpZiAoIXN0cmluZ3Aoc3RyKSkgCisgICAgICByZXR1cm4gMDsKKyAgaWYgKHBsYW50SWQ9PS0xKQorICAgICAgcmV0dXJuIHN0cisiICh1bndpcmtzYW0pLlxuIjsKKyAgZWxzZSBpZiAoYWdlPT1EUklFRF9QTEFOVCkKKyAgICAgcmV0dXJuIHN0cisiIChnZXRyb2NrbmV0KS5cbiI7CisgIGVsc2UgaWYgKGFnZStGUkVTSF9USU1FK1BMQU5UX0xJRkVUSU1FPHRpbWUoKSkKKyAgICAgcmV0dXJuIHN0cisiICh2ZXJmYXVsdCkuXG4iOworICByZXR1cm4gc3RyKyIuXG4iOworfQorCisvLyBMaWVmZXJ0IGVpbmVuIFNrYWxpZXJ1bmdzZmFrdG9yIHp1cnVlY2ssIGRlciBtaXQgZGVtIGFrdHVlbGxlbiBXZXJ0IHZvbgorLy8gUF9RVUFMSVRZIHZlcnJlY2huZXQgd2lyZC4gUnVlY2tnYWJld2VydGU6CisvLyBQZmxhbnplIGdldHJvY2tuZXQgb2RlciBuaWNodCBhZWx0ZXIgYWxzIDYgaCA6IDEwMAorLy8gUGZsYW56ZSBhZWx0ZXIgYWxzIDYsIGFiZXIganVlbmdlciBhbHMgMzAgaCA6IDk5Li4uMQorLy8gUGZsYW56ZSBhZWx0ZXIgYWxzIDMwIGg6IDAuCisvLyBEcnlQbGFudCgpIHplcnN0b2VydCBkYXMgS3JhdXQsIHdlbm4gUF9RVUFMSVRZIHVudGVyIDEgZmFlbGx0LgorcHVibGljIGludCBQbGFudFF1YWxpdHkoKQoreworICBpbnQgZmFjdG9yOworICAvLyBzY2hvbiBnZXRyb2NrbmV0IG9kZXIgbmljaHQgYWVsdGVyIGFscyA2IGg/IAorICAvLyBEYW5uIGtlaW5lIHdlaXRlcmUgUmVkdWt0aW9uLgorICBpZiAoIGFnZSA9PSBEUklFRF9QTEFOVCB8fCBhZ2UrRlJFU0hfVElNRSA+IHRpbWUoKSkgCisgICAgZmFjdG9yID0gMTAwOworICAvLyA+MzAgU3R1bmRlbiBuYWNoIGRlbSBQZmx1ZWNrZW4gaXN0IGRhcyBLcmF1dCB2ZXJzY2hpbW1lbHQuCisgIGVsc2UgaWYgKCBhZ2UgKyBGUkVTSF9USU1FICsgUExBTlRfTElGRVRJTUUgPCB0aW1lKCkgKSAKKyAgICBmYWN0b3IgPSAxOworICAvLyBaZWl0IHp3aXNjaGVuIDYgdW5kIDMwIFN0dW5kZW4gbmFjaCBkZW0gUGZsdWVja2VuIGluIDk5IGdsZWljaG1hZXNzaWdlCisgIC8vIEFic2Nobml0dGUgdW50ZXJ0ZWlsZW4uIDI0IGggc2luZCA4NjQwMCBzLCA4NjQwMC85OSA9IDg3My4KKyAgZWxzZQorICAgIGZhY3Rvcj0odGltZSgpLWFnZS1GUkVTSF9USU1FKS84NzM7CisKKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX1FVQUxJVFkpKmZhY3Rvci8xMDA7Cit9CisKKy8vIFdpZSBsYW5nZSAoaW4gU2VrdW5kZW4pIGlzdCBkYXMgS3JhdXQgbm9jaCBoYWx0YmFyPworcHVibGljIGludCBUaW1lVG9MaXZlKCkKK3sKKyAgaWYgKCBhZ2UgPT0gRFJJRURfUExBTlQgKQorICAgIHJldHVybiBfX0lOVF9NQVhfXzsKKyAgcmV0dXJuIGFnZS10aW1lKCkrUExBTlRfTElGRVRJTUU7Cit9CisKKy8vVE9ETzogdmllbGxlaWNodCBldHdhcyB6dWZhbGw/IFNvbnN0IEtyYWV1dGVycXVhbGl0YWV0IGhpZXJhbiBlcm1pdHRlbGJhci4KK3N0YXRpYyBpbnQgX3F1ZXJ5X3ZhbHVlKCkKK3sKKyAgaW50IHZhbCA9IFF1ZXJ5KFBfVkFMVUUsRl9WQUxVRSkqUGxhbnRRdWFsaXR5KCkvMTAwOworICBpZiAocGxhbnRJZDw9MCB8fCB2YWwgPSAwKQorICAgIHJldHVybiAwOworICByZXR1cm4gdmFsLXZhbCUxMDsKK30KKworc3RhdGljIHN0cmluZyBfcXVlcnlfbm9zZWxsKCkgCit7CisgIGlmIChhZ2UgIT0gRFJJRURfUExBTlQpCisgICAgcmV0dXJuICJNaXQgdW5nZXRyb2NrbmV0ZW4gS3JhZXV0ZXJuIGhhbmRlbGUgaWNoIG5pY2h0LiBEaWUgdmVyZGVyYmVuICIKKyAgICAgICJpbW1lciBzbyBzY2huZWxsIGltIExhZ2VyLCB1bmQgZGFubiB3ZXJkZSBpY2ggc2llIG5pY2h0IHdpZWRlciBsb3MuIjsKKyAgcmV0dXJuIDA7Cit9CisKKy8vIE1pdCBEcnlQbGFudCgpIHdpcmQgZGllIFBmbGFuemUgZ2V0cm9ja25ldC4gQWxzIEFyZ3VtZW50IHdpcmQgZGVyIFByb3plbnQtCisvLyB3ZXJ0IHVlYmVyZ2ViZW4sIGF1ZiBkZW4gZGllIFF1YWxpdGFldCBzaW5rZW4gc29sbC4gQWxzIEF1c2dhbmdzd2VydAorLy8gZGllc2VyIEJlcmVjaG51bmcgd2lyZCBkZXIgUnVlY2tnYWJld2VydCB2b24gUGxhbnRRdWFsaXR5KCkgdmVyd2VuZGV0LgorLy8gSGludGVyZ3J1bmQ6IERpZSBRdWFsaXRhZXQgZGVzIEtyYXV0cyBzaW5rdCBpbSB1bmdldHJvY2tuZXRlbiBadXN0YW5kCisvLyB1ZWJlciBlaW5lbiBaZWl0cmF1bSB2b24gMjQgaCBrb250aW51aWVybGljaCB2b24gMTAwIGF1ZiAxIGFiLCBzb2JhbGQKKy8vIGVzIGFlbHRlciBhbHMgNiBTdHVuZGVuIGlzdC4gRGFuYWNoIGlzdCBlcyB2ZXJzY2hpbW1lbHQsIHdhcyBhYmVyIHNlaW5lcgorLy8gdmVyYmxlaWJlbmRlbiAiV2lya3VuZyIga2VpbmVuIEFiYnJ1Y2ggdHV0LgorLy8gRXMgd2lyZCBkaWUgenVtIFplaXRwdW5rdCBkZXMgVHJvY2tudW5nc3ZvcmdhbmdlcyBndWVsdGlnZSBRdWFsaXRhZXQKKy8vIGFsc28gc296dXNhZ2VuICJlaW5nZWZyb3JlbiIgdW5kIGVudHNwcmVjaGVuZCBkZW0gUnVlY2tnYWJld2VydCB2b24KKy8vIFBsYW50UXVhbGl0eSgpIGhlcnVudGVyZ2VyZWNobmV0LgorCisvLyBEaWVzZSBGdW5rdGlvbiBrYW5uIG5hdHVlcmxpY2ggYXVjaCB1ZWJlcnNjaHJpZWJlbiB3ZXJkZW4sIHdlbm4gYmVzdGltbXRlCisvLyBLcmFldXRlciBlcnN0IGR1cmNoIHRyb2NrbmVuIGluIGRlciBRdWFsaXRhZXQgc3RlaWdlbi4KKworLy8gVE9ETzogSXN0IGRhcyBBcmd1bWVudCAicXVhbCIgZGFiZWkgcHJvemVudHVhbCBhdWZ6dWZhc3Nlbiwgb2RlciAKKy8vIHNvbGwgbnVyIGVpbiBub2NoIHp1IGJlc3RpbW1lbmRlciBGZXN0d2VydCBhYmdlem9nZW4gd2VyZGVuPworLy8gQXJhdGhvcm46IEVzIGJsZWlidCBqZXR6dCBlcnN0bWFsIHByb3plbnR1YWwuCisKKyNkZWZpbmUgRFJZSU5HX0FMTE9XRUQgKHtQTEFOVE1BU1RFUiwgIi9pdGVtcy9rcmFldXRlci90cm9ja25lciJ9KQorCitwdWJsaWMgdm9pZCBEcnlQbGFudChpbnQgcXVhbCkgCit7CisgIC8vIEtlaW5lIG1laHJmYWNoZSBUcm9ja251bmcgenVsYXNzZW4uCisgIGlmICggYWdlID09IERSSUVEX1BMQU5UICkKKyAgICByZXR1cm47CisgCisgIC8vIE51ciBiZXN0aW1tdGUgT2JqZWt0ZSBkdWVyZmVuIFRyb2NrbnVuZ2VuIGF1c2xvZXNlbi4KKyAgaWYgKCBtZW1iZXIoRFJZSU5HX0FMTE9XRUQsIGxvYWRfbmFtZShwcmV2aW91c19vYmplY3QoKSkpID09IC0xICkKKyAgICByZXR1cm47CisKKyAgLy8gUXVhbGl0YWV0IGF1ZiAxMDAgZGVja2Vsbi4KKyAgaWYgKCBxdWFsPjEwMCApCisgICAgcXVhbCA9IDEwMDsKKyAgCisgIC8vIFF1YWxpdGFldCBtaXR0ZWxzIFBsYW50UXVhbGl0eSgpIHJ1bnRlcnNrYWxpZXJlbi4KKyAgcXVhbCA9IFBsYW50UXVhbGl0eSgpKnF1YWwvMTAwOworICAKKyAgaWYgKCBxdWFsIDwgMSApIHsKKyAgICBpZihvYmplY3RwKHRoaXNfcGxheWVyKCkpKQorICAgICAgdGVsbF9vYmplY3QodGhpc19wbGF5ZXIoKSwgCisgICAgICAgIE5hbWUoV0VSLDEpKyIgemVyZmFlbGx0IGluIHVuemFlaGxpZ2UgZmVpbmUgS3J1ZW1lbC5cbiIpOworICAgIHJlbW92ZSgpOworICAgIHJldHVybjsKKyAgfQorICAvLyBLcmF1dCBhbHMgZ2V0cm9ja25ldCBrZW5uemVpY2huZW4uCisgIGFnZT1EUklFRF9QTEFOVDsKKyAgcXVhbGl0eSA9IHF1YWw7Cit9CisKKy8qIEZ1bmt0aW9uZW4genVtIEluaXRpYWxpc2llcmVuIGRlciBQZmxhbnplICovCisvLyBEZXIgS3JhZXV0ZXJtYXN0ZXIgcHJ1ZWZ0IGRlbiBDbG9uZSBhdWYgR3VlbHRpZ2tlaXQuIEVpbmUgZWlubWFsIGdlc2V0enRlCisvLyBJRCBrYW5uIGF1ZiBkaWVzZW0gV2VnIG5pY2h0IG1laHIgZ2VhZW5kZXJ0IHdlcmRlbi4KK25vbWFzayBpbnQgU2V0UGxhbnRJZChpbnQgbmV3X2lkKQoreworICBpZiAocGxhbnRJZCAhPSAwKQorICAgIHJldHVybiAtMTsKKyAgY2xvbmVyPTA7CisgIGFnZT10aW1lKCk7CisgIGlmIChjYXRjaChjbG9uZXI9Y2FsbF9vdGhlcihQTEFOVE1BU1RFUiwgIkNoZWNrUGxhbnQiLCBuZXdfaWQpKSB8fCAhY2xvbmVyKQorICAgIG5ld19pZCA9IC0xOworICByZXR1cm4gKHBsYW50SWQ9bmV3X2lkKTsKK30KKworbm9tYXNrIGludCBRdWVyeVBsYW50SWQoKQoreworICByZXR1cm4gcGxhbnRJZDsKK30KKworbm9tYXNrIHN0cmluZyBRdWVyeUNsb25lcigpCit7CisgIHJldHVybiBjbG9uZXI7Cit9CisKK25vbWFzayBpbnQgUXVlcnlEcmllZCgpIAoreworICByZXR1cm4gKGFnZSA9PSBEUklFRF9QTEFOVCk7Cit9CmRpZmYgLS1naXQgYS9zdGQvaXRlbXMva3JhZXV0ZXIvdHJhbmsuYyBiL3N0ZC9pdGVtcy9rcmFldXRlci90cmFuay5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmYzYzBlZmUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvaXRlbXMva3JhZXV0ZXIvdHJhbmsuYwpAQCAtMCwwICsxLDExNDcgQEAKKy8vVE9ETzoKKworI3ByYWdtYSBzdHJvbmdfdHlwZXMscnR0X2NoZWNrcworCitpbmhlcml0ICIvc3RkL3RoaW5nIjsKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8aXRlbXMva3JhZXV0ZXIva3JhZXV0ZXIuaD4KKyNpbmNsdWRlIDxpdGVtcy9rcmFldXRlci90cmFua2F0dHJpYnV0ZS5oPgorI2luY2x1ZGUgPGhvb2suaD4KKyNpbmNsdWRlIDxjbGFzcy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKworI2lmbmRlZiBCUworIyAgZGVmaW5lIEJTKHgpICAgICAgICAgICAgIGJyZWFrX3N0cmluZyh4LCA3OCkKKyNlbmRpZgorCisjZGVmaW5lIGFsbG93ZWQoeCkgKG9iamVjdF9uYW1lKHgpPT1QTEFOVE1BU1RFUikKKyNkZWZpbmUgRFJJTktfUE9USU9OICJsaWJfa3JhZXV0ZXJ0cmFua190cmlua2VuIgorLy8gZm9yIGRlYnVnCisjZGVmaW5lIHByaXZhdGUgcHVibGljCisKKy8vIEFibGF1ZnplaXQgZGVzIFRyYW5rcywgYWIgZGFubiBrZWluZSBXaXJrdW5nIG1laHIKK3ByaXZhdGUgbm9zYXZlIGludCBleHBpcnk7CisvLyBBYmxhdWZ6ZWl0IGRlciB3aXJrdW5nZW4gZGVzIFRyYW5rZXMgKDAsIHdlbm4gVHJhbmsgbmljaHQgZ2V0cnVua2VuKQorcHJpdmF0ZSBub3NhdmUgaW50IGR1cmF0aW9uOworLy8gVHJhbmthdHRyaWJ1dGUsIHZvbSBLcmF1dG1hc3RlciBzY2hvbiBza2FsaWVydCwgZ2VrYXBwdCwgYmVzY2hyYWVua3QgYXVmCisvLyBkaWUgamV3ZWlscyBtYXguIHBvc2l0aXZlbiBFZmZla3RlCitwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIGRhdGE7CisvLyBLbGFzc2VuLCBkaWUgYmVpIFNjaHV0eiBvZGVyIHZlcnN0YWVya3RlbSBTY2hhZGVuIGJldHJvZmZlbiBzaW5kLiBXZXJ0ZQorLy8gaXN0IGRlciBTY2h1dHotIG9kZXIgQXR0YWNrZWJvbnVzLy1tYWx1cy4KK3ByaXZhdGUgbm9zYXZlIG1hcHBpbmcgYXR0X2NsYXNzZXM7Citwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIHByb3RfY2xhc3NlczsKKy8vIG1heC4gU3VtbWUgdm9uIEdpZnRzdHVmZW4gKFBfUE9JU09OIHVuZCBQX0xFVkVMLzEwIGJlaSBDTF9QT0lTT04pLgorcHJpdmF0ZSBub3NhdmUgaW50IHByb3RfcG9pc29uOworLy8gbWF4LiBnZWhlaWx0ZSBTdW1tZSB2b24gS3JhbmtoZWl0c2xldmVsIChQX0xFVkVMLzUgaW4gQ0xfRElTRUFTRSkuCitwcml2YXRlIG5vc2F2ZSBpbnQgcHJvdF9kaXNlYXNlOworLy8gbmFjaCBXaXJrdW5nIGFic3RlaWdlbmQgc29ydGllcnRlIExpc3RlIGRlciBFZmZla3RlLCB3aXJkIGJlaW0gZXJzdGVuCisvLyBBdWZydWYgdm9uIERldGVybWluZVN0cm9uZ2VzRWZmZWN0KCkgYmVmdWVsbHQuCitwcml2YXRlIG5vc2F2ZSBzdHJpbmcqIHNvcnRlZF9lZmZlY3RzOworCittaXhlZCBfcXVlcnlfZGF0YSgpIHtyZXR1cm4gZGF0YTt9CitpbnQgX3NldF9kYXRhKG1peGVkIGQpIHtkYXRhPWQ7IGV4cGlyeSA9IF9fSU5UX01BWF9fOyByZXR1cm4gZGF0YSE9MDt9Citwcml2YXRlIHN0cmluZyBlZmZlY3QyY29sb3VyKCk7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIGlmIChvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSA9PSBfX0ZJTEVfX1swLi48M10pCisgIHsKKyAgICBzZXRfbmV4dF9yZXNldCgtMSk7CisgICAgcmV0dXJuOworICB9CisgIDo6Y3JlYXRlKCk7CisgIFNldFByb3AoUF9HRU5ERVIsIEZFTUFMRSk7CisgIFNldFByb3AoUF9OQU1FLCAiR2xhc2ZsYXNjaGUiKTsKKyAgU2V0UHJvcChQX05BTUVfQURKLCAoeyJrbGVpbiJ9KSk7CisgIFNldFByb3AoUF9WQUxVRSwgMTApOworICBTZXRQcm9wKFBfV0VJR0hULCAxMDApOworICBTZXRQcm9wKFBfS0lMTF9OQU1FLCAiRWluIEtyYWV1dGVydHJhbmsiKTsKKyAgU2V0UHJvcChQX0tJTExfTVNHLCAiJXMgaGF0IHNpY2ggd29obCBiZWltIEFucnVlaHJlbiB2ZXJ0YW4uIik7CisgIEFkZElkKCh7ImdsYXNmbGFzY2hlIiwgImZsYXNjaGUifSkpOworICBBZGRBZGplY3RpdmUoKHsia2xlaW4iLCAia2xlaW5lIn0pKTsKKyAgQWRkQ21kKCJ0cmlua3x0cmlua2UmQElEIiwgImNtZF90cmlua2VuIiwKKyAgICAiV2FzIHdpbGxzdCBEdSB0cmlua2VuPyIpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKQoreworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3N0YXRpYyBzdHJpbmcgX3F1ZXJ5X3Nob3J0KCkKK3sKKyAgaWYgKCFjbG9uZXAoTUUpKQorICAgIHJldHVybiAiRWluZSBrbGVpbmUgR2xhc2ZsYXNjaGUiOworICByZXR1cm4gTmFtZShXRU4sIDApKyhkYXRhPT0wID8gIiIgOiAiIChnZWZ1ZWxsdCkiKTsKK30KKworc3RhdGljIHN0cmluZyBfcXVlcnlfbG9uZygpCit7CisgIGlmIChkYXRhPT0wKQorICAgIHJldHVybiBicmVha19zdHJpbmcoCisgICAgICAiRWluZSBrbGVpbmUgbGVlcmUgR2xhc2ZsYXNjaGUsIGRpZSBtaXQgZWluZW0gS29ya2VuIHZlcnNjaGxvc3NlbiAiCisgICAgICAiaXN0LlxuIgorICAgICAgIkZsYXNjaGVuIHdpZSBkaWVzZSB3ZXJkZW4gdWVibGljaGVyd2Vpc2UgdmVyd2VuZGV0LCB1bSBkYXJpbiAiCisgICAgICAibWFnaXNjaGUgVHJhZW5rZSBhYnp1ZnVlbGxlbi4iLCA3OCwgMCwgQlNfTEVBVkVfTVlfTEZTKTsKKworICByZXR1cm4gYnJlYWtfc3RyaW5nKAorICAgICJFaW5lIGtsZWluZSBHbGFzZmxhc2NoZSwgZGllIG1pdCBlaW5lciAiK2VmZmVjdDJjb2xvdXIoKSsiZW4gIgorICAgICJGbHVlc3NpZ2tlaXQgZ2VmdWVsbHQgaXN0LlxuIgorICAgICJTaWUgaXN0IG1pdCBlaW5lbSBLb3JrZW4gdmVyc2NobG9zc2VuLCB1bSBkZW4gSW5oYWx0IGRlciAiCisgICAgIkZsYXNjaGUgenUgc2NodWV0emVuLiIsNzgsIDAsIEJTX0xFQVZFX01ZX0xGUyk7Cit9CisKK3ByaXZhdGUgc3RyaW5nIG51bTJkZXNjKGludCBidW1tcykKK3sKKyAgc3dpdGNoKGFicyhidW1tcykpCisgIHsKKyAgICBjYXNlIDAuLjQ5OToKKyAgICAgIHJldHVybiAiZWluIHdlbmlnIjsKKyAgICBjYXNlIDUwMC4uOTk5OgorICAgICAgcmV0dXJuICJzbyBlaW5pZ2VzIjsKKyAgICBjYXNlIDEwMDAuLjE0OTk6CisgICAgICByZXR1cm4gImVyaGVibGljaCI7CisgICAgY2FzZSAxNTAwLi4yMDAwOgorICAgICAgcmV0dXJuICJ1bmdsYXVibGljaCI7CisgIH0KKyAgcmV0dXJuICJ1bmdlbmVobWlndCB2aWVsIjsgLy8ga29tbXQgaG9mZmVudGxpY2ggbmljaHQgdm9yLgorfQorCit2YXJhcmdzIHByaXZhdGUgc3RyaW5nIERldGVybWluZVN0cm9uZ2VzdEVmZmVjdChpbnQgcG9zKQoreworICAvLyBnbG9iYWxlIFdlcnRlbGlzdGUgYmVmdWVsbGVuLCB3ZW5uIGRhIG5vY2ggbmljaHRzIGRyaW5zdGVodC4KKyAgaWYgKCAhcG9pbnRlcnAoc29ydGVkX2VmZmVjdHMpICkgeworICAgIHNvcnRlZF9lZmZlY3RzID0gc29ydF9hcnJheShtX2luZGljZXMoZGF0YSkgJiBUX0tSQVVUX0VGRkVDVFMsCisgICAgICBmdW5jdGlvbiBpbnQgKHN0cmluZyBhLCBzdHJpbmcgYikgeworICAgICAgICByZXR1cm4gKGFicyhkYXRhW2FdKTw9YWJzKGRhdGFbYl0pKTsKKyAgICAgIH0pOworICB9CisKKyAgLy8gWnVyIEluZGl6aWVydW5nIGRlcyBBcnJheXMgbXVzcyA8cG9zPiBiZWkgTnVsbCBzdGFydGVuLCBlcyB3aXJkCisgIC8vIGFiZXIgbWl0IGRlciBCZWRldXR1bmcgZWluZXIgT3JkaW5hbHphaGwgKGVyc3RlLCB6d2VpdGUsIGRyaXR0ZSwgLi4uKQorICAvLyB1ZWJlcmdlYmVuLiBEYWhlciB1bSAxIHJlZHV6aWVyZW4uCisgIC0tcG9zOworCisgIHN0cmluZyByZXQ7CisKKyAgLy8gSW0gQXJyYXkgbXVzcyBtaW5kZXN0ZW5zIGVpbiBFaW50cmFnIHN0ZWhlbiwgc29uc3QgZ2lidCdzIGdhciBrZWluZW4KKyAgLy8gRWZmZWt0LgorICBpZiAoIHNpemVvZihzb3J0ZWRfZWZmZWN0cykgKQorICB7CisgICAgLy8gV2VubiBkZXIgYW5nZWZyYWd0ZSBJbmRleCBhdXNzZXJoYWxiIGRlciBBcnJheWdyZW56ZW4gbGllZ3QsIHdpcmQKKyAgICAvLyBhbmdlbm9tbWVuLCBkYXNzIGRlciBlcnN0ZSBiencuIGxldHp0ZSBFaW50cmFnIGdlc3VjaHQgd2FyZW4uCisgICAgaWYgKCBwb3MgPCAwICkKKyAgICAgIHJldCA9IHNvcnRlZF9lZmZlY3RzWzBdOworICAgIGVsc2UgaWYgKCBwb3MgPj0gc2l6ZW9mKHNvcnRlZF9lZmZlY3RzKSApCisgICAgICByZXQgPSBzb3J0ZWRfZWZmZWN0c1s8MV07CisgICAgZWxzZQorICAgICAgcmV0ID0gc29ydGVkX2VmZmVjdHNbcG9zXTsKKyAgfQorICByZXR1cm4gcmV0OworfQorCisvLyBMaWVmZXJ0IHp1IGRlbSBtYXhpbWFsIHdpcmtzYW1lbiBFZmZla3QgZGllIEZhcmJlIGRlcyBUcmFua2VzIHp1cnVlY2suCitwcml2YXRlIHN0cmluZyBlZmZlY3QyY29sb3VyKCkKK3sKKyAgLy8gSXN0IGRpZSBIYWx0YmFya2VpdCBzY2hvbiBhYmdlbGF1ZmVuLCB3aXJkIGRlciBUcmFuayBmYXJibG9zLgorICBpZiAoIHRpbWUoKSA+IGV4cGlyeSApCisgICAgcmV0dXJuICJmYXJibG9zIjsKKworICAvLyBOYW1lbiBkZXMgc3RhZXJrc3RlbiBFZmZla3RzIGhvbGVuLgorICBzdHJpbmcgZWZmZWN0ID0gRGV0ZXJtaW5lU3Ryb25nZXN0RWZmZWN0KDEpOworICBtYXBwaW5nIGNvbG91cnMgPSAoWworICAgIFRfQ0FSUlk6ICAgICAgICAgICAgICAidHJ1ZWIgYnJhdW4iLAorICAgIFRfREFNQUdFX0FOSU1BTFM6ICAgICAiYmx1dHJvdCIsCisgICAgVF9EQU1BR0VfTUFHSUM6ICAgICAgICJva3RhcmluZmFyYmVuIiwKKyAgICBUX0RBTUFHRV9VTkRFQUQ6ICAgICAgImFudGhyYXppdGZhcmJlbiIsCisgICAgVF9GTEVFX1RQT1JUOiAgICAgICAgICJzY2h3ZWZlbGdlbGIiLAorICAgIFRfRlJPRzogICAgICAgICAgICAgICAic2NobGFtbWdydWVuIiwKKyAgICBUX0hFQUxfRElTRUFTRTogICAgICAgInBlcmxtdXR0ZmFyYmVuIiwKKyAgICBUX0hFQUxfUE9JU09OOiAgICAgICAgImdydWVuIiwKKyAgICBUX0hFQUxfU1A6ICAgICAgICAgICAgImJsYXUiLAorICAgIFRfSEVBTF9MUDogICAgICAgICAgICAic2NoYXJsYWNocm90IiwKKyAgICBUX1BST1RFQ1RJT05fQU5JTUFMUzogIm1ldGFsbGlzY2ggZ3JhdSIsCisgICAgVF9QUk9URUNUSU9OX01BR0lDOiAgICJ2aW9sZXR0IiwKKyAgICBUX1BST1RFQ1RJT05fVU5ERUFEOiAgInN0cmFobGVuZCB3ZWlzcyIsCisgICAgVF9TQV9TUEVFRDogICAgICAgICAgICJvcmFuZ2VmYXJiZW4iLAorICAgIFRfU0FfU1BFTExfUEVORVRSQVRJT046ICJzdGFobGJsYXUiLAorICAgIFRfU0FfRFVSQVRJT046ICAgICAgICAicGlua2ZhcmJlbiIsCisgIF0pOworICBzdHJpbmcgcmV0ID0gY29sb3Vyc1tlZmZlY3RdOworICByZXR1cm4gc3RyaW5ncChyZXQpID8gcmV0IDogImZhcmJsb3MiOworfQorCisvLyBXaXJkIGdlcnVmZW4sIHdlbm4gZGllIFdpcmt1bmcgZGVzIFRyYW5rZXMgYWJsYXVmZW4gc29sbC4KK3ByaXZhdGUgdm9pZCB0ZXJtaW5hdGVfZWZmZWN0cygpCit7CisgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksCisgICAgICAiRGllIGxldHp0ZW4gV2lya3VuZ2VuIGRlcyBLcmFldXRlcnRyYW5rZXMga2xpbmdlbiBhYi5cbiIpOworICByZW1vdmUoMSk7Cit9CisKKy8vIFZvbiBkZW4gSG9va3MgSF9IT09LX0FUVEFDS19NT0QgdW5kIEhfSE9PS19ERUZFTkQgZ2VydWZlbiwgZXJob2VodCBvZGVyCisvLyB2ZXJyaW5nZXJ0IGRlbiBTY2hhZGVuIGdlZ2VuIExlYmVud2VzZW4gYmVzdGltbXRlciBLbGFzc2VuIChLZXlzIGluCisvLyA8Y2xhc3Nlcz4pLiBEZXIgTWFsdXMvQm9udXMgc3RlaHQgYWxzIFdlcnQgenVtIGpld2VpbGlnZW4gS2V5IGluIGRlbQorLy8gTWFwcGluZy4KK21peGVkIGhjYWxsYmFjayhvYmplY3QgaG9va1NvdXJjZSwgaW50IGhvb2tpZCwgbWl4ZWQgaG9va0RhdGEpCit7CisgICAgaWYgKGhvb2tTb3VyY2UgIT0gZW52aXJvbm1lbnQoKSkKKyAgICAgICAgcmV0dXJuICh7SF9OT19NT0QsaG9va0RhdGF9KTsKKyAgICBzd2l0Y2goaG9va2lkKQorICAgIHsKKyAgICAgIGNhc2UgSF9IT09LX0FUVEFDS19NT0Q6CisgICAgICAgIGZvcmVhY2goc3RyaW5nIGNsYXNzLCBpbnQgbW9kdmFsIDogYXR0X2NsYXNzZXMpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoaG9va0RhdGFbU0lfRU5FTVldLT5pc19jbGFzc19tZW1iZXIoY2xhc3MpKQorICAgICAgICAgIHsKKyAgICAgICAgICAgIC8vIFllYWguIFRyZWZmZXIuIFNjaGFkZW4gZXJob2VoZW4gb2RlciB2ZXJyaW5nZXJuLi4uIDspCisgICAgICAgICAgICBob29rRGF0YVtTSV9TS0lMTERBTUFHRV0gKz0gbW9kdmFsOworICAgICAgICAgICAgLy8gRW5kZS4ga2VpbmUgd2VpdGVyZW4gS2xhc3NlbiBwcnVlZmVuLgorICAgICAgICAgICAgcmV0dXJuICh7SF9BTFRFUkVELCBob29rRGF0YX0pOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSF9IT09LX0RFRkVORDoKKyAgICAgICAgLy8gaG9va0RhdGE6ICh7ZGFtLGRhbV90eXBlLHNwZWxsLGVuZW15fSkKKyAgICAgICAgZm9yZWFjaChzdHJpbmcgY2xhc3MsIGludCBtb2R2YWwgOiBwcm90X2NsYXNzZXMpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoaG9va0RhdGFbM10tPmlzX2NsYXNzX21lbWJlcihjbGFzcykpCisgICAgICAgICAgeworICAgICAgICAgICAgLy8gWWVhaC4gVHJlZmZlci4gU2NoYWRlbiBlcmhvZWhlbiBvZGVyIHZlcnJpbmdlcm4uLi4gOykKKyAgICAgICAgICAgIGhvb2tEYXRhWzBdICs9IG1vZHZhbDsKKyAgICAgICAgICAgIC8vIEVuZGUuIGtlaW5lIHdlaXRlcmVuIEtsYXNzZW4gcHJ1ZWZlbi4KKyAgICAgICAgICAgIHJldHVybiAoe0hfQUxURVJFRCwgaG9va0RhdGF9KTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEhfSE9PS19JTlNFUlQ6CisgICAgICAgIC8vIFdlbm4gZGllIEdpZnRzY2h1dHprYXBheml0YWV0IG5vY2ggYXVzcmVpY2h0LCB3aXJkIGRhcyByZWlua29tbWVuZGUKKyAgICAgICAgLy8gT2JqZWt0IHplcnN0b2VydCAodW5kIGRpZSBLYXBheml0YWV0IHJlZHV6aWVydCkuCisgICAgICAgIC8vIGhvb2tEYXRhOiBuZXVlcyBvYmplY3QKKyAgICAgICAgaWYgKHByb3RfcG9pc29uID4gMAorICAgICAgICAgICAgJiYgaG9va0RhdGEtPmlzX2NsYXNzX21lbWJlcihDTF9QT0lTT04pKQorICAgICAgICB7CisgICAgICAgICAgLy8ga29zdGV0IGVpbiBaZWhudGVsIGRlcyBMZXZlbHMsIGFiZXIgbWluLiAxLgorICAgICAgICAgIGludCBwPWhvb2tEYXRhLT5RdWVyeVByb3AoUF9MRVZFTCkgLyAxMCArIDE7CisgICAgICAgICAgaWYgKHAgPCBwcm90X3BvaXNvbikKKyAgICAgICAgICB7CisgICAgICAgICAgICBob29rRGF0YS0+cmVtb3ZlKDEpOworICAgICAgICAgICAgcHJvdF9wb2lzb24tPXA7CisgICAgICAgICAgICByZXR1cm4gKHtIX0NBTkNFTExFRCwgaG9va0RhdGF9KTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gV2VubiBkaWUgS3JhbmtoZWl0c3NjaHV0emthcGF6aXRhZXQgbm9jaCBhdXNyZWljaHQsIHdpcmQgZGFzIHJlaW5rb21tZW5kZQorICAgICAgICAvLyBPYmpla3QgemVyc3RvZXJ0ICh1bmQgZGllIEthcGF6aXRhZXQgcmVkdXppZXJ0KS4KKyAgICAgICAgLy8gaG9va0RhdGE6IG5ldWVzIG9iamVjdAorICAgICAgICBpZiAocHJvdF9kaXNlYXNlID4gMAorICAgICAgICAgICAgJiYgaG9va0RhdGEtPmlzX2NsYXNzX21lbWJlcihDTF9ESVNFQVNFKSkKKyAgICAgICAgeworICAgICAgICAgIC8vIGtvc3RldCBlaW4gRnVlbmZ0ZWwgZGVzIExldmVscywgYWJlciBtaW4uIDEuCisgICAgICAgICAgaW50IGx2bCA9IGhvb2tEYXRhLT5RdWVyeVByb3AoUF9MRVZFTCkgLyA1ICsgMTsKKyAgICAgICAgICBpZiAobHZsIDwgcHJvdF9kaXNlYXNlKQorICAgICAgICAgIHsKKyAgICAgICAgICAgIGhvb2tEYXRhLT5yZW1vdmUoMSk7CisgICAgICAgICAgICBwcm90X2Rpc2Vhc2UtPWx2bDsKKyAgICAgICAgICAgIHJldHVybiAoe0hfQ0FOQ0VMTEVELCBob29rRGF0YX0pOworICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgSF9IT09LX1BPSVNPTjoKKyAgICAgICAgLy8gaG9va0RhdGE6IHBvaXNvbnZhbAorICAgICAgICAvLyBBbGxlIEdpZnRsZXZlbCB3ZXJkZW4gcmVkdXppZXJ0IGF1ZiAwIHVuZCB2b24gcHJvdF9wb2lzb24KKyAgICAgICAgLy8gYWJnZXpvZ2VuLiBXZW5uIGRhcyAwIGlzdCwgZW5kZXQgZGVyIEdpZnRzY2h1dHouCisgICAgICAgIGlmIChwcm90X3BvaXNvbj4wKQorICAgICAgICB7CisgICAgICAgICAgaWYgKGhvb2tEYXRhIDwgcHJvdF9wb2lzb24pCisgICAgICAgICAgeworICAgICAgICAgICAgcHJvdF9wb2lzb24tPWhvb2tEYXRhOworICAgICAgICAgICAgaG9va0RhdGEgPSAwOworICAgICAgICAgIH0KKyAgICAgICAgICBlbHNlCisgICAgICAgICAgeworICAgICAgICAgICAgaG9va0RhdGEgLT0gcHJvdF9wb2lzb247CisgICAgICAgICAgICBwcm90X3BvaXNvbj0wOworICAgICAgICAgIH0KKyAgICAgICAgICByZXR1cm4gKHtIX0FMVEVSRUQsIGhvb2tEYXRhfSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgfQorICAgIHJldHVybiAoe0hfTk9fTU9ELCBob29rRGF0YX0pOworfQorCitwcml2YXRlIGludCByZWdfaG9vayhpbnQgaG9vaywgaW50IGhvb2t0eXBlKQoreworICAvLyBXZW5uIHNjaG9uIHJlZ2lzdHJpZXJ0LCB6YWVobHQgZGFzIGF1Y2ggYWxzIEVyZm9sZy4KKyAgaWYgKGVudmlyb25tZW50KCktPkhJc0hvb2tDb25zdW1lcihob29rLCAjJ2hjYWxsYmFjaykpCisgICAgcmV0dXJuIDE7CisgIGludCByZXMgPSBlbnZpcm9ubWVudCgpLT5IUmVnaXN0ZXJUb0hvb2soaG9vaywgIydoY2FsbGJhY2ssCisgICAgICAgICAgICAgICAgIEhfSE9PS19PVEhFUlBSSU8oMCksIGhvb2t0eXBlLCBkdXJhdGlvbik7CisgIGlmIChyZXMgPD0gMCkKKyAgeworICAgIC8vIHdlbm4gYW5kZXJlIEZlaGxlciBhbHMgLTcgKHp1dmllbGUgSG9va3MgcmVnaXN0cmllcnQpIHZvcmtvbW1lbjoKKyAgICAvLyBGZWhsZXJtZWxkdW5nIGF1c2dlYmVuCisgICAgaWYgKHJlcyAhPSAtNykKKyAgICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksYnJlYWtfc3RyaW5nKHNwcmludGYoCisgICAgICAgICAgIlRlY2huaXNjaGVyIEhpbndlaXMsIGRlbiBEdSBhbiBlaW5lbiBNYWdpZXIgd2VpdGVyZ2ViZW4gIgorICAgICAgICAgICJzb2xsdGVzdDogQmVpbSBSZWdpc3RyaWVyZW4gZGVzIEhvb2tzICVkIGdhYiBlcyBGZWhsZXI6ICVkXG4iLAorICAgICAgICAgIGhvb2ssIHJlcyksNzgpKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICByZXR1cm4gMTsKK30KKworLy8gZWZmZWt0OiBXaXJrdW5nc3dlcnQgZGVzIFRyYW5rcyAobXVzcyBuZWdhdGl2IHNlaW4pCisvLyB0eXBlOiAxIGZ1ZXIgR2lmdCwgMCBmdWVyIEtyYW5raGVpdAorcHJpdmF0ZSB2b2lkIHRpY2t0YWNrKGludCBlZmZla3QsIGludCB0eXBlKQoreworICAvLyBTY2hhZGVuIHRpY2t0IGFsbGUgNSBTZWt1bmRlbgorICBpbnQgZGVsYXkgPSA1OworICAvLyBEZXIgaGFsYmUgQmV0cmFnIGRlcyBuZWdhdGl2ZW4gRWZmZWt0cyB3aXJkIGFscyBTY2hhZGVuIGFtCisgIC8vIFNwaWVsZXIgdmVydXJzYWNodC4KKyAgLy8gQmVyZWNobnVuZzogKFNjaGFkZW4gcHJvIFNla3VuZGUpICogKERlbGF5IGluIFNla3VuZGVuKQorICAvLyBpbiBmbG9hdCByZWNobmVuIGlzdCBoaWVyIHNpbm52b2xsLCBpbmtsLiBhdWZydW5kZW4gKGR1cmNoIGRpZSArMC41KQorLy8gIGludCBkYW0gPSB0b19pbnQoKCgtMC41KmVmZmVrdCkvZHVyYXRpb24pKmRlbGF5ICsgMC41KTsKKyAgaW50IGRhbSA9IHRvX2ludCgwLjUqYWJzKGVmZmVrdCkvZGF0YVtUX0VGRkVDVF9EVVJBVElPTl0qZGVsYXkgKyAwLjUpOworCisgIGlmICh0eXBlKQorICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksCisgICAgICBicmVha19zdHJpbmcoIkdpZnQgcHVsc2llcnQgYnJlbm5lbmQgZHVyY2ggRGVpbmUgQWRlcm4uIiw3OCkpOworICBlbHNlCisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwKKyAgICAgIGJyZWFrX3N0cmluZygiRHUgZnVlaGxzdCBEaWNoIHNjaHdhY2ggdW5kIGVsZW5kLCBlaW5lIEVya3Jhbmt1bmcgIgorICAgICAgInplaHJ0IGFuIERlaW5lbiBLcmFlZnRlbi4iLDc4KSk7CisKKyAgZW52aXJvbm1lbnQoKS0+ZG9fZGFtYWdlKGRhbSwgdGhpc19vYmplY3QoKSk7CisgIGNhbGxfb3V0KCMndGlja3RhY2ssIGRlbGF5LCBlZmZla3QsIHR5cGUpOworfQorCitwcml2YXRlIGludCBhY3RfYXR0cl9oZWFsX3BvaXNvbihpbnQgZWZmZWt0KQoreworICBpbnQgZXJmb2xncmVpY2g7CisgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksIGJyZWFrX3N0cmluZygKKyAgICAgIkR1IGZ1ZWhsc3QsIHdpZSBkZXIgVHJhbmsgd2llIEZldWVyIGR1cmNoIERlaW5lbiBLb2VycGVyIHNjaGllc3N0ICIKKyAgICAgInVuZCBrcnVlbW1zdCBEaWNoIHZvciBTY2htZXJ6ZW4uIERvY2ggTW9tZW50ZSBzcGFldGVyIGxhZXNzdCBkaWUgIgorICAgICAiVG9ydHVyIG5hY2guIiw3OCkpOworCisgIC8vIG1heC4gNDAgR2lmdGxldmVsIGhlaWxlbi4uLgorICBwcm90X3BvaXNvbiA9IGVmZmVrdCAvIDUwOworCisgIGlmIChwcm90X3BvaXNvbiA8IDApCisgIHsKKyAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBCUygKKyAgICAgICJCYWghIERlciBUcmFuayBzY2htZWNrdCB3aWRlcmxpY2ggYml0dGVyLiBXZW5uIGRlciBtYWwgbmljaHQgIgorICAgICAgImdpZnRpZyB3YXIuIikpOworICAgIGNhbGxfb3V0KCMndGlja3RhY2ssIDUsIGVmZmVrdCwgMSk7IC8vIDEgPT4gR2lmdAorICAgIHJldHVybiAxOworICB9CisgIAorICAvLyBhYiBqZXR6dCBudXIgbm9jaCBwb3NpdGl2ZSBXaXJrdW5nZW4uCisKKyAgLy8gUF9QT0lTT04genVlcnN0LgorICBpbnQgcG9pc29uID0gZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfUE9JU09OKTsKKyAgaWYgKHBvaXNvbikKKyAgeworICAgIGlmIChwb2lzb24gPD0gcHJvdF9wb2lzb24pCisgICAgeworICAgICAgcHJvdF9wb2lzb24gLT0gcG9pc29uOworICAgICAgZW52aXJvbm1lbnQoKS0+U2V0UHJvcChQX1BPSVNPTiwwKTsKKyAgICAgIGlmICghZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfUE9JU09OKSkKKyAgICAgICAgKytlcmZvbGdyZWljaDsKKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgIHBvaXNvbiAtPSBwcm90X3BvaXNvbjsKKyAgICAgIHByb3RfcG9pc29uPTA7CisgICAgICBlbnZpcm9ubWVudCgpLT5TZXRQcm9wKFBfUE9JU09OLCBwb2lzb24pOworICAgICAgLy8gV2VubiBlcmZvbGdyZWljaCwgZGlyZWt0IE1lbGR1bmcgdW5kIHJhdXMuCisgICAgICBpZiAoZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfUE9JU09OKSA9PSBwb2lzb24pCisgICAgICB7CisgICAgICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksIGJyZWFrX3N0cmluZygKKyAgICAgICAgICAgIlVlYmVycmFzY2h0IHN0ZWxsc3QgRHUgZmVzdCwgZGFzcyBEdSBEaWNoICIKKyAgICAgICAgICAgImJlc3NlciBmdWVobHN0IC0gZGVyIFRyYW5rIGhhdCBEZWluZSBWZXJnaWZ0dW5nIG9mZmVuYmFyICIKKyAgICAgICAgICAgImdlbGluZGVydC4iLDc4KSk7CisgICAgICAgIHJldHVybiAxOworICAgICAgfQorICAgIH0KKyAgfQorCisgIC8vIHdlbm4gVHJhbmsgaW1tZXIgbm9jaCBwb3NpdGl2IChhbHNvIG5vY2ggV0lya3VuZyB1ZWJyaWcpCisgIGlmIChwcm90X3BvaXNvbiA+IDApCisgIHsKKyAgICAvLyBBbHMgbmFlY2hzdGVzIE9iamVrdGUgc3VjaGVuLgorICAgIG9iamVjdCAqb2IgPSBmaWx0ZXJfb2JqZWN0cyhhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaXNfY2xhc3NfbWVtYmVyIiwgQ0xfUE9JU09OKTsKKyAgICBmb3JlYWNoKG9iamVjdCBvOiBvYikKKyAgICB7CisgICAgICAvLyBFbnRnaWZ0ZW4ga29zdGV0IGVpbiBaZWhudGVsIGRlcyBMZXZlbHMsIGFiZXIgbWluLiAxLgorICAgICAgcG9pc29uID0gby0+UXVlcnlQcm9wKFBfTEVWRUwpOworICAgICAgaWYgKHBvaXNvbiA8PSBwcm90X3BvaXNvbioxMCkKKyAgICAgIHsKKyAgICAgICAgcHJvdF9wb2lzb24gLT0gcG9pc29uLzEwICsgMTsKKyAgICAgICAgby0+U2V0UHJvcChQX0xFVkVMLCAwKTsKKyAgICAgICAgaWYgKG8tPnJlbW92ZSgpKQorICAgICAgICAgICsrZXJmb2xncmVpY2g7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIHBvaXNvbiAtPSBwcm90X3BvaXNvbiAqIDEwOworICAgICAgICBwcm90X3BvaXNvbiA9IDA7CisgICAgICAgIG8tPlNldFByb3AoUF9MRVZFTCwgcG9pc29uKTsKKyAgICAgICAgaWYgKG8tPlF1ZXJ5UHJvcChQX0xFVkVMKSA9PSBwb2lzb24pCisgICAgICAgICAgKytlcmZvbGdyZWljaDsKKyAgICAgIH0KKyAgICAgIGlmIChwcm90X3BvaXNvbiA8PSAwKQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKworICBpZiAoZXJmb2xncmVpY2gpCisgIHsKKyAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBicmVha19zdHJpbmcoCisgICAgICAiVWViZXJyYXNjaHQgc3RlbGxzdCBEdSBmZXN0LCBkYXNzIER1IERpY2ggdmllbCBiZXNzZXIgZnVlaGxzdCAtIGRlciAiCisgICAgICAiVHJhbmsgd2lya3Qgb2ZmZW5iYXIgZ2VnZW4gVmVyZ2lmdHVuZ2VuLiIsNzgpKTsKKyAgfQorICBlbHNlCisgIHsKKyAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBicmVha19zdHJpbmcoCisgICAgICAiRWluZSBBaG51bmcgc2FndCBEaXIsIGRhc3MgZGVyIFRyYW5rIGlyZ2VuZGVpbmUgcG9zaXRpdmUgIgorICAgICAgIldpcmt1bmcgaGF0LiIpKTsKKyAgfQorCisgIC8vIGdnZi4gYW4gZGllIEhvb2tzIHJlZ2lzdHJpZXJlbiwgd2VubiBub2NoIFNjaHV0endpcmt1bmcgdWVicmlnIGlzdC4KKyAgaWYgKHByb3RfcG9pc29uID4gMCkKKyAgeworICAgIC8vIFJ1ZWNrZ2FiZXdlcnRlIHZvbiBIUmVnaXN0ZXJUb0hvb2sgc3BlaWNoZXJuLi4uCisgICAgaW50ICpyZXMgPSAoeyByZWdfaG9vayhIX0hPT0tfUE9JU09OLCBIX0RBVEFfTU9ESUZJQ0FUT1IpIH0pOworICAgIHJlcyArPSAoeyByZWdfaG9vayhIX0hPT0tfSU5TRVJULCBIX0hPT0tfTU9ESUZJQ0FUT1IpIH0pOworICAgIC8vIFdlbm4gYWxsZSB2ZXJzdWNodGVuIFJlZ2lzdHJpZXJ1bmdlbiBlcmZvbGdyZWljaCB3YXJlbi4uLj8gQW5zb25zdGVuCisgICAgLy8gYW5kZXJlIE1lbGR1bmcuLi4gSWNoIGJpbiBub2NoIG5pY2h0IGdsdWVja2xpY2gsIGRhcyBoaWVyIHNvIGV4cGxpeml0CisgICAgLy8gYXVzenVnZWJlbiwgYWJlciBpY2ggd2Vpc3MgZ2VyYWRlIHNvbnN0IG5pY2h0LCB3aWUgbWFuIGRyYXVmIGtvbW1lbgorICAgIC8vIHNvbGwsIGRhc3MgZXMgZWluIFByb2JsZW0gZ2lidC4KKyAgICBpZiAoc2l6ZW9mKHJlcykgPT0gc2l6ZW9mKHJlcyAmICh7MX0pKSkKKyAgICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksCisgICAgICAgICAiVmllbGxlaWNodCBoYWVsdCBkaWVzZSBXaXJrdW5nIGphIHNvZ2FyIG5vY2ggZXR3YXMgYW4/XG4iKTsKKyAgICBlbHNlCisgICAgeworICAgICAgLy8genVtaW5kZXN0IGVpbiBlcmZvbGc/CisgICAgICBpZiAobWVtYmVyKHJlcywgMSkgPiAtMSkKKyAgICAgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwKKyAgICAgICAgICAgICJWaWVsbGVpY2h0IGhhZWx0IGVpbiBUZWlsIGRpZXNlciBXaXJrdW5nIGphIHNvZ2FyIG5vY2ggZXR3YXMgYW4/XG4iKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3ByaXZhdGUgaW50IGFjdF9hdHRyX2hlYWxfZGlzZWFzZShpbnQgZWZmZWt0KQoreworICBpbnQgZXJmb2xncmVpY2g7CisKKyAgLy8gbWF4LiA0MCBLcmFua2hlaXRzbGV2ZWwgaGVpbGVuLi4uCisgIHByb3RfZGlzZWFzZSA9IGVmZmVrdCAvIDUwOworCisgIGlmIChwcm90X2Rpc2Vhc2UgPiAwKQorICB7CisgICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksIGJyZWFrX3N0cmluZygKKyAgICAgICAiRHUgZnVlaGxzdCwgd2llIGRlciBUcmFuayBpbiBEZWluZW0gQmF1Y2ggZWluZSB3b2hsaWdlIFdhZXJtZSAiCisgICAgICAgInZlcmJyZWl0ZXQgdW5kIGxhZWNoZWxzdCB1bndpbGxrdWVybGljaC4iLDc4KSk7CisgICAKKyAgICAvLyBPYmpla3RlIHN1Y2hlbi4KKyAgICBvYmplY3QgKm9iID0gZmlsdGVyX29iamVjdHMoYWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImlzX2NsYXNzX21lbWJlciIsIENMX0RJU0VBU0UpOworICAgIGZvcmVhY2gob2JqZWN0IG86IG9iKQorICAgIHsKKyAgICAgIC8vIEhlaWxlbiBrb3N0ZXQgZWluIEZ1ZW5mdGVsIGRlcyBMZXZlbHMsIGFiZXIgbWluLiAxLgorICAgICAgaW50IGRpc2Vhc2UgPSBvLT5RdWVyeVByb3AoUF9MRVZFTCk7CisgICAgICBpZiAoZGlzZWFzZSA8PSBwcm90X2Rpc2Vhc2UqNSkKKyAgICAgIHsKKyAgICAgICAgcHJvdF9kaXNlYXNlIC09IGRpc2Vhc2UvNSArIDE7CisgICAgICAgIG8tPlNldFByb3AoUF9MRVZFTCwgMCk7CisgICAgICAgIGlmIChvLT5yZW1vdmUoKSkKKyAgICAgICAgICArK2VyZm9sZ3JlaWNoOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgeworICAgICAgICBkaXNlYXNlIC09IHByb3RfZGlzZWFzZSAqIDU7CisgICAgICAgIHByb3RfZGlzZWFzZSA9IDA7CisgICAgICAgIG8tPlNldFByb3AoUF9MRVZFTCwgZGlzZWFzZSk7CisgICAgICAgIGlmIChvLT5RdWVyeVByb3AoUF9MRVZFTCkgPT0gZGlzZWFzZSkKKyAgICAgICAgICArK2VyZm9sZ3JlaWNoOworICAgICAgfQorICAgICAgaWYgKHByb3RfZGlzZWFzZSA8PSAwKQorICAgICAgICBicmVhazsKKyAgICB9CisgIH0KKyAgZWxzZQorICB7CisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgQlMoCisgICAgICAiRGVyIFRyYW5rIHNjaG1lY2t0IGVrbGlnIGZhdWxpZy4gRGVpbiBNYWdlbiByZWJlbGxpZXJ0IHVtZ2VoZW5kLiAiCisgICAgICAiRHUga2FubnN0IERlaW5lbiBCcmVjaHJlaXogZ2VyYWRlIG5vY2ggdW50ZXJkcnVlY2tlbiwgZnVlaGxzdCAiCisgICAgICAiRGljaCBhYmVyIGtyYW5rLiIpKTsKKyAgICBjYWxsX291dCgjJ3RpY2t0YWNrLCA1LCBlZmZla3QsIDApOyAvLyAwID0+IEtyYW5raGVpdAorICAgIHJldHVybiAxOworICB9CisKKyAgaWYgKGVyZm9sZ3JlaWNoKQorICB7CisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgYnJlYWtfc3RyaW5nKAorICAgICAgIkVudHNwYW5udCBkdXJjaGF0bWVuZCBzdGVsbHN0IER1IGZlc3QsIGRhc3MgRHUgRGljaCB2aWVsIGJlc3NlciBmdWVobHN0IC0gZGVyICIKKyAgICAgICJUcmFuayB3aXJrdCBvZmZlbmJhciBnZWdlbiBLcmFua2hlaXRlbi4iLDc4KSk7CisgIH0KKyAgZWxzZQorICB7CisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgYnJlYWtfc3RyaW5nKAorICAgICAgIkVpbmUgQWhudW5nIHNhZ3QgRGlyLCBkYXNzIGRlciBUcmFuayBpcmdlbmRlaW5lIHBvc2l0aXZlICIKKyAgICAgICJXaXJrdW5nIGhhdC4iKSk7CisgIH0KKworICAvLyBnZ2YuIGFuIGRpZSBIb29rcyByZWdpc3RyaWVyZW4uCisgIGlmIChwcm90X2Rpc2Vhc2UgPiAwKQorICB7CisgICAgLy8gUmVnaXN0cmllcnVuZyBlcmZvbGdyZWljaC4uLj8gQW5zb25zdGVuIGFuZGVyZSBNZWxkdW5nLi4uIEljaCBiaW4KKyAgICAvLyBub2NoIG5pY2h0IGdsdWVja2xpY2gsIGRhcyBoaWVyIHNvIGV4cGxpeml0IGF1c3p1Z2ViZW4sIGFiZXIgaWNoCisgICAgLy8gd2Vpc3MgZ2VyYWRlIHNvbnN0IG5pY2h0LCB3aWUgbWFuIGRyYXVmIGtvbW1lbiBzb2xsLCBkYXNzIGVzIGVpbgorICAgIC8vIFByb2JsZW0gZ2lidC4KKyAgICBpZiAocmVnX2hvb2soSF9IT09LX0lOU0VSVCwgSF9IT09LX01PRElGSUNBVE9SKT09MSkKKyAgICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksCisgICAgICAgICAiVmllbGxlaWNodCBoYWVsdCBkaWVzZSBXaXJrdW5nIGphIHNvZ2FyIG5vY2ggZXR3YXMgYW4/XG4iKTsKKworICB9CisgIHJldHVybiAxOworfQorCitwcml2YXRlIHN0cmluZyBudW0yZGVzY19maWdodChpbnQgYnVtbXMpCit7CisgIHN3aXRjaChhYnMoYnVtbXMpKQorICB7CisgICAgY2FzZSAwLi40OTk6CisgICAgICByZXR1cm4gImVpbiB3ZW5pZyI7CisgICAgY2FzZSA1MDAuLjk5OToKKyAgICAgIHJldHVybiAic3B1ZXJiYXIiOworICAgIGNhc2UgMTAwMC4uMTQ5OToKKyAgICAgIHJldHVybiAiZGV1dGxpY2giOworICAgIGNhc2UgMTUwMC4uMjAwMDoKKyAgICAgIHJldHVybiAiZXJoZWJsaWNoIjsKKyAgfQorICByZXR1cm4gInVuZ2VuZWhtaWd0IHZpZWwiOyAvLyBrb21tdCBob2ZmZW50bGljaCBuaWNodCB2b3IuCit9CisKKy8vIEFOOiBUaWVyZSBzaW5kOiBDTF9BTklNQUwsIENMX0ZJU0gsIENMX0ZST0csIENMX0lOU0VDVCwgQ0xfTUFNTUFMLAorLy8gQ0xfTUFNTUFMX0xBTkQsIENMX01BTU1BTF9XQVRFUiwgQ0xfUkVQVElMRSwgQ0xfQVJBQ0hOSUQsIENMX0JJUkQKK3ByaXZhdGUgaW50IGFjdF9hdHRyX2RhbV9hbmltYWxzKGludCBlZmZla3QpCit7CisgIGlmIChyZWdfaG9vayhIX0hPT0tfQVRUQUNLX01PRCwgSF9EQVRBX01PRElGSUNBVE9SKSA9PSAxKQorICB7CisgICAgaWYgKCFtYXBwaW5ncChhdHRfY2xhc3NlcykpIGF0dF9jbGFzc2VzPW1fYWxsb2NhdGUoMSk7CisgICAgYXR0X2NsYXNzZXNbQ0xfQU5JTUFMXSA9IGVmZmVrdC8yMDsKKyAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBicmVha19zdHJpbmcoCisgICAgICAgICJEdSBzcHVlcnN0IGluIERpciBlaW4gc2VsdHNhbWVzIFZlcmxhbmdlbiBhdWZzdGVpZ2VuLCBhdWYgZGllIEphZ2QgIgorICAgICAgICAienUgZ2VoZW4gLSBhbHMgd3VlcmRlIEFydGVtaXMgcGVyc29lbmxpY2ggRGVpbmUgQW5ncmlmZmUgIgorICAgICAgICArIG51bTJkZXNjX2ZpZ2h0KGVmZmVrdCkKKyAgICAgICAgKyAiIHZlcmJlc3Nlcm4uIiw3OCkpOworICAgIHJldHVybiAxOworICB9CisgIHJldHVybiAwOworfQorCisvLyBBTjogTWFnaXNjaGUgV2VzZW4gc29sbGVuIHNlaW46IENMX0VMRU1FTlRBTCwgQ0xfSUxMVVNJT04sIENMX1NIQURPVworLy8gQ0xfRFJBR09OLCBDTF9ERU1PTiwgQ0xfU0hBUEVDSEFOR0VSLCBDTF9IQVJQWQorcHJpdmF0ZSBpbnQgYWN0X2F0dHJfZGFtX21hZ2ljYWwoaW50IGVmZmVrdCkKK3sKKyAgaWYgKHJlZ19ob29rKEhfSE9PS19BVFRBQ0tfTU9ELCBIX0RBVEFfTU9ESUZJQ0FUT1IpID09IDEpCisgIHsKKyAgICBpZiAoIW1hcHBpbmdwKGF0dF9jbGFzc2VzKSkgYXR0X2NsYXNzZXM9bV9hbGxvY2F0ZSg0KTsKKyAgICBhdHRfY2xhc3Nlc1tDTF9EUkFHT05dID0gYXR0X2NsYXNzZXNbQ0xfRUxFTUVOVEFMXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gYXR0X2NsYXNzZXNbQ0xfU0hBRE9XXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgID0gYXR0X2NsYXNzZXNbQ0xfSUxMVVNJT05dCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBlZmZla3QvMjA7CisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgYnJlYWtfc3RyaW5nKAorICAgICAgICAiTWVya3d1ZXJkaWcuIER1IGhhc3QgZ2VyYWRlIGRhcyBHZWZ1ZWhsLCBhbHMgZmllbGUgRGlyIGRlciAiCisgICAgICAgICJLYW1wZiBnZWdlbiB2b24gSGVrYXRlIGJlc2NoZW5rdGUgV2VzZW4gIgorICAgICAgICArIG51bTJkZXNjX2ZpZ2h0KGVmZmVrdCkKKyAgICAgICAgKyAiIGxlaWNodGVyLiIsNzgpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworLy8gQU46IFVudG90ZSBzb2xsZW4gc2VpbjogQ0xfU0tFTEVUT04sIENMX0dIT1VMLCBDTF9HSE9TVCwgQ0xfVkFNUElSRQorLy8gQ0xfWk9NQklFLCBDTF9VTkRFQUQKKy8vIEJsb2VkIGlzdCBudXIsIGRhc3MgQ0xfVU5ERUFEIGFsbGUgYW5kZXJlbiBlbnRoYWVsdCBiaXMgYXVmIENMX0dIT1NULgorLy8gQWxzbyBsYXNzZW4gd2lyIGRpZSBVbnRlcnNjaGVpZHVuZyB1bmQgc2Nocml0dHdlaXNlIEZyZWlzY2hhbHR1bmcKKy8vIGVyc3QgZWlubWFsIHNlaW4uCitwcml2YXRlIGludCBhY3RfYXR0cl9kYW1fdW5kZWFkKGludCBlZmZla3QpCit7CisgIGlmIChyZWdfaG9vayhIX0hPT0tfQVRUQUNLX01PRCwgSF9EQVRBX01PRElGSUNBVE9SKSA9PSAxKQorICB7CisgICAgLy8gWm9tYmllcywgU2tlbGV0dGUsIEdodWxlLi4uCisgICAgaWYgKCFtYXBwaW5ncChhdHRfY2xhc3NlcykpIGF0dF9jbGFzc2VzPW1fYWxsb2NhdGUoMSk7CisgICAgYXR0X2NsYXNzZXNbQ0xfVU5ERUFEXSA9ICBlZmZla3QvMjA7CisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgYnJlYWtfc3RyaW5nKAorICAgICAgICAiQXVmIGVpbm1hbCBoYXN0IER1IGRlbiBFaW5kcnVjaywgZGFzcyBkaWUgS3JlYXR1cmVuIGRlcyAiCisgICAgICAgICJIYWRlcyBEZWluZW4gQW5ncmlmZmVuICIKKyAgICAgICAgKyBudW0yZGVzY19maWdodChlZmZla3QpCisgICAgICAgICsgIiB3ZW5pZ2VyIGVudGdlZ2VuIHp1IHNldHplbiBoYWJlbi4iLDc4KSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3ByaXZhdGUgaW50IGFjdF9hdHRyX3Byb3RfYW5pbWFscyhpbnQgZWZmZWt0KQoreworICBpZiAocmVnX2hvb2soSF9IT09LX0RFRkVORCwgSF9EQVRBX01PRElGSUNBVE9SKSA9PSAxKQorICB7CisgICAgaWYgKCFtYXBwaW5ncChwcm90X2NsYXNzZXMpKSBwcm90X2NsYXNzZXM9bV9hbGxvY2F0ZSgxKTsKKyAgICBwcm90X2NsYXNzZXNbQ0xfQU5JTUFMXSA9IGVmZmVrdC8yMDsKKyAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBicmVha19zdHJpbmcoCisgICAgICAgICJEdSBoYXN0IGRhcyBHZWZ1ZWhsLCBkYXNzIEFydGVtaXMgaWhyZSBzY2h1ZXR6ZW5kZSBIYW5kICIKKyAgICAgICAgKyBudW0yZGVzY19maWdodChlZmZla3QpCisgICAgICAgICsgIiB1ZWJlciBEaWNoIGhhZWx0LiIsNzgpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworcHJpdmF0ZSBpbnQgYWN0X2F0dHJfcHJvdF9tYWdpY2FsKGludCBlZmZla3QpCit7CisgIGlmIChyZWdfaG9vayhIX0hPT0tfREVGRU5ELCBIX0RBVEFfTU9ESUZJQ0FUT1IpID09IDEpCisgIHsKKyAgICBpZiAoIW1hcHBpbmdwKHByb3RfY2xhc3NlcykpIHByb3RfY2xhc3Nlcz1tX2FsbG9jYXRlKDQpOworICAgIHByb3RfY2xhc3Nlc1tDTF9EUkFHT05dID0gcHJvdF9jbGFzc2VzW0NMX0VMRU1FTlRBTF0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IHByb3RfY2xhc3Nlc1tDTF9TSEFET1ddCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBwcm90X2NsYXNzZXNbQ0xfSUxMVVNJT05dCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSBlZmZla3QvMjA7CisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgYnJlYWtfc3RyaW5nKAorICAgICAgICAiRHUgaGFzdCBkYXMgR2VmdWVobCwgZGFzcyB2b24gSGVrYXRlIGJlc2NoZW5rdGUgV2VzZW5oZWl0ZW4gRGlyICIKKyAgICAgICAgK251bTJkZXNjX2ZpZ2h0KGVmZmVrdCkKKyAgICAgICAgKyAiIHdlbmlnZXIgYW5oYWJlbiBrb2VubmVuLiIsNzgpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworcHJpdmF0ZSBpbnQgYWN0X2F0dHJfcHJvdF91bmRlYWQoaW50IGVmZmVrdCkKK3sKKyAgaWYgKHJlZ19ob29rKEhfSE9PS19ERUZFTkQsIEhfREFUQV9NT0RJRklDQVRPUikgPT0gMSkKKyAgeworICAgIC8vIFpvbWJpZXMsIFNrZWxldHRlLCBHaHVsZS4uLgorICAgIGlmICghbWFwcGluZ3AocHJvdF9jbGFzc2VzKSkgcHJvdF9jbGFzc2VzPW1fYWxsb2NhdGUoMSk7CisgICAgcHJvdF9jbGFzc2VzW0NMX1VOREVBRF0gPSAgZWZmZWt0LzIwOworICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksIGJyZWFrX3N0cmluZygKKyAgICAgICAgIkR1IGJpc3QgcGxvZXR6bGljaCB6dXZlcnNpY2h0bGljaCwgQW5ncmlmZmVuIGRlciBLcmVhdHVyZW4gIgorICAgICAgICAiZGVzIEhhZGVzICIKKyAgICAgICAgKyBudW0yZGVzY19maWdodChlZmZla3QpCisgICAgICAgICsgIiBiZXNzZXIgd2lkZXJzdGVoZW4genUga29lbm5lbi4iLDc4KSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKworcHJpdmF0ZSBpbnQgYWN0X2F0dHJfdHJhZ2VuKGludCBlZmZla3QpCit7CisgIGlmICggSVNfTEVBUk5FUihlbnZpcm9ubWVudCgpKSApCisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgc3ByaW50ZigiZWZmZWt0OiAlZFxuIixlZmZla3QpKTsKKyAgU2V0UHJvcChQX1dFSUdIVCwgUXVlcnlQcm9wKFBfV0VJR0hUKSAtIGVmZmVrdCo0KTsKKyAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwKKyAgICAgIEJTKCJEdSBmdWVobHN0IERpY2ggcGxvZXR6bGljaCAiK251bTJkZXNjKGVmZmVrdCkKKyAgICAgICAgKyAoZWZmZWt0PjAgPyAiIGVudGxhc3RldCIgOiAiIGJlbGFzdGV0IikgKyAiLiIpKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vIEJlcmVjaG5ldCBlaW5lIG1heC4gVmVyem9lZ2VydW5nIGRlciBXaXJrdW5nIGFiaGFlbmdpZyB2b24gZGVyIFdpcmt1bmcgdW5kCisvLyBlaW5lciBXaXJrc2Nod2VsbGUuIERlciByZWwuIEFic3RhbmQgdm9uIGRlciBXaXJrc2Nod2VsbGUgKHJlbGF0aXYgenVtIG1heC4KKy8vIG1vZWdsaWNoZW4gQWJzdGFuZCkgd2lyZCBoaWVyYmVpIGdlbnV0enQuIEF1c3NlcmRlbSBpc3QgZGllIG1heC4KKy8vIFZlcnpvZWdlcnVuZyBuYXR1ZXJsaWNoIGRpZSBXaXJrdW5nc2RhdWVyIGRlcyBUcmFua2VzLgorLy8gPGR1cmF0aW9uPiBtdXNzIGltIFRyYW5rIHNjaG9uIGdlc2V0enQgc2Vpbi4KK3ByaXZhdGUgaW50IGNhbGNfbWF4X2RlbGF5KGludCBlZmZla3QsIGludCB3aXJrc2Nod2VsbGUpCit7CisgIGludCBhYnN0YW5kID0gYWJzKGVmZmVrdCAtIHdpcmtzY2h3ZWxsZSk7CisgIGlmICghZHVyYXRpb24pIGR1cmF0aW9uID0gdGltZSgpKzYwMDsKKyAgaWYgKCBJU19MRUFSTkVSKGVudmlyb25tZW50KCkpICkKKyAgICBwcmludGYoImNhbGNfbWF4X2RlbGF5OiAlZFxuIiwoKGR1cmF0aW9uLXRpbWUoKSkgKiBhYnN0YW5kKSAvCisgICAgICAoMjAwMC1hYnMod2lya3NjaHdlbGxlKSkpOworICByZXR1cm4gKChkdXJhdGlvbi10aW1lKCkpICogYWJzdGFuZCkgLyAoMjAwMC1hYnMod2lya3NjaHdlbGxlKSk7Cit9CisKKy8vVE9ETzogZGllIFplaXR2ZXJ6b2VnZXJ1bmcgaXN0IG5lbiBuZXR0ZXIgRWZmZWt0LCBhYmVyIHplaXR2ZXJnem9lZ2VydGUKKy8vVHBvcnRzIHNpbmQgb2VmdGVyIGtlaW5lIGd1dGUgSWRlZSAtPiBub2NoIHBydWVmZW4KKy8vVE9ETzogRGllIFplaXR2ZXJ6b2VnZXJ1bmcgYmVpIE5PX1RQT1JUX09VVCBhdWNoIG5vY2htYWwgcHJ1ZWZlbgorcHJpdmF0ZSBpbnQgYWN0X2F0dHJfZmxlZV90cG9ydChpbnQgZWZmZWt0KQoreworICAvLyBlZmZla3QgPiAwIHRlbGVwb3J0aWVydCBzb2ZvcnQgenUgaGFsYndlZ3Mgc2ljaGVyZW4gT3J0ZW4KKyAgLy8gLTc1MCA8PSBlZmZla3QgPCAwIHRlbGVwb3J0aWVydCBhdWNoIHNvZm9ydCB6dSBuaWNodCBzbyBkb2xsZW4gT3J0ZW4KKyAgLy8gLTIwMDAgPD0gZWZmZWt0IDwgLTc1MCB0ZWxlcG9ydGllcnQgc3BhZXRlciB6dSBibG9lZGVuIE9ydGVuCisgIGlmIChlZmZla3QgPCAtNzUwICYmIGVmZmVrdCA+PSAtMjAwMCkKKyAgeworICAgIC8vIFZlcnpvZWdlcnVuZyBhdXNyZWNobmVuIHVuZCBkaWVzIGhpZXIgcGVyIGNhbGxfb3V0IG5vY2htYWwgbWl0IGVpbmVtCisgICAgLy8gZWZmZWt0IHJ1ZmVuLCBkZXIgZWluZSBpbnN0YW50YW5lIFJlYWt0aW9uIGF1c2xvZXN0LgorICAgIC8vIGVmZmVrdCAtIDIwMDAgaXN0IGVpbiBIYWNrLCBkYW1pdCBuaWNodCBub2NobWFsIHZlcnpvZWdlcnQgd2lyZC4KKyAgICBjYWxsX291dCgjJ2FjdF9hdHRyX2ZsZWVfdHBvcnQsCisgICAgICAgIHJhbmRvbShjYWxjX21heF9kZWxheShlZmZla3QsIC03NTApKSsxLCBlZmZla3QgLSAyMDAwKTsKKyAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLAorICAgICAgICAiRGVpbmUgVW1nZWJ1bmcgZnVlaGx0IHNpY2ggbmFjaCB1bmQgbmFjaCB1bndpcmtsaWNoZXIgYW4uXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIC8vIEVmZmVrdGUgaW5zdGFudGFuIGF1c2xvZXNlbi4KKworICAvLyB3ZW5uIGhpZXIga2VpbiBQX05PX1RQT1JUIGVybGF1YnQgaXN0LCBtYWwgZ3Vja2VuLCBvYiB3aXIgc3BhZXRlciBub2NoCisgIC8vIHplaXQgaGFiZW4uCisgIGlmIChlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKS0+UXVlcnlQcm9wKFBfTk9fVFBPUlQpPT1OT19UUE9SVF9PVVQpCisgIHsKKyAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLAorICAgICAgICBCUygiSXJnZW5kZXR3YXMgaGFlbHQgRGljaCBhbiBkaWVzZW0gT3J0IGZlc3QuIikpOworICAgIGludCBkZWxheSA9IGR1cmF0aW9uIC0gdGltZSgpOworICAgIC8vIHdlbm4gbm9jaCBnZW51ZyBSZXN0emVpdCwgbm9jaG1hbCB2ZXJzdWNoZW4sIHNvbnN0IG5peCBtYWNoZW4uCisgICAgaWYgKGRlbGF5PjEwKQorICAgIHsKKyAgICAgIC8vIEFOL1RPRE86IEthbm4gZGFzIG5pY2h0IGF1Y2ggemllbWxpY2ggbGFuZyBzZWluPworICAgICAgY2FsbF9vdXQoIydhY3RfYXR0cl9mbGVlX3Rwb3J0LCByYW5kb20oZGVsYXkpLCBlZmZla3QpOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorCisgIC8vIGRlbiBIYWNrIHZvbiBvYmVuIHJ1ZWNrZ2FlbmdpZyBtYWNoZW4sIHdpciBicmF1Y2hlbiBkZW4gb3JpZ2luYWxlbgorICAvLyBFZmZla3R3ZXJ0IHp1cnVlY2suCisgIGlmIChlZmZla3QgPCAtMjAwMCkKKyAgICBlZmZla3QgKz0gMjAwMDsKKworICBzdHJpbmcqIGRlc3RzOworICBpZiAoIGVmZmVrdCA+IDAgKQorICB7CisgICAgc3dpdGNoKGVmZmVrdCkKKyAgICB7CisgICAgICBjYXNlIDAuLjQ5OToKKyAgICAgICAgZGVzdHMgPSAoeyIvZC9pbnNlbG4vemVzc3RyYS92dWxrYW53ZWcvcm9vbS9yMSIsCisgICAgICAgICAgICAgICAgICAiL2QvZmVybndlc3QvbGkveGlhbi9sYWIyL2dyYWIyIiwKKyAgICAgICAgICAgICAgICAgICIvZC9lYmVuZS9taXJpbC9zY2hsb3NzL2hlaWRlMTEiLAorICAgICAgICAgICAgICAgICAgIi9kL3BvbGFyL2FsbGUvcm9vbS93ZWc0XzE1IiwKKyAgICAgICAgICAgICAgICAgICIvZC9kc2NodW5nZWwvYXJhdGhvcm4vdGVtcGVsL3Jvb20vdDQtNSIsCisgICAgICAgICAgICAgICAgICAiL2QvYW5mYWVuZ2VyL2FyYXRob3JuL21pbml0dXQvcm9vbS9odWV0dGVfIisKKyAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQoKS0+cXVlcnlfcmVhbF9uYW1lKCksCisgICAgICAgICAgICAgICAgIH0pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNTAwLi43NDk6CisgICAgICAgIGRlc3RzID0gKHsiL2QvZWJlbmUvYmVydHJhbS9lYmVuZS93YXNzZXI4IiwKKyAgICAgICAgICAgICAgICAgICIvZC9lYmVuZS9yb29tL2dlYnVlc2NoMl8zIiwKKyAgICAgICAgICAgICAgICAgICIvZC9wb2xhci9hbGxlL3Jvb20vZWlzd3Vlc3RlL2Vpc3d1ZXN0ZVs0LDZdIiwKKyAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgIGlmIChlbnZpcm9ubWVudCgpLT5RdWVyeVByb3AoUF9SRUFMX1JBQ0UpIT0iRHVua2VsZWxmIikKKyAgICAgICAgICBkZXN0cyArPSAoeyIvZC91bnRlcndlbHQvcGFkcmVpYy9rbmVpcGUva25laXBlIn0pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNzUwLi45OTk6CisgICAgICAgIGRlc3RzID0gKHsiL2QvZ2ViaXJnZS9zaWx2YW5hL2Nyb25vZXJ0YWwvcm9vbS90ZjQiLAorICAgICAgICAgICAgICAgICAgIi9kL2luc2Vsbi9zY2hpZmZlL2Zsb3NzIiwKKyAgICAgICAgICAgICAgICAgICIvZC9wb2xhci9odW1uaS9oZXhlbi9yb29tL2xldWNodGthbW1lciIsCisgICAgICAgICAgICAgICAgICAiL2QvcG9sYXIvZ2FieWxvbi90ZW1vbmcvcm9vbXMvYW5sZWdlc3RlbGxlIiwKKyAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAxMDAwLi4xMjQ5OgorICAgICAgICBkZXN0cyA9ICh7Ii9kL2Zlcm53ZXN0L3NoaW5vYmkva29uZnVfcXVlc3Qvcm9vbS9pbnNlbDQiLAorICAgICAgICAgICAgICAgICAgIi9kL2Zlcm53ZXN0L3Vsby9tdXJhL3Rva29yby9oYXVzNCIsCisgICAgICAgICAgICAgICAgICAiL2QvZWJlbmUvcm9vbS9IYWxsZS9zaGFsbGUxNCIsCisgICAgICAgICAgICAgICAgIH0pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMTI1MC4uMTQ5OToKKyAgICAgICAgZGVzdHMgPSAoeyIvZC9nZWJpcmdlL3NpbHZhbmEvY3Jvbm9lcnRhbC9yb29tL3RmNCIsCisgICAgICAgICAgICAgICAgICAiL2dpbGRlbi96YXViZXJlciIsCisgICAgICAgICAgICAgICAgICAiL2QvZ2ViaXJnZS9nZW9yZy9yb29tL3cxMSIKKyAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAxNTAwLi4xNzQ5OgorICAgICAgICBkZXN0cyA9ICh7Ii9naWxkZW4vYmllcnNjaHVldHRsZXIiLAorICAgICAgICAgICAgICAgICAgIi9naWxkZW4va2FlbXBmZXIiLAorICAgICAgICAgICAgICAgICAgIi9kL3dhbGQvZ3VuZHVyL2hvYmJpdGRvcmYvc2NocmVpbiIsCisgICAgICAgICAgICAgICAgICAiL2QvdmxhbmQvbW9yZ290aC9yb29tL2NpdHkvcmF0aGFsbGUiLAorICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICBkZXN0cyA9ICh7ZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfU1RBUlRfSE9NRSl8fAorICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCgpLT5RdWVyeURlZmF1bHRIb21lKCksCisgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCgpLT5RdWVyeURlZmF1bHRIb21lKCksCisgICAgICAgICAgICAgICAgICAiL2QvZWJlbmUvcm9vbS9Qb3J0VmFpbi9wb19oYWYyIiwKKyAgICAgICAgICAgICAgICAgICIvZC9nZWJpcmdlL3Jvb20vaGUzeDMiLAorICAgICAgICAgICAgICAgICAgIi9kL2ViZW5lL3Jvb20vaHVldHRlIiwKKyAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorICBlbHNlIGlmICggZWZmZWt0IDwgMCApCisgIHsKKyAgICBzd2l0Y2goZWZmZWt0KQorICAgIHsKKyAgICAgIGNhc2UgLTQ5OS4uMDoKKyAgICAgICAgZGVzdHMgPSAoeyIvZC9wb2xhci9iZW5kZWlnaWQvcm9vbXMvbmVza2F5YS9uZXNrYXkxMiIsCisgICAgICAgICAgICAgICAgICAiL3BsYXllcnMva2V0b3MvZ2wvcm9vbS9nbDF4MSIsCisgICAgICAgICAgICAgICAgICAiL2QvaW5zZWxuL3plc3N0cmEvdnVsa2Fud2VnL3Jvb20vcjEwIiwKKyAgICAgICAgICAgICAgICAgICIvZC92bGFuZC9tb3Jnb3RoL3Jvb20va2F0YS9rdGFua2UiLAorICAgICAgICAgICAgICAgICAgIi9kL2ViZW5lL3phcmRvei9idXJnL2ZldWVycmF1IiwKKyAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAtOTk5Li4tNTAwOgorICAgICAgICBkZXN0cyA9ICh7Ii9kL2ViZW5lL3Jvb20vSG9laGxlL2hnNiIsCisgICAgICAgICAgICAgICAgICAiL2QvZ2ViaXJnZS9zaWx2YW5hL3dhcm9rL3Jvb20vbDMvd2FfM3g3IiwKKyAgICAgICAgICAgICAgICAgICIvZC92bGFuZC9tb3Jnb3RoL3Jvb20va2F0YS94a2F0MDMiLAorICAgICAgICAgICAgICAgICAgIi9kL3ZsYW5kL21vcmdvdGgvcm9vbS9rYXRhL2thdGE1IiwKKyAgICAgICAgICAgICAgICAgICIvZC93YWxkL3lvcnUvb3J0L2RyYXZpL3dlZzUiLAorICAgICAgICAgICAgICAgICAgIi9kL3dhbGQvYXRhbXVyL3Jvb20vZTgzIiwKKyAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAtMTQ5OS4uLTEwMDA6CisgICAgICAgIGRlc3RzID0gKHsiL2QvcG9sYXIvYmVuZGVpZ2lkL3Jvb21zL3Bhc3MvcGFzc19lMSIsCisgICAgICAgICAgICAgICAgICAiL2QvZWJlbmUvcm9vbS9nZWJ1ZXNjaCIsCisgICAgICAgICAgICAgICAgICAiL2QvZ2ViaXJnZS9zaWx2YW5hL3dhcm9rL3Jvb20vbDEvd2FfMXg2IiwKKyAgICAgICAgICAgICAgICAgICIvZC92bGFuZC9tb3Jnb3RoL3Jvb20va2F0YS9na2F0MTciLAorICAgICAgICAgICAgICAgICAgIi9kL3dhbGQvYXRhbXVyL3Jvb20vZTEyIiwKKyAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgIGlmIChlbnZpcm9ubWVudCgpLT5RdWVyeVByb3AoUF9SRUFMX1JBQ0UpPT0iRHVua2VsZWxmIikKKyAgICAgICAgICBkZXN0cyArPSAoeyIvZC91bnRlcndlbHQvcGFkcmVpYy9rbmVpcGUva25laXBlIn0pOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgLTE3NDkuLi0xNTAwOgorICAgICAgICBkZXN0cyA9ICh7Ii9kL2RzY2h1bmdlbC93dXJ6ZWwvdDIiLAorICAgICAgICAgICAgICAgICAgIi9kL3ZsYW5kL21vcmdvdGgvcm9vbS9rYXRhL3VrYXQyNiIsCisgICAgICAgICAgICAgICAgICAiL2QvdmxhbmQvbW9yZ290aC9yb29tL2thdGEvaDEyIiwKKyAgICAgICAgICAgICAgICAgICIvZC9nZWJpcmdlL2JvaW5nL3NtL2w1L201eDIiLAorICAgICAgICAgICAgICAgICB9KTsKKyAgICAgICAgaWYgKGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX0dVSUxEKT09ImNoYW9zIikKKyAgICAgICAgICBkZXN0cys9KHsiL2dpbGRlbi9rbGVydXMifSk7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgZGVzdHMgPSAoeyIvZC9lYmVuZS9yb2NodXMvcm9vbS9zcDEwIiwKKyAgICAgICAgICAgICAgICAgICIvZC9lYmVuZS9yb2NodXMvcXVlc3RfM3BsYXllci9yb29tL3NjaGFjaHQxMCIsCisgICAgICAgICAgICAgICAgIH0pOworICAgICAgICBpZiAoIElTX1NFRVIoZW52aXJvbm1lbnQoKSkgKQorICAgICAgICAgIGRlc3RzICs9ICh7Ii9kL3dhbGQvcGFyYWNlbHN1cy9mcm9vbS9zY2hfNmUiLAorICAgICAgICAgICAgICAgICAgICAgIi9kL3dhbGQvcGFyYWNlbHN1cy9mcm9vbS9zY2hfOXgiLAorICAgICAgICAgICAgICAgICAgICAgIi9kL3dhbGQvcGFyYWNlbHN1cy9mcm9vbS9zY2gyXzZkIiwKKyAgICAgICAgICAgICAgICAgICAgfSk7CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgfQorICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLAorICAgICAgQlMoIkVpbmUgS3JhZnQgemVycnQgYW4gRGlyLCBkaWUgV2VsdCB2ZXJzY2h3aW1tdC4uLiIpKTsKKyAgaWYgKGVudmlyb25tZW50KCktPm1vdmUoZGVzdHNbcmFuZG9tKHNpemVvZihkZXN0cykpXSxNX1RQT1JUKSA9PSBNT1ZFX09LKQorICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksCisgICAgICAgICJFaW5lbiBNb21lbnQgc3BhZXRlciBiaXN0IER1IGdhbnogd29hbmRlcnMuXG4iKTsKKyAgZWxzZQorICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksCisgICAgICAgICJBYmVyIHNvbnN0IHBhc3NpZXJ0IG5pY2h0cy5cbiIpOworICByZXR1cm4gMTsKK30KKworcHJpdmF0ZSBpbnQgYWN0X2F0dHJfY2hhbmdlX2RpbWVuc2lvbihpbnQgZWZmZWt0KQoreworICAvLyBudXIgZWZmZWt0ID49IDEwMDAgYWVuZGVybiBkaWUgRGltZW5zaW9uIGluc3RhbnRhbi4gOy0pCisgIGlmIChlZmZla3QgPiAwICYmIGVmZmVrdCA8IDEwMDApCisgIHsKKyAgICAvLyBWZXJ6b2VnZXJ1bmcgYXVzcmVjaG5lbiB1bmQgZGllcyBoaWVyIHBlciBjYWxsX291dCBub2NobWFsIG1pdCBlaW5lbQorICAgIC8vIGVmZmVrdCBydWZlbiwgZGVyIGVpbmUgaW5zdGFudGFuZSBSZWFrdGlvbiBhdXNsb2VzdC4KKyAgICBjYWxsX291dCgjJ2FjdF9hdHRyX2NoYW5nZV9kaW1lbnNpb24sCisgICAgICAgIHJhbmRvbShjYWxjX21heF9kZWxheShlZmZla3QsMTAwMCkpKzEsIDEwMDApOworICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksQlMoIlVtIERpY2ggaGVydW0gd2lyZCBhbGxlcyAiCisgICAgICAgICJsYW5nc2FtIGdyYXVlci5cbiIpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICAvLyBudXIgLTYwMCA8IGVmZmVrdCA8IDAgYWVuZGVybiBkaWUgRGltZW5zaW9uIGluc3RhbnRhbiA7LSkKKyAgaWYgKGVmZmVrdCA8IC02MDApCisgIHsKKyAgICAvLyBWZXJ6b2VnZXJ1bmcgYXVzcmVjaG5lbiB1bmQgZGllcyBoaWVyIHBlciBjYWxsX291dCBub2NobWFsIG1pdCBlaW5lbQorICAgIC8vIGVmZmVrdCBydWZlbiwgZGVyIGVpbmUgaW5zdGFudGFuZSBSZWFrdGlvbiBhdXNsb2VzdC4KKyAgICBjYWxsX291dCgjJ2FjdF9hdHRyX2NoYW5nZV9kaW1lbnNpb24sCisgICAgICAgIHJhbmRvbShjYWxjX21heF9kZWxheShlZmZla3QsIC02MDApKSsxLCAtNjAxKTsKKyAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLEJTKCJVbSBEaWNoIGhlcnVtIHdpcmQgYWxsZXMgIgorICAgICAgICAibGFuZ3NhbSBncmF1ZXIuXG4iKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgLy8gRWZmZWt0ZSBpbnN0YW50YW4gYXVzbG9lc2VuLgorICAvLyB3ZW5uIGhpZXIga2VpbiBQYXJhLVRyYW5zIGVybGF1YnQgaXN0LCBtYWwgZ3Vja2VuLCBvYiB3aXIgc3BhZXRlciBub2NoCisgIC8vIHplaXQgaGFiZW4uCisgIGlmIChlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKS0+UXVlcnlQcm9wKFBfTk9fUEFSQV9UUkFOUykpCisgIHsKKyAgICBpbnQgZGVsYXkgPSBkdXJhdGlvbiAtIHRpbWUoKTsKKyAgICAvLyB3ZW5uIG5vY2ggZ2VudWcgUmVzdHplaXQsIG5vY2htYWwgdmVyc3VjaGVuLCBzb25zdCBuaXggbWFjaGVuLgorICAgIGlmIChkZWxheT4xMCkKKyAgICB7CisgICAgICBjYWxsX291dCgjJ2FjdF9hdHRyX2NoYW5nZV9kaW1lbnNpb24sIHJhbmRvbShkZWxheSksIGVmZmVrdCk7CisgICAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBCUygiRGllIFdlbHQgdW0gRGljaCB3aXJkIGVpbiAiCisgICAgICAgICAgICAid2VuaWcgZ3JhdWVyLiIpKTsKKyAgICB9CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKCBlZmZla3QgPiAwICkKKyAgeworICAgIGlmICggZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfUEFSQSkgPiAwICkKKyAgICB7CisgICAgICBlbnZpcm9ubWVudCgpLT5TZXRQcm9wKFBfUEFSQSwgMCk7CisgICAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBCUygiRnVlciBlaW5lbiBrdXJ6ZW4gTW9tZW50IHNpZWhzdCBEdSBudXIgIgorICAgICAgICAgICJlaW4gZ3JhdWVzIFdhYmVybiB1bSBEaWNoIGhlcnVtLCBiZXZvciBkaWUgV2VsdCB3aWVkZXIgIgorICAgICAgICAgICJub3JtYWwgYXVzc2llaHQuXG4iKSk7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBCUygiRnVlciBlaW5lbiBrdXJ6ZW4gTW9tZW50IHNpZWh0IGFsbGVzIHVtICIKKyAgICAgICAgICAgICJEaWNoIGhlcnVtIGdyYXUgYXVzLiIpKTsKKyAgICB9CisgIH0KKyAgZWxzZSBpZiAoIGVmZmVrdCA8IDAgKQorICB7CisgICAgaWYgKCAhZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfUEFSQSkgKQorICAgIHsKKyAgICAgIGVudmlyb25tZW50KCktPlNldFByb3AoUF9QQVJBLCAxKTsKKyAgICAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBCUygiRnVlciBlaW5lbiBrdXJ6ZW4gTW9tZW50IHNpZWhzdCBEdSBudXIgIgorICAgICAgICAgICJlaW4gZ3JhdWVzIFdhYmVybiB1bSBEaWNoIGhlcnVtLCBiZXZvciBkaWUgV2VsdCB3aWVkZXIgIgorICAgICAgICAgICJub3JtYWwgYXVzc2llaHQuIEFiZXIgZXMgYmxlaWJ0IGVpbiB1bmd1dGVzIEdlZnVlaGwuXG4iKSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgQlMoIkZ1ZXIgZWluZW4ga3VyemVuIE1vbWVudCBzaWVodCBhbGxlcyB1bSAiCisgICAgICAgICAgICAiRGljaCBoZXJ1bSBncmF1IGF1cy4iKSk7CisgICAgfQorICB9CisgIHJldHVybiAxOworfQorCitwcml2YXRlIGludCBhY3RfYXR0cl9kZWZyb2coaW50IGVmZmVrdCkKK3sKKyAgLy8gbnVyIGVmZmVrdCA+IDEwMDAgZW50ZnJvc2NodCBpbnN0YW50YW4uIDstKQorICBpZiAoZWZmZWt0ID4gMCAmJiBlZmZla3QgPCAxMDAwKQorICB7CisgICAgLy8gVmVyem9lZ2VydW5nIGF1c3JlY2huZW4gdW5kIGRpZXMgaGllciBwZXIgY2FsbF9vdXQgbm9jaG1hbCBtaXQgZWluZW0KKyAgICAvLyBlZmZla3QgcnVmZW4sIGRlciBlaW5lIGluc3RhbnRhbmUgUmVha3Rpb24gYXVzbG9lc3QuCisgICAgY2FsbF9vdXQoIydhY3RfYXR0cl9kZWZyb2csIHJhbmRvbShjYWxjX21heF9kZWxheShlZmZla3QsMTAwMCkpKzEsIDEwMDApOworICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksQlMoCisgICAgICAgICJEdSBob2Vyc3QgcGxvZXR6bGljaCBsYXV0ZXMgR2VxdWFrZSwgd2FzIGxhbmdzYW0gaW1tZXIgbGVpc2VyICIKKyAgICAgICAgIndpcmQuXG4iKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgLy8gbnVyIC01MDAgPCBlZmZla3QgPCAwIGZyb3NjaHQgaW5zdGFudGFuIDstKQorICBpZiAoZWZmZWt0IDwgLTUwMCkKKyAgeworICAgIC8vIFZlcnpvZWdlcnVuZyBhdXNyZWNobmVuIHVuZCBkaWVzIGhpZXIgcGVyIGNhbGxfb3V0IG5vY2htYWwgbWl0IGVpbmVtCisgICAgLy8gZWZmZWt0IHJ1ZmVuLCBkZXIgZWluZSBpbnN0YW50YW5lIFJlYWt0aW9uIGF1c2xvZXN0LgorICAgIGNhbGxfb3V0KCMnYWN0X2F0dHJfZGVmcm9nLCByYW5kb20oY2FsY19tYXhfZGVsYXkoZWZmZWt0LCAtNTAwKSkrMSwgLTUwMSk7CisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSxCUygKKyAgICAgICAgIkR1IGhvZXJzdCBwbG9ldHpsaWNoIGdhbnogbGVpc2VzcyBHZXF1YWtlLCB3YXMgbGFuZ3NhbSBpbW1lciBsYXV0ZXIgIgorICAgICAgICAid2lyZC5cbiIpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIC8vIEVmZmVrdGUgaW5zdGFudGFuIGF1c2xvZXNlbi4KKyAgaWYgKCBlZmZla3QgPiAwICkKKyAgeworICAgIGlmICggZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfRlJPRykgKQorICAgIHsKKyAgICAgIGVudmlyb25tZW50KCktPlNldFByb3AoUF9GUk9HLDApOworICAgICAgdGVsbF9vYmplY3QoUEwsICJEdSBmdWVobHN0IERpY2ggZGV1dGxpY2ggd2VuaWdlciBncnVlbi5cbiIpOworICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgYnJlYWtfc3RyaW5nKCJEaWUgV2VsdCB1bSBEaWNoIGhlcnVtIHZlcmxpZXJ0ICIKKyAgICAgICAgInBsb2V0emxpY2ggYWxsZSBncnVlbmVuIEZhcmJ0b2VuZSwgZGllIGJhbGQgZGFyYXVmIGFsbG1hZWhsaWNoICIKKyAgICAgICAgInp1cnVlY2trZWhyZW4uIiw3OCkpOworICAgIH0KKyAgfQorICBlbHNlIGlmICggZWZmZWt0IDwgMCApIHsKKyAgICBpZiAoICFlbnZpcm9ubWVudCgpLT5RdWVyeVByb3AoUF9GUk9HKSApIHsKKyAgICAgIGVudmlyb25tZW50KCktPlNldFByb3AoUF9GUk9HLCAxKTsKKyAgICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksICJRdWFrIVxuIik7CisgICAgfQorICAgIGVsc2UgeworICAgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgYnJlYWtfc3RyaW5nKCJEZWluZSBTaWNodCB2ZXJzY2h3aW1tdCwgYWxsZXMgd2lyZCAiCisgICAgICAgICJpbnRlbnNpdiBncnVlbi4gTWVya3d1ZXJkaWcuIFp1bSBHbHVlY2sgaXN0IGRhcyBzY2huZWxsIHdpZWRlciAiCisgICAgICAgICJ2b3JiZWkuIiw3OCkpOworICAgIH0KKyAgfQorICByZXR1cm4gMTsKK30KKworcHJpdmF0ZSBpbnQgYWN0X2F0dHJfaGVhbF9scChpbnQgZWZmZWt0KQoreworICBpZiAoZWZmZWt0ID4gMCkKKyAgeworICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksCisgICAgICAgIEJTKCJEdSBmdWVobHN0IERpY2ggc2NobGFnYXJ0aWcgIitudW0yZGVzYyhlZmZla3QpCisgICAgICAgICAgKyAiIGJlc3Nlci4iKSk7CisgICAgZW52aXJvbm1lbnQoKS0+cmVzdG9yZV9oaXRfcG9pbnRzKGVmZmVrdC8xMCk7CisgIH0KKyAgZWxzZQorICB7CisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwKKyAgICAgICAgQlMoIkR1IGZ1ZWhsc3QgRGljaCBzY2hsYWdhcnRpZyAiK251bTJkZXNjKGVmZmVrdCkKKyAgICAgICAgICArICIgc2NobGVjaHRlci4iKSk7CisgICAgZW52aXJvbm1lbnQoKS0+ZG9fZGFtYWdlKC1lZmZla3QvMTApOworICB9CisgIHJldHVybiAxOworfQorCitwcml2YXRlIGludCBhY3RfYXR0cl9oZWFsX3NwKGludCBlZmZla3QpCit7CisgIGlmIChlZmZla3QgPiAwKQorICB7CisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwKKyAgICAgICAgQlMoIkR1IGZ1ZWhsc3QgRGljaCBzY2hsYWdhcnRpZyAiK251bTJkZXNjKGVmZmVrdCkKKyAgICAgICAgICArICIga29uemVudHJpZXJ0ZXIuIikpOworICAgIGVudmlyb25tZW50KCktPnJlc3RvcmVfc3BlbGxfcG9pbnRzKGVmZmVrdC8xMCk7CisgIH0KKyAgZWxzZQorICB7CisgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwKKyAgICAgICAgQlMoIkR1IGZ1ZWhsc3QgRGljaCBzY2hsYWdhcnRpZyAiK251bTJkZXNjKGVmZmVrdCkKKyAgICAgICAgICArICIgdW5rb256ZW50cmllcnRlci4iKSk7CisgICAgZW52aXJvbm1lbnQoKS0+cmVkdWNlX3NwZWxsX3BvaW50cygtZWZmZWt0LzEwKTsKKyAgfQorICByZXR1cm4gMTsKK30KKworCitwcml2YXRlIGludCBtb2RpZnlfc2Eoc3RyaW5nIHNhLCBpbnQgZWZmZWt0KQoreworICBzdHJpbmcgbXNnOworICBzd2l0Y2ggKHNhKQorICB7CisgICAgY2FzZSBTQV9TUEVFRDoKKyAgICAgIG1zZyA9ICJEdSB3aXJzdCBnZXJhZGUgIiArIG51bTJkZXNjKGVmZmVrdCkKKyAgICAgICAgICAgICsoZWZmZWt0PjAgPyAiIHNjaG5lbGxlci4iIDogIiBsYW5nc2FtZXIuIik7CisgICAgICBlZmZla3QgPSAoZWZmZWt0ICogMzApIC8gMjAwMDsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgU0FfRFVSQVRJT046CisgICAgICBtc2cgPSAiRHUgd2lyc3QgZ2VyYWRlICIgKyBudW0yZGVzYyhlZmZla3QpCisgICAgICAgICAgICArKGVmZmVrdD4wID8gIiBhdXNkYXVlcm5kZXIuIgorICAgICAgICAgICAgICAgICAgICAgICA6ICIgd2VuaWdlciBhdXNkYXVlcm5kLiIpOworICAgICAgZWZmZWt0ID0gKGVmZmVrdCAqIDI1KSAvIDIwMDA7CisgICAgICBicmVhazsKKyAgICBjYXNlIFNBX1NQRUxMX1BFTkVUUkFUSU9OOgorICAgICAgbXNnID0gIkRlaW5lIGdlaXN0aWdlIER1cmNoc2V0enVuZ3NrcmFmdCBoYXQgc2ljaCBnZXJhZGUgIgorICAgICAgICAgICAgKyBudW0yZGVzYyhlZmZla3QpCisgICAgICAgICAgICArKGVmZmVrdD4wID8gIiB2ZXJiZXNzZXJ0LiIgOiAiIHZlcnNjaGxlY2h0ZXJ0LiIpOworICAgICAgZWZmZWt0ID0gKGVmZmVrdCAqIDMwKSAvIDIwMDA7CisgICAgICBicmVhazsKKyAgfQorICBpZiAoZW52aXJvbm1lbnQoKS0+TW9kaWZ5U2tpbGxBdHRyaWJ1dGUoc2EsIGVmZmVrdCwgZHVyYXRpb24tdGltZSgpKSA9PQorICAgICAgICBTQV9NT0RfT0spCisgIHsKKyAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLEJTKG1zZykpOworICAgIHJldHVybiAxOworICB9CisgIHJldHVybiAwOworfQorCitwcml2YXRlIGludCBhY3RfYXR0cl9jaGFuZ2Vfc2Ffc3BlZWQoaW50IGVmZmVrdCkKK3sKKyAgcmV0dXJuIG1vZGlmeV9zYShTQV9TUEVFRCwgZWZmZWt0KTsKK30KK3ByaXZhdGUgaW50IGFjdF9hdHRyX2NoYW5nZV9zYV9kdXJhdGlvbihpbnQgZWZmZWt0KQoreworICByZXR1cm4gbW9kaWZ5X3NhKFNBX0RVUkFUSU9OLCBlZmZla3QpOworfQorcHJpdmF0ZSBpbnQgYWN0X2F0dHJfY2hhbmdlX3NhX3NwZWxsX3BlbmV0cmF0aW9uKGludCBlZmZla3QpCit7CisgIHJldHVybiBtb2RpZnlfc2EoU0FfU1BFTExfUEVORVRSQVRJT04sIGVmZmVrdCk7Cit9CisKKworLy8gU3BpZWxlciBNVVNTIGRhcyBlbnZpcm9ubWVudCgpIHNlaW4hCitwcml2YXRlIHZvaWQgZWZmZWt0KCkKK3sKKyAgLy8gQWxzIGVyc3RlcyBkaWUgV2lya3VuZ3NkYXVlciB2ZXJ3dXJzdGVuLCBlaW5pZ2UgRWZmZWt0ZSBicmF1Y2hlbgorICAvLyA8ZHVyYXRpb24+LgorICAvLyBXYW5uIGxhdWZlbiBkaWUgRWZmZWt0ZSBkZW5uIHNwYWV0ZW5zdGVucyBhYj8KKyAgZHVyYXRpb24gPSB0aW1lKCkgKyBkYXRhW1RfRUZGRUNUX0RVUkFUSU9OXTsKKyAgY2FsbF9vdXQoIyd0ZXJtaW5hdGVfZWZmZWN0cywgZGF0YVtUX0VGRkVDVF9EVVJBVElPTl0pOworCisgIC8vIG51ciBlY2h0ZSB3aXJrdW5nZW4gYmVydWVja3NpY2h0aWdlbiwga2VpbmUgIk1ldGFkYXRlbiIKKyAgbWFwcGluZyBlZmZlY3RzID0gZGF0YSAmIFRfS1JBVVRfRUZGRUNUUzsKKyAgLy8gZnVlciBTcGllbGVyIHdpcmQgZGVyIFBhcmF0cmFucyBuaWNodCBzdGF0dGZpbmRlbi4KKyAgaWYgKCFJU19TRUVSKGVudmlyb25tZW50KCkpKQorICAgIG1fZGVsZXRlKGRhdGEsIFRfQ0hBTkdFX0RJTUVOU0lPTik7CisKKyAgLy8gV2FlaHJlbmQgZGVyIFdpcmt1bmcgaXN0IGRpZXNlcyBPYmpla3Qgc2Nob25tYWwgdW5zaWNodGJhci4KKyAgU2V0UHJvcChQX0lOVklTLCAxKTsKKyAgLy8gR2V3aWNodCBudWxsZW4sIGJldm9yIGRpZSBXaXJrdW5nZW4gYWt0aXZpZXJ0IHdlcmRlbiwgZGEgZGllCisgIC8vIFdpcmt1bmcgdm9uIFRfQ0FSUlkgYW5zb25zdGVuIHdpZWRlciBkZWFrdGl2aWVydCB3dWVyZGUuIAorICBTZXRQcm9wKFBfV0VJR0hULCAwKTsKKyAgLy8gbmV1ZSwgbGVlcmUgRmxhc2NoZSBpbnMgSW52ZW50YXIgZGVzIFNwaWVsZXJzIGJld2VnZW4uCisgIGNsb25lX29iamVjdChUUkFOS0lURU0pLT5tb3ZlKGVudmlyb25tZW50KCksTV9OT0NIRUNLfE1fU0lMRU5UKTsKKworICAvLyBhdWZ0cmVubmVuIGluIHBvc2l0aXZlIHVuZCBuZWdhdGl2ZSBFZmZla3RlLiBLZXlzIG1pdCBXZXJ0IDAgd2VyZGVuCisgIC8vIGlnbm9yaWVydC4KKyAgbWFwcGluZyBwZWZmID0gZmlsdGVyKGVmZmVjdHMsIGZ1bmN0aW9uIGludCAoc3RyaW5nIGssIGludCB2YWwpCisgICAgICAgICAgICAgICAgICAgICAgICB7cmV0dXJuIHZhbCA+IDA7fSk7CisgIG1hcHBpbmcgbmVmZiA9IGZpbHRlcihlZmZlY3RzLCBmdW5jdGlvbiBpbnQgKHN0cmluZyBrLCBpbnQgdmFsKQorICAgICAgICAgICAgICAgICAgICAgICAge3JldHVybiB2YWwgPCAwO30pOworICAvLyBlcnN0IGRpZSBwb3NpdGl2ZW4sIGRhbm4gZGllIG5lZ2F0aXZlbiBXaXJrdW5nZW4gYWt0aXZpZXJlbgorICAvLyBmdWVyIGplZGUgV2lya3VuZyB3aXJkIGVpbmUgbGZ1biBhY3RfPHRyYW5rYXR0cmlidXQ+KCkgZ2VydWZlbiwgei5CLgorICAvLyBhY3RfYXR0cl90cmFnZW4oKSAoLT4gYWN0X1RfQ0FSUlkoKSApCisgIG1hcHBpbmcgbm90YWN0aXZhdGVkID0KKyAgICAgICAgICBmaWx0ZXIocGVmZiwgZnVuY3Rpb24gaW50IChzdHJpbmcgaywgaW50IHZhbCkKKyAgICAgICAgICAgICAge3JldHVybiAhZnVuY2FsbChzeW1ib2xfZnVuY3Rpb24oImFjdF8iK2ssdGhpc19vYmplY3QoKSksIHZhbCk7fSkKKyAgICAgICAgICsKKyAgICAgICAgICBmaWx0ZXIobmVmZiwgZnVuY3Rpb24gaW50IChzdHJpbmcgaywgaW50IHZhbCkKKyAgICAgICAgICAgICAge3JldHVybiAhZnVuY2FsbChzeW1ib2xfZnVuY3Rpb24oImFjdF8iK2ssdGhpc19vYmplY3QoKSksIHZhbCk7fSk7CisgIC8vIE1lbGR1bmdlbiBhdXNnZWJlbiB1ZWJlciBuaWNodCBha3RpdmllcnRlIFdpcmt1bmdlbj8KKyAgLy8gVE9ETworfQorCitzdGF0aWMgaW50IGNtZF90cmlua2VuKHN0cmluZyBzdHIsIG1peGVkICpwYXJhbSkKK3sKKyAgaWYgKGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpICE9IFBMKQorICB7CisgICAgd3JpdGUoIkF1cyBhdWYgZGVtIEJvZGVuIGxpZWdlbmRlIEZsYXNjaGVuIHRyaW5rdCBlcyBzaWNoIHNvICIKKyAgICAgICAic2NobGVjaHQhXG4iKTsKKyAgfQorICBlbHNlIGlmIChkYXRhPT0wKQorICB7CisgICAgd3JpdGUoIkRpZSBGbGFzY2hlIGlzdCBsZWVyLCBEdSBtdWVzc3Rlc3QgZXJzdCBldHdhcyBoaW5laW5mdWVsbGVuLlxuIik7CisgIH0KKyAgZWxzZSBpZiAodGltZSgpPmV4cGlyeSkgCisgIHsKKyAgICB3cml0ZShCUygiSXJnZW5kd2llIHBhc3NpZXJ0IG5pY2h0cy4gSGF0dGVzdCBEdSB2aWVsbGVpY2h0IGRvY2ggbnVyICIKKyAgICAgICJrbGFyZXMgV2Fzc2VyIGFiZ2VmdWVsbHQ/IikpOworICAgIGRhdGE9MDsKKyAgfQorICBlbHNlIHsKKyAgICAvLyBEaWUgU3BlcnJ6ZWl0IG11c3MgaGllciBzZXBhcmF0IGJlcmVjaG5ldCB3ZXJkZW4sIHdlaWwgZWluZQorICAgIC8vIEFucGFzc3VuZyBkZXIgV2lya3VuZ3NkYXVlciBpbSBLcmF1dG1hc3RlciBkYXp1IGZ1ZWhyZW4gd3VlcmRlLAorICAgIC8vIGRhc3MgZXMga2VpbmUgaW5zdGFudGFuIHdpcmtlbmRlbiBUcmFlbmtlIG1laHIgZ2FlYmUuCisgICAgaW50IGJsb2NrdGltZSA9IG1heCg2MCtyYW5kb20oNjApLCBkYXRhW1RfRUZGRUNUX0RVUkFUSU9OXSk7CisgICAgaWYoZW52aXJvbm1lbnQoKS0+Y2hlY2tfYW5kX3VwZGF0ZV90aW1lZF9rZXkoYmxvY2t0aW1lLCBEUklOS19QT1RJT04pPT0tMSkKKyAgICB7CisgICAgICB3cml0ZShCUygiRHUgb2VmZm5lc3QgZGllIEZsYXNjaGUgdW5kIHRyaW5rc3QgaWhyZW4gSW5oYWx0IGF1cy4iKSk7CisgICAgICBzYXkoQlMoUEwtPk5hbWUoV0VSLCAwKSsiIG9lZmZuZXQgZWluZSBGbGFzY2hlIHVuZCB0cmlua3Qgc2llIGluIGVpbmVtICIKKyAgICAgICAgIlNjaGx1Y2sgYXVzLiIpKTsKKyAgICAgIGVmZmVrdCgpOworICAgICAgLy8gVE9ETzogcmVpY2h0IGRhcyBoaWVyIGF1cywgb2RlciBtdXNzIGRhcyBub2NoIGFuIGFuZGVyZW4gU3RlbGxlbiAKKyAgICAgIC8vIGVpbmdlYmF1dCB3ZXJkZW4/CisgICAgICBSZW1vdmVJZCgoeyJ0cmFuayIsImtyYWV1dGVydHJhbmsifSkpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIHRlbGxfb2JqZWN0KGVudmlyb25tZW50KCksIEJTKAorICAgICAgICAiRGVyIGxldHp0ZSBUcmFuayB3aXJrdCBub2NoIGVpbiB3ZW5pZyBuYWNoLiBEdSBrYW5uc3QgRGVpbmVtICIKKyAgICAgICAgIk1hZ2VuIG5pY2h0IHNvIGJhbGQgc2Nob24gZGVuIG5hZWNoc3RlbiB6dW11dGVuLiIpKTsKKyAgICB9CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyBub21hc2sgaW50IEZpbGwob2JqZWN0ICpwbGFudHMpCit7CisgIGlmICghcG9pbnRlcnAocGxhbnRzKSkgcmV0dXJuIC0xOworICBpZiAoZGF0YSkgcmV0dXJuIC0yOyAgLy8gc2Nob24gdm9sbAorICBkYXRhID0gUExBTlRNQVNURVItPm1ha2VfcG90aW9uKHBsYW50cyk7CisgIEFkZElkKCh7InRyYW5rIiwia3JhZXV0ZXJ0cmFuayJ9KSk7CisgIGlmIChtYXBwaW5ncChkYXRhKSkKKyAgeworICAgIC8vIFBmbGFuemVuIHplcnN0b2VydCBkZXIgTWFzdGVyLCB3ZW5ucyBnZWtsYXBwdCBoYXQuCisgICAgZXhwaXJ5PXRpbWUoKStkYXRhW1RfRVhQSVJFXTsKKyAgICBTZXRQcm9wKFBfV0VJR0hULCAzMDApOworICAgIHJldHVybiAxOworICB9CisgIHJldHVybiAtMzsKK30KKwordm9pZCBOb3RpZnlQbGF5ZXJEZWF0aChvYmplY3QgdmljLCBvYmplY3Qga2lsbGVyLCBpbnQgZXhwKQoreworICBjYWxsX291dCgicmVtb3ZlIiwxKTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9rcmFldXRlcnN0b3JlLmMgYi9zdGQva3JhZXV0ZXJzdG9yZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjk5NmExZDYKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQva3JhZXV0ZXJzdG9yZS5jCkBAIC0wLDAgKzEsMzUgQEAKKy8vIChjKSAyMDAzIGJ5IFBhZHJlaWMgKHBhZHJlaWNAbWcubXVkLmRlKQorLy8gU3Rkc3RvcmUgZnVlciBLcmFldXRlcmxhZWRlbiEKKworaW5oZXJpdCAiL3N0ZC9zdG9yZSI7CisKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8YmFuay5oPgorCit2b2lkIGNyZWF0ZSgpCit7CisgICBpZiAob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bMC4uPDNdKQorICAgeworICAgICBzZXRfbmV4dF9yZXNldCgtMSk7CisgICAgIHJldHVybjsKKyAgIH0KKyAgIDo6Y3JlYXRlKCk7CisgICBTZXRQcm9wKFBfTUlOX1NUT0NLLCA1MCk7CisgICAvLyBpbiBqZWRlbSBSZXNldCB2ZXJzY2h3aW5kZW4gbnVyIDIlIGFsbGVyIE9iamVrdGUKKyAgIFNldFByb3AoUF9TVE9SRV9DT05TVU1FLCAyKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkKK3sKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCit2b2lkIHJlc2V0KCkKK3sKKyAgIDo6cmVzZXQoKTsKKyAgIC8vIGRhbWl0IGRpZSBLcmFldXRlciBpbSBMYWRlbiBuaWNodCBzY2hpbW1lbG4sIGdnZi4gdHJvY2tuZW4uLi4KKyAgIG9iamVjdCAqb2JzID0gZmlsdGVyKCBhbGxfaW52ZW50b3J5KCksIGZ1bmN0aW9uIGludCAob2JqZWN0IG9iKSB7CisgICAgICAgICAgICAgICAgICAgcmV0dXJuIG9iLT5UaW1lVG9MaXZlKCk8MzYwMDt9ICk7CisgICBvYnMtPkRyeVBsYW50KDk1KTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2xpZ2h0c291cmNlLmMgYi9zdGQvbGlnaHRzb3VyY2UuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNGIyMjQ1Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2xpZ2h0c291cmNlLmMKQEAgLTAsMCArMSwzMTMgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBsaWdodHNvdXJjZS5jIC0tIHN0YW5kYXJkIGxpZ2h0IHNvdXJjZQorLy8KKy8vICRJZDogbGlnaHRzb3VyY2UuYyA3ODA2IDIwMTEtMDctMTEgMjA6Mjg6MTdaIFplc3N0cmEgJAorCisvLyBzdGQvbGlnaHRzb3VyY2UuYworLy8KKy8vIE9yaWdpbmFsIHZvbiBNaXJpbCBBcHJpbCAnOTIKKy8vIE5ldWZhc3N1bmcgdm9uIFNpciBEZXplbWJlciAnOTIgKCB1bnRlciBCb2luZ3MgQWVnaWRlIDopCisvLyBWZXJzaW9uIDogMS4wCisvLworLy8gQnVnZml4ZXMgdm9uIFNpciBKdW5pICc5MworLy8gVmVyc2lvbiA6IDEuMgorLy8KKy8vIFdpY2h0aWdlIEZ1bmt0aW9uZW4sIGRpZSBtYW4gaW4gY3JlYXRlKCkgYXVmcnVmZW4gc29sbHRlIDoKKy8vCisvLyBTZXR6ZW4gZGVyIEJyZW5uc3RvZmZtZW5nZSA6ICAKKy8vIFNldFByb3AoIFBfRlVFTCwgaW50ICkgICAgICAgaW50IGdpYnQgZGllIEJyZW5uemVpdCBpbiBTZWt1bmRlbiBhbgorLy8KKy8vIFNldHplbiBkZXIgQmVzY2hyZWlidW5nIHdlbm4gT2JqZWt0IGFuZ2V6dWVuZGV0KCBkZWZhdWx0IDogImJyZW5uZW5kIiApIDoKKy8vIFNldFByb3AoIFBfTElHSFRERVNDLCBzdHJpbmcgKQorLy8KKy8vIExlZ3QgZmVzdCwgb2IgZWluIExldWNodG9iamVrdCBuYWNoIHNlaW5lbSBBYmJyZW5uZW4gZGVzdHJ1Y3RlZCB3aXJkCisvLyBTZXRQcm9wKCBQX0RPX0RFU1RSVUNULCBpbnQgKQorLy8KKy8vIExlZ3QgZmVzdCwgd2llIGhlbGwgZGllIEZhY2tlbCBsZXVjaHRldC4KKy8vIFNldFByb3AoIFBfTElHSFQsIGludCApCisvLworLy8gQW5zb25zdGVuIHNpbmQgZGllIFN0YW5kYXJkZnVrdGlvbmVuIHdpZSB6LkIuIFNldFByb3AoIFBfR0VOREVSLCBNQUxFICkgCisvLyBhdWZ6dXJ1ZmVuCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworaW5oZXJpdCAic3RkL3RoaW5nIiA7CisKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisKKyNkZWZpbmUgVFJVRSAgMQorI2RlZmluZSBGQUxTRSAwCisjZGVmaW5lIGJvb2wgIGludAorCisjZGVmaW5lIERGTFRfRlVFTCAgICAgICAyMCAvLyAyMCBTZWt1bmRlbgorI2RlZmluZSBERkxUX0xJR0hUREVTQyAgImJyZW5uZW5kIgorI2RlZmluZSBERkxUX0xJR0hUICAgICAgMgorCisvLyBTbyBlcmdpYnQgc2ljaCBkaWUgTW9lZ2xpY2hrZWl0IHNpZSB3aWVkZXIgYXV6dWZ1ZWxsZW4KKyNkZWZpbmUgQ0FMTF9PVVRfVElNRSAgIDEwMAorCisjdW5kZWYgREVCVUcKKworLy8gVE9ETzogUHJpdmF0ZSB3YWVyIGxhbmdmcmlzdGlnIG5ldHQuLi4KK25vc2F2ZSBpbnQgIGZ1ZWwsIG1heF9mdWVsOworbm9zYXZlIGJvb2wgbGlnaHRlZCA7Citub3NhdmUgaW50ICBjYWxsX3RpbWUgOworCit2b2lkIGNyZWF0ZSgpCit7CisgIHRoaW5nOjpjcmVhdGUoKSA7CisgIAorICBTZXRQcm9wKCBQX05BTUUsICJMaWNodHF1ZWxsZSIgKSA7CisgIFNldFByb3AoIFBfU0hPUlQsICJFaW5lIExpY2h0cXVlbGxlIiApIDsKKyAgU2V0UHJvcCggUF9MT05HLCAiRHUgc2llaHN0IG5pY2h0cyBiZXNvbmRlcmVzLlxuIiApIDsKKyAgU2V0UHJvcCggUF9HRU5ERVIsIEZFTUFMRSApIDsKKyAgU2V0UHJvcCggUF9GVUVMLCBERkxUX0ZVRUwgKSA7CisgIFNldFByb3AoIFBfTElHSFRERVNDLCBERkxUX0xJR0hUREVTQyApIDsKKyAgU2V0UHJvcCggUF9MSUdIVCwgREZMVF9MSUdIVCApOworICBTZXRQcm9wKCBQX0RPX0RFU1RSVUNULCBUUlVFICkgOworICBTZXRQcm9wKCBQX1ZBTFVFLCA1ICkgOworICAKKyAgQWRkSWQoICh7ICJsaWNodHF1ZWxsZSIsICJcbmxpY2h0cXVlbGxlIiB9KSApIDsKKyAgQWRkQ21kKCAoeyAienVlbmRlIiwgInp1ZW5kIiB9KSwgImxpZ2h0IiApOworICBBZGRDbWQoICh7ICJsb2VzY2hlIiwgImxvZXNjaCIgfSksICJleHRpbmd1aXNoIiApOworfQorCit2b2lkIHRlc3RfcmVtb3ZlKCkKK3sgIGlmIChRdWVyeVByb3AoUF9ET19ERVNUUlVDVCkpIHJlbW92ZSgpOyAgfQorCisvKgorICogTGljaHRxdWVsbGUgYW56dWVuZGVuCisgKi8KK2Jvb2wgbGlnaHQoc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nIHRtcCA7CisgIG9iamVjdCBlbnY7CisKKyAgX25vdGlmeV9mYWlsKCAiWnVlbmRlIHdhcyBhbj9cbiIgKSA7CisKKyAgaWYoICghc3RyKSB8fCAoIXNzY2FuZiggc3RyLCAiJXMgYW4iLCB0bXAgKSkgfHwgKCFpZCggdG1wICkpICkKKyAgICByZXR1cm4gRkFMU0UgOworICAKKyAgaWYoIGVudmlyb25tZW50KCkgIT0gUEwgKSAvLyBQbGF5ZXIgaGF0IGVzIG5pY2h0CisgIHsKKyAgICBfbm90aWZ5X2ZhaWwoICJFcnN0bWFsIG11c3N0IER1ICIgKyBuYW1lKCBXRU4sIDAgKSArICIgaGFiZW4uXG4iICkgOworICAgIHJldHVybiBGQUxTRSA7CisgIH0KKyAgCisgIGlmKCBsaWdodGVkICkKKyAgeworICAgIF9ub3RpZnlfZmFpbCggQ0FQKCBuYW1lKCBXRVIsIDEgKSApICsgIiBicmVubnQgc2Nob24uXG4iICkgOworICAgIHJldHVybiBGQUxTRSA7CisgIH0KKworICBpZiggZnVlbCA8PSAwICkKKyAgeworICAgIF9ub3RpZnlfZmFpbCggQ0FQKCBuYW1lKCBXRVIsIDEgKSApICsgIiBpc3QgYWJnZWJyYW5udC5cbiIgKSA7CisgICAgdGVzdF9yZW1vdmUoKSA7CisgICAgcmV0dXJuIEZBTFNFIDsKKyAgfQorCisgIGxpZ2h0ZWQgPSBUUlVFIDsKKyAgZW52PXRoaXNfb2JqZWN0KCk7CisgIHdoaWxlIChvYmplY3RwKGVudj1lbnZpcm9ubWVudChlbnYpKSkKKyAgICAgIC8vIEphLiBNYW4gcnVmdCBkaWUgX3NldF94eHgoKS1GdW5rdGlvbmVuIGVpZ2VudGxpY2ggbmljaHQgZGlyZWt0IGF1Zi4KKyAgICAgIC8vIEFiZXIgZGFzIExpY2h0c3lzdGVtIGlzdCBzY2hvbiAqc28qIHJlY2hlbmludGVuc2l2IHVuZCBnZXJhZGUgZGVyCisgICAgICAvLyBQX0xBU1RfQ09OVEVOVF9DSEFOR0UtQ2FjaGUgd2lyZCAqc28qIG9mdCBiZW5vZXRpZ3QsIGRhc3MgZXMgbWlyCisgICAgICAvLyBkYSB1bSBqZWRlcyBiaXNzY2hlbiBSZWNoZW56ZWl0IGdlaHQuCisgICAgICAvLyBEZXIgWndlY2sgaGVpbGlndCBqYSBiZWthbm50bGljaCBkaWUgTWl0dGVsLiA7LSkKKyAgICAgIC8vCisgICAgICAvLyBUaWFtYWsKKyAgICAgIGVudi0+X3NldF9sYXN0X2NvbnRlbnRfY2hhbmdlKCk7CisgIGNhbGxfdGltZSA9IChmdWVsIDwgQ0FMTF9PVVRfVElNRSk/IGZ1ZWwgOiBDQUxMX09VVF9USU1FIDsKKyAgY2FsbF9vdXQoICJvdXRfb2ZfZnVlbCIsIGNhbGxfdGltZSApIDsKKyAgaWYoIChpbnQpUEwtPlF1ZXJ5UHJvcChQX1BMQVlFUl9MSUdIVCkgPT0gMSApCisgICAgd3JpdGUoICJEdSBrYW5uc3Qgd2llZGVyIGV0d2FzIHNlaGVuLlxuIiApIDsKKyAgZWxzZSB3cml0ZSggIk9rLlxuIiApIDsKKyAgc2F5KChzdHJpbmcpUEwtPk5hbWUoV0VSKQorICAgICAgKyAiIHp1ZW5kZXQgIiArIG5hbWUoIFdFTiwgMCApICsgIiBhbi5cbiIgKSA7CisKKyAgcmV0dXJuIFRSVUUgOworfQorCitib29sIGV4dGluZ3Vpc2goc3RyaW5nIHN0cikKK3sKKyAgaW50IHRpOworICBvYmplY3QgZW52OworCisgIF9ub3RpZnlfZmFpbCggIldlbGNoZSBMaWNodHF1ZWxsZSBtb2VjaHRlc3QgRHUgbG9lc2NoZW4/XG4iICkgOworCisgIGlmKCAoIXN0cikgfHwgKCFpZCggc3RyICkpICkKKyAgICByZXR1cm4gRkFMU0UgOworICAKKyAgaWYoICFsaWdodGVkICkKKyAgeworICAgIF9ub3RpZnlfZmFpbCggQ0FQKCBuYW1lKCBXRVIsIDEgKSApICsgIiBicmVubnQgZ2FyIG5pY2h0LlxuIiApIDsKKyAgICByZXR1cm4gRkFMU0UgOworICB9CisKKyAgaWYoIGVudmlyb25tZW50KCkgIT0gUEwgKQorICB7CisgICAgX25vdGlmeV9mYWlsKCAiRXJzdG1hbCBtdXNzdCBEdSAiICsgbmFtZSggV0VOLCAwICkgKyAiIGhhYmVuLlxuIiApIDsKKyAgICByZXR1cm4gRkFMU0UgOworICB9CisKKyAgaWYoICggdGkgPSByZW1vdmVfY2FsbF9vdXQoICJvdXRfb2ZfZnVlbCIgKSApID09IC0xICkKKyAgICB0aSA9IDAgOworCisgIGZ1ZWwgLT0gKGNhbGxfdGltZSAtIHRpKSA7CisgIGxpZ2h0ZWQgPSBGQUxTRSA7CisgIGVudj10aGlzX29iamVjdCgpOworICB3aGlsZSAob2JqZWN0cChlbnY9ZW52aXJvbm1lbnQoZW52KSkpCisgICAgICAvLyBKYS4gTWFuIHJ1ZnQgZGllIF9zZXRfeHh4KCktRnVua3Rpb25lbiBlaWdlbnRsaWNoIG5pY2h0IGRpcmVrdCBhdWYuCisgICAgICAvLyBBYmVyIGRhcyBMaWNodHN5c3RlbSBpc3Qgc2Nob24gKnNvKiByZWNoZW5pbnRlbnNpdiB1bmQgZ2VyYWRlIGRlcgorICAgICAgLy8gUF9MQVNUX0NPTlRFTlRfQ0hBTkdFLUNhY2hlIHdpcmQgKnNvKiBvZnQgYmVub2V0aWd0LCBkYXNzIGVzIG1pcgorICAgICAgLy8gZGEgdW0gamVkZXMgYmlzc2NoZW4gUmVjaGVuemVpdCBnZWh0LgorICAgICAgLy8gRGVyIFp3ZWNrIGhlaWxpZ3QgamEgYmVrYW5udGxpY2ggZGllIE1pdHRlbC4gOy0pCisgICAgICAvLworICAgICAgLy8gVGlhbWFrCisgICAgICBlbnYtPl9zZXRfbGFzdF9jb250ZW50X2NoYW5nZSgpOworICBpZiAoIHRoaXNfcGxheWVyKCktPlF1ZXJ5UHJvcChQX1BMQVlFUl9MSUdIVCkgPT0gMCApCisgIHsKKyAgICB3cml0ZSggIkVzIHdpcmQgZHVua2VsLlxuIiApIDsKKyAgICBzYXkoKHN0cmluZylQTC0+TmFtZShXRVIpIAorCSsgIiBtYWNodCBkYXMgTGljaHQgYXVzLlxuIiApIDsKKyAgfQorICBlbHNlCisgIHsKKyAgICB3cml0ZSggIk9rLlxuIiApIDsKKyAgICBzYXkoKHN0cmluZylQTC0+TmFtZShXRVIpCisJKyAiIGxvZXNjaHQgIiArIG5hbWUoIFdFTiwgMCApICsgIiBhdXMuXG4iICkgOworICB9CisKKyAgaWYoIGZ1ZWwgPD0gMCApIHRlc3RfcmVtb3ZlKCkgOworICByZXR1cm4gVFJVRSA7Cit9CisKK2Jvb2wgdW5saWdodCgpCit7CisgIGludCB0aTsKKyAgb2JqZWN0IGVudjsKKworICBpZiggIWxpZ2h0ZWQgKQorICAgIHJldHVybiBGQUxTRSA7CisKKyAgaWYoICggdGkgPSByZW1vdmVfY2FsbF9vdXQoICJvdXRfb2ZfZnVlbCIgKSApID09IC0xICkKKyAgICB0aSA9IDAgOworCisgIGZ1ZWwgLT0gKGNhbGxfdGltZSAtIHRpKSA7CisgIGxpZ2h0ZWQgPSBGQUxTRSA7CisgIGVudj10aGlzX29iamVjdCgpOworICB3aGlsZSAob2JqZWN0cChlbnY9ZW52aXJvbm1lbnQoZW52KSkpCisgICAgICAvLyBLb21tZW50YXIgc2llaGUgb2JlbiA7XikKKyAgICAgIGVudi0+X3NldF9sYXN0X2NvbnRlbnRfY2hhbmdlKCk7CisgIGlmKCBmdWVsIDw9IDAgKSB0ZXN0X3JlbW92ZSgpIDsKKyAgcmV0dXJuIFRSVUUgOworfQorCit2b2lkIG91dF9vZl9mdWVsKCkKK3sKKyAgaW50IGk7CisgIG9iamVjdCAqaW52LCBlbnY7CisgIAorICBmdWVsIC09IGNhbGxfdGltZSA7CisKKyAgaWYgKGZ1ZWw+MCkgeworICAgIGNhbGxfb3V0KCAib3V0X29mX2Z1ZWwiLCBjYWxsX3RpbWUgKSA7CisgICAgcmV0dXJuIDsKKyAgfQorICBsaWdodGVkPUZBTFNFOworICBlbnY9dGhpc19vYmplY3QoKTsKKyAgd2hpbGUgKG9iamVjdHAoZW52PWVudmlyb25tZW50KGVudikpKQorICAgICAgLy8gSW1tZXIgbm9jaCBuaWNodCB3aXJrbGljaCBzYXViZXIuIEFiZXIgQmVncnVlbmR1bmcgc2llaGUgb2Jlbi4KKyAgICAgIGVudi0+X3NldF9sYXN0X2NvbnRlbnRfY2hhbmdlKCk7CisKKyAgaWYgKGVudmlyb25tZW50KCkpCisgIHsKKyAgICBpZiAoIGxpdmluZyhlbnZpcm9ubWVudCgpKSAmJiBlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSApCisgICAgeworICAgICAgaW52PSh1c2VycygpICYgYWxsX2ludmVudG9yeShlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSkpLSh7IGVudmlyb25tZW50KCkgfSk7CisgICAgICBmb3IgKGk9c2l6ZW9mKGludiktMTsgaT49MDsgaS0tKSAKKyAgICAgICAgaWYgKGludltpXS0+UXVlcnlQcm9wKFBfUExBWUVSX0xJR0hUKTw9MCkKKyAgICAgICAgICB0ZWxsX29iamVjdChpbnZbaV0sICJFcyB3aXJkIGR1bmtlbCBhbHMgIiArIGVudmlyb25tZW50KCktPm5hbWUoV0VTU0VOKSArCisgICAgICAgICAgICAiICIgKyBRdWVyeVByb3AoUF9OQU1FKSArICIgZXJsaXNjaHQuXG4iICkgOworICAgICAgICBlbHNlIHRlbGxfb2JqZWN0KGludltpXSwgQ0FQKCBuYW1lKCBXRVIsIDAgKSApICsgIiBlcmxpc2NodC5cbiIgKSA7CisgICAgICBpZiAoZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfUExBWUVSX0xJR0hUKTw9MCkKKyAgICAgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgCisgICAgICAgICAgQ0FQKCBuYW1lKCBXRVIsIDEgKSApICsgIiBlcmxpc2NodCB1bmQgZXMgd2lyZCBkdW5rZWwuXG4iICkgOworICAgICAgZWxzZSB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBDQVAoIG5hbWUoIFdFUiwgMSApICkgKyAiIGVybGlzY2h0LlxuIiApIDsgICAgCisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICBpbnY9KHVzZXJzKCkgJiBhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpKTsKKyAgICAgIGZvciAoaT1zaXplb2YoaW52KS0xOyBpPj0wOyBpLS0pIAorICAgICAgICBpZiAoaW52W2ldLT5RdWVyeVByb3AoUF9QTEFZRVJfTElHSFQpPD0wKQorICAgICAgICAgIHRlbGxfb2JqZWN0KGludltpXSwgIkVzIHdpcmQgZHVua2VsIGFscyAiICsgbmFtZShXRVIsMSkKKyAgICAgICAgICArICIgZXJsaXNjaHQuXG4iICkgOworICAgICAgICBlbHNlIHRlbGxfb2JqZWN0KGludltpXSwgQ0FQKCBuYW1lKCBXRVIsIDAgKSApICsgIiBlcmxpc2NodC5cbiIgKSA7CisgICAgfQorICB9ICAKKyAgdGVzdF9yZW1vdmUoKSA7Cit9CisKKy8vIEJyZW5uc3RvZmYgbmFjaGZ1ZWxsZW4KK3ZvaWQgQWRkRnVlbChpbnQgZikKK3sgIGZ1ZWwgKz0gZiA7ICB9CisKKy8vIFByb3BlcnR5IC0gRnVua3Rpb25lbgorCitzdGF0aWMgdm9pZCBfc2V0X2xpZ2h0ZWQoYm9vbCBsKQoreyAgbGlnaHRlZCA9IGwgOyAgfQorCitib29sIF9xdWVyeV9saWdodGVkKCkKK3sgIHJldHVybiBsaWdodGVkIDsgIH0KKworc3RhdGljIHZvaWQgX3NldF9mdWVsKGludCBmKQoreworICBpZiAoZj5tYXhfZnVlbCkgbWF4X2Z1ZWw9ZjsKKyAgZnVlbCA9IGYgOworfQorCitzdGF0aWMgaW50IF9xdWVyeV9mdWVsKCkKK3sKKyAgaW50IHRtcDsKKworICBpZiAoKHRtcD1maW5kX2NhbGxfb3V0KCJvdXRfb2ZfZnVlbCIpKT49MCkKKyAgICByZXR1cm4gZnVlbC1jYWxsX3RpbWUrdG1wOworICBlbHNlIHJldHVybiBmdWVsOworfQorCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9saWdodGRlc2MoKQoreworICBzdHJpbmcgKnRtcDsKKyAgaW50IG4saTsKKyAgCisgIHRtcD1RdWVyeShQX0xJR0hUREVTQyk7CisgIGlmICghcG9pbnRlcnAodG1wKSkgcmV0dXJuIChzdHJpbmcpdG1wOworICBuPXNpemVvZih0bXApOworICBpPW4qX3F1ZXJ5X2Z1ZWwoKS9tYXhfZnVlbDsKKyAgaWYgKGk+PW4pIGk9bi0xOworICByZXR1cm4gdG1wW2ldOworfQorCitzdGF0aWMgaW50IF9xdWVyeV9saWdodCgpCit7ICAgcmV0dXJuIChsaWdodGVkID8gUXVlcnkoUF9MSUdIVCkgOiAwKTsgIH0KKworLyoKKyAqIHNob3J0KCkgdWViZXJsYWRlbgorICovCitzdHJpbmcgc2hvcnQoKQoreworICBzdHJpbmcgczsKKyAgc3RyaW5nIGRlc2M7CisKKyAgaWYoIShzPVF1ZXJ5UHJvcChQX1NIT1JUKSkpCisgICAgcmV0dXJuIDA7CisgIHJldHVybiBzICsgKCAobGlnaHRlZCk/ICgiICgiK1F1ZXJ5UHJvcCggUF9MSUdIVERFU0MgKSArIikuXG4iKSA6ICIuXG4iICk7Cit9CmRpZmYgLS1naXQgYS9zdGQvbGl2aW5nL2F0dHJpYnV0ZXMuYyBiL3N0ZC9saXZpbmcvYXR0cmlidXRlcy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkwMDI3YTQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL2F0dHJpYnV0ZXMuYwpAQCAtMCwwICsxLDY3MSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9hdHRyaWJ1dGVzLmMgLS0gYXR0cmlidXRlcyBmb3IgbGl2aW5nIG9iamVjdHMKKy8vCisvLyAkSWQ6IGF0dHJpYnV0ZXMuYyA4Mzc1IDIwMTMtMDItMTIgMjE6NTI6NThaIFplc3N0cmEgJAorCisjaW5jbHVkZSA8c3lzX2RlYnVnLmg+CisKKy8vIGF0dHJpYnV0ZSBoYW5kbGluZworLy8KKy8vICAgZmlsdGVyX2xkZmllZDogc3RyLCBkZXgsIGNvbiwgaW50CisvLworLy8gSW4gZGVuIEF0dHJpYnV0ZW4gdW5kIEFiaWxpdGVzIHdlcmRlbiBSYXNzZW5zcHppZmlzY2hlIHVuZCBlcndvcmJlbmUKKy8vIEZhZWhpZ2tlaXRlbiAobWl0IGF1dG9sb2FkLUVpZ2Vuc2NoYWZ0KSBhYmdlcHNlaWNoZXJ0LgorLy8KKy8vIEZ1bmt0aW9uZW46CisvLyAgIFNldEF0dHJpYnV0ZSggYXR0ciwgdmFsICkgKEVyemV1Z2UgdW5kKSBzZXR6ZSBkYXMgQXR0cmlidXQgYXVmIHZhbC4KKy8vICAgUXVlcnlBdHRyaWJ1dGUoIGF0dHIgKSAgICBHZWJlIGRlbiBXZXJ0IGRlcyBBdHRyaWJ1dGVzIHp1cnVlY2suCisvLworLy8gICBXZW5uIGVpbiBPYmpla3QgZWluZSBGdW5rdGlvbiBfZmlsdGVyYXR0cl88bmFtZT4gYmVpdHp0LCB3aXJkIGJlaW0gU2V0emVuCisvLyAgIGRlcyBBdHRyaWJ1dGVzIDxuYW1lPiwgZGVyIHZvcmdlc2NobGFnZW5lIFdlcnQgdWViZXJnZWJlbiB1bmQgZGVyIHZvbgorLy8gICBkaWVzZXIgRnVua3Rpb24genVydWVja2dlZ2ViZW5lIGdlc2V0enQuIChmdWVyIHVlYmVycHJ1ZWZ1bmdzendlY2tlKQorLy8gICBHbGVpY2hlcyBnaWx0IGZ1ZXIgX2ZpbHRlcmFiaWxfPG5hbWU+LgorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGF0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvZ21jcC5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCittYXBwaW5nIGF0dHJpYnV0ZXM7IC8vIERpZXMgc2luZCBkaWUgbWl0IFpUcyB2ZXJhZW5kZXJiYXJlbiBBdHRyaWJ1dGUKK21hcHBpbmcgYXR0cmlidXRlc19tb2RpZmllcjsgLy8gTW9kaWZpZXIgc29sbGVuIGdlc3BlaWNoZXJ0IHdlcmRlbgorbm9zYXZlIG1peGVkKiBhdHRyaWJ1dGVzX3RpbWVkX21vZHM7IC8vUF9USU1FRF9BVFRSX01PRAorbm9zYXZlIG1hcHBpbmcgYXR0cmlidXRlc19vZmZzZXRzOyAvLyBPZmZzZXRzIE5JQ0hUIHNwZWljaGVybiEKK25vc2F2ZSBtYXBwaW5nIHVzZWRfYXR0cmlidXRlc19vZmZzZXRzOyAvLyBadXIgQmVzY2hsZXVuaWd1bmcgZGVyIEJlcmVjaG51bmcKK25vc2F2ZSBvYmplY3QqIGFsbF9tb2RpZmllcnM7IC8vIG9iamVrdGUgbWl0IFBfWC9NX0FUVFJfTU9ELCBQX1gvTV9IRUFMVEhfTU9ECitub3NhdmUgb2JqZWN0KiBpbnZhbGlkX21vZGlmaWVyczsgLy8gb2JqZWt0ZSB3ZWxjaGUgZGFzIGxpbWl0IHVlYmVyc2NocmVpdGVuCitub3NhdmUgaW50IGN1bXVsYXRpdmVfbW9kOyAvLyBiaWxhbnogZGVyIFBfWC9NX0FUVFJfTU9ECitub3NhdmUgaW50IGhwX29mZjsKK25vc2F2ZSBpbnQgc3Bfb2ZmOworCisKK25vbWFzayBwdWJsaWMgaW50IFNldFRpbWVkQXR0ck1vZGlmaWVyKHN0cmluZyBrZXksIG1hcHBpbmcgbW9kaWZpZXIsIAorICAgIGludCBvdXRkYXRlZCwgb2JqZWN0IGRlcGVuZGVudCwgbWl4ZWQgbm90aWZ5KSB7CisgIGlmKCFrZXkgfHwga2V5PT0iIiB8fCAhbW9kaWZpZXIgfHwgKG91dGRhdGVkPjAgJiYgb3V0ZGF0ZWQ8dGltZSgpKSB8fCAKKyAgICAgIChub3RpZnkgJiYgIXN0cmluZ3Aobm90aWZ5KSAmJiAhb2JqZWN0cChub3RpZnkpKSApIHsKKyAgICByZXR1cm4gVEFUVFJfSU5WQUxJRF9BUkdTOworICB9CisgIAorICAKKyAgaWYobWVtYmVyKGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXSxrZXkpKSB7CisgICAgLy8gY2hhbmdlIGVudHJ5CisgICAgYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdW2tleSxUQVRUUl9NT0RdPW1vZGlmaWVyOworICAgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXVtrZXksVEFUVFJfT1VUREFURURdPW91dGRhdGVkOworICAgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXVtrZXksVEFUVFJfREVQRU5ERU5UXT1kZXBlbmRlbnQ7CisgICAgYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdW2tleSxUQVRUUl9OT1RJRlldPW5vdGlmeTsKKyAgfQorICBlbHNlIHsKKyAgICAvLyBhZGQgZW50cnkKKyAgICBhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU10rPShba2V5Om1vZGlmaWVyO291dGRhdGVkO2RlcGVuZGVudDtub3RpZnldKTsKKyAgfQorICAKKyAgLy8gYWRkIG91dGRhdGUKKyAgaWYob3V0ZGF0ZWQ+MCAmJiBtZW1iZXIoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX09VVERBVEVdLG91dGRhdGVkKT09LTEpCisgIHsKKyAgICBhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfT1VUREFURV0rPSh7b3V0ZGF0ZWR9KTsKKyAgICBhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfT1VUREFURV09CisgICAgICBzb3J0X2FycmF5KGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9PVVREQVRFXSwjJzwpOworICB9CisgIAorICAvLyBhZGQgZGVwZW5kZW50CisgIGlmKG9iamVjdHAoZGVwZW5kZW50KSkKKyAgeworICAJaWYobWVtYmVyKGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9ERVBFTkRFTlRTXSxrZXkpKQorICAJeworCSAgYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0RFUEVOREVOVFNdW2tleV09ZGVwZW5kZW50OworICAJfQorICAJZWxzZQorICAJeworICAgICAgICAgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9ERVBFTkRFTlRTXSs9KFtrZXk6ZGVwZW5kZW50XSk7CisgIAl9CisgIH0KKyAgZWxzZQorICB7CisgIAkvLyByZW1vdmUgcHJldmlvdXNseSBzZXQgZGVwZW5kZW50CisgIAlpZihtZW1iZXIoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0RFUEVOREVOVFNdLGtleSkpCisgIAl7CisJICBhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfREVQRU5ERU5UU10tPShba2V5XSk7CisgIAl9CisgIH0KKyAgCisgIFVwZGF0ZUF0dHJpYnV0ZXMoKTsKKworICByZXR1cm4gVEFUVFJfT0s7Cit9CisKK25vbWFzayBwdWJsaWMgbWFwcGluZyBRdWVyeVRpbWVkQXR0ck1vZGlmaWVyKHN0cmluZyBrZXkpCit7CisgIGludCBvdXRkYXRlZDsKKyAgb2JqZWN0IGRlcGVuZGVudDsKKyAgbWl4ZWQgbm90aWZ5OworICBtYXBwaW5nIG1vZDsKKyAgCisgIGlmKCFrZXkgfHwga2V5PT0iIikKKyAgeworICAgIHJldHVybiAoW10pOworICB9CisKKyAgaWYoIW1lbWJlcihhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU10sa2V5KSkKKyAgeyAKKyAgICByZXR1cm4gKFtdKTsKKyAgfQorCisgIG1vZD1kZWVwX2NvcHkoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdW2tleSxUQVRUUl9NT0RdKTsKKyAgb3V0ZGF0ZWQ9YXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdW2tleSxUQVRUUl9PVVREQVRFRF07CisgIGRlcGVuZGVudD1hdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5LFRBVFRSX0RFUEVOREVOVF07CisgIG5vdGlmeT1hdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5LFRBVFRSX05PVElGWV07CisgIAorICByZXR1cm4gKFtrZXk6bW9kO291dGRhdGVkO2RlcGVuZGVudDtub3RpZnkgXSk7Cit9CisKK25vbWFzayBwdWJsaWMgaW50IERlbGV0ZVRpbWVkQXR0ck1vZGlmaWVyKHN0cmluZyBrZXkpCit7CisgIGlmKCFrZXkgfHwga2V5PT0iIikKKyAgeworICAgIHJldHVybiBUQVRUUl9JTlZBTElEX0FSR1M7CisgIH0KKworICBpZighbWVtYmVyKGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXSxrZXkpKQorICB7IAorICAgIHJldHVybiBUQVRUUl9OT19TVUNIX01PRElGSUVSOworICB9CisgIAorICBhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfREVQRU5ERU5UU10tPShba2V5XSk7CisgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXS09KFtrZXldKTsKKyAgVXBkYXRlQXR0cmlidXRlcygpOworICAKKyAgcmV0dXJuIFRBVFRSX09LOworfQorCitub21hc2sgcHJvdGVjdGVkIHZvaWQgYXR0cmlidXRlX2hiKCkKK3sKKyAgaW50IG5vdyxpLGssdXBkYXRlLG91dGRhdGVkOworICBzdHJpbmcqIGtleXM7CisgIG1hcHBpbmcgdG9ub3RpZnk7CisJCisgIC8vIGluaXRpYWxpemUKKyAgbm93PXRpbWUoKTsKKyAgdG9ub3RpZnk9KFtdKTsKKworICBrZXlzPW1faW5kaWNlcyhhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU10pOworICAKKyAgLy8gZGVsZXRlIG91dGRhdGVkIAorICBmb3IoaT1zaXplb2YoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX09VVERBVEVdKS0xO2k+PTA7aS0tKQorICB7CisgIAlvdXRkYXRlZD1hdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfT1VUREFURV1baV07CisgIAlpZihvdXRkYXRlZD5ub3cpCisgIAl7CisgIAkgIGJyZWFrOworICAJfQorICAJCisgIAlmb3Ioaz1zaXplb2Yoa2V5cyktMTtrPj0wO2stLSkKKyAgCXsKKyAgCSAgaWYoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdW2tleXNba10sVEFUVFJfT1VUREFURURdPT1vdXRkYXRlZCkKKyAgCSAgeworICAJICAgIC8vIGJlaSBmZWhsZW5kZW0gbm90aWZpZXIgd3VyZGUgZGFzIHp1bSB2ZXJoYWVuZ25pcworICAJICAgIC8vIGRhbmsgYW4gZ2xvaW5zb24KKyAgCSAgICAvKgorICAJICAgIGlmKG9iamVjdHAoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdW2tleXNba10sVEFUVFJfTk9USUZZXSkpCisgIAkgICAgeworICAJICAgICovCisgIAkgICAgdG9ub3RpZnkrPShba2V5c1trXTphdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5c1trXSxUQVRUUl9OT1RJRlldXSk7CisgIAkgICAgLy99CisgIAkgICAgCisJICAgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9ERVBFTkRFTlRTXS09KFtrZXlzW2tdXSk7CisgCSAgICBhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU10tPShba2V5c1trXV0pOworICAJICAgIGtleXMtPSh7a2V5c1trXX0pOworICAJICB9CisgIAl9CisgIAkKKyAgCWF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9PVVREQVRFXS09KHtvdXRkYXRlZH0pOworICB9CisgIAorICAvLyBkZWxldGUgZGVwZW5kaW5nCisgIGtleXM9bV9pbmRpY2VzKGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9ERVBFTkRFTlRTXSk7CisgIGZvcihpPXNpemVvZihrZXlzKS0xO2k+PTA7aS0tKQorICB7CisgIAlpZighb2JqZWN0cChhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfREVQRU5ERU5UU11ba2V5c1tpXV0pKQorICAJeworICAJICAgIC8vIHNpZWhlIG9iZW4KKyAgCSAgICAvKgorICAJICAgIGlmKG9iamVjdHAoYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0VOVFJJRVNdW2tleXNbaV0sVEFUVFJfTk9USUZZXSkpCisgIAkgICAgeworICAJICAgICovCisgIAkgICAgdG9ub3RpZnkrPShba2V5c1tpXTphdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11ba2V5c1tpXSxUQVRUUl9OT1RJRlldXSk7CisgIAkgICAgLy99CisKKwkgICAgYXR0cmlidXRlc190aW1lZF9tb2RzW1RBVFRSX0RFUEVOREVOVFNdLT0oW2tleXNbaV1dKTsKKyAJICAgIGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXS09KFtrZXlzW2ldXSk7CisgIAkgICAga2V5cy09KHtrZXlzW2ldfSk7CisgIAl9CisgIH0KKyAgCisgIAorICAvLyB1cGRhdGUKKyAgaWYoc2l6ZW9mKHRvbm90aWZ5KSkKKyAgeworICAgIFVwZGF0ZUF0dHJpYnV0ZXMoKTsKKyAgICBjYWxsX291dCgjJ25vdGlmeUV4cGlyZWRNb2RpZmllcnMsMCx0b25vdGlmeSk7CisgIH0KK30KKworbm9tYXNrIHByb3RlY3RlZCB2b2lkIG5vdGlmeUV4cGlyZWRNb2RpZmllcnMobWFwcGluZyBub3RzKQoreworICBpbnQgaTsKKyAgc3RyaW5nKiBrZXlzOworICB3aGlsZShyZW1vdmVfY2FsbF9vdXQoIydub3RpZnlFeHBpcmVkTW9kaWZpZXJzKSE9LTEpOworICAKKyAgaWYoIW5vdHMpCisgIHsKKyAgICByZXR1cm47CisgIH0KKyAgCisgIGtleXM9bV9pbmRpY2VzKG5vdHMpOworICBmb3IoaT1zaXplb2Yobm90cyktMTtpPj0wO2ktLSkKKyAgeworICAJaWYobm90c1trZXlzW2ldXSAmJiAKKwkgICAgKCBvYmplY3RwKG5vdHNba2V5c1tpXV0pfHxzdHJpbmdwKG5vdHNba2V5c1tpXV0pICkgKQorICAJeworICAJICAgY2FsbF9vdGhlcihub3RzW2tleXNbaV1dLCJOb3RpZnlUaW1lZEF0dHJNb2RFeHBpcmVkIixrZXlzW2ldKTsKKyAgCX0KKyAgfQorfQorCisKKy8vIGludmFsaWRlIG1vZGlmaWVyIGJlbmFjaHJpY2h0aWdlbgorbm9tYXNrIHByb3RlY3RlZCB2b2lkIG5vdGlmeUludmFsaWRNb2RpZmllcnMoKSB7CisKKyAgd2hpbGUocmVtb3ZlX2NhbGxfb3V0KCMnbm90aWZ5SW52YWxpZE1vZGlmaWVycykhPS0xKTsKKyAgCisgIGlmKCFpbnZhbGlkX21vZGlmaWVycykgeworICAgIGludmFsaWRfbW9kaWZpZXJzPSh7fSk7CisgIH0KKyAgCisgIGNhbGxfb3RoZXIoaW52YWxpZF9tb2RpZmllcnMsIk5vdGlmeVhNQXR0ck1vZExpbWl0VmlvbGF0aW9uIik7CisKK30KKworCisvLyB3ZWxjaGUgTW9kaWZpZXIgLyBtb2RpZi4gT2JqZWt0ZSB3aXJrZW4gbnVuPworcHJvdGVjdGVkIG5vbWFzayB2b2lkIGNhbGN1bGF0ZV92YWxpZF9tb2RpZmllcnMoKSB7CisgIGNsb3N1cmUgcXA7CisgIG1hcHBpbmcgcmVzOwkKKyAgc3RyaW5nIGtleTsJCisgIGludCB3ZXJ0OworICAvLyBVbnRlcnNjaGVpZHVuZyBCb251cyA8LT4gTWFsdXMsIHdlaWwgZGVyIE1hbHVzIHZvbGwgZWluZ2VoZW4gc29sbAkKKyAgaW50IGhwX21hbHVzLCBzcF9tYWx1czsKKyAKKyAgdXNlZF9hdHRyaWJ1dGVzX29mZnNldHM9KFtdKTsKKyAgY3VtdWxhdGl2ZV9tb2Q9MDsKKyAgaHBfb2ZmPXNwX29mZj0wOworICBpbnZhbGlkX21vZGlmaWVycz0oe30pOworCisgIC8vIHJhc3NlbnNwZXppZmlzY2hlIGJvbmkgUF9BVFRSSUJVVEVTX09GRlNFVFMgIAorICBpZiAoIG1hcHBpbmdwKGF0dHJpYnV0ZXNfb2Zmc2V0cykgKQorICAgIHVzZWRfYXR0cmlidXRlc19vZmZzZXRzKz1hdHRyaWJ1dGVzX29mZnNldHM7CisKKyAgaWYgKCFwb2ludGVycChhbGxfbW9kaWZpZXJzKSB8fCAhc2l6ZW9mKGFsbF9tb2RpZmllcnMpKSB7CisgICAgLy8gaW4gZGllc2VtIEZhbGwga29lbm5lbiB3aXIgaGllciBkaXJla3QgbWl0IGRpZXNlciBGdW5rdGlvbiBTY2hsdXNzCisgICAgLy8gbWFjaGVuLiA7LSkKKyAgICByZXR1cm47CisgIH0KKyAgZWxzZQorICAgIGFsbF9tb2RpZmllcnMtPSh7MH0pOyAvL3plcnN0b2VydGUgT2JqZWt0ZSByYXVzd2VyZmVuLgorICAgIAorICAvLyBlaW5tYWwgdWViZXIgYWxsZSBtb2RpZml6aWVyZW5kZW4gT2JqZWt0IGl0ZXJpZXJlbiB1bmQgYXVmYWRkaWVyZW4KKyAgZm9yZWFjaChvYmplY3Qgb2I6IGFsbF9tb2RpZmllcnMpIHsKKyAgICBxcCA9IHN5bWJvbF9mdW5jdGlvbigiUXVlcnlQcm9wIixvYik7CisgCisgICAgaWYgKCFvYmplY3RwKG9iKSB8fCBlbnZpcm9ubWVudChvYikhPXRoaXNfb2JqZWN0KCkpIHsKKyAgICAgIGFsbF9tb2RpZmllcnMtPSh7b2J9KTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAJCQorICAgIC8vIGV4dC4gQXR0cmlidXQtTW9kaWZpZXIKKyAgICBpZiAoIG1hcHBpbmdwKHJlcz1mdW5jYWxsKHFwLFBfWF9BVFRSX01PRCkpICkgewkJCisgICAgICBmb3JlYWNoKGtleSwgd2VydDogcmVzKSB7CisgICAgICAgIGN1bXVsYXRpdmVfbW9kKz13ZXJ0OworICAgICAgfQorICAgIH0KKworICAgIC8vIG1hZ2ljIEF0dHJpYnV0LU1vZGlmaWVyCisgICAgaWYgKCBtYXBwaW5ncChyZXM9ZnVuY2FsbChxcCxQX01fQVRUUl9NT0QpKQorICAgICAgICAmJiAoIGZ1bmNhbGwocXAsUF9XT1JOKQorICAgICAgICAgICAgfHwgZnVuY2FsbChxcCxQX1dJRUxERUQpICkgKSB7CQkKKyAgICAgIGZvcmVhY2goa2V5LCB3ZXJ0OiByZXMpIHsKKyAgICAgICAgY3VtdWxhdGl2ZV9tb2QrPXdlcnQ7CisgICAgICB9CisgICAgfQorICAgIC8vIE1hZ2ljIEhlYWx0aC1Nb2RpZmllciAJCQorICAgIGlmICggbWFwcGluZ3AocmVzPWZ1bmNhbGwocXAsUF9NX0hFQUxUSF9NT0QpKQorICAgICAgICAmJiAoIGZ1bmNhbGwocXAsUF9XT1JOKQorICAgICAgICAgICAgfHwgZnVuY2FsbChxcCxQX1dJRUxERUQpICkgKSB7CisgICAgICBpZiAocmVzW1BfSFBdIDwgMCkKKyAgICAgICAgaHBfbWFsdXMgKz0gcmVzW1BfSFBdOworICAgICAgZWxzZQorICAgICAgICBocF9vZmYrPXJlc1tQX0hQXTsKKworICAgICAgaWYgKHJlc1tQX1NQXSA8IDApCisgICAgICAgIHNwX21hbHVzICs9IHJlc1tQX1NQXTsKKyAgICAgIGVsc2UKKyAgICAgICAgc3Bfb2ZmKz1yZXNbUF9TUF07CisgICAgICB9CisJICAgICAgCisgICAgLy8gZXh0ZXJuYWwgSGVhbHRoIE1vZGlmaWVyCisgICAgaWYgKCBtYXBwaW5ncChyZXM9ZnVuY2FsbChxcCxQX1hfSEVBTFRIX01PRCkpICkgeworICAgICAgaWYgKHJlc1tQX0hQXSA8IDApCisgICAgICAgIGhwX21hbHVzICs9IHJlc1tQX0hQXTsKKyAgICAgIGVsc2UKKyAgICAgICAgaHBfb2ZmKz1yZXNbUF9IUF07CisKKyAgICAgIGlmIChyZXNbUF9TUF0gPCAwKQorICAgICAgICBzcF9tYWx1cyArPSByZXNbUF9TUF07CisgICAgICBlbHNlCisgICAgICAgIHNwX29mZis9cmVzW1BfU1BdOwkgICAgCisgICAgfQkKKyAgCisgIH0gLy8gRW5kZSAxLiBmb3JlYWNoKCkKKyAgCisgCisgIC8vIHVuZCBub2NobWFsLCBzb3ZpZWxlIE9iamVrdCB3aWVkZXIgcmF1c3NjaG1laXNzZW4sIGJpcyBkYXMgTGltaXQgd2llZGVyCisgIC8vIHVudGVyc2Nocml0dGVuIHdpcmQuIChWZXJiZXNzZXJ1bmdzdm9yc2NobGFlZ2UgZXJ3dWVuc2NodC4pIDotKAorICBmb3JlYWNoKG9iamVjdCBvYjogYWxsX21vZGlmaWVycykgeworCisgICAgcXAgPSBzeW1ib2xfZnVuY3Rpb24oIlF1ZXJ5UHJvcCIsb2IpOworIAorICAgIGlmICggbWFwcGluZ3AocmVzPWZ1bmNhbGwocXAsUF9YX0FUVFJfTU9EKSkgKSB7CisgICAgICBpZihjdW11bGF0aXZlX21vZD5DVU1VTEFUSVZFX0FUVFJfTElNSVQpIHsgCisgICAgICAgIGludmFsaWRfbW9kaWZpZXJzKz0oe29ifSk7CSAgCisJZm9yZWFjaChrZXksIHdlcnQ6IHJlcykgeworICAgICAgICAgIGN1bXVsYXRpdmVfbW9kLT13ZXJ0OworICAgICAgICB9CisgICAgICB9CisgICAgICBlbHNlIHsKKyAgICAgICAgYWRkX29mZnNldHMocmVzKTsKKyAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoIG1hcHBpbmdwKHJlcz1mdW5jYWxsKHFwLFBfTV9BVFRSX01PRCkpCisgICAgICAgICYmICggZnVuY2FsbChxcCxQX1dPUk4pCisgICAgICAgICAgICB8fCBmdW5jYWxsKHFwLFBfV0lFTERFRCkgKSApIHsKKyAgICAgIGlmKGN1bXVsYXRpdmVfbW9kPkNVTVVMQVRJVkVfQVRUUl9MSU1JVCkgeyAgICAgCisgICAgICAgIGlmKG1lbWJlcihpbnZhbGlkX21vZGlmaWVycyxvYik9PS0xKSB7CisgICAgICAgICAgaW52YWxpZF9tb2RpZmllcnMrPSh7b2J9KTsKKyAgICAgICAgfQkJCQorCWZvcmVhY2goa2V5LCB3ZXJ0OiByZXMpIHsKKyAgICAgICAgICBjdW11bGF0aXZlX21vZC09d2VydDsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIGFkZF9vZmZzZXRzKHJlcyk7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gSEVBTFRIX01PRCB3ZXJkZW4gZHVyY2ggZWluZSBGb3JtZWwgJ2VudHNjaGFlcmZ0JywgZGFtaXQgbWFuIG51ciBzY2h3ZXIKKyAgLy8gZGFzIE1heGltdW0gdm9uIDE1MCBlcnJlaWNoZW4ga2Fubi4gKEZvcm1lbCB2b24gSHVtbmksIGJlc2NobG9zc2VuIGF1ZiAzLgorICAvLyBFTS1UcmVmZmVuKQorICAvLyBNYWxpIGdlaGVuIGFiZXIgdm9sbCBlaW4KKyAgaHBfb2ZmID0gKGludCkoMTUwIC0gKDE1MCoxNTAuMC8oMTUwICsgaHBfb2ZmKSkpICsgaHBfbWFsdXM7CisgIHNwX29mZiA9IChpbnQpKDE1MCAtICgxNTAqMTUwLjAvKDE1MCArIHNwX29mZikpKSArIHNwX21hbHVzOworCisgIC8qIGFsdGUgVmVyc2lvbgorICAgIGhwX29mZiArPSBocF9tYWx1czsKKyAgICBzcF9vZmYgKz0gc3BfbWFsdXM7CisgICovCisgCisgIC8vIG5vdGlmeSBpbnZhbGlkIG1vZGlmaWVycworICBpZihzaXplb2YoaW52YWxpZF9tb2RpZmllcnMpPjApIHsKKyAgICBjYWxsX291dCgjJ25vdGlmeUludmFsaWRNb2RpZmllcnMsMCk7CisgIH0KK30KKworLy8gYWJtZWxkZW4gZWluZXMgbW9kaWZpZXJzIAorbm9tYXNrIHB1YmxpYyB2b2lkIGRlcmVnaXN0ZXJfbW9kaWZpZXIob2JqZWN0IG1vZGlmaWVyKQoreyAKKyAgaWYgKCFwb2ludGVycChhbGxfbW9kaWZpZXJzKSkgeworICAgIHJldHVybjsKKyAgfQorCisgIC8vIHZhbGlkIG9iamVjdD8KKyAgaWYgKCFvYmplY3RwKG1vZGlmaWVyKSB8fCBtZW1iZXIoYWxsX21vZGlmaWVycyxtb2RpZmllcik9PS0xKSB7CisgICAgcmV0dXJuOworICB9CisgIAorICBhbGxfbW9kaWZpZXJzLT0oe21vZGlmaWVyfSk7CisgIGlmIChpbnZhbGlkX21vZGlmaWVycykgeworICAgIGludmFsaWRfbW9kaWZpZXJzLT0oe21vZGlmaWVyfSk7CisgIH0KK30KKworLy8gYW5tZWxkZW4gZWluZXMgbW9kaWZpZXJzIAorbm9tYXNrIHB1YmxpYyB2b2lkIHJlZ2lzdGVyX21vZGlmaWVyKG9iamVjdCBtb2RpZmllcikgeyAKKyAgY2xvc3VyZSBxcDsKKyAgCisgIGlmICghcG9pbnRlcnAoYWxsX21vZGlmaWVycykpIHsKKyAgICBhbGxfbW9kaWZpZXJzPSh7fSk7CisgIH0KKworICAvLyB2YWxpZCBvYmplY3Q/CisgIGlmICghb2JqZWN0cChtb2RpZmllcikgfHwgZW52aXJvbm1lbnQobW9kaWZpZXIpIT10aGlzX29iamVjdCgpIHx8IAorICAgICAgbWVtYmVyKGFsbF9tb2RpZmllcnMsbW9kaWZpZXIpIT0tMSkgeworICAgIHJldHVybjsKKyAgfQorICAKKyAgcXAgPSBzeW1ib2xfZnVuY3Rpb24oIlF1ZXJ5UHJvcCIsbW9kaWZpZXIpOworICAvLyBtb2RpZmllciBhZnRlciBhbGw/IERpZSBQX01fKiBtdWVzc2VuIGdldHJhZ2VuL2dlenVlY2t0IHNlaW4uCisgIGlmKG1hcHBpbmdwKGZ1bmNhbGwocXAsUF9YX0FUVFJfTU9EKSkgfHwKKyAgICAgbWFwcGluZ3AoZnVuY2FsbChxcCxQX1hfSEVBTFRIX01PRCkpIHx8CisgICAgKChtYXBwaW5ncChmdW5jYWxsKHFwLFBfTV9BVFRSX01PRCkpIHx8CisgICAgICAgbWFwcGluZ3AoZnVuY2FsbChxcCxQX01fSEVBTFRIX01PRCkpKSAmJgorICAgICAgKGZ1bmNhbGwocXAsUF9XT1JOKSB8fCBmdW5jYWxsKHFwLFBfV0lFTERFRCkpICkgKSB7CisgICAgYWxsX21vZGlmaWVycys9KHttb2RpZmllcn0pOworICB9Cit9CisKK3Byb3RlY3RlZCB2b2lkIGFkZF9vZmZzZXRzKG1hcHBpbmcgYXJyKSB7CisgIG1peGVkICppbmQ7CisgIGludCBpOworICAKKyAgaWYgKCAhbWFwcGluZ3AoYXJyKSApCisgICAgcmV0dXJuOworCisgIGZvcmVhY2goc3RyaW5nIGtleSwgaW50IHdlcnQ6IGFycikgeworICAgIHVzZWRfYXR0cmlidXRlc19vZmZzZXRzW2tleV0rPXdlcnQ7CisgIH0KK30KKworcHVibGljIHZvaWQgVXBkYXRlQXR0cmlidXRlcygpIHsKKyAgbWl4ZWQgICAqaW5kOworICBpbnQgICAgIGk7CisgIAorICAvLyBhbGxlIGd1ZWx0aWdlbiBNb2RpZmllciBlcm1pdHRlbG4gYXVzIE9iamVrdGVuIGltIEludmVudGFyLgorICBjYWxjdWxhdGVfdmFsaWRfbW9kaWZpZXJzKCk7CisKKyAgLy8gcGVyc2lzdGVudGUgbW9kaWZpZXIgZHJhdWYgKGZyb3NjaCB6YikKKyAgLy8gYXVzIFBfQVRUUklCVVRFU19NT0RJRklFUlMKKyAgaWYgKCBtYXBwaW5ncChhdHRyaWJ1dGVzX21vZGlmaWVyKSApIHsKKyAgICBmb3JlYWNoKG1peGVkIGtleSwgbWFwcGluZyB3ZXJ0OiBhdHRyaWJ1dGVzX21vZGlmaWVyKSB7CisgICAgICBhZGRfb2Zmc2V0cyh3ZXJ0KTsgLy8gTW9kaWZpZXIgYWRkaWVyZW4uLi4JCQorICAgIH0KKyAgfQorICAvLyB0aW1lZCBtb2RpZmllciBkcmF1ZiBhdXMgUF9USU1FRF9BVFRSX01PRAorICBpbmQ9bV9pbmRpY2VzKGF0dHJpYnV0ZXNfdGltZWRfbW9kc1tUQVRUUl9FTlRSSUVTXSk7CisgIGZvciAoIGk9c2l6ZW9mKGluZCktMSA7IGk+PTAgOyBpLS0gKSB7CisgICAgLy8gTW9kaWZpZXIgYWRkaWVyZW4uLi4KKyAgICBhZGRfb2Zmc2V0cyhhdHRyaWJ1dGVzX3RpbWVkX21vZHNbVEFUVFJfRU5UUklFU11baW5kW2ldLDBdKTsKKyAgfQorICAvLyBCZWkgTW9uc3Rlcm4gd2VyZGVuIGRpZSBIUC9TUCB1ZWJsaWNoZXJ3ZWlzZSBzZWxic3QgZ2VzZXR6dAorICBpZiAoICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpKQorICAgIHJldHVybjsKKworICBTZXRQcm9wKFBfTUFYX0hQLCBRdWVyeUF0dHJpYnV0ZShBX0NPTikqOCs0MitocF9vZmYpOworICBTZXRQcm9wKFBfTUFYX1NQLCBRdWVyeUF0dHJpYnV0ZShBX0lOVCkqOCs0MitzcF9vZmYpOworICAKKyAgaWYoUXVlcnlQcm9wKFBfSFApPlF1ZXJ5UHJvcChQX01BWF9IUCkpIHsKKyAgICBTZXRQcm9wKFBfSFAsUXVlcnlQcm9wKFBfTUFYX0hQKSk7CisgIH0KKyAgCisgIGlmKFF1ZXJ5UHJvcChQX1NQKT5RdWVyeVByb3AoUF9NQVhfU1ApKSB7CisgICAgU2V0UHJvcChQX1NQLFF1ZXJ5UHJvcChQX01BWF9TUCkpOworICB9CisKKyAgR01DUF9DaGFyKCAoWyBBX0lOVDogUXVlcnlBdHRyaWJ1dGUoQV9JTlQpLAorICAgICAgICAgICAgICAgIEFfREVYOiBRdWVyeUF0dHJpYnV0ZShBX0RFWCksCisgICAgICAgICAgICAgICAgQV9TVFI6IFF1ZXJ5QXR0cmlidXRlKEFfU1RSKSwKKyAgICAgICAgICAgICAgICBBX0NPTjogUXVlcnlBdHRyaWJ1dGUoQV9DT04pIF0pICk7Cit9CisKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkgeworICBocF9vZmY9c3Bfb2ZmPTA7CisgIHVzZWRfYXR0cmlidXRlc19vZmZzZXRzPShbXSk7CisgIGFsbF9tb2RpZmllcnM9KHt9KTsKKyAgaW52YWxpZF9tb2RpZmllcnM9KHt9KTsKKyAgY3VtdWxhdGl2ZV9tb2Q9MDsKKyAgCisgIFNldChQX0FUVFJJQlVURVNfTU9ESUZJRVIsIGF0dHJpYnV0ZXNfbW9kaWZpZXI9KFtdKSk7IC8vIG5pY2h0IGdlc2NodWV0enQKKyAgU2V0KFBfQVRUUklCVVRFU19PRkZTRVRTLCBhdHRyaWJ1dGVzX29mZnNldHM9KFtdKSk7CisgIFNldChQX0FUVFJJQlVURVNfT0ZGU0VUUywgUFJPVEVDVEVELCBGX01PREUpOworICBTZXQoUF9BVFRSSUJVVEVTLCBhdHRyaWJ1dGVzPShbXSkpOworICBTZXQoUF9BVFRSSUJVVEVTLCBQUk9URUNURUQsIEZfTU9ERSk7CisKKyAgU2V0KFBfVElNRURfQVRUUl9NT0QsIGF0dHJpYnV0ZXNfdGltZWRfbW9kcz0oeyAoe30pLChbXSksKFtdKSB9KSk7CisgIFNldChQX1RJTUVEX0FUVFJfTU9ELCBOT1NFVE1FVEhPRHxTRUNVUkVELCBGX01PREVfQVMpOworfQorCitzdGF0aWMgbWl4ZWQgX3F1ZXJ5X3RpbWVkX2F0dHJfbW9kKCkgeworICBtaXhlZCByZXQ7CisgIHJldHVybiBTZXQoUF9USU1FRF9BVFRSX01PRCwJICAgIAorICAgICAgKHthdHRyaWJ1dGVzX3RpbWVkX21vZHNbMF0sCisJZGVlcF9jb3B5KGF0dHJpYnV0ZXNfdGltZWRfbW9kc1sxXSksCisJZGVlcF9jb3B5KGF0dHJpYnV0ZXNfdGltZWRfbW9kc1syXSl9KSk7Cit9CisKK3N0YXRpYyBtYXBwaW5nIF9zZXRfYXR0cmlidXRlcyhtYXBwaW5nIGFycikgCit7CisgIFNldChQX0FUVFJJQlVURVMsIGF0dHJpYnV0ZXM9YXJyKTsKKyAgVXBkYXRlQXR0cmlidXRlcygpOworICByZXR1cm4gYXJyOworfQorCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfYXR0cmlidXRlcygpIAoreworICByZXR1cm4gZGVlcF9jb3B5KFNldChQX0FUVFJJQlVURVMsIGF0dHJpYnV0ZXMpKTsgCit9CisKK3N0YXRpYyBtYXBwaW5nIF9zZXRfYXR0cmlidXRlc19vZmZzZXRzKG1hcHBpbmcgYXJyKSAKK3sKKyAgU2V0KFBfQVRUUklCVVRFU19PRkZTRVRTLCBhdHRyaWJ1dGVzX29mZnNldHM9YXJyKTsKKyAgVXBkYXRlQXR0cmlidXRlcygpOworICByZXR1cm4gYXR0cmlidXRlc19vZmZzZXRzOworfQorCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfYXR0cmlidXRlc19vZmZzZXRzKCkgCit7IAorICByZXR1cm4gZGVlcF9jb3B5KFNldChQX0FUVFJJQlVURVNfT0ZGU0VUUywgYXR0cmlidXRlc19vZmZzZXRzKSk7Cit9CisKK3N0YXRpYyBtaXhlZCBfc2V0X2F0dHJpYnV0ZXNfbW9kaWZpZXIobWl4ZWQgYXJyKSAKK3sgc3RyaW5nIGZuOworICBtaXhlZCBwcmU7CisgIG1hcHBpbmcgbWFwX2xkZmllZDsKKyAgCisgIGlmICggcG9pbnRlcnAoYXJyKSAmJiAoc2l6ZW9mKGFycik+PTIpICkKKyAgeworICAgIHByZT1hcnJbMF07CisgICAgbWFwX2xkZmllZD1hcnJbMV07CisgIH0KKyAgZWxzZSAKKyAgeworICAgIHByZT1wcmV2aW91c19vYmplY3QoKTsKKyAgICBtYXBfbGRmaWVkPWFycjsKKyAgfQorCisgIGlmICggb2JqZWN0cChwcmUpICkKKyAgICBmbj1vbGRfZXhwbG9kZShvYmplY3RfbmFtZShwcmUpLCIjIilbMF07CisgIGVsc2UKKyAgICBmbj1wcmU7CisKKyAgaWYgKCAhc3RyaW5ncChmbikgKQorICAgIHJldHVybiAwOworCisgIC8vIHdlbm4gTW9kaWZpZXIga2VpbiBtYXBwaW5nIG9kZXIgZWluIGxlZXJlcyBNYXBwaW5nOiBsb2VzY2hlbgorICBpZiAoICFtYXBwaW5ncChtYXBfbGRmaWVkKSB8fCAhc2l6ZW9mKG1hcF9sZGZpZWQpKQorICAgIG1fZGVsZXRlKGF0dHJpYnV0ZXNfbW9kaWZpZXIsZm4pOworICBlbHNlCisgICAgYXR0cmlidXRlc19tb2RpZmllcltmbl09bWFwX2xkZmllZDsKKworICBTZXQoUF9BVFRSSUJVVEVTX01PRElGSUVSLCBhdHRyaWJ1dGVzX21vZGlmaWVyKTsKKyAgVXBkYXRlQXR0cmlidXRlcygpOworICByZXR1cm4gYXR0cmlidXRlc19tb2RpZmllcltmbl07Cit9CisKK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV9hdHRyaWJ1dGVzX21vZGlmaWVyKCkgCit7CisgIHJldHVybiBkZWVwX2NvcHkoYXR0cmlidXRlc19tb2RpZmllcik7ICAKK30KKworcHVibGljIGludCBTZXRBdHRyKHN0cmluZyBhdHRyLCBpbnQgdmFsKSAKK3sgY2xvc3VyZSBmaWx0ZXJfbGRmaWVkOworCisgIGlmICggZmlsdGVyX2xkZmllZCA9IHN5bWJvbF9mdW5jdGlvbigiX2ZpbHRlcmF0dHJfIithdHRyLCB0aGlzX29iamVjdCgpKSApIAorICAgIHZhbCA9IGZ1bmNhbGwoZmlsdGVyX2xkZmllZCwgdmFsICk7CisKKyAgYXR0cmlidXRlc1thdHRyXSA9IHZhbDsKKyAgVXBkYXRlQXR0cmlidXRlcygpOworICByZXR1cm4gdmFsOworfQorCitwdWJsaWMgaW50IFNldEF0dHJpYnV0ZShzdHJpbmcgYXR0ciwgaW50IHZhbCkgCit7CisgIHJldHVybiBTZXRBdHRyKGF0dHIsIHZhbC11c2VkX2F0dHJpYnV0ZXNfb2Zmc2V0c1thdHRyXSk7Cit9CisKKy8vIERpZXNlIEZ1bmt0aW9uIHNvbGx0ZSB6dW0gQWJmcmFnZW4gdmVyd2VuZGV0IHdlcmRlbjoKK3B1YmxpYyBpbnQgUXVlcnlBdHRyaWJ1dGUoc3RyaW5nIGF0dHIpIAoreyBpbnQgcmU7CisKKyAgcmU9YXR0cmlidXRlc1thdHRyXSt1c2VkX2F0dHJpYnV0ZXNfb2Zmc2V0c1thdHRyXTsKKworICBpZiAoIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkgJiYgKHJlPjMwKSApCisgICAgcmU9MzA7CisKKyAgcmV0dXJuIHJlOworfQorCitwdWJsaWMgaW50IFF1ZXJ5UmVhbEF0dHJpYnV0ZShzdHJpbmcgYXR0cikgCit7CisgIHJldHVybiBhdHRyaWJ1dGVzW2F0dHJdOworfQorCitwdWJsaWMgaW50IFNldFJlYWxBdHRyaWJ1dGUoc3RyaW5nIGF0dHIsIGludCB2YWwpIAoreworICByZXR1cm4gU2V0QXR0cihhdHRyLCB2YWwpOworfQorCitwdWJsaWMgaW50IFF1ZXJ5QXR0cmlidXRlT2Zmc2V0KHN0cmluZyBhdHRyKSAKK3sKKyAgcmV0dXJuIHVzZWRfYXR0cmlidXRlc19vZmZzZXRzW2F0dHJdOworfQorCitwdWJsaWMgc3RhdHVzIFRlc3RMaW1pdFZpb2xhdGlvbihtYXBwaW5nIGNoZWNrKQoreworICBpbnQgayx0ZXN0OworICBtaXhlZCogaW5kOworICAgIAorICBpZighY2hlY2sgfHwgIW1hcHBpbmdwKGNoZWNrKSkKKyAgeworICAgIHJldHVybiAwOworICB9CisKKyAgdGVzdD0wOworICBpbmQ9bV9pbmRpY2VzKGNoZWNrKTsKKyAgZm9yKCBrPXNpemVvZihpbmQpLTEgOyBrPj0wIDsgay0tICkKKyAgeworICAgIHRlc3QrPWNoZWNrW2luZFtrXV07CisgIH0KKyAgCisgIHRlc3QrPWN1bXVsYXRpdmVfbW9kOworICBpZih0ZXN0PkNVTVVMQVRJVkVfQVRUUl9MSU1JVCkKKyAgeworICAgIHJldHVybiAxOworICB9CisgIAorICByZXR1cm4gMDsKK30KKworLyoKKyAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBhdHRyaWJ1dGVzIGNvbXBhdGliaWxpdHkgZnVuY3Rpb25zCisgKi8KKworcHJvdGVjdGVkIGludCBfZmlsdGVyYXR0cl9zdHIoaW50IHZhbCkKK3sKKyAgcmV0dXJuICggKHZhbDwwKSA/IDAgOiAodmFsPjIwKSA/IDIwIDogdmFsICk7Cit9CisKK3Byb3RlY3RlZCBpbnQgX2ZpbHRlcmF0dHJfZGV4KGludCB2YWwpCit7CisgIHJldHVybiAoICh2YWw8MCkgPyAwIDogKHZhbD4yMCkgPyAyMCA6IHZhbCApOworfQorCitwcm90ZWN0ZWQgaW50IF9maWx0ZXJhdHRyX2ludChpbnQgdmFsKQoreworICByZXR1cm4gKCAodmFsPDApID8gMCA6ICh2YWw+MjApID8gMjAgOiB2YWwgKTsKK30KKworcHJvdGVjdGVkIGludCBfZmlsdGVyYXR0cl9jb24oaW50IHZhbCkKK3sKKyAgcmV0dXJuICggKHZhbDwwKSA/IDAgOiAodmFsPjIwKSA/IDIwIDogdmFsICk7Cit9CmRpZmYgLS1naXQgYS9zdGQvbGl2aW5nL2Nsb3RoaW5nLmMgYi9zdGQvbGl2aW5nL2Nsb3RoaW5nLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTZhZmY0NAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvY2xvdGhpbmcuYwpAQCAtMCwwICsxLDk2IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL2Nsb3RoaW5nLmMgLS0gTW9kdWwgZnVlciBCZWtsZWlkdW5nc2ZyYWdlbi4gOy0pCisvLworLy8gJElkOiBhcm1vdXIuYyx2IDMuOCAyMDAzLzA4LzI1IDA5OjM2OjA0IFJpa3VzIEV4cCAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGxpdmluZy9jbG90aGluZy5oPgorI2luY2x1ZGUgPGxpdmluZy9jb21iYXQuaD4KKyNpbmNsdWRlIDxhcm1vdXIuaD4KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkgeworICBTZXRQcm9wKFBfQ0xPVEhJTkcsICh7fSkpOworICBTZXQoUF9DTE9USElORywgUFJPVEVDVEVELCBGX01PREVfQVMpOworfQorCitwdWJsaWMgb2JqZWN0ICpGaWx0ZXJDbG90aGluZyhjbG9zdXJlIGZpbHRlcmZ1biwgdmFyYXJncyBtaXhlZCogZXh0cmEpIHsKKyAgaWYgKCFjbG9zdXJlcChmaWx0ZXJmdW4pKQorICAgIHJldHVybiAoe30pOworICByZXR1cm4gYXBwbHkoIydmaWx0ZXIsIFF1ZXJ5UHJvcChQX0NMT1RISU5HKSwgZmlsdGVyZnVuLCBleHRyYSk7Cit9CisKK3B1YmxpYyBvYmplY3QgKkZpbHRlckFybW91cnMoY2xvc3VyZSBmaWx0ZXJmdW4sIHZhcmFyZ3MgbWl4ZWQqIGV4dHJhKSB7CisgIGlmICghY2xvc3VyZXAoZmlsdGVyZnVuKSkKKyAgICByZXR1cm4gKHt9KTsKKyAgcmV0dXJuIGFwcGx5KCMnZmlsdGVyLCBRdWVyeVByb3AoUF9BUk1PVVJTKS0oezB9KSwgZmlsdGVyZnVuLCBleHRyYSk7Cit9CisKK3B1YmxpYyBpbnQgV2VhckNsb3RoaW5nKG9iamVjdCBvYikgeworICBvYmplY3QgKmNsb3RoaW5nID0gUXVlcnlQcm9wKFBfQ0xPVEhJTkcpOworICBpZiAobWVtYmVyKGNsb3RoaW5nLCBvYikgIT0gLTEpCisgICAgcmV0dXJuIDA7CisgIGNsb3RoaW5nICs9ICh7b2J9KTsKKyAgU2V0UHJvcChQX0NMT1RISU5HLCBjbG90aGluZyk7CisgIHJldHVybiAxOworfQorCitwdWJsaWMgaW50IFdlYXJBcm1vdXIob2JqZWN0IG9iKSB7CisgIGlmICghVkFMSURfQVJNT1VSX1RZUEUob2ItPlF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKSkpCisgICAgcmV0dXJuIDA7CisKKyAgb2JqZWN0ICphcm1vdXJzID0gUXVlcnlQcm9wKFBfQVJNT1VSUyk7CisgIGlmIChtZW1iZXIoYXJtb3Vycywgb2IpICE9IC0xKQorICAgIHJldHVybiAwOworCisgIGFybW91cnMgKz0gKHtvYn0pOworICBTZXRQcm9wKFBfQVJNT1VSUywgYXJtb3Vycyk7CisgIHJldHVybiAxOworfQorCitwdWJsaWMgaW50IFdlYXIob2JqZWN0IG9iKSB7CisgIC8vIHJlaWhlbmZvbGdlIGlzdCB3aWNodGlnISBSdWVzdHVuZyBzaW5kIF9hdWNoXyBLbGVpZHVuZywgYWJlciBLbGVpZHVuZworICAvLyBrZWluZSBSdWVzdHVuZy4KKyAgaWYgKG9iLT5Jc0FybW91cigpKQorICAgIHJldHVybiBXZWFyQXJtb3VyKG9iKTsKKyAgZWxzZSBpZiAob2ItPklzQ2xvdGhpbmcoKSkKKyAgICByZXR1cm4gV2VhckNsb3RoaW5nKG9iKTsKKyAgcmV0dXJuIDA7Cit9CisKK3B1YmxpYyBpbnQgVW53ZWFyQ2xvdGhpbmcob2JqZWN0IG9iKSB7CitvYmplY3QgKmNsb3RoaW5nID0gUXVlcnlQcm9wKFBfQ0xPVEhJTkcpOworICBpZiAobWVtYmVyKGNsb3RoaW5nLCBvYikgPT0gLTEpCisgICAgcmV0dXJuIDA7CisgIGNsb3RoaW5nIC09ICh7b2J9KTsKKyAgU2V0UHJvcChQX0NMT1RISU5HLCBjbG90aGluZyk7CisgIHJldHVybiAxOworfQorCitwdWJsaWMgaW50IFVud2VhckFybW91cihvYmplY3Qgb2IpIHsKKyAgb2JqZWN0ICphcm1vdXJzID0gUXVlcnlQcm9wKFBfQVJNT1VSUyk7CisgIGlmIChtZW1iZXIoYXJtb3Vycywgb2IpID09IC0xKQorICAgIHJldHVybiAwOworCisgIGFybW91cnMgLT0gKHtvYn0pOworICBTZXRQcm9wKFBfQVJNT1VSUywgYXJtb3Vycyk7CisgIHJldHVybiAxOworfQorCitwdWJsaWMgaW50IFVud2VhcihvYmplY3Qgb2IpIHsKKyAgLy8gcmVpaGVuZm9sZ2UgaXN0IHdpY2h0aWchIFJ1ZXN0dW5nIHNpbmQgX2F1Y2hfIEtsZWlkdW5nLCBhYmVyIEtsZWlkdW5nCisgIC8vIGtlaW5lIFJ1ZXN0dW5nLgorICBpZiAob2ItPklzQXJtb3VyKCkpCisgICAgcmV0dXJuIFVud2VhckFybW91cihvYik7CisgIGVsc2UgaWYgKG9iLT5Jc0Nsb3RoaW5nKCkpCisgICAgcmV0dXJuIFVud2VhckNsb3RoaW5nKG9iKTsKKyAgcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvY29tYmF0LmMgYi9zdGQvbGl2aW5nL2NvbWJhdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4MGYzZjYKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL2NvbWJhdC5jCkBAIC0wLDAgKzEsMjMxMSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9jb21iYXQuYyAtLSBCYXNpcy1LYW1wZm1vZHVsCisvLworLy8gJElkOiBjb21iYXQuYyA5NTY4IDIwMTYtMDYtMDUgMTg6NTM6MTBaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL2xpdmluZy9za2lsbF91dGlscyI7Citpbmhlcml0ICIvc3RkL2xpdmluZy9pbnZlbnRvcnkiOworaW5oZXJpdCAiL3N0ZC9saXZpbmcvdGVhbSI7CisKKyNpbmNsdWRlIDxzeXNfZGVidWcuaD4KKyNpbmNsdWRlIDxkZWJ1Z19tZXNzYWdlLmg+CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8aG9vay5oPgorI2luY2x1ZGUgPGxpdmluZy9za2lsbHMuaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cGxheWVyL2NvbW0uaD4KKyNpbmNsdWRlIDxsaXZpbmcvc2tpbGxfYXR0cmlidXRlcy5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPGxpdmluZy5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8YXR0cmlidXRlcy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKworI2luY2x1ZGUgPGRlZmluZXMuaD4KKworI2luY2x1ZGUgPHNlbnNpdGl2ZS5oPgorCisjZGVmaW5lIEhVTlRUSU1FIDMwMCAvLzMwMCBIQnMgc2luZCAxMCBNaW51dGVuCisjZGVmaW5lIFJOQU1FKHgpIGNhcGl0YWxpemUoZ2V0dWlkKHgpKQorCisvLyAncHJpdmF0ZSctUHJvdG90eXBlcworcHJpdmF0ZSBzdHJpbmcgX2tpbGxfYWxpYXMoIHN0cmluZyBzdHIgKTsKKworLy8gZ2xvYmFsZSBWYXJpYWJsZW4KK25vc2F2ZSBtYXBwaW5nIGVuZW1pZXM7Citwcml2YXRlIG5vc2F2ZSBzdHJpbmcgbWFnaWNfYXR0YWNrOworcHJpdmF0ZSBub3NhdmUgaW50IGF0dGFja19idXN5Oworbm9zYXZlIGludCBub19tb3JlX2F0dGFja3M7Citwcml2YXRlIG5vc2F2ZSBpbnQgcmVtYWluaW5nX2hlYXJ0X2JlYXRzOworcHJpdmF0ZSBub3NhdmUgaW50IGF0dDJfdGltZTsKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyBsYXN0X2F0dGFja19tc2c7Citwcml2YXRlIG5vc2F2ZSBvYmplY3QgKm1pc3NpbmdfYXR0YWNrczsKK3ByaXZhdGUgbm9zYXZlIG1hcHBpbmcgcGVhY2VfdHJpZXM7CisvLyBDYWNoZSBmdWVyIFF1ZXJ5QXJtb3VyQnlUeXBlKCkKK3ByaXZhdGUgbm9zYXZlIG1hcHBpbmcgUUFCVENhY2hlOworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBTZXQoUF9XSU1QWSwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfVE9UQUxfQUMsIFBST1RFQ1RFRCwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfSEFORFMsIFNBVkUsIEZfTU9ERV9BUyk7CisgIFNldChQX1NIT1dfQVRUQUNLX01TRyxTQVZFLEZfTU9ERV9BUyk7CisgIFNldChQX1JFU0lTVEFOQ0UsICh7fSkpOworICBTZXQoUF9WVUxORVJBQklMSVRZLCAoe30pKTsKKyAgU2V0KFBfR1VJTERfUFJFUEFSRUJMT0NLLCBTQVZFLCBGX01PREVfQVMpOworICAvLyBLZWluIFNldHplbiB2b24gUF9BUk1PVVJTIHZvbiBhdXNzZW4gcGVyIFNldCgpLiAoUGVyIFNldFByb3AoKSBnZWh0IGVzCisgIC8vIGR1cmNoIGRpZSBTZXRtZXRob2RlKS4KKyAgU2V0KFBfQVJNT1VSUyxQUk9URUNURUQsRl9NT0RFX0FTKTsKKyAgU2V0UHJvcChQX0FSTU9VUlMsICh7fSkpOworICBhdHRhY2tfYnVzeT0xMDA7CisgIGF0dDJfdGltZT0wOworICBlbmVtaWVzPShbXSk7CisgIHBlYWNlX3RyaWVzPShbXSk7CisgIHRlYW06OmNyZWF0ZSgpOyAKKyAgb2ZmZXJIb29rKEhfSE9PS19ERUZFTkQsMSk7CisgIG9mZmVySG9vayhIX0hPT0tfQVRUQUNLLDEpOworICBvZmZlckhvb2soSF9IT09LX0FUVEFDS19NT0QsMSk7Cit9CisKKyN1bmRlZiBERUJVRworI2RlZmluZSBERUJVRyh4KSBpZiAoZmluZF9vYmplY3QoInplc3N0cmEiKSkgXAorICB0ZWxsX29iamVjdChmaW5kX3BsYXllcigiemVzc3RyYSIpLHgpCisKK3B1YmxpYyB2b2lkIFVwZGF0ZVJlc2lzdGFuY2VTdHJlbmd0aHMoKSB7IAorICBtYXBwaW5nIHJlc21vZHMsIHN0cm1hcDsKKworICBpZiAoICFtYXBwaW5ncChyZXNtb2RzPVF1ZXJ5KFBfUkVTSVNUQU5DRV9NT0RJRklFUikpICkKKyAgICByZXR1cm47CisKKyAgLy9lcnN0bWFsIGRpZSBhbHRlIEF1ZnN1bW1hdGlvbiBsb2VzY2hlbgorICBtX2RlbGV0ZShyZXNtb2RzLCJtZSIpOworCisgIC8vd2VubiBqZXR6dCBsZWVyOiBBYmJydWNoLCBrZWluZSBSZXMtTW9kaWZpZXIgZGEuCisgIGlmICghc2l6ZW9mKHJlc21vZHMpKQorICAgICAgcmV0dXJuKFNldChQX1JFU0lTVEFOQ0VfTU9ESUZJRVIsMCkpOworCisgIHN0cm1hcCA9IChbXSk7CisKKyAgLy8gdWViZXIgYWxsZSBnZXNldHp0ZW4gUmVzTW9kaWZpZXIgZ2VoZW4KKyAgZm9yZWFjaChzdHJpbmcgbW9kLCBtYXBwaW5nIHJlc21hcCwgb2JqZWN0IG9iOiByZXNtb2RzKSB7CisgICAgaWYgKCAhbWFwcGluZ3AocmVzbWFwKSB8fCAhc2l6ZW9mKHJlc21hcCkKKyAgICAgICAgfHwgIW9iamVjdHAob2IpICkgeworICAgICAgbV9kZWxldGUocmVzbW9kcywgbW9kKTsKKyAgICAgIGNvbnRpbnVlOyAvLyBSZXNpIHVuZ3VlbHRpZywgd2VnIGRhbWl0LgorICAgIH0KKyAgICAvLyBqZXR6dCBub2NoIHVlYmVyIGRpZSBTdWJtYXBwaW5ncyBsYXVmZW4sIGRpZSBkaWUgUmVzaXMgZGVyIE9iamVrdGUKKyAgICAvLyBiZWluaGFsdGVuLgorICAgIGZvcmVhY2goc3RyaW5nIHJlc2tleSwgZmxvYXQgcmVzaTogcmVzbWFwKSB7CisgICAgICAgIHN0cm1hcFtyZXNrZXldID0gKChzdHJtYXBbcmVza2V5XSsxLjApKihyZXNpKzEuMCkpLTEuMDsKKyAgICB9CisgIH0KKworICBpZiAoICFzaXplb2Yoc3RybWFwKSApCisgICAgU2V0KFBfUkVTSVNUQU5DRV9NT0RJRklFUiwgMCk7CisgIGVsc2UKKyAgICBTZXQoUF9SRVNJU1RBTkNFX01PRElGSUVSLCByZXNtb2RzKyhbICJtZSIgOiBzdHJtYXA7IDAgXSkgKTsKK30KKworcHVibGljIHZhcmFyZ3MgaW50IEFkZFJlc2lzdGFuY2VNb2RpZmllcihtYXBwaW5nIG1vZCwgc3RyaW5nIGFkZCkKK3sgc3RyaW5nICBrZXk7CisgIG1hcHBpbmcgcmVzOworCisgIGlmICggIW1hcHBpbmdwKG1vZCkgfHwgIXNpemVvZihtb2QpIHx8ICFwcmV2aW91c19vYmplY3QoKSApCisgICAgcmV0dXJuIDA7CisKKyAga2V5ID0gZXhwbG9kZShvYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSksIiMiKVswXTsKKworICBpZiAoIGFkZCApCisgICAga2V5ICs9ICgiIyIrYWRkKTsKKworICByZXMgPSBRdWVyeShQX1JFU0lTVEFOQ0VfTU9ESUZJRVIpOworICBtb2QgPSBkZWVwX2NvcHkobW9kKTsKKworICBpZiAoICFtYXBwaW5ncChyZXMpICkKKyAgICByZXMgPSAoWyBrZXkgOiBtb2Q7IHByZXZpb3VzX29iamVjdCgpIF0pOworICBlbHNlCisgICAgcmVzICs9IChbIGtleSA6IG1vZDsgcHJldmlvdXNfb2JqZWN0KCkgXSk7CisKKyAgU2V0KFBfUkVTSVNUQU5DRV9NT0RJRklFUiwgcmVzKTsKKyAgVXBkYXRlUmVzaXN0YW5jZVN0cmVuZ3RocygpOworCisgIHJldHVybiAxOworfQorCitwdWJsaWMgdmFyYXJncyB2b2lkIFJlbW92ZVJlc2lzdGFuY2VNb2RpZmllcihzdHJpbmcgYWRkKQoreyBzdHJpbmcgIGtleTsKKyAgbWFwcGluZyByZXM7CisKKyAgaWYgKCAhcHJldmlvdXNfb2JqZWN0KCkgKQorICAgIHJldHVybjsKKworICBrZXkgPSBleHBsb2RlKG9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSwiIyIpWzBdOworCisgIGlmICggYWRkICkKKyAgICBrZXkgKz0gKCIjIithZGQpOworCisgIGlmICggIW1hcHBpbmdwKHJlcyA9IFF1ZXJ5KFBfUkVTSVNUQU5DRV9NT0RJRklFUikpICkKKyAgICByZXR1cm47CisKKyAgbV9kZWxldGUocmVzLCBrZXkpOworICBTZXQoUF9SRVNJU1RBTkNFX01PRElGSUVSLCByZXMpOworICBVcGRhdGVSZXNpc3RhbmNlU3RyZW5ndGhzKCk7Cit9CisKKy8vIHZlcmFsdGV0ZSBQcm9wLCBhdXMgS29tcGF0aWJpbGl0YWV0c2dydWVuZGVuIG5vY2ggdm9yaGFuZGVuLgorc3RhdGljIG1peGVkIF9zZXRfcmVzaXN0YW5jZShtaXhlZCBhcmcpCit7IGludCAgICAgaTsKKyAgbWFwcGluZyByZXNpbWFwOworICBtaXhlZCAgIG9sZDsKKworICBpZiAoICFwb2ludGVycChhcmcpICkKKyAgICBhcmc9KHthcmd9KTsKKworICBpZiAoICFtYXBwaW5ncChyZXNpbWFwPVF1ZXJ5KFBfUkVTSVNUQU5DRV9TVFJFTkdUSFMpKSApCisgICAgcmVzaW1hcD0oW10pOworCisgIGlmICggcG9pbnRlcnAob2xkPVF1ZXJ5UHJvcChQX1JFU0lTVEFOQ0UpKSApCisgICAgZm9yICggaT1zaXplb2Yob2xkKS0xIDsgaT49MCA7IGktLSApCisgICAgICByZXNpbWFwW29sZFtpXV09KDEuMCsoKGZsb2F0KXJlc2ltYXBbb2xkW2ldXSkpKjIuMC0xLjA7CisKKyAgZm9yICggaT1zaXplb2YoYXJnKS0xIDsgaT49MCA7IGktLSApCisgICAgcmVzaW1hcFthcmdbaV1dPSgxLjArKChmbG9hdClyZXNpbWFwW2FyZ1tpXV0pKSowLjUtMS4wOworCisgIFNldFByb3AoUF9SRVNJU1RBTkNFX1NUUkVOR1RIUyxyZXNpbWFwKTsKKworICByZXR1cm4gU2V0KFBfUkVTSVNUQU5DRSxhcmcpOworfQorCisvLyB2ZXJhbHRldGUgUHJvcCwgYXVzIEtvbXBhdGliaWxpdGFldHNncnVlbmRlbiBub2NoIHZvcmhhbmRlbi4KK3N0YXRpYyBtaXhlZCBfc2V0X3Z1bG5lcmFiaWxpdHkobWl4ZWQgYXJnKQoreyBpbnQgICAgIGk7CisgIG1hcHBpbmcgcmVzaW1hcDsKKyAgbWl4ZWQgICBvbGQ7CisKKyAgaWYgKCAhcG9pbnRlcnAoYXJnKSApCisgICAgYXJnPSh7YXJnfSk7CisKKyAgaWYgKCAhbWFwcGluZ3AocmVzaW1hcD1RdWVyeShQX1JFU0lTVEFOQ0VfU1RSRU5HVEhTKSkgKQorICAgIHJlc2ltYXA9KFtdKTsKKworICBpZiAoIHBvaW50ZXJwKG9sZD1RdWVyeVByb3AoUF9WVUxORVJBQklMSVRZKSkgKQorICAgIGZvciAoIGk9c2l6ZW9mKG9sZCktMSA7IGk+PTAgOyBpLS0gKQorICAgICAgcmVzaW1hcFtvbGRbaV1dPSgxLjArKChmbG9hdClyZXNpbWFwW29sZFtpXV0pKSowLjUtMS4wOworCisgIGZvciAoIGk9c2l6ZW9mKGFyZyktMSA7IGk+PTAgOyBpLS0gKQorICAgIHJlc2ltYXBbYXJnW2ldXT0oMS4wKygoZmxvYXQpcmVzaW1hcFthcmdbaV1dKSkqMi4wLTEuMDsKKworICBTZXRQcm9wKFBfUkVTSVNUQU5DRV9TVFJFTkdUSFMscmVzaW1hcCk7CisKKyAgcmV0dXJuIFNldChQX1ZVTE5FUkFCSUxJVFksYXJnKTsKK30KKworCisvKioga2lsbCAtIEthbXBmIHN0YXJ0ZW4uCisgKiBGdWVndCBvYiBkZXIgRmVpbmRlc2xpc3RlIGhpbnp1LgorICovCitwdWJsaWMgaW50IEtpbGwob2JqZWN0IG9iKQoreyBpbnQgICByZXMsIGFyZW5hOworICBpbnR8c3RyaW5nIG5vX2F0dGFjazsKKworICBpZiAoICFvYmplY3RwKG9iKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCBvYi0+UXVlcnlQcm9wKFBfR0hPU1QpICkKKyAgeworICAgIHRlbGxfb2JqZWN0KE1FLG9iLT5OYW1lKFdFUikrIiBpc3QgZG9jaCBzY2hvbiB0b3QhXG4iKTsKKyAgICByZXR1cm4gLTE7CisgIH0KKworICBpZiAoIG5vX2F0dGFjayA9IG9iLT5RdWVyeVByb3AoUF9OT19BVFRBQ0spICkKKyAgeworICAgIGlmICggc3RyaW5ncChub19hdHRhY2spICkKKyAgICAgIHRlbGxfb2JqZWN0KE1FLCBub19hdHRhY2spOworICAgIGVsc2UKKyAgICAgIHRlbGxfb2JqZWN0KE1FLCBvYi0+TmFtZShXRVIsMSkrIiBsYWVzc3Qgc2ljaCBuaWNodCBhbmdyZWlmZW4hXG4iKTsKKworICAgIHJldHVybiAtMjsKKyAgfQorCisgIGlmICggUXVlcnlQcm9wKFBfTk9fQVRUQUNLKSApCisgICAgcmV0dXJuIC0zOworCisgIHJlcz1JbnNlcnRFbmVteShvYik7CisgIGlmIChyZXMpCisgICAgdGVsbF9vYmplY3QoTUUsICJPay5cbiIpOworICBlbHNlIGlmIChJc0VuZW15KG9iKSkKKyAgICB0ZWxsX29iamVjdChNRSwgIkphamFqYSwgbWFjaHN0IER1IGRvY2ggc2Nob24hXG4iKTsKKyAgLy9lbHNlIC8va2VpbiBndWVsdGlnZXIgRmVpbmQsIG9iIHd1cmRlIG5pY2h0IGVpbmdldHJhZ2VuLgorCisgIGlmICggIXJlcyApCisgICAgcmV0dXJuIC00OyAgLy8gbmljaHQgYWVuZGVybiBvaG5lIEtpbGwgaW4gcGxheWVyL2NvbWJhdC5jCisKKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyBpbnQgSW5zZXJ0U2luZ2xlRW5lbXkob2JqZWN0IG9iKQoreworICAgIGlmICggIWxpdmluZyhvYikgKQorICAgICAgICByZXR1cm4gMDsKKworICAgIC8vIFdpZSBsYW5nZSB2ZXJmb2xndCBkaWVzZXMgTGl2aW5nPyBXZW5uIFByb3AgbmljaHQgZ2VzZXR6dCBvZGVyIAorICAgIC8vIHVuZ3VlbHRpZywgZC5oLiBrZWluIGludCBvZGVyIDw9IDAsIGRhbm4gd2lyZCBkaWUgRGVmYXVsdHplaXQgZ2Vub21tZW4uCisgICAgaW50IGh1bnR0aW1lID0gKGludClRdWVyeVByb3AoUF9IVU5UVElNRSk7CisgICAgaHVudHRpbWUgPSAoaW50cChodW50dGltZSkgJiYgaHVudHRpbWUgPiAwKSA/IAorICAgICAgICAgICAgICAgICBodW50dGltZSAvIF9fSEVBUlRfQkVBVF9JTlRFUlZBTF9fIDogSFVOVFRJTUU7CisKKyAgICAvLyBBdWNoIHdlbm4gZWluIE9iamVrdCBzY2hvbiBhbHMgR2VnbmVyIGVpbmdldHJhZ2VuIGlzdCwgdHJvdHpkZW0gZGllCisgICAgLy8gSFVOVFRJTUUgZXJuZXVlcm4uIERhcyAicmV0dXJuIDA7IiBtdXNzIGFiZXIgYmxlaWJlbiwgZGEgZGVyIEdlZ25lcgorICAgIC8vIGphIG5pY2h0IG5ldSBpc3QuCisgICAgLy8KKyAgICAvLyAwOS4xMi4yMDAwLCBUaWFtYWsKKyAgICBpZiAoIG1lbWJlciggZW5lbWllcywgb2IgKSApIHsKKyAgICAgICAgZW5lbWllc1tvYixFTkVNWV9IVU5UVElNRV0gPSBodW50dGltZTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgaWYgKCAob2I9PU1FKSB8fCBRdWVyeVByb3AoUF9OT19BVFRBQ0spCisgICAgICAgICB8fCAhb2JqZWN0cChvYikgfHwgKG9iLT5RdWVyeVByb3AoUF9OT19BVFRBQ0spKQorICAgICAgICAgfHwgKG9iLT5RdWVyeVByb3AoUF9HSE9TVCkpICkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBvYmplY3QgdGVhbTsKKyAgICBpZiAoICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgfHwgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvYikgKQorICAgICAgICAgJiYgb2JqZWN0cCh0ZWFtPVF1ZXJ5KFBfVEVBTSkpICYmICh0ZWFtPT0ob2ItPlF1ZXJ5KFBfVEVBTSkpKSApCisgICAgICAgIHJldHVybiAwOworCisgICAgc2V0X2hlYXJ0X2JlYXQoMSk7CisKKyAgICBsYXN0X2F0dGFja19tc2c9MDsKKworICAgIGVuZW1pZXNbb2IsRU5FTVlfSFVOVFRJTUVdID0gaHVudHRpbWU7CisgICAgU2V0KFBfTEFTVF9DT01CQVRfVElNRSx0aW1lKCkpOworCisgICAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyBpbnQgSW5zZXJ0RW5lbXkob2JqZWN0IG9iKQoreyBpbnQgcmVzOworCisgIGlmICggcmVzPUluc2VydFNpbmdsZUVuZW15KG9iKSApCisgICAgSW5zZXJ0RW5lbXlUZWFtKG9iKTsKKworICByZXR1cm4gcmVzOworfQorCitwdWJsaWMgb2JqZWN0IFF1ZXJ5UHJlZmVyZWRFbmVteSgpCit7IGludCAgICBzeixyOworICA8aW50fG9iamVjdD4qICBwcmVmOworICBvYmplY3QgZW5lbXk7CisKKyAgZW5lbXk9MDsKKyAgaWYgKCBwb2ludGVycChwcmVmPVF1ZXJ5UHJvcChQX1BSRUZFUkVEX0VORU1ZKSkgJiYgKChzej1zaXplb2YocHJlZikpPjEpCisgICAgICAmJiBpbnRwKHI9cHJlZlswXSkgJiYgKHJhbmRvbSgxMDApPHIpICkKKyAgeworICAgIGVuZW15PXByZWZbMStyYW5kb20oc3otMSldOworCisgICAgaWYgKCAhb2JqZWN0cChlbmVteSkgKQorICAgIHsKKyAgICAgIHByZWYtPSh7ZW5lbXl9KTsKKworICAgICAgaWYgKCBzaXplb2YocHJlZik8MiApCisgICAgICAgIHByZWY9MDsKKworICAgICAgU2V0UHJvcChQX1BSRUZFUkVEX0VORU1ZLHByZWYpOworCisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAoICFJc0VuZW15KGVuZW15KSApCisgICAgICByZXR1cm4gMDsKKyAgfQorCisgIHJldHVybiBlbmVteTsKK30KKworcHVibGljIG9iamVjdCAqUHJlc2VudEVuZW1pZXMoKSB7CisKKyAgb2JqZWN0ICpoZXJlPSh7fSk7CisgIG9iamVjdCAqbmV0ZGVhZD0oe30pOworICBtaXhlZCBub19hdHRhY2s7CisgIGZvcmVhY2gob2JqZWN0IHBsOiBlbmVtaWVzKSB7CisgICAgaWYgKG5vX2F0dGFjayA9IChtaXhlZClwbC0+UXVlcnlQcm9wKFBfTk9fQVRUQUNLKSkgeworICAgICAgbV9kZWxldGUoZW5lbWllcyxwbCk7CisgICAgICAvLyBVbmQgYXVjaCBpbSBHZWduZXIgYXVzdHJhZ2VuLCBzb25zdCBoYXV0IGRlciB3ZWl0ZXIgenUgdW5kIGRpZXNlcworICAgICAgLy8gTGl2aW5nIHdlaHJ0IHNpY2ggbmljaHQuIChaZXNzdHJhLCAyNi4xMS4yMDA2KQorICAgICAgaWYgKHN0cmluZ3Aobm9fYXR0YWNrKSkgeworICAgICAgICB0ZWxsX29iamVjdChNRSwgbm9fYXR0YWNrKTsKKyAgICAgICAgcGwtPlN0b3BIdW50Rm9yKE1FLCAxKTsKKyAgICAgIH0KKyAgICAgIGVsc2UgcGwtPlN0b3BIdW50Rm9yKE1FLCAwKTsKKyAgICB9CisgICAgZWxzZSBpZiAoIGVudmlyb25tZW50KCk9PWVudmlyb25tZW50KHBsKSApCisgICAgeworICAgICAgaWYgKCBpbnRlcmFjdGl2ZShwbCkgfHwgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUocGwpICkKKyAgICAgICAgaGVyZSs9KHtwbH0pOworICAgICAgZWxzZQorICAgICAgICBuZXRkZWFkKz0oe3BsfSk7CisgICAgfQorICB9CisKKyAgaWYgKCAhc2l6ZW9mKGhlcmUpICkgLy8gTmV0enRvdGUgc2luZCBudXIgRmVpbmRlLCBmYWxscyBrZWluZSBhbmRlcmVuIGRhIHNpbmQKKyAgICByZXR1cm4gbmV0ZGVhZDsKKworICByZXR1cm4gaGVyZTsKK30KKworcHVibGljIHZhcmFyZ3Mgb2JqZWN0IFNlbGVjdEVuZW15KG9iamVjdCAqaGVyZSkKK3sgb2JqZWN0IGVuZW15OworCisgIGlmICggIXBvaW50ZXJwKGhlcmUpICkKKyAgICBoZXJlPVByZXNlbnRFbmVtaWVzKCk7CisKKyAgaWYgKCAhc2l6ZW9mKGhlcmUpICkKKyAgICByZXR1cm4gMDsKKworICBpZiAoICFvYmplY3RwKGVuZW15PVF1ZXJ5UHJlZmVyZWRFbmVteSgpKQorICAgICAgfHwgKGVudmlyb25tZW50KGVuZW15KSE9ZW52aXJvbm1lbnQoKSkgKQorICAgIGVuZW15PWhlcmVbcmFuZG9tKHNpemVvZihoZXJlKSldOworCisgIHJldHVybiBlbmVteTsKK30KKworcHJvdGVjdGVkIHZvaWQgaGVhcnRfYmVhdCgpIHsKKyAgaW50IGhiczsgCisgIC8vIGxlaWRlciBydWZlbiB2aWVsZSBMZXV0ZSBlaW5mYWNoIGRhcyBnZWVyYnRlIGhlYXJ0X2JlYXQoKSBvYndvaGwgc2llCisgIC8vIHNjaG9uIHRvdCBzaW5kIHVuZCBkYW1pdCBkYXMgT2JqZWt0IHplcnN0b2VydCBpc3QuCisgIGlmICghbGl2aW5nKHRoaXNfb2JqZWN0KCkpKQorICAgICAgcmV0dXJuOworCisgIC8vIFBhcmFseXNlIHBydWVmZW4sIGdnZi4gcmVkdXppZXJlbgorICBpbnQgZGlzX2F0dGFjayA9IFF1ZXJ5UHJvcChQX0RJU0FCTEVfQVRUQUNLKTsKKyAgaWYgKCBpbnRwKGRpc19hdHRhY2spICYmIChkaXNfYXR0YWNrID4gMCkgKQorICB7CisgICAgICBTZXRQcm9wKFBfRElTQUJMRV9BVFRBQ0ssIC0tZGlzX2F0dGFjayk7CisgIH0KKworICAvLyBBdHRhY2tlbiBlcm1pdHRlbG46IFNBX1NQRUVEICsgUmVzdCBhdXMgZGVtIGxldHp0ZW4gSEIKKyAgaGJzID0gcmVtYWluaW5nX2hlYXJ0X2JlYXRzICsgUXVlcnlTa2lsbEF0dHJpYnV0ZShTQV9TUEVFRCk7CisgIGlmICggaGJzIDw9IDAgKQorICAgIGhicyA9IDEwMDsgCisKKyAgLy8gUF9BVFRBQ0tfQlVTWSBiZXN0aW1tZW4KKyAgaWYgKCBhdHRhY2tfYnVzeSA+IDk5KSAKKyAgIGF0dGFja19idXN5ID0gMTAwICsgaGJzOworICBlbHNlCisgICAgYXR0YWNrX2J1c3kgKz0gMTAwICsgaGJzOworICAvLyBtZWhyIGZ1ZXIgU2VoZXIuLi4KKyAgaWYgKCBJU19TRUVSKE1FKSApCisgICAgYXR0YWNrX2J1c3krPSgxMDArUXVlcnlQcm9wKFBfTEVWRUwpKTsgCisgIC8vIG1heC4gNTAwLCBkLmguIDUgQXR0YWNrZW4KKyAgaWYgKCBhdHRhY2tfYnVzeT41MDAgKQorICAgIGF0dGFja19idXN5PTUwMDsKKworICAvLyB1bmdhbnp6YWhsaWdlbiBSZXN0IGZ1ZXIgbmFlY2hzdGVuIEhCIHNwZWljaGVybgorICByZW1haW5pbmdfaGVhcnRfYmVhdHMgPSBoYnMgJSAxMDA7CisgIGhicyAvPSAxMDA7IC8vIGdhbnplIEF0dGFja2VuLiA7LSkKKworICBpZiAoIGhicyA+IDEwICkgLy8gbmljaHQgbWVociBhbHMgMTAgQXR0YWNrZW4uCisgICAgaGJzID0gMTA7IAorCisgIC8vIEZhbGxzIGplbWFuZCBzZWl0IGRlbSBsZXR6dGVuIEhCIGluIGRpZXNlbSBMaXZpbmcgdm9uIGF1c3NlbiBBdHRhY2soKQorICAvLyBnZXJ1ZmVuIGhhdCAobmljaHQgRXh0cmFBdHRhY2soKSksIHdpcmQgamV0enQgd2FzIGFiZ2V6b2dlbi4KKyAgaGJzIC09IG5vX21vcmVfYXR0YWNrczsKKyAgbm9fbW9yZV9hdHRhY2tzID0gMDsKKworICAvLyBXaWUgbGFuZ2UgdmVyZm9sZ3QgZGllc2VyIE5QQz8gV2VubiBQcm9wIG5pY2h0IGdlc2V0enQgb2RlciB1bmd1ZWx0aWcsCisgIC8vIGQuaC4ga2VpbiBpbnQgb2RlciA8PSAwLCBkYW5uIHdpcmQgZGllIERlZmF1bHR6ZWl0IGdlbm9tbWVuLgorICBpbnQgaHVudHRpbWUgPSAoaW50KVF1ZXJ5UHJvcChQX0hVTlRUSU1FKTsKKyAgaHVudHRpbWUgPSAoaW50cChodW50dGltZSkgJiYgaHVudHRpbWUgPiAwKSA/IAorICAgICAgICAgICAgICBodW50dGltZSAvIF9fSEVBUlRfQkVBVF9JTlRFUlZBTF9fIDogSFVOVFRJTUU7CisgIC8vIGVyc3RtYWwgZGllIEh1bnR0aW1lcyBkZXIgR2VnbmVyIGFrdHVhbGlzaWVyZW4gdW5kIG5lYmVuYmVpIGRpZQorICAvLyBhbndlc2VuZGVuIEZlaW5kZSBtZXJrZW4uIEF1c3NlcmRlbSBnZ2YuIEthbXBmIGFiYnJlY2hlbiwgd2VubgorICAvLyBQX05PX0FUVEFDSyBnZXNldHp0IGlzdC4KKyAgLy8gZWlnZW50bGljaCBpc3QgZGllc2UgZ2FuemUgU2NobGVpZmUgZmFzdCBkYXMgZ2xlaWNoZSB3aWUKKyAgLy8gUHJlc2VudEVuZW1pZXMoKSwgYWJlciBsZWlkZXIgbXVlc3NlbiBqYSBkaWUgSHVudHRpbWVzIGFrdHVsaXNpZXJ0IHdlcmRlLAorICAvLyBkYWhlciBrYW5uIG1hbiBuaWNodCBkaXJla3QgUHJlc2VudEVuZW1pZXMoKSBuZWhtZW4uCisgIC8vIFRPRE86IERpZXNlIFNjaGxlaWZlIHVuZCBQcmVzZW50RW5taWVzKCkgaXJnZW5kd2llIHZlcmVpbmlnZW4uCisgIG9iamVjdCAqbmV0ZGVhZD0oe30pOworICBvYmplY3QgKmhlcmU9KHt9KTsKKyAgb2JqZWN0IGVuZW15OworICBtaXhlZCBub19hdHRhY2s7CisgIGZvcmVhY2goZW5lbXksIGludCBodGltZTogJmVuZW1pZXMpIHsgLy8gS2V5cyBpbiBlbmVteQorICAgIC8vIGdnZi4gTWVsZHVuZ2VuIGF1c2dlYmVuIHVuZCBHZWduZXIgYXVzdHJhZ2VuIHVuZCBkaWVzZXMgTGl2aW5nIGJlaW0KKyAgICAvLyBHZWduZXIgYXVzdHJhZ2VuLgorICAgIGlmIChub19hdHRhY2s9ZW5lbXktPlF1ZXJ5UHJvcChQX05PX0FUVEFDSykpIHsKKyAgICAgIG1fZGVsZXRlKGVuZW1pZXMsZW5lbXkpOworICAgICAgICBpZiAoIHN0cmluZ3Aobm9fYXR0YWNrKSApIHsKKyAgICAgICAgICAgIHdyaXRlKCBub19hdHRhY2sgKTsKKyAgICAgICAgICAgIGVuZW15LT5TdG9wSHVudEZvciggTUUsIDEgKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICBlbmVteS0+U3RvcEh1bnRGb3IoIE1FLCAwICk7CisgICAgfQorICAgIGVsc2UgaWYgKCBlbnZpcm9ubWVudCgpPT1lbnZpcm9ubWVudChlbmVteSkgKSB7CisgICAgICAvLyBHZWduZXIgYW53ZXNlbmQsIGFscyBGZWluZCBtZXJrZW4uLi4KKyAgICAgIGlmICggaW50ZXJhY3RpdmUoZW5lbXkpIHx8ICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGVuZW15KSApCisgICAgICAgIGhlcmUrPSh7ZW5lbXl9KTsKKyAgICAgIGVsc2UKKyAgICAgICAgbmV0ZGVhZCs9KHtlbmVteX0pOworICAgICAgLy8gLi4uIHVuZCBIdW50dGltZSBlcm5ldWVybi4KKyAgICAgIGh0aW1lID0gaHVudHRpbWU7CisgICAgfQorICAgIC8vIEZlaW5kIG5pY2h0IGFud2VzZW5kLiBUaW1lciBkZWtyZW1lbnRpZXJlbiB1bmQgRmVpbmQgYXVzdHJhZ2VuLCB3ZW5uCisgICAgLy8gSmFnZHplaXQgYWJnZWxhdWZlbi4KKyAgICBlbHNlIGlmICggKC0taHRpbWUpIDw9IDAgKQorICAgICAgU3RvcEh1bnRGb3IoZW5lbXkpOworICB9CisgIC8vIE5ldHp0b3RlIHNpbmQgbnVyIEZlaW5kZSwgd2VubiBzb25zdCBrZWluZSBkYSBzaW5kLgorICBpZiAoICFzaXplb2YoaGVyZSkgKQorICAgIGhlcmU9bmV0ZGVhZDsKKworICAvLyBzY2hvbm1hbCBhYmZyYWdlbiwgb2IgZWluIFNwZWxsIHZvcmJlcmVpdGV0IHdpcmQuCisgIG1peGVkIHBzcGVsbD1RdWVyeVByb3AoUF9QUkVQQVJFRF9TUEVMTCk7CisKKyAgLy9EYSBoYnMgMCB1bmQgbm9fbW9yZV9hdHRhY2tzIGR1cmNoIGVpbmVuIG1hbnVlbGxlbiBBdWZydWYgdm9uIEF0dGFjaygpIGltCisgIC8vU3BpZWxlciA+MCBzZWluIGthbm4sIGthbm4gamV0enQgaGJzIDwwIHNlaW4uIChzLm8uKQorICBpZiAoaGJzID4gMCAmJiBzaXplb2YoaGVyZSkpIHsKKyAgICBmb3JlYWNoKGludCBpOiBoYnMpIHsKKyAgICAgIC8vIEZlaW5kIGluIE5haGthbXBmcmVpY2h3ZWl0ZSBmaW5kZW4KKyAgICAgIGlmICggb2JqZWN0cChlbmVteT1TZWxlY3ROZWFyRW5lbXkoaGVyZSkpICkgeworICAgICAgICAvLyBGbHVjaHQgZXJ3dWVuc2NodD8KKyAgICAgICAgaWYgKCBRdWVyeVByb3AoUF9XSU1QWSkgPiBRdWVyeVByb3AoUF9IUCkgKSB7CisgICAgICAgICAgRmxlZSgpOworICAgICAgICAgIC8vIEZsdWNodCBnZWx1bmdlbj8KKyAgICAgICAgICBpZiAoIGVuZW15ICYmIChlbnZpcm9ubWVudChlbmVteSkhPWVudmlyb25tZW50KCkpICkgeworICAgICAgICAgICAgaGVyZSA9IDA7IC8vIG5hZWNoc3RlIFJ1bmRlIG5ldWUgRmVpbmRlIHN1Y2hlbgorICAgICAgICAgICAgZW5lbXkgPSAwOworICAgICAgICAgICAgY29udGludWU7IC8vIGtlaW4gS2FtcGYsIFJ1bmRlIHVlYmVyc3ByaW5nZW4KKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICAvLyBrZWluZSBGZWluZGUgZ2VmdW5kZW4uLi4gQWJicmVjaGVuLgorICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIC8vIFBhcmFseXNlIGdlc2V0enQ/IC0+IEFiYnJlY2hlbi4gRGllc2VzIFBydWVmdW5nIG11c3MgaGllciBwYXNzaWVyZW4sCisgICAgICAvLyBkYW1pdCBnZ2YuIGRpZSBhdXRvbWF0aXNjaGUgRmx1Y2h0IGRlcyBMZWJld2VzZW5zIGR1cmNoZ2VmdWVocnQgd2lyZCwKKyAgICAgIC8vIGF1Y2ggd2VubiBlcyBwYXJhbHlzaWVydCBpc3QuCisgICAgICBpZiAoZGlzX2F0dGFjayA+IDApIGJyZWFrOworCisgICAgICAvLyBLYW1wZiBkdXJjaCBTcGVsbC1QcmVwYXJlIGJsb2NraWVydD8KKyAgICAgIC8vIEtlaW5lIGdlbmF1ZSBBYmZyYWdlLCB3aXJkIHNwYWV0ZXIgbm9jaCBnZW5hdSBnZXBydWVmdC4KKyAgICAgIGlmICggcHNwZWxsICYmIFF1ZXJ5UHJvcChQX0dVSUxEX1BSRVBBUkVCTE9DSykgKQorICAgICAgICBicmVhazsgLy8ga2VpbmUgQW5ncmlmZmUgaW4gZGllc2VtIEhCLgorICAgICAgLy8gd2VubiBGZWluZCBkYTogaGl0J2VtIGhhcmQuCisgICAgICBpZiAoIG9iamVjdHAoZW5lbXkpICkKKyAgICAgICAgQXR0YWNrKGVuZW15KTsKKyAgICAgIC8vIGdnZi4gaGF0IEF0dGFjaygpIG5vX21vcmVfYXR0YWNrcyBnZXNldHp0LiBadXJ1ZWNrc2V0emVuCisgICAgICBub19tb3JlX2F0dGFja3MgPSAwOworICAgICAgLy8gbmFlY2hzdGUgS2FtcGZydW5kZSBuZXVlIEZlaW5kZSBzdWNoZW4KKyAgICAgIGhlcmUgPSAwOworICAgIH0gIC8vIGZvcmVhY2gKKyAgfQorCisgIG5vX21vcmVfYXR0YWNrcz0wOworCisgIC8vIElzdCBlaW4gU3BlbGwgaW4gVm9yYmVyZWl0dW5nIHVuZCBldnRsLiBqZXR6dCBmZXJ0aWcgdm9yYmVyZWl0ZXQ/CisgIGlmICggcG9pbnRlcnAocHNwZWxsKQorICAgICAgJiYgKHNpemVvZihwc3BlbGwpPj0zKSAmJiBpbnRwKHBzcGVsbFswXSkgJiYgc3RyaW5ncChwc3BlbGxbMV0pICkgeworICAgIGlmICggdGltZSgpPj1wc3BlbGxbMF0gKSAvLyBLYW5uIGRlciBTcHJ1Y2ggamV0enQgYXVzZ2VmdWVocnQgd2VyZGVuPworICAgIHsKKyAgICAgIFVzZVNwZWxsKHBzcGVsbFsyXSxwc3BlbGxbMV0pOyAvLyBEYW5uIGxvcworICAgICAgU2V0UHJvcChQX1BSRVBBUkVEX1NQRUxMLDApOworICAgIH0KKyAgfQorICBlbHNlIGlmICggcHNwZWxsICkgLy8gVW5icmF1Y2hiYXJlciBXZXJ0LCBsb2VzY2hlbgorICAgIFNldFByb3AoUF9QUkVQQVJFRF9TUEVMTCwwKTsKKworfSAvLyBFbmRlIGhlYXJ0X2JlYXQKKworLy8gd2lyZCB2b24gTlBDIGdlcnVmZW4sIGRpZSBIZWFydGJlYXRzIG5hY2hob2xlbiB1bmQgZGFiZWkgZGllIEh1bnR0aW1lcyB1bQorLy8gZGllIEFuemFobCB2ZXJwYXNzdGVyIEhlYXJ0YmVhdHMgcmVkdXppZXJlbiBtdWVzc2VuLgorLy8gV2lyZCB2b24gU3BpZWxlcm9iamVrdGVuIGdlcnVmZW4sIHdlbm4gc2llIG5hY2ggJ3NjaGxhZmUgZWluJyBhdWZ3YWNoZW4sIHVtCisvLyBkaWUgbm90d2VuZGlnZSBBbnphaGwgYW4gSEIgaGllciBhYnp1emllaGVuIHVuZCBnZ2YuIGRpZSBGZWluZGUgenUgZXhwaXJlbiwKKy8vIGRhIFNwaWVsZXIgamEgbmV0enRvdCBrZWluZW4gSGVhcnRiZWF0IGhhYmVuLgorcHJvdGVjdGVkIHZvaWQgdXBkYXRlX2h1bnRfdGltZXMoaW50IGJlYXRzKSB7CisgIGlmICghbWFwcGluZ3AoZW5lbWllcykpIHJldHVybjsKKyAgZm9yZWFjaChvYmplY3QgZW4sIGludCBodGltZTogJmVuZW1pZXMpIHsgLy8gTWFwcGluZy1LZXlzIGluIGVuCisgICAgaHRpbWUgLT0gYmVhdHM7CisgICAgaWYgKCBodGltZSA8PSAwICkKKyAgICAgIFN0b3BIdW50Rm9yKGVuKTsKKyAgfQorfQorCitwdWJsaWMgaW50IElzRW5lbXkob2JqZWN0IHdlcikKK3sKKyAgcmV0dXJuIChtZW1iZXIoZW5lbWllcyx3ZXIpKTsKK30KKworcHVibGljIHZvaWQgU3RvcEh1bnRUZXh0KG9iamVjdCBhcmcpCit7CisgIHRlbGxfb2JqZWN0KGFyZywKKyAgICBOYW1lKFdFUiwxKSsiICIrKFF1ZXJ5UHJvcChQX1BMVVJBTCk/ImphZ2VuICI6ImphZ3QgIikrCisgICAgICAgICAgICAgICAoYXJnLT5RdWVyeVByb3AoUF9QTFVSQUwpPyJFdWNoIjoiRGljaCIpKyIgbmljaHQgbWVoci5cbiIpOworICB0ZWxsX29iamVjdChNRSwoUXVlcnlQcm9wKFBfUExVUkFMKT8iSWhyIGphZ3QgIjoiRHUgamFnc3QgIikrCisgICAgICAgICAgICAgICAgIGFyZy0+bmFtZShXRU4sMSkrIiBuaWNodCBtZWhyLlxuIik7Cit9CisKK3B1YmxpYyB2YXJhcmdzIGludCBTdG9wSHVudEZvcihvYmplY3QgYXJnLCBpbnQgc2lsZW50KQoreworICBpZiAoICFvYmplY3RwKGFyZykgfHwgIUlzRW5lbXkoYXJnKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCFzaWxlbnQpCisgICAgU3RvcEh1bnRUZXh0KGFyZyk7CisKKyAgbV9kZWxldGUoZW5lbWllcyxhcmcpOworICBsYXN0X2F0dGFja19tc2c9MDsKKworICByZXR1cm4gMTsKK30KKworLy8gQmVncnVlc3N1bmdzc2NobGFnIG51ciBlaW5tYWwgcHJvIEhCCitwdWJsaWMgdm9pZCBBdHRhY2syKG9iamVjdCBlbmVteSkKK3sKKyAgaWYgKCBhdHQyX3RpbWUgPiB0aW1lKCkgKQorICAgIHJldHVybjsKKworICBhdHQyX3RpbWU9dGltZSgpICsgX19IRUFSVF9CRUFUX0lOVEVSVkFMX187CisgIEF0dGFjayhlbmVteSk7Cit9CisKKy8vIEZ1ZXIgZXZ0bC4gQXR0YWNrLUFlbmRlcnVuZ2VuLCBvaG5lIGRhc3MgbWFuIGdsZWljaCBkYXMgZ2FuemUKKy8vIEF0dGFjayB1ZWJlcmxhZ2VybiBtdXNzOgorcHJvdGVjdGVkIHZvaWQgSW50ZXJuYWxNb2RpZnlBdHRhY2sobWFwcGluZyBhaW5mbykKK3sKKyAgcmV0dXJuOyAvLyBWb3JlcnN0IQorLyoKKyAgaW50ICAgZmFjOworICBtaXhlZCByZXM7CisKKyAgZmFjPTEwMDsKKworICBpZiAoQ2Fubm90U2VlKDEpKQorICAgIGZhYyAtPSA1MDsKKworICAvLyBXZWl0ZXJlIE1hbGk/CisKKyAgaWYgKGZhYzwxMDApCisgICAgYWluZm9bU0lfU0tJTExEQU1BR0VdID0gYWluZm9bU0lfU0tJTExEQU1BR0VdKmZhYy8xMDA7CisgIC8vIEZlcnRpZworKi8KK30KKworLy8gQXVzZnVlaHJlbiBFaW5lcyBBbmdyaWZmcyBhdWNoIHdlbm4gZXMgYmVyZWl0cyBlaW5lbiBBbmdyaWZmCisvLyBpbiBkaWVzZXIgUnVuZGUgZ2VnZWJlbiBoYXQuIERpZXNlciBBbmdyaWZmIHdpcmQgYXVjaCBuaWNodAorLy8gZ2V6YWVobHQuIERpZSBOdXR6dW5nIGRpZXNlciBGdW5rdGlvbiBpc3QgbnVyIGZ1ZXIgU3BlemlhbGZhZWxsZQorLy8gZ2VkYWNodCB1bmQgaW1tZXIgQkFMQU5DRVBGTElDSFRJRyEKK3ZhcmFyZ3MgcHVibGljIHZvaWQgRXh0cmFBdHRhY2sob2JqZWN0IGVuZW15LCBpbnQgaWdub3JlX3ByZXZpb3VzKQoreworICBpbnQgc2F2ZWRfbm9fbW9yZV9hdHRhY2tzOworCisgIC8vIEVyc3RzY2hsYWdzaW5mbyBzcGVpY2hlcm4uCisgIHNhdmVkX25vX21vcmVfYXR0YWNrcyA9IG5vX21vcmVfYXR0YWNrczsKKworICAvLyBCZWkgQmVkYXJmIGJpc2hlciBzY2hvbiBkdXJjaGdlZnVlaHJ0ZSBFcnN0c2NobGFlZ2UgaWdub3JpZXJlbgorICBpZiAoaWdub3JlX3ByZXZpb3VzKSBub19tb3JlX2F0dGFja3M9MDsKKworICAvLyBOb3JtYWxlbiBBbmdyaWZmIGR1cmNoZnVlaHJlbgorICBBdHRhY2sgKGVuZW15KTsKKworICAvLyBHZXNwZWljaGVydGVuIFdlcnQgenVydWVja3NldHplbgorICBub19tb3JlX2F0dGFja3MgPSBzYXZlZF9ub19tb3JlX2F0dGFja3M7CisKKyAgcmV0dXJuOworfQorCitwdWJsaWMgdm9pZCBBdHRhY2sob2JqZWN0IGVuZW15KQoreworICBjbG9zdXJlIGNsOworICBtaXhlZCAgIHJlczsKKyAgbWFwcGluZyBhaW5mbzsKKyAgbWFwcGluZyBlZGVmZW5kaW5mbzsgLy8gZXJ3ZWl0ZXJ0ZSBEZWZlbmQtSW5mb3MKKyAgbWl4ZWQgaG9va0RhdGE7CisgIG1peGVkIGhvb2tSZXM7CisKKyAgaWYgKCBub19tb3JlX2F0dGFja3MgfHwgUXVlcnlQcm9wKFBfR0hPU1QpIHx8IAorICAgICAgIW9iamVjdHAoZW5lbXkpIHx8ICFvYmplY3RwKHRoaXNfb2JqZWN0KCkpIHx8IAorICAgICAgKFF1ZXJ5UHJvcChQX0RJU0FCTEVfQVRUQUNLKSA+IDApIHx8IGVuZW15LT5RdWVyeVByb3AoUF9OT19BVFRBQ0spIHx8IAorICAgICAgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkgJiYgIWludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpKSApCisgICAgcmV0dXJuOworCisgIGVkZWZlbmRpbmZvPShbXSk7CisKKyAgU2V0KFBfTEFTVF9DT01CQVRfVElNRSx0aW1lKCkpOworCisgIC8vIGlua3JlbWVudGllcmVuLiBEaWVzZSBWYXJpYWJsZSB3aXJkIGltIEhCIG5hY2ggZGVuIEFuZ3JpZmZlbiBnZW51bGx0LgorICAvLyBEaWVzZSBWYXJpYWJsZSB3aXJkIGltIG5hZWNoc3RlbiBIZWFydGJlYXQgdm9uIGRlciBBbnphaGwgYW4gdmVyZnVlZ2JhcmVuCisgIC8vIEFuZ3JpZmZlbiBkZXMgTGl2aW5ncyBhYmdlem9nZW4uIERpZXMgYmVydWVja3NpY2h0aWd0IGFsc28gendpc2NoZW4gZGVuCisgIC8vIEhCcyAoei5CLiBleHRlcm4pIGdlcnVmZW5lIEF0dGFja3MoKS4KKyAgbm9fbW9yZV9hdHRhY2tzKys7CisKKyAgLy8gV2lyZCBkYXMgQXR0YWNrIGR1cmNoIGVpbmVuIHRlbXBvcmFlcmVuIEF0dGFjay1Ib29rIGVyc2V0enQ/CisgIGlmICggcmVzPVF1ZXJ5UHJvcChQX1RNUF9BVFRBQ0tfSE9PSykgKQorICB7CisgICAgaWYgKCBwb2ludGVycChyZXMpICYmIChzaXplb2YocmVzKT49MykgJiYgaW50cChyZXNbMF0pICYmICh0aW1lKCk8cmVzWzBdKQorICAgICAgICAmJiBvYmplY3RwKHJlc1sxXSkgJiYgc3RyaW5ncChyZXNbMl0pICkKKyAgICB7CisgICAgICBpZiAoICEocmVzPWNhbGxfb3RoZXIocmVzWzFdLHJlc1syXSxlbmVteSkpICkKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBlbHNlCisgICAgICBTZXRQcm9wKFBfVE1QX0FUVEFDS19IT09LLDApOworICB9CisKKyAgLy8gdHJpZ2dlciBhdHRhY2sgaG9vaworICBob29rRGF0YT0oe2VuZW15fSk7CisgIGhvb2tSZXM9SG9va0Zsb3coSF9IT09LX0FUVEFDSyxob29rRGF0YSk7CisgIGlmKGhvb2tSZXMgJiYgcG9pbnRlcnAoaG9va1JlcykgJiYgc2l6ZW9mKGhvb2tSZXMpPkhfUkVUREFUQSl7CisgICAgaWYoaG9va1Jlc1tIX1JFVENPREVdPT1IX0NBTkNFTExFRCl7CisgICAgICByZXR1cm47CisgICAgfQorICB9CisKKyAgYWluZm8gPSAoWyBTSV9FTkVNWSA6IGVuZW15LAorICAgICAgICAgICAgIFNJX1NQRUxMIDogMCwKKyAgICAgICAgICAgXSk7CisKKyAgaWYgKCBvYmplY3RwKGFpbmZvW1BfV0VBUE9OXT1RdWVyeVByb3AoUF9XRUFQT04pKSApCisgIHsKKyAgICBhaW5mb1tQX1dFQVBPTl0tPlRha2VGbGF3KGVuZW15KTsKKworICAgIC8vIEFiZnJhZ2UgZnVlciBkZW4gRmFsbCwgZGFzcyBXYWZmZSBkdXJjaCBkYXMgVGFrZUZsYXcoKSB6ZXJzdG9lcnQKKyAgICAvLyB3dXJkZS4gRGFubiB3aXJkIGRhcyBBdHRhY2sgYWJnZWJyb2NoZW4uCisgICAgaWYgKCAhb2JqZWN0cChhaW5mb1tQX1dFQVBPTl0pICkKKyAgICAgIHJldHVybjsKKworICAgIGNsPXN5bWJvbF9mdW5jdGlvbigibmFtZSIsYWluZm9bUF9XRUFQT05dKTsKKyAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV9NU0ddID0gKCIgbWl0ICIrKHN0cmluZylmdW5jYWxsKGNsLFdFTSwwKSk7CisgICAgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHMl0gPSAoIiBtaXQgIisoc3RyaW5nKWZ1bmNhbGwoY2wsV0VNLDEpKTsKKworICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFXSA9IChpbnQpYWluZm9bUF9XRUFQT05dLT5RdWVyeURhbWFnZShlbmVteSk7CisKKyAgICBjbD1zeW1ib2xfZnVuY3Rpb24oIlF1ZXJ5UHJvcCIsYWluZm9bUF9XRUFQT05dKTsKKyAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV9UWVBFXSA9IGZ1bmNhbGwoY2wsUF9EQU1fVFlQRSk7CisgICAgYWluZm9bUF9XRUFQT05fVFlQRV0gPSAoc3RyaW5nKWZ1bmNhbGwoY2wsUF9XRUFQT05fVFlQRSk7CisgICAgYWluZm9bUF9OUl9IQU5EU10gPSAoaW50KWZ1bmNhbGwoY2wsUF9OUl9IQU5EUyk7CisgICAgYWluZm9bUF9XQ10gPSAoaW50KWZ1bmNhbGwoY2wsUF9XQyk7CisKKyAgICAvLyBad2VpaGFlbmRpZ2UgV2FmZmU/CisgICAgaWYgKCBhaW5mb1tQX05SX0hBTkRTXT09MgorICAgICAgICAmJiBtYXBwaW5ncChyZXM9VXNlU2tpbGwoU0tfVFdPSEFOREVELGRlZXBfY29weShhaW5mbykpKQorICAgICAgICAmJiBtZW1iZXIocmVzLFNJX1NLSUxMREFNQUdFKSApCisgICAgeworICAgICAgLy8gTnVyIGRlbiBuZXVlbiBTY2hhZGVuc3dlcnQgdWViZXJuZWhtZW4uCisgICAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV09KChpbnQpKHJlc1tTSV9TS0lMTERBTUFHRV0pKTsKKyAgICB9CisgIH0KKyAgZWxzZSAvLyBLZWluZSBXYWZmZSBnZXp1ZWNrdAorICB7CisgICAgLyogQ2hlY2sgaWYgdGhlcmUgaXMgYSBtYWdpY2FsIGF0dGFjayAqLworICAgIGlmICggbWFwcGluZ3AocmVzPVVzZVNraWxsKFNLX01BR0lDX0FUVEFDSywoW1NJX0VORU1ZOmVuZW15XSkpKSApCisgICAgeworICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VdPShpbnQpcmVzW1NJX1NLSUxMREFNQUdFXTsKKyAgICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX1RZUEVdPXJlc1tTSV9TS0lMTERBTUFHRV9UWVBFXTsKKworICAgICAgaWYgKCBzdHJpbmdwKHJlc1tTSV9TS0lMTERBTUFHRV9NU0ddKSApCisgICAgICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TR10gPSAiIG1pdCAiKyhzdHJpbmcpcmVzW1NJX1NLSUxMREFNQUdFX01TR107CisgICAgICBlbHNlCisgICAgICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TR10gPSAiIG1pdCBtYWdpc2NoZW4gRmFlaGlna2VpdGVuIjsKKworICAgICAgaWYgKCBzdHJpbmdwKHJlc1tTSV9TS0lMTERBTUFHRV9NU0cyXSkgKQorICAgICAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV9NU0cyXSA9ICIgbWl0ICIrKHN0cmluZylyZXNbU0lfU0tJTExEQU1BR0VfTVNHMl07CisgICAgICBlbHNlCisgICAgICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TRzJdID0gKHN0cmluZylhaW5mb1tTSV9TS0lMTERBTUFHRV9NU0ddOworCisgICAgICBpZiAoICEoYWluZm9bUF9XRUFQT05fVFlQRV09cmVzW1BfV0VBUE9OX1RZUEVdKSApCisgICAgICAgIGFpbmZvW1BfV0VBUE9OX1RZUEVdPVdUX01BR0lDOworCisgICAgICBpZiAoIG1lbWJlcihyZXMsU0lfU1BFTEwpICkKKyAgICAgICAgYWluZm9bU0lfU1BFTExdPXJlc1tTSV9TUEVMTF07CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICAvKiBPaG5lIChmcmVpZSkgSGFlbmRlIHdpcmQgYXVjaCBuaWNodCBhbmdlZ3JpZmZlbiAqLworICAgICAgaWYgKCBpbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKQorICAgICAgICAgICYmIChRdWVyeVByb3AoUF9VU0VEX0hBTkRTKSA+PSBRdWVyeVByb3AoUF9NQVhfSEFORFMpKSApCisgICAgICAgIHJldHVybiA7CisKKyAgICAgIGlmICggIXBvaW50ZXJwKHJlcz1RdWVyeVByb3AoUF9IQU5EUykpIHx8IChzaXplb2YocmVzKTwyKSApCisgICAgICAgIHJldHVybjsKKworICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VdID0gKCggMipyYW5kb20oKChpbnQpcmVzWzFdKSsxKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyAxMCooUXVlcnlBdHRyaWJ1dGUoQV9TVFIpKSApLzMpOworICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VfVFlQRV0gPSByZXNbMl07CisgICAgICBhaW5mb1tTSV9TS0lMTERBTUFHRV9NU0ddID0gYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHMl0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPSAoKHN0cmluZylyZXNbMF0pOworICAgICAgYWluZm9bUF9XRUFQT05fVFlQRV0gPSBXVF9IQU5EUzsKKyAgICAgIGFpbmZvW1BfV0NdID0gKGludClyZXNbMV07CisgICAgfQorICB9ICAvLyBiZXNvbmRlcmUgRmFlaGlna2VpdGVuIG1pdCBkaWVzZW0gV2FmZmVudHlwPworICBpZiAoIG1hcHBpbmdwKHJlcz1Vc2VTa2lsbChGSUdIVChhaW5mb1tQX1dFQVBPTl9UWVBFXSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZXBfY29weShhaW5mbykpKSApCisgICAgU2tpbGxSZXNUcmFuc2ZlcihyZXMsYWluZm8pOworCisgIC8vIGJlc29uZGVyZSBhbGxnZW1laW5lIEthbXBmZmFlaGlna2VpdGVuPworICBpZiAoIG1hcHBpbmdwKHJlcz1Vc2VTa2lsbChTS19GSUdIVCxkZWVwX2NvcHkoYWluZm8pKSkgKQorICAgIFNraWxsUmVzVHJhbnNmZXIocmVzLGFpbmZvKTsKKworICAvLyBWZXJhZW5kZXJ1bmdlbiBkdXJjaCBlaW5lbiBBdHRhY2stTW9kaWZpZXI/CisgIGlmICggKHJlcz1RdWVyeVByb3AoUF9UTVBfQVRUQUNLX01PRCkpICkKKyAgeworICAgIGlmICggcG9pbnRlcnAocmVzKSAmJiAoc2l6ZW9mKHJlcyk+PTMpICYmIGludHAocmVzWzBdKQorICAgICAgICAmJiAodGltZSgpPHJlc1swXSkgJiYgb2JqZWN0cChyZXNbMV0pICYmIHN0cmluZ3AocmVzWzJdKSApCisgICAgeworICAgICAgaWYgKCAhKHJlcz1jYWxsX290aGVyKHJlc1sxXSxyZXNbMl0sZGVlcF9jb3B5KGFpbmZvKSkpCisgICAgICAgICAgfHwgIW1hcHBpbmdwKHJlcykgKQorICAgICAgICByZXR1cm47CisgICAgICBlbHNlCisgICAgICAgIFNraWxsUmVzVHJhbnNmZXIocmVzLGFpbmZvKTsKKyAgICB9CisgICAgZWxzZQorICAgICAgU2V0UHJvcChQX1RNUF9BVFRBQ0tfTU9ELDApOworICB9CisKKyAgLy8gdHJpZ2dlciBhdHRhY2sgbW9kIGhvb2sKKyAgaG9va0RhdGE9ZGVlcF9jb3B5KGFpbmZvKTsKKyAgaG9va1Jlcz1Ib29rRmxvdyhIX0hPT0tfQVRUQUNLX01PRCxob29rRGF0YSk7CisgIGlmKGhvb2tSZXMgJiYgcG9pbnRlcnAoaG9va1JlcykgJiYgc2l6ZW9mKGhvb2tSZXMpPkhfUkVUREFUQSl7CisgICAgaWYoaG9va1Jlc1tIX1JFVENPREVdPT1IX0NBTkNFTExFRCl7CisgICAgICByZXR1cm47CisgICAgfQorICAgIGVsc2UgaWYoaG9va1Jlc1tIX1JFVENPREVdPT1IX0FMVEVSRUQgJiYgaG9va1Jlc1tIX1JFVERBVEFdICYmCisgICAgICAgICAgICAgbWFwcGluZ3AoaG9va1Jlc1tIX1JFVERBVEFdKSl7CisgICAgICAgIFNraWxsUmVzVHJhbnNmZXIoaG9va1Jlc1tIX1JFVERBVEFdLGFpbmZvKTsKKyAgICB9CisgIH0KKworICAvLyBJbnRlcm5lIE1vZGlmaWthdGlvbmVuIGRlciBBbmdyaWZmc3dlcnRlCisgIEludGVybmFsTW9kaWZ5QXR0YWNrKGFpbmZvKTsKKworICBpZiAoICFvYmplY3RwKGVuZW15KSApCisgICAgcmV0dXJuOworCisgIC8vIGhpZXIgbWFsIGJld3Vzc3QgbmljaHQgYXVmIFBfUExVUkFMIHp1ZXJzdCB0ZXN0ZW4uIGluIDkwJSBkZXIgRmFlbGxlCisgIC8vIHdpcmQgZWgga2VpbmUgQW5ncmlmZnNtZWxkdW5nIG1laHIgYXVzZ2VnZWJlbiwgYWxzbyBwcnVlZmVuIHdpciBkYXMKKyAgLy8gbGllYmVyIHp1ZXJzdC4gUGx1cmFsIHRlc3RlbiB6aWVodCBzY2hvbiBnZW51ZyBSZWNoZW56ZWl0IDovCisgIC8vIE5pY2h0IG1laW5lIElkZWUhIE5pY2h0IG1laW5lIElkZWUhIE5hY2h0d2luZCA3LjcuMjAwMQorICBpZiAoIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TRzJdIT1sYXN0X2F0dGFja19tc2cgKQorICB7CisgICAgbGFzdF9hdHRhY2tfbXNnID0gYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHMl07CisgICAgaWYgKFF1ZXJ5UHJvcChQX1BMVVJBTCkpCisgICAgeworICAgICAgdGVsbF9vYmplY3QoIE1FLCAiICBJaHIgZ3JlaWZ0ICIgKyBlbmVteS0+bmFtZShXRU4sMSkKKyAgICAgICAgICAgICAgICAgICArIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TRzJdICsgIiBhbi5cbiIgKTsKKyAgICAgIHNheSgiICAiKyhOYW1lKFdFUiwxKSkrIiBncmVpZmVuICIrKGVuZW15LT5uYW1lKFdFTiwxKSkrCisgICAgICAgICAgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHXSsiIGFuLlxuIiwgZW5lbXkgKTsKKyAgICAgIHRlbGxfb2JqZWN0KCBlbmVteSwgIiAgIisoTmFtZShXRVIsMSkpKyIgZ3JlaWZlbiAiKworICAgICAgICAgICAgICAgICAgKGVuZW15LT5RdWVyeVByb3AoUF9QTFVSQUwpPyJFdWNoIjoiRGljaCIpKworICAgICAgICAgICAgICAgICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TRzJdKyIgYW4uXG4iICk7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICB0ZWxsX29iamVjdCggTUUsICIgIER1IGdyZWlmc3QgIiArIGVuZW15LT5uYW1lKFdFTiwxKQorICAgICAgICAgICAgICAgICAgICsgYWluZm9bU0lfU0tJTExEQU1BR0VfTVNHMl0gKyAiIGFuLlxuIiApOworICAgICAgc2F5KCIgICIrKE5hbWUoV0VSLDIpKSsiIGdyZWlmdCAiKyhlbmVteS0+bmFtZShXRU4sMSkpKworICAgICAgICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TR10rIiBhbi5cbiIsIGVuZW15ICk7CisgICAgICB0ZWxsX29iamVjdCggZW5lbXksICIgICIrKE5hbWUoV0VSLDEpKSsiIGdyZWlmdCAiKworICAgICAgICAgICAgICAgICAgKGVuZW15LT5RdWVyeVByb3AoUF9QTFVSQUwpPyJFdWNoIjoiRGljaCIpKworICAgICAgICAgICAgICAgICAgIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TRzJdKyIgYW4uXG4iICk7ICAgIH0KKyAgfQorICBlbHNlIGlmICggUXVlcnkoUF9TSE9XX0FUVEFDS19NU0cpICkKKyAgICBpZiAoUXVlcnlQcm9wKFBfUExVUkFMKSkKKyAgICAgIHRlbGxfb2JqZWN0KCBNRSwgIiAgSWhyIGdyZWlmdCAiICsgZW5lbXktPm5hbWUoV0VOLDEpCisgICAgICAgICAgICAgICAgICAgKyBhaW5mb1tTSV9TS0lMTERBTUFHRV9NU0cyXSArICIgYW4uXG4iICk7CisgICAgZWxzZQorICAgICAgdGVsbF9vYmplY3QoIE1FLCAiICBEdSBncmVpZnN0ICIgKyBlbmVteS0+bmFtZShXRU4sMSkKKyAgICAgICAgICAgICAgICAgICArIGFpbmZvW1NJX1NLSUxMREFNQUdFX01TRzJdICsgIiBhbi5cbiIgKTsKKworICAvLyBhaW5mbyBpbiBkZWZlbmRpbmZvIG1lcmtlbgorICBlZGVmZW5kaW5mb1sgT1JJR0lOQUxfQUlORk9dPSBkZWVwX2NvcHkoYWluZm8pOworICBlZGVmZW5kaW5mb1sgT1JJR0lOQUxfREFNXT0gYWluZm9bU0lfU0tJTExEQU1BR0VdOworICBlZGVmZW5kaW5mb1sgT1JJR0lOQUxfREFNVFlQRV09IGFpbmZvW1NJX1NLSUxMREFNQUdFX1RZUEVdOworICBlZGVmZW5kaW5mb1sgQ1VSUkVOVF9EQU1dPSBhaW5mb1tTSV9TS0lMTERBTUFHRV07CisgIGVkZWZlbmRpbmZvWyBDVVJSRU5UX0RBTVRZUEVdPSBhaW5mb1tTSV9TS0lMTERBTUFHRV9UWVBFXTsKKworICAvLyBhaW5mb1tTSV9TUEVMTF0gYXVmIGVpbiBtYXBwaW5nIG5vcm1pZXJlbgorICBpZiAoIGludHAoYWluZm9bU0lfU1BFTExdKSApCisgIHsKKyAgICBhaW5mb1tTSV9TUEVMTF0gPSAoWyBTUF9QSFlTSUNBTF9BVFRBQ0sgOiAhYWluZm9bU0lfU1BFTExdLAorICAgICAgICAgICAgICAgU1BfU0hPV19EQU1BR0UgICAgIDogIWFpbmZvW1NJX1NQRUxMXSwKKyAgICAgICAgICAgICAgIFNQX1JFRFVDRV9BUk1PVVIgICA6IChbIF0pICBdKTsKKyAgfQorCisgIC8vIGRlZmVuZGluZm8gYW5oYWVuZ2VuLCBmYWxscyBhaW5mb1tTSV9TUEVMTF0gZWluIG1hcHBpbmcgaXN0CisgIGlmKCBtYXBwaW5ncChhaW5mb1tTSV9TUEVMTF0pKQorICB7CisgICAgYWluZm9bU0lfU1BFTExdW0VJTkZPX0RFRkVORF09ZWRlZmVuZGluZm87CisgIH0KKworCisgIGVuZW15LT5EZWZlbmQoYWluZm9bU0lfU0tJTExEQU1BR0VdLCBhaW5mb1tTSV9TS0lMTERBTUFHRV9UWVBFXSwKKyAgICAgICAgICAgICAgICBhaW5mb1tTSV9TUEVMTF0sICAgICAgIHRoaXNfb2JqZWN0KCkpOworCisKKyAgLy9lZGVmZW5kaW5mbz0oW10pOworCisgIC8qIERvbmUgYXR0YWNraW5nICovCit9CisKK3B1YmxpYyB2b2lkIEFkZERlZmVuZGVyKG9iamVjdCBmcmllbmQpCit7IG9iamVjdCAqZGVmczsKKworICBpZiAoICFvYmplY3RwKGZyaWVuZCkgKQorICAgIHJldHVybjsKKworICBpZiAoICFwb2ludGVycChkZWZzPVF1ZXJ5UHJvcChQX0RFRkVOREVSUykpICkKKyAgICBkZWZzPSh7fSk7CisKKyAgaWYgKCBtZW1iZXIoZGVmcyxmcmllbmQpPj0wICkKKyAgICByZXR1cm47CisKKyAgZGVmcys9KHtmcmllbmR9KTsKKyAgU2V0UHJvcChQX0RFRkVOREVSUyxkZWZzKTsKK30KKworcHVibGljIHZvaWQgUmVtb3ZlRGVmZW5kZXIob2JqZWN0IGZyaWVuZCkKK3sgb2JqZWN0ICpkZWZzOworCisgIGlmICggIW9iamVjdHAoZnJpZW5kKSApCisgICAgcmV0dXJuOworCisgIGlmICggIXBvaW50ZXJwKGRlZnM9UXVlcnlQcm9wKFBfREVGRU5ERVJTKSkgKQorICAgIGRlZnM9KHt9KTsKKworICBpZiAoIG1lbWJlcihkZWZzLGZyaWVuZCk9PS0xICkKKyAgICByZXR1cm47CisKKyAgZGVmcyAtPSAoe2ZyaWVuZH0pOworICBTZXRQcm9wKFBfREVGRU5ERVJTLGRlZnMpOworfQorCitwdWJsaWMgdm9pZCBJbmZvcm1EZWZlbmQob2JqZWN0IGVuZW15KQoreworICBVc2VTa2lsbChTS19JTkZPUk1fREVGRU5ELChbIFNJX0VORU1ZICA6IGVuZW15LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJX0ZSSUVORCA6IHByZXZpb3VzX29iamVjdCgpIF0pKTsKKyAgLy8gT2gsIG9oIC0gaWNoIGhvZmZlIG1hbCwgZGFzcyBJbmZvcm1EZWZlbmQgd2lya2xpY2ggTlVSIGF1cyBEZWZlbmQKKyAgLy8gZWluZXMgYmVmcmV1bmRldGVuIGxpdmluZ3MgYXVmZ2VydWZlbiB3aXJkLi4uIChTaWx2YW5hKQorICAvLyBUaGlzIGlzIG9ubHkgZXhwZXJpbWVudGFsLi4uIDspCit9CisKK3B1YmxpYyA8aW50fHN0cmluZyp8bWFwcGluZz4qIERlZmVuZE90aGVyKGludCBkYW0sIHN0cmluZ3xzdHJpbmcqIGRhbV90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50fG1hcHBpbmcgc3BlbGwsIG9iamVjdCBlbmVteSkKK3sKKyAgPGludHxzdHJpbmcqfG1hcHBpbmc+KiByZXM7CisKKyAgaWYgKCAocmVzPVVzZVNraWxsKFNLX0RFRkVORF9PVEhFUiwoWyBTSV9TS0lMTERBTUFHRSA6IGRhbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSV9TS0lMTERBTUFHRV9UWVBFIDogZGFtX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0lfU1BFTEwgOiBzcGVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSV9GUklFTkQgOiBwcmV2aW91c19vYmplY3QoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSV9FTkVNWSA6IGVuZW15IF0pKSkKKyAgICAgICYmIHBvaW50ZXJwKHJlcykgKQorICAgIHJldHVybiByZXM7CisKKyAgcmV0dXJuIDA7Cit9CisKK3B1YmxpYyB2b2lkIENoZWNrV2ltcHlBbmRGbGVlKCkKK3sKKyAgaWYgKCAoUXVlcnlQcm9wKFBfV0lNUFkpPlF1ZXJ5UHJvcChQX0hQKSkgJiYgIVRlYW1GbGVlKCkKKyAgICAgICYmIGZpbmRfY2FsbF9vdXQoIkZsZWUiKTwwICkKKyAgICBjYWxsX291dCgjJ0ZsZWUsMCxlbnZpcm9ubWVudCgpKTsKK30KKworcHJvdGVjdGVkIHN0cmluZyBtZXNzKHN0cmluZyBtc2csb2JqZWN0IG1lLG9iamVjdCBlbmVteSkKK3sgY2xvc3VyZSBtbmFtZSwgZW5hbWU7CisgIHN0cmluZyAgKnBhcnRzLHg7CisgIGludCAgICAgaTsKKworICBtbmFtZSA9IHN5bWJvbF9mdW5jdGlvbigibmFtZSIsIG1lKTsKKyAgZW5hbWUgPSBzeW1ib2xfZnVuY3Rpb24oIm5hbWUiLCBlbmVteSk7CisKKyAgcGFydHM9cmVnZXhwbG9kZShtc2csIkBXRVtBLVpdKlsxMl0iKTsKKyAgZm9yICggaT1zaXplb2YocGFydHMpLTIgOyBpPj0xIDsgaS09MiApCisgIHsKKyAgICBzd2l0Y2gocGFydHNbaV0pCisgICAgeworICAgICAgY2FzZSAiQFdFUjEiOiAgICBwYXJ0c1tpXT1mdW5jYWxsKG1uYW1lLFdFUiwxKTsgICAgYnJlYWs7CisgICAgICBjYXNlICJAV0VTU0VOMSI6IHBhcnRzW2ldPWZ1bmNhbGwobW5hbWUsV0VTU0VOLDEpOyBicmVhazsKKyAgICAgIGNhc2UgIkBXRU0xIjogICAgcGFydHNbaV09ZnVuY2FsbChtbmFtZSxXRU0sMSk7ICAgIGJyZWFrOworICAgICAgY2FzZSAiQFdFTjEiOiAgICBwYXJ0c1tpXT1mdW5jYWxsKG1uYW1lLFdFTiwxKTsgICAgYnJlYWs7CisgICAgICBjYXNlICJAV0VSMiI6ICAgIHBhcnRzW2ldPWZ1bmNhbGwoZW5hbWUsV0VSLDEpOyAgICBicmVhazsKKyAgICAgIGNhc2UgIkBXRVNTRU4yIjogcGFydHNbaV09ZnVuY2FsbChlbmFtZSxXRVNTRU4sMSk7IGJyZWFrOworICAgICAgY2FzZSAiQFdFTTIiOiAgICBwYXJ0c1tpXT1mdW5jYWxsKGVuYW1lLFdFTSwxKTsgICAgYnJlYWs7CisgICAgICBjYXNlICJAV0VOMiI6ICAgIHBhcnRzW2ldPWZ1bmNhbGwoZW5hbWUsV0VOLDEpOyAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6IDsKKyAgICB9CisgIH0KKworICByZXR1cm4gYnJlYWtfc3RyaW5nKGNhcGl0YWxpemUoaW1wbG9kZShwYXJ0cywiIikpLDc4LCIgICIsMSk7Cit9CisKKy8vIEZ1ZXIgZXZ0bC4gRGVmZW5kLUFlbmRlcnVuZ2VuLCBvaG5lIGRhc3MgbWFuIGdsZWljaCBkYXMgZ2FuemUKKy8vIEF0dGFjayB1ZWJlcmxhZ2VybiBtdXNzOgorcHJvdGVjdGVkIHZvaWQgSW50ZXJuYWxNb2RpZnlEZWZlbmQoaW50IGRhbSwgc3RyaW5nKiBkdCwgbWFwcGluZyBzcGVsbCwgb2JqZWN0IGVuZW15KQoreworICByZXR1cm47Cit9CisKK3B1YmxpYyBpbnQgRGVmZW5kKGludCBkYW0sIHN0cmluZ3xzdHJpbmcqIGRhbV90eXBlLCBpbnR8bWFwcGluZyBzcGVsbCwgb2JqZWN0IGVuZW15KQoreworICBpbnQgICAgIGksazsKKyAgbWl4ZWQgICByZXMscmVzMjsKKyAgb2JqZWN0ICAqYXJtb3Vycyx0bXA7CisgIG1peGVkIGhvb2tEYXRhOworICBtaXhlZCBob29rUmVzOworICAKKyAgLy8gIHN0cmluZyAgd2hhdCwgaG93OworICBzdHJpbmcgZW5uYW1lLCBteW5hbWU7CisKKyAgLy8gdGhpc19wbGF5ZXIoKSwgd2VubiBrZWluIGVuZW15IGJla2FubnQuLi4KKyAgZW5lbXkgfHw9IHRoaXNfcGxheWVyKCk7CisgIC8vIFRlc3Rlbiwgb2IgZGllc2VzIExlYmV3ZXNlbiB1ZWJlcmhhdXB0IGFuZ2VncmlmZmVuIHdlcmRlbiBkYXJmCisgIGlmICggIXRoaXNfb2JqZWN0KCkgfHwgIWVuZW15IHx8IFF1ZXJ5UHJvcChQX05PX0FUVEFDSykKKyAgICAgIHx8ICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShlbmVteSkgJiYgISBpbnRlcmFjdGl2ZShlbmVteSkgKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCBpbnRwKHNwZWxsKSApCisgICAgc3BlbGwgPSAoWyBTUF9QSFlTSUNBTF9BVFRBQ0sgOiAhc3BlbGwsCisgICAgICAgICAgICAgICBTUF9TSE9XX0RBTUFHRSAgICAgOiAhc3BlbGwsCisgICAgICAgICAgICAgICBTUF9SRURVQ0VfQVJNT1VSICAgOiAoWyBdKSAgXSk7CisgIGVsc2UgaWYgKCAhbWFwcGluZ3Aoc3BlbGwpICkgLy8gSWxsZWdhbGVyIHNwZWxsLVBhcmFtZXRlcgorICAgIHJldHVybiAwOworCisgIC8vIHRlc3RlbiBvYiBlaW5lIGVyd2VpdGVydGUgZGVmZW5kaW5mbyB2b3JoYW5kZW4gaXN0CisgIGlmKCFtZW1iZXIoc3BlbGwsRUlORk9fREVGRU5EKSkKKyAgeworICAgICAgICAgIC8vc3BlbGwrPShbRUlORk9fREVGRU5EOihbXSldKTsgLy8gZ2dmIGhpbnp1ZnVlZ2VuCisgICAgICAgIC8vIHVzZSBhIHRlbXBvcmFyeSBtYXBwaW5nIHRvIGF2b2lkIHJlY3Vyc2l2ZQorICAgICAgICAvLyB2YWxbeF1beV0gPSBkZWVwX2NvcHkodmFsKTsKKyAgICAgICAgbWFwcGluZyB0bXBkZWZlbmQgPSAoWworICAgICAgICAgICAgICAgIE9SSUdJTkFMX0FJTkZPOmRlZXBfY29weShzcGVsbCksCisgICAgICAgICAgICAgICAgT1JJR0lOQUxfREFNOmRhbSwKKyAgICAgICAgICAgICAgICAgIE9SSUdJTkFMX0RBTVRZUEU6ZGFtX3R5cGUsCisgICAgICAgIF0pOworICAgICAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF09dG1wZGVmZW5kOworICB9CisKKyAgLy8gU2NoYWRlbnN0eXAgdWViZXJwcnVlZmVuCisgIGlmICggIXBvaW50ZXJwKGRhbV90eXBlKSApCisgICAgZGFtX3R5cGUgPSAoeyBkYW1fdHlwZSB9KTsKKworICBzcGVsbFtFSU5GT19ERUZFTkRdW0NVUlJFTlRfREFNVFlQRV09ZGFtX3R5cGU7CisgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1dPWRhbTsKKworICAvLyBUZXN0ZW4sIG9iIGRlciBBbmdyZWlmZXIgc2Nob24gYWxzIEZlaW5kIHJlZ2lzdHJpZXJ0IHdvcmRlbiBpc3QuCisgIC8vIFdlbm4gbmVpbiwgcmVnaXN0cmllcmVuLgorICBpZiAoICFJc0VuZW15KGVuZW15KSAmJiAhc3BlbGxbU1BfTk9fRU5FTVldICkKKyAgeworICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bRU5FTVlfSU5TRVJURURdPTE7CisgICAgSW5zZXJ0RW5lbXkoZW5lbXkpOworICB9CisKKyAgLy8gUkZSLVRha3RpayBhYmZhbmdlbgorICBpZiAoICFRdWVyeVByb3AoUF9FTkFCTEVfSU5fQVRUQUNLX09VVCkgKQorICB7CisgICAgaT10aW1lKCktKGVuZW15LT5RdWVyeVByb3AoUF9MQVNUX01PVkUpKTsKKyAgICAvLyBHZWduZXIgaGF0IHNpY2ggYmV3ZWd0LCBtYW4gc2VsYnN0IG5pY2h0CisgICAgaWYgKCAoaTwzKSAmJiAodGltZSgpLVF1ZXJ5UHJvcChQX0xBU1RfTU9WRSk+PTUpICkKKyAgICB7CisgICAgICAvLyBCZWkgRXJzdGVyIEthbXBmcnVuZGUgd2VuaWdlIFNjaGFkZW4KKyAgICAgIGRhbS89KDQtaSk7CisgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW1JGUl9SRURVQ0VdPWRhbTsKKyAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1dPWRhbTsKKyAgICB9CisgIH0KKworICAvLyBNYW4ga2FubiBWZXJ0ZWlkaWdlciBoYWJlbi4gRGllc2Uga29tbWVuIGFscyBlcnN0ZSB6dW0gWnVnZQorICBpZiAoIHJlcz1RdWVyeVByb3AoUF9ERUZFTkRFUlMpICkKKyAgeyBvYmplY3QgKmRlZnMsKmRlZnNfaGVyZTsKKworICAgIGRlZnM9KHt9KTsKKyAgICBkZWZzX2hlcmU9KHt9KTsKKyAgICBpZiAoICFwb2ludGVycChyZXMpICkKKyAgICAgIHJlcz0oe3Jlc30pOworICAgIC8vIGVyc3QgYWxsZSBhbndlc2VuZGVuIGZpbmRlbi4KKyAgICBmb3JlYWNoKG9iamVjdCBkZWZlbmRlcjogcmVzKSB7CisgICAgICBpZiAoIG9iamVjdHAoZGVmZW5kZXIpICYmIChtZW1iZXIoZGVmcyxkZWZlbmRlcik8MCkgKQorICAgICAgeworICAgICAgICBkZWZzKz0oe2RlZmVuZGVyfSk7CisgICAgICAgIC8vICBWZXJ0ZWlkaWdlciBtdWVzc2VuIGltIGdsZWljaGVuIFJhdW0gb2RlciBpbSBMaXZpbmcgc2VsYmVyCisgICAgICAgIC8vICBlbnRoYWx0ZW4gc2Vpbi4KKyAgICAgICAgaWYgKCBlbnZpcm9ubWVudChkZWZlbmRlcikgPT0gZW52aXJvbm1lbnQoKQorICAgICAgICAgICAgfHwgZW52aXJvbm1lbnQoZGVmZW5kZXIpID09IE1FKQorICAgICAgICB7CisgICAgICAgICAgY2FsbF9vdGhlcihkZWZlbmRlciwiSW5mb3JtRGVmZW5kIixlbmVteSk7CisgICAgICAgICAgaWYgKGRlZmVuZGVyKQorICAgICAgICAgICAgZGVmc19oZXJlICs9ICh7IGRlZmVuZGVyIH0pOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIC8vQW53ZXNlbmRlIFZlcnRlaWRpZ2VyIGVpbnRyYWdlbi4KKyAgICBzcGVsbFtFSU5GT19ERUZFTkRdW1BSRVNFTlRfREVGRU5ERVJTXT1kZWZzX2hlcmU7CisKKyAgICAvLyBQX0RFRkVOREVSUyBhdWNoIGdsZWljaCBha3R1YWxpc2llcmVuCisgICAgaWYgKCBzaXplb2YoZGVmcyk8MSApCisgICAgICBkZWZzPTA7CisgICAgU2V0UHJvcChQX0RFRkVOREVSUyxkZWZzKTsKKworICAgIGlmICggc3BlbGxbU1BfUEhZU0lDQUxfQVRUQUNLXSApIHsKKyAgICAgIC8vIEJlaSBwaHlzaXNjaGVuIEFuZ3JpZmZlbiBudXIgVmVydGVpZGlnZXIgYXVzIFJlaWhlIDEKKyAgICAgIC8vIG5laG1lbiAoei5CLiBmdWVyIFJ1ZWNrZW5kZWNrdW5nKQorICAgICAgZm9yZWFjaChvYmplY3QgZGVmZW5kZXI6IGRlZnNfaGVyZSkgeworICAgICAgICBpZiAoIChkZWZlbmRlci0+UHJlc2VudFBvc2l0aW9uKCkpPjEgKSB7CisgICAgICAgICAgZGVmc19oZXJlLT0oe2RlZmVuZGVyfSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgCisgICAgaWYgKCAoaT1zaXplb2YoZGVmc19oZXJlKSkgKQorICAgIHsKKyAgICAgIG1peGVkIGVkZWZlbmR0bXA9KHtkZWZzX2hlcmVbcmFuZG9tKGkpXSwwLDAsMH0pOyAKKyAgICAgIHJlcz1jYWxsX290aGVyKGVkZWZlbmR0bXBbREVGX0RFRkVOREVSXSwiRGVmZW5kT3RoZXIiLAorICAgICAgICAgICAgICAgICAgICAgZGFtLGRhbV90eXBlLHNwZWxsLGVuZW15KTsKKyAgICAgIGlmICggcG9pbnRlcnAocmVzKSAmJiAoc2l6ZW9mKHJlcyk+PTMpICYmIGludHAocmVzWzBdKQorICAgICAgICAgICYmIHBvaW50ZXJwKHJlc1sxXSkpCisgICAgICB7CisgICAgICAgIC8vIEhlbGZlciBrb2VubmVuIGRlbiBTY2hhZGVuIG9kZXIgU2NoYWRlbnN0eXAgYWVuZGVybiwKKyAgICAgICAgLy8gei5CLiBVbXdhbmRsdW5nIHZvbiBGZXVlciBuYWNoIEVpcyBvZGVyIHNvLi4uCisgICAgICAgIGRhbT1yZXNbMF07CisgICAgICAgIGVkZWZlbmR0bXBbREVGX0RBTV09ZGFtOworICAgICAgICBkYW1fdHlwZT1yZXNbMV07CisgICAgICAgIGVkZWZlbmR0bXBbREVGX0RBTVRZUEVdPWRhbV90eXBlOworCisgICAgICAgIGlmICggbWFwcGluZ3AocmVzWzJdKSApCisgICAgICAgIHsKKyAgICAgICAgICBzcGVsbD1yZXNbMl07CisgICAgICAgICAgLy8gdGV1ZXIsIGFiZXIgZ2VodCBuaWNodCBhbmRlcnMgKFJla3Vyc2lvbiB2ZXJtZWlkZW4pCisgICAgICAgICAgZWRlZmVuZHRtcFtERUZfU1BFTExdPWRlZXBfY29weShyZXNbMl0pOworICAgICAgICB9CisgICAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1UWVBFXT1kYW1fdHlwZTsKKyAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTV09ZGFtOworICAgICAgfQorICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRJTkdfREVGRU5ERVJdPWVkZWZlbmR0bXA7CisgICAgfQorICB9IC8vIEVuZGUgRGVmZW5kZXItVmVyYXJiZWl0dW5nCisKKworICAvLyBVZWJlciBlaW5lbiBQX1RNUF9ERUZFTkRfSE9PSyB3ZXJkZW4gei5CLiBTY2h1dHp6YXViZXIgZ2VoYW5kaGFidAorICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9IT09LXT1ESV9OT0hPT0s7CisgIGlmICggcmVzPVF1ZXJ5UHJvcChQX1RNUF9ERUZFTkRfSE9PSykgKQorICB7CisgICAgaWYgKCBwb2ludGVycChyZXMpICYmIChzaXplb2YocmVzKT49MykgJiYgaW50cChyZXNbMF0pICYmICh0aW1lKCk8cmVzWzBdKQorICAgICAgICAmJiBvYmplY3RwKHJlc1sxXSkgJiYgc3RyaW5ncChyZXNbMl0pICkKKyAgICB7CisgICAgICBpZiAoICEocmVzPWNhbGxfb3RoZXIocmVzWzFdLHJlc1syXSxkYW0sZGFtX3R5cGUsc3BlbGwsZW5lbXkpKSApCisgICAgICB7CisgICAgICAgIC8vIEVpbiBQX1RNUF9ERUZFTkRfSE9PSyBrYW5uIGRlbiBTY2hhZGVuIHZvbGxzdGFlbmRpZyBhYmZhbmdlbiwKKyAgICAgICAgLy8gZGFzIERlZmVuZCB3aXJkIGRhbm4gaGllciBhYmdlYnJvY2hlbiAqU0lDSyogdW5kIGVzIHdpcmQgbnVyCisgICAgICAgIC8vIG5vY2ggZ2V0ZXN0ZXQsIG9iIG1hbiBpbiBkaWUgRmx1Y2h0IGdlc2NobGFnZW4gd3VyZGUKKyAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRfSE9PS109RElfSE9PS0lOVEVSUlVQVDsKKyAgICAgICAgQ2hlY2tXaW1weUFuZEZsZWUoKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bREVGRU5EX0hPT0tdPURJX0hPT0s7CisgICAgICAgIGlmICggcG9pbnRlcnAocmVzKSAmJiAoc2l6ZW9mKHJlcyk+PTMpCisgICAgICAgICAgICAmJiBpbnRwKHJlc1swXSAmJiBwb2ludGVycChyZXNbMV0pKSApCisgICAgICAgIHsKKyAgICAgICAgICBtaXhlZCBlZGVmZW5kdG1wPSh7MCwwLDB9KTsKKyAgICAgICAgICAvLyBEZXIgUF9UTVBfREVGRU5EX0hPT0sga2FubiBlYmVuZmFsbHMgU2NoYWRlbnNob2VoZSB1bmQKKyAgICAgICAgICAvLyAtYXJ0IHNvd2llIGRpZSBTcGVsbC1JbmZvcyB2ZXJhZW5kZXJuCisgICAgICAgICAgZGFtPXJlc1swXTsKKyAgICAgICAgICBlZGVmZW5kdG1wW0hPT0tfREFNXT1kYW07CisgICAgICAgICAgZGFtX3R5cGU9cmVzWzFdOworICAgICAgICAgIGVkZWZlbmR0bXBbSE9PS19EQU1UWVBFXT1kYW1fdHlwZTsKKworICAgICAgICAgIGlmICggbWFwcGluZ3AocmVzWzJdKSApCisgICAgICAgICAgeworICAgICAgICAgICAgc3BlbGw9cmVzWzJdOworICAgICAgICAgICAgLy8gV2FlaC4gVGV1ZXIuIEFiZXIgZ2VodCBuaWNodCBhbmRlcnMuCisgICAgICAgICAgICBlZGVmZW5kdG1wW0hPT0tfU1BFTExdPWRlZXBfY29weShzcGVsbCk7CisgICAgICAgICAgfQorICAgICAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bREVGRU5EX0hPT0tdPWVkZWZlbmR0bXA7CisgICAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTVRZUEVdPWRhbV90eXBlOworICAgICAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1dPWRhbTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICBlbHNlCisgICAgICBTZXRQcm9wKFBfVE1QX0RFRkVORF9IT09LLDApOworICB9IC8vIFBfVE1QX0RFRkVORF9IT09LCisKKyAgLy8gdHJpZ2dlciBkZWZlbmQgaG9vaworICBob29rRGF0YT0oe2RhbSxkYW1fdHlwZSxzcGVsbCxlbmVteX0pOworICBob29rUmVzPUhvb2tGbG93KEhfSE9PS19ERUZFTkQsaG9va0RhdGEpOworICBpZihob29rUmVzICYmIHBvaW50ZXJwKGhvb2tSZXMpICYmIHNpemVvZihob29rUmVzKT5IX1JFVERBVEEpeworICAgIGlmKGhvb2tSZXNbSF9SRVRDT0RFXT09SF9DQU5DRUxMRUQpeworICAgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9IT09LXT1ESV9IT09LSU5URVJSVVBUOworICAgICAgICBDaGVja1dpbXB5QW5kRmxlZSgpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZWxzZSBpZihob29rUmVzW0hfUkVUQ09ERV09PUhfQUxURVJFRCAmJiBob29rUmVzW0hfUkVUREFUQV0peworICAgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9IT09LXT1ESV9IT09LOworICAgICAgICBpZiAoIHBvaW50ZXJwKGhvb2tSZXNbSF9SRVREQVRBXSkgJiYgKHNpemVvZihob29rUmVzW0hfUkVUREFUQV0pPj0zKQorICAgICAgICAgICAgJiYgaW50cChob29rUmVzW0hfUkVUREFUQV1bMF0gJiYgcG9pbnRlcnAoaG9va1Jlc1tIX1JFVERBVEFdWzFdKSkgKQorICAgICAgICB7CisgICAgICAgICAgbWl4ZWQgZWRlZmVuZHRtcD0oezAsMCwwfSk7CisgICAgICAgICAgLy8gRGVyIFBfVE1QX0RFRkVORF9IT09LIGthbm4gZWJlbmZhbGxzIFNjaGFkZW5zaG9laGUgdW5kCisgICAgICAgICAgLy8gLWFydCBzb3dpZSBkaWUgU3BlbGwtSW5mb3MgdmVyYWVuZGVybgorICAgICAgICAgIGRhbT1ob29rUmVzW0hfUkVUREFUQV1bMF07CisgICAgICAgICAgZWRlZmVuZHRtcFtIT09LX0RBTV09ZGFtOworICAgICAgICAgIGRhbV90eXBlPWhvb2tSZXNbSF9SRVREQVRBXVsxXTsKKyAgICAgICAgICBlZGVmZW5kdG1wW0hPT0tfREFNVFlQRV09ZGFtX3R5cGU7CisKKyAgICAgICAgICBpZiAoIG1hcHBpbmdwKGhvb2tSZXNbSF9SRVREQVRBXVsyXSkgKQorICAgICAgICAgIHsKKyAgICAgICAgICAgIHNwZWxsPWhvb2tSZXNbSF9SRVREQVRBXVsyXTsKKyAgICAgICAgICAgIC8vIFRldWVyLCB0ZXVlci4uLiA6LSgKKyAgICAgICAgICAgIGVkZWZlbmR0bXBbSE9PS19TUEVMTF09ZGVlcF9jb3B5KHNwZWxsKTsKKyAgICAgICAgICB9CisgICAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRfSE9PS109ZWRlZmVuZHRtcDsKKyAgICAgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0NVUlJFTlRfREFNVFlQRV09ZGFtX3R5cGU7CisgICAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTV09ZGFtOworICAgICAgICB9CisgICAgfQorICB9IC8vIEVuZGUgSG9vay1CZWhhbmRsdW5nCisKKyAgaWYgKCAhbWVtYmVyKHNwZWxsLFNQX1JFRFVDRV9BUk1PVVIpIHx8ICFtYXBwaW5ncChzcGVsbFtTUF9SRURVQ0VfQVJNT1VSXSkgKQorICAgICAgICBzcGVsbFtTUF9SRURVQ0VfQVJNT1VSXSA9IChbXSk7CisKKyAgLy8gRXMgZ2lidCBhdWNoIFBhcmllcndhZmZlbiwKKyAgaWYgKCBvYmplY3RwKHRtcD1RdWVyeVByb3AoUF9QQVJSWV9XRUFQT04pKSApCisgIHsKKyAgICByZXMyPXRtcC0+UXVlcnlEZWZlbmQoZGFtX3R5cGUsIHNwZWxsLCBlbmVteSk7CisKKyAgICAvLyBSZWR1emllcmJhcmUgV2lya3NhbWtlaXQgZGVyIFBhcmllcndhZmZlPworICAgIGlmICggbWVtYmVyKHNwZWxsW1NQX1JFRFVDRV9BUk1PVVJdLFBfUEFSUllfV0VBUE9OKQorICAgICAgICAmJiBpbnRwKHJlcz1zcGVsbFtTUF9SRURVQ0VfQVJNT1VSXVtQX1BBUlJZX1dFQVBPTl0pICYmIChyZXM+PTApICkKKyAgICB7CisgICAgICByZXMyPShyZXMyKnJlcykvMTAwOworICAgIH0KKworICAgIGRhbS09cmVzMjsKKyAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0NVUlJFTlRfREFNXT1kYW07CisgIH0KKworICAvLyBKZXR6dCBrb21tZW4gZGllIFJ1ZXN0dW5nZW4gZGVzIExlYmV3ZXNlbnMgaW5zIFNwaWVsICh3ZW5uIGVzIGRlbm4KKyAgLy8gd2VsY2hlIHRyYWVndCkKKworICBhcm1vdXJzPVF1ZXJ5UHJvcChQX0FSTU9VUlMpLSh7MH0pOworICBpZiAoIChpPXNpemVvZihhcm1vdXJzKSk+MCApIHsgCisgICAgc3RyaW5nIGF0eTsKKworICAgIHRtcD1hcm1vdXJzW3JhbmRvbShpKV07CisKKyAgICBpZiAoIG9iamVjdHAodG1wKSApCisgICAgICAvL1VlYmVyZ2FiZSBkZXMgTWFwcGluZ3MgZWggYWxzIFBvaW50ZXIvUmVmZXJlbnosIGRhaGVyIGJpbGxpZworICAgICAgdG1wLT5UYWtlRmxhdyhkYW1fdHlwZSxzcGVsbFtFSU5GT19ERUZFTkRdKTsKKworICAgIC8vIHBybyBSdWVzdHVuZyBlaW4gS2V5IGFuIFBsYXR6IHJlc2VydmllcmVuCisgICAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRfQVJNT1VSU109bV9hbGxvY2F0ZShpLDIpOworICAgIGZvcmVhY2gob2JqZWN0IGFybW91ciA6IGFybW91cnMpIHsKKyAgICAgIGlmICggb2JqZWN0cChhcm1vdXIpICkgeworICAgICAgICBhdHk9KHN0cmluZylhcm1vdXItPlF1ZXJ5UHJvcChQX0FSTU9VUl9UWVBFKTsKKworICAgICAgICBpZiAoIG1lbWJlcihzcGVsbFtTUF9SRURVQ0VfQVJNT1VSXSxhdHkpCisgICAgICAgICAgICAmJiBpbnRwKHJlczI9c3BlbGxbU1BfUkVEVUNFX0FSTU9VUl1bYXR5XSkgJiYgKHJlczI+PTApICkKKyAgICAgICAgICBkYW0gLT0gKHJlczIqYXJtb3VyLT5RdWVyeURlZmVuZChkYW1fdHlwZSwgc3BlbGwsIGVuZW15KSkvMTAwOworICAgICAgICBlbHNlCisgICAgICAgICAgZGFtIC09IChpbnQpKGFybW91ci0+UXVlcnlEZWZlbmQoZGFtX3R5cGUsIHNwZWxsLCBlbmVteSkpOworICAgICAgICAvLyBTY2hhZGVuIE5BQ0ggRGVmZW5kRnVuYyB2ZXJtZXJrZW4uIAorICAgICAgICAvLyBTY2h1dHp3aXJrdW5nIFZPUiBEZWZlbmRGdW5jIChERUZfQVJNT1VSX1BST1QpIHZlcm1lcmt0CisgICAgICAgIC8vIGRhcyBRdWVyeURlZmVuZCgpIHNlbGJlci4KKyAgICAgICAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRfQVJNT1VSU11bYXJtb3VyLERFRl9BUk1PVVJfREFNXT1kYW07CisgICAgICAgIC8vIGFrdC4gU2NoYWRlbiB2ZXJtZXJrZW4gdW5kIFNjaHV0eiBkZXIgYWt0dWVsbGVuIFJ1ZXN0dW5nICh2b3IKKyAgICAgICAgLy8gRGVmZW5kRnVuYykgd2llZGVyIGF1ZiAwIHNldHplbiBmdWVyIGRlbiBuYWVjaHN0ZW4gRHVyY2hsYXVmLgorICAgICAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0NVUlJFTlRfREFNXT1kYW07CisgICAgICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bREVGRU5EX0NVUl9BUk1PVVJfUFJPVF09MDsKKyAgICAgIH0KKyAgICB9CisgIH0KKworICAvLyBNYW5jaGUgR2lsZGVuIGhhYmVuIGVpbmVuIFZlcnRlaWRpZ3VuZ3Nza2lsbC4gRGVyIGtvbW10IGpldHp0IHp1bQorICAvLyB0cmFnZW4uIERlciBTa2lsbCBrYW5uIGRpZSBTY2hhZGVuc2hvZWhlIHVuZCAtYXJ0IGJlZWluZmx1c3Nlbi4KKyAgc3BlbGxbRUlORk9fREVGRU5EXSs9KFtERUZFTkRfR1VJTEQ6KHt9KV0pOworICBpZiAoIG1hcHBpbmdwKHJlcz1Vc2VTa2lsbChTS19NQUdJQ19ERUZFTlNFLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIChbIFNJX0VORU1ZICAgICAgICAgICAgOiBlbmVteSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSV9TS0lMTERBTUFHRSAgICAgIDogZGFtLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJX1NLSUxMREFNQUdFX1RZUEUgOiBkYW1fdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSV9TUEVMTCAgICAgICAgICAgIDogc3BlbGwgICAgIF0pKSkgKQorICB7CisgICAgZGFtPShpbnQpcmVzW1NJX1NLSUxMREFNQUdFXTsKKworICAgIGlmICggcG9pbnRlcnAocmVzW1NJX1NLSUxMREFNQUdFX1RZUEVdKSApCisgICAgICAgIGRhbV90eXBlPXJlc1tTSV9TS0lMTERBTUFHRV9UWVBFXTsKKworICAgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1UWVBFXT1kYW1fdHlwZTsKKyAgICBzcGVsbFtFSU5GT19ERUZFTkRdW0NVUlJFTlRfREFNXT1kYW07CisgICAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRfR1VJTERdPSh7ZGFtLGRhbV90eXBlfSk7CisgIH0KKworICAvLyBFdnRsLiBpbnRlcm5lIE1vZGlmaWthdGlvbmVuCisgIEludGVybmFsTW9kaWZ5RGVmZW5kKCZkYW0sICZkYW1fdHlwZSwgJnNwZWxsLCAmZW5lbXkpOworCisgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1UWVBFXT1kYW1fdHlwZTsKKyAgc3BlbGxbRUlORk9fREVGRU5EXVtDVVJSRU5UX0RBTV09ZGFtOworCisgIC8vIFRlc3Rlbiwgb2IgaXJnZW5kd2FzIGltIEludmVudG9yeSBkZXMgTGViZXdlc2VuIGF1ZiBkZW4gQW5ncmlmZgorICAvLyAicmVhZ2llcnQiCisgIENoZWNrU2Vuc2l0aXZlQXR0YWNrKGRhbSxkYW1fdHlwZSxzcGVsbCxlbmVteSk7CisKKyAgaWYgKCAhb2JqZWN0cChlbmVteSkgKQorICAgIHJldHVybiAwOworCisgIC8vIEFuZ3JpZmZzemVpdCBpbSBHZWduZXIgc2V0emVuCisgIGVuZW15LT5TZXRQcm9wKFBfTEFTVF9DT01CQVRfVElNRSx0aW1lKCkpOworCisgIC8vIERpZSBSZXNpc3RlbnplbiBkZXMgTGViZXdlc2VucyAobmF0dWVybGljaGUgdW5kIGR1cmNoIFJ1ZXN0dW5nZW4KKyAgLy8gZ2VzZXR6dGUpIGJlcnVlY2tzaWNodGlnZW4KKyAgZGFtID0gdG9faW50KENoZWNrUmVzaXN0YW5jZShkYW1fdHlwZSkqZGFtKTsKKyAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRfUkVTSV09ZGFtOworCisgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1dPWRhbTsKKworICAvLyBCZWkgcGh5c2lrYWxpc2NoZW4gQW5ncmlmZmVuIHdpcmQgZGllIG5hdHVlcmxpY2hlIFBhbnplcnVuZyB1bmQgZGllCisgIC8vIEdlc2NoaWNrbGljaGtlaXQgZGVzIExlYmV3ZXNlbnMgYmVydWVja3NpY2h0aWd0CisgIG9iamVjdCBzdGF0ID0gZmluZF9vYmplY3QoIi9kL2Vyem1hZ2llci96ZXNzdHJhL3BhY3N0YXQiKTsgLy8gVE9ETzogcmVtb3ZlCisgIGlmICggc3BlbGxbU1BfUEhZU0lDQUxfQVRUQUNLXSApCisgIHsKKyAgICAvLyBNaW5pbXVtIGlzdCBhdWNoIGhpZXIgMS4KKyAgICBpbnQgYm9keSA9IFF1ZXJ5UHJvcChQX0JPRFkpK1F1ZXJ5QXR0cmlidXRlKEFfREVYKTsKKyAgICByZXMyID0gKGJvZHkvNCArIHJhbmRvbShib2R5KjMvNCArIDEpKSB8fCAxOworICAgIGlmIChzdGF0KQorICAgICAgc3RhdC0+Ym9keXN0YXQoYm9keSwgcmVzMiwgcmFuZG9tKGJvZHkpKzEpOworCisgICAgLy8gUmVkdXppZXJiYXJlIFdpcmtzYW1rZWl0IGRlcyBCb2RpZXM/CisgICAgaWYgKCBtZW1iZXIoc3BlbGxbU1BfUkVEVUNFX0FSTU9VUl0sIFBfQk9EWSkKKyAgICAgICAgJiYgaW50cChyZXM9c3BlbGxbU1BfUkVEVUNFX0FSTU9VUl1bUF9CT0RZXSkgJiYgKHJlcz49MCkgKQorICAgICAgcmVzMj0ocmVzMipyZXMpLzEwMDsKKworICAgIGRhbS09cmVzMjsKKyAgfQorICBzcGVsbFtFSU5GT19ERUZFTkRdW0RFRkVORF9CT0RZXT1kYW07CisgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1dPWRhbTsKKworICAvLyBJc3QgdWViZXJoYXVwdCBub2NoIGV0d2FzIHZvbSBTY2hhZGVuIHVlYnJpZyBnZWJsaWViZW4/CisgIGlmICggZGFtPDAgKQorICAgIGRhbSA9IDA7CisgIHNwZWxsW0VJTkZPX0RFRkVORF1bQ1VSUkVOVF9EQU1dPWRhbTsKKworICAvLyBmdWVyIGRpZSBTdGF0aXN0aWsKKyAgLy8gVE9ETzogZW50ZmVybmVuIG5hY2ggVGVzdC1VcHRpbWUKKyAgaWYgKHN0YXQpCisgICAgc3RhdC0+ZGFtYWdlc3RhdChzcGVsbFtFSU5GT19ERUZFTkRdKTsKKworICAvLyBEaWUgQW56YWhsIGRlciBhYnp1emllaGVuZGVuIExlYmVuc3B1bmt0ZSBpc3QgZGVyIGR1cmNoIDEwIGdldGVpbHRlCisgIC8vIFNjaGFkZW5zd2VydAorICBkYW0gPSBkYW0gLyAxMDsKKyAgc3BlbGxbRUlORk9fREVGRU5EXVtERUZFTkRfTE9TVExQXT1kYW07CisKKyAgLy8gZXZ0bC4gaGF0IGVudHdlZGVyIGRlciBBdWZydWZlciBvZGVyIGRhcyBMZWJld2VzZW4gc2VsYmVyIGVpZ2VuZQorICAvLyBTY2hhZGVuc21lbGR1bmdlbiBkZWZpbmllcnQuIERpZSB2b20gQXVmcnVmZXIgaGFiZW4gUHJpb3JpdGFldC4KKyAgbWl4ZWQgZGFtX21zZyA9IHNwZWxsW1NQX1NIT1dfREFNQUdFXTsKKyAgLy8gV2VubiAhPSAwIChkLmguIFRyZWZmZXJtZWxkdW5nZW4gZ3J1bmRzYWV0emxpY2ggZXJ3dWVuc2NodCksIGFiZXIga2VpbgorICAvLyBBcnJheSwgaGllciBpbSBMaXZpbmcgZnJhZ2VuLgorICBpZiAoZGFtX21zZyAmJiAhcG9pbnRlcnAoZGFtX21zZykpCisgICAgZGFtX21zZyA9IFF1ZXJ5UHJvcChQX0RBTUFHRV9NU0cpOworCisgIC8vIEluIGRlbiBtZWlzdGVuIEZhZWxsZW4gc29sbCBhdWNoIGVpbmUgU2NoYWRlbnNtZWxkdW5nIGF1c2dlZ2ViZW4KKyAgLy8gd2VyZGVuLCBkaWUgZGllIEhvZWhlIGRlcyBTY2hhZGVucyAoZ3JvYikgYW56ZWlndAorICBpZiAoc3BlbGxbU1BfU0hPV19EQU1BR0VdICYmICFwb2ludGVycChkYW1fbXNnKSkgeworICAgIG15bmFtZT1uYW1lKFdFTik7CisgICAgZW5uYW1lPWVuZW15LT5OYW1lKFdFUik7CisgICAgaWYgKGVuZW15LT5RdWVyeVByb3AoUF9QTFVSQUwpKSB7CisgICAgICBzd2l0Y2ggKGRhbSkgeworICAgICAgY2FzZSAwOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIElociB2ZXJmZWhsdCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyB2ZXJmZWhsZW4gRGljaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgICBzcHJpbnRmKCIgICVzIHZlcmZlaGxlbiAlcy5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAxOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIElociBraXR6ZWx0ICVzIGFtIEJhdWNoLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIGtpdHplbG4gRGljaCBhbSBCYXVjaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMga2l0emVsbiAlcyBhbSBCYXVjaC5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAyLi4zOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIElociBrcmF0enQgJXMuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLHNwcmludGYoIiAgJXMga3JhdHplbiBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBrcmF0emVuICVzLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDQuLjU6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIHRyZWZmdCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyB0cmVmZmVuIERpY2guXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHRyZWZmZW4gJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNi4uMTA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIHRyZWZmdCAlcyBoYXJ0LlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIHRyZWZmZW4gRGljaCBoYXJ0LlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB0cmVmZmVuICVzIGhhcnQuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMTEuLjIwOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIElociB0cmVmZnQgJXMgc2VociBoYXJ0LlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHRyZWZmZW4gRGljaCBzZWhyIGhhcnQuXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHRyZWZmZW4gJXMgc2VociBoYXJ0LlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDIxLi4zMDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksCisgICAgICAgICAgc3ByaW50ZigiICBJaHIgc2NobGFndCAlcyBtaXQgZGVtIEtyYWNoZW4gYnJlY2hlbmRlciBLbm9jaGVuLlxuIiwKKyAgICAgICAgICAgICAgICAgIG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgc2NobGFnZW4gRGljaCBtaXQgZGVtIEtyYWNoZW4gYnJlY2hlbmRlciBLbm9jaGVuLlxuIiwKKyAgICAgICAgICAgICAgICAgIGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHNjaGxhZ2VuICVzIG1pdCBkZW0gS3JhY2hlbiBicmVjaGVuZGVyIEtub2NoZW4uXG4iLAorICAgICAgICAgICAgICAgICAgZW5uYW1lLG15bmFtZSksICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDMxLi41MDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksCisgICAgICAgICAgc3ByaW50ZigiICBJaHIgemVyc2NobWV0dGVydCAlcyBpbiBrbGVpbmUgU3R1ZWNrY2hlbi5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB6ZXJzY2htZXR0ZXJuIERpY2ggaW4ga2xlaW5lIFN0dWVja2NoZW4uXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgemVyc2NobWV0dGVybiAlcyBpbiBrbGVpbmUgU3R1ZWNrY2hlbi5cbiIsCisgICAgICAgICAgICAgICAgICBlbm5hbWUsbXluYW1lKSwgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgNTEuLjc1OgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIElociBzY2hsYWd0ICVzIHp1IEJyZWkuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgc2NobGFnZW4gRGljaCB6dSBCcmVpLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBzY2hsYWdlbiAlcyB6dSBCcmVpLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDc2Li4xMDA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIHB1bHZlcmlzaWVydCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyBwdWx2ZXJpc2llcmVuIERpY2guXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHB1bHZlcmlzaWVyZW4gJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMTAxLi4xNTA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIHplcnN0YWV1YnQgJXMuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLHNwcmludGYoIiAgJXMgemVyc3RhZXViZW4gRGljaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgemVyc3RhZXViZW4gJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMTUxLi4yMDA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIGF0b21pc2llcnQgJXMuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLHNwcmludGYoIiAgJXMgYXRvbWlzaWVyZW4gRGljaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgYXRvbWlzaWVyZW4gJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgSWhyIHZlcm5pY2h0ZXQgJXMuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLHNwcmludGYoIiAgJXMgdmVybmljaHRlbiBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB2ZXJuaWNodGVuICVzLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisKKyAgICB9CisgICAgZWxzZSB7CisgICAgICBzd2l0Y2ggKGRhbSkgeworICAgICAgY2FzZSAwOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIER1IHZlcmZlaGxzdCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyB2ZXJmZWhsdCBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB2ZXJmZWhsdCAlcy5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAxOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIER1IGtpdHplbHN0ICVzIGFtIEJhdWNoLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIGtpdHplbHQgRGljaCBhbSBCYXVjaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMga2l0emVsdCAlcyBhbSBCYXVjaC5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAyLi4zOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIER1IGtyYXR6dCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyBrcmF0enQgRGljaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMga3JhdHp0ICVzLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDQuLjU6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgRHUgdHJpZmZzdCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyB0cmlmZnQgRGljaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgdHJpZmZ0ICVzLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDYuLjEwOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIER1IHRyaWZmc3QgJXMgaGFydC5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyB0cmlmZnQgRGljaCBoYXJ0LlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB0cmlmZnQgJXMgaGFydC5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAxMS4uMjA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgRHUgdHJpZmZzdCAlcyBzZWhyIGhhcnQuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgdHJpZmZ0IERpY2ggc2VociBoYXJ0LlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB0cmlmZnQgJXMgc2VociBoYXJ0LlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDIxLi4zMDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksCisgICAgICAgICAgc3ByaW50ZigiICBEdSBzY2hsYWVnc3QgJXMgbWl0IGRlbSBLcmFjaGVuIGJyZWNoZW5kZXIgS25vY2hlbi5cbiIsCisgICAgICAgICAgICAgICAgICBteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIHNjaGxhZWd0IERpY2ggbWl0IGRlbSBLcmFjaGVuIGJyZWNoZW5kZXIgS25vY2hlbi5cbiIsCisgICAgICAgICAgICAgICAgICBlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBzY2hsYWVndCAlcyBtaXQgZGVtIEtyYWNoZW4gYnJlY2hlbmRlciBLbm9jaGVuLlxuIiwKKyAgICAgICAgICAgICAgICAgIGVubmFtZSxteW5hbWUpLCAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAzMS4uNTA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LAorICAgICAgICAgIHNwcmludGYoIiAgRHUgemVyc2NobWV0dGVyc3QgJXMgaW4ga2xlaW5lIFN0dWVja2NoZW4uXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgemVyc2NobWV0dGVydCBEaWNoIGluIGtsZWluZSBTdHVlY2tjaGVuLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB6ZXJzY2htZXR0ZXJ0ICVzIGluIGtsZWluZSBTdHVlY2tjaGVuLlxuIiwKKyAgICAgICAgICAgICAgICAgIGVubmFtZSxteW5hbWUpLCAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSA1MS4uNzU6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgRHUgc2NobGFlZ3N0ICVzIHp1IEJyZWkuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgc2NobGFlZ3QgRGljaCB6dSBCcmVpLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyBzY2hsYWVndCAlcyB6dSBCcmVpLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDc2Li4xMDA6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgRHUgcHVsdmVyaXNpZXJzdCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyBwdWx2ZXJpc2llcnQgRGljaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgcHVsdmVyaXNpZXJ0ICVzLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIDEwMS4uMTUwOgorICAgICAgICB0ZWxsX29iamVjdChlbmVteSxzcHJpbnRmKCIgIER1IHplcnN0YWV1YnN0ICVzLlxuIixteW5hbWUpKTsKKyAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxzcHJpbnRmKCIgICVzIHplcnN0YWV1YnQgRGljaC5cbiIsZW5uYW1lKSk7CisgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbmVteSl8fGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIHNwcmludGYoIiAgJXMgemVyc3RhZXVidCAlcy5cbiIsZW5uYW1lLG15bmFtZSksCisgICAgICAgICAgICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKSB9KSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAxNTEuLjIwMDoKKyAgICAgICAgdGVsbF9vYmplY3QoZW5lbXksc3ByaW50ZigiICBEdSBhdG9taXNpZXJzdCAlcy5cbiIsbXluYW1lKSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigiICAlcyBhdG9taXNpZXJ0IERpY2guXG4iLGVubmFtZSkpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoZW5lbXkpfHxlbnZpcm9ubWVudCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICBzcHJpbnRmKCIgICVzIGF0b21pc2llcnQgJXMuXG4iLGVubmFtZSxteW5hbWUpLAorICAgICAgICAgICAgICAgICAgKHsgZW5lbXksIHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LHNwcmludGYoIiAgRHUgdmVybmljaHRlc3QgJXMuXG4iLG15bmFtZSkpOworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLHNwcmludGYoIiAgJXMgdmVybmljaHRldCBEaWNoLlxuIixlbm5hbWUpKTsKKyAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVuZW15KXx8ZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgc3ByaW50ZigiICAlcyB2ZXJuaWNodGV0ICVzLlxuIixlbm5hbWUsbXluYW1lKSwKKyAgICAgICAgICAgICAgICAgICh7IGVuZW15LCB0aGlzX29iamVjdCgpIH0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisKKyAgLy8gTWFuIGthbm4gYXVjaCBzZWxic3QtZGVmaW5pZXJ0ZSBTY2hhZGVuc21lbGR1bmdlbiBhdXNnZWJlbiBsYXNzZW4KKyAgZWxzZSBpZiggc3BlbGxbU1BfU0hPV19EQU1BR0VdICYmIHBvaW50ZXJwKGRhbV9tc2cpICkKKyAgeworICAgIGZvciggaT1zaXplb2YoZGFtX21zZykgOyAtLWkgPj0gMCA7ICkKKyAgICB7CisgICAgICBpZiAoIGRhbT5kYW1fbXNnW2ldWzBdICkKKyAgICAgIHsKKyAgICAgICAgdGVsbF9vYmplY3QoTUUsbWVzcyhkYW1fbXNnW2ldWzFdLE1FLGVuZW15KSk7CisgICAgICAgIHRlbGxfb2JqZWN0KGVuZW15LG1lc3MoZGFtX21zZ1tpXVsyXSxNRSxlbmVteSkpOworICAgICAgICBzYXkobWVzcyhkYW1fbXNnW2ldWzNdLE1FLGVuZW15KSwgZW5lbXkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgLy8gZWxzZSAoIXNwZWxsW1NQX1NIT1dfREFNQUdFXSkga2VpbmUgU2NoYWRlbnNtZWxkdW5nLgorCisgIC8vIEluZm9ybWF0aW9uZW4gdWViZXIgZGVuIGxldHp0ZW4gQW5ncmlmZiBmZXN0aGFsdGVuCisgIFNldChQX0xBU1RfREFNVFlQRVMsIGRhbV90eXBlKTsKKyAgU2V0KFBfTEFTVF9EQU1USU1FLCAgdGltZSgpKTsKKyAgU2V0KFBfTEFTVF9EQU1BR0UsICAgZGFtKTsKKworICAvLyBCZWkgQW5ncmlmZmVuIG1pdCBTUF9OT19FTkVNWS1GbGFnIGthbm4gbWFuIG5pY2h0IHN0ZXJiZW4gLi4uCisgIGlmICggc3BlbGxbU1BfTk9fRU5FTVldICkKKyAgICByZWR1Y2VfaGl0X3BvaW50cyhkYW0pOworICAvLyAuLi4gYmVpIGFsbGVuIGFuZGVyZW4gbmF0dWVybGljaCBzY2hvbgorICBlbHNlCisgICAgZG9fZGFtYWdlKGRhbSxlbmVteSk7CisKKyAgLy8gZXZ0bC4gaXN0IGRpZXMgT2JqZWt0IGhpZXIgdG90Li4uCisgIGlmICghb2JqZWN0cChNRSkpIHJldHVybiBkYW07CisKKyAgLy8gVGVzdGVuLCBvYiBtYW4gaW4gZGllIEZ1Y2h0IGdlc2NobGFnZW4gd2lyZAorICBDaGVja1dpbXB5QW5kRmxlZSgpOworCisgIC8vIFZlcnVyc2FjaHRlbiBTY2hhZGVuIChpbiBMUCkgenVydWVja2dlYmVuCisgIHJldHVybiBkYW07Cit9CisKK3B1YmxpYyBmbG9hdCBDaGVja1Jlc2lzdGFuY2Uoc3RyaW5nICpkYW1fdHlwZSkgeworICAgIC8vZnVua3Rpb24ga3JpZWd0IGRpZSBzY2hhZGVuc2FydGVuIHVlYmVyZ2ViZW4sIHNjaGF1dCBzaWNoIGRpZXNlcworICAgIC8vc293aWUgUF9SRVNJU1RFTkNFX1NUUkVOR1RIIHVuZCBQX1JFU0lURU5DRV9NT0RGSUZJRVIgYW4gdW5kIGJlcmVjaG5ldAorICAgIC8vZWluZW4gRmFrdG9yLCBtaXQgZGVtIGRpZSB1cnNwcnVlbmdsaWNoZSBTY2hhZGVuc21lbmdlIG11bHRpcGxpemllcnQKKyAgICAvL3dpcmQsIHVtIGRlbiBTY2hhZGVuIG5hY2ggQmVydWVja3NpY2h0aWd1bmcgZGVyIFJlc2lzL0FuZmFlbGxpZ2tlaXRlbiB6dQorICAgIC8vZXJoYWx0ZW4uIFJ1ZWNrZ2FiZXdlcnQgbm9ybWFsZXJ3ZWlzZSAocy51LikgPj0wLgorICBtYXBwaW5nIHJzdHJlbiwgbW9kOworICBmbG9hdCAgIGZha3RvcixuOworICBpbnQgICAgIGk7CisKKyAgbW9kID0gUXVlcnkoUF9SRVNJU1RBTkNFX01PRElGSUVSKTsKKyAgaWYgKCBtYXBwaW5ncChtb2QpICkKKyAgICBtb2QgPSBtb2RbIm1lIl07CisKKyAgaWYgKCAhbWFwcGluZ3AocnN0cmVuPVF1ZXJ5KFBfUkVTSVNUQU5DRV9TVFJFTkdUSFMpKSApCisgIHsKKyAgICBpZiAoIW1hcHBpbmdwKG1vZCkpCisgICAgICByZXR1cm4gMS4wOworICAgIGVsc2UKKyAgICAgIHJzdHJlbiA9IChbXSk7CisgIH0KKworICBpZiAoICFtYXBwaW5ncChtb2QpICkKKyAgICBtb2QgPSAoW10pOworCisgIGlmICggKGk9c2l6ZW9mKGRhbV90eXBlKSk8MSApCisgICAgcmV0dXJuIDEuMDsKKworICBuPXRvX2Zsb2F0KGkpOworICBmYWt0b3I9MC4wOworCisgIC8vZGllcyBoaWVyIHR1dCBuaWNodCBtZWhyIGRhcyBnZXd1ZW5zY2h0ZSwgd2VubiBpbiBQX1JFU0lTVEVOQ0VfU1RSRU5HVEhTCisgIC8vRmFrdG9yZW4gPC0xLjAgYW5nZWdlYmVuIHdlcmRlbi4gUnVlY2tnYWJld2VydGUgPDAgc2luZCBkYW5uIG1vZWdsaWNoIHVuZAorICAvL2xlaWRlciB3ZXJkZW4gZGllIFNjaGFkZW5zYXJ0ZW4gb2huZSBSZXNpcyBuaWNodCBtZWhyIHJpY2h0aWcgdmVyd3Vyc3RldC4gOi0vCisgIGZvcmVhY2goc3RyaW5nIGR0OiBkYW1fdHlwZSkgeworICAgIGZha3RvciA9IGZha3RvciArICgxLjAgKyB0b19mbG9hdChyc3RyZW5bZHRdKSkKKyAgICAgICAgICAgKiAoMS4wICsgdG9fZmxvYXQobW9kW2R0XSkpLTEuMDsKKyAgfQorICByZXR1cm4gMS4wKyhmYWt0b3Ivbik7Cit9CisKK3B1YmxpYyB2YXJhcmdzIG1hcHBpbmcgU3RvcEh1bnRpbmdNb2RlKGludCBzaWxlbnQpCit7IG1hcHBpbmcgc2F2ZV9lbmVteTsKKyAgaW50ICAgICBpOworCisgIHNhdmVfZW5lbXk9ZW5lbWllczsKKyAgaWYgKCAhc2lsZW50ICkKKyAgICB3YWxrX21hcHBpbmcoZW5lbWllcywgIydTdG9wSHVudFRleHQpOyAvLyMnKTsKKworICBlbmVtaWVzPW1fYWxsb2NhdGUoMCwxKTsKKyAgbGFzdF9hdHRhY2tfbXNnPTA7CisKKyAgcmV0dXJuIHNhdmVfZW5lbXk7Cit9CisKK3B1YmxpYyA8b2JqZWN0KnxpbnQqPiogUXVlcnlFbmVtaWVzKCkKK3sKKyAgcmV0dXJuICh7bV9pbmRpY2VzKGVuZW1pZXMpLG1fdmFsdWVzKGVuZW1pZXMpfSk7Cit9CisKK3B1YmxpYyBtYXBwaW5nIEdldEVuZW1pZXMoKQoreworICByZXR1cm4gZW5lbWllczsKK30KKworcHVibGljIG1hcHBpbmcgU2V0RW5lbWllcyg8b2JqZWN0KnxpbnQqPiogbXllbmVtaWVzKQoreworICBlbmVtaWVzPW1rbWFwcGluZyhteWVuZW1pZXNbMF0sbXllbmVtaWVzWzFdKTsKKyAgcmV0dXJuIGVuZW1pZXM7Cit9CisKK3ByaXZhdGUgc3RyaW5nIF9raWxsX2FsaWFzKCBzdHJpbmcgc3RyICkKK3sKKyAgICByZXR1cm4gIlxcIiArIHN0cjsKK30KKworcHVibGljIHZhcmFyZ3Mgdm9pZCBGbGVlKCBvYmplY3Qgb2xkZW52LCBpbnQgZm9yY2UgKQoreyBtaXhlZCAgICpleGl0cywgZXhpdCwgZGV4OworICBtYXBwaW5nIHRtcDsKKyAgaW50ICAgICBpOworICBvYmplY3QgIGVudjsKKworICBpZiAoICFlbnZpcm9ubWVudCgpICkKKyAgICByZXR1cm47CisKKyAgLy8gbWl0ICdmb3JjZScga2FubiBtYW4gZGllIENoZWNrcyB1bWdlaGVuLCBkYW1pdCBkZXIgU3BpZWxlciBhdWYgamVkZW4KKyAgLy8gRmFsbCBmbHVlY2h0ZXQgLi4uCisgIGlmICggIWZvcmNlICYmICggb2xkZW52ICYmIChvbGRlbnYgIT0gZW52aXJvbm1lbnQoKSkgfHwKKyAgICAgICAgICAgICAgICAgICBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSAmJiAoIUVuZW15UHJlc2VudCgpIHx8CisgICAgICAgICAgICAgICAgICAgKFF1ZXJ5UHJvcChQX0hQKSA+PSBRdWVyeVByb3AoUF9XSU1QWSkpKSApICkKKyAgICByZXR1cm47CisKKyAgLy8gLi4uIGFiZXIgTWFnaWVyIGZsdWVjaHRlbiB6dSBsYXNzZW4gaXN0IG5pY2h0IGdhbnogc28gZWluZmFjaCA7LSkKKyAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpICYmIElTX0xFQVJOSU5HKHRoaXNfb2JqZWN0KCkpICkKKyAgICByZXR1cm47CisKKyAgLy8gR2Vpc3RlciBicmF1Y2hlbiBuaWNodCB1bSBpaHIgTGViZW4genUgZnVlcmNodGVuCisgIGlmICggUXVlcnlQcm9wKFBfR0hPU1QpICkKKyAgICByZXR1cm47CisKKyAgdGVsbF9vYmplY3QoIE1FLCAiRGllIEFuZ3N0IGlzdCBzdGFlcmtlciBhbHMgRHUgLi4uICIrCisgICAgICAgICAgICAgICAgICAgIkR1IHdpbGxzdCBudXIgbm9jaCB3ZWcgaGllci5cbiIpOworCisgIGlmICggVGVhbUZsZWUoKSApIC8vIEVyZm9sZ3JlaWNoZSBGbHVjaHQgaW4gaGludGVyZSBLYW1wZnJlaWhlPworICAgIHJldHVybjsKKworICBlbnYgPSBlbnZpcm9ubWVudCgpOworICB0bXAgPSBlbnZpcm9ubWVudCgpLT5RdWVyeVByb3AoUF9FWElUUyk7CisgIGV4aXRzID0gbV9pbmRpY2VzKHRtcCk7CisgIHRtcCA9IGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX1NQRUNJQUxfRVhJVFMpOworICBleGl0cyArPSBtX2luZGljZXModG1wKTsKKworICBpZiAoIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICkKKyAgICAgICAgZXhpdHMgPSBtYXAoIGV4aXRzLCAjJ19raWxsX2FsaWFzLyonKi8gKTsKKworICAvLyBkaWUgRmx1Y2h0cmljaHR1bmcgdm9uIE1hZ2llcm4gd2lyZCBhdXMgU2ljaGVyaGVpdHNncnVlbmRlbgorICAvLyBuaWNodCBhdXNnZXdlcnRldAorICBpZiAoIGludGVyYWN0aXZlKE1FKSAmJiBJU19TRUVSKE1FKSAmJiAhSVNfTEVBUk5FUihNRSkKKyAgICAgICYmIChkZXg9UXVlcnlQcm9wKFBfV0lNUFlfRElSRUNUSU9OKSkgKQorICB7CisgICAgaSA9IDYwICsgNCAqIChRdWVyeVByb3AoUF9MRVZFTCkgLSAzMCkgLyAzOworICAgIGV4aXRzICs9ICh7ZGV4fSk7IC8vIGJldm9yenVndGUgRmx1Y2h0cmljaHR1bmcgbWluZGVzdGVucyBlaW5tYWwKKyAgfQorCisgIGlmICggIXNpemVvZihleGl0cykgKQorICB7CisgICAgdGVsbF9vYmplY3QoIE1FLCAiRHUgdmVyc3VjaHN0IHp1IGZsaWVoZW4sIHNjaGFmZnN0IGVzIGFiZXIgbmljaHQuXG4iICk7CisKKyAgICByZXR1cm47CisgIH0KKworICB3aGlsZSAoIHNpemVvZihleGl0cykgJiYgKGVudmlyb25tZW50KCk9PWVudikgKQorICB7CisgICAgaWYgKCBkZXggICAgICAgICAgICAgICAgICAgICAgICAgLy8gVm9yenVnc3dlaXNlIEZsdWNodHJpY2h0dW5nPworICAgICAgICAmJiAobWVtYmVyKGV4aXRzLGRleCkgPj0gMCkgIC8vIG1vZWdsaWNoPworICAgICAgICAmJiAocmFuZG9tKDEwMCkgPD0gaSkpICAgICAgIC8vIHVuZCBXYWhyc2NoZWlubGljaGtlaXQgZ3Jvc3MgZ2VudWc/CisgICAgICBleGl0ID0gZGV4OworICAgIGVsc2UKKyAgICAgIGV4aXQgPSBleGl0c1tyYW5kb20oc2l6ZW9mKGV4aXRzKSldOworCisgICAgY2F0Y2goY29tbWFuZChleGl0KTtwdWJsaXNoKTsKKyAgICBleGl0cyAtPSAoe2V4aXR9KTsKKyAgfQorCisgIGlmICggZW52aXJvbm1lbnQoKT09ZW52ICkKKyAgICB0ZWxsX29iamVjdCggTUUsICJEZWluIEZsdWNodHZlcnN1Y2ggaXN0IGdlc2NoZWl0ZXJ0LlxuIiApOworfQorCitwdWJsaWMgb2JqZWN0IEVuZW15UHJlc2VudCgpCit7CisgIGZvcmVhY2gob2JqZWN0IGVuOiBlbmVtaWVzKSB7CisgICAgaWYgKGVudmlyb25tZW50KCk9PWVudmlyb25tZW50KGVuKSkKKyAgICAgIHJldHVybiBlbjsKKyAgfQorICByZXR1cm4gMDsKK30KKworcHVibGljIG9iamVjdCBJbkZpZ2h0KCkKK3sKKyAgcmV0dXJuIEVuZW15UHJlc2VudCgpOworfQorCitwdWJsaWMgdmFyYXJncyBpbnQgU3RvcEh1bnRJRChzdHJpbmcgc3RyLCBpbnQgc2lsZW50KSB7IAorCisgIGlmICggIXN0cmluZ3Aoc3RyKSApCisgICAgcmV0dXJuIDA7CisKKyAgaW50IGo7CisgIGZvcmVhY2gob2JqZWN0IGVuOiBlbmVtaWVzKSB7CisgICAgaWYgKGVuLT5pZChzdHIpKSB7CisgICAgICBTdG9wSHVudEZvcihlbixzaWxlbnQpOworICAgICAgaisrOworICAgIH0KKyAgfQorCisgIHJldHVybiBqOworfQorCitwdWJsaWMgaW50IFNwZWxsRGVmZW5kKG9iamVjdCBjYXN0ZXIsIG1hcHBpbmcgc2luZm8pCit7IGludCAgICByZTsKKyAgbWl4ZWQgIHJlczsKKyAgc3RyaW5nICppbmQ7CisKKyAgcmUgPSBVc2VTa2lsbChTS19TUEVMTF9ERUZFTkQsKFsgU0lfU0tJTExBUkcgOiBzaW5mbyAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJX0VORU1ZICAgIDogY2FzdGVyIF0pICk7CisKKyAgaWYgKCAocmVzPVF1ZXJ5UHJvcChQX01BR0lDX1JFU0lTVEFOQ0VfT0ZGU0VUKSkgJiYgbWFwcGluZ3AocmVzKQorICAgICAgJiYgcG9pbnRlcnAoc2luZm9bU0lfTUFHSUNfVFlQRV0pKQorICB7CisgICAgaW5kID0gbV9pbmRpY2VzKHJlcykgJiBzaW5mb1tTSV9NQUdJQ19UWVBFXTsKKworICAgIGlmIChwb2ludGVycChpbmQpICYmIHNpemVvZihpbmQpICkgeworICAgICAgZm9yZWFjaChzdHJpbmcgaW5kZXggOiBpbmQpCisgICAgICAgIHJlKz1yZXNbaW5kZXhdOworICAgIH0KKyAgfQorICBlbHNlIGlmKHJlcyAmJiBpbnRwKHJlcykpCisgICAgcmUrPXJlczsKKworICBpZiAoIChyZT4zMzMzKSAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpICkKKyAgICByZT0zMzMzOyAvKiBNYXhpbWFsIDMzJSBBYndlaHJjaGFuY2UgYmVpIFNwaWVsZXJuICovCisgIHJldHVybiByZTsKK30KKworLy8gKioqKiB0aGlzIGlzIHByb3BlcnR5LWxpa2UKKworc3RhdGljIGludCBfc2V0X2F0dGFja19idXN5KG1peGVkIHZhbCkKK3sKKyAgaWYgKCAoKHRvX2ludCh2YWwpKT41KSAmJiBwcmV2aW91c19vYmplY3QoMSkKKyAgICAgICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUocHJldmlvdXNfb2JqZWN0KDEpKSApCisgICAgbG9nX2ZpbGUoIkFUVEFDS0JVU1kiLHNwcmludGYoIiVzICVkIFRhZXRlcjogJU8gT3BmZXI6ICVPXG4iLAorICAgICAgICAgICAgIGR0aW1lKHRpbWUoKSksdG9faW50KHZhbCkscHJldmlvdXNfb2JqZWN0KDEpLHRoaXNfb2JqZWN0KCkpKTsKKworICBhdHRhY2tfYnVzeS09dG9faW50KHZhbCoxMDAuMCk7CisKKyAgaWYgKCBhdHRhY2tfYnVzeTwtMjAwMCApCisgICAgYXR0YWNrX2J1c3k9LTIwMDA7CisKKyAgcmV0dXJuIGF0dGFja19idXN5OworfQorCitzdGF0aWMgaW50IF9xdWVyeV9hdHRhY2tfYnVzeSgpCit7CisgIGlmIChJU19MRUFSTklORyhNRSkpCisgICAgcmV0dXJuIDA7CisKKyAgcmV0dXJuIChhdHRhY2tfYnVzeTwxMDApOworfQorCisvLyAqKioqIGxvY2FsIHByb3BlcnR5IG1ldGhvZHMKK3N0YXRpYyBpbnQgX3NldF93aW1weShpbnQgaSkKK3sKKyAgaWYgKCAhaW50cChpKSB8fCAoaT5RdWVyeVByb3AoUF9NQVhfSFApKSB8fCAoaTwwKSApCisgICAgcmV0dXJuIDA7CisKKyAgLy8gZ2dmLiBTdGF0dXNyZXBvcnQgYXVzZ2ViZW4KKyAgaWYgKGludGVyYWN0aXZlKE1FKSkKKyAgICBzdGF0dXNfcmVwb3J0KERPX1JFUE9SVF9XSU1QWSwgaSk7CisKKyAgcmV0dXJuIFNldChQX1dJTVBZLCBpKTsKK30KKworc3RhdGljIHN0cmluZyBfc2V0X3dpbXB5X2RpcihzdHJpbmcgcykgeworICAvLyBnZ2YuIFN0YXR1c3JlcG9ydCBhdXNnZWJlbgorICBpZiAoaW50ZXJhY3RpdmUoTUUpKQorICAgIHN0YXR1c19yZXBvcnQoRE9fUkVQT1JUX1dJTVBZX0RJUiwgcyk7CisgIHJldHVybiBTZXQoUF9XSU1QWV9ESVJFQ1RJT04sIHMsIEZfVkFMVUUpOworfQorCitzdGF0aWMgbWl4ZWQgX3NldF9oYW5kcyhtaXhlZCBoKQoreyAKKyAgaWYgKCBzaXplb2YoaCk9PTIgKQorICAgIGggKz0gKHsgKHtEVF9CTFVER0VPTn0pIH0pOworICBpZiAoIXBvaW50ZXJwKGhbMl0pKQorICAgIGhbMl0gPSAoe2hbMl19KTsKKyAgcmV0dXJuIFNldChQX0hBTkRTLCBoLCBGX1ZBTFVFKTsKK30KKworLy9UT0RPIG5vcm1hbGlzaWVyZW4va29ycmlnaWVyZW4gaW4gdXBkYXRlc19hZnRlcl9yZXN0b3JlKCkuCitzdGF0aWMgbWl4ZWQgX3F1ZXJ5X2hhbmRzKCkKK3sKKyAgbWl4ZWQgKmhhbmRzID0gUXVlcnkoUF9IQU5EUyk7CisgIGlmICggIWhhbmRzICkKKyAgICByZXR1cm4gU2V0KFBfSEFORFMsICh7ICIgbWl0IGJsb3NzZW4gSGFlbmRlbiIsIDMwLCAoe0RUX0JMVURHRU9OfSl9KSk7CisgIGVsc2UgaWYgKCBzaXplb2YoaGFuZHMpPDMgKQorICAgIHJldHVybiBTZXQoUF9IQU5EUywgKHtoYW5kc1swXSwgaGFuZHNbMV0sICh7RFRfQkxVREdFT059KX0pKTsKKyAgZWxzZSBpZiAoICFwb2ludGVycChoYW5kc1syXSkgKQorICAgIHJldHVybiBTZXQoUF9IQU5EUywgKHtoYW5kc1swXSwgaGFuZHNbMV0sICh7IGhhbmRzWzJdIH0pfSkpOworCisgIHJldHVybiBRdWVyeShQX0hBTkRTKTsKK30KKworc3RhdGljIGludCBfcXVlcnlfdG90YWxfd2MoKQoreyBtaXhlZCByZXM7CisgIGludCAgIHRvdHdjOworCisgIGlmICggb2JqZWN0cChyZXM9UXVlcnlQcm9wKFBfV0VBUE9OKSkgKQorICAgIHRvdHdjID0gKChpbnQpKHJlcy0+UXVlcnlQcm9wKFBfV0MpKSk7CisgIGVsc2UgaWYgKCBwb2ludGVycChyZXM9UXVlcnlQcm9wKFBfSEFORFMpKSAmJiBzaXplb2YocmVzKT4xCisgICAgICAgICAgICYmIGludHAocmVzWzFdKSApCisgICAgdG90d2M9KChpbnQpcmVzWzFdKTsKKyAgZWxzZQorICAgIHRvdHdjPTMwOworCisgIHRvdHdjID0gKCgyKnRvdHdjKSsoMTAqUXVlcnlBdHRyaWJ1dGUoQV9TVFIpKSkvMzsKKworICByZXR1cm4gU2V0KFBfVE9UQUxfV0MsIHRvdHdjLCBGX1ZBTFVFKTsKK30KKworc3RhdGljIGludCBfcXVlcnlfdG90YWxfYWMoKSB7CisKKyAgaW50IHRvdGFjID0gMDsKKyAgb2JqZWN0ICphcm1vdXJzID0gUXVlcnlQcm9wKFBfQVJNT1VSUyk7CisgIG9iamVjdCBwYXJyeSA9IFF1ZXJ5UHJvcChQX1BBUlJZX1dFQVBPTik7CisKKyAgaWYgKCBtZW1iZXIoYXJtb3VycywwKT49MCApIHsKKyAgICBhcm1vdXJzIC09ICh7IDAgfSk7IAorICB9CisKKyAgZm9yZWFjaChvYmplY3QgYXJtb3VyOiBhcm1vdXJzKQorICAgIHRvdGFjICs9ICgoaW50KWFybW91ci0+UXVlcnlQcm9wKFBfQUMpKTsKKworICBpZiAoIG9iamVjdHAocGFycnkpICkKKyAgICB0b3RhYyArPSBwYXJyeS0+UXVlcnlQcm9wKFBfQUMpOworCisgIHRvdGFjICs9IChRdWVyeVByb3AoUF9CT0RZKStRdWVyeUF0dHJpYnV0ZShBX0RFWCkpOworCisgIHJldHVybiBTZXQoUF9UT1RBTF9BQywgdG90YWMsIEZfVkFMVUUpOworfQorCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfcmVzaXN0YW5jZV9zdHJlbmd0aHMoKSB7CisKKyAgVXBkYXRlUmVzaXN0YW5jZVN0cmVuZ3RocygpOworCisgIG1hcHBpbmcgcnN0cmVuID0gY29weShRdWVyeShQX1JFU0lTVEFOQ0VfU1RSRU5HVEhTLCBGX1ZBTFVFKSk7CisgIG1hcHBpbmcgbW9kID0gUXVlcnkoUF9SRVNJU1RBTkNFX01PRElGSUVSLCBGX1ZBTFVFKTsKKworICBpZiAoICFtYXBwaW5ncChyc3RyZW4pICkKKyAgICByc3RyZW4gPSAoW10pOworCisgIGlmICggIW1hcHBpbmdwKG1vZCkgfHwgIW1hcHBpbmdwKG1vZD1tb2RbIm1lIl0pIHx8ICFzaXplb2YobW9kKSApCisgICAgcmV0dXJuIHJzdHJlbjsKKworICBmb3JlYWNoKHN0cmluZyBtb2RrZXksIGZsb2F0IG1vZHZhbHVlIDogbW9kKQorICAgIHJzdHJlblttb2RrZXldID0gKCgxLjArcnN0cmVuW21vZGtleV0pKigxLjArbW9kdmFsdWUpKS0xLjA7CisKKyAgcmV0dXJuIHJzdHJlbjsKK30KKworc3RhdGljIGludCBfc2V0X2Rpc2FibGVfYXR0YWNrKGludCB2YWwpCit7CisgIGlmICh2YWw8LTEwMDAwMCkKKyAgICAgICAgICAgeworICAgICAgICAgICAgICAgICAgbG9nX2ZpbGUoIlBBUkFMWVNFX1RPT19MT1ciLAorICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCJXZXJ0IHp1IGtsZWluOiAlcywgV2VydDogJWQsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQXVmcnVmZXI6ICVPLCBPcGZlcjogJU8iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0aW1lKHRpbWUoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWwscHJldmlvdXNfb2JqZWN0KDEpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc19vYmplY3QoKSkpOworICAgICAgICAgICB9CisgIGlmICggdmFsPjMwICkKKyAgICB2YWw9MzA7CisgIGlmICggKHZhbD49MjApICYmIHByZXZpb3VzX29iamVjdCgxKSE9TUUgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKQorICAgIGxvZ19maWxlKCJQQVJBTFlTRSIsc3ByaW50ZigiJXMgJWQgVGFldGVyOiAlTyBPcGZlcjogJU9cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0aW1lKHRpbWUoKSlbNC4uMTVdLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWwscHJldmlvdXNfb2JqZWN0KDEpLHRoaXNfb2JqZWN0KCkpKTsKKyAKKyAgaWYgKHRpbWUoKTxRdWVyeVByb3AoUF9ORVhUX0RJU0FCTEVfQVRUQUNLKSkKKyAgeworICAgIC8vIGd1ZWx0aWdlIFplaXRzcGVycmUgZXhpc3RpZXJ0LgorICAgIC8vIEVyaG9laGVuIHZvbiBQX0RJU0FCTEVfQVRUQUNLIGdlaHQgZGFubiBuaWNodC4gKEphLCBhdWNoIG5pY2h0IGVyaG9laGVuCisgICAgLy8gZWluZXMgbmVnYXRpdmVuIFBfRElTQUJMRV9BVFRBQ0spCisgICAgaWYgKHZhbCA+PSBRdWVyeVByb3AoUF9ESVNBQkxFX0FUVEFDSykpCisgICAgICByZXR1cm4gRElTQUJMRV9UT09fRUFSTFk7CisgICAgLy8gdmFsIGlzdCBrbGVpbmVyIGFscyBha3R1ZWxsZXMgUF9ESVNBQkxFX0FUVEFDSyAtIGRhcyBpc3QgZXJsYXVidCwgQUJFUiBlcworICAgIC8vIGRhcmYgZGllIGJlc3RlaGVuZGUgWmVpdHNwZXJyZSBuaWNodCB2ZXJyaW5nZXJuLCBkYWhlciB3aXJkIHNpZSBuaWNodAorICAgIC8vIGdlYWVuZGVydC4KKyAgICByZXR1cm4gU2V0KFBfRElTQUJMRV9BVFRBQ0ssdmFsLEZfVkFMVUUpOworICB9CisgIC8vIGVzIGV4aXN0aWVydCBrZWluZSBndWVsdGlnZSBaZWl0c3BlcnJlIC0gZGFubiB3aXJkIHNpZSBudW4gZ2VzZXR6dC4KKyAgLy8gKFNvbGx0ZSB2YWwgPCAwIHNlaW4sIHdpcmQgZWluZSBaZWl0c3BlcnJlIGluIGRlciBWZXJnYW5nZW5oZWl0IGdlc2V0enQsCisgIC8vIGRpZSBzY2hvbiBhYmdlbGF1ZmVuIGlzdC4gRGFzIGlzdCB1ZWJlcmZsdWVzc2lnLCBzY2hhZGV0IGFiZXIgYXVjaAorICAvLyBuaWNodC4pCisgIFNldFByb3AoUF9ORVhUX0RJU0FCTEVfQVRUQUNLLHRpbWUoKSt2YWwqMipfX0hFQVJUX0JFQVRfSU5URVJWQUxfXyk7CisgIHJldHVybiBTZXQoUF9ESVNBQkxFX0FUVEFDSyx2YWwpOworfQorCisvLyBOZXVlIFZlcndhbHR1bmcgZGVyIEhhZW5kZToKKworLy8gUF9IQU5EU19VU0VEX0JZIGVuaGFlbHQgZWluIEFycmF5IG1pdCBhbGxlbiBPYmpla3RlbiwgZGllIEhhZW5kZQorLy8gYmVsZWdlbiwgamVkZXMga29tbXQgc28gb2Z0IHZvciB3aWUgSGFlbmRlIGJlbGVndCB3ZXJkZW4uCisKK3N0YXRpYyBtaXhlZCAqX3F1ZXJ5X2hhbmRzX3VzZWRfYnkoKQoreworICByZXR1cm4gKChRdWVyeShQX0hBTkRTX1VTRURfQlksIEZfVkFMVUUpIHx8ICh7fSkgKSAtICh7MH0pKTsKK30KKworc3RhdGljIGludCBfcXVlcnlfdXNlZF9oYW5kcygpCit7CisgIHJldHVybiBzaXplb2YoUXVlcnlQcm9wKFBfSEFORFNfVVNFRF9CWSkpOworfQorCitzdGF0aWMgaW50IF9xdWVyeV9mcmVlX2hhbmRzKCkKK3sKKyAgcmV0dXJuIChRdWVyeVByb3AoUF9NQVhfSEFORFMpLVF1ZXJ5UHJvcChQX1VTRURfSEFORFMpKTsKK30KKworcHVibGljIHZhcmFyZ3MgaW50IFVzZUhhbmRzKG9iamVjdCBvYiwgaW50IG51bSkKK3sgbWl4ZWQgKmg7CisKKyAgaWYgKCAhb2IgJiYgIShvYj1wcmV2aW91c19vYmplY3QoMSkpICkKKyAgICByZXR1cm4gMDsKKworICBpZiAoIChudW08PTApICYmICgobnVtPW9iLT5RdWVyeVByb3AoUF9IQU5EUykpPD0wKSApCisgICAgcmV0dXJuIDA7CisKKyAgaD1RdWVyeVByb3AoUF9IQU5EU19VU0VEX0JZKS0oe29ifSk7CisKKyAgaWYgKCAoc2l6ZW9mKGgpK251bSk+UXVlcnlQcm9wKFBfTUFYX0hBTkRTKSApCisgICAgcmV0dXJuIDA7CisKKyAgZm9yZWFjaChpbnQgaTogbnVtKQorICAgIGgrPSh7b2J9KTsKKworICBTZXRQcm9wKFBfSEFORFNfVVNFRF9CWSxoKTsKKworICByZXR1cm4gMTsKK30KKworcHVibGljIHZhcmFyZ3MgaW50IEZyZWVIYW5kcyhvYmplY3Qgb2IpCit7CisgIGlmICggIW9iICYmICEob2I9cHJldmlvdXNfb2JqZWN0KDEpKSApCisgICAgcmV0dXJuIDA7CisKKyAgU2V0UHJvcChQX0hBTkRTX1VTRURfQlksUXVlcnlQcm9wKFBfSEFORFNfVVNFRF9CWSktKHtvYn0pKTsKKworICByZXR1cm4gMTsKK30KKworLy8gS29tcGF0aWJsaXRhZXRzZnVua3Rpb25lbjoKKworc3RhdGljIGludCBfc2V0X3VzZWRfaGFuZHMoaW50IG5ld19udW0pCit7IGludCAgICBvbGRfbnVtLCBkaWY7CisgIG9iamVjdCBvYjsKKworICBvbGRfbnVtPVF1ZXJ5UHJvcChQX1VTRURfSEFORFMpOworCisgIGlmICggIW9iamVjdHAob2I9cHJldmlvdXNfb2JqZWN0KDEpKSApCisgICAgcmV0dXJuIG9sZF9udW07CisKKyAgLy8gTWVsZHVuZyBpbnMgRGVidWdsb2cgc2NocmVpYmVuLiBBdWZydWZlciBzb2xsdGUgZ2VmaXh0IHdlcmRlbi4KKyAgZGVidWdfbWVzc2FnZShzcHJpbnRmKCJQX1VTRURfSEFORFMgaW4gJU8gd2lyZCBnZXNldHp0IGR1cmNoICVPXG4iLAorICAgICAgICB0aGlzX29iamVjdCgpLCBvYiksIERNU0dfTE9HRklMRXxETVNHX1NUQU1QKTsKKworICBpZiAoICEoZGlmPW5ld19udW0tb2xkX251bSkgKQorICAgIHJldHVybiBuZXdfbnVtOworCisgIGlmICggZGlmPjAgKQorICAgIFVzZUhhbmRzKG9iLGRpZik7CisgIGVsc2UKKyAgICBGcmVlSGFuZHMob2IpOworCisgIHJldHVybiBRdWVyeVByb3AoUF9VU0VEX0hBTkRTKTsKK30KKworLy8gRnVua3Rpb25lbiBmdWVyIEJlZ3J1ZXNzdW5nc3NjaGxhZyAvIE5hY2tlbnNjaGxhZzoKKworcHVibGljIGludCBDaGVja0VuZW15KG9iamVjdCBvYikKK3sKKyAgcmV0dXJuIChsaXZpbmcob2IpICYmIElzRW5lbXkob2IpKTsKK30KKworcHVibGljIHZhcmFyZ3Mgdm9pZCBFeGVjdXRlTWlzc2luZ0F0dGFja3Mob2JqZWN0ICpyZW1vdmVfYXR0YWNrZXJzKQoreworICBpZiAoICFwb2ludGVycChtaXNzaW5nX2F0dGFja3MpICkKKyAgICBtaXNzaW5nX2F0dGFja3M9KHt9KTsKKworICBpZiAoIHBvaW50ZXJwKHJlbW92ZV9hdHRhY2tlcnMpICkKKyAgICBtaXNzaW5nX2F0dGFja3MtPXJlbW92ZV9hdHRhY2tlcnM7CisKKyAgZm9yZWFjaChvYmplY3Qgb2IgOiBtaXNzaW5nX2F0dGFja3MpIHsKKyAgICBpZiAoIG9iamVjdHAob2IpICYmIChlbnZpcm9ubWVudChvYik9PWVudmlyb25tZW50KCkpICkKKyAgICAgIG9iLT5BdHRhY2syKE1FKTsKKyAgfQorICBtaXNzaW5nX2F0dGFja3M9KHt9KTsKK30KKworcHVibGljIHZvaWQgSW5pdEF0dGFjaygpCit7IG9iamVjdCBvYixuZXh0OworICBjbG9zdXJlIGNiOworCisgIGlmICggIWxpdmluZyhNRSkgKQorICAgIHJldHVybjsKKworICBFeGVjdXRlTWlzc2luZ0F0dGFja3MoKTsKKyAgLy9FTUEga2FubiBkYXMgTGl2aW5nIHplcnN0b2VyZW4gb2RlciB0b2V0ZW4uLi4KKyAgaWYgKCFsaXZpbmcoTUUpIHx8IFF1ZXJ5UHJvcChQX0dIT1NUKSkgcmV0dXJuOworCisgIGlmICggb2JqZWN0cChvYj1Jc1RlYW1Nb3ZlKCkpICkKKyAgICBjYj1zeW1ib2xfZnVuY3Rpb24oIkluaXRBdHRhY2tfQ2FsbGJhY2siLG9iKTsKKyAgZWxzZQorICAgIGNiPTA7CisKKyAgZm9yICggb2I9Zmlyc3RfaW52ZW50b3J5KGVudmlyb25tZW50KCkpIDsgb2JqZWN0cChvYikgOyBvYj1uZXh0KQorICB7CisgICAgbmV4dD1uZXh0X2ludmVudG9yeShvYik7CisKKyAgICBpZiAoICFsaXZpbmcob2IpICkKKyAgICAgIGNvbnRpbnVlOworCisgICAgaWYgKG9iLT5Jc0VuZW15KE1FKSkKKyAgICB7CisgICAgICAvLyBEYXMgaXN0IG5pY2h0IHNvIHNpbm5sb3Mgd2llIGVzIGF1c3NpZWh0LiBhKSB3ZXJkZW4gZGllIEh1bnR0aW1lcworICAgICAgLy8gYWt0dWFsaXNpZXJ0IHVuZCBiKSB3ZXJkZW4gVGVhbW1pdGdsaWVkZXIgdm9uIG1pciBiZWkgZGllc2VtCisgICAgICAvLyBJbnNlcnRFbmVteSgpIGdnZi4gZXJmYXNzdC4KKyAgICAgIG9iLT5JbnNlcnRFbmVteShNRSk7CisKKyAgICAgIGlmICggY2xvc3VyZXAoY2IpICYmIGZ1bmNhbGwoY2Isb2IpICkgLy8gV2lyZCBnYW56ZXMgVGVhbSBnZW1vdmVkPworICAgICAgICBtaXNzaW5nX2F0dGFja3MgKz0gKHsgb2IgfSk7IC8vIERhbm4gZXJzdG1hbCB3YXJ0ZW4gYmlzIGFsbGUgZGEgc2luZAorICAgICAgZWxzZQorICAgICAgICBvYi0+QXR0YWNrMihNRSk7CisKKyAgICB9CisgICAgZWxzZSBpZiAoIElzRW5lbXkob2IpICkKKyAgICB7CisgICAgICAvLyBEYXMgaXN0IG5pY2h0IHNvIHNpbm5sb3Mgd2llIGVzIGF1c3NpZWh0LiBhKSB3ZXJkZW4gZGllIEh1bnR0aW1lcworICAgICAgLy8gYWt0dWFsaXNpZXJ0IHVuZCBiKSB3ZXJkZW4gVGVhbW1pdGdsaWVkZXIgdm9uIG9iIGJlaSBkaWVzZW0gCisgICAgICAvLyBJbnNlcnRFbmVteSgpIGdnZi4gZXJmYXNzdC4KKyAgICAgIEluc2VydEVuZW15KG9iKTsKKyAgICAgIEF0dGFjazIob2IpOworICAgIH0KKyAgICAvL0F0dGFjazIga2FubiBkaWVzZXMgT2JqZWt0IHplcnN0b2VyZW4gb2RlciB0b2V0ZW4uIFdlbm4gamE6IGFiYnJ1Y2gKKyAgICBpZiAoICFsaXZpbmcoTUUpIHx8IFF1ZXJ5UHJvcChQX0dIT1NUKSkgYnJlYWs7CisgIH0KK30KKworcHVibGljIHZvaWQgRXhpdEF0dGFjaygpCit7CisgIGlmICggIWxpdmluZyhNRSkgKQorICAgIHJldHVybjsKKworICAvLyBOb2NoIG5hY2h6dWhvbGVuZGUgQmVncnVlc3N1bmdzc2NobGFlZ2U6CisgIEV4ZWN1dGVNaXNzaW5nQXR0YWNrcygpOworfQorCitwdWJsaWMgb2JqZWN0fG9iamVjdCp8bWFwcGluZyBRdWVyeUFybW91ckJ5VHlwZShzdHJpbmcgdHlwZSkKK3sKKyAgLy8gUnVlY2tnYWJld2VydDoKKyAgLy8gRElFIFJ1ZXN0dW5nIHZvbSBUeXAgPHR5cGU+LCBmYWxscyA8dHlwZT4gbmljaHQgQVRfTUlTQywKKyAgLy8gQXJyYXkgYWxsZXIgQVRfTUlTQy1SdWVzdHVuZ2VuIGZhbGxzIDx0eXBlPiBBVF9NSVNDIChhdWNoIGxlZXIpLAorICAvLyBNYXBwaW5nIG1pdCBhbGxlbiBvYmVuIGdlbmFubnRlbiBJbmZvcywgZmFsbHMgPHR5cGU+IE51bGwKKworICBvYmplY3QgKmFybW91cnM7CisgIHN0cmluZyB0eXAyOworCisgIC8vIFdlbm4gQ2FjaGUgdm9yaGFuZGVuLCBkYW5uIENhY2hlIGxpZWZlcm4uCisgIGlmIChtYXBwaW5ncChRQUJUQ2FjaGUpKSB7CisgICAgaWYgKHR5cGUgPT0gQVRfTUlTQykKKyAgICAgIHJldHVybiBRQUJUQ2FjaGVbQVRfTUlTQ10gLSAoezB9KTsKKyAgICBlbHNlIGlmICh0eXBlKQorICAgICAgcmV0dXJuIFFBQlRDYWNoZVt0eXBlXTsKKyAgICBlbHNlCisgICAgICByZXR1cm4gY29weShRQUJUQ2FjaGUpOworICB9CisKKyAgaWYgKCAhcG9pbnRlcnAoYXJtb3Vycz1RdWVyeVByb3AoUF9BUk1PVVJTKSkgKQorICAgIGFybW91cnM9KHt9KTsKKworICAvLyBDYWNoZSBlcnpldWdlbgorICBRQUJUQ2FjaGUgPSAoWyBBVF9NSVNDOiAoe30pIF0pOworICBmb3JlYWNoKG9iamVjdCBvYjogYXJtb3VycyAtICh7MH0pICkgeworICAgIGlmICggIXN0cmluZ3AodHlwMj1vYi0+UXVlcnlQcm9wKFBfQVJNT1VSX1RZUEUpKSApCisgICAgICBjb250aW51ZTsKKyAgICBpZiAoIHR5cDI9PUFUX01JU0MgKQorICAgICAgUUFCVENhY2hlW0FUX01JU0NdICs9ICh7b2J9KTsKKyAgICBlbHNlCisgICAgICBRQUJUQ2FjaGVbdHlwMl0gPSBvYjsKKyAgfQorICAvLyBVbmQgZ2V3dWVuc2NodGVzIERhdHVtIGxpZWZlcm4uCisgIGlmICh0eXBlKQorICAgIHJldHVybiBRQUJUQ2FjaGVbdHlwZV07CisgIGVsc2UKKyAgICByZXR1cm4gY29weShRQUJUQ2FjaGUpOworfQorCisvL1RPRE86IGxhbmdmcmlzdGlnIHdhZXJzIGJlc3Nlciwgd2VubiBoaWVyIG5pY2h0IGplZGVyIHBlciBTZXRQcm9wKCkgZHJhdWYKKy8vbG9zIHNjaHJlaWJlbiB3dWVyZGUuCitzdGF0aWMgb2JqZWN0ICpfc2V0X2FybW91cnMob2JqZWN0ICphcm1vdXJzKSB7CisgIGlmIChwb2ludGVycChhcm1vdXJzKSkgeworICAgIC8vIENhY2hlIHdlZ3dlcmZlbgorICAgIFFBQlRDYWNoZSA9IDA7CisgICAgLy8gYXJtb3VycyBnZ2YuIHVuaWZpemllcmVuLiBBdXNzZXJkZW0gS29waWUgcmVpbnNjaHJlaWJlbi4KKyAgICByZXR1cm4gU2V0KFBfQVJNT1VSUywgbV9pbmRpY2VzKG1rbWFwcGluZyhhcm1vdXJzKSksIEZfVkFMVUUpOworICB9CisgIHJldHVybiBRdWVyeVByb3AoUF9BUk1PVVJTKTsKK30KKworLyoqIFJlZHV6aWVydCBkaWUgQmVmcmllZGV6YWVobGVyIHBybyBSZXNldCBpbSBEdXJjaHNjaG5pdHQgdW0gMi41LgorICBCZXJlY2huZXQgZ2FuenphaGxpZ2UgZHVyY2hzY2huaXR0bGljaGUgUmVzZXRzIHNlaXQgZGVtIGxldHp0ZW4gRXhwaXJlIHVuZAorICBlcmhvZWh0IGRpZSBsZXR6dGUgRXhwaXJlemVpdCB1bSBSZXNldHMqX19SRVNFVF9USU1FX18gKFN0YW5kYXJkIEludGVydmFsbAorICBmdWVyIFJlc2V0IGlzdCBtb21lbnRhbiAzNjAwcywgaW0gRHVyY2hzY2huaXR0IGtvbW1lbiBkYW5uIDI3MDAgendpc2NoZW4gMgorICBSZXNldHMgYmVpIHJhdXMpLiBTbyB3aXJkIGRlciB1bmdhbnp6YWhsaWdlIFJlc3QgYmVpbSBuYWVjaHN0ZW4gQXVmcnVmCisgIGJlcnVlY2tzaWNodGlndC4KKyAgRGllc2UgVmFyaWFudGUgZGVzIEV4cGlyZXMgd3VyZGUgZ2V3YWVobHQsIHVtIHp1IHZlcm1laWRlbiwgY29tYmF0LmMgZWluZW4KKyAgcmVzZXQoKSB6dSBnZWJlbiB1bmQgaW4gamVkZW0gUmVzZXQgaW4gamVkZW0gTGViZXdlc2VuIGVpbiBFeHBpcmUgbWFjaGVuIHp1CisgIG11ZXNzZW4sIGF1Y2ggd2VubiBudXIgaW4gc2VociB3ZW5pZ2VuIExlYmV3ZXNlbiB3YXMgZ2VtYWNodCB3ZXJkZW4gbXVzcy4KKyAgQHBhcmFtW2luLG91dF0gcGggTWFwcGluZyBhdXMgUF9QRUFDRV9ISVNUT1JZLiBXaXJkIGRpcmVrdCBha3R1YWxpc2llcnQuCisgIEBhdHRlbnRpb24gTXVzcyBlaW4gZ3VlbHRpZ2VzIFBfUEVBQ0VfSElTVE9SWSB1ZWJlcmdlYmVuIGJla29tbWVuLCBhbmRlcmVtCisgIERhdGVudHlwIGlua2wuIDAgd2lyZCBkaWUgRnVua3Rpb24gYnVnZ2VuLgorICAqLworcHJpdmF0ZSB2b2lkIF9kZWNheV9wZWFjZV9oaXN0b3J5KG1peGVkIHBoKSB7CisgIC8vIEdhbnp6YWhsaWdlIHJlc2V0cyBzZWl0IGxldHp0ZW0gRXhwaXJlIGVybWl0dGVsbi4gKER1cmNoc2Nobml0dCkKKyAgaW50IHJlc2V0cyA9ICh0aW1lKCkgLSBwaFswXSkgLyAoX19SRVNFVF9USU1FX18qNzUvMTAwKTsKKyAgLy8gYXVmIFplaXRzdGVtcGVsIGRyYXVmcmVjaG5lbiwgZGFtaXQgZGVyIHVuZ2FuenphaGxpZ2UgUmVzdCBuaWNodAorICAvLyB2ZXJsb3JlbmdlaHQsIGRlciB3aXJkIGJlaW0gbmFlY2hzdGVuIEV4cGlyZSBkYW5uIGJlcnVlY2tzaWNodGlndC4KKyAgcGhbMF0gKz0gcmVzZXRzICogKF9fUkVTRVRfVElNRV9fICogNzUgLyAxMDApOworICAvLyBwcm8gUmVzZXQgd2VyZGVuIGltIER1cmNoc2Nobml0dCAyLjUgVmVyc3VjaGUgYWJnZXpvZ2VuLiAoSGllciB3ZXJkZW4KKyAgLy8gYmVpbSBFeHBpcmUgbWFsIDIgdW5kIG1hbCAzIFZlcnN1Y2hlIHBybyBSZXNldCBnZXJlY2huZXQuIEFiZXIgZmFsbHMgaGllcgorICAvLyB2aWVsZSBSZXNldHMgdmVyZ2FuZ2VuIHNpbmQsIGlzdCBlcyB2ZXJtdXRsaWNoIGVoIGVnYWwsIHdlaWwgZGllIENvdW50ZXIKKyAgLy8gYXVmIDAgZmFsbGVuLikKKyAgaW50IGV4cGlyZSA9IHJlc2V0cyAqIChyYW5kb20oMikgKyAyKTsKKyAgLy8gdWViZXIgYWxsZSBHaWxkZW4KKyAgbWFwcGluZyB0bXA9cGhbMV07CisgIGZvcmVhY2goc3RyaW5nIGtleSwgaW50IGNvdW50OiAmdG1wICkgeworICAgIGNvdW50LT1leHBpcmU7CisgICAgaWYgKGNvdW50IDwgMCkgY291bnQgPSAwOworICB9Cit9CisKKy8qKiBQYWNpZnkoKSBkaWVudCB6dXIgQmVzdGltbXVuZywgb2Igc2ljaCBlaW4gTGViZXdlc2VuIGdlcmFkZSAKKyAqIGJlZnJpZWRlbiBsYXNzZW4gd2lsbC4KKyAqIEJlcmVjaG5ldCBlaW5lIFdhaHJzY2hlaW5saWNoa2VpdCBuYWNoIHVudGVuIHN0ZWhlbmRlciBGb3JtZWwsIHdlbGNoZSBkaWUKKyAqIEludGVsbGlnZW56IGRpZXNlcyBMZWJlbndlc2VucywgZGllIEludGVsbGlnZW56IGRlcyBDYXN0ZXJzIHVuZCBkaWUKKyAqIGJpc2hlcmlnZSBBbnphaGwgZXJmb2xncmVpY2hlciBCZWZyaWVkdW5nc3ZlcnN1Y2hlIGRpZXNlciBHaWxkZSBlaW5nZWh0LgorICogQW5zY2hsaWVzc2VuZCB3aXJkIGF1cyBkZXIgV2FocnNjaGVpbmxpY2hrZWl0IHVuZCByYW5kb20oKSBiZXN0aW1tdCwgb2IKKyAqIGRpZXNlciBWZXJzdWNoIGVyZm9sZ3JlaWNoIGlzdC4KK0Zvcm1lbDogdyA9IChJTlRfQ0FTVEVSICsgMTAgLSBBTloqNCkgLyAoSU5UX01FICsgMTApCitJTlRfQ0FTVEVSOiBDYXN0ZXItSW50ZWxsaWdlbnosIElOVF9NRTogSW50ZWxsaWdlbnogZGllc2VzIExpdmluZ3MKK0FOWjogQW56YWhsIGVyZm9sZ3JlaWNoZXIgQmVmcmllZHVuZ3N2ZXJzdWNoZQorCitBbm5haG1lOiBJTlRfQ0FTVEVSID09PSAyMiwgYWxsZSBXYWhyc2NoZWlubGljaGtlaXRlbiAqIDEwMAorCitJTlRfTUUgICBFcmZvbGdzd2FocnNjaGVpbmxpY2hrZWl0ZW4gamUgbmFjaCBBbnphaGwgZXJmb2xncmVpY2hlciBWZXJzdWNoZQorICAgICAgICAgICAgICAxICAgICAgIDIgICAgICAgMyAgICAgICA0ICAgICAgIDUgICAgICAgNiAgICAgICA3ICAgICAgIDgKKyAgICAgIDAgICAgIDI4MCAgICAgMjQwICAgICAyMDAgICAgIDE2MCAgICAgMTIwICAgICAgODAgICAgICA0MCAgICAgICAwCisgICAgICAyICAyMzMsMzMgICAgIDIwMCAgMTY2LDY3ICAxMzMsMzMgICAgIDEwMCAgIDY2LDY3ICAgMzMsMzMgICAgICAgMAorICAgICAgNCAgICAgMjAwICAxNzEsNDMgIDE0Miw4NiAgMTE0LDI5ICAgODUsNzEgICA1NywxNCAgIDI4LDU3ICAgICAgIDAKKyAgICAgIDYgICAgIDE3NSAgICAgMTUwICAgICAxMjUgICAgIDEwMCAgICAgIDc1ICAgICAgNTAgICAgICAyNSAgICAgICAwCisgICAgICA4ICAxNTUsNTYgIDEzMywzMyAgMTExLDExICAgODgsODkgICA2Niw2NyAgIDQ0LDQ0ICAgMjIsMjIgICAgICAgMAorICAgICAxMCAgICAgMTQwICAgICAxMjAgICAgIDEwMCAgICAgIDgwICAgICAgNjAgICAgICA0MCAgICAgIDIwICAgICAgIDAKKyAgICAgMTIgIDEyNywyNyAgMTA5LDA5ICAgOTAsOTEgICA3Miw3MyAgIDU0LDU1ICAgMzYsMzYgICAxOCwxOCAgICAgICAwCisgICAgIDE0ICAxMTYsNjcgICAgIDEwMCAgIDgzLDMzICAgNjYsNjcgICAgICA1MCAgIDMzLDMzICAgMTYsNjcgICAgICAgMAorICAgICAxNiAgMTA3LDY5ICAgOTIsMzEgICA3Niw5MiAgIDYxLDU0ICAgNDYsMTUgICAzMCw3NyAgIDE1LDM4ICAgICAgIDAKKyAgICAgMTggICAgIDEwMCAgIDg1LDcxICAgNzEsNDMgICA1NywxNCAgIDQyLDg2ICAgMjgsNTcgICAxNCwyOSAgICAgICAwCisgICAgIDIwICAgOTMsMzMgICAgICA4MCAgIDY2LDY3ICAgNTMsMzMgICAgICA0MCAgIDI2LDY3ICAgMTMsMzMgICAgICAgMAorICAgICAyMiAgICA4Nyw1ICAgICAgNzUgICAgNjIsNSAgICAgIDUwICAgIDM3LDUgICAgICAyNSAgICAxMiw1ICAgICAgIDAKKyAgICAgMjQgICA4MiwzNSAgIDcwLDU5ICAgNTgsODIgICA0NywwNiAgIDM1LDI5ICAgMjMsNTMgICAxMSw3NiAgICAgICAwCisgICAgIDI2ICAgNzcsNzggICA2Niw2NyAgIDU1LDU2ICAgNDQsNDQgICAzMywzMyAgIDIyLDIyICAgMTEsMTEgICAgICAgMAorICAgICAyOCAgIDczLDY4ICAgNjMsMTYgICA1Miw2MyAgIDQyLDExICAgMzEsNTggICAyMSwwNSAgIDEwLDUzICAgICAgIDAKKyAgICAgMzAgICAgICA3MCAgICAgIDYwICAgICAgNTAgICAgICA0MCAgICAgIDMwICAgICAgMjAgICAgICAxMCAgICAgICAwCisgICAgIDMyICAgNjYsNjcgICA1NywxNCAgIDQ3LDYyICAgIDM4LDEgICAyOCw1NyAgIDE5LDA1ICAgIDksNTIgICAgICAgMAorICAgICAzNCAgIDYzLDY0ICAgNTQsNTUgICA0NSw0NSAgIDM2LDM2ICAgMjcsMjcgICAxOCwxOCAgICA5LDA5ICAgICAgIDAKKyAgICAgMzUgICA2MiwyMiAgIDUzLDMzICAgNDQsNDQgICAzNSw1NiAgIDI2LDY3ICAgMTcsNzggICAgOCw4OSAgICAgICAwCisgICAgIDM2ICAgNjAsODcgICA1MiwxNyAgIDQzLDQ4ICAgMzQsNzggICAyNiwwOSAgIDE3LDM5ICAgICA4LDcgICAgICAgMAorICAgICAzOCAgIDU4LDMzICAgICAgNTAgICA0MSw2NyAgIDMzLDMzICAgICAgMjUgICAxNiw2NyAgICA4LDMzICAgICAgIDAKKyAgICAgNDAgICAgICA1NiAgICAgIDQ4ICAgICAgNDAgICAgICAzMiAgICAgIDI0ICAgICAgMTYgICAgICAgOCAgICAgICAwCisgICAgIDQyICAgNTMsODUgICA0NiwxNSAgIDM4LDQ2ICAgMzAsNzcgICAyMywwOCAgIDE1LDM4ICAgIDcsNjkgICAgICAgMAorICAgICA0NCAgIDUxLDg1ICAgNDQsNDQgICAzNywwNCAgIDI5LDYzICAgMjIsMjIgICAxNCw4MSAgICA3LDQxICAgICAgIDAKKyAgICAgNDYgICAgICA1MCAgIDQyLDg2ICAgMzUsNzEgICAyOCw1NyAgIDIxLDQzICAgMTQsMjkgICAgNywxNCAgICAgICAwCisgICAgIDQ4ICAgNDgsMjggICA0MSwzOCAgIDM0LDQ4ICAgMjcsNTkgICAyMCw2OSAgIDEzLDc5ICAgICA2LDkgICAgICAgMAorICAgICA1MCAgIDQ2LDY3ICAgICAgNDAgICAzMywzMyAgIDI2LDY3ICAgICAgMjAgICAxMywzMyAgICA2LDY3ICAgICAgIDAKKyAgICAgNTIgICA0NSwxNiAgIDM4LDcxICAgMzIsMjYgICAyNSw4MSAgIDE5LDM1ICAgIDEyLDkgICAgNiw0NSAgICAgICAwCisgICAgIDU0ICAgNDMsNzUgICAgMzcsNSAgIDMxLDI1ICAgICAgMjUgICAxOCw3NSAgICAxMiw1ICAgIDYsMjUgICAgICAgMAorICAgICA1NiAgIDQyLDQyICAgMzYsMzYgICAgMzAsMyAgIDI0LDI0ICAgMTgsMTggICAxMiwxMiAgICA2LDA2ICAgICAgIDAKKyAgICAgNTggICA0MSwxOCAgIDM1LDI5ICAgMjksNDEgICAyMyw1MyAgIDE3LDY1ICAgMTEsNzYgICAgNSw4OCAgICAgICAwCisgICAgIDYwICAgICAgNDAgICAzNCwyOSAgIDI4LDU3ICAgMjIsODYgICAxNywxNCAgIDExLDQzICAgIDUsNzEgICAgICAgMAorICAgICA2MiAgIDM4LDg5ICAgMzMsMzMgICAyNyw3OCAgIDIyLDIyICAgMTYsNjcgICAxMSwxMSAgICA1LDU2ICAgICAgIDAKKyAgICAgNjQgICAzNyw4NCAgIDMyLDQzICAgMjcsMDMgICAyMSw2MiAgIDE2LDIyICAgMTAsODEgICAgNSw0MSAgICAgICAwCisgICAgIDY2ICAgMzYsODQgICAzMSw1OCAgIDI2LDMyICAgMjEsMDUgICAxNSw3OSAgIDEwLDUzICAgIDUsMjYgICAgICAgMAorICAgICA2OCAgICAzNSw5ICAgMzAsNzcgICAyNSw2NCAgIDIwLDUxICAgMTUsMzggICAxMCwyNiAgICA1LDEzICAgICAgIDAKKyAgICAgNzAgICAgICAzNSAgICAgIDMwICAgICAgMjUgICAgICAyMCAgICAgIDE1ICAgICAgMTAgICAgICAgNSAgICAgICAwCisgICAgIDcyICAgMzQsMTUgICAyOSwyNyAgIDI0LDM5ICAgMTksNTEgICAxNCw2MyAgICA5LDc2ICAgIDQsODggICAgICAgMAorICAgICA3NCAgIDMzLDMzICAgMjgsNTcgICAyMyw4MSAgIDE5LDA1ICAgMTQsMjkgICAgOSw1MiAgICA0LDc2ICAgICAgIDAKKyAgICAgNzYgICAzMiw1NiAgIDI3LDkxICAgMjMsMjYgICAgMTgsNiAgIDEzLDk1ICAgICA5LDMgICAgNCw2NSAgICAgICAwCisgICAgIDc4ICAgMzEsODIgICAyNywyNyAgIDIyLDczICAgMTgsMTggICAxMyw2NCAgICA5LDA5ICAgIDQsNTUgICAgICAgMAorICAgICA4MCAgIDMxLDExICAgMjYsNjcgICAyMiwyMiAgIDE3LDc4ICAgMTMsMzMgICAgOCw4OSAgICA0LDQ0ICAgICAgIDAKKyAgICAgODIgICAzMCw0MyAgIDI2LDA5ICAgMjEsNzQgICAxNywzOSAgIDEzLDA0ICAgICA4LDcgICAgNCwzNSAgICAgICAwCisgICAgIDg0ICAgMjksNzkgICAyNSw1MyAgIDIxLDI4ICAgMTcsMDIgICAxMiw3NyAgICA4LDUxICAgIDQsMjYgICAgICAgMAorICAgICA4NiAgIDI5LDE3ICAgICAgMjUgICAyMCw4MyAgIDE2LDY3ICAgIDEyLDUgICAgOCwzMyAgICA0LDE3ICAgICAgIDAKKyAgICAgODggICAyOCw1NyAgIDI0LDQ5ICAgMjAsNDEgICAxNiwzMyAgIDEyLDI0ICAgIDgsMTYgICAgNCwwOCAgICAgICAwCisgICAgIDkwICAgICAgMjggICAgICAyNCAgICAgIDIwICAgICAgMTYgICAgICAxMiAgICAgICA4ICAgICAgIDQgICAgICAgMAorICAgICA5MiAgIDI3LDQ1ICAgMjMsNTMgICAxOSw2MSAgIDE1LDY5ICAgMTEsNzYgICAgNyw4NCAgICAzLDkyICAgICAgIDAKKyAgICAgOTQgICAyNiw5MiAgIDIzLDA4ICAgMTksMjMgICAxNSwzOCAgIDExLDU0ICAgIDcsNjkgICAgMyw4NSAgICAgICAwCisgICAgIDk2ICAgMjYsNDIgICAyMiw2NCAgIDE4LDg3ICAgMTUsMDkgICAxMSwzMiAgICA3LDU1ICAgIDMsNzcgICAgICAgMAorICAgICA5OCAgIDI1LDkzICAgMjIsMjIgICAxOCw1MiAgIDE0LDgxICAgMTEsMTEgICAgNyw0MSAgICAgMyw3ICAgICAgIDAKKyAgICAxMDAgICAyNSw0NSAgIDIxLDgyICAgMTgsMTggICAxNCw1NSAgIDEwLDkxICAgIDcsMjcgICAgMyw2NCAgICAgICAwCisgKiBAcmV0dXJuIDEsIGZhbGxzIEJlZnJpZWRlbiBlcmxhdWJ0IGlzdCwgMCBzb25zdC4KKyAqIEBwYXJhbVtpbl0gY2FzdGVyIERlcmplbmlnZSwgZGVyIGRlbiBTcHJ1Y2ggYXVzZnVlaHJ0LgorICogQGF0dGVudGlvbiBXZW5uIGFjaWZ5KCkgMSB6dXJ1ZWNrbGllZmVydCwgemFlaGx0IGRpZXMgYWxzCisgKiBlcmZvbGdyZWljaGVyIEJlZnJpZWR1bmdzdmVyc3VjaCB1bmQgaW4gZGllc2VtIExlYmV3ZXNlbiB3dXJkZQorICogU3RvcEh1bnRpbmdNb2RlKDEpIGF1ZmdlcnVmZW4uCisqLworcHVibGljIGludCBQYWNpZnkob2JqZWN0IGNhc3RlcikgeworICAKKyAgLy8gd2VubiBkYXMgVmllY2gga2VpbmUgR2VnbmVyIGhhdCwgZGFubiB3aXR6bG9zLiA7LSkgT2huZSBDYXN0ZXIgZ2VodHMgYXVjaAorICAvLyBkaXJla3QgcmF1cy4KKyAgaWYgKCFtYXBwaW5ncChlbmVtaWVzKSB8fCAhc2l6ZW9mKGVuZW1pZXMpCisgICAgICB8fCAhb2JqZWN0cChjYXN0ZXIpKSB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICAvLyBXZW5uIFBfQUNDRVBUX1BFQUNFIGdlc2V0enQgaXN0LCBhbHRlcyBWZXJoYWx0ZW4gd2llZGVyc3BpZWdlbG4KKyAgLy8gLT4gZGVyIE5QQyBpc3QgZWluZmFjaCBpbW1lciBiZWZyaWVkYmFyLiBHbGVpY2hlcyBnaWx0IGZ1ZXIgZGVuIENhc3RlcgorICAvLyBzZWxiZXIsIGRlciB3aXJkIHNpY2ggamEgbmljaHQgZ2VnZW4gZGFzIGVpZ2VuZSBCZWZyaWVkZSB3ZWhyZW4uIFVuZCBhdWNoCisgIC8vIGltIHRlYW0gd2VocnQgbWFuIHNpY2ggbmljaHQgZ2VnZW4gZGFzIEJlZnJpZWRlIGVpbmVzIFRlYW1rb2xsZWdlbgorICBpZiAoUXVlcnlQcm9wKFBfQUNDRVBUX1BFQUNFKT09MSB8fCBjYXN0ZXI9PU1FCisgICAgICB8fCBtZW1iZXIoVGVhbU1lbWJlcnMoKSwgY2FzdGVyKSA+IC0xKSB7CisgICAgU3RvcEh1bnRpbmdNb2RlKDEpOyAvLyBDYXN0ZXIvR2lsZGUgc29sbHRlIGVpZ2VuZSBNZWxkdW5nIGF1c2dlYmVuCisgICAgcmV0dXJuIDE7CisgIH0KKworICBzdHJpbmcgZ2lsZGUgPSBjYXN0ZXItPlF1ZXJ5UHJvcChQX0dVSUxEKSB8fCAiQU5ZIjsKKworICAvLyBnZ2YuIFBfUEVBQ0VfSElTVE9SWSBpbml0aWFsaXNpZXJlbgorICBtaXhlZCBwaCA9IChtaXhlZClRdWVyeVByb3AoUF9QRUFDRV9ISVNUT1JZKTsKKyAgaWYgKCFwb2ludGVycChwaCkpCisgICAgU2V0UHJvcChQX1BFQUNFX0hJU1RPUlksIHBoPSh7dGltZSgpLCAoW10pIH0pICk7CisgIAorICAvLyBnZ2YuIGRpZSBaYWVobGVyIHJlZHV6aWVyZW4uCisgIGlmICggcGhbMF0gKyBfX1JFU0VUX1RJTUVfXyAqIDc1LzEwMCA8IHRpbWUoKSkgeworICAgIF9kZWNheV9wZWFjZV9oaXN0b3J5KCZwaCk7CisgIH0KKyAgCisgIGZsb2F0IHcgPSAoY2FzdGVyLT5RdWVyeUF0dHJpYnV0ZShBX0lOVCkgKyAxMCAtIHBoWzFdW2dpbGRlXSAqIDQuMCkgLyAKKyAgICAgICAgICAgICAoUXVlcnlBdHRyaWJ1dGUoQV9JTlQpICsgMTApOworICAvLyBhdWYgWzAsMV0gYmVncmVuemVuLgorICBpZiAodzwwKSB3PTAuMDsKKyAgZWxzZSBpZiAodz4xKSB3PTEuMDsKKyAgLy8gdyAqIG4gaXN0IGVpbmUgWmFobCB6d2lzY2hlbiAwIHVuZCBuLCB3ZW5uIHcgKiBuID4gcmFuZG9tKG4pKzEsCisgIC8vIGRhcmYgYmVmcmllZGV0IHdlcmRlbi4gRGEgZGFzIFJhbmRvbSBmdWVyIGdyb3NzZSBaYWhsZW4KKyAgLy8gYmVzc2VyIHZlcnRlaWx0IGlzdCwgbmVobSBpY2ggbiA9IF9fSU5UX01BWF9fIHVuZCB2ZXJuYWNobGFlc3NpZ2UKKyAgLy8gYXVzc2VyZGVtIGRpZSArMSBiZWltIHJhbmRvbSgpLgorICBpZiAoY2VpbCh3ICogX19JTlRfTUFYX18pID4gcmFuZG9tKF9fSU5UX01BWF9fKSApIHsKKyAgICBwaFsxXVtnaWxkZV0rKzsKKyAgICBTdG9wSHVudGluZ01vZGUoMSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgLy8gZWluIFNldFByb3AoUF9QRUFDRV9ISVNUT1JZKSBrYW5uIGVudGZhbGxlbiwgZGEgZGFzIE1hcHBpbmcgZGlyZWt0CisgIC8vIGdlYWVuZGVydCB3aXJkLiBTb2xsdGUgZGllIFByb3AgYWxsZXJkaW5ncyBtYWwgbmUgUXVlcnltZXRob2RlIGhhYmVuLAorICAvLyB3ZWxjaGUgZWluZSBLb3BpZSBkYXZvbiBsaWVmZXJ0LCBtdXNzIGRhcyBoaWVyIGdlYWVuZGVydCBvZGVyIGRpZQorICAvLyBQcm9wIHBlciBRdWVyeSgpIGFiZ2VmcmFndCB3ZXJkZW4uCisgIHJldHVybiAwOworfQorCmRpZmYgLS1naXQgYS9zdGQvbGl2aW5nL2NvbW0uYyBiL3N0ZC9saXZpbmcvY29tbS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwMDFmZmQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL2NvbW0uYwpAQCAtMCwwICsxLDEzMyBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9jb21tLmMgLS0gY29tbXVuaWN0aW9uIG1vZHVsZSBmb3IgbGl2aW5ncworLy8KKy8vICRJZCQKKworI3ByYWdtYSBzdHJvbmdfdHlwZXMsc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPGxpdmluZy9jb21tLmg+CisKK3ZvaWQgY3JlYXRlX3N1cGVyKCkKK3sKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCitwcm90ZWN0ZWQgc3RyaW5nIGNvbW1fZ3Vlc3NfYWN0aW9uKCkgeworICBzdHJpbmcgY21kOworICBzdHJpbmcgYWN0aW9uID0gcXVlcnlfdmVyYigpOworICAvLyBEaWUgQWt0aW9uZW4gc2luZCBpbnRlcm4gaW4gZGVyIFJlZ2VsIG5hY2ggZGVuIGhhZXVmaWdzdGVuIEtvbW1hbmRvdmVyYmVuCisgIC8vIGRpZXNlciBBa3Rpb24gYmVuYW5udC4gQmVpIGVpbmlnZW4gQWt0aW9uZW4gc2luZCBtZWhyZXJlIEtvbW1hbmRvdmVyYmVuCisgIC8vIHVlYmxpY2gsIGRpZSBzb2xsZW4gaGllciBub2NoIGFiZ2VoYW5kZWx0IHdlcmRlbi4KKyAgc3dpdGNoKGFjdGlvbikgeworICAgIGNhc2UgIm5laG1lIjoKKyAgICAgIC8vIE1BX1RBS0UgPT0gbmltbQorICAgICAgYWN0aW9uID0gTUFfVEFLRTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAibm9yZGVuIjoKKyAgICBjYXNlICJub3Jkb3N0ZW4iOgorICAgIGNhc2UgIm9zdGVuIjoKKyAgICBjYXNlICJzdWVkb3N0ZW4iOgorICAgIGNhc2UgInN1ZWRlbiI6CisgICAgY2FzZSAic3VlZHdlc3RlbiI6CisgICAgY2FzZSAid2VzdGVuIjoKKyAgICBjYXNlICJub3Jkd2VzdGVuIjoKKyAgICBjYXNlICJvYmVuIjoKKyAgICBjYXNlICJ1bnRlbiI6CisgICAgY2FzZSAiYmV0cmV0ZSI6CisgICAgY2FzZSAidmVybGFzc2UiOgorICAgIGNhc2UgInRlbGVwb3J0IjoKKyAgICBjYXNlICJ0ZWxlcG9ydGllcmUiOgorICAgICAgYWN0aW9uID0gTUFfTU9WRTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAidW50IjoKKyAgICAgIGFjdGlvbiA9IE1BX0xPT0s7CisgICAgICBicmVhazsKKworICAgIGNhc2UgIndpcmYiOgorICAgICAgaWYgKHN0cnN0cihxdWVyeV9jb21tYW5kKCksICIgd2VnIikgPiAtMSkKKyAgICAgICAgYWN0aW9uID0gTUFfUFVUOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlICJzdGVja2UiOgorICAgICAgY21kID0gcXVlcnlfY29tbWFuZCgpOworICAgICAgaWYgKHN0cnN0cihjbWQsICIgd2VnIikgPiAtMSkKKyAgICAgICAgYWN0aW9uID0gTUFfVU5XSUVMRDsKKyAgICAgIGVsc2UgaWYgKHN0cnN0cihjbWQsIiBpbiAiKSA+IC0xKQorICAgICAgICBhY3Rpb24gPSBNQV9QVVQ7CisgICAgICBicmVhazsKKworICAgIGNhc2UgInppZWhlIjoKKyAgICAgIGNtZCA9IHF1ZXJ5X2NvbW1hbmQoKTsKKyAgICAgIGlmIChzdHJzdHIoY21kLCAiIGFuIikgPiAtMSkKKyAgICAgICAgYWN0aW9uID0gTUFfV0VBUjsKKyAgICAgIGVsc2UgaWYgKHN0cnN0cihjbWQsICIgYXVzIikgPiAtMSkKKyAgICAgICAgYWN0aW9uID0gTUFfVU5XRUFSOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlICJlc3NlIjoKKyAgICBjYXNlICJmcmlzcyI6CisgICAgICBhY3Rpb24gPSBNQV9FQVQ7CisgICAgICBicmVhazsKKworICAgIGNhc2UgInNhdWZlIjoKKyAgICAgIGFjdGlvbiA9IE1BX0RSSU5LOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlICJob2VyZSI6CisgICAgICAvL01BX0xJU1RFTiA9PSBsYXVzY2hlCisgICAgICBhY3Rpb24gPSBNQV9MSVNURU47CisgICAgICBicmVhazsKKyAgICBjYXNlICJsZXNlIjoKKyAgICAgIGFjdGlvbiA9IE1BX1JFQUQ7CisgICAgICBicmVhazsKKworICAgIGNhc2UgIjoiOgorICAgIGNhc2UgIjsiOgorICAgICAgYWN0aW9uID0gTUFfRU1PVEU7CisgICAgICBicmVhazsKKworICAgIGNhc2UgInplcmJyZWNoZSI6CisgICAgY2FzZSAiemVyc3RvZXJlIjoKKyAgICBjYXNlICJ2ZXJicmVubmUiOgorICAgIGNhc2UgImVudHNvcmdlIjoKKyAgICAgIGFjdGlvbiA9IE1BX1JFTU9WRTsKKyAgICAgIGJyZWFrOworICB9CisgIHJldHVybiBhY3Rpb247Cit9CisKK3Byb3RlY3RlZCBpbnQgY29tbV9ndWVzc19tZXNzYWdlX3R5cGUoc3RyaW5nIGFjdGlvbiwgbWl4ZWQgb3JpZ2luKSB7CisgIC8vIGV2ZXJ5dGhpbmcgbm90IG1lbnRpb25lZCBpbiB0aGUgc3dpdGNoIGJlY29tZXMgTVRfTE9PSy4KKyAgc3dpdGNoKGFjdGlvbikgeworICAgIGNhc2UgTUFfRklHSFQ6CisgICAgICAvLyBLYW1wZiBrYW5uIG1hbiBtZWlzdGVuIHNvd29obCBzZWhlbiBhbHMgYXVjaCBob2VyZW4uCisgICAgICByZXR1cm4gTVRfTE9PSyB8IE1UX0xJU1RFTjsKKyAgICBjYXNlIE1BX0xJU1RFTjoKKyAgICBjYXNlIE1BX1NBWToKKyAgICAgIHJldHVybiBNVF9MSVNURU47CisgICAgY2FzZSBNQV9GRUVMOgorICAgICAgcmV0dXJuIE1UX0ZFRUw7CisgICAgY2FzZSBNQV9TTUVMTDoKKyAgICAgIHJldHVybiBNVF9TTUVMTDsKKyAgICBjYXNlIE1BX0NIQU5ORUw6CisgICAgICByZXR1cm4gTVRfQ09NTSB8IE1UX0ZBUjsKKyAgICBjYXNlIE1BX0VNT1RFOgorICAgICAgaWYgKG9iamVjdHAob3JpZ2luKQorICAgICAgICAgICYmIGVudmlyb25tZW50KG9yaWdpbikgPT0gZW52aXJvbm1lbnQoKSkKKyAgICAgICAgcmV0dXJuIE1UX0NPTU07CisgICAgICBlbHNlCisgICAgICAgIHJldHVybiBNVF9DT01NIHwgTVRfRkFSOworICAgIGNhc2UgTUFfU0hPVVQ6CisgICAgICByZXR1cm4gTVRfTElTVEVOIHwgTVRfRkFSOworICB9CisgIC8vIGRpZSBtZWlzdGVuIEFrdGlvbmVuIHNpbmQgenVtaW5kZXN0IHNpY2h0YmFyLi4uCisgIHJldHVybiBNVF9MT09LOworfQorCmRpZmYgLS1naXQgYS9zdGQvbGl2aW5nL2Rlc2NyaXB0aW9uLmMgYi9zdGQvbGl2aW5nL2Rlc2NyaXB0aW9uLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjM1M2NhOQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvZGVzY3JpcHRpb24uYwpAQCAtMCwwICsxLDMzMiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9kZXNjcmlwdGlvbi5jIC0tIGRlc2NyaXB0aW9uIGZvciBsaXZpbmcgb2JqZWN0cworLy8KKy8vICRJZDogZGVzY3JpcHRpb24uYyA5Mzk1IDIwMTUtMTItMDggMjM6MDQ6MzhaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL2NvbnRhaW5lci9kZXNjcmlwdGlvbiI7CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxsaXZpbmcvc2tpbGxzLmg+CisjaW5jbHVkZSA8bGl2aW5nL2Nsb3RoaW5nLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8Y2xhc3MuaD4KKyNpbmNsdWRlIDxzeXNfZGVidWcuaD4KKworcHVibGljIHN0cmluZyBfcXVlcnlfaW50ZXJuYWxfZXh0cmFsb29rKCkgeworICBtaXhlZCB4bDsKKyAgaW50IHplaXQ7CisgIHN0cmluZyByZXMsIGxvb2s9IiI7CisKKyAgeGw9UXVlcnkoUF9JTlRFUk5BTF9FWFRSQV9MT09LLEZfVkFMVUUpOworICBpZiAoIW1hcHBpbmdwKHhsKSkKKyAgICByZXR1cm4oMCk7CisKKyAgZm9yZWFjaChzdHJpbmcga2V5LCBtYXBwaW5nIHhsZDogeGwpIHsKKyAgICBpZiAoaW50cCh6ZWl0PXhsZFsieGxkdXJhdGlvbiJdKSkgeworICAgICAgLy9oYXQgb2ZmZW5iYXIgbmVuIEFibGF1ZmRhdHVtCisgICAgICBpZiAoICh6ZWl0ID4gMCAmJiB6ZWl0IDwgdGltZSgpKSB8fAorICAgICAgICAgICAoemVpdCA8IDAgJiYgYWJzKHplaXQpIDwgb2JqZWN0X3RpbWUoTUUpKSApIHsKKyAgICAgICAgLy8gWmVpdCBhYmdlbGF1ZmVuIG9kZXIKKyAgICAgICAgLy8gbmVnYXRpdmUgIkFibGF1ZnplaXQiIHVuZCBkYXMgT2JqZWt0IGlzdCBuZXVlciBhbHMgZGllCisgICAgICAgIC8vIEVpbnRyYWd6ZWl0LCBhbHNvIGxvZXNjaGVuIHVuZCB3ZWl0ZXIgKGphLCBkYXMgZ2VodC4gOy0pIHVuZCB4bGQKKyAgICAgICAgLy8gaGF0IGRhcyBFaW50cmFnc21hcHBpbmcgamEgbm9jaCwgd2VpdGVyZSBCZW51dHp1bmcgYWxzbyBtb2VnbGljaC4pCisgICAgICAgIG1fZGVsZXRlKHhsLGtleSk7CisgICAgICAgIC8vIGdnZi4gTWVsZHVuZyBhdXNnZWJlbgorICAgICAgICBpZiAoaW50ZXJhY3RpdmUoTUUpKSB7CisgICAgICAgICAgaWYgKHNpemVvZih4bGRbInhsZW5kZSJdKSkgeworICAgICAgICAgICAgdGVsbF9vYmplY3QoTUUseGxkWyJ4bGVuZGUiXSk7CisgICAgICAgICAgfQorICAgICAgICAgIC8va2VpbiBlaW5mYWNoZXIgU3RyaW5nLCBhYmVyIE9iamVrdCtGdW5rdGlvbiBnZWdlYmVuPworICAgICAgICAgIGVsc2UgaWYgKHNpemVvZih4bGRbInhsZW5kZWZ1biJdKSAmJiBzaXplb2YoeGxkWyJ4bG9iamVjdG5hbWUiXSkgJiYKKyAgICAgICAgICAgICghY2F0Y2gocmVzPWNhbGxfb3RoZXIoeGxkWyJ4bG9iamVjdG5hbWUiXSx4bGRbInhsZW5kZWZ1biJdLE1FKQorICAgICAgICAgICAgICAgICAgICA7cHVibGlzaCkpKSB7CisgICAgICAgICAgICAgIGlmIChzdHJpbmdwKHJlcykgJiYgc2l6ZW9mKHJlcykpCisgICAgICAgICAgICAgICAgdGVsbF9vYmplY3QoTUUscmVzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBjb250aW51ZTsKKyAgICAgIH0KKyAgICB9CisgICAgLy8gRGVyIEVpbnRyYWcgaXN0IG9mZmVuYmFyIG5vY2ggZ3VlbHRpZywgTWVsZHVuZyBhbmhhZW5nZW4sIGJ6dy4gdmlhCisgICAgLy8gRnVua3Rpb25zYXVmcnVmIGJlc2NoYWZmZW4uCisgICAgaWYgKHNpemVvZih4bGRbInhsbG9vayJdKSkKKyAgICAgIGxvb2srPXhsZFsieGxsb29rIl07CisgICAgZWxzZSBpZiAoc2l6ZW9mKHhsZFsieGxmdW4iXSkgJiYgc2l6ZW9mKHhsZFsieGxvYmplY3RuYW1lIl0pKSB7CisgICAgICBjbG9zdXJlIGNsOworICAgICAgaWYgKGNhdGNoKGNsPXN5bWJvbF9mdW5jdGlvbih4bGRbInhsZnVuIl0seGxkWyJ4bG9iamVjdG5hbWUiXSk7cHVibGlzaCkKKyAgICAgICAgICB8fCAhY2wpIHsKKyAgICAgICAgICAvLyB3ZW5uIEZlaGxlciBiZWltIExhZGVuL0Nsb3N1cmUgZXJzdGVsbGVuLCBkYW5uIEVpbnRyYWcgbG9lc2NoZW4KKyAgICAgICAgICAvLyAtPiBBbm5haG1lLCBkYXNzIGRpZXNlciBGZWhsZXIgcGVybWFuZW50IHNlaW4gd2lyZCwgei5CLiBFaW50cmFnCisgICAgICAgICAgLy8gdm9uIENsb25lbgorICAgICAgICAgIG1fZGVsZXRlKHhsLGtleSk7CisgICAgICAgICAgY29udGludWU7CisgICAgICB9CisgICAgICBlbHNlIGlmICghY2F0Y2gocmVzPWZ1bmNhbGwoY2wsIE1FKTsgcHVibGlzaCkpIHsKKyAgICAgICAgaWYgKCFzdHJpbmdwKHJlcykgfHwgIXNpemVvZihyZXMpKSB7CisgICAgICAgICAgLy8ga2VpbmVuIFN0cmluZyBvZGVyIGxlZXJlbiBTdHJpbmcgZ2VrcmllZ3QgLT4gdWViZXJzcHJpbmdlbi4KKyAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgbG9vays9cmVzOworICAgICAgfQorICAgIH0KKyAgfQorICAvLyBmZXJ0aWcuIFdlbm4gbG9vayBuaWNodCBsZWVyIGlzdCwgenVydWVja2dlYmVuLCBzb25zdCAwLgorICBpZiAoc2l6ZW9mKGxvb2spKQorICAgIHJldHVybihsb29rKTsKKyAgZWxzZQorICAgIHJldHVybigwKTsKK30KKworcHVibGljIHZhcmFyZ3MgaW50IEFkZEV4dHJhTG9vayhzdHJpbmcgbG9vaywgaW50IGR1cmF0aW9uLCBzdHJpbmcga2V5LCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGxvb2tlbmRlLCBvYmplY3Qgb2IpIHsKKyAgbWFwcGluZyB4bDsKKyAgc3RyaW5nIG9uYW1lOworICBpZiAoIXN0cmluZ3Aoa2V5KSB8fCAhc2l6ZW9mKGtleSkpIHsKKyAgICAvLyBBdXRvbWF0aXNjaCBlcnpldWdlbiwgd2VubiBtb2VnbGljaAorICAgIGlmICghb2JqZWN0cChwcmV2aW91c19vYmplY3QoKSkgfHwgCisgICAgICAgICFzdHJpbmdwKGtleT1vYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSkpIHx8ICFzaXplb2Yoa2V5KSkKKyAgICAgIHJldHVybigtMSk7CisgIH0KKworICBpZiAoIXN0cmluZ3AobG9vaykgfHwgIXNpemVvZihsb29rKSkKKyAgICByZXR1cm4oLTIpOworICBpZiAoIWludHAoZHVyYXRpb24pKQorICAgIHJldHVybigtMyk7CisKKyAgeGw9UXVlcnkoUF9JTlRFUk5BTF9FWFRSQV9MT09LLEZfVkFMVUUpOyAvLyBkcmFuIGRlbmtlbjogbGllZmVydCByZWZlcmVueiB6dXJ1ZWNrCisgIGlmICghbWFwcGluZ3AoeGwpKSB7CisgICAgU2V0KFBfSU5URVJOQUxfRVhUUkFfTE9PSywgeGw9KFtdKSApOworICB9CisKKyAgLy8ga2VpbiBBdXRvbWF0aXNjaGVzIFVlYmVyc2NocmVpYmVuLgorICBpZiAobWVtYmVyKHhsLGtleSkpCisgICAgcmV0dXJuKC00KTsKKworICAvLyBuZWcuIFdlcnRlOiAiYmlzIEVuZGUvcmVib290IiwgYWJzKGR1cmF0aW9uKSA9PSBFaW50cmFnemVpdAorICAvLyAwOiAiZnVlciBld2lnIiwgPjA6IFplaXRkYXVlciBpbiBTZWt1bmRlbgorICBpZiAoZHVyYXRpb24gPiAwKQorICAgIGR1cmF0aW9uKz10aW1lKCk7ICAvLyBob2ZmZW50bGljaCBnaWJ0IGVzIHJlaWNodHplaXRpZyA2NGJpdC1JbnRzCisgIGVsc2UgaWYgKGR1cmF0aW9uIDwgMCkKKyAgICBkdXJhdGlvbj1uZWdhdGUodGltZSgpKTsKKyAgLy8gMCBibGVpYnQsIHdpZSBlcyBpc3QuCisKKyAgaWYgKG9iamVjdHAob2IpKSB7CisgICAgLy8gRnVua3Rpb25zbmFtZSB1bmQgT2JqZWt0bmFtZSAoYWxzIE5hbWUsIGRhbWl0IGVzIGF1Y2ggbm9jaCBnZWh0LCB3ZW5uCisgICAgLy8gZGFzIE9iamVrdCBlbnRsYWRlbiB3dXJkZSwgQ3Jhc2gvcmVib290IHdhciBldGMuKSBzcGVpY2hlcm4KKyAgICAvLyBDbG9uZSB3ZXJkZW4gYXVjaCBnZXNwZWljaGVydCwgYWJlciBlcyB3aXJkIGRpcmVrdCBlaW4gaGFydGVyIEZlaGxlcgorICAgIC8vIGF1c2dlbG9lc3QsIHdlbm4gZWluIHBlcm1hbmVudGVyIFhsb29rIGZ1ZXIgZWluZW4gQ2xvbmUgcmVnaXN0cmllcnQKKyAgICAvLyB3ZXJkZW4gc29sbDogZGFzIGthbm4gbmljaHQgZ2VoZW4uCisgICAgaWYgKCFkdXJhdGlvbiAmJiBjbG9uZXAob2IpKQorICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAiQWRkRXh0cmFMb29rKCk6IEZlaGxlcmhhZnRlcyBBcmd1bWVudCA8ZHVyYXRpb24+OiAlZCwgIgorICAgICAgICAgICAicGVybWFuZW50ZSBFeHRyYWxvb2tzIGR1cmNoIENsb25lICglcykgbmljaHQgcmVnaXN0cmllcmJhci5cbiIsCisgICAgICAgICAgIGR1cmF0aW9uLCBvYmplY3RfbmFtZShvYikpKTsKKworICAgIHhsW2tleV09KFsieGxvYmplY3RuYW1lIjpvYmplY3RfbmFtZShvYiksCisgICAgICAgICAgICAgICJ4bGZ1biI6IGxvb2ssCisgICAgICAgICAgICAgXSk7CisgICAgLy8gZ2dmLiBOYW1lIGRlciBGdW5rdGlvbiBzcGVpY2hlcm4sIGRpZSBiZWkgQWJsYXVmIGF1ZmdlcnVmZW4gd2lyZC4KKyAgICBpZiAoc3RyaW5ncChsb29rZW5kZSkgJiYgc2l6ZW9mKGxvb2tlbmRlKSkKKyAgICAgICAgeGxba2V5XVsieGxlbmRlZnVuIl09bG9va2VuZGU7CisgIH0KKyAgZWxzZSB7CisgICAgLy8gRWluZmFjaGVyIEVpbnRyYWcsIG51ciBkZW4gYmVhcmJlaXRldGVuIFN0cmluZyBtZXJrZW4uIDstKQorICAgIHhsW2tleV09KFsieGxsb29rIjogYnJlYWtfc3RyaW5nKHJlcGxhY2VfcGVyc29uYWwobG9vaywoe01FfSksMSksNzgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiIsQlNfTEVBVkVfTVlfTEZTKSwKKyAgICAgICAgICAgICBdKTsKKyAgICAvLyBnZ2YuIE1lbGR1bmcgc3BlaWNoZXJuLCBkaWUgYmVpIEFibGF1ZiBhdXNnZWdlYmVuIHdlcmRlbiBzb2xsLgorICAgIGlmIChzdHJpbmdwKGxvb2tlbmRlKSAmJiBzaXplb2YobG9va2VuZGUpKSB7CisgICAgICB4bFtrZXldWyJ4bGVuZGUiXT1icmVha19zdHJpbmcocmVwbGFjZV9wZXJzb25hbChsb29rZW5kZSwoe01FfSksMSksNzgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiIsQlNfTEVBVkVfTVlfTEZTKTsKKyAgICB9CisgIH0KKyAgLy8gRW5kZXplaXQgdmVybWVya2VuLgorICBpZiAoZHVyYXRpb24gIT0gMCkKKyAgICB4bFtrZXldWyJ4bGR1cmF0aW9uIl09ZHVyYXRpb247CisKKyAgLy8gS2VpbiBTZXQgbm9ldGlnLCB3ZWlsIFF1ZXJ5IGRhcyBNYXBwaW5nIGphIGFscyBSZWZlcmVueiBsaWVmZXJ0ZS4KKyAgcmV0dXJuKDEpOworfQorCitwdWJsaWMgaW50IFJlbW92ZUV4dHJhTG9vayhzdHJpbmcga2V5KSB7CisgIG1hcHBpbmcgeGw7CisgIGlmICghc3RyaW5ncChrZXkpIHx8ICFzaXplb2Yoa2V5KSkgeworICAgIC8vIEF1dG9tYXRpc2NoIGVyemV1Z2VuLCB3ZW5uIG1vZWdsaWNoCisgICAgaWYgKCFvYmplY3RwKHByZXZpb3VzX29iamVjdCgpKSB8fAorICAgICAgICAhc3RyaW5ncChrZXk9b2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpKSB8fCAhc2l6ZW9mKGtleSkpCisgICAgICByZXR1cm4oLTEpOworICB9CisgIHhsPVF1ZXJ5KFBfSU5URVJOQUxfRVhUUkFfTE9PSyxGX1ZBTFVFKTsgLy8gZHJhbiBkZW5rZW46IGxpZWZlcnQgcmVmZXJlbnogenVydWVjaworICBpZiAoIW1hcHBpbmdwKHhsKSkKKyAgICByZXR1cm4gKC0yKTsKKyAgaWYgKCFtZW1iZXIoeGwsa2V5KSkKKyAgICByZXR1cm4oLTIpOworCisgIG1fZGVsZXRlKHhsLGtleSk7CisgIC8vIEtlaW4gU2V0IG5vZXRpZywgd2VpbCBRdWVyeSBkYXMgTWFwcGluZyBqYSBhbHMgUmVmZXJlbnogbGllZmVydGUuCisgIHJldHVybigxKTsKK30KKwordm9pZCBjcmVhdGUoKQoreyAKKyAgOjpjcmVhdGUoKTsKKyAgU2V0KFBfR0VOREVSLCBTQVZFLCBGX01PREUpOworICAvLyBFeHRyYWxvb2stUHJvcGVydHkgc3BlaWNoZXJuIHVuZCB2b3IgbWFudWVsbGVyIEFlbmRlcnVuZyBzY2h1ZXR6ZW4KKyAgLy8gRU1zIGR1ZXJmZW4sIGRpZSB3aXNzZW4gaG9mZmVudGxpY2gsIHdhcyBzaWUgdHVuLgorICBTZXQoUF9JTlRFUk5BTF9FWFRSQV9MT09LLCBTQVZFfFBST1RFQ1RFRCwgRl9NT0RFX0FTKTsKKyAgU2V0UHJvcChQX0NMT1RISU5HLCh7fSkpOworICBBZGRJZCgiTGl2aW5nIik7Cit9CisKK3N0cmluZyBjb25kaXRpb24oKQoreworICBpbnQgaHBudCwgbWF4X2hwbnQsIHBlcmM7CisKKyAgaHBudCAgICAgICAgPSBRdWVyeVByb3AoIFBfSFAgKTsKKyAgbWF4X2hwbnQgICAgPSBRdWVyeVByb3AoIFBfTUFYX0hQICk7CisKKyAgaWYobWF4X2hwbnQ+MCAmJiBocG50PjApCisgICAgcGVyYz0xMDAqaHBudC9tYXhfaHBudDsKKyAKKyAgc3dpdGNoKHBlcmMpIHsKKyAgICBjYXNlIDAuLjk6CisgICAgICAgIHJldHVybiBjYXBpdGFsaXplKFF1ZXJ5UHJvbm91bihXRVIpKSsiIHN0ZWh0IGF1ZiBkZXIgU2Nod2VsbGUgZGVzIFRvZGVzLlxuIjsKKyAgICBjYXNlIDEwLi4xOToKKyAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgYnJhdWNodCBkcmluZ2VuZCBlaW5lbiBBcnp0LlxuIjsKKyAgICBjYXNlIDIwLi4yOToKKyAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgaXN0IGluIGtlaW5lciBndXRlbiBWZXJmYXNzdW5nLlxuIjsKKyAgICBjYXNlIDMwLi4zOToKKyAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgd2Fua3QgYmVyZWl0cyBiZWRlbmtsaWNoLlxuIjsKKyAgICBjYXNlIDQwLi40OToKKyAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgbWFjaHQgZWluZW4gbWl0Z2Vub21tZW5lbiBFaW5kcnVjay5cbiI7CisgICAgY2FzZSA1MC4uNTk6CisgICAgICAgIHJldHVybiBjYXBpdGFsaXplKFF1ZXJ5UHJvbm91bihXRVIpKSsiIHNpZWh0IG5pY2h0IG1laHIgdGF1ZnJpc2NoIGF1cy5cbiI7CisgICAgY2FzZSA2MC4uNjk6CisgICAgICAgIHJldHVybiBjYXBpdGFsaXplKFF1ZXJ5UHJvbm91bihXRVIpKSsiIGlzdCBsZWljaHQgYW5nZXNjaGxhZ2VuLlxuIjsKKyAgICBjYXNlIDcwLi43OToKKyAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgZnVlaGx0ZSBzaWNoIGhldXRlIHNjaG9uIGJlc3Nlci5cbiI7CisgICAgY2FzZSA4MC4uODk6CisgICAgICAgIHJldHVybiBjYXBpdGFsaXplKFF1ZXJ5UHJvbm91bihXRVIpKSsiIGlzdCBzY2hvbiBldHdhcyBnZXNjaHdhZWNodC5cbiI7CisgIH0KKyAgLy9mYWxsLXRocm91Z2gKKyAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnlQcm9ub3VuKFdFUikpKyIgaXN0IGFic29sdXQgZml0LlxuIjsKK30KKwordmFyYXJncyBzdHJpbmcgbG9uZygpIHsKKyAgc3RyaW5nIHN0ciwgY2FwX3Byb25vdW47CisgIHN0cmluZyBkZXNjciwgaW52bCx0bXAsZXhsOworICBpbnQgaHBudCwgbWF4X2hwbnQ7CisgIG1peGVkIGZpbHRlcl9sZGZpZWQ7CisgIG9iamVjdCBvYjsKKworICBzdHIgPSBwcm9jZXNzX3N0cmluZyggUXVlcnlQcm9wKFBfTE9ORykgKTsKKyAgaWYoIXN0cmluZ3Aoc3RyKSkgc3RyID0gIiI7CisKKyAgc3RyICs9IGNvbmRpdGlvbigpOworCisgIC8vIEV4dHJhbG9vaworICBpZihzdHJpbmdwKHRtcCA9IFF1ZXJ5UHJvcChQX0VYVFJBX0xPT0spKSkKKyAgICBzdHIgKz0gdG1wOworICBpZiAoc3RyaW5ncCh0bXAgPSBRdWVyeVByb3AoUF9JTlRFUk5BTF9FWFRSQV9MT09LKSkpCisgICAgc3RyICs9IHRtcDsKKyAgZm9yKG9iID0gZmlyc3RfaW52ZW50b3J5KE1FKTsgb2I7IG9iID0gbmV4dF9pbnZlbnRvcnkob2IpKQorICAgIGlmKGV4bCA9IG9iLT5RdWVyeVByb3AoUF9FWFRSQV9MT09LKSkgCisgICAgICBzdHIgKz0gZXhsOworICAgIGVsc2UgaWYoZXhsID0gb2ItPmV4dHJhX2xvb2soKSkgCisgICAgICBzdHIgKz0gZXhsOyAvLyBUTyBCRSBSRU1PVkVECisKKyAgCisgIGlmKGZpbHRlcl9sZGZpZWQgPSBRdWVyeVByb3AoUF9UUkFOU1BBUkVOVCkpCisgIHsKKyAgICBpbnZsID0gbWFrZV9pbnZsaXN0KFBMLCBhbGxfaW52ZW50b3J5KE1FKSk7CisgICAgaWYoaW52bCAhPSAiIikKKyAgICAgIHN0ciArPSBjYXBpdGFsaXplKFF1ZXJ5UHJvbm91bihXRVIpKSsiIHRyYWVndCBiZWkgc2ljaDpcbiIgKyBpbnZsOworICB9CisgIHJldHVybiBzdHI7Cit9CisKK3ZhcmFyZ3Mgc3RyaW5nIG5hbWUoaW50IGNhc3VzLCBpbnQgZGVtb25zdCkKK3sgCisgIGlmKCBRdWVyeVByb3AoIFBfSU5WSVMgKSApCisgIHsKKyAgICBpZiggY2FzdXMgPT0gUkFXICkgcmV0dXJuICJKZW1hbmQiOworICAgIHJldHVybiAoeyJKZW1hbmQiLCJKZW1hbmRzIiwiSmVtYW5kZW0iLCJKZW1hbmRlbiJ9KVtjYXN1c107CisgIH0KKyAgaWYgKFF1ZXJ5UHJvcChQX0ZST0cpICYmIGNhc3VzICE9IFJBVyApCisgIHsKKyAgICBzdHJpbmcgcz1RdWVyeUFydGljbGUoY2FzdXMsIDAsIDEpKyJGcm9zY2giOworICAgIGlmIChjYXN1cz09V0VTU0VOKSBzICs9ICJlcyI7CisgICAgcmV0dXJuIHM7CisgIH0KKyAgcmV0dXJuIDo6bmFtZSggY2FzdXMsIGRlbW9uc3QgKTsKK30KKworc3RhdGljIGludCBfcXVlcnlfZ2VuZGVyKCkKK3sKKyAgaWYgKFF1ZXJ5UHJvcChQX0ZST0cpKSByZXR1cm4gMTsKKyAgcmV0dXJuIFF1ZXJ5KFBfR0VOREVSKTsKK30KKworLy8gTlBDIHNvbGxlbiBhdXMgS29tcGF0aWJpbGl0YWV0c2dydWVuZGVuIGF1Y2ggZWluZSAiZWNodGUiIFJhc3NlIGhhYmVuLgorLy8gRGVmYXVsdCBpc3QgaGllciBkaWUgUmFzc2UsIG1hbiBrYW5uIGFiZXIgaGllcm1pdCBhdWNoIGVpbmVuIE5QQyBmYWtlbiwKKy8vIGRlciBzaWNoIHRhcm50LCBpbmRlbSBtYW4gUF9SRUFMX1JBQ0UgcGVyIEhhbmQgc2V0enQuCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9yZWFsX3JhY2UoKQoreworICByZXR1cm4gUXVlcnkoUF9SRUFMX1JBQ0UsRl9WQUxVRSl8fFF1ZXJ5UHJvcChQX1JBQ0UpOworfQorCitzdGF0aWMgbWl4ZWQgX3NldF9uYW1lKG1peGVkIG5tICkKK3sKKyAgc3RyaW5nIGx2bmFtOworICBsdm5hbSA9IG5tOworICBpZihwb2ludGVycChubSkpIGx2bmFtID0gbm1bMF07CisgIHNldF9saXZpbmdfbmFtZShsb3dlcl9jYXNlKGx2bmFtKSk7CisgIHJldHVybiBTZXQoUF9OQU1FLCBubSk7Cit9CisKK2ludCBfcXVlcnlfY29udGFpbmVyKCkKK3sKKyAgcmV0dXJuIDA7Cit9CisKK2ludCBpc19jbGFzc19tZW1iZXIobWl4ZWQgc3RyKSB7CisgIC8vIEtlaW5lIEtsYXNzZSwga2VpbmUgTWl0Z2xpZWRzY2hhZnQgLi4uCisgIGlmICghc3RyIHx8ICghc3RyaW5ncChzdHIpICYmICFwb2ludGVycChzdHIpKSB8fCBzdHI9PSIiKSAKKyAgICAgIHJldHVybiAwOworCisgIGlmICg6OmlzX2NsYXNzX21lbWJlcihzdHIpKQorICAgIHJldHVybiAxOworCisgIGlmIChzdHJpbmdwKHN0cikpCisgICAgc3RyID0gKHtzdHJ9KTsKKworICAvLyBSYXNzZW4gd2VyZGVuIGFscyBpbXBsaXppdGUgS2xhc3NlbiBhdWZnZWZhc3N0LgorICAvLyBUT0RPOiBQcnVlZmVuLCBvYiBkYXMgdW5iZWRpbmd0IGhhcnQta29kaWVydCBzZWluIG11c3MuCisgIHN0cmluZyByYWNlID0gUXVlcnlQcm9wKFBfUkFDRSk7CisgIGlmICggc3RyaW5ncChyYWNlKSAmJiBtZW1iZXIoIHN0ciwgbG93ZXJfY2FzZShyYWNlKSApID4gLTEgKQorICAgIHJldHVybiAxOworICBlbHNlCisgICAgcmV0dXJuIDA7Cit9CisKK21hcHBpbmcgX3F1ZXJ5X21hdGVyaWFsKCkgeworICBtaXhlZCByZXM7CisKKyAgaWYgKG1hcHBpbmdwKHJlcz1RdWVyeShQX01BVEVSSUFMKSkpCisgICAgcmV0dXJuIHJlczsKKyAgcmV0dXJuIChbTUFUX01JU0NfTElWSU5HOjEwMF0pOworfQorCmRpZmYgLS1naXQgYS9zdGQvbGl2aW5nL2hlbHBlcnMuYyBiL3N0ZC9saXZpbmcvaGVscGVycy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNkMjkyYzAKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL2hlbHBlcnMuYwpAQCAtMCwwICsxLDE0OSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9oZWxwZXJzLmMgLS0gKFF1ZXJ5KU1ldGhvZGVuIGZ1ZXIgSGlsZnNvYmpla3RlLCB6LkIuIHp1bSBUYXVjaGVuCisvLworLy8gJElkOiBtb25leWhhbmRsZXIuaCx2IDMuMSAxOTk3LzAyLzEyIDEzOjI5OjA5IFdhcmdvbiBFeHAgJQorCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDxsaXZpbmcvaGVscGVycy5oPgorI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKK3B1YmxpYyBpbnQgUmVnaXN0ZXJIZWxwZXJPYmplY3Qob2JqZWN0IGhlbHBlciwgaW50IHR5cGUsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmd8Y2xvc3VyZSBjYWxsYmFjaykgCit7CisgIC8vIGNiOiBjbG9zdXJlIGF1ZiBkaWUgQ2FsbGJhY2stRnVua3Rpb24gaW4gcHJldmlvdXNfb2JqZWN0KCkKKyAgY2xvc3VyZSBjYjsKKyAgLy8gaGVscGVyczogTWFwcGluZyBhbGxlciBlaW5nZXRyYWdlbmVuIEhlbGZlci1PYmpla3RlCisgIG1hcHBpbmcgaGVscGVyczsKKworICAvLyBLZWluIHBvc2l0aXZlciBJbnRlZ2Vyd2VydCBhbHMgSGVsZmVydHlwIHVlYmVyZ2ViZW4/CisgIGlmICggIWludHAodHlwZSkgfHwgdHlwZSA8IDEgKQorICAgICByYWlzZV9lcnJvcihzcHJpbnRmKCAiV3JvbmcgYXJndW1lbnQgMSB0byBSZWdpc3RlckhlbHBlck9iamVjdCgpLiAiCisgICAgICAgICJFeHBlY3RlZCBwb3NpdGl2ZSA8aW50PiwgZ290ICVPLlxuIiwgdHlwZSkpOworICAvLyBLZWluIE9iamVrdCB2b3JoYW5kZW4sIGFuIGRlbSBkaWUgQ2FsbGJhY2stRnVua3Rpb24gZ2VydWZlbiB3ZXJkZW4gc29sbD8KKyAgaWYgKCAhb2JqZWN0cChoZWxwZXIpICkKKyAgICByZXR1cm4gSEVMUEVSX05PX0NBTExCQUNLX09CSkVDVDsKKworICAvLyBGdW5rdGlvbnNuYW1lIHp1bSBad2VjayBkZXMgQ2FsbGJhY2tzIHVlYmVyZ2ViZW4/CisgIGlmICggc3RyaW5ncChjYWxsYmFjaykgKSB7CisgICAgLy8gRGFubiBDbG9zdXJlIGRhdm9uIGVyc3RlbGxlbi4KKyAgICBjYiA9IHN5bWJvbF9mdW5jdGlvbihjYWxsYmFjaywgaGVscGVyKTsKKyAgICAvLyBXZW5uIGRhcyBuaWNodCBrbGFwcHQgKHpCIHdlaWwgZGllIEZ1bmt0aW9uIHByaXZhdGUgaXN0KSwgZGFubgorICAgIC8vIEZlaGxlciB3ZXJmZW4gdW5kIGFiYnJlY2hlbi4KKyAgICBpZiAoICFjbG9zdXJlcChjYikgKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiRXJyb3IgaW4gUmVnaXN0ZXJIZWxwZXJPYmplY3QoKTogVW5hYmxlIHRvIGNhbGwgIgorICAgICAgICAiZnVuY3Rpb24gJXMgaW4gb2JqZWN0ICVPLlxuIiwgY2FsbGJhY2ssIGhlbHBlcikpOworICB9CisgIC8vIFdlbm4gc2Nob24gZWluZSBDbG9zdXJlIHVlYmVyZ2ViZW4gd3VyZGUsIGRhbm4gZGllc2UgZGlyZWt0IHNwZWljaGVybi4KKyAgZWxzZSBpZiAoIGNsb3N1cmVwKGNhbGxiYWNrKSApIHsKKyAgICBjYiA9IGNhbGxiYWNrOworICB9CisgIC8vIFdlZGVyIEZ1bmt0aW9uc25hbWUsIG5vY2ggQ2xvc3VyZSwgZGFubiBGZWhsZXIgd2VyZmVuIHVuZCBhYmJyZWNoZW4uCisgIGVsc2UKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJXcm9uZyBhcmd1bWVudCAyIHRvIFJlZ2lzdGVySGVscGVyT2JqZWN0KCkuICIKKyAgICAgICJFeHBlY3RlZCA8c3RyaW5nL2Nsb3N1cmU+LCBnb3QgJU8uXG4iLGNhbGxiYWNrKSk7CisKKyAgLy8gUHJvcGVydHkgYXVzbGVzZW4gdW5kIHp3aXNjaGVuc3BlaWNoZXJuCisgIGhlbHBlcnMgPSBRdWVyeVByb3AoUF9IRUxQRVJfT0JKRUNUUyk7CisgIC8vIFdlbm4gZGllIFByb3AgbGVlciBpc3QsIGhpZXIgaW5pdGlhbGlzaWVyZW4KKyAgaWYgKCAhaGVscGVycyApIHsKKyAgICBoZWxwZXJzID0gKFt0eXBlOih7fSldKTsKKyAgfQorICAvLyBXZW5uIGRlciBUeXAgbm9jaCBuaWNodCBleGlzdGllcnQsIGhpZXIgbmFjaHRyYWdlbi4KKyAgZWxzZSBpZiAoICFwb2ludGVycChoZWxwZXJzW3R5cGVdKSApIHsKKyAgICBoZWxwZXJzW3R5cGVdID0gKHt9KTsKKyAgfQorCisgIC8vIENsb3N1cmUgZWludHJhZ2VuLCB3ZW5uIG5vY2ggbmljaHQgdm9yaGFuZGVuCisgIGlmICggbWVtYmVyKGhlbHBlcnNbdHlwZV0sIGNiKT09LTEgKSB7CisgICAgaGVscGVyc1t0eXBlXSA9IGhlbHBlcnNbdHlwZV0rKHtjYn0pOworICAgIFNldFByb3AoUF9IRUxQRVJfT0JKRUNUUywgaGVscGVycyk7CisgICAgcmV0dXJuIEhFTFBFUl9TVUNDRVNTOworICB9CisgIGVsc2UKKyAgICByZXR1cm4gSEVMUEVSX0FMUkVBRFlfTElTVEVEOworfQorCitwdWJsaWMgaW50IFVucmVnaXN0ZXJIZWxwZXJPYmplY3Qob2JqZWN0IGhlbHBlciwgaW50IHR5cGUpIHsKKyAgaWYgKCAhaW50cCh0eXBlKSB8fCB0eXBlIDwgMSApCisgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoICJXcm9uZyBhcmd1bWVudCAyIHRvIFVucmVnaXN0ZXJIZWxwZXJPYmplY3QoKS4gIgorICAgICAgICAiRXhwZWN0ZWQgcG9zaXRpdmUgPGludD4sIGdvdCAlTy5cbiIsIHR5cGUpKTsKKyAgaWYgKCAhb2JqZWN0cChoZWxwZXIpICkKKyAgICByZXR1cm4gSEVMUEVSX05PX0NBTExCQUNLX09CSkVDVDsKKworICBtYXBwaW5nIGhlbHBlcnMgPSBRdWVyeShQX0hFTFBFUl9PQkpFQ1RTLCBGX1ZBTFVFKTsKKworICBpZiAoIG1hcHBpbmdwKGhlbHBlcnMpICkgeworICAgIGZvcmVhY2goY2xvc3VyZSBjbDogaGVscGVyc1t0eXBlXSkgeworICAgICAgaWYgKCBnZXRfdHlwZV9pbmZvKGNsLDIpID09IGhlbHBlciApIHsKKyAgICAgICAgaGVscGVyc1t0eXBlXSA9IGhlbHBlcnNbdHlwZV0tKHtjbH0pOworICAgICAgICByZXR1cm4gSEVMUEVSX1NVQ0NFU1M7CisgICAgICB9CisgICAgfQorICB9CisgIHJldHVybiBIRUxQRVJfTk9USElOR19UT19VTlJFR0lTVEVSOworfQorCisvLyBRdWVyeW1ldGhvZGUgZnVlciBQX0FRVUFUSUNfSEVMUEVSUworcHVibGljIG1hcHBpbmcgX3F1ZXJ5X2xpYl9wX2FxdWF0aWNfaGVscGVycygpIHsKKyAgbWFwcGluZyByZXQgPSAoW10pOworICAvLyBlaW5nZXRyYWdlbmUgQ2FsbGJhY2stQ2xvc3VyZXMgYXVzbGVzZW4KKyAgY2xvc3VyZSAqaGVscGVycyA9IAorICAgICggUXVlcnkoUF9IRUxQRVJfT0JKRUNUUywgRl9WQUxVRSkgfHwgKFtdKSApW0hFTFBFUl9UWVBFX0FRVUFUSUNdOworICAvLyBFcyBzaW5kIGdhciBrZWluZSBXZXJ0ZSBlaW5nZXRyYWdlbj8gRGFubiBnbGVpY2ggcmF1c3NwcmluZ2VuLgorICBpZiAoICFwb2ludGVycChoZWxwZXJzKSApCisgICAgcmV0dXJuIHJldDsKKworICAvLyBOdWxsZWxlbWVudCBzdWJzdHJhaGllcmVuCisgIGhlbHBlcnMgLT0gKHswfSk7CisKKyAgaWYgKCBzaXplb2YoaGVscGVycykgKSB7CisgICAgLy8gTWFwcGluZyBlcnN0ZWxsZW46IEtleXMgc2luZCBkaWUgT2JqZWt0ZSwgZGVyZW4gQ2xvc3VyZXMgZWluZ2V0cmFnZW4KKyAgICAvLyBzaW5kLiBWYWx1ZXMgc2luZCBkaWUgUnVlY2tnYWJld2VydGUgZGVyIENsb3N1cmVzLAorICAgIC8vIGRpZSBkYWJlaSBkYXMgU3BpZWxlcm9iamVrdCB1bmQgZGFzIGFiZnJhZ2VuZGUgT2JqZWt0IHVlYmVyZ2ViZW4KKyAgICAvLyBiZWtvbW1lbi4KKyAgICBvYmplY3QgKmtleXMgPSBtYXAoaGVscGVycywgIydnZXRfdHlwZV9pbmZvLCAyKTsKKyAgICBpbnQgKnZhbHMgPSBtYXAoaGVscGVycywgIydmdW5jYWxsLCB0aGlzX29iamVjdCgpLCBwcmV2aW91c19vYmplY3QoMSkpOworICAgIHJldCA9IG1rbWFwcGluZyhrZXlzLHZhbHMpOworICB9CisgIHJldHVybiByZXQ7Cit9CisKKy8vIFF1ZXJ5bWV0aG9kZSBmdWVyIFBfQUVSSUFMX0hFTFBFUlMKK3B1YmxpYyBtYXBwaW5nIF9xdWVyeV9saWJfcF9hZXJpYWxfaGVscGVycygpIHsKKyAgbWFwcGluZyByZXQgPSAoW10pOworICAvLyBlaW5nZXRyYWdlbmUgQ2FsbGJhY2stQ2xvc3VyZXMgYXVzbGVzZW4KKyAgY2xvc3VyZSAqaGVscGVycyA9IAorICAgICggUXVlcnkoUF9IRUxQRVJfT0JKRUNUUywgRl9WQUxVRSkgfHwgKFtdKSApW0hFTFBFUl9UWVBFX0FFUklBTF07CisKKyAgLy8gRXMgc2luZCBnYXIga2VpbmUgV2VydGUgZWluZ2V0cmFnZW4/IERhbm4gZ2xlaWNoIHJhdXNzcHJpbmdlbi4KKyAgaWYgKCAhcG9pbnRlcnAoaGVscGVycykgKQorICAgIHJldHVybiByZXQ7CisgIAorICAvLyBOdWxsZWxlbWVudCBzdWJzdHJhaGllcmVuCisgIGhlbHBlcnMgLT0gKHswfSk7CisKKyAgaWYgKCBzaXplb2YoaGVscGVycykgKSB7CisgICAgLy8gTWFwcGluZyBlcnN0ZWxsZW46IEtleXMgc2luZCBkaWUgT2JqZWt0ZSwgZGVyZW4gQ2xvc3VyZXMgZWluZ2V0cmFnZW4KKyAgICAvLyBzaW5kLiBWYWx1ZXMgc2luZCBkaWUgUnVlY2tnYWJld2VydGUgZGVyIENsb3N1cmVzLAorICAgIC8vIGRpZSBkYWJlaSBkYXMgU3BpZWxlcm9iamVrdCB1bmQgZGFzIGFiZnJhZ2VuZGUgT2JqZWt0IHVlYmVyZ2ViZW4KKyAgICAvLyBiZWtvbW1lbi4KKyAgICBvYmplY3QgKmtleXMgPSBtYXAoaGVscGVycywjJ2dldF90eXBlX2luZm8sIDIpOworICAgIGludCAqdmFscyA9IG1hcChoZWxwZXJzLCAjJ2Z1bmNhbGwsIHRoaXNfb2JqZWN0KCksIHByZXZpb3VzX29iamVjdCgxKSk7CisgICAgcmV0ID0gbWttYXBwaW5nKGtleXMsdmFscyk7CisgIH0KKyAgcmV0dXJuIHJldDsKK30KKworLy8gUXVlcnltZXRob2RlIGZ1ZXIgUF9IRUxQRVJfT0JKRUNUUworcHVibGljIG1hcHBpbmcgX3F1ZXJ5X2xpYl9wX2hlbHBlcl9vYmplY3RzKCkgeworICByZXR1cm4gZGVlcF9jb3B5KFF1ZXJ5KFBfSEVMUEVSX09CSkVDVFMsRl9WQUxVRSkpOworfQorCmRpZmYgLS1naXQgYS9zdGQvbGl2aW5nL2ludmVudG9yeS5jIGIvc3RkL2xpdmluZy9pbnZlbnRvcnkuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMzAyN2U0Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2xpdmluZy9pbnZlbnRvcnkuYwpAQCAtMCwwICsxLDY2IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gY29udGFpbmVyL2ludmVudG9yeS5jIC0tIFVtZ2FuZyBtaXQgYmVzb25kZXJlbiBPYmpla3RlbiBpbSBJbnZlbnRvcnkKKy8vCisvLyAkSWQ6IGludmVudG9yeS5jIDY1NTQgMjAwNy0xMC0xNyAyMjo0NTo1M1ogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL2ludmVudG9yeSI7CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8c2Vuc2l0aXZlLmg+CisjaW5jbHVkZSA8YXR0cmlidXRlcy5oPgorCisjZGVmaW5lIE1FIHRoaXNfb2JqZWN0KCkKKworcHVibGljIHZvaWQgUmVtb3ZlU2Vuc2l0aXZlT2JqZWN0KG9iamVjdCBvYikgeworICA6OlJlbW92ZVNlbnNpdGl2ZU9iamVjdChvYik7CisgIFJlbW92ZVNlbnNpdGl2ZU9iamVjdEZyb21MaXN0KG9iLFNFTlNJVElWRV9BVFRBQ0spOworICBpZiAob2JqZWN0cChvYikgJiYgKG9iLT5RdWVyeVByb3AoUF9YX0FUVFJfTU9EKSAgIHx8CisgICAgICAgICAgICAgICAgICAgICAgb2ItPlF1ZXJ5UHJvcChQX1hfSEVBTFRIX01PRCkgKSkKKyAgeworICAgIGRlcmVnaXN0ZXJfbW9kaWZpZXIob2IpOworICAgIC8vIEVyc3Qgd2VubiBkYXMgT2JqZWt0IGRlbiBTcGllbGVyIHZlcmxhc3NlbiBrb25udGUsIGRpZSBBdHRyaWJ1dGUKKyAgICAvLyBuZXUgYmVyZWNobmVuLgorICAgIGlmIChmaW5kX2NhbGxfb3V0KCJVcGRhdGVBdHRyaWJ1dGVzIik9PS0xKQorICAgICAgY2FsbF9vdXQoIlVwZGF0ZUF0dHJpYnV0ZXMiLDApOyAKKyAgfQorfQorCitwdWJsaWMgdm9pZCBJbnNlcnRTZW5zaXRpdmVPYmplY3Qob2JqZWN0IG9iLCBtaXhlZCBhcmcpIHsKKyAgOjpJbnNlcnRTZW5zaXRpdmVPYmplY3Qob2IsYXJnKTsKKyAgaWYgKG9iamVjdHAob2IpICYmIChvYi0+UXVlcnlQcm9wKFBfWF9BVFRSX01PRCkgICB8fAorICAgICAgICAgICAgICAgICAgICAgIG9iLT5RdWVyeVByb3AoUF9YX0hFQUxUSF9NT0QpICkpCisgIHsKKyAgICByZWdpc3Rlcl9tb2RpZmllcihvYik7CisgICAgVXBkYXRlQXR0cmlidXRlcygpOworICB9Cit9CisKK3B1YmxpYyB2b2lkIENoZWNrU2Vuc2l0aXZlQXR0YWNrKGludCBkYW0sIG1peGVkIGRhbV90eXBlLCBtaXhlZCBzcGVsbCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QgZW5lbXkpIHsKKyAgbWl4ZWQgYSx4OworICBpbnQgaTsKKyAgCisgIGlmICghcG9pbnRlcnAoYT1RdWVyeVByb3AoUF9TRU5TSVRJVkVfQVRUQUNLKSkpCisgICAgcmV0dXJuOworICBpZiAoIXBvaW50ZXJwKGRhbV90eXBlKSkKKyAgICBkYW1fdHlwZT0oe2RhbV90eXBlfSk7CisgIGZvciAoaT1zaXplb2YoYSktMTtpPj0wO2ktLSkKKyAgICBpZiAocG9pbnRlcnAoeD1hW2ldKSAmJgorCWRhbT54W1NFTlNfVEhSRVNIT0xEXSAmJgorCW1lbWJlcihkYW1fdHlwZSx4W1NFTlNfS0VZXSk+PTAgJiYKKwlvYmplY3RwKHhbU0VOU19PQkpFQ1RdKSAmJgorCWVudmlyb25tZW50KHhbU0VOU19PQkpFQ1RdKT09TUUgJiYKKwljbG9zdXJlcCh4W1NFTlNfQ0xPU1VSRV0pKQorICAgICAgZnVuY2FsbCh4W1NFTlNfQ0xPU1VSRV0sCisJICAgICAgZW5lbXkseFtTRU5TX0tFWV0sZGFtLAorCSAgICAgIHNwZWxsLHhbU0VOU19PUFRdKTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2xpdmluZy9saWZlLmMgYi9zdGQvbGl2aW5nL2xpZmUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mM2E3MmY1Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2xpdmluZy9saWZlLmMKQEAgLTAsMCArMSwxNTcyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL2xpZmUuYyAtLSBsaWZlIHZhcmlhYmxlcworLy8KKy8vICRJZDogbGlmZS5jIDk0MjYgMjAxNi0wMS0wMyAxMDowMjo1N1ogWmVzc3RyYSAkCisKKy8vIGxpdmluZyBvYmplY3QgbGlmZSB2YXJpYWJsZXMKKy8vCisvLyAgUF9BTElHTiAgICAgICAgIC0tIGFsaWdubWVudCB2YWx1ZQorLy8gIFBfTlBDICAgICAgICAgICAtLSBpZiBsaXZpbmcgaXMgYW4gTlBDCisvLyAgUF9IUCAgICAgICAgICAgIC0tIEhpdFBvaW50cworLy8gIFBfU1AgICAgICAgICAgICAtLSBTcGVsbFBvaW50cworLy8gIFBfQUxDT0hPTCAgICAgICAtLSB2YWx1ZSBvZiBpbnRveGljYXRpb24KKy8vICBQX0RSSU5LICAgICAgICAgLS0gdmFsdWUgb2Ygc29ha25lc3MKKy8vICBQX0ZPT0QgICAgICAgICAgLS0gdmFsdWUgb2Ygc3R1ZmZuZXNzCisvLyAgUF9YUCAgICAgICAgICAgIC0tIGV4cGVyaWVuY2UKKy8vICBQX1BPSVNPTiAgICAgICAgLS0gbGV2ZWwgb2YgcG9pc29uCisvLyAgUF9DT1JQU0UgICAgICAgIC0tIGNvcnBzZS1vYmplY3QKKy8vICBQX0RFQUYgICAgICAgICAgLS0gaWYgbGl2aW5nIGlzIGRlYWYKKyNwcmFnbWEgc3Ryb25nX3R5cGVzLHNhdmVfdHlwZXMscnR0X2NoZWNrcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGhvb2suaD4KKyNpbmNsdWRlIDxsaXZpbmcvc2tpbGxzLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxpdmluZy9saWZlLmg+CisjaW5jbHVkZSA8bGl2aW5nL21vdmluZy5oPgorI2luY2x1ZGUgPGxpdmluZy9jb21iYXQuaD4KKyNpbmNsdWRlIDxsaXZpbmcvYXR0cmlidXRlcy5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8dGhpbmcvbGFuZ3VhZ2UuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxoZWFsdGguaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPHNjb3JlbWFzdGVyLmg+CisjaW5jbHVkZSA8ZGVmdWVsLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGV2ZW50cy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorCisjZGVmaW5lIEFMQ09IT0xfVkFMVUUobikgbgorCisjaW5jbHVkZSA8ZGVidWdfaW5mby5oPiAvL3ZvcnVlYmVyZ2VoZW5kCisKKworLy8gJ3ByaXZhdGUnLVByb3RvdHlwZW4KK3ByaXZhdGUgdm9pZCBEaXN0cmlidXRlRXhwKG9iamVjdCBlbmVteSwgaW50IGV4cF90b19naXZlKTsKKworLy8gVmFyaWFibGVuCitub3NhdmUgaW50IGRlbGF5X2FsY29ob2w7IC8qIHRpbWUgdW50aWwgbmV4dCBhbGNvaG9sIGVmZmVjdCAqLworbm9zYXZlIGludCBkZWxheV9kcmluazsgICAvKiB0aW1lIHVudGlsIG5leHQgZHJpbmsgZWZmZWN0ICovCitub3NhdmUgaW50IGRlbGF5X2Zvb2Q7ICAgIC8qIHRpbWUgdW50aWwgbmV4dCBmb29kIGVmZmVjdCAqLworbm9zYXZlIGludCBkZWxheV9oZWFsOyAgICAvKiB0aW1lIHVudGlsIG5leHQgaGVhbCBlZmZlY3QgKi8KK25vc2F2ZSBpbnQgZGVsYXlfc3A7ICAgICAgLyogdGltZSB1bnRpbCBuZXh0IHNwIHJlZ2VuZXJhdGlvbiAqLworbm9zYXZlIGludCBkZWxheV9wb2lzb247ICAvKiB0aW1lIHVudGlsIG5leHQgcG9pc29uIGVmZmVjdCAqLworbm9zYXZlIGludCBkcm9wX3BvaXNvbjsKK25vc2F2ZSBtYXBwaW5nIGVuZW15X2RhbWFnZTsKK25vc2F2ZSBtYXBwaW5nIGhwX2J1ZmZlcjsKK25vc2F2ZSBtYXBwaW5nIHNwX2J1ZmZlcjsKK25vc2F2ZSBpbnQgcmVtb3ZlX21lOworaW50IG5leHRkZWZ1ZWx0aW1lZm9vZDsKK2ludCBuZXh0ZGVmdWVsdGltZWRyaW5rOworCisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIFNldChQX0dIT1NULCBTQVZFLCBGX01PREUpOworICBTZXQoUF9GUk9HLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9BTElHTiwgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfSFAsIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX1NQLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9YUCwgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KCBQX0xBU1RfWFAsICh7ICIiLCAwIH0pICk7CisgIFNldCggUF9MQVNUX1hQLCBQUk9URUNURUQsIEZfTU9ERV9BUyApOworCisgIFNldChQX0FMQ09IT0wsIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0RSSU5LLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9GT09ELCBTQVZFLCBGX01PREUpOworICBTZXQoUF9QT0lTT04sIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0RFQUYsIFNBVkUsIEZfTU9ERSk7CisKKyAgU2V0UHJvcChQX0ZPT0RfREVMQVksIEZPT0RfREVMQVkpOworICBTZXRQcm9wKFBfRFJJTktfREVMQVksIERSSU5LX0RFTEFZKTsKKyAgU2V0UHJvcChQX0FMQ09IT0xfREVMQVksIEFMQ09IT0xfREVMQVkpOworICBTZXRQcm9wKFBfSFBfREVMQVksSEVBTF9ERUxBWSk7CisgIFNldFByb3AoUF9TUF9ERUxBWSxIRUFMX0RFTEFZKTsKKyAgU2V0UHJvcChQX1BPSVNPTl9ERUxBWSxQT0lTT05fREVMQVkpOworICAvLyBkZWZhdWx0IGZ1ZXIgYWxsZSBMZWJld2VzZW4gKE5QQyArIFNwaWVsZXIpOgorICBTZXRQcm9wKFBfTUFYX1BPSVNPTiwgMTApOworICBTZXRQcm9wKFBfQ09SUFNFLCAiL3N0ZC9jb3Jwc2UiKTsKKworICBuZXh0ZGVmdWVsdGltZWZvb2Q9dGltZSgpK1F1ZXJ5UHJvcChQX0RFRlVFTF9USU1FX0ZPT0QpOworICBuZXh0ZGVmdWVsdGltZWRyaW5rPXRpbWUoKStRdWVyeVByb3AoUF9ERUZVRUxfVElNRV9EUklOSyk7CisKKyAgZW5lbXlfZGFtYWdlPShbOjIgXSk7CisgIGhwX2J1ZmZlcj0oW10pOworICBzcF9idWZmZXI9KFtdKTsKKworICBTZXRQcm9wKFBfREVGVUVMX0xJTUlUX0ZPT0QsMSk7CisgIFNldFByb3AoUF9ERUZVRUxfTElNSVRfRFJJTkssMSk7CisgIFNldFByb3AoUF9ERUZVRUxfVElNRV9GT09ELDEpOworICBTZXRQcm9wKFBfREVGVUVMX1RJTUVfRFJJTkssMSk7CisgIFNldFByb3AoUF9ERUZVRUxfQU1PVU5UX0ZPT0QsMSk7CisgIFNldFByb3AoUF9ERUZVRUxfQU1PVU5UX0RSSU5LLDEpOworCisgIG9mZmVySG9vayhIX0hPT0tfRElFLDEpOworCisgIG9mZmVySG9vayhIX0hPT0tfRk9PRCwxKTsKKyAgb2ZmZXJIb29rKEhfSE9PS19EUklOSywxKTsKKyAgb2ZmZXJIb29rKEhfSE9PS19BTENPSE9MLDEpOworICBvZmZlckhvb2soSF9IT09LX1BPSVNPTiwxKTsKKyAgb2ZmZXJIb29rKEhfSE9PS19DT05TVU1FLDEpOworfQorCisvLyBXZW5uIGRlciBsZXR6dGUgS2FtcGYgbGFuZyBoZXIgaXN0IHVuZCBkYXMgTGViZXdlc2VuIHdpZWRlciB2b2xsZ2VoZWlsdAorLy8gaXN0LCB3aXJkIFBfRU5FTVlfREFNQUdFIHp1cnVlY2tnZXNldHp0LgorcHJvdGVjdGVkIHZvaWQgUmVzZXRFbmVteURhbWFnZSgpIHsKKyAgaWYgKHRpbWUoKSA+IFF1ZXJ5UHJvcChQX0xBU1RfQ09NQkFUX1RJTUUpICsgX19SRVNFVF9USU1FX18gKiA0CisgICAgICAmJiBRdWVyeVByb3AoUF9IUCkgPT0gUXVlcnlQcm9wKFBfTUFYX0hQKSkKKyAgICBlbmVteV9kYW1hZ2U9KFs6MiBdKTsKK30KKworcHJpdmF0ZSB2b2lkIERpc3RyaWJ1dGVFeHAob2JqZWN0IGVuZW15LCBpbnQgZXhwX3RvX2dpdmUpIHsKKyAgaW50IHRvdGFsX2RhbWFnZSwgdG1wLCBleDsKKyAgbWFwcGluZyBwcmVzZW50X2VuZW1pZXM7CisKKyAgaWYgKCBleHBfdG9fZ2l2ZTw9MCApCisgICAgcmV0dXJuOworCisgIG1hcHBpbmcgZW5kbWc9ZGVlcF9jb3B5KGVuZW15X2RhbWFnZSk7CisKKyAgLy8gTWl0Z2xpZWRlciBpbSBUZWFtIGRlcyBLaWxsZXJzIGJla29tbWVuOgorICAvLworICAvLyAgICAgICAgICAgICAgICAgIEdlc2FtdGFudGVpbCBkZXMgVGVhbXMKKyAgLy8gRWlnZW5lbiBBbnRlaWwgKyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgIC8vICAgICAgICAgICAgICAgICAgQW56YWhsICBUZWFtbWl0Z2xpZWRlcgorICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgLy8gICAgICAgICAgICAgICAgMgorICAvLworICBvYmplY3QgKmludiA9IGVuZW15LT5UZWFtTWVtYmVycygpOworICBpZiAoIHBvaW50ZXJwKGludikgKQorICB7CisgICAgcHJlc2VudF9lbmVtaWVzPW1fYWxsb2NhdGUoc2l6ZW9mKGludiksIDEpOworICAgIGZvcmVhY2gob2JqZWN0IG9iOiBpbnYpCisgICAgeworICAgICAgaWYgKCBvYmplY3RwKG9iKSAmJiAoZW52aXJvbm1lbnQob2IpPT1lbnZpcm9ubWVudCgpKSApCisgICAgICB7CisgICAgICAgIHRtcD1lbmRtZ1tvYmplY3RfbmFtZShvYildOworICAgICAgICB0b3RhbF9kYW1hZ2UrPXRtcDsKKyAgICAgICAgcHJlc2VudF9lbmVtaWVzW29iXSA9IHRtcC8yOworICAgICAgICBtX2RlbGV0ZShlbmRtZyxvYmplY3RfbmFtZShvYikpOyAvL3MudS4KKyAgICAgIH0KKyAgICB9CisgICAgaW50IG1pdGdsaWVkZXIgPSBzaXplb2YocHJlc2VudF9lbmVtaWVzKTsKKyAgICBpZiAoIG1pdGdsaWVkZXIgKQorICAgIHsKKyAgICAgIHRtcD10b3RhbF9kYW1hZ2UvKDIqbWl0Z2xpZWRlcik7CisgICAgICBmb3JlYWNoKG9iamVjdCBvYiwgaW50IHB1bmt0ZTogJnByZXNlbnRfZW5lbWllcykKKyAgICAgICAgcHVua3RlICs9IHRtcDsKKyAgICB9CisgIH0KKyAgZWxzZSB7CisgICAgLy8gb2huZSBUZWFtIHdpcmQgdHJvdHpkZW0gZWluIE1hcHBpbmcgZ2VicmF1Y2h0LiBEYSBHcm9lc3NlbnZlcmFlbmRlcnVuZworICAgIC8vIHJlbC4gdGV1ZXIgc2luZCwga2FubiBlaW5mYWNoIG1hbCBmdWVyIDMgRWludHJhZWdlIFBsYXR6IHJlc2VydmllcmVuLgorICAgIHByZXNlbnRfZW5lbWllcz1tX2FsbG9jYXRlKDMsIDEpOworICB9CisgIC8vIFVuZCBub2NoIGRpZSBMZWJld2VzZW4gaW0gUmF1bSBvaG5lIFRlYW0uCisgIGZvcmVhY2gob2JqZWN0IG9iOiBhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpKQorICB7CisgICAgaWYgKCB0bXA9ZW5kbWdbb2JqZWN0X25hbWUob2IpXSApCisgICAgeworICAgICAgdG90YWxfZGFtYWdlICs9IHRtcDsKKyAgICAgIHByZXNlbnRfZW5lbWllc1tvYl0gPSB0bXA7CisgICAgICBtX2RlbGV0ZShlbmRtZyxvYmplY3RfbmFtZShvYikpOyAvLyBOdXIgZWlubWFsIHBybyBMZWJlbiBQdW5rdGUgOikKKyAgICB9CisgIH0KKyAgaWYgKCAhdG90YWxfZGFtYWdlICkKKyAgeworICAgIGVuZW15LT5BZGRFeHAoZXhwX3RvX2dpdmUpOworICB9CisgIGVsc2UKKyAgeworICAgIGZvcmVhY2gob2JqZWN0IG9iLCBpbnQgZGFtYWdlOiBwcmVzZW50X2VuZW1pZXMpCisgICAgeworICAgICAgaWYgKCAhb2JqZWN0cChvYikgKQorICAgICAgICBjb250aW51ZTsKKyAgICAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvYikgJiYgKCAhaW50ZXJhY3RpdmUob2IpCisgICAgICAgICAgICAgIHx8IChxdWVyeV9pZGxlKG9iKT42MDApICkgKQorICAgICAgICBjb250aW51ZTsKKyAgICAgIC8vZXhwX3RvX2dpdmUqcHJlc2VudF9lbmVtaWVzW2ldWzFdL3RvdGFsX2RhbWFnZSBnaWJ0IGJlaSB2aWVsIFNjaGFkZW4KKyAgICAgIC8vZWluZW4gbnVtZXJpY2FsIG92ZXJmbG93LiBEYWhlciBtdWVzc2VuIHdpciBoaWVyIHdvaGwgZG9jaAorICAgICAgLy96d2lzY2hlbnplaXRsaWNoIG1pdCBmbG9hdHMgcmVjaG5lbiwgYXVjaCB3ZW5uIGRhcyAwLTEgWFAgVmVybHVzdAorICAgICAgLy9kdXJjaCBmbG9hdC0+aW50LUtvbnZlcnNpb24gZ2lidC4gKGNlaWwoKSBsb2hudCBzaWNoIElNSE8gbmljaHQuKQorICAgICAgZXggPSAoaW50KShleHBfdG9fZ2l2ZSooKGZsb2F0KWRhbWFnZS8oZmxvYXQpdG90YWxfZGFtYWdlKSk7CisgICAgICBvYi0+QWRkRXhwKGV4KTsKKyAgICB9CisgIH0KK30KKworLyoKKyAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGZyb20gb3RoZXIgcGxheWVycyB3aGVuIHRoZXkgd2FudCB0byBtYWtlCisgKiBkYW1hZ2UgdG8gdXMuIEJ1dCBpdCB3aWxsIG9ubHkgYmUgY2FsbGVkIGluZGlyZWN0bHkuCisgKiBXZSByZXR1cm4gaG93IG11Y2ggZGFtYWdlIHdlIHJlY2VpdmVkLCB3aGljaCB3aWxsCisgKiBjaGFuZ2UgdGhlIGF0dGFja2VycyBzY29yZS4gVGhpcyByb3V0aW5lIGlzIHByb2JhYmx5IGNhbGxlZCBmcm9tCisgKiBoZWFydF9iZWF0KCkgZnJvbSBhbm90aGVyIHBsYXllci4KKyAqIENvbXBhcmUgdGhpcyBmdW5jdGlvbiB0byByZWR1Y2VfaGl0X3BvaW50cyhkYW0pLgorICovCitwdWJsaWMgaW50IGRvX2RhbWFnZShpbnQgZGFtLCBvYmplY3QgZW5lbXkpCit7IGludCBoaXRfcG9pbnQsYWwsYWwyOworCisgIGlmICggZXh0ZXJuX2NhbGwoKQorICAgICAgJiYgb2JqZWN0cChlbmVteSkKKyAgICAgICYmIGxpdmluZyhlbmVteSkKKyAgICAgICYmICFRdWVyeVByb3AoUF9FTkFCTEVfSU5fQVRUQUNLX09VVCkpCisgIHsKKyAgICBhbD10aW1lKCktZW5lbXktPlF1ZXJ5UHJvcChQX0xBU1RfTU9WRSk7CisgICAgaWYgKGFsPDMpICAgICAgLy8gRXJzdGUgS2FtcGZydW5kZSBuYWNoIEJldHJldGVuIGRlcyBSYXVtZXM/CisgICAgICBkYW0vPSg0LWFsKTsgLy8gR2VnZW4gUmVpbi1GZXVlcmJhbGwtUmF1cy1UYWt0aWsKKyAgfQorCisgIGlmICggUXVlcnlQcm9wKFBfR0hPU1QpIHx8IFF1ZXJ5UHJvcChQX05PX0FUVEFDSykgfHwgKGRhbTw9MCkKKyAgICAgIHx8ICggb2JqZWN0cChlbmVteSkKKyAgICAgICAgICAmJiAoIGVuZW15LT5RdWVyeVByb3AoUF9HSE9TVCkKKyAgICAgICAgICAgICAgfHwgZW5lbXktPlF1ZXJ5UHJvcChQX05PX0FUVEFDSykgKSApICkKKyAgICByZXR1cm4gMDsKKworICBoaXRfcG9pbnQgPSBRdWVyeVByb3AoUF9IUCktZGFtOworCisgIGlmICggUXVlcnlQcm9wKFBfWFApICYmIG9iamVjdHAoZW5lbXkpICkKKyAgeworICAgIGlmICggIVF1ZXJ5UHJvcChQX05PX1hQKSApCisgICAgICBlbmVteS0+QWRkRXhwKGRhbSooaW50KVF1ZXJ5UHJvcChQX1RPVEFMX1dDKS8xMCk7CisgIH0KKworICBpZiAobGl2aW5nKGVuZW15KSkgeworICAgICAgc3RyaW5nIGVubmFtZSA9IG9iamVjdF9uYW1lKGVuZW15KTsKKyAgICAgIC8vIEhtcGYuIEJsdWVwcmludHMgc2luZCBkb29mLiBEaWUgQ2hhbmNlIGlzdCB6d2FyIGdlcmluZywgYWJlciBrb2VubnRlCisgICAgICAvLyBzZWluLCBkYXNzIGVpbiBVbmlxdWUtTlBDIG1pdCB6d2VpIHZlcnNjaGllZGVuZW4gU3BpZWxlcm4gYW0gZ2xlaWNoZW4KKyAgICAgIC8vIE5QQyBtZXR6ZWx0LgorICAgICAgLy8gVE9ETzogTUhtbS4gd2llIGdyb3NzIGlzdCBkYXMgUmlzaWtvIHdpcmtsaWNoPworICAgICAgLy9pZiAoIWNsb25lcChlbmVteSkpCisgICAgICAvLyAgICBlbm5hbWUgPSBlbm5hbWUgKyAiXyIgKyB0b19zdHJpbmcob2JqZWN0X3RpbWUoZW5lbXkpKTsKKyAgICAgIC8vIG51ciB3ZW5uIGdlZ25lciBOUEMgaXN0IHVuZCBub2NoIG5pY2h0IGRyaW5zdGVodDogRGF0ZW4gYXVzCisgICAgICAvLyBQX0hFTFBFUl9OUEMgYXVzd2VydGVuCisgICAgICBpZiAoIW1lbWJlcihlbmVteV9kYW1hZ2UsZW5lbXkpICYmICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGVuZW15KSkgeworICAgICAgICAgIG1peGVkIGhlbHBlciA9IGVuZW15LT5RdWVyeVByb3AoUF9IRUxQRVJfTlBDKTsKKyAgICAgICAgICBpZiAocG9pbnRlcnAoaGVscGVyKSAmJiBvYmplY3RwKGhlbHBlclswXSkpCisgICAgICAgICAgICAgIGVuZW15X2RhbWFnZVtlbm5hbWUsMV0gPSBoZWxwZXJbMF07CisgICAgICB9CisgICAgICBlbmVteV9kYW1hZ2VbZW5uYW1lLDBdKz1kYW07CisgIH0KKworICBTZXRQcm9wKFBfSFAsIGhpdF9wb2ludCk7CisKKyAgaWYgKCBoaXRfcG9pbnQ8MCApCisgIHsKKyAgICAvL1RPRE86IFdhcnVtIG5pY2h0IGRhcyBnYW56ZSBaZXVnIGlucyBkaWUoKSB2ZXJsZWdlbj8KKyAgICBpZiAoIGVuZW15ICkKKyAgICB7CisgICAgICBlbmVteS0+U3RvcEh1bnRGb3IoTUUsMSk7CisgICAgICBpZiAoICFRdWVyeVByb3AoUF9OT19YUCkgKQorICAgICAgICBEaXN0cmlidXRlRXhwKGVuZW15LFF1ZXJ5UHJvcChQX1hQKS8xMDApOworICAgICAgaWYgKCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKQorICAgICAgICBsb2dfZmlsZSAoIk5QQ19YUCIsIHNwcmludGYoCisJICAgICJbJXNdICVzLCBYUDogJWQsIEhQKldDOiAlZCwgS2lsbGVyOiAlc1xuIiwKKwkgICAgZHRpbWUodGltZSgpKSwgb2JqZWN0X25hbWUoTUUpLCAoUXVlcnlQcm9wKFBfWFApLzEwMCksCisgICAgICAgICAgICAgICAgICBRdWVyeVByb3AoUF9UT1RBTF9XQykqUXVlcnlQcm9wKFBfTUFYX0hQKS8xMCwKKyAgICAgICAgICAgICAgICAgIGVuZW15LT5uYW1lKCl8fCJOb05hbWUiICkpOworICAgICAgYWwgPSBRdWVyeVByb3AoUF9BTElHTikvNTAgKyBlbmVteS0+UXVlcnlQcm9wKFBfQUxJR04pLzIwMDsKKyAgICAgIGlmIChhbD4yMCkKKyAgICAgICAgYWw9MjA7CisgICAgICBlbHNlIGlmKGFsPC0yMCkKKyAgICAgICAgYWw9LTIwOworICAgICAgZW5lbXktPlNldFByb3AoUF9BTElHTixlbmVteS0+UXVlcnlQcm9wKFBfQUxJR04pLWFsKTsKKyAgICB9CisgICAgU2V0UHJvcChQX0tJTExFUiwgZW5lbXkpOworICAgIAorICAgIGRpZSgpOworICB9CisgIHJldHVybiBkYW07Cit9CisKKworcHJpdmF0ZSB2b2lkIF90cmFuc2Zlciggb2JqZWN0ICpvYnMsIHN0cmluZ3xvYmplY3QgZGVzdCwgaW50IGZsYWcgKQoreyAgIGludCBpOworCisgICAgaSA9IHNpemVvZihvYnMpOworCisgICAgLy8gRWluZSBTY2hsZWlmZSBpc3QgendhciBsYW5nc2FtZXIgYWxzIGZpbHRlcigpIG8uYWUuLCBhYmVyCisgICAgLy8gc2VsYnN0IG1pdCBlaW5lciBub2NoIHNvIHNjaG5lbGxlbiBMb2VzdW5nIGthbm4gbGVpZGVyIG5pY2h0CisgICAgLy8gYXVzZ2VzY2hsb3NzZW4gd2VyZGVuLCBkYXNzIGlyZ2VuZHdvIGVpbiB0b28tbG9uZy1ldmFsLUJ1ZyBkYXp3aXNjaGVuCisgICAgLy8ga29tbXQuIERhenUgc2luZCBkaWUgS2FlbXBmZSBtaXQgR2lsZGVuLU5QQ3MgZXRjLiBlaW5mYWNoIHp1IHRldWVyIC4uLgorICAgIC8vIFBydWVmdW5nIGF1ZiB6ZXJzdG9lcnRlIE9iamVrdGUsIGRhIGVpbmlnZSBzaWNoIGV2dGwuIGltIE5vdGlmeVBsYXllckRlYXRoKCkgCisgICAgLy8gemVyc3RvZXJlbi4KKyAgIHdoaWxlICggaSAmJiBnZXRfZXZhbF9jb3N0KCkgPiAzMDAwMDAgKQorICAgICAgICBpZiAoIG9iamVjdHAob2JzWy0taV0pICYmICFvYnNbaV0tPlF1ZXJ5UHJvcChQX05FVkVSRFJPUCkgKQorICAgICAgICAvLyBKZXR6dCB3aXJkJ3Mgbm9jaCBldHdhcyB0ZXVyZXIgbWl0IGNhdGNoKCkgLSBhYmVyIG1hbmNoZSBTYWNoZW4KKyAgICAgICAgLy8gZHVlcmZlbiBlaW5mYWNoIG5pY2h0IGJ1Z2dlbgorICAgICAgICAgICAgY2F0Y2goIG9ic1tpXS0+bW92ZSggZGVzdCwgZmxhZyApO3B1Ymxpc2ggKTsKKworICAgIGlmICggaSA+IDAgKQorICAgICAgICAvLyBadXZpZWwgUmVjaGVuemVpdCB2ZXJicmF0ZW4sIGVzIG11ZXNzZW4gbm9jaCBPYmpla3RlIGJld2VndCB3ZXJkZW4KKyAgICAgICAgY2FsbF9vdXQoICMnX3RyYW5zZmVyLCAwLCBvYnNbMC4uaS0xXSwgZGVzdCwgZmxhZyApOworICAgIGVsc2UgeworICAgICAgICBpZiAoIHJlbW92ZV9tZSApCisgICAgICAgICAgICByZW1vdmUoKTsKKyAgICB9Cit9CisKKworcHVibGljIHZhcmFyZ3Mgdm9pZCB0cmFuc2Zlcl9hbGxfdG8oIHN0cmluZ3xvYmplY3QgZGVzdCwgaW50IGlzbnBjICkgeworICAgIGludCBmbGFnczsKKyAgICBvYmplY3QgKm9iczsKKworICAgIGlmICggIW9iamVjdHAoTUUpICkKKyAgICAgICAgcmV0dXJuOworCisgICAgLy8gRGFzIEZsYWcgImlzbnBjIiBpc3QgZnVlciBOUENzIGdlZGFjaHQuIERlcmVuIEF1c3J1ZXN0dW5nIGRhcmYgbmljaHQKKyAgICAvLyBtaXQgTV9OT0NIRUNLIGJld2VndCB3ZXJkZW4sIGRhIFNwaWVsZXIgZGFzIGJlaSBOaWNodC1TdGFuZGFyZC1MZWljaGVuCisgICAgLy8gc29uc3QgdS5VLiBhdXNudXR6ZW4ga29lbm50ZW4uCisgICAgaWYgKCBpc25wYyApCisgICAgICAgIGZsYWdzID0gTV9TSUxFTlQ7CisgICAgZWxzZQorICAgICAgICBmbGFncyA9IE1fU0lMRU5UfE1fTk9DSEVDSzsKKworICAgIG9icyA9IGFsbF9pbnZlbnRvcnkoTUUpIHx8ICh7fSk7CisKKyAgICAvLyB1bm5vZXRpZywgd2VpbCBfdHJhbnNmZXIoKSBhdWNoIGF1ZiBQX05FVkVSRFJPUCBwcnVlZnQuIFplc3N0cmEKKyAgICAvL29icyAtPSBmaWx0ZXJfb2JqZWN0cyggb2JzLCAiUXVlcnlQcm9wIiwgUF9ORVZFUkRST1AgKTsKKworICAgIF90cmFuc2Zlciggb2JzLCBkZXN0LCBmbGFncyApOworfQorCisKK3Byb3RlY3RlZCB2YXJhcmdzIHZvaWQgY3JlYXRlX2tpbGxfbG9nX2VudHJ5KHN0cmluZyBraWxsZXIsIG9iamVjdCBlbmVteSkgeworICBpbnQgbGV2ZWwsbG9zdF9leHA7CisKKyAgaWYgKCAobGV2ZWw9UXVlcnlQcm9wKFBfTEVWRUwpKTwyMCB8fCAhSVNfU0VFUihNRSkgKQorICAgIGxvc3RfZXhwID0gUXVlcnlQcm9wKFBfWFApLzM7CisgIGVsc2UKKyAgICBsb3N0X2V4cCA9IFF1ZXJ5UHJvcChQX1hQKS8obGV2ZWwtMTcpOworICAKKyAgbG9nX2ZpbGUoIktJTExTIixzcHJpbnRmKCIlcyAlcyAoJWQsJWQpICVzXG4iLCBzdHJmdGltZSgiJWUgJWIgJUg6JU0iKSwKKyAgICAgICAgICAgICAgIGNhcGl0YWxpemUoUkVBTF9VSUQoTUUpKSwgbGV2ZWwsIGxvc3RfZXhwLzEwMDAsIGtpbGxlcikpOyAKK30KKworLy8gTGllZmVydCBpbSBUb2QgKG5hY2ggZGVtIHRvZXRlbmRlbiBkb19kYW1hZ2UoKSkgZGFzIFNwaWVsZXJvYmpla3QsIHdhcyBkZW4KKy8vIFRvZCB3b2hsIHp1IHZlcmFudHdvcnRlbiBoYXQsIGZhbGxzIGVzIGVybWl0dGVsdCB3ZXJkZW4ga2Fubi4gRXMgd2VyZGVuIHZvcgorLy8gYWxsZW0gcmVnaXN0cmllcnRlIEhlbGZlci1OUEMgdW5kIGVpbmlnZSBTb25kZXJvYmpla3RlIGJlcnVlY2tzaWNodGlndC4KK3Byb3RlY3RlZCBvYmplY3QgZ2V0X2tpbGxpbmdfcGxheWVyKCkKK3sKKyAgb2JqZWN0IGtpbGxlcj1RdWVyeVByb3AoUF9LSUxMRVIpOworICAvLyBrb2VubnRlIHNlaW4sIHdlbm4gYXVzc2VyaGFsYiBkZXMgVG9kZXMgZ2VydWZlbiBvZGVyIGVpbmUgVmVyZ2lmdHVuZyB1bnMKKyAgLy8gdW1nZWJyYWNodCBoYXQuCisgIGlmICghb2JqZWN0cChraWxsZXIpKQorICAgIHJldHVybiAwOworCisgIHdoaWxlIChraWxsZXIgJiYgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoa2lsbGVyKSkKKyAgICBraWxsZXIgPSBraWxsZXItPlF1ZXJ5VXNlcigpOworCisgIHJldHVybiBraWxsZXI7Cit9CisKK3Byb3RlY3RlZCBvYmplY3QgR2l2ZUtpbGxTY29yZShvYmplY3QgcGwsIGludCBucGNudW0pCit7CisgIC8vIFN0dWZlbnB1bmt0IGZ1ZXIgZGVuIEtpbGwgdmVyZ2ViZW4uCisgIC8vIEZhbGxzIGRlciBLaWxsZXIgZGVuIFB1bmt0IHNjaG9uIGhhdCwgd2lyZAorICAvLyB6dWZhZWxsaWcgZWluIE1pdGdsaWVkIHNlaW5lcyBUZWFtcyBhdXNnZXdhZWhsdAorICAvLyB1bmQgZGllc2VtIGRlciBQdW5rdCBnZWdlYmVuLgorICBvYmplY3QgKm9icyxvYjsKKyAgbWl4ZWQgKmZyOworICBpbnQgaSxqLHN6OworCisgIGlmICggcG9pbnRlcnAob2JzPXBsLT5UZWFtTWVtYmVycygpKSAmJiAobWVtYmVyKG9icyxwbCk+PTApICkKKyAgeworICAgIGlmICggIXBvaW50ZXJwKGZyPXBsLT5QcmVzZW50VGVhbVJvd3MoKSkKKyAgICAgICAgfHwgIXNpemVvZihmcikKKyAgICAgICAgfHwgIXBvaW50ZXJwKGZyPWZyWzBdKSkgLy8gRXJzdGUgUmVpaGUgZGVzIFRlYW1zCisgICAgICBmcj0oe30pOworICAgIGZyLT0oe3BsLDB9KTsKKyAgICBvYnMtPSh7cGwsMH0pOworICAgIG9icy09ZnI7CisgICAgaT1zej1zaXplb2Yob2JzKTsgLy8gcmVzdGxpY2hlIFRlYW1taXRnbGllZGVyIGluIHp1ZmFlbGxpZ2VyIFJlaWhlbmZvbGdlOgorICAgIGZvciAoIC0taSA7IGk+PTAgOyBpLS0gKQorICAgIHsKKyAgICAgIGo9cmFuZG9tKHN6KTsKKyAgICAgIG9iPW9ic1tqXTsKKyAgICAgIG9ic1tqXT1vYnNbMF07CisgICAgICBvYnNbMF09b2I7CisgICAgfQorICAgIGk9c3o9c2l6ZW9mKGZyKTsgIC8vIEVyc3RlIFJlaWhlIGluIHp1ZmFlbGxpZ2VyIFJlaWhlbmZvbGdlOgorICAgIGZvciAoIC0taSA7IGk+PTAgOyBpLS0gKQorICAgIHsKKyAgICAgIGo9cmFuZG9tKHN6KTsKKyAgICAgIG9iPWZyW2pdOworICAgICAgZnJbal09ZnJbMF07CisgICAgICBmclswXT1vYjsKKyAgICB9CisKKyAgICBvYnMrPWZyOyAgICAgLy8gRXJzdGUgUmVpaGUgd2lyZCB2b3IgUmVzdCBnZXRlc3RldAorICAgIG9icys9KHtwbH0pOyAvLyBLaWxsZXIgd2lyZCBhbHMgZXJzdGVzIGdldGVzdGV0CisgIH0KKyAgZWxzZQorICB7CisgICAgb2JzPSh7cGx9KTsKKyAgfQorICBmb3IgKCBpPXNpemVvZihvYnMpLTEgOyBpPj0wIDsgaS0tICkKKyAgICBpZiAoIG9iamVjdHAob2I9b2JzW2ldICkKKyAgICAgICAgJiYgaW50ZXJhY3RpdmUob2IpICAgICAvLyBOdXIgbmV0enRvdCBkYWJlaSBzdGVoZW4gZ2lsdCBuaWNodCA6KQorICAgICAgICAmJiBxdWVyeV9pZGxlKG9iKTw2MDAgIC8vIGdlZ2VuIExldXRlIGRpZSBzaWNoIG51ciBtaXRzY2hsZXBwZW4gbGFzc2VuCisgICAgICAgICYmIGVudmlyb25tZW50KG9iKT09ZW52aXJvbm1lbnQocGwpIC8vIE51ciBhbndlc2VuZGUgVGVhbW1pdGdsaWVkZXIKKyAgICAgICAgJiYgIUlTX0xFQVJORVIob2IpCisvLyAgICAgICAgJiYgIW9iLT5RdWVyeVByb3AoUF9URVNUUExBWUVSKQorICAgICAgICAmJiAhKFNDT1JFTUFTVEVSLT5IYXNLaWxsKG9iLE1FKSkgKQorICAgICAgcmV0dXJuIFNDT1JFTUFTVEVSLT5HaXZlS2lsbChvYixucGNudW0pLG9iOworCisgIHJldHVybiBTQ09SRU1BU1RFUi0+R2l2ZUtpbGwocGwsbnBjbnVtKSxwbDsKK30KKworLy8genVtIHVlYmVyc2NocmVpYmVuIGluIFNwaWVsZXJuCitwdWJsaWMgaW50IGRlYXRoX3N1ZmZlcmluZygpIHsKKyAgcmV0dXJuIDA7IC8vIE5QQyBoYWJlbiBrZWluZSBUb2Rlc2ZvbGdlbgorfQorCisvLyBrZWluIDIuIExlYmVuIGZ1ZXIgTmljaHQtU3BpZWxlci4gOy0pCit2YXJhcmdzIHByb3RlY3RlZCBpbnQgc2Vjb25kX2xpZmUoIG9iamVjdCBjb3Jwc2UgKSB7CisgICAgcmV0dXJuIDA7Cit9CisKK3B1YmxpYyB2YXJhcmdzIHZvaWQgZGllKCBpbnQgcG9pc29uZGVhdGgsIGludCBleHRlcm4gKQoreyAgIG9iamVjdCBjb3Jwc2U7CisgICAgc3RyaW5nIGRpZV9tc2csIHRtcDsKKyAgICBtaXhlZCByZXM7CisgICAgbWl4ZWQgaG9va0RhdGE7CisgICAgbWl4ZWQgaG9va1JlczsKKworICAgIGlmICggIW9iamVjdHAodGhpc19vYmplY3QoKSkgfHwgUXVlcnlQcm9wKFBfR0hPU1QpICkKKyAgICAgICAgcmV0dXJuOyAvLyBHaG9zdHMgZG9udCBkaWUgLi4uCisKKyAgICAvLyBkaXJla3Qgdm9uIGV4dGVybiBhdWZnZXJ1ZmVuIHVuZCBuaWNodCB1ZWJlciBoZWFydF9iZWF0KCkgb2RlcgorICAgIC8vIGRvX2RhbWFnZSgpIGhpZXJoZXIgZ2VsYW5ndD8KKyAgICBpZiAoZXh0ZXJuX2NhbGwoKSAmJiBwcmV2aW91c19vYmplY3QoKSAhPSB0aGlzX29iamVjdCgpKSB7CisgICAgICBleHRlcm49MTsKKyAgICAgIFNldFByb3AoUF9LSUxMRVIsIHByZXZpb3VzX29iamVjdCgpKTsKKyAgICB9CisKKyAgICBpZiAoIHJlcyA9IFF1ZXJ5UHJvcChQX1RNUF9ESUVfSE9PSykgKXsKKyAgICAgICAgaWYgKCBwb2ludGVycChyZXMpICYmIHNpemVvZihyZXMpPj0zCisgICAgICAgICAgICAmJiBpbnRwKHJlc1swXSkgJiYgdGltZSgpPHJlc1swXQorICAgICAgICAgICAgJiYgb2JqZWN0cChyZXNbMV0pICYmIHN0cmluZ3AocmVzWzJdKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIGlmICggcmVzID0gY2FsbF9vdGhlciggcmVzWzFdLCByZXNbMl0sIHBvaXNvbmRlYXRoICkgKSB7CisgICAgICAgICAgICAgIFNldFByb3AoUF9LSUxMRVIsMCk7CisgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICBTZXRQcm9wKFBfVE1QX0RJRV9IT09LLDApOworICAgIH0KKworICAgIC8vIHRyaWdnZXIgZGllIGhvb2sKKyAgICBob29rRGF0YT1wb2lzb25kZWF0aDsKKyAgICBob29rUmVzPUhvb2tGbG93KEhfSE9PS19ESUUsaG9va0RhdGEpOworICAgIGlmIChwb2ludGVycChob29rUmVzKSAmJiBzaXplb2YoaG9va1Jlcyk+SF9SRVREQVRBKXsKKyAgICAgIGlmKGhvb2tSZXNbSF9SRVRDT0RFXT09SF9DQU5DRUxMRUQpIHsKKyAgICAgICAgU2V0UHJvcChQX0tJTExFUiwwKTsKKyAgICAgICAgcmV0dXJuOworICAgICAgfQorICAgICAgZWxzZSBpZiAoaG9va1Jlc1tIX1JFVENPREVdPT1IX0FMVEVSRUQpCisgICAgICAgICAgcG9pc29uZGVhdGggPSBob29rUmVzW0hfUkVUREFUQV07CisgICAgfQorCisgICAgaWYgKCBJU19MRUFSTklORyhNRSkgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKXsKKyAgICAgICB0ZWxsX29iamVjdCggTUUsICJTZWkgZnJvaCBkYXNzIER1IHVuc3RlcmJsaWNoIGJpc3QsIHNvbnN0IHdhZXJlIGVzICIKKyAgICAgICAgICAgICAgICAgICAgICAgICJlYmVuIERlaW4gRW5kZSBnZXdlc2VuLlxuIik7CisgICAgICAgU2V0UHJvcChQX0tJTExFUiwwKTsKKyAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLy8gR2VnbmVyIGJlZnJpZWRlbi4KKyAgICBtYXBfb2JqZWN0cyggUXVlcnlFbmVtaWVzKClbMF0sICJTdG9wSHVudEZvciIsIE1FLCAxICk7CisgICAgU3RvcEh1bnRpbmdNb2RlKDEpOworCisgICAgLy8gRmFsbHMgZGllKCkgZGlyZWt0IGF1ZmdlcnVmZW4gd3VyZGUgdW5kIGRpZXMgZWluIFNwaWVsZXIgaXN0LCBtdXNzIGRhcworICAgIC8vIGRpZSgpIG5vY2ggRWludHJhZWdlIGluIC9sb2cvS0lMTFMgdmlhIGNyZWF0ZV9raWxsX2xvZ19lbnRyeSBiencuIGluCisgICAgLy8gL2xvZy9LSUxMRVIgZXJzdGVsbGVuLgorICAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgJiYgZXh0ZXJuICkKKyAgICB7CisgICAgICBvYmplY3Qga2lsbGVyID0gUXVlcnlQcm9wKFBfS0lMTEVSKSAKKyAgICAgICAgICAgICAgICAgICAgIHx8IHByZXZpb3VzX29iamVjdCgpIHx8IHRoaXNfaW50ZXJhY3RpdmUoKSB8fCB0aGlzX3BsYXllcigpOworICAgICAgaWYgKCBraWxsZXIgJiYgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoa2lsbGVyKSApCisgICAgICB7CisgICAgICAgICAgdG1wID0gZXhwbG9kZSggb2JqZWN0X25hbWUoa2lsbGVyKSwgIiMiKVswXSArICIgKGRpcmVrdCAhKSI7CisKKyAgICAgICAgICBjcmVhdGVfa2lsbF9sb2dfZW50cnkoIHRtcCArICIgKCIgKyBSRUFMX1VJRChraWxsZXIpICsgIikiLCBraWxsZXIgKTsKKyAgICAgIH0KKyAgICAgIGVsc2UgaWYgKCBraWxsZXIgJiYgIVF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpICYmICFJU19MRUFSTkVSKE1FKSApCisgICAgICB7CisgICAgICAgICAgbG9nX2ZpbGUoICJLSUxMRVIiLCBzcHJpbnRmKCAiJXMgJXMgKCVkLyVkKSB0b2V0ZXRlICVzICglZC8lZClcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdGltZSh0aW1lKCkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShnZXR1aWQoa2lsbGVyKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWVyeV93aXpfbGV2ZWwoa2lsbGVyKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtpbGxlci0+UXVlcnlQcm9wKFBfTEVWRUwpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShnZXR1aWQoTUUpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5X3dpel9sZXZlbChNRSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRdWVyeVByb3AoUF9MRVZFTCkgKSApOworCisgICAgICAgICAga2lsbGVyLT5TZXRQcm9wKCBQX0tJTExTLCAtMSApOworICAgICAgfQorICAgIH0KKworICAvLyBCZWkgTlBDIEVLcyB2ZXJnZWJlbiB1bmQgZ2dmLiBpbiBkZXIgR2lsZGUgZGVzIEtpbGxlcnMgdW5kIGltIFJhdW0KKyAgLy8gTlBDX0tpbGxlZF9CeSgpIHJ1ZmVuLgorICBpZiAoICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApCisgIHsKKyAgICBvYmplY3Qga2lsbGVyID0gKChvYmplY3QpIFF1ZXJ5UHJvcChQX0tJTExFUikpIHx8IHByZXZpb3VzX29iamVjdCgpIHx8CisgICAgICB0aGlzX2ludGVyYWN0aXZlKCkgfHwgdGhpc19wbGF5ZXIoKTsKKworICAgIGlmICgga2lsbGVyICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoa2lsbGVyKSApCisgICAgeworICAgICAgaWYgKHN0cmluZ3AocmVzPWtpbGxlci0+UXVlcnlQcm9wKFBfR1VJTEQpKQorICAgICAgICAgICYmIG9iamVjdHAocmVzPWZpbmRfb2JqZWN0KCIvZ2lsZGVuLyIrcmVzKSkpCisgICAgICAgIHJlcy0+TlBDX0tpbGxlZF9CeShraWxsZXIpOworCisgICAgICBpZiAoZW52aXJvbm1lbnQoKSkKKyAgICAgICAgICBlbnZpcm9ubWVudCgpLT5OUENfS2lsbGVkX0J5KGtpbGxlcik7CisKKyAgICAgIHJlcyA9IFF1ZXJ5UHJvcChQX1hQKTsKKyAgICAgIHJlcyA9IChyZXMgPCBTQ09SRV9MT1dfTUFSSykgPyAwIDogKChyZXMgPiBTQ09SRV9ISUdIX01BUkspID8gMiA6IDEpOworICAgICAgaWYgKCAhUXVlcnlQcm9wKFBfTk9fU0NPUkUpICYmICFJU19MRUFSTkVSKGtpbGxlcikgJiYKKyAgICAgICAgICAgLy8gIWtpbGxlci0+UXVlcnlQcm9wKFBfVEVTVFBMQVlFUikgJiYKKyAgICAgICAgICAgcG9pbnRlcnAoIHJlcyA9IFNDT1JFTUFTVEVSLT5RdWVyeU5QQyhyZXMpKSApCisgICAgICAgIEdpdmVLaWxsU2NvcmUoIGtpbGxlciwgcmVzWzBdICk7CisgICAgfQorICB9CisKKyAgaWYoICEoZGllX21zZyA9IFF1ZXJ5UHJvcChQX0RJRV9NU0cpKSApCisgICAgaWYgKFF1ZXJ5UHJvcChQX1BMVVJBTCkpCisgICAgICBkaWVfbXNnID0gIiBmYWxsZW4gdG90IHp1IEJvZGVuLlxuIjsKKyAgICBlbHNlCisgICAgICBkaWVfbXNnID0gIiBmYWVsbHQgdG90IHp1IEJvZGVuLlxuIjsKKworICBpZiAoIHBvaXNvbmRlYXRoICkKKyAgeworICAgICAgU2V0KCBQX0xBU1RfREFNVFlQRVMsICh7IERUX1BPSVNPTiB9KSApOworICAgICAgU2V0KCBQX0xBU1RfREFNVElNRSwgdGltZSgpICk7CisgICAgICBTZXQoIFBfTEFTVF9EQU1BR0UsIDEgKTsKKyAgICAgIGRpZV9tc2cgPSAiIHdpcmQgdm9uIEdpZnQgaGlud2VnZ2VyYWZmdCB1bmQga2lwcHQgdW0uXG4iOworICB9CisKKyAgc2F5KCBjYXBpdGFsaXplKG5hbWUoV0VSLDEpKSArIGRpZV9tc2cgKTsKKworICAvLyBXZW5uIGtlaW5lIExlaWNoZSwgZGFubiBLcmFtIGlucyBFbnYgbGVnZW4uCisgIGlmICggUXVlcnlQcm9wKFBfTk9DT1JQU0UpIHx8ICEodG1wID0gUXVlcnlQcm9wKFBfQ09SUFNFKSkKKyAgICAgIHx8IGNhdGNoKGNvcnBzZSA9IGNsb25lX29iamVjdCh0bXApO3B1Ymxpc2gpIAorICAgICAgfHwgIW9iamVjdHAoY29ycHNlKSApCisgIHsKKyAgICAgIC8vIE1hZ2llciBvZGVyIFRlc3RzcGllbGVyIGJlaGFsdGVuIGlocmUgQXVzcnVlc3R1bmcuCisgICAgICAvLyBTb25zdCBrYWVtZW4gdS5VLiBTcGllbGVyIGFuIE1hZ2llcnRvb2xzIGV0Yy4gaGVyYW4KKyAgICAgIGlmICggIShJU19MRUFSTkVSKE1FKSB8fCAodG1wID0gUXVlcnkoUF9URVNUUExBWUVSKSkgJiYKKyAgICAgICAgICAgICAoIXN0cmluZ3AodG1wKSB8fCBJU19MRUFSTkVSKCBsb3dlcl9jYXNlKHRtcCkgKSkpICkKKyAgICAgICAgICB0cmFuc2Zlcl9hbGxfdG8oIGVudmlyb25tZW50KCksIDAgKTsKKyAgICAgIGVsc2UKKyAgICAgICAgICAvLyBBYmVyIHNpZSB6aWVoZW4gc2ljaCBhdXMuCisgICAgICAgICAgZmlsdGVyX29iamVjdHMoUXVlcnlQcm9wKFBfQVJNT1VSUyksIkRvVW53ZWFyIixNX05PQ0hFQ0ssMCk7CisgIH0KKyAgZWxzZQorICAvLyBzb25zdCBpbiBkaWUgTGVpY2hlIGxlZ2VuLgorICB7CisgICAgICBjb3Jwc2UtPklkZW50aWZ5KE1FKTsKKyAgICAgIGNvcnBzZS0+bW92ZSggZW52aXJvbm1lbnQoKSwgTV9OT0NIRUNLfE1fU0lMRU5UICk7CisgICAgICAvLyBNYWdpZXIgb2RlciBUZXN0c3BpZWxlciBiZWhhbHRlbiBpaHJlIEF1c3J1ZXN0dW5nLgorICAgICAgLy8gU29uc3Qga2FlbWVuIHUuVS4gU3BpZWxlciBhbiBNYWdpZXJ0b29scyBldGMuIGhlcmFuCisgICAgICBpZiAoICEoSVNfTEVBUk5FUihNRSkgfHwgKHRtcCA9IFF1ZXJ5KFBfVEVTVFBMQVlFUikpICYmCisgICAgICAgICAgICAgKCFzdHJpbmdwKHRtcCkgfHwgSVNfTEVBUk5FUiggbG93ZXJfY2FzZSh0bXApICkpKSApCisgICAgICAgICAgdHJhbnNmZXJfYWxsX3RvKCBjb3Jwc2UsICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApOworICAgICAgZWxzZQorICAgICAgICAgIC8vIEFiZXIgc2llIHppZWhlbiBzaWNoIGF1cy4KKyAgICAgICAgICBmaWx0ZXJfb2JqZWN0cyhRdWVyeVByb3AoUF9BUk1PVVJTKSwiRG9VbndlYXIiLE1fTk9DSEVDSywwKTsKKyAgfQorCisgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKSB7CisgICAgICBTZXQoIFBfREVBRFMsIFF1ZXJ5KFBfREVBRFMpICsgMSApOworICAgICAgLy8gU3BpZWxlci1Ub2QtZXZlbnQgYXVzbG9lc2VuCisgICAgICBFVkVOVEQtPlRyaWdnZXJFdmVudChFVlRfTElCX1BMQVlFUl9ERUFUSCwgKFsKKyAgICAgIEVfT0JKRUNUOiBNRSwgRV9QTE5BTUU6IGdldHVpZChNRSksCisgICAgICBFX0VOVklST05NRU5UOiBlbnZpcm9ubWVudCgpLCBFX1RJTUU6IHRpbWUoKSwKKyAgICAgIFBfS0lMTEVSOiBRdWVyeVByb3AoUF9LSUxMRVIpLAorICAgICAgUF9MQVNUX0RBTUFHRTogUXVlcnlQcm9wKFBfTEFTVF9EQU1BR0UpLAorICAgICAgUF9MQVNUX0RBTVRZUEVTOiBjb3B5KFF1ZXJ5UHJvcChQX0xBU1RfREFNVFlQRVMpKSwKKyAgICAgIEVfRVhURVJOQUxfREVBVEg6IGV4dGVybiwKKyAgICAgIEVfUE9JU09OX0RFQVRIOiBwb2lzb25kZWF0aCwgCisgICAgICBFX0NPUlBTRTogKG9iamVjdHAoY29ycHNlKT9jb3Jwc2U6MCkgXSkgKTsKKyAgfQorICBlbHNlIHsKKyAgICAgIC8vIE5QQy1Ub2Rlcy1FdmVudCBhdXNsb2VzZW4uIERpdi4gTWFwcGluZ3MvQXJyYXlzIHdlcmRlbiBuaWNodCBrb3BpZXJ0LAorICAgICAgLy8gd2VpbCBkZXIgTlBDIGphIGpldHp0IGVoIHplcnN0b2VydCB3aXJkLgorICAgICAgbWFwcGluZyBkYXRhID0gKFsKKyAgICAgICAgICAgIEVfT0JOQU1FOiBvYmplY3RfbmFtZShNRSksCisgICAgICAgICAgICBFX0VOVklST05NRU5UOiBlbnZpcm9ubWVudCgpLCBFX1RJTUU6IHRpbWUoKSwKKyAgICAgICAgICAgIFBfTkFNRTogUXVlcnlQcm9wKFBfTkFNRSksCisgICAgICAgICAgICBQX0tJTExFUjogUXVlcnlQcm9wKFBfS0lMTEVSKSwKKyAgICAgICAgICAgIFBfRU5FTVlfREFNQUdFOiBRdWVyeVByb3AoUF9FTkVNWV9EQU1BR0UpLAorICAgICAgICAgICAgUF9MQVNUX0RBTUFHRTogUXVlcnlQcm9wKFBfTEFTVF9EQU1BR0UpLAorICAgICAgICAgICAgUF9MQVNUX0RBTVRZUEVTOiBRdWVyeVByb3AoUF9MQVNUX0RBTVRZUEVTKSwKKyAgICAgICAgICAgIEVfRVhURVJOQUxfREVBVEg6IGV4dGVybiwKKyAgICAgICAgICAgIEVfUE9JU09OX0RFQVRIOiBwb2lzb25kZWF0aCwKKyAgICAgICAgICAgIEVfQ09SUFNFOiAob2JqZWN0cChjb3Jwc2UpP2NvcnBzZTowKSwKKyAgICAgICAgICAgIFBfWFA6IFF1ZXJ5UHJvcChQX1hQKSwKKyAgICAgICAgICAgIFBfQVRUUklCVVRFUzogUXVlcnlQcm9wKFBfQVRUUklCVVRFUyksCisgICAgICAgICAgICBQX01BWF9IUDogUXVlcnlQcm9wKFBfTUFYX0hQKSwKKyAgICAgICAgICAgIFBfSEFORFM6IFF1ZXJ5UHJvcChQX0hBTkRTKSwKKyAgICAgICAgICAgIFBfQUxJR046IFF1ZXJ5UHJvcChQX0FMSUdOKSwKKyAgICAgICAgICAgIFBfUkFDRTogUXVlcnlQcm9wKFBfUkFDRSksCisgICAgICAgICAgICBQX0NMQVNTOiBRdWVyeVByb3AoUF9DTEFTUyksCisgICAgICAgICAgICBdKTsKKyAgICAgIEVWRU5URC0+VHJpZ2dlckV2ZW50KEVWVF9MSUJfTlBDX0RFQVRIKCIiKSwgZGF0YSk7CisgICAgICBFVkVOVEQtPlRyaWdnZXJFdmVudCgKKyAgICAgICAgICBFVlRfTElCX05QQ19ERUFUSChsb2FkX25hbWUoTUUpKSwgZGF0YSk7CisgIH0KKworICAvLyB0cmFuc2Zlcl9hbGxfdG8oKSBpc3QgZXZ0bC4gKHdlbm4genV2aWVsZSBPYmpla3RlIGJld2VndCB3ZXJkZW4gbXVzc3RlbikKKyAgLy8gbm9jaCBuaWNodCBnYW56IGZlcnRpZyB1bmQgd2lyZCBwZXIgY2FsbF9vdXQoKSBkZW4gUmVzdCBlcmxlZGlnZW4uCisgIC8vIFNvbGx0ZSBkaWUgTGVpY2hlIGRhbm4gbmljaHQgbWVociBleGlzdGllcmVuLCB2ZXJibGVpYmVuIGRpZSByZXN0bGljaGVuCisgIC8vIE9iamVrdGUgaW0gU3BpZWxlci4KKyAgLy8gRXMgYmxlaWJlbiBhYmVyIGF1ZiBqZWRlbiBGYWxsIG5vY2ggcnVuZCAzMDBrIEV2YWwtVGlja3MgdWViZXIsIGRhbWl0CisgIC8vIGtlaW4gU3BpZWxlciBkYW5rICJldmFsY29zdCB0b28gaGlnaCIgdW5nZXNjaG9yZW4gZGF2b24ga29tbXQuCisgIGlmICggIShzZWNvbmRfbGlmZShjb3Jwc2UpKSApCisgIHsKKyAgICAgIFNldCggUF9HSE9TVCwgMSApOyAvLyBGdWVyIGtvcnJla3RlIEF1c2dhYmUgYXVmIFRlYW1rYW5hbC4KKworICAgICAgaWYgKCBmaW5kX2NhbGxfb3V0KCMnX3RyYW5zZmVyKSA9PSAtMSApCisgICAgICAgICAgLy8gRmFsbHMga2VpbiBjYWxsX291dCgpIG1laHIgbGFldWZ0LCBzb2ZvcnQgZGVzdHJ1Y3RlbiAuLi4KKyAgICAgICAgICByZW1vdmUoKTsKKyAgICAgIGVsc2UKKyAgICAgICAgICAvLyAuLi4gYW5zb25zdGVuIHZvcm1lcmtlbgorICAgICAgICAgIHJlbW92ZV9tZSA9IDE7CisgIH0KK30KKworcHVibGljIHZvaWQgaGVhbF9zZWxmKGludCBoKQoreworICBpZiAoIGg8PTAgKQorICAgIHJldHVybjsKKyAgU2V0UHJvcChQX0hQLCBRdWVyeVByb3AoUF9IUCkraCk7CisgIFNldFByb3AoUF9TUCwgUXVlcnlQcm9wKFBfU1ApK2gpOworfQorCisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIGludCBkZWZ1ZWxfZm9vZCggLyogdm9pZCAqLyApCisvLworLy8gICBFbnR0YW5rdCBkZW4gU3BpZWxlciB1bSBlaW5lbiBnZXdpc3NlbiBFc3NlbnMtV2VydC4KKy8vICAgU29sbHRlIG51ciB2b24gVG9pbGV0dGVuIGF1ZmdlcnVmZW4gd2VyZGVuLgorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3B1YmxpYyBpbnQgZGVmdWVsX2Zvb2QoKQoreworICBpbnQgZm9vZDsKKworICBmb29kPVF1ZXJ5UHJvcChQX0ZPT0QpOworCisvLyB3ZW5uIHNwaWVsZXIga2VpbiBmb29kIGhhdDogcmV0dXJuIDAKKyAgaWYgKCAhZm9vZCApCisgICByZXR1cm4gTk9fREVGVUVMOworCisvLyB3ZW5uIHNwaWVsZXIgdW50ZXIgZW50dGFuay1ncmVuemU6IHJldHVybiAtMQorICBpZiAoIGZvb2QgPCBRdWVyeVByb3AoUF9ERUZVRUxfTElNSVRfRk9PRCkgKQorICAgcmV0dXJuIERFRlVFTF9UT09fTE9XOworCisvLyB3ZW5uIGxldHp0ZXMgZW50dGFua2VuIG5pY2h0IGxhbmdlIGdlbnVnIHp1cnVlY2tsaWVndDogcmV0dXJuIC0yCisgIGlmICggdGltZSgpIDwgbmV4dGRlZnVlbHRpbWVmb29kICkKKyAgIHJldHVybiBERUZVRUxfVE9PX1NPT047CisKKyAgZm9vZD10b19pbnQoKChmb29kKlF1ZXJ5UHJvcChQX0RFRlVFTF9BTU9VTlRfRk9PRCkpLzIpKTsKKyAgZm9vZCs9cmFuZG9tKGZvb2QpOworCisvLyBzaWNoZXJoZWl0c2hhbGJlcgorICBpZiAoIGZvb2QgPiBRdWVyeVByb3AoUF9GT09EKSApCisgICBmb29kPVF1ZXJ5UHJvcChQX0ZPT0QpOworCisgIFNldFByb3AoUF9GT09ELChRdWVyeVByb3AoUF9GT09EKS1mb29kKSk7CisKKyAgbmV4dGRlZnVlbHRpbWVmb29kPXRpbWUoKStRdWVyeVByb3AoUF9ERUZVRUxfVElNRV9GT09EKTsKKworICByZXR1cm4gZm9vZDsKK30KKworCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLworLy8gICBpbnQgZGVmdWVsX2RyaW5rKCAvKiB2b2lkICovICkKKy8vCisvLyAgIEVudHRhbmt0IGRlbiBTcGllbGVyIHVtIGVpbmVuIGdld2lzc2VuIEZsdWVzc2lna2VpdHMtV2VydC4KKy8vICAgR2xlaWNoemVpdGlnIHdpcmQgZWluZSBnZXdpc3NlIE1lbmdlIEFsa29ob2wgcmVkdXppZXJ0LgorLy8gICBTb2xsdGUgbnVyIHZvbiBUb2lsZXR0ZW4gYXVmZ2VydWZlbiB3ZXJkZW4uCisvLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorcHVibGljIGludCBkZWZ1ZWxfZHJpbmsoKQoreworICBpbnQgYWxjLCBkcmluazsKKworICBkcmluaz1RdWVyeVByb3AoUF9EUklOSyk7CisKKy8vIHdlbm4gc3BpZWxlciBrZWluIGRyaW5rIGhhdDogcmV0dXJuIDAKKyAgaWYgKCAhZHJpbmsgKQorICAgcmV0dXJuIE5PX0RFRlVFTDsKKworLy8gd2VubiBzcGllbGVyIHVudGVyIGVudHRhbmstZ3JlbnplOiByZXR1cm4gLTEKKyAgaWYgKCBkcmluayA8IFF1ZXJ5UHJvcChQX0RFRlVFTF9MSU1JVF9EUklOSykgKQorICAgcmV0dXJuIERFRlVFTF9UT09fTE9XOworCisvLyB3ZW5uIGxldHp0ZXMgZW50dGFua2VuIG5pY2h0IGxhbmdlIGdlbnVnIHp1cnVlY2tsaWVndDogcmV0dXJuIC0yCisgIGlmICggdGltZSgpIDwgbmV4dGRlZnVlbHRpbWVkcmluayApCisgICByZXR1cm4gREVGVUVMX1RPT19TT09OOworICAgIAorICBkcmluaz10b19pbnQoKChkcmluaypRdWVyeVByb3AoUF9ERUZVRUxfQU1PVU5UX0RSSU5LKSkvMikpOworICBkcmluays9cmFuZG9tKGRyaW5rKTsKKworLy8gc2ljaGVyaGVpdHNoYWxiZXIKKyAgaWYgKCBkcmluayA+IFF1ZXJ5UHJvcChQX0RSSU5LKSApCisgICBkcmluaz1RdWVyeVByb3AoUF9EUklOSyk7CisKKyAgU2V0UHJvcChQX0RSSU5LLChRdWVyeVByb3AoUF9EUklOSyktZHJpbmspKTsKKworLy8gamVkZXMgZmx1ZXNzaWdlIEVudHRhbmtlbiBtYWNodCBhdWNoIGV0d2FzIG51ZWNodGVybmVyIDpeKQorLy8gYmVpIHNlaHIga2xlaW5lbiBNZW5nZW4gZW50dGFua3QgbWFuIGtlaW5lbiBBbGtvaG9sCisvLyBhbnNvbnN0ZW4gaW4gQWJoYWVuZ2lna2VpdCB2b24gZW50dGFua3RlciBNZW5nZSwgUF9BTENPSE9MIHVuZCBQX1dFSUdIVAorCisgIGlmICggZHJpbmsgPiA5ICYmIFF1ZXJ5UHJvcChQX0FMQ09IT0wpID4gMCApCisgICB7CisgICAgYWxjPSh0b19pbnQoZXhwKGxvZygxLjEpKihkcmluaykpKSoKKyAgICAgICAgIHRvX2ludChleHAobG9nKDAuNjcpKihRdWVyeVByb3AoUF9BTENPSE9MKSkpKSkvCisgICAgICAgICAoUXVlcnlQcm9wKFBfTUFYX0RSSU5LKSpRdWVyeVByb3AoUF9NQVhfQUxDT0hPTCkpKgorICAgICAgICAgKHRvX2ludChRdWVyeVByb3AoUF9XRUlHSFQpLzEwMDApKTsKKworICAgICBTZXRQcm9wKFBfQUxDT0hPTCxRdWVyeVByb3AoUF9BTENPSE9MKS0oYWxjK3JhbmRvbShhbGMpKSk7CisgICB9CisKKyAgbmV4dGRlZnVlbHRpbWVkcmluaz10aW1lKCkrUXVlcnlQcm9wKFBfREVGVUVMX1RJTUVfRFJJTkspOworIAorICByZXR1cm4gZHJpbms7Cit9CisKKworcHVibGljIHZvaWQgcmVkdWNlX3NwZWxsX3BvaW50cyhpbnQgaCkKK3sKKyAgU2V0UHJvcChQX1NQLCBRdWVyeVByb3AoUF9TUCktaCk7Cit9CisKK3B1YmxpYyB2b2lkIHJlc3RvcmVfc3BlbGxfcG9pbnRzKGludCBoKQoreworICBTZXRQcm9wKFBfU1AsIFF1ZXJ5UHJvcChQX1NQKStoKTsKK30KKworLyogUmVkdWNlIGhpdHBvaW50cy4gTG9nIHdobyBpcyBkb2luZyBpdC4gKi8KK3B1YmxpYyBpbnQgcmVkdWNlX2hpdF9wb2ludHMoaW50IGRhbSkKK3sgb2JqZWN0IG87CisgIGludCBpOworCisjaWZkZWYgTE9HX1JFRFVDRV9IUAorICBpZiAodGhpc19wbGF5ZXIoKSE9TUUpCisgIHsKKyAgICBsb2dfZmlsZSgiUkVEVUNFX0hQIiwgbmFtZSgpKyIgYnkgIik7CisgICAgaWYoIXRoaXNfcGxheWVyKCkpIGxvZ19maWxlKCJSRURVQ0VfSFAiLCI/XG4iKTsKKyAgICBlbHNlIHsKKyAgICAgIGxvZ19maWxlKCJSRURVQ0VfSFAiLHRoaXNfcGxheWVyKCktPm5hbWUoKSk7CisgICAgICBvPXByZXZpb3VzX29iamVjdCgpOworICAgICAgaWYgKG8pCisgICAgICAgIGxvZ19maWxlKCJSRURVQ0VfSFAiLCAiICIgKyBvYmplY3RfbmFtZShvKSArICIsICIgKworICAgICAgICAgICAgICAgICBvLT5uYW1lKFdFUiwwKSArICIgKCIgKyBjcmVhdG9yKG8pICsgIilcbiIpOworICAgICAgZWxzZQorICAgICAgICBsb2dfZmlsZSgiUkVEVUNFX0hQIiwgIiA/P1xuIik7CisgICAgfQorICB9CisjZW5kaWYKKyAgaWYgKChpPVF1ZXJ5UHJvcChQX0hQKSkgPD0gZGFtKQorICAgIHJldHVybiBTZXRQcm9wKFBfSFAsMSk7CisgIHJldHVybiBTZXRQcm9wKFBfSFAsIGkgLSBkYW0pOworfQorCitwdWJsaWMgaW50IHJlc3RvcmVfaGl0X3BvaW50cyhpbnQgaGVhbCkKK3sKKyAgcmV0dXJuIHJlZHVjZV9oaXRfcG9pbnRzKC1oZWFsKTsKK30KKworcHVibGljIHZhcmFyZ3MgaW50IGRyaW5rX2FsY29ob2woaW50IHN0cmVuZ3RoLGludCB0ZXN0b25seSwgc3RyaW5nIG15dGV4dCkKK3sgaW50IGFsYyxhZGQscmVzOworCisgIGFkZD1BTENPSE9MX1ZBTFVFKHN0cmVuZ3RoKTsKKyAgcmVzPVVzZVNraWxsKFNLX0JPT1pFLChbCisgICAgICBTSV9TS0lMTEFSRyA6IGFkZCwKKyAgICAgIFNJX1RFU1RGTEFHIDogMV0pKTsgLy8gS2FubiBkZXIgU3BpZWxlciBndXQgc2F1ZmVuPworICBpZiAoaW50cChyZXMpICYmIHJlcz4wKSBhZGQ9cmVzOworICBhbGM9UXVlcnlQcm9wKFBfQUxDT0hPTCkrYWRkOworICBpZiAoKGFsYyA+PSBRdWVyeVByb3AoUF9NQVhfQUxDT0hPTCkpICYmICFJU19MRUFSTklORyh0aGlzX29iamVjdCgpKSl7CisgICAgaWYoIXRlc3Rvbmx5KQorICAgICAgdGVsbF9vYmplY3QoTUUsbXl0ZXh0fHwiU28gZWluIFBlY2gsIER1IGhhc3QgYWxsZXMgdmVyc2NodWV0dGV0LlxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYodGVzdG9ubHkpcmV0dXJuIDE7CisgIFVzZVNraWxsKFNLX0JPT1pFLChbIFNJX1NLSUxMQVJHIDogQUxDT0hPTF9WQUxVRShzdHJlbmd0aCkgXSkpOworICBpZihhbGMgPCAwKSBhbGMgPSAwOworICBpZighYWxjKSB0ZWxsX29iamVjdChNRSwgIkR1IGJpc3Qgc3RvY2tudWVjaHRlcm4uXG4iKTsKKyAgU2V0UHJvcChQX0FMQ09IT0wsIGFsYyk7CisgIHJldHVybiAxOworfQorCitwdWJsaWMgdmFyYXJncyBpbnQgZHJpbmtfc29mdChpbnQgc3RyZW5ndGgsIGludCB0ZXN0b25seSwgc3RyaW5nIG15dGV4dCkKK3sgaW50IHNvYWtlZDsKKworICBzb2FrZWQgPSBRdWVyeVByb3AoUF9EUklOSyk7CisgIGlmKChzb2FrZWQgKyBzdHJlbmd0aCA+IFF1ZXJ5UHJvcChQX01BWF9EUklOSykpICYmCisgICAgICFJU19MRUFSTklORyh0aGlzX29iamVjdCgpKSl7CisgICAgaWYoIXRlc3Rvbmx5KQorICAgICB0ZWxsX29iamVjdChNRSwgbXl0ZXh0fHwKKyAgICAgICAiTmVlLCBzbyB2aWVsIGthbm5zdCBEdSBtb21lbnRhbiBlY2h0IG5pY2h0IHRyaW5rZW4uXG4iICk7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYodGVzdG9ubHkpcmV0dXJuIDE7CisgIGlmKChzb2FrZWQgKz0gRFJJTktfVkFMVUUoc3RyZW5ndGgpKSA8IDApIHNvYWtlZCA9IDA7CisgIGlmKCFzb2FrZWQpIHRlbGxfb2JqZWN0KE1FLCAiRGlyIGtsZWJ0IGRpZSBadW5nZSBhbSBHYXVtZW4uXG4iKTsKKyAgU2V0UHJvcChQX0RSSU5LLCBzb2FrZWQpOworICByZXR1cm4gMTsKK30KKworcHVibGljIHZhcmFyZ3MgaW50IGVhdF9mb29kKGludCBzdHJlbmd0aCwgaW50IHRlc3Rvbmx5LCBzdHJpbmcgbXl0ZXh0KQoreyBpbnQgc3R1ZmZlZDsKKworICBzdHVmZmVkID0gUXVlcnlQcm9wKFBfRk9PRCk7CisgIGlmICgoc3R1ZmZlZCArIHN0cmVuZ3RoID4gUXVlcnlQcm9wKFBfTUFYX0ZPT0QpKSAmJgorICAgICAgIUlTX0xFQVJOSU5HKHRoaXNfb2JqZWN0KCkpKQorICB7CisgICAgaWYoIXRlc3Rvbmx5KQorICAgICAgICB0ZWxsX29iamVjdChNRSwKKyAgICAgICAgICAgIG15dGV4dCB8fCAiRGFzIGlzdCB2aWVsIHp1IHZpZWwgZnVlciBEaWNoISBXaWUgd2FlcnMgbWl0IGV0d2FzICIKKyAgICAgICAgICAgICJsZWljaHRlcmVtP1xuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYodGVzdG9ubHkpcmV0dXJuIDE7CisgIHN0dWZmZWQgKz0gRk9PRF9WQUxVRShzdHJlbmd0aCk7CisgIGlmKHN0dWZmZWQgPCAwKSBzdHVmZmVkID0gMDsKKyAgaWYoIXN0dWZmZWQpIHRlbGxfb2JqZWN0KE1FLCAiV2FzIHJ1bXBlbHQgZGVubiBkYSBpbiBEZWluZW0gQmF1Y2g/XG4iKTsKKyAgU2V0UHJvcChQX0ZPT0QsIHN0dWZmZWQpOworICByZXR1cm4gMTsKK30KKworcHVibGljIGludCBidWZmZXJfaHAoaW50IHZhbCxpbnQgcmF0ZSkKK3sKKyAgaW50IGRpZjsKKworICBpZih2YWw8PTAgfHwgcmF0ZTw9MClyZXR1cm4gMDsKKyAgaWYodmFsIDwgcmF0ZSlyYXRlID0gdmFsOworICBpZihyYXRlPjIwKSByYXRlPTIwOworCisgIC8qIENoZWNrIGZvciBCdWZmZXJPdmVyZmxvdyAqLworICBpZigoZGlmPShocF9idWZmZXJbMF0rdmFsKS1RdWVyeVByb3AoUF9NQVhfSFApKSA+IDApdmFsLT1kaWY7CisgIGlmKHZhbDw9MClyZXR1cm4gMDsKKworICBocF9idWZmZXJbMF0gKz0gdmFsOworICBocF9idWZmZXJbMStyYXRlXSArPSB2YWw7CisgIGlmKHJhdGUgPiBocF9idWZmZXJbMV0paHBfYnVmZmVyWzFdID0gcmF0ZTsKKworICByZXR1cm4gaHBfYnVmZmVyWzBdOworfQorCitwdWJsaWMgaW50IGJ1ZmZlcl9zcChpbnQgdmFsLGludCByYXRlKQoreworICBpbnQgZGlmOworCisgIGlmKHZhbDw9MCB8fCByYXRlPD0wKXJldHVybiAwOworICBpZih2YWwgPCByYXRlKXJhdGUgPSB2YWw7CisgIGlmKHJhdGU+MjApIHJhdGU9MjA7CisKKyAgLyogQ2hlY2sgZm9yIEJ1ZmZlck92ZXJmbG93ICovCisgIGlmKChkaWY9KHNwX2J1ZmZlclswXSt2YWwpLVF1ZXJ5UHJvcChQX01BWF9TUCkpID4gMCl2YWwtPWRpZjsKKyAgaWYodmFsPD0wKXJldHVybiAwOworCisgIHNwX2J1ZmZlclswXSArPSB2YWw7CisgIHNwX2J1ZmZlclsxK3JhdGVdICs9IHZhbDsKKyAgaWYocmF0ZSA+IHNwX2J1ZmZlclsxXSlzcF9idWZmZXJbMV0gPSByYXRlOworCisgIHJldHVybiBzcF9idWZmZXJbMF07Cit9CisKK3Byb3RlY3RlZCB2b2lkIHVwZGF0ZV9idWZmZXJzKCkKK3sgaW50IGksIHJhdGUsIG1heDsKKworICByYXRlPTA7CisgIG1heD0wOworICBmb3IoaT0xO2k8PTIwO2krKyl7CisgICAgaWYobWVtYmVyKGhwX2J1ZmZlciwgaSsxKSkKKyAgICAgIGlmKGhwX2J1ZmZlcltpKzFdPD0wKQorICAgICAgICBocF9idWZmZXIgPSBtX2RlbGV0ZShocF9idWZmZXIsaSsxKTsKKyAgICAgIGVsc2V7CisgICAgICAgIG1heCs9aHBfYnVmZmVyW2krMV07CisgICAgICAgIHJhdGU9aTsKKyAgICAgIH0KKyAgfQorCisgIGhwX2J1ZmZlclswXT1tYXg7CisgIGhwX2J1ZmZlclsxXT1yYXRlOworICByYXRlPTA7CisgIG1heD0wOworICBmb3IoaT0xO2k8PTIwO2krKyl7CisgICAgaWYobWVtYmVyKHNwX2J1ZmZlciwgaSsxKSkKKyAgICAgIGlmKHNwX2J1ZmZlcltpKzFdPD0wKQorICAgICAgICBzcF9idWZmZXIgPSBtX2RlbGV0ZShzcF9idWZmZXIsaSsxKTsKKyAgICAgIGVsc2V7CisgICAgICAgIG1heCs9c3BfYnVmZmVyW2krMV07CisgICAgICAgIHJhdGU9aTsKKyAgICAgIH0KKyAgfQorICBzcF9idWZmZXJbMF09bWF4OworICBzcF9idWZmZXJbMV09cmF0ZTsKK30KKworcHVibGljIGludCBjaGVja190aW1lZF9rZXkoc3RyaW5nIGtleSkgeworCisgIC8vIGtlaW5lIDAgYWxzIGtleSAoVHlwIHdpcmQgcGVyIFJUVEMgZ2VwcnVlZnQpCisgIGlmICgha2V5KQorICAgIHJldHVybiAwOworICBtYXBwaW5nIHRtYXA9UXVlcnkoUF9USU1JTkdfTUFQLCBGX1ZBTFVFKTsKKyAgaWYgKCFtYXBwaW5ncCh0bWFwKSkgeworICAgIHRtYXA9KFtdKTsKKyAgICBTZXQoUF9USU1JTkdfTUFQLCB0bWFwLCBGX1ZBTFVFKTsKKyAgfQorICAvLyBXZW5uIGtleSBub2NoIG5pY2h0IGFiZ2VsYXVmZW4sIEFibGF1ZnplaXRwdW5rdCB6dXJ1ZWNrZ2ViZW4uCisgIC8vIFNvbnN0IDAgKGtleSBmcmVpKQorICByZXR1cm4gKHRpbWUoKSA8IHRtYXBba2V5XSkgJiYgdG1hcFtrZXldOworfQorCitwdWJsaWMgaW50IGNoZWNrX2FuZF91cGRhdGVfdGltZWRfa2V5KGludCBkdXJhdGlvbixzdHJpbmcga2V5KSB7CisKKyAgLy8gd2VubiBrZXkgbm9jaCBnZXNwZXJydCwgZGllIHplaXQgZGVyIG5hZWNoc3RlbiBWZXJmdWVnYmFya2VpdAorICAvLyB6dXJ1ZWNrZ2ViZW4uCisgIGludCByZXMgPSBjaGVja190aW1lZF9rZXkoa2V5KTsKKyAgaWYgKHJlcykgeworICAgIHJldHVybiByZXM7CisgIH0KKworICAvLyBkdXJhdGlvbiA8PSAwIGlzdCB1bnNpbm5pZy4gQWJlciBrZXkgaXN0IG5pY2h0IG1laHIgZ2VzcGVycnQsIGQuaC4gdGltZSgpCisgIC8vIGlzdCBlaW4gc2lubnZvbGxlciBSdWVja2dhYmV3ZXJ0LgorICBpZiAoZHVyYXRpb24gPD0gMCkKKyAgICByZXR1cm4gdGltZSgpOworIAorICBtYXBwaW5nIHRtYXAgPSBRdWVyeShQX1RJTUlOR19NQVAsRl9WQUxVRSk7CisgIHRtYXBba2V5XT10aW1lKCkrZHVyYXRpb247CisgIAorICAvLyBzcGVpY2hlcm4gcGVyIFNldFByb3AoKSB1bm5vZXRpZywgZGEgbWFuIGRhcyBNYXBwaW5nIGRpcmVrdCBhZW5kZXJ0LAorICAvLyBrZWluZSBLb3BpZS4KKyAgLy9TZXRQcm9wKFBfVElNSU5HX01BUCwgdG1hcCk7CisgIAorICByZXR1cm4gLTE7IC8vIEVyZm9sZy4KK30KKworcHJvdGVjdGVkIHZvaWQgZXhwaXJlX3RpbWluZ19tYXAoKSB7CisgIAorICBtYXBwaW5nIHRtYXAgPSBRdWVyeShQX1RJTUlOR19NQVAsIEZfVkFMVUUpOworICBpZiAoIW1hcHBpbmdwKHRtYXApIHx8ICFzaXplb2YodG1hcCkpCisgICAgcmV0dXJuOworICBmb3JlYWNoKHN0cmluZyBrZXksIGludCBlbmR0aW1lOiB0bWFwKSB7CisgICAgaWYgKGVuZHRpbWUgPCB0aW1lKCkpCisgICAgICBtX2RlbGV0ZSh0bWFwLCBrZXkpOworICB9CisgIC8vIHNwZWljaGVybiBwZXIgU2V0UHJvcCgpIHVubm9ldGlnLCBkYSBtYW4gZGFzIE1hcHBpbmcgZGlyZWt0IGFlbmRlcnQsCisgIC8vIGtlaW5lIEtvcGllLgorfQorCitwcm90ZWN0ZWQgdm9pZCBoZWFydF9iZWF0KCkKK3sKKyAgICBpZiAoICF0aGlzX29iamVjdCgpICkKKyAgICAgICAgcmV0dXJuOworCisgICAgYXR0cmlidXRlX2hiKCk7CisKKyAgICAvLyBBbHMgR2Vpc3QgbGVpZGV0IG1hbiBuaWNodCB1bnRlciBzbyB3ZWx0bGljaGVuIERpbmdlbiB3aWUKKyAgICAvLyBBbGtvaG9sLCBHaWZ0JkNvIC4uLgorICAgIGlmICggUXVlcnlQcm9wKFBfR0hPU1QpICkKKyAgICAgICAgcmV0dXJuOworCisgICAgaW50IGhwb2lzb24gPSBRdWVyeVByb3AoUF9QT0lTT04pOworICAgIGludCBybG9jayA9IFF1ZXJ5UHJvcChQX05PX1JFR0VORVJBVElPTik7CisgICAgaW50IGhwID0gUXVlcnlQcm9wKFBfSFApOworICAgIGludCBzcCA9IFF1ZXJ5UHJvcChQX1NQKTsKKyAgICBpbnQgYWxjOworCisgICAgLy8gV2VubiBBbGtvaG9sIGdldHJ1bmtlbjogQWxrb2hvbGF1c3dpcmt1bmdlbj8KKyAgICBpZiAoIChhbGMgPSBRdWVyeVByb3AoUF9BTENPSE9MKSkgJiYgIXJhbmRvbSg0MCkgKXsKKyAgICAgICAgaW50IG47CisgICAgICAgIHN0cmluZyBnaWxkZTsKKyAgICAgICAgb2JqZWN0IG9iOworCisgICAgICAgIG4gPSByYW5kb20oIDUgKiAoYWxjIC0gMSkvUXVlcnlQcm9wKFBfTUFYX0FMQ09IT0wpICk7CisKKyAgICAgICAgc3dpdGNoIChuKXsKKyAgICAgICAgY2FzZSBBTENfRUZGRUNUX0hJQ0s6CisgICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZSggV0VSLCAxICkpICsgIiBzYWd0OiA8SGljaz4hXG4iICk7CisgICAgICAgICAgICB3cml0ZSggIjxIaWNrPiEgT2gsIFRzY2h1bGRpZ3VuZy5cbiIgKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgCisgICAgICAgIGNhc2UgQUxDX0VGRkVDVF9TVFVNQkxFOgorICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoIFdFUiwgMSApKSArICIgc3RvbHBlcnQgdWViZXIgIiArCisgICAgICAgICAgICAgICAgIFF1ZXJ5UG9zc1Byb25vdW4oIEZFTUFMRSwgV0VOICkgKyAiIEZ1ZXNzZS5cbiIgKTsKKyAgICAgICAgICAgIHdyaXRlKCAiRHUgc3RvbHBlcnN0LlxuIiApOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAKKyAgICAgICAgY2FzZSBBTENfRUZGRUNUX0xPT0tEUlVOSzoKKyAgICAgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKCBXRVIsIDEgKSkgKyAiIHNpZWh0IGJldHJ1bmtlbiBhdXMuXG4iICk7CisgICAgICAgICAgICB3cml0ZSggIkR1IGZ1ZWhsc3QgRGljaCBiZW5vbW1lbi5cbiIgKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgCisgICAgICAgIGNhc2UgQUxDX0VGRkVDVF9SVUVMUFM6CisgICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZSggV0VSLCAxICkpICsgIiBydWVscHN0LlxuIiApOworICAgICAgICAgICAgd3JpdGUoICJEdSBydWVscHN0LlxuIiApOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAKKyAgICAgICAgLy8gR2lsZGUgdW5kIEVudmlyb25tZW50IGluZm9ybWllcmVuIHVlYmVyIEFsa29ob2xhdXN3aXJrdW5nLgorICAgICAgICBpZiAoIHN0cmluZ3AoZ2lsZGUgPSBRdWVyeVByb3AoUF9HVUlMRCkpCisgICAgICAgICAgICAgJiYgb2JqZWN0cChvYiA9IGZpbmRfb2JqZWN0KCAiL2dpbGRlbi8iICsgZ2lsZGUgKSkgKQorICAgICAgICAgICAgb2ItPkluZm9ybUFsY29ob2xFZmZlY3QoIE1FLCBuLCBBTENfRUZGRUNUX0FSRUFfR1VJTEQgKTsKKyAgICAgICAgCisgICAgICAgIGlmICggZW52aXJvbm1lbnQoKSApCisgICAgICAgICAgICBlbnZpcm9ubWVudCgpLT5JbmZvcm1BbGNvaG9sRWZmZWN0KCBNRSwgbiwgQUxDX0VGRkVDVF9BUkVBX0VOViApOworICAgIH0KKyAgICAKKyAgICAvLyBBbGtvaG9sIGFiYmF1ZW4gdW5kIGV0d2FzIGV4dHJhIGhlaWxlbiwgZmFsbHMgZXJsYXVidC4KKyAgICBpZiAoIGFsYyAmJiAoLS1kZWxheV9hbGNvaG9sIDwgMCkKKyAgICAgICAgICYmICEocmxvY2sgJiBOT19SRUdfQUxDT0hPTCkgKXsKKworICAgICAgICBTZXRQcm9wKCBQX0FMQ09IT0wsIGFsYyAtIDEgKTsKKyAgICAgICAgCisgICAgICAgIGlmICggIWhwb2lzb24gKXsKKyAgICAgICAgICAgIGhwKys7CisgICAgICAgICAgICBzcCsrOworICAgICAgICB9CisgICAgICAgIAorICAgICAgICBkZWxheV9hbGNvaG9sID0gUXVlcnlQcm9wKFBfQUxDT0hPTF9ERUxBWSk7CisgICAgfQorCisgICAgLy8gUF9EUklOSyByZWR1emllcmVuLCBmYWxscyBlcmxhdWJ0LgorICAgIGlmICggKC0tZGVsYXlfZHJpbmsgPCAwKSAmJiAhKHJsb2NrICYgTk9fUkVHX0RSSU5LKSApeworICAgICAgICBkZWxheV9kcmluayA9IFF1ZXJ5UHJvcChQX0RSSU5LX0RFTEFZKTsKKyAgICAgICAgU2V0UHJvcCggUF9EUklOSywgUXVlcnlQcm9wKFBfRFJJTkspIC0gMSApOworICAgIH0KKworICAgIC8vIFBfRk9PRCByZWR1emllcmVuLCBmYWxscyBlcmxhdWJ0LgorICAgIGlmICggKC0tZGVsYXlfZm9vZCA8IDApICYmICEocmxvY2sgJiBOT19SRUdfRk9PRCkgKXsKKyAgICAgICAgZGVsYXlfZm9vZCA9IFF1ZXJ5UHJvcChQX0ZPT0RfREVMQVkpOworICAgICAgICBTZXRQcm9wKCBQX0ZPT0QsIFF1ZXJ5UHJvcChQX0ZPT0QpIC0gMSApOworICAgIH0KKworICAgIC8vIFJlZ2VuZXJhdGlvbiBhdXMgZGVtIEhQLVB1ZmZlcgorICAgIC8vIEhpZXJiZWkgd2lyZCB6d2FyIG51ciBnZWhlaWx0LCB3ZW5uIGRhcyBlcmxhdWJ0IGlzdCwgYWJlciBkZXIgUHVmZmVyCisgICAgLy8gbXVzcyB0cm90emRlbSBhYmdlYXJiZWl0ZXQvcmVkdXppZXJ0IHdlcmRlbiwgZGEgRGVsZmVuIHNvbnN0IGVpbmUKKyAgICAvLyBtb2JpbGUgVGFua2Uga3JpZWdlbi4gKEtlaW5lIEhlaWx1bmcgaW0gSGVsbGVuLCBQdWZmZXIgYmxlaWJ0IHNvbnN0CisgICAgLy8ga29uc3RhbnQgdW5kIGthbm4gYmVpIEJlZGFyZiB1ZWJlciBkdW5rZWxtYWNoZW5kZSBJdGVtcyBhYmdlcnVmZW4KKyAgICAvLyB3ZXJkZW4uKQorICAgIGludCB2YWw7CisgICAgaWYgKGhwX2J1ZmZlclswXSkgeworICAgICAgICBpbnQgcmF0ZSA9IGhwX2J1ZmZlclsxXTsKKyAgICAgICAgdmFsID0gaHBfYnVmZmVyW3JhdGUgKyAxXTsKKyAgICAKKyAgICAgICAgaWYgKCB2YWwgPiByYXRlICkKKyAgICAgICAgICAgIHZhbCA9IHJhdGU7CisgICAgICAgIGhwX2J1ZmZlclswXSAtPSB2YWw7CisgICAgICAgIGhwX2J1ZmZlcltyYXRlICsgMV0gLT0gdmFsOworICAgICAgICBpZiAoIGhwX2J1ZmZlcltyYXRlICsgMV0gPD0gMCApCisgICAgICAgICAgICB1cGRhdGVfYnVmZmVycygpOworICAgIH0KKyAgICAvLyBKZXR6dCBSZWdlbmVyYXRpb24gYXVzIGRlbSBQdWZmZXIgZHVyY2hmdWVocmVuLCBhYmVyIG51ciB3ZW5uIGVybGF1YnQuCisgICAgaWYgKCB2YWwgJiYgIShybG9jayAmIE5PX1JFR19CVUZGRVJfSFApICkKKyAgICAgICAgaHAgKz0gdmFsOyAKKyAgICAvLyBub3JtYWxlcyBIZWlsZW4sIGZhbGxzIGtlaW5lIFJlZ2VuZXJhdGlvbiBhdXMgZGVtIFB1ZmZlciBlcmZvbGd0ZSB1bmQKKyAgICAvLyBlcyBlcmxhdWJ0IGlzdC4KKyAgICBlbHNlIGlmICggKC0tZGVsYXlfaGVhbCA8IDApICYmICEocmxvY2sgJiBOT19SRUdfSFApICl7CisgICAgICAgIGRlbGF5X2hlYWwgPSBRdWVyeVByb3AoUF9IUF9ERUxBWSk7CisgICAgICAgIGlmICggIWhwb2lzb24gKQorICAgICAgICAgICAgaHArKzsKKyAgICB9CisKKyAgICAvLyBHbGVpY2hlcyBTcGllbCBqZXR6dCBmdWVyIGRlbiBTUC1QdWZmZXIgKHMuby4pCisgICAgdmFsPTA7CisgICAgaWYgKCBzcF9idWZmZXJbMF0gKSB7CisgICAgICAgIGludCByYXRlID0gc3BfYnVmZmVyWzFdOworICAgICAgICB2YWwgPSBzcF9idWZmZXJbcmF0ZSArIDFdOworICAgICAgICAKKyAgICAgICAgaWYgKCB2YWwgPiByYXRlICkKKyAgICAgICAgICAgIHZhbCA9IHJhdGU7CisgICAgICAgIAorICAgICAgICBzcF9idWZmZXJbMF0gLT0gdmFsOworICAgICAgICBzcF9idWZmZXJbcmF0ZSArIDFdIC09IHZhbDsKKyAKKyAgICAgICAgaWYgKCBzcF9idWZmZXJbcmF0ZSArIDFdIDw9IDAgKQorICAgICAgICAgICAgdXBkYXRlX2J1ZmZlcnMoKTsKKyAgICB9CisgICAgLy8gUmVnZW5lcmF0aW9uIGVybGF1YnQ/CisgICAgaWYgKCB2YWwgJiYgIShybG9jayAmIE5PX1JFR19CVUZGRVJfU1ApICkKKyAgICAgICAgIHNwICs9IHZhbDsKKyAgICAvLyBXZW5uIG5pY2h0LCBub3JtYWxlcyBIb2NoaWRlbG4gdmVyc3VjaGVuLgorICAgIGVsc2UgaWYgKCAoLS1kZWxheV9zcCA8IDApICYmICEocmxvY2sgJiBOT19SRUdfU1ApICl7CisgICAgICAgIGRlbGF5X3NwID0gUXVlcnlQcm9wKFBfU1BfREVMQVkpOworICAgICAgICBpZiAoICFocG9pc29uICkKKyAgICAgICAgICAgIHNwKys7CisgICAgfQorCisgICAgaWYgKCBocG9pc29uICYmIChpbnRlcmFjdGl2ZShNRSkgfHwgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpKSApeworICAgICAgICAvLyBWYW5pb24sIDI2LjEwLjAzCisgICAgICAgIC8vIFdlbm4gX3NldF9wb2lzb24oKSBwZXIgU0VUX01FVEhPRCB1ZWJlcnNjaHJpZWJlbiB3aXJkLCBrYW5uCisgICAgICAgIC8vIG5pY2h0IHNpY2hlcmdlc3RlbGx0IHdlcmRlbiwgZGFzcyBwb2lzb24gaW1tZXIgZ3JvZXNzZXIgMCBpc3QKKyAgICAgICAgLy8gRGFoZXIgbXVzcyBoaWVyIGVpbiBUZXN0IHJlaW4sIHNvIHRldWVyIGRhcyBhdWNoIGlzdCA6KAorICAgICAgICBpZiAoLS1ocG9pc29uIDwgMCkKKyAgICAgICAgICBocG9pc29uPTA7CisgICAgICAgIAorICAgICAgICBpZiAoIC0tZGVsYXlfcG9pc29uIDwgMCApeworICAgICAgICAgICAgZGVsYXlfcG9pc29uID0gUXVlcnlQcm9wKFBfUE9JU09OX0RFTEFZKQorICAgICAgICAgICAgICAgICsgcmFuZG9tKFBPSVNPTl9NRVJDWV9ERUxBWSk7CisgICAgICAgICAgICBocCAtPSBocG9pc29uOworCisgICAgICAgICAgICBpZiAoIGhwIDwgMCApeworICAgICAgICAgICAgICAgIHRlbGxfb2JqZWN0KCBNRSwgIk9oIHdlaCAtIGRhcyBHaWZ0IHdhciB6dXZpZWwgZnVlciBEaWNoIVxuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICArICJEdSBzdGlyYnN0LlxuIiApOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKXsKKyAgICAgICAgICAgICAgICAgICAgY3JlYXRlX2tpbGxfbG9nX2VudHJ5KCAiVmVyZ2lmdHVuZyIsIDAgKTsKKyAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgIC8vIEJlaW0gR2lmdHRvZCBnaWJ0IGVzIGtlaW5lbiBLaWxsZXIuIEFiZXIgYXVmIGRpZXNlIEFydAorICAgICAgICAgICAgICAgICAgICAvLyBlcmtlbm50IGRlciBUb2Rlc3JhdW0gZGllIFVyc2FjaGUga29ycmVrdCB1bmQgZ2lidCBkaWUKKyAgICAgICAgICAgICAgICAgICAgLy8gcmljaHRpZ2UgTWVsZHVuZyBhdXMuCisgICAgICAgICAgICAgICAgICAgIFNldFByb3AoIFBfS0lMTEVSLCAiZ2lmdCIgKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgZGllKDEpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIAorICAgICAgICAgICAgaWYgKCAoaHBvaXNvbiA8IDMgfHwgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICkKKyAgICAgICAgICAgICAgICAgJiYgLS1kcm9wX3BvaXNvbiA8IDApCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgLy8gR2lmdGxldmVsIGVpbnMgcmVkdXppZXJlbi4gaHBvaXNvbiB3dXJkZSBvYmVuIHNjaG9uCisgICAgICAgICAgICAgICAgLy8gcmVkdXppZXJ0LCBkLmguIGVpbmZhY2ggaHBvaXNvbiBpbiBQX1BPSVNPTiBzY2hyZWliZW4uCisgICAgICAgICAgICAgICAgLy8gZGFiZWkgd2lyZCBkYW5uIGF1Y2ggZ2dmLiBkcm9wX3BvaXNvbiByaWNodGlnIGdlc2V0enQuCisgICAgICAgICAgICAgICAgU2V0UHJvcCggUF9QT0lTT04sIGhwb2lzb24gKTsKKyAgICAgICAgICAgICAgICBpZiAoICFocG9pc29uICkKKyAgICAgICAgICAgICAgICAgICAgdGVsbF9vYmplY3QoIE1FLCAiRHUgc2NoZWluc3QgZGllIFZlcmdpZnR1bmcgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1ZWJlcnd1bmRlbiB6dSBoYWJlbi5cbiIgKTsgIAorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIAorICAgICAgICBpZiAoIGhwb2lzb24gJiYgIXJhbmRvbSgxNSkgKQorICAgICAgICAgICAgc3dpdGNoICggaHAqMTAwL1F1ZXJ5UHJvcChQX01BWF9IUCkgKXsKKyAgICAgICAgICAgIGNhc2UgNzEuLjEwMCA6CisgICAgICAgICAgICAgICAgd3JpdGUoICJEdSBmdWVobHN0IERpY2ggbmljaHQgZ3V0LlxuIiApOworICAgICAgICAgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKFdFUikpICsKKyAgICAgICAgICAgICAgICAgICAgICIgc2llaHQgZXR3YXMgYmVub21tZW4gYXVzLlxuIiApOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgY2FzZSA0Ni4uNzAgOgorICAgICAgICAgICAgICAgIHdyaXRlKCAiRGlyIGlzdCBzY2h3aW5kbGlnIHVuZCBEZWluIE1hZ2VuIHJldm9sdGllcnQuXG4iICk7CisgICAgICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoV0VSKSkgKyAiIHRhdW1lbHQgZWluIHdlbmlnLlxuIiApOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgY2FzZSAyNi4uNDUgOgorICAgICAgICAgICAgICAgIHdyaXRlKCAiRGlyIGlzdCBoZWlzcy4gRHUgZnVlaGxzdCBEaWNoIHNjaHdhY2guIEtvcGZ3ZWggIgorICAgICAgICAgICAgICAgICAgICAgICAiaGFzdCBEdSBhdWNoLlxuIiApOworICAgICAgICAgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKFdFUikpICsgIiBnbHVlaHQgZGlyZWt0IHVuZCBzY2hlaW50ICIKKyAgICAgICAgICAgICAgICAgICAgICJncm9zc2UgU2Nod2llcmlna2VpdGVuIHp1IGhhYmVuLlxuIiApOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgY2FzZSAxMS4uMjUgOgorICAgICAgICAgICAgICAgIHdyaXRlKCAiRHUgZnVlaGxzdCBEaWNoIGJlc2NoaXNzZW4uIEFsbGVzIHR1dCB3ZWgsIHVuZCBEdSAiCisgICAgICAgICAgICAgICAgICAgICAgICJzaWVoc3QgbnVyIG5vY2ggdW5zY2hhcmYuXG4iICk7CisgICAgICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoV0VSKSkgKyAiIHRhdW1lbHQgdW5kIHN0b2VobnQgdW5kICIKKyAgICAgICAgICAgICAgICAgICAgICJrYW5uIGdlcmFkZSBub2NoIHZlcm1laWRlbiwgaGluenVmYWxsZW4uXG4iICk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgCisgICAgICAgICAgICBjYXNlIDAuLjEwIDoKKyAgICAgICAgICAgICAgICB3cml0ZSggYnJlYWtfc3RyaW5nKCAiRHUgc2llaHN0IGZhc3QgbmljaHRzIG1laHIgdW5kIGthbm5zdCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkRpY2ggbnVyIG5vY2ggdW50ZXIgZ3JvZXNzdGVuIFNjaG1lcnplbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJld2VnZW4uIEFiZXIgYmFsZCB0dXQgbmljaHRzIG1laHIgd2VoIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIuLi4iLCA3OCApICk7CisgICAgICAgICAgICAgICAgc2F5KCBicmVha19zdHJpbmcoIGNhcGl0YWxpemUobmFtZShXRVIpKSArICIgZ2x1ZWh0IHdpZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbSBGaWViZXIsIGthbm4gc2ljaCBrYXVtIG5vY2ggcnVlaHJlbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmQgaGF0IGVpbiBzY2htZXJ6dmVyemVycnRlcyBHZXNpY2h0LlxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgNzggKSApOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgIH0KKworICAgIFNldFByb3AoIFBfSFAsIGhwICk7CisgICAgU2V0UHJvcCggUF9TUCwgc3AgKTsKK30KKworcHVibGljIGludCBBZGRFeHAoIGludCBlICkKK3sKKyAgaW50IGV4cGVyaWVuY2U7CisgIHN0cmluZyBmbjsKKyAgbWl4ZWQgbGFzdDsKKworICBleHBlcmllbmNlID0gUXVlcnlQcm9wKFBfWFApOworCisgIGlmICggUXVlcnlQcm9wKFBfS0lMTFMpID4gMSAmJiBlID4gMCApCisgICAgICByZXR1cm4gZXhwZXJpZW5jZTsKKworICBmbiA9IGltcGxvZGUoIGV4cGxvZGUoIG9iamVjdF9uYW1lKCBlbnZpcm9ubWVudCgpIHx8IHRoaXNfb2JqZWN0KCkgKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiLyIgKVswLi48Ml0sICIvIiApOworCisgIGlmICggcG9pbnRlcnAobGFzdCA9IFF1ZXJ5KFBfTEFTVF9YUCkpICYmIHNpemVvZihsYXN0KSA9PSAyICYmIGxhc3RbMF0gPT0gZm4gKQorICAgICAgU2V0KCBQX0xBU1RfWFAsICh7IGZuLCBsYXN0WzFdK2UgfSkgKTsKKyAgZWxzZQorICAgICAgU2V0KCBQX0xBU1RfWFAsICh7IGZuLCBlIH0pICk7CisKKyAgaWYgKCAoZXhwZXJpZW5jZSArPSBlKSA8IDAgKQorICAgICAgZXhwZXJpZW5jZSA9IDA7CisKKyAgcmV0dXJuIFNldFByb3AoIFBfWFAsIGV4cGVyaWVuY2UgKTsKK30KKworc3RhdGljIDxzdHJpbmd8aW50PiogX3NldF9sYXN0X3hwKCA8aW50fHN0cmluZz4qIGxhc3QgKQoreworICAgIGlmICggIXBvaW50ZXJwKGxhc3QpIHx8IHNpemVvZihsYXN0KSAhPSAyIHx8ICFzdHJpbmdwKGxhc3RbMF0pIHx8CisgICAgICAgICAhaW50cChsYXN0WzFdKSApCisgICAgICAgIHJldHVybiBRdWVyeShQX0xBU1RfWFApOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFNldCggUF9MQVNUX1hQLCBsYXN0ICk7Cit9CisKKworc3RhdGljIGludCBfc2V0X2FsaWduKGludCBhKQoreworICBpZiAoYTwtMTAwMCkgYSA9IC0xMDAwOworICBpZiAoYT4xMDAwKSBhID0gMTAwMDsKKyAgcmV0dXJuIFNldChQX0FMSUdOLCBhKTsKK30KKworCitzdGF0aWMgaW50IF9zZXRfaHAoIGludCBocCApCit7CisgICAgaWYgKCBRdWVyeVByb3AoUF9HSE9TVCkgKQorICAgICAgICByZXR1cm4gUXVlcnlQcm9wKFBfSFApOworCisgICAgaWYgKCBocCA8IDAgKQorICAgICAgICByZXR1cm4gU2V0KCBQX0hQLCAwICk7CisKKyAgICBpZiAoIGhwID4gUXVlcnlQcm9wKFBfTUFYX0hQKSApCisgICAgICAgIHJldHVybiBTZXQoIFBfSFAsIFF1ZXJ5UHJvcChQX01BWF9IUCksIEZfVkFMVUUgKTsKKworICAgIHJldHVybiBTZXQoIFBfSFAsIGhwLCBGX1ZBTFVFICk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9zcCggaW50IHNwICkKK3sKKyAgICAvL2VpbmlnZSBMZXV0ZSBzY2hyZWliZW4gZmxvYXRzIGluIGRpZSBQX0hQLiA6LSgKKyAgICBpZiAoIWludHAoc3ApKSB7CisJc3A9dG9faW50KHNwKTsKKwkvL2phLCBlcyBpc3QgdGV1ZXIuIEFiZXIgaWNoIHdpbGwgd2lzc2VuLCB3ZXJzIGlzdC4gS2FubiB2b3IKKwkvL25hZWNoc3RlbSBSZWJvb3Qgd2llZGVyIHJhdXMuCisJbG9nX2ZpbGUoIklMTEVHQUxfVFlQRS5sb2ciLHNwcmludGYoCisJICAgICAgIlZlcnN1Y2gsIGVpbmVuIG5pY2h0LWludCBpbiBQX1NQIGluICVPIHp1IHNjaHJlaWJlbjogXG4lT1xuIiwKKwkgICAgICB0aGlzX29iamVjdCgpLAorCSAgICAgIGRlYnVnX2luZm8oRElORk9fVFJBQ0UsRElUX1NUUl9DVVJSRU5UKSkpOworICAgIH0KKworICAgIGlmICggUXVlcnlQcm9wKFBfR0hPU1QpICkKKyAgICAgICAgUXVlcnlQcm9wKFBfU1ApOworCisgICAgaWYgKCBzcCA8IDAgKQorICAgICAgICByZXR1cm4gU2V0KCBQX1NQLCAwICk7CisKKyAgICBpZiAoIHNwID4gUXVlcnlQcm9wKFBfTUFYX1NQKSApCisgICAgICAgIHJldHVybiBTZXQoIFBfU1AsIFF1ZXJ5UHJvcChQX01BWF9TUCksIEZfVkFMVUUgKTsKKworICAgIHJldHVybiBTZXQoIFBfU1AsIHNwLCBGX1ZBTFVFICk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9hbGNvaG9sKGludCBuKQoreworICBpZighaW50cChuKSkKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICJfc2V0X2FsY29ob2woKTogZXhwZWN0ZWQgPGludD4sIGdvdCAlLjUwT1xuIiwgbikpOworCisgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpCisgICAgcmV0dXJuIFF1ZXJ5KFBfQUxDT0hPTCwgRl9WQUxVRSk7CisKKyAgLy8gbnVyIMRuZGVydW5nZW4gdW5kIFdlcnRlID49MCB3ZXJkZW4gZ2VzZXR6dC4uLgorICBuID0gbiA8IDAgPyAwIDogbjsKKyAgaW50IG9sZCA9IFF1ZXJ5KFBfQUxDT0hPTCwgRl9WQUxVRSk7CisgIGlmICggb2xkID09IG4pCisgICAgcmV0dXJuIG9sZDsKKworICAvLyBIb29rcyBhdWZydWZlbgorICBpbnQgKnJldCA9IEhvb2tGbG93KEhfSE9PS19BTENPSE9MLCBuKTsKKyAgLy8gQmVpIEFiYnJ1Y2ggYWx0ZW4gV2VydCB6dXJ1ZWNrZ2ViZW4KKyAgc3dpdGNoIChyZXRbSF9SRVRDT0RFXSkgeworICAgIGNhc2UgSF9DQU5DRUxMRUQ6CisgICAgICByZXR1cm4gb2xkOworICAgIGNhc2UgSF9BTFRFUkVEOgorICAgICAgLy8gc29uc3QgbmV1ZW4gV2VydCBzZXR6ZW4KKyAgICAgIGlmKCFpbnRwKHJldFtIX1JFVERBVEFdKSkKKyAgICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAgIl9zZXRfYWxjb2hvbCgpOiBkYXRhIGZyb20gSG9va0Zsb3coKSAhPSA8aW50PjogJS41ME9cbiIsCisgICAgICAgICAgICByZXRbSF9SRVREQVRBXSkpOworICAgICAgbiA9IHJldFtIX1JFVERBVEFdOworICAgICAgbiA9IG4gPCAwID8gMCA6IG47CisKKyAgICAvLyBIX05PX01PRCBpcyBmYWxsdGhyb3VnaAorICB9CisKKyAgcmV0dXJuIFNldChQX0FMQ09IT0wsIG4sIEZfVkFMVUUpOworfQorCitzdGF0aWMgaW50IF9zZXRfZHJpbmsoaW50IG4pCit7CisgIGlmKCFpbnRwKG4pKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgIl9zZXRfZHJpbmsoKTogZXhwZWN0ZWQgPGludD4sIGdvdCAlLjUwT1xuIiwgbikpOworCisgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpCisgICAgcmV0dXJuIFF1ZXJ5KFBfRFJJTkssIEZfVkFMVUUpOworCisgIC8vIG51ciDEbmRlcnVuZ2VuIHVuZCBXZXJ0ZSA+PTAgd2VyZGVuIGdlc2V0enQuLi4KKyAgbiA9IG4gPCAwID8gMCA6IG47CisgIGludCBvbGQgPSBRdWVyeShQX0RSSU5LLCBGX1ZBTFVFKTsKKyAgaWYgKCBvbGQgPT0gbikKKyAgICByZXR1cm4gb2xkOworCisgIC8vIEhvb2tzIGF1ZnJ1ZmVuCisgIGludCAqcmV0ID0gSG9va0Zsb3coSF9IT09LX0RSSU5LLCBuKTsKKyAgLy8gQmVpIEFiYnJ1Y2ggYWx0ZW4gV2VydCB6dXJ1ZWNrZ2ViZW4KKyAgc3dpdGNoIChyZXRbSF9SRVRDT0RFXSkgeworICAgIGNhc2UgSF9DQU5DRUxMRUQ6CisgICAgICByZXR1cm4gb2xkOworICAgIGNhc2UgSF9BTFRFUkVEOgorICAgICAgLy8gc29uc3QgbmV1ZW4gV2VydCBzZXR6ZW4KKyAgICAgIGlmKCFpbnRwKHJldFtIX1JFVERBVEFdKSkKKyAgICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAgIl9zZXRfZHJpbmsoKTogZGF0YSBmcm9tIEhvb2tGbG93KCkgIT0gPGludD46ICUuNTBPXG4iLAorICAgICAgICAgICAgcmV0W0hfUkVUREFUQV0pKTsKKyAgICAgIG4gPSByZXRbSF9SRVREQVRBXTsKKyAgICAgIG4gPSBuIDwgMCA/IDAgOiBuOworCisgICAgLy8gSF9OT19NT0QgaXMgZmFsbHRocm91Z2gKKyAgfQorCisgIHJldHVybiBTZXQoUF9EUklOSywgbiwgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9mb29kKGludCBuKQoreworICBpZighaW50cChuKSkKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICJfc2V0X2Zvb2QoKTogZXhwZWN0ZWQgPGludD4sIGdvdCAlLjUwT1xuIiwgbikpOworCisgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpCisgICAgcmV0dXJuIFF1ZXJ5KFBfRk9PRCwgRl9WQUxVRSk7CisKKyAgLy8gbnVyIMRuZGVydW5nZW4gdW5kIFdlcnRlID49MCB3ZXJkZW4gZ2VzZXR6dC4uLgorICBuID0gbiA8IDAgPyAwIDogbjsKKyAgaW50IG9sZCA9IFF1ZXJ5KFBfRk9PRCwgRl9WQUxVRSk7CisgIGlmICggb2xkID09IG4pCisgICAgcmV0dXJuIG9sZDsKKworICAvLyBIb29rcyBhdWZydWZlbgorICBpbnQgKnJldCA9IEhvb2tGbG93KEhfSE9PS19GT09ELCBuKTsKKyAgLy8gQmVpIEFiYnJ1Y2ggYWx0ZW4gV2VydCB6dXJ1ZWNrZ2ViZW4KKyAgc3dpdGNoIChyZXRbSF9SRVRDT0RFXSkgeworICAgIGNhc2UgSF9DQU5DRUxMRUQ6CisgICAgICByZXR1cm4gb2xkOworICAgIGNhc2UgSF9BTFRFUkVEOgorICAgICAgLy8gc29uc3QgbmV1ZW4gV2VydCBzZXR6ZW4KKyAgICAgIGlmKCFpbnRwKHJldFtIX1JFVERBVEFdKSkKKyAgICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAgIl9zZXRfZm9vZCgpOiBkYXRhIGZyb20gSG9va0Zsb3coKSAhPSA8aW50PjogJS41ME9cbiIsCisgICAgICAgICAgICByZXRbSF9SRVREQVRBXSkpOworICAgICAgbiA9IHJldFtIX1JFVERBVEFdOworICAgICAgbiA9IG4gPCAwID8gMCA6IG47CisKKyAgICAvLyBIX05PX01PRCBpcyBmYWxsdGhyb3VnaAorICB9CisKKyAgcmV0dXJuIFNldChQX0ZPT0QsIG4sIEZfVkFMVUUpOworfQorCitzdGF0aWMgaW50IF9zZXRfcG9pc29uKGludCBuKQoreworICAgIGlmKCFpbnRwKG4pKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgIl9zZXRfcG9pc29uKCk6IGV4cGVjdGVkIDxpbnQ+LCBnb3QgJS41ME9cbiIsIG4pKTsKKworICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKQorICAgIHJldHVybiBRdWVyeShQX1BPSVNPTiwgRl9WQUxVRSk7CisKKyAgaW50IG1wID0gUXVlcnlQcm9wKFBfTUFYX1BPSVNPTik7CisgIG4gPSAobjwwID8gMCA6IChuPm1wID8gbXAgOiBuKSk7CisKKyAgLy8gbnVyID49MCB6dWxhc3Nlbi4KKyAgbiA9IG4gPCAwID8gMCA6IG47CisKKyAgaW50IG9sZCA9IFF1ZXJ5KFBfUE9JU09OLCBGX1ZBTFVFKTsKKyAgaWYgKCBvbGQgPT0gMCAmJiBuID09IDApCisgICAgcmV0dXJuIG9sZDsKKworICAvLyBIb29rcyBhdWZydWZlbgorICBpbnQgKnJldCA9IEhvb2tGbG93KEhfSE9PS19QT0lTT04sIG4pOworICAvLyBCZWkgQWJicnVjaCBhbHRlbiBXZXJ0IHp1cnVlY2tnZWJlbgorICBzd2l0Y2ggKHJldFtIX1JFVENPREVdKSB7CisgICAgY2FzZSBIX0NBTkNFTExFRDoKKyAgICAgIHJldHVybiBvbGQ7CisgICAgY2FzZSBIX0FMVEVSRUQ6CisgICAgICAvLyBzb25zdCBuZXVlbiBXZXJ0IHNldHplbgorICAgICAgaWYoIWludHAocmV0W0hfUkVUREFUQV0pKQorICAgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICAgICAiX3NldF9wb2lzb24oKTogZGF0YSBmcm9tIEhvb2tGbG93KCkgIT0gPGludD46ICUuNTBPXG4iLAorICAgICAgICAgICAgcmV0W0hfUkVUREFUQV0pKTsKKyAgICAgIG4gPSByZXRbSF9SRVREQVRBXTsKKyAgICAgIG4gPSBuIDwgMCA/IDAgOiBuOworCisgICAgLy8gSF9OT19NT0QgaXMgZmFsbHRocm91Z2gKKyAgfQorCisgIC8vIEZ1ZXIgZGllIFNlbGJzdGhlaWx1bmcuCisgIHN3aXRjaChuKSB7CisgIGNhc2UgMToKKyAgICBkcm9wX3BvaXNvbiA9IDQwK3JhbmRvbSgxNik7CisgICAgYnJlYWs7CisgIGNhc2UgMjoKKyAgICBkcm9wX3BvaXNvbiA9IDI1K3JhbmRvbSg4KTsKKyAgICBicmVhazsKKyAgY2FzZSAzOgorICAgIGRyb3BfcG9pc29uID0gMTgrcmFuZG9tKDQpOworICAgIGJyZWFrOworICBkZWZhdWx0OgorICAgIC8vIG51ciByZWxldmFudCBmdWVyIE5QQywgZGEgU3BpZWxlciBiZWkgPjMgR2lmdCBuaWNodCBtZWhyIHJlZ2VnZW5pZXJlbi4KKyAgICBkcm9wX3BvaXNvbiA9IDIyIC0gMipuICsgcmFuZG9tKDQzIC0gMypuKTsKKyAgICBicmVhazsKKyAgfQorCisgIC8vIGZ1ZXIgU2V0emVuIGRlciBQcm9wIHZvbiBhdXNzZW4gZWluIExvZyBzY2hyZWliZW4KKyAgaWYgKHByZXZpb3VzX29iamVjdCgxKSAhPSBNRSkKKyAgICBsb2dfZmlsZSgiUE9JU09OIiwgc3ByaW50ZigiJXMgLSAlczogJWQgdm9uICVPICglcylcbiIsCisgICAgICAgICAgIGR0aW1lKHRpbWUoKSlbNS4uXSwKKyAgICAgICAgICAgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkgPworICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0ZXVpZCh0aGlzX29iamVjdCgpKSkgOgorICAgICAgICAgICAgIGNhcGl0YWxpemUobmFtZShXRVIpKSksCisgICAgICAgICAgIG4sCisgICAgICAgICAgIChwcmV2aW91c19vYmplY3QoMikgPyBwcmV2aW91c19vYmplY3QoMikgOiBwcmV2aW91c19vYmplY3QoMSkpLAorICAgICAgICAgICAodGhpc19wbGF5ZXIoKSA/IGNhcGl0YWxpemUoZ2V0ZXVpZCh0aGlzX3BsYXllcigpKSkgOiAiPz8/IikpKTsKKworICByZXR1cm4gU2V0KFBfUE9JU09OLCBuLCBGX1ZBTFVFKTsKK30KKworc3RhdGljIGludCBfc2V0X3hwKGludCB4cCkgeyByZXR1cm4gU2V0KFBfWFAsIHhwIDwgMCA/IDAgOiB4cCwgRl9WQUxVRSk7IH0KKworc3RhdGljIG1peGVkIF9zZXRfZGllX2hvb2sobWl4ZWQgaG9vaykKK3sKKyAgaWYoaG9vayAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpKQorICAgIGxvZ19maWxlKCJESUVfSE9PSyIsCisgICAgICAgICAgICAgc3ByaW50ZigiJXMgOiBESUVfSE9PSyBnZXNldHp0IHZvbiAlTyBpbiAlTyAoJXMpXG4iLAorICAgICAgICAgICAgICAgICAgICAgZHRpbWUodGltZSgpKVs1Li5dLAorICAgICAgICAgICAgICAgICAgICAgKHByZXZpb3VzX29iamVjdCgyKSA/IHByZXZpb3VzX29iamVjdCgyKTpwcmV2aW91c19vYmplY3QoMSkpLAorICAgICAgICAgICAgICAgICAgICAgdGhpc19vYmplY3QoKSxnZXR1aWQodGhpc19vYmplY3QoKSkpKTsKKyAgcmV0dXJuIFNldChQX1RNUF9ESUVfSE9PSyxob29rLCBGX1ZBTFVFKTsKK30KKworc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X2VuZW15X2RhbWFnZSgpCit7CisgIHJldHVybiBjb3B5KGVuZW15X2RhbWFnZSk7Cit9CisKKy8vIG51ciBuZSBLb3BpZSBsaWVmZXJuLCBzb25zdCBrYW5uIGRhcyBqZWRlciB2b24gYXVzc2VuIGFlbmRlcm4uCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfdGltaW5nX21hcCgpIHsKKyAgcmV0dXJuIGNvcHkoUXVlcnkoUF9USU1JTkdfTUFQKSk7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgKiBDb25zdW1lLUZ1bmt0aW9uLCB1bSB6ZW50cmFsIGR1cmNoIGtvbnN1bWllcmJhcmUgRGluZ2UgYXVzZ2Vsb2VzdGUKKyAqIEFlbmRlcnVuZ2VuIGRlcyBHZXN1bmRoZWl0c3p1c3RhbmRlcyBoZXJiZWl6dWZ1ZWhyZW4uCisgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKiBLb25zdW1pZXJ0IGV0d2FzCisgKgorICogUnVlY2tnYWJld2VydAorICogICAgICAxICAgICAgIGVyZm9sZ3JlaWNoIGtvbnN1bWllcnQKKyAqICAgICAgMCAgICAgICBmZWhsZW5kZSBvZGVyIGZhbHNjaGUgUGFyYW1ldGVyCisgKiAgICAgPDAgICAgICAgQmVkaW5ndW5nIGZ1ZXIga29uc3VtaWVyZW4gbmljaHQgZXJmdWVsbHQsIEJpdHNldCBhdXM6CisgKiAgICAgIDEgICAgICAgS2FubiBuaWNodHMgbWVociBlc3NlbgorICogICAgICAyICAgICAgIEthbm4gbmljaHRzIG1laHIgdHJpbmtlbgorICogICAgICA0ICAgICAgIEthbm4gbmljaHRzIG1laHIgc2F1ZmVuCisgKiAgICAgIDggICAgICAgQWJnZWJyb2NoZW4gZHVyY2ggSG9vayBIX0hPT0tfQ09OU1VNRQorICovCitwdWJsaWMgdmFyYXJncyBpbnQgY29uc3VtZShtYXBwaW5nIGNpbmZvLCBpbnQgdGVzdG9ubHkpCit7CisgIGludCByZXR2YWwgPSAwOworICAvLyBudXIgd2FzIHR1biwgd2VubiBhdWNoIEluZm9zIHJlaW5rb21tZW4KKyAgaWYgKG1hcHBpbmdwKGNpbmZvKSAmJiBzaXplb2YoY2luZm8pKSB7CisgICAgLy8gSG9va3MgYXVmcnVmZW4sIHNpZSBhZW5kZXJuIGdnZi4gbm9jaCB3YXMgaW4gY2luZm8uCisgICAgbWl4ZWQgKmhyZXQgPSBIb29rRmxvdyhIX0hPT0tfQ09OU1VNRSwgKHtjaW5mbywgdGVzdG9ubHl9KSApOworICAgIHN3aXRjaChocmV0W0hfUkVUQ09ERV0pCisgICAgeworICAgICAgICBjYXNlIEhfQ0FOQ0VMTEVEOgorICAgICAgICAgIHJldHVybiAtSENfSE9PS19DQU5DRUxMQVRJT047CisgICAgICAgIGNhc2UgSF9BTFRFUkVEOgorICAgICAgICAgIC8vIHRlc3Rvbmx5IGthbm4gbmljaHQgZ2VhZW5kZXJ0IHdlcmRlbi4KKyAgICAgICAgICBjaW5mbyA9IGhyZXRbSF9SRVREQVRBXVswXTsKKyAgICB9CisgICAgLy8gTGVnYWN5LU1hcHBpbmdzIChmbGFjaGUpIG5lYmVuIHN0cnVrdHVyaWVydGVuIE1hcHBpbmdzIHp1bGFzc2VuCisgICAgLy8gZmxhY2hlIEtvcGllbiBlcnpldWdlbiAoVE9ETz86IHVuZCBmdWVyIFRlaWxtYXBwaW5ncyBuaWNodCByZWxldmFudGUKKyAgICAvLyBFaW50cmFlZ2UgbG9lc2NoZW4pCisgICAgbWFwcGluZyBjb25kaXRpb25zOworICAgIGlmIChtYXBwaW5ncChjaW5mb1tIX0NPTkRJVElPTlNdKSkgeworICAgICAgY29uZGl0aW9ucyA9IGNvcHkoY2luZm9bSF9DT05ESVRJT05TXSk7CisgICAgfSBlbHNlIHsKKyAgICAgIGNvbmRpdGlvbnMgPSBjb3B5KGNpbmZvKTsKKyAgICB9CisgICAgbWFwcGluZyBlZmZlY3RzOworICAgIGlmIChtYXBwaW5ncChjaW5mb1tIX0VGRkVDVFNdKSkgeworICAgICAgZWZmZWN0cyA9IGZpbHRlcihjaW5mb1tIX0VGRkVDVFNdLCAoOiBtZW1iZXIoSF9BTExPV0VEX0VGRkVDVFMsICQxKSA+IC0xIDopKTsKKyAgICB9IGVsc2UgeworICAgICAgZWZmZWN0cyA9IGZpbHRlcihjaW5mbywgKDogbWVtYmVyKEhfQUxMT1dFRF9FRkZFQ1RTLCAkMSkgPiAtMSA6KSk7CisgICAgfQorCisgICAgLy8gQmVkaW5ndW5nZW4gcHJ1ZWZlbgorICAgIGlmIChtYXBwaW5ncChjb25kaXRpb25zKSAmJiBzaXplb2YoY29uZGl0aW9ucykpIHsKKyAgICAgIC8vIEJlZGluZ3VuZ2VuIGZ1ZXIgS29uc3VtIGF1c3dlcnRlbgorICAgICAgaWYgKGNvbmRpdGlvbnNbUF9GT09EXSAmJiAhZWF0X2Zvb2QoY29uZGl0aW9uc1tQX0ZPT0RdLCAxKSkKKyAgICAgICAgcmV0dmFsIHw9IEhDX01BWF9GT09EX1JFQUNIRUQ7CisgICAgICBlbHNlIGlmIChjb25kaXRpb25zW1BfRFJJTktdICYmICFkcmlua19zb2Z0KGNvbmRpdGlvbnNbUF9EUklOS10sIDEpKQorICAgICAgICByZXR2YWwgfD0gSENfTUFYX0RSSU5LX1JFQUNIRUQ7CisgICAgICBlbHNlIGlmIChjb25kaXRpb25zW1BfQUxDT0hPTF0gJiYgIWRyaW5rX2FsY29ob2woY29uZGl0aW9uc1tQX0FMQ09IT0xdLCAxKSkKKyAgICAgICAgcmV0dmFsIHw9IEhDX01BWF9BTENPSE9MX1JFQUNIRUQ7CisgICAgICAvLyByZXR2YWwgbmVnYXRpdiBtYWNoZW4sIGRhbWl0IEZlaGxlciBsZWljaHQgZXJrZW5uYmFyIGlzdAorICAgICAgcmV0dmFsID0gLXJldHZhbDsKKyAgICB9CisgICAgLy8gQmVkaW5ndW5nZW4gd3VyZGVuIGFiZ2VhcmJlaXRldCwgamV0enQgZGllIEhlaWx1bmcgZHVyY2hmdWVocmVuCisgICAgaWYgKCFyZXR2YWwpIHsKKyAgICAgIGlmICghdGVzdG9ubHkpIHsKKyAgICAgICAgLy8gQmVkaW5ndW5nZW4gZXJmdWVsbGVuLCB3ZW5uIGFsbGVzIHBhc3N0IHVuZCBrZWluIFRlc3QKKyAgICAgICAgaWYgKGNvbmRpdGlvbnNbUF9BTENPSE9MXSkKKyAgICAgICAgICBkcmlua19hbGNvaG9sKGNvbmRpdGlvbnNbUF9BTENPSE9MXSk7CisgICAgICAgIGlmIChjb25kaXRpb25zW1BfRFJJTktdKQorICAgICAgICAgIGRyaW5rX3NvZnQoY29uZGl0aW9uc1tQX0RSSU5LXSk7CisgICAgICAgIGlmIChjb25kaXRpb25zW1BfRk9PRF0pCisgICAgICAgICAgZWF0X2Zvb2QoY29uZGl0aW9uc1tQX0ZPT0RdKTsKKyAgICAgICAgLy8gVW5kIGpldHp0IGRpZSBXaXJrdW5nZW4KKyAgICAgICAgaWYgKGVmZmVjdHNbUF9QT0lTT05dKQorICAgICAgICAgIFNldFByb3AoUF9QT0lTT04sIFF1ZXJ5UHJvcChQX1BPSVNPTikgKyBlZmZlY3RzW1BfUE9JU09OXSk7CisgICAgICAgIC8vIFVuZCBudW4gd2lya2xpY2ggaGVpbGVuCisgICAgICAgIHN3aXRjaCAoY2luZm9bSF9ESVNUUklCVVRJT05dKSB7CisgICAgICAgIGNhc2UgSERfSU5TVEFOVDoKKyAgICAgICAgICBtYXAoZWZmZWN0cywgKDogU2V0UHJvcCgkMSwgUXVlcnlQcm9wKCQxKSArICQyKSA6KSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgMS4uNTA6CisgICAgICAgICAgYnVmZmVyX2hwKGVmZmVjdHNbUF9IUF0sIGNpbmZvW0hfRElTVFJJQlVUSU9OXSk7CisgICAgICAgICAgYnVmZmVyX3NwKGVmZmVjdHNbUF9TUF0sIGNpbmZvW0hfRElTVFJJQlVUSU9OXSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgYnVmZmVyX2hwKGVmZmVjdHNbUF9IUF0sIEhEX1NUQU5EQVJEKTsKKyAgICAgICAgICBidWZmZXJfc3AoZWZmZWN0c1tQX1NQXSwgSERfU1RBTkRBUkQpOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICB9CisgICAgICByZXR2YWwgPSAxOworICAgIH0KKyAgfQorICByZXR1cm4gcmV0dmFsOworfQpkaWZmIC0tZ2l0IGEvc3RkL2xpdmluZy9saWdodC5jIGIvc3RkL2xpdmluZy9saWdodC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjViMTJlMWYKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL2xpZ2h0LmMKQEAgLTAsMCArMSw1NSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9kZXNjcmlwdGlvbi5jIC0tIGRlc2NyaXB0aW9uIGZvciBsaXZpbmcgb2JqZWN0cworLy8KKy8vICRJZDogZGVzY3JpcHRpb24uYyA3MzQwIDIwMDktMTEtMTkgMjE6NDQ6NTFaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGxpdmluZy9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPGxpdmluZy9za2lsbHMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHBsYXllci92aWV3Y21kLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPGNvbnRhaW5lci5oPgorI2luY2x1ZGUgPHBsYXllci9iYXNlLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL2xpZ2h0IjsKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkgeworICA6OmNyZWF0ZSgpOworICBTZXRQcm9wKFBfTElHSFRfVFJBTlNQQVJFTkNZLCAwKTsKK30KKworc3RhdGljIGludCBfcXVlcnlfcGxheWVyX2xpZ2h0KCkKK3sKKyAgaWYgKGVudmlyb25tZW50KCkpCisgICAgcmV0dXJuIGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX0lOVF9MSUdIVCkgKyBRdWVyeVByb3AoUF9MSUdIVF9NT0RJRklFUik7Cit9CisKK3ZhcmFyZ3MgaW50IENhbm5vdFNlZShpbnQgc2lsZW50KQoreworICAgc3RyaW5nIGlzX2JsaW5kOworICAgaWYgKGlzX2JsaW5kID0gUXVlcnlQcm9wKFBfQkxJTkQpKSB7CisgICAgICBpZiAoIXNpbGVudCkgeworICAgICAgICAgaWYgKHN0cmluZ3AoaXNfYmxpbmQpKQorICAgICAgICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwgaXNfYmxpbmQpOworICAgICAgICAgZWxzZSB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLCAiRHUgYmlzdCBibGluZCFcbiIpOworICAgICAgfQorICAgICAgcmV0dXJuIDI7CisgICB9CisgICBpZiAoVXNlU2tpbGwoU0tfTklHSFRWSVNJT04pPD0wICYmCisgICAgICAgZW52aXJvbm1lbnQoKSAmJiBRdWVyeVByb3AoUF9QTEFZRVJfTElHSFQpPD0wICYmCisgICAgICAgKCFJU19MRUFSTkVSKHRoaXNfb2JqZWN0KCkpIHx8ICFRdWVyeShQX1dBTlRTX1RPX0xFQVJOKSkpCisgICB7CisgICAgICAgaWYgKCFzaWxlbnQpIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksICJFcyBpc3QgenUgZHVua2VsIVxuIik7CisgICAgICAgcmV0dXJuIDE7CisgICB9CisgICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvbW9uZXloYW5kbGVyLmMgYi9zdGQvbGl2aW5nL21vbmV5aGFuZGxlci5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdhMjIyMjYKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL21vbmV5aGFuZGxlci5jCkBAIC0wLDAgKzEsMjYgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBsaXZpbmcvbW9uZXloYW5kbGVyLmMgLS0gbW9uZXkgaGFuZGxlciBmb3IgbGl2aW5ncworLy8KKy8vICRJZDogbW9uZXloYW5kbGVyLmMgNjczOCAyMDA4LTAyLTE5IDE4OjQ2OjE0WiBIdW1uaSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL21vbmV5aGFuZGxlciI7CisKKy8vIEZ1bmt0aW9uZW4gc29sbGVuIG51ciBkYXMgUHJvZ3JhbW0gZXJzZXR6ZW4sIG5hdHVlcmxpY2ggbnVyIGluIGRlcgorLy8gQmx1ZXByaW50IF9kaWVzZXNfIE9iamVrdGVzLCBuaWNodCBpbiBhbmRlcmVuLiA7LSkgQlRXOiBOb3JtYWxlcndlaXNlCisvLyBzb2xsdGUgbmllbWFuZCBoaWVyZHJpbiBjcmVhdGUoKSBydWZlbiwgZGVyIGRhcyBEaW5nIGhpZXIgZXJidC4KK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgaWYgKG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpID09IF9fRklMRV9fWy4uPDNdKQorICAgIHJlcGxhY2VfcHJvZ3JhbSgpOworfQorCisvLyB3aXJkIG5pY2h0IHZvbiBlcmJlbmRlbiBPYmpla3RlbiBnZXJ1ZmVuLiAoV296dSBhdWNoLikKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIHsKKyAgY3JlYXRlX3N1cGVyKCk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvbW92aW5nLmMgYi9zdGQvbGl2aW5nL21vdmluZy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmM2MTQ5ZmYKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL21vdmluZy5jCkBAIC0wLDAgKzEsNDU3IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL21vdmluZy5jIC0tIG1vdmluZyBvZiBsaXZpbmcgb2JqZWN0cworLy8KKy8vICRJZDogbW92aW5nLmMgOTQ0OCAyMDE2LTAxLTIyIDE3OjUyOjI4WiBaZXNzdHJhICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC90aGluZy9tb3ZpbmciOworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGhvb2suaD4KKyNpbmNsdWRlIDxsaXZpbmcvbW92aW5nLmg+CisjaW5jbHVkZSA8bGl2aW5nL3NraWxscy5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDxsaXZpbmcuaD4KKworI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorCisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgICAgaWYgKG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpID09IF9fRklMRV9fWzAuLjwzXSkKKyAgICB7CisgICAgICByZXR1cm47CisgICAgfQorICAgIG9mZmVySG9vayhIX0hPT0tfTU9WRSwxKTsKK30KKworcHVibGljIHZvaWQgQWRkUHVyc3VlcihvYmplY3Qgb2IpCit7CisgIG1peGVkICpwdXI7CisKKyAgaWYgKCFvYmplY3RwKG9iKSkKKyAgICByZXR1cm47CisKKyAgaWYgKCFwb2ludGVycChwdXI9UXVlcnkoUF9QVVJTVUVSUykpKQorICAgIHB1cj0oezAsKHt9KX0pOworICBlbHNlIGlmIChtZW1iZXIocHVyWzFdLG9iKSE9LTEpCisgICAgcmV0dXJuOworICAKKyAgU2V0UHJvcChQX1BVUlNVRVJTLCh7IHB1clswXSwgcHVyWzFdKyh7b2J9KS0oezB9KSB9KSk7CisgIG9iLT5fU2V0UHVyc3VlZChNRSk7Cit9CisKK3B1YmxpYyB2b2lkIFJlbW92ZVB1cnN1ZXIob2JqZWN0IG9iKQoreworICBtaXhlZCAqcHVyOworCisgIGlmIChwb2ludGVycChwdXI9UXVlcnkoUF9QVVJTVUVSUyxGX1ZBTFVFKSkgCisgICAgICAmJiBtZW1iZXIocHVyWzFdLG9iKSE9LTEpCisgIHsKKyAgICBwdXJbMV0tPSh7b2IsMH0pOworICAgIGlmIChvYikKKyAgICAgIG9iLT5fUmVtb3ZlUHVyc3VlZChNRSk7CisgICAgaWYgKCFwdXJbMF0mJiFzaXplb2YocHVyWzFdKSkKKyAgICAgIHB1cj0wOworICAgIFNldFByb3AoUF9QVVJTVUVSUyxwdXIpOworICB9Cit9CisKK3B1YmxpYyB2b2lkIF9TZXRQdXJzdWVkKG9iamVjdCBvYikKK3sKKyAgbWl4ZWQgKnB1cjsKKworICBpZiAoIXBvaW50ZXJwKHB1cj1RdWVyeShQX1BVUlNVRVJTKSkpCisgICAgcHVyPSh7MCwoe30pfSk7CisgIGVsc2UKKyAgICBpZiAob2JqZWN0cChwdXJbMF0pKQorICAgICAgcHVyWzBdLT5SZW1vdmVQdXJzdWVyKE1FKTsKKyAgcHVyWzBdPW9iOworICBwdXJbMV0tPSh7MH0pOworICBTZXQoUF9QVVJTVUVSUyxwdXIpOworfQorCitwdWJsaWMgdm9pZCBfUmVtb3ZlUHVyc3VlZChvYmplY3Qgb2IpCit7CisgIG1peGVkICpwdXI7CisKKyAgaWYgKCFwb2ludGVycChwdXI9UXVlcnkoUF9QVVJTVUVSUykpIHx8IHB1clswXSE9b2IpCisgICAgcmV0dXJuOworICBwdXJbMF09MDsKKyAgcHVyWzFdLT0oezB9KTsKKyAgaWYgKCFzaXplb2YocHVyWzFdKSkKKyAgICBwdXI9MDsKKyAgU2V0KFBfUFVSU1VFUlMscHVyKTsKK30KKworCitwcml2YXRlIHZvaWQga2FtcGZlbmRlKCBvYmplY3QgZW4gKSB7CisgIGlmICghb2JqZWN0cChlbikpIHJldHVybjsKKyAgdGVsbF9vYmplY3QoIE1FLCBjYXBpdGFsaXplKGVuLT5uYW1lKCkpICsKKyAgICAgICIgaXN0IGpldHp0IGhpbnRlciBEaXIgaGVyLlxuIiApOworICB0ZWxsX29iamVjdCggZW4sICJEdSB2ZXJmb2xnc3QgamV0enQgIiArIG5hbWUoV0VOKSArICIuXG4iICk7ICAgICAgCisgIGVuLT5JbnNlcnRTaW5nbGVFbmVteShNRSk7Cit9CisKK3ByaXZhdGUgaW50IF9pc19sZWFybmVyKG9iamVjdCBwbCkgeworICByZXR1cm4gSVNfTEVBUk5FUihwbCk7IAorfQorCisKKy8vIGEpIFBydWVmdW5nZW4sIG9iIGRhcyBtb3ZlIGVybGF1YnQgaXN0LgorLy8gYikgenVtIFVlYmVyc2NocmVpYmVuCitwcm90ZWN0ZWQgaW50IFByZXZlbnRNb3ZlKG9iamVjdCBkZXN0LCBvYmplY3Qgb2xkZW52LCBpbnQgbWV0aG9kKSB7CisKKyAgLy8gTV9OT0NIRUNLPyAtPiBCZXdlZ3VuZyBlaCBlcmxhdWJ0ICh1bmQgUnVlY2tnYWJld2VydCB3dWVyZGUgaWdub3JpZXJ0KSwKKyAgLy8gYWJlciBQcmV2ZW50SW5zZXJ0L1ByZXZlbnRMZWF2ZSgpIHJ1ZmVuIHVuZCBpZ25vcmllcmVuLgorICBpZiAoKG1ldGhvZCZNX05PQ0hFQ0spKSB7CisgICAgICAvLyBlcnN0IFByZXZlbnRMZWF2ZUxpdmluZygpIHJ1ZmVuLi4uCisgICAgICBpZihlbnZpcm9ubWVudCgpKSAgICAgICAgCisgICAgICAgICAgZW52aXJvbm1lbnQoKS0+UHJldmVudExlYXZlTGl2aW5nKHRoaXNfb2JqZWN0KCksIGRlc3QpOworICAgICAgLy8gZGFubiBQcmV2ZW50SW5zZXJ0TGl2aW5nKCkgaW0gWmllbC1FbnYuCisgICAgICBkZXN0LT5QcmV2ZW50SW5zZXJ0TGl2aW5nKHRoaXNfb2JqZWN0KCkpOworICAgICAgLy8gdW5kIHJhdXMuLi4KKyAgICAgIHJldHVybigwKTsKKyAgfQorCisgIC8vIGJlaSBMZWJld2VzZW4gbXVzcyBkaWUgQmV3ZWd1bmdzbWV0aG9kZSBNX0dPIHVuZCBNX1RQT1JUIHNlaW4uIERpZXMgaXN0CisgIC8vIGdsZWljaHplaWd0IGRpZSBSZXN0cmlrdGlvbiBnZWdlbiBkYXMgTmVobWVuIHZvbiBMZWJld2VzZW4sIGRhIGRvcnQKKyAgLy8gTV9HRVQvTV9HSVZFL01fUFVUIGV0Yy4gdmVyd2VuZGV0IHd1ZXJkZS4gQmVpIE1fR08gdW5kIE1fVFBPUlQgZmluZGV0CisgIC8vIGtlaW5lIFBydWVmdW5nIHN0YXR0LCBvYiBkYXMgT2JqZWt0IGlucyBaaWVsICdyZWlucGFzc3QnIChHZXdpY2h0LCBBbnphaGwKKyAgLy8gT2JqZWt0ZSB1c3cuKS4KKyAgLy8gSWNoIGZpbmRlIGVzIGV0d2FzIG1lcmt3dWVyZGlnIGdlYmF1dCAoWmVzc3RyYSkuCisgIGlmICggIShtZXRob2QgJiAoTV9HTyB8IE1fVFBPUlQpKSApCisgICAgICByZXR1cm4gTUVfUExBWUVSOworICAKKyAgLy8gYWx0ZSB1bmQgbmV1ZSBVbWdlYnVuZyBhdWYgTk9fVFBPUlQgcHJ1ZWZlbi4KKyAgaWYgKCAobWV0aG9kICYgTV9UUE9SVCkgKSB7CisgICAgaWYgKCBlbnZpcm9ubWVudCgpICYmCisgICAgICAgIChlbnZpcm9ubWVudCgpLT5RdWVyeVByb3AoUF9OT19UUE9SVCkgJiAoTk9fVFBPUlRfT1VUfE5PX1RQT1JUKSkgKQorICAgICAgICAgIHJldHVybiBNRV9DQU5UX1RQT1JUX09VVDsKKyAgICBlbHNlIGlmICggZGVzdC0+UXVlcnlQcm9wKFBfTk9fVFBPUlQpICYgKE5PX1RQT1JUX0lOfE5PX1RQT1JUKSApCisgICAgICAgICAgcmV0dXJuIE1FX0NBTlRfVFBPUlRfSU47CisgIH0KKworICAvLyBlcnN0IFByZXZlbnRMZWF2ZUxpdmluZygpIHRlc3Rlbi4uLgorICBpZiggZW52aXJvbm1lbnQoKSAmJiBlbnZpcm9ubWVudCgpLT5QcmV2ZW50TGVhdmVMaXZpbmcodGhpc19vYmplY3QoKSwgZGVzdCkpCisgICAgICByZXR1cm4gTUVfQ0FOVF9MRUFWRV9FTlY7CisgIC8vIGRhbm4gUHJldmVudEluc2VydExpdmluZygpIGltIFppZWwtRW52CisgIGlmIChkZXN0LT5QcmV2ZW50SW5zZXJ0TGl2aW5nKHRoaXNfb2JqZWN0KCkpKSAKKyAgICAgIHJldHVybiBNRV9DQU5UX0JFX0lOU0VSVEVEOworCisgIHJldHVybiAwOworfQorCisvLyBLcmFtcyBuYWNoIGRlbSBNb3ZlIG1hY2hlbiB1bmQgbmViZW5iZWkgenVtIFVlYmVyc2NocmVpYmVuLgorcHJvdGVjdGVkIHZvaWQgTm90aWZ5TW92ZShvYmplY3QgZGVzdCwgb2JqZWN0IG9sZGVudiwgaW50IG1ldGhvZCkgeworICBtaXhlZCByZXM7CisgIG9iamVjdCBlbmVtOworCisgIC8vIEJlZ3J1ZXNzdW5nc3NjaGxhZyBmdWVyIGRpZSBHZWdlbmVyCisgIGlmICggIShtZXRob2QgJiBNX05PX0FUVEFDSykgKQorICAgICAgSW5pdEF0dGFjaygpOworCisgIGlmICghb2JqZWN0cChNRSkpIHJldHVybjsKKworICAvLyBWZXJmb2xnZXIgbmFjaGhvbGVuLgorICBpZiAoIHBvaW50ZXJwKHJlcyA9IFF1ZXJ5KFBfUFVSU1VFUlMpKSAmJiBzaXplb2YocmVzWzFdKSApIHsKKyAgICAgIHdoaWxlICggcmVtb3ZlX2NhbGxfb3V0KCAiVGFrZUZvbGxvd2VycyIgKSA+PSAwICk7CisKKyAgICAgIGNhbGxfb3V0KCAiVGFrZUZvbGxvd2VycyIsIDAgKTsKKyAgfQorCisgIC8vIHVuZCBub2NoIGRhcyBUZWFtIG5hY2hob2xlbi4KKyAgaWYgKCBvbGRlbnYgIT0gZGVzdAorICAgICAgJiYgb2JqZWN0cChNRSkKKyAgICAgICYmIFF1ZXJ5UHJvcChQX1RFQU1fQVVUT0ZPTExPVykKKyAgICAgICYmIG9iamVjdHAoIGVuZW0gPSBJc1RlYW1MZWFkZXIoKSApICkKKyAgICAgIGVuZW0tPlN0YXJ0Rm9sbG93KG9sZGVudik7IC8vIFRlYW12ZXJmb2xndW5nCisKK30KKwordmFyYXJncyBwdWJsaWMgaW50IG1vdmUoIG9iamVjdHxzdHJpbmcgZGVzdCwgaW50IG1ldGhvZCwgc3RyaW5nIGRpcmVjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgdGV4dG91dCwgc3RyaW5nIHRleHRpbiApCit7CisgICAgaW50IHBhcmEsIG5pZ2h0dmlzLCBpbnZpcywgdG1wOworICAgIG9iamVjdCBvbGRlbnYsICppbnY7CisgICAgc3RyaW5nIGZuLHZjOworICAgIG1peGVkIHJlczsKKyAgICBtaXhlZCBob29rRGF0YSwgaG9va1JlczsKKworICAgIGlmICghb2JqZWN0cChkZXN0KSAmJiAhc3RyaW5ncChkZXN0KSkKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIldyb25nIGFyZ3VtZW50IDEgdG8gbW92ZSgpLiAnZGVzdCcgbXVzdCBiZSBhICIKKyAgICAgICAgICAgICJzdHJpbmcgb3Igb2JqZWN0ISBBcmd1bWVudCB3YXM6ICUuMTAwT1xuIiwKKyAgICAgICAgICAgIGRlc3QpKTsKKworICAgIC8vIGFsdGVzIEVudiBlcnN0bWFsIG1lcmtlbi4KKyAgICBvbGRlbnYgPSBlbnZpcm9ubWVudCgpOworICAgIAorICAgIC8vZXJzdG1hbCBkZW4gcmljaHRpZ2VuIFppZWxyYXVtIHN1Y2hlbiwgYmV2b3IgaXJnZW5kd2VsY2hlIENoZWNrcyBnZW1hY2h0CisgICAgLy93ZXJkZW4uLi4KKyAgICAvLyBJc3QgZGVyIFNwaWVsZXIgaW4gZWluZXIgUGFyYWxsZWx3ZWx0PworICAgIGlmICggKHBhcmEgPSBRdWVyeVByb3AoUF9QQVJBKSkgJiYgaW50cChwYXJhKSApIHsKKyAgICAgICAgZm4gPSBvYmplY3RwKGRlc3QpID8gb2JqZWN0X25hbWUoZGVzdCkgOiBkZXN0OworCisgICAgICAgIC8vIEZhbGxzIGRlciBaaWVscmF1bSBuaWNodCBzY2hvbiBleHBsaXppdCBpbiBkZXIgUGFyYWxsZWx3ZWx0IGlzdCwKKyAgICAgICAgLy8gbmV1ZW4gWmllbHJhdW0gc3VjaGVuLiBBYmVyIG51ciwgd2VubiBmbiBrZWluICMgZW50aGFlbHQgKGFsc28ga2VpbgorICAgICAgICAvLyBDbG9uZSBpc3QpLCBzb25zdCB3dWVyZGUgZWluZSBCZXdlZ3VuZyBuYWNoIHJhdW0jNDJecGFyYSB2ZXJzdWNodCwKKyAgICAgICAgLy8gd2FzIGRhbm4gYnVnZ3QuIDstKSBQcm9ibGVtIHdpcmQgb2ZmZW5iYXIsIHdlbm4gZWluIFBhcmEtTGViZXdlc2VuCisgICAgICAgIC8vIGltIGNyZWF0ZSgpIGVpbmVzIFZDLVJhdW1zIGluIFBhcmEgaW4gZGVuIFJhdW0gYmV3ZWd0IHdpcmQsIGRhCisgICAgICAgIC8vIGRpZXNlciBkYW5uIG5vY2ggbmljaHQgdm9tIERyaXZlciB1bWJlbmFubnQgd3VyZGUgdW5kIHJhdW0jNDIKKyAgICAgICAgLy8gaGVpc3N0LgorICAgICAgICBpZiAoICFzaXplb2YocmVnZXhwKCAoeyBmbiB9KSwgIlxcXlsxLTldWzAtOV0qJCIgKSkgJiYKKyAgICAgICAgICAgIHN0cnJzdHIoZm4sIiMiKT09LTEgKQorICAgICAgICB7CisgICAgICAgICAgICBmbiArPSAiXiIgKyBwYXJhOworCisgICAgICAgICAgLy8gRGVyIFBhcmFsbGVsd2VsdC1SYXVtIG11c3MgZXhpc3RpZXJlbiB1bmQgZnVlciBTcGllbGVyCisgICAgICAgICAgLy8gZnJlaWdlZ2ViZW4gc2VpbiwgZGFtaXQgZXIgenVtIG5ldWVuIFppZWwgd2lyZC4gQW5zb25zdGVuCisgICAgICAgICAgLy8gZHVlcmZlbiBudXIgTlBDcywgVGVzdHNwaWVsZXIgdW5kIE1hZ2llciBoZXJlaW4uCisgICAgICAgICAgaWYgKCAoZmluZF9vYmplY3QoZm4pIAorICAgICAgICAgICAgICAgIHx8ICgoZmlsZV9zaXplKGZuKyIuYyIpPjAgfHwKKyAgICAgICAgICAgICAgICAgICAgKGZpbGVfc2l6ZSh2Yz1pbXBsb2RlKGV4cGxvZGUoZm4sIi8iKVswLi48Ml0sIi8iKSsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIi92aXJ0dWFsX2NvbXBpbGVyLmMiKT4wICYmCisgICAgICAgICAgICAgICAgICAgICFjYXRjaCh0bXA9KGludCljYWxsX290aGVyKHZjLCJRdWVyeVZhbGlkT2JqZWN0Iixmbik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICBwdWJsaXNoKSAmJiB0bXA+MCkpICYmCisgICAgICAgICAgICAgICAgICAgICFjYXRjaChsb2FkX29iamVjdChmbik7cHVibGlzaCkgKSkgJiYKKyAgICAgICAgICAgICAgICAgICghaW50ZXJhY3RpdmUoTUUpIHx8ICFmbi0+UXVlcnlQcm9wKFBfTk9fUExBWUVSUykgfHwgCisgICAgICAgICAgICAgICAgICAobWV0aG9kICYgTV9OT0NIRUNLKSB8fCBJU19MRUFSTkVSKE1FKSB8fAorICAgICAgICAgICAgICAgICAgKHN0cmluZ3AocmVzID0gUXVlcnlQcm9wKFBfVEVTVFBMQVlFUikpICYmCisgICAgICAgICAgICAgICAgICAgSVNfTEVBUk5FUiggbG93ZXJfY2FzZShyZXMpICkpKSApCisgICAgICAgICAgeworICAgICAgICAgICAgICBkZXN0ID0gZm47CisgICAgICAgICAgfQorICAgICAgICAgIGVsc2UKKyAgICAgICAgICB7CisgICAgICAgICAgICAgIC8vIFdpciBibGVpYmVuIGluIGRlciBOb3JtYWx3ZWx0LgorICAgICAgICAgICAgICBwYXJhID0gMDsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBqZXR6dCBlcnN0bWFsIEhvb2tzIGFicHJ1ZWZlbiwgZGEgc2llIGdnZi4gZGllIERhdGVuIGFlbmRlcm4uCisgICAgLy8gYWx0ZW4gUF9UTVBfTU9WRV9IT09LIHBydWVmZW4uCisgICAgaWYgKCByZXMgPSBRdWVyeVByb3AoUF9UTVBfTU9WRV9IT09LKSApeworICAgICAgICBpZiAoIHBvaW50ZXJwKHJlcykgJiYgc2l6ZW9mKHJlcykgPj0gMworICAgICAgICAgICAgICYmIGludHAocmVzWzBdKSAmJiB0aW1lKCk8cmVzWzBdCisgICAgICAgICAgICAgJiYgb2JqZWN0cChyZXNbMV0pICYmIHN0cmluZ3AocmVzWzJdKSApeworICAgICAgICAgICAgaWYgKCByZXMgPSBjYWxsX290aGVyKCByZXNbMV0sIHJlc1syXSwgZGVzdCwgbWV0aG9kLCBkaXJlY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHRvdXQsIHRleHRpbiApICl7CisgICAgICAgICAgICAgICAgaWYgKCBwb2ludGVycChyZXMpICYmIHNpemVvZihyZXMpID09IDUgKXsKKyAgICAgICAgICAgICAgICAgICAgZGVzdCA9IHJlc1swXTsKKyAgICAgICAgICAgICAgICAgICAgbWV0aG9kID0gcmVzWzFdOworICAgICAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSByZXNbMl07CisgICAgICAgICAgICAgICAgICAgIHRleHRvdXQgPSByZXNbM107CisgICAgICAgICAgICAgICAgICAgIHRleHRpbiA9IHJlc1s0XTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSBpZiAoIGludHAocmVzKSAmJiByZXMgPT0gLTEgKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gTUVfQ0FOVF9MRUFWRV9FTlY7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgU2V0UHJvcCggUF9UTVBfTU9WRV9IT09LLCAwICk7CisgICAgfQorICAgIC8vIG1vdmUgaG9vayBuYWNoIG5ldWVtIEhvb2tzeXN0ZW0gdHJpZ2dlcm4uCisgICAgaG9va0RhdGE9KHtkZXN0LG1ldGhvZCxkaXJlY3Rpb24sdGV4dG91dCx0ZXh0aW59KTsKKyAgICBob29rUmVzPUhvb2tGbG93KEhfSE9PS19NT1ZFLGhvb2tEYXRhKTsKKyAgICBpZihob29rUmVzICYmIHBvaW50ZXJwKGhvb2tSZXMpICYmIHNpemVvZihob29rUmVzKT5IX1JFVERBVEEpIHsKKyAgICAgIGlmKGhvb2tSZXNbSF9SRVRDT0RFXT09SF9DQU5DRUxMRUQpIHsKKyAgICAgICAgcmV0dXJuIE1FX0NBTlRfTEVBVkVfRU5WOworICAgICAgfQorICAgIGVsc2UgaWYoaG9va1Jlc1tIX1JFVENPREVdPT1IX0FMVEVSRUQgJiYgaG9va1Jlc1tIX1JFVERBVEFdICYmCisgICAgICAgICAgcG9pbnRlcnAoaG9va1Jlc1tIX1JFVERBVEFdKSAmJiBzaXplb2YoaG9va1Jlc1tIX1JFVERBVEFdKT49NSApeworICAgICAgZGVzdCA9IGhvb2tSZXNbSF9SRVREQVRBXVswXTsKKyAgICAgIG1ldGhvZCA9IGhvb2tSZXNbSF9SRVREQVRBXVsxXTsKKyAgICAgIGRpcmVjdGlvbiA9IGhvb2tSZXNbSF9SRVREQVRBXVsyXTsKKyAgICAgIHRleHRvdXQgPSBob29rUmVzW0hfUkVUREFUQV1bM107CisgICAgICB0ZXh0aW4gPSBob29rUmVzW0hfUkVUREFUQV1bNF07CisgICAgICB9CisgICAgfQorCisgICAgLy8gZGVzdCBhdWYgT2JqZWN0IG5vcm1pZXJlbgorICAgIGlmIChzdHJpbmdwKGRlc3QpKSBkZXN0PWxvYWRfb2JqZWN0KGRlc3QpOworCisgICAgLy8gamV0enQgQ2hlY2tzIGR1cmNoZnVlaHJlbiwgb2IgZGFzIE1vdmUgZHVyY2hnZWZ1ZWhydCB3ZXJkZW4gZGFyZi4KKyAgICBpZiAodG1wPVByZXZlbnRNb3ZlKGRlc3QsIG9sZGVudiwgbWV0aG9kKSkgeworICAgICAgLy8gYXVmIGd1ZWx0aWdlbiBGZWhsZXIgcHJ1ZWZlbiwgd2VyIHdlaXNzLCB3YXMgTWFnaWVyIGRhIGV2dGwuCisgICAgICAvLyB2ZXJzZWhlbnRsaWNoIHp1cnVlY2tnZWJlbi4KKyAgICAgIGlmIChWQUxJRF9NT1ZFX0VSUk9SKHRtcCkpCisgICAgICAgIHJldHVybih0bXApOworICAgICAgZWxzZQorICAgICAgICByZXR1cm4oTUVfRE9OVF9XQU5UX1RPX0JFX01PVkVEKTsKKyAgICB9CisgIAorICAgIGlmICggaW52aXMgPSBRdWVyeVByb3AoUF9JTlZJUykgKQorICAgICAgICBtZXRob2QgfD0gTV9TSUxFTlQ7CisKKyAgICBpZiAoIG9iamVjdHAob2xkZW52KSApIHsKKyAgICAgICAgaWYgKCAhKG1ldGhvZCAmIE1fU0lMRU5UKSApIHsKKyAgICAgICAgICAgIHN0cmluZyAqbW91dDsKKyAgICAgICAgICAgIGlmICggIXRleHRvdXQgKXsKKyAgICAgICAgICAgICAgICBpZiAoIG1ldGhvZCAmIE1fVFBPUlQgKQorICAgICAgICAgICAgICAgICAgICB0ZXh0b3V0ID0gKHN0cmluZykgUXVlcnlQcm9wKFBfTU1TR09VVCkgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgIChzdHJpbmcpIFF1ZXJ5UHJvcChQX01TR09VVCk7CisgICAgICAgICAgICAgICAgZWxzZSAKKyAgICAgICAgICAgICAgICAgICAgdGV4dG91dCA9IChtb3V0ID0gZXhwbG9kZSggKHN0cmluZykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFF1ZXJ5UHJvcChQX01TR09VVCkgfHwgIiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIyIgKSlbMF0KKyAgICAgICAgICAgICAgICAgICAgICAgICB8fCAoc3RyaW5nKVF1ZXJ5UHJvcChQX01NU0dPVVQpOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoICFzaXplb2YoZGlyZWN0aW9uKSApCisgICAgICAgICAgICAgICAgZGlyZWN0aW9uID0gMDsKKworICAgICAgICAgICAgaW52ID0gYWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSAtICh7IHRoaXNfb2JqZWN0KCkgfSk7CisgICAgICAgICAgICBpbnYgPSBmaWx0ZXIoIGludiwgIydsaXZpbmcvKicqLyApOworICAgICAgICAgICAgaW52IC09IGZpbHRlcl9vYmplY3RzKCBpbnYsICJDYW5ub3RTZWUiLCAxICk7CisKKyAgICAgICAgICAgIGZpbHRlciggaW52LCAjJ3RlbGxfb2JqZWN0LyonKi8sCisgICAgICAgICAgICAgICAgICAgICAgICAgIE5hbWUoIFdFUiwgMiApICsgIiAiICsgdGV4dG91dCArCisgICAgICAgICAgICAgICAgICAgICAgICAgIChkaXJlY3Rpb24gPyAiICIgKyBkaXJlY3Rpb24gOiAiIikgKworICAgICAgICAgICAgICAgICAgICAgICAgICAoc2l6ZW9mKG1vdXQpID4gMSA/IG1vdXRbMV0gOiAiIikgKyAiLlxuIiApOworICAgICAgICB9CisgICAgICAgIC8vIE1hZ2llciBzZWhlbiBhdWNoIEJld2VndW5nZW4sIGRpZSBNX1NJTEVOVCBzaW5kCisgICAgICAgIGVsc2UgaWYgKCBpbnRlcmFjdGl2ZShNRSkgKXsKKyAgICAgICAgICAgIGludiA9IChhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpICYgdXNlcnMoKSkKKyAgICAgICAgICAgICAgICAtICh7IHRoaXNfb2JqZWN0KCkgfSk7CisgICAgICAgICAgICBpbnYgPSBmaWx0ZXIoIGludiwgIydfaXNfbGVhcm5lci8qJyovICk7CisKKyAgICAgICAgICAgIGlmICggaW52aXMgKQorICAgICAgICAgICAgICAgIGZuID0gIigiICsgY2FwaXRhbGl6ZShnZXR1aWQoTUUpKSArICIpIHZlcnNjaHdpbmRldCAiCisgICAgICAgICAgICAgICAgICAgICJ1bnNpY2h0YmFyLlxuIjsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBmbiA9IGNhcGl0YWxpemUoZ2V0dWlkKE1FKSkgKyAiIHZlcnNjaHdpbmRldCBnYW56IGxlaXNlLlxuIjsKKyAgICAgICAgICAgIAorICAgICAgICAgICAgZmlsdGVyKCBpbnYsICMndGVsbF9vYmplY3QvKicqLywgZm4gKTsKKyAgICAgICAgfQorICAgICAgICAKKyAgICAgICAgLy8gTmFja2Vuc2NobGFnIGJlaW0gRmx1ZWNodGVuOgorICAgICAgICBpZiAoICEobWV0aG9kICYgTV9OT19BVFRBQ0spICYmIG9iamVjdHAoTUUpICkKKyAgICAgICAgICAgIEV4aXRBdHRhY2soKTsKKyAgICAgICAgLy9mYWxscyBuYWNoIEV4aXRBdHRhY2soKSBkYXMgTGl2aW5nIG5pY2h0IG1laHIgZXhpc3RpZXJ0LCBtdXNzIGRhcworICAgICAgICAvL21vdmUoKSBhdWNoIG5pY2h0IG1laHIgZm9ydGdlc2V0enQgd2VyZGVuLiBXZWl0ZXIgdW50ZW4gZ2lidCBlcyBhdWNoCisgICAgICAgIC8vbWluLiBlaW5lIFN0ZWxsZSwgZGllIG5pY2h0IHBydWVmdCB1bmQgZ2dmLiBidWdndC4gRGFoZXIgZXJmb2xndAorICAgICAgICAvL2hpZXIgZ2dmLiBlaW4gQWJicnVjaC4gMTUuMTEuMDYgWmVzc3RyYQorICAgICAgICBpZiAoIW9iamVjdHAoTUUpKSByZXR1cm4oTUVfV0FTX0RFU1RSVUNURUQpOworCisgICAgICAgIC8vIE5hY2tlbnNjaGxhZyBrYW5uIE1FIGluIGRlbiBUb2Rlc3JhdW0gYmV3ZWd0IGhhYmVuLi4uCisgICAgICAgIGlmICggb2xkZW52ID09IGVudmlyb25tZW50KCkgKSB7CisgICAgICAgICAgICAvLyBGdWVyIGFsbGUgYW53ZXNlbmRlbiBnZWduZXIga2FtcGZlbmRlKCkgYXVmcnVmZW4KKyAgICAgICAgICAgIGZpbHRlcigoUXVlcnlFbmVtaWVzKClbMF0gJiBhbGxfaW52ZW50b3J5KG9sZGVudikpLSh7MH0pLAorICAgICAgICAgICAgICAgICMna2FtcGZlbmRlKTsKKyAgICAgICAgICAgIC8vIEJ1Z3MgaW0gZXhpdCgpIHNpbmQgb2huZSBjYXRjaCgpIGVpbmZhY2ggbWlzdC4KKyAgICAgICAgICAgIGNhdGNoKGVudmlyb25tZW50KCktPmV4aXQoTUUsIGRlc3QpO3B1Ymxpc2gpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gaXJnZW5kd2FzIGthbm4gZGFzIE9iamVrdCB6ZXJzdG9lcnQgaGFiZW4sIHouQi4gZW52LT5leGl0KCkuCisgICAgaWYgKCFvYmplY3RwKE1FKSkgcmV0dXJuKE1FX1dBU19ERVNUUlVDVEVEKTsKKworICAgIGlmICggb2xkZW52ICE9IGVudmlyb25tZW50KCkgKQorICAgICAgICAvLyBEZXIgTmFja2Vuc2NobGFnIG9kZXIgZXhpdCgpIGtvZW5uZW4gZWluZW4gc2Nob24gYmV3ZWd0IGhhYmVuLgorICAgICAgICAvLyBVbmQgd2VubiBlcyBpbiBkZW4gVG9kZXNyYXVtIGlzdC4gO14pCisgICAgICAgIHJldHVybiBNT1ZFX09LOworICAgIAorICAgIFNldFByb3AoIFBfUFJFUEFSRURfU1BFTEwsIDAgKTsgLy8gU3BydWNodm9yYmVyZWl0dW5nIGFiZ2Vicm9jaGVuCisgICAgU2V0UHJvcCggUF9MQVNUX01PVkUsIHRpbWUoKSApOyAvLyBaZWl0cHVua3QgZGVyIGxldHp0ZW4gQmV3ZWd1bmcKKyAgICAKKyAgICBtb3ZlX29iamVjdChNRSwgZGVzdCk7CisgICAgaWYgKCFvYmplY3RwKE1FKSkKKyAgICAgIHJldHVybihNRV9XQVNfREVTVFJVQ1RFRCk7CisKKyAgICBkZXN0ID0gZW52aXJvbm1lbnQoKTsKKyAgICAKKyAgICBuaWdodHZpcyA9IFVzZVNraWxsKFNLX05JR0hUVklTSU9OKTsKKyAgICAvLyBNZWxkdW5nZW4gYW4gbmljaHQtQmxpbmRlIGF1c2dlYmVuLCBmYWxscyBrZWluZSAnc3RpbGxlJyBCZXdlZ3VuZworICAgIGlmICggIShtZXRob2QgJiBNX1NJTEVOVCkgKSB7CisgICAgICBpZiAoICF0ZXh0aW4gKSB7ICAgICAgICAKKyAgICAgICAgaWYgKCBtZXRob2QgJiBNX1RQT1JUICkKKyAgICAgICAgICAgICAgdGV4dGluID0gKHN0cmluZykgUXVlcnlQcm9wKFBfTU1TR0lOKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgICB0ZXh0aW4gPSAoc3RyaW5nKSBRdWVyeVByb3AoUF9NU0dJTik7CisgICAgICB9CisgICAgICAgICAgICAKKyAgICAgIGludiA9IGFsbF9pbnZlbnRvcnkoZW52aXJvbm1lbnQoKSkgLSAoeyB0aGlzX29iamVjdCgpIH0pOworICAgICAgaW52ID0gZmlsdGVyKCBpbnYsICMnbGl2aW5nLyonKi8gKTsKKyAgICAgICAgICAgIGludiAtPSBmaWx0ZXJfb2JqZWN0cyggaW52LCAiQ2Fubm90U2VlIiwgMSApOworICAgICAgICAgICAgZmlsdGVyKCBpbnYsICMndGVsbF9vYmplY3QvKicqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShuYW1lKCBXRVIsIDAgKSkgKyAiICIgKyB0ZXh0aW4gKyAiLlxuIiApOworICAgIH0KKyAgICAvLyBzb25zdDogTWFnaWVyIHNlaGVuIGF1Y2ggTV9TSUxFTlQtQmV3ZWd1bmdlbiwgaGllciBhbHNvIG51ciBhbiBNYWdpZXIKKyAgICAvLyBhdXNnZWJlbiwgYWxsZSBhbmRlcmVuIHNlaGVuIGVoIG5peC4KKyAgICBlbHNlIGlmICggaW50ZXJhY3RpdmUoTUUpICkgeyAgCisgICAgICBpbnYgPSAoYWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSAmIHVzZXJzKCkpIC0gKHt0aGlzX29iamVjdCgpfSk7ICAgICAgICAKKyAgICAgIGludiA9IGZpbHRlciggaW52LCAjJ19pc19sZWFybmVyLyonKi8gKTsgICAgICAgIAorICAgICAgaWYgKCBpbnZpcyApCisgICAgICAgIGZuID0gIigiICsgY2FwaXRhbGl6ZShnZXR1aWQoTUUpKSArICIpIHRhdWNodCB1bnNpY2h0YmFyIGF1Zi5cbiI7CisgICAgICBlbHNlCisgICAgICAgIGZuID0gY2FwaXRhbGl6ZShnZXR1aWQoTUUpKSArICIgc2NobGVpY2h0IGxlaXNlIGhlcmVpbi5cbiI7ICAgICAgICAKKyAgICAgIGZpbHRlciggaW52LCAjJ3RlbGxfb2JqZWN0LCBmbiApOyAgICAKKyAgICB9CisKKyAgICAvLyAiT2JqZWt0IiB1ZWJlciBkYXMgTW92ZSBpbmZvcm1pZXJlbi4KKyAgICBOb3RpZnlNb3ZlKGRlc3QsIG9sZGVudiwgbWV0aG9kKTsKKworICAgIC8vIEluaXRBdHRhY2soKSBpbiBOb3RpZnlNb3ZlKCkga2FubiBkYXMgT2JqZWt0IHplcnN0b2VydCBoYWJlbi4KKyAgICBpZiAoIW9iamVjdHAoTUUpKQorICAgICAgcmV0dXJuKE1FX1dBU19ERVNUUlVDVEVEKTsKKworICAgIC8vc2NoZWludCB3b2hsIGdla2xhcHB0IHp1IGhhYmVuLgorICAgIHJldHVybiBNT1ZFX09LOworfQorCitwdWJsaWMgdm9pZCBUYWtlRm9sbG93ZXJzKCkKK3sKKyAgbWl4ZWQgKmYsZW52OworICBpbnQgbWV0aCxpLHI7CisKKyAgZj1RdWVyeShQX1BVUlNVRVJTKTsKKyAgaWYgKCFwb2ludGVycChmKSkKKyAgICByZXR1cm47CisgIGVudj1lbnZpcm9ubWVudCgpOworICBpZihvYmplY3RfbmFtZShlbnYpID09ICIvcm9vbS9uZXR6dG90IikgcmV0dXJuOworICBmb3JlYWNoKG9iamVjdCBmb2xsb3dlcjogZlsxXS0oezB9KSApIHsKKyAgICAvLyBkaWUgcHJ1ZWZ1bmcgYXVmIG9iamVjdHAgaXN0IG5pY2h0IHZlcnJ1ZWNrdCwgZXMga2FubiB0aGVvLiBzZWluLCBkYXNzCisgICAgLy8gVmVyZm9sZ2VyIGltIFByZXZlbnRGb2xsb3coKSBvZGVyIGluIGlocmVtIG1vdmUvaW5pdCBhbmRlcmUgVmVyZm9sZ2VyCisgICAgLy8gemVyc3RvZXJlbi4KKyAgICBpZiAob2JqZWN0cChmb2xsb3dlcikgJiYgZW52aXJvbm1lbnQoZm9sbG93ZXIpIT1lbnYpIHsKKyAgICAgIC8vbWV0aD1NX05PQ0hFQ0s7CisgICAgICBtZXRoPU1fR087CisgICAgICBpZiAoZm9sbG93ZXItPlF1ZXJ5KFBfRk9MTE9XX1NJTEVOVCkpCisgICAgICAgICAgbWV0aHw9TV9TSUxFTlR8TV9OT19TSE9XOworICAgICAgY2F0Y2gocj1mb2xsb3dlci0+UHJldmVudEZvbGxvdyhlbnYpO3B1Ymxpc2gpOworICAgICAgaWYgKCFyKQorICAgICAgICAgIGZvbGxvd2VyLT5tb3ZlKGVudixtZXRoKTsKKyAgICAgIGVsc2UgaWYgKHI9PTIpCisgICAgICAgICAgUmVtb3ZlUHVyc3Vlcihmb2xsb3dlcik7CisgICAgfQorICB9Cit9CisKK3ZhcmFyZ3MgcHVibGljIGludCByZW1vdmUoKQoreyBvYmplY3QgdGVhbTsKKworICBpZiAoZW52aXJvbm1lbnQoKSkKKyAgeworICAgIGlmICggb2JqZWN0cCh0ZWFtPVF1ZXJ5KFBfVEVBTSkpICkKKyAgICAgIGNhdGNoKHRlYW0tPlJlbW92ZU1lbWJlcihNRSk7cHVibGlzaCk7CisKKyAgICBlbnZpcm9ubWVudCgpLT5Ob3RpZnlSZW1vdmUoTUUpOworICB9CisgIGRlc3RydWN0KE1FKTsKKyAgcmV0dXJuIDE7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvcHV0X2FuZF9nZXQuYyBiL3N0ZC9saXZpbmcvcHV0X2FuZF9nZXQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40ZTFhOTdmCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL2xpdmluZy9wdXRfYW5kX2dldC5jCkBAIC0wLDAgKzEsMTI0MyBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9wdXRfYW5kX2dldC5jIC0tIHRha2luZyBhbmQgcHV0dGluZyB0aGluZ3MKKy8vCisvLyAkSWQ6IHB1dF9hbmRfZ2V0LmMgODc1NSAyMDE0LTA0LTI2IDEzOjEzOjQwWiBaZXNzdHJhICQKKworLyoKKyAgR3J1bmRsZWdlbmQgbmV1IHN0cnVrdHVyaWVydCB2b24gQW15bnRob3IgaW0gQXByaWwtSnVuaSAyMDA3CisKK0RpZSBlaWdlbnRsaWNoZW4gRnVua3Rpb25lbjoKKworICBwcml2YXRlIHN0cmluZyBwdXRfb3JfZ2V0KG9iamVjdCBvLCBvYmplY3QgZGVzdCkKKyAgICBCZXdlZ3QgZWluIGVpbnplbG5lcyBPYmpla3QgbWl0IGF1dG9tYXRpc2NoIGJlc3RpbW10ZXIgTWV0aG9kLiBHaWJ0IGltCisgICAgRXJmb2xnc2ZhbGwgMCB6dXJ1ZWNrLCBzb25zdCBkaWUgYXVzenVnZWJlbmRlIEZlaGxlcm1lbGR1bmcuCisKKyAgdmFyYXJncyBpbnQgZHJvcChvYmplY3QgbywgbWl4ZWQgbXNnKQorICB2YXJhcmdzIGludCBwdXQob2JqZWN0IG8sIG9iamVjdCBkZXN0LCBtaXhlZCBtc2cpCisgIHZhcmFyZ3MgaW50IHBpY2sob2JqZWN0IG8sIG1peGVkIG1zZykKKyAgdmFyYXJncyBpbnQgZ2l2ZShvYmplY3Qgbywgb2JqZWN0IGRlc3QsIG1peGVkIG1zZykKKyAgdmFyYXJncyBpbnQgc2hvdyhvYmplY3Qgbywgb2JqZWN0IGRlc3QsIG1peGVkIG1zZykKKyAgICBEZXIgU3BpZWxlciBuaW1tdC9sZWd0L2dpYnQvemVpZ3QvbGFlc3N0IGVpbiBPYmpla3QgZmFsbGVuLCB3b2JlaSBkaWUKKyAgICBlbnRzcHJlY2hlbmRlbiBvZGVyIG9wdGlvbmFsIGFid2VpY2hlbmRlIChpbSBGb3JtYXQgdm9uIFBfWFhYX01TRykgb2RlcgorICAgIGdhciBrZWluZSAobXNnID09IDEpIE1lbGR1bmdlbiBhdXNnZWdlYmVuIHdlcmRlbi4gRXMgbGllZ3QgaW4gZGVyCisgICAgVmVyYW50d29ydHVuZyBkZXMgUnVmZW5kZW4sIHNpbm52b2xsZSBXZXJ0ZSB6dSB1ZWJlcmdlYmVuOyBpbnNiZXNvbmRlcmUKKyAgICB3aXJkIG5pY2h0IGdlcHJ1ZWZ0LCBvYiBzaWNoIGRpZSBPYmpla3RlIGluIGRlciBSZWljaHdlaXRlIGRlcyBTcGllbGVycworICAgIGJlZmluZGVuLiBHaWJ0IDEgenVydWVjaywgd2VubiBkYXMgT2JqZWt0IGJld2VndCB3dXJkZSwgc29uc3QgMC4KKworSGlsZnNmdW5rdGlvbmVuOgorCisgIHByaXZhdGUgb2JqZWN0ICpfX2ZpbmRfb2JqZWN0cyhzdHJpbmcgKnRva2Vucywgb2JqZWN0IGVudiwgaW50IGlzX3NvdXJjZSkKKyAgb2JqZWN0ICpmaW5kX29iamVjdHMoc3RyaW5nIHdoYXQsIG9iamVjdCBlbnYsIGludCBpc19zb3VyY2UpCisgICAgU3VjaHQgaW0gUmF1bSB1bmQgaW0gU3BpZWxlciAob2RlciBhbHRlcm5hdGl2IGluIGRlciBhbmdlZ2ViZW5lbiBVbWdlYnVuZykKKyAgICBuYWNoIGRlbiBpbiB0b2tlbnMvd2hhdCBiZXplaWNobmV0ZW4gT2JqZWt0ZW4uIGlzX3NvdXJjZSBiZXN0aW1tdCBkaWUKKyAgICBlcndhcnRldGUgZ3JhbW1hdGlzY2hlIEZvcm0gKDAgZnVlciAidG9wZiBhdWYgaGVyZCIgdW5kIDEgZnVlciAidG9wZiB2b24KKyAgICBoZXJkIiwgc2llaGUgTWFucGFnZSkuCisKKyAgdmFyYXJncyBpbnQgZHJvcF9vYmplY3RzKHN0cmluZyBzdHIsIG1peGVkIG1zZykKKyAgdmFyYXJncyBpbnQgcHV0X29iamVjdHMoc3RyaW5nIHN0ciwgaW50IGNhc3VzLCBzdHJpbmcgdmVyYiwgbWl4ZWQgbXNnKQorICB2YXJhcmdzIGludCBwaWNrX29iamVjdHMoc3RyaW5nIHN0ciwgbWl4ZWQgbXNnLCBpbnQgZmxhZykKKyAgdmFyYXJncyBpbnQgZ2l2ZV9vYmplY3RzKHN0cmluZyBzdHIsIG1peGVkIG1zZykKKyAgdmFyYXJncyBpbnQgc2hvd19vYmplY3RzKHN0cmluZyBzdHIsIG1peGVkIG1zZykKKyAgICBFaW4gQmVmZWhsIHdpZSAid2lyZiB3YWZmZW4gd2VnIiByZXN1bHRpZXJ0IGluIGVpbmVtIEF1ZnJ1ZiB2b24KKyAgICBkcm9wX29iamVjdHMoIndhZmZlbiIpLiBEaWVzZSBGdW5rdGlvbmVuIHNpbmQgaGF1cHRzYWVjaGxpY2ggZnVlciBkaWUKKyAgICBCZWhhbmRsdW5nIGRlciBqZXdlaWxpZ2VuIEtvbW1hbmRvcyB2b3JnZXNlaGVuLCBrb2VubmVuIGplZG9jaCBhdWNoIGZ1ZXIKKyAgICBlaWdlbmUgQmVmZWhsZSB2ZXJ3ZW5kZXQgd2VyZGVuLiBwdXRfb2JqZWN0cygpIGVyd2FydGV0IGF1c3NlcmRlbSBkZW4KKyAgICBLYXN1cyAoIkR1IGthbm5zdCBuaWNodHMgYW4gREVSIFBpbndhbmQgYmVmZXN0aWdlbi4iKSB1bmQgZGFzIHZlcndlbmRldGUKKyAgICBWZXJiIGluIGRlciBHdW5kZm9ybSAoImJlZmVzdGlnZW4iKS4gRGFzIEZsYWcgZnVlciBwaWNrX29iamVjdHMoKSBnaWJ0CisgICAgYW4sIG9iIGRhcyBPYmpla3QgYXVjaCBlaW5mYWNoIGhlcnVtbGllZ2VuIGRhcmYgKCJuaW1tIC4uLiIpIG9kZXIgbmljaHQKKyAgICAoImhvbGUgLi4uIikuIEdpYnQgYmVpIEVyZm9sZyAxLCBzb25zdCAwIHp1cnVlY2suCisKKyAgb2JqZWN0ICptb3ZlZF9vYmplY3RzKCkKKyAgb2JqZWN0IG1vdmVkX3doZXJlKCkKKyAgICBHaWJ0IGRpZSBlYmVuIGZhbGxlbmdlbGFzc2VuZW4vZ2VzdGVja3Rlbi8uLi4gT2JqZWt0ZSB6dXJ1ZWNrIHVuZCB3b2hpbgorICAgIHNpZSBnZXN0ZWNrdC93ZW0gc2llIGdlZ2ViZW4vZ2V6ZWlndCB3dXJkZW4uIEZ1ZXIgZGVuIEZhbGwsIGRhc3MgbWFuCisgICAgYW5zY2hsaWVzc2VuZCBub2NoIGV0d2FzIG1pdCBpaG5lbiBtYWNoZW4gbW9lY2h0ZS4KKworRGllIGVpbnplbG5lbiBLb21tYW5kb3M6CisgIHN0YXRpYyBpbnQgZmFsbGVubGFzc2VuKHN0cmluZyBzdHIpCisgIHN0YXRpYyBpbnQgd2VyZmVuKHN0cmluZyBzdHIpCisgIHN0YXRpYyBpbnQgbGVnZW4oc3RyaW5nIHN0cikKKyAgc3RhdGljIGludCBzdGVja2VuKHN0cmluZyBzdHIpCisgIHN0YXRpYyBpbnQgaG9sZW4oc3RyaW5nIHN0cikKKyAgc3RhdGljIGludCBuZWhtZW4oc3RyaW5nIHN0cikKKyAgc3RhdGljIGludCBnZWJlbihzdHJpbmcgc3RyKQorICAgIE1pbmltYWxlIFdyYXBwZXIgZnVlciBYWFhfb2JqZWN0cygpLCBlbnRmZXJuZW4gImZhbGxlbiIsICJ3ZWciIGJ6dy4gImFiIgorICAgIGF1cyBkZW4gQXJndW1lbnRlbiB1bmQgc2V0emVuIGVudHNwcmVjaGVuZGUgU3RhbmRhcmQtRmVobGVybWVsZHVuZ2VuLgorICAgIAorICBwcm90ZWN0ZWQgdm9pZCBhZGRfcHV0X2FuZF9nZXRfY29tbWFuZHMoKQorICAgIFJlZ2lzdHJpZXJ0IG9iaWdlIEZ1bmt0aW9uZW4gcGVyIGFkZF9hY3Rpb24oKS4KKworQXVzIHJlaW5lbiBLb21wYXRpYmlsaXRhZXRzZ3J1ZW5kZW4gd2VpdGVyaGluIGVudGhhbHRlbjoKKworICBvYmplY3QqIGZpbmRfb2JzKHN0cmluZyBzdHIsIGludCBtZXRoKQorICBpbnQgcGlja19vYmoob2JqZWN0IG9iKQorICBpbnQgZHJvcF9vYmoob2JqZWN0IG9iKQorICBpbnQgcHV0X29iaihvYmplY3Qgb2IsIG9iamVjdCB3aGVyZSkKKyAgaW50IGdpdmVfb2JqKG9iamVjdCBvYiwgb2JqZWN0IHdoZXJlKQorICAgIHNpZWhlIE1hbnBhZ2VzCisKKyovCisKKy8qCisgIDIxLiBPa3QgMTk5OCBrb21wbGV0dGUgbmV1IHByb2dyYW1taWVydW5nIHZvbiBwdXRfYW5kX2dldC5jIChQYWRyZWljKQorLSBkaWUgR3J1cHBlbmF1c3dhaGxlbiBhbGxlcywgd2FmZmVuIHVuZCBydWVzdHVuZ2VuIHNpbmQgamV0enQgaW1tZXIgbW9lZ2xpY2gKKyAgZGllIEdydXBwZW4gc2luZCBzZWhyIGxlaWNodCBlcndlaXRlcmJhciB1bmQgbWFuIHNvbGx0ZSBzaWNoIG5pY2h0IHNjaGV1ZW4KKyAgZGF2b24gZ2VicmF1Y2ggenUgbWFjaGVuLi4uCistIG1pdCAiaW4gbWlyIiB1bmQgImltIHJhdW0iIGthbm4gbWFuIGRlbiBhYnp1c3VjaGVuZGVuIFJhdW0gc2VsYnN0IGVpbmdyZW56ZW4KKy0gbWl0ICJhbGxlfGplZGV8amVkZW58amVkZXMgPGlkPiIga2FubiBtYW4gYXVjaCBnYW56ZSBvYmpla3RncnVwcGVuIGF1c3dhZWhsZW4KKyovCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPGNvbnRhaW5lci5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKworI2RlZmluZSBUTUUoc3RyKSB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLCBcCisgICAgYnJlYWtfc3RyaW5nKHN0ciwgNzgsIDAsIEJTX0xFQVZFX01ZX0xGUykpCisjZGVmaW5lIFRPQihvYixzdHIpIHRlbGxfb2JqZWN0KG9iLCBicmVha19zdHJpbmcoc3RyLCA3OCwgMCwgQlNfTEVBVkVfTVlfTEZTKSkKKyNkZWZpbmUgU0FZKHN0cikgdGVsbF9yb29tKGVudmlyb25tZW50KCksIFwKKyAgICBicmVha19zdHJpbmcoc3RyLCA3OCwgMCwgQlNfTEVBVkVfTVlfTEZTKSwgKHt0aGlzX29iamVjdCgpfSkpCisjZGVmaW5lIFNBWTIob2JzLCBzdHIpIHRlbGxfcm9vbShlbnZpcm9ubWVudCgpLCBcCisgICAgYnJlYWtfc3RyaW5nKHN0ciwgNzgsIDAsIEJTX0xFQVZFX01ZX0xGUyksICh7dGhpc19vYmplY3QoKX0pICsgb2JzKQorI2RlZmluZSBORihzdHIpIF9ub3RpZnlfZmFpbChicmVha19zdHJpbmcoc3RyLCA3OCwgMCwgQlNfTEVBVkVfTVlfTEZTKSkKKworcHJpdmF0ZSBub3NhdmUgY2xvc3VyZSBjbDsKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyB3ZW4wLCB3ZW4xLCB3ZXIwOworcHJpdmF0ZSBub3NhdmUgb2JqZWN0ICpsYXN0X21vdmVkX29iamVjdHM7Citwcml2YXRlIG5vc2F2ZSBvYmplY3QgbGFzdF9tb3ZlZF93aGVyZTsKKworCisvKioqKioqKioqKioqKioqKioqKioqKiogRGllIGVpZ2VudGxpY2hlbiBGdW5rdGlvbmVuICoqKioqKioqKioqKioqKioqKioqKioqKi8KKworcHJpdmF0ZSBzdHJpbmcgcHV0X29yX2dldChvYmplY3Qgbywgb2JqZWN0IGRlc3QpCisKKy8qIEJld2VndCBlaW4gZWluemVsbmVzIE9iamVrdCA8bz4gaW4gZGFzIFppZWxvYmpla3QgPGRlc3Q+LiBWZXJ3ZW5kZXQgZGF6dQorICogamUgbmFjaCBVbXN0YWVuZGVuIChaaWVsIGlzdCBkZXIgU3BpZWxlciwgZGllIFVtZ2VidW5nLCBlaW4gTGViZXdlc2VuKSBkZW4KKyAqIGVudHNwcmVjaGVuZGVuIFdlcnQgZnVlciA8bWV0aG9kPi4gR2lidCBpbSBFcmZvbGdzZmFsbCAwIHp1cnVlY2ssIGVyc3RlbGx0CisgKiBzb25zdCBkaWUgYXVzenVnZWJlbmRlIEZlaGxlcm1lbGR1bmcgdW5kIGdpYnQgZGllc2UgenVydWVjay4KKyAqLworCit7CisgICAgaW50IG1ldGhvZCwgcmV0OworICAgIHN0cmluZyBzdHI7CisKKyAgICAvL2lmIChsaXZpbmcobykpCisgICAgLy8gICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiTGViZW5kZXMgQXJndW1lbnQgZnVlciBwdXRfb3JfZ2V0OiAlT1xuIiwgbykpOworCisgICAgaWYgKGRlc3QgPT0gdGhpc19vYmplY3QoKSkgICAgICAgICAgLyogcGljayAqLworICAgICAgICBtZXRob2QgPSBNX0dFVDsKKyAgICBlbHNlIGlmIChkZXN0ID09IGVudmlyb25tZW50KCkpICAgICAvKiBkcm9wICovCisgICAgICAgIG1ldGhvZCA9IE1fUFVUOworICAgIGVsc2UgaWYgKGxpdmluZyhkZXN0KSkgICAgICAgICAgICAgIC8qIGdpdmUgKi8KKyAgICAgICAgbWV0aG9kID0gTV9HSVZFOworICAgIGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHB1dCAqLworICAgICAgICBtZXRob2QgPSBNX1BVVCB8IE1fR0VUOworICAgICAgICBpZiAoZmlyc3RfaW52ZW50b3J5KG8pKQorICAgICAgICAgICAgcmV0dXJuIG8tPk5hbWUoV0VSLCAxKSArICIgaXN0IG5pY2h0IGxlZXIhIjsKKyAgICB9CisKKyAgICBpZiAoKHJldCA9IG8tPm1vdmUoZGVzdCwgbWV0aG9kKSkgPiAwKQorICAgICAgICByZXR1cm4gMDsKKworICAgIHN3aXRjaCAocmV0KSB7CisgICAgICAgIGNhc2UgTUVfVE9PX0hFQVZZOgorICAgICAgICAgICAgaWYgKGRlc3QgPT0gdGhpc19vYmplY3QoKSkKKyAgICAgICAgICAgICAgICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gIkFscyBHZWlzdCBrYW5uc3QgRHUgbmljaHRzIG1pdG5laG1lbi4iOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuICJEdSBrYW5uc3QgIiArIHdlbjEgKyAiIG5pY2h0IG1laHIgdHJhZ2VuLiI7CisKKyAgICAgICAgICAgIGlmIChzdHJpbmdwKHN0ciA9IGRlc3QtPlF1ZXJ5UHJvcChQX1RPT19IRUFWWV9NU0cpKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZShyZXBsYWNlX3BlcnNvbmFsKHN0ciwgKHtvLCBkZXN0fSksIDEpKTsKKworICAgICAgICAgICAgaWYgKGxpdmluZyhkZXN0KSkgeworICAgICAgICAgICAgICAgIGlmIChkZXN0LT5RdWVyeVByb3AoUF9HSE9TVCkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAiQWxzIEdlaXN0IGthbm4gIiArIGRlc3QtPm5hbWUoV0VSLCAxKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiIG5pY2h0cyBtaXRuZWhtZW4uIjsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBkZXN0LT5OYW1lKFdFUiwgMSkgKyAiIGthbm4gIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZW4wICsgIiBuaWNodCBtZWhyIHRyYWdlbi4iOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoZGVzdCA9PSBlbnZpcm9ubWVudCgpKQorICAgICAgICAgICAgICAgIHJldHVybiAoc3RyaW5ncChzdHIgPSBkZXN0LT5OYW1lKFdFUiwgMSkpICYmIHNpemVvZihzdHIpID8KKyAgICAgICAgICAgICAgICAgICAgICAgIHN0ciA6ICJEZXIgUmF1bSIpICsgIiB3dWVyZGUgZGFubiB6dSBzY2h3ZXIgd2VyZGVuLiI7CisKKyAgICAgICAgICAgIHJldHVybiBjYXBpdGFsaXplKHdlcjAgKyAiIHBhc3N0IGluICIgKyBkZXN0LT5uYW1lKFdFTiwgMSkgKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBuaWNodCBtZWhyIHJlaW4uIik7CisKKyAgICAgICAgY2FzZSBNRV9DQU5UX0JFX0RST1BQRUQ6CisgICAgICAgICAgICBpZiAobyAmJiBzdHJpbmdwKHN0ciA9IG8tPlF1ZXJ5UHJvcChQX05PRFJPUCkpKQorICAgICAgICAgICAgICAgIHJldHVybiBzdHI7CisKKyAgICAgICAgICAgIGlmIChkZXN0ID09IGVudmlyb25tZW50KCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICJEdSBrYW5uc3QgIiArIHdlbjEgKyAiIG5pY2h0IHdlZ3dlcmZlbiEiOworCisgICAgICAgICAgICBpZiAobGl2aW5nKGRlc3QpKQorICAgICAgICAgICAgICAgIHJldHVybiAiRHUga2FubnN0ICIgKyB3ZW4xICsgIiBuaWNodCB3ZWdnZWJlbi4iOworCisgICAgICAgICAgICByZXR1cm4gIlNvIHdpcnN0IER1ICIgKyB3ZW4xICsgIiBuaWNodCBsb3MuLi4iOworCisgICAgICAgIGNhc2UgTUVfQ0FOVF9CRV9UQUtFTjoKKyAgICAgICAgICAgIGlmIChvICYmIHN0cmluZ3Aoc3RyID0gby0+UXVlcnlQcm9wKFBfTk9HRVQpKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gc3RyOworCisgICAgICAgICAgICBpZiAoc3RyaW5ncChzdHIgPSBlbnZpcm9ubWVudChvKS0+UXVlcnlQcm9wKFBfTk9MRUFWRV9NU0cpKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZSgKKyAgICAgICAgICAgICAgICAgICAgcmVwbGFjZV9wZXJzb25hbChzdHIsICh7bywgZW52aXJvbm1lbnQobyl9KSwgMSkpOworCisgICAgICAgICAgICAvL2lmIChkZXN0ICE9IGVudmlyb25tZW50KCkpCisgICAgICAgICAgICAvLyAgICByZXR1cm4gIkR1IGthbm5zdCAiICsgd2VuMSArICIgbmljaHQgZWlubWFsIG5laG1lbi4iOworCisgICAgICAgICAgICByZXR1cm4gIkR1IGthbm5zdCAiICsgd2VuMSArICIgbmljaHQgbmVobWVuLiI7CisKKyAgICAgICAgY2FzZSBNRV9DQU5UX0JFX0lOU0VSVEVEOgorICAgICAgICAgICAgaWYgKHN0cmluZ3Aoc3RyID0gZGVzdC0+UXVlcnlQcm9wKFBfTk9JTlNFUlRfTVNHKSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUocmVwbGFjZV9wZXJzb25hbChzdHIsICh7bywgZGVzdH0pLCAxKSk7CisKKyAgICAgICAgICAgIGlmIChkZXN0ID09IGVudmlyb25tZW50KCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICJEYXMgZGFyZnN0IER1IGhpZXIgbmljaHQgYWJsZWdlbi4iOworCisgICAgICAgICAgICBpZiAoZGVzdCA9PSB0aGlzX29iamVjdCgpKQorICAgICAgICAgICAgICAgIHJldHVybiAiRHUga2FubnN0ICIgKyB3ZW4xICsgIiBuaWNodCBuZWhtZW4uIjsKKworICAgICAgICAgICAgaWYgKGxpdmluZyhkZXN0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gIkRhcyBrYW5uc3QgRHUgIiArIGRlc3QtPm5hbWUoV0VNLCAxKSArICIgbmljaHQgZ2ViZW4uIjsKKworICAgICAgICAgICAgcmV0dXJuIGNhcGl0YWxpemUod2VuMCArICIga2FubnN0IER1IGRvcnQgbmljaHQgaGluZWluc3RlY2tlbi4iKTsKKworICAgICAgICBjYXNlIE1FX0NBTlRfTEVBVkVfRU5WOgorICAgICAgICAgICAgLy8gTUVfQ0FOVF9MRUFWRV9FTlYga2FubiBudXIgYXVmdHJldGVuLCB3ZW5uIG8gZWluIEVudmlyb25tZW50CisgICAgICAgICAgICAvLyBoYXQsIGRlc2hhbGIga2VpbiBDaGVjayBkYWRyYXVmCisgICAgICAgICAgICBpZiAoc3RyaW5ncChzdHIgPSBlbnZpcm9ubWVudChvKS0+UXVlcnlQcm9wKFBfTk9MRUFWRV9NU0cpKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZSgKKyAgICAgICAgICAgICAgICAgICAgcmVwbGFjZV9wZXJzb25hbChzdHIsICh7bywgZW52aXJvbm1lbnQobyl9KSwgMSkpOworCisgICAgICAgICAgICBpZiAoZW52aXJvbm1lbnQobykgIT0gdGhpc19vYmplY3QoKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gIkR1IGthbm5zdCAiICsgd2VuMSArICIgbmljaHQgbmVobWVuLiI7CisKKyAgICAgICAgICAgIGlmIChkZXN0ID09IGVudmlyb25tZW50KCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICJEdSBrYW5uc3QgIiArIHdlbjEgKyAiIG5pY2h0IHdlZ3dlcmZlbiEiOworCisgICAgICAgICAgICBpZiAobGl2aW5nKGRlc3QpKQorICAgICAgICAgICAgICAgIHJldHVybiAiRHUga2FubnN0ICIgKyB3ZW4xICsgIiBuaWNodCB3ZWdnZWJlbi4iOworCisgICAgICAgICAgICByZXR1cm4gIlNvIHdpcnN0IER1ICIgKyB3ZW4xICsgIiBuaWNodCBsb3MuLi4iOworCisgICAgICAgIGNhc2UgTUVfVE9PX0hFQVZZX0ZPUl9FTlY6CisgICAgICAgICAgICBpZiAoc3RyaW5ncChzdHIgPSBkZXN0LT5RdWVyeVByb3AoUF9FTlZfVE9PX0hFQVZZX01TRykpKQorICAgICAgICAgICAgICAgIHJldHVybiBjYXBpdGFsaXplKHJlcGxhY2VfcGVyc29uYWwoc3RyLCAoe28sIGRlc3R9KSwgMSkpOworCisgICAgICAgICAgICBpZiAoZW52aXJvbm1lbnQoZGVzdCkgPT0gdGhpc19vYmplY3QoKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gZGVzdC0+TmFtZShXRVIsIDEpICsKKyAgICAgICAgICAgICAgICAgICAgICAgIiB3dWVyZGUgRGlyIGRhbm4genUgc2Nod2VyIHdlcmRlbi4iOworCisgICAgICAgICAgICByZXR1cm4gKHN0cmluZ3Aoc3RyID0gZW52aXJvbm1lbnQoZGVzdCktPk5hbWUoV0VSLCAxKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICYmIHNpemVvZihzdHIpID8gc3RyIDogIkRlciBSYXVtIikgKworICAgICAgICAgICAgICAgICAgICAiIHd1ZXJkZSBkYW5uIHp1IHNjaHdlciB3ZXJkZW4uIjsKKworICAgICAgICBjYXNlIFRPT19NQU5ZX09CSkVDVFM6CisgICAgICAgICAgICBpZiAoc3RyaW5ncChzdHIgPSBkZXN0LT5RdWVyeVByb3AoUF9UT09fTUFOWV9NU0cpKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gY2FwaXRhbGl6ZShyZXBsYWNlX3BlcnNvbmFsKHN0ciwgKHtvLCBkZXN0fSksIDEpKTsKKworICAgICAgICAgICAgaWYgKGRlc3QgPT0gdGhpc19vYmplY3QoKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gIlNvdmllbGUgR2VnZW5zdGFlbmRlIGthbm5zdCBEdSB1bm1vZWdsaWNoIHRyYWdlbiEiOworCisgICAgICAgICAgICBpZiAoZGVzdCA9PSBlbnZpcm9ubWVudCgpKQorICAgICAgICAgICAgICAgIHJldHVybiAiRGFmdWVyIGlzdCBoaWVyIG5pY2h0IG1laHIgZ2VudWcgUGxhdHouIjsKKworICAgICAgICAgICAgaWYgKGxpdmluZyhkZXN0KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gZGVzdC0+TmFtZShXRVIsIDEpICsgIiBrYW5uICIgICsgd2VuMCArCisgICAgICAgICAgICAgICAgICAgICAgICIgbmljaHQgbWVociB0cmFnZW4uIjsKKworICAgICAgICAgICAgcmV0dXJuICJEYWZ1ZXIgaXN0IG5pY2h0IG1laHIgZ2VudWcgUGxhdHogaW4gIiArCisgICAgICAgICAgICAgICAgICAgZGVzdC0+bmFtZShXRU0sIDEpICsgIi4iOworCisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBpZiAoZGVzdCA9PSB0aGlzX29iamVjdCgpKQorICAgICAgICAgICAgICAgIHJldHVybiAiRHUga2FubnN0ICIgKyB3ZW4xICsgIiBuaWNodCBuZWhtZW4uIjsKKworICAgICAgICAgICAgaWYgKGRlc3QgPT0gZW52aXJvbm1lbnQoKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gIkR1IGthbm5zdCAiICsgd2VuMSArICIgbmljaHQgd2Vnd2VyZmVuISI7CisKKyAgICAgICAgICAgIGlmIChsaXZpbmcoZGVzdCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICJEdSBrYW5uc3QgIiArIHdlbjEgKyAiIG5pY2h0IHdlZ2dlYmVuLiI7CisKKyAgICAgICAgICAgIHJldHVybiBjYXBpdGFsaXplKHdlbjAgKyAiIGthbm5zdCBEdSBkb3J0IG5pY2h0IGhpbmVpbnN0ZWNrZW4uIik7CisgICAgfQorICAgIHJldHVybiAwOyAvLyBOT1QgUkVBQ0hFRAorfQorCisKKy8qIHZhcmFyZ3MgaW50IGRyb3Aob2JqZWN0IG8sIG1peGVkIG1zZykKKyAqIHZhcmFyZ3MgaW50IHB1dChvYmplY3Qgbywgb2JqZWN0IGRlc3QsIG1peGVkIG1zZykKKyAqIHZhcmFyZ3MgaW50IHBpY2sob2JqZWN0IG8sIG1peGVkIG1zZykKKyAqIHZhcmFyZ3MgaW50IGdpdmUob2JqZWN0IG8sIG9iamVjdCBkZXN0LCBtaXhlZCBtc2cpCisgKiB2YXJhcmdzIGludCBzaG93KG9iamVjdCBvLCBvYmplY3QgZGVzdCwgbWl4ZWQgbXNnKQorICoKKyAqIERlciBTcGllbGVyIG5pbW10L2xlZ3QvZ2lidC96ZWlndC9sYWVzc3QgZWluIE9iamVrdCBmYWxsZW4sIHdvYmVpIGRpZQorICogZW50c3ByZWNoZW5kZW4gb2RlciBvcHRpb25hbCBhYndlaWNoZW5kZSAoaW0gRm9ybWF0IHZvbiBQX1hYWF9NU0cpIG9kZXIKKyAqIGdhciBrZWluZSAobXNnID09IDEpIE1lbGR1bmdlbiBhdXNnZWdlYmVuIHdlcmRlbi4gRXMgbGllZ3QgaW4gZGVyCisgKiBWZXJhbnR3b3J0dW5nIGRlcyBSdWZlbmRlbiwgc2lubnZvbGxlIFdlcnRlIHp1IHVlYmVyZ2ViZW47IGluc2Jlc29uZGVyZQorICogd2lyZCBuaWNodCBnZXBydWVmdCwgb2Igc2ljaCBkaWUgT2JqZWt0ZSBpbiBkZXIgUmVpY2h3ZWl0ZSBkZXMgU3BpZWxlcnMKKyAqIGJlZmluZGVuLiBHaWJ0IDEgenVydWVjaywgd2VubiBkYXMgT2JqZWt0IGJld2VndCB3dXJkZSwgc29uc3QgMC4KKyAqLworCit2YXJhcmdzIGludCBkcm9wKG9iamVjdCBvLCBtaXhlZCBtc2cpCit7CisgICAgc3RyaW5nIHN0cjsKKworICAgIC8vIHZvcmhlciBzcGVpY2hlcm4sIGZhbGxzIGRhcyBPYmpla3QgemVyc3RvZXJ0IHdpcmQKKyAgICBjbCA9IHN5bWJvbF9mdW5jdGlvbigibmFtZSIsIG8pOworICAgIHdlbjAgPSBmdW5jYWxsKGNsLCBXRU4sIDApOworICAgIHdlbjEgPSBmdW5jYWxsKGNsLCBXRU4sIDEpOworICAgIHdlcjAgPSAwOworCisgICAgaWYgKCFtc2cpCisgICAgICAgIG1zZyA9IG8tPlF1ZXJ5UHJvcChQX0RST1BfTVNHKTsKKworICAgIGlmIChzdHIgPSBwdXRfb3JfZ2V0KG8sIGVudmlyb25tZW50KCkpKSB7CisgICAgICAgIFRNRShzdHIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAoIW1zZykgeworICAgICAgICBUTUUoIkR1IGxhZXNzdCAiICsgd2VuMSArICIgZmFsbGVuLiIpOworICAgICAgICBTQVkoTmFtZShXRVIsMSkgKyAiIGxhZXNzdCAiICsgd2VuMCArICIgZmFsbGVuLiIpOworICAgIH0gZWxzZSBpZiAocG9pbnRlcnAobXNnKSkKKyAgICAgICAgc3dpdGNoIChzaXplb2YobXNnKSkgeworICAgICAgICAgIC8vIFdlbm4gZXMgendlaSBTdHJpbmdzIGdpYnQsIGdlaHQgZGllIDIuIGFucyBFbnZpcm9ubWVudAorICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgIFNBWShyZXBsYWNlX3BlcnNvbmFsKG1zZ1sxXSwgKHt0aGlzX29iamVjdCgpLCBvfHx3ZW4wfSksIDEpKTsKKyAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICBUTUUocmVwbGFjZV9wZXJzb25hbChtc2dbMF0sICh7dGhpc19vYmplY3QoKSwgb3x8d2VuMX0pLCAxKSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICAgICAgICAiRmFsc2NoZXMgRm9ybWF0IGZ1ZXIgUF9EUk9QX01TRzogJU9cbiIsIG98fHdlbjEpKTsKKyAgICAgICAgfQorCisgICAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3MgaW50IHB1dChvYmplY3Qgbywgb2JqZWN0IGRlc3QsIG1peGVkIG1zZykKK3sKKyAgICBzdHJpbmcgc3RyOworCisgICAgLy8gRmFsbHMgZGFzIGplbWFuZCB2b24gYXVzc2VuIHJ1ZnQgdW5kIFNjaHJvdHQgdWViZXJnaWJ0Li4uCisgICAgLy9pZiAobGl2aW5nKGRlc3QpKQorICAgIC8vICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIkxlYmVuZGVzIFppZWwgZnVlciBwdXQoKTogJU9cbiIsIGRlc3QpKTsKKyAgICBpZiAoZGVzdCA9PSBlbnZpcm9ubWVudCgpKQorICAgICAgICByYWlzZV9lcnJvcigiWmllbCBmdWVyIHB1dCgpIGlzdCBVbWdlYnVuZyBkZXMgU3BpZWxlcnNcbiIpOworCisgICAgLy8gdm9yaGVyIHNwZWljaGVybiwgZmFsbHMgZGFzIE9iamVrdCB6ZXJzdG9lcnQgd2lyZAorICAgIGNsID0gc3ltYm9sX2Z1bmN0aW9uKCJuYW1lIiwgbyk7CisgICAgd2VuMCA9IGZ1bmNhbGwoY2wsIFdFTiwgMCk7CisgICAgd2VuMSA9IGZ1bmNhbGwoY2wsIFdFTiwgMSk7CisgICAgd2VyMCA9IGZ1bmNhbGwoY2wsIFdFUiwgMCk7CisKKyAgICBpZiAoIW1zZykKKyAgICAgICAgbXNnID0gby0+UXVlcnlQcm9wKFBfUFVUX01TRyk7CisKKyAgICBpZiAoc3RyID0gcHV0X29yX2dldChvLCBkZXN0KSkgeworICAgICAgICBUTUUoc3RyKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgIAorICAgIGlmICghbXNnKSB7CisgICAgICAgIFRNRSgiRHUgc3RlY2tzdCAiICsgd2VuMSArICIgaW4gIiArIGRlc3QtPm5hbWUoV0VOLCAxKSArICIuIik7CisgICAgICAgIGlmIChlbnZpcm9ubWVudCgpKQorCSAgU0FZKE5hbWUoV0VSLCAxKSArICIgc3RlY2t0ICIgKyB3ZW4wICsKKwkgICAgICAiIGluICIgKyBkZXN0LT5uYW1lKFdFTiwgMCkgKyAiLiIpOworICAgIH0KKyAgICBlbHNlIGlmIChwb2ludGVycChtc2cpKSB7CisgICAgICAgIHN3aXRjaCAoc2l6ZW9mKG1zZykpIHsKKyAgICAgICAgICBjYXNlIDI6CisgICAgICAgICAgICBpZiAoZW52aXJvbm1lbnQoKSkKKwkgICAgICBTQVkocmVwbGFjZV9wZXJzb25hbChtc2dbMV0sICh7dGhpc19vYmplY3QoKSwgb3x8d2VuMCwgZGVzdH0pLCAxKSk7CisgICAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgVE1FKHJlcGxhY2VfcGVyc29uYWwobXNnWzBdLCAoe3RoaXNfb2JqZWN0KCksIG98fHdlbjEsIGRlc3R9KSwgMSkpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICAgICAgICAgIkZhbHNjaGVzIEZvcm1hdCBmdWVyIFBfUFVUX01TRzogJU9cbiIsb3x8d2VuMSkpOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3MgaW50IHBpY2sob2JqZWN0IG8sIG1peGVkIG1zZykKK3sKKyAgICBzdHJpbmcgc3RyOworCisgICAgLy8gdm9yaGVyIHNwZWljaGVybiwgZmFsbHMgZGFzIE9iamVrdCB6ZXJzdG9lcnQgd2lyZAorICAgIGNsID0gc3ltYm9sX2Z1bmN0aW9uKCJuYW1lIiwgbyk7CisgICAgd2VuMCA9IDA7CisgICAgd2VuMSA9IGZ1bmNhbGwoY2wsIFdFTiwgMSk7CisgICAgd2VyMCA9IDA7CisKKyAgICBpZiAoIW1zZykKKyAgICAgICAgbXNnID0gby0+UXVlcnlQcm9wKFBfUElDS19NU0cpOworCisgICAgaWYgKHN0ciA9IHB1dF9vcl9nZXQobywgdGhpc19vYmplY3QoKSkpIHsKKyAgICAgICAgVE1FKHN0cik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICghbXNnKSB7CisgICAgICAgIFRNRSgiRHUgbmltbXN0ICIgKyB3ZW4xICsgIi4iKTsKKyAgICAgICAgU0FZKE5hbWUoV0VSLCAxKSArICIgbmltbXQgIiArIHdlbjEgKyAiLiIpOworICAgIH0gZWxzZSBpZiAocG9pbnRlcnAobXNnKSkKKyAgICAgICAgc3dpdGNoIChzaXplb2YobXNnKSkgeworICAgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgIFNBWShyZXBsYWNlX3BlcnNvbmFsKG1zZ1sxXSwgKHt0aGlzX29iamVjdCgpLCBvfHx3ZW4xfSksIDEpKTsKKyAgICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICBUTUUocmVwbGFjZV9wZXJzb25hbChtc2dbMF0sICh7dGhpc19vYmplY3QoKSwgb3x8d2VuMX0pLCAxKSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICAgICAgICAiRmFsc2NoZXMgRm9ybWF0IGZ1ZXIgUF9QSUNLX01TRzogJU9cbiIsIG98fHdlbjEpKTsKKyAgICAgICAgfQorCisgICAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3MgaW50IGdpdmUob2JqZWN0IG8sIG9iamVjdCBkZXN0LCBtaXhlZCBtc2cpCit7CisgICAgc3RyaW5nIHpuYW1lLCBnbmFtZTsKKyAgICBzdHJpbmcgc3RyOworCisgICAgLy8gRmFsbHMgZGFzIGplbWFuZCB2b24gYXVzc2VuIHJ1ZnQgdW5kIFNjaHJvdHQgdWViZXJnaWJ0Li4uCisgICAgaWYgKCFsaXZpbmcoZGVzdCkpCisgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIlRvdGVzIFppZWwgZnVlciBnaXZlKCk6ICVPXG4iLCBkZXN0KSk7CisKKyAgICB6bmFtZSA9IGRlc3QtPm5hbWUoV0VNLCAxKTsKKyAgICBnbmFtZSA9IE5hbWUoV0VSLCAxKTsKKworICAgIC8vIHZvcmhlciBzcGVpY2hlcm4sIGZhbGxzIGRhcyBPYmpla3QgemVyc3RvZXJ0IHdpcmQKKyAgICBjbCA9IHN5bWJvbF9mdW5jdGlvbigibmFtZSIsIG8pOworICAgIHdlbjAgPSBmdW5jYWxsKGNsLCBXRU4sIDApOworICAgIHdlbjEgPSBmdW5jYWxsKGNsLCBXRU4sIDEpOworICAgIHdlcjAgPSAwOworCisgICAgaWYgKCFtc2cpCisgICAgICAgIG1zZyA9IG8tPlF1ZXJ5UHJvcChQX0dJVkVfTVNHKTsKKworICAgIGlmIChzdHIgPSBwdXRfb3JfZ2V0KG8sIGRlc3QpKSB7CisgICAgICAgIFRNRShzdHIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAoIW1zZykgeworICAgICAgICBUTUUoIkR1IGdpYnN0ICIgKyB6bmFtZSArICIgIiArIHdlbjEgKyAiLiIpOworICAgICAgICBUT0IoZGVzdCwgZ25hbWUgKyAiIGdpYnQgRGlyICIgKyB3ZW4wICsgIi4iKTsKKyAgICAgICAgU0FZMigoe2Rlc3R9KSwgZ25hbWUgKyAiIGdpYnQgIiArIHpuYW1lICsgIiAiICsgd2VuMCArICIuIik7CisgICAgfSBlbHNlIGlmIChwb2ludGVycChtc2cpKQorICAgICAgICBzd2l0Y2ggKHNpemVvZihtc2cpKSB7CisgICAgICAgICAgY2FzZSAzOgorICAgICAgICAgICAgVE9CKGRlc3QsIHJlcGxhY2VfcGVyc29uYWwoCisgICAgICAgICAgICAgICAgbXNnWzJdLCAoe3RoaXNfb2JqZWN0KCksIG98fHdlbjAsIGRlc3R8fHpuYW1lfSksIDEpKTsKKyAgICAgICAgICBjYXNlIDI6CisgICAgICAgICAgICBTQVkyKCh7ZGVzdCwgdGhpc19vYmplY3QoKX0pLCByZXBsYWNlX3BlcnNvbmFsKAorICAgICAgICAgICAgICAgICBtc2dbMV0sICh7dGhpc19vYmplY3QoKSwgb3x8d2VuMCwgZGVzdHx8em5hbWV9KSwgMSkpOworICAgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgIFRNRShyZXBsYWNlX3BlcnNvbmFsKAorICAgICAgICAgICAgICAgIG1zZ1swXSwgKHt0aGlzX29iamVjdCgpLCBvfHx3ZW4xLCBkZXN0fHx6bmFtZX0pLCAxKSk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKKyAgICAgICAgICAgICAgICAiRmFsc2NoZXMgRm9ybWF0IGZ1ZXIgUF9HSVZFX01TRzogJU9cbiIsIG98fHdlbjEpKTsKKyAgICAgICAgfQorCisgICAgaWYgKCFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGRlc3QpKQorICAgICAgICBkZXN0LT5naXZlX25vdGlmeShvKTsKKworICAgIHJldHVybiAxOworfQorCit2YXJhcmdzIGludCBzaG93KG9iamVjdCBvLCBvYmplY3Qgd2hvbSwgbWl4ZWQgbXNnKQoreworICAgIHN0cmluZyB6bmFtZSwgZ25hbWU7CisgICAgc3RyaW5nIHdlbjAsIHdlbjIsIGxvbmc7CisKKyAgICB6bmFtZSA9IHdob20gPyB3aG9tLT5uYW1lKFdFTSwgMSkgOiAiYWxsZW4iOworICAgIGduYW1lID0gTmFtZShXRVIsIDEpOworCisgICAgaWYgKCFtc2cpCisgICAgICAgIG1zZyA9IG8tPlF1ZXJ5UHJvcChQX1NIT1dfTVNHKTsKKworICAgIGlmIChlbnZpcm9ubWVudChvKSA9PSB0aGlzX29iamVjdCgpIHx8CisgICAgICAgIGVudmlyb25tZW50KGVudmlyb25tZW50KG8pKSA9PSB0aGlzX29iamVjdCgpKSB7CisgICAgICAgIHdlbjAgPSBvLT5uYW1lKFdFTiwgMCk7CisKKyAgICAgICAgLyogRGVyIEFra3VzYXRpdiBtdXNzIG1pdCBkZW0gdW5iZXN0aW1tdGVuIEFydGlrZWwgZ2ViaWxkZXQgd2VyZGVuLAorICAgICAgICAgKiBkYW1pdCBldmVudHVlbGxlIEFkamVrdGl2ZSBkaWUgcmljaHRpZ2UgRW5kdW5nIGJlc2l0emVuLgorICAgICAgICAgKiAoZWluIGtsZWluZXMgU2Nod2VydCAtPiBrbGVpbmVzIFNjaHdlcnQgLT4gRGVpbiBrbGVpbmVzIFNjaHdlcnQpCisgICAgICAgICAqLworCisgICAgICAgIGlmIChvLT5RdWVyeVByb3AoUF9BUlRJQ0xFKSAmJiBtZW1iZXIod2VuMCwgJyAnKSA+PSAwKSB7CisgICAgICAgICAgICBpbnQgb2JnZW5kZXIgPSBvLT5RdWVyeVByb3AoUF9HRU5ERVIpOworICAgICAgICAgICAgaW50IG9ibnVtID0gby0+UXVlcnlQcm9wKFBfQU1PVU5UKSA+IDEgPyBQTFVSQUwgOiBTSU5HVUxBUjsKKworICAgICAgICAgICAgLy8gV2ljaHRpZzogUF9BTU9VTlQgaXN0IDAgZnVlciBPYmpla3RlLCBkaWUgbmljaHQgdm9uIHVuaXQgZXJiZW4uCisgICAgICAgICAgICAvLyBEYSB1bml0LmMga2VpbiBQX0FNT1VOVD09MCB6dWxhZXNzdCwgbmVobWVuIHdpciBkaWVzZW4gRmFsbCBhbHMKKyAgICAgICAgICAgIC8vIHNpbmd1bGFyIGFuLiAqUnVtYXRhCisKKyAgICAgICAgICAgIHdlbjIgPSB3ZW4wW21lbWJlcih3ZW4wLCAnICcpLi5dOworICAgICAgICAgICAgd2VuMCA9IFF1ZXJ5UG9zc1Byb25vdW4obywgV0VOLCBvYm51bSkgKyB3ZW4yOworCisgICAgICAgICAgICBpZiAob2JudW0gPT0gUExVUkFMIHx8IG9iZ2VuZGVyID09IEZFTUFMRSkKKyAgICAgICAgICAgICAgICB3ZW4yID0gIkRlaW5lIiArIHdlbjI7CisgICAgICAgICAgICBlbHNlIGlmIChvYmdlbmRlciA9PSBNQUxFKQorICAgICAgICAgICAgICAgIHdlbjIgPSAiRGVpbmVuIiArIHdlbjI7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgd2VuMiA9ICJEZWluIiArIHdlbjI7CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgd2VuMiA9IHdlbjA7CisgICAgfSBlbHNlCisgICAgICAgIHdlbjIgPSB3ZW4wID0gby0+bmFtZShXRU4sIDEpOworCisgICAgLy8gdm9yaGVyIHNwZWljaGVybiwgZmFsbHMgZGFzIE9iamVrdCBpbSBjYXRjaF90ZWxsKCkgemVyc3RvZXJ0IHdpcmQKKyAgICBsb25nID0gby0+bG9uZyg0KTsKKworICAgIGlmICghbXNnKSB7CisgICAgICAgIFRNRSgiRHUgemVpZ3N0ICIgKyB6bmFtZSArICIgIiArIHdlbjIgKyAiLiIpOworICAgICAgICBpZiAoIXdob20pCisgICAgICAgICAgICBTQVkoZ25hbWUgKyAiIHplaWd0IERpciAiICsgd2VuMCArICIuIik7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgVE9CKHdob20sIGduYW1lICsgIiB6ZWlndCBEaXIgIiArIHdlbjAgKyAiLiIpOworICAgICAgICAgICAgU0FZMigoe3dob219KSwgZ25hbWUgKyAiIHplaWd0ICIgKyB6bmFtZSArICIgIiArIHdlbjAgKyAiLiIpOworICAgICAgICB9CisgICAgfSBlbHNlIGlmIChwb2ludGVycChtc2cpKQorICAgICAgICBzd2l0Y2ggKHNpemVvZihtc2cpKSB7CisgICAgICAgICAgY2FzZSAzOgorICAgICAgICAgICAgaWYgKHdob20pCisgICAgICAgICAgICAgICAgVE9CKHdob20sIHJlcGxhY2VfcGVyc29uYWwoCisgICAgICAgICAgICAgICAgICAgIG1zZ1syXSwgKHt0aGlzX29iamVjdCgpLCBvfHx3ZW4wLCB3aG9tfHx6bmFtZX0pLCAxKSk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgU0FZKHJlcGxhY2VfcGVyc29uYWwoCisgICAgICAgICAgICAgICAgICAgIG1zZ1syXSwgKHt0aGlzX29iamVjdCgpLCBvfHx3ZW4wLCB3aG9tfHx6bmFtZX0pLCAxKSk7CisgICAgICAgICAgY2FzZSAyOgorICAgICAgICAgICAgaWYgKHdob20pCisgICAgICAgICAgICAgICAgU0FZMigoe3dob20sIHRoaXNfb2JqZWN0KCl9KSwgcmVwbGFjZV9wZXJzb25hbCgKKyAgICAgICAgICAgICAgICAgICAgIG1zZ1sxXSwgKHt0aGlzX29iamVjdCgpLCBvfHx3ZW4wLCB3aG9tfHx6bmFtZX0pLCAxKSk7CisgICAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgVE1FKHJlcGxhY2VfcGVyc29uYWwoCisgICAgICAgICAgICAgICAgbXNnWzBdLCAoe3RoaXNfb2JqZWN0KCksIG98fHdlbjIsIHdob218fHpuYW1lfSksIDEpKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAgICAgICJGYWxzY2hlcyBGb3JtYXQgZnVlciBQX1NIT1dfTVNHOiAlT1xuIiwgb3x8d2VuMCkpOworICAgICAgICB9CisKKyAgICBpZiAoIXdob20pCisgICAgICAgIFNBWShsb25nKTsKKyAgICBlbHNlIHsKKyAgICAgICAgVE9CKHdob20sIGxvbmcpOworICAgICAgICBpZiAoIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUod2hvbSkpCisgICAgICAgICAgICB3aG9tLT5zaG93X25vdGlmeShvKTsKKyAgICB9CisKKyAgICByZXR1cm4gMTsKK30KKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogSGlsZnNmdW5rdGlvbmVuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKiBwcml2YXRlIG9iamVjdCAqX19maW5kX29iamVjdHMoc3RyaW5nICp0b2tlbnMsIG9iamVjdCBlbnYsIGludCBpc19zb3VyY2UpOworICogb2JqZWN0ICpmaW5kX29iamVjdHMoc3RyaW5nIHdoYXQsIG9iamVjdCBlbnYsIGludCBpc19zb3VyY2UpOworICoKKyAqIFN1Y2h0IGltIFJhdW0gdW5kIGltIFNwaWVsZXIgKG9kZXIgYWx0ZXJuYXRpdiBpbiBkZXIgYW5nZWdlYmVuZW4gVW1nZWJ1bmcpCisgKiBuYWNoIGRlbiBpbiB0b2tlbnMvd2hhdCBiZXplaWNobmV0ZW4gT2JqZWt0ZW4uIGlzX3NvdXJjZSBiZXN0aW1tdCBkaWUKKyAqIGVyd2FydGV0ZSBncmFtbWF0aXNjaGUgRm9ybSAoMCBmdWVyICJ0b3BmIGF1ZiBoZXJkIiB1bmQgMSBmdWVyICJ0b3BmIHZvbgorICogaGVyZCIsIHNpZWhlIE1hbnBhZ2UpLgorICovCisgCitwcml2YXRlIG9iamVjdCAqX19maW5kX29iamVjdHMoc3RyaW5nICp0b2tlbnMsIG9iamVjdCBlbnYsIGludCBpc19zb3VyY2UpCit7CisgICAgb2JqZWN0IG9iLCAqb2JzOworCisgICAgLy8gaXNfc291cmNlID09IDA6IE9iamVrdCBzb2xsIG5pY2h0IGJld2VndCB3ZXJkZW4gKCJ0b3BmIGF1ZiBoZXJkIikKKyAgICAvLyAgICAgICAgICAgICAgMTogT2JqZWt0IHNvbGwgYmV3ZWd0IHdlcmRlbiAoInRvcGYgdm9uIGhlcmQiKQorICAgIC8vICAgICAgICAgICAgICAyOiBpbnRlcm4KKworICAgIGlmICghZW52ICYmIHNpemVvZih0b2tlbnMpID4gMSAmJiB0b2tlbnNbPDFdID09ICJoaWVyIikgeworICAgICAgICB0b2tlbnMgPSB0b2tlbnNbLi48Ml07CisgICAgICAgIGVudiA9IGVudmlyb25tZW50KCk7CisgICAgfQorICAgIGVsc2UgaWYgKCFlbnYgJiYgc2l6ZW9mKHRva2VucykgPiAyICYmIHRva2Vuc1s8Ml0gPT0gImluIikKKyAgICB7CisgICAgICAgIGlmICh0b2tlbnNbPDFdID09ICJtaXIiIHx8CisgICAgICAgICAgICB0b2tlbnNbPDFdID09ICJkaXIiKSB7CisgICAgICAgICAgICB0b2tlbnMgPSB0b2tlbnNbLi48M107CisgICAgICAgICAgICBlbnYgPSB0aGlzX29iamVjdCgpOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKHRva2Vuc1s8MV0gPT0gInJhdW0iKSB7CisgICAgICAgICAgICB0b2tlbnMgPSB0b2tlbnNbLi48M107CisgICAgICAgICAgICBlbnYgPSBlbnZpcm9ubWVudCgpOworICAgICAgICB9CisgICAgfQorCisgICAgZm9yIChpbnQgaSA9IHNpemVvZih0b2tlbnMpLTE7IGkgPiAxOyBpLS0pIHsKKyAgICAgICAgaWYgKGVudikKKyAgICAgICAgICAgIG9iID0gcHJlc2VudChpbXBsb2RlKHRva2Vuc1tpLi5dLCAiICIpLCBlbnYpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBvYiA9IHByZXNlbnQoaW1wbG9kZSh0b2tlbnNbaS4uXSwgIiAiKSwgZW52aXJvbm1lbnQoKSkgfHwKKyAgICAgICAgICAgICAgICAgcHJlc2VudChpbXBsb2RlKHRva2Vuc1tpLi5dLCAiICIpLCB0aGlzX29iamVjdCgpKTsKKworICAgICAgICBpZiAoIW9iKQorICAgICAgICAgICAgY29udGludWU7CisKKyAgICAgICAgaWYgKGxpdmluZyhvYikpIHsKKyAgICAgICAgICAgIE5GKCJBYmVyICIgKyBvYi0+bmFtZShXRVIsIDEpICsgIiBsZWJ0IGRvY2ghIik7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChvYi0+UXVlcnlQcm9wKFBfQ05UX1NUQVRVUykpIHsKKyAgICAgICAgICAgIE5GKCJBYmVyICIgKyBvYi0+bmFtZShXRVIsIDEpICsgIiBpc3QgZG9jaCBnZXNjaGxvc3NlbiEiKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKGlzX3NvdXJjZSAhPSAwICYmCisgICAgICAgICAgICB0b2tlbnNbaS0xXSA9PSBvYi0+UXVlcnlQcm9wKFBfU09VUkNFX1BSRVBPU0lUSU9OKSkKKyAgICAgICAgICAgIHJldHVybiBvYi0+cHJlc2VudF9vYmplY3RzKGltcGxvZGUodG9rZW5zWy4uaS0yXSwgIiAiKSk7CisKKyAgICAgICAgaWYgKHRva2Vuc1tpLTFdID09IG9iLT5RdWVyeVByb3AoUF9QUkVQT1NJVElPTikpCisgICAgICAgICAgICByZXR1cm4gX19maW5kX29iamVjdHModG9rZW5zWy4uaS0yXSwgb2IsIGlzX3NvdXJjZSA/IDIgOiAwKTsKKworICAgICAgICBORigiRHUga2FubnN0IG5pY2h0cyAiICsgdG9rZW5zW2ktMV0gKyAiICIgKworICAgICAgICAgICBvYi0+bmFtZShXRU0sIDEpICsgIiBuZWhtZW4uIik7CisgICAgfQorCisgICAgaWYgKGlzX3NvdXJjZSA9PSAyKQorICAgICAgICByZXR1cm4gKHt9KTsKKworICAgIGlmIChlbnYpCisgICAgICAgIHJldHVybiBlbnYtPnByZXNlbnRfb2JqZWN0cyhpbXBsb2RlKHRva2VucywgIiAiKSk7CisKKyAgICBpZiAoZW52aXJvbm1lbnQoKSAmJgorICAgICAgICBzaXplb2Yob2JzID0gZW52aXJvbm1lbnQoKS0+cHJlc2VudF9vYmplY3RzKGltcGxvZGUodG9rZW5zLCAiICIpKSkpCisgICAgICAgIHJldHVybiBvYnM7CisKKyAgICByZXR1cm4gcHJlc2VudF9vYmplY3RzKGltcGxvZGUodG9rZW5zLCAiICIpKTsKK30KKworb2JqZWN0ICpmaW5kX29iamVjdHMoc3RyaW5nIHdoYXQsIG9iamVjdCBlbnYsIGludCBpc19zb3VyY2UpCit7CisgIGlmICghc3RyaW5ncCh3aGF0KSB8fCAhc2l6ZW9mKHdoYXQpKQorICAgIHJldHVybiAoe30pOworICByZXR1cm4gX19maW5kX29iamVjdHMoZXhwbG9kZSh3aGF0LCAiICIpLCBlbnYsIGlzX3NvdXJjZSk7Cit9CisKKworLyogdmFyYXJncyBpbnQgZHJvcF9vYmplY3RzKHN0cmluZyBzdHIsIG1peGVkIG1zZyk7CisgKiB2YXJhcmdzIGludCBwdXRfb2JqZWN0cyhzdHJpbmcgc3RyLCBpbnQgY2FzdXMsIHN0cmluZyB2ZXJiLCBtaXhlZCBtc2cpOworICogdmFyYXJncyBpbnQgcGlja19vYmplY3RzKHN0cmluZyBzdHIsIGludCBmbGFnLCBtaXhlZCBtc2cpOworICogdmFyYXJncyBpbnQgZ2l2ZV9vYmplY3RzKHN0cmluZyBzdHIsIG1peGVkIG1zZyk7CisgKiB2YXJhcmdzIGludCBzaG93X29iamVjdHMoc3RyaW5nIHN0ciwgbWl4ZWQgbXNnKTsKKyAqCisgKiBFaW4gQmVmZWhsIHdpZSAid2lyZiB3YWZmZW4gd2VnIiByZXN1bHRpZXJ0IGluIGVpbmVtIEF1ZnJ1ZiB2b24KKyAqIGRyb3Bfb2JqZWN0cygid2FmZmVuIikuIERpZXNlIEZ1bmt0aW9uZW4gc2luZCBoYXVwdHNhZWNobGljaCBmdWVyIGRpZQorICogQmVoYW5kbHVuZyBkZXIgamV3ZWlsaWdlbiBLb21tYW5kb3Mgdm9yZ2VzZWhlbiwga29lbm5lbiBqZWRvY2ggYXVjaCBmdWVyCisgKiBlaWdlbmUgQmVmZWhsZSB2ZXJ3ZW5kZXQgd2VyZGVuLiBwdXRfb2JqZWN0cygpIGVyd2FydGV0IGF1c3NlcmRlbSBkZW4KKyAqIEthc3VzICgiRHUga2FubnN0IG5pY2h0cyBhbiBERVIgUGlud2FuZCBiZWZlc3RpZ2VuLiIpIHVuZCBkYXMgdmVyd2VuZGV0ZQorICogVmVyYiBpbiBkZXIgR3VuZGZvcm0gKCJiZWZlc3RpZ2VuIikuIERhcyBGbGFnIGZ1ZXIgcGlja19vYmplY3RzKCkgZ2lidAorICogYW4sIG9iIGRhcyBPYmpla3QgYXVjaCBlaW5mYWNoIGhlcnVtbGllZ2VuIGRhcmYgKCJuaW1tIC4uLiIpIG9kZXIgbmljaHQKKyAqICgiaG9sZSAuLi4iKS4gR2lidCBiZWkgRXJmb2xnIDEsIHNvbnN0IDAgenVydWVjay4KKyAqLworCit2YXJhcmdzIGludCBkcm9wX29iamVjdHMoc3RyaW5nIHN0ciwgbWl4ZWQgbXNnKQoreworICAgIG9iamVjdCAqb2JzOworCisgICAgaWYgKCFzaXplb2Yob2JzID0gZmluZF9vYmplY3RzKHN0ciwgdGhpc19vYmplY3QoKSwgMSkpKQorICAgICAgICByZXR1cm4gMDsKKworICAgIGZvcmVhY2ggKG9iamVjdCBvOiBvYnMpIHsKKyAgICAgICAgaWYgKG9iamVjdHAobykpCisgICAgICAgICAgICBkcm9wKG8sIG1zZyk7CisKKyAgICAgICAgaWYgKGdldF9ldmFsX2Nvc3QoKSA8IDEwMDAwMCkgeworICAgICAgICAgICAgVE1FKCJEZW4gUmVzdCBiZWhhZWx0c3QgRHUgZXJzdCBtYWwuIik7CisgICAgICAgICAgICBsYXN0X21vdmVkX29iamVjdHMgPSBvYnNbLi5tZW1iZXIob2JzLCBvKV07CisgICAgICAgICAgICBsYXN0X21vdmVkX3doZXJlID0gMDsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgfQorCisgICAgbGFzdF9tb3ZlZF9vYmplY3RzID0gb2JzOworICAgIGxhc3RfbW92ZWRfd2hlcmUgPSAwOworICAgIHJldHVybiAxOworfQorCit2YXJhcmdzIGludCBwdXRfb2JqZWN0cyhzdHJpbmcgc3RyLCBpbnQgY2FzdXMsIHN0cmluZyB2ZXJiLCBtaXhlZCBtc2cpCit7CisgICAgb2JqZWN0ICpvYnMsIGRlc3QsICpub19tb3ZlOworICAgIAorICAgIGlmICghc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSkgcmV0dXJuIDA7CisKKyAgICBzdHJpbmcgKnRva2VucyA9IGV4cGxvZGUoc3RyLCAiICIpOworICAgIGludCBhbGxvd19yb29tID0gMTsKKyAgICBpbnQgYWxsb3dfbWUgPSAxOworCisgICAgaWYgKHNpemVvZih0b2tlbnMpID4gMSAmJiB0b2tlbnNbPDFdID09ICJoaWVyIikgeworICAgICAgICB0b2tlbnMgPSB0b2tlbnNbLi48Ml07CisgICAgICAgIGFsbG93X21lID0gMDsKKyAgICB9IGVsc2UgaWYgKHNpemVvZih0b2tlbnMpID4gMiAmJiB0b2tlbnNbPDJdID09ICJpbiIpCisgICAgICAgIGlmICh0b2tlbnNbPDFdID09ICJtaXIiIHx8CisgICAgICAgICAgICB0b2tlbnNbPDFdID09ICJkaXIiKSB7CisgICAgICAgICAgICB0b2tlbnMgPSB0b2tlbnNbLi48M107CisgICAgICAgICAgICBhbGxvd19yb29tID0gMDsKKyAgICAgICAgfSBlbHNlIGlmICh0b2tlbnNbPDFdID09ICJyYXVtIikgeworICAgICAgICAgICAgdG9rZW5zID0gdG9rZW5zWy4uPDNdOworICAgICAgICAgICAgYWxsb3dfbWUgPSAwOworICAgICAgICB9CisKKyAgICBmb3IgKGludCBpID0gc2l6ZW9mKHRva2VucyktMTsgaSA+IDE7IGktLSkgeworICAgICAgICBpZiAoIShkZXN0ID0gYWxsb3dfcm9vbSAmJiBwcmVzZW50KGltcGxvZGUodG9rZW5zW2kuLl0sICIgIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQoKSkpICYmCisgICAgICAgICAgICAhKGRlc3QgPSBhbGxvd19tZSAmJiBwcmVzZW50KGltcGxvZGUodG9rZW5zW2kuLl0sICIgIiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfb2JqZWN0KCkpKSkKKyAgICAgICAgICAgIGNvbnRpbnVlOworCisgICAgICAgIGlmIChsaXZpbmcoZGVzdCkpIHsKKyAgICAgICAgICAgIE5GKCJBYmVyICIgKyBkZXN0LT5uYW1lKFdFUiwgMSkgKyAiIGxlYnQgZG9jaCEiKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisvKgorICAgICAgICBpZiAodmVyYiA9PSAibGVnZW4iICYmICFkZXN0LT5RdWVyeVByb3AoUF9UUkFZKSkgeworICAgICAgICAgICAgTkYoIkR1IGthbm5zdCBuaWNodHMgYXVmICIgKyBkZXN0LT5uYW1lKFdFTiwgMSkgKyAiIGxlZ2VuLiIpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyovCisgICAgICAgIGlmICh2ZXJiID09ICJzdGVja2VuIiAmJiAhZGVzdC0+UXVlcnlQcm9wKFBfQ09OVEFJTkVSKSkgeworICAgICAgICAgICAgTkYoIkR1IGthbm5zdCBpbiAiICsgZGVzdC0+bmFtZShXRU4sIDEpICsgIiBuaWNodHMgcmVpbnN0ZWNrZW4uIik7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChkZXN0LT5RdWVyeVByb3AoUF9DTlRfU1RBVFVTKSkgeworICAgICAgICAgICAgTkYoIkFiZXIgIiArIGRlc3QtPm5hbWUoV0VSLCAxKSArICIgaXN0IGRvY2ggZ2VzY2hsb3NzZW4hIik7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh0b2tlbnNbaS0xXSAhPSBkZXN0LT5RdWVyeVByb3AoUF9ERVNUX1BSRVBPU0lUSU9OKSkgeworICAgICAgICAgICAgTkYoIkR1IGthbm5zdCBuaWNodHMgIiArIHRva2Vuc1tpLTFdICsgIiAiICsKKyAgICAgICAgICAgICAgIGRlc3QtPm5hbWUoY2FzdXMsIDEpICsgIiAiICsgdmVyYiArICIuIik7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghc2l6ZW9mKG9icyA9IF9fZmluZF9vYmplY3RzKHRva2Vuc1suLmktMl0sIDAsIDEpIC0gKHsgZGVzdCB9KSkpIHsKKyAgICAgICAgICAgIE5GKCJXQVMgbW9lY2h0ZXN0IER1ICIgKyB0b2tlbnNbaS0xXSArICIgIiArCisgICAgICAgICAgICAgICBkZXN0LT5uYW1lKGNhc3VzLCAxKSArICIgIiArIHZlcmIgKyAiPyIpOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc2l6ZW9mKG5vX21vdmUgPSBvYnMgJiBhbGxfaW52ZW50b3J5KGRlc3QpKSkgeworICAgICAgICAgICAgVE1FKGNhcGl0YWxpemUoQ291bnRVcChtYXBfb2JqZWN0cyhub19tb3ZlLCAibmFtZSIsIFdFUiwgMSkpKSArCisgICAgICAgICAgICAgICAgKHNpemVvZihub19tb3ZlKSA9PSAxID8gIiBpc3QiIDogIiBzaW5kIikgKworICAgICAgICAgICAgICAgICIgZG9jaCBiZXJlaXRzIGluICIgKyBkZXN0LT5uYW1lKFdFTSwxKSArICIuIik7CisgICAgICAgICAgICBpZiAoIXNpemVvZihvYnMgLT0gbm9fbW92ZSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBmb3JlYWNoIChvYmplY3Qgbzogb2JzKSB7CisgICAgICAgICAgICBpZiAob2JqZWN0cChvKSkKKyAgICAgICAgICAgICAgICBwdXQobywgZGVzdCwgbXNnKTsKKworICAgICAgICAgICAgaWYgKGdldF9ldmFsX2Nvc3QoKSA8IDEwMDAwMCkgeworICAgICAgICAgICAgICAgIFRNRSgiRGVuIFJlc3QgbGFlc3N0IER1IGVyc3QgbWFsLCB3byBlciBpc3QuIik7CisgICAgICAgICAgICAgICAgbGFzdF9tb3ZlZF9vYmplY3RzID0gb2JzWy4ubWVtYmVyKG9icywgbyldOworICAgICAgICAgICAgICAgIGxhc3RfbW92ZWRfd2hlcmUgPSBkZXN0OworICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgbGFzdF9tb3ZlZF9vYmplY3RzID0gb2JzOworICAgICAgICBsYXN0X21vdmVkX3doZXJlID0gZGVzdDsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIAorICAgIHJldHVybiAwOworfQorCit2YXJhcmdzIGludCBwaWNrX29iamVjdHMoc3RyaW5nIHN0ciwgaW50IGZsYWcsIG1peGVkIG1zZykKK3sKKyAgICBvYmplY3QgKm9iczsKKworICAgIGlmICgoKGludClRdWVyeVByb3AoUF9NQVhfSEFORFMpKSA8IDEpeworICAgICAgICBORigiT2huZSBIYWVuZGUga2FubnN0IER1IG5pY2h0cyBuZWhtZW4uIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICghc2l6ZW9mKG9icyA9IGZpbmRfb2JqZWN0cyhzdHIsIDAsIDEpIC0gYWxsX2ludmVudG9yeSgpCisJICAtIChmbGFnID8gYWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSA6ICh7fSkpKSkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBmb3JlYWNoIChvYmplY3Qgbzogb2JzKSB7CisgICAgICAgIGlmIChvYmplY3RwKG8pKQorICAgICAgICAgICAgcGljayhvLCBtc2cpOworCisgICAgICAgIGlmIChnZXRfZXZhbF9jb3N0KCkgPCAxMDAwMDApIHsKKyAgICAgICAgICAgIFRNRSgiRGVuIFJlc3QgbGFlc3N0IER1IGVyc3QgbWFsIGxpZWdlbi4iKTsKKyAgICAgICAgICAgIGxhc3RfbW92ZWRfb2JqZWN0cyA9IG9ic1suLm1lbWJlcihvYnMsIG8pXTsKKyAgICAgICAgICAgIGxhc3RfbW92ZWRfd2hlcmUgPSAwOworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBsYXN0X21vdmVkX29iamVjdHMgPSBvYnM7CisgICAgbGFzdF9tb3ZlZF93aGVyZSA9IDA7CisgICAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3MgaW50IGdpdmVfb2JqZWN0cyhzdHJpbmcgc3RyLCBtaXhlZCBtc2cpCit7CisgICAgb2JqZWN0ICpvYnMsIGRlc3Q7CisgICAgCisgICAgaWYgKCFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpKSByZXR1cm4gMDsKKworICAgIHN0cmluZyAqdG9rZW5zID0gZXhwbG9kZShzdHIsICIgIik7CisKKyAgICBpZiAoKChpbnQpUXVlcnlQcm9wKFBfTUFYX0hBTkRTKSkgPCAxKXsKKyAgICAgICAgTkYoIk9obmUgSGFlbmRlIGthbm5zdCBEdSBuaWNodHMgd2VnZ2ViZW4uIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGZvciAoaW50IGkgPSAwOyBpIDwgc2l6ZW9mKHRva2VucyktMTsgaSsrKSB7CisgICAgICAgIGlmICghKGRlc3QgPSBwcmVzZW50KGltcGxvZGUodG9rZW5zWy4uaV0sICIgIiksIGVudmlyb25tZW50KCkpKSkKKyAgICAgICAgICAgIGNvbnRpbnVlOworCisgICAgICAgIGlmICghbGl2aW5nKGRlc3QpKSB7CisgICAgICAgICAgICBORigiQWJlciAiICsgZGVzdC0+bmFtZShXRVIsIDEpICsgIiBsZWJ0IGRvY2ggZ2FyIG5pY2h0ISIpOworICAgICAgICAgICAgZGVzdCA9IDA7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghc2l6ZW9mKG9icyA9IF9fZmluZF9vYmplY3RzKHRva2Vuc1tpKzEuLl0sIDAsIDEpKSkgeworICAgICAgICAgICAgTkYoIldBUyBtb2VjaHRlc3QgRHUgIiArIGRlc3QtPm5hbWUoV0VNLCAxKSsiIGdlYmVuPyIpOworICAgICAgICAgICAgZGVzdCA9IDA7CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgaWYgKCFkZXN0KSB7CisgICAgICAgIGludCBwb3M7CisKKyAgICAgICAgaWYgKChwb3MgPSBzdHJyc3RyKHN0ciwgIiBhbiAiKSkgPj0gMCkgeworICAgICAgICAgICAgZGVzdCA9IHByZXNlbnQoc3RyW3Bvcys0Li5dLCBlbnZpcm9ubWVudCgpKTsKKyAgICAgICAgICAgIC8vIHp1IGdlYmVuZGUgT2JqZWt0ZSBpbiBFbnYgKyBMaXZpbmcgc3VjaGVuCisgICAgICAgICAgICBvYnMgPSBmaW5kX29iamVjdHMoc3RyWy4ucG9zLTFdLCAwLCAxKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmICghZGVzdCB8fCAhbGl2aW5nKGRlc3QpIHx8ICFzaXplb2Yob2JzKSkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBmb3JlYWNoIChvYmplY3Qgbzogb2JzKSB7CisgICAgICAgIGlmIChvYmplY3RwKG8pKQorICAgICAgICAgICAgZ2l2ZShvLCBkZXN0LCBtc2cpOworCisgICAgICAgIGlmIChnZXRfZXZhbF9jb3N0KCkgPCAxMDAwMDApIHsKKyAgICAgICAgICAgIFRNRSgiRGVuIFJlc3QgYmVoYWVsdHN0IER1IGVyc3QgbWFsLiIpOworICAgICAgICAgICAgbGFzdF9tb3ZlZF9vYmplY3RzID0gb2JzWy4ubWVtYmVyKG9icywgbyldOworICAgICAgICAgICAgbGFzdF9tb3ZlZF93aGVyZSA9IGRlc3Q7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGxhc3RfbW92ZWRfb2JqZWN0cyA9IG9iczsKKyAgICBsYXN0X21vdmVkX3doZXJlID0gZGVzdDsKKyAgICByZXR1cm4gMTsKK30KKwordmFyYXJncyBpbnQgc2hvd19vYmplY3RzKHN0cmluZyBzdHIsIG1peGVkIG1zZykKK3sKKyAgICBvYmplY3QgKm9icywgd2hvbTsKKyAgICAKKyAgICBpZiAoIXN0cmluZ3Aoc3RyKSB8fCAhc2l6ZW9mKHN0cikpCisgICAgICByZXR1cm4gMDsKKworICAgIHN0cmluZyAqdG9rZW5zID0gZXhwbG9kZShzdHIsICIgIik7CisKKyAgICBmb3IgKGludCBpID0gMDsgaSA8IHNpemVvZih0b2tlbnMpLTE7IGkrKykgeworICAgICAgICBpZiAod2hvbSA9IHByZXNlbnQoaW1wbG9kZSh0b2tlbnNbLi5pXSwgIiAiKSwgZW52aXJvbm1lbnQoKSkpIHsKKyAgICAgICAgICAgIGlmICghbGl2aW5nKHdob20pKSB7CisgICAgICAgICAgICAgICAgTkYoIkFiZXIgIiArIHdob20tPm5hbWUoV0VSLCAxKSArICIgbGVidCBkb2NoIGdhciBuaWNodCEiKTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGlmIChpICE9IDAgfHwgdG9rZW5zWzBdICE9ICJhbGxlbiIpCisgICAgICAgICAgICAgICAgY29udGludWU7CisKKyAgICAgICAgICAgIGlmICghc2l6ZW9mKGZpbHRlcihhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpIC0KKyAgICAgICAgICAgICAgICAgICAgKHsgdGhpc19vYmplY3QoKSB9KSwgIydsaXZpbmcpKSkgeworICAgICAgICAgICAgICAgIE5GKCJIaWVyIGlzdCBuaWVtYW5kLCBkZW0gRHUgZXR3YXMgemVpZ2VuIGtvZW5udGVzdCEiKTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmICh3aG9tID09IHRoaXNfb2JqZWN0KCkpIHsKKyAgICAgICAgICAgIE5GKCJEYXp1IHNvbGx0ZXN0IER1IGRhbm4gYmVzc2VyICdzY2hhdScgYmVudXR6ZW4hXG4iKTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCFzaXplb2Yob2JzID0gX19maW5kX29iamVjdHModG9rZW5zW2krMS4uXSwgdGhpc19vYmplY3QoKSwgMCkpICYmCisgICAgICAgICAgICAhc2l6ZW9mKG9icyA9IF9fZmluZF9vYmplY3RzKHRva2Vuc1tpKzEuLl0sIDAsIDApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSAoeyB0aGlzX29iamVjdCgpLCB3aG9tIH0pKSkgeworICAgICAgICAgICAgTkYoIldBUyBtb2VjaHRlc3QgRHUgIiArICh3aG9tID8gd2hvbS0+bmFtZShXRU0sIDEpIDogImFsbGVuIikgKworICAgICAgICAgICAgICAgIiB6ZWlnZW4/Iik7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIGZvcmVhY2ggKG9iamVjdCBvOiBvYnMpIHsKKyAgICAgICAgICAgIGlmIChvYmplY3RwKG8pKQorICAgICAgICAgICAgICAgIHNob3cobywgd2hvbSwgbXNnKTsKKworICAgICAgICAgICAgaWYgKGdldF9ldmFsX2Nvc3QoKSA8IDEwMDAwMCkgeworICAgICAgICAgICAgICAgIFRNRSgiRGFzIHJlaWNodCBlcnN0IG1hbC4iKTsKKyAgICAgICAgICAgICAgICBsYXN0X21vdmVkX29iamVjdHMgPSBvYnNbLi5tZW1iZXIob2JzLCBvKV07CisgICAgICAgICAgICAgICAgbGFzdF9tb3ZlZF93aGVyZSA9IHdob207CisgICAgICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICBsYXN0X21vdmVkX29iamVjdHMgPSBvYnM7CisgICAgICAgIGxhc3RfbW92ZWRfd2hlcmUgPSB3aG9tOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICByZXR1cm4gMDsKK30KKworb2JqZWN0ICptb3ZlZF9vYmplY3RzKHZvaWQpCit7CisgICAgcmV0dXJuIGxhc3RfbW92ZWRfb2JqZWN0czsKK30KKworb2JqZWN0IG1vdmVkX3doZXJlKHZvaWQpCit7CisgICAgcmV0dXJuIGxhc3RfbW92ZWRfd2hlcmU7Cit9CisKKworLyoqKioqKioqKioqKioqKioqKioqKioqKiogRGllIGVpbnplbG5lbiBLb21tYW5kb3MgKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qIHN0YXRpYyBpbnQgZmFsbGVubGFzc2VuKHN0cmluZyBzdHIpCisgKiBzdGF0aWMgaW50IHdlcmZlbihzdHJpbmcgc3RyKQorICogc3RhdGljIGludCBsZWdlbihzdHJpbmcgc3RyKQorICogc3RhdGljIGludCBzdGVja2VuKHN0cmluZyBzdHIpCisgKiBzdGF0aWMgaW50IGhvbGVuKHN0cmluZyBzdHIpCisgKiBzdGF0aWMgaW50IG5laG1lbihzdHJpbmcgc3RyKQorICogc3RhdGljIGludCBnZWJlbihzdHJpbmcgc3RyKQorICogICBNaW5pbWFsZSBXcmFwcGVyIGZ1ZXIgWFhYX29iamVjdHMoKSwgZW50ZmVybmVuICJmYWxsZW4iLCAid2VnIiBiencuICJhYiIKKyAqICAgYXVzIGRlbiBBcmd1bWVudGVuIHVuZCBzZXR6ZW4gZW50c3ByZWNoZW5kZSBTdGFuZGFyZC1GZWhsZXJtZWxkdW5nZW4uCisgKiAgIAorICogcHJvdGVjdGVkIHZvaWQgYWRkX3B1dF9hbmRfZ2V0X2NvbW1hbmRzKCkKKyAqICAgUmVnaXN0cmllcnQgb2JpZ2UgRnVua3Rpb25lbiBwZXIgYWRkX2FjdGlvbigpLgorICovCisKK3N0YXRpYyBpbnQgZmFsbGVubGFzc2VuKHN0cmluZyBzdHIpCit7CisgICAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSkgeworICAgICAgICBfbm90aWZ5X2ZhaWwoIkFscyBHZWlzdCBrYW5uc3QgRHUgbmljaHRzIGZhbGxlbmxhc3Nlbi5cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAoIXN0ciB8fCBzdHJbPDcuLl0gIT0gIiBmYWxsZW4iKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiTGFzcyBldHdhcyBGQUxMRU4sIG9kZXIgd2FzIG1laW5zdCBEdT9cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBfbm90aWZ5X2ZhaWwoIldBUyBtb2VjaHRlc3QgRHUgZmFsbGVubGFzc2VuP1xuIik7CisgICAgcmV0dXJuIGRyb3Bfb2JqZWN0cyhzdHJbMC4uPDhdKTsKK30KKworc3RhdGljIGludCB3ZXJmZW4oc3RyaW5nIHN0cikKK3sKKyAgICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiQWxzIEdlaXN0IGthbm5zdCBEdSBuaWNodHMgd2Vnd2VyZmVuLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICghc3RyIHx8IHN0cls8NC4uXSAhPSAiIHdlZyIpIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJXaXJmIGV0d2FzIFdFRywgb2RlciB3YXMgbWVpbnN0IER1P1xuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIF9ub3RpZnlfZmFpbCgiV0FTIG1vZWNodGVzdCBEdSBsb3N3ZXJkZW4/XG4iKTsKKyAgICByZXR1cm4gZHJvcF9vYmplY3RzKHN0clswLi48NV0pOworfQorCitzdGF0aWMgaW50IGxlZ2VuKHN0cmluZyBzdHIpCit7CisgICAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSkgeworICAgICAgICBfbm90aWZ5X2ZhaWwoIkFscyBHZWlzdCBrYW5uc3QgRHUgbmljaHRzIHdlZ2xlZ2VuLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICghc3RyKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiTGVnZSBldHdhcyBBQiwgb2RlciB3YXMgbWVpbnN0IER1P1xuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmIChzdHJbPDMuLl0gPT0gIiBhYiIpIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJXQVMgbW9lY2h0ZXN0IER1IGFibGVnZW4/XG4iKTsKKyAgICAgICAgcmV0dXJuIGRyb3Bfb2JqZWN0cyhzdHJbMC4uPDRdKTsKKyAgICB9CisKKyAgICBpZiAoc3RyWzw0Li5dID09ICIgd2VnIikgeworICAgICAgICBfbm90aWZ5X2ZhaWwoIldBUyBtb2VjaHRlc3QgRHUgd2VnbGVnZW4/XG4iKTsKKyAgICAgICAgcmV0dXJuIGRyb3Bfb2JqZWN0cyhzdHJbMC4uPDVdKTsKKyAgICB9CisKKyAgICBfbm90aWZ5X2ZhaWwoIldBUyBtb2VjaHRlc3QgRHUgV09ISU4gbGVnZW4/XG4iKTsKKyAgICByZXR1cm4gcHV0X29iamVjdHMoc3RyLCBXRU4sICJsZWdlbiIpOworfQorCitzdGF0aWMgaW50IHN0ZWNrZW4oc3RyaW5nIHN0cikKK3sKKyAgICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiRGFzIGthbm5zdCBEdSBpbiBEZWluZW0gaW1tYXRlcmllbGxlbiBadXN0YW5kIG5pY2h0LlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIF9ub3RpZnlfZmFpbCgiV0FTIG1vZWNodGVzdCBEdSBXT0hJTiBzdGVja2VuP1xuIik7CisgICAgcmV0dXJuIHB1dF9vYmplY3RzKHN0ciwgV0VOLCAic3RlY2tlbiIpOworfQorCitzdGF0aWMgaW50IGhvbGVuKHN0cmluZyBzdHIpCit7CisgICAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSkgeworICAgICAgICBfbm90aWZ5X2ZhaWwoIkFscyBHZWlzdCBrYW5uc3QgRHUgbmljaHRzIG5laG1lbi5cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBfbm90aWZ5X2ZhaWwoIldBUyBtb2VjaHRlc3QgRHUgYXVzIFdBUyBob2xlbj9cbiIpOworICAgIHJldHVybiBwaWNrX29iamVjdHMoc3RyLCAxKTsKK30KKworc3RhdGljIGludCBuZWhtZW4oc3RyaW5nIHN0cikKK3sKKyAgICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiQWxzIEdlaXN0IGthbm5zdCBEdSBuaWNodHMgbmVobWVuLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIF9ub3RpZnlfZmFpbCgiV0FTIG1vZWNodGVzdCBEdSBuZWhtZW4/XG4iKTsKKyAgICByZXR1cm4gcGlja19vYmplY3RzKHN0ciwgMCk7Cit9CisKK3N0YXRpYyBpbnQgZ2ViZW4oc3RyaW5nIHN0cikKK3sKKyAgICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiQWxzIEdlaXN0IGthbm5zdCBEdSBuaWNodHMgd2VnZ2ViZW4uXG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgX25vdGlmeV9mYWlsKCJXRU0gbW9lY2h0ZXN0IER1IFdBUyBnZWJlbj9cbiIpOworICAgIHJldHVybiBnaXZlX29iamVjdHMoc3RyKTsKK30KKworc3RhdGljIGludCB6ZWlnZW4oc3RyaW5nIHN0cikKK3sKKyAgICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiQWxzIEdlaXN0IGthbm5zdCBEdSBuaWVtYW5kZW0gZXR3YXMgemVpZ2VuLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIF9ub3RpZnlfZmFpbCgiV0VNIG1vZWNodGVzdCBEdSBXQVMgemVpZ2VuP1xuIik7CisgICAgcmV0dXJuIHNob3dfb2JqZWN0cyhzdHIpOworfQorCitwcm90ZWN0ZWQgdm9pZCBhZGRfcHV0X2FuZF9nZXRfY29tbWFuZHModm9pZCkKK3sKKyAgICBhZGRfYWN0aW9uKCJmYWxsZW5sYXNzZW4iLCAibGFzcyIpOworICAgIGFkZF9hY3Rpb24oImZhbGxlbmxhc3NlbiIsICJsYXNzZSIpOworICAgIGFkZF9hY3Rpb24oIndlcmZlbiIsICAgICAgICJ3aXJmIik7CisgICAgYWRkX2FjdGlvbigid2VyZmVuIiwgICAgICAgIndlcmYiKTsKKyAgICBhZGRfYWN0aW9uKCJ3ZXJmZW4iLCAgICAgICAid2VyZmUiKTsKKyAgICBhZGRfYWN0aW9uKCJsZWdlbiIsICAgICAgICAibGVnIik7CisgICAgYWRkX2FjdGlvbigibGVnZW4iLCAgICAgICAgImxlZ2UiKTsKKyAgICBhZGRfYWN0aW9uKCJzdGVja2VuIiwgICAgICAic3RlY2siKTsKKyAgICBhZGRfYWN0aW9uKCJzdGVja2VuIiwgICAgICAic3RlY2tlIik7CisgICAgYWRkX2FjdGlvbigiaG9sZW4iLCAgICAgICAgImhvbCIpOworICAgIGFkZF9hY3Rpb24oImhvbGVuIiwgICAgICAgICJob2xlIik7CisgICAgYWRkX2FjdGlvbigibmVobWVuIiwgICAgICAgIm5pbW0iKTsKKyAgICBhZGRfYWN0aW9uKCJuZWhtZW4iLCAgICAgICAibmVobSIpOworICAgIGFkZF9hY3Rpb24oIm5laG1lbiIsICAgICAgICJuZWhtZSIpOworICAgIGFkZF9hY3Rpb24oImdlYmVuIiwgICAgICAgICJnZWJlIik7CisgICAgYWRkX2FjdGlvbigiZ2ViZW4iLCAgICAgICAgImdpYiIpOworICAgIGFkZF9hY3Rpb24oInplaWdlbiIsICAgICAgICJ6ZWlnIik7CisgICAgYWRkX2FjdGlvbigiemVpZ2VuIiwgICAgICAgInplaWdlIik7Cit9CisKKworLyoqKioqKioqKiogQXVzIHJlaW5lbiBLb21wYXRpYmlsaXRhZXRzZ3J1ZW5kZW4gd2VpdGVyaGluIGVudGhhbHRlbiAqKioqKioqKiovCisKK29iamVjdCogZmluZF9vYnMoc3RyaW5nIHN0ciwgaW50IG1ldGgpCisvLyBnaWJ0IGVpbiBhcnJheSB6dXJ1ZWNrIG1pdCBhbGxlbiBPYmpla3RlbiBkaWUgbWl0IHN0ciBhbmdlc3Byb2NoZW4gd2VyZGVuCit7CisgICBvYmplY3QgaW52OworICAgaWYgKCFzdHIpIHJldHVybiAwOworICAgaWYgKHN0cls8Ny4uXT09IiBpbiBtaXIiKSB7CisgICAgIGludj1NRTsKKyAgICAgc3RyPXN0clswLi48OF07CisgICB9CisgICBlbHNlIGlmIChzdHJbPDguLl09PSIgaW4gcmF1bSIpIHsKKyAgICAgaWYgKG1ldGggJiBQVVRfR0VUX0RST1ApIHsgLy8gbWFuIGthbm4gbmljaHRzIGF1cyBkZW0gUmF1bSB3ZWd3ZXJmZW4KKyAgICAgICBfbm90aWZ5X2ZhaWwoIkR1IGthbm5zdCBuaWNodHMgd2Vnd2VyZmVuLCBkYXMgRHUgZ2FyIG5pY2h0IGhhc3QuXG4iKTsKKyAgICAgICByZXR1cm4gMDsKKyAgICAgfQorICAgICBpbnY9ZW52aXJvbm1lbnQoKTsKKyAgICAgc3RyPXN0clswLi48OV07CisgICB9CisgICBlbHNlIGlmIChtZXRoICYgUFVUX0dFVF9EUk9QKSBpbnY9TUU7IC8vIFJhdW0gYmVpIGRyb3AgdW5pbnRlcmVzc2FudAorICAgLy8gZWxzZSBrZWluIGJlc29uZGVyZXMgaW52IGF1c2dld2FlaGx0IGFsc28gaW52PTAKKyAgIGlmICghc2l6ZW9mKHN0cikpCisgICAgIHJldHVybiAwOyAvLyBoaWVyIHBhc3N0IGRpZSBiZXJlaXRzIGdlc2V0enRlIF9ub3RpZnlfZmFpbAorICAgZWxzZSB7CisgICAgIG9iamVjdCAqb2JzOworICAgICBzdHJpbmcgY29uOworICAgICBpZiAoc3NjYW5mKHN0ciwgIiVzIGF1cyAlcyIsIHN0ciwgY29uKT09MiB8fAorICAgICAgICAgc3NjYW5mKHN0ciwgIiVzIGluICVzIiwgc3RyLCBjb24pPT0yIHx8CisgICAgICAgICBzc2NhbmYoc3RyLCAiJXMgdm9uICVzIiwgc3RyLCBjb24pPT0yIHx8CisgICAgICAgICBzc2NhbmYoc3RyLCAiJXMgdm9tICVzIiwgc3RyLCBjb24pPT0yKSB7CisgICAgICAgaWYgKCFpbnYpIHsKKyAgICAgICAgIGlmICghZW52aXJvbm1lbnQoKSB8fCAhKGludj1wcmVzZW50KGNvbiwgZW52aXJvbm1lbnQoKSkpKQorICAgICAgICAgICAgaW52PXByZXNlbnQoY29uLCBNRSk7IC8vIHNvd29obCBpbSBlbnYgYWxzIGF1Y2ggaW0gaW52IHN1Y2hlbgorICAgICAgIH0KKyAgICAgICBlbHNlIGludj1wcmVzZW50KGNvbiwgaW52KTsgLy8gbnVyIGluIGF1c2dld2FlaGx0ZW0gaW52IHN1Y2hlbgorICAgICAgIGlmIChpbnY9PU1FKSBpbnY9MDsKKyAgICAgICBpZiAoIWludiB8fCAhKGludi0+c2hvcnQoKSkpIHsKKyAgICAgICAgIF9ub3RpZnlfZmFpbChicmVha19zdHJpbmcoIkR1IGhhc3QgaGllciBhYmVyIGtlaW4gJyIrY2FwaXRhbGl6ZShjb24pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIicuIiw3OCkpOworICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgfQorICAgICAgIGlmIChsaXZpbmcoaW52KSkgeworICAgICAgICAgX25vdGlmeV9mYWlsKGJyZWFrX3N0cmluZygiQWJlciAiK2ludi0+bmFtZShXRVIsMSkrIiBsZWJ0IGRvY2ghIiw3OCkpOworICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgfQorICAgICAgIC8vIHdpZXNvIG1hbiBhdXMgT2JqZWt0ZW4gZGllIHZvbiBzdGQvdHJheSBhYmdlbGVpdGV0IHdlcmRlbiBldHdhcworICAgICAgIC8vIG5laG1lbiBrb2VubmVuIHNvbGwsIHZlcnN0ZWggaWNoIHp3YXIgbmljaHQgc28gZ2Fuei4uLgorICAgICAgIGlmICghKGludi0+UXVlcnlQcm9wKFBfQ09OVEFJTkVSKSkgJiYgIShpbnYtPlF1ZXJ5UHJvcChQX1RSQVkpKSkgeworICAgICAgICAgX25vdGlmeV9mYWlsKGJyZWFrX3N0cmluZygiRHUga2FubnN0IG5pY2h0cyBhdXMgIitpbnYtPm5hbWUoV0VNLDEpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiBuZWhtZW4uIiw3OCkpOworICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgfQorICAgICAgIGlmIChpbnYtPlF1ZXJ5UHJvcChQX0NOVF9TVEFUVVMpKSB7IC8vIENvbnRhaW5lciBpc3QgZ2VzY2hsb3NzZW4KKyAgICAgICAgIF9ub3RpZnlfZmFpbChicmVha19zdHJpbmcoIkFiZXIgIitpbnYtPm5hbWUoV0VSLDEpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiBpc3QgZG9jaCBnZXNjaGxvc3Nlbi4iLCA3OCkpOworICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgfQorICAgICB9CisgICAgIGVsc2UgaWYgKGludj09TUUgJiYgKG1ldGggJiBQVVRfR0VUX1RBS0UpKSB7IC8vIG5pY2h0cyBhdXMgc2ljaCBuZWhtZW4KKyAgICAgICBfbm90aWZ5X2ZhaWwoIkR1IGthbm5zdCBuaWNodHMgbmVobWVuLCAiCisgICAgICAgICAgICAgICAgICAgICJ3YXMgRHUgc2Nob24gYmVpIERpciB0cmFlZ3N0LlxuIik7CisgICAgICAgcmV0dXJuIDA7CisgICAgIH0KKyAgICAgaWYgKCFpbnYgJiYgKG1ldGggJiBQVVRfR0VUX1RBS0UpKQorICAgICAgIGludj1lbnZpcm9ubWVudCgpOyAvLyBuaWNodHMgbmVobWVuIHdhcyBtYW4gc2Nob24gaGF0CisKKyAgICAgaWYgKCFpbnYpIHsKKyAgICAgICBpZiAoZW52aXJvbm1lbnQoKSkgeworICAgICAgICAgb2JzPShlbnZpcm9ubWVudCgpLT5wcmVzZW50X29iamVjdHMoc3RyKXx8KHt9KSk7CisgICAgICAgICBpZiAoIXNpemVvZihvYnMpKSBvYnMrPShNRS0+cHJlc2VudF9vYmplY3RzKHN0cil8fCh7fSkpOworICAgICAgIH0KKyAgICAgICBlbHNlIG9icz0oTUUtPnByZXNlbnRfb2JqZWN0cyhzdHIpIHx8ICh7fSkpOworICAgICB9CisgICAgIGVsc2Ugb2JzPShpbnYtPnByZXNlbnRfb2JqZWN0cyhzdHIpIHx8ICh7fSkpOworICAgICByZXR1cm4gb2JzLSh7IE1FIH0pOworICAgfQorICAgcmV0dXJuKDApOworfQorCitpbnQgcGlja19vYmoob2JqZWN0IG9iKQoreworICBvYmplY3QgZW52OworCisgIGlmICghb2IgfHwgb2IgPT0gdGhpc19vYmplY3QoKSB8fCBlbnZpcm9ubWVudChvYikgPT0gdGhpc19vYmplY3QoKSkgcmV0dXJuIDA7CisgIGlmICgoZW52PWVudmlyb25tZW50KG9iKSkgIT0gZW52aXJvbm1lbnQoKSkgeworICAgIGlmICghZW52LT5RdWVyeVByb3AoUF9DT05UQUlORVIpICYmICFlbnYtPlF1ZXJ5UHJvcChQX1RSQVkpKSB7CisgICAgICBUTUUoIkR1IGthbm5zdCBuaWNodHMgYXVzICIgKyBlbnYtPm5hbWUoV0VNLDEpICsgIiBuZWhtZW4uIik7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgZWxzZSBpZiAoZW52LT5RdWVyeVByb3AoUF9DTlRfU1RBVFVTKSkgeyAgLy8gQ29udGFpbmVyIGlzdCBnZXNjaGxvc3NlbgorICAgICAgVE1FKCJBYmVyICIgKyBlbnYtPm5hbWUoV0VSLCAxKSArICIgaXN0IGRvY2ggZ2VzY2hsb3NzZW4uIik7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKyAgaWYgKG9iLT5Jc1VuaXQoKSAmJiBvYi0+UXVlcnlQcm9wKFBfQU1PVU5UKTwwKSB7CisgICAgVE1FKCJEdSBrYW5uc3QgbmljaHQgbWVociBuZWhtZW4gYWxzIGRhIGlzdC4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBwaWNrKG9iKTsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBkcm9wX29iaihvYmplY3Qgb2IpCit7CisgIGlmICghb2IgfHwgb2I9PXRoaXNfb2JqZWN0KCkgfHwgZW52aXJvbm1lbnQob2IpIT10aGlzX29iamVjdCgpKSByZXR1cm4gMDsKKyAgZHJvcChvYik7CisgIHJldHVybiAxOworfQorCitpbnQgcHV0X29iaihvYmplY3Qgb2IsIG9iamVjdCB3aGVyZSkKK3sKKyAgb2JqZWN0IGVudjsKKworICBpZiAob2IgPT0gdGhpc19vYmplY3QoKSB8fCBvYiA9PSB3aGVyZSB8fCBlbnZpcm9ubWVudChvYikgPT0gd2hlcmUpIHJldHVybiAwOworICBlbnY9ZW52aXJvbm1lbnQob2IpOworICBpZiAoIXdoZXJlLT5RdWVyeVByb3AoUF9DT05UQUlORVIpKSB7CisgICAgVE1FKCJEdSBrYW5uc3QgaW4gIiArIHdoZXJlLT5uYW1lKFdFTiwxKSArICIgbml4IHJlaW5zdGVja2VuLiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmICh3aGVyZS0+UXVlcnlQcm9wKFBfQ05UX1NUQVRVUykpIHsgIC8vIENvbnRhaW5lciBpc3QgZ2VzY2hsb3NzZW4KKyAgICBUTUUoIkFiZXIgIiArIHdoZXJlLT5uYW1lKFdFUiwgMSkgKyAiIGlzdCBkb2NoIGdlc2NobG9zc2VuLiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmIChlbnYhPWVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpICYmIGVudiE9dGhpc19vYmplY3QoKSkgeworICAgIF9ub3RpZnlfZmFpbCgiRGEga29tbXN0IGR1IHNvIG5pY2h0IHJhbi5cbiIpOworICAgIHJldHVybiAwOworICB9CisgIHB1dChvYiwgd2hlcmUpOworICByZXR1cm4gMTsKK30KKworaW50IGdpdmVfb2JqKG9iamVjdCBvYiwgb2JqZWN0IHdoZXJlKQoreworICBvYmplY3QgZW52OworCisgIGlmIChlbnZpcm9ubWVudChvYikhPXRoaXNfb2JqZWN0KCkpIHsKKyAgICBUTUUoIkRhcyBzb2xsdGVzdCBEdSBlcnN0bWFsIG5laG1lbi4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoIW9iIHx8IG9iID09IHRoaXNfb2JqZWN0KCkgfHwgb2IgPT0gd2hlcmUgfHwKKyAgICAgIGVudmlyb25tZW50KHdoZXJlKSE9ZW52aXJvbm1lbnQoKSkKKyAgICByZXR1cm4gMDsKKyAgaWYgKGVudmlyb25tZW50KG9iKSA9PSB3aGVyZSkgeworICAgIF9ub3RpZnlfZmFpbCgiRGFzIFppZWwgaXN0IGluIGRlbSB6dSBnZWJlbmRlbiBPYmplY3QgZW50aGFsdGVuIVxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKGVudmlyb25tZW50KG9iKSE9dGhpc19vYmplY3QoKSkgeworICAgIFRNRSgiRGFzIGhhc3QgRHUgbmljaHQuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgZ2l2ZShvYiwgd2hlcmUpOworICByZXR1cm4gMTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvc2tpbGxfYXR0cmlidXRlcy5jIGIvc3RkL2xpdmluZy9za2lsbF9hdHRyaWJ1dGVzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWQ5MGFhMAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9saXZpbmcvc2tpbGxfYXR0cmlidXRlcy5jCkBAIC0wLDAgKzEsMzc5IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL3NraWxsc19hdHRyaWJ1dGVzLmMgLSBWZXJ3YWx0dW5nIGRlciBTa2lsbGF0dHJpYnV0ZSB2b24gTGViZXdlc2VuCisvLworLy8gJElkOiBza2lsbHMuYyA2NjczIDIwMDgtMDEtMDUgMjA6NTc6NDNaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL3V0aWwvZXhlY3V0ZXIiOworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGxpdmluZy9za2lsbF9hdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8cGxheWVyL2xpZmUuaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisKKy8vI2RlZmluZSBaREVCVUcoeCkgaWYgKGZpbmRfcGxheWVyKCJ6ZXNzdHJhIikpIHRlbGxfb2JqZWN0KGZpbmRfcGxheWVyKCJ6ZXNzdHJhIikseCkKKyNkZWZpbmUgWkRFQlVHKHgpCisvLyNkZWZpbmUgU0FTRVRMT0coeCkgbG9nX2ZpbGUoIlNBU0VULkxPRyIsIHgsIDI1MDAwMCkKKworLy8jZGVmaW5lIF9fREVCVUdfXworCisvLyBWYXJpYWJsZSBmdWVyIGRpZSBTa2lsbC1BdHRyaWJ1dGUsIERhdGVuc3RydWt0dXI6CisvKiAgKFsgU0FfQVRUUjogKHtTdW1tZV9TdGF0X01vZGlmaWVyLCBaZWl0cHVua3QsIEFuemFobE1vZGlmaWVyLCB9KTsKKyAgICAgICAgICAgICAgKFsgb2IxOnZhbHVlO2R1cmF0aW9uLAorICAgICAgICAgICAgICAgICBvYjI6dmFsdWU7ZHVyYXRpb24sIC4uLl0pOyAgLy8gc3RhdC4gTW9kaWZpZXIKKyAgICAgICAgICAgICAgKFsgb2IxOmNsb3N1cmU7ZHVyYXRpb24sCisgICAgICAgICAgICAgICAgIG9iMjpjbG9zdXJlO2R1cmF0aW9uLCAuLi5dKSAgICAgLy8gZHluLiBNb2RpZmllcgorICAgICAgICAgICAgICwKKyAgICAgU0FfQVRUUjI6ICh7Li4ufSk7IChbXSk7IChbXSksCisgICBdKSAqLworcHJpdmF0ZSBub3NhdmUgbWFwcGluZyBza2lsbGF0dHJzOworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CisgIFNldChQX1NLSUxMX0FUVFJJQlVURVMsIFNFQ1VSRUQsIEZfTU9ERV9BUyk7Cit9CisKKy8vIHZvbiBhdXNzZW4gUHJvcCBzZXR6ZW4gaXN0IG5pY2h0Li4uCittYXBwaW5nIF9zZXRfc2tpbGxfYXR0cihtYXBwaW5nIHNhKSB7CisgIHJldHVybiBkZWVwX2NvcHkoc2tpbGxhdHRycyk7Cit9CisvLyB1bmQgYXVjaCBiZWltIEFiZnJhZ2VuIG51ciBrb3BpZW4gbGllZmVybi4gOy0pCittYXBwaW5nIF9xdWVyeV9za2lsbF9hdHRyKCkgeworICByZXR1cm4gZGVlcF9jb3B5KHNraWxsYXR0cnMpOworCisvL1RPRE86IEV2dGwuIGV4dC4gU2V0emVuIHZvbiBQX1NLSUxMX0FUVFJJQlVURV9PRkZTRVRTIG1pdGxvZ2dlbj8KK30KKworcHJpdmF0ZSB2b2lkIFVwZGF0ZVNBQ2FjaGUoc3RyaW5nICphdHRycykgeworI2lmZGVmIF9fREVCVUdfXworICAgIGlmIChnZXR1aWQodGhpc19vYmplY3QoKSkgPT0gInplc3N0cmEiKQorICAgIFpERUJVRyhzcHJpbnRmKCIlT1xuIixza2lsbGF0dHJzKSk7CisjZW5kaWYKKyAgaWYgKCFtYXBwaW5ncChza2lsbGF0dHJzKSkgcmV0dXJuOworICBpZiAoIXBvaW50ZXJwKGF0dHJzKSB8fCBzaXplb2YoYXR0cnMpKQorICAgIGF0dHJzID0gbV9pbmRpY2VzKHNraWxsYXR0cnMpOyAvLyBhbGxlCisgIC8vIHNvbnN0IHNjaG5pdHRtZW5nZSBhdXMgZXhpc3RpZXJlbmRlbiB1bmQgZGVuIHVlYmVyZ2ViZW5lbi4KKyAgYXR0cnMgPSBtX2luZGljZXMoc2tpbGxhdHRycykgJiBhdHRyczsKKworICAvLyB1bmQgamV0enQgdWViZXIgYWxsZSBnZXd1ZW5zY2h0ZW4gU0FzIGRydWViZXIKKyAgZm9yZWFjaChzdHJpbmcgYXR0ciA6IGF0dHJzKSB7CisgICAgaW50ICpjYWNoZSA9IHNraWxsYXR0cnNbYXR0ciwgU0FNX0NBQ0hFXTsKKyAgICBtYXBwaW5nIHN0YXQgPSBza2lsbGF0dHJzW2F0dHIsIFNBTV9TVEFUSUNdOworICAgIG1hcHBpbmcgZHluID0gc2tpbGxhdHRyc1thdHRyLCBTQU1fRFlOQU1JQ107CisgICAgaW50IHN1bSA9IDA7CisgICAgaW50IHRpbWVvdXQgPSBfX0lOVF9NQVhfXzsKKyAKKyAgICAvLyB1ZWJlciBzdGF0LiBNb2RzIGl0ZXJpZXJlbiB1bmQgQXVmc3VtbWllcmVuLCBrbGVpbnN0ZW4gVGltZW91dAorICAgIC8vIGVybWl0dGVsbi4KKyAgICBmb3JlYWNoKG9iamVjdCBvYiwgaW50IHZhbHVlLCBpbnQgZHVyYXRpb246IHN0YXQpIHsKKyAgICAgIC8vIGd1ZWx0aWdlIE1vZHMgYXVmYWRkaWVyZW4sIGFiZ2VsYXVmZW5lIHJhdXN3ZXJmZW4KKyAgICAgIGlmIChkdXJhdGlvbiA+PSB0aW1lKCkpIHsKKyAgICAgICAgc3VtICs9IHZhbHVlOworICAgICAgICBpZiAoZHVyYXRpb24gPCB0aW1lb3V0KQorICAgICAgICAgIHRpbWVvdXQgPSBkdXJhdGlvbjsKKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgICAgbV9kZWxldGUoc3RhdCwgb2IpOyAvLyBqYSwgZ2VodCBpbSBmb3JlYWNoIDstKQorICAgIH0KKyAgICAvLyBBYmxhdWZ6ZWl0ZW4gZGVyIGR5bi4gTW9kcyBwcnVlZmVuLCB3YWVyZSBoaWVyIHp3YXIgbmljaHQgdW5iZWRpbmd0CisgICAgLy8gbm9ldGlnIHNvbmRlcm4ga29lbm50ZSBtYW4gYXVzc2NobGllc3NsaWNoIGltIFF1ZXJ5U2tpbGxBdHRyaWJ1dGUoKQorICAgIC8vIG1hY2hlbiwgYWJlciBkYW5uIHdhZXJlIGRpZSBFcm1pdHRsdW5nIGRlciBTdW1tZSBkZXIgTW9kcyBzY2h3aWVyaWdlci4KKyAgICBmb3JlYWNoKG9iamVjdCBvYiwgY2xvc3VyZSB2YWx1ZSwgaW50IGR1cmF0aW9uOiBkeW4pIHsKKyAgICAgIGlmIChkdXJhdGlvbiA8IHRpbWUoKSkKKyAgICAgICAgbV9kZWxldGUoZHluLCBvYik7IC8vIHVuZ3VlbHRpZywgd2VnIGRhbWl0LgorICAgIH0KKyAgICAvLyBnZXNhbXR6YWhsIE1vZHM/CisgICAgY2FjaGVbU0FNX0NPVU5UXSA9IHNpemVvZihzdGF0KSArIHNpemVvZihkeW4pOworICAgIGlmICghY2FjaGVbU0FNX0NPVU5UXSkgeworICAgICAgLy8ga2VpbmUgbW9kcyBkYSwgU3VibWFwcGluZyBmdWVyIGRpZXNlcyBTQSBrb21wbGV0dCBsb2VzY2hlbi4KKyAgICAgIG1fZGVsZXRlKHNraWxsYXR0cnMsIGF0dHIpOworICAgICAgY29udGludWU7CisgICAgfQorICAgIC8vIHNvbnN0IGRpZSBhbmRlcmVuIENhY2hlLVdlcnRlIHNldHplbi4KKyAgICBjYWNoZVtTQU1fU1VNXSA9IHN1bTsKKyAgICBjYWNoZVtTQU1fQ0FDSEVfVElNRU9VVF0gPSB0aW1lb3V0OworICB9CisgIC8vIHdlbm4gYWxsZSBNb2RzIGdlbG9lc2NodCB3dXJkZW4uCisgIGlmICghc2l6ZW9mKHNraWxsYXR0cnMpKSBza2lsbGF0dHJzPTA7CisjaWZkZWYgX19ERUJVR19fCisgIGlmIChnZXR1aWQodGhpc19vYmplY3QoKSkgPT0gInplc3N0cmEiKQorICAgIFpERUJVRyhzcHJpbnRmKCIlT1xuIixza2lsbGF0dHJzKSk7CisjZW5kaWYKK30KKworcHJpdmF0ZSBpbnQgSW50ZXJuYWxNb2RpZnlTa2lsbEF0dHJpYnV0ZShvYmplY3QgY2FzdGVyLCBzdHJpbmcgYXRybmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWl4ZWQgdmFsdWUsIGludCBkdXJhdGlvbikgeworICBpbnQgemVpdCA9IHV0aW1lKClbMV07CisgIGludCB0aWNrcyA9IGdldF9ldmFsX2Nvc3QoKTsKKworICAvLyBudXIgZXhpc3RpZXJlbmRlIFNBcy4uLgorICBpZiAoIXN0cmluZ3AoYXRybmFtZSkKKyAgICAgIHx8IG1lbWJlcihWQUxJRF9TS0lMTF9BVFRSSUJVVEVTLCBhdHJuYW1lKSA9PSAtMSkKKyAgICByZXR1cm4gU0FfTU9EX0lOVkFMSURfQVRUUjsKKworICBpZiAoIW9iamVjdHAoY2FzdGVyKSkgcmV0dXJuIFNBX01PRF9JTlZBTElEX09CSkVDVDsKKworICBpZiAoIW1hcHBpbmdwKHNraWxsYXR0cnMpKSBza2lsbGF0dHJzPW1fYWxsb2NhdGUoMSwzKTsKKyAgCisgIGlmICghbWVtYmVyKHNraWxsYXR0cnMsIGF0cm5hbWUpKSB7CisgICAgc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9DQUNIRV0gPSAoezAsIDAsIDB9KTsKKyAgICAvLyBkaWUgbWVpc3RlbiBNb2RzIHNpbmQgc3RhdGlzY2gsIGRhaGVyIGF1ZiBWZXJkYWNodCBoaWVyIGZ1ZXIgZWluZW4KKyAgICAvLyBFaW50cmFnIFBsYXR6IHJlc2VydmllcmVuLCBhYmVyIG5pY2h0IGZ1ZXIgZGVuIGR5bi4gVGVpbC4KKyAgICBza2lsbGF0dHJzW2F0cm5hbWUsU0FNX1NUQVRJQ10gPSBtX2FsbG9jYXRlKDEsMik7CisgICAgc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9EWU5BTUlDXSA9IG1fYWxsb2NhdGUoMCwyKTsKKyAgfQorICAvLyBwcnVlZmVuLCBvYiBNYXhpbWFsemFobCBhbiBFaW50cmFlZ2VuIGRyaW4gaXN0CisgIGVsc2UgaWYgKHNraWxsYXR0cnNbYXRybmFtZSxTQU1fQ0FDSEVdW1NBTV9DT1VOVF0gPj0gU0FNX01BWF9NT0RTKSB7CisgICAgLy8gbGV0enRlIENoYW5jZTogZGVzdHJ1Y3RldGUgT2JqZWt0ZSBkcmluPworICAgIHNraWxsYXR0cnNbYXRybmFtZSxTQU1fQ0FDSEVdW1NBTV9DT1VOVF0gPSAKKyAgICAgIHNpemVvZihza2lsbGF0dHJzW2F0cm5hbWUsU0FNX1NUQVRJQ10pCisgICAgK3NpemVvZihza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0RZTkFNSUNdKTsKKyAgICAvLyBlcyBrYW5uIHNlaW4sIGRhc3Mgbm9jaCBhYmdlbGF1ZmVuZSBPYmpla3RlIGRyaW5zdGVoZW4sCisgICAgLy8gYWJlciBkaWUgUHJ1ZWZ1bmcgaXN0IG1pciBnZXJhZGUgenUgdGV1ZXIuIFRPRE8KKyAgICAvLyBub2NobWFsIGd1Y2tlbiAocmVzdCB2b20gY2FjaGUgd2lyZCBnZ2YuIHVudGVuIGdlcHJ1ZWZ0LikKKyAgICBpZiAoc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9DQUNIRV1bU0FNX0NPVU5UXSA+PSBTQU1fTUFYX01PRFMpCisgICAgICByZXR1cm4gU0FfVE9PX01BTllfTU9EUzsgLy8gZGFubiBuaWNodC4KKyAgfQorCisgIC8vIERhdWVyIGRhcmYgbnVyIGVpbiBpbnQgc2Vpbi4KKyAgaWYgKCFpbnRwKGR1cmF0aW9uKSkKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJXcm9uZyBhcmd1bWVudCAzIHRvIE1vZGlmeVNraWxsQXR0cmlidXRlOiAiCisgICAgImV4cGVjdGVkICdpbnQnLCBnb3QgJS4xME9cbiIsIGR1cmF0aW9uKSk7CisgIC8vIFplaXRzdGVtcGVsIGVybWl0dGVsbgorICBkdXJhdGlvbiArPSB0aW1lKCk7CisKKyAgLy8gc3RhdGlzY2hlciBvZGVyIGR5bi4gTW9kaWZpZXI/CisgIGlmIChpbnRwKHZhbHVlKSkgeworICAgIC8vIE1vZCBkYXJmIG5pY2h0IHp1IGdyb3NzIG9kZXIgenUga2xlaW4gc2Vpbi4gVE9ETzogR3Jlbnplbj8KKyAgICBpZiAodmFsdWUgPCAtMTAwMCkKKyAgICAgIHJldHVybiBTQV9NT0RfVE9PX1NNQUxMOworICAgIGVsc2UgaWYgKHZhbHVlID4gMTAwMCkKKyAgICAgIHJldHVybiBTQV9NT0RfVE9PX0JJRzsKKyAgICBlbHNlIGlmICghdmFsdWUpCisgICAgICByZXR1cm4gU0FfTU9EX0lOVkFMSURfVkFMVUU7IAorICAgIC8vIGplZGVzIE9iamVrdCBkYXJmIG51ciBlaW5lbiBtb2QgaGFiZW4uIFdlbm4gZGllc2VzIHNjaG9uIGVpbmVuIGR5bi4KKyAgICAvLyBoYXQsIG11c3MgZGVyIGdlbG9lc2NodCB3ZXJkZW4gKHN0YXQuIHdlcmRlbiBqYSBlaCBlcnNldHp0KS4KKyAgICBpZiAobWVtYmVyKHNraWxsYXR0cnNbYXRybmFtZSxTQU1fRFlOQU1JQ10sIGNhc3RlcikpCisgICAgICBtX2RlbGV0ZShza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0RZTkFNSUNdLCBjYXN0ZXIpOworICAgIC8vIHNvbnN0IGVpbnRyYWdlbgorICAgIHNraWxsYXR0cnNbYXRybmFtZSwgU0FNX1NUQVRJQ10gKz0gKFtjYXN0ZXI6IHZhbHVlOyBkdXJhdGlvbl0pOworICB9CisgIGVsc2UgaWYgKGNsb3N1cmVwKHZhbHVlKSkgeworICAgIC8vIG51ciBlaW4gTW9kIHBybyBPYmpla3QsIHMuby4KKyAgICBpZiAobWVtYmVyKHNraWxsYXR0cnNbYXRybmFtZSxTQU1fU1RBVElDXSwgY2FzdGVyKSkKKyAgICAgIG1fZGVsZXRlKHNraWxsYXR0cnNbYXRybmFtZSxTQU1fU1RBVElDXSwgY2FzdGVyKTsKKyAgICAvLyBkaXJla3Qgb2huZSB3ZWl0ZXJlIFBydWVmdW5nIGVpbnRyYWdlbgorICAgIHNraWxsYXR0cnNbYXRybmFtZSwgU0FNX0RZTkFNSUNdICs9IChbY2FzdGVyOiB2YWx1ZTsgZHVyYXRpb25dKTsKKyAgfQorICBlbHNlCisgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiV3JvbmcgYXJndW1lbnQgMiB0byBNb2RpZnlTa2lsbEF0dHJpYnV0ZSgpOiAiCisgICAgImV4cGVjdGVkICdpbnQnIG9yICdjbG9zdXJlJywgZ290ICUuMTBPXG4iLHZhbHVlKSk7CisKKyNpZmRlZiBTQVNFVExPRworICBpZiAocXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKSkKKyAgICBTQVNFVExPRyhzcHJpbnRmKCIlczogJU8sICVzLCAlTywgJU9cbiIsIAorICAgICAgICBzdHJmdGltZSgiJXklbSVkLSVIJU0lUyIpLCB0aGlzX29iamVjdCgpLCBhdHJuYW1lLCBjYXN0ZXIsIHZhbHVlKSk7CisjZW5kaWYKKyNpZmRlZiBTQVNUQVRECisgIG9iamVjdCBkYWVtb247CisgIGlmIChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKQorICAgICAgJiYgb2JqZWN0cChkYWVtb249ZmluZF9vYmplY3QoU0FTVEFURCkpKQorICAgIGRhZW1vbi0+TG9nTW9kaWZpZXIoY2FzdGVyLCBhdHJuYW1lLCB2YWx1ZSwgZHVyYXRpb24pOworI2VuZGlmCisgIC8vIG5vY2ggZGVuIENhY2hlIGZ1ZXIgZGllc2VzIFNBIG5ldSBiZXJlY2huZW4KKyAgLy8gVE9ETzogQ2FjaGUgbnVyIGludmFsaWRpZXJlbiwgZGFtaXQgZXIgZXJzdCBiZWkgZGVyIG5hZWNoc3RlbiBBYmZyYWdlCisgIC8vIGFrdHVhbGlzaWVydCB3aXJkLiBTcGFydCBaZWl0LCB3ZW5uIGJpcyBkYWhpbiBtZWhyZXJlIE1vZHMKKyAgLy8gZW50ZmVybnQvYWRkaWVydCB3ZXJkZW4uIERhZnVlciBpc3QgZGllIGdlY2FjaGUgQW56YWhsIGFuIE1vZHMKKyAgLy8gaW5rb25zaXN0ZW50LgorICBVcGRhdGVTQUNhY2hlKCAoe2F0cm5hbWV9KSApOworCisgIFpERUJVRyhzcHJpbnRmKCJNU0E6ICVPLCBaZWl0OiAlZCwgVGlja3M6ICVkXG4iLAorCXRoaXNfb2JqZWN0KCksCisJdXRpbWUoKVsxXS16ZWl0LCB0aWNrcy1nZXRfZXZhbF9jb3N0KCkpKTsKKworICByZXR1cm4gU0FfTU9EX09LOworfQorCitwdWJsaWMgaW50IE1vZGlmeVNraWxsQXR0cmlidXRlKHN0cmluZyBhdHJuYW1lLCBtaXhlZCB2YWx1ZSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgZHVyYXRpb24pIHsKKyAgcmV0dXJuIEludGVybmFsTW9kaWZ5U2tpbGxBdHRyaWJ1dGUoCisgICAgICAoZXh0ZXJuX2NhbGwoKT9wcmV2aW91c19vYmplY3QoKTpNRSksIGF0cm5hbWUsIHZhbHVlLCBkdXJhdGlvbik7Cit9CisKK3B1YmxpYyBpbnQgUmVtb3ZlU2tpbGxBdHRyaWJ1dGVNb2RpZmllcihvYmplY3QgY2FzdGVyLCBzdHJpbmcgYXR0cm5hbWUpIHsKKyAgaWYgKCFzdHJpbmdwKGF0dHJuYW1lKSB8fCAhbWFwcGluZ3Aoc2tpbGxhdHRycykgfHwgIW9iamVjdHAoY2FzdGVyKQorICAgICAgfHwgIW1lbWJlcihza2lsbGF0dHJzLCBhdHRybmFtZSkpCisgICAgcmV0dXJuIFNBX01PRF9OT1RfRk9VTkQ7CisgIC8vIFRPRE86IEJlcmVjaHRpZ3VuZyBwcnVlZmVuLiA7LSkKKworICBpZiAobWVtYmVyKHNraWxsYXR0cnNbYXR0cm5hbWUsIFNBTV9TVEFUSUNdLCBjYXN0ZXIpKSB7CisgICAgbV9kZWxldGUoc2tpbGxhdHRyc1thdHRybmFtZSwgU0FNX1NUQVRJQ10sIGNhc3Rlcik7CisgIH0KKyAgZWxzZSBpZiAobWVtYmVyKHNraWxsYXR0cnNbYXR0cm5hbWUsIFNBTV9EWU5BTUlDXSwgY2FzdGVyKSkgeworICAgIG1fZGVsZXRlKHNraWxsYXR0cnNbYXR0cm5hbWUsIFNBTV9EWU5BTUlDXSwgY2FzdGVyKTsKKyAgfQorICBlbHNlCisgICAgcmV0dXJuIFNBX01PRF9OT1RfRk9VTkQ7CisgIAorICAvLyBUT0RPOiBDYWNoZSBudXIgaW52YWxpZGllcmVuLCBkYW1pdCBlciBlcnN0IGJlaSBkZXIgbmFlY2hzdGVuIEFiZnJhZ2UKKyAgLy8gYWt0dWFsaXNpZXJ0IHdpcmQuIFNwYXJ0IFplaXQsIHdlbm4gYmlzIGRhaGluIG1laHJlcmUgTW9kcworICAvLyBlbnRmZXJudC9hZGRpZXJ0IHdlcmRlbi4gRGFmdWVyIGlzdCBkaWUgZ2VjYWNoZSBBbnphaGwgYW4gTW9kcworICAvLyBpbmtvbnNpc3RlbnQuCisgIFVwZGF0ZVNBQ2FjaGUoICh7YXR0cm5hbWV9KSApOworCisgIHJldHVybiBTQV9NT0RfUkVNT1ZFRDsKK30KKworcHVibGljIGludCBRdWVyeVNraWxsQXR0cmlidXRlKHN0cmluZyBhdHJuYW1lKQoreworICBtaXhlZCBvZmZzZXRzLCBhdHRyOworICBpbnQgbW9kc3VtbWUsIHF1YWwsIHJldCwgY3ZhbDsKKworICBpZiAoIXN0cmluZ3AoYXRybmFtZSkpIC8vIFZBTElEX1NLSUxMX0FUVFJJQlVURVMgYmVydWVja3NpY2h0aWdlbj8KKyAgICByZXR1cm4gMTAwOworCisgIC8vIHdlbm4gbmljaHQgU0FfUVVBTElUWSBnZWZyYWd0IGlzdCwgZXJzdG1hbCBqZW5lcyBlcm1pdHRlbG4sIHdlaWwgZXMgZGVuCisgIC8vIGVyc3RlbiBNb2RpZmllciBhdWYgYWxsZSBhbmRlcmVuIFNBcyBkYXJzdGVsbHQuIFNvbnN0IGRlbiBTdGFydHdlcnQgZnVlcgorICAvLyBTQV9RVUFMSVRZICgxMDApIG1vZGlmaXppZXJ0IGR1cmNoIGV2dGwuIFRvZGVzZm9sZ2VuIGVybWl0dGVsbi4KKyAgaWYgKCBhdHJuYW1lICE9IFNBX1FVQUxJVFkgKQorICAgIHF1YWwgPSBRdWVyeVNraWxsQXR0cmlidXRlKFNBX1FVQUxJVFkpOworICBlbHNlCisgICAgLy8gYmVpIFNBX1FVQUxJVFkgZ2VoZW4gZGllIFRvZGVzZm9sZ2VuIGVpbgorICAgIHF1YWwgPSB0b19pbnQoMTAwICogcG93KDAuOSwgZGVhdGhfc3VmZmVyaW5nKCkvMTAuMCkpOworCisgIC8vIERpZSBPZmZzZXRzIHNpbmQgc296dXNhZ2VuIGRlciBCYXNpc3dlcnQgZGVyIFNBcy4gQWxzIGVyc3RlcyB2ZXJ3dXJzdGVuLAorICAvLyBzb2Zlcm4gdm9yaGFuZGVuLCBuZW4gaW50IGRyaW5zdGVodCB1bmQgZGVyIG9mZnNldCAhPSAwIGlzdC4KKyAgaWYgKCBtYXBwaW5ncChvZmZzZXRzID0gUXVlcnkoUF9TS0lMTF9BVFRSSUJVVEVfT0ZGU0VUUykpCisgICAgICAgJiYgaW50cChhdHRyPW9mZnNldHNbYXRybmFtZV0pIAorICAgICAgICYmIGF0dHIpCisgICAgcmV0ID0gYXR0cjsKKyAgZWxzZQorICAgIHJldCA9IDEwMDsKKworICAvLyB3ZW5uIGtlaW5lIE1vZHMgZ2VzZXR6dCBzaW5kLCB3YXJzIGRhcyBqZXR6dC4gOy0pCisgIGlmICggIW1hcHBpbmdwKHNraWxsYXR0cnMpCisgICAgICAgfHwgIW1lbWJlcihza2lsbGF0dHJzLCBhdHJuYW1lKSApCisgICAgcmV0dXJuIChyZXQqcXVhbCkvMTAwOworCisgIC8vIHdlbm4gQ2FjaGUgZGVyIHN0YXQuIE1vZHMgYWJnZWxhdWZlbiBvZGVyIG9mZmVuYmFyIE9iamVrdGUgemVyc3RvZXJ0CisgIC8vIHd1cmRlbiwgbXVzcyBkZXIgQ2FjaGUgbmV1IGJlcmVjaG5ldCB3ZXJkZW4uCisgIGlmICggc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9DQUNIRV1bU0FNX0NBQ0hFX1RJTUVPVVRdIDwgdGltZSgpCisgICAgICB8fCBzaXplb2Yoc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9TVEFUSUNdKQorICAgICAgICAgK3NpemVvZihza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0RZTkFNSUNdKSAhPQorICAgICAgICAgICBza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0NBQ0hFXVtTQU1fQ09VTlRdICkKKyAgeworICAgIFVwZGF0ZVNBQ2FjaGUoICh7YXRybmFtZX0pICk7CisgICAgLy8gVXBkYXRlU0FDYWNoZSgpIGxvZXNjaHQgdVUgZGFzIFNBLU1hcHBpbmcgb2RlciBFaW50cmFlZ2UgZGFyYXVzLgorICAgIGlmICggIW1hcHBpbmdwKHNraWxsYXR0cnMpCisgICAgICAgICB8fCAhbWVtYmVyKHNraWxsYXR0cnMsIGF0cm5hbWUpICkKKyAgICByZXR1cm4gKHJldCpxdWFsKS8xMDA7CisgIH0KKyAgLy8gU3VtbWUgZGVyIHN0YXRpc2NoZW4gTW9kcy4KKyAgbW9kc3VtbWUgPSBza2lsbGF0dHJzW2F0cm5hbWUsU0FNX0NBQ0hFXVtTQU1fU1VNXTsKKworICAvLyBUT0RPISBFdnRsLiBhbmRlcmUgRGF0ZW4gYWxzIE1FIGFuIGRpZSBGdW5rdGlvbiB1ZWJlcmdlYmVuCisgIC8vIFRPRE8hIGJlcmVpdHMgbmFjaCBBZGRpdGlvbiBkZXMgRnVua3Rpb25zcnVlY2tnYWJld2VydGVzIHBydWVmZW4sIG9iIGRlcgorICAvLyAgICAgICBXZXJ0ZWJlcmVpY2ggZGVzIFNBLU1vZGlmaWVycyB1ZWJlcnNjaHJpdHRlbiBpc3QsIG9kZXIgZnJlaWVuCisgIC8vICAgICAgIFdlcnRlYmVyZWljaCBlcmxhdWJlbiB1bmQgZXJzdCBhbSBFbmRlIGRlY2tlbG4gKGFrdHVlbGxlIFZhcmlhbnRlKQorICAvLyBEeW5hbWlzY2hlIE1vZGlmaWVyIGF1c3dlcnRlbgorICBmb3JlYWNoKCBvYmplY3Qgb2IsIGNsb3N1cmUgY2wsIGludCBkdXJhdGlvbjoKKyAgICAgICAgICAgc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9EWU5BTUlDXSApCisgIHsKKyAgICBpZiAoIGR1cmF0aW9uID4gdGltZSgpICAgICAgICAgICAgICAgLy8gTm9jaCBuaWNodCBhYmdlbGF1ZmVuIHVuZAorICAgICAgICAgJiYgaW50cChjdmFsPWZ1bmNhbGwoY2wsIE1FKSkgKSAvLyBGdW5rdGlvbiBsaWVmZXJ0IGludCB6dXJ1ZWNrCisgICAgICBtb2RzdW1tZSArPSBjdmFsOworICAgIGVsc2UgeworICAgICAgbV9kZWxldGUoc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9EWU5BTUlDXSwgb2IpOworICAgICAgc2tpbGxhdHRyc1thdHJuYW1lLFNBTV9DQUNIRV1bU0FNX0NPVU5UXS0tOworICAgIH0KKyAgfQorICByZXQgPSAoKHJldCttb2RzdW1tZSkqcXVhbCkvMTAwOworICBpZiAoIHJldCA8IDEwICkKKyAgICByZXQgPSAxMDsKKyAgZWxzZSBpZiAoIHJldCA+IDEwMDAgKQorICAgIHJldCA9IDEwMDA7CisKKyAgcmV0dXJuIHJldDsKK30KKworcHVibGljIHZhcmFyZ3MgbWFwcGluZyBRdWVyeVNraWxsQXR0cmlidXRlTW9kaWZpZXIob2JqZWN0IGNhc3RlciwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgKmF0dHJuYW1lcykgeworICAKKyAgLy8gYXVmIGFiZ2VsYXVmZW5lIE1vZGlmaWthdG9yZW4gcHJ1ZWZlbgorICBpZiAoIXBvaW50ZXJwKGF0dHJuYW1lcykpCisgICAgVXBkYXRlU0FDYWNoZSggKHt9KSApOworICBlbHNlCisgICAgVXBkYXRlU0FDYWNoZShhdHRybmFtZXMpOworCisgIGlmICghbWFwcGluZ3Aoc2tpbGxhdHRycykpCisgICAgcmV0dXJuIChbXSk7CisgIGlmICghcG9pbnRlcnAoYXR0cm5hbWVzKSB8fCAhc2l6ZW9mKGF0dHJuYW1lcykpCisgICAgYXR0cm5hbWVzID0gbV9pbmRpY2VzKHNraWxsYXR0cnMpOyAvLyBhbGxlIGR1cmNoc3VjaGVuCisgIGVsc2UgLy8gc2Nobml0dG1lbmdlIGRlciBnZXcuIHVuZCB2b3JoYW5kZW5lbiBiaWxkZW4KKyAgICBhdHRybmFtZXMgPSBtX2luZGljZXMoc2tpbGxhdHRycykgJiBhdHRybmFtZXM7CisgIAorICBtYXBwaW5nIHJlcz1tX2FsbG9jYXRlKHNpemVvZihhdHRybmFtZXMpLCAxKTsKKworICBmb3JlYWNoKHN0cmluZyBhdHI6IGF0dHJuYW1lcykgeworICAgIHJlc1thdHJdID0gbV9hbGxvY2F0ZSg1LCAyKTsgLy8gbWFsIGZ1ZXIgNSBXZXJ0ZSBQbGF0eiByZXNlcnZpZXJlbgorICAgIGlmICghb2JqZWN0cChjYXN0ZXIpKSB7CisgICAgICAvLyB3ZW5uIGtlaW4gYmVzdGltbXRlciBjYXN0ZXIgYW5nZWZyYWd0IGlzdCwgYWxsZSBtb2RzIGxpZWZlcm4KKyAgICAgIGZvcmVhY2gob2JqZWN0IGMsIGludCB2YWx1ZSwgaW50IGR1cjogc2tpbGxhdHRyc1thdHIsIFNBTV9TVEFUSUNdKSB7CisJcmVzW2F0cl0gKz0gKFtjOiB2YWx1ZTsgZHVyXSk7CisgICAgICB9CisgICAgICBmb3JlYWNoKG9iamVjdCBjLCBjbG9zdXJlIHZhbHVlLCBpbnQgZHVyOiBza2lsbGF0dHJzW2F0ciwgU0FNX0RZTkFNSUNdKSB7CisJcmVzW2F0cl0gKz0gKFtjOiB2YWx1ZTsgZHVyXSk7CisgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgLy8gc29uc3QgbnVyIGRlbiBNb2Qgdm9uIGNhc3RlcgorICAgICAgaWYgKG1lbWJlcihza2lsbGF0dHJzW2F0ciwgU0FNX1NUQVRJQ10sIGNhc3RlcikpIHsKKwlyZXNbYXRyXSArPSAoW2Nhc3RlcjogCisJCQkgc2tpbGxhdHRyc1thdHIsIFNBTV9TVEFUSUNdW2Nhc3RlciwgU0FNX1ZBTFVFXTsKKwkgICAgICAgICAgICAgICAgIHNraWxsYXR0cnNbYXRyLCBTQU1fU1RBVElDXVtjYXN0ZXIsIFNBTV9EVVJBVElPTl0KKwkJICAgIF0pOworICAgICAgfQorICAgICAgZWxzZSBpZiAobWVtYmVyKHNraWxsYXR0cnNbYXRyLCBTQU1fRFlOQU1JQ10sIGNhc3RlcikpIHsKKwlyZXNbYXRyXSArPSAoW2Nhc3RlcjoKKwkJCSBza2lsbGF0dHJzW2F0ciwgU0FNX0RZTkFNSUNdW2Nhc3RlciwgU0FNX1ZBTFVFXTsKKwkgICAgICAgICAgICAgICAgIHNraWxsYXR0cnNbYXRyLCBTQU1fRFlOQU1JQ11bY2FzdGVyLCBTQU1fRFVSQVRJT05dCisJCSAgICBdKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIHJlczsKK30KKworLy8gS29tcGF0aWJpbGl0YWV0c2Z1bmt0aW9uIG1pdCBhbHRlbSBJbnRlcmZhY2UuIElzdCBudXIgZWluIFdyYXBwZXIsIGRlcgorLy8gdmFsdWUgdW1yZWNobmV0IHVuZCAnYWx0ZScgUnVlY2tnYWJld2VydGUgbGllZmVydC4KKworcHVibGljIHZhcmFyZ3MgaW50IE1vZGlmeVNraWxsQXR0cmlidXRlT2xkKG9iamVjdCBjYXN0ZXIsIHN0cmluZyBhdHJuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgdmFsdWUsIGludCBkdXJhdGlvbiwgbWl4ZWQgZnVuKSB7CisgIGludCByZXM7CisgIC8vIENhbGxlciBlcm1pdHRlbG4KKyAgaWYgKGV4dGVybl9jYWxsKCkpIGNhc3Rlcj1wcmV2aW91c19vYmplY3QoKTsKKyAgZWxzZSBjYXN0ZXI9TUU7CisKKyAgLy8gQ2xvc3VyZXMga29lbm5lbiB2aWEgTW9kaWZ5U2tpbGxBdHRyaWJ1dGVPbGQoKSBuaWNodCBtZWhyIGdlc2V0enQgd2VyZGVuLAorICAvLyBkYSBkZXJlbiBSdWVja2dhYmV3ZXJ0IG5pY2h0IHNpbm52b2xsIHVtZ2VyZWNobmV0IHdlcmRlbiBrb2VubmVuLiAoTWFuCisgIC8vIHdlaXNzIG5pY2h0LCBvYiBlcyBlaW5lIG5ldWUgb2RlciBhbHRlIENsb3N1cmUgaXN0LikKKyAgaWYgKHBvaW50ZXJwKGZ1bikgfHwgY2xvc3VyZXAoZnVuKSkKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIkNsb3N1cmVzIGZvciBTQSBtb2RpZmllcnMgY2FuJ3QgYmUgc2V0IGJ5ICIKKyAgICAgICJNb2RpZnlTa2lsbEF0dHJpYnV0ZU9sZCgpISBVc2UgTW9kaWZ5U2tpbGxBdHRyaWJ1dGUoKSFcbiIpKTsKKyAgCisgIHJlcyA9IEludGVybmFsTW9kaWZ5U2tpbGxBdHRyaWJ1dGUoY2FzdGVyLCBhdHJuYW1lLCB2YWx1ZS0xMDAsIGR1cmF0aW9uKTsKKyAgLy8gZGllIGFsdGUgZnVua3Rpb24gaGF0dGUgbnVyIDAgZnVlciB1bmd1ZWx0aWdlbiBXZXJ0IHVuZCA8IDAgZnVlciB6dQorICAvLyBrbGVpbmVzIExldmVsIGFscyBSdWVja2dhYmV3ZXJ0LiBadSBrbGVpbmVzIExldmVsIGdpYnQgbmljaHQgbWVociwgYWxzbworICAvLyBibGVpYnQgbnVyIDAgYWxzIFNhbW1lbC1GZWhsZXJjb2RlIHVlYnJpZy4gKnNldWZ6KgorICBpZiAocmVzIDwgMCkgcmV0dXJuIDA7CisgIHJldHVybiByZXM7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvc2tpbGxfdXRpbHMuYyBiL3N0ZC9saXZpbmcvc2tpbGxfdXRpbHMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNGNhZjc1Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2xpdmluZy9za2lsbF91dGlscy5jCkBAIC0wLDAgKzEsMzUgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBsaXZpbmcvc2tpbGxfdXRpbHMgLS0gc29tZSBoZWxwZXIgZnVuY3Rpb25zIGZvciBtYW5pcHVsYXRpbmcgc2tpbGwgZGF0YSAKKy8vICAgICAgICAgICAgICAgICAgICAgICBuZWVkZWQgaW4gbW9yZSB0aGFuIG9uZSBwcm9ncmFtLgorLy8KKy8vICRJZDogc2tpbGxfdXRpbHMuYyA2NzM4IDIwMDgtMDItMTkgMTg6NDY6MTRaIEh1bW5pICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKworcHJvdGVjdGVkIHZvaWQgU2tpbGxSZXNUcmFuc2ZlcihtYXBwaW5nIGZyb21fTSwgbWFwcGluZyB0b19NKQoreworICBpZiAoICFtYXBwaW5ncChmcm9tX00pIHx8ICFtYXBwaW5ncCh0b19NKSApCisgICAgcmV0dXJuOworCisgIGlmICggbWVtYmVyKGZyb21fTSxTSV9TS0lMTERBTUFHRSkgKQorICAgIHRvX01bU0lfU0tJTExEQU1BR0VdID0gdG9faW50KGZyb21fTVtTSV9TS0lMTERBTUFHRV0pOworCisgIGlmICggbWVtYmVyKGZyb21fTSxTSV9TS0lMTERBTUFHRV9NU0cpICkKKyAgICB0b19NW1NJX1NLSUxMREFNQUdFX01TR10gPSB0b19zdHJpbmcoZnJvbV9NW1NJX1NLSUxMREFNQUdFX01TR10pOworCisgIGlmICggbWVtYmVyKGZyb21fTSxTSV9TS0lMTERBTUFHRV9NU0cyKSApCisgICAgdG9fTVtTSV9TS0lMTERBTUFHRV9NU0cyXSA9IHRvX3N0cmluZyhmcm9tX01bU0lfU0tJTExEQU1BR0VfTVNHMl0pOworCisgIGlmICggbWVtYmVyKGZyb21fTSxTSV9TS0lMTERBTUFHRV9UWVBFKSApCisgICAgdG9fTVtTSV9TS0lMTERBTUFHRV9UWVBFXSA9IGZyb21fTVtTSV9TS0lMTERBTUFHRV9UWVBFXTsKKworICBpZiAoIG1lbWJlcihmcm9tX00sU0lfU1BFTEwpICkKKyAgICB0b19NW1NJX1NQRUxMXSA9IGZyb21fTVtTSV9TUEVMTF07Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9saXZpbmcvc2tpbGxzLmMgYi9zdGQvbGl2aW5nL3NraWxscy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjkzYzlkY2MKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL3NraWxscy5jCkBAIC0wLDAgKzEsNTk1IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbGl2aW5nL3NraWxscy5jIC0tIEdpbGRlbi0sIFNraWxsLSB1bmQgU3BlbGxmdW5rdGlvbmVuIGZ1ZXIgTGViZXdlc2VuCisvLworLy8gJElkOiBza2lsbHMuYyA4NzU1IDIwMTQtMDQtMjYgMTM6MTM6NDBaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL2xpdmluZy9zdGRfc2tpbGxzIjsKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxsaXZpbmcvc2tpbGxzLmg+CisjaW5jbHVkZSA8bGl2aW5nL3NraWxsX2F0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvbGlmZS5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisKKy8vIHNwZWljaGVydCBkaWUgU3BlbGwtRmF0aWd1ZXMgKGdsb2JhbCwgU3BydWNoZ3J1cHBlbiwgRWluemVsc3BydWVjaGUpCitwcml2YXRlIG1hcHBpbmcgc3BlbGxfZmF0aWd1ZXMgPSAoW10pOworCisvLyBQcm90b3R5cGVuCitwcml2YXRlIHZvaWQgZXhwaXJlX3NwZWxsX2ZhdGlndWVzKCk7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIC8vIG1haW5seSBuZWNlc3NhcnkgZm9yIHBsYXllcnMsIGJ1dCB0aGVyZSBtYXkgYmUgc29tZSBOUEMgd2l0aCBzYXZlZmlsZXMuCisgIC8vIEFkZGl0aW9uYWxseSwgaXQgc2ltcGxpZmllcyBleHBpcmF0aW9uIG9mIG9sZCBrZXlzIHRvIGhhdmUgaXQgaGVyZS4KKyAgY2FsbF9vdXQoIydleHBpcmVfc3BlbGxfZmF0aWd1ZXMsIDQpOworfQorCisKKy8vIERpZXNlIC0gaGllciBzY2hlaW5iYXIgc2lubmxvc2UgLSBGdW5rdGlvbiB3aXJkIHZvbiAvc3RkL3BsYXllci9za2lsbHMuYyBkYW5uIAorLy8gdWViZXJsYWRlbi4KK3B1YmxpYyBpbnQgaXNfZGVhY3RpdmF0ZWRfc2tpbGwoc3RyaW5nIHNuYW1lLCBzdHJpbmcgZ2lsZGUpCit7CisJcmV0dXJuIDA7Cit9CisKKworCitzdGF0aWMgc3RyaW5nIF9xdWVyeV92aXNpYmxlX2d1aWxkKCkKK3sgc3RyaW5nIHJlczsKKworICBpZiAoIHN0cmluZ3AocmVzPVF1ZXJ5KFBfVklTSUJMRV9HVUlMRCkpICkKKyAgICByZXR1cm4gcmVzOworCisgIHJldHVybiBRdWVyeVByb3AoUF9HVUlMRCk7Cit9CisKK3N0YXRpYyBzdHJpbmcgX3F1ZXJ5X3Zpc2libGVfc3ViZ3VpbGRfdGl0bGUoKQoreyBzdHJpbmcgcmVzOworCisgIGlmICggc3RyaW5ncChyZXM9UXVlcnkoUF9WSVNJQkxFX1NVQkdVSUxEX1RJVExFKSkgKQorICAgIHJldHVybiByZXM7CisKKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX1NVQkdVSUxEX1RJVExFKTsKK30KKworc3RhdGljIG1peGVkIF9xdWVyeV9ndWlsZF9wcmVwYXJlYmxvY2soKQoreyBtYXBwaW5nIHJlczsKKyAgc3RyaW5nICBnaWxkZTsKKworICBpZiAoICFzdHJpbmdwKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgKQorICAgIHJldHVybiAwOworICBpZiAoICFtYXBwaW5ncChyZXM9UXVlcnkoUF9HVUlMRF9QUkVQQVJFQkxPQ0spKSAKKyAgICAgIHx8ICFtZW1iZXIocmVzLGdpbGRlKSApCisgICAgcmV0dXJuIDA7CisgIHJldHVybiByZXNbZ2lsZGVdOworfQorCitzdGF0aWMgbWl4ZWQgX3NldF9ndWlsZF9wcmVwYXJlYmxvY2sobWl4ZWQgYXJnKQoreyBtYXBwaW5nIHJlczsKKyAgc3RyaW5nICBnaWxkZTsKKworICBpZiAoICFzdHJpbmdwKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgKQorICAgIHJldHVybiAwOworICBpZiAoICFtYXBwaW5ncChyZXM9UXVlcnkoUF9HVUlMRF9QUkVQQVJFQkxPQ0spKSApCisgICAgcmVzPShbXSk7CisKKyAgcmVzW2dpbGRlXT1hcmc7CisgIFNldChQX0dVSUxEX1BSRVBBUkVCTE9DSyxyZXMpOworCisgIHJldHVybiBhcmc7Cit9CisKKworcHJpdmF0ZSBub3NhdmUgaW50IHZhbGlkX3NldHNraWxsc19vdmVycmlkZTsKKy8vIE1hbiBzb2xsdGUgZWlnZW50bGljaCBqYSBuaWNodCBQYXJhbWV0ZXIgYWxzIGdsb2JhbGUgVmFyaWFibGVuCisvLyB1ZWJlcmdlYmVuLCBhYmVyIGhpZXIgZ2luZyBlcyBuaWNodCBhbmRlcnMKK25vbWFzayBwcml2YXRlIGludCB2YWxpZF9zZXRza2lsbHMoc3RyaW5nIGdpbGRlKQoreyBzdHJpbmcgZm47CisKKyAgaWYgKCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKSApCisgICAgcmV0dXJuIDE7IC8vIE1vbnN0ZXIgZHVlcmZlbiBzaWNoIHNlbGJlciBTa2lsbHMgc2V0emVuIDopCisKKyAgaWYgKCBRdWVyeVByb3AoUF9URVNUUExBWUVSKSB8fCBJU19XSVpBUkQodGhpc19vYmplY3QoKSkgKQorICAgICAgcmV0dXJuIDE7IC8vIFRlc3RzcGllbGVyIHVuZCBNYWdpZXIgc2luZCBzY2h1dHpsb3NlIE9wZmVyIDstKQorCisgIGlmICggcHJldmlvdXNfb2JqZWN0KCkgKQorICB7CisgICAgaWYgKCBwcmV2aW91c19vYmplY3QoKT09dGhpc19vYmplY3QoKQorICAgICAgICAmJiB0aGlzX2ludGVyYWN0aXZlKCk9PXRoaXNfb2JqZWN0KCkgKQorICAgICAgcmV0dXJuIDE7CisKKyAgICBmbj1vYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSk7CisgICAgaWYgKCBmblswLi43XT09Ii9naWxkZW4vIgorICAgICAgICB8fCBmblswLi4xMV09PSIvc3BlbGxib29rcy8iCisgICAgICAgIHx8IGZuWzAuLjddPT0iL3NlY3VyZS8iCisgICAgICAgIHx8IGZuWzAuLjExXT09Ii9wL3phdWJlcmVyLyIgKQorICAgICAgcmV0dXJuIDE7IC8vIERpZSBzb2xsdGVuIHByb2JsZW1sb3MgYWVuZGVybiBkdWVyZmVuCisKKyAgICBpZiAoIGZpbGVfc2l6ZSgiL2dpbGRlbi9hY2Nlc3NfcmlnaHRzIik+MAorICAgICAgICYmIGNhbGxfb3RoZXIoIi9naWxkZW4vYWNjZXNzX3JpZ2h0cyIsCisgICAgICAgICAgICAgICAgICAgICJhY2Nlc3NfcmlnaHRzIiwKKyAgICAgICAgICAgICAgICAgICAgZ2V0dWlkKHByZXZpb3VzX29iamVjdCgpKSwKKyAgICAgICAgICAgICAgICAgICAgZ2lsZGUrIi5jIikpCisgICAgICByZXR1cm4gMTsgLy8gU2V0emVuZGVzIE9iamVrdCBrb21tdCB2b20gR2lsZGVucHJvZ3JhbW1pZXJlcgorCisgICAgaWYgKCBmaWxlX3NpemUoIi9naWxkZW4vIitnaWxkZSsiLmMiKT4wCisgICAgICAgICYmIGNhbGxfb3RoZXIoIi9naWxkZW4vIitnaWxkZSwKKyAgICAgICAgICAgICAgICAgICAgICAidmFsaWRfc2V0c2tpbGxzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGV4cGxvZGUoZm4sIiMiKVswXSkgKQorICAgICAgcmV0dXJuIDE7IC8vIERpZSBHaWxkZSBzZWxiZXIga2FubiBBdXNuYWhtZW4genVsYXNzZW4KKyAgfQorCisgIGlmICh2YWxpZF9zZXRza2lsbHNfb3ZlcnJpZGUpCisgIHsKKyAgICB2YWxpZF9zZXRza2lsbHNfb3ZlcnJpZGU9MDsKKyAgICByZXR1cm4gMTsgLy8gRnVlcnMgU2V0emVuIGRlciBDbG9zdXJlCisgIH0KKworICBpZiAoIHRoaXNfaW50ZXJhY3RpdmUoKSApCisgIHsKKyAgICBpZiAoIElTX0FSQ0godGhpc19pbnRlcmFjdGl2ZSgpKSApCisgICAgICByZXR1cm4gMTsgLy8gRXJ6bWFnaWVyIGR1ZXJmZW4gaW1tZXIgYWVuZGVybgorCisgICAgaWYgKCBjYWxsX290aGVyKCIvZ2lsZGVuL2FjY2Vzc19yaWdodHMiLAorICAgICAgICAgICAgICAgICAgICAiYWNjZXNzX3JpZ2h0cyIsCisgICAgICAgICAgICAgICAgICAgIGdldHVpZCh0aGlzX2ludGVyYWN0aXZlKCkpLAorICAgICAgICAgICAgICAgICAgICBnaWxkZSsiLmMiKSkKKyAgICAgIHJldHVybiAxOyAgLy8gRGVyIEdpbGRlbnByb2dyYW1taWVyZXIgc2VsYmVyIGF1Y2gKKyAgfQorCisgIC8vIEZ1ZXIgZGllIFdhZmZlbnNraWxscywgZGllIHNvbGxlbiBzaWNoIHNlbGJzdCBhdWNoIHNldHplbiBkdWVyZmVuCisgIGlmICghdGhpc19pbnRlcmFjdGl2ZSgpICYmIHRoaXNfb2JqZWN0KCk9PXByZXZpb3VzX29iamVjdCgpKQorCSAgcmV0dXJuIDE7CisgIAorICAKKyAgbG9nX2ZpbGUoIlNFVFNLSUxMUyIsc3ByaW50ZigiKioqKipcbiVzIFBPOiVPLT5UTzolTyBUSTolT1xuIEdVSUxEOiVzIFZFUkJfQVJHUzonJXMnXG4iLAorICAgICAgICAgICAgY3RpbWUodGltZSgpKVs0Li4xNV0sCisgICAgICAgICAgICBwcmV2aW91c19vYmplY3QoKSwKKyAgICAgICAgICAgIHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgICB0aGlzX2ludGVyYWN0aXZlKCksCisgICAgICAgICAgICBnaWxkZSwKKyAgICAgICAgICAgICggdGhpc19pbnRlcmFjdGl2ZSgpID8gcXVlcnlfdmVyYigpICsgIiAiICsKKyAgICAgICAgICAgICAgICB0aGlzX2ludGVyYWN0aXZlKCktPl91bnBhcnNlZF9hcmdzKCkgOiAiIikgKSk7CisKKyAgcmV0dXJuIDA7Cit9CisKKy8vIE51ciBpbnRlcm5lIFZlcndlbmR1bmcsIHZhbHVlIHdpcmQgbmljaHQgd2VpdGVyIHBydWVmdCwgbXVzcyBvayBzZWluLgorLy8gRXMgd2lyZCBrZWluZSBLb3BpZSB2b24gdmFsdWUgZ2VtYWNodCwgd2VubiBlcyBpbnMgTWFwcGluZyBnZXNjaHJpZWJlbgorLy8gd2lyZCEKK3ByaXZhdGUgbWFwcGluZyBpbnRlcm5hbF9zZXRfbmV3c2tpbGxzKG1hcHBpbmcgdmFsdWUsIHN0cmluZyBnaWxkZSkgeworICBtYXBwaW5nIHNraWxsczsKKworICAvLyBpbiBkZXIgcmljaHRpZ2VuIEdpbGRlIHNldHplbi4KKyAgaWYgKCAhZ2lsZGUgJiYgIShnaWxkZT1RdWVyeVByb3AoUF9HVUlMRCkpICkKKyAgICBnaWxkZT0iQU5ZIjsKKworICAvLyBRdWVyeSgpLCBoaWVyIGlzdCBlaW5lIEtvcGllIG5pY2h0IHNpbm52b2xsLgorICBpZiAoICFtYXBwaW5ncChza2lsbHM9UXVlcnkoUF9ORVdTS0lMTFMsRl9WQUxVRSkpICkgeworICAgIHNraWxscz0oW10pOworICAgIFNldChQX05FV1NLSUxMUywgc2tpbGxzLCBGX1ZBTFVFKTsKKyAgfQorCisgIC8vIEZhbGxzIGRpZXMgaGllciBtYWwgYXVzZ2V3ZXJ0ZXQgd2VyZGVuIHNvbGx0ZSwgbmljaHQgdmVyZ2Vzc2VuLCBkYXNzCisgIC8vIGVpbmlnZSBGdW5rdGlvbiBoaWVyIGltIEZpbGUgZGllIFByb3AgZXZ0bC4gdmlhCisgIC8vIGludGVybmFsX3F1ZXJ5X25ld3NraWxscygpIGFicnVmZW4gdW5kIGRpcmVrdCBhZW5kZXJuLi4uCisgIHZhbGlkX3NldHNraWxscyhnaWxkZSk7IC8vIFNpY2hlcmhlaXRzdWViZXJwcnVlZnVuZworICAKKyAgLy8gU2tpbGxzIHNldHplbi4gU2V0KCkgdW5ub2V0aWcsIHdlaWwgd2lyIGRhcyB2b24gUXVlcnkoKSBnZWxpZWZlcnRlCisgIC8vIE1hcHBpbmcgYWVuZGVybiB1bmQgZGFzIGphIHZpYSBSZWZlcmVueiBiZWtvbW1lbiBoYWJlbi4KKyAgc2tpbGxzW2dpbGRlXT12YWx1ZTsKKyAgLy9TZXQoUF9ORVdTS0lMTFMsc2tpbGxzKTsKKworICByZXR1cm4odmFsdWUpOworfQorCisvLyBudXIgenVyIGludGVybmVuIFZlcndlbmR1bmcsIGVzIHdpcmQga2VpbmUgS29waWUgZGVzIFNraWxsbWFwcGluZ3MgZ2VtYWNodCEKK3ByaXZhdGUgbWFwcGluZyBpbnRlcm5hbF9xdWVyeV9uZXdza2lsbHMoc3RyaW5nIGdpbGRlKSB7CisgIG1hcHBpbmcgc2tpbGxzOworCisgIC8vIHJpY2h0aWdlIEdpbGRlIGFiZnJhZ2VuLgorICBpZiAoICFnaWxkZSAmJiAhKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgKQorICAgIGdpbGRlPSJBTlkiOworCisgIHNraWxscz1RdWVyeShQX05FV1NLSUxMUyk7CisKKyAgaWYgKCFtYXBwaW5ncChza2lsbHMpIHx8ICFtYXBwaW5ncChza2lsbHM9c2tpbGxzW2dpbGRlXSkgKQorICAgIHJldHVybiAoW10pOworCisgIHJldHVybihza2lsbHMpOworfQorCisvLyBFaWdlbnRsaWNoIHNvbGx0ZSBtYW4gZGVuIF9xdWVyeS1GdW5rdGlvbmVuIGtlaW5lIFBhcmFtZXRlciBnZWJlbi4uLgorc3RhdGljIHZhcmFyZ3MgbWFwcGluZyBfcXVlcnlfbmV3c2tpbGxzKHN0cmluZyBnaWxkZSkgeworCisgIC8vIHNvbnN0IEtvcGllIGRlcyBzcGVsbG1hcHBpbmdzIGxpZWZlcm4hIEtvc3RldCB6d2FyLCBhYmVyIHZlcmhpbmRlcnQKKyAgLy8gZWluaWdlIGFuZGVyZSBCdWdzIHVuZCB2ZXJzZWhlbnRsaWNoZSBBZW5kZXJ1bmdlbiBhbiBkZW4gU2tpbGxzIQorICByZXR1cm4oZGVlcF9jb3B5KGludGVybmFsX3F1ZXJ5X25ld3NraWxscyhnaWxkZSkpKTsKK30KKworLy8gRWlnZW50bGljaCBzb2xsdGUgbWFuIGRlbiBfc2V0LUZ1bmt0aW9uZW4ga2VpbmUgd2VpdGVyZW4gUGFyYW1ldGVyIGdlYmVuCitzdGF0aWMgdmFyYXJncyBtYXBwaW5nIF9zZXRfbmV3c2tpbGxzKG1hcHBpbmcgdmFsdWUsIHN0cmluZyBnaWxkZSkgeworCisgIC8vIHZhbHVlIGF1ZiBNYXBwaW5ncyBub3JtYWxpc2llcmVuLCBnZ2YuIEtvcGllcmVuCisgIGlmICggIW1hcHBpbmdwKHZhbHVlKSApCisgICAgICB2YWx1ZT0oW10pOworICBlbHNlCisgICAgICAvL3p1ciBTaWNoZXJoZWl0LCB3ZXIgd2Vpc3MsIHdhcyBkZXIgc2V0emVuZGUgbm9jaCBkYW1pdCBtYWNodC4uLgorICAgICAgdmFsdWU9ZGVlcF9jb3B5KHZhbHVlKTsKKworICAvLyB1bmQgc2V0emVuLi4uCisgIGludGVybmFsX3NldF9uZXdza2lsbHModmFsdWUsIGdpbGRlKTsKKworICAvLyB1bmQgbm9jaCBuZSBLb3BpZSB2b24gZGVtIExpZWZlcm4sIHdhcyB3aXIgZ2VzZXR6dCBoYWJlbiAoa2VpbmUgUmVmZXJlbnosCisgIC8vIHNvbnN0IGtvZW5udGUgZGVyIEF1ZnJ1ZmVuZGUgamEgbm9jaCBpbSBOYWNoaGluZWluIGFlbmRlcm4pLgorICByZXR1cm4oX3F1ZXJ5X25ld3NraWxscyhnaWxkZSkpOworfQorCitwcml2YXRlIG1hcHBpbmcgSW50ZXJuYWxRdWVyeVNraWxsKHN0cmluZyBzbmFtZSwgc3RyaW5nIGdpbGRlKSB7CisgIG1peGVkIHNraWxsLCBza2lsbHM7CisgIC8vIEluIGlzX2FueSB3aXJkIGdlc3BlaWNoZXJ0LCBvYiBlcyBlaW4gZ2lsZGVudW5hYmhhZW5naWVyIFNraWxsIGlzdCwKKyAgLy8gZnVlciBkaWUgaXNfZGVhY3RpdmF0ZV9za2lsbC1BYmZyYWdlLgorICBpbnQgaXNfYW55OworCisgIC8vIFNraWxscyBrb21wbGV0dCBhYmZyYWdlbiwga2VpbmUgc3Blei4gR2lsZGUKKyAgaWYgKCFtYXBwaW5ncChza2lsbHM9UXVlcnkoUF9ORVdTS0lMTFMsRl9WQUxVRSkpKQorICAgICAgcmV0dXJuIDA7CisKKyAgaWYgKHN0cmluZ3AoZ2lsZGUpICYmIHNpemVvZihnaWxkZSkpIHsKKyAgICAvL2Jlc3RpbW10ZSBHaWxkZSBhbmdlZ2ViZW4sIGd1dCwgZG9ydCBndWNrZW4uCisgICAgaWYgKG1hcHBpbmdwKHNraWxsc1tnaWxkZV0pKQorICAgICAgc2tpbGw9c2tpbGxzW2dpbGRlXVtzbmFtZV07IAorICB9CisgIGVsc2UgeworICAgIGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKTsgLy9yZWFsZSBHaWxkZSBob2xlbgorICAgIGlmIChnaWxkZSAmJiBtYXBwaW5ncChza2lsbHNbZ2lsZGVdKSAmJiAKKwkoc2tpbGw9c2tpbGxzW2dpbGRlXVtzbmFtZV0pKSB7CisgICAgICAvLyBnaWJ0IGVzIGRlbiBTcGVsbCBpbiBkZXIgR2lsZGUgZGVzIFNwaWVsZXJzPworICAgICAgLy8gZGFubiBoaWVyIG5peCBtYWNoZW4uLi4KKyAgICB9CisgICAgZWxzZSBpZiAobWFwcGluZ3Aoc2tpbGxzWyJBTlkiXSkpIHsKKyAgICAgLy8gWnVtIFNjaGx1c3M6IEdpYnQgZXMgZGVuIFNraWxsIHZpZWxsZWljaHQgR2lsZGVudW5hYmhhZW5naWc/CisgICAgICBza2lsbD1za2lsbHNbIkFOWSJdW3NuYW1lXTsKKyAgICAgIC8vIHdlbm4gbWFuIGhpZXIgcmVpbmtvbW10LCBkYW5uIHNwYWV0ZXIgbWl0IGlzX2RlYWN0aXZhdGVkX3NraWxsKCkgCisgICAgICAvLyBwcnVlZmVuIQorICAgICAgaXNfYW55PTE7CisgICAgfQorICB9CisKKyAgLy8gd2VubiBrZWluIFNraWxsIGdlZnVuZGVuLCBtaXQgMCBkaXJla3QgcmF1cworICBpZiAoIXNraWxsKSByZXR1cm4gMDsKKworICAvLyBCZWkgZ2lsZGVudW5hYmhhZW5naWdlbiBhdWNoIGltIFNraWxsbWFwcGluZyB2ZXJtZXJrZW4KKyAgaWYgKCBpc19hbnkgKSB7CQorICAgICAgc2tpbGwrPShbU0lfR1VJTEQ6IkFOWSJdKTsJCisgICAgICAvLyBJc3QgZXIgdmllbGxlaWNodCBpbiBkZXIgR2lsZGUgZGVzIFNwaWVsZXJzIGRlYWt0aXZpZXJ0PyAJCQorICAgICAgLy8gRGllcyBrYW5uIG51ciBkZXIgRmFsbCBzZWluLCB3ZW5uIGVzIGtlaW4gR2lsZGVuc2tpbGwgaXN0LgkJCisgICAgICBpZiAoaXNfZGVhY3RpdmF0ZWRfc2tpbGwoc25hbWUsZ2lsZGUpKSB7CQkgICAgCisJICByZXR1cm4gMDsJCQorICAgICAgfQorICB9CisKKyAgcmV0dXJuKHNraWxsKTsKK30KKworcHVibGljIHZhcmFyZ3MgbWFwcGluZyBRdWVyeVNraWxsKHN0cmluZyBzbmFtZSwgc3RyaW5nIGdpbGRlKSB7CisgCisgICAgaWYgKCFzdHJpbmdwKHNuYW1lKSB8fCAhc2l6ZW9mKHNuYW1lKSkKKwlyZXR1cm4gMDsKKworICAgIC8vS29waWUgenVydWVja2xpZWZlcm4KKyAgICByZXR1cm4oZGVlcF9jb3B5KEludGVybmFsUXVlcnlTa2lsbChzbmFtZSxnaWxkZSkpKTsKK30KKworI2RlZmluZSBTTVVMKHgseSkgKCh4PDAgJiYgeTwwKT8oLTEqeCp5KTooeCp5KSkKK3B1YmxpYyB2YXJhcmdzIGludCBRdWVyeVNraWxsQWJpbGl0eShzdHJpbmcgc25hbWUsIHN0cmluZyBnaWxkZSkKK3sgbWFwcGluZyBza2lsbDsKKyAgc3RyaW5nIHNraWxsMjsKKworICBpZiAoICEoc2tpbGw9SW50ZXJuYWxRdWVyeVNraWxsKHNuYW1lLCBnaWxkZSkpICkKKyAgICByZXR1cm4gMDsKKworICBpbnQgdmFsPXNraWxsW1NJX1NLSUxMQUJJTElUWV07CisKKyAgaWYgKHNraWxsMj1za2lsbFtTSV9JTkhFUklUXSkKKyAgeworICAgIGludCB2YWwyOworICAgIHZhbDI9UXVlcnlTa2lsbEFiaWxpdHkoc2tpbGwyKTsKKyAgICB2YWw9KHZhbCpNQVhfQUJJTElUWStTTVVMKHZhbCx2YWwyKSkvKDIqTUFYX0FCSUxJVFkpOworICB9CisKKyAgcmV0dXJuIHZhbDsKK30KKworcHJvdGVjdGVkIHZhcmFyZ3MgbWl4ZWQgTGltaXRBYmlsaXR5KG1hcHBpbmcgc2luZm8sIGludCBkaWZmKQoreyBtaXhlZCBhYmlsOworICBpbnQgbWF4LG9sZCxkMjsKKworICBhYmlsPXNpbmZvW1NJX1NLSUxMQUJJTElUWV07CisKKyAgaWYgKCAhaW50cChhYmlsKSApCisgICAgcmV0dXJuIHNpbmZvOworICBvbGQ9YWJpbDsKKworICAvLyBCZWltIFNwaWVsZXIgZWluZ2V0cmFnZW5lIFNjaHdpZXJpZ2tlaXQgZ2lsdCB2b3IgYW5nZWdlYmVuZXIuCisgIGlmICggKGQyPXNpbmZvW1NJX0RJRkZJQ1VMVFldKSApCisgICAgZGlmZj1kMjsKKworICAvLyBkaWZmIDwtMTAwIHNvbGwgbmljaHQgaGVtbWVuIHVuZCBtYWNodCBrZWluZW4gU2lubgorICBkaWZmPShkaWZmPCgtMTAwKSk/KC0xMDApOmRpZmY7CisgIAorICBtYXg9TUFYX0FCSUxJVFktKGRpZmYrMTAwKSooMzUtUXVlcnlQcm9wKFBfTEVWRUwpKTsKKworLy8gZGlmZnxsdmwgMTp8ICAgMzp8CTc6fCAxMDp8IDEzOnwgMTY6fCAxOTp8IDIyOnwgMjU6fCAyODp8IDMxOnwgMzQ6fAorLy8gLS0tLSstLS0tLS0rLS0tLS0rLS0tLS0rLS0tLSstLS0tKy0tLS0rLS0tLSstLS0tKy0tLS0rLS0tLSstLS0tKy0tLS0rCisvLyAgLTUwfCAgIDgzJXwgIDg0JXwgIDg2JXwgODclfCA4OSV8IDkwJXwgOTIlfCA5MyV8IDk1JXwgOTYlfCA5OCV8IDk5JXwKKy8vICAtMTB8ICAgNjklfCAgNzIlfCAgNzQlfCA3NyV8IDgwJXwgODIlfCA4NSV8IDg4JXwgOTElfCA5MyV8IDk2JXwgOTklfAorLy8gICAgMHwgICA2NiV8ICA2OSV8ICA3MiV8IDc1JXwgNzglfCA4MSV8IDg0JXwgODclfCA5MCV8IDkzJXwgOTYlfCA5OSV8CisvLyAgIDEwfCAgIDYyJXwgIDY1JXwgIDY5JXwgNzIlfCA3NSV8IDc5JXwgODIlfCA4NSV8IDg5JXwgOTIlfCA5NSV8IDk4JXwKKy8vICAgMjB8ICAgNTklfCAgNjIlfCAgNjYlfCA3MCV8IDczJXwgNzclfCA4MCV8IDg0JXwgODglfCA5MSV8IDk1JXwgOTglfAorLy8gICAzMHwgICA1NSV8ICA1OSV8ICA2MyV8IDY3JXwgNzElfCA3NSV8IDc5JXwgODMlfCA4NyV8IDkwJXwgOTQlfCA5OCV8CisvLyAgIDQwfCAgIDUyJXwgIDU2JXwgIDYwJXwgNjUlfCA2OSV8IDczJXwgNzclfCA4MSV8IDg2JXwgOTAlfCA5NCV8IDk4JXwKKy8vICAgNTB8ICAgNDklfCAgNTMlfCAgNTglfCA2MiV8IDY3JXwgNzElfCA3NiV8IDgwJXwgODUlfCA4OSV8IDk0JXwgOTglfAorLy8gIDEwMHwgICAzMiV8ICAzOCV8ICA0NCV8IDUwJXwgNTYlfCA2MiV8IDY4JXwgNzQlfCA4MCV8IDg2JXwgOTIlfCA5OCV8CisvLyAgMTUwfCAgIDE1JXwgIDIyJXwgIDMwJXwgMzclfCA0NSV8IDUyJXwgNjAlfCA2NyV8IDc1JXwgODIlfCA5MCV8IDk3JXwKKy8vICAyMDB8ICAgLTIlfCAgIDclfCAgMTYlfCAyNSV8IDM0JXwgNDMlfCA1MiV8IDYxJXwgNzAlfCA3OSV8IDg4JXwgOTclfAorLy8gIDI1MHwgIC0xOSV8ICAtOCV8CTIlfCAxMiV8IDIzJXwgMzMlfCA0NCV8IDU0JXwgNjUlfCA3NSV8IDg2JXwgOTYlfAorLy8gIDMwMHwgIC0zNiV8IC0yNCV8IC0xMiV8ICAwJXwgMTIlfCAyNCV8IDM2JXwgNDglfCA2MCV8IDcyJXwgODQlfCA5NiV8CisvLyAgNDAwfCAgLTcwJXwgLTU1JXwgLTQwJXwtMjUlfC0xMCV8ICA1JXwgMjAlfCAzNSV8IDUwJXwgNjUlfCA4MCV8IDk1JXwKKy8vICA1MDB8IC0xMDQlfCAtODYlfCAtNjglfC01MCV8LTMyJXwtMTQlfCAgNCV8IDIyJXwgNDAlfCA1OCV8IDc2JXwgOTQlfAorLy8gIDYwMHwgLTEzOCV8LTExNyV8IC05NiV8LTc1JXwtNTQlfC0zMyV8LTEyJXwgIDklfCAzMCV8IDUxJXwgNzIlfCA5MyV8CisKKyAgaWYgKCBhYmlsPm1heCApCisgICAgYWJpbD1tYXg7CisgIGlmICggYWJpbD5NQVhfQUJJTElUWQorICAgICkgYWJpbD1NQVhfQUJJTElUWTsKKyAgZWxzZSBpZiAoIGFiaWw8LU1BWF9BQklMSVRZICkKKyAgICBhYmlsPS1NQVhfQUJJTElUWTsKKworICBpZiAoIG9sZCAmJiAhYWJpbCApCisgICAgYWJpbD0xOworICAvLyBGYWVoaWdrZWl0ZW4gc29sbGVuIG5pY2h0IGR1cmNoIGRpZSBCZWdyZW56dW5nIHZlcnNjaHdpbmRlbgorCisgIHNpbmZvW1NJX1NLSUxMQUJJTElUWV09YWJpbDsKKworICByZXR1cm4gc2luZm87Cit9CisKK3B1YmxpYyB2YXJhcmdzIHZvaWQgTW9kaWZ5U2tpbGwoc3RyaW5nIHNuYW1lLCBtaXhlZCB2YWwsIGludCBkaWZmLCBzdHJpbmcgZ2lsZGUpCit7IAorICBtYXBwaW5nIHNraWxsczsKKyAgbWl4ZWQgc2tpbGw7CisKKyAgaWYgKCAhc3RyaW5ncChzbmFtZSkgfHwgIXNpemVvZihzbmFtZSkgKQorICAgIHJldHVybjsKKworICAvLyBpbnRlcm5hbF9xdWVyeV9uZXdza2lsbHMoKSBtYWNodCBrZWluZSBLb3BpZQorICBza2lsbHM9aW50ZXJuYWxfcXVlcnlfbmV3c2tpbGxzKGdpbGRlKTsKKworICAvLyBTa2lsbCBlcm1pdHRlbG4sIHdlbm4gbmljaHQgZXhpc3RpZXJ0LCB3aXJkIGVyIGFuZ2VsZWd0LgorICBpZiAoIXNraWxsPXNraWxsc1tzbmFtZV0pIHsKKyAgICAgIHNraWxsPShbXSk7IAorICB9CisgIAorICAvLyBadXIgU2ljaGVyaGVpdCBtYWwgZGFzIE1hcHBpbmcga29waWVyZW4sIHdlciB3ZWlzcywgd2FzIGRlcgkKKyAgLy8gQXVmcnVmZW5kZSBkaWVzZXIgRnVua3Rpb24gc2VsYmVyIHNwYWV0ZXIgZGFtaXQgbm9jaCBtYWNodC4KKyAgLy8gaXN0IG9rLCB3ZW5uIHZhbCBrZWluIE1hcHBpbmcgaXN0LCBkYW5uIG1hY2h0IGRlZXBfY29weSBuaXguCisgIHZhbD1kZWVwX2NvcHkodmFsKTsKKworICAvLyBTa2lsbCB1bmQgdmFsIHZlcmVpbmlnZW4KKyAgaWYgKCBtYXBwaW5ncCh2YWwpICkKKyAgICBza2lsbCs9dmFsOworICBlbHNlIGlmIChpbnRwKHZhbCkpCisgICAgc2tpbGxbU0lfU0tJTExBQklMSVRZXT12YWw7CisgIGVsc2UKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJCYWQgYXJnIDIgdG8gTW9kaWZ5U2tpbGwoKTogZXhwZWN0ZWQgJ2ludCcsICIKKyAgICAgICAgICAiZ290ICUuMTBPLlxuIix2YWwpKTsKKworICAvLyBMZXJuZW4gZW50c3ByZWNoZW5kIFNJX0RJRkZJQ1VMVFkgYmVncmVuemVuLgorICBpZihkaWZmICYmICFtZW1iZXIoc2tpbGwsU0lfRElGRklDVUxUWSkpCisgICAgc2tpbGxbU0lfRElGRklDVUxUWV09ZGlmZjsKKyAgc2tpbGw9TGltaXRBYmlsaXR5KHNraWxsLGRpZmYgfHwgc2tpbGxbU0lfRElGRklDVUxUWV0pOworICAKKyAgLy8gc2NobGllc3NsaWNoIGltIFNraWxsbWFwcGluZyB2ZXJtZXJrZW4uIEltIE5vcm1hbGZhbGwgaXN0IGRlciBTa2lsbCBqZXR6dAorICAvLyBzY2hvbiBnZWFlbmRlcnQsIG5pY2h0IGVyc3QgbmFjaCBkZW0gaW50ZXJuYWxfc2V0X25ld3NraWxscygpLgorICBza2lsbHNbc25hbWVdPXNraWxsOworCisgIC8vIGV4cGxpeml0ZXMgQWJzcGVpY2hlcm4gZmFzdCB1ZWJlcmZsdWVzc2lnLCB3ZWlsIHdpciBvYmVuIGVpbmUgUmVmZXJlbnoKKyAgLy8gYXVmIGRhcyBTa2lsbG1hcHBpbmcgZ2VrcmllZ3QgaGFiZW4uLi4KKyAgLy8gQWJlciBlcyBrb2VubnRlIHNlaW4sIGRhc3MgZGllcyBkZXIgZXJzdGUgU2tpbGwgZnVlciBkaWVzZSBHaWxkZSBpc3QsCisgIC8vIGRhbm4gaXN0IGVzIG5vZXRpZy4gWnVtIGFuZGVyZW4gd2lyZCBpbnRlcm5hbF9zZXRfbmV3c2tpbGxzKCkgbm9jaG1hbAorICAvLyBnZWxvZ2d0LgorICBpbnRlcm5hbF9zZXRfbmV3c2tpbGxzKHNraWxscyxnaWxkZSk7Cit9CisKK3B1YmxpYyB2YXJhcmdzIHZvaWQgTGVhcm5Ta2lsbChzdHJpbmcgc25hbWUsIGludCBhZGQsIGludCBkaWZmKQoreyBtYXBwaW5nIHNraWxsOworICBzdHJpbmcgc2tpbGwyLGdpbGRlOworICBpbnQgdmFsOworCisgIC8vIFNwaWVsZXIgc29sbGVuIG51ciBsZXJuZW4sIHdlbm4gc2llIGludGVyYWN0aXZlIHNpbmQuIERhcyBzb2xsCisgIC8vIG5hdHVlcmxpY2ggbnVyIGZ1ZXIgU3BpZWxlciBnZWx0ZW4uCisgIGlmIChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpICYmICFpbnRlcmFjdGl2ZSgpKQorCSAgcmV0dXJuOworCisgIGlmICggYWRkPk1BWF9TS0lMTEVBUk4gKQorICAgIGFkZD1NQVhfU0tJTExFQVJOOworICBlbHNlIGlmICggYWRkPDEgKQorICAgIGFkZD0xOworCisgIC8vIFNraWxsbWFwcGluZyBlcm1pdHRlbG4gKGhpZXIga29tbXQga2VpbmUgS29waWUgenVydWVjaykKKyAgc2tpbGw9SW50ZXJuYWxRdWVyeVNraWxsKHNuYW1lLCAwKTsKKyAgLy8gd2VubiBrZWluIFNraWxsLCBkYW5uIEFiYnJ1Y2gKKyAgaWYgKCFza2lsbCkgcmV0dXJuOworCisgIHZhbD1za2lsbFtTSV9TS0lMTEFCSUxJVFldOworICBnaWxkZT1za2lsbFtTSV9HVUlMRF07CisgCisgIHZhbCs9YWRkOworCisgIE1vZGlmeVNraWxsKHNuYW1lLHZhbCxkaWZmLGdpbGRlKTsKKyAgaWYgKCBza2lsbDI9c2tpbGxbU0lfSU5IRVJJVF0gKQorICAgIExlYXJuU2tpbGwoc2tpbGwyLGFkZC8zLGRpZmYpOworfQorCitwdWJsaWMgdmFyYXJncyBpbnQgVXNlU3BlbGwoc3RyaW5nIHN0ciwgc3RyaW5nIHNwZWxsKQoreyBzdHJpbmcgZ2lsZGUsc2Jvb2s7CisgIG1hcHBpbmcgc2luZm87CisgIGNsb3N1cmUgY2w7CisgIAorICBpZiAoICFzcGVsbCAmJiAhKHNwZWxsPXF1ZXJ5X3ZlcmIoKSkgKQorICAgIHJldHVybiAwOworCisgIHNwZWxsPWxvd2VyX2Nhc2Uoc3BlbGwpOworCisgIC8vIFF1ZXJ5U2tpbGwoKSBsaWVmZXJ0IGVpbmUgS29waWUgZGVzIFNraWxsbWFwcGluZ3MuCisgIC8vIHdlbm4gc2tpbGwgdW5iZWthbm50IG9kZXIgQWJpbGl0eSA8PSAwLCBpc3QgZGVyIFNwZWxsIG5pY2h0IG51dHpiYXIuCisgIGlmICggIShzaW5mbz1RdWVyeVNraWxsKHNwZWxsLDApKQorICAgICAgICB8fCBzaW5mb1tTSV9TS0lMTEFCSUxJVFldIDw9IDAgKQorICAgIHJldHVybiAwOworCisgIHNpbmZvW1NJX1NLSUxMQVJHXT1zdHI7IC8vIEFyZ3VtZW50IGVpbnRyYWdlbgorCisgIGlmICggIWNsb3N1cmVwKGNsPXNpbmZvW1NJX0NMT1NVUkVdKSApCisgIHsKKyAgICAvLyBXZW5uIGVpbiBTcGVsbGJvb2sgYW5nZWdlYmVuIGlzdCB3aXJkIGRlciBTcGVsbCBkaXJla3QgYXVzZ2VmdWVocnQKKyAgICBpZiAoIHN0cmluZ3Aoc2Jvb2s9c2luZm9bU0lfU1BFTExCT09LXSkgKQorICAgICAgY2w9c3ltYm9sX2Z1bmN0aW9uKCJVc2VTcGVsbCIsU1BFTExCT09LX0RJUitzYm9vayk7CisKKyAgICAvLyBXZW5uIGRlciBTcGllbGVyIGluIGVpbmVyIEdpbGRlIGlzdCwgc28gd2Vpc3MgZGllc2UsIGluIHdlbGNoZW0KKyAgICAvLyBTcGVsbGJvb2sgZGVyIFNwZWxsIHp1IGZpbmRlbiBpc3QuLi4KKyAgICBlbHNlIGlmICggKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgJiYgCisgICAgICAoIGZpbmRfb2JqZWN0KEdVSUxEX0RJUitnaWxkZSkgfHwgZmlsZV9zaXplKEdVSUxEX0RJUitnaWxkZSsiLmMiKT4tMSkpCisgICAgICBjbD1zeW1ib2xfZnVuY3Rpb24oIlVzZVNwZWxsIixHVUlMRF9ESVIrZ2lsZGUpOworICAgIGVsc2UKKyAgICAgIGNsPWZ1bmN0aW9uIGludCAoKSB7cmV0dXJuIDA7fTsKKworICAgIHNpbmZvW1NJX0NMT1NVUkVdPWNsOworICAgIHZhbGlkX3NldHNraWxsc19vdmVycmlkZT0xOworICAgIE1vZGlmeVNraWxsKHNwZWxsLChbU0lfQ0xPU1VSRTpjbF0pLDAsc2luZm9bU0lfR1VJTERdKTsKKyAgICB2YWxpZF9zZXRza2lsbHNfb3ZlcnJpZGU9MDsKKyAgfQorICByZXR1cm4gZnVuY2FsbChjbCx0aGlzX29iamVjdCgpLHNwZWxsLHNpbmZvKTsKK30KKworcHVibGljIHZhcmFyZ3MgbWl4ZWQgVXNlU2tpbGwoc3RyaW5nIHNraWxsLCBtYXBwaW5nIGFyZ3MpCit7IG1hcHBpbmcgc2luZm87CisgIHN0cmluZyBnaWxkZSwgZnVuYyxza2lsbDI7CisgIG1peGVkIHJlczsKKyAgY2xvc3VyZSBjbDsKKyAgCisgIGlmICggIXNraWxsIHx8CisgICAgICAgUXVlcnlQcm9wKFBfR0hPU1QpKQorICAgIHJldHVybiAwOworCisgIHNraWxsPWNhcGl0YWxpemUoc2tpbGwpOworICAvLyBRdWVyeVNraWxsKCkgbGllZmVydCBlaW5lIEtvcGllIGRlcyBTa2lsbG1hcHBpbmdzCisgIGlmICggIShzaW5mbz1RdWVyeVNraWxsKHNraWxsLDApKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKGFyZ3MpCisgICAgc2luZm8rPWFyZ3M7CisKKyAgaWYgKCAhY2xvc3VyZXAoY2w9c2luZm9bU0lfQ0xPU1VSRV0pICkKKyAgeworICAgIGlmICggIShmdW5jPXNpbmZvW1NJX1NLSUxMRlVOQ10pICAgIC8vIEtlaW5lIEZ1bmt0aW9uIGFuZ2VnZWJlbj8KKyAgICAgICAgfHwgIShnaWxkZT1RdWVyeVByb3AoUF9HVUlMRCkpKSAvLyBLZWluZSBHaWxkZSBhbmdlZ2ViZW4/CisgICAgeworICAgICAgLy8gRGFubiBTdGFuZGFyZC1GdW5rdGlvbiBuZWhtZW4sIHdlbm4gZXMgZGllIG5pY2h0IGdpYnQsIGRlbgorICAgICAgLy8gQWJpbGl0eS1XZXJ0IHp1cnVlY2tsaWVmZXJuLgorICAgICAgaWYgKCFjbG9zdXJlcChjbCA9IHN5bWJvbF9mdW5jdGlvbigiU3RkU2tpbGxfIitza2lsbCx0aGlzX29iamVjdCgpKSkpCisgICAgICAgIGNsPWZ1bmN0aW9uIGludCAob2JqZWN0IG9iLCBzdHJpbmcgc25hbWUpCisgICAgICAgICAgICAge3JldHVybiBRdWVyeVNraWxsQWJpbGl0eShzbmFtZSk7fSA7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICAvLyBTb25zdCBkaWVzZSBGdW5rdGlvbiBpbSBHaWxkZW5vYmpla3QgYXVmcnVmZW4KKyAgICAgIGNsPXN5bWJvbF9mdW5jdGlvbihmdW5jLEdVSUxEX0RJUitnaWxkZSk7CisgICAgfQorCisgICAgc2luZm9bU0lfQ0xPU1VSRV09Y2w7CisgICAgdmFsaWRfc2V0c2tpbGxzX292ZXJyaWRlPTE7CisgICAgTW9kaWZ5U2tpbGwoc2tpbGwsKFtTSV9DTE9TVVJFOmNsXSksMCxzaW5mb1tTSV9HVUlMRF0pOworICAgIHZhbGlkX3NldHNraWxsc19vdmVycmlkZT0wOworICB9CisKKyAgcmVzPWZ1bmNhbGwoY2wsdGhpc19vYmplY3QoKSxza2lsbCxzaW5mbyk7CisgIGlmICggKHNraWxsMj1zaW5mb1tTSV9JTkhFUklUXSkgJiYgbWFwcGluZ3AocmVzKSApCisgICAgcmVzPVVzZVNraWxsKHNraWxsMixyZXMpOyAvLyBGdWVyIFNraWxscywgZGllIHZvbiBhbmRlcmVuIGFiaGFlbmdlbgorCisgIHJldHVybiByZXM7Cit9CisKKy8vICoqKioqKioqKioqKioqIFNwZWxsZmF0aWd1ZXMgKioqKioqKioqKioqKioqCisKKy8qICBQcnVlZnQgZGllIFNwZWxsZmF0aWd1ZSBmdWVyIFNwcnVjaChncnVwcGUpIDxrZXk+LgorICogIDxrZXk+IGRhcmYgMCBzZWluIChnbG9iYWxlIFNwcnVjaHNwZXJyZSkuCisgKiAgTGllZmVydCAwLCB3ZW5uIGtlaW5lIFNwZXJyZSB1bmQgZGllIEFibGF1ZnplaXQsIHdlbm4gZWluZSBTcGVycmUgbm9jaAorICogIGd1ZWx0aWcuIGlzdC4KKyAqLworcHVibGljIHZhcmFyZ3MgaW50IENoZWNrU3BlbGxGYXRpZ3VlKHN0cmluZyBrZXkpIHsKKyAgLy8ga2V5PT0wIGlzIHRoZSAoZGVmYXVsdCkgZ2xvYmFsIHNwZWxsZmF0aWd1ZS4KKyAgaWYgKHNwZWxsX2ZhdGlndWVzW2tleV0gPiB0aW1lKCkpCisgICAgcmV0dXJuIHNwZWxsX2ZhdGlndWVzW2tleV07IC8vIEFibGF1ZnplaXQgenVydWVja2dlYmVuLgorCisgIHJldHVybiAwOyAvLyBvaywga2VpbmUgU3BlcnJlLgorfQorCisvKiogU3BlaWNoZXJ0IGVpbmUgU3BlbGxmYXRpZ3VlIHZvbiA8ZHVyYXRpb24+IFNla3VuZGVuIGZ1ZXIgPGtleT4uCisgKiA8a2V5PiBkYXJmIDAgc2VpbiB1bmQgYmV6ZWljaG5ldCBkYXMgZ2xvYmFsZSBTcGVsbGZhdGlndWUuCisgKiBSdWVja2dhYmV3ZXJ0OiBBYmxhdWZ6ZWl0IGRlciBnZXNldHp0ZW4gU3BlcnJlCisgICAgICAgICAgICAgICAgICAtMSwgd2VubiBub2NoIGVpbmUgbmljaHQtYWJnZWxhdWZlbmUgU3BlcnJlIGF1ZiBkZW0gPGtleT4gbGFnLgorICAgICAgICAgICAgICAgICAgMCwgd2VubiBkdXJhdGlvbiAwIGlzdC4KKyAqLworcHVibGljIHZhcmFyZ3MgaW50IFNldFNwZWxsRmF0aWd1ZShpbnQgZHVyYXRpb24sIHN0cmluZyBrZXkpIHsKKyAgLy8gYWt0dWVsbGUgU3BlcnJlIGFiZ2VsYXVmZW4/CisgIGlmIChDaGVja1NwZWxsRmF0aWd1ZShrZXkpKQorICAgIHJldHVybiAtMTsgLy8gYWx0ZSBTcGVycmUgbm9jaCBha3Rpdi4KKworICBkdXJhdGlvbiArPSB0aW1lKCk7CisgIC8vIDAgaXMgT0sgZm9yIDxrZXk+LCBpdCBpcyB0aGUga2V5IGZvciBnbG9iYWwgc3BlbGwgZmF0aWd1ZXMKKyAgc3BlbGxfZmF0aWd1ZXNba2V5XSA9IGR1cmF0aW9uOworICByZXR1cm4gZHVyYXRpb247Cit9CisKKy8qICBQcnVlZnQgZGllIFNwZWxsZmF0aWd1ZSBmdWVyIFNwcnVjaChncnVwcGUpIDxrZXk+LgorICogIDxrZXk+IGRhcmYgZnVlciBkaWVzZSBGdW5rdGlvbiAwIChnbG9iYWxlIFNwcnVjaHNwZXJyZSkgc2VpbiwgYWJlciBtYW4KKyAqICBkYXJmIGRhcyBBcmd1bWVudCBuaWNodCB3ZWdsYXNzZW4sIGRhbWl0IG5pY2h0IGVpbiB2ZXJwZWlsdGVyIE1hZ2llcgorICogIHZlcnNlaGVudGxpY2ggZGllIGdsb2JhbGUgU3BydWNoc3BlcnJlIG51bGx0LgorICovCitwdWJsaWMgdm9pZCBEZWxldGVTcGVsbEZhdGlndWUoc3RyaW5nIGtleSkgeworICAvLyBrZXk9PTAgaXMgdGhlIChkZWZhdWx0KSBnbG9iYWwgc3BlbGxmYXRpZ3VlLgorICBtX2RlbGV0ZShzcGVsbF9mYXRpZ3Vlcywga2V5KTsKK30KKworLyoqIExvZXNjaHQgYWJnZWxhdWZlbmUgS2V5cyBhdXMgZGVtIHNwZWxsX2ZhdGlndWUgbWFwcGluZy4KKyAqLworcHJpdmF0ZSB2b2lkIGV4cGlyZV9zcGVsbF9mYXRpZ3VlcygpIHsKKyAgZm9yZWFjaChzdHJpbmcga2V5LCBpbnQgZW5kdGltZTogc3BlbGxfZmF0aWd1ZXMpIHsKKyAgICBpZiAoZW5kdGltZSA8PSB0aW1lKCkpCisgICAgICBtX2RlbGV0ZShzcGVsbF9mYXRpZ3Vlcywga2V5KTsKKyAgfQorfQorCisvKiogU2V0bWV0aG9kZSBmdWVyIFBfTkVYVF9TUEVMTF9USU1FLgorICAqLworc3RhdGljIGludCBfc2V0X25leHRfc3BlbGwoaW50IGZhdGlndWUpIHsKKyAgcmV0dXJuIFNldFNwZWxsRmF0aWd1ZShmYXRpZ3VlIC0gdGltZSgpKTsKK30KKy8qKiBRdWVyeW1ldGhvZGUgZnVlciBQX05FWFRfU1BFTExfVElNRS4KKyAgKi8KK3N0YXRpYyBpbnQgX3F1ZXJ5X25leHRfc3BlbGwoKSB7CisgIHJldHVybiBDaGVja1NwZWxsRmF0aWd1ZSgpOworfQorCmRpZmYgLS1naXQgYS9zdGQvbGl2aW5nL3N0ZF9za2lsbHMuYyBiL3N0ZC9saXZpbmcvc3RkX3NraWxscy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQxMzJlZmMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbGl2aW5nL3N0ZF9za2lsbHMuYwpAQCAtMCwwICsxLDEwNCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9zdGRfc2tpbGxzLmMgLS0gU3RhbmRhcmRmYWVoaWdrZWl0ZW4KKy8vCisvLyAkSWQ6IHN0ZF9za2lsbHMuYyA2NjczIDIwMDgtMDEtMDUgMjA6NTc6NDNaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGxpdmluZy9za2lsbHMuaD4KKyNpbmNsdWRlIDxsaXZpbmcvc2tpbGxfYXR0cmlidXRlcy5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxhdHRyaWJ1dGVzLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKworI2RlZmluZSBTSUcoeCkgKHg/KHg+MD8xOi0xKTowKQorCitwcm90ZWN0ZWQgaW50IFN0ZFNraWxsX05pZ2h0dmlzaW9uKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtaXhlZCBzaW5mbykgeworICBpbnQgYWJpbCxsaWdodCxsbHQsZHQscmVzOworCisgIGlmICghc2luZm8gfHwgIWVudmlyb25tZW50KCkpIHJldHVybiAwOworICBpZiAoaW50cChzaW5mbykpIHNpbmZvPShbU0lfU0tJTExBQklMSVRZOnNpbmZvXSk7CisgIGlmICghbWFwcGluZ3Aoc2luZm8pKSByZXR1cm4gMDsKKyAgaWYgKChsaWdodD1RdWVyeVByb3AoUF9QTEFZRVJfTElHSFQpKT4wKSB7CisgICAgTW9kaWZ5U2tpbGwoc25hbWUsKFtTSV9MQVNUTElHSFQ6dGltZSgpXSkpOworICAgIHJldHVybiBsaWdodDsKKyAgfQorICBhYmlsPXNpbmZvW1NJX1NLSUxMQUJJTElUWV07CisgIGlmICghKGxsdD1zaW5mb1tTSV9MQVNUTElHSFRdKSkgeworICAgIE1vZGlmeVNraWxsKHNuYW1lLChbU0lfTEFTVExJR0hUOnRpbWUoKV0pKTsKKyAgICBkdD0wOworICB9IGVsc2UgeworICAgIGR0PXRpbWUoKS1sbHQ7CisgICAgaWYgKGR0PDApIGR0PTA7CisgICAgaWYgKGR0Pjg2NDAwKSBkdD04NjQwMDsKKyAgfQorCisgIHJlcz0oYWJpbCpkdCkvKDIwKk1BWF9BQklMSVRZKStsaWdodDsKKyAgaWYgKHJlczw9MCkgeworICAgIHJlcy0tOyAvLyBXZXJ0IG11c3MgIT0wIHNlaW4KKyAgICBpZiAocmVzPC1NQVhfQUJJTElUWSkgcmVzPS1NQVhfQUJJTElUWTsKKyAgfSBlbHNlIHsKKyAgICBpZiAocmVzPk1BWF9BQklMSVRZKSByZXM9TUFYX0FCSUxJVFk7CisgIH0KKyAgcmV0dXJuIHJlczsKK30KKworcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfQmloYW5kKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKSB7CisgIGludCBhYmlsLHZhbDsKKworICAvLyBwcmludGYoIkJpaGFuZDogJU9cbiIsc2luZm8pOworICBpZiAoIXNpbmZvKSByZXR1cm4gMDsKKyAgYWJpbD1zaW5mb1tTSV9TS0lMTEFCSUxJVFldOworICB2YWw9KGFiaWwqKFF1ZXJ5QXR0cmlidXRlKEFfU1RSKSszMykpL01BWF9BQklMSVRZOworICB2YWw9KHZhbCpRdWVyeVNraWxsQXR0cmlidXRlKFNBX0RBTUFHRSkpLzEwMDsKKyAgc2luZm9bU0lfU0tJTExEQU1BR0VdKz12YWw7CisgIC8vICsgbWF4LiA1MworICByZXR1cm4gc2luZm87Cit9CisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X3N3b3JkKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKSB7CisgIGludCBhYmlsLGFzaWcsdmFsOworCisgIGFiaWw9c2luZm9bU0lfU0tJTExBQklMSVRZXTthc2lnPVNJRyhhYmlsKTsKKyAgdmFsPShhYmlsKihRdWVyeUF0dHJpYnV0ZShBX1NUUikgKworICAgICAgICAgICAgIFF1ZXJ5QXR0cmlidXRlKEFfREVYKSphc2lnICsKKyAgICAgICAgICAgICAzMykpL01BWF9BQklMSVRZOworICB2YWw9KHZhbCpRdWVyeVNraWxsQXR0cmlidXRlKFNBX0RBTUFHRSkpLzEwMDsKKyAgc2luZm9bU0lfU0tJTExEQU1BR0VdKz12YWw7CisgIC8vICsgbWF4LiA3MworICByZXR1cm4gc2luZm87Cit9CisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X2hhbmRzKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKSB7CisgIGludCBhYmlsLGFzaWcsdmFsOworCisgIGlmICghc2luZm8pIHJldHVybiAwOworICBhYmlsPXNpbmZvW1NJX1NLSUxMQUJJTElUWV07YXNpZz1TSUcoYWJpbCk7CisgIHZhbD0oYWJpbCooUXVlcnlBdHRyaWJ1dGUoQV9TVFIpICsKKyAgICAgICAgICAgICBRdWVyeUF0dHJpYnV0ZShBX0RFWCkqMyphc2lnICsKKyAgICAgICAgICAgICAxMDApKS9NQVhfQUJJTElUWTsKKyAgdmFsPSh2YWwqUXVlcnlTa2lsbEF0dHJpYnV0ZShTQV9EQU1BR0UpKS8xMDA7CisgIHNpbmZvW1NJX1NLSUxMREFNQUdFXSs9dmFsOworICAvLyArIG1heC4gMTgwCisgIHJldHVybiBzaW5mbzsKK30KKworcHJvdGVjdGVkIGludCBTdGRTa2lsbF9Cb296ZShvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykgeworICBpbnQgYWJpbCx2YWw7CisKKyAgdmFsPTA7CisgIGlmICghc2luZm8gfHwgKHZhbD1zaW5mb1tTSV9TS0lMTEFSR10pPD0wKQorICAgIHJldHVybiB2YWw7CisgIGFiaWw9c2luZm9bU0lfU0tJTExBQklMSVRZXTsKKyAgdmFsLT0odmFsKmFiaWwpLyhNQVhfQUJJTElUWSsyNTAwKTsgLy8gQmlzIHp1IDgwJSBBYnp1ZyBiZWkgQWxrb2hvbGlrZXJuLgorICBpZiAodmFsPD0wKSB2YWw9MTsKKyAgcmV0dXJuIHZhbDsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL2xpdmluZy90ZWFtLmMgYi9zdGQvbGl2aW5nL3RlYW0uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYjMxZGI5Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL2xpdmluZy90ZWFtLmMKQEAgLTAsMCArMSw2NTAgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBsaXZpbmcvdGVhbS5jCisvLworLy8gJElkOiB0ZWFtLmMgOTEzOCAyMDE1LTAyLTAzIDIxOjQ2OjU2WiBaZXNzdHJhICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGl2aW5nL2NvbWJhdC5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPGxpdmluZy90ZWFtLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8aG9vay5oPgorCisjZGVmaW5lIE1FIHRoaXNfb2JqZWN0KCkKKyNkZWZpbmUgVFAgdGhpc19wbGF5ZXIoKQorI2RlZmluZSBQTyBwcmV2aW91c19vYmplY3QoKQorI2RlZmluZSBFTlYgZW52aXJvbm1lbnQoKQorCitwcml2YXRlIG5vc2F2ZSBzdHJpbmcgdGVhbV9hdHRhY2tfY21kOworcHJpdmF0ZSBub3NhdmUgbWFwcGluZyB0ZWFtX2ZvbGxvd190b2RvOworcHJpdmF0ZSBub3NhdmUgaW50IHRlYW1fYXV0b2ZvbGxvdzsKK3ByaXZhdGUgbm9zYXZlIG9iamVjdCB0ZWFtbW92ZTsKKwordm9pZCBjcmVhdGUoKSB7CisgIFNldChQX1RFQU1fQVRUQUNLX0NNRCwtMSxGX1NFVF9NRVRIT0QpOworICBTZXQoUF9URUFNX0FUVEFDS19DTUQsUFJPVEVDVEVELEZfTU9ERV9BUyk7CisgIFNldChQX1RFQU1fQVVUT0ZPTExPVywtMSxGX1NFVF9NRVRIT0QpOworICBTZXQoUF9URUFNX0FVVE9GT0xMT1csUFJPVEVDVEVELEZfTU9ERV9BUyk7CisgIHRlYW1tb3ZlPTA7CisgIG9mZmVySG9vayhIX0hPT0tfVEVBTVJPV0NIQU5HRSwgMSk7Cit9CisKK3ZvaWQgYWRkX3RlYW1fY29tbWFuZHMoKSB7CisgIGFkZF9hY3Rpb24oInRlYW1jbWQiLCJncnVwcGUiKTsKKyAgYWRkX2FjdGlvbigidGVhbWNtZCIsImciKTsKKyAgYWRkX2FjdGlvbigidGVhbWNtZCIsInRlYW0iKTsKK30KKworc3RyaW5nIF9xdWVyeV90ZWFtX2F0dGFja19jbWQoKSB7CisgIHJldHVybiBTZXQoUF9URUFNX0FUVEFDS19DTUQsdGVhbV9hdHRhY2tfY21kKTsKK30KKworaW50IF9xdWVyeV90ZWFtX2F1dG9mb2xsb3coKSB7CisgIHJldHVybiBTZXQoUF9URUFNX0FVVE9GT0xMT1csdGVhbV9hdXRvZm9sbG93KTsKK30KKworcHJpdmF0ZSBpbnQgdGVhbV9oZWxwKCkgeworICAvLyBTeW50YXgtS29tcGF0aWJsaXRhZXQgKEF2YWxvbikgaXN0IGdhbnogbmV0dCA6LSkKKyAgd3JpdGUoIlwKKyhCZWZlaGxlIGRlcyBUZWFtbGVpdGVycyBzaW5kIG1pdCAqIGdla2VubnplaWNobmV0XG5cCitcblwKKyogdGVhbSBhbmdyaWZmXG5cCisgIHRlYW0gYW5ncmlmZnNiZWZlaGwgPGJlZmVobD5cblwKKyogdGVhbSBhdWZuYWhtZSA8bmFtZT5cblwKKyAgdGVhbSBhdXRvZltvbGdlXSA8ZWluL2F1cz5cblwKKyogdGVhbSBhdXRvaVtuZm9dIDxlaW4vYXVzPiBbK1tscF1dIFsrW2twXV0gW3NvZm9ydF1cblwKKyogdGVhbSBlbnRsYXNzZSA8bmFtZT5cblwKKyAgdGVhbSBmYXJiZW4gbHBfcm90IGxwX2dlbGIga3Bfcm90IGtwX2dlbGJcblwKKyAgdGVhbSBmbHVjaHRbcmVpaGVdIDxyZWloZT5cblwKKyAgdGVhbSBmb2xnZSA8bmFtZT5cblwKKyogdGVhbSBmb3JtYXRpb24gPG1pblstbWF4XT4gWzxtaW5bLW1heF0+IC4uLl1cblwKKyAgdGVhbSBoaWxmZXw/XG5cCisgIHRlYW0gW2luZm9dIFtzb3J0aWVydHxhbHBoYWJldGlzY2hdXG5cCisgIHRlYW0gW2thbXBmXXJlaWhlIDxyZWloZT5cblwKKyogdGVhbSBsZWl0ZXJbaW5dIDxuYW1lPlxuXAorICB0ZWFtIGxpc3RlXG5cCisqIHRlYW0gbmFtZSA8Z3J1cHBlbm5hbWU+XG5cCisgIHRlYW0gb3J0ZSBbYWxsZV1cblwKKyAgdGVhbSBydWZbZV1cblwKKyAgdGVhbSB1ZWJlcnNpY2h0XG5cCisgIHRlYW0gdmVybGFzc2VcbiIpOworICByZXR1cm4gMTsKK30KKworb2JqZWN0IElzVGVhbUxlYWRlcigpIHsKKyAgb2JqZWN0IHRlYW07CisKKyAgaWYgKCFvYmplY3RwKHRlYW09UXVlcnkoUF9URUFNKSkKKyAgICAgIHx8IHRlYW0hPVF1ZXJ5KFBfVEVBTV9MRUFERVIpCisgICAgICB8fCB0ZWFtLT5MZWFkZXIoKSE9TUUpCisgICAgcmV0dXJuIDA7CisgIHJldHVybiB0ZWFtOworfQorCitvYmplY3QgKlRlYW1NZW1iZXJzKCkgeworICBvYmplY3QgdGVhbTsKKworICBpZiAoIW9iamVjdHAodGVhbT1RdWVyeShQX1RFQU0pKSkKKyAgICByZXR1cm4gKHtNRX0pOworICByZXR1cm4gdGVhbS0+TWVtYmVycygpOworfQorCitzdHJpbmcgVGVhbVByZWZpeCgpIHsKKyAgb2JqZWN0IHRlYW07CisKKyAgaWYgKCFvYmplY3RwKHRlYW09UXVlcnkoUF9URUFNKSkpCisgICAgcmV0dXJuICIiOworICByZXR1cm4gIlsiK3RlYW0tPk5hbWUoKSsiXSAiOworfQorCisKK3ByaXZhdGUgaW50IHRlYW1fYXVmbmFobWV3dW5zY2goc3RyaW5nIGFyZykgeworICBvYmplY3QgcGw7CisKKyAgaWYgKCghb2JqZWN0cChwbD1maW5kX3BsYXllcihhcmcpKSAmJiAhb2JqZWN0cChwbD1wcmVzZW50KGFyZyxFTlYpKSkKKyAgICAgIHx8IHBsLT5RdWVyeVByb3AoUF9JTlZJUykgfHwgZW52aXJvbm1lbnQocGwpIT1FTlYpCisgICAgcmV0dXJuIG5vdGlmeV9mYWlsKGNhcGl0YWxpemUoYXJnKSsiIG5pY2h0IGdlZnVuZGVuLlxuIiksMDsKKyAgaWYgKCFsaXZpbmcocGwpKQorICAgIHJldHVybiBub3RpZnlfZmFpbChwbC0+TmFtZShXRVIpKyIgaXN0IGV0d2FzIHp1IGluYWt0aXYuXG4iKSwwOworICBpZiAocGw9PU1FKQorICAgIHJldHVybiBub3RpZnlfZmFpbCgiRHUgYmlzdCBlaW5lIFBlcnNvbiB6dSB3ZW5pZyBmdWVyIGVpbiBUZWFtLlxuIiksMDsKKyAgU2V0UHJvcChQX1RFQU1fTkVXTUVNQkVSLHBsKTsKKyAgaWYgKHBsLT5Jc1RlYW1MZWFkZXIoKSkgeworICAgIHdyaXRlKCJEdSBiaXR0ZXN0ICIrcGwtPm5hbWUoV0VOKSsiIHVtIEF1Zm5haG1lIGlucyBUZWFtLlxuIik7CisgICAgdGVsbF9vYmplY3QocGwsVFAtPk5hbWUoV0VSKSsiIGJpdHRldCBEaWNoIHVtIEF1Zm5haG1lIGlucyBUZWFtLlxuIik7CisgIH0gZWxzZSB7CisgICAgd3JpdGUoIkR1IGJpdHRlc3QgIitwbC0+bmFtZShXRU4pKyIgdW0gR3J1ZW5kdW5nIGVpbmVzIFRlYW1zLlxuIik7CisgICAgdGVsbF9vYmplY3QocGwsVFAtPk5hbWUoV0VSKSsiIGJpdHRldCBEaWNoIHVtIEdydWVuZHVuZyBlaW5lcyBUZWFtcy5cbiIpOworICB9CisgIHJldHVybiAxOworfQorCitwcml2YXRlIGludCB0ZWFtX2F1Zm5haG1lKHN0cmluZyBhcmcpIHsKKyAgb2JqZWN0IHBsLHRlYW07CisgIGludCByZXM7CisKKyAgaWYgKCghb2JqZWN0cChwbD1maW5kX3BsYXllcihhcmcpKSAmJiAhb2JqZWN0cChwbD1wcmVzZW50KGFyZyxFTlYpKSkKKyAgICAgIHx8IHBsLT5RdWVyeVByb3AoUF9JTlZJUykgfHwgZW52aXJvbm1lbnQocGwpIT1FTlYpCisgICAgcmV0dXJuIG5vdGlmeV9mYWlsKGNhcGl0YWxpemUoYXJnKSsiIG5pY2h0IGdlZnVuZGVuLlxuIiksMDsKKyAgaWYgKHBsLT5RdWVyeVByb3AoUF9URUFNX05FV01FTUJFUikhPU1FKQorICAgIHJldHVybiBub3RpZnlfZmFpbChwbC0+TmFtZShXRVIpKyIgaGF0IERpY2ggbmljaHQgdW0gQXVmbmFobWUgZ2ViZXRlbi5cbiIpLAorICAgICAgMDsKKyAgaWYgKHBsPT1NRSkKKyAgICByZXR1cm4gbm90aWZ5X2ZhaWwoIkR1IGJpc3QgZWluZSBQZXJzb24genUgd2VuaWcgZnVlciBlaW4gVGVhbS5cbiIpLDA7CisgIGlmICghb2JqZWN0cCh0ZWFtPVF1ZXJ5UHJvcChQX1RFQU0pKSkKKyAgICB0ZWFtPWNsb25lX29iamVjdChURUFNX09CSkVDVCk7CisgIHJlcz10ZWFtLT5BZGRNZW1iZXIocGwpOworICBpZiAoIXNpemVvZih0ZWFtLT5NZW1iZXJzKCkpKQorICAgIHRlYW0tPnJlbW92ZSgpOworICByZXR1cm4gcmVzOworfQorCitvYmplY3QgSXNUZWFtTW92ZSgpIHsKKyAgaWYgKCFvYmplY3RwKHRlYW1tb3ZlKSB8fCAodGVhbW1vdmUhPVF1ZXJ5KFBfVEVBTSkpKQorICAgIHRlYW1tb3ZlPTA7CisgIHJldHVybiB0ZWFtbW92ZTsKK30KKworc3RhdGljIHZvaWQgRG9UZWFtQXR0YWNrKG9iamVjdCBlbnYsIG9iamVjdCBjYWxsYmFja3RvKSB7CisgIGlmIChlbnY9PUVOViAmJiBzdHJpbmdwKHRlYW1fYXR0YWNrX2NtZCkgJiYgIUlTX0xFQVJORVIoTUUpCisgICAgICAmJiAoaW50ZXJhY3RpdmUoTUUpIHx8ICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSkKKyAgICAgICYmIG9iamVjdHAoY2FsbGJhY2t0bykgJiYgY2FsbGJhY2t0bz09UXVlcnkoUF9URUFNKSkgeworICAgIHRlYW1tb3ZlPWNhbGxiYWNrdG87CisgICAgY29tbWFuZCh0ZWFtX2F0dGFja19jbWQpOworICB9CisgIGlmIChvYmplY3RwKGNhbGxiYWNrdG8pKQorICAgIGNhbGxiYWNrdG8tPlRlYW1BdHRhY2tFeGVjdXRlZF9DYWxsYmFjayh0ZWFtbW92ZT8xOjApOworICB0ZWFtbW92ZT0wOworfQorCitpbnQgQ2FsbFRlYW1BdHRhY2sob2JqZWN0IGVudikgeworICBpZiAoc3RyaW5ncCh0ZWFtX2F0dGFja19jbWQpCisgICAgICAmJiBmaW5kX2NhbGxfb3V0KCJEb1RlYW1BdHRhY2siKTwwCisgICAgICAmJiBQTworICAgICAgJiYgUE89PVF1ZXJ5KFBfVEVBTSkpCisgICAgcmV0dXJuIGNhbGxfb3V0KCJEb1RlYW1BdHRhY2siLDAsZW52LFBPKSwxOworICByZXR1cm4gMDsKK30KKworc3RhdGljIGludCBEb1RlYW1Gb2xsb3coKSB7CisgIHN0cmluZyBjbWQ7CisKKyAgaWYgKCF0ZWFtX2F1dG9mb2xsb3cKKyAgICAgIHx8ICghaW50ZXJhY3RpdmUoTUUpICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpKQorICAgICAgfHwgSVNfTEVBUk5FUihNRSkKKyAgICAgIHx8ICFtYXBwaW5ncCh0ZWFtX2ZvbGxvd190b2RvKSkKKyAgICByZXR1cm4gMDsKKyAgaWYgKCFzdHJpbmdwKGNtZD10ZWFtX2ZvbGxvd190b2RvW0VOVl0pKQorICAgIHJldHVybiB0ZWFtX2ZvbGxvd190b2RvPTA7CisKKyAgZG8geworICAgIG1fZGVsZXRlKHRlYW1fZm9sbG93X3RvZG8sRU5WKTsKKyAgICB0ZWxsX29iamVjdChNRSxzcHJpbnRmKCJEdSBmb2xnc3QgRGVpbmVtIFRlYW0gbWl0IFwiJXNcIi5cbiIsY21kKSk7CisgICAgY29tbWFuZChjbWQpOworICB9IHdoaWxlIChnZXRfZXZhbF9jb3N0KCk+OTAwMDAwICYmIHJhbmRvbSgxMDAwKT4yMCAmJiBvYmplY3RwKE1FKQorICAgICAgICAgICAmJiBzdHJpbmdwKGNtZD10ZWFtX2ZvbGxvd190b2RvW0VOVl0pKTsKKworICAvLyBJc3QgU3BpZWxlciBpbiBVbWdlYnVuZyBnZWxhbmRldCwgZnVlciBkaWUgbm9jaCBlaW4KKyAgLy8gQmVmZWhsIGF1c3p1ZnVlaHJlbiBpc3Q/CisgIGlmICghb2JqZWN0cChNRSkgfHwgIXN0cmluZ3AodGVhbV9mb2xsb3dfdG9kb1tFTlZdKSkKKyAgICByZXR1cm4gdGVhbV9mb2xsb3dfdG9kbz0wOworICB3aGlsZSAgKHJlbW92ZV9jYWxsX291dCgiRG9UZWFtRm9sbG93IikhPS0xKSA7CisgIGNhbGxfb3V0KCJEb1RlYW1Gb2xsb3ciLDApOworICByZXR1cm4gMDsKK30KKworaW50IENhbGxUZWFtRm9sbG93KG9iamVjdCBlbnYsIHN0cmluZyBjbWQpIHsKKyAgaWYgKCF0ZWFtX2F1dG9mb2xsb3cKKyAgICAgIHx8IFBPIT1RdWVyeShQX1RFQU0pCisgICAgICB8fCAhUE8KKyAgICAgIHx8ICFvYmplY3RwKGVudikKKyAgICAgIHx8ICFzdHJpbmdwKGNtZCkpCisgICAgcmV0dXJuIDA7CisgIGlmICghbWFwcGluZ3AodGVhbV9mb2xsb3dfdG9kbykpCisgICAgdGVhbV9mb2xsb3dfdG9kbz0oW10pOworICBpZiAoRU5WIT1lbnYgJiYgIXRlYW1fZm9sbG93X3RvZG9bRU5WXSkKKyAgICByZXR1cm4gMDsKKyAgdGVhbV9mb2xsb3dfdG9kb1tlbnZdPWNtZDsKKyAgaWYgKGZpbmRfY2FsbF9vdXQoIkRvVGVhbUZvbGxvdyIpPDApCisgICAgY2FsbF9vdXQoIkRvVGVhbUZvbGxvdyIsMCk7CisgIHJldHVybiAxOworfQorCitpbnQgQ2xlYXJUZWFtRm9sbG93KCkgeworICBpZiAoUE8hPVF1ZXJ5KFBfVEVBTSkgfHwgIVBPKQorICAgIHJldHVybiAwOworICB0ZWFtX2ZvbGxvd190b2RvPShbXSk7CisgIHJldHVybiAxOworfQorCittaXhlZCAqUHJlc2VudFRlYW1Sb3dzKCkgeworICBvYmplY3QgdGVhbTsKKyAgbWl4ZWQgKnJlczsKKyAgaW50IGk7CisKKyAgaWYgKCFvYmplY3RwKHRlYW09UXVlcnkoUF9URUFNKSkpIHsKKyAgICByZXM9RU1QVFlfVEVBTUFSUkFZOworICAgIHJlc1swXT0oe01FfSk7CisgICAgcmV0dXJuIHJlczsKKyAgfQorICByZXM9dGVhbS0+UHJlc2VudFJvd3MoRU5WKTsKKyAgZm9yIChpPTA7aTxNQVhfVEVBTVJPV1M7aSsrKQorICAgIGlmIChtZW1iZXIocmVzW2ldLE1FKT49MCkKKyAgICAgIHJldHVybiByZXM7CisgIHJlc1swXSs9KHtNRX0pOworICByZXR1cm4gcmVzOworfQorCit2YXJhcmdzIG1peGVkICpQcmVzZW50RW5lbXlSb3dzKG9iamVjdCAqaGVyZSkgeworICBtaXhlZCAqcmVzLCpyb3dzOworICBtYXBwaW5nIGFkZGVkX3RlYW1zOworICBpbnQgaSxqOworICBvYmplY3Qgb2IsdGVhbTsKKworICBhZGRlZF90ZWFtcz0oW1F1ZXJ5KFBfVEVBTSk6MV0pOyAvLyBOaWNodCBhdWYgZWlnZW5lcyBUZWFtIGhhdWVuCisgIHJlcz1FTVBUWV9URUFNQVJSQVk7CisgIGlmICghcG9pbnRlcnAoaGVyZSkpCisgICAgaGVyZT1QcmVzZW50RW5lbWllcygpOworICBmb3IgKGk9c2l6ZW9mKGhlcmUpLTE7aT49MDtpLS0pIHsKKyAgICBpZiAoIW9iamVjdHAob2I9aGVyZVtpXSkpCisgICAgICBjb250aW51ZTsKKyAgICBpZiAoIW9iamVjdHAodGVhbT1vYi0+UXVlcnlQcm9wKFBfVEVBTSkpKSB7CisgICAgICByZXNbMF0rPSh7b2J9KTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBpZiAoYWRkZWRfdGVhbXNbdGVhbV0pCisgICAgICBjb250aW51ZTsKKyAgICBhZGRlZF90ZWFtc1t0ZWFtXT0xOworICAgIHJvd3M9dGVhbS0+UHJlc2VudFJvd3MoRU5WKTsKKyAgICBmb3IgKGo9MDtqPE1BWF9URUFNUk9XUztqKyspCisgICAgICByZXNbal0rPXJvd3Nbal07CisgIH0KKyAgcmV0dXJuIHJlczsKK30KKwordmFyYXJncyBvYmplY3QgU2VsZWN0TmVhckVuZW15KG9iamVjdCAqaGVyZSwgaW50IGZvcmNlZnJvbSkgeworICBvYmplY3Qgb2IsZW4sdGVhbTsKKyAgbWl4ZWQgKnJvd3M7CisgIGludCAqcHJvYixwcm90LGkscixzeix1cHN6LHN1bTsKKworICBpZiAoIXBvaW50ZXJwKGhlcmUpKQorICAgIGhlcmU9UHJlc2VudEVuZW1pZXMoKTsKKyAgaWYgKCFvYmplY3RwKG9iPVNlbGVjdEVuZW15KGhlcmUpKSkKKyAgICByZXR1cm4gMDsKKyAgZW49b2ItPlF1ZXJ5UHJvcChQX1RFQU0pOyAgICAgICAgICAvLyBGZWluZGxpY2hlcyBUZWFtCisgIGlmIChvYmplY3RwKHRlYW09UXVlcnkoUF9URUFNKSkpIHsgLy8gRWlnZW5lcyBUZWFtCisgICAgaWYgKGVuPT10ZWFtKSAvLyBGZWluZCBpbSBlaWdlbmVuIFRlYW0sIGtlaW4gQU5ERVJFUyBNaXRnbGllZCB3YWVobGVuLgorICAgICAgcmV0dXJuIG9iOyAgLy8gQWJlciBhdWNoIGF1c3NlcmhhbGIgUmVpaGUgMSBkcmF1ZmhhdWVuCisgICAgcm93cz10ZWFtLT5QcmVzZW50Um93cyhFTlYpOworICAgIGlmIChtZW1iZXIocm93c1swXSxNRSk8MCkgLy8gU3RlaGUgaWNoIGluIGRlciBlcnN0ZW4gUmVpaGU/CisgICAgICByZXR1cm4gMDsgLy8gRmFsbHMgbmVpbiBpc3QgYXVjaCBrZWluIEdlZ25lciBuYWhlLgorICB9CisgIGlmICghb2JqZWN0cChlbikpCisgICAgcmV0dXJuIG9iOyAvLyBJc3QgbmljaHQgaW4gZWluZW0gVGVhbSwgYWxzbyBkcmF1Zi4KKyAgcm93cz1lbi0+UHJlc2VudFJvd3MoZW52aXJvbm1lbnQob2IpKTsKKyAgcHJvYj0oezEsMCwwLDAsMH0pOworICBwcm90PXN1bT0wOworICBmb3IgKGk9MDtpPE1BWF9URUFNUk9XUztpKyspIHsKKyAgICBpZiAocHJvdD4wKSBwcm90LS07ICAgICAgICAgICAgICAgIC8vIFNjaHV0emtlZ2VsIG5pbW10IGFiLgorICAgIGlmICghc3o9c2l6ZW9mKHJvd3NbaV0pKSBjb250aW51ZTsgLy8gR2VnbmVyIGluIGRpZXNlciBSZWloZQorICAgIHVwc3o9c3otcHJvdDtpZiAodXBzejwwKSBjb250aW51ZTsgLy8gQW56YWhsIHVuZ2VzY2h1ZXR6dGVyIEdlZ25lcgorICAgIHByb2JbaV0rPSh1cHN6K3N1bSk7ICAgICAgICAgICAgICAgLy8gV2FocnNjaGVpbmxpY2hrZWl0ICs9IHVuZ2VzY2h1ZXR6dAorICAgIHN1bT1wcm9iW2ldOyAgICAgICAgICAgICAgICAgICAgICAgLy8gU3VtbWUgYmlzaGVyaWdlciBXYWhyc2NoZWlubGljaGtlaXRlbgorICAgIGlmIChzej5wcm90KSBwcm90PXN6OyAgICAgICAgICAgICAgLy8gTmV1ZXIgU2NodXR6a2VnZWwKKyAgfQorICByPXJhbmRvbShzdW0pOworICBmb3IgKGk9MDtpPE1BWF9URUFNUk9XUztpKyspCisgICAgaWYgKHI8cHJvYltpXSkKKyAgICAgIGJyZWFrOworICBpZiAoaT49TUFYX1RFQU1ST1dTKQorICAgIGk9MDsKKyAgaWYgKG9iamVjdHAoZW49U2VsZWN0RW5lbXkoZm9yY2Vmcm9tPyhoZXJlJnJvd3NbaV0pOnJvd3NbaV0pKSkKKyAgICByZXR1cm4gZW47CisgIGlmIChpICYmIG9iamVjdHAoZW49U2VsZWN0RW5lbXkoZm9yY2Vmcm9tPyhoZXJlJnJvd3NbMF0pOnJvd3NbMF0pKSkKKyAgICByZXR1cm4gZW47CisgIHJldHVybiBvYjsKK30KKwordmFyYXJncyBvYmplY3QgU2VsZWN0RmFyRW5lbXkob2JqZWN0ICpoZXJlLCBpbnQgbWluLCBpbnQgbWF4LCBpbnQgZm9yY2Vmcm9tKSB7CisgIG1peGVkICpyb3dzOworICBpbnQgKnByb2IsaSxyLHN1bTsKKyAgb2JqZWN0IGVuOworCisgIGlmIChtYXg8MCB8fCBtaW4+PU1BWF9URUFNUk9XUyB8fCBtYXg8bWluKQorICAgIHJldHVybiAwOworICBpZiAobWluPDApIG1pbj0wOworICBpZiAobWF4Pj1NQVhfVEVBTVJPV1MpIG1heD1NQVhfVEVBTVJPV1MtMTsKKyAgaWYgKCFwb2ludGVycChoZXJlKSkKKyAgICBoZXJlPVByZXNlbnRFbmVtaWVzKCk7CisgIHJvd3M9UHJlc2VudEVuZW15Um93cyhoZXJlKTsKKyAgcHJvYj0oezAsMCwwLDAsMH0pOworICBzdW09MDsKKyAgZm9yIChpPW1pbjtpPD1tYXg7aSsrKQorICAgIHN1bT1wcm9iW2ldPXN1bStzaXplb2Yocm93c1tpXSkrbWF4LWk7CisKKyAgcj1yYW5kb20oc3VtKTsKKyAgZm9yIChpPW1pbjtpPD1tYXg7aSsrKQorICAgIGlmIChyPHByb2JbaV0pCisgICAgICBicmVhazsKKyAgaWYgKGk+bWF4KQorICAgIGk9bWluOworICBpZiAob2JqZWN0cChlbj1TZWxlY3RFbmVteShmb3JjZWZyb20/KGhlcmUmcm93c1tpXSk6cm93c1tpXSkpKQorICAgIHJldHVybiBlbjsKKyAgZm9yIChpPW1pbjtpPD1tYXg7aSsrKQorICAgIGlmIChvYmplY3RwKGVuPVNlbGVjdEVuZW15KGZvcmNlZnJvbT8oaGVyZSZyb3dzW2ldKTpyb3dzW2ldKSkpCisgICAgICByZXR1cm4gZW47CisgIHJldHVybiAwOworfQorCittaXhlZCBfcXVlcnlfZnJpZW5kKCkgeworICBtaXhlZCByZXM7CisKKyAgaWYgKHJlcz1RdWVyeShQX0ZSSUVORCkpCisgICAgcmV0dXJuIHJlczsKKyAgaWYgKG9iamVjdHAocmVzPVF1ZXJ5KFBfVEVBTV9BU1NPQ19NRU1CRVJTKSkKKyAgICAgICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUocmVzKSkKKyAgICByZXR1cm4gcmVzOworICByZXR1cm4gMDsKK30KKworaW50IERlQXNzb2NNZW1iZXIob2JqZWN0IG5wYykgeworICBtaXhlZCBvYnM7CisgIG9iamVjdCB0ZWFtOworCisgIGlmIChleHRlcm5fY2FsbCgpICYmIFBPIT1ucGMgJiYKKyAgICAgIG1lbWJlcigoeyJnaWxkZW4iLCJzcGVsbGJvb2tzIn0pLAorICAgICAgICAgICAgIGV4cGxvZGUob2JqZWN0X25hbWUoUE8pLCIvIilbMV0pPDApCisgICAgcmV0dXJuIDA7CisgIG9icz1RdWVyeVByb3AoUF9URUFNX0FTU09DX01FTUJFUlMpOworICBpZiAoIXBvaW50ZXJwKG9icykpCisgICAgcmV0dXJuIDA7CisgIG9icy09KHtucGMsMH0pOworICBTZXRQcm9wKFBfVEVBTV9BU1NPQ19NRU1CRVJTLG9icyk7CisgIGlmIChvYmplY3RwKHRlYW09UXVlcnlQcm9wKFBfVEVBTSkpKQorICAgIHRlYW0tPlJlbW92ZUFzc29jTWVtYmVyKE1FLG5wYyk7CisgIHJldHVybiAxOworfQorCitpbnQgQXNzb2NNZW1iZXIob2JqZWN0IG5wYykgeworICBtaXhlZCBvYnM7CisgIG9iamVjdCB0ZWFtOworCisgIGlmIChleHRlcm5fY2FsbCgpICYmIFBPIT1ucGMgJiYKKyAgICAgIG1lbWJlcigoeyJnaWxkZW4iLCJzcGVsbGJvb2tzIn0pLAorICAgICAgICAgICAgIGV4cGxvZGUob2JqZWN0X25hbWUoUE8pLCIvIilbMV0pPDApCisgICAgcmV0dXJuIDA7CisgIGlmICghb2JqZWN0cChucGMpCisgICAgICB8fCBucGMtPlF1ZXJ5UHJvcChQX1RFQU1fQVNTT0NfTUVNQkVSUykKKyAgICAgIHx8IElzRW5lbXkobnBjKQorICAgICAgfHwgbnBjPT1NRQorICAgICAgfHwgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShucGMpKQorICAgIHJldHVybiAwOworICBvYnM9UXVlcnlQcm9wKFBfVEVBTV9BU1NPQ19NRU1CRVJTKTsKKyAgaWYgKG9iamVjdHAob2JzKSkKKyAgICByZXR1cm4gMDsKKyAgaWYgKCFwb2ludGVycChvYnMpKQorICAgIG9icz0oe30pOworICBvYnM9KG9icy0oe25wYywwfSkpKyh7bnBjfSk7CisgIFNldFByb3AoUF9URUFNX0FTU09DX01FTUJFUlMsb2JzKTsKKyAgbnBjLT5TZXRQcm9wKFBfVEVBTV9BU1NPQ19NRU1CRVJTLE1FKTsKKyAgaWYgKG9iamVjdHAodGVhbT1RdWVyeVByb3AoUF9URUFNKSkpCisgICAgdGVhbS0+QWRkQXNzb2NNZW1iZXIoTUUsbnBjKTsKKyAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3Mgdm9pZCBJbnNlcnRFbmVteVRlYW0obWl4ZWQgZW5zLCBpbnQgcmVrKSB7CisgIG9iamVjdCAqb2JzLG9iLGV0ZWFtLHRlYW07CisgIGludCBpOworCisgIHRlYW09UXVlcnkoUF9URUFNKTsKKyAgLy8gQWxsZSBUZWFtbWl0Z2xpZWRlciBkZXMgR2VnbmVycyBzaW5kIEZlaW5kOgorICBpZiAob2JqZWN0cChlbnMpKSB7CisgICAgaWYgKG9iamVjdHAoZXRlYW09ZW5zLT5RdWVyeVByb3AoUF9URUFNKSkpIHsKKyAgICAgIGlmIChldGVhbT09dGVhbSkgLy8gZmVpbmRsaWNoZXMgVGVhbSA9IGVpZ2VuZXMgVGVhbT8KKyAgICAgICAgcmV0dXJuOyAgICAgICAgLy8gYWxzbyBuaWNodCBhbGxlIFRlYW1taXRnbGllZGVyIGdlZ2VuZWluYW5kZXIgaGV0emVuCisgICAgICBlbnM9ZXRlYW0tPk1lbWJlcnMoKTsKKyAgICB9IGVsc2UgeworICAgICAgZW5zPSh7ZW5zfSk7CisgICAgfQorICB9CisgIGlmICghcG9pbnRlcnAoZW5zKSkKKyAgICByZXR1cm47CisgIGVucy09KHtNRX0pOworCisgIC8vIEludGVyYWN0aXZlcyBzb2xsZW4ga2VpbmUgSW50ZXJhY3RpdmVzIGR1cmNoIFRlYW0gYW5ncmVpZmVuOgorICBpZiAocXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkpIHsKKyAgICBmb3IgKGk9c2l6ZW9mKGVucyktMTtpPj0wO2ktLSkKKyAgICAgIGlmIChvYmplY3RwKG9iPWVuc1tpXSkgJiYgZW52aXJvbm1lbnQob2IpPT1lbnZpcm9ubWVudCgpCisgICAgICAgICAgJiYgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob2IpKQorICAgICAgICBJbnNlcnRTaW5nbGVFbmVteShvYik7CisgIH0gZWxzZSB7CisgICAgZm9yIChpPXNpemVvZihlbnMpLTE7aT49MDtpLS0pCisgICAgICBpZiAob2JqZWN0cChvYj1lbnNbaV0pICYmIGVudmlyb25tZW50KG9iKT09ZW52aXJvbm1lbnQoKSkKKyAgICAgICAgSW5zZXJ0U2luZ2xlRW5lbXkob2IpOworICB9CisKKyAgLy8gQWxsZSBhbmRlcmVuIFRlYW1taXRnbGllZGVyIEluZm9ybWllcmVuOgorICBpZiAocmVrIHx8ICFvYmplY3RwKHRlYW0pIHx8ICFwb2ludGVycChvYnM9dGVhbS0+TWVtYmVycygpKSkKKyAgICByZXR1cm47CisgIG9icy09KHtNRX0pOworICBvYnMtPWVuczsKKyAgZm9yIChpPXNpemVvZihvYnMpLTE7aT49MDtpLS0pCisgICAgaWYgKG9iamVjdHAob2I9b2JzW2ldKSkKKyAgICAgIG9iLT5JbnNlcnRFbmVteVRlYW0oZW5zLDEpOworfQorCitpbnQgVGVhbUZsZWUoKSB7CisgIG9iamVjdCB0ZWFtOworCisgIGlmIChRdWVyeShQX1RFQU1fV0lNUFlfUk9XKTwyIHx8ICFvYmplY3RwKHRlYW09UXVlcnkoUF9URUFNKSkpCisgICAgcmV0dXJuIDA7CisgIGlmICghdGVhbS0+RmxlZVRvUm93KE1FKSkKKyAgICAgcmV0dXJuIDA7CisgIGlmIChRdWVyeShQX1RFQU1fTEVBREVSKT09dGVhbSkgeworICAgIGlmICh0ZWFtX2F1dG9mb2xsb3cpCisgICAgICB0ZWxsX29iamVjdChNRSwiRHUgdmVyc3VjaHN0IHp1IGZsaWVoZW4sICIrCisgICAgICAgICAgICAgICAgICAiRGVpbiBUZWFtIGZvbGd0IERpciBuaWNodCBtZWhyLlxuIik7CisgICAgdGVhbV9hdXRvZm9sbG93PTA7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3MgbWFwcGluZyBQcmVzZW50VGVhbVBvc2l0aW9ucyhtaXhlZCBwcmVzX3Jvd3MpIHsKKyAgbWFwcGluZyByZXM7CisgIGludCBpLGo7CisgIG9iamVjdCAqb2JzLG9iOworCisgIHJlcz0oW10pOworICBpZiAoIXBvaW50ZXJwKHByZXNfcm93cykpCisgICAgcHJlc19yb3dzPVByZXNlbnRUZWFtUm93cygpOworICBmb3IgKGk9MDtpPE1BWF9URUFNUk9XUztpKyspIHsKKyAgICBvYnM9cHJlc19yb3dzW2ldOworICAgIGZvciAoaj1zaXplb2Yob2JzKS0xO2o+PTA7ai0tKQorICAgICAgaWYgKG9iamVjdHAob2I9b2JzW2pdKSAmJiAhcmVzW29iXSkKKyAgICAgICAgcmVzW29iXT1pKzE7CisgIH0KKyAgcmV0dXJuIHJlczsKK30KKwordmFyYXJncyBpbnQgUHJlc2VudFBvc2l0aW9uKG1peGVkIHBtYXApIHsKKyAgb2JqZWN0IHRlYW07CisgIGludCBpOworCisgIGlmICghb2JqZWN0cCh0ZWFtPVF1ZXJ5KFBfVEVBTSkpKQorICAgIHJldHVybiAxOworICBpZiAobWFwcGluZ3AocG1hcCkpCisgICAgcmV0dXJuIHBtYXBbTUVdOworICBpZiAoIXBvaW50ZXJwKHBtYXApKQorICAgIHBtYXA9dGVhbS0+UHJlc2VudFJvd3MoRU5WKTsKKyAgZm9yIChpPTE7aTxNQVhfVEVBTVJPV1M7aSsrKQorICAgIGlmIChtZW1iZXIocG1hcFtpXSxNRSk+PTApCisgICAgICByZXR1cm4gaSsxOworICByZXR1cm4gMTsKK30KKworI2RlZmluZSBGSUxMU1RSSU5HICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIgordmFyYXJncyBwcml2YXRlIHN0cmluZyBjZW50ZXJfc3RyaW5nKHN0cmluZyBzdHIsIGludCB3KSB7CisgIHJldHVybiAoRklMTFNUUklOR1swLi4oKHctc2l6ZW9mKHN0cikpLzItMSldK3N0citGSUxMU1RSSU5HKVswLi4ody0xKV07Cit9CisKK3ByaXZhdGUgaW50IFNob3dUZWFtUm93cygpIHsKKyAgaW50IGksaixzejsKKyAgbWl4ZWQgKnByZXNfcm93czsKKyAgb2JqZWN0ICpvYnMsb2I7CisgIHN0cmluZyBzdHI7CisKKyAgcHJlc19yb3dzPVByZXNlbnRFbmVteVJvd3MoKTsKKyAgZm9yIChzej1NQVhfVEVBTVJPV1MtMTtzej49MDtzei0tKQorICAgIGlmIChzaXplb2YocHJlc19yb3dzW3N6XSkpCisgICAgICBicmVhazsKKyAgZm9yIChpPXN6O2k+PTA7aS0tKSB7CisgICAgb2JzPXByZXNfcm93c1tpXTtzdHI9IiI7CisgICAgZm9yIChqPXNpemVvZihvYnMpLTE7aj49MDtqLS0pCisgICAgICBpZiAob2JqZWN0cChvYj1vYnNbal0pKSB7CisgICAgICAgIGlmIChzdHIhPSIiKSBzdHIrPSIgLyAiOworICAgICAgICBzdHIrPW9iLT5OYW1lKFJBVyk7CisgICAgICB9CisgICAgcHJpbnRmKCIlZC4gJXNcbiIsaSsxLGNlbnRlcl9zdHJpbmcoc3RyLDc1KSk7CisgIH0KKyAgaWYgKHN6Pj0wKQorICAgIHdyaXRlKCIgICAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpOworICBwcmVzX3Jvd3M9UHJlc2VudFRlYW1Sb3dzKCk7CisgIGZvciAoc3o9TUFYX1RFQU1ST1dTLTE7c3o+MDtzei0tKQorICAgIGlmIChzaXplb2YocHJlc19yb3dzW3N6XSkpCisgICAgICBicmVhazsKKyAgZm9yIChpPTA7aTw9c3o7aSsrKSB7CisgICAgb2JzPXByZXNfcm93c1tpXTtzdHI9IiI7CisgICAgZm9yIChqPXNpemVvZihvYnMpLTE7aj49MDtqLS0pCisgICAgICBpZiAob2JqZWN0cChvYj1vYnNbal0pKSB7CisgICAgICAgIGlmIChzdHIhPSIiKSBzdHIrPSIgLyAiOworICAgICAgICBzdHIrPW9iLT5OYW1lKFJBVyk7CisgICAgICB9CisgICAgcHJpbnRmKCIlZC4gJXNcbiIsaSsxLGNlbnRlcl9zdHJpbmcoc3RyLDc1KSk7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3MgaW50IHRlYW1fbGlzdChzdHJpbmcgYXJnKSB7CisgIG9iamVjdCAqdG9icywqb2JzLHRvYixvYixsZDsKKyAgc3RyaW5nICpubXMsKnRubXMsc3RyOworICBpbnQgaSxqOworCisgIGlmICghcG9pbnRlcnAodG9icz1URUFNX01BU1RFUi0+TGlzdFRlYW1PYmplY3RzKCkpKSByZXR1cm4gMDsKKyAgaWYgKGFyZyE9ImFsbGUiKSBhcmc9MDsKKyAgdG5tcz0oe30pOworICBmb3IgKGk9c2l6ZW9mKHRvYnMpLTE7aT49MDtpLS0pIHsKKyAgICBpZiAoIW9iamVjdHAodG9iPXRvYnNbaV0pCisgICAgICAgIHx8ICFvYmplY3RwKGxkPXRvYi0+TGVhZGVyKCkpCisgICAgICAgIHx8ICghcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShsZCkgJiYgIWFyZykKKyAgICAgICAgfHwgIXBvaW50ZXJwKG9icz10b2ItPk1lbWJlcnMoKSkpCisgICAgICBjb250aW51ZTsKKyAgICBubXM9KHt9KTsKKyAgICBmb3IgKGo9c2l6ZW9mKG9icyktMTtqPj0wO2otLSkgeworICAgICAgaWYgKCFvYmplY3RwKG9iPW9ic1tqXSkKKyAgICAgICAgICB8fCAoIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob2IpICYmIWFyZykpCisgICAgICAgIGNvbnRpbnVlOworICAgICAgaWYgKCFzdHJpbmdwKHN0cj1vYi0+TmFtZShXRVIpKSkgc3RyPSI/IjsKKyAgICAgIGlmIChvYj09bGQpIHN0cis9IigqKSI7CisgICAgICBubXMrPSh7c3RyfSk7CisgICAgICBubXM9c29ydF9hcnJheShubXMsIyc+KTsKKyAgICB9CisgICAgaWYgKCFzdHJpbmdwKHN0cj10b2ItPk5hbWUoKSkpIHN0cj0iVGVhbSA/IjsKKyAgICBzdHIrPSI6ICI7CisgICAgdG5tcys9KHticmVha19zdHJpbmcoaW1wbG9kZShubXMsIiwgIiksNzgsc3RyKX0pOworICAgIHRubXM9c29ydF9hcnJheSh0bm1zLCMnPCk7CisgIH0KKyAgaWYgKHNpemVvZih0bm1zKSkKKyAgICB0ZWxsX29iamVjdChNRSwgc3ByaW50ZigiJUBzXG4iLCB0bm1zKSk7CisgIGVsc2UKKyAgICB0ZWxsX29iamVjdChNRSwgIktlaW5lIFRlYW1zIGdlZnVuZGVuLlxuIik7IAorICAKKyAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3MgaW50IHRlYW1jbWQoc3RyaW5nIGFyZykgeworICBzdHJpbmcgKndvcmRzLG5hcmc7CisgIG9iamVjdCB0ZWFtOworCisgIGlmICghYXJnKQorICAgIGFyZz0iIjsKKyAgaWYgKCFzdHJpbmdwKG5hcmc9VFAtPl91bnBhcnNlZF9hcmdzKCkpKQorICAgIG5hcmcgPSBhcmc7CisgIGlmICghc2l6ZW9mKHdvcmRzPWV4cGxvZGUoYXJnLCIgIikpKQorICAgIHJldHVybiAwOworIAorICBpZiAoc2l6ZW9mKHdvcmRzKSA+IDEpIHsKKyAgICAgIGFyZz1pbXBsb2RlKHdvcmRzWzEuLl0sIiAiKTsKKyAgICAgIG5hcmcgPSBpbXBsb2RlKGV4cGxvZGUobmFyZywgIiAiKVsxLi5dLCAiICIpOworICB9CisgIGVsc2UKKyAgICAgIGFyZyA9IG5hcmcgPSAiIjsKKworICBzd2l0Y2god29yZHNbMF0pIHsgLy8gQmVmZWhsZSBkaWUga2VpbmUgTWl0Z2xpZWRzY2hhZnQgZXJmb3JkZXJuOgorICBjYXNlICJhdWZuYWhtZSI6CisgICAgcmV0dXJuIHRlYW1fYXVmbmFobWUoYXJnKTsKKyAgY2FzZSAiZm9sZ2UiOgorICAgIHJldHVybiB0ZWFtX2F1Zm5haG1ld3Vuc2NoKGFyZyk7CisgIGNhc2UgIj8iOgorICBjYXNlICJoaWxmZSI6CisgICAgcmV0dXJuIHRlYW1faGVscCgpOworICBjYXNlICJsaXN0ZSI6CisgICAgcmV0dXJuIHRlYW1fbGlzdChhcmcpOyAgCisgIGNhc2UgInVlYmVyc2ljaHQiOgorICAgIHJldHVybiBTaG93VGVhbVJvd3MoKTsKKyAgZGVmYXVsdDo7CisgIH0KKworICBpZiAoIW9iamVjdHAodGVhbT1RdWVyeVByb3AoUF9URUFNKSkpCisgICAgcmV0dXJuIG5vdGlmeV9mYWlsKCJEdSBiaXN0IGluIGtlaW5lbSBUZWFtLlxuIiksMDsKKworICBzd2l0Y2god29yZHNbMF0pIHsKKyAgY2FzZSAiYW5ncmlmZnNiZWZlaGwiOgorICAgIGlmIChuYXJnPT0iIikgbmFyZz0wOworICAgIHRlYW1fYXR0YWNrX2NtZD1uYXJnOworICAgIGlmIChzdHJpbmdwKG5hcmcpKQorICAgICAgd3JpdGUoIkR1IGJlZ2lubnN0IGRlbiBLYW1wZiBtaXQgXCIiK25hcmcrIlwiXG4iKTsKKyAgICBlbHNlCisgICAgICB3cml0ZSgiRHUgaGFzdCBkZW4gVGVhbWFuZ3JpZmZzYmVmZWhsIGRlYWt0aXZpZXJ0LlxuIik7CisgICAgYnJlYWs7IC8vIE5JQ0hUIHJldHVybiEKKyAgY2FzZSAiYXV0b2ZvbGdlIjoKKyAgY2FzZSAiYXV0b2YiOgorICAgIGlmIChhcmc9PSJlaW4iIHx8IGFyZz09ImFuIikgeworICAgICAgdGVhbV9hdXRvZm9sbG93PTE7CisgICAgICBpZiAoSXNUZWFtTGVhZGVyKCkpCisgICAgICAgIHdyaXRlKCJEZWluIFRlYW0gZm9sZ3QgRGlyLlxuIik7CisgICAgICBlbHNlCisgICAgICAgIHdyaXRlKCJEdSBmb2xnc3QgamV0enQgZGVtIFRlYW1sZWl0ZXIuXG4iKTsKKyAgICB9IGVsc2UgeworICAgICAgdGVhbV9hdXRvZm9sbG93PTA7CisgICAgICBpZiAoSXNUZWFtTGVhZGVyKCkpCisgICAgICAgIHdyaXRlKCJEZWluIFRlYW0gZm9sZ3QgRGlyIG5pY2h0IG1laHIuXG4iKTsKKyAgICAgIGVsc2UKKyAgICAgICAgd3JpdGUoIkR1IGZvbGdzdCBqZXR6dCBuaWNodCBtZWhyIGRlbSBUZWFtbGVpdGVyLlxuIik7CisgICAgfQorICAgIGJyZWFrOyAvLyBOSUNIVCByZXR1cm4hCisgIGRlZmF1bHQ6IDsKKyAgfQorICByZXR1cm4gdGVhbS0+VGVhbUNtZCh3b3Jkc1swXSxuYXJnKTsgLy8gQmVmZWhsZSBkaWUgTWl0Z2xpZWRzY2hhZnQgZXJmb3JkZXJuOgorfQorCit2YXJhcmdzIHZvaWQgSW5mb3JtUm93Q2hhbmdlKGludCBmcm9tLCBpbnQgdG8sIG9iamVjdCBjYXN0ZXIpIHsKKworICBpZiAoY2FzdGVyKSByZXR1cm47IC8vIEZ1ZXIgZGVuIEZhbGwsIGRhc3MgR2lsZGVub2JqZWt0PT1NRSBpc3QKKyAgaWYgKFBPIT1RdWVyeShQX1RFQU0pKSByZXR1cm47CisjaWYgX19CT09UX1RJTUVfXyA8IDEyODE5MDQ0MzcKKyAgbWl4ZWQgZ2lsZGUgPSBRdWVyeVByb3AoUF9HVUlMRCk7CisgIGlmICghc3RyaW5ncChnaWxkZSkpIHJldHVybjsKKyAgaWYgKCFvYmplY3RwKGdpbGRlPWZpbmRfb2JqZWN0KCIvZ2lsZGVuLyIrZ2lsZGUpKSkgcmV0dXJuOworICBnaWxkZS0+SW5mb3JtUm93Q2hhbmdlKGZyb20sdG8sTUUpOworI2VuZGlmCisgIEhvb2tGbG93KEhfSE9PS19URUFNUk9XQ0hBTkdFLCAoe2Zyb20sdG99KSApOworfQpkaWZmIC0tZ2l0IGEvc3RkL21haWxjYWJpbi5jIGIvc3RkL21haWxjYWJpbi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjFhOTRlODUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbWFpbGNhYmluLmMKQEAgLTAsMCArMSwxMiBAQAorI3ByYWdtYSBzdHJpY3RfdHlwZXMsc2F2ZV90eXBlcworCitpbmhlcml0ICIvcC9zZXJ2aWNlL2xvY28vc3RkL21haWxjYWJpbiI7CisKK3ZvaWQgY3JlYXRlKCkgeworICBpZiAoIWNsb25lcCgpIHx8IG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpID09IF9fRklMRV9fWzAuLjwzXSkgeworICAgICAgc2V0X25leHRfcmVzZXQoLTEpOworICAgICAgcmV0dXJuOworICB9CisgIDo6Y3JlYXRlKCk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9tb3JlLmMgYi9zdGQvbW9yZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1MTg5ODEKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvbW9yZS5jCkBAIC0wLDAgKzEsMTQzIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbW9yZS5jIC0tIG1vcmUgZmlsZXMKKy8vCisvLyAkSWQ6IG1vcmUuYyA5MTQyIDIwMTUtMDItMDQgMjI6MTc6MjlaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisKK2luaGVyaXQgIi9zdGQvdXRpbC9wYWdlciI7CisKKyNpbmNsdWRlIDxwYWdlci5oPgorCisjaWZkZWYgR0VSTUFOCisjIGRlZmluZSBNU0dfV1JBUFBFRAkiIFZPTSBBTkZBTkciCisjIGRlZmluZSBNU0dfTk9UX0ZPVU5ECSIgTklDSFRTIEdFRlVOREVOIgorIyBkZWZpbmUgTVNHX05PX1JFR1gJIiBGRUhMRU5ERVIgUkVHLiBBVVNEUlVDSyIKKyMgZGVmaW5lIE1TR19JTExFR0FMCSIgSUxMRUdBTEUgWkVJTEVOWkFITCIKKyMgZGVmaW5lIE1TR19IRUxQICAgICAgICJcCitIaWxmZSBmdWVyIG1vcmU6XG5cCitcblwKK2IsQiAgICAgICAgLS0gRWluZSBTZWl0ZSB6dXJ1ZWNrLlxuXAordSxVICAgICAgICAtLSBFaW5lIGhhbGJlIFNlaXRlIHp1cnVlY2suXG5cCitmLEYgICAgICAgIC0tIEVpbmUgU2VpdGUgdm9yd2FlcnRzLlxuXAorZCxEICAgICAgICAtLSBFaW5lIGhhbGJlIFNlaXRlIHZvcndhZXJ0cy5cblwKKzxaZWlsZT4gICAgLS0gU3ByaW5nZSB6dSBaZWlsZSA8WmVpbGU+XG5cCitxLHggICAgICAgIC0tIFZlcmxhc3NlbiB2b24gbW9yZS5cblwKKy88UmVnRXhwPiAgLS0gTmFjaCBkZW0gcmVndWxhZXJlbiBBdXNkcnVjayA8UmVnRXhwPiBzdWNoZW4uXG4iCisjZWxzZQorIyBkZWZpbmUgTVNHX1dSQVBQRUQJIiBXUkFQUEVEIgorIyBkZWZpbmUgTVNHX05PVF9GT1VORAkiIE5PVEhJTkcgRk9VTkQiCisjIGRlZmluZSBNU0dfTk9fUkVHWAkiIE5PIFBSRVYgUkVHVUxBUiBFWFBSIgorIyBkZWZpbmUgTVNHX0lMTEVHQUwJIiBJTExFR0FMIExJTkUgTlVNQkVSIgorIyBkZWZpbmUgTVNHX0hFTFAgICAgICAgIlwKK0hlbHAgZm9yIG1vcmU6XG5cCitcblwKK2IsQiAgICAgICAgLS0gT25lIHBhZ2UgYmFjay5cblwKK3UsVSAgICAgICAgLS0gSGFsZiBhIHBhZ2UgYmFjay5cblwKK2YsRiAgICAgICAgLS0gT25lIHBhZ2UgZm9yd2FyZC5cblwKK2QsRCAgICAgICAgLS0gSGFsZiBhIHBhZ2UgZm9yd2FyZC5cblwKKzxsaW5lPiAgICAgLS0gSnVtcCB0byBsaW5lIG51bWJlciA8bGluZT5cblwKK3EseCAgICAgICAgLS0gUXVpdCBvciBlWGl0IG1vcmUuXG5cCisvPHJlZ2V4cD4gIC0tIFNlYXJjaCBmb3IgdGhlIHJlZ3VsYXIgZXhwcmVzc2lvbiA8cmVnZXhwPi5cbiIKKyNlbmRpZgorCitwcml2YXRlIG5vc2F2ZSBzdHJpbmcgY3Byb21wdCA9ICIiOworCitzdHJpbmcgcHJvbXB0KG1peGVkIHBpbmZvLCBzdHJpbmcgYWRkKQoreworICBpbnQgbGluZSxtYXg7IG1heCA9IDE7CisgIGlmKHBvaW50ZXJwKHBpbmZvKSkKKyAgeworICAgICBpZihwaW5mb1tDVVJMXSArIHBpbmZvW1BBR0VdID49IHBpbmZvW01BWExdKSBsaW5lID0gcGluZm9bTUFYTF07CisgICAgIGVsc2UgbGluZSA9IHBpbmZvW0NVUkxdICsgcGluZm9bUEFHRV07CisgICAgIG1heCA9IHBpbmZvW01BWExdOworICB9CisgIGlmIChwaW5mb1tGTEFHXSAmIEVfQUJTKQorICAgIHJldHVybiBzcHJpbnRmKCIlcyAoJWQvJWQpJXMgJXMiLAorCQkgICA6OnByb21wdChwaW5mbywgIiIpLAorCQkgICBsaW5lLTEsIHBpbmZvW01BWExdLAorCQkgICBjcHJvbXB0LCBzdHJpbmdwKGFkZCk/YWRkOiIiKTsKKyAgZWxzZQorICAgIHJldHVybiBzcHJpbnRmKCIlcyglZCUlKSVzICVzIiwKKwkJICAgOjpwcm9tcHQocGluZm8sICIiKSwKKwkJICAgbGluZSoxMDAvbWF4LCAKKwkJICAgY3Byb21wdCwgc3RyaW5ncChhZGQpP2FkZDoiIik7Cit9CisKK2ludCBzZWFyY2gobWl4ZWQgcGluZm8pCit7CisgIGludCBsLCBsaW5lczsKKyAgbWl4ZWQgdG1wOworICBsID0gcGluZm9bQ1VSTF07CisgIHdoaWxlKCh0bXAgPSBmcmVhZChwaW5mbywgbCwgcGluZm9bUEFHRV0pKSAmJgorICAgICAgICAhc2l6ZW9mKHJlZ2V4cChvbGRfZXhwbG9kZSh0bXAsICJcbiIpLCBwaW5mb1tSRUdYXSkpKQorICAgIGwgKz0gcGluZm9bUEFHRV07CisgIGlmKCF0bXApCisgIHsKKyAgICBjcHJvbXB0ICs9IE1TR19XUkFQUEVEOworICAgIGwgPSAxOworICAgIHdoaWxlKGwgPCBwaW5mb1tDVVJMXSAmJgorICAgICAgICAgICh0bXAgPSBmcmVhZChwaW5mbywgbCwgcGluZm9bUEFHRV0pKSAmJgorICAgICAgICAgICFzaXplb2YocmVnZXhwKG9sZF9leHBsb2RlKHRtcCwgIlxuIiksIHBpbmZvW1JFR1hdKSkpCisgICAgICBsICs9IHBpbmZvW1BBR0VdOworICAgIGlmKGwgPj0gcGluZm9bQ1VSTF0pIHJldHVybiAwOworICB9CisgIHJldHVybiBsOworfQorCit2YXJhcmdzIGludCBldmFsX2NvbW1hbmQobWl4ZWQgaW4sIG1peGVkIHBpbmZvKQoreworICBjcHJvbXB0ID0gIiI7CisgIGlmKHN0cmluZ3AoaW4pKQorICAgIHN3aXRjaChpbikKKyAgICB7CisgICAgY2FzZSAiPyI6CisgICAgICB3cml0ZShNU0dfSEVMUCsiXG4iKTsKKyAgICAgIHJldHVybiAwOyAKKyAgICBjYXNlICJiIjoKKyAgICBjYXNlICJCIjoKKyAgICAgIHBpbmZvW0NVUkxdIC09IHBpbmZvW1BBR0VdOworICAgICAgYnJlYWs7CisgICAgY2FzZSAidSI6CisgICAgY2FzZSAiVSI6CisgICAgICBwaW5mb1tDVVJMXSAtPSBwaW5mb1tQQUdFXSAvIDI7CisgICAgICBicmVhazsKKyAgICBjYXNlICJmIjoKKyAgICBjYXNlICJGIjoKKyAgICAgIHBpbmZvW0NVUkxdICs9IHBpbmZvW1BBR0VdOworICAgICAgYnJlYWs7CisgICAgY2FzZSAiZCI6CisgICAgY2FzZSAiRCI6CisgICAgICBwaW5mb1tDVVJMXSArPSBwaW5mb1tQQUdFXSAvIDI7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgIHsKKyAgICAgIGludCBsOworICAgICAgaWYobCA9IHRvX2ludChpbikpCisgICAgICB7CisgICAgICAgIGlmKGwgPiBwaW5mb1tNQVhMXSB8fCBsIDwgMSkgcmV0dXJuIChjcHJvbXB0ID0gTVNHX0lMTEVHQUwsIDApOworICAgICAgICBwaW5mb1tDVVJMXSA9IGw7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaWYoc2l6ZW9mKGluKSAmJiBpblswXSA9PSAnLycpCisgICAgICB7CisJaWYoc2l6ZW9mKGluKSA9PSAxKQorCXsKKwkgIGlmKCFwaW5mb1tSRUdYXSkgcmV0dXJuIChjcHJvbXB0ID0gTVNHX05PX1JFR1gsIDApOworCX0KKwllbHNlIHBpbmZvW1JFR1hdID0gaW5bMS4uXTsKKwlpZihsID0gc2VhcmNoKHBpbmZvKSkgcGluZm9bQ1VSTF0gPSBsOworCWVsc2UgcmV0dXJuIChjcHJvbXB0ID0gTVNHX05PVF9GT1VORCwgMCk7CisgICAgICB9CisgICAgICBlbHNlIHJldHVybiA6OmV2YWxfY29tbWFuZChpbiwgcGluZm8pOyAgICAKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICB9CisgIGVsc2UgcmV0dXJuIDo6ZXZhbF9jb21tYW5kKGluLCBwaW5mbyk7CisgIHJldHVybiA6OmV2YWxfY29tbWFuZCgtMSwgcGluZm8pOworfSAgIApkaWZmIC0tZ2l0IGEvc3RkL25ld3NjbGllbnQuYyBiL3N0ZC9uZXdzY2xpZW50LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjA0N2U0MQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9uZXdzY2xpZW50LmMKQEAgLTAsMCArMSwyNDQgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBuZXdzY2xpZW50LmMgLS0gTmFjaHJpY2h0ZW5icmV0dGVyCisvLworLy8gJElkOiBuZXdzY2xpZW50LmMgODM0OSAyMDEzLTAyLTA0IDIxOjE1OjI4WiBaZXNzdHJhICQKKworLyogMTk5MiBKT0YgKi8KKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC90aGluZyI7Citpbmhlcml0ICIvc3RkL21vcmUiOworCisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPG5ld3MuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxpbnB1dF90by5oPgorCitzdHJpbmcgR1JPVVA7CitzdHJpbmcgd3JpdGVyOworc3RyaW5nIHVzZW1zZzsKKwordm9pZCBTZXRJblVzZU1lc3NhZ2Uoc3RyaW5nIHN0cikKK3sKKyAgdXNlbXNnPXN0cjsKK30KKworc3RyaW5nIFNldEdyb3VwKHN0cmluZyBzdHIpCit7CisgIHJldHVybiBHUk9VUD1zdHI7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIHRoaW5nOjpjcmVhdGUoKTsKKyAgd3JpdGVyPT0iIjsKKworfQorCit2b2lkIHRoaW5naW5pdCgpIC8qIElmIHNvbWVvbmUgZG9lc250IHdhbnQgb3VyIGFkZF9hY3Rpb24gaGUgbWF5IGNhbGwgdGhpcyAqLworeworICB0aGluZzo6aW5pdCgpOworfQorCit2YXJhcmdzIGludCByZW1vdmUoaW50IHNpbGVudCkKK3sKKyAgcmV0dXJuIHRoaW5nOjpyZW1vdmUoKTsKK30KKwordm9pZCBpbml0KCkKK3sKKyAgdGhpbmc6OmluaXQoKTsKKyAgYWRkX2FjdGlvbigic2NocmVpYiIsInNjaHJlaWIiLDEpOworICBhZGRfYWN0aW9uKCJsaWVzIiwibGllcyIpOworICBhZGRfYWN0aW9uKCJsb2VzY2hlIiwibG9lc2NoIiwxKTsKK30KKworc3RyaW5nIGxhZGooc3RyaW5nIHN0ciwgaW50IHdlaXRlKQoreworICByZXR1cm4oKHN0cisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKVswLi53ZWl0ZS0xXSk7Cit9CisKK3N0cmluZyBRdWVyeUxvbmcoKQoreworICBtaXhlZCAqbWVzc2FnZXM7CisgIHN0cmluZyBkZXNjOworICBpbnQgaTsKKworICBkZXNjPVF1ZXJ5UHJvcChQX0xPTkcpOworICBkZXNjKz0iXG4iOworICBtZXNzYWdlcz1ORVdTU0VSVkVSLT5HZXROb3RlcyhHUk9VUCk7CisgIGlmICghcG9pbnRlcnAobWVzc2FnZXMpIHx8ICFzaXplb2YobWVzc2FnZXMpKSAKKyAgICByZXR1cm4gZGVzYysiWnVyIFplaXQgYmVmaW5kZW4gc2ljaCBrZWluZSBOYWNocmljaHRlbiBhbSBCcmV0dC5cbiI7CisgIGlmIChzaXplb2YobWVzc2FnZXMpPT0xKQorICAgIGRlc2MrPSJadXIgWmVpdCBiZWZpbmRldCBzaWNoIGVpbmUgTmFjaHJpY2h0IGFtIEJyZXR0OlxuXG4iOworICBlbHNlCisgICAgZGVzYys9Ilp1ciBaZWl0IGJlZmluZGVuIHNpY2ggIitzaXplb2YobWVzc2FnZXMpKyIgTmFjaHJpY2h0ZW4gYW0gQnJldHQ6XG5cbiI7CisgIGZvciAoaT0wO2k8c2l6ZW9mKG1lc3NhZ2VzKTtpKyspCisgIHsKKyAgICBpZiAoaTw5KSBkZXNjKz0iICI7CisgICAgZGVzYys9IiIrKGkrMSkrIi4gIjsKKyAgICBkZXNjKz0obGFkaihtZXNzYWdlc1tpXVtNX1RJVExFXSw0NSkrIiAoIisKKwkgICBsYWRqKG1lc3NhZ2VzW2ldW01fV1JJVEVSXSsiLCIsMTMpKworCSAgIGR0aW1lKG1lc3NhZ2VzW2ldW01fVElNRV0pWzQuLjI0XSArICIpXG4iKTsKKyAgfQorICByZXR1cm4gZGVzYzsKK30KKwordmFyYXJncyBzdHJpbmcgbG9uZyhpbnQgbW9kZSkKK3sKKyAgcmV0dXJuIFF1ZXJ5TG9uZygpOworfQorCittaXhlZCAqbWVzc2FnZTsKKworaW50IHNjaHJlaWIoc3RyaW5nIHN0cikKK3sKKyAgaW50IGVycjsKKworICBpZiAoIXRoaXNfaW50ZXJhY3RpdmUoKSB8fCAhdGhpc19pbnRlcmFjdGl2ZSgpLT5xdWVyeV9yZWFsX25hbWUoKSkgcmV0dXJuIDA7CisgIGlmICh3cml0ZXIpCisgIHsKKyAgICB3cml0ZSgiRGFzIGdlaHQgaW0gTW9tZW50IG5pY2h0LCBkYSAiK2NhcGl0YWxpemUod3JpdGVyKSsiIGdlcmFkZSBhbiBkaWVzZW0gQnJldHQgc2NocmVpYnQuXG4iKTsKKyAgICBpZiAodXNlbXNnKSB3cml0ZSh1c2Vtc2crIlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgX25vdGlmeV9mYWlsKCJEdSBtdXNzdCBlaW5lbiBUaXRlbCBmdWVyIGRpZSBOb3RpeiBhbmdlYmVuICFcbiIpOworICBpZiAoIXN0cikgcmV0dXJuIDA7CisgIHN3aXRjaCAoZXJyPU5FV1NTRVJWRVItPkFza0FsbG93ZWRXcml0ZShHUk9VUCkpCisgIHsKKyAgICBjYXNlICAxOiBicmVhazsKKwkgICAgIGNhc2UgLTE6IHdyaXRlKCJEdSBkYXJmc3Qga2VpbmUgTm90ZXMgYW4gZGllc2VzIEJyZXR0IGhlZnRlbiAhXG4iKTsgcmV0dXJuIDE7CisJICAgICBjYXNlIC0zOiB3cml0ZSgiRGFzIEJyZXR0IGlzdCBsZWlkZXIgdm9sbCAhXG4iKTsgcmV0dXJuIDE7CisJICAgICBkZWZhdWx0OiB3cml0ZSgiSW50ZXJuZXIgRmVobGVyICIrZXJyKyIsIEVyem1hZ2llciB2ZXJzdGFlbmRpZ2VuICFcbiIpOyByZXR1cm4gMTsKKwkgICB9CisgIHdyaXRlcj10aGlzX2ludGVyYWN0aXZlKCktPnF1ZXJ5X3JlYWxfbmFtZSgpOworICBtZXNzYWdlPWFsbG9jYXRlKDYpOworICBtZXNzYWdlW01fQk9BUkRdPUdST1VQOworICBtZXNzYWdlW01fVElUTEVdPXN0cjsKKyAgbWVzc2FnZVtNX01FU1NBR0VdPSIiOworICB3cml0ZSgiT2ssIGJlZW5kZSBEZWluZSBOb3RpeiBtaXQgJyoqJyBvZGVyIGJyaWNoIHNpZSBtaXQgJ35xJyBhYiAhXG4iKTsKKyAgaWYgKElTX1dJWkFSRCh0aGlzX3BsYXllcigpKSkKKyAgICB3cml0ZSgiQWxzIE1hZ2llciIrKHRoaXNfcGxheWVyKCktPlF1ZXJ5UHJvcChQX0dFTkRFUik9PUZFTUFMRSA/ICJpbiIgOiAiIikrCisJICAiIGthbm5zdCBEdSBwZXIgJ35yPGZpbGVuYW1lPicgZWluIEZpbGUgaW4gZGllIE5vdGl6IGVpbmxlc2VuLlxuIik7CisgIGlucHV0X3RvKCJnZXRfbm90ZV9saW5lIiwgSU5QVVRfUFJPTVBULCAiOiIpOworICByZXR1cm4gMTsKK30KKworaW50IGdldF9ub3RlX2xpbmUoc3RyaW5nIHN0cikKK3sKKyAgaW50IGVycjsKKyAgaWYgKHN0cj09IioqIiB8fCBzdHI9PSJ+LiIpCisgIHsKKyAgICB3cml0ZXI9MDsKKyAgICBzd2l0Y2ggKGVycj0oTkVXU1NFUlZFUi0+V3JpdGVOb3RlKG1lc3NhZ2UpKSkKKyAgICB7CisgICAgICBjYXNlIDE6ICB3cml0ZSgiT2ssIE5hY2hyaWNodCBhdWZnZWhhZW5ndC5cbiIpOworCSAgICAgICBzYXkobWVzc2FnZVtNX1dSSVRFUl0rIiBoYXQgZWluZSBOYWNocmljaHQgYW5zIEJyZXR0IGdlaGFlbmd0LlxuIik7CisJICAgICAgIHJldHVybiAxOworCSAgICAgICBjYXNlIC0xOiB3cml0ZSgiRHUgZGFyZnN0IGxlaWRlciBrZWluZSBOYWNocmljaHRlbiBoaWVyIGF1ZmhhZW5nZW4uXG4iKTsKKwkgICAgICAgcmV0dXJuIDE7CisJICAgICAgIGNhc2UgLTM6IHdyaXRlKCJEYXMgQnJldHQgaXN0IGxlaWRlciB2b2xsICFcbiIpOworCSAgICAgICByZXR1cm4gMTsKKwkgICAgICAgZGVmYXVsdDogd3JpdGUoIkludGVybmVyIEZlaGxlciAiK2VycisiIGF1ZmdldHJldGVuICEgQml0dGUgRXJ6bWFnaWVyIHZlcnN0YWVuZGlnZW4uXG4iKTsKKwkgICAgICAgcmV0dXJuIDE7CisJICAgICB9CisgIH0KKyAgaWYgKHN0cj09In5xIikKKyAgeworICAgIHdyaXRlcj0wOworICAgIHdyaXRlKCJOb3RpeiBuaWNodCBhbmdlaGVmdGV0LlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKHN0clswLi4xXT09In5yIiAmJiBJU19XSVpBUkQodGhpc19wbGF5ZXIoKSkpIHsKKyAgICBzdHI9c3RyWzIuLjwxXTsKKyAgICBpZiAoc3RyWzBdPT0nICcpIHN0cj1zdHJbMS4uPDFdOworICAgIGlmICghc3RyIHx8IGNhdGNoKGVycj1maWxlX3NpemUoc3RyKTtwdWJsaXNoKSB8fCBlcnI8MCkgeworICAgICAgd3JpdGUoIkZpbGUgbmljaHQgZ2VmdW5kZW4uXG4iKTsKKyAgICAgIGlucHV0X3RvKCJnZXRfbm90ZV9saW5lIiwgSU5QVVRfUFJPTVBULCAiOiIpOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIHN0cj1yZWFkX2ZpbGUoc3RyKTsKKyAgICBpZiAoIXN0cil7CisgICAgICB3cml0ZSgiWnUgZ3Jvc3MhXG4iKTsKKyAgICAgIGlucHV0X3RvKCJnZXRfbm90ZV9saW5lIiwgSU5QVVRfUFJPTVBULCAiOiIpOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIHdyaXRlKCJPay5cbiIpOworICB9CisgIGlmIChtZXNzYWdlW01fTUVTU0FHRV0gJiYgbWVzc2FnZVtNX01FU1NBR0VdIT0iIikgbWVzc2FnZVtNX01FU1NBR0VdKz0iXG4iOworICBtZXNzYWdlW01fTUVTU0FHRV0rPXN0cjsKKyAgaW5wdXRfdG8oImdldF9ub3RlX2xpbmUiLCBJTlBVVF9QUk9NUFQsICI6Iik7CisgIHJldHVybiAxOworfQorCitpbnQgbGllcyhzdHJpbmcgc3RyKQoreworICBpbnQgbnVtOworICBtaXhlZCAqbWVzc2FnZXM7CisKKyAgaWYgKCFzdHIgfHwgc3RyPT0iIiB8fCBzc2NhbmYoc3RyLCIlZCIsbnVtKSE9MSB8fCBudW08PTApCisgIHsKKyAgICBfbm90aWZ5X2ZhaWwoIldFTENIRSBOYWNocmljaHQgd2lsbHN0IER1IGxlc2VuID9cbiIpOworICAgIHJldHVybiAwOworICB9CisgIG51bS0tOworICBtZXNzYWdlcz0oTkVXU1NFUlZFUi0+R2V0Tm90ZXMoR1JPVVApKTsKKyAgaWYgKHNpemVvZihtZXNzYWdlcyk8PW51bSkKKyAgeworICAgIF9ub3RpZnlfZmFpbCgiU28gdmllbGUgTmFjaHJpY2h0ZW4gc2luZCBkYSBuaWNodCAhXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICB0aGlzX3BsYXllcigpLT5Nb3JlKG1lc3NhZ2VzW251bV1bTV9USVRMRV0rIiAoIittZXNzYWdlc1tudW1dW01fV1JJVEVSXSsiLCAiKworICAgICAgZHRpbWUobWVzc2FnZXNbbnVtXVtNX1RJTUVdKVs1Li4yNl0gKyAiKTpcbiIgKyAKKyAgICAgICBtZXNzYWdlc1tudW1dW01fTUVTU0FHRV0pOworICByZXR1cm4gMTsKK30KKworaW50IGxvZXNjaGUoc3RyaW5nIHN0cikKK3sKKyAgaW50IG51bTsKKworICBpZiAoIXN0ciB8fCBzdHI9PSIiIHx8IHNzY2FuZihzdHIsIiVkIixudW0pIT0xIHx8IG51bTw9MCkKKyAgeworICAgIF9ub3RpZnlfZmFpbCgiV0VMQ0hFIE5hY2hyaWNodCB3aWxsc3QgRHUgbG9lc2NoZW4gP1xuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgbnVtLS07CisgIHN3aXRjaCAoTkVXU1NFUlZFUi0+UmVtb3ZlTm90ZShHUk9VUCwgbnVtKSl7CisgICAgY2FzZSAxOiB3cml0ZSgiT2suXG4iKTsKKwkgICAgc2F5KHRoaXNfcGxheWVyKCktPm5hbWUoKSsiIGVudGZlcm50IGVpbmUgTmFjaHJpY2h0IHZvbSBCcmV0dC5cbiIpOworCSAgICByZXR1cm4gMTsKKwkgICAgY2FzZSAtMTogd3JpdGUoIkRhcyBkYXJmc3QgRHUgbmljaHQuXG4iKTsKKwkgICAgc2F5KHRoaXNfcGxheWVyKCktPm5hbWUoKSsiIHZlcnN1Y2h0LCBlaW5lIE5hY2hyaWNodCB2b20gQnJldHQgenUgcmVpc3Nlbi5cbiIpOworCSAgICByZXR1cm4gMTsKKwkgICAgY2FzZSAtMzogd3JpdGUoIlNvIHZpZWxlIE5hY2hyaWNodGVuIHNpbmQgZGEgbmljaHQgIVxuIik7CisJICAgIHJldHVybiAxOworCSAgICBkZWZhdWx0OiB3cml0ZSgiSW50ZXJuZXIgRmVobGVyLiBCaXR0ZSBFcnptYWdpZXIgdmVyc3RhZW5kaWdlbiAhXG4iKTsKKwkgICAgcmV0dXJuIDE7CisJICB9CisgIHJldHVybiAwOworfQorCit2b2lkIENydW1ibGUoKQoreworICBpZiAoZW52aXJvbm1lbnQoKSAmJiBsaXZpbmcoZW52aXJvbm1lbnQoKSkpCisgICAgcmV0dXJuOworICBzYXkoY2FwaXRhbGl6ZShuYW1lKFdFUikpKyIgemVyZmFlbGx0IHp1IFN0YXViLCBkZXIgc2ljaCBzb2ZvcnQgdmVydGVpbHQuXG4iKTsKKyAgd3JpdGUoY2FwaXRhbGl6ZShuYW1lKFdFUikpKyIgemVyZmFlbGx0IHp1IFN0YXViLCBkZXIgc2ljaCBzb2ZvcnQgdmVydGVpbHQuXG4iKTsKKyAgcmVtb3ZlKCk7Cit9CisKK3ZhcmFyZ3MgaW50IG1vdmUob2JqZWN0IHRhcmdldCxtaXhlZCBtZXRob2QpCit7CisgIGlmIChvYmplY3RwKHRhcmdldCkmJiFsaXZpbmcodGFyZ2V0KSYmZW52aXJvbm1lbnQoKSYmbGl2aW5nKGVudmlyb25tZW50KCkpKQorICAgIGNhbGxfb3V0KCJDcnVtYmxlIiwzMCtyYW5kb20oMzApKTsKKyAgcmV0dXJuIDo6bW92ZSh0YXJnZXQsIG1ldGhvZCk7Cit9CmRpZmYgLS1naXQgYS9zdGQvbnBjLmMgYi9zdGQvbnBjLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjYxMmYxZQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9ucGMuYwpAQCAtMCwwICsxLDE3NSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIG5wYy5jIC0tIGEgZ2VuZXJpYyBucGMgKG5vbiBwbGF5ZXIgY2hhcmFjdGVyKQorLy8KKy8vIFRlc3R2ZXJzaW9uIG1pdCBzdXBwb3J0IGZ1ZXIgQWRkSXRlbQorLy8gc29sbCBzcGFldGVyIGluIG5wYy5jIGF1ZmdlaGVuCisvLworLy8gJElkOiBucGMuYyA5NDc4IDIwMTYtMDItMTkgMjE6MTg6MzVaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL3RoaW5nL3Byb3BlcnRpZXMiOworaW5oZXJpdCAiL3N0ZC9ob29rX3Byb3ZpZGVyIjsKK2luaGVyaXQgIi9zdGQvbGl2aW5nL2Rlc2NyaXB0aW9uIjsKK2luaGVyaXQgIi9zdGQvbGl2aW5nL2xpZ2h0IjsKK2luaGVyaXQgIi9zdGQvbGl2aW5nL2xpZmUiOworaW5oZXJpdCAiL3N0ZC9saXZpbmcvYXR0cmlidXRlcyI7Citpbmhlcml0ICIvc3RkL25wYy9tb3ZpbmciOworaW5oZXJpdCAiL3N0ZC9saXZpbmcvc2tpbGxfYXR0cmlidXRlcyI7Citpbmhlcml0ICIvc3RkL2xpdmluZy9za2lsbHMiOworaW5oZXJpdCAiL3N0ZC9saXZpbmcvY2xvdGhpbmciOworaW5oZXJpdCAiL3N0ZC9ucGMvY29tYmF0IjsKK2luaGVyaXQgIi9zdGQvbnBjL2NoYXQiOworaW5oZXJpdCAiL3N0ZC9ucGMvY29tbSI7Citpbmhlcml0ICIvc3RkL2NvbnRhaW5lci9yZXN0cmljdGlvbnMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9jb21tYW5kcyI7Citpbmhlcml0ICIvc3RkL3RoaW5nL2xhbmd1YWdlIjsKK2luaGVyaXQgIi9zdGQvbnBjL2luZm8iOworaW5oZXJpdCAiL3N0ZC9ucGMvcHV0X2FuZF9nZXQiOworaW5oZXJpdCAiL3N0ZC9ucGMvaXRlbXMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9lbnZjaGsiOworaW5oZXJpdCAiL3N0ZC9saXZpbmcvaGVscGVycyI7CisKKyNpbmNsdWRlIDxjb25maWcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8YW5zaS5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGxpdmluZy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8YXR0cmlidXRlcy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxoZWFsdGguaD4KKyNpbmNsdWRlIDxucGMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxndWFyZC5oPgorCitzdGF0aWMgaW50IF9zZXRfbGV2ZWwoaW50IGFyZyk7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7IAorICBzZXRldWlkKGdldHVpZCgpKTsKKyAgcHJvcGVydGllczo6Y3JlYXRlKCk7CisgIHJlc3RyaWN0aW9uczo6Y3JlYXRlKCk7CisgIGNvbW1hbmRzOjpjcmVhdGUoKTsKKyAgbGlnaHQ6OmNyZWF0ZSgpOworICBkZXNjcmlwdGlvbjo6Y3JlYXRlKCk7CisgIGF0dHJpYnV0ZXM6OmNyZWF0ZSgpOworICBjbG90aGluZzo6Y3JlYXRlKCk7CisgIGxpZmU6OmNyZWF0ZSgpOworICBlbmFibGVfY29tbWFuZHMoKTsKKyAgY29tbTo6Y3JlYXRlKCk7CisgIGNvbWJhdDo6Y3JlYXRlKCk7CisgIGluZm86OmNyZWF0ZSgpOworICBwdXRfYW5kX2dldDo6YWRkX3B1dF9hbmRfZ2V0X2NvbW1hbmRzKCk7CisgIGFkZF90ZWFtX2NvbW1hbmRzKCk7CisgIGl0ZW1zOjpjcmVhdGUoKTsKKyAgZW52Y2hrOjpjcmVhdGUoKTsKKyAgbW92aW5nOjpjcmVhdGUoKTsKKworICBhZGRfYWN0aW9uKCJVc2VTcGVsbCIsIiIsMSk7CisKKyAgU2V0UHJvcChQX0xJR0hUX01PRElGSUVSLCAxKTsKKyAgU2V0UHJvcChQX1dFSUdIVF9QRVJDRU5ULCAxMDApOworICBTZXRQcm9wKFBfTkFNRSwgIk5pZW1hbmQiKTsKKyAgU2V0UHJvcChQX01TR0lOLCAia29tbXQgYW4iKTsKKyAgU2V0UHJvcChQX01TR09VVCwgImdlaHQiKTsKKyAgU2V0UHJvcChQX01NU0dJTiwgImVyc2NoZWludCBpbiBlaW5lciBSYXVjaHdvbGtlIik7CisgIFNldFByb3AoUF9NTVNHT1VULCAidmVyc2Nod2luZGV0IG1pdCBLbmFsbCB1bmQgU2Nod2VmZWxkdWZ0Iik7CisgIFNldFByb3AoUF9HRU5ERVIsIE5FVVRFUiApOworICBTZXRQcm9wKFBfV0VJR0hULCA3NTAwMCk7CisgIFNldFByb3AoUF9NQVhfV0VJR0hULCA1MDAwMCk7CisgIFNldFByb3AoUF9SQUNFLCAiTnBjIik7CisgIFNldFByb3AoUF9NQVhfSFAsMTAwKTsKKyAgU2V0UHJvcChQX01BWF9TUCwxMDApOworICBTZXRQcm9wKFBfSFAsNTApOworICBTZXRQcm9wKFBfU1AsNTApOworICBTZXRQcm9wKFBfTUFYX0FMQ09IT0wsMTAwKTsKKyAgU2V0UHJvcChQX01BWF9EUklOSywxMDApOworICBTZXRQcm9wKFBfTUFYX0ZPT0QsMTAwKTsKKyAgU2V0UHJvcChQX0RSSU5LLCAwKTsKKyAgU2V0UHJvcChQX0ZPT0QsIDApOworICBTZXRQcm9wKFBfQUxDT0hPTCwgMCk7CisgIFNldFByb3AoUF9IQU5EUywgKHsgIiIsIDMwIH0pICk7CisgIFNldFByb3AoUF9NQVhfSEFORFMsIDIpOworICBTZXRQcm9wKFBfTlBDLCAxKTsKKyAgU2V0UHJvcChQX0dVQVJELDEwMCk7CisgIFNldFByb3AoUF9OT19UUE9SVCxOT19UUE9SVF9JTik7CisKKyAgc2V0X2hlYXJ0X2JlYXQoMSk7CisgIGhlYXJ0YmVhdD0xOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKwordm9pZCByZXNldCgpeworICBpdGVtczo6cmVzZXQoKTsKKyAgY29tYmF0OjpyZXNldCgpOworfQorCitzdGF0aWMgaW50IF9zZXRfbGV2ZWwoaW50IGFyZykKK3sKKyAgU2V0KFBfTEVWRUwsIGFyZyk7CisgIFNldEF0dHIoQV9DT04sIGFyZyk7CisgIFNldEF0dHIoQV9ERVgsIGFyZyk7CisgIFNldEF0dHIoQV9JTlQsIGFyZyk7CisgIFNldEF0dHIoQV9TVFIsIGFyZyk7CisgIHJldHVybihhcmcpOyAvL1J1ZWNrZ2FiZXdlcnQgbm9ldGlnIQorfQorCit2YXJhcmdzIHZvaWQgY3JlYXRlX2RlZmF1bHRfbnBjKGludCBsZXZlbCwgaW50IG1heGhwKQoreyAKKyAgaWYobGV2ZWwgPCAxKSByZXR1cm47CisgIFNldFByb3AoUF9MRVZFTCwgbGV2ZWwpOworICBpZiAobWF4aHA8PTApIG1heGhwID0gNDIgKyBsZXZlbCo4OworICBTZXRQcm9wKFBfTUFYX0hQLCBtYXhocCk7CisgIFNldFByb3AoUF9NQVhfU1AsIG1heGhwKTsKKyAgU2V0UHJvcChQX0hBTkRTLCAoeyIgbWl0IGJsb3NzZW4gSGFlbmRlbiIsIGxldmVsKjEwIH0pICk7CisgIFNldFByb3AoUF9CT0RZLCAobGV2ZWwqMjApLzMpOworICBTZXRQcm9wKFBfWFAsIGxldmVsICogbWF4aHAgKiA1MCk7Cit9IAorCitwcm90ZWN0ZWQgdm9pZCBoZWFydF9iZWF0KCkKK3sKKyAgaWYoIGVudmlyb25tZW50KCkgKSBsaWZlOjpoZWFydF9iZWF0KCk7CisgIGlmICghdGhpc19vYmplY3QoKSkgcmV0dXJuOyAvLyBFdnRsLiBhbiBHaWZ0IGdlc3RvcmJlbi4uLgorICBjb21iYXQ6OmhlYXJ0X2JlYXQoKTsKKyAgY2hhdDo6aGVhcnRfYmVhdCgpOworfQorCit2b2lkIGdpdmVfbm90aWZ5KG9iamVjdCBvYikKK3sKKyAgcHV0X2FuZF9nZXQ6OmdpdmVfbm90aWZ5KG9iKTsKK30KKworLy8gRm9yY2UgdGhlIG1vbnN0ZXIgdG8gZG8gYSBjb21tYW5kLgoraW50IGNvbW1hbmRfbWUoc3RyaW5nIGNtZCkgeyByZXR1cm4gY29tbWFuZChjbWQpOyB9CisKK3ZvaWQgaW5pdCgpCit7CisgIGNvbWJhdDo6aW5pdCgpOworICBpbmZvOjppbml0KCk7CisgIGNvbW1hbmRzOjppbml0KCk7CisvLyAgZGVzY3JpcHRpb246OmluaXQoKTsKK30KKworLy8gaXRlbXMgaW5pdGlhbGlzaWVyZW4/Citwcm90ZWN0ZWQgdm9pZCBOb3RpZnlNb3ZlKG9iamVjdCBkZXN0LCBvYmplY3Qgb2xkZW52LCBpbnQgbWV0aG9kKSB7CisgICAgCisgIDo6Tm90aWZ5TW92ZShkZXN0LCBvbGRlbnYsIG1ldGhvZCk7CisgIC8vIGdlc3RvcmJlbj8KKyAgaWYgKCFvYmplY3RwKHRoaXNfb2JqZWN0KCkpKSByZXR1cm47CisKKyAgaWYgKCBRdWVyeShOUENfTkVFRFNfSVRFTV9JTklULCBGX1ZBTFVFKSkKKyAgICAgIF9jbG9uZV9pdGVtcygpOworfQorCitzdHJpbmcgX3F1ZXJ5X3JhY2UoKQoreworICAgaWYgKHN0cmluZ3AoUXVlcnkoUF9SQUNFKSkpIHJldHVybiBjYXBpdGFsaXplKFF1ZXJ5KFBfUkFDRSkpOworfQpkaWZmIC0tZ2l0IGEvc3RkL25wYy9jaGF0LmMgYi9zdGQvbnBjL2NoYXQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43ZjRmODliCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL25wYy9jaGF0LmMKQEAgLTAsMCArMSw2NiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIG5wYy9jaGF0LmMgLS0gTGFiZXJuZGUgTlBDcworLy8KKy8vICRJZDogY2hhdC5jIDY4MDEgMjAwOC0wMy0yMSAyMzozNDo0NlogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPGxpdmluZy9jb21iYXQuaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNkZWZpbmUgTUUgdGhpc19vYmplY3QoKQorCisvKgorICogU29tZSBzaW1wbGUgY2hhdCB2YXJpYWJsZXMKKyAqLworCisvKgorICogaGVhcnRfYmVhdCBpcyBjYWxsZWQgc28gdGhlIG1vbnN0ZXIgbWF5IGNoYXQuCisgKi8KK3ZvaWQgU2V0Q2hhdHMoaW50IGNoYW5jZSwgbWl4ZWQgc3RycykgeworICBpZiAoIXBvaW50ZXJwKHN0cnMpKQorICAgIHJldHVybjsKKyAgU2V0UHJvcChQX0NIQVRfQ0hBTkNFLGNoYW5jZSk7CisgIFNldFByb3AoUF9DSEFUUyxzdHJzKTsKK30KKwordm9pZCBTZXRBdHRhY2tDaGF0cyhpbnQgY2hhbmNlLCBtaXhlZCBzdHJzKSB7CisgIGlmICghcG9pbnRlcnAoc3RycykpCisgICAgcmV0dXJuOworICBTZXRQcm9wKFBfQUNIQVRfQ0hBTkNFLGNoYW5jZSk7CisgIFNldFByb3AoUF9BQ0hBVFMsc3Rycyk7Cit9CisKK3ZvaWQgRG9BdHRhY2tDaGF0KCkgeworICBzdHJpbmcqIGM7CisgIGlmICghTUUgfHwgIWVudmlyb25tZW50KE1FKSkKKyAgICByZXR1cm47CisgIGlmIChRdWVyeVByb3AoUF9ESVNBQkxFX0FUVEFDSyk+MClyZXR1cm4gOworICBpZiAocmFuZG9tKDEwMCkgPCBRdWVyeVByb3AoUF9BQ0hBVF9DSEFOQ0UpKQorICAgIGlmICgoYyA9IFF1ZXJ5UHJvcChQX0FDSEFUUykpICYmIHNpemVvZihjKSkgCisgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoTUUpLAorCQlwcm9jZXNzX3N0cmluZyhjW3JhbmRvbShzaXplb2YoYykpXSkpOworfQorCit2b2lkIERvQ2hhdCgpIHsKKyAgc3RyaW5nICpjOworICBpZiAoIU1FIHx8ICFlbnZpcm9ubWVudChNRSkpCisgICAgcmV0dXJuOworICBpZiAocmFuZG9tKDEwMCkgPCBRdWVyeVByb3AoUF9DSEFUX0NIQU5DRSkpCisgICAgaWYgKChjID0gUXVlcnlQcm9wKFBfQ0hBVFMpKSAmJiBzaXplb2YoYykpIAorICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KE1FKSwKKwkJcHJvY2Vzc19zdHJpbmcoY1tyYW5kb20oc2l6ZW9mKGMpKV0pKTsKK30KKworcHJvdGVjdGVkIHZvaWQgaGVhcnRfYmVhdCgpCit7CisgIGlmKCBJbkZpZ2h0KCkgKSBEb0F0dGFja0NoYXQoKTsKKyAgZWxzZSAgICAgICAgICAgIERvQ2hhdCgpOworfQpkaWZmIC0tZ2l0IGEvc3RkL25wYy9jb21iYXQuYyBiL3N0ZC9ucGMvY29tYmF0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzQ3NzE0YgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9ucGMvY29tYmF0LmMKQEAgLTAsMCArMSw0MDcgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBucGMvY29tYmF0LmMgLS0gTlBDLXNwZXppZmlzY2hlIEthbXBmZnVua3Rpb25lbgorLy8KKy8vICRJZDogY29tYmF0LmMgOTQ4OCAyMDE2LTAyLTE5IDIxOjI0OjA0WiBBcmF0aG9ybiAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK2luaGVyaXQgInN0ZC9saXZpbmcvY29tYmF0IjsKKworI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGhlYWx0aC5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMgMQorI2luY2x1ZGUgPGxpdmluZy9saWZlLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNkZWZpbmUgSEJfQ0hFQ0sgNworI2RlZmluZSBNRSB0aGlzX29iamVjdCgpCisjZGVmaW5lIFNUQVRNQVNURVIgIi9wL3NlcnZpY2Uvcm9jaHVzL2d1aWxkc3RhdC9tYXN0ZXIiCisKK25vc2F2ZSBpbnQgaGVhcnRiZWF0LCBiZWF0Y291bnQ7CisKK3ByaXZhdGUgdm9pZCBjYXRjaF91cF9oYnMoKTsKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkgeworICA6OmNyZWF0ZSgpOworICBiZWF0Y291bnQ9MTsKKyAgaGVhcnRiZWF0PTE7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCisvLyBha3R1ZWxsZXMgTGViZXdlc2VuLCBmdWVyIGRhcyBkaWVzZXIgTlBDIGdlcmFkZSB0YWV0aWcgaXN0LiBEZWZhdWx0OgorLy8gU3BpZWxlciwgYmVpIGRlbSBlciBhbHMgSGVsZmVyLU5QQyByZWdpc3RyaWVydCBpc3QuCitwdWJsaWMgb2JqZWN0IFF1ZXJ5VXNlcigpCit7CisgIG1peGVkIGhlbHBlcmRhdGEgPSBRdWVyeVByb3AoUF9IRUxQRVJfTlBDKTsKKyAgaWYgKHBvaW50ZXJwKGhlbHBlcmRhdGEpICYmIG9iamVjdHAoaGVscGVyZGF0YVswXSkpCisgICAgcmV0dXJuIGhlbHBlcmRhdGFbMF07CisgIHJldHVybiAwOworfQorCisvLyBnZ2YuIEZlaW5kZSBleHBpcmVuLiBTb2xsIGRhcyBQcm9ibGVtIHZlcnJpbmdlcm4sIGRhc3MgU3BpZWxlciBuYWNoIFRhZ2VuCisvLyBlcnN0IGRpZSBNZWxkdW5nIGtyaWVnZW4sIGRhc3MgZGVyIE5QQyBzaWUgbmljaHQgbWVociBqYWd0LCB3ZW5uIGRlciBIQgorLy8gcmVha3RpdmVydCB3aXJkLgordm9pZCByZXNldCgpIHsKKyAgLy8gZ2dmLiBkaWUgYWJnZXNjaGFsdGV0ZW4gSEJzIG5hY2hob2xlbi4KKyAgaWYgKCFoZWFydGJlYXQpCisgICAgY2F0Y2hfdXBfaGJzKCk7CisgIC8vIGdnZi4gUF9FTkVNWV9EQU1BR0UgenVydWVja3NldHplbgorICBSZXNldEVuZW15RGFtYWdlKCk7Cit9CisKK3N0YXRpYyB2b2lkIF9zZXRfbWF4X2hwKGludCBpKSB7CisgIFNldChQX01BWF9IUCxpKTsKKyAgU2V0UHJvcChQX0hQLGkpOworfQorCitzdGF0aWMgdm9pZCBfc2V0X21heF9zcChpbnQgaSkgeworICBTZXQoUF9NQVhfU1AsaSk7CisgIFNldFByb3AoUF9TUCxpKTsKK30KKworCisvLyBDaGVjay1GdW5rdGlvbiBmdWVyIGRpZSBQX05PX0FUVEFDSy1RdWVyeU1ldGhvZAorc3RhdGljIG1peGVkIF9jaGVja19pbW1vcnRhbGl0eSgpCit7CisgICAgaW50IHQ7CisKKyAgICBpZiAoICEodCA9IFF1ZXJ5KCJ0aW1lX3RvX21vcnRhbGl0eSIpKSB8fCB0aW1lKCkgPiB0ICl7CisgICAgICAgIC8vIFplaXQgaXN0IGFiZ2VsYXVmZW4gLSB3aWVkZXIgYW5ncmVpZmJhciBtYWNoZW4KKyAgICAgICAgU2V0KCBQX05PX0FUVEFDSywgMCwgRl9RVUVSWV9NRVRIT0QgKTsKKyAgICAgICAgaGVhcnRiZWF0ID0gMTsKKyAgICAgICAgYmVhdGNvdW50ID0gMTsKKyAgICAgICAgc2V0X2hlYXJ0X2JlYXQoMSk7CisKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLy8gZGVyIE5QQyBpc3Qgbm9jaCB1bmFuZ3JlaWZiYXIKKyAgICByZXR1cm4gYnJlYWtfc3RyaW5nKCBjYXBpdGFsaXplKG5hbWUoIFdFUiwgMSApKSArICIgdmVyc3RlY2t0IHNpY2ggaGludGVyICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiZWluZW0gRmVobGVyIGltIFJhdW0tWmVpdC1HZWZ1ZWdlIHVuZCBlbnRnZWh0IHNvICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAidm9ydWViZXJnZWhlbmQgYWxsZW4gQW5ncmlmZmVuLiIsIDc4ICk7Cit9CisKKworLy8gd2VubiBkZXIgSGVhcnRCZWF0IGJ1Z2d0LCB3aXJkIGRpZXNlIEZ1bmt0aW9uIHZvbSBNYXN0ZXIgYXVmZ2VydWZlbgorcHVibGljIHZvaWQgbWFrZV9pbW1vcnRhbCgpCit7CisgICAgLy8gZnVlciA1IE1pbnV0ZW4gdW5hbmdyZWlmYmFyIG1hY2hlbgorICAgIFNldCggUF9OT19BVFRBQ0ssICMnX2NoZWNrX2ltbW9ydGFsaXR5LCBGX1FVRVJZX01FVEhPRCApOworCisgICAgU2V0KCAidGltZV90b19tb3J0YWxpdHkiLCB0aW1lKCkgKyAzMDAsIEZfVkFMVUUgKTsKKworICAgIC8vIGRhbWl0IGRpZSBTcGllbGVyIGtlaW5lbiBWb3J0ZWlsIGR1cmNoIGRlbiBCdWcgaGFiZW4sIGhlaWxlbgorICAgIGhlYWxfc2VsZigxMDAwMCk7CisKKyAgICAvLyBkYSBudW4gZGVyIEhlYXJ0YmVhdCBhYmdlc2NoYWx0ZXQgaXN0IHVuZCBub3JtYWxlcndlaXNlIGVyc3QKKyAgICAvLyByZWFrdGl2aWVydCB3aXJkLCBzb2JhbGQgamVtYW5kIG5hY2ggNW1pbiBQX05PX0FUVEFDSyBhYmZyYWd0LCBtdXNzIG1hbgorICAgIC8vIGFiZXIgYXVmIFZpZWNoZXIgYWNodGVuLCBkaWUgaW1tZXIgbmVuIEhlYXJ0YmVhdCBoYWJlbiB3b2xsZW4uIEluIGRlbQorICAgIC8vIGZhbGwgcGVyIGNhbGxfb3V0IHNlbGJlciBkaWUgUHJvcCBhYmZyYWdlbi4KKyAgICBpZiAoUXVlcnlQcm9wKFBfSEIpKQorICAgICAgY2FsbF9vdXQoIydRdWVyeVByb3AsIDMwMSwgUF9OT19BVFRBQ0spOworfQorCisKKy8vIERhbWl0IE5QQ3MgZ2VnZW5laW5hbmRlciB3ZWl0ZXJrYWVtcGZlbiwgYXVjaCB3ZW5uIGtlaW4gU3BpZWxlcgorLy8gaW4gZGVyIE5hZWhlIGlzdDoKK3N0YXRpYyBpbnQgX3F1ZXJ5X2hiKCkKK3sKKyAgICAvLyBUT0RPOiByZXR1cm4gSW5GaWdodCgpIHx8IFF1ZXJ5KFBfSEIsIEZfVkFMVUUpLCBzb2JhbGQgSW5GaWdodCgpCisgICAgLy8gZ2VhZW5kZXJ0LgorICAgIHJldHVybiAoSW5GaWdodCgpIHx8IFF1ZXJ5KFBfSEIsRl9WQUxVRSkpID8gMSA6IDA7Cit9CisKKworI2RlZmluZSBTUEVMTF9UT1RBTFJBVEUgMAorI2RlZmluZSBTUEVMTF9EQU1BR0UgMQorI2RlZmluZSBTUEVMTF9URVhUX0ZPUl9FTkVNWSAyCisjZGVmaW5lIFNQRUxMX1RFWFRfRk9SX09USEVSUyAzCisjZGVmaW5lIFNQRUxMX0RBTVRZUEUgNAorI2RlZmluZSBTUEVMTF9GVU5DIDUKKyNkZWZpbmUgU1BFTExfQVJHIDYKKwordmFyYXJncyBpbnQgQWRkU3BlbGwoaW50IHJhdGUsIGludCBkYW1hZ2UsIHN0cmluZyBUZXh0Rm9yRW5lbXksCisgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgVGV4dEZvck90aGVycywgc3RyaW5nfHN0cmluZyogZGFtX3R5cGUsIHN0cmluZyBmdW5jLAorICAgICAgICAgICAgICAgICAgICAgaW50fG1hcHBpbmcgc3BlbGxhcmcpIHsKKyAgbWl4ZWQgKnNwZWxsczsKKyAgaW50IHRvdGFsX3JhdGVzOworCisgIGlmIChyYXRlPDAgfHwgZGFtYWdlPD0wIHx8ICFzdHJpbmdwKFRleHRGb3JFbmVteSkgfHwKKyAgICAgICFzdHJpbmdwKFRleHRGb3JPdGhlcnMpKQorICAgICByZXR1cm4gMDsKKworICBpZiAoc3RyaW5ncChkYW1fdHlwZSkpCisgICAgIGRhbV90eXBlID0gKHtkYW1fdHlwZX0pOworICBlbHNlIGlmICghcG9pbnRlcnAoZGFtX3R5cGUpKQorICAgICAgZGFtX3R5cGUgPSAoe0RUX01BR0lDfSk7CisgIAorICAvLyBUYXRzYWVjaGxpY2ggaXN0IGVzIGltbWVyIGVpbiBuaWNodC1waHlzaXNjaGVyIEFuZ3JpZmYsIHdlbm4gc3BlbGxhcmcgZWluCisgIC8vIGludCBpc3QsIHdlaWwgd2VubiBzcGVsbGFyZz09MCBpc3QgZGVyIERlZmF1bHQgbmljaHQtcGh5c2lzY2hlciBBbmdyaWZmCisgIC8vIHVuZCBiZWkgc3BlbGxhcmchPTAgYXVjaC4gTnVyIG1pdCBlaW5lbSBtYXBwaW5nIGthbm4gbWFuIGVpbmVuIHBoeXMuCisgIC8vIEFuZ3JpZmYgZXJ6ZXVnZW4uCisgIGlmIChpbnRwKHNwZWxsYXJnKSkKKyAgICBzcGVsbGFyZyA9IChbU1BfUEhZU0lDQUxfQVRUQUNLOiAwXSk7CisKKyAgLy8gRmFsbHMgdm9yaGFuZGVuLCBhbHRlIFN5bnRheCBhdWYgZGllIHZvbiByZXBsYWNlX3BlcnNvbmFsKCkgYW5wYXNzZW4sCisgIC8vIGRpZSBpbSBoZWFydF9iZWF0KCkgYmVpbSBBdXNnZWJlbiBkZXIgTWVsZHVuZyB2ZXJ3ZW5kZXQgd2lyZC4KKyAgaWYgKCBzdHJzdHIoVGV4dEZvck90aGVycywgIkAiLCAwKSAhPSAtMSApCisgIHsKKyAgICAvLyBaZWljaGVuIG5hY2ggQFdFUiAmIENvIGluIHJ1bmRlIEtsYW1tZXJuIGVpbnNjaGxpZXNzZW4sIGRhbWl0IGVzIGFscworICAgIC8vIFN1Yi1QYXR0ZXJuIGltIEF1c2dhYmVzdHJpbmcgd2llZGVyaG9sdCB3ZXJkZW4ga2Fubi4gQW5zb25zdGVuIHd1ZXJkZQorICAgIC8vIGVzIG1pdCBlcnNldHp0LgorICAgIFRleHRGb3JPdGhlcnMgPSByZWdyZXBsYWNlKFRleHRGb3JPdGhlcnMsICJAV0VSKFteMS05XSkiLCAiQFdFUjFcXDEiLCAxKTsKKyAgICBUZXh0Rm9yT3RoZXJzID0gcmVncmVwbGFjZShUZXh0Rm9yT3RoZXJzLCAiQFdFU1NFTihbXjEtOV0pIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQFdFU1NFTjFcXDEiLCAxKTsKKyAgICBUZXh0Rm9yT3RoZXJzID0gcmVncmVwbGFjZShUZXh0Rm9yT3RoZXJzLCAiQFdFTShbXjEtOV0pIiwgIkBXRU0xXFwxIiwgMSk7CisgICAgVGV4dEZvck90aGVycyA9IHJlZ3JlcGxhY2UoVGV4dEZvck90aGVycywgIkBXRU4oW14xLTldKSIsICJAV0VOMVxcMSIsIDEpOworICB9CisgIHRvdGFsX3JhdGVzPVF1ZXJ5KCJucGM6dG90YWxfcmF0ZXMiKStyYXRlOworICBzcGVsbHM9UXVlcnkoUF9TUEVMTFMpOworICBpZiAoIXBvaW50ZXJwKHNwZWxscykpCisgICAgc3BlbGxzPSh7fSk7CisgIHNwZWxscys9KHsoe3RvdGFsX3JhdGVzLCBkYW1hZ2UsIFRleHRGb3JFbmVteSwgVGV4dEZvck90aGVycywKKyAgICAgICAgICAgICAgZGFtX3R5cGUsIGZ1bmMsIHNwZWxsYXJnfSl9KTsKKyAgU2V0KFBfU1BFTExTLHNwZWxscyk7CisgIFNldCgibnBjOnRvdGFsX3JhdGVzIix0b3RhbF9yYXRlcyk7CisgIHJldHVybiAxOworfQorCitpbnQgQXV0b0F0dGFjayhvYmplY3Qgb2IpIHsKKyAgbWl4ZWQgbTsKKworICBpZiAoIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob2IpKQorICAgIHJldHVybiAwOworICBpZiAobWFwcGluZ3AobT1RdWVyeVByb3AoUF9BR0dSRVNTSVZFKSkpIHsKKyAgICBtaXhlZCAqaW5kLHgsejsKKyAgICBmbG9hdCBmOworICAgIGludCBpLG47CisKKyAgICBpbmQ9bV9pbmRpY2VzKG0pLSh7MH0pO249MDtmPTAuMDsKKyAgICBmb3IgKGk9c2l6ZW9mKGluZCktMTtpPj0wO2ktLSkgeworICAgICAgeD1pbmRbaV07CisgICAgICBpZiAoKHo9bVt4XVtvYi0+UXVlcnlQcm9wKHgpXSkgfHwgKHo9bVt4XVswXSkpIHsKKyAgZj1mKyhmbG9hdCl6OworICBuKys7CisgICAgICB9CisgICAgfQorICAgIGlmIChuKQorICAgICAgbT1mLygoZmxvYXQpbik7CisgICAgZWxzZQorICAgICAgbT1tWzBdOworICB9CisgIGlmICgoKGludCkoMTAwKihtK29iLT5RdWVyeVByb3AoUF9BR0dSRVNTSVZFKSkpKTw9cmFuZG9tKDEwMCkpCisgICAgcmV0dXJuIDA7CisgIGlmICAoSVNfTEVBUk5FUihvYikKKyAgICAgICAmJiAob2ItPlF1ZXJ5UHJvcChQX0lOVklTKQorICAgICB8fCBvYi0+UXVlcnlQcm9wKFBfV0FOVFNfVE9fTEVBUk4pKSkKKyAgICByZXR1cm4gMDsKKyAgcmV0dXJuIDE7Cit9CisKK3ZvaWQgU3BlbGxBdHRhY2sob2JqZWN0IGVuZW15KSB7Cit9CisKKyNpZiAwCitUSihzdHJpbmcgcykgeworICBvYmplY3QgbzsKKyAgaWYgKG89ZmluZF9wbGF5ZXIoImpvZiIpKQorICAgIHRlbGxfb2JqZWN0KG8sc3ByaW50ZigiJU86ICVzXG4iLHRoaXNfb2JqZWN0KCkscykpOworfQorI2Vsc2UKKyNkZWZpbmUgVEooeCkKKyNlbmRpZgorCitwcm90ZWN0ZWQgdm9pZCBoZWFydF9iZWF0KCkgeworICBpbnQgcixpOworICBtaXhlZCBlbnYsKnNwZWxscywgc2luZm87CisgIG9iamVjdCBlbmVteTsKKworICBpZiAoIC0tYmVhdGNvdW50IDwgMCApCisgICAgICBiZWF0Y291bnQgPSAwOworICAKKyAgaWYgKCFiZWF0Y291bnQgJiYgIVF1ZXJ5KFBfSEIpKSB7CisgICAgaWYgKCFlbnZpcm9ubWVudCgpKSB7CisgICAgICBzZXRfaGVhcnRfYmVhdCgwKTsKKyAgICAgIGhlYXJ0YmVhdCA9IDA7CisgICAgICBpZiggY2xvbmVwKHRoaXNfb2JqZWN0KCkpICkgcmVtb3ZlKCk7CisgICAgICByZXR1cm47CisgICAgfQorICAgIGlmICghUXVlcnlQcm9wKFBfUE9JU09OKSkgeworICAgICAgLy8gU3BpZWxlciBhbndlc2VuZD8KKyAgICAgIGVudiA9IGZpbHRlcihhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpLCAjJ3F1ZXJ5X29uY2VfaW50ZXJhY3RpdmUpOworICAgICAgaWYgKCFzaXplb2YoZW52KSkgeworCS8vIE5laW4sIEhCcyBhYnNjaGFsdGVuLgorCXNldF9oZWFydF9iZWF0KDApOworCWhlYXJ0YmVhdD0wOworCVRKKCJPRkZcbiIpOworCWJlYXRjb3VudD1IQl9DSEVDSzsKKwlTZXQoIm5wYzpiZWF0X29mZl9udW0iLGFic29sdXRlX2hiX2NvdW50KCkpOworCXJldHVybjsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgOjpoZWFydF9iZWF0KCk7CisgIGlmICghTUUpCisgICAgICByZXR1cm47CisgIGVuZW15PVNlbGVjdEVuZW15KCk7CisgIGlmIChRdWVyeVByb3AoUF9BR0dSRVNTSVZFKQorICAgICAgJiYgKCFlbmVteSB8fCBlbnZpcm9ubWVudCgpIT1lbnZpcm9ubWVudChlbmVteSkpCisgICAgICAmJiAhYmVhdGNvdW50KSB7CisgICAgYmVhdGNvdW50PUhCX0NIRUNLOworICAgIGVudj1maWx0ZXIoYWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSwjJ0F1dG9BdHRhY2spOworICAgIGlmICghc2l6ZW9mKGVudikpCisgICAgICAgcmV0dXJuOworICAgIGk9cmFuZG9tKHNpemVvZihlbnYpKTsKKyAgICBLaWxsKGVudltpXSk7CisgIH0KKyAgZWxzZSBpZiAoIWJlYXRjb3VudCkKKyAgICBiZWF0Y291bnQ9SEJfQ0hFQ0s7CisgIGlmICghb2JqZWN0cChlbmVteSkgfHxRdWVyeVByb3AoUF9ESVNBQkxFX0FUVEFDSyk+MCkKKyAgICByZXR1cm47CisgIFNwZWxsQXR0YWNrKGVuZW15KTsKKworICBpZiAoIXBvaW50ZXJwKHNwZWxscz1RdWVyeShQX1NQRUxMUykpCisgICAgICB8fCAhc2l6ZW9mKHNwZWxscykKKyAgICAgIHx8ICFvYmplY3RwKGVuZW15PVNlbGVjdEVuZW15KCkpCisgICAgICB8fCBlbnZpcm9ubWVudChlbmVteSkhPWVudmlyb25tZW50KCkKKyAgICAgIHx8IChRdWVyeVByb3AoUF9ESVNBQkxFX0FUVEFDSyk+MCkKKyAgICAgIHx8IHJhbmRvbSgxMDApPlF1ZXJ5KFBfU1BFTExSQVRFKSkKKyAgICByZXR1cm47CisgIHI9cmFuZG9tKFF1ZXJ5KCJucGM6dG90YWxfcmF0ZXMiKSk7CisgIGZvciAoaT1zaXplb2Yoc3BlbGxzKS0xOyhpPjAgJiYgc3BlbGxzW2ktMV1bU1BFTExfVE9UQUxSQVRFXT5yKTtpLS0pCisgICAgOworICBzdHJpbmcgYWt0X3NwZWxsX21lc3MgPSBzcGVsbHNbaV1bU1BFTExfVEVYVF9GT1JfRU5FTVldOworICBpZiAoIHNpemVvZihha3Rfc3BlbGxfbWVzcykgKQorICAgIHRlbGxfb2JqZWN0KGVuZW15LCBicmVha19zdHJpbmcoYWt0X3NwZWxsX21lc3MsIDc4KSk7CisgIGFrdF9zcGVsbF9tZXNzID0gc3BlbGxzW2ldW1NQRUxMX1RFWFRfRk9SX09USEVSU107CisgIC8vIE51ciwgd2VubiB1ZWJlcmhhdXB0IGVpbmUgTWVsZHVuZyBnZXNldHp0IHd1cmRlLCBtdXNzIGRpZXNlIHZlcmFyYmVpdGV0CisgIC8vIHdlcmRlbi4KKyAgaWYgKHN0cmluZ3AoYWt0X3NwZWxsX21lc3MpICYmIHNpemVvZihha3Rfc3BlbGxfbWVzcykpCisgIHsKKyAgICBha3Rfc3BlbGxfbWVzcyA9IHJlcGxhY2VfcGVyc29uYWwoYWt0X3NwZWxsX21lc3MsICh7ZW5lbXl9KSwgMSk7CisgICAgc2F5KGJyZWFrX3N0cmluZyhha3Rfc3BlbGxfbWVzcywgNzgpLCh7ZW5lbXksIHRoaXNfb2JqZWN0KCl9KSk7CisgIH0KKyAgc2luZm8gPSBkZWVwX2NvcHkoc3BlbGxzW2ldW1NQRUxMX0FSR10pOworICBpZighbWFwcGluZ3Aoc2luZm8pKQorICAgIHNpbmZvPShbIFNJX01BR0lDX1RZUEUgOih7IE1UX0FOR1JJRkYgfSkgXSk7CisgIGVsc2UgaWYoIXNpbmZvW1NJX01BR0lDX1RZUEVdKQorICAgIHNpbmZvWyBTSV9NQUdJQ19UWVBFXT0oeyBNVF9BTkdSSUZGIH0pOworICBpZighc2luZm9bU1BfUEhZU0lDQUxfQVRUQUNLXSAmJgorICAgICAoZW5lbXktPlNwZWxsRGVmZW5kKHRoaXNfb2JqZWN0KCksc2luZm8pID4KKyAgICAgIHJhbmRvbShNQVhfQUJJTElUWStRdWVyeVByb3AoUF9MRVZFTCkqNTApKSl7CisgICAgdGVsbF9vYmplY3QoZW5lbXksIkR1IHdlaHJzdCBkZW4gU3BydWNoIGFiLlxuIik7CisgICAgc2F5KGVuZW15LT5OYW1lKFdFUiwxKSsiIHdlaHJ0IGRlbiBTcHJ1Y2ggYWIuXG4iLAorICAgICAgICAoeyBlbmVteSwgdGhpc19vYmplY3QoKX0pKTsKKyAgICByZXR1cm4gOworICB9CisgIGludCBkYW1hZ2UgPSByYW5kb20oc3BlbGxzW2ldW1NQRUxMX0RBTUFHRV0pKzE7CisgIGVuZW15LT5EZWZlbmQoZGFtYWdlLCBzcGVsbHNbaV1bU1BFTExfREFNVFlQRV0sCisgICAgICAgICAgICAgICAgc3BlbGxzW2ldW1NQRUxMX0FSR10sCisgICAgICAgICAgICAgICAgdGhpc19vYmplY3QoKSk7CisKKyAgLy8gRmFsbHMgZGVyIEdlZ25lciAob2RlciB3aXIpIGltIERlZmVuZCBzdGlyYnQsIGhpZXIgYWJicmVjaGVuCisgIGlmICggIW9iamVjdHAoTUUpIHx8ICFvYmplY3RwKGVuZW15KSAKKyAgICAgIHx8IGVuZW15LT5RdWVyeVByb3AoUF9HSE9TVCkgKSByZXR1cm47CisgIAorICBpZiAoc3BlbGxzW2ldW1NQRUxMX0ZVTkNdICYmIHN0cmluZ3Aoc3BlbGxzW2ldW1NQRUxMX0ZVTkNdKSkKKyAgICBjYXRjaChjYWxsX290aGVyKHRoaXNfb2JqZWN0KCksCisgICAgICAgICBzcGVsbHNbaV1bU1BFTExfRlVOQ10sCisgICAgICAgICBlbmVteSwKKyAgICAgICAgIGRhbWFnZSwKKyAgICAgICAgIHNwZWxsc1tpXVtTUEVMTF9EQU1UWVBFXSk7cHVibGlzaCk7Cit9CisKKy8vIEhlYXJ0YmVhdHMgbmFjaGhvbGVuLgorcHJpdmF0ZSB2b2lkIGNhdGNoX3VwX2hicygpIHsKKyAgLy8gZ2lidCBlcyBIQnMgenVtIG5hY2hob2xlbj8KKyAgaW50IGJlYXRfb2ZmX251bSA9IFF1ZXJ5KCJucGM6YmVhdF9vZmZfbnVtIik7CisgIGlmICghYmVhdF9vZmZfbnVtKQorICAgIHJldHVybjsgLy8gbmVpbi4KKyAgLy8gd2lldmllbGUgSEJzIG5hY2hob2xlbj8KKyAgYmVhdF9vZmZfbnVtID0gYWJzb2x1dGVfaGJfY291bnQoKSAtIGJlYXRfb2ZmX251bTsKKyAgCisgIGlmIChiZWF0X29mZl9udW0+MCkgeworICAgIC8vIE5pY2h0IGF1c2dlZnVlaHJ0ZXMgSEVJTEVOIG5hY2hob2xlbgorICAgIGludCBybG9jaz1RdWVyeVByb3AoUF9OT19SRUdFTkVSQVRJT04pOworICAgIGludCBocD1RdWVyeVByb3AoUF9IUCk7CisgICAgaW50IHNwPVF1ZXJ5UHJvcChQX1NQKTsKKyAgICBpbnQgYWxjPVF1ZXJ5UHJvcChQX0FMQ09IT0wpOworICAgIGlmICghKHJsb2NrICYgTk9fUkVHX0hQKSkgeworICAgICAgaHArPWJlYXRfb2ZmX251bS9IRUFMX0RFTEFZK2FsYy9BTENPSE9MX0RFTEFZOworICAgICAgU2V0UHJvcChQX0hQLGhwKTsKKyAgICB9CisgICAgaWYgKCEocmxvY2sgJiBOT19SRUdfU1ApKSB7CisgICAgICBzcCs9YmVhdF9vZmZfbnVtL0hFQUxfREVMQVkrYWxjL0FMQ09IT0xfREVMQVk7CisgICAgICBTZXRQcm9wKFBfU1Asc3ApOworICAgIH0KKyAgICBhbGMtPWJlYXRfb2ZmX251bS9BTENPSE9MX0RFTEFZOworICAgIGlmICggYWxjIDwgMCApCisgICAgICBhbGMgPSAwOworICAgIFNldFByb3AoUF9BTENPSE9MLGFsYyk7CisgICAgaW50IGRhID0gUXVlcnlQcm9wKFBfRElTQUJMRV9BVFRBQ0spOworICAgIC8vIFBhcmFseXNlbiBhYmJhdWVuCisgICAgaWYgKCBkYSA+IDAgKSB7CisgICAgICBkYSAtPSBiZWF0X29mZl9udW07CisgICAgICBpZiAoIGRhIDwgMCApCisJZGEgPSAwOworICAgICAgU2V0UHJvcCggUF9ESVNBQkxFX0FUVEFDSywgZGEgKTsKKyAgICB9CisgICAgLy8gSHVudHRpbWVzIGFrdHVhbGlzaWVyZW4sIEZlaW5kZSBleHBpcmVuCisgICAgdXBkYXRlX2h1bnRfdGltZXMoYmVhdF9vZmZfbnVtKTsKKyAgICBpZiAoIWhlYXJ0YmVhdCkKKyAgICAgIC8vIEhCcyBpbW1lciBub2NoIGFiZ2VzY2hhbHRldCwgbmFlY2hzdGVzIE1hbCBIQnMgc2VpdCBqZXR6dCBuYWNoaG9sZW4uCisgICAgICBTZXQoIm5wYzpiZWF0X29mZl9udW0iLGFic29sdXRlX2hiX2NvdW50KCkpOworICAgIGVsc2UKKyAgICAgIC8vIEhCIGxhZXVmdCB3aWVkZXIsIG5peCBtZWhyIG5hY2hob2xlbiwgYmlzIHp1ciBuYWVjaHN0ZW4gQWJzY2hhbHR1bmcuCisgICAgICBTZXQoIm5wYzpiZWF0X29mZl9udW0iLDApOworICB9Cit9CisKK3ZvaWQgaW5pdCgpIHsKKworICAvLyBnZ2YuIEhlYXJ0YmVhdHMgbmFjaGhvbGVuIHVuZCB3aWVkZXIgZWluc2NoYWx0ZW4uCisgIGlmICghaGVhcnRiZWF0KSB7CisgICAgc2V0X2hlYXJ0X2JlYXQoMSk7CisgICAgaGVhcnRiZWF0PTE7CisgICAgY2F0Y2hfdXBfaGJzKCk7CisgIH0KKworICBpZiAoQXV0b0F0dGFjayh0aGlzX3BsYXllcigpKSkKKyAgICBLaWxsKHRoaXNfcGxheWVyKCkpOworfQorCitwcml2YXRlIG5vc2F2ZSBjbG9zdXJlIG1vZF9hdHRfc3RhdDsKKworaW50IERlZmVuZChpbnQgZGFtLCBtaXhlZCBkYW1fdHlwZSwgbWl4ZWQgc3BlbGwsIG9iamVjdCBlbmVteSkgeworICBpZiAob2JqZWN0cChlbmVteT0oZW5lbXl8fHRoaXNfcGxheWVyKCkpKQorICAgICAgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShlbmVteSkKKyAgICAgICYmICFJU19MRUFSTkVSKGVuZW15KSkgeworICAgIGlmICghb2JqZWN0cChnZXRfdHlwZV9pbmZvKG1vZF9hdHRfc3RhdCwyKSkpIHsKKyAgICAgIG9iamVjdCBtYTsKKyAgICAgIGlmICghb2JqZWN0cChtYT1maW5kX29iamVjdChTVEFUTUFTVEVSKSkpCisgICAgICAgIHJldHVybiA6OkRlZmVuZChkYW0sZGFtX3R5cGUsc3BlbGwsZW5lbXkpOworICAgICAgLy8gS2VpbmUgU3RhdGlzdGlrIHdlbm4gTWFzdGVyIG5pY2h0IGdlbGFkZW4gaXN0LgorICAgICAgbW9kX2F0dF9zdGF0PXN5bWJvbF9mdW5jdGlvbigiTW9kaWZ5QXR0YWNrU3RhdCIsbWEpOworICAgIH0KKyAgICBmdW5jYWxsKG1vZF9hdHRfc3RhdCwKKyAgICAgICAgICAgIGVuZW15LT5RdWVyeVByb3AoUF9HVUlMRCksCisgICAgICAgICAgICBlbmVteS0+UXVlcnlQcm9wKFBfR1VJTERfTEVWRUwpLAorICAgICAgICAgICAgZGFtLAorICAgICAgICAgICAgZGFtX3R5cGUsCisgICAgICAgICAgICBzcGVsbCk7CisgIH0KKworICByZXR1cm4gOjpEZWZlbmQoZGFtLGRhbV90eXBlLHNwZWxsLGVuZW15KTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9ucGMvY29tbS5jIGIvc3RkL25wYy9jb21tLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODkyZDhmYQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9ucGMvY29tbS5jCkBAIC0wLDAgKzEsNTcgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBucGMvY29tbS5jIC0tIEJhc2lza29tbXVuaWthdGlvbiBmdWVyIE5QQ3MKKy8vCisvLyAkSWQ6IGNvbW0uYyA5MzU4IDIwMTUtMTAtMjIgMTg6MzU6MDRaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL2xpdmluZy9jb21tIjsKKworI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8bGl2aW5nL2NvbW0uaD4KKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKworCit2b2lkIGNyZWF0ZSgpIHsKKyAgYWRkX2FjdGlvbiggInNhZ2UiLCAic2FnIiwgMSApOworICBhZGRfYWN0aW9uKCAiZWNobyIsICJlY2hvIiApOworICBhZGRfYWN0aW9uKCAiZW1vdGUiLCAiZW1vdGUiICk7Cit9CisKK2ludCBlY2hvKCBzdHJpbmcgc3RyICkgeworICBzYXkoIHN0ciArICJcbiIgKTsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBzYWdlKCBzdHJpbmcgc3RyICkgeworICBzYXkoIGJyZWFrX3N0cmluZyhzdHIsIDc4LCBjYXBpdGFsaXplKG5hbWUoV0VSLDIpKSsiIHNhZ3Q6ICIpKTsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBlbW90ZSggc3RyaW5nIHN0ciApIHsKKyAgc2F5KCBjYXBpdGFsaXplKG5hbWUoV0VSLDIpKSsiICIrc3RyKyJcbiIgKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vIHp1bSB1ZWJlcnNjaHJlaWJlbiAtIERFUFJFQ0FURUQhIFVTRSBSZWNlaXZlTXNnKCkhCitwdWJsaWMgdm9pZCBjYXRjaF9tc2cobWl4ZWQgKmFyciwgb2JqZWN0IG9iaikge30KK3B1YmxpYyB2b2lkIGNhdGNoX3RlbGwoc3RyaW5nIHN0cikge30KKworLy8gYnkgZGVmYXVsdCwgdGhlIG1zZyBpcyBkZWxpdmVyZWQgdG8gY2F0Y2hfdGVsbCgpIGZvciBjb21wYXRpYmlsaXR5IHJlYXNvbnMKKy8vIGFuZCBvdGhlcndpc2UgaWdub3JlZC4KK3B1YmxpYyB2YXJhcmdzIGludCBSZWNlaXZlTXNnKHN0cmluZyBtc2csIGludCBtc2dfdHlwLCBzdHJpbmcgbXNnX2FjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBtc2dfcHJlZml4LCBvYmplY3Qgb3JpZ2luKQoreworICAvLyBjb21wYXRpYmlsaXR5Li4uCisgIGlmIChtc2dfdHlwICYgTVNHX0RPTlRfV1JBUCkKKyAgICBjYXRjaF90ZWxsKHNwcmludGYoIiVzJXMiLCBtc2dfcHJlZml4fHwiIiwgbXNnKSk7CisgIGVsc2UKKyAgICBjYXRjaF90ZWxsKHNwcmludGYoIiVzJXNcbiIsIG1zZ19wcmVmaXh8fCIiLCBtc2cpKTsKKyAgcmV0dXJuIE1TR19ERUxJVkVSRUQ7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9ucGMvaW5mby5jIGIvc3RkL25wYy9pbmZvLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDY2ZWUyNgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9ucGMvaW5mby5jCkBAIC0wLDAgKzEsMzQ1IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbnBjL2luZm8uYyAtLSBCZWhhbmRlbG4gdm9uIEZyYWdlbiBhbiBkZW4gTlBDCisvLworLy8gJElkOiBpbmZvLmMgOTUyMiAyMDE2LTAzLTAxIDE5OjIwOjEwWiBBcmF0aG9ybiAkCisKKy8qIExldHp0ZSBBZW5kZXJ1bmdlbiB2b24gV2ltIDguMS45OQorICoKKyAqIEFkZEluZm8oIHNjaGx1ZXNzZWwsIGFudHdvcnQgWywgaW5kZW50IFssIFtzaWxlbnQgWywgY2FzZWJhc2VkXSBdIF0gKQorICogIFdlbm4gZWluIFNwaWVsZXIgZGllc2VzIE1vbnN0ZXIgbmFjaCAic2NobHVlc3NlbCIgZnJhZ3QsIHNvIGdpYiBkaWUKKyAqICBQcm9ncmFtbWllcnRlIEFudHdvcnQgYXVzLgorICogIEVyd2VpdGVydW5nIHZvbiBXaW06IGlzdCBzaWxlbnQgZ2VzZXR6dCwgc28gZXJmb2xndCBlaW5lICJwZXJzb2VubGljaGUiCisgKiAgICBBbnR3b3J0LiBkLmguIHVtc3RlaGVuZGUgUGVyc29uZW4gYmVrb21tZW4gYmVpIHNpbGVudD09MSBrZWluZW4sIGJlaQorICogICAgc3RyaW5ncChzaWxlbnQpLCBkZW4gU3RyaW5nIGF1c2dlZ2ViZW4sIGRhYmVpIGthbm4gZXIgYXVjaCBkaWUgU2NobHVlc3NlbC0KKyAqICAgIFdvcnRlIEBXRVIgQFdFU1NFTiBAV0VNIEBXRU4gZW50aGFsdGVuLgorICogIC0gRXJnYWVuenQgdW0gQENBUF9XRVIuLi4gZnVlciB6d2FuZ3MtY2FwaXRhbGlzaWVydGUgTmFtZW4gYW4gU2F0emFuZmFlbmdlbi4KKyAqICAgIGlzdCBiZWkgZnJhZ2VuZGVuIE5QQ3MgdW5kIFBDcyBtaXQgVGFybmthcHBlIHdpY2h0aWchIChTaWx2YW5hKQorICogIC0gQXVjaCBpbiBkZXIgQW50d29ydCBkZXMgZnJhZ2VuZGVuIHdpcmQgbnVuIGVyc2V0enQgKFZhbmlvbikKKyAqICBFbnRoYWVsdCBjYXNlZGJhc2VkIGVpbmVuIEZ1bmt0aW9uc25hbWVuIG9kZXIgdmVyd2Vpc3QgYXVmIGVpbmUgY2xvc3VyZSwgc28KKyAqICAgIHdpcmQgZGllIEJlYW50d29ydHVuZyBkZXIgRnJhZ2Ugdm9uIGRlbSByZXR1cm4tV2VydCBhYmhhZW5naWcgZ2VtYWNodC4KKyAqICAgIEJlaSAwIHdpcmQgZGllIEZyYWdlIG5vcm1hbCBiZWFudHdvcnRldCwgYmVpIDEgZXJmb2xndCBkaWUgQXVzZ2FiZSBkZXMKKyAqICAgIHVudGVyIERFRkFVTFRfTk9JTkZPIGdlc3BlaWNoZXJ0ZW4gVGV4dGVzLgorICogICAgV2lyZCBlaW4gU3RyaW5nIHp1cnVlY2tnZWdlYmVuLCBzbyB3aXJkIGVyIHVudGVyIEJlYWNodHVuZyB2b24gaWRlbnQgYW4KKyAqICAgIFN0ZWxsZSBkZXIgdXJzcHJ1ZW5nbGljaGVuIEluZm9ybWF0aW9uIGF1c2dlZ2ViZW4uCisgKgorICogUmVtb3ZlSW5mbyggc2NobHVlc3NlbCApCisgKiAgRGFzIE1vbnN0ZXIgYW50d29ydGV0IG5pY2h0IG1laHIgYXVmIGRpZXNlbiBTY2hsdWVzc2VsLgorICoKKyAqIFNldFByb3AoIFBfREVGQVVMVF9JTkZPLCBhbnR3b3J0IFssIGluZGVudCBdICkKKyAqICBTZXR6ZSBkaWUgQW50d29ydCwgZGllIGRhcyBNb25zdGVyIGF1ZiB1bnZlcnN0YWVuZGxpY2hlIEZyYWdlbiBnZWJlbgorICogIHNvbGwuIChEaWVzZSBGdW5rdGlvbiBpc3Qgb2Jzb2xldCEgQmVudXR6ZSBzdGF0dGRlc3NlbgorICogIEFkZEluZm8oICJcbmRlZmF1bHQgaW5mbyIsIGFudHdvcnQgWywgaW5kZW50IF0gKTsKKyAqCisgKiBHZXRJbmZvKCBbc2NobHVlc3NlbF0gKQorICogIFdlbm4gU2NobHVlc3NlbCBnZXNldHp0IGlzdCwgc28gd2lyZCBkaWUgZGF6dWdlaG9lcmlnZSBJbmZvLAorICogIGFuc29uc3RlbiB3ZXJkZW4gYWxsZSBJbmZvcyB6dXJ1ZWNrZ2VnZWJlbi4KKyAqCisgKiBEaWUgQW50d29ydGVuIHNvbGx0ZW4gd2llIGVtb3RlIC0ga29tbWFuZG9zIGF1c3NlaGVuLgorICogRGVyIG9wdGlvbmFsZSBJbmRlbnQgd2lyZCB6dW0gVW1icmVjaGVuIHZvbiBsYW5nZW4gSW5mb3MgYmVudXR6dC4KKyAqIChUeXBpc2NoZXJ3ZWlzZSBzb2xsdGUgaW5kZW50PSJzYWd0OiAiIHNlaW4uKQorICoKKyAqIEluIGRlbiBJbmZvcyBkYXJmIG1pdCBwcm9jZXNzX3N0cmluZyBnZWFyYmVpdGV0IHdlcmRlbi4gRGFzIEVyZ2VibmlzIHZvbgorICogcHJvY2Vzc19zdHJpbmcgd2lyZCBkYW5uIG1pdCB1bWdlYnJvY2hlbiEKKyAqCisgKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICovCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bnBjLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8ZXhwbG9yYXRpb24uaD4KKworLy8gVE9ETzogbGFuZ2ZyaXN0aWcgd2FlciBoaWVyIHByaXZhdGUgc2Nob2VuLgorbm9zYXZlIG1hcHBpbmcgaW5mb3M7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgICAgLy8gSW5pdGlhbGlzaWVydW5nIG51ciB3ZW5uIG5vZXRpZywgZGFtaXQgYmVpbSB2aXJ0dWVsbGVuIEVyYmVuIHZvbgorICAgIC8vIC9zdGQvbnBjIGluIG5wYzEgdW5kIG5wYzIgZGFubiBpbiBucGMzIGJlaW0gbnBjMTo6Y3JlYXRlKCk7CisgICAgLy8gbnBjMjpjcmVhdGUoKTsgaW0gendlaXRlbiBjcmVhdGUoKSBkaWUgSW5mb3MgbmljaHQKKyAgICAvLyB1ZWJlcnNjaHJpZWJlbi9nZWxvZXNjaHQgd2VyZGVuLgorICAgIGlmICghbWFwcGluZ3AoaW5mb3MpKSB7CisgICAgICAgIGluZm9zID0gKFsKKyAgICAgICAgICAgIERFRkFVTFRfSU5GTzoic2NoYXV0IERpY2ggZnJhZ2VuZCBhbi5cbiI7MDsKKyAgICAgICAgICAgICJzY2hhdXQgQFdFTiBmcmFnZW5kIGFuLlxuIjswLAorICAgICAgICAgICAgREVGQVVMVF9OT0lORk86Im1vZWNodGUgRGlyIG5pY2h0IGFudHdvcnRlbi5cbiI7MDsKKyAgICAgICAgICAgICJ2ZXJ3ZWlnZXJ0IEBXRU0gZGllIEFudHdvcnQuXG4iOzEKKyAgICAgICAgICAgIF0pOworICAgIH0KK30KKworCit2b2lkIGluaXQoKSB7CisgIGFkZF9hY3Rpb24oICJmcmFnZSIsICJmcmFnIiwgMSApOworfQorCisKK3N0YXRpYyB2b2lkIHNtYXJ0X25wY19sb2coc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nIGNyZWF0LCBjcmVhdF9kZXQ7CisKKyAgaWYgKCFzdHJpbmdwKGNyZWF0PVF1ZXJ5UHJvcChQX0xPR19JTkZPKSkpIHsKKyAgICBjcmVhdCA9IE1BU1RFUi0+Y3JlYXRvcl9maWxlKHRoaXNfb2JqZWN0KCkpOworICAgIGlmIChjcmVhdCA9PSBST09USUQpCisgICAgICBjcmVhdCA9ICJST09UIjsKKyAgICBlbHNlIGlmKCBjcmVhdD09QkFDS0JPTkVJRCApCisgICAgICBjcmVhdD0iU1REIjsKKyAgICBjcmVhdF9kZXQ9InJlcG9ydC8iK2V4cGxvZGUoY3JlYXQsICIuIilbPDFdKyJfSU5GTy5yZXAiOworICAgIGNyZWF0PSJyZXBvcnQvIitleHBsb2RlKGNyZWF0LCAiLiIpWzwxXSsiLnJlcCI7CisgIH0KKyAgbG9nX2ZpbGUoY3JlYXQsCisgICAgICAgICAgIHNwcmludGYoIklORk8gdm9uICVzIFslc10gKCVzKTpcbiVzXG4iLAorICAgICAgICAgICAgICAgICAgIGdldHVpZCh0aGlzX2ludGVyYWN0aXZlKCkpLAorICAgICAgICAgICAgICAgICAgIGV4cGxvZGUob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSksIiMiKVswXSwKKyAgICAgICAgICAgICAgICAgICBzdHJmdGltZSgiJWQuICViICVZIiksCisgICAgICAgICAgICAgICAgICAgc3RyKSk7CisgIGlmIChzdHJpbmdwKGNyZWF0X2RldCkgJiYgc2l6ZW9mKGNyZWF0X2RldCkpCisgICAgbG9nX2ZpbGUoY3JlYXRfZGV0LAorICAgICAgICAgICAgIHNwcmludGYoIklORk8gdm9uICVzIFslc10gKCVzKTpcbiVzXG4iLAorICAgICAgICAgICAgICAgICAgICAgZ2V0dWlkKHRoaXNfaW50ZXJhY3RpdmUoKSksCisgICAgICAgICAgICAgICAgICAgICBleHBsb2RlKG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpLCIjIilbMF0sCisgICAgICAgICAgICAgICAgICAgICBzdHJmdGltZSgiJWQuICViICVZIiksCisgICAgICAgICAgICAgICAgICAgICBzdHIpKTsKK30KKworcHVibGljIGludCBmcmFnZShzdHJpbmcgc3RyKSB7CisgIHN0cmluZyBteW5hbWUsIHRleHQ7CisKKyAgc3RyPShleHRlcm5fY2FsbCgpP3RoaXNfcGxheWVyKCktPl91bnBhcnNlZF9hcmdzKCk6c3RyKTsKKyAgaWYoICFzdHIgfHwgc3NjYW5mKCBzdHIsICIlcyBuYWNoICVzIiwgbXluYW1lLCB0ZXh0ICkgIT0gMiApIHsKKyAgICBfbm90aWZ5X2ZhaWwoICJXRU4gd2lsbHN0IER1IG5hY2ggV0FTIGZyYWdlbj9cbiIgKTsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIGlmKCAhaWQoIGxvd2VyX2Nhc2UobXluYW1lKSApCisgICAgfHwgUXVlcnlQcm9wKFBfSU5WSVMpICkgeworICAgIF9ub3RpZnlfZmFpbCggIlNvIGplbWFuZGVuIGZpbmRlc3QgRHUgaGllciBuaWNodC5cbiIgKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBzYXkoIGNhcGl0YWxpemUodGhpc19wbGF5ZXIoKS0+bmFtZShXRVIpKSsiIGZyYWd0ICIgKworICAgIG5hbWUoV0VOLDIpKyIgbmFjaCAiK2NhcGl0YWxpemUodGV4dCkrIi5cbiIsCisgICAgICB0aGlzX3BsYXllcigpICk7CisKKyAgdGV4dCA9IGxvd2VyX2Nhc2UodGV4dCk7CisgIEdpdmVFUChFUF9JTkZPLCB0ZXh0KTsKKworICByZXR1cm4gZG9fZnJhZ2UoIHRleHQgKTsKK30KKworc3RhdGljIHN0cmluZyBpbmZvRGVmYXVsdFJlcGxhY2Uoc3RyaW5nIHBzdHJpbmcsIG9iamVjdCBwbCkKK3sKKyAgcHN0cmluZz0iICIrcHN0cmluZzsKKyAgaWYgKHN0cnN0cihwc3RyaW5nLCJAV0VSIiwwKSA+LTEgKQorICAgIHBzdHJpbmc9IHJlZ3JlcGxhY2UocHN0cmluZywiQFdFUiIscGwtPm5hbWUoV0VSLDEpLDEpOworICBpZiAoc3Ryc3RyKHBzdHJpbmcsIkBXRVNTRU4iLDApID4tMSApCisgICAgcHN0cmluZz0gcmVncmVwbGFjZShwc3RyaW5nLCJAV0VTU0VOIixwbC0+bmFtZShXRVNTRU4sMSksMSk7CisgIGlmIChzdHJzdHIocHN0cmluZywiQFdFTSIsMCkgPi0xICkKKyAgICBwc3RyaW5nPSByZWdyZXBsYWNlKHBzdHJpbmcsIkBXRU0iLHBsLT5uYW1lKFdFTSwxKSwxKTsKKyAgaWYgKHN0cnN0cihwc3RyaW5nLCJAV0VOIiwwKSA+LTEgKQorICAgIHBzdHJpbmc9IHJlZ3JlcGxhY2UocHN0cmluZywiQFdFTiIscGwtPm5hbWUoV0VOLDEpLDEpOworICBpZiAoc3Ryc3RyKHBzdHJpbmcsIkBDQVBfV0VSIiwwKSA+LTEgKQorICAgIHBzdHJpbmc9IHJlZ3JlcGxhY2UocHN0cmluZywiQENBUF9XRVIiLHBsLT5OYW1lKFdFUiwxKSwxKTsKKyAgaWYgKHN0cnN0cihwc3RyaW5nLCJAQ0FQX1dFU1NFTiIsMCkgPi0xICkKKyAgICBwc3RyaW5nPSByZWdyZXBsYWNlKHBzdHJpbmcsIkBDQVBfV0VTU0VOIixwbC0+TmFtZShXRVNTRU4sMSksMSk7CisgIGlmIChzdHJzdHIocHN0cmluZywiQENBUF9XRU0iLDApID4tMSApCisgICAgcHN0cmluZz0gcmVncmVwbGFjZShwc3RyaW5nLCJAQ0FQX1dFTSIscGwtPk5hbWUoV0VNLDEpLDEpOworICBpZiAoc3Ryc3RyKHBzdHJpbmcsIkBDQVBfV0VOIiwwKSA+LTEgKQorICAgIHBzdHJpbmc9IHJlZ3JlcGxhY2UocHN0cmluZywiQENBUF9XRU4iLHBsLT5OYW1lKFdFTiwxKSwxKTsKKworICByZXR1cm4gcHN0cmluZ1sxLi5dOworfQorCitzdGF0aWMgbWl4ZWQgKkdldEluZm9BcnIoc3RyaW5nIHN0cikKK3sgIAorICAgcmV0dXJuICh7IGluZm9zW3N0ciwgMF0sIGluZm9zW3N0ciwgMV0sIGluZm9zW3N0ciwyXSwgaW5mb3Nbc3RyLCAzXSB9KTsKK30KKworcHVibGljIGludCBkb19mcmFnZShzdHJpbmcgdGV4dCkKK3sKKyAgc3RyaW5nIGluZGVudCxhbnN3ZXI7CisgIG1peGVkIHNpbGVudCwgcHJlaW5mbywgbm9hbnN3ZXI7CisgIG1peGVkICppbmZvOworCisgIGlmIChzdHJpbmdwKHByZWluZm8gPSBRdWVyeVByb3AoUF9QUkVfSU5GTykpKQorICB7CisgICAgIC8vIERpZSBtZXNzYWdlIGFjdGlvbiB3aXJkIGF1ZiAiZnJhZ2UiIGZpeGllcnQsIGRhbWl0IGRpZXMgaW1tZXIgZGFzCisgICAgIC8vIGdsZWljaGUgaXN0LCBlZ2FsLCBtaXQgd2VsY2hlbSBWZXJiIG1hbiBpbiBkaWVzZSBGdW5rdGlvbiBrb21tdC4KKyAgICAgdGhpc19wbGF5ZXIoKS0+UmVjZWl2ZU1zZyhwcmVpbmZvLCBNVF9MSVNURU4sICJmcmFnZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmFtZShXRVIsMikrIiAiLHRoaXNfb2JqZWN0KCkpOworICAgICBzZW5kX3Jvb20oZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgICAgICAiaXN0IG5pY2h0IGdld2lsbHQsICIrdGhpc19wbGF5ZXIoKS0+TmFtZShXRU0sMikKKyAgICAgICAgICAgICAgICsiIHp1IGFudHdvcnRlbi4iLAorICAgICAgICAgICAgICAgTVRfTElTVEVOLCAiZnJhZ2UiLAorICAgICAgICAgICAgICAgTmFtZShXRVIsMikrIiAiLAorICAgICAgICAgICAgICAgKHt0aGlzX3BsYXllcigpfSkgKTsKKyAgICAgcmV0dXJuIDE7CisgIH0KKyAgZWxzZQorICB7CisgICAgaWYgKGludHAocHJlaW5mbykgJiYgcHJlaW5mbyA+IDApCisgICAgICByZXR1cm4gMTsKKyAgfQorCisgIGluZm89R2V0SW5mb0Fycih0ZXh0KTsKKyAgaWYgKCFpbmZvWzBdKQorICB7CisgICAgaWYoIHRoaXNfaW50ZXJhY3RpdmUoKSAmJiBRdWVyeVByb3AoUF9MT0dfSU5GTykgKQorICAgICAgc21hcnRfbnBjX2xvZyh0ZXh0KTsKKyAgICB0ZXh0ID0gREVGQVVMVF9JTkZPOworICAgIGluZm89R2V0SW5mb0Fycih0ZXh0KTsKKyAgfQorCisgIGlmIChjbG9zdXJlcChpbmZvWzBdKSApIHsKKyAgICBhbnN3ZXI9ZnVuY2FsbChpbmZvWzBdKTsKKyAgICBpZiggIWFuc3dlciB8fCBhbnN3ZXI9PSIiKSByZXR1cm4gMTsKKyAgfSBlbHNlIHsKKyAgICBhbnN3ZXI9cHJvY2Vzc19zdHJpbmcoaW5mb1swXSk7CisgIH0KKworICBpZiAoY2xvc3VyZXAoaW5mb1szXSkgKQorICAgeworICAgIG5vYW5zd2VyPWZ1bmNhbGwoaW5mb1szXSk7CisgICAgaWYgKCBpbnRwKG5vYW5zd2VyKSAmJiBub2Fuc3dlciA+IDApCisgICAgIHsKKyAgICAgICB0ZXh0ID0gREVGQVVMVF9OT0lORk87CisgICAgICAgaW5mbyA9IEdldEluZm9BcnIodGV4dCk7CisgICAgICAgaWYgKGNsb3N1cmVwKGluZm9bMF0pICkgeworICAgICAgICAgYW5zd2VyPWZ1bmNhbGwoaW5mb1swXSk7CisgICAgICAgICBpZiggIWFuc3dlciB8fCBhbnN3ZXI9PSIiKSByZXR1cm4gMTsKKyAgICAgICB9IGVsc2UgeworICAgICAgICAgYW5zd2VyPXByb2Nlc3Nfc3RyaW5nKGluZm9bMF0pOworICAgICAgIH0KKyAgICAgfQorICAgIGVsc2UgaWYgKCBzdHJpbmdwKG5vYW5zd2VyKSApCisgICAgICBhbnN3ZXIgPSBub2Fuc3dlcjsKKyAgIH0KKworICBzaWxlbnQ9aW5mb1syXTsKKworICAvLyBSZXBsYWNlbWVudHMgZ2VoZW4gYXVjaCBpbiBkZXIgQW50d29ydCBkZXMgTlBDLiBEYXMgZ2lidCBkZW4gQW50d29ydGVuIAorICAvLyBlaW5lIHBlcnNvZW5saWNoZSBOb3RlLCB1bmQgc28gdGV1ZXIgaXMgZGFzIGF1Y2ggbmljaHQgOikKKyAgYW5zd2VyID0gaW5mb0RlZmF1bHRSZXBsYWNlKGFuc3dlciwgdGhpc19wbGF5ZXIoKSk7CisKKyAgaWYoIGluZGVudD1pbmZvWzFdICkKKyAgeworICAgIGlmIChzdHJpbmdwKHNpbGVudCkgfHwgKGludHAoc2lsZW50KSAmJiBzaWxlbnQgPiAwKSApCisgICAgeyAgLy8gUGVyc29lbmxpY2hlIEFudHdvcnQgbWl0IGluZGVudAorICAgICAgIHRoaXNfcGxheWVyKCktPlJlY2VpdmVNc2coYW5zd2VyLCBNVF9MSVNURU58TVNHX0JTX0xFQVZFX0xGUywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmcmFnZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lKFdFUiwyKSsiICIraW5kZW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc19vYmplY3QoKSk7CisgICAgICAgaWYgKHN0cmluZ3Aoc2lsZW50KSkKKyAgICAgICB7CisgICAgICAgICAgc2lsZW50PWluZm9EZWZhdWx0UmVwbGFjZShzaWxlbnQsIHRoaXNfcGxheWVyKCkpOworICAgICAgICAgIHNlbmRfcm9vbShlbnZpcm9ubWVudCgpLCBzaWxlbnQsIE1UX0xJU1RFTiwgImZyYWdlIiwKKyAgICAgICAgICAgICAgICAgICAgTmFtZShXRVIsMikrIiAiLCAoe3RoaXNfcGxheWVyKCl9KSk7CisgICAgICAgfQorICAgIH0KKyAgICBlbHNlIC8vICJub3JtYWxlIEFudHdvcnQiIG1pdCBJbmRlbnQKKyAgICB7CisgICAgICBzZW5kX3Jvb20oZW52aXJvbm1lbnQoKSwgYW5zd2VyLCBNVF9MSVNURU58TVNHX0JTX0xFQVZFX0xGUywKKyAgICAgICAgICAgICAgICAiZnJhZ2UiLAorICAgICAgICAgICAgICAgIE5hbWUoV0VSLDIpKyIgIitpbmRlbnQsICh7dGhpc19vYmplY3QoKX0pKTsKKyAgICB9CisgIH0KKyAgZWxzZQorICB7CisgICAgaWYgKHN0cmluZ3Aoc2lsZW50KSB8fCAoaW50cChzaWxlbnQpICYmIHNpbGVudCA+IDApICkKKyAgICB7ICAvLyBQZXJzb2VubGljaGUgQW50d29ydCBvaG5lIGluZGVudAorICAgICAgIHRoaXNfcGxheWVyKCktPlJlY2VpdmVNc2coYW5zd2VyLCBNVF9MSVNURU58TVNHX0RPTlRfV1JBUCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmcmFnZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYW1lKFdFUiwyKSsiICIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzX29iamVjdCgpKTsKKyAgICAgICBpZiAoc3RyaW5ncChzaWxlbnQpKQorICAgICAgIHsKKyAgICAgICAgICBzaWxlbnQ9aW5mb0RlZmF1bHRSZXBsYWNlKHNpbGVudCwgdGhpc19wbGF5ZXIoKSk7CisgICAgICAgICAgc2VuZF9yb29tKGVudmlyb25tZW50KCksIHNpbGVudCwgTVRfTElTVEVOLCAiZnJhZ2UiLAorICAgICAgICAgICAgICAgICAgICBOYW1lKFdFUiwyKSsiICIsICh7dGhpc19wbGF5ZXIoKX0pICk7CisgICAgICAgfQorICAgIH0KKyAgICBlbHNlIC8vICJub3JtYWxlIEFudHdvcnQiIG9obmUgSW5kZW50CisgICAgICBzZW5kX3Jvb20oZW52aXJvbm1lbnQoKSwgYW5zd2VyLCBNVF9MSVNURU58TVNHX0RPTlRfV1JBUCwKKyAgICAgICAgICAgICAgICAiZnJhZ2UiLCBOYW1lKFdFUiwyKSsiICIpOworICB9CisgIHJldHVybiAxOworfQorCisvKgorICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqIFNldHplbiB2b24gSW5mb3MKKyAqLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKi8KKworcHVibGljIHZhcmFyZ3Mgdm9pZCBBZGRJbmZvKG1peGVkIGtleSwgbWl4ZWQgaW5mbywgc3RyaW5nIGluZGVudCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWl4ZWQgc2lsZW50LCBtaXhlZCBjYXNlYmFzZWQgKSB7CisKKyAgaWYgKHN0cmluZ3AoY2FzZWJhc2VkKSkKKyAgICBjYXNlYmFzZWQ9c3ltYm9sX2Z1bmN0aW9uKGNhc2ViYXNlZCx0aGlzX29iamVjdCgpKTsKKworICBpZiggcG9pbnRlcnAoIGtleSApICkgeworICAgIGludCBpOworICAgIGZvciAoIGk9c2l6ZW9mKCBrZXkgKS0xOyBpPj0wOyBpLS0gKQorICAgICAgaW5mb3MgKz0gKFsga2V5W2ldOiBpbmZvOyBpbmRlbnQ7IHNpbGVudDsgY2FzZWJhc2VkIF0pOworICB9CisgIGVsc2UKKyAgICBpbmZvcyArPSAoWyBrZXk6IGluZm87IGluZGVudDsgc2lsZW50OyBjYXNlYmFzZWQgXSk7Cit9CisKK3B1YmxpYyB2YXJhcmdzIHZvaWQgQWRkU3BlY2lhbEluZm8obWl4ZWQga2V5cywgc3RyaW5nIGZ1bmN0aW9ubmFtZSwgCisgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIGluZGVudCwgbWl4ZWQgc2lsZW50LCBtaXhlZCBjYXNlYmFzZWQgKQoreworICBpbnQgaTsKKyAgY2xvc3VyZSBjbDsKKworICBpZighKGNsPXN5bWJvbF9mdW5jdGlvbihmdW5jdGlvbm5hbWUsdGhpc19vYmplY3QoKSkpKSByZXR1cm47CisgIHJldHVybiBBZGRJbmZvKGtleXMsY2wsaW5kZW50LHNpbGVudCxjYXNlYmFzZWQpOworfQorCisKK3B1YmxpYyB2b2lkIFJlbW92ZUluZm8oIHN0cmluZyBrZXkgKQoreworICBtX2RlbGV0ZShpbmZvcyxrZXkpOworfQorCitzdGF0aWMgdmFyYXJncyB2b2lkIF9zZXRfZGVmYXVsdF9pbmZvKCBtaXhlZCBpbmZvICkKK3sKKyAgaWYgKHBvaW50ZXJwKGluZm8pKQorICAgIGFwcGx5KCMnQWRkSW5mby8qJyovLERFRkFVTFRfSU5GTyxpbmZvKTsKKyAgZWxzZQorICAgIEFkZEluZm8oREVGQVVMVF9JTkZPLGluZm8pOworfQorCitwdWJsaWMgdmFyYXJncyBtaXhlZCBHZXRJbmZvKHN0cmluZyBzdHIpCit7CisgIGlmICghc3RyKSByZXR1cm4gZGVlcF9jb3B5KGluZm9zKTsKKyAgcmV0dXJuIGluZm9zW3N0cl07Cit9CisKKworc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X25wY19pbmZvKCkKK3sKKyAgICByZXR1cm4gZGVlcF9jb3B5KGluZm9zKTsKK30KKworCitzdGF0aWMgbWFwcGluZyBfc2V0X25wY19pbmZvKCBtYXBwaW5nIG1hcF9sZGZpZWQgKQoreworICAgIGlmICggIW1hcHBpbmdwKG1hcF9sZGZpZWQpICkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICByZXR1cm4gaW5mb3MgPSBtYXBfbGRmaWVkOworfQorCmRpZmYgLS1naXQgYS9zdGQvbnBjL2l0ZW1zLmMgYi9zdGQvbnBjL2l0ZW1zLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjAyNjBjZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9ucGMvaXRlbXMuYwpAQCAtMCwwICsxLDI0MCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIC9zdGQvbnBjL2l0ZW1zLmMgLS0gSXRlbS1WZXJ3YWx0dW5nIGZ1ZXIgTlBDcworLy8KKy8vICRJZDogaXRlbXMuYyA4MTQ2IDIwMTItMTAtMzAgMTg6MTg6MTRaIFplc3N0cmEgJAorLy8KKy8vIChjKSBieSBQYWRyZWljIChQYWRyZWljQG1nLm11ZC5kZSkKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKyNpbmNsdWRlIDxsaXZpbmcvY29tYmF0Lmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8bnBjLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPGNvbmZpZy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPHN5c19kZWJ1Zy5oPgorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICAvLyBkaWVzZXMgZmxhZyBpc3QgbnVyIGJpcyB6dW0gZXJzdGVuIG1vdmUgZ2VzZXR6dC4gTmltbXQgZGFuYWNoIGFsc28gYXVjaAorICAgU2V0KE5QQ19ORUVEU19JVEVNX0lOSVQsIDEpOyAgLy8ga2VpbmVuIFNwZWljaGVyIG1laHIgaW4gQW5zcHJ1Y2guCisgICAvLyBTZXQoUF9JVEVNUywgKHt9KSk7IC8vIGtlaW5lIGluaXRpYWxpc2llcnVuZyBzcGFydCBTcGVpY2hlciAgCit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgICAgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKworcHJvdGVjdGVkIG9iamVjdCogbWF5YmVfb3duX3N0dWZmKCkgeworICBvYmplY3QqIG9icyA9IGFsbF9pbnZlbnRvcnkoZW52aXJvbm1lbnQoKSk7CisgIG9iamVjdCBoYXVmZW4gPSBwcmVzZW50KCJcbmhhdWZlbiAiK25hbWUoV0VNKSxlbnZpcm9ubWVudCgpKTsKKyAgaWYoIG9iamVjdHAoaGF1ZmVuKSApIG9icyArPSBhbGxfaW52ZW50b3J5KGhhdWZlbik7CisgIG9iamVjdCBsZWljaGUgPSBwcmVzZW50KCJcbmxlaWNoZSAiK25hbWUoV0VNKSxlbnZpcm9ubWVudCgpKTsKKyAgaWYoIG9iamVjdHAobGVpY2hlKSApIG9icyArPSBhbGxfaW52ZW50b3J5KGxlaWNoZSk7CisgIHJldHVybiBvYnM7Cit9CisKKy8vIGNsb250IGFsbGUgT2JqZWt0ZSBkaWUgZ2VjbG9udCB3ZXJkZW4gbXVlc3Nlbi4uLgorcHJvdGVjdGVkIHZvaWQgX2Nsb25lX2l0ZW1zKCkKK3sKKyAgaW50IGksIGosIG1vZGUsIHJlZnJlc2g7CisgIG9iamVjdCBvYiwgKmludjE7CisgIG1peGVkICBwcm9wcywgKml0ZW1zOworICBzdHJpbmcgZmlsZSwgKmludjI7CisKKyAgaWYgKCFwb2ludGVycChpdGVtcz1RdWVyeVByb3AoUF9JVEVNUykpKSByZXR1cm47CisgIGlmIChlbnZpcm9ubWVudCgpKSB7IC8vIExpc3RlIG1pdCBmaWxlbmFtZW4gKGludjIpIGVyc3RlbGxlbi4KKyAgICBpbnYxID0gbWF5YmVfb3duX3N0dWZmKCk7CisgICAgaW52MiA9IG1hcChpbnYxLCAjJ2xvYWRfbmFtZSk7CisgIH0KKyAgZWxzZSBpbnYyPSh7fSk7IC8vIGludjEgd2lyZCBnYXIgbmljaHQgbWVociBiZW5vZXRpZ3QKKworICBmb3IgKGk9c2l6ZW9mKGl0ZW1zKS0xOyBpPj0wOyBpLS0pIHsKKyAgICBvYiA9IGl0ZW1zW2ldW1JJVEVNX09CSkVDVF07CisgICAgZmlsZSA9IGl0ZW1zW2ldW1JJVEVNX0ZJTEVdOworICAgIG1vZGUgPSBpdGVtc1tpXVtSSVRFTV9SRUZSRVNIXTsKKyAgICByZWZyZXNoID0gbW9kZSAmIDB4MDAwMGZmZmY7CisgICAgcHJvcHMgPSBpdGVtc1tpXVtSSVRFTV9QUk9QU107CisgICAgaWYgKHByb3BzICYmIGludHAocHJvcHMpKSB7IC8vIHVuaXF1ZSBHZWdlbnN0YW5kPworICAgICAgb2I9ZmluZF9vYmplY3QoZmlsZSk7CisgICAgICBpZiAob2IpIHsKKyAgICAgICAgLy8ga2FubiBvYiBhdWZnZW5vbW1lbiB3ZXJkZW4/IFdlbm4gZGFzIE9iamVrdCBpbiBpbnYxIGRyaW4gaXN0LCBpc3QgZXMKKyAgICAgICAgLy8gaW0gRW52IG9kZXIgaW4gZWluZXIgTGVpY2hlIG9kZXIgZWluZW0gSGF1ZmVuLgorICAgICAgICBpZiAobWVtYmVyKGludjEsb2IpID4gLTEpIHsKKyAgICAgICAgICBpZiAoZW52aXJvbm1lbnQoKSkgeworICAgICAgICAgICAgaWYgKGVudmlyb25tZW50KG9iKSA9PSBlbnZpcm9ubWVudCgpKQorICAgICAgICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoKSwKKyAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUobmFtZShXRVIpKSsiIGhlYnQgIitvYi0+bmFtZShXRU4pKyIgYXVmLlxuIik7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCgpLGJyZWFrX3N0cmluZygKKyAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUobmFtZShXRVIpKSsiIG5pbW10ICIrb2ItPm5hbWUoV0VOKSsgIiBhdXMgIgorICAgICAgICAgICAgICAgICAgK2Vudmlyb25tZW50KG9iKS0+bmFtZShXRU0pICsgIi4iLDc4KSk7CisgICAgICAgICAgfQorICAgICAgICAgIG9iLT5yZW1vdmUoKTsgIC8vIHplcnN0b2VyZW4gdW5kIG5ldWxhZGVuLgorICAgICAgICAgIGlmIChvYikgZGVzdHJ1Y3Qob2IpOworICAgICAgICAgIGlmIChjYXRjaChvYj1sb2FkX29iamVjdChmaWxlKTtwdWJsaXNoKSkgICAgICAgICAgICAgCisgICAgICAgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICAgICAgICAgIl9jbG9uZV9pdGVtcygpOiAlTyBkb2VzIG5vdCBleGlzdCBvciBpcyBub3QgbG9hZGFibGVcbiIsIGZpbGUpKTsgCisgICAgICAgICAgb2ItPm1vdmUodGhpc19vYmplY3QoKSwgTV9OT0NIRUNLKTsKKyAgICAgICAgICBpdGVtc1tpXVtSSVRFTV9PQkpFQ1RdPW9iOworICAgICAgICB9CisgICAgICAgIGVsc2Ugc3dpdGNoKCByZWZyZXNoICkgeworICAgICAgICAgIGNhc2UgUkVGUkVTSF9ERVNUUlVDVDoKKyAgICAgICAgICAgIGlmIChlbnZpcm9ubWVudChvYikpIHsKKyAgICAgICAgICAgICAgb2I9MDsgLy8gbmljaHQgenVlY2tlbiwgdHJhZ2VuLCBpbml0aWFsaXNpZXJlbi4uLgorICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICBjYXNlIFJFRlJFU0hfQUxXQVlTOgorICAgICAgICAgIGNhc2UgUkVGUkVTSF9SRU1PVkU6ICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgb2ItPnJlbW92ZSgpOworICAgICAgICAgICAgaWYgKG9iKSBkZXN0cnVjdChvYik7CisgICAgICAgICAgICBpZiAoY2F0Y2gob2I9bG9hZF9vYmplY3QoZmlsZSk7cHVibGlzaCkpIAorICAgICAgICAgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIl9jbG9uZV9pdGVtcygpOiAiCisgICAgICAgICAgICAgICAgICAgICAgIiVPIGRvZXMgbm90IGV4aXN0IG9yIGlzIG5vdCBsb2FkYWJsZVxuIiwgZmlsZSkpOworICAgICAgICAgICAgb2ItPm1vdmUodGhpc19vYmplY3QoKSwgTV9OT0NIRUNLKTsKKyAgICAgICAgICAgIGl0ZW1zW2ldW1JJVEVNX09CSkVDVF09b2I7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFJFRlJFU0hfTk9ORToKKyAgICAgICAgICBkZWZhdWx0OiBvYj0wOyAvLyBuaWNodCB6dWVja2VuLCB0cmFnZW4sIGluaXRpYWxpc2llcmVuLi4uCisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICBpZiAoY2F0Y2gob2I9bG9hZF9vYmplY3QoZmlsZSk7cHVibGlzaCkpIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICAgIl9jbG9uZV9pdGVtcygpOiAlTyBkb2VzIG5vdCBleGlzdCBvciBpcyBub3QgbG9hZGFibGVcbiIsIGZpbGUpKTsKKyAgICAgICAgaWYgKG9iamVjdHAob2IpKSBvYi0+bW92ZSh0aGlzX29iamVjdCgpLCBNX05PQ0hFQ0spOworICAgICAgICBpdGVtc1tpXVtSSVRFTV9PQkpFQ1RdPW9iOworICAgICAgfQorICAgIH0gLy8gaWYgKHByb3BzIC4uLikgLy8gYWxzbyBuaWNodCB1bmlxdWUKKyAgICBlbHNlIHsKKyAgICAgIHN3aXRjaCggcmVmcmVzaCApIHsKKyAgICAgICAgY2FzZSBSRUZSRVNIX0RFU1RSVUNUOiAvLyBlcmZ1ZWxsdCBhdWNoIFJFRlJFU0hfUkVNT1ZFIEJlZGluZ3VuZy4uLgorICAgICAgICAgIGlmIChvYikgeworICAgICAgICAgICAgb2I9MDsgLy8gbmljaHQgenVlY2tlbiwgdHJhZ2VuLCBpbml0aWFsaXNpZXJlbi4uLgorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICBjYXNlIFJFRlJFU0hfUkVNT1ZFOgorICAgICAgICAgIGlmIChvYikgeworICAgICAgICAgICAgaWYocHJlc2VudChvYiwgdGhpc19vYmplY3QoKSkpIHsKKyAgICAgICAgICAgICAgb2I9MDsgLy8gbmljaHQgenVlY2tlbiwgdHJhZ2VuLCBpbml0aWFsaXNpZXJlbi4uLgorICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICBpZiAoKG1lbWJlcihpbnYyLCBmaWxlKSk9PS0xKSB7ICAKKyAgICAgICAgICAgICAgICBvYj0wOworICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICBjYXNlIFJFRlJFU0hfTk9ORTogLy8gd2lyZCBlbnRmZXJudCBuYWNoIGRlbSBlcnN0ZW4gY2xvbmVuISEhCisgICAgICAgIGNhc2UgUkVGUkVTSF9BTFdBWVM6CisgICAgICAgICAgLy8gc2NoYXVlbiBvYiBkZXIgR2VnZW5zdGFuZCBpbSBlbnZpcm9ubWVudCBsaWVndC4KKyAgICAgICAgICBpZiAoKGo9bWVtYmVyKGludjIsIGZpbGUpKSE9LTEpIHsKKyAgICAgICAgICAgIG9iPWludjFbal07IC8vIGludjEga2FubiBsZWVyIHNlaW4sIGFiZXIgZGFubiBpc3QgaW52MiBhdWNoIGxlZXIKKyAgICAgICAgICAgIGludjFbal09MDsgLy8gd2ljaHRpZyBmYWxscyBtZWhyZXJlIGdsZWljaGUgQWRkSXRlbXMKKyAgICAgICAgICAgIGludjJbal09MDsgLy8gPSAwIHNldHplbiB1bSBBcnJheSBrb3BpZXJlbiB6dSB2ZXJtZWlkZW4KKyAgICAgICAgICAgIGlmIChlbnZpcm9ubWVudCgpKSB7CisgICAgICAgICAgICAgIGlmIChlbnZpcm9ubWVudCgpID09IGVudmlyb25tZW50KG9iKSkKKyAgICAgICAgICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoKSwKKyAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShuYW1lKFdFUikpKyIgaGVidCAiK29iLT5uYW1lKFdFTikrIiBhdWYuXG4iKTsKKyAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCgpLGJyZWFrX3N0cmluZygKKyAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShuYW1lKFdFUikpKyIgbmltbXQgIitvYi0+bmFtZShXRU4pKyIgYXVzICIKKyAgICAgICAgICAgICAgICAgICAgK2Vudmlyb25tZW50KG9iKS0+bmFtZShXRU0pICsgIi4iLDc4KSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChvYikgeworICAgICAgICAgICAgb2ItPnJlbW92ZSgpOworICAgICAgICAgICAgaWYgKG9iKSBkZXN0cnVjdChvYik7CisgICAgICAgICAgfQorICAgICAgICAgIGlmIChjYXRjaChvYj1jbG9uZV9vYmplY3QoZmlsZSk7cHVibGlzaCkpIHJhaXNlX2Vycm9yKHNwcmludGYoCisgICAgICAgICAgICAiX2Nsb25lX2l0ZW1zKCk6ICVPIGRvZXMgbm90IGV4aXN0IG9yIGlzIG5vdCBsb2FkYWJsZVxuIiwgZmlsZSkpOworICAgICAgICAgIG9iLT5tb3ZlKHRoaXNfb2JqZWN0KCksIE1fTk9DSEVDSyk7CisgICAgICAgICAgc3dpdGNoKCByZWZyZXNoICkgeworICAgICAgICAgIGNhc2UgUkVGUkVTSF9OT05FOgorICAgICAgICAgICAgaXRlbXNbaV0gPSAwOyAvLyBTcGVpY2hlciBmcmVpbWFjaGVuCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICBjYXNlIFJFRlJFU0hfQUxXQVlTOgorICAgICAgICAgICAgaXRlbXNbaV1bUklURU1fT0JKRUNUXSA9IDA7IC8vIE9iamVrdCAidmVyZ2Vzc2VuIgorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGl0ZW1zW2ldW1JJVEVNX09CSkVDVF0gPSBvYjsKKyAgICAgICAgICB9CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6IG9iPTA7IC8vIG5pY2h0IHp1ZWNrZW4sIHRyYWdlbiwgaW5pdGlhbGlzaWVyZW4uLi4KKyAgICAgIH0KKyAgICB9IC8vIGlmIChwcm9wcyAuLi4pIGVsc2UgCisgICAgaWYgKG9iKSB7CisgICAgICBpZiAobWFwcGluZ3AocHJvcHMpKSB3YWxrX21hcHBpbmcocHJvcHMsIHN5bWJvbF9mdW5jdGlvbigiU2V0UHJvcCIsIG9iKSk7CisgICAgICAvLyBFaWdlbnRsaWNoIHdpbGwgbWFuIGhpZXIgc293YXMgd2llIGNvbW1hbmQoInp1ZWNrZSBzY2h3ZXJ0IikKKyAgICAgIC8vIG1hY2hlbiwgYWJlciBkYXMgaGFuZGxpbmcgZGVyIGlkJ3Mga2FubiBuaWNodCBzaWNoZXJzdGVsbGVuLAorICAgICAgLy8gZGFzcyBkZXIgTlBDIGRpZSByaWNodGlnZSBXYWZmZSBlcndpc2NodCwgZGVzaGFsYiBtYWNoZW4gd2lyCisgICAgICAvLyBkYXMgdHJhZ2VuIGhpZXIgdm9uIEhhbmQuCisgICAgICBpZiAobW9kZSAmIENMT05FX1dFQVIpIHsKKyAgICAgICAgaWYoIG1vZGUgJiBDTE9ORV9OT19DSEVDSyApIHsKKyAgICAgICAgICBvYmplY3QgKmFybW91cnM7CisgICAgICAgICAgb2ItPkRvVW53ZWFyKCk7IC8vIGV2dGwuIGRlbSBWb3JnYWVuZ2VyIGFibmVobWVuLgorICAgICAgICAgIFVzZUhhbmRzKG9iLCBvYi0+UXVlcnlQcm9wKFBfTlJfSEFORFMpKTsKKyAgICAgICAgICBhcm1vdXJzPVF1ZXJ5UHJvcChQX0FSTU9VUlMpKyh7IG9iIH0pOworICAgICAgICAgIFNldFByb3AoUF9BUk1PVVJTLCBhcm1vdXJzKTsKKyAgICAgICAgICBTZXRQcm9wKFBfVE9UQUxfQUMsIFF1ZXJ5UHJvcChQX1RPVEFMX0FDKStvYi0+UXVlcnlQcm9wKFBfQUMpKTsKKyAgICAgICAgICBvYi0+U2V0UHJvcChQX1dPUk4sIHRoaXNfb2JqZWN0KCkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGNvbW1hbmQoICJ0cmFnZSBcbiIrb2JqZWN0X25hbWUob2IpICk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGlmIChtb2RlICYgQ0xPTkVfV0lFTEQpIHsKKyAgICAgICAgaWYoIG1vZGUgJiBDTE9ORV9OT19DSEVDSyApIHsKKyAgICAgICAgICBvYi0+RG9VbndpZWxkKCk7IC8vIGV2dGwuIGRlbSBWb3JnYWVuZ2VyIGFibmVobWVuLiAKKyAgICAgICAgICBVc2VIYW5kcyhvYiwgb2ItPlF1ZXJ5UHJvcChQX05SX0hBTkRTKSk7CisgICAgICAgICAgU2V0UHJvcChQX1dFQVBPTiwgb2IpOworICAgICAgICAgIFNldFByb3AoUF9UT1RBTF9XQywgb2ItPlF1ZXJ5UHJvcChQX1dDKSk7CisgICAgICAgICAgb2ItPlNldFByb3AoUF9XSUVMREVELCB0aGlzX29iamVjdCgpKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBjb21tYW5kKCAienVlY2tlIFxuIitvYmplY3RfbmFtZShvYikgKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0gLy8gaWYgKG9iKSAKKyAgfSAvLyBmb3IgaQorICBpdGVtcy09KHsgMCB9KTsgLy8gUkVGUkVTSF9OT05FcyB2b24gbmljaHQgdW5pcXVlIE9iamVrdGVuIAorICBpZiAoIXNpemVvZihpdGVtcykpIGl0ZW1zPTA7IC8vIFNwZWljaGVyIHNwYXJlbi4uLgorICBTZXRQcm9wKFBfSVRFTVMsIGl0ZW1zKTsKKyAgU2V0KE5QQ19ORUVEU19JVEVNX0lOSVQsIDApOworfQorCitwdWJsaWMgdmFyYXJncyBvYmplY3QgQWRkSXRlbShtaXhlZCBmaWxlbmFtZSwgaW50IHJlZnJlc2gsIG1peGVkIHByb3BzKQoreworICAvLyBBdXMgQXJyYXkgZWluIEVsZW1lbnQgYXVzd2FlaGxlbgorICBpZiAocG9pbnRlcnAoZmlsZW5hbWUpKSAKKyAgICBmaWxlbmFtZSA9IGZpbGVuYW1lW3JhbmRvbShzaXplb2YoZmlsZW5hbWUpKV07CisgCisgIC8vIEtlaW4gU3RyaW5nPyAtPiBGZWhsZXIKKyAgaWYgKCFzdHJpbmdwKGZpbGVuYW1lKSl7CisgICAgcmFpc2VfZXJyb3IoIkFkZEl0ZW06IGZpbGVuYW1lIG9yIGFycmF5IG9mIGZpbGVuYW1lcyBleHBlY3RlZC5cbiIpOyAKKyAgfSBlbHNlIHsKKyAgICAvLyBQZmFkIG5vcm1pZXJlbiB1bmQgZXZlbnR1ZWxsIHZvcmhhbmRlbmVzICIuYyIgZW50ZmVybmVuCisgICAgZmlsZW5hbWUgPSBNQVNURVItPl9nZXRfcGF0aCgKKyAgICAgICAgICAgICAgICAgIGZpbGVuYW1lWzwyLi5dPT0iLmMiP2ZpbGVuYW1lPWZpbGVuYW1lWzAuLjwzXQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZmlsZW5hbWUsIj8iKTsgCisgICAgLy8gUHJvcGVydHkgc2V0emVuCisgICAgU2V0UHJvcChQX0lURU1TLCAoUXVlcnlQcm9wKFBfSVRFTVMpfHwoe30pKSsKKyAgICAgICAgICAgICAgICAgICAgICh7ICh7IDAsIGZpbGVuYW1lLCByZWZyZXNoLCBwcm9wcyB9KSB9KSk7CisKKyAgaWYgKGVudmlyb25tZW50KCkpIF9jbG9uZV9pdGVtcygpOworICB9CisgIHJldHVybiAwOworfQorCit2b2lkIHJlc2V0KCkKKy8vIGZ1ZXIgUkVGUkVTSF8gT2JqZWt0ZS4uLgoreworICBfY2xvbmVfaXRlbXMoKTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL25wYy9tb3ZpbmcuYyBiL3N0ZC9ucGMvbW92aW5nLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjA2ZTBkYQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9ucGMvbW92aW5nLmMKQEAgLTAsMCArMSwzOSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGxpdmluZy9tb3ZpbmcuYyAtLSBtb3Zpbmcgb2YgbGl2aW5nIG9iamVjdHMKKy8vCisvLyAkSWQkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK2luaGVyaXQgIi9zdGQvbGl2aW5nL21vdmluZyI7CisKKyNpbmNsdWRlIDxob29rLmg+CisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPG1vdmluZy5oPgorCisvLzxpbnR8PHN0cmluZ3xjbG9zdXJlPiogPiogR3VhcmRFeGl0KG9iamVjdCByb29tLCBpbnQgaG9va2lkLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3RyaW5nfGNsb3N1cmU+KiBoZGF0YSkKKy8veworLy99CisKK3Byb3RlY3RlZCBpbnQgX3JlZ19leGl0X2hvb2sob2JqZWN0IGRlc3QsIG9iamVjdCBvbGRlbnYpCit7CisgIGNsb3N1cmUgY2wgPSBzeW1ib2xfZnVuY3Rpb24oIkd1YXJkRXhpdCIsIHRoaXNfb2JqZWN0KCkpOworICBpZiAoY2wpCisgIHsKKyAgICBpZiAob2xkZW52KQorICAgICAgb2xkZW52LT5IVW5yZWdpc3RlckZyb21Ib29rKEhfSE9PS19FWElUX1VTRSwgY2wpOworICAgIHJldHVybiBkZXN0LT5IUmVnaXN0ZXJNb2RpZmllcihIX0hPT0tfRVhJVF9VU0UsIGNsKTsKKyAgfQorICByZXR1cm4gMDsKK30KKy8vIEtyYW1zIG5hY2ggZGVtIE1vdmUgbWFjaGVuIHVuZCBuZWJlbmJlaSB6dW0gVWViZXJzY2hyZWliZW4uCitwcm90ZWN0ZWQgdm9pZCBOb3RpZnlNb3ZlKG9iamVjdCBkZXN0LCBvYmplY3Qgb2xkZW52LCBpbnQgbWV0aG9kKQoreworICBfcmVnX2V4aXRfaG9vayhkZXN0LCBvbGRlbnYpOworICByZXR1cm4gOjpOb3RpZnlNb3ZlKGRlc3QsIG9sZGVudiwgbWV0aG9kKTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9ucGMvcHV0X2FuZF9nZXQuYyBiL3N0ZC9ucGMvcHV0X2FuZF9nZXQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YjcyY2Y0Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL25wYy9wdXRfYW5kX2dldC5jCkBAIC0wLDAgKzEsMzYgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBucGMvcHV0X2FuZF9nZXQuYy5jIC0tIEdlYmVuIHVuZCBuZWhtZW4gZnVlciBOUENzCisvLworLy8gJElkOiBwdXRfYW5kX2dldC5jIDYzNzEgMjAwNy0wNy0xNyAyMjo0Njo1MFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK2luaGVyaXQgInN0ZC9saXZpbmcvcHV0X2FuZF9nZXQiOworI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKwordm9pZCBnaXZlX25vdGlmeSggb2JqZWN0IG9iaiApCit7CisgICBtaXhlZCogbXNnOworICAgaWYgKHBvaW50ZXJwKG1zZz1RdWVyeVByb3AoUF9SRUpFQ1QpKSkgeworICAgICAgc3dpdGNoKG1zZ1swXSkgeworICAgICAgICAgY2FzZSBSRUpFQ1RfR0lWRToKKyAgICAgICAgICAgIHNheShtc2dbMV0pOworICAgICAgICAgICAgZ2l2ZV9vYmooIG9iaiwgdGhpc19wbGF5ZXIoKSApOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICBjYXNlIFJFSkVDVF9MSUdIVF9NT0RJRklFUjoKKyAgICAgICAgICAgIGlmIChvYmotPlF1ZXJ5UHJvcChQX0xJR0hUX01PRElGSUVSKSB8fAorICAgICAgICAgICAgICAgIG9iai0+UXVlcnlQcm9wKFBfTElHSFQpKSBicmVhazsKKyAgICAgICAgIGNhc2UgUkVKRUNUX0RST1A6CisgICAgICAgICAgICBzYXkobXNnWzFdKTsKKyAgICAgICAgICAgIGRyb3Bfb2JqKCBvYmogKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgY2FzZSBSRUpFQ1RfS0VFUDoKKyAgICAgICAgIGRlZmF1bHQ6IHNheShtc2dbMV0pOyAvKiBrZWVwIGl0ICovCisgICAgfQorICB9Cit9CmRpZmYgLS1naXQgYS9zdGQvbnBjL3NlcXVlbmNlci5jIGIvc3RkL25wYy9zZXF1ZW5jZXIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MGM4NWUzCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL25wYy9zZXF1ZW5jZXIuYwpAQCAtMCwwICsxLDEyNSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIG5wYy9zZXF1ZW5jZXIuYyAtLSBTY3JpcHRlIHVuZCBUcmlnZ2VyIGZ1ZXIgTlBDcyA6KQorLy8KKy8vICRJZDogc2VxdWVuY2VyLmMgNzUyNiAyMDEwLTA0LTAyIDAwOjAxOjI2WiBBcmF0aG9ybiAkCisKKy8vIHNlcTIuYworLy8gVmVyc2lvbiAyLjAgZGVzIFNlcXVlbmNlcnMgdm9uIERvbiBSdW1hdGEgMjguMDYuOTMKKy8vIAorLy8gU2lubjoKKy8vICAgQmVyZWl0c3RlbGx1bmcgdm9uIEZ1bmt0aW9uZW4sIGRkYW1pdCBlaW4gbnBjIG1laHJlcmUgQmVmZWhsZQorLy8gICBiZWkgRWludHJpdHQgZWluZXMgYmVzdGltbXRlbiBFcmVpZ25pc3NlcyBuYWNoZWluYW5kZXIKKy8vICAgYXV0b21hdGlzY2ggZHVyY2hmdWVocnQuCisvLworLy8gRXJlaWduaXNzZToKKy8vICAgVGVsbEV2ZW50OiBFcyB3aXJkIGV0d2FzIGluIGRlbSBSYXVtLCBpbiBkZW0gZGVyIG5wYyBzaWNoCisvLyAgICAgICAgICAgICAgYmVmaW5kZXQsIGdlc2FndC4KKy8vICAgR2l2ZUV2ZW50OiBFcyB3aXJkIGRlbSBucGMgZXR3YXMgZ2VnZWJlbi4KKy8vCisvLyBQcm9ncmFtbToKKy8vICAgRWluIFByb2dyYW1tIGlzdCBlaW5lIExpc3RlIHZvbiBCZWZlaGxlbi4KKy8vICAgSmVkZXIgQmVmZWhsIGlzdCBlaW5lIExpc3RlLCBiZXN0ZWhlbmQgYXVzIGVpbmVtIEtvbW1hbmRvCisvLyAgIHVuZCBlaW5lciBaYWhsLgorLy8gICBEYXMgS29tbWVuZG8gd2lyZCBhZWhubGljaCBkZXIgQmVmZWhsZSwgZGllIGVpbiBTcGllbGVyIGVpbi0KKy8vICAgZ2lidCBhdXNnZWZ1ZWhydC4KKy8vICAgVm9yc2ljaHQ6IE5QQ3Mga29lbm5lbiBudXIgZWluZW4gVGVpbCBkZXIgQmVmZWhsZSwgZGllIGVpbgorLy8gICBTcGllbGVyIGthbm4sIGRhZnVlciBhYmVyIGltbWVyICdlY2hvJyB1bmQgJ2Vtb3RlJy4KKy8vICAgRGllIFphaGwgZ2lidCBkaWUgQW56YWhsIGRlciBTZWt1bmRlbiBhbiwgaW4gZGVyIGRlciBuYWVjaHN0ZQorLy8gICBCZWZlaGwgYXVzZ2VmdWVocnQgd2lyZC4KKy8vCisvLyBGdW5rdGlvbmVuOgorLy8gICBSZWdpc3RlclRlbGwoIGZ1bmt0aW9uLCBwcm9ncmFtbSApCisvLyAgICAgV2VubiBkZW0gbnBjIGV0d2FzIGdlc2FndCB3aXJkLCBzbyB3aXJkIGRpZSBnZXNhZ3RlIE1lbGR1bmcKKy8vICAgICBhbiBkaWUgRnVua3Rpb24gdWViZXJnZWJlbi4gR2lidCBkaWUgRnVua3Rpb25lbiBuaWNodCAwCisvLyAgICAgenVydWVjaywgd2lyZCBkYXMgUHJvZ3JhbW0gZ2VzdGFydGV0LgorLy8gICBSZWdpc3RlckdpdmUoIGZ1bmt0aW9uLCBwcm9ncmFtbSApCisvLyAgICAgV2lyZCBkZW0gbnBjIGV0d2FzIGdlZ2ViZW4sIHNvIHdpcmQgZGFzIE9iamVrdCBhbiBkaWUKKy8vICAgICBGdW5rdGlvbiB1ZWJlcmdlYmVuLiBHaWJ0IGRpZSBGdW5rdGlvbiBuaWNodCAwIHp1cnVlY2ssIHNvCisvLyAgICAgd2lyZCBkYXMgUHJvZ3JhbW0gZ2VzdGFydGV0LgorLy8gICBMb2FkKCBwcm9ncmFtbSApCisvLyAgICAgU3RhcnRlIGRhcyBhbmdlZ2ViZW5lIFByb2dyYW1tLgorLy8KKy8vICAgZ2l2ZV9ub3RpZnkoKSBnaWJ0IGVpbmUgMSB6dXJ1ZWNrLCB3ZW5uIGRhcyBPYmpla3QgYWt6ZXB0aWVydAorLy8gICAgIHd1cmRlLiAoRXMgbXVzcyAtIGZhbGxzIGdld3VlbnNjaHQgLSBkYW5uIHZvbiBIYW5kIHp1cnVlY2gtCisvLyAgICAgZ2VnZWJlbiB3ZXJkZW4uIChnaXZlX29iaihvYix0aGlzX3BsYXllcigpKSkgaW4gZGVyIEZ1bmsuKQorLy8gICBtaXR0ZWxzIGFkZF9hY3Rpb24oKSBrYW5uIG1hbiBpbSBjcmVhdGUoKSBkcyBOUENzIGVpZ2VuZQorLy8gICAgIFZlcmJlbiBmdWVyIGRlbiBOUEMgZWluZnVlaHJlbi4KKy8vCisvLyBFcyBrYW5uIGltbWVyIG51ciBlaW5lIEZ1bmt0aW9uIChlZ2FsIG9iIFRlbGwgb2RlciBHaXZlKSBhbmdlbWVsZGV0CisvLyBzZWluLiBFcyBrYW5uIGltbWVyIG51ciBlaW4gUHJvZ3JhbW0gZ2xlaWNoemVpdGlnIGxhdWZlbi4KKy8vCisvLyBJZGVlbiB1bmQgQnVncmVwb3J0cyBhbiBSdW1hdGEKKworc3RyaW5nIGdpdmVmdW4sIHRlbGxmdW47CittaXhlZCAqcHJvZ3JhbTsKK2ludCBpc1J1bm5pbmc7CisKKy8vIHp1ciBzaWNoZXJoZWl0IG5pY2h0IHZvbiBhdXNzZW4gYXVmcnVmYmFyICEhISEKK3N0YXRpYyBzdHJpbmcgUmVnaXN0ZXJHaXZlKCBzdHJpbmcgZnVuLCBtaXhlZCBwcm9nICkKK3sKKyAgaWYoIGlzUnVubmluZyApIHJldHVybiAwOworICBwcm9ncmFtID0gcHJvZzsKKyAgdGVsbGZ1biA9IDA7CisgIHJldHVybiBnaXZlZnVuID0gZnVuOworfQorCisvLyB6dXIgc2ljaGVyaGVpdCBuaWNodCB2b24gYXVzc2VuIGF1ZnJ1ZmJhciAhISEhCitzdGF0aWMgc3RyaW5nIFJlZ2lzdGVyVGVsbCggc3RyaW5nIGZ1biwgbWl4ZWQgcHJvZyApCit7CisgIGlmKCBpc1J1bm5pbmcgKSByZXR1cm4gMDsKKyAgcHJvZ3JhbSA9IHByb2c7CisgIGdpdmVmdW4gPSAwOworICByZXR1cm4gdGVsbGZ1biA9IGZ1bjsKK30KKworLy8genVyIHNpY2hlcmhlaXQgbmljaHQgdm9uIGF1c3NlbiBhdWZydWZiYXIgISEhIQorc3RhdGljIHZvaWQgU3RhcnQoKQoreworICBpZiggaXNSdW5uaW5nIHx8ICFvYmplY3RwKHRoaXNfb2JqZWN0KCkpKSByZXR1cm47CisgIGlzUnVubmluZyA9IDE7CisgIGNhbGxfb3V0KCAibmV4dFN0ZXAiLCAwLCAwICk7Cit9CisKK3N0YXRpYyB2b2lkIExvYWQoIG1peGVkIHByb2cgKQoreworICBpZiggaXNSdW5uaW5nICkgcmV0dXJuOworICBwcm9ncmFtID0gcHJvZzsKKyAgU3RhcnQoKTsKK30KKworcHVibGljIHZvaWQgY2F0Y2hfdGVsbCggc3RyaW5nIHN0ciApCit7CisgIGlmKCBpc1J1bm5pbmcgfHwgcHJldmlvdXNfb2JqZWN0KCk9PXRoaXNfb2JqZWN0KCkpIHJldHVybjsKKyAgaWYoIHN0cmluZ3AodGVsbGZ1bikgJiYgY2FsbF9vdGhlciggdGhpc19vYmplY3QoKSwgdGVsbGZ1biwgc3RyICkgKQorICAgIFN0YXJ0KCk7Cit9CisKK2ludCBnaXZlX25vdGlmeSggb2JqZWN0IG9iICkKK3sKKyAgaWYoIGlzUnVubmluZyApIHJldHVybiAwOworICBpZiggc3RyaW5ncChnaXZlZnVuKSAmJiBjYWxsX290aGVyKCB0aGlzX29iamVjdCgpLCBnaXZlZnVuLCBvYiApICkKKyAgeworICAgIFN0YXJ0KCk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkIG5leHRTdGVwKCBpbnQgbGluZSApCit7CisgIGlmKCAhaXNSdW5uaW5nICkgcmV0dXJuOworICBpZiggbGluZSA+PSBzaXplb2YoIHByb2dyYW0gKSApCisgIHsKKyAgICBpc1J1bm5pbmcgPSAwOworICAgIHJldHVybjsKKyAgfQorICBjb21tYW5kKCBwcm9jZXNzX3N0cmluZyggcHJvZ3JhbVtsaW5lXVswXSApICk7CisgIGlmKCAhaXNSdW5uaW5nIHx8ICFvYmplY3RwKHRoaXNfb2JqZWN0KCkpICkgcmV0dXJuOworICBjYWxsX291dCggIm5leHRTdGVwIiwgcHJvZ3JhbVtsaW5lXVsxXSwgbGluZSsxICk7Cit9CisKK21peGVkIFF1ZXJ5UHJvZygpCit7CisgIHJldHVybiBwcm9ncmFtWzAuLl07Cit9IApkaWZmIC0tZ2l0IGEvc3RkL3BpbGUuYyBiL3N0ZC9waWxlLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGNmZTVlZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9waWxlLmMKQEAgLTAsMCArMSwxMjQgQEAKKy8vIEVpbiB0cmFuc3BhcmVudGVyIENvbnRhaW5lciwgaW4gZGVtIGRpZSBHZWdlbnN0YWVuZGUgbGFuZGVuLAorLy8gZGllIGVpbiBTcGllbGVyIGJlaSBzZWluZW0gVG9kIHZlcmxpZXJ0LgorLy8gU2lubiBkaWVzZXMgT2JqZWt0ZXMgaXN0IGVzLCBkYXMgaW52ZW5vdHJ5IGVpbmVzIFJhdW1lcyBrbGVpbgorLy8genUgaGFsdGVuIHVuZCBkaWUga29zdGVuIGltIGluaXQoKSBlaW5lcyBTcGllbGVycyB6dSBzZW5rZW4uCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworaW5oZXJpdCAic3RkL2NvbnRhaW5lciI7CisKKy8vIFNwaWVsZXJoYXVmZW4gc29sbGVuIHNpY2ggZXR3YXMgYW5kZXJzIGFscyBOUEMtaGF1ZmVuIHZlcmhhbHRlbi4KK3ByaXZhdGUgbm9zYXZlIHN0YXR1cyBzcGllbGVyaGF1ZmVuOworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorCit2b2lkIGNyZWF0ZSgpIHsKKwlzdHJpbmcgdm9uOworCWlmIChvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSA9PSBfX0ZJTEVfX1swLi48M10pIHsKKwkgIHNldF9uZXh0X3Jlc2V0KC0xKTsKKwkgIHJldHVybjsKKwl9ICAgCisJaWYoICFjbG9uZXAodGhpc19vYmplY3QoKSkgKSByZXR1cm47CisJOjpjcmVhdGUoKTsKKwl2b24gPSAoc3RyaW5nKXByZXZpb3VzX29iamVjdCgpLT5RdWVyeVByb3AoUF9QSUxFX05BTUUpOworCVNldFByb3AoIFBfUElMRV9OQU1FLCAiXG5oYXVmZW4gIit2b24gKTsKKwlzcGllbGVyaGF1ZmVuID0gKGludClwcmV2aW91c19vYmplY3QoKS0+SXNQbGF5ZXJDb3Jwc2UoKTsKKworCUFkZElkKCAoeyJoYXVmZW4iLCJrcmVtcGVsIiwia2x1ZW5nZWwiLCJnZWdlbnN0YWVuZGUifSkgKTsKKwlBZGRJZCggUXVlcnlQcm9wKFBfUElMRV9OQU1FKSApOworCVNldFByb3AoIFBfTkFNRSwgIkhhdWZlbiBLcmVtcGVsIiApOworCVNldFByb3AoIFBfR0VOREVSLCBNQUxFICk7CisJU2V0UHJvcCggUF9JTkZPLCAiRGllc2UgR2VnZW5zdGFlbmRlIGdlaG9lcnRlbiBlaW5tYWwgIiArIHZvbiArICIuXG4iICk7CisJU2V0UHJvcCggUF9MT05HLCBicmVha19zdHJpbmcoIkR1IGJldHJhY2h0ZXN0IGVpbmVuIEhhdWZlbiwgZGVyIGF1cyBlaW5lciB2b24gTGVpY2hlbnJlc3RlbiB6dXNhbW1lbmdlYmFja2VuZW4gTWVuZ2UgZGl2ZXJzZXIgR2VnZW5zdGFlbmRlIGJlc3RlaHQuIFp1bSBHbHVlY2sgaXN0IHZvbiBkZXIgTGVpY2hlIG5pY2h0IG1laHIgZ2VudWcgdWVicmlnLCB1bSBFa2VsZ2VmdWVobGUgenUgd2Vja2VuLiBHYW56IGltIEdlZ2VudGVpbDogRGlyIGp1Y2t0IGVzIGVpbiB3ZW5pZyBpbiBkZW4gRmluZ2VybiwgRGljaCBhbiBkaWVzZW0gSGF1ZmVuIHp1IGJlZGllbmVuLiBBYmVyIG1hbiBrYW5uIHNpY2ggbmllIGdhbnogc2ljaGVyIHNlaW4sIG9iIG5pY2h0IGRvY2ggZWluIEZsdWNoIGF1ZiBkZW4gRGluZ2VuIGxhc3RldC4gVmllbGxlaWNodCBoYXQgZGVyIHZlcnNjaGllZGVuZSBCZXNpdHplciBzaWUgYXVjaCBqZW1hbmRlbSB2ZXJlcmJ0PyBBbmRlcmVyc2VpdHMsIHdlbm4gZ2VyYWRlIG5pZW1hbmQgZ3Vja3QgLi4uXG4iICkgKTsKKwlBZGREZXRhaWwoICh7ImZldHplbiIsImxlaWNoZSIsImxlaWNoZW50ZWlsZSJ9KSwgIk1pdCBibG9zc2VuIEF1Z2VuIGthbm4gbWFuIG5pY2h0IG1laHIgdmllbCBlcmtlbm5lbiwgYWJlciBlaW5pZ2UgRmV0emVuIGRldXRlbiBkYXJhdWYgaGluLCBkYXNzIGRpZSBTYWNoZW4gdm9uICIrdm9uKyIgc3RhbW1lbi5cbiIgKTsKKwlBZGREZXRhaWwoICh7ImVrZWwiLCJla2VsZ2VmdWVobGUifSksICJFcyBpc3QgbmljaHQgbWVociBnZW51ZyBkYSwgdW0gd2VsY2hlIHp1IHdlY2tlbi5cbiIgKTsKKwlBZGREZXRhaWwoICJtZW5nZSIsICJWaWVsZSBrbGVpbmUgRmV0emVuLCBkaWUgYW4gZGVuIEdlZ2Vuc3RhZW5kZW4ga2xlYmVuLlxuIiApOworCUFkZERldGFpbCggImZsdWNoIiwgIkRlbSBBbnNjaGVpbiBuYWNoIGxhc3RldCBhdWYgZGVuIFNhY2hlbiBrZWluIEZsdWNoLCBhYmVyIHdlciB3ZWlzcyAuLi4/XG4iICk7CisJY2FsbF9vdXQoICJtZXJnZV9waWxlIiwgMSApOworfQorCittaXhlZCBfcXVlcnlfc2hvcnQoKSB7CisJaW50IHN6ID0gc2l6ZW9mKGFsbF9pbnZlbnRvcnkoKSk7CisJaWYoIHN6PT0wICkgeworCQljYWxsX291dCgicmVtb3ZlIiwwLDEpOyAvLyBmYWxsYmFjaywgd2VubiBpbmhhbHQgYXVmIHVuZXJ3YXJ0ZXRlIHdlaXNlIHZlcnNjaHdpbmRldAorCQlyZXR1cm4gMDsKKwl9IGVsc2UgaWYoIHN6PDEwICkgeworCQlyZXR1cm4gIkVpbiBrbGVpbmVyIEhhdWZlbiBLcmVtcGVsIjsKKwl9IGVsc2UgaWYoIHN6PDMwICkgeworCQlyZXR1cm4gIkVpbiBIYXVmZW4gS3JlbXBlbCI7CisJfSBlbHNlIHsKKwkJcmV0dXJuICJFaW4gZ3Jvc3NlciBIYXVmZW4gS3JlbXBlbCI7CisJfQorICByZXR1cm4gMDsKK30KKworLy8gUHJ1ZWZ0LCBvYiB3aXIgaW4gZWluZW4gU3BpZWxlciBnZW1vdnQgd2VyZGVuIHNvbGxlbi4KKy8vIExpZWZlcnQgcGFzc2VuZGVzIE1vdmVyZXN1bHQsIGFuc29uc3RlbiAwLgorcHJvdGVjdGVkIGludCBQcmV2ZW50TW92ZShvYmplY3QgZGVzdCwgb2JqZWN0IG9sZGVudiwgaW50IG1ldGhvZCkgeworICAgIGlmKCAhb2JqZWN0cChkZXN0KSApIHJldHVybiAwOworICAgIGlmKCBtZXRob2QgJiBNX05PQ0hFQ0sgKSByZXR1cm4gMDsKKyAgICBpZiggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShkZXN0KSApIHsKKyAgICAgIHJldHVybiBNRV9OT1RfQUxMT1dFRDsKKyAgICAvLyBkZWZhdWx0IG1lbGR1bmcgaW4gcHV0X2FuZF9nZXQ6cGljaworICAgIC8vIElERUU6IGltIHNwaWVsZXIgcGVyIGhvb2sgZWluZSBhbmRlcmUgbWVsZHVuZyB1bnRlcmJyaW5nZW4KKyAgICB9CisgICAgcmV0dXJuIDo6UHJldmVudE1vdmUoZGVzdCwgb2xkZW52LCBtZXRob2QpOworfQorCisvLyBTb3JndCBkYWZ1ZXIsIGRhc3MgaW0gTlBDIHNpY2ggZGVyIEhhdWZlbiBzZWxic3QgemVyc3RvZXJ0LgorcHJvdGVjdGVkIHZvaWQgTm90aWZ5TW92ZShvYmplY3QgZGVzdCwgb2JqZWN0IG9sZGVudiwgaW50IG1ldGhvZCkgeworICAgIGlmKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGRlc3QpKSB7CisJbG9nX2ZpbGUoICJQSUxFLmxvZyIsIGR0aW1lKHRpbWUoKSkgKyAiOiBwaWxlIGluICIgCisJICAgICsgZGVzdC0+cXVlcnlfcmVhbF9uYW1lKCkgKyAiIGdlbGFuZGV0LlxuIiApOworICAgIH0KKyAgICBpZiggbGl2aW5nKGRlc3QpICkgeworCWZpbHRlcl9vYmplY3RzKCBhbGxfaW52ZW50b3J5KCksICJtb3ZlIiwgZGVzdCwgTV9TSUxFTlQgfCBNX05PQ0hFQ0sgKTsKKwkvLyBOUENzIGVyd2FydGVuIG5pY2h0LCBkYXNzIGRpbmdlIGltIG1vdmUgdmVyc2Nod2luZGVuLCBkZXNoYWxiCisJLy8gYWJ3YXJ0ZW4KKwljYWxsX291dCggInJlbW92ZSIsIDAsIDEgKTsKKyAgICB9CisgICAgcmV0dXJuIDo6Tm90aWZ5TW92ZShkZXN0LCBvbGRlbnYsIG1ldGhvZCk7Cit9CisKKy8vIHdlbm4gbnVyIG5vY2ggZWluIE9iamVrdCBpbSBIYXVmZW4gaXN0LCBzb2xsIGRpZXNlciB6ZXJzdG9lcnQgd2VyZGVuLgorcHVibGljIHZvaWQgTm90aWZ5TGVhdmUoIG9iamVjdCBvYiwgb2JqZWN0IGRlc3QgKSB7CisJaWYoIHNpemVvZihhbGxfaW52ZW50b3J5KCkpPjEgKSByZXR1cm47CisJY2FsbF9vdXQoICJyZW1vdmUiLCAwLCAxICk7IC8vIHZlcnpvZWdlcm4sIHVtIHByZXBhcmVfZGVzdHJ1Y3QgZ25hZWRpZyB6dSBzdGltbWVuCit9CisKKy8vIGRpdG8gZnVlcnMgbG9lc2NoZW4KK3B1YmxpYyB2b2lkIE5vdGlmeVJlbW92ZSggb2JqZWN0IG9iICkgeworICAgIE5vdGlmeUxlYXZlKCBvYiwgMCk7Cit9CisKKy8vIEhhdWZlbiwgZGllIHZvbiB6d2VpbWFsIGRlbSBzZWxiZW4gTlBDIGtvbW1lbiwgd2VyZGVuCisvLyB6dXNhbW1lbmdlbGVndAordm9pZCBtZXJnZV9waWxlKCkgeworCW9iamVjdCogb3RoZXIgPSBmaWx0ZXJfb2JqZWN0cygKKwkJYWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSAtICh7IHRoaXNfb2JqZWN0KCkgfSksCisJCSJpZCIsCisJCVF1ZXJ5UHJvcCggUF9QSUxFX05BTUUgKQorCSk7CisJaWYoICFzaXplb2Yob3RoZXIpICkgcmV0dXJuOworCWZpbHRlcl9vYmplY3RzKCBhbGxfaW52ZW50b3J5KCksICJtb3ZlIiwgb3RoZXJbMF0sIE1fU0lMRU5UIHwgTV9OT0NIRUNLICk7CisJcmVtb3ZlKCk7Cit9CisKK3ZvaWQgcmVzZXQoKSB7CisgIC8vIHdlbm4gZXMgZWluIE5QQy1IYXVmZW4gaXN0LCB3ZXJkZW4gR2VnZW5zdGFlbmRlLCBkaWUgb2VmdGVyIGFscyAzbWFsCisgIC8vIHZvcmtvbW1lbiwgemVyc3RvZXJ0LiBTY2hyYWVua3QgZGllIE9iamVrdGZsdXQgYW4gU3RlbGxlbiBlaW4sIHdvIE5QQworICAvLyBpaHJlbiBLcmFtIG5pY2h0IG1pdCBBZGRJdGVtIGNsb25lbi4KKyAgaWYgKCFzcGllbGVyaGF1ZmVuKQorICAgIHJlbW92ZV9tdWx0aXBsZSgzKTsKKyAgOjpyZXNldCgpOworICAvLyB3ZW5uIG51ciBub2NoIHVuc2ljaHRiYXJlIGl0ZW1zIGltIEhhdWZlbjogYXVmbG9lc2VuCisgIGlmICghc2l6ZW9mKGZpbHRlcihhbGxfaW52ZW50b3J5KCksIGZ1bmN0aW9uIGludCAob2JqZWN0IG8pCisgICAgICAgICAgeyByZXR1cm4gIW8tPnNob3J0KCk7fSApKSkKKyAgICByZW1vdmUoMSk7CisKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9iYXNlLmMgYi9zdGQvcGxheWVyL2Jhc2UuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzlhNmUxCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9iYXNlLmMKQEAgLTAsMCArMSw0MzU1IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL2Jhc2UuYyAtLSB0aGUgYmFzaWMgcGxheWVyIG9iamVjdAorLy8KKy8vICRJZDogYmFzZS5jIDk0NjcgMjAxNi0wMi0xOSAxOTo0ODoyNFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDxzeXNfZGVidWcuaD4KKyNpbmNsdWRlIDxyZWdleHAuaD4KKyNpbmNsdWRlIDxpbnB1dF90by5oPgorI2luY2x1ZGUgPGxvZ2dpbmcuaD4KKyNpbmNsdWRlIDx3ZXJsaXN0ZS5oPgorI2luY2x1ZGUgPHRpbWUuaD4KKyNpbmNsdWRlIDxlcnJvcmQuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxtb25leS5oPgorCitpbmhlcml0ICIvc3RkL2hvb2tfcHJvdmlkZXIiOworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvcmVzdHJpY3Rpb25zIjsKK2luaGVyaXQgIi9zdGQvbGl2aW5nL2F0dHJpYnV0ZXMiOworaW5oZXJpdCAiL3N0ZC9saXZpbmcvcHV0X2FuZF9nZXQiOworaW5oZXJpdCAiL3N0ZC9saXZpbmcvY2xvdGhpbmciOworaW5oZXJpdCAiL3N0ZC90aGluZy9wcm9wZXJ0aWVzIjsKK2luaGVyaXQgIi9zdGQvcGxheWVyL3V0aWwiOworaW5oZXJpdCAiL3N0ZC90aGluZy9sYW5ndWFnZSI7Citpbmhlcml0ICIvc3RkL3BsYXllci90cmF2ZWwiOworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvY29tYmF0IjsKK2luaGVyaXQgIi9zdGQvcGxheWVyL2Rlc2NyaXB0aW9uIjsKK2luaGVyaXQgIi9zdGQvcGxheWVyL21vdmluZyI7Citpbmhlcml0ICIvc3RkL3BsYXllci9saWZlIjsKK2luaGVyaXQgIi9zdGQvcGxheWVyL2NvbW0iOworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvdmlld2NtZCI7Citpbmhlcml0ICIvc3RkL3BsYXllci9tb25leWhhbmRsZXIiOworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvY29tbWFuZCI7Citpbmhlcml0ICIvc3RkL2xpdmluZy9za2lsbF9hdHRyaWJ1dGVzIjsKK2luaGVyaXQgIi9zdGQvbGl2aW5nL2xpZ2h0IjsKK2luaGVyaXQgIi9zdGQvcGxheWVyL3NraWxscyI7Citpbmhlcml0ICIvc3RkL3BsYXllci9xdWVzdHMiOworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvcG90aW9uIjsKK2luaGVyaXQgIi9zdGQvcGxheWVyL3NvdWwiOworaW5oZXJpdCAiL3N0ZC9tb3JlIjsKK2luaGVyaXQgIi9zdGQvdXNlcl9maWx0ZXIiOworaW5oZXJpdCAiL3NlY3VyZS90ZWxuZXRuZWciOworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvZ3VpZGUiOworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvcmVwdXRhdGlvbiI7Citpbmhlcml0ICIvc3RkL3BsYXllci9wcm90b2NvbHMvZ21jcCI7Citpbmhlcml0ICIvc3RkL2xpdmluZy9oZWxwZXJzIjsKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwbGF5ZXIvc2tpbGxzLmg+CisjaW5jbHVkZSA8cGxheWVyL2dtY3AuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwbGF5ZXIuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8dWRwLmg+CisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8YW5zaS5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGxpdmluZy5oPgorI2luY2x1ZGUgPGF0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDx0ZXJtaW5hbC5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDxwYWdlci5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgIi9zZWN1cmUvcXVlc3RtYXN0ZXIuaCIKKyNpbmNsdWRlICIvc2VjdXJlL2xlcG1hc3Rlci5oIgorI2luY2x1ZGUgPGV2ZW50cy5oPgorCisjdW5kZWYgTkFNRSAvKiBERUZJTkVEIEJZIFVEUC5IOyBCQUQgTkFNRSBDTEFTSCA6KCAqLworI2RlZmluZSBOQU1FKHdobykgY2FwaXRhbGl6ZShnZXR1aWQod2hvKSkKKworbWFwcGluZyBhdXRvbG9hZDsgICAgICAgICAgIC8qIGF1dG9sb2FkLW1hcHBpbmcgKi8KK2ludCBoY19wbGF5OworCitwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIGF1dG9sb2FkX3Jlc3Q7Citwcml2YXRlIG5vc2F2ZSBzdHJpbmcgICphdXRvbG9hZF9lcnJvcjsKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyByZWFsaXA7IAorCitwcml2YXRlIG5vc2F2ZSBzdHJpbmcgcGFzc3c7ICAgICAgICAvKiB0ZW1wb3JhcmlseSBmb3IgcGFzc3dvcmQgY2hhbmdlICovCitwcml2YXRlIG5vc2F2ZSBzdHJpbmcgcGFzc3dvbGQ7ICAgICAvKiB0ZW1wb3JhcmlseSBmb3IgcGFzc3dvcmQgY2hhbmdlICovCisKKy8vIEhCLVphZWhsZXIuIFdlbm4gMCBlcnJlaWNodCB3aXJkLCB3aXJkICBlaW4gVGVsbmV0IFRNIFBha2V0IGFscyBLZWVwLUFsaXZlCisvLyBhbiBkZW4gQ2xpZW50IGdlc2VuZGV0IHVuZCBkZXIgQ291bnRlciB3aWVkZXIgYXVmIGhvY2hnZXNldHp0LiAKKy8vIFdlbm4gPT0gMCwgaXN0IGRhcyBLZWVwLUFsaXZlIGFiZ2VzY2hhbHRldC4KK3ByaXZhdGUgaW50IHRlbG5ldF90bV9jb3VudGVyOworCitub3NhdmUgc3RyaW5nIGRlZmF1bHRfaG9tZTsgLyogV2hlcmUgdG8gbW92ZSB1cyBpZiB3ZSBkb250IGhhdmUgYSBob21lIHNldCAqLworCitub3NhdmUgaW50IG5kZWFkX2xhc3R0aW1lOworbm9zYXZlIG1peGVkIG5kZWFkX2xvY2F0aW9uOworbm9zYXZlIHN0cmluZyBuZGVhZF9sX2ZpbGVuYW1lOworbm9zYXZlIGludCBuZGVhZF9jdXJyZW50bHk7Citub3NhdmUgaW50IG5kZWFkX25leHRfY2hlY2s7Citub3NhdmUgb2JqZWN0ICpoYl9vYnM7CisKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyBkZWZhdWx0X3ByYXlfcm9vbTsKKworbm9zYXZlIG1peGVkIGVudl9uZGVhZF9pbmZvOworCitzdGF0aWMgaW50IF9zZXRfaW52aXMoaW50IGEpOworc3RhdGljIHN0cmluZyBfc2V0X3R0eShzdHJpbmcgc3RyKTsKK3N0YXRpYyBtaXhlZCBfc2V0X2ZyYXRlcm5pdGFzZG9ub2FyY2htYWdvcnVtKG1peGVkIGFyZyk7CisKKworc3RhdGljIHN0cmluZyBhbF90b190aXRsZShpbnQgYSk7CisKK3N0YXRpYyB2b2lkIG5kZWFkX3Jldml2ZSgpOworCitzdGF0aWMgaW50IHdlZ21lbGR1bmcoc3RyaW5nIHBsYXllcik7CisKK2ludCBxdWl0KCk7Cit2b2lkIHNhdmVfbWUobWl4ZWQgdmFsdWVfaXRlbXMpOwordmFyYXJncyBpbnQgcmVtb3ZlKG1peGVkIGFyZyk7CittaXhlZCBSYWNlRGVmYXVsdChzdHJpbmcgYXJnKTsKKworLyoqIFNldHp0IERlZmF1bHR3ZXJ0ZSB2b3IgZGVtIExhZGVuIGRlcyBTYXZlZmlsZXMuCisgICAgTnVyIGRpZSBXZXJ0ZSBibGVpYmVuIHNwYWV0ZXIgdWVicmlnLCBkaWUgTklDSFQgYXVzIGRlbSBTYXZlZmlsZSBnZWxhZGVuCisgICAgd2VyZGVuIHVuZCBkaWVzZSBoaWVyIGVyc2V0emVuLgorICAgIEF1c3NlcmRlbSBrYW5uIG1hbiBoaWVyIG5pY2h0IG1pdCBkZW4gV2VydGVuIGF1cyBkZW4gU2F2ZWZpbGVzIGFyYmVpdGVuLgorICAgIEhpZXJ6dSBtdXNzIG1hbiB1cGRhdGVzX2FmdGVyX3Jlc3RvcmUoKSB2ZXJ3ZW5kZW4uCisqLworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgaWYoUXVlcnlQcm9wKFBfTEVWRUwpKSAKKyAgeworICAgIHJldHVybjsgLy8gZGFyZiBudXIgRUlOTUFMIGdlbWFjaHQgd2VyZGVuCisgIH0KKyAgY2FsbF9vdXQoImNoZWNrQ29uc2lzdGVuY3kiLCAwKTsKKworICBuZGVhZF9uZXh0X2NoZWNrPU5FVERFQURfQ0hFQ0tfVElNRTsKKyAgbmRlYWRfbGFzdHRpbWU9MDsKKyAgbmRlYWRfbG9jYXRpb249MDsKKyAgbmRlYWRfbF9maWxlbmFtZT0wOworICBuZGVhZF9jdXJyZW50bHk9MDsKKyAgbmRlYWRfbmV4dF9jaGVjaz0wOworICBoY19wbGF5PTA7CisgIAorICBjb21tYW5kOjpjcmVhdGUoKTsKKyAgcHJvcGVydGllczo6Y3JlYXRlKCk7CisgIGRlc2NyaXB0aW9uOjpjcmVhdGUoKTsKKyAgbGlnaHQ6OmNyZWF0ZSgpOworICBhdHRyaWJ1dGVzOjpjcmVhdGUoKTsKKyAgY2xvdGhpbmc6OmNyZWF0ZSgpOworICBjb21iYXQ6OmNyZWF0ZSgpOworICBsaWZlOjpjcmVhdGUoKTsKKyAgY29tbTo6Y3JlYXRlKCk7CisgIHZpZXdjbWQ6OmNyZWF0ZSgpOworICBxdWVzdHM6OmNyZWF0ZSgpOworICByZXN0cmljdGlvbnM6OmNyZWF0ZSgpOworICBtb3Zpbmc6OmNyZWF0ZSgpOworICB0cmF2ZWw6OmNyZWF0ZSgpOworICBza2lsbHM6OmNyZWF0ZSgpOworICAgCisgIFNldFByb3AoUF9MRVZFTCwgLTEpOworICBTZXQoUF9MRVZFTCwgU0FWRXxTRUNVUkVELCBGX01PREVfQVMpOworICBTZXQoUF9HSE9TVCwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0UHJvcChQX1NDUkVFTlNJWkUsIC0xKTsKKyAgU2V0KFBfU0NSRUVOU0laRSwgU0FWRSxGX01PREVfQVMpOworICBTZXQoUF9NT1JFX0ZMQUdTLCBTQVZFLCBGX01PREVfQVMpOworICBTZXRQcm9wKFBfV0VJR0hUX1BFUkNFTlQsMTAwKTsKKyAgU2V0UHJvcChQX0xPTkcsIDApOworICBTZXRQcm9wKFBfVElUTEUsICJkZXIgaG9mZm51bmdzdm9sbGUgQW5mYWVuZ2VyIik7CisgIFNldFByb3AoUF9BTElHTiwgMCk7CisgIFNldFByb3AoUF9HRU5ERVIsIE5FVVRFUik7CisgIFNldChQX0dFTkRFUiwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0UHJvcChQX1RUWSwgInZ0MTAwIik7CisgIFNldChQX1RUWSwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0UHJvcChQX1dFSUdIVCwgNzUwMDApOworICBTZXRQcm9wKFBfTUFYX0hQLDUwKTsKKyAgU2V0UHJvcChQX01BWF9TUCw1MCk7CisgIFNldFByb3AoUF9NQVhfRk9PRCwxMDApOworICBTZXRQcm9wKFBfTUFYX0RSSU5LLDEwMCk7CisgIFNldFByb3AoUF9NQVhfQUxDT0hPTCwxMDApOworICBTZXQoIFBfV0lNUFksIDIwLCBGX1ZBTFVFKTsKKworICBTZXRQcm9wKFBfSEFORFMsICh7IiBtaXQgYmxvc3NlbiBIYWVuZGVuIiwgMzB9KSk7CisgIFNldChQX0hBTkRTLCBTQVZFLCBGX01PREVfQVMpOworICBTZXRQcm9wKFBfTUFYX0hBTkRTLCAyKTsKKworICBTZXQoUF9NQVJSSUVELCBTQVZFLCBGX01PREVfQVMpOworICBTZXQoUF9FWFRSQV9MT09LLCBTQVZFLCBGX01PREVfQVMpOworICBTZXQoUF9TSE9XX0VYSVRTLCBTQVZFLCBGX01PREVfQVMpOworICBTZXQoUF9TSE9XX0VYSVRTLCAxKTsKKyAgU2V0KFBfV0FOVFNfVE9fTEVBUk4sIFNBVkUsIEZfTU9ERV9BUyk7CisgIFNldChQX0NBTl9GTEFHUywgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfVEVTVFBMQVlFUiwgU0FWRXxQUk9URUNURUQsIEZfTU9ERV9BUyk7CisgIFNldChQX0FMTE9XRURfU0hBRE9XLCBTQVZFfFNFQ1VSRUQsIEZfTU9ERV9BUyk7CisgIFNldChQX1NFQ09ORCwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfSU5WSVMsIFNBVkUsIEZfTU9ERV9BUyk7CisgIFNldChQX1JFQURfTkVXUywgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfU1RBUlRfSE9NRSwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfUFJBWV9ST09NLCBTQVZFLCBGX01PREVfQVMpOworICBTZXQoUF9NQUlMQUREUiwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfSE9NRVBBR0UsIFNBVkUsIEZfTU9ERV9BUyk7CisgIFNldChQX0lDUSwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfTUVTU0VOR0VSLCBTQVZFLCBGX01PREVfQVMpOworICBTZXQoUF9MT0NBVElPTiwgU0FWRSwgRl9NT0RFX0FTKTsKKworICBTZXQoUF9OT19BU0NJSV9BUlQsIFNBVkUsIEZfTU9ERV9BUyk7CisKKyAgU2V0KFBfVklTVUFMQkVMTCwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfQ0FSUklFRF9WQUxVRSwgU0FWRSwgRl9NT0RFX0FTKTsKKworICBTZXQoUF9QUk9NUFQsICI+ICIpOworICBTZXQoUF9QUk9NUFQsIFNBVkUsIEZfTU9ERV9BUyk7CisgIFNldChQX0NBTExFRF9GUk9NX0lQLCBTQVZFLCBGX01PREVfQVMpOworICBTZXQoUF9JTkZPUk1NRSxTQVZFfFBST1RFQ1RFRCxGX01PREVfQVMpOworICBTZXQoUF9XQUlURk9SLFNBVkV8UFJPVEVDVEVELEZfTU9ERV9BUyk7CisgIFNldChQX1dBSVRGT1JfUkVBU09OLFNBVkV8UFJPVEVDVEVELEZfTU9ERV9BUyk7CisgIFNldChQX0RBSUxZX1BMQVlUSU1FLFNBVkV8UFJPVEVDVEVELEZfTU9ERV9BUyk7CisgIFNldChQX05FVERFQURfRU5WLCBQUk9URUNURUR8Tk9TRVRNRVRIT0QsIEZfTU9ERV9BUyk7CisgIAorICBhdXRvbG9hZCA9IChbXSk7CisgIGF1dG9sb2FkX3Jlc3QgPSAoW10pOworICBhdXRvbG9hZF9lcnJvciA9ICh7fSk7CisgIFNldFByb3AoUF9BUlRJQ0xFLDApOworICBTZXQoUF9HVUlMRCxTQVZFLEZfTU9ERV9BUyk7CisgIFNldChQX0dVSUxEX1RJVExFLFNBVkUsRl9NT0RFX0FTKTsKKyAgU2V0KFBfR1VJTERfTEVWRUwsU0FWRSxGX01PREVfQVMpOworICBTZXQoUF9HVUlMRF9SQVRJTkcsU0FWRSxGX01PREVfQVMpOworICBTZXQoUF9ORVdTS0lMTFMsU0FWRSxGX01PREVfQVMpOworICBTZXQoUF9ORUVERURfUVAsUkVRX1FQKTsKKyAgU2V0KFBfREVBRFMsMCk7CisgIFNldChQX0RFQURTLCBOT1NFVE1FVEhPRCxGX1NFVF9NRVRIT0QpOworICBTZXQoUF9ERUFEUyxTQVZFfFBST1RFQ1RFRHxTRUNVUkVELEZfTU9ERV9BUyk7CisgIFNldChQX0xBU1RfTE9HSU4sLTEpOworICBTZXQoUF9MQVNUX0xPR0lOLCBOT1NFVE1FVEhPRCxGX1NFVF9NRVRIT0QpOworICBTZXQoUF9MQVNUX0xPR0lOLFNBVkV8UFJPVEVDVEVEfFNFQ1VSRUQsRl9NT0RFX0FTKTsKKyAgU2V0KFBfTEFTVF9MT0dPVVQsLTEpOworICBTZXQoUF9MQVNUX0xPR09VVCwgTk9TRVRNRVRIT0QsRl9TRVRfTUVUSE9EKTsKKyAgU2V0KFBfTEFTVF9MT0dPVVQsU0FWRXxQUk9URUNURUR8U0VDVVJFRCxGX01PREVfQVMpOworICBTZXQoUF9DTE9DS01TRyxTQVZFLEZfTU9ERV9BUyk7CisgIFNldChQX1RJTUVaT05FLFNBVkUsRl9NT0RFX0FTKTsKKyAgU2V0KFBfU0hPV0VNQUlMLFNBVkUsRl9NT0RFX0FTKTsKKyAgU2V0KFBfTEFTVF9RVUlULFNBVkV8UFJPVEVDVEVEfFNFQ1VSRUQsRl9NT0RFX0FTKTsKKworICBTZXQoUF9DTVNHLCAwLCBGX01PREUpOyAvLyB0byBjbGVhbiBvdXQgdGhlIG9sZCBjbG9uZSBtZXNzYWdlcworICBTZXQoUF9ETVNHLCAwLCBGX01PREUpOworICBTZXQoUF9DTE9ORV9NU0csIFNBVkUsIEZfTU9ERSk7CisgIFNldFByb3AoUF9DTE9ORV9NU0csICJ6YXViZXJ0IGV0d2FzIGhlcnZvciIpOworICBTZXQoUF9ERVNUUlVDVF9NU0csIFNBVkUsIEZfTU9ERSk7CisgIFNldFByb3AoUF9ERVNUUlVDVF9NU0csICJ2ZXJzY2h3aW5kZXQgZWluZmFjaCIpOworCisgIFNldChQX0ZBTywgU0FWRXxTRUNVUkVELCBGX01PREVfQVMpOworICBTZXQoUF9GQU9fUE9SVEFMUywgU0FWRSwgRl9NT0RFX0FTKTsKKworICBTZXRQcm9wKFBfTkVXQklFX0dVSURFLDApOworICBTZXQoUF9ORVdCSUVfR1VJREUsU0FWRSxGX01PREVfQVMpOworCisgIC8vVE9ETzogUmVtb3ZlIC0gUHJvcGVydHkgaXN0IG5vdCBuZWVkZWQgYW55IG1vcmUuCisgIFNldChQX1RFTE5FVF9LRUVQX0FMSVZFLCBQUk9URUNURUR8U0FWRSwgRl9NT0RFX0FEKTsKKyAgU2V0UHJvcChQX1RFTE5FVF9LRUVQX0FMSVZFLCAwKTsKKworICBBZGRJZCgiSW50ZXJhY3RpdmUiKTsKKworICByZWFsaXA9IiI7Cit9CisKKy8vIEFDSFRVTkc6IEZhbGxzIGhpZXIgbWFsIHNvbnN0IG5vY2ggd2VpdGVyZSBSZXNldHMgZ2VlcmJ0IHdlcmRlbiwgbXVzcyBkYXMKKy8vIGhpZXIgb3JkZW50bGljaCBkZWZpbmllcnQgd2VyZGVuIQordm9pZCByZXNldCgpIHsgCisgIGNvbW06OnJlc2V0KCk7CisgIC8vIG1vbWVudGFuIGthbm4gZGVyIFJlc2V0IGpldHp0IGFiZ2VzY2hhbHRldCB3ZXJkZW4sIGRhIGVyIG51ciBkaWUKKyAgLy8gVE0tSGlzdG9yeSBsb2VzY2h0IHVuZCBnZ2YuIHZvbiBOZXRkZWFkKCkgdW5kIERpc2Nvbm5lY3QoKSByZWFrdGl2aWVydAorICAvLyB3aXJkLgorICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIE5vdGlmeU1vdmUob2JqZWN0IGRlc3QsIG9iamVjdCBvbGRlbnYsIGludCBtZXRob2QpCit7CisgIG1vdmluZzo6Tm90aWZ5TW92ZShkZXN0LG9sZGVudixtZXRob2QpOworICAvLyBnZ2YuIERhdGVuIHVlYmVyIG5ldWVzIEVudiBwZXIgR01DUCBzZW5kZW4uCisgIGlmIChkZXN0ICE9IG9sZGVudikKKyAgICBHTUNQX1Jvb20oKTsKK30KKworc3RyaW5nIEZvcnNjaHVuZygpCit7CisgIHJldHVybiBMRVBNQVNURVItPlF1ZXJ5Rm9yc2NodW5nKCk7Cit9CisKKy8qKiBTZXR6dCBEZWZhdWx0d2VydGUgZnVlciBSYXNzZW4gLSB3aXJkIHZvbiBkZW4gU2hlbGxzIHVlYmVyc2NocmllYmVuLgorKi8KK21peGVkIFJhY2VEZWZhdWx0KHN0cmluZyBhcmcpCit7CisgIGlmICghYXJnKQorICAgIHJldHVybiAwOworICBzd2l0Y2goYXJnKQorICB7CisgICAgY2FzZSBQX0hBTkRTIDoKKyAgICAgIHJldHVybiAoeyIgbWl0IGJsb3NzZW4gSGFlbmRlbiIsMzAsRFRfQkxVREdFT059KTsKKyAgICBjYXNlIFBfQk9EWSA6CisgICAgICByZXR1cm4gMDsKKyAgfQorICByZXR1cm4gMDsKK30KKworLyoqIFBydWVmdCBTcGllbGVyb2JqZWt0IGF1ZiBLb25zaXN0ZW56LgorICBVZWJlcnBydWVmdCBkYXMgU3BpZWxlcm9iamVrdCBuYWNoIGtvbXBsZXR0ZXIgSW5pdGlhbGlzaWVydW5nIChpbSAKKyAgY2FsbG91dCkgYXVmIGtvcnJla3RlIFdlcnRlIGVpbmlnZXIgUHJvcHMuCisqLwordm9pZCBjaGVja0NvbnNpc3RlbmN5KCkKK3sgbWl4ZWQgaDsKKyAgaW50ICAgbTsKKworICBpZiAocG9pbnRlcnAoaD1SYWNlRGVmYXVsdChQX0hBTkRTKSkgJiYgc2l6ZW9mKGgpPjEpCisgICAgbT0oaW50KWhbMV07CisgIGVsc2UKKyAgICBtPTMwOworICBpZigoaD1RdWVyeShQX0hBTkRTKSlbMV0gPiBtICYmICFJU19MRUFSTkVSKHRoaXNfb2JqZWN0KCkpKSB7CisgICAgbG9nX2ZpbGUoImluY29uc2lzdGVudCIsIHNwcmludGYoCisgICAgICAiWyVzXSAlTzogSEFORFM6ICVkXG4iLCBkdGltZSh0aW1lKCkpLCB0aGlzX3BsYXllcigpLCBoWzFdKSk7CisgICAgaFsxXSA9IG07CisgICAgU2V0KFBfSEFORFMsaCk7CisgIH0KKworICBpZiAoUXVlcnkoUF9CT0RZKSE9KG09UmFjZURlZmF1bHQoUF9CT0RZKSkpCisgICAgIFNldChQX0JPRFksbSk7CisKKyAgaWYgKCFRdWVyeShQX1NFQ09ORF9NQVJLLEZfTU9ERSkpCisgICAgU2V0KFBfU0VDT05EX01BUkssU0FWRXxQUk9URUNURUQsRl9NT0RFX0FTKTsKKyAgaWYgKCFRdWVyeShQX1RUWV9TSE9XLEZfTU9ERSkmU0FWRSkKKyAgeworICAgIFNldChQX1RUWV9TSE9XLDAsRl9WQUxVRSk7CisgICAgU2V0KFBfVFRZX1NIT1csU0FWRSxGX01PREVfQVMpOworICB9CisgIGlmIChRdWVyeShQX1RUWV9DT0xTLEZfTU9ERSkmU0FWRSkKKyAgeworICAgIFNldChQX1RUWV9DT0xTLFNBVkUsRl9NT0RFX0FEKTsKKyAgICBTZXQoUF9UVFlfUk9XUyxTQVZFLEZfTU9ERV9BRCk7CisgICAgU2V0KFBfVFRZX1RZUEUsU0FWRSxGX01PREVfQUQpOworICB9Cit9CisKKy8qKiBCaXR0ZXQgZGFzIFNwaWVsZXJvYmpla3QsIHNpY2ggenUgemVyc3RvZXJlbi4KKyAgXHBhcmFtW2luXSBzaWxlbnQgRmxhZywgb2Igb2huZSBUZXh0YXVzZ2FiZW4gemVyc3RvZXJ0IHdlcmRlbiBzb2xsCisgIFxyZXR1cm4gRXJmb2xnIGRlciBTZWxic3R6ZXJzdG9lcnVuZworKi8KK3ZhcmFyZ3MgaW50IHJlbW92ZShpbnQgc2lsZW50KQoreworICByZXR1cm4gbW92aW5nOjpyZW1vdmUoc2lsZW50KTsKK30KKworLyoqIFNjaGFsdGV0IGluIGFsbGVuIE9iamVrdGVuIGltIEludiBIQnMgYXVzLgorICBTY2hhbHRldCBpbSBJbnYgaW4gYWxsZW4gT2JqZWt0ZW4gKHJla3Vyc2l2LCBkZWVwX2ludmVudG9yeSkKKyAgZGllIEhlYXJ0YmVhdHMgYXVzLiBGYWxscyBvYnMgdWViZXJnZWJlbiB3aXJkLCB3ZXJkZW4gZGllc2UgT2JqZWt0ZQorICBzdGF0dCBkZXMgSW52ZW50YXJzIGJlbnV0enQuCisgIFNwZWljaGVydCBkaWUgT2JqZWt0ZSwgZGllIGVpbmVuIEhCIGhhdHRlbiwgaW4gZGVyIGdsb2IuIFZhci4gaGJfb2JzLgorICBAcGFyYW1baW5dIG9icyBtaXhlZCAtIE9iamVrdGUsIGluIGRlbmVuIGRlciBIQiBhYmdlc2NoYWx0ZXQgd2VyZGVuIHNvbGwuIAorICAgIENvbnRhaW5lciB3ZXJkZW4gcmVrdXJzaXYgYmVoYW5kZWx0LgorICBAYXR0ZW50aW9uIEFjaHR1bmchIE5pZW1hbHMgendlaW1hbCBoaW50ZXJlaW5hbmRlciBydWZlbiwgb2huZSAKKyAgICB6d2lzY2hlbmR1cmNoIHJlc3RhcnRfaGVhcnRfYmVhdHMoKSBnZXJ1ZmVuIHp1IGhhYmVuIQorICBAc2EgcmVzdGFydF9oZWFydF9iZWF0cworKi8KK3ZhcmFyZ3Mgc3RhdGljIHZvaWQgc3RvcF9oZWFydF9iZWF0cyhtaXhlZCBvYnMpCit7CisgIGludCBpOworCisgIGlmICghb2JzKQorICB7CisgICAgaGJfb2JzPSh7fSk7CisgICAgb2JzPWRlZXBfaW52ZW50b3J5KE1FKTsKKyAgfSAKKyAgZm9yZWFjaChtaXhlZCBvYjogb2JzKSB7CisgICAgaWYgKHBvaW50ZXJwKG9iKSkKKyAgICAgICAgc3RvcF9oZWFydF9iZWF0cyhvYik7CisgICAgZWxzZSBpZiAoc2V0X29iamVjdF9oZWFydF9iZWF0KG9iLDApKSAgCisgICAgICAgIGhiX29icys9KHtvYn0pOworICB9Cit9CisKKy8qKiBTY2hhbHRldCBIQnMgaW4gT2JqZWt0ZW4gaW0gSW52IHdpZWRlciBlaW4uCisgIFNjaGFsdGV0IGluIGFsbGVuIE9iamVrdGVuIGluIGhiX29icyBkZW4gSGVhcnRiZWF0IGVpbi4KKyAgICBJbiBoYl9vYnMgKGdsb2IuIFZhci4pIHN0ZWhlbiBhbGxlIE9iamVrdGUsIGRpZSBiZWltIGxldHp0ZW4gQXVmcnVmIHZvbgorICAgIHN0b3BfaGVhcnRfYmVhdHMoKSBlaW5lbiBIQiBoYXR0ZW4uCisgIEBzYSBzdG9wX2hlYXJ0X2JlYXRzCisqLworc3RhdGljIHZvaWQgcmVzdGFydF9oZWFydF9iZWF0cygpCit7CisgIGludCBpOworCisgIGlmIChwb2ludGVycChoYl9vYnMpKQorICB7CisgICAgZm9yZWFjaChvYmplY3Qgb2I6IGhiX29icykKKyAgICAgIHNldF9vYmplY3RfaGVhcnRfYmVhdChvYiwxKTsKKyAgICBoYl9vYnM9MDsKKyAgfQorfQorCisvKiogUHJ1ZWZ0IGF1ZiBhYmdlbGF1ZmVuZSBTcGllbHplaXQuCisgIFBydWVmdCBpbiBTcGllbGVyb2JqZWt0ZW4sIG9iIGRpZSB0YWVnbGljaGUgTWF4aW1hbHNwaWVsemVpdAorICAgIGFiZ2VsYXVmZW4gaXN0LgorICAgIFdpcmQgaW0gaGVhcnRfYmVhdCgpIGdlcnVmZW4uCisgIEByZXR1cm4gaW50IC0gRmxhZywgb2IgU3BpZWx6ZWl0IGFiZ2VsYXVmZW4gdW5kIExvZ291dCBlcmZvbGdlbiBzb2xsCisqLworc3RhdGljIGludCBDaGVja0RhaWx5UGxheXRpbWUoKSB7CisgIGludCAqc3BpZWxkYXVlcixkOworCisgIGlmICghcG9pbnRlcnAoc3BpZWxkYXVlcj1RdWVyeShQX0RBSUxZX1BMQVlUSU1FKSkpCisgICAgcmV0dXJuIDA7CisgIC8vIDA6TWludXRlbiBwcm8gVGFnLCAxOk5yLiBkZXMgbGV0emVuIFRhZ2VzLCAyOk5yLiBkZXMgYW5nZWZhbmdlbmVuIFRhZ2VzLAorICAvLyAzOmxldHp0ZSBaZWl0cHJ1ZWZ1bmcsIDQ6dmVyYmxlaWJlbmRlIFplaXQKKyAgZD10aW1lKCkvODY0MDA7CisgIGlmIChzcGllbGRhdWVyWzFdPD1kKSB7IC8vIEVuZGUgZGVyIHplaXRiZXNjaHJhZW5rdGVuIFRhZ2U/CisgICAgU2V0KFBfREFJTFlfUExBWVRJTUUsMCk7CisgICAgcmV0dXJuIDA7CisgIH0gZWxzZSBpZiAoc3BpZWxkYXVlclsyXSE9ZCkgeyAvLyBOZXVlciBUYWc/CisgICAgc3BpZWxkYXVlcls0XT1zcGllbGRhdWVyWzBdOworICAgIHNwaWVsZGF1ZXJbMl09ZDsKKyAgfSBlbHNlIHsKKyAgICBzcGllbGRhdWVyWzRdLT0odGltZSgpLXNwaWVsZGF1ZXJbM10pOworICB9CisgIHNwaWVsZGF1ZXJbM109dGltZSgpOyAgLy8gTGV0enRlIFplaXRwcnVlZnVuZworICBTZXQoUF9EQUlMWV9QTEFZVElNRSxzcGllbGRhdWVyKTsKKyAgaWYgKHNwaWVsZGF1ZXJbNF08MCkgeyAvLyBLZWluZSBaZWl0IG1laHIgdWVicmlnIGZ1ZXIgaGV1dGUKKyAgICBpZiAoIWludGVyYWN0aXZlKE1FKSkKKyAgICAgIHJldHVybiAxOworICAgIHdyaXRlKCJEdSBoYXN0IGxhbmdlIGdlbnVnIGdlbXVkZGV0IGZ1ZXIgaGV1dGUuXG4iKTsKKyAgICBzYXkoTmFtZShXRVIpKyIgaGF0IGZ1ZXIgaGV1dGUgZ2VudWcgZ2VtdWRkZXQuXG4iKTsKKyAgICByZW1vdmVfaW50ZXJhY3RpdmUoTUUpOworICAgIHJldHVybiAxOworICB9CisgIHJldHVybiAwOworfQorCisvKiogR2lidCBFcndhcnRlbWVsZHVuZyBtaXQgR3J1bmQgYXVzLgorICBAcGFyYW1baW5dIHdobyAgIHN0cmluZyAtIFdlciBpc3QgaGVyZWluZ2Vrb21tZW4/CisgIEBwYXJhbVtpbl0gaW52aXMgaW50IC0gSXN0IGRlciBTcGllbGVyIEludmlzPworKi8KK3N0YXRpYyB2b2lkIFNob3dfV2FpdEZvcl9SZWFzb24oc3RyaW5nIHdobywgaW50IGludmlzKQoreworICBtaXhlZCBsaXN0OworICBzdHJpbmcgcmVhc29uLG5hbWU7CisKKyAgaWYgKGludmlzKSBuYW1lPSIoIit3aG8rIikiOworICAgIGVsc2UgbmFtZT13aG87CisgIGlmICgobWFwcGluZ3AobGlzdD1RdWVyeVByb3AoUF9XQUlURk9SX1JFQVNPTikpKSAmJiAocmVhc29uPWxpc3Rbd2hvXSkpCisgICAgdGVsbF9vYmplY3QoTUUsc3ByaW50ZigiXG5EdSBlcndhcnRlc3QgJXMgd2VnZW46XG4lc1xuIixuYW1lLHJlYXNvbikpOworICBlbHNlCisgICAgdGVsbF9vYmplY3QoTUUsc3ByaW50ZigiRHUgZXJ3YXJ0ZXN0ICVzIGF1cyBrZWluZW0gYmVzdGltbXRlbiBHcnVuZC5cbiIsCisgICAgICBuYW1lKSk7Cit9CisKKy8qKiBHaWJ0IExpc3RlIGRlciBFcndhcnRldGVuIFNwaWVsZXIgYW4gdGhpc19wbGF5ZXIoKSBhdXMuCisqLworc3RhdGljIHZvaWQgTGlzdEF3YWl0ZWQoKSAvL0Fud2VzZW5kZSBFcndhcnRldGUgYXVmbGlzdGVuCit7CisgICAgc3RyaW5nICpsaXN0OworICAgIG1peGVkIG1saXN0OworICAgIG9iamVjdCBvYjsKKyAgICBpbnQgbWFnOworCisgICAgbWFnPUlTX0xFQVJORVIoTUUpOworCisgICAgbGlzdD0oe30pOworICAgIGZvcmVhY2goc3RyaW5nIGVyd2FydGV0IDogUXVlcnlQcm9wKFBfV0FJVEZPUikpIHsKKyAgICAgICAgaWYgKG9iamVjdHAob2I9ZmluZF9wbGF5ZXIobG93ZXJfY2FzZShlcndhcnRldCkpKSkgeworICAgICAgICAgICAgaWYgKG9iLT5RdWVyeVByb3AoUF9JTlZJUykpIHsKKyAgICAgICAgICAgICAgICBpZiAobWFnKSBsaXN0Kz0oeyBzcHJpbnRmKCIoJXMpIixlcndhcnRldCkgfSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGxpc3QrPSh7ZXJ3YXJ0ZXR9KTsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoc2l6ZW9mKGxpc3QpKQorICAgICAgICBwcmludGYoIkFud2VzZW5kZSBFcndhcnRldGU6ICVzLlxuIiwKKyAgICAgICAgICAgIENvdW50VXAoc29ydF9hcnJheShsaXN0LCMnPikpKTsKKworICAgIGlmICgobWFwcGluZ3AobWxpc3Q9UXVlcnlQcm9wKFBfV0FJVEZPUl9SRUFTT04pKSkgJiYgKHNpemVvZihtbGlzdCkpKQorICAgICAgICB7CisgICAgICAgICAgZm9yZWFjaChzdHJpbmcgZXJ3YXJ0ZXQgOiBtbGlzdCkgeworICAgICAgICAgICAgICAgIGlmICghKG9iPWZpbmRfcGxheWVyKGxvd2VyX2Nhc2UoZXJ3YXJ0ZXQpKSkgfHwKKyAgICAgICAgICAgICAgICAgICAgKCFtYWcgJiYgb2ItPlF1ZXJ5UHJvcChQX0lOVklTKSkpOworICAgICAgICAgICAgICAgIGVsc2UgU2hvd19XYWl0Rm9yX1JlYXNvbihlcndhcnRldCxvYi0+UXVlcnlQcm9wKFBfSU5WSVMpKTsKKyAgICAgICAgICB9CisgICAgICAgIH0KK30KKy8qKiBUZWlsdCBkZW4gR2lsZGVuIHVuZCBhbmRlcmVuIFNwaWVsZXJuIG1pdCwgd2VyIHJlaW5nZWtvbW1lbiBpc3QuCisgIEF1c3NlcmRlbSB3aXJkIGdnZi4gUGxheWVyUXVpdCgpIGltIEVudmlyb25tZW50IGdlcnVmZW4uCisgIFxwYXJhbVtpbl0gcmVpbiBpbnQgLSB3YWhyLCB3ZW5uIGRlciBTcGllbGVyIGVpbmxvZ2d0LgorKi8KK3Byb3RlY3RlZCB2b2lkIGNhbGxfbm90aWZ5X3BsYXllcl9jaGFuZ2UoaW50IHJlaW4pCit7CisgIHN0cmluZyB3ZXIgPSBnZXR1aWQoTUUpOworICAvLyBlcnN0IGRpZSBHaWxkZSBpbmZvcm1pZXJlbgorICBzdHJpbmcgZ2lsZGUgPSBRdWVyeVByb3AoUF9HVUlMRCk7CisgIGlmIChzdHJpbmdwKGdpbGRlKSAmJiAoZmluZF9vYmplY3QoIi9naWxkZW4vIitnaWxkZSkKKyAgICAgICAgfHwgZmlsZV9zaXplKCIvZ2lsZGVuLyIrZ2lsZGUrIi5jIik+MCkpCisgICAgY2F0Y2goKCIvZ2lsZGVuLyIrZ2lsZGUpLT5ub3RpZnlfcGxheWVyX2NoYW5nZShNRSwgcmVpbik7IHB1Ymxpc2gpOworCisgIC8vIGRhbm4gZGllIGFuZGVyZW4gU3BpZWxlcgorICBpbnQgbWFnID0gSVNfTEVBUk5FUihNRSk7CisgIGludCBpbnZpcyA9IFF1ZXJ5UHJvcChQX0lOVklTKTsKKyAgb2JqZWN0ICp1ID0gdXNlcnMoKSAtICh7TUV9KTsgLy8gc2ljaCBzZWxiZXIgbmljaHQgbWVsZGVuIAorICBpZiAobWFnICYmIGludmlzKSB7ICAgLy8gSW52aXNtYWdpZXIgbnVyIE1hZ2llcm4gbWVsZGVuCisgICAgdSA9IGZpbHRlcih1LCBmdW5jdGlvbiBpbnQgKG9iamVjdCBvKQorICAgICAgICB7IHJldHVybiBxdWVyeV93aXpfbGV2ZWwobykgPj0gTEVBUk5FUl9MVkw7IH0KKyAgICAgICAgKTsKKyAgfQorICB1LT5ub3RpZnlfcGxheWVyX2NoYW5nZShjYXBpdGFsaXplKHdlcikscmVpbixpbnZpcyk7CisKKyAgLy8gdW5kIGJlaW0gQXVzbG9nZ2VuIG5vY2ggZGFzIEVudiBpbmZvcm1pZXJlbi4KKyAgaWYgKCFyZWluKSB7CisgICAgaWYoZW52aXJvbm1lbnQoKSkgY2F0Y2goZW52aXJvbm1lbnQoKS0+UGxheWVyUXVpdChNRSk7cHVibGlzaCk7CisgIH0KK30KKworLyoqIFJ1ZnQgaW0gdWViZXJnZWJlbmVuIE9iamVrdCBlaW4gaW5pdCgpIGF1Ziwgc29mZXJuIG5vdHdlbmRpZy4KKyAgUnVmdCBpbiBvYiBlaW4gaW5pdCgpIGF1ZiwgZmFsbHMgZGFzIE9iamVrdCBuYWNoIGRlbQorICAgIGxldHp0ZW4gQXVzbG9nZ2VuIGdlc2NoYWZmZW4gd3VyZGUuCisgIFxwYXJhbVtpbl0gb2Igb2JqZWN0IC0gT2JqZWt0LCBpbiBkZW0gaW5pdCgpIGdlcnVmZW4gd2lyZC4KKyAgXHBhcmFtW2luXSBsb2dvdXQgaW50IC0gTGV0enRlciBMb2dvdXQKKyAgXHJldHVybiAxLCBmYWxscyBpbml0KCkgZ2VydWZlbiB3dXJkZS4gMCBzb25zdC4KKyovCitzdGF0aWMgaW50IGNhbGxfaW5pdCggb2JqZWN0IG9iLCBpbnQgbG9nb3V0ICkKK3sKKyAgICBpZiAoIG9iamVjdHAob2IpICYmIG9iamVjdF90aW1lKG9iKSA+IGxvZ291dCApCisgICAgICAgIHJldHVybiBjYXRjaChvYi0+aW5pdCgpOyBwdWJsaXNoKSwgMTsKKyAgICByZXR1cm4oMCk7Cit9CisKKy8qKiBIb2x0IHNlaXQgZGVtIGxldHp0ZW4gQXVzbG9nZ2VuIGF1c2dlZmFsbGVuZSBJbml0cyBuYWNoLgorICBSdWZ0IGluIGRlbiB1ZWJlcmdlYmVuZW4gT2JqZWt0ZW4gY2FsbF9pbml0KCksIHdhcyBlaW5lbiBpbml0KCkKKyAgYXVzbG9lc3QsIGZhbGxzIGRhcyBPYmpla3Qgc2VpdCBkZW0gbGV0enRlbiBBdXNsb2dnZW4gZXJzdGVsbHQgd3VyZGUuCisgIFxwYXJhbVtpbl0gbG9nb3V0IFplaXRwdW5rdCBkZXMgbGV0enRlbiBMb2dvdXRzCisgIFxwYXJhbVtpbl0gb2JzIEFycmF5IHZvbiBPYmpla3RlbgorICBcc2EgY2FsbF9pbml0KCkKKyovCitzdGF0aWMgdm9pZCBpbml0c19uYWNoaG9sZW4oIGludCBsb2dvdXQsIG9iamVjdCAqb2JzICkKK3sKKyAgICBmaWx0ZXIoIG9icywgImNhbGxfaW5pdCIsIE1FLCBsb2dvdXQgKTsKK30KKworLyoqIEJlbGVidCBlaW5lbiBOZXR6dG90ZW4gd2llZGVyLgorICBXaXJkIGltIExvZ2luIGdlcnVmZW4sIHdlbm4gZGVyIFNwaWVsZXIgbmV0enRvdCB3YXIuIEFlcXVpdmFsZW50IHp1CisgIHN0YXJ0X3BsYXllcigpCisgIEBwYXJhbVtpbl0gc2lsZW50IFdlbm4gRmxhZyBnZXNldHp0LCB3ZXJkZW4ga2VpbmUgTWVsZHVuZyBhbiBkZW4gUmF1bQorICBhdXNnZWdlYmVuLgorICBAcGFyYW1baW5dIGlwIFRleHR1ZWxsZSBSZXByYWVzZW50YXRpb24gZGVyIElQLUFkcmVzc2UsIHZvbiBkZXIgZGVyIFNwaWVsZXIKKyAga29tbXQuCisgIEBzZWUgc3RhcnRfcGxheWVyKCkKKyovCit2YXJhcmdzIHZvaWQgUmVjb25uZWN0KCBpbnQgc2lsZW50ICkKK3sKKyAgICBpbnQgbnVtOworICAgIHN0cmluZyBjYWxsZWRfZnJvbV9pcDsKKyAgICBvYmplY3QgKmludjsKKworICAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKQorICAgIHsKKyAgICAgICAgLy8gcGVyZm9ybSB0aGUgdGVsbmV0IG5lZ290aWF0aW9ucy4gKGFsbCB0aGF0IGFyZSBhdmFpbGFibGUpCisgICAgICAgICIqIjo6c3RhcnR1cF90ZWxuZXRfbmVncygpOworICAgICAgICBTZXQoIFBfTEFTVF9MT0dJTiwgdGltZSgpICk7CisgICAgfQorCisgICAgZW5hYmxlX2NvbW1hbmRzKCk7CisgICAgc2V0X2xpdmluZ19uYW1lKCBnZXR1aWQoKSApOworICAgIF9yZW1vdmVfbmV0ZGVhZCgpOworICAgIHNldF9oZWFydF9iZWF0KDEpOworICAgIC8vIEh1bnR0aW1lcyBha3R1YWxpc2llcmVuIHVuZCBnZ2YuIEZlaW5kZSB2ZXJnZXNzZW4uCisgICAgdXBkYXRlX2h1bnRfdGltZXMoKHRpbWUoKS1RdWVyeVByb3AoUF9MQVNUX0xPR09VVCkpIC9fX0hFQVJUX0JFQVRfSU5URVJWQUxfXyk7CisgICAgLy8gSGVhcnRiZWF0cyBpbiBPYmpla3RlbiBpbSBJbnYgcmVha3RpdmVyZW4uCisgICAgcmVzdGFydF9oZWFydF9iZWF0cygpOworICAgIC8vIGxpZmUuYyB3aWxsIGdnZi4gd2FzIGF1ZnJhZXVtZW4KKyAgICBsaWZlOjpyZWNvbm5lY3QoKTsKKworICAgIGxvZ19maWxlKCAiUkVFTlRFUiIsIHNwcmludGYoICIlLTExcyAlcywgJS0xNXMgKCVzKS5cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShnZXR1aWQoTUUpKSwgY3RpbWUodGltZSgpKVs0Li4xNV0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnlfaXBfbnVtYmVyKE1FKXx8IlVua25vd24iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5X2lwX25hbWUoTUUpfHwiVW5rbm93biIgKSwKKyAgICAgICAgICAgICAgMjAwMDAwICk7CisKKyAgICBpZiAoIG5kZWFkX2N1cnJlbnRseSApCisgICAgICAgIG5kZWFkX3Jldml2ZSgpOworCisgICAgaWYgKCAhc2lsZW50ICYmIGludGVyYWN0aXZlKE1FKSApCisgICAgICAgIGNhbGxfbm90aWZ5X3BsYXllcl9jaGFuZ2UoMSk7CisKKyAgICBjb21tYW5kOjpyZWNvbm5lY3QoKTsKKyAgICBpZiAoIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICkKKyAgICAgICAgbW9kaWZ5X3Byb21wdCgpOworCisgICAgLy8gTG9naW4tZXZlbnQgYXVzbG9lc2VuCisgICAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoRVZUX0xJQl9MT0dJTiwgKFsKKyAgICAgICAgICBFX09CSkVDVDogTUUsCisgICAgICAgICAgRV9QTE5BTUU6IGdldHVpZChNRSksCisgICAgICAgICAgRV9FTlZJUk9OTUVOVDogZW52aXJvbm1lbnQoKSBdKSApOworCisgICAgY2F0Y2goIG51bSA9ICJzZWN1cmUvbWFpbGVyIi0+RmluZ2VyTWFpbChnZXRldWlkKCkpO3B1Ymxpc2ggKTsKKworICAgIGlmICggbnVtICkKKyAgICAgICAgd3JpdGUoICJEdSBoYXN0ICIgKyBudW0gKyAiIG5ldWUiICsgKG51bSA9PSAxID8gIm4gQnJpZWYiIDogIiBCcmllZmUiKQorICAgICAgICAgICAgICAgKyAiIGltIFBvc3RhbXQgbGllZ2VuLlxuIiApOworCisgICAgaWYgKCBRdWVyeVByb3AoUF9BV0FZKSApCisgICAgICAgIHdyaXRlKCBicmVha19zdHJpbmcoICJEdSBiaXN0IGFscyBhYndlc2VuZCBnZWtlbm56ZWljaG5ldDogIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFF1ZXJ5UHJvcChQX0FXQVkpICsgIi4iLCA3OCApICk7CisKKyAgICBjYXRjaCggUmVnaXN0ZXJDaGFubmVscygpOyBwdWJsaXNoICk7CisKKyAgICBpZiAoIChjYWxsZWRfZnJvbV9pcCA9IFF1ZXJ5KFBfQ0FMTEVEX0ZST01fSVApKSAmJgorICAgICAgICAgcXVlcnlfaXBfbnVtYmVyKE1FKSAhPSBjYWxsZWRfZnJvbV9pcCApIHsKKyAgICAgICAgc3RyaW5nIHRtcDsKKworICAgICAgICBpZiAoIHN0cmluZ3AodG1wID0gcXVlcnlfaXBfbmFtZShjYWxsZWRfZnJvbV9pcCkpICYmCisgICAgICAgICAgICAgdG1wICE9IGNhbGxlZF9mcm9tX2lwICkKKyAgICAgICAgICAgIHRtcCA9ICIgWyIgKyB0bXAgKyAiXSI7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHRtcCA9ICIiOworCisgICAgICAgIHdyaXRlKCAiRGFzIGxldHp0ZSBNYWwga2Ftc3QgRHUgdm9uICIgKyBjYWxsZWRfZnJvbV9pcCArIHRtcCArICIuXG4iICk7CisgICAgfQorCisgICAgU2V0KCBQX0NBTExFRF9GUk9NX0lQLCBxdWVyeV9pcF9udW1iZXIoTUUpICk7CisKKyAgICAvLyBmYWxscyBHZWdlbnN0YWVuZGUgbWl0ICd1cGQgLWFyJyB1cGdlZGF0ZWQgd3VyZGVuLCBtdWVzc2VuIGRpZQorICAgIC8vICJ2ZXJsb3JlbiBnZWdhbmdlbmVuIiBpbml0KCkncyBuYWNoZ2Vob2x0IHdlcmRlbgorICAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgJiYgIUlTX0xFQVJORVIoTUUpICkKKyAgICAgICAgY2FsbF9vdXQoICJpbml0c19uYWNoaG9sZW4iLCAwLCBRdWVyeShQX0xBU1RfTE9HT1VUKSwKKyAgICAgICAgICAgICAgICAgIGFsbF9pbnZlbnRvcnkoTUUpICk7CisKKyAgICAvLyBub2NoIG5pY2h0IGdlY2xvbnRlIEF1dG9sb2FkZXIgIm5hY2giY2xvbmVuCisgICAgd2hpbGUgKCByZW1vdmVfY2FsbF9vdXQoImxvYWRfYXV0b19vYmplY3RzIikgIT0gLTEgKQorICAgICAgICAvKiBkbyBub3RoaW5nICovOworCisgICAgaWYgKCBzaXplb2YoYXV0b2xvYWRfcmVzdCkgKQorICAgICAgICBjYWxsX291dCggImxvYWRfYXV0b19vYmplY3RzIiwgMCwgYXV0b2xvYWRfcmVzdCApOworCisgICAgaWYgKG5kZWFkX2xvY2F0aW9uKSB7CisgICAgICBjYXRjaCggbmRlYWRfbG9jYXRpb24tPkJlY29tZXNOZXRBbGl2ZShNRSk7cHVibGlzaCApOworICAgICAgaW52ID0gYWxsX2ludmVudG9yeShuZGVhZF9sb2NhdGlvbik7CisgICAgICBuZGVhZF9sb2NhdGlvbiA9IDA7CisgICAgfQorICAgIGVsc2UKKyAgICAgIGludiA9ICh7fSk7CisKKyAgICBpbnYgKz0gZGVlcF9pbnZlbnRvcnkoTUUpOworCisgICAgLy9aWiBmb3JlYWNoIHN0YXR0IGNhbGxfb3RoZXIoKSwgZGFtaXQgbmVuIGJ1ZyBpbiBCTkEgbmljaHQgZGllIGFuZGVyZW4KKyAgICAvL0JOQSB2ZXJoaW5kZXJ0LgorICAgIGZvcmVhY2gob2JqZWN0IG9iOiBpbnYpIHsKKyAgICAgICAgLy9lcyBpc3QgbmljaHQgYXVzenVzY2hsaWVzc2VuLCBkYXNzIEl0ZW1zIGR1cmNoIEJlY29tZXNOZXRBbGl2ZSgpCisgICAgICAgIC8vZWluZXMgYW5kZXJlbiB6ZXJzdG9lcnQgd2VyZGVuLgorICAgICAgICBpZiAob2JqZWN0cChvYikpCisgICAgICAgICAgY2F0Y2goIGNhbGxfb3RoZXIob2IsICJCZWNvbWVzTmV0QWxpdmUiLCBNRSk7cHVibGlzaCApOworICAgIH0KKworICAgIC8vIEVyc3QgYW4gZGllc2VyIFN0ZWxsZSwgd2VpbCBkZXIgU3BpZWxlciB1LlUuIGR1cmNoIGVpbiBCZWNvbWVzTmV0QWxpdmUoKQorICAgIC8vIG5vY2ggYmV3ZWd0IHd1cmRlLgorICAgIGlmICggIXNpbGVudCAmJiBlbnZpcm9ubWVudCgpICYmIG9iamVjdF9uYW1lKGVudmlyb25tZW50KCkpICE9IE5FVERFQURfUk9PTSApCisgICAgeworICAgICAgICBpZihxdWVyeV9oY19wbGF5KCk8PTEpCisgICAgICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KCksUXVlcnlQcm9wKFBfTkFNRSkgKyAiIHdlaWx0IHdpZWRlciB1bnRlciBkZW4gTGViZW5kZW4uXG4iLCh7TUV9KSApOworICAgICAgICBlbHNlIAorICAgICAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCgpLFF1ZXJ5UHJvcChQX05BTUUpICsgIiB3ZWlsdCB3aWVkZXIgdW50ZXIgZGVuIFZlcnN0b3JiZW5lbi5cbiIsKHtNRX0pICk7CisgICAgfQorCisgICAgTmV3YmllSW50cm9Nc2coKTsKKworICAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKQorICAgICAgICBMaXN0QXdhaXRlZCgpOworfQorCisvKiogTG9nZ3QgZWluZW4gU3BpZWxlciBhdXMgdW5kIG1hY2h0IGlobiBuZXR6dG90LgorICBCZXdlZ3QgZWluZW4gU3BpZWxlciBpbiBkZW4gTmV0enRvdGVucmF1bSwgZGVha3RpdmllcnQgSGVhcnRiZWF0cyBpbQorICBJbnZlbnRhciwgcnVmdCBCZWNvbWVzTmV0RGVhZCgpLCBsb2VzdCBFcndhcnRlbWVsZHVuZ2VuIGF1cywgdHJpZ2dlcnQKKyAgQXVzbG9nZ2V2ZW50LgorKi8KK3ZvaWQgTmV0RGVhZCgpCit7CisgIG9iamVjdCAqaW52OworICBpbnQgbnVtOworCisgIGNhdGNoKFJlbW92ZUNoYW5uZWxzKCk7cHVibGlzaCk7CisKKyAgaWYocXVlcnlfaGNfcGxheSgpPjEpCisgICAgc2F5KCJQbG9ldHpsaWNoIHdlaWNodCBhbGxlIHNwaXJpdHVlbGxlIEVuZXJnaWUgYXVzICIrUXVlcnlQcm9wKFBfTkFNRSkrIi5cbiIpOworICBlbHNlCisgICAgc2F5KCJQbG9ldHpsaWNoIHdlaWNodCBhbGxlcyBMZWJlbiBhdXMgIitRdWVyeVByb3AoUF9OQU1FKSsiLlxuIik7CisKKyAgX3NldF9uZXRkZWFkKCk7CisgIHJlbW92ZV9jYWxsX291dCgicXVpdCIpOworICByZW1vdmVfbGl2aW5nX25hbWUoKTsKKyAgLy8gV2lyZCB6d2FyIGltIHNhdmVfbWUoKSBnZW1hY2h0LCBhYmVyIGRpZSBaZWl0dW50ZXJzY2hpZWRlIGJlaW0KKyAgLy8gZmluZ2VybiBkaXJla3QgbmFjaCBkZW0gQXVzbG9nZ2VuIGZ1ZWhyZW4gaW1tZXIgd2llZGVyIHp1IFZlcndpcnJ1bmdlbgorICBpZihxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSAmJiAhUXVlcnlQcm9wKFBfSU5WSVMpKQorICAgICAgU2V0KFBfTEFTVF9MT0dPVVQsdGltZSgpKTsKKyAgaWYgKE1FKQorICAgIG5kZWFkX2xvY2F0aW9uID0gZW52aXJvbm1lbnQoKTsKKworICBpZiAocXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkpCisgICAgY2FsbF9ub3RpZnlfcGxheWVyX2NoYW5nZSgwKTsKKworICAvLyBMb2dvdXQtZXZlbnQgYXVzbG9lc2VuCisgIEVWRU5URC0+VHJpZ2dlckV2ZW50KEVWVF9MSUJfTE9HT1VULCAoWworICAgICAgICAgIEVfT0JKRUNUOiBNRSwKKyAgICAgICAgICBFX1BMTkFNRTogZ2V0dWlkKE1FKSwKKyAgICAgICAgICBFX0VOVklST05NRU5UOiBlbnZpcm9ubWVudCgpIF0pICk7CisKKyAgc2V0X25leHRfcmVzZXQoOTAwKTsKKyAgLyogQmVpIE5pY2h0LU1hZ2llci1TaGVsbHMgd2lyZCBjb21tOjpyZXNldCgpIGF1ZmdlcnVmZW4sIGRhcyBwcnVlZnQsIG9iCisgICAgIGRlciBTcGllbGVyIGltbWVyIG5vY2ggbmV0enRvdCBpc3QsIHVuZCBmYWxscyBqYSwgZGllIHRtaGlzdCBsb2VzY2h0LgorICAgICBEaWUgTWV0aG9kZSB3aXJkIHZvbiAvc3RkL3NoZWxscy9tYWdpZXIuYyB1ZWJlcnNjaHJpZWJlbiwgbmV0enRvdGUKKyAgICAgTWFnaWVyIChkaWUgZWlnZW50bGljaCBzY2hvbiBhbmRlcndlaXRpZyBiZXNlaXRpZ3Qgd29yZGVuIHNlaW4gc29sbHRlbikKKyAgICAgd2VyZGVuIHJlbW92ZSgpZCB1bmQgZGVzdHJ1Y3QoKWVkLiAtLUFteW50aG9yIDA1LjA1LjIwMDggKi8KKworICBpZiAoZW52aXJvbm1lbnQoKSkgeworICAgIGNhdGNoKGVudmlyb25tZW50KCktPkJlY29tZXNOZXREZWFkKE1FKTtwdWJsaXNoKTsKKyAgICBpbnYgPSBkZWVwX2ludmVudG9yeShNRSkrYWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKTsKKyAgfQorICBlbHNlIGludj1kZWVwX2ludmVudG9yeShNRSk7CisgIGZvcmVhY2gob2JqZWN0IG9iOiBpbnYpIHsKKyAgICAgIGlmIChvYmplY3RwKG9iKSkgLy9tYW4gd2Vpc3MgbmllIHdhcyBCTkQoKSBtYWNodC4uLgorICAgICAgICAgIGNhdGNoKCBjYWxsX290aGVyKG9iLCAiQmVjb21lc05ldERlYWQiLCBNRSk7cHVibGlzaCApOworICB9Cit9CisKKworLyoqIFNlbmRldCBnZ2YuIFRlbG5ldCBUaW1pbmcgTWFya3MgYWxzIEtlZXAtQWxpdmUgUGFrZXRlIGFuIGRlbiBDbGllbnQuCisgICogV2lyZCBpbiBoZWFydF9iZWF0KCkgZ2VydWZlbi4KKyAgKiBAcmV0dXJuIDEsIGZhbGxzIGRlciBTcGllbGVyIEtlZXAtQWxpdmUgUGFrZXQgd3VlbnNjaHQsIHNvbnN0IDAuIAorICAqIEBzZWUgaGVhcnRfYmVhdCgpCisqLworcHJvdGVjdGVkIGludCBDaGVja1RlbG5ldEtlZXBBbGl2ZSgpIHsKKyAgaWYgKHRlbG5ldF90bV9jb3VudGVyID4gMCkgeworICAgIC8vIFNwaWVsZXIgaGF0IG9mZmVuYmFyIGVpbiBLZWVwLUFsaXZlIGtvbmZpZ3VyaWVydCAuLi4KKyAgICBpZiAoISgtLXRlbG5ldF90bV9jb3VudGVyKSkgeworICAgICAgLy8gdW5kIGRhcyBJbnRlcnZhbGwgaXN0IGdlcmFkZSBhYmdlbGF1ZmVuLgorICAgICAgLy8gUHJvcCBvZmZlbmJhciBnZXNldHp0LCBGRWF0dXJlIGlzdCB3aXJrbGljaCBnZXd1ZW5zY2h0LAorICAgICAgLy8gVGVsbmV0IFRpbWluZyBNYXJrIHNlbmRlbiAKKyAgICAgIHNlbmRfdGVsbmV0X3RpbWluZ19tYXJrKCk7CisgICAgICAvLyBhbGxlIDEyMCBIQnMgKDI0MHMsIDRtaW4pLgorICAgICAgLy8gc29sbHRlIGVpZ2VudGxpY2ggMjQwIC8gX19IRUFSVF9CRUFUX0lOVEVSVkFMX18gc2Vpbi4gQWJlciBzcGFydAorICAgICAgLy8gZWluZSBPcGVyYXRpb24gaW0gSEIuIDstKQorICAgICAgdGVsbmV0X3RtX2NvdW50ZXIgPSAxMjA7CisgICAgfQorICAgIHJldHVybiAxOyAvLyBLZWVwLUFsaXZlIGlzdCBlaW5nZXNjaGFsdGV0CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkIG5kZWFkX21vdmVfbWUoKTsKKworLyoqIEhlYXJ0YmVhdCBkZXMgU3BpZWxlcm9iamVrdGVzLgorICBQcnVlZnQgdGFlZ2xpY2hlIFNwaWVsemVpdCwgc3BlaWNoZXJ0IHJlZ2VsbWFlc3NpZyBkZW4gU3BpZWxlciwKKyAgYmV3ZWd0IE5ldHp0b3RlIGluIGRlbiBOZXR6dG9kZW5yYXVtLCBydWZ0IGRpZSBIQnMgYXVzIGxpdmluZy9jb21iYXQgdW5kCisgIHBsYXllci9saWZlLgorKi8KK3Byb3RlY3RlZCB2b2lkIGhlYXJ0X2JlYXQoKSB7CisgIGlmICghTUUpCisgICAgcmV0dXJuOworICBpZiAobmRlYWRfY3VycmVudGx5KQorICB7CisgICAgaWYgKGludGVyYWN0aXZlKE1FKSkKKyAgICB7CisgICAgICBuZGVhZF9yZXZpdmUoKTsKKyAgICAgIG5kZWFkX2xvY2F0aW9uPTA7CisgICAgfQorICAgIGVsc2UgcmV0dXJuOworICB9CisgIGVsc2UKKyAgICBpZiAoIShuZGVhZF9uZXh0X2NoZWNrLS0pKQorICAgIHsKKyAgICAgIG5kZWFkX25leHRfY2hlY2s9TkVUREVBRF9DSEVDS19USU1FOworICAgICAgaWYgKCFpbnRlcmFjdGl2ZShNRSkpCisgICAgICAgIGlmIChuZGVhZF9sYXN0dGltZSkKKyAgICAgICAgeworICAgICAgICAgIHNhdmVfbWUoMSk7CisgICAgICAgICAgaWYgKElTX0xFQVJORVIoTUUpKQorICAgICAgICAgIHsKKyAgICAgICAgICAgIHF1aXQoKTsKKyAgICAgICAgICAgIGlmIChNRSkKKyAgICAgICAgICAgICAgcmVtb3ZlKCk7CisgICAgICAgICAgICBpZiAoTUUpCisgICAgICAgICAgICAgIGRlc3RydWN0KE1FKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICB9CisgICAgICAgICAgbmRlYWRfbW92ZV9tZSgpOworICAgICAgICAgIC8vIFp1bWluZGVzdCBiZWkgR2Flc3RlbiBpc3QgZGFzIE9iamVrdCBqZXR6dCB6ZXJzdG9lcnQKKyAgICAgICAgICBpZiAoIW9iamVjdHAodGhpc19vYmplY3QoKSkpCisgICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICAgIG5kZWFkX2xhc3R0aW1lPTE7CisgICAgfQorICBpZiAoTUUgJiYgbmRlYWRfbGFzdHRpbWUgJiYgaW50ZXJhY3RpdmUoTUUpKQorICAgIG5kZWFkX2xhc3R0aW1lPTA7CisgIGlmIChDaGVja0RhaWx5UGxheXRpbWUoKSkKKyAgICByZXR1cm47CisKKyAgQ2hlY2tUZWxuZXRLZWVwQWxpdmUoKTsKKworICBsaWZlOjpoZWFydF9iZWF0KCk7CisgIGNvbWJhdDo6aGVhcnRfYmVhdCgpOworICBza2lsbHM6OmhlYXJ0X2JlYXQoKTsKK30KKworLyoqIElELUZ1bmt0aW9uIGZ1ZXIgU3BpZWxlcm9iamVrdGUuCisgKiBpZCgpIGZ1ZXIgU3BpZWxlci4gQmVzb25kZXJlIEJlaGFuZGx1bmcgZnVlciBGcm9lc2NoZSB1bmQgR2Vpc3RlciwKKyAqIHNvd2llIEludmlzLVN0YXR1cy4KKyAqIEdpYnQgaW1tZXIgMCB6dXJ1ZWNrLCB3ZW5uIFBfSU5WSVMgJiYgbHZsIDwgUF9MRVZFTAorICogQHBhcmFtW2luXSBzdHIgYW5nZWZyYWd0ZXIgSUQtU3RyaW5nCisgKiBAcGFyYW1baW5dIGx2bCBMZXZlbCBkZXMgQW5mcmFnZW5kZW4KKyAqIEByZXR1cm4gMSwgZmFsbHMgc3RyIGF1ZiBkZW4gU3BpZWxlciB6dXRyaWZmdCwgMCBzb25zdC4KKyAqLwordmFyYXJncyBpbnQgaWQoc3RyaW5nIHN0ciwgaW50IGx2bCkKK3sKKyAgaWYgKDo6aWQoc3RyKSkKKyAgICByZXR1cm4gMTsKKyAgaWYgKFF1ZXJ5KFBfSU5WSVMpICYmIGx2bCA8IFF1ZXJ5UHJvcChQX0xFVkVMKSkKKyAgICByZXR1cm4gMDsKKyAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSYmIHN0ciA9PSAiZ2Vpc3Qgdm9uICIrIGxvd2VyX2Nhc2UoUXVlcnlQcm9wKFBfTkFNRSkpKQorICAgIHJldHVybiAxOworICBpZiAoUXVlcnlQcm9wKFBfRlJPRykgJiYgc3RyID09ICJmcm9zY2giKSByZXR1cm4gMTsKKyAgcmV0dXJuKDApOworfQorCisvKiogU2V0enQgU3BpZWxlcmhvbWVwYWdlIChTcGllbGVya29tbWFuZG8pLgorICAqIEBwYXJhbVtpbl0gc3RyIFNwaWVsZXJlaW5nYWJlCisgICogQHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICovCitzdGF0aWMgaW50IHNldF9ob21lcGFnZShzdHJpbmcgc3RyKQoreworICBtaXhlZCB0bXA7CisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSkgeworICAgIGlmICghUXVlcnlQcm9wKFBfSE9NRVBBR0UpKQorICAgICAgd3JpdGUoIkR1IGhhc3Qga2VpbmUgVVJMLUFkcmVzc2UgZ2VzZXR6dCFcbiIpOworICAgIGVsc2UKKyAgICAgIHdyaXRlKCJEZWluZSBvZmZpemllbGxlIFVSTC1BZHJlc3NlIGxhdXRldDogIiArIFF1ZXJ5UHJvcChQX0hPTUVQQUdFKQorICAgICAgICAgICAgKyJcbiIpOworICAgIHJldHVybiAxOworICB9CisgIHdyaXRlKCJEZWluZSBvZmZpemllbGxlIFVSTC1BZHJlc3NlIHd1cmRlIGdlYWVuZGVydC5cbiIpOworICBpZiAoc3RyPT0ia2VpbmUiKSAKKyAgICBTZXRQcm9wKFBfSE9NRVBBR0UsIDApOworICBlbHNlIHsKKyAgICB0bXAgPSBmaWx0ZXIocmVnZXhwbG9kZShzdHIsICJbPF1bXj5dKls+XSIpLAorICAgICAgICAgICAgICAgICAgICAgICBsYW1iZGEoKHsnZX0pLCAoeyMnIT0sICh7IydbLCAnZSwgMH0pLCAnPCd9KSkpOworICAgIHdyaXRlKCJTaWUgbGF1dGV0IGpldHp0OiAiKyhzdHIgPSBpbXBsb2RlKHRtcCwgIiIpKSsiXG4iKTsKKyAgICBTZXRQcm9wKFBfSE9NRVBBR0UsIHN0cik7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKKy8qKiBTZXR6dCBTcGllbGVyLVdvaG5vcnQgKFNwaWVsZXJrb21tYW5kbykuCisgICogXHBhcmFtW2luXSBzdHIgU3BpZWxlcmVpbmdhYmUKKyAgKiBccmV0dXJuIDEgYmVpIEVyZm9sZywgMCBzb25zdC4KKyAgKi8KK3N0YXRpYyBpbnQgc2V0X2xvY2F0aW9uKCBzdHJpbmcgc3RyICkKK3sKKyAgICBtaXhlZCBvcnQ7CisKKyAgICBpZiAoIHN0ciA9PSAiMCIgfHwgc3RyID09ICJsb2VzY2hlbiIgKXsKKyAgICAgICAgU2V0KCBQX0xPQ0FUSU9OLCAwICk7CisgICAgICAgIHdyaXRlKCAiRHUgbG9lc2NodCBEZWluZSBPcnRzYW5nYWJlLlxuIiApOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICBpZiAoIHN0cmluZ3Aoc3RyID0gX3VucGFyc2VkX2FyZ3MoKSkgJiYgc3RyICE9ICIiICl7CisgICAgICAgIFNldCggUF9MT0NBVElPTiwgY2FwaXRhbGl6ZShzdHIpICk7CisgICAgICAgIHByaW50ZiggIkR1IGFlbmRlcnN0IERlaW5lIE9ydHNhbmdhYmUgYXVmIFwiJXNcIi5cbiIsCisgICAgICAgICAgICAgICAgUXVlcnkoUF9MT0NBVElPTikgKTsKKyAgICB9CisgICAgZWxzZSBpZiAoIHN0cmluZ3Aob3J0ID0gUXVlcnkoUF9MT0NBVElPTikpICkKKyAgICAgICAgcHJpbnRmKCAiRGVpbmUgT3J0c2FuZ2FiZSBsYXV0ZXQgXCIlc1wiLlxuIiwgUXVlcnkoUF9MT0NBVElPTikgKTsKKyAgICBlbHNleworICAgICAgICBTZXQoIFBfTE9DQVRJT04sIDAsIEZfVkFMVUUgKTsKKyAgICAgICAgd3JpdGUoICJEdSBoYXN0IGtlaW5lIE9ydHNhbmdhYmUgZ2VzZXR6dC5cbiIgKTsKKyAgICB9CisKKyAgICByZXR1cm4gMTsKK30KKworLyoqIFNldHp0IElDUS1VSU4gZGVzIFNwaWVsZXJzIChTcGllbGVya29tbWFuZG8pLgorICAqIFxwYXJhbVtpbl0gc3RyIFNwaWVsZXJlaW5nYWJlCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICovCitzdGF0aWMgaW50IHNldF9pY3Eoc3RyaW5nIHN0cikgeworICBpbnQgbnVtOworCisgIGlmICghc3RyIHx8IHN0cj09IiIpIHsKKyAgICBpZiAoIW51bT1RdWVyeVByb3AoUF9JQ1EpKQorICAgICAgd3JpdGUoIkR1IGhhc3Qga2VpbmUgSUNRLU51bW1lciBnZXNldHp0IVxuIik7CisgICAgZWxzZQorICAgICAgcHJpbnRmKCJEZWluZSBJQ1EtTnVtbWVyIGxhdXRldDogJWRcbiIsbnVtKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoc3NjYW5mKHN0ciwiJWQiLG51bSkhPTEgfHwgIW51bSkgeworICAgIHdyaXRlKCJEZWluZSBJQ1EtTnVtbWVyIHd1cmRlIGdlbG9lc2NodC5cbiIpOworICAgIFNldFByb3AoUF9JQ1EsIDApOworICB9IGVsc2UgeworICAgIHdyaXRlKCJEZWluZSBJQ1EtTnVtbWVyIHd1cmRlIGdlYWVuZGVydC5cbiIpOworICAgIHByaW50ZigiU2llIGxhdXRldCBqZXR6dDogJWRcbiIsbnVtKTsKKyAgICBTZXRQcm9wKFBfSUNRLCBudW0pOworICB9CisgIHJldHVybiAxOworfQorCisvKiogU2V0enQgSW5zdGFudCBNZXNzYW5nZXIgdm9tIFNwaWVsZXIgKFNwaWVsZXJrb21tYW5kbykuCisgICogXHBhcmFtW2luXSBzdHIgU3BpZWxlcmVpbmdhYmUKKyAgKiBccmV0dXJuIDEgYmVpIEVyZm9sZywgMCBzb25zdC4KKyAgKi8KK3N0YXRpYyBpbnQgc2V0X21lc3NlbmdlcihzdHJpbmcgc3RyKSB7CisgIGludCBudW07CisgIHN0cmluZyBzOworCisgIGlmICghc3RyIHx8IHN0cj09IiIpIHsKKyAgICBpZiAoIXM9UXVlcnlQcm9wKFBfTUVTU0VOR0VSKSkKKyAgICAgIGlmICghbnVtPVF1ZXJ5UHJvcChQX0lDUSkpIAorICAgICAgICB3cml0ZSgiRHUgaGFzdCBrZWluZSBNZXNzZW5nZXItSUQgZ2VzZXR6dC5cbiIpOworICAgICAgZWxzZSAKKyAgICAgICAgcHJpbnRmKCJEdSBoYXN0IGtlaW5lIE1lc3Nlbmdlci1JRCBnZXNldHp0LCBhYmVyIGVpbmUgSUNRLU51bW1lcjogJWRcbiIsIG51bSk7CisgICAgZWxzZQorICAgICAgcHJpbnRmKCJEZWluZSBNZXNzZW5nZXItSUQgbGF1dGV0OiAlc1xuIiwgcyk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKHN0cj09ImxvZXNjaGVuIiB8fCBzdHI9PSJrZWluZSIpIHsKKyAgICB3cml0ZSgiRGVpbmUgTWVzc2VuZ2VyLUlEIHd1cmRlIGdlbG9lc2NodC5cbiIpOworICAgIFNldFByb3AoUF9NRVNTRU5HRVIsIDApOworICB9IGVsc2UgeworICAgIHMgPSBfdW5wYXJzZWRfYXJncygpOworICAgIHByaW50ZigiRGVpbmUgTWVzc2VuZ2VyLUlEIGxhdXRldCBudW46ICVzXG4iLCBzKTsKKyAgICBTZXRQcm9wKFBfTUVTU0VOR0VSLCBzKTsKKyAgfQorICByZXR1cm4gMTsKK30KKworCisvLyBQcnVlZnQsIG9iIGRlciBTdHJpbmcgdmVybXV0bGljaCBlaW5lIGVNYWlsLUFkcmVzc2UgaXN0LgorLy8gZGllcyBpc3QgbmljaHQgbmFycmVuc2ljaGVyLCB3aXJkIGFiZXIgZGllIG1laXN0ZW4gZU1haWwtQWRyZXNzZW4genVsYXNzZW4KKy8vIHVuZCB2aWVsIFNjaHJvdHQgYWJsZWhuZW4uCitwcml2YXRlIHN0cmluZyBjaGVja19lbWFpbChzdHJpbmcgc3RyKSB7CisgIGlmICghc3RyaW5ncChzdHIpKSByZXR1cm4gMDsKKyAgcmV0dXJuIHJlZ21hdGNoKGxvd2VyX2Nhc2Uoc3RyKSwKKyAgICAgICJbYS16MC05Ll8lKy1dK0AoPzpbYS16MC05LV0rXC4pK1thLXpdezIsNH0iLFJFX1BDUkUpOworfQorCisvKiogU2V0enQgRW1haWwtQWRyZXNzZSBkZXMgU3BpZWxlcnMgKFNwaWVsZXJrb21tYW5kbykuCisgICogXHBhcmFtW2luXSBzdHIgU3BpZWxlcmVpbmdhYmUKKyAgKiBccmV0dXJuIDEgYmVpIEVyZm9sZywgMCBzb25zdC4KKyAgKi8KK3N0YXRpYyBpbnQgc2V0X2VtYWlsKHN0cmluZyBzdHIpCit7CisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSkgeworICAgIHdyaXRlKCJEZWluZSBvZmZpemllbGxlIEVtYWlsLUFkcmVzc2UgbGF1dGV0OiAiICsgUXVlcnlQcm9wKFBfTUFJTEFERFIpCisgICAgICAgICAgKyJcbiIpOworICAgIHJldHVybiAxOworICB9CisgIHN0ciA9IGNoZWNrX2VtYWlsKHN0cik7CisgIGlmICghc3RyKSB7CisgICAgbm90aWZ5X2ZhaWwoIkRlaW5lIEVpbmdhYmUgc2NoZWludCBrZWluZSBndWVsdGlnZSBFTWFpbC1BZHJlc3NlICIKKyAgICAgICAgInp1IHNlaW4uXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICB3cml0ZSgiRGVpbmUgRU1haWwtQWRyZXNzZSB3dXJkZSBnZWFlbmRlcnQgenU6XG4iCisgICAgICArc3RyKyJcbiIpOworICBTZXRQcm9wKFBfTUFJTEFERFIsIHN0cik7CisgIHJldHVybiAxOworfQorCisvKiogU3BpZWxlcmtvbW1hbmRvICdzZWxic3Rsb2VzY2h1bmcnLgorICAqIEdpYnQgTWVsZHVuZyBhdXMgdW5kIGZyYWd0IG5hY2ggZWluZXIgQmVzdGFldGlndW5nLgorICAqIFxyZXR1cm4gMSBiZWkgRXJmb2xnLCAwIHNvbnN0LgorICAqLworc3RhdGljIGludCBzZWxmX2RlbGV0ZSgpCit7CisgIHdyaXRlKAorICAgICIgICAgIEIgSSBTIFQgIEQgVSAgRCBJIFIgIFcgSSBSIEsgTCBJIEMgSCAgUyBJIEMgSCBFIFIgPz8/Pz8/Pz8/Pz8/XG4iKworICAgICJXZW5uIER1IERpY2ggc2VsYnN0bG9lc2NoZW4gd2lsbHN0LCBpc3QgRGVpbiBDaGFyYWt0ZXIgVU5XSURFUlJVRkxJQ0hcbiIrCisgICAgInZlcmxvcmVuLiBFcyBnaWJ0IEtFSU5FIE1vZWdsaWNoa2VpdCBpaG4gd2llZGVyenVlcnNjaGFmZmVuLiBTb2xsdGVzdFxuIisKKyAgICAiRHUgbnVyIHplaXR3ZWlsaWcgdm9tICJNVUROQU1FIiB3ZWdibGVpYmVuIHdvbGxlbiwgc28gYmVudXR6ZSBiaXR0ZVxuIisKKyAgICAiZGVuIEJlZmVobCAnc3BpZWxwYXVzZScuXG4iKworICAgICJGYWxsc3QgRHUgRGljaCBpbW1lciBub2NoIHNlbGJzdGxvZXNjaGVuIHdpbGxzdCwgZ2liIERlaW4gUGFzc3dvcmQgZWluLiIrCisgICAgIlxuXG4iKTsKKyAgaW5wdXRfdG8oInNlbGZfZGVsZXRlMiIsSU5QVVRfUFJPTVBUfElOUFVUX05PRUNITywgIkJpdHRlIGRhcyBQYXNzd29yZCBhbmdlYmVuOiAiKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8qKiBTcGllbGVya29tbWFuZG8gJ3NlbGJzdGxvZXNjaHVuZycuCisgICogRW1wZmFlbmd0IEJlc3RhZXRpZ3VuZyBkZXMgU3BpZWxlcnMgdW5kIHJ1ZnQgTG9lc2NoZnVua3Rpb24gaW4gCisgICogL3NlY3VyZS9tYXN0ZXIgYXVmLgorICAqIFxwYXJhbVtpbl0gc3RyIFNwaWVsZXJlaW5nYWJlCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICovCitpbnQgc2VsZl9kZWxldGUyKHN0cmluZyBzdHIpCit7CisgIGludCByZXQ7CisgIHJldD0oaW50KSJzZWN1cmUvbWFzdGVyIi0+ZGVsZXRlX3BsYXllcihzdHIsIGdldHVpZChQTCkpOworICBpZiAoIXJldCkKKyAgeworICAgIHdyaXRlKCJEYXMgaGF0IG5pY2h0IGhpbmdlaGF1ZW4gKEdvdHQgc2VpIERhbmsgLi4uLilcbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmIChRdWVyeVByb3AoUF9HVUlMRCkmJmZpbGVfc2l6ZShHVUlMRF9ESVIrUXVlcnlQcm9wKFBfR1VJTEQpKyIuYyIpPi0xKQorICAgIGNhdGNoKGNhbGxfb3RoZXIoR1VJTERfRElSK1F1ZXJ5UHJvcChQX0dVSUxEKSwgImF1c3RyZXRlbiIpO3B1Ymxpc2gpOworCisgIGlmIChRdWVyeVByb3AoUF9ERUFEUykgPCA1KSB7CisgICAgd3JpdGUoIkFkaW9zISBNYW4gc2llaHQgc2ljaC5cbiIpOworICAgIHNheShuYW1lKFdFUiwxKSsiIGhhdCBzaWNoIGdlcmFkZSBzZWxic3QgemVyc3RvZXJ0LlxuIik7CisgIH0KKyAgZWxzZSB7CisgICAgd3JpdGUoCisgICAgICAiXG5Ub2Qga29tbXQgYXVmIHNlaW5lbSB3ZWlzc2VuIFBmZXJkIGFuZ2VyaXR0ZW4uXG4iCisgICAgICsiRXIgc3RlaWd0IGFiLCBiYXV0IHNpY2ggZHJvaGVuZCB2b3IgRGlyIGF1ZiB1bmQgbXVzdGVydCBEaWNoIHNjaGFkZW5mcm9oLlxuIgorICAgICArIlxuVG9kIHNhZ3Q6IEVORExJQ0ghIE5VTiBLQU5OIERJUiBBVUNIIExBUlMgTklDSFQgTUVIUiBIRUxGRU4hXG4iCisgICAgICsiXG5Ub2QgaG9sdCB3ZWl0IG1pdCBzZWluZXIgU2Vuc2UgYXVzLiBNaXQgZ3Jvc3NlbSBTY2h3dW5nIGxhZXNzdCBlciBzaWUgYXVmXG4iCisgICAgICsiRGljaCB6dXNhdXNlbiB1bmQgZGFubi4uLlxuIik7CisgICAgc2F5KG5hbWUoV0VSLDEpKyIgc2NoaWVkIGdlcmFkZSBlbmRndWVsdGlnIHZvbiB1bnMuXG4iKTsKKyAgfQorCisgIC8vIEV2ZW50IGF1c2xvZXNlbi4gOy0pCisgIEVWRU5URC0+VHJpZ2dlckV2ZW50KEVWVF9MSUJfUExBWUVSX0RFTEVUSU9OLCAoWworICAgICAgICBFX1BMTkFNRTogZ2V0dWlkKE1FKSwKKyAgICAgICAgRV9FTlZJUk9OTUVOVDogZW52aXJvbm1lbnQoKSwKKyAgICAgICAgRV9HVUlMRE5BTUU6IFF1ZXJ5UHJvcChQX0dVSUxEKSBdKSApOworCisgIHJlbW92ZSgxKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8qKiBTZXR6dCBuZXVlIHRhZWdsaWNoZSBTcGllbGRhdWVyIChTcGllbGVya29tbWFuZG8pLgorICAqIFxwYXJhbVtpbl0gc3RyIFNwaWVsZXJlaW5nYWJlCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICovCitzdGF0aWMgaW50IHNwaWVsZGF1ZXIoc3RyaW5nIHN0cikgeworICBpbnQgbWluLGRheTsKKyAgc3RyaW5nIGZvbzsKKworICBub3RpZnlfZmFpbCgiICBzcGllbGRhdWVyIDx4PiBtaW51dGVuIGZ1ZXIgJWQgdGFnZVxub2RlclxuIisKKyAgICAgICAgICAgICAgIiAgc3BpZWxkYXVlciA8eD4gc3R1bmRlbiBmdWVyICVkIHRhZ2VcbiIpOworICBpZiAoIXN0cikKKyAgICByZXR1cm4gMDsKKyAgaWYgKHNzY2FuZihzdHIsIiVkIHN0dW5kZSVzIGZ1ZXIgJWQgdGFnJXMiLG1pbixmb28sZGF5LGZvbyk9PTQpCisgICAgbWluKj02MDsKKyAgZWxzZSBpZiAoc3NjYW5mKHN0ciwiJWQgbWludXRlJXMgZnVlciAlZCB0YWclcyIsbWluLGZvbyxkYXksZm9vKSE9NCkKKyAgICByZXR1cm4gMDsKKyAgaWYgKG1pbjw1KQorICAgIG1pbj01OworICBpZiAobWluPj0xNDQwKQorICAgIHJldHVybiBub3RpZnlfZmFpbCgiV2l0emJvbGQuXG4iKSwwOworCisgIFNldChQX0RBSUxZX1BMQVlUSU1FLAorICAgICAgKHttaW4qNjAsdGltZSgpLzg2NDAwK2RheSx0aW1lKCkvODY0MDAsdGltZSgpLG1pbio2MH0pKTsKKyAgLy8gMDpNaW51dGVuIHBybyBUYWcsIDE6TnIuIGRlcyBsZXR6ZW4gVGFnZXMsIDI6TnIuIGRlcyBhbmdlZmFuZ2VuZW4gVGFnZXMsCisgIC8vIDM6bGV0enRlIFplaXRwcnVlZnVuZywgNDp2ZXJibGVpYmVuZGUgWmVpdAorICBwcmludGYoIkR1IGRhcmZzdCBkaWUgbmFlY2hzdGVuICVkIFRhZyhlKSBudXIgbm9jaFxuIisKKyAgICIlZCBNaW51dGVuIGFtIFRhZyBtdWRkZW4uXG4iLGRheSxtaW4pOworICByZXR1cm4gMTsKK30KKworLyoqIEludGVycHJldGllcnQgQW5nYWJlIGRlcyBTcGllbGVycyBmdWVyIFNwaWVscGF1c2UuCisgICogXHBhcmFtW2luXSBhIFplaXRhbmdhYmUgZnVlciBTcGllbHBhdXNlLgorICAqIFxyZXR1cm4gWmVpdHB1bmt0LCBFbmRlIGRlciBTcGllbHBhdXNlLgorICAqLworcHJpdmF0ZSBpbnQgSW50ZXJwcmV0VGltZShzdHJpbmcgYSl7CisgIC8vIGFremVwdGllcnQgZm9sZ2VuZGUgRm9ybWF0ZToKKyAgLy8gICBkZC5tbS5qaiAgICAgKFJ1ZWNrZ2FiZTogMDowMCBkZXMgZW50c3ByZWNoZW5kZW4gVGFnZXMpCisKKyAgaW50ICp0cyA9IGFsbG9jYXRlKDkpOworICBpbnQgaSxqLGssbnJhcmdzOworCisgIGlmICgobnJhcmdzPXNzY2FuZihhLCIlZC4lZC4lZCIsaSxqLGspKT09MyB8fAorICAgICAgKG5yYXJncz1zc2NhbmYoYSwiJWQuJWQuIixpLGopKT09MikgeworICAgIC8vIHdlbm4ga2VpbiBqYWhyIGFuZ2VnZWJlbiBpc3QsIGRhcyBha3R1ZWxsZSBuZWhtZW4uCisgICAgaWYgKG5yYXJncyA9PSAyKQorICAgICAgIHRzW1RNX1lFQVJdID0gbG9jYWx0aW1lKClbVE1fWUVBUl07CisgICAgZWxzZSB7CisgICAgICAgLy8gWndlaS1aaWZmZXJuLUFuZ2FiZSBkZXMgSmFocmVzLi4uCisgICAgICAgaWYgKGs8MTAwKQorICAgICAgICAgICBrICs9IDIwMDA7CisgICAgICAgdHNbVE1fWUVBUl0gPSBrOworICAgIH0KKyAgICB0c1tUTV9NREFZXSA9IGk7CisgICAgdHNbVE1fTU9OXSA9IGogLSAxOworCisgICAgaW50IHplaXQgPSBta3RpbWUodHMpOworCisgICAgLy8gbmVnYXRpdmUgdW5kIHZlcmdhbmdlbmUgWmVpdGVuIHBydWVmZW4uCisgICAgaWYgKHplaXQgPD0gdGltZSgpKSB7CisgICAgICB3cml0ZSgiRGllc2VyIFplaXRwdW5rdCBsaWVndCBpbiBkZXIgVmVyZ2FuZ2VuaGVpdC5cbiIpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHJldHVybiB6ZWl0OworICB9CisgIHJldHVybiAwOworfQorCisvKiogU2V0enQgbmV1ZSBTcGllbHBhdXNlIChTcGllbGVya29tbWFuZG8pLgorICAqIEZyYWd0IHZvcmhlciBuYWNoIEJlc3RhZXRpZ3VuZyBkdXJjaCBkZW4gU3BpZWxlci4KKyAgKiBccGFyYW1baW5dIHN0ciBTcGllbGVyZWluZ2FiZQorICAqIFxyZXR1cm4gMSBiZWkgRXJmb2xnLCAwIHNvbnN0LgorICAqIFxzYSBzcGllbHBhdXNlMigpCisgICovCitzdGF0aWMgaW50IHNwaWVscGF1c2Uoc3RyaW5nIHN0cikKK3sKKyAgaW50IGRheXMsZW5kZXplaXQ7CisgIHN0cmluZyBmb287CisKKyAgbm90aWZ5X2ZhaWwoInNwaWVscGF1c2UgPHg+IHRhZ2UgICAgICAgICAgb2RlclxuIisKKyAgICAgICAgICAgICAgInNwaWVscGF1c2UgYmlzIHR0Lm1tWy5qal1cbiIpOworICBpZiAoIXN0cikgcmV0dXJuIDA7CisgIGlmKHNzY2FuZihfdW5wYXJzZWRfYXJncygpLCJiaXMgJXMiLGZvbyk9PTEpIHsKKyAgICBlbmRlemVpdCA9IEludGVycHJldFRpbWUoZm9vKTsKKyAgICBpZiAoZW5kZXplaXQgPT0gMCkgCisgICAgICAgIHJldHVybiAwOworICAgIGRheXMgPSAoKGVuZGV6ZWl0IC0gdGltZSgpKSAvIDg2NDAwKSArIDE7CisgIH0KKyAgZWxzZSBpZihzc2NhbmYoc3RyLCAiJWQgdGFnJXMiLCBkYXlzLCBmb28pID09IDIpIHsKKyAgICBpZiAoZGF5cyA8IDApCisgICAgICAgIGRheXMgPSAtMTsKKyAgICBlbHNlCisgICAgICAgIGVuZGV6ZWl0ID0gKHRpbWUoKS84NjQwMCkgKiA4NjQwMCArIGRheXMgKiA4NjQwMDsKKyAgfQorICBlbHNlIHJldHVybiAwOworCisgIGlmIChkYXlzID4gMCkKKyAgICB3cml0ZShzdHJmdGltZSgiRHUgd2lyc3QgRGljaCBlcnN0IHdpZWRlciBhbSAlZC4lbS4lWSBlaW5sb2dnZW4ga29lbm5lbiFcbiIsCisgICAgICAgICAgZW5kZXplaXQpKTsKKyAgZWxzZSBpZiAoZGF5cyA8IDApCisgICAgd3JpdGUoICJEdSB3aXJzdCBEaWNoIGF1ZiB1bmJlc3RpbW10ZSBaZWl0IG5pY2h0IG1laHIgZWlubG9nZ2VuIGtvZW5uZW4uXG4iCisgICAgICAgICAgKyJXZW5uIER1IHdpZWRlciBzcGllbGVuIHdpbGxzdCwgbXVzc3QgRHUgRGljaCBhbiBlaW5lbiBHb3R0IG9kZXJcbiIKKyAgICAgICAgICArIkVyem1hZ2llciB3ZW5kZW4gKG1pdCBlaW5lbSBHYXN0IG9kZXIgTWFpbCB2b24gYXVzc2VuKS5cbiIgKTsKKyAgZWxzZSB7CisgICAgd3JpdGUoICJEaWUgU3BpZWxwYXVzZSBpc3QgYXVmZ2Vob2Jlbi5cbiIgKTsKKyAgICBtYXN0ZXIoKS0+VEJhbmlzaE5hbWUoZ2V0dWlkKHRoaXNfb2JqZWN0KCkpLCAwKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICB3cml0ZSggIldlbm4gRHUgZGFzIHdpcmtsaWNoIHdpbGxzdCwgZ2liIGpldHp0ICdqYScgZWluLlxuIiApOworICBpbnB1dF90byggInNwaWVscGF1c2UyIiwgSU5QVVRfUFJPTVBULCAiXSIsIGRheXMpOworICByZXR1cm4gMTsKK30KKworLyoqIFNldHp0IG5ldWUgdGFlZ2xpY2hlIFNwaWVsZGF1ZXIsIHdpcmQgdWViZXIgc3BpZWxwYXVzZSgpIGdlcnVmZW4uCisgICogXHBhcmFtW2luXSBzdHIgU3BpZWxlcmVpbmdhYmUsIEJlc3RhZXRpZ3VuZworICAqIFxwYXJhbVtpbl0gZGF5cyBEYXVlciBkZXIgU3BpZWxwYXVzZSAoaW4gVGFnZW4pLgorICAqIFxzYSBzcGllbHBhdXNlKCkKKyAgKi8KK3N0YXRpYyB2b2lkIHNwaWVscGF1c2UyKHN0cmluZyBzdHIsIGludCBkYXlzKQoreworICBpZiAoc3RyICYmIChzdHIgPT0gImphIiB8fCBzdHIgPT0gIkphIiB8fCBzdHIgPT0gIkpBIikpIHsKKyAgICBtYXN0ZXIoKS0+VEJhbmlzaE5hbWUoZ2V0dWlkKHRoaXNfb2JqZWN0KCkpLCBkYXlzKTsKKyAgICB3cml0ZSgKKyAgICAgICJPaywgZGllIFNwaWVscGF1c2Ugd2lyZCBtaXQgZGVtIG5hZWNoc3RlbiBBdXNsb2dnZW4gd2lya3NhbS5cbiIKKyAgICAgKyJTb2xsdGVzdCBEdSBlcyBEaXIgYmlzIGRhaGluIG5vY2ggZWlubWFsIHVlYmVybGVndCBoYWJlbiwgc28ga2FubnN0XG4iCisgICAgICsiRHUgZGVuIFZvcmdhbmcgbWl0ICdzcGllbHBhdXNlIDAgdGFnZScgd2llZGVyIHJ1ZWNrZ2FlbmdpZyBtYWNoZW4uXG4iICk7CisgICAgcmV0dXJuOworICB9CisgIHdyaXRlKCJWb3JnYW5nIHd1cmRlIGFiZ2Vicm9jaGVuLlxuIiApOworfQorCisvKiogU2V0enQgbmV1ZXMgUGFzc3dvcnQgKFNwaWVsZXJrb21tYW5kbykuCisgICogRnJhZ3QgbmFjaCBhbHRlbSBQYXNzd29ydCB1bmQgcnVmdCBjaGFuZ2VfcGFzc3dvcmQyKCkuCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICogXHNhIGNoYW5nZV9wYXNzd29yZDIoKSwgY2hhbmdlX3Bhc3N3b3JkMygpLCBjaGFuZ2VfcGFzc3dvcmQ0KCkKKyAgKi8KK3N0YXRpYyBpbnQgY2hhbmdlX3Bhc3N3b3JkKCkgeworICBzdHJpbmcgdmVyYjsKKyAgdmVyYj1xdWVyeV92ZXJiKCk7CisgIGlmICh2ZXJiIT0icGFzc3dkIiYmdmVyYiE9InBhc3N3b3JkIiYmdmVyYiE9InBhc3N3b3J0IikKKyAgICByZXR1cm4gMDsKKyAgaW5wdXRfdG8oImNoYW5nZV9wYXNzd29yZDIiLElOUFVUX05PRUNIT3xJTlBVVF9QUk9NUFQsCisgICAgICAiQml0dGUgZGFzIEFMVEUgUGFzc3dvcnQgYW5nZWJlbjogIik7CisgIHJldHVybiAxOworfQorCisvKiogU2V0enQgbmV1ZXMgUGFzc3dvcnQgKFNwaWVsZXJrb21tYW5kbykuCisgICogUHJ1ZWZ0IGFsdGVzIFBhc3N3b3J0LCBmcmFndCBuYWNoIG5ldWVtIFBhc3N3b3J0IHVuZCBydWZ0IAorICAqICAgY2hhbmdlX3Bhc3N3b3JkMygpLgorICAqIFxwYXJhbVtpbl0gc3RyIFNwaWVsZXJlaW5nYWJlIGRlcyBhbHRlbiBQYXNzd29ydGVzCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICogXHNhIGNoYW5nZV9wYXNzd29yZCgpLCBjaGFuZ2VfcGFzc3dvcmQzKCksIGNoYW5nZV9wYXNzd29yZDQoKQorICAqLworc3RhdGljIGludCBjaGFuZ2VfcGFzc3dvcmQyKHN0cmluZyBzdHIpIHsKKyAgd3JpdGUoIlxuIik7CisgIGlmICghc3RyKQorICAgIHN0cj0iIjsKKyAgaWYgKE1BU1RFUi0+dXBkYXRlX3Bhc3N3b3JkKHN0cixzdHIpID09IDApIHsKKyAgICB3cml0ZSgiRmFsc2NoZXMgUGFzc3dvcnQhXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBwYXNzd29sZCA9IHN0cjsKKyAgaW5wdXRfdG8oImNoYW5nZV9wYXNzd29yZDMiLElOUFVUX05PRUNIT3xJTlBVVF9QUk9NUFQsCisgICAgICAiQml0dGUgZGFzIE5FVUUgUGFzc3dvcnQgZWluZ2ViZW46ICIpOworICByZXR1cm4gMTsKK30KKworLyoqIFNldHp0IG5ldWVzIFBhc3N3b3J0IChTcGllbGVya29tbWFuZG8pLgorICAqIFBydWVmdCBuZXVlcyBQYXNzd29ydCwgZnJhZ3QgbmFjaCBCZXN0YWV0aWd1bmcgZGVzIG5ldWVzCisgICogUGFzc3dvcnRlcyB1bmQgcnVmdCBjaGFuZ2VfcGFzc3dvcmQ0KCkuCisgICogXHBhcmFtW2luXSBzdHIgU3BpZWxlcmVpbmdhYmUgZGVzIG5ldWVuIFBhc3N3b3J0ZXMKKyAgKiBccmV0dXJuIDEgYmVpIEVyZm9sZywgMCBzb25zdC4KKyAgKiBcc2EgY2hhbmdlX3Bhc3N3b3JkKCksIGNoYW5nZV9wYXNzd29yZDIoKSwgY2hhbmdlX3Bhc3N3b3JkNCgpCisgICovCitzdGF0aWMgaW50IGNoYW5nZV9wYXNzd29yZDMoIHN0cmluZyBzdHIgKQoreworICAgIHdyaXRlKCAiXG4iICk7CisKKyAgICBpZiAoICFzdHIgfHwgc3RyID09ICIiICl7CisgICAgICAgIHdyaXRlKCAiQWJnZWJyb2NoZW4gIVxuIiApOworICAgICAgICBwYXNzd29sZCA9IHBhc3N3ID0gMDsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgaWYgKCBwYXNzd29sZCA9PSBzdHIgKXsKKyAgICAgICAgd3JpdGUoICJEYXMgd2FyIERlaW4gYWx0ZXMgUGFzc3dvcnQuXG4iICk7CisgICAgICAgIGlucHV0X3RvKCAiY2hhbmdlX3Bhc3N3b3JkMyIsIElOUFVUX05PRUNIT3xJTlBVVF9QUk9NUFQsCisgICAgICAgICAgICAiQml0dGUgZGFzIE5FVUUgUGFzc3dvcnQgZWluZ2ViZW4gKHp1bSBBYmJydWNoIFJldHVybiBkcnVlY2tlbik6ICIpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICBpZiAoICFNQVNURVItPmdvb2RfcGFzc3dvcmQoIHN0ciwgZ2V0dWlkKE1FKSApICl7CisgICAgICAgIGlucHV0X3RvKCAiY2hhbmdlX3Bhc3N3b3JkMyIsIElOUFVUX05PRUNIT3xJTlBVVF9QUk9NUFQsCisgICAgICAgICAgICAiQml0dGUgZGFzIE5FVUUgUGFzc3dvcnQgZWluZ2ViZW46ICIpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICBwYXNzdyA9IHN0cjsKKyAgICBpbnB1dF90byggImNoYW5nZV9wYXNzd29yZDQiLCBJTlBVVF9OT0VDSE98SU5QVVRfUFJPTVBULAorICAgICAgICAiQml0dGUgbm9jaG1hbDogIik7CisgICAgcmV0dXJuIDE7Cit9CisKKy8qKiBTZXR6dCBuZXVlcyBQYXNzd29ydCAoU3BpZWxlcmtvbW1hbmRvKS4KKyAgKiBQcnVlZnQgbmV1ZXMgUGFzc3dvcnQgdW5kIHNldHp0IG5ldWVzIFBhc3N3b3J0LgorICAqIFxwYXJhbVtpbl0gc3RyIFNwaWVsZXJlaW5nYWJlIGRlcyBuZXVlbiBQYXNzd29ydGVzCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICogXHNhIGNoYW5nZV9wYXNzd29yZCgpLCBjaGFuZ2VfcGFzc3dvcmQyKCksIGNoYW5nZV9wYXNzd29yZDMoKQorICAqLworc3RhdGljIGludCBjaGFuZ2VfcGFzc3dvcmQ0KCBzdHJpbmcgc3RyICkKK3sKKyAgICB3cml0ZSggIlxuIiApOworCisgICAgaWYgKCAhc3RyIHx8IHN0ciAhPSBwYXNzdyApeworICAgICAgICB3cml0ZSggIkRhcyB3YXIgdmVyc2NoaWVkZW4hIFBhc3N3b3J0IE5JQ0hUIGdlYWVuZGVydC5cbiIgKTsKKyAgICAgICAgcGFzc3dvbGQgPSBwYXNzdyA9IDA7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIGlmICggTUFTVEVSLT51cGRhdGVfcGFzc3dvcmQoIHBhc3N3b2xkLCBwYXNzdyApICkKKyAgICAgICAgd3JpdGUoICJQYXNzd29ydCBnZWFlbmRlcnQuXG4iICk7CisgICAgZWxzZQorICAgICAgICB3cml0ZSggIkhhdCBuaWNodCBnZWtsYXBwdCFcbiIgKTsKKworICAgIHBhc3N3b2xkID0gcGFzc3cgPSAwOworICAgIHJldHVybiAxOworfQorCisKKy8qCisgKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBSdWVja21lbGR1bmdlbiB2b24gU3BpZWxlcm4gYW4gTWFnaWVyCisgKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKi8KK3N0YXRpYyBpbnQgZmVobGVyaGlsZmUoc3RyaW5nIHN0cikgeworICB3cml0ZSgiV2VsY2hlIEFydCB2b24gRmVobGVyIG1vZWNodGVzdCBEdSBkZW5uIG1lbGRlbj9cbiIKKyAgICAgICJGZWhsZnVua3Rpb25lbiAgICAtPiAgYnVnXG4iCisgICAgICAiSWRlZW4vQW5yZWd1bmdlbiAgLT4gIGlkZWVcbiIKKyAgICAgICJUaXBwZmVobGVyL1R5cG9zICAtPiAgdHlwb1xuIgorICAgICAgImZlaGxlbmRlIERldGFpbHMgIC0+ICBkZXRhaWxcbiIpOworCisgIHJldHVybiAxOworfQorCisvKiogU2V0enQgZWluZSBGZWhsZXJtZWxkdW5nIGFuIE1hZ2llciBhYiAoU3BpZWxlcmtvbW1hbmRvKS4KKyAgKiBGcmFndCBuYWNoIGRlciBGZWhsZXJtZWxkdW5nIHVuZCBsaWVzdCBzaWUgdmlhIGJ1ZzIoKSBlaW4sIGZhbGwgZGVyCisgICogU3BpZWxlciBrZWluIEFyZ3VtZW50IGFuZ2ViZW4gaGF0LgorICAqIFxwYXJhbVtpbl0gc3RyIG9wdGlvbmFsZSBTcGllbGVyZWluZ2FiZSBkZXIgRmVobGVyYmVzY2hyZWlidW5nCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICogQHNlZSBidWcyKHN0cmluZykKKyAgKi8KK3N0YXRpYyBpbnQgYnVnKHN0cmluZyBzdHIpIHsKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpKSB7CisgICAgd3JpdGUoICJXaWUgc2llaHQgZGVyIEZlaGxlciBkZW5uIGF1cz9cbiIgKTsKKyAgICBpbnB1dF90bygiYnVnMiIsIElOUFVUX1BST01QVCwgIl0iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICB3cml0ZSgiVmllbGVuIERhbmsgZnVlciBkaWUgSGlsZmUuXG4iKTsKKyAgc21hcnRfbG9nKCJCVUdTIixzdHIpOworICByZXR1cm4gMTsKK30KKworLyoqIFNldHp0IGVpbmUgRmVobGVybWVsZHVuZyBhbiBNYWdpZXIgYWIgKFNwaWVsZXJrb21tYW5kbykuCisgICogTGllcyBGZWhsZXJiZXNjaHJlaWJ1bmcgZWluIHVuZCBzcGVpY2hlcnQgc2llIGFiLgorICAqIFxwYXJhbVtpbl0gc3RyIFNwaWVsZXJlaW5nYWJlIGRlciBGZWhsZXJiZXNjaHJlaWJ1bmcuCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICogQHNlZSBidWcoc3RyaW5nKQorICAqLworc3RhdGljIGludCBidWcyKHN0cmluZyBzdHIpIHsKKyAgaWYgKCFzdHIgfHwgc3RyID09ICIiKSB7CisgICAgd3JpdGUoIkJ1ZyBhYmdlYnJvY2hlbi4uLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgd3JpdGUoIlZpZWxlbiBEYW5rIGZ1ZXIgZGllIEhpbGZlLlxuIik7CisgIHNtYXJ0X2xvZygiQlVHUyIsc3RyKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8qKiBTZXR6dCBlaW5lIFR5cG9tZWxkdW5nIGFuIE1hZ2llciBhYiAoU3BpZWxlcmtvbW1hbmRvKS4KKyAgKiBGcmFndCBuYWNoIGRlciBUeXBvbWVsZHVuZyB1bmQgbGllc3Qgc2llIHZpYSB0eXBvMigpIGVpbiwgZmFsbCBkZXIKKyAgKiBTcGllbGVyIGtlaW4gQXJndW1lbnQgYW5nZWJlbiBoYXQuCisgICogXHBhcmFtW2luXSBzdHIgb3B0aW9uYWxlIFNwaWVsZXJlaW5nYWJlIGRlciBUeXBvYmVzY2hyZWlidW5nCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICogQHNlZSB0eXBvMihzdHJpbmcpCisgICovCitzdGF0aWMgaW50IHR5cG8oc3RyaW5nIHN0cikgeworICBpZiAoIShzdHI9X3VucGFyc2VkX2FyZ3MoKSkpIHsKKyAgICB3cml0ZSggIldvIGlzdCBkZW5uIGRlciBUaXBwZmVobGVyP1xuIiApOworICAgIGlucHV0X3RvKCJ0eXBvMiIsIElOUFVUX1BST01QVCwgIl0iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICB3cml0ZSgiVmllbGVuIERhbmsgZnVlciBkaWUgSGlsZmUuXG4iKTsKKyAgc21hcnRfbG9nKCJUWVBPIixzdHIpOworICByZXR1cm4gMTsKK30KKworLyoqIFNldHp0IGVpbmUgRmVobGVybWVsZHVuZyBhbiBNYWdpZXIgYWIgKFNwaWVsZXJrb21tYW5kbykuCisgICogTGllc3QgZGllIFR5cG9iZXNjaHJlaWJ1bmcgZWluIHVuZCBzcGVpY2hlcnQgc2llLgorICAqIFxwYXJhbVtpbl0gc3RyIFNwaWVsZXJlaW5nYWJlIGRlciBUeXBvYmVzY2hyZWlidW5nCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICogQHNlZSB0eXBvKHN0cmluZykKKyAgKi8KK3N0YXRpYyBpbnQgdHlwbzIoc3RyaW5nIHN0cikgeworICBpZiAoIXN0ciB8fCBzdHIgPT0gIiIpIHsKKyAgICB3cml0ZSgiVHlwbyBhYmdlYnJvY2hlbi4uLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgc21hcnRfbG9nKCJUWVBPIixzdHIpOworICB3cml0ZSgiVmllbGVuIERhbmsgZnVlciBkaWUgSGlsZmUuXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8qKiBTZXR6dCBlaW5lIElkZWUgYW4gTWFnaWVyIGFiIChTcGllbGVya29tbWFuZG8pLgorICAqIEZyYWd0IG5hY2ggZGVyIElkZWUgdW5kIGxpZXN0IHNpZSB2aWEgaWRlZTIoKSBlaW4sIGZhbGxzIGRlcgorICAqIFNwaWVsZXIga2VpbiBBcmd1bWVudCBhbmdlYmVuIGhhdC4KKyAgKiBccGFyYW1baW5dIHN0ciBvcHRpb25hbGUgU3BpZWxlcmVpbmdhYmUgZGVyIElkZWUKKyAgKiBccmV0dXJuIDEgYmVpIEVyZm9sZywgMCBzb25zdC4KKyAgKiBAc2VlIGlkZWEyKHN0cmluZykKKyAgKi8KK3N0YXRpYyBpbnQgaWRlYShzdHJpbmcgc3RyKSB7CisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSkgeworICAgIHdyaXRlKCAiV2FzIGZ1ZXIgZWluZSBJZGVlIGhhc3QgRHUgZGVubj9cbiIgKTsKKyAgICBpbnB1dF90bygiaWRlYTIiLElOUFVUX1BST01QVCwgIl0iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICB3cml0ZSgiVmllbGVuIERhbmsgZnVlciBkaWUgSGlsZmUuXG4iKTsKKyAgc21hcnRfbG9nKCJJREVBIixzdHIpOworICByZXR1cm4gMTsKK30KKworLyoqIFNldHp0IGVpbmUgSWRlZSBhbiBNYWdpZXIgYWIgKFNwaWVsZXJrb21tYW5kbykuCisgICogTGllc3QgZGllIElkZWUgZWluIHVuZCBzcGVpY2hlcnQgc2llLgorICAqIFxwYXJhbVtpbl0gc3RyIFNwaWVsZXJlaW5nYWJlIGRlciBJZGVlCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICogQHNlZSBpZGVhKHN0cmluZykKKyAgKi8KK3N0YXRpYyBpbnQgaWRlYTIoc3RyaW5nIHN0cikgeworICBpZiAoIXN0ciB8fCBzdHIgPT0gIiIpIHsKKyAgICB3cml0ZSgiSWRlZSBhYmdlYnJvY2hlbi4uLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgd3JpdGUoIlZpZWxlbiBEYW5rIGZ1ZXIgZGllIEhpbGZlLlxuIik7CisgIHNtYXJ0X2xvZygiSURFQSIsc3RyKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8qKiBTZXR6dCBlaW4gZmVobGVuZGVzIERldGFpbCBhbiBNYWdpZXIgYWIgKFNwaWVsZXJrb21tYW5kbykuCisgICogRnJhZ3QgbmFjaCBkZW0gRGV0YWlsIHVuZCBsaWVzdCBlcyB2aWEgaWRlZTIoKSBlaW4sIGZhbGxzIGRlcgorICAqIFNwaWVsZXIga2VpbiBBcmd1bWVudCBhbmdlYmVuIGhhdC4KKyAgKiBccGFyYW1baW5dIHN0ciBvcHRpb25hbGUgU3BpZWxlcmVpbmdhYmUgZGVzIGZlaGxlbmRlbiBEZXRhaWxzCisgICogXHJldHVybiAxIGJlaSBFcmZvbGcsIDAgc29uc3QuCisgICogQHNlZSBtZDIoc3RyaW5nKQorICAqLworc3RhdGljIGludCBtZChzdHJpbmcgc3RyKSB7CisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSkgeworICAgIHdyaXRlKCAiRnVlciB3ZWxjaGVzIERldGFpbCBmZWhsdCBkZW5uIGRpZSBCZXNjaHJlaWJ1bmc/XG4iICk7CisgICAgaW5wdXRfdG8oIm1kMiIsSU5QVVRfUFJPTVBULCAiXSIpOworICAgIHJldHVybiAxOworICB9CisgIHdyaXRlKCJWaWVsZW4gRGFuayBmdWVyIGRpZSBIaWxmZS5cbiIpOworICBzbWFydF9sb2coIkRFVEFJTFMiLHN0cik7CisgIHJldHVybiAxOworfQorCisvKiogU2V0enQgZWluIGZlaGxlbmRlcyBEZXRhaWwgYW4gTWFnaWVyIGFiIChTcGllbGVya29tbWFuZG8pLgorICAqIExpZXN0IGRhcyBEZXRhaWwgZWluIHVuZCBzcGVpY2hlcnQgZXMuCisgICogXHBhcmFtW2luXSBzdHIgU3BpZWxlcmVpbmdhYmUgZGVzIGZlaGxlbmRlbiBEZXRhaWxzLgorICAqIFxyZXR1cm4gMSBiZWkgRXJmb2xnLCAwIHNvbnN0LgorICAqIEBzZWUgbWQoc3RyaW5nKQorICAqLworc3RhdGljIGludCBtZDIoc3RyaW5nIHN0cikgeworICBpZiAoIXN0ciB8fCBzdHIgPT0gIiIpIHsKKyAgICB3cml0ZSgiRGV0YWlscyBhYmdlYnJvY2hlbi4uLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgd3JpdGUoIlZpZWxlbiBEYW5rIGZ1ZXIgZGllIEhpbGZlLlxuIik7CisgIHNtYXJ0X2xvZygiREVUQUlMUyIsc3RyKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8qKiBMb2dndCBlaW5lIFNwaWVsZXJtZWxkdW5nIGFuIE1hZ2llci4KKyAgKiBMb2dndCBkaWUgU3BpZWxlcm1lbGR1bmcgaW4gZGFzIHBhc3NlbmRlIEZpbGUgdW50ZXIgL2xvZy9yZXBvcnQvIG9kZXIgaW0KKyAgKiB2b20gTWFnaWVyIGdld3VlbnNjaHRlbiBGaWxlLiBIaWVyYmVpIHdlcmRlbiBGZWhsZXIsIElkZWVuLCBNRHMgdW5kIFR5cG9zCisgICogaW4gZ2V0cmVubnRlIEZpbGVzIHNvcnRpZXJ0LgorICAqIFxwYXJhbVtpbl0gc3RyIFNwaWVsZXJtZWxkdW5nCisgICogXHBhcmFtW2luXSBteW5hbWUgQXJ0IGRlciBTcGllbGVybWVsZHVuZyAoREVUQUlMUywgQlVHLCBUWVBPLCBNRCkKKyAgKiBAc2VlIG1kKHN0cmluZyksIGlkZWEoc3RyaW5nKSwgYnVnKHN0cmluZyksIHR5cG8oc3RyaW5nKQorICAqLwordm9pZCBzbWFydF9sb2coc3RyaW5nIG15bmFtZSwgc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nIG9ibmFtOworICBvYmplY3Qgb2JqOworCisgIHN0cmluZyAqdG1wID0gZXhwbG9kZShzdHIsICI6Iik7CisgIGlmIChzaXplb2YodG1wKSA+IDEpIHsKKyAgICBvYm5hbSA9IGxvd2VyX2Nhc2UodHJpbSh0bXBbMF0pKTsKKyAgICBvYmogPSBwcmVzZW50KG9ibmFtLCBlbnZpcm9ubWVudCgpKSB8fCBwcmVzZW50KG9ibmFtKTsKKyAgICBpZiAoIW9iaikgeworICAgICAgb2JqID0gZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSk7CisgICAgfQorICAgIGVsc2UgLy8gbnVyIGhpZXIgVGVpbCB2b3IgZGVtIDogd2Vnc2NobmVpZGVuCisgICAgICBzdHIgPSB0cmltKGltcGxvZGUodG1wWzEuLl0sIjoiKSk7CisgIH0KKyAgZWxzZSB7CisgICAgb2JqID0gUXVlcnlQcm9wKFBfUkVGRVJFTkNFX09CSkVDVCk7CisgICAgaWYgKCFvYmogfHwgIXByZXNlbnQob2JqKSkKKyAgICAgIG9iaiA9IGVudmlyb25tZW50KHRoaXNfaW50ZXJhY3RpdmUoKSk7CisgIH0KKworICBtYXBwaW5nIGVyciA9IChbIEZfUFJPRzogInVuYmVrYW5udCIsCisgICAgICAgICAgIEZfTElORTogMCwKKyAgICAgICAgICAgRl9NU0c6IHN0ciwKKyAgICAgICAgICAgRl9PQko6IG9iagorICAgICAgICAgXSk7CisKKyAgc3RyaW5nIGRlc2M9ImV0d2FzIHVuYmVrYW5udGVzIjsKKyAgc3dpdGNoKG15bmFtZSkgeworICAgIGNhc2UgIkJVR1MiOgorICAgICAgZGVzYz0iZWluZW4gRmVobGVyIjsKKyAgICAgIGVycltGX1RZUEVdPVRfUkVQT1JURURfRVJSOworICAgICAgYnJlYWs7CisgICAgY2FzZSAiREVUQUlMUyI6CisgICAgICBkZXNjPSJlaW4gZmVobGVuZGVzIERldGFpbCI7CisgICAgICBlcnJbRl9UWVBFXT1UX1JFUE9SVEVEX01EOworICAgICAgYnJlYWs7CisgICAgY2FzZSAiSURFQSI6CisgICAgICBkZXNjPSJlaW5lIElkZWUiOworICAgICAgZXJyW0ZfVFlQRV09VF9SRVBPUlRFRF9JREVBOworICAgICAgYnJlYWs7CisgICAgY2FzZSAiVFlQTyI6CisgICAgICBkZXNjPSJlaW5lbiBUeXBvIjsKKyAgICAgIGVycltGX1RZUEVdPVRfUkVQT1JURURfVFlQTzsKKyAgICAgIGJyZWFrOworICB9CisKKyAgLy8gRWludHJhZ3VuZyBpbiBkaWUgRmVobGVyLURCCisgIHN0cmluZyBoYXNoa2V5ID0gKHN0cmluZylFUlJPUkQtPkxvZ1JlcG9ydGVkRXJyb3IoZXJyKTsKKworICAvLyBnZ2YuIHdpbGwgZGFzIE9iamVrdGUgbWl0IG5vY2ggaXJnZW5kd2FzIGFuZmFuZ2VuLgorICBvYmotPlNtYXJ0TG9nKDAsIG15bmFtZSwgc3RyLCBzdHJmdGltZSgiJWQuICViICVZIikpOworCisgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksIGJyZWFrX3N0cmluZyggc3ByaW50ZigKKyAgICAiRHUgaGFzdCBhbiAlcyBlcmZvbGdyZWljaCAlcyBhYmdlc2V0enQuXG4iCisgICAgIkRpZSBJRCBkZXIgYWJnZXNldHp0ZW4gTWVsZHVuZyBsYXV0ZXQ6ICVzXG4iLAorICAgIChvYmotPklzUm9vbSgpID8gImRpZXNlbSBSYXVtIiA6IG9iai0+bmFtZShXRU0sMSkpLGRlc2MsCisgICAgaGFzaGtleXx8Ik4vQSIpLDc4LEJTX0xFQVZFX01ZX0xGUykpOworfQorCisvKiogU3BlaWNoZXJ0IGRlbiBTcGllbGVyIHVuZCBsb2dndCBpaG4gYXVzIChTcGllbGVya29tbWFuZG8gJ2VuZGUnKS4KKyAgKiBEZXIgU3BpZWxlciB3aXJkIHZvbGxzdGFlbmRpZyBhdXNnZWxvZ2d0LCBkLmguIGRhcyBTcGllbGVyb2JqZWt0CisgICogemVyc3RvZXJ0LgorICAqIFxyZXR1cm4gMSBiZWkgRXJmb2xnLCAwIHNvbnN0LgorICAqIEBzZWUgZGlzY29ubmVjdCgpCisgICovCitpbnQgcXVpdCgpCit7CisgIGludCBhcmc7CisgIFNldFByb3AoUF9MQVNUX1FVSVQsdGltZSgpKTsKKyAgY2F0Y2goUmVtb3ZlQ2hhbm5lbHMoKTtwdWJsaXNoKTsKKyAgaWYoIVF1ZXJ5R3Vlc3QoKSkKKyAgeworICAgIHNhdmVfbWUoMCk7CisgICAgdGVsbF9vYmplY3QoTUUsIlNwZWljaGVyZSAiK1F1ZXJ5UHJvcChQX05BTUUpKyIuXG4iKTsKKyAgfQorCisgIGlmIChpbnRlcmFjdGl2ZShNRSkpCisgICAgY2FsbF9ub3RpZnlfcGxheWVyX2NoYW5nZSgwKTsKKworICByZW1vdmVfbGl2aW5nX25hbWUoKTsKKyAgLy8gRVZUX0xJQl9MT0dPVVQgd2lyZCBpbiByZW1vdmUoKSBnZXRyaWdnZXJ0LgorICBpZihjYXRjaChyZW1vdmUoKTtwdWJsaXNoKSkgZGVzdHJ1Y3QoTUUpOworICByZXR1cm4gMTsKK30KKworLyoqIFdyYXBwZXIgaW0gcXVpdCgpIGhlcnVtLCB2ZXJoaW5kZXJ0ICdlbmRlJywgZmFsbHMgU3BpZWxlciBrYWVtcGZ0LgorICAqIFxyZXR1cm4gMCBvZGVyIFJ1ZWNrZ2FiZXdlcnQgdm9uIHF1aXQoKQorICAqIEBzZWUgcXVpdCgpCisgICovCitzdGF0aWMgaW50IG5ld19xdWl0KCkgeworICBub3RpZnlfZmFpbCgiRHUgYmlzdCBpbiBHZWRhbmtlbiBub2NoIGJlaSBEZWluZW0gbGV0enRlbiBLYW1wZi5cbiIrCisgICAgICAgICAgICAgICJXYXJ0ZSBub2NoIGV0d2FzIGJldm9yIER1IGRhcyBTcGllbCB2ZXJsYWVzc3QsXG4iKworICAgICAgICAgICAgICAiZGFtaXQgRHUgc28gbmljaHQgaW4gUkwgd2VpdGVybWFjaHN0Li4uXG4iKTsKKyAgaWYgKHRpbWUoKS1RdWVyeShQX0xBU1RfQ09NQkFUX1RJTUUpPDEyMCAmJiAhSVNfTEVBUk5JTkcoTUUpKQorICAgIHJldHVybiAwOworICByZXR1cm4gcXVpdCgpOworfQorCisvKiogR2lidCBkaWUgSW5mb3MgdWViZXIgZGVuIENoYXIgYW4gZGVuIFNwaWVsZXIgYXVzIChTcGllbGVya29tbWFuZG8gJ2luZm8nKS4KKyAgKiBccGFyYW1baW5dIGFyZyBXZW5uIGFyZz09InNob3J0Iiwgd2lyZCBlaW5lIEt1cnp1ZWJlcnNpY2h0IGF1c2dlZ2ViZW4uCisgICogXHJldHVybiAxCisgICogQHNlZSBzaG9ydF9zY29yZSgpCisgICovCitzdGF0aWMgaW50IHNjb3JlKHN0cmluZyBhcmcpIHsKKyAgc3RyaW5nIHRtcCwgZ2VuZGVyOworICBpbnQgaSxzeix2YWw7CisgIG1peGVkIGluZDsKKyAgb2JqZWN0ICplbmVtMSwgKmVuZW0yLCAqaW52OworCisgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkpIHsKKyAgICB3cml0ZSgiSW0gZXdpZ2VuIExlYmVuIGdpYnQgZXMga2VpbmUgUHVua3RlLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBpbnQgcGxldiA9IExFUE1BU1RFUi0+UXVlcnlMZXZlbCgpOworIAorICBzd2l0Y2godG1wID0gUXVlcnlQcm9wKFBfR0VOREVSKSkgeworICBjYXNlIE1BTEU6IGdlbmRlciA9ICJtYWVubmxpY2giOyBicmVhazsKKyAgY2FzZSBGRU1BTEU6IGdlbmRlciA9ICJ3ZWlibGljaCI7IGJyZWFrOworICBjYXNlIE5FVVRFUjogZ2VuZGVyID0gIm5ldXRyYWwiOyBicmVhazsKKyAgZGVmYXVsdDogZ2VuZGVyID0gbG93ZXJfY2FzZSh0bXApOworICB9CisKKyAgaW5kID0gbV9pbmRpY2VzKFF1ZXJ5UHJvcChQX0FUVFJJQlVURVMpKTsKKyAgdG1wID0gIiI7CisgIGZvcmVhY2goc3RyaW5nIGluZGV4OiBpbmQpIHsKKyAgICBzdHJpbmcgYW5hbWU7CisgICAgc3dpdGNoIChpbmRleCkgeworICAgICAgY2FzZSAiaW50IjogYW5hbWUgPSAiSW50ZWxsaWdlbnoiOyBicmVhazsKKyAgICAgIGNhc2UgImNvbiI6IGFuYW1lID0gIkF1c2RhdWVyIjsgYnJlYWs7CisgICAgICBjYXNlICJkZXgiOiBhbmFtZSA9ICJHZXNjaGlja2xpY2hrZWl0IjsgYnJlYWs7CisgICAgICBjYXNlICJzdHIiOiBhbmFtZSA9ICJLcmFmdCI7IGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgaWYoc3RyaW5ncChpbmRleCkpIGFuYW1lID0gY2FwaXRhbGl6ZShpbmRleCk7CisgICAgICAgIGVsc2UgYW5hbWUgPSAiVW5iZWthbm50IjsKKyAgICB9CisgICAgYW5hbWUgPSBzcHJpbnRmKCIlLTE4Jy4ncyAlMi4yZCIsIGFuYW1lKyIgIiwgUXVlcnlSZWFsQXR0cmlidXRlKGluZGV4KSk7CisgICAgaWYoKHZhbCA9IFF1ZXJ5QXR0cmlidXRlT2Zmc2V0KGluZGV4KSkpCisgICAgICBhbmFtZSArPSBzcHJpbnRmKCIgKCVzJWQpIiwgKHZhbD49MD8iKyI6IiIpLCB2YWwpOworICAgIHRtcCArPSBhbmFtZSArICJcbiI7CisgIH0KKworICBwcmludGYoIi0gJS0nLSc2OHNcbiIsCisgICAgICAgICBUZWFtUHJlZml4KCkrY2FwaXRhbGl6ZShpbXBsb2RlKGV4cGxvZGUoc2hvcnQoKXx8IiIsIlxuIiksIiIpKSsiICIpOworICBpZihhcmchPSJzaG9ydCIpIHsKKyAgICBwcmludGYoIlJhc3NlIC4uLi4uLi4uLi4uLiAlLScgJzE4cyBBYmVudGV1ZXIgLi4uLi4uLi4gJWQgJXNcbiIsCisgICAgICAgICAgIFF1ZXJ5UHJvcChQX1JBQ0UpLCBRdWVyeVByb3AoUF9RUCksCisgICAgICAgICAgICh2YWwgPSBRTS0+UXVlcnlUb3RhbFFQKCkpID09IFF1ZXJ5UHJvcChQX1FQKSA/ICIiIDogIigiK3ZhbCsiKSIpOworICAgIHByaW50ZigiR2VzY2hsZWNodCAuLi4uLi4uICUtJyAnMThzIEdyb2Vzc2UgLi4uLi4uLi4uLiAlZCBjbVxuIiwKKyAgICAgICAgICAgZ2VuZGVyLCBRdWVyeVByb3AoUF9TSVpFKSk7CisgICAgcHJpbnRmKCJTdHVmZSAuLi4uLi4uLi4uLi4gJS0zLjNkICUtJyAnMTRzIEdld2ljaHQgLi4uLi4uLi4uLiAlZCBrZ1xuIiwKKyAgICAgICAgICAgUXVlcnlQcm9wKFBfTEVWRUwpLCAoUXVlcnlQcm9wKFBfTEVWRUwpIDwgcGxldiA/ICIoIitwbGV2KyIpIiA6ICIiKSwKKyAgICAgICAgICAgUXVlcnlQcm9wKFBfV0VJR0hUKSAvIDEwMDApOworICAgIHByaW50ZigiR2lsZGUgLi4uLi4uLi4uLi4uICUtJyAnMThzIEdpbGRlbnN0dWZlIC4uLi4uLiAlZFxuIiwKKyAgICAgICAgIGNhcGl0YWxpemUoUXVlcnlQcm9wKFBfR1VJTEQpKSwgUXVlcnlQcm9wKFBfR1VJTERfTEVWRUwpKTsKKyAgfQorICBwcmludGYoIkVyZmFocnVuZyAuLi4uLi4uLiAlLScgJzE4cyBDaGFyYWt0ZXIgLi4uLi4uLi4gJS1zXG5cbiIsCisgICAgICAgICBRdWVyeVByb3AoUF9YUCkrICIgUHVua3RlIiwgYWxfdG9fdGl0bGUoUXVlcnlQcm9wKFBfQUxJR04pKSk7CisgIHByaW50ZigiJSMtNzYuMnNcblxuIiwgdG1wKTsKKyAgcHJpbnRmKCJHZXN1bmRoZWl0IC4uLi4uLi4gJS0zLjNkICUtJyAnMTRzIEdpZnQgLi4uLi4uLi4uLi4uLiAlc1xuIiwKKyAgICAgICAgIFF1ZXJ5UHJvcChQX0hQKSwKKyAgICAgICAgIChRdWVyeVByb3AoUF9IUCkgPT0gKHZhbCA9IFF1ZXJ5UHJvcChQX01BWF9IUCkpID8gIiIgOiAiKCIrdmFsKyIpIiksCisgICAgICAgICAoKHZhbCA9IFF1ZXJ5UHJvcChQX1BPSVNPTikpID8KKyAgICAgICAgICAodmFsIDwgNCA/ICJsZWljaHQiIDogImdlZmFlaHJsaWNoIikgOiAiZ2VzdW5kIikpOworICBwcmludGYoIktvbnplbnRyYXRpb24gLi4uLiAlLTMuM2QgJS0nICcxNHMgVm9yc2ljaHQgLi4uLi4uLi4uICVzXG4iLAorICAgICAgICAgUXVlcnlQcm9wKFBfU1ApLAorICAgICAgICAgKFF1ZXJ5UHJvcChQX1NQKSA9PSAodmFsID0gUXVlcnlQcm9wKFBfTUFYX1NQKSkgPyAiIiA6ICIoIit2YWwrIikiKSwKKyAgICAgICAgICgoaW5kID0gUXVlcnlQcm9wKFBfV0lNUFkpKSA/ICIiK2luZCA6ICJtdXRpZyIpKTsKKyAgcHJpbnRmKCJUb2Rlc2ZvbGdlbi4uLi4uLi4gJS0nICcxOHMgJXNcbiIsCisgICAgICAgICAoKHZhbCA9IGRlYXRoX3N1ZmZlcmluZygpKSA/ICIiKygodmFsKzkpLzEwKSA6ICJrZWluIE1hbHVzIiksCisgICAgICAgICAoUXVlcnlQcm9wKFBfV0lNUFkpICYmIGluZD1RdWVyeVByb3AoUF9XSU1QWV9ESVJFQ1RJT04pKQorICAgICAgICAgPyBzcHJpbnRmKCJGbHVjaHRyaWNodHVuZyAuLi4gJU8iLCBpbmQpIDogIiIpOworICBwcmludGYoIiVzIiwKKyAgICAgICAgICh0aW1lKCktUXVlcnkoUF9MQVNUX0NPTUJBVF9USU1FKTwxMjAgJiYgIUlTX0xFQVJOSU5HKE1FKSkgPworICAgICAgICAgIlNwaWVsIHZlcmxhc3NlbiAuLiBuaWNodCBtb2VnbGljaFxuIiA6ICIiCisgICAgICAgICApOworCisgIGlmKGFyZyE9InNob3J0IikgeworICAgIHdyaXRlKGJyZWFrX3N0cmluZyhGb3JzY2h1bmcoKSwgNzApKTsKKyAgICBpZihpbmQ9UXVlcnlQcm9wKFBfQVdBWSkpCisgICAgICBwcmludGYoIkR1IGJpc3QgbmljaHQgYW5zcHJlY2hiYXI6ICVPXG4iLGluZCk7CisgIH0KKworICBpZihzaXplb2YoZW5lbTE9KChtaXhlZClRdWVyeUVuZW1pZXMoKSlbMF0pKSB7CisgICAgZW5lbTI9KHt9KTsKKyAgICBpbnY9YWxsX2ludmVudG9yeShlbnZpcm9ubWVudChNRSkpOworICAgIGZvcmVhY2gob2JqZWN0IGVuOiBlbmVtMSkgeworICAgICAgaWYgKG1lbWJlcihpbnYsZW4pPT0tMSkgLy8gSXN0IHVuc2VyIEZlaW5kIHVuZCBpc3QgbmljaHQgaGllcgorICAgICAgICBlbmVtMis9KHtlbn0pOworICAgIH0KKyAgICBpZihzaXplb2YoZW5lbTIpKQorICAgIHsKKyAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygKKyAgICAgICAgICAgICJEdSB2ZXJmb2xnc3QgIiArIENvdW50VXAobWFwX29iamVjdHMoZW5lbTIsICJuYW1lIiwgV0VOKSkrIi4iLAorICAgICAgICAgICAgNzgpKTsKKyAgICB9CisgIH0KKyAgaWYoYXJnIT0ic2hvcnQiKSBzaG93X2FnZSgpOworICBwcmludGYoIiUtJy0nNzBzXG4iLCAiIik7CisgIHJldHVybiAxOworfQorCisvKiogR2lidCBlaW5lIGt1ZXJ6ZXJlIEluZm8gdWViZXIgZGVuIENoYXIgYXVzIChTcGllbGVya29tbWFuZG8gcHVua3RlfHNjb3JlKS4KKyAgICBSdWZ0IHNjb3JlKCJzaG9ydCIpLgorICAqIFxwYXJhbVtpbl0gYXJnIFVOVVNFRAorICAqIFxyZXR1cm4gMSBiZWkgRXJmb2xnLCAwIHNvbnN0LgorICAqIEBzZWUgc2NvcmUoc3RyaW5nKSwgdmVyeV9zaG9ydF9zY29yZSgpCisgICovCitzdGF0aWMgaW50IHNob3J0X3Njb3JlKHN0cmluZyBhcmcpIHsKKyAgcmV0dXJuIHNjb3JlKCJzaG9ydCIpOworfQorCisvKiogR2lidCBlaW5lIE1pbmlpbmZvIHVlYmVyIExQIC8gS1AgYXVzIChTcGllbGVya29tbWFuZG86IGt1cnppbmZvKQorICAqIFxyZXR1cm4gMQorICAqIEBzZWUgc2NvcmUoc3RyaW5nKSwgc2hvcnRfc2NvcmUoc3RyaW5nKQorICAqLworc3RhdGljIGludCB2ZXJ5X3Nob3J0X3Njb3JlKHN0cmluZyBhcmcpIHsKKyAgaW50ICAgIGxwLG1scCx4bHAsa3AsbWtwLHhrcDsKKyAgc3RyaW5nIGJhcjsKKworICBscD1RdWVyeVByb3AoUF9IUCk7IG1scD1RdWVyeVByb3AoUF9NQVhfSFApOworICBrcD1RdWVyeVByb3AoUF9TUCk7IG1rcD1RdWVyeVByb3AoUF9NQVhfU1ApOworICBpZiAobWxwKQorICAgIHhscD0obHAqNDAvbWxwKTsKKyAgaWYgKG1rcCkKKyAgICB4a3A9KGtwKjQwL21rcCk7CisgIGJhcj0iICAuICAgIC4gICAgLiAgICAuICAgIC4gICAgLiAgICAuICAgIC4gICI7CisgIGlmIChRdWVyeVByb3AoUF9OT19BU0NJSV9BUlQpIHx8IGFyZyA9PSAiLWsiKQorICAgIHByaW50ZigiR2VzdW5kaGVpdDogJTMuM2QgKCUzLjNkKSwgS29uemVudHJhdGlvbjogJTMuM2QgKCUzLjNkKVxuIiwKKyAgICAgICAgICAgbHAsIG1scCwga3AsIG1rcCk7CisgIGVsc2UKKyAgICBwcmludGYoIkdlc3VuZGhlaXQ6ICAgIDAgfCUnIyc0MC40MHN8ICUzLjNkJXNcbiIrCisgICAgICAgICAgICJLb256ZW50cmF0aW9uOiAwIHwlJyMnNDAuNDBzfCAlMy4zZCVzXG4iLAorICAgICAgICAgICAoeGxwPDA/YmFyOmJhclt4bHAuLl0pLGxwLChscD09bWxwPyIiOnNwcmludGYoIiAoJWQpIixtbHApKSwKKyAgICAgICAgICAgKHhrcDwwP2JhcjpiYXJbeGtwLi5dKSxrcCwoa3A9PW1rcD8iIjpzcHJpbnRmKCIgKCVkKSIsbWtwKSkKKyAgICAgICAgICAgKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8qKiBHaWJ0IGVpbmUgTWFucGFnZS9IaWxmZXNlaXRlIGFuIGRlbiBTcGllbGVyIGF1cy4KKyAgICBCZXJ1ZWNrc2ljaHRpZ3QgaGllcmJlaSBkaWUgU3lub255bWxpc3RlIGF1cyBkaXIvLnN5bm9ueW0sIHVtIGRpZSByaWNodGlnZQorICAgIE1hbnBhZ2UgYXVzenVnZWJlbi4KKyAgKiBccGFyYW1baW5dIGRpciBWZXJ6ZWljaG5pcyBkZXIgZ2V3dWVuc2NodGVuIE1hbnBhZ2UKKyAgKiBccGFyYW1baW5dIHBhZ2UgTmFtZSBkZXIgZ2V3dWVuc2NodGVuIE1hbnBhZ2UKKyAgKiBccmV0dXJuIFN0cmluZyBkZXIgZ2V3dWVuc2NodGVuIE1hbnBhZ2UKKyAgKi8KK3N0YXRpYyBzdHJpbmcgZ2V0bWFucGFnZShzdHJpbmcgZGlyLCBzdHJpbmcgcGFnZSkKK3sKKyAgc3RyaW5nIHRleHQsICpzeW47CisgIGludCBpOworCisgIGlmIChkaXJbPDFdICE9ICcvJykKKyAgICBkaXIgKz0gIi8iOworCisgIGlmICgodGV4dD1yZWFkX2ZpbGUoZGlyK3BhZ2UpKSAmJiBzaXplb2YodGV4dCkpCisgICAgcmV0dXJuIHRleHQ7CisKKyAgaWYgKHRleHQgPSByZWFkX2ZpbGUoZGlyKyIuc3lub255bSIpKSB7CisgICAgc3luID0gcmVnZXhwbG9kZSh0ZXh0LCAiKFsgXHRdWyBcdF0qfFxuKSIpOworICAgIGlmICgoaT1tZW1iZXIoc3luLCBwYWdlKSkhPS0xKQorICAgICAgcmV0dXJuIHJlYWRfZmlsZShkaXIrc3luW2krMl0pOworICB9CisgIHJldHVybiAwOworfQorCisvKiogR2lidCBlaW5lIEhpbGZlc2VpdGUgYW4gZGVuIFNwaWVsZXIgYXVzIChTcGllbGVya29tbWFuZG8gaGlsZmV8bWFuKS4KKyAgKiBEaWUgSGlsZmVzZWl0ZSB3aXJkIGluIGRpdi4gVmVyemVpY2huaXNzZW4gZ2VzdWNodCAoamUgbmFjaCBHaWxkZSwKKyAgKiBNYWdpZXItL1NwaWVsZXJzdGF0dXMpLgorICAqIFxwYXJhbVtpbl0gc3RyIE5hbWUgZGVyIGdld3VlbnNjaHRlbiBIaWxmZXNlaXRlLgorICAqIFxyZXR1cm4gMQorICAqLworc3RhdGljIGludCBoZWxwKHN0cmluZyBzdHIpIHsKKyAgc3RyaW5nIHZlcmIsIHJlc3QsIHRleHQsIGdpbGRlOworICBtaXhlZCBmb3VuZDsKKworICBmb3VuZD0wOworICB0ZXh0ID0gIiI7CisgIGlmIChzdHIpIHsKKyAgICBzdHIgPSBpbXBsb2RlKCBleHBsb2RlKHN0ciwgIi4uIiApLCAiIik7CisKKyAgICBpZiAoIHNzY2FuZiggc3RyLCAiZ2lsZGUgJXMgJXMiLCBnaWxkZSwgcmVzdCk9PTIpCisgICAgICBzdHI9cmVzdDsKKyAgICBlbHNlCisgICAgICBnaWxkZT1RdWVyeVByb3AoUF9HVUlMRCk7CisgICAgaWYgKCFnaWxkZSkgZ2lsZGU9ImFiZW50ZXVyZXIiOworCisgICAgaWYgKCBzc2NhbmYoIHN0ciwgIiVzICVzIix2ZXJiLHJlc3QgKT09MiApIHN0ciA9IHZlcmI7CisKKyAgICBpZiAoKElTX0xFQVJORVIoUEwpKSApIHsKKyAgICAgIGlmIChyZXN0ID0gZ2V0bWFucGFnZSgiL2RvYy93aXovIixzdHIpKSB7CisgICAgICAgIGZvdW5kID0gMTsKKyAgICAgICAgdGV4dCArPSByZXN0OworICAgICAgfQorICAgICAgZWxzZSBpZiAocmVzdCA9IGdldG1hbnBhZ2UoIi9kb2MvbWNtZC8iLCBzdHIpKSB7CisgICAgICAgIGZvdW5kID0gMTsKKyAgICAgICAgdGV4dCArPSByZXN0OworICAgICAgfQorICAgIH0KKworICAgIGlmICgoSVNfU0VFUihQTCkpIC8qJiYgIWZvdW5kKi8gKSB7CisgICAgICBpZiAocmVzdCA9IGdldG1hbnBhZ2UoIi9kb2Mvc2NtZC8iLHN0cikpIHsKKyAgICAgICAgaWYgKGZvdW5kKQorICAgICAgICAgIHRleHQgKz0gIlxuLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CisgICAgICAgIGZvdW5kID0gMTsKKyAgICAgICAgdGV4dCArPSByZXN0OworICAgICAgfQorICAgIH0KKworICAgIGlmIChyZXN0ID0gZ2V0bWFucGFnZSgiL2RvYy9nLiIrZ2lsZGUrIi8iLHN0cikpIHsKKyAgICAgIGlmIChmb3VuZCkKKyAgICAgICAgdGV4dCArPSAiXG4tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIjsKKyAgICAgIGZvdW5kID0gMTsKKyAgICAgIHRleHQgKz0gcmVzdDsKKyAgICB9IGVsc2UgeworICAgICAgaWYgKHJlc3QgPSBnZXRtYW5wYWdlKCIvZG9jL2hlbHAvIixzdHIpKSB7CisgICAgICAgIGlmIChmb3VuZCkKKyAgICAgICAgICB0ZXh0ICs9ICJcbi0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iOworICAgICAgICBmb3VuZCA9IDE7CisgICAgICAgIHRleHQgKz0gcmVzdDsKKyAgICAgIH0KKyAgICAgIGVsc2UgaWYgKHJlc3QgPSBnZXRtYW5wYWdlKCIvZG9jL3BjbWQvIixzdHIpKSB7CisgICAgICAgIGlmIChmb3VuZCkKKyAgICAgICAgICB0ZXh0ICs9ICJcbi0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iOworICAgICAgICBmb3VuZCA9IDE7CisgICAgICAgIHRleHQgKz0gcmVzdDsKKyAgICAgIH0KKyAgICAgIGVsc2UgaWYgKHJlc3QgPSBnZXRtYW5wYWdlKCIvZG9jL1JFR0VMTi8iLHN0cikpIHsKKyAgICAgICAgaWYgKGZvdW5kKQorICAgICAgICAgIHRleHQgKz0gIlxuLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CisgICAgICAgIGZvdW5kID0gMTsKKyAgICAgICAgdGV4dCArPSByZXN0OworICAgICAgfQorICAgIH0KKworICAgIGlmICghZm91bmQpCisgICAgICB0ZXh0ID0gIkRhenUgaXN0IGtlaW5lIEhpbGZlIHZlcmZ1ZWdiYXIuXG4iOworCisgICAgTW9yZSh0ZXh0LDApOworICAgIHJldHVybiAxOworICB9CisgIGlmIChJU19MRUFSTkVSKFBMKSkKKyAgICB0ZXh0ID0gcmVhZF9maWxlKCIvZG9jL2hpbGZlLm1hZ2llciIpOworICBlbHNlIGlmIChJU19TRUVSKFBMKSkKKyAgICB0ZXh0ID0gcmVhZF9maWxlKCIvZG9jL2hpbGZlLnNlaGVyIik7CisKKyAgTW9yZSh0ZXh0ICsgcmVhZF9maWxlKCIvZG9jL2hpbGZlLnNwaWVsZXIiKSwgMCk7CisgIHJldHVybiAxOworfQorCisvKiogRXJtaXR0ZWx0IGFuZ2ViZW5lIE9wdGlvbmVuIGZ1ZXIgZGFzIFNwaWVsZXJrb21tYW5kbyAnd2VyJy4KKyAgKiBccGFyYW1baW5dIHN0ciB2b20gU3BpZWxlciBzcGV6aWZpemllcnRlciBTdHJpbmcgdm9uIEZpbHRlcm9wdGlvbmVuOiAtaywKKyAgKiAtdiwgLWEsIC1zICgrIExhbmdmb3JtZW4pLgorICAqIFxyZXR1cm4gQXJyYXkgdm9uIFNwaWVsZXJvcHRpb25lbiBhbHMgdmVyb2RlcnRlIEludC1GbGFncyB1bmQgUmVzdCBkZXIKKyAgKiBTcGllbGVyZWluZ2FiZSBvaG5lIGRpZSBPcHRpb25lbi4KKyAgKi8KK3N0YXRpYyBtaXhlZCBmaWx0ZXJfd2hvX29wdGlvbnMoc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nKiBvcHQsICphbnM7CisgIGludCBpLGxlbixyZXM7CisKKyAgb3B0ID0gZXhwbG9kZShzdHIsIiAiKTsgbGVuPXNpemVvZihvcHQpOworICBhbnMgPSAoe30pOworICByZXMgPSAwOworICBmb3IoaT0wO2k8bGVuO2krKykKKyAgICBzd2l0Y2gob3B0W2ldKXsKKyAgICAgIGNhc2UgIi1rIjoKKyAgICAgIGNhc2UgIi1rdXJ6IjoKKyAgICAgIHJlcyB8PSBXSE9fU0hPUlQ7IGJyZWFrOworICAgICAgY2FzZSAiLXYiOgorICAgICAgY2FzZSAiLXZlcnRpa2FsIjoKKyAgICAgIHJlcyB8PSBXSE9fVkVSVElDQUw7IGJyZWFrOworICAgICAgY2FzZSAiLWFscGhhYmV0aXNjaCI6CisgICAgICBjYXNlICItYSI6CisgICAgICBjYXNlICItYWxwaGEiOgorICAgICAgcmVzIHw9IFdIT19BTFBIQTsgYnJlYWs7CisgICAgICBjYXNlICItcyI6CisgICAgICBjYXNlICItc3BpZWxlciI6CisgICAgICByZXMgfD0gV0hPX1BMQVlFUl9WSUVXOyBicmVhazsKKyAgICAgIGRlZmF1bHQ6CisgICAgICByZXR1cm4gKHsgcmVzLCBpbXBsb2RlKG9wdFtpLi5dLCIgIikgfSk7CisgICAgfQorICByZXR1cm4gKHsgcmVzLCAwIH0pOworCit9CisKKy8qKiBTcGllbGVya29tbWFuZG8gJ3dlcicsIGZyYWd0IC9vYmovd2VybGlzdGUgYWIuCisgICogXHBhcmFtW2luXSBzdHIgU3BpZWxlcmVpbmdhYmUgbWl0IE9wdGlvbmVuIGZ1ZXIgd2VyLgorICAqIFxyZXR1cm4gMQorICAqLworc3RhdGljIGludCB3aG8oc3RyaW5nIHN0cikgeworICBpbnQgaSxzaHJ0OworICBzdHJpbmcgcmV0OworICBtaXhlZCBhbnM7CisKKyAgaWYgKChzdHI9X3VucGFyc2VkX2FyZ3MoKSkmJnN0clswLi4wXSE9Ii0iKSB7CisgICAgYW5zID0gZmlsdGVyX3dob19vcHRpb25zKHN0cik7CisgICAgc2hydCA9IGFuc1swXTsKKyAgICBzdHIgPSBhbnNbMV07CisgICAgaWYgKCFzaHJ0KSB7CisgICAgICBpZiAocmV0PUlORVRELT5fc2VuZF91ZHAoc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFsgUkVRVUVTVDogIndobyIsIFNFTkRFUjogZ2V0dWlkKE1FKSBdKSwgMSApKQorICAgICAgICB3cml0ZShyZXQpOworICAgICAgZWxzZQorICAgICAgICB3cml0ZSgiQW5mcmFnZSBhYmdlc2NoaWNrdC5cbiIpOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICB9CisgIGlmIChzdHIpIGk9KG1lbWJlcihzdHIsJ28nKT4wKTsgZWxzZSBpPTA7CisgIGlmIChzaXplb2Yoc3RyKT4xICYmIHN0clswXSA9PSAnLScpIHN0ciA9IHN0clsxLi4xXTsKKyAgTW9yZShpbXBsb2RlKCAiL29iai93ZXJsaXN0ZSItPlF1ZXJ5V2hvTGlzdGUoCisgICAgSVNfTEVBUk5FUihNRSkgJiYgUXVlcnlQcm9wKFBfV0FOVFNfVE9fTEVBUk4pLHNocnQsMCxzdHIsaSksIlxuIiksMCk7CisgIHJldHVybiAxOworfQorCisvKiogU3BpZWxlcmtvbW1hbmRvICdrd2VyJywgZnJhZ3QgL29iai93ZXJsaXN0ZSBhYi4KKyAgKiBccGFyYW1baW5dIHN0ciBTcGllbGVyZWluZ2FiZSBtaXQgT3B0aW9uZW4gZnVlciB3ZXIuCisgICogXHJldHVybiAxCisgICovCitzdGF0aWMgaW50IGt3aG8oc3RyaW5nIHN0cikKK3sKKyAgaW50IHNocnQ7CisgIG1peGVkIHJlczsKKworICBpZihzdHIpIHsKKyAgICByZXMgPSBmaWx0ZXJfd2hvX29wdGlvbnMoc3RyKTsKKyAgICBzaHJ0ID0gcmVzWzBdOworICAgIHN0ciA9IHJlc1sxXTsKKyAgfQorICBNb3JlKGltcGxvZGUoICIvb2JqL3dlcmxpc3RlIi0+UXVlcnlXaG9MaXN0ZSgKKyAgICAgIElTX0xFQVJORVIoTUUpICYmIFF1ZXJ5UHJvcChQX1dBTlRTX1RPX0xFQVJOKSwgc2hydHxXSE9fU0hPUlQgLDAsc3RyKSwKKyAgICAiXG4iKSsiXG5cbiIsMCk7CisgIHJldHVybiAxOworfQorCisvKiogU3BpZWxlcmtvbW1hbmRvICdra3dlcicsIGdpYnQgZWluZSBlaW5mYWNoZSBMaXN0ZSBkZXIgQW53ZXNlbmRlbiBhdXMuCisgICAgRmlsdGVydCB1bnNpY2h0YmFyZSBTcGllbGVyIGF1cywgZmFsbHMgU1BpZWxlcm9iamVrdCBrZWluIE1hZ2llciBpc3QuCisgICogXHBhcmFtW2luXSBzdHIgU3BpZWxlcmVpbmdhYmUgbWl0IE9wdGlvbmVuIGZ1ZXIgd2VyLgorICAqIFxyZXR1cm4gMQorICAqLworc3RhdGljIHZhcmFyZ3MgaW50IGtrd2hvKHN0cmluZyBzdHIpIHsKKyAgb2JqZWN0ICpvYnM7CisgIHN0cmluZyAqbmFtZW47CisKKyAgb2JzPWZpbHRlcl91c2VycyhzdHIpOworICBuYW1lbj0oe30pOworICBpZiAoSVNfTEVBUk5FUih0aGlzX3BsYXllcigpKSkgeworICAgIGZvcmVhY2gob2JqZWN0IG9iOiBvYnMpIHsKKyAgICAgIGlmIChlbnZpcm9ubWVudChvYikpCisgICAgICAgIG5hbWVuKz0oe2NhcGl0YWxpemUoZ2V0ZXVpZChvYikpfSk7CisgICAgfQorICB9IAorICBlbHNlIHsKKyAgICBmb3JlYWNoKG9iamVjdCBvYjogb2JzKSB7CisgICAgICBpZiAoIW9iLT5RdWVyeVByb3AoUF9JTlZJUykgJiYgZW52aXJvbm1lbnQob2IpKQorICAgICAgICBuYW1lbis9KHtjYXBpdGFsaXplKGdldGV1aWQob2IpKX0pOworICAgIH0KKyAgfQorICBpZiAoc2l6ZW9mKG5hbWVuKSkKKyAgICB3cml0ZShicmVha19zdHJpbmcoQ291bnRVcChzb3J0X2FycmF5KG5hbWVuLCMnPiksIiwgIiwgIiwgIikrIi4iLDc1KSk7CisgIGVsc2UKKyAgICB3cml0ZSgiS2VpbmUgcGFzc2VuZGVuIFNwaWVsZXIgZ2VmdW5kZW4uXG4iKTsKKyAgCisgIHJldHVybiAxOworfQorCisvKiogU3BpZWxlcmtvbW1hbmRvICd0b2V0ZScuCisgICogUHJ1ZWZ0IGF1ZiBHZWlzdCwgR2FzdCwgdG90ZW4gSEMtU3BpZWxlciwgV2FmZmUvZnJlaWUgSGFuZC4gVmVyc3VjaHQgZWluZW4KKyAgKiBHZWduZXIgenUgZmluZGVuIHVuZCBydWZ0IGRhbm4gS2lsbChzdHJpbmcpLgorICAqIFxwYXJhbVtpbl0gc3RyIFNwaWVsZXJlaW5nYWJlCisgICogXHJldHVybiAxIG9kZXIgMCwgZmFsbHMga2VpbiBwb3RlbnRpZWxsZXIgR2VnbmVyIGJlaSAndG9ldGUgYWxsZScgZ2VmdW5kZW4KKyAgKiB3aXJkLgorICAqLworc3RhdGljIGludCBraWxsKHN0cmluZyBzdHIpIHsKKyAgb2JqZWN0IGVvYix3b2I7CisKKyAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSkKKyAgeworICAgIHdyaXRlKCJEYXMga2FubnN0IER1IGluIERlaW5lbSBpbW1hdGVyaWVsbGVuIFp1c3RhbmQgbmljaHQuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICAKKyAgaWYoaGNfcGxheT4xKQorICB7CisgICAgd3JpdGUoIkRBUyBIQVNUIERVIEhJTlRFUiBESVIuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICAKKyAgaWYgKFF1ZXJ5R3Vlc3QoKSkKKyAgeworICAgIHdyaXRlKCJEdSBiaXN0IGRvY2ggbnVyIEdhc3QgaGllci5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmICghc3RyIHx8IHN0ciA9PSAiIikgeworICAgIHdyaXRlKCJXRU4gd2lsbHN0IER1IHRvZXRlbj9cbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmKCAhUXVlcnlQcm9wKFBfV0VBUE9OKSAmJiBRdWVyeVByb3AoUF9GUkVFX0hBTkRTKT09MCApIHsKKyAgICB3cml0ZSgKKyAgICAgICJEYXp1IHNvbGx0ZXN0IER1IGVpbmUgV2FmZmUgZ2V6dWVja3Qgb2RlciBlaW5lIEhhbmQgZnJlaSBoYWJlbi5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIHN0cj1sb3dlcl9jYXNlKHN0cik7CisgIGlmIChzdHI9PSJhbGxlIikgeworICAgIG9iamVjdCBsaXZzOworICAgIGxpdnM9ZmlsdGVyKGFsbF9pbnZlbnRvcnkoZW52aXJvbm1lbnQoUEwpKSwKKyAgICAgICAgZnVuY3Rpb24gaW50IChvYmplY3Qgb2IpIHsKKyAgICAgICAgICAgIGlmIChsaXZpbmcob2IpICYmICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iKQorICAgICAgICAgICAgICAgICAgJiYgIW9iLT5RdWVyeVByb3AoUF9JTlZJUykKKyAgICAgICAgICAgICAgICAgICYmICFvYi0+UXVlcnlQcm9wKFBfTk9fR0xPQkFMX0FUVEFDSykKKyAgICAgICAgICAgICAgICAgICYmICFvYi0+UXVlcnlQcm9wKFBfRlJJRU5EKSkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBLaWxsKG9iKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9ICk7CisgICAgLy8gd2VubiBHZWduZXIgZ2VmdW5kZW4sIHJhdXMsIGFuc29uc3RlbiBrb21tdCBkaWUgRmVobGVybWVsZHVuZyB1bnRlbi4KKyAgICBpZiAoc2l6ZW9mKGxpdnMpKSByZXR1cm4gMTsKKyAgfQorICBlbHNlIHsKKyAgICBpbnQgaT0xOworICAgIHdoaWxlKG9iamVjdHAoZW9iID0gcHJlc2VudChzdHIsaSsrLGVudmlyb25tZW50KFBMKSkpKSB7CisgICAgICBpZiAobGl2aW5nKGVvYikgJiYgIWVvYi0+UXVlcnlQcm9wKFBfSU5WSVMpKQorICAgICAgICBicmVhazsKKyAgICAgIGVsc2UKKyAgICAgICAgZW9iPTA7CisgICAgfQorICB9CisgIGlmICghb2JqZWN0cChlb2IpKSB7CisgICAgLy8gcGVyIHdyaXRlIHVuZCByZXR1cm4gMSBpc3QgaGllciBtYWwgb2ssIHdlaWwgZGllcyBLb21tYW5kbyBpbSBTcGllbGVyCisgICAgLy8gZWggenVsZXR6dCBpbiBkZXIgS29tbWFuZG9rZXR0ZSBhdXNnZWZ1ZWhydCB3aXJkIHVuZCBwZXIgcmV0dXJuIDAgZWgKKyAgICAvLyBrZWluIGFuZGVyZXMgbWVociB6dW0gWnVnIGtvbW10LgorICAgIHdyaXRlKCJEdSBzaWVoc3QgaGllciBrZWluIGRlcmFydGlnZXMgV2VzZW4hXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBlbHNlIGlmIChlb2IgPT0gUEwpIHsKKyAgICB3cml0ZSgiU2VsYnN0bW9yZCBpc3Qga2VpbmUgTG9lc3VuZyFcbiIpOworICAgIHJldHVybiAxOworICB9CisKKyAgLyogS2lsbCBoaW0gKi8KKyAgS2lsbChlb2IpOworICByZXR1cm4gMTsKK30KKworLyoqIFNwaWVsZXJrb21tYW5kbyAnc3RvcCcuCisgICogTG9lc2NodCBkaWUgR2VnbmVybGlzdGUsIHNvZmVybiBtYW4gbmljaHQgSW5GaWdodCgpIGlzdC4KKyAgKiBccGFyYW1baW5dIHN0ciBTcGllbGVyZWluZ2FiZSwgd2lyZCBpZ25vcmllcnQuCisgICogXHJldHVybiAxCisgICovCitzdGF0aWMgaW50IHN0b3AoIHN0cmluZyBzdHIgKQoreworICAgIGlmICggSW5GaWdodCgpICl7CisgICAgICAgIHdyaXRlKCAiRGFzIGdlaHQgbmljaHQgbWl0dGVuIGltIEthbXBmLlxuIiApOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICBpZiAoICFzdHIgKXsKKyAgICAgICAgU3RvcEh1bnRpbmdNb2RlKCk7CisgICAgICAgIHdyaXRlKCAiT2suXG4iICk7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIGlmICggIVN0b3BIdW50SUQoc3RyKSApCisgICAgICAgIHdyaXRlKCAiU28gamVtYW5kZW4gdmVyZm9sZ3N0IER1IG5pY2h0IVxuIiApOworCisgICAgcmV0dXJuIDE7Cit9CisKKy8qKiBTcGllbGVya29tbWFuZG8gZnVlcnMgZW1vdGVuICc6Jy4KKyAgKiBccGFyYW1baW5dIHN0ciBTcGllbGVyZWluZ2FiZQorICAqIFxwYXJhbVtpbl0gZ2VuaXRpdiBHZW5ldGl2ZmxhZworICAqIFxyZXR1cm4gMSBvZGVyIDAsIGZhbGxzIFNwaWVsZXIgbmljaHQgZW1vdGVuIGthbm4gKGtlaW4gQ0FOX0VNT1RFIEZsYWcgaW4KKyAgKiBQX0NBTl9GTEFHUykuCisgICovCitpbnQgZW1vdGUoc3RyaW5nIHN0cixpbnQgZ2VuaXRpdikKK3sKKyAgc3RyaW5nICpjb21tYW5kcyxtZXNzYWdlLHZlcmI7CisgIG9iamVjdCBsaXZpbmc7CisgIGludCBpLHNpemU7CisKKyAgaWYgKCEoUXVlcnkoUF9DQU5fRkxBR1MpJkNBTl9FTU9URSkpIHJldHVybiAwOworICBpZiAocXVlcnlfdmVyYigpWzBdPT0nOycpIGdlbml0aXY9MTsKKyAgaWYgKHF1ZXJ5X3ZlcmIoKVswXT09JzonfHxxdWVyeV92ZXJiKClbMF09PSc7JykKKyAgICB2ZXJiPXF1ZXJ5X3ZlcmIoKVsxLi5dKyIgIjsKKyAgZWxzZQorICAgIHZlcmI9IiI7CisgIHN0cj10aGlzX3BsYXllcigpLT5fdW5wYXJzZWRfYXJncygpOworICBjb21tYW5kcz1leHBsb2RlKHZlcmIrKHN0cnx8IiIpLCIjIik7CisgIG1lc3NhZ2U9YnJlYWtfc3RyaW5nKChJU19TRUVSKE1FKSA/ICIiIDogIj4iKQorICAgICAgICAgICAgICAgICAgICAgICArY2FwaXRhbGl6ZShnZW5pdGl2ID8gbmFtZShXRVNTRU4pIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSgpKQorICAgICAgICAgICAgICAgICAgICAgICArIiAiK2NvbW1hbmRzWzBdLDc4KTsKKyAgc2l6ZT1zaXplb2YoY29tbWFuZHMpOworICBpZihzaXplPj0zKQorICB7CisgICAgbGl2aW5nPWZpbmRfbGl2aW5nKGxvd2VyX2Nhc2UoY29tbWFuZHNbMV0pKTsKKyAgICBpZighbGl2aW5nIHx8IGVudmlyb25tZW50KGxpdmluZykhPWVudmlyb25tZW50KCkgfHwKKyAgICAgICAobGl2aW5nLT5RdWVyeVByb3AoUF9JTlZJUykpICYmICFJU19MRUFSTkVSKE1FKSkKKyAgICB7CisgICAgICB3cml0ZShjYXBpdGFsaXplKGNvbW1hbmRzWzFdKSsiIHNlaGUgaWNoIGhpZXIgbmljaHQhXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBpZihsaXZpbmchPXRoaXNfb2JqZWN0KCkpCisgICAgICB0ZWxsX29iamVjdChsaXZpbmcsYnJlYWtfc3RyaW5nKChJU19TRUVSKHRoaXNfcGxheWVyKCkpID8gIiIgOiAiPiIpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArY2FwaXRhbGl6ZShnZW5pdGl2ID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfcGxheWVyKCktPm5hbWUoV0VTU0VOKSA6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzX3BsYXllcigpLT5uYW1lKCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIiAiK2NvbW1hbmRzWzJdLDc4KSk7CisgIH0KKyAgaWYoc2l6ZT49NCkKKyAgICB3cml0ZShicmVha19zdHJpbmcoY29tbWFuZHNbM10sNzgpKTsKKyAgZWxzZQorICAgIHdyaXRlKG1lc3NhZ2UpOworICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoKSxtZXNzYWdlLCh7dGhpc19vYmplY3QoKSxsaXZpbmd9KSk7CisgIHJldHVybiAxOworfQorCisvKiogU3BpZWxlcmtvbW1hbmRvIGZ1ZXJzIHJlbW90ZW4gJ3I6Jy4KKyAgKiBccGFyYW1baW5dIHN0ciBTcGllbGVyZWluZ2FiZQorICAqIFxwYXJhbVtpbl0gZmxhZyBHZW5ldGl2ZmxhZworICAqIFxyZXR1cm4gMSBvZGVyIDAsIGZhbGxzIFNwaWVsZXIgbmljaHQgZW1vdGVuIGthbm4gKGtlaW4gQ0FOX1JFTU9URSBGbGFnIGluCisgICogUF9DQU5fRkxBR1MpLgorICAqLworc3RhdGljIGludCByZW1vdGUoc3RyaW5nIHN0ciwgaW50IGZsYWcpCit7CisgIGludCBtOworICBzdHJpbmcgdG1wLCBkZXN0OworICBzdHJpbmcgKmV4c3RyOworICBvYmplY3QgZGVzdHBsOworCisgIGlmICggIShRdWVyeShQX0NBTl9GTEFHUykgJiBDQU5fUkVNT1RFKSApCisgICAgICByZXR1cm4gMDsKKworICBpZiAoICEoc3RyPV91bnBhcnNlZF9hcmdzKCkpIHx8CisgICAgICAgc2l6ZW9mKCAoZXhzdHI9ZXhwbG9kZShzdHIsIiAiKSkgLSAoeyIifSkgKSA8PSAxICl7CisgICAgICB3cml0ZSgiV2FzIHdpbGxzdCBEdSB6dSB3ZW0gYGVtb3RlbmA/XG4iKTsKKyAgICAgIHJldHVybiAxOworICB9CisKKyAgZGVzdCA9IGxvd2VyX2Nhc2UoZXhzdHJbMF0pOworCisgIGlmKCAhKGRlc3RwbD1maW5kX3BsYXllciggZGVzdCApICkgfHwKKyAgICAgIChkZXN0cGwtPlF1ZXJ5UHJvcChQX0lOVklTKSAmJiAhSVNfTEVBUk5FUihNRSkpICl7CisgICAgd3JpdGUoIkVpbmVuIHNvbGNoZW4gU3BpZWxlciBnaWJ0IGVzIGRlcnplaXQgbmljaHQuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIHRtcCA9IGltcGxvZGUoIGV4c3RyWzEuLl0sICIgIiApOworCisgIHRtcCA9IHJlZ3JlcGxhY2UoIHRtcCwgIihefFteI10pIygkfFteI10pIiwgIlxcMWF1cyBkZXIgRmVybmVcXDIiLCAxICk7CisgIHRtcCA9IHJlZ3JlcGxhY2UoIHRtcCwgIihefFteXFxeXSlcXF4oJHxbXlxcXl0pIiwgIlxcMWluIGRlciBGZXJuZVxcMiIsIDEgKTsKKyAgdG1wID0gcmVncmVwbGFjZSggdG1wLCAiIyMiLCAiIyIsIDEgKTsKKyAgdG1wID0gcmVncmVwbGFjZSggdG1wLCAiXFxeXFxeIiwgIl4iLCAxICk7CisKKyAgaWYgKCBzdHJzdHIoIHRtcCwgImF1cyBkZXIgRmVybmUiICkgPT0gLTEKKyAgICAgICAmJiBzdHJzdHIoIHRtcCwgImluIGRlciBGZXJuZSIgKSA9PSAtMSApCisgICAgICB0bXAgKz0gIiBhdXMgZGVyIEZlcm5lIjsKKworICBpZiAoIFF1ZXJ5UHJvcChQX0lOVklTKSAmJiBJU19MRUFSTkVSKGRlc3RwbCkgKXsKKyAgICAgIHN0ciA9ICIoIiArIGNhcGl0YWxpemUoZ2V0dWlkKE1FKSk7CisgICAgICBpZiAoIGZsYWcgKQorICAgICAgICAgIHN0ciArPSBtZW1iZXIoICJzeHoiLCBzdHJbPDFdICkgPT0gLTEgPyAicyIgOiAiJyI7CisgICAgICBzdHIgKz0gIikiOworICB9CisgIGVsc2UKKyAgICAgIHN0ciA9IChmbGFnID8gY2FwaXRhbGl6ZShuYW1lKFdFU1NFTikpIDogY2FwaXRhbGl6ZShuYW1lKFdFUikpKTsKKworICBzdHIgKz0gIiAiICsgdG1wICsgKG1lbWJlciggIi4/ISIsIHRtcFs8MV0gKSA9PSAtMSA/ICIuIiA6ICIiKSArICJcbiI7CisKKyAgbSA9IGRlc3RwbC0+UmVjZWl2ZU1zZyhzdHIsIE1UX0NPTU18TVRfRkFSLCBNQV9FTU9URSwwLCBNRSk7CisgIHN3aXRjaChtKQorICB7CisgICAgY2FzZSBNU0dfREVMSVZFUkVEOgorICAgICAgX3JlY3YoZGVzdHBsLCBjYXBpdGFsaXplKGRlc3RwbC0+bmFtZSgpKSArICItPiIgKyBzdHIsIE1TR0ZMQUdfUkVNT1RFKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTVNHX0JVRkZFUkVEOgorICAgICAgd3JpdGUoIGNhcGl0YWxpemUoZGVzdHBsLT5uYW1lKFdFUikgKyAiIGlzdCBnZXJhZGUgYmVzY2hhZWZ0aWd0LlxuIikgKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTVNHX0lHTk9SRUQ6CisgICAgICB3cml0ZSggY2FwaXRhbGl6ZShkZXN0cGwtPm5hbWUoV0VSKSArICIgaWdub3JpZXJ0IERpY2guXG4iKSApOworICAgICAgYnJlYWs7CisgICAgY2FzZSBNU0dfVkVSQl9JR046CisgICAgY2FzZSBNU0dfTVVEX0lHTjoKKyAgICAgIHdyaXRlKCBjYXBpdGFsaXplKGRlc3RwbC0+bmFtZShXRVIpICsgIiBpZ25vcmllcnQgRGVpbmUgTWVsZHVuZy5cbiIpICk7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgd3JpdGUoIGNhcGl0YWxpemUoZGVzdHBsLT5uYW1lKFdFUikgKyAiIGthbm4gRGljaCBnZXJhZGUgbmljaHQgIgorICAgICAgICAgICAgIndhaHJuZWhtZW4uXG4iKSApOworICB9CisgIHJldHVybiAxOworfQorCisvKiogU3BpZWxlcmtvbW1hbmRvIGZ1ZXJzIGVtb3RlbiBpbSBHZW5pdGl2ICc7Jy4KKyAgKiBSdWZ0IGVtb3RlKHN0cmluZyxpbnQpIGF1Zi4KKyAgKi8KK3N0YXRpYyBpbnQgZ2Vtb3RlKHN0cmluZyBzdHIpCit7CisgIHJldHVybiBlbW90ZShzdHIsIDEpOworfQorCisvKiogU3BpZWxlcmtvbW1hbmRvIGZ1ZXJzIHJlbW90ZW4gaW0gR2VuaXRpdiAncjsnLgorICAqIFJ1ZnQgcmVtb3RlKHN0cmluZywgaW50KSBhdWYuCisgICovCitzdGF0aWMgaW50IGdyZW1vdGUoc3RyaW5nIHN0cikKK3sKKyAgcmV0dXJuIHJlbW90ZShzdHIsIDEpOworfQorCitzdGF0aWMgdm9pZCBsb2FkX2F1dG9fb2JqZWN0cyhtYXBwaW5nIG1hcF9sZGZpZWQpOworCitwcml2YXRlIHZvaWQgSW5pdFBsYXllcigpOworcHJpdmF0ZSB2b2lkIEluaXRQbGF5ZXIyKCk7Citwcml2YXRlIHZvaWQgSW5pdFBsYXllcjMoKTsKKworLyoqIEdpYnQgZWluZSBadWZhbGxzemFobCB1bSBQX0FWRVJBR0VfU0laRSBoZXJ1bSB6dXJ1ZWNrLgorICAqIFxyZXR1cm4gWnVmYWVsbGlnZSBHcm9lc3NlLgorICAqLworcHJpdmF0ZSBpbnQgUmFuZG9tU2l6ZSgpCit7CisgIHJldHVybiAoMTAwK3JhbmRvbSgxMyktcmFuZG9tKDEzKStyYW5kb20oMTMpLXJhbmRvbSgxMykpKgorICAgIChRdWVyeVByb3AoUF9BVkVSQUdFX1NJWkUpfHwxNzApLzEwMDsKK30KKworLyoqIFNldHp0IGJlc3RpbW10ZSBQcm9wcyBpbSBTcGllbGVyLCBmYWxscyBkaWVzZSBuaWNodCBnZXNldHp0IHNpbmQgb2RlcgorICAqIGxvZXNjaHQgb2Jzb2xldGUgUHJvcHMuIFJlcGFyaWVydCBiZXN0aW1tdGUgRGF0ZW5zdHJ1a3R1cmVuIGltIFNwaWVsZXIuCisgICogV2lyZCB2b24gc3RhcnRfcGxheWVyKCkgbmFjaCBMYWRlbiBkZXMgU2F2ZWZpbGVzIGdlcnVmZW4uCisgICogTW9tZW50YW4gd2lyZCB6LkIuIGRpZSBHcm9lc3NlIGdlc2V0enQsIGZhbGxzIHNpZSBiaXNoZXIgMCBpc3QgdW5kIGRpZQorICAqIFNraWxscyBkZXMgU3BpZWxlcnMgaW5pdGlhbGlzaWVydCBiencuIHJlcGFyaWVydCBvZGVyIGF1ZiBkaWUgYWt0dWVsbHN0ZQorICAqIFZlcnNpb24gZGVzIFNraWxsc3lzdGVtcworICAqIFJ1ZnQgZ2dmLiBJbml0U2tpbGxzKCkgdW5kIEZpeFNraWxscygpLgorICAqIEBwYXJhbVtpbl0gbmV3ZmxhZyBHaWJ0IGFuLCBvYiBlcyBlaW4gbmV1ZXJzdGVsbHRlciBTcGllbGVyIGlzdC4KKyAgKiBAc2Egc3RhcnRfcGxheWVyKCksIEluaXRTa2lsbHMoKSwgRml4U2tpbGxzKCkKKyAgKi8KK3ByaXZhdGUgdm9pZCB1cGRhdGVzX2FmdGVyX3Jlc3RvcmUoaW50IG5ld2ZsYWcpIHsKKyAKKyAgLy8gU2VoZXIgZHVlcmZlbiBkaWUgRmx1Y2h0cmljaHR1bmcgdWViZXJtaXR0ZWxuIGxhc3Nlbi4KKyAgLy8gRWlnZW50bGljaCBrb2VubnRlIGVzIE1lcmxpbiBtYWNoZW4uIER1bW1lcndlaXNlIGdpYnQgZXMgamEgYXVjaCBhbHRlCisgIC8vIFNlaGVyIHVuZCBkYW5uIGthbm4gZXMgZ2xlaWNoZSBmdWVyIGFsbGUgaGllciBnZW1hY2h0IHdlcmRlbi4gKE9iIGRlcgorICAvLyBDb2RlIGplbWFscyByYXVza2Fubj8pCisgIC8vVE9ETzogSXJnZW5kd2FubiBhbGxlIFNlaGVyIGtvcnJpZ2llcmVuIHVuZCBDb2RlIG5hY2ggTWVybGluIHNjaGllYmVuLi4uCisgIGlmIChJU19TRUVSKE1FKSkKKyAgICBTZXRQcm9wKFBfQ0FOX0ZMQUdTLFF1ZXJ5UHJvcChQX0NBTl9GTEFHUykgfCBDQU5fUkVQT1JUX1dJTVBZX0RJUik7CisKKyAgLy8gZ2dmLiBJbnZpcy1FaWdlbnNjaGFmdCBhdXMgZGVtIExvZ2lub2JqZWt0IGFicnVmZW4gKEludmlzbG9naW4pLCBrb2VubnRlCisgIC8vIGphIGFuZGVycyBhbHMgYXVzIFNhdmVmaWxlIHNlaW4uIEdlc2V0enRlcyBQX0lOVklTIGF1cyBkaWVzZW0gYWJlcgorICAvLyBiZWliZWhhbHRlbi4KKyAgaWYgKElTX0xFQVJORVIoTUUpICYmICFRdWVyeVByb3AoUF9JTlZJUykKKy8vICAgICAgJiYgbG9hZF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSA9PSAiL3NlY3VyZS9sb2dpbiIKKyAgICAgICkKKyAgeworICAgIFNldFByb3AoUF9JTlZJUywgcHJldmlvdXNfb2JqZWN0KCktPnF1ZXJ5X2ludmlzKCkpOworICAgIGlmIChRdWVyeVByb3AoUF9JTlZJUykpCisgICAgICB0ZWxsX29iamVjdChNRSwgIkRVIEJJU1QgVU5TSUNIVEJBUiFcbiIgKTsKKyAgfQorICAiKiI6OnVwZGF0ZXNfYWZ0ZXJfcmVzdG9yZShuZXdmbGFnKTsKKworICBhdHRyaWJ1dGVzOjpVcGRhdGVBdHRyaWJ1dGVzKCk7CisKKyAgaW50IHNpemU9UXVlcnkoUF9TSVpFKTsKKyAgaWYgKCFzaXplKSBzaXplPVJhbmRvbVNpemUoKTsKKyAgd2hpbGUoc2l6ZT09UXVlcnlQcm9wKFBfQVZFUkFHRV9TSVpFKSkKKyAgICBzaXplPVJhbmRvbVNpemUoKTsKKyAgU2V0KFBfU0laRSxzaXplKTsKKworICAvLyBQcm9wIHdpcmQgbmljaHQgbWVociBnZW51dHp0LiBUT0RPOiBpcmdlbmR3YW5uIGVudGZlcm5lbi4KKyAgU2V0KFBfU0VDT05EX0xJU1QsIFNBVkUsIEZfTU9ERV9BRCk7CisgIFNldChQX1NFQ09ORF9MSVNULCAwLCBGX1ZBTFVFKTsKK30KKworCisvKiogU2V0enQgZGVuIEhDLU1vZHVzLgorICAqLwordmFyYXJncyBub21hc2sgdm9pZCBzZXRfaGNfcGxheShzdHJpbmcgc3RyLGludCB2YWwpCit7CisgICBzdHJpbmcgc3RyMTsKKworICAgIHN0cjEgPSBleHBsb2RlKCBvYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSksICIjIiApWzBdOworICAgIAorICAgIGlmICggc3RyMSAhPSAiL3NlY3VyZS9sb2dpbiIgJiYKKyAgICAgICAgIHByZXZpb3VzX29iamVjdCgpIT10aGlzX29iamVjdCgpICYmCisgICAgICAgICBleHRlcm5fY2FsbCgpICYmCisgICAgICAgICAoIWdldGV1aWQoTUUpIHx8IGdldGV1aWQoTUUpICE9IGdldHVpZChNRSkgfHwKKyAgICAgICAgICBjYXBpdGFsaXplKGdldGV1aWQoTUUpKSAhPSBzdHIgfHwKKyAgICAgICAgICBnZXRldWlkKE1FKSAhPSBnZXRldWlkKHByZXZpb3VzX29iamVjdCgpKSkgKXsKKyAgICAgICAgd3JpdGUoICJESUVTRVIgVkVSU1VDSCBXQVIgSUxMRUdBTCAhIVxuIiApOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIAorICAgIGhjX3BsYXk9dmFsOworfQorCisvKiogZ2lidCBkZW4gSEMtTW9kdXMgenVydWVjay4KKyAgKi8KK25vbWFzayBpbnQgcXVlcnlfaGNfcGxheSgpCit7CisgIHJldHVybiBoY19wbGF5OworfQorCisvKiogSW5pdGlhbGlzaWVydCB1bmQgYWt0aXZpZXJ0IGRhcyBTcGllbGVyb2JqZWt0LgorICAqIEthbm4gbnVyIHZvbiAvc2VjdXJlL2xvZ2luIG9kZXIgL3NlY3VyZS9tYXN0ZXIgZ2VydWZlbiB3ZXJkZW4uCisgICogU3RhcnRldCBUZWxuZXQgTmVnb3RpYXRpb24sIGxhZWR0IFNhdmVmaWxlLCBzZXR6dCBlaW5pZ2UgUHJvcHMuIAorICAqIFJ1ZnQgdXBkYXRlc19hZnRlcl9yZXN0b3JlKCksIHVtIGRpdi4gRGF0ZW4genUgYWt0dWFsaXNpZXJlbi9yZXBhcmllcmVuLgorICAqIFJ1ZnQgY3JlYXRlKCkgYXVzIC9zdGQvcGxheWVyL3BvdGlvbi5jLgorICAqIEJlaSBuZXVlbSBTcGllbGVyIHdpcmQgZGVyIGVudHNwcmVjaGVuZGUgRXZlbnQgYXVzZ2Vsb2VzdCBkaWUgQXR0cmlidXRlCisgICogYXVmIGRpZSBTdGFydHdlcnRlIGdlc2V0enQuCisgICogUHJ1ZWZ0IFp3ZWl0aWVtYXJraWVydW5nZW4uCisgICogUnVmdCBJbml0UGxheWVyKCkuCisgICogQHBhcmFtW2luXSBzdHIgTmFtZSBkZXMgQ2hhcmFrdGVycywgZGVyIGdlbGFkZW4gd2VyZGVuIHNvbGwuCisgICogQHBhcmFtW2luXSBpcCB0ZXh0dWVsbGUgUmVwcmFlc2VudGF0aW9uIGRlciBJUC1BZHJlc3NlIGRlcyBTcGllbGVycy4KKyAgKiBAcmV0dXJuIDEgYmVpIEVyZm9sZywgMCBzb25zdC4KKyAgKiBAdG9kbyBEaXYuIFJlcGFyYXR1cmVuL1VwZGF0ZXMgbmFjaCB1cGRhdGVzX2FmdGVyX3Jlc3RvcmUoKSBhdXNsYWdlcm4uCisgICovCit2YXJhcmdzIG5vbWFzayBpbnQgc3RhcnRfcGxheWVyKCBzdHJpbmcgc3RyLCBzdHJpbmcgaXAgKQoreworICAgIG1peGVkIHNlY29uZDsKKyAgICBpbnQgbmV3ZmxhZzsgIC8qIGNvdWxkIHBsYXllciBiZSByZXN0b3JlZD8gKi8KKyAgICBzdHJpbmcgc3RyMTsKKworICAgIGNhbGxfb3V0KCAiZGlzY29ubmVjdCIsIDYwMCApOworCisgICAgc3RyMSA9IGV4cGxvZGUoIG9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSwgIiMiIClbMF07CisKKyAgICBpZiAoIHN0cjEgIT0gIi9zZWN1cmUvbG9naW4iICYmCisgICAgICAgICBzdHIxICE9ICIvc2VjdXJlL21hc3RlciIgJiYKKyAgICAgICAgICghZ2V0ZXVpZChNRSkgfHwgZ2V0ZXVpZChNRSkgIT0gZ2V0dWlkKE1FKSB8fAorICAgICAgICAgIGNhcGl0YWxpemUoZ2V0ZXVpZChNRSkpICE9IHN0ciB8fAorICAgICAgICAgIGdldGV1aWQoTUUpICE9IGdldGV1aWQocHJldmlvdXNfb2JqZWN0KCkpKSApeworICAgICAgICB3cml0ZSggIkRJRVNFUiBWRVJTVUNIIFdBUiBJTExFR0FMICEhXG4iICk7CisgICAgICAgIGRlc3RydWN0KE1FKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyogdHJ5IHRvIHJlc3RvcmUgcGxheWVyLiBJZiBpdCBkb2Vzbid0IGV4aXN0LCBzZXQgdGhlIG5ldyBmbGFnICovCisgICAgbmV3ZmxhZyA9ICFyZXN0b3JlX29iamVjdCggIi8iICsgU0FWRVBBVEggKyBsb3dlcl9jYXNlKHN0cilbMC4uMF0gKyAiLyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArbG93ZXJfY2FzZShzdHIpICk7CisKKyAgICB1cGRhdGVzX2FmdGVyX3Jlc3RvcmUobmV3ZmxhZyk7CisKKyAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKQorICAgIHsKKyAgICAgIC8vIFRlbG5ldC1OZWdvdGlhdGlvbnMgZHVyY2hmdWVocmVuLCBhYmVyIG51ciBkaWUgZ3J1bmRsZWdlbmRlbiBhdXMKKyAgICAgIC8vIHRlbG5ldG5lZy4gQWxsZSBhbmRlcmVuIHNvbGx0ZW4gZXJzdCBzcGFldGVyLCBuYWNoIHZvbGxzdGFlbmRpZ2VyCisgICAgICAvLyBJbml0aWFsaXNpZXJ1bmcgZ2VtYWNodCB3ZXJkZW4uCisgICAgICAgIHRlbG5ldG5lZzo6c3RhcnR1cF90ZWxuZXRfbmVncygpOworICAgICAgICBtb2RpZnlfcHJvbXB0KCk7CisgICAgICAgIFNldCggUF9MQVNUX0xPR0lOLCB0aW1lKCkgKTsKKyAgICB9CisKKyAgICBTZXQoIFBfV0FOVFNfVE9fTEVBUk4sIDEgKTsgLy8gMSBzb2xsdGUgZGVyIGRlZmF1bHQgc2VpbiAhISEKKyAgICBTZXQoIFBfV0FOVFNfVE9fTEVBUk4sIFBST1RFQ1RFRCwgRl9NT0RFX0FTICk7CisgICAgLy8gRWluZ2VmdWVndCAxOC4xMS45OSwga2FubiBuYWNoIGVpbmVtIEphaHIgd2llZGVyIHJhdXM6CisgICAgU2V0KCBQX1RFU1RQTEFZRVIsIFBST1RFQ1RFRCwgRl9NT0RFX0FTICk7CisKKyAgICBpZiAoIElTX0xFQVJORVIoTUUpICkKKyAgICAgICAgU2V0UHJvcCggUF9DQU5fRkxBR1MsIFF1ZXJ5UHJvcChQX0NBTl9GTEFHUyl8Q0FOX1JFTU9URSApOworCisgICAgU2V0KCBQX05BTUUsIHN0ciApOworICAgIFNldCggUF9OQU1FLCBTRUNVUkVELCBGX01PREVfQVMgKTsKKworICAgIGlmICggIVF1ZXJ5UHJvcChQX05FRURFRF9RUCkgKQorICAgICAgICBTZXRQcm9wKCBQX05FRURFRF9RUCwgUkVRX1FQICk7CisKKyAgICBTZXQoIFBfTkVFREVEX1FQLCBOT1NFVE1FVEhPRCwgRl9TRVRfTUVUSE9EICk7CisgICAgU2V0KCBQX05FRURFRF9RUCwgU0FWRXxTRUNVUkVELCBGX01PREVfQVMgKTsKKworICAgIC8qIGF1dG9zYXZlIHRoZSBwbGF5ZXIgYWZ0ZXIgNTAwIGhlYXJ0YmVhdHMgKi8KKyAgICB0aW1lX3RvX3NhdmUgPSBhZ2UgKyA1MDA7CisgICAgcG90aW9uOjpjcmVhdGUoKTsgLyogRE8gSVQgSEVSRSBBRlRFUiBUSEUgUkVTVE9SRSAhISAqLworCisgICAgQWRkSWQoIGdldHVpZCgpICk7CisgICAgU2V0UHJvcCggUF9BQywgMCApOworICAgIFNldFByb3AoIFBfV0VBUE9OLCAwICk7CisKKyAgICAvKiBTZXQgc29tZSB0aGluZ3Mgd2hpY2ggd29udCBiZSBzZXQgd2hlbiBhbGwgaXMgT0sgKi8KKyAgICBTZXRQcm9wKCBQX01BWF9IUCwgKFF1ZXJ5QXR0cmlidXRlKEFfQ09OKSAqIDggKyA0MiApKTsKKyAgICBTZXRQcm9wKCBQX01BWF9TUCwgKFF1ZXJ5QXR0cmlidXRlKEFfSU5UKSAqIDggKyA0MiApKTsKKworICAgIGNhdGNoKCBiYiA9ICIvc2VjdXJlL2JibWFzdGVyIi0+cXVlcnlfYmIoKSApOworCisgICAgLyogSWYgdGhpcyBpcyBhIG5ldyBjaGFyYWN0ZXIsIHdlIGNhbGwgdGhlIGFkdmVudHVyZXJzIGd1aWxkIHRvIGdldAorICAgICAqIG91ciBmaXJzdCB0aXRsZSAhCisgICAgICovCisgICAgaWYgKCBuZXdmbGFnICkgeworICAgICAgICBpZiAoIFF1ZXJ5R3Vlc3QoKSkKKyAgICAgICAgICAgIFNldFByb3AoIFBfVElUTEUsICJ1ZWJlcmtvbW10IGRhcyAiTVVETkFNRSIgLi4uIiApOworCisgICAgICAgIFNldCggUF9MRVZFTCwgLTEgKTsKKyAgICAgICAgU2V0UHJvcCggUF9BVFRSSUJVVEVTLCAoWyBBX1NUUjoxLCBBX0NPTjoxLCBBX0lOVDoxLCBBX0RFWDoxIF0pICk7CisgICAgICAgIFNldFByb3AoIFBfSFAsIFF1ZXJ5UHJvcChQX01BWF9IUCkgKTsKKworICAgICAgICAvLyBFdmVudCBhdXNsb2VzZW4KKyAgICAgICAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoRVZUX0xJQl9QTEFZRVJfQ1JFQVRJT04sIChbCisgICAgICAgICAgICAgIEVfT0JKRUNUOiBNRSwKKyAgICAgICAgICAgICAgRV9QTE5BTUU6IGdldHVpZChNRSkgXSkgKTsKKyAgICB9CisgICAgCisgICAgSW5pdFBsYXllcigpOworCisgICAgLy8gUGFkcmVpYyAwMS4wMi4xOTk5CisgICAgaWYgKCAhSVNfTEVBUk5FUihNRSkgJiYgc2Vjb25kID0gUXVlcnlQcm9wKFBfU0VDT05EKSApIHsKKyAgICAgICAgaWYgKCBzdHJpbmdwKHNlY29uZCkgJiYgbG93ZXJfY2FzZShzZWNvbmQpWzAuLjNdID09ICJ2b24gIiApIHsKKyAgICAgICAgICAgIHNlY29uZCA9IGxvd2VyX2Nhc2Uoc2Vjb25kWzQuLl0pOworICAgICAgICAgICAgU2V0UHJvcCggUF9TRUNPTkQsIHNlY29uZCApOworICAgICAgICB9CisKKyAgICAgICAgaWYgKCAhc3RyaW5ncChzZWNvbmQgKSB8fAorICAgICAgICAgICAgIGZpbGVfc2l6ZSggIi9zYXZlLyIgKyBzZWNvbmRbMC4uMF0gKyAiLyIgKyBzZWNvbmQgKyAiLm8iICkgPD0gMCApeworICAgICAgICAgICAgaWYgKCBzdHJpbmdwKHNlY29uZCkgJiYKKyAgICAgICAgICAgICAgICAgZmlsZV9zaXplKCAiL3NhdmUvIiArIGxvd2VyX2Nhc2Uoc2Vjb25kWzAuLjBdKSArICIvIiArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJfY2FzZShzZWNvbmQpICsgIi5vIiApID4wICl7CisgICAgICAgICAgICAgICAgU2V0UHJvcCggUF9TRUNPTkQsIGxvd2VyX2Nhc2Uoc2Vjb25kKSApOworICAgICAgICAgICAgICAgIGxvZ19maWxlKCAiV1JPTkdfU0VDT05EIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZiggIiVzOiAlczogUF9TRUNPTkQgPSAlTyAtPiBBdXRvbWF0aXNjaCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJrb3JyaWdpZXJ0LFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHRpbWUodGltZSgpKSwgb2JqZWN0X25hbWUoKSwgc2Vjb25kICkgKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIHRlbGxfb2JqZWN0KCBNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIipcbipcbiogRGVpbmUgWndlaXRpZW1hcmtpZXJ1bmcgaXN0IHVuZ3VlbHRpZywgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYml0dGUgYWVuZGVyZSBkaWVzZSB1bmQgc3ByaWNoIGltXG4qIFp3ZWlmZWwgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYml0dGUgZWluZW4gRXJ6bWFnaWVyIGFuLlxuKlxuKlxuIiApOworCisgICAgICAgICAgICAgICAgbG9nX2ZpbGUoICJXUk9OR19TRUNPTkQiLAorICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCAiJXM6ICVzOiBQX1NFQ09ORCA9ICVPXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkdGltZSh0aW1lKCkpLCBvYmplY3RfbmFtZSgpLCBzZWNvbmQgKSApOworICAgICAgICAgICAgICAgIC8vIGVpbiBiaXNzY2hlbiBkZXV0bGljaGVyIGF1ZmZvcmRlcm4uLiBQYWRyZWljIDA4LjA0LjE5OTkKKyAgICAgICAgICAgICAgICBtb3ZlKCAiL2QvZ2ViaXJnZS9yb29tL3p3YWZmbGFkIiwgTV9HTyApOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHJldHVybigwKTsKK30KKworLyoqIExldHp0ZSBQaGFzZSBkZXIgU3BpZWxlcmluaXRpYWxpc2llcnVuZyBiZWltIExhZGVuIGRlcyBDaGFyYWt0ZXJzLgorICAqIFJ1ZnQgZW5hYmxlX2NvbW1hbmRzKCksIGFrdGl2aWVydCBkZW4gSGVhcnRiZWF0IHVuZCBha3RpdmllcnQgZGllCisgICogS29tbWFuZG9zIGF1cyBkZW4gZ2VlcmJ0ZW4gY29tbWFuZC5jLCBwdXRfYW5kX2dldC5jLCB0ZWFtLmMsIHNvdWwuYywKKyAgKiBndWlkZS5jLCBzZXR6dCBkZW4gTGl2aW5nIE5hbWUuCisgICogUmVnaXN0cmllcnQgVXNlU3BlbGwoKSBhbHMgQ2F0Y2hhbGwtS29tbWFuZG8uCisgICogTGFlc3N0IGRlbiBTcGllbGVyIGdnZi4gZWluZW4gTGV2ZWwgcGVyIC9zdGQvZ2lsZGUgYXVmc3RlaWdlbiwgcnVmdAorICAqIGNhbGxfbm90aWZ5X3BsYXllcl9jaGFuZ2UoKSwgbG9lc3QgTG9naW4tRXZlbnQgYXVzLgorICAqIEdpYnQgV2lsbGtvbW1lbnN0ZXh0ZSwgTmV3cyB1bmQgbmV1ZSBNYWlscyBhdXMuCisgICogRmluZGV0IGRlbiBTdGFydHJhdW0gdW5kIGJld2VndCBkZW4gU3BpZWxlciBkb3J0aGluLgorICAqIFJ1ZnQgRmluYWxTZXR1cCgpIChhdXMgZGVuIFJhc3NlbnNoZWxscykuCisgICogQmVncmVuenQgR2VsZG1lbmdlIGltIFNwaWVsZXIgKHdlZ2VuIEJhbmt6d2VpdGllcykgbmFjaCBUcmFna3JhZnQgdW5kCisgICogZXJzdGF0dGV0IEdlbGQgYmVpIFJlYm9vdC4KKyAgKiBSdWZ0IHNldF9pc193aXphcmQoKS4KKyAgKiBTdGFydGV0IENsb25lbiBkZXIgQXV0b2xvYWRlci4KKyAgKiBAc2EgSW5pdFBsYXllcjMoKSxJbml0UGxheWVyMigpLCBJbml0UGxheWVyKCksIHN0YXJ0X3BsYXllcigpLgorICAqLworcHJpdmF0ZSB2b2lkIEluaXRQbGF5ZXI0KCkKK3sKKyAgICBpbnQgbnVtLCBzdHIsIHNraTsKKyAgICBzdHJpbmcgZXJyLCBjYWxsZWRfZnJvbV9pcDsKKyAgICBtaXhlZCBzdGFydF9wbGFjZTsKKyAgICBvYmplY3QgbW9uOworCisgICAgZW5hYmxlX2NvbW1hbmRzKCk7CisgICAgc2V0X2hlYXJ0X2JlYXQoMSk7CisgICAgY29tbWFuZDo6aW5pdGlhbGl6ZSgpOworICAgIGFkZF9wdXRfYW5kX2dldF9jb21tYW5kcygpOworICAgIGFkZF90ZWFtX2NvbW1hbmRzKCk7CisgICAgYWRkX3NvdWxfY29tbWFuZHMoKTsKKyAgICBhZGRfZ3VpZGVfY29tbWFuZHMoKTsKKyAgICBhZGRfYWN0aW9uKCAiVXNlU3BlbGwiLCAiIiwgMSApOworICAgIHNldF9saXZpbmdfbmFtZSggZ2V0dWlkKCkgKTsKKyAgICB3aGlsZSAoIHJlbW92ZV9jYWxsX291dCgiZGlzY29ubmVjdCIpICE9IC0xICkKKyAgICAgICAgOworCisgICAgaWYgKCBRdWVyeVByb3AoUF9MRVZFTCkgPT0gLTEgKQorICAgIHsKKyAgICAgICAgY2F0Y2goICIvc3RkL2dpbGRlIi0+dHJ5X3BsYXllcl9hZHZhbmNlKHRoaXNfb2JqZWN0KCkpIDtwdWJsaXNoICk7CisgICAgfQorCisgICAgaWYgKCBpbnRlcmFjdGl2ZShNRSkgKQorICAgICAgICBjYWxsX25vdGlmeV9wbGF5ZXJfY2hhbmdlKDEpOworCisgICAgaWYgKCBpbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKSApIHsKKyAgICAgICAgY2F0KCAiL2V0Yy9ORVdTIiApOworCisgICAgICAgIE5ld2JpZUludHJvTXNnKCk7CisKKyAgICAgICAgaWYgKCBRdWVyeVByb3AoUF9JTlZJUykgJiYgIUlTX1dJWkFSRChNRSkgKQorICAgICAgICAgICAgU2V0UHJvcCggUF9JTlZJUywgMCApOworCisgICAgICAgIGNhdGNoKCBudW0gPSAic2VjdXJlL21haWxlciItPkZpbmdlck1haWwoZ2V0dWlkKCkpO3B1Ymxpc2ggKTsKKworICAgICAgICBpZiAoIG51bSApCisgICAgICAgICAgICB3cml0ZSggIkR1IGhhc3QgIiArIG51bSArICIgbmV1ZSIgKworICAgICAgICAgICAgICAgICAgIChudW0gPT0gMSA/ICJuIEJyaWVmIiA6ICIgQnJpZWZlIikrIiBpbSBQb3N0YW10IGxpZWdlbi5cbiIgKTsKKworICAgICAgICBjYXRjaCggUmVnaXN0ZXJDaGFubmVscygpO3B1Ymxpc2ggKTsKKworICAgICAgICBpZiAoIChjYWxsZWRfZnJvbV9pcCA9IFF1ZXJ5KFBfQ0FMTEVEX0ZST01fSVApKSAmJgorICAgICAgICAgICAgIHF1ZXJ5X2lwX251bWJlcihNRSkgIT0gY2FsbGVkX2Zyb21faXAgKXsKKyAgICAgICAgICAgIHN0cmluZyB0bXA7CisKKyAgICAgICAgICAgIGlmICggc3RyaW5ncCh0bXAgPSBxdWVyeV9pcF9uYW1lKGNhbGxlZF9mcm9tX2lwKSkgJiYKKyAgICAgICAgICAgICAgICAgdG1wICE9IGNhbGxlZF9mcm9tX2lwICkKKyAgICAgICAgICAgICAgICB0bXAgPSAiIFsiICsgdG1wICsgIl0iOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHRtcCA9ICIiOworCisgICAgICAgICAgICB3cml0ZSggIkRhcyBsZXR6dGUgTWFsIGthbXN0IER1IHZvbiAiICsgY2FsbGVkX2Zyb21faXAKKyAgICAgICAgICAgICAgICAgICArIHRtcCArICIuXG4iICk7CisgICAgICAgIH0KKworICAgICAgICBTZXQoIFBfQ0FMTEVEX0ZST01fSVAsIHF1ZXJ5X2lwX251bWJlcihNRSkgKTsKKyAgICB9CisKKyAgICBpZiAoICFzdHJpbmdwKGRlZmF1bHRfaG9tZSkgfHwgZGVmYXVsdF9ob21lID09ICIiICkKKyAgICAgICAgZGVmYXVsdF9ob21lID0gIi9naWxkZW4vYWJlbnRldXJlciI7CisKKyAgICBpZiAoIElTX1NFRVIoTUUpICYmICFJU19MRUFSTkVSKE1FKSApCisgICAgICAgIGNhdGNoKCBzdGFydF9wbGFjZSA9IEhBVVNWRVJXQUxURVItPkZpbmRlSGF1cyhnZXR1aWQoTUUpKTtwdWJsaXNoICk7CisgICAgLy8gd2VubiBkZXIgU3BpZWxlciBub2NoIGdhbnogZnJpc2NoIGlzdCB1bmQgbm9jaCB3ZW5pZyAgU3R1ZmVucHVua3RlCisgICAgLy8gZ2VrcmllZ3QgaGF0IHVuZCBkYXMgVHV0b3JpYWwgbm9jaCBuaWNodCBnZW1hY2h0IGhhdCwgc3RhcnRldCBlciBpbQorICAgIC8vIFR1dG9yaWFsLgorICAgIGVsc2UgaWYgKFF1ZXJ5UHJvcChQX0xFUCkgPD0gMTIwCisgICAgICAgICAgICAgJiYgUU0tPkhhc01pbmlRdWVzdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgICAgICAgIi9kL2FuZmFlbmdlci9lbm5veC90dXRvcmlhbC9ucGNzL3ZlcmthZXVmZXIiKSAhPSAxKQorICAgICAgICBzdGFydF9wbGFjZSA9ICIvcm9vbS93ZWxjb21lLyIrIGdldHVpZCh0aGlzX29iamVjdCgpKTsKKyAgICBlbHNlCisgICAgICAgIHN0YXJ0X3BsYWNlID0gMDsKKworICAgIGlmICggIXN0YXJ0X3BsYWNlICkKKyAgICAgICAgc3RhcnRfcGxhY2UgPSBRdWVyeVByb3AoUF9TVEFSVF9IT01FKTsKKworICAgIGlmKCBvYmplY3RwKHN0YXJ0X3BsYWNlKSB8fCAoc3RyaW5ncChzdGFydF9wbGFjZSkgJiYgc3RhcnRfcGxhY2UgIT0gIiIgKSApeworICAgICAgICBpZiAoKGVyciA9IGNhdGNoKG1vdmUoIHN0YXJ0X3BsYWNlLCBNX0dPfE1fU0lMRU5UfE1fTk9fU0hPVyApO3B1Ymxpc2gpKSAKKyAgICAgICAgICAgIHx8ICFlbnZpcm9ubWVudCgpICkKKyAgICAgICAgICAgIGVyciA9IGNhdGNoKG1vdmUoIGRlZmF1bHRfaG9tZSwgTV9HT3xNX1NJTEVOVHxNX05PX1NIT1cgKTtwdWJsaXNoKTsKKyAgICB9CisgICAgZWxzZQorICAgICAgICBlcnIgPSBjYXRjaChtb3ZlKCBkZWZhdWx0X2hvbWUsIE1fR098TV9TSUxFTlR8TV9OT19TSE9XICk7cHVibGlzaCk7CisKKyAgICBpZiAoIGVyciApCisgICAgICAgIGNhdGNoKG1vdmUoICIvZ2lsZGVuL2FiZW50ZXVyZXIiLCBNX0dPfE1fU0lMRU5UfE1fTk9fU0hPVyApO3B1Ymxpc2gpOworCisgICAgLy8gRGllIFNoZWxsIG11c3MgRmluYWxTZXR1cCgpIG5pY2h0IGltcGxlbWVudGllcmVuLiBEYWhlciBDYWxsb3RoZXIKKyAgICBjYXRjaCggTUUtPkZpbmFsU2V0dXAoKTtwdWJsaXNoICk7CisKKyAgICAvLyBMb2dpbi1ldmVudCBhdXNsb2VzZW4KKyAgICBFVkVOVEQtPlRyaWdnZXJFdmVudChFVlRfTElCX0xPR0lOLCAoWworICAgICAgICAgIEVfT0JKRUNUOiBNRSwKKyAgICAgICAgICBFX1BMTkFNRTogZ2V0dWlkKE1FKSwKKyAgICAgICAgICBFX0VOVklST05NRU5UOiBlbnZpcm9ubWVudCgpIF0pICk7CisKKyAgICAvLyBlcnN0IGpldHp0IEdNQ1AgZnJlaWdlYmVuIHVuZCB6dSB2ZXJoYW5kZWxuLgorICAgIGdtY3A6OnN0YXJ0dXBfdGVsbmV0X25lZ3MoKTsKKworICAgIC8vIFNjaG9ubWFsIHNpY2hlcm4sIGZhbGxzIGVpbiBCdWcgKEV2YWxjb3N0Li4uKSBkYXp3aXNjaGVuIGtvbW1lbiBzb2xsdGUuCisgICAgYXV0b2xvYWRfcmVzdCA9IGF1dG9sb2FkOworCisgICAgLy8gVW0gR2VsZC1YdGllcyBtaXQgaWxsZWdhbCB2aWVsIEdlbGQgenUgdmVybWVpZGVuLCBrb21tdCBlaW4gQ2hlY2s6CisgICAgaWYgKCAhSVNfTEVBUk5FUihNRSkgJiYgIVF1ZXJ5KFBfVEVTVFBMQVlFUikgJiYKKyAgICAgICAgIG1vbiA9IHByZXNlbnQoICJcbmdlbGQiLCBNRSApICl7CisgICAgICAgIC8vIG1heGltYWxlIEtyYWZ0LCBkaWUgZGVyIFNwaWVsZXIgaGFldHRlIGhhYmVuIGtvZW5uZW4KKyAgICAgICAgc3RyID0gUXVlcnlBdHRyaWJ1dGUoQV9TVFIpICsgNDsKKyAgICAgICAgaWYgKCBRdWVyeShQX0ZST0cpICkKKyAgICAgICAgICAgIHN0ciArPSAzMDsKKyAgICAgICAgaWYgKCBzdHIgPCAxICkKKyAgICAgICAgICAgIHN0ciA9IFF1ZXJ5UmVhbEF0dHJpYnV0ZShBX1NUUikgKyA0OworICAgICAgICBpZiAoIHN0ciA+IDMwICkKKyAgICAgICAgICAgIHN0ciA9IDMwOworCisgICAgICAgIC8vIFRyYWdlc2tpbGwgYmVhY2h0ZW4KKyAgICAgICAgc2tpID0gdG9faW50KFVzZVNraWxsKCBTS19DQVJSWSwgKFtTSV9TS0lMTEFSRyA6IHN0ciBdKSApKTsKKyAgICAgICAgaWYgKCAhaW50cChza2kpICkKKyAgICAgICAgICAgIHNraSA9IDA7CisKKyAgICAgICAgLy8gV2lldmllbCBrb25udGUgZGVyIFNwaWVsZXIgaW5zZ2VzYW10IG1heGltYWwgdHJhZ2VuPworICAgICAgICBudW0gPSA5MjAwICsgc3RyICogODAwICsgc2tpOworICAgICAgICBpZiAoIG51bSA8IDMwMDAgKQorICAgICAgICAgICAgbnVtID0gMzAwMDsKKworICAgICAgICAvLyBWZXJkb3BwZWxuIGZ1ZXIgZWluZW4gZ3V0ZW4gQ29udGFpbmVyIHVuZCBub2NobWFsIDIwJSBkcmF1ZnNjaGxhZ2VuCisgICAgICAgIC8vIHp1ciBTaWNoZXJoZWl0LiBEYXMgR2FuemUgZGFuYWNoICo0LCB1bSBkaWUgbWF4aW1hbGUgQW56YWhsIE11ZW56ZW4KKyAgICAgICAgLy8genUgZXJoYWx0ZW4uCisgICAgICAgIG51bSA9IChpbnQpIChudW0gKiA4LjgpOworCisgICAgICAgIC8vIEdlbGQsIGRhcyB6dXZpZWwgaXN0LCBhdWYgZGVuIE1heGltYWx3ZXJ0IGt1ZXJ6ZW4uCisgICAgICAgIC8vIFp1ciBTaWNoZXJoZWl0IHdpcmQgbWl0Z2Vsb2dndC4gRmFsbHMgZWluIFNwaWVsZXIgc2ljaCAoenUgcmVjaHQpCisgICAgICAgIC8vIGJlc2Nod2VydCwga2FubiBtYW4gaW1tZXIgbm9jaCB3aWVkZXIgZGllIFN1bW1lIGtvcnJpZ2llcmVuIDstKQorICAgICAgICBpZiAoIChzdHIgPSBtb24tPlF1ZXJ5UHJvcChQX0FNT1VOVCkpID4gbnVtICl7CisgICAgICAgICAgICBtb24tPlNldFByb3AoIFBfQU1PVU5ULCBudW0gKTsKKyAgICAgICAgICAgIGxvZ19maWxlKCAiWlVWSUVMX0dFTEQiLCBzcHJpbnRmKCAiJXM6ICVzIGhhdHRlICVkIE11ZW56ZW4gYmVpICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2ljaC4gS29ycmlnaWVydCBhdWYgJWQuXG4gIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdGltZSh0aW1lKCkpWzQuLl0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShnZXR1aWQoTUUpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIsIG51bSApICk7CisgICAgICAgIH0KKyAgICB9CisgICAgaW50IGVudHNjaGFlZGlndW5nID0gUXVlcnlQcm9wKFBfQ0FSUklFRF9WQUxVRSk7CisgICAgaWYgKCBlbnRzY2hhZWRpZ3VuZyA+IDAgKQorICAgIHsKKyAgICAgICAgd3JpdGUoICJEdSBmaW5kZXN0ICIgKyBlbnRzY2hhZWRpZ3VuZyArCisgICAgICAgICAgICAgICAiIE11ZW56ZW4sIGRpZSBEdSBiZWltIGxldHp0ZW4gTWFsIHZlcmxvcmVuIGhhc3QuXG4iICk7CisKKyAgICAgICAgaWYgKCBNYXlBZGRXZWlnaHQoIGVudHNjaGFlZGlndW5nIC8gNCApICl7CisgICAgICAgICAgICB3cml0ZSggIldlaWwgRHUgbmljaHQgbWVociBzb3ZpZWwgdHJhZ2VuIGthbm5zdCwgc3BlbmRlc3QgRHUgZGVuICIrCisgICAgICAgICAgICAgICAgICAgIlJlc3QgZGVyIFplbnRyYWxiYW5rLlxuIiApOworCisgICAgICAgICAgICBudW0gPSAoUXVlcnlQcm9wKFBfTUFYX1dFSUdIVCkgLSBxdWVyeV93ZWlnaHRfY29udGVudHMoKSkgKiA0OworICAgICAgICAgICAgZW50c2NoYWVkaWd1bmcgPSAobnVtIDwgMCkgPyAwIDogbnVtOworICAgICAgICB9CisKKyAgICAgICAgQWRkTW9uZXkoIGVudHNjaGFlZGlndW5nICk7CisgICAgICAgIFNldFByb3AoUF9DQVJSSUVEX1ZBTFVFLDApOworICAgIH0KKworICAgIGlmICggIVF1ZXJ5UHJvcChQX0lOVklTKSApCisgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKFdFUikpICsgIiBiZXRyaXR0IGRpZXNlIFdlbHQuXG4iICk7CisgICAgZWxzZQorICAgICAgICB3cml0ZSggIkRVIEJJU1QgVU5TSUNIVEJBUiFcblxuIiApOworI2lmIF9fRUZVTl9ERUZJTkVEX18oc2V0X2lzX3dpemFyZCkKKyAgICBpZiAoIElTX1dJWkFSRChnZXR1aWQoTUUpKSApCisgICAgICAgIHNldF9pc193aXphcmQoIE1FLCAxICk7CisgICAgZWxzZQorICAgICAgICBzZXRfaXNfd2l6YXJkKCBNRSwgMCApOworI2VuZGlmCisgICAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApCisgICAgICAgIExpc3RBd2FpdGVkKCk7CisKKyAgICAvLyBBdXRvbG9hZGVyIHdlcmRlbiBnYW56IHp1bSBTY2hsdXNzIGdlY2xvbnQsIGRhIGRhcyBiaXMgenVtIGJpdHRlcmVuCisgICAgLy8gKEV2YWxjb3N0LSlFbmRlIGdlc2NoaWVodCB1bmQgZGFuYWNoIHUuVS4ga2VpbmUgUmVjaGVuemVpdCBmdWVyCisgICAgLy8gYW5kZXJlIEFrdGlvbmVuIG1laHIgdWViZXIgaXN0CisgICAgbG9hZF9hdXRvX29iamVjdHMoIGF1dG9sb2FkICk7Cit9CisKKy8qKiBTZXR6dCBkaWUgU3BpZWxlcmluaXRpYWxpc2llcnVuZyBuYWNoIHN0YXJ0X3BsYXllcigpIGZvcnQuCisgICogUHJ1ZWZ0IGRlbiBXZXJ0IGRlciB2b20gU3BpZWxlciBnZXRyYWdlbmVuIFNhY2hlbiAoZnVlciBFbnRzY2hhZWRpZ3VuZworICAqIG5hY2ggUmVib290KS4KKyAgKiBTZXR6dCBkaXYuIFByb3BlcnRpZXMgZGVzICJTcGllbGVya29lcnBlcnMiLCBkaWUgZWlnZW50bGljaCBnZXNwZWljaGVydAorICAqIHdlcmRlbiwgbmFjaCBlaW5lbSBSZWJvb3QgenVydWVjay4KKyAgKiBGcmFndCBnZ2YuIG5hY2ggZU1haWwtQWRyZXNzZSB1bmQgdWViZXJnaWJ0IHBlciBpbnB1dF90byBhbgorICAqIEluaXRQbGF5ZXIyKCkuCisgICogQHNhIEluaXRQbGF5ZXIzKCksSW5pdFBsYXllcjIoKSwgSW5pdFBsYXllcigpLCBzdGFydF9wbGF5ZXIoKS4KKyovCitwcml2YXRlIHZvaWQgSW5pdFBsYXllcigpCit7CisgICAgc3RyaW5nIG1haWxhZGRyOworCisgICAgLy8gd2VubiBlcyBlaW5lbiBDcmFzaCBnYWIsIHNvbGxlbiBTcGllbGVyIG5pY2h0IG5vY2ggZXh0cmEgYmVzdHJhZnQgd2VyZGVuCisgICAgaWYgKCBmaWxlX3RpbWUoICIvc2F2ZS8iICsgZ2V0dWlkKClbMC4uMF0gKyAiLyIgKyBnZXR1aWQoKSArICIubyIgKQorICAgICAgICAgPCBsYXN0X3JlYm9vdF90aW1lKCkgKXsKKyAgICAgICAgU2V0UHJvcCggUF9GT09ELCAwICk7CisgICAgICAgIFNldFByb3AoIFBfRFJJTkssIDAgKTsKKyAgICAgICAgU2V0UHJvcCggUF9BTENPSE9MLCAwICk7CisgICAgICAgIFNldFByb3AoIFBfQkxJTkQsIDAgKTsKKyAgICAgICAgU2V0UHJvcCggUF9ERUFGLCAwICk7CisgICAgICAgIFNldFByb3AoIFBfUE9JU09OLCAwICk7CisgICAgICAgIFNldFByb3AoIFBfR0hPU1QsIDAgKTsKKyAgICAgICAgU2V0UHJvcCggUF9GUk9HLCAwICk7CisgICAgICAgIFNldFByb3AoIFBfSFAsIFF1ZXJ5UHJvcChQX01BWF9IUCkgKTsKKyAgICAgICAgU2V0UHJvcCggUF9TUCwgUXVlcnlQcm9wKFBfTUFYX1NQKSApOworICAgIH0KKworICAgIGlmICggUXVlcnlHdWVzdCgpICkKKyAgICAgICAgU2V0KCBQX01BSUxBRERSLCAibm9uZSIgKTsKKyAgICBlbHNlIGlmICggIShtYWlsYWRkciA9IFF1ZXJ5KFBfTUFJTEFERFIpKSB8fCBtYWlsYWRkciA9PSAiIiApIHsKKyAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKAorICAgICAgICAgICJFaW5lIGd1ZWx0aWdlIEVNYWlsLUFkcmVzc2UgZXJsZWljaHRlcnQgZXMgZXJoZWJsaWNoLCBEaXIgIgorICAgICAgICAgICJlaW4gbmV1ZXMgUGFzc3dvcnQgc2V0emVuIHp1IGxhc3NlbiwgZmFsbHMgRHUgZWlubWFsIERlaW4gIgorICAgICAgICAgICJQYXNzd29ydCB2ZXJnaXNzdC4iLDc4KSk7IAorICAgICAgICBpbnB1dF90byggImdldG1haWxhZGRyIixJTlBVVF9QUk9NUFQsCisgICAgICAgICAgICAiR2liIGJpdHRlIERlaW5lIEVNYWlsLUFkcmVzc2UgYW46ICIgKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBJbml0UGxheWVyMigpOworfQorCisvKiogbGllc3QgZU1haWwtQWRyZXNzZSB2b20gU3BpZWxlciBlaW4gdW5kIHNwZWljaGVydCBzaWUuCisgICogVWViZXJnaWJ0IGFuc2NobGllc3NlbmQgYW4gSW5pdFBsYXllcjIoKQorICAqIEBwYXJhbVtpbl0gbWFkZHIgU3BpZWxlcmVpbmdhYmUgZGVyIEVtYWlsYWRyZXNzZS4KKyAgKiBAc2EgSW5pdFBsYXllcjIoKS4KKyAgKi8KK3N0YXRpYyB2b2lkIGdldG1haWxhZGRyKCBzdHJpbmcgbWFkZHIgKQoreworICAgIG1hZGRyID0gY2hlY2tfZW1haWwobWFkZHIpOworCisgICAgaWYgKCAhc3RyaW5ncChtYWRkcikpIHsKKyAgICAgIHdyaXRlKCJEZWluZSBFaW5nYWJlIHNjaGVpbnQga2VpbmUgZ3VlbHRpZ2UgRU1haWwtQWRyZXNzZSBnZXdlc2VuICIKKyAgICAgICAgICAienUgc2Vpbi5cbiIpOworICAgICAgaW5wdXRfdG8oICJnZXRtYWlsYWRkciIsIElOUFVUX1BST01QVCwKKyAgICAgICAgICAiR2liIGJpdHRlIERlaW5lIEVNYWlsLUFkcmVzc2UgYW46ICIgKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgU2V0KCBQX01BSUxBRERSLCBtYWRkciApOworICAgIEluaXRQbGF5ZXIyKCk7Cit9CisKKworLyoqIFBydWVmdCBHZXNjaGxlY2h0IGRlcyBTcGllbGVycyB1bmQgZnJhZ3QgZ2dmLiBiZWltIFNwaWVsZXIgbmFjaC4KKyAgKiBVZWJlcmdpYnQgYW4gSW5pdFBsYXllcjMoKSBvZGVyIGdldF9nZW5kZXIoKS4KKyAgKiBAc2EgSW5pdFBsYXllcjMoKSwgZ2V0X2dlbmRlcigpLgorICAqLworcHJpdmF0ZSB2b2lkIEluaXRQbGF5ZXIyKCkKK3sKKyAgICBpZiggbWVtYmVyKCh7IE1BTEUsIEZFTUFMRSB9KSwgUXVlcnlQcm9wKFBfR0VOREVSKSApID09IC0xICkgeworICAgICAgICBpbnB1dF90byggImdldGdlbmRlciIsIElOUFVUX1BST01QVCwKKyAgICAgICAgICAgICJCaXN0IER1IG1hZW5ubGljaCBvZGVyIHdlaWJsaWNoOiAiKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIEluaXRQbGF5ZXIzKCk7Cit9CisKKy8qKiBMaWVzdCBTcGllbGVyYW50d29ydCBhdWYgZGllIEZyYWdlIG5hY2ggZGVtIEdlc2NobGVjaHQgZGVzIENoYXJzIGVpbi4KKyAgKiBXaXJkIGdlcnVmZW4gdm9uIGlucHV0X3RvKCkuCisgICogVWViZXJnaWJ0IGFuIEluaXRQbGF5ZXIzKCkuCisgICogQHNhIEluaXRQbGF5ZXIzKCkuCisgICovCitzdGF0aWMgdm9pZCBnZXRnZW5kZXIoIHN0cmluZyBnZW5kZXJfc3RyaW5nICkKK3sKKyAgICBnZW5kZXJfc3RyaW5nID0gbG93ZXJfY2FzZSggZ2VuZGVyX3N0cmluZyApOworCisgICAgaWYgKCBzaXplb2YoZ2VuZGVyX3N0cmluZyk9PTEgJiYgZ2VuZGVyX3N0cmluZ1swXSA9PSAnbScgKXsKKyAgICAgICAgd3JpdGUoICJXaWxsa29tbWVuLCBtZWluIEhlcnIhXG4iICk7CisgICAgICAgIFNldFByb3AoIFBfR0VOREVSLCBNQUxFICk7CisgICAgfQorICAgIGVsc2UgaWYgKCBzaXplb2YoZ2VuZGVyX3N0cmluZyk9PTEgJiYgZ2VuZGVyX3N0cmluZ1swXSA9PSAndycgKXsgICAgCisgICAgICAgIHdyaXRlKCAiV2lsbGtvbW1lbiwgZ25hZScgRnJhdSFcbiIgKTsKKyAgICAgICAgU2V0UHJvcCggUF9HRU5ERVIsIEZFTUFMRSApOyAgICAKKyAgICB9ICAgIAorICAgIGVsc2UgeworICAgICAgICB3cml0ZSggIldpZT8gV2FzPyBWZXJzdGVoZSBpY2ggbmljaHQhXG4iICk7ICAgIAorICAgICAgICBpbnB1dF90byggImdldGdlbmRlciIsIElOUFVUX1BST01QVCwKKyAgICAgICAgICAgICJCaXN0IER1IG1hZW5ubGljaCBvZGVyIHdlaWJsaWNoPyAodGlwcGUgbSBvZGVyIHcpOiAiKTsgICAgCisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBJbml0UGxheWVyMygpOworfQorCisKKy8qKiBQcnVlZnQgVGVybWluYWx0eXAgZGVzIFNwaWVsZXJzIHVuZCBmcmFndCBnZ2YuIGJlaW0gU3BpZWxlciBuYWNoLgorICAqIFVlYmVyZ2lidCBhbiBJbml0UGxheWVyNCgpIG9kZXIgZ2V0dHR5KCkuCisgICogQHNhIEluaXRQbGF5ZXI0KCksIGdldHR0eSgpLgorICAqLworcHJpdmF0ZSB2b2lkIEluaXRQbGF5ZXIzKCkKK3sKKyAgICBpZiAoICFRdWVyeVByb3AoUF9UVFkpIHx8IFF1ZXJ5UHJvcChQX1RUWSkgPT0gIm5vbmUiICkKKyAgICB7CisgICAgICAgIHdyaXRlKCAiV2FlaGxlIGVpbmVuIFRlcm1pbmFsdHlwIChrYW5uIHNwYWV0ZXIgbWl0IDxzdHR5PiBnZWFlbmRlcnQgIgorICAgICAgICAgICAgICAgIndlcmRlbilcbiIpOworICAgICAgICBpbnB1dF90byggImdldHR0eSIsIElOUFVUX1BST01QVCwgInZ0MTAwLCBhbnNpLCBkdW1iIChTdGFuZGFyZDogZHVtYik6ICIgKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBJbml0UGxheWVyNCgpOworfQorCisvKiogTGllc3QgU3BpZWxlcmFudHdvcnQgYXVmIGRpZSBGcmFnZSBuYWNoIGRlbSBUZXJtaW5hbHR5cCBlaW4uCisgICogV2lyZCBnZXJ1ZmVuIHZvbiBpbnB1dF90bygpLgorICAqIFVlYmVyZ2lidCBhbiBJbml0UGxheWVyNCgpLgorICAqIEBzYSBJbml0UGxheWVyNCgpLgorICAqLworc3RhdGljIHZvaWQgZ2V0dHR5KCBzdHJpbmcgdHR5c3RyICkKK3sKKyAgICBpZiAoICF0dHlzdHIgfHwgdHR5c3RyID09ICIiICkKKyAgICAgICAgdHR5c3RyID0gImR1bWIiOworCisgICAgdHR5c3RyID0gbG93ZXJfY2FzZSh0dHlzdHIpOworCisgICAgaWYgKCB0dHlzdHIgPT0gInZ0MTAwIiApeworICAgICAgICB3cml0ZSggIkRpZXMgc29sbHRlICIgKyBBTlNJX0JPTEQgKyAiZmV0dCIgKyBBTlNJX05PUk1BTCArICIgc2Vpbi5cbiIgKTsKKyAgICAgICAgU2V0UHJvcCggUF9UVFksIHR0eXN0ciApOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIGlmICggdHR5c3RyID09ICJhbnNpIiApeworICAgICAgICAgICAgd3JpdGUoICJEaWVzIHNvbGx0ZSAiICsgQU5TSV9SRUQgKyAicm90IiArIEFOU0lfTk9STUFMICsKKyAgICAgICAgICAgICAgICAgICAiIHNlaW4uXG4iICk7CisgICAgICAgICAgICBTZXRQcm9wKCBQX1RUWSwgImFuc2kiICk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoIHR0eXN0ciA9PSAiZHVtYiIgKXsKKyAgICAgICAgICAgIHdyaXRlKCAiT2hqZSwgb2VkZSEgQmVzb3JnIERpciBlaW4gYmVzc2VyZXMgVGVybWluYWwhXG4iICk7CisgICAgICAgICAgICBTZXRQcm9wKCBQX1RUWSwgImR1bWIiICk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICB3cml0ZSggIkRpZXNlciBUZXJtaW5hbHR5cCB3aXJkIG5pY2h0IHVudGVyc3R1ZXR6dC4gTmltbSBiaXR0ZSAiCisgICAgICAgICAgICAgICAgICAgImVpbmVuIGF1czpcbnZ0MTAwLCBhbnNpIG9yIGR1bWIgKFN0YW5kYXJkIGlzdCBkdW1iKS5cbiIgKTsKKyAgICAgICAgICAgIGlucHV0X3RvKCAiZ2V0dHR5IiwgSU5QVVRfUFJPTVBULAorICAgICAgICAgICAgICAgICJ2dDEwMCwgYW5zaSBvciBkdW1iIChTdGFuZGFyZCBpc3QgZHVtYik6ICIpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisKKyAgICBJbml0UGxheWVyNCgpOworfQorCisKKy8qKiBMaWVmZXJ0IGRpZSBVSUQgZGVzIENoYXJha3RlcnMgenVydWVjaywgYWxzbyBkZW4gQ2hhcmFrdGVybmFtZW4uCisgICogQHJldHVybiBVSUQgZGVzIE9iamVrdHMgKENoYXJha3Rlcm5hbWUpLgorICAqLworbm9tYXNrIHN0cmluZyBxdWVyeV9yZWFsX25hbWUoKSB7CisgIC8qIEFDSFRVTkcgISEgRElFUyBMRlVOIERBUkYgTklDSFQgRU5URkVSTlQgV0VSREVOICEhISAqLworICAvKiBTaWUgd2lyZCB2b20gR2FtZWRyaXZlciAoekIgYmVpIEZfRUQpIGF1ZmdlcnVmZW4gISEgKi8KKyAgLyogSWNoIGJpbiBkYSB6d2FyIG5pY2h0IHNvIHVlYmVyemV1Z3Qgdm9uLCBkYXNzIGRlciBEcml2ZXIgZGllIGhldXR6dXRhZ2UKKyAgICogbm9jaCBydWZ0LCBhYmVyIGRpZSBoYWxiZSBNdWRsaWIgcnVmdCBzaWUuIDstKSAoWmVzc3RyYSwgMjcuNC4wOCkKKyAgICovCisgIHJldHVybiBnZXR1aWQoKTsKK30KKworLyoKKyAqIHRoZSB3aXphcmQgY29tbWFuZCByZXZpZXc6IHNob3cgcGxheWVyIG1vdmluZyBtZXNzYWdlcworICovCitpbnQgcmV2aWV3KCkgeworICBzdHJpbmcgKm1zZzsKKyAgd3JpdGUoc2hvcnQoKSk7CisgIHdyaXRlKCJEZWluZSBCZXdlZ3VuZ2VuIHdlcmRlbiB3aWUgZm9sZ3QgZ2VtZWxkZXQ6XG4iKworICAgICAgICAibW91dDogICIrbmFtZShXRVIpKyIgIisobXNnPWV4cGxvZGUoUXVlcnlQcm9wKFBfTVNHT1VUKSwiIyIpKVswXQorICAgICAgICsiIDxSaWNodHVuZz4iKyhzaXplb2YobXNnKT4xID8gbXNnWzFdIDogIiIpKyIuXG4iKworICAgICAgICAibWluOiAgICIrbmFtZShXRVIpKyIgIitRdWVyeVByb3AoUF9NU0dJTikrIi5cbiIrCisgICAgICAgICJtbW91dDogIituYW1lKFdFUikrIiAiK1F1ZXJ5UHJvcChQX01NU0dPVVQpKyIuXG4iKworICAgICAgICAibW1pbjogICIrbmFtZShXRVIpKyIgIitRdWVyeVByb3AoUF9NTVNHSU4pKyIuXG4iKworICAgICAgICAoSVNfTEVBUk5FUihNRSkgPworICAgICAgICAgImNtc2c6ICAiK25hbWUoV0VSKSsiICIrUXVlcnlQcm9wKFBfQ0xPTkVfTVNHKSsiLlxuIisKKyAgICAgICAgICJkbXNnOiAgPElyZ2VuZGV0d2FzPiAiK1F1ZXJ5UHJvcChQX0RFU1RSVUNUX01TRykrIi5cbiIKKyAgICAgICAgIDogIiIpKworICAgICAgICAiV2VubiBEdSBqZW1hbmRlbiBhbmdyZWlmc3QsIHNpZWh0IGRhcyBzbyBhdXM6XG4iKworICAgICAgICBuYW1lKFdFUikrIiBncmVpZnQgRGljaCIrUXVlcnlQcm9wKFBfSEFORFMpWzBdKyIgYW4uXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8qCisgKiBzZXQgcGxheWVyIG1vdmluZyBtZXNzYWdlcworICovCisKK3N0YXRpYyBpbnQgc2V0bWluKHN0cmluZyBzdHIpCit7CisgIFNldFByb3AoUF9NU0dJTiwgX3VucGFyc2VkX2FyZ3MoKXx8ImtvbW10IGFuIik7CisgIHdyaXRlKCJPay5cbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBzZXRtb3V0KHN0cmluZyBzdHIpCit7CisgIHN0cmluZyAqbXNnOworCisgIGlmKHNpemVvZihtc2c9ZXhwbG9kZSgoX3VucGFyc2VkX2FyZ3MoKXx8ImdlaHQiKSwiIyIpKT4yKQorICB7CisgICAgd3JpdGUoIkR1IGRhcmZzdCBudXIgZWlubWFsICcjJyBmdWVyIGRpZSBSaWNodHVuZyBhbmdlYmVuLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYoc2l6ZW9mKG1zZyk+MSkKKyAgeworICAgIGlmIChtc2dbMF0hPSIiICYmIG1zZ1swXVs8MV09PScgJykgbXNnWzBdPW1zZ1swXVswLi48Ml07CisgICAgU2V0UHJvcChQX01TR09VVCwgbXNnWzBdKyIjIittc2dbMV0pOworICB9CisgIGVsc2UKKyAgICBTZXRQcm9wKFBfTVNHT1VULCBfdW5wYXJzZWRfYXJncygpfHwiZ2VodCIpOworICB3cml0ZSgiT2suXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgc2V0bW1pbihzdHJpbmcgc3RyKQoreworICBTZXRQcm9wKFBfTU1TR0lOLCBfdW5wYXJzZWRfYXJncygpfHwiZXJzY2hlaW50Iik7CisgIHdyaXRlKCJPay5cbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBzZXRtbW91dChzdHJpbmcgc3RyKQoreworICBTZXRQcm9wKFBfTU1TR09VVCwgX3VucGFyc2VkX2FyZ3MoKXx8InZlcnNjaHdpbmRldCIpOworICB3cml0ZSgiT2suXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgc2V0Y21zZyhzdHJpbmcgc3RyKQoreworICBTZXRQcm9wKFBfQ0xPTkVfTVNHLCBfdW5wYXJzZWRfYXJncygpfHwiemF1YmVydCBldHdhcyBhdXMgIgorICAgICAgICAgICsgUXVlcnlQb3NzUHJvbm91bihNQUxFLFdFTSkgKyAiIEFlcm1lbCBoZXJ2b3IiKTsKKyAgd3JpdGUoIk9rLlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IHNldGRtc2coc3RyaW5nIHN0cikKK3sKKyAgU2V0UHJvcChQX0RFU1RSVUNUX01TRywgX3VucGFyc2VkX2FyZ3MoKXx8IndpcmQgdm9uICIgKyBuYW1lKFdFUiwxKQorICAgICAgICAgICsgIiB6ZXJzdGFldWJ0Iik7CisgIHdyaXRlKCJPay5cbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBzZXRfdGl0bGUoc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nIGJvbnVzOworICAKKyAgaWYoIUlTX1NFRVIodGhpc19vYmplY3QoKSkgJiYgIUZBT19IQVNfVElUTEVfR0lGVCh0aGlzX29iamVjdCgpKSApCisgIHsKKyAgICByZXR1cm4gMDsKKyAgfQorICAKKyAgYm9udXMgPSAiIjsKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpKQorICAgIHN0ciA9ICIiOworICBlbHNlIGlmKCBzdHJbMC4uMl09PSJcXGIsIiB8fCBzdHJbMC4uMl09PSJcXGInIiApCisgIHsKKyAgICBib251cyA9ICJcYiI7IC8vIGVpbiBiYWNrc3BhY2UgZnVlciBlaW4gKGhvY2gpa29tbWEgaXN0IG9rISA6LSkKKyAgICBzdHIgPSBzdHJbMi4uXTsKKyAgfQorICBpZihzdHI9PSIwIikgIC8vIGRhbWl0IGRlciBHaWxkZW50aXRlbCB6dW0gVm9yc2NoZWluIGtvbW1lbiBrYW5uCisgICAgU2V0UHJvcChQX1RJVExFLCAwKTsKKyAgZWxzZQorICAgIFNldFByb3AoUF9USVRMRSwgYm9udXMrc3RyKTsKKyAgd3JpdGUoIk9rLlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IGV4dHJhX2lucHV0KHN0cmluZyBzdHIsIHN0cmluZyBsb29rKQoreworICBpZiAoc3RyPT0iKioiKQorICB7CisgICAgaWYgKGxvb2s9PSIiKQorICAgICAgU2V0UHJvcChQX0VYVFJBX0xPT0ssMCk7CisgICAgZWxzZQorICAgICAgU2V0UHJvcChQX0VYVFJBX0xPT0ssbG9vayk7CisgICAgd3JpdGUoIk9rLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaW5wdXRfdG8oImV4dHJhX2lucHV0IixJTlBVVF9QUk9NUFQsICJdIiAsbG9vaytzdHIrIlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IGV4dHJhbG9vayhtaXhlZCBzdHIpCit7CisgIGlmKCBzdHI9PSI/IiApCisgIHsKKyAgICB3cml0ZSggIkRlaW4gRXh0cmFsb29rIGlzdCA6ICIrUXVlcnlQcm9wKFBfRVhUUkFfTE9PSykgKyAiXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICB3cml0ZSgiQml0dGUgZ2liIERlaW5lbiBFeHRyYS1Mb29rIGVpbi4gQmVlbmRlbiBtaXQgKio6XG4iKTsKKyAgaW5wdXRfdG8oImV4dHJhX2lucHV0IixJTlBVVF9QUk9NUFQsIl0iLCIiKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyB2b2lkIGNhbGN1bGF0ZV92YWx1ZSgpCit7CisgIGludCBpLCBjYXJyaWVkX3ZhbHVlLCB2YWx1ZTsKKworICBjYXJyaWVkX3ZhbHVlPTA7CisgIGZvcmVhY2gob2JqZWN0IG9iOiBkZWVwX2ludmVudG9yeShNRSkpIHsKKyAgICBpZiAoIW9iLT5RdWVyeVByb3AoUF9BVVRPTE9BRE9CSikpCisgICAgICBjYXJyaWVkX3ZhbHVlKz0oKHZhbHVlPShpbnQpb2ItPlF1ZXJ5UHJvcChQX1ZBTFVFKSkgPiAxMDAwID8gMTAwMCA6IHZhbHVlKTsKKyAgfQorICBTZXRQcm9wKFBfQ0FSUklFRF9WQUxVRSwgY2FycmllZF92YWx1ZSk7Cit9CisKKy8qIENhbGxlZCBieSBjb21tYW5kICdzYXZlJyAqLworaW50IHNhdmVfY2hhcmFjdGVyKCkgeworICBzYXZlX21lKDEpOworICB3cml0ZSgiT2suXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3ZvaWQgc2F2ZV9tZShtaXhlZCB2YWx1ZV9pdGVtcykKK3sKKyAgLy8gR2Flc3RlIHdlcmRlbiBuaWNodCBnZXNwZWljaGVydAorICBpZiggZ2V0dWlkKClbMC4uM109PSJnYXN0IiApCisgICAgcmV0dXJuOworIAorICAvLyBBdXRvbG9hZGVyIGlkZW50aWZpemllcmVuIHVuZCBzcGVpY2hlcm4KKyAgYXV0b2xvYWQ9KFtdKTsKKyAgZm9yZWFjaChvYmplY3Qgb2I6IGRlZXBfaW52ZW50b3J5KE1FKSkgeworICAgIGludCB2YWwgPSBvYi0+UXVlcnlQcm9wKCBQX0FVVE9MT0FET0JKICk7CisgICAgaWYgKHZhbCAmJiBjbG9uZXAob2IpKQorICAgIHsKKyAgICAgIHN0cmluZyBvYm5hbWU9bG9hZF9uYW1lKG9iKTsKKyAgICAgIGlmIChvYm5hbWUgPT0gR0VMRCkKKyAgICAgICAgYXV0b2xvYWRbb2JuYW1lXSArPSB2YWw7CisgICAgICBlbHNlCisgICAgICAgIGF1dG9sb2FkICs9IChbb2JuYW1lOnZhbF0pOworICAgIH0KKyAgfQorICAvLyBBbiBub2NoIG5pY2h0IGdlY2xvbnRlIEF1dG9sb2FkZXIgZGVua2VuIQorICBhdXRvbG9hZCArPSBhdXRvbG9hZF9yZXN0OworICAKKyAgLy8gSW0gQmVkYXJmc2ZhbGwgV2VydCBkZXMgSW52ZW50b3J5IGJlc3RpbW1lbgorICBpZiAodmFsdWVfaXRlbXMpCisgICAgY2FsY3VsYXRlX3ZhbHVlKCk7CisgIGVsc2UKKyAgICBTZXRQcm9wKFBfQ0FSUklFRF9WQUxVRSwgMCk7CisKKyAgLy8gTG9nb3V0LVplaXQgc3BlaWNoZXJuCisgIGlmKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICYmICFRdWVyeVByb3AoUF9JTlZJUykpCisgICAgU2V0KFBfTEFTVF9MT0dPVVQsdGltZSgpKTsKKworICAvLyBGdW5rdGlvbiB6dXIgQmVzdGltbXVuZyBkZXMgR2lsZGVucmF0aW5nIGF1ZnJ1ZmVuCisgIHN0cmluZyBnaWxkZT1HVUlMRF9ESVIrUXVlcnlQcm9wKFBfR1VJTEQpOworICBpZiAoZmluZF9vYmplY3QoZ2lsZGUpIHx8IGZpbGVfc2l6ZShnaWxkZSsiLmMiKT4tMSkKKyAgICBjYXRjaChjYWxsX290aGVyKGdpbGRlLCJHdWlsZFJhdGluZyIsdGhpc19vYmplY3QoKSk7cHVibGlzaCk7CisKKyAgLy8gU3BlaWNoZXJuIGRlcyBTcGllbGVycworICBzYXZlX29iamVjdCgiLyIrU0FWRVBBVEgrZ2V0dWlkKClbMC4uMF0rIi8iICsgZ2V0dWlkKCkpOworfQorCitzdGF0aWMgdmFyYXJncyB2b2lkIGxvZ19hdXRvbG9hZCggc3RyaW5nIGZpbGUsIHN0cmluZyByZWFzb24sIG1peGVkIGRhdGEsIHN0cmluZyBlcnJvciApCit7CisgIGlmIChtZW1iZXIoYXV0b2xvYWRfZXJyb3IsZmlsZSkhPS0xKSByZXR1cm47CisgIGxvZ19maWxlKFNIRUxMTE9HKCJOT19BVVRPX0ZJTEUiKSxzcHJpbnRmKCIlczogJXM6ICVzXG5yZWFzb246IGNhbm5vdCAlcyBmaWxlXG5kYXRhOiAlT1xuJXNcbiIsCisgICAgICAgICAgIGN0aW1lKClbNC4uMTVdLGNhcGl0YWxpemUoZ2V0dWlkKCkpLGZpbGUscmVhc29uLGRhdGEsCisgICAgICAgICAgIChlcnJvcj8iRmVobGVybWVsZHVuZzogIitlcnJvcisiXG4iOiIiKSkpOworICBhdXRvbG9hZF9lcnJvcis9KHtmaWxlfSk7Cit9CisKKy8vIHRpY3MsIGRpZSBmdWVyIGF1dG9sb2FkZXIgcmVpY2hlbiBzb2xsdGVuOgorI2RlZmluZSBTQUZFX0ZPUl9BVVRPTE9BREVSIF9fTUFYX0VWQUxfQ09TVF9fLzQKKworcHJpdmF0ZSB2b2lkIGxvYWRfYXV0b19vYmplY3QoIHN0cmluZyBmaWxlLCBtaXhlZCBkYXRhICkKK3sKKyAgICBvYmplY3Qgb2I7CisgICAgc3RyaW5nIGVycm9yOworICAgCisgICAgaWYoIGdldF9ldmFsX2Nvc3QoKSA8IFNBRkVfRk9SX0FVVE9MT0FERVIgKSByZXR1cm47CisgICAgbV9kZWxldGUoIGF1dG9sb2FkX3Jlc3QsIGZpbGUgKTsKKyAgICBhdXRvbG9hZF9lcnJvci09KHtmaWxlfSk7CisKKyAgICBpZiAoIGZpbGUgPT0gIi9vYmovbW9uZXkiICkKKyAgICAgIGZpbGUgPSAiL2l0ZW1zL21vbmV5IjsKKyAgICBpZiAoIGZpbGUgPT0gIi9vYmovc2VlcmNhcmQiICkKKyAgICAgIGZpbGUgPSAiL2l0ZW1zL3NlZXJjYXJkIjsKKyAgICAKKyAgICBvYiA9IGZpbmRfb2JqZWN0KGZpbGUpOworICAgIAorICAgIGlmICghb2IpCisgICAgeworICAgICAgICBpZiAoZmlsZV9zaXplKGZpbGUrIi5jIik8MCYmCisgICAgICAgICAgIGZpbGVfc2l6ZShpbXBsb2RlKGV4cGxvZGUoZmlsZSwiLyIpWzAuLjwyXSwiLyIpKworICAgICAgICAgICAgICAgICAgICAgIi92aXJ0dWFsX2NvbXBpbGVyLmMiKTwwKQorICAgICAgICB7CisgICAgICAgICAgIGxvZ19hdXRvbG9hZChmaWxlLCJmaW5kIixkYXRhLDApOworICAgICAgICAgICByZXR1cm47CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVycm9yID0gY2F0Y2gobG9hZF9vYmplY3QoZmlsZSk7IHB1Ymxpc2gpKQorICAgICAgICB7CisgICAgICAgICAgIGxvZ19hdXRvbG9hZChmaWxlLCJsb2FkIixkYXRhLGVycm9yKTsKKyAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgfQorICAgIGlmICggZXJyb3IgPSBjYXRjaChvYiA9IGNsb25lX29iamVjdChmaWxlKTsgcHVibGlzaCkgKQorICAgIHsKKyAgICAgICAgbG9nX2F1dG9sb2FkKGZpbGUsImNsb25lIixkYXRhLCBlcnJvcik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoIGVycm9yID0gY2F0Y2gob2ItPlNldFByb3AoIFBfQVVUT0xPQURPQkosIGRhdGEgKTsgcHVibGlzaCkgKQorICAgIHsKKyAgICAgICAgbG9nX2F1dG9sb2FkKGZpbGUsIlNldFByb3AiLGRhdGEsIGVycm9yKTsKKyAgICAgICAgb2ItPnJlbW92ZSgxKTsKKyAgICAgICAgaWYgKG9iKSBkZXN0cnVjdChvYik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpZiAoIGVycm9yID0gY2F0Y2gob2ItPm1vdmUoIE1FLCBNX05PQ0hFQ0sgKTtwdWJsaXNoKSApIHsKKyAgICAgICAgbG9nX2F1dG9sb2FkKGZpbGUsIm1vdmUiLGRhdGEsIGVycm9yKTsKKyAgICAgICAgb2ItPnJlbW92ZSgxKTsKKyAgICAgICAgaWYob2IpIGRlc3RydWN0KG9iKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KK30KKworc3RhdGljIHZvaWQgbG9hZF9hdXRvX29iamVjdHMoIG1hcHBpbmcgbWFwX2xkZmllZCApCit7CisgICAgaWYgKCAoIW1hcHBpbmdwKG1hcF9sZGZpZWQpIHx8ICFzaXplb2YobWFwX2xkZmllZCkpICYmICFzaXplb2YoYXV0b2xvYWRfcmVzdCkgKQorICAgICAgICByZXR1cm47CisKKyAgICAvLyBNaXQgTmV0enRvdGVuIFNwaWVsZXJuIHJlY2huZW4gbWFuY2hlIEF1dG9sb2FkZXIgbmljaHQuIEFsc28KKyAgICAvLyBkYXMgQ2xvbmVuIHVudGVyYnJlY2hlbiB1bmQgaW4gUmVjb25uZWN0KCkgd2llZGVyIGFud2VyZmVuLgorICAgIGlmICggIWludGVyYWN0aXZlKCkgKQorICAgICAgICByZXR1cm47CisKKyAgICAvLyBLbGVpbmVyIEhhY2s6IGF1dG9sb2FkX3Jlc3QgaXN0IGVpbmUgZ2xvYmFsZSBWYXJpYWJsZSwgZGllIGJlaW0KKyAgICAvLyBDbG9uZW4gZGVyIGVpbnplbG5lbiBBdXRvbG9hZGVyIGRpcmVrdCB2ZXJhZW5kZXJ0IHdpcmQuCisgICAgLy8gU28gbGFuZ2UgZGFzIE1hcHBpbmcgbm9jaCBFaW50cmFlZ2UgaGF0LCBtdWVzc2VuIHdpciBub2NoIGZlaGxlbmRlCisgICAgLy8gQXV0b2xvYWRlciBjbG9uZW4uCisgICAgaWYgKCAhc2l6ZW9mKGF1dG9sb2FkX3Jlc3QpICkKKyAgICAgICAgYXV0b2xvYWRfcmVzdCA9IG1hcF9sZGZpZWQ7CisKKyAgICAvLyBTY2hvbiBoaWVyIGVpbmVuIGNhbGxfb3V0KCkgenVtICJOYWNoImNsb25lbiB2b24gbm9jaCBuaWNodCBnZWNsb250ZW4KKyAgICAvLyBBdXRvbG9hZGVybiBzdGFydGVuLCBkYSBzcGFldGVyIHUuVS4ga2VpbmUgUmVjaGVuemVpdCBtZWhyIGRhZnVlciBkYSBpc3QuCisgICAgd2hpbGUgKCByZW1vdmVfY2FsbF9vdXQoImxvYWRfYXV0b19vYmplY3RzIikgIT0gLTEgKQorICAgICAgICAvKiBkbyBub3RoaW5nICovOworICAgIAorICAgIC8vIE1pdCBQYXJhbWV0ZXIgJzAnIGF1ZnJ1ZmVuLCBkYSBkYXMgZ2xvYmFsZSBNYXBwaW5nIGJlbnV0enQgd2lyZC4KKyAgICAvLyBWZXJ6b2VnZXJ1bmcgMCBpbiByZWt1cnNpdmVuIENhbGxvdXRzIGlzdCBibG9lZCwgYWxzbyAxcyBEZWxheQorICAgIGNhbGxfb3V0KCAibG9hZF9hdXRvX29iamVjdHMiLCAyLCAwICk7CisgICAgCisgICAgLy8gTWl0IGNhdGNoKCkgZ2VnZW4gZGllIEV2YWxjb3N0LUZhbGxlIQorICAgIC8vIE1pdCBBYnNpY2h0IGRhcyB3YWxrX21hcHBpbmcoKSBhdXMgZGVyICJhbHRlbiIgVmVyc2lvbiBlcmhhbHRlbiB1bmQKKyAgICAvLyBuaWNodCBkdXJjaCBlaW5lIChlaW5mYWNoZXJlKSBTY2hsZWlmZSBpbmtsLiBnZXRfZXZhbF9jb3N0KCkgZXJzZXR6dCwKKyAgICAvLyBkYSBlaW5lIFNjaGxlaWZlIGdlZ2VudWViZXIgZGVyIHdhbGtfbWFwcGluZygpLUxvZXN1bmcgZGVuIEF1ZmJhdQorICAgIC8vIGRlciBwcmV2aW91c19vYmplY3QoKS1LZXR0ZSB2ZXJhZW5kZXJuIHd1ZXJkZTsgZGFyYXVmIHRlc3RlbiBhYmVyCisgICAgLy8gbWFuY2hlIE9iamVrdGUuCisgICAgY2F0Y2goIHdhbGtfbWFwcGluZyggYXV0b2xvYWRfcmVzdCwgIydsb2FkX2F1dG9fb2JqZWN0LyonKi8gKSApOworfQorCisvKgorICogYWxfdG9fdGl0bGU6IE1ha2UgdGhlIG51bWVyaWMgYWxpZ25tZW50IHZhbHVlIGludG8gYSBzdHJpbmcKKyAqLworc3RhdGljIHN0cmluZyBhbF90b190aXRsZShpbnQgYSkKK3sKKyAgaWYgKGEgPj0gS0lMTF9ORVVUUkFMX0FMSUdOTUVOVCAqIDEwMCkKKyAgICByZXR1cm4gImhlaWxpZyI7CisgIGlmIChhID4gS0lMTF9ORVVUUkFMX0FMSUdOTUVOVCAqIDIwKQorICAgIHJldHVybiAiZ3V0IjsKKyAgaWYgKGEgPiBLSUxMX05FVVRSQUxfQUxJR05NRU5UICogNCkKKyAgICByZXR1cm4gIm5ldHQiOworICBpZiAoYSA+IC0gS0lMTF9ORVVUUkFMX0FMSUdOTUVOVCAqIDQpCisgICAgcmV0dXJuICJuZXV0cmFsIjsKKyAgaWYgKGEgPiAtIEtJTExfTkVVVFJBTF9BTElHTk1FTlQgKiAyMCkKKyAgICByZXR1cm4gImZyZWNoIjsKKyAgaWYgKGEgPiAtIEtJTExfTkVVVFJBTF9BTElHTk1FTlQgKiAxMDApCisgICAgcmV0dXJuICJib2VzZSI7CisgIHJldHVybiAic2F0YW5pc2NoIjsKK30KKworc3RhdGljIGludCB0b2dnbGVfd2hpbXB5X2RpcihzdHJpbmcgc3RyKSB7CisgIFNldFByb3AoUF9XSU1QWV9ESVJFQ1RJT04sc3RyPV91bnBhcnNlZF9hcmdzKCl8fHN0cik7CisgIGlmIChzdHIpCisgICAgcHJpbnRmKCJPaywgRmx1Y2h0cmljaHR1bmcgJU8uXG4iLHN0cik7CisgIGVsc2UKKyAgICBwcmludGYoIk9rLCBiZXZvcnp1Z3RlIEZsdWNodHJpY2h0dW5nIGRlYWt0aXZpZXJ0LlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IHRvZ2dsZV93aGltcHkoc3RyaW5nIHN0cikKK3sKKyAgaW50IGk7CisKKyAgaWYoIXN0ciB8fCBzdHI9PSIiIHx8IChzc2NhbmYoc3RyLCIlZCIsaSk8MCkpCisgIHsKKyAgICB3cml0ZSgidm9yc2ljaHQgPGhwPiwgMDw9aHA8IitRdWVyeVByb3AoUF9NQVhfSFApKyJcbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmKGk+PVF1ZXJ5UHJvcChQX01BWF9IUCkgfHwgaTwwKQorICB7CisgICAgd3JpdGUoIkRlciBXZXJ0IGlzdCBuaWNodCBlcmxhdWJ0LlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYoIWkpIHdyaXRlKCJQcmlueiBFaXNlbmhlcnotTW9kdXMuXG4iKTsKKyAgZWxzZSB3cml0ZSgiVm9yc2ljaHQtTW9kdXMgKCIraSsiKVxuIik7CisgIFNldFByb3AoUF9XSU1QWSxpKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8qKiBCZXN0aW1tdCwgb2IgZGFzIFNwaWVsZXJvYmpla3QgYmVzY2hhdHRldCB3ZXJkZW4gZGFyZi4KKyAgKiBCZXNjaGF0dGVuIGlzdCBudXIgZnVlciBPYmpla3RlIGVybGF1YnQsIGRpZSBpbiAvc3RkL3BsYXllci9zaGFkb3dzCisgICogYWJnZWxlZ3Qgc2luZC4KKyAgKiBBdXNuYWhtZTogVGVzdHNwaWVsZXIgbWl0IGdlc2V0enRlbSBQX0FMTE9XRURfU0hBRE9XCisgICogQHBhcmFtW2luXSBvYmogT2JqZWt0LCB3YXMgYmVzY2hhdHRlbiBtb2VjaHRlLgorICAqIEByZXR1cm4gMCwgd2VubiBCZXNjaGF0dGVuIGVybGF1YnQsIDEgc29uc3QuCisgICovCit2YXJhcmdzIG5vbWFzayBpbnQgcXVlcnlfcHJldmVudF9zaGFkb3cob2JqZWN0IG9iaikKK3sKKyAgc3RyaW5nIHdoYXQsIGFsbG93ZWRfc2hhZG93OworICBpbnQgICAgZHVtbXk7CisKKy8vICBpZiAoIFF1ZXJ5KFBfVEVTVFBMQVlFUikgKQorLy8gICAgICByZXR1cm4gMDsKKyAgCisgIGlmIChvYmopeworICAgIHdoYXQ9b2JqZWN0X25hbWUob2JqKTsKKyAgICBpZiAod2hhdCAmJiB3aGF0ICE9ICIiICYmCisgICAgICAgIHNzY2FuZih3aGF0LCIvc3RkL3BsYXllci9zaGFkb3dzLyVzIyVkIix3aGF0LGR1bW15KT09MikKKyAgICAgIHJldHVybiAwOworICAgIAorICAgIC8vIEVpbmVtIFRlc3RzcGllbGVyIGthbm4gbWFuIFBfQUxMT1dFRF9TSEFET1cgYXVmIGVpbmVuIHp1IHRlc3RlbmRlbgorICAgIC8vIFNoYWRvdyBzZXR6ZW4uCisgICAgaWYgKCBRdWVyeShQX1RFU1RQTEFZRVIpICYmIAorICAgICAgICAgc3RyaW5ncCh3aGF0KSAmJiAKKyAgICAgICAgIHN0cmluZ3AoYWxsb3dlZF9zaGFkb3c9UXVlcnkoUF9BTExPV0VEX1NIQURPVykpICYmCisgICAgICAgICBzdHJzdHIod2hhdCwgYWxsb3dlZF9zaGFkb3cpPT0wKQorICAgICAgICAgICAgcmV0dXJuIDA7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgdWhyemVpdCgpCit7CisgIHdyaXRlKGR0aW1lKHRpbWUoKStRdWVyeVByb3AoUF9USU1FWk9ORSkqMzYwMCkrIi5cbiIpOworICByZXR1cm4gMTsKK30KKworcHJvdGVjdGVkIHN0cmluZyBTZXREZWZhdWx0SG9tZShzdHJpbmcgc3RyKQoreworICByZXR1cm4gZGVmYXVsdF9ob21lPXN0cjsKK30KKworc3RyaW5nIFF1ZXJ5RGVmYXVsdEhvbWUoKQoreworICByZXR1cm4gZGVmYXVsdF9ob21lOworfQorCitwcm90ZWN0ZWQgc3RyaW5nIFNldERlZmF1bHRQcmF5Um9vbShzdHJpbmcgc3RyKQoreworICBpZihoY19wbGF5PjEpCisgIHsKKyAgICBkZWZhdWx0X3ByYXlfcm9vbT0iL3Jvb20vbmlydmFuYSI7CisgIH0KKyAgZWxzZQorICAgIGRlZmF1bHRfcHJheV9yb29tPXN0cjsKKyAgCisgIHJldHVybiBkZWZhdWx0X3ByYXlfcm9vbTsKK30KKworc3RyaW5nIFF1ZXJ5UHJheVJvb20oKQoreworICBpZihoY19wbGF5PjEpCisgIHsKKyAgICByZXR1cm4gIi9yb29tL25pcnZhbmEiOworICB9IAorICBzdHJpbmcgcm9vbSA9IFF1ZXJ5UHJvcChQX1BSQVlfUk9PTSk7CisgIGlmIChzdHJpbmdwKHJvb20pKQorICAgIHJldHVybiByb29tOworICBlbHNlIGlmIChkZWZhdWx0X3ByYXlfcm9vbSkKKyAgICByZXR1cm4gZGVmYXVsdF9wcmF5X3Jvb207CisgIC8vIGhvZmZlbnRsaWNoIGlzdCBkYXMgd2VuaWdzdGVucyBnZXNldHp0LiAKKyAgcmV0dXJuIGRlZmF1bHRfaG9tZTsKK30KKwordm9pZCBfcmVzdGFydF9iZWF0KCkKK3sKKyAgdGVsbF9vYmplY3QoTUUsCisgICAgICAiRGVyIEdhbWVEcml2ZXIgdGVpbHQgRGlyIG1pdDogRGVpbiBIZXJ6c2NobGFnIGhhdCB3aWVkZXIgZWluZ2VzZXR6dC5cbiIpOworICBzZXRfaGVhcnRfYmVhdCgxKTsKK30KKworc3RhdGljIGludCB3ZWcoc3RyaW5nIHN0cikKK3sKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpKQorICB7CisgICAgcHJpbnRmKCJEdSBiaXN0IG5pY2h0JXMgYWxzIGFid2VzZW5kIGdla2VubnplaWNobmV0LlxuIiwKKyAgICAgICAgICAgUXVlcnlQcm9wKFBfQVdBWSkgPyAiIG1laHIiIDogIiIpOworICAgIFNldFByb3AoUF9BV0FZLCAwKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICB3cml0ZSgiRHUgYmlzdCBqZXR6dCBhbHMgYWJ3ZXNlbmQgZ2VrZW5uemVpY2huZXQuXG4iKTsKKyAgU2V0UHJvcChQX0FXQVksIHN0cik7CisgIHJldHVybiAxOworfQorCisvKiBFaW4gQmVmZWhsIHp1bSBhbnNjaGF1ZW4gZGVyIFdlZ21lbGR1bmcgYW5kZXJlciBTcGllbGVyICovCitzdGF0aWMgaW50IHdlZ21lbGR1bmcoc3RyaW5nIHBsYXllcikKK3sKKworICBvYmplY3QgcGxheWVyX29iOworICBzdHJpbmcgd2VnOworCisgIGlmICggIXBsYXllciB8fCBwbGF5ZXI9PSIiIHx8IAorICAgICAgIHBsYXllcj09bG93ZXJzdHJpbmcodGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfTkFNRSkpKQorICB7CisgICAgd2VnPXRoaXNfcGxheWVyKCktPlF1ZXJ5UHJvcChQX0FXQVkpOworICAgIHdyaXRlICgiRHUgYmlzdCAiKyh3ZWc/IiI6Im5pY2h0ICIpKyJhbHMgYWJ3ZXNlbmQgZ2VrZW5uemVpY2huZXQuXG4iKTsKKyAgICBpZiAod2VnKQorICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKHdlZywgNzgsIkdydW5kOiAiLEJTX0lOREVOVF9PTkNFKSk7CisgICAgcmV0dXJuIDE7ICAKKyAgfQorCisgIC8vIFdlbGNoZXIgU3BpZWxlciBpc3QgZ2VtZWludD8KKyAgcGxheWVyX29iPWZpbmRfcGxheWVyKHBsYXllcik7CisKKyAgLy8gU3BpZWxlciBuaWNodCBkYSBvZGVyIEludmlzIHVuZCBBbmZyYWdlciBpcyBrZWluIE1hZ2llcgorICBpZiAoIXBsYXllcl9vYiB8fCAKKyAgICAgIChwbGF5ZXJfb2ItPlF1ZXJ5UHJvcChQX0lOVklTKSAmJiAhSVNfTEVBUk5FUih0aGlzX3BsYXllcigpKSkpIAorICB7CisgICAgd3JpdGUoY2FwaXRhbGl6ZShwbGF5ZXIpKyIgaXN0IGdlcmFkZSBuaWNodCBpbSBTcGllbC5cbiIpOworICAgIHJldHVybiAxOworICB9CisKKyAgd2VnPXBsYXllcl9vYi0+UXVlcnlQcm9wKFBfQVdBWSk7CisKKyAgICAgICAgLy8gcGxheWVyX29iLT5OYW1lKCkgZ2lidCBiZWkgaW52aXMtTWFnaWVybiAiSmVtYW5kIiB6dXJ1ZWNrCisgIHdyaXRlIChwbGF5ZXJfb2ItPlF1ZXJ5UHJvcChQX05BTUUpKyIgaXN0ICIrCisgICAgICAgICAod2VnPyIiOiJuaWNodCAiKSsiYWxzIGFid2VzZW5kIGdla2VubnplaWNobmV0LlxuIik7CisKKyAgaWYgKHdlZykKKyAgICB3cml0ZShicmVha19zdHJpbmcod2VnLCA3OCwiR3J1bmQ6ICIsQlNfSU5ERU5UX09OQ0UpKTsKKworICByZXR1cm4gMTsKK30KKworc3RhdGljIHN0cmluZyB0aW1lZGlmZihpbnQgdGltZSkKK3sKKyAgc3RyaW5nIHJldDsKKworICByZXQ9IiI7CisgIGlmKHRpbWU+PTg2NDAwKSB7CisgICAgcmV0Kz10aW1lLzg2NDAwKyJkICI7CisgICAgdGltZSU9ODY0MDA7CisgIH0KKyAgaWYodGltZTwzNjAwMCkgcmV0Kz0iMCI7CisgIHJldCs9dGltZS8zNjAwKyI6IjsKKyAgdGltZSU9MzYwMDsKKyAgaWYodGltZTw2MDApIHJldCs9IjAiOworICByZXQrPXRpbWUvNjArIjoiOworICB0aW1lJT02MDsKKyAgaWYodGltZTwxMCkgcmV0Kz0iMCI7CisgIHJldCs9dGltZSsiIjsKKyAgcmV0dXJuIHJldDsKK30KKworCisvKiBFaW4gQmVmZWhsIHp1bSBhbnNjaGF1ZW4gZGVyIElkbGV6ZWl0IGFuZGVyZXIgU3BpZWxlciAqLworc3RhdGljIGludCBpZGxlemVpdChzdHJpbmcgcGxheWVyKQoreworCisgIG9iamVjdCBwbGF5ZXJfb2I7CisgIGludCBpZGxlOworCisgIGlmICggIXBsYXllciB8fCBwbGF5ZXI9PSIiIHx8IAorICAgICAgIHBsYXllcj09bG93ZXJzdHJpbmcodGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfTkFNRSkpKQorICB7CisgICAgd3JpdGUgKCJEdSBiaXN0IHNlbGJlciBuYXR1ZXJsaWNoIGdlcmFkZSBuaWNodCBpZGxlLlxuIik7CisgICAgcmV0dXJuIDE7ICAKKyAgfQorCisgIC8vIFdlbGNoZXIgU3BpZWxlciBpc3QgZ2VtZWludD8KKyAgcGxheWVyX29iPWZpbmRfcGxheWVyKHBsYXllcik7CisKKyAgLy8gU3BpZWxlciBuaWNodCBkYSBvZGVyIEludmlzIHVuZCBBbmZyYWdlciBpcyBrZWluIE1hZ2llcgorICBpZiAoIXBsYXllcl9vYiB8fCAKKyAgICAgIChwbGF5ZXJfb2ItPlF1ZXJ5UHJvcChQX0lOVklTKSAmJiAhSVNfTEVBUk5FUih0aGlzX3BsYXllcigpKSkpIAorICB7CisgICAgd3JpdGUoY2FwaXRhbGl6ZShwbGF5ZXIpKyIgaXN0IGdlcmFkZSBuaWNodCBpbSBTcGllbC5cbiIpOworICAgIHJldHVybiAxOworICB9CisKKyAgaWRsZT1xdWVyeV9pZGxlKHBsYXllcl9vYik7CisKKyAgICAgICAgLy8gcGxheWVyX29iLT5OYW1lKCkgZ2lidCBiZWkgaW52aXMtTWFnaWVybiAiSmVtYW5kIiB6dXJ1ZWNrCisgIHdyaXRlIChwbGF5ZXJfb2ItPlF1ZXJ5UHJvcChQX05BTUUpKyIgaXN0ICIrCisgICAgICAgICAoaWRsZT49NjA/dGltZWRpZmYoaWRsZSk6Im5pY2h0IikrIiBwYXNzaXYuXG4iKTsKKworICByZXR1cm4gMTsKK30KKworCisvKiogQmVsZWJ0IGVpbmVuIG5ldHp0b3RlbiBTcGllbGVyIHdpZWRlci4KKyAgKiBSZWFrdGl2aWVydCBIZWFydGJlYXRzLCBiZXdlZ3QgZGVuIFNwaWVsZXIgenVydWVjayBhbiBkZW4gT3J0LCBkZXIgZWltCisgICogRWluc2NobGFmZW4genVtIEF1ZndhY2hlbiBlcm1pdHRlbHQgd3VyZGUgKGltIGVpbmZhY2hzdGVuIEZhbGwgZGVyIFJhdW0sCisgICogd28gbWFuIGVpbmdlc2NobGFmZW4gaXN0KS4KKyAgKi8KK3N0YXRpYyB2b2lkIG5kZWFkX3Jldml2ZSgpCit7CisgICAgc3RyaW5nIGZuYW1lOworICAgIGludCByZXQ7CisKKyAgICBzZXRfaGVhcnRfYmVhdCgxKTsKKyAgICBuZGVhZF9uZXh0X2NoZWNrID0gTkVUREVBRF9DSEVDS19USU1FOworICAgIG5kZWFkX2N1cnJlbnRseSA9IDA7CisgICAgbmRlYWRfbGFzdHRpbWUgPSAwOworCisgICAgaWYgKCAhb2JqZWN0cChuZGVhZF9sb2NhdGlvbikgJiYgCisgICAgICAgICBzdHJpbmdwKG5kZWFkX2xfZmlsZW5hbWUpICYmIHNpemVvZihuZGVhZF9sX2ZpbGVuYW1lKSkgeworICAgICAgICAKKyAgICAgICAgaWYgKCBtZW1iZXIoIG5kZWFkX2xfZmlsZW5hbWUsICcjJyApID09IC0xICl7CisgICAgICAgICAgICBjYXRjaChsb2FkX29iamVjdCggbmRlYWRfbF9maWxlbmFtZSk7IHB1Ymxpc2gpOworICAgICAgICAgICAgbmRlYWRfbG9jYXRpb24gPSBmaW5kX29iamVjdChuZGVhZF9sX2ZpbGVuYW1lKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIG5kZWFkX2xvY2F0aW9uID0gZmluZF9vYmplY3QobmRlYWRfbF9maWxlbmFtZSk7CisgICAgICAgICAgICBpZiAoICFuZGVhZF9sb2NhdGlvbiAmJiBlbnZfbmRlYWRfaW5mbyApeworICAgICAgICAgICAgICAgIGZuYW1lID0gZXhwbG9kZSggbmRlYWRfbF9maWxlbmFtZSwgIiMiIClbMF07CisgICAgICAgICAgICAgICAgY2F0Y2gobmRlYWRfbG9jYXRpb24gPSAKKyAgICAgICAgICAgICAgICAgICAgKGxvYWRfb2JqZWN0KGZuYW1lKS0+U2V0UHJvcChQX05FVERFQURfSU5GTywgZW52X25kZWFkX2luZm8pKTsKKyAgICAgICAgICAgICAgICAgICAgcHVibGlzaCk7CisgICAgICAgICAgICAgICAgaWYgKCAhb2JqZWN0cChuZGVhZF9sb2NhdGlvbikgKXsKKyAgICAgICAgICAgICAgICAgICAgY2F0Y2gobG9hZF9vYmplY3QoIG5kZWFkX2xvY2F0aW9uKTtwdWJsaXNoKTsKKyAgICAgICAgICAgICAgICAgICAgbmRlYWRfbG9jYXRpb24gPSBmaW5kX29iamVjdChuZGVhZF9sb2NhdGlvbik7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgaWYgKCAhb2JqZWN0cChuZGVhZF9sb2NhdGlvbikKKyAgICAgICAgfHwgY2F0Y2gocmV0ID0gbW92ZSggbmRlYWRfbG9jYXRpb24sIE1fR098TV9TSUxFTlQgKTtwdWJsaXNoKSAKKyAgICAgICAgfHwgcmV0ICE9IDEgKSB7CisgICAgICAgIG1vdmUoICJnaWxkZW4vYWJlbnRldXJlciIsIE1fR098TV9TSUxFTlQgKTsKKyAgICAgICAgbmRlYWRfbG9jYXRpb24gPSBlbnZpcm9ubWVudCgpOworICAgIH0KKworICAgIC8vICBuZGVhZF9sb2NhdGlvbj0wOworICAgIG5kZWFkX2xfZmlsZW5hbWUgPSAwOworICAgIGVudl9uZGVhZF9pbmZvID0gMDsKK30KKworLyoqIEJld2VndCBlaW5lbiBuZXR6dG90ZW4gU3BpZWxlciBpbiBkZW4gTmV0enRvdGVucmF1bQorICAqIEdlcnVmZW4gdm9uIGhlYXJ0YmVhdCgpLgorICAqIFplcnN0b2VydCBHYWVzdGUsIHZlcmxhZXNzdCBnZ2YuIGRhcyBUZWFtLCBlcm1pdHRlbHQsIG9iIGRlciBTcGllbGVyIGJlaW0KKyAgKiBBdWZ3YWNoZW4gaW4gZGFzIGFsdGUgRW52aXJvbm1lbnQgYmV3ZWd0IHdlcmRlbiBzb2xsIG9kZXIgaW4gZWluZW4gYW5kZXJlbgorICAqIFJhdW0sIGhpZXJ6dSB3aXJkIGltIEVudmlyb25tZW50IFBfTkVUREVBRF9JTkZPIGFiZ2VmcmFndC4KKyAgKiBEZWFrdGl2aWVydCBkaWUgS29tbWFuZG9zIHBlciBkaXNhYmxlX2NvbW1hbmRzKCkuCisgICovCitzdGF0aWMgdm9pZCBuZGVhZF9tb3ZlX21lKCkgeworICBvYmplY3QgdGVhbTsKKyAgbWl4ZWQgYW1lbTsKKworICBzZXRfaGVhcnRfYmVhdCgwKTsKKyAgc3RvcF9oZWFydF9iZWF0cygpOworICBpZiAoUXVlcnlHdWVzdCgpKSB7CisgICAgcXVpdCgpOworICAgIGlmIChNRSkKKyAgICAgIHJlbW92ZSgpOworICAgIGlmIChNRSkKKyAgICAgIGRlc3RydWN0KE1FKTsKKyAgICByZXR1cm47CisgIH0KKyAgbmRlYWRfbmV4dF9jaGVjaz1ORVRERUFEX0NIRUNLX1RJTUU7CisgIG5kZWFkX2N1cnJlbnRseT0xOworICBuZGVhZF9sYXN0dGltZT0wOworICBuZGVhZF9sb2NhdGlvbj1lbnZpcm9ubWVudCgpOworICBpZiAob2JqZWN0cChuZGVhZF9sb2NhdGlvbikpCisgICAgbmRlYWRfbF9maWxlbmFtZT1vYmplY3RfbmFtZShuZGVhZF9sb2NhdGlvbik7CisgIAorICBpZiAob2JqZWN0cChlbnZpcm9ubWVudCgpKQorICAgICAgJiYgc2l6ZW9mKGV4cGxvZGUob2JqZWN0X25hbWUoZW52aXJvbm1lbnQoKSksIiMiKSkgPiAxKQorICAgIGVudl9uZGVhZF9pbmZvPWVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX05FVERFQURfSU5GTyk7CisgIGVsc2UKKyAgICBlbnZfbmRlYWRfaW5mbz0wOworICAKKyAgaWYgKCBvYmplY3RwKHRlYW09UXVlcnkoUF9URUFNKSkgKQorICAgICAgLy8gRGVyIFRlc3QgYXVmIGFzc296aWllcnRlIFRlYW1taXRnbGllZGVyICg9PSBGb2xnZU5QQ3MpCisgICAgICAvLyB2ZXJoaW5kZXJ0LCBkYXNzIFNwaWVsZXIgbmFjaCAic2NobGFmZSBlaW4iIGF1cyBkZW0KKyAgICAgIC8vIFRlYW0gYXVzZ2V0cmFnZW4gd2VyZGVuLiAtLSAyOS4wMS4yMDAyIFRpYW1haworICAgICAgLy8gICAgICAmJiAhb2JqZWN0cChhbWVtPVF1ZXJ5KFBfVEVBTV9BU1NPQ19NRU1CRVJTKSkKKyAgICAgIC8vICAgICAgJiYgIShwb2ludGVycChhbWVtKSAmJiBzaXplb2YoYW1lbSkpKQorICAgIHRlYW0tPlJlbW92ZU1lbWJlcihNRSk7CisgIAorICBkaXNhYmxlX2NvbW1hbmRzKCk7CisgIG1vdmUoTkVUREVBRF9ST09NLE1fR098TV9OT19BVFRBQ0t8TV9OT0NIRUNLLCJpbnMgUmVpY2ggZGVyIE5ldHp0b3RlbiIpOworfQorCisvKiogSXN0IGRpZXNlciBDaGFyYWN0ZXIgZWluIEdhc3Q/CisgICogQHJldHVybiAxLCB3ZW5uIEdhc3QsIDAgc29uc3QuCisgICovCitpbnQgUXVlcnlHdWVzdCgpCit7CisgIHN0cmluZyBkdW1teTsKKyAgcmV0dXJuIHNzY2FuZihnZXR1aWQoKSwiZ2FzdCVkIixkdW1teSk7Cit9CisKKy8qKiBTcGllbGVya29tbWFuZG8gJ3NjaGxhZmUgZWluJy4KKyAgKiBSdWZ0IHJlbW92ZV9pbnRlcmFjdGl2ZSgpIGJlaSBTcGllbGVybiwgYmVpIE1hZ2llcm4gd2lyZCBxdWl0KCkgZ2VydWZlbiwKKyAgKiB1bSBkYXMgTWFnaWVyb2JqZWt0IHp1IHplcnN0b2VyZW4uCisgICogQHNhIHF1aXQoKQorICAqLworaW50IGRpc2Nvbm5lY3Qoc3RyaW5nIHN0cikKK3sgCisgIHN0cmluZyB2ZXJiOworICBzdHJpbmcgZGVzYyA9IGJyZWFrX3N0cmluZygKKyAgICAgICJcInNjaGxhZmUgZWluXCIgYmVlbmRldCBEZWluZSBWZXJiaW5kdW5nIG1pdCAiTVVETkFNRSIuIER1IGJlaGFlbHRzdCAiCisgICAgICJEZWluZSBTYWNoZW4uXG5GYWxscyAiTVVETkFNRSIgamVkb2NoIGFic3R1ZXJ6dCBvZGVyIG5ldSBnZXN0YXJ0ZXQgIgorICAgICAid2lyZCwgd2FlaHJlbmQgRHUgd2VnIGJpc3QsIHZlcmxpZXJzdCBEdSBkaWUgbWVpc3RlbiBhbGxlcmRpbmdzICIKKyAgICAgIihnZW5hdXNvLCBhbHMgd2VubiBEdSBEZWluZSBWZXJiaW5kdW5nIG1pdCBcImVuZGVcIiBiZWVuZGV0IGhhZXR0ZXN0KS4gIgorICAgICAiSW4gZGllc2VtIEZhbGwgYmVrb21tc3QgRHUgZGFubiBlaW5lIGtsZWluZSBFbnRzY2hhZWRpZ3VuZy4iCisgICAgICw3OCwwLEJTX0xFQVZFX01ZX0xGUyk7CisKKyAgdmVyYj1xdWVyeV92ZXJiKCk7CisgIGlmICghdmVyYikKKyAgICB2ZXJiPSJBVVRPQ0FMTCI7CisgIGlmICh2ZXJiWzAuLjVdPT0ic2NobGFmIiAmJiBzdHIhPSJlaW4iKQorICB7CisgICAgbm90aWZ5X2ZhaWwoZGVzYyk7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKElTX0xFQVJORVIodGhpc19vYmplY3QoKSkpCisgICAgcmV0dXJuIHF1aXQoKTsKKyAgCisgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksIGRlc2MpOworCisgIGlmIChjbG9uZXAoZW52aXJvbm1lbnQoKSkgJiYgIWVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX05FVERFQURfSU5GTykpCisgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxicmVha19zdHJpbmcoCisgICAgICAgICJcbkFDSFRVTkc6IFdlbm4gRHUgaGllciBsYWVuZ2VyZSBaZWl0IHNjaGxhZWZzdCwgIgorICAgICAgICAia29tbXN0IER1IHZlcm11dGxpY2ggbmljaHQgYW4gZGllc2VuIE9ydCB6dXJ1ZWNrISIsNzgpKTsKKworICBzYXkoY2FwaXRhbGl6ZShuYW1lKFdFUikpKyIgaGF0IGdlcmFkZSBkaWUgVmVyYmluZHVuZyB6dSAiTVVETkFNRSIgZ2VrYXBwdC5cbiIpOworICByZW1vdmVfaW50ZXJhY3RpdmUoTUUpOworICBjYWxsX291dCgjJ2NsZWFyX3RlbGxfaGlzdG9yeSw0KTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgZmluZ2VyIChzdHJpbmcgc3RyKQoreworICBzdHJpbmcgcmV0OworICBtaXhlZCB4bmFtZTsKKworICBpZiAoIXN0ciB8fCBzdHI9PSIiCisgICAgICB8fCBzaXplb2YoZXhwbG9kZShzdHIsIiAiKS0oeyItbiIsIi1wIiwiLXMiLCItdiIsIi1hIn0pKT4xKQorICB7CisgICAgd3JpdGUoImZpbmdlciA8c3BpZWxlcm5hbWU+IG9kZXIgZmluZ2VyIDxzcGllbGVybmFtZUBtdWRuYW1lPlxuIisKKyAgICAgICJCaXR0ZSBudXIgZGVuIHJlaW5lbiBTcGllbGVybmFtZW4gdmVyd2VuZGVuLCBrZWluZSBOYW1lbnN2b3JzYWV0emUgb2RlciBUaXRlbFxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgeG5hbWU9ZXhwbG9kZShzdHIsIkAiKTsKKyAgaWYoc2l6ZW9mKHhuYW1lKT09MikKKyAgeworICAgIGlmICh4bmFtZVswXT09Ii1uICIgfHwgeG5hbWVbMF09PSItcCAiIHx8IHhuYW1lWzBdPT0iLXMgIikgIHsKKyAgICAgIHdyaXRlKCJmaW5nZXIgPHNwaWVsZXJuYW1lPkA8bXVkbmFtZT4gLSBkZXIgU3BpZWxlcm5hbWUgZmVobHQuXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBpZiAocmV0PUlORVRELT5fc2VuZF91ZHAoeG5hbWVbMV0sKFsKKyAgICAgICAgICAgICAgICAgICBSRVFVRVNUOiAiZmluZ2VyIiwKKyAgICAgICAgICAgICAgICAgICBTRU5ERVI6IGdldHVpZChNRSksCisgICAgICAgICAgICAgICAgICAgREFUQTogKGV4cGxvZGUoeG5hbWVbMF0sIiAiKS0oeyItbiIsIi1wIiwiLXMifSkpWzBdCisgICAgICAgICAgICAgICAgICAgXSksIDEpKQorICAgICAgICAgICAgd3JpdGUocmV0KTsKKyAgICAgICAgZWxzZQorICAgICAgd3JpdGUoIkFuZnJhZ2UgYWJnZXNjaGlja3QuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICAiL3AvZGFlbW9uL2ZpbmdlciItPmZpbmdlcl9zaW5nbGUoc3RyLDEpOworICByZXR1cm4gMTsKK30KKworc3RyaW5nIGxhbGlnbihzdHJpbmcgc3RyLCBpbnQgd2lkKQoreworICByZXR1cm4gKHN0cisiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIisKKyAgICAgICIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKVswLi53aWQtMV07Cit9CisKKyNkZWZpbmUgTVVEU19CQVIgIlwKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0iCisKK3ByaXZhdGUgdm9pZCBmb3JtYXQobWl4ZWQgbXVkLCBtaXhlZCBob3N0cywgc3RyaW5nIG91dHB1dCkKK3sKKyAgb3V0cHV0ICs9IGxhbGlnbihob3N0c1ttdWRdW0hPU1RfTkFNRV0sIDIwKSArICIgICIgKworICAgICAgICAoaG9zdHNbbXVkXVtIT1NUX1NUQVRVU10gPworICAgICAgICAgICBob3N0c1ttdWRdW0hPU1RfU1RBVFVTXSA+IDAgPworICAgICAgICAgICAgICJVUCAgICAgICAiICsgY3RpbWUoaG9zdHNbbXVkXVtIT1NUX1NUQVRVU10pWzQuLjE1XSA6CisgICAgICAgICAgICAgIkRPV04gICAgICIgKyBjdGltZSgtaG9zdHNbbXVkXVtIT1NUX1NUQVRVU10pWzQuLjE1XQorICAgICAgICAgOiAiVU5LTk9XTiAgTmV2ZXIgYWNjZXNzZWQuIikgKyAiXG4iOworfQorCitzdGF0aWMgaW50IG11ZHMoKSB7CisgIG1hcHBpbmcgaG9zdHM7CisgIGludCBpOworICBtaXhlZCBtdWRzLCBvdXRwdXQ7CisKKyAgb3V0cHV0ID0gbGFsaWduKCJNdWRuYW1lIiwgMjApICsgIiAgU3RhdHVzICAgTGFzdCBhY2Nlc3MiOworICBvdXRwdXQgKz0gIlxuIiArIE1VRFNfQkFSWzAuLnNpemVvZihvdXRwdXQpXSArICJcbiI7CisgIG11ZHMgPSBzb3J0X2FycmF5KG1faW5kaWNlcyhob3N0cyA9IElORVRELT5xdWVyeSgiaG9zdHMiKSksIyc+KTsKKyAgbWFwKG11ZHMsICMnZm9ybWF0LCBob3N0cywgJm91dHB1dCk7CisgIE1vcmUob3V0cHV0KTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vICoqKiogbG9jYWwgcHJvcGVydHkgbWV0aG9kcworc3RhdGljIGludCBfc2V0X2xldmVsKGludCBpKQoreworICBpZiAoIWludHAoaSkpIHJldHVybiAtMTsKKyAgaWYgKGk8MSkgcmV0dXJuIC0xOworICBTZXQoUF9MRVZFTCwgaSk7CisgIEdNQ1BfQ2hhciggKFtQX0xFVkVMOiBpXSkgKTsKKyAgcmV0dXJuIGk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9pbnZpcyhpbnQgYSkKK3sKKyAgcmV0dXJuIFNldChQX0lOVklTLCBpbnRwKGEpID8gYSA6ICFRdWVyeShQX0lOVklTKSk7Cit9CisKKy8qIHNldHMgdGhlIHRlcm1pbmFsIHR5cGUgKi8KKy8qIG5vdGU6IHN1cHBvcnQgdnQxMDAgKGIvdyksIGFuc2kgKGNvbG9yKSwgZHVtYiAobm9uZSkgKi8KK3N0YXRpYyBzdHJpbmcgX3NldF90dHkoc3RyaW5nIHN0cikgeworICBpZihzdHIgIT0gImR1bWIiICYmIHN0ciAhPSAidnQxMDAiICYmIHN0ciAhPSAiYW5zaSIpCisgICAgcmV0dXJuIFF1ZXJ5KFBfVFRZKTsKKyAgcmV0dXJuIFNldChQX1RUWSwgc3RyKTsKK30KKworc3RhdGljIGludCBzdHR5KHN0cmluZyBzdHIpCit7CisgIGlmKHN0ciE9ImR1bWIiJiZzdHIhPSJ2dDEwMCImJnN0ciE9ImFuc2kiJiZzdHIhPSJyZXNldCIpCisgIHsKKyAgICB3cml0ZSgiS29tbWFuZG86IHN0dHkgZHVtYnx2dDEwMHxhbnNpIG9kZXIgcmVzZXRcbiIpOworICB9CisgIGlmKHN0ciA9PSAicmVzZXQiKSB7CisgICAgICBwcmludGYoIhtbMzA7NDdtG1swbURpZXNlciBUZXh0IHNvbGx0ZSBsZXNiYXIgc2VpbiFcbiIpOworICAgICAgcmV0dXJuIDE7CisgIH0KKworICB3cml0ZSgiVFRZIHN0ZWh0IGpldHp0IGF1ZiAiK1NldFByb3AoUF9UVFksc3RyKSsiLlxuIik7CisgIGlmKHN0ciA9PSAiYW5zaSIgfHwgc3RyID09ICJ2dDEwMCIpIHsKKyAgICAgIHByaW50ZigiVGVybWluYWwgVGVzdDpcbiIpOworICAgICAgcHJpbnRmKCJWVDEwMDogG1sxbWZldHQbWzBtIBtbNG11bnRlcnN0cmljaGVuG1swbSAiKworICAgICAgICAgICAgICIbWzVtYmxpbmtlbmQbWzBtIBtbN21pbnZlcnMbWzBtXG4iKTsKKyAgICAgIGlmKHN0ciA9PSAiYW5zaSIpIHsKKyAgICAgICAgICBwcmludGYoIkFOU0kgRmFyYmVuIHVuZCBWVDEwMCBBdHRyaWJ1dGU6XG4iKTsKKyAgICAgICAgICBmb3JlYWNoKGludCBmZzogMzAgLi4gMzcpIHsKKyAgICAgICAgICAgICAgZm9yZWFjaChpbnQgYmc6IDQwIC4uIDQ3KSB7CisgICAgICAgICAgICAgICAgICBwcmludGYoIhtbJWQ7JWRtG1sxbUAbWzBtIiwgZmcsIGJnKTsKKyAgICAgICAgICAgICAgICAgIHByaW50ZigiG1slZDslZG0bWzRtQBtbMG0iLCBmZywgYmcpOworICAgICAgICAgICAgICAgICAgcHJpbnRmKCIbWyVkOyVkbRtbNW1AG1swbSIsIGZnLCBiZyk7CisgICAgICAgICAgICAgICAgICBwcmludGYoIhtbJWQ7JWRtG1s3bUAbWzBtIiwgZmcsIGJnKTsKKyAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICBwcmludGYoIlxuIik7CisgICAgICAgICAgfQorICAgICAgICAgIHByaW50ZigiU29sbHRlIGRpZXNlciBUZXh0IGhpZXIgbmljaHQgcmljaHRpZyBsZXNiYXJcbnNlaW4sIisKKyAgICAgICAgICAgICAgICAgImJlbnV0emUgZGFzIEtvbW1hbmRvIHN0dHkgcmVzZXQhXG4iKTsKKyAgICAgIH0KKworICB9CisgIHJldHVybiAxOworfQorCitpbnQgc2V0X2FzY2lpX2FydChzdHJpbmcgc3RyKQoreworICBpZiAoc3RyIT0iZWluIiYmc3RyIT0iYXVzIikKKyAgeworICAgICBwcmludGYoIkR1IG1vZWNodGVzdCAnR3JhZmlrJyAiKyhRdWVyeVByb3AoUF9OT19BU0NJSV9BUlQpPyJOSUNIVCAiOiIiKSsKKyAgICAgICAgICAgICAgICAgICAgICJzZWhlbi5cbiIpOworICB9CisKKyAgaWYgKHN0cj09ImVpbiIpIHsKKyAgICBTZXRQcm9wKFBfTk9fQVNDSUlfQVJULCAwKTsKKyAgICBwcmludGYoIlp1a3VlbmZ0aWcgbW9lY2h0ZXN0IER1ICdHcmFmaWsnIHNlaGVuLlxuIik7CisgIH0KKworICBpZiAoc3RyPT0iYXVzIikgeworICAgIFNldFByb3AoUF9OT19BU0NJSV9BUlQsIDEpOworICAgIHByaW50ZigiWnVrdWVuZnRpZyBtb2VjaHRlc3QgRHUgS0VJTkUgJ0dyYWZpaycgbWVociBzZWhlbi5cbiIpOworICB9CisKKworICByZXR1cm4gMTsKK30KKworaW50IF9zZXRfc2hlbGxfdmVyc2lvbihpbnQgYXJnKQoreworICBpZiAoIWludHAoYXJnKSkKKyAgICByZXR1cm4gLTE7CisgIFNldChQX1NIRUxMX1ZFUlNJT04sKHtRdWVyeVByb3AoUF9SQUNFKSxhcmd9KSk7CisgIHJldHVybiAxOworfQorCitpbnQgX3F1ZXJ5X3NoZWxsX3ZlcnNpb24oKQoreyAgIG1peGVkIHN2OworCisgICAgaWYgKCEoc3Y9UXVlcnkoUF9TSEVMTF9WRVJTSU9OKSkgfHwgIXBvaW50ZXJwKHN2KSB8fCBzaXplb2Yoc3YpIT0yIHx8CisgICAgICAgIHN2WzBdIT1RdWVyeVByb3AoUF9SQUNFKSB8fCAhaW50cChzdlsxXSkpCisgICAgICByZXR1cm4gMDsKKyAgICByZXR1cm4gc3ZbMV07Cit9CisKKy8vIFh4WHhYeFh4WHgKKworaW50IG1vcmUoc3RyaW5nIHN0cikKK3sKKyAgaWYoIXN0cikKKyAgeworICAgIG5vdGlmeV9mYWlsKCJVc2FnZTogbW9yZSA8ZmlsZT5cbiIpOworICAgIHJldHVybiAwOworICB9CisgIGlmIChmaWxlX3NpemUoc3RyKSA8PSAwKSB7CisgICAgbm90aWZ5X2ZhaWwoc3RyKyI6IE5vIHN1Y2ggZmlsZVxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgTW9yZShzdHIsIDEpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBzZXRfdmlzdWFsYmVsbChzdHJpbmcgc3RyKQoreworICBpZighc3RyKQorICB7CisgICAgd3JpdGUoIkRlcnplaXRpZ2UgRWluc3RlbGx1bmcgZnVlciBUb25hdXNnYWJlOiAiKworICAgICAgICAgKFF1ZXJ5UHJvcChQX1ZJU1VBTEJFTEwpPyJBVVMiOiJFSU4iKSsiLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKHN0cj09ImVpbiIpCisgIHsKKyAgICBpZighUXVlcnlQcm9wKFBfVklTVUFMQkVMTCkpCisgICAgICB3cml0ZSgiRGllIFRvbmF1c2dhYmUgc3RhbmQgc2Nob24gYXVmIEVJTi5cbiIpOworICAgIGVsc2UKKyAgICAgIHsKKyAgU2V0UHJvcChQX1ZJU1VBTEJFTEwsMCk7CisgICAgICAgIHdyaXRlKCJPSywgVG9uYXVzZ2FiZSBhdWYgRUlOIGdlc3RlbGx0LlxuIik7CisgICAgICB9CisgIH0KKyAgZWxzZQorICAgIGlmIChzdHI9PSJhdXMiKQorICAgIHsKKyAgICAgIGlmKFF1ZXJ5UHJvcChQX1ZJU1VBTEJFTEwpKQorICAgICAgICB3cml0ZSgiRGllIFRvbmF1c2dhYmUgc3RhbmQgc2Nob24gYXVmIEFVUy5cbiIpOworICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgU2V0UHJvcChQX1ZJU1VBTEJFTEwsMSk7CisgICAgd3JpdGUoIk9LLCBUb25hdXNnYWJlIGF1ZiBBVVMgZ2VzdGVsbHQuXG4iKTsKKyAgfQorICAgIH0KKyAgICBlbHNlCisgICAgICB3cml0ZSgiU3ludGF4OiB0b24gW2VpbnxhdXNdXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgc2V0X3NjcmVlbnNpemUoc3RyaW5nIHN0cikKK3sKKyAgaW50IHNpemU7CisKKyAgaWYgKHN0ciAmJiAoc3RyWzAuLjJdID09ICJhYnMiIHx8IHN0clswLi4yXT09InJlbCIpKSB7CisgICAgc2l6ZSA9IFF1ZXJ5UHJvcChQX01PUkVfRkxBR1MpOworICAgIGlmIChzdHJbMC4uMl0gPT0gImFicyIpIHsKKyAgICAgIHNpemUgfD0gRV9BQlM7CisgICAgICB3cml0ZSgiRXMgd2lyZCBiZWltIFByb21wdCBkaWUgWmVpbGVuemFobCBkZXMgVGV4dGVzIGFuZ2VnZWJlbi5cbiIpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIHNpemUgJj0gfkVfQUJTOworICAgICAgd3JpdGUoIkVzIHdpcmQgYmVpbSBQcm9tcHQgZGVyIHByb3plbnR1YWxlIEFudGVpbCBkZXMgVGV4dGVzIGFuZ2VnZWJlbi5cbiIpOworICAgIH0KKyAgICBTZXRQcm9wKFBfTU9SRV9GTEFHUywgc2l6ZSk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBpZiAoIHN0ciAmJiAoc3RyPT0iYXV0byIgfHwgc3NjYW5mKCBzdHIsICJhdXRvICVkIiwgc2l6ZSApKSApeworICAgICAgaWYgKCBzaXplID4gMCApeworICAgICAgICAgIHdyaXRlKCJVbmd1ZWx0aWdlciBXZXJ0ISAiCisgICAgICAgICAgICAgICAgIkluIFZlcmJpbmR1bmcgbWl0ICdhdXRvJyBzaW5kIG51ciBuZWdhdGl2ZSBXZXJ0ZSBlcmxhdWJ0LlxuIik7CisgICAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisKKyAgICAgIFNldFByb3AoIFBfU0NSRUVOU0laRSwgc2l6ZS0xICk7CisKKyAgICAgIHdyaXRlKCJPaywgRGVpbmUgWmVpbGVuemFobCB3aXJkIG51biBhdXRvbWF0aXNjaCBlcm1pdHRlbHQgKGRlcnplaXQgIisKKyAgICAgICAgICAgIFF1ZXJ5UHJvcChQX1NDUkVFTlNJWkUpKyIpLlxuIisKKyAgICAgICAgICAgIGJyZWFrX3N0cmluZygiQml0dGUgYmVhY2h0ZSwgZGFzcyBkaWVzIG51ciBlaW53YW5kZnJlaSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgImZ1bmt0aW9uaWVydCwgd2VubiBEZWluIENsaWVudCBUZWxuZXRuZWdvdGlhdGlvbnMgIgorICAgICAgICAgICAgICAgICAgICAgICAgICJ1bnRlcnN0dWV0enQgKHNpZWhlIGF1Y2ggXCJoaWxmZSB0ZWxuZWdzXCIpLiIpICk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBpZiAoICFzdHIgfHwgc3RyPT0iIiB8fCAhc3NjYW5mKCBzdHIsICIlZCIsIHNpemUgKSB8fCBzaXplIDwgMCB8fCBzaXplID4gMTAwKXsKKyAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygKKyAgICAgICAgICAgIHNwcmludGYoIk1pdCBkZW0gQmVmZWhsICd6ZWlsZW4gPGdyb2Vzc2U+JyBrYW5uc3QgRHUgZWluc3RlbGxlbiwgIgorICAgICAgICAgICAgIndpZXZpZWxlIFplaWxlbiBiZWkgbWVocnNlaXRpZ2VuIFRleHRlbiBhdWYgZWlubWFsIGF1c2dlZ2ViZW4gIgorICAgICAgICAgICAgIndlcmRlbi4gRGllIGFuZ2VnZWJlbmUgR3JvZXNzZSBtdXNzIHp3aXNjaGVuIDAgdW5kIDEwMCBsaWVnZW4uICIKKyAgICAgICAgICAgICJCZWkgR3JvZXNzZSAwIHdpcmQgZWluZmFjaCBhbGxlcyBhdXNnZWdlYmVuIChvaG5lIFBhdXNlKS4gTWl0ICIKKyAgICAgICAgICAgICJkZXIgRWluc3RlbGx1bmcgJ2F1dG8nIHdpcmQgZGllIEdyb2Vzc2UgYXV0b21hdGlzY2ggdWViZXIgIgorICAgICAgICAgICAgImRpZSBUZWxuZXRuZWdvdGlhdGlvbnMgZXJtaXR0ZWx0IChzaWVoZSBhdWNoICdoaWxmZSB0ZWxuZWdzJykuICIKKyAgICAgICAgICAgICJVbSBuYWNoIGVpbmVyIFNlaXRlIFRleHQgbm9jaCBldHdhcyBQbGF0eiB6dSBoYWJlbiwga2FubiBtYW4gei5CLiAiCisgICAgICAgICAgICAiJ3plaWxlbiBhdXRvIC0zJyBlaW5zdGVsbGVuLlxuIgorICAgICAgICAgICAgIkRpZSBWb3JlaW5zdGVsbHVuZyBpc3QgMjAgWmVpbGVuLlxuIgorICAgICAgICAgICAgIk1pdCAnemVpbGVuIGFic1tvbHV0XScgdW5kICd6ZWlsZW4gcmVsW2F0aXZdJyBrYW5uc3QgRHUgZmVzdCIKKyAgICAgICAgICAgICJsZWdlbiwgb2IgaW0gUHJvbXB0IGJlaSBsYW5nZW4gVGV4dGVuIGRpZSBha3R1ZWxsZSBaZWlsZW5udW1tZXIgIgorICAgICAgICAgICAgIm9kZXIgZWluZSBwcm96ZW50dWFsZSBBbmdhYmUgYXVzZ2VnZWJlbiB3aXJkLlxuIgorICAgICAgICAgICAgIkRlaW5lIGFrdHVlbGxlIEVpbnN0ZWxsdW5nIGlzdCAlZCVzIFplaWxlbiAoJXMpLiIsCisgICAgICAgICAgICBRdWVyeVByb3AoUF9TQ1JFRU5TSVpFKSwKKyAgICAgICAgICAgIFF1ZXJ5KFBfU0NSRUVOU0laRSkgPCAwID8gIiAnYXV0b21hdGlzY2hlJyIgOiAiIiwKKyAgICAgICAgICAgIFF1ZXJ5UHJvcChQX01PUkVfRkxBR1MpICYgRV9BQlMgPyAiYWJzb2x1dCIgOiAicmVsYXRpdiIpLDc4LDAsMSkpOworICAgIHJldHVybiAxOworICB9CisKKyAgU2V0UHJvcCggUF9TQ1JFRU5TSVpFLCBzaXplICk7CisKKyAgcHJpbnRmKCAiT2theSwgRGVpbmUgWmVpbGVuemFobCBzdGVodCBudW4gYXVmICVkLlxuIiwgc2l6ZSApOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBfcXVlcnlfc2NyZWVuc2l6ZSgpCit7CisgICAgaW50IHN6LHJvd3M7CisKKyAgICBpZiAoIChzej1RdWVyeShQX1NDUkVFTlNJWkUpKSA+PSAwICkKKyAgICAgICAgcmV0dXJuIHN6OworCisgICAgaWYgKCAhcm93cz1RdWVyeVByb3AoUF9UVFlfUk9XUykgKQorICAgICAgICByZXR1cm4gMDsKKworICAgIHJldHVybiAocm93cys9c3opID49IDUgPyByb3dzIDogNTsKK30KKworc3RhdGljIGludCBwcmVzYXkoc3RyaW5nIHN0cikKK3sKKyAgaWYgKCFzdHI9X3VucGFyc2VkX2FyZ3MoKSkKKyAgICB3cml0ZSgiRGVpbiBQcmVzYXkgaXN0IGpldHp0IGdlbG9lc2NodC5cbiIpOworICBlbHNlCisgICAgcHJpbnRmKCJEZWluIFByZXNheSBsYXV0ZXQgamV0enQ6IFwiJXNcIi5cbiIsc3RyPWNhcGl0YWxpemUoc3RyKSk7CisgIFNldFByb3AoUF9QUkVTQVksc3RyKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgc2V0aGFuZHMoc3RyaW5nIHN0cikKK3sKKyAgbWl4ZWQgKmhhbmRzOworCisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSkKKyAgeworICAgIHdyaXRlKCJzZXRoYW5kcyA8bWVzc2FnZT5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmIChzdHI9PSIwIikKKyAgICAgIGhhbmRzPVJhY2VEZWZhdWx0KFBfSEFORFMpOworICBpZiAoIWhhbmRzIHx8ICFwb2ludGVycChoYW5kcykpCisgICAgICBoYW5kcz1RdWVyeShQX0hBTkRTKTsKKyAgaGFuZHNbMF09IiAiK3N0cjsKKyAgU2V0KFBfSEFORFMsaGFuZHMpOworICB3cml0ZSgiT2suXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgaW5mb3JtKHN0cmluZyBzdHIpCit7CisgIHN3aXRjaCAoc3RyKSB7CisgICAgY2FzZSAib24iOgorICAgIGNhc2UgImVpbiI6CisgICAgY2FzZSAiYW4iOgorICAgICAgaWYgKFF1ZXJ5KFBfSU5GT1JNTUUpKQorICAgIHdyaXRlKCJEYXMgaGF0dGVzdCBEdSBzY2hvbiBzbyBlaW5nZXN0ZWxsdC5cbiIpOworICAgICAgZWxzZQorICAgICAgeworICAgIHdyaXRlKCJLdWVuZnRpZyB3aXJzdCBEdSBpbmZvcm1pZXJ0LCB3ZW5uIGplbWFuZCBkYXMgIk1VRE5BTUUiIHZlcmxhZXNzdC9iZXRyaXR0LlxuIik7CisgICAgU2V0KFBfSU5GT1JNTUUsMSk7CisgICAgICB9CisgICAgICByZXR1cm4gMTsKKyAgICBjYXNlICJhdXMiOgorICAgIGNhc2UgIm9mZiI6CisgICAgICBpZiAoIVF1ZXJ5KFBfSU5GT1JNTUUpKQorICAgIHdyaXRlKCJEYXMgaGF0dGVzdCBEdSBzY2hvbiBzbyBlaW5nZXN0ZWxsdC5cbiIpOworICAgICAgZWxzZQorICAgICAgeworICAgIHdyaXRlKCJPay5cbiIpOworICAgIFNldChQX0lORk9STU1FLDApOworICAgICAgfQorICAgICAgcmV0dXJuIDE7CisgICAgY2FzZSAwOgorICAgICAgd3JpdGUoIkluZm9ybS1Nb2RlIGlzdCAiKyhRdWVyeShQX0lORk9STU1FKT8iYW4iOiJhdXMiKSsiZ2VzY2hhbHRldC5cbiIpOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICB3cml0ZSgiaW5mb3JtIGFuIG9kZXIgaW5mb3JtIGF1cywgYml0dGUuXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3ZvaWQgZGVsYXllZF93cml0ZShtaXhlZCAqd2hhdCkKK3sKKyAgaWYgKCFwb2ludGVycCh3aGF0KXx8IXNpemVvZih3aGF0KXx8IXBvaW50ZXJwKHdoYXRbMF0pKQorICAgIHJldHVybjsKKyAgdGVsbF9vYmplY3QoTUUsd2hhdFswXVswXSk7CisgIGlmIChzaXplb2Yod2hhdCk+MSYmc2l6ZW9mKHdoYXRbMF0pPjEpCisgICAgY2FsbF9vdXQoImRlbGF5ZWRfd3JpdGUiLHdoYXRbMF1bMV0sd2hhdFsxLi5dKTsKK30KKwordm9pZCBub3RpZnlfcGxheWVyX2NoYW5nZShzdHJpbmcgd2hvLCBpbnQgcmVpbiwgaW50IGludmlzKQoreworICBzdHJpbmcgKmxpc3QsbmFtZTsKKyAgbWl4ZWQgbWxpc3Q7CisKKyAgaWYgKGludmlzKSBuYW1lPSIoIit3aG8rIikiOworICAgIGVsc2UgbmFtZT13aG87CisKKyAgaWYgKFF1ZXJ5KFBfSU5GT1JNTUUpKQorICB7CisgICAgICBpZiAocmVpbikKKyAgICAgICAgdGVsbF9vYmplY3QoTUUsbmFtZSsiIGlzdCBnZXJhZGUgaW5zICJNVUROQU1FIiBnZWtvbW1lbi5cbiIpOworICAgICAgZWxzZQorICAgICAgICB0ZWxsX29iamVjdChNRSxuYW1lKyIgaGF0IGdlcmFkZSBkYXMgIk1VRE5BTUUiIHZlcmxhc3Nlbi5cbiIpOworICB9CisKKyAgaWYoUXVlcnkoUF9XQUlURk9SX0ZMQUdTKSAmICgweDAxKSlyZXR1cm4gOworCisgIGlmKHBvaW50ZXJwKGxpc3Q9UXVlcnkoUF9XQUlURk9SKSkgJiYgc2l6ZW9mKGxpc3QpICYmIG1lbWJlcihsaXN0LHdobykhPS0xKQorICB7CisgICAgaWYgKCFRdWVyeVByb3AoUF9WSVNVQUxCRUxMKSkKKyAgICAgICAgbmFtZSs9c3ByaW50ZigiJWMiLDcpOyAvLyBDaGFyIGZ1ZXIgUGllcHMgYW4gZGVuIFN0cmluZyBhbmhhZW5nZW4uCisgICAgLy8gTW9lY2h0ZSBkZXIgU3BpZWxlciBrZWluZSBBU0NJSS1HcmFmaWsgc2VoZW4sIHdpcmQgZGllc2UgTWVsZHVuZyBvaG5lCisgICAgLy8gTGVlcnplaWNoZW4gZm9ybWF0aWVydCwgc28gZGFzcyBzaWUgdm9uIFNjcmVlbnJlYWRlcm4gdm9yZ2VsZXNlbiB3aXJkLgorICAgIC8vIEFuZGVyZW5mYWxscyB3dWVyZGUgc2llIGVpbnplbG4gYnVjaHN0YWJpZXJ0LgorICAgIGlmICggUXVlcnlQcm9wKFBfTk9fQVNDSUlfQVJUKSApCisgICAgeworICAgICAgZGVsYXllZF93cml0ZSggKHsgKHsgc3ByaW50ZigiJXMgSVNUIEpFVFpUICVzREEgISEhXG4iLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUsIChyZWluPyIiOiJOSUNIVCBNRUhSICIpKSB9KSB9KSApOworICAgIH0KKyAgICBlbHNlIAorICAgIHsKKyAgICAgIGRlbGF5ZWRfd3JpdGUoICh7ICh7IHNwcmludGYoIiVzICAgSSBTIFQgICBKIEUgVCBaIFQgICAlc0QgQSAhISFcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCAocmVpbj8iIjoiTiBJIEMgSCBUICAgTSBFIEggUiAgICIpKSB9KSB9KSApOworICAgIH0KKyAgfQorCisgIGlmIChyZWluICYmIChzaXplb2YobWxpc3Q9UXVlcnlQcm9wKFBfV0FJVEZPUl9SRUFTT04pKSkgJiYKKyAgICAgKG1hcHBpbmdwKG1saXN0KSkgJiYgKG1saXN0W3dob10pKQorICAgICAgICBTaG93X1dhaXRGb3JfUmVhc29uKHdobyxpbnZpcyk7Cit9CisKK3N0YXRpYyBpbnQgZXJ3YXJ0ZShzdHJpbmcgc3RyKQoreworICBzdHJpbmcgKmxpc3QsKnN0cjE7CisgIG1peGVkIG1saXN0OworICBpbnQgaTsKKworICBpZiAoIW1hcHBpbmdwKG1saXN0PVF1ZXJ5UHJvcChQX1dBSVRGT1JfUkVBU09OKSkpCisgICAgIG1saXN0PShbXSk7CisgIGlmICghcG9pbnRlcnAobGlzdD1RdWVyeShQX1dBSVRGT1IpKSkKKyAgICAgbGlzdD0oe30pOworCisgIGlmICghc3RyIHx8IHN0cj09Ii11IikKKyAgeworICAgICBpZihRdWVyeShQX1dBSVRGT1JfRkxBR1MpJjB4MDEpCisgICAgICAgd3JpdGUoIkR1IGhhc3QgJ2Vyd2FydGUnIHRlbXBvcmFlciBkZWFrdGl2aWVydC5cbiIpOworICAgICB3cml0ZSgiRHUgZXJ3YXJ0ZXN0IGpldHp0Iik7CisgICAgIGlmICghc2l6ZW9mKGxpc3QpKQorICAgICAgICB3cml0ZSgiIG5pZW1hbmRlbiBtZWhyLlxuIik7CisgICAgIGVsc2UKKyAgICAgeworICAgICAgICB3cml0ZSgiOlxuIik7CisgICAgICAgIGlmICghc3RyKSBsaXN0PXNvcnRfYXJyYXkobGlzdCwjJz4pOworICAgICAgICBNb3JlKGJyZWFrX3N0cmluZyhDb3VudFVwKGxpc3QpLDc4KSk7CisgICAgIH0KKyAgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYoc3RyPT0iYXVzIil7CisgICAgU2V0KFBfV0FJVEZPUl9GTEFHUyxRdWVyeShQX1dBSVRGT1JfRkxBR1MpfDB4MDEpOworICAgIHdyaXRlKCJFcndhcnRlIGlzdCBqZXR6dCBkZWFrdGl2aWVydC5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmKHN0cj09ImFuIiB8fCBzdHI9PSJlaW4iKXsKKyAgICBTZXQoUF9XQUlURk9SX0ZMQUdTLFF1ZXJ5KFBfV0FJVEZPUl9GTEFHUykmMHhGRSk7CisgICAgd3JpdGUoIkVyd2FydGUgaXN0IGpldHp0IGFrdGl2LlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBzdHIxPWV4cGxvZGUoX3VucGFyc2VkX2FyZ3MoKXx8IiIsIiAiKTsKKyAgaWYgKHNpemVvZihzdHIxKT09MSkKKyAgeworICAgICBpZiAoc3RyMVswXSE9IndlZ2VuIikKKyAgICAgeworICAgICAgICBzdHI9Y2FwaXRhbGl6ZShsb3dlcl9jYXNlKHN0cikpOworICAgICAgICBpZiAobWVtYmVyKGxpc3Qsc3RyKSE9LTEpCisgICAgICAgIHsKKyAgICAgICAgICAgU2V0UHJvcChQX1dBSVRGT1JfUkVBU09OLG1fY29weV9kZWxldGUobWxpc3Qsc3RyKSk7CisgICAgICAgICAgIGxpc3QtPSh7c3RyfSk7CisgICAgICAgICAgIHdyaXRlKHN0cisiIGF1cyBkZXIgTGlzdGUgZW50ZmVybnQuXG4iKTsKKyAgICAgICAgfSBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICAgaWYgKHNpemVvZihsaXN0KT4xMDAwKQorICAgICAgICAgICB7CisgICAgICAgICAgICAgd3JpdGUoIkR1IGVyd2FydGVzdCBzY2hvbiBnZW51ZWdlbmQhXG4iKTsKKyAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICAgfQorICAgICAgICAgICBsaXN0Kz0oe3N0cn0pOworICAgICAgICAgICB3cml0ZShzdHIrIiBhbiBkaWUgTGlzdGUgYW5nZWhhZW5ndC5cbiIpOworICAgICAgICB9CisgICAgICAgIFNldChQX1dBSVRGT1IsbGlzdCk7CisgICAgIH0KKyAgICAgZWxzZQorICAgICB7CisgICAgICAgIGlmIChzaXplb2YobWxpc3QpICYmIHNpemVvZihsaXN0PW1faW5kaWNlcyhtbGlzdCkpKQorICAgICAgICB7CisgICAgICAgICAgIHdyaXRlKCJEdSBlcndhcnRlc3QgYXVzIGVpbmVtIGJlc3RpbW10ZW4gR3J1bmQ6XG4iKTsKKyAgICAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKENvdW50VXAoc29ydF9hcnJheShsaXN0LCMnPikpKyIuIiw3OCkpOworICAgICAgICB9CisgICAgICAgIGVsc2Ugd3JpdGUoIkR1IGVyd2FydGVzdCBuaWVtYW5kZW4gYXVzIGVpbmVtIGJlc3RpbW10ZW4gR3J1bmQuXG4iKTsKKyAgICAgfQorICAgICByZXR1cm4gMTsKKyAgfQorICBub3RpZnlfZmFpbCgiRmFsc2NoZSBTeW50YXgsIHNpZWhlICdoaWxmZSBlcndhcnRlJyFcbiIpOworICBpZiAoc3RyMVsxXSE9IndlZ2VuIikgcmV0dXJuIDA7CisgIGlmIChzaXplb2Yoc3RyMSk9PTIpCisgICAgIFNob3dfV2FpdEZvcl9SZWFzb24oY2FwaXRhbGl6ZShsb3dlcl9jYXNlKHN0cjFbMF0pKSwwKTsKKyAgZWxzZSB7CisgICAgIHN0cmluZyBzPWNhcGl0YWxpemUobG93ZXJfY2FzZShzdHIxWzBdKSk7CisgICAgIGlmIChzaXplb2Yoc3RyMSk9PTMgJiYgKHN0cjFbMl09PSJuaWNodHMiIHx8IHN0cjFbMl09PSJsb2VzY2hlbiIpKQorICAgICAgICBpZiAoIW1saXN0W3NdKQorICAgICAgICAgICB3cml0ZSgiRHUgaGFzdCAiK3MrIiBhdXMga2VpbmVtIGJlc3RpbW10ZW4gR3J1bmQgZXJ3YXJ0ZXQhXG4iKTsKKyAgICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgIFNldFByb3AoUF9XQUlURk9SX1JFQVNPTixtX2NvcHlfZGVsZXRlKG1saXN0LHMpKTsKKyAgICAgICAgICAgd3JpdGUoIkR1IGVyd2FydGVzdCAiK3MrIiBhdXMga2VpbmVtIGJlc3RpbW10ZW4gR3J1bmQgbWVociFcbiIpOworICAgICAgICB9CisgICAgIGVsc2UKKyAgICAgeworICAgICAgICBpZiAoSVNfQVJDSChNRSkpIGk9ODA7IGVsc2UgaWYgKElTX0xFQVJORVIoTUUpKSBpPTQwOworICAgICAgICBlbHNlIGlmIChJU19TRUVSKE1FKSkgaT0yMDsgZWxzZSBpPTEwOworICAgICAgICBpZiAoIW1saXN0W3NdICYmIHNpemVvZihtbGlzdCk+PWkpCisgICAgICAgICAgIHdyaXRlKCJTb3JyeSwgYWJlciBEdSBlcndhcnRlc3Qgc2Nob24gZ2VudWVnZW5kIExldXRlIVxuIik7CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgICBTZXRQcm9wKFBfV0FJVEZPUl9SRUFTT04sbWxpc3QrKFtzOmltcGxvZGUoc3RyMVsyLi5dLCIgIildKSk7CisgICAgICAgICAgIFNob3dfV2FpdEZvcl9SZWFzb24ocywwKTsKKyAgICAgICAgfQorICAgICB9CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgdWhybWVsZHVuZyhzdHJpbmcgc3RyKQoreworICBpZiAoIShzdHI9X3VucGFyc2VkX2FyZ3MoKSkpCisgIHsKKyAgICBzdHI9UXVlcnlQcm9wKFBfQ0xPQ0tNU0cpOworICAgIGlmICghc3RyKQorICAgIHsKKyAgICAgIHdyaXRlKCJEdSBoYXN0IGRpZSBTdGFuZGFyZC1VaHJtZWxkdW5nLlxuIik7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgICAgIGlmKCAhc3RyaW5ncChzdHIpICkgc3RyID0gc3ByaW50ZigiJU9cbiIsc3RyKTsKKyAgICBwcmludGYoIkRlaW5lIFVocm1lbGR1bmcgaXN0OlxuJXNcbiIsc3RyWzAuLjwyXSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKHN0cj09IjAiKQorICB7CisgICAgU2V0UHJvcChQX0NMT0NLTVNHLDApOworICAgIHdyaXRlKCJPaywgRHUgaGFzdCBqZXR6dCB3aWVkZXIgZGllIFN0YW5kYXJkLU1lbGR1bmcuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoc2l6ZW9mKGV4cGxvZGUoc3RyLCIlZCIpKT4yKQorICB7CisgICAgd3JpdGUoIkZlaGxlciwgZXMgZGFyZiBudXIgZWluICVkIGluIGRlciBNZWxkdW5nIHZvcmtvbW1lbi5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIC8qIE1laHJlcmUgJS1QYXJhbWV0ZXIgdmVydXJzYWNoZW4gZGFzIEFic2NoYWx0ZW4gZGVyIFVociB6dXIgdm9sbGVuIFN0dW5kZS4KKyAgICovCisgIGlmIChzaXplb2YoZXhwbG9kZShzdHIsIiUiKSk+MikKKyAgeworICAgIHdyaXRlKCJGZWhsZXI6IFp1dmllbGUgJS1QYXJhbWV0ZXIgaW4gZGVyIE1lbGR1bmcuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICAvKiBOdXIgZWluICUtUGFyYW1ldGVyLCBhYmVyIGRlciBmYWxzY2hlOiBuaWNodCBzaW5udm9sbC4gKi8KKyAgZWxzZQorICB7CisgICAgaW50IGkgPSBzdHJzdHIoc3RyLCIlIiwwKTsKKyAgICBpZiAoIGk+LTEgJiYgKCBpPT1zaXplb2Yoc3RyKS0xIHx8IHN0cltpKzFdIT0nZCcpKQorICAgIHsKKyAgICAgIHdyaXRlKCJGZWhsZXI6IEZhbHNjaGVyICUtUGFyYW1ldGVyIGluIGRlciBNZWxkdW5nLlxuIik7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKyAgc3RyKz0iXG4iOworICBTZXRQcm9wKFBfQ0xPQ0tNU0csc3RyKTsKKyAgd3JpdGUoIk9rLlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IHplaXR6b25lKHN0cmluZyBzdHIpCit7CisgIGludCB6dDsKKyAgaWYoIXN0ciB8fCBzdHI9PSIiKXsKKyAgICBpZighKHp0PVF1ZXJ5UHJvcChQX1RJTUVaT05FKSkpCisgICAgICB3cml0ZSgiRHUgaGFzdCBkZXJ6ZWl0IGRpZSBnbGVpY2hlIFplaXR6b25lIHdpZSBkYXMgIk1VRE5BTUUiICIrCisgICAgICAgICAgICAiZWluZ2VzdGVsbHQuXG4iKTsKKyAgICBlbHNlIGlmKHp0PjApCisgICAgICBwcmludGYoIkRlaW5lIFplaXR6b25lIGlzdCBhdWYgJWQgU3R1bmRlbiB2b3IgKG9lc3RsaWNoKSB2b24gQmVybGluICIrCisgICAgICAgICAgICAgImVpbmdlc3RlbGx0LlxuIix6dCk7CisgICAgZWxzZQorICAgICAgcHJpbnRmKCJEZWluZSBaZWl0em9uZSBpc3QgYXVmICVkIFN0dW5kZW4gbmFjaCAod2VzdGxpY2gpIHZvbiAiKworICAgICAgICAgICAgICJCZXJsaW4gZWluZ2VzdGVsbHQuXG4iLC16dCk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYoc3NjYW5mKHN0ciwidXRjICVkIix6dCk9PTEpICB6dD0oenQtMSklMjQ7CisgIGVsc2UgenQ9dG9faW50KHN0ciklMjQ7CisKKyAgU2V0UHJvcChQX1RJTUVaT05FLHp0KTsKKworICBpZighenQpCisgICAgd3JpdGUoIkR1IGhhc3QgZGVyemVpdCBkaWUgZ2xlaWNoZSBaZWl0em9uZSB3aWUgZGFzICJNVUROQU1FIiAiKworICAgICAgICAgICJlaW5nZXN0ZWxsdC5cbiIpOworICBlbHNlIGlmKHp0PjApCisgICAgcHJpbnRmKCJEZWluZSBaZWl0em9uZSBpc3QgYXVmICVkIFN0dW5kZW4gdm9yIChvZXN0bGljaCkgdm9uIEJlcmxpbiAiKworICAgICAgICAgICAiZWluZ2VzdGVsbHQuXG4iLHp0KTsKKyAgZWxzZQorICAgIHByaW50ZigiRGVpbmUgWmVpdHpvbmUgaXN0IGF1ZiAlZCBTdHVuZGVuIG5hY2ggKHdlc3RsaWNoKSB2b24gIisKKyAgICAgICAgICAgIkJlcmxpbiBlaW5nZXN0ZWxsdC5cbiIsLXp0KTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgZW1haWxhbnplaWdlKHN0cmluZyBzdHIpeworICBub3RpZnlfZmFpbCgiU3ludGF4OiBlbWFpbGFuemVpZ2UgW2FsbGV8ZnJldW5kZXxuaWVtYW5kXVxuIik7CisgIGlmKCFzdHIgfHwgc3RyPT0iIil7CisgICAgaWYoIShzdHI9UXVlcnlQcm9wKFBfU0hPV0VNQUlMKSkpc3RyPSJOaWVtYW5kZW0iOworICAgIGVsc2UgaWYoc3RyPT0iYWxsZSIpc3RyPSJhbGxlbiI7CisgICAgZWxzZSBpZihzdHI9PSJmcmV1bmRlIilzdHI9IkRlaW5lbiBGcmV1bmRlbiI7CisgICAgZWxzZSBpZihzdHI9PSJuaWVtYW5kIilzdHI9Im5pZW1hbmRlbSI7CisgICAgZWxzZXsKKyAgICAgIFNldFByb3AoUF9TSE9XRU1BSUwsMCk7CisgICAgICBzdHI9Ik5pZW1hbmRlbSI7CisgICAgfQorICAgIHdyaXRlKCJEZWluZSBFbWFpbCB3aXJkICIrc3RyKyIgYW5nZXplaWd0LlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgZWxzZSBpZihtZW1iZXIoKHsiYWxsZSIsImZyZXVuZGUiLCJuaWVtYW5kIn0pLHN0cik9PS0xKXJldHVybiAwOworCisgIFNldFByb3AoUF9TSE9XRU1BSUwsc3RyKTsKKworICBpZihzdHI9PSJhbGxlIilzdHI9ImFsbGVuIjsKKyAgZWxzZSBpZihzdHI9PSJmcmV1bmRlIilzdHI9IkRlaW5lbiBGcmV1bmRlbiI7CisgIGVsc2Ugc3RyPSJuaWVtYW5kZW0iOworICB3cml0ZSgiRGVpbmUgRW1haWwgd2lyZCAiK3N0cisiIGFuZ2V6ZWlndC5cbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCB6YXViZXJ0cmFlbmtlKCkKK3sKKyAgTW9yZSgiL3Jvb20vb3Jha2VsIi0+VGlwTGlzdGUoKSk7CisgIHJldHVybiAxOworfQorCit2YXJhcmdzIHN0YXRpYyBpbnQgYW5ncmlmZnNtZWxkdW5nKHN0cmluZyBhcmcpIHsKKyAgaWYgKGFyZz09ImVpbiIgfHwgYXJnPT0iYW4iKQorICAgIFNldFByb3AoUF9TSE9XX0FUVEFDS19NU0csMSk7CisgIGVsc2UgaWYgKGFyZz09ImF1cyIpCisgICAgU2V0UHJvcChQX1NIT1dfQVRUQUNLX01TRywwKTsKKyAgaWYgKFF1ZXJ5UHJvcChQX1NIT1dfQVRUQUNLX01TRykpCisgICAgd3JpdGUoIkR1IHNpZWhzdCBzYWVtdGxpY2hlIEFuZ3JpZmZzbWVsZHVuZ2VuIHZvbiBEaXIuXG4iKTsKKyAgZWxzZQorICAgIHdyaXRlKCJEdSBzaWVoc3QgbnVyIG5ldWUgQW5ncmlmZnNtZWxkdW5nZW4gdm9uIERpci5cbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIG1peGVkIF9xdWVyeV9sb2NhbGNtZHMoKQoreworICByZXR1cm4gKHsoeyJ6ZWlsZW4iLCJzZXRfc2NyZWVuc2l6ZSIsMCwwfSksCisgICAgICAgICAgICh7ImVtYWlsIiwic2V0X2VtYWlsIiwwLDB9KSwKKyAgICAgICAgICAgKHsidXJsIiwic2V0X2hvbWVwYWdlIiwwLDB9KSwKKyAgICAgICAgICAgKHsiaWNxIiwic2V0X2ljcSIsMCwwfSksCisgICAgICAgICAgICh7Im1lc3NlbmdlciIsICJzZXRfbWVzc2VuZ2VyIiwgMCwgMH0pLCAKKyAgICAgICAgICAgKHsib3J0Iiwic2V0X2xvY2F0aW9uIiwwLDB9KSwKKyAgICAgICAgICAgKHsicHVua3RlIiwic2hvcnRfc2NvcmUiLDAsMH0pLAorICAgICAgICAgICAoeyJzY29yZSIsInNob3J0X3Njb3JlIiwwLDB9KSwKKyAgICAgICAgICAgKHsiaW5mbyIsInNjb3JlIiwwLDB9KSwKKyAgICAgICAgICAgKHsia3VyemluZm8iLCJ2ZXJ5X3Nob3J0X3Njb3JlIiwwLDB9KSwKKyAgICAgICAgICAgKHsicXVpdCIsIm5ld19xdWl0IiwwLDB9KSwKKyAgICAgICAgICAgKHsiZW5kZSIsIm5ld19xdWl0IiwwLDB9KSwKKyAgICAgICAgICAgKHsiZGlzY29ubmVjdCIsImRpc2Nvbm5lY3QiLDAsMH0pLAorICAgICAgICAgICAoeyJzY2hsYWYiLCJkaXNjb25uZWN0IiwxLDB9KSwKKyAgICAgICAgICAgKHsic3BlaWNoZXJuIiwic2F2ZV9jaGFyYWN0ZXIiLDAsMH0pLAorICAgICAgICAgICAoeyJzYXZlIiwic2F2ZV9jaGFyYWN0ZXIiLDAsMH0pLAorICAgICAgICAgICAoeyJ0b2V0ZSIsImtpbGwiLDAsMH0pLAorICAgICAgICAgICAoeyJhbmdyaWZmc21lbGR1bmciLCJhbmdyaWZmc21lbGR1bmciLDAsMH0pLAorICAgICAgICAgICAoeyJwYXNzdyIsImNoYW5nZV9wYXNzd29yZCIsMSwwfSksCisgICAgICAgICAgICh7ImhpbGZlIiwiaGVscCIsMSwwfSksCisgICAgICAgICAgICh7InNlbGJzdGxvZXNjaHVuZyIsInNlbGZfZGVsZXRlIiwwLDB9KSwKKyAgICAgICAgICAgKHsic3BpZWxwYXVzZSIsInNwaWVscGF1c2UiLDAsMH0pLAorICAgICAgICAgICAoeyJzcGllbGRhdWVyIiwic3BpZWxkYXVlciIsMCwwfSksCisgICAgICAgICAgICh7ImlkZWUiLCJpZGVhIiwwLDB9KSwKKyAgICAgICAgICAgKHsidHlwbyIsInR5cG8iLDAsMH0pLAorICAgICAgICAgICAoeyJidWciLCJidWciLDAsMH0pLAorICAgICAgICAgICAoeyJmZWhsZXIiLCJmZWhsZXJoaWxmZSIsMCwwfSksCisgICAgICAgICAgICh7Im1kIiwibWQiLDAsMH0pLAorICAgICAgICAgICAoeyJkZXRhaWwiLCJtZCIsMCwwfSksCisgICAgICAgICAgICh7InZvcnNpY2h0IiwidG9nZ2xlX3doaW1weSIsMCwwfSksCisgICAgICAgICAgICh7InN0b3AiLCJzdG9wIiwwLDB9KSwKKyAgICAgICAgICAgKHsia3dobyIsImt3aG8iLDAsMH0pLAorICAgICAgICAgICAoeyJrd2VyIiwia3dobyIsMCwwfSksCisgICAgICAgICAgICh7Imtrd2VyIiwia2t3aG8iLDAsMH0pLAorICAgICAgICAgICAoeyJra3dobyIsImtrd2hvIiwwLDB9KSwKKyAgICAgICAgICAgKHsid2hvIiwid2hvIiwwLDB9KSwKKyAgICAgICAgICAgKHsid2VyIiwid2hvIiwwLDB9KSwKKyAgICAgICAgICAgKHsiemVpdCIsInVocnplaXQiLDAsMH0pLAorICAgICAgICAgICAoeyJ1aHJ6ZWl0IiwidWhyemVpdCIsMCwwfSksCisgICAgICAgICAgICh7IndlZyIsIndlZyIsMCwwfSksCisgICAgICAgICAgICh7IndlZ21lbGR1bmciLCAid2VnbWVsZHVuZyIsIDAsIDB9KSwKKyAgICAgICAgICAgKHsiaWRsZXplaXQiLCAiaWRsZXplaXQiLCAwLCAwfSksCisgICAgICAgICAgICh7ImZpbmdlciIsImZpbmdlciIsMCwwfSksCisgICAgICAgICAgICh7Im11ZHMiLCJtdWRzIiwwLDB9KSwKKyAgICAgICAgICAgKHsiZW1vdGUiLCJlbW90ZSIsMCwwfSksCisgICAgICAgICAgICh7IjoiLCJlbW90ZSIsMSwwfSksCisgICAgICAgICAgICh7IjsiLCJlbW90ZSIsMSwwfSksCisgICAgICAgICAgICh7InJlbW90ZSIsInJlbW90ZSIsMCxTRUVSX0xWTH0pLAorICAgICAgICAgICAoeyJyOiIsInJlbW90ZSIsMSwwfSksCisgICAgICAgICAgICh7InI7IiwiZ3JlbW90ZSIsMSwwfSksCisgICAgICAgICAgICh7InRpdGVsIiwic2V0X3RpdGxlIiwwLDB9KSwKKyAgICAgICAgICAgKHsicmV2aWV3IiwicmV2aWV3IiwwLFNFRVJfTFZMfSksCisgICAgICAgICAgICh7InNldG1pbiIsInNldG1pbiIsMCxTRUVSX0xWTH0pLAorICAgICAgICAgICAoeyJzZXRtb3V0Iiwic2V0bW91dCIsMCxTRUVSX0xWTH0pLAorICAgICAgICAgICAoeyJzZXRtbWluIiwic2V0bW1pbiIsMCxTRUVSX0xWTH0pLAorICAgICAgICAgICAoeyJzZXRtbW91dCIsInNldG1tb3V0IiwwLFNFRVJfTFZMfSksCisgICAgICAgICAgICh7InNldGhhbmRzIiwic2V0aGFuZHMiLDAsU0VFUl9MVkx9KSwKKyAgICAgICAgICAgKHsicHJlc2F5IiwicHJlc2F5IiwwLFNFRVJfTFZMfSksCisgICAgICAgICAgICh7ImV4dHJhbG9vayIsImV4dHJhbG9vayIsMCxTRUVSX0xWTH0pLAorICAgICAgICAgICAoeyJmbHVjaHRyaWNodHVuZyIsInRvZ2dsZV93aGltcHlfZGlyIiwwLFNFRVJfTFZMfSksCisgICAgICAgICAgICh7ImluZm9ybSIsImluZm9ybSIsMCwwfSksCisgICAgICAgICAgICh7ImVyd2FydGUiLCJlcndhcnRlIiwwLDB9KSwKKyAgICAgICAgICAgKHsic3R0eSIsInN0dHkiLDAsMH0pLAorICAgICAgICAgICAoeyJncmFmaWsiLCAic2V0X2FzY2lpX2FydCIsIDAsIDB9KSwgCisgICAgICAgICAgICh7InVocm1lbGR1bmciLCJ1aHJtZWxkdW5nIiwwLDB9KSwKKyAgICAgICAgICAgKHsiemVpdHpvbmUiLCJ6ZWl0em9uZSIsMCwwfSksCisgICAgICAgICAgICh7ImJlaGFsdGUiLCJiZWhhbHRlIiwwLDB9KSwKKyAgICAgICAgICAgKHsiendlaXRpZW1hcmtpZXJ1bmciLCJ6d2VpdGllbWFya2llcnVuZyIsMCwwfSksCisgICAgICAgICAgICh7ImVtYWlsYW56ZWlnZSIsImVtYWlsYW56ZWlnZSIsMCwwfSksCisgICAgICAgICAgICh7InRvcGxpc3RlIiwidG9wbGlzdGUiLDAsMH0pLAorICAgICAgICAgICAoeyJ0b24iLCJzZXRfdmlzdWFsYmVsbCIsMCwwfSksCisgICAgICAgICAgICh7InRlbG5lZ3MiLCJzaG93X3RlbG5lZ3MiLDAsMH0pLAorICAgICAgICAgICAoeyJzcG90dGUiLCAic3BvdHRlIiwgMCwgMH0pLAorICAgICAgICAgICAoeyJyZWlzZSIsInJlaXNlIiwwLDB9KSwKKyAgICAgICAgICAgKHsiemF1YmVydHJhZW5rZSIsInphdWJlcnRyYWVua2UiLDAsMH0pLAorICAgICAgICAgICAoeyJ0ZWxuZXQiLCJ0ZWxuZXRfY21kIiwwLDB9KSwKKyAgICAgfSkrCisgICAgIGNvbW1hbmQ6Ol9xdWVyeV9sb2NhbGNtZHMoKSsKKyAgICAgdmlld2NtZDo6X3F1ZXJ5X2xvY2FsY21kcygpKworICAgICBjb21tOjpfcXVlcnlfbG9jYWxjbWRzKCkrCisgICAgIHNraWxsczo6X3F1ZXJ5X2xvY2FsY21kcygpKworICAgICBkZXNjcmlwdGlvbjo6X3F1ZXJ5X2xvY2FsY21kcygpOworfQorCitzdGF0aWMgaW50IF9jaGVja19rZWVwKG9iamVjdCBvYikKK3sKKyAgcmV0dXJuIChvYi0+UXVlcnlQcm9wKFBfS0VFUF9PTl9TRUxMKSk9PWdldGV1aWQoTUUpOworfQorCitzdGF0aWMgbWl4ZWQgX3NldF90ZXN0cGxheWVyKG1peGVkIGFyZykgeworICBtaXhlZCByZXM7CisgIG9iamVjdCBzZXRvYjsKKworICBzZXRvYj10aGlzX3BsYXllcigpOworICBpZiAoIW9iamVjdHAoc2V0b2IpIHx8ICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHNldG9iKSkKKyAgICBzZXRvYj10aGlzX2ludGVyYWN0aXZlKCk7CisgIGlmICghb2JqZWN0cChzZXRvYikpCisgICAgc2V0b2I9cHJldmlvdXNfb2JqZWN0KCk7CisgIGlmIChzZXRvYiAmJiAhSVNfREVQVVRZKHNldG9iKSkgeworICAgIGFyZz1nZXRldWlkKHNldG9iKTsKKyAgICBpZiAoIWFyZyB8fCBhcmc9PSJOT0JPRFkiKQorICAgICAgYXJnPWdldHVpZChzZXRvYik7CisgICAgYXJnPWNhcGl0YWxpemUoYXJnKTsKKyAgfQorICByZXM9U2V0KFBfVEVTVFBMQVlFUixhcmcpOworICBTZXQoUF9URVNUUExBWUVSLFBST1RFQ1RFRCxGX01PREVfQVMpOworICByZXR1cm4gcmVzOworfQorCitpbnQgendlaXRpZW1hcmtpZXJ1bmcoc3RyaW5nIGFyZykKK3sKKyAgaWYgKCFRdWVyeVByb3AoUF9TRUNPTkQpKQorICAgIHJldHVybiBfbm90aWZ5X2ZhaWwoIkFiZXIgRHUgYmlzdCBkb2NoIGdhciBrZWluIFp3ZWl0aS5cbiIpLDA7CisgIG5vdGlmeV9mYWlsKCJTeW50YXg6IHp3ZWl0aWVtYXJraWVydW5nIFt1bnNpY2h0YmFyfHNpY2h0YmFyfG5hbWVdXG4iKTsKKyAgaWYgKCFhcmcpCisgICAgcmV0dXJuIDA7CisgIHN3aXRjaCAoYXJnKQorICB7CisgICAgY2FzZSAidW5zaWNodGJhciIgOgorICAgICAgU2V0UHJvcChQX1NFQ09ORF9NQVJLLC0xKTsKKyAgICAgIHdyaXRlKCJKZXR6dCBzaWVodCBrZWluIFNwaWVsZXIgbWVociwgZGFzcyBEdSBlaW4gWndlaXRpIGJpc3QuXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgIGNhc2UgInNpY2h0YmFyIiA6CisgICAgICBTZXRQcm9wKFBfU0VDT05EX01BUkssMCk7CisgICAgICB3cml0ZSgiSmV0enQgc2llaHQga2VpbiBTcGllbGVyIG1laHIsIHdlc3NlbiBad2VpdGkgRHUgYmlzdC5cbiIpOworICAgICAgcmV0dXJuIDE7CisgICAgY2FzZSAibmFtZSIgOgorICAgICAgU2V0UHJvcChQX1NFQ09ORF9NQVJLLDEpOworICAgICAgd3JpdGUoIkpldHp0IGtvZW5uZW4gYWxsZSBzZWhlbiwgd2Vzc2VuIFp3ZWl0aSBEdSBiaXN0LlxuIik7CisgICAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworaW50IHRvcGxpc3RlKHN0cmluZyBhcmcpCit7CisgICAgaWYgKCFhcmcpCisgICAgeworICAgICAgICBwcmludGYoIkR1IGhhc3QgRGljaCBmdWVyIGRpZSBUb3BsaXN0ZSAlcy5cbiIsCisgICAgICAgICAgICAoUXVlcnlQcm9wKFBfTk9fVE9QTElTVCkgPyAiZ2VzcGVycnQiIDogImZyZWlnZWdlYmVuIikpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgZWxzZSBpZiAobWVtYmVyKCh7ImoiLCJqYSIsIm4iLCJuZWluIn0pLGFyZyk9PS0xKQorICAgICAgICByZXR1cm4gX25vdGlmeV9mYWlsKCJTeW50YXg6IHRvcGxpc3RlIFtqYXxuZWluXVxuIiksMDsKKyAgICBpZiAoYXJnWzBdPT0naicpCisgICAgeworICAgICAgICBTZXRQcm9wKFBfTk9fVE9QTElTVCwwKTsKKyAgICAgICAgd3JpdGUoIkR1IGthbm5zdCBqZXR6dCAodGhlb3JldGlzY2gpIGluIGRlciBUb3BsaXN0ZSBhdWZ0YXVjaGVuLlxuIik7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICAgIFNldFByb3AoUF9OT19UT1BMSVNULDEpOworICAgICAgICB3cml0ZSgiRHUgd2lyc3QgamV0enQgbmljaHQgaW4gZGVyIFRvcGxpc3RlIGF1ZnRhdWNoZW4uXG4iKTsKKyAgICB9CisgICAgU2V0KFBfTk9fVE9QTElTVCxTQVZFfFBST1RFQ1RFRCxGX01PREVfQVMpOworICAgIHJldHVybiAxOworfQorCitpbnQgc2hvd190ZWxuZWdzKHN0cmluZyBhcmcpCit7CisgICAgaWYgKCFhcmcpCisgICAgeworICAgICAgICB3cml0ZSgiRHUgYmVrb21tc3QgQWVuZGVydW5nZW4gRGVpbmVyIEZlbnN0ZXJncm9lc3NlICIrCisgICAgICAgICAgICAgIChRdWVyeVByb3AoUF9UVFlfU0hPVyk/IiI6Im5pY2h0ICIpKyJhbmdlemVpZ3QuXG4iKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIGlmIChtZW1iZXIoKHsiZWluIiwiYW4iLCJhdXMifSksYXJnKT09LTEpCisgICAgeworICAgICAgICB3cml0ZSgiU3ludGF4OiB0ZWxuZWdzIFtlaW58YXVzXVxuIik7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBpZiAoYXJnPT0iZWluIiB8fCBhcmc9PSJhbiIpCisgICAgeworICAgICAgICB3cml0ZSgiRHUgYmVrb21tc3QgIisoUXVlcnlQcm9wKFBfVFRZX1NIT1cpPyIiOiJudW4gIikrCisgICAgICAgICAgICAgICJBZW5kZXJ1bmdlbiBEZWluZXIgRmVuc3Rlcmdyb2Vzc2UgYW5nZXplaWd0LlxuIik7CisgICAgICAgIFNldChQX1RUWV9TSE9XLDEpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgd3JpdGUoIkR1IGJla29tbXN0ICIrKFF1ZXJ5UHJvcChQX1RUWV9TSE9XKT8ibnVuICI6IiIpKworICAgICAgICAgICJBZW5kZXJ1bmdlbiBEZWluZXIgRmVuc3Rlcmdyb2Vzc2UgbmljaHQgIisKKyAgICAgICAgICAoUXVlcnlQcm9wKFBfVFRZX1NIT1cpPyJtZWhyICI6IiIpKyJhbmdlemVpZ3QuXG4iKTsKKyAgICBTZXQoUF9UVFlfU0hPVywwKTsKKyAgICByZXR1cm4gMTsKK30KKworcHJpdmF0ZSBpbnQgc2V0X2tlZXBfYWxpdmUoc3RyaW5nIHN0cikgeworICBpZiAoc3RyID09ICJlaW4iKSB7CisgICAgdGVsbmV0X3RtX2NvdW50ZXIgPSAyNDAgLyBfX0hFQVJUX0JFQVRfSU5URVJWQUxfXzsKKyAgICB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLCBicmVha19zdHJpbmcoCisgICAgICAgICJBbiBEZWluZW4gQ2xpZW50IHdlcmRlbiBqZXR6dCBhbGxlIDQgTWludXRlbiB1bnNpY2h0YmFyZSBEYXRlbiAiCisgICAgICAgICJnZXNjaGlja3QsIHVtIHp1IHZlcmhpbmRlcm4sIGRhc3MgRGVpbmUgVmVyYmluZHVuZyB6dW0gIk1VRE5BTUUKKyAgICAgICAgIiBiZWVuZGV0IHdpcmQuIiwgNzgpKTsKKyAgfQorICBlbHNlIGlmIChzdHIgPT0gImF1cyIpIHsKKyAgICB0ZWxuZXRfdG1fY291bnRlciA9IDA7CisgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSxicmVha19zdHJpbmcoCisgICAgICAgICJEdSBoYXN0IGRhcyBTZW5kZW4gdm9uIHVuc2ljaHRiYXJlbiBEYXRlbiAoS2VlcC1BbGl2ZS1QYWtldGUpIGFuICIKKyAgICAgICAgIkRlaW5lbiBDbGllbnQgYXVzZ2VzY2hhbHRldC4iLDc4KSk7CisgIH0KKyAgZWxzZSB7CisgICAgaWYgKCF0ZWxuZXRfdG1fY291bnRlcikKKyAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksIGJyZWFrX3N0cmluZygKKyAgICAgICAgIkFuIERlaW5lbiBDbGllbnQgd2VyZGVuIGtlaW5lIEtlZXAtQWxpdmUtUGFrZXRlIGdlc2NoaWNrdC4iLDc4KSk7CisgICAgZWxzZQorICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwgYnJlYWtfc3RyaW5nKAorICAgICAgICAiQW4gRGVpbmVuIENsaWVudCB3ZXJkZW4gYWxsZSA0IE1pbnV0ZW4gIiAKKyAgICAgICAgInVuc2ljaHRiYXJlIERhdGVuIGdlc2NoaWNrdCwgZGFtaXQgRGVpbmUgVmVyYmluZHVuZyAiCisgICAgICAgICJ6dW0gIk1VRE5BTUUiIG5pY2h0IGJlZW5kZXQgd2lyZC4iLDc4KSk7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3ByaXZhdGUgaW50IHByaW50X3RlbG5ldF9ydHRpbWUoKSB7CisgIGludCBydHQgPSBRdWVyeVByb3AoUF9URUxORVRfUlRUSU1FKTsKKyAgaWYgKHJ0dD4wKQorICAgIHRlbGxfb2JqZWN0KE1FLCBicmVha19zdHJpbmcoCisgICAgICAiRGllIGxldHp0ZSBnZW1lc3NlbmUgJ3JvdW5kLXRyaXAnIFplaXQgdm9tIE1HIHp1IERlaW5lbSBDbGllbnQgIgorICAgICAgInVuZCB6dXJ1ZWNrIGJldHJ1ZyAiICsgcnR0ICsgIiB1cy4iLDc4KSk7CisgIGVsc2UKKyAgICB0ZWxsX29iamVjdChNRSwgYnJlYWtfc3RyaW5nKAorICAgICAgIkJpc2xhbmcgd3VyZGUgZGllICdyb3VuZC10cmlwJyBaZWl0IHZvbSBNRyB6dSBEZWluZW0gQ2xpZW50ICIKKyAgICAgICJub2NoIG5pY2h0IGdlbWVzc2VuIG9kZXIgRGVpbiBDbGllbnQgdW50ZXJzdHVldHp0IGRpZXNlcyAiCisgICAgICAibmljaHQuIiw3OCkpOworICByZXR1cm4gMTsKK30KKworaW50IHRlbG5ldF9jbWQoc3RyaW5nIHN0cikgeworICBpZiAoIXN0cikgcmV0dXJuIDA7CisgIHN0cmluZyAqYXJncyA9IGV4cGxvZGUoc3RyLCAiICIpOworICBzdHJpbmcgbmV3YXJnczsKKyAgaWYgKHNpemVvZihhcmdzKSA+IDEpCisgICAgbmV3YXJncyA9IGltcGxvZGUoYXJnc1sxLi5dLCAiICIpOworICBlbHNlCisgICAgbmV3YXJncyA9ICIiOworCisgIHN3aXRjaChhcmdzWzBdKQorICB7CisgICAgY2FzZSAia2VlcGFsaXZlIjoKKyAgICAgIHJldHVybiBzZXRfa2VlcF9hbGl2ZShuZXdhcmdzKTsKKyAgICBjYXNlICJydHRpbWUiOgorICAgICAgcmV0dXJuIHByaW50X3RlbG5ldF9ydHRpbWUoKTsKKyAgfQorICByZXR1cm4gMDsKK30KKworaW50IHNwb3R0ZSggc3RyaW5nIHN0ciApCit7CisgICAgX25vdGlmeV9mYWlsKCAiSGllciBpc3QgbmljaHRzLCB3YXMgRHUgdmVyc3BvdHRlbiBrb2VubnRlc3QhXG4iICk7CisgICAgcmV0dXJuIDA7Cit9CisKK2ludCBiZWhhbHRlKHN0cmluZyBzdHIpCit7CisgIG9iamVjdCBvYiwqb2JzOworICBzdHJpbmcgczsKKworICBpZiAoc3RyKQorICB7CisgICAgaWYgKHN0cj09ImFsbGVzIikgeworICAgICAgZmlsdGVyX29iamVjdHMoYWxsX2ludmVudG9yeSgpLCAiU2V0UHJvcCIsIFBfS0VFUF9PTl9TRUxMLCBnZXR1aWQoKSk7CisgICAgICB3cml0ZSgiT2shXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBpZiAoc3RyPT0ibmljaHRzIikgeworICAgICAgZmlsdGVyX29iamVjdHMoYWxsX2ludmVudG9yeSgpLCAiU2V0UHJvcCIsIFBfS0VFUF9PTl9TRUxMLCAwKTsKKyAgICAgIHdyaXRlKCJPayFcbiIpOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIGlmICghc2l6ZW9mKG9icz1maW5kX29icyhzdHIsUFVUX0dFVF9OT05FKSkpCisgICAgeworICAgICAgX25vdGlmeV9mYWlsKCJBYmVyIHNvd2FzIGhhc3QgRHUgbmljaHQgZGFiZWkhXG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBlbHNlIG9iPW9ic1swXTsKKworICAgIGlmIChvYi0+UXVlcnlQcm9wKFBfS0VFUF9PTl9TRUxMKT09Z2V0ZXVpZChNRSkpCisgICAgICAgIG9iLT5TZXRQcm9wKFBfS0VFUF9PTl9TRUxMLDApOworICAgIGVsc2UKKyAgICAgICAgb2ItPlNldFByb3AoUF9LRUVQX09OX1NFTEwsZ2V0ZXVpZChNRSkpOworCisgICAgLy8gZXJuZXV0IGFiZnJhZ2VuLCBkYSBzaWNoIGRlciBXZXJ0IG5pY2h0IGdlYWVuZGVydCBoYWJlbiBtdXNzCisgICAgaWYgKG9iLT5RdWVyeVByb3AoUF9LRUVQX09OX1NFTEwpPT1nZXRldWlkKE1FKSkKKyAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKHNwcmludGYoIk9rLCBEdSB3aXJzdCAlcyBqZXR6dCBiZWkgJ3ZlcmthdWZlIGFsbGVzJyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiZWhhbHRlbi5cbiIsb2ItPm5hbWUoV0VOKSksNzgpKTsKKyAgICBlbHNlCisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhzcHJpbnRmKCJPaywgRHUgd2lyc3QgJXMgYmVpbSBuYWVjaHN0ZW4gJ3ZlcmthdWZlICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFsbGVzJyBtaXR2ZXJrYXVmZW4hXG4iLG9iLT5uYW1lKFdFTikpLDc4KSk7CisKKyAgICByZXR1cm4gMTsKKyAgfQorICBzPW1ha2VfaW52bGlzdChNRSxmaWx0ZXIoYWxsX2ludmVudG9yeShNRSksIydfY2hlY2tfa2VlcCkpOyAvLycpKTsKKyAgTW9yZShzKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X2xlcCgpCit7CisgIGludCB2YWw7CisgIHZhbCA9IExFUE1BU1RFUi0+UXVlcnlMRVAoKTsKKyAgU2V0KCBQX0xFUCwgdmFsICk7CisgIHJldHVybiB2YWw7Cit9CisKK3N0YXRpYyBtaXhlZCBfc2V0X2ZyYXRlcm5pdGFzZG9ub2FyY2htYWdvcnVtKG1peGVkIGFyZykKK3sKKyAgaWYgKCFpbnRwKGFyZykpIHJldHVybiAtMTsKKworICBpZiAoKCFwcmV2aW91c19vYmplY3QoMSl8fG9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgxKSkhPUZBT19NQVNURVIpICYmIAorICAgICAgKCF0aGlzX2ludGVyYWN0aXZlKCkgfHwgIUlTX0FSQ0godGhpc19pbnRlcmFjdGl2ZSgpKSkpCisgICAgcmV0dXJuIC0xOworCisgIGlmICghaW50cChhcmcpKSByZXR1cm4gLTE7CisKKyAgbG9nX2ZpbGUoImZhby9QX0ZBTyIsc3ByaW50ZigiJXMgLSAlcyBQX0ZBTyBnZXNldHp0IGF1ZiAlT1xuIiwKKyAgICAgICAgZHRpbWUodGltZSgpKSxxdWVyeV9yZWFsX25hbWUoKSxhcmcpICk7CisgIHJldHVybiBTZXQoUF9GQU8sYXJnKTsKK30KKworbm9tYXNrIHZvaWQgc2V0X3JlYWxpcChzdHJpbmcgc3RyKQoreworICBpZihwcmV2aW91c19vYmplY3QoKSAmJiBzdHJzdHIob2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpLCIvc2VjdXJlIik9PTApCisgIHsKKyAgICByZWFsaXA9c3RyOworICB9Cit9CisKK25vbWFzayBzdHJpbmcgcXVlcnlfcmVhbGlwKCkKK3sKKyAgcmV0dXJuIHJlYWxpcCA/IHJlYWxpcCA6ICIiOworfQorCittaXhlZCBfcXVlcnlfbmV0ZGVhZF9lbnYoKSB7CisgICAgICAgIHJldHVybiBuZGVhZF9sb2NhdGlvbiB8fCBuZGVhZF9sX2ZpbGVuYW1lOworfQpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9jaGFubmVsLmMgYi9zdGQvcGxheWVyL2NoYW5uZWwuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45Zjg1MTJhCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9jaGFubmVsLmMKQEAgLTAsMCArMSw1NzkgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBjaGFubmVsLmMgLS0gY2hhbm5lbCBjbGllbnQKKy8vCisvLyAkSWQ6IGNoYW5uZWwuYyA5NDA0IDIwMTUtMTItMTMgMDA6MjE6NDRaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHV0aWwuaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGl2aW5nL2NvbW0uaD4KKyNpbmNsdWRlIDxwbGF5ZXIuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvY29tbS5oPgorI2luY2x1ZGUgPGRhZW1vbi5oPgorI2luY2x1ZGUgPHBsYXllci9nbWNwLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHN5c19kZWJ1Zy5oPgorI2luY2x1ZGUgPHJlZ2V4cC5oPgorCisjZGVmaW5lIFBfU1dBUF9DSEFOTkVMUyAgInN3YXBfY2hhbm5lbHMiCisjZGVmaW5lIFBfQ0hBTk5FTF9TSE9SVCAgInNob3J0X2NoYW5uZWxzIgorCisjZGVmaW5lIENIQU5ORUxDTURTICAgICAgIlsjQCUkJigpPD5hLXpBLVowLTlcXC1dIgorCisjZGVmaW5lIERFRkFVTFRfQ0hBTk5FTFMgKHsiQWJlbnRldWVyIiwgIkFuZmFlbmdlciIsIkdyYXRzIiwiVG9kIiwgIlpUIn0pCisjZGVmaW5lIERFRkFVTFRfU0hPUlRDVVRTIFwKKyhbICAgICAgICAgICAgICAgICAgICAgXAorICJiIjoiQWJlbnRldWVyIiwgICAgICBcCisgImEiOiJBbGxnZW1laW4iLCAgICAgIFwKKyAiQiI6IkJlaWxlaWQiLCAgICAgICAgXAorICJxIjoiRC1jaGF0IiwgICAgICAgICBcCisgIkciOiJHcmF0cyIsICAgICAgICAgIFwKKyAiTSI6Ik1vZXJkZXIiLCAgICAgICAgXAorICJoIjoiU2VoZXIiLCAgICAgICAgICBcCisgIlQiOiJUb2QiLCAgICAgICAgICAgIFwKK10pCisKKyNkZWZpbmUgV0laQVJEX1NIT1JUQ1VUUyBcCisoWyAgICAgICAgICAgICAgICAgICAgIFwKKyAiUCI6IkQtY29kZSIsICAgICAgICAgXAorICJEIjoiRGVidWciLCAgICAgICAgICBcCisgIk8iOiJJbnRlcmNvZGUiLCAgICAgIFwKKyAiSSI6IkludGVybXVkIiwgICAgICAgXAorICJtIjoiTWFnaWVyIiwgICAgICAgICBcCitdKQorCisKK3ByaXZhdGUgbm9zYXZlIG1hcHBpbmcgc2hvcnRjdXQ7Citwcml2YXRlIG5vc2F2ZSBpbnQgY19zdGF0dXM7CisKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgU2V0KFBfQ0hBTk5FTFMsIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0NIQU5ORUxTLCBERUZBVUxUX0NIQU5ORUxTKTsKKyAgU2V0KFBfU1dBUF9DSEFOTkVMUywgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfU1REX0NIQU5ORUwsICJBbGxnZW1laW4iKTsKKyAgU2V0KFBfU1REX0NIQU5ORUwsIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0NIQU5ORUxfU0hPUlQsIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0NIQU5ORUxfU0hPUlQsIERFRkFVTFRfU0hPUlRDVVRTCisgICAgICArIChJU19MRUFSTkVSKHRoaXNfb2JqZWN0KCkpID8gV0laQVJEX1NIT1JUQ1VUUyA6IChbXSkpKTsKK30KKworc3RhdGljIG1peGVkIF9xdWVyeV9sb2NhbGNtZHMoKQoreworICByZXR1cm4gKHsoeyItIiwiQ2hhbm5lbFBhcnNlciIsIDEsIDB9KSwKKyAgICAgICAgICAgKHsiZWJlbmUiLCAiQ2hhbm5lbEFkbWluIiwgMCwgMH0pLAorICAgICAgICAgICAoeyJlYmVuZW4iLCAiQ2hhbm5lbEFkbWluIiwgMSwgMH0pLAorICAgICAgICAgfSk7Cit9CisKK21peGVkIFJlZ2lzdGVyQ2hhbm5lbHMoKQoreworICBtaXhlZCBlcnI7CisgIGlmKGV4dGVybl9jYWxsKCkgJiYKKyAgICAgcHJldmlvdXNfb2JqZWN0KCkgIT0gZmluZF9vYmplY3QoQ0hNQVNURVIpKSByZXR1cm47CisgIGNfc3RhdHVzID0gMDsKKyAgc2hvcnRjdXQgPSBRdWVyeVByb3AoUF9DSEFOTkVMX1NIT1JUKTsKKyAgU2V0UHJvcChQX0NIQU5ORUxTLCBtYXAoUXVlcnlQcm9wKFBfQ0hBTk5FTFMpIHx8ICh7fSksCisJIydsb3dlcl9jYXNlKSk7CisgIGVyciA9IGZpbHRlcihRdWVyeVByb3AoUF9DSEFOTkVMUyksCisgICAgICAgICBzeW1ib2xfZnVuY3Rpb24oImpvaW4iLCBDSE1BU1RFUiksCisgICAgICAgICB0aGlzX29iamVjdCgpKTsKKyAgaWYoUXVlcnlQcm9wKFBfTEVWRUwpIDwgNSkgcmV0dXJuIGVycjsKKyAgd2hpbGUoc2l6ZW9mKGVycikpIHsKKyAgICBDSE1BU1RFUi0+bmV3KGVyclswXSwgdGhpc19vYmplY3QoKSk7CisgICAgZXJyWzAuLjBdID0gKHt9KTsKKyAgfQorICByZXR1cm4gZXJyOworfQorCittaXhlZCBSZW1vdmVDaGFubmVscygpCit7CisgIGNsb3N1cmUgY2w7CisgIG1peGVkIGVycj0oe30pOworICBpZihleHRlcm5fY2FsbCgpICYmCisgICAgIHByZXZpb3VzX29iamVjdCgpICE9IGZpbmRfb2JqZWN0KENITUFTVEVSKSkgcmV0dXJuOworICBpZighY19zdGF0dXMpIGNfc3RhdHVzID0gMTsKKyAgZWxzZSByZXR1cm4gKHt9KTsKKyAgY2w9c3ltYm9sX2Z1bmN0aW9uKCJsZWF2ZSIsIENITUFTVEVSKTsKKyAgaWYgKGNsb3N1cmVwKGNsKSkgeworICAgICAgZXJyID0gZmlsdGVyKFF1ZXJ5UHJvcChQX0NIQU5ORUxTKSwgY2wsIHRoaXNfb2JqZWN0KCkpOworICAgICAgU2V0UHJvcChQX0NIQU5ORUxTLCBRdWVyeVByb3AoUF9DSEFOTkVMUykgLSBlcnIpOworICB9CisgIHJldHVybiBlcnI7Cit9CisKK3ZhcmFyZ3MgcHJpdmF0ZSBzdHJpbmcgZ2V0TmFtZShtaXhlZCB4LCBpbnQgZmFsbCkgeworICAKKyAgbWl4ZWQgbyA9IGNsb3N1cmVwKHgpID8gcXVlcnlfY2xvc3VyZV9vYmplY3QoeCkgOiB4OworICBpZihzdHJpbmdwKG8pICYmIHNpemVvZihvKSAmJiAoeCA9IGZpbmRfb2JqZWN0KG8pKSkgCisgICAgbyA9IHg7CisgIAorICAvLyBPYmpla3RlCisgIGlmIChvYmplY3RwKG8pKSB7CisgICAgLy8gTWFnaWVyIHNlaGVuIHVuc2ljaHRiYXJlIG5pY2h0IG51ciBhbHMgIkplbWFuZCIKKyAgICBpZiAoby0+UXVlcnlQcm9wKFBfSU5WSVMpICYmIElTX0xFQVJOSU5HKHRoaXNfb2JqZWN0KCkpKQorICAgICAgcmV0dXJuICIoIitjYXBpdGFsaXplKGdldHVpZChvKSkrIikiOworICAgIC8vIEZyb2VzY2hlIG1pdCBOYW1lbiB2ZXJzb3JnZW4uCisgICAgaWYgKG8tPlF1ZXJ5UHJvcChQX0ZST0cpKQorICAgICAgcmV0dXJuICJGcm9zY2ggIitjYXBpdGFsaXplKGdldHVpZChvKSk7CisgICAgLy8gRGVmYXVsdCAoVW5zaWNodGJhcmUgYWxzICJKZW1hbmQiIChzLiBOYW1lKCkpKQorICAgIHJldHVybiBvLT5OYW1lKGZhbGwsIDIpfHwiPFVuYmVrYW5udD4iOworICB9CisgIC8vIFN0cmluZ3MKKyAgZWxzZSBpZiAoc3RyaW5ncChvKSAmJiBzaXplb2YobykpIHsKKyAgICBpZiAob1swXSA9PSAnLycpIHsKKyAgICAgIC8vIHVuc2ljaHRiYXJlIE9iamVrdGUuLi4KKyAgICAgIGludCBwID0gc3Ryc3RyKG8sICIkIik7CisgICAgICBpZiAocCAhPSAtMSkgeworCS8vIE1hZ2llciBpbSBNYWdpZXJtb2R1cyBrcmllZ2VuIGRlbiBSZWFsbmFtZW4sIGFuZGVyZSBuaWNodC4KKwlpZiAoSVNfTEVBUk5JTkcodGhpc19vYmplY3QoKSkpCisJICByZXR1cm4gb1sxLi5wLTFdOworCWVsc2UKKwkgIHJldHVybiBvW3ArMS4uXTsKKyAgICAgIH0KKyAgICAgIGVsc2UKKwkvLyBkb2NoIG5pY2h0IHVuc2ljaHRiYXIKKwlyZXR1cm4gKGZhbGwgPT0gV0VTU0VOID8gbysicyIgOiBvKTsKKyAgICB9CisgICAgZWxzZQorICAgICAgLy8gbmljaHQgdW5zaWNodGJhcgorICAgICAgcmV0dXJuIChmYWxsID09IFdFU1NFTiA/IG8rInMiIDogbyk7CisgIH0KKyAgLy8gRmFsbC10aHJvdWdoCisgIHJldHVybiAiPFVuYmVrYW5udD4iOworfQorCisvLyA8bm9uaW50PiB1bnRlcmRydWVja3QgZGllIEFVc2dhYmUgYW4gZGVuIFNwaWVsZXIgdW5kIGxpZWZlcnQgZGVuIFRleHQKKy8vIHp1cnVlY2suIFdpcmQgbnVyIGZ1ZXIgZGllIEViZW5lbmhpc3RvcnkgYmVudXR6dC4gCitzdHJpbmcgQ2hhbm5lbE1lc3NhZ2UobWl4ZWQqIG1zZywgaW50IG5vbmludCkKK3sKKyAgc3RyaW5nIGNoYW5uZWxfbWVzc2FnZTsKKyAgc3RyaW5nIGNoYW5uZWw9bXNnWzBdOworICBvYmplY3Qgc2VuZGVyPW1zZ1sxXTsKKyAgc3RyaW5nIG1lc3NhZ2U9bXNnWzJdOworICBpbnQgbXNnX3R5cGUgPSBtc2dbM107CisKKyAgaWYgKCBwcmV2aW91c19vYmplY3QoKSAhPSBmaW5kX29iamVjdChDSE1BU1RFUikgJiYKKyAgICAgICBwcmV2aW91c19vYmplY3QoKSAhPSBNRSApCisgICAgICByZXR1cm4gMDsKKworICBzdHJpbmcgc2VuZGVyX25hbWUgPSBnZXROYW1lKHNlbmRlciwgbXNnX3R5cGUgPT0gTVNHX0dFTU9URSA/IFdFU1NFTiA6IFdFUik7CisgIGludCBwcmVwZW5kX2luZGVudF9mbGFnPVF1ZXJ5UHJvcChQX01FU1NBR0VfUFJFUEVORCkgPyBCU19QUkVQRU5EX0lOREVOVCA6IDA7CisgIHN3aXRjaChtc2dfdHlwZSkgeworICBjYXNlIE1TR19FTVBUWToKKyAgICBjaGFubmVsX21lc3NhZ2U9IG1lc3NhZ2UrIlxuIjsKKyAgICBicmVhazsKKyAgY2FzZSBNU0dfR0VNT1RFOgorICBjYXNlIE1TR19FTU9URToKKyAgICBjaGFubmVsX21lc3NhZ2UgPSBicmVha19zdHJpbmcoc2VuZGVyX25hbWUgKyAiICIrIG1lc3NhZ2UrIl0iLAorICAgICAgICAgICAgICAgICAgIDc4LCBzcHJpbnRmKCJbJXM6IiwgY2hhbm5lbCksCisgICAgICAgICAgICAgICAgICAgQlNfSU5ERU5UX09OQ0V8cHJlcGVuZF9pbmRlbnRfZmxhZyk7CisgICAgYnJlYWs7CisgIGNhc2UgTVNHX1NBWToKKyAgZGVmYXVsdDoKKyAgICBzdHJpbmcgcHJlc2F5PXNwcmludGYoIlslczolc10gIiwgY2hhbm5lbCwgc2VuZGVyX25hbWUpOworICAgIGNoYW5uZWxfbWVzc2FnZSA9IGJyZWFrX3N0cmluZyhtZXNzYWdlLCBtYXgoNzgsc2l6ZW9mKHByZXNheSkrMTApLAorICAgICAgICAgICAgICAgICAgIHByZXNheSwgcHJlcGVuZF9pbmRlbnRfZmxhZyk7CisgICAgYnJlYWs7CisgIH0KKyAgaWYobm9uaW50KQorICAgIHJldHVybiBjaGFubmVsX21lc3NhZ2U7CisKKyAgLy8gV2VubiBHTUNQIHNpY2ggdW0gVWViZXJ0cmFndW5nIGRlciBOYWNocmljaHQga3VlbW1lcnQsIHdpcmQgUmVjZWl2ZU1zZygpCisgIC8vIG5pY2h0IG1laHIgYXVmZ2VydWZlbi4KKyAgaWYgKEdNQ1BfQ2hhbm5lbChjaGFubmVsX21lc3NhZ2UsIGNoYW5uZWwsIHNlbmRlcl9uYW1lKSAhPSAxKQorICB7CisgICAgLy8gRGVyIEViZW5lbm5hbWUgbXVzcyBpbiBLbGVpbmJ1Y2hzdGFiZW4gdWViZXJnZWJlbiB3ZXJkZW4sIGRhbWl0IGRpZQorICAgIC8vIElnbm9yaWVyZXBydWVmdW5nIGZ1bmt0aW9uaWVydC4gRGllIGlnbm9yaWVyZXN0cmluZ3Mgc2luZCBuYWVtbGljaCBhbGxlCisgICAgLy8ga2xlaW5nZXNjaHJpZWJlbi4KKyAgICBSZWNlaXZlTXNnKGNoYW5uZWxfbWVzc2FnZSwgCisgICAgICAgICAgICAgICBNVF9DT01NfE1UX0ZBUnxNU0dfRE9OVF9TVE9SRXxNU0dfRE9OVF9XUkFQLAorICAgICAgICAgICAgICAgTUFfQ0hBTk5FTCIuIiArIGxvd2VyX2Nhc2UoY2hhbm5lbCksIDAsIHNlbmRlcik7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3ByaXZhdGUgdm9pZCBjcmVhdGVMaXN0KHN0cmluZyBuLCBtaXhlZCBhLCBtaXhlZCBtLCBtaXhlZCBsKQoreworICBpbnQgcG9zOyBzdHJpbmcgc2gsICptZW07CisgIGlmKChwb3MgPSBtZW1iZXIobWFwKG1fdmFsdWVzKHNob3J0Y3V0KSwgIydsb3dlcl9jYXNlLyonKi8pLCBuKSkgIT0gLTEpCisgICAgc2ggPSBtX2luZGljZXMoc2hvcnRjdXQpW3Bvc107CisgIGVsc2Ugc2ggPSAiIjsKKyAgbWVtPW1hcChhW0lfTUVNQkVSXSwjJ2dldE5hbWUvKicqLywgV0VSKTsKKyAgbWVtLT0oeyI8TWFzdGVSPiJ9KTsKKyAgbCArPSAoeyBzcHJpbnRmKCIlLTEyLjEyJy4ncyAlY1slLTEuMXNdICV8MTIuMTInICdzICglLXwzJyAnZCkgJS00Mi40MnNcbiIsCisgICAgICAgICAgICAgICAgICBhW0lfTkFNRV0sIChtZW1iZXIobSwgbikgIT0gLTEgPyAnKicgOiAnICcpLCBzaCwKKyAgICAgICAgICAgICAgICAgIGFbSV9NQVNURVJdID8KKyAgICAgICAgICAgICAgICAgIGdldE5hbWUoYVtJX01BU1RFUl0pIDogZ2V0TmFtZShhW0lfQUNDRVNTXSksCisgICAgICAgICAgICAgICAgICBzaXplb2YobWVtKSwKKyAgICAgICAgICAgIChjbG9zdXJlcChhW0lfSU5GT10pICYmIG9iamVjdHAocXVlcnlfY2xvc3VyZV9vYmplY3QoYVtJX0lORk9dKSkpID8KKyAgICAgICAgICAgICAgICAgIGZ1bmNhbGwoYVtJX0lORk9dKSB8fCAiLSBLZWluZSBCZXNjaHJlaWJ1bmcgLSIgOgorICAgICAgICAgICAgICAgICAgKHN0cmluZ3AoYVtJX0lORk9dKSA/IGFbSV9JTkZPXSA6ICItIEtlaW5lIEJlc2NocmVpYnVuZyAtIikKKyAgICAgICAgKSB9KTsKK30KKworcHJpdmF0ZSBtaXhlZCBnZXRDaGFubmVsKHN0cmluZyBjaCkKK3sKKyAgbWl4ZWQgZmY7CisgIGlmKCFzaXplb2YoY2gpKSBjaCA9IFF1ZXJ5UHJvcChQX1NURF9DSEFOTkVMKTsKKyAgaWYoc2hvcnRjdXQgJiYgc2hvcnRjdXRbY2hdKSBjaCA9IHNob3J0Y3V0W2NoXTsKKyAgcmV0dXJuIENITUFTVEVSLT5maW5kKGNoLCB0aGlzX29iamVjdCgpKTsKK30KKworI2lmbmRlZiBERUJVRworI2RlZmluZSBERUJVRyh4KSAgICAgICAgaWYgKGZ1bmNhbGwoc3ltYm9sX2Z1bmN0aW9uKCdmaW5kX3BsYXllciksInplc3N0cmEiKSlcCisgICAgICAgICAgdGVsbF9vYmplY3QoZnVuY2FsbChzeW1ib2xfZnVuY3Rpb24oJ2ZpbmRfcGxheWVyKSwiemVzc3RyYSIpLFwKKwkgICAgICAgICAgICAgICJNREJHOiAiK3grIlxuIikKKyNlbmRpZgoraW50IENoYW5uZWxQYXJzZXIoc3RyaW5nIGFyZ3MpCit7CisgIG1peGVkIGNoLCBjbWQsIHRtcDsKKyAgaW50IHBvcywgdHlwZSwgZXJyOworICBzdHJpbmcgdHh0OworICBjbWQgPSBxdWVyeV92ZXJiKCk7CisgIGFyZ3MgPSBfdW5wYXJzZWRfYXJncygpOworICBub3RpZnlfZmFpbCgiQmVudXR6dW5nOiAtPEViZW5lPlsgXVsnfDp8O108VGV4dD5cbiIKKyAgICAgICAgICAgICAgIiAgICAgICAgICAgLTxFYmVuZT5bK3wtfD98IXwqXVxuIgorICAgICAgICAgICAgICAiICAgICAgICAgICAtP1xuIik7CisgIGlmKCFjbWQgJiYgIWFyZ3MpIHJldHVybiAwOworICBpZighYXJncykgYXJncyA9ICIiOworICBjbWQgPSBjbWRbMS4uXTsKKyAgaWYoc2l6ZW9mKGNtZCA9IHJlZ2V4cGxvZGUoY21kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiXiIgQ0hBTk5FTENNRFMgIioiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoWystXXxcXCF8XFw/fFxcKikqIikpID4gMSkKKyAgeworICAgIC8vei5CLiBjbWQ9ICh7IiIsImFsbGdlbWVpbiIsIjp0ZXN0ZXQifSkKKyAgICBpZihzaXplb2YoY21kWzFdKSA+IDEgJiYKKyAgICAgICBzdHJzdHIoIistPyEqIiwgY21kWzFdWzwxLi48MV0pID4gLTEpCisgICAgICB0bXAgPSBjbWRbMV1bMC4uPDJdOworICAgIGVsc2UKKyAgICAgIHRtcCA9IGNtZFsxXTsKKyAgICBpZihjbWRbMV0gIT0gIj8iICYmIGNtZFsxXSAhPSAiISIpCisgICAgICBpZihwb2ludGVycChjaCA9IGdldENoYW5uZWwodG1wKSkpCisgICAgICB7CisgICAgICAgIG5vdGlmeV9mYWlsKCJEaWVzZSBBbmdhYmUgd2FyIG5pY2h0IGVpbmRldXRpZyEgIgorICAgICAgICAgICAgICAgICAgICAiRm9sZ2VuZGUgRWJlbmVuIHBhc3NlbjpcbiIKKyAgICAgICAgICAgICAgICAgICAgK2ltcGxvZGUoY2gsICIsICIpKyJcbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICAgIGVsc2UgaWYoIWNoKSByZXR1cm4gKG5vdGlmeV9mYWlsKCJEaWUgRWJlbmUgJyIrdG1wCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIicgZ2lidCBlcyBuaWNodCFcbiIpLCAwKTsKKyAgICAvL0RFQlVHKHNwcmludGYoIkNoYW5DbWQ6ICVPXG4iLGNtZCkpOworICAgIGlmIChzaXplb2YoY21kWzFdKSkgeworICAgICAgc3dpdGNoKGNtZFsxXVs8MV0pIHsKKyAgICBjYXNlICcrJzoKKyAgICAgIHN3aXRjaChDSE1BU1RFUi0+am9pbihjaCwgdGhpc19vYmplY3QoKSkpCisgICAgICB7CisgICAgICBjYXNlIEVfQUNDRVNTX0RFTklFRDoKKyAgICAgICAgbm90aWZ5X2ZhaWwoIkR1IGRhcmZzdCBhbiBkaWUgRWJlbmUgJyIrY2grIicgbmljaHQgaGVyYW4uXG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgICBjYXNlIEVfQUxSRUFEWV9KT0lORUQ6CisgICAgICAgIG5vdGlmeV9mYWlsKCJEdSBoYXN0IGRpZXNlIEViZW5lIHNjaG9uIGJldHJldGVuIVxuIik7CisgICAgICAgIHJldHVybiAwOworICAgICAgZGVmYXVsdDogYnJlYWs7CisgICAgICB9CisgICAgICB3cml0ZSgiRHUgYmV0cml0dHN0IGRpZSBFYmVuZSAnIitjaCsiJy5cbiIpOworICAgICAgaWYobWVtYmVyKFF1ZXJ5UHJvcChQX0NIQU5ORUxTKSwgY2ggPSBsb3dlcl9jYXNlKGNoKSkgPT0gLTEpCisgICAgICAgIFNldFByb3AoUF9DSEFOTkVMUywgUXVlcnlQcm9wKFBfQ0hBTk5FTFMpICsgKHsgY2ggfSkpOworICAgICAgcmV0dXJuIDE7CisgICAgY2FzZSAnLSc6CisgICAgICBzd2l0Y2goQ0hNQVNURVItPmxlYXZlKGNoLCB0aGlzX29iamVjdCgpKSkKKyAgICAgIHsKKyAgICAgIGNhc2UgRV9BQ0NFU1NfREVOSUVEOgorICAgICAgICB3cml0ZSgiRHUga2FubnN0IGRpZSBFYmVuZSAnIitjaCsiJyBuaWNodCB2ZXJsYXNzZW4uXG4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIEVfTk9UX01FTUJFUjoKKyAgICAgICAgd3JpdGUoIldpZSB3aWxsc3QgRHUgZWluZSBFYmVuZSB2ZXJsYXNzZW4sIHdlbGNoZSBEdSBuaWNodCAiCisgICAgICAgICAgICAgICJiZXRyZXRlbiBoYXN0P1xuIik7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgd3JpdGUoIkR1IHZlcmxhZXNzdCBkaWUgRWJlbmUgJyIrY2grIicuXG4iKTsKKyAgICAgICAgU2V0UHJvcChQX0NIQU5ORUxTLCBRdWVyeVByb3AoUF9DSEFOTkVMUykgLSAoeyBsb3dlcl9jYXNlKGNoKSwgY2ggfSkpOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIHJldHVybiAxOworICAgIGNhc2UgJyEnOgorICAgIGNhc2UgJz8nOgorICAgIHsKKyAgICAgIG1hcHBpbmcgbDsKKyAgICAgIGlmKG1hcHBpbmdwKGwgPSBDSE1BU1RFUi0+bGlzdCh0aGlzX29iamVjdCgpKSkpCisgICAgICAgIGlmKHN0cmluZ3AoY2gpICYmIHNpemVvZihjaCkgJiYgcG9pbnRlcnAobFtjaCA9IGxvd2VyX2Nhc2UoY2gpXSkpCisgICAgICAgIHsKKyAgICAgICAgICBpbnQgYzsgb2JqZWN0IG87IHN0cmluZyBuOyBzdHJpbmcgKm07CisgICAgICAgICAgbT1zb3J0X2FycmF5KG1hcChsW2NoXVtJX01FTUJFUl0sIydnZXROYW1lLyonKi8sIFdFUiksIyc+LyonKi8pOworICAgICAgICAgIG0tPSh7IjxNYXN0ZVI+In0pOworICAgICAgICAgIHdyaXRlKGxbY2hdW0lfTkFNRV0rIiwgIitmdW5jYWxsKGxbY2hdW0lfSU5GT10pKyIuXG4iKTsKKyAgICAgICAgICB3cml0ZSgiRHUgc2llaHN0ICIrKChjID0gc2l6ZW9mKG0pKSA+IDAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gKGMgPT0gMSA/ICJlaW4gR2VzaWNodCIgOiBjKyIgR2VzaWNodGVyIikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogIm5pZW1hbmRlbiIpKyIgYXVmIGRlciBFYmVuZSAnIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArbFtjaF1bSV9OQU1FXSsiJzpcbiIpOworICAgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhpbXBsb2RlKG0sIiwgIiksIDc4KSk7CisgICAgICAgICAgd3JpdGUoKGxbY2hdW0lfTUFTVEVSXSA/CisgICAgICAgICAgICAgICAgIGdldE5hbWUobFtjaF1bSV9NQVNURVJdKSA6IGdldE5hbWUobFtjaF1bSV9BQ0NFU1NdLCBXRVIpKQorICAgICAgICAgICAgICAgICsiIGhhdCBkYXMgU2FnZW4gYXVmIGRpZXNlciBFYmVuZS5cbiIpOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgIG1peGVkIGxpc3Q7IGxpc3QgPSAoe30pOworICAgICAgICAgIGlmKGNtZFsxXVs8MV0gPT0gJyEnKQorICAgICAgICAgICAgbCAtPSBta21hcHBpbmcobV9pbmRpY2VzKGwpIC0gUXVlcnlQcm9wKFBfQ0hBTk5FTFMpKTsKKyAgICAgICAgICB3YWxrX21hcHBpbmcobCwgIydjcmVhdGVMaXN0LyonKi8sIFF1ZXJ5UHJvcChQX0NIQU5ORUxTKSwgJmxpc3QpOworICAgICAgICAgIGxpc3QgPSBzb3J0X2FycmF5KGxpc3QsICMnPi8qJyovKTsKKyAgICAgICAgICB0eHQgPSBzcHJpbnRmKCIlLTEyLjEyJyAncyAgW0FdICV8MTInICdzICglLTMnICdzKSAlLTQyLjQyc1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICJOYW1lIiwgIkVpZ25lciIsICJTcCIsICJCZXNjaHJlaWJ1bmciKQorICAgICAgICAgICAgICArICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIgorICAgICAgICAgICAgICArICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIgorICAgICAgICAgICAgICArIGltcGxvZGUobGlzdCwgIiIpOworICAgICAgICAgIE1vcmUodHh0KTsKKyAgICAgICAgfQorICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIGNhc2UgJyonOgorICAgIHsKKyAgICAgIG1peGVkIGhpc3Q7IGludCBhbW91bnQ7CisgICAgICBpZighcG9pbnRlcnAoaGlzdCA9IENITUFTVEVSLT5oaXN0b3J5KGNoLCB0aGlzX29iamVjdCgpKSkgCisJCSAgICAgIHx8ICFzaXplb2YoaGlzdCkpCisgICAgICB7CisgICAgICAgIHdyaXRlKCJFcyBpc3Qga2VpbmUgR2VzY2hpY2h0ZSBmdWVyICciK2NoKyInIHZlcmZ1ZWdiYXIuXG4iKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgICAKKyAgICAgIC8vKFplc3N0cmEpIGNtZCBoYXQgb2ZmZW5iYXIgaW1tZXIgMyBFbGVtZW50ZS4uLgorICAgICAgLy9iZWkgLWFsbCogKHsiIiwiYWxsKiIsIiJ9KQorICAgICAgLy9iZWkgLWFsbCoxMCAoeyIiLCJhbGwqLCIxMCJ9KQorICAgICAgLy9hbHNvIGlzdCBiZWkgLWFsbCogYW1vdW50IGltbWVyID09IDAgdW5kIGVzIGZ1bmt0aW9uaWVydCBlaGVyIHp1ZmFlbGxpZy4KKyAgICAgIC8qaWYoc2l6ZW9mKGNtZCkgPiAyKSAKKyAgICAgICAgYW1vdW50ID0gdG9faW50KGNtZFsyXSk7CisgICAgICBlbHNlIAorICAgICAgICBhbW91bnQ9c2l6ZW9mKGhpc3QpOyovCisgICAgICBhbW91bnQ9dG9faW50KGNtZFsyXSk7CisgICAgICBpZiAoYW1vdW50IDw9IDAgfHwgYW1vdW50ID49IHNpemVvZihoaXN0KSkKKyAgICAgICAgYW1vdW50PXNpemVvZihoaXN0KTsKKworICAgICAgdHh0ID0gIkZvbGdlbmRlcyBpc3QgYXVmICciK2NoKyInIHBhc3NpZXJ0OlxuIgorICAgICAgICAgICsgaW1wbG9kZShtYXAoaGlzdFs8YW1vdW50Li5dLCAjJ0NoYW5uZWxNZXNzYWdlLyonKi8sIDEpLCAiIik7CisgICAgICBNb3JlKHR4dCk7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgZGVmYXVsdDoKKyAgICAgIGJyZWFrOworICAgIH0KKyAgICB9CisgIH0KKyAgaWYoc2l6ZW9mKGNtZCA9IGltcGxvZGUoY21kWzIuLl0sICIiKSkpCisgICAgIGFyZ3MgPSBjbWQgKyAoc2l6ZW9mKGFyZ3MpID8gIiAiIDogIiIpICsgYXJnczsKKworICAvLyBLT250cm9sbGNoYXJzIGF1c2ZpbHRlcm4uCisgIGFyZ3MgPSByZWdyZXBsYWNlKGFyZ3MsIltbOmNudHJsOl1dIiwiIixSRV9QQ1JFfFJFX0dMT0JBTCk7CisgIGlmKCFzaXplb2YoYXJncykpIHJldHVybiAwOworCisgIC8vV2VubiBjbWQgbGVlciBpc3Q6IE1TR19TQVkKKyAgaWYgKCFzaXplb2YoY21kKSkgdHlwZT1NU0dfU0FZOworICBlbHNlIHsKKyAgICBzd2l0Y2goY21kWzBdKQorICAgIHsKKyAgICBjYXNlICc6JyA6CisgICAgICB0eXBlID0gTVNHX0VNT1RFOworICAgICAgYXJncyA9IGFyZ3NbMS4uXTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgJzsnIDoKKyAgICAgIHR5cGUgPSBNU0dfR0VNT1RFOworICAgICAgYXJncyA9IGFyZ3NbMS4uXTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgJ1wnJzoKKyAgICAgIGFyZ3MgPSBhcmdzWzEuLl07CisgICAgZGVmYXVsdCAgOiB0eXBlID0gTVNHX1NBWTsgYnJlYWs7CisgICAgfQorICB9CisgIGlmKCFjaCB8fCAhc2l6ZW9mKGNoKSkgY2ggPSBRdWVyeVByb3AoUF9TVERfQ0hBTk5FTCk7CisgIGlmKChlcnIgPSBDSE1BU1RFUi0+c2VuZChjaCwgdGhpc19vYmplY3QoKSwgYXJncywgdHlwZSkpIDwgMCkKKyAgICBpZighKGVyciA9IENITUFTVEVSLT5qb2luKGNoLCB0aGlzX29iamVjdCgpKSkpCisgICAgeworICAgICAgaWYobWVtYmVyKFF1ZXJ5UHJvcChQX0NIQU5ORUxTKSwgY2ggPSBsb3dlcl9jYXNlKGNoKSkgPT0gLTEpCisgICAgICAgIFNldFByb3AoUF9DSEFOTkVMUywgUXVlcnlQcm9wKFBfQ0hBTk5FTFMpICsgKHsgY2ggfSkpOworICAgICAgZXJyID0gQ0hNQVNURVItPnNlbmQoY2gsIHRoaXNfb2JqZWN0KCksIGFyZ3MsIHR5cGUpOworICAgIH0KKworICBzd2l0Y2goZXJyKQorICB7CisgIGNhc2UgRV9BQ0NFU1NfREVOSUVEOgorICAgIG5vdGlmeV9mYWlsKCJBdWYgZGVyIEViZW5lICciK2NoKyInIGRhcmZzdCBEdSBuaWNodHMgc2FnZW4uXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgY2FzZSBFX05PVF9NRU1CRVI6CisgICAgbm90aWZ5X2ZhaWwoIkR1IGhhc3QgZGllIEViZW5lICciK2NoKyInIG5pY2h0IGJldHJldGVuIVxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK2ludCBDaGFubmVsQWRtaW4oc3RyaW5nIGFyZ3MpCit7CisgIHN0cmluZyBuLCBkZXNjciwgc2gsIGNuOworICBtaXhlZCBwYSwgdG1wOworICBhcmdzID0gX3VucGFyc2VkX2FyZ3MoKTsKKyAgbm90aWZ5X2ZhaWwoIkJlbnV0enVuZzogZWJlbmUgPEFia3Vlcnp1bmc+PTxFYmVuZT5cbiIKKyAgICAgICAgICAgICAgIiAgICAgICAgICAgZWJlbmUgPEFia3Vlcnp1bmc+PVxuIgorICAgICAgICAgICAgICAiICAgICAgICAgICBlYmVuZSBhYmt1ZXJ6dW5nZW4gW3N0YW5kYXJkXVxuIgorICAgICAgICAgICAgICAiICAgICAgICAgICBlYmVuZSBzdGFuZGFyZCA8RWJlbmU+XG4iCisgICAgICAgICAgICAgICIgICAgICAgICAgIGViZW5lIGFufGVpbnxhdXNcbiIKKyAgICAgICAgICAgICAgKyhRdWVyeVByb3AoUF9MRVZFTCkgPj0gNSA/CisgICAgICAgICAgICAgICAgIiAgICAgICAgICAgZWJlbmUgbmV1IDxOYW1lPiA8QmV6ZWljaG51bmc+XG4iCisgICAgIiAgICAgICAgICAgZWJlbmUgYmVzY2hyZWlidW5nIDxOYW1lPiA8QmVzY2hyZWlidW5nPlxuIiA6ICIiKQorICAgICAgICArKElTX0FSQ0godGhpc19vYmplY3QoKSkgPworICAgICAgICAgICIgICAgICAgICAgIGViZW5lIGtpbGwgPE5hbWU+XG4iCisJICAiICAgICAgICAgICBlYmVuZSBjbGVhciA8TmFtZT5cbiI6ICIiKSk7CisgIGlmKCFhcmdzIHx8ICFzaXplb2YoYXJncykpIHJldHVybiAwOworICBpZihzc2NhbmYoYXJncywgImtpbGwgJXMiLCBuKSAmJiBJU19BUkNIKHRoaXNfb2JqZWN0KCkpKQorICB7CisgICAgaWYoIShjbiA9IENITUFTVEVSLT5maW5kKG4sIHRoaXNfb2JqZWN0KCkpKSkgY24gPSBuOworICAgIHN3aXRjaChDSE1BU1RFUi0+cmVtb3ZlKGNuLCB0aGlzX29iamVjdCgpKSkKKyAgICB7CisgICAgY2FzZSBFX0FDQ0VTU19ERU5JRUQ6CisgICAgIG5vdGlmeV9mYWlsKCJEaWUgRWJlbmUgJyIrY24rIicgbGllcyBzaWNoIG5pY2h0IGVudGZlcm5lbiFcbiIpOworICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgd3JpdGUoIkR1IGVudGZlcm5zdCBkaWUgRWJlbmUgJyIrY24rIicuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZihzc2NhbmYoYXJncywgImNsZWFyICVzIiwgbikgJiYgSVNfQVJDSCh0aGlzX29iamVjdCgpKSkKKyAgeworICAgIGlmKCEoY24gPSBDSE1BU1RFUi0+ZmluZChuLCB0aGlzX29iamVjdCgpKSkpIGNuID0gbjsKKyAgICBzd2l0Y2goQ0hNQVNURVItPmNsZWFyX2hpc3RvcnkoY24sIHRoaXNfb2JqZWN0KCkpKQorICAgIHsKKyAgICBjYXNlIEVfQUNDRVNTX0RFTklFRDoKKyAgICAgbm90aWZ5X2ZhaWwoIkRlciBWZXJsYXVmIHp1ciBFYmVuZSAnIitjbisiJyBsaWVzIHNpY2ggbmljaHQgZW50ZmVybmVuIVxuIik7CisgICAgIHJldHVybiAwOworICAgIH0KKyAgICB3cml0ZSgiRHUgZW50ZmVybnN0IGRlbiBWZXJsYXVmIHp1ciBFYmVuZSAnIitjbisiJy5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmKHNzY2FuZihhcmdzLCAibmV1ICVzICVzIiwgbiwgZGVzY3IpID09IDIpCisgIHsKKyAgICBtaXhlZCB4OworICAgIGlmKFF1ZXJ5UHJvcChQX0xFVkVMKSA8IDUpCisgICAgICByZXR1cm4gKG5vdGlmeV9mYWlsKCJOZXVlIEViZW5lbiB6dSBlcnN0ZWxsZW4gaXN0IGRpciB2ZXJ3ZWhydC5cbiIpLCAwKTsKKyAgICBpZighc2l6ZW9mKHJlZ2V4cCgoeyBuIH0pLCAiXiIgQ0hBTk5FTENNRFMgQ0hBTk5FTENNRFMgIioiKSkpCisgICAgICByZXR1cm4gKG5vdGlmeV9mYWlsKCJEZXIgTmFtZSAnIituKyInIGlzdCBuaWNodCBrb25mb3JtIVxuIiksIDApOworICAgIGlmIChzaXplb2YobikgPiAyMCApCisgICAgICByZXR1cm4obm90aWZ5X2ZhaWwoIkRlciBOYW1lICciK24rIicgaXN0IHp1IGxhbmcuXG4iKSwgMCk7CisgICAgc3dpdGNoKHggPSBDSE1BU1RFUi0+bmV3KG4sIHRoaXNfb2JqZWN0KCksIGRlc2NyKSkKKyAgICB7CisgICAgY2FzZSBFX0FDQ0VTU19ERU5JRUQ6CisgICAgICBub3RpZnlfZmFpbCgiRGllc2UgRWJlbmUgZGFyZnN0IGR1IG5pY2h0IGVyc2NoYWZmZW4hXG4iKTsgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIHdyaXRlKCJEdSBlcnNjaGFmZnN0IGRpZSBFYmVuZSAnIituKyInLlxuIik7CisgICAgICBTZXRQcm9wKFBfQ0hBTk5FTFMsIFF1ZXJ5UHJvcChQX0NIQU5ORUxTKSArICh7IGxvd2VyX2Nhc2UobikgfSkpOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICB9CisgIGlmKHNzY2FuZihhcmdzLCAiYmVzY2hyZWlidW5nICVzICVzIiwgbiwgZGVzY3IpID09IDIpCisgIHsKKyAgICBtaXhlZCBjaDsKKyAgICBjbiA9IENITUFTVEVSLT5maW5kKG4sIHRoaXNfb2JqZWN0KCkpOworICAgIGlmKCFjbiB8fCBwb2ludGVycChjbikpCisgICAgICByZXR1cm4gKG5vdGlmeV9mYWlsKCJEaWUgRWJlbmUgJyIrbisiJyBleGlzdGllcnQgbmljaHQgb2RlciBkaWUgQW5nYWJlICIKKyAgICAgICAgIndhciBuaWNodCBlaW5kZXV0aWcuXG4iKSwgMCk7CisgICAgY2ggPSBDSE1BU1RFUi0+bGlzdCh0aGlzX29iamVjdCgpKTsKKyAgICBpZihjaFtsb3dlcl9jYXNlKGNuKV1bSV9NQVNURVJdICE9IHRoaXNfb2JqZWN0KCkpCisgICAgICByZXR1cm4gKG5vdGlmeV9mYWlsKCJEdSBiaXN0IG5pY2h0IGJlcmVjaHRpZ3QgZGllIEJlc2NocmVpYnVuZyBkZXIgRWJlbmUiCisgICAgICAgICIgJyIrY24rIicgenUgYWVuZGVybi5cbiIpLCAwKTsKKyAgICBjaFtsb3dlcl9jYXNlKGNuKV1bSV9JTkZPXSA9IGRlc2NyOworICAgIHdyaXRlKCJEaWUgRWJlbmUgJyIrY24rIicgaGF0IGFiIHNvZm9ydCBkaWUgQmVzY2hyZWlidW5nOlxuIitkZXNjcisiXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZihzc2NhbmYoYXJncywgIiVzPSVzIiwgc2gsIG4pID09IDIgJiYgc2l6ZW9mKG4pKQorICB7CisgICAgbWFwcGluZyBzYzsKKyAgICBpZihwb2ludGVycCh0bXAgPSBDSE1BU1RFUi0+ZmluZChuLCB0aGlzX29iamVjdCgpKSkgfHwgIXRtcCkKKyAgICAgIHJldHVybiAobm90aWZ5X2ZhaWwoIkJlbnV0enVuZzogZWJlbmUgPEFia3Vlcnp1bmc+PTxFYmVuZT5cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKyhwb2ludGVycCh0bXApID8gaW1wbG9kZSh0bXAsICIsICIpICsgIlxuIiA6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkViZW5lICciK24rIicgbmljaHQgZ2VmdW5kZW4hXG4iKSksIDApOworICAgIHNjID0gUXVlcnlQcm9wKFBfQ0hBTk5FTF9TSE9SVCk7CisgICAgaWYoIXNjKSBzYyA9IChbXSk7CisgICAgc2Nbc2hdID0gdG1wOworICAgIFNldFByb3AoUF9DSEFOTkVMX1NIT1JULCBzYyk7CisgICAgc2hvcnRjdXQgPSBRdWVyeVByb3AoUF9DSEFOTkVMX1NIT1JUKTsKKyAgICB3cml0ZSgiJyIrc2grIicgd2lyZCBqZXR6dCBhbHMgQWJrdWVyenVuZyBmdWVyICciK3RtcCsiJyBhbmVya2FubnQuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZihzc2NhbmYoYXJncywgIiVzPSIsIHNoKSkKKyAgeworICAgIFNldFByb3AoUF9DSEFOTkVMX1NIT1JULCBtX2NvcHlfZGVsZXRlKFF1ZXJ5UHJvcChQX0NIQU5ORUxfU0hPUlQpIHx8IChbXSksIHNoKSk7CisgICAgc2hvcnRjdXQgPSBRdWVyeVByb3AoUF9DSEFOTkVMX1NIT1JUKTsKKyAgICB3cml0ZSgiRHUgbG9lc2Noc3QgZGllIEFia3Vlcnp1bmcgJyIrc2grIicuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZihhcmdzID09ICJhbiIgfHwgYXJncyA9PSAiZWluIikKKyAgeworICAgIG1peGVkIGV4Y2w7CisgICAgaWYocG9pbnRlcnAoUXVlcnlQcm9wKFBfU1dBUF9DSEFOTkVMUykpKQorICAgICAgU2V0UHJvcChQX0NIQU5ORUxTLCBRdWVyeVByb3AoUF9TV0FQX0NIQU5ORUxTKSk7CisgICAgZWxzZQorICAgICAgU2V0UHJvcChQX0NIQU5ORUxTLCBtX2luZGljZXMoQ0hNQVNURVItPmxpc3QodGhpc19vYmplY3QoKSkpKTsKKyAgICBleGNsID0gUmVnaXN0ZXJDaGFubmVscygpOworICAgIHdyaXRlKCJEdSBzY2hhbHRlc3QgZm9sZ2VuZGUgRWJlbmVuIGVpbjpcbiIKKyAgICAgICAgICArYnJlYWtfc3RyaW5nKGltcGxvZGUoUXVlcnlQcm9wKFBfQ0hBTk5FTFMpIC0gZXhjbCwgIiwgIiksIDc4KSk7CisgICAgU2V0UHJvcChQX1NXQVBfQ0hBTk5FTFMsIDApOworICAgIHJldHVybiAxOworICB9CisgIGlmKGFyZ3MgPT0gImF1cyIpCisgIHsKKyAgICBTZXRQcm9wKFBfU1dBUF9DSEFOTkVMUywgUXVlcnlQcm9wKFBfQ0hBTk5FTFMpKTsKKyAgICBSZW1vdmVDaGFubmVscygpOworICAgIFNldFByb3AoUF9DSEFOTkVMUywgKHt9KSk7CisgICAgd3JpdGUoIkR1IHN0ZWxsc3QgZGllIEViZW5lbiBhYi5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIHBhID0gb2xkX2V4cGxvZGUoYXJncywgIiAiKTsKKyAgaWYoIXN0cnN0cigiYWJrdWVyenVuZ2VuIiwgcGFbMF0pKQorICB7CisgICAgc3RyaW5nIHR4dDsgdHh0ID0gIiI7CisgICAgaWYoc2l6ZW9mKHBhKSA+IDEgJiYgIXN0cnN0cigic3RhbmRhcmQiLCBwYVsxXSkpCisgICAgeworICAgICAgd3JpdGUoIkRpZSBTdGFuZGFyZCBBYmt1ZXJ6dW5nZW4gd2VyZGVuIGdlc2V0enQuXG4iKTsKKyAgICAgIFNldFByb3AoUF9DSEFOTkVMX1NIT1JULCBERUZBVUxUX1NIT1JUQ1VUUworICAgICAgICAgICAgICArIChJU19MRUFSTkVSKHRoaXNfb2JqZWN0KCkpID8gV0laQVJEX1NIT1JUQ1VUUyA6IChbXSkpKTsKKyAgICB9CisgICAgd2Fsa19tYXBwaW5nKFF1ZXJ5UHJvcChQX0NIQU5ORUxfU0hPUlQpLAorICAgICAgICAgICAgICAgICBsYW1iZGEoKHsnaS8qJyovLCAnYywgJ3J9KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICh7IycrPSwgJ3IvKicqLywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKHsjJ3NwcmludGYvKicqLywgIiU1LjVzID0gJXNcbiIsICdpLCAnY30pfSkpLAorICAgICAgICAgICAgICAgICAmdHh0KTsKKyAgICB0eHQgPSBzcHJpbnRmKCJGb2xnZW5kZSBBYmt1ZXJ6dW5nZW4gc2luZCBkZWZpbmllcnQ6XG4lLTc4I3NcbiIsCisgICAgICAgICAgICAgICAgICBpbXBsb2RlKHNvcnRfYXJyYXkob2xkX2V4cGxvZGUodHh0LCAiXG4iKSwgIyc+LyonKi8pLCAiXG4iKSk7CisgICAgTW9yZSh0eHQpOworICAgIHJldHVybiAxOworICB9CisgIGlmKCFzdHJzdHIoInN0YW5kYXJkIiwgcGFbMF0pKQorICAgIGlmKHNpemVvZihwYSkgPCAyKQorICAgICAgcmV0dXJuIChub3RpZnlfZmFpbCgiQmVudXR6dW5nOiBlYmVuZSBzdGFuZGFyZCA8RWJlbmU+XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICsoUXVlcnlQcm9wKFBfU1REX0NIQU5ORUwpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAiTW9tZW50YW4gaXN0ICciK1F1ZXJ5UHJvcChQX1NURF9DSEFOTkVMKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICsiJyBlaW5nZXN0ZWxsdC5cbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICJFcyBpc3Qga2VpbmUgU3RhbmRhcmRlYmVuZSBlaW5nZXN0ZWxsdC5cbiIpKSwwKTsKKyAgICBlbHNlCisgICAgICBpZihwb2ludGVycCh0bXAgPSBDSE1BU1RFUi0+ZmluZChwYVsxXSwgdGhpc19vYmplY3QoKSkpKQorICAgICAgICByZXR1cm4gKG5vdGlmeV9mYWlsKCJEYXMgd2FyIGtlaW5lIGVpbmRldXRpZ2UgQW5nYWJlISAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkZvbGdlbmRlIEViZW5lbiBwYXNzZW46XG4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgK2JyZWFrX3N0cmluZyhpbXBsb2RlKHRtcCwgIiwgIiksIDc4KSksIDApOworICAgICAgZWxzZQorICAgICAgICBpZighdG1wKSByZXR1cm4gKG5vdGlmeV9mYWlsKCJFYmVuZSAnIitwYVsxXSsiJyBuaWNodCBnZWZ1bmRlbiFcbiIpLDApOworICAgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICB3cml0ZSgiJyIrdG1wKyInIGlzdCBqZXR6dCBkaWUgU3RhbmRhcmRlYmVuZS5cbiIpOworICAgICAgICAgIFNldFByb3AoUF9TVERfQ0hBTk5FTCwgdG1wKTsKKyAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICByZXR1cm4oMCk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvY29tYmF0LmMgYi9zdGQvcGxheWVyL2NvbWJhdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiYjVhMWIKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2NvbWJhdC5jCkBAIC0wLDAgKzEsMjE3IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL2NvbWJhdC5jIC0tIGNvbWJhdCBzdGF0aXN0aWNzCisvLworLy8gJElkOiBjb21iYXQuYyA5MDA4IDIwMTUtMDEtMDYgMTc6MjA6MTdaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL2xpdmluZy9jb21iYXQiOworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvcGtsb2ciOworCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxjb21iYXQuaD4KKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisKKyNkZWZpbmUgTUUgdGhpc19vYmplY3QoKQorI2RlZmluZSBTVEFUTUFTVEVSICIvcC9zZXJ2aWNlL3JvY2h1cy9ndWlsZHN0YXQvbWFzdGVyIgorCitwcml2YXRlIG5vc2F2ZSBjbG9zdXJlIG1vZF9kZWZfc3RhdDsKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyAqcGxBdHRhY2tlZCA9ICh7fSk7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpIHsKKyAgY29tYmF0OjpjcmVhdGUoKTsKKyAgLy8gUF9OT19BVFRBQ0sgaXN0IG5pY2h0IGZ1ZXIgU3BpZWxlciBnZWRhY2h0LiBBdXNuYWhtZTogU3BpZWxlciBpc3QKKyAgLy8gR2Vpc3QsIGRhbm4gc2V0enQgZGFzIFNwaWVsZXJvYmpla3QgYWJlciBzZWxiZXIuCisgIFNldChQX05PX0FUVEFDSywgU0VDVVJFRHxOT1NFVE1FVEhPRCwgRl9NT0RFX0FTKTsKKyAgCisgIFNldChQX0hFTFBFUl9OUEMsIFBST1RFQ1RFRCwgRl9NT0RFKTsKKyAgU2V0UHJvcChQX0hFTFBFUl9OUEMsIChbXSkgKTsKK30KKworLy8gTWFza2UgZnVlciBhbGxlIG1vZWdsaWNoZW4gS2xhc3NlbiB2b24gSGVsZmVyLU5QQworI2RlZmluZSBDTEFTU19NQVNLIDB4MWZmZmZmZmYKKy8qKiByZWdpc3RyaWVydCBkZW4gTlBDIGFscyBIZWxmZXIgdm9uIGRpZXNlbSBTcGllbGVyLgorICBAcGFyYW1baW5dIG5wYyBvYmplY3QgSGVsZmVyLU5QQworICBAcGFyYW1baW5dIGZsYWdzIGludCBCaXRmZWxkIHZvbiBGbGFncworICBAcmV0dXJuIGludCAxLCBmYWxscyBkZXIgSGVsZmVyLU5QQyByZWdpc3RyaWVydCB3dXJkZSB1bmQgbm9jaCBuaWNodAorICByZWdpc3RyaWVydCB3YXIuCisgIEBhdHRlbnRpb24gTnV0enQgYXVzLCBkYXNzIFF1ZXJ5UHJvcChQX0hFTFBFUl9OUEMpIF9rZWluZV8gS29waWUgZGVzCisgIE1hcHBpbmdzIGluIGRlciBQcm9wIGxpZWZlcnQuCisgICovCitwdWJsaWMgaW50IFJlZ2lzdGVySGVscGVyTlBDKG9iamVjdCBucGMsIGludCBmbGFncykgeworICBpZiAoIW9iamVjdHAobnBjKSkKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCAiV3JvbmcgYXJndW1lbnQgMSBpbiBSZWdpc3RlckhlbHBlck5QQygpLiAiCisgICAgICAgICAgIkV4cGVjdGVkIDxvYmplY3Q+LCBnb3QgJS4xMDBPXG4iLCBucGMpKTsKKyAgaWYgKCFpbnRwKGZsYWdzKSB8fCBmbGFncyA8IDEpCisgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoICJXcm9uZyBhcmd1bWVudCAyIGluIFJlZ2lzdGVySGVscGVyTlBDKCkuICIKKyAgICAgICAgICAiRXhwZWN0ZWQgcG9zaXRpdmUgPGludD4sIGdvdCAlT1xuIiwgZmxhZ3MpKTsKKyAgCisgIG1hcHBpbmcgaGVscGVycyA9IFF1ZXJ5UHJvcChQX0hFTFBFUl9OUEMpOworICAKKyAgLy8gc2Nob24gcmVnaXN0cmllcnRlIHNpbmQgd2l0emxvcy4KKyAgaWYgKG1lbWJlcihoZWxwZXJzLCBucGMpKQorICAgIHJldHVybiAwOworICAKKyAgLy8gYXVmIGV4a2x1c2l2ZSBIZWxmZXIgcHJ1ZWZlbi4KKyAgZm9yZWFjaChvYmplY3QgaGVscGVyLCBpbnQgZmw6IGhlbHBlcnMpIHsKKyAgICAvLyBmbGFncyBpZGVudGlzY2g/IERhbm4gS2xhc3NlIHVuZCBFeGtsdXNpdml0YWV0IGlkZW50aXNjaAorICAgIGlmIChmbCA9PSBmbGFncykKKyAgICAgIHJldHVybiAwOworICAgIC8vIG9kZXIgZWluZXIgdm9uIGJlaWRlbiBleGtsdXNpdiB1bmQgYmVpZGUgaW4gZGVyIGdsZWljaGVuIEtsYXNzZT8KKyAgICBlbHNlIGlmICggKChmbCAmIEVYQ0xVU0lWRV9IRUxQRVIpIHx8IChmbGFncyAmIEVYQ0xVU0lWRV9IRUxQRVIpKQorICAgICAgICAgICAgICAmJiAoKGZsICYgQ0xBU1NfTUFTSykgPT0gKGZsYWdzICYgQ0xBU1NfTUFTSykpICkKKyAgICAgIHJldHVybiAwOworICB9CisgIC8vIHNjaGVpbnQgd29obCBvayB6dSBzZWluLiBSZWdpc3RyaWVyZW4gdW5kIFByb3AgaW0gTlBDIHNldHplbi4KKyAgaGVscGVycyArPSAoWyBucGM6IGZsYWdzIF0pOworICBucGMtPlNldFByb3AoUF9IRUxQRVJfTlBDLCAoeyB0aGlzX29iamVjdCgpLCBmbGFncyB9KSApOworICAvLyBtb21lbnRhbiB1bm5vZXRpZywgZGEgaGVscGVycyBrZWluZSBLb3BpZSBpc3QuCisgIC8vIFNldFByb3AoUF9IRUxQRVJfTlBDLCBoZWxwZXJzKTsKKworICByZXR1cm4gMTsKK30KKyN1bmRlZiBDTEFTU19NQVNLCisKKy8qKiBkZS1yZWdpc3RyaWVydCBkZW4gTlBDIGFscyBIZWxmZXIgdm9uIGRpZXNlbSBTcGllbGVyLgorICBAcGFyYW1baW5dIG5wYyBvYmplY3QgSGVsZmVyLU5QQworICBAcmV0dXJuIGludCAxLCBmYWxscyBkZXIgSGVsZmVyLU5QQyByZWdpc3RyaWVydCB3YXIgdW5kIGVudGZlcm50IHd1cmRlLgorICBAYXR0ZW50aW9uIE51dHp0IGF1cywgZGFzcyBRdWVyeVByb3AoUF9IRUxQRVJfTlBDKSBfa2VpbmVfIEtvcGllIGRlcworICBNYXBwaW5ncyBpbiBkZXIgUHJvcCBsaWVmZXJ0LgorICovCitwdWJsaWMgaW50IFVucmVnaXN0ZXJIZWxwZXJOUEMob2JqZWN0IG5wYykgeworICBpZiAoIW9iamVjdHAobnBjKSkKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJXcm9uZyBhcmd1bWVudCBpbiBVbnJlZ2lzdGVySGVscGVybk5QQygpLiAiCisgICAgICAgICAgIkV4cGVjdGVkIDxvYmplY3Q+LCBnb3QgJS4xMDBPXG4iLCBucGMpKTsKKworICBtYXBwaW5nIGhlbHBlcnMgPSBRdWVyeVByb3AoUF9IRUxQRVJfTlBDKTsKKyAgaWYgKG1lbWJlcihoZWxwZXJzLCBucGMpKSB7CisgICAgbV9kZWxldGUoaGVscGVycywgbnBjKTsKKyAgICAvLyBtb21lbnRhbiB1bm5vZXRpZywgZGEgaGVscGVycyBrZWluZSBLb3BpZSBpc3QuCisgICAgLy8gU2V0UHJvcChQX0hFTFBFUl9OUEMsIGhlbHBlcnMpOworICAgIG5wYy0+U2V0UHJvcChQX0hFTFBFUl9OUEMsIDApOworICAgIHJldHVybiAxOworICB9CisgIHJldHVybiAwOworfQorCisvKiogRmVpbmQgZWludHJhZ2VuLgorICAqIFRyYWVndCBvYiBhbHMgRmVpbmQgZWluLiBEaWVzIGFsbGVyZGluZ3MgbnVyLCB3ZW5uIG9iIGtlaW4gU3BpZWxlciBpc3QKKyAgKiBvZGVyIGJlaWRlIFNwaWVsZXIgKGRpZXNlcyBPYmpla3QgdW5kIG9iKSBpbiBkZXIgU2NoYXR0ZW53ZWx0IHNpbmQgb2RlcgorICAqIGJlaWRlIFNwaWVsZXIgVGVzdHNwaWVsZXIgc2luZC4KKyAgIEBwYXJhbVtpbl0gb2IgcG90ZW50aWVsbGVyIEZlaW5kLgorICAgQHJldHVybiBpbnQgMSwgZmFsbHMgb2IgYWxzIF9uZXVlcl8gRmVpbmQgZWluZ2V0cmFnZW4gd3VyZGUuCisgICAqLworcHVibGljIGludCBJbnNlcnRFbmVteShvYmplY3Qgb2IpIHsKKyAgLy8gd2VubiBvYiBlaW4gU3BpZWxlciBpc3QgdW5kIG5pY2h0IHNvd29obCBpY2ggYWxzIGF1Y2ggb2IgaW4gZGVyCisgIC8vIFNjaGF0dGVud2VsdCBzaW5kLCB3aXJkIG9iIG5pY2h0IGFscyBGZWluZCBlaW5nZXRyYWdlbi4KKyAgaWYgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob2IpCisgICAgICAmJiAoc3Ryc3RyKG9iamVjdF9uYW1lKGVudmlyb25tZW50KG9iKSksIi9kL3NjaGF0dGVud2VsdC8iKSE9MAorICAgICAgICAgIHx8IHN0cnN0cihvYmplY3RfbmFtZShlbnZpcm9ubWVudChNRSkpLCIvZC9zY2hhdHRlbndlbHQvIikhPTApCisgICAgICAmJiAoIVF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpIHx8ICFvYi0+UXVlcnlQcm9wKFBfVEVTVFBMQVlFUikpCisgICAgICkKKyAgeworICAgIHJldHVybiAwOworICB9CisgIHJldHVybiA6Okluc2VydEVuZW15KG9iKTsKK30KKworLyoqIEhhdCBkaWVzZXIgU3BpZWxlciBkZW4gU3BpZWxlciBwbCBhbmdlZ3JpZmZlbj8uCisgIEBwYXJhbVtpbl0gcGwgb2JqZWN0IHp1IHBydWVmZW5kZXIgU3BpZWxlcgorICBAcmV0dXJuIGludCAxLCBmYWxscyBkaWVzZXIgU3BpZWxlciBwbCBhbmdlZ3JpZmZlbiBoYXQuCisgIEBhdHRlbnRpb24gTmViZW5lZmZla3Q6IGJlcmVpbmlndCBkZW4gaW50ZXJuZW4gU3BlaWNoZXIgdm9uIFVJRHMgdm9uCisgIHplcnN0b2VydGVuIFNwaWVsZXJuIHVuZCBzb2xjaGVuLCBkaWUga2VpbmUgRmVpbmRlIG1laHIgc2luZC4KKyAgKi8KK3B1YmxpYyBpbnQgUXVlcnlQbEF0dGFja2VkKG9iamVjdCBwbCkgeworICBvYmplY3Qgb2I7CisKKyAgaWYgKCAhb2JqZWN0cChwbCkgKQorICAgIHJldHVybiAwOworCisgIGZvcmVhY2goc3RyaW5nIHBsbmFtZTogcGxBdHRhY2tlZCkgeworICAgIGlmICggISggb2I9KGZpbmRfcGxheWVyKHBsbmFtZSl8fGZpbmRfbmV0ZGVhZChwbG5hbWUpKSApCisgICAgICAgIHx8ICggIUlzRW5lbXkob2IpICYmICEob2ItPklzRW5lbXkoTUUpKSApICkKKyAgICAgIHBsQXR0YWNrZWQgLT0gKHtwbG5hbWV9KTsgLy8gamEsIGRhcyBnZWh0LiA7LSkKKyAgfQorICByZXR1cm4gKG1lbWJlciggcGxBdHRhY2tlZCwgZ2V0dWlkKHBsKSApID49IDApOworfQorCisvKioga2lsbCAtIEthbXBmIHN0YXJ0ZW4uCisgKiBGdWVndCBvYiBkZXIgRmVpbmRlc2xpc3RlIGhpbnp1LgorICovCitwdWJsaWMgaW50IEtpbGwob2JqZWN0IG9iKSB7CisKKyAgaWYgKCFvYmplY3RwKG9iKSkgcmV0dXJuIDA7CisKKyAgLy8gZGllcyBkaWVudCBudXIgZGF6dSwgZGFzIHBsQXR0YWNrZWQgbWFwcGluZyB6dSBiZXJlaW5pZ2VuLgorICAvLyBUT0RPOiBiZXNzZXIgbWFjaGVuLiA7LSkKKyAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iKSAmJiAhSXNFbmVteShvYikpIHsKKyAgICBRdWVyeVBsQXR0YWNrZWQoTUUpOworICAgIG9iLT5RdWVyeVBsQXR0YWNrZWQob2IpOyAvLyBha3R1YWxpc2llcmVuIC4uLgorICB9CisKKyAgaW50IHJlcyA9IGNvbWJhdDo6S2lsbChvYik7CisKKyAgLy8gZmFsbHMgb2IgbmVuIFNwaWVsZXIgaXN0LCBwcnVlZmVuLCBvYiBlcyBlaW4gU3BpZWxlci1TcGllbGVyLUFuZ3JpZmYKKyAgLy8gaXN0LgorICAvLyBEYWJlaSBnZ2YuIGxvZ2dlbiB1bmQgTWFnaWVyIHZlcnN0YWVuZGlnZW4uCisgIGlmIChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iKSAmJiBDaGVja1BsYXllckF0dGFjayhNRSwgb2IsIDApKQorICB7CisgICAgaWYgKHJlcyA9PSAtNCkgLy8gZmVpbmQgd3VyZGUgbmljaHQgZWluZ2V0cmFnZW4KKyAgICAgIHRlbGxfb2JqZWN0KE1FLCAiRWluIGdvZXR0bGljaGVyIEJlZmVobCBoaW5kZXJ0IERpY2ggYW0gS2FtcGYuXG4iKTsKKyAgICBlbHNlCisgICAgICBwbEF0dGFja2VkICs9ICh7IGdldHVpZChvYikgfSk7CisgIH0KKworICByZXR1cm4gcmVzOworfQorCitwdWJsaWMgaW50IERlZmVuZChpbnQgZGFtLCBzdHJpbmd8c3RyaW5nKiBkYW1fdHlwZSwgaW50fG1hcHBpbmcgc3BlbGwsIG9iamVjdCBlbmVteSkgeworICBpbnQgZGVsdGFfaHAscmVzOworCisgIGlmIChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKQorICAgICAgJiYgIUlTX0xFQVJORVIoTUUpCisgICAgICAmJiAhb2JqZWN0cChnZXRfdHlwZV9pbmZvKG1vZF9kZWZfc3RhdCwyKSkpIHsKKyAgICBvYmplY3QgbWE7CisgICAgaWYgKCFvYmplY3RwKG1hPWZpbmRfb2JqZWN0KFNUQVRNQVNURVIpKSkKKyAgICAgIHJldHVybiA6OkRlZmVuZChkYW0sZGFtX3R5cGUsc3BlbGwsZW5lbXkpOworICAgIC8vIFN0YXRpc3RpayBudXIgYXVmcnVmZW4gZmFsbHMgTWFzdGVyIGdlbGFkZW4KKyAgICBtb2RfZGVmX3N0YXQ9c3ltYm9sX2Z1bmN0aW9uKCJNb2RpZnlEZWZlbmRTdGF0IixtYSk7CisgIH0KKworICBpZiAoY2xvc3VyZXAobW9kX2RlZl9zdGF0KSkKKyAgICBkZWx0YV9ocD1RdWVyeVByb3AoUF9IUCk7CisKKyAgcmVzPTo6RGVmZW5kKGRhbSxkYW1fdHlwZSxzcGVsbCxlbmVteSk7CisKKyAgaWYgKGNsb3N1cmVwKG1vZF9kZWZfc3RhdCkpIHsKKyAgICBkZWx0YV9ocC09UXVlcnlQcm9wKFBfSFApOworICAgIGlmIChkZWx0YV9ocDwwKQorICAgICAgZGVsdGFfaHA9MDsKKyAgICBmdW5jYWxsKG1vZF9kZWZfc3RhdCwKKyAgICAgICAgICAgIFF1ZXJ5UHJvcChQX0dVSUxEKSwKKyAgICAgICAgICAgIFF1ZXJ5UHJvcChQX0dVSUxEX0xFVkVMKSwKKyAgICAgICAgICAgIGRhbS0xMCpkZWx0YV9ocCwKKyAgICAgICAgICAgIGRhbV90eXBlLAorICAgICAgICAgICAgc3BlbGwpOworICB9CisKKyAgcmV0dXJuIHJlczsKK30KKworLy8gU3BpZWxlciBrb2VubmVuIGFscyBHZWlzdCBuaWNodCBr5G1wZmVuCisvLyBUT0RPOiBwcnVlZmVuLCBvYiBkYXMgU2V0emVuIHVuZCBMb2VzY2hlbiBkZXIgUHJvcCBpbiBzZXRfZ2hvc3QoKSBuaWNodAorLy8gYXVjaCBhdXNyZWljaGVuIHd1ZXJkZS4gSW4gZGVtIEZhbGwgbXVlc3N0ZSBtYW4gYWJlciBQX05PX0FUVEFDSyBhdWNoCisvLyBzcGVpY2hlcm4sIGRhIFBfR0hPU1QgZ2VzcGVpY2hlcnQgd2lyZC4uLgorc3RhdGljIG1peGVkIF9xdWVyeV9ub19hdHRhY2soKQoreworICAgIGlmICggUXVlcnlQcm9wKFBfR0hPU1QpICkKKyAgICAgICAgcmV0dXJuIDE7CisKKyAgICByZXR1cm4gUXVlcnkoUF9OT19BVFRBQ0spOworfQpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9jb21tLmMgYi9zdGQvcGxheWVyL2NvbW0uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mOTFmMWRlCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9jb21tLmMKQEAgLTAsMCArMSwxOTIyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL2NvbW0uYy0tIGJhc2ljIHBsYXllciBjb21tdW5pY3Rpb24gY29tbWFuZHMKKy8vCisvLyAkSWQ6IGNvbW0uYyA5NTc2IDIwMTYtMDYtMTggMTU6MDA6MDFaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworLy8jcHJhZ21hIHJhbmdlX2NoZWNrCisKK2luaGVyaXQgIi9zdGQvbGl2aW5nL2NvbW0iOworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvY2hhbm5lbCI7Citpbmhlcml0ICIvc3RkL3BsYXllci9jb21tX3N0cnVjdHMiOworCisjaW5jbHVkZSA8aW5wdXRfdG8uaD4KKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwbGF5ZXIvcXVlc3QuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvZ21jcC5oPgorI2luY2x1ZGUgPGxpdmluZy9kZXNjcmlwdGlvbi5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8c3lzX2RlYnVnLmg+CisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cGxheWVyL2NvbW0uaD4KKyNpbmNsdWRlIDxwbGF5ZXIvYmFzZS5oPgorCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGNvbmZpZy5oPgorI2luY2x1ZGUgPGFuc2kuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPHVkcC5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxkYWVtb24uaD4KKyNpbmNsdWRlIDxzdHJpbmdzLmg+CisjaW5jbHVkZSA8cmVnZXhwLmg+CisjaW5jbHVkZSA8aW50ZXJhY3RpdmVfaW5mby5oPgorCisjZGVmaW5lIFRFTExISVNUX0RJU0FCTEVEICAgMAorI2RlZmluZSBURUxMSElTVF9OT19NRVNTQUdFIDEKKyNkZWZpbmUgVEVMTEhJU1RfRU5BQkxFRCAgICAyCisjZGVmaW5lIFRFTExISVNUX0xPTkdMSUZFICAgMworCisjZGVmaW5lIEVDSE9fQ09TVCA1MAorI2RlZmluZSBFUldJREVSX1BBUkFNICIsIgorCisjZGVmaW5lIFpERUJVRyh4KSAgaWYgKGZpbmRfcGxheWVyKCJ6ZXNzdHJhIikpXAorICAgICAgICAgICAgICBlZnVuOjp0ZWxsX29iamVjdChmaW5kX3BsYXllcigiemVzc3RyYSIpLCJDb21tREJHOiAiK3grIlxuIikKKworcHJpdmF0ZSBpbnQgdGVsbF9oaXN0b3J5X2VuYWJsZWQgPSBURUxMSElTVF9OT19NRVNTQUdFOworcHJpdmF0ZSBub3NhdmUgbWFwcGluZyB0ZWxsX2hpc3Rvcnk9KFtdKTsKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyAqY29tbXJlY2VpdmVycyA9ICh7fSk7Citwcml2YXRlIG5vc2F2ZSBzdHJpbmcgbGFzdF9jb21tX3BhcnRuZXI7Citwcml2YXRlIG5vc2F2ZSBpbnQgbGFzdF9iZWVwX3RpbWU7CisKKy8vIFN0YXR1c3JlcG9ydGUgYWt0aXZpZXJ0PyBCaW5hZXJlIEZsYWdzIChzLiBzZXRfcmVwb3J0KCkpCitwcml2YXRlIGludCBzdGF0X3JlcG9ydHM7CisvLyBpbnRlcm5lciBDYWNoZSBmdWVyIGRpZSBMUC9LUC9HaWZ0LVdlcnRlIGZ1ZXIgZGllIFN0YXR1c3JlcG9ydC1BdXNnYWJlbgorLy8gRWludHJhZWdlIChpbiBkaWVzZXIgUmVpaGVuZm9sZ2UpOiBQX0hQLCBQX1NQLCBHaWZ0c3RhdHVzCisvLyBJbml0aWFsaXNpZXJ1bmcgZXJmb2xndCBiZWltIGVyc3RlbiBSZXBvcnQgbmFjaCBMb2dpbgorcHJpdmF0ZSBub3NhdmUgbWl4ZWQgKnJlcG9ydF9jYWNoZTsKKworLy8gUHVmZmVyIGZ1ZXIgS29ib2xkLgorcHJpdmF0ZSBub3NhdmUgc3RydWN0IG1zZ19idWZmZXJfcyBrb2JvbGQgPSAoPG1zZ19idWZmZXJfcz4KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZjogYWxsb2NhdGUoMzIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5kZXg6IC0xLCk7CisjZGVmaW5lIE1BWF9LT0JPTERfTElNSVQgMjU2CisKK3ZhcmFyZ3Mgc3RyaW5nIG5hbWUoaW50IGNhc3VzLCBpbnQgZGVtb25zdCk7CisKKy8vbG9jYWwgcHJvcGVydHkgcHJvdG90eXBlcworc3RhdGljIGludCBfcXVlcnlfaW50ZXJtdWQoKTsKK3B1YmxpYyBpbnQgUmVtb3ZlSWdub3JlKHN0cmluZyBpZ24pOworcHVibGljIGludCBBZGRJZ25vcmUoc3RyaW5nIGlnbik7CisKK3B1YmxpYyB2YXJhcmdzIGludCBSZWNlaXZlTXNnKHN0cmluZyBtc2csIGludCBtc2dfdHlwZSwgc3RyaW5nIG1zZ19hY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbXNnX3ByZWZpeCwgb2JqZWN0IG9yaWdpbik7CisKKy8vIGVyemV1Z3Qgc29ydGllcnRlIExpc3RlIGFuIEtvbW11bmlrYXRpb25zcGFydG5lcm4KK3ByaXZhdGUgc3RyaW5nICpzb3J0ZWRfY29tbXBhcnRuZXJzKGludCByZXZlcnNlZCk7CisKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyAqYnVmZmVyID0gKHt9KTsKKwordm9pZCBjcmVhdGUoKQoreworICA6OmNyZWF0ZSgpOworICBTZXQoUF9FQVJNVUZGUywgMCk7CisgIFNldChQX0VBUk1VRkZTLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9FQVJNVUZGUywgU0VDVVJFRCwgRl9NT0RFKTsKKyAgU2V0KFBfSU5URVJNVUQsIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0lHTk9SRSwgKFtdKSwgRl9WQUxVRSk7CisgIFNldChQX0lHTk9SRSwgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfQlVGRkVSLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9NRVNTQUdFX1BSRVBFTkQsIFNBVkUsIEZfTU9ERV9BUyk7CisgIFNldChQX01FU1NBR0VfQkVFUCwgU0FWRSwgRl9NT0RFX0FTKTsKK30KKwordm9pZCBjcmVhdGVfc3VwZXIoKQoreworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKKy8vIHVlYmVybWl0dGVsdCBlaW5lIE1UX05PVElGSUNBVElPTiBhbiB0aGlzX29iamVjdCgpLCB3ZWxjaGUgbmljaHQgaWdub3JpZXJ0CisvLyB3ZXJkZW4ga2FubiB1bmQgYXVjaCBuaWNodCBnZXNwZWljaGVydCB3aXJkLgorcHJvdGVjdGVkIHZvaWQgX25vdGlmeShzdHJpbmcgbXNnLCBzdHJpbmcgYWN0aW9uKSB7CisgIFJlY2VpdmVNc2cobXNnLAorICAgICAgICAgICAgIE1UX05PVElGSUNBVElPTnxNU0dfRE9OVF9CVUZGRVJ8TVNHX0RPTlRfSUdOT1JFfE1TR19ET05UX1NUT1JFLAorICAgICAgICAgICAgIGFjdGlvbiwgMCwgdGhpc19vYmplY3QoKSk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIHVwZGF0ZXNfYWZ0ZXJfcmVzdG9yZShpbnQgbmV3ZmxhZykgeworICAvLyBBbHRlcyBJZ25vcmllcmUgbG9lc2NoZW4uLi4KKyAgbWl4ZWQgaWduID0gUXVlcnkoUF9JR05PUkUsRl9WQUxVRSk7CisgIGlmICghbWFwcGluZ3AoaWduKSkKKyAgeworICAgIGlmIChwb2ludGVycChpZ24pKQorICAgICAgX25vdGlmeShicmVha19zdHJpbmcoCisgICAgICAgICJEZWluZSBJZ25vcmllcmUtRWluc3RlbGx1bmdlbiB3dXJkZW4gc29lYmVuIGdlbG9lc2NodCwgIgorICAgICAgICAid2VpbCBlcyBlaW5lIEFrdHVhbGlzaWVydW5nIGRlciBJZ25vcmllcmVmdW5rdGlvbiBnYWIsICIKKyAgICAgICAgImJlaSBkZXIgZWluZSBLb252ZXJzaW9uIGRlciBEYXRlbiBsZWlkZXIgbmljaHQgIgorICAgICAgICAibW9lZ2xpY2ggd2FyLiIsNzgpLCAwKTsKKworICAgIFNldChQX0lHTk9SRSwgKFtdKSwgRl9WQUxVRSk7CisgIH0KK30KKworc3RhdGljIGludCBzZXRfcmVwb3J0KHN0cmluZyBzdHIpIHsKKyAgaW50IGNhbmZsYWdzID0gUXVlcnlQcm9wKFBfQ0FOX0ZMQUdTKTsKKworICBpZighc3RyKQorICB7CisgICAgaWYgKHN0YXRfcmVwb3J0cykgeworICAgIHN0cmluZyAqcmVzPSh7fSk7CisgICAgaWYgKHN0YXRfcmVwb3J0cyAmIERPX1JFUE9SVF9IUCkKKyAgICAgIHJlcys9KHsiTGViZW5zcHVua3RlIn0pOworICAgIGlmIChzdGF0X3JlcG9ydHMgJiBET19SRVBPUlRfU1ApCisgICAgICByZXMrPSh7IktvbnplbnRyYXRpb25zcHVua3RlIn0pOworICAgIGlmIChzdGF0X3JlcG9ydHMgJiBET19SRVBPUlRfUE9JU09OKQorICAgICAgcmVzKz0oeyJWZXJnaWZ0dW5nZW4ifSk7CisgICAgaWYgKHN0YXRfcmVwb3J0cyAmIERPX1JFUE9SVF9XSU1QWSkKKyAgICAgIHJlcys9KHsiVm9yc2ljaHQifSk7CisKKyAgICB0ZWxsX29iamVjdChNRSxicmVha19zdHJpbmcoCisgICAgICAgICJEaXIgd2VyZGVuIGpldHp0IFZlcmFlbmRlcnVuZ2VuIERlaW5lciAiCisgICAgICAgICtDb3VudFVwKHJlcykgKyAiIGJlcmljaHRldC4iLDc4KSk7CisgICAgfQorICAgIGVsc2UKKyAgICAgIHRlbGxfb2JqZWN0KE1FLAorICAgICAgICAiQWxsZSBTdGF0dXNyZXBvcnRzIHNpbmQgYXVzZ2VzY2hhbHRldC5cbiIpOworCisgICAgcmV0dXJuIDE7CisgIH0KKyAgZWxzZSBpZiAoc3RyID09ICJhdXMiKSB7CisgICAgaWYgKHN0YXRfcmVwb3J0cyAmIERPX1JFUE9SVF9IUCB8fCBzdGF0X3JlcG9ydHMgJiBET19SRVBPUlRfV0lNUFkpIHsKKyAgICAgIHN0cmluZyBzPSIiOworICAgICAgaWYgKHN0YXRfcmVwb3J0cyAmIERPX1JFUE9SVF9IUCkgeworICAgICAgICBzdHI9ImViZW5mYWxscyAiOworICAgICAgICB0ZWxsX29iamVjdChNRSwgIkRlciBSZXBvcnQgd3VyZGUgYXVzZ2VzY2hhbHRldC5cbiIpOworICAgICAgfQorICAgICAgaWYgKCBzdGF0X3JlcG9ydHMgJiBET19SRVBPUlRfV0lNUFkgKSB7CisgICAgICAgIHRlbGxfb2JqZWN0KE1FLCAiRGVyIFZvcnNpY2h0LVJlcG9ydCB3dXJkZSAiK3MrCisgICAgICAgICAgImF1c2dlc2NoYWx0ZXQuXG4iKTsKKyAgICAgIH0KKyAgICAgIHN0YXRfcmVwb3J0cz0wOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIHRlbGxfb2JqZWN0KE1FLCAiRGVyIFJlcG9ydCBpc3QgYmVyZWl0cyBhdXNnZXNjaGFsdGV0LlxuIik7CisgICAgfQorICAgIHJldHVybiAxOworICB9CisgIGVsc2UgaWYgKHN0ciA9PSAiZWluIikgeworICAgIGlmICggc3RhdF9yZXBvcnRzICYgRE9fUkVQT1JUX0hQICkgeworICAgICAgdGVsbF9vYmplY3QoTUUsICJEZXIgUmVwb3J0IGlzdCBiZXJlaXRzIGVpbmdlc2NoYWx0ZXQuXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICB0ZWxsX29iamVjdChNRSwgIkRlciBSZXBvcnQgd3VyZGUgZWluZ2VzY2hhbHRldC5cbiIpOworICAgIHN0YXRfcmVwb3J0cyB8PSBET19SRVBPUlRfSFA7CisgICAgaWYgKCEoY2FuZmxhZ3MgJiBDQU5fUkVQT1JUX1NQKSkgeworICAgICAgaWYgKFF1ZXJ5UXVlc3QoIkhpbGYgZGVuIEduYXJmZW4iKT09MSkgeworICAgICAgICBTZXRQcm9wKFBfQ0FOX0ZMQUdTLCBjYW5mbGFncyB8IENBTl9SRVBPUlRfU1ApOworICAgICAgICBzdGF0X3JlcG9ydHMgfD0gRE9fUkVQT1JUX1NQOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIHRlbGxfb2JqZWN0KE1FLCBicmVha19zdHJpbmcoCisgICAgICAgICAgIkZ1ZXIgZGVuIFN0YXR1c3JlcG9ydCBEZWluZXIgS29uemVudHJhdGlvbiBtdXNzdCBEdSBqZWRvY2ggIgorICAgICAgICAgICJ6dW5hZWNoc3QgZGllIFF1ZXN0IFwiSGlsZiBkZW4gR25hcmZlblwiIGJlc3RlaGVuLiIsNzgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICBzdGF0X3JlcG9ydHMgfD0gRE9fUkVQT1JUX1NQOworICAgIH0KKyAgICBpZiAoIShjYW5mbGFncyAmIENBTl9SRVBPUlRfUE9JU09OKSkgeworICAgICAgaWYgKFF1ZXJ5UXVlc3QoIkthdHplbmphbW1lciIpPT0xKSB7CisgICAgICAgIFNldFByb3AoUF9DQU5fRkxBR1MsIGNhbmZsYWdzIHwgQ0FOX1JFUE9SVF9QT0lTT04pOworICAgICAgICBzdGF0X3JlcG9ydHMgfD0gRE9fUkVQT1JUX1BPSVNPTjsKKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICB0ZWxsX29iamVjdChNRSwgYnJlYWtfc3RyaW5nKAorICAgICAgICAgICJGdWVyIGRlbiBTdGF0dXNyZXBvcnQgRGVpbmVyIFZlcmdpZnR1bmcgbXVzc3QgRHUgamVkb2NoICIKKyAgICAgICAgICAienVuYWVjaHN0IGRpZSBRdWVzdCBcIkthdHplbmphbW1lclwiIGJlc3RlaGVuLiIsNzgpKTsKKyAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICBzdGF0X3JlcG9ydHMgfD0gRE9fUkVQT1JUX1BPSVNPTjsKKyAgICB9CisgICAgLy8gQ2FjaGUgbG9lc2NoZW4sIGRhbWl0IGJlaW0gbmFlY2hzdGVuIFJlcG9ydC1FdmVudCBhbGxlIERhdGVuIG5ldQorICAgIC8vIGVpbmdldHJhZ2VuIHdlcmRlbiBtdWVzc2VuLiBNdXNzIGJlaW0gRWluc2NoYWx0ZW4gZGVzIFJlcG9ydHMKKyAgICAvLyBwYXNzaWVyZW4sIHdlaWwgYXVjaCBpbiBkZXIgaW5ha3RpdmVuIFplaXQgd2VpdGVyaGluIEFlbmRlcnVuZ2VuIGluCisgICAgLy8gc3RhdHVzX3JlcG9ydCgpIGVpbmdlaGVuLCBzbyBkYXNzIGRlciBDYWNoZSB6d2FyIGVyc3QgZWlubWFsIGxlZXIgaXN0LAorICAgIC8vIGFiZXIgYmVpbSBXaWVkZXJlaW5zY2hhbHRlbiBuaWNodCBtZWhyIHVuZ3VlbHRpZyB3YWVyZSB1bmQgc29taXQKKyAgICAvLyB2ZXJhbHRldGUgRGF0ZW4gYW4gZGVuIFNwaWVsZXIgYXVzZ2VnZWJlbiB3ZXJkZW4uIEltIHVuZ3VlbnN0aWdzdGVuCisgICAgLy8gRmFsbCB3dWVyZGUgZGFzIHNvZ2FyIGRhenUgZnVlaHJlbiwgZGFzcyBkaWUgdmVyYWx0ZXRlbiBEYXRlbiBsYW5nZQorICAgIC8vIFplaXQgbmljaHQgYWt0dWFsaXNpZXJ0IHdlcmRlbiwgd2VubiB6LkIuIFBfSFAgPT0gUF9NQVhfSFAsIHNvIGRhc3MKKyAgICAvLyBrZWluIFBfSFAtRXZlbnQgbWVociBlaW5nZWh0LgorICAgIHJlcG9ydF9jYWNoZT0wOworICB9CisgIGVsc2UgaWYgKHN0ciA9PSAidm9yc2ljaHQiKSB7CisgICAgaWYgKCEoY2FuZmxhZ3MgJiBDQU5fUkVQT1JUX1dJTVBZKSkgeworICAgICAgaWYgKFF1ZXJ5UXVlc3QoIlNjaHJhdCBrYW5uIG5pY2h0IGVpbnNjaGxhZmVuIik9PTEpIHsKKyAgICAgICAgU2V0UHJvcChQX0NBTl9GTEFHUywgY2FuZmxhZ3MgfCBDQU5fUkVQT1JUX1dJTVBZKTsKKyAgICAgICAgdGVsbF9vYmplY3QoTUUsICJEZXIgVm9yc2ljaHQtUmVwb3J0IHd1cmRlIGVpbmdlc2NoYWx0ZXQuXG4iKTsKKyAgICAgICAgc3RhdF9yZXBvcnRzIHw9IERPX1JFUE9SVF9XSU1QWTsKKyAgICAgIH0KKyAgICAgIGVsc2UgeworICAgICAgICB0ZWxsX29iamVjdChNRSwgYnJlYWtfc3RyaW5nKAorICAgICAgICAgICJGdWVyIGRlbiBTdGF0dXNyZXBvcnQgRGVpbmVyIFZvcnNpY2h0IG11c3N0IER1ICIKKyAgICAgICAgICAienVuYWVjaHN0IGRpZSBRdWVzdCBcIlNjaHJhdCBrYW5uIG5pY2h0IGVpbnNjaGxhZmVuXCIgIgorICAgICAgICAgICJiZXN0ZWhlbi4iLDc4KSk7CisgICAgICB9CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICBzdGF0X3JlcG9ydHMgfD0gRE9fUkVQT1JUX1dJTVBZOworICAgIH0KKyAgICAvLyBmdWVyIFNlaGVyIGF1Y2ggQmVyaWNodCBkZXIgRmx1Y2h0cmljaHR1bmcgZWluc2NoYWx0ZW4uCisgICAgaWYgKChzdGF0X3JlcG9ydHMgJiBET19SRVBPUlRfV0lNUFkpCisgICAgICAgICYmICEoc3RhdF9yZXBvcnRzICYgRE9fUkVQT1JUX1dJTVBZX0RJUikKKyAgICAgICAgJiYgKChjYW5mbGFncyAmIENBTl9SRVBPUlRfV0lNUFkpIHx8IElTX1NFRVIoTUUpKSkKKyAgICB7CisgICAgICBzdGF0X3JlcG9ydHMgfD0gRE9fUkVQT1JUX1dJTVBZX0RJUjsgICAgICAgIAorICAgIH0KKyAgfQorICAvLyBzZW5kZXQgZWlubWFsaWcgZ2VuYXUgamV0enQgZGVuIGtvbmZpZ3VyaWVydGVuIHJlcG9ydC4gS2FubiB6dW0gdGVzdGVuCisgIC8vICh2b24gVHJpZ2dlcm4pIG9kZXIgYmVpbSBMb2dpbiBiZW51dHp0IHdlcmRlbiwgd2VubiBtYW4gZWluZW4gaW5pdGlhbGVuCisgIC8vIERhdGVuYmVzdGFuZCBlcmhhbHRlbiB3aWxsLgorICBlbHNlIGlmIChzdHI9PSJzZW5kZW4iKQorICB7CisgICAgLy8gRXMgd2lyZCBBdXNnYWJlIHZvbiBMUCB1bmQgVm9yc2ljaHQgZ2V0cmlnZ2VydCwgZGFzIHNlbmRldCBiZWlkZQorICAgIC8vIFplaWxlbi4KKyAgICBzdGF0dXNfcmVwb3J0KERPX1JFUE9SVF9IUCwgUXVlcnlQcm9wKFBfSFApKTsKKyAgICBzdGF0dXNfcmVwb3J0KERPX1JFUE9SVF9XSU1QWSwgUXVlcnlQcm9wKFBfV0lNUFkpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBlbHNlIAorICAgIHJldHVybiAwOworICAvLyBudXIgYWt0dWVsbGVuIFp1c3RhbmQgYmVyaWNodGVuCisgIHNldF9yZXBvcnQoMCk7CisgIHJldHVybiAxOworfQorCitwcml2YXRlIHN0cmluZyBnZXRfcG9pc29uX2Rlc2MoaW50IHApIHsKKyAgc3RyaW5nIHJldDsKKyAgaWYgKCBpbnRwKHApICkgeworICAgIHN3aXRjaChwKSB7CisgICAgICBjYXNlIDA6ICAgIHJldD0ia2VpbnMiOyAgICAgICBicmVhazsKKyAgICAgIGNhc2UgMS4uMzogcmV0PSJsZWljaHQiOyAgICAgIGJyZWFrOworICAgICAgY2FzZSA0Li44OiByZXQ9ImdlZmFlaHJsaWNoIjsgYnJlYWs7CisgICAgICBkZWZhdWx0OiAgIHJldD0ic2VociBlcm5zdCI7ICBicmVhazsKKyAgICB9CisgICAgcmV0dXJuIHJldDsKKyAgfQorICBlbHNlIHJldHVybiAiKG5pY2h0IHZlcmZ1ZWdiYXIpIjsKK30KKworLy8gc3ByaW50ZigpLUZvcm1hdHN0cmluZ3MgZnVlciBkaWUgUmVwb3J0YXVzZ2FiZS4KKyNkZWZpbmUgUkVQT1JUTElORSAiTFA6ICUzZCwgS1A6ICUzcywgR2lmdDogJXMuXG4iCisjZGVmaW5lIFJFUE9SVExJTkVfV0lNUFkgIlZvcnNpY2h0OiAlZCwgRmx1Y2h0cmljaHR1bmc6ICVzLlxuIgorLy8gRGVmaW5lcyB6dXIgQWRyZXNzaWVydW5nIGRlciBDYWNoZS1FaW50cmFlZ2UKKyNkZWZpbmUgUkVQX0hQICAgICAwCisjZGVmaW5lIFJFUF9TUCAgICAgMQorI2RlZmluZSBSRVBfUE9JU09OIDIKKworcHJvdGVjdGVkIHZvaWQgc3RhdHVzX3JlcG9ydChpbnQgdHlwZSwgbWl4ZWQgdmFsKSB7CisgIC8vIFdlbm4gZGVyIFNwaWVsZXIgR01DUCBoYXQgdW5kIGRhcyBzaWNoIHVtIGRpZSBJbmZvcm1hdGlvbiBrdWVtbWVydCwKKyAgLy8gZXJmb2xndCBrZWluZSB0ZXh0dWVsbGUgQXVzZ2FiZSBtZWhyLiBEYWhlciByZXR1cm4sIHdlbm4gR01DUF9DaGFyKCkKKyAgLy8gZXJmb2xnIHZlcm1lbGRldCBoYXQuCisgIGludCBmbGFncyA9IFF1ZXJ5UHJvcChQX0NBTl9GTEFHUyk7CisgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgRE9fUkVQT1JUX0hQOgorICAgICAgaWYgKEdNQ1BfQ2hhciggKFsgUF9IUDogdmFsIF0pICkgKSByZXR1cm47CisgICAgICBicmVhazsKKyAgICBjYXNlIERPX1JFUE9SVF9TUDoKKyAgICAgIGlmICghKGZsYWdzICYgQ0FOX1JFUE9SVF9TUCkpIHJldHVybjsKKyAgICAgIGlmIChHTUNQX0NoYXIoIChbIFBfU1A6IHZhbCBdKSApICkgcmV0dXJuOworICAgICAgYnJlYWs7CisgICAgY2FzZSBET19SRVBPUlRfUE9JU09OOgorICAgICAgIGlmICghKGZsYWdzICYgQ0FOX1JFUE9SVF9QT0lTT04pKSByZXR1cm47CisgICAgICAgaWYgKEdNQ1BfQ2hhciggKFsgUF9QT0lTT046IHZhbCBdKSApICkgcmV0dXJuOworICAgICAgYnJlYWs7CisgICAgY2FzZSBET19SRVBPUlRfV0lNUFk6CisgICAgICBpZiAoIShmbGFncyAmIENBTl9SRVBPUlRfV0lNUFkpKSByZXR1cm47CisgICAgICBpZiAoR01DUF9DaGFyKCAoWyBQX1dJTVBZOiB2YWwgXSkgKSApIHJldHVybjsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgRE9fUkVQT1JUX1dJTVBZX0RJUjoKKyAgICAgIGlmICghKGZsYWdzICYgQ0FOX1JFUE9SVF9XSU1QWV9ESVIpKSByZXR1cm47CisgICAgICBpZiAoR01DUF9DaGFyKCAoWyBQX1dJTVBZX0RJUkVDVElPTjogdmFsIF0pICkgKSByZXR1cm47CisgICAgICBicmVhazsKKyAgfQorCisgIC8vIGtvbnZlbnRpb25lbGxlIHRleHR1ZWxsZSBBdXNnYWJlIGRlcyBSZXBvcnRzIGFiIGhpZXIuCisgIGlmICghKHR5cGUgJiBzdGF0X3JlcG9ydHMpKQorICAgIHJldHVybjsKKworICBpZiAoICFyZXBvcnRfY2FjaGUgKSB7CisgICAgcmVwb3J0X2NhY2hlID0gKHsKKyAgICAgIFF1ZXJ5UHJvcChQX0hQKSwKKyAgICAgIChzdGF0X3JlcG9ydHMmRE9fUkVQT1JUX1NQKSA/IHRvX3N0cmluZyhRdWVyeVByb3AoUF9TUCkpIDogIiMjIyIsCisgICAgICAoc3RhdF9yZXBvcnRzJkRPX1JFUE9SVF9QT0lTT04pID8KKyAgICAgICAgICBnZXRfcG9pc29uX2Rlc2MoUXVlcnlQcm9wKFBfUE9JU09OKSkgOiAiKG5pY2h0IHZlcmZ1ZWdiYXIpIgorICAgIH0pOworICB9CisKKyAgc3dpdGNoKHR5cGUpIHsKKyAgICAgIC8vIExQIGJlcmljaHRlbjogQ2FjaGUgYWt0dWFsaXNpZXJlbiB1bmQgTWVsZHVuZyBhdXNnZWJlbi4KKyAgICAgIGNhc2UgRE9fUkVQT1JUX0hQOgorICAgICAgICByZXBvcnRfY2FjaGVbUkVQX0hQXT12YWw7CisgICAgICAgIHRlbGxfb2JqZWN0KE1FLCBzcHJpbnRmKFJFUE9SVExJTkUsIHJlcG9ydF9jYWNoZVtSRVBfSFBdLAorICAgICAgICAgIHJlcG9ydF9jYWNoZVtSRVBfU1BdLCByZXBvcnRfY2FjaGVbUkVQX1BPSVNPTl0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICAvLyBLUCBiZXJpY2h0ZW46IFdlbm4gZGVyIFNwaWVsZXIgZGVuIFJlcG9ydCBmcmVpZ2VzY2hhbHRldCBoYXQsCisgICAgICAvLyB3aXJkIGJlaSBBZW5kZXJ1bmdlbiBnZW1lbGRldC4gV2VubiBuaWNodCwgYWVuZGVydCBzaWNoIG51ciBkZXIKKyAgICAgIC8vIENhY2hlLUVpbnRyYWcuIFNvIHdpcmQgdmVyaGluZGVydCwgZGFzcyBlaW4gU3BpZWxlciB1ZWJlciBLUC0KKyAgICAgIC8vIFZlcmFlbmRlcnVuZ2VuIGF1Y2ggZGFubiBpbmZvcm1pZXJ0IHd1ZXJkZSwgd2VubiBlciBkZW4gS1AtUmVwb3J0CisgICAgICAvLyBnYXIgbmljaHQgYmVudXR6ZW4ga29lbm50ZS4KKyAgICAgIGNhc2UgRE9fUkVQT1JUX1NQOgorICAgICAgICByZXBvcnRfY2FjaGVbUkVQX1NQXT10b19zdHJpbmcodmFsKTsKKyAgICAgICAgdGVsbF9vYmplY3QoTUUsIHNwcmludGYoUkVQT1JUTElORSwgcmVwb3J0X2NhY2hlW1JFUF9IUF0sCisgICAgICAgICAgcmVwb3J0X2NhY2hlW1JFUF9TUF0sIHJlcG9ydF9jYWNoZVtSRVBfUE9JU09OXSkpOworICAgICAgICBicmVhazsKKyAgICAgIC8vIEdpZnRzdGF0dXMgYmVyaWNodGVuOiBXZW5uIGRlciBHaWZ0cmVwb3J0IGZyZWlnZXNjaGFsdGV0IGlzdCwKKyAgICAgIC8vIENhY2hlIGFrdHVhbGlzaWVyZW4gdW5kIGJlcmljaHRlbi4gV2VubiBuaWNodCwgYWVuZGVydCBzaWNoIG51cgorICAgICAgLy8gZGVyIENhY2hlLUVpbnRyYWcuIEVybGFldXRlcnVuZyBoaWVyenUgcy5vLiBiZWltIEtQLVJlcG9ydC4KKyAgICAgIGNhc2UgRE9fUkVQT1JUX1BPSVNPTjoKKyAgICAgICAgcmVwb3J0X2NhY2hlW1JFUF9QT0lTT05dID0gZ2V0X3BvaXNvbl9kZXNjKHZhbCk7CisgICAgICAgIHRlbGxfb2JqZWN0KE1FLCBzcHJpbnRmKFJFUE9SVExJTkUsIHJlcG9ydF9jYWNoZVtSRVBfSFBdLAorICAgICAgICAgIHJlcG9ydF9jYWNoZVtSRVBfU1BdLCByZXBvcnRfY2FjaGVbUkVQX1BPSVNPTl0pKTsKKyAgICAgICAgYnJlYWs7CisgICAgICAvLyBWb3JzaWNodC1SZXBvcnQ6IGthbm4gb2huZSB3ZWl0ZXJlIEFiZnJhZ2VuIGF1c2dlZ2ViZW4gd2VyZGVuLCBkYQorICAgICAgLy8gYWxsZSBub2V0aWdlbiBDaGVja3Mgc2Nob24genUgQmVnaW5uIGRpZXNlciBGdW5rdGlvbiBlcmxlZGlndCB3dXJkZW4uCisgICAgICAvLyBMZWRpZ2xpY2ggZGVyIEluaGFsdCBkZXIgTWVsZHVuZyBtdXNzIGFiaGFlbmdpZyB2b20gU2VoZXJzdGF0dXMKKyAgICAgIC8vIGtvbmZpZ3VyaWVydCB3ZXJkZW4uCisgICAgICBjYXNlIERPX1JFUE9SVF9XSU1QWToKKyAgICAgICAgc3RyaW5nIHJlczsKKyAgICAgICAgaWYgKElTX1NFRVIoTUUpKSB7CisgICAgICAgICAgLy8gUXVlcnlQcm9wKCkgYXVzIEtvc3RlbmdydWVuZGVuIGltIGlmKCksIGRhbWl0IGRpZSBBdWZydWYtCisgICAgICAgICAgLy8gSGFldWZpZ2tlaXQgenVtaW5kZXN0IGVpbiB3ZW5pZyByZWR1emllcnQgd2lyZC4KKyAgICAgICAgICBzdHJpbmcgZGlyID0gUXVlcnlQcm9wKFBfV0lNUFlfRElSRUNUSU9OKXx8ImtlaW5lIjsKKyAgICAgICAgICByZXMgPSBzcHJpbnRmKFJFUE9SVExJTkVfV0lNUFksIHZhbCwgZGlyKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgcmVzID0gc3ByaW50ZihSRVBPUlRMSU5FX1dJTVBZLCB2YWwsICIobmljaHQgdmVyZnVlZ2JhcikiKTsKKyAgICAgICAgdGVsbF9vYmplY3QoTUUsIHJlcyk7CisgICAgICAgIGJyZWFrOworICAgICAgLy8gRmx1Y2h0cmljaHR1bmdzLVJlcG9ydDogd2lyZCBudXIgYmVpIFNlaGVybiBhdXNnZWdlYmVuLCBkYW1pdAorICAgICAgLy8gbmljaHQgYXVjaCBTcGllbGVyIGVpbmUgVlMtL0ZSLU1lbGR1bmcgYmVrb21tZW4sIHdlbm4gei5CLiBlaW5lCisgICAgICAvLyBleHRlcm5lIE1hbmlwdWxhdGlvbiBkZXIgRmx1Y2h0cmljaHR1bmcgc3RhdHRmaW5kZXQsIHNpZSBhYmVyIGRlbgorICAgICAgLy8gUmVwb3J0IG1hbmdlbHMgU2VoZXJzdGF0dXMgZ2FyIG5pY2h0IGZyZWlnZXNjaGFsdGV0IGhhYmVuLgorICAgICAgY2FzZSBET19SRVBPUlRfV0lNUFlfRElSOgorICAgICAgICBpZiAoSVNfU0VFUihNRSkpIHsKKyAgICAgICAgICBpZiAoIXZhbCkgdmFsID0gImtlaW5lIjsKKyAgICAgICAgICB0ZWxsX29iamVjdChNRSxzcHJpbnRmKFJFUE9SVExJTkVfV0lNUFksIFF1ZXJ5UHJvcChQX1dJTVBZKSwgdmFsKSk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgIH0KK30KKworI3VuZGVmIFJFUE9SVExJTkUKKyN1bmRlZiBSRVBPUlRMSU5FX1dJTVBZCisjdW5kZWYgUkVQX0hQCisjdW5kZWYgUkVQX1NQCisjdW5kZWYgUkVQX1BPSVNPTgorCitwcml2YXRlIHN0cmluZyBwZXJtdXRhdGUoc3RyaW5nIG1zZykKK3sKKyAgLy8gS29udHJvbGx6ZWljaGVuIHJhdXNmaWx0ZXJuLiAqc2V1ZnoqCisgIG1zZyA9IHJlZ3JlcGxhY2UobXNnLCJbWzpjbnRybDpdXSIsIiIsUkVfUENSRXxSRV9HTE9CQUwpOworICBvYmplY3Qgb2I9UXVlcnlQcm9wKFBfUEVSTV9TVFJJTkcpOworICBpZiAoIW9iamVjdHAob2IpKQorICAgIHJldHVybiBtc2c7CisKKyAgcmV0dXJuIChzdHJpbmcpb2ItPnBlcm11dGF0ZV9zdHJpbmcobXNnKXx8IiI7Cit9CisKKy8vIG5ldWUgbmFjaHJpY2h0IGFuIGRlbiBLb2JvbGQgYW5oYWVuZ2VuCisvLyBSdWVja2dhYmV3ZXJ0ZTogTVNHX0JVRkZFUl9GVUxMIG9kZXIgTVNHX0JVRkZFUkVECitwcml2YXRlIGludCBhZGRfdG9fa29ib2xkKHN0cmluZyBtc2csIGludCBtc2dfdHlwZSwgc3RyaW5nIG1zZ19hY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBtc2dfcHJlZml4LCBvYmplY3Qgb3JpZ2luKQoreworICAvLyBOYWNocmljaHQgc29sbCBpbSBLb2JvbGQgZ2VzcGVpY2hlcnQgd2VyZGVuLgorICAvLyBLb2JvbGQgc3BlaWNoZXJ0IFJvaGRhdGVuIHVuZCBnaWJ0IHNwYWV0ZXIgZGFzIGdhbnplIGF1Y2ggd2llZGVyIHZpYQorICAvLyBSZWNlaXZlTXNnKCkgYXVzIC0gZGFiZWkgd2lyZCBNU0dfRE9OVF9CVUZGRVIgfCBNU0dfRE9OVF9TVE9SRSBnZXNldHosCisgIC8vIGRhbWl0IGtlaW5lIGVybmV1dGUgU3BlaWNoZXIgaW4gS29ib2xkIG9kZXIgS29tbS1IaXN0b3J5IGVyZm9sZ3QuCisKKyAgLy8gd2VubiBkZXIgUHVmZmVyIHp1IGtsZWluIGlzdCwgR3JvZXNzZSB2ZXJkb3BwZWxuLCB3ZW5uIG5vY2ggdW50ZXJoYWxiCisgIC8vIGRlcyBMaW1pdHMuCisgIGlmIChrb2JvbGQtPmluZGV4ID49IHNpemVvZihrb2JvbGQtPmJ1ZiktMSkgeworICAgIGlmIChzaXplb2Yoa29ib2xkLT5idWYpIDwgTUFYX0tPQk9MRF9MSU1JVCkKKyAgICAgIGtvYm9sZC0+YnVmICs9IGFsbG9jYXRlKHNpemVvZihrb2JvbGQtPmJ1ZikpOworICAgIGVsc2UKKyAgICAgIHJldHVybiBNU0dfQlVGRkVSX0ZVTEw7CisgIH0KKyAga29ib2xkLT5pbmRleCA9IGtvYm9sZC0+aW5kZXggKzE7CisgIC8vIG5ldWUgTmFjaHJpY2h0IGFuIGRlbiBQdWZmZXIgYW5oYWVuZ2VuLgorICBzdHJpbmcgc2VuZGVybmFtZSA9IHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob3JpZ2luKSA/CisgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luLT5xdWVyeV9yZWFsX25hbWUoKSA6CisgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luLT5uYW1lKFdFUikgfHwgIjxVbmJla2FubnQ+IjsKKyAga29ib2xkLT5idWZba29ib2xkLT5pbmRleF0gPSAoPG1zZ19zPiBtc2c6IG1zZywKKyAgICAgIHR5cGUgOiBtc2dfdHlwZSwgYWN0aW9uIDogbXNnX2FjdGlvbiwgcHJlZml4IDogbXNnX3ByZWZpeCwKKyAgICAgIHNlbmRlcm5hbWUgOiBzZW5kZXJuYW1lKTsKKyAgcmV0dXJuIE1TR19CVUZGRVJFRDsKK30KKworcHJpdmF0ZSB2b2lkIF9mbHVzaF9jYWNoZShpbnQgdmVyYm9zZSkgeworICAvLyBudXIgbWl0IGdlbnVnIEV2YWx0aWNrcyBhdXNnZWJlbi4KKyAgaWYgKGdldF9ldmFsX2Nvc3QoKSA8IDEwMDAwMCkgcmV0dXJuOworICBpZiAoa29ib2xkLT5pbmRleCA+PSAwKQorICB7CisgICAgUmVjZWl2ZU1zZygiRWluIGtsZWluZXIgS29ib2xkIHRlaWx0IERpciBmb2xnZW5kZXMgbWl0OiIsCisgICAgICAgICAgICAgICBNVF9OT1RJRklDQVRJT058TVNHX0RPTlRfSUdOT1JFfE1TR19ET05UX0JVRkZFUiwKKyAgICAgICAgICAgICAgIDAsIDAsIHRoaXNfb2JqZWN0KCkpOworICAgIGludCBwcmVwZW5kID0gUXVlcnlQcm9wKFBfTUVTU0FHRV9QUkVQRU5EKTsKKyAgICBmb3JlYWNoKGludCBpOiAwIC4uIGtvYm9sZC0+aW5kZXgpIC8vICcwIC4uJyBpc3Qgd2ljaHRpZyEKKyAgICB7CisgICAgICBzdHJ1Y3QgbXNnX3MgbXNnID0ga29ib2xkLT5idWZbaV07CisgICAgICAvLyBkaWVzIGlzdCBkaWVudCBkZXIgRmVobGVyYWJzaWNoZXJ1bmcsIGZhbGxzIGVzIG5lbiBGZWhsZXIgKHouQi4gVExFKQorICAgICAgLy8gaW4gZGVyIFNjaGxlaWZlIHVudGVuIGdhYjogZGFubiBpc3QgaW5kZXggbmljaHQgYXVmIC0xIGdlc2V0enQKKyAgICAgIC8vIHdvcmRlbiwgYWJlciBlaW5pZ2UgTmFjaHJpY2h0ZW4gc2luZCBzY2hvbiBnZWxvZXNjaHQuCisgICAgICBpZiAoIXN0cnVjdHAobXNnKSkgY29udGludWU7CisgICAgICAvLyBBdXNnYWJlIHZpYSBlZnVuOjp0ZWxsX29iamVjdCgpLCB3ZWlsIGRpZSBBcmJlaXQgdm9uIFJlY2VpdmVNc2coKQorICAgICAgLy8gc2Nob24gZ2V0YW4gd3VyZGUuIEFsbGVyZGluZ3MgbXVlc3NlbiB3aXIgdW5zIG5vY2ggdW0gZGVuIFVNYnJ1Y2gKKyAgICAgIC8vIGt1ZW1tZXJuLgorICAgICAgaWYgKChtc2ctPnR5cGUpICYgTVNHX0RPTlRfV1JBUCkKKyAgICAgICAgbXNnLT5tc2cgPSAobXNnLT5wcmVmaXggPyBtc2ctPnByZWZpeCA6ICIiKSArIG1zZy0+bXNnOworICAgICAgZWxzZQorICAgICAgeworICAgICAgICBpbnQgYnNmbGFncyA9IG1zZy0+dHlwZSAmIE1TR19BTExfQlNfRkxBR1M7CisgICAgICAgIGlmIChwcmVwZW5kKQorICAgICAgICAgIGJzZmxhZ3MgfD0gQlNfUFJFUEVORF9JTkRFTlQ7CisgICAgICAgIG1zZy0+bXNnID0gYnJlYWtfc3RyaW5nKG1zZy0+bXNnLCA3OCwgbXNnLT5wcmVmaXgsIGJzZmxhZ3MpOworICAgICAgfQorICAgICAgZWZ1bjo6dGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwgbXNnLT5tc2cpOworICAgICAga29ib2xkLT5idWZbaV09MDsKKyAgICB9CisgICAga29ib2xkLT5pbmRleD0tMTsKKyAgfQorICBlbHNlIGlmICh2ZXJib3NlKQorICB7CisgICAgUmVjZWl2ZU1zZygiRGVyIGtsZWluZSBLb2JvbGQgaGF0IGxlaWRlciBuaWNodHMgTmV1ZXMgZnVlciBEaWNoLiIsCisgICAgICAgICAgICAgICBNVF9OT1RJRklDQVRJT058TVNHX0RPTlRfSUdOT1JFfE1TR19ET05UX0JVRkZFUiwKKyAgICAgICAgICAgICAgIDAsIDAsIHRoaXNfb2JqZWN0KCkpOworICB9Cit9CisKK3ZhcmFyZ3MgaW50IGNtZF9rb2JvbGQoc3RyaW5nIGFyZykKK3sKKyAgc3dpdGNoKGFyZykKKyAgeworICAgIGNhc2UgImVpbiI6CisgICAgICBTZXRQcm9wKFBfQlVGRkVSLCAxKTsKKyAgICAgIHByaW50ZigiRGVyIEtvYm9sZCBtZXJrdCBzaWNoIGpldHp0IGFsbGVzIVxuIik7IGJyZWFrOworICAgIGNhc2UgImF1cyI6CisgICAgICBTZXRQcm9wKFBfQlVGRkVSLCAwKTsKKyAgICAgIHByaW50ZigiRGVyIEtvYm9sZCB3aXJkIERpY2ggbmljaHQgc3RvZXJlbiFcbiIpOyBicmVhazsKKyAgICBkZWZhdWx0OiBpZihhcmcpIHByaW50ZigiRGVyIEtvYm9sZCBzYWd0OiBrb2JvbGQgZWluIG9kZXIga29ib2xkIGF1c1xuIik7CisgIH0KKyAgX2ZsdXNoX2NhY2hlKDEpOworICByZXR1cm4gMTsKK30KKworcHVibGljIGludCBUZXN0SWdub3JlU2ltcGxlKHN0cmluZyAqYXJnKQoreyAgIHN0cmluZyAqaWdub3JlOworCisgICAgaWYgKCFwb2ludGVycChhcmcpIHx8ICFtYXBwaW5ncChpZ25vcmU9UXVlcnkoUF9JR05PUkUsRl9WQUxVRSkpKQorICAgICAgICByZXR1cm4gMDsKKyAgICBmb3JlYWNoKHN0cmluZyBzOiBhcmcpCisgICAgeworICAgICAgaWYgKG1lbWJlcihpZ25vcmUscykpCisgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworLy9UT0RPOiBkZXByZWNhdGVkIC0gZW50ZmVybmVuLCB3ZW5uIE1lc3NhZ2UoKSBlbnRmZXJudCB3aXJkLgorcHJpdmF0ZSBpbnQgY2hlY2tfaWdub3JlKG1peGVkIGlnbm9yZSwgc3RyaW5nIHZlcmIsIHN0cmluZyBuYW1lKQoreworICBpZiAoaWdub3JlID09IHZlcmIpCisgICAgcmV0dXJuIDE7CisgIGlnbm9yZSA9IGV4cGxvZGUoaWdub3JlLCAiLiIpOworICByZXR1cm4gKChzaXplb2YoaWdub3JlKSA+IDEpICYmCisgICAgIChuYW1lID09IGlnbm9yZVswXSAmJiBtZW1iZXIoaWdub3JlWzEuLl0sIHZlcmIpICE9IC0xKSk7Cit9CisKK3ByaXZhdGUgaW50IGNvbW1fYmVlcCgpIHsKKyAgaWYgKFF1ZXJ5UHJvcChQX1ZJU1VBTEJFTEwpKSByZXR1cm4gMDsgLy8ga2VpbiB0b24KKyAgaW50IGJlZXBfaW50ZXJ2YWw9KGludClRdWVyeVByb3AoUF9NRVNTQUdFX0JFRVApOworICBpZiAoIWJlZXBfaW50ZXJ2YWwgfHwgKCh0aW1lKCktbGFzdF9iZWVwX3RpbWUpIDwgYmVlcF9pbnRlcnZhbCkpIHJldHVybiAwOworICBsYXN0X2JlZXBfdGltZT10aW1lKCk7CisgIHJldHVybiAxOworfQorCitwcml2YXRlIHZhcmFyZ3Mgdm9pZCBhZGRfdG9fdGVsbF9oaXN0b3J5KCBzdHJpbmcgdWlkLCBpbnQgc2VudCwgaW50IHJlY3YsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbWVzc2FnZSwgc3RyaW5nIGluZGVudCwgaW50IGZsYWdzICkKK3sKKyAgLyogdGVsbF9oaXN0b3J5IGlzdCBlaW4gTWFwcGluZyBtaXQgVUlEcyBkZXIgR2VzcHJhZWNoc3BhcnRuZXIgYWxzIEtleS4KKyAgICAgQWxzIFdlcnQgaXN0IGVpbmUgU3RydWt1ciB2b20gVHlwIGNoYXRfcyBlaW5nZXRyYWdlbi4KKyAgICAgU3RydWt0dXJlbiBjaGF0X3MgdW5kIHN0b3JlZF9tc2dfcyBzaW5kIGluIC9zdGQvcGxheWVyL2NvbW1fc3RydWN0cy5jCisgICAgIGRlZmluaWVydC4KKyAgICAgVE9ETyBmdWVyIHNwYWV0ZXIsIGdlcmFkZSBrZWluZSBaZWl0IGZ1ZXI6CisgICAgIEFscyBXZXJ0IGlzdCBlaW4gQXJyYXkgdm9uIGNoYXRfcyBlbnRoYWx0ZW4sIHdvYmVpIGRhcyAwLiBFbGVtZW50IGRhcworICAgICBqZXdlaWxzIGp1ZW5nc3RlIEdlc3ByYWVjaCBtaXQgZGllc2VtIEdlc3ByYWVjaHNwYXJ0bmVyIGlzdCB1bmQgYWxsZQorICAgICB3ZWl0ZXJlbiBFbGVtZW50ZSBpbiBkZXIgemVpdGxpY2hlbiBSZWloZW5mb2xnZSBrb21tZW4gKGFsc28gbGV0enRlcworICAgICBFbGVtZW50IGlzdCBhZWx0ZXN0ZXMgR2VzcHJhZWNoKS4KKyAgICAgKi8KKworICAvL1RPRE86IEVudGZlcm5lbiwgd2VubiBkYXMgbmljaHQgbWVociBwYXNzaWVydC4KKyAgaWYgKCFzdHJpbmdwKHVpZCkpCisgIHsKKyAgICBSZWNlaXZlTXNnKHNwcmludGYoCisgICAgICAiXG5hZGRfdG9fdGVsbF9oaXN0b3J5KCk6IGdvdCBiYWQgdWlkIGFyZ3VtZW50ICVPLiIKKyAgICAgICJzZW50OiAlZCwgcmVjdjogJWQsIGZsYWdzOiAlZCwgbXNnOiAlcyIsIAorICAgICAgdWlkLCBzZW50LCByZWN2LCBmbGFncywgbWVzc2FnZSksTVRfREVCVUd8TVNHX0JTX0xFQVZFX0xGUywwLDAsTUUpOyAgICAgICAgICAgICAgCisgIH0KKyAgCisgIC8vIGxldHp0ZW4gR2VzcHJhZWNoc3BhcnRuZXIgZnVlciBlcndpZGVyZS4KKyAgaWYgKCEoZmxhZ3MgJiBNU0dGTEFHX1JFTU9URSkpCisgICAgbGFzdF9jb21tX3BhcnRuZXIgPSB1aWQ7CisKKyAgLy8gaXN0IGVpbiBzb3J0aWVydGVzIEFycmF5IHZvbiBtYXguIE1BWF9TQVZFRF9DSEFUUyBHcm9lc3NlLCB3ZWxjaGVzIGRpZQorICAvLyBTcGllbGVyIGVudGhhZWx0LCBkZW5lbiBtYW4gc2Nob24gd2FzIG1pdGdldGVpbHQgaGF0LiBBa3R1ZWxsc3RlIGFtCisgIC8vIEFuZmFuZy4KKyAgaWYgKHNlbnQpIHsKKyAgICBpZiAoIXNpemVvZihjb21tcmVjZWl2ZXJzKSkKKyAgICAgIGNvbW1yZWNlaXZlcnMgPSAoe3VpZH0pOworICAgIGVsc2UgaWYgKGNvbW1yZWNlaXZlcnNbMF0gIT0gdWlkKSB7CisgICAgICAvLyBudXIgd2VubiBkZXIgYWt0dWVsbGUgUGFydG5lciBuaWNodCBhbSBBbmZhbmcgc3RlaHQsIG11c3MgbWFuIGhpZXIgd2FzCisgICAgICAvLyB0dW4uIENvbW0tUGFydG5lciBhbiBkZW4gQW5mYW5nIHN0ZWxsZW4gdW5kIGdnZi4gYWx0ZW4gRWludHJhZworICAgICAgLy8gZW50ZmVybmVuLgorICAgICAgLy8gVE9ETzogRWZmaXppZW50ZXIgZ2VzdGFsdGVuLgorICAgICAgY29tbXJlY2VpdmVycyA9ICh7dWlkfSkgKyAoY29tbXJlY2VpdmVycy0oe3VpZH0pKTsKKyAgICAgIC8vIGdnZi4ga3Vlcnplbi4gKHdlbm4gIXRlbGxfaGlzdG9yeV9lbmFibGVkLCB3aXJkIGVzIGdnZi4gdW50ZW4KKyAgICAgIC8vIGdlbWFjaHQsIGRlbm4gZGllIEhpc3QgbXVzcyBtaW4uIGFsbGUgVUlEIGVudGhhbHRlbiwgZGllIGF1Y2ggaW4KKyAgICAgIC8vIGNvbW1yZWNlaXZlcnMgZHJpbiBzaW5kLikKKyAgICAgIGlmICghdGVsbF9oaXN0b3J5X2VuYWJsZWQgJiYgc2l6ZW9mKGNvbW1yZWNlaXZlcnMpID4gTUFYX1NBVkVEX0NIQVRTKQorICAgICAgICBjb21tcmVjZWl2ZXJzID0gY29tbXJlY2VpdmVyc1swLi5NQVhfU0FWRURfQ0hBVFNdOworICAgIH0KKyAgfQorCisgIGlmICghdGVsbF9oaXN0b3J5X2VuYWJsZWQpCisgICAgcmV0dXJuOworCisgIGlmICghaW5kZW50ICYmIG1lc3NhZ2VbPDFdID09IDEwKQorICAgICAgbWVzc2FnZSA9IG1lc3NhZ2VbLi48Ml07CisKKyAgc3RydWN0IGNoYXRfcyBjaGF0OworICAvLyBHZXNwcmFlY2hzcGFydG5lciB1bmJla2FubnQ/CisgIGlmICghbWVtYmVyKHRlbGxfaGlzdG9yeSwgdWlkKSkgeworICAgIC8vIHp1dmllbGUgR2VzcHJhZWNoZSBpbiBIaXN0PyA+PSBpc3QgQWJzaWNodCB3ZWlsIGphIGdsZWljaCBub2NoIGVpbnMKKyAgICAvLyBkYXp1IGtvbW10LgorICAgIGlmIChzaXplb2YodGVsbF9oaXN0b3J5KSA+PSBNQVhfU0FWRURfQ0hBVFMpIHsKKyAgICAgIHN0cmluZyBkZWx1aWQ7CisgICAgICBpbnQgemVpdCA9IF9fSU5UX01BWF9fOworICAgICAgZm9yZWFjaChzdHJpbmcgdHVpZCwgY2hhdCA6IHRlbGxfaGlzdG9yeSkgeworICAgICAgICAvLyBhZWx0ZXN0ZXMgR2VzcHJhZWNoIHN1Y2hlbgorICAgICAgICBpZiAoemVpdCA+IGNoYXQtPnRpbWVfbGFzdF9tc2cpIHsKKyAgICAgICAgICBkZWx1aWQgPSB0dWlkOworICAgICAgICAgIHplaXQgPSBjaGF0LT50aW1lX2xhc3RfbXNnOworICAgICAgICB9CisgICAgICB9CisgICAgICAvLyBhZWx0ZXN0ZXMgR2VzcHJhZWNoIHJhdXMuCisgICAgICBtX2RlbGV0ZSh0ZWxsX2hpc3RvcnksIGRlbHVpZCk7CisgICAgICBpZiAobWVtYmVyKGNvbW1yZWNlaXZlcnMsZGVsdWlkKT4tMSkKKyAgICAgICAgY29tbXJlY2VpdmVycy09KHtkZWx1aWR9KTsKKyAgICB9CisgICAgLy8gbmV1ZXMgR2VzcHJhZWNoIGFubGVnZW4KKyAgICBjaGF0ID0gKDxjaGF0X3M+IHVpZDogdWlkLCB0aW1lX2ZpcnN0X21zZzogdGltZSgpLCAKKyAgICAgICAgICAgICAgIHRpbWVfbGFzdF9tc2c6IHRpbWUoKSwKKyAgICAgICAgIHNlbnRjb3VudDogc2VudCwgcmVjdmNvdW50OiByZWN2LAorICAgICAgICAgbXNnYnVmOiAwLCBwdHI6IDAgKTsKKyAgICB0ZWxsX2hpc3RvcnlbdWlkXSA9IGNoYXQ7CisgIH0KKyAgZWxzZSB7CisgICAgLy8gR2VzcHJhZWNoc3BhcnRuZXIgYmVrYW5udCwgYWx0ZXMgR2VzcHJhZWNoIHdlaXRlcmJlbnV0emVuCisgICAgY2hhdCA9IHRlbGxfaGlzdG9yeVt1aWRdOworICAgIGNoYXQtPnRpbWVfbGFzdF9tc2cgPSB0aW1lKCk7CisgICAgY2hhdC0+c2VudGNvdW50ICs9IHNlbnQ7CisgICAgY2hhdC0+cmVjdmNvdW50ICs9IHJlY3Y7CisgIH0KKworICBpZiAodGVsbF9oaXN0b3J5X2VuYWJsZWQgPCBURUxMSElTVF9FTkFCTEVEKQorICAgIHJldHVybjsKKworICAvLyBnZ2YuIEFycmF5IGZ1ZXIgTWVzc2FnZXMgYW5sZWdlbgorICBpZiAoIXBvaW50ZXJwKGNoYXQtPm1zZ2J1ZikpCisgICAgY2hhdC0+bXNnYnVmID0gYWxsb2NhdGUoTUFYX1NBVkVEX01FU1NBR0VTKTsKKworICAvLyBNZXNzYWdlLVN0cnVrdHVyIGVybWl0dGVsbiBvZGVyIG5ldSBhbmxlZ2VuCisgIHN0cnVjdCBzdG9yZWRfbXNnX3MgbXNnOworICBpZiAoIXN0cnVjdHAoY2hhdC0+bXNnYnVmW2NoYXQtPnB0cl0pKSB7CisgICAgLy8gbmV1ZSBTdHJ1Y3QgaW5zIEFycmF5IHNjaHJlaWJlbgorICAgIGNoYXQtPm1zZ2J1ZltjaGF0LT5wdHJdID0gbXNnID0gKDxzdG9yZWRfbXNnX3M+KTsKKyAgfQorICBlbHNlIHsKKyAgICAvLyBhbHRlIFN0cnVjdCB1ZWJlcnNjaHJlaWJlbgorICAgIG1zZyA9IGNoYXQtPm1zZ2J1ZltjaGF0LT5wdHJdOworICB9CisgIC8vIEluZGV4IGF1ZiBuYWVjaHN0ZSBNZXNzYWdlc3RydWt0dXIgZXJtaXR0ZWxuCisgIGNoYXQtPnB0ciA9IChjaGF0LT5wdHIgKyAxKSAlIE1BWF9TQVZFRF9NRVNTQUdFUzsKKyAgLy8gTWVzc2FnZSBzcGVpY2hlcm4KKyAgbXNnLT5tc2cgPSBtZXNzYWdlOworICBtc2ctPnByZWZpeCA9IGluZGVudDsKKyAgbXNnLT50aW1lc3RhbXAgPSB0aW1lKCk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNsZWFyX3RlbGxfaGlzdG9yeSgpCit7CisgIC8qIE5hY2ggZWluZW0gInNjaGxhZmUgZWluIiB3ZXJkZW4gZGllIGdlc3BlaWNoZXJ0ZW4gTWl0dGVpbHVuZ2VuIGdlbG9lc2NodCwKKyAgICAgc29mZXJuIGRlciBTcGllbGVyIG5pY2h0cyBhYndlaWNoZW5kZXMgZWluZ2VzdGVsbHQgaGF0LiAqLworCisjaWZkZWYgVEVMTEhJU1RfTE9OR0xJRkUKKyAgaWYgKHRlbGxfaGlzdG9yeV9lbmFibGVkID09IFRFTExISVNUX0xPTkdMSUZFKQorICAgIHJldHVybjsKKyNlbmRpZgorCisgIGZvcmVhY2ggKHN0cmluZyB1aWQsIHN0cnVjdCBjaGF0X3MgY2hhdDogdGVsbF9oaXN0b3J5KQorICAgIGlmIChwb2ludGVycChjaGF0LT5tc2didWYpKSB7CisgICAgICBjaGF0LT5tc2didWYgPSAwOworICAgICAgY2hhdC0+cHRyID0gMDsKKyAgICB9Cit9CisKK3Byb3RlY3RlZCB2b2lkIHJlc2V0KHZvaWQpCit7CisgIC8qIFdpcmQgMTUgTWludXRlbiBuYWNoIGRlbSBWZXJsdXN0IGRlciBWZXJiaW5kdW5nIGF1ZmdlcnVmZW4uIEZhbGxzIGRlcgorICAgICBTcGllbGVyIG5pY2h0IGluendpc2NoZW4gZWluZSBWZXJiaW5kdW5nIHdpZWRlcmhlcmdlc3RlbGx0IGhhdCwgd2VyZGVuCisgICAgIHdpZSBiZWkgZWluZW0gInNjaGxhZmUgZWluIiBkaWUgTWl0dGVpbHVuZ2VuIGdlbG9lc2NodC4gKi8KKworICBpZiAoIWludGVyYWN0aXZlKCkpCisgICAgY2xlYXJfdGVsbF9oaXN0b3J5KCk7CisKK30KKworLy8gZ2VydWZlbiwgd2VubiB6aWVsZ2VyaWNodGV0IG1pdCBqZW1hbmRlbSBrb21tdW5pemllcnQgd2lyZCBfdW5kXyBkYXMKKy8vIEVyZ2VibmlzIGRlcyBSZWNlaXZlTXNnKCkgZ2VwcnVlZnQgd2VyZGVuIHVuZCBlaW5lIE1lbGR1bmcgYXVzZ2VnZWJlbgorLy8gd2VyZGVuIHNvbGwuCitwcml2YXRlIHZvaWQgX3NlbmQob2JqZWN0IG9iLCBzdHJpbmcgbXNnLCBpbnQgbXNnX3R5cGUsCisgICAgICAgICAgICAgICAgICAgc3RyaW5nIG1zZ19hY3Rpb24sIHN0cmluZyBtc2dfcHJlZml4KQoreworICBpbnQgcmVzID0gb2ItPlJlY2VpdmVNc2cobXNnLCBtc2dfdHlwZSwgbXNnX2FjdGlvbiwgbXNnX3ByZWZpeCwgTUUpOworICBzd2l0Y2gocmVzKSB7CisgICAgY2FzZSBNU0dfREVMSVZFUkVEOgorICAgICAgYnJlYWs7ICAvLyBuaXggbWFjaGVuCisgICAgY2FzZSBNU0dfQlVGRkVSRUQ6CisgICAgICBSZWNlaXZlTXNnKG9iLT5OYW1lKFdFUikgKyAiIG1vZWNodGUgZ2VyYWRlIG5pY2h0IGdlc3RvZXJ0IHdlcmRlbi4iCisgICAgICAgICAgIkRpZSBNaXR0ZWlsdW5nIHd1cmRlIHZvbiBlaW5lbSBrbGVpbmVuIEtvYm9sZCBpbiBFbXBmYW5nICIKKyAgICAgICAgICAiZ2Vub21tZW4uIEVyIHdpcmQgc2llIHNwYWV0ZXIgd2VpdGVybGVpdGVuISIsCisgICAgICAgICAgTVRfTk9USUZJQ0FUSU9OLCBtc2dfYWN0aW9uLCAwLCB0aGlzX29iamVjdCgpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTVNHX0lHTk9SRUQ6CisgICAgY2FzZSBNU0dfVkVSQl9JR046CisgICAgY2FzZSBNU0dfTVVEX0lHTjoKKyAgICAgIFJlY2VpdmVNc2cob2ItPk5hbWUoV0VSKSArICIgaG9lcnQgZ2FyIG5pY2h0IHp1LCB3YXMgRHUgc2Fnc3QuIiwKKyAgICAgICAgICAgTVRfTk9USUZJQ0FUSU9OLCBtc2dfYWN0aW9uLCAwLCB0aGlzX29iamVjdCgpKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgTVNHX1NFTlNFX0JMT0NLOgorICAgICAgUmVjZWl2ZU1zZyhvYi0+TmFtZShXRVIpICsgIiBrYW5uIERpY2ggbGVpZGVyIG5pY2h0IHdhaHJuZWhtZW4uIiwKKyAgICAgICAgICBNVF9OT1RJRklDQVRJT04sIG1zZ19hY3Rpb24sIDAsIHRoaXNfb2JqZWN0KCkpOworICAgICAgYnJlYWs7CisgICAgY2FzZSBNU0dfQlVGRkVSX0ZVTEw6CisgICAgICBSZWNlaXZlTXNnKG9iLT5OYW1lKFdFUikgKyAiIG1vZWNodGUgZ2VyYWRlIG5pY2h0IGdlc3RvZXJ0IHdlcmRlbi4iCisgICAgICAgICAgIkRpZSBNaXR0ZWlsdW5nIGdpbmcgdmVybG9yZW4sIGRlbm4gZGVyIEtvYm9sZCBrYW5uIHNpY2ggIgorICAgICAgICAgICJuaWNodHMgbWVociBtZXJrZW4hIiwgTVRfTk9USUZJQ0FUSU9OLCBtc2dfYWN0aW9uLCAKKyAgICAgICAgICAwLCB0aGlzX29iamVjdCgpKTsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICBSZWNlaXZlTXNnKG9iLT5OYW1lKFdFUikgKyAiIGhhdCBEZWluZSBOYWNocmljaHQgbGVpZGVyIG5pY2h0ICIKKyAgICAgICAgICAibWl0YmVrb21tZW4uIiwgTVRfTk9USUZJQ0FUSU9OLCBtc2dfYWN0aW9uLCAwLCB0aGlzX29iamVjdCgpKTsKKyAgICAgIGJyZWFrOworICB9Cit9CisKKy8vIEF1c2dhYmUgYW4gZGFzIE9iamVrdCBzZWxiZXIgdW5kIEF1ZnplaWNobnVuZyBpbiBkZXIgS29tbWhpc3RvcnksIGZhbGxzCisvLyBub2V0aWcuIFdpcmQgYmVpIF9hdXNnZWhlbmRlbl8gTmFjaHJpY2h0ZW4gaW0gZWlnZW5lbiBPYmpla3QgZ2VydWZlbiwgZGFtaXQKKy8vIGRpZSBOYWNocmljaHQgZ2dmLiBpbiBkZW4gS29tbWhpc3RvcnkgZXJmYXNzdCB3aXJkLgorLy8gVE9ETzogZW50ZmVybmVuLCB3ZW5uIGFsbGVzIEF1ZnJ1ZmVyIGVyc2V0enQgc2luZCBkdXJjaCBSZWNlaXZlTXNnKCkuCitwcm90ZWN0ZWQgdmFyYXJncyBpbnQgX3JlY3Yob2JqZWN0IG9iLCBzdHJpbmcgbWVzc2FnZSwgaW50IGZsYWcsIHN0cmluZyBpbmRlbnQpCit7CisgIHdyaXRlKGJyZWFrX3N0cmluZyhtZXNzYWdlLCA3OCwgaW5kZW50LAorICAgICAgICBRdWVyeVByb3AoUF9NRVNTQUdFX1BSRVBFTkQpID8gQlNfUFJFUEVORF9JTkRFTlQgOiAwKSk7CisgIGlmICgoZmxhZyAmIE1TR0ZMQUdfVEVMTCB8fCBmbGFnICYgTVNHRkxBR19SRU1PVEUpICYmCisgICAgICBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iKSkKKyAgeworICAgIGlmIChmbGFnICYgTVNHRkxBR19XSElTUEVSKQorICAgICAgYWRkX3RvX3RlbGxfaGlzdG9yeShnZXR1aWQob2IpLCAxLCAwLAorICAgICAgICAiRHUgZmx1ZXN0ZXJzdCAiICsgb2ItPm5hbWUoV0VNKSArICIgYXVzIGRlciBGZXJuZSBldHdhcyB6dS4iLCAwLAorICAgICAgICBmbGFnKTsKKyAgICBlbHNlCisgICAgICBhZGRfdG9fdGVsbF9oaXN0b3J5KGdldHVpZChvYiksIDEsIDAsIG1lc3NhZ2UsIGluZGVudCwgZmxhZyk7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKKy8vIDxzZW5kZXI+IHNvbGx0ZSBlaW4gT2JqZWt0IHNlaW4uIEluIHNlbHRlbmVuIEZhZWxsZW4gKHouQi4KKy8vIEZlaGxlcmJlaGFuZGx1bmcpIGlzdCBlcyBqZWRvY2ggYXVjaCBtYWwgZWluIFN0cmluZy4KK3ZhcmFyZ3MgaW50IE1lc3NhZ2Uoc3RyaW5nIG1zZywgaW50IGZsYWcsIHN0cmluZyBpbmRlbnQsCisgICAgICAgICAgICAgICAgICAgIHN0cmluZyBjbmFtZSwgbWl4ZWQgc2VuZGVyKQoreworICBvYmplY3QgdGk7CisgIHN0cmluZyB2ZXJiLCByZXBseSwgKmlnbm9yZSwgdGluOworICBpbnQgZW0sIHRlOworICBtaXhlZCBkZWFmOworCisgIC8vIEJlaSBkZW4gS2FuYWVsZW4gJ0RlYnVnJyB1bmQgJ0VudHdpY2tsdW5nJyBrYW5uIG1hbiBnZXppZWx0IEJ1Z3MKKyAgLy8gZWluemVsbmVyIE1hZ2llciBpZ25vcmllcmVuLiBEYXp1IHdpcmQgZGVyIEthbmFsbmFtZSB6dW0gJ3ZlcmInLAorICAvLyBkYW1pdCAnaWdub3JpZXJlIG5hbWUuZGVidWcnIGZ1bmt0aW9uaWVydC4KKyAgaWYoIGZsYWcgPT0gTVNHRkxBR19DSEFOTkVMICl7CisgICAgICBpZigobXNnWzEuLjVdID09ICJEZWJ1ZyIgfHwgbXNnWzEuLjExXSA9PSAiRW50d2lja2x1bmciCisgICAgICAgICAgICB8fCBtc2dbMS4uOV09PSJXYXJudW5nZW4iKSkKKyAgICAgIHsKKyAgICAgICAgLy8gTWlzc2JyYXVjaCBkZXIgVmFyaWFibGUgJ2lnbm9yZScgYWxzIFp3aXNjaGVuc3BlaWNoZXIKKyAgICAgICAgaWdub3JlID0gcmVnZXhwbG9kZSggbXNnLCAiOnwgfFxcXSIgKTsKKyAgICAgICAgdmVyYiA9IGxvd2VyX2Nhc2UoaWdub3JlWzBdWzEuLl0pOworICAgICAgICB0aW4gPSBsb3dlcl9jYXNlKGlnbm9yZVsyXSk7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIGlmKGNuYW1lKQorICAgICAgICAgIHZlcmI9bG93ZXJfY2FzZShjbmFtZSk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICB2ZXJiPXF1ZXJ5X3ZlcmIoKTsKKyAgICAgICAgaWYoIHRpID0gdGhpc19pbnRlcmFjdGl2ZSgpICkKKyAgICAgICAgeworICAgICAgICAgIHRpbiA9IGdldHVpZCh0aGlzX2ludGVyYWN0aXZlKCkpOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgIC8vZmFsbHMgZG9jaCBrZWluIE9iamVrdC4uLgorICAgICAgICAgIGlmIChvYmplY3RwKHNlbmRlcikpCisgICAgICAgICAgICB0aW49bG93ZXJfY2FzZShzZW5kZXItPm5hbWUoUkFXKXx8IjxVbmJla2FubnQ+Iik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgfQorICBlbHNlIHsKKyAgICBpZiggdGkgPSB0aGlzX2ludGVyYWN0aXZlKCkgKQorICAgICAgdGluID0gZ2V0dWlkKHRoaXNfaW50ZXJhY3RpdmUoKSk7CisgICAgdmVyYiA9IHF1ZXJ5X3ZlcmIoKTsKKyAgfQorCisgIHRlID0gZmxhZyAmIChNU0dGTEFHX1RFTEwgfCBNU0dGTEFHX1dISVNQRVIpOworCisgIC8vIGZ1ZXIgImVyd2lkZXJlIgorICBpZiAodGkgJiYgKGZsYWcgJiBNU0dGTEFHX1RFTEwgfHwgZmxhZyAmIE1TR0ZMQUdfUkVNT1RFKSkgeworICAgIGlmICghdGktPlF1ZXJ5UHJvcChQX0lOVklTKXx8SVNfTEVBUk5FUihNRSkpIHsKKyAgICAgIGlmIChmbGFnICYgTVNHRkxBR19XSElTUEVSKQorICAgICAgICBhZGRfdG9fdGVsbF9oaXN0b3J5KGdldHVpZCh0aSksIDAsIDEsCisgICAgICAgICAgY2FwaXRhbGl6ZSgoKChJU19MRUFSTkVSKHRpKSAmJiAhdGktPlF1ZXJ5UHJvcChQX0lOVklTKSAmJgorICAgICAgICAgICAgKHRpLT5RdWVyeVByb3AoUF9DQU5fRkxBR1MpICYgQ0FOX1BSRVNBWSkpID8KKyAgICAgICAgICAgIHRpLT5RdWVyeVByb3AoUF9QUkVTQVkpIDogIiIpICsgdGktPm5hbWUoKSkgfHwgIiIpICsKKyAgICAgICAgICAiIGZsdWVzdGVydCBEaXIgYXVzIGRlciBGZXJuZSBldHdhcyB6dS4iLCAwLCBmbGFnLCAwKTsKKyAgICAgIGVsc2UKKyAgICAgICAgYWRkX3RvX3RlbGxfaGlzdG9yeShnZXR1aWQodGkpLCAwLCAxLCBtc2csIGluZGVudCwgZmxhZywgMCk7CisgICAgfQorICB9CisgIC8vIEhvZXJ0IGRlciBTcGllbGVyIG5pY2h0PworICBlbSA9ICh0aSAmJgorICAgICAgICAodGUgfHwgZmxhZyAmIE1TR0ZMQUdfU0hPVVQpICYmCisgICAgICAgIChRdWVyeVByb3AoUF9FQVJNVUZGUykgJiYKKyAgICAgICAgICAocXVlcnlfd2l6X2xldmVsKHRpKSA8IFF1ZXJ5UHJvcChQX0VBUk1VRkZTKSkpKTsKKyAgaWdub3JlID0gKHBvaW50ZXJwKGlnbm9yZSA9IFF1ZXJ5UHJvcChQX0lHTk9SRSkpID8gaWdub3JlIDogKHt9KSk7CisKKyAgLy8gV2VyZGVuIGRlciBTZW5kZXIgb2RlciBkYXMgVmVyYiBpZ25vcmllcnQ/CisgIGlmKCF0aSAmJiB0aW4gJiYgZmxhZyA9PSBNU0dGTEFHX0NIQU5ORUwpCisgIHsKKyAgICAgaWYoKG1lbWJlcihpZ25vcmUsIHRpbikgIT0gLTEpKQorICAgICB7CisgICAgICAgcmV0dXJuIE1FU1NBR0VfSUdOT1JFX1lPVTsKKyAgICAgfQorICAgICBpZih2ZXJiICYmICBzaXplb2YoZmlsdGVyKGlnbm9yZSwgIydjaGVja19pZ25vcmUsIHZlcmIsIHRpbikpICkKKyAgICAgeworICAgICAgIHJldHVybiBNRVNTQUdFX0lHTk9SRV9ZT1U7CisgICAgIH0KKyAgfQorICBpZiAodGkgJiYgKG1lbWJlcihpZ25vcmUsIGdldHVpZCh0aSkpICE9IC0xKSkgeworICAgIGlmKHRlICYmIChJU19MRUFSTkVSKHRpKXx8IVF1ZXJ5UHJvcChQX0lOVklTKSkpCisgICAgICBlZnVuOjp0ZWxsX29iamVjdCh0aSwgY2FwaXRhbGl6ZShuYW1lKCkpKworICAgICAgICAgICAgICAgICAgICAgICIgaG9lcnQgZ2FyIG5pY2h0IHp1LCB3YXMgRHUgc2Fnc3QuXG4iKTsKKyAgICByZXR1cm4gTUVTU0FHRV9JR05PUkVfWU9VOworICB9CisgIGlmKHRpbiAmJiB2ZXJiICYmCisgICAgIHNpemVvZihmaWx0ZXIoaWdub3JlLCAjJ2NoZWNrX2lnbm9yZS8qJyovLCB2ZXJiLCB0aW4pKSkKKyAgeworICAgIGlmKHRpICYmIHZlcmJbMC4uMl0gIT0gInJ1ZiIgJiYgdmVyYlswLi4zXSAhPSAibXJ1ZiIgJiYKKyAgICAgICB2ZXJiWzAuLjNdICE9ICJlY2hvIiAmJiB2ZXJiWzBdICE9ICctJyAmJiAhKGZsYWcgJiBNU0dGTEFHX0NIQU5ORUwpICkKKyAgICAgIGVmdW46OnRlbGxfb2JqZWN0KHRpLCBuYW1lKCkrIiB3ZWhydCBcIiIrdmVyYisiXCIgYWIuXG4iKTsKKyAgICByZXR1cm4gTUVTU0FHRV9JR05PUkVfVkVSQjsKKyAgfQorICBpZiAoZmxhZyAmIE1TR0ZMQUdfUlRFTEwpIHsKKyAgICBpbnQgYXQ7CisKKyAgICB2ZXJiID0gbG93ZXJfY2FzZShvbGRfZXhwbG9kZShtc2csICIgIilbMF1bMS4uXSk7CisgICAgYXQgPSBtZW1iZXIodmVyYiwgJ0AnKTsKKyAgICAvKiB2ZXJiIHdpcmQgaGllciBlaCBtaXNzYnJhdWNodCwgYWxzbyBhdWNoIGZ1ZXIgZWluIGludGVybXVkLWVyd2lkZXJlKi8KKyAgICBhZGRfdG9fdGVsbF9oaXN0b3J5KHZlcmIsIDAsIDEsIG1zZywgaW5kZW50LCBmbGFnLCAwKTsKKworICAgIGlmICgobWVtYmVyKGlnbm9yZSwgdmVyYikgPj0gMCkgfHwgKG1lbWJlcihpZ25vcmUsdmVyYlswLi5hdF0pID49IDApKQorICAgICAgcmV0dXJuIE1FU1NBR0VfSUdOT1JFX1lPVTsKKyAgICBlbHNlIGlmIChhdCA+IDAgJiYgbWVtYmVyKGlnbm9yZSwgdmVyYlthdC4uXSkgPj0gMCkKKyAgICAgIHJldHVybiBNRVNTQUdFX0lHTk9SRV9NVUQ7CisgIH0KKworICAvLyBUYXViaGVpdC9Pcm9wYXgKKyAgdGUgfD0gKGZsYWcgJiBNU0dGTEFHX1NBWSk7CisKKyAgaWYgKFF1ZXJ5UHJvcChQX0RFQUYpICYmIChmbGFnICYgTVNHRkxBR19ERUFGQ0hLKSAmJiAhKGZsYWcgJiBNU0dGTEFHX0NISVNUKSkgeworICAgIGRlYWYgPSBRdWVyeVByb3AoUF9ERUFGKTsKKyAgICBpZiAodGUpCisgICAgICByZXBseSA9IHN0cmluZ3AoZGVhZikgPworICAgICAgICBjYXBpdGFsaXplKHNwcmludGYoZGVhZiwgbmFtZSgpKSkgOgorICAgICAgICBjYXBpdGFsaXplKG5hbWUoKSkrIiBpc3QgbW9tZW50YW4gbGVpZGVyIHRhdWIuXG4iOworICB9CisgIGVsc2UgaWYgKGVtKQorICAgIHJlcGx5ID0gY2FwaXRhbGl6ZShuYW1lKCkpKyIgaGF0IE9yb3BheCBpbiBkZW4gT2hyZW4uXG4iOworCisgIG1zZyA9IGJyZWFrX3N0cmluZyhtc2csIDc4LCBpbmRlbnQsCisgICAgKFF1ZXJ5UHJvcChQX01FU1NBR0VfUFJFUEVORCkgPyBCU19QUkVQRU5EX0lOREVOVCA6IDApIHwgQlNfTEVBVkVfTVlfTEZTKTsKKworICBpZihRdWVyeVByb3AoUF9CVUZGRVIpICYmCisgICAgIChkZWFmIHx8CisgICAgICBxdWVyeV9lZGl0aW5nKHRoaXNfb2JqZWN0KCkpIHx8CisgICAgICBxdWVyeV9pbnB1dF9wZW5kaW5nKHRoaXNfb2JqZWN0KCkpKSkKKyAgeworICAgIGRlYWYgPSBNRVNTQUdFX0RFQUY7CisgICAgaWYoZmxhZyAmIE1TR0ZMQUdfQ0FDSEUpCisgICAgeworICAgICAgaWYoIXN0cmluZ3AocmVwbHkpKQorICAgICAgICByZXBseSA9IG5hbWUoKSsiIG1vZWNodGUgZ2VyYWRlIG5pY2h0IGdlc3RvZXJ0IHdlcmRlbi5cbiI7CisKKyAgICAgIG1zZyA9IG1zZ1swLi48Ml0rIiBbIiArIHN0cmZ0aW1lKCIlSDolTSIsdGltZSgpKSArICJdXG4iOworCisgICAgICBpbnQgcmVzID0gIGFkZF90b19rb2JvbGQobXNnLCAwLCAwLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdHAoc2VuZGVyKSA/IHNlbmRlciA6IE1FKTsKKyAgICAgIGlmKHJlcyA9PSBNU0dfQlVGRkVSRUQpCisgICAgICB7CisKKyAgICAgICAgcmVwbHkgKz0gIkRpZSBNaXR0ZWlsdW5nIHd1cmRlIHZvbiBlaW5lbSBrbGVpbmVuIEtvYm9sZCBpbiBFbXBmYW5nICIrCisgICAgICAgICAgICAgICAgICJnZW5vbW1lbi5cbkVyIHdpcmQgc2llIHNwYWV0ZXIgd2VpdGVybGVpdGVuISI7CisgICAgICAgIGRlYWYgPSBNRVNTQUdFX0NBQ0hFOworICAgICAgfQorICAgICAgZWxzZSB7CisgICAgICAgIHJlcGx5ICs9ICJEaWUgTWl0dGVpbHVuZyBnaW5nIHZlcmxvcmVuLCBkZW5uICIrCisgICAgICAgICAgICAgICAgICJkZXIgS29ib2xkIGthbm4gc2ljaCBuaWNodHMgbWVociBtZXJrZW4hIjsKKyAgICAgICAgZGVhZiA9IE1FU1NBR0VfQ0FDSEVfRlVMTDsKKyAgICAgIH0KKyAgICAgIGlmKHRpICYmIChJU19MRUFSTkVSKHRpKXx8IVF1ZXJ5UHJvcChQX0lOVklTKSkpCisgICAgICAgIGVmdW46OnRlbGxfb2JqZWN0KHRpLCByZXBseSsiXG4iKTsKKyAgICB9CisgICAgcmV0dXJuIGRlYWY7CisgIH0KKyAgZWxzZSBpZigoZGVhZiB8fCBlbSkgJiYKKyAgICAgICAgICAoIChmbGFnICYgTVNHRkxBR19SVEVMTCkgfHwKKyAgICAgICAgICAgICh0aSAmJiAoSVNfTEVBUk5FUih0aSl8fCFRdWVyeVByb3AoUF9JTlZJUykpKSkpIHsKKyAgICBpZiAodGUgJiYgdGkpCisgICAgICBlZnVuOjp0ZWxsX29iamVjdCh0aSwgcmVwbHkpOworICAgIHJldHVybiBNRVNTQUdFX0RFQUY7CisgIH0KKworICBfZmx1c2hfY2FjaGUoMCk7CisgIGlmKHRlICYmIFF1ZXJ5UHJvcChQX0FXQVkpKQorICAgIG1zZyA9IG1zZ1swLi48Ml0rIiBbIiArIHN0cmZ0aW1lKCIlSDolTSIsdGltZSgpKSArICJdXG4iOworCisgIGlmIChmbGFnICYgKE1TR0ZMQUdfU0FZIHwgTVNHRkxBR19URUxMKSAmJiBjb21tX2JlZXAoKSkgeworICAgIG1zZz1NRVNTQUdFX0JFRVArbXNnOworICB9CisgIGVmdW46OnRlbGxfb2JqZWN0KE1FLCBtc2cpOworICByZXR1cm4gTUVTU0FHRV9PSzsKK30KKworc3RhdGljIGludCBpZ25vcmllcmUoc3RyaW5nIHN0cikKK3sKKyAgc3RyID0gX3VucGFyc2VkX2FyZ3MoMSk7CisgIG1hcHBpbmcgaWdub3JlPVF1ZXJ5KFBfSUdOT1JFLCBGX1ZBTFVFKTsKKworICBpZiAoIXN0cikKKyAgeworICAgIHN0cmluZyogaWduYXJyID0gbV9pbmRpY2VzKGlnbm9yZSk7CisgICAgaWYgKCFzaXplb2YoaWduYXJyKSkKKyAgICAgICAgdGVsbF9vYmplY3QoTUUsICJEdSBpZ25vcmllcnN0IG5pZW1hbmRlbi5cbiIpOworICAgICAgZWxzZQorICAgICAgICBSZWNlaXZlTXNnKCJEdSBpZ25vcmllcnN0OlxuIgorICAgICAgICAgICAgICAgICAgICsgYnJlYWtfc3RyaW5nKENvdW50VXAobWFwKHNvcnRfYXJyYXkoaWduYXJyLCAjJz4gKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMnY2FwaXRhbGl6ZSApIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApICsgIi4iLDc4KSwKKyAgICAgICAgICAgICAgICAgICBNVF9OT1RJRklDQVRJT058TVNHX0RPTlRfSUdOT1JFfE1TR19ET05UX1NUT1JFfE1TR19ET05UX1dSQVAsCisgICAgICAgICAgICAgICAgICAgMCwwLHRoaXNfb2JqZWN0KCkpOworICAgICAgcmV0dXJuIDE7CisgIH0KKyAgLy8gdHJpbSBzcGFjZXMgZnJvbSBhcmdzIGFuZCBjb252ZXJ0IHRvIGxvd2VyIGNhc2UuCisgIHN0ciA9IGxvd2VyX2Nhc2UodHJpbShzdHIsIFRSSU1fQk9USCkpOworCisgIGlmIChtZW1iZXIoaWdub3JlLCBzdHIpKQorICB7CisgICAgUmVtb3ZlSWdub3JlKHN0cik7CisgICAgdGVsbF9vYmplY3QoTUUsIHNwcmludGYoIkR1IGlnbm9yaWVyc3QgJXMgbmljaHQgbWVoci5cbiIsIGNhcGl0YWxpemUoc3RyKSkpOworICB9CisgIGVsc2UgaWYgKHNpemVvZihpZ25vcmUpPjEwMCkKKyAgeworICAgdGVsbF9vYmplY3QoTUUsICJEdSBpZ25vcmllcnN0IHNjaG9uIGdlbnVlZ2VuZCFcbiIpOworICB9CisgIGVsc2UgaWYgKEFkZElnbm9yZShzdHIpID09IDEpCisgIHsKKyAgICB0ZWxsX29iamVjdChNRSwKKyAgICAgICAgc3ByaW50ZigiRHUgaWdub3JpZXJzdCBqZXR6dCAlcy5cbiIsIGNhcGl0YWxpemUoc3RyKSkpOworICB9CisgIGVsc2UKKyAgeworICAgIHRlbGxfb2JqZWN0KE1FLAorICAgICAgICBzcHJpbnRmKCInJXMnIGthbm5zdCBEdSBuaWNodCBpZ25vcmllcmVuLlxuIixzdHIpKTsKKyAgfQorICByZXR1cm4gMTsKK30KKworCitzdGF0aWMgaW50IF9tc2dfYmVlcChzdHJpbmcgc3RyKSB7CisgIGludCBiZWVwX2ludGVydmFsOworICBub3RpZnlfZmFpbCgiU3ludGF4OiBrbGluZ2VsdG9uIDwxIGJpcyAzNjAwIFNla3VuZGVuPiBvZGVyIGtsaW5nZWx0b24gYXVzXG4iKTsKKyAgaWYgKHN0cmluZ3Aoc3RyKSkgeworICAgIGlmIChzdHI9PSJhdXMiKQorICAgICAgU2V0UHJvcChQX01FU1NBR0VfQkVFUCwwKTsKKyAgICBlbHNlIGlmICgoYmVlcF9pbnRlcnZhbD10b19pbnQoc3RyKSkgPiAwICYmIGJlZXBfaW50ZXJ2YWw8PTM2MDApCisgICAgICBTZXRQcm9wKFBfTUVTU0FHRV9CRUVQLGJlZXBfaW50ZXJ2YWwpOworICAgIGVsc2UgcmV0dXJuIDA7CisgIH0KKworICBiZWVwX2ludGVydmFsPShpbnQpUXVlcnlQcm9wKFBfTUVTU0FHRV9CRUVQKTsKKyAgX25vdGlmeSgiVG9uIGJlaSBNaXR0ZWlsdW5nZW46ICIrCisgICAgICAgIChiZWVwX2ludGVydmFsID8gImFsbGVyICIrYmVlcF9pbnRlcnZhbCsiIFNla3VuZGVuLiIgOiAiYXVzLiIpLAorICAgICAgICBxdWVyeV92ZXJiKCkpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBfbXNnX3ByZXBlbmQoc3RyaW5nIHN0cikgeworICBpbnQgYmVlcF9pbnRlcnZhbDsKKyAgbm90aWZ5X2ZhaWwoIlN5bnRheDogc2VuZGVyd2llZGVyaG9sdW5nIGVpbi9hdXNcbiIpOworICBpZiAoc3RyaW5ncChzdHIpKSB7CisgICAgaWYgKHN0cj09ImF1cyIpICAKKyAgICAgIFNldFByb3AoUF9NRVNTQUdFX1BSRVBFTkQsMSk7CisgICAgZWxzZSBpZiAoc3RyPT0iZWluIikgIAorICAgICAgU2V0UHJvcChQX01FU1NBR0VfUFJFUEVORCwwKTsKKyAgICBlbHNlIHJldHVybiAwOworICB9CisKKyAgX25vdGlmeSgiU2VuZGVyd2llZGVyaG9sdW5nIGJlaSBNaXR0ZWlsdW5nZW46ICIrIAorICAgICAgICAgICgoaW50KVF1ZXJ5UHJvcChQX01FU1NBR0VfUFJFUEVORCkgPyAgImF1cyIgOiAiZWluIikrIi4iLAorICAgICAgICAgIHF1ZXJ5X3ZlcmIoKSk7CisKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgX2NvbW11bmljYXRlKG1peGVkIHN0ciwgaW50IHNpbGVudCkKK3sKKyAgc3RyaW5nICB2ZXJiOworICBzdHJpbmcgIG15bmFtZTsKKyAgc3RyaW5nICBtc2c7CisKKyAgaWYgKCFzdHIgfHwgZXh0ZXJuX2NhbGwoKSkgc3RyPV91bnBhcnNlZF9hcmdzKCl8fCIiOworICAvKiBzdHI9X3VucGFyc2VkX2FyZ3MoKXx8IiI7ICovCisgIHZlcmIgPSBxdWVyeV92ZXJiKCk7CisgIGlmKHN0cmluZ3AodmVyYikgJiYgdmVyYlswXSA9PSAnXCcnKSBzdHIgPSB2ZXJiWzEuLl0gKyAiICIgKyBzdHI7CisgIGlmIChzdHI9PSIifHxzdHI9PSIgInx8IXN0cikKKyAgeworICAgIF9ub3RpZnkoIldhcyB3aWxsc3QgRHUgc2FnZW4/IixNQV9TQVkpOworICAgIHJldHVybiAxOworICB9CisgIG1zZz1wZXJtdXRhdGUoc3RyKTsKKworICBteW5hbWU9KCgoUXVlcnlQcm9wKFBfSU5WSVMpfHwhSVNfTEVBUk5FUihNRSkpfHwKKyAgICAgIShRdWVyeVByb3AoUF9DQU5fRkxBR1MpJkNBTl9QUkVTQVkpPworICAgICIiOlF1ZXJ5UHJvcChQX1BSRVNBWSkpK25hbWUoKSl8fCIiOworCisgIC8vIGFuIGFsbGVzIGltIFJhdW0gc2VuZGVuLiAoTVRfTElTVEVOLCB3ZWlsIGRpZXMgZ2VzcHJvY2hlbmUgS29tbXVuaWthdGlvbgorICAvLyBpc3QsIGtlaW5lIE1UX0NPTU0pCisgIHNlbmRfcm9vbShlbnZpcm9ubWVudCgpLCBtc2csIE1UX0xJU1RFTiwgTUFfU0FZLAorICAgICAgICAgICAgY2FwaXRhbGl6ZShteW5hbWUpKyIgc2FndDogIiwgKHt0aGlzX29iamVjdCgpfSkgKTsKKworICBpZighc2lsZW50KQorICB7CisgICAgUmVjZWl2ZU1zZyhtc2csIE1UX05PVElGSUNBVElPTnxNU0dfRE9OVF9JR05PUkV8TVNHX0RPTlRfU1RPUkUsCisgICAgICAgICAgICAgICBNQV9TQVksICJEdSBzYWdzdDogIiwgTUUpOworICB9CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IF9zaG91dF90b19hbGwobWl4ZWQgc3RyKQoreworICBzdHJpbmcgcHJlLCBteW5hbWUsIHJlYWxuYW1lLCB3aXphcmRzX21zZywgcGxheWVyc19tc2c7CisgIHN0cmluZyB3aXphcmRfcHJlZml4LCBwbGF5ZXJfcHJlZml4OworICBpbnQgY2hhcnM7CisKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpKQorICB7CisgICAgX25vdGlmeSgiV2FzIHdpbGxzdCBEdSBydWZlbj8iLE1BX1NIT1VUKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBjaGFycz1zaXplb2Yoc3RyKS8yOworICBpZiAoY2hhcnM8NCkgY2hhcnM9NDsKKyAgcHJlID0gKCFJU19MRUFSTkVSKE1FKSB8fAorICAgUXVlcnlQcm9wKFBfSU5WSVMpIHx8CisgICAhKFF1ZXJ5UHJvcChQX0NBTl9GTEFHUykgJiBDQU5fUFJFU0FZKSkgPyAiIiA6IFF1ZXJ5UHJvcChQX1BSRVNBWSk7CisgIHJlYWxuYW1lID0gY2FwaXRhbGl6ZSgocHJlICsgY2FwaXRhbGl6ZShnZXR1aWQoKSkpfHwiIik7CisgIG15bmFtZSA9IGNhcGl0YWxpemUocHJlICsgbmFtZSgpfHwiIik7CisgIGlmIChRdWVyeVByb3AoUF9JTlZJUykpCisgICAgcmVhbG5hbWUgPSAiKCIrcmVhbG5hbWUrIikiOworCisgIHdpemFyZHNfbXNnID0gcGVybXV0YXRlKHN0cik7CisgIHdpemFyZF9wcmVmaXggPSBteW5hbWUrIiBydWZ0OiAiOworCisgIGlmKFF1ZXJ5UHJvcChQX0ZST0cpKSB7CisgICAgcGxheWVyc19tc2cgPSAiUXVhYWFrLCBxdWFhYWFhaywgcXV1dXVhYWFhYWFhYWFhYWFhYWFhYWFhYWsgISEiOworICAgIHBsYXllcl9wcmVmaXggPSBteW5hbWUrIiBxdWFrdDogIjsKKyAgfQorICBlbHNlIHsKKyAgICBwbGF5ZXJzX21zZyA9IHdpemFyZHNfbXNnOworICAgIHBsYXllcl9wcmVmaXggPSB3aXphcmRfcHJlZml4OworICB9CisKKyAgaWYoIUlTX0xFQVJORVIodGhpc19wbGF5ZXIoKSkpCisgIHsKKyAgICBpZihRdWVyeVByb3AoUF9HSE9TVCkpIHsKKyAgICAgICAgX25vdGlmeSgiU28gZ2FueiBvaG5lIEtvZXJwZXIgYmVrb21tc3QgRHUga2VpbmVuIFRvbiBoZXJhdXMuIiwKKyAgICAgICAgICAgICAgICBNQV9TSE9VVCk7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBpZiAoUXVlcnlQcm9wKFBfU1ApIDwoY2hhcnMrMjApKQorICAgIHsKKyAgICAgIF9ub3RpZnkoIkR1IG11c3N0IGVyc3Qgd2llZGVyIG1hZ2lzY2hlIEtyYWVmdGUgc2FtbWVsbi4iLAorICAgICAgICAgICAgICBNQV9TSE9VVCk7CisgICAgICBfbm90aWZ5KCJUaXA6IEJlbnV0eiBkb2NoIG1hbCBkaWUgRWJlbmVuIChIaWxmZSBkYXp1IG1pdCAnaGlsZmUgIgorICAgICAgICAgICAgICAiRWJlbmVuJykuIiwgTUFfU0hPVVQpOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIFNldFByb3AoUF9TUCwgUXVlcnlQcm9wKFBfU1ApIC0gY2hhcnMgLSAyMCk7CisgIH0KKworICBSZWNlaXZlTXNnKHdpemFyZHNfbXNnLCBNVF9OT1RJRklDQVRJT058TVNHX0RPTlRfSUdOT1JFfE1TR19ET05UX1NUT1JFLAorICAgICAgICAgICAgICJydWZlIiwgIkR1IHJ1ZnN0OiAiLCBNRSk7CisKKyAgZm9yZWFjaCAoIG9iamVjdCBvYiA6IHVzZXJzKCktKHt0aGlzX29iamVjdCgpfSkgKQorICAgIGlmICggSVNfTEVBUk5FUihvYikgKQorICAgICAgb2ItPlJlY2VpdmVNc2cod2l6YXJkc19tc2csIE1UX0xJU1RFTnxNVF9GQVIsIE1BX1NIT1VULCB3aXphcmRfcHJlZml4LAorICAgICAgICAgICAgICAgICAgICB0aGlzX29iamVjdCgpKTsKKyAgICBlbHNlCisgICAgICBvYi0+UmVjZWl2ZU1zZyhwbGF5ZXJzX21zZywgTVRfTElTVEVOfE1UX0ZBUiwgTUFfU0hPVVQsIHBsYXllcl9wcmVmaXgsCisgICAgICAgICAgICAgICAgICAgIHRoaXNfb2JqZWN0KCkpOworCisgIHJldHVybiAxOworfQorCit2YXJhcmdzIGludCBfdGVsbChzdHJpbmcgd2hvLCBtaXhlZCBtc2cpCit7CisgIG9iamVjdCAgICBvYjsKKyAgc3RyaW5nICAgIGF3YXksbXluYW1lLHJldDsKKyAgbWl4ZWQgICAgIGlnbm9yZSxpdDsKKyAgc3RyaW5nICAgICp4bmFtZTsKKyAgaW50ICAgICAgIGksdmlzZmxhZzsKKworICBpZiAoZXh0ZXJuX2NhbGwoKSAmJiB0aGlzX2ludGVyYWN0aXZlKCkhPU1FKSByZXR1cm4gMTsKKyAgaWYgKCF3aG8gfHwgIW1zZykgeworICAgIF9ub3RpZnkoIldhcyB3aWxsc3QgRHUgbWl0dGVpbGVuPyIsTUFfVEVMTCk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBpZih3aG8gPT0gRVJXSURFUl9QQVJBTSkKKyAgeworICAgIGlmICghbGFzdF9jb21tX3BhcnRuZXIpCisgICAgeworICAgICAgX25vdGlmeV9mYWlsKCJEdSBoYXN0IGFiZXIgbm9jaCBrZWluZSBNaXR0ZWlsdW5nZW4gZXJoYWx0ZW4sIGF1ZiBkaWUgIgorICAgICAgICAgICJEdSB3YXMgZXJ3aWRlcm5cbmtvZW5udGVzdC5cbiIpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHdobz1sYXN0X2NvbW1fcGFydG5lcjsKKyAgfQorCisgIC8vIHRlaWxlIC54IG1pdCB0ZWlsdCBiaXNoZXJpZ2VuIEdlc3ByYWVjaHNwYXJ0bmVybiBldHdhcyBtaXQuCisgIGlmICh3aG8gPT0gIi4iKQorICAgd2hvID0gIi4xIjsKKworICBpZiAoIHNzY2FuZih3aG8sICIuJWQiLCBpKSA9PSAxICkgeworICAgIGlmKGkgPiAwICYmIGkgPD0gc2l6ZW9mKGNvbW1yZWNlaXZlcnMpKQorICAgICAgd2hvID0gY29tbXJlY2VpdmVyc1tpLTFdOworICAgIGVsc2UgeworICAgICAgX25vdGlmeV9mYWlsKCJTbyB2aWVsZW4gTGV1dGVuIGhhc3QgRHUgbm9jaCBuaWNodHMgbWl0Z2V0ZWlsdCFcbiIpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICB9CisKKyAgeG5hbWUgPSBleHBsb2RlKHdobywgIkAiKTsKKworICBpZiAoc2l6ZW9mKHhuYW1lKSA9PSAyKSAKKyAgeworICAgIGlmICggUXVlcnlQcm9wKFBfUVApICkKKyAgICB7CisgICAgICBpZiAocmV0PShzdHJpbmcpSU5FVEQtPl9zZW5kX3VkcCh4bmFtZVsxXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChbIFJFUVVFU1Q6ICAgInRlbGwiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVDSVBJRU5UOiB4bmFtZVswXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNFTkRFUjogICAgZ2V0dWlkKE1FKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERBVEE6ICAgICBtc2cgXSksIDEpKQorICAgICAgeworICAgICAgICBfbm90aWZ5KHJldCwgTUFfVEVMTCk7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIHdyaXRlKCJOYWNocmljaHQgYWJnZXNjaGlja3QuXG4iKTsKKyAgICAgICAgYWRkX3RvX3RlbGxfaGlzdG9yeSh3aG8sIDEsIDAsIG1zZywKKyAgICAgICAgICAiRHUgdGVpbHN0ICIgKyBjYXBpdGFsaXplKHdobykgKyAiIG1pdDogIiwgTVNHRkxBR19URUxMLCAxKTsKKyAgICAgIH0KKyAgICB9CisgICAgZWxzZQorICAgICAgd3JpdGUoIkR1IGhhc3QgbmljaHQgZ2VudWcgQWJlbnRldWVycHVua3RlLCB1bSBTcGllbGVybiBpbiBhbmRlcmVuIFxuIgorICAgICAgICAiTXVkcyBldHdhcyBtaXR0ZWlsZW4genUga29lbm5lbi5cbiIpOworICAgIHJldHVybiAxOworICB9CisKKyAgaWYgKCFvYj1maW5kX3BsYXllcihpdCA9IGxvd2VyX2Nhc2Uod2hvKSkpCisgIHsKKyAgICBpdCA9IG1hdGNoX2xpdmluZyhpdCwgMCk7CisgICAgaWYgKCFzdHJpbmdwKGl0KSkKKyAgICAgIHN3aXRjaChpdCkgeworICAgICAgY2FzZSAtMToKKyAgICAgICAgX25vdGlmeSgiRGFzIHdhciBuaWNodCBlaW5kZXV0aWchIixNQV9URUxMKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICBjYXNlIC0yOgorICAgICAgICBfbm90aWZ5KCJLZWluIHNvbGNoZXIgU3BpZWxlciEiLE1BX1RFTEwpOworICAgICAgICByZXR1cm4gMTsKKyAgICAgIH0KKyAgICBvYiA9IGZpbmRfcGxheWVyKGl0KSB8fCBmaW5kX2xpdmluZyhpdCk7CisgICAgaWYoIW9iKSB7CisgICAgICBfbm90aWZ5KCJLZWluIHNvbGNoZXIgU3BpZWxlciEiLE1BX1RFTEwpOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICB9CisKKyAgaWYoUXVlcnlQcm9wKFBfSU5WSVMpKXsKKyAgICBpZighSVNfTEVBUk5FUihvYikpCisgICAgICBteW5hbWUgPSBuYW1lKCk7CisgICAgZWxzZQorICAgICAgbXluYW1lPSIoIisKKyAgICAgICAgICAgICAoKFF1ZXJ5UHJvcChQX0NBTl9GTEFHUykgJiBDQU5fUFJFU0FZKT9RdWVyeVByb3AoUF9QUkVTQVkpOiIiKSsKKyAgICAgICAgICAgICBjYXBpdGFsaXplKGdldHVpZCgpKSArICIpIjsKKyAgfQorICBlbHNlCisgICAgbXluYW1lPSgoSVNfTEVBUk5FUihNRSkgJiYgKFF1ZXJ5UHJvcChQX0NBTl9GTEFHUykgJiBDQU5fUFJFU0FZKSkgPworICAgICAgICAgICAgICBRdWVyeVByb3AoUF9QUkVTQVkpOiIiKSArIG5hbWUoKTsKKyAgaWYgKG15bmFtZSAmJiBzaXplb2YobXluYW1lKSkgbXluYW1lPWNhcGl0YWxpemUobXluYW1lKTsKKyAgLy8gZXJzdG1hbCBhbiBFbXBmYWVuZ2VyIHNlbmRlbgorICBfc2VuZChvYiwgcGVybXV0YXRlKG1zZyksIE1UX0NPTU18TVRfRkFSLCBNQV9URUxMLAorICAgICAgICBteW5hbWUgKyAiIHRlaWx0IERpciBtaXQ6ICIpOworCisgIC8vIGRhbm4gZXZ0bC4gbm9jaCBhbiBBYnNlbmRlciBhdXNnZWJlbi4uLgorICBpZiAodmlzZmxhZyA9ICFvYi0+UXVlcnlQcm9wKFBfSU5WSVMpIHx8IElTX0xFQVJORVIodGhpc19wbGF5ZXIoKSkpCisgICAgX3JlY3Yob2IsIG1zZywgTVNHRkxBR19URUxMLCAiRHUgdGVpbHN0ICIgKyBjYXBpdGFsaXplKGl0KSArICIgbWl0OiAiKTsKKyAgLy8gb2RlciBpcmdlbmR3YXMgYW5kZXJlcyBhbiBkZW4gQWJzZW5kZXIgYXVzZ2ViZW4uLi4KKyAgaWYgKCF2aXNmbGFnICYmIGludGVyYWN0aXZlKG9iKSkKKyAgICAgIF9ub3RpZnkoIktlaW4gc29sY2hlciBTcGllbGVyISIsTUFfVEVMTCk7CisgIGVsc2UgaWYgKGF3YXkgPSAoc3RyaW5nKW9iLT5RdWVyeVByb3AoUF9BV0FZKSkKKyAgICAgIFJlY2VpdmVNc2coIGJyZWFrX3N0cmluZyggYXdheSwgNzgsIGNhcGl0YWxpemUoaXQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICArICIgaXN0IGdlcmFkZSBuaWNodCBkYTogIiwgQlNfSU5ERU5UX09OQ0UgKSwKKyAgICAgICAgICBNVF9OT1RJRklDQVRJT058TVNHX0RPTlRfV1JBUHxNU0dfRE9OVF9JR05PUkUsCisgICAgICAgICAgTUFfVEVMTCwgMCwgdGhpc19vYmplY3QoKSk7CisgIGVsc2UgaWYgKGludGVyYWN0aXZlKG9iKSAmJiAoaT1xdWVyeV9pZGxlKG9iKSk+PTYwMCkKKyAgeyAvL2FiIDEwIE1pbnMKKyAgICAgIGlmIChpPDM2MDApCisgICAgICAgIGF3YXk9dGltZTJzdHJpbmcoIiVtICVNIixpKTsKKyAgICAgIGVsc2UKKyAgICAgICAgYXdheT10aW1lMnN0cmluZygiJWggJUggdW5kICVtICVNIixpKTsKKworICAgICAgX25vdGlmeShzcHJpbnRmKCIlcyBpc3Qgc2VpdCAlcyB2b2VsbGlnIHVudGFldGlnLiIsCisgICAgICAgICAgICAgIGNhcGl0YWxpemUoaXQpLGF3YXkpLAorICAgICAgICAgICAgICBNQV9URUxMKTsKKyAgICB9CisKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgX3RlaWxlKHN0cmluZyBzdHIpCit7CisgIHN0cmluZyB3aG8sIG1lc3NhZ2U7CisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSkgcmV0dXJuIDA7CisgIGlmIChzc2NhbmYoc3RyLCAiJXMgbWl0ICVzIiwgd2hvLCBtZXNzYWdlKSA9PSAyKQorICAgIHJldHVybiBfdGVsbCh3aG8sIG1lc3NhZ2UsMSk7CisgIHJldHVybiAwOworfQorc3RhdGljIGludCBfdGVpbGVfbWl0X2FsaWFzKHN0cmluZyBzdHIpCit7CisgIHN0ciA9IF91bnBhcnNlZF9hcmdzKCksIFRSSU1fTEVGVDsKKyAgaWYgKCFzdHIpIHJldHVybiAwOworICBzdHIgPSB0cmltKHN0ciwgVFJJTV9MRUZUKTsKKyAgLy8gWmllbCBtdXNzIG1pbi4gMiBCdWNoc3RhYmVuIGhhYmVuICguPG5yPikKKyAgaWYgKHNpemVvZihzdHIpIDwgNCkgcmV0dXJuIDA7CisgIGludCBwb3MgPSBzdHJzdHIoc3RyLCAiICIpOworICBpZiAocG9zID49IDIpCisgICAgcmV0dXJuIF90ZWxsKHN0clsuLnBvcy0xXSwgc3RyW3BvcysxLi5dKTsKKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgX2VyemFlaGxlKHN0cmluZyBzdHIpCit7CisgIHN0cmluZyB3aG8sIG1lc3NhZ2U7CisKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpKSByZXR1cm4gMDsKKyAgaWYgKHNzY2FuZihzdHIsICIlcyAlcyIsIHdobywgbWVzc2FnZSkgPT0gMikKKyAgICByZXR1cm4gX3RlbGwod2hvLCBtZXNzYWdlLDEpOworICByZXR1cm4gMDsKK30KKworc3RhdGljIGludCBfd2hpc3BlcihzdHJpbmcgc3RyKQoreworICBvYmplY3QgICAgb2I7CisgIHN0cmluZyAgICB3aG87CisgIHN0cmluZyAgICBtc2c7CisgIHN0cmluZyAgICBteW5hbWU7CisKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpIHx8CisgICAgICAgKHNzY2FuZihzdHIsICIlcyB6dSAlcyIsIHdobywgbXNnKSAhPSAyICYmCisgICAgICAgIHNzY2FuZihzdHIsICIlcyAlcyIsIHdobywgbXNnKSAhPTIgKSkgeworICAgIF9ub3RpZnkoIldhcyB3aWxsc3QgRHUgd2VtIHp1Zmx1ZXN0ZXJuPyIsTUFfU0FZKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoIShvYiA9IHByZXNlbnQod2hvLCBlbnZpcm9ubWVudCh0aGlzX3BsYXllcigpKSkpIHx8ICFsaXZpbmcob2IpKSB7CisgICAgX25vdGlmeShjYXBpdGFsaXplKHdobykrIiBpc3QgbmljaHQgaW4gZGllc2VtIFJhdW0uIixNQV9TQVkpOworICAgIHJldHVybiAxOworICB9CisKKyAgbXluYW1lID0gY2FwaXRhbGl6ZSgoKChJU19MRUFSTkVSKE1FKSAmJgorICAgICAgICFRdWVyeVByb3AoUF9JTlZJUykgJiYKKyAgICAgICAoUXVlcnlQcm9wKFBfQ0FOX0ZMQUdTKSAmIENBTl9QUkVTQVkpKT8KKyAgICAgIFF1ZXJ5UHJvcChQX1BSRVNBWSkgOiAiIikgKyBuYW1lKCkpIHx8ICIiKTsKKworICBfc2VuZChvYiwgcGVybXV0YXRlKG1zZyksIE1UX0xJU1RFTnxNU0dfRE9OVF9TVE9SRSwKKyAgICAgICAgTVNHX1NBWSwgbXluYW1lICsgIiBmbHVlc3RlcnQgRGlyIHp1OiAiKTsKKyAgc2VuZF9yb29tKGVudmlyb25tZW50KCksCisgICAgICAgICAgICBteW5hbWUgKyAiIGZsdWVzdGVydCAiICsgb2ItPm5hbWUoV0VNLCAxKSArICIgZXR3YXMgenUuIiwKKyAgICAgICAgICAgIE1UX0xJU1RFTnxNU0dfRE9OVF9TVE9SRSwgTUFfU0FZLCAwLCAoe3RoaXNfb2JqZWN0KCksb2J9KSk7CisKKyAgX3JlY3Yob2IsIG1zZywgTVNHRkxBR19XSElTUEVSLCAiRHUgZmx1ZXN0ZXJzdCAiICsgb2ItPm5hbWUoV0VNKSArICIgenU6ICIpOworCisKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgX3JlbW90ZV93aGlzcGVyKHN0cmluZyBzdHIpCit7CisgIC8qIFdpZSAndGVpbGUgbWl0JywgbnVyIG1pdCBNU0dGTEFHX1dISVNQRVIuIERhZHVyY2ggd2lyZCBkZXIgSW5oYWx0IGRlcgorICAgICBOYWNocmljaHQgbmljaHQgaW4gZGVyIHRlbGxfaGlzdG9yeSB2ZXJld2lndC4gKi8KKworICBvYmplY3QgICAgb2I7CisgIHN0cmluZyAgICB3aG8sIGl0OworICBzdHJpbmcgICAgbXNnOworICBzdHJpbmcgICAgbXluYW1lOworCisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSB8fAorICAgICAgIChzc2NhbmYoc3RyLCAiJXMgenUgJXMiLCB3aG8sIG1zZykgIT0gMiAmJgorICAgICAgICBzc2NhbmYoc3RyLCAiJXMgJXMiLCB3aG8sIG1zZykgIT0yICkpIHsKKyAgICBfbm90aWZ5KCJXYXMgd2lsbHN0IER1IHdlbSBhdXMgZGVyIEZlcm5lIHp1Zmx1ZXN0ZXJuPyIsTUFfRU1PVEUpOworICAgIHJldHVybiAxOworICB9CisKKyAgaWYgKCFvYj1maW5kX3BsYXllcihpdCA9IGxvd2VyX2Nhc2Uod2hvKSkpCisgIHsKKyAgICBpdCA9IG1hdGNoX2xpdmluZyhpdCwgMCk7CisgICAgaWYgKCFzdHJpbmdwKGl0KSkKKyAgICAgIHN3aXRjaChpdCl7CisgICAgICBjYXNlIC0xOgorICAgICAgICBfbm90aWZ5KCJEYXMgd2FyIG5pY2h0IGVpbmRldXRpZyEiLE1BX0VNT1RFKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICBjYXNlIC0yOgorICAgICAgICBfbm90aWZ5KCJLZWluIHNvbGNoZXIgU3BpZWxlciEiLE1BX0VNT1RFKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgb2IgPSBmaW5kX3BsYXllcihpdCk7CisgICAgaWYoIW9iKSBvYiA9IGZpbmRfbGl2aW5nKGl0KTsKKyAgICBpZighb2IpeworICAgICAgX25vdGlmeSgiS2VpbiBzb2xjaGVyIFNwaWVsZXIhIixNQV9FTU9URSk7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKyAgaWYgKGVudmlyb25tZW50KG9iKSA9PSBlbnZpcm9ubWVudCgpKSB7CisgICAgX25vdGlmeSgiV2VubiBqZW1hbmQgbmViZW4gRGlyIHN0ZWh0LCBuaW1tIGZsdWVzdGVyLiIsTUFfRU1PVEUpOworICAgIHJldHVybiAxOworICB9CisKKyAgbXluYW1lID0gY2FwaXRhbGl6ZSgoKChJU19MRUFSTkVSKE1FKSAmJgorICAgICAgICFRdWVyeVByb3AoUF9JTlZJUykgJiYKKyAgICAgICAoUXVlcnlQcm9wKFBfQ0FOX0ZMQUdTKSAmIENBTl9QUkVTQVkpKT8KKyAgICAgIFF1ZXJ5UHJvcChQX1BSRVNBWSkgOiAiIikgKyBuYW1lKCkpIHx8ICIiKTsKKworICAvLyBBbiBFbXBmYWVuZ2VyIHNlbmRlbi4KKyAgX3NlbmQob2IsIHBlcm11dGF0ZShtc2cpLCBNVF9DT01NfE1UX0ZBUnxNU0dfRE9OVF9TVE9SRSwgTUFfRU1PVEUsCisgICAgICAgICBteW5hbWUgKyAiIGZsdWVzdGVydCBEaXIgYXVzIGRlciBGZXJuZSB6dTogIik7CisKKyAgLy8gd2VubiBFbXBmYWVuZ2VyIGludmlzIHVuZCB3aXIga2VpbiBNYWdpZXIgLCBnZ2YuIGZha2VmZWhsZXIgYXVzZ2ViZW4uCisgIGlmIChvYi0+UXVlcnlQcm9wKFBfSU5WSVMpICYmICFJU19MRUFSTkVSKHRoaXNfcGxheWVyKCkpKSB7CisgICAgX25vdGlmeSgiS2VpbiBzb2xjaGVyIFNwaWVsZXIhIixNQV9FTU9URSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgLy8gc29uc3QgZWlnZW5lIE1lbGR1bmcgdmlhIF9yZWN2KCkgYXVzZ2ViZW4uCisgIGVsc2UgCisgICAgX3JlY3Yob2IsIG1zZywgTVNHRkxBR19XSElTUEVSIHwgTVNHRkxBR19SRU1PVEUsCisgICAgICAgICJEdSBmbHVlc3RlcnN0ICIgKyBvYi0+bmFtZShXRU0pICsgIiBhdXMgZGVyIEZlcm5lIHp1OiAiKTsKKworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBfY29udmVyc2Uoc3RyaW5nIGFyZykKK3sKKyAgX25vdGlmeSgiTWl0ICcqKicgd2lyZCBkYXMgR2VzcHJhZWNoIGJlZW5kZXQuIixNQV9TQVkpOworICBpZiAoc3RyaW5ncChhcmcpICYmIHN0cnN0cihhcmcsICItcyIpID09IDApCisgICAgaW5wdXRfdG8oIl9jb252ZXJzZV9tb3JlIiwgSU5QVVRfUFJPTVBULCAiXSIsIDEpOworICBlbHNlCisgICAgaW5wdXRfdG8oIl9jb252ZXJzZV9tb3JlIiwgSU5QVVRfUFJPTVBULCAiXSIsIDApOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBfY29udmVyc2VfbW9yZShtaXhlZCBzdHIsIGludCBzaWxlbnQpCit7CisgIGlmIChzdHIgPT0gIioqIikgeworICAgIF9ub3RpZnkoIk9rLiIsTUFfU0FZKTsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIGlmKHN0ciAhPSAiIikKKyAgICBfY29tbXVuaWNhdGUoc3RyLCBzaWxlbnQpOworCisgIGlucHV0X3RvKCJfY29udmVyc2VfbW9yZSIsIElOUFVUX1BST01QVCwgIl0iLCBzaWxlbnQpOworICByZXR1cm4gMTsKK30KKworcHJpdmF0ZSBpbnQgaXNfbGVhcm5lcihvYmplY3QgbykgeyByZXR1cm4gSVNfTEVBUk5FUihvKTsgfQorCitzdGF0aWMgaW50IF9zaG91dF90b193aXphcmRzKG1peGVkIHN0cikKK3sKKyAgaW50ICAgICBpLCBqOworICBzdHJpbmcgICAgbXluYW1lOworICBvYmplY3QgICAqdTsKKworICBzdHIgPSBfdW5wYXJzZWRfYXJncygpOworICBpZiAoIXN0cnx8IXNpemVvZihzdHIpKSB7CisgICAgX25vdGlmeSgiV2FzIHdpbGxzdCBEdSBkZW4gTWFnaWVybiB6dXJ1ZmVuPyIsTUFfU0hPVVQpOworICAgIHJldHVybiAxOworICB9CisgIC8vIEtvbnRyb2xsemVpY2hlbiByYXVzZmlsdGVybi4KKyAgc3RyID0gcmVncmVwbGFjZShzdHIsIltbOmNudHJsOl1dIiwiIixSRV9QQ1JFfFJFX0dMT0JBTCk7CisgIG15bmFtZSA9IGNhcGl0YWxpemUoZ2V0dWlkKHRoaXNfb2JqZWN0KCkpKTsKKyAgaWYgKCFJU19MRUFSTkVSKHRoaXNfb2JqZWN0KCkpKQorICAgIF9yZWN2KDAsIHN0ciwgTVNHRkxBR19NRUNITywgIkR1IHRlaWxzdCBhbGxlbiBNYWdpZXJuIG1pdDogIik7CisKKyAgLy8gbXJ1ZmUgaXN0IG5pY2h0IGlnbm9yaWVyYmFyLCBkYSBlcyBudXIgZnVlciBzY2h3ZXJlIFByb2JsZW1lIGdlZGFjaHQgaXN0LgorICBmaWx0ZXIodXNlcnMoKSwgIydpc19sZWFybmVyKS0+UmVjZWl2ZU1zZyhzdHIsCisgICAgICBNVF9DT01NfE1UX0ZBUnxNU0dfRE9OVF9JR05PUkV8TVNHX0RPTlRfU1RPUkUsCisgICAgICBNQV9TSE9VVCwgbXluYW1lKyIgYW4gYWxsZSBNYWdpZXI6ICIsIHRoaXNfb2JqZWN0KCkpOworCisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IF9lY2hvKHN0cmluZyBzdHIpIHsKKyAgaWYgKCFJU19TRUVSKE1FKSB8fCAoIUlTX0xFQVJORVIoTUUpCisgICAgICAgICYmICEoUXVlcnlQcm9wKFBfQ0FOX0ZMQUdTKSAmIENBTl9FQ0hPKSkpCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpKSB7CisgICAgX25vdGlmeSgiV2FzIG1vZWNodGVzdCBEdSAnZWNob2VuJz8iLCAwKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIGlmICghSVNfTEVBUk5FUih0aGlzX2ludGVyYWN0aXZlKCkpKQorICB7CisgICAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSkKKyAgICB7CisgICAgICBfbm90aWZ5X2ZhaWwoIk9obmUgS29lcnBlciBmZWhsdCBEaXIgZGF6dSBkaWUgbm9ldGlnZSBtYWdpc2NoZSBLcmFmdC5cbiIpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmIChRdWVyeVByb3AoUF9TUCk8RUNIT19DT1NUKQorICAgIHsKKyAgICAgIF9ub3RpZnlfZmFpbCgiRHUgbXVzc3QgZXJzdCB3aWVkZXIgbWFnaXNjaGUgS3JhZWZ0ZSBzYW1tZWxuLlxuIik7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgU2V0UHJvcChQX1NQLFF1ZXJ5UHJvcChQX1NQKS1FQ0hPX0NPU1QpOworICAgIHN0cj0iPlxiIitzdHI7CisgICAgbG9nX2ZpbGUoIkFSQ0gvRUNIT19TRUhFUiIsIHNwcmludGYoIiVzICVzOiAlc1xuIiwgZHRpbWUodGltZSgpKSwgZ2V0dWlkKCksCisgICAgICAgICAgIHN0cikpOworICB9CisgIC8vIEFuIGRlbiBSYXVtIHNlbmRlbi4gVHlwIGlzdCBNVF9DT01NLCBhYmVyIGRhcyBFY2hvIHNvbGwgd2VkZXIgaW4gZGVyCisgIC8vIEtvbW1oaXN0b3J5IG5vY2ggaW0gS29ib2xkIGxhbmRlbi4KKyAgc2VuZF9yb29tKGVudmlyb25tZW50KE1FKSwgc3RyLCBNVF9DT01NfE1TR19ET05UX1NUT1JFfE1TR19ET05UX0JVRkZFUiwKKyAgICAgICAgICAgIE1BX1VOS05PV04sIDAsIDApOworICByZXR1cm4gMTsKK30KKworLy8gRGllbnQgYWxzIFZlcnRlaWRpZ3VuZyBnZWdlbiBMZXV0ZSwgZGllIGVoZXIgdW5iZWRhY2h0IHJlaW5zY2hyZWliZW4sIG5pY2h0CisvLyBnZWdlbiBMZXV0ZSwgZGllIGRhIGFic2ljaHRsaWNoIHJlaW5zY2hyZWliZW4uIERpZSB3ZXJkZW4gZ2V0ZWVydAorLy8gdW5kIGdlZmVkZXJ0Lgorc3RhdGljIHN0cmluZyAqX3NldF9pZ25vcmUobWl4ZWQgYXJnKQoreworICByYWlzZV9lcnJvcigiRGlyZWt0ZXMgU2V0emVuIHZvbiBQX0lHTk9SRSBpc3QgbmljaHQgZXJsYXVidC4gIgorICAgICAgIkJlbnV0emUgQWRkSWdub3JlL1JlbW92ZUlnbm9yZSgpIVxuIik7Cit9CisvLyBLb21wYXRpYmlsdGFldCB6dW0gYWx0ZW4gSWdub3JlOiBBcnJheSB2b24gSW5kaWNlcyBsaWVmZXJuLiBBZW5kZXJ0IGFiZXIKKy8vIG5peCBkcmFuLCBkYXNzIGFsbGUgVGVzdElnbm9yZSgpICYgQ28gYmVudXR6ZW4gc29sbGVuLgorc3RhdGljIHN0cmluZyAqX3F1ZXJ5X2lnbm9yZSgpIHsKKyAgbWl4ZWQgaWduPVF1ZXJ5KFBfSUdOT1JFLCBGX1ZBTFVFKTsKKyAgaWYgKG1hcHBpbmdwKGlnbikpCisgICAgcmV0dXJuIG1faW5kaWNlcyhpZ24pOworICByZXR1cm4gKHt9KTsKK30KKworcHVibGljIGludCBBZGRJZ25vcmUoc3RyaW5nIGlnbikgeworICAvLyBFaW5pZ2Ugc3RyaW5ncyBzaW5kIG5pY2h0IGVybGF1YnQsIHouQi4ga29uc2VrdXRpdmUgLgorICBpZiAoIXNpemVvZihpZ24pCisgICAgICB8fCByZWdtYXRjaChpZ24sIlsuXXsyLH0iLFJFX1BDUkUpCisgICAgICB8fCByZWdtYXRjaChpZ24sIiAiLFJFX1BDUkUpCisgICAgICB8fCBzaXplb2YoZXhwbG9kZShpZ24sIi4iKSk+MykKKyAgICByZXR1cm4gMDsKKworICBtYXBwaW5nIGlnbm9yZXM9UXVlcnkoUF9JR05PUkUsIEZfVkFMVUUpOworICBpZ25vcmVzW2lnbl09dGltZSgpOworICAvLyBrZWluIFNldCgpIG5vZXRpZy4KKyAgcmV0dXJuIDE7Cit9CisKK3B1YmxpYyBpbnQgUmVtb3ZlSWdub3JlKHN0cmluZyBpZ24pCit7CisgIG1hcHBpbmcgaWdub3Jlcz1RdWVyeShQX0lHTk9SRSxGX1ZBTFVFKTsKKyAgbV9kZWxldGUoaWdub3JlcyxpZ24pOworICAvLyBLZWluIFNldCgpIG5vZXRpZworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBfcXVlcnlfaW50ZXJtdWQoKQoreworICBtaXhlZCB0bXA7CisgIHJldHVybiBtZW1iZXIocG9pbnRlcnAodG1wPVF1ZXJ5KFBfQ0hBTk5FTFMpKT90bXA6KHt9KSwgIkludGVybXVkIikgPiAtMTsKK30KKworCitpbnQgZXJ3aWRlcmUoc3RyaW5nIHN0cikKK3sKKyAgc3RyPV91bnBhcnNlZF9hcmdzKCk7CisgIGlmICghc3RyKSByZXR1cm4gMDsKKyAgcmV0dXJuIF90ZWxsKEVSV0lERVJfUEFSQU0sIHN0ciAsMSk7Cit9CisKK3N0YXRpYyBpbnQgdG1oaXN0KHN0cmluZyBzdHIpCit7CisKKyAgaWYgKHN0ciA9PSAiYXVzIikgeworICAgIHRlbGxfaGlzdG9yeV9lbmFibGVkID0gVEVMTEhJU1RfRElTQUJMRUQ7CisgICAgd3JpdGUoIk9rLCBlcyB3aXJkIG5pY2h0cyBtZWhyIGdlc3BlaWNoZXJ0LlxuIik7CisgICAgaWYgKHNpemVvZih0ZWxsX2hpc3RvcnkpKSB7CisgICAgICB0ZWxsX2hpc3RvcnkgPSAoW10pOworICAgICAgY29tbXJlY2VpdmVycyA9ICh7fSk7CisgICAgICB3cml0ZSgiRGVpbmUgTWl0dGVpbHVuZ3NnZXNjaGljaHRlIHd1cmRlIGdlbG9lc2NodC5cbiIpOworICAgIH0KKyAgICByZXR1cm4gMTsKKyAgfQorCisgIGlmIChzdHIgPT0gIm5hbWVuIikgeworICAgIGludCBmbGFnOworICAgIHRlbGxfaGlzdG9yeV9lbmFibGVkID0gVEVMTEhJU1RfTk9fTUVTU0FHRTsKKyAgICB3cml0ZSgiT2ssIGRpZSBOYW1lbiB6dWt1ZW5mdGlnZXIgR2VzcHJhZWNoc3BhcnRuZXIgd2VyZGVuIGdlc3BlaWNoZXJ0LlxuIik7CisgICAgZm9yZWFjaCAoc3RyaW5nIHVpZCwgc3RydWN0IGNoYXRfcyBjaGF0OiB0ZWxsX2hpc3RvcnkpCisgICAgICBpZiAocG9pbnRlcnAoY2hhdC0+bXNnYnVmKSkgeworICAgICAgICBjaGF0LT5tc2didWYgPSAwOworICAgICAgICBjaGF0LT5wdHIgPSAwOworICAgICAgICBmbGFnID0gMTsKKyAgICAgIH0KKyAgICBpZiAoZmxhZykKKyAgICAgIHdyaXRlKCJEZXIgSW5oYWx0IERlaW5lciBNaXR0ZWlsdW5nZW4gd3VyZGUgZ2Vsb2VzY2h0LlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBpZiAoc3RyID09ICJlaW4iIHx8IHN0ciA9PSAiYW4iKSB7CisgICAgdGVsbF9oaXN0b3J5X2VuYWJsZWQgPSBURUxMSElTVF9FTkFCTEVEOworICAgIHdyaXRlKCJPaywgenVrdWVuZnRpZ2UgTWl0dGVpbHVuZ2VuIHdlcmRlbiBnZXNwZWljaGVydC5cbiIpOworICAgIHJldHVybiAxOworICB9CisKKyNpZmRlZiBURUxMSElTVF9MT05HTElGRQorICBpZiAoc3RyID09ICJsYW5nbGViaWciKSB7CisgICAgdGVsbF9oaXN0b3J5X2VuYWJsZWQgPSBURUxMSElTVF9MT05HTElGRTsKKyAgICB3cml0ZSgiT2ssIHp1a3VlbmZ0aWdlIE1pdHRlaWx1bmdlbiB3ZXJkZW4gamV3ZWlscyBiaXMgenVtIG5hZWNoc3RlbiAiCisgICAgICAgICAgIkVuZGUvQ3Jhc2gvXG5SZWJvb3QgZ2VzcGVpY2hlcnQuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorI2VuZGlmCisKKyAgaWYgKHN0ciA9PSAic3RhdHVzIikgeworICAgIHN3aXRjaCAodGVsbF9oaXN0b3J5X2VuYWJsZWQpIHsKKyAgICAgIGNhc2UgVEVMTEhJU1RfRElTQUJMRUQ6CisgICAgICAgIHdyaXRlKCJEaWUgTmFtZW4gRGVpbmVyIEdlc3ByYWVjaHNwYXJ0bmVyIHdlcmRlbiBuaWNodCBnZXNwZWljaGVydC5cbiIpOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgVEVMTEhJU1RfTk9fTUVTU0FHRToKKyAgICAgICAgd3JpdGUoIkRpZSBOYW1lbiBEZWluZXIgR2VzcHJhZWNoc3BhcnRuZXIgd2VyZGVuIGdlc3BlaWNoZXJ0LlxuIik7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBURUxMSElTVF9FTkFCTEVEOgorICAgICAgICB3cml0ZSgiRGVpbmUgTWl0dGVpbHVuZ2VuIHdlcmRlbiBnZXNwZWljaGVydC5cbiIpOworICAgICAgICBicmVhazsKKyNpZmRlZiBURUxMSElTVF9MT05HTElGRQorICAgICAgY2FzZSBURUxMSElTVF9MT05HTElGRToKKyAgICAgICAgd3JpdGUoIkRlaW5lIE1pdHRlaWx1bmdlbiB3ZXJkZW4gamV3ZWlscyBiaXMgenVtIG5hZWNoc3RlbiBFbmRlLyIKKyAgICAgICAgICAgICAgIkNyYXNoL1JlYm9vdFxuZ2VzcGVpY2hlcnQuXG4iKTsKKyAgICAgICAgYnJlYWs7CisjZW5kaWYKKyAgICB9CisgICAgcmV0dXJuIDE7CisgIH0KKworICBpZiAodGVsbF9oaXN0b3J5X2VuYWJsZWQgPT0gVEVMTEhJU1RfRElTQUJMRUQpIHsKKyAgICBfbm90aWZ5X2ZhaWwoIkRlaW5lIEdlc3ByYWVjaHNwYXJ0bmVyIHdlcmRlbiBuaWNodCBnZXNwZWljaGVydC5cbiIpOworICAgIHJldHVybiAwOworICB9CisKKyAgaWYgKCFzaXplb2YodGVsbF9oaXN0b3J5KSkgeworICAgIF9ub3RpZnlfZmFpbCgiRHUgaGFzdCBub2NoIGtlaW5lbSBldHdhcyBtaXRnZXRlaWx0ICIKKyAgICAgICAgICAgICAgICAgInVuZCBub2NoIGtlaW5lIE1pdHRlaWx1bmdlbiBlcmhhbHRlbi5cbiIpOworICAgIHJldHVybiAwOworICB9CisKKyAgaWYgKHN0ciAmJiBzaXplb2Yoc3RyKSkgeworCisgICAgaWYgKHRlbGxfaGlzdG9yeV9lbmFibGVkIDwgVEVMTEhJU1RfRU5BQkxFRCkgeworICAgICAgX25vdGlmeV9mYWlsKCJEZXIgSW5oYWx0IERlaW5lciBNaXR0ZWlsdW5nZW4gd2lyZCBuaWNodCBnZXNwZWljaGVydC5cbiIpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgc3RyaW5nIHVpZDsKKyAgICBpZiAobWVtYmVyKHRlbGxfaGlzdG9yeSwgc3RyKSkgeworICAgICAgLy8gTmFtZSBnZXd1ZW5zY2h0LCBkYSBkZXIgU3RyaW5nIGluIGRlciBIaXN0b3J5IHZvcmtvbW10LgorICAgICAgdWlkID0gc3RyOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIC8vIGV2dGwuIG5lIFphaGwgYW5nZWdlYmVuLgorICAgICAgaW50IGk7CisgICAgICBzdHJpbmcgKnBhcnRuZXJzID0gc29ydGVkX2NvbW1wYXJ0bmVycygwKTsKKyAgICAgIGlmICgoaSA9IHRvX2ludChzdHIpIC0gMSkgPj0gMCAmJiBpIDwgc2l6ZW9mKHBhcnRuZXJzKSkKKyAgICAgICAgdWlkID0gcGFydG5lcnNbaV07CisgICAgICBlbHNlIHsKKyAgICAgICAgbm90aWZ5X2ZhaWwoIk1pdCBzbyB2aWVsZW4gTGV1dGVuIGhhc3QgRHUgbmljaHQgZ2VzcHJvY2hlbiFcbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICB9CisKKyAgICBtaXhlZCAqZGF0YSA9IHRlbGxfaGlzdG9yeVt1aWRdLT5tc2didWY7CisgICAgaWYgKCFkYXRhKSB7CisgICAgICBfbm90aWZ5X2ZhaWwoCisgICAgICAgICJEZXIgSW5oYWx0IGRpZXNlciBNaXR0ZWlsdW5nIGlzdCBuaWNodCAobWVocikgZ2VzcGVpY2hlcnQuXG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGludCBwdHIgPSB0ZWxsX2hpc3RvcnlbdWlkXS0+cHRyOworCisgICAgTW9yZShzcHJpbnRmKCIlQHMiLCBtYXAoZGF0YVtwdHIuLk1BWF9TQVZFRF9NRVNTQUdFUy0xXSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhWzAuLnB0ci0xXSwKKyAgICAgICAgIGZ1bmN0aW9uIHN0cmluZyAoc3RydWN0IHN0b3JlZF9tc2dfcyBtc2cpIHsKKyAgICAgICAgICAgICBpZiAoIXN0cnVjdHAobXNnKSkgcmV0dXJuICIiOworICAgICAgICAgICAgICAgcmV0dXJuIGJyZWFrX3N0cmluZyggbXNnLT5tc2cgKyAiIDwiCisgICAgICAgICAgICAgICAgICsgc3RyZnRpbWUoIiVIOiVNOiVTIixtc2ctPnRpbWVzdGFtcCkgKyAiPiIsIDc4LAorICAgICAgICAgICAgICAgICBtc2ctPnByZWZpeCB8fCAiIiwgbXNnLT5wcmVmaXggPyBCU19MRUFWRV9NWV9MRlMgOiAwKTsKKyAgICAgICAgIH0gKSApICk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBzdHJpbmcgaGlzdG9yeSA9ICJGb2xnZW5kZSBHZXNwcmFlY2hlIGhhc3QgRHUgYmVyZWl0cyBnZWZ1ZWhydDpcbiI7CisgIGludCBpOworICBmb3JlYWNoIChzdHJpbmcgdWlkIDogc29ydGVkX2NvbW1wYXJ0bmVycygwKSApIHsKKyAgICBpbnQgajsKKyAgICBzdHJ1Y3QgY2hhdF9zIGNoYXQgPSB0ZWxsX2hpc3RvcnlbdWlkXTsKKyAgICBoaXN0b3J5ICs9IHNwcmludGYoIiUyZC4lLTRzICVzICAlLTExcyAgJWQgZ2VzZW5kZXQvJWQgZW1wZmFuZ2VuXG4iLCArK2ksCisgICAgICAoKGo9bWVtYmVyKGNvbW1yZWNlaXZlcnMsdWlkKSk+LTEgPyBzcHJpbnRmKCIvJTJkLiIsaisxKSA6ICIiKSwKKyAgICAgIHN0cmZ0aW1lKCIlYSwgJWUuJW0uJXkiLGNoYXQtPnRpbWVfbGFzdF9tc2cpLAorICAgICAgY2FwaXRhbGl6ZShjaGF0LT51aWQpLCBjaGF0LT5zZW50Y291bnQsIGNoYXQtPnJlY3Zjb3VudCk7CisgIH0KKworICBNb3JlKGhpc3RvcnkpOworCisgIHJldHVybiAxOworfQorCitzdGF0aWMgbWl4ZWQgX3F1ZXJ5X2xvY2FsY21kcygpCit7CisgIHJldHVybiAoeworICAgICh7ImtvYm9sZCIsICJjbWRfa29ib2xkIiwwLDB9KSwKKyAgICAgKHsic2FnIiwiX2NvbW11bmljYXRlIiwwLDB9KSwKKyAgICAgKHsic2FnZSIsIl9jb21tdW5pY2F0ZSIsMCwwfSksCisgICAgICh7IiciLCJfY29tbXVuaWNhdGUiLDEsMH0pLAorICAgICAoeyJtcnVmIiwiX3Nob3V0X3RvX3dpemFyZHMiLDAsMH0pLAorICAgICAoeyJtcnVmZSIsIl9zaG91dF90b193aXphcmRzIiwwLDB9KSwKKyAgICAgKHsicnVmIiwiX3Nob3V0X3RvX2FsbCIsMCwwfSksCisgICAgICh7InJ1ZmUiLCJfc2hvdXRfdG9fYWxsIiwwLDB9KSwKKyAgICAgKHsiZXJ6YWVobCIsIl9lcnphZWhsZSIsMCwwfSksCisgICAgICh7ImVyemFlaGxlIiwiX2VyemFlaGxlIiwwLDB9KSwKKyAgICAgKHsidGVpbCIsIl90ZWlsZSIsMCwwfSksCisgICAgICh7InRlaWxlIiwiX3RlaWxlIiwwLDB9KSwKKyAgICAgKHsidG0iLCJfdGVpbGVfbWl0X2FsaWFzIiwwLDB9KSwKKyAgICAgKHsiZmx1ZXN0ZXIiLCJfd2hpc3BlciIsMCwwfSksCisgICAgICh7ImZsdWVzdGVyZSIsIl93aGlzcGVyIiwwLDB9KSwKKyAgICAgKHsicmZsdWVzdGVyIiwiX3JlbW90ZV93aGlzcGVyIiwwLDB9KSwKKyAgICAgKHsicmZsdWVzdGVyZSIsIl9yZW1vdGVfd2hpc3BlciIsMCwwfSksCisgICAgICh7Imdlc3ByYWVjaCIsIl9jb252ZXJzZSIsMCwwfSksCisgICAgICh7ImVjaG8iLCJfZWNobyIsMCwwfSksCisgICAgICh7Imlnbm9yaWVyIiwiaWdub3JpZXJlIiwwLDB9KSwKKyAgICAgKHsiaWdub3JpZXJlIiwiaWdub3JpZXJlIiwwLDB9KSwKKyAgICAgKHsidG1oaXN0IiwidG1oaXN0IiwwLDB9KSwKKyAgICAgKHsiZXJ3aWRlciIsImVyd2lkZXJlIiwwLDB9KSwKKyAgICAgKHsiZXJ3aWRlcmUiLCJlcndpZGVyZSIsMCwwfSksCisgICAgICh7ImtsaW5nZWx0b24iLCJfbXNnX2JlZXAiLDAsMH0pLAorICAgICAoeyJzZW5kZXJ3aWVkZXJob2x1bmciLCJfbXNnX3ByZXBlbmQiLDAsMH0pLAorICAgICAoeyJyZXBvcnQiLCJzZXRfcmVwb3J0IiwwLDB9KSwKKyAgICB9KStjaGFubmVsOjpfcXVlcnlfbG9jYWxjbWRzKCk7Cit9CisKK3ByaXZhdGUgc3RyaW5nICpzb3J0ZWRfY29tbXBhcnRuZXJzKGludCByZXZlcnNlZCkgeworICByZXR1cm4gc29ydF9hcnJheShtX2luZGljZXModGVsbF9oaXN0b3J5KSwKKyAgICAgIGZ1bmN0aW9uIGludCAoc3RyaW5nIHVpZDEsIHN0cmluZyB1aWQyKSB7CisgICAgICAgICAgaWYgKHJldmVyc2VkKQorICAgICAgICAgICAgcmV0dXJuIHRlbGxfaGlzdG9yeVt1aWQxXS0+dGltZV9sYXN0X21zZyA+CisgICAgICAgICAgICAgICAgICAgdGVsbF9oaXN0b3J5W3VpZDJdLT50aW1lX2xhc3RfbXNnOworICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiB0ZWxsX2hpc3RvcnlbdWlkMV0tPnRpbWVfbGFzdF9tc2cgPD0KKyAgICAgICAgICAgICAgICAgICB0ZWxsX2hpc3RvcnlbdWlkMl0tPnRpbWVfbGFzdF9tc2c7CisgICAgICB9ICk7Cit9CisKKy8vIEVpZ2VudGxpY2ggbnVyIGluIE1hZ2llcm9iamVrdGVuIGdlcnVmZW4uIEdlaG9lcnQgYWJlciB0aGVtYXRpc2NoIGhpZXIKKy8vIGlyZ2VuZHdpZSBoaW4uCitzdGF0aWMgdm9pZCBtb2RpZnlfcHJvbXB0KCkgeworICAgIHN0cmluZyB0ZXh0ID0gUXVlcnkoUF9QUk9NUFQsIEZfVkFMVUUpOworCisgICAgaWYgKCAhc3RyaW5ncCh0ZXh0KSB8fCAhc2l6ZW9mKHRleHQpICkKKyAgICAgICAgdGV4dCA9ICI+ICI7CisgICAgZWxzZSB7CisgICAgICAgIHN0cmluZyBwYXRoID0gUXVlcnkoUF9DVVJSRU5URElSLCBGX1ZBTFVFKTsKKyAgICAgICAgaWYgKHN0cmluZ3AocGF0aCkgJiYgc2l6ZW9mKHBhdGgpKQorICAgICAgICAgIHRleHQgPSByZWdyZXBsYWNlKHRleHQsIlxcdyIscGF0aCwwKTsgLy8gUGZhZCBlaW5zZXR6ZW4KKyAgICB9CisgICAgY29uZmlndXJlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCksIElDX1BST01QVCwgdGV4dCk7Cit9CisKKy8vIFBydWVmdCBhdWYgSW5nb3JpZXJlZWludHJhZWdlLgorLy8gUnVlY2tnYWJlOiAwIChuaWNodCBpZ25vcmllcnQpIG9kZXIgTVNHX0lHTk9SRUQKKyNpZmRlZiBfX0xQQ19VTklPTlNfXworcHVibGljIGludCBUZXN0SWdub3JlKHN0cmluZ3xzdHJpbmcqIHNyY25hbWVzKQorI2Vsc2UKK3B1YmxpYyBpbnQgVGVzdElnbm9yZShtaXhlZCBzcmNuYW1lcykKKyNlbmRpZgoreworICBtYXBwaW5nIGlnbiA9IFF1ZXJ5KFBfSUdOT1JFLCBGX1ZBTFVFKTsKKyAgaWYgKHN0cmluZ3Aoc3JjbmFtZXMpKQorICAgIHNyY25hbWVzID0gKHtzcmNuYW1lc30pOworCisgIGZvcmVhY2goc3RyaW5nIHNyY25hbWU6IHNyY25hbWVzKQorICB7CisgICAgLy8gZWluZmFjaHN0ZXIgRmFsbCwgZXhha3RlciBNYXRjaAorICAgIGlmIChtZW1iZXIoaWduLCBzcmNuYW1lKSkKKyAgICAgIHJldHVybiBNU0dfSUdOT1JFRDsKKyAgICAvLyBhbnNvbnN0ZW4gbXVzcyBhdWZnZXRyZW5udCB3ZXJkZW4uCisgICAgaWYgKHN0cnN0cihzcmNuYW1lLCIuIikgPiAtMSkKKyAgICB7CisgICAgICBzdHJpbmcgKnNyY3BhcnRzPWV4cGxvZGUoc3JjbmFtZSwiLiIpOworICAgICAgc3dpdGNoKHNpemVvZihzcmNwYXJ0cykpCisgICAgICB7CisgICAgICAgIC8vIGNhc2UgMCB1bmQgMSBrYW5uIG5pY2h0IHBhc3NpZXJlbi4KKyAgICAgICAgY2FzZSAzOgorICAgICAgICAgIC8vIHp1IHBydWVmZW46IFtzZW5kZXJdLmFrdGlvbi5xdWFsaWZpemllcmVyLgorICAgICAgICAgIC8vIERlciBGYWxsLCBkYXNzIGRlciBTcGllbGVyIGRpZXMgX2dlbmF1XyBfc29fIGlnbm9yaWVydCBoYXQsIHdpcmQKKyAgICAgICAgICAvLyBvYmVuIHNjaG9uIGdlcHJ1ZWZ0LiBpbSBTcGllbGVyIGdlcHJ1ZWZ0IHdlcmRlbiBtdXNzIG5vY2g6CisgICAgICAgICAgLy8gc3BpZWxlciwgLmFrdGlvbiwgc3BpZWxlci5ha3Rpb24gdW5kIC5ha3Rpb24ucXVhbGlmaXppZXJlcgorICAgICAgICAgIGlmICggKHNpemVvZihzcmNwYXJ0c1swXSkgJiYgbWVtYmVyKGlnbixzcmNwYXJ0c1swXSkpIC8vIHNwaWVsZXIKKyAgICAgICAgICAgICAgfHwgbWVtYmVyKGlnbiwgIi4iK3NyY3BhcnRzWzFdKSAgICAgIC8vIC5ha3Rpb24KKyAgICAgICAgICAgICAgfHwgbWVtYmVyKGlnbiwgc3JjcGFydHNbMF0rIi4iK3NyY3BhcnRzWzFdKSAvLyBbc3BpZWxlcl0uYWt0aW9uCisgICAgICAgICAgICAgIHx8IG1lbWJlcihpZ24sICIuIitzcmNwYXJ0c1sxXSsiLiIrc3JjcGFydHNbMl0pIC8vIC5ha3QucXVhbAorICAgICAgICAgICAgICkKKyAgICAgICAgICB7CisgICAgICAgICAgICByZXR1cm4gTVNHX0lHTk9SRUQ7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDI6CisgICAgICAgICAgLy8genUgcHJ1ZWZlbjogc3BpZWxlci5ha3Rpb24KKyAgICAgICAgICAvLyBEZXIgRmFsbCwgZGFzcyBkZXIgU3BpZWxlciBkYXMgX2dlbmF1XyBfc29fIGVpbmdlZ2ViZW4gaGF0LCBpc3QKKyAgICAgICAgICAvLyBvYmVuIHNjaG9uIGdlcHJ1ZWZ0LiBJbSBTcGllbGVyIHp1IHBydWVmZW4gaXN0IG5vY2g6CisgICAgICAgICAgLy8gc3BpZWxlciB1bmQgLmFrdGlvbgorICAgICAgICAgIGlmICgoc2l6ZW9mKHNyY3BhcnRzWzBdKSAmJiBtZW1iZXIoaWduLHNyY3BhcnRzWzBdKSkKKyAgICAgICAgICAgICAgfHwgbWVtYmVyKGlnbiwgIi4iK3NyY3BhcnRzWzFdKSkKKyAgICAgICAgICB7CisgICAgICAgICAgICByZXR1cm4gTVNHX0lHTk9SRUQ7CisgICAgICAgICAgfQorICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OiAvLyBtZWhyIGFscyAzIFRlaWxlLi4uCisgICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiVGVzdElnbm9yZUV4dCgpOiB0b28gbWFueSBxdWFsaWZpZXJzLCBvbmx5IDEgIgorICAgICAgICAgICAgICAgICJpcyBzdXBwb3J0ZWQuIEdvdDogJXNcbiIsc3JjbmFtZSkpOworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorICAvLyBEZWZhdWx0OiBuaWNodCBpZ25vcmllcmVuLgorICByZXR1cm4gMDsKK30KKworI2lmZGVmIF9fTFBDX1VOSU9OU19fCitwdWJsaWMgaW50IFRlc3RJZ25vcmVFeHQoc3RyaW5nfHN0cmluZyogc3JjbmFtZXMpCisjZWxzZQorcHVibGljIGludCBUZXN0SWdub3JlRXh0KG1peGVkIHNyY25hbWVzKQorI2VuZGlmCit7CisgIHJldHVybiBUZXN0SWdub3JlKHNyY25hbWVzKTsKK30KKworLy8gUHJ1ZWZ0IGZ1ZXIgUmVjZWl2ZU1zZygpIGF1ZiBJbmdvcmllcmVlaW50cmFlZ2UuIElnbm9yaWVydCBhYmVyIG5pY2h0IGFsbGUKKy8vIFR5cGVuLiAKKy8vIFJ1ZWNrZ2FiZTogMCBvZGVyIE1TR19JR05PUkVEIHwgTVNHX1ZFUkJfSUdOIHwgTVNHX01VRF9JR04KK3ByaXZhdGUgaW50IGNoZWNrX2lnbm9yZXMoc3RyaW5nIG1zZywgaW50IG1zZ190eXBlLCBzdHJpbmcgbXNnX2FjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbXNnX3ByZWZpeCwgb2JqZWN0IG9yaWdpbikKK3sKKyAgLy8gRWluaWdlIERpbmdlIGxhc3NlbiBzaWNoIG5pY2h0IGlnbm9yaWVyZW4uCisgIGlmIChtc2dfdHlwZSAmIChNVF9ORVdTfE1UX05PVElGSUNBVElPTikpCisgICAgcmV0dXJuIDA7CisgIC8vIGFsbGVzIGFuZGVyZSBnZWh0IHp1ciB6ZWl0IGVyc3RtYWwsIHdlbm4gb3JpZ2luIGJla2FubnQgVU5EIE5JQ0hUIGRhcworICAvLyBlaWdlbmUgT2JqZWt0IGlzdC4gV2FlciBnZ2YuIHNvbnN0IGRvb2YuIEF1c3NlcmRlbSBtdXNzIGVzIG5hdHVlcmxpY2gKKyAgLy8gZWluZSBpZ25vcmllcmJhcmUgbXNnX2FjdGlvbiBnZWJlbi4KKyAgZWxzZSBpZiAoc3RyaW5ncChtc2dfYWN0aW9uKSAmJiBvcmlnaW4gJiYgb3JpZ2luICE9IE1FKQorICB7CisgICAgc3RyaW5nIHNyY25hbWUgPQorICAgICAgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob3JpZ2luKSA/IG9yaWdpbi0+cXVlcnlfcmVhbF9uYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBvcmlnaW4tPm5hbWUoV0VSKSB8fCAiIik7CisgICAgbWFwcGluZyBpZ24gPSBRdWVyeShQX0lHTk9SRSwgRl9WQUxVRSk7CisKKyAgICBpZiAobWVtYmVyKGlnbiwgc3JjbmFtZSkpCisgICAgICByZXR1cm4gTVNHX0lHTk9SRUQ7CisgICAgLy8gdmllbGxlaWNodCB3aXJkIGlyZ2VuZHdhcyBhIGxhIG5hbWUuYWt0aW9uIGlnbm9yaWVydD8KKyAgICAvLyBkaWVzIGlnbm9yaWVydCBhdWNoIHNwaWVsZXIuZWJlbmVuLjxlYmVuZT4gKHMuIG1zZ19hY3Rpb24gYmVpCisgICAgLy8gRWJlbmVubWVsZHVuZ2VuKQorICAgIGlmIChtZW1iZXIoaWduLCBzcmNuYW1lKyIuIittc2dfYWN0aW9uKSkKKyAgICAgIHJldHVybiBNU0dfVkVSQl9JR047CisgICAgLy8gT2RlciBkaWUgQWt0aW9uIGtvbXBsZXR0PyBEaWVzIGlnbm9yaWVydCBhdWNoIC5lYmVuZW4uPGViZW5lPiwgb2J3b2hsCisgICAgLy8gZGFzIHJlaWNobGljaCBzaW5uZnJlaSBpc3QuCisgICAgaWYgKG1lbWJlcihpZ24sICIuIittc2dfYWN0aW9uKSkKKyAgICAgIHJldHVybiBNU0dfVkVSQl9JR047CisgICAgLy8gU3BpZWxlciBhdWYgRWJlbmVuIGlnbm9yaWVydD8KKyAgICAvLyBtc2dfYWN0aW9uIGlzdCBoaWVyIG5hY2ggZGllc2VtIE11c3RlcjogTUFfQ0hBTk5FTC48ZWJlbmU+CisgICAgaWYgKHN0cnN0cihtc2dfYWN0aW9uLCBNQV9DSEFOTkVMKSA9PSAwKQorICAgIHsKKyAgICAgIC8vIHNwaWVsZXIuZWJlbmVuPyAoc3BpZWxlci5lYmVuZW4uPGViZW5lPiBvYmVuIHNjaG9uIGdlcHJ1ZWZ0KQorICAgICAgaWYgKG1lbWJlcihpZ24sIHNyY25hbWUgKyAiLiJNQV9DSEFOTkVMKSkKKyAgICAgICAgcmV0dXJuIE1TR19JR05PUkVEOworICAgICAgLy8gc3BpZWxlci5lYmVuZW4uZWJlbmVubmFtZSBpc3Qgb2JlbiBzY2hvbiBhYmdlZGVja3QuCisgICAgICAvLyAuZWJlbmVuIGhhbHRlIGljaCBmdWVyIHNpbm5mcmVpLCBuaWNodCBnZXBydWVmdC4KKyAgICB9CisgICAgLy8gU3BpZWxlciBhdXMgYW5kZXJlbSBtdWQ/ICpzZXVmeioKKyAgICBpZiAoc3Ryc3RyKHNyY25hbWUsIkAiKSA+IC0xKQorICAgIHsKKyAgICAgIHN0cmluZyAqc3JjcGFydHMgPSBleHBsb2RlKHNyY25hbWUsIkAiKTsKKyAgICAgIGlmIChzaXplb2Yoc3JjcGFydHMpPT0yKQorICAgICAgeworICAgICAgICAvLyBzcGllbGVyQD8KKyAgICAgICAgaWYgKG1lbWJlcihpZ24sIHNyY3BhcnRzWzBdKyJAIikpCisgICAgICAgICAgcmV0dXJuIE1TR19JR05PUkVEOworICAgICAgICAvLyBvZGVyIE11ZCBwZXIgQG11ZD8KKyAgICAgICAgaWYgKG1lbWJlcihpZ24sICJAIiArIHNyY3BhcnRzWzFdKSkKKyAgICAgICAgICByZXR1cm4gTVNHX01VRF9JR047CisgICAgICAgIC8vIEJUVzogc3BpZWxlckBtdWQgd3VyZGUgc2Nob24gZ2FueiBvYmVuIGVyZmFzc3QuCisgICAgICB9CisgICAgfQorICB9CisgIC8vIERlZmF1bHQ6IG5pY2h0IGlnbm9yaWVyZW4uCisgIHJldHVybiAwOworfQorCisvLyBXaXJkIGRpZSBuYWNocmljaHQgd2Focmdlbm9tbWVuPyBEaWUgUHJ1ZWZ1bmcgZXJmb2xndCBhdWZncnVuZCB2b24KKy8vIG1zZ190eXBlLiBadXIgd2lyZCBNVF9MT09LIHVuZCBNVF9MSVNURU4gYmVydWVja3NpY2h0aWd0IChQcnVlZnVuZyBhdWYKKy8vIEJMaW5kaGVpdC9UYXViaGVpdCkuCisvLyBXaWNodGlnOiBlbnRoYWVsdCBtc2dfYWN0aW9uIHdlZGVyIE1UX0xPT0sgbm9jaCBNVF9MSVNURU4sIHdpcmQgZGllCisvLyBOYWNocmljaHQgd2Focmdlbm9tbWVuLCBkYSBkYXZvbiBhdXNnZWdhbmdlbiB3aXJkLCBkYXNzIHNpZSBtaXQgZGVuIGJlaWRlbgorLy8gU2lubiBnYXIgbml4IHp1IHR1biBoYXQuCisvLyBSdWVja2dhYmU6IDAgb2RlciBNU0dfU0VOU0VfQkxPQ0sKK3ByaXZhdGUgaW50IGNoZWNrX3NlbnNlcyhzdHJpbmcgbXNnLCBpbnQgbXNnX3R5cGUsIHN0cmluZyBtc2dfYWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIG1zZ19wcmVmaXgsIG9iamVjdCBvcmlnaW4pCit7CisgIGludCBzZW5zZXMgPSBtc2dfdHlwZSAmIChNVF9MT09LfE1UX0xJU1RFTik7CisgIC8vIFdlbm4gdm9uIHZvcmhlcmVpbiBrZWluIFNpbm4gYW5nZXNwcm9jaGVuLCBkYW5uIGlzdCBlcyBlaW5lIG5hY2hyaWNodCwKKyAgLy8gZGllIHZvbiBrZWluZW0gZGVyIGJlaWRlbiB3YWhyZ2Vub21tZW4gd2lyZCB1bmQgc29sbHRlIGRlbW5hY2ggbmljaHQKKyAgLy8gdW50ZXJkcnVlY2t0IHdlcmRlbi4KKyAgaWYgKCFzZW5zZXMpCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKChzZW5zZXMgJiBNVF9MT09LKSAmJiBDYW5ub3RTZWUoMSkpCisgICAgc2Vuc2VzICY9IH5NVF9MT09LOyAgLy8gU2lubiBsb2VzY2hlbgorCisgIGlmICgoc2Vuc2VzICYgTVRfTElTVEVOKSAmJiBRdWVyeVByb3AoUF9ERUFGKSkKKyAgICBzZW5zZXMgJj0gfk1UX0xJU1RFTjsKKworICAvLyB3ZW5uIGtlaW4gU2lubiBtZWhyIHVlYmVyLCB3aXJkIGRpZSBOYWNocmljaHQgbmljaHQgd2Focmdlbm9tbWVuLgorICBpZiAoIXNlbnNlcykKKyAgICByZXR1cm4gTVNHX1NFTlNFX0JMT0NLOworCisgIHJldHVybiAwOworfQorCitwdWJsaWMgdmFyYXJncyBpbnQgUmVjZWl2ZU1zZyhzdHJpbmcgbXNnLCBpbnQgbXNnX3R5cGUsIHN0cmluZyBtc2dfYWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nIG1zZ19wcmVmaXgsIG9iamVjdCBvcmlnaW4pCit7CisgIGlmICghbXNnKSByZXR1cm4gTVNHX0ZBSUxFRDsKKworICAvLyBGbGFncyB1bmQgVHlwZW4gc3BhbHRlbgorICBpbnQgZmxhZ3MgPSBtc2dfdHlwZSAmIE1TR19BTExfRkxBR1M7CisgIGludCB0eXBlID0gbXNnX3R5cGUgJiB+ZmxhZ3M7CisKKyAgLy8gZ2dmLiBkZWZhdWx0cyBlcm1pdHRlbG4KKyAgb3JpZ2luIHx8PSBwcmV2aW91c19vYmplY3QoKTsKKyAgbXNnX2FjdGlvbiB8fD0gY29tbV9ndWVzc19hY3Rpb24oKTsKKyAgdHlwZSB8fD0gY29tbV9ndWVzc19tZXNzYWdlX3R5cGUobXNnX2FjdGlvbiwgb3JpZ2luKTsKKworICAvLyBEZWJ1Z21lbGR1bmdlbiBudXIgYW4gTWFnaWVyIG9kZXIgVGVzdHNwaWVsZXIgbWl0IFBfV0laX0RFQlVHCisgIGlmIChtc2dfdHlwZSAmIE1UX0RFQlVHKQorICB7CisgICAgaWYgKCFRdWVyeVByb3AoUF9XSVpfREVCVUcpCisgICAgICAgIHx8ICghSVNfTEVBUk5FUihNRSkgJiYgIVF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpKSApCisgICAgcmV0dXJuIE1TR19GQUlMRUQ7CisgIH0KKworICAvLyBadWVyc3Qgd2VyZGVuIFNpbm5lIHVuZCBQX0lHTk9SRSBzb3dpZSBnZ2YuIHNvbnN0aWdlIEZpbHRlciBnZXBydWVmdC4gSW4KKyAgLy8gZGVtIEZhbGwgaXN0IGRpcmVrdCBFbmRlLCBrZWluIEtvYm9sZCwga2VpbmUgS29tbS1IaXN0b3J5LCBrZWluZQorICAvLyBXZWl0ZXJiZWFyYmVpdHVuZy4KKyAgLy8gYWJlciBiZXN0aW1tdGUgRGluZ2UgbGFzc2VuIHNpY2ggZWluZmFjaCBuaWNodCBpZ25vcmllcmVuLgorICBpZiAoIShmbGFncyAmIE1TR19ET05UX0lHTk9SRSkpCisgIHsKKyAgICAvLyBTaW5uZSBwcnVlZmVuLiAobnVyIHR5cGVuIHVlYmVyZ2ViZW4sIGtlaW5lIEZsYWdzKQorICAgIGludCByZXM9Y2hlY2tfc2Vuc2VzKG1zZywgdHlwZSwgbXNnX2FjdGlvbiwgbXNnX3ByZWZpeCwgb3JpZ2luKTsKKyAgICBpZiAocmVzKSByZXR1cm4gcmVzOworCisgICAgLy8gU3BpZWxlci1kZWZpbmllcnRlcyBJZ25vcmllcmU/IChudXIgdHlwZW4gdWViZXJnZWJlbiwga2VpbmUgRmxhZ3MpCisgICAgcmVzPWNoZWNrX2lnbm9yZXMobXNnLCB0eXBlLCBtc2dfYWN0aW9uLCBtc2dfcHJlZml4LCBvcmlnaW4pOworICAgIGlmIChyZXMpIHJldHVybiByZXM7CisgIH0KKworICAvLyBGdWVyIE1UX0NPTU0gZ2lidCBlcyBlaW4gcGFhciBTb25kZXJkaW5nZSB6dSBtYWNoZW4uCisgIGlmICgodHlwZSAmIE1UX0NPTU0pKQorICB7CisgICAgLy8gZXJzdG1hbCBpbiBkZXIgS29tbS1IaXN0b3J5IGFibGVnZW4sIHdlbm4gZ2V3dWVuc2NodC4KKyAgICBpZiAoKCEoZmxhZ3MgJiBNU0dfRE9OVF9TVE9SRSkpKQorICAgIHsKKyAgICAgIHN0cmluZyB1aWQ7CisgICAgICBpZiAocXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvcmlnaW4pKQorICAgICAgICB1aWQgPSBvcmlnaW4tPnF1ZXJ5X3JlYWxfbmFtZSgpOworICAgICAgZWxzZQorICAgICAgICB1aWQgPSBvcmlnaW4tPm5hbWUoV0VSKSB8fCAiPHVuYmVrYW5udD4iOworICAgICAgYWRkX3RvX3RlbGxfaGlzdG9yeSh1aWQsIDAsIDEsIG1zZywgbXNnX3ByZWZpeCwgMCk7CisgICAgfQorCisgICAgLy8gZ2dmLiBVaHJ6ZWl0IGJlaSBhYndlc2VuZGVuIFNwaWVsZXJuIGFuaGFlbmdlbiwgYWJlciBuaWNodCBiZWkKKyAgICAvLyBFYmVuZW5tZWxkdW5nZW4uIChEaWUgaGFiZW4gZ2dmLiBzY2hvbi4pCisgICAgaWYgKHN0cmluZ3AobXNnX2FjdGlvbikgJiYgUXVlcnlQcm9wKFBfQVdBWSkKKyAgICAgICAgJiYgc3Ryc3RyKG1zZ19hY3Rpb24sIE1BX0NIQU5ORUwpICE9IDApCisgICAgeworICAgICAgLy8gVWhyemVpdCBhbmhhZW5nZW4sIGFiZXIgZ2dmLiBtdXNzIGVpbiBcbiBhYmdlc2Nobml0dGVuIHdlcmRlbi4KKyAgICAgIGlmIChtc2dbPDFdID09ICdcbicpCisgICAgICAgIG1zZyA9IG1zZ1swLi48Ml0rIiBbIiArIHN0cmZ0aW1lKCIlSDolTSIsdGltZSgpKSArICJdXG4iOworICAgICAgZWxzZQorICAgICAgICBtc2cgPSBtc2cgKyAiIFsiICsgc3RyZnRpbWUoIiVIOiVNIix0aW1lKCkpICsgIl0iOworICAgIH0KKyAgICAvLyBLb2JvbGQgZXJsYXVidCB1bmQgZ2V3dWVuc2NodD8gS29ib2xkIGlzdCBmdWVyIGRpZQorICAgIC8vIGRpcmVrdGUgS29tbXVuaWthdGlvbiBtaXR0ZWxzIE1UX0NPTU0gdm9yZ2VzZWhlbi4KKyAgICAvLyBPcm9wYXggdm9uIE1hZ2llcm4gbGVpdGV0IGluendpc2NoZW4gYXVjaCBudXIgaW4gS29ib2xkIHVtIHN0YXR0IHp1CisgICAgLy8gaWdub3JpZXJlbi4KKyAgICAvLyBkaWUgaWYtS29uc3RydWt0aW9uIGlzdCBzbywgd2VpbCBpY2ggZGFzIF9mbHVzaF9jYWNoZSgpIGltIGVsc2UKKyAgICAvLyBicmF1Y2hlLgorICAgIGlmIChxdWVyeV9lZGl0aW5nKHRoaXNfb2JqZWN0KCkpIHx8IHF1ZXJ5X2lucHV0X3BlbmRpbmcodGhpc19vYmplY3QoKSkKKyAgICAgICAgfHwgUXVlcnlQcm9wKFBfRUFSTVVGRlMpKQorICAgIHsKKyAgICAgIGlmICghKGZsYWdzICYgTVNHX0RPTlRfQlVGRkVSKQorICAgICAgICAgICAgJiYgUXVlcnlQcm9wKFBfQlVGRkVSKSkKKyAgICAgIHsKKyAgICAgICAgLy8gTmFjaHJpY2h0IHNvbGwgaW0gS29ib2xkIGdlc3BlaWNoZXJ0IHdlcmRlbi4KKyAgICAgICAgcmV0dXJuIGFkZF90b19rb2JvbGQobXNnLCBtc2dfdHlwZSwgbXNnX2FjdGlvbiwgbXNnX3ByZWZpeCwgb3JpZ2luKTsKKyAgICAgIH0KKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgIC8vIHdlbm4gbmljaHQgaW4gRWRpdG9yL2lucHV0X3RvLCBtYWwgdmVyc3VjaGVuLCBkZW4gS29ib2xkIHp1CisgICAgICAvLyBlbnRsZWVyZW4uCisgICAgICBfZmx1c2hfY2FjaGUoMCk7CisgICAgfQorCisgICAgLy8gZ2dmLiBQaWVwc3RvbiBhbmhhZW5nZW4uIE5BQ0ggS29ib2xkYWJsYWdlLCBkaWUgc29sbGVuIGVyc3RtYWwga2VpbmVuCisgICAgLy8gUGllcHMga3JpZWdlbi4KKyAgICBpZiAoY29tbV9iZWVwKCkpCisgICAgICBtc2c9bXNnICsgTUVTU0FHRV9CRUVQOworICB9CisKKyAgLy8gQXVzZ2FiZW5hY2hyaWNodCBiYXVlbiB1bmQgYW4gZGVuIFNwaWVsZXIgc2VuZGVuLgorICBpZiAoZmxhZ3MgJiBNU0dfRE9OVF9XUkFQKQorICAgIG1zZyA9IChtc2dfcHJlZml4ID8gbXNnX3ByZWZpeCA6ICIiKSArIG1zZzsKKyAgZWxzZQorICB7CisgICAgaW50IGJzZmxhZ3MgPSBmbGFncyAmIE1TR19BTExfQlNfRkxBR1M7CisgICAgaWYgKFF1ZXJ5UHJvcChQX01FU1NBR0VfUFJFUEVORCkpCisgICAgICBic2ZsYWdzIHw9IEJTX1BSRVBFTkRfSU5ERU5UOworICAgIG1zZyA9IGJyZWFrX3N0cmluZyhtc2csIDc4LCBtc2dfcHJlZml4LCBic2ZsYWdzKTsKKyAgfQorICBlZnVuOjp0ZWxsX29iamVjdChNRSwgbXNnKTsKKworICByZXR1cm4gTVNHX0RFTElWRVJFRDsKK30KZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvY29tbV9zdHJ1Y3RzLmMgYi9zdGQvcGxheWVyL2NvbW1fc3RydWN0cy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjVmMjY4ZWIKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2NvbW1fc3RydWN0cy5jCkBAIC0wLDAgKzEsNDEgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBwbGF5ZXIvY29tbS5jLS0gYmFzaWMgcGxheWVyIGNvbW11bmljdGlvbiBjb21tYW5kcworLy8KKy8vICRJZDogY29tbS5jIDY5MTggMjAwOC0wOC0wNyAyMToxMzoxNlogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworc3RydWN0IG1zZ19zIHsKKyAgc3RyaW5nIG1zZzsgICAgICAgLy8gSW5oYWx0IGRlciBOYWNocmljaHQKKyAgaW50IHR5cGU7ICAgICAgICAgLy8gTWVzc2FnZXR5cCBmdWVyIFJlY2VpdmVNc2cKKyAgc3RyaW5nIGFjdGlvbjsgICAgLy8gTWVzc2FnZWFjdGlvbiBmdWVyIFJlY2VpdmVNc2cKKyAgc3RyaW5nIHByZWZpeDsgICAgLy8gRWlucnVlY2t1bmcgZGVyIE5hY2hyaWNodCBiZWkgRGFyc3RlbGx1bmcgKG1zZ19wcmVmaXgpCisgIHN0cmluZyBzZW5kZXJuYW1lOy8vIFVyc3BydW5nIGRlciBOYWNocmljaHQKK307CisKK3N0cnVjdCBzdG9yZWRfbXNnX3MgKG1zZ19zKSB7CisgIGludCB0aW1lc3RhbXA7ICAgIC8vIFplaXRzdGVtcGVsIGRlciBOYWNocmljaHQKK307CisKK3N0cnVjdCBtc2dfYnVmZmVyX3MgeworICAvL3N0cnVjdCBtc2dfcyAqYnVmOworICBtaXhlZCAqYnVmOworICBpbnQgaW5kZXg7Cit9OworCitzdHJ1Y3QgY2hhdF9zIHsKKyAgc3RyaW5nIHVpZDsgICAgICAgICAgIC8vIFVJRCBkZXMgR2VzcHJhZWNoc3BhcnRuZXJzCisgIGludCB0aW1lX2ZpcnN0X21zZzsgICAvLyBaZWl0IGRlciBlcnN0ZW4gTmFjaHJpY2h0CisgIGludCB0aW1lX2xhc3RfbXNnOyAgICAvLyBaZWl0IGRlciBsZXR6ZW4gTmFjaHJpY2h0CisgIGludCBzZW50Y291bnQ7ICAgICAgICAvLyBBbnphaGwgZ2VzZW5kZXRlciBOYWNocmljaHRlbgorICBpbnQgcmVjdmNvdW50OyAgICAgICAgLy8gQW56YWhsIGVtcGZhbmdlbmVyIE5hY2hyaWNodGVuCisgIG1peGVkIG1zZ2J1ZjsgICAgICAgICAvLyBBcnJheSB2b24gbXNnX3MgKEFydCBSaW5ncHVmZmVyKQorICBpbnQgcHRyOyAgICAgICAgICAgICAgLy8gUG9pbnRlciBhdWYgZGllIG5hZWNoc3RlIHp1IHVlYmVyc2NocmVpYmVuZGUgbXNnX3MKKyAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluIG1zZ2J1ZgorfTsKKwpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9jb21tYW5kLmMgYi9zdGQvcGxheWVyL2NvbW1hbmQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMzA0NDVkCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9jb21tYW5kLmMKQEAgLTAsMCArMSwxMDc0IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL2NvbW1hbmRzLmMgLS0gYWxpYXMsIGhpc3RvcnkgYW5kIHBsYXllciBjb21tYW5kIGhhbmRsaW5nCisvLworLy8gJElkOiBjb21tYW5kLmMgOTU3NiAyMDE2LTA2LTE4IDE1OjAwOjAxWiBaZXNzdHJhICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKy8vI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHBsYXllci9jb21tYW5kLmg+CisjaW5jbHVkZSA8cGxheWVyL2NvbW0uaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGl2aW5nL21vdmluZy5oPgorI2luY2x1ZGUgPHBsYXllci5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPGNvbmZpZy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxsb2dnaW5nLmg+CisjaW5jbHVkZSA8c3RyaW5ncy5oPgorCisjZGVmaW5lIENCTE9HKHgpICAgIGxvZ19maWxlKFNIRUxMTE9HKCJESVNBQkxFQ09NTUFORFMiKSx4LDIwMDAwMCkKKworI2RlZmluZSBISVNUX1NJWkUgNDAKKyNkZWZpbmUgRVBNQVNURVIgIi9zZWN1cmUvZXhwbG9yYXRpb25tYXN0ZXIiCisKK3ByaXZhdGUgbWFwcGluZyBhbGlhc2VzOworcHJpdmF0ZSBzdHJpbmcgKmNvbW1hbmRzOworcHJpdmF0ZSBpbnQgaGlzdF9zaXplLCBzaG93X3Byb2Nlc3NpbmcsIGhpc3RtaW47Citwcml2YXRlIHN0cmluZyBkZWZhdWx0X25vdGlmeV9mYWlsOworcHJpdmF0ZSBub3NhdmUgc3RyaW5nICpoaXN0b3J5LCAqdW5wYXJzZWRfYXJncywgdW5tb2RpZmllZDsKK3ByaXZhdGUgbm9zYXZlIGludCBoaXN0X25vdzsKK3ByaXZhdGUgbm9zYXZlIG9iamVjdCBsYXN0X2NvbW1hbmRfZW52OworcHJpdmF0ZSBub3NhdmUgaW50IGNtZHNfcGVyX3RpbWUsIGxhc3RfY2hnLCBtYXhfY29tbWFuZHMsICpjbWRfdHlwZXM7CisvLyBEYXRlbnN0cnVrdHVyOiAoe1NldHplciwgQWJsYXVmemVpdCwgU3RyaW5nL0Nsb3N1cmV9KQorcHJpdmF0ZSBub3NhdmUgbWl4ZWQgZGlzYWJsZWNvbW1hbmRzOworcHJpdmF0ZSBub3NhdmUgb2JqZWN0KiBzeW50YXhkYjsKKworbm9tYXNrIHZvaWQgX19zZXRfYmIoaW50IGZsYWcpOworCitzdGF0aWMgdmFyYXJncyBpbnQgX19hdXN3ZXJ0ZW4oc3RyaW5nIHN0ciwgc3RyaW5nIGludGVybik7Cit2YXJhcmdzIGludCBTb3VsQ29tbShzdHJpbmcgc3RyLCBzdHJpbmcgX3ZlcmIpOwordmFyYXJncyBtaXhlZCBNb3JlKHN0cmluZyBzdHIsIGludCBmZmxhZywgc3RyaW5nIHJldHVybnRvKTsKK3N0YXRpYyBpbnQgX3N0YXJ0c193aXRoKHN0cmluZyBzdHIsIHN0cmluZyBzdGFydCk7CitzdGF0aWMgdm9pZCByZWFsbG9jYXRlX2hpc3RidWYoKTsKKworcHJpdmF0ZSB2b2lkIEFkZEhpc3Rvcnkoc3RyaW5nIHN0cikKK3sKKyAgaWYgKCFzdHJpbmdwKHN0cikgfHwgc3RyPT0iIiB8fCBzdHJbMF09PScmJyB8fCBzdHJbMF09PSdeJyB8fAorICAgICAgc3RyPT0iaGlzdCIpCisgICAgcmV0dXJuOworICBpZiAoIWhpc3Rfc2l6ZSkgcmV0dXJuOworICBpZiAoIXBvaW50ZXJwKGhpc3RvcnkpIHx8IHNpemVvZihoaXN0b3J5KSE9aGlzdF9zaXplKQorICAgIHJlYWxsb2NhdGVfaGlzdGJ1ZigpOworICBpZiAoc2l6ZW9mKHN0cik+PWhpc3RtaW4gJiYgaGlzdG9yeVsoaGlzdF9zaXplK2hpc3Rfbm93LTEpJWhpc3Rfc2l6ZV0hPXN0cikKKyAgICBoaXN0b3J5WyhoaXN0X25vdysrKSVoaXN0X3NpemVdPXN0cjsKK30KKworc3RhdGljIHZvaWQgY3JlYXRlKCkKK3sKKyAgbGFzdF9jaGc9MDsKKyAgaGlzdG1pbj1oaXN0X25vdz0wOworICBTZXQoUF9MT0NBTENNRFMsKHt9KSk7CisgIFNldChQX0xPQ0FMQ01EUyxQUk9URUNURUQsRl9NT0RFX0FTKTsKKyAgU2V0KCJfc3ludGF4ZGIiLCBTRUNVUkVEfFNBVkUsIEZfTU9ERV9BUyk7CisKKyAgc2hvd19wcm9jZXNzaW5nPTE7CisgIHVucGFyc2VkX2FyZ3M9KHswLDAsMH0pOworICBoaXN0X3NpemU9SElTVF9TSVpFOworfQorCitzdGF0aWMgaW50IHJlcGxhY2VkaXNwbGF5KHN0cmluZyBzdHIpCit7CisgIGlmICghc3RyIHx8IHN0cj09IiIgfHwgIXNzY2FuZihzdHIsIiVkIixzaG93X3Byb2Nlc3NpbmcpKQorICAgIHByaW50ZigiVW56dWxhZXNzaWdlIEVpbmdhYmUhXG4lcyAwfDF8MlxuIixxdWVyeV92ZXJiKCkpOworICAgIHByaW50ZigiRXJzZXR6dW5nc2FuemVpZ2UgYXVmIExldmVsICVkLlxuTGV2ZWwgMDogTmljaHRzIGFuemVpZ2VuXG4iKworICAgICAiTGV2ZWwgMTogTnVyIEhpc3RvcnktRXJzZXR6dW5nZW4gYW56ZWlnZW5cbiIrCisgICAgICJMZXZlbCAyOiBIaXN0b3J5LSB1bmQgQWxpYXMtRXJzZXR6dW5nZW4gYW56ZWlnZW5cbiIsc2hvd19wcm9jZXNzaW5nKTsKKyAgaWYgKHNob3dfcHJvY2Vzc2luZz4yJiYhSVNfV0laQVJEKE1FKSkgc2hvd19wcm9jZXNzaW5nPTI7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IGhpc3RtaW4oc3RyaW5nIHN0cikKK3sKKyAgaW50IGxlbjsKKworICBpZiAoIXN0cnx8IXNzY2FuZihzdHIsIiVkIixsZW4pfHxsZW48MCkKKyAgeworICAgIHdyaXRlKCJCZW51dHp1bmc6IGhpc3RtaW4gWkFITFxuTGVndCBkaWUgTWluZGVzdGxhZW5nZSBmZXN0LCBkaWUgZWluZSBcCitCZWZlaGxzemVpbGUgaGFiZW4gbXVzcywgdW0gaW4gZGVuXG5IaXN0b3J5LVB1ZmZlciB6dSBnZWxhbmdlbi4gRGVyemVpdCBcCitlaW5nZXN0ZWxsdCBhdWYgIisoc3RyaW5nKWhpc3RtaW4rIiBaZWljaGVuLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaGlzdG1pbj1sZW47CisgIHdyaXRlKCJNaW5kZXN0bGFlbmdlIGF1ZiAiKyhzdHJpbmcpbGVuKyIgZWluZ2VzdGVsbHQuXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyB2b2lkIHJlYWxsb2NhdGVfaGlzdGJ1ZigpCit7CisgIGludCBpOworCisgIGhpc3Rvcnk9YWxsb2NhdGUoaGlzdF9zaXplKTsKKyAgaGlzdF9ub3c9MDsKKyAgZm9yIChpPTA7aTxoaXN0X3NpemU7aSsrKQorICAgIGlmICghc3RyaW5ncChoaXN0b3J5W2ldKSkKKyAgICAgIGhpc3RvcnlbaV09IlxuXG4iOworfQorCitzdGF0aWMgaW50IGhpc3RsZW4oc3RyaW5nIHN0cikKK3sKKyAgaW50IGQ7CisgIGlmICghc3RyfHwhc3NjYW5mKHN0ciwiJWQiLGQpfHxkPDB8fGQ+NDApCisgIHsKKyAgICB3cml0ZSgiQmVudXR6dW5nOiBoaXN0bGVuIFpBSExcblpBSEwgbXVzcyB6d2lzY2hlbiAwIHVuZCA0MCBsaWVnZW4uXG4iKTsKKyAgICBwcmludGYoIkRlaW5lIEhpc3RvcnktQnVmZmVyLUxhZW5nZSBsaWVndCBiZWkgJWQgQmVmZWhsZW4uXG4iLGhpc3Rfc2l6ZSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaGlzdF9zaXplPWQ7CisgIHByaW50ZigiRGVpbmUgSGlzdG9yeS1CdWZmZXItTGFlbmdlIGxpZWd0IGpldHp0IGJlaSAlZCBCZWZlaGxlbi5cbiIsCisgICBoaXN0X3NpemUpOworICByZWFsbG9jYXRlX2hpc3RidWYoKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyB2b2lkIGluaXRpYWxpemUoKQoreworICBpZiAoIXBvaW50ZXJwKGhpc3RvcnkpfHxzaXplb2YoaGlzdG9yeSkhPWhpc3Rfc2l6ZSkKKyAgICByZWFsbG9jYXRlX2hpc3RidWYoKTsKKyAgYWRkX2FjdGlvbigiX19hdXN3ZXJ0ZW4iLCIiLDEpOworICAgIG1heF9jb21tYW5kcyA9IEVQTUFTVEVSLT5RdWVyeUNvbW1hbmRzKCk7CisgICAgY21kX3R5cGVzID0gRVBNQVNURVItPlF1ZXJ5Q21kVHlwZXMoKSB8fCAoe30pOworCisgICAgaWYgKCAhbWFwcGluZ3AoYWxpYXNlcykgKQorICAgICAgICBhbGlhc2VzID0gKFtdKTsKKworICAgIGlmICggIXBvaW50ZXJwKGNvbW1hbmRzKSApCisgICAgICAgIGNvbW1hbmRzID0gKHt9KTsKKworICAgIGlmIChRdWVyeVByb3AoIl9zeW50YXhkYiIpKQorICAgICAgICBzeW50YXhkYiA9ICh7ZmluZF9vYmplY3QoIi9zZWN1cmUvc3ludGF4ZGIiKX0pOworLyogICAgZWxzZSBpZiAoUXVlcnlQcm9wKFBfVEVTVFBMQVlFUikpCisgICAgeworICAgICAgU2V0UHJvcCgiX3N5bnRheGRiIiwgMSk7CisgICAgICBjYWxsX291dCgjJ19ub3RpZnksIDIsCisgICAgICAgICAgIlxuRGEgRHUgYWxzIFRlc3RzcGllbGVyIG1hcmtpZXJ0IGJpc3QsIHd1cmRlIGJlaSBEaXIgIgorICAgICAgICAgICJkaWUgU3ludGF4c2FtbWx1bmcgZWluZ2VzY2hhbHRldC4gRHUga2FubnN0IGRpZXMgIgorICAgICAgICAgICJ3aWVkZXIgYXVzc2NoYWx0ZW4uIChoaWxmZSBzeW50YXhzYW1tbHVuZykgIgorICAgICAgICAgICJFcyB3YWVyZSBzY2hvZW4sIHdlbm4gRHUgZXMgYmVpbSBUZXN0ZW4gdm9uICIKKyAgICAgICAgICAiR2ViaWV0ZW4gZWluc2NoYWx0ZXN0LiIsIDApOworICAgIH0qLworfQorCitzdGF0aWMgbWl4ZWQgX3NldF9kZWZhdWx0X25vdGlmeV9mYWlsKHN0cmluZyBzKQoreworICBpZiAoc3RyaW5ncChzKSYmcyE9IiIpCisgIHsKKyAgICBpZiAoc1s8MV0hPSdcbicpIHMrPSJcbiI7CisgICAgcmV0dXJuIGRlZmF1bHRfbm90aWZ5X2ZhaWw9czsKKyAgfQorICBlbHNlIGlmICghc3x8cz09IiIpCisgICAgcmV0dXJuIChkZWZhdWx0X25vdGlmeV9mYWlsPTApOworfQorCitzdGF0aWMgbWl4ZWQgX3F1ZXJ5X2RlZmF1bHRfbm90aWZ5X2ZhaWwoKQoreworICByZXR1cm4gZGVmYXVsdF9ub3RpZnlfZmFpbDsKK30KKworc3RhdGljIGludCBzZXRfZXJyb3JtZXNzYWdlKHN0cmluZyBzKQoreworICBpZiAoIShzPV91bnBhcnNlZF9hcmdzKCkpKQorICB7CisgICAgX3NldF9kZWZhdWx0X25vdGlmeV9mYWlsKDApOworICAgIHdyaXRlKCJTdGFuZGFyZC1GZWhsZXJtZWxkdW5nIGF1ZiBcIldpZSBiaXR0ZT9cIiBnZXNldHp0LlxuIik7CisgIH0gZWxzZQorICB7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKHNwcmludGYoIlN0YW5kYXJkLUZlaGxlcm1lbGR1bmcgYXVmICVzIGdlc2V0enQuXG4iLAorICAgICAgICAgICAgIHMpLDc4KSk7CisgICAgX3NldF9kZWZhdWx0X25vdGlmeV9mYWlsKHMpOworICB9CisgIHJldHVybiAxOworfQorCit2b2lkIHJlY29ubmVjdCgpCit7CisgIGlmICghbWFwcGluZ3AoYWxpYXNlcykpIGFsaWFzZXM9KFtdKTsKKworICAgIGlmICggIXBvaW50ZXJwKGNvbW1hbmRzKSApCisgICAgICAgIGNvbW1hbmRzID0gKHt9KTsKKworICAgIG1heF9jb21tYW5kcyA9IEVQTUFTVEVSLT5RdWVyeUNvbW1hbmRzKCk7CisgICAgY21kX3R5cGVzID0gRVBNQVNURVItPlF1ZXJ5Q21kVHlwZXMoKSB8fCAoe30pOworfQorCitzdGF0aWMgaW50IHNob3dfaGlzdCgpCit7CisgIGludCBpOworICBzdHJpbmcgY29tbTsKKworICB0ZWxsX29iamVjdCggTUUsICJEaWUgSGlzdG9yeS1MaXN0ZSBlbnRoYWVsdCBmb2xnZW5kZSBLb21tYW5kb3M6XG4iICk7CisKKyAgZm9yKCBpID0gMDsgaSA8IGhpc3Rfc2l6ZTsgaSsrICkKKyAgICAgIGlmICgoY29tbT1oaXN0b3J5WyhoaXN0X25vdytpKSUgaGlzdF9zaXplXSkhPSAiXG5cbiIpCisgICAgICAgICAgdGVsbF9vYmplY3QoIE1FLCAiICYiKyhoaXN0X25vdytpLWhpc3Rfc2l6ZSkrIi8tIisgKGhpc3Rfc2l6ZS1pLTEpCisgICAgICArIlx0PSAiK2NvbW0rIlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgc3RyaW5nIHByZXNlbnRfYWxpYXMobWl4ZWQgKmFsaSkKK3sKKyAgaW50IGosazsKKyAgc3RyaW5nIHMsczI7CisKKyAgZm9yIChzPSIiLGo9c2l6ZW9mKGFsaSktMTtqPj0wO2otLSkKKyAgICBpZiAoaW50cChhbGlbal0pKQorICAgICAgaWYgKChrPWFsaVtqXSk8MCkKKyAgcz0iJCIrKGs9PS0xPyIiOihzdHJpbmcpLWspKyIqIitzOworICAgICAgZWxzZQorICBzPSIkIisoc3RyaW5nKWsrczsKKyAgICBlbHNlCisgICAgICB7CisgICAgICAgICBzMj1pbXBsb2RlKGV4cGxvZGUoYWxpW2pdLCJcXCIpLCJcXFxcIik7CisgICAgICAgICBzPWltcGxvZGUoZXhwbG9kZShzMiwiJCIpLCJcXCQiKStzOworICAgICAgfQorICByZXR1cm4gczsKK30KKworI2RlZmluZSBBTElGT1JNQVQgKHsiICVzXHQ9ICVzIiwgImFsaWFzICVzICVzIn0pW2Rpc3BsYXlfYXNfYWxpYXNjb21tYW5kXQorLy8gSWNoIHdlaXNzLCBkZW4gVmFyaWFibGVubmFtZW4gaW0gZGVmaW5lIHp1IGhhYmVuIGlzdCB1bmZlaW4sIGFiZXIgZGFzCisvLyBtYWNodCBlcyBpbSBDb2RlIGRhbm4gYW5nZW5laG0gdWViZXJzaWNodGxpY2guICAtSHJUCisKK3N0YXRpYyBpbnQgcXVlcnlfYWxpYXNlcyhpbnQgZGlzcGxheV9hc19hbGlhc2NvbW1hbmQpCit7CisgIGludCBpOworICBzdHJpbmcgKmEsKmFsaTsKKworICBpZihpPXNpemVvZihhbGk9c29ydF9hcnJheShtX2luZGljZXMoYWxpYXNlcyksIyc8KSkpIC8vJykpKQorICB7CisgICAgZm9yKGE9KHt9KSxpLS07IGk+PTA7IGktLSkKKyAgICAgICAgYSs9KHtzcHJpbnRmKEFMSUZPUk1BVCwgYWxpW2ldLCBwcmVzZW50X2FsaWFzKCBhbGlhc2VzW2FsaVtpXV0gKSApIH0pOworICAgIE1vcmUoIkR1IGhhc3QgZm9sZ2VuZGUgQWxpYXNlIGRlZmluaWVydDpcbiIraW1wbG9kZShhLCJcbiIpKTsKKyAgfQorICBlbHNlCisgICAgd3JpdGUoIkR1IGhhc3Qga2VpbmUgQWxpYXNlIGRlZmluaWVydC5cbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludAorX3N0YXJ0c193aXRoKHN0cmluZyBzdHIsIHN0cmluZyBzdGFydCkKK3sKKyAgcmV0dXJuIChzaXplb2Yoc3RhcnQpPnNpemVvZihzdHIpID8gMAorICAgIDogc3RyWzAuLnNpemVvZihzdGFydCktMV09PXN0YXJ0KTsKK30KKworc3RhdGljIGludCBhbGlhcyhzdHJpbmcgc3RyKQoreworICBzdHJpbmcgY29tbWFuZDsKKyAgc3RyaW5nICp0bXAsdW0sKmhpdHM7CisgIGludCBudW0sIGwsIHBvcywgY29udDsKKyAgaW50IGRpc3BsYXlfYXNfYWxpYXNjb21tYW5kOworCisgIGlmICh1bm1vZGlmaWVkJiZ1bm1vZGlmaWVkIT0iIikKKyAgICB1bT1pbXBsb2RlKG9sZF9leHBsb2RlKHVubW9kaWZpZWQsIiAiKVsxLi5dLCIgIik7CisgIGlmICh1bT09IiIpIHVtPTA7CisgIGlmKCEoc3RyPXVtfHxfdW5wYXJzZWRfYXJncygpKSB8fCBzdHI9PSIqIikgcmV0dXJuIHF1ZXJ5X2FsaWFzZXMoMCk7CisKKyAgICBpZiAoc3RyPT0iLWEiIHx8IHN0cnN0cihzdHIsICItYSAiKT09MCApICB7CisgICAgc3RyPXN0clsyLi5dOworICAgIGlmIChzdHIgJiYgc3RyIT0iIiAmJiBzdHJbMF09PScgJykgc3RyPXN0clsxLi5dOworICAgIGlmICghc3RyIHx8IHN0cj09IiIgfHwgc3RyPT0iKiIpIHJldHVybiBxdWVyeV9hbGlhc2VzKDEpOworICAgIGRpc3BsYXlfYXNfYWxpYXNjb21tYW5kPTE7CisgIH0KKworICBpZiAoKHBvcz1tZW1iZXIoc3RyLCcgJykpPDApIC8vIDEgQXJnIG9ubHkKKyAgeworICAgIGlmICgodG1wPWFsaWFzZXNbc3RyXSkpCisgICAgICBwcmludGYoQUxJRk9STUFUKyJcbiIsc3RyLHByZXNlbnRfYWxpYXModG1wKSk7CisgICAgZWxzZQorICAgICAgaWYgKHN0cls8MV09PScqJykKKyAgICAgIHsKKyAgICAgICAgc3RyPXN0clswLi48Ml07CisgICAgICAgIGhpdHM9ZmlsdGVyKG1faW5kaWNlcyhhbGlhc2VzKSwgIydfc3RhcnRzX3dpdGgsIHN0cik7CisgICAgICAgIGlmICghc2l6ZW9mKGhpdHMpKQorICAgICAgICB7CisgICAgICAgICAgcHJpbnRmKCJEdSBoYXN0IGtlaW4gQWxpYXMsIGRhcyBtaXQgXCIlc1wiIGFuZmFlbmd0LlxuIiwgc3RyKTsKKyAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgICAgICBoaXRzPXNvcnRfYXJyYXkoaGl0cywgIyc+KTsKKyAgICAgICAgZm9yIChsPXNpemVvZihoaXRzKTsgbC0tOykKKyAgICAgICAgICBoaXRzW2xdPXNwcmludGYoQUxJRk9STUFULCBoaXRzW2xdLCBwcmVzZW50X2FsaWFzKGFsaWFzZXNbaGl0c1tsXV0pKTsKKyAgICAgICAgTW9yZSgiRm9sZ2VuZGUgQWxpYXNlIGJlZ2lubmVuIG1pdCBcIiIrc3RyKyJcIjpcbiIraW1wbG9kZShoaXRzLCJcbiIpKTsKKyAgICAgIH0KKyAgICBlbHNlCisgICAgICBwcmludGYoIkR1IGhhc3Qga2VpbiBBbGlhcyBcIiVzXCIgZGVmaW5pZXJ0LlxuIixzdHIpOworICAgIHJldHVybiAxOworICB9CisgIGlmICghcG9zKQorICB7CisgICAgd3JpdGUoIkZlaGxlcjogQmxhbmMgYW0gQWxpYXMtQW5mYW5nXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoKGNvbW1hbmQ9c3RyWzAuLnBvcy0xXSk9PSJ1bmFsaWFzIikKKyAgeworICAgIHdyaXRlCisgICAgICAoIkVzIG5pY2h0IG1vZWdsaWNoLCBkZW4gQmVmZWhsIHVuYWxpYXMgenUgdWViZXJsYWRlbiAod2FlciBkdW1tIDopKVxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKChjb21tYW5kPXN0clswLi5wb3MtMV0pPT0iKiIpCisgIHsKKyAgICB3cml0ZQorICAgICAgKCJFcyBuaWNodCBtb2VnbGljaCwgZGVuIEJlZmVobCBcIipcIiB6dSB1ZWJlcmxhZGVuLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBzdHI9c3RyW3BvcysxLi5dLHRtcD0oe30pOworICB3aGlsZSAobD1zaXplb2Yoc3RyKSkgeworICAgIHBvcz0wLGNvbnQ9MTsKKyAgICB3aGlsZSAoY29udCkgeworICAgICAgaWYgKHBvczxsKSB7CisgICAgICAgIGlmKHN0cltwb3NdPT0nXFwnKSB7CisgICAgICAgICAgc3RyPXN0clswLi5wb3MtMV0rc3RyW3BvcysxLi5dOworICAgICAgICAgIGwtLTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICBpZiAoc3RyW3Bvc109PScmJyB8fCBzdHJbcG9zXT09JyQnKSB7CisgICAgICAgICAgICBjb250PTA7CisgICAgICAgICAgICBpZiAocG9zPjApIHsKKyAgICAgICAgICAgICAgdG1wKz0oe3N0clswLi5wb3MtMV19KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChwb3M9PWwtMSkgeworICAgICAgICAgICAgICBwcmludGYoIkZlaGxlcjogJWMgYW0gWmVpbGVuZW5kZVxuIixzdHJbcG9zXSk7CisgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKChudW09c3RyWysrcG9zXSk9PScqJykgeworICAgICAgICAgICAgICBudW09MTsKKyAgICAgICAgICAgICAgcG9zLS07CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICBudW0tPScwJzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChudW08MCB8fCBudW0+OSkgeworICAgICAgICAgICAgICBwcmludGYoIkZlaGxlcjogTmFjaCAlYyBtdXNzIFppZmZlciBvZGVyICogZm9sZ2VuXG4iLAorICAgICAgICAgICAgICAgc3RyW3Bvcy0xXSk7CisgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKChzdHI9c3RyW3BvcysxLi5dKSE9IiImJnN0clswXT09JyonKSB7CisgICAgICAgICAgICAgIHN0cj1zdHJbMS4uXTsKKyAgICAgICAgICAgICAgbnVtPS1udW07CisgICAgICAgICAgICB9CisgICAgICAgICAgICB0bXArPSh7bnVtfSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIHBvcysrOworICAgICAgfSBlbHNlIHsKKyAgICAgICAgY29udD0wOworICAgICAgICBpZiAoc3RyIT0iIikgdG1wKz0oe3N0cn0pOworICAgICAgICBzdHI9IiI7CisgICAgICB9CisgICAgfQorICB9CisgIGlmICgoIWFsaWFzZXNbY29tbWFuZF0pICYmIChzaXplb2YoYWxpYXNlcyk+MjAwMCkpCisgICAgcHJpbnRmKCJEdSBoYXN0IHNjaG9uIGdlbnVlZ2VuZCBBbGlhc2UgZGVmaW5pZXJ0IVxuIik7CisgIGVsc2UKKyAgeworICAgIGFsaWFzZXNbY29tbWFuZF09dG1wOworICAgIHByaW50ZigiTmV1ZXMgQWxpYXM6ICVzXHQ9ICVzXG4iLGNvbW1hbmQscHJlc2VudF9hbGlhcyh0bXApKTsKKyAgfQorICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCB1bmFsaWFzKHN0cmluZyBzdHIpIHsKKyAgaW50IGk7CisgIHN0cmluZyAqYWxzLHVtOworCisgIGlmICh1bm1vZGlmaWVkJiZ1bm1vZGlmaWVkIT0iIikKKyAgICB1bT1pbXBsb2RlKG9sZF9leHBsb2RlKHVubW9kaWZpZWQsIiAiKVsxLi5dLCIgIik7CisgIGlmICh1bT09IiIpIHVtPTA7CisgIGlmICggIShzdHI9dW0gfHwgX3VucGFyc2VkX2FyZ3MoKSkpIHJldHVybiAwOworICBpZiAoc3RyID09ICIqLioiIHx8IHN0ciA9PSAiKiIpIHsKKyAgICB3cml0ZShicmVha19zdHJpbmcoCisgICAgICAiVmVyc3VjaHMgbWFsIG1pdCAndW5hbGlhcyAuKicsIHdlbm4gRHUgd2lya2xpY2ggYWxsZSBBbGlhcyBlbnRmZXJuZW4gIgorICAgICAgIndpbGxzdC4iLDc4KSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKCFtZW1iZXIoYWxpYXNlcyxzdHIpKSB7CisgICAgYWxzPXJlZ2V4cChtX2luZGljZXMoYWxpYXNlcyksKCJeIitzdHIrIiQiKSk7CisgICAgaWYgKCEoaT1zaXplb2YoYWxzKSkpIHsKKyAgICAgIHdyaXRlKCJTbyBlaW4gQWxpYXMgaGFzdCBEdSBuaWNodCBkZWZpbmllcnQuXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBmb3IgKC0taTtpPj0wO2ktLSkKKyAgICAgIG1fZGVsZXRlKGFsaWFzZXMsYWxzW2ldKTsKKyAgICB3cml0ZShicmVha19zdHJpbmcoKCJEdSBlbnRmZXJuc3QgZm9sZ2VuZGUgQWxpYXNlOiAiKworICAgICAgaW1wbG9kZShhbHMsIiAiKSsiLlxuIiksNzUpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBtX2RlbGV0ZShhbGlhc2VzLHN0cik7CisgIHdyaXRlKCJEdSBlbnRmZXJuc3QgZGFzIEFsaWFzIFwiIitzdHIrIlwiLlxuIik7CisgIHJldHVybiAxOworfQorCit2YXJhcmdzIHN0cmluZyBfdW5wYXJzZWRfYXJncyhpbnQgbGV2ZWwpCit7CisgIHJldHVybiB1bnBhcnNlZF9hcmdzW2xldmVsXTsKK30KKworI2RlZmluZSBBUlRJS0VMICh7ImRhcyIsImRlciIsImRpZSIsImRlcyIsImRlbSIsImRlbiIsImVpbiIsImVpbmUiLCJlaW5lciIsXAorICAgICAgICAgICAgICAgICAgImVpbmVzIn0pCisKKyNkZWZpbmUgVFJFTk5FUiAoeyJpbiIsImF1cyIsInVlYmVyIiwiYXVmIiwidW50ZXIiLCJtaXQiLCJkdXJjaCIsImZ1ZXIiLFwKKyAgICAgICAgICAgICAgICAgICJ2b24iLCJ2b20iLCJpbSIsImF1ZnMiLCJlaW4iLCJ3ZWciLCJ6dXJ1ZWNrIn0pCisKK3N0YXRpYyBzdHJpbmcgX3NpbmdsZV9zcGFjZXMoc3RyaW5nIHN0cikKK3sKKyAgcmV0dXJuIHJlZ3JlcGxhY2Uoc3RyLCAiICAqIiwgIiAiLCAxKTsKK30KKworc3RhdGljIG1peGVkIF9yZXR1cm5fYXJncyhzdHJpbmcgc3RyKQoreworICBzdHJpbmcgKnQsKnQyLHZlcmIsczI7CisgIGludCBpLGwsaixsMjsKKworICB0PWV4cGxvZGUodHJpbShzdHIsVFJJTV9CT1RIKSwiICIpOworICB2ZXJiPXRbMF07CisgIHQgPSB0WzEuLl07CisgIGlmICghc2l6ZW9mKHQpKQorICB7CisgICAgdW5wYXJzZWRfYXJnc1swXT11bnBhcnNlZF9hcmdzWzFdPXVucGFyc2VkX2FyZ3NbMl09MDsKKyAgICByZXR1cm4gc3RyPXZlcmI7CisgIH0KKyAgZWxzZQorICAgIHN0ciA9IHVucGFyc2VkX2FyZ3NbMF0gPSBpbXBsb2RlKHQsICIgIik7CisKKyAgc3RyPXVucGFyc2VkX2FyZ3NbMV09bG93ZXJfY2FzZShfc2luZ2xlX3NwYWNlcyhzdHIpKTsKKyAgdD1yZWdleHBsb2RlKHN0ciwiXFw8aW1cXD58XFw8aW5zXFw+Iik7CisgIGZvciAoaT0xO2k8c2l6ZW9mKHQpO2krPTIpIHRbaV09ImluIjsKKyAgdD1yZWdleHBsb2RlKGltcGxvZGUodCwiIiksIltcXCxcXCFcXDpdW1xcLFxcIVxcOl0qIik7CisgIGw9c2l6ZW9mKHQpOworICBmb3IoaT0xO2k8bDtpKz0yKSB0W2ldPSIiOworICB0PW9sZF9leHBsb2RlKGltcGxvZGUodCwiIiksIiAiKS0oeyIifSk7CisgIGZvciAoaT1zaXplb2YodCktMjtpPj0wO2ktLSkKKyAgeworICAgIGlmIChtZW1iZXIoQVJUSUtFTCx0W2ldKT49MCkKKyAgICAgIHQ9dFswLi5pLTFdK3RbaSsxLi5dOworICB9CisgIHVucGFyc2VkX2FyZ3NbMl09aW1wbG9kZSh0LCIgIik7CisgIHQ9cmVnZXhwbG9kZSgoc3RyPWltcGxvZGUodCwiICIpKSwiWzAtOV1bMC05XSpcXC4iKTsKKyAgaWYgKChsPXNpemVvZih0KSk+MikKKyAgeworICAgIGk9MTsKKyAgICB3aGlsZSAoaTxsLTEpCisgICAgeworICAgICAgdFtpXT0iICIrdFtpXVswLi48Ml0rIiAiOworICAgICAgaWYgKChsMj1zaXplb2YodDI9b2xkX2V4cGxvZGUodFtpKzFdLCIgIikpKTwyKQorICB0W2krMV0rPXRbaV07CisgICAgICBlbHNlCisgICAgICB7CisgIGZvciAoaj0xO2o8bDI7aisrKQorICB7CisgICAgaWYgKG1lbWJlcihUUkVOTkVSLHQyW2pdKT49MCkKKyAgICB7CisgICAgICB0MltqLTFdKz10W2ldOworICAgICAgbDI9MDsKKyAgICB9CisgIH0KKyAgaWYgKCFsMikKKyAgICB0W2krMV09aW1wbG9kZSh0MiwiICIpOworICBlbHNlCisgICAgdFtpKzFdKz10W2ldOworICAgICAgfQorICAgICAgdFtpXT0iIjsKKyAgICAgIGkrPTI7CisgICAgfQorICAgIHN0cj1fc2luZ2xlX3NwYWNlcyh2ZXJiKyIgIitpbXBsb2RlKHQsIiAiKSk7CisgICAgaWYgKHN0cls8MV09PScgJykgc3RyPXN0clswLi48Ml07CisgIH0gZWxzZSBzdHI9dmVyYisoc3RyPT0iIj8iIjoiICIrc3RyKTsKKyAgaWYgKHNob3dfcHJvY2Vzc2luZz4yKQorICAgIHByaW50ZigiLT4geyVzfVxuIixzdHIpOworICByZXR1cm4gc3RyOworfQorCitzdGF0aWMgdm9pZCBkZWNheV9hdmVyYWdlKCkKK3sKKyAgaWYgKGFic29sdXRlX2hiX2NvdW50KCktbGFzdF9jaGc+MTQpCisgIHsKKyAgICBsYXN0X2NoZz1hYnNvbHV0ZV9oYl9jb3VudCgpLWxhc3RfY2hnOworICAgIGlmIChsYXN0X2NoZz4zMDAwKQorICAgICAgbGFzdF9jaGc9YWJzb2x1dGVfaGJfY291bnQoKSxjbWRzX3Blcl90aW1lPTA7CisgICAgZWxzZQorICAgIHsKKyAgICAgIHdoaWxlIChsYXN0X2NoZz4xNCkKKyAgY21kc19wZXJfdGltZT1jbWRzX3Blcl90aW1lKjkvMTAsIGxhc3RfY2hnLT0xNTsKKyAgICAgIGxhc3RfY2hnPWFic29sdXRlX2hiX2NvdW50KCktbGFzdF9jaGc7CisgICAgfQorICB9Cit9CisKK3ByaXZhdGUgdm9pZCBEZWxheVByZXBhcmVkU3BlbGxzKCkgeworICBtaXhlZCBwczsKKworICBpZiAocG9pbnRlcnAocHM9UXVlcnlQcm9wKFBfUFJFUEFSRURfU1BFTEwpKQorICAgICAgJiYgc2l6ZW9mKHBzKT49MSAmJiBpbnRwKHBzWzBdKSkgeworICAgIHBzWzBdKys7CisgICAgU2V0UHJvcChQX1BSRVBBUkVEX1NQRUxMLHBzKTsKKyAgICB3cml0ZSgiRGllIEF1c2Z1ZWhydW5nIERlaW5lcyB2b3JiZXJlaXRldGVuIFNwcnVjaGVzIHdpcmQgdmVyem9lZ2VydC5cbiIpOworICB9IGVsc2UgaWYgKHBzKSB7CisgICAgU2V0UHJvcChQX1BSRVBBUkVEX1NQRUxMLDApOworICB9Cit9CisKK3N0YXRpYyBtaXhlZCBiYjsKKyNpZm5kZWYgQkJNQVNURVIKKyNkZWZpbmUgQkJNQVNURVIgIi9zZWN1cmUvYmJtYXN0ZXIiCisjZW5kaWYKKworLyoqIEludGVycHJldGllcnQgQWxpYXNlIHVuZCBIaXN0b3J5LUtvbW1hbmRvcworICBFaWdlbnRsaWNoIG11ZXNzdGUgaGllciBub2NoIGRpZSBVbXdhbmRsdW5nIGRlciBTb25kZXJ6ZWljaGVuCisgIHZlcnNjaGllZGVuZXIgWmVpY2hlbnNhZXR6ZSBtaXQgY29udmVydF9jaGFyc2V0IGdlbWFjaHQgd2VyZGVuLAorICBhYmVyIG5vY2ggZ2lidCBlcyBrZWluZSBNb2VnbGljaGtlaXQsIGRlbiB2b20gU3BpZWxlciBnZW51dHp0ZW4KKyAgWmVpY2hlbnNhdHogenUgaWRlbnRpZml6aWVyZW4uCisgIFxwYXJhbVtpbl0gc3RyIHN0cmluZyAtIEtvbW1hbmRvIGRlcyBTcGllbGVycworICBccmV0dXJuIGludGVycHJldGllcnRlcyBBbGlhcyBiencuIGtvcnJla3RlcyBLb21tYW5kbyBhdXMgZGVyIEhpc3RvcnkKKyovCitwcml2YXRlIHN0cmluZyBwYXJzZWNvbW1hbmQoc3RyaW5nIHN0cikKK3sKKyAgaWYgKHN0clswXT09J1xcJykKKyAgeworICAgIC8vIEtvbW1hbmRvIHNvbGwgbmljaHQgaW50ZXJwcmV0aWVydCB3ZXJkZW4KKyAgICByZXR1cm4gc3RyWzEuLl07CisgIH0KKyAgZWxzZSBpZiAoc3RyWzBdPT0nJicpCisgIHsKKyAgICAvLyBLb21tYW5kbyBhdXMgZGVyIEhpc3RvcnkKKyAgICBzdHJpbmcgY21kID0gc3RyWzEuLl07CisgICAgaW50IGNtZF9zaXplID0gc2l6ZW9mKGNtZCk7CisgICAgaW50IGNtZF9mb3VuZCA9IDA7CisgICAgaWYgKGNtZF9zaXplKQorICAgIHsKKyAgICAgIC8vIFRlc3Qgb2IgJjx0ZXh0PiBldHdhcyBmaW5kZXQKKyAgICAgIGZvciAoaW50IGk9MDtpPGhpc3Rfc2l6ZS0xICYmICFjbWRfZm91bmQ7aSsrKQorICAgICAgeworICAgICAgICBpbnQgaWR4ID0gKGhpc3Rfc2l6ZS1pK2hpc3Rfbm93LTEpJWhpc3Rfc2l6ZTsKKyAgICAgICAgaWYgKGhpc3RvcnlbaWR4XVswLi5jbWRfc2l6ZS0xXT09Y21kKQorICAgICAgICB7CisgICAgICAgICAgc3RyID0gaGlzdG9yeVtpZHhdOworICAgICAgICAgIGNtZF9mb3VuZCA9IDE7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGNtZF9mb3VuZCkKKyAgICAgICAgeworICAgICAgICAgIGlmIChzaG93X3Byb2Nlc3NpbmcpCisgICAgICAgICAgICBwcmludGYoIlslc11cbiIsc3RyKTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICBpZiAoIWNtZF9mb3VuZCkKKyAgICB7CisgICAgICAvLyBUZXN0LCBvYiAmPG5yPiBrbGFwcHQKKyAgICAgIGludCBudW1tZXI7CisgICAgICBpZiAoc3RyPT0iJiYiKQorICAgICAgICBzdHIgPSAiJi0wIjsKKyAgICAgIGlmIChzc2NhbmYoc3RyLCImJWQiLG51bW1lcikpCisgICAgICB7CisgICAgICAgIGlmIChudW1tZXI8MCB8fCAoIW51bW1lciAmJiBzdHJbMV09PSctJykpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAobnVtbWVyPC0oaGlzdF9zaXplLTEpKQorICAgICAgICAgICAgbnVtbWVyPS0xOworICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgIG51bW1lcj0oaGlzdF9ub3crbnVtbWVyLTEraGlzdF9zaXplKSVoaXN0X3NpemU7CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgaWYgKG51bW1lcj5oaXN0X25vdyB8fCBoaXN0X25vdy1udW1tZXI+aGlzdF9zaXplKQorICAgICAgICAgICAgbnVtbWVyPS0xOworICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgIG51bW1lcj1udW1tZXIlaGlzdF9zaXplOworICAgICAgICB9CisgICAgICAgIGlmIChudW1tZXI8MCAKKyAgICAgICAgICAgIHx8ICggKGNtZD1oaXN0b3J5W251bW1lcl0pID09IlxuXG4iKSApCisgICAgICAgICAgbm90aWZ5X2ZhaWwoIkRlciBCZWZlaGwgaXN0IG5pY2h0IGluIGRlciBIaXN0b3J5IVxuIik7CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgIHN0ciA9IGNtZDsKKyAgICAgICAgICBpZiAoc2hvd19wcm9jZXNzaW5nKQorICAgICAgICAgICAgcHJpbnRmKCJbJXNdXG4iLHN0cik7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisgIH0KKyAgc3dpdGNoIChzdHIpCisgIHsKKyAgICBjYXNlICJuIjogcmV0dXJuICJub3JkZW4iOworICAgIGNhc2UgInMiOiByZXR1cm4gInN1ZWRlbiI7CisgICAgY2FzZSAidyI6IHJldHVybiAid2VzdGVuIjsKKyAgICBjYXNlICJvIjogcmV0dXJuICJvc3RlbiI7CisgICAgY2FzZSAibnciOiByZXR1cm4gIm5vcmR3ZXN0ZW4iOworICAgIGNhc2UgInN3IjogcmV0dXJuICJzdWVkd2VzdGVuIjsKKyAgICBjYXNlICJzbyI6IHJldHVybiAic3VlZG9zdGVuIjsKKyAgICBjYXNlICJubyI6IHJldHVybiAibm9yZG9zdGVuIjsKKyAgICBjYXNlICJvYiI6IHJldHVybiAib2JlbiI7CisgICAgY2FzZSAidSI6IHJldHVybiAidW50ZW4iOworICB9CisgIC8vIFRlc3QgYXVmIEFsaWFzCisgIHN0cmluZyBvdXRwdXQgPSAiIjsKKyAgc3RyaW5nKiBpbnB1dCA9IGV4cGxvZGUoc3RyLCIgIik7CisgIGludCBpbnB1dF9zaXplID0gc2l6ZW9mKGlucHV0KTsKKyAgbWl4ZWQgYWxpYXMgPSBhbGlhc2VzW2lucHV0WzBdXTsKKyAgaWYgKCFhbGlhcykKKyAgICByZXR1cm4gc3RyOworICBmb3JlYWNoIChtaXhlZCBhOmFsaWFzKQorICB7CisgICAgaWYgKCFpbnRwKGEpKQorICAgICAgb3V0cHV0ICs9IGE7CisgICAgZWxzZQorICAgIHsKKyAgICAgIGlmIChhID49IDApCisgICAgICB7CisgICAgICAgIGlmIChpbnB1dF9zaXplID4gYSkKKyAgICAgICAgICBvdXRwdXQgKz0gaW5wdXRbYV07CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIGEgPSAtYTsKKyAgICAgICAgaWYgKGlucHV0X3NpemUgPiBhKQorICAgICAgICAgIG91dHB1dCArPSBpbXBsb2RlKGlucHV0W2EuLl0sIiAiKTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgb3V0cHV0ID0gX3NpbmdsZV9zcGFjZXMob3V0cHV0KTsKKyAgc3RyID0gdHJpbShvdXRwdXQsVFJJTV9SSUdIVCk7CisgIGlmIChzaG93X3Byb2Nlc3Npbmc+MSkKKyAgICBwcmludGYoIlslc11cbiIsc3RyKTsKKyAgcmV0dXJuIHN0cjsKK30KKworLyoqIEJlaGFuZGVsdCBhbGxlIFNvbmRlcmZhZWxsZSBkZXIgRWluZ2FiZSBkZXMgU3BpZWxlcnMKKyAgQWxsZSBCZWZlaGxlIGRlcyBTcGllbGVycywgZGllIG5pY2h0IGR1cmNoIE9iamVrdGUgYmVoYW5kZWx0CisgIHdlcmRlbiBzb2xsZW4sIHdlcmRlbiBoaWVyIGVya2FubnQgdW5kIGF1c2dlZnVlaHJ0LgorICBEYXp1IGdlaG9lcnQgYXVjaCBkaWUgSW50ZXJwcmV0YXRpb24gdm9uIEFsaWFzZXMgdW5kIEhpc3RvcnktCisgIGJlZmVobGVuLgorICBccGFyYW1baW5dIHN0ciBzdHJpbmc6IEtvbW1hbmRvIGRlcyBTcGllbGVycworICBccmV0dXJuIGF1c3p1ZnVlaHJlbmRlcyBLb21tYW5kbworICAgIG9kZXIgMCBmdWVyIGVpbiBuaWNodCBpbnRlcnByZXRpZXJiYXJlcyBLb21tYW5kbworICAgIG9kZXIgMSBmdWVyIGVpbiBiZXJlaXRzIGR1cmNoZ2VmdWVocnRlcyBLb21tYW5kbworKi8KK21peGVkIG1vZGlmeV9jb21tYW5kKHN0cmluZyBzdHIpCit7CisKKyAgaWYgKGV4dGVybl9jYWxsKCkgJiYgcHJldmlvdXNfb2JqZWN0KCkgJiYKKyAgICAgIChwcmV2aW91c19vYmplY3QoKSE9dGhpc19vYmplY3QoKSB8fCBwcm9jZXNzX2NhbGwoKSkgKQorICB7CisgICAgcmV0dXJuIDA7CisgIH0KKworICAvLyBMZWVyemVpY2hlbiBhbiBkZW4gRW5kZW4gYWJzY2huZWlkZW4uCisgIHN0ciA9IHRyaW0oc3RyLCBUUklNX0JPVEgpOworCisgIGlmIChiYikKKyAgICBCQk1BU1RFUi0+QkJXcml0ZSh0cmltKHN0cixUUklNX1JJR0hULCJcbiIpLCAwKTsKKworICBkZWNheV9hdmVyYWdlKCk7CisgIGNtZHNfcGVyX3RpbWUrPTEwMDAwOworCisgIHVucGFyc2VkX2FyZ3NbMF09dW5wYXJzZWRfYXJnc1sxXT11bnBhcnNlZF9hcmdzWzJdPXVubW9kaWZpZWQ9IiI7IAorCisgIGlmICghc2l6ZW9mKHN0cikpIHJldHVybiAiIjsKKworICAvLyBLb21tYW5kbyB3aXJkIGdlcGFyc3QKKyAgdW5tb2RpZmllZD1wYXJzZWNvbW1hbmQoc3RyKTsKKworICAvLyBFbnZpcm9ubWVudCBzY2hvbm1hbCBtZXJrZW4uCisgIGxhc3RfY29tbWFuZF9lbnY9ZW52aXJvbm1lbnQoKTsKKworICBpZiAodW5tb2RpZmllZCA9PSAiIikKKyAgICAgIHJldHVybiAiIjsKKyAgLy8gS29tbWFuZG8gaW4gSGlzdG9yeSBtZXJrZW4sIGF1Y2ggd2VubiBlcyBpbSBLb21tYW5kb2Jsb2NrIGFiZ2Vicm9jaGVuCisgIC8vIHdpcmQuCisgIEFkZEhpc3RvcnkodW5tb2RpZmllZCk7CisKKyAgLy8gcHJ1ZWZlbiwgb2IgS29tbWFuZG9ibG9jayBnZXNldHp0IGlzdC4KKyAgLy8gKEZ1ZXIgTWFnaWVyIG1pdCBtc2NoYXUgZWluIHdpcmQgZGFzIGlnbm9yaWVydC4pCisgIC8vIEJUVzogRXMgd2lyZCBhYnNpY2h0bGljaCBuaWNodCBkYXMgRXJnZWJuaXMgZGVyIENsb3N1cmUgenVydWVja2dlZ2ViZW4sCisgIC8vIHNvbnN0IHd1ZXJkZSBtYW4gYmVsaWViaWdlbiBPYmpla3RlbiBuaWNodCBudXIgZGFzIEFiYnJlY2hlbiwgc29uZGVybgorICAvLyBhdWNoIGRhcyBBZW5kZXJuIHZvbiBLb21tYW5kb3MgZXJtb2VnbGljaGVuLgorICBpZiAoZGlzYWJsZWNvbW1hbmRzICYmICFJU19MRUFSTklORyhNRSkgKQorICB7CisgICAgaWYgKGRpc2FibGVjb21tYW5kc1tCX1RJTUVdID49IHRpbWUoKQorICAgICAgJiYgb2JqZWN0cChkaXNhYmxlY29tbWFuZHNbQl9PQkpFQ1RdKSkKKyAgICB7CisgICAgICAvLyBkaXNhYmxlY29tbWFuZHMgdmFsaWQKKyAgICAgIC8vIGhhcnQta29kaWVydGUgQXVzbmFtZWxpc3RlIHBydWVmZW4KKyAgICAgIGlmICggbWVtYmVyKCh7Im1ydWZlIiwibXNjaGF1IiwiYnVnIiwiaWRlZSIsInR5cG8iLCJkZXRhaWwifSksCisgICAgICAgICAgICBleHBsb2RlKHN0ciwiICIpWzBdKSA9PSAtMSkKKyAgICAgIHsKKyAgICAgICAgaWYgKGNsb3N1cmVwKGRpc2FibGVjb21tYW5kc1tCX1ZBTFVFXSkpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoZnVuY2FsbChkaXNhYmxlY29tbWFuZHNbQl9WQUxVRV0sX3JldHVybl9hcmdzKHVubW9kaWZpZWQpKSkKKyAgICAgICAgICB7CisgICAgICAgICAgICAvLyBOb24temVybyBDbG9zdXJlLUVyZ2VibmlzLCBBYmJydWNoLiBEaWUgZ2VydWZlbmUgRnVua3Rpb24gaXN0CisgICAgICAgICAgICAvLyBmdWVyIGVpbmUgZ2VlaWduZXRlIE1lbGR1bmcgYW4gZGVuIFNwaWVsZXIgdmVyYW50d29ydGxpY2guCisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLy8gd2VubiBUZXh0LCBkYW5uIGF1Y2ggcHJ1ZWZlbiwgb2IgZGFzIEtvbW1hbmRvdmVyYiBpbiBkZW4gQXVzbmFobWVuCisgICAgICAgIC8vIHN0ZWh0LiAocXVlcnlfdmVyYigpIGdlaHQgbGVpZGVyIGhpZXIgbm9jaCBuaWNodC4pCisgICAgICAgIGVsc2UgaWYgKHN0cmluZ3AoZGlzYWJsZWNvbW1hbmRzW0JfVkFMVUVdKQorICAgICAgICAgICAgICAgICAmJiBtZW1iZXIoZGlzYWJsZWNvbW1hbmRzW0JfRVhDRVBUSU9OU10sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBleHBsb2RlKHN0ciwiICIpWzBdKSA9PSAtMSkKKyAgICAgICAgeworICAgICAgICAgIC8vIG1lbGR1bmcgYXVzZ2ViZW4uLi4KKyAgICAgICAgICB0ZWxsX29iamVjdChQTCwgZGlzYWJsZWNvbW1hbmRzW0JfVkFMVUVdKTsKKyAgICAgICAgICAvLyB1bmQgRW5kZS4uLgorICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgICB9CisgICAgfQorICAgIGVsc2UgZGlzYWJsZWNvbW1hbmRzPTA7CisgIH0KKworICAvLyBWZXJmb2xnZXIgZGlyZWt0IGlucyBFbnYgcmVpbmhvbGVuLgorICBpZiAocmVtb3ZlX2NhbGxfb3V0KCJUYWtlRm9sbG93ZXJzIik+PTApCisgICAgY2F0Y2goVGFrZUZvbGxvd2VycygpO3B1Ymxpc2gpOworCisgIERlbGF5UHJlcGFyZWRTcGVsbHMoKTsKKworICAvLyBIaXN0b3J5ZWludHJhZyBrb3JyaWdpZXJlbgorICBpZiAodW5tb2RpZmllZFswXT09J14nKQorICB7CisgICAgc3RyaW5nICpvbGRuZXcscHJlLHBvc3Q7CisgICAgaWYgKHNpemVvZihvbGRuZXc9ZXhwbG9kZSh1bm1vZGlmaWVkLCJeIikpPjIpCisgICAgeworICAgICAgaW50IGhpc3RfaWR4ID0gKGhpc3Rfbm93LTEpJWhpc3Rfc2l6ZTsKKyAgICAgIHNzY2FuZihoaXN0b3J5W2hpc3RfaWR4XSwiJXMiK29sZG5ld1sxXSsiJXMiLCBwcmUsIHBvc3QpOworICAgICAgdW5tb2RpZmllZCA9IHByZStvbGRuZXdbMl0rcG9zdDsKKyAgICAgIGlmIChzaG93X3Byb2Nlc3NpbmcpCisgICAgICAgIHdyaXRlKCJbIit1bm1vZGlmaWVkKyJdXG4iKTsKKyAgICAgIC8vIGtvcnJpZ2llcnRlcyBLb21tYW5kbyBuYXR1ZXJsaWNoIGF1Y2ggaW4gZGllIEhpc3RvcnkuCisgICAgICBBZGRIaXN0b3J5KHVubW9kaWZpZWQpOworICAgIH0KKyAgfQorCisgIGlmKCBiYiApCisgICAgQkJNQVNURVItPkJCV3JpdGUoIiAtPiAiICsgdW5tb2RpZmllZCwgMSk7CisKKyAgaWYgKHNob3dfcHJvY2Vzc2luZz4xKQorICAgIHByaW50ZigiWyVzXVxuIix1bm1vZGlmaWVkKTsKKworICBtaXhlZCByZXQgPSBfcmV0dXJuX2FyZ3ModW5tb2RpZmllZCk7CisKKyAgLy8gd2VubiBTcGllbGVyIGVpbmdld2lsbGlndCBoYXQgdW5kIGRpZSBTeW50YXhEQiBnZWxhZGVuIGlzdCwgQmVmZWhsCisgIC8vIGRvcnRoaW4gbWVsZGVuLgorICBpZiAoc3ludGF4ZGIpCisgIHsKKyAgICBpZiAoIW9iamVjdHAoc3ludGF4ZGJbMF0pKQorICAgICAgc3ludGF4ZGJbMF0gPSBmaW5kX29iamVjdCgiL3NlY3VyZS9zeW50YXhkYiIpOworICAgIGlmIChzeW50YXhkYlswXSkKKyAgICAgIGNhdGNoKHN5bnRheGRiWzBdLT5zdGFydF9jbWQodW5tb2RpZmllZCk7bm9sb2cpOworICB9CisgIHJldHVybiByZXQ7Cit9CisKK3N0YXRpYyBpbnQgZG9fbGlzdChzdHJpbmcgc3RyKQoreworICBzdHJpbmcgKmNtZGxpc3Q7CisgIGludCBpOworCisgIGlmICghUXVlcnlQcm9wKFBfV0FOVFNfVE9fTEVBUk4pKQorICAgIHJldHVybiAwOworICBjbWRsaXN0PW9sZF9leHBsb2RlKF91bnBhcnNlZF9hcmdzKCl8fCIiLCI7IiktKHsgIiIgfSk7CisgIGZvciAoaT0wO2k8c2l6ZW9mKGNtZGxpc3QpO2krKykKKyAgeworICAgIGNtZGxpc3RbaV09aW1wbG9kZShvbGRfZXhwbG9kZShjbWRsaXN0W2ldLCIgIiktKHt9KSwgIiAiKTsKKyAgICBpZiAoc2hvd19wcm9jZXNzaW5nKQorICAgICAgd3JpdGUoIlsiK2NtZGxpc3RbaV0rIl1cbiIpOworICAgIGNvbW1hbmQoY21kbGlzdFtpXSk7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKKy8vZmFsbHMgZGllIGFsaWFzbGlzdGUga2FwdXR0IGlzdCAuLi4KKworaW50IHVuYWxpYXNfYWxsKCkKK3sKKyAgaWYgKElTX0VMREVSKHRoaXNfaW50ZXJhY3RpdmUoKSkpIGFsaWFzZXM9KFtdKTsKKyAgcmV0dXJuIDE7Cit9CisKK29iamVjdCBfcXVlcnlfbGFzdF9jb21tYW5kX2VudigpCit7CisgIHJldHVybiBsYXN0X2NvbW1hbmRfZW52OworfQorCitpbnQgX3F1ZXJ5X3Nob3dfYWxpYXNfcHJvY2Vzc2luZygpCit7CisgIHJldHVybiBzaG93X3Byb2Nlc3Npbmc7Cit9CisKK2ludCBfcXVlcnlfaGlzdG1pbigpCit7CisgIHJldHVybiBoaXN0bWluOworfQorCit2YXJhcmdzIHZvaWQgQWRkQWN0aW9uKG1peGVkIGZ1biwgbWl4ZWQgY21kLCBpbnQgZmxhZywgaW50IGx2bCkKK3sKKyAgaW50IGk7CisgIG1peGVkICpjbWRzOworCisgIGxvZ19maWxlKCAiQVJDSC9BRERfQUNUSU9OIiwgc3ByaW50ZigKKwkiJXM6XG4gIFRPOiAlTyBUUDogJU8gUE86ICVPXG4gICBmdW46ICVPIGNtZDogJU8gZmxhZzogJU8gbHZsOiAlTyIsCisgICAgICAgIGR0aW1lKHRpbWUoKSksIHRoaXNfb2JqZWN0KCksIHRoaXNfcGxheWVyKCksIHByZXZpb3VzX29iamVjdCgpLAorCWZ1biwgY21kLCBmbGFnLCBsdmwpKTsKKworICBpZiAoIShjbWRzPVF1ZXJ5KFBfTE9DQUxDTURTKSkpIGNtZHM9KHt9KTsKKworICBpZiAoIXBvaW50ZXJwKGNtZCkpIGNtZD0oe2NtZH0pOworCisgIGZvciAoaSA9IHNpemVvZihjbWQpLTE7IGk+PTA7IGktLSkKKyAgICBjbWRzICs9ICh7KHsgY21kW2ldICwgZnVuLCBmbGFnLCBsdmx9KX0pOworCisgIFNldChQX0xPQ0FMQ01EUywgY21kcyk7Cit9CisKK3N0YXRpYyBpbnQgYXVzd2VydGVuKG1peGVkIGNtZCwgc3RyaW5nIHN0cikKK3sKKyAgaWYgKGNsb3N1cmVwKGNtZCkpCisgICAgcmV0dXJuIGZ1bmNhbGwoY21kLHN0cik7CisgIGlmIChzdHJpbmdwKGNtZCkpCisgICAgcmV0dXJuIGNhbGxfb3RoZXIodGhpc19vYmplY3QoKSxjbWQsc3RyKTsKKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2YXJhcmdzIGludCBfX2F1c3dlcnRlbihzdHJpbmcgc3RyLCBzdHJpbmcgaW50ZXJuKQoreworICBzdHJpbmcgdmVyYjsKKyAgbWl4ZWQgKmNtZCwgY21kczsKKyAgaW50IGkscmV0LGx2bCxsLHZsOworCisgIGlmICghaW50ZXJuKQorICAgIHZlcmI9cXVlcnlfdmVyYigpOworICBlbHNlCisgICAgdmVyYj1pbnRlcm47CisgIGx2bD1xdWVyeV93aXpfbGV2ZWwoTUUpOworICB2bD1zaXplb2YodmVyYik7CisgIGNtZHM9UXVlcnlQcm9wKFBfTE9DQUxDTURTKTsKKworICBmb3IoaT1zaXplb2YoY21kcyktMTtpPj0wO2ktLSkKKyAgeworICAgIGNtZD1jbWRzW2ldLGw9c2l6ZW9mKGNtZFswXSk7CisgICAgaWYgKGNtZFswXT09dmVyYlswLi5sLTFdICYmIGNtZFszXTw9bHZsICYmIChjbWRbMl18fHZsPT1sKSAmJgorICAocmV0PWF1c3dlcnRlbihjbWRbMV0sc3RyKSkpCisgICAgICByZXR1cm4gcmV0OworICB9CisgIC8vIEFuIGRpZXNlciBTdGVsbGUgZ2lidCBlcyBoaWVyIHVuZCB2ZXJtdXRsaWNoIG5pcmdlbmR3byBhbmRlcnMgZXR3YXMsIHdhcworICAvLyBkaWVzZXMgS29tbWFuZG8gYWxzIGd1ZWx0aWcgYmV0cmFjaHRldC4gV2lyIGluZm9ybWllcmVuIGdnZi4gZGllCisgIC8vIFN5bnRheC1EQi4gKEFjaHR1bmc6IHdlbm4gamVtYW5kIG5lIGFkZF9hY3Rpb24oKSBpbSBTcGllbGVyb2JqZWt0CisgIC8vIGVpbmJhdXQsIGRpZSB2b3IgZGllc2VyIGVpbmdldHJhZ2VuIHdpcmQsIGlzdCBkaWUgQW5uYWhtZSBnZ2YuIGZhbHNjaC4pCisgIC8vIHdlbm4gU3BpZWxlciBlaW5nZXdpbGxpZ3QgaGF0IHVuZCBkaWUgU3ludGF4REIgZ2VsYWRlbiBpc3QsIEJlZmVobAorICAvLyBkb3J0aGluIG1lbGRlbi4KKyAgaWYgKHN5bnRheGRiKQorICB7CisgICAgaWYgKCFvYmplY3RwKHN5bnRheGRiWzBdKSkKKyAgICAgIHN5bnRheGRiWzBdID0gZmluZF9vYmplY3QoIi9zZWN1cmUvc3ludGF4ZGIiKTsKKyAgICBpZiAoc3ludGF4ZGJbMF0pCisgICAgICBjYXRjaChzeW50YXhkYlswXS0+Y21kX3Vuc3VjY2Vzc2Z1bCgpO25vbG9nKTsKKyAgfQorCisgIHJldHVybiAwOworfQorCitwdWJsaWMgdm9pZCBzeW50YXhfbG9nX2VwKGludCB0eXBlKQoreworICAvLyB3ZW5uIFNwaWVsZXIgZWluZ2V3aWxsaWd0IGhhdCB1bmQgZGllIFN5bnRheERCIGdlbGFkZW4gaXN0LCBCZWZlaGwKKyAgLy8gZG9ydGhpbiBtZWxkZW4uCisgIGlmIChzeW50YXhkYiAmJiBzeW50YXhkYlswXSkKKyAgeworICAgICAgY2F0Y2goc3ludGF4ZGJbMF0tPkxvZ0VQKHR5cGUpO25vbG9nKTsKKyAgfQorfQorCitzdGF0aWMgbWl4ZWQgX3F1ZXJ5X2xvY2FsY21kcygpCit7CisgIG1peGVkICpsOworCisgIGw9UXVlcnkoUF9MT0NBTENNRFMpOworICBpZiAoIXBvaW50ZXJwKGwpKQorICAgIGw9KHt9KTsKKyAgcmV0dXJuICh7CisgICAgKHsiYWxpIiwiYWxpYXMiLDAsMH0pLAorICAgICh7ImFsaWFzIiwiYWxpYXMiLDAsMH0pLAorICAgICh7InVuYWxpIiwidW5hbGlhcyIsMSwwfSksCisgICAgKHsiaGlzdG1pbiIsImhpc3RtaW4iLDAsMH0pLAorICAgICh7Imhpc3RsZW4iLCJoaXN0bGVuIiwwLDB9KSwKKyAgICAoeyJoaXN0Iiwic2hvd19oaXN0IiwwLDB9KSwKKyAgICAoeyJoaXN0b3J5Iiwic2hvd19oaXN0IiwwLDB9KSwKKyAgICAoeyJkbyIsImRvX2xpc3QiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAoeyJlcnNldHp1bmdzYW56ZWlnZSIsInJlcGxhY2VkaXNwbGF5IiwwLDB9KSwKKyAgICAoeyJzeW50YXhzYW1tbHVuZyIsImNvbGxlY3RfY21kcyIsMCwwfSksCisgICAgKHsiZmVobGVybWVsZHVuZyIsInNldF9lcnJvcm1lc3NhZ2UiLDAsU0VFUl9MVkx9KSwKKyAgfSkrbDsKK30KKworc3RhdGljIGludCBjb2xsZWN0X2NtZHMoc3RyaW5nIGNtZCkKK3sKKyAgaWYgKCFzdHJpbmdwKGNtZCkpCisgIHsKKyAgICBfbm90aWZ5KCJNaXQgZGllc2VtIEJlZmVobCBrYW5uc3QgRHUgbWl0aGVsZmVuLCBTeW50YXhlbiBpbSBNRyB6dSAiCisgICAgICAgICAgICAidmVyYmVzc2Vybi4gV2VubiBEdSBlaW52ZXJzdGFuZGVuIGJpc3QsIHNwZWljaGVybiB3aXIgIgorICAgICAgICAgICAgImFub255bSAoZC5oLiBvaG5lIERlaW5lbiBDaGFybmFtZW4pLCB3ZWxjaGUgRGVpbmVyIEJlZmVobGUgIgorICAgICAgICAgICAgImVyZm9sZ3JlaWNoIHVuZCBuaWNodCBlcmZvbGdyZWljaCB3YXJlbi4gVWVibGljaGUgIgorICAgICAgICAgICAgIktvbW11bmlrYXRpb25zYmVmZWhsZSB3ZXJkZW4gZGFiZWkgbmljaHQgZ2VzcGVpY2hlcnQuIiwKKyAgICAgICAgICAgIDApOworICAgIF9ub3RpZnkoIk1pdCAnc3ludGF4c2FtbWx1bmcgamEnIGthbm5zdCBEdSBkaWUgU3BlaWNoZXJ1bmcgZWluc2NoYWx0ZW4sICIKKyAgICAgICAgICAgICJtaXQgJ3N5bnRheHNhbW1sdW5nIG5laW4nIGthbm5zdCBEdSBzaWUgYXVzc2NoYWx0ZW4uIiwwKTsKKyAgICBfbm90aWZ5KCJEZWluZSBCZWZlaGxlIHdlcmRlbiB6dXIgWmVpdCIKKyAgICAgICAgICAgICsgKFF1ZXJ5UHJvcCgiX3N5bnRheGRiIikgPyAiICIgOiAiIE5JQ0hUICIpCisgICAgICAgICAgICArICJnZXNwZWljaGVydC4iLCAwKTsKKyAgfQorICBlbHNlIGlmIChjbWQgPT0gImphIikKKyAgeworICAgIFNldFByb3AoIl9zeW50YXhkYiIsIDEpOworICAgIF9ub3RpZnkoIkFiIGpldHp0IHdlcmRlbiBEZWluZSBCZWZlaGxlIGdlc3BlaWNoZXJ0LiBWaWVsZW4gRGFuayEiLCAwKTsKKyAgfQorICBlbHNlCisgIHsKKyAgICBTZXRQcm9wKCJfc3ludGF4ZGIiLCAwKTsKKyAgICBfbm90aWZ5KCJBYiBqZXR6dCB3ZXJkZW4gRGVpbmUgQmVmZWhsZSBOSUNIVCBnZXNwZWljaGVydC4iLCAwKTsKKyAgfQorICByZXR1cm4gMTsKK30KKworaW50IF9xdWVyeV9jb21tYW5kX2F2ZXJhZ2UoKQoreworICBkZWNheV9hdmVyYWdlKCk7CisgIHJldHVybiBjbWRzX3Blcl90aW1lOworfQorCitub21hc2sgdm9pZCBfX3NldF9iYihpbnQgZmxhZykgIHsKKyAgaWYoIHByZXZpb3VzX29iamVjdCgpIT1maW5kX29iamVjdChCQk1BU1RFUikgfHwgcHJvY2Vzc19jYWxsKCkgKQorICAgIHJldHVybjsKKyAgYmI9ZmxhZzsKK30KKworCitub21hc2sgcHVibGljIHZvaWQgY291bnRDbWRzKCBpbnQgdHlwZSwgc3RyaW5nIGtleSApCit7CisgICAgc3RyaW5nIHRtcDsKKworICAgIGlmICggdGhpc19wbGF5ZXIoKSAhPSB0aGlzX2ludGVyYWN0aXZlKCkKKyAgICAgICAgIHx8IHRoaXNfaW50ZXJhY3RpdmUoKSAhPSB0aGlzX29iamVjdCgpCisgICAgICAgICB8fCBtZW1iZXIoIGNtZF90eXBlcywgdHlwZSApIDwgMCApCisgICAgICAgIHJldHVybjsKKworICAgIHRtcCA9IHNwcmludGYoICIlZFxuJXMiLCB0eXBlLCBrZXkgKTsKKworICAgIGNvbW1hbmRzIC09ICh7IHRtcCB9KTsKKyAgICBjb21tYW5kcyArPSAoeyB0bXAgfSk7CisgICAgY29tbWFuZHMgPSBjb21tYW5kc1swLi5tYXhfY29tbWFuZHMtMV07Cit9CisKKworbm9tYXNrIHB1YmxpYyBzdHJpbmcgKmdldENtZHMoKQoreworICAgIHN0cmluZyAqdG1wOworCisgICAgaWYgKCBwcmV2aW91c19vYmplY3QoKSAhPSBmaW5kX29iamVjdChCQk1BU1RFUikgKQorICAgICAgICByZXR1cm4gKHt9KTsKKworICAgIHRtcCA9IGNvbW1hbmRzOworICAgIGNvbW1hbmRzID0gKHt9KTsKKworICAgIHJldHVybiB0bXA7Cit9CisKKy8qCisgKiBGb3JjZSB0aGUgbW9uc3RlciB0byBkbyBhIGNvbW1hbmQuIFRoZSBmb3JjZV91cygpIGZ1bmN0aW9uIGlzbid0CisgKiBhbHdheXMgZ29vZCwgYmVjYXVzZSBpdCBjaGVja3MgdGhlIGxldmVsIG9mIHRoZSBjYWxsZXIsIGFuZCB0aGlzIGZ1bmN0aW9uCisgKiBjYW4gYmUgY2FsbGVkIGJ5IGEgcm9vbS4KKyAqLworaW50IGNvbW1hbmRfbWUoc3RyaW5nIGNtZCkKK3sKKyAgaWYgKElTX0xFQVJORVIoTUUpKQorICB7CisgICAgaWYgKCF0aGlzX2ludGVyYWN0aXZlKCkgfHwgIXByZXZpb3VzX29iamVjdCgpKQorICAgICAgcmV0dXJuIDA7CisgICAgaWYoIGdldGV1aWQoTUUpIT1nZXRldWlkKHRoaXNfaW50ZXJhY3RpdmUoKSkKKyAgICAgICAgfHwgZ2V0ZXVpZChNRSkhPWdldGV1aWQocHJldmlvdXNfb2JqZWN0KCkpICkKKyAgICB7CisgICAgICBpZiggcXVlcnlfd2l6X2xldmVsKE1FKTxxdWVyeV93aXpfbGV2ZWwocHJldmlvdXNfb2JqZWN0KCkpKQorICAgICAgICB0ZWxsX29iamVjdChNRSxwcmV2aW91c19vYmplY3QoKS0+bmFtZSgpKyIgendpbmd0IERpY2ggenU6ICIKKyAgICAgICAgICAgICAgICAgICAgKyBjbWQgKyAiLlxuIik7CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIHRlbGxfb2JqZWN0KE1FLHByZXZpb3VzX29iamVjdCgpLT5uYW1lKCkKKyAgICAgICAgICAgICAgICAgICAgKyAiIHZlcnN1Y2h0LCBEaWNoIHp1ICIgKyBjbWQgKyAiIHp1IHp3aW5nZW4uXG4iICk7CisgICAgICAgIHJldHVybiAwOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gY29tbWFuZChjbWQpOworfQorCisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfcF9saWJfZGlzYWJsZWNvbW1hbmRzKCkgeworICAgIC8vIGFiZ2VsYXVmZW4gb2RlciBPYmpla3QgemVyc3RvZXJ0PyBXZWcgZGFtaXQuCisgICAgaWYgKHBvaW50ZXJwKGRpc2FibGVjb21tYW5kcykKKyAgICAgICAgJiYgKGRpc2FibGVjb21tYW5kc1tCX1RJTUVdIDwgdGltZSgpCisgICAgICAgICAgfHwgIW9iamVjdHAoZGlzYWJsZWNvbW1hbmRzW0JfT0JKRUNUXSkpICkKKyAgICAgICAgcmV0dXJuKGRpc2FibGVjb21tYW5kcyA9IDApOworCisgICAgLy8gc29uc3QgS29waWUgenVydWVjayAoY29weSgwKSBnZWh0KQorICAgIHJldHVybihjb3B5KGRpc2FibGVjb21tYW5kcykpOworfQorCitzdGF0aWMgbWl4ZWQgX3NldF9wX2xpYl9kaXNhYmxlY29tbWFuZHMobWl4ZWQgZGF0YSkgeworCisgIC8vIHNldHplbmRlcyBPYmpla3QgZXJtaXR0ZWxuLCBkYSBkaWVzZSBGdW5rdGlvbiBudXIgcGVyIFNldFByb3AoKSBnZXJ1ZmVuCisgIC8vIHdlcmRlbiBzb2xsdGUgKCEpLCBpc3QgZGFzIFBPKDEpOworICBvYmplY3Qgb3JpZ2luID0gcHJldmlvdXNfb2JqZWN0KDEpOworICAvLyB3ZW5uIG5pY2h0IGV4aXN0ZW50LCBkaXJla3QgYWJicnVjaAorICBpZiAoIW9iamVjdHAob3JpZ2luKSkKKyAgICByZXR1cm4gX3F1ZXJ5X3BfbGliX2Rpc2FibGVjb21tYW5kcygpOworCisgIC8vIFByb3AgbG9lc2NoZW4/IEV4cGxpeml0IGxvZXNjaGVuIGRhcmYgamVkZXIsIGFsbGVyZGluZ3MgbmljaHQgZGlyZWt0CisgIC8vIHVuZ2VwcnVlZnQgdWViZXJzY2hyZWliZW4uCisgIGlmICghZGF0YSkgeworICAgICAgcmV0dXJuIChkaXNhYmxlY29tbWFuZHMgPSAwICk7CisgIH0KKyAgLy8gbWFsIGRpcmVrdCBidWdnZW4gYmVpIGZhbHNjaGVuIERhdGVudHlwLCBkYW1pdHMgYXVmZmFlbGx0LgorICBpZiAoIXBvaW50ZXJwKGRhdGEpIHx8IHNpemVvZihkYXRhKSA8IDIgfHwgIWludHAoZGF0YVswXSkKKyAgICAgIHx8ICghc3RyaW5ncChkYXRhWzFdKSAmJiAhY2xvc3VyZXAoZGF0YVsxXSkpCisgICAgICB8fCAoc2l6ZW9mKGRhdGEpID49IDMgJiYgIXBvaW50ZXJwKGRhdGFbMl0pKSApCisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAgIldyb25nIGRhdGEgdHlwZSBmb3IgUF9ESVNBQkxFX0NPTU1BTkRTLiBFeHBlY3RlZCBBcnJheSB3aXRoICIKKyAgICAgICAgICAgICIyIG9yIDMgZWxlbWVudHMgKGludCwgc3RyaW5nfGNsb3N1cmUsIFtzdHJpbmcqXSksIGdvdCAlLjI1T1xuIiwKKyAgICAgICAgICAgIGRhdGEpKTsKKworICAvLyBXZW5uIGFiZ2VsYXVmZW4gb2RlciBnbGVpY2hlcyBPYmpla3Qgd2llIGxldHp0ZXMgTWFsOiBlaW50cmFnZW4uCisgIGlmICghZGlzYWJsZWNvbW1hbmRzIHx8IChkaXNhYmxlY29tbWFuZHNbQl9USU1FXSA8IHRpbWUoKQorICAgICAgICB8fCAhb2JqZWN0cChkaXNhYmxlY29tbWFuZHNbQl9PQkpFQ1RdKSAKKyAgICAgICAgfHwgZGlzYWJsZWNvbW1hbmRzW0JfT0JKRUNUXSA9PSBvcmlnaW4pICkgeworICAgICAgLy8gTG9nZ2VuIG51ciwgd2VubiBlaW5lIENsb3N1cmUgZWluZ2V0cmFnZW4gd2lyZC4gUmVkdXppZXJ0IGRlbgorICAgICAgLy8gTG9nc2Nyb2xsIHVuZCBTdHJpbmdzIGhhYmVuIGRldXRsaWNoIHdlbmlnZXIgTWlzc2JyYXVjaHNwb3RlbnRpYWwuCisgICAgICBpZiAoY2xvc3VyZXAoZGF0YVsxXSkpIHsKKyAgICAgICAgQ0JMT0coc3ByaW50ZigiWyVzXSBDQiBnZXNldHp0IHZvbiAlTywgZ3VlbHRpZyBiaXMgJXMsIERhdGVuOiAlT1xuIiwKKyAgICAgICAgc3RyZnRpbWUoIiVZJW0lZC0lSDolTTolUyIpLG9yaWdpbiwKKyAgICAgICAgc3RyZnRpbWUoIiVZJW0lZC0lSDolTTolUyIsZGF0YVswXSksCisgICAgICAgIChzdHJpbmdwKGRhdGFbMV0pID8gcmVncmVwbGFjZShkYXRhWzFdLCJcbiIsIlxcbiIsMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgOiBkYXRhWzFdKSkpOworICAgICAgfQorICAgICAgaWYgKHNpemVvZihkYXRhKSsxIDw9IEJfRVhDRVBUSU9OUykKKyAgICAgICAgZGlzYWJsZWNvbW1hbmRzID0gKHsgb3JpZ2luLCBkYXRhWzBdLCBkYXRhWzFdLCAoe30pIH0pOworICAgICAgZWxzZQorICAgICAgICBkaXNhYmxlY29tbWFuZHMgPSAoeyBvcmlnaW4sIGRhdGFbMF0sIGRhdGFbMV0sIGRhdGFbMl0gfSk7CisgICAgICByZXR1cm4oY29weShkaXNhYmxlY29tbWFuZHMpKTsKKyAgfQorCisgIHJldHVybihfcXVlcnlfcF9saWJfZGlzYWJsZWNvbW1hbmRzKCkpOworfQorCitzdGF0aWMgbWl4ZWQgX3NldF9fc3ludGF4ZGIobWl4ZWQgdikKK3sKKyAgU2V0KCJfc3ludGF4ZGIiLCB2LCBGX1ZBTFVFKTsKKyAgaWYgKHYpCisgICAgICBzeW50YXhkYiA9ICh7ZmluZF9vYmplY3QoIi9zZWN1cmUvc3ludGF4ZGIiKX0pOworICBlbHNlCisgICAgICBzeW50YXhkYiA9IDA7CisgIHJldHVybiBRdWVyeVByb3AoIl9zeW50YXhkYiIpOworfQorCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL2Rlc2NyaXB0aW9uLmMgYi9zdGQvcGxheWVyL2Rlc2NyaXB0aW9uLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGEwNjYzZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvZGVzY3JpcHRpb24uYwpAQCAtMCwwICsxLDI5MiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHBsYXllci9kZXNjcmlwdGlvbi5jIC0tIHBsYXllciBkZXNjcmlwdGlvbiBoYW5kbGluZworLy8KKy8vICRJZDogZGVzY3JpcHRpb24uYyA4NzU1IDIwMTQtMDQtMjYgMTM6MTM6NDBaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL2xpdmluZy9kZXNjcmlwdGlvbiI7CisKKyNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgorI2luY2x1ZGUgPHBsYXllci9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPGxpdmluZy9jbG90aGluZy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8c3lzX2RlYnVnLmg+CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8cGxheWVyL2NvbW1hbmQuaD4KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgOjpjcmVhdGUoKTsKKyAgU2V0KFBfTkFNRSwgTk9TRVRNRVRIT0QsIEZfU0VUX01FVEhPRCk7CisgIFNldChQX1BSRVNBWSwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfVElUTEUsIFNBVkUsIEZfTU9ERV9BUyk7CisgIFNldChQX0VYVFJBX0xPT0ssIFNBVkUsIEZfTU9ERV9BUyk7CisgIFNldChQX0dFTkRFUiwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfU0laRSwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgU2V0KFBfSU5GTywgTk9TRVRNRVRIT0QsIEZfU0VUX01FVEhPRCk7CisgIC8vIEF2YXRhci1VUklzIHNwZWljaGVybi4gQXVzc2VyZGVtIGhhdCBhbiBkZW5lbiBrZWluZXIgcnVtenVmdW1tZWxuLgorICBTZXQoUF9BVkFUQVJfVVJJLCBTQVZFfFNFQ1VSRUQsIEZfTU9ERV9BUyk7Cit9CisKK3N0cmluZyBfcXVlcnlfaW5mbygpCit7CisgIHN0cmluZyBpbmZvOworICBpbmZvID0gUXVlcnkoUF9JTkZPKTsKKyAgaWYoIWluZm8paW5mbz09IiI7CisgIGluZm8gPSAoc3RyaW5nKXF1ZXJ5X3dpel9sZXZlbCh0aGlzX29iamVjdCgpKTsKKyAgaWYoSVNfR09EKHRoaXNfb2JqZWN0KCkpKQorICAgIHJldHVybiBpbmZvKyIgW0dvdHRdXG4iOworICBpZihJU19BUkNIKHRoaXNfb2JqZWN0KCkpKQorICAgIHJldHVybiBpbmZvKyIgW0Vyem1hZ2llcl1cbiI7CisgIGlmKElTX0VMREVSKHRoaXNfb2JqZWN0KCkpKQorICAgIHJldHVybiBpbmZvKyIgW1dlaXNlcl1cbiI7CisgIGlmKElTX0xPUkQodGhpc19vYmplY3QoKSkpCisgICAgcmV0dXJuIGluZm8rIiBbUmVnaW9uc2NoZWZdXG4iOworICBpZihJU19TUEVDSUFMKHRoaXNfb2JqZWN0KCkpKQorICAgIHJldHVybiBpbmZvKyIgW1NwZWNpYWxdXG4iOworICBpZihJU19ET01BSU5NRU1CRVIodGhpc19vYmplY3QoKSkpCisgICAgcmV0dXJuIGluZm8rIiBbUmVnaW9uc21pdGFyYmVpdGVyXVxuIjsKKyAgaWYoSVNfV0laQVJEKHRoaXNfb2JqZWN0KCkpKQorICAgIHJldHVybiBpbmZvKyIgW01hZ2llcl1cbiI7CisgIGlmKElTX0xFQVJORVIodGhpc19vYmplY3QoKSkpCisgICAgcmV0dXJuIGluZm8rIiBbTWFnaWVyYW53YWVydGVyXVxuIjsKKyAgaW5mbyA9IFF1ZXJ5UHJvcChQX0xFVkVMKTsKKyAgaWYoSVNfU0VFUih0aGlzX29iamVjdCgpKSkKKyAgICByZXR1cm4gaW5mbysiIFtTZWhlcl1cbiI7CisgIHJldHVybiBpbmZvKyIgW1NwaWVsZXJdXG4iOworfQorCitpbnQgX3F1ZXJ5X3NpemUoKSB7CisgIGlmIChRdWVyeVByb3AoUF9GUk9HKSkKKyAgICByZXR1cm4gMjA7CisgIHJldHVybiBRdWVyeShQX1NJWkUpOworfQorCisvLyBzaG9ydCgpIC0tIGdldCB0aGUgc2hvcnQgZGVzY3JpcHRpb24gb2YgYSBwbGF5ZXIKK3N0cmluZyBzaG9ydCgpCit7CisgIHN0cmluZyBhbnN3ZXI7CisgIHN0cmluZyB0aXRsZTsKKworICBpZihRdWVyeVByb3AoUF9JTlZJUykpCisgICAgaWYoaW50ZXJhY3RpdmUocHJldmlvdXNfb2JqZWN0KCkpICYmIElTX0xFQVJOSU5HKHByZXZpb3VzX29iamVjdCgpKSkKKyAgICAgIHJldHVybiAiKCIrUXVlcnlQcm9wKFBfTkFNRSkrIikgXG4iOworICAgIGVsc2UKKyAgICAgIHJldHVybiAwOworCisgIGlmKFF1ZXJ5UHJvcChQX0dIT1NUKSkKKyAgeworICAgIGlmIChRdWVyeVByb3AoUF9GUk9HKSkKKyAgICAgIHJldHVybiAiRGVyIEdlaXN0IGVpbmVzIGtsZWluZW4gRnJvc2NoZXMgbmFtZW5zICIrUXVlcnlQcm9wKFBfTkFNRSkrCisgICAgICAgIi5cbiI7CisgICAgZWxzZQorICAgICAgcmV0dXJuICJEZXIgR2Vpc3Qgdm9uICIrUXVlcnlQcm9wKFBfTkFNRSkrIi5cbiI7CisgIH0KKworICBpZiAoUXVlcnlQcm9wKFBfRlJPRykpCisgICAgcmV0dXJuICJFaW4ga2xlaW5lciBGcm9zY2ggbmFtZW5zICIrUXVlcnlQcm9wKFBfTkFNRSkrIi5cbiI7CisKKyAgYW5zd2VyID0gUXVlcnlQcm9wKFBfUFJFU0FZKSArIFF1ZXJ5UHJvcChQX05BTUUpOworICBpZiAoUXVlcnlQcm9wKFBfQVJUSUNMRSkpIGFuc3dlcj1RdWVyeUFydGljbGUoMCwwKSthbnN3ZXI7CisgIGlmKCh0aXRsZT1RdWVyeVByb3AoUF9USVRMRSkpICYmIHRpdGxlICE9ICIiKSBhbnN3ZXIgKz0gIiAiICsgdGl0bGU7CisgIGlmKCFpbnRlcmFjdGl2ZShNRSkpIGFuc3dlciArPSAiIChuZXR6dG90KSI7CisgIHJldHVybiBhbnN3ZXIrIi5cbiI7Cit9CisKK3ByaXZhdGUgc3RyaW5nIGFuZGxpc3Qob2JqZWN0ICphcnIpIHsKKyAgc3RyaW5nICp0bXA7CisgIGlmKCFwb2ludGVycChhcnIpKSByZXR1cm4gIiI7CisgIGlmKHNpemVvZih0bXAgPSBtYXBfb2JqZWN0cyhhcnIsICJuYW1lIiwgV0VOKSkpCisgICAgcmV0dXJuKENvdW50VXAodG1wKSk7CisgIHJldHVybiAiIjsKK30KKworLy8gZ2lidCBmdWVyIG5pY2h0LUludmlzLU9iamVrdGUgZGVuIE5hbWVuIHp1cnVlY2sKK3ByaXZhdGUgc3RyaW5nIGdldF92aXNfbmFtZShvYmplY3Qgb2IpIHsKKyAgaWYgKG9iLT5RdWVyeVByb3AoUF9JTlZJUykpCisgICAgcmV0dXJuIDA7CisgIHJldHVybiAob2ItPm5hbWUoV0VOKSk7Cit9CisKK3ZhcmFyZ3Mgc3RyaW5nIGxvbmcoKQoreworICBzdHJpbmcgZXhsLCBkZXNjciwgdG1wLCBzaXplX2Rlc2NyOworICBvYmplY3Qgb2I7CisgIG1peGVkIHRyYW5zLCB3LCBhLCByOworICBpbnQgcGVyOworICBzdHJpbmcgZmlsbCwgZmlsbDI7CisgIC8qIGZ1ZXIgZ3JvZXNzZW52ZXJnbGVpY2ggKi8KKyAgc3RyaW5nIGNvbXBhcmVzaXplLCBwZXJzMSwgcGVyczI7CisgIGludCByZWxhdGlvbjsKKworICBwZXI9MTAwMCpRdWVyeVByb3AoUF9TSVpFKS9RdWVyeVByb3AoUF9BVkVSQUdFX1NJWkUpOworICBzd2l0Y2gocGVyKQorICB7CisgICAgY2FzZSAwLi44MDA6IHNpemVfZGVzY3I9InppZW1saWNoIHdpbnppZyI7IGJyZWFrOworICAgIGNhc2UgODAxLi44NTA6IHNpemVfZGVzY3I9ImVoZXIgd2luemlnIjsgYnJlYWs7CisgICAgY2FzZSA4NTEuLjkwMDogc2l6ZV9kZXNjcj0icmVjaHQga2xlaW4iOyBicmVhazsKKyAgICBjYXNlIDkwMS4uOTUwOiBzaXplX2Rlc2NyPSJlaGVyIGtsZWluIjsgYnJlYWs7CisgICAgY2FzZSA5NTEuLjEwNTA6IHNpemVfZGVzY3I9Im1pdHRlbGdyb3NzIjsgYnJlYWs7CisgICAgY2FzZSAxMDUxLi4xMTAwOiBzaXplX2Rlc2NyPSJyZWxhdGl2IGdyb3NzIjsgYnJlYWs7CisgICAgY2FzZSAxMTAxLi4xMTUwOiBzaXplX2Rlc2NyPSJ6aWVtbGljaCBncm9zcyI7IGJyZWFrOworICAgIGNhc2UgMTE1MS4uMTIwMDogc2l6ZV9kZXNjcj0ic2VociBncm9zcyI7IGJyZWFrOworICAgIGRlZmF1bHQ6IHNpemVfZGVzY3I9InJpZXNpZyI7IGJyZWFrOworICB9CisjZGVmaW5lIFJhc3NlblN0cmluZygpICgoUXVlcnlQcm9wKFBfRlJPRykgPyAiZW4gRnJvc2NoIiA6XAorICAgICAgICghUXVlcnlQcm9wKFBfR0VOREVSKT8iICI6UXVlcnlQcm9wKFBfR0VOREVSKT09Mj8iZSAiOiJlbiAiKStcCisgICAgICAgKHBvaW50ZXJwKFF1ZXJ5UHJvcChQX1JBQ0VTVFJJTkcpKT9cCisgICAgICAgIFF1ZXJ5UHJvcChQX1JBQ0VTVFJJTkcpW1dFTl06UXVlcnlQcm9wKFBfUkFDRSkpKSkKKyAgZmlsbDI9ZmlsbD0wOworICBpZiAoUXVlcnlQcm9wKFBfQVZFUkFHRV9TSVpFKTwxNzApCisgIHsKKyAgICBpZiAocGVyPDk1MCkKKyAgICAgIGZpbGw9InNlbGJzdCBmdWVyIGVpbiIrUmFzc2VuU3RyaW5nKCkrIiAiOworICAgIGVsc2UKKyAgICAgIGlmIChwZXI+MTA1MCkKKyAgZmlsbDI9Iiwgd2VubiBhdWNoIG51ciBmdWVyIGVpbiIrUmFzc2VuU3RyaW5nKCk7CisgIH0KKyAgZWxzZQorICB7CisgICAgaWYgKFF1ZXJ5UHJvcChQX0FWRVJBR0VfU0laRSk+MTcwKQorICAgICAgaWYgKHBlcj4xMDUwKQorICBmaWxsPSJzb2dhciBmdWVyIGVpbiIrUmFzc2VuU3RyaW5nKCkrIiAiOworICAgICAgZWxzZQorICBpZiAocGVyPDk1MCkKKyAgICBmaWxsMj0iLCB3ZW5uIGF1Y2ggbnVyIGZ1ZXIgZWluIitSYXNzZW5TdHJpbmcoKTsKKyAgfQorICBpZiAoIWZpbGwmJiFmaWxsMikgZmlsbD0iZnVlciBlaW4iK1Jhc3NlblN0cmluZygpKyIgIjsKKyAgZGVzY3IgPSAiRGFzIGlzdCAiK25hbWUoV0VSLDEpKyIuICIrY2FwaXRhbGl6ZShRdWVyeVByb25vdW4oKSkrIiBpc3QgIisKKyAgICAoZmlsbHx8IiIpK3NpemVfZGVzY3IrKGZpbGwyfHwiIikrIi5cbiI7CisKKyAgaWYodGhpc19wbGF5ZXIoKSkgeworICAgIC8qIGdyb2Vzc2VudmVyZ2xlaWNoX2FuZmFuZyAoTkVVKSAqLworICAgIHBlcnMxID0gUXVlcnlQcm9ub3VuKFdFUik7CisgICAgcGVyczIgPSBRdWVyeVByb25vdW4oV0VNKTsKKyAKKyAgICAvLyB8fCBmYWxscyBUUCBrZWluZSBHcm9lc3NlIGdlc2V0enQgaGF0Li4uIFdhcnVtIGF1Y2ggaW1tZXIuLi4KKyAgICByZWxhdGlvbiA9IChRdWVyeVByb3AoUF9TSVpFKSoxMDApIC8gCisgICAgICAgICAgICAgICAgICAodGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfU0laRSkgfHwgMSk7CisgICAgc3dpdGNoIChyZWxhdGlvbikgCisgICAgIHsKKyAgICAgY2FzZSAgIDAgLi4gIDI1IDogY29tcGFyZXNpemUgPSAiRGFtaXQgZ2lidCAiK3BlcnMxKyIgZWluZW4gZ3V0ZW4iCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBGdXNzY2hlbWVsIGZ1ZXIgRGljaCBhYiI7IAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICBjYXNlICAyNiAuLiAgNTAgOiBjb21wYXJlc2l6ZSA9ICJEYW1pdCByZWljaHQgIitwZXJzMSsiIERpciBuaWNodCBtYWwgYmlzIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgenVyIEh1ZWZ0ZSI7IAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICBjYXNlICA1MSAuLiAgNzUgOiBjb21wYXJlc2l6ZSA9ICJEYW1pdCBrYW5uc3QgRHUgIitwZXJzMisiIGxvY2tlciBhdWYgZGVuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgS29wZiBzcHVja2VuIjsgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgIGNhc2UgIDc2IC4uICA5MCA6IGNvbXBhcmVzaXplID0gIkRhbWl0IGlzdCAiK3BlcnMxKyIgZWluZW4gS29wZiBrbGVpbmVyIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgYWxzIER1IjsgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgIGNhc2UgIDkxIC4uIDExMCA6IGNvbXBhcmVzaXplID0gIkRhbWl0IGhhdCAiK3BlcnMxKyIgZXR3YSBEZWluZSBHcm9lc3NlIjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgIAorICAgICBjYXNlIDExMSAuLiAxMjAgOiBjb21wYXJlc2l6ZSA9ICJEYW1pdCBpc3QgIitwZXJzMSsiIGVpbmVuIEtvcGYgZ3JvZXNzZXIiIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgYWxzIER1IjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgY2FzZSAxMjEgLi4gMTUwIDogY29tcGFyZXNpemUgPSAiRGFtaXQgaG9sc3QgRHUgRGlyIGVpbmVuIHN0ZWlmZW4gTmFja2VuLCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIHdlbm4gRHUgIitwZXJzMisiIGluIGRpZSBBdWdlbiBzaWVoc3QiOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICBjYXNlIDE1MSAuLiAyMDAgOiBjb21wYXJlc2l6ZSA9ICJEYW1pdCB2ZXJzcGVycnQgIitwZXJzMSsiIERpciBhYnNvbHV0IgorCQkgICAgICAgICAgICAgICAgICAgICAiIGRpZSBTaWNodCI7IAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICBjYXNlIDIwMSAuLiAzMDAgOiBjb21wYXJlc2l6ZSA9ICJEYW1pdCB3YWVyZSBqZWRlciBTY2hsYWcgdm9uIERpciBlaW4iIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgVGllZnNjaGxhZyI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgIGRlZmF1bHQgICAgICAgICA6IGNvbXBhcmVzaXplID0gIkRhbWl0IGthbm5zdCBEdSAiK3BlcnMyKyIgYmVxdWVtIHp3aXNjaGVuIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgZGVuIEJlaW5lbiBkdXJjaGxhdWZlbiI7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgIH0KKyAgCisgICAgIGRlc2NyKz1jb21wYXJlc2l6ZSsiLlxuIjsKKyAgICAgLyogZ3JvZXNzZW52ZXJnbGVpY2hfZW5kZSAoTkVVKSAqLworICAgfQorCisgIGlmKFF1ZXJ5UHJvcChQX0dIT1NUKSkgcmV0dXJuIGRlc2NyOworCisgIHRyYW5zID0gUXVlcnlQcm9wKFBfVFJBTlNQQVJFTlQpOyBTZXRQcm9wKFBfVFJBTlNQQVJFTlQsIDApOworICBkZXNjciArPSA6OmxvbmcoKTsgU2V0UHJvcChQX1RSQU5TUEFSRU5ULCB0cmFucyk7CisKKyAgLy8gV2FmZmVuLCBSdWVzdHVuZ2VuL0tsZWlkdW5nIHVuZCBTb25zdGlnZXMgZXJtaXR0ZWxuCisgIHcgPSAoe1F1ZXJ5UHJvcChQX1dFQVBPTiksIFF1ZXJ5UHJvcChQX1BBUlJZX1dFQVBPTil9KSAtICh7MH0pOworICBhID0gUXVlcnlQcm9wKFBfQVJNT1VSUykgKyBRdWVyeVByb3AoUF9DTE9USElORykgLSAoezB9KTsKKyAgciA9IGFsbF9pbnZlbnRvcnkoTUUpIC0gdyAtIGE7IC8vUmVzdCBsb2dpc2NoZXJ3ZWlzZQorCisgIC8vIHJlc3Qgbm9jaCBuYWNoIHNpY2hiYXJrZWl0IHZvbiBhdXNzZXJoYWxiIGRlcyBTUGllbGVycyBmaWx0ZXJuLgorICByPW1hcChyLGZ1bmN0aW9uIHN0cmluZyAob2JqZWN0IG9iKSB7CisJICBpZihzaXplb2YoYWxsX2ludmVudG9yeShvYikpIHx8IG9iLT5RdWVyeVByb3AoUF9MSUdIVCkgfHwgCisJICAgICBvYi0+UXVlcnlQcm9wKFBfTElHSFRFRCkgfHwgb2ItPlF1ZXJ5UHJvcChQX1NIT1dfSU5WKSkKKwkgICAgcmV0dXJuKGdldF92aXNfbmFtZShvYikpOworICAgICAgICAgIHJldHVybigwKTsgfSApIC0gKHswfSk7CisKKyAgLy8gSW52aXMtT2JqZWt0ZSBhdXNmaWx0ZXJuIHVuZCBOYW1lbiBlcm1pdHRlbG4sIGFuc2NobGllc3NlbmQgc2luZCBpbiB3LCBhCisgIC8vIHVuZCByIGplIGVpbiBBcnJheSB2b24gU3RyaW5ncworICB3ID0gbWFwKHcsICMnZ2V0X3Zpc19uYW1lKSAtICh7MH0pOworICBhID0gbWFwKGEsICMnZ2V0X3Zpc19uYW1lKSAtICh7MH0pOworCisgIHJldHVybiBkZXNjciArCisgICAgICAgICAoUXVlcnlQcm9wKFBfVFJBTlNQQVJFTlQpID8KKyAgICAgICAgICBicmVha19zdHJpbmcoY2FwaXRhbGl6ZShuYW1lKFdFUiwgMSkpKyIgaGF0ICIKKyAgICAgICAgICAgICAgICAgICAgICArKHNpemVvZihhKT9Db3VudFVwKGEpOiJrZWluZSBSdWVzdHVuZyIpKyIgYW4iCisgICAgICAgICAgICAgICAgICAgICAgKyhzaXplb2Yocik/IiwgIjoiIHVuZCAiKQorICAgICAgICAgICAgICAgICAgICAgICsoc2l6ZW9mKHcpP0NvdW50VXAodyk6ImtlaW5lIFdhZmZlIikrIiBnZXp1ZWNrdCIKKyAgICAgICAgICArKHNpemVvZihyKT8iIHVuZCB0cmFlZ3QgIitDb3VudFVwKHIpOiIiKSsiLiIsIDc4KTogIiIpOworfQorCisKKy8vICoqKiogbG9jYWwgcHJvcGVydHkgbWV0aG9kcworc3RhdGljIG1peGVkIF9xdWVyeV9wcmVzYXkoKQoreworICBzdHJpbmcgcHJlc2F5OworICBpZigocHJlc2F5ID0gUXVlcnkoUF9QUkVTQVkpKSAmJiAocHJlc2F5ICE9ICIiKSkgcmV0dXJuIHByZXNheSArICIgIjsKKyAgcmV0dXJuICIiOworfQorCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9uYW1lKCkKK3sKKyAgcmV0dXJuIGNhcGl0YWxpemUoUXVlcnkoUF9OQU1FKSB8fCAiTm9OYW1lIik7Cit9CisvLyAqKioqCisKKy8vIExvY2FsIGNvbW1hbmRzCitzdGF0aWMgbWl4ZWQgX3F1ZXJ5X2xvY2FsY21kcygpIHsKKyAgcmV0dXJuCisgICAgKHsKKyAgICAgICh7ImF2YXRhciIsInNldF9hdmF0YXJ1cmkiLDAsMH0pLAorICAgIH0pOworfQorCitpbnQgc2V0X2F2YXRhcnVyaShzdHJpbmcgYXJnKSB7CisgIGFyZyA9IF91bnBhcnNlZF9hcmdzKDApOworICBpZiAoIWFyZyB8fCAhc2l6ZW9mKGFyZykpIHsKKyAgICBzdHJpbmcgdXJpID0gUXVlcnlQcm9wKFBfQVZBVEFSX1VSSSk7CisgICAgaWYgKHN0cmluZ3AodXJpKSkKKyAgICAgIHRlbGxfb2JqZWN0KE1FLAorICAgICAgICAgICJBa3R1ZWxsZSBBdmF0YXItVVJJOiAiICsgdXJpICsgIlxuIik7CisgICAgZWxzZQorICAgICAgdGVsbF9vYmplY3QoTUUsICJEdSBoYXN0IGtlaW5lIEF2YXRhci1VUkkgZWluZ2VzdGVsbHQuXG4iKTsKKyAgfQorICBlbHNlIGlmIChhcmcgPT0gImtlaW5lIikgeworICAgICAgU2V0UHJvcChQX0FWQVRBUl9VUkksIDApOworICAgICAgdGVsbF9vYmplY3QoTUUsICJEZWluZSBBdmF0YXItVVJJIHd1cmRlIGdlbG9lc2NodC5cbiIpOworICB9CisgIGVsc2UgaWYgKHNpemVvZihhcmcpID4gNTEyKQorICAgICAgdGVsbF9vYmplY3QoTUUsICJEZWluZSBuZXVlIEF2YXRhci1VUkkgaXN0IHp1IGxhbmchXG4iKTsKKyAgZWxzZSB7CisgICAgICBTZXRQcm9wKFBfQVZBVEFSX1VSSSwgYXJnKTsKKyAgICAgIHRlbGxfb2JqZWN0KE1FLAorICAgICAgICAgICJBa3R1ZWxsZSBBdmF0YXItVVJJOiAiICsgYXJnICsgIlxuIik7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvZXhwbG9yYXRpb24uYyBiL3N0ZC9wbGF5ZXIvZXhwbG9yYXRpb24uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YTE5NzZlCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9leHBsb3JhdGlvbi5jCkBAIC0wLDAgKzEsMTI1IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL2V4cGxvcmF0aW9uLmMgLS0gZXhwbG9yYXRpb24gcG9pbnQgbWFuYWdlbWVudAorLy8KKy8vICRJZDogZXhwbG9yYXRpb24uYyA5MTQyIDIwMTUtMDItMDQgMjI6MTc6MjlaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHBsYXllci9saWZlLmg+CisjaW5jbHVkZSA8cGxheWVyL2Jhc2UuaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxleHBsb3JhdGlvbi5oPgorI2luY2x1ZGUgPHNjb3JlbWFzdGVyLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKworcHJpdmF0ZSBzdHJpbmcgZ2l2ZW5fc2NvcmVzOworCitwcml2YXRlIG5vc2F2ZSBtaXhlZCBlcG51bTsKKwordm9pZCBjcmVhdGUoKSB7CisgIFNldChQX0xFUCwgU0VDVVJFRHxTQVZFLCBGX01PREVfQVMpOworCisgIGdpdmVuX3Njb3JlcyA9ICIiOworfQorCitzdHJpbmcgRm9yc2NodW5nKCkKK3sKKyAgcmV0dXJuIEVQTUFTVEVSLT5RdWVyeUZvcnNjaHVuZygpOworfQorCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9naXZlbl9zY29yZXMoKQoreworICByZXR1cm4gZ2l2ZW5fc2NvcmVzOworfQorCisvLyBIaWVyIGtvbW1lbiBGdW5rdGlvbmVuIGZ1ZXIgZGllIExldmVscHVua3RlCisKKyNkZWZpbmUgWFBfRkFDIChbMToxMCwyOjQwLDM6MTUwLDQ6NjAwLDU6MjI1MCw2OjkwMDAsNzozNTAwMCw4OjE0MDAwMCw5OjUwMDAwMF0pCisKKy8vI2RlZmluZSBERUJVRyh4LHkpIHByaW50Zih4LHkpCisjZGVmaW5lIERFQlVHKHgseSkKKworaW50IEFkZFNjb3JlKGludCBjb250cmlidXRvcikKK3sKKyAgbWl4ZWQgaW5mbzsKKyAgb2JqZWN0IHBvOworICBpbnQgZHJpbjsKKyAgCisgIGlmICghcG9pbnRlcnAoaW5mbyA9IFNDT1JFTUFTVEVSLT5RdWVyeU5QQ2J5TnVtYmVyKGNvbnRyaWJ1dG9yKSkpCisgICAgcmV0dXJuIC0xOworCisgIGlmICgocG8gPSBwcmV2aW91c19vYmplY3QoKSkgJiYgKG9iamVjdF9uYW1lKHBvKSA9PSBTQ09SRU1BU1RFUikpCisgICAgcG8gPSBwcmV2aW91c19vYmplY3QoMSk7CisKKyAgaWYgKCFwbyB8fCBvbGRfZXhwbG9kZShvYmplY3RfbmFtZShwbyksIiMiKVswXSAhPSBpbmZvW1NDT1JFX0tFWV0pCisgICAgcmV0dXJuIC0yOworCisgIGlmICghc3RyaW5ncChnaXZlbl9zY29yZXMpKQorICAgIGdpdmVuX3Njb3JlcyA9ICIgIjsKKworICBpZiAoY2F0Y2goZHJpbiA9IHRlc3RfYml0KGdpdmVuX3Njb3JlcywgY29udHJpYnV0b3IpO3B1Ymxpc2gpKQorICAgIHJldHVybiAtMzsKKworICBpZiAoIWRyaW4pIHsKKyAgICBnaXZlbl9zY29yZXMgPSBzZXRfYml0KGdpdmVuX3Njb3JlcywgY29udHJpYnV0b3IpOworICAgIFNldChQX0xFUCwgUXVlcnkoUF9MRVApICsgaW5mb1tTQ09SRV9TQ09SRV0pOworICAgIGZvcmNlX3NhdmUoKTsKKyAgICByZXR1cm4gaW5mb1tTQ09SRV9TQ09SRV07CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK2ludCBUZXN0U2NvcmUoaW50IGNvbnRyaWJ1dG9yKQoreworICBpbnQgcmV0OworICAKKyAgaWYgKCFwcmV2aW91c19vYmplY3QoKSB8fCAob2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpICE9IFNDT1JFTUFTVEVSKSkKKyAgICByZXR1cm4gMDsKKworICBjYXRjaChyZXQgPSB0ZXN0X2JpdChnaXZlbl9zY29yZXMsIGNvbnRyaWJ1dG9yKTtwdWJsaXNoKTsKKworICByZXR1cm4gcmV0OworfQorCitpbnQgU2V0U2NvcmVCaXQoaW50IGNvbnRyaWJ1dG9yKQoreworICBpbnQgZHJpbjsKKyAgCisgIGlmICghcHJldmlvdXNfb2JqZWN0KCkgfHwgKG9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSAhPSBTQ09SRU1BU1RFUikpCisgICAgcmV0dXJuIC0xOworCisgIGlmIChjYXRjaChkcmluID0gdGVzdF9iaXQoZ2l2ZW5fc2NvcmVzLCBjb250cmlidXRvcik7cHVibGlzaCkpCisgICAgcmV0dXJuIC0yOworCisgIGlmIChkcmluKSByZXR1cm4gLTM7CisKKyAgZ2l2ZW5fc2NvcmVzID0gc2V0X2JpdChnaXZlbl9zY29yZXMsIGNvbnRyaWJ1dG9yKTsKKyAgZm9yY2Vfc2F2ZSgpOworICByZXR1cm4gMTsKK30KKworaW50IENsZWFyU2NvcmVCaXQoaW50IGNvbnRyaWJ1dG9yKQoreworICBpbnQgZHJpbjsKKyAgCisgIGlmICghcHJldmlvdXNfb2JqZWN0KCkgfHwgKG9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSAhPSBTQ09SRU1BU1RFUikpCisgICAgcmV0dXJuIC0xOworCisgIGlmIChjYXRjaChkcmluID0gdGVzdF9iaXQoZ2l2ZW5fc2NvcmVzLCBjb250cmlidXRvcik7cHVibGlzaCkpCisgICAgcmV0dXJuIC0yOworCisgIGlmICghZHJpbikgcmV0dXJuIC0zOworCisgIGdpdmVuX3Njb3JlcyA9IGNsZWFyX2JpdChnaXZlbl9zY29yZXMsIGNvbnRyaWJ1dG9yKTsKKyAgZm9yY2Vfc2F2ZSgpOworICByZXR1cm4gMTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9ndWlkZS5jIGIvc3RkL3BsYXllci9ndWlkZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmZiMDhiNDMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2d1aWRlLmMKQEAgLTAsMCArMSwxODIgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vIAorLy8gcGxheWVyL2d1aWRlLmMgLS0gbmV3YmllIGd1aWRlIGhhbmRsaW5nIAorLy8KKy8vICRJZDogZ3VpZGUuYyA3MzkxIDIwMTAtMDEtMjUgMjI6NTI6NTFaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDxjb25maWcuaD4KKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8cGxheWVyL3VzZXJfZmlsdGVyLmg+IC8vIGZ1ZXIgaXNfYWN0aXZlX2d1aWRlKCkKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKworLyogRnVua3Rpb24sIGRpZSBkaWUgR3VpZGUtS29tbWFuZG9zIGFrdGl2aWVydCAqLwordm9pZCBhZGRfZ3VpZGVfY29tbWFuZHMoKQoreworCWFkZF9hY3Rpb24oIkNpY2Vyb25lQ21kIiwiY2ljZXJvbmUiKTsKKwkvLyBTb2xsdGUgZWlnZW50bGljaCBhbiBkZXJzZWxiZW4gU3RlbGxlIG1vZWdsaWNoIHNlaW4uCit9CisKKy8qIEdpYnQgZGllIE1lbGR1bmcgYmVpbSBBZW5kZXJuIGF1cyovCitwcm90ZWN0ZWQgaW50IE5ld2JpZUNoYW5nZU1zZygpIHsKKyAgICBpbnQgY2ljPVF1ZXJ5UHJvcChQX05FV0JJRV9HVUlERSk7CisgICAgLy8gYmVncmVuemVuIGF1ZiAxIFRhZywgZmFsbHMgamVtYW5kIGRhIFNjaHJvdHQgcmVpbmdzY2hyaWViZW4gaGF0LgorICAgIGlmIChjaWMgPiA4NjQwMCkgeworCWNpYz04NjQwMDsKKwlTZXRQcm9wKFBfTkVXQklFX0dVSURFLGNpYyk7CisgICAgfQorICAgIGlmIChjaWM8PTApIHsKKwl3cml0ZSgiRHUgYmlzdCBqZXR6dCBrZWluIENpY2Vyb25lIG1laHIuXG4iKTsKKyAgICB9CisgICAgZWxzZSBpZiAoY2ljIDwgNjApIHsKKwl3cml0ZSgiRHUgYmlzdCBqZXR6dCBlaW4gQ2ljZXJvbmUuXG4iKTsKKyAgICB9CisgICAgZWxzZSB7CisJd3JpdGUoYnJlYWtfc3RyaW5nKAorCSAgICAiRHUgYmlzdCBqZXR6dCBlaW4gQ2ljZXJvbmUsIGFsbGVyZGluZ3MgbnVyIGluIGRlbiBaZWl0ZW4sICIKKwkgICAgImluIGRlbmVuIER1IHdlbmlnZXIgYWxzICIgKyBjaWMvNjAKKwkgICAgKyAoKGNpYy82MCk8MiA/ICIgTWludXRlICI6IiBNaW51dGVuICIpCisJICAgICsgImlkbGUgYmlzdC5cbiIsNzgpKTsKKyAgICB9CisgICAgcmV0dXJuIDE7Cit9CisKKy8qIEdpYnQgZGllIFN0YXR1c21lbGR1bmcgYXVzICovCitwcm90ZWN0ZWQgaW50IE5ld2JpZVN0YXR1c01zZygpIHsKKyAgaW50IGNpYz1RdWVyeVByb3AoUF9ORVdCSUVfR1VJREUpOworICAvLyBiZWdyZW56ZW4gYXVmIDEgVGFnLCBmYWxscyBqZW1hbmQgZGEgU2Nocm90dCByZWluZ3NjaHJpZWJlbiBoYXQuCisgIGlmIChjaWMgPiA4NjQwMCkgeworICAgICAgY2ljPTg2NDAwOworICAgICAgU2V0UHJvcChQX05FV0JJRV9HVUlERSxjaWMpOworICB9CisKKyAgaWYgKGNpYyA8PSAwKQorICAgIHdyaXRlICgiRHUgYmlzdCBrZWluIENpY2Vyb25lLlxuIik7CisgIGVsc2UgaWYgKGNpYyA8IDYwKQorICAgIHdyaXRlICgiRHUgc3RlaHN0IE5ldXNwaWVsZXJuIGFscyBDaWNlcm9uZSB6dXIgVmVyZnVlZ3VuZy5cbiIpOworICBlbHNlIHsKKyAgICB3cml0ZShicmVha19zdHJpbmcoCisJICAgICJEdSBzdGVoc3QgTmV1c3BpZWxlcm4gYWxzIENpY2Vyb25lIHp1ciBWZXJmdWVndW5nLCBhbGxlcmRpbmdzICIKKwkgICAgIm51ciBpbiBkZW4gWmVpdGVuLCBpbiBkZW5lbiBEdSB3ZW5pZ2VyIGFscyAiICsgY2ljLzYwCisJICAgICsgKChjaWMvNjApPDIgPyAiIE1pbnV0ZSAiOiIgTWludXRlbiAiKQorCSAgICArICJpZGxlIGJpc3QuXG4iLDc4KSk7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKKy8qIEZ1ZWhydCBkYXMgZWlnZW50bGljaGUgS29tbWFuZG8gYXVzKi8KKworaW50IENpY2Vyb25lQ21kKHN0cmluZyBzdHIpCit7CisJaWYgKFF1ZXJ5UHJvcChQX0xFVkVMKTwyMCkKKwl7CisJCXdyaXRlKGJyZWFrX3N0cmluZygiRHUgc29sbHRlc3QgZXJzdCBub2NoIGVpbiB3ZW5pZyAiCisJCQkJCSJFcmZhaHJ1bmcgc2FtbWVsbiwgYmV2b3IgRHUgRGljaCAiCisJCQkJICAgICAgICJhbHMgQ2ljZXJvbmUgenVyIFZlcmZ1ZWd1bmcgc3RlbGxzdC4iLDc4KSk7CisJCXJldHVybiAxOworCX0KKwkvLyBJZGxlemVpdCB1ZWJlcmdlYmVuPworCWludCBpZGxlPXRvX2ludChzdHIpOworCS8vIG1heC4gZWluZW4gVGFnICgxNDQwIG1pbikgenVsYXNzZW4uCisJaWYgKGlkbGUgPCAwKSBpZGxlPTA7CisJZWxzZSBpZiAoaWRsZSA+IDE0NDApIGlkbGU9MTQ0MDsKKworCWlmICghc3RyKSB7CisJICAgIHJldHVybiBOZXdiaWVTdGF0dXNNc2coKTsKKwl9CisJZWxzZSBpZiAoc3RyPT0ic3RhdHVzIikgeworCSAgICByZXR1cm4gTmV3YmllU3RhdHVzTXNnKCk7CisJfQorCS8vICJlaW4iIHNjaGFsdGV0IGVpbmZhY2ggZ2VuZXJlbGwgZWluLCBoaWVyYmVpIHN0ZWh0IDEgaW4gZGVyIFByb3AKKwkvLyBmdWVyICJwZXJtYW5lbnQgZWluIi4KKwllbHNlIGlmIChzdHI9PSJlaW4iKSB7CisJICAgIFNldFByb3AoUF9ORVdCSUVfR1VJREUsMSk7CisJICAgIHJldHVybiBOZXdiaWVDaGFuZ2VNc2coKTsKKwl9CisJLy8gImF1cyIgb2RlciAiMCIgZGVha3RpdmllcnQuCisJZWxzZSBpZiAoc3RyPT0iYXVzIikgeworCSAgICBTZXRQcm9wKFBfTkVXQklFX0dVSURFLDApOworCSAgICByZXR1cm4gTmV3YmllQ2hhbmdlTXNnKCk7CisJfQorCS8vIHdlbm4gWmFobCB1ZWJlcmdlYmVuIGlzdCwgZGllIGdyb2Vzc2VyIDAgdW5kIGtsZWluZXIgMTQ0MCBpc3QKKwkvLyAocy5vLiksIHdpcmQgZXMgYWxzIEFuemFobCBhbiBJZGxlLU1pbnV0ZW4gYXVmZ2VmYXNzdCwgYWIgZGVyIG1hbgorCS8vIGF1c2dlYmxlbmRldCB3ZXJkZW4gd2lsbC4KKwllbHNlIGlmIChpZGxlKSB7CisJICAgIFNldFByb3AoUF9ORVdCSUVfR1VJREUsIGlkbGUqNjApOyAvLyBhbHMgU2VrdW5kZW4gc3BlaWNoZXJuLgorCSAgICByZXR1cm4gTmV3YmllQ2hhbmdlTXNnKCk7CisJfQorCXdyaXRlKGJyZWFrX3N0cmluZygKKwkgICAgICAiY2ljZXJvbmUgZWluICAtIER1IGJpc3QgQ2ljZXJvbmVcbiIKKwkgICAgICAiY2ljZXJvbmUgYXVzICAtIER1IGJpc3Qga2VpbiBDaWNlcm9uZVxuIgorCSAgICAgICJjaWNlcm9uZSAgICAgIC0gU3RhdHVzIGFuemVpZ2VuXG4iCisJICAgICAgK2JyZWFrX3N0cmluZygKKwkJIkR1IGJpc3QgQ2ljZXJvbmUsIGFiZXIgd2VubiBEdSBsYWVuZ2VyIGFscyA8emFobD4gTWludXRlbiAiCisJCSJpZGxlIGJpc3QsIHdpcnN0IER1IGF1dG9tYXRpc2NoIGF1c2dlYmxlbmRldCwgYmlzIER1IHdpZWRlciAiCisJCSJlbmRpZGVsdCBiaXN0LiIsCisJCTc2LCJjaWNlcm9uZSB6YWhsIC0gIixCU19JTkRFTlRfT05DRSksCisJICAgICAgNzgsIlN5bnRheGhpbGZlOiIsQlNfUFJFUEVORF9JTkRFTlR8QlNfTEVBVkVfTVlfTEZTKSk7CisKKwlyZXR1cm4gMTsKK30KKworcHJvdGVjdGVkIHN0cmluZyBJc3RTaW5kTXNnKHN0cmluZyogbmFtZW4pCit7CisJaWYgKHNpemVvZihuYW1lbik9PTEpCisJCXJldHVybiAiaXN0IGRhdm9uICIrbmFtZW5bMF07CisJZWxzZQorCQlyZXR1cm4gInNpbmQgZGF2b24gIitDb3VudFVwKG5hbWVuKTsKK30KKwordm9pZCBOZXdiaWVJbnRyb01zZygpCit7CisJb2JqZWN0KiBjaWNlcm9uZXM7CisJc3RyaW5nKiBuYW1lbjsKKwlzdHJpbmcgcmVzdGV4dDsKKworCS8vIE51ciBiaXMgTGV2ZWwgNSB3aXJkIGV0d2FzIGF1c2dlZ2ViZW4uCisJaWYgKFF1ZXJ5UHJvcChQX0xFVkVMKT41KSByZXR1cm47CisJCisJLy8gaXNfYWN0aXZlX2d1aWRlKCkgaXN0IGluIC9zdGQvdXNlcl9maWx0ZXIuYywgd2VsY2hlcyB2b20KKwkvLyBTcGllbGVyb2JqZWt0IGdlZXJidCB3aXJkIHVuZCBkYW1pdCB6dXIgVmVyZnVlZ3VuZyBzdGVodC4KKwljaWNlcm9uZXM9ZmlsdGVyKHVzZXJzKCksIydpc19hY3RpdmVfZ3VpZGUpOworCS8vIHVpZCB2ZXJ3ZW5kZW4sIGRhIHNvbnN0IGtsZWluZSBTcGllbGVyIGVpbmVuIGdldGFybnRlbiAKKwkvLyAiUmllc2VuIiBvZGVyIGFlaG5saWNoZXMgYW5zdHByZWNoZW4uCisJbmFtZW49bWFwKGNpY2Vyb25lcyxmdW5jdGlvbiBzdHJpbmcgKG9iamVjdCBvKSAKKwkgICAgeyByZXR1cm4oY2FwaXRhbGl6ZShnZXRldWlkKG8pKSk7IH0gKTsKKworCWlmIChuYW1lbiAmJiBzaXplb2YobmFtZW4pPjApCisJeworCQlyZXN0ZXh0PSJcbkVzIGdpYnQgZWluaWdlIG5ldHRlIFNwaWVsZXIsIGRpZSBiZXJlaXQgc2luZCwgRGljaCAiCisJCQkJImF1ZiBEZWluZW4gZXJzdGVuIFNjaHJpdHRlbiBpbSAiTVVETkFNRQorCQkJCSIgenUgYmVnbGVpdGVuLiBcblxuRGVyemVpdCAiCisJCQkJK0lzdFNpbmRNc2cobmFtZW4pKyIgZWluZ2Vsb2dndC4gRHUga2FubnN0ICIKKwkJCQkiZWluZW4gb2RlciBlaW5lIHZvbiBJaG5lbiBhbnNwcmVjaGVuLCAiCisJCQkJImluZGVtIER1IHouQi4gZWluZmFjaCBcbiIKKwkJCQkiICAndGVpbGUgIisKKwkJCQlsb3dlcl9jYXNlKG5hbWVuW3JhbmRvbShzaXplb2YobmFtZW4pKV0pKworCQkJCSIgbWl0IEhhbGxvIGljaCBiaW4gbmV1IGhpZXIsIGthbm5zdCBEdSAiCisJCQkJIm1pciBiaXR0ZSBoZWxmZW4/J1xuIgorCQkJCSJlaW50aXBwc3QuIE51ciBrZWluZSBTY2hldSwgZGllc2UgU3BpZWxlciAiCisJCQkJImhhYmVuIHNpY2ggZnJlaXdpbGxpZyBkYXp1IGJlcmVpdGVya2xhZXJ0IVxuIgorCQkJCSJcbkR1IGthbm5zdCBEaXIgZGllc2UgU3BpZWxlciBqZWRlcnplaXQgIgorCQkJCSJtaXQgJ2t3ZXIgY2ljZXJvbmVzJyBhbnplaWdlbiBsYXNzZW4uXG5cbiI7CisJCXdyaXRlKGJyZWFrX3N0cmluZyhyZXN0ZXh0LDc4LCIqICAiLEJTX0xFQVZFX01ZX0xGUykpOworCX0KKwllbHNlCisJeworCQkvLyBXZWlhLCBrZWluIE5ld2JpZS1HdWlkZSBkYS4gTGllYmVyIGVyc3RtYWwgbml4IHR1biwKKwkJLy8gYmlzIHVucyB3YXMgYmVzc2VyZXMgZWluZmFlbGx0LgorCX0KKwlyZXR1cm47Cit9CisKKworCisKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9BbXVsZXR0X2ZlbWFsZSBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9BbXVsZXR0X2ZlbWFsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MDg1MDI2Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0FtdWxldHRfZmVtYWxlCkBAIC0wLDAgKzEsNSBAQAorNgorMzUKKzUKK1xfLworPyYKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9BbXVsZXR0X21hbGUgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvQW11bGV0dF9tYWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIyNGUwOWMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvQW11bGV0dF9tYWxlCkBAIC0wLDAgKzEsNSBAQAorNgorMzYKKzUKK1xfLworPyYKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9CZXNjaHJpZnR1bmcgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvQmVzY2hyaWZ0dW5nCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFmZGRjNWUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvQmVzY2hyaWZ0dW5nCkBAIC0wLDAgKzEsMjQgQEAKKzcKKzAKKzAKKz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P19fX19fX19fX19fX19fX19fX19fPEhlbG0+Cis/PFdhZmZlPl9fX19fX19fX19fX19fCis/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/XD8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P19fX19fX19fX19fX188S29lY2hlcj4KKworPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P19fX19fX19fX19fX188QW11bGV0dD4KKz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/X19fX19fCis/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P1wKKz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/PzxQYW56ZXI+CisKKz88UmluZz5fX19fX19fX19fX19fLworPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Lz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/X19fX19fX19fX188U2NoaWxkPgorPzxIYW5kc2NodWhlPl9fX19fX18vPz8/Pz8/Pz8/Py8KKz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Py8KKz88R3VlcnRlbD5fX19fX19fX19fX19fX19fX19fLworCis/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz9cX19fX19fX19fX19fPFVtaGFuZz4KKworPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P19fX19fX19fXzxIb3NlPgorCisKKz8/Pz8/Pz8/PzxTY2h1aGU+X19fX19fX19fX19fXwpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0d1ZXJ0ZWxfZmVtYWxlIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0d1ZXJ0ZWxfZmVtYWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjgzZWQ4ODQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvR3VlcnRlbF9mZW1hbGUKQEAgLTAsMCArMSw0IEBACis1CiszMworMTAKK2A9PU89PScKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9HdWVydGVsX21hbGUgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvR3VlcnRlbF9tYWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI1YzE0YTQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvR3VlcnRlbF9tYWxlCkBAIC0wLDAgKzEsNCBAQAorNQorMzMKKzEwCitgPT09Tz09PScKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9IYW5kc2NodWhfZmVtYWxlIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0hhbmRzY2h1aF9mZW1hbGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOGUzZjE5ZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9IYW5kc2NodWhfZmVtYWxlCkBAIC0wLDAgKzEsMTAgQEAKKzQKKzIxCis3Cis/XywtXworKF9fLEkKKworPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P3w3Cis/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/L3wKKz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/P2ApLworPz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/PycKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9IYW5kc2NodWhfbWFsZSBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9IYW5kc2NodWhfbWFsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YjgxZGQxCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0hhbmRzY2h1aF9tYWxlCkBAIC0wLDAgKzEsMTAgQEAKKzQKKzIyCis3CissLS1fXworKF9fLEkKKz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Xz8KKz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz98IHwKKz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8vIHwKKz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz9gKSkKKz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8gJyAKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9IZWxtX2ZlbWFsZSBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9IZWxtX2ZlbWFsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42M2JhNjQ3Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0hlbG1fZmVtYWxlCkBAIC0wLDAgKzEsNiBAQAorMQorMzQKKzAKKywtby0uCis9PT09SQorPz8/XF9cCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvSGVsbV9tYWxlIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0hlbG1fbWFsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yYzE4OGEzCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0hlbG1fbWFsZQpAQCAtMCwwICsxLDYgQEAKKzEKKzM1CiswCissLW8tLgorPT09PUkKKz8/P1xfXApkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0hvc2VuX2ZlbWFsZSBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9Ib3Nlbl9mZW1hbGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTljZmRkNgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9Ib3Nlbl9mZW1hbGUKQEAgLTAsMCArMSwxMyBAQAorNgorMzIKKzEwCisvYC0tLS0tJ1wKK3wvICAgICBcfAorfCAgIFkgICB8Cit8ICAgfCAgIHwKKz98ICB8ICB8Cis/KCAgfCAgKQorP3wgIHwgIHwKKz98ICB8ICB8Cis/fCAgfCAgfAorP0xfLyBcX0oKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9Ib3Nlbl9tYWxlIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0hvc2VuX21hbGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZThlNjM5MAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9Ib3Nlbl9tYWxlCkBAIC0wLDAgKzEsMTMgQEAKKzYKKzMzCisxMAorL2AtLS0tLSdcCit8LyAgICAgXHwKK3wgICBZICAgfAorfCAgIHwgICB8Cit8ICAgfCAgIHwKKzwuICB8ICAuPgorfCAgIHwgICB8Cit8ICAgfCAgIHwKK3wgICB8ICAgfAorP0xfLyBcX0oKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9Lb2VjaGVyX2ZlbWFsZSBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9Lb2VjaGVyX2ZlbWFsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZTBiMWNmCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L0tvZWNoZXJfZmVtYWxlCkBAIC0wLDAgKzEsNSBAQAorNworNDAKKzMKKyIiIgorLy8KZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9Lb2VjaGVyX21hbGUgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvS29lY2hlcl9tYWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRlMGIxY2YKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvS29lY2hlcl9tYWxlCkBAIC0wLDAgKzEsNSBAQAorNworNDAKKzMKKyIiIgorLy8KZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9SaW5nX2ZlbWFsZSBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9SaW5nX2ZlbWFsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMGY4YjAwCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L1JpbmdfZmVtYWxlCkBAIC0wLDAgKzEsNCBAQAorNgorMjEKKzgKK2MKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9SaW5nX21hbGUgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvUmluZ19tYWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjAzNjIwYTgKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvUmluZ19tYWxlCkBAIC0wLDAgKzEsNCBAQAorNgorMjIKKzgKK2MKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9SdWVzdHVuZ19mZW1hbGUgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvUnVlc3R1bmdfZmVtYWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4NDlmMzUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvUnVlc3R1bmdfZmVtYWxlCkBAIC0wLDAgKzEsOSBAQAorMQorMjYKKzQKKz8/Pz8/P19fXz8/P19fXworPz8/Pz8vKCAgXF8vICApXAorPz8/Py8gfFxfX19fXy98IFwKK19fXy8gLz9cXy9fXF8vP1wgXAorfF9fXCc/Pz8pXF8vKD8/P1wvfAorPz8/Pz8/Py9fX19fX1w/Pz98fApkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L1J1ZXN0dW5nX21hbGUgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvUnVlc3R1bmdfbWFsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lNTliNjdjCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L1J1ZXN0dW5nX21hbGUKQEAgLTAsMCArMSw5IEBACisxCisyNQorNAorPz8/Pz9fXl9fX18/Pz9fX19fXl8/Cis/Pz8/KCAgXCAgIFxfLyAgIC8gICkKKz8/Pz8vXCB8XF9fXyBfX18vfCAvXAorP19fLyAgLz9cXyAgICAgXy8/XF8gPgorSV9fX1w+Pz8/KVxfX18vKD8/P3wgfAorPz8/Pz8/Pz8vX19fX19fX1w/P3xffApkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L1NjaGlsZF9mZW1hbGUgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvU2NoaWxkX2ZlbWFsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mYzQ5ZWVhCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L1NjaGlsZF9mZW1hbGUKQEAgLTAsMCArMSwxMCBAQAorNworNDMKKzcKKz8/fFwKKz8/fHwKKz8/fHwKKz09fHwpCis/P3x8Cis/P3x8Cis/P3wvCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvU2NoaWxkX21hbGUgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvU2NoaWxkX21hbGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTViMzI5ZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9TY2hpbGRfbWFsZQpAQCAtMCwwICsxLDEwIEBACis3Cis0NQorNworPz98XAorPz98fAorPz98fAorPT18fCkKKz8/fHwKKz8/fHwKKz8/fC8KZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9TY2h1aGVfZmVtYWxlIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L1NjaHVoZV9mZW1hbGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGJlOTU4ZAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9TY2h1aGVfZmVtYWxlCkBAIC0wLDAgKzEsNyBAQAorNQorMzIKKzE4Cis/P18/Pz9fCis/fF98P3xffAorPy8gSj9MIFwKKyhfLz8/P1xfKQpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L1NjaHVoZV9tYWxlIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L1NjaHVoZV9tYWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJiMzMwMTQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvU2NodWhlX21hbGUKQEAgLTAsMCArMSw3IEBACis1CiszMgorMTgKKz8/P18/Pz9fCis/P3xffD98X3wKKz8vLyBKP0wgXFwKKyhfXy8/Pz9cX18pCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvVW1oYW5nX2ZlbWFsZSBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9VbWhhbmdfZmVtYWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjJkODg1YmEKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvVW1oYW5nX2ZlbWFsZQpAQCAtMCwwICsxLDE3IEBACisyCiszMQorNAorPz9fPz8/Pz9fCis/P1Y/Pz8/P1YKKworCit8Pz8/Pz8/Pz8/fAorfD8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz98Cit8Pz8/Pz8/Pz8/fAorfD8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz98Cit8Pz8/Pz8/Pz8/fAorfD8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz98Cis/XD8/Pz8/Pz8vCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvVW1oYW5nX21hbGUgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvVW1oYW5nX21hbGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDAyNWRiZQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9VbWhhbmdfbWFsZQpAQCAtMCwwICsxLDE3IEBACis0CiszMQorNAorPz8/Xz8/Pz8/XworPz8/Vj8/Pz8/VgorCisKK3w/Pz8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz8/P3wKK3w/Pz8/Pz8/Pz8/P3wKKz9cXz8/Pz8/Pz9fLwpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L2F4ZSBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9heGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTkyN2Y0OAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9heGUKQEAgLTAsMCArMSwxMyBAQAorNworMTkKKzEKKz9fXz8/Pz9fXworLy8gXCgpLyBcXAorfHwgIHx8ICB8fAorXFxfL3x8XF8vLworPz8/P3x8Cis/Pz8/fHwKKworCis/Pz8/fHwKKz8/Pz9cLwpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L2Jhc2VfZmVtYWxlIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L2Jhc2VfZmVtYWxlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjllYWVjMWEKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvYmFzZV9mZW1hbGUKQEAgLTAsMCArMSwyNSBAQAorMworMAorMAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICBcXCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxfIC98ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fX3wgfHxfXyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvICBgICAgJyAgXCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyB8XF8vIFxfL3wgXCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgIC4tX19fLC8gLyBcICAgICAvIFwgXCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgYC0tLi5fXycgICApICAgKCAgIFwgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyAgLiAgXCAgIHx8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIFwgLyAgfCAgL3wgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgIFkgICB8ICB8JyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCAgfCAgLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICB8ICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIHwgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCAgfCAgKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHwgfCB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgKSAoIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCApICggfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHwgfCB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8gSiBMIFwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnJycgICBgYGAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvYmFzZV9tYWxlIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L2Jhc2VfbWFsZQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iODM2NjUzCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L2Jhc2VfbWFsZQpAQCAtMCwwICsxLDI1IEBACiszCiswCiswCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9fXyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8ICBcXCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxfIC98ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX19fX3wgfF9fX18gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL14gICBgIHwgJyAgIF5cICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8gLHxcX18vIFxfXy98LixcICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAsLS1fX198ICcvIFwgIF9fXyAgLyBcX2BcICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgIHxfLi5fX18uJyAgICkvX3xfXCggICB8IHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgL1xffF8vXCAgIFwgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgLlwgLy4gfCAgIHx8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbHwgIFkgIHxsICAvIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAgfCAgfHwgICBcfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxgICd8YCAnfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIHwgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCAgfCAgKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHwgfCB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgIHwgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgfCAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IHwgfCB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyBKLiAuTCBcICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICcnJyAgICAgYGBgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9jbHViIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L2NsdWIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTU2NmVjZQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9jbHViCkBAIC0wLDAgKzEsMTMgQEAKKzcKKzIxCiswCis/P19fCitfL19fXF8KK198X198XworX3xfX3xfCis/XD8/LworPz98fAorPz98fAorCisKKz8/KCkKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9mZXJud2FmZmUgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvZmVybndhZmZlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjMwODk3ZTgKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvZmVybndhZmZlCkBAIC0wLDAgKzEsMTkgQEAKKzcKKzIzCiswCis/Pz8pCis/Py8uCis/Lz8uCit8Pz8uCit8Pz8uCit8Pz8uCitJPz8uCisKKworST8/LgorfD8/LgorfD8/LgorfD8/LgorP1w/LgorPz9cLgorPz8/KQpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L2tuaWZlIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L2tuaWZlCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY2YTRlY2QKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngva25pZmUKQEAgLTAsMCArMSw5IEBACis3CisyMworNAorPywKKyh8CisofAorLS0KKworP1UKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9tYWdpYyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9tYWdpYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wNmM1OTRiCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L21hZ2ljCkBAIC0wLDAgKzEsMTAgQEAKKzcKKzIwCiswCissCis/Lj8nPz8uCis/Llx8Lz8sCistPy0rLT8tCissPy98XD8uCisuPywuPz8/LgorPz8/XC8KZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9taXNjIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L21pc2MKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzRiNTI4MQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9taXNjCkBAIC0wLDAgKzEsMTEgQEAKKzcKKzIzCis0CisvXAorfHwKK3x8CisKKworfHwKK3x8CitgJwpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L3NwZWFyIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L3NwZWFyCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhZTlkNmMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvc3BlYXIKQEAgLTAsMCArMSwyNSBAQAorNworMjMKKzAKKy9cCishfAorXC8KK3x8Cit8fAorfHwKK3x8CisKKworfHwKK3x8Cit8fAorfHwKK3x8Cit8fAorfHwKK3x8Cit8fAorfHwKK3x8Cit8fAorYCcKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9zdGFmZiBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9zdGFmZgpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ODQ0NmQwCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L3N0YWZmCkBAIC0wLDAgKzEsMjIgQEAKKzcKKzIzCiswCissLgorfHwKK3x8Cit8fAorfHwKK3x8Cit8fAorCisKK3x8Cit8fAorfHwKK3x8Cit8fAorfHwKK3x8Cit8fAorfHwKK2AnCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvc3dvcmQgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvc3dvcmQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTBmZjJkYwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2dmeC9zd29yZApAQCAtMCwwICsxLDEzIEBACis3CisyMgorMAorPz8sCis/fHwKKz98fAorP3x8Cis/fHwKKz98fAorX3x8XworCisKKz9gJwpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L3doaXAgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9nZngvd2hpcApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMGRiODQzCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9pbnZtYXN0ZXIvZ2Z4L3doaXAKQEAgLTAsMCArMSwyMSBAQAorNworMTYKKzIKKz8/ICxfIAorPyAvICBcIAorIC8gPz8gXAorIHwgPz8/IHwKKyB8ID8/PyBeCisgfAorPyBcCis/PyB8ID8/IworPz8gLyAKKz8gLyAKKz8gfCAKKz8gLyAKKyAvIAorIHwgCisgfCAKKyB8IAorIFwgCis/IGAgCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL2ludm1hc3Rlci9pbnZtYXN0ZXIuYyBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2ludm1hc3Rlci5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2Y2NkYTAKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9pbnZtYXN0ZXIuYwpAQCAtMCwwICsxLDQ2NCBAQAorLy8gaW52bWFzdGVyLmMgYnkgTmFjaHR3aW5kQE1HIFYxLjEgKDUuMy4yMDAxKQorLy8gQSBzbWFsbCBtYXN0ZXIgdGhhdCBwcm92aWRlcyBhIGdyYXBoaWNhbCBkaXNwbGF5IG9mIHRoZSBwbGF5ZXK0cworLy8gZXF1aXBtZW50LiAKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMscnR0X2NoZWNrcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjaW5jbHVkZSA8aW5wdXRfdG8uaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8YW5zaS5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSAiaW52bWFzdGVyLmgiCisKKworbWFwcGluZyBkYXRhOworY2xvc3VyZSBhYmJyZXZpYXRlOworCisKKy8vIGknbSBhd2FyZSB0aGlzIGNhbiBiZSBkZXRlcm1pbmVkIHdpdGggbV9pbmRpY2VzKFZBTElEX0FSTU9VUl9UWVBFKSwKKy8vIGJ1dCB0aGUgcG9zaXRpb24gaW4gdGhlIGFycmF5cyBpcyBpbXBvcnRhbnQgZm9yIHRoZSBkcmF3aW5nIG9yZGVyLgorLy8gZmlyc3QgaXRlbSBpbiB0aGUgYXJyYXkgaXMgZHJhd24gbGFzdAorc3RhdGljIHN0cmluZyAqYXJtb3VyX3R5cGVzID0gCisoe0FUX0JFTFQsCisgIEFUX1NISUVMRCwKKyAgQVRfSEVMTUVULAorICBBVF9CT09ULAorICBBVF9UUk9VU0VSUywKKyAgQVRfQU1VTEVULAorICBBVF9SSU5HLAorICBBVF9HTE9WRSwKKyAgQVRfUVVJVkVSLAorICBBVF9DTE9BSywKKyAgQVRfQVJNT1VSfSk7CisKK3N0YXRpYyBtYXBwaW5nIGNvbG9ycyA9IAorKFswOkFOU0lfQkxBQ0ssCisgIDE6QU5TSV9SRUQsIAorICAyOkFOU0lfR1JFRU4sCisgIDM6QU5TSV9ZRUxMT1csCisgIDQ6QU5TSV9CTFVFLAorICA1OkFOU0lfUFVSUExFLAorICA2OkFOU0lfQ1lBTiwKKyAgNzpBTlNJX1dISVRFLAorICA4OiIiXSk7CisgIAorc3RhdGljIG1hcHBpbmcgYmdjb2xvcnMgPSAKKyhbMDpBTlNJX0JHX0JMQUNLLAorICAxOkFOU0lfQkdfUkVELCAKKyAgMjpBTlNJX0JHX0dSRUVOLAorICAzOkFOU0lfQkdfWUVMTE9XLAorICA0OkFOU0lfQkdfQkxVRSwKKyAgNTpBTlNJX0JHX1BVUlBMRSwKKyAgNjpBTlNJX0JHX0NZQU4sCisgIDc6QU5TSV9CR19XSElURSwKKyAgODoiIl0pOworICAKKworCitzdGF0aWMgc3RyaW5nIE1hcHBpbmcyQ29sb3JlZFRleHQobWFwcGluZyBwaWMsIG9iamVjdCBwbGF5ZXIpOworc3RhdGljIHN0cmluZyBNYXBwaW5nMlBsYWluVGV4dChtYXBwaW5nIHBpYyk7CitzdGF0aWMgdm9pZCBBZGREZXNjcmlwdGlvbihtYXBwaW5nIHBpYywgc3RyaW5nIHR5cGUsIG9iamVjdCBpdGVtKTsKK3N0YXRpYyBzdHJpbmcgQ29tcG9zZURlc2Mob2JqZWN0IGl0ZW0pOworc3RhdGljIHZvaWQgQ29uZmlndXJlQ29sb3JzKHN0cmluZyB0ZXh0KTsKKwordm9pZCBTaG93SW52KG9iamVjdCBwbGF5ZXIsIHN0cmluZyBhcmcpOworCisvLyBvaywgbGV0tHMganVzdCByZWFkIGluIHRoZSBncmFwaGljcy4uLgorLy8gcmVhbGx5IHRha2VzIHNvbWUgdGltZSAofjI1MCBldmFsIHRpY2tzKSBidXQgaXMgb25seSBkb25lCisvLyBvbmNlIGluIGFuIHVwdGltZQordm9pZCBjcmVhdGUoKQoreworICBtYXBwaW5nIHBpYzsKKyAgc3RyaW5nICpmaWxlcywgKmxpbmVzLCB0ZXh0OworICBpbnQgaSxqLGssIGluZGVudHgsaW5kZW50eSwgY29sb3I7CisKKyAgZGF0YT0oW10pOworICAKKyAgREIoIlRyeWluZyB0byBmaXJlIHVwIG1hc3RlciwgcGF0aCBpcyAnIitJTlZQQVRIKyInLi4uIik7CisgIGZpbGVzPWdldF9kaXIoSU5WUEFUSCsiZ2Z4LyoiKS0oeyIuIiwgIi4uIn0pOworICBEQihzcHJpbnRmKCJGaWxlcyBmb3VuZCBpbiAnZ2Z4Lyc6IFxuJU8iLCBmaWxlcykpOworICBmb3IgKGk9c2l6ZW9mKGZpbGVzKS0xO2k+PTA7aS0tKQorICB7CisgICAgREIoIlJlYWRpbmcgJyIrZmlsZXNbaV0rIicgLi4uIik7CisgICAgdGV4dD1yZWFkX2ZpbGUoSU5WUEFUSCsiZ2Z4LyIrZmlsZXNbaV0pOworICAgIGlmICghc3RyaW5ncCh0ZXh0KSkKKyAgICB7CisgICAgICBEQigiRmFpbGVkIHRvIHJlYWQgZmlsZS4iKTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBsaW5lcz1leHBsb2RlKHRleHQsICJcbiIpOworICAgIGlmIChzaXplb2YobGluZXMpIDwgNCkKKyAgICB7CisgICAgICBEQigiRmlsZSBjb3JydXB0LiIpOworICAgICAgY29udGludWU7CisgICAgfQorICAgIGluZGVudHg9dG9faW50KGxpbmVzWzFdKTsKKyAgICBpbmRlbnR5PXRvX2ludChsaW5lc1syXSk7CisgICAgY29sb3I9dG9faW50KGxpbmVzWzBdKTsKKyAgICBwaWM9KFtdKTsKKyAgICBmb3IgKGo9c2l6ZW9mKGxpbmVzKS0xO2o+MjtqLS0pCisgICAgeworICAgICAgZm9yIChrPXNpemVvZihsaW5lc1tqXSktMTtrPj0wO2stLSkKKyAgICAgIHsKKyAgICAgICAgaWYgKGxpbmVzW2pdW2suLmtdIT0iPyIpCisgICAgICAgICAgcGljKz0oWyhqLTMraW5kZW50eSkqODAraytpbmRlbnR4OmxpbmVzW2pdW2suLmtdO2NvbG9yXSk7CisgICAgICB9CisgICAgfQorICAgIGRhdGErPShbZmlsZXNbaV06cGljXSk7CisgICAgREIoIkZpbGUgc3VjY2Vzc2Z1bGx5IHJlYWQuIik7CisgIH0KKyAgREIoc3ByaW50ZigiVHlwZXMgY292ZXJlZDpcbiVPXG4iLCBtX2luZGljZXMoZGF0YSkpKTsKKworICAvLyBjcmVhdGUgY2xvc3VyZSBvbmx5IG9uY2UgdG8gc2F2ZSB0aW1lCisgIC8vIG5lZWRlZCBieSBDb21wb3NlRGVzYygpCisgIC8vIHRoZSBjbG9zdXJlIGlzdCBub3QgYXMgY29tcGxpY2F0ZWQgYXMgaXQgc2VlbXMgOykKKyAgLy8gaXQganVzdCBjaGVja3MgZXZlcnkgd29yZCBvZiB0aGUgbmFtZSwgaWYgaXQgZG9lcyBub3QgYmVnaW4KKyAgLy8gd2l0aCBhIGNhcGl0YWwgbGV0dGVyLCBpdCBpcyBhYmJyZXZpYXRlZAorICAvLyB0aGlzIGhhcHBlbnMgb25seSBpZiB0aGUgbmFtZSBsZW5ndGggZXhjZWVkcyAyMCBjaGFycy4uLgorICBhYmJyZXZpYXRlPWxhbWJkYSgoeyd4fSksIAorICAgICAgKHsjJz8sICh7Iyc+LCAoeyMnbWVtYmVyLCBxdW90ZSgoeyJkZXIiLCAiZGVzIn0pKSwgJ3h9KSwgMH0pLAorICAgICAgICAiZC4iLAorICAgICAgICAoeyMnPywgKHsjJz4sICh7IydzaXplb2YsICd4fSksIDN9KSwgCisgICAgICAgICAgKHsjJz8sICh7IycsLCAoeyMnPSwgJ2EsICh7IydhbGxvY2F0ZSwgMX0pIH0pLAorICAgICAgICAgICAgICAgICAgICAgICAgKHsjJz0sICh7IydbLCAnYSwgMH0pLCAneCB9KSwgCisgICAgICAgICAgICAgICAgICAgICAgICAoeyMnc2l6ZW9mLCAoeyMncmVnZXhwLCAnYSwgIl5bYS16XS4qIn0pIH0pIAorICAgICAgICAgICAgICAgICB9KSwgCisgICAgICAgICAgICAoeyMnKywgKHsjJ1suLl0sICd4LCAwLCAxfSksICIuIn0pLAorICAgICAgICAgICAgJ3gKKyAgICAgICAgICB9KSwgCisgICAgICAgICAgJ3gKKyAgICAgICAgfSkKKyAgICAgIH0pKTsKK30KKworLy8gZnVuY3Rpb24gdGhhdCB0cmllcyB0byBndWVzcyBhIGdvb2QgaXRlbSBuYW1lIGFuZCB1c2UgYWJicmV2YXRpb25zCisvLyB3aGVyZSBwb3NzaWJsZQorc3RhdGljIHN0cmluZyBDb21wb3NlRGVzYyhvYmplY3QgaXRlbSkKK3sKKyAgaW50IGk7CisgIHN0cmluZyB0ZXh0LCAqYnVmZjsKKyAgCisgIHRleHQ9cmVncmVwbGFjZShpdGVtLT5RdWVyeVByb3AoUF9TSE9SVCkKKyAgICAgICAgICAgICAgICB8fGl0ZW0tPlF1ZXJ5UHJvcChQX05BTUUpCisgICAgICAgICAgICAgICAgfHwiPD8+IiwKKyAgICAgICAgICAgICAgICAiXihFaW4gUGFhcnxFaW58RWluZXxEZXJ8RGllfERhcykgIiwiIiwwKTsKKyAgICAgICAgICAgICAgICAKKy8vIHRyeSB0byBzaG9ydGVuIHRoZSBuYW1lIHdpdGggdGhlIGNsb3N1cmUKKyAgaWYgKHNpemVvZih0ZXh0KSA+IDIwKQorICAgIHJldHVybiBpbXBsb2RlKG1hcChleHBsb2RlKHRleHQsICIgIiksIGFiYnJldmlhdGUpLCAiICIpOworICBlbHNlICAgICAgCisgICAgcmV0dXJuIHRleHQ7Cit9CisKKy8vIGNvbnZlcnRzIGEgbWFwcGluZyB3aXRoIGNoYXJhY3RlcnMgYW5kIGNvbG9yIGluZm8gaW50byBhCisvLyB0ZXh0LiBkYXRhIGluIHRoZSBtYXBwaW5nIGlzIHN0b3JlZCBpbiBhIG9uZS1kaW1lbnNpb25hbCAKKy8vIG9yZGVyIHdpdGggdGhlIHBvc2l0aW9uIGFzIGtleSAoeXBvcyBpcyBwb3MvODAsIHhwb3MgcG9zJTgwKQorLy8gdGhpcyBzZXR1cCBoYXMgYSBodWdlIGFkdmFudGFnZTogY29tYmluaW5nIHNldmVyYWwKKy8vIGdyYXBoaWNzIGp1c3QgdGFrZXMgYSAiKyIgb3BlcmF0b3IsIHRoZSByZXN0IGlzIGhhbmRsZWQKKy8vIGJ5IHRoZSBnYW1lIGRyaXZlci4gZnJlYWtpbicgZmFzdCwgbXVjaCBiZXR0ZXIgdGhhbiBkb2luZyBhbgorLy8gaXRlcmF0aW9uIG92ZXIgb25lIG9yIG1vcmUgYXJyYXkgaW4gbHBjLgorc3RhdGljIHN0cmluZyBNYXBwaW5nMkNvbG9yZWRUZXh0KG1hcHBpbmcgcGljLCBvYmplY3QgcGxheWVyKQoreworICBzdHJpbmcgdGV4dDsKKyAgbWFwcGluZyBjb25maWdtYXA7CisgIGludCBpLGosY29sb3I7CisgIAorICBjb25maWdtYXA9ZGVmYXVsdF9jb25maWcrKHBsYXllci0+UXVlcnlQcm9wKFBfSU5WTUFTVEVSX0NPTkZJRyl8fChbXSkpOworCisgIHRleHQ9IiI7CisgIGNvbG9yPTA7CisgIGZvciAoaT0wO2k8MjI7aSsrKQorICB7CisgICAgdGV4dCs9Ymdjb2xvcnNbY29uZmlnbWFwWzhdXTsKKyAgICBmb3IgKGo9MDtqPDc4O2orKykKKyAgICB7IAorICAgICAgaWYgKHBpY1tpKjgwK2osMV0hPWNvbG9yKQorICAgICAgeworICAgICAgICBjb2xvcj1waWNbaSo4MCtqLDFdOworICAgICAgICB0ZXh0Kz1jb2xvcnNbY29uZmlnbWFwW2NvbG9yXV07CisgICAgICB9CisgICAgICB0ZXh0Kz1waWNbaSo4MCtqXTsKKyAgICB9CisgICAgdGV4dCs9QU5TSV9OT1JNQUwrIlxuIjsKKyAgICBjb2xvcj0wOworICB9CisgIHJldHVybiB0ZXh0OworfQorCitzdGF0aWMgc3RyaW5nIE1hcHBpbmcyUGxhaW5UZXh0KG1hcHBpbmcgcGljKQoreworICBzdHJpbmcgdGV4dDsKKyAgaW50IGksajsKKyAgCisgIHRleHQ9IiI7CisKKyAgZm9yIChpPTA7aTwyMjtpKyspCisgIHsKKyAgICBmb3IgKGo9MDtqPDc4O2orKykKKyAgICAgIHRleHQrPXBpY1tpKjgwK2pdOworICAgIHRleHQrPSJcbiI7CisgIH0KKyAgcmV0dXJuIHRleHQ7Cit9CitzdGF0aWMgdm9pZCBBZGREZXNjcmlwdGlvbihtYXBwaW5nIHBpYywgc3RyaW5nIHR5cGUsIG9iamVjdCBpdGVtKQoreworICBpbnQgaW5kZW50eCwgaW5kZW50eSwgaTsKKyAgc3RyaW5nIHRleHQ7CisKKyAgc3dpdGNoKHR5cGUpCisgIHsKKyAgIGNhc2UgQVRfSEVMTUVUOgorICAgICAgaW5kZW50eD00NzsKKyAgICAgIGluZGVudHk9MDsKKyAgICAgIHRleHQ9c3ByaW50ZigiJS0zMHMiLENvbXBvc2VEZXNjKGl0ZW0pWzAuLjMwXSk7YnJlYWs7CisgICAgY2FzZSBBVF9RVUlWRVI6CisgICAgICBpbmRlbnR4PTQ5OworICAgICAgaW5kZW50eT0yOworICAgICAgdGV4dD1zcHJpbnRmKCIlLTI4cyIsQ29tcG9zZURlc2MoaXRlbSlbMC4uMjhdKTticmVhazsgICAgIAorICAgIGNhc2UgQVRfQU1VTEVUOgorICAgICAgaW5kZW50eD00OTsKKyAgICAgIGluZGVudHk9NDsgICAgIAorICAgICAgdGV4dD1zcHJpbnRmKCIlLTI3cyIsQ29tcG9zZURlc2MoaXRlbSlbMC4uMjhdKTticmVhazsgICAgIAorICAgIGNhc2UgQVRfQVJNT1VSOgorICAgICAgaW5kZW50eD01MzsKKyAgICAgIGluZGVudHk9NzsKKyAgICAgIHRleHQ9c3ByaW50ZigiJS0yNHMiLENvbXBvc2VEZXNjKGl0ZW0pWzAuLjI1XSk7YnJlYWs7ICAgICAgICAgIAorICAgIGNhc2UgQVRfU0hJRUxEOgorICAgICAgaW5kZW50eD01NDsKKyAgICAgIGluZGVudHk9MTA7ICAgCisgICAgICB0ZXh0PXNwcmludGYoIiUtMjBzIixDb21wb3NlRGVzYyhpdGVtKVswLi4yNF0pO2JyZWFrOworICAgIGNhc2UgQVRfQ0xPQUs6CisgICAgICBpbmRlbnR4PTUzOworICAgICAgaW5kZW50eT0xNTsKKyAgICAgIHRleHQ9c3ByaW50ZigiJS0yMHMiLENvbXBvc2VEZXNjKGl0ZW0pWzAuLjI1XSk7YnJlYWs7CisgICAgY2FzZSBBVF9UUk9VU0VSUzoKKyAgICAgIGluZGVudHg9NDk7CisgICAgICBpbmRlbnR5PTE3OworICAgICAgdGV4dD1zcHJpbnRmKCIlLTIwcyIsQ29tcG9zZURlc2MoaXRlbSlbMC4uMjBdKTticmVhazsgICAgIAorICAgIGNhc2UgQVRfUklORzoKKyAgICAgIGluZGVudHg9MDsKKyAgICAgIGluZGVudHk9OTsKKyAgICAgIHRleHQ9c3ByaW50ZigiJTE0cyIsQ29tcG9zZURlc2MoaXRlbSlbMC4uMTddKTticmVhazsKKyAgICBjYXNlIEFUX0dMT1ZFOgorICAgICAgaW5kZW50eD0wOworICAgICAgaW5kZW50eT0xMTsKKyAgICAgIHRleHQ9c3ByaW50ZigiJTE0cyIsQ29tcG9zZURlc2MoaXRlbSlbMC4uMTddKTticmVhazsKKyAgICBjYXNlIEFUX0JFTFQ6CisgICAgICBpbmRlbnR4PTE7CisgICAgICBpbmRlbnR5PTEzOworICAgICAgdGV4dD1zcHJpbnRmKCIlMTRzIixDb21wb3NlRGVzYyhpdGVtKVswLi4xOF0pO2JyZWFrOyAgICAgCisgICAgY2FzZSBBVF9CT09UOgorICAgICAgaW5kZW50eD0xOworICAgICAgaW5kZW50eT0yMDsKKyAgICAgIHRleHQ9c3ByaW50ZigiJTE4cyIsQ29tcG9zZURlc2MoaXRlbSlbMC4uMThdKTticmVhazsKKyAgICBjYXNlICJXYWZmZSI6CisgICAgICBpbmRlbnR4PTE7CisgICAgICBpbmRlbnR5PTE7CisgICAgICB0ZXh0PXNwcmludGYoIiUxOHMiLENvbXBvc2VEZXNjKGl0ZW0pWzAuLjI1XSk7CisgICAgICBpZiAoaXRlbS0+UXVlcnlQcm9wKFBfTlJfSEFORFMpID4gMSAmJgorICAgICAgICAgIHRoaXNfcGxheWVyKCkgJiYKKyAgICAgICAgICAhKHRoaXNfcGxheWVyKCktPlF1ZXJ5QXJtb3JCeVR5cGUoQVRfU0hJRUxEKSkpCisgICAgICAgIEFkZERlc2NyaXB0aW9uKHBpYywgQVRfU0hJRUxELCBpdGVtKTticmVhazsKKyAgICBkZWZhdWx0OiByZXR1cm47CisgIH0KKyAgZm9yIChpPTA7aTxzaXplb2YodGV4dCk7aSsrKQorICAgIHBpYys9KFsoODAqaW5kZW50eStpbmRlbnR4K2kpOnRleHRbaS4uaV07Ml0pOworfQorCit2YXJhcmdzIHN0YXRpYyB2b2lkIENvbmZpZ3VyZUNvbG9ycyhzdHJpbmcgdGV4dCkKK3sgCisgIG1hcHBpbmcgY29uZmlnLCBkaXNwbGF5OworICBzdHJpbmcgKnN0cnM7CisgIAorICBpZiAoIW9iamVjdHAodGhpc19wbGF5ZXIoKSkpIHJldHVybjsKKyAgCisgIGlmICh0aGlzX3BsYXllcigpLT5JbkZpZ2h0KCkpCisgIHsKKyAgICB3cml0ZShicmVha19zdHJpbmcoCisgICAgICAiSW0gS2FtcGY/IE5hIER1IGhhc3QgTmVydmVuLCBkYXMgbGFzc2VuIHdpciBkb2NoIG1hbCBsaWViZXIhICIKKyAgICAgICJQcm9iaWVyIGVzIGRhbmFjaCBub2NobWFsLi4uIiwgNzgpKTsKKyAgICByZXR1cm47CisgIH0KKyAgCisgIGlmIChzdHJpbmdwKHRleHQpKSB0ZXh0PWxvd2VyX2Nhc2UodGV4dCk7CisgIAorICBpZiAodGV4dD09Im9rIikKKyAgeworICAgIHdyaXRlKCJGYXJia29uZmlndXJhdGlvbiBiZWVuZGV0LlxuIik7CisgICAgcmV0dXJuOworICB9CisKKyAgLy8iYW5zaV9jb25maWciLCBkZWYgaW4gaW52bWFzdGVyLmgKKyAgY29uZmlnPXRoaXNfcGxheWVyKCktPlF1ZXJ5UHJvcChQX0lOVk1BU1RFUl9DT05GSUcpfHwoW10pOworICBkaXNwbGF5PWRlZmF1bHRfY29uZmlnK2NvbmZpZzsKKyAgCisgIGlmICghdGV4dCB8fCB0ZXh0PT0iIikKKyAgeworICAgIHdyaXRlKCAKKyAgICAiKioqIEZhcmJrb25maWd1cmF0aW9uIGZ1ZXIgZGVuIEF1c3J1ZXN0dW5nc2JlZmVobCAqKipcblxuIgorICAgICIgRmFyYmU6ICAgICAgICAgICAgICAgICAgICAgd2lyZCBkYXJnZXN0ZWxsdCBtaXQ6XG4iCisgICAgIi0tLS0tLS0tLS0tLS0tLS0tLSAgICAgICAgICAtLS0tLS0tLS0tLS0tLS0tLS0tLVxuIgorICAgICIgSGludGVyZ3J1bmQgICAgICAgICAgICAgICAgICIrQ09MT1JOQU1FU1tkaXNwbGF5WzhdXSsiXG4iCisgICAgIiBTY2h3YXJ6ICAgICAgICAgICAgICAgICAgICAgIitDT0xPUk5BTUVTW2Rpc3BsYXlbMF1dKyJcbiIKKyAgICAiIFJvdCAgICAgICAgICAgICAgICAgICAgICAgICAiK0NPTE9STkFNRVNbZGlzcGxheVsxXV0rIlxuIgorICAgICIgR3J1ZW4gICAgICAgICAgICAgICAgICAgICAgICIrQ09MT1JOQU1FU1tkaXNwbGF5WzJdXSsiXG4iCisgICAgIiBHZWxiICAgICAgICAgICAgICAgICAgICAgICAgIitDT0xPUk5BTUVTW2Rpc3BsYXlbM11dKyJcbiIKKyAgICAiIEJsYXUgICAgICAgICAgICAgICAgICAgICAgICAiK0NPTE9STkFNRVNbZGlzcGxheVs0XV0rIlxuIgorICAgICIgTWFnZW50YSAgICAgICAgICAgICAgICAgICAgICIrQ09MT1JOQU1FU1tkaXNwbGF5WzVdXSsiXG4iCisgICAgIiBUdWVya2lzICAgICAgICAgICAgICAgICAgICAgIitDT0xPUk5BTUVTW2Rpc3BsYXlbNl1dKyJcbiIKKyAgICAiIFdlaXNzICAgICAgICAgICAgICAgICAgICAgICAiK0NPTE9STkFNRVNbZGlzcGxheVs3XV0rIlxuXG4iCisgICAgIkZhcmJlIGFlbmRlcm4gbWl0ICc8ZmFyYmU+IDxnZXd1ZW5zY2h0ZSBmYXJiZT4nLlxuIgorICAgICJCZWlzcGllbDogJ2dlbGIgcm90Jy5cbiIKKyAgICAiQWxsZXMsIHdhcyBzdGFuZGFyZG1hZXNzaWcgZ2VsYiB3YWVyZSwgd3VlcmRlIGRhbm4gbWl0IGRlciBBTlNJLUZhcmJlIFxuIgorICAgICJSb3QgZGFyZ2VzdGVsbHQuXG4iCisgICAgIkRlciBIaW50ZXJncnVuZCBrYW5uIHp1c2FldHpsaWNoIGRpZSBGYXJiZSAna2VpbmUnIGhhYmVuLCBiZWkgZGVyIGRlciBcbiIKKyAgICAiSGludGVyZ3J1bmQgZWJlbiB1ZWJlcmhhdXB0IG5pY2h0IGdlZmFlcmJ0IHdpcmQuXG4iCisgICAgIkJlaXNwaWVsOiAnaGludGVyZ3J1bmQga2VpbmUnLiBTY2hhbHRldCBkaWUgSGludGVyZ3J1bmRmYXJiZSBhdXMuXG5cbiIKKyAgICAiQmVlbmRlbiBtaXQgJ29rJy4gXG4iCisgICAgIldpZWRlcmhvbHVuZyBkZXIgRmFyYmxpc3RlIG1pdCA8UmV0dXJuPi5cbiIKKyAgICAiRmFyYmxpc3RlIGF1ZiBTdGFuZGFyZCB6dXJ1ZWNrc2V0emVuIG1pdCAncmVzZXQnLlxuIik7CisgIH0KKyAgZWxzZQorICBpZiAodGV4dD09InJlc2V0IikKKyAgeworICAgIHRoaXNfcGxheWVyKCktPlNldChQX0lOVk1BU1RFUl9DT05GSUcsIFNBVkUsIEZfTU9ERV9BRCk7ICAgIAorICAgIHRoaXNfcGxheWVyKCktPlNldFByb3AoUF9JTlZNQVNURVJfQ09ORklHLCAwKTsKKyAgICB3cml0ZSgiRmFyYmVuIHp1cnVlY2tnZXNldHp0IVxuIik7ICAgIAorICB9CisgIGVsc2UKKyAgeworICAgIGlmICggc2l6ZW9mKHN0cnM9ZXhwbG9kZSh0ZXh0LCAiICIpLSh7IiJ9KSkgIT0yIAorICAgICAgfHwgIW1lbWJlcigoQ09MT1JDT0RFUy0oWyJrZWluZSJdKSksIHN0cnNbMF0pCisgICAgICB8fCAhbWVtYmVyKChDT0xPUkNPREVTLShbImhpbnRlcmdydW5kIl0pKSwgc3Ryc1sxXSkKKyAgICAgIHx8ICgoc3Ryc1swXSE9ImhpbnRlcmdydW5kIikgJiYgKHN0cnNbMV09PSJrZWluZSIpKSApIAorICAgIHsKKyAgICAgIHdyaXRlKCJGYWxzY2hlIEVpbmdhYmUuXG4iCisgICAgICAgICAgICAiRm9ybWF0OiA8ZmFyYmV8aGludGVyZ3J1bmQ+IDx6dWdld2llc2VuZSBGYXJiZT5cbiIKKyAgICAgICAgICAgICJBYmJyZWNoZW4gbWl0ICdvaycuXG4iKTsKKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgIGlmIChDT0xPUkNPREVTW3N0cnNbMV1dPT1kZWZhdWx0X2NvbmZpZ1tDT0xPUkNPREVTW3N0cnNbMF1dXSkKKyAgICAgICAgY29uZmlnLT0oW0NPTE9SQ09ERVNbc3Ryc1swXV1dKTsKKyAgICAgIGVsc2UKKyAgICAgICAgY29uZmlnKz0oW0NPTE9SQ09ERVNbc3Ryc1swXV06Q09MT1JDT0RFU1tzdHJzWzFdXV0pOworICAgICAgaWYgKCFzaXplb2YoY29uZmlnKSkKKyAgICAgIHsKKyAgICAgICAgdGhpc19wbGF5ZXIoKS0+U2V0KFBfSU5WTUFTVEVSX0NPTkZJRywgU0FWRSwgRl9NT0RFX0FEKTsgICAgCisgICAgICAgIHRoaXNfcGxheWVyKCktPlNldFByb3AoUF9JTlZNQVNURVJfQ09ORklHLCAwKTsKKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgIHsKKyAgICAgICAgdGhpc19wbGF5ZXIoKS0+U2V0UHJvcChQX0lOVk1BU1RFUl9DT05GSUcsIGRlZXBfY29weShjb25maWcpKTsKKyAgICAgICAgdGhpc19wbGF5ZXIoKS0+U2V0KFBfSU5WTUFTVEVSX0NPTkZJRywgU0FWRSwgRl9NT0RFX0FTKTsgICAgICAgIAorICAgICAgfQorICAgICAgd3JpdGUoIk9rLCBGYXJiZSBnZXdhZWhsdCFcbiIpOworICAgIH0KKyAgfQorICBpbnB1dF90bygiQ29uZmlndXJlQ29sb3JzIiwgSU5QVVRfUFJPTVBULCAiXG5FaW5nYWJlOiAiKTsKK30KKworCitzdHJpbmcqIGFybW91cl9vcmRlcj0oeyAKKyAgICBBVF9IRUxNRVQsIEFUX0FNVUxFVCwgQVRfUVVJVkVSLCBBVF9BUk1PVVIsIEFUX0NMT0FLLAorICBBVF9HTE9WRSwgQVRfUklORywgQVRfQkVMVCwKKyAgQVRfVFJPVVNFUlMsIEFUX0JPT1QsIEFUX1NISUVMRCwgQVRfTUlTQ30pOyAKKworbWFwcGluZyB3ZWFwb25fbmFtZXM9KFsKKwkJICAgICAgIFdUX1NQRUFSIDogIlNwZWVyIiwKKwkJICAgICAgIFdUX1NXT1JEIDogIlNjaHdlcnQiLAorCQkgICAgICAgV1RfU1RBRkYgOiAiS2FtcGZzdGFiIiwKKwkJICAgICAgIFdUX1dISVAgIDogIlBlaXRzY2hlIiwKKwkJICAgICAgIFdUX0NMVUIgIDogIktldWxlIiwKKwkJICAgICAgIFdUX0tOSUZFIDogIk1lc3NlciIsCisJCSAgICAgICBXVF9NSVNDICA6ICJJcmdlbmR3YXMiLAorCQkgICAgICAgV1RfTUFHSUMgOiAiQXJ0ZWZha3QiLAorCQkgICAgICAgV1RfQVhFICAgOiAiQXh0IiwKKwkgICAgICAgV1RfUkFOR0VEX1dFQVBPTiA6ICJGZXJud2FmZmUiCisJCSAgICAgICBdKTsKKworc3RyaW5nIFNpbXBsZUludihvYmplY3QgcGxheWVyKSB7CisgIG9iamVjdCogYXJtb3Vycz1wbGF5ZXItPlF1ZXJ5UHJvcChQX0FSTU9VUlMpOworICBpbnQgY291bnQ9c2l6ZW9mKGFybW91cl9vcmRlcik7CisgIHN0cmluZyogbGlzdD1hbGxvY2F0ZShjb3VudCk7CisgIHN0cmluZyByZXN1bHQ9IkF1c3J1ZXN0dW5nXG4iOworICBpbnQgaTsKKworICBmb3JlYWNoKG9iamVjdCBvYjogYXJtb3VycykgeworICAgIGlmICghb2JqZWN0cChvYikpIGNvbnRpbnVlOworICAgICAgaW50IGlkeCA9IG1lbWJlcihhcm1vdXJfb3JkZXIsIG9iLT5RdWVyeVByb3AoUF9BUk1PVVJfVFlQRSkpOwkgICAgICAKKyAgICAgIGlmIChpZHg+PTApCisgICAgICAgIGxpc3RbaWR4XT1vYi0+UXVlcnlQcm9wKFBfU0hPUlQpOworICB9CisKKyAgLy8gQVRfTUlTQyAobGV0enRlcyBFbGVtZW50IGluIGxpc3QgdW5kIGFybW91cl9vcmRlcikgd2VnbGFzc2VuLgorICBmb3IgKGk9MDtpPGNvdW50LTE7aSsrKSB7CisgICAgcmVzdWx0Kz1zcHJpbnRmKCIlLTIwcyAlLTU3c1xuIixhcm1vdXJfb3JkZXJbaV0sbGlzdFtpXSB8fCAiIik7CisgIH0KKworICBvYmplY3Qgb2I9b2I9cGxheWVyLT5RdWVyeVByb3AoUF9XRUFQT04pOworICBpZiAob2JqZWN0cChvYikpIHsKKyAgICByZXN1bHQrPXNwcmludGYoIiUtMjBzICUtNTdzXG4iLAorCQkgICAgKG9iLT5RdWVyeVByb3AoUF9OUl9IQU5EUyk9PTEgPyAiRWluaGFuZC0iOiJad2VpaGFuZC0iKQorCQkgICAgK3dlYXBvbl9uYW1lc1tvYi0+UXVlcnlQcm9wKFBfV0VBUE9OX1RZUEUpXSwKKwkJICAgIG9iLT5RdWVyeVByb3AoUF9TSE9SVCkpOworICB9IGVsc2UgcmVzdWx0Kz0iS2VpbmUgV2FmZmVcbiI7CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKy8vIHRoZSBtYWluIGZ1bmN0aW9uIGNhbGxlZCBieSB0aGUgcGxheWVyIG9iamVjdC4KKy8vIGRldGVybWluZXMgZ2VuZGVyLCB0aGVuIGFkZHMgYXJtb3Ivd2VhcG9uIGdyYXBoaWNzCisvLyBkeW5hbWljYWxseS4gc3RpbGwgdmVyeSBmYXN0IGR1ZSB0byB0aGUgdXNlIG9mIHRoZSAiKyIgb3BlcmF0b3IsCisvLyBzZWUgYWJvdmUuCit2b2lkIFNob3dJbnYob2JqZWN0IHBsYXllciwgc3RyaW5nIGFyZykKK3sKKyAgc3RyaW5nIGdlbmRlciwgdHlwZTsKKyAgbWFwcGluZyBwaWM7CisgIGludCBpOworICBvYmplY3QgaXRlbTsKKworICBpZiAoIW9iamVjdHAocGxheWVyKXx8IWludGVyYWN0aXZlKHBsYXllcikpIHJldHVybjsKKworICAvLyBzcGxpdCBhcmdzLgorICBzdHJpbmcgKmFyZ3M7CisgIGlmIChzdHJpbmdwKGFyZykpCisgICAgYXJncyA9IGV4cGxvZGUobG93ZXJfY2FzZShhcmcpLCAiICIpIC0gKHsiICJ9KTsKKyAgZWxzZQorICAgIGFyZ3MgPSAoe30pOworCisgIGlmIChtZW1iZXIoYXJncywgImZhcmJlbiIpID4gLTEpIHsKKyAgICAgIENvbmZpZ3VyZUNvbG9ycygpOworICAgICAgcmV0dXJuOworICB9CisKKyAgaWYgKG1lbWJlcihhcmdzLCAiLWsiKSA+IC0xIHx8IHBsYXllci0+UXVlcnlQcm9wKFBfTk9fQVNDSUlfQVJUKSkgeworICAgIHRlbGxfb2JqZWN0KHBsYXllciwgU2ltcGxlSW52KHBsYXllcikpOworICAgIHJldHVybjsKKyAgfQorCisgIGdlbmRlcj1wbGF5ZXItPlF1ZXJ5UHJvcChQX0dFTkRFUik9PUZFTUFMRT8iX2ZlbWFsZSI6Il9tYWxlIjsKKyAgcGljPWRlZXBfY29weShkYXRhWyJiYXNlIitnZW5kZXJdKTsKKyAgcGljKz1kYXRhWyJCZXNjaHJpZnR1bmciXTsKKyAgZm9yIChpPXNpemVvZihhcm1vdXJfdHlwZXMpLTE7aT49MDtpLS0pCisgICAgaWYgKG9iamVjdHAoaXRlbT1wbGF5ZXItPlF1ZXJ5QXJtb3VyQnlUeXBlKGFybW91cl90eXBlc1tpXSkpKQorICAgIHsKKyAgICAgIHBpYys9ZGF0YVthcm1vdXJfdHlwZXNbaV0rZ2VuZGVyXTsKKyAgICAgIEFkZERlc2NyaXB0aW9uKHBpYywgYXJtb3VyX3R5cGVzW2ldLCBpdGVtKTsKKyAgICB9CisgIGlmIChpdGVtPXBsYXllci0+UXVlcnlQcm9wKFBfV0VBUE9OKSkKKyAgeworICAgIHBpYys9ZGF0YVsoVkFMSURfV0VBUE9OX1RZUEUodHlwZT1pdGVtLT5RdWVyeVByb3AoUF9XRUFQT05fVFlQRSkpKT8KKyAgICAgIHR5cGU6V1RfTUlTQ107CisgICAgQWRkRGVzY3JpcHRpb24ocGljLCAiV2FmZmUiLCBpdGVtKTsKKyAgfSAgICAgIAorICBpZiAocGxheWVyLT5RdWVyeVByb3AoUF9UVFkpIT0iYW5zaSIpCisgICAgcGxheWVyLT5Nb3JlKE1hcHBpbmcyUGxhaW5UZXh0KHBpYykpOworICBlbHNlCisgICAgcGxheWVyLT5Nb3JlKE1hcHBpbmcyQ29sb3JlZFRleHQocGljLCBwbGF5ZXIpKTsKKyAgREIoZ2V0ZXVpZChwbGF5ZXIpKyIgZXZhbCBjb3N0OiAiKygxMDAwMDAwLWdldF9ldmFsX2Nvc3QoKSkrIiB0aWNrcy5cbiIpOworfQorCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL2ludm1hc3Rlci9pbnZtYXN0ZXIuaCBiL3N0ZC9wbGF5ZXIvaW52bWFzdGVyL2ludm1hc3Rlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg4MjFiNjMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL2ludm1hc3Rlci9pbnZtYXN0ZXIuaApAQCAtMCwwICsxLDIxIEBACisjZGVmaW5lIElOVlBBVEggIi9zdGQvcGxheWVyL2ludm1hc3Rlci8iCisjZGVmaW5lIERCKHgpCisvKgorI2RlZmluZSBEQih4KSBpZiAoZmluZF9wbGF5ZXIoInJpa3VzIikpIFwKKyAgICAgICAgICAgICAgICAgICB0ZWxsX29iamVjdChmaW5kX3BsYXllcigicmlrdXMiKSwgXAorICAgICAgICAgICAgICAgICAgICAgYnJlYWtfc3RyaW5nKHgsIDc4LCAiSU5WTUFTVEVSOiAiLCAxKSk7CisqLworI2RlZmluZSBQX0lOVk1BU1RFUl9DT05GSUcgImludm1hc3Rlcl9jb25maWciCisjZGVmaW5lIENPTE9STkFNRVMgKHsiU2Nod2FyeiIsIlJvdCIsIkdydWVuIiwiR2VsYiIsXAorICAgICAgICAgICAgICAgICAgICAgIkJsYXUiLCJNYWdlbnRhIiwiVHVlcmtpcyIsIldlaXNzIiwiS2VpbmUifSkKKyNkZWZpbmUgQ09MT1JDT0RFUyAoWyJzY2h3YXJ6IjowLFwKKyAgICAgICAgICAgICAgICAgICAgICJyb3QiOjEsXAorICAgICAgICAgICAgICAgICAgICAgImdydWVuIjoyLFwKKyAgICAgICAgICAgICAgICAgICAgICJnZWxiIjozLFwKKyAgICAgICAgICAgICAgICAgICAgICJibGF1Ijo0LFwKKyAgICAgICAgICAgICAgICAgICAgICJtYWdlbnRhIjo1LFwKKyAgICAgICAgICAgICAgICAgICAgICJ0dWVya2lzIjo2LFwKKyAgICAgICAgICAgICAgICAgICAgICJ3ZWlzcyI6NyxcCisgICAgICAgICAgICAgICAgICAgICAia2VpbmUiOjgsXAorICAgICAgICAgICAgICAgICAgICAgImhpbnRlcmdydW5kIjo4XSkKKyNkZWZpbmUgZGVmYXVsdF9jb25maWcgKFswOjAsIDE6MSwgMjoyLCAzOjMsIDQ6NCwgNTo1LCA2OjYsIDc6NywgODowXSkKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvbGlmZS5jIGIvc3RkL3BsYXllci9saWZlLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzNmMWZmNwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvbGlmZS5jCkBAIC0wLDAgKzEsODQxIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL2xpZmUuYyAtLSBwbGF5ZXIgbGlmZSBoYW5kbGluZworLy8KKy8vICRJZDogbGlmZS5jIDkzOTcgMjAxNS0xMi0xMSAyMDoyOToyNlogWmVzc3RyYSAkCisKKy8vIERlZmluZXMgc29tZSB0aGluZ3Mgd2hpY2ggYXJlIGRpZmZlcmVudCB0aGFuIGluIGxpdmluZy5jCisvLyBPbmUgZXhhbXBsZSBpcyB0aGUgaGVhcnRfYmVhdCgpLgorCisvLyBQcm9wZXJ0aWVzCisvLyAgUF9BR0UgICAgICAgICAgIC0tIEFnZQorCisjcHJhZ21hIHN0cm9uZ190eXBlcywgc2F2ZV90eXBlcywgcnR0X2NoZWNrcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL2xpdmluZy9saWZlIjsKKworI2luY2x1ZGUgPHJ0bGltaXRzLmg+CisjaW5jbHVkZSA8ZGVidWdfaW5mby5oPgorCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvYmFzZS5oPgorI2luY2x1ZGUgPHBsYXllci9saWZlLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8cGxheWVyL2NvbW0uaD4KKyNpbmNsdWRlIDxwbGF5ZXIvZ21jcC5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGhvb2suaD4KKworI2luY2x1ZGUgPGxpdmluZy9saWZlLmg+CisjaW5jbHVkZSA8cGxheWVyL3BrbG9nLmg+CisjaW5jbHVkZSA8cGxheWVyL2NvbWJhdC5oPgorI2luY2x1ZGUgPGhlYWx0aC5oPgorI2luY2x1ZGUgPGxpdmluZy9jb21iYXQuaD4KKyNpbmNsdWRlIDxhdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8ZGVmdWVsLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorCisvLyBEaWUgRm9sZ2VuIGVpbmVzIFRvZGVzIHdpcmtlbiA0IFN0dW5kZW4gbGFuZyBuYWNoCisjZGVmaW5lIFNVRkZFUl9USU1FIDcyMDAKKyNkZWZpbmUgUF9ERUFUSF9JTkZPICJkZWF0aF9pbmZvIgorCitpbnQgYWdlOyAgICAgICAgICAgICAgICAgIC8qIE51bWJlciBvZiBoZWFydCBiZWF0cyBvZiB0aGlzIGNoYXJhY3Rlci4gKi8KKworcHJpdmF0ZSBpbnQgc3VmZmVyX3RpbWU7CitzdGF0aWMgaW50IHRpbWVfdG9fc2F2ZTsgIC8qIHdoZW4gdG8gbmV4dCBzYXZlIHBsYXllciAqLworcHJpdmF0ZSBub3NhdmUgaW50IGRpZV9pbl9wcm9ncmVzczsgLy8gc2VtYXBob3JlIGZ1ZXIgZGllKCktQXVmcnVmZS4KKworc3RhdGljIGludCBfc2V0X3BsYXllcmtpbGxzKCBpbnQgdmFsICk7CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgICAgOjpjcmVhdGUoKTsKKyAgICBTZXQoUF9BR0UsIC0xLCBGX1NFVF9NRVRIT0QpOworICAgIFNldChQX0FHRSwgUFJPVEVDVEVELCBGX01PREUpOworICAgIFNldCggUF9LSUxMUywgU0FWRXxTRUNVUkVELCBGX01PREVfQVMgKTsKKyAgICBTZXQoIFBfR0hPU1QsIFNBVkUsIEZfTU9ERV9BUyApOworICAgIFNldCggUF9USU1JTkdfTUFQLCBTQVZFfFNFQ1VSRUQsIEZfTU9ERV9BUyApOworICAgIFNldCggUF9MQVNUX0RFQVRIX1RJTUUsIFNBVkV8U0VDVVJFRCwgRl9NT0RFX0FTICk7CisgICAgU2V0KCBQX0RFQVRIX0lORk8sIFNBVkV8U0VDVVJFRCwgRl9NT0RFX0FTICk7CisgICAgU2V0KCBQX0RFRlVFTF9MSU1JVF9GT09ELFBST1RFQ1RFRCxGX01PREVfQVMpOworICAgIFNldCggUF9ERUZVRUxfTElNSVRfRFJJTkssUFJPVEVDVEVELEZfTU9ERV9BUyk7CisgICAgU2V0KCBQX0RFRlVFTF9USU1FX0ZPT0QsUFJPVEVDVEVELEZfTU9ERV9BUyk7CisgICAgU2V0KCBQX0RFRlVFTF9USU1FX0RSSU5LLFBST1RFQ1RFRCxGX01PREVfQVMpOworICAgIFNldCggUF9ERUZVRUxfQU1PVU5UX0ZPT0QsUFJPVEVDVEVELEZfTU9ERV9BUyk7CisgICAgU2V0KCBQX0RFRlVFTF9BTU9VTlRfRFJJTkssUFJPVEVDVEVELEZfTU9ERV9BUyk7CisgICAgb2ZmZXJIb29rKEhfSE9PS19IUCwxKTsKKyAgICBvZmZlckhvb2soSF9IT09LX1NQLDEpOworICAgIC8vIFBfVElNSU5HX01BUCBhdWZyYWV1bWVuLCBhYmVyIHplaXR2ZXJ6b2VnZXJ0LCB3ZWlsIGpldHp0IGRpZSBEYXRlbiBub2NoCisgICAgLy8gbmljaHQgYXVzIGRlbSBTYXZlZmlsZSBnZWxhZGVuIHd1cmRlbi4KKyAgICBjYWxsX291dCgjJ2V4cGlyZV90aW1pbmdfbWFwLCA0KTsKK30KKworLy8gY2FsbGVkIGZyb20gYmFzZS5jIGluIFJlY29ubmVjdCgpCitwcm90ZWN0ZWQgdm9pZCByZWNvbm5lY3QoKSB7CisgIGV4cGlyZV90aW1pbmdfbWFwKCk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9wbGF5ZXJraWxscyggaW50IHZhbCApCit7CisgICAgc3RyaW5nIHRtcDsKKyAgICBpbnQgcGxheWVya2lsbHM7CisKKyAgICAvLyBpc3QgZGVyIFNldHplciBpbiBlaW5lciBBcmVuYS9TY2hhdHRlbndlbHQuIERhbm4gbmljaHQuIChKYSwgQnVnIGlzdCwKKyAgICAvLyBkYXNzIEVNcyBhdXMgU2NoYXR0ZW53ZWx0L0FyZW5hIGhlcmF1cyBhdWNoIGRhcyBQSy1GbGFnIG5pY2h0CisgICAgLy8genVydWVja3NldHplbiBrb2VubmVuLikKKyAgICBpZiAoIHByZXZpb3VzX29iamVjdCgxKSAmJiBlbnZpcm9ubWVudChwcmV2aW91c19vYmplY3QoMSkpICYmCisgICAgICAgICAodG1wID0gb2JqZWN0X25hbWUoZW52aXJvbm1lbnQocHJldmlvdXNfb2JqZWN0KDEpKSkpICYmCisgICAgICAgICBDaGVja0FyZW5hRmlnaHQocHJldmlvdXNfb2JqZWN0KDEpKSApCisgICAgICAgIHJldHVybiAwOworCisgICAgdG1wID0gc3ByaW50ZiggIiVPOiAlcyAlTyAlcyIsCisgICAgICAgICAgICAgICAgICAgcHJldmlvdXNfb2JqZWN0KDEpIHx8IHRoaXNfaW50ZXJhY3RpdmUoKSB8fCB0aGlzX3BsYXllcigpLAorICAgICAgICAgICAgICAgICAgIGdldHVpZChNRSksIHZhbCwgZHRpbWUodGltZSgpKSApOworCisgICAgcGxheWVya2lsbHMgPSBRdWVyeShQX0tJTExTKTsKKworICAgIGlmKCBpbnRwKHZhbCkgJiYgdmFsID49IDAgKQorICAgICAgICBpZiggcHJldmlvdXNfb2JqZWN0KDEpICYmIElTX0FSQ0goZ2V0dWlkKHByZXZpb3VzX29iamVjdCgxKSkpICYmCisgICAgICAgICAgICB0aGlzX2ludGVyYWN0aXZlKCkgJiYgSVNfQVJDSCh0aGlzX2ludGVyYWN0aXZlKCkpICkKKyAgICAgICAgICAgIHBsYXllcmtpbGxzID0gdmFsOworICAgICAgICBlbHNlCisgICAgICAgICAgICB0bXAgKz0gIiBJTExFR0FMISI7CisgICAgZWxzZQorICAgICAgICBwbGF5ZXJraWxscysrOworCisgICAgaWYgKCAhcHJldmlvdXNfb2JqZWN0KDEpIHx8ICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHByZXZpb3VzX29iamVjdCgxKSkgfHwKKyAgICAgICAgIElTX0xFQVJORVIocHJldmlvdXNfb2JqZWN0KDEpKSApCisgICAgICAgIGxvZ19maWxlKCAiU0VUX0tJTExTIiwgdG1wICsgIlxuIiApOworCisgICAgcmV0dXJuIFNldCggUF9LSUxMUywgcGxheWVya2lsbHMgKTsKK30KKworCitwdWJsaWMgaW50IGRlYXRoX3N1ZmZlcmluZygpCit7CisgICAgaWYgKCBzdWZmZXJfdGltZSA8PSAwICkKKyAgICByZXR1cm4gc3VmZmVyX3RpbWUgPSAwOworCisgICAgcmV0dXJuIDEgKyAoMTAgKiBzdWZmZXJfdGltZSkgLyBTVUZGRVJfVElNRTsKK30KKworCitwcm90ZWN0ZWQgdm9pZCBoZWFydF9iZWF0KCkKK3sKKyAgICBtYXBwaW5nIGRpLCBtb2RzOworCisgICAgKythZ2U7IC8vIGVyc3RtYWwgYWx0ZXJuIDstKQorCisgICAgOjpoZWFydF9iZWF0KCk7CisKKyAgICBpZiAoIGFnZSA+IHRpbWVfdG9fc2F2ZSApeworICAgICAgICBzYXZlX21lKDEpOworICAgICAgICB0aW1lX3RvX3NhdmUgPSBhZ2UgKyA1MDA7CisgICAgfQorCisgICAgLy8gYWxzIGdlaXN0IGhhdCBtYW4gbWl0IGRlbiBtZWlzdGVuIHdlbHRsaWNoZW4gRGluZ2VuIG5pY2h0IGFsbHp1dmllbCB6dQorICAgIC8vIHR1bi4KKyAgICBpZiAoIFF1ZXJ5UHJvcChQX0dIT1NUKSApCisgICAgICAgIHJldHVybjsKKworICAgIGlmICggc3VmZmVyX3RpbWUgPiAwICkKKyAgICAgICAgc3VmZmVyX3RpbWUtLTsKKworICAgIC8vIFRvZGVzZm9sZ2VuIG51ciBhbGxlIDIwIFNla3VuZGVuICgxMCBIQikgY2hlY2tlbi4KKyAgICAvLyBEYXMgaXN0IGltbWVyIG5vY2ggb2Z0IGdlbnVnIHVuZCBzcGFydCBSZWNoZW56ZWl0LgorICAgIGlmICggKGFnZSAlIDEwKSB8fCAhbWFwcGluZ3AoZGkgPSBRdWVyeVByb3AoUF9ERUFUSF9JTkZPKSkgKQorICAgICAgICByZXR1cm47CisKKyAgICBtb2RzID0gUXVlcnlQcm9wKFBfQVRUUklCVVRFU19NT0RJRklFUilbIiNkZWF0aCJdOworICAgIGlmICghbWFwcGluZ3AobW9kcykpIHJldHVybjsKKworICAgIGlmICggbW9kc1tBX1NUUl0gJiYgLS1kaVtBX1NUUl0gPD0gMCkgeworICAgICAgICAvLyBlaW5lbiBBdHRyaWJ1dHNwdW5rdCByZWdlbmVyaWVyZW4KKyAgICAgICAgaWYgKCBtb2RzW0FfU1RSXSA8IC0xICkgeworICAgICAgICAgICAgbW9kc1tBX1NUUl0rKzsKKyAgICAgICAgICAgIGRpW0FfU1RSXSA9ICgxMTAgKyA1ICogKGRpW0FfU1RSLCAxXSArIG1vZHNbQV9TVFJdKSkgLyAxMDsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIG1fZGVsZXRlKCBtb2RzLCBBX1NUUiApOworICAgICAgICAgICAgbV9kZWxldGUoIGRpLCBBX1NUUiApOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKCBtb2RzW0FfQ09OXSAmJiAtLWRpW0FfQ09OXSA8PSAwKSB7CisgICAgICAgIC8vIGVpbmVuIEF0dHJpYnV0c3B1bmt0IHJlZ2VuZXJpZXJlbgorICAgICAgICBpZiAoIG1vZHNbQV9DT05dIDwgLTEgKXsKKyAgICAgICAgICAgIG1vZHNbQV9DT05dKys7CisgICAgICAgICAgICBkaVtBX0NPTl0gPSAoMTEwICsgNSAqIChkaVtBX0NPTiwgMV0gKyBtb2RzW0FfQ09OXSkpIC8gMTA7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBtX2RlbGV0ZSggbW9kcywgQV9DT04gKTsKKyAgICAgICAgICAgIG1fZGVsZXRlKCBkaSwgQV9DT04gKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmICggbW9kc1tBX0RFWF0gJiYgLS1kaVtBX0RFWF0gPD0gMCkgeworICAgICAgICAvLyBlaW5lbiBBdHRyaWJ1dHNwdW5rdCByZWdlbmVyaWVyZW4KKyAgICAgICAgaWYgKCBtb2RzW0FfREVYXSA8IC0xICl7CisgICAgICAgICAgICBtb2RzW0FfREVYXSsrOworICAgICAgICAgICAgZGlbQV9ERVhdID0gKDExMCArIDUgKiAoZGlbQV9ERVgsIDFdICsgbW9kc1tBX0RFWF0pKSAvIDEwOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgbV9kZWxldGUoIG1vZHMsIEFfREVYICk7CisgICAgICAgICAgICBtX2RlbGV0ZSggZGksIEFfREVYICk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoIG1vZHNbQV9JTlRdICYmIC0tZGlbQV9JTlRdIDw9IDApIHsKKyAgICAgICAgLy8gZWluZW4gQXR0cmlidXRzcHVua3QgcmVnZW5lcmllcmVuCisgICAgICAgIGlmICggbW9kc1tBX0lOVF0gPCAtMSApeworICAgICAgICAgICAgbW9kc1tBX0lOVF0rKzsKKyAgICAgICAgICAgIGRpW0FfSU5UXSA9ICgxMTAgKyA1ICogKGRpW0FfSU5ULCAxXSArIG1vZHNbQV9JTlRdKSkgLyAxMDsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIG1fZGVsZXRlKCBtb2RzLCBBX0lOVCApOworICAgICAgICAgICAgbV9kZWxldGUoIGRpLCBBX0lOVCApOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKCBzaXplb2YoZGkpICYmIHNpemVvZihtb2RzKSkKKyAgICAgICAgU2V0UHJvcCggUF9ERUFUSF9JTkZPLCBkaSApOworICAgIGVsc2UKKyAgICAgICAgU2V0UHJvcCggUF9ERUFUSF9JTkZPLCAwICk7CisKKyAgICBTZXRQcm9wKCBQX0FUVFJJQlVURVNfTU9ESUZJRVIsICh7ICIjZGVhdGgiLCBtb2RzIH0pICk7Cit9CisKKworcHVibGljIHZvaWQgZm9yY2Vfc2F2ZSgpIHsKKyAgICB0aW1lX3RvX3NhdmUgPSAwOworfQorCisKK25vbWFzayBwdWJsaWMgaW50IGRvX2RhbWFnZSggaW50IGRhbSwgb2JqZWN0IGVuZW15ICkKK3sKKyAgICBpbnQgaGl0X3BvaW50OworCisgICAgaWYoIFF1ZXJ5UHJvcChQX0dIT1NUKSB8fCBkYW0gPD0gMCApCisgICAgICAgIHJldHVybiAwOworCisgICAgaGl0X3BvaW50ID0gUXVlcnlQcm9wKFBfSFApOworCisgICAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSAmJiBkYW0gPj0gaGl0X3BvaW50ICYmIElTX0xFQVJOSU5HKE1FKSApeworICAgICAgICB0ZWxsX29iamVjdCggTUUsICJEZWluZSBtYWdpc2NoZW4gS3JhZWZ0ZSB2ZXJoaW5kZXJuIERlaW5lbiBUb2QuXG4iICk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICggIW9iamVjdHAoZW5lbXkpICkKKyAgICAgICAgZW5lbXkgPSBwcmV2aW91c19vYmplY3QoKSB8fCB0aGlzX2ludGVyYWN0aXZlKCkgfHwgdGhpc19wbGF5ZXIoKTsKKworICAgIGhpdF9wb2ludCAtPSBkYW07CisKKyAgICBpZiggaGl0X3BvaW50IDwgMCApeworICAgICAgICBpZiAoICFpbnRlcmFjdGl2ZShNRSkgKQorICAgICAgICAgICAgLy8gTmV0enRvdGUgc3RlcmJlbiBuaWNodAorICAgICAgICAgICAgaGl0X3BvaW50ID0gMTA7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgaWYgKCBvYmplY3RwKGVuZW15KSAmJiBpbnRlcmFjdGl2ZSggZW5lbXkgKSAmJiBlbmVteSAhPSBNRSAmJgorICAgICAgICAgICAgICAgICAhUXVlcnlQcm9wKFBfVEVTVFBMQVlFUikgJiYgIUlTX1dJWkFSRChNRSkgJiYKKyAgICAgICAgICAgICAgICAgIUNoZWNrQXJlbmFGaWdodChNRSkgKSB7CisgICAgICAgICAgICAgICAgaWYgKCBRdWVyeVBsQXR0YWNrZWQoZW5lbXkpICkKKyAgICAgICAgICAgICAgICAgICAgaGl0X3BvaW50ID0gMTsKKyAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaGl0X3BvaW50ID0gMDsKKyAgICAgICAgICAgICAgICAgICAgZW5lbXktPlNldFByb3AoIFBfS0lMTFMsIC0xICk7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgbG9nX2ZpbGUoICJLSUxMRVIiLAorICAgICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCAiJXMgJXMoJWQvJWQpIHRvZXRldGUgJXMoJWQvJWQpJXNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0aW1lKHRpbWUoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldHVpZChlbmVteSksIHF1ZXJ5X3dpel9sZXZlbChlbmVteSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpIGVuZW15LT5RdWVyeVByb3AoUF9MRVZFTCksIGdldHVpZChNRSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5X3dpel9sZXZlbChNRSksIFF1ZXJ5UHJvcChQX0xFVkVMKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGhpdF9wb2ludCA/ICIgTk9UV0VIUj0+S0VJTiBQSyIgOiAiIikgKSApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7IAorICAgICAgICAgICAgICAgIHN0cmluZyBraWxsZXJuYW1lOworICAgICAgICAgICAgICAgIGlmIChvYmplY3RwKGVuZW15KSkKKyAgICAgICAgICAgICAgICAgICAga2lsbGVybmFtZT1zcHJpbnRmKCIlcyAoJXMpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIEJMVUVfTkFNRShlbmVteSksIFJFQUxfVUlEKGVuZW15KSk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBraWxsZXJuYW1lPSI/Pz8gKD8/PykiOyAKKworICAgICAgICAgICAgICAgIGlmICggIVF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpICkKKyAgICAgICAgICAgICAgICAgICAgY3JlYXRlX2tpbGxfbG9nX2VudHJ5KGtpbGxlcm5hbWUsIGVuZW15ICk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICggZW5lbXkgKQorICAgICAgICAgICAgICAgIGVuZW15LT5TdG9wSHVudEZvciggTUUsIDEgKTsKKworICAgICAgICAgICAgbWFwX29iamVjdHMoIFF1ZXJ5RW5lbWllcygpWzBdLCAiU3RvcEh1bnRGb3IiLCBNRSwgMSApOworICAgICAgICAgICAgU3RvcEh1bnRpbmdNb2RlKDEpOworCisgICAgICAgICAgICBTZXQoIFBfS0lMTEVSLCBlbmVteSApOworICAgICAgICAgICAgZGllKCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBTZXRQcm9wKCBQX0hQLCBoaXRfcG9pbnQgKTsKKyAgICByZXR1cm4gZGFtOworfQorCisKKy8vIExvZXNjaHQgaW0gc3RlcmJlbmRlbiBTcGllbGVyIGRpZSAna29lcnBlcmFiaGFlbmdpZ2VuJyBQcm9wZXJ0aWVzCitwcml2YXRlIHZvaWQgcmVzZXRfbXlfcHJvcGVydGllcygpCit7CisgIC8vIExvZXNjaGVuIGRlciBQcm9wZXJ0aWVzCisgIGlmICggUXVlcnlQcm9wKFBfUE9JU09OKSApCisgIHsKKyAgICAgLy8gRG9uJ3QgZGllIHR3aWNlICdjYXVzZSBvZiB0aGUgc2FtZSBwb2lzb24KKyAgICAgU2V0KCBQX1BPSVNPTiwgMCwgRl9TRVRfTUVUSE9EICk7CisgICAgIFNldCggUF9QT0lTT04sIDAsIEZfUVVFUllfTUVUSE9EICk7CisgICAgIFNldFByb3AoIFBfUE9JU09OLCAwICk7CisgIH0KKworICBTZXQoIFBfRlJPRywgMCwgRl9RVUVSWV9NRVRIT0QgKTsgCisgIFNldCggUF9GUk9HLCAwLCBGX1NFVF9NRVRIT0QgKTsKKyAgU2V0UHJvcCggUF9GUk9HLCAwICk7IC8vIERhbWl0IGRpZSBBdHRyaWJ1dGUgYXVjaCBzdGltbWVuLgorICBTZXQoIFBfQUxDT0hPTCwgMCwgRl9RVUVSWV9NRVRIT0QgKTsKKyAgU2V0KCBQX0FMQ09IT0wsIDAsIEZfU0VUX01FVEhPRCApOworICBTZXRQcm9wKFBfQUxDT0hPTCwgMCApOworICBTZXQoIFBfRFJJTkssIDAsIEZfUVVFUllfTUVUSE9EICk7CisgIFNldCggUF9EUklOSywgMCwgRl9TRVRfTUVUSE9EICk7CisgIFNldFByb3AoUF9EUklOSywgMCApOworICBTZXQoIFBfRk9PRCwgMCwgRl9RVUVSWV9NRVRIT0QgKTsKKyAgU2V0KCBQX0ZPT0QsIDAsIEZfU0VUX01FVEhPRCApOworICBTZXRQcm9wKFBfRk9PRCwgMCApOworICBTZXQoIFBfQkxJTkQsIDAsIEZfUVVFUllfTUVUSE9EICk7CisgIFNldCggUF9CTElORCwgMCwgRl9TRVRfTUVUSE9EICk7CisgIFNldFByb3AoUF9CTElORCwgMCApOworICBTZXQoIFBfREVBRiwgMCwgRl9RVUVSWV9NRVRIT0QgKTsKKyAgU2V0KCBQX0RFQUYsIDAsIEZfU0VUX01FVEhPRCApOworICBTZXRQcm9wKFBfREVBRiwgMCApOworICBTZXQoIFBfTUFYX0hBTkRTLCAwLCBGX1FVRVJZX01FVEhPRCApOworICBTZXQoIFBfTUFYX0hBTkRTLCAwLCBGX1NFVF9NRVRIT0QgKTsKKyAgU2V0UHJvcCggUF9NQVhfSEFORFMsIDIgKTsKKyAgU2V0KCBQX0hBTkRTX1VTRURfQlksIDAsIEZfUVVFUllfTUVUSE9EICk7CisgIFNldCggUF9IQU5EU19VU0VEX0JZLCAwLCBGX1NFVF9NRVRIT0QgKTsKKyAgU2V0UHJvcCggUF9IQU5EU19VU0VEX0JZLCAoe30pICk7CisgIFNldCggUF9QQVJBLCAwICk7CisgIFNldCggUF9OT19SRUdFTkVSQVRJT04sIDAsIEZfUVVFUllfTUVUSE9EICk7CisgIFNldCggUF9OT19SRUdFTkVSQVRJT04sIDAsIEZfU0VUX01FVEhPRCApOworICBTZXRQcm9wKFBfTk9fUkVHRU5FUkFUSU9OLCAwICk7CisgIFNldCggUF9UTVBfTU9WRV9IT09LLCAwLCBGX1FVRVJZX01FVEhPRCApOworICBTZXQoIFBfVE1QX01PVkVfSE9PSywgMCwgRl9TRVRfTUVUSE9EICk7CisgIFNldFByb3AoUF9UTVBfTU9WRV9IT09LLCAwICk7CisgIFNldCggUF9MQVNUX0RFQVRIX1RJTUUgLCB0aW1lKCkgKTsKKyAgLy8gZGFtaXQgZGVyIFRlZGR5IG8uYWUuIG1pdGJla29tbXQsIGRhc3MgbWFuIGpldHp0IHRvdCBpc3QgXTotPgorICBTZXRQcm9wKCBQX0hQLCAwICk7CisgIFNldFByb3AoIFBfU1AsIDAgKTsKK30KKwordmFyYXJncyBwcm90ZWN0ZWQgaW50IHNlY29uZF9saWZlKCBvYmplY3QgY29ycHNlICkKK3sKKyAgICBpbnQgbG9zdF9leHAsIGxldmVsOworICAgIC8vIEVzIGdpYnQgRnVua3Rpb25lbiwgZGllIHNvbGx0ZSBtYW4gbmljaHQgcGVyIEhhbmQgYXVmcnVmZW4gZHVlcmZlbiA7LSkKKyAgICBpZiAoIGV4dGVybl9jYWxsKCkgJiYgcHJldmlvdXNfb2JqZWN0KCkgIT0gTUUgKQorICAgICAgICByZXR1cm4gMDsKKworICAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgJiYgSVNfTEVBUk5JTkcoTUUpICl7CisgICAgICAgIHRlbGxfb2JqZWN0KCBNRSwgIlNlaSBmcm9oLCBkYXNzIER1IHVuc3RlcmJsaWNoIGJpc3QsIHNvbnN0IHdhZXJlICIKKyAgICAgICAgICAgICAgICAgICAgICJlcyBlYmVuIHp1IEVuZGUgZ2V3ZXNlbi5cbiIgKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgaWYgKCAhSVNfU0VFUihNRSkgfHwgKGxldmVsID0gUXVlcnlQcm9wKFBfTEVWRUwpKSA8IDIwICkKKyAgICAgICAgbG9zdF9leHAgPSBRdWVyeVByb3AoUF9YUCkgLyAzOworICAgIGVsc2UKKyAgICAgICAgbG9zdF9leHAgPSBRdWVyeVByb3AoUF9YUCkgLyAobGV2ZWwgLSAxNyk7CisKKyAgICBBZGRFeHAoLWxvc3RfZXhwKTsKKworCisgICAgLy8gVG9kZXNmb2xnZW4gc2V0emVuLi4uLgorICAgIC8vU2V0UHJvcCggUF9ERUFUSF9JTkZPLCAxKTsKKyAgICBpZiAoICFJU19MRUFSTklORyhNRSkgJiYgIVF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpICkgeworCisgICAgICAgIG1hcHBpbmcgYXR0ciA9IFF1ZXJ5UHJvcChQX0FUVFJJQlVURVMpOworICAgICAgICBtYXBwaW5nIG1vZHMgPSBRdWVyeVByb3AoUF9BVFRSSUJVVEVTX01PRElGSUVSKVsiI2RlYXRoIl0gfHwgKFtdKTsKKworICAgICAgICAvLyBBdHRyaWJ1dGUgYXVmIDc1JSB2b20gYWt0dWVsbGVuIFdlcnQgc2Vua2VuCisgICAgICAgIG1vZHNbQV9TVFJdID0gLWF0dHJbQV9TVFJdICsgKDMgKiAoYXR0cltBX1NUUl0gKyBtb2RzW0FfU1RSXSkgLyA0KTsKKyAgICAgICAgbW9kc1tBX0NPTl0gPSAtYXR0cltBX0NPTl0gKyAoMyAqIChhdHRyW0FfQ09OXSArIG1vZHNbQV9DT05dKSAvIDQpOworICAgICAgICBtb2RzW0FfREVYXSA9IC1hdHRyW0FfREVYXSArICgzICogKGF0dHJbQV9ERVhdICsgbW9kc1tBX0RFWF0pIC8gNCk7CisgICAgICAgIG1vZHNbQV9JTlRdID0gLWF0dHJbQV9JTlRdICsgKDMgKiAoYXR0cltBX0lOVF0gKyBtb2RzW0FfSU5UXSkgLyA0KTsKKworICAgICAgICBTZXRQcm9wKCBQX0FUVFJJQlVURVNfTU9ESUZJRVIsICh7ICIjZGVhdGgiLCBtb2RzIH0pICk7CisKKyAgICAgICAgaW50IG9mZnMgPSAyMjA7ICAvLyAyMjAgaGVhcnRfYmVhdHMgPT0gN21pbjIwCisgICAgICAgIC8vIERpZSAyMjAgSEIgc2luZCBmaXgsIGRhenUga29tbWVuIG5vY2ggNSBIQiBwcm8gcmVhbGVtIAorICAgICAgICAvLyBBdHRyaWJ1dHNwdW5rdC4gR2V0ZWlsdCB3aXJkIGRhcyBnYW56ZSBub2NoIGR1cmNoIDEwLCB3ZWlsIGltIEhCCisgICAgICAgIC8vIG51ciBhbGxlIDEwIEhCcyBkaWUgVEYgZ2VjaGVja3Qgd2VyZGVuLiBEYSB3aXJkIGRhbm4gYWxsZSAxMCBIQiBlaW4KKyAgICAgICAgLy8gUHVua3QgYWJnZXpvZ2VuIHVuZCB3ZW5uIDAgZXJyZWljaHQgaXN0LCB3aXJkIGRhcyBBdHRyaWJ1dCB1bSBlaW5zCisgICAgICAgIC8vIHJlZ2VuZXJpZXJ0LgorICAgICAgICBTZXRQcm9wKCBQX0RFQVRIX0lORk8sIChbIAorICAgICAgICAgICAgQV9TVFI6IChvZmZzICsgNSAqIChhdHRyW0FfU1RSXSArIG1vZHNbQV9TVFJdKSkvMTA7IGF0dHJbQV9TVFJdLAorICAgICAgICAgICAgQV9DT046IChvZmZzICsgNSAqIChhdHRyW0FfQ09OXSArIG1vZHNbQV9DT05dKSkvMTA7IGF0dHJbQV9DT05dLAorICAgICAgICAgICAgQV9ERVg6IChvZmZzICsgNSAqIChhdHRyW0FfREVYXSArIG1vZHNbQV9ERVhdKSkvMTA7IGF0dHJbQV9ERVhdLAorICAgICAgICAgICAgQV9JTlQ6IChvZmZzICsgNSAqIChhdHRyW0FfSU5UXSArIG1vZHNbQV9JTlRdKSkvMTA7IGF0dHJbQV9JTlRdCisgICAgICAgICAgICAgICAgICBdKSApOworCisgICAgICAgIC8vIGRpZSBzdWZmZXJfdGltZSB3aXJkIHZpYSBkZWF0aF9zdWZmZXJpbmcoKSB2b24KKyAgICAgICAgLy8gUXVlcnlTa2lsbEF0dHJpYnV0ZSgpIGFiZ2VmcmFndCB1bmQgZ2VodCBkYW5uIGFscyBNYWx1cyBpbgorICAgICAgICAvLyBTQV9RVUFMSVRZIG1pdCBlaW4uCisgICAgICAgIGlmICggc3VmZmVyX3RpbWUgPD0gMipTVUZGRVJfVElNRSApCisgICAgICAgICAgICBzdWZmZXJfdGltZSArPSBTVUZGRVJfVElNRSAtIDE7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHN1ZmZlcl90aW1lID0gMyAqIFNVRkZFUl9USU1FIC0gMTsKKyAgICB9CisKKyAgICAvLyBEaWUgdmVyc2NoaWVkZW5lbiBOb3RpZnlQbGF5ZXJEZWF0aC1GdW5rdGlvbmVuIGtvZW5uZW4gdS5VLiBzY2hsZWNodAorICAgIC8vIHByb2dyYW1taWVydCBzZWluIHVuZCB6dXZpZWwgUmVjaGVuemVpdCB6aWVoZW4uIERlc2hhbGIgd2VyZGVuIHNpZSBtaXQKKyAgICAvLyBlaW5lbSBMaW1pdHMgdm9uIDE1MGsgYnp3LiA4MGsgYXVmZ2VydWZlbi4gQXVzc2VyZGVtIHdlcmRlbiBzaWUgbnVyCisgICAgLy8gZ2VydWZlbiwgc29sYW5nZSBub2NoIG1pbi4gMjVrIFRpY2tzIGRhIHNpbmQuCisgICAgaW50ICpsaW1pdHM9cXVlcnlfbGltaXRzKCk7CisgICAgbGltaXRzW0xJTUlUX0VWQUxdID0gMTUwMDAwOworICAgIGxpbWl0c1tMSU1JVF9DT1NUXSA9IExJTUlUX0RFRkFVTFQ7CisKKyAgICBtaXhlZCBraWxsZXIgPSBRdWVyeVByb3AoUF9LSUxMRVIpOworICAgIG1peGVkIGdpID0gUXVlcnlQcm9wKFBfR1VJTEQpOworICAgIGlmIChzdHJpbmdwKGdpKSkKKyAgICAgICAgZ2kgPSBmaW5kX29iamVjdCgiL2dpbGRlbi8iK2dpKTsKKyAgICAvLyBqZWRlcyBPYmpla3QgbnVyIGVpbm1hbCwgYWJlciBuaWNodCB2aWEgbV9pbmRpY2VzKG1rbWFwcGluZykpIHdlZ2VuCisgICAgLy8gVmVybHVzdCBkZXIgUmVpaGVuZm9sZ2UuCisgICAgb2JqZWN0ICppdGVtcyA9ICh7a2lsbGVyfSk7CisgICAgaWYgKGVudmlyb25tZW50KCkgIT0ga2lsbGVyKQorICAgICAgICBpdGVtcyArPSAoe2Vudmlyb25tZW50KCl9KTsKKyAgICBpZiAoZ2kgIT0ga2lsbGVyICYmIGdpICE9IGVudmlyb25tZW50KCkpCisgICAgICAgIGl0ZW1zICs9ICh7Z2l9KTsKKyAgICBmb3JlYWNoKG9iamVjdCBpdGVtOiBpdGVtcykgeworICAgICAgICBpZiAoZ2V0X2V2YWxfY29zdCgpIDwgbGltaXRzW0xJTUlUX0VWQUxdICsgMjAwMDApCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgLy8gZmFsbHMgZWluIE5QRCgpIGltcGxpeml0IGFuZGVyZSBPYmpla3QgemVyc3RvZXJ0IGhhdC4KKyAgICAgICAgaWYgKG9iamVjdHAoaXRlbSkpIHsKKyAgICAgICAgICAgIGNhdGNoKGxpbWl0ZWQoIydjYWxsX290aGVyLCBsaW1pdHMsIGl0ZW0sICJOb3RpZnlQbGF5ZXJEZWF0aCIsCisgICAgICAgICAgICAgICAgICBNRSwga2lsbGVyLCBsb3N0X2V4cCk7cHVibGlzaCk7CisgICAgICAgIH0KKyAgICB9CisgICAgLy8gamV0enQgZGVuIFJlc3QuCisgICAgbGltaXRzW0xJTUlUX0VWQUxdID0gODAwMDA7CisgICAgZm9yZWFjaChvYmplY3QgaXRlbTogKGVudmlyb25tZW50KCkgPyBhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpIDogKHt9KSkKKyAgICAgICAgICAgICAgICAgICAgICAgICsgZGVlcF9pbnZlbnRvcnkoTUUpCisgICAgICAgICAgICAgICAgICAgICAgICArIChvYmplY3RwKGNvcnBzZSkgPyBkZWVwX2ludmVudG9yeShjb3Jwc2UpIDogKHt9KSkKKyAgICAgICAgICAgICAgICAgICAgICAgIC0gaXRlbXMgKSB7CisgICAgICAgIC8vIHdlbm4gbmljaHQgbWVociBnZW51ZyBUaWNrcywgaGFiZW4gZGllIHJlc3RsaWNoZW4gUGVjaCBnZWhhYnQuCisgICAgICAgIGlmIChnZXRfZXZhbF9jb3N0KCkgPCBsaW1pdHNbTElNSVRfRVZBTF0gKyAyMDAwMCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAvLyBOUEQoKSBrb2VubmVuIGFuZGVyZSBPYmpla3QgemVyc3RvZXJlbi4KKyAgICAgICAgaWYgKG9iamVjdHAoaXRlbSkpIHsKKyAgICAgICAgICAgIGNhdGNoKGxpbWl0ZWQoIydjYWxsX290aGVyLCBsaW1pdHMsIGl0ZW0sICJOb3RpZnlQbGF5ZXJEZWF0aCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNRSwga2lsbGVyLCBsb3N0X2V4cCk7cHVibGlzaCk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvLyBQcm9wZXJ0aWVzIHp1cnVlY2tzZXR6ZW4sIHNvbGx0ZSBuYWNoIGRlbSBOb3RpZnlQbGF5ZXJEZWF0aCgpCisgICAgLy8gcGFzc2llcmVuLCB3ZWlsIE9iamVrdGUgc2ljaCBkYXJpbiBldnRsLiBlcnN0bWFsIG5vY2ggYXVmcmFldW1lbiB1bmQKKyAgICAvLyBwcm9wcyBtYW5pcHVsaWVyZW4uCisgICAgcmVzZXRfbXlfcHJvcGVydGllcygpOworICAgIFVwZGF0ZUF0dHJpYnV0ZXMoKTsgLy8gQmVpbSBUb2Qgd2VyZGVuIERpbmdlIGVudGZlcm50LCBBdHRyaWJ1dGUgcHJ1ZWZlbgorICAgIAorICAgIC8vIEF1Y2ggQmV3ZWd1bmcgZXJzdCBuYWNoIGRlbiBOUEQoKSwgZGEgZGllc2UgZGVuIFNwaWVsZXIgYmV3ZWdlbgorICAgIC8vIGtvZW5udGVuLCB3YXMgZWluZSBCZXdlZ3VuZyBhdXMgZGVtIFRvZGVzcmF1bSB3YWVyZSwgd2VubiBkaWUgQmV3ZWd1bmcKKyAgICAvLyB2b3IgZGVtIE5QRCgpIHN0YXR0ZmFlbmRlLgorICAgIFNldFByb3AoIFBfR0hPU1QsIDEgKTsgLy8gbmFjaCByZXNldF9teV9wcm9wZXJ0aWVzKCkgIQorICAgIGNsb25lX29iamVjdCggInJvb20vZGVhdGgvZGVhdGhfbWFyayIgKS0+bW92ZSggTUUsIE1fTk9DSEVDSyApOyAKKworICAgIHJldHVybiAxOworfQorCisKK3B1YmxpYyBpbnQgQWRkSHBIb29rKCBvYmplY3Qgb2IgKQoreworICAgIG9iamVjdCAqaG9va3M7CisKKyAgICBpZiAoICFvYmplY3RwKG9iKSApCisgICAgICAgIHJldHVybiAwOworCisgICAgaWYgKCAhcG9pbnRlcnAoaG9va3MgPSBRdWVyeShQX0hQX0hPT0tTKSkgKXsKKyAgICAgICAgU2V0KCBQX0hQX0hPT0tTLCAoeyBvYiB9KSApOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICBpZiAoIG1lbWJlciggaG9va3MsIG9iICkgPj0gMCApCisgICAgICAgIHJldHVybiAwOworCisgICAgU2V0KCBQX0hQX0hPT0tTLCAoaG9va3MgLSAoezB9KSkgKyAoeyBvYiB9KSApOworICAgIHJldHVybiAxOworfQorCisKK3B1YmxpYyBpbnQgUmVtb3ZlSHBIb29rKCBvYmplY3Qgb2IgKQoreworICAgIG9iamVjdCAqaG9va3M7CisKKyAgICBpZiAoICFwb2ludGVycChob29rcyA9IFF1ZXJ5KFBfSFBfSE9PS1MpKSApCisgICAgICAgIHJldHVybiAwOworCisgICAgU2V0KCBQX0hQX0hPT0tTLCBob29rcyAtICh7IG9iLCAwIH0pICk7CisgICAgcmV0dXJuIDE7Cit9CisKKworc3RhdGljIGludCBfcXVlcnlfYWdlKCkgeworICAgIHJldHVybiBTZXQoUF9BR0UsIGFnZSwgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9ocCggaW50IGhwICkKK3sKKyAgICBvYmplY3QgKmhvb2tzOworICAgIGludCByZXQsIGksIG9sZDsKKworICAgIGlmICggKG9sZCA9IFF1ZXJ5KFBfSFAsIEZfVkFMVUUpKSA9PSBocCApCisgICAgICAgIHJldHVybiBvbGQ7CisKKyAgICByZXQgPSBsaWZlOjpfc2V0X2hwKGhwKTsKKworICAgIGlmICggcmV0ID09IG9sZCApCisgICAgICAgIHJldHVybiByZXQ7CisKKyAgICAvLyBDYWxsIG9sZCBob29rcyBpbiBhbGwgb2JqZWN0cy4uLiBkZXN0cnVjdGVkIG9iamVjdHMgd2lsbCBiZSBpZ25vcmVkLgorICAgIGlmIChwb2ludGVycChob29rcyA9IFF1ZXJ5KFBfSFBfSE9PS1MpKSkKKyAgICAgIGNhbGxfb3RoZXIoaG9va3MsICJOb3RpZnlIcENoYW5nZSIpOworCisgICAgLy8gQ2FsbCBuZXcgaG9va3MuCisgICAgSG9va0Zsb3coSF9IT09LX0hQLHJldCk7CisKKyAgICAvLyBSZXBvcnQtYXVzZ2FiZQorICAgIHN0YXR1c19yZXBvcnQoRE9fUkVQT1JUX0hQLCByZXQpOworCisgICAgcmV0dXJuIHJldDsKK30KKworCitzdGF0aWMgaW50IF9zZXRfc3AoIGludCBzcCApCit7CisgICAgb2JqZWN0ICpob29rczsKKyAgICBpbnQgcmV0LCBpLCBvbGQ7CisKKyAgICBpZiAoIChvbGQgPSBRdWVyeShQX1NQLEZfVkFMVUUpKSA9PSBzcCApCisgICAgICAgIHJldHVybiBvbGQ7CisKKyAgICByZXQgPSBsaWZlOjpfc2V0X3NwKHNwKTsKKworICAgIGlmICggcmV0ID09IG9sZCApCisgICAgICAgIHJldHVybiByZXQ7CisKKyAgICAvLyBDYWxsIG9sZCBob29rcyBpbiBhbGwgb2JqZWN0cy4uLiBkZXN0cnVjdGVkIG9iamVjdHMgd2lsbCBiZSBpZ25vcmVkLgorICAgIGlmIChwb2ludGVycChob29rcyA9IFF1ZXJ5KFBfSFBfSE9PS1MpKSkKKyAgICAgIGNhbGxfb3RoZXIoaG9va3MsICJOb3RpZnlIcENoYW5nZSIpOworCisgICAgLy8gQ2FsbCBuZXcgaG9va3MuCisgICAgSG9va0Zsb3coSF9IT09LX1NQLHJldCk7CisKKyAgICAvLyBSZXBvcnQtYXVzZ2FiZQorICAgIHN0YXR1c19yZXBvcnQoRE9fUkVQT1JUX1NQLCByZXQpOworCisgICAgcmV0dXJuIHJldDsKK30KKworc3RhdGljIGludCBfc2V0X3BvaXNvbihpbnQgbikKK3sKKyAgaW50IG9sZCA9IFF1ZXJ5KFBfUE9JU09OLCBGX1ZBTFVFKTsKKyAgaWYgKG9sZCA9PSBuICkKKyAgICAgIHJldHVybiBvbGQ7CisgIG4gPSBsaWZlOjpfc2V0X3BvaXNvbihuKTsKKyAgaWYgKCBuID09IG9sZCApCisgICAgICByZXR1cm4gbjsKKyAgLy8gZ2dmLiBTdGF0dXNyZXBvcnQgYXVzZ2ViZW4KKyAgaWYgKGludGVyYWN0aXZlKE1FKSkKKyAgICBzdGF0dXNfcmVwb3J0KERPX1JFUE9SVF9QT0lTT04sIG4pOworICByZXR1cm4gbjsKK30KKworc3RhdGljIGludCBfc2V0X21heF9wb2lzb24oaW50IG4pCit7CisgIGlmIChuID49IDApCisgIHsKKyAgICBTZXQoUF9NQVhfUE9JU09OLCBuLCBGX1ZBTFVFKTsKKyAgICBpbnQgbWF4cD1RdWVyeVByb3AoUF9NQVhfUE9JU09OKTsgLy8ga29lbm50ZSBuZSBRdWVyeW1ldGhvZGUgZHJhdWYgc2Vpbi4uLgorICAgIGlmIChRdWVyeVByb3AoUF9QT0lTT04pID4gbWF4cCkKKyAgICAgIFNldFByb3AoUF9QT0lTT04sIG1heHApOworICB9CisgIEdNQ1BfQ2hhciggKFtQX01BWF9QT0lTT046IG5dKSApOworICByZXR1cm4gbjsKK30KKworc3RhdGljIGludCBfc2V0X21heF9ocCggaW50IGhwICkKK3sKKyAgaWYgKGhwID49IDApCisgIHsKKyAgICBTZXQoUF9NQVhfSFAsIGhwLCBGX1ZBTFVFKTsKKyAgICBpbnQgbWF4aHA9UXVlcnlQcm9wKFBfTUFYX0hQKTsgLy8ga29lbm50ZSBuZSBRdWVyeW1ldGhvZGUgZHJhdWYgc2Vpbi4uLgorICAgIGlmIChRdWVyeVByb3AoUF9IUCkgPiBtYXhocCkKKyAgICAgIFNldFByb3AoUF9IUCwgbWF4aHApOworICB9CisgIEdNQ1BfQ2hhciggKFtQX01BWF9IUDogaHBdKSApOworICByZXR1cm4gaHA7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9tYXhfc3AoIGludCBzcCApCit7CisgIGlmIChzcCA+PSAwKQorICB7CisgICAgU2V0KFBfTUFYX1NQLCBzcCwgRl9WQUxVRSk7CisgICAgaW50IG1heHNwPVF1ZXJ5UHJvcChQX01BWF9TUCk7IC8vIGtvZW5udGUgbmUgUXVlcnltZXRob2RlIGRyYXVmIHNlaW4uLi4KKyAgICBpZiAoUXVlcnlQcm9wKFBfU1ApID4gbWF4c3ApCisgICAgICBTZXRQcm9wKFBfU1AsIG1heHNwKTsKKyAgfQorICBHTUNQX0NoYXIoIChbUF9NQVhfU1A6IHNwXSkgKTsKKyAgcmV0dXJuIHNwOworfQorCitzdGF0aWMgaW50IF9zZXRfZ2hvc3QoIGludCBnICkgeworICAgIG9iamVjdCB0ZWFtOworCisgICAgaWYoIWcgJiYgcXVlcnlfaGNfcGxheSgpPjEpCisgICAgeworICAgICAgd3JpdGUoIkhBSEFIQSwgRFUgQklTVCBBVUYgRVdJRyBNRUlOLlxuIik7CisgICAgICByZXR1cm4gUXVlcnkoUF9HSE9TVCk7CisgICAgfQorCisgICAgZyA9IFNldCggUF9HSE9TVCwgZyApOworCisgICAgaWYgKCBnICYmIG9iamVjdHAodGVhbSA9IFF1ZXJ5KFBfVEVBTSkpICkKKyAgICAgICAgdGVhbS0+UmVtb3ZlTWVtYmVyKE1FKTsKKworICAgIHJldHVybiBnOworfQorCisKK3B1YmxpYyBpbnQgdW5kaWUoKQoreworICAgIG1peGVkIHgsIGRpOworICAgIG1hcHBpbmcgYXR0ciwgbW9kczsKKworICAgIGlmICggIXRoaXNfaW50ZXJhY3RpdmUoKSB8fCAhcHJldmlvdXNfb2JqZWN0KCkgKQorICAgICAgICByZXR1cm4gMDsKKworICAgIGlmICggIUlTX0FSQ0godGhpc19pbnRlcmFjdGl2ZSgpKSB8fCAhSVNfQVJDSChnZXR1aWQocHJldmlvdXNfb2JqZWN0KCkpKSB8fAorICAgICAgICAgcHJvY2Vzc19jYWxsKCkgKQorICAgICAgICBsb2dfZmlsZSggIlVORElFIiwgc3ByaW50ZiggIiVzICVPIC0+ICVPXG4iLCBkdGltZSh0aW1lKCkpWzUuLjE2XSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfaW50ZXJhY3RpdmUoKSwgTUUgKSApOworCisgICAgaWYgKCB4ID0gUXVlcnkoUF9ERUFEUykgKQorICAgICAgICB4LS07CisKKyAgICBTZXQoIFBfREVBRFMsIHggKTsKKworICAgIHggPSBRdWVyeVByb3AoUF9YUCk7CisKKyAgICBpZiAoIChkaSA9IFF1ZXJ5UHJvcChQX0xFVkVMKSkgPCAyMCB8fCAhSVNfU0VFUihNRSkgKQorICAgICAgICB4ID0gKGludCkoeCAqIDEuNSk7CisgICAgZWxzZQorICAgICAgICAvLyBVbXdlZyB1ZWJlciBmbG9hdCwgd2VpbCBiZWkgaG9oZW4gWFArTGV2ZWwgc29uc3QgMzJCaXQgbmljaHQKKyAgICAgICAgLy8gbWVociBhdXNyZWljaGVuIC0+IG5lZ2F0aXZlIFhQCisgICAgICAgIHggPSAoaW50KSAoIHggKiAoKGZsb2F0KSAoZGkgLSAxNykgLyAoZGkgLSAxOCkpICk7CisKKyAgICBTZXQoIFBfWFAsIHggKTsKKworICAgIGF0dHIgPSBRdWVyeVByb3AoUF9BVFRSSUJVVEVTKSB8fCAoW10pOworICAgIG1vZHMgPSBRdWVyeVByb3AoUF9BVFRSSUJVVEVTX01PRElGSUVSKVsiI2RlYXRoIl0gfHwgKFtdKTsKKworICAgIGlmICggbWFwcGluZ3AoZGkgPSBRdWVyeVByb3AoUF9ERUFUSF9JTkZPKSkgKXsKKyAgICAgICAgLy8gQmVpbSBuYWVjaHN0ZW4gaGVhcnRfYmVhdCBjaGVja2VuCisgICAgICAgIC8vIFplc3N0cmE6IFdpZXNvIGVpZ2VudGxpY2g/IERpZSBNb2RpZmllciB3ZXJkZW4gZG9jaCBkaXJla3QgaGllcgorICAgICAgICAvLyBnZWxvZXNjaHQuIFNvIGV4cGlyZWQgbWFuIGF1Y2ggZWluZW4gVGVpbCB2b24gbmljaHQtdW5kaWUtdGVuIFRvZGVuCisgICAgICAgIC8vIHZvcnplaXRpZy4uLj8gTWFsIGF1c2tvbW1lbnRpZXJ0LiAyOS4xMC4yMDA3CisgICAgICAgIC8vZGlbQV9TVFJdID0gMTsKKyAgICAgICAgLy9kaVtBX0RFWF0gPSAxOworICAgICAgICAvL2RpW0FfSU5UXSA9IDE7CisgICAgICAgIC8vZGlbQV9DT05dID0gMTsKKyAgICB9CisgICAgZWxzZQorICAgICAgZGkgPSAoW10pOworICAgIAorICAgIG1vZHNbQV9TVFJdID0gKCg0ICogKGF0dHJbQV9TVFJdICsgbW9kc1tBX1NUUl0pKSAvIDMpIC0gYXR0cltBX1NUUl07CisgICAgbW9kc1tBX0RFWF0gPSAoKDQgKiAoYXR0cltBX0RFWF0gKyBtb2RzW0FfREVYXSkpIC8gMykgLSBhdHRyW0FfREVYXTsKKyAgICBtb2RzW0FfSU5UXSA9ICgoNCAqIChhdHRyW0FfSU5UXSArIG1vZHNbQV9JTlRdKSkgLyAzKSAtIGF0dHJbQV9JTlRdOworICAgIG1vZHNbQV9DT05dID0gKCg0ICogKGF0dHJbQV9DT05dICsgbW9kc1tBX0NPTl0pKSAvIDMpIC0gYXR0cltBX0NPTl07CisKKyAgICBpZiAoIG1vZHNbQV9TVFJdID49IDAgKSB7CisgICAgICAgIG1fZGVsZXRlKCBtb2RzLCBBX1NUUiApOworICAgICAgICBtX2RlbGV0ZSggZGksIEFfU1RSKTsKKyAgICB9CisgICAgaWYgKCBtb2RzW0FfREVYXSA+PSAwICkgeworICAgICAgICBtX2RlbGV0ZSggbW9kcywgQV9ERVggKTsKKyAgICAgICAgbV9kZWxldGUoIGRpLCBBX0RFWCk7CisgICAgfQorICAgIGlmICggbW9kc1tBX0lOVF0gPj0gMCApIHsKKyAgICAgICAgbV9kZWxldGUoIG1vZHMsIEFfSU5UICk7CisgICAgICAgIG1fZGVsZXRlKCBkaSwgQV9JTlQpOworICAgIH0KKyAgICBpZiAoIG1vZHNbQV9DT05dID49IDAgKSB7CisgICAgICAgIG1fZGVsZXRlKCBtb2RzLCBBX0NPTiApOworICAgICAgICBtX2RlbGV0ZSggZGksIEFfQ09OKTsKKyAgICB9CisKKyAgICBTZXRQcm9wKCBQX0FUVFJJQlVURVNfTU9ESUZJRVIsICh7ICIjZGVhdGgiLCBtb2RzIH0pICk7CisgICAgaWYgKHNpemVvZihkaSkpCisgICAgICBTZXRQcm9wKCBQX0RFQVRIX0lORk8sIGRpICk7CisgICAgZWxzZQorICAgICAgU2V0UHJvcCggUF9ERUFUSF9JTkZPLCAwKTsKKworICAgIHN1ZmZlcl90aW1lIC09ICgoU1VGRkVSX1RJTUUpLTEpOworCisgICAgaWYgKCBzdWZmZXJfdGltZSA8IDAgKQorICAgICAgICBzdWZmZXJfdGltZSA9IDA7CisKKyAgICBTZXQoIFBfR0hPU1QsIDAgKTsKKyAgICByZXR1cm4gMTsKK30KKworCit2YXJhcmdzIHB1YmxpYyB2b2lkIGRpZSggaW50IHBvaXNvbmRlYXRoLCBpbnQgZXh0ZXJuKQoreworICAgIC8vIGxhZXVmdCBzY2hvbiBlaW4gZGllKCk/IEZlaGxlciBhdXNsb2VzZW4sIFVyc2FjaGUgcmVrdXJzaXZlciBkaWUoKSBzb2xsCisgICAgLy8gZ2VmdW5kZW4gd2VyZGVuLiBESU5GT19FVkFMX05VTUJFUiB3aXJkIGluIGplZGVtIFRvcC1MZXZlbCBDYWxsIGltCisgICAgLy8gZHJpdmVyIGVyaG9laHQsIGQuaC4gZ2xlaWNoZSBaYWhsIHNpZ25hbGlzaWVydCBlaW4gcmVrdXJzaXZlcyBkaWUoKS4KKworICAgIGlmIChkaWVfaW5fcHJvZ3Jlc3MgPT0gZGVidWdfaW5mbyhESU5GT19FVkFMX05VTUJFUikpCisgICAgeworICAgICAgLy8gVE9ETzogaXN0IGRhcyBkaWVfaW5fcHJvZ3Jlc3MgYXVzIGRlbSBsZXR6dGVuIEJhY2tlbmQtQ3ljbGU/CisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgICAgImRpZSgpIGluICVPIGdlcnVmZW4sIGFiZXIgZGllKCkgbGFldWZ0IGJlcmVpdHMhXG4iLAorICAgICAgICAgICAgdGhpc19vYmplY3QoKSkpOworICAgIH0KKyAgICBkaWVfaW5fcHJvZ3Jlc3MgPSBkZWJ1Z19pbmZvKERJTkZPX0VWQUxfTlVNQkVSKTsKKyAgICAKKyAgICAvLyBGdWVyIEhDLVBsYXllciBpc3RzIGpldHp0IGdlbGF1ZmVuLi4uCisgICAgaWYocXVlcnlfaGNfcGxheSgpPT0xKQorICAgIHsKKyAgICAgIHNldF9oY19wbGF5KGNhcGl0YWxpemUoZ2V0ZXVpZChNRSkpLHRpbWUoKSk7CisgICAgICBTZXREZWZhdWx0SG9tZSgiL3Jvb20vbmlydmFuYSIpOworICAgICAgU2V0RGVmYXVsdFByYXlSb29tKCIvcm9vbS9uaXJ2YW5hIik7CisgICAgICBTZXRQcm9wKFBfU1RBUlRfSE9NRSwiL3Jvb20vbmlydmFuYSIpOworICAgICAgbG9nX2ZpbGUoIkhDREVBRCIsZHRpbWUodGltZSgpKSsiICIrY2FwaXRhbGl6ZShnZXRldWlkKE1FKSkKKyAgICAgICAgICArIiBnZWh0IGluIGRhcyBOaXJ2YW5hIGVpbiFcbiIpOworICAgIH0KKworICAgIC8vIFdlbm4gZGFzIGRpZSgpIGRpcmVrdCB2b24gYXVzc2VuIGdlcnVmZW4gd3VyZGUsIG11c3MgUF9LSUxMRVIgaGllcgorICAgIC8vIGdlc3BlaWNoZXJ0IHdlcmRlbi4KKyAgICBpZiAoZXh0ZXJuX2NhbGwoKSkKKyAgICAgICAgU2V0UHJvcChQX0tJTExFUiwgcHJldmlvdXNfb2JqZWN0KCkpOworCisgICAgLy8gU2ljaGVybiBkZXIgenUgbG9lc2NoZW5kZW4gUHJvcGVydGllcy4gRGllc2UgUHJvcHMgd2VyZGVuIGltIFZlcmxhdWYgZGVzCisgICAgLy8gVG9kZXMgenVydWVja2dlc2V0enQuIEVpbmlnZSBNYWdpZXIgd29sbGVuIGRpZXNlIERhdGVuIGFiZXIgc3BhZXRlcgorICAgIC8vIG5vY2ggaGFiZW4gdW5kIGZyYWdlbiB0ZWlsd2Vpc2UgUF9MQVNUX0RFQVRIX1BST1BTIGltCisgICAgLy8gTm90aWZ5UGxheWVyRGVhdGgoKSBhYi4gRGFoZXIgd2lyZCBkZXIgS3JhbSBqZXR6dCBoaWVyIHNjaG9ubWFsCisgICAgLy8gZ2VzaWNoZXJ0LgorICAgIC8vIEJUVzogUHJvcHMgbWl0IE1hcHBpbmdzL0FycmF5cyBzb2xsdGVuIGtvcGllcnQgd2VyZGVuLgorICAgIFNldFByb3AoUF9MQVNUX0RFQVRIX1BST1BTLCAoWworICAgICAgUF9QT0lTT04gICAgICAgICAgOiBRdWVyeVByb3AoUF9QT0lTT04pLAorICAgICAgUF9GUk9HICAgICAgICAgICAgOiBRdWVyeVByb3AoUF9GUk9HKSwKKyAgICAgIFBfQUxDT0hPTCAgICAgICAgIDogUXVlcnlQcm9wKFBfQUxDT0hPTCksCisgICAgICBQX0RSSU5LICAgICAgICAgICA6IFF1ZXJ5UHJvcChQX0RSSU5LKSwKKyAgICAgIFBfRk9PRCAgICAgICAgICAgIDogUXVlcnlQcm9wKFBfRk9PRCksCisgICAgICBQX0JMSU5EICAgICAgICAgICA6IFF1ZXJ5UHJvcChQX0JMSU5EKSwKKyAgICAgIFBfREVBRiAgICAgICAgICAgIDogUXVlcnlQcm9wKFBfREVBRiksCisgICAgICBQX01BWF9IQU5EUyAgICAgICA6IFF1ZXJ5UHJvcChQX01BWF9IQU5EUyksCisgICAgICBQX1BBUkEgICAgICAgICAgICA6IFF1ZXJ5UHJvcChQX1BBUkEpLAorICAgICAgUF9OT19SRUdFTkVSQVRJT04gOiBRdWVyeVByb3AoUF9OT19SRUdFTkVSQVRJT04pLAorICAgICAgUF9IUCAgICAgICAgICAgICAgOiBRdWVyeVByb3AoUF9IUCksCisgICAgICBQX1NQICAgICAgICAgICAgICA6IFF1ZXJ5UHJvcChQX1NQKSwKKyAgICAgIFBfTEFTVF9ERUFUSF9USU1FIDogUXVlcnlQcm9wKFBfTEFTVF9ERUFUSF9USU1FICkKKyAgICBdKSApOworCisgICAgLy8gY2FsbCB0aGUgaW5oZXJpdGVkIGRpZSgpIHdpdGggMTAgTWlvIFRpY2tzIHdoaWNoIHdpbGwgYmUgYWNjb3VudGVkIGFzIDEKKyAgICAvLyBUaWNrLi4uIDstKQorICAgIGludCAqbGltaXRzID0gcXVlcnlfbGltaXRzKCk7CisgICAgbGltaXRzW0xJTUlUX0VWQUxdID09IDEwMDAwMDAwOworICAgIGxpbWl0c1tMSU1JVF9DT1NUXSA9PSBMSU1JVF9VTkxJTUlURUQ7CisgICAgbGltaXRlZCgjJzo6ZGllLCBsaW1pdHMsIHBvaXNvbmRlYXRoLCAoZXh0ZXJuX2NhbGwoKSA/IDEgOiAwKSk7IAorCisgICAgLy8gbmFjaCBkZW0gVG9kIHNvbGx0ZSBtYW4gYXVjaCBrZWluZSBMUCBtZWhyIGhhYmVuLgorICAgIFNldFByb3AoUF9IUCwgMCk7CisKKyAgICAvLyBuYWVjaHN0ZXIgVG9kIGthbm4ga29tbWVuLiBEZWtyZW1lbnRpZXJ1bmcsIGRhIDAgZWluIGd1ZWx0aWdlciBXZXJ0CisgICAgLy8gZnVlciBESU5GT19FVkFMX05VTUJFUiB3YWVyZS4gYWJzKCksIHVtIG5pY2h0ICAtX19JTlRfTUFYX18genUKKyAgICAvLyBkZWtyZW1lbnRpZXJlbi4KKyAgICBkaWVfaW5fcHJvZ3Jlc3MgPSBhYnMoZGllX2luX3Byb2dyZXNzKSAtIDE7Cit9CisKK2ludCBkZWZ1ZWxfZm9vZCgpCit7CisgICAgaW50IHJldDsKKyAgICBvYmplY3QgcHJldjsKKyAgICAKKyAgICByZXQ9OjpkZWZ1ZWxfZm9vZCgpOworICAgIHByZXY9cHJldmlvdXNfb2JqZWN0KCk7CisgICAgaWYoIXByZXYgfHwgIW9iamVjdHAocHJldikpCisgICAgeworICAgICAgICBwcmV2PXRoaXNfb2JqZWN0KCk7CisgICAgfQorICAgIAorICAgIGlmKHJldDw9MCkKKyAgICB7CisgICAgICAgICAgICBjYWxsX290aGVyKEZVRUxTVEFULCJhZGREZWZ1ZWxTdGF0RW50cnkiLHByZXYsdGhpc19vYmplY3QoKSwwLDEsMCwxKTsKKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgICAgICAgIGNhbGxfb3RoZXIoRlVFTFNUQVQsImFkZERlZnVlbFN0YXRFbnRyeSIscHJldix0aGlzX29iamVjdCgpLDAsMCxyZXQsMSk7CisgICAgfQorICAgIHJldHVybiByZXQ7Cit9CisKK2ludCBkZWZ1ZWxfZHJpbmsoKQoreworICAgIGludCByZXQ7CisgICAgb2JqZWN0IHByZXY7CisgICAgCisgICAgcmV0PTo6ZGVmdWVsX2RyaW5rKCk7CisgICAgcHJldj1wcmV2aW91c19vYmplY3QoKTsKKyAgICBpZighcHJldiB8fCAhb2JqZWN0cChwcmV2KSkKKyAgICB7CisgICAgICAgIHByZXY9dGhpc19vYmplY3QoKTsKKyAgICB9CisgICAgCisgICAgaWYocmV0PD0wKQorICAgIHsKKyAgICAgICAgICAgIGNhbGxfb3RoZXIoRlVFTFNUQVQsImFkZERlZnVlbFN0YXRFbnRyeSIscHJldix0aGlzX29iamVjdCgpLDAsMSwwLDApOworICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgICAgICAgY2FsbF9vdGhlcihGVUVMU1RBVCwiYWRkRGVmdWVsU3RhdEVudHJ5IixwcmV2LHRoaXNfb2JqZWN0KCksMCwwLHJldCwwKTsKKyAgICB9CisgICAgcmV0dXJuIHJldDsKK30KKworcHVibGljIHZvaWQgc2hvd19hZ2UoKQoreyBpbnQgaSxqOworCisgICAgd3JpdGUoIkFsdGVyOlx0Iik7CisgICAgaSA9IFF1ZXJ5UHJvcChQX0FHRSk7CisgICAgaWYgKChqPWkvNDMyMDApKQorICAgIHsKKyAgICAgIHdyaXRlKGogKyAiIFRhZyIrKGo9PTE/IiAiOiJlICIpKTsKKyAgICAgIGkgJT0gNDMyMDA7CisgICAgfQorICAgIGlmICgoaj1pLzE4MDApKQorICAgIHsKKyAgICAgIHdyaXRlKGogKyAiIFN0dW5kZSIrKGo9PTE/IiAiOiJuICIpKTsKKyAgICAgIGkgJT0gMTgwMDsKKyAgICB9CisgICAgaWYgKChqPWkvMzApKQorICAgIHsKKyAgICAgIHdyaXRlKGogKyAiIE1pbnV0ZSIrKGo9PTE/IiAiOiJuICIpKTsKKyAgICAgIGkgJT0gMzA7CisgICAgfQorICAgIHdyaXRlKGkqMiArICIgU2VrdW5kZW4uXG4iKTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9tb25leWhhbmRsZXIuYyBiL3N0ZC9wbGF5ZXIvbW9uZXloYW5kbGVyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODZhMTdkYgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvbW9uZXloYW5kbGVyLmMKQEAgLTAsMCArMSw1NiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHBsYXllci9tb25leWhhbmRsZXIuYyAtLSBtb25leSBoYW5kbGVyIGZvciBwbGF5ZXJzCisvLyBOdXIgbm9jaCBhdXMgS29tcGF0aWJpbGl0YWV0c2dydWVuZGVuIHZvcmhhbmRlbgorLy8KKy8vICRJZDogbW9uZXloYW5kbGVyLmMgOTA1MSAyMDE1LTAxLTExIDIwOjI4OjAwWiBaZXNzdHJhICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC9jb250YWluZXIvbW9uZXloYW5kbGVyIjsKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8Y29udGFpbmVyL21vbmV5aGFuZGxlci5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxtb25leS5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorCitwdWJsaWMgaW50IEFkZE1vbmV5KCBpbnQgYW1vdW50ICkKK3sKKyAgb2JqZWN0IG9iOworCisgIGlmICggIWFtb3VudCApCisgICAgcmV0dXJuIDE7CisKKyAgaW50IHJldCA9IG1vbmV5aGFuZGxlcjo6QWRkTW9uZXkoYW1vdW50KTsKKworICAvLyBnZ2YuIG5vY2ggbG9nZ2VuCisgIGlmICggcmV0ID09IE1PVkVfT0sKKyAgICAgICAmJiBvYmplY3RwKG9iID0gZmluZF9vYmplY3QoIi9wL2RhZW1vbi9tb25leWxvZyIpKQorICAgICAgICYmIGFtb3VudCA+IDAKKyAgICAgICAvLyBkaWVzZXMgbXVzcyBsZWlkZXIgZHJpbmJsZWliZW4sIHdlaWwgdmllbGUgbmljaHQtU3BpZWxlciBkaWVzZXMKKyAgICAgICAvLyBlcmJlbgorICAgICAgICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkKKyAgICAgICAmJiAhSVNfV0laQVJEKHRoaXNfb2JqZWN0KCkpCisgICAgICAgJiYgIVF1ZXJ5KFBfVEVTVFBMQVlFUikgKQorICAgIG9iLT5BZGRNb25leSggcHJldmlvdXNfb2JqZWN0KCksIGFtb3VudCApOworCisgIHJldHVybiByZXQ7Cit9CisKK3B1YmxpYyBpbnQgUXVlcnlNb25leSgpCit7CisgIG9iamVjdCBtb25leSA9IHByZXNlbnQoU0VIRVJLQVJURUlEX0FLVElWLCB0aGlzX29iamVjdCgpKTsKKyAgLy8genVzYWV0emxpY2ggenUgZGVuIGFuZGVyZW4gR2VsZHF1ZWxsZW4gYXVjaCBub2NoIGRpZSBTZWhlcmthcnRlIHBydWVmZW4uCisgIGlmIChtb25leSkKKyAgICByZXR1cm4gbW9uZXloYW5kbGVyOjpRdWVyeU1vbmV5KCkgKyBtb25leS0+UXVlcnlQcm9wKFBfQU1PVU5UKTsKKworICByZXR1cm4gbW9uZXloYW5kbGVyOjpRdWVyeU1vbmV5KCk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvbW92aW5nLmMgYi9zdGQvcGxheWVyL21vdmluZy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmFiNjJmNTkKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL21vdmluZy5jCkBAIC0wLDAgKzEsMTgyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL21vdmluZy5jIC0tIHBsYXllciBtb3ZpbmcKKy8vCisvLyAkSWQ6IG1vdmluZy5jIDk0MzQgMjAxNi0wMS0xMiAxMjozNDowNVogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK2luaGVyaXQgInN0ZC9saXZpbmcvbW92aW5nIjsKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwbGF5ZXIvYmFzZS5oPgorI2luY2x1ZGUgPGxpdmluZy9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPHBsYXllci92aWV3Y21kLmg+CisjaW5jbHVkZSA8cGxheWVyLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGV2ZW50cy5oPgorI2luY2x1ZGUgPHBhdGhkLmg+CisKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyAqY29ubmVjdGlvbnM7CisKK3B1YmxpYyB2b2lkIGNyZWF0ZSgpCit7CisgICAgU2V0UHJvcCggUF9NU0dJTiwgICJrb21tdCBhbiIgKTsKKyAgICBTZXRQcm9wKCBQX01TR09VVCwgImdlaHQiICk7CisgICAgU2V0UHJvcCggUF9NTVNHSU4sICJ0cml0dCBhdXMgZWluZXIgU2Nod2VmZWx3b2xrZSIgKTsKKyAgICBTZXRQcm9wKCBQX01NU0dPVVQsICJ2ZXJzY2h3aW5kZXQgbWl0IEtuYWxsIHVuZCBTY2h3ZWZlbGR1ZnQiICk7CisgICAgU2V0KCBQX01TR0lOLCAgIFNBVkUsIEZfTU9ERSApOworICAgIFNldCggUF9NU0dPVVQsICBTQVZFLCBGX01PREUgKTsKKyAgICBTZXQoIFBfTU1TR0lOLCAgU0FWRSwgRl9NT0RFICk7CisgICAgU2V0KCBQX01NU0dPVVQsIFNBVkUsIEZfTU9ERSApOworICAgIGNvbm5lY3Rpb25zID0gKHt9KTsKKworICAgIDo6Y3JlYXRlKCk7Cit9CisKKworc3RhdGljIG1peGVkIF90b19yZW1vdmUoIG9iamVjdCBvYiApCit7CisgICAgcmV0dXJuIG9iLT5RdWVyeVByb3AoUF9BVVRPTE9BRE9CSikgfHwgb2ItPlF1ZXJ5UHJvcChQX05PRFJPUCk7Cit9CisKKworLy8gYXV0b2xvYWQgYW5kIG5vZHJvcCBvYmplY3QgbWF5IG5vdCBmYWxsIGludG8gdGhlIGVudmlyb25tZW50CitzdGF0aWMgdmFyYXJncyBpbnQgcmVtb3ZlKCBpbnQgc2lsZW50ICkKK3sKKyAgICBvYmplY3QqIGRlc3Rfb2JqID0gZmlsdGVyKCBkZWVwX2ludmVudG9yeShNRSkgLSAoezB9KSwgIl90b19yZW1vdmUiICk7CisgICAgZmlsdGVyX29iamVjdHMoIGRlc3Rfb2JqLCAicmVtb3ZlIiApOworICAgIGZpbHRlciggZGVzdF9vYmogLSAoezB9KSwgIydkZXN0cnVjdCApOworCisgICAgaWYgKCAhUXVlcnlQcm9wKFBfSU5WSVMpICYmICFzaWxlbnQgKQorICAgICAgICBjYXRjaCggc2F5KCBuYW1lKFdFUiwgMSkgKyAiIHZlcmxhZXNzdCBkaWVzZSBXZWx0LlxuIiwgTUUgKTtwdWJsaXNoICk7CisgICAgCisgICAgaWYgKCBNRSAmJiAhc2lsZW50ICkKKyAgICAgICAgdGVsbF9vYmplY3QoIE1FLCAiQmlzIGJhbGQhXG4iICk7CisKKyAgICAvLyBJbSBGYWxsZSBkZXMgUmVzZXRzIGlzdCBwcmV2aW91c19vYmplY3QoKSA9PSBNRSwgYWJlcgorICAgIC8vIHByZXZpb3VzX29iamVjdCgwKSA9PSAwLiBBdXNzZXJkZW0gaXN0IGRlciBDYWxsZXItU3RhY2sgbGVlci4gQWxzbworICAgIC8vIHNjaGF1ZW4sIG9iIGVzIGVpbiBQTyBnaWJ0LCB3YXMgbmljaHQgZ2xlaWNoIGRlbSBPYmpla3Qgc2VsYmVyIGlzdCwgVEkKKyAgICAvLyBwcnVlZmVuIHVuZCAKKyAgICBpZiAoIHRoaXNfaW50ZXJhY3RpdmUoKSAhPSBNRQorICAgICAgICAmJiBvYmplY3RwKHByZXZpb3VzX29iamVjdCgpKSAmJiBwcmV2aW91c19vYmplY3QoKSAhPSBNRQorICAgICAgICAmJiBvYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSlbMC4uN10gIT0gIi9zZWN1cmUvIgorICAgICAgICAmJiBtZW1iZXIob2JqZWN0X25hbWUoTUUpLCAnOicpID4gLTEgKQorICAgICAgbG9nX2ZpbGUoICJQTEFZRVJERVNUIiwKKyAgICAgICAgICAgICAgICBzcHJpbnRmKCAiJXM6ICVPIHZlcm5pY2h0ZXQgdm9uIFBPICVPLCBUSSAlTywgVFAgJU9cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgZHRpbWUodGltZSgpKSwgTUUsIHByZXZpb3VzX29iamVjdCgpLAorICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfaW50ZXJhY3RpdmUoKSwgdGhpc19wbGF5ZXIoKSApICk7CisKKyAgICAvLyBMb2dvdXQtZXZlbnQgYXVzbG9lc2VuCisgICAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoRVZUX0xJQl9MT0dPVVQsIChbCisJICAgIEVfT0JKRUNUOiBNRSwKKwkgICAgRV9QTE5BTUU6IGdldHVpZChNRSksCisJICAgIEVfRU5WSVJPTk1FTlQ6IGVudmlyb25tZW50KCkgXSkgKTsKKworICAgIHJldHVybiA6OnJlbW92ZSgpOworfQorCitwdWJsaWMgc3RyaW5nIE5vdGlmeURlc3RydWN0KG9iamVjdCBjYWxsZXIpIHsKKyAgCisgIGlmIChwcmV2aW91c19vYmplY3QoKSAhPSBtYXN0ZXIoKQorICAgICAgfHwgb2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bLi48M10pCisgICAgcmV0dXJuIDA7CisKKyAgLy8gRGFzIFplcnN0b2VyZW4gdm9uIFNwaWVsZXJuIHdpcmQgZ2dmLiBnZWxvZ2d0LgorICBpZiAoIG9iamVjdHAoY2FsbGVyKSAmJiBjYWxsZXIgIT0gdGhpc19vYmplY3QoKQorICAgICAgICYmIGdldHVpZChjYWxsZXIpICE9IFJPT1RJRCApIHsKKyAgICAgIGxvZ19maWxlKCAiUExBWUVSREVTVCIsCisJCXNwcmludGYoICIlczogJU8gVkVSTklDSFRFVCB2b24gUE8gJU8sIFRJICVPLCBUUCAlT1xuIiwKKwkJCSBkdGltZSh0aW1lKCkpLCB0aGlzX29iamVjdCgpLCBjYWxsZXIsCisJCQkgdGhpc19pbnRlcmFjdGl2ZSgpLCB0aGlzX3BsYXllcigpICkgKTsKKyAgfQorICAvLyBlcnN0bWFsIG5peCB3ZWl0ZXIgdHVuLCBkZXN0cnVjdCBnZXN0YXR0ZW4uCisgIHJldHVybiAwOworfQorCitwcm90ZWN0ZWQgaW50IFByZXZlbnRNb3ZlKG9iamVjdCBkZXN0LCBvYmplY3Qgb2xkZW52LCBpbnQgbWV0aG9kKSB7CisgIHN0cmluZyBoY3Jvb207CisgIG1peGVkIHJlczsKKworICAvLyBnZXN0b3JiZW5lIEhDLVNwaWVsZXIgZHVlcmZlbiBuaWNodCBtZWhyIGF1cyBkZW0gTmlydmFuYSwgbmljaHQgdW1nZWhiYXIKKyAgLy8gZHVyY2ggTV9OT0NIRUNLCisgIGlmICggaW50ZXJhY3RpdmUoTUUpICYmIChxdWVyeV9oY19wbGF5KCk+MSkgKSB7CisgICAgaWYgKG9iamVjdHAoZGVzdCkpCisgICAgICBoY3Jvb209b2JqZWN0X25hbWUoZGVzdCk7CisgICAgaWYgKHNpemVvZihoY3Jvb20pPDcgfHwgaGNyb29tWzAuLjVdIT0iL3Jvb20vIikgeyAKKyAgICAgIHJldHVybiBNRV9DQU5UX0JFX0lOU0VSVEVEOworICAgIH0KKyAgfQorCisgIC8vIGFsbGUgYW5kZXJlbiBQcnVlZnVuZ2VuIHNpbmQgbWl0IE1fTk9DSEVDSyBlZ2FsLgorICBpZiAoIChtZXRob2QgJiBNX05PQ0hFQ0spICkKKyAgICByZXR1cm4oOjpQcmV2ZW50TW92ZShkZXN0LG9sZGVudixtZXRob2QpKTsKKworICAvLyBTcGllbGVyIGR1ZXJmZW4gaW4gUmFldW1lIG1pdCBnZXNldHp0ZW0gUF9OT19QTEFZRVJTIG5pY2h0IGhpbmVpbgorICBpZiAoIGRlc3QtPlF1ZXJ5UHJvcChQX05PX1BMQVlFUlMpICYmIGludGVyYWN0aXZlKE1FKSAmJgorCSEobWV0aG9kICYgTV9OT0NIRUNLKSAmJgorICAgICAgICAhSVNfTEVBUk5FUihNRSkgJiYgKCFzdHJpbmdwKHJlcyA9IFF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8fCAhSVNfTEVBUk5FUiggbG93ZXJfY2FzZShyZXMpICkpICl7CisgICAgICB0ZWxsX29iamVjdCggTUUsICJEYSBkYXJmc3QgRHUgYWxzIFNwaWVsZXIgbmljaHQgaGluLlxuIiApOworICAgICAgcmV0dXJuIE1FX05PVF9BTExPV0VEOworICB9CisKKyAgcmV0dXJuIDo6UHJldmVudE1vdmUoZGVzdCxvbGRlbnYsbWV0aG9kKTsKK30KKworLy8gRnVjay4gQXVzbmFobXN3ZWlzZSB3ZWdlbiBWQyBicmF1Y2ggaWNoIG5lbiBhbmRlcmVzIEJMVUVfTkFNRQorI2RlZmluZSBPTERfQkxVRV9OQU1FKG9iKSAoZXhwbG9kZShvYmplY3RfbmFtZShvYiksIiMiKVswXSkKKy8vIEtyYW1zIG5hY2ggZGVtIE1vdmUgbWFjaGVuIHVuZCBuZWJlbmJlaSB6dW0gVWViZXJzY2hyZWliZW4uCitwcm90ZWN0ZWQgdm9pZCBOb3RpZnlNb3ZlKG9iamVjdCBkZXN0LCBvYmplY3Qgb2xkZW52LCBpbnQgbWV0aG9kKSB7CisKKyAgLy8gZXJzdG1hbCBnZ2YuIFJhdW1pbmhhbHQgYW4gU3BpZWxlciBhdXNnZWJlbi4KKyAgaWYgKCBpbnRlcmFjdGl2ZShNRSkgJiYgIShtZXRob2QgJiBNX05PX1NIT1cpICkgeworICAgICAgaWYgKCFDYW5ub3RTZWUoMSkpCisgICAgICAgICAgdGVsbF9vYmplY3QoIE1FLCAiIiArIGVudl9kZXNjcigxKSApOworICAgICAgZWxzZSBpZiAoIFF1ZXJ5UHJvcChQX0JSSUVGKSA8IDIgKQorICAgICAgICAgIHRlbGxfb2JqZWN0KCBNRSwgIkZpbnN0ZXJuaXMuXG4iICk7CisgIH0KKworICAvL2Rhbm4gZ2VlcmJ0ZW4gS3JhbSBtYWNoZW4KKyAgOjpOb3RpZnlNb3ZlKGRlc3Qsb2xkZW52LG1ldGhvZCk7CisKKyAgLy8gU2NobHVzc2VuZGxpY2ggbm9jaCBmdWVyIGRlbiBQYXRoRCBiZXdlZ3VuZyBwcm90b2tvbGxpZXJlbi4KKyAgLy8gKGRlc3QgbmljaHQgZ2VwcnVlZnQsIGRhIGVpbiBTcGllbGVyIG5pY2h0IGF1c3NlcmhhbGIgamVkZXMgRW52IGJld2VndAorICAvLyB3ZXJkZW4ga2FubikKKyAgaWYgKCBpbnRlcmFjdGl2ZSgpICYmIGVudmlyb25tZW50KCkgJiYgcXVlcnlfdmVyYigpICYmIG9iamVjdHAob2xkZW52KSkgeworICAgICAgY29ubmVjdGlvbnMgKz0gKHsgKHsgT0xEX0JMVUVfTkFNRShvbGRlbnYpLCBPTERfQkxVRV9OQU1FKGRlc3QpLAorICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnlfdmVyYigpICsgIiAiICsgKF91bnBhcnNlZF9hcmdzKDIpIHx8ICIiKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCwgZGVzdC0+UXVlcnlQcm9wKFBfUEFSQSkgfSkgfSk7CisKKyAgICAgIGlmICggc2l6ZW9mKGNvbm5lY3Rpb25zKSA+IDUwCisgICAgICAgICAgICYmIGZpbmRfY2FsbF9vdXQoImZsdXNoX2Nvbm5lY3Rpb25zIikgPT0gLTEgKQorICAgICAgICAgICAgY2FsbF9vdXQoICJmbHVzaF9jb25uZWN0aW9ucyIsIDAsIGNvbm5lY3Rpb25zICk7CisgIH0KK30KKworcHVibGljIHZvaWQgZmx1c2hfY29ubmVjdGlvbnMoKSB7CisgICAgY2F0Y2goUEFUSEQtPmFkZF9wYXRocyhjb25uZWN0aW9ucyk7cHVibGlzaCk7CisgICAgY29ubmVjdGlvbnMgPSAoe30pOworfQorCisvKioqIFF1ZXJ5LU1ldGhvZGVuIGZ1ZXIgRnJvZXNjaGUuLi4gO14pICoqKi8KK3N0YXRpYyBzdHJpbmcgX3F1ZXJ5X21zZ2luKCkKK3sKKyAgICByZXR1cm4gUXVlcnlQcm9wKFBfRlJPRykgPyAiaHVlcGZ0IGhlcmVpbiIgOiBRdWVyeShQX01TR0lOKTsKK30KKworCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9tc2dvdXQoKQoreworICAgIHJldHVybiBRdWVyeVByb3AoUF9GUk9HKSA/ICJodWVwZnQiIDogUXVlcnkoUF9NU0dPVVQpOworfQpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9vYmplY3RzLmMgYi9zdGQvcGxheWVyL29iamVjdHMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MjYzZWEzCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9vYmplY3RzLmMKQEAgLTAsMCArMSwyNDMgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBwbGF5ZXIvb2JqZWN0cy5jIC0tIG9iamVjdCBoYW5kbGluZyBmb3IgcGxheWVyCisvLworLy8gJElkOiBvYmplY3RzLmMgODY3NSAyMDE0LTAyLTE4IDIwOjM5OjU0WiBaZXNzdHJhICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlICIvc3lzL3BsYXllci9maWxlc3lzLmgiCisKKyNpbmNsdWRlIDxjb25maWcuaD4KKyNpbmNsdWRlIDxwbGF5ZXIuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDx0aGluZy9tb3ZpbmcuaD4KKworc3RhdGljIGludCB1cGRhdGVfb2JqZWN0KHN0cmluZyBzdHIpIHsKKyAgb2JqZWN0IG9iOworICBzdHJpbmcgdXBkX2ZpbGU7CisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSkgeworICAgIG5vdGlmeV9mYWlsKCJVc2FnZTogVXBkYXRlIDxvYmplY3RfcGF0aD5cbiIpOyByZXR1cm4gMDsKKyAgfQorICB1cGRfZmlsZSA9IGZpbmRfZmlsZShzdHIsIi5jIik7CisgIGlmICghdXBkX2ZpbGUpIHVwZF9maWxlPWZpbmRfZmlsZShzdHIpOworICBpZiAoIXVwZF9maWxlKSB7CisgICAgbm90aWZ5X2ZhaWwoc3RyKyI6IE5vIHN1Y2ggZmlsZS5cbiIpOyByZXR1cm4gMDsKKyAgfQorICBvYiA9IGZpbmRfb2JqZWN0KHVwZF9maWxlKTsKKyAgaWYgKCFvYikgeworICAgIG5vdGlmeV9mYWlsKHVwZF9maWxlKyI6IE5vIHN1Y2ggb2JqZWN0LlxuIik7IHJldHVybiAwOworICB9CisgIGRlc3RydWN0KG9iKTsKKyAgd3JpdGUodXBkX2ZpbGUgKyAiOiB3aWxsIGJlIHJlbG9hZGVkIGF0IG5leHQgcmVmZXJlbmNlLlxuIik7CisgIHJldHVybiAxOworfQorCisvKgorICogInNvZnQiIG1lYW5zIHRoYXQgdGhlIG9iamVjdCBpcyBnaXZlbiB0aGUgY2hhbmNlIHRvIHNlbGYtZGVzdHJ1Y3QsIHRodXMKKyAqIGFsbG93aW5nIGl0IHRvIGRvIG5lY2Vzc2FyeSBjbGVhbnVwIGxpa2Ugc3VidHJhY3RpbmcgZnJvbSB0aGUgY2FycmllZAorICogd2VpZ2h0IG9mIHRoZSBlbnZpcm9ubWVudCgpLiBXZSBjYWxsIHJlbW92ZSgpIGluIHRoZSBvYmplY3QgdG8gYmUKKyAqIGRlc3RydWN0ZWQuCisgKi8KK3N0YXRpYyBpbnQgc29mdF91cGRhdGVfb2JqZWN0KHN0cmluZyBzdHIpIAoreworICBvYmplY3Qgb2I7CisgIHN0cmluZyB1cGRfZmlsZTsKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpKSB7CisgICAgbm90aWZ5X2ZhaWwoIlVzYWdlOiB1cGRhdGUgPG9iamVjdF9wYXRoPlxuIik7IHJldHVybiAwOworICB9CisgIHVwZF9maWxlID0gZmluZF9maWxlKHN0ciwiLmMiKTsKKyAgaWYgKCF1cGRfZmlsZSkgdXBkX2ZpbGU9ZmluZF9maWxlKHN0cik7CisgIGlmICghdXBkX2ZpbGUpIHsKKyAgICBub3RpZnlfZmFpbChzdHIrIjogTm8gc3VjaCBmaWxlLlxuIik7IHJldHVybiAwOworICB9CisgIG9iID0gZmluZF9vYmplY3QodXBkX2ZpbGUpOworICBpZiAoIW9iKSB7CisgICAgbm90aWZ5X2ZhaWwodXBkX2ZpbGUrIjogTm8gc3VjaCBvYmplY3QuXG4iKTsgcmV0dXJuIDA7CisgIH0KKyAgaWYgKG9iLT5yZW1vdmUoKSA9PSAwKSB7CisgICAgbm90aWZ5X2ZhaWwodXBkX2ZpbGUrIjogZG9lc24ndCB3YW50IHRvIGJlIGRlc3RydWN0ZWQhXG4iKTsgcmV0dXJuIDA7CisgIH0KKyAgd3JpdGUodXBkX2ZpbGUgKyAiOiB3aWxsIGJlIHJlbG9hZGVkIGF0IG5leHQgcmVmZXJlbmNlLlxuIik7CisgIHJldHVybiAxOworfQorCitpbnQgY2xvbmUoc3RyaW5nIHN0cikgCit7CisgIG9iamVjdCBvYjsKKyAgc3RyaW5nIGNsb25lX2ZpbGU7CisKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpKXsKKyAgICBub3RpZnlfZmFpbCgiVXNhZ2U6IGNsb25lIDxvYmplY3RfcGF0aD5cbiIpOyByZXR1cm4gMDsKKyAgfQorICBjbG9uZV9maWxlID0gZmluZF9maWxlKHN0ciwiLmMiKTsKKyAgaWYgKCFjbG9uZV9maWxlKSBjbG9uZV9maWxlPWZpbmRfZmlsZShzdHIpOworICBpZiAoIWNsb25lX2ZpbGUpIHsKKyAgICBub3RpZnlfZmFpbChzdHIrIjogTm8gc3VjaCBmaWxlLlxuIik7IHJldHVybiAwOworICB9CisgIGlmICghKG9iID0gY2xvbmVfb2JqZWN0KGNsb25lX2ZpbGUpKSkKKyAgICByZXR1cm4gbm90aWZ5X2ZhaWwoc3RyKyI6IEZhaWxlZCB0byBsb2FkLlxuIiksIDA7CisKKyAgLyogU29tZSBvYmplY3RzIGRlc3RydWN0IHRoZW1zZWx2ZXMgcmF0aGVyIGZhc3QgKi8KKyAgaWYgKCFvYmplY3RwKG9iKSkKKyAgICByZXR1cm4gbm90aWZ5X2ZhaWwoc3RyKyI6IERlc3RydWN0ZWQgd2hpbHN0IGNyZWF0ZWQuXG4iKSwgMDsKKyAgCisgIC8qIHRyeSB0byBtb3ZlIHRoZSBvYmplY3QgdG8gbXkgZW52aXJvbm1lbnQgKi8KKyAgaWYgKChvYi0+bW92ZSh0aGlzX29iamVjdCgpLE1fR0VUKT4wKSB8fCAKKyAgICAgIChvYi0+bW92ZShlbnZpcm9ubWVudCgpLE1fTk9DSEVDSyk+MCkpCisgIHsKKyAgICBpZiAoIW9iamVjdHAob2IpKQorICAgICAgcmV0dXJuIG5vdGlmeV9mYWlsKHN0cisiOiBEZXN0cnVjdGVkIHdoaWxzdCBjcmVhdGVkLlxuIiksIDA7CisgICAgd3JpdGUoIkNsb25lZCAiK29iamVjdF9uYW1lKG9iKSsiLlxuIik7CisgICAgc2F5KHRoaXNfcGxheWVyKCktPm5hbWUoV0VSLDEpICsgIiAiCisJCSsgdGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfQ0xPTkVfTVNHKSsiLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgc2F5KHRoaXNfcGxheWVyKCktPm5hbWUoV0VSLDEpKyIgbWFsdCB3aWxkZSBaZWljaGVuIGluIGRpZSBMdWZ0IHVuZCAiCisgICAgICArIm11cm1lbHQgdm9yIHNpY2ggaGluLCBhYmVyIG5pY2h0cyBwYXNzaWVydC4uLlxuIik7CisgIGRlc3RydWN0KG9iKTsKKyAgd3JpdGUoY2xvbmVfZmlsZSsiOiBmYWlsZWQgdG8gbW92ZVxuIik7CisgIHJldHVybiAxOworfQorCisvKgorICogInNvZnQiIG1lYW5zIHRoYXQgdGhlIG9iamVjdCBpcyBnaXZlbiB0aGUgY2hhbmNlIHRvIHNlbGYtZGVzdHJ1Y3QsIHRodXMKKyAqIGFsbG93aW5nIGl0IHRvIGRvIG5lY2Vzc2FyeSBjbGVhbnVwIGxpa2Ugc3VidHJhY3RpbmcgZnJvbSB0aGUgY2FycmllZAorICogd2VpZ2h0IG9mIHRoZSBlbnZpcm9ubWVudCgpLiBXZSBjYWxsIHJlbW92ZSgpIGluIHRoZSBvYmplY3QgdG8gYmUKKyAqIGRlc3RydWN0ZWQuCisgKi8KK3N0YXRpYyBpbnQgc29mdF9kZXN0cnVjdF9vYmplY3Qoc3RyaW5nIHN0cikKK3sgCisgIG9iamVjdCBvYjsKKyAgb2JqZWN0ICpvYnM7CisgIHN0cmluZyBzdHJXRVIsc3RyV0VOOworCisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSl7CisgICAgbm90aWZ5X2ZhaWwoIlVzYWdlOiBkZXN0cnVjdCA8b2JqZWN0bmFtZT5cbiIpOyByZXR1cm4gMDsKKyAgfQorICBzdHJXRVIgPSBsb3dlcl9jYXNlKHN0cik7CisgIG9icyA9IHRoaXNfcGxheWVyKCktPmZpbmRfb2JzKHN0cldFUixQVVRfR0VUX05PTkUpOworICBpZiAoIW9icyB8fCAhc2l6ZW9mKG9icykpIHsKKyAgICBub3RpZnlfZmFpbCgiS2VpbiBcIiIgKyBzdHIgKyAiXCIgZ2VmdW5kZW4uXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBvYj1vYnNbMF07CisgIHN0cldFUj1vYi0+bmFtZShXRVIpOworICBzdHJXRU49b2ItPm5hbWUoV0VOKTsKKyAgaWYgKCFzdHJXRVIpCisgICAgc3RyV0VSPSJqZW1hbmQiOworICBpZiAoIXN0cldFTikKKyAgICBzdHJXRU49ImplbWFuZGVuIjsKKworICBpZiAob2ItPnJlbW92ZSgpID09IDApIHsKKyAgICBub3RpZnlfZmFpbChzdHJXRVIrIiB3aWxsIG5pY2h0ICdkZXN0cnVjdGVkJyB3ZXJkZW4hXG4iKTsKKyAgICBzYXkodGhpc19wbGF5ZXIoKS0+bmFtZShXRVIsMSkrIiB2ZXJzdWNodCB2ZXJnZWJsaWNoLCAiK3N0cldFTisKKyAgICAgICAgIiB6dSBhdG9taXNpZXJlbi5cbiIpOworICAgIHJldHVybiAwOworICB9CisgIHNheShjYXBpdGFsaXplKHN0cldFUikrIiAiK3RoaXNfcGxheWVyKCktPlF1ZXJ5UHJvcChQX0RFU1RSVUNUX01TRykrIi5cbiIpOworICB3cml0ZShjYXBpdGFsaXplKHN0cldFUikrIiB3aXJkIHZvbiBkaXIgemVyc3RhZXVidC5cbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBkZXN0cnVjdF9vYmplY3Qoc3RyaW5nIHN0cikKK3sgCisgIG9iamVjdCBvYjsKKyAgb2JqZWN0ICpvYnM7CisgIHN0cmluZyBzdHJXRVIsc3RyV0VOOworCisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSkgeworICAgIG5vdGlmeV9mYWlsKCJVc2FnZTogRGVzdHJ1Y3QgPG9iamVjdG5hbWU+XG4iKTsgcmV0dXJuIDA7CisgIH0KKyAgc3RyV0VSID0gbG93ZXJfY2FzZShzdHIpOworICBvYnMgPSB0aGlzX3BsYXllcigpLT5maW5kX29icyhzdHJXRVIsUFVUX0dFVF9OT05FKTsKKyAgaWYgKCFvYnMgfHwgIXNpemVvZihvYnMpKSB7CisgICAgbm90aWZ5X2ZhaWwoIktlaW4gXCIiICsgc3RyICsgIlwiIGdlZnVuZGVuLlxuIik7IHJldHVybiAwOworICB9CisgIG9iPW9ic1swXTsKKyAgc3RyV0VSPW9iLT5uYW1lKFdFUik7CisgIHN0cldFTj1vYi0+bmFtZShXRU4pOworCisgIHNheShjYXBpdGFsaXplKHN0cldFUikrIiAiK3RoaXNfcGxheWVyKCktPlF1ZXJ5UHJvcChQX0RFU1RSVUNUX01TRykrIi5cbiIpOworICBkZXN0cnVjdCggb2IgKTsKKyAgd3JpdGUoY2FwaXRhbGl6ZShzdHJXRVIpKyIgd2lyZCB2b24gZGlyIHplcnN0YWV1YnQuXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgbG9hZChzdHJpbmcgc3RyKQoreyAKKyAgb2JqZWN0IGVudjsKKyAgc3RyaW5nIGZpbGU7CisgIHN0cmluZyBlcnI7CisKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpKSB7CisgICAgbm90aWZ5X2ZhaWwoIlVzYWdlOiBsb2FkIDxvYmplY3RfcGF0aD5cbiIpOyByZXR1cm4gMDsKKyAgfQorICBmaWxlID0gZmluZF9maWxlKHN0ciwiLmMiKTsKKyAgaWYgKCFmaWxlKSBmaWxlPWZpbmRfZmlsZShzdHIpOworICBpZiAoIWZpbGUpIHsKKyAgICBub3RpZnlfZmFpbChzdHIrIjogTm8gc3VjaCBmaWxlLlxuIik7IHJldHVybiAwOworICB9CisgIGlmICggZXJyID0gY2F0Y2gobG9hZF9vYmplY3QoZmlsZSk7cHVibGlzaCkgKQorICAgIHByaW50ZigiQ2Fubm90IGxvYWQgJU8sIGVyciA9ICVPXG4iLGZpbGUsZXJyKTsKKyAgZWxzZSB3cml0ZShmaWxlKyJcbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBleGVjX3BsYXllcm9iKHN0cmluZyBuYW1lKQoreworICBvYmplY3Qgb2IsICppbnY7CisgIGludCBpOworCisgIGlmICghSVNfTE9SRCh0aGlzX29iamVjdCgpKSkgcmV0dXJuIDA7CisgIGlmICh0aGlzX3BsYXllcigpICE9IHRoaXNfaW50ZXJhY3RpdmUoKSkgcmV0dXJuIDA7CisgIGlmICh0aGlzX3BsYXllcigpICE9IHRoaXNfb2JqZWN0KCkpIHJldHVybiAwOworICBpZiAoIShuYW1lPV91bnBhcnNlZF9hcmdzKCkpKSByZXR1cm4gMDsKKyAgbmFtZT0ic2VjdXJlL21hc3RlciItPl9nZXRfcGF0aChuYW1lLGdldHVpZCh0aGlzX29iamVjdCgpKSk7CisgIGlmIChjYXRjaChsb2FkX29iamVjdChuYW1lKTtwdWJsaXNoKSApIAorICB7CisgICAgd3JpdGUoIkJVRyBpbiAiK25hbWUrIlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgb2I9Y2xvbmVfb2JqZWN0KG5hbWUpOworICBpZiAoIW9iKSByZXR1cm4gMDsKKyAgaWYgKGdldHVpZChvYikgIT0gZ2V0dWlkKHRoaXNfb2JqZWN0KCkpKQorICB7CisgICAgd3JpdGUoIlVJRCBjb25mbGljdC5cbiIpOworICAgIGRlc3RydWN0KG9iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBsb2dfZmlsZSgiRVhFQyIsIGdldHVpZCh0aGlzX29iamVjdCgpKSsiICIrbmFtZSsiICIrZHRpbWUodGltZSgpKSk7CisgIGRpc2FibGVfY29tbWFuZHMoKTsKKyAgZXhlYyhvYix0aGlzX29iamVjdCgpKTsKKyAgaWYgKGludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpIHx8ICFpbnRlcmFjdGl2ZShvYikpCisgIHsKKyAgICBlbmFibGVfY29tbWFuZHMoKTsKKyAgICB3cml0ZSgiRmVobGVyIGluIGV4ZWNcbiIpOworICAgIHJldHVybiAxOworICB9CisgIGludj1hbGxfaW52ZW50b3J5KHRoaXNfb2JqZWN0KCkpOworICBvYi0+c3RhcnRfcGxheWVyKGNhcGl0YWxpemUoZ2V0dWlkKHRoaXNfb2JqZWN0KCkpKSk7CisgIHJlbW92ZSgpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIG1peGVkIF9xdWVyeV9sb2NhbGNtZHMoKQoreworICByZXR1cm4gKHsKKyAgICAgICAgICAgKHsiY2xvbmUiLCJjbG9uZSIsMCxXSVpBUkRfTFZMfSksCisJICAgKHsiZGVzdHJ1Y3QiLCJzb2Z0X2Rlc3RydWN0X29iamVjdCIsMCxMRUFSTkVSX0xWTH0pLAorCSAgICh7IkRlc3RydWN0IiwiZGVzdHJ1Y3Rfb2JqZWN0IiwwLExFQVJORVJfTFZMfSksCisJICAgKHsibG9hZCIsImxvYWQiLDAsV0laQVJEX0xWTH0pLAorCSAgICh7InVwZGF0ZSIsInNvZnRfdXBkYXRlX29iamVjdCIsMCxMRUFSTkVSX0xWTH0pLAorCSAgICh7IlVwZGF0ZSIsInVwZGF0ZV9vYmplY3QiLDAsTEVBUk5FUl9MVkx9KSwKKwkgICAoeyJleGVjIiwiZXhlY19wbGF5ZXJvYiIsMCxMRUFSTkVSX0xWTH0pCisJIH0pOworfQpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9wa2xvZy5jIGIvc3RkL3BsYXllci9wa2xvZy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2MTNlYmUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL3BrbG9nLmMKQEAgLTAsMCArMSwxMDggQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8qKiBcZmlsZSAvc3RkL3BsYXllci9wa2xvZy5jCisqIEZ1bmt0aW9uIHp1ciBEZXRla3Rpb24gdW5kIExvZ2dlbiB2b24gQW5ncmlmZmVuIHZvbiBTcGllbGVybiBhdWYgU3BpZWxlci4KKyogXGF1dGhvciBaZXNzdHJhCisqIFxkYXRlIDEyLjA4LjIwMDgKKyogXHZlcnNpb24gJElkJAorKi8KKy8qIENoYW5nZWxvZzoKKyovCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIG5vX3NoYWRvdworI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPGNvbW1hbmRzLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8cGxheWVyL2Jhc2UuaD4KKworI2RlZmluZSBSTkFNRSh4KSBjYXBpdGFsaXplKGdldHVpZCh4KSkKKworLyoqIElzdCB2aWN0aW0gaW4gZWluZXIgQXJlbmEgb2RlciBTY2hhdHRlbndlbHQ/CisgICovCitub21hc2sgaW50IENoZWNrQXJlbmFGaWdodChvYmplY3QgdmljdGltKSB7CisgIHJldHVybiAob2JqZWN0X25hbWUoZW52aXJvbm1lbnQodmljdGltKSlbMC4uMTRdPT0iL2Qvc2NoYXR0ZW53ZWx0Iik7Cit9CisKK25vbWFzayBwcm90ZWN0ZWQgaW50IENoZWNrUGxheWVyQXR0YWNrKG9iamVjdCBhdHRhY2tlciwgb2JqZWN0IHZpY3RpbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBhbmdyaWZmc21zZykKK3sKKyAgLy8gZmFsbHMgbWFsIGplbWFuZCBuZSBDbG9zdXJlIGF1ZiBkaWVzZSBGdW5rdGlvbiBpbiBkaWUgRmluZ2VyIGJla29tbXQgdW5kCisgIC8vIHByb3RlY3RlZCB1bWdlaHQuCisgIGlmIChleHRlcm5fY2FsbCgpKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiRXh0ZXJuIENhbGwgdG8gQ2hlY2tQbGF5ZXJBdHRhY2sgaW4gJU8hXG4iLE1FKSk7CisKKyAgLy8gbnVyIFNwaWVsZXIgc2luZCBpbnRlcmVzc2FudC4KKyAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGF0dGFja2VyKSAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHZpY3RpbSkKKyAgICAgICYmICEoIElTX0xFQVJORVIoYXR0YWNrZXIpICYmIElTX0xFQVJORVIodmljdGltKSApICkgeworICAgIHN0cmluZyBmaWxlbWVzc2FnZSwgd2l6c2hvdXQ7CisgICAgaW50IGFyZW5hOworCisgICAgLy8gQXJlbmEtIG9kZXIgU2NoYXR0ZW53ZWx0a2FtcGY/CisgICAgYXJlbmE9Q2hlY2tBcmVuYUZpZ2h0KGF0dGFja2VyKTsKKworICAgIHdpenNob3V0ID0gc3ByaW50ZigiXG4qKioqICVzIGdyZWlmdCAlcyBhbi4gKCVzKSAqKipcbiIsCisgICAgICAgIFJOQU1FKGF0dGFja2VyKSwgUk5BTUUodmljdGltKSwgb2JqZWN0X25hbWUoTUUpKTsKKyAgICBmaWxlbWVzc2FnZSA9IHNwcmludGYoIlxuWyVzXSAlcyBncmVpZnQgJXMgYW4uICglcykgJXMgJXNcbiIsCisgICAgICAgIHN0cmZ0aW1lKCIlZCVtJXktJUg6JU06JVMiLHRpbWUoKSksIFJOQU1FKGF0dGFja2VyKSwKKyAgICAgICAgUk5BTUUodmljdGltKSwgb2JqZWN0X25hbWUodGhpc19vYmplY3QoKSksCisgICAgICAgIChhcmVuYSA/ICIoQVJFTkEpIiA6ICIiKSwKKyAgICAgICAgKHZpY3RpbS0+UXVlcnlQcm9wKFBfVEVTVFBMQVlFUikgPyAiKFRlc3RzcGllbGVyKSIgOiAiIikpOworCisgICAgLy8gQW5ncmlmZnNtc2cgdm9tIEF1ZnJ1ZmVyIGFuaGFlbmdlbi4KKyAgICBpZiAoc3RyaW5ncChhbmdyaWZmc21zZykgJiYgc2l6ZW9mKGFuZ3JpZmZzbXNnKSkgeworICAgICAgd2l6c2hvdXQgKz0gYW5ncmlmZnNtc2c7CisgICAgICBmaWxlbWVzc2FnZSArPSBhbmdyaWZmc21zZzsKKyAgICB9CisgICAgLy8gZ2dmLiBlY2h0ZW4gVEkgYW5oYWVuZ2VuIG9kZXIgd2FybmVuLCBmYWxscyBrZWluZXIgZXhpc3RpZXJ0LgorICAgIGlmICggdGhpc19pbnRlcmFjdGl2ZSgpICE9IGF0dGFja2VyICkgeworICAgICAgICBpZiAoIHRoaXNfaW50ZXJhY3RpdmUoKSApIHsKKyAgICAgICAgICB3aXpzaG91dCArPSAiQUNIVFVORzogVEkgPSAiICsgZ2V0dWlkKHRoaXNfaW50ZXJhY3RpdmUoKSkKKyAgICAgICAgICAgICsiXG4iOworICAgICAgICAgIGZpbGVtZXNzYWdlICs9ICJBQ0hUVU5HOiBUSSA9ICIrZ2V0dWlkKHRoaXNfaW50ZXJhY3RpdmUoKSkKKyAgICAgICAgICAgICsiXG4iOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgZmlsZW1lc3NhZ2UgKz0gIiBBQ0hUVU5HOiBLZWluIFRJIHZvcmhhbmRlbiFcbiI7CisgICAgICAgICAgICB3aXpzaG91dCArPSAiIEFDSFRVTkc6IEtlaW4gVEkgdm9yaGFuZGVuIVxuIjsKKyAgICAgICAgfQorICAgIH0KKyAgICAvLyBjYWxsZXJfc3RhY2soKSBtaXRsb2dnZW4gKGFiZXIgbmljaHQgTWFnaWVyIHZvbGxzY3JvbGxlbikuCisgICAgZmlsZW1lc3NhZ2UgKz0gIkNhbGxlcnN0YWNrOiAiICsgQ291bnRVcChtYXAoY2FsbGVyX3N0YWNrKDEpLAorICAgICAgICAgIGZ1bmN0aW9uIHN0cmluZyAob2JqZWN0IHBvKSB7cmV0dXJuIHRvX3N0cmluZyhwbyk7fSksCisgICAgICAgICIsICIsICIsICIpICsgIlxuIjsKKyAgICAvLyBDb21tYW5kc3RhY2sgYW5oYWVuZ2VuCisgICAgbWl4ZWQgY3N0YWNrID0gY29tbWFuZF9zdGFjaygpOworICAgIGZpbGVtZXNzYWdlICs9ICJDb21tYW5kc3RhY2s6ICIgKyBDb3VudFVwKG1hcChjc3RhY2ssCisgICAgICAgICAgZnVuY3Rpb24gc3RyaW5nIChtaXhlZCBhcnIpIHsKKyAgICAgICAgICAgICAgcmV0dXJuIHNwcmludGYoIih7T3JpZ2luYWwtVFA6ICVPLCBUUDogJU8sIEtvbW1hbmRvOiAlc30pIiwKKyAgICAgICAgICAgICAgICBhcnJbQ01EX09SSUdJTl0sYXJyW0NNRF9QTEFZRVJdLGFycltDTURfVEVYVF0gfHwgIiIpOworICAgICAgICAgIH0sIiwgIiwiLCAiKSkgKyAiXG4iOworICAgIC8vIGZ1ZXIgTWFnaWVyIG9yaWdpbmFlcmVuIEJlZmVobCBhbmhhZW5nZW46CisgICAgaWYgKHNpemVvZihjc3RhY2spKQorICAgICAgd2l6c2hvdXQgKz0gc3ByaW50ZigiS29tbWFuZG86ICVzXG4iLAorICAgICAgICAgIGNzdGFja1swXVtDTURfVEVYVF0gfHwgIjx1bmJla2FubnQ+Iik7CisKKyAgICB3aXpzaG91dCArPSAiXG4iOworCisgICAgLy8gZXJzdG1hbCBsb2dnZW4KKyAgICBpZiAoIGFyZW5hICkKKyAgICAgICAgbG9nX2ZpbGUoIkFUVEFDS1NfQVJFTkEiLCBmaWxlbWVzc2FnZSk7CisgICAgZWxzZSAKKyAgICAgICAgbG9nX2ZpbGUoIkFUVEFDS1MiLCBmaWxlbWVzc2FnZSk7CisKKyAgICAvLyBkYW5uIE1hZ2llcm4gYmVzY2hlaWRnZWJlbgorICAgIGlmICggIWFyZW5hICYmICEodmljdGltLT5RdWVyeVByb3AoUF9URVNUUExBWUVSKSkgKSB7CisgICAgICBmb3JlYWNoKG9iamVjdCB3aXo6IHVzZXJzKCkpIHsKKyAgICAgICAgaWYgKCBJU19MT1JEKHdpeikgfHwgSVNfREVQVVRZKHdpeikgKQorICAgICAgICAgIHRlbGxfb2JqZWN0KHdpeiwgd2l6c2hvdXQpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gMTsgLy8gU3BpZWxlci1TcGllbGVya2FtcGYKKyAgfQorICByZXR1cm4gMDsgLy8ga2VpbiBTcGllbGVyLVNwaWVsZXJrYW1wZgorfQorCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL3BvdGlvbi5jIGIvc3RkL3BsYXllci9wb3Rpb24uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yM2Q4Y2FhCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9wb3Rpb24uYwpAQCAtMCwwICsxLDI1MiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHBsYXllci9wb3Rpb24uYyAtLSBwb3Rpb24gaGFuZGxpbmcgZm9yIHBsYXllcgorLy8KKy8vICRJZDogcG90aW9uLmMgOTI4MCAyMDE1LTA4LTE1IDIyOjIwOjM2WiBBcmF0aG9ybiAkCisvLworCisjcHJhZ21hIHN0cm9uZ190eXBlcyxzYXZlX3R5cGVzCisKKyNpbmNsdWRlIDxpbnB1dF90by5oPgorCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvcG90aW9uLmg+CisjaW5jbHVkZSA8YXR0cmlidXRlcy5oPgorI2luY2x1ZGUgPGxpdmluZy9saWZlLmg+CisjaW5jbHVkZSA8cGxheWVyL2Jhc2UuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisKKyNkZWZpbmUgUE9USU9OTUFTVEVSICIvc2VjdXJlL3BvdGlvbm1hc3RlciIKKworc3RhdGljIG1peGVkICpsaXN0OworCittaXhlZCAqcG90aW9ucm9vbXM7CittaXhlZCAqa25vd25fcG90aW9ucm9vbXM7CisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfcG90aW9ucm9vbXMoKTsKK3N0YXRpYyBtaXhlZCBfcXVlcnlfa25vd25fcG90aW9ucm9vbXMoKTsKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgaWYgKCFwb3Rpb25yb29tcykgcG90aW9ucm9vbXMgPSBQT1RJT05NQVNURVItPkluaXRpYWxMaXN0KCk7CisgIFNldChQX1BPVElPTlJPT01TLCBOT1NFVE1FVEhPRCwgRl9TRVRfTUVUSE9EKTsgIC8vIG5vIHRhbXBlcmluZyBieSBtZXRob2RzCisgIFNldChQX1BPVElPTlJPT01TLCBTRUNVUkVELCBGX01PREVfQVMpOyAgICAgICAgIC8vIG5vIHRhbXBlcmluZyB3aXRoIGxpc3QKKworICBpZiAoIWtub3duX3BvdGlvbnJvb21zKSBrbm93bl9wb3Rpb25yb29tcyA9ICh7fSk7CisgIFNldChQX0tOT1dOX1BPVElPTlJPT01TLCBOT1NFVE1FVEhPRCwgRl9TRVRfTUVUSE9EKTsKKyAgU2V0KFBfS05PV05fUE9USU9OUk9PTVMsIFNFQ1VSRUQsIEZfTU9ERV9BUyk7Cit9CisKK3N0YXRpYyBpbnQgUmVwb3J0UG90aW9uKHN0cmluZyBzLCBpbnQgcG51bSk7CitzdGF0aWMgaW50IFNlbGVjdFdoaWNoKGludCBwbnVtKTsKK3N0YXRpYyBpbnQgYXNrX3F1ZXN0aW9uKGludCBwbnVtKTsKK3N0YXRpYyBpbnQgZ2V0X2Fuc3dlcihzdHJpbmcgZXJnLCBpbnQgcG51bSk7CitzdGF0aWMgaW50IHJhaXNlKHN0cmluZyB3aGF0LCBpbnQgcG51bSk7CitpbnQgQWRkS25vd25Qb3Rpb24oaW50IG5yKTsKK2ludCBSZW1vdmVLbm93blBvdGlvbihpbnQgbnIpOworCitwcm90ZWN0ZWQgdm9pZCB1cGRhdGVzX2FmdGVyX3Jlc3RvcmUoaW50IG5ld2ZsYWcpCit7CisgIC8vIFBfVklTSVRFRF9QT1RJT05ST09NUyBpc3QgbGFuZyB2ZXJhbHRldCB1bmQgdW5iZW51dHp0LCBhYmVyIGJpcyB6dW0KKyAgLy8gMjEuMS4yMDE1IHNvZ2FyIGluIG5ldWVuIFNwaWVsZXJuIGdlc3BlaWNoZXJ0IHdvcmRlbi4KKyAgLy8gQWVobmxpY2ggZnVlciBQX0JPTlVTX1BPVElPTlMuIFdlZyBkYW1pdC4KKyAgU2V0KFBfVklTSVRFRF9QT1RJT05ST09NUywgU0FWRXxQUk9URUNURUQsIEZfTU9ERV9BRCk7CisgIFNldChQX0JPTlVTX1BPVElPTlMsIFNBVkV8UFJPVEVDVEVELCBGX01PREVfQUQpOworfQorCit2YXJhcmdzIGludCBGaW5kUG90aW9uKHN0cmluZyBzKQoreworICBvYmplY3QgcG8gPSBwcmV2aW91c19vYmplY3QoKTsKKyAgaW50IHBudW0gPSBQT1RJT05NQVNURVItPkhhc1BvdGlvbihwbyk7CisgIGludCBmbGFnID0gMTsKKworICBpZiAoIFF1ZXJ5UHJvcChQX1RSQU5LX0ZJTkRFTikgJiYgSVNfV0laQVJEKE1FKSApCisgIHsKKyAgICByZXR1cm4gUmVwb3J0UG90aW9uKHMsIHBudW0pOworICB9CisKKyAgaWYgKCBRdWVyeVByb3AoUF9LSUxMUykgKQorICAgIHJldHVybiAwOworCisgIGlmICggIXBvdGlvbnJvb21zIHx8ICFzaXplb2YocG90aW9ucm9vbXMpIHx8CisgICAgICAgIShQT1RJT05NQVNURVItPkluTGlzdChwbywgcG90aW9ucm9vbXMsIGtub3duX3BvdGlvbnJvb21zKSkgKQorICAgIGZsYWc9MDsKKworICBpZiAoIHBudW0gPCAwIHx8ICFmbGFnICkKKyAgICByZXR1cm4gMDsKKworICBpZiAoIHF1ZXJ5X2lucHV0X3BlbmRpbmcoTUUpIHx8IHF1ZXJ5X2VkaXRpbmcoTUUpICkKKyAgeworICAgIHRlbGxfb2JqZWN0KE1FLAorICAgICAgIkpldHp0IGhhZXR0ZXN0IER1IGZhc3QgZWluZW4gWmF1YmVydHJhbmsgZ2VmdW5kZW4uIER1IHNvbGx0ZXN0IGRlblxuIgorICAgICAgIkVkaXRvci9kYXMgTW9yZSB2ZXJsYXNzZW4gdW5kIGVzIGRhbm4gbm9jaCBlaW5tYWwgdmVyc3VjaGVuIVxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICAvLyBIaWVyIGRlciBBdXNiYXUgZGVyIFpUcyBmdWVyIEdlaXN0ZXIsIHdvYmVpIGRhcyBuYXR1ZXJsaWNoIGluIGRlcgorICAvLyBHZWlzdGVyc2NobG9zc3F1ZXN0IGltbWVyIG5vY2ggZ2VoZW4gc29sbHRlLgorICBvYmplY3QgZW52ID0gZW52aXJvbm1lbnQoTUUpOworICBzdHJpbmcgZm4gPSBvbGRfZXhwbG9kZShvYmplY3RfbmFtZShlbnYpLCAiIyIpWzBdOworICBpZiAoIFF1ZXJ5UHJvcChQX0dIT1NUKSAmJiBmblswLi4yNF0gIT0gIi9kL3dhbGQvYmVydHJhbS9nc2NobG9zcy8iICkKKyAgeworICAgIHRlbGxfb2JqZWN0KE1FLCJBbHMgR2Vpc3QgZWluZW4gWmF1YmVydHJhbms/IEhpZXIgbmljaHQhXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBsb2dfZmlsZSgiQVJDSC9QT1RJT05TIiwgc3ByaW50ZigiJXMgICVzIGluICVzXG4iLCBkdGltZSh0aW1lKCkpLAorICAgIGNhcGl0YWxpemUoZ2V0dWlkKCkpLCBvYmplY3RfbmFtZShwbykpKTsKKworICByZXR1cm4gUmVwb3J0UG90aW9uKHMsIHBudW0pOworfQorCitzdGF0aWMgaW50IFJlcG9ydFBvdGlvbihzdHJpbmcgcywgaW50IHBudW0pCit7CisgIGlmIChzdHJpbmdwKHMpICYmIHNpemVvZihzKSkKKyAgICB0ZWxsX29iamVjdChNRSwgcyk7CisgIGVsc2UKKyAgICB0ZWxsX29iamVjdChNRSwgIkR1IGZpbmRlc3QgZWluZW4gWmF1YmVydHJhbmssIGRlbiBEdSBzb2ZvcnQgdHJpbmtzdC5cbiIpOworCisgIFNlbGVjdFdoaWNoKHBudW0pOworCisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IFNlbGVjdFdoaWNoKGludCBwbnVtKQoreworICBsaXN0PSh7IkludGVsbGlnZW56IiwiS3JhZnQiLCJHZXNjaGlja2xpY2hrZWl0IiwiQXVzZGF1ZXIifSk7CisgIGlmIChRdWVyeVJlYWxBdHRyaWJ1dGUoQV9JTlQpPj0yMCkgbGlzdC09KHsiSW50ZWxsaWdlbnoifSk7CisgIGlmIChRdWVyeVJlYWxBdHRyaWJ1dGUoQV9TVFIpPj0yMCkgbGlzdC09KHsiS3JhZnQifSk7CisgIGlmIChRdWVyeVJlYWxBdHRyaWJ1dGUoQV9ERVgpPj0yMCkgbGlzdC09KHsiR2VzY2hpY2tsaWNoa2VpdCJ9KTsKKyAgaWYgKFF1ZXJ5UmVhbEF0dHJpYnV0ZShBX0NPTik+PTIwKSBsaXN0LT0oeyJBdXNkYXVlciJ9KTsKKyAgaWYgKCFzaXplb2YobGlzdCkpIHsKKyAgICBoZWFsX3NlbGYoMTAwMDAwMDApOworICAgIHRlbGxfb2JqZWN0KE1FLCAiRGVyIFRyYW5rIGhhdCBEaWNoIGdlaGVpbHQuXG4iKTsKKyAgICBsb2dfZmlsZSgiQVJDSC9QT1RJT05TIiwKKyAgICAgICBzcHJpbnRmKCIgICVzOiBIZWlsdHJhbmsgKG5vY2ggJWQpXG4iLAorICAgICAgICAgY2FwaXRhbGl6ZShnZXR1aWQoKSksIHNpemVvZihwb3Rpb25yb29tcyktMSkpOworCisgICAgcG90aW9ucm9vbXMgLT0gKHtwbnVtfSk7CisgICAga25vd25fcG90aW9ucm9vbXMgLT0gKHtwbnVtfSk7CisgICAgc2F2ZV9tZSgxKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoIHNpemVvZihsaXN0KT09MSApCisgICAgcmV0dXJuIHJhaXNlKGxpc3RbMF0sIHBudW0pOworICBhc2tfcXVlc3Rpb24ocG51bSk7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IGFza19xdWVzdGlvbihpbnQgcG51bSkKK3sKKyAgaW50IGk7CisKKyAgdGVsbF9vYmplY3QoTUUsICJEZWluZSBBdHRyaWJ1dGUgc2VoZW4gc28gYXVzOlxuXG4iCisgICAgK3NwcmludGYoIkludGVsbGlnZW56ICAgICA6ICUyZCAoJStkKVxuIiwKKyAgICAgICAgIFF1ZXJ5UmVhbEF0dHJpYnV0ZShBX0lOVCksUXVlcnlBdHRyaWJ1dGVPZmZzZXQoQV9JTlQpKQorICAgICtzcHJpbnRmKCJLcmFmdCAgICAgICAgICAgOiAlMmQgKCUrZClcbiIsCisgICAgICAgICBRdWVyeVJlYWxBdHRyaWJ1dGUoQV9TVFIpLFF1ZXJ5QXR0cmlidXRlT2Zmc2V0KEFfU1RSKSkKKyAgICArc3ByaW50ZigiR2VzY2hpY2tsaWNoa2VpdDogJTJkICglK2QpXG4iLAorICAgICAgICAgUXVlcnlSZWFsQXR0cmlidXRlKEFfREVYKSxRdWVyeUF0dHJpYnV0ZU9mZnNldChBX0RFWCkpCisgICAgK3NwcmludGYoIkF1c2RhdWVyICAgICAgICA6ICUyZCAoJStkKVxuIiwKKyAgICAgICAgIFF1ZXJ5UmVhbEF0dHJpYnV0ZShBX0NPTiksUXVlcnlBdHRyaWJ1dGVPZmZzZXQoQV9DT04pKQorICAgICk7CisKKyAgdGVsbF9vYmplY3QoTUUsCisgICAgIlxuV2FzIG1vZWNodGVzdCBEdSBlcmhvZWhlbj8gRHUgaGFzdCBmb2xnZW5kZSBNb2VnbGljaGtlaXRlbjpcbiIpOworICBmb3IgKGk9MDsgaTxzaXplb2YobGlzdCk7IGkrKykKKyAgICB0ZWxsX29iamVjdChNRSwgc3ByaW50ZigiJWQpICVzXG4iLCBpKzEsIGxpc3RbaV0pKTsKKworICBpbnB1dF90bygiZ2V0X2Fuc3dlciIsIElOUFVUX1BST01QVCwKKyAgICBzcHJpbnRmKCJcbkJpdHRlIGdpYiBqZXR6dCBlaW5lIFphaGwgKDEtJWQpIGFuOiAiLCBpKSwgcG51bSk7CisKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgZ2V0X2Fuc3dlcihzdHJpbmcgZXJnLCBpbnQgcG51bSkKK3sKKyAgaW50IG51bSA9IHRvX2ludChlcmcpOworCisgIGlmICggbnVtID4gMCAmJiBudW0gPD0gc2l6ZW9mKGxpc3QpICkKKyAgICByZXR1cm4gcmFpc2UobGlzdFtudW0tMV0sIHBudW0pOworCisgIHRlbGxfb2JqZWN0KE1FLCAiRGVpbmUgV2FobCB3YXIgdW5ndWVsdGlnLiBCaXR0ZSB2ZXJzdWNoJ3Mgbm9jaG1hbCFcblxuIik7CisgIHJldHVybiBhc2tfcXVlc3Rpb24ocG51bSk7Cit9CisKK3N0YXRpYyBpbnQgcmFpc2Uoc3RyaW5nIHdoYXQsIGludCBwbnVtKSB7CisgIHN0cmluZyBhdHRyOworCisgIHN3aXRjaCAod2hhdCkKKyAgeworICAgIGNhc2UgIkdlc2NoaWNrbGljaGtlaXQiOiBhdHRyPUFfREVYOyBicmVhazsKKyAgICBjYXNlICJJbnRlbGxpZ2VueiI6ICAgICAgYXR0cj1BX0lOVDsgYnJlYWs7CisgICAgY2FzZSAiS3JhZnQiOiAgICAgICAgICAgIGF0dHI9QV9TVFI7IGJyZWFrOworICAgIGNhc2UgIkF1c2RhdWVyIjogICAgICAgICBhdHRyPUFfQ09OOyBicmVhazsKKyAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgIH0KKworICBpbnQgeWV0PVF1ZXJ5UmVhbEF0dHJpYnV0ZShhdHRyKTsKKyAgU2V0UmVhbEF0dHJpYnV0ZShhdHRyLCB5ZXQrMSk7CisgIHRlbGxfb2JqZWN0KE1FLAorICAgIHNwcmludGYoIkRlaW5lICVzIGhhdCBzaWNoIHZvbiAlZCBhdWYgJWQgZXJob2VodC5cbiIsIHdoYXQsIHlldCwgeWV0KzEpKTsKKyAgbG9nX2ZpbGUoIkFSQ0gvUE9USU9OUyIsCisgICAgIHNwcmludGYoIiAgJXM6ICVzICVkLT4lZCAobm9jaCAlZClcbiIsCisgICAgICAgY2FwaXRhbGl6ZShnZXR1aWQoKSksIGNhcGl0YWxpemUoYXR0ciksCisgICAgICAgeWV0LCB5ZXQrMSwgc2l6ZW9mKHBvdGlvbnJvb21zKS0xKSk7CisKKyAgLy8gV2VubiBkaWUgUHJvcGVydHkgZ2VzZXR6dCBpc3QsIHdpcmQgbmljaHQgdmVyc3VjaHQsIGRlbiBnZWZ1bmRlbmVuIFRyYW5rCisgIC8vIGF1cyBkZXIgWlQtTGlzdGUgZGVzIE1hZ2llcnMgYXVzenV0cmFnZW4uIERlciBOZWJlbmVmZmVrdCwgZGFzcworICAvLyBleGlzdGllcmVuZGUsIGFuZ2VzY2hsb3NzZW5lIFpUcyBhdWNoIG5pY2h0IG1laHIgYXVzIGRlciBaVC1MaXN0ZSB2b24KKyAgLy8gdGVzdGVuZGVuIE1hZ2llcm4gYXVzZ2V0cmFnZW4gd2VyZGVuLCB3aXJkIGRhYmVpIGluIEthdWYgZ2Vub21tZW4uCisgIGlmICggIVF1ZXJ5UHJvcChQX1RSQU5LX0ZJTkRFTikgKQorICB7CisgICAgcG90aW9ucm9vbXMgICAgICAgLT0gKHsgcG51bSB9KTsKKyAgICBrbm93bl9wb3Rpb25yb29tcyAtPSAoeyBwbnVtIH0pOworICAgIHNhdmVfbWUoMSk7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfcG90aW9ucm9vbXMoKQoreworICByZXR1cm4gY29weShTZXQoUF9QT1RJT05ST09NUywgcG90aW9ucm9vbXMpKTsKK30KKworc3RhdGljIG1peGVkIF9xdWVyeV9rbm93bl9wb3Rpb25yb29tcygpCit7CisgIHJldHVybiBjb3B5KFNldChQX0tOT1dOX1BPVElPTlJPT01TLCBrbm93bl9wb3Rpb25yb29tcykpOworfQorCitpbnQgQWRkS25vd25Qb3Rpb24oaW50IG5yKQoreworICBpZiAoIXByZXZpb3VzX29iamVjdCgpIHx8CisgICAgICBvYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSkgIT0gIi9yb29tL29yYWtlbCIpCisgICAgcmV0dXJuIC0xOyAvLyBLZWluZSBCZXJlY2h0aWd1bmcKKworICBpZiAobWVtYmVyKGtub3duX3BvdGlvbnJvb21zLCBucikgIT0gLTEpCisgICAgcmV0dXJuIC0yOyAvLyBOdW1tZXIgYmVyZWl0cyBlaW5nZXRyYWdlbgorICBlbHNlCisgIHsKKyAgICBrbm93bl9wb3Rpb25yb29tcyArPSAoeyBuciB9KTsKKyAgICByZXR1cm4gMTsKKyAgfQorfQorCitpbnQgUmVtb3ZlS25vd25Qb3Rpb24oaW50IG5yKQoreworICBpZiAoIXByZXZpb3VzX29iamVjdCgpIHx8CisgICAgICBvYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSkgIT0gIi9yb29tL29yYWtlbCIpCisgICAgcmV0dXJuIC0xOyAvLyBLZWluZSBCZXJlY2h0aWd1bmcKKworICBpZiAobWVtYmVyKGtub3duX3BvdGlvbnJvb21zLCBucikgPT0gLTEpCisgICAgcmV0dXJuIC0yOyAvLyBOdW1tZXIgbmljaHQgZWluZ2V0cmFnZW4KKyAgZWxzZQorICB7CisgICAga25vd25fcG90aW9ucm9vbXMgLT0gKHsgbnIgfSk7CisgICAgcmV0dXJuIDE7CisgIH0KK30KZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvcHJvdG9jb2xzL2dtY3AuYyBiL3N0ZC9wbGF5ZXIvcHJvdG9jb2xzL2dtY3AuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTUxZGFhCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9wcm90b2NvbHMvZ21jcC5jCkBAIC0wLDAgKzEsNzg1IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gZ21jcC5jIC0tIFZlcndhbHR1bmcgdm9uIEdNQ1AgaW0gU3BpZWxlcm9iamVrdAorLy8KKy8vICRJZCQKKworI3ByYWdtYSBzdHJvbmdfdHlwZXMsc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBub19zaGFkb3cKKyNwcmFnbWEgcGVkYW50aWMKKworI2luY2x1ZGUgPHJlZ2V4cC5oPgorI2luY2x1ZGUgPHRlbG5ldC5oPgorCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHBsYXllci9iYXNlLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxpdmluZy9hdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8cGxheWVyL2dtY3AuaD4KKyNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPGxpdmluZy9kZXNjcmlwdGlvbi5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDxyb29tcy5oPgorI2luY2x1ZGUgPHRscy5oPgorCitpbmhlcml0ICIvc2VjdXJlL3RlbG5ldG5lZy1zdHJ1Y3RzLmMiOworCitzdHJ1Y3QgZ21jcF9tb2RfcyB7CisgIHN0cmluZyBpZDsgICAgICAgIC8vIE5hbWUgZGVzIEdNQ1AtTW9kdWxzICh6LkIuICJNRy5DaGFyIikKKyAgaW50IHZlcnNpb247ICAgICAgLy8gVmVyc2lvbiBkZXMgYWt0aXZpZXJ0ZW4gbW9kdWxzCisgIGNsb3N1cmUgc2VuZGNsOyAgIC8vIEhhbmRsZXIgenVtIFNlbmRlbiAobGZ1bi1jbG9zdXJlKQorICBjbG9zdXJlIHJlY3ZjbDsgICAvLyBIYW5kbGVyIHp1bSBFbXBmYW5nZW4gKGxmdW5jLWNsb3N1cmUpCisgIG1peGVkIGRhdGE7ICAgICAgIC8vIG9wdGlvbmFsIGRhdGEgb2YgdGhlIG1vZHVsZQorfTsKKworbm9zYXZlIG1hcHBpbmcgZ21jcGRhdGE7CisvKiBTdHJ1a3R1cjoKKyAgIEplZGVzIE1vZHVsIGhhdCBlaW5lbiBTY2hsdWVzc2VsIGltIFRvcGxldmVsLCB3b3J1bnRlciBnZ2YuIHNlaW5lIERhdGVuCisgICBhYmdlbGVndCBzaW5kLiBEaWUgRGF0ZW4gc2luZCBlaW5lIHN0cnVjdCBnbWNwX21vZF9zLiBEZXIgU2NobHVlc3NlbCBpc3QKKyAgIGRlciBNb2R1bG5hbWUgT0hORSBWZXJzaW9uLgorICAgKi8KKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSAiL3NlY3VyZS90ZWxuZXRuZWcuaCIKKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworLy8jZGVmaW5lIF9fR01DUF9ERUJVR19fIDEKKy8vIExvdyBwcmlvcml0eSBkZWJ1ZyBtZXNzYWdlcworI2RlZmluZSBHTUNQX0RFQlVHKHByZSxtc2cscHJpbykgaWYgKGludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAmJiBnbWNwZGF0YSkgXAorICAgICAgICAgICAgICAgICAgICAgICAgICBHTUNQX2RlYnVnKHByZSxtc2cscHJpbyk7CisvLyBoaWdoZXIgcHJpb3JpdHkgZXJyb3IgbWVzc2FnZXMKKyNkZWZpbmUgR01DUEVSUk9SKG1zZykgaWYgKGludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpIFwKKyAgICAgICAgICAgICAgICAgICAgICAgJiYgZ21jcGRhdGEpIFwKKyAgICAgICAgICAgICAgICAgICAgIEdNQ1BfZGVidWcoIkVSUk9SIixtc2csMTApOworCisKKy8vICoqKioqKioqKioqKioqKiogQVBJIG5hY2ggQXVzc2VuIGZvbGd0IGFiIGhpZXIgKioqKioqKioqKioqKioqKioqKioKKworLy8gV2lyZCB2b20gU3BpZWxlcm9iamVrdCBnZXJ1ZmVuLCB3ZW5uIHNpY2ggRGF0ZW4gYW0gQ2hhcmFrdGVyIHZlcmFlbmRlcnQKKy8vIGhhYmVuLCBkaWUgZ2VzZW5kZXQgd2VyZGVuIHNvbGx0ZW4uCisvLyBEaWVzIGlzdCBlaWdlbnRsaWNoIG51ciBlaW4gV3JhcHBlciwgZGVyIGRpZSBEYXRlbiBhbiBkZW4gSGFuZGxlciBlaW5lcworLy8gTW9kdWxzIHdlaXRlcmdpYnQsIHdlbGNoZXMgdm9tIENsaWVudCBha3RpdmllcnQgd3VyZGUuIEhpZXJ6dSBrb21tZW4genVyCisvLyBaZWl0IDIgaW4gRnJhZ2U6IE1HLkNoYXIgKGJldm9yenVndCkgdW5kIENoYXIgKG1pbmltYWxlciBTdXBwb3J0KS4KKy8qcHJvdGVjdGVkKi8gaW50IEdNQ1BfQ2hhcihtYXBwaW5nIGRhdGEpIHsKKworICBpZiAoIW1hcHBpbmdwKGdtY3BkYXRhKSkgcmV0dXJuIDA7CisKKyAgLy8gQWxzIGVyc3RlcyBzY2hhdWVuLCBvYiBkZXIgQ2xpZW50IE1HLkNoYXIgYWt0aXZpZXJ0IGhhdC4KKyAgc3RydWN0IGdtY3BfbW9kX3MgbW9kID0gZ21jcGRhdGFbIk1HLmNoYXIiXTsKKyAgaWYgKHN0cnVjdHAobW9kKSAmJiBjbG9zdXJlcChtb2QtPnNlbmRjbCkpCisgIHsKKyAgICBmdW5jYWxsKG1vZC0+c2VuZGNsLCBkYXRhKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICAvLyBEYW5uIG5vY2ggZGFzIE1vZHVsIGNoYXIgcHJ1ZWZlbi4gRGFzIGlzdCBhYmVyIHppZW1saWNoIGVpbmdlc2NocmFlbmt0CisgIC8vIHVuZCBlcyBnaWJ0IGhvZmZlbnRsaWNoIG5pY2h0IHZpZWxlIENsaWVudHMsIGRpZSBlcyBiZW51dHplbi4KKyAgLy8gKEFhcmR3b2xmLU1vZHVsKQorICBtb2QgPSBnbWNwZGF0YVsiY2hhciJdOworICBpZiAoc3RydWN0cChtb2QpICYmIGNsb3N1cmVwKG1vZC0+c2VuZGNsKSkKKyAgeworICAgIGZ1bmNhbGwobW9kLT5zZW5kY2wsIGRhdGEpOworICAgIHJldHVybiAxOworICB9CisgIC8vIERhbm4gbm9jaCBkYXMgTW9kdWwgQ2hhciBwcnVlZmVuLiBEYXMgaXN0IGFiZXIgemllbWxpY2ggZWluZ2VzY2hyYWVua3QKKyAgLy8gdW5kIGVzIGdpYnQgaG9mZmVudGxpY2ggbmljaHQgdmllbGUgQ2xpZW50cywgZGllIGVzIGJlbnV0emVuLgorICAvLyAoSVJFLU1vZHVsKQorICBtb2QgPSBnbWNwZGF0YVsiQ2hhciJdOworICBpZiAoc3RydWN0cChtb2QpICYmIGNsb3N1cmVwKG1vZC0+c2VuZGNsKSkKKyAgeworICAgIGZ1bmNhbGwobW9kLT5zZW5kY2wsIGRhdGEpOworICAgIHJldHVybiAxOworICB9CisgIHJldHVybiAwOworfQorCisvKnByb3RlY3RlZCovIGludCBHTUNQX0NoYW5uZWwoc3RyaW5nIG1zZywgc3RyaW5nIGNoYW5uZWwsIHN0cmluZyBzZW5kZXIpIHsKKyAgaWYgKCFtYXBwaW5ncChnbWNwZGF0YSkpIHJldHVybiAwOworICAvLyBjb21tLmNoYW5uZWwgTW9kdWwgYWt0aXY/CisgIHN0cnVjdCBnbWNwX21vZF9zIG1vZCA9IGdtY3BkYXRhWyJjb21tLmNoYW5uZWwiXTsKKyAgaWYgKHN0cnVjdHAobW9kKSAmJiBjbG9zdXJlcChtb2QtPnNlbmRjbCkpCisgIHsKKyAgICBmdW5jYWxsKG1vZC0+c2VuZGNsLCAoWyJjaGFuIjpjaGFubmVsLCAicGxheWVyIjogc2VuZGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1zZyI6IG1zZ10pICk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKy8qcHJvdGVjdGVkKi8gaW50IEdNQ1BfUm9vbSgpIHsKKyAgaWYgKCFtYXBwaW5ncChnbWNwZGF0YSkpIHJldHVybiAwOworICAvLyBNRy5yb29tIE1vZHVsIGFrdGl2PworICBzdHJ1Y3QgZ21jcF9tb2RfcyBtb2QgPSBnbWNwZGF0YVsiTUcucm9vbSJdOworICBpZiAoc3RydWN0cChtb2QpICYmIGNsb3N1cmVwKG1vZC0+c2VuZGNsKSkKKyAgeworICAgIGZ1bmNhbGwobW9kLT5zZW5kY2wsIDApOworICAgIHJldHVybiAxOworICB9CisgIHJldHVybiAwOworfQorCisvLyAqKioqKioqKioqKioqKioqIEFiIGhpZXIgZm9sZ2VuIGVoZXIgZGllIExvd2xldmVsLURpbmdlICoqKioqKioqKioqCitwcml2YXRlIHZvaWQgR01DUF9kZWJ1ZyhzdHJpbmcgcHJlLCBzdHJpbmcgbXNnLCBpbnQgcHJpbykgeworICBzdHJ1Y3QgZ21jcF9tb2RfcyBtb2QgPSBnbWNwZGF0YVsiQ29yZSJdOworICBpZiAobW9kICYmIChtb2QtPmRhdGEpWyJEZWJ1ZyJdID49IHByaW8pCisgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwgc3ByaW50ZigiR01DUCAlczogJXNcbiIscHJlLG1zZykpOworfQorCitwcml2YXRlIHZvaWQgR01DUF9zZW5kKHN0cmluZyBjbWQsIG1peGVkIGRhdGEpCit7CisgIEdNQ1BfREVCVUcoIkdNQ1Bfc2VuZCIsc3ByaW50ZigiJXMgJU8iLGNtZCxkYXRhKSwgMzApOworICBzZW5kX3RlbG5ldF9uZWdfc3RyKHNwcmludGYoIiVjJWMlcyAlcyIsIFNCLCBURUxPUFRfR01DUCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNtZCwganNvbl9zZXJpYWxpemUoZGF0YSkpLCAxKTsKK30KKworcHJpdmF0ZSB2b2lkIEdNQ1BfdW5yZWdpc3Rlcl9tb2R1bGUoc3RyaW5nIG1vZCkKK3sKKyAgaW50IHZlcnNpb247CisgIC8vIFdlbm4gbmljaHQgIm1vZCB2ZXJzaW9uIiBTY2hlbWEsIGlnbm9yaWVyZW4KKyAgaWYgKHNzY2FuZihtb2QsICIlcyAlZCIsIG1vZCwgdmVyc2lvbikgIT0gMikKKyAgICAgIHJldHVybjsKKworICBpZiAobW9kPT0iQ29yZSIpIC8vIGRhcmYgbmljaHQgYWJnZXNjaGFsdGV0IHdlcmRlbi4KKyAgICAgIHJldHVybjsKKworICBtX2RlbGV0ZShnbWNwZGF0YSwgbW9kKTsKK30KKworcHJpdmF0ZSB2b2lkIEdNQ1BfcmVnaXN0ZXJfbW9kdWxlKHN0cmluZyBtb2RuYW1lKQoreworICBpbnQgdmVyc2lvbjsKKyAgR01DUF9ERUJVRygicmVnaXN0ZXJfbW9kdWxlKCk6IHRyeWluZyAuLi4gIixtb2RuYW1lLCAyMCk7CisgIC8vIFdlbm4gbmljaHQgIm1vZCB2ZXJzaW9uIiBTY2hlbWEsIGlnbm9yaWVyZW4KKyAgaWYgKHNzY2FuZihtb2RuYW1lLCAiJXMgJWQiLCBtb2RuYW1lLCB2ZXJzaW9uKSAhPSAyKQorICAgICAgcmV0dXJuOworCisvLyAgR01DUF9ERUJVRygicmVnaXN0ZXJfbW9kdWxlKCkiLG1vZG5hbWUgKyAiIHYiICsgdmVyc2lvbik7CisKKyAgLy8gTW9kdWwgKGdnZi4gbWl0IGFuZGVyZXIgVmVyc2lvbikgYmVyZWl0cyBha3Rpdj8KKyAgc3RydWN0IGdtY3BfbW9kX3MgbW9kID0gZ21jcGRhdGFbbW9kbmFtZV07CisgIGlmIChzdHJ1Y3RwKG1vZCkpIHsKKyAgICAvLyB3ZW5uIGdsZWljaGVyIE5hbWUgdW5kIFZlcnNpb24sIHdpcmQgbml4IGdlbWFjaHQsIGJlaSBhbmRlcmVyIFZlcnNpb24KKyAgICAvLyB3aXJkIGVpbiBuZXVlciBIYW5kbGVyIGVpbmdldHJhZ2VuIHVuZCBkaWUgRGF0ZW4gZ2Vsb2VzY2h0LgorICAgIC8vIFdlbm4gbmljaHQtZXhpc3RpZXJlbmRlIE1vZHVsL1ZlcnNpb24tS29tYmkgYW5nZWZvcmRlcnQgd2lyZCwgaXN0IGRhcworICAgIC8vIE1vZHVsIGhpbnRlcmhlciBhdXMuCisgICAgaWYgKG1vZC0+aWQgPT0gbW9kbmFtZSAmJiBtb2QtPnZlcnNpb24gPT0gdmVyc2lvbikKKyAgICAgIHJldHVybjsKKyAgICBlbHNlCisgICAgICBtX2RlbGV0ZShnbWNwZGF0YSxtb2RuYW1lKTsKKyAgfQorCisgIC8vIERhcyBHTUNQLU1vZHVsIGlzdCBudXIgdmVyZnVlZ2Jhciwgd2VubiBlcyB6dSBkZXIgS29tYmluYXRpb24gYXVzIG1vZCB1bmQKKyAgLy8gdmVyc2lvbiBlaW5lbiBIYW5kbGVyIHp1bSBTZW5kZW4gZ2lidC4uLgorICAvLyBEZXIgSGFuZGxlciBpc3Q6IEdNQ1BfPG1vZD5fdjx2ZXJzaW9uPl9zZW5kLCBhYmVyIGluIDxtb2Q+IHdlcmRlbiBhbGxlCisgIC8vICIuIiBkdXJjaCAiXyIgZXJzZXR6dC4KKyAgc3RyaW5nIHJlcGxhY2VkbmFtZSA9IHJlZ3JlcGxhY2UobW9kbmFtZSwgIlxcLiIsICJfIiwgUkVfR0xPQkFMKTsKKyAgY2xvc3VyZSBzZW5kY2wgPSBzeW1ib2xfZnVuY3Rpb24oc3ByaW50ZigiR01DUG1vZF8lc192JWRfc2VuZCIsCisgICAgICAgICAgICAgICAgICAgICAgcmVwbGFjZWRuYW1lLCB2ZXJzaW9uKSwKKyAgICAgICAgICAgICAgICAgICB0aGlzX29iamVjdCgpKTsKKyAgaWYgKCFzZW5kY2wpCisgICAgcmV0dXJuOworICAvLyBEaWVzZSBDbG9zdXJlIGRhcmYgMCBzZWluLiBEYW5uIGZpbmRldCBrZWluZSBCZWhhbmRsdW5nIHZvbiB2b20gQ2xpZW50CisgIC8vIGdlc2VuZGV0ZW4gS29tbWFuZG9zIHN0YXR0LiBXYXMgZnVlciBkaWUgbWVpc3RlbiBNb2R1bGUgYXVjaCBpbiBPcmRudW5nCisgIC8vIGlzdCwgZGEgc2llIGRlbSBDbGllbnQga2VpbmUgS29tbWFuZG9zIGFuYmlldGVuLgorICBjbG9zdXJlIHJlY3ZjbCA9IHN5bWJvbF9mdW5jdGlvbihzcHJpbnRmKCJHTUNQbW9kXyVzX3YlZF9yZWN2IiwKKyAgICAgICAgICAgICAgICAgICAgICByZXBsYWNlZG5hbWUsIHZlcnNpb24pLAorICAgICAgICAgICAgICAgICAgIHRoaXNfb2JqZWN0KCkpOworCisgIEdNQ1BfREVCVUcoInJlZ2lzdGVyX21vZHVsZSgpIixtb2RuYW1lKyIgZXJmb2xncmVpY2ggcmVnaXN0cmllcnQuIiwxMCk7CisKKyAgbW9kID0gKDxnbWNwX21vZF9zPiBpZDogbW9kbmFtZSwgdmVyc2lvbiA6IHZlcnNpb24sCisgICAgICAgICBzZW5kY2wgOiBzZW5kY2wsIHJlY3ZjbDogcmVjdmNsLCBkYXRhOiAoW10pICk7CisgIGdtY3BkYXRhW21vZG5hbWVdID0gbW9kOworCisgIC8vIFp1bSBzY2hsdXNzIG5vY2ggZGVuIFNlbmRlbi1oYW5kbGVyIG1hbCBydWZlbiwgZGFtaXQgZGVyIG1hbCBhbGxlCisgIC8vIHZlcmZ1ZWdiYXJlbiBkYXRlbiBzZW5kZXQuCisgIGZ1bmNhbGwobW9kLT5zZW5kY2wsIDApOworfQorCisvLyBIYW5kbGVyIGZ1ZXIgZGFzIENvcmUgTW9kdWwgdm9uIEdNQ1AKKy8vIEdlcnVmZW4gYmVpIEVtcGZhbmcgdm9uIEtvbW1hbmRvcyB2b20gQ2xpZW50LgorcHJvdGVjdGVkIHZvaWQgR01DUG1vZF9Db3JlX3YxX3JlY3Yoc3RyaW5nIGNtZCwgbWl4ZWQgYXJncykKK3sKKyAgc3RydWN0IGdtY3BfbW9kX3MgbW9kID0gZ21jcGRhdGFbIkNvcmUiXTsKKyAgbWFwcGluZyBkYXRhID0gbW9kLT5kYXRhOworCisvKiAgaWYgKCFtb2QpCisgIHsKKyAgICBHTUNQRVJST1IoIkNvbW1hbmQgJXMgZm9yIGRpc2FibGVkIG1vZHVsZSBpZ25vcmVkLiIpOworICAgIHJldHVybjsKKyAgfQorICAqLworICBHTUNQX0RFQlVHKCJHTUNQbW9kX0NvcmVfdjE6ICIsIGNtZCwgMjApOworCisgIHN3aXRjaCAoY21kKQorICB7CisgICAgY2FzZSAiQ29yZS5IZWxsbyI6CisgICAgICBpZiAobWFwcGluZ3AoYXJncykpCisgICAgICAgIGRhdGFbIkhlbGxvIl0gPSAoWyJjbGllbnQiOiBhcmdzWyJjbGllbnQiXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgInZlcnNpb24iOiBhcmdzWyJ2ZXJzaW9uIl0gXSk7CisgICAgICBicmVhazsKKyAgICBjYXNlICJDb3JlLlN1cHBvcnRzLlNldCI6CisgICAgICBpZiAocG9pbnRlcnAoYXJncykpCisgICAgICB7CisgICAgICAgIC8vIEFsdGUgTW9kdWxlIGFic2NoYWx0ZW4vbG9lc2NoZW4KKyAgICAgICAgZm9yZWFjaChzdHJpbmcgbSA6IGRhdGFbIlN1cHBvcnRzIl0pCisgICAgICAgICAgR01DUF91bnJlZ2lzdGVyX21vZHVsZShtKTsKKyAgICAgICAgZGF0YVsiU3VwcG9ydHMiXSA9IGFyZ3M7CisgICAgICAgIC8vIFZlcnN1Y2hlbiwgZGllIG5ldWVuIE1vZHVsZSB6dSByZWdpc3RyaWVyZW4KKyAgICAgICAgZm9yZWFjaChzdHJpbmcgbSA6IGFyZ3MpCisgICAgICAgICAgR01DUF9yZWdpc3Rlcl9tb2R1bGUobSk7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICAgICAgR01DUF9ERUJVRygiR01DUG1vZF9Db3JlX3YxOiAiLAorICAgICAgICAgICAgICAiRGF0YSBmb3IgQ29yZS5TdXBwb3J0cy5TZXQgaXMgbm8gYXJyYXkiLCA1KTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgIkNvcmUuU3VwcG9ydHMuQWRkIjoKKyAgICAgIGlmICghcG9pbnRlcnAoZGF0YVsiU3VwcG9ydHMiXSkpCisgICAgICAgIGRhdGFbIlN1cHBvcnRzIl0gPSAoe30pOworICAgICAgaWYgKHBvaW50ZXJwKGFyZ3MpKQorICAgICAgeworICAgICAgICBmb3JlYWNoKHN0cmluZyBtOiBhcmdzKQorICAgICAgICAgIEdNQ1BfcmVnaXN0ZXJfbW9kdWxlKG0pOworICAgICAgICBkYXRhWyJTdXBwb3J0cyJdICs9IGFyZ3M7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICBjYXNlICJDb3JlLlN1cHBvcnRzLlJlbW92ZSI6CisgICAgICBpZiAoIXBvaW50ZXJwKGRhdGFbIlN1cHBvcnRzIl0pKQorICAgICAgICBicmVhazsKKyAgICAgIGlmIChwb2ludGVycChhcmdzKSkKKyAgICAgIHsKKyAgICAgICAgZm9yZWFjaChzdHJpbmcgbTogYXJncykKKyAgICAgICAgICBHTUNQX3VucmVnaXN0ZXJfbW9kdWxlKG0pOworICAgICAgICBkYXRhWyJTdXBwb3J0cyJdIC09IGFyZ3M7CisgICAgICB9CisgICAgICBicmVhazsKKyAgICBjYXNlICJDb3JlLlN1cHBvcnRzLktlZXBBbGl2ZSI6CisgICAgICBicmVhazsgIC8vIHRoaXMgaXMgaWdub3JlZCBieSB1cy4KKyAgICBjYXNlICJDb3JlLlBpbmciOgorICAgICAgaWYgKGludHAoYXJncykpCisgICAgICAgIGRhdGFbIlBpbmciXSA9IGFyZ3M7CisgICAgICAvLyBzZW5kIGEgcGluZyBiYWNrCisgICAgICBHTUNQX3NlbmQoIkNvcmUuUGluZyIsMCk7CisgICAgICBicmVhazsKKyAgICBjYXNlICJDb3JlLkRlYnVnIjoKKyAgICAgIGlmIChpbnRwKGFyZ3MpICYmIGFyZ3MgPj0gMCkKKyAgICAgICAgZGF0YVsiRGVidWciXSA9IGFyZ3M7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgR01DUEVSUk9SKHNwcmludGYoIlVua25vd24gR01DUCBDb3JlIGNtZCAlcyB3aXRoIGFyZ3MgJU8iLAorICAgICAgICAgICAgY21kLCBhcmdzKSk7CisgICAgICBicmVhazsKKyAgfQorfQorCisvLyBIYW5kbGVyIGZ1ZXIgZGFzIENvcmUgTW9kdWwgdm9uIEdNQ1AKKy8vIEdlcnVmZW4sIHdlbm4gRGF0ZW4genUgc2VuZGVuIHNpbmQuCitwcm90ZWN0ZWQgdm9pZCBHTUNQbW9kX0NvcmVfdjFfc2VuZChtYXBwaW5nIGRhdGEpCit7CisgIC8vIFp1ciBaZWl0IG5peCwgc3BhZXRlciBtYWwgQ29yZS5Hb29kYnllLgorfQorCisKKy8vIEhhbmRsZXIgZnVlciBkYXMgTUcuQ2hhciBNb2R1bAorLy8gR2VydWZlbiBiZWkgRW1wZmFuZyB2b24gS29tbWFuZG9zIHZvbSBDbGllbnQuCitwcm90ZWN0ZWQgdm9pZCBHTUNQbW9kX01HX2NoYXJfdjFfc2VuZChtYXBwaW5nIGRhdGEpCit7CisgIG1hcHBpbmcgc3F1ZXVlID0gbV9hbGxvY2F0ZSg1LDApOworICBzdHJ1Y3QgZ21jcF9tb2RfcyBtb2QgPSBnbWNwZGF0YVsiTUcuY2hhciJdOworICAvLyBtb2QtPmRhdGEgZnVuZ2llcnQgaGllciBhdWNoIGFscyBDYWNoZSBkZXIgRGF0ZW4uIERpZSBtdXNzIG1hbiBuYWVtbGljaAorICAvLyBsZWlkZXIgaW1tZXIgYWxsZSBzZW5kZW4sIG5pY2h0IG51ciBkaWUgZ2VhZW5kZXJ0ZW4uCisgIGlmICghbWFwcGluZ3AoZGF0YSkpCisgIHsKKyAgICAvLyBBbGxlIHZlcmZ1ZWdiYXJlbiBJbmZvcm1hdGlvbmVuIHNlbmRlbi4uLgorICAgIG1vZC0+ZGF0YSA9IG1fYWxsb2NhdGUoNik7CisgICAgbV9hZGQobW9kLT5kYXRhLCAiTUcuY2hhci5iYXNlIiwKKyAgICAgICAgICAgICAgKFtQX05BTUU6IE5hbWUoV0VSKSwKKyAgICAgICAgICAgICAgICBQX0dVSUxEOiBRdWVyeVByb3AoUF9HVUlMRCksCisgICAgICAgICAgICAgICAgUF9QUkVTQVk6IFF1ZXJ5UHJvcChQX1BSRVNBWSksICAvLyBUT0RPCisgICAgICAgICAgICAgICAgUF9USVRMRTogUXVlcnlQcm9wKFBfVElUTEUpLAorICAgICAgICAgICAgICAgICJ3aXpsZXZlbCI6IHF1ZXJ5X3dpel9sZXZlbCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICAgICAgICBQX1JBQ0U6IFF1ZXJ5UHJvcChQX1JBQ0UpXSkgKTsgIC8vIFRPRE8KKyAgICBtX2FkZChtb2QtPmRhdGEsIk1HLmNoYXIudml0YWxzIiwgCisgICAgICAgICAgICAgIChbUF9IUDogUXVlcnlQcm9wKFBfSFApLAorICAgICAgICAgICAgICAgIFBfU1A6IFF1ZXJ5UHJvcChQX1NQKSwKKyAgICAgICAgICAgICAgICBQX1BPSVNPTjogUXVlcnlQcm9wKFBfUE9JU09OKSBdKSApOworICAgIG1fYWRkKG1vZC0+ZGF0YSwiTUcuY2hhci5tYXh2aXRhbHMiLAorICAgICAgICAgICAgICAoW1BfTUFYX0hQOiBRdWVyeVByb3AoUF9NQVhfSFApLAorICAgICAgICAgICAgICAgIFBfTUFYX1NQOiBRdWVyeVByb3AoUF9NQVhfU1ApLAorICAgICAgICAgICAgICAgIFBfTUFYX1BPSVNPTjogUXVlcnlQcm9wKFBfTUFYX1BPSVNPTikgXSkgKTsKKyAgICBtX2FkZChtb2QtPmRhdGEsIk1HLmNoYXIuYXR0cmlidXRlcyIsCisgICAgICAgICAgICAgIChbIEFfU1RSOiBRdWVyeUF0dHJpYnV0ZShBX1NUUiksCisgICAgICAgICAgICAgICAgIEFfSU5UOiBRdWVyeUF0dHJpYnV0ZShBX0lOVCksCisgICAgICAgICAgICAgICAgIEFfREVYOiBRdWVyeUF0dHJpYnV0ZShBX0RFWCksCisgICAgICAgICAgICAgICAgIEFfQ09OOiBRdWVyeUF0dHJpYnV0ZShBX0NPTikgXSkgKTsKKyAgICBtX2FkZChtb2QtPmRhdGEsIk1HLmNoYXIuaW5mbyIsCisgICAgICAgICAgICAgIChbUF9MRVZFTDogUXVlcnlQcm9wKFBfTEVWRUwpLAorICAgICAgICAgICAgICAgIFBfR1VJTERfTEVWRUw6IFF1ZXJ5UHJvcChQX0dVSUxEX0xFVkVMKSwKKyAgICAgICAgICAgICAgICBQX0dVSUxEX1RJVExFOiBRdWVyeVByb3AoUF9HVUlMRF9USVRMRSkgXSkgKTsKKyAgICBtX2FkZChtb2QtPmRhdGEsIk1HLmNoYXIud2ltcHkiLAorICAgICAgICAgICAgICAoW1BfV0lNUFk6IFF1ZXJ5UHJvcChQX1dJTVBZKSwKKyAgICAgICAgICAgICAgICBQX1dJTVBZX0RJUkVDVElPTjogUXVlcnlQcm9wKFBfV0lNUFlfRElSRUNUSU9OKSBdKSApOworICAgIG1fYWRkKHNxdWV1ZSwiTUcuY2hhci5iYXNlIik7CisgICAgbV9hZGQoc3F1ZXVlLCJNRy5jaGFyLnZpdGFscyIpOworICAgIG1fYWRkKHNxdWV1ZSwiTUcuY2hhci5tYXh2aXRhbHMiKTsKKyAgICBtX2FkZChzcXVldWUsIk1HLmNoYXIuYXR0cmlidXRlcyIpOworICAgIG1fYWRkKHNxdWV1ZSwiTUcuY2hhci5pbmZvIik7CisgICAgbV9hZGQoc3F1ZXVlLCJNRy5jaGFyLndpbXB5Iik7CisgICAgLy8gZGllcyB3aXJkIGRpcmVrdCBnZXNlbmRldCwgd2VpbCBlcyBuaWNodCBnZXNwZWljaGVydCB3ZXJkZW4gbXVzcy4gKHdpcmQKKyAgICAvLyBudXIgYmVpbSBTdGFydCBkZXMgTW9kdWxzIGdlc2VuZGV0KS4KKyAgICBHTUNQX3NlbmQoIk1HLmNoYXIuaW5mb1ZhcnMiLCAoWworICAgICAgICAgIFBfTEVWRUw6ICJTcGllbGVyc3R1ZmUiLCBQX0dVSUxEX0xFVkVMOiAiR2lsZGVuc3R1ZmUiLAorICAgICAgICAgIFBfR1VJTERfVElUTEU6ICJHaWxkZW50aXRlbCIgXSkgKTsKKyAgfQorICBlbHNlCisgIHsKKyAgICAvLyBudXIgZGllIGluIGRhdGEgZW50aGFsdGVuZW4gc2VuZGVuLgorICAgIC8vIGpldHp0IGVyc3RtYWwgYWxsZXMgYXVzIGRhdGEgc28gc29ydGllcmVuLCB3aWUgZXMgZ2VzZW5kZXQgd2VyZGVuCisgICAgLy8gbXVzcy4uLiAqc2V1ZnoqCisgICAgZm9yZWFjaChzdHJpbmcga2V5LCBtaXhlZCB2YWwgOiBkYXRhKQorICAgIHsKKyAgICAgIHN3aXRjaChrZXkpCisgICAgICB7CisgICAgICAgIGNhc2UgUF9IUDoKKyAgICAgICAgY2FzZSBQX1NQOgorICAgICAgICBjYXNlIFBfUE9JU09OOgorICAgICAgICAgIChtb2QtPmRhdGEpWyJNRy5jaGFyLnZpdGFscyJdICs9IChba2V5OiB2YWxdKTsKKyAgICAgICAgICBtX2FkZChzcXVldWUsIk1HLmNoYXIudml0YWxzIik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUF9NQVhfSFA6CisgICAgICAgIGNhc2UgUF9NQVhfU1A6CisgICAgICAgIGNhc2UgUF9NQVhfUE9JU09OOgorICAgICAgICAgIChtb2QtPmRhdGEpWyJNRy5jaGFyLm1heHZpdGFscyJdICs9IChba2V5OiB2YWxdKTsKKyAgICAgICAgICBtX2FkZChzcXVldWUsIk1HLmNoYXIubWF4dml0YWxzIik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUF9OQU1FOgorICAgICAgICAgIChtb2QtPmRhdGEpWyJNRy5jaGFyLmJhc2UiXSArPSAoW2tleTogTmFtZShXRVIpXSk7CisgICAgICAgICAgbV9hZGQoc3F1ZXVlLCJNRy5jaGFyLmJhc2UiKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBQX1JBQ0U6CisgICAgICAgIGNhc2UgUF9QUkVTQVk6CisgICAgICAgIGNhc2UgUF9USVRMRToKKyAgICAgICAgY2FzZSBQX0dVSUxEOgorICAgICAgICAgIChtb2QtPmRhdGEpWyJNRy5jaGFyLmJhc2UiXSArPSAoW2tleTogdmFsXSk7CisgICAgICAgICAgbV9hZGQoc3F1ZXVlLCJNRy5jaGFyLmJhc2UiKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBBX0RFWDoKKyAgICAgICAgY2FzZSBBX1NUUjoKKyAgICAgICAgY2FzZSBBX0NPTjoKKyAgICAgICAgY2FzZSBBX0lOVDoKKyAgICAgICAgICAobW9kLT5kYXRhKVsiTUcuY2hhci5hdHRyaWJ1dGVzIl0gKz0gKFtrZXk6IHZhbF0pOworICAgICAgICAgIG1fYWRkKHNxdWV1ZSwiTUcuY2hhci5hdHRyaWJ1dGVzIik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUF9MRVZFTDoKKyAgICAgICAgY2FzZSBQX0dVSUxEX0xFVkVMOgorICAgICAgICBjYXNlIFBfR1VJTERfVElUTEU6CisgICAgICAgICAgKG1vZC0+ZGF0YSlbIk1HLmNoYXIuaW5mbyJdICs9IChba2V5OiB2YWxdKTsKKyAgICAgICAgICBtX2FkZChzcXVldWUsIk1HLmNoYXIuaW5mbyIpOworICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFBfV0lNUFk6CisgICAgICAgIGNhc2UgUF9XSU1QWV9ESVJFQ1RJT046CisgICAgICAgICAgKG1vZC0+ZGF0YSlbIk1HLmNoYXIud2ltcHkiXSArPSAoW2tleTogdmFsXSk7CisgICAgICAgICAgbV9hZGQoc3F1ZXVlLCJNRy5jaGFyLndpbXB5Iik7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgfQorICB9CisgIEdNQ1BfREVCVUcoIkdNQ1Btb2RfTUdfY2hhcl92MV9zZW5kKCkiLAorICAgICAgc3ByaW50ZigiRGF0YSByZWFkeTogJU8sIFNlbmRxdWV1ZTogJU8iLG1vZC0+ZGF0YSwgc3F1ZXVlKSw1MCk7CisKKyAgLy8gSmV0enQgZGllIHNxdWV1ZSBzZW5kZW4uLi4KKyAgZm9yZWFjaChzdHJpbmcga2V5IDogc3F1ZXVlKQorICB7CisgICAgR01DUF9zZW5kKGtleSwgKG1vZC0+ZGF0YSlba2V5XSk7CisgIH0KK30KKworLy8gSGFuZGxlciBmdWVyIGRhcyBNRy5DaGFyIE1vZHVsCisvLyBHZXJ1ZmVuIGJlaSBFbXBmYW5nIHZvbiBLb21tYW5kb3Mgdm9tIENsaWVudC4KK3Byb3RlY3RlZCB2b2lkIEdNQ1Btb2RfTUdfY2hhcl92MV9yZWN2KHN0cmluZyBjbWQsIG1peGVkIGFyZ3MpCit7CisgIC8vIGRpZXNlcyBNb2R1bCBiaWV0ZXQgZGVtIENsaWVudCBrZWluZSBLb21tYW5kb3MgYW4sIGRhaGVyIGlnbm9yaWVyZW4uCisgIEdNQ1BfREVCVUcoIkdNQ1Btb2RfTUdfQ2hhcl92MV9yZWN2IiwiQ2xpZW50LUtvbW1hbmRvIGlnbm9yaWVydDogIitjbWQsMjApOworfQorCisvKgorLy8gSGFuZGxlciBmdWVyIGRhcyBNRy5Sb29tIE1vZHVsIHZvbiBHTUNQCisvLyBHZXJ1ZmVuLCB3ZW5uIERhdGVuIHp1IHNlbmRlbiBzaW5kLgorcHJvdGVjdGVkIHZvaWQgR01DUG1vZF9NR19Sb29tX3YxX3NlbmQobWFwcGluZyBkYXRhKQoreworfQorCisvLyBIYW5kbGVyIGZ1ZXIgZGFzIFJvb20gTW9kdWwgdm9uIEdNQ1AKKy8vIEdlcnVmZW4gYmVpIEVtcGZhbmcgdm9uIEtvbW1hbmRvcyB2b20gQ2xpZW50LgorcHJvdGVjdGVkIHZvaWQgR01DUG1vZF9NR19Sb29tX3YxX3JlY3Yoc3RyaW5nIGNtZCwgbWl4ZWQgYXJncykKK3sKKyAgLy8gZGllc2VzIE1vZHVsIGJpZXRldCBkZW0gQ2xpZW50IGtlaW5lIEtvbW1hbmRvcyBhbiwgZGFoZXIgaWdub3JpZXJlbi4KKyAgR01DUF9ERUJVRygiR01DUG1vZF9NR19Sb29tX3YxX3JlY3YiLCJDbGllbnQtS29tbWFuZG8gaWdub3JpZXJ0OiAiK2NtZCwyMCk7Cit9CisqLworCisvLyBSZWN2IEhhbmRsZXIgZnVlciBkYXMgY29tbS5jaGFubmVsIE1vZHVsIHZvbiBHTUNQCisvLyBHZXJ1ZmVuIGJlaSBFbXBmYW5nIHZvbiBLb21tYW5kb3Mgdm9tIENsaWVudC4KK3Byb3RlY3RlZCB2b2lkIEdNQ1Btb2RfY29tbV9jaGFubmVsX3YxX3JlY3Yoc3RyaW5nIGNtZCwgbWl4ZWQgYXJncykKK3sKKyAgR01DUF9ERUJVRygiR01DUG1vZF9jb21tX2NoYW5uZWxfdjFfcmVjdiIsCisgICAgICAiQ2xpZW50LUtvbW1hbmRvIGlnbm9yaWVydDogIitjbWQsMjApOworfQorCisvLyBTZW5kIEhhbmRsZXIgZnVlciBkYXMgY29tbS5jaGFubmVsIE1vZHVsIHZvbiBHTUNQCitwcm90ZWN0ZWQgdm9pZCBHTUNQbW9kX2NvbW1fY2hhbm5lbF92MV9zZW5kKG1hcHBpbmcgZGF0YSkKK3sKKyAgLy8gR2FueiBzaW1wZWw6IGVpbmZhY2ggcmF1c3NlbmRlbi4uLgorICAvLyBDb3JlIHVlYmVyZ2lidCBiZWltIEVpbnNjaGFsdGVuIDAgYWxzIGRhdGEuIERpZXNlcyBtb2R1bCBtdXNzIGFiZXIgYmVpbQorICAvLyBFaXNuY2hhbHRlbiBuaXggbWFjaGVuLiBBbHNvIG51ciBpZ25vcmllcmVuLgorICBpZiAobWFwcGluZ3AoZGF0YSkpCisgICAgR01DUF9zZW5kKCJjb21tLmNoYW5uZWwiLCBkYXRhKTsKK30KKworLy8gUmVjdiBIYW5kbGVyIGZ1ZXIgZGFzIE1HLnJvb20gTW9kdWwgdm9uIEdNQ1AKKy8vIEdlcnVmZW4gYmVpIEVtcGZhbmcgdm9uIEtvbW1hbmRvcyB2b20gQ2xpZW50LgorcHJvdGVjdGVkIHZvaWQgR01DUG1vZF9NR19yb29tX3YxX3JlY3Yoc3RyaW5nIGNtZCwgbWl4ZWQgYXJncykKK3sKKyAgR01DUF9ERUJVRygiR01DUG1vZF9NR19yb29tX3YxX3JlY3YiLAorICAgICAgIkNsaWVudC1Lb21tYW5kbyBpZ25vcmllcnQ6ICIrY21kLDIwKTsKK30KKworLy8gU2VuZCBIYW5kbGVyIGZ1ZXIgZGFzIGNvbW0uY2hhbm5lbCBNb2R1bCB2b24gR01DUAorcHJvdGVjdGVkIHZvaWQgR01DUG1vZF9NR19yb29tX3YxX3NlbmQobWFwcGluZyBkYXRhKQoreworICAvLyBCZWtvbW10IGltbWVyIDAgYWxzIDxkYXRhPiB1ZWJlcmdlYmVuIHVuZCBzdWNodCBzaWNoIGRpZSBEYXRlbiBhdXMgZGVtCisgIC8vIFJhdW0genVzYW1tZW4uCisKKyAgLy8gQmFlaC4gV2FydW0gd2lyZCBkYXMgZGVubiBvaG5lIEVudiBnZXJ1ZmVuLiA6LSgKKyAgaWYgKCFlbnZpcm9ubWVudCgpKQorICAgIHJldHVybjsKKworICAvLyBCbGluZCBnaWJ0IGVzIGF1Y2ggcGVyIEdNQ1Agbml4LgorICBpZiAoQ2Fubm90U2VlKDEpKQorICAgIHJldHVybjsKKworICBpbnQgcmVzdHIgPSBlbnZpcm9ubWVudCgpLT5RdWVyeVByb3AoUF9NQVBfUkVTVFJJQ1RJT05TKTsKKworICBpZiAocmVzdHIgJiBNUl9OT0lORk8pCisgICAgcmV0dXJuOyAvLyBnYXIga2VpbmUgaW5mbyBzZW5kZW4uCisKKyAgLy8gQW5tZXJrdW5nOiBpbnRfc2hvcnQoKSB3YWVyZSBjb29sLiBEdW1tZXJ3ZWlzZSB1ZWJlcnRyYWVndCBkYXMgYXVjaAorICAvLyBzaWNodGJhcmUgQXVzZ2FuZ2UgdW5kIE9iamVrdGUuIEluc29mZXJuOiBnZWh0IG5pY2h0LgorICBkYXRhID0gKFsKKyAgICAgIFBfU0hPUlQ6IHByb2Nlc3Nfc3RyaW5nKGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX0lOVF9TSE9SVCl8fCIiKSsiLiIsCisgICAgICAiZG9tYWluIjogZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfRE9NQUlOKSB8fCAidW5iZWthbm50IiwKKyAgICAgIF0pOworCisgIC8vIHNpY2h0YmFyZSBBdXNnYWVuZ2UgYXVzZ2ViZW4KKyAgbWl4ZWQgaGlkZSA9IGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX0hJREVfRVhJVFMpOworICBpZiAoaGlkZSAmJiAhcG9pbnRlcnAoaGlkZSkpCisgICAgICBkYXRhWyJleGl0cyJdID0gKHt9KTsgICAvLyBhbGxlIHZlcnN0ZWNrZW4KKyAgZWxzZQorICB7CisgICAgICAvLyBRdWVyeSgpIHZlcndlbmRlbiwgZGFtaXQgc293b2hsIG5vcm1hbGUgYWxzIGF1Y2ggU3BlY2lhbCBFeGl0cworICAgICAgLy8ga29tbWVuLi4uIERpZSBTdW1tZSB2b24gYmVpZGVuIHd1ZXJkZSBhdWNoIGdlaGVuLCBhYmVyIGRhbm4gaGF0IG1hbgorICAgICAgLy8gendlaSB1bm5vZXRpZ2UgRmlsdGVyIGluIGRlbiBRdWVyeW1ldGhvZGVuLiBIbmdsLgorICAgICAgbWFwcGluZyBleGl0cyA9IGVudmlyb25tZW50KCktPlF1ZXJ5KFBfRVhJVFMsIEZfVkFMVUUpIHx8IChbXSk7CisgICAgICBpZiAocG9pbnRlcnAoaGlkZSkpCisgICAgICAgIGRhdGFbImV4aXRzIl0gPSBtX2luZGljZXMoZXhpdHMpIC0gaGlkZTsKKyAgICAgIGVsc2UKKyAgICAgICAgZGF0YVsiZXhpdHMiXSA9IG1faW5kaWNlcyhleGl0cyk7CisgIH0KKworICBpZiAocmVzdHIgJiBNUl9OT1VJRCkKKyAgICBkYXRhWyJpZCJdID0gIiI7CisgIGVsc2UKKyAgICBkYXRhWyJpZCJdID0gaGFzaChUTFNfSEFTSF9NRDUsIG9iamVjdF9uYW1lKGVudmlyb25tZW50KCkpKTsKKworICBHTUNQX3NlbmQoIk1HLnJvb20uaW5mbyIsIGRhdGEpOworfQorCisKKy8vIEhhbmRsZXIgZnVlciBkYXMgImNoYXIiIE1vZHVsIHZvbiBHTUNQIChNb2R1bCB2b24gQWFyZHdvbGYpCisvLyBHZXJ1ZmVuLCB3ZW5uIERhdGVuIHp1IHNlbmRlbiBzaW5kLgorcHJvdGVjdGVkIHZvaWQgR01DUG1vZF9jaGFyX3YxX3NlbmQobWFwcGluZyBkYXRhKQoreworICBtYXBwaW5nIHNxdWV1ZSA9IG1fYWxsb2NhdGUoNCwwKTsKKyAgc3RydWN0IGdtY3BfbW9kX3MgbW9kID0gZ21jcGRhdGFbImNoYXIiXTsKKyAgLy8gbW9kLT5kYXRhIGZ1bmdpZXJ0IGhpZXIgYXVjaCBhbHMgQ2FjaGUgZGVyIERhdGVuLiBEaWUgbXVzcyBtYW4gbmFlbWxpY2gKKyAgLy8gbGVpZGVyIGltbWVyIGFsbGUgc2VuZGVuLCBuaWNodCBudXIgZGllIGdlYWVuZGVydGVuLgorICBpZiAoIW1hcHBpbmdwKGRhdGEpKQorICB7CisgICAgLy8gQWxsZSB2ZXJmdWVnYmFyZW4gSW5mb3JtYXRpb25lbiBzZW5kZW4uLi4KKyAgICBtb2QtPmRhdGEgPSBtX2FsbG9jYXRlKDQpOworICAgIG1fYWRkKG1vZC0+ZGF0YSwgImNoYXIuYmFzZSIsIChbIm5hbWUiOiBxdWVyeV9yZWFsX25hbWUoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyYWNlIjogUXVlcnlQcm9wKFBfUkFDRSldKSApOworICAgIG1fYWRkKG1vZC0+ZGF0YSwiY2hhci52aXRhbHMiLCAoWyJocCI6IFF1ZXJ5UHJvcChQX0hQKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWFuYSI6IFF1ZXJ5UHJvcChQX1NQKV0pICk7CisgICAgbV9hZGQobW9kLT5kYXRhLCJjaGFyLnN0YXRzIiwgKFsgInN0ciI6IFF1ZXJ5QXR0cmlidXRlKEFfU1RSKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW50IjogUXVlcnlBdHRyaWJ1dGUoQV9JTlQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJkZXgiOiBRdWVyeUF0dHJpYnV0ZShBX0RFWCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNvbiI6IFF1ZXJ5QXR0cmlidXRlKEFfQ09OKSBdKSApOworICAgIG1fYWRkKG1vZC0+ZGF0YSwiY2hhci5zdGF0dXMiLCAoWyJsZXZlbCI6IFF1ZXJ5UHJvcChQX0xFVkVMKSBdKSApOworICAgIG1fYWRkKHNxdWV1ZSwiY2hhci5iYXNlIik7CisgICAgbV9hZGQoc3F1ZXVlLCJjaGFyLnZpdGFscyIpOworICAgIG1fYWRkKHNxdWV1ZSwiY2hhci5zdGF0cyIpOworICAgIG1fYWRkKHNxdWV1ZSwiY2hhci5zdGF0dXMiKTsKKyAgfQorICBlbHNlCisgIHsKKyAgICAvLyBudXIgZGllIGluIGRhdGEgZW50aGFsdGVuZW4gc2VuZGVuLgorICAgIC8vIGpldHp0IGVyc3RtYWwgYWxsZXMgYXVzIGRhdGEgc28gc29ydGllcmVuLCB3aWUgZXMgZ2VzZW5kZXQgd2VyZGVuCisgICAgLy8gbXVzcy4uLiAqc2V1ZnoqCisgICAgZm9yZWFjaChzdHJpbmcga2V5LCBtaXhlZCB2YWwgOiBkYXRhKQorICAgIHsKKyAgICAgIHN3aXRjaChrZXkpCisgICAgICB7CisgICAgICAgIGNhc2UgUF9IUDoKKyAgICAgICAgICAobW9kLT5kYXRhKVsiY2hhci52aXRhbHMiXSArPSAoWyJocCI6IHZhbF0pOworICAgICAgICAgIG1fYWRkKHNxdWV1ZSwiY2hhci52aXRhbHMiKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBQX1NQOgorICAgICAgICAgIChtb2QtPmRhdGEpWyJjaGFyLnZpdGFscyJdICs9IChbIm1hbmEiOiB2YWxdKTsKKyAgICAgICAgICBtX2FkZChzcXVldWUsImNoYXIudml0YWxzIik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUF9OQU1FOgorICAgICAgICBjYXNlIFBfUkFDRToKKyAgICAgICAgICAobW9kLT5kYXRhKVsiY2hhci5iYXNlIl0gKz0gKFtrZXk6IHZhbF0pOworICAgICAgICAgIG1fYWRkKHNxdWV1ZSwiY2hhci5iYXNlIik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgQV9ERVg6CisgICAgICAgIGNhc2UgQV9TVFI6CisgICAgICAgIGNhc2UgQV9DT046CisgICAgICAgIGNhc2UgQV9JTlQ6CisgICAgICAgICAgKG1vZC0+ZGF0YSlbImNoYXIuc3RhdHMiXSArPSAoW2tleTogdmFsXSk7CisgICAgICAgICAgbV9hZGQoc3F1ZXVlLCJjaGFyLnN0YXRzIik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUF9MRVZFTDoKKyAgICAgICAgICAobW9kLT5kYXRhKVsiY2hhci5zdGF0dXMiXSArPSAoW2tleTogdmFsXSk7CisgICAgICAgICAgbV9hZGQoc3F1ZXVlLCJjaGFyLnN0YXR1cyIpOworICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorICBHTUNQX0RFQlVHKCJHTUNQbW9kX2NoYXJfdjFfc2VuZCgpIiwKKyAgICAgIHNwcmludGYoIkRhdGEgcmVhZHk6ICVPLCBTZW5kcXVldWU6ICVPIixtb2QtPmRhdGEsIHNxdWV1ZSksNTApOworCisgIC8vIEpldHp0IGRpZSBzcXVldWUgc2VuZGVuLi4uCisgIGZvcmVhY2goc3RyaW5nIGtleSA6IHNxdWV1ZSkKKyAgeworICAgIEdNQ1Bfc2VuZChrZXksIChtb2QtPmRhdGEpW2tleV0pOworICB9Cit9CisKKy8vIEhhbmRsZXIgZnVlciBkYXMgImNoYXIiIE1vZHVsIHZvbiBHTUNQIChNb2R1bCB2b24gQWFyZHdvbGYpCisvLyBHZXJ1ZmVuIGJlaSBFbXBmYW5nIHZvbiBLb21tYW5kb3Mgdm9tIENsaWVudC4KK3Byb3RlY3RlZCB2b2lkIEdNQ1Btb2RfY2hhcl92MV9yZWN2KHN0cmluZyBjbWQsIG1peGVkIGRhdGEpCit7CisgIC8vIGRpZXNlcyBNb2R1bCBiaWV0ZXQgZGVtIENsaWVudCBrZWluZSBLb21tYW5kb3MgYW4sIGRhaGVyIGlnbm9yaWVyZW4uCisgIEdNQ1BfREVCVUcoIkdNQ1Btb2RfY2hhcl92MV9yZWN2IiwiQ2xpZW50LUtvbW1hbmRvIGlnbm9yaWVydDogIitjbWQsMjApOworfQorCisKKy8vIEhhbmRsZXIgZnVlciBkYXMgIkNoYXIiIE1vZHVsIHZvbiBHTUNQIChNb2R1bCB2b24gSVJFKQorLy8gR2VydWZlbiwgd2VubiBEYXRlbiB6dSBzZW5kZW4gc2luZC4KK3Byb3RlY3RlZCB2b2lkIEdNQ1Btb2RfQ2hhcl92MV9zZW5kKG1hcHBpbmcgZGF0YSkKK3sKKyAgbWFwcGluZyBzcXVldWUgPSBtX2FsbG9jYXRlKDQsMCk7CisgIHN0cnVjdCBnbWNwX21vZF9zIG1vZCA9IGdtY3BkYXRhWyJDaGFyIl07CisgIC8vIG1vZC0+ZGF0YSBmdW5naWVydCBoaWVyIGF1Y2ggYWxzIENhY2hlIGRlciBEYXRlbi4gRGllIG11c3MgbWFuIG5hZW1saWNoCisgIC8vIGxlaWRlciBpbW1lciBhbGxlIHNlbmRlbiwgbmljaHQgbnVyIGRpZSBnZWFlbmRlcnRlbi4KKyAgaWYgKCFtYXBwaW5ncChkYXRhKSkKKyAgeworICAgIC8vIEFsbGUgdmVyZnVlZ2JhcmVuIEluZm9ybWF0aW9uZW4gc2VuZGVuLi4uCisgICAgbW9kLT5kYXRhID0gbV9hbGxvY2F0ZSg0KTsKKyAgICBtX2FkZChtb2QtPmRhdGEsIkNoYXIuVml0YWxzIiwgKFsiaHAiOiBRdWVyeVByb3AoUF9IUCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1wIjogUXVlcnlQcm9wKFBfU1ApLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtYXhocCI6IFF1ZXJ5UHJvcChQX01BWF9IUCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1heG1wIjogUXVlcnlQcm9wKFBfTUFYX1NQKSBdKSApOworICAgIG1fYWRkKG1vZC0+ZGF0YSwiQ2hhci5TdGF0dXMiLCAoWyJsZXZlbCI6IFF1ZXJ5UHJvcChQX0xFVkVMKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZ3VpbGQiOiBRdWVyeVByb3AoUF9HVUlMRCkgXSkgKTsKKyAgICBtX2FkZChzcXVldWUsIkNoYXIuVml0YWxzIik7CisgICAgbV9hZGQoc3F1ZXVlLCJDaGFyLlN0YXR1cyIpOworICAgIC8vIGRpZXMgd2lyZCBkaXJla3QgZ2VzZW5kZXQsIHdlaWwgZXMgbmljaHQgZ2VzcGVpY2hlcnQgd2VyZGVuIG11c3MuICh3aXJkCisgICAgLy8gbnVyIGJlaW0gU3RhcnQgZGVzIE1vZHVscyBnZXNlbmRldCkuCisgICAgR01DUF9zZW5kKCJDaGFyLlN0YXR1c1ZhcnMiLCAoWworICAgICAgICAgICJsZXZlbCI6ICJTcGllbGVyc3R1ZmUiLCAiZ3VpbGQiOiAiR2lsZGUiIF0pICk7CisgIH0KKyAgZWxzZQorICB7CisgICAgLy8gbnVyIGRpZSBpbiBkYXRhIGVudGhhbHRlbmVuIHNlbmRlbi4KKyAgICAvLyBqZXR6dCBlcnN0bWFsIGFsbGVzIGF1cyBkYXRhIHNvIHNvcnRpZXJlbiwgd2llIGVzIGdlc2VuZGV0IHdlcmRlbgorICAgIC8vIG11c3MuLi4gKnNldWZ6KgorICAgIGZvcmVhY2goc3RyaW5nIGtleSwgbWl4ZWQgdmFsIDogZGF0YSkKKyAgICB7CisgICAgICBzd2l0Y2goa2V5KQorICAgICAgeworICAgICAgICBjYXNlIFBfSFA6CisgICAgICAgICAgKG1vZC0+ZGF0YSlbIkNoYXIuVml0YWxzIl0gKz0gKFsiaHAiOiB2YWxdKTsKKyAgICAgICAgICBtX2FkZChzcXVldWUsIkNoYXIuVml0YWxzIik7CisgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgUF9TUDoKKyAgICAgICAgICAobW9kLT5kYXRhKVsiQ2hhci5WaXRhbHMiXSArPSAoWyJtcCI6IHZhbF0pOworICAgICAgICAgIG1fYWRkKHNxdWV1ZSwiQ2hhci5WaXRhbHMiKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBQX01BWF9IUDoKKyAgICAgICAgICAobW9kLT5kYXRhKVsiQ2hhci5WaXRhbHMiXSArPSAoWyJtYXhocCI6IHZhbF0pOworICAgICAgICAgIG1fYWRkKHNxdWV1ZSwiQ2hhci5WaXRhbHMiKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBQX01BWF9TUDoKKyAgICAgICAgICAobW9kLT5kYXRhKVsiQ2hhci5WaXRhbHMiXSArPSAoWyJtYXhtcCI6IHZhbF0pOworICAgICAgICAgIG1fYWRkKHNxdWV1ZSwiQ2hhci5WaXRhbHMiKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBQX0xFVkVMOgorICAgICAgICBjYXNlIFBfR1VJTEQ6CisgICAgICAgICAgKG1vZC0+ZGF0YSlbIkNoYXIuU3RhdHVzIl0gKz0gKFtrZXk6IHZhbF0pOworICAgICAgICAgIG1fYWRkKHNxdWV1ZSwiQ2hhci5TdGF0dXMiKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgR01DUF9ERUJVRygiR01DUG1vZF9DaGFyX3YxX3NlbmQoKSIsCisgICAgICBzcHJpbnRmKCJEYXRhIHJlYWR5OiAlTywgU2VuZHF1ZXVlOiAlTyIsbW9kLT5kYXRhLCBzcXVldWUpLDUwKTsKKworICAvLyBKZXR6dCBkaWUgc3F1ZXVlIHNlbmRlbi4uLgorICBmb3JlYWNoKHN0cmluZyBrZXkgOiBzcXVldWUpCisgIHsKKyAgICBHTUNQX3NlbmQoa2V5LCAobW9kLT5kYXRhKVtrZXldKTsKKyAgfQorfQorCisvLyBIYW5kbGVyIGZ1ZXIgZGFzICJjaGFyIiBNb2R1bCB2b24gR01DUCAoTW9kdWwgdm9uIEFhcmR3b2xmKQorLy8gR2VydWZlbiBiZWkgRW1wZmFuZyB2b24gS29tbWFuZG9zIHZvbSBDbGllbnQuCitwcm90ZWN0ZWQgdm9pZCBHTUNQbW9kX0NoYXJfdjFfcmVjdihzdHJpbmcgY21kLCBtaXhlZCBhcmdzKQoreworICAvLyBkaWVzZXMgTW9kdWwgYmlldGV0IGRlbSBDbGllbnQga2VpbmUgS29tbWFuZG9zIGFuLCBkYWhlciBpZ25vcmllcmVuLgorICBHTUNQX0RFQlVHKCJHTUNQbW9kX0NoYXJfdjFfcmVjdiIsIkNsaWVudC1Lb21tYW5kbyBpZ25vcmllcnQ6ICIrY21kLDIwKTsKK30KKworCisvLyBIYW5kbGVyLCBkZXIgdm9uIHRlbG5ldG5lZy5jIGdlcnVmZW4gd2lyZC4KK3ByaXZhdGUgdm9pZCBfc3RkX3JlX2hhbmRsZXJfZ21jcChzdHJ1Y3QgdGVsb3B0X3Mgb3B0LCBpbnQgYWN0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAqb3B0YXJncykKK3sKKyAgc3dpdGNoKGFjdGlvbikKKyAgeworICAgIGNhc2UgTE9DQUxPTjoKKyAgICAgIC8vIHN1cGVyIQorICAgICAgR01DUF9ERUJVRygicmVjdjoiLCAiTE9DQUxPTiIsMTApOworICAgICAgZ21jcGRhdGEgPSAoW10pOworICAgICAgb3B0LT5kYXRhID0gZ21jcGRhdGE7ICAgLy8gZGF0ZW4gYXVjaCBkb3J0IGFibGVnZW4uCisgICAgICAvLyBDb3JlbW9kdWxlIGluIGRlciBWZXJzaW9uIDEgcmVnaXN0cmllcmVuIChlcyBnaWJ0IG51ciBlaW5lKS4KKyAgICAgIEdNQ1BfcmVnaXN0ZXJfbW9kdWxlKCJDb3JlIDEiKTsKKyNpZmRlZiBfX0dNQ1BfREVCVUdfXworICAgICAgR01DUG1vZF9Db3JlX3YxX3JlY3YoIkNvcmUuRGVidWciLDMwKTsKKyNlbmRpZgorICAgICAgYnJlYWs7CisgICAgY2FzZSBMT0NBTE9GRjoKKyAgICAgIC8vIGFsbGVzIGFic2NoYWx0ZW4gdW5kIERhdGVuIGxvZXNjaGVuCisgICAgICBHTUNQX0RFQlVHKCJyZWN2OiIsICJMT0NBTE9GRiIsMTApOworICAgICAgb3B0LT5kYXRhID0gMDsKKyAgICAgIGdtY3BkYXRhID0gMDsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgUkVNT1RFT046CisgICAgY2FzZSBSRU1PVEVPRkY6CisgICAgICAvLyBIdWNoLiBBdWYgQ2xpZW50c2VpdGUgaXN0IEdNQ1AgZWlnZW50bGljaCBuaWUgYW4uIElnbm9yaWVyZW4uLi4KKyAgICAgIEdNQ1BfREVCVUcoInJlY3Y6IiwgIkh1aD8gUkVNT1RFIHN0YXRlIGNoYW5nZWQ/Iiw1MCk7CisgICAgICBicmVhazsKKyAgICBjYXNlIFNCOgorICAgICAgLy8gRGVyIGVpZ2VudGxpY2ggaW50ZXJlc3NhbnRlIEZhbGwuLi4gR01DUC1Lb21tYW5kb3MKKyAgICAgIGlmICghbWFwcGluZ3AoZ21jcGRhdGEpKSByZXR1cm47IC8vIEdNQ1Agd29obCBuaWNodCBlaW5nZXNjaGFsdGV0Li4uCisgICAgICBzdHJpbmcgY21kOworICAgICAgbWl4ZWQgYXJnczsKKyAgICAgIHN0cmluZyBwYXlsb2FkPXRvX3N0cmluZyhvcHRhcmdzKTsKKyAgICAgIEdNQ1BfREVCVUcoInJlY3YiLCBwYXlsb2FkLDEwKTsKKyAgICAgIGlmIChzc2NhbmYocGF5bG9hZCwiJXMgJXMiLCBjbWQsIGFyZ3MpICE9IDIpIHsKKyAgICAgICAgLy8gaXN0IHZlcm11dGxpY2ggZWluIEtvbW1hbmRvIG9obmUgZGF0ZW4gKG9kZXIgTXVlbGwpCisgICAgICAgIGNtZCA9IHBheWxvYWQ7CisgICAgICAgIC8vYXJncyA9IDA7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIHN0cmluZyBlcnI9Y2F0Y2goYXJncyA9IGpzb25fcGFyc2UoYXJncyk7bm9sb2cpOworICAgICAgICBpZiAoZXJyKQorICAgICAgICB7CisgICAgICAgICAgcHJpbnRmKCJcbkZlaGxlciBiZWltIFBhcnNlbiBlaW5lciBHTUNQLU5hY2hyaWNodDogJXMuICIKKyAgICAgICAgICAgICAgICAgIk5hY2hyaWNodCB3YXI6ICclcydcbiIKKyAgICAgICAgICAgICAgICAgIkJlZmVobDogJyVzJywgQXJndW1lbnQ6ICclcydcblxuIixlcnIscGF5bG9hZCxjbWQsYXJnc3x8IiIpOworICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgR01DUF9ERUJVRygicmVjdiIsIHNwcmludGYoIkNvbW1hbmQ6ICVzLCBEYXRhOiAlTyIsIGNtZCwgYXJncyksMjApOworCisgICAgICBzdHJpbmcgKmNtZHBhcnRzID0gZXhwbG9kZShjbWQsICIuIik7CisgICAgICBzdHJ1Y3QgZ21jcF9tb2RfcyBtb2Q7CisgICAgICBzdHJpbmcgbW9kbmFtZTsKKyAgICAgIC8vIHZlcnN1Y2gsIGVpbiBNb2R1bCBmdWVyIGRhcyBLb21tYW5kbyB6dSBmaW5kZW4uIEFuZmFuZ2VuIG1pdCBkZXIKKyAgICAgIC8vIEFubmFobWUsIGRhc3MgYmlzIHp1bSBsZXR6dGVuIFB1bmt0IGRlciBNb2R1bG5hbWUgZ2VodCB1bmQgZGFubgorICAgICAgLy8gaW4gamVkZW0gY2FzZSBlaW5lbiBQdW5rdCBrdWVyemVyIHdlcmRlbmQuCisgICAgICBzd2l0Y2goc2l6ZW9mKGNtZHBhcnRzKSkKKyAgICAgIHsKKyAgICAgICAgY2FzZSA0OgorICAgICAgICAgIG1vZG5hbWUgPSBpbXBsb2RlKGNtZHBhcnRzWzAuLjJdLCIuIik7CisgICAgICAgICAgR01DUF9ERUJVRygidHJ5aW5nIG1vZG5hbWUuLi4gIiwgbW9kbmFtZSwgMjAgKTsKKyAgICAgICAgICBpZiAobWVtYmVyKGdtY3BkYXRhLCBtb2RuYW1lKSkgeworICAgICAgICAgICAgbW9kID0gZ21jcGRhdGFbbW9kbmFtZV07CisgICAgICAgICAgICBmdW5jYWxsKG1vZC0+cmVjdmNsLCBjbWQsIGFyZ3MpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgfQorICAgICAgICAgIC8vIEZhbGwtdGhyb3VnaCEKKyAgICAgICAgY2FzZSAzOgorICAgICAgICAgIG1vZG5hbWUgPSBpbXBsb2RlKGNtZHBhcnRzWzAuLjFdLCIuIik7CisgICAgICAgICAgR01DUF9ERUJVRygidHJ5aW5nIG1vZG5hbWUuLi4gIiwgbW9kbmFtZSwgMjApOworICAgICAgICAgIGlmIChtZW1iZXIoZ21jcGRhdGEsIG1vZG5hbWUpKSB7CisgICAgICAgICAgICBtb2QgPSBnbWNwZGF0YVttb2RuYW1lXTsKKyAgICAgICAgICAgIGZ1bmNhbGwobW9kLT5yZWN2Y2wsIGNtZCwgYXJncyk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICB9CisgICAgICAgICAgLy8gRmFsbC10aHJvdWdoIQorICAgICAgICBjYXNlIDI6CisgICAgICAgICAgbW9kbmFtZSA9IGltcGxvZGUoY21kcGFydHNbMC4uMF0sIi4iKTsKKyAgICAgICAgICBHTUNQX0RFQlVHKCJ0cnlpbmcgbW9kbmFtZS4uLiAiLCBtb2RuYW1lLCAyMCk7CisgICAgICAgICAgaWYgKG1lbWJlcihnbWNwZGF0YSwgbW9kbmFtZSkpIHsKKyAgICAgICAgICAgIG1vZCA9IGdtY3BkYXRhW21vZG5hbWVdOworICAgICAgICAgICAgZnVuY2FsbChtb2QtPnJlY3ZjbCwgY21kLCBhcmdzKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0KKyAgICAgICAgICAvLyBIaWVyIGlzdHMgamV0enQgbmVuIEZlaGxlci4KKyAgICAgICAgICBHTUNQRVJST1Ioc3ByaW50ZigiVW5rbm93biBHTUNQIG1vZHVsZSBmb3IgY21kICVzIixjbWQpKTsKKyAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAvLyB6dXZpZWxlIG9kZXIgenV3ZW5pZyAuIDstKQorICAgICAgICAgIEdNQ1BFUlJPUihzcHJpbnRmKCJJbGxlZ2FsIEdNQ1AgY21kICVzIHdpdGggYXJncyAlTyIsCisgICAgICAgICAgICAgICAgY21kLCBhcmdzKSk7CisgICAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICAvLyBzYmRhdGEgYnJhdWNoZW4gd2lyIGVpZ2VudGxpY2ggbmljaHQgbWVoci4KKyAgICAgIG9wdC0+cmVfd2lzaGVzLT5zYmRhdGEgPSAwOworICAgICAgYnJlYWs7CisgIH0gLy8gc3dpdGNoIChhY3Rpb24pCit9CisKKy8vIHdpcmQgdm9uIGJhc2UuYyBuYWNoIEtvbm5la3RpZXJ1bmcgZ2VydWZlbi4KKy8vIERhcmYgYWJlciBlcnN0IGdlcnVmZW4gd2VyZGVuLCB3ZW5uIGRhcyBTcGllbGVyb2JqZWt0IGZlcnRpZyBpbml0aWFsaXNpZXJ0CisvLyB1bmQgZWluZ2VsZXNlbiBpc3QuCitwcm90ZWN0ZWQgdm9pZCBzdGFydHVwX3RlbG5ldF9uZWdzKCkKK3sKKyAgLy8gZXZ0bC4gd2FyIGVzIGVpbiByZWNvbm5lY3QsIGRhbm4gc3RlaHQgaW4gZ21jcCBub2NoIGFsdGVyIGtyYW0gZHJpbi4gRGVyCisgIC8vIG11c3Mgd2VnLCBrb2VubnRlIGphIGF1Y2ggc2VpbiwgZGFzcyBkZXIgQ2xpZW50IChqZXR6dCkga2VpbiBHTUNQCisgIC8vIG1laHIKKyAgLy8gd2lsbC4KKyAgZ21jcGRhdGEgPSAwOworCisgIC8vIEhhY2sgYmVzb25kZXJlciBTb3J0ZTogR01DUCBzb2xsIGxva2FsIGVpbmdlc2NoYWx0ZXQgc2Vpbi4gQXVmCisgIC8vIENsaWVudHNlaXRlbiBpc3QgZXMgbGF1dCBQcm90b2tvbGwgbmljaHQgdm9yZ2VzZWhlbiwgZGFoZXIgZHVlcmZlbgorICAvLyAoc29sbHRlbj8pIHdpciBrZWluIERPIGFuIGRlbiBDbGllbnQgc2VuZGVuLiBXaXIgYnJhdWNoZW4gYWJlciBlaW5lbgorICAvLyByZW1vdGUgaGFuZGxlciwgdW0gZGllIFd1ZW5zY2hlIHZvbSBDbGllbnQgenUgdmVyYXJiZWl0ZW4uIERhaGVyIGVyc3RtYWwKKyAgLy8gbnVyIGRlbiBsb2NhbCBoYW5kbGVyIGJpbmRlbiAodW5kIGdsZWljaHplaXRpZyBuZWdvdGlhdGlvbiBhbnN0b3NzZW4pIHVuZAorICAvLyBkYW5uIGRpcmVrdCBkYW5hY2ggZGVuIHJlbW90ZSBoYW5kbGVyIGF1Y2ggYmluZGVuIChvaG5lIGVybmV1dGUKKyAgLy8gbmVnb3RpYXRpb24genUgc3RhcnRlbikuIEFjaGphIHVuZCB3aXIgbmVobWVuIGRpZSBnbGVpY2hlIEZ1bmt0aW9uIGFscworICAvLyBIYW5kbGVyIGZ1ZXIgcmVtb3RlIHVuZCBsb2thbC4KKyAgYmluZF90ZWxuZWdfaGFuZGxlcihURUxPUFRfR01DUCwgMCwgIydfc3RkX3JlX2hhbmRsZXJfZ21jcCwgMSk7CisgIGJpbmRfdGVsbmVnX2hhbmRsZXIoVEVMT1BUX0dNQ1AsICMnX3N0ZF9yZV9oYW5kbGVyX2dtY3AsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMnX3N0ZF9yZV9oYW5kbGVyX2dtY3AsIDApOworfQorCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL3F1ZXN0cy5jIGIvc3RkL3BsYXllci9xdWVzdHMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYWU1NjZkCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9xdWVzdHMuYwpAQCAtMCwwICsxLDI0NCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHBsYXllci9xdWVzdHMuYyAtLSBxdWVzdCBoYW5kbGVyCisvLworLy8gJElkOiBxdWVzdHMuYyA5MTQyIDIwMTUtMDItMDQgMjI6MTc6MjlaIFplc3N0cmEgJAorCisvLyBEaWVzZXMgTW9kdWwgZW5oYWVsdCBkaWUgUXVlc3Qtc3BlemlmaXNjaGVuIFRlaWxlIGRlciBQbGF5ZXJvYmpla3RlLgorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHBsYXllci9saWZlLmg+CisjaW5jbHVkZSA8cGxheWVyL3F1ZXN0Lmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHBsYXllci9iYXNlLmg+CisjaW5jbHVkZSA8bGl2aW5nL2xpZmUuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgIi9zZWN1cmUvcXVlc3RtYXN0ZXIuaCIKKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxkYWVtb24uaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPG1haWwuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxldmVudHMuaD4KKworbWl4ZWQgcXVlc3RzOworCitpbnQgUXVlcnlRdWVzdChzdHJpbmcgcXVlc3RuYW1lKTsKKy8vIGxvY2FsIHByb3BlcnRpZXMgcHJvdG90eXBlCitzdGF0aWMgbWl4ZWQgX3F1ZXJ5X3F1ZXN0cygpOworc3RhdGljIGludCAgIF9xdWVyeV9xdWVzdHBvaW50cygpOworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CisgIFNldChQX1FVRVNUUywgTk9TRVRNRVRIT0QsIEZfU0VUX01FVEhPRCk7CisgIFNldChQX1FVRVNUUywgcXVlc3RzID0gKFtdKSwgRl9WQUxVRSk7CisgIFNldChQX1FVRVNUUywgU0VDVVJFRCwgRl9NT0RFKTsKKyAgU2V0KFBfUVAsIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX1FQLCBTRUNVUkVELCBGX01PREUpOworfQorCit2YXJhcmdzIGludCBHaXZlUXVlc3Qoc3RyaW5nIHF1ZXN0bmFtZSwgc3RyaW5nIG1lc3NhZ2UpIHsKKyAgbWl4ZWQgKnF1ZXN0ID0gUU0tPlF1ZXJ5UXVlc3QocXVlc3RuYW1lKTsKKworICAvLyBRdWVzdG5hbWUgdW5ndWVsdGlnCisgIGlmICghcXVlc3R8fCFwb2ludGVycChxdWVzdCl8fHF1ZXN0PT0oe30pKQorICAgIHJldHVybiBHUV9LRVlfSU5WQUxJRDsKKyAgLy8gVW5iZWZ1Z3RlciBadWdyaWZmIGF1ZiBkZWFrdGl2aWVydGUgUXVlc3QKKyAgaWYgKCFxdWVzdFs2XSYmIUlTX0FSQ0godGhpc19pbnRlcmFjdGl2ZSgpKSkKKyAgICByZXR1cm4gR1FfSVNfSU5BQ1RJVkU7CisgIC8vIFVuYmVmdWd0ZXIgWnVncmlmZgorICBpZiAobWVtYmVyKHF1ZXN0WzJdLCBsb2FkX25hbWUocHJldmlvdXNfb2JqZWN0KCkpKT09LTEgJiYKKyAgICAgICFJU19BUkNIKHRoaXNfaW50ZXJhY3RpdmUoKSkpCisgICAgcmV0dXJuIEdRX0lMTEVHQUxfT0JKOworCisgIC8vIEdpbGRlIHdpcmQgaW4gamVkZW0gRmFsbCBpbmZvcm1pZXJ0LgorICBzdHJpbmcgZ3VpbGQ9R1VJTERfRElSK1F1ZXJ5UHJvcChQX0dVSUxEKTsKKyAgaWYgKGZpbmRfb2JqZWN0KGd1aWxkKSB8fCBmaWxlX3NpemUoZ3VpbGQrIi5jIik+LTEpCisgICAgY2F0Y2goIGNhbGxfb3RoZXIoZ3VpbGQsICJOb3RpZnlHaXZlUXVlc3QiLCBNRSwgcXVlc3RuYW1lKTtwdWJsaXNoICk7CisKKyAgLy8gUXVlc3QgYmVyZWl0cyBnZXNldHp0CisgIGlmIChRdWVyeVF1ZXN0KHF1ZXN0bmFtZSkpCisgICAgcmV0dXJuIEdRX0FMUkVBRFlfU0VUOworICBBZGRFeHAocXVlc3RbMV0pOworICBxdWVzdHMgKz0gKFsgcXVlc3RuYW1lIDogcXVlc3RbMF07IHRpbWUoKSBdKTsKKyAgZm9yY2Vfc2F2ZSgpOworICAvLyBFdmVudCBhdXNsb2VzZW4KKyAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoRVZUX0xJQl9RVUVTVF9TT0xWRUQsKFsKKyAgICAgICAgICAgICBFX09CSkVDVDogTUUsCisgICAgICAgICAgICAgRV9QTE5BTUU6IGdldHVpZChNRSksCisgICAgICAgICAgICAgRV9FTlZJUk9OTUVOVDogZW52aXJvbm1lbnQoKSwKKyAgICAgICAgICAgICBFX1FVRVNUTkFNRTogcXVlc3RuYW1lLAorICAgICAgICAgICAgIEVfUVBfR1JBTlRFRDogcXVlc3RbMF0gXSkgKTsKKworICBpZiAobWVzc2FnZSAmJiBtZXNzYWdlIT0iIikgeworICAgIGlmIChtZXNzYWdlIT0iX19zaWxlbnRfXyIpIHsKKyAgICAgIG1lc3NhZ2U9aW1wbG9kZShleHBsb2RlKG1lc3NhZ2UsIkBAbmFtZUBAIiksCisgICAgICAgICAgY2FwaXRhbGl6ZShxdWVyeV9yZWFsX25hbWUoKSkpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgIG1lc3NhZ2U9IiI7CisgICAgfQorICB9CisgIGVsc2UKKyAgICBtZXNzYWdlPWNhcGl0YWxpemUocXVlcnlfcmVhbF9uYW1lKCkpCisgICAgICArIiBoYXQgZ2VyYWRlIGVpbiBBYmVudGV1ZXIgYmVzdGFuZGVuOiAiKyBxdWVzdG5hbWUrIlxuIjsKKyAgaWYobWVzc2FnZSE9IiIpCisgICAgY2F0Y2goUU0tPkNoYW5uZWwobWVzc2FnZSk7cHVibGlzaCk7CisgIGNhdGNoKFFNLT5TZW5kTWFpbChxdWVzdG5hbWUsIHF1ZXN0LCBNRSk7cHVibGlzaCk7CisgIHJldHVybiBPSzsKK30KKworaW50IERlbGV0ZVF1ZXN0KHN0cmluZyBxdWVzdG5hbWUpIHsKKyAgLy8gUXVlc3QgaXN0IG5pY2h0IGdlc2V0enQKKyAgaWYoIVF1ZXJ5UXVlc3QocXVlc3RuYW1lKSkKKyAgICByZXR1cm4gRFFfTk9UX1NFVDsKKworICBtaXhlZCAqcXVlc3QgPSBRTS0+UXVlcnlRdWVzdChxdWVzdG5hbWUpOworICAvLyBRdWVzdG5hbWUgdW5ndWVsdGlnCisgIGlmICghcXVlc3R8fCFwb2ludGVycChxdWVzdCl8fHF1ZXN0PT0oe30pKQorICAgIHJldHVybiBEUV9LRVlfSU5WQUxJRDsKKyAgLy8gVW5iZWZ1Z3RlciBadWdyaWZmCisgIGlmICghSVNfQVJDSCh0aGlzX2ludGVyYWN0aXZlKCkpKQorICAgIHJldHVybiBEUV9JTExFR0FMX09CSjsKKyAgQWRkRXhwKC1xdWVzdFsxXSk7CisgIG1fZGVsZXRlKHF1ZXN0cywgcXVlc3RuYW1lKTsKKyAgZm9yY2Vfc2F2ZSgpOworICByZXR1cm4gT0s7Cit9CisKK2ludCBRdWVyeVF1ZXN0KHN0cmluZyBxdWVzdG5hbWUpIHsKKyAgaW50IGR1bW15OworCisgIC8vIEdhZXN0ZSBoYWJlbiBrZWluZSBRdWVzdHMuCisgIGlmKCBzc2NhbmYoIGdldHVpZCgpLCAiZ2FzdCVkIiwgZHVtbXkgKSA9PSAxICkKKyAgICByZXR1cm4gUVFfR1VFU1Q7CisgIC8vIFVlYmVyZ2ViZW5lciBQYXJhbWV0ZXIgInF1ZXN0bmFtZSIgdW5ndWVsdGlnIG9kZXIgbGVlcj8KKyAgaWYoIXF1ZXN0bmFtZSB8fCAhc3RyaW5ncChxdWVzdG5hbWUpIHx8IHF1ZXN0bmFtZSA9PSAiIikKKyAgICByZXR1cm4gUVFfS0VZX0lOVkFMSUQ7CisgIC8vIFF1ZXN0bmFtZSBpc3QgdGF0c2FlY2hsaWNoIGluIGRlciBRdWVzdGxpc3RlIGVudGhhbHRlbj8gQWxsZXMga2xhciEKKyAgaWYgKCBtZW1iZXIocXVlc3RzLCBxdWVzdG5hbWUpICkKKyAgICByZXR1cm4gT0s7CisgIC8vIEFuc29uc3RlbiB3YXIgZGVyIE5hbWUgd29obCB1bmd1ZWx0aWcuCisgIHJldHVybiBRUV9LRVlfSU5WQUxJRDsKK30KKworaW50IE1vZGlmeVF1ZXN0VGltZShzdHJpbmcgcW5hbWUsIGludCB3aGVuKSB7CisgIGlmICggcHJvY2Vzc19jYWxsKCkgKQorICAgIHJldHVybiAtMTsKKworICAvLyBOdXIgRU0rIG9kZXIgZGVyIFRhZ2VidWNobWFzdGVyIGR1ZXJmZW4gZGllIFdlcnRlIGFlbmRlcm4uCisgIGlmICggIUlTX0FSQ0godGhpc19pbnRlcmFjdGl2ZSgpKSAmJgorICAgIGxvYWRfbmFtZShwcmV2aW91c19vYmplY3QoKSkhPSIvZC93YWxkL2xldXNlbC9xdWVzdC9vYmpzL3RhZ2VidWNoLW1hc3RlciIpCisgICAgcmV0dXJuIC0xOworCisgIC8vIFF1ZXN0bGlzdGUgaXN0IHVuZXJ3YXJ0ZXQga2VpbiBNYXBwaW5nLgorICBpZiAoICFtYXBwaW5ncChxdWVzdHMpICkKKyAgICByZXR1cm4gLTI7CisKKyAgLy8gS2VpbiBRdWVzdG5hbWUgYW5nZWdlYmVuLCBvZGVyIFNwaWVsZXIgaGF0IGRpZXNlIFF1ZXN0IHVlYmVyaGF1cHQgbmljaHQKKyAgLy8gZ2Vsb2VzdC4KKyAgaWYgKCAhc3RyaW5ncChxbmFtZSkgfHwgIW1lbWJlcihxdWVzdHMsIHFuYW1lKSApCisgICAgcmV0dXJuIC0zOworCisgIC8vIERlciBUYWdlYnVjaG1hc3RlciBzZXR6dCBFaW50cmFlZ2UgZ2dmLiBhdWYgMCwgd2VubiBlciBrZWluZSBEYXRlbgorICAvLyBmaW5kZXQsIHVuZCBFTSsgd29sbGVuIEVpbnRyYWVnZSBhdWYgLTEgc2V0emVuIGtvZW5uZW4sIHVtIGRhcyBFaW5sZXNlbgorICAvLyBkZXIgRGF0ZW4gbm9jaCBlaW5tYWwgenUgZXJtb2VnbGljaGVuLCBkLmguIGRpZXNlIFdlcnRlIHNpbmQgenVzYWV0emxpY2gKKyAgLy8genUgZ3VlbHRpZ2VuIFplaXR3ZXJ0ZW4gZXJsYXVidC4KKyAgaWYgKCAhaW50cCh3aGVuKSB8fCB3aGVuIDwgLTEgfHwgd2hlbiA+IHRpbWUoKSApCisgICAgcmV0dXJuIC00OworCisgIC8vIE5ldWVuIFdlcnQgZWludHJhZ2VuLgorICBxdWVzdHNbcW5hbWUsMV0gPSB3aGVuOworICByZXR1cm4gMTsKK30KKworaW50IFF1ZXJ5UXVlc3RUaW1lKHN0cmluZyBxbmFtZSkgeworICByZXR1cm4gcXVlc3RzW3FuYW1lLDFdOworfQorCisvLyBLb252ZXJ0aWVydCBEYXRlbnN0cnVrdHVyIHZvbiBxdWVzdHMgaW4gZWluIE1hcHBpbmcgbWl0IGZvbGdlbmRlbSBBdWZiYXU6CisvLyBxdWVzdHMgPSAoWyAicXVlc3RuYW1lIiA6IEFiZW50ZXVlcnB1bmt0ZTsgWmVpdF9kZXNfUXVlc3RhYnNjaGx1c3NlcywgXSkKK3Byb3RlY3RlZCB2b2lkIHVwZGF0ZXNfYWZ0ZXJfcmVzdG9yZShtaXhlZCBuZXdmbGFnKSB7CisgIC8vIEdhbnogZnJpc2NoZXIgU3BpZWxlcj8gRGFubiBrZWluZSBCZWhhbmRsdW5nIGVyZm9yZGVybGljaC4KKyAgaWYgKCBuZXdmbGFnICkKKyAgICByZXR1cm47CisgIC8vIFdlbm4gZGllIFF1ZXN0bGlzdGUgbm9jaCBrZWluIE1hcHBpbmcgaXN0LCBLb252ZXJ0aWVydW5nIGFuc3Rvc3Nlbi4KKyAgaWYgKCAhbWFwcGluZ3AocXVlc3RzKSApIHsKKyAgICAvLyBXZW5uIG5vY2gga2VpbmUgUXVlc3RzIGVpbmdldHJhZ2VuIHNpbmQsIExlZXJtYXBwaW5nIGVpbnRyYWdlbi4KKyAgICBpZiAoICFzaXplb2YocXVlc3RzKSApIHsKKyAgICAgIHF1ZXN0cyA9IChbOjJdKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisgICAgLy8gVm9yc2ljaHRzaGFsYmVyIExlZXJlaW50cmFlZ2UgcmF1c3ppZWhlbi4KKyAgICBxdWVzdHMgLT0gKHsoe30pfSk7CisgICAgLy8gTGlzdGUgZGVyIFF1ZXN0emVpdGVuIGF1cyBkZW0gU3BpZWxlciBhdXNsZXNlbi4gV2VubiBuaWNodCB2b3JoYW5kZW4sCisgICAgLy8gQXJyYXkgbWl0IC0xLUVsZW1lbnRlbiBwYXNzZW5kZXIgTGFlbmdlIGVyemV1Z2VuLgorICAgIC8vIC0xIGFuIGFsbGVuIFN0ZWxsZW4gZWludHJhZ2VuLCB3byBiaXNoZXIga2VpbmUgRGF0ZW4gdm9ybGllZ2VuLgorICAgIC8vIERpZXNlIHdlcmRlbiBkYW5uIHZvbSBRdWVzdHRhZ2VidWNoIGR1cmNoIGRpZSBEYXRlbiBlcnNldHp0LgorICAgIGludCAqcXRpbWVzID0gUXVlcnlQcm9wKCJxdWVzdHRpbWUiKXx8YWxsb2NhdGUoc2l6ZW9mKHF1ZXN0cyksIC0xKTsKKyAgICAvLyBGYWxscyBkaWUgUXVlc3RsaXN0ZSBsYWVuZ2VyIGlzdCBhbHMgZGllIFplaXRlbmxpc3RlLCB3aXJkIGxldHp0ZXJlCisgICAgLy8gdW0gZGllIGZlaGxlbmRlIExhZW5nZSBpbiBGb3JtIHZvbiAtMS1laW50cmFlZ2VuIGVyZ2Flbnp0LCB1bnRlciBkZXIKKyAgICAvLyBBbm5haG1lLCBkYXNzIGRpZSBmZWhsZW5kZW4gRWludHJhZWdlIGJpc2hlciBsZWRpZ2xpY2ggbmljaHQKKyAgICAvLyBlaW5nZWxlc2VuIHd1cmRlbi4gSW0gdW1nZWtlaHJ0ZW4gRmFsbCB3ZXJkZW4gYWxsZSBaZWl0ZW4gdmVyd29yZmVuLAorICAgIC8vIGRhIGRpZXNlciBGYWxsIGVpbnRyaXR0LCB3ZW5uIGVpbmVtIFNwaWVsZXIgZWluZSBRdWVzdCBhdXNnZXRyYWdlbgorICAgIC8vIHd1cmRlIHVuZCBkaWUgTGlzdGVuIGluIGRlciBWZXJnYW5nZW5oZWl0IG5pY2h0IHN5bmNocm9uIGdlaGFsdGVuCisgICAgLy8gd3VyZGVuLgorICAgIGlmICggc2l6ZW9mKHF0aW1lcykgPCBzaXplb2YocXVlc3RzKSApIHsKKyAgICAgIHF0aW1lcyArPSBhbGxvY2F0ZShzaXplb2YocXVlc3RzKS1zaXplb2YocXRpbWVzKSwgLTEpOworICAgIH0KKyAgICBpZiAoIHNpemVvZihxdGltZXMpID4gc2l6ZW9mKHF1ZXN0cykgKSB7CisgICAgICBxdGltZXMgPSBhbGxvY2F0ZShzaXplb2YocXVlc3RzKSwgLTEpOworICAgIH0KKyAgICAvLyBRdWVzdGRhdGVuIHVuZCBRdWVzdHplaXRlbiB6dXNhbW1lbnBmZXJjaGVuLiBFcmdpYnQgZm9sZy4gTWFwcGluZzoKKyAgICAvLyB0ZW1wID0gKFsgKHtRdWVzdG5hbWUxLCBRUDF9KSA6IFF1ZXN0emVpdCwgLi4uIF0pCisgICAgbWFwcGluZyB0ZW1wID0gbWttYXBwaW5nKHF1ZXN0cywgcXRpbWVzKTsKKyAgICBxdWVzdHMgPSBtX2FsbG9jYXRlKHNpemVvZihxdWVzdHMpLDIpOworICAgIGZvcmVhY2gobWl4ZWQgcWRhdGEsIGludCBxdGltZSA6IHRlbXApIHsKKyAgICAgIHF1ZXN0cyArPSAoWyBxZGF0YVswXSA6IHFkYXRhWzFdOyBxdGltZSBdKTsKKyAgICB9CisgICAgaWYgKFF1ZXJ5UHJvcCgicXVlc3R0aW1lIikpIHsKKyAgICAgIFNldFByb3AoInF1ZXN0dGltZSIsMCk7CisgICAgICBTZXQoInF1ZXN0dGltZSIsIFNBVkUsIEZfTU9ERV9BRCk7CisgICAgfQorICB9Cit9CisKKy8vICoqKiogbG9jYWwgcHJvcGVydHkgbWV0aG9kcworc3RhdGljIGludCBfcXVlcnlfcXVlc3Rwb2ludHMoKSB7CisgIGludCBxcDsKKworICBpZiAoICFtYXBwaW5ncChxdWVzdHMpIHx8ICFzaXplb2YocXVlc3RzKSApIHsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIGNsb3N1cmUgcXFwID0gc3ltYm9sX2Z1bmN0aW9uKCJRdWVyeVF1ZXN0UG9pbnRzIiwgUU0pOworICAvLyBEaWUgYWt0dWVsbCBndWVsdGlnZW4gQWJlbnRldWVycHVua3RlIGF1cyBkZW0gUXVlc3RtYXN0ZXIgaG9sZW4gdW5kCisgIC8vIGRpZSBRdWVzdGxpc3RlIGRhbWl0IGFrdHVhbGlzaWVyZW4uIHFwIHdpcmQgYWxzIFJlZmVyZW56IG1pdCB1ZWJlcmdlYmVuCisgIC8vIGRhbWl0IGRhcyBBZGRpdGlvbnNlcmdlYm5pcyBhdWNoIG5hY2ggZGVtIER1cmNobGF1ZiBhdXNzZXJoYWxiIGRlcgorICAvLyBDbG9zdXJlIHZlcmZ1ZWdiYXIgaXN0LgorICAvLyBGYWxscyBBYmVudGV1ZXJwdW5rdGUgPCAwIGV4aXN0aWVyZW4sIHdpcmQgZGllIGVudHNwcmVjaGVuZGUgUXVlc3QKKyAgLy8gYXVzIGRlciBMaXN0ZSBhdXNnZXRyYWdlbi4KKyAgd2Fsa19tYXBwaW5nKHF1ZXN0cywKKyAgICBmdW5jdGlvbiB2b2lkIChzdHJpbmcgcW5hbWUsIGludCBxcG9pbnRzLCBpbnQgcXRpbWUsIGludCBzdW0pCisgICAgeworICAgICAgcXBvaW50cyA9IGZ1bmNhbGwocXFwLCBxbmFtZSk7CisgICAgICBpZiAocXBvaW50czwwKQorICAgICAgICBtX2RlbGV0ZShxdWVzdHMscW5hbWUpOworICAgICAgZWxzZQorICAgICAgICBzdW0gKz0gcXBvaW50czsKKyAgICB9LCAmcXApOworCisgIFNldChQX1FQLCBxcCk7CisgIHJldHVybiBxcDsKK30KKworc3RhdGljIG1peGVkIF9xdWVyeV9xdWVzdHMoKSB7CisgIHJldHVybiBjb3B5KHF1ZXN0cyk7Cit9CmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL3JlcHV0YXRpb24uYyBiL3N0ZC9wbGF5ZXIvcmVwdXRhdGlvbi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjlmYjNkMTcKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL3JlcHV0YXRpb24uYwpAQCAtMCwwICsxLDczIEBACisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxyZXB1dGF0aW9uLmg+CisKK3ByaXZhdGUgbWFwcGluZyByZXB1dGF0aW9ucyA9IChbIF0pOworCisvKgorICogQXJndW1lbnRlOgorICogcmVwaWQgPSBSZXB1dGF0aW9uLUlEIGltIFJlcG1hc3RlcgorICogdmFsdWUgPSBXZXJ0IHVtIGRlbiBkaWUgUmVwdXRhdGlvbiBnZWFlbmRlcnQgd2VyZGVuIHNvbGwsCisgKiAgICAgICAgIHBvc2l0aXYgb2RlciBuZWdhdGl2CisgKiBzaWxlbnQgPSBLZWluZSBTdGQtTWVsZHVuZyBhdXNnZWJlbgorICoKKyAqIFJldHVybjoKKyAqIFJFUF9SRVRfV1JPTkdBUkdTID0gRmFsc2NoZSBBcmd1bWVudGUKKyAqIFJFUF9SRVRfSU5BQ1RJVkUgPSBSZXAgaW5ha3RpdiAoa2FubiBkZXJ6ZWl0IG5pY2h0IGdlYWVuZGVydCB3ZXJkZW4pCisgKiBSRVBfUkVUX0lOVkFMSURVSUQgPSBVbnp1bGFlc3NpZSBVSUQKKyAqIFJFUF9SRVRfQUxSRUFEWU1BWCA9IFJlcCBiZXJlaXRzIG1heGltdW0gLyBtaW5pbXVtCisgKiBSRVBfUkVUX0lOVkFMSURSRVAgPSBSZXB1dGF0aW9uIG5pY2h0IHZvcmhhbmRlbgorICoKKyAqIFJFUF9SRVRfU1VDQ0VTUyA9IFJlcHV0YXRpb24gd3VyZGUgdmVyYWVuZGVydAorICogUkVQX1JFVF9TVUNDRVNTQ1VUID0gUmVwdXRhdGlvbiB3dXJkZSBhdWYgTWluIC8gTWF4IHZlcmFlbmRlcnQKKyAqLworcHVibGljIHZhcmFyZ3MgaW50IENoYW5nZVJlcHV0YXRpb24oc3RyaW5nIHJlcGlkLCBpbnQgdmFsdWUsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNpbGVudCkgeworICBzdHJpbmcgdWlkLCBjaGFuZ2Vtc2c7IGludCBuZXd2YWw7IG1hcHBpbmcgcmVwOworICAKKyAgaWYoIWludHAodmFsdWUpIHx8ICF2YWx1ZSB8fCAhc3RyaW5ncChyZXBpZCkgfHwgIXNpemVvZihyZXBpZCkpIAorICAgIHJldHVybiBSRVBfUkVUX1dST05HQVJHUzsKKyAgaWYoIW1hcHBpbmdwKHJlcCA9IFJFUE1BU1RFUi0+R2V0UmVwdXRhdGlvbkRhdGEocmVwaWQpKSkKKyAgICByZXR1cm4gUkVQX1JFVF9JTlZBTElEUkVQOworICBpZighKHJlcFsiZmxhZ3MiXSAmIFJFUF9GTEFHX0FDVElWRSkpCisgICAgcmV0dXJuIFJFUF9SRVRfSU5BQ1RJVkU7CisgIGlmKFJFUE1BU1RFUi0+Q2hlY2tWYWxpZFVpZChyZXBpZCwgcHJldmlvdXNfb2JqZWN0KCkpIDwgMSkKKyAgICByZXR1cm4gUkVQX1JFVF9JTlZBTElEVUlEOworICBpZihyZXB1dGF0aW9uc1tyZXBpZF0gPj0gUkVQX01BWElNVU0gfHwgcmVwdXRhdGlvbnNbcmVwaWRdIDw9IFJFUF9NSU5JTVVNKSAKKyAgICByZXR1cm4gUkVQX1JFVF9BTFJFQURZTUFYOworCisgIGlmKHJlcHV0YXRpb25zW3JlcGlkXSArIHZhbHVlID4gUkVQX01BWElNVU0pIAorICAgIG5ld3ZhbCA9IHJlcHV0YXRpb25zW3JlcGlkXSArIHZhbHVlIC0gUkVQX01BWElNVU07CisgIGVsc2UgaWYocmVwdXRhdGlvbnNbcmVwaWRdIC0gdmFsdWUgPCBSRVBfTUlOSU1VTSkKKyAgICBuZXd2YWwgPSByZXB1dGF0aW9uc1tyZXBpZF0gKyB2YWx1ZSArIFJFUF9NSU5JTVVNOworCisgIGlmKCFzaWxlbnQgJiYKKyAgICAgc3RyaW5ncChjaGFuZ2Vtc2cgPSBSRVBNQVNURVItPkdldERlZmF1bHRDaGFuZ2VNc2cocmVwaWQsIAorICAgICAgIG5ld3ZhbCB8fCB2YWx1ZSkpKQorICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksIGNoYW5nZW1zZyk7CisKKyAgcmVwdXRhdGlvbnNbcmVwaWRdICs9IG5ld3ZhbCB8fCB2YWx1ZTsKKworICByZXR1cm4gbmV3dmFsID8gUkVQX1JFVF9TVUNDRVNTQ1VUIDogUkVQX1JFVF9TVUNDRVNTOworfQorCisvKgorICogQXJndW1lbnRlOgorICogcmVwaWQgPSBSZXB1dGF0aW9uLUlEIGltIFJlcG1hc3RlcgorICoKKyAqIFJldHVybjoKKyAqIDAgPSBSZXB1dGF0aW9uIG5vY2ggbmljaHQgdmVyYWVuZGVydCAvIGVudGhhbHRlbiAKKyAqICEwID0gUmVwdXRhdGlvbnN3ZXJ0CisgKi8KK3B1YmxpYyBpbnQgR2V0UmVwdXRhdGlvbihzdHJpbmcgcmVwaWQpIHsgcmV0dXJuIHJlcHV0YXRpb25zW3JlcGlkXTsgfQorCisvKgorICogUmV0dXJuOgorICogTWFwcGluZ2tvcGllIGFsbGVyIGdlc3BlaWNoZXJ0ZW4gUmVwdXRhdGlvbnN3ZXJ0CisgKi8KK3B1YmxpYyBtYXBwaW5nIEdldFJlcHV0YXRpb25zKCkgeyByZXR1cm4gY29weShyZXB1dGF0aW9ucyk7IH0KZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvcmVzdHJpY3Rpb25zLmMgYi9zdGQvcGxheWVyL3Jlc3RyaWN0aW9ucy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ3MWUxNGMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL3Jlc3RyaWN0aW9ucy5jCkBAIC0wLDAgKzEsMTMwIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL3Jlc3RyaWN0aW9ucy5jIC0tIGNvbnRhaW5lciBhc3BlY3Qgb2YgcGxheWVycworLy8KKy8vICRJZDogcmVzdHJpY3Rpb25zLmMgOTAyMCAyMDE1LTAxLTEwIDIxOjQ5OjQxWiBaZXNzdHJhICQKKworLy8gVGhpcyBpcyBhIHNpbXBsZSBjb250YWluZXIgdG8gcHV0IG9iamVjdHMgaW4uIEl0IGRlZmluZXMgYWxsIGZ1bmN0aW9ucworLy8gd2hpY2ggYXJlIG5lY2Vzc2FyeSB0byBkZXNjcmliZSBhbiBvYmplY3Qgd2hpY2ggY2FuIGJlIGZpbGxlZCB3aXRoCisvLyBvdGhlciB0aGluZ3MuCisvLworLy8gSXQgd2lsbCBzdXBwb3J0IHJlc3RyaWN0aW9ucyBmb3Igdm9sdW1lLCB3ZWlnaHQgZXRjLgorLy8KKy8vIFRoZSBmb2xsb3dpbmcgcHJvcGVydGllcyBhcmUgZGVmaW5lZDoKKy8vIFBfTUFYX1dFSUdIVCAtIG1heGltdW0gd2VpZ2h0IHdoaWNoIGNvbnRhaW5lciBjYW4gY2FycnkKKy8vIFBfV0VJR0hUX0NPTlRFTlRTIC0gY3VycmVudCBjb250ZW50cworLy8gUF9XRUlHSFQgLSBidWlsdGluIHByb3BlcnR5OiByZWFkLT50b3RhbCB3ZWlnaHQsIHdyaXRlLT5vd24gd2VpZ2h0CisvLworLy8gRnVuY3Rpb25zIGZvciBtYW5pcHVsYXRpb24gb2Ygd2VpZ2h0CisvLyBNYXlBZGRXZWlnaHQod2VpZ2h0KSAtIENhbiA8d2VpZ2h0PiBiZSBpbnNlcnRlZD8KKy8vIEFkZFdlaWdodCh3ZWlnaHQpIC0gQWRkIGFuIGFtb3VudCBvZiA8d2VpZ2h0PgorLy8KKy8vIElNUE9SVEFOVDogdW5pdCBzaG91bGQgYmUgaW50ZXJwcmV0ZWQgYXMgZ3JhbXMgKGcpLgorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL2NvbnRhaW5lci9yZXN0cmljdGlvbnMiOworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxob29rLmg+CisjaW5jbHVkZSA8bGl2aW5nL3NraWxscy5oPgorI2luY2x1ZGUgPGF0dHJpYnV0ZXMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8Y29udGFpbmVyLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKworLy9MaXN0ZSB2b24gT2JqZWt0ZW4sIGluIGRlbmVuIEluc2VydE5vdGlmeSgpIGdlcnVmZW4gd2lyZCwgd2VubiBldHdhcyBpbiBkZW4KKy8vU3BpZWxlciBiZXdlZ3Qgd3VyZGUuCitub3NhdmUgb2JqZWN0ICpJbnNlcnRIb29rcz0oe30pOworCisvLyBsb2NhbCBwcm9wZXJ0aWVzIHByb3RvdHlwZXMKK3N0YXRpYyBpbnQgX3F1ZXJ5X21heF93ZWlnaHQoKTsKK3N0YXRpYyBtaXhlZCBfc2V0X2Zyb2cobWl4ZWQgYXJnKTsKKwordm9pZCBjcmVhdGUoKQoreworICA6OmNyZWF0ZSgpOworCisgIFNldChQX01BWF9XRUlHSFQsIE5PU0VUTUVUSE9ELCBGX1NFVF9NRVRIT0QpOworICBTZXQoUF9NQVhfV0VJR0hULCBTRUNVUkVELCBGX01PREUpOworICBvZmZlckhvb2soSF9IT09LX0lOU0VSVCwgMSk7Cit9CisKKy8vICoqKiogbG9jYWwgcHJvcGVydHkgbWV0aG9kcworc3RhdGljIGludCBfcXVlcnlfbWF4X3dlaWdodCgpIHsKKyAgaW50IHN0cix2YWw7CisgIG1peGVkIHNraTsKKyAgCisgIGlmIChRdWVyeVByb3AoUF9HSE9TVCkgJiYgIUlTX1dJWkFSRChNRSkpCisgICAgcmV0dXJuIDA7CisgIHN0cj1RdWVyeUF0dHJpYnV0ZShBX1NUUik7CisgIHNraSA9IFVzZVNraWxsKFNLX0NBUlJZLCAoW1NJX1NLSUxMQVJHIDogc3RyIF0pKTsKKworICBpZiAoIWludHAoc2tpKSkKKyAgICBza2kgPSAwOworICAKKyAgaWYgKHN0cjwwKSB7CisgICAgdmFsPTkyMDArc3RyKjE2MCsoaW50KXNraTsKKyAgICBpZiAodmFsPDMwMDApIHZhbD0zMDAwOworICAgIHJldHVybiB2YWw7CisgIH0KKyAgdmFsID0gOTIwMCtzdHIqODAwKyhpbnQpc2tpOworICBpZiAodmFsPDMwMDApCisgICAgdmFsID0gMzAwMDsKKyAgcmV0dXJuIHZhbDsKK30KKworc3RhdGljIG1peGVkIF9zZXRfZnJvZyhtaXhlZCBhcmcpIHsKKyAgbWl4ZWQgcmVzOworICAKKyAgcmVzPVNldChQX0ZST0csYXJnKTsKKyAgaWYgKHJlcykKKyAgICBTZXRQcm9wKFBfQVRUUklCVVRFU19NT0RJRklFUiwoeyIjZnJvc2NoIiwoW0FfU1RSOi0zMF0pfSkpOworICBlbHNlCisgICAgU2V0UHJvcChQX0FUVFJJQlVURVNfTU9ESUZJRVIsKHsiI2Zyb3NjaCIsMCB9KSk7CisgIHJldHVybiByZXM7Cit9CisKK3B1YmxpYyB2b2lkIE5vdGlmeUluc2VydChvYmplY3Qgb2IsIG9iamVjdCBvbGRlbnYpCit7CisgIDo6Tm90aWZ5SW5zZXJ0KG9iLCBvbGRlbnYpOworICAvLyBBbGxlIExpc3RlbmVyIGltIG5ldWVuIEhvb2tzeXN0ZW0gdm9tIEluc2VydEhvb2sgaW5mb3JtaWVyZW4KKyAgSG9va0Zsb3coSF9IT09LX0lOU0VSVCwgb2IpOworICAvLyBBbGxlIExpc3RlbmVyIGltIGFsdGVuIEluc2VydEhvb2sgaW5mb3JtaWVyZW4KKyAgaWYgKHNpemVvZihJbnNlcnRIb29rcykpCisgIHsKKyAgICBmb3JlYWNoKG9iamVjdCBoOiAmSW5zZXJ0SG9va3MpCisgICAgeworICAgICAgaWYgKGggJiYgZW52aXJvbm1lbnQoaCkgPT0gTUUpCisgICAgICAgIGgtPkluc2VydE5vdGlmeShvYik7CisgICAgICBlbHNlCisgICAgICAgIGg9MDsKKyAgICB9CisgICAgSW5zZXJ0SG9va3MtPSh7MH0pOyAvLyBnZW51bGx0ZSBFbGVtZW50ZSBsb2VzY2hlbgorICB9Cit9CisKK3ZvaWQgQWRkSW5zZXJ0SG9vayhvYmplY3Qgb2IpCit7CisgIGlmIChtZW1iZXIoSW5zZXJ0SG9va3Msb2IpIT0tMSB8fCBlbnZpcm9ubWVudChvYikhPXRoaXNfb2JqZWN0KCkpCisgICAgcmV0dXJuOworICBJbnNlcnRIb29rcys9KHtvYn0pOworfQorCit2b2lkIFJlbW92ZUluc2VydEhvb2sob2JqZWN0IG9iKQoreworICBJbnNlcnRIb29rcy09KHtvYn0pOworfQorCitvYmplY3QgKlF1ZXJ5SW5zZXJ0SG9va3MoKQoreworICByZXR1cm4gSW5zZXJ0SG9va3M7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvc2hhZG93cy9hcmtfaHVuZ2VyX3NoYWRvdy5jIGIvc3RkL3BsYXllci9zaGFkb3dzL2Fya19odW5nZXJfc2hhZG93LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDJkNmRmZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvc2hhZG93cy9hcmtfaHVuZ2VyX3NoYWRvdy5jCkBAIC0wLDAgKzEsNTQgQEAKKy8qIERlciBTaGFkb3cgZnVlciBkZW4gSHVuZ2VyZmx1Y2ggKi8KKy8qIC9kL2ViZW5lL2Fyay93b2xmL29iai9odW5nZXIuYyAgKi8KKy8qIFNoYWRvdzogL3N0ZC9wbGF5ZXIvc2hhZG93cy9hcmtfaHVuZ2VyX3NoYWRvdy5jICovCisvKiBPcmlnaW5hbDogL2QvZWJlbmUvYXJrL3dvbGYvb2JqL2h1bmdlcl9vYmouYyAqLworCisjcHJhZ21hIHN0cm9uZ190eXBlcyxzYXZlX3R5cGVzCisKKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCisjZGVmaW5lIEJTIGJyZWFrX3N0cmluZworCitvYmplY3Qgc3BpZWxlcjsKKwordm9pZCBTZXR6ZW4ob2JqZWN0IHNwKQoreworIGlmICghb2JqZWN0cChzcCkgfHwgIWludGVyYWN0aXZlKHNwKSkgcmV0dXJuIGRlc3RydWN0KHRoaXNfb2JqZWN0KCkpOworIHNwaWVsZXI9c3A7CisgaWYgKCFzaGFkb3coc3AsMSkpIGRlc3RydWN0KHRoaXNfb2JqZWN0KCkpOworfQorCitpbnQgX3F1ZXJ5X2Zvb2QoKSB7IHJldHVybiAwOyB9CisKK2ludCBfcXVlcnlfbWF4X2Zvb2QoKSB7IHJldHVybiAwOyB9CisKK2ludCBlYXRfZm9vZChpbnQgc3RyZW5ndGgsIGludCB0ZXN0b25seSkKK3sKKyBpZiAoc3RyZW5ndGg9PTApIHJldHVybiAxOworIGlmIChzdHJlbmd0aD4wKQorIHsKKyAgc3RyZW5ndGg9MDsKKyAgaWYgKHNwaWVsZXIpCisgIHsKKyAgICB0ZWxsX29iamVjdChzcGllbGVyLCBCUygiRHUgaGFzdCB6d2FyIGVpbmVuIHRpZXJpc2NoZW4gSHVuZ2VyLCBkb2NoIGlyZ2VuZHdhcyBzYWd0IERpciwgZGFzcyBEdSBkYXMsIHdhcyAiKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICJEdSBnZXJhZGUgZXNzZW4gd2lsbHN0LCBuaWNodCBtZWhyIGluIERlaW5lbiBNYWdlbiBiZWtvbW1zdC4gRGFzIGlzdCB6aWVtbGljaCAiKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZWZhZWhybGljaCwgaG9mZmVudGxpY2ggdmVyaHVuZ2Vyc3QgRHUgbmljaHQgISIsIDc4KSk7CisgICAgcmV0dXJuIDA7CisgIH0KKyB9CisgZWxzZQorIHsKKyAgaWYgKHNwaWVsZXIpCisgIHsKKyAgIHRlbGxfb2JqZWN0KHNwaWVsZXIsIEJTKCJEZWluIEh1bmdlciB2ZXJ0aWVmdCBzaWNoIHNvIG51ciwgRHUgbGVpZGVzdCBIb2VsbGVucXVhbGVuLiIsIDc4KSk7CisgICBzcGllbGVyLT5yZWR1Y2VfaGl0X3BvaW50cyhzdHJlbmd0aCk7CisgIH0KKyAgcmV0dXJuIDA7CisgfQorfQorCit2b2lkIExvZXNjaGVuKCkgeworICAgIHVuc2hhZG93KCk7CisgICAgZGVzdHJ1Y3QodGhpc19vYmplY3QoKSk7Cit9CmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL3NoYWRvd3MvYmxvY2tfc2hhZG93LmMgYi9zdGQvcGxheWVyL3NoYWRvd3MvYmxvY2tfc2hhZG93LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjdhNDMzMwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvc2hhZG93cy9ibG9ja19zaGFkb3cuYwpAQCAtMCwwICsxLDQ3IEBACisjcHJhZ21hIHN0cm9uZ190eXBlcyxzYXZlX3R5cGVzCisKKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisKK3ByaXZhdGUgbm9zYXZlIG9iamVjdCBwbDsKKwordm9pZCBjcmVhdGUoKQoreworICBpZiggSVNfQkxVRShNRSkgKSByZXR1cm47CisgIHNoYWRvdyggUEwsIDEpOworICBwbCA9IFBMOworfQorCitpbnQKK0FkZEV4cChpbnQgZXApCit7CisgIG9iamVjdCBibG9jazsKKyAgaW50IGRpZmYsIGxpbTsKKworICBibG9jayA9IHByZXNlbnQoIlxuIGJsb2NrIiwgcGwpOworICBsaW0gPSAzMCArIHJhbmRvbSgxMCk7CisKKyAgaWYgKCBlcCA+IGxpbSAmJgkJCQkgICAgICAvLyBNaW5kZXN0d2VydAorICAgICAgIHByZXZpb3VzX29iamVjdCgpICYmCisgICAgICAgKCBwcmV2aW91c19vYmplY3QoKSA9PSBwbCB8fAkJICAgICAgLy8gekIuIEdpdmVRdWVzdCgpCisJICggbGl2aW5nKHByZXZpb3VzX29iamVjdCgpKSAmJiAJICAgICAgLy8gT2RlciBOUENzCisJICAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShwcmV2aW91c19vYmplY3QoKSkKKwkgKQorICAgICAgICkKKyAgICAgKQorICB7CisgICAgZGlmZiA9IGJsb2NrLT5HdXRzY2hyZWliZW4oZXAtbGltKTsKKyAgICByZXR1cm4gcGwtPkFkZEV4cChsaW0rZGlmZik7CisgIH0KKyAgcmV0dXJuIHBsLT5BZGRFeHAoZXApOworfQorCit2b2lkCitTZWhlckhhdEdlbnVnKCkKK3sKKyAgdW5zaGFkb3coKTsKKyAgZGVzdHJ1Y3QodGhpc19vYmplY3QoKSk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvc2hhZG93cy9tb3JwaF9zaGFkb3cuYyBiL3N0ZC9wbGF5ZXIvc2hhZG93cy9tb3JwaF9zaGFkb3cuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZmM5N2M0Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9zaGFkb3dzL21vcnBoX3NoYWRvdy5jCkBAIC0wLDAgKzEsNTk4IEBACisvKiAtKi0gbHBjIC0qLSAqLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgbW9ycGguYworLy8KKy8vICAgKGMpIFRyb3kgKHRyb3lAbWcubXVkLmRlKQorLy8gICBLb3BpZXJlbiwgVmVyYWVuZGVybiBvZGVyIFdlaXRlcmdhYmU6IG5hIGtsYXIsIGltbWVyIHp1LCBqZSBzY2hsaW1tZXIgCisvLyAgIHVtIHNvIGJlc3NlcgorLy8KKy8vICAgT2JqZWt0IGVyc3RlbGx0OiAxNC4wOC4wMSwgVHJveQorLy8KKy8vICAgRGllc2VyIHNoYWRvdyBpbXBsZW1lbnRpZXJ0IGdlbmVyaXNjaGUgVmVyd2FuZGx1bmdlbi4gSW0gR2VnZW5zYXR6IG9kZXIKKy8vICAgaW4gRXJn5G56dW5nIHp1bSBUYXJuaGVsbSBzaW5kIGRpZXNlIG5pY2h0IGF1ZiBkaWUgQmVzY2hyZWlidW5nCisvLyAgIGJlc2NocuRua3QsIHNvbmRlcm4gc2NobGFnZW4gc2ljaCBhdWNoIGluIGFuZGVyZW4gUHJvcGVydGllcyBuaWVkZXIuCisvLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzLHNhdmVfdHlwZXMKKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCit2YXJhcmdzIGludCByZW1vdmUoIGludCBzaWxlbnQgKTsKKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgUHJvcGVydHktRWluc3RlbGx1bmdlbiBqZSBuYWNoIFJhc3NlCisvLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitwcml2YXRlIG1hcHBpbmcgbW9ycGhfcHJvcGVydGllczsKKworcHJpdmF0ZSBvYmplY3QgcGw7IC8vIGRlciBzY2hhdHRpZXJ0ZSBTcGllbGVyCisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIHN0YXJ0X3NoYWRvdyggU3BpZWxlciwgUHJvcGVydGllcyApCisvLworLy8gICBTdGFydGV0IGRhcyBTaGFkb3dpbmcgdm9uIFNwaWVsZXIuIFByb3BlcnRpZXMgaXN0IGVpbiBNYXBwaW5nIG1pdAorLy8gICBkZW4genUg5G5kZXJuZGVuIFByb3BlcnRpZXMuIERvcnQgbmljaHQgdm9yaGFuZGVuZSBQcm9wZXJ0aWVzIHdlcmRlbgorLy8gICB6dW0gU3BpZWxlciBkdXJjaGdlcmVpY2h0LiBFcyB3ZXJkZW4gZG9ydCBlbnR3ZWRlciBlaW56ZWxuZSBXZXJ0ZQorLy8gICBlcndhcnRldCAoQmVpc3BpZWw6IChbIFBfR0VOREVSOiBNQUxFIF0pKSwgZGllIGRhbm4gZvxyIGFsbGUgUmFzc2VuCisvLyAgIGdlbHRlbiwgb2RlciBjbG9zdXJlcywgZGllIGRhbm4gYXVzZ2Vm/GhydCB3ZXJkZW4gdW50ZXIg3GJlcmdhYmUgZGVyCisvLyAgIFNwaWVsZXJyYXNzZSBhbHMgUGFyYW1ldGVyIG9kZXIgYWJlciBNYXBwaW5ncyBtaXQgZGVuIFJhc3Nlbm5hbWVuCisvLyAgIChCZWlzcGllbDogKFsgUF9HRU5ERVI6IChbICJNZW5zY2giOiBORVVURVIsICJFbGYiOiBGRU1BTEUsCisvLyAgICJad2VyZyI6IE1BTEUsIC4uLiBdKaBdKSkuIElzdCBlaW5lIFJhc3NlIGluIGRlbSBSYXNzZW5tYXBwaW5nIG5pY2h0CisvLyAgIHZvcmhhbmRlbiwgc28gd2lyZCBkYXMgUHJvcGVydHkgenVtIFNwaWVsZXIgZHVyY2hnZXJlaWNodC4gU3BlemllbGwKKy8vICAgYmVoYW5kZWx0IHdlcmRlbiBQX0lEUyAoc2llaGUgX3F1ZXJ5X2lkcygpKSB1bmQgUF9OQU1FIChzaWVoZQorLy8gICBfcXVlcnlfbmFtZSgpKS4gCisvLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoraW50IHN0YXJ0X3NoYWRvdyggb2JqZWN0IF9wbCwgbWFwcGluZyBwcmVzZXQgKQoreworICBpZiAoICFjbG9uZXAoIHRoaXNfb2JqZWN0KCkgKSApCisgICAgcmV0dXJuIDE7CisgIGlmICggIV9wbCB8fCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZSggX3BsICkgKQorICAgIHJldHVybiByZW1vdmUoKTsKKyAgcGwgPSBfcGw7CisgIG1vcnBoX3Byb3BlcnRpZXMgPSBkZWVwX2NvcHkoIHByZXNldCApOworICBzaGFkb3coIHBsLCAxICk7CisgIHJldHVybiAxOworfQorCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLworLy8gICBzdG9wX3NoYWRvdygpCisvLworLy8gICBCZWVuZGV0IGRhcyBTaGFkb3dpbmcgdW5kIHplcnN09nJ0IGRpZXNlcyBPYmpla3QKKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbnQgc3RvcF9zaGFkb3coIC8qIHZvaWQgKi8gKQoreworICBpZiAoICFjbG9uZXAoIHRoaXNfb2JqZWN0KCkgKSApCisgICAgcmV0dXJuIDA7CisgIHVuc2hhZG93KCk7CisgIHJldHVybiByZW1vdmUoKTsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgX3F1ZXJ5X3Byb3BlcnR5KCBQcm9wZXJ0eSApCisvLworLy8gICBHZW5lcmlzY2hlIFByb3BlcnR5LU1hc2tpZXJ1bmcuIGxpZWZlcnQgYXVzIG1vcnBoX3Byb3BlcnRpZXMgZGVuIHp1cgorLy8gICBSYXNzZSBkZXMgVHLkZ2VycyBwYXNzZW5kZW4gRWludHJhZy4KKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitub21hc2sgc3RhdGljIG1peGVkIF9xdWVyeV9wcm9wZXJ0eSggc3RyaW5nIHByb3AgKQoreworICBzdHJpbmcgcmFjZTsKKworICAvLyBSYXNzZSBob2xlbi4KKyAgaWYgKCBJU19MRUFSTkVSKHBsKSApCisgICAgcmFjZSA9ICJNYWdpZXIiOworICBlbHNlIC8vIF9xdWVyeV9yYWNlKCkgaXN0IG5vdHdlbmRpZywgdW0gY2xvc3VyZXMgenUgdW1nZWhlbi4KKyAgICByYWNlID0gcGwtPl9xdWVyeV9yYWNlKCk7CisKKyAgaWYgKCBtZW1iZXIoIG1vcnBoX3Byb3BlcnRpZXMsIHByb3AgKSA9PSAwICkKKyAgICByZXR1cm4gcGwtPlF1ZXJ5KCBwcm9wICk7CisgIGlmICggY2xvc3VyZXAoIG1vcnBoX3Byb3BlcnRpZXNbIHByb3AgXSApICkKKyAgICByZXR1cm4gZnVuY2FsbCggbW9ycGhfcHJvcGVydGllc1sgcHJvcCBdLCByYWNlICk7CisgIGlmICggbWFwcGluZ3AoIG1vcnBoX3Byb3BlcnRpZXNbIHByb3AgXSApICkKKyAgeworICAgIGlmICggbWVtYmVyKCBtb3JwaF9wcm9wZXJ0aWVzWyBwcm9wIF0sIHJhY2UgKSA9PSAwICkKKyAgICAgIHJldHVybiBwbC0+UXVlcnkoIHByb3AgKTsKKyAgICBpZiAoIGNsb3N1cmVwKCBtb3JwaF9wcm9wZXJ0aWVzWyBwcm9wIF1bIHJhY2UgXSApICkKKyAgICAgIHJldHVybiBmdW5jYWxsKCBtb3JwaF9wcm9wZXJ0aWVzWyBwcm9wIF1bIHJhY2UgXSApOworCisgICAgcmV0dXJuIG1vcnBoX3Byb3BlcnRpZXNbIHByb3AgXVsgcmFjZSBdOworICB9CisgIHJldHVybiBtb3JwaF9wcm9wZXJ0aWVzWyBwcm9wIF07Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIF9xdWVyeV9hcnRpY2xlKCkKKy8vCisvLyAgIFByb3BlcnR5LU1hc2tpZXJ1bmcgZvxyIFBfQVJUSUNMRQorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK2ludCBfcXVlcnlfYXJ0aWNsZSggLyogdm9pZCAqLyApCit7CisgIHJldHVybiAoaW50KV9xdWVyeV9wcm9wZXJ0eSggUF9BUlRJQ0xFICk7Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIF9xdWVyeV9hdmVyYWdlX3NpemUoKQorLy8KKy8vICAgUHJvcGVydHktTWFza2llcnVuZyBm/HIgUF9BVkVSQUdFX1NJWkUKKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbnQgX3F1ZXJ5X2F2ZXJhZ2Vfc2l6ZSggLyogdm9pZCAqLyApCit7CisgIHJldHVybiAoaW50KV9xdWVyeV9wcm9wZXJ0eSggUF9BVkVSQUdFX1NJWkUgKTsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgX3F1ZXJ5X2F2ZXJhZ2Vfd2VpZ2h0KCkKKy8vCisvLyAgIFByb3BlcnR5LU1hc2tpZXJ1bmcgZvxyIFBfQVZFUkFHRV9XRUlHSFQKKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbnQgX3F1ZXJ5X2F2ZXJhZ2Vfd2VpZ2h0KCAvKiB2b2lkICovICkKK3sKKyAgcmV0dXJuIChpbnQpX3F1ZXJ5X3Byb3BlcnR5KCBQX0FWRVJBR0VfV0VJR0hUICk7Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIF9xdWVyeV9ib2R5KCkKKy8vCisvLyAgIFByb3BlcnR5LU1hc2tpZXJ1bmcgZvxyIFBfQk9EWQorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK2ludCBfcXVlcnlfYm9keSggLyogdm9pZCAqLyApCit7CisgIHJldHVybiAoaW50KV9xdWVyeV9wcm9wZXJ0eSggUF9CT0RZICk7Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIF9xdWVyeV9nZW5kZXIoKQorLy8KKy8vICAgUHJvcGVydHktTWFza2llcnVuZyBm/HIgUF9HRU5ERVIKKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbnQgX3F1ZXJ5X2dlbmRlciggLyogdm9pZCAqLyApCit7CisgIHJldHVybiAoaW50KV9xdWVyeV9wcm9wZXJ0eSggUF9HRU5ERVIgKTsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgX3F1ZXJ5X2hhbmRzKCkKKy8vCisvLyAgIFByb3BlcnR5LU1hc2tpZXJ1bmcgZvxyIFBfSEFORFMKKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCittaXhlZCBfcXVlcnlfaGFuZHMoIC8qIHZvaWQgKi8gKQoreworICByZXR1cm4gX3F1ZXJ5X3Byb3BlcnR5KCBQX0hBTkRTICk7Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIF9xdWVyeV9pZHMoKQorLy8KKy8vICAgUHJvcGVydHktTWFza2llcnVuZyBm/HIgUF9JRFMgLSBOaWNodC1TdGFuZGFyZCwgZGEgamUgbmFjaCBVcnNwcnVuZ3MtCisvLyAgIGdlc2NobGVjaHQgZGVzIFNwaWVsZXJzIHp1c+R0emxpY2hlIGlkcyBm5GxsaWcgd2VyZGVuLiBBYmxhdWY6IEVzIGdpYnQKKy8vICAgNSBTY2hyaXR0ZSwgYmVpIGRlcmVuIGpld2VpbGlnZW0gVmVyc2FnZW4gZGllIGlkcyBkZXMgU3BpZWxlcnMgZHVyY2gtCisvLyAgIGdlcmVpY2h0IHdlcmRlbjoKKy8vICAgMS4gUF9JRFMgaXN0IGltIHByb3BlcnR5LW1hcHBpbmcgdm9yaGFuZGVuCisvLyAgIDIuIGEpIGVzIGlzdCBlaW4gc3RyaW5nIG9kZXIgZWluIGFycmF5OiBlcyB3aXJkIGFuIGRpZSBpZHMgZGVzIFNwaWVsZXJzCisvLyAgICAgICAgIGFuZ2Vo5G5ndCB1bmQgenVy/GNrZ2VnZWJlbi4KKy8vICAgICAgYikgZXMgaXN0IGVpbmUgY2xvc3VyZS4gRGllc2Ugd2lyZCBhdXNnZWb8aHJ0IHVudGVyINxiZXJnYWJlIGRlcgorLy8gICAgICAgICBTcGllbGVyLWlkcywgZGVyIFJhc3NlIGRlcyBTcGllbGVycyB1bmQgZGVyIEdlc2NobGVjaHRlcgorLy8gICAgICAgICAoZGllc2VzIE9iamVrdHMgdW5kIGRlcyBTcGllbGVycykuIERlciBFcmdlYm5pc3dlcnQgZGVyIGNsb3N1cmUKKy8vICAgICAgICAgd2lyZCBkaXJla3QgenVy/GNrZ2VnZWJlbi4KKy8vICAgICAgYykgZXMgaXN0IGVpbiBtYXBwaW5nLiBIaWVyIG5laG1lbiB3aXIgbnVuIGRhcyD8YmxpY2hlIFJhc3Nlbm5hbWVuLQorLy8gICAgICAgICBtYXBwaW5nIGFuIC0+IDMuKQorLy8gICAzLiBG/HIgZGllIFJhc3NlIGRlcyBTcGllbGVycyB3aXJkIGVpbiBFaW50cmFnIGdlc3VjaHQKKy8vICAgICAgYSkgZXIgaXN0IGVpbiBzdHJpbmcgb2RlciBlaW4gYXJyYXk6IGVyIHdpcmQgYW4gZGllIGlkcyBkZXMgU3BpZWxlcnMKKy8vICAgICAgICAgYW5nZWjkbmd0IHVuZCB6dXL8Y2tnZWdlYmVuLgorLy8gICAgICBiKSBlciBpc3QgZWluZSBjbG9zdXJlLiBEaWVzZSB3aXJkIGF1c2dlZvxocnQgdW50ZXIg3GJlcmdhYmUgZGVyCisvLyAgICAgICAgIFNwaWVsZXItaWRzLCBkZXIgUmFzc2UgZGVzIFNwaWVsZXJzIHVuZCBkZXIgR2VzY2hsZWNodGVyCisvLyAgICAgICAgIChkaWVzZXMgT2JqZWt0cyB1bmQgZGVzIFNwaWVsZXJzKS4gRGVyIEVyZ2Vibmlzd2VydCBkZXIgY2xvc3VyZQorLy8gICAgICAgICB3aXJkIGRpcmVrdCB6dXL8Y2tnZWdlYmVuLgorLy8gICAgICBjKSBlciBpc3QgZWluIG1hcHBpbmcuIEVzIHdpcmQgYW5nZW5vbW1lbiwgZGFzcyBqZSBHZXNjaGxlY2h0IERJRVNFUworLy8gICAgICAgICBPYmpla3RzIGVpbiBFaW50cmFnIHZvcmhhbmRlbiBpc3QuIC0+IDQuKQorLy8gICA0LiBG/HIgZGFzIEdlc2NobGVjaHQgZGllc2VzIE9iamVrdHMgd2lyZCBlaW4gRWludHJhZyBnZXN1Y2h0CisvLyAgICAgIGEpIGVyIGlzdCBlaW4gc3RyaW5nIG9kZXIgZWluIGFycmF5OiBlciB3aXJkIGFuIGRpZSBpZHMgZGVzIFNwaWVsZXJzCisvLyAgICAgICAgIGFuZ2Vo5G5ndCB1bmQgenVy/GNrZ2VnZWJlbi4KKy8vICAgICAgYikgZXIgaXN0IGVpbmUgY2xvc3VyZS4gRGllc2Ugd2lyZCBhdXNnZWb8aHJ0IHVudGVyINxiZXJnYWJlIGRlcgorLy8gICAgICAgICBTcGllbGVyLWlkcywgZGVyIFJhc3NlIGRlcyBTcGllbGVycyB1bmQgZGVyIEdlc2NobGVjaHRlcgorLy8gICAgICAgICAoZGllc2VzIE9iamVrdHMgdW5kIGRlcyBTcGllbGVycykuIERlciBFcmdlYm5pc3dlcnQgZGVyIGNsb3N1cmUKKy8vICAgICAgICAgd2lyZCBkaXJla3QgenVy/GNrZ2VnZWJlbi4KKy8vICAgICAgYykgZXIgaXN0IGVpbiBtYXBwaW5nLiBFcyB3aXJkIGFuZ2Vub21tZW4sIGRhc3MgamUgR2VzY2hsZWNodCBERVMKKy8vICAgICAgICAgU3BpZWxlcnMgZWluIEVpbnRyYWcgdm9yaGFuZGVuIGlzdC4gLT4gNS4pCisvLyAgIDUuIEb8ciBkYXMgR2VzY2hsZWNodCBkZXMgU3BpZWxlcnMgd2lyZCBlaW4gRWludHJhZyBnZXN1Y2h0CisvLyAgICAgIGEpIGVyIGlzdCBlaW4gc3RyaW5nIG9kZXIgZWluIGFycmF5OiBlciB3aXJkIGFuIGRpZSBpZHMgZGVzIFNwaWVsZXJzCisvLyAgICAgICAgIGFuZ2Vo5G5ndCB1bmQgenVy/GNrZ2VnZWJlbi4KKy8vICAgICAgYikgZXIgaXN0IGVpbmUgY2xvc3VyZS4gRGllc2Ugd2lyZCBhdXNnZWb8aHJ0IHVudGVyINxiZXJnYWJlIGRlcgorLy8gICAgICAgICBTcGllbGVyLWlkcywgZGVyIFJhc3NlIGRlcyBTcGllbGVycyB1bmQgZGVyIEdlc2NobGVjaHRlcgorLy8gICAgICAgICAoZGllc2VzIE9iamVrdHMgdW5kIGRlcyBTcGllbGVycykuIERlciBFcmdlYm5pc3dlcnQgZGVyIGNsb3N1cmUKKy8vICAgICAgICAgd2lyZCBkaXJla3QgenVy/GNrZ2VnZWJlbi4KKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCittaXhlZCBfcXVlcnlfaWRzKCAvKiB2b2lkICovICkKK3sKKyAgc3RyaW5nIHJhY2U7CisgIG1peGVkIGlkczsKKyAgaW50IGdlbmRlciwgc2dlbmRlcjsKKworICAvLyBUZXN0IDEuCisgIGlkcyA9IHBsLT5RdWVyeSggUF9JRFMgKTsKKyAgaWYgKCBtZW1iZXIoIG1vcnBoX3Byb3BlcnRpZXMsIFBfSURTICkgPT0gMCApCisgICAgcmV0dXJuIGlkczsKKworICAvLyBSYXNzZSBob2xlbi4KKyAgaWYgKCBJU19MRUFSTkVSKHBsKSApCisgICAgcmFjZSA9ICJNYWdpZXIiOworICBlbHNlIC8vIF9xdWVyeV9yYWNlKCkgaXN0IG5vdHdlbmRpZywgdW0gY2xvc3VyZXMgenUgdW1nZWhlbi4KKyAgICByYWNlID0gcGwtPl9xdWVyeV9yYWNlKCk7CisKKyAgLy8gR2VzY2hsZWNodGVyIGhvbGVuCisgIGdlbmRlciA9IF9xdWVyeV9nZW5kZXIoKTsKKyAgc2dlbmRlciA9IHBsLT5RdWVyeSggUF9HRU5ERVIgKTsKKworICAvLyBUZXN0IDIuCisgIC8vIHN0cmluZz8gRGFubiBlaW5mYWNoIGRlbiBub3JtYWxlbiBpZHMgZGF6dSwgZ2VuYXVzbyBtaXQgYXJyYXkKKyAgaWYgKCBzdHJpbmdwKCBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdICkgKQorICAgIHJldHVybiBpZHMgKyAoeyBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdIH0pOworICBpZiAoIHBvaW50ZXJwKCBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdICkgKQorICAgIHJldHVybiBpZHMgKyBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdOworICBpZiAoIGNsb3N1cmVwKCBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdICkgKQorICAgIHJldHVybiBmdW5jYWxsKCBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdLCBpZHMsIHJhY2UsIGdlbmRlciwgc2dlbmRlciApOworICAvLyBmYWxscyBrZWluIG1hcHBpbmcsIGRhbm4gcmF1cworICBpZiAoICFtYXBwaW5ncCggbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXSApICkKKyAgICByZXR1cm4gaWRzOworCisgIC8vIFRlc3QgMy4KKyAgaWYgKCBtZW1iZXIoIG1vcnBoX3Byb3BlcnRpZXNbIFBfSURTIF0sIHJhY2UgKSA9PSAwICkKKyAgICByZXR1cm4gaWRzOworICBpZiAoIHN0cmluZ3AoIG1vcnBoX3Byb3BlcnRpZXNbIFBfSURTIF1bIHJhY2UgXSApICkKKyAgICByZXR1cm4gaWRzICsgKHsgbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdIH0pOworICBpZiAoIHBvaW50ZXJwKCBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdWyByYWNlIF0gKSApCisgICAgcmV0dXJuIGlkcyArIG1vcnBoX3Byb3BlcnRpZXNbIFBfSURTIF1bIHJhY2UgXTsKKyAgaWYgKCBjbG9zdXJlcCggbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdICkgKQorICAgIHJldHVybiBmdW5jYWxsKCBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdWyByYWNlIF0sIGlkcywgcmFjZSwgZ2VuZGVyLCBzZ2VuZGVyICk7CisgIC8vIGZhbGxzIGtlaW4gbWFwcGluZywgZGFubiByYXVzCisgIGlmICggIW1hcHBpbmdwKCBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdWyByYWNlIF0gKSApCisgICAgcmV0dXJuIGlkczsKKworICAvLyBUZXN0IDQuCisgIGlmICggbWVtYmVyKCBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdWyByYWNlIF0sIGdlbmRlciApID09IDAgKQorICAgIHJldHVybiBpZHM7CisgIGlmICggc3RyaW5ncCggbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdWyBnZW5kZXIgXSApICkKKyAgICByZXR1cm4gaWRzICsgKHsgbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdWyBnZW5kZXIgXSB9KTsKKyAgaWYgKCBwb2ludGVycCggbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdWyBnZW5kZXIgXSApICkKKyAgICByZXR1cm4gaWRzICsgbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdWyBnZW5kZXIgXTsKKyAgaWYgKCBjbG9zdXJlcCggbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdWyBnZW5kZXIgXSApICkKKyAgICByZXR1cm4gZnVuY2FsbCggbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdWyBnZW5kZXIgXSwKKwkJICAgIGlkcywgcmFjZSwgZ2VuZGVyLCBzZ2VuZGVyICk7CisgIC8vIGZhbGxzIGtlaW4gbWFwcGluZywgZGFubiByYXVzCisgIGlmICggIW1hcHBpbmdwKCBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdWyByYWNlIF1bIGdlbmRlciBdICkgKQorICAgIHJldHVybiBpZHM7CisKKyAgLy8gVGVzdCA1LgorICBpZiAoIG1lbWJlciggbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdWyBnZW5kZXIgXSwgc2dlbmRlciApID09IDAgKQorICAgIHJldHVybiBpZHM7CisgIGlmICggc3RyaW5ncCggbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdWyBnZW5kZXIgXVsgc2dlbmRlciBdICkgKQorICAgIHJldHVybiBpZHMgKyAoeyBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdWyByYWNlIF1bIGdlbmRlciBdWyBzZ2VuZGVyIF0gfSk7CisgIGlmICggcG9pbnRlcnAoIG1vcnBoX3Byb3BlcnRpZXNbIFBfSURTIF1bIHJhY2UgXVsgZ2VuZGVyIF1bIHNnZW5kZXIgXSApICkKKyAgICByZXR1cm4gaWRzICsgbW9ycGhfcHJvcGVydGllc1sgUF9JRFMgXVsgcmFjZSBdWyBnZW5kZXIgXVsgc2dlbmRlciBdOworICBpZiAoIGNsb3N1cmVwKCBtb3JwaF9wcm9wZXJ0aWVzWyBQX0lEUyBdWyByYWNlIF1bIGdlbmRlciBdWyBzZ2VuZGVyIF0gKSApCisgICAgcmV0dXJuIGZ1bmNhbGwoIG1vcnBoX3Byb3BlcnRpZXNbIFBfSURTIF1bIHJhY2UgXVsgZ2VuZGVyIF1bIHNnZW5kZXIgXSwKKwkJICAgIGlkcywgcmFjZSwgZ2VuZGVyLCBzZ2VuZGVyICk7CisKKyAgcmV0dXJuIGlkczsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgX3F1ZXJ5X2lzX21vcnBoZWQoKQorLy8KKy8vICAgUHJvcGVydHktTWV0aG9kZSBm/HIgImlzX21vcnBoZWQiCisvLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoraW50IF9xdWVyeV9pc19tb3JwaGVkKCAvKiB2b2lkICovICkKK3sKKyAgcmV0dXJuIDE7Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIF9xdWVyeV9tYXhfaGFuZHMoKQorLy8KKy8vICAgUHJvcGVydHktTWFza2llcnVuZyBm/HIgUF9NQVhfSEFORFMKKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbnQgX3F1ZXJ5X21heF9oYW5kcyggLyogdm9pZCAqLyApCit7CisgIHJldHVybiAoaW50KV9xdWVyeV9wcm9wZXJ0eSggUF9NQVhfSEFORFMgKTsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgX3F1ZXJ5X21tc2dpbigpCisvLworLy8gICBQcm9wZXJ0eS1NYXNraWVydW5nIGb8ciBQX01NU0dJTgorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3N0cmluZyBfcXVlcnlfbW1zZ2luKCAvKiB2b2lkICovICkKK3sKKyAgcmV0dXJuIChzdHJpbmcpKF9xdWVyeV9wcm9wZXJ0eSggUF9NTVNHSU4gKSB8fCAiIik7Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIF9xdWVyeV9tbXNnb3V0KCkKKy8vCisvLyAgIFByb3BlcnR5LU1hc2tpZXJ1bmcgZvxyIFBfTU1TR09VVAorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3N0cmluZyBfcXVlcnlfbW1zZ291dCggLyogdm9pZCAqLyApCit7CisgIHJldHVybiAoc3RyaW5nKShfcXVlcnlfcHJvcGVydHkoIFBfTU1TR09VVCApIHx8ICIiKTsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgX3F1ZXJ5X21zZ2luKCkKKy8vCisvLyAgIFByb3BlcnR5LU1hc2tpZXJ1bmcgZvxyIFBfTVNHSU4KKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitzdHJpbmcgX3F1ZXJ5X21zZ2luKCAvKiB2b2lkICovICkKK3sKKyAgcmV0dXJuIChzdHJpbmcpKF9xdWVyeV9wcm9wZXJ0eSggUF9NU0dJTiApIHx8ICIiKTsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgX3F1ZXJ5X21zZ291dCgpCisvLworLy8gICBQcm9wZXJ0eS1NYXNraWVydW5nIGb8ciBQX01TR09VVAorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3N0cmluZyBfcXVlcnlfbXNnb3V0KCAvKiB2b2lkICovICkKK3sKKyAgcmV0dXJuIChzdHJpbmcpKF9xdWVyeV9wcm9wZXJ0eSggUF9NU0dPVVQgKSB8fCAiIik7Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIF9xdWVyeV9uYW1lKCkKKy8vCisvLyAgIFByb3BlcnR5LU1ldGhvZGUgZvxyIFBfTkFNRS4gTGVpZGVyIGlzdCBkaWUgcGxheWVyLXNoZWxsIHNvIGdyb3R0aWcsCisvLyAgIGRhc3Mg/GJlcmFsbCBhbmdlbm9tbWVuIHdpcmQsIFF1ZXJ5UHJvcChQX05BTUUpIGxpZWZlcmUgZWluZW4gU3RyaW5nIDotfAorLy8gICBWb2xsc3TkbmRpZ2VzIFByb3BlcnR5IGRhaGVyIHVudGVyIF9xdWVyeV9uYW1lX2Z1bGwoKS4KKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitzdHJpbmcgX3F1ZXJ5X25hbWUoIC8qIHZvaWQgKi8gKQoreworICBtaXhlZCBwcm9wOworICBwcm9wID0gX3F1ZXJ5X3Byb3BlcnR5KCBQX05BTUUgKTsKKyAgaWYgKCBzdHJpbmdwKCBwcm9wICkgKQorICAgIHJldHVybiBzcHJpbnRmKCBwcm9wLCBwbC0+UXVlcnkoIFBfTkFNRSApICk7CisgIGlmICggcG9pbnRlcnAoIHByb3AgKSApCisgICAgcmV0dXJuIG1hcCggcHJvcCwKKwkJICAgICAgbGFtYmRhKCAoeyAnZWwsICdzIH0pLAorCQkJICAgICAgKHsjJ3NwcmludGYsICdlbCwgJ3N9KSApLAorCQkgICAgICBwbC0+UXVlcnkoIFBfTkFNRSApIClbIFdFUiBdOworICByZXR1cm4gcGwtPlF1ZXJ5KCBQX05BTUUgKTsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgX3F1ZXJ5X25hbWVfZnVsbCgpCisvLworLy8gICBQcm9wZXJ0eS1NZXRob2RlIGb8ciAibmFtZV9mdWxsIi4KKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCittaXhlZCBfcXVlcnlfbmFtZV9mdWxsKCAvKiB2b2lkICovICkKK3sKKyAgbWl4ZWQgcHJvcDsKKyAgcHJvcCA9IF9xdWVyeV9wcm9wZXJ0eSggUF9OQU1FICk7CisgIGlmICggc3RyaW5ncCggcHJvcCApICkKKyAgICByZXR1cm4gc3ByaW50ZiggcHJvcCwgcGwtPlF1ZXJ5KCBQX05BTUUgKSApOworICBpZiAoIHBvaW50ZXJwKCBwcm9wICkgKQorICAgIHJldHVybiBtYXAoIHByb3AsCisJCSAgICAgIGxhbWJkYSggKHsgJ2VsLCAncyB9KSwKKwkJCSAgICAgICh7IydzcHJpbnRmLCAnZWwsICdzfSkgKSwKKwkJICAgICAgcGwtPlF1ZXJ5KCBQX05BTUUgKSApOworICByZXR1cm4gcGwtPlF1ZXJ5KCBQX05BTUUgKTsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgX3F1ZXJ5X3ByZXNheSgpCisvLworLy8gICBQcm9wZXJ0eS1NYXNraWVydW5nIGb8ciBQX1BSRVNBWQorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3N0cmluZyBfcXVlcnlfcHJlc2F5KCAvKiB2b2lkICovICkKK3sKKyAgcmV0dXJuIChzdHJpbmcpKF9xdWVyeV9wcm9wZXJ0eSggUF9QUkVTQVkgKSB8fCAiIik7Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIF9xdWVyeV9yYWNlKCkKKy8vCisvLyAgIFByb3BlcnR5LU1hc2tpZXJ1bmcgZvxyIFBfUkFDRQorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3N0cmluZyBfcXVlcnlfcmFjZSggLyogdm9pZCAqLyApCit7CisgIHJldHVybiAoc3RyaW5nKShfcXVlcnlfcHJvcGVydHkoIFBfUkFDRSApIHx8ICIiKTsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgX3F1ZXJ5X3JhY2VzdHJpbmcoKQorLy8KKy8vICAgUHJvcGVydHktTWFza2llcnVuZyBm/HIgUF9SQUNFU1RSSU5HCisvLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorc3RyaW5nKiBfcXVlcnlfcmFjZXN0cmluZyggLyogdm9pZCAqLyApCit7CisgIHJldHVybiAoc3RyaW5nKilfcXVlcnlfcHJvcGVydHkoIFBfUkFDRVNUUklORyApOworfQorCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLworLy8gICBfcXVlcnlfc2l6ZSgpCisvLworLy8gICBQcm9wZXJ0eS1NYXNraWVydW5nIGb8ciBQX1NJWkUKKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCitpbnQgX3F1ZXJ5X3NpemUoIC8qIHZvaWQgKi8gKQoreworICByZXR1cm4gKGludClfcXVlcnlfcHJvcGVydHkoIFBfU0laRSApOworfQorCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLworLy8gICBfcXVlcnlfdGl0bGUoKQorLy8KKy8vICAgUHJvcGVydHktTWFza2llcnVuZyBm/HIgUF9USVRMRQorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3N0cmluZyBfcXVlcnlfdGl0bGUoIC8qIHZvaWQgKi8gKQoreworICByZXR1cm4gKHN0cmluZykoX3F1ZXJ5X3Byb3BlcnR5KCBQX1RJVExFICkgfHwgIiIpOworfQorCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLworLy8gICBfcXVlcnlfd2VpZ2h0KCkKKy8vCisvLyAgIFByb3BlcnR5LU1hc2tpZXJ1bmcgZvxyIFBfV0VJR0hUCisvLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoraW50IF9xdWVyeV93ZWlnaHQoIC8qIHZvaWQgKi8gKQoreworICByZXR1cm4gKGludCkoX3F1ZXJ5X3Byb3BlcnR5KCBQX1dFSUdIVCApIHx8ICIiKTsKK30KKworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorLy8KKy8vICAgaWQoIFRleHQsIExldmVsKQorLy8KKy8vICAgRGllIElkZW50aWZpemllcnVuZyBzcGlubnQgbWl0IFBfTkFNRS1BcnJheXMKKy8vCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCit2YXJhcmdzIGludCBpZCggc3RyaW5nIHN0ciwgaW50IGx2bCApCit7CisgIHN0cmluZyBwbG5hbWU7CisKKyAgaWYgKCBwbC0+UXVlcnlQcm9wKCBQX0dIT1NUICkgKQorICAgIGlmICggc3RyID09ICJnZWlzdCIgKQorICAgICAgcmV0dXJuIDE7CisgICAgZWxzZSBpZiAoICggc3NjYW5mKCBzdHIsICJnZWlzdCB2b24gJXMiLCBwbG5hbWUgKSA9PSAxICkgJiYKKwkgICAgICBwbC0+aWQoIHBsbmFtZSApICkKKyAgICAgIHJldHVybiAxOworICAgIGVsc2UgaWYgKCAoIHNzY2FuZiggc3RyLCAiZ2Vpc3QgJXMiLCBwbG5hbWUgKSA9PSAxICkgJiYKKwkgICAgICBwbC0+aWQoIHBsbmFtZSApICkKKyAgICAgIHJldHVybiAxOworCisgIHJldHVybiBwbC0+aWQoIHN0ciwgbHZsICk7Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIGxvbmcoKQorLy8KKy8vICAgRGllIExhbmdiZXNjaHJlaWJ1bmcgaW0gU3BpZWxlciBoYWRlcnQgbWl0IGRlbSBHZXNjaGxlY2h0IE5FVVRFUi4uLgorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3ZhcmFyZ3Mgc3RyaW5nIGxvbmcoIC8qIHZvaWQgKi8gKQoreworICBzdHJpbmcgc2xvbmc7CisgIHNsb25nID0gcGwtPmxvbmcoKTsKKworICBpZiAoIF9xdWVyeV9nZW5kZXIoKSA9PSBORVVURVIgKQorICB7CisgICAgc3RyaW5nICphbG9uZzsKKyAgICBpbnQgaTsKKworICAgIC8vIGFsbGUgRXItcyB1bmQgZXItcyBzdWNoZW4uLi4KKyAgICBhbG9uZyA9IHJlZ2V4cGxvZGUoIHNsb25nLCAiXFw8W0VlXXJcXD4iICk7CisgICAgLy8gLi4uIHVuZCBkYXMgciBkdXJjaCBlaW4gcyBlcnNldHplbi4KKyAgICBmb3IgKCBpID0gMSA7IGkgPCBzaXplb2YoIGFsb25nICkgOyBpICs9IDIgKQorICAgICAgYWxvbmdbIGkgXVsgMSBdID0gJ3MnOworICAgIHNsb25nID0gaW1wbG9kZSggYWxvbmcsICIiICk7CisgIH0KKworICByZXR1cm4gc2xvbmc7Cit9CisKKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKy8vCisvLyAgIHNob3J0KCkKKy8vCisvLyAgIERpZSBLdXJ6YmVzY2hyZWlidW5nIGltIFNwaWVsZXIgaGF0IGVpbiBQcm9ibGVtIG1pdCBQX05BTUUtQXJyYXlzCisvLworLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorc3RyaW5nIHNob3J0KCAvKiB2b2lkICovICkKK3sKKyAgbWl4ZWQgbmFtZXM7CisgIHN0cmluZyBhbnN3ZXI7CisgIHN0cmluZyB0aXRsZTsKKworICBpZiAoIHBsLT5RdWVyeVByb3AoIFBfSU5WSVMgKSApCisgICAgaWYgKCBpbnRlcmFjdGl2ZSggcHJldmlvdXNfb2JqZWN0KCkgKSAmJgorCSBJU19MRUFSTklORyggcHJldmlvdXNfb2JqZWN0KCkgKSApCisgICAgICByZXR1cm4gIigiICsgcGwtPlF1ZXJ5KCBQX05BTUUgKSArICIpIFxuIjsKKyAgICBlbHNlCisgICAgICByZXR1cm4gKHN0cmluZykwOworCisgIG5hbWVzID0gX3F1ZXJ5X25hbWVfZnVsbCgpOworICBpZiAoIHN0cmluZ3AoIG5hbWVzICkgKQorICAgIG5hbWVzID0gKHsgbmFtZXMsIG5hbWVzLCBuYW1lcywgbmFtZXMgfSk7CisKKyAgaWYgKCBwbC0+UXVlcnlQcm9wKCBQX0dIT1NUICkgKQorICAgIGFuc3dlciA9ICJEZXIgR2Vpc3QgIiArIHBsLT5RdWVyeUFydGljbGUoIFdFU1NFTiwgMCApICsgbmFtZXNbIFdFU1NFTiBdOworICBlbHNlCisgICAgYW5zd2VyID0gcGwtPlF1ZXJ5QXJ0aWNsZSggV0VSLCAwICkgKyBuYW1lc1sgV0VSIF07CisgIGlmICggKCB0aXRsZSA9IHBsLT5RdWVyeVByb3AoIFBfVElUTEUgKSApICYmCisgICAgICAgKCB0aXRsZSAhPSAiIiApICkKKyAgICAgYW5zd2VyICs9ICIgIiArIHRpdGxlOworICBpZiAoICFpbnRlcmFjdGl2ZSggcGwgKSApCisgICAgIGFuc3dlciArPSAiIChuZXR6dG90KSI7CisgIHJldHVybiBjYXBpdGFsaXplKCBhbnN3ZXIgKSArICIuXG4iOworfQorCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLworLy8gICByZW1vdmUoIFNjaG5hdXplICkKKy8vCisvLyAgIGF1ZnLkdW1lbgorLy8KKy8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3ZhcmFyZ3MgaW50IHJlbW92ZSggaW50IHNpbGVudCApCit7CisgIGRlc3RydWN0KCB0aGlzX29iamVjdCgpICk7CisgIHJldHVybiAxOworfQorCisvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisvLyAgIC0tIEVOREUgLS0KZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvc2hhZG93cy9wb255LmMgYi9zdGQvcGxheWVyL3NoYWRvd3MvcG9ueS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhkM2RlOGQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL3NoYWRvd3MvcG9ueS5jCkBAIC0wLDAgKzEsNTkgQEAKKyNwcmFnbWEgc3Ryb25nX3R5cGVzLHNhdmVfdHlwZXMKKworI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKworLy8gCisvLyBEYSBkZXIgU2hhZG93IHNpY2ggbmljaHQgaW0gUGxheWVyIGJlZmluZGV0LCB3aXJkIGVpbgorLy8gWnVzYXR6b2JqZWt0IGJlbm9ldGlndC4KKy8vIDcuMTAuOTcgLSBEaWUgSG9vayBzb2xsdGUgaW4gZGVuIFZlcnplaWNobmlzc2VuIGRlciBCZW5uaWVxdWVzdAorLy8gICAgICAgICAgIHp1IGZpbmRlbiBzZWluLiAtIFJ1bWF0YQorCisjZGVmaW5lIEhPT0sgImQvd2FsZC9rYXNzYW5kcmEvYmVubmllL29iai9wb255X2hvb2siCisKK3N0YXRpYyBvYmplY3QgcGw7CisKK3ZvaWQgY3JlYXRlKCkKK3sKKyBpZiggSVNfQkxVRShNRSkgKSByZXR1cm47CisgIHNoYWRvdyggUEwsIDEpOworIHBsPVBMOworIC8vdGVsbF9vYmplY3QodGhpc19wbGF5ZXIoKSwiRHUgYmVzdGVpZ3N0IGRhcyBQb255IHNhbXQgU2NoYXR0ZW4uXG4iKTsKKyAgY2xvbmVfb2JqZWN0KCBIT09LICk7IC8vIFN0ZXVlcnVuZyBkZXMgc2hhZG93cyB1ZWJlciBkaWUgaG9vaworfQorCitzdHJpbmcgX3F1ZXJ5X3RpdGxlKCkKK3sgCisgaWYoIHBsLT5RdWVyeVByb3AoUF9HRU5ERVIpID09IEZFTUFMRSApCisgICAgIHJldHVybiAiZGllIFBvbnlyZWl0ZXJpbiI7CisgcmV0dXJuICJkZXIgUG9ueXJlaXRlciI7Cit9CisKK3N0cmluZyBfcXVlcnlfbXNnaW4oKSB7IHJldHVybiAicmVpdGV0IGhlcmVpbiI7IH0KK3N0cmluZyBfcXVlcnlfbXNnb3V0KCkgeyByZXR1cm4gInJlaXRldCI7IH0KKwordmFyYXJncyBpbnQgbW92ZShtaXhlZCBkZXN0LCBpbnQgbWV0aG9kLCBzdHJpbmcgZGlyLCBzdHJpbmcgdGV4dG91dCxzdHJpbmcgdGV4dGluKQoreworIGlmKCAhKG1ldGhvZCAmIE1fTk9DSEVDSykgJiYgZGVzdC0+UXVlcnlQcm9wKFBfSU5ET09SUykgKQorIHsKKyAgd3JpdGUoICJEYXMgUG9ueSB3ZWlnZXJ0IHNpY2gsIGRvcnRoaW4genUgdHJhYmVuLlxuIiApOworICByZXR1cm4gMTsKKyB9CisgcmV0dXJuIHBsLT5tb3ZlKCBkZXN0LCBtZXRob2QsIGRpciwgdGV4dG91dCwgdGV4dGluICk7Cit9CisKK2ludCBfaW52ZW50b3J5KHN0cmluZyBzdHIpCit7CisgaWYoICFlbnZpcm9ubWVudCgpIHx8IHNldF9saWdodCgwKT4wICkKKyAgd3JpdGUoICJEdSBzaXR6dCBhdWYgZWluZW0gUG9ueS5cbiIgKTsKKyByZXR1cm4gcGwtPl9pbnZlbnRvcnkoc3RyKTsKK30KKwordm9pZCBhYnN0ZWlnZW4oKSB7CisgIHVuc2hhZG93KCk7CisgIGRlc3RydWN0KE1FKTsKK30KKworaW50IFF1ZXJ5UmVpdGVyKCkgeyByZXR1cm4gMTsgfQpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9zaGFkb3dzL3NpemV0ZXN0LmMgYi9zdGQvcGxheWVyL3NoYWRvd3Mvc2l6ZXRlc3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xMjY4OTExCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9zaGFkb3dzL3NpemV0ZXN0LmMKQEAgLTAsMCArMSw1NyBAQAorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKworI2RlZmluZSBTUElFTEVSICJuZWZpcyIKKyNkZWZpbmUgREVCVUcoeCkgIGlmIChmaW5kX3BsYXllcigiemVzc3RyYSIpKVwKKyAgICAgICAgICAgIHRlbGxfb2JqZWN0KGZpbmRfcGxheWVyKCJ6ZXNzdHJhIiksXAorCQkgICAgICAgICAgICAgICAgICAgICAgIk5lZmlzIFBfU0laRTogIit4KyJcbiIpCisjZGVmaW5lIExPRyh4KSBsb2dfZmlsZSgiemVzc3RyYS9QX1NJWkUubG9nIiwgeCkKKworcHJpdmF0ZSBub3NhdmUgb2JqZWN0IHBsOworCit2b2lkIGNyZWF0ZSgpCit7CisgIGlmICghY2xvbmVwKCkgKSByZXR1cm47CisgIHBsID0gZmluZF9wbGF5ZXIoU1BJRUxFUikgfHwgZmluZF9uZXRkZWFkKFNQSUVMRVIpOworICBpZiAoIW9iamVjdHAocGwpKSB7CisgICAgICBERUJVRygiUGxheWVyb2JqZWt0IG5pY2h0IGdlZnVuZGVuLiIpOworICAgICAgZGVzdHJ1Y3QoTUUpOworICAgICAgcmV0dXJuOworICB9CisgIHNoYWRvdyggcGwsIDEpOworICBERUJVRyhzcHJpbnRmKCIlTyBzaGFkb3dlZCBieTogJU9cbiIsIHBsLCBzaGFkb3cocGwsIDApKSk7Cit9CisKK2ludCBfc2V0X3NpemUoaW50IHN6KSB7CisgIExPRyhzcHJpbnRmKCJbJXNdIEFlbmRlcnVuZyB2b24gUF9TSVpFIGluICVPIGF1ZiAlTyxcbkNhbGxlcnN0YWNrOiAlT1xuXG4iLAorCXN0cmZ0aW1lKCIlYyIsdGltZSgpKSwgcGwsIHN6LCBjYWxsZXJfc3RhY2soKSkpOworICByZXR1cm4gcGwtPlNldChQX1NJWkUsIHN6LCBGX1ZBTFVFKTsKK30KKworcHVibGljIHZhcmFyZ3MgbWl4ZWQgU2V0KCBzdHJpbmcgbmFtZSwgbWl4ZWQgVmFsdWUsIGludCBUeXBlLCBpbnQgZXh0ZXJuICkgeworICBpZiAobmFtZSA9PSBQX1NJWkUpIHsKKyAgTE9HKHNwcmludGYoIlslc10gQWVuZGVydW5nIHZvbiBQX1NJWkUgaW4gJU8gYXVmICVPIChUeXA6ICVPKSBbU2V0KCkhXSIKKwkiLFxuQ2FsbGVyc3RhY2s6ICVPXG5cbiIsCisJICAgICAgICBzdHJmdGltZSgiJWMiLHRpbWUoKSksIHBsLCBWYWx1ZSwgVHlwZSwgY2FsbGVyX3N0YWNrKCkpKTsKKyAgfQorICByZXR1cm4gcGwtPlNldChuYW1lLCBWYWx1ZSwgVHlwZSwgZXh0ZXJuKTsKK30KKworaW50IHN0b3AoKSB7CisgIHVuc2hhZG93KCk7CisgIGRlc3RydWN0KE1FKTsKKyAgcmV0dXJuIDE7Cit9CisKK3ZvaWQgcmVzZXQoKSB7CisgIGlmICghb2JqZWN0cChwbCkpIAorICAgIHN0b3AoKTsKK30KKworaW50IHJlbW92ZSgpIHsKKyAgc3RvcCgpOworICByZXR1cm4gMTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9zaGFkb3dzL3Rhcm5oZWxtX3NoYWRvdy5jIGIvc3RkL3BsYXllci9zaGFkb3dzL3Rhcm5oZWxtX3NoYWRvdy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYzZWE3NDQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL3NoYWRvd3MvdGFybmhlbG1fc2hhZG93LmMKQEAgLTAsMCArMSwxNDAgQEAKKyNwcmFnbWEgc3Ryb25nX3R5cGVzLHNhdmVfdHlwZXMKKworI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisKKyNkZWZpbmUgV0VHKCkgZGVzdHJ1Y3QodGhpc19vYmplY3QoKSkKKworb2JqZWN0IHBsYXllcjsKK2ludCBnZW5kZXI7CitzdHJpbmcgZGVzYzsKKwordm9pZCBfdGFybl90dXJuX29uKG9iamVjdCBwbCxzdHJpbmcgdHh0LGludCBnZW4pCit7CisgIGlmICghb2JqZWN0cChwbCl8fCFpbnRlcmFjdGl2ZShwbCkpIHJldHVybiBXRUcoKTsKKyAgaWYgKCFzdHJpbmdwKHR4dCl8fHR4dD09IiIpIHJldHVybiBXRUcoKTsKKyAgaWYgKGdlbjwwfHxnZW4+MikgcmV0dXJuIFdFRygpOworICBwbGF5ZXI9cGw7CisgIGRlc2M9Y2FwaXRhbGl6ZSh0eHQpOworICBnZW5kZXI9Z2VuOworICBzaGFkb3cocGwsMSk7Cit9CisKK2ludCBzcGVjaWFsX3ZlcmIoKQoreworICBzdHJpbmcgdmVyYjsKKyAgCisgIHZlcmI9cXVlcnlfdmVyYigpOworICBpZiAoIXZlcmJ8fHZlcmI9PSIiKSByZXR1cm4gMDsKKyAgaWYgKHZlcmJbMF09PSctJykgcmV0dXJuIDE7CisgIGlmICh2ZXJiPT0icnVmInx8dmVyYj09InJ1ZmUifHx2ZXJiPT0idGVpbGUifHx2ZXJiPT0idGVpbCJ8fHZlcmI9PSJtcnVmInx8CisgICAgICB2ZXJiPT0ibXJ1ZmUifHx2ZXJiPT0iZXJ6YWVobCJ8fHZlcmI9PSJlcnphZWhsZSIpIHJldHVybiAxOworICByZXR1cm4oMCk7IC8vIG5vbi12b2lkIGZ1bmt0aW9uLCBaZXNzdHJhCit9CisKK2ludCBfcXVlcnlfZ2VuZGVyKCkKK3sKKyAgcmV0dXJuIGdlbmRlcjsKK30KKworc3RyaW5nIF9xdWVyeV9uYW1lKCkKK3sKKyAgaWYgKCFzcGVjaWFsX3ZlcmIoKSkKKyAgICByZXR1cm4gY2FwaXRhbGl6ZShkZXNjKTsKKyAgcmV0dXJuIHBsYXllci0+UXVlcnkoUF9OQU1FKTsKK30KKworc3RyaW5nIF9xdWVyeV9zaG9ydCgpCit7CisgIHJldHVybiBjYXBpdGFsaXplKHBsYXllci0+bmFtZSgpKTsKK30KKworc3RyaW5nIF9xdWVyeV9sb25nKCkKK3sKKyAgc3RyaW5nIHN0cjsKKworICBzdHI9cGxheWVyLT5uYW1lKCk7CisgIHJldHVybiBjYXBpdGFsaXplKHN0cikrIiBpc3QgIitzdHIrIiBpc3QgIitzdHIrIi5cbiI7Cit9CisKK3N0cmluZyogX3F1ZXJ5X2lkcygpCit7CisgIHJldHVybiBwbGF5ZXItPlF1ZXJ5KCJpZHMiKSsoe2xvd2VyX2Nhc2UoZGVzYyl9KTsKK30KKworc3RyaW5nIF9xdWVyeV9yYWNlKCkKK3sKKyAgcmV0dXJuIGRlc2M7Cit9CisKK3ZvaWQgX3Rhcm5fdHVybl9vZmYoKQoreworICB1bnNoYWRvdygpOworICBkZXN0cnVjdCh0aGlzX29iamVjdCgpKTsKK30KKworaW50IF9xdWVyeV9hcnRpY2xlKCkKK3sKKyAgaWYgKCFzcGVjaWFsX3ZlcmIoKSkKKyAgICByZXR1cm4gMTsKKyAgcmV0dXJuKDApOyAvLyBub24tdm9pZCBmdW5rdGlvbiwgWmVzc3RyYQorfQorCitzdHJpbmcgX3F1ZXJ5X3ByZXNheSgpCit7CisgIHJldHVybiAiIjsKK30KKworc3RyaW5nIF9xdWVyeV90aXRsZSgpCit7CisgIHJldHVybiAiIjsKK30KKwordm9pZCBEZWZlbmQoaW50IGRhbSxtaXhlZCBkYW1fdHlwZSxtaXhlZCBzcGVsbCxvYmplY3QgZW5lbXkpCit7CisgIG9iamVjdCBvOworCisgIGlmICghcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShwcmV2aW91c19vYmplY3QoKSkpCisgICAgcGxheWVyLT5EZWZlbmQoZGFtLCBkYW1fdHlwZSwgc3BlbGwsIGVuZW15KTsKKyAgZWxzZQorICAgIHByZXZpb3VzX29iamVjdCgpLT5TdG9wSHVudEZvcihwbGF5ZXIpOworICBpZiAoKG89cHJlc2VudCgiXG50YXJuaGVsbSIscGxheWVyKSkpCisgICAgICAgIG8tPkRvVW53ZWFyKCk7CisgIGlmICh0aGlzX29iamVjdCgpKSBkZXN0cnVjdCh0aGlzX29iamVjdCgpKTsKK30KKworaW50IEtpbGwob2JqZWN0IG9iKQoreworICBvYmplY3QgbzsKKworICBpZiAoKG89cHJlc2VudCgiXG50YXJuaGVsbSIscGxheWVyKSkpCisgICAgICBvLT5Eb1Vud2VhcigpOworICBpZiAodGhpc19vYmplY3QoKSkgZGVzdHJ1Y3QodGhpc19vYmplY3QoKSk7CisgIHJldHVybigwKTsgLy8gbm9uLXZvaWQgZnVua3Rpb24sIFplc3N0cmEKK30KKworaW50IEluc2VydEVuZW15KG9iamVjdCBvYikKK3sKKyAgb2JqZWN0IG87CisKKyAgaWYgKCFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iKSkKKyAgICBwbGF5ZXItPkluc2VydEVuZW15KG9iKTsKKyAgZWxzZQorICAgIG9iLT5TdG9wSHVudEZvcihwbGF5ZXIpOworICBpZiAoKG89cHJlc2VudCgiXG50YXJuaGVsbSIscGxheWVyKSkpCisgICAgICBvLT5Eb1Vud2VhcigpOworICBpZiAodGhpc19vYmplY3QoKSkgZGVzdHJ1Y3QodGhpc19vYmplY3QoKSk7CisgIHJldHVybiAwOworfQorCitzdHJpbmcgc2hvcnQoKQoreworICBpZiAob2xkX2V4cGxvZGUob2JqZWN0X25hbWUocHJldmlvdXNfb2JqZWN0KCkpLCIjIilbMF09PSIvb2JqL3dlcmxpc3RlIikKKyAgICByZXR1cm4gY2FwaXRhbGl6ZShnZXRldWlkKHBsYXllcikrIiB2ZXJrbGVpZGV0IGFscyAiK3BsYXllci0+c2hvcnQoKSk7CisgIHJldHVybiBwbGF5ZXItPnNob3J0KCk7Cit9CisKK3N0cmluZyBRdWVyeURpc2d1aXNlKCkKK3sKKyAgcmV0dXJuIGRlc2M7IAorfQpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci9zaGFkb3dzL3phdWJlcnNoLmMgYi9zdGQvcGxheWVyL3NoYWRvd3MvemF1YmVyc2guYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMTljZWNjCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci9zaGFkb3dzL3phdWJlcnNoLmMKQEAgLTAsMCArMSwyMjAgQEAKKyNwcmFnbWEgc3Ryb25nX3R5cGVzLHNhdmVfdHlwZXMKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKworb2JqZWN0IGNhc3RlcjsKK3N0cmluZyppZHMsbmFtZTsKK2ludCBnZW5kZXIsYXJ0aWNsZSxwbHVyYWw7CitzdHJpbmcgbGdkZXNjOworc3RyaW5nIG1pbixtb3V0LG1taW4sbW1vdXQ7CittaXhlZCBoYW5kczsKKwordm9pZCBJbml0aWFsaXplKG9iamVjdCBfY2FzdGVyLAorICAgICAgICAgICAgICAgIHN0cmluZypfaWRzLAorICAgICAgICAgICAgICAgIHN0cmluZyBfbmFtZSwKKyAgICAgICAgICAgICAgICBpbnQgX2dlbmRlciwKKyAgICAgICAgICAgICAgICBpbnQgX2FydGljbGUsCisgICAgICAgICAgICAgICAgaW50IF9wbHVyYWwpCit7IGlmKCFvYmplY3RwKF9jYXN0ZXIpICAgIHx8CisgICAgICFpbnRlcmFjdGl2ZShfY2FzdGVyKXx8CisgICAgICFzdHJpbmdwKF9uYW1lKSAgICAgIHx8CisgICAgIF9uYW1lPT0iIiAgICAgICAgICAgIHx8CisgICAgIF9nZW5kZXI8MCAgICAgICAgICAgIHx8CisgICAgIF9nZW5kZXI+MikKKyAgeyBkZXN0cnVjdCh0aGlzX29iamVjdCgpKTsKKyAgICByZXR1cm47CisgIH0KKyAgY2FzdGVyPV9jYXN0ZXI7CisgIGlkcz1faWRzOworICBuYW1lPV9uYW1lOworICBnZW5kZXI9X2dlbmRlcjsKKyAgYXJ0aWNsZT1fYXJ0aWNsZTsKKyAgcGx1cmFsPV9wbHVyYWw7CisgIGxnZGVzYz0wOworICBzaGFkb3coY2FzdGVyLDEpOworfQorCit2b2lkIFNldExvbmdEZXNjKHN0cmluZyB0eHQpCit7IGlmKCFzdHJpbmdwKHR4dCl8fHR4dD09IiIpCisgICAgcmV0dXJuOworICBsZ2Rlc2M9dHh0OworfQorCitzdHJpbmcqIF9xdWVyeV9pZHMoKQoreyByZXR1cm4gY2FzdGVyLT5RdWVyeShQX0lEUykraWRzOworfQorCisvLyBuaWNodCBhbGxlIFZlcmJlbiBtaXQgdmVyYWVuZGVydGVtIEF1c3NlaGVuCitpbnQgc3BlY2lhbF92ZXJiKCkKK3sgc3RyaW5nIHZlcmI7CisgIHZlcmI9cXVlcnlfdmVyYigpOworICBpZighc3RyaW5ncCh2ZXJiKXx8dmVyYj09IiIpCisgICAgcmV0dXJuIDA7CisgIGlmKHZlcmJbMF09PSctJykKKyAgICByZXR1cm4gMTsKKyAgaWYobWVtYmVyKCh7InJ1ZiIsInJ1ZmUiLCJtcnVmIiwibXJ1ZmUiLAorICAgICAgICAgICAgICAidGVpbCIsInRlaWxlIiwiZXJ6YWVobCIsImVyemFlaGxlIn0pLHZlcmIpIT0tMSkKKyAgICByZXR1cm4gMTsKKyAgcmV0dXJuIDA7Cit9CisKK3N0cmluZyBfcXVlcnlfbmFtZSgpCit7IGlmKCFzcGVjaWFsX3ZlcmIoKSkKKyAgICByZXR1cm4gbmFtZTsKKyAgcmV0dXJuIGNhcGl0YWxpemUoY2FzdGVyLT5RdWVyeShQX05BTUUpKTsKK30KKworc3RyaW5nIF9xdWVyeV9zaG9ydCgpCit7IGlmKCFzcGVjaWFsX3ZlcmIoKSkKKyAgICByZXR1cm4gY2FzdGVyLT5OYW1lKCk7CisgIHJldHVybiBjYXN0ZXItPlF1ZXJ5KFBfU0hPUlQpOworfQorCitzdHJpbmcgX3F1ZXJ5X2xvbmcoKQoreyBpZighc3BlY2lhbF92ZXJiKCkpCisgIHsgc3RyaW5nIHN0cjsKKyAgICBpZihsZ2Rlc2MpCisgICAgICByZXR1cm4gbGdkZXNjOworICAgIHN0cj1jYXN0ZXItPm5hbWUoKTsKKyAgICByZXR1cm4gYnJlYWtfc3RyaW5nKGNhcGl0YWxpemUoc3RyKSsiIGlzdCAiK3N0cisiIGlzdCAiK3N0cisiLiIsNzgpOworICB9CisgIHJldHVybiBjYXN0ZXItPlF1ZXJ5KFBfTE9ORyk7Cit9CisKK2ludCBfcXVlcnlfZ2VuZGVyKCkKK3sgaWYoIXNwZWNpYWxfdmVyYigpKQorICAgIHJldHVybiBnZW5kZXI7CisgIHJldHVybiBjYXN0ZXItPlF1ZXJ5KFBfR0VOREVSKTsKK30KKworaW50IF9xdWVyeV9hcnRpY2xlKCkKK3sgaWYoIXNwZWNpYWxfdmVyYigpKQorICAgIHJldHVybiBhcnRpY2xlOworICByZXR1cm4gY2FzdGVyLT5RdWVyeShQX0FSVElDTEUpOworfQorCitpbnQgX3F1ZXJ5X3BsdXJhbCgpCit7IGlmKCFzcGVjaWFsX3ZlcmIoKSkKKyAgICByZXR1cm4gcGx1cmFsOworICByZXR1cm4gY2FzdGVyLT5RdWVyeShQX1BMVVJBTCk7Cit9CisKK3N0cmluZyBfcXVlcnlfcmFjZSgpCit7IGlmKCFzcGVjaWFsX3ZlcmIoKSkKKyAgICByZXR1cm4gbmFtZTsKKyAgcmV0dXJuIGNhc3Rlci0+UXVlcnkoUF9SQUNFKTsKK30KKwordmFyYXJncyBpbnQgcmVtb3ZlKGludCBzaWxlbnQpIHsKKyAgdW5zaGFkb3coKTsKKyAgZGVzdHJ1Y3QodGhpc19vYmplY3QoKSk7CisgIHJldHVybiAxOworfQorCit2b2lkIHN0b3Bfc2hhZG93KCkKK3sgCisgIHJlbW92ZSgpOworfQorCitzdHJpbmcgX3F1ZXJ5X3ByZXNheSgpCit7IHJldHVybiIiOworfQorCitzdHJpbmcgX3F1ZXJ5X3RpdGxlKCkKK3sgcmV0dXJuIiI7Cit9CisKK3N0cmluZyBfc2V0X21zZ2luKHN0cmluZyB2YWwpCit7IHJldHVybiBtaW49dmFsOworfQorCitzdHJpbmcgX3F1ZXJ5X21zZ2luKCkKK3sgcmV0dXJuIG1pbjsKK30KKworc3RyaW5nIF9zZXRfbXNnb3V0KHN0cmluZyB2YWwpCit7IHJldHVybiBtb3V0PXZhbDsKK30KKworc3RyaW5nIF9xdWVyeV9tc2dvdXQoKQoreyByZXR1cm4gbW91dDsKK30KKworc3RyaW5nIF9zZXRfbW1zZ2luKHN0cmluZyB2YWwpCit7IHJldHVybiBtbWluPXZhbDsKK30KKworc3RyaW5nIF9xdWVyeV9tbXNnaW4oKQoreyByZXR1cm4gbW1pbjsKK30KKworc3RyaW5nIF9zZXRfbW1zZ291dChzdHJpbmcgdmFsKQoreyByZXR1cm4gbW1vdXQ9dmFsOworfQorCitzdHJpbmcgX3F1ZXJ5X21tc2dvdXQoKQoreyByZXR1cm4gbW1vdXQ7Cit9CisKK21peGVkIF9zZXRfaGFuZHMobWl4ZWQgdmFsKQoreyByZXR1cm4gaGFuZHM9dmFsOworfQorCittaXhlZCBfcXVlcnlfaGFuZHMoKQoreyByZXR1cm4gaGFuZHM7Cit9CisKK3ZhcmFyZ3MgaW50IERlZmVuZChpbnQgZGFtLG1peGVkIGRhbV90eXBlLG1peGVkIHNwZWxsLG9iamVjdCBlbmVteSkKK3sgb2JqZWN0IG9iOworICBpZighZW5lbXkgfHwgIC8vIFNpbHZhbmEgMjYuMS4yMDAyCisgICAgICghcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShwcmV2aW91c19vYmplY3QoKSkmJgorICAgICAgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoZW5lbXkpKSkKKyAgICByZXR1cm4gY2FzdGVyLT5EZWZlbmQoZGFtLGRhbV90eXBlLHNwZWxsLGVuZW15KTsKKyAgZWxzZQorICB7IGVuZW15LT5TdG9wSHVudEZvcihjYXN0ZXIpOworICAgIGNhc3Rlci0+U3RvcEh1bnRGb3IoZW5lbXkpOworICB9CisgIGlmKG9iamVjdHAob2I9cHJlc2VudCgiemF1YmVyZXJcbnNoYWRvdyIsY2FzdGVyKSkpCisgICAgb2ItPnJlbW92ZSgpOworICBpZih0aGlzX29iamVjdCgpKQorICAgIHJlbW92ZSgpOworICByZXR1cm4gMDsKK30KKworaW50IEtpbGwob2JqZWN0IGVuZW15KQoreyBvYmplY3Qgb2I7CisgIGlmKCFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGVuZW15KSkKKyAgICByZXR1cm4gY2FzdGVyLT5LaWxsKGVuZW15KTsKKyAgaWYob2JqZWN0cChvYj1wcmVzZW50KCJ6YXViZXJlclxuc2hhZG93IixjYXN0ZXIpKSkKKyAgICBvYi0+cmVtb3ZlKCk7CisgIGlmKHRoaXNfb2JqZWN0KCkpCisgICAgcmVtb3ZlKCk7CisgIHJldHVybiAwOworfQorCitpbnQgSW5zZXJ0RW5lbXkob2JqZWN0IGVuZW15KQoreyBvYmplY3Qgb2I7CisgIGlmKCFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGVuZW15KSkKKyAgICByZXR1cm4gY2FzdGVyLT5JbnNlcnRFbmVteShlbmVteSk7CisgIGVsc2UgeworICAgIGVuZW15LT5TdG9wSHVudEZvcihjYXN0ZXIpOworICAgIGNhc3Rlci0+U3RvcEh1bnRGb3IoZW5lbXkpOworICB9CisgIGlmKG9iamVjdHAob2I9cHJlc2VudCgiemF1YmVyZXJcbnNoYWRvdyIsY2FzdGVyKSkpCisgICAgb2ItPnJlbW92ZSgpOworICBpZih0aGlzX29iamVjdCgpKQorICAgIHJlbW92ZSgpOworICByZXR1cm4gMDsKK30KKworc3RyaW5nIHNob3J0KCkKK3sgaWYobG9hZF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSA9PSAiL29iai93ZXJsaXN0ZSIpCisgICAgcmV0dXJuIGNhcGl0YWxpemUoZ2V0ZXVpZChjYXN0ZXIpKSsiIHZlcmtsZWlkZXQgYWxzICIrY2FzdGVyLT5zaG9ydCgpOworICByZXR1cm4gY2FzdGVyLT5zaG9ydCgpOworfQorCit2YXJhcmdzIHN0cmluZyBsb25nKCkKK3sgaWYobGdkZXNjKQorICAgIHJldHVybiBsZ2Rlc2M7CisgIHJldHVybiBjYXN0ZXItPmxvbmcoKTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvc2tpbGxzLmMgYi9zdGQvcGxheWVyL3NraWxscy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwM2RhOTcKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL3NraWxscy5jCkBAIC0wLDAgKzEsNjIxIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL3NraWxscy5jIC0tIFNwaWVsZXJza2lsbHMKKy8vCisvLyAkSWQ6IHNraWxscy5jIDg4MDkgMjAxNC0wNS0wOCAxOTo1Mjo0OFogWmVzc3RyYSAkCisKKy8vCisvLyAyMDAzLTAxLTIwOiBOdW4gWm9va3MgQmF1c3RlbGxlCisvLworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL2xpdmluZy9za2lsbHMiOworCisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxicmVha19zdHJpbmcuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwbGF5ZXIvYmFzZS5oPgorI2luY2x1ZGUgPHBsYXllci9nbWNwLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKy8vIERpZXNlcyBNYXBwaW5nIHNwZWljaGVydCBkaWUgZGVha3RpdmllcnRlbiBTa2lsbHMgZGVyIGVpbnplbG5lbiBHaWxkZW4KKy8vIERpZXNlIHdlcmRlbiBpbiBkZW4gR2lsZGVuIHVlYmVyIFBfR1VJTERfREVBQ1RJVkFURURfU0tJTEwgZ2VzZXR6dC4KK25vc2F2ZSBtYXBwaW5nIGRlYWN0aXZhdGVkX3NraWxscyA9IChbXSk7CisKKy8vIEZsYWcgZnVlciBkZW4gS29tcGF0aWJpbGl0YWV0c21vZHVzIGRlcyBLYW1wZnMgKEVtdWxhdGlvbiB2b24KKy8vIDJzLUFsYXJtemVpdCkuIFdlbm4gIT0gMCBzcGVpY2hlcnQgZGFzIEZsYWcgZ2xlaWNoemVpdGlnIGRpZSBaZWl0IGRlcworLy8gbGV0enRlbiBIZWFydGJlYXRzLiBBdWYgZGllc2UgWmVpdCB3aXJkIGRlciBTdGFydHB1bmt0IGVpbmVzIFNwZWxsZmF0aWd1ZXMKKy8vIGdnZi4genVydWVja2RhdGllcnQuIChtYXguIGVpbmUgU2VrdW5kZSkKK2ludCBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlOworCisvLyBFaW4gY3JlYXRlKCkgZnVlciBkYXMgTWFwcGluZworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBtYXBwaW5nIGFjdDsKKworICA6OmNyZWF0ZSgpOworCisgIC8vIFdpciBob2xlbiBkaWUgR2lsZGVuIGF1cyBkZW0gR2lsZGVubWFzdGVyIAorICBmb3JlYWNoKHN0cmluZyBndWlsZDoKKyAgICAgIChzdHJpbmcgKiljYWxsX290aGVyKEdVSUxETUFTVEVSLCJRdWVyeVByb3AiLFBfVkFMSURfR1VJTERTKSkKKyAgeworICAgIGlmKGNhdGNoKGFjdD1jYWxsX290aGVyKCIvZ2lsZGVuLyIrZ3VpbGQsIlF1ZXJ5UHJvcCIsCisgICAgICAgIFBfR1VJTERfREVBQ1RJVkFURV9TS0lMTFMpOyBwdWJsaXNoICkpCisgICAgICAgIGxvZ19maWxlKCJXRUFQT05fU0tJTExTIiwgc3ByaW50ZiAoIiVzOiBHaWxkZSBuaWNodCBsYWRiYXI6ICIKKyAgICAgICAgICAgICAgKyJUUDogJU8sIFRJOiAlTywgUE86ICVPLCBHaWxkZTogJXNcbiIsIGR0aW1lKHRpbWUoKSksCisgICAgICAgICAgICAgIHRoaXNfcGxheWVyKCksIHRoaXNfaW50ZXJhY3RpdmUoKSwgcHJldmlvdXNfb2JqZWN0KCksIGd1aWxkKSk7CisgICAgZWxzZSBpZiAoYWN0KSAvLyB3ZW5uIGFjdCwgaW5zIE1hcHBpbmcgYXVmbmVobWVuLgorICAgICAgICBkZWFjdGl2YXRlZF9za2lsbHMrPShbZ3VpbGQ6YWN0XSk7CisgIH0KKyAgLy8ga2VpbmUgZWNodGUgUHJvcCBtZWhyLCBTYXZlLU1vZHVzIHVubm9ldGlnLgorICBTZXQoUF9ORVhUX1NQRUxMX1RJTUUsU0FWRSxGX01PREVfQUQpOworCisgIFNldChQX1NLSUxMU1ZFUlNJT04sIFNBVkV8U0VDVVJFRCwgRl9NT0RFX0FTKTsKK30KKworLy8gRGFzIE1hcHBpbmcga2FubiBtYW4gYXVjaCBhYmZyYWdlbgorCitwdWJsaWMgbWFwcGluZyBHZXREZWFjdGl2YXRlZFNraWxscygpCit7CisgICAgcmV0dXJuIGNvcHkoZGVhY3RpdmF0ZWRfc2tpbGxzKTsKK30KKworLy8gRnVua3Rpb24sIGRpZSBzYWd0IG9iIGVpbiBBTlktU2tpbGwgZGVha3RpdmllcnQgaXN0LgorcHVibGljIGludCBpc19kZWFjdGl2YXRlZF9za2lsbChzdHJpbmcgc25hbWUsc3RyaW5nIGd1aWxkKQoreworICAgICAgICBpZiAoZGVhY3RpdmF0ZWRfc2tpbGxzW2d1aWxkXSkgICAgICAgIAorICAgICAgICAgICAgICAgIHJldHVybiBkZWFjdGl2YXRlZF9za2lsbHNbZ3VpbGRdW3NuYW1lXTsKKyAgICAgICAgcmV0dXJuIDA7Cit9CisKKworLy8gRnVua3Rpb24gZnVlciBkaWUgV2FmZmVuc2tpbGxzCisvLyB0cmFlZ3QgZGllIGFsbGcuIFdhZmZlbnNraWxscyBlaW4uIFdpcmQgZ2dmLiB2b24gRml4U2tpbGxzKCkgZ2VydWZlbi4KKy8vIChEYXMgRWludHJhZ2VuIGJlZGV1dGV0IG5pY2h0LCBkYXNzIGRpZSBha3RpdiBzaW5kISBBYmVyIGJlaSBHaWxkZW53ZWNoc2VsCisvLyB3ZXJkZW4gc2llIG5pY2h0IGVpbmdldHJhZ2VuKS4KK3ByaXZhdGUgdm9pZCBzZXRfd2VhcG9uX3NraWxscygpIHsKKworICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfU1dPUkQpKTw9MCkgICAgICAgICAgICAgICAgCisgICAgICBNb2RpZnlTa2lsbChGSUdIVChXVF9TV09SRCksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7ICAgIAorICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfQVhFKSk8PTApICAgICAgICAgICAgICAgIAorICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfQVhFKSwoW1NJX1NLSUxMQUJJTElUWTowXSksMTUwLCJBTlkiKTsgICAgICAgICAgCisgIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9TUEVBUikpPD0wKSAgICAgICAgCisgICAgICBNb2RpZnlTa2lsbChGSUdIVChXVF9TUEVBUiksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7ICAgICAgICAgIAorICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfV0hJUCkpPD0wKQorICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfV0hJUCksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7CisgIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9LTklGRSkpPD0wKSAgICAgICAgICAgICAgICAKKyAgICAgIE1vZGlmeVNraWxsKEZJR0hUKFdUX0tOSUZFKSwoW1NJX1NLSUxMQUJJTElUWTowXSksMTUwLCJBTlkiKTsgICAgICAgICAgCisgIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9DTFVCKSk8PTApICAgICAgICAgICAgICAgIAorICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfQ0xVQiksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7ICAgICAgICAgIAorICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfU1RBRkYpKTw9MCkKKyAgICAgIE1vZGlmeVNraWxsKEZJR0hUKFdUX1NUQUZGKSwoW1NJX1NLSUxMQUJJTElUWTowXSksMTUwLCJBTlkiKTsKK30gCisKKy8vIGluaXRpYWxpc2llcnQgZGllIFNraWxscyBmdWVyIFNwaWVsZXIgKG1vbWVudGFuOiBhbGxnLiBXYWZmZW5za2lsbHMgc2V0emVuCisvLyB1bmQgUF9TS0lMTFNfVkVSU0lPTikKK3Byb3RlY3RlZCB2b2lkIEluaXRTa2lsbHMoKSB7CisgIG1hcHBpbmcgc2tpOworICAvLyBzY2hvbm1hbCBpbml0aWFsaXNpZXJ0PworICBpZiAobWFwcGluZ3Aoc2tpPVF1ZXJ5KFBfTkVXU0tJTExTLCBGX1ZBTFVFKSkgJiYgc2l6ZW9mKHNraSkpCisgICAgcmV0dXJuOworCisgIC8vIGFsbGcuIFdhZmZlbnNraWxscyBha3RpdmllcmVuCisgIHNldF93ZWFwb25fc2tpbGxzKCk7CisKKyAgLy8gVmVyc2lvbiBzZXR6ZW4KKyAgU2V0UHJvcChQX1NLSUxMU1ZFUlNJT04sIENVUlJFTlRfU0tJTExfVkVSU0lPTik7CisgIFNldChQX1NLSUxMU1ZFUlNJT04sIFNBVkV8U0VDVVJFRCwgRl9NT0RFX0FTKTsKK30KKworLy8gVXBkYXRlZCBTa2lsbHMgYXVzIFZlcnNpb24gMCB1bmQgMSBoZXJhdXMuCitwcml2YXRlIHZvaWQgRml4U2tpbGxWMShzdHJpbmcgc2tpbGxuYW1lLCBtaXhlZCBzaW5mbykgeworICAvLyBhbHRlIFNraWxscyBhdWYgbWFwcGluZ3Mgbm9ybWllcmVuCisgIGlmIChpbnRwKHNpbmZvKSkgeworICAgIHNpbmZvID0gKFtTSV9TS0lMTEFCSUxJVFk6IHNpbmZvIF0pOworICB9CisgIC8vIEVpbmUgUmVpaGUgdm9uIERhdGVuIHdlcmRlbiBnZWxvZXNjaHQsIGRhIGRpZSBEYXRlbiBhdXMgZGVyCisgIC8vIEdpbGRlL1NwZWxsYm9vayBmcmlzY2gga29tbWVuIHNvbGx0ZW4gdW5kIHNpZSBuaWNodCBzcGllbGVyLWluZGl2aWR1ZWxsCisgIC8vIHNpbmQ6IFNJX0NMT1NVUkUgKHdpcmQgb250aGVmbHkga29ycmVrdCBuZXUgZXJ6ZXVndCksIFNJX1NLSUxMQVJHLAorICAvLyBTSV9OVU1CRVJfRU5FTUlFUywgU0lfTlVNQkVSX0ZSSUVORFMsIFNJX0RJU1RBTkNFLCBTSV9XSURUSCwgU0lfREVQVEgsCisgIC8vIFNJX1RFU1RGTEFHLCBTSV9FTkVNWSwgU0lfRlJJRU5ELgorICAvLyBBdXNzZXJkZW0gc2luZCBhbGxlIFNQXyogaW0gdG9wbGV2ZWwgZmFsc2NoLCBkaWUgbXVlc3NlbiBhKSBpbiBTSV9TUEVMTAorICAvLyB1bmQgc29sbHRlbiBiKSBuaWNodCBpbSBTcGllbGVyIGdlc3BlaWNoZXJ0IHdlcmRlbiwgc29uZGVybiB2b24KKyAgLy8gR2lsZGVuL1NwZWxsYm9vayBqZXdlaWxzIGZyaXNjaCBrb21tZW4uCisgIC8vIGFsbCBkaWVzZXMgWmV1ZyBsYW5kZXRlIGluIGFsdGVuIFNwaWVsZXJuIGltIFNhdmVmaWxlLgorICBpZiAobWFwcGluZ3Aoc2luZm8pKQorICAgIHNpbmZvIC09IChbU0lfQ0xPU1VSRSwgU0lfU0tJTExBUkcsIFNJX05VTUJFUl9FTkVNSUVTLCBTSV9OVU1CRVJfRlJJRU5EUywKKyAgICAgICAgICAgICBTSV9ESVNUQU5DRSwgU0lfV0lEVEgsIFNJX0RFUFRILCBTSV9URVNURkxBRywgU0lfRU5FTVksCisgICAgICAgICAgICAgU0lfRlJJRU5ELCBTUF9OQU1FLCBTUF9TSE9XX0RBTUFHRSwgU1BfUkVEVUNFX0FSTU9VUiwKKyAgICAgICAgICAgICBTUF9QSFlTSUNBTF9BVFRBQ0ssIFNQX1JFQ1VSU0lWRSwgU1BfTk9fRU5FTVksCisgICAgICAgICAgICAgU1BfTk9fQUNUSVZFX0RFRkVOU0UsIFNQX0dMT0JBTF9BVFRBQ0sgXSk7CisgIGVsc2UKKyAgeworICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigKKyAgICAgICJcbioqKiogQUNIVFVORyAtIEZFSExFUiAqKipcbiIgCisgICAgICAiRGVpbmUgU2tpbGxzIGVudGhhbHRlbiBlaW5lbiBkZWZla3RlbiBTa2lsbCAlTzpcbiIKKyAgICAgICJCaXR0ZSBsYXNzIGRpZXMgdm9uIGVpbmVtIEVyem1hZ2llciB1ZWJlcnBydWVmZW4uXG4iLAorICAgICAgc2tpbGxuYW1lKSk7CisgIH0KK30KKworLy8gVXBkYXRldCB1bmQgcmVwYXJpZXJ0IGdnZi4gU2tpbGxtYXBwaW5ncyBpbiBTcGllbGVybgorcHJvdGVjdGVkIHZvaWQgRml4U2tpbGxzKCkgeworCisgIC8vIG51ciBiZWkgZ2VudWcgcmVjaGVuemVpdCBsb3NsZWdlbgorICBpZiAoZ2V0X2V2YWxfY29zdCgpIDwgNzUwMDAwKSB7CisgICAgY2FsbF9vdXQoIydGaXhTa2lsbHMsIDEpOworICAgIHJldHVybjsKKyAgfQorICAvLyB3ZW5uIGdhciBrZWluZSBTa2lsbHMgZGEgKD8pOiBJbml0U2tpbGxzKCkgcnVmZW4uCisgIG1hcHBpbmcgYWxsc2tpbGxzID0gUXVlcnkoUF9ORVdTS0lMTFMsIEZfVkFMVUUpOworICBpZiAoIW1hcHBpbmdwKGFsbHNraWxscykgfHwgIXNpemVvZihhbGxza2lsbHMpKSB7CisgICAgICBJbml0U2tpbGxzKCk7CisgICAgICByZXR1cm47CisgIH0KKworICAvLyBEaWUgRmFsbHRocm91Z2hzIGluIGRpZXNlbSBzd2l0Y2ggc2luZCB2b2xsIEFic2ljaHQhCisgIHN3aXRjaChRdWVyeVByb3AoUF9TS0lMTFNWRVJTSU9OKSkgeworICAgIC8vIGJlaSBWZXJzaW9uIDAgdW5kIDEgZGFzIGdsZWljaGUgdHVuCisgICAgY2FzZSAwOiAvLyB2b24gMCBhdWYgMQorICAgIGNhc2UgMTogLy8gdm9uIDEgYXVmIDIKKyAgICAgIGZvcmVhY2goc3RyaW5nIGdpbGRlLCBtYXBwaW5nIHNraWxsczogYWxsc2tpbGxzKSB7CisgICAgICAgIGlmICghc3RyaW5ncChnaWxkZSkpIHsKKyAgICAgICAgICAvLyBzb2xsdGUgbmljaHQgdm9ya29tbWVuIC0gdGF0IGFiZXIuLi4gKnNldWZ6KgorICAgICAgICAgIG1fZGVsZXRlKHNraWxscywgZ2lsZGUpOworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIHdhbGtfbWFwcGluZyhza2lsbHMsICMnRml4U2tpbGxWMSk7CisgICAgICB9CisgICAgICAvLyBhbGxnLiBXYWZmZW5za2lsbHMgYWt0aXZpZXJlbiwgZWluaWdlIGFsdGUgU3BpZWxlciBoYWJlbiBkaWUgbm9jaAorICAgICAgLy8gbmljaHQuCisgICAgICBzZXRfd2VhcG9uX3NraWxscygpOworICAgICAgLy8gU3BlaWNoZXJmbGFnIGZ1ZXIgZGllIFZlcnNpb25zcHJvcCBtdXNzIG5vY2ggZ2VzZXR6dCB3ZXJkZW4uCisgICAgICBTZXQoUF9TS0lMTFNWRVJTSU9OLCBTQVZFfFNFQ1VSRUQsIEZfTU9ERV9BUyk7CisgICAgICAvLyBWZXJzaW9uIGlzdCBqZXR6dCAyLgorICAgICAgU2V0UHJvcChQX1NLSUxMU1ZFUlNJT04sIDIpOworICAgICAgLy8gRmFsbC10aHJvdWdoCisgICBjYXNlIDI6CisgICAgICAvLyBnaWJ0IGVzIG5vY2ggbmljaHQsIG5pY2h0cyBtYWNoZW4uCisgICAgICAvL1NldFByb3AoUF9TS0lMTFNWRVJTSU9OLCAzKTsKKyAgICAgIC8vIEZhbGwtdGhyb3VnaCwgYXVzc2VyIGVzIHNpbmQgenV3ZW5pZyBUaWNrcyBkYSEKKyAgICAgIGlmIChnZXRfZXZhbF9jb3N0KCkgPCA3NTAwMDApCisgICAgICAgIGJyZWFrOyAKKyAgfQorICAvLyBGYWxscyBub2NoIG5pY2h0IGF1ZiBkZXIgYWt0dWVsbGVuIFZlcnNpb24gYW5nZWtvbW1lbiwgbmV1ZXIgY2FsbG91dAorICBpZiAoUXVlcnlQcm9wKFBfU0tJTExTVkVSU0lPTikgPCBDVVJSRU5UX1NLSUxMX1ZFUlNJT04pCisgICAgICBjYWxsX291dCgjJ0ZpeFNraWxscywgMik7Cit9CisKK3Byb3RlY3RlZCB2b2lkIHVwZGF0ZXNfYWZ0ZXJfcmVzdG9yZShpbnQgbmV3ZmxhZykgeworICAvL0FsbGdlbWVpbmUgV2FmZmVuc2tpbGxzIGFrdGl2aWVyZW4sIHdlbm4gbm9ldGlnCisgIC8vIFdpcmQgbnVuIHZvbiBJbml0U2tpbGxzIGJ6dy4gRml4U2tpbGxzIHVlYmVybm9tbWVuLCBmYWxscyBub2V0aWcuCisgIGlmIChuZXdmbGFnKSB7CisgICAgSW5pdFNraWxscygpOworICB9CisgIGVsc2UgaWYgKFF1ZXJ5UHJvcChQX1NLSUxMU1ZFUlNJT04pIDwgQ1VSUkVOVF9TS0lMTF9WRVJTSU9OKSB7CisgICAgLy8gRmFsbHMgbm9ldGlnLCBTa2lsbHMgZml4ZW4vdXBkYXRlbi4gKmdydW1tZWwqCisgICAgRml4U2tpbGxzKCk7CisgIH0KKyAgLy8gUHJvcCBnaWJ0IGVzIG5pY2h0IG1laHIuIFNBVkUtU3RhdHVzIGxvZXNjaGVuLiAKKyAgU2V0KFBfR1VJTERfUFJFVkVOVFNfUkFDRVNLSUxMLFNBVkUsRl9NT0RFX0FEKTsKK30KKworLy8gU3RhbmRhcmRpc2llcnRlIE5haGthbXBmLUZ1bmt0aW9uIGZ1ZXIgYWxsZSBOYWhrYW1wZi1XYWZmZW5hcnRlbgorcHJvdGVjdGVkIG1hcHBpbmcgU2hvcnRSYW5nZVNraWxsKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKSAKK3sgCisgIGludCB2YWwsIHc7CisgIG9iamVjdCBlbmVteTsKKyAgCisgIGlmICghbWFwcGluZ3Aoc2luZm8pIHx8ICFvYmplY3RwKHNpbmZvW1BfV0VBUE9OXSkpCisgICAgcmV0dXJuIDA7CisKKyAgdyA9IChbV1RfS05JRkUgOiA4LAorICAgICAgICBXVF9TV09SRCA6IDUsCisgICAgICAgIFdUX0FYRSAgIDogNCwKKyAgICAgICAgV1RfU1BFQVIgOiA2LAorICAgICAgICBXVF9DTFVCICA6IDEsCisgICAgICAgIFdUX1dISVAgIDogOSwKKyAgICAgICAgV1RfU1RBRkYgOiA3XSlbc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9XRUFQT05fVFlQRSldOworICAgICAgCisKKyAgdmFsID0gc2luZm9bU0lfU0tJTExBQklMSVRZXSooc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9XQykqCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh3KlF1ZXJ5QXR0cmlidXRlKEFfREVYKSsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxMC13KSpRdWVyeUF0dHJpYnV0ZShBX1NUUikpLzcwMCkKKyAgICAgICAgL01BWF9BQklMSVRZOworCisgIGlmICh2YWwgPiA4NSkgeworICAgIGxvZ19maWxlKCJXRUFQT05fU0tJTExTIiwgc3ByaW50ZigiJXM6IFp1IGhvaGVyIFNjaGFkZW4gdm9uOiAiCisgICAgKyJUTzogJU8sIFRJOiAlTywgUE86ICVPLCB2YWw6ICVkLCBBX0RFWDogJWQsIEFfU1RSOiAlZCwgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIlBfV0VBUE9OOiAlTywgUF9XQzogJWRcbiIsIGR0aW1lKHRpbWUoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfb2JqZWN0KCksIHRoaXNfaW50ZXJhY3RpdmUoKSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzX29iamVjdCgpLCB2YWwsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRdWVyeUF0dHJpYnV0ZShBX0RFWCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFF1ZXJ5QXR0cmlidXRlKEFfU1RSKSwgc2luZm9bUF9XRUFQT05dLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaW5mb1tQX1dFQVBPTl0tPlF1ZXJ5UHJvcChQX1dDKSkpOworICAgIHZhbCA9IDg1OworICB9CisKKyAgLyoKKyAgICBEZXIgenVz5HR6bGljaGUgU2NoYWRlbiBkZXIgYWxsZ2VtZWluZW4gV2FmZmVuc2tpbGxzIGJlcmVjaG5ldAorICAgIHNpY2ggd2llIGZvbGd0OiAKKworICAgIHNpbmZvW1NJX1NLSUxMQUJJTElUWSkqIChQX1dDICogKCBYICkgLyA4MDApIC8gTUFYX0FCSUxJVFkKKworICAgIERhYmVpIGJlcnVlY2tzaWNodGlndCBYIGplIG5hY2ggV2FmZmVudHlwIGluIHVudGVyc2NoaWVkbGljaGVyCisgICAgR2V3aWNodHVuZyBkaWUgV2VydGUgZnVlciBHZXNjaGlja2xpY2hrZWl0IHVuZCBTdGFlcmtlLiAKKworICAgICBYID09IAorCisgICAgICAgTWVzc2VyICAgOiA4KkFfREVYICsgMipBX1NUUgorICAgICAgIFNjaHdlcnQgIDogNSpBX0RFWCArIDUqQV9TVFIKKyAgICAgICBBeHQgICAgICA6IDQqQV9ERVggKyA2KkFfU1RSIAorICAgICAgIFNwZWVyICAgIDogNipBX0RFWCArIDQqQV9TVFIKKyAgICAgICBLZXVsZSAgICA6IDEqQV9ERVggKyA5KkFfU1RSCisgICAgICAgUGVpdHNjaGUgOiA5KkFfREVYICsgMSpBX1NUUgorICAqLworCisgIHNpbmZvW1NJX1NLSUxMREFNQUdFXSs9dmFsOworCisKKyAgLyogTGVybmVuOiBXaXJkIGltbWVyIHNjaHdpZXJpZ2VyLCBudXIgYmVpIGplZGVtIDIwLiBTY2hsYWcgaW0gU2Nobml0dCwKKyAgICogdW5kIG51ciBkYW5uLCB3ZW5uIGRlciBHZWduZXIgYXVjaCBYUCBnaWJ0LiAqLworICBpZiAocmFuZG9tKE1BWF9BQklMSVRZKzEpPnNpbmZvW1NJX1NLSUxMQUJJTElUWV0gJiYgIXJhbmRvbSgxMCkpCisgIHsKKyAgICAgICAgIGVuZW15PXNpbmZvW1NJX0VORU1ZXTsKKyAgICAgICAgIGlmIChvYmplY3RwKGVuZW15KSAmJiAoZW5lbXktPlF1ZXJ5UHJvcChQX1hQKT4wKSkKKyAgICAgICAgIHsKKyAgICAgICAgICAgb2JqZWN0IGF1c2JpbGRlcjsKKyAgICAgICAgLy8gICAgICAgICBsb2dfZmlsZSgiaHVtbmkvbG9nX3d1cm0iLCJIYXV0OiAlcyB1bmQgendhciAlcywgbWl0IHhwICVkXG4iLGdldGV1aWQodGhpc19vYmplY3QoKSksdG9fc3RyaW5nKGVuZW15KSxlbmVteS0+UXVlcnlQcm9wKFBfWFApKTsKKyAgICAgICAgICAgIExlYXJuU2tpbGwoc25hbWUsIHJhbmRvbSg1KSwgMTUwKTsKKyAgICAgICAgLy8gR2lidCBlcyBlaW5lbiBBdXNiaWxkZXI/CisgICAgICAgIGlmIChRdWVyeVByb3AoUF9XRUFQT05fVEVBQ0hFUikgJiYgCisgICAgICAgICAgICAgICAgICAgICAgICBhdXNiaWxkZXI9ZmluZF9wbGF5ZXIoUXVlcnlQcm9wKFBfV0VBUE9OX1RFQUNIRVIpKSkKKyAgICAgICAgICB7CisgICAgICAgICAgICAvLyBJc3QgZGVyIEF1c2JpbGRlciBhbndlc2VuZD8KKyAgICAgICAgICAgIGlmIChwcmVzZW50KGF1c2JpbGRlcixlbnZpcm9ubWVudCgpKSkKKyAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAvLyBBdXNiaWxkZXIgdW5kIEF6dWJpIG11ZXNzZW4gZGllc2VsYmUgV2FmZmUgaGFiZW4uCisgICAgICAgICAgICAgIC8vc3RyaW5nIHd0X2F1cyx3dF9henU7CisgICAgICAgICAgICAgIG9iamVjdCB3YWZfYXVzLHdhZl9henU7CisKKyAgICAgICAgICAgICAgd2FmX2F6dT1RdWVyeVByb3AoUF9XRUFQT04pOworICAgICAgICAgICAgICB3YWZfYXVzPWNhbGxfb3RoZXIoYXVzYmlsZGVyLCJRdWVyeVByb3AiLFBfV0VBUE9OKTsKKworICAgICAgICAgICAgICAvL3d0X2F6dT1jYWxsX290aGVyKHdhZl9henUsIlF1ZXJ5UHJvcCIsUF9XRUFQT05fVFlQRSk7CisgICAgICAgICAgICAgIC8vd3RfYXVzPWNhbGxfb3RoZXIod2FmX2F1cywiUXVlcnlQcm9wIixQX1dFQVBPTl9UWVBFKTsKKyAgICAgICAgICAgICAgLy9pZiAod3RfYXp1PT13dF9hdXMpCisgICAgICAgICAgICAgIGlmIChvYmplY3RwKHdhZl9hdXMpICYmIG9iamVjdHAod2FmX2F6dSkgJiYKKyAgICAgICAgICAgICAgICAgIChzdHJpbmcpd2FmX2F1cy0+UXVlcnlQcm9wKFBfV0VBUE9OX1RZUEUpCisgICAgICAgICAgICAgICAgICAgICA9PSAoc3RyaW5nKXdhZl9henUtPlF1ZXJ5UHJvcChQX1dFQVBPTl9UWVBFKSkgCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIC8vIEJvbnVzIHZvbiBiaXMgenUgNSBQdW5rdGVuCisgICAgICAgICAgICAgICAgLy9sb2dfZmlsZSgiaHVtbmkvbG9nX2F6dWJpIiwKKyAgICAgICAgICAgICAgICAgIC8vIHNwcmludGYoIkF6dWJpICVPIHVuZCBBdXNiaWxkZXIgJU8gOiBXYWZmZW50eXBlbiAlcyB1bmQgJXMsIGdlbGVybnRcbiIsdGhpc19vYmplY3QoKSwKKyAgICAgICAgICAgICAgICAgICAgLy8gICBhdXNiaWxkZXIsIHd0X2F6dSwgd3RfYXVzKSk7CisgICAgICAgICAgICAgICAgTGVhcm5Ta2lsbChzbmFtZSxyYW5kb20oNiksMTUwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICB9CisKKyAgLyogCisgICAgIERpZSBTY2h3aWVyaWdrZWl0IGxpZWd0IGJlaSAxNTAsIHNvIGRhc3MgCisgICAgIGVpbiBMdmwuIDEgU3BpZWxlciBtYXhpbWFsIDE1JSBTa2lsbCAKKyAgICAgdXN3Li4uCisgICAgIGxlcm5lbiBrYW5uLiAoR2VuYXVlIFRhYmVsbGUgaW4gL3N0ZC9saXZpbmcvc2tpbGxzIGJlaSBMaW1pdEFiaWxpdHkpCisgICovICAgICAgICAgCisKKyAgcmV0dXJuIHNpbmZvOworfQorCisKKy8vIFN0YW5kYXJkaXNpZXJ0ZSBGZXJua2FtcGYtRnVua3Rpb24gZnVlciBhbGxlIEZlcm5rYW1wZi1XYWZmZW5hcnRlbgorCisvLyAqKiogbm9jaCBkZWFrdGl2aWVydCAqKioKKworcHJvdGVjdGVkIG1hcHBpbmcgTG9uZ1JhbmdlU2tpbGwob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8sIGludCBkYW0pIAoreyBpbnQgYWJpbCx2YWw7CisKKyAgaWYgKCFtYXBwaW5ncChzaW5mbykgfHwgIWRhbSB8fCAhb2JqZWN0cChzaW5mb1tQX1dFQVBPTl0pIHx8CisgICAgICAoc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9TSE9PVElOR19XQykpPDUpCisgICAgcmV0dXJuIDA7CisKKyAgYWJpbD1zaW5mb1tTSV9TS0lMTEFCSUxJVFldK3NpbmZvW09GRlNFVChTSV9TS0lMTEFCSUxJVFkpXTsgCisgIHZhbD1kYW0qYWJpbC9NQVhfQUJJTElUWTsKKyAgdmFsPXZhbC8yK3JhbmRvbSh2YWwvMisxKTsKKyAgdmFsPSh2YWwqUXVlcnlTa2lsbEF0dHJpYnV0ZShTQV9EQU1BR0UpKS8xMDA7CisgIHNpbmZvW1NJX1NLSUxMREFNQUdFXSs9dmFsOworCisgIGlmIChyYW5kb20oTUFYX0FCSUxJVFkrMSk+c2luZm9bU0lfU0tJTExBQklMSVRZXSAmJiByYW5kb20oNTApPT00MikKKyAgICBMZWFyblNraWxsKHNuYW1lLCAxLCAxNTApOworCisgIHJldHVybiBzaW5mbzsKK30KKworCisKKy8vIERpZSBlaW56ZWxuZW4gV2FmZmVuc2tpbGxzIHJ1ZmVuIGRhbm4gbnVyIGRpZSBTdGFuZGFyZC1GdW5rdGlvbiBhdWYuCisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X2F4ZShvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKK3sKKyAgcmV0dXJuIFNob3J0UmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvKTsKK30KKworcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfY2x1YihvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKK3sKKyAgcmV0dXJuIFNob3J0UmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvKTsKK30KKworcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfa25pZmUob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCit7CisgIHJldHVybiBTaG9ydFJhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbyk7Cit9CisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X3NwZWFyKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQoreworICByZXR1cm4gU2hvcnRSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8pOworfQorCitwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9GaWdodF9zd29yZChvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykgCit7CisgIHJldHVybiBTaG9ydFJhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbyk7Cit9CisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X3doaXAob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCit7CisgIHJldHVybiBTaG9ydFJhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbyk7Cit9CisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X3N0YWZmKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQoreworICByZXR1cm4gU2hvcnRSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8pOworfQorCisKKworCisvLyBEaWUgRmVybndhZmZlbnNraWxscyBzaW5kIE11bml0aW9uc2FiaGFlbmdpZworCisvLyAqKiogbm9jaCBkZWFrdGl2aWVydCAqKioKKworcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfU2hvb3RfYXJyb3cob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCit7CisgIHJldHVybiBMb25nUmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvLCA0MCk7Cit9CisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX1Nob290X2JvbHQob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCit7IAorICByZXR1cm4gTG9uZ1JhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbywgNDApOworfQorCitwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9TaG9vdF9kYXJ0KG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQoreworICByZXR1cm4gTG9uZ1JhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbywgMjApOworfQorCitwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9TaG9vdF9zdG9uZShvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKK3sKKyAgcmV0dXJuIExvbmdSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8sIDQwKTsKK30KKworcHJvdGVjdGVkIG1peGVkIF9xdWVyeV9sb2NhbGNtZHMoKSB7CisgICAgcmV0dXJuICh7ICh7InNwcnVjaGVybXVlZHVuZyIsImVuYWJsZV9zcGVsbF9mYXRpZ3VlX2NvbXBhdCIsMCwwfSkgfSk7Cit9CisKKworCisvLyAqKiogS29tcGF0aWJpbGl0YWV0c21vZHVzIGZ1ZXIgU3BlbGxmYXRpZ3VlcyAoRW11bGF0aW9uIDJzLUFsYXJtemVpdCkgKioqCisKKy8qKiBTcGVpY2hlcnQgZWluZSBTcGVsbGZhdGlndWUgdm9uIDxkdXJhdGlvbj4gU2VrdW5kZW4gZnVlciA8a2V5Pi4KKyAqIElzdCBoaWVyIG51ciBmdWVyIGRlbiBTcGVsbGZhdGlndWUtQ29tcGF0LW1vZGUuCisgKiA8a2V5PiBkYXJmIDAgc2VpbiB1bmQgYmV6ZWljaG5ldCBkYXMgZ2xvYmFsZSBTcGVsbGZhdGlndWUuCisgKiBSdWVja2dhYmV3ZXJ0OiBBYmxhdWZ6ZWl0IGRlciBnZXNldHp0ZW4gU3BlcnJlCisgICAgICAgICAgICAgICAgICAtMSwgd2VubiBub2NoIGVpbmUgbmljaHQtYWJnZWxhdWZlbmUgU3BlcnJlIGF1ZiBkZW0gPGtleT4gbGFnLgorICAgICAgICAgICAgICAgICAgMCwgd2VubiBkdXJhdGlvbiAwIGlzdC4KKyAqLworcHVibGljIHZhcmFyZ3MgaW50IFNldFNwZWxsRmF0aWd1ZShpbnQgZHVyYXRpb24sIHN0cmluZyBrZXkpIHsKKworICAvLyAwIHNvbGx0ZSBuaWUgZWluZSBTcGVycmUgYmV3aXJrZW4sIGF1Y2ggbmljaHQgaW0gY29tcGF0IG1vZGUuCisgIGlmICghZHVyYXRpb24pIHJldHVybiAwOworCisgIGlmIChzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlKSB7CisgICAgLy8gU3BlbGwtRmF0aWd1ZXMgYXVmIEhCcyBzeW5jaHJvbmlzaWVyZW4gKDJzLUFsYXJtemVpdC1FbXVsYXRpb24pLgorICAgIC8vIEF1ZnJ1bmRlbiBhdWYgZ2FuenphaGxpZ2UgVmllbGZhY2hlIHZvbiBfX0hFQVJUX0JFQVRfSU5URVJWQUxfXworICAgIGlmIChkdXJhdGlvbiAlIF9fSEVBUlRfQkVBVF9JTlRFUlZBTF9fKQorICAgICAgICArK2R1cmF0aW9uOworCisgICAgLy8gU3RhcnRwdW5rdCBkZXMgRGVsYXkgc29sbCBCZWdpbm4gZGVyIGFrdHVlbGxlbiBLYW1wZnJ1bmRlIChIQi1aeWtsdXMpCisgICAgLy8gc2VpbiwgZ2dmLiB1bSBtYXguIGVpbmUgU2VrdW5kZSB6dXJ1ZWNrZGF0aWVyZW4uCisgICAgLy8gKHNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGUgaGF0IGRpZSBaZWl0IGRlcyBsZXR6dGVuIEhCLUF1ZnJ1ZnMpCisgICAgLy8gRmFsbHMgZHVyY2ggaXJnZW5kZWluIFByb2JsZW0gKHouQi4gc2VociBob2hlIExhc3QpLCBkZXIgbGV0enRlIEhCCisgICAgLy8gbGFlbmdlciBhbHMgMXMgenVydWVja2xpZWd0LCBmdW5rdGlvbmllcnQgZGFzIG5hdHVlcmxpY2ggbmljaHQsIGFiZXIKKyAgICAvLyBiZWkgZmF0aWd1ZSs9c3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSBrYW5uIGRlciBTcGllbGVyIHp1dmllbCBaZWl0CisgICAgLy8gZWluc3BhcmVuLgorICAgIGlmICh0aW1lKCkgPiBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlKQorICAgICAgICAtLWR1cmF0aW9uOyAgLy8xcyB6dXJ1ZWNrZGF0aWVyZW4KKyAgfQorCisgIHJldHVybiA6OlNldFNwZWxsRmF0aWd1ZShkdXJhdGlvbiwga2V5KTsKK30KKworLyoqIEJlZmVobHNmdW5rdGlvbiBmdWVyIFNwaWVsZXIgdW0gZGVuIFNwZWxsZmF0aWd1ZS1Lb21wYXRpYmlsaXRhZXRzbW9kdXMKKyAqIHVtenVzY2hhbHRlbi4KKyAqLworcHVibGljIGludCBlbmFibGVfc3BlbGxfZmF0aWd1ZV9jb21wYXQoc3RyaW5nIGNtZCkgeworICBpZiAoUXVlcnlQcm9wKFBfTEFTVF9DT01CQVRfVElNRSkgKyA2MDAgPiB0aW1lKCkpIHsKKyAgICB3cml0ZShicmVha19zdHJpbmcoCisgICAgICAiSW0gS2FtcGYgb2RlciBrdXJ6IG5hY2ggZWluZW0gS2FtcGYga2FubnN0IER1IG5pY2h0IHp3aXNjaGVuICIKKyAgICAgICJhbHRlciB1bmQgbmV1ZXIgU3BydWNoZXJtdWVkdW5nIHVtc2NoYWx0ZW4uXG4iCisgICAgICAiTW9tZW50YW4gYmVudXR6dCBEdSBkaWUgIgorICAgICAgKyAoc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSA/ICJhbHRlICh1bmdlbmF1ZXJlKSIgOiAibmV1ZSAobm9ybWFsZSkiKQorICAgICAgKyAiIFNwcnVjaGVybXVlZHVuZy4iLDc4LDAsQlNfTEVBVkVfTVlfTEZTKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBpZiAoY21kPT0iYWx0IikgeworICAgIHNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGU9dGltZSgpOworICAgIHdyaXRlKGJyZWFrX3N0cmluZygKKyAgICAgICJBbHRlIFNwcnVjaGVybXVlZHVuZyB3dXJkZSBlaW5nZXNjaGFsdGV0LiBBbGxlIEVybXVlZHVuZ3NwYXVzZW4gIgorICAgICAgInp3aXNjaGVuIFNwcnVlY2hlbiB3ZXJkZW4gYXVmIFZpZWxmYWNoZSB2b24gMnMgYXVmZ2VydW5kZXQgdW5kICIKKyAgICAgICJiZWdpbm5lbiBpbiBkZXIgUmVnZWwgYW0gQW5mYW5nIERlaW5lciBLYW1wZnJ1bmRlLiIpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBlbHNlIGlmIChjbWQ9PSJuZXUiIHx8IGNtZD09Im5vcm1hbCIpIHsKKyAgICBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlPTA7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKAorICAgICAgIk5vcm1hbGUgU3BydWNoZXJtdWVkdW5nIHd1cmRlIGVpbmdlc2NoYWx0ZXQuIEFsbGUgRXJtdWVkdW5nc3BhdXNlbiAiCisgICAgICAiendpc2NoZW4gU3BydWVjaGVuIHdlcmRlbiBzZWt1bmRlbmdlbmF1IGJlcmVjaG5ldC4iKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBub3RpZnlfZmFpbChicmVha19zdHJpbmcoCisgICAgICAiTW9lY2h0ZXN0IER1IGRpZSBhbHRlIG9kZXIgZGllIG5ldWUgU3BydWNoZXJtdWVkdW5nP1xuIgorICAgICAgIk1vbWVudGFuIGJlbnV0enQgRHUgZGllICIKKyAgICAgICsgKHNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGUgPyAiYWx0ZSAodW5nZW5hdWVyZSkiIDogIm5ldWUgKG5vcm1hbGUpIikKKyAgICAgICsgIiBTcHJ1Y2hlcm11ZWR1bmcuIiw3OCwwLEJTX0xFQVZFX01ZX0xGUykpOworICByZXR1cm4gMDsKK30KKworLyoqIFNwZWljaGVydCBkaWUgWmVpdCBkZXMgbGV0enRlcyBIZWFydGJlYXRzLgorICovCitwcm90ZWN0ZWQgdm9pZCBoZWFydF9iZWF0KCkgeworICBpZiAoc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSkKKyAgICBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlID0gdGltZSgpOworfQorCitzdGF0aWMgaW50IF9zZXRfZ3VpbGRfbGV2ZWwoaW50IG51bSkKK3sgc3RyaW5nIGdpbGRlOworICBtYXBwaW5nIGxldmVsczsKKworICBpZiAoICEoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCAhbWFwcGluZ3AobGV2ZWxzPVF1ZXJ5KFBfR1VJTERfTEVWRUwpKSApCisgICAgbGV2ZWxzPShbXSk7CisKKyAgbGV2ZWxzW2dpbGRlXT1udW07CisgIFNldChQX0dVSUxEX0xFVkVMLGxldmVscyk7CisgIEdNQ1BfQ2hhciggKFtQX0dVSUxEX0xFVkVMOiBudW1dKSApOworCisgIHJldHVybiBudW07Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X2d1aWxkX2xldmVsKCkKK3sgc3RyaW5nICBnaWxkZTsKKyAgbWFwcGluZyBsZXZlbHM7CisKKyAgaWYgKCAhKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgKQorICAgIHJldHVybiAwOworCisgIGlmICggIW1hcHBpbmdwKGxldmVscz1RdWVyeShQX0dVSUxEX0xFVkVMKSkgKQorICAgICAgcmV0dXJuIDA7CisKKyAgcmV0dXJuIGxldmVsc1tnaWxkZV07Cit9CisKK3N0YXRpYyBzdHJpbmcgX3NldF9ndWlsZF90aXRsZShzdHJpbmcgdCkKK3sgc3RyaW5nIGdpbGRlOworICBtYXBwaW5nIHRpdGxlczsKKworICBpZiAoICEoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCAhbWFwcGluZ3AodGl0bGVzPVF1ZXJ5KFBfR1VJTERfVElUTEUpKSApCisgICAgdGl0bGVzPShbXSk7CisKKyAgdGl0bGVzW2dpbGRlXT10OworICBTZXQoUF9HVUlMRF9USVRMRSx0aXRsZXMpOworICBHTUNQX0NoYXIoIChbUF9HVUlMRF9USVRMRTogdF0pICk7CisgIHJldHVybiB0OworfQorCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9ndWlsZF90aXRsZSgpCit7IHN0cmluZyBnaWxkZSx0OworICBvYmplY3QgZzsKKyAgbWFwcGluZyB0aXRsZXM7CisKKyAgaWYgKCAhKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgKQorICAgIHJldHVybiAwOworCisgIGlmICggIW1hcHBpbmdwKHRpdGxlcz1RdWVyeShQX0dVSUxEX1RJVExFKSkgKQorICAgIHRpdGxlcz0oW10pOworCisgIHQ9dGl0bGVzW2dpbGRlXTsKKyAgaWYgKCAhdCAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpCisgICAgICAmJiBvYmplY3RwKGc9ZmluZF9vYmplY3QoIi9naWxkZW4vIitnaWxkZSkpICkKKyAgeworICAgIGctPmFkanVzdF90aXRsZSh0aGlzX29iamVjdCgpKTsKKyAgICBTZXRQcm9wKFBfVElUTEUsMCk7CisKKyAgICBpZiAoICFtYXBwaW5ncCh0aXRsZXM9UXVlcnkoUF9HVUlMRF9USVRMRSkpICkKKyAgICAgIHJldHVybiAwOworCisgICAgdD10aXRsZXNbZ2lsZGVdOworICB9CisKKyAgcmV0dXJuIHQ7Cit9CisKKworc3RhdGljIHN0cmluZyBfc2V0X2d1aWxkKHN0cmluZyBnaWxkZW5uYW1lKQoreyBvYmplY3QgcHJlOworCisgIGlmICghb2JqZWN0cChwcmU9cHJldmlvdXNfb2JqZWN0KCkpKQorICAgIHJldHVybiAwOworCisgIGlmICggcHJlIT10aGlzX29iamVjdCgpIC8vIERhcyBMZWJld2VzZW4gc2VsYmVyIGRhcmYgZGllIEdpbGRlIHNldHplbiwKKyAgICAgICYmIG9iamVjdF9uYW1lKHByZSkhPUdVSUxETUFTVEVSICAvLyBkZXIgR2lsZGVubWFzdGVyIGF1Y2gKKyAgICAgICYmICghdGhpc19wbGF5ZXIoKQorICAgICAgICAgIHx8IHRoaXNfcGxheWVyKCkgIT0gdGhpc19pbnRlcmFjdGl2ZSgpCisgICAgICAgICAgfHwgIUlTX0FSQ0godGhpc19wbGF5ZXIoKSkKKyAgICAgICAgICkKKyAgICAgICkKKyAgICByZXR1cm4gMDsKKworICBTZXQoUF9HVUlMRCxnaWxkZW5uYW1lKTsKKyAgR01DUF9DaGFyKCAoW1BfR1VJTEQ6IGdpbGRlbm5hbWVdKSApOworICByZXR1cm4gZ2lsZGVubmFtZTsKK30KKworc3RhdGljIHN0cmluZyBfcXVlcnlfZ3VpbGQoKQoreyBzdHJpbmcgcmVzOworCisgIGlmICggIShyZXM9UXVlcnkoUF9HVUlMRCkpICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkgKQorICB7CisgICAgLy8gU3BpZWxlciwgZGllIGtlaW5lciBHaWxkZSBhbmdlaG9lcmVuLCBnZWhvZXJlbiB6dXIgQWJlbnRldXJlcmdpbGRlCisgICAgaWYgKCAhKHJlcz1RdWVyeVByb3AoUF9ERUZBVUxUX0dVSUxEKSkgKQorICAgICAgcmV0dXJuIERFRkFVTFRfR1VJTEQ7CisgICAgZWxzZQorICAgICAgU2V0KFBfR1VJTEQscmVzKTsKKyAgICByZXR1cm4gcmVzOworICB9CisKKyAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIHN0cmluZyBfcXVlcnlfdGl0bGUoKQoreyBzdHJpbmcgdGk7CisKKyAgaWYgKCBzdHJpbmdwKHRpPVF1ZXJ5KFBfVElUTEUpKSApCisgICAgcmV0dXJuIHRpOworCisgIHJldHVybiBRdWVyeVByb3AoUF9HVUlMRF9USVRMRSk7Cit9CisKK3N0YXRpYyBzdHJpbmcgX3NldF90aXRsZShzdHJpbmcgdCkKK3sKKyAgU2V0KFBfVElUTEUsIHQsIEZfVkFMVUUpOworICBHTUNQX0NoYXIoIChbUF9USVRMRTogdF0pICk7CisgIHJldHVybiB0OworfQorCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL3NvdWwuYyBiL3N0ZC9wbGF5ZXIvc291bC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQzOGYyYzYKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL3NvdWwuYwpAQCAtMCwwICsxLDMyMTggQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBwbGF5ZXIvc291bC5jIC0tIERpZSBTZWVsZSBkZXMgU3BpZWxlcnMKKy8vCisvLyAkSWQ6IHNvdWwuYyA5NTI3IDIwMTYtMDMtMTIgMTE6Mzc6NTRaIEFyYXRob3JuICQKKworLy8gTGV0enRlIEFlbmRlcnVuZyB2b20gMDguMDkuOTUgIFdhcmdvbgorCisvLyBTZXQgVGFiU3RvcCB0byAyIGNoYXJhY3RlcnMKKworLyogVmVyc2lvbiAxLjQxIE1HLCBTZXB0ZW1iZXIgOTUKKyAgIC0gQmVpICJmcmFnZSIgdW5kICJhbnR3b3J0ZSIgVGVzdCBhdWYgUF9QRVJNX1NUUklORyBmdWVyIFNwcmFjaGZsdWVjaGUuCisgICAtIGJ1Z2ZpeCBiZWkgInNjaHdlaWdlIiAobmFobSBrZWluZSBBZHZlcmJpZW4gYW4pCisgICAqLworCisvKiBWZXJzaW9uIDEuNCBNRywgQXVndXN0IDk1CisgICAtIEhpbGZlZnVua3Rpb24gZWluZ2ViYXV0LCBzaWVoZSBhdWNoIHNvdWxoZWxwLmMKKyAgIC0gZWluaWdlIGtsZWluZXJlIEFlbmRlcnVuZ2VuIGVyc3QgamV0enQgZHVyY2ggZWluZSBuZXVlIFZlcnNpb24gZ2V3dWVyZGlndAorICAgLSBuZXVlIFZlcmJlbiwgd2llIGVpZ2VudGxpY2ggZmFzdCBpbW1lciA6PgorICAgLSB0eXBvcyB1bmQgYnVncyBnZWZpeGVkICh1bmQgbmV1ZSBlaW5nZWJhdXQuLi4pCisgICAtIEZ1bmt0aW9uIHp1ciBBYmZyYWdlIHZvbiBBZHZlcmJpZW4gdm9uIGF1c3NlbiBlaW5nZWJhdXQgKEhhbGxvLCBBbnRoZWEgOj4pCisgICAtIHNvIHNjaGxpbW0ga2FubiBkYXMgZG9jaCBuaWNodCBzZWluLCBlaW5lbiBUYWJTdG9wIHZvbiAyIHp1IG5laG1lbiwgZnVlcgorICAgICBkaWVzZXMgZWluZSBmaWxlLCBhbGxlcyBhbmRlcmUgemVybGVndCBtZWluZSBGb3JtYXRpZXJ1bmcgaW1tZXIgc28gOjwKKyAgIC0ga29lbm50ZXQgaWhyIGJpdHRlIG1hbCBvYmVuIGRhcyAiTGV0enRlIEFlbmRlcnVuZyIgYWVuZGVybiwgd2VubiBpaHIKKyAgICAgaXJnZW5kd28gd2FzIGFlbmRlcnQ/CisgICAqLworCisvKiBWZXJzaW9uIDEuMzUgTUcsIERlemVtYmVyIDk0CisgICAtIFZlcmJlbgorICAgLSBBZW5kZXJ1bmcgZGVzIFBhcnNpbmdzIGRlciBxdW90ZWQgYWR2ZXJicworICAgLSBya251ZGRlbCBpZ25vcmllcmVuIHdpcmQgdm9tIG5vcm1hbGVuIGlnbm9yZSB1ZWJlcm5vbW1lbgorICAgKi8KKworLyogVmVyc2lvbiAxLjMyIE1HLCBKdWxpIDk0CisgICAtIGVpbmlnZSBWZXJiZW4KKyAgIC0gaWdub3JpZXJlbiBkZXMgcmtudWRkZWwKKyAgICovCisKKy8qIFZlcnNpb24gMS4zMSBNRywgTWFpIDk0CisgICAtIGVpbmlnZSBWZXJiZW4KKyAgICovCisKKy8qIFZlcnNpb24gMS4zIE1HLCBNYWkgOTQKKyAgIC0gcXVvdGVkIGFkdmVyYnMgR0VIRU4gamV0enQKKyAgIC0gUGFyc2VSZXN0IC8gUGFyc2VSZW1vdGUgbmV1IGdlc2NocmllYmVuCisgICAqLworCisvKiBWZXJzaW9uIDEuMjEgTUcsIEFwcmlsIDk0CisgICAtIHF1b3RlZCBhZHZlcmJzCisgICAqLworCisvKiBEYW5rZSBhbiBBbmd1cyBmdWVyIGRlbiBUZXh0IHZvbiAibGllYmUiICovCisKKy8qIFZlcnNpb24gMS4yIE1HLCBKYW51YXIgOTQKKyAgIC0gVW1zdGVsbHVuZyBkZXIgRmVlbGluZ3Mgdm9uIHZpZWxlbiBrbGVpbmVuIEZ1bmt0aW9uZW4gYXVmIGVpbmUgZ3Jvc3NlLAorICAgICBkYW1pdCBkZXIgRnVua3Rpb25zb3ZlcmhlYWQgd2VnZmFlbGx0LgorICAgLSBuZXVlIEF1c2dhYmUgZGVyIEFkdmVyYmllbiwgbWl0IG1vcmUgdW5kIG51ciBub2NoIGVpbmVzIHBybyBaZWlsZQorICAgLSBtYWwgd2llZGVyIG5ldWUgVmVyYmVuLgorICAgLSB1bmQgZGFzIG5ldWUgU3RhbmRhcmRhZHZlcmIgImpvZmkiIDopCisgICAqLworCisvKiBWZXJzaW9uIDEuMSBNRywgTm92ZW1iZXIgOTMKKyAgIEFlbmRlcnVuZ2VuOgorICAgLSBJY2ggaGFiZSAiYWxsZShuKSIgZWluZ2ViYXV0LiBEaWUgVmVyd2FsdHVuZyBzdGVodCwgbWFuIGthbm4gamV0enQKKyAgICAgVmVyYmVuIGRpZSBNb2VnbGljaGtlaXQgImFsbGUiIGdlYmVuIChCc3AuICJ3aW5rIGFsbGUiKS4KKyAgIC0gaW56d2lzY2hlbiB3aWVkZXIgZWluaWdlIFZlcmJlbiBtZWhyLCBhYmVyIG11c3MgaWNoIGRhcyBub2NoCisgICAgIGVyd2FlaG5lbj8KKyAgIC0gKEhBU1MpIFJ1bWF0YSBoYXQgbWVpbiBzY2hvZW5lcyBTeXN0ZW0gZnVlciBkaWUgQXVzZ2FiZXN0cmluZ3MKKyAgICAgdmVya29tcGxpemllcnQuIFN0YXR0ICZhIHN0ZWh0IGRhIGpldHp0IHouQi4gQEBhZHZlcmJAQCwgd2FzIGluCisgICAgIGVpbmVyIHdlaXRlcmVuIHVubm9ldGlnZW4gRnVua3Rpb24gcmVzdWx0aWVydGUuIE5hamEuCisgICBIaWdobGFuZGVyIHJ5biBUYWhhcgorICAgKi8KKworLyoKKyAgIEhhISBJY2ggbmVobWUgamV0enQgZGllIGVyc3RlIGdhbnplIFZlcnNpb25zbnVtbWVyIGZ1ZXIgbWljaCBpbiBBbnNwcnVjaCA6KQorICAgU28sIGhldXRlIGlzdCdzIGdlc2NoYWZmdCAoSWNoIGF1Y2guLi4pLiBJY2ggYmluIGZlcnRpZyAtIGljaCBtYWNoIG51cgorICAgbm9jaCBuZXVlIFZlcmJlbiByZWluLCB3ZW5uIElkZWVuIGtvbW1lbi4KKyAgIEdlZ2ViZW4gYW4gRGllbnN0YWcsIGRlbSAyMi4gSnVuaSAxOTkzIGltIGhlaW1hdGxpY2hlbiBIb3JzdC4KKyAgIEhpZ2hsYW5kZXIgcnluIFRhaGFyLgorICAgUC5TLjogS29waWVyZSBzaWNoIGRhcyBEaW5nLCB3ZXIgd2lsbCAtIHVudGVyIGZvbGdlbmRlbiBCZWRpbmd1bmdlbjoKKyAgIC0gRGVuIEdvZXR0ZXJuIHZvbiBNb3JnZW5HcmF1ZW4gdW5kCisgICAtIEhpZ2hsYW5kZXJAVEFQUE11ZCAgICAgQmVzY2hlaWQgc2FnZW4gdW5kIGF1c3NlcmRlbQorICAgKnNldWZ6KiBuZWhtdCBIaWdobGFuZGVyIGhpZXIgaW4gTW9yZ2VuR3JhdWVuISEgLUhyVAorICAgSGEhIElociBrb2VubnQgd2llZGVyIFRBUFBNdWQgbmVobWVuIDo+ICBBYmVyIHNhZ3QncyBydWhpZyBpbiBNRy4gLUhyVAorICAgLSBlbnR3ZWRlciBkZW4gZ2FuemVuIFNjaHdhbGwgaGllciBkcmlubGFzc2VuIG9kZXIgbWljaCBtaXQgZWluZW0KKyAgIG5ldWVuIFRleHQgZXJ3YWVobmVuLgorICAgRGFzIEdhbnplIHVudGVyIGRlciBWb3JhdXNzZXR6dW5nLCBkYXNzIHVlYmVyaGF1cHQgbWFsIGplbWFuZCBlaW5lIGRldXRzY2hlCisgICBTZWVsZSBicmF1Y2h0IHVuZCBzaWUgbmljaHQgc2VsYmVyIHNjaHJlaWJlbiB3aWxsIDotKSAoZXJzcGFydHMgZXVjaCBsaWViZXIpCisgICBIaWdobGFuZGVyIHJ5biBUYWhhci4KKworICAgKipBcmJlaXQ6CisgICBFaW5iYXUgdm9uIEFkdmVyYmllbiwgYW5kZXJlIFJlYWt0aW9uZW4gYmVpIEdlaXN0ZXJuIGFscyAiV2llIGJpdHRlPyIsCisgICBlaW5pZ2UgbmV1ZSBWZXJiZW4sIGVpbmlnZSBhbHRlIFZlcmJlbiByYXVzZ2VzY2htaXNzZW4uCisgICBXZWlsIGVzIFByb2JsZW1lIG1pdCBkZW0gYXV0b2xvYWRpbmcgZGVyIHBsYXllcmFkdmVyYnMgZ2FiLCB3dXJkZQorICAgYXVzc2VyZGVtIGRpZSBzb3VsIHZvbSBPYmpla3QgenVtIGluaGVyaXRmaWxlIGZ1ZXIgZGllIHBsYXllcnNoZWxsLgorCisgICAqKklkZWVuICB6dW0gV2VpdGVybWFjaGVuOgorICAgLSAodmVyYikgYWxsZSwgei5CLiB0cml0dCBhbGxlICAgLS0gTW9lZ2xpY2hrZWl0IGVpbmdlYmF1dAorICAgLSBHZWlzdGVydmVyYmVuIG1pdCBBZHZlcmIKKworICAgVmVyc2lvbiAxLjAgZnVlciBNb3JnZW5HcmF1ZW4gICAgSGlnaGxhbmRlciBNYWkvSnVuaSA5MworICAgKi8KKworCisvKiBIaWVyIGlzdCBzaWUgbnVuLCBkaWUgREVVVFNDSEUgdmVyc2lvbiBkZXIgc291bCwKKyAgIHZpZWwgU3Bhc3MgZGFtaXQuCisgICBQb2lldGl4ICBNYWkgMTk5MgorICAgVmVycy46IDAuNCBmdWVyIEpSTXVkCisgICBQLlMuIGJpdHRlIG1lY2tlcnQgbmljaHQgZHJhbiBydW0gLCBzb25kZXJuIHZlcmJlc3NlcnQgdW5kCisgICBlcndlaXRlcnQgc2llLgorCisgICBPbHBwIE5vdmVtYmVyIDE5OTIKKyAgIFZlcnMuOiAwLjUgZnVlciBNb3JnZW5HcmF1ZW4KKworICAgSGUsIE9scHAsIHNjaHJlaWJ0IG1hbiBuaWNodCBkaWUgbmV1ZXN0ZSBBZW5kZXJ1bmcgVUVCRVIgZGllIGFsdGVuPworICAgKmdyaW5zKiwgSGlnaGxhbmRlcgorICAgKi8KKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKy8vI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIFNPVUxIRUxQICIvc3RkL3BsYXllci9zb3VsaGVscCIKKyNkZWZpbmUgTEYgIlxuIgorI2RlZmluZSBOT1RfU0VMRiAxCisjZGVmaW5lIE5PVF9ERUFEIDEKKworI2RlZmluZSBRUFAgUXVlcnlQb3NzUHJvbm91bgorI2RlZmluZSBSRVRVUk4gcmV0dXJuIF9ub3RpZnlfZmFpbAorI2RlZmluZSBSZXR1cm4gcmV0dXJuIDB8fF9ub3RpZnlfZmFpbCAgLy8gbmV0dGVyIFRyaWNrLCBtdXNzIGljaCBtaXIgbWVya2VuIC1IclQKKyNkZWZpbmUgR0hPU1RDSEVDSyhzZWwsb3RoLHZpYykgaWYgKGdob3N0KCkpIHsgIHdyaXRlKHNlbCk7IHNheShvdGgsd2hvfHxNRSk7XAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2aWMpIHdoby0+TWVzc2FnZSh2aWMpOyByZXR1cm4gMTsgIH0KKyNkZWZpbmUgSEVMUENIRUNLKHgpIGlmIChzdHIgJiYgKHN0cj09Ii1oIiB8fCBzdHI9PSItPyIgfHwgc3RyPT0iL2giIFwKKyAgICAgICAgIHx8IHN0cj09Ii8/IiB8fCBzdHI9PSJoaWxmZSIpKVwKKyAgICAgICAgICAgICAgICAgICAgICAgeyBNb3JlKFNPVUxIRUxQLT5IZWxwKHgpKTsgcmV0dXJuIDE7IH0KKworLy8gInNjaGF1IGFuIiBhbHMgbmljaHQtVW50ZXJzdWNodW5nLiBLbGFwcHQgYWJlciBhbnNjaGVpbmVuZCBuaWNodCwgd2VpbAorLy8gaWNoIG5pY2h0IGdlZ2VuIGRlbiBHRCBhbmtvbW1lLiBBbHNvIGJlc3NlciBhdXNrb21tZW50aWVydCBsYXNzZW4uCisjaWZkZWYgU0NIQVVfQU4KKyN1bmRlZiBTQ0hBVV9BTgorI2VuZGlmCisKKy8vIEFucGllcHNlbiBtaXQgVGV4dC4gSW0gTW9tZW50IGVybGF1YnQsIGJlaSBNaXNzZmFsbGVuIGF1c2tvbW1lbnRpZXJlbiB1bmQKKy8vIGluIGRlciBIaWxmZSBhdXNrb21tZW50aWVyZW4uCisjaWZkZWYgV0VDS0UKKyN1bmRlZiBXRUNLRQorI2VuZGlmCisKKyNkZWZpbmUgV0VDS0UKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvY29tbS5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisKKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8Y2xhc3MuaD4KKworc3RhdGljIG9iamVjdCB3aG8sIG9mb287CitzdGF0aWMgaW50IGZvcl9hbGwsIGZsYWcsIGlmb287CittYXBwaW5nIHBscl9hZHZlcmJzOworc3RhdGljIHN0cmluZyBvdXRfc2VsLCBvdXRfdmljLCBvdXRfb3RoLCBhZHZlcmIsIHNmb287CisKK3ByaXZhdGUgdm9pZCBQYXJzZUFkdmVyYihzdHJpbmcgKndvcmRzKTsKK3ByaXZhdGUgc3RyaW5nIGNvbnZlcnRfc3RyaW5nKHN0cmluZyBzdHIpOwordmFyYXJncyBtaXhlZCBNb3JlKHN0cmluZyBzdHIsIGludCBmZmxhZywgc3RyaW5nIHJldHVybnRvKTsKK3N0cmluZyBNYXRjaEFkdmVyYihzdHJpbmcgc3RyKTsKKworbWFwcGluZworUXVlcnlTdGRBZHZlcmJzKCkgIHsKKyAgcmV0dXJuIChbCisgICAgInVudmUiIDogInVudmVyc2NoYWVtdCIsCisgICAgImd1dGciIDogImd1dGdlbGF1bnQiLAorICAgICJndXRtIiA6ICJndXRtdWV0aWciLAorICAgICJmcm9oIiA6ICJmcm9oIiwKKyAgICAiZ2x1ZSIgOiAiZ2x1ZWNrbGljaCIsCisgICAgInd1ZXQiIDogInd1ZXRlbmQiLAorICAgICJmcmVjIiA6ICJmcmVjaCIsCisgICAgImRhZW0iIDogImRhZW1vbmlzY2giLAorICAgICJib2VzIiA6ICJib2VzZSIsCisgICAgInVuZ2wiIDogInVuZ2x1ZWNrbGljaCIsCisgICAgImxhbmciIDogImxhbmdzYW0iLAorICAgICJzY2huIiA6ICJzY2huZWxsIiwKKyAgICAiamFtbSIgOiAiamFtbWVybmQiLAorICAgICJmcmV1IiA6ICJmcmV1bmRsaWNoIiwKKyAgICAic2h1ZSIgOiAic2NodWVjaHRlcm4iLAorICAgICJhbXVlIiA6ICJhbXVlc2llcnQiLAorICAgICJhZXJnIiA6ICJhZXJnZXJsaWNoIiwKKyAgICAiYW5lciIgOiAiYW5lcmtlbm5lbmQiLAorICAgICJlcnN0IiA6ICJlcnN0YXVudCIsCisgICAgImJpdHQiIDogImJpdHRlciIsCisgICAgImJyZWkiIDogImJyZWl0IiwKKyAgICAidm9ycyIgOiAidm9yc2ljaHRpZyIsCisgICAgImNoYXIiIDogImNoYXJtYW50IiwKKyAgICAia2FsdCIgOiAia2FsdCIsCisgICAgInZlcmYiIDogInZlcmZ1ZWhyZXJpc2NoIiwKKyAgICAienVmciIgOiAienVmcmllZGVuIiwKKyAgICAidGllZiIgOiAidGllZiIsCisgICAgInZlcnoiIDogInZlcnp3ZWlmZWx0IiwKKyAgICAiZHJlYyIgOiAiZHJlY2tpZyIsCisgICAgInZlcnQiIDogInZlcnRyYWV1bXQiLAorICAgICJ1ZWJlIiA6ICJ1ZWJlcnpldWd0IiwKKyAgICAiZnJ1cyIgOiAiZnJ1c3RyaWVydCIsCisgICAgInN0cmEiIDogInN0cmFobGVuZCIsCisgICAgImhvZmYiIDogImhvZmZudW5nc3ZvbGwiLAorICAgICJ1bmdlIiA6ICJ1bmdlZHVsZGlnIiwKKyAgICAidW5zaSIgOiAidW5zaW5uaWdlcndlaXNlIiwKKyAgICAidW5zYyIgOiAidW5zY2h1bGRpZyIsCisgICAgInVud2kiIDogInVud2lzc2VuZCIsCisgICAgImlyb24iIDogImlyb25pc2NoIiwKKyAgICAid2lzcyIgOiAid2lzc2VuZCIsCisgICAgImdlbWEiIDogImdlbWFlY2hsaWNoIiwKKyAgICAic2VobiIgOiAic2VobnN1ZWNodGlnIiwKKyAgICAibGF1dCIgOiAibGF1dCIsCisgICAgImxpZWIiIDogImxpZWJldm9sbCIsCisgICAgImZyb2UiIDogImZyb2VobGljaCIsCisgICAgImRhbmsiIDogImRhbmtiYXIiLAorICAgICJuYXR1IiA6ICJuYXR1ZXJsaWNoIiwKKyAgICAiZ2VkdSIgOiAiZ2VkdWxkaWciLAorICAgICJwZXJmIiA6ICJwZXJmZWt0IiwKKyAgICAidmVycyIgOiAidmVyc3BpZWx0IiwKKyAgICAiaG9lZiIgOiAiaG9lZmxpY2giLAorICAgICJzdG9sIiA6ICJzdG9seiIsCisgICAgImZyYWciIDogImZyYWdlbmQiLAorICAgICJydXBwIiA6ICJydXBwaWciLAorICAgICJ0cmF1IiA6ICJ0cmF1cmlnIiwKKyAgICAidmVyYSIgOiAidmVyYWVjaHRsaWNoIiwKKyAgICAic2NoYSIgOiAic2NoYW1sb3MiLAorICAgICJlcm5zIiA6ICJlcm5zdCIsCisgICAgInNjaHUiIDogInNjaHVlY2h0ZXJuIiwKKyAgICAiemFlciIgOiAiemFlcnRsaWNoIiwKKyAgICAic2FuZiIgOiAic2FuZnQiLAorICAgICJlbnRnIiA6ICJlbnRnZWlzdGVydCIsCisgICAgImhlaW0iIDogImhlaW10dWVja2lzY2giLAorICAgICJnZWxhIiA6ICJnZWxhbmd3ZWlsdCIsCisgICAgIndpbGQiIDogIndpbGQiLAorICAgICJqb2ZpIiA6ICJ3aWUgSm9mLCB3ZW5uIGVyIG1hbCBuaWNodCBpZGxldCIsCisgIF0pOworfQorCittYXBwaW5nCitRdWVyeUFkdmVyYnMoKSB7CisgIGlmIChleHRlcm5fY2FsbCgpKQorICAgIHJldHVybiBkZWVwX2NvcHkocGxyX2FkdmVyYnMpOworICByZXR1cm4gcGxyX2FkdmVyYnM7Cit9CisKK3N0cmluZworTWF0Y2hBZHZlcmIoc3RyaW5nIGEpICB7CisgIFBhcnNlQWR2ZXJiKGV4cGxvZGUoYSwiICIpKTsKKyAgcmV0dXJuIGFkdmVyYjsKK30KKworLy8gVmVyd2FsdHVuZ3Nyb3V0aW5lbgorCitzdGF0aWMgdm9pZAorYWRkX3NvdWxfY29tbWFuZHMoKSAgeworICBpZiAoIXBscl9hZHZlcmJzKQorICAgIHBscl9hZHZlcmJzPShbXSk7CisgIGFkZF9hY3Rpb24oIlNvdWxDb21tIiwgIiIsIDEpOworfQorCitzdGF0aWMgaW50Cit2ZXJiZW5fbGlzdGUoKSAgeworICBNb3JlKFNPVUxIRUxQLT5IZWxwKCkpOworICByZXR1cm4gMTsKK30KKworI2RlZmluZSBnaG9zdCgpIFF1ZXJ5UHJvcChQX0dIT1NUKQorI2RlZmluZSBmcm9nKCkgUXVlcnlQcm9wKFBfRlJPRykKKyNkZWZpbmUgY2FwbmFtZSgpIGNhcGl0YWxpemUobmFtZSgpKQorI2RlZmluZSBnbmFtZSgpIChnaG9zdCgpPyhmcm9nKCk/IkRlciBHZWlzdCBlaW5lcyBGcm9zY2hlcyJcCisJCQkgICAgICAgIDoiRGVyIEdlaXN0IHZvbiAiK2NhcG5hbWUoKSlcCisJCSAgICAgICAgOmNhcG5hbWUoKSkKKwordmFyYXJncyBwcml2YXRlIHZvaWQKK1BhcnNlUmVzdChzdHJpbmcgYXJnLCBtaXhlZCBleHRyYSkgIHsKKyAgc3RyaW5nIHdlcix3aWUsKndvcmRzLHF1b3RlYTsKKyAgaW50IG51bSxiaXM7CisgIHdobyA9IGZvcl9hbGwgPSBhZHZlcmIgPSAwOworICBpZiAoIWFyZykgcmV0dXJuOworICBpZiAoZXh0cmEpCisgICAgaWYgKCFwb2ludGVycChleHRyYSkpIHsKKyAgICAgIGlmIChzc2NhbmYoYXJnLCBleHRyYSsiICVzIiwgd2llKT09MSkKKyAgICAgIGFyZz13aWU7CisgICAgfQorICAgIGVsc2UKKyAgICAgIGZvciAoYmlzPXNpemVvZihleHRyYSksbnVtPTA7IG51bTxiaXM7IG51bSsrKQorICAgICAgICBpZiAoc3NjYW5mKGFyZywgZXh0cmFbbnVtXSsiICVzIiwgd2llKT09MSkKKyAgICAgICAgICBhcmc9d2llOworCisgIGlmICgoYmlzPXN0cnN0cihhcmcsICIvIikpPj0wKQorICAgIHF1b3RlYT1hcmdbYmlzLi5dLGFyZz1hcmdbMC4uYmlzLTFdOworICBxdW90ZWE9cXVvdGVhfHwiIixhcmc9YXJnfHwiIjsKKworICB3b3Jkcz1leHBsb2RlKGltcGxvZGUoZXhwbG9kZShhcmcsICIsIiksICIgdW5kIiksICIgIik7CisgIGlmICghc2l6ZW9mKHdvcmRzKSkgcmV0dXJuOworICBpZiAoc2l6ZW9mKHdvcmRzKSAmJiAod29yZHNbMF09PSJhbGxlIiB8fCB3b3Jkc1swXT09ImFsbGVuIikpCisgICAgZm9yX2FsbD0xLHdlcj13b3Jkc1swXSx3b3Jkcz13b3Jkc1sxLi5dOworICBpZiAoIWZvcl9hbGwpICB7ICAgICAvKiBub2NoIGtlaW4gT3BmZXIgKi8KKyAgICB3ZXI9bWF0Y2hfbGl2aW5nKGxvd2VyX2Nhc2Uod29yZHNbMF0pKTsKKyAgICBpZiAoc3RyaW5ncCh3ZXIpKSB3aG89cHJlc2VudCh3ZXIsIGVudmlyb25tZW50KE1FKSk7CisgICAgaWYgKCF3aG8pIHdobz1wcmVzZW50KHdvcmRzWzBdLCBlbnZpcm9ubWVudChNRSkpOworICAgIGlmICh3aG8gJiYgd2hvLT5RdWVyeVByb3AoUF9JTlZJUykpIHdobz0wOworICAgIH0KKyAgaWYgKHdobyAmJiBzaXplb2Yod29yZHMpKQorICAgIHdvcmRzPXdvcmRzWzEuLl07ICAvKiBPcGZlciBnZWZ1bmRlbiAtIHdlbm4ncyBlaW5lcyBnaWJ0ICovCisgIHdvcmRzKz1leHBsb2RlKHF1b3RlYSwgIiAiKTsKKyAgd29yZHMtPSh7IiJ9KTsKKyAgaWYgKHNpemVvZih3b3JkcykpIFBhcnNlQWR2ZXJiKHdvcmRzKTsKK30KKworcHJpdmF0ZSBpbnQKK1BhcnNlUmVtb3RlKHN0cmluZyBhcmcpICB7CisgIHN0cmluZyB3ZXIsKndvcmRzOyAKKworICBhZHZlcmIgPSAwOyAvLyBBZHZlcmIgdm9tIGxldHp0ZW4gTWFsIGtlaW5lc2ZhbGxzIHdpZWRlcnZlcndlbmRlbi4gOy0pCisKKyAgaWYgKCFzdHJpbmdwKGFyZykgfHwgIXNpemVvZihhcmcpKSByZXR1cm4gMDsKKyAgCisgIHdvcmRzPWV4cGxvZGUoYXJnLCIgIik7CisKKyAgbWl4ZWQgbGl2ID0gbWF0Y2hfbGl2aW5nKGxvd2VyX2Nhc2Uod29yZHNbMF0pKTsKKyAgaWYgKHN0cmluZ3AobGl2KSkKKyAgICAgIHdobz1maW5kX3BsYXllcihsaXYpOworICAKKyAgaWYgKHdobykgeworICAgIC8vIFppZWwgaXN0IGVpbiBTcGllbGVyLgorICAgIGlmICghd2hvLT5RdWVyeVByb3AoUF9JTlZJUykgfHwgSVNfV0laQVJEKE1FKSkKKyAgICB7CisgICAgICAvLyBTcGllbGVyIGlzdCBuaWNodCBJbnZpcyBvZGVyIGljaCBiaW4gTWFnaWVyLgorICAgICAgc3RyaW5nIG5hbSA9IChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSA/IGdldHVpZCgpIDogCisJICAgICAgICAgICAgIGxvd2VyX2Nhc2UobmFtZShSQVcpKSk7CisgICAgICBpZiAocXVlcnlfdmVyYigpWzAuLjVdPT0icmtudWRkIiAmJgorCSAgd2hvLT5UZXN0SWdub3JlKG5hbSsiLnJrbnVkZGVsIikgKQorICAgICAgeworICAgICAgICAvLyBpY2ggb2RlciBkYXMgS29tbWFuZG8gd2VyZGUgaWdub3JpZXJ0LgorICAgICAgICB3cml0ZSh3aG8tPk5hbWUoV0VSKSsiIGlnbm9yaWVydCBEZWluZW4gS251ZGRlbHZlcnN1Y2guXG4iKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgfQorICAgIGVsc2UKKyAgICAgIC8vIFNwaWVsZXIgaXN0IGludmlzIHVuZCBpY2ggYmluIGtlaW4gTWFnaWVyLgorICAgICAgd2hvID0gMDsKKyAgfQorICAvLyBrZWluIGVpbmdlbG9nZ3RlciB1bmQgc2ljaHRiYXJlciBTcGllbGVyLiBWaWVsbGVpY2h0IGVpbiBOUEM/IChCVFc6IGtlaW4KKyAgLy8gZWxzZSBpZiwgd2VpbCBpbSBpZiBmdWVyIFNwaWVsZXIgb2JlbiB3aG8gZ2VudWxsdCB3ZXJkZW4ga2FubiB1bmQgZGFubgorICAvLyBub2NobWFsIG5hY2ggbmVtIE5QQyBnZXN1Y2h0IHdlcmRlbiBzb2xsLikKKyAgaWYgKCF3aG8pIHsKKyAgICB3ZXIgPSBtYXRjaF9saXZpbmcobG93ZXJfY2FzZSh3b3Jkc1swXSkpOworICAgIGlmKHN0cmluZ3Aod2VyKSkgCisgICAgICB3aG89cHJlc2VudCh3ZXIsZW52aXJvbm1lbnQoTUUpKTsKKyAgICBpZiAoIXdobykgd2hvPXByZXNlbnQod29yZHNbMF0sIGVudmlyb25tZW50KE1FKSk7CisgICAgaWYgKHdobyAmJiB3aG8tPlF1ZXJ5UHJvcChQX0lOVklTKSkgd2hvPTA7CisgIH0KKworICBpZiAoIXdobyB8fCBzaXplb2Yod29yZHMpPT0xKSByZXR1cm4gMDsKKyAgd29yZHM9d29yZHNbMS4uXTsKKyAgUGFyc2VBZHZlcmIod29yZHMpOworICByZXR1cm4oMCk7Cit9CisKKy8qKgorIEdpYnQgZGVuIHBhc3NlbmRlbiBBZHZlcmItVGV4dCB6dSBlaW5lbSBrZXkgenVydWVjaworIFxwYXJhbSBzIERhbmFjaCB3aXJkIGluIGRlciBBZHZlcmJpZW4tTGlzdGUgZ2VzdWNodAorIFxwYXJhbSBmdXp6eSAKKyBccmV0dXJuIERlciBnZWZ1bmRlbmUgQWR2ZXJiaWVudGV4dCBvZGVyIDAKKyAqLwordmFyYXJncyBzdHJpbmcgR2V0UGxheWVyQWR2ZXJiKCBzdHJpbmcgcywgaW50IGZ1enp5ICkgeworICBpbnQgaSwgajsgCisgIHN0cmluZyAqc2VhcmNoX3BhdHRlcm4sCisgICAgICAgICAqc2VhcmNoX3Jlc3VsdCwgCisgICAgICAgICAgcmVzdWx0OworCisgIC8vIEVyc3RtYWwgZ3Vja2VuLCBvYiBkZXIgU3RyaW5nIGRpcmVrdCBnZWZ1bmRlbiB3ZXJkZW4ga2FubgorICAvLyBkYXMgZ2VodCBhbSBzY2huZWxsc3RlbgorICByZXN1bHQgPSBRdWVyeVN0ZEFkdmVyYnMoKVtzXSB8fCBwbHJfYWR2ZXJic1tzXTsKKworICAvLyBXZW5uIG5vY2gga2VpbiBFcmdlYm5pcyBnZWZ1bmRlbiwgdW5kIG1hbiB1bnNjaGFyZiBzdWNoZW4gd2lsbAorICBpZiAoIGZ1enp5ICYmICFyZXN1bHQpIHsKKworICAgIC8vIFN1Y2htdXN0ZXIgZnVlciBkYXMgSW50ZXJzZWN0IGVyemV1Z2VuCisgICAgc2VhcmNoX3BhdHRlcm49KHtzfSk7CisKKyAgICBqID0gc2l6ZW9mKHMpLTE7CisgICAgZm9yICggaT0yOyAgaSA8IGogO2krKykgeworICAgICAgc2VhcmNoX3BhdHRlcm4gKz0gKHtzWzAuLjxpXX0pOworICAgIH0KKworICAgIC8vIEludGVyc2VjdCB6d2lzY2hlbiBhbGxlbiBiZWthbm50ZW4gQWJrdWVyenVuZ2VuIHVuZCBTZWFyY2gtUGF0dGVybgorICAgIC8vIGVyemV1Z2VuLiBEaWVzZXMgd2lyZCBkYW5uIGdsZWljaHplaXRpZyBuYWNoIExhZW5nZSBzb3J0aWVydAorICAgIC8vIGdlbmF1ZXN0ZXIgVHJlZmZlciA9IFN0cmluZyBtaXQgZ3JvZXNzdGVyIExhZW5nZQorICAgIHNlYXJjaF9yZXN1bHQgPSBzb3J0X2FycmF5KAorICAgICAgKG1faW5kaWNlcyhRdWVyeVN0ZEFkdmVyYnMoKSkgfCBtX2luZGljZXMocGxyX2FkdmVyYnMpKSZzZWFyY2hfcGF0dGVybiwgCisgICAgICAgICAjJz4pOworCisgICAgLy8gQWR2ZXJiIHp1bSBnZW5hdWVzdGVuIFRyZWZmZXIgenVydWVja2dlYmVuCisgICAgaWYgKHNpemVvZihzZWFyY2hfcmVzdWx0KSkgCisgICAgICByZXN1bHQgPSBRdWVyeVN0ZEFkdmVyYnMoKVtzZWFyY2hfcmVzdWx0WzBdXSB8fCAKKyAgICAgICAgICAgICAgIHBscl9hZHZlcmJzW3NlYXJjaF9yZXN1bHRbMF1dOworICB9CisKKyAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoqCisgIFBhcnN0IGRpZSBBZHZlcmJpZW5wYXJhbWV0ZXIgZnVlciBWZXJiZW4gdW5kIHNwZWljaGVydCBkaWUKKyAgcGFzc2VuZGUgVGV4dGF1c2dhYmUgaW4gZGVyIGdsb2JhbGVuIFZhcmlhYmxlICJhZHZlcmIiCisgIFxwYXJhbSB3b3JkcyBBcnJheSBtaXQgZGVuIHp1IHBhcnNlbmRlbiBBZHZlcmJpZW4tU3RyaW5ncworKi8KK3ByaXZhdGUgdm9pZAorUGFyc2VBZHZlcmIoc3RyaW5nICp3b3JkcykgIHsKKyAgaW50IG51bSxhbmRzaWduLGJpczsKKyAgc3RyaW5nIHFhZHYsKmFkdixjbnQ7CisKKyAgYWR2PSh7fSk7CisgIHFhZHY9MDsKKworICBiaXM9c2l6ZW9mKHdvcmRzKTsKKyAgLy8gU29uZGVyZmFsbCBHZXF1b3RldGVzIEFkdmVyYiAoYWxsZXMgbmFjaCBkZW0gUXVvdGUpIHNwZWljaGVybiB1bmQgYXVzIAorICAvLyBXb3JkcyByYXVzc2NobmVpZGVuLgorICBmb3IgKG51bT0wOyBudW08YmlzOyBudW0rKykKKyAgICBpZiAod29yZHNbbnVtXVswLi4wXT09Ii8iKSAgeworICAgICAgd29yZHNbbnVtXT13b3Jkc1tudW1dWzEuLl07CisgICAgICBxYWR2PWltcGxvZGUod29yZHNbbnVtLi5dLCAiICIpOworICAgICAgd29yZHM9d29yZHNbMC4ubnVtLTFdOworICAgICAgYnJlYWs7CisgICAgfQorCisgIC8vIEVzIGthbm4gc2VpbiwgZGFzcyB2b3IgZGVtIFF1b3RlIG5vY2ggZWluZSB1bmQgc3RlaHQuIERhcyB3aXJkIGpldHp0IGF1Y2ggCisgIC8vIG5vY2ggZW50ZmVybnQsIG11c3MgYWJlciBzcGFldGVyIHdpZWRlciBlaW5nZWZ1ZWd0IHdlcmRlbi4KKyAgaWYgKHNpemVvZih3b3JkcykgJiYgd29yZHNbPDFdPT0idW5kIikgIHsKKyAgICB3b3Jkcz13b3Jkc1swLi48Ml07CisgICAgYW5kc2lnbj0xOworICB9CisKKyAgLy8gV2VpdGVyc3VjaGVuPworICBpZiAoYmlzPXNpemVvZih3b3JkcykpCisgICAgZm9yIChudW09MDsgbnVtPGJpczsgbnVtKz0yKQorICAgICAgIGFkdis9KHtHZXRQbGF5ZXJBZHZlcmIod29yZHNbbnVtXSwgMSl9KTsKKyAgY250PUNvdW50VXAoYWR2LSh7MH0pKTsKKworICAvLyBBdXNnYWJlIHp1c2FtbWVuYmF1ZW4KKyAgaWYgKGFuZHNpZ24pCisgICAgYWR2ZXJiPUNvdW50VXAoKHNpemVvZihhZHYpID8gYWR2IDogKHt9KSkrKHFhZHYgPyAoe3FhZHZ9KSA6ICh7fSkpKTsKKyAgZWxzZSBpZiAoc2l6ZW9mKGNudCkgJiYgc2l6ZW9mKHFhZHYpKQorICAgIGFkdmVyYiA9IGNudCArICIgIiArIHFhZHY7CisgIGVsc2UgaWYgKHNpemVvZihxYWR2KSkKKyAgICBhZHZlcmIgPSBxYWR2OworICBlbHNlIGlmIChzaXplb2YoY250KSkKKyAgICBhZHZlcmIgPSBjbnQ7IAorICBpZiAoYWR2ZXJiPT0iIikgYWR2ZXJiPTA7Cit9CisKK3ByaXZhdGUgbWl4ZWQgTWl4ZWRPdXQoaW50IGNhc3VzKSAgeworICBvYmplY3QgKmVudnMsKnZpY3M7CisgIHN0cmluZyAqbmFtZXMsb3V0LGF1Zno7CisgIGludCBjb3VudCxtc2c7CisKKyAgZm9yX2FsbD0wOworICB2aWNzPSh7fSk7CisgIG5hbWVzPSh7fSk7CisgIGVudnM9YWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKS0oe3RoaXNfcGxheWVyKCl9KTsKKyAgaWYgKCEoY291bnQ9c2l6ZW9mKGVudnMpKSkKKyAgICBSRVRVUk4oIk5pY2h0cyB1bmQgbmllbWFuZCBkYS4gU2NoYXUgRGljaCBuYWVjaHN0ZXMgTWFsIGJlc3NlciB1bS5cbiIpOworICBmb3IgKCA7IGNvdW50LS07ICkKKyAgICBpZiAobGl2aW5nKGVudnNbY291bnRdKSAmJiAhZW52c1tjb3VudF0tPlF1ZXJ5UHJvcChQX0lOVklTKSkgIHsKKyAgICAgIHZpY3MrPSh7ZW52c1tjb3VudF19KTsKKyAgICAgIG5hbWVzKz0oe2VudnNbY291bnRdLT5uYW1lKGNhc3VzKX0pOworICAgIH0KKyAgaWYgKCFzaXplb2YodmljcykpCisgICAgUkVUVVJOKCJLZWluZXIgZGEuIFNjaGF1IERpY2ggbmFlY2hzdGVzIE1hbCBiZXNzZXIgdW0uXG4iKTsKKyAgYXVmej1Db3VudFVwKG5hbWVzKTsKKyAgZm9yIChjb3VudD1zaXplb2Yodmljcyk7IGNvdW50LS07KQorICB7CisgICAgb3V0PWltcGxvZGUoZXhwbG9kZShvdXRfdmljLCAiQEBhbGxlQEAiKSxhdWZ6KTsKKyAgICAgICAgb3V0ID0gcmVncmVwbGFjZSggb3V0LCAiXFw8Iit2aWNzW2NvdW50XS0+bmFtZShjYXN1cykrIlxcPiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUodmljc1tjb3VudF0tPlF1ZXJ5RHUoY2FzdXMpKSwgMCApOworCisgICAgbXNnPXZpY3NbY291bnRdLT5SZWNlaXZlTXNnKGNvbnZlcnRfc3RyaW5nKG91dCksTVRfQ09NTSxNQV9FTU9URSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCx0aGlzX29iamVjdCgpKTsKKyAgICBzd2l0Y2gobXNnKQorICAgIHsKKyAgICAgIGNhc2UgTVNHX0RFTElWRVJFRDoKKyAgICAgIGNhc2UgTVNHX0JVRkZFUkVEOgorICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgTVNHX0lHTk9SRUQ6CisgICAgICBjYXNlIE1TR19WRVJCX0lHTjoKKyAgICAgIGNhc2UgTVNHX01VRF9JR046CisgICAgICAgIHdyaXRlKHZpY3NbY291bnRdLT5OYW1lKCkrIiBpZ25vcmllcnQgRGljaCBvZGVyIGRpZXNlbiBCZWZlaGwuXG4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBkZWZhdWx0OgorICAgICAgICB3cml0ZSh2aWNzW2NvdW50XS0+TmFtZSgpKyIga29ubnRlIERpY2ggZ2VyYWRlIG5pY2h0IGxlc2VuLlxuIik7CisgICAgfQorICB9CisgIHdyaXRlKGJyZWFrX3N0cmluZyhjb252ZXJ0X3N0cmluZyhpbXBsb2RlKGV4cGxvZGUob3V0X3NlbCwiQEBhbGxlQEAiKSxhdWZ6KQorICAgICtMRiksIDc4KSk7CisgIHJldHVybiAxOworfQorCit2YXJhcmdzIHByaXZhdGUgaW50CitDaGVja0xpZmUoaW50IG5vX3NlbGYsaW50IG5vX2RlYWQsIHN0cmluZyBub19zZWxmX3RleHQsIHN0cmluZyBub19kZWFkX3RleHQpICB7CisgIGlmICh3aG8gJiYgbGl2aW5nKHdobykgJiYgd2hvIT10aGlzX3BsYXllcigpKSByZXR1cm4gMDsKKyAgaWYgKG5vX3NlbGYgJiYgd2hvICYmIHdobz09dGhpc19wbGF5ZXIoKSkgIHsKKyAgICBpZiAobm9fc2VsZl90ZXh0KQorICAgICAgd3JpdGUobm9fc2VsZl90ZXh0K0xGKTsKKyAgICBlbHNlCisgICAgICB3cml0ZSgiTWFjaCBkYXMgbWl0IGFuZGVyZW4sIG5pY2h0IG1pdCBEaXIgc2VsYmVyLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKHdobyAmJiAhbGl2aW5nKHdobykgJiYgbm9fZGVhZCkgIHsKKyAgICBpZiAobm9fZGVhZF90ZXh0KQorICAgICAgd3JpdGUobm9fZGVhZF90ZXh0K0xGKTsKKyAgICBlbHNlCisgICAgICB3cml0ZSgiRGFzIGRhcmZzdCBEdSBudXIgbWl0IExlYmV3ZXNlbi5cbiIpOworICAgIHJldHVybiAyOworICB9CisgIGlmICghd2hvKSAgeworICAgIHdyaXRlKCJTY2hhdSBEaWNoIGVyc3QgbWFsIHVtIC0gZGFzIGFuZ2VnZWJlbmUgT2JqZWt0IGlzdCBuaWNodCBkYS5cbiIpOworICAgIHJldHVybiAzOworICB9CisgIHJldHVybigwKTsgLy9ub24tdm9pZC4gRmFsbC10aHJvdWdoLCBhbGxlcyBPSy4KK30KKworcHJpdmF0ZSBzdHJpbmcKK2NvbnZlcnRfc3RyaW5nKHN0cmluZyBzdHIpICB7CisgIC8qIEljaCBiaW4gdW5zY2h1bGRpZywgaWNoIGhhdHRlIGRhcyB2aWVsIGVpbmZhY2hlciB1bmQgc2Nob2VuZXIgOikKKyAgICAgUnVtYXRhIHdvbGx0ZSBkYXMgc28gOykgIC1IclQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KKyAgc3RyID0gaW1wbG9kZSggZXhwbG9kZSggc3RyLCAiQEBuYW1lQEAiICksIGNhcG5hbWUoKSApOworICBzdHIgPSBpbXBsb2RlKCBleHBsb2RlKCBzdHIsICJAQGduYW1lQEAiICksIGduYW1lKCkgKTsKKyAgc3RyID0gaW1wbG9kZSggZXhwbG9kZSggc3RyLCAiQEB3ZXJAQCIgKSwKKyAgICAod2hvP2NhcGl0YWxpemUod2hvLT5uYW1lKFdFUiwyKXx8IiIpOiIiICkpOworICBzdHIgPSBpbXBsb2RlKCBleHBsb2RlKCBzdHIsICJAQCB3ZW5AQCIgKSwKKyAgICAod2hvPyIgIit3aG8tPm5hbWUoV0VOLDIpOiIiKSk7CisgIHN0ciA9IGltcGxvZGUoIGV4cGxvZGUoIHN0ciwgIkBAIHdlbUBAIiApLAorICAgICh3aG8/IiAiK3doby0+bmFtZShXRU0sMik6IiIpKTsKKyAgc3RyID0gaW1wbG9kZSggZXhwbG9kZSggc3RyLCAiQEB3ZW5AQCIgKSwKKyAgICAod2hvP3doby0+bmFtZShXRU4sMik6IiIpKTsKKyAgc3RyID0gaW1wbG9kZSggZXhwbG9kZSggc3RyLCAiQEB3ZW1AQCIgKSwKKyAgICAod2hvP3doby0+bmFtZShXRU0sMik6IiIpKTsKKyAgc3RyID0gaW1wbG9kZSggZXhwbG9kZSggc3RyLCAiQEB3ZXNzZW5AQCIgKSwKKyAgICAod2hvP3doby0+bmFtZShXRVNTRU4sMik6IiIpKTsKKyAgc3RyID0gaW1wbG9kZSggZXhwbG9kZSggc3RyLCAiQEBhZHZlcmJAQCIgKSwKKyAgICAoYWR2ZXJiPyIgIithZHZlcmI6IiIpICk7CisgIHJldHVybiBzdHI7Cit9CisKK3ByaXZhdGUgaW50CitGZWVsSXQoKSAgeworICBpbnQgbXNnLCBmbGc7CisKKyAgZmxnID0gTVNHRkxBR19TT1VMOworICBpZiAocXVlcnlfdmVyYigpICYmIChxdWVyeV92ZXJiKClbMC4uM109PSJmcmFnIiB8fCBxdWVyeV92ZXJiKClbMC4uM109PSJhbnR3IikpCisgICAgZmxnIHw9IE1TR0ZMQUdfU0FZOworICBpZiAocXVlcnlfdmVyYigpICYmIChxdWVyeV92ZXJiKClbMC4uNV09PSJya251ZGQiIHx8IHF1ZXJ5X3ZlcmIoKT09InJ3aW5rIikpCisgICAgZmxnIHw9IE1TR0ZMQUdfUkVNT1RFOworCisgIC8vIE5QQyBoYWJlbiBrZWluZSBUTS1IaXN0IChjb21tLmMpLiBMZWlkZXIgZXJiZW4gYWJlciBkaXYuIE1hZ2llciBkaWUgU291bAorICAvLyAodHJvdHpkZW0gc2llIGluIC9zdGQvcGxheWVyLyBsaWVndCkgaW4gaWhyZW4gTlBDLi4uICpmbHVjaCoKKyAgaWYgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpKQorICAgIF9yZWN2KHdobywgYnJlYWtfc3RyaW5nKGNvbnZlcnRfc3RyaW5nKG91dF9zZWwpLDc4KSwgZmxnKTsKKyAgZWxzZQorICAgIHRlbGxfb2JqZWN0KE1FLCBicmVha19zdHJpbmcoY29udmVydF9zdHJpbmcob3V0X3NlbCksNzgpKTsKKworICBpZiAob3V0X3ZpYyAmJiB3aG8pICB7CisgICAgaWYgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUod2hvKSkgIHsKKyAgICAgIG1zZz13aG8tPk1lc3NhZ2UoIGJyZWFrX3N0cmluZyhjb252ZXJ0X3N0cmluZyggb3V0X3ZpYyApLDc4KSwgZmxnKTsKKyAgICAgIGlmIChtc2c9PS0xKQorICAgICAgICB3cml0ZSh3aG8tPm5hbWUoKSsiIGlnbm9yaWVydCBEaWNoIG9kZXIgZGllc2VuIEJlZmVobC5cbiIpOworICAgIH0gZWxzZQorICAgICAgdGVsbF9vYmplY3Qod2hvLGJyZWFrX3N0cmluZyhjb252ZXJ0X3N0cmluZyggb3V0X3ZpYyApLDc4KSk7CisgIH0KKyAgaWYgKG91dF9vdGgpCisgIHNheSggYnJlYWtfc3RyaW5nKGNvbnZlcnRfc3RyaW5nKCBvdXRfb3RoICksNzgpLCAoe3dobyx0aGlzX3BsYXllcigpfSkgKTsKKyAgb3V0X3NlbD1vdXRfdmljPW91dF9vdGg9MDsKKyAgcmV0dXJuIDE7Cit9CisKKy8qKgorICBEaWUgRnVua3Rpb24gc3RlbGx0IGVpbmVuIEhpbGZldGV4dCB6dXIgVmVyZnVlZ3VuZyB1bmQgbGlzdGV0IGRpZSAKKyAgZGVmaW5pZXJ0ZW4gQWR2ZXJiaWVuIGF1Zi4KKyAgXHBhcmFtIG1pbmUgMCA9IGFsbGUgQWR2ZXJiaWVuLCAKKyAgICAgICAgICAgICAgMT1udXIgc2VsYnN0IGRlZmluaWVydGUgQWR2ZXJiaWVuIAorICAgICAgICAgICAgICAyPW51ciBkaWUgdm9tIFN5c3RlbSBiZXJlaXRnZXN0ZWxsdGVuCisgKi8KK3ByaXZhdGUgaW50IHplaWdlX2FkdmVyYnMoaW50IG1pbmUpICB7CisgIG1hcHBpbmcgYWR2ZXJiX2xpc3Q7CisgIHN0cmluZyBvdXQsczsKKworICAvLyBQYXJhbWV0ZXIgYXVzd2VydGVuCisgIHN3aXRjaCAobWluZSl7CisgICAgY2FzZSAxOgorICAgICAgYWR2ZXJiX2xpc3Q9cGxyX2FkdmVyYnM7CisgICAgICBvdXQgPSAiRHUgaGFzdCBmb2xnZW5kZSBBZHZlcmJpZW4gZGVmaW5pZXJ0OlxuIjsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgMjoKKyAgICAgIGFkdmVyYl9saXN0PVF1ZXJ5U3RkQWR2ZXJicygpOworICAgICAgb3V0ID0gIlN5c3RlbXNlaXRpZyBzaW5kIGZvbGdlbmRlIEFkdmVyYmllbiBkZWZpbmllcnQ6XG4iOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIGFkdmVyYl9saXN0PVF1ZXJ5U3RkQWR2ZXJicygpK3Bscl9hZHZlcmJzOworICAgICAgb3V0ID0gIkZvbGdlbmRlIEFkdmVyYmllbiBzdGVoZW4gRGlyIHp1ciBWZXJmdWVndW5nOlxuIjsKKyAgfQorCisgIG91dCArPSIgIEFiay4gICAgQWR2ZXJiXG4gID09PT09PSAgPT09PT09XG4iOworCisgIGlmICggc2l6ZW9mKGFkdmVyYl9saXN0KSA9PSAwKSAKKyAgICBvdXQgKz0gIiBrZWluZS5cbiI7CisgIGVsc2UKKyAgICAvLyBVZWJlciBhbGxlIEVsZW1lbnRlIGRlciBpbmRpemllcyBkZXIgQWR2ZXJiaWVubGlzdGUgZ2VoZW4KKyAgIGZvcmVhY2ggKCBzIDogc29ydF9hcnJheShtX2luZGljZXMoYWR2ZXJiX2xpc3QpLCAjJz4gKSApIHsKKyAgICAgIG91dCArPSBicmVha19zdHJpbmcoYWR2ZXJiX2xpc3Rbc10sNzgsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoIiAgJS02cyAgIixzKSxCU19JTkRFTlRfT05DRSk7CisgICAgfQorCisgIE1vcmUob3V0KyJcbldpZSBkaWVzZSBBZHZlcmJpZW4gYmVudXR6dCB3ZXJkZW4gaXN0IGluIDxoaWxmZSBhZHZlcmI+ICIKKyAgICAiYmVzY2hyaWViZW4uXG4iKTsKKworICByZXR1cm4gMTsKK30KKwordmFyYXJncyBzdGF0aWMgaW50CitTb3VsQ29tbShzdHJpbmcgc3RyLCBzdHJpbmcgX3ZlcmIpICB7CisgIGludCB0X2csdF9uLGZsYWc7CisgIHN0cmluZyBzdHIxLHN0cjIsc3RyMywqdGFlbnplLHZiOworICBvdXRfc2VsPW91dF92aWM9b3V0X290aD13aG89MDsKKy8vICBpZiAodGhpc19pbnRlcmFjdGl2ZSgpIT1NRSkgcmV0dXJuIDA7CisgIGlmIChpbnRlcmFjdGl2ZShNRSkpIHN0cj1fdW5wYXJzZWRfYXJncygpOyAvLyBOUENzIGhhYmVuIGRhcyBuaWNodCA6KAorICBpZiAoc3RyPT0iIikgc3RyPTA7CisgIHZiPV92ZXJifHxxdWVyeV92ZXJiKCk7CisgIGlmIChzaXplb2YodmIpPjEgJiYgdmJbPDFdPT0nZScgJiYgdmIhPSJub2UiKSB2Yj12YlswLi48Ml07CisgIHNmb28gPSAwOworICBzd2l0Y2ggKHZiKSAgeworICAgIC8qKioqKioqKioqKioqKioqIEFlY2h6ZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImFlY2h6IjoKKyAgICBIRUxQQ0hFQ0soImFlY2h6Iik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJBZWNoemUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgYWVjaHp0QEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBhZWNoenRAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogQW5zY2htaWVnZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInNjaG1pZWciOgorICAgIEhFTFBDSEVDSygic2NobWllZyIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghd2hvKQorICAgICAgUmV0dXJuKCJBbiB3ZW4gd2lsbHN0IER1IERpY2ggYW5zY2htaWVnZW4/XG4iKTsKKyAgICBpZiAoQ2hlY2tMaWZlKE5PVF9TRUxGLE5PVF9ERUFELAorICAgICAgIkRhcyBnZWh0IGRvY2ggbmljaHQuIiwKKyAgICAgICJOZWluLCBkYXMgbWFjaHQga2VpbmVuIFNwYXNzLiBMZWJ0IGphIG5pY2h0IG1hbC4iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgb3V0X3NlbD0iRHUgc2NobWllZ3N0IERpY2hAQGFkdmVyYkBAIGFuQEAgd2VuQEAgYW4uIjsKKyAgICBvdXRfdmljPSJAQGduYW1lQEAgc2NobWllZ3Qgc2ljaEBAYWR2ZXJiQEAgYW4gRGljaC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBzY2htaWVndCBzaWNoQEBhZHZlcmJAQCBhbkBAIHdlbkBAIGFuLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogQW50d29ydGVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJhbnR3b3J0IjoKKyAgICBIRUxQQ0hFQ0soImFudHdvcnQiKTsKKyAgICBpZiAoIXN0cikKKyAgICAgIFJldHVybigiQW50d29ydGUgW1dFTV0gV0FTP1xuIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBzdHIxPWNhcGl0YWxpemUoc3RyKTsKKyAgICBlbHNlCisgICAgICBpZiAoc3NjYW5mKHN0ciwiJXMgJXMiLHN0cjEsc3RyMSkhPTIpCisgICAgICAgIFJldHVybigiQW50d29ydGUgd2FzP1xuIik7CisgICAgICBlbHNlCisgICAgICAgIHN0cjE9Y2FwaXRhbGl6ZShzdHIxKTsKKyAgICBvdXRfc2VsPSJEdSBhbnR3b3J0ZXN0QEAgd2VtQEA6ICIrc3RyMTsKKyAgICAvKiBTcHJhY2hmbHVlY2hlIGJlcnVlY2tzaWNodGlnZW4gLVdhcmdvbiwgOC4gOS4gOTUgKi8KKyAgICBpZiAoUXVlcnlQcm9wKFBfUEVSTV9TVFJJTkcpKQorICAgICAgc3RyMSA9IGNhbGxfb3RoZXIoUXVlcnlQcm9wKFBfUEVSTV9TVFJJTkcpLCJwZXJtdXRhdGVfc3RyaW5nIixzdHIxKXx8IiI7CisgICAgaWYgKHdobykgb3V0X3ZpYz0iQEBnbmFtZUBAIGFudHdvcnRldCBEaXI6ICIrc3RyMTsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgYW50d29ydGV0QEAgd2VtQEA6ICIrc3RyMTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBBcHBsYXVkaWVyZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImFwcGxhdWRpZXIiOgorICAgIEhFTFBDSEVDSygiYXBwbGF1ZGllciIpOworICAgIEdIT1NUQ0hFQ0soIkRlaW5lIEhhZW5kZSBmYWhyZW4gZHVyY2hlaW5hbmRlciBkdXJjaCAtIHdhciB3b2hsIG5peC5cbiIsCisgICAgICBnbmFtZSgpKyIgd2lsbCBhcHBsYXVkaWVyZW4sIGFiZXIgIitRUFAoRkVNQUxFLFdFUixQTFVSQUwpCisgICAgICAgICsiIEhhZW5kZSBzYXVzZW5cbmR1cmNoZWluYW5kZXIgZHVyY2guXG4iLCAwKTsKKyAgICBpZiAoIXN0cikgIHsKKyAgICAgIG91dF9zZWw9IkR1IGFwcGxhdWRpZXJzdCB2b24gZ2FuemVtIEhlcnplbi4iOworICAgICAgb3V0X290aD0iQEBuYW1lQEAgZ2lidCBlaW5lIFJ1bmRlIEFwcGxhdXMuIjsKKyAgICB9CisgICAgZWxzZSAgeworICAgICAgUGFyc2VSZXN0KHN0cik7CisgICAgICBpZiAoZm9yX2FsbCkgIHsKKyAgICAgICAgb3V0X3NlbD0iRHUgYXBwbGF1ZGllcnN0IEBAYWxsZUBAQEBhZHZlcmJAQC4iOworICAgICAgICBvdXRfdmljPSJAQG5hbWVAQCBhcHBsYXVkaWVydCBAQGFsbGVAQEBAYWR2ZXJiQEAuIjsKKyAgICAgICAgcmV0dXJuIE1peGVkT3V0KFdFTSk7CisgICAgICB9CisgICAgICBpZiAoIXdobyAmJiAhYWR2ZXJiKQorICAgICAgICBSZXR1cm4oIkFwcGxhdWRpZXJlIHdlbSBvZGVyIHdpZSBvZGVyIHNvIGFlaG5saWNoLlxuIik7CisgICAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICAgIk5laW4sIGRhcyBnZWhvZXJ0IHNpY2ggbmljaHQuIiwKKyAgICAgICAgIlNhY2hlbiB3aXJkIGhpZXIgbmljaHQgYXBwbGF1ZGllcnQsIE9LPyIpKQorICAgICAgICAgIHJldHVybiAxOworICAgICAgb3V0X3NlbD0iRHUgYXBwbGF1ZGllcnN0QEAgd2VtQEBAQGFkdmVyYkBALiI7CisgICAgICBpZiAod2hvKSBvdXRfdmljPSJAQG5hbWVAQCBhcHBsYXVkaWVydCBEaXJAQGFkdmVyYkBALiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCBhcHBsYXVkaWVydEBAIHdlbUBAQEBhZHZlcmJAQC4iOworICAgIH0KKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBBcmdsbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiYXJnbCI6CisgICAgSEVMUENIRUNLKCJhcmdsIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJBcmdsZSB3aWU/XG4iKTsKKyAgICBvdXRfc2VsPSJEdSBhcmdsc3QiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQC4iIDogIiBlaW4gd2VuaWcgdm9yIERpY2ggaGluLiIpOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBhcmdsdCIKKyAgICAgICsoYWR2ZXJiID8gIkBAYWR2ZXJiQEAuIiA6ICIgZWluIHdlbmlnIHZvciBzaWNoIGhpbi4iKTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBBdWZhdG1lbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiYXRtIjoKKyAgICBIRUxQQ0hFQ0soImF0bSIpOworICAgIGlmICghc3RyIHx8IHNzY2FuZihzdHIsIiVzYXVmIixzdHIxKSE9MSkKKyAgICAgIFJldHVybigiQXRtZSB3aWUgYXVmP1xuIik7CisgICAgUGFyc2VSZXN0KHN0cjEpOworICAgIG91dF9zZWw9IkR1IGF0bWVzdCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBAIiA6ICIgZXJsZWljaHRlcnQiKSsiIGF1Zi4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBhdG1ldCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBAIiA6ICIgZXJsZWljaHRlcnQiKSsiIGF1Zi4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEJlZ3J1ZXNzZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImhhbGxvIjoKKyAgICBjYXNlICJoaSI6CisgICAgY2FzZSAiYmVncnVlc3MiOgorICAgIEhFTFBDSEVDSygiYmVncnVlc3MiKTsKKyAgICBQYXJzZVJlbW90ZShzdHIpOworICAgIGlmICghd2hvKQorICAgICAgUmV0dXJuKCJXZW4gd2lsbHN0IER1IGJlZ3J1ZXNzZW4/XG4iKTsKKyAgICBpZiAocHJlc2VudCh3aG8sIGVudmlyb25tZW50KCkpKSAgeworICAgICAgb3V0X3NlbD0iRHUgaGVpc3N0IEBAd2VuQEBAQGFkdmVyYkBAIHdpbGxrb21tZW4uIjsKKyAgICAgIG91dF92aWM9IkBAZ25hbWVAQCBoZWlzc3QgRGljaEBAYWR2ZXJiQEAgd2lsbGtvbW1lbi4iOworICAgICAgb3V0X290aD0iQEBnbmFtZUBAIGhlaXNzdCBAQHdlbkBAQEBhZHZlcmJAQCB3aWxsa29tbWVuLiI7CisgICAgfQorICAgIGVsc2UgIHsKKyAgICAgIG91dF9zZWw9IkR1IGhlaXNzdCBAQHdlbkBAQEBhZHZlcmJAQCBhdXMgZGVyIEZlcm5lIHdpbGxrb21tZW4uIjsKKyAgICAgIG91dF92aWM9IkBAZ25hbWVAQCBoZWlzc3QgRGljaEBAYWR2ZXJiQEAgYXVzIGRlciBGZXJuZSB3aWxsa29tbWVuLiI7CisgICAgfQorICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEJldGFzdGVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJiZXRhc3QiOgorICAgIEhFTFBDSEVDSygiYmV0YXN0Iik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIkJlZ3JhYnNjaGUgd2VuP1xuIik7CisgICAgb3V0X3NlbD0iRHUgZ3JhYmJlbHN0QEBhZHZlcmJAQCBhbiAiK3doby0+bmFtZShXRU0pKyIgaGVydW0uIjsKKyAgICBvdXRfdmljPSJAQGduYW1lQEAgZ3JhYmJlbHRAQGFkdmVyYkBAIGFuIERpciBoZXJ1bS4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBncmFiYmVsdEBAYWR2ZXJiQEAgYW4gIit3aG8tPm5hbWUoV0VNKSsiIGhlcnVtLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogQmV3dW5kZXJuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJiZXd1bmRlciI6CisgICAgSEVMUENIRUNLKCJiZXd1bmRlciIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghd2hvKQorICAgICAgUmV0dXJuKCJCZXd1bmRlcmUgd2VuP1xuIik7CisgICAgb3V0X3NlbD0iRHUgYmV3dW5kZXJzdCBAQHdlbkBAQEBhZHZlcmJAQC4iOworICAgIG91dF92aWM9IkBAZ25hbWVAQCBiZXd1bmRlcnQgRGljaEBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgYmV3dW5kZXJ0IEBAd2VuQEBAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogQmliYmVybiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiYmliYmVyIjoKKyAgICBIRUxQQ0hFQ0soImJpYmJlciIpOworICAgIGlmIChnaG9zdCgpKQorICAgICAgUmV0dXJuKCJBbHMgR2Vpc3QgZnVlaGxzdCBEdSBrZWluZSBLYWVsdGUuXG4iKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIkJpYmJlcmUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgYmliYmVyc3RAQGFkdmVyYkBAIHZvciBLYWVsdGUuIjsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBiaWJiZXJ0QEBhZHZlcmJAQCB2b3IgS2FlbHRlLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogQm9ocmUgTmFzZSAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiYm9ociI6CisgICAgSEVMUENIRUNLKCJib2hyIik7CisgICAgUGFyc2VSZXN0KHN0ciwgKHsibmFzZSIsImluIGRlciBuYXNlIiwiaW4gbmFzZSJ9KSk7CisgICAgaWYgKHN0ciAmJiBzdHIhPSJuYXNlIiAmJiBzdHIhPSJpbiBuYXNlIiAmJiBzdHIhPSJpbiBkZXIgbmFzZSIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiQm9ocmUgd2llIE5hc2U/XG4iKTsKKyAgICBvdXRfc2VsPSJEdSBib2hyc3RAQGFkdmVyYkBAIGluIERlaW5lciBOYXNlLiI7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIGJvaHJ0QEBhZHZlcmJAQCBpbiBkZXIgTmFzZS4gICAgIElnaXR0ISA6KSI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogQnJ1bW1lbG4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImJydW1tZWwiOgorICAgIEhFTFBDSEVDSygiYnJ1bW1lbCIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIG91dF9zZWw9IkR1IGJydW1tZWxzdCIKKyAgICAgICsoYWR2ZXJiID8gIkBAYWR2ZXJiQEAuIiA6IChzdHIgPyAiIGthdW0gdmVyc3RhZW5kbGljaDogIitzdHIrIi4iIDogIi4iKSk7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIGJydW1tZWx0IgorICAgICAgKyhhZHZlcmIgPyAiQEBhZHZlcmJAQC4iIDogKHN0ciA/ICIga2F1bSB2ZXJzdGFlbmRsaWNoOiAiK3N0cisiLiIgOiAiLiIpKTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBjbHMgKioqKioqKioqKioqKioqLworICAgIGNhc2UgImNscyI6CisgICAgSEVMUENIRUNLKCJjbHMiKTsKKyAgICB3cml0ZSgiG1syShtbSCIpOworICAgIHJldHVybiAxOworCisgICAgLyoqKioqKioqKioqKioqKiogRGFldW1jaGVuZHJlaGVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJkcmVoIjoKKyAgICBIRUxQQ0hFQ0soImRyZWgiKTsKKyAgICBpZiAoIXN0cikKKyAgICAgIFJldHVybigiRHJlaGUgd2FzP1xuIik7CisgICAgaWYoc3Ryc3RyKHN0ciwiZGFldW1jaGVuIik8MCAmJiBzdHJzdHIoc3RyLCJkYXVtZW4iKTwwKQorICAgICAgUmV0dXJuKCJEcmVoZSB3YXM/XG4iKTsKKyAgICBQYXJzZVJlc3Qoc3RyLCh7ImRhZXVtY2hlbiIsImRhdW1lbiJ9KSk7CisgICAgb3V0X3NlbD0iRHUgZHJlaHN0QEBhZHZlcmJAQCBEYWV1bWNoZW4uIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgZHJlaHRAQGFkdmVyYkBAIERhZXVtY2hlbi4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIERhbmtlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZGFuayI6CisgICAgSEVMUENIRUNLKCJkYW5rIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIkJlaSB3ZW0gd2lsbHN0IER1IERpY2ggYmVkYW5rZW4/XG4iKTsKKyAgICBpZiAoQ2hlY2tMaWZlKE5PVF9TRUxGLCBOT1RfREVBRCwKKyAgICAgICJMZWlkZXN0IER1IGpldHp0IHNjaG9uIGFuIFBlcnNvZW5saWNrZWl0c3NwYWx0dW5nPyBOZSwgbmUuLi4iLAorICAgICAgIktlaW5lIFJlYWt0aW9uLiBJc3Qgd29obCBiZWZyaWVkaWdlbmRlciwgc2ljaCBiZWkgTGViZXdlc2VuIHp1ICIKKyAgICAgICAgKyJiZWRhbmtlbi4iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgb3V0X3NlbD0iRHUgYmVkYW5rc3QgRGljaEBAYWR2ZXJiQEAgYmVpQEAgd2VtQEAuIjsKKyAgICBvdXRfdmljPSJAQGduYW1lQEAgYmVkYW5rdCBzaWNoQEBhZHZlcmJAQCBiZWkgRGlyLiI7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIGJlZGFua3Qgc2ljaEBAYWR2ZXJiQEAgYmVpQEAgd2VtQEAuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBEZW5rZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImRlbmsiOgorICAgIEhFTFBDSEVDSygiZGVuayIpOworICAgIGlmIChnaG9zdCgpKQorICAgICAgUmV0dXJuKCJXb21pdCB3aWxsc3QgRHUgZGVubiBkZW5rZW4/IER1IGhhc3Qga2VpbmUgZ3JhdWVuIFplbGxlbi4uLlxuIik7CisvLyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBzdHIyPW9sZF9leHBsb2RlKHN0cnx8IiIsIiAiKVswXTsKKyAgICBpZiAoc3RyCisgICAgJiYgKCFhZHZlcmJ8fCgoUXVlcnlTdGRBZHZlcmJzKClbc3RyMl18fHBscl9hZHZlcmJzW3N0cjJdKSkhPWFkdmVyYikpICB7CisgICAgICBvdXRfc2VsPSJEdSBkZW5rc3QgICAuIG8gTyAoIitzdHIrIikiOworICAgICAgb3V0X290aD0iQEBuYW1lQEAgZGVua3QgICAuIG8gTyAoIitzdHIrIikiOworICAgICAgb3V0X3ZpYz0iQEBuYW1lQEAgZGVua3QgICAuIG8gTyAoIitzdHIrIikiOworICAgIH0KKyAgICBlbHNlICB7CisgICAgICBvdXRfc2VsPSJEdSBmYWVuZ3N0QEBhZHZlcmJAQCBhbiB6dSBkZW5rZW4uXG5LbGVpbmUgIgorICAgICAgICArIlJhdWNod29lbGtjaGVuIHN0ZWlnZW4gYXVmLi4uIjsKKyAgICAgIG91dF9vdGg9IkBAbmFtZUBAIGZhZW5ndEBAYWR2ZXJiQEAgYW4genUgZGVua2VuLlxuS2xlaW5lICIKKyAgICAgICAgKyJSYXVjaHdvZWxrY2hlbiBzdGVpZ2VuIGF1Zi4uLiI7CisgICAgfQorICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIERldXRlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZGV1dCI6CisgICAgSEVMUENIRUNLKCJkZXV0Iik7CisgICAgUGFyc2VSZXN0KHN0ciwiYXVmIik7CisgICAgaWYgKGZvcl9hbGwpICB7CisgICAgICBvdXRfc2VsPSJEdSBkZXV0ZXN0QEBhZHZlcmJAQCBhdWYgQEBhbGxlQEAuIjsKKyAgICAgIG91dF92aWM9IkBAZ25hbWVAQCBkZXV0ZXRAQGFkdmVyYkBAIGF1ZiBAQGFsbGVAQC4iOworICAgICAgcmV0dXJuIE1peGVkT3V0KFdFTik7CisgICAgfQorICAgIGlmICghd2hvKQorICAgICAgUmV0dXJuKCJBdWYgd2VuIG9kZXIgd2FzIHdpbGxzdCBEdSBkZXV0ZW4/XG4iKTsKKyAgICBvdXRfc2VsPSJEdSBkZXV0ZXN0QEBhZHZlcmJAQCBhdWYiCisgICAgICArKHdobz09dGhpc19vYmplY3QoKT8iIERpY2guIiA6ICJAQCB3ZW5AQC4iKTsKKyAgICBpZiAod2hvICE9IHRoaXNfb2JqZWN0KCkpIG91dF92aWM9IkBAZ25hbWVAQCBkZXV0ZXRAQGFkdmVyYkBAIGF1ZiBEaWNoLiI7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIGRldXRldEBAYWR2ZXJiQEAgYXVmIgorICAgICAgKyh3aG89PXRoaXNfb2JqZWN0KCkgPyAiIHNpY2ggc2VsYmVyLiI6ICJAQCB3ZW5AQC4iKTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBEcnVlY2tlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZHJ1ZWNrIjoKKyAgICBIRUxQQ0hFQ0soImRydWVjayIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChmb3JfYWxsKSAgeworICAgICAgb3V0X3NlbD0iRHUgZHJ1ZWNrc3QgQEBhbGxlQEAiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQCIgOiAiIHphZXJ0bGljaCIpCisgICAgICAgICsiIGFuIERpY2guIjsKKyAgICAgIG91dF92aWM9IkBAZ25hbWVAQCBkcnVlY2t0IEBAYWxsZUBAIisKKyAgICAgICAgKGFkdmVyYiA/ICJAQGFkdmVyYkBAIiA6ICIgemFlcnRsaWNoIikrIiBhbiBzaWNoLiI7CisgICAgICByZXR1cm4gTWl4ZWRPdXQoV0VOKTsKKyAgICB9CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIldlbiB3aWxsc3QgRHUgZGVubiBkcnVlY2tlbj9cbiIpOworICAgIGlmIChDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAiRGFzIG1hY2h0IGRvY2gga2VpbmVuIFNwYXNzLiIsCisgICAgICAiSWNoIGRydWVja2UgbnVyIGplbWFuZGVuLCBuaWNodCBldHdhcy4iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgR0hPU1RDSEVDSygiRHUgd2lsbHN0ICIrd2hvLT5uYW1lKFdFTikrIiBhbiBEaWNoIGRydWVja2VuIC0gbnVyIGhhc3QgRHUgIgorICAgICAgICArInNjaG9uXG53aWVkZXIgbmljaHQgZGFyYW4gZ2VkYWNodCwgZGFzcyBzbyB3YXMgYWxzIEdlaXN0IG5pY2h0ICIKKyAgICAgICAgKyJnZWh0LlxuIiwKKyAgICAgIGduYW1lKCkrIiB3aWxsICIrd2hvLT5uYW1lKFdFTikrIiBhbiBzaWNoIGRydWVja2VuIC0gaGF0IGFiZXJcbiIKKyAgICAgICAgKyJtYWwgd2llZGVyIG5pY2h0IGFuIGRpZSBOYWNodGVpbGUgZGVzIEdlaXN0ZXJkYXNlaW5zIGdlZGFjaHQuXG4iLAorICAgICAgZ25hbWUoKSsiIHdpbGwgRGljaCBhbiBzaWNoIGRydWVja2VuIC0gaGF0IGFiZXIgbWFsIHdpZWRlclxuIgorICAgICAgICArIm5pY2h0IGFuIGRpZSBOYWNodGVpbGUgZGVzIEdlaXN0ZXJkYXNlaW5zIGdlZGFjaHQuXG4iKTsKKyAgICBvdXRfc2VsPSJEdSBkcnVlY2tzdCBAQHdlbkBAIisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAiIDogIiB6YWVydGxpY2giKQorICAgICAgKyIgYW4gRGljaC4iOworICAgIG91dF92aWM9IkBAbmFtZUBAIGRydWVja3QgRGljaCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBAIiA6ICIgemFlcnRsaWNoIikKKyAgICAgICsiIGFuIHNpY2guIjsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBkcnVlY2t0IEBAd2VuQEAiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQCIgOiAiIHphZXJ0bGljaCIpCisgICAgICArIiBhbiBzaWNoLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogRW50c2NodWxkaWdlICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJlbnRzY2h1bGRpZyI6CisgICAgSEVMUENIRUNLKCJlbnRzY2h1bGRpZyIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIXdobyAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJFbnRzY2h1bGRpZ2UgRGljaCB3aWUgb2RlciBiZWkgd2VtP1xuIik7CisgICAgb3V0X3NlbD0iRHUgYml0dGVzdCIrKHdobyA/ICIgQEB3ZW5AQCIgOiAiIikKKyAgICAgICsiQEBhZHZlcmJAQCB1bSBFbnRzY2h1bGRpZ3VuZy4iOworICAgIGlmICh3aG8pIG91dF92aWM9IkBAZ25hbWVAQCBiaXR0ZXQgRGljaEBAYWR2ZXJiQEAgdW0gRW50c2NodWxkaWd1bmcuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgYml0dGV0Iisod2hvID8gIiBAQHdlbkBAIiA6ICIiKQorICAgICAgKyJAQGFkdmVyYkBAIHVtIEVudHNjaHVsZGlndW5nLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogRXJibGVpY2hlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZXJibGVpY2giOgorICAgIEhFTFBDSEVDSygiZXJibGVpY2giKTsKKyAgICBHSE9TVENIRUNLKCJJY2ggd2Vpc3MgendhciBuaWNodCwgd2llIER1IGRhcyBzY2hhZmZzdCwgYWJlciBEdSB3aXJzdCAiCisgICAgICAgICsibm9jaCBibGVpY2hlci5cbiIsCisgICAgICBicmVha19zdHJpbmcoIldpZSB1bndhaHJzY2hlaW5saWNoIGRhcyBhdWNoIGlzdCwgYWJlciAiK2duYW1lKCkKKyAgICAgICAgKyIgc2NoYWZmdCBlcyB0YXRzYWVjaGxpY2gsIG5vY2ggYmxlaWNoZXIgenUgd2VyZGVuLiIsNzgpLCAwICk7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJXaWUgd2lsbHN0IER1IGVyYmxlaWNoZW4/XG4iKTsKKyAgICBvdXRfc2VsPSJEdSBlcmJsZWljaHN0QEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIGVyYmxlaWNodEBAYWR2ZXJiQEAuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBFcnJvZXRlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZXJyb2V0IjoKKyAgICBIRUxQQ0hFQ0soImVycm9ldCIpOworICAgIEdIT1NUQ0hFQ0soIkR1IHNjaGFmZnN0IGVzIG51ciBiaXMgenUgZWluZW0gYmxhc3NlbiBSb3NhLCBhYmVyIGltbWVyaGluLlxuIiwKKyAgICAgICJEaWUgV2FuZ2VuIGRlcyBHZWlzdGVzIHZvbiAiK2NhcG5hbWUoKSsiIHdlcmRlbiBsZWljaHQgcm9zYS5cbiIsIDApOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghYWR2ZXJiICYmIHN0cikKKyAgICAgIFJldHVybigiRXJyb2V0ZSB3aWU/XG4iKTsKKyAgICBvdXRfc2VsPSJEZWluZSBXYW5nZW4gZ2x1ZWhlbkBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBlcnJvZXRldEBAYWR2ZXJiQEAuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBFcnNjaHJlY2tlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZXJzY2hyZWNrIjoKKyAgICBjYXNlICJlcnNjaHJpY2siOgorICAgIGlmICghZ2hvc3QoKSkKKyAgICAgIFJldHVybigiRHUgYmlzdCB6dSBoYXJtbG9zLCBHZWlzdCBtdWVzc3RlIG1hbiBzZWluLi4uXG4iKTsKKyAgICBIRUxQQ0hFQ0soImVyc2NocmVjayIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghd2hvKQorICAgICAgUmV0dXJuKCJXZW4gd2lsbHN0IER1IGRlbm4gZXJzY2hyZWNrZW4/XG4iKTsKKyAgICBvdXRfc2VsPSJNaXQgZWluZW0gbGF1dGVuIEJVSCEgZXJzY2hyZWNrc3QgRHUgQEB3ZW5AQCIKKyAgICAgICsoYWR2ZXJiID8gIkBAYWR2ZXJiQEAuIiA6ICIgZnVlcmNodGVybGljaC4iKTsKKyAgICBvdXRfdmljPSJCVUghIER1IHp1Y2tzdCB2b3IgU2NocmVjayB6dXNhbW1lbi4gTXVzcyBkaWVzZXIgR2Vpc3Qgdm9uICIKKyAgICAgICsiQEBnbmFtZUBAIERpY2ggYXVjaEBAYWR2ZXJiQEAgZXJzY2hyZWNrZW4uIjsKKyAgICBvdXRfb3RoPSJCVUghIEBAZ25hbWVAQCBlcnNjaHJlY2t0IEBAd2VuQEAiCisgICAgICArKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOiAiIGZ1ZXJjaHRlcmxpY2guIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogRmxpcHBlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZmxpcHAiOgorICAgIEhFTFBDSEVDSygiZmxpcHAiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIkF1c2ZsaXBwZW4gd29sbGVuIHdpciBhbHNvLCBzbyBzby4gVW5kIHdpZSwgd2VubiBpY2ggIgorICAgICAgICArImZyYWdlbiBkYXJmP1xuIik7CisgICAgb3V0X3NlbD0iRHUgZmxpcHBzdCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBAIGF1cy4iIDogIiB0b3RhbCBhdXMuIik7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIGZsaXBwdCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBAIGF1cy4iIDogIiB0b3RhbCBhdXMuIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogRmx1Y2hlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZmx1Y2giOgorICAgIEhFTFBDSEVDSygiZmx1Y2giKTsKKyAgICBHSE9TVENIRUNLKCJEdSBmYWVuZ3N0IG1hbmdlbHMgUmVzb25hbnprb2VycGVyIGxlaXNlIGFuIHp1IGZsdWNoZW4uXG4iLAorICAgICAgZ25hbWUoKSsiIGZhZW5ndCBsZWlzZSBhbiB6dSBmbHVjaGVuLiBMYXV0IGthbm4gZXIgbmljaHQsXG4iCisgICAgICAgICsibWFuZ2VscyBMdWZ0IHVuZCBSZXNvbmFuemtvZXJwZXIuXG4iLCAwKTsKKyAgICBpZiAoIXN0cikgIHsKKyAgICAgIG91dF9zZWw9IkR1IGZsdWNoc3QgbGF1dHN0YXJrLiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCBmYWVuZ3QgYW4sIGZ1ZXJjaHRlcmxpY2ggenUgZmx1Y2hlbi4iOworICAgIH0KKyAgICBlbHNlICB7CisgICAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICAgIGlmICghYWR2ZXJiKQorICAgICAgICBSZXR1cm4oIldpZSB3aWxsc3QgRHUgZmx1Y2hlbj9cbiIpOworICAgICAgb3V0X3NlbD0iRHUgZmx1Y2hzdEBAYWR2ZXJiQEAuIjsKKyAgICAgIG91dF9vdGg9IkBAbmFtZUBAIGZsdWNodCBhdWYgZWlubWFsQEBhZHZlcmJAQC4iOworICAgIH0KKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBGcmFnZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImZyYWciOgorICAgIEhFTFBDSEVDSygiZnJhZyIpOworICAgIGlmICghc3RyKQorICAgICAgUmV0dXJuKCJGcmFnZSB3ZW4gd2FzP1xuIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHdobyAmJiBDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAiRHUgZmFlbmdzdCB6dSBncnVlYmVsbiBhbi4uLiIsCisgICAgICAiRnJhZ2UgamVtYW5kLCBkZXIgbGVidC4iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgaWYgKHdobykKKyAgICAgIHNzY2FuZihzdHIsIiVzICVzIiwgc3RyMSxzdHIxKTsKKyAgICBlbHNlCisgICAgICBzdHIxPXN0cjsKKyAgICBpZiAoIXN0cjEpCisgICAgICBSZXR1cm4oIkZyYWdlICIrd2hvLT5uYW1lKFdFTikrIiBXQVM/XG4iKTsKKyAgICBzdHIxPWNhcGl0YWxpemUoc3RyMSk7CisgICAgaWYgKHN0cjFbPDFdICE9ICc/JykKKyAgICAgIHN0cjEgKz0gIj8iOworICAgIG91dF9zZWw9IkR1IGZyYWdzdEBAIHdlbkBAOiAiK3N0cjE7CisgICAgLyogU3ByYWNoZmx1Y2ggYmVydWVja3NpY2h0aWdlbiAtV2FyZ29uLCA4LiA5LiA5NSAqLworICAgIGlmIChvYmplY3RwKFF1ZXJ5UHJvcChQX1BFUk1fU1RSSU5HKSkpCisgICAgICBzdHIxID0gY2FsbF9vdGhlcihRdWVyeVByb3AoUF9QRVJNX1NUUklORyksICJwZXJtdXRhdGVfc3RyaW5nIiwgc3RyMSl8fCIiOworICAgIGlmICh3aG8pIG91dF92aWM9KGdob3N0KCkgPyAiRGVyIEdlaXN0IHZvbiAiIDogLyogSVNfTEVBUk5FUihNRSkgPworICAgICAgUXVlcnlQcm9wKFBfUFJFU0FZKXx8IiIgOiAqLyAiIikrY2FwbmFtZSgpKyIgZnJhZ3QgRGljaDogIitzdHIxOworICAgIG91dF9vdGg9KGdob3N0KCkgPyAiRGVyIEdlaXN0IHZvbiAiIDogLyogSVNfTEVBUk5FUihNRSkgPworICAgICAgUXVlcnlQcm9wKFBfUFJFU0FZKXx8IiIgOiAqLyAiIikrY2FwbmFtZSgpKyIgZnJhZ3RAQCB3ZW5AQDogIitzdHIxOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEZyZXVlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZnJldSI6CisgICAgSEVMUENIRUNLKCJmcmV1Iik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhd2hvICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIkZyZXVlIERpY2ggd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgIisod2hvID8gImdyaW5zdCBAQHdlbkBAIGFuIHVuZCAiIDogIiIpCisgICAgICArImZyZXVzdCBEaWNoQEBhZHZlcmJAQC4iOworICAgIGlmICh3aG8pIG91dF92aWM9IkBAZ25hbWVAQCBncmluc3QgRGljaCBhbiB1bmQgZnJldXQgc2ljaEBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgIisod2hvID8gImdyaW5zdCBAQHdlbkBAIGFuIHVuZCAiIDogIiIpCisgICAgICArImZyZXV0IHNpY2hAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogRnVyemVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJmdXJ6IjoKKyAgICBIRUxQQ0hFQ0soImZ1cnoiKTsKKyAgICBHSE9TVENIRUNLKCJEdSBsYWVzc3QgZWluZW4gZmFocmVuIC0gYWJlciBlciByaWVjaHQgbmFjaCBnYXIgbml4LlxuIiwKKyAgICAgIGduYW1lKCkrIiBsYWVzc3QgZWluZW4gZmFocmVuLiBNYW4gcmllY2h0IGFiZXIgbml4LlxuIiwgMCk7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJGdXJ6ZSB3aWU/XG4iKTsKKyAgICBvdXRfc2VsPSJEdSBmdXJ6dCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOiAiIGhlbW11bmdzbG9zLiIpOworICAgIG91dF9vdGg9IkBAbmFtZUBAIGxhZXNzdEBAYWR2ZXJiQEAgZWluZW4gU3RpbmtlZnVyeiBmYWhyZW4uIjsKKyAgICBvZm9vPWNsb25lX29iamVjdCgiL2l0ZW1zL2Z1cnoiKTsKKyAgICBvZm9vLT5zZXRfZnVyemVyKHRoaXNfcGxheWVyKCkpOworICAgIG9mb28tPm1vdmUoZW52aXJvbm1lbnQodGhpc19wbGF5ZXIoKSkpOworICAgIHJldHVybiBGZWVsSXQoKTsKKy8vIERFQlVHIEZ1cnogdGVzdGVuIQorCisgICAgLyoqKioqKioqKioqKioqKiogR2FlaG5lbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZ2FlaG4iOgorICAgIEhFTFBDSEVDSygiZ2FlaG4iKTsKKyAgICBpZiAoZ2hvc3QoKSkKKyAgICAgIFJldHVybigiQWxzIEdlaXN0IHdpcnN0IER1IG5pY2h0IG11ZWRlIC0gYWxzbyBuaWNodCBnYWVobmVuLlxuIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJXaWUgd2lsbHN0IER1IGdhZWhuZW4/XG4iKTsKKyAgICBpZiAoIWFkdmVyYikKKyAgICAgIG91dF9zZWw9Ikthbm5zdCBEdSBhYmVyIERlaW4oZW4pIE11bmQvTWF1bC9TY2huYWJlbCB3ZWl0IGF1ZnJlaXNzZW4hIjsKKyAgICBlbHNlCisgICAgICBvdXRfc2VsPSJEdSBnYWVobnN0QEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBnYWVobnRAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogR2x1Y2tzZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImdsdWNrcyI6CisgICAgSEVMUENIRUNLKCJnbHVja3MiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIkdsdWNrc2Ugd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgZ2x1Y2tzdCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOiAiIHdpZSBlaW4gSHVobi4iKTsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgZ2x1Y2tzdCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOiAiIHdpZSBlaW4gSHVobi4iKTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBHcmF0dWxpZXJlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZ3JhdHVsaWVyIjoKKyAgICBjYXNlICJiZWdsdWVja3d1ZW5zY2giOgorICAgIEhFTFBDSEVDSygiZ3JhdHVsaWVyIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIldlbSB3aWxsc3QgRHUgZ3JhdHVsaWVyZW4/XG4iKTsKKyAgICBpZiAoQ2hlY2tMaWZlKE5PVF9TRUxGLCBOT1RfREVBRCwKKyAgICAgICJOYSwgbWVpbnN0IER1IG5pY2h0LCBkYXNzIEVpZ2VubG9iIHN0aW5rdD8iLAorICAgICAgIlNvbGwgaWNoIGRlbSBEaW5nIHZpZWxsZWljaHQgenVtIFRvdHNlaW4gZ3JhdHVsaWVyZW4/IE5lZSBuZWUuIikpCisgICAgICAgIHJldHVybiAxOworICAgIG91dF9zZWw9IkR1IGdyYXR1bGllcnN0IEBAd2VtQEBAQGFkdmVyYkBALiI7CisgICAgb3V0X3ZpYz0iQEBnbmFtZUBAIGdyYXR1bGllcnQgRGlyQEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBncmF0dWxpZXJ0IEBAd2VtQEBAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogR3JpbnNlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZ3JpbnMiOgorICAgIEhFTFBDSEVDSygiZ3JpbnMiKTsKKyAgICBHSE9TVENIRUNLKCJBbHMgRHUgZ3JpbnN0LCBzaWVoc3QgRHUgcmVnZWxyZWNodCwgd2llIGRpZSBhbmRlcmVuIGVpbmUgIgorICAgICAgICArIkdhZW5zZWhhdXQgYmVrb21tZW4uXG4iLAorICAgICAgIkR1IGJla29tbXN0IGVpbmUgR2FlbnNlaGF1dCwgYWxzIGRlciBHZWlzdCB2b24gIitjYXBuYW1lKCkKKyAgICAgICAgKyIgenUgZ3JpbnNlbiBhbmZhZW5ndC5cbiIsIDApOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChmb3JfYWxsKSAgeworICAgICAgb3V0X3NlbD0iRHUgZ3JpbnN0IEBAYWxsZUBAQEBhZHZlcmJAQCBhbi4iOworICAgICAgb3V0X3ZpYz0iQEBuYW1lQEAgZ3JpbnN0IEBAYWxsZUBAQEBhZHZlcmJAQCBhbi4iOworICAgICAgcmV0dXJuIE1peGVkT3V0KFdFTik7CisgICAgfQorICAgIGlmICghd2hvICYmICFhZHZlcmIgJiYgc3RyKQorICAgICAgUmV0dXJuKCJHcmluc2VuIC0gc2Nob2VuIHVuZCBndXQuIEFiZXIgd2VuIG9kZXIgd2llIChhbilncmluc2VuP1xuIik7CisgICAgaWYgKHdobyAmJiBDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAiRHUgZ3JpbnN0IERpciB3YXMsIGFiZXIgc28sIGRhc3MgZXMga2VpbiBhbmRlcmVyIHNpZWh0LiIsCisgICAgICAiTmljaHQgbWFsIGVpbmVuIFNwaWVnZWwgZGFyZiBtYW4gaGllciBhbmdyaW5zZW4sIG51ciBMZWJld2VzZW4hIikpCisgICAgICAgIHJldHVybiAxOworICAgIG91dF9zZWw9IkR1IGdyaW5zdEBAIHdlbkBAQEBhZHZlcmJAQCIrKHdobyA/ICIgYW4iIDogIiIpKyIuIjsKKyAgICBpZiAod2hvKSBvdXRfdmljPSJAQG5hbWVAQCBncmluc3QgRGljaEBAYWR2ZXJiQEAgYW4uIjsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBncmluc3RAQCB3ZW5AQEBAYWR2ZXJiQEAiKyh3aG8gPyAiIGFuIiA6ICIiKSsiLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogR3J1ZWJlbG4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImdydWViZWwiOgorICAgIGNhc2UgImdydWVibCI6CisgICAgSEVMUENIRUNLKCJncnVlYmVsIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJHcnVlYmxlIHdpZT9cbiIpOworICAgIG91dF9zZWw9IkR1IGdydWViZWxzdEBAYWR2ZXJiQEAgZWluZSBXZWlsZSB2b3IgRGljaCBoaW4uIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgZ3J1ZWJlbHRAQGFkdmVyYkBAIGVpbmUgV2VpbGUgdm9yIHNpY2ggaGluLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogR3J1bW1lbG4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImdydW1tZWwiOgorICAgIGNhc2UgImdydW1tbCI6CisgICAgSEVMUENIRUNLKCJncnVtbWVsIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJHcnVtbWxlIHdpZT9cbiIpOworICAgIG91dF9zZWw9IkR1IGdydW1tZWxzdEBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgZ3J1bW1lbHRAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogR3J1bnplbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiZ3J1bnoiOgorICAgIEhFTFBDSEVDSygiZ3J1bnoiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIkdydW56ZSB3aWU/XG4iKTsKKyAgICBvdXRfc2VsPSJEdSBncnVuenRAQGFkdmVyYkBALiI7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIGdydW56dEBAYWR2ZXJiQEAuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBHdWNrZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImd1Y2siOgorICAgIEhFTFBDSEVDSygiZ3VjayIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghYWR2ZXJiKQorICAgICAgUmV0dXJuKCJHdWNrZSB3aWUgYXVzIGRlciBXYWVzY2hlP1xuIik7CisgICAgb3V0X3NlbD0iRHUgZ3Vja3N0QEBhZHZlcmJAQCBhdXMgZGVyIFdhZXNjaGUuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgZ3Vja3RAQGFkdmVyYkBAIGF1cyBkZXIgV2Flc2NoZS4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEphbW1lcm4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImphbW1lciI6CisgICAgSEVMUENIRUNLKCJqYW1tZXIiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIldpZSB3aWxsc3QgRHUgamFtbWVybj9cbiIpOworICAgIG91dF9zZWw9IkR1IGphbW1lcnN0QEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBqYW1tZXJ0QEBhZHZlcmJAQC4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEhhZXRzY2hlbG4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImhhZXRzY2hlbCI6CisgICAgY2FzZSAiaGFldHNjaGwiOgorICAgIEhFTFBDSEVDSygiaGFldHNjaGVsIik7CisgICAgR0hPU1RDSEVDSygiRHUgdWViZXJsZWdzdCBlcyBEaXIgYW5kZXJzIC0gbWl0IERlaW5lbiBkdXJjaGxhZXNzaWdlbiAiCisgICAgICAgICsiSGFlbmRlbi4uLiIsCisgICAgICBnbmFtZSgpKyIgd2lsbCBhbnNjaGVpbmVuZCBqZW1hbmQgaGFldHNjaGVsbiwgdWViZXJsZWd0XG4iCisgICAgICAgICsiZXMgc2ljaCBuYWNoIGVpbmVtIGt1cnplbiBCbGljayBhdWYgc2VpbmUgSGFlbmRlIGFuZGVycy5cbiIsIDApOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChmb3JfYWxsKSAgeworICAgICAgb3V0X3NlbD0iRHUgaGFldHNjaGVsc3QgQEBhbGxlQEBAQGFkdmVyYkBALiI7CisgICAgICBvdXRfdmljPSJAQG5hbWVAQCBoYWV0c2NoZWx0IEBAYWxsZUBAQEBhZHZlcmJAQC4iOworICAgICAgcmV0dXJuIE1peGVkT3V0KFdFTik7CisgICAgfQorICAgIGlmICghc3RyIHx8ICF3aG8pCisgICAgICBSZXR1cm4oIldlbiB3aWxsc3QgRHUgaGFldHNjaGVsbj9cbiIpOworICAgIGlmICh3aG8gJiYgQ2hlY2tMaWZlKE5PVF9TRUxGLCBOT1RfREVBRCwKKyAgICAgICJEYXMgc2llaHQgdmllbCB6dSBhbGJlcm4gYXVzIC0gRHUgbGFlc3N0IGVzIGJsZWliZW4uIiwKKyAgICAgICJJc3QgZGEgdWViZXJoYXVwdCB3YXMgenUgaGFldHNjaGVsbj8gTmVpbiwgZGEgbGVidCBkb2NoIG5peC4iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgb3V0X3NlbD0iRHUgaGFldHNjaGVsc3RAQCB3ZW5AQEBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfdmljPSJAQG5hbWVAQCBoYWV0c2NoZWx0IERpY2hAQGFkdmVyYkBALiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAgaGFldHNjaGVsdEBAIHdlbkBAQEBhZHZlcmJAQC4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEhpY2tzZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImhpY2tzIjoKKyAgICBIRUxQQ0hFQ0soImhpY2tzIik7CisgICAgR0hPU1RDSEVDSygiSG9wcGxhISBEaWVzZXIgSGlja3NlciB6aWVodCBEaWNoIGdhbnogc2Nob2VuIHp1c2FtbWVuIVxuIiwKKyAgICAgIGduYW1lKCkrIiBoYXQgYW5zY2hlaW5lbmQgU2NobHVja2F1Zi5cbiIKKyAgICAgICAgKyJVbmQgd2FzIGZ1ZXIgZWluZW4hIEZ1ZXIgZWluZW4gTW9tZW50IHppZWh0IGVzICIrUXVlcnlQcm9ub3VuKFdFTikKKyAgICAgICAgKyIgemllbWxpY2ggenVzYW1tZW4uXG4iLCAwKTsKKyAgICBpZiAoIXN0cikgIHsKKyAgICAgIG91dF9zZWw9IkhpY2tzISI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCBtdXNzIGhpY2tzZW4uIFdhaHJzY2hlaW5saWNoIHp1IHZpZWwgQWxrb2hvbC4uLiI7CisgICAgfQorICAgIGVsc2UgIHsKKyAgICAgIFBhcnNlUmVzdChzdHIpOworICAgICAgaWYgKCFhZHZlcmIpCisgICAgICAgIFJldHVybigiSGlja3NlIHdpZT9cbiIpOworICAgICAgb3V0X3NlbD0iRHUgaGlja3N0QEBhZHZlcmJAQC4iOworICAgICAgb3V0X290aD0iQEBuYW1lQEAgaGlja3N0QEBhZHZlcmJAQC4iOworICAgIH0KKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBIdWVwZmVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJodWVwZiI6CisgICAgSEVMUENIRUNLKCJodWVwZiIpOworICAgIEdIT1NUQ0hFQ0soIkR1IHNjaHdlYnN0IGR1cmNoIGRpZSBHZWdlbmQuXG4iLAorICAgICAgZ25hbWUoKSsiIHNjaHdlYnQgZHVyY2ggZGllIEdlZ2VuZC5cbiIsIDApOworICAgIGlmICghc3RyKSAgeworICAgICAgb3V0X3NlbD0iQiBPIEkgTiBHICEhIER1IGh1ZXBmc3QgaW4gZGVyIEdlZ2VuZCBoZXJ1bS4iOworICAgICAgb3V0X290aD0iQEBuYW1lQEAgaHVlcGZ0IGluIGRlciBHZWdlbmQgaGVydW0uIjsKKyAgICB9CisgICAgZWxzZSAgeworICAgICAgUGFyc2VSZXN0KHN0cik7CisgICAgICBpZiAoIXdobyAmJiAhYWR2ZXJiKQorICAgICAgICBSZXR1cm4oIkh1ZXBmZSB3aWUgb2RlciB1bSB3ZW4gb2RlciB3aWUgb2RlciB3YXMgb2RlciBoYWVoP1xuIik7CisgICAgICBvdXRfc2VsPSJEdSBodWVwZnN0QEBhZHZlcmJAQCIrKHdobyA/ICIgdW1AQCB3ZW5AQCIgOiAiIikrIiBoZXJ1bS4iOworICAgICAgaWYgKHdobykgb3V0X3ZpYz0iQEBuYW1lQEAgaHVlcGZ0QEBhZHZlcmJAQCB1bSBEaWNoIGhlcnVtLiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCBodWVwZnRAQGFkdmVyYkBAIisod2hvID8gIiB1bUBAIHdlbkBAIiA6ICIiKSsiIGhlcnVtLiI7CisgICAgfQorICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEh1c3RlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiaHVzdCI6CisgICAgSEVMUENIRUNLKCJodXN0Iik7CisgICAgR0hPU1RDSEVDSygiRHUgdmVyc3RyZXVzdCBlaW4gcGFhciBHZWlzdGVyYmF6aWxsZW4gaW0gUmF1bS5cbiIsCisgICAgICBnbmFtZSgpKyIgbWFjaHQgdWZmZiwgdWZmZiB1bmQgdmVydGVpbHQgZWluIHBhYXIgR2Vpc3Rlci1cbiIKKyAgICAgICAgKyJiYXppbGxlbiBpbSBSYXVtLlxuIiwgMCk7CisgICAgaWYgKCFzdHIpICB7CisgICAgICBvdXRfc2VsPSJIdXN0ISBLZXVjaCEgSGFsdCBkaXIgZG9jaCB3ZW5pZ3N0ZW5zIGRpZSBIYW5kIHZvciBkZW4gTXVuZCEiOworICAgICAgb3V0X290aD0iQEBuYW1lQEAgaHVzdGV0IHNpY2ggZmFzdCBkaWUgU2VlbGUgYXVzIGRlbSBMZWliLiI7CisgICAgfQorICAgIGVsc2UgIHsKKyAgICAgIFBhcnNlUmVzdChzdHIpOworICAgICAgaWYgKCF3aG8gJiYgIWFkdmVyYikKKyAgICAgICAgUmV0dXJuKCJXZW5uIER1IHNjaG9uIHdhcyBoaW50ZXIgaHVzdGUgdGlwcHN0LCBkYW5uIGJpdHRlIHdhcyAiCisgICAgICAgICAgKyJ2ZXJudWVuZnRpZ2VzIVxuIik7CisgICAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICAgIkRpciBzZWxiZXIga29lbm5lbiBudXIgYW5kZXJlIHdhcyBodXN0ZW4uIiwKKyAgICAgICAgIkJpdHRlIGh1c3RlIG51ciBMZWJld2VzZW4gd2FzLiIpKQorICAgICAgICAgIHJldHVybiAxOworICAgICAgb3V0X3NlbD0iRHUgaHVzdGVzdEBAIHdlbUBAQEBhZHZlcmJAQCIrKHdobz8gIiB3YXMiIDogIiIpKyIuIjsKKyAgICAgIGlmICh3aG8pIG91dF92aWM9IkBAbmFtZUBAIGh1c3RldCBEaXJAQGFkdmVyYkBAd2FzLiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCBodXN0ZXRAQCB3ZW1AQEBAYWR2ZXJiQEAiKyh3aG8/ICIgd2FzIiA6ICIiKSsiLiI7CisgICAgfQorICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEp1YmVsbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAianViZWwiOgorICAgIGNhc2UgImp1YmwiOgorICAgIEhFTFBDSEVDSygianViZWwiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICF3aG8gJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiSnVibGUgd2llPyBPZGVyIHdlbSB6dT9cbiIpOworICAgIG91dF9zZWw9IkR1IGp1YmVsc3RAQCB3ZW1AQEBAYWR2ZXJiQEAiKyh3aG8gPyAiIHp1LiIgOiAiLiIpOworICAgIGlmICh3aG8pIG91dF92aWM9IkBAZ25hbWVAQCBqdWJlbHQgRGlyQEBhZHZlcmJAQCB6dS4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBqdWJlbHRAQCB3ZW1AQEBAYWR2ZXJiQEAiKyh3aG8gPyAiIHp1LiIgOiAiLiIpOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEtldWNoZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImtldWNoIjoKKyAgICBIRUxQQ0hFQ0soImtldWNoIik7CisgICAgaWYgKGdob3N0KCkpCisgICAgICBSZXR1cm4oIkFscyBHZWlzdCBzdHJlbmd0IERpY2ggbml4IGFuIC0gYWxzbyB3aXJkIGF1Y2ggbmljaHQgIgorICAgICAgICArImdla2V1Y2h0LlxuIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJLZXVjaGUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUga2V1Y2hzdCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOiAiIHZvciBBbnN0cmVuZ3VuZy4iKTsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBrZXVjaHQiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQC4iIDogIiB2b3IgQW5zdHJlbmd1bmcuIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogS2ljaGVybiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAia2ljaGVyIjoKKyAgICBIRUxQQ0hFQ0soImtpY2hlciIpOworICAgIGlmICghc3RyKSAgeworICAgICAgb3V0X3NlbD0iRHUga2ljaGVyc3QuIChXaWUgYWxiZXJuIHZvbiBEaXIpIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCBnaWJ0IGVpbiBhbGJlcm5lcyBLaWNoZXJuIHZvbiBzaWNoLiI7CisgICAgfQorICAgIGVsc2UgIHsKKyAgICAgIFBhcnNlUmVzdChzdHIpOworICAgICAgaWYgKCF3aG8gJiYgIWFkdmVyYikKKyAgICAgICAgUmV0dXJuKCJEYXMgaGF1dCBzbyBuaWNodCBoaW4sIGdpYiB2ZXJudWVuZnRpZ2UgUGFyYW1ldGVyLlxuIik7CisgICAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICAgIkluIGRpZXNlbSBGYWxsIG5pbW0gYml0dGUgbnVyIGtpY2hlci4iLAorICAgICAgICAiTXVzc3Qgc2Nob24gZXR3YXMgTGViZW5kZXMgYW5nZWJlbiwgbmljaHRzIFRvdGVzLiIpKQorICAgICAgICAgIHJldHVybiAxOworICAgICAgb3V0X3NlbD0iRHUga2ljaGVyc3RAQGFkdmVyYkBAIisod2hvID8gIiBoaW50ZXIgIit3aG8tPm5hbWUoV0VTU0VOKSsKKyAgICAgICAgIiBSdWVja2VuLiIgOiAiLiIpOworICAgICAgaWYgKHdobykgIG91dF92aWM9IkplbWFuZCBraWNoZXJ0QEBhZHZlcmJAQCBoaW50ZXIgZGVpbmVtIFJ1ZWNrZW4uIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCBraWNoZXJ0QEBhZHZlcmJAQCIrKHdobyA/ICIgaGludGVyICIrd2hvLT5uYW1lKFdFU1NFTikKKyAgICAgICAgKyIgUnVlY2tlbi4iIDogIi4iKTsKKyAgICB9CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogS2l0emVsbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAia2l0emVsIjoKKyAgICBjYXNlICJraXR6bCI6CisgICAgSEVMUENIRUNLKCJraXR6ZWwiKTsKKyAgICBHSE9TVENIRUNLKCJNaXQgRGVpbmVuIGltbWF0ZXJpZWxsZW4gRmluZ2VybiBzY2hhZmZzdCBEdSBkYXMgbmljaHQuXG4iLAorICAgICAgZ25hbWUoKSsiIG11c3MgZ2VyYWRlIGZlc3RzdGVsbGVuLCBkYXNzIG1hbiBtaXRcbiIKKyAgICAgICAgKyJpbW1hdGVyaWVsbGVuIEZpbmdlcm4gbmljaHQga2l0emVsbiBrYW5uLlxuIiwgMCk7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIldlbiB3aWxsc3QgRHUga2l0emVsbj9cbiIpOworICAgIGlmICh3aG8gJiYgQ2hlY2tMaWZlKE5PVF9TRUxGLE5PVF9ERUFELAorICAgICAgIkR1IGJpc3QgZG9jaCBrZWluIE1hc29jaGlzdCEgRHUgbGFlc3N0IGVzIGJsZWliZW4uIiwKKyAgICAgICJEaW5nZSBzaW5kIHNvIHNlbHRlbiBraXR6bGlnLiBMYXNzIGVzIGJsZWliZW4uIikpCisgICAgICAgIHJldHVybiAxOworICAgIGlmIChtZW1iZXIoKHsiaGlnaGxhbmRlciIsImhvYm8ifSksIHdoby0+cXVlcnlfcmVhbF9uYW1lKCkpPi0xKQorICAgICAgc3dpdGNoICh3aG8tPnF1ZXJ5X3JlYWxfbmFtZSgpKSAgeworICAgICAgICBjYXNlICJoaWdobGFuZGVyIjogc3RyMT0idW50ZXIiOyBzdHIyPSJGZWRlcm4iOyBicmVhazsKKyAgICAgICAgY2FzZSAiaG9ibyIgICAgICA6IHN0cjE9ImFuIjsgICAgc3RyMj0iS2lubiI7IGJyZWFrOworICAgICAgfQorICAgIGVsc2UgaWYgKHdoby0+UXVlcnlQcm9wKFBfUkFDRSkpCisgICAgICBzd2l0Y2ggKGxvd2VyX2Nhc2Uod2hvLT5RdWVyeVByb3AoUF9SQUNFKSkpICB7CisgICAgICAgIGNhc2UgImRyYWNoZSIgOiBzdHIxPSJ1bnRlciI7c3RyMj0iU2NodXBwZW4iOworICAgICAgICAgIHRfZz1GRU1BTEU7IHRfbj1QTFVSQUw7IGJyZWFrOworICAgICAgICBjYXNlICJncmVpZiIgIDogc3RyMT0idW50ZXIiO3N0cjI9IkZlZGVybiI7CisgICAgICAgICAgdF9nPUZFTUFMRTsgdF9uPVBMVVJBTDsgYnJlYWs7CisgICAgICAgIGRlZmF1bHQgICAgICAgOiBzdHIxPSJhbiI7IHN0cjI9Iktpbm4iOyB0X2c9TkVVVEVSOyB0X249U0lOR1VMQVI7CisgICAgICB9CisgICAgZWxzZSAgeworICAgICAgc3RyMT0iYW4iOyBzdHIyPSJLaW5uIjsgdF9nPU5FVVRFUjsgdF9uPVNJTkdVTEFSOworICAgIH0KKyAgICBpZiAoZ2V0dWlkKHdobyk9PSJ0cmVzdCIgfHwgZ2V0dWlkKHdobyk9PSJ3b2Vsa2NoZW4iKSAgeworICAgICAgc3RyMT0iYW4iOyBzdHIyPSJGdWVzc2VuIjsgdF9nPU1BTEU7IHRfbj1QTFVSQUw7CisgICAgfQorICAgIG91dF9zZWw9IkR1IGtpdHplbHN0QEAgd2VuQEBAQGFkdmVyYkBAICIrc3RyMSsiICIrd2hvLT5RUFAodF9nLFdFTSx0X24pCisgICAgICArIiAiK3N0cjIrIi5cbkBAd2VyQEAgdmVyc3VjaHQsIHNpY2ggenUgYmVoZXJyc2NoZW4sIG11c3MgYWJlciAiCisgICAgICArImRvY2ggbGFjaGVuLiI7CisgICAgb3V0X3ZpYz0iQEBuYW1lQEAga2l0emVsdCBEaWNoQEBhZHZlcmJAQCAiK3N0cjErIiBEZWluZSIKKyAgICAgICsodF9uID8gIm4iIDogKHRfZz09RkVNQUxFID8gInIiIDogIm0iKSkrIiAiK3N0cjIKKyAgICAgICsiLlxuRHUgdmVyc3VjaHN0LCBEaWNoIHp1IGJlaGVycnNjaGVuLCBtdXNzdCBhYmVyIGRvY2ggbGFjaGVuLiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAga2l0emVsdEBAIHdlbkBAQEBhZHZlcmJAQCAiK3N0cjErIiAiCisgICAgICArd2hvLT5RUFAodF9nLFdFTSx0X24pKyIgIitzdHIyCisgICAgICArIi5cbkBAd2VyQEAgdmVyc3VjaHQsIHNpY2ggenUgYmVoZXJyc2NoZW4sIG11c3MgYWJlciBkb2NoIGxhY2hlbi4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEtsYXRzY2hlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAia2xhdHNjaCI6CisgICAgSEVMUENIRUNLKCJrbGF0c2NoIik7CisgICAgR0hPU1RDSEVDSygiRGVpbmUgSGFlbmRlIHNhdXNlbiBkdXJjaGVpbmFuZGVyIGR1cmNoLlxuIiwKKyAgICAgIGduYW1lKCkrIiB3aWxsIGluIGRpZSBIYWVuZGUga2xhdHNjaGVuIC0gYWJlciBzaWVcbiIKKyAgICAgICAgKyJzYXVzZW4gZHVyY2hlaW5hbmRlciBkdXJjaC5cbiIsIDApOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghYWR2ZXJiICYmIHN0cikKKyAgICAgIFJldHVybigiS2xhdHNjaGUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUga2xhdHNjaHN0QEBhZHZlcmJAQCBpbiBkaWUgSGFlbmRlLiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAga2xhdHNjaHRAQGFkdmVyYkBAIGluIGRpZSBIYWVuZGUuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBLbG9wZmVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJrbG9wZiI6CisgICAgSEVMUENIRUNLKCJrbG9wZiIpOworICAgIGlmICghc3RyfHxzc2NhbmYoc3RyLCIlcyBhdWYgc2NodWx0ZXIiLHNmb28pIT0xKQorICAgICAgaWYgKCFzdHJ8fHNzY2FuZihzdHIsIiVzIGF1ZiBkaWUgc2NodWx0ZXIiLHNmb28pIT0xKQorICAgICAgICBSZXR1cm4oIktsb3BmZSB3aWUgd2VtIHdpZXNvIHdhcz9cbiIpOworICAgIGlmIChnaG9zdCgpKQorICAgICAgUmV0dXJuKCJEYXMgZ2VodCBsZWlkZXIgbmljaHQgbWl0IGR1cmNobGFlc3NpZ2VuIEhhZW5kZW4uXG4iKTsKKyAgICBzdHI9c2ZvbzsKKyAgICBpZiAoc3RyPT0iIikgc3RyPTA7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIktsb3BmZSB3ZW0gYXVmIGRpZSBTY2h1bHRlcj9cbiIpOworICAgIG91dF9zZWw9IkR1IGtsb3Bmc3QgQEB3ZW1AQEBAYWR2ZXJiQEAgYXVmIGRpZSBTY2h1bHRlci4iOworICAgIG91dF92aWM9IkBAbmFtZUBAIGtsb3BmdCBEaXJAQGFkdmVyYkBAIGF1ZiBkaWUgU2NodWx0ZXIuIjsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBrbG9wZnQgQEB3ZW1AQEBAYWR2ZXJiQEAgYXVmIGRpZSBTY2h1bHRlci4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEtuYWJiZXJuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJrbmFiYmVyIjoKKyAgICBIRUxQQ0hFQ0soImtuYWJiZXIiKTsKKyAgICBpZiAoZ2hvc3QoKSkKKyAgICAgIFJldHVybigiU29ycnksIGFiZXIgZGFmdWVyIGZlaGx0IERpciBpbSBNb21lbnQgZGVyIG5vZXRpZ2UgIgorICAgICAgICArIlwiQmlzc1wiLi4uXG4iKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiS25hYmJlcmUgd2VuIGFuP1xuIik7CisgICAgaWYgKENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICJEdSBrb21tc3QgbmljaHQgYW4gZGVpbiBlaWdlbmVzIE9ociByYW4uLi4iLAorICAgICAgIk5vZSwgbm9lLCBkYXMgc2NobWVja3QgYmVzdGltbXQgbmljaHQgZ3V0LiIpKQorICAgICAgICByZXR1cm4gMTsKKyAgICBvdXRfc2VsPSJEdSBrbmFiYmVyc3RAQGFkdmVyYkBAIGFuICIrd2hvLT5uYW1lKFdFU1NFTikrIiBPaHIuIjsKKyAgICBvdXRfdmljPSJAQG5hbWVAQCBrbmFiYmVydEBAYWR2ZXJiQEAgYW4gRGVpbmVtIE9oci4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIGtuYWJiZXJ0QEBhZHZlcmJAQCBhbiAiK3doby0+bmFtZShXRVNTRU4pKyIgT2hyLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogS25pY2tzZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImtuaWNrcyI6CisgICAgSEVMUENIRUNLKCJrbmlja3MiKTsKKyAgICBHSE9TVENIRUNLKCJEdSBrbmlja3N0IGluIGRlciBNaXR0ZSBhYiwga3JpZWdzdCBEaWNoIGFiZXIgc2NobmVsbCB3aWVkZXIgIgorICAgICAgICArInp1c2FtbWVuLlxuIiwKKyAgICAgIGduYW1lKCkrIiBrbmljayhzKXQgaW4gZGVyIE1pdHRlIGFiLCBrcmllZ3Qgc2ljaCBhYmVyXG4iCisgICAgICAgICsienVtIEdsdWVjayBzY2huZWxsIHdpZWRlciB6dXNhbW1lbi5cbiIsIDApOworICAgIGlmICghc3RyKSB7CisgICAgICBvdXRfc2VsPSJEdSBtYWNoc3QgZWluZW4gYW5tdXRpZ2VuIEtuaWNrcy4iOworICAgICAgb3V0X290aD0iQEBuYW1lQEAgbWFjaHQgZWluZW4gYW5tdXRpZ2VuIEtuaWNrcy4iOworICAgIH0KKyAgICBlbHNlICB7CisgICAgICBQYXJzZVJlc3Qoc3RyLCJ2b3IiKTsKKyAgICAgIGlmIChmb3JfYWxsKSAgeworICAgICAgICBvdXRfc2VsPSJEdSBrbmlja3N0QEBhZHZlcmJAQCB2b3IgQEBhbGxlQEAuIjsKKyAgICAgICAgb3V0X3ZpYz0iQEBuYW1lQEAga25pY2tzdEBAYWR2ZXJiQEAgdm9yIEBAYWxsZUBALiI7CisgICAgICAgIHJldHVybiBNaXhlZE91dChXRU0pOworICAgICAgfQorICAgICAgaWYgKCF3aG8gJiYgIWFkdmVyYikKKyAgICAgICAgUmV0dXJuKCJLbmlja3NlIGlyZ2VuZHdpZSBvZGVyIHZvciBqZW1hbmRlbS5cbiIpOworICAgICAgaWYgKHdobyAmJiBDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAgICJXaWUgd2lsbHN0IER1IGRhcyBkZW5uIHNjaGFmZmVuPyIsCisgICAgICAgICJWb3IgU2FjaGVuIHdpcmQgaGllciBuaWNodCBnZWtuaWNrc3QhIikpCisgICAgICAgICAgcmV0dXJuIDE7CisgICAgICBvdXRfc2VsPSJEdSBrbmlja3N0QEBhZHZlcmJAQCIrKHdobyA/ICIgdm9yIiA6ICIiKSsiQEAgd2VtQEAuIjsKKyAgICAgIGlmICh3aG8gKSBvdXRfdmljPSJAQG5hbWVAQCBrbmlja3N0QEBhZHZlcmJAQCB2b3IgRGlyLiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCBrbmlja3N0QEBhZHZlcmJAQCIrKHdobyA/ICIgdm9yIiA6ICIiKSsiQEAgd2VtQEAuIjsKKyAgICB9CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogS25pcnNjaGVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJrbmlyc2NoIjoKKyAgICBIRUxQQ0hFQ0soImtuaXJzY2giKTsKKyAgICBpZiAoZ2hvc3QoKSkKKyAgICAgIFJldHVybigiRHUga2FubnN0IG1pdCBuaWNodHMga25pcnNjaGVuLCBzbyBhbHMgR2Vpc3QuIFZlcnN1Y2hlIGRvY2ggIgorICAgICAgICArImRhZnVlclxubWFsLCB6dSByYXNzZWxuLi4uXG4iKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIktuaXJzY2hlIHdpZT9cbiIpOworICAgIHN3aXRjaCAoUXVlcnlQcm9wKFBfUkFDRSkpICB7CisgICAgICBjYXNlICJncmVpZiIgIDogc3RyMT0iZGVtIFNjaG5hYmVsLiI7IGJyZWFrOworICAgICAgY2FzZSAic2FuZHRpZ2VyIiA6IHN0cjE9ImRlbiBGYW5nemFlaG5lbi4iOyBicmVhazsKKyAgICAgIGNhc2UgImRyYWNoZSIgOiBzdHIxPSJkZW4gRmFuZ3phZWhuZW4uIjsgYnJlYWs7CisgICAgICBkZWZhdWx0ICAgICAgIDogc3RyMT0iZGVuIFphZWhuZW4uIjsKKyAgICB9CisgICAgb3V0X3NlbD0iRHUga25pcnNjaHN0QEBhZHZlcmJAQCBtaXQgIitzdHIxOworICAgIG91dF9vdGg9IkBAbmFtZUBAIGtuaXJzY2h0QEBhZHZlcmJAQCBtaXQgIitzdHIxOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEtudWRkZWxuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJrbnVkZGVsIjoKKyAgICBjYXNlICJrbnVkZGwiOgorICAgIEhFTFBDSEVDSygia251ZGRlbCIpOworICAgIGlmIChnaG9zdCgpKQorICAgICAgUmV0dXJuKCJTb3JyeSwgbmljaHQgYWxzIEdlaXN0LlxuIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKGZvcl9hbGwpICB7CisgICAgICBvdXRfc2VsPSJEdSBrbnVkZGVsc3QgQEBhbGxlQEBAQGFkdmVyYkBALiI7CisgICAgICBvdXRfdmljPSJAQG5hbWVAQCBrbnVkZGVsdCBAQGFsbGVAQEBAYWR2ZXJiQEAuIjsKKyAgICAgIHJldHVybiBNaXhlZE91dChXRU4pOworICAgIH0KKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiS251ZGRsZSB3ZW4/XG4iKTsKKyAgICBpZiAoQ2hlY2tMaWZlKE5PVF9TRUxGLE5PVF9ERUFELAorICAgICAgIkRhcyBicmluZ3QgZG9jaCBuaXgsIGxhc3MgZXMgaGFsdC4iLAorICAgICAgIkR1IGthbm5zdCBzb3ZpZWwgaWNoIHdlaXNzIGF1c3NlciBMZWJld2VzZW4gbnVyIFRlZGR5cyBrbnVkZGVsbi4iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgb3V0X3NlbD0iRHUga251ZGRlbHN0QEAgd2VuQEBAQGFkdmVyYkBALiI7CisgICAgb3V0X3ZpYz0iQEBuYW1lQEAga251ZGRlbHQgRGljaEBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBrbnVkZGVsdEBAIHdlbkBAQEBhZHZlcmJAQC4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEtudXJyZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImtudXJyIjoKKyAgICBIRUxQQ0hFQ0soImtudXJyIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKGZvcl9hbGwpICB7CisgICAgICBvdXRfc2VsPSJEdSBrbnVycnN0IEBAYWxsZUBAQEBhZHZlcmJAQCBhbi4iOworICAgICAgb3V0X3ZpYz0iQEBnbmFtZUBAIGtudXJydCBAQGFsbGVAQEBAYWR2ZXJiQEAgYW4uIjsKKyAgICAgIHJldHVybiBNaXhlZE91dChXRU4pOworICAgIH0KKyAgICBpZiAoc3RyICYmICF3aG8gJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiV2VuIGFua251cnJlbiBvZGVyIHdpZSBrbnVycmVuP1xuIik7CisgICAgaWYgKHdobyAmJiBDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAiRHUga251cnJzdCBpbiBEaWNoIGhpbmVpbi4iLAorICAgICAgIlJlYWdpZXJ0IG5pY2h0LiBTb2xsdGVzdCB3b2hsIGJlc3NlciBMZWJ3ZXNlbiBhbmtudXJyZW4uIikpCisgICAgICAgIHJldHVybiAxOworICAgIG91dF9zZWw9IkR1IGtudXJyc3RAQCB3ZW5AQEBAYWR2ZXJiQEAiKyh3aG8gPyAiIGFuLiIgOiAiLiIpOworICAgIGlmICh3aG8pIG91dF92aWM9IkBAZ25hbWVAQCBrbnVycnQgRGljaEBAYWR2ZXJiQEAgYW4uIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAga251cnJ0QEAgd2VuQEBAQGFkdmVyYkBAIisod2hvID8gIiBhbi4iIDogIi4iKTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiAgS251dHNjaGVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJrbnV0c2NoIjoKKyAgICBIRUxQQ0hFQ0soImtudXRzY2giKTsKKyAgICBpZiAoZ2hvc3QoKSkKKyAgICAgIFJldHVybigiRGFzIGthbm5zdCBEdSBhbHMgR2Vpc3QgbGVpZGVyIG5pY2h0LiBJcmdlbmR3aWUgZmVobHQgRGlyICIKKyAgICAgICAgKyJkYXp1IGRhcyBIZXJ6LlxuIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIktudXRzY2hlIHdlbiBhYj9cbiIpOworICAgIGlmIChDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAiRGFzIGdlaHQgbmljaHQuIiwKKyAgICAgICJJZ2l0dCEgTGllYmVyIG5pY2h0ISIpKQorICAgICAgICByZXR1cm4gMTsKKyAgICBvdXRfc2VsPSJEdSBnaWJzdCBAQHdlbUBAQEBhZHZlcmJAQCBlaW5lbiBSSUNIVElHRU4gS3Vzcy4iOworICAgIG91dF92aWM9IkBAbmFtZUBAIGdpYnQgRGlyQEBhZHZlcmJAQCBlaW5lbiB0aWVmZW4gdW5kIGhpbmdlYnVuZ3N2b2xsZW4gIgorICAgICAgKyJLdXNzLlxuRHUgc2Nod2Vic3QgaW0gNy4gSGltbWVsLiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAgZ2lidCBAQHdlbUBAQEBhZHZlcmJAQCBlaW5lbiB0aWVmZW4gdW5kICIKKyAgICAgICsiaGluZ2VidW5nc3ZvbGxlbiBLdXNzLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogS290emVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJrb3R6IjoKKyAgICBIRUxQQ0hFQ0soImtvdHoiKTsKKyAgICBpZiAoZ2hvc3QoKSkKKyAgICAgIFJldHVybigiTmUsIGRhcyBpc3QgZWlucyB2b24gZGVuIFNhY2hlbiwgZGllIGFscyBHZWlzdCBuaWNodCBnZWhlbi5cbiIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIXdobyAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJLb3R6ZSB3aWU/IEtvdHplIGF1ZiB3ZW4/XG4iKTsKKyAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRiwwLAorICAgICAgIklnaXR0LCBuZWluIGRhbmtlLiIpKQorICAgICAgICByZXR1cm4gMTsKKyAgICBpZighc3RyKSB7CisgICAgICBvdXRfc2VsPSJEdSBrb3R6dCB1ZWJlciBkZWluZSBTY2h1aGUuIjsKKyAgICAgIG91dF9vdGg9IkBAbmFtZUBAIHZlcmRyZWh0IGRpZSBBdWdlbiB1bmQga290enQuIjsKKyAgICB9CisgICAgZWxzZSAgeworICAgICAgb3V0X3NlbD0iRHUga290enRAQGFkdmVyYkBAIisod2hvID8gIiBhdWYgQEB3ZW5AQC4iIDogIi4iKTsKKyAgICAgIGlmICh3aG8pIG91dF92aWM9IkBAbmFtZUBAIGtvdHp0QEBhZHZlcmJAQCBhdWYgRGljaC4iOworICAgICAgb3V0X290aD0iQEBuYW1lQEAga290enRAQGFkdmVyYkBAIisod2hvID8gIiBhdWYgQEB3ZW5AQC4iIDogIi4iKTsKKyAgICB9CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogS3JhdHplbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAia3JhdHoiOgorICAgIEhFTFBDSEVDSygia3JhdHoiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAod2hvICYmICh3aG8hPXRoaXNfcGxheWVyKCkpKQorICAgICAgUmV0dXJuKCJEYXMgbWFjaCBtYWwgc2Nob2VuIG51ciBtaXQgRGlyIHNlbGJlci5cbiIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiV2llIHdpbGxzdCBEdSBEaWNoIGtyYXR6ZW4/XG4iKTsKKyAgICBvdXRfc2VsPSJEdSBrcmF0enQgZGljaEBAYWR2ZXJiQEAgYW0gS29wcC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBrcmF0enQgc2ljaEBAYWR2ZXJiQEAgYW0gS29wcC4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEtyaWVjaGUgKioqKioqKioqKioqKioqLworICAgIGNhc2UgImtyaWVjaCI6CisgICAgSEVMUENIRUNLKCJrcmllY2giKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBvdXRfc2VsPSJEdSBrcmllY2hzdCIrKHdobyA/ICIgdm9yIEBAd2VtQEAiIDogIiIpKyJAQGFkdmVyYkBAIGltIFN0YXViLiI7CisgICAgaWYgKHdobykgb3V0X3ZpYz0iQEBnbmFtZUBAIGtyaWVjaHRAQGFkdmVyYkBAIHZvciBEaXIgaW0gU3RhdWIuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAga3JpZWNodCIrKHdobyA/ICIgdm9yIEBAd2VtQEAiIDogIiIpCisgICAgICArIkBAYWR2ZXJiQEAgaW0gU3RhdWIuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBLdWVzc2VuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJrdWVzcyI6CisgICAgSEVMUENIRUNLKCJrdWVzcyIpOworICAgIGlmIChnaG9zdCgpKQorICAgICAgUmV0dXJuKCJBbHMgR2Vpc3Qga2FubnN0IER1IGxlaWRlciBuaWVtYW5kZW4ga3Vlc3Nlbi5cbiIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghd2hvKQorICAgICAgUmV0dXJuKCJXZW4gd2lsbHN0IER1IGt1ZXNzZW4/XG4iKTsKKyAgICBpZiAoQ2hlY2tMaWZlKE5PVF9TRUxGLE5PVF9ERUFELAorICAgICAgIkRhIGhhc3QgRHUgYWJlciBTY2h3aWVyaWdrZWl0ZW4uLi4gRHUgZ2lic3QgZXMgc2NobGllc3NsaWNoIGF1Zi4iLAorICAgICAgIk5peC4gQWJzb2x1dCBuaXguIEt1ZXNzZSBsaWViZXIgTGViZXdlc2VuIC0gZGllIHJlYWdpZXJlblxuIgorICAgICAgICArIndlbmlnc3RlbnMgKHVuZCBzZWkgZXMsIGRhc3Mgc2llIERpY2ggZnJlc3Nlbi4uLikuIikpCisgICAgICAgIHJldHVybiAxOworICAgIG91dF9zZWw9IkR1IGt1ZXNzdEBAIHdlbkBAQEBhZHZlcmJAQC4iOworICAgIG91dF92aWM9IkBAbmFtZUBAIGt1ZXNzdCBEaWNoQEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIGt1ZXNzdEBAIHdlbkBAQEBhZHZlcmJAQC4iOworICAgIEZlZWxJdCgpOworICAgIGlmICh3aG8tPlF1ZXJ5UHJvcChQX0ZST0cpJiZRdWVyeVByb3AoUF9MRVZFTCk+d2hvLT5RdWVyeVByb3AoUF9MRVZFTCkpIHsKKyAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCh0aGlzX3BsYXllcigpKSwiUExPUFAhXG4iKTsKKyAgICAgIHdyaXRlKCJIdWNoISBEdSB3aXJzdCBhdWYgZWlubWFsIHNvIGdydWVuIHVuZCBrbGVpbiB1bmQga3JpZWdzdCBhdWZcbiIKKyAgICAgICAgKyJlaW5tYWwgZnVyY2h0YmFyIEh1bmdlciBhdWYgRmxpZWdlbiB1bmQgc28uLi5cbiIpOworICAgICAgd2hvLT5NZXNzYWdlKCJBdWYgZWlubWFsIHdpcmQgZGllIFdlbHQgdW0gRGljaCB3aWVkZXIgc28ga2xlaW4sIHdpZSBzaWVcbiIKKyAgICAgICAgKyIgZnJ1ZWhlciBtYWwgd2FyIC0gdW5kIHZvciBEaXIgc2l0enQgZWluIGtsZWluZXIgZ3J1ZW5lciBGcm9zY2guXG4iKTsKKyAgICAgIHNheSh3aG8tPm5hbWUoV0VSKSsiIHN0ZWh0IGF1ZiBlaW5tYWwgZGEgdW5kIHNjaGF1dCBkdW1tIGF1cyBkZXIgIgorICAgICAgICArIldhZXNjaGUuIERhZnVlciBmZWhsdFxuamV0enQgc2VsdHNhbWVyd2Vpc2UgIitjYXBuYW1lKCkKKyAgICAgICAgKyIuIERpZSBHZXNhbXR6YWhsIGFuIGtsZWluZW4gZ3J1ZW5lblxuRnJvZXNjaGVuIGltIFJhdW0gaGF0IHNpY2ggIgorICAgICAgICArImplZG9jaCBuaWNodCBnZWFlbmRlcnQuLi5cbiIsKHt3aG8sdGhpc19wbGF5ZXIoKX0pKTsKKyAgICAgIHdoby0+U2V0UHJvcChQX0ZST0csMCk7CisgICAgICBTZXRQcm9wKFBfRlJPRywxKTsKKyAgICB9CisgICAgcmV0dXJuIDE7CisKKyAgICAvKioqKioqKioqKioqKioqKiBLdXNjaGVsbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAia3VzY2hlbCI6CisgICAgY2FzZSAia3VzY2hsIjoKKyAgICBIRUxQQ0hFQ0soImt1c2NoZWwiKTsKKyAgICBHSE9TVENIRUNLKCJEYXp1IGJpc3QgRHUgYWxzIEdlaXN0IHZpZWwgenUga2FsdCB1bmQgZ2FyICIKKyAgICAgICAgKyJzY2hyb2Vja2xpY2ggYW56dXNlaGVuLlxuIiwKKyAgICAgIGduYW1lKCkrIiBzY2hlaW50IEFud2FuZGx1bmdlbiB6dSBoYWJlbiwgc2ljaCBhbiBqZW1hbmQgIgorICAgICAgICArImFua3VzY2hlbG4genUgd29sbGVuLlxuRW50c2V0enQgc3ByaW5nZW4gYWxsZSB6dXJ1ZWNrLCB3ZWlsICIKKyAgICAgICAgKyJkYXp1IGlzdCBlciBkb2NoIHp1IGthbHQgdW5kIHNjaHJvZWNrbGljaFxuYW56dXNlaGVuLlxuIiwgMCk7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIkFuIHdlbiB3aWxsc3QgRHUgRGljaCBhbmt1c2NoZWxuP1xuIik7CisgICAgb3V0X3NlbD0iRHUga3VzY2hlbHN0IERpY2hAQGFkdmVyYkBAIGFuIEBAd2VuQEAgYW4uIjsKKyAgICBvdXRfdmljPSJAQG5hbWVAQCBrdXNjaGVsdCBzaWNoQEBhZHZlcmJAQCBhbiBEaWNoIGFuLiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAga3VzY2hlbHQgc2ljaEBAYWR2ZXJiQEAgYW4gQEB3ZW5AQCBhbi4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIExhY2hlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAibGFjaCI6CisgICAgSEVMUENIRUNLKCJsYWNoIik7CisgICAgR0hPU1RDSEVDSygiRHUgbGFjaHN0IG1pdCBob2hsZXIgU3RpbW1lLiBEZW4gVW1zdGVoZW5kZW4gKHNpbmQgZG9jaCB3ZWxjaGUiCisgICAgICAgICsiIGRhLCBvZGVyPylcbmxhZXVmdCBlcyBrYWx0IGRlbiBSdWVja2VuIHJ1bnRlci5cbiIsCisgICAgICBnbmFtZSgpKyIgbGFjaHQgbWl0IGhvaGxlciBTdGltbWUuXG5EaXIgbGFldWZ0IGVzIGVpc2thbHQgZGVuIFJ1ZWNrZW4iCisgICAgICAgICsiIHJ1bnRlci5cbiIsIDApOworICAgIGlmICghc3RyKSAgeworICAgICAgb3V0X3NlbD0iRHUgYnJpY2hzdCB2b3IgTGFjaGVuIHp1c2FtbWVuLiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCBicmljaHQgdm9yIExhY2hlbiB6dXNhbW1lbi4iOworICAgIH0KKyAgICBlbHNlICB7CisgICAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICAgIGlmIChmb3JfYWxsKSAgeworICAgICAgICBvdXRfc2VsPSJEdSBsYWNoc3RAQGFkdmVyYkBAIHVlYmVyIEBAYWxsZUBALiI7CisgICAgICAgIG91dF92aWM9IkBAbmFtZUBAIGxhY2h0QEBhZHZlcmJAQCB1ZWJlciBAQGFsbGVAQC4iOworICAgICAgICByZXR1cm4gTWl4ZWRPdXQoV0VOKTsKKyAgICAgIH0KKyAgICAgIGlmICghd2hvICYmICFhZHZlcmIpCisgICAgICAgIFJldHVybigiTGFjaGUgd2llLCBsYWNoZSB1ZWJlciB3ZW4/XG4iKTsKKyAgICAgIGlmICh3aG8gJiYgQ2hlY2tMaWZlKE5PVF9TRUxGLE5PVF9ERUFELAorICAgICAgICAiTGFjaCBEaWNoIGRvY2ggbmljaHQgc2VsYmVyIGF1cyAtIGRhcyBtYWNoZW4gc2Nob24gYW5kZXJlLi4uIiwKKyAgICAgICAgIkdlbGFjaHQgd2lyZCBudXIgdWViZXIgTGViZXdlc2VuIChkaWUga29lbm5lbiBzaWNoIGRydWViZXIgYWVyZ2VybikuIikpCisgICAgICAgICAgcmV0dXJuIDE7CisgICAgICBvdXRfc2VsPSJEdSBsYWNoc3RAQGFkdmVyYkBAIisod2hvPyIgdWViZXJAQCB3ZW5AQCI6IiIpKyIuIjsKKyAgICAgIGlmICh3aG8pIG91dF92aWM9IkBAbmFtZUBAIGxhY2h0QEBhZHZlcmJAQCB1ZWJlciBEaWNoLiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCBsYWNodEBAYWR2ZXJiQEAiKyh3aG8/IiB1ZWJlckBAIHdlbkBAIjoiIikrIi4iOworICAgIH0KKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBMYWVjaGVsbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAibGFlY2hlbCI6CisgICAgY2FzZSAibGFlY2hsIjoKKyAgICBIRUxQQ0hFQ0soImxhZWNoZWwiKTsKKyAgICBpZiAoZ2hvc3QoKSkgeworICAgICAgd3JpdGUoIkR1IGxhZWNoZWxzdCBpbm5lcmxpY2guXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBpZighc3RyKSB7CisgICAgICBvdXRfc2VsPSJEdSBsYWVjaGVsc3QuIjsKKyAgICAgIG91dF9vdGg9IkBAbmFtZUBAIGxhZWNoZWx0LiI7CisgICAgfQorICAgIGVsc2UgIHsKKyAgICAgIFBhcnNlUmVzdChzdHIpOworICAgICAgaWYgKGZvcl9hbGwpICB7CisgICAgICAgIG91dF9zZWw9IkR1IGxhZWNoZWxzdCBAQGFsbGVAQEBAYWR2ZXJiQEAgYW4uIjsKKyAgICAgICAgb3V0X3ZpYz0iQEBuYW1lQEAgbGFlY2hlbHQgQEBhbGxlQEBAQGFkdmVyYkBAIGFuLiI7CisgICAgICAgIHJldHVybiBNaXhlZE91dChXRU4pOworICAgICAgfQorICAgICAgaWYgKCF3aG8gJiYgIWFkdmVyYiAmJiBzdHIpCisgICAgICAgIFJldHVybigiV2llIG9kZXIgd2VuP1xuIik7CisgICAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICAgIk11c3N0IHNjaG9uIGplbWFuZCBhbmRlcnMgYW5sYWVjaGVsbi4iLAorICAgICAgICAiQml0dGUgZWluIExlYmV3ZXNlbiBhbmxhZWNoZWxuLiIpKQorICAgICAgICAgIHJldHVybiAxOworICAgICAgb3V0X3NlbD0iRHUgbGFlY2hlbHN0QEAgd2VuQEBAQGFkdmVyYkBAIisod2hvID8gIiBhbi4iIDogIi4iKTsKKyAgICAgIGlmICh3aG8pIG91dF92aWM9IkBAbmFtZUBAIGxhZWNoZWx0IERpY2hAQGFkdmVyYkBAIGFuLiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCBsYWVjaGVsdEBAIHdlbkBAQEBhZHZlcmJAQCIrKHdobyA/ICIgYW4uIiA6ICIuIik7CisgICAgfQorICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIExpZWJlICoqKioqKioqKioqKioqKi8KKyAgICAvKiBUaGVzZSBsaW5lcyBhcHBlYXIgQ291cnRlc3kgb2YgQW5ndXNATW9yZ2VuR3JhdWVuLiBTbyBsb25nLCBhbmQgdGhhbmtzICovCisgICAgLyogZm9yIGFsbCB0aGUgZmlzaCwgZXJyciwgdGV4dCwgQW5ndXMgOikgKi8KKyAgICBjYXNlICJsaWViIjoKKyAgICBIRUxQQ0hFQ0soImxpZWIiKTsKKyAgICBpZiAoZ2hvc3QoKSkKKyAgICAgIFJldHVybigiQXVmIGRpZXNlIEZyZXVkZW4gbXVzc3QgRHUgYWxzIEdlaXN0IGxlaWRlciB2ZXJ6aWNodGVuLlxuIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIldlbiBoYXN0IER1IGxpZWI/XG4iKTsKKyAgICBpZiAoQ2hlY2tMaWZlKE5PVF9TRUxGLE5PVF9ERUFELAorICAgICAgIkphLCBpY2ggd2Vpc3MsIER1IG1hZ3N0IERpY2gsIGFiZXIgZGFzIG11c3N0IER1IG5pY2h0IHp1ciBTY2hhdSIKKyAgICAgICAgKyJzdGVsbGVuLiIsCisgICAgICAiRHUgZW50d2lja2Vsc3Qgc2VsdHNhbWUgTmVpZ3VuZ2VuLCBmaW5kZSBpY2guIikpCisgICAgICAgIHJldHVybiAxOworICAgIHN0cjE9KHdoby0+UXVlcnlQcm9wKFBfR0VOREVSKT09RkVNQUxFID8gImlociIgOiAiaWhtIik7CisgICAgLyogb2xkIHZlcnNpb246CisgICAgICBvdXRfc2VsPSJEdSBmbHVlc3RlcnN0IEBAd2VtQEBAQGFkdmVyYkBAIGxpZWJldm9sbGUgV29ydGUgaW5zIE9oci4iOworICAgICAgb3V0X3ZpYz1nbmFtZSgpKyIgZmx1ZXN0ZXJ0IERpckBAYWR2ZXJiQEAgbGllYmV2b2xsZSBXb3J0ZSBpbnMgT2hyLiI7CisgICAgICBvdXRfb3RoPWduYW1lKCkrIiBmbHVlc3RlcnRAQGFkdmVyYkBAIHNhbmZ0ZSBXb3J0ZSB6dSBAQHdlbUBALiI7CisgICAgKi8KKyAgICBvdXRfc2VsPSJEdSBzY2hsaWVzc3QgZGllIEF1Z2VuLCBzY2htaWVnc3QgRGljaCBlbmcgYW4gQEB3ZW5AQCB1bmQgZ2lic3QiCisgICAgICArTEYrc3RyMSsiIGVpbmVuIHphZXJ0bGljaGVuIHVuZCBsZWlkZW5zY2hhZnRsaWNoZW4gS3Vzcy5cbiIKKyAgICAgICsiVW0gRGljaCBoZXJ1bSB2ZXJzaW5rdCBkaWUgV2VsdCB1bmQgRHUgZ2xhdWJzdCwgYXVmIFdvbGtlbiB6dSAiCisgICAgICArInNjaHdlYmVuLiI7CisgICAgb3V0X3ZpYz0iQEBuYW1lQEAgZHJ1ZWNrdCBEaWNoIHphZXJ0bGljaCBhbiBzaWNoIHVuZCBnaWJ0IERpclxuIgorICAgICAgKyJlaW5lbiB6YWVydGxpY2hlbiB1bmQgbGVpZGVuc2NoYWZ0bGljaGVuIEt1c3MuIER1IHNjaGxpZXNzdCBkaWVcbiIKKyAgICAgICsiQXVnZW4gdW5kIHRyYWV1bXN0IGVpbiB3ZW5pZy4uLi4uLkR1IHNjaHdlYnN0IGF1ZiBXb2xrZW4gZGlyZWt0XG4iCisgICAgICArImluIGRlbiBzaWVidGVuIEhpbW1lbC4iOworICAgIG91dF9vdGg9IkR1IHNjaGF1c3QgZGV6ZW50IHdlZywgYWxzIHNpY2ggQEBuYW1lQEAgdW5kICIrd2hvLT5uYW1lKCkKKyAgICAgICsiIHZlcmxpZWJ0IGluIGRpZSBBcm1lXG5zaW5rZW4uIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBMb2JlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAibG9iIjoKKyAgICBIRUxQQ0hFQ0soImxvYiIpOworICAgIGlmICghc3RyKQorICAgICAgUmV0dXJuKCJXZW4gb2RlciB3YXMgd2lsbHN0IER1IGxvYmVuP1xuIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHdobz09TUUpICB7CisgICAgICBvZm9vPWNsb25lX29iamVjdCgiL2l0ZW1zL2Z1cnoiKTsKKyAgICAgIG9mb28tPnNldF9mdXJ6ZXIodGhpc19wbGF5ZXIoKSk7CisgICAgICBvZm9vLT5zZXRfZWlnZW5sb2IoKTsKKyAgICAgIG9mb28tPm1vdmUoZW52aXJvbm1lbnQodGhpc19wbGF5ZXIoKSkpOworICAgICAgLy9ERUJVRyBGdXJ6IHp1bSBFaWdlbmxvYiBwYXRjaGVuIDo+CisgICAgICBvdXRfc2VsPSJEdSBsb2JzdCBEaWNoIHNlbGJlckBAYWR2ZXJiQEAuIERpZSBGb2xnZW4ga2VubnN0IER1IGphLi4uIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCBsb2J0IHNpY2ggc2VsYmVyQEBhZHZlcmJAQCwgbWl0IGRlbiBiZWthbm50ZW4gRm9sZ2VuLiI7CisgICAgfSBlbHNlIGlmICh3aG8pIHsKKyAgICAgIG91dF9zZWw9IkR1IGxvYnN0IEBAd2VuQEBAQGFkdmVyYkBALiI7CisgICAgICBvdXRfdmljPSJAQGduYW1lQEAgbG9idCBEaWNoQEBhZHZlcmJAQC4iOworICAgICAgb3V0X290aD0iQEBnbmFtZUBAIGxvYnQgQEB3ZW5AQEBAYWR2ZXJiQEAuIjsKKyAgICB9IGVsc2UgIHsKKyAgICAgIG91dF9zZWw9IkR1IGxvYnN0ICIrc3RyKyIuIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCBsb2J0ICIrc3RyKyIuIjsKKyAgICB9CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogTW9wcGVybiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAibW9wcGVyIjoKKyAgICBIRUxQQ0hFQ0soIm1vcHBlciIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiTW9wcGVyZSB3aWU/XG4iKTsKKyAgICBvdXRfc2VsPSJEdSBtb3BwZXJzdEBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgbW9wcGVydEBAYWR2ZXJiQEAuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBNdXN0ZXJuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJtdXN0ZXIiOgorICAgIEhFTFBDSEVDSygibXVzdGVyIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIk11c3RlcmUgd2VuP1xuIik7CisgICAgb3V0X3NlbD0iRHUgbXVzdGVyc3QgQEB3ZW5AQEBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfdmljPSJAQGduYW1lQEAgbXVzdGVydCBEaWNoQEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBtdXN0ZXJ0IEBAd2VuQEBAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogTmlja2VuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJqYSI6CisgICAgY2FzZSAibmljayI6CisgICAgSEVMUENIRUNLKCJuaWNrIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKGZvcl9hbGwpICB7CisgICAgICBvdXRfc2VsPSJEdSBuaWNrc3QgQEBhbGxlQEBAQGFkdmVyYkBAIHp1LiI7CisgICAgICBvdXRfdmljPSJAQGduYW1lQEAgbmlja3QgQEBhbGxlQEBAQGFkdmVyYkBAIHp1LiI7CisgICAgICByZXR1cm4gTWl4ZWRPdXQoV0VNKTsKKyAgICB9CisgICAgaWYgKHN0ciAmJiAhd2hvICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIk5pY2tlIHdpZSBvZGVyIHdlbSB6dSBvZGVyIHdlbSB3aWUgenU/XG4iKTsKKyAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICJEdSB3aWxsc3QgRGlyIHNlbGJlciB6dW5pY2tlbj8gTGllYmVyIG5pY2h0LCBkYXMgc2llaHQgc28gYWxiZXJuIGF1cy4iLAorICAgICAgIkhtLiBOaXggcGFzc2llcnQuIFZvbiBMZWJld2VzZW4gYmVrb21tdCBtYW4gbWVpc3RlbnMgbWVociBGZWVkYmFjay4iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgb3V0X3NlbD0iRHUgbmlja3N0QEAgd2VtQEBAQGFkdmVyYkBAIgorICAgICAgKyh3aG8gPyAiIHp1LiIgOiAoYWR2ZXJiID8gIi4iIDogIiB6dXN0aW1tZW5kLiIpKTsKKyAgICBpZiAod2hvKSBvdXRfdmljPSJAQGduYW1lQEAgbmlja3QgRGlyQEBhZHZlcmJAQCB6dS4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBuaWNrdEBAIHdlbUBAQEBhZHZlcmJAQCIKKyAgICAgICsod2hvID8gIiB6dS4iIDogKGFkdmVyYiA/ICIuIiA6ICIgenVzdGltbWVuZC4iKSk7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogTmllc2VuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJuaWVzIjoKKyAgICBIRUxQQ0hFQ0soIm5pZXMiKTsKKyAgICBpZiAoZ2hvc3QoKSkKKyAgICAgIFJldHVybigiRHUgaGFzdCBrZWluZSBOYXNlIG1laHIsIGluIGRlciBlcyBEaWNoIGp1Y2tlbiBrb2VubnRlLi4uXG4iKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIk5pZXNlIHdpZT9cbiIpOworICAgIG91dF9zZWw9IkhhYWFhYWEtdHNjaGkhIEdlc3VuZGhlaXQhIisoYWR2ZXJiID8gIiBEdSBuaWVzdEBAYWR2ZXJiQEAuIiA6ICIiKTsKKyAgICBvdXRfb3RoPSJIYWFhYWFhLXRzY2hpISBAQG5hbWVAQCBuaWVzdEBAYWR2ZXJiQEAuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBPaHJmZWlnZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImdpYiI6CisgICAgSEVMUENIRUNLKCJnaWIiKTsKKyAgICBpZiAoIXN0cikKKyAgICAgIFJldHVybigiR2liIHdlbSB3YXM/XG4iKTsKKyAgICBpZiAoc3NjYW5mKCBzdHIsIiVzIG9ocmZlaWdlIixzdHIxKT09MCkKKyAgICAgIHJldHVybiAwOworICAgIFBhcnNlUmVzdChzdHIsICh7Im9ocmZlaWdlIiwgImVpbmUgb2hyZmVpZ2UifSkpOworICAgIGlmIChmb3JfYWxsKSAgeworICAgICAgb3V0X3NlbD0iRHUgdmVycGFzc3QgQEBhbGxlQEBAQGFkdmVyYkBAIGVpbmUgT2hyZmVpZ2UuIjsKKyAgICAgIG91dF92aWM9IkBAbmFtZUBAIHZlcnBhc3N0IEBAYWxsZUBAQEBhZHZlcmJAQCBlaW5lIE9ocmZlaWdlLiI7CisgICAgICByZXR1cm4gTWl4ZWRPdXQoV0VNKTsKKyAgICB9CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIkdpYiB3ZW0gZWluZSBPaHJmZWlnZT9cbiIpOworICAgIGlmIChDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAiRGF6dSBzaW5kIERpciBEZWluZSBCYWNrZW4gZG9jaCB6dSBzY2hhZGUuIiwKKyAgICAgICJEdSB3aXJzdCBkb2NoIG5pY2h0cyBzY2hsYWdlbiwgd2FzIHNpY2ggbmljaHQgd2VocmVuIGthbm4/IikpCisgICAgICAgIHJldHVybiAxOworICAgIEdIT1NUQ0hFQ0soIkRlaW5lIEhhbmQgc2F1c3QgbWl0IHZvbGxlciBXdWNodCBkdXJjaCBkZWluIE9wZmVyIGR1cmNoISIsCisgICAgICBnbmFtZSgpKyIgd2lsbCAiK3doby0+bmFtZShXRU0pKyIgZWluZSBPaHJmZWlnZSBnZWJlbiAtIGFiZXIgZGllIEhhbmRcbiIKKyAgICAgICAgKyJzYXVzdCBtaXQgdm9sbGVyIFd1Y2h0IGR1cmNoIGRhcyBPcGZlciBkdXJjaCEiLCAwKTsKKyAgICBvdXRfc2VsPSJEdSB2ZXJwYXNzdCBAQHdlbUBAQEBhZHZlcmJAQCBlaW5lIHNjaGFsbGVuZGUgT2hyZmVpZ2UuIjsKKyAgICBvdXRfdmljPSJAQG5hbWVAQCB2ZXJwYXNzdCBEaXJAQGFkdmVyYkBAIGVpbmUgV2F0c2NoZSwgZGFzcyBEaXIgSG9lcmVuICIKKyAgICAgICsidW5kIFNlaGVuIHZlcmdlaHQuIjsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCB2ZXJwYXNzdCBAQHdlbUBAQEBhZHZlcmJAQCBlaW5lIHNjaGFsbGVuZGUgT2hyZmVpZ2UuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBQZmVpZmVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJwZmVpZiI6CisgICAgSEVMUENIRUNLKCJwZmVpZiIpOworICAgIEdIT1NUQ0hFQ0soIkVzIGtvbW10IGxlaWRlciBudXIgKG5pY2h0IG1hbCBoZWlzc2UpIEx1ZnQsIGFiZXIga2VpbiAiCisgICAgICAgICsiUGZpZmYuXG4iLAorICAgICAgZ25hbWUoKSsiIHNwaXR6dCBkZW4gTXVuZCB1bmQgcHVzdGV0IGFuZ2VzdHJlbmd0LiBOaWNodHMgcGFzc2llcnQuXG4iLCAwKTsKKyAgICBQYXJzZVJlc3Qoc3RyLCAibmFjaCIpOworICAgIGlmIChzdHIgJiYgIXdobyAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJQZmVpZmUgd2llPyBQZmVpZmUgd2VtIG5hY2g/IEhhZWg/XG4iKTsKKyAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICJXYXMgd2lsbHN0IER1IGRlbm4gZGFtaXQgYXVzZHJ1ZWNrZW4/IERhcyBnaWJ0IGZ1ZXIgbWljaCBrZWluZW4gU2lubi4iLAorICAgICAgIkljaCBoYWJlIGtlaW5lIEx1c3QgZGF6dS4iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgb3V0X3NlbD0iRHUgcGZlaWZzdEBAIHdlbkBAQEBhZHZlcmJAQCIKKyAgICAgICsod2hvID8gIiBuYWNoLiIgOiAoYWR2ZXJiID8gIi4iIDogIiBhbmVya2VubmVuZC4iKSk7CisgICAgaWYgKHdobykgb3V0X3ZpYz0iQEBuYW1lQEAgcGZlaWZ0IERpckBAYWR2ZXJiQEAgbmFjaC4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIHBmZWlmdEBAIHdlbkBAQEBhZHZlcmJAQCIKKyAgICAgICsod2hvID8gIiBuYWNoLiIgOiAoYWR2ZXJiID8gIi4iIDoiIGFuZXJrZW5uZW5kLiIpKTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBQaGlsb3NvcGhpZXJlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAicGhpbG9zb3BoaWVyIjoKKyAgICBIRUxQQ0hFQ0soInBoaWxvc29waGllciIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIG91dF9zZWw9IkR1IHBoaWxvc29waGllcnN0IisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAuIiA6CisgICAgICAoc3RyID8gIiB1ZWJlciAiK3N0cisiLiIgOiAiLiIpKTsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgcGhpbG9zb3BoaWVydCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOgorICAgICAgKHN0ciA/ICIgdWViZXIgIitzdHIrIi4iIDogIi4iKSk7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogKE5hc2UpIFB1dHplbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAicHV0eiI6CisgICAgSEVMUENIRUNLKCJwdXR6Iik7CisgICAgaWYgKGdob3N0KCkpCisgICAgICBSZXR1cm4oIk5peCBkYSB6dW0gUHV0emVuLCBzbyBuZWJ1bG9lcywgd2llIER1IGJpc3QuXG4iKTsKKyAgICBQYXJzZVJlc3Qoc3RyLCAoeyJuYXNlIiwgImRpZSBuYXNlIn0pKTsKKyAgICBpZiAoc3RyICYmIHN0ciE9Im5hc2UiICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIlB1dHplIERlaW5lIE5hc2Ugd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgcHV0enQgRGVpbmUgTmFzZUBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBwdXR6dEBAYWR2ZXJiQEAgIitRUFAoRkVNQUxFLFdFTikrIiBOYXNlLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogUXVha2VuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJxdWFrIjoKKyAgICBIRUxQQ0hFQ0soInF1YWsiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIlF1YWtlIHdpZT9cbiIpOworICAgIHNmb289IiI7CisgICAgZmxhZz1RdWVyeVByb3AoUF9GUk9HKSYmIWdob3N0KCk7CisgICAgZm9yICh0X2c9MDsgdF9nPD1yYW5kb20oZmxhZyA/IDQgOiAyKTsgdF9nKyspICB7CisgICAgICBzZm9vKz0oZmxhZyA/ICIgUXUiIDogIiBrdyIpOworICAgICAgZm9yICh0X249MDsgdF9uPD1yYW5kb20oZmxhZyA/IDEwIDogNSk7IHRfbisrKQorICAgICAgICBzZm9vKz0iYUEiW3JhbmRvbSgxKS4ucmFuZG9tKDEpXTsKKyAgICAgIHNmb28rPSJrIjsKKyAgICB9CisgICAgaWYgKCFmbGFnKQorICAgICAgc2Zvbz1sb3dlcl9jYXNlKHNmb28pOworICAgIGVsc2UKKyAgICAgIHNmb28rPSIhIjsKKyAgICBvdXRfc2VsPSJEdSBxdWFrc3QiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQCIgOiAoZmxhZyA/ICIgYXVzIHZvbGxlciBLZWhsZSIKKyAgICAgIDogIiBpbiBldHdhIHdpZSBlaW4gRnJvc2NoIikpKyI6IitzZm9vOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBxdWFrdCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBAIiA6IChmbGFnID8gIiBhdXMgdm9sbGVyIEtlaGxlIgorICAgICAgOiAiIGluIGV0d2Egd2llIGVpbiBGcm9zY2giKSkrIjoiK3Nmb287CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogUXVpZXRzY2hlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAicXVpZXRzY2giOgorICAgIGNhc2UgInF1aWVrIjoKKyAgICBIRUxQQ0hFQ0soInF1aWVrIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJRdWlldHNjaGUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgcXVpZXRzY2hzdCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOiAiIHZlcmdudWVndC4iKTsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgcXVpZXRzY2h0IisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAuIiA6ICIgdmVyZ251ZWd0LiIpOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFJhZXVzcGVybiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAicmFldXNwZXIiOgorICAgIEhFTFBDSEVDSygicmFldXNwZXIiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIkhtPyBXaWUgbWVpbmVuP1xuIik7CisgICAgb3V0X3NlbD0iRHUgcmFldXNwZXJzdCBEaWNoQEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCByYWV1c3BlcnQgc2ljaEBAYWR2ZXJiQEAuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBSZWliZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInJlaWIiOgorICAgIEhFTFBDSEVDSygicmVpYiIpOworICAgIGlmIChnaG9zdCgpKQorICAgICAgUmV0dXJuKCJEdSBoYXN0IG5pY2h0cyB6dW0gUmVpYmVuLCBhYmVyIGF1Y2ggZ2FyIG5pY2h0cy5cbiIpOworICAgIGlmIChzdHIgJiYgKHNzY2FuZihzdHIsIiVzIGRpZSBBdWdlbiIsc2Zvbyk9PTEgfHwgc3NjYW5mKHN0ciwiJXMgQXVnZW4iLHNmb28pPT0xKSkKKyAgICAgIHN0cj1zZm9vOworICAgIGVsc2UgaWYgKHN0ciAmJiAoc3NjYW5mKHN0ciwiJXMgZGllIEhhZW5kZSIsc2Zvbyk9PTEKKyAgICB8fHNzY2FuZihzdHIsIiVzIEhhZW5kZSIsc2Zvbyk9PTEpKSAgeworICAgICAgZmxhZz0yOworICAgICAgc3RyPXNmb287CisgICAgfQorICAgIGlmIChzdHI9PSIiKSBzdHI9MDsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIlJlaWJlIHdpZSBkaWUgIisoZmxhZz09MiA/ICJIYWVuZGUiIDogIkF1Z2VuIikrIj9cbiIpOworICAgIG91dF9zZWw9IkR1IHJlaWJzdCBEaXIiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQCIKKyAgICAgIDogKGZsYWc9PTIgPyAiIHZlcmdudWVndCIgOiAiIG11ZWRlIikpKyIgZGllICIKKyAgICAgICsoZmxhZz09MiA/ICJIYWVuZGUuIiA6ICJBdWdlbi4iKTsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCByZWlidCBzaWNoIisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAiCisgICAgICA6IChmbGFnPT0yID8gIiB2ZXJnbnVlZ3QiIDogIiBtdWVkZSIpKSsiIGRpZSAiCisgICAgICArKGZsYWc9PTIgPyAiSGFlbmRlLiIgOiAiQXVnZW4uIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogUm90ZmxuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJyb3RmbCI6CisgICAgSEVMUENIRUNLKCJyb3RmbCIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiUm90Zmwgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgcm90ZmxzdEBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgcm90Zmx0QEBhZHZlcmJAQC4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFJ1ZWxwc2VuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJydWVscHMiOgorICAgIEhFTFBDSEVDSygicnVlbHBzIik7CisgICAgR0hPU1RDSEVDSygiRWluIGxlaWNodGVyIFdpbmRoYXVjaCBlbnRmYWVocnQgRGVpbmVtIE11bmQsIG1laHIgbmljaHQuXG4iLAorICAgICAgIkRlbSBNdW5kIGRlcyBHZWlzdGVzIHZvbiAiK2NhcG5hbWUoKQorICAgICAgICArIiBlbnRmYWVocnQgZWluIGxlaWNodGVzIEx1ZWZ0Y2hlbi5cbiIsIDApOworICAgIGlmICghc3RyKSAgeworICAgICAgb3V0X3NlbD0iQk9PT09FRUVSUlJSUFAhICBFbnRzY2h1bGRpZ2UgZGljaCBnZWZhZWxsaWdzdCEiOworICAgICAgb3V0X290aD0iQEBuYW1lQEAgcnVlbHBzdCB1bmFuc3RhZW5kaWcuIjsKKyAgICB9CisgICAgZWxzZSAgeworICAgICAgUGFyc2VSZXN0KHN0cik7CisgICAgICBpZiAoIWFkdmVyYikgIHsKKyAgICAgICAgd3JpdGUoIlJ1ZWxwc2Ugd2llIChzY2hsaW1tIGdlbnVnLCBkYXNzIER1IERpY2ggbmljaHQgYmVoZXJyc2NoZW4gIgorICAgICAgICAgICsia2FubnN0ISk/XG4iKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgICBvdXRfc2VsPSJEdSBydWVscHN0QEBhZHZlcmJAQC4gU2NoYWVtIERpY2ghIjsKKyAgICAgIG91dF9vdGg9IkBAbmFtZUBAIHJ1ZWxwc3RAQGFkdmVyYkBAIHVuZCB3aXJkIG5pY2h0IG1hbCByb3QgZGFiZWkuIjsKKyAgICB9CisgICAgcmV0dXJuIEZlZWxJdCgpOworICB9CisKKyAgc3dpdGNoICh2YikgIHsKKyAgICAvKioqKioqKioqKioqKioqKiBSdW56ZWxuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJydW56ZWwiOgorICAgIGNhc2UgInJ1bnpsIjoKKyAgICBIRUxQQ0hFQ0soInJ1bnplbCIpOworICAgIGlmIChnaG9zdCgpKQorICAgICAgUmV0dXJuKCJEQVMgZ2VodCBhbHMgR2Vpc3QgbnVuIHdpcmtsaWNoIG5pY2h0LlxuIik7CisgICAgUGFyc2VSZXN0KHN0ciwic3Rpcm4iKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIlJ1bnpsZSBkaWUgU3Rpcm4gd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgcnVuemVsc3RAQGFkdmVyYkBAIGRpZSBTdGlybi4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIHJ1bnplbHRAQGFkdmVyYkBAIGRpZSBTdGlybi4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFNhYmJlcmUgKioqKioqKioqKioqKioqLworICAgIGNhc2UgInNhYmJlciI6CisgICAgSEVMUENIRUNLKCJzYWJiZXIiKTsKKyAgICBzZm9vPWdob3N0KCkgPyAic2NobGVpbSIgOiAic2FiYmVyIjsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIgJiYgIXdobykKKyAgICAgIFJldHVybigiU2FiYmVyIHdpZSBvZGVyIHdlbiBhbj9cbiIpOworICAgIG91dF9zZWw9IkR1ICIrc2Zvbysic3RAQCB3ZW5AQEBAYWR2ZXJiQEAgIgorICAgICAgKyh3aG8gPyAiYW4uIiA6ICJhdWYgZGVuIEJvZGVuLiIpOworICAgIGlmICh3aG8pIG91dF92aWM9IkBAZ25hbWVAQCAiK3Nmb28rInQgRGljaEBAYWR2ZXJiQEAgYW4uIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgIitzZm9vKyJ0QEAgd2VuQEBAQGFkdmVyYkBAICIKKyAgICAgICsod2hvID8gImFuLiIgOiAiYXVmIGRlbiBCb2Rlbi4iKTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBTY2hhZW1lbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic2NoYWVtIjoKKyAgICBIRUxQQ0hFQ0soInNjaGFlbSIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYiAmJiBsb3dlcl9jYXNlKHN0cikhPSJkaWNoIikKKyAgICAgIFJldHVybigiU2NoYWVtZSBEaWNoIHdpZT9cbiIpOworICAgIG91dF9zZWw9IkR1IHNjaGFlbXN0IERpY2hAQGFkdmVyYkBALiI7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIHNjaGFlbXQgc2ljaEBAYWR2ZXJiQEAuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyNpZmRlZiBTQ0hBVV9BTgorICAgIC8qKioqKioqKioqKioqKioqIFNjaGF1IGFuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzY2hhdSI6CisgICAgSEVMUENIRUNLKCJzY2hhdSIpOworICAgIGlmICghc3RyIHx8IG9sZF9leHBsb2RlKHN0ciwgIiAiKVtzaXplb2Yob2xkX2V4cGxvZGUoc3RyLCAiICIpKV0hPSJhbiIpCisgICAgICByZXR1cm4gMDsKKyAgICBQYXJzZVJlc3Qoc3RyLCAiYW4iKTsKKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiU2NoYXUgd2VuIGFuP1xuIik7CisgICAgb3V0X3NlbD0iRHUgc2NoYXVzdCBAQHdlbkBAQEBhZHZlcmJAQCBhbi4iOworICAgIG91dF92aWM9IkBAZ25hbWVAQCBzY2hhdXQgRGljaEBAYWR2ZXJiQEAgYW4uIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgc2NoYXV0IEBAd2VuQEBAQGFkdmVyYkBAIGFuLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworI2VuZGlmCisKKyAgICAvKioqKioqKioqKioqKioqKiBTY2hsdWNoemVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzY2hsdWNoeiI6CisgICAgSEVMUENIRUNLKCJzY2hsdWNoeiIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiU2NobHVjaHplIHdpZT9cbiIpOworICAgIG91dF9zZWw9IkR1IHNjaGx1Y2h6dCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOiAiIGhlcnp6ZXJyZWlzc2VuZC4iKTsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgc2NobHVjaHp0IgorICAgICAgKyhhZHZlcmIgPyAiQEBhZHZlcmJAQC4iIDogIiBoZXJ6emVycmVpc3NlbmQuIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU2NobW9sbGVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzY2htb2xsIjoKKyAgICBIRUxQQ0hFQ0soInNjaG1vbGwiKTsKKyAgICBHSE9TVENIRUNLKCJEdSBzY2h3ZWJzdCBiZWxlaWRpZ3QgaW4gZGllIEVja2UuXG4iLAorICAgICAgZ25hbWUoKSsiIHNjaHdlYnQgYmVsZWlkaWd0IGluIGRpZSBFY2tlIHVuZCBzY2htb2xsdC5cbiIsIDApOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiU2NobW9sbGUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgc2NobW9sbHN0QEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIGdlaHQgaW4gZGllIEVja2UgdW5kIHNjaG1vbGx0QEBhZHZlcmJAQC4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFNjaG11bnplbG4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInNjaG11bnplbCI6CisgICAgY2FzZSAic2NobXVuemwiOgorICAgIEhFTFBDSEVDSygic2NobXVuemVsIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJTY2htdW56bGUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgc2NobXVuemVsc3RAQGFkdmVyYkBALiI7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIHNjaG11bnplbHRAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU2NobmFsemVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzY2huYWx6IjoKKyAgICBIRUxQQ0hFQ0soInNjaG5hbHoiKTsKKyAgICBQYXJzZVJlc3Qoc3RyLCAoeyJ6dW5nZSIsIm1pdCB6dW5nZSIsICJtaXQgZGVyIHp1bmdlIn0pKTsKKyAgICBvdXRfc2VsPSJEdSBzY2huYWx6dEBAYWR2ZXJiQEAgbWl0IGRlciBadW5nZS4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBzY2huYWx6dEBAYWR2ZXJiQEAgbWl0IGRlciBadW5nZS4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFNjaG5hdWJlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic2NobmF1YiI6CisgICAgSEVMUENIRUNLKCJzY2huYXViIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJTY2huYXViZSB3aWU/XG4iKTsKKyAgICBvdXRfc2VsPSJEdSBzY2huYXVic3QiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQC4iIDogIiBlbnRydWVzdGV0LiIpOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBzY2huYXVidCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOiAiIGVudHJ1ZXN0ZXQuIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU2NobmF1ZmVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzY2huYXVmIjoKKyAgICBIRUxQQ0hFQ0soInNjaG5hdWYiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIlNjaG5hdWZlIHdpZT9cbiIpOworICAgIG91dF9zZWw9IkR1IHNjaG5hdWZzdCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOiAiIHZvciBBbnN0cmVuZ3VuZy4iKTsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgc2NobmF1ZnQiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQC4iIDogIiB2b3IgQW5zdHJlbmd1bmcuIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU2NobmlwcGVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzY2huaXBwIjoKKyAgICBjYXNlICJzY2huaXBwcyI6CisgICAgSEVMUENIRUNLKCJzY2huaXBwIik7CisgICAgR0hPU1RDSEVDSygiRHUgc2NoYWZmc3QgZXMgbmljaHQsIHdlaWwgZGllIEZpbmdlciBkdXJjaGVpbmFuZGVyIGR1cmNoICIKKyAgICAgICAgKyJnZWhlbi5cbiIsCisgICAgICBnbmFtZSgpKyIgdmVyc2FndCBiZWltIFNjaG5pcHBlbiAtIGRpZSBGaW5nZXJcbmdlaGVuIGR1cmNoZWluYW5kZXIgIgorICAgICAgICArImR1cmNoLlxuIiwgMCk7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJTY2huaXBwZSB3aWU/XG4iKTsKKyAgICBvdXRfc2VsPSJEdSBzY2huaXBwc3RAQGFkdmVyYkBAIG1pdCBkZWluZW4gRmluZ2Vybi4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIHNjaG5pcHB0QEBhZHZlcmJAQCBtaXQgZGVuIEZpbmdlcm4uIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBTY2huYXJjaGVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzY2huYXJjaCI6CisgICAgSEVMUENIRUNLKCJzY2huYXJjaCIpOworICAgIGlmIChnaG9zdCgpKQorICAgICAgUmV0dXJuKCJJY2ggZ2xhdWJlLCBkYSBmZWhsZW4gRGlyIGlyZ2VuZHdpZSBkaWUgcGh5c2lzY2hlbiAiCisgICAgICAgICsiVm9yYXVzc2V0enVuZ2VuIGRhenUuXG4iKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIlNjaG5hcmNoZSB3aWU/XG4iKTsKKyAgICBvdXRfc2VsPShzdHIgPyAiWnp6enp6enp6enouLi4iIDogIkR1IHNjaG5hcmNoc3RAQGFkdmVyYkBALiIpOworICAgIG91dF9vdGg9IkBAbmFtZUBAIHNjaG5hcmNodCAiKyhzdHIgPyAiQEBhZHZlcmJAQC4iIDogImxhdXQuIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU2NobmllZmVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzbmllZiI6CisgICAgY2FzZSAic2NobmllZiI6CisgICAgSEVMUENIRUNLKCJzY2huaWVmIik7CisgICAgR0hPU1RDSEVDSygiRHUgc2NobmllZnN0IGdhbnogbGVpc2UuXG4iLAorICAgICAgZ25hbWUoKSsiIHNjaG5pZWZ0IGdhbnogbGVpc2UuXG4iLCAwKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIlNjaG5pZWZlIHdpZT9cbiIpOworICAgIG91dF9zZWw9IkR1IHNjaG5pZWZzdEBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBzY2huaWVmdEBAYWR2ZXJiQEAuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBTY2hudXJyZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInNjaG51cnIiOgorICAgIEhFTFBDSEVDSygic2NobnVyciIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiV2llIHdpbGxzdCBEdSBzY2hudXJyZW4/XG4iKTsKKyAgICBvdXRfc2VsPSJNTU1NSUlJSUlBQUFBQUFVVVVVVVVVVSEgRHUgc2NobnVycnN0IgorICAgICAgKyhhZHZlcmIgPyAiQEBhZHZlcmJAQC4iIDogIiB6dWZyaWVkZW4uIik7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIHNjaG51cnJ0IisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAuIiA6ICIgenVmcmllZGVuLiIpOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFNjaHJlaWVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzY2hyZWkiOgorICAgIEhFTFBDSEVDSygic2NocmVpIik7CisgICAgR0hPU1RDSEVDSygiQUFBQUlJSUlJSUlJSUlJRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUVFRUUhIEphLCBudXIgR2Vpc3RlciAiCisgICAgICAgICsia29lbm5lbiBzbyBzY2hyZWllbiFcbiIsCisgICAgICBnbmFtZSgpKyIgc2NocmVpdCAtIGRhcyBCbHV0IGdlZnJpZXJ0IGZhc3QgaW4gZGVpbmVuIEFkZXIhXG4iLCAwKTsKKyAgICBpZiAoIXN0cikgIHsKKyAgICAgIG91dF9zZWw9IkFVVVVBQUFISEhISEghISEhIjsKKyAgICAgIG91dF9vdGg9IkBAbmFtZUBAIHNjaHJlaXQgbGF1dCEiOworICAgIH0KKyAgICBlbHNlICB7CisgICAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICAgIGlmICghd2hvICYmICFhZHZlcmIpCisgICAgICAgIFJldHVybigiU2NocmVpZW4gLSB3aWUgZGVubj8gT2RlciB3ZW4gZGVubiBhbnNjaHJlaWVuP1xuIik7CisgICAgICBvdXRfc2VsPSJEdSBzY2hyZWlzdEBAIHdlbkBAQEBhZHZlcmJAQCIrKHdobyA/ICIgYW4iIDogIiIpKyIuIjsKKyAgICAgIGlmICh3aG8pIG91dF92aWM9IkBAbmFtZUBAIHNjaHJlaXQgRGljaEBAYWR2ZXJiQEAgYW4uIjsKKyAgICAgIG91dF9vdGg9IkBAbmFtZUBAIHNjaHJlaXRAQCB3ZW5AQEBAYWR2ZXJiQEAiKyh3aG8/ICIgYW4iIDogIiIpKyIuIjsKKyAgICB9CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU2NodWV0dGVsbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic2NodWV0dGVsIjoKKyAgICBjYXNlICJzY2h1ZXR0bCI6CisgICAgSEVMUENIRUNLKCJzY2h1ZXR0ZWwiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoZm9yX2FsbCkgIHsKKyAgICAgIG91dF9zZWw9IkR1IHNjaHVldHRlbHN0IEBAYWxsZUBAQEBhZHZlcmJAQCBkaWUgSGFlbmRlLiI7CisgICAgICBvdXRfdmljPSJAQGduYW1lQEAgc2NodWV0dGVsdCBAQGFsbGVAQEBAYWR2ZXJiQEAgZGllIEhhZW5kZS4iOworICAgICAgcmV0dXJuIE1peGVkT3V0KFdFTSk7CisgICAgfQorICAgIGlmIChzdHIgJiYgIXdobyAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJTY2h1ZXR0bGUgd2llPyBTY2h1ZXR0bGUgd2VtIGRpZSBIYW5kP1xuIik7CisgICAgaWYoIXdobykgeworICAgICAgb3V0X3NlbD0iRHUgc2NodWV0dGVsc3QgRGljaEBAYWR2ZXJiQEAuIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCBzY2h1ZXR0ZWx0IHNpY2hAQGFkdmVyYkBALiI7CisgICAgfQorICAgIGVsc2UgIHsKKyAgICAgIGlmIChDaGVja0xpZmUoMCxOT1RfREVBRCwKKyAgICAgICAgIiIsICJOb2UsIGRhcyBtYWNoIGljaCBudXIgbWl0IExlYmV3ZXNlbi4iKSkKKyAgICAgICAgICByZXR1cm4gMTsKKyAgICAgIGlmICh3aG8gPT0gdGhpc19wbGF5ZXIoKSkgIHsKKyAgICAgICAgb3V0X3NlbD0iRHUgaGVic3QiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQCIgOiAiIHRyaXVtcGhpZXJlbmQiKQorICAgICAgICAgICsiIERlaW5lIEhhZW5kZSB1ZWJlciBkZW4gS29wZiB1bmQgc2NodWV0dGVsc3Qgc2llLiI7CisgICAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCBoZWJ0IisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAiIDogIiB0cml1bXBoaWVyZW5kIikKKyAgICAgICAgICArIiBkaWUgSGFlbmRlIHVlYmVyIGRlbiBLb3BmXG51bmQgc2NodWV0dGVsdCBzaWUuIjsKKyAgICAgIH0KKyAgICAgIGVsc2UgIHsKKyAgICAgICAgb3V0X3NlbD0iRHUgc2NodWV0dGVsc3RAQCB3ZW1AQEBAYWR2ZXJiQEAgZGllIEhhZW5kZS4iOworICAgICAgICBpZiAoZ2hvc3QoKSkgb3V0X3NlbCs9IlxuTmFqYSwgRHUgdmVyc3VjaHN0IGVzIHdlbmlnc3RlbnMgLSAiCisgICAgICAgICAgKyJpbW1lciBkaWVzZSBkdXJjaGxhZXNzaWdlbiBIYWVuZGUuLi4iOworICAgICAgICBvdXRfdmljPSJAQGduYW1lQEAgc2NodWV0dGVsdCBEaXJAQGFkdmVyYkBAIGRpZSBIYWVuZGUuIjsKKyAgICAgICAgaWYgKGdob3N0KCkpIG91dF92aWMrPSJcbk5hamEsIER1IHZlcnN1Y2hzdCBlcyB3ZW5pZ3N0ZW5zIC0gIgorICAgICAgICAgICsiaW1tZXIgZGllc2UgZHVyY2hsYWVzc2lnZW4gSGFlbmRlLi4uIjsKKyAgICAgICAgb3V0X290aD0iQEBnbmFtZUBAIHNjaHVldHRlbHRAQCB3ZW1AQEBAYWR2ZXJiQEAgZGllIEhhZW5kZS4iOworICAgICAgICBpZiAoZ2hvc3QoKSkgb3V0X290aCs9IlxuTmFqYSwgRHUgdmVyc3VjaHN0IGVzIHdlbmlnc3RlbnMgLSAiCisgICAgICAgICAgKyJpbW1lciBkaWVzZSBkdXJjaGxhZXNzaWdlbiBIYWVuZGUuLi4iOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBTY2h3ZWlnZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInNjaHdlaWciOgorICAgIEhFTFBDSEVDSygic2Nod2VpZyIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiU2Nod2VpZ2Ugd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgc2Nod2VpZ3N0QEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBzY2h3ZWlndEBAYWR2ZXJiQEAuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBTZXVmemVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzZXVmeiI6CisgICAgSEVMUENIRUNLKCJzZXVmeiIpOworICAgIEdIT1NUQ0hFQ0soIkR1IHNldWZ6dCBnZWlzdGVyaGFmdC5cbiIsCisgICAgICBnbmFtZSgpKyIgc2V1Znp0IGdlaXN0ZXJoYWZ0LiBOYWphLCB3aWUgZGVubiBzb25zdD9cbiIsIDApOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghYWR2ZXJiICYmIHN0cikKKyAgICAgIFJldHVybigiU2V1ZnplIHdpZT9cbiIpOworICAgIG91dF9zZWw9IkR1IHNldWZ6c3RAQGFkdmVyYkBALiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAgc2V1Znp0QEBhZHZlcmJAQC4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFNpbmdlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic2luZyI6CisgICAgSEVMUENIRUNLKCJzaW5nIik7CisgICAgaWYgKCFzdHIpIHsKKyAgICAgIG91dF9zZWw9Ik9oIHNvbGUgbWlvISI7CisgICAgICBvdXRfb3RoPSJAQGduYW1lQEAgc2luZ3QgaXJnZW5kd2FzIGl0YWxpZW5pc2NoZXMuIjsKKyAgICB9CisgICAgZWxzZSAgeworICAgICAgUGFyc2VSZXN0KHN0cik7CisgICAgICBvdXRfc2VsPSJEdSBzaW5nc3RAQGFkdmVyYkBAIisoYWR2ZXJiID8gIi4iIDogIiAnIitjYXBpdGFsaXplKHN0cikrIicuIik7CisgICAgICBvdXRfb3RoPSJAQGduYW1lQEAgc2luZ3RAQGFkdmVyYkBAIisoYWR2ZXJiID8gIi4iIDogIiAnIgorICAgICAgICArY2FwaXRhbGl6ZShzdHIpKyInLiIpOworICAgIH0KKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBTbmlmZmVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzbmlmZiI6CisgICAgSEVMUENIRUNLKCJzbmlmZiIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYiAmJiAhd2hvKQorICAgICAgUmV0dXJuKCJTbmlmZmUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgc25pZmZzdCIrKHdobyA/ICIgQEB3ZW5AQCIgOiAiIikKKyAgICAgICsoYWR2ZXJiID8gIkBAYWR2ZXJiQEAiIDogIiB0cmF1cmlnIikrKHdobyA/ICIgYW4uIiA6ICIuIik7CisgICAgaWYgKHdobykgb3V0X3ZpYz0iQEBnbmFtZUBAIHNuaWZmdCBEaWNoIgorICAgICAgKyhhZHZlcmIgPyAiQEBhZHZlcmJAQCIgOiAiIHRyYXVyaWciKSsiIGFuLiI7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIHNuaWZmdCIrKHdobyA/ICIgQEB3ZW5AQCIgOiAiIikKKyAgICAgICsoYWR2ZXJiID8gIkBAYWR2ZXJiQEAiIDogIiB0cmF1cmlnIikrKHdobyA/ICIgYW4uIiA6ICIuIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU3B1Y2tlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic3B1Y2siOgorICAgIEhFTFBDSEVDSygic3B1Y2siKTsKKyAgICBHSE9TVENIRUNLKCJEdSBicmluZ3N0IG5pY2h0IGdlbnVnIFNwdWNrZSB6dXNhbW1lbi5cbiIsCisgICAgICBnbmFtZSgpKyIgc3RlbGx0IGdlcmFkZSBmZXN0LCBkYXNzIG1hbiBvaG5lIFNwdWNrZSBuaWNodFxuIgorICAgICAgICArInNwdWNrZW4ga2Fubi5cbiIsIDApOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIXdobyAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJTcHVja2Ugd2VuIHdpZSBhbj9cbiIpOworICAgIGlmICh3aG8gJiYgQ2hlY2tMaWZlKE5PVF9TRUxGLDAsCisgICAgICAiSGFzdCBEdSBEaWNoIHNvIHNjaGxlY2h0IGJlbm9tbWVuPyBMYXNzIGVzIGxpZWJlciBibGVpYmVuLiIpKQorICAgICAgICByZXR1cm4gMTsKKyAgICBvdXRfc2VsPSJEdSBzcHVja3N0QEAgd2VuQEBAQGFkdmVyYkBAICIrKHdobyA/ICJhbi4iIDogImF1ZiBkZW4gQm9kZW4uIik7CisgICAgaWYgKHdobykgb3V0X3ZpYz0iQEBuYW1lQEAgc3B1Y2t0IERpY2hAQGFkdmVyYkBAIGFuLiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAgc3B1Y2t0QEAgd2VuQEBAQGFkdmVyYkBAICIKKyAgICAgICsod2hvID8gImFuLiIgOiAiYXVmIGRlbiBCb2Rlbi4iKTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBTdGFtcGZlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic3RhbXBmIjoKKyAgICBIRUxQQ0hFQ0soInN0YW1wZiIpOworICAgIFBhcnNlUmVzdChzdHIsICJhdWYiKTsKKyAgICBvdXRfc2VsPSJEdSBzdGFtcGZzdEBAYWR2ZXJiQEAgbWl0IGRlbSBGdXNzIGF1Zi4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBzdGFtcGZ0QEBhZHZlcmJAQCBtaXQgZGVtIEZ1c3MgYXVmLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU3RhcnJlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic3RhcnIiOgorICAgIEhFTFBDSEVDSygic3RhcnIiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICF3aG8gJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiU3RhcnJlIHdpZSBiencuIHdlbiBhbj9cbiIpOworICAgIGlmICh3aG8gJiYgQ2hlY2tMaWZlKE5PVF9TRUxGLDAsCisgICAgICAiV2llIHdpbGxzdCBEdSBpbiBEZWluZSBlaWdlbmVuIEF1Z2VuIHN0YXJyZW4/ICIKKyAgICAgICAgKyIoU3BpZWdlbCBnZWx0ZW4gbmljaHQuLi4pIikpCisgICAgICAgIHJldHVybiAxOworICAgIG91dF9zZWw9IkR1IHN0YXJyc3QiKyghc3RyID8gIiBpbnMgTGVlcmUuIiA6ICh3aG8gPyAiQEAgd2VuQEAiIDogIiIpCisgICAgICArKGFkdmVyYiA/ICJAQGFkdmVyYkBAIiA6ICIgdmVydHJhZXVtdCIpKyh3aG8gPyAiIGFuLiIgOiAiLiIpKTsKKyAgICBpZiAod2hvKSBvdXRfdmljPSJAQGduYW1lQEAgc3RhcnJ0IisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAiIDogIiB0aWVmIikKKyAgICAgICsiIGluIERlaW5lIEF1Z2VuLiI7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIHN0YXJydCIrKCFzdHIgPyAiIGlucyBMZWVyZS4iIDogKHdobyA/ICJAQCB3ZW5AQCIgOiAiIikKKyAgICAgICsoYWR2ZXJiID8gIkBAYWR2ZXJiQEAiIDogIiB2ZXJ0cmFldW10IikrKHdobyA/ICIgYW4uIiA6ICIuIikpOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFN0YXVuZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInN0YXVuIjoKKyAgICBIRUxQQ0hFQ0soInN0YXVuIik7CisgICAgaWYgKCFzdHIpICB7CisgICAgICBvdXRfc2VsPSJEdSBiaXN0IGVyc3RhdW50LiI7CisgICAgICBvdXRfb3RoPSJAQGduYW1lQEAgaXN0IGVyc3RhdW50LiI7CisgICAgfQorICAgIGVsc2UgIHsKKyAgICAgIFBhcnNlUmVzdChzdHIsICJ1ZWJlciIpOworICAgICAgaWYgKCF3aG8gJiYgIWFkdmVyYikKKyAgICAgICAgUmV0dXJuKCJCbGEgYmxhLiBXZW5uIER1IG5hY2ggc3RhdW5lIG5vY2ggd2FzIHRpcHBzdCwgc29sbHRlICIKKyAgICAgICAgICArImRhcyBlaW5cbkxlYmV3ZXNlbiBzZWluLlxuIik7CisgICAgICBpZiAod2hvID09IHRoaXNfcGxheWVyKCkpICB7CisgICAgICAgIG91dF9zZWw9IkR1IHN0YXVuc3RAQGFkdmVyYkBAIHVlYmVyIERpY2ggc2VsYmVyLiI7CisgICAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCBzdGF1bnRAQGFkdmVyYkBAIHVlYmVyIHNpY2ggc2VsYmVyLiI7CisgICAgICB9CisgICAgICBlbHNlICB7CisgICAgICAgIG91dF9zZWw9IkR1IHN0YXVuc3RAQGFkdmVyYkBAIisod2hvID8gIiB1ZWJlciBAQHdlbkBALiIgOiAiLiIpOworICAgICAgICBpZiAod2hvKSBvdXRfdmljPSJAQGduYW1lQEAgc3RhdW50QEBhZHZlcmJAQCB1ZWJlciBEaWNoLiI7CisgICAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCBzdGF1bnRAQGFkdmVyYkBAIisod2hvID8gIiB1ZWJlciBAQHdlbkBALiIgOiAiLiIpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBTdGllcmVuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJzdGllciI6CisgICAgSEVMUENIRUNLKCJzdGllciIpOworICAgIEdIT1NUQ0hFQ0soIkR1IHN0aWVyc3QgbWl0IGhvaGxlbSBCbGljayBpbiBkaWUgR2VnZW5kLlxuIiwKKyAgICAgIGduYW1lKCkrIiBzdGllcnQgbWl0IGhvaGxlbSBCbGljayBpbiBkaWUgR2VnZW5kLlxuIiwgMCk7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhd2hvICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIlN0aWVyZSB3aWUgb2RlciB3ZW4gYW4/XG4iKTsKKyAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICJEdSBrYW5uc3QgRGljaCBuaWNodCBzZWxiZXIgYW5zdGllcmVuLiIsCisgICAgICAiQml0dGUgbnVyIExlYmV3ZXNlbiBhbnN0aWVyZW4uIikpCisgICAgICAgIHJldHVybiAxOworICAgIG91dF9zZWw9IkR1IHN0aWVyc3RAQCB3ZW5AQEBAYWR2ZXJiQEAiCisgICAgICArKHdobyA/ICIgYW4uIiA6ICIgaW4gZGVyIEdlZ2VuZCBoZXJ1bS4iKTsKKyAgICBpZiAod2hvKSBvdXRfdmljPSJAQGduYW1lQEAgc3RpZXJ0IERpY2hAQGFkdmVyYkBAIGFuLiI7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIHN0aWVydEBAIHdlbkBAQEBhZHZlcmJAQCIKKyAgICAgICsod2hvID8gIiBhbi4iIDogIiBpbiBkZXIgR2VnZW5kIGhlcnVtLiIpOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFN0aW1tZSB6dSAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic3RpbW0iOgorICAgIEhFTFBDSEVDSygic3RpbW0iKTsKKyAgICBQYXJzZVJlc3Qoc3RyLCAienUiKTsKKyAgICBpZiAoc3RyICYmICF3aG8gJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiU3RpbW1lIHdlbSB6dT9cbiIpOworICAgIG91dF9zZWw9IkR1IHN0aW1tc3RAQCB3ZW1AQEBAYWR2ZXJiQEAgenUuIjsKKyAgICBpZiAod2hvKSBvdXRfdmljPSJAQGduYW1lQEAgc3RpbW10IERpckBAYWR2ZXJiQEAgenUuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgc3RpbW10QEAgd2VtQEBAQGFkdmVyYkBAIHp1LiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU3RvZWhuZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInN0b2VobiI6CisgICAgSEVMUENIRUNLKCJzdG9laG4iKTsKKyAgICBHSE9TVENIRUNLKCJEdSBzdG9laG5zdCBzY2hhdWRlcmxpY2guXG4iLAorICAgICAgZ25hbWUoKSsiIHN0b2VobnQgc2NoYXVkZXJsaWNoLiBadW0gR2x1ZWNrXG5oYXN0IER1IHppZW1saWNoICIKKyAgICAgICAgKyJndXRlIE5lcnZlbi5cbiIsIDApOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghYWR2ZXJiICYmIHN0cikKKyAgICAgIFJldHVybigiV2llIHdpbGxzdCBEdSBzdG9laG5lbj9cbiIpOworICAgIG91dF9zZWw9IkR1IHN0b2VobnN0QEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIHN0b2VobnRAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU3Rvc3NlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic3Rvc3MiOgorICAgIEhFTFBDSEVDSygic3Rvc3MiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiU3Rvc3NlIHdlbj9cbiIpOworICAgIGlmIChDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAiV2FzIHNvbGwgZGVyIFVuc2lubj8gTGFzcyBkYXMhIiwKKyAgICAgICJEYXMgZ2lidCBudXIgYmVpIExlYmV3ZXNlbiBTaW5uLiIpKQorICAgICAgICByZXR1cm4gMTsKKyAgICBHSE9TVENIRUNLKCJEZWluIEVsbGVuYm9nZW4gdmVyc2lua3QgaW4gIit3aG8tPm5hbWUoV0VNKSsiLlxuIiwKKyAgICAgIGduYW1lKCkrIiB3aWxsICIrd2hvLT5uYW1lKFdFTSkrIiBpbiBkaWUgUmlwcGVuIHN0b3NzZW4sIGFiZXIgIgorICAgICAgICArUVBQKE1BTEUsV0VSLFBMVVJBTCkrIlxuRWxsZW5ib2dlbiB2ZXJ0ZWlsZW4ga2VpbmVuIFN0b3NzLCAiCisgICAgICAgICsic29uZGVybiB2ZXJzaW5rZW4uXG4iLAorICAgICAgZ25hbWUoKSsiIHdpbGwgRGljaCBpbiBkaWUgUmlwcGVuIHN0b3NzZW4sIGFiZXIgIitRUFAoTUFMRSxXRVIsUExVUkFMKQorICAgICAgICArIiBFbGxlbmJvZ2VuIHZlcnNpbmtlbi5cbiIpOworICAgIG91dF9zZWw9IkR1IHN0b2Vzc3RAQCB3ZW5AQEBAYWR2ZXJiQEAgaW4gZGllIFJpcHBlbi4iOworICAgIG91dF92aWM9IkBAbmFtZUBAIHN0b2Vzc3QgRGlyQEBhZHZlcmJAQCBpbiBkaWUgUmlwcGVuLiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAgc3RvZXNzdEBAIHdlbkBAQEBhZHZlcmJAQCBpbiBkaWUgUmlwcGVuLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU3RyZWljaGVsbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic3RyZWljaGVsIjoKKyAgICBjYXNlICJzdHJlaWNobCI6CisgICAgSEVMUENIRUNLKCJzdHJlaWNoZWwiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiU3RyZWljaGxlIHdlbj9cbiIpOworICAgIGlmIChmb3JfYWxsKSAgeworICAgICAgb3V0X3NlbD0iRHUgc3RyZWljaGVsc3QgQEBhbGxlQEBAQGFkdmVyYkBALiI7CisgICAgICBvdXRfdmljPSJAQGduYW1lQEAgc3RyZWljaGVsdCBAQGFsbGVAQEBAYWR2ZXJiQEAuIjsKKyAgICAgIHJldHVybiBNaXhlZE91dChXRU4pOworICAgIH0KKyAgICBpZiAoQ2hlY2tMaWZlKE5PVF9TRUxGLE5PVF9ERUFELAorICAgICAgIkxhc3MgRGljaCB2b24gYW5kZXJlbiBzdHJlaWNoZWxuLiIsCisgICAgICAiSWNoIHN0cmVpY2hsZSBudXIgTGViZXdlc2VuLiIpKQorICAgICAgICByZXR1cm4gMTsKKyAgICBHSE9TVENIRUNLKCJEdSB3aWxsc3QgIit3aG8tPm5hbWUoV0VOLDIpKyIgc3RyZWljaGVsbiwgYWJlciBEZWluZSAiCisgICAgICArIkhhZW5kZSBrb2VubmVuXG5uaWNodHMgYmVydWVocmVuLlxuIiwKKyAgICBnbmFtZSgpKyIgd2lsbCAiK3doby0+bmFtZShXRU4sMikrIiBzdHJlaWNoZWxuLCBhYmVyIGRpZXNlXG4iCisgICAgICArIkdlaXN0ZXJoYWVuZGUga29lbm5lbiBoYWx0IG5peCBiZXJ1ZWhyZW4uLi5cbiIsCisgICAgZ25hbWUoKSsiIHdpbGwgRGljaCBzdHJlaWNoZWxuLCBzY2hlaXRlcnQgYWJlciB3aWUgc28gb2Z0IGFuXG4iCisgICAgICArImRpZXNlbiBkdW1tZW4gZHVyY2hsYWVzc2lnZW4gR2Vpc3RlcmhhZW5kZW4uXG4iKTsKKyAgICBvdXRfc2VsPSJEdSBzdHJlaWNoZWxzdCBAQHdlbkBAQEBhZHZlcmJAQC4iOworICAgIG91dF92aWM9IkBAbmFtZUBAIHN0cmVpY2hlbHQgRGljaEBAYWR2ZXJiQEAuIjsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBzdHJlaWNoZWx0IEBAd2VuQEBAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU3R1cHNlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic3R1cHMiOgorICAgIEhFTFBDSEVDSygic3R1cHMiKTsKKyAgICBpZiAoZ2hvc3QoKSkKKyAgICAgIFJldHVybigiRGFzIGdlaHQgbmljaHQgb2huZSBFbGxlbmJvZ2VuLC4uXG4iKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiU3R1cHNlIHdlbiBhbj9cbiIpOworICAgIG91dF9zZWw9IkR1IHN0dXBzdCBAQHdlbkBAQEBhZHZlcmJAQCBhbi4iOworICAgIG91dF92aWM9IkBAbmFtZUBAIHN0dXBzdCBEaWNoQEBhZHZlcmJAQCBhbi4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIHN0dXBzdCBAQHdlbkBAQEBhZHZlcmJAQCBhbi4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFN0dXR6ZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInN0dXR6IjoKKyAgICBIRUxQQ0hFQ0soInN0dXR6Iik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJTdHV0emUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgc3R1dHp0QEBhZHZlcmJAQC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBzdHV0enRAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogVGFldHNjaGVsbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAidGFldHNjaGVsIjoKKyAgICBjYXNlICJ0YWV0c2NobCI6CisgICAgSEVMUENIRUNLKCJ0YWV0c2NoZWwiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiVGFldHNjaGxlIHdlbj9cbiIpOworICAgIGlmIChDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAiRGFzIHNpZWh0IHp1IGRvb2YgYXVzLCBkYXMgbWFjaGUgaWNoIG5pY2h0LiIsCisgICAgICAiSWNoIHRhZXRzY2hsZSBudXIgTGViZXdlc2VuLiIpKQorICAgICAgICByZXR1cm4gMTsKKyAgICAgR0hPU1RDSEVDSygiRHUgd2lsbHN0ICIrd2hvLT5uYW1lKFdFTikrIiB0YWV0c2NoZWxuIC0gYWJlciBEZWluZSAiCisgICAgICAgICsiSGFlbmRlIGdlaGVuXG5nbGF0dCBkdXJjaCBkZW4gS29wZiBkdXJjaC5cbiIsCisgICAgICBnbmFtZSgpKyIgd2lsbCAiK3doby0+bmFtZShXRU4pKyIgZGVuIEtvcGYgdGFldHNjaGVsbiwgYWJlciAiCisgICAgICAgICsiZGllIEdlaXN0ZXItXG5oYWVuZGUgZ2VoZW4gZ2xhdHQgZHVyY2ggZGVuIEtvcGYgZHVyY2guXG4iLAorICAgICAgZ25hbWUoKSsiIHdpbGwgRGVpbmVuIEtvcGYgdGFldHNjaGVsbiwgYWJlciBkaWVzZSBHZWlzdGVyaGFlbmRlICIKKyAgICAgICAgKyJnZWhlblxuZ2xhdHQgZHVyY2ggRGVpbmVuIEtvcGYgZHVyY2ggLSBEdSBoYXN0IGVpbiBzZWx0c2FtZXMgIgorICAgICAgICArIkdlZnVlaGwgZGFiZWkuXG4iKTsKKyAgICBvdXRfc2VsPSJEdSB0YWV0c2NoZWxzdCBAQHdlbUBAQEBhZHZlcmJAQCBkZW4gS29wZi4iOworICAgIG91dF92aWM9IkBAbmFtZUBAIHRhZXRzY2hlbHQgRGlyQEBhZHZlcmJAQCBkZW4gS29wZi4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIHRhZXRzY2hlbHQgQEB3ZW1AQEBAYWR2ZXJiQEAgZGVuIEtvcGYuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBUYW56ZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInRhbnoiOgorICAgIEhFTFBDSEVDSygidGFueiIpOworICAgIEdIT1NUQ0hFQ0soIkR1IHRhbnp0IGRlbiBrbGFzc2lzY2hlbiBHZWlzdGVyVGFueiAodG0pLlxuIiwKKyAgICAgIGduYW1lKCkrIiB0YW56dCBkZW4ga2xhc3Npc2NoZW4gR2Vpc3RlclRhbnogKHRtKS5cbiIsIDApOworICAgIGlmICghc3RyKSB7CisgICAgICBvdXRfc2VsPSJLb21tc3QgRHUgRGlyIG5pY2h0IGlyZ2VuZHdpZSBibG9lZCB2b3I/IER1IHRhbnp0ICIKKyAgICAgICAgKyJkZW4gRW50ZW50YW56LiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCB0YW56dCBkZW4gRW50ZW50YW56LiI7CisgICAgfQorICAgIGVsc2UgIHsKKyAgICAgIHRhZW56ZT0oeyJXYWx6ZXIiLCJQb2xrYSIsIlJ1bWJhIiwiVGFuZ28iLCJDaGEgY2hhIGNoYSIsIkZveHRyb3R0IiwKKyAgICAgICAgIk1hbWJvIiwiU2Fsc2EiLCJTbG93Zm94IiwiQnJlYWtkYW5jZSIsIlBvZ28iLCJNZXJlbmd1ZSIsCisgICAgICAgICJSb2NrJ24nUm9sbCIsIkJhbGxldHQiLCJSZWdlbnRhbnoiLCJIZXhlbnRhbnoifSk7CisgICAgICBQYXJzZVJlc3Qoc3RyLCJtaXQiKTsKKyAgICAgIGlmICghd2hvKQorICAgICAgICBSZXR1cm4oIk1pdCB3ZW0gd2lsbHN0IER1IHRhbnplbj9cbiIpOworICAgICAgaWYgKHdobyAmJiBDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAgICJNaXQgRGlyIHNlbGJlciBrYW5uc3QgRHUgbmljaHQgdGFuemVuLiIsCisgICAgICAgICJLZWluZSBSZWFrdGlvbiAtIHdpbGwgd2FocnNjaGVpbmxpY2ggbmljaHQgdGFuemVuLiIpKQorICAgICAgICAgIHJldHVybiAxOworICAgICAgaWZvbz1yYW5kb20oc2l6ZW9mKHRhZW56ZSkpOworICAgICAgb3V0X3NlbD0iRHUgdGFuenRAQGFkdmVyYkBAIG1pdCBAQHdlbUBAIGVpbmUgUnVuZGUgIit0YWVuemVbaWZvb10rIi4iOworICAgICAgb3V0X3ZpYz0iQEBuYW1lQEAgcmVpc3N0IERpY2ggYW4gc2ljaCB1bmQgdGFuenRAQGFkdmVyYkBAIGVpbmUgUnVuZGUgIgorICAgICAgICArdGFlbnplW2lmb29dKyIgbWl0IERpci4iOworICAgICAgb3V0X290aD0iQEBuYW1lQEAgc2NobmFwcHQgc2ljaCBAQHdlbkBAIHVuZCBkaWUgYmVpZGVuIHRhbnplbiIKKyAgICAgICAgKyJAQGFkdmVyYkBAIGVpbmUgUnVuZGUgIit0YWVuemVbaWZvb10rIi4iOworICAgIH0KKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBUcmFldW1lbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAidHJhZXVtIjoKKyAgICBIRUxQQ0hFQ0soInRyYWV1bSIpOworICAgIGlmICghc3RyKQorICAgICAgUmV0dXJuKCJUcmFldW1lIHdvdm9uIG9kZXIgdm9uIHdlbT9cbiIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIG91dF9zZWw9IkR1IHRyYWV1bXN0Iisod2hvID8gIkBAYWR2ZXJiQEAgdm9uIEBAd2VtQEAuIgorICAgICAgOiAoYWR2ZXJiID8gIkBAYWR2ZXJiQEAuIiA6ICIgIitzdHIrIi4iKSk7CisgICAgaWYgKHdobykgb3V0X3ZpYz0iQEBnbmFtZUBAIHRyYWV1bXRAQGFkdmVyYkBAIHZvbiBEaXIuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgdHJhZXVtdCIrKHdobyA/ICJAQGFkdmVyYkBAIHZvbiBAQHdlbUBALiIKKyAgICAgIDogKGFkdmVyYiA/ICJAQGFkdmVyYkBALiIgOiAiICIrc3RyKyIuIikpOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFRyZXRlbiAodHJpdHQpICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJ0cml0dCI6CisgICAgY2FzZSAidHJldCI6CisgICAgSEVMUENIRUNLKCJ0cml0dCIpOworICAgIGlmICghc3RyKSAgeworICAgICAgR0hPU1RDSEVDSygiRGVpbiBGdXNzIGZhZWhydCBkdXJjaCBkaWUgYmVydWVobXRlIGxhbmd2ZXJnZXNzZW5lICIKKyAgICAgICAgICArInVuc2ljaHRiYXJlIFNjaGlsZGtyb2V0ZVxuaGluZHVyY2guXG4iLAorICAgICAgICBnbmFtZSgpKyIgd2lsbCBkaWUgYmVydWVobXRlIGxhbmd2ZXJnZXNzZW5lIHVuc2ljaHRiYXJlXG4iCisgICAgICAgICAgKyJTY2hpbGRrcm9ldGUgdHJldGVuLCBhYmVyICIrUVBQKE1BTEUsV0VSKQorICAgICAgICAgICsiIEZ1c3MgZmFlaHJ0IGR1cmNoIHNpZSBoaW5kdXJjaC5cbiIsIDApOworICAgICAgb3V0X3NlbD0iRHUgdHJpdHRzdCBkaWUgYmVydWVobXRlIGxhbmd2ZXJnZXNzZW5lIHVuc2ljaHRiYXJlICIKKyAgICAgICAgKyJTY2hpbGRrcm9ldGUuIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCB0cml0dCBkaWUgYmVydWVobXRlIGxhbmd2ZXJnZXNzZW5lIHVuc2ljaHRiYXJlICIKKyAgICAgICAgKyJTY2hpbGRrcm9ldGUuIjsKKyAgICB9CisgICAgZWxzZSAgeworICAgICAgUGFyc2VSZXN0KHN0cik7CisgICAgICBpZiAoZm9yX2FsbCkgIHsKKyAgICAgICAgb3V0X3NlbD0iRHUgdHJpdHRzdCBAQGFsbGVAQEBAYWR2ZXJiQEAuIFNvbGx0ZXN0IER1IG5pY2h0IGxhbmdzYW0gIgorICAgICAgICAgICsiYW4gRmx1Y2h0IGRlbmtlbj8iOworICAgICAgICBvdXRfdmljPSJAQG5hbWVAQCB0cml0dCBAQGFsbGVAQEBAYWR2ZXJiQEAuIFRyYXV0IHNpY2ggZ2FueiAiCisgICAgICAgICAgKyJzY2hvZW4gd2FzISI7CisgICAgICAgIHJldHVybiBNaXhlZE91dChXRU4pOworICAgICAgfQorICAgICAgaWYgKCF3aG8gJiYgIWFkdmVyYikKKyAgICAgICAgUmV0dXJuKCJXZW5uIER1IHNjaG9uIHdhcyBuYWNoIHRyaXR0IHRpcHBzdCwgZGFubiBzYWcgbWlyLCB3ZW4gIgorICAgICAgICAgICsib2RlciB3aWUgaWNoIGRhcyBzb2xsLlxuIik7CisgICAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICAgIkR1IHNjaGFmZnN0IGVzIG5pY2h0LCBEaXIgc2VsYmVyIGluIGRlbiBIaW50ZXJuIHp1IHRyZXRlbi4iLAorICAgICAgICAiVG90ZSBTYWNoZW4gdHJpdHQgbWFuIG5pY2h0IGF1Y2ggbm9jaCEiKSkKKyAgICAgICAgICByZXR1cm4gMTsKKyAgICAgIGlmICh3aG8pICB7CisgICAgICAgIG91dF9zZWw9IkR1IHRyaXR0c3RAQCB3ZW5AQEBAYWR2ZXJiQEAuIjsKKyAgICAgICAgaWYgKHdobykgb3V0X3ZpYz0iQEBnbmFtZUBAIHRyaXR0IERpY2hAQGFkdmVyYkBALiI7CisgICAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCB0cml0dEBAIHdlbkBAQEBhZHZlcmJAQC4iOworICAgICAgfQorICAgICAgZWxzZSAgeworICAgICAgICBvdXRfc2VsPSJEdSB0cml0dHN0IGRpZSBiZXJ1ZWhtdGUgbGFuZ3Zlcmdlc3NlbmUgdW5zaWNodGJhcmUgIgorICAgICAgICAgICsiU2NoaWxka3JvZXRlQEBhZHZlcmJAQC4iOworICAgICAgICBvdXRfb3RoPSJAQGduYW1lQEAgdHJpdHQgZGllIGJlcnVlaG10ZSBsYW5ndmVyZ2Vzc2VuZSB1bnNpY2h0YmFyZSAiCisgICAgICAgICAgKyJTY2hpbGRrcm9ldGVcbkBAYWR2ZXJiQEAuIjsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogVHJvZXN0ZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInRyb2VzdCI6CisgICAgSEVMUENIRUNLKCJ0cm9lc3QiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiV2VuIHdpbGxzdCBEdSB0cm9lc3Rlbj9cbiIpOworICAgIGlmICh3aG8gJiYgQ2hlY2tMaWZlKE5PVF9TRUxGLE5PVF9ERUFELAorICAgICAgIlRyb3N0IG11c3N0IER1IGJlaSBqZW1hbmQgYW5kZXJzIHN1Y2hlbi4iLAorICAgICAgIkRhcyBUZWlsIG11c3N0IER1IG5pY2h0IHRyb2VzdGVuLCBkYXMgZnVlaGx0IG5peC4iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgb3V0X3NlbD0iRHUgdHJvZXN0ZXN0QEAgd2VuQEBAQGFkdmVyYkBALiI7CisgICAgb3V0X3ZpYz0iQEBnbmFtZUBAIHRyb2VzdGV0IERpY2hAQGFkdmVyYkBALiI7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIHRyb2VzdGV0QEAgd2VuQEBAQGFkdmVyYkBALiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogVW1hcm1lbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAidW1hcm0iOgorICAgIEhFTFBDSEVDSygidW1hcm0iKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiV2VuIHdpbGxzdCBEdSB1bWFybWVuP1xuIik7CisgICAgaWYgKHdobyAmJiBDaGVja0xpZmUoMCxOT1RfREVBRCwwLCJCaXR0ZSB1bWFybWUgbnVyIExlYmV3ZXNlbi4iKSkKKyAgICAgIHJldHVybiAxOworICAgIGlmIChnaG9zdCgpICYmIENoZWNrTGlmZShOT1RfU0VMRiwwLAorICAgICAgIkR1IGthbm5zdCBEaWNoIGFscyBHZWlzdCBuaWNodCBzZWxiZXIgd2Flcm1lbi4iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgc3RyMT13aG8tPlF1ZXJ5UHJvcChQX05BTUUpOworICAgIGlmKHBvaW50ZXJwKHN0cjEpKXN0cjE9KHN0cmluZylzdHIxWzBdOyAvLyBSdW1hdGEKKyAgICBzdHIyPXdoby0+UXVlcnlQcm9ub3VuKFdFTik7CisgICAgR0hPU1RDSEVDSygiRHUgd2lsbHN0ICIrc3RyMSsiIHVtYXJtZW4sIGFiZXIgRGVpbmUgQXJtZSBnZWhlbiBkdXJjaCAiCisgICAgICAgICtzdHIyKyIgZHVyY2guXG4iLAorICAgICAgZ25hbWUoKSsiIHdpbGwgIitzdHIxKyIgdW1hcm1lbiwgYWJlciAiK1FQUChNQUxFLFdFUixQTFVSQUwpCisgICAgICAgICsiIEFybWUgZ2VoZW5cbmR1cmNoICIrc3RyMisiIGhpbmR1cmNoLlxuIiwKKyAgICAgIGduYW1lKCkrIiB3aWxsIERpY2ggdW1hcm1lbiwgYWJlciAiK1FQUChNQUxFLFdFUixQTFVSQUwpCisgICAgICAgICsiIEFybWUgZ2VoZW4gZHVyY2ggRGljaCBoaW5kdXJjaC5cbiIpOworICAgIGlmIChmb3JfYWxsKSAgeworICAgICAgb3V0X3NlbD0iRHUgdW1hcm1zdCBAQGFsbGVAQEBAYWR2ZXJiQEAuIjsKKyAgICAgIG91dF92aWM9IkBAbmFtZUBAIHVtYXJtdCBAQGFsbGVAQEBAYWR2ZXJiQEAuIjsKKyAgICAgIHJldHVybiBNaXhlZE91dChXRU4pOworICAgIH0KKyAgICBpZiAod2hvPT10aGlzX3BsYXllcigpKSAgeworICAgICAgb3V0X3NlbD0iRHUgbGVnc3QgRGVpbmUgQXJtZSB1bSBEaWNoIHVuZCB3YWVybXN0IERpY2ggIgorICAgICAgICArImVpbiBiaXNzY2hlbiBzZWxiZXIuIjsKKyAgICAgIG91dF9vdGg9IkBAbmFtZUBAIGxlZ3QgIitRUFAoTUFMRSxXRVIsUExVUkFMKQorICAgICAgICArIiBBcm1lIHVtIHNpY2ggdW5kIHdhZXJtdCBzaWNoIGVpbiBiaXNzY2hlbiBzZWxiZXIuIjsKKyAgICB9CisgICAgZWxzZSAgeworICAgICAgb3V0X3NlbD0iRHUgdW1hcm1zdEBAIHdlbkBAQEBhZHZlcmJAQC4iOworICAgICAgb3V0X3ZpYz0iQEBuYW1lQEAgdW1hcm10IERpY2hAQGFkdmVyYkBALiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCB1bWFybXRAQCB3ZW5AQEBAYWR2ZXJiQEAuIjsKKyAgICB9CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogVmVyZmx1Y2hlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAidmVyZmx1Y2giOgorICAgIEhFTFBDSEVDSygidmVyZmx1Y2giKTsKKyAgICBpZiAoIXN0cikKKyAgICAgIFJldHVybigiV2VuIG9kZXIgd2FzIHdpbGxzdCBEdSBkZW5uIHZlcmZsdWNoZW4/XG4iKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoIXdobykgIHsKKyAgICAgIG91dF9zZWw9IkR1IHZlcmZsdWNoc3QgIitzdHIrIi4iOworICAgICAgb3V0X290aD0iQEBnbmFtZUBAIHZlcmZsdWNodCAiK3N0cisiLiI7CisgICAgfQorICAgIGVsc2UgIHsKKyAgICAgIGlmICh3aG89PXRoaXNfcGxheWVyKCkpCisgICAgICAgIFJldHVybigiU2ljaCBzZWxiZXIgdmVyZmx1Y2h0IG1hbiBiZXNzZXIgbmljaHQuLi5cbiIpOworICAgICAgaWYgKCFhZHZlcmIpICB7CisgICAgICAgIGZsYWc9c3NjYW5mKHN0ciwgIiVzICVzIiwgc3RyMSxzdHIyKTsKKyAgICAgICAgb3V0X3NlbD0iRHUgdmVyZmx1Y2hzdEBAIHdlbkBAIisoZmxhZz09MiA/ICIgIitzdHIyIDogIiIpKyIuIjsKKyAgICAgICAgb3V0X3ZpYz0iQEBnbmFtZUBAIHZlcmZsdWNodCBEaWNoIisoZmxhZz09Mj8iICIrc3RyMiA6ICIiKSsiLiI7CisgICAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCB2ZXJmbHVjaHRAQCB3ZW5AQCIrKGZsYWc9PTIgPyAiICIrc3RyMiA6ICIiKSsiLiI7CisgICAgICB9CisgICAgICBlbHNlICB7CisgICAgICAgIG91dF9zZWw9IkR1IHZlcmZsdWNoc3RAQCB3ZW5AQEBAYWR2ZXJiQEAuIjsKKyAgICAgICAgb3V0X3ZpYz0iQEBnbmFtZUBAIHZlcmZsdWNodCBEaWNoQEBhZHZlcmJAQC4iOworICAgICAgICBvdXRfb3RoPSJAQGduYW1lQEAgdmVyZmx1Y2h0QEAgd2VuQEBAQGFkdmVyYkBALiI7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFZlcm5laWdlbiAvIFZlcmJldWdlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAidmVybmVpZyI6CisgICAgY2FzZSAidmVyYmV1ZyI6CisgICAgSEVMUENIRUNLKCJ2ZXJuZWlnIik7CisgICAgR0hPU1RDSEVDSygiRHUgdmVybmVpZ3N0IERpY2ggZWluIGJpc3NjaGVuIGhlZnRpZyAtIERlaW4gS29wZiB0YXVjaHQgIgorICAgICAgICArImt1cnogaW4gZGVuIEJvZGVuLlxuIiwKKyAgICAgIGduYW1lKCkrIiB2ZXJuZWlndCBzaWNoLiBFaW4gYmlzc2NoZW4gaGVmdGlnIC0gIitRUFAoTUFMRSxXRVIpCisgICAgICAgICsiIEtvcGZcbnRhdWNodCBrdXJ6IGluIGRlbiBCb2RlbiBlaW4uXG4iLCAwKTsKKyAgICBpZiAoKCFzdHIpIHx8IChzdHIgPT0gImRpY2giKSkgeworICAgICAgb3V0X3NlbD0iRHUgdmVybmVpZ3N0IERpY2ggdm9yIGRlbiBBbndlc2VuZGVuLiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCB2ZXJuZWlndCBzaWNoIGFubXV0aWcuIjsKKyAgICB9CisgICAgZWxzZSAgeworICAgICAgUGFyc2VSZXN0KHN0cik7CisgICAgICBpZiAoZm9yX2FsbCkgIHsKKyAgICAgICAgb3V0X3NlbD0iRHUgdmVybmVpZ3N0IERpY2hAQGFkdmVyYkBAIHZvciBAQGFsbGVAQC4iOworICAgICAgICBvdXRfdmljPSJAQG5hbWVAQCB2ZXJuZWlndCBzaWNoQEBhZHZlcmJAQCB2b3IgQEBhbGxlQEAuIjsKKyAgICAgICAgcmV0dXJuIE1peGVkT3V0KFdFTSk7CisgICAgICB9CisgICAgICBpZiAoIXdobyAmJiAhYWR2ZXJiKQorICAgICAgICBSZXR1cm4oIlZlcm5laWdlIGRpY2ggaXJnZW5kd2llIG9kZXIgdm9yIGplbWFuZGVtLlxuIik7CisgICAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICAgIldpZSB3aWxsc3QgRHUgZGFzIGRlbm4gc2NoYWZmZW4/IiwKKyAgICAgICAgIlZvciBTYWNoZW4gd2lyZCBoaWVyIG5pY2h0IHZlcm5laWd0LCBrbGFyP1xuIikpCisgICAgICAgICAgcmV0dXJuIDE7CisgICAgICBvdXRfc2VsPSJEdSB2ZXJuZWlnc3QgRGljaEBAYWR2ZXJiQEAiKyh3aG8gPyAiIHZvciIgOiAiIikrIkBAIHdlbUBALiI7CisgICAgICBpZiAod2hvICkgb3V0X3ZpYz0iQEBuYW1lQEAgdmVybmVpZ3Qgc2ljaEBAYWR2ZXJiQEAgdm9yIERpci4iOworICAgICAgb3V0X290aD0iQEBuYW1lQEAgdmVybmVpZ3Qgc2ljaEBAYWR2ZXJiQEAiKyh3aG8gPyAiIHZvciIgOiAiIikKKyAgICAgICAgKyJAQCB3ZW1AQC4iOworICAgIH0KKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBWZXJuZWluZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgIm5laW4iOgorICAgIGNhc2UgIm5vZSI6CisgICAgSEVMUENIRUNLKCJuZWluIik7CisgICAgR0hPU1RDSEVDSygiRHUgc2NodWV0dGVsc3QgRGVpbmVuIEtvcGYgc28gaGVmdGlnLCBkYXNzIGVyIGt1cnogIgorICAgICAgICArImRhdm9uc2Nod2VidC5cbiIsCisgICAgICBnbmFtZSgpKyIgc2NodWV0dGVsdCBoZWZ0aWcgZGVuIEtvcGYuXG5TbyBoZWZ0aWcsIGRhc3MgZGllc2VyICIKKyAgICAgICAgKyJrdXJ6IGRhdm9uc2Nod2VidCB1bmQgd2llZGVyIGVpbmdlZmFuZ2VuIHdlcmRlbiBtdXNzLlxuIiwgMCk7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKHN0ciAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJTY2h1ZXR0bGUgd2llIGRlbiBLb3BmP1xuIik7CisgICAgb3V0X3NlbD0iRHUgc2NodWV0dGVsc3RAQGFkdmVyYkBAIGRlbiBLb3BmLiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAgc2NodWV0dGVsdEBAYWR2ZXJiQEAgZGVuIEtvcGYuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBXYWNrZWxuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJ3YWNrZWwiOgorICAgIGNhc2UgIndhY2tsIjoKKyAgICBIRUxQQ0hFQ0soIndhY2tlbCIpOworICAgIGlmIChnaG9zdCgpKQorICAgICAgUmV0dXJuKCJEYSBnaWJ0IGVzIG5pY2h0cyBtZWhyLCB3b21pdCBEdSB3YWNrZWxuIGthbm5zdC5cbiIpOworICAgIGlmIChzdHIpCisgICAgICBpZiAoc3Ryc3RyKHN0ciwgIm1pdCAiKT09MCkKKyAgICAgICAgc3NjYW5mKHN0ciwgIm1pdCAlcyIsIHNmb28pOworICAgICAgZWxzZSBpZiAoc3Ryc3RyKHN0ciwibWl0ICIpPjApICB7CisgICAgICAgIHNzY2FuZihzdHIsICIlcyBtaXQgJXMiLCBzZm9vLCBzZm9vKTsKKyAgICAgICAgZmxhZz0xOworICAgICAgfQorICAgIGlmIChzZm9vPT0iIikgc2Zvbz0wOworICAgIFBhcnNlUmVzdChzdHIsIChzZm9vID8gKGZsYWcgPyAiIG1pdCAiIDogIm1pdCAiKStzZm9vIDogMCkpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYiAmJiAhc2ZvbykKKyAgICAgIFJldHVybigiV2Fja2xlIHdpZSBvZGVyIHdvbWl0P1xuIik7CisgICAgb3V0X3NlbD0iRHUgd2Fja2Vsc3RAQGFkdmVyYkBAIG1pdCAiKyhzZm9vID8gc2ZvbysiLiIgOiAiZGVtIEhpbnRlcm4uIik7CisgICAgb3V0X290aD0iQEBuYW1lQEAgd2Fja2VsdEBAYWR2ZXJiQEAgbWl0ICIKKyAgICAgICsoc2ZvbyA/IHNmb28rIi4iIDogUVBQKE1BTEUsV0VNKSsiIEhpbnRlcm4uIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogV2FlbHplbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAid2FlbHoiOgorICAgIEhFTFBDSEVDSygid2FlbHoiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIldhZWx6ZSBEaWNoIHdpZSBhdWYgZGVtIEJvZGVuP1xuIik7CisgICAgb3V0X3NlbD0iRHUgd2FlbHp0IERpY2giKyhhZHZlcmIgPyAiQEBhZHZlcmJAQCIgOiAiIHZvciBMYWNoZW4iKQorICAgICAgKyIgYXVmIGRlbSBCb2Rlbi4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCB3YWVsenQgc2ljaCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBAIiA6ICIgdm9yIExhY2hlbiIpCisgICAgICArKGdob3N0KCkgPyAiIGltIiA6ICIgYXVmIGRlbSIpKyIgQm9kZW4uIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBXYXJ0ZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgIndhcnQiOgorICAgIEhFTFBDSEVDSygid2FydCIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghc3RyKSAgeworICAgICAgb3V0X3NlbD0iRHUgdGlwcHN0IG1pdCBkZW0gRnVzcyBhdWYgZGVuIEJvZGVuLiI7CisgICAgICBvdXRfb3RoPSJAQGduYW1lQEAgdGlwcHQgbWl0IGRlbSBGdXNzIGF1ZiBkZW4gQm9kZW4uIjsKKyAgICB9IGVsc2UgaWYgKCF3aG8gJiYgYWR2ZXJiKSAgeworICAgICAgb3V0X3NlbD0iRHUgd2FydGVzdEBAYWR2ZXJiQEAuIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCB3YXJ0ZXRAQGFkdmVyYkBALiI7CisgICAgfSBlbHNlICB7CisgICAgICBvdXRfc2VsPSJEdSB3YXJ0ZXN0QEBhZHZlcmJAQCBhdWYgIisod2hvID8gIkBAd2VuQEAuIiA6IHN0cisiLiIpOworICAgICAgaWYgKHdobykgb3V0X3ZpYz0iQEBnbmFtZUBAIHdhcnRldEBAYWR2ZXJiQEAgYXVmIERpY2guIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCB3YXJ0ZXRAQGFkdmVyYkBAIGF1ZiAiKyh3aG8gPyAiQEB3ZW5AQC4iIDogc3RyKyIuIik7CisgICAgfQorICAgIHJldHVybiBGZWVsSXQoKTsKKworI2lmZGVmIFdFQ0tFCisgICAgLyoqKioqKioqKioqKioqKiogV2Vja2VuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJ3ZWNrIjoKKyAgICBIRUxQQ0hFQ0soIndlY2siKTsKKyAgICBpZiAoUGFyc2VSZW1vdGUoc3RyKSkKKyAgICAgIHJldHVybiAxOworLy8gICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIldlbiB3aWxsc3QgRHUgd2Vja2VuP1xuIik7CisgICAgaWYgKHNzY2FuZihzdHIsICIlcyAlcyIsIHNmb28sIHNmb28pPT0yKQorICAgICAgZmxhZz0xOworICAgIG91dF9zZWw9IkRlaW4gV2Vja2VyIGtsaW5nZWx0IGJlaSBAQHdlbUBAQEBhZHZlcmJAQCIKKyAgICAgICsoYWR2ZXJiID8gIi4iIDogKGZsYWcgPyAiOiAiK3Nmb28gOiAiLiIpKTsKKyAgICBvdXRfdmljPSIgIituYW1lKFdFU1NFTikrIiBXZWNrZXIga2xpbmdlbHQgYmVpIERpckBAYWR2ZXJiQEAiCisgICAgICArKGFkdmVyYiA/ICIuIiA6IChmbGFnID8gIjogIitzZm9vIDogIi4iKSk7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIHdpcmZ0ICIrUVBQKE1BTEUsIFdFTikKKyAgICAgICsiIFdlY2tlckBAYWR2ZXJiQEAgbmFjaCBAQHdlbUBALiI7CisgICAgICAgICAgaWYgKCF3aG8tPlF1ZXJ5UHJvcChQX1ZJU1VBTEJFTEwpKQorICAgICAgICAgb3V0X3ZpY1swXT03OyAvLyBjaHIoNyk9PUJFTAorICAgICAgZWxzZSBvdXRfdmljPW91dF92aWNbMS4uXTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisjZW5kaWYKKworICAgIC8qKioqKioqKioqKioqKioqIFdlaW5lbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAid2VpbiI6CisgICAgSEVMUENIRUNLKCJ3ZWluIik7CisgICAgR0hPU1RDSEVDSygiRXMgcmVpY2h0IGxlaWRlciBudXIgZnVlciBlaW4gcGFhciB3aW56aWdlIE5lYmVsd29lbGtjaGVuLCAiCisgICAgICAgICsibmljaHQgZnVlciBUcmFlbmVuLlxuIiwKKyAgICAgIGduYW1lKCkrIiB2ZXJ6aWVodCBkYXMgR2VzaWNodCB1bmQgZWluIHBhYXIgd2luemlnZSBOZWJlbC1cbiIKKyAgICAgICAgKyJ3b2Vsa2NoZW4gZW50ZmVybmVuIHNpY2ggdm9uIHNlaW5lbiBcIkF1Z2VuXCIuXG4iLCAwKTsKKyAgICBpZiAoIXN0cikgIHsKKyAgICAgIG91dF9zZWw9IldhYWFhYWghIER1IHdlaW5zdCBiaXR0ZXJsaWNoLiI7CisgICAgICBvdXRfb3RoPSJAQG5hbWVAQCBicmljaHQgaW4gVHJhZW5lbiBhdXMgdW5kIHdlaW50IGJpdHRlcmxpY2guIjsKKyAgICB9CisgICAgZWxzZSAgeworICAgICAgUGFyc2VSZXN0KHN0cik7CisgICAgICBpZiAoIXdobyAmJiAhYWR2ZXJiKQorICAgICAgICBSZXR1cm4oIldlaW5lIERpY2ggaXJnZW5kd2llIGJlaSBpcmdlbmR3ZW0gYXVzLCBhYmVyIG5pY2h0IHNvLlxuIik7CisgICAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICAgIkJlaSBzaWNoIHNlbGJlciBrYW5uIG1hbiBzaWNoIHNvIHNjaGxlY2h0IGF1c3dlaW5lbi4iLAorICAgICAgICAiQmVpIHdlbSB3aWxsc3QgRHUgRGljaCBhdXN3ZWluZW4/Pz8iKSkKKyAgICAgICAgICByZXR1cm4gMTsKKyAgICAgIGlmICh3aG8pICB7CisgICAgICAgIG91dF9zZWw9IkR1IHdlaW5zdCBEaWNoQEBhZHZlcmJAQCBiZWlAQCB3ZW1AQCBhdXMuIjsKKyAgICAgICAgb3V0X3ZpYz0iQEBuYW1lQEAgd2VpbnQgc2ljaEBAYWR2ZXJiQEAgYmVpIERpciBhdXMuIjsKKyAgICAgICAgb3V0X290aD0iQEBuYW1lQEAgd2VpbnQgc2ljaEBAYWR2ZXJiQEAgYmVpQEAgd2VtQEAgYXVzLiI7CisgICAgICB9CisgICAgICBlbHNlICB7CisgICAgICAgIG91dF9zZWw9IkR1IGJyaWNoc3QgaW4gVHJhZW5lbiBhdXMgdW5kIHdlaW5zdEBAYWR2ZXJiQEAuIjsKKyAgICAgICAgb3V0X290aD0iQEBuYW1lQEAgYnJpY2h0IGluIFRyYWVuZW4gYXVzIHVuZCB3ZWludEBAYWR2ZXJiQEAuIjsKKyAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogV2lua2VuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJ3aW5rIjoKKyAgICBIRUxQQ0hFQ0soIndpbmsiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoZm9yX2FsbCkgIHsKKyAgICAgIG91dF9zZWw9IkR1IHdpbmtzdCBAQGFsbGVAQEBAYWR2ZXJiQEAgenUuIjsKKyAgICAgIG91dF92aWM9IkBAbmFtZUBAIHdpbmt0IEBAYWxsZUBAQEBhZHZlcmJAQCB6dS4iOworICAgICAgcmV0dXJuIE1peGVkT3V0KFdFTSk7CisgICAgfQorICAgIGlmICghd2hvICYmICFhZHZlcmIgJiYgc3RyKQorICAgICAgUmV0dXJuKCJWaWVsbGVpY2h0IHNvbGx0ZXN0IER1IGF1Y2ggc2FnZW4sIHdlbSBvZGVyIHdpZSBEdSAiCisgICAgICAgICsiKHp1KXdpbmtlbiB3aWxsc3QuXG4iKTsKKyAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRiwgTk9UX0RFQUQsCisgICAgICAiV2luayBEaXIgbmljaHQgc2VsYmVyIHp1LiIsCisgICAgICAiRHUgbXVzc3Qgc2Nob24gZWluZW0gTGViZXdlc2VuIHp1d2lua2VuLiIpKQorICAgICAgICByZXR1cm4gMTsKKyAgICBvdXRfc2VsPSJEdSB3aW5rc3RAQCB3ZW1AQEBAYWR2ZXJiQEAiKyh3aG8gPyAiIHp1IiA6ICIiKSsiLiI7CisgICAgaWYgKHdobykgb3V0X3ZpYz0iQEBnbmFtZUBAIHdpbmt0IERpckBAYWR2ZXJiQEAgenUuIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgd2lua3RAQCB3ZW1AQEBAYWR2ZXJiQEAiKyh3aG8gPyAiIHp1IiA6ICIiKSsiLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogV3VlcmdlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAid3VlcmciOgorICAgIEhFTFBDSEVDSygid3VlcmciKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICF3aG8gJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiV3VlcmdlIHdlbiBvZGVyIHdpZT9cbiIpOworICAgIGlmICghd2hvKSAgeworICAgICAgb3V0X3NlbD0iRHUgZmFlbmdzdEBAYWR2ZXJiQEAgYW4genUgd3Vlcmdlbi4iOworICAgICAgb3V0X290aD0iQEBnbmFtZUBAIGZhZW5ndEBAYWR2ZXJiQEAgYW4genUgd3Vlcmdlbi4iOworICAgIH0gZWxzZSBpZiAoQ2hlY2tMaWZlKE5PVF9TRUxGLCBOT1RfREVBRCwKKyAgICAgICAgICAiRHUgd3VlcmdzdCBlaW4gYmlzY2hlbiBhbiBEaXIgcnVtLiBEaXIgd2lyZCBzY2huZWxsIGxhbmd3ZWlsaWcuIiwKKwkgICJXdWVyZyBsaWViZXIgZWluIExlYmV3ZXNlbi4iKSkgeworICAgICAgcmV0dXJuIDE7CisgICAgfSBlbHNlIHsKKyAgICAgIG91dF9zZWw9IkR1IHNwcmluZ3N0IEBAd2VuQEAgYW4gdW5kIGZhZW5nc3QgYW4sICIrd2hvLT5RdWVyeVByb25vdW4oV0VOKQorICAgICAgICArIkBAYWR2ZXJiQEAgenUgd3Vlcmdlbi4iOworICAgICAgb3V0X3ZpYz0iQEBnbmFtZUBAIHNwcmluZ3QgRGljaCBhdWYgZWlubWFsIGFuIHVuZCB3dWVyZ3QgRGljaEBAYWR2ZXJiQEAuIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCBzcHJpbmd0IGF1ZiBlaW5tYWwgQEB3ZW5AQCBhbiB1bmQgd3Vlcmd0ICIKKyAgICAgICAgK3doby0+UXVlcnlQcm9ub3VuKFdFTikrIkBAYWR2ZXJiQEAuIjsKKyAgICB9CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogV3VuZGVybiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAid3VuZGVyIjoKKyAgICBIRUxQQ0hFQ0soInd1bmRlciIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIXdobyAmJiAhYWR2ZXJiKQorICAgICAgUmV0dXJuKCJXaWUgb2RlciB1ZWJlciB3ZW4gd2lsbHN0IER1IERpY2ggd3VuZGVybj9cbiIpOworICAgIG91dF9zZWw9IkR1IHd1bmRlcnN0IERpY2hAQGFkdmVyYkBAIisod2hvID8gIiB1ZWJlciBAQHdlbkBALiIgOiAiLiIpOworICAgIGlmICh3aG8pIG91dF92aWM9IkBAZ25hbWVAQCB3dW5kZXJ0IHNpY2hAQGFkdmVyYkBAIHVlYmVyIERpY2guIjsKKyAgICBvdXRfb3RoPSJAQGduYW1lQEAgd3VuZGVydCBzaWNoQEBhZHZlcmJAQCIrKHdobyA/ICIgdWViZXIgQEB3ZW5AQC4iIDogIi4iKTsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBXdXNjaGVsbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAid3VzY2hlbCI6CisgICAgY2FzZSAid3VzY2hsIjoKKyAgICBIRUxQQ0hFQ0soInd1c2NoZWwiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiV2VuIHdpbGxzdCBEdSBkZW5uIHd1c2NoZWxuP1xuIik7CisgICAgaWYgKENoZWNrTGlmZSgwLE5PVF9ERUFELAorICAgICAgIiIsICJIbW0sIHNlaHIgdG90LiBOZSwgbGllYmVyIG5pY2h0LiIpKQorICAgICAgICByZXR1cm4gMTsKKyAgICBpZiAod2hvLT5RdWVyeVByb3AoUF9GUk9HKSkgIHsKKyAgICAgIHdyaXRlKCJEdSB2ZXJ3dXNjaGVsc3QuLi4gIGFlaC4uLiBobS4gRWluIEZyb3NjaCBoYXQgd29obCBuaXggIgorICAgICAgICArInp1bSBXdXNjaGVsbi5cbiIpOworICAgICAgcmV0dXJuIDE7CisgICAgfTsKKyAgICBHSE9TVENIRUNLKCJEdSB3aWxsc3QgIit3aG8tPm5hbWUoV0VOKSsiIHd1c2NoZWxuIC0gYWJlciBEZWluZSAiCisgICAgICAgICsiSGFlbmRlIGdlaGVuXG5nbGF0dCBkdXJjaCBkZW4gS29wZiBkdXJjaC5cbiIsCisgICAgICBnbmFtZSgpKyIgd2lsbCAiK3doby0+bmFtZShXRU4pKyIgZGVuIEtvcGYgd3VzY2hlbG4sIGFiZXIgIgorICAgICAgICArImRpZSBHZWlzdGVyLVxuaGFlbmRlIGdlaGVuIGdsYXR0IGR1cmNoIGRlbiBLb3BmIGR1cmNoLlxuIiwKKyAgICAgIGduYW1lKCkrIiB3aWxsIERpY2ggd3VzY2hlbG4sIGFiZXIgZGllc2UgR2Vpc3RlcmhhZW5kZSAiCisgICAgICAgICsiZ2VoZW5cbmdsYXR0IGR1cmNoIERlaW5lbiBLb3BmIGR1cmNoIC0gRHUgaGFzdCBlaW4gc2VsdHNhbWVzICIKKyAgICAgICAgKyJHZWZ1ZWhsIGRhYmVpLlxuIik7CisgICAgaWYgKG1lbWJlcigoeyJoaWdobGFuZGVyIiwiYm9pbmciLCJtaWV6ZSIsImZyZXVuZCJ9KSwgd2hvLT5xdWVyeV9yZWFsX25hbWUoKSk+LTEpCisgICAgICBzd2l0Y2ggKHdoby0+cXVlcnlfcmVhbF9uYW1lKCkpICB7CisgICAgICAgIGNhc2UgImhpZ2hsYW5kZXIiOiBzdHIxPSJGZWRlcm4iOyBicmVhazsKKyAgICAgICAgY2FzZSAiZnJldW5kIiAgICA6CisgICAgICAgIGNhc2UgIm1pZXplIiAgICAgOgorICAgICAgICBjYXNlICJib2luZyIgICAgIDogc3RyMT0iRmVsbCI7IGJyZWFrOworICAgICAgfQorICAgIGVsc2UgaWYgKHdoby0+aXNfY2xhc3NfbWVtYmVyKCh7Q0xfRFJBR09OLCBDTF9GSVNILCBDTF9SRVBUSUxFfSkpKQorICAgICAgc3RyMT0iU2NodXBwZW4iOworICAgIGVsc2UgaWYgKHdoby0+aXNfY2xhc3NfbWVtYmVyKCh7Q0xfQklSRCwgImVsc3RlciIsImdyZWlmIn0pKSkKKyAgICAgIHN0cjE9IkZlZGVybiI7CisgICAgZWxzZSBpZiAod2hvLT5pc19jbGFzc19tZW1iZXIoKHtDTF9NQU1NQUxfTEFORCxDTF9GRUxJTkUsInRpZ2VyIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdGVpbmJlaXNzZXIiLCJrbnVkZGVsZWlzYmFlciJ9KSkpCisgICAgICBzdHIxPSJGZWxsIjsKKyAgICBlbHNlIHN0cjE9IkhhYXJlIjsKKyAgICBvdXRfc2VsPSJEdSB2ZXJ3dXNjaGVsc3RAQGFkdmVyYkBAIEBAd2Vzc2VuQEAgIitzdHIxKyIuIjsKKyAgICBvdXRfdmljPSJAQG5hbWVAQCB2ZXJ3dXNjaGVsdEBAYWR2ZXJiQEAgRGVpbiIKKyAgICAgICsoc3RyMT09IkZlbGwiID8gIiAiIDogImUgIikrc3RyMSsiLiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAgdmVyd3VzY2hlbHRAQGFkdmVyYkBAIEBAd2Vzc2VuQEAgIitzdHIxKyIuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBaaXRpZXJlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAieml0aWVyIjoKKyAgICBIRUxQQ0hFQ0soInppdGllciIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmICghc3RyKQorICAgICAgUmV0dXJuKCJaaXRpZXJlIHdhcyBvZGVyIHdlbiB3b21pdD9cbiIpOworICAgIHNmb289aW1wbG9kZShleHBsb2RlKHN0ciwgIiAiKVsxLi5dLCAiICIpOworICAgIGlmIChzZm9vPT0iIikgc2Zvbz0wOworICAgIGlmICh3aG8pICB7CisgICAgICBvdXRfc2VsPSJEdSB6aXRpZXJzdCBAQHdlbkBAIisoc2ZvbyA/ICI6IFwiIitzZm9vKyJcIiIgOiAiIikrIi4iOworICAgICAgb3V0X3ZpYz0iQEBnbmFtZUBAIHppdGllcnQgRGljaCIrKHNmb28gPyAiOiBcIiIrc2ZvbysiXCIiIDogIiIpKyIuIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCB6aXRpZXJ0IEBAd2VuQEAiKyhzZm9vID8gIjogXCIiK3Nmb28rIlwiIiA6ICIiKSsiLiI7CisgICAgfQorICAgIGVsc2UgIHsKKyAgICAgIHNmb289ZXhwbG9kZShzdHIsICIvIilbMF07CisgICAgICBvdXRfc2VsPSJEdSB6aXRpZXJzdEBAYWR2ZXJiQEAiKyhzZm9vID8gIjogXCIiK3Nmb28rIlwiIiA6ICIiKSsiLiI7CisgICAgICBvdXRfb3RoPSJAQGduYW1lQEAgeml0aWVydEBAYWR2ZXJiQEAiKyhzZm9vID8gIjogXCIiK3Nmb28rIlwiIiA6ICIiKSsiLiI7CisgICAgfQorICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFppdHRlcm4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInppdHRlciI6CisgICAgSEVMUENIRUNLKCJ6aXR0ZXIiKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICFhZHZlcmIpCisgICAgICBSZXR1cm4oIlppdHRlcmUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgeml0dGVyc3QiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQC4iIDogIiB2b3IgQW5nc3QuIik7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIHppdHRlcnQiKyhhZHZlcmIgPyAiQEBhZHZlcmJAQC4iIDogIiB2b3IgQW5nc3QuIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogU2NodWx0ZXJ6dWNrZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInp1Y2siIDoKKyAgICBIRUxQQ0hFQ0soInp1Y2siKTsKKyAgICAgICAgICBpZiAoc3RyKQorICAgICAgaWYgKHNzY2FuZihzdHIsIiVzIG1pdCBkZW4gc2NodWx0ZXJuIixzZm9vKSkKKyAgICAgICAgc3RyPXNmb287CisgICAgZWxzZSBpZiAoc3NjYW5mKHN0ciwiJXMgZGVuIHNjaHVsdGVybiIsc2ZvbykpCisgICAgICBzdHI9c2ZvbzsKKyAgICBlbHNlCisgICAgICBpZiAoc3NjYW5mKHN0ciwiJXMgc2NodWx0ZXJuIixzZm9vKSkKKyAgICAgICAgc3RyPXNmb287CisgICAgaWYgKHN0cj09IiIpIHN0cj0wOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiWnVja2Ugd2llIG1pdCBkZW4gU2NodWx0ZXJuP1xuIik7CisgICAgb3V0X3NlbD0iRHUgenVja3N0QEBhZHZlcmJAQCBtaXQgZGVuIFNjaHVsdGVybi4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCB6dWNrdCIrKGFkdmVyYiA/ICJAQGFkdmVyYkBAIiA6ICIgcmF0bG9zIikKKyAgICAgICAgICAgICsiIG1pdCBkZW4gU2NodWx0ZXJuLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogWndpbmtlcm4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInp3aW5rZXIiOgorICAgIEhFTFBDSEVDSygiendpbmtlciIpOworICAgIGlmIChnaG9zdCgpKQorICAgICAgUmV0dXJuKCJWZXJnaXNzIGVzIC0gZGFzIGlzdCBhbHMgR2Vpc3QgdmllbCB6dSB1bmF1ZmZhZWxsaWcsIGFscyBkYXNzXG4iCisgICAgICAgICsiZXMgYW5kZXJlIExldXRlIHNlaGVuIHd1ZXJkZW4uXG4iKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoc3RyICYmICF3aG8gJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiWndpbmtlcmUgd2llPyBad2lua2VyZSB3ZW0genU/XG4iKTsKKyAgICBpZiAod2hvICYmIENoZWNrTGlmZShOT1RfU0VMRixOT1RfREVBRCwKKyAgICAgICJEdSBrYW5uc3QgRGlyIG5pY2h0IHNlbGJlciB6dXp3aW5rZXJuLiIsCisgICAgICAiV2llc28gcmVhZ2llcnQgZGFzIERpbmcgZGEgbmljaHQgYXVmIERlaW4gWndpbmtlcm4/IElzdCBlcyBldHdhIHRvdD8iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgb3V0X3NlbD0iRHUgendpbmtlcnN0QEAgd2VtQEBAQGFkdmVyYkBAIisod2hvID8gIiB6dS4iIDogIi4iKTsKKyAgICBpZiAod2hvKSBvdXRfdmljPSJAQG5hbWVAQCB6d2lua2VydCBEaXJAQGFkdmVyYkBAIHp1LiI7CisgICAgb3V0X290aD0iQEBuYW1lQEAgendpbmtlcnRAQCB3ZW1AQEBAYWR2ZXJiQEAiKyh3aG8gPyAiIHp1LiIgOiAiLiIpOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIFp1bmdlIHJhdXNzdHJlY2tlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic3RyZWNrIjoKKyAgICBIRUxQQ0hFQ0soInN0cmVjayIpOworICAgIEdIT1NUQ0hFQ0soIlNvcnJ5LCBEdSBoYXN0IGtlaW5lIFp1bmdlIHp1bSBSYXVzc3RyZWNrZW4uXG4iLCIiLDApOworICAgIGlmICghc3RyKQorICAgICAgUmV0dXJuKCJTdHJlY2tlIHdhcyB3aWUgd2VtIHdvIHdhbm4gd2llc28/XG4iKTsKKyAgICBzdHI9bG93ZXJfY2FzZShzdHIpOworICAgIGlmIChzc2NhbmYoc3RyLCAiJXMgenVuZ2UgcmF1cyIsIHN0cjEpIT0xICYmCisgICAgc3NjYW5mKHN0ciwgIiVzIGRpZSB6dW5nZSByYXVzIiwgc3RyMSkhPTEpCisgICAgICBSZXR1cm4oIlN0cmVja2Ugd2FzIHdpZSB3ZW0gd28gd2FubiB3aWVzbz9cbiIpOworICAgIFBhcnNlUmVzdChzdHIxKTsKKyAgICBpZiAoZm9yX2FsbCkgIHsKKyAgICAgIG91dF9zZWw9IkR1IHN0cmVja3N0IEBAYWxsZUBAQEBhZHZlcmJAQCBkaWUgWnVuZ2UgcmF1cy4iOworICAgICAgb3V0X3ZpYz0iQEBuYW1lQEAgc3RyZWNrdCBAQGFsbGVAQEBAYWR2ZXJiQEAgZGllIFp1bmdlIHJhdXMuIjsKKyAgICAgIHJldHVybiBNaXhlZE91dChXRU0pOworICAgIH0KKyAgICBvdXRfc2VsPSJEdSBzdHJlY2tzdEBAIHdlbUBAQEBhZHZlcmJAQCBkaWUgWnVuZ2UgcmF1cy4iOworICAgIGlmICh3aG8pIG91dF92aWM9IkBAbmFtZUBAIHN0cmVja3QgRGlyQEBhZHZlcmJAQCBkaWUgWnVuZ2UgcmF1cy4iOworICAgIG91dF9vdGg9IkBAbmFtZUBAIHN0cmVja3RAQCB3ZW1AQEBAYWR2ZXJiQEAgZGllIFp1bmdlIHJhdXMuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvLyBTcGV6aWFsc2FjaGVuIC0gR2Vpc3RlcnZlcmJlbiB1bmQgTWFnaWVydmVyYmVuCisKKyAgICAvKioqKioqKioqKioqKioqKiBSYXNzZWxuICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJyYXNzZWwiOgorICAgIGNhc2UgInJhc3NsIjoKKyAgICBpZiAoIWdob3N0KCkpCisgICAgICBSZXR1cm4oIkRhcyBpc3QgbmljaHQgRGVpbiBGYWNoZ2ViaWV0IC0gRHUgYmlzdCBkb2NoIGtlaW4gR2Vpc3QhXG4iKTsKKyAgICBIRUxQQ0hFQ0soInJhc3NlbCIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiUmFzc2VsIHdpZT9cbiIpOworICAgIG91dF9zZWw9IkR1IHJhc3NlbHN0IisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAiIDogIiBmdWVyY2h0ZXJsaWNoIikKKyAgICAgICsiIG1pdCBlaW5lciByb3N0aWdlbiBSYXNzZWxrZXR0ZSxcbiIKKyAgICAgICsiZGllIER1IGF1ZiBlaW5tYWwgZnVlciBlaW5lbiBNb21lbnQgaW4gZGVyIEhhbmQgaGFlbHRzdC4iOworICAgIG91dF9vdGg9IkBAZ25hbWVAQCBob2x0IGF1ZiBlaW5tYWwgZWluZSByb3N0aWdlIFJhc3NlbGtldHRlIGF1c1xuIgorICAgICAgKyJkZW0gTmljaHRzIHVuZCBmYWVuZ3QgYW4sIisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAiIDogIiBmdWVyY2h0ZXJsaWNoIikKKyAgICAgICsiIGRhbWl0IHp1IHJhc3NlbG4uXG4iCisgICAgICArIkRhbmFjaCBpc3QgZGllIEtldHRlIGF1ZiBlaW5tYWwgd2llZGVyIHZlcnNjaHd1bmRlbi4iOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqKioqIEhldWxlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiaGV1bCI6CisgICAgaWYgKCFnaG9zdCgpKQorICAgICAgUmV0dXJuKCJMYXNzIGRhcyBtYWwgZGVuIEZhY2hsZXV0ZW4gKGFsc28gZGVuIEdlaXN0ZXJuKS5cbiIpOworICAgIEhFTFBDSEVDSygiaGV1bCIpOworICAgIFBhcnNlUmVzdChzdHIpOworICAgIGlmIChzdHIgJiYgIWFkdmVyYikKKyAgICAgIFJldHVybigiSGV1bGUgd2llP1xuIik7CisgICAgb3V0X3NlbD0iRHUgaGV1bHN0IisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAuIiA6ICIgc2NoYXVlcmxpY2guIik7CisgICAgb3V0X290aD0iQEBnbmFtZUBAIGhldWx0IisoYWR2ZXJiID8gIkBAYWR2ZXJiQEAuIiA6ICIgc2NoYXVlcmxpY2guIik7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogVHJldGVuICh0cmV0ZXQpICoqKioqKioqKioqKioqKi8KKyAgICBjYXNlICJraWNrIjoKKyAgICBpZiAoIUlTX1dJWkFSRCh0aGlzX3BsYXllcigpKSkKKyAgICAgIHJldHVybiAwOworICAgIEhFTFBDSEVDSygia2ljayIpOworICAgIGlmICghc3RyKSAgeworICAgICAgR0hPU1RDSEVDSygiRGVpbiBGdXNzIGZhZWhydCBkdXJjaCBkaWUgYmVydWVobXRlIGxhbmd2ZXJnZXNzZW5lICIKKyAgICAgICAgICArInVuc2ljaHRiYXJlIFNjaGlsZGtyb2V0ZVxuaGluZHVyY2guXG4iLAorICAgICAgICBnbmFtZSgpKyIgd2lsbCBkaWUgYmVydWVobXRlIGxhbmd2ZXJnZXNzZW5lIHVuc2ljaHRiYXJlXG4iCisgICAgICAgICAgKyJTY2hpbGRrcm9ldGUgdHJldGVuLCBhYmVyICIrUVBQKE1BTEUsV0VSKQorICAgICAgICAgICsiIEZ1c3MgZmFlaHJ0IGR1cmNoIHNpZSBoaW5kdXJjaC5cbiIsIDApOworICAgICAgb3V0X3NlbD0iRHUgdHJldGVzdCBkaWUgYmVydWVobXRlIGxhbmd2ZXJnZXNzZW5lIHVuc2ljaHRiYXJlICIKKyAgICAgICAgKyJTY2hpbGRrcm9ldGUuIjsKKyAgICAgIG91dF9vdGg9IkBAbmFtZUBAIHRyZXRldCBkaWUgYmVydWVobXRlIGxhbmd2ZXJnZXNzZW5lIHVuc2ljaHRiYXJlICIKKyAgICAgICAgKyJTY2hpbGRrcm9ldGUuIjsKKyAgICB9CisgICAgZWxzZSAgeworICAgICAgUGFyc2VSZXN0KHN0cik7CisgICAgICBpZiAoZm9yX2FsbCkgIHsKKyAgICAgICAgb3V0X3NlbD0iRHUgdHJldGVzdCBAQGFsbGVAQEBAYWR2ZXJiQEAuIjsKKyAgICAgICAgb3V0X3ZpYz0iQEBuYW1lQEAgdHJldGV0IEBAYWxsZUBAQEBhZHZlcmJAQC4iOworICAgICAgICByZXR1cm4gTWl4ZWRPdXQoV0VOKTsKKyAgICAgIH0KKyAgICAgIGlmICghd2hvICYmICFhZHZlcmIpCisgICAgICAgIFJldHVybigiV2VubiBEdSBzY2hvbiB3YXMgbmFjaCBraWNrIHRpcHBzdCwgZGFubiBzYWcgbWlyIHdlbiAiCisgICAgICAgICAgKyJvZGVyIHdpZSBpY2hkYXMgc29sbC5cbiIpOworICAgICAgaWYgKHdobyAmJiBDaGVja0xpZmUoTk9UX1NFTEYsTk9UX0RFQUQsCisgICAgICAgICJEdSBzY2hhZmZzdCBlcyBuaWNodCwgRGlyIHNlbGJlciBpbiBkZW4gSGludGVybiB6dSB0cmV0ZW4uIiwKKyAgICAgICAgIlRvdGUgU2FjaGVuIHRyaXR0IG1hbiBuaWNodCBhdWNoIG5vY2ghIikpCisgICAgICAgICAgcmV0dXJuIDE7CisgICAgICBpZiAod2hvKSAgeworICAgICAgICBvdXRfc2VsPSJEdSB0cmV0ZXN0QEAgd2VuQEBAQGFkdmVyYkBALiI7CisgICAgICAgIGlmICh3aG8pIG91dF92aWM9IkBAZ25hbWVAQCB0cmV0ZXQgRGljaEBAYWR2ZXJiQEAuIjsKKyAgICAgICAgb3V0X290aD0iQEBnbmFtZUBAIHRyZXRldEBAIHdlbkBAQEBhZHZlcmJAQC4iOworICAgICAgfQorICAgICAgZWxzZSAgeworICAgICAgICBvdXRfc2VsPSJEdSB0cmV0ZXN0IGRpZSBiZXJ1ZWhtdGUgbGFuZ3Zlcmdlc3NlbmUgdW5zaWNodGJhcmUgIgorICAgICAgICAgICsiU2NoaWxka3JvZXRlQEBhZHZlcmJAQC4iOworICAgICAgICBvdXRfb3RoPSJAQGduYW1lQEAgdHJldGV0IGRpZSBiZXJ1ZWhtdGUgbGFuZ3Zlcmdlc3NlbmUgdW5zaWNodGJhcmUgIgorICAgICAgICAgICsiU2NoaWxka3JvZXRlXG5AQGFkdmVyYkBALiI7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8qKioqKioqKioqKioqIE5hc3NzcHJpdHplbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAic3BsYXNoIjoKKyAgICBpZiAoIUlTX1dJWkFSRCh0aGlzX3BsYXllcigpKSAmJgorICAgICEoSVNfU0VFUih0aGlzX3BsYXllcigpKSAmJiBwcmVzZW50KCJTRUhFUlxuc3ByaXR6cGlzdG9sZSIsdGhpc19wbGF5ZXIoKSkpKQorICAgICAgcmV0dXJuIDA7CisgICAgSEVMUENIRUNLKCJzcGxhc2giKTsKKyAgICBQYXJzZVJlc3Qoc3RyKTsKKyAgICBpZiAoZm9yX2FsbCkgIHsKKyAgICAgIG91dF9zZWw9IkR1IHppZWhzdCBEZWluZSBXYXNzZXJwaXN0b2xlIHVuZCBzcHJpdHp0IEBAYWxsZUBAQEBhZHZlcmJAQCAiCisgICAgICAgICsicGF0c2NobmFzcy4iOworICAgICAgb3V0X3ZpYz0iQEBnbmFtZUBAIHppZWh0ICIrUVBQKEZFTUFMRSxXRU4pKyIgV2Fzc2VycGlzdG9sZSB1bmQgc3ByaXR6dFxuIgorICAgICAgICArIkBAYWxsZUBAQEBhZHZlcmJAQCBwYXRzY2huYXNzLiI7CisgICAgICByZXR1cm4gTWl4ZWRPdXQoV0VOKTsKKyAgICB9CisgICAgaWYgKCF3aG8pCisgICAgICBSZXR1cm4oIldlbiB3aWxsc3QgRHUgZGVubiBuYXNzbWFjaGVuP1xuIik7CisgICAgaWYgKHdobyA9PSB0aGlzX3BsYXllcigpKSAgeworICAgICAgb3V0X3NlbD0iU2FnIG1hbCwga29tbXN0IER1IERpciBuaWNodCBlaW4gYmlzc2NoZW4gZG9vZiB2b3I/XG4iCisgICAgICAgICsiRHUgemllaHN0IERlaW5lIFdhc3NlcnBpc3RvbGUgdW5kIHNwcml0enQgRGljaEBAYWR2ZXJiQEAgc2VsYmVyIHBhdHNjaG5hc3MuIjsKKyAgICAgIG91dF9vdGg9IkBAZ25hbWVAQCB6aWVodCAiK1FQUChGRU1BTEUsV0VOKSsiIFdhc3NlcnBpc3RvbGUgdW5kIHNwcml0enQgIgorICAgICAgICArInNpY2hAQGFkdmVyYkBAIGF1cyB1bmVyZmluZGxpY2hlbiBHcnVlbmRlbiBzZWxic3QgcGF0c2NobmFzcy4iOworICAgIH0KKyAgICBlbHNlICB7CisgICAgICBvdXRfc2VsPSJEdSB6aWVoc3QgRGVpbmUgV2Fzc2VycGlzdG9sZSB1bmQgc3ByaXR6dCBAQHdlbkBAQEBhZHZlcmJAQCAiCisgICAgICAgICsicGF0c2NobmFzcy4iOworICAgICAgb3V0X3ZpYz0iQEBnbmFtZUBAIHppZWh0ICIrUVBQKEZFTUFMRSxXRU4pKyIgV2Fzc2VycGlzdG9sZSB1bmQgc3ByaXR6dCAiCisgICAgICAgICsiRGljaEBAYWR2ZXJiQEAgcGF0c2NobmFzcy4iOworICAgICAgb3V0X290aD0iQEBnbmFtZUBAIHppZWh0ICIrUVBQKEZFTUFMRSxXRU4pKyIgV2Fzc2VycGlzdG9sZSB1bmQgc3ByaXR6dCAiCisgICAgICAgICsiQEB3ZW5AQEBAYWR2ZXJiQEAgcGF0c2NobmFzcy4iOworICAgIH0KKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBBbmZsYW1tZW4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgImZsYW0iOgorICAgIGlmICghSVNfV0laQVJEKHRoaXNfcGxheWVyKCkpICYmCisgICAgIShJU19TRUVSKHRoaXNfcGxheWVyKCkpICYmIHByZXNlbnQoIlNFSEVSXG5mbGFtbWVud2VyZmVyIix0aGlzX3BsYXllcigpKSkpCisgICAgICByZXR1cm4gMDsKKyAgICBIRUxQQ0hFQ0soImZsYW1lIik7CisgICAgaWYgKGdob3N0KCkpCisgICAgICBSZXR1cm4oIkR1IGhhc3QgbGVpZGVyIGdyYWRlIERlaW5lbiBGbGFtbWVud2VyZmVyIG5pY2h0IGRhYmVpLlxuIik7CisgICAgUGFyc2VSZXN0KHN0cik7CisgICAgaWZvbz0hcmFuZG9tKDcpOworICAgIGlmIChmb3JfYWxsKSAgeworICAgICAgb3V0X3NlbD0iRHUgaG9sc3QgYXVzIERlaW5lbiB0aWVmc3RlbiBUYXNjaGVuIChvZGVyIHdhcyB3ZWlzcyBkZW5uICIKKyAgICAgICAgKyJpY2ggd29oZXIpIERlaW5lblxuTW9yZ2VuR3JhdWVuIGhhbmRnZWFyYmVpdGV0ZW4gTWluaS1GbGFtbWVud2VyZmVyICIKKyAgICAgICAgKyIodG0pLCByaWNodGVzdCBpaG4gYXVzIHVuZC4uLlxuIgorICAgICAgICArKGlmb28gPyAic2NoYXVzdCBsZWljaHQgZnJ1c3RyaWVydCBhdWYgZGFzIFN0cmVpY2hob2x6LCBpbiBkYXMgIgorICAgICAgICAgICsiZXIgc2ljaCB2ZXJ3YW5kZWx0IGhhdC4iCisgICAgICAgIDogImZldWVyc3RAQGFkdmVyYkBAIGVpbmVuIHJpZXNpZ2VuIEZldWVyYmFsbCBhdWYgQEBhbGxlQEAgYWIuXG4iCisgICAgICAgICAgKyJFcyByaWVjaHQgYXVmIGVpbm1hbCBzbyB2ZXJicmFubnQgaGllci4uLiIpOworICAgICAgb3V0X3ZpYz0iQEBuYW1lQEAgaG9sdCBhdWYgZWlubWFsIGlyZ2VuZHdvaGVyIGVpbmVuIE1vcmdlbkdyYXVlbiAiCisgICAgICAgICsiaGFuZGdlYXJiZWl0ZXRlblxuTWluaS1GbGFtbWVud2VyZmVyICh0bSksIHJpY2h0ZXQgaWhuIGF1cyB1bmQuLi5cbiIKKyAgICAgICAgKyhpZm9vID8gInNjaGF1dCB6aWVtbGljaCBmcnVzdHJpZXJ0IGF1ZiBkYXMgU3RyZWljaGhvbHosIGluIGRhcyAiCisgICAgICAgICAgKyJzaWNoIGRhcyBEaW5nIHZlcndhbmRlbHQgaGF0LiIKKyAgICAgICAgOiAiZmV1ZXJ0QEBhZHZlcmJAQCBlaW5lbiByaWVzaWdlbiBGZXVlcmJhbGwgYXVmIEBAYWxsZUBAIGFiLlxuIgorICAgICAgICAgICsiRGlyIHdpcmQgc28gd2FybSB1bSdzIEhlcnouLi4iKTsKKyAgICAgIHJldHVybiBNaXhlZE91dChXRU4pOworICAgIH0KKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiV2VuIHdpbGxzdCBEdSBkZW5uIGFua29rZWxuP1xuIik7CisgICAgb3V0X3NlbD0iRHUgaG9sc3QgYXVzIERlaW5lbiB0aWVmc3RlbiBUYXNjaGVuIChvZGVyIHdhcyB3ZWlzcyBkZW5uICIKKyAgICAgICsiaWNoIHdvaGVyKSBEZWluZW5cbk1vcmdlbkdyYXVlbiBoYW5kZ2VhcmJlaXRldGVuIE1pbmktRmxhbW1lbndlcmZlciAiCisgICAgICArIih0bSksIHJpY2h0ZXN0IGlobiBhdXMgdW5kLi4uXG4iCisgICAgICArKGlmb28gPyAic2NoYXVzdCBsZWljaHQgZnJ1c3RyaWVydCBhdWYgZGFzIFN0cmVpY2hob2x6LCBpbiBkYXMgZXIgIgorICAgICAgICArInNpY2ggdmVyd2FuZGVsdCBoYXQuIgorICAgICAgOiAiZmV1ZXJzdEBAYWR2ZXJiQEAgZWluZW4gcmllc2lnZW4gRmV1ZXJiYWxsIGF1ZiBAQHdlbkBAIGFiLlxuIgorICAgICAgICArIkVzIHJpZWNodCBhdWYgZWlubWFsIHNvIHZlcmJyYW5udCBoaWVyLi4uIik7CisgICAgb3V0X3ZpYz0iQEBuYW1lQEAgaG9sdCBhdWYgZWlubWFsIGlyZ2VuZHdvaGVyIGVpbmVuIE1vcmdlbkdyYXVlbiAiCisgICAgICArImhhbmRnZWFyYmVpdGV0ZW5cbk1pbmktRmxhbW1lbndlcmZlciAodG0pLCByaWNodGV0IGlobiBhdWYgRGljaCAiCisgICAgICArImF1cyB1bmQuLi5cbiIKKyAgICAgICsoaWZvbyA/ICJzY2hhdXQgemllbWxpY2ggZnJ1c3RyaWVydCBhdWYgZGFzIFN0cmVpY2hob2x6LCBpbiBkYXMgIgorICAgICAgICArInNpY2ggZGFzIERpbmdcbnZlcndhbmRlbHQgaGF0LiIKKyAgICAgIDogImZldWVydEBAYWR2ZXJiQEAgZWluZW4gcmllc2lnZW4gRmV1ZXJiYWxsIGF1ZiBEaWNoIGFiLlxuIgorICAgICAgICArIkRpciB3aXJkIHNvIHdhcm0gdW1zIEhlcnouLi4iKTsKKyAgICBvdXRfb3RoPSJAQG5hbWVAQCBob2x0IGF1ZiBlaW5tYWwgaXJnZW5kd29oZXIgZWluZW4gTW9yZ2VuR3JhdWVuICIKKyAgICAgICsiaGFuZGdlYXJiZWl0ZXRlblxuTWluaS1GbGFtbWVud2VyZmVyICh0bSksIHJpY2h0ZXQgaWhuICIKKyAgICAgICsiYXVmQEAgd2VuQEAgYXVzIHVuZC4uLlxuIgorICAgICAgKyhpZm9vID8gInNjaGF1dCB6aWVtbGljaCBmcnVzdHJpZXJ0IGF1ZiBkYXMgU3RyZWljaGhvbHosIGluIGRhcyAiCisgICAgICAgICsic2ljaCBkYXMgRGluZ1xudmVyd2FuZGVsdCBoYXQuIgorICAgICAgOiAiZmV1ZXJ0QEBhZHZlcmJAQCBlaW5lbiByaWVzaWdlbiBGZXVlcmJhbGwgYXVmQEAgd2VuQEAgYWIuXG5FcyAiCisgICAgICAgICsicmllY2h0IGF1ZiBlaW5tYWwgaXJnZW5kd2llIHZlcmJyYW5udCBoaWVyIC4uLiIpOworICAgIHJldHVybiBGZWVsSXQoKTsKKworICAgIC8vIFNwZWNpYWwgMjogcmVtb3RlIHZlcmJzCisKKyAgICAvKioqKioqKioqKioqKioqKiBSZW1vdGUga251ZGRlbG4gKioqKioqKioqKioqKioqLworICAgIGNhc2UgInJrbnVkZGVsIjoKKyAgICBjYXNlICJya251ZGRsIjoKKyAgICBIRUxQQ0hFQ0soInJrbnVkZGVsIik7CisgICAgaWYgKFBhcnNlUmVtb3RlKHN0cikpCisgICAgICByZXR1cm4gMTsKKyAgICBpZiAoIXdobykKKyAgICAgIFJldHVybigiS251ZGRsZSB3ZW4/XG4iKTsKKyAgICBpZiAoQ2hlY2tMaWZlKE5PVF9TRUxGLDAsCisgICAgICAiRGFzIGJyaW5ndCBkb2NoIG5peCwgbGFzcyBlcyBoYWx0LiIsCisgICAgICAwKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgaWYgKHByZXNlbnQod2hvLCBlbnZpcm9ubWVudCgpKSkKKyAgICAgIFJldHVybigiV2VubiBqZW1hbmQgbmViZW4gRGlyIHN0ZWh0LCBuaW1tIGtudWRkZWwuXG4iKTsKKyAgICBvdXRfc2VsPSJEdSBrbnVkZGVsc3QgQEB3ZW5AQEBAYWR2ZXJiQEAgYXVzIGRlciBGZXJuZS4iOworICAgIG91dF92aWM9IkBAZ25hbWVAQCBrbnVkZGVsdCBEaWNoQEBhZHZlcmJAQCBhdXMgZGVyIEZlcm5lLiI7CisgICAgcmV0dXJuIEZlZWxJdCgpOworCisgICAgLyoqKioqKioqKioqKioqKiogUmVtb3RlIHdpbmtlbiAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAicndpbmsiOgorICAgIEhFTFBDSEVDSygicndpbmsiKTsKKyAgICBpZiAoUGFyc2VSZW1vdGUoc3RyKSkKKyAgICAgIHJldHVybiAxOworICAgIGlmICghd2hvKQorICAgICAgUmV0dXJuKCJXaW5rZSB3ZW0genU/XG4iKTsKKyAgICBpZiAoQ2hlY2tMaWZlKE5PVF9TRUxGLDAsCisgICAgICAiU2VociB3aXR6aWcuIFBhaC4iLCAwKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgaWYgKHByZXNlbnQod2hvLCBlbnZpcm9ubWVudCgpKSkKKyAgICAgIFJldHVybigiV2VubiBqZW1hbmQgbmViZW4gRGlyIHN0ZWh0LCBuaW1tIHdpbmsuXG4iKTsKKyAgICBvdXRfc2VsPSJEdSB3aW5rc3QgQEB3ZW1AQEBAYWR2ZXJiQEAgYXVzIGRlciBGZXJuZSB6dS4iOworICAgIG91dF92aWM9IkBAZ25hbWVAQCB3aW5rdCBEaXJAQGFkdmVyYkBAIGF1cyBkZXIgRmVybmUgenUuIjsKKyAgICByZXR1cm4gRmVlbEl0KCk7CisKKyAgICAvKioqKioqKioqKioqKioqKiBWZXJiZW5saXN0ZSAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAidmVyYiI6CisgICAgY2FzZSAidmVyYmVuIjoKKyAgICBIRUxQQ0hFQ0soInZlcmIiKTsKKyAgICBNb3JlKFNPVUxIRUxQLT5IZWxwKCkpOworICAgIHJldHVybiAxOworCisgICAgLyoqKioqKioqKioqKioqKiogQWR2ZXJiaWVudmVyd2FsdHVuZyAqKioqKioqKioqKioqKiovCisgICAgY2FzZSAiYWR2ZXJiIjoKKyAgICBjYXNlICJhZHZlcmJlbiI6CisgICAgY2FzZSAiYWR2ZXJiaWVuIjogeyAgIC8qIERhcyBpc3QgZGllIHJpY2h0aWdlIEZvcm0sIGFiZXIgd2VyIHdlaXNzIGRhcz8gKi8KKyAgICBzdHJpbmcgZjEsZjI7CisgICAgSEVMUENIRUNLKCJhZHZlcmIiKTsKKyAgICBpZiAoIXN0ciB8fCBzdHI9PSIjIiB8fCBzdHI9PSIkIikKKyAgICAgIHJldHVybiB6ZWlnZV9hZHZlcmJzKChzdHI9PSIjIiA/IDEgOiAoc3RyPT0iJCIgPyAyIDogMCkpKTsKKyAgICBpZiAoc3NjYW5mKHN0ciwgIiVzICVzIiwgZjEsZjIpPT0yKSAgeworICAgICAgZjEgPSBsb3dlcl9jYXNlKGYxKTsgLy8ga2xlaW5nZXNjaHJpZWJlbiBzcGVpY2hlcm4sIHNwYXJ0IFVtd2FuZGx1bmcKKyAgICAgIGlmIChmMT09IiIpCisgICAgICAgIFJldHVybigiSG0sIGRhIG11c3Mgd29obCBlaW4gTGVlcnplaWNoZW4genUgdmllbCBnZXdlc2VuIHNlaW4uIEJpdHRlICIKKyAgICAgICAgICArIm5vY2htYWwsXG5hYmVyIG9obmUgenV2aWVsZSBMZWVyemVpY2hlbi5cbiIpOworICAgICAgaWYgKGYxPT0iPyIpICB7CisgICAgICAgIGYyID0gbG93ZXJfY2FzZShmMik7CisgICAgICAgIHN0cmluZyBtYXRjaDsKKyAgICAgICAgaWYgKChtYXRjaD1RdWVyeVN0ZEFkdmVyYnMoKVtmMl0gfHwgcGxyX2FkdmVyYnNbZjJdKSkKKyAgICAgICAgICB3cml0ZSgiRGllIEFia3Vlcnp1bmcgIitmMisiIGdlaG9lcnQgenUgZGVtIEFkdmVyYjpcbiIrbWF0Y2grTEYpOworICAgICAgICBlbHNlCisgICAgICAgICAgd3JpdGUoIkRpZXNlIEFia3Vlcnp1bmcgaXN0IGJpc2hlciBuaWNodCBkZWZpbmllcnQuXG4iKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgICBpZiAoUXVlcnlTdGRBZHZlcmJzKClbZjFdKQorICAgICAgICBSZXR1cm4oIkRpZSBTdGFuZGFyZGFia3Vlcnp1bmdlbiBrb2VubmVuIG5pY2h0IG5ldSBkZWZpbmllcnQgIgorICAgICAgICAgICsid2VyZGVuLlxuIik7CisgICAgICBpZiAoc2l6ZW9mKHBscl9hZHZlcmJzKT49MTAwKSAKKyAgICAgIHsKKyAgICAgICAgd3JpdGUoIk1laHIgYWxzIDEwMCBlaWdlbmUgQWR2ZXJiaWVuIGthbm5zdCBEdSBuaWNodCBkZWZpbmllcmVuLlxuIik7CisgICAgICAgIHJldHVybiAxOworICAgICAgfQorICAgICAgaWYgKHBscl9hZHZlcmJzW2YxXSkgIHsKKyAgICAgICAgcGxyX2FkdmVyYnNbZjFdPWYyOworICAgICAgICB3cml0ZSgiT0ssIEFkdmVyYiBtaXQgZGVyIEFia3Vlcnp1bmcgXCIiK2YxKyJcIiBhdWYgXCIiK2YyCisgICAgICAgICAgKyJcIiBnZXNldHp0LlxuIik7CisgICAgICB9CisgICAgICBlbHNlICB7CisgICAgICAgIGlmIChzaXplb2YoZjEpID4gNikKKyAgICAgICAgICBSZXR1cm4oIkRpZSBBYmt1ZXJ6dW5nIGlzdCB6dSBsYW5nLCBiaXR0ZSBuaWNodCBtZWhyIGFscyAiCisgICAgICAgICAgICArIjYgWmVpY2hlbi5cbiIpOworICAgICAgICBwbHJfYWR2ZXJic1tmMV09ZjI7CisgICAgICAgIHdyaXRlKCJPSywgbmV1ZXMgQWR2ZXJiIFwiIitmMisiXCIgbWl0IGRlciBBYmt1ZXJ6dW5nIFwiIitmMSsiXCIuXG4iKTsKKyAgICAgIH0KKyAgICB9CisgICAgZWxzZSAgeworICAgICAgc3RyID0gbG93ZXJfY2FzZShzdHIpOworICAgICAgaWYgKFF1ZXJ5U3RkQWR2ZXJicygpW3N0cl0pCisgICAgICAgIFJldHVybigiRGllIFN0YW5kYXJkYWR2ZXJiZW4ga29lbm5lbiBuaWNodCBnZWxvZXNjaHQgd2VyZGVuLlxuIik7CisgICAgICBlbHNlIGlmICghcGxyX2FkdmVyYnNbc3RyXSkKKyAgICAgICAgUmV0dXJuKCJEdSBoYXN0IGtlaW4gQWR2ZXJiIG1pdCBkaWVzZXIgQWJrdWVyenVuZy5cbiIKKyAgICAgICAgICArIlN5bnRheDogYWR2ZXJiLCB1bSBkaWUgQWR2ZXJiaWVuIGFuenV6ZWlnZW4sXG4iCisgICAgICAgICAgKyIgICAgICAgIGFkdmVyYiAjLCB1bSBudXIgRGVpbmUgQWR2ZXJiaWVuIGFuenV6ZWlnZW4sXG4iCisgICAgICAgICAgKyIgICAgICAgIGFkdmVyYiAkLCB1bSBudXIgZGllIFN0YW5kYXJkYWR2ZXJiaWVuIGFuenV6ZWlnZW4sXG4iCisgICAgICAgICAgKyIgICAgICAgIGFkdmVyYiA/IDxBYmt1ZXJ6dW5nPiwgdW0gbmFjaHp1c2VoZW4sIG9iIDxBYmt1ZXJ6dW5nPiAiCisgICAgICAgICAgICArImRlZmluaWVydCBpc3QsXG4iCisgICAgICAgICAgKyIgICAgICAgIGFkdmVyYiA8QWJrdWVyenVuZz4gPEFkdmVyYj4sIHVtIGRlciA8QWJrdWVyenVuZz4gZGFzICIKKyAgICAgICAgICAgICsiPEFkdmVyYj5cbiIKKyAgICAgICAgICArIiAgICAgICAgICAgICAgIHp1enVvcmRuZW4sXG4iCisgICAgICAgICAgKyIgICAgICAgIGFkdmVyYiA8QWJrdWVyenVuZz4sIHVtIGRhcyBBZHZlcmIgbWl0IGRlciA8QWJrdWVyenVuZz4gIgorICAgICAgICAgICAgKyJ6dSBsb2VzY2hlbixcbiIpOworICAgICAgZWxzZSAgeworICAgICAgICB3cml0ZSgiT0ssIEFkdmVyYiBcIiIrcGxyX2FkdmVyYnNbc3RyXSsiXCIgZ2Vsb2VzY2h0LlxuIik7CisgICAgICAgIHBscl9hZHZlcmJzPW1fY29weV9kZWxldGUocGxyX2FkdmVyYnMsIHN0cik7CisgICAgICB9CisgICAgfQorICAgIHJldHVybiAxOyAKKyAgICB9CisgIH0KKyAgcmV0dXJuKDApOyAgLy9mYWxsdGhyb3VnaAorfQorCmRpZmYgLS1naXQgYS9zdGQvcGxheWVyL3NvdWxoZWxwLmMgYi9zdGQvcGxheWVyL3NvdWxoZWxwLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjdhNDhmOQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvc291bGhlbHAuYwpAQCAtMCwwICsxLDMxNyBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHBsYXllci9zb3VsaGVscC5jIC0tIEhpbGZlIHp1IGRlbiBTb3Vsa29tbWFuZG9zCisvLworLy8gJElkOiBzb3VsaGVscC5jIDc0MjMgMjAxMC0wMi0wNyAyMjo1NjozOFogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzLHNhdmVfdHlwZXMKKworI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2lmZGVmIFdFQ0tFCisjdW5kZWYgV0VDS0UKKyNlbmRpZgorI2RlZmluZSBXRUNLRQorCitzdGF0aWMgc3RyaW5nICp3aXpjbWRzLCAqcGxyY21kcywgKmdob3N0Y21kczsKK3N0YXRpYyBtYXBwaW5nIGhlbHA7CisKK3ByaXZhdGUgc3RyaW5nIEhlbHBWZXJiKHN0cmluZyB2KTsKK3ByaXZhdGUgc3RyaW5nKiBTb3J0SXQoc3RyaW5nICphcnIpOworCisKKy8qKgorICBJbml0aWFsaXNpZXJ1bmcKKyovCit2b2lkIGNyZWF0ZSgpICB7CisJcGxyY21kcz0oeworCQkienVjayIsICJzY2htaWVnIiwgImFudHdvcnRlIiwgImFwcGxhdWRpZXJlIiwKKwkJImJldGFzdGUiLCAiY2xzIiwgImRyZWhlIChkYWV1bWNoZW4pIiwgImRhbmtlIiwKKwkJImRydWVja2UiLCAiZXJyb2V0ZSIsICJmbGlwcGUiLCAiZnJhZ2UiLAorCQkiZnVyemUiLCAiZ2FlaG5lIiwgImdsdWNrc2UiLCAiZ3JpbnNlIiwKKwkJImd1Y2siLCAiaGFldHNjaGVsIiwgImhpY2tzZSIsICJodWVwZmUiLAorCQkiaHVzdGUiLCAia2V1Y2hlIiwgImtpY2hlcmUiLCAia2xhdHNjaGUiLAorCQkia25hYmJlcmUiLCAia25pY2tzZSIsICJrbmlyc2NoZSIsICJrbnVycmUiLAorCQkia251dHNjaGUiLCAia290emUiLCAia3Vlc3NlIiwgImxhY2hlIiwKKwkJImxhZWNobGUiLCAibGllYmUiLCAibmlja2UiLCAibmllc2UiLAorCQkiZ2liIiwgInBmZWlmZSIsICJydWVscHNlIiwgInJ1bnpsZSIsCisJCSJzY2htb2xsZSIsICJzY2htdW56bGUiLCAic2NobmlwcGUiLCAic2NobmFyY2hlIiwKKwkJInNjaG51cnJlIiwgInNjaHJlaWUiLCAic2NodWV0dGxlIiwgInNldWZ6ZSIsCisJCSJzaW5nZSIsICJzbmllZmUvc2NobmllZmUiLCAic3B1Y2tlIiwgInN0YXJyZSIsCisJCSJzdGF1bmUiLCAic3RpZXJlIiwgInN0b2VobmUiLCAic3Rvc3NlIiwKKwkJInN0cmVpY2hsZSIsICJ0YW56ZSIsICJ0cml0dCIsICJ0cm9lc3RlIiwKKwkJInVtYXJtZSIsICJ2ZXJuZWlnZSIsICJ3YWNrbGUiLCAid2FlbHplIiwKKwkJIndlaW5lIiwgIndpbmtlIiwgInp3aW5rZXJlIiwgInZlcmJlbiIsCisJCSJhZWNoemUiLCAiZXJibGVpY2hlIiwgImZsdWNoZSIsICJ2ZXJmbHVjaGUiLAorCQkia2l0emxlIiwgIm5laW4iLCAiZGV1dGUiLCAvLyAiemVpZ2UiLAorCQkiZGVua2UgW3RleHRdIiwgImtudWRkbGUiLCAidGFldHNjaGVsIiwgInd1c2NoZWwiLAorCQkic3RyZWNrZSAuLi4gW2RpZV0genVuZ2UgcmF1cyIsICJrcmF0eiIsCisJCSJncnVtbWVsIiwgImp1YmVsIC8ganVibGUgLi4uIFt6dV0iLCAid3VlcmciLAorCQkiZ3JhdHVsaWVyZSAvIGJlZ2x1ZWNrd3VlbnNjaGUiLCAicmFldXNwZXIiLAorCQkiYXJnbCIsICJyb3RmbCIsICJncnVueiIsICJrdXNjaGVsIiwgImF0bWUgLi4uIGF1ZiIsCisJCSJmcmV1ZSIsICJzbmlmZiIsICJncnVlYmxlIiwgImJvaHJlIC4uLiBbaW4gZGVyIG5hc2VdIiwKKwkJInB1dHplIFtuYXNlXSIsICJiaWJiZXJlIiwgInF1aWV0c2NoZS9xdWlla2UiLCAic2NobHVjaHplIiwKKwkJInNjaG5hdWZlIiwgInNjaG5hdWJlIiwgInBoaWxvc29waGllcmUiLCAic2FiYmVyZSIsCisJCSJzdGltbWUgWy4uLl0genUiLCAia3JpZWNoZSIsICJtdXN0ZXJlIiwgInNjaGFlbWUiLAorCQkic2NobmFsemUgLi4uIFt6dW5nZV0iLCAic3RhbXBmZSAuLi4gW2F1Zl0iLCAieml0aWVyZSIsICJsb2JlIiwKKwkJInF1YWtlIiwgInJlaWJlIC4uLiBbZGllXSBBdWdlbnxIYWVuZGUiLCAic3R1dHplIiwgInNjaHdlaWdlIiwKKwkJImtsb3BmZSIsICJ3dW5kZXJlIiwgInN0dXBzZSIsICJicnVtbWVsIiwgImVudHNjaHVsZGlnZSIsCisJCSJtb3BwZXIiLCAiemVpZ2UiLCAidHJhZXVtZSIsICJiZWdydWVzc2UiLCJqYW1tZXIiLAorCX0pOworI2lmZGVmIFdFQ0tFCisJcGxyY21kcys9KHsid2Vja2UifSk7CisjZW5kaWYKKwl3aXpjbWRzPSh7CisJCSJraWNrIiwgInNwbGFzaCIsICJmbGFtZSIsCisJfSk7CisJZ2hvc3RjbWRzPSh7CisJCSJyYXNzZWwvcmFzc2xlIiwgImhldWxlIiwgImVyc2NocmVja2UiLAorCX0pOworCS8vIEF1ZmJhdSBkZXMgaGVscC1tYXBwaW5nczoKKwkvLyBrZXkgICAgOiBWZXJiLCB3aWUgZXMgaW4gc291bC5jIGluIENIRUNLX0hFTFAgZ2VzY2hyaWViZW4gaXN0CisJLy8gZW50cnkgMTogJm4gPSBbPE5hbWU+XSAgICZhID0gWzxBZHZlcmI+XSAgICAmdD1bPFRleHQ+fQorCS8vICAgICAgICAgICEgZGFuYWNoIGhlaXNzdCBub2V0aWdlIEFuZ2FiZSwgYWxzbyBvaG5lIFtdCisJLy8gZW50cnkgMjogJmcgPSBWZXJoYWVsdCBzaWNoIGJlaSBHZWlzdGVybiBhbmRlcnMKKwkvLyAgICAgICAgICAmYSA9IE1hbiBrYW5uICJhbGxlIiBhbHMgWmllbCBhbmdlYmVuCisJLy8gICAgICAgICAgJmQgPSBEZWZhdWx0YWR2ZXJiOyBtdXNzIGFtIEVuZGUgYW5nZWdlYmVuIHdlcmRlbgorCWhlbHA9KFsKKwkJInp1Y2siIDogIiZhIFtbbWl0IFtkZW5dXSBzY2h1bHRlcm5dIjsgIkdpYnQgbWFuIG5pY2h0IG1pbmRlc3RlbnMgIgorCQkJKyJcInNjaHVsdGVyblwiIGFuLCBzbyB6dWNrdCBtYW4genVzYW1tZW4uIERhcyBEZWZhdWx0YWR2ZXJiIGdpbHQgIgorCQkJKyJudXIgZnVlciBkYXMgU2NodWx0ZXJ6dWNrZW4uJmRyYXRsb3MiLAorCQkic2NobWllZyIgOiAiJm4gJmEiOyAiIiwKKwkJImFudHdvcnQiIDogIiZuICZ0ISI7ICIiLAorCQkiYXBwbGF1ZGllciIgOiAiJm4gJmEiOyAiJmcmYSIsCisJCSJiZWdydWVzcyIgOiAiJm4hICZhIjsgIiIsCisJCSJiZXRhc3QiIDogIiZuISAmYSI7ICIiLAorCQkiYmliYmVyIiA6ICImYSI7ICIiLAorCQkiYm9ociIgOiAiJmEgW1tpbiBbZGVyXV0gbmFzZV0iOyAiIiwKKwkJImJydW1tZWwiIDogIiZhIHwgJnQiOyAiIiwKKwkJImNscyIgOiAiIjsgIkxvZXNjaHQgZGVuIEJpbGRzY2hpcm0gYXVmIHZ0MTAwLWtvbXBhdGlibGVuIFRlcm1pbmFscy4iLAorCQkiZHJlaCIgOiAiJmEgW2RhZXVtY2hlbiB8IGRhdW1lbl0iOyAiIiwKKwkJImRhbmsiIDogIiZuISAmYSI7ICIiLAorCQkiZHJ1ZWNrIiA6ICImbiEgJmEiOyAiJmcmYSZkemFlcnRsaWNoIiwKKwkJImVudHNjaHVsZGlnIiA6ICImbiAmYSI7ICIiLAorCQkiZXJyb2V0IiA6ICImYSI7ICImZyIsCisJCSJlcnNjaHJlY2siIDogIiZuISAmYSI7ICImZyZkZnVlcmNodGVybGljaCIsCisJCSJmbGlwcCIgOiAiJmEiOyAiJmR0b3RhbCIsCisJCSJmcmFnIiA6ICImbiFbfF0mdCEiOyAiIiwKKwkJImZyZXUiIDogIiZuICZhIjsgIiIsCisJCSJmdXJ6IiA6ICImYSI7ICImZ0hpbnRlcmxhZXNzdCBlaW5lIGR1ZnRpZ2UgRXJpbm5lcnVuZyBpbSBSYXVtLiIsCisJCSJnYWVobiIgOiAiJmEiOyAiJmciLAorCQkiZ2x1Y2tzIiA6ICImYSI7ICImZHdpZSBlaW4gSHVobiIsCisJCSJncmF0dWxpZXIiIDogIiZuISAmYSI7ICIiLAorCQkiZ3JpbnMiIDogIiZuICZhIjsgIiZnJmEiLAorCQkiZ3J1ZWJlbCIgOiAiJmEiOyAiIiwKKwkJImdydW1tZWwiIDogIiZhIjsgIiIsCisJCSJndWNrIiA6ICImYSI7ICIiLAorCQkiaGFldHNjaGVsIiA6ICImbiEgJmEiOyAiJmcmYSIsCisJCSJoaWNrcyIgOiAiJmEiOyAiJmciLAorCQkiaHVlcGYiIDogIiZuICZhIjsgIiZnIiwKKwkJImh1c3QiIDogIiZuICZhIjsgIiZnIiwKKwkJImp1YmVsIiA6ICImbiAmYSI7ICIiLAorCQkiamFtbWVyIiA6ICImYSI7ICIiLAorCQkia2V1Y2giIDogIiZhIjsgIiZnJmR2b3IgQW5zdHJlbmd1bmciLAorCQkia2ljaGVyIiA6ICImbiAmYSI7ICIiLAorCQkia2xhdHNjaCIgOiAiJmEiOyAiJmciLAorCQkia2xvcGYiIDogIiZuISAmYSI7ICIiLAorCQkia25hYmJlciIgOiAiJm4hICZhIjsgIiZnIiwKKwkJImtuaWNrcyIgOiAiJm4gJmEiOyAiJmcmYSIsCisJCSJrbmlyc2NoIiA6ICImYSI7ICImZyIsCisJCSJrbnVyciIgOiAiJm4gJmEiOyAiJmEiLAorCQkia251dHNjaCIgOiAiJm4hICZhIjsgIiZnIiwKKwkJImtvdHoiIDogIiZuICZhIjsgIiZnIiwKKwkJImtyaWVjaCIgOiAiJm4gJmEiOyAiIiwKKwkJImt1ZXNzIiA6ICImbiEgJmEiOyAiJmdLYW5uIGF1c3NlcmRlbSBiZWkgYmVzdGltbXRlbiBHZWxlZ2VuaGVpdGVuICIKKwkJCSsiZ2V3aXNzZSBOZWJlbmVmZmVrdGUgaGFiZW4uIiwKKwkJImxhY2giIDogIiZuICZhIjsgIiZnJmEiLAorCQkibGFlY2hlbCIgOiAiJm4gJmEiOyAiJmcmYSIsCisJCSJsaWViIiA6ICImbiEgJmEiOyAiIiwKKwkJImxvYiIgOiAieyZuISAmYX0gfCAmdCEiOyAiS2FubiBlaW5lbiBOZWJlbmVmZmVrdCBoYWJlbi4iLAorCQkibW9wcGVyIiA6ICImYSI7ICIiLAorCQkibXVzdGVyIiA6ICImbiEgJmEiOyAiIiwKKwkJIm5pY2siIDogIiZuICZhIjsgIiZhJmR6dXN0aW1tZW5kIiwKKwkJIm5pZXMiIDogIiZhIjsgIiZnIiwKKwkJImdpYiIgOiAiJm4hICZhIFtbZWluZV0gb2hyZmVpZ2VdIjsgIiZnJmEiLAorCQkicGZlaWYiIDogIiZuICZhIFtuYWNoXSI7ICImZyZkYW5lcmtlbm5lbmQiLAorCQkicGhpbG9zb3BoaWVyIiA6ICImYSB8ICZ0IjsgIiIsCisJCSJwdXR6IiA6ICImYSBbW2RpZV0gbmFzZV0iOyAiIiwKKwkJInF1YWsiIDogIiZhIjsgIkdlaHQgYWxzIEZyb3NjaCB3ZXNlbnRsaWNoIGJlc3Nlci4iLAorCQkicXVpZWsiIDogIiZhIjsgIiZkdmVyZ251ZWd0IiwKKwkJInJhZXVzcGVyIiA6ICImYSI7ICIiLAorCQkicmVpYiIgOiAiJmEgW1tkaWVdIEF1Z2VuXSB8IFtbZGllXSBIYWVuZGVdIjsgIk9obmUgd2VpdGVyZSBBbmdhYmUgcmVpYnQgIgorCQkJKyJtYW4gc2ljaCBkaWUgQXVnZW47JmRtdWVkZSBiencuIHZlcmdudWVndCIsCisJCSJydWVscHMiIDogIiZhIjsgIiZnIiwKKwkJInJ1bnplbCIgOiAiJmEiOyAiJmciLAorCQkic2FiYmVyIiA6ICImbiAmYSI7ICIiLAorCQkic2NoYWVtIiA6ICImYSI7ICIiLAorCQkic2NobHVjaHoiIDogIiZhIjsgIiZkaGVyenplcnJlaXNzZW5kIiwKKwkJInNjaG1vbGwiIDogIiZhIjsgIiZnIiwKKwkJInNjaG11bnplbCIgOiAiJmEiOyAiIiwKKwkJInNjaG5hbHoiIDogIiZhIFtbbWl0IFtkZXJdXSB6dW5nZV0iOyAiIiwKKwkJInNjaG5hdWIiIDogIiZhIjsgIiZkZW50cnVlc3RldCIsCisJCSJzY2huYXVmIiA6ICImYSI7ICImZHZvciBBbnN0cmVuZ3VuZyIsCisJCSJzY2huaXBwIiA6ICImYSI7ICImZyIsCisJCSJzY2huYXJjaCIgOiAiJmEiOyAiJmcmZGxhdXQiLAorCQkic2NobmllZiIgOiAiJmEiOyAiJmciLAorCQkic2NobnVyciIgOiAiJmEiOyAiJmR6dWZyaWVkZW4iLAorCQkic2NocmVpIiA6ICImbiAmYSI7ICImZyIsCisJCSJzY2h1ZXR0ZWwiIDogIiZuICZhIjsgIiZnJmFIYXQgZWluZW4gVW50ZXJzY2hpZWQsIGplIG5hY2hkZW0sIG9iIGVpbiBOYW1lIgorCQkJKyIgYW5nZWdlYmVuIHd1cmRlIG9kZXIgbmljaHQuIiwKKwkJInNjaHdlaWciIDogIiZhIjsgIiIsCisJCSJzZXVmeiIgOiAiJmEiOyAiJmciLAorCQkic2luZyIgOiAiJmEgfCAmdCI7ICIiLAorCQkic25pZmYiIDogIiZuICZhIjsgIiZkdHJhdXJpZyIsCisJCSJzcHVjayIgOiAiJm4gJmEiOyAiJmciLAorCQkic3RhbXBmIiA6ICImYSI7ICIiLAorCQkic3RhcnIiIDogIiZuICZhIjsgIlN0YW5kYXJkYWR2ZXJiIGdpbHQgaGllciBudXIgYmVpIEFuZ2FiZSBlaW5lcyBOYW1lbnMuIgorCQkJKyImZHZlcnRyYWV1bXQiLAorCQkic3RhdW4iIDogIiZuICZhIjsgIiIsCisJCSJzdGllciIgOiAiJm4gJmEiOyAiJmciLAorCQkic3RpbW0iIDogIiZuICZhIjsgIiIsCisJCSJzdG9laG4iIDogIiZhIjsgIiZnIiwKKwkJInN0b3NzIiA6ICImbiEgJmEiOyAiJmciLAorCQkic3RyZWljaGVsIiA6ICImbiEgJmEiOyAiJmcmYSIsCisJCSJzdHVwcyIgOiAiJm4hICZhIjsgIiIsCisJCSJzdHV0eiIgOiAiJmEiOyAiIiwKKwkJInRhbnoiIDogIiZuICZhIjsgIiZnIiwKKwkJInRyYWV1bSIgOiAieyZuICZhfSB8ICZ0IjsgIkVzIGtvZW5uZW4gUHJvYmxlbWUgYXVmdHJldGVuLCB3ZW5uIGVpbiBBZHZlcmIiCisJCQkrIiBpbiBmcmVpZW0gVGV4dCBlcmthbm50IHdpcmQuIFRleHQgd2lyZCBnZW5hdSBzbyBhbiBcInRyYWV1bShzKXRcIiAiCisJCQkrImFuZ2VoYWVuZ3QsIHdpZSBlciBhbmdlZ2ViZW4gd3VyZGUuIiwKKwkJInRyaXR0IiA6ICImbiAmYSI7ICImZyZhIiwKKwkJInRyb2VzdCIgOiAiJm4hICZhIjsgIiIsCisJCSJ1bWFybSIgOiAiJm4hICZhIjsgIiZnJmEiLAorCQkidmVybmVpZyIgOiAiJm4gJmEiOyAiJmcmYSIsCisJCSJ3YWNrZWwiIDogIiZhIFttaXQgJnQhXSI7ICImZ01hbiBrYW5uIG1pdCBhbGxlbSBtb2VnbGljaGVtIHdhY2tlbG4uIiwKKwkJIndhZWx6IiA6ICImYSI7ICImZHZvciBMYWNoZW4iLAorCQkid2FydCIgOiAiJm4gJmEiOyAiTWFuIGthbm4gYXVmIGFsbGVzIG1vZWdsaWNoZSB3YXJ0ZW4gKHdhcnRlIGFsbGVzICIKKwkJCSsibW9lZ2xpY2hlKSIsCisJCSJ3ZWNrIiA6ICImbiB7JmEgfCAmdH0iOyAiUGllcHN0IDxOYW1lPiBhbiB1bmQgc2VuZGV0IGlobSBnZ2YuIGRlbiBUZXh0LiIsCisJCSJ3ZWluIiA6ICImbiAmYSI7ICImZyIsCisJCSJ3aW5rIiA6ICImbiAmYSI7ICImYSIsCisJCSJ3dWVyZyIgOiAiJm4gJmEiOyAiIiwKKwkJInd1bmRlciIgOiAiJm4gJmEiOyAiIiwKKwkJInplaWciIDogIjxPYmpla3QtSUQ+IjsgIiZhWmVpZ3QgZGFzIE9iamVrdCAoTGFuZ2Jlc2NocmVpYnVuZykuIiwKKwkJInppdGllciIgOiAiJm4gJmEiOyAiSGllciB1ZWJlcm5pbW10IGRhcyBBZHZlcmIgZ2dmLiBkaWUgU3RlbGxlIGRlcyAiCisJCQkrInppdGllcnRlbiwgd2VubiBkaWVzZXIgbmljaHQgYW53ZXNlbmQgaXN0ICh6aXRpZXJlIEphIC9Kb2YpIiwKKwkJInppdHRlciIgOiAiJmEiOyAiIiwKKwkJInp3aW5rZXIiIDogIiZuICZhIjsgIiZnIiwKKwkJImFlY2h6IiA6ICImYSI7ICIiLAorCQkiYXJnbCIgOiAiJmEiOyAiIiwKKwkJImF0bSIgOiAiJmEiOyAiJmRlcmxlaWNodGVydCIsCisJCSJiZXd1bmRlciIgOiAiJm4hICZhIjsgIiIsCisJCSJlcmJsZWljaCIgOiAiJmEiOyAiJmciLAorCQkiZmx1Y2giIDogIiZhIjsgIiZnIiwKKwkJImdydW56IiA6ICImYSI7ICIiLAorCQkia3VzY2hlbCIgOiAiJm4hICZhIjsgIiZnIiwKKwkJInJvdGZsIiA6ICImYSI7ICIiLAorCQkidmVyZmx1Y2giIDogInsmbiAmYX0gfCAmdCEiOyAiIiwKKwkJImtpdHplbCIgOiAiJm4hICZhIjsgIiZnIiwKKwkJIm5laW4iIDogIiZhIjsgIiZnIiwKKwkJImRldXQiIDogIiZuISAmYSI7ICImYSIsCisJCSJkZW5rIiA6ICImYSB8ICZ0IjsgIiZnIiwKKwkJImtudWRkZWwiIDogIiZuISAmYSI7ICImZyZhIiwKKwkJImtyYXR6IiA6ICImYSI7ICIiLAorCQkic3RyZWNrIiA6ICImbiAmYSBbW2RpZV0genVuZ2UgcmF1cyI7ICImZyIsCisJCSJ0YWV0c2NoZWwiIDogIiZuISAmYSI7ICImZyIsCisJCSJ3dXNjaGVsIiA6ICImbiEgJmEiOyAiIiwKKwkJInJhc3NlbCIgOiAiJmEiOyAiJmcmZGZ1ZXJjaHRlcmxpY2giLAorCQkiaGV1bCIgOiAiJmEiOyAiJmcmZHNjaGF1ZXJsaWNoIiwKKwkJImtpY2siIDogIiZuICZhIjsgIiZnJmEiLAorCQkic3BsYXNoIiA6ICImbiEgJmEiOyAiJmEiLAorCQkiZmxhbWUiIDogIiZuISAmYSI7ICImZyZhIiwKKwkJInJrbnVkZGVsIiA6ICImbiEgJmEiOyAiTnVyIGZ1ZXIgRmVybmdlYnJhdWNoIGdlZGFjaHQuIiwKKwkJInJ3aW5rIiA6ICImbiEgJmEiOyAiTnVyIGZ1ZXIgRmVybmdlYnJhdWNoIGdlZGFjaHQuIiwKKwkJInZlcmIiIDogIiI7ICJMaXN0ZXQgYWxsZSBkZXJ6ZWl0IG1vZWdsaWNoZW4gVmVyYmVuIGF1Zi4iLAorCQkiYWR2ZXJiIiA6ICJbIyB8ICQgfCB7PyA8QWJrdWVyenVuZz59IHwgPEFia3Vlcnp1bmc+IFs8QWR2ZXJiPl1dIjsKKwkJCSJHZW5hdWVyZSBIaWxmZSBtaXQgXCJhZHZlcmIgP1wiIiwKKwldKTsKK30KKworLyoqCisgIEdpYnQgZGllIEhpbGZlIHp1IGVpbmVtIFZlcmIgb2RlciBkaWUgVmVyYmVudWViZXJzaWNodCB6dXJ1ZWNrCisgIFxwYXJhbSB2ZXJiICAgInN0cmluZyIgIEVpbiBWZXJiIGRlc3NlbiBIaWxmZSBhbmdlemVpZ3Qgd2VyZGVuIHNvbGwuCisgICAgICAgICAgICAgICAgMCBvZGVyICIiIFVlYmVyYmxpY2tzc2VpdGUKKyAgXHJldHVybiAJU3RyaW5nIGRlciBhbiBkZW4gU3BpZWxlciBhdXNnZWdlYmVuIHdlcmRlbiBrYW5uLgorKi8KK3N0cmluZyBIZWxwKHN0cmluZyB2ZXJiKSAgeworCXN0cmluZyBvdXQ7CisJaWYgKHZlcmIgJiYgdmVyYiE9IiIpCisJCXJldHVybiBIZWxwVmVyYih2ZXJiKTsKKwlvdXQ9IiI7CisJb3V0Kz1icmVha19zdHJpbmcoIlN0YW5kYXJkdmVyYmVuOlxuIitpbXBsb2RlKFNvcnRJdChwbHJjbWRzKSwgIiwgIikKKwkJKyIuIiwgNzgsIDAsIDEpOworCWlmIChJU19XSVpBUkQodGhpc19wbGF5ZXIoKSkpCisJCW91dCs9IlxuIiticmVha19zdHJpbmcoIk1hZ2llcnZlcmJlbjpcbiIraW1wbG9kZShTb3J0SXQod2l6Y21kcyksICIsICIpCisJCQkrIi4iLCA3OCwgMCwgMSk7CisJaWYgKHRoaXNfcGxheWVyKCktPmdob3N0KCkpCisJCW91dCs9IlxuIiticmVha19zdHJpbmcoIkdlaXN0ZXJ2ZXJiZW46XG4iK2ltcGxvZGUoU29ydEl0KGdob3N0Y21kcyksICIsICIpCisJCQkrIi4iLCA3OCwgMCwgMSk7CisJb3V0Kz1icmVha19zdHJpbmcoIlxuQWR2ZXJiaWVuIGtvZW5uZW4gZW50d2VkZXIgaW4gZGVyIEFia3Vlcnp1bmcgKGJlaSAiCisJCSsiYmVyZWl0cyBkZWZpbmllcnRlbiBBZHZlcmJpZW4pIG9kZXIgbWl0IFwiLzxUZXh0PlwiIGFuZ2VnZWJlbiB3ZXJkZW4uICIKKwkJKyJCZWkgZGVyIHp3ZWl0ZW4gTWV0aG9kZSB3aXJkIDxUZXh0PiBzbywgd2llIGVyIGFuZ2VnZWJlbiB3dXJkZSwgYW4gIgorCQkrIlN0ZWxsZSBkZXMgQWR2ZXJicyBlaW5nZXNldHp0LiIsIDc4LCAwLCAxKTsKKwlvdXQrPSJcbiIrYnJlYWtfc3RyaW5nKCJFaW5lIGt1cnplIEhpbGZlIHp1IGVpbmVtIFZlcmIgYmVrb21tc3QgZHUgbWl0IGVpbmVtIGRlciAiCisgICAgICAgICAgICAgICAgKyJCZWZlaGxlIFwiPFZlcmI+IC0/XCIsIFwiPFZlcmI+IC8/XCIsIFwiPFZlcmI+IC1oXCIsIFwiPFZlcmI+IC9oXCIgb2RlciAiCisgICAgICAgICAgICAgICAgKyJcIjxWZXJiPiBoaWxmZVwiLiAoRGEgd2FyIGplbWFuZCB3aXJrbGljaCBmbGVpc3NpZykuIiwgNzgpOworCXJldHVybiBvdXQrIlxuIiticmVha19zdHJpbmcoIkVpbmlnZSBCZWZlaGxlIHJlYWdpZXJlbiBhdWNoIGF1ZiBsZWljaHQgIgorCQkrInVudGVyc2NoaWVkbGljaGUgU2NocmVpYndlaXNlLiBEaWVzZSBCZWZlaGxzbGlzdGUga2FubiBzaWNoIG1pdCBEZWluZW0gIgorCQkrIlp1c3RhbmQgYWVuZGVybi4iLCA3OCk7Cit9CisKKy8qKgorICBTb3J0aWVydCBlaW4gYXJyYXkgb2Ygc3RyaW5nIGFscGhhYmV0aXNjaC4gCisgIFxwYXJhbSBhcnIgRGFzIHp1IHNvcnRpZXJlbmRlIEFycmF5CisgIFxyZXR1cm4gICAgU29ydGllcnRlIEtvcGllIGRlcyBBcnJheXMKKyovCitwcml2YXRlIHN0cmluZyoKK1NvcnRJdChzdHJpbmcgKmFycikgIHsKKyAgcmV0dXJuIHNvcnRfYXJyYXkoYXJyLCAKKyAgICAgICAgICAgZnVuY3Rpb24gaW50IChzdHJpbmcgeCwgc3RyaW5nIHkpeyAKKyAgICAgICAgICAgICByZXR1cm4gbG93ZXJfY2FzZSh4KSA+IGxvd2VyX2Nhc2UoeSkgOworICAgICAgICAgICB9IAorICAgICAgICAgKTsKK30KKworI2RlZmluZSBOT19NT1JFX0UgKHsiY2xzIiwiZmxpcHAiLCJncnVlYmVsIiwiZ3J1bW1lbCIsImd1Y2siLCJoYWV0c2NoZWwiLFwKKyAgImp1YmVsIiwibGFlY2hlbCIsImdpYiIsInJ1bnplbCIsInNjaG11bnplbCIsInNjaHVldHRlbCIsInNuaWZmIixcCisgICJzdHJlaWNoZWwiLCJ0cml0dCIsICJ3YWNrZWwiLCJhcmdsIiwicm90ZmwiLCJrdXNjaGVsIiwia2l0emVsIiwia251ZGRlbCIsXAorICAidGFldHNjaGVsIiwid3VzY2hlbCIsInJhc3NlbCIsImtpY2siLCJzcGxhc2giLCJmbGFtZSIsInZlcmIiLCJhZHZlcmIiLFwKKyAgIm5laW4iLCJicnVtbWVsIiwibW9wcGVyIix9KQorCisvKioKKyAgR2lidCBkaWUgSGlsZmUgenUgZWluZW0gVmVyYiAKKyAgXHBhcmFtIHYgICAgIEVpbiBWZXJiIGRlc3NlbiBIaWxmZSBhbmdlemVpZ3Qgd2VyZGVuIHNvbGwuCisgIFxyZXR1cm4gCUhpbGZlIHp1bSBWZXJiIGluIEZvcm0gZWluZXMgU3RyaW5ncworKi8KK3ByaXZhdGUgc3RyaW5nCitIZWxwVmVyYihzdHJpbmcgdikgIHsKKwlzdHJpbmcgaCx0OworCWlmIChtZW1iZXIobV9pbmRpY2VzKGhlbHApLHYpPDApCisJCXJldHVybiAiRGF6dSBpc3Qga2VpbmUgSGlsZmUgdm9yaGFuZGVuLlxuIjsKKwloPSJTeW50YXg6XG4qICIrdjsKKwlpZiAobWVtYmVyKE5PX01PUkVfRSwgdik8MCkKKwkJaCs9ImUiOworCWgrPSIgIjsKKwl0PWhlbHBbdiwwXTsKKwl0PWltcGxvZGUoZXhwbG9kZSh0LCImdCEiKSwgIjxUZXh0PiIpOworCXQ9aW1wbG9kZShleHBsb2RlKHQsIiZuISIpLCAiPE5hbWU+Iik7CisJdD1pbXBsb2RlKGV4cGxvZGUodCwiJnQiKSwgIls8VGV4dD5dIik7CisJdD1pbXBsb2RlKGV4cGxvZGUodCwiJm4iKSwgIls8TmFtZT5dIik7CisJdD1pbXBsb2RlKGV4cGxvZGUodCwiJmEiKSwgIls8QWR2ZXJiPl0iKTsKKwloKz10OworCXQ9aGVscFt2LDFdOworCWlmICh0IT0iIikgIHsKKwkJaCs9IlxuQmVtZXJrdW5nZW46IjsKKwkJaWYgKChleHBsb2RlKHQsIiYiKSlbMF0hPSIiKQorCQkJdD0iXG4iK2JyZWFrX3N0cmluZygoZXhwbG9kZSh0LCImIikpWzBdLCA3NiwgIiogIiwgMSlbMC4uPDJdCisJCQkJKyImIitpbXBsb2RlKChleHBsb2RlKHQsIiYiKSlbMS4uPDFdLCImIik7CisJCXQ9aW1wbG9kZShleHBsb2RlKHQsIiZnIiksICJcbiogVmVyaGFlbHQgc2ljaCBiZWkgR2Vpc3Rlcm4gYW5kZXJzICIKKwkJCSsiYWxzIHNvbnN0LiIpOworCQl0PWltcGxvZGUoZXhwbG9kZSh0LCImYSIpLCAiXG4qIEJlaSBkaWVzZW0gVmVyYiBnZWh0IGFsbGUobikgYWxzICIKKwkJCSsiWmllbGFuZ2FiZS4iKTsKKwkJaWYgKHN0cnN0cih0LCImZCIpPj0wKSAgeworCQkJdD1pbXBsb2RlKGV4cGxvZGUodCwiJmQiKSwgIlxuKiBTdGFuZGFyZGFkdmVyYiBpc3QgIik7CisJCQl0Kz0iLiI7CisJCX0KKwl9CisJcmV0dXJuIGJyZWFrX3N0cmluZyhoK3QsIDc4LCAyLCAxKTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvdHJhdmVsLmMgYi9zdGQvcGxheWVyL3RyYXZlbC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNlMDdjMGEKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL3RyYXZlbC5jCkBAIC0wLDAgKzEsNTA2IEBACisKKy8qICdyZWlzZScgaGFuZGxpbmcKKyAqCisgKiBVZWJlcmFyYmVpdGV0ZSB1bmQgCisgKiBlcndlaXRlcnRlIFZlcnNpb246IFRpbGx5QE1vcmdlbkdyYXVlbiwgMTAuMDEuMDIKKyAqIEJhc2llcmVuZCBhdWYgICAgIDogYmFzZS5jQFNpbGJlckxhbmQsCisgKiAgICAgICAgICAgICAgICAgICAgIFJldmlzaW9uIDMuNTUsIFdvb2R5QFNpbGJlckxhbmQsIDExLjA1Ljk5CisgKi8gICAKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwbGF5ZXIuaD4KKyNpbmNsdWRlIDxsaXZpbmcvbW92aW5nLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGNvbmZpZy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPGxpdmluZy5oPgorI2luY2x1ZGUgPGF0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPHRyYW5zcG9ydC5oPgorCit2b2lkIGNyZWF0ZSgpe30KKworcHJpdmF0ZSBzdHJpbmcgX3RyYXZlbGxlcihzdHJpbmcgKnMpCit7CisgIHN3aXRjaCAoc2l6ZW9mKHMpKQorICB7CisgICAgY2FzZSAxIDogcmV0dXJuIHNbMF07CisgICAgY2FzZSAyIDogcmV0dXJuIHNbMF0rIiBvZGVyICIrc1sxXTsKKyAgfQorICByZXR1cm4gZWZ1bjo6aW1wbG9kZShzWzAuLjwyXSwiLCAiKSsiIG9kZXIgIitzWzwxXTsKK30KKworc3RhdGljIGludCByZWlzZShzdHJpbmcgc3RyKQoreworICBtaXhlZCAgdCwgc2hpcCwgZHN0cjsKKyAgc3RyaW5nIG1pdCwgbmFjaCwgczEsIHMyOworICBpbnQgICAgaTsKKworICBfbm90aWZ5X2ZhaWwoIlN5bnRheDogcmVpc2UgbWl0IDx0cmFuc3BvcnRtaXR0ZWw+IG5hY2ggPHppZWxvcnQ+XG5cbiIKKyAgICAgICAgICAgICAgICJXZWl0ZXJlIFN5bnRheGVuIG1vZWdsaWNoLCBiaXR0ZSAnaGlsZmUgcmVpc2UnIGxlc2VuLlxuIik7CisKKyAgdCA9IFF1ZXJ5UHJvcChQX1RSQVZFTF9JTkZPKTsKKyAgCisgIGlmICghcG9pbnRlcnAodCkgfHwgKHNpemVvZih0KSA8IDQpIHx8ICFvYmplY3RwKHRbMF0pIHx8ICFvYmplY3RwKHRbMV0pKQorICB7CisgICAgU2V0UHJvcChQX1RSQVZFTF9JTkZPLCB0ID0gMCk7CisgIH0KKy8qICogKiAqIAorICogUkVJU0UKKyAqICogKiAqLworICBpZiAoIXN0cikKKyAgeworICAgIGlmICghdCkKKyAgICB7CisgICAgICB3cml0ZSgiRHUgaGFzdCBrZWluZSBSZWlzZXJvdXRlIGZlc3RnZWxlZ3QuXG4iKTsKKyAgICB9CisgICAgZWxzZSBpZiAodFswXSA9PSBlbnZpcm9ubWVudCgpKQorICAgIHsKKyAgICAgIGlmIChlbnZpcm9ubWVudCgpLT5pZCgiVHJhbnNwb3J0ZXIiKSkKKyAgICAgIHsKKyAgICAgICAgd3JpdGUoc3ByaW50ZigiRHUgcmVpc3QgbWl0ICVzJXMuXG4iLGVudmlyb25tZW50KCktPm5hbWUoV0VNLDEpLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRbMl0/IiAiK3RbM106IiIpKTsKKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgIHsKKyAgICAgICAgd3JpdGUoc3ByaW50ZigiRHUgd2lyc3QgbWl0ICVzJXMgcmVpc2VuLlxuIix0WzFdLT5uYW1lKFdFTSwxKSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0WzJdPyIgIit0WzNdOiIiKSk7CisgICAgICB9CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICAgd3JpdGUoc3ByaW50ZigiRGVpbmUgbGV0enRlIFJvdXRlIChtaXQgJXMlcykgaXN0IGhpZXIgbmljaHQgd2lya3NhbS5cbiIsCisgICAgICAgICAgICAgICAgICAgICB0WzFdLT5uYW1lKFdFTSwxKSwKKyAgICAgICAgICAgICAgICAgICAgIHRbMl0/IiAiK3RbM106IiIpKTsKKyAgICB9CisgICAgcmV0dXJuIDE7CisgIH0KKworICBzdHIgPSBsb3dlcl9jYXNlKCBfdW5wYXJzZWRfYXJncygpICk7CisvKiAqICogKiAqICogKiAKKyAqIFJFSVNFIFJPVVRFCisgKiAqICogKiAqICogKi8KKyAgaWYgKHN0ciA9PSAicm91dGUiKQorICB7CisgICAgc3RyaW5nICpoYXJib3VyczsKKyAgICAKKyAgICBpZiAoZW52aXJvbm1lbnQoKS0+aWQoIlRyYW5zcG9ydGVyIikpCisgICAgeworICAgICAgaWYgKGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX05PX1RSQVZFTElORykpCisgICAgICB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygKKyAgICAgICAgIGNhcGl0YWxpemUoZW52aXJvbm1lbnQoKS0+bmFtZShXRVIsMSkpKyIgaGF0IGdhciBrZWluZSAiCisgICAgICAgICAiUmVpc2Vyb3V0ZS4gV28gRGljaCBkYXMgd29obCBoaW5mdWVocnQ/Iiw3OCkpOworICAgICAgICByZXR1cm4gMTsKKyAgICAgIH0KKworICAgICAgaGFyYm91cnMgPSBlbnZpcm9ubWVudCgpLT5RdWVyeUhhcmJvdXJzKDEpOworICAgICAgCisgICAgICBpZiAoIXNpemVvZihoYXJib3VycykgfHwgIXN0cmluZ3AoaGFyYm91cnNbMF0pKQorICAgICAgeworICAgICAgICB3cml0ZSgiRGllIFJlaXNlcm91dGUgIitlbnZpcm9ubWVudCgpLT5uYW1lKFdFU1NFTiwxKSsiIGlzdCAiCisgICAgICAgICAgICAgKyJsZWlkZXIgbmljaHQgYmVrYW5udC5cbiIpOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgeworICAgICAgICB3cml0ZShicmVha19zdHJpbmcoY2FwaXRhbGl6ZShlZnVuOjppbXBsb2RlKGhhcmJvdXJzLCIgLSAiKSkrIi4iLDc4LAorICAgICAgICAgIlJlaXNlcm91dGUgIitlbnZpcm9ubWVudCgpLT5uYW1lKFdFU1NFTiwxKSsiOiAiLEJTX0lOREVOVF9PTkNFKSk7CisgICAgICB9CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgaWYgKGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX05PX1RSQVZFTElORykpCisgICAgeworICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJIaWVyIGthbm5zdCBEdSBsZWlkZXIga2VpbmUgUmVpc2Vyb3V0ZSB3YWVobGVuLiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgIldhcyBuaWNodCBoZWlzc3QsIGRhc3MgaGllciBrZWluIFRyYW5zcG9ydG1pdHRlbCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgInZlcmtlaHJ0LiIsNzgpKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBpZiAoIXBvaW50ZXJwKHNoaXAgPSBUUkFWRUxELT5IYXNUcmFuc3BvcnRlcihlbnZpcm9ubWVudCgpKSkpCisgICAgeworICAgICAgX25vdGlmeV9mYWlsKCJIaWVyIHZlcmtlaHJ0IGtlaW4gVHJhbnNwb3J0bWl0dGVsLlxuIik7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICB3cml0ZSgiSGllciB2ZXJrZWhyZW4gZm9sZ2VuZGUgVHJhbnNwb3J0bWl0dGVsIFxuIgorICAgICAgICAgICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gXG4iKTsKKyAgICAgICAgIAorICAgIGZvciAoaSA9IDA7IGkgPCBzaXplb2Yoc2hpcCk7IGkrKykKKyAgICB7ICAgIAorICAgICAgaWYgKCFzaGlwW2ldLT5RdWVyeShQX1NIT1JUKSkgY29udGludWU7CisgICAgICAKKyAgICAgIGhhcmJvdXJzID0gc2hpcFtpXS0+UXVlcnlIYXJib3VycygxKTsKKworICAgICAgaWYgKHNpemVvZihoYXJib3VycykgJiYgc3RyaW5ncChoYXJib3Vyc1swXSkpCisgICAgICB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhlZnVuOjppbXBsb2RlKGhhcmJvdXJzLCIgLSAiKSsiLiIsNzgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGlwW2ldLT5RdWVyeShQX1NIT1JUKSsiOiAiLEJTX0lOREVOVF9PTkNFKSk7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIHdyaXRlKHNoaXBbaV0tPlF1ZXJ5KFBfU0hPUlQpKyI6IFJvdXRlIHVuYmVrYW5udC5cbiIpOworICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gMTsKKyAgfQorLyogKiAqICogKiAqICogCisgKiBSRUlTRSBBVVMKKyAqIFJFSVNFIE5JQ0hUCisgKiAqICogKiAqICogKi8KKyAgaWYgKG1lbWJlcigoWyJhdXMiLCJuaWNodCJdKSxzdHIpKQorICB7CisgICAgaWYgKCF0KQorICAgIHsKKyAgICAgIHdyaXRlKCJEdSBoYXR0ZXN0IGtlaW5lIFJlaXNlcm91dGUgZWluZ2VzdGVsbHQuXG4iKTsKKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgIHdyaXRlKCJEdSBsb2VzY2hzdCBEZWluZSBSZWlzZXJvdXRlLlxuIik7CisgICAgfQorICAgIFNldFByb3AoUF9UUkFWRUxfSU5GTywgMCk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBzdHIgPSByZWdyZXBsYWNlKHN0ciwiXFw8KHp1fHp1bXx6dXJ8aW5zfGFucylcXD4iLCJuYWNoIiwwKTsKKy8qICogKiAqICogKiAqICogKgorICogUkVJU0UgTUlUIE5BQ0gKKyAqIFJFSVNFIE5BQ0ggTUlUCisgKiAqICogKiAqICogKiAqICovCisgIGlmICgoc3NjYW5mKHN0ciwgIm1pdCAlcyBuYWNoICVzIiwgbWl0LCBuYWNoKSA9PSAyKSB8fAorICAgICAgKHNzY2FuZihzdHIsICJuYWNoICVzIG1pdCAlcyIsIG5hY2gsIG1pdCkgPT0gMikpCisgIHsKKyAgICBfbm90aWZ5X2ZhaWwoIkhpZXIga2FubnN0IER1IGxlaWRlciBrZWluZSBSZWlzZXJvdXRlIHdhZWhsZW4uXG4iKTsKKworICAgIGlmIChlbnZpcm9ubWVudCgpLT5RdWVyeVByb3AoUF9OT19UUkFWRUxJTkcpKQorICAgIHsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpZiAoIXNpemVvZihuYWNoKSkKKyAgICB7CisgICAgICBfbm90aWZ5X2ZhaWwoIlN5bnRheDogcmVpc2UgbWl0IDx0cmFuc3BvcnRtaXR0ZWw+IG5hY2ggPHppZWxvcnQ+XG4iCisgICAgICAgICAgICAgICAgICAgIiAgICAgICAgcmVpc2UgbmFjaCA8emllbG9ydD4gbWl0IDx0cmFuc3BvcnRtaXR0ZWw+XG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpZiAoZW52aXJvbm1lbnQoKS0+aWQoIlRyYW5zcG9ydGVyIikpCisgICAgeworICAgICAgaWYgKGVudmlyb25tZW50KCktPmlkKG1pdCkpCisgICAgICB7CisgICAgICAgIGNvbW1hbmQoInJlaXNlIG5hY2ggIituYWNoKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiQmVlbmRlIGVyc3RtYWwgRGVpbmUgYWt0dWVsbGUgUmVpc2UgbWl0ICIrCisgICAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQoKS0+bmFtZShXRU0sMSkrIi5cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICB9CisgICAgaWYgKCFwb2ludGVycChzaGlwID0gVFJBVkVMRC0+SGFzVHJhbnNwb3J0ZXIoZW52aXJvbm1lbnQoKSwgbWl0KSkpCisgICAgeworICAgICAgX25vdGlmeV9mYWlsKCJTbyBlaW4gVHJhbnNwb3J0bWl0dGVsIHZlcmtlaHJ0IGhpZXIgbmljaHQuXG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBmb3IgKGkgPSBzaXplb2Yoc2hpcCkgLTEgOyBpID49IDA7IGktLSkKKyAgICAgIGlmICghc2hpcFtpXS0+SGFzUm91dGUobmFjaCkpCisgICAgICB7CisgICAgICAgIHNoaXBbaV0gPSAwOworICAgICAgfQorCisgICAgc2hpcCAtPSAoezB9KTsKKworICAgIGlmIChwb2ludGVycCh0KSAmJiBvYmplY3RwKHRbMV0pICYmIChtZW1iZXIoc2hpcCx0WzFdKSAhPSAtMSkpCisgICAgeworICAgICAgc2hpcCA9ICh7IHRbMV0gfSk7CisgICAgfQorICAgIGlmIChzaXplb2Yoc2hpcCkgPiAxKQorICAgIHsKKyAgICAgIGlmIChvYmplY3RfbmFtZShlbnZpcm9ubWVudCgpKSA9PSBzaGlwWzBdLT5IYXNSb3V0ZShuYWNoKVswXSkKKyAgICAgIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJBYmVyIGRhIGJpc3QgRHUgZG9jaCBiZXJlaXRzLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgICAgfQorICAgICB3cml0ZSgiRG9ydGhpbiBrYW5uc3QgRHUgbWl0ICIrQ291bnRVcChtYXBfb2JqZWN0cyhzaGlwLCJuYW1lIixXRU0pKQorICAgICAgICAgICArInJlaXNlbi5cbiIpOworIAorCisgICAgICBkc3RyID0gZmlsdGVyKCBmaWx0ZXJfb2JqZWN0cyhzaGlwLCJzaG9ydCIpLCBsYW1iZGEoICh7J3h9KSwKKyAgICAgICAgICAgICAoeyAjJz09LCAoeyMnZW52aXJvbm1lbnQsICd4fSksIGVudmlyb25tZW50KCkgfSkgKSApOworCisgICAgICBpZiAoc2l6ZW9mKGRzdHIpKQorICAgICAgeworICAgICAgICBzaGlwID0gZHN0clswXTsKKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgIHsKKyAgICAgICAgc2hpcCA9IHNoaXBbMF07CisgICAgICB9CisKKyAgICAgIGRzdHIgPSBzaGlwLT5IYXNSb3V0ZShuYWNoKTsKKworICAgICAgd3JpdGUoc3ByaW50ZigiRHUgZW50c2NoZWlkZXN0IERpY2ggZnVlciAlcyB1bmQgcmVpc3QgJXMuXG4iLAorICAgICAgICAgICAgc2hpcC0+bmFtZShXRU4sMSksZHN0clsxXSkpOworICAgIH0KKyAgICBlbHNlIGlmIChzaXplb2Yoc2hpcCkgPCAxKQorICAgIHsKKyAgICAgIF9ub3RpZnlfZmFpbCgiTmFjaCAnIitjYXBpdGFsaXplKG5hY2gpKyInIGthbm4gRGljaCBkYXMgYW5nZWdlYmVuZSAiCisgICAgICAgICAgICAgICAgICArIlRyYW5zcG9ydG1pdHRlbCBsZWlkZXIgbmljaHQgYnJpbmdlbi5cbiIpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICBzaGlwID0gc2hpcFswXTsKKyAgICAgIGRzdHIgPSBzaGlwLT5IYXNSb3V0ZShuYWNoKTsKKworICAgICAgaWYgKG9iamVjdF9uYW1lKGVudmlyb25tZW50KCkpID09IGRzdHJbMF0pCisgICAgICB7CisgICAgICAgIF9ub3RpZnlfZmFpbCgiQWJlciBkYSBiaXN0IER1IGRvY2ggYmVyZWl0cy5cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICAgIGlmICh0ICYmIHN0cmluZ3AodFsyXSkpCisgICAgICB7CisgICAgICAgIGlmICh0WzJdID09IGRzdHJbMF0pCisgICAgICAgIHsKKyAgICAgICAgICBfbm90aWZ5X2ZhaWwoIkFiZXIgZGFzIHR1c3QgRHUgZG9jaCBiZXJlaXRzLlxuIik7CisgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHdyaXRlKHNwcmludGYoIk9rLCBEdSByZWlzdCBudW4gbWl0ICVzICVzLlxuIiwKKyAgICAgICAgICAgICAgICAgICAgIHNoaXAtPm5hbWUoV0VNLDEpLGRzdHJbMV0pKTsKKyAgICB9CisgICAgaWYgKGVudmlyb25tZW50KHNoaXApPT1lbnZpcm9ubWVudCgpICYmIHNoaXAtPnNob3J0KCkpCisgICAgeworICAgICAgc2hpcC0+RW50ZXIodGhpc19vYmplY3QoKSk7CisgICAgfQorICAgIFNldFByb3AoUF9UUkFWRUxfSU5GTywgKHsgZW52aXJvbm1lbnQoKSwgc2hpcCwgZHN0clswXSwgZHN0clsxXSB9KSApOworICAgIHJldHVybiAxOworICB9CisvKiAqICogKiAqICogKgorICogUkVJU0UgTkFDSAorICogKiAqICogKiAqICovCisgIGlmIChzc2NhbmYoc3RyLCJuYWNoICVzIixuYWNoKSkKKyAgeworICAgIF9ub3RpZnlfZmFpbCgiSGllciBrYW5uc3QgRHUgbGVpZGVyIGtlaW5lIFJlaXNlcm91dGUgd2FlaGxlbi5cbiIpOworCisgICAgaWYgKGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX05PX1RSQVZFTElORykpCisgICAgeworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmIChlbnZpcm9ubWVudCgpLT5pZCgiVHJhbnNwb3J0ZXIiKSkKKyAgICB7CisgICAgICBpZiAoIWRzdHIgPSBlbnZpcm9ubWVudCgpLT5IYXNSb3V0ZShuYWNoKSkKKyAgICAgIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJEb3J0aGluIGthbm4gRGljaCAiK2Vudmlyb25tZW50KCktPm5hbWUoV0VSLDEpKworICAgICAgICAgICAgICAgICAgICAgIiBsZWlkZXIgbmljaHQgYnJpbmdlbi5cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICAgIGlmICh0ICYmIHN0cmluZ3AodFsyXSkpCisgICAgICB7CisgICAgICAgIGlmICh0WzJdID09IGRzdHJbMF0pCisgICAgICAgIHsKKyAgICAgICAgICBfbm90aWZ5X2ZhaWwoIkFiZXIgZGFzIHR1c3QgRHUgZG9jaCBiZXJlaXRzLlxuIik7CisgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHdyaXRlKHNwcmludGYoIk9rLCBEdSByZWlzdCBqZXR6dCBtaXQgJXMgJXMuXG4iLAorICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCgpLT5uYW1lKFdFTSwxKSxkc3RyWzFdKSk7CisgICAgICAKKyAgICAgIGlmIChJU19XSVpBUkQodGhpc19vYmplY3QoKSkpCisgICAgICB7CisgICAgICAgIHdyaXRlKCJBbHMgTWFnaWVyIG5pbW1zdCBEdSBuYXR1ZXJsaWNoIGRpZSBBYmt1ZXJ6dW5nLlxuIik7CisgICAgICAgIG1vdmUoZHN0clswXSxNX05PQ0hFQ0spOworICAgICAgICByZXR1cm4gMTsKKyAgICAgIH0KKyAgICAgIFNldFByb3AoUF9UUkFWRUxfSU5GTywoeyBlbnZpcm9ubWVudCgpLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCgpLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RyWzBdLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RyWzFdIH0pICk7CisKKyAgICAgIGlmIChvYmplY3RfbmFtZShlbnZpcm9ubWVudChzaGlwID0gZW52aXJvbm1lbnQoKSkpID09IGRzdHJbMF0gJiYgCisgICAgICAgICAgc2hpcC0+c2hvcnQoKSkKKyAgICAgIHsKKyAgICAgICAgZW52aXJvbm1lbnQoKS0+TGVhdmUodGhpc19vYmplY3QoKSk7CisKKyAgICAgICAgaWYgKGVudmlyb25tZW50KCkgIT0gc2hpcCkKKyAgICAgICAgeworICAgICAgICAgIFNldFByb3AoUF9UUkFWRUxfSU5GTywgMCk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBpZiAoIXBvaW50ZXJwKHNoaXAgPSBUUkFWRUxELT5IYXNUcmFuc3BvcnRlcihlbnZpcm9ubWVudCgpKSkpCisgICAgeworICAgICAgX25vdGlmeV9mYWlsKCJWb24gaGllciBhdXMga2FubnN0IER1IG5pY2h0IHJlaXNlbi5cbiIpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGZvciAoaSA9IHNpemVvZihzaGlwKSAtIDE7IGkgPj0gMDsgaS0tKQorICAgICAgaWYgKCFzaGlwW2ldLT5IYXNSb3V0ZShuYWNoKSkKKyAgICAgIHsKKyAgICAgICAgc2hpcFtpXSA9IDA7CisgICAgICB9CisKKyAgICBzaGlwIC09ICh7IDAgfSk7CisgCisgICAgaWYgKHBvaW50ZXJwKHQpICYmIG9iamVjdHAodFsxXSkgJiYgKG1lbWJlcihzaGlwLHRbMV0pICE9IC0xKSkKKyAgICB7CisgICAgICBzaGlwID0gKHsgdFsxXSB9KTsKKyAgICB9CisgICAgaWYgKHNpemVvZihzaGlwKSA+IDEpCisgICAgeworICAgICAgaWYgKG9iamVjdF9uYW1lKGVudmlyb25tZW50KCkpID09IHNoaXBbMF0tPkhhc1JvdXRlKG5hY2gpWzBdKQorICAgICAgeworICAgICAgICBfbm90aWZ5X2ZhaWwoIkFiZXIgZGEgYmlzdCBEdSBkb2NoIGJlcmVpdHMuXG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgICB9CisKKyAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygiRGFoaW4ga2FubnN0IER1IG1pdCAiCisgICAgICAgICAgICtfdHJhdmVsbGVyKG1hcF9vYmplY3RzKHNoaXAsICJuYW1lIiwgV0VNKSkrIiBnZWxhbmdlbi4iLDc4KSk7CisKKyAgICAgIGRzdHIgPSBmaWx0ZXIoZmlsdGVyX29iamVjdHMoc2hpcCwic2hvcnQiKSxsYW1iZGEoICh7J3h9KSwKKyAgICAgICAgICAgICh7ICMnPT0sICh7IydlbnZpcm9ubWVudCwgJ3h9KSwgZW52aXJvbm1lbnQoKSB9KSApICk7CisKKyAgICAgIGlmIChzaXplb2YoZHN0cikpCisgICAgICB7CisgICAgICAgIHNoaXAgPSBkc3RyWzBdOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgeworICAgICAgICBzaGlwID0gc2hpcFswXTsKKyAgICAgIH0KKworICAgICAgZHN0ciA9IHNoaXAtPkhhc1JvdXRlKG5hY2gpOworCisgICAgICB3cml0ZShzcHJpbnRmKCJEdSB3YWVobHN0ICVzIHVuZCByZWlzdCAlcy5cbiIsc2hpcC0+bmFtZShXRU4sMSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHN0clsxXSkpOworICAgIH0KKyAgICBlbHNlIGlmIChzaXplb2Yoc2hpcCkgPCAxKQorICAgIHsKKyAgICAgIF9ub3RpZnlfZmFpbCgiTmFjaCAnIitjYXBpdGFsaXplKG5hY2gpKyInIGthbm4gRGljaCBsZWlkZXIga2VpbmVzIGRlciAiCisgICAgICAgICAgICAgICAgICArImhpZXIgdmVya2VocmVuZGVuIFRyYW5zcG9ydG1pdHRlbCBicmluZ2VuLlxuIik7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgIHNoaXAgPSBzaGlwWzBdOworICAgICAgZHN0ciA9IHNoaXAtPkhhc1JvdXRlKG5hY2gpOworCisgICAgICBpZiAob2JqZWN0X25hbWUoZW52aXJvbm1lbnQoKSkgPT0gZHN0clswXSkKKyAgICAgIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJBYmVyIGRhIGJpc3QgRHUgamEgYmVyZWl0cy5cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICAgIGVsc2UgaWYgKHQgJiYgc3RyaW5ncCh0WzJdKSkKKyAgICAgIHsKKyAgICAgICAgaWYgKHRbMl0gPT0gZHN0clswXSkKKyAgICAgICAgeworICAgICAgICAgIF9ub3RpZnlfZmFpbCgiQWJlciBkYXMgdHVzdCBEdSBkb2NoIGJlcmVpdHMuXG4iKTsKKyAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgd3JpdGUoc3ByaW50ZigiT2ssIER1IHJlaXN0IG51biBtaXQgJXMgJXMuXG4iLHNoaXAtPm5hbWUoV0VNKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkc3RyWzFdKSk7CisgICAgfQorICAgIGlmIChJU19XSVpBUkQodGhpc19vYmplY3QoKSkpCisgICAgeworICAgICAgd3JpdGUoIkFscyBNYWdpZXIgbmltbXN0IER1IG5hdHVlcmxpY2ggZGllIEFia3Vlcnp1bmcuXG4iKTsKKyAgICAgIG1vdmUoZHN0clswXSxNX05PQ0hFQ0spOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIGlmIChlbnZpcm9ubWVudChzaGlwKT09ZW52aXJvbm1lbnQoKSAmJiBzaGlwLT5zaG9ydCgpKQorICAgIHsKKyAgICAgIHNoaXAtPkVudGVyKHRoaXNfb2JqZWN0KCkpOworICAgIH0KKyAgICBTZXRQcm9wKFBfVFJBVkVMX0lORk8sICh7IGVudmlyb25tZW50KCksIHNoaXAsIGRzdHJbMF0sIGRzdHJbMV0gfSkgKTsKKyAgICByZXR1cm4gMTsKKyAgfQorLyogKiAqICogKiAqCisgKiBSRUlTRSBNSVQKKyAqICogKiAqICogKi8KKyAgaWYgKHNzY2FuZihzdHIsICJtaXQgJXMiLCBtaXQpKQorICB7CisgICAgX25vdGlmeV9mYWlsKCJIaWVyIGthbm5zdCBEdSBsZWlkZXIga2VpbmUgUmVpc2Vyb3V0ZSB3YWVobGVuLlxuIik7CisKKyAgICBpZiAoZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfTk9fVFJBVkVMSU5HKSkKKyAgICB7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgaWYgKGVudmlyb25tZW50KCktPmlkKCJUcmFuc3BvcnRlciIpKQorICAgIHsKKyAgICAgIGlmIChlbnZpcm9ubWVudCgpLT5pZChtaXQpKQorICAgICAgeworICAgICAgICBfbm90aWZ5X2ZhaWwoIkFiZXIgZGFzIHR1c3QgRHUgZG9jaCBiZXJlaXRzLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgeworICAgICAgICBfbm90aWZ5X2ZhaWwoIkJlZW5kZSBlcnN0bWFsIERlaW5lIGFrdHVlbGxlIFJlaXNlIG1pdCAiKworICAgICAgICAgICAgICAgICAgICAgIGVudmlyb25tZW50KCktPm5hbWUoV0VNLDEpKyIuXG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgICB9CisgICAgfQorICAgIGlmICh0ICYmIG9iamVjdHAodFsxXSkgJiYgdFsxXS0+aWQobWl0KSAmJiB0WzBdID09IGVudmlyb25tZW50KCkpCisgICAgeworICAgICAgX25vdGlmeV9mYWlsKCJBYmVyIGRhcyB0dXN0IER1IGRvY2ggYmVyZWl0cy5cbiIpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmICghcG9pbnRlcnAoc2hpcCA9IFRSQVZFTEQtPkhhc1RyYW5zcG9ydGVyKGVudmlyb25tZW50KCksbWl0KSkpCisgICAgeworICAgICAgX25vdGlmeV9mYWlsKCJTbyBlaW4gVHJhbnNwb3J0bWl0dGVsIHZlcmtlaHJ0IGhpZXIgbmljaHQuXG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpZiAoc2l6ZW9mKHNoaXApID4gMSkKKyAgICB7CisgICAgICB3cml0ZSgiJyIrY2FwaXRhbGl6ZShtaXQpKyInIGtvZW5udGUgIgorICAgICAgICAgICAgICAgK190cmF2ZWxsZXIobWFwX29iamVjdHMoc2hpcCwibmFtZSIsV0VSKSkrIiBzZWluLlxuIik7CisKKyAgICAgIGRzdHIgPSBmaWx0ZXIoZmlsdGVyX29iamVjdHMoc2hpcCwic2hvcnQiKSxsYW1iZGEoICh7J3h9KSwKKyAgICAgICAgICAgICh7ICMnPT0sICh7IydlbnZpcm9ubWVudCwgJ3h9KSwgZW52aXJvbm1lbnQoKSB9KSApICk7CisKKyAgICAgIGlmIChzaXplb2YoZHN0cikpCisgICAgICB7CisgICAgICAgIHNoaXAgPSBkc3RyWzBdOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgeworICAgICAgICBzaGlwID0gc2hpcFswXTsKKyAgICAgIH0KKyAgICAgIHdyaXRlKHNwcmludGYoIkR1IHdhZWhsc3QgJXMuXG4iLCBzaGlwLT5uYW1lKFdFTiwxKSkpOworICAgIH0KKyAgICBlbHNlIGlmIChzaXplb2Yoc2hpcCkgPCAxKQorICAgIHsKKyAgICAgIG5vdGlmeV9mYWlsKCJTbyBlaW4gVHJhbnNwb3J0bWl0dGVsIHZlcmtlaHJ0IGhpZXIgbmljaHQuXG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgc2hpcCA9IHNoaXBbMF07CisgICAgICB3cml0ZShzcHJpbnRmKCJEdSByZWlzdCBudW4gbWl0ICVzLlxuIixzaGlwLT5uYW1lKFdFTSwxKSkpOworICAgIH0KKyAgICBpZiAoZW52aXJvbm1lbnQoc2hpcCk9PWVudmlyb25tZW50KCkgJiYgc2hpcC0+c2hvcnQoKSkKKyAgICB7CisgICAgICBzaGlwLT5FbnRlcih0aGlzX29iamVjdCgpKTsKKyAgICB9CisgICAgaWYgKHBvaW50ZXJwKHQpICYmIHN0cmluZ3AodFsyXSkgJiYgc3RyaW5ncCh0WzNdKSAmJgorICAgICAgICBtZW1iZXIoc2hpcC0+UXVlcnlIYXJib3VycygpLHRbMl0pICE9IC0xKQorICAgIHsKKyAgICAgIHdyaXRlKCJEdSBiZWhhZWx0c3QgRGVpbiBiaXNoZXJpZ2VzIFJlaXNlemllbCAoIit0WzNdKyIpIGJlaS5cbiIpOworICAgICAgU2V0UHJvcChQX1RSQVZFTF9JTkZPLCAoeyBlbnZpcm9ubWVudCgpLCBzaGlwLCB0WzJdLCB0WzNdIH0pICk7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICBTZXRQcm9wKFBfVFJBVkVMX0lORk8sICh7IGVudmlyb25tZW50KCksIHNoaXAsIDAsIDAgfSkgKTsKKyAgICB9CisgICAgcmV0dXJuIDE7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvdXRpbC5jIGIvc3RkL3BsYXllci91dGlsLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTZjOGZhOQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wbGF5ZXIvdXRpbC5jCkBAIC0wLDAgKzEsMTExIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL3V0aWwuIC0tIFV0aWxpdGllcworLy8KKy8vICRJZDogdXRpbC5jIDYzNzEgMjAwNy0wNy0xNyAyMjo0Njo1MFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlICIvc3lzL3BsYXllci91dGlsLmgiCisjaW5jbHVkZSAiL3N5cy90aGluZy9wcm9wZXJ0aWVzLmgiCisKK3B1YmxpYyB2b2lkIFNob3dQcm9wTGlzdChzdHJpbmcgKnByb3BzKSAKK3sKKyAgaW50IGksajsKKworICBqPXNpemVvZihwcm9wcyk7CisKKyAgZm9yICggaT0wOyBpPGogOyBpKyspIAorICB7CisgICAgd3JpdGUoIioiK3Byb3BzW2ldKyI6ICIpOworICAgIFByZXR0eUR1bXAoUXVlcnlQcm9wKHByb3BzW2ldKSk7CisgICAgd3JpdGUoIlxuIik7CisgIH0KK30KKworc3RhdGljIHZvaWQgUHJldHR5RHVtcChtaXhlZCB4KSAKK3sKKyAgaWYgKHBvaW50ZXJwKHgpKSAKKyAgeworICAgIER1bXBBcnJheSh4KTsKKyAgfQorICBlbHNlIGlmIChtYXBwaW5ncCh4KSkKKyAgeworICAgIER1bXBNYXBwaW5nKHgpOworICB9CisgIGVsc2UgaWYgKG9iamVjdHAoeCkpIAorICB7CisgICAgd3JpdGUgKCJPQkooIitvYmplY3RfbmFtZSh4KSsiKSIpOworICB9CisgIGVsc2UgaWYgKHN0cmluZ3AoeCkpCisgIHsKKyAgICB3cml0ZSgiXCIiK3grIlwiIik7CisgIH0KKyAgZWxzZQorICB7CisgICAgd3JpdGUgKHgpOworICB9Cit9CisKK3N0YXRpYyB2b2lkIER1bXBBcnJheShtaXhlZCAqeCkgCit7CisgIGludCBpLGo7CisKKyAgd3JpdGUgKCIoeyAiKTsKKyAgaWYgKCAoaj1zaXplb2YoeCkpPjAgKQorICB7CisgICAgZm9yICggaT0wIDsgaTwoai0xKSA7IGkrKykgCisgICAgeworICAgICAgUHJldHR5RHVtcCh4W2ldKTsKKyAgICAgIHdyaXRlKCIsICIpOworICAgIH0KKyAgICBQcmV0dHlEdW1wKHhbaV0pOworICAgIHdyaXRlKCIgIik7CisgIH0KKyAgd3JpdGUgKCJ9KSIpOworfQorCitzdGF0aWMgdm9pZCBEdW1wTWFwcGluZyhtYXBwaW5nIHgpCit7CisgIGludCAgIGksIGMsIHM7CisgIG1peGVkICppbmQ7CisKKyAgd3JpdGUoIihbICIpOworCisgIGlmICggKGM9c2l6ZW9mKGluZD1tX2luZGljZXMoeCkpKTwxICkKKyAgeworICAgIHdyaXRlKCIgXSkiKTsKKyAgICByZXR1cm47CisgIH0KKworICBzPWdldF90eXBlX2luZm8oeCwxKTsKKworICBEdW1wS2V5VmFsUGFpcih4LCBpbmRbMF0sIHMpOworICBmb3IgKCBpPTEgOyBpPGMgOyBpKysgKQorICB7CisgICAgd3JpdGUoIiwgIik7CisgICAgRHVtcEtleVZhbFBhaXIoeCwgaW5kW2ldLCBzKTsKKyAgfQorICB3cml0ZSgiIF0pIik7Cit9CisKKy8vIExhY2h0IG5pY2h0IHVlYmVyIGRlbiBOYW1lbiEhISAtQm9pbmcKKy8vIE5laW4sIHVlYmVyIGRlbiBOYW1lbiBsYWNoZSBpY2ggbmljaHQgLi4uIC1QYXJhY2Vsc3VzCitzdGF0aWMgdm9pZCBEdW1wS2V5VmFsUGFpcihtYXBwaW5nIHgsIG1peGVkIGtleSwgaW50IHNpemUpCit7IGludCBqLCB2YzsKKworICBQcmV0dHlEdW1wKGtleSk7CisgIHdyaXRlKCIgOiAiKTsKKyAgUHJldHR5RHVtcCh4W2tleSwwXSk7CisKKyAgZm9yICggaj0xOyBqPHNpemU7IGorKykKKyAgeworICAgIHdyaXRlKCI7ICIpOworICAgIFByZXR0eUR1bXAoeFtrZXksIGpdKTsKKyAgfQorfQpkaWZmIC0tZ2l0IGEvc3RkL3BsYXllci92aWV3Y21kLmMgYi9zdGQvcGxheWVyL3ZpZXdjbWQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41ZDdlNjE4Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3BsYXllci92aWV3Y21kLmMKQEAgLTAsMCArMSw3NTQgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBwbGF5ZXIvdmlld2NtZC5jIC0tIHBsYXllciB2aWV3IGNvbW1hbmQgaGFuZGxpbmcKKy8vCisvLyAkSWQ6IHZpZXdjbWQuYyA5NTQ4IDIwMTYtMDQtMTcgMTk6Mjg6MjJaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSAiL3N5cy90aGluZy9wcm9wZXJ0aWVzLmgiCisjaW5jbHVkZSAiL3N5cy9saXZpbmcvcHV0X2FuZF9nZXQuaCIKKyNpbmNsdWRlICIvc3lzL2xpdmluZy9kZXNjcmlwdGlvbi5oIgorCisjaW5jbHVkZSA8Y29udGFpbmVyLmg+CisjaW5jbHVkZSA8cGxheWVyLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHJvb21zLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDxhbnNpLmg+CisKKyNpbmNsdWRlIDxzeXNfZGVidWcuaD4KKwordmFyYXJncyBtaXhlZCBNb3JlKHN0cmluZyBzdHIsIGludCBmZmxhZywgc3RyaW5nIHJldHVybnRvKTsKKwordm9pZCBjcmVhdGUoKQoreworICBTZXQoUF9CUklFRiwgU0FWRSwgRl9NT0RFKTsKKyAgU2V0KFBfQkxJTkQsIFNBVkUsIEZfTU9ERSk7Cit9CisKK2ludCBfdG9nZ2xlX2JyaWVmKCkKK3sKKyAgaW50IGJyaWVmOworCisgIGlmIChxdWVyeV92ZXJiKCk9PSJrdXJ6IikKKyAgICBicmllZj0xOworICBlbHNlIGlmIChxdWVyeV92ZXJiKCk9PSJ1bHRyYWt1cnoiKQorICAgIGJyaWVmPTI7CisgIGVsc2UgYnJpZWY9MDsKKyAgU2V0UHJvcChQX0JSSUVGLCBicmllZik7CisgIHdyaXRlKCJEdSBiaXN0IG51biBpbSBcIiIrCisgICAgICAgIChicmllZj8oYnJpZWY9PTE/Ikt1cnoiOiJVbHRyYWt1cnoiKToiTGFuZyIpKyJcIm1vZHVzLlxuIik7CisgIHJldHVybiAxOworfQorCitwcml2YXRlIGludCBzb3J0aW52KG1peGVkIGEsIG1peGVkIGIpIHsgcmV0dXJuIGFbMF0gPiBiWzBdOyB9CisKK3ByaXZhdGUgc3RyaW5nIGNvbGxlY3RpbnYobWl4ZWQgb2JqKQoreworICBpZihvYmpbMF09PSIiKSByZXR1cm4gMDsKKyAgcmV0dXJuIChvYmpbMl0gPyAiICIgOiAiIikKKyAgICAgICArIG9ialswXQorICAgICAgICsgKG9ialsxXSA+IDEgPyAiICgiK29ialsxXSsiKSIgOiAiIik7Cit9CisKKyNkZWZpbmUgSV9BVVRPTE9BRCAgICAgIDEKKyNkZWZpbmUgSV9LRUVQICAgICAgICAgIDQKKyNkZWZpbmUgSV9GT1JNQVRURUQgICAgIDE2CisjZGVmaW5lIElfQVJNT1VSICAgICAgICA2NAorI2RlZmluZSBJX1NPUlQgICAgICAgICAgMjU2CisjZGVmaW5lIElfV0VBUE9OICAgICAgICAxMDI0CisjZGVmaW5lIElfRk9SQ0VfU09SVCAgICA0MDk2CisjZGVmaW5lIElfTk9fVEFCTEUgICAgICAxNjM4NAorCitwcml2YXRlIHN0cmluZyBnZXRmbGFncyhzdHJpbmcgYXJnLCBpbnQgZmxhZ3MpCit7CisgIGludCBubywgaTsKKyAgaWYoc2l6ZW9mKGFyZykgPCAyKSByZXR1cm4gMDsKKyAgbm8gPSAoYXJnWzBdID09ICctJyk7CisKKyAgZm9yKGkgPSAxOyBpIDwgc2l6ZW9mKGFyZyk7IGkrKykKKyAgeworICAgIHN3aXRjaChhcmdbaV0pCisgICAgeworICAgIGNhc2UgJ2EnOiBmbGFncyB8PSBJX0FVVE9MT0FEIDw8IG5vOyBicmVhazsKKyAgICBjYXNlICdiJzogZmxhZ3MgfD0gSV9LRUVQIDw8IG5vOyBicmVhazsKKyAgICBjYXNlICdmJzogZmxhZ3MgfD0gSV9GT1JNQVRURUQgPDwgbm87IGJyZWFrOworICAgIGNhc2UgJ3InOiBmbGFncyB8PSBJX0FSTU9VUiA8PCBubzsgYnJlYWs7CisgICAgY2FzZSAncyc6IGZsYWdzIHw9IElfU09SVCA8PCBubzsgYnJlYWs7CisgICAgY2FzZSAndyc6IGZsYWdzIHw9IElfV0VBUE9OIDw8IG5vOyBicmVhazsKKyAgICBjYXNlICd2JzogZmxhZ3MgfD0gKElfQVJNT1VSIHwgSV9XRUFQT04pIDw8ICFubzsgYnJlYWs7CisgICAgY2FzZSAnMSc6IGZsYWdzIHw9IElfTk9fVEFCTEU7IGJyZWFrOworICAgICAgICAvLyBEaWUgT3B0aW9uIG1hY2h0IG51ciBBZXJnZXIgdW5kIGtvbW1lbnRpZXJ0IGlzdCBzaWUgZWggbmljaHQuCisgICAgICAgIC8vIFdlciBkYXMgZHJpbmdlbmQgYnJhdWNodCwgc29sbCBXYXJnb25zIFNjaGllYmVwdXp6bGUgYmVudXR6ZW4uCisgICAgICAgIC8vCisgICAgICAgIC8vIFRpYW1haywgMTUuMTAuMjAwMAorICAgICAgICAvLyAgICBjYXNlICdTJzogZmxhZ3MgfD0gSV9GT1JDRV9TT1JUIDw8IG5vOyBicmVhazsKKyAgICBkZWZhdWx0IDogcmV0dXJuIGFyZ1tpLi5pXTsgLy8gd2lyZCBhdXNnZWdlYmVuIGFuIFNwaWVsZXIgYWxzIHVuYmVrYW5udC4KKyAgICB9CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgX2NoZWNrX2tlZXAob2JqZWN0IG9iKQoreworICByZXR1cm4gKG9iLT5RdWVyeVByb3AoUF9LRUVQX09OX1NFTEwpKT09Z2V0ZXVpZChNRSk7Cit9CisKK2ludCBfaW52ZW50b3J5KHN0cmluZyBzdHIpCit7CisgIG1peGVkICphcmdzLCBvdXRwdXQ7CisgIGludCBhbnNpLCBpLCBmbGFncywgbWludjsKKyAgbWl4ZWQgaW52ZW50b3J5LCB3ZWFwb25zLCBhcm1vdXJzLCBtaXNjOworICBzdHJpbmcgZm9ybWF0OworCisgIGlmKENhbm5vdFNlZSgpKSByZXR1cm4gMTsKKworICBpZigoc3RyID0gX3VucGFyc2VkX2FyZ3MoKSkgJiYgc3RyIT0iIikKKyAgeworICAgIHN0cmluZyBlcnJvcjsKKyAgICBlcnJvciA9ICJCZW51dHp1bmc6IGlbbnZlbnRhcl0gWy0vKzFhYmZyc3Z3XVxuIjsKKyAgICBhcmdzID0gcmVnZXhwKHJlZ2V4cGxvZGUoc3RyLCAiWy0rXVsxYWJmcnN3dl1bMWFiZnJzd3ZdKiIpLAorICAgICAgICAgICAgICAgICAgIlstK11bMWFiZnJzd3ZdWzFhYmZyc3d2XSoiKTsKKyAgICBpZighc2l6ZW9mKGFyZ3MpKSByZXR1cm4gKF9ub3RpZnlfZmFpbChlcnJvciksIDApOworICAgIGlmKHNpemVvZihhcmdzID0gbWFwKGFyZ3MsICMnZ2V0ZmxhZ3MvKicqLywgJmZsYWdzKSAtICh7IDAgfSkpKQorICAgIHsKKyAgICAgIHByaW50ZigiJXM6IFVuYmVrYW5udGVzIEFyZ3VtZW50LlxuIitlcnJvciwgaW1wbG9kZShhcmdzLCAiLCAiKSk7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKyAgLy8gRnVlciBTcGllbGVyIGdlaGVuIG51ciBzaWNodGJhcmUgT2JqZWt0ZSBpbiBkZW4gQWxnb3JpdGhtdXMKKyAgaWYgKElTX0xFQVJOSU5HKE1FKSkgIAorICAgIGludmVudG9yeSA9IGFsbF9pbnZlbnRvcnkoTUUpOworICBlbHNlCisgICAgaW52ZW50b3J5ID0gZmlsdGVyX29iamVjdHMoYWxsX2ludmVudG9yeShNRSksICJzaG9ydCIpOworICAKKyAgYW5zaSA9IG1lbWJlcigoeyJ2dDEwMCIsICJhbnNpIn0pLCBRdWVyeVByb3AoUF9UVFkpKSAhPSAtMTsKKyAgbWludiA9IDEgfCAoZmxhZ3MgJiAoSV9GT1JNQVRURUQgfCAoSV9GT1JNQVRURUQgPDwgMSkpID8gMiA6IDApOworICBmb3JtYXQgPSAoZmxhZ3MgJiBJX05PX1RBQkxFKSA/ICI9IiA6ICIjIjsKKworLy8gIGlmKGZsYWdzICYgKElfRk9SQ0VfU09SVCB8IElfRk9SQ0VfU09SVCA8PCAxKSkKKy8vICB7CisvLyAgICBjbG9zdXJlIHNmOworLy8gICAgc2YgPSBmbGFncyAmIElfRk9SQ0VfU09SVCA/ICMnPiA6ICMnPDsKKy8vICAgIHMgPSBzb3J0X2FycmF5KHMsIGxhbWJkYSgoeydhLCAnYn0pLAorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICh7IydmdW5jYWxsLCBzZiwKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoeyMnfHwsKHsjJ2NhbGxfb3RoZXIsJ2EsInNob3J0In0pLCIifSksCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHsjJ3x8LCh7IydjYWxsX290aGVyLCdiLCJzaG9ydCJ9KSwiIn0pfSkpKTsKKy8vICAgIG1hcF9vYmplY3RzKHMsICJtb3ZlIiwgdGhpc19vYmplY3QoKSk7CisvLyAgICBzID0gYWxsX2ludmVudG9yeShNRSk7CisvLyAgfQorCisgIGlmIChmbGFncyAmIElfQVVUT0xPQUQpCisgICAgaW52ZW50b3J5ID0gZmlsdGVyX29iamVjdHMoaW52ZW50b3J5LCJRdWVyeVByb3AiLFBfQVVUT0xPQURPQkopOworICBlbHNlIGlmIChmbGFncyAmIChJX0FVVE9MT0FEIDw8IDEpKQorICAgIGludmVudG9yeSAtPSBmaWx0ZXJfb2JqZWN0cyhpbnZlbnRvcnksIlF1ZXJ5UHJvcCIsUF9BVVRPTE9BRE9CSik7CisKKyAgaWYoZmxhZ3MgJiBJX0tFRVApCisgICAgaW52ZW50b3J5ID0gZmlsdGVyKGludmVudG9yeSwjJ19jaGVja19rZWVwKTsKKyAgZWxzZSBpZihmbGFncyAmIChJX0tFRVAgPDwgMSkpCisgICAgaW52ZW50b3J5IC09IGZpbHRlcihpbnZlbnRvcnksIydfY2hlY2tfa2VlcCk7CisKKyAgYXJtb3VycyA9IGZpbHRlcl9vYmplY3RzKGludmVudG9yeSwgIlF1ZXJ5UHJvcCIsIFBfQVJNT1VSX1RZUEUpOworICAvLyBLbGVpZHVuZyBkYXp1IGFkZGllcmVuLCB2b3JoZXIgZGllIGVya2FubnRlbiBSdWVzdHVuZ2VuIGFiemllaGVuLCBkaWUKKyAgLy8gbXVlc3NlbiBuaWNodCBub2NobWFsIGR1cmNoaXRlcmllcnQgd2VyZGVuLgorICBhcm1vdXJzICs9IGZpbHRlcl9vYmplY3RzKGludmVudG9yeS1hcm1vdXJzLCAiSXNDbG90aGluZyIpOworICAvLyBSdWVzdHVuZ2VuIHdlcmRlbiBoaWVyIG5pY2h0IGFiZ2V6b2dlbiwgd2VpbCBlcyBLcmFtIGdpYnQsIHdlbGNoZSBzb3dvaGwKKyAgLy8gUnVlc3R1bmcgYWxzIGF1Y2ggV2FmZmUgaXN0LgorICB3ZWFwb25zID0gZmlsdGVyX29iamVjdHMoaW52ZW50b3J5LCAiUXVlcnlQcm9wIiwgUF9XRUFQT05fVFlQRSk7CisgIG1pc2MgPSBpbnZlbnRvcnkgLSB3ZWFwb25zIC0gYXJtb3VyczsgLy8gcmVzdCA7LSkKKworICBpZihmbGFncyAmIElfV0VBUE9OKQorICB7CisgICAgaW52ZW50b3J5ID0gd2VhcG9uczsgbWlzYyA9ICh7fSk7CisgICAgaWYoIShmbGFncyAmIChJX0FSTU9VUikpKSBhcm1vdXJzID0gKHt9KTsKKyAgfQorICBpZihmbGFncyAmIElfQVJNT1VSKQorICB7CisgICAgIGludmVudG9yeSA9IGFybW91cnM7IG1pc2MgPSAoe30pOworICAgICBpZighKGZsYWdzICYgSV9XRUFQT04pKSB3ZWFwb25zID0gKHt9KTsKKyAgfQorICBpZihmbGFncyAmIChJX1dFQVBPTiA8PCAxKSkgeyB3ZWFwb25zID0gKHt9KTsgaW52ZW50b3J5ID0gYXJtb3VycyArIG1pc2M7IH0KKyAgaWYoZmxhZ3MgJiAoSV9BUk1PVVIgPDwgMSkpIHsgYXJtb3VycyA9ICh7fSk7IGludmVudG9yeSA9IHdlYXBvbnMgKyBtaXNjOyB9CisKKyAgb3V0cHV0ID0gIiI7CisgIGlmKGZsYWdzICYgKElfRk9STUFUVEVEIHwgKElfRk9STUFUVEVEIDw8IDEpKSkKKyAgeworICAgIGludmVudG9yeSA9IG1ha2VfaW52bGlzdCh0aGlzX3BsYXllcigpLCBpbnZlbnRvcnksIG1pbnYpOworICAgIGlmKGZsYWdzICYgKElfU09SVCB8IChJX1NPUlQgPDwgMSkpKQorICAgIGludmVudG9yeSA9IHNvcnRfYXJyYXkoaW52ZW50b3J5LCAjJ3NvcnRpbnYvKicqLyk7CisgICAgb3V0cHV0ICs9IHNwcmludGYoIiUiK2Zvcm1hdCsiLTc4c1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICBpbXBsb2RlKG1hcChpbnZlbnRvcnksIydjb2xsZWN0aW52LyonKi8pLCJcbiIpKTsKKyAgfQorICBlbHNlCisgIHsKKyAgICBpZih3ZWFwb25zICYmIHNpemVvZih3ZWFwb25zKSkKKyAgICB7CisgICAgICB3ZWFwb25zID0gbWFrZV9pbnZsaXN0KHRoaXNfcGxheWVyKCksIHdlYXBvbnMsIG1pbnYpOworICAgICAgaWYoZmxhZ3MgJiAoSV9TT1JUIHwgKElfU09SVCA8PCAxKSkpCisgICAgICAgIHdlYXBvbnMgPSBzb3J0X2FycmF5KHdlYXBvbnMsICMnc29ydGludi8qJyovKTsKKyAgICAgIG91dHB1dCArPSAoYW5zaT9BTlNJX0JPTEQ6IiIpICsgIldhZmZlbjoiICsgKGFuc2k/QU5TSV9OT1JNQUw6IiIpKyJcbiIKKyAgICAgICAgICAgICAgKyBzcHJpbnRmKCIlIitmb3JtYXQrIi03OHNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICBpbXBsb2RlKG1hcCh3ZWFwb25zLCAjJ2NvbGxlY3RpbnYvKicqLyksICJcbiIpKTsKKyAgICB9CisgICAgaWYoYXJtb3VycyAmJiBzaXplb2YoYXJtb3VycykpCisgICAgeworICAgICAgYXJtb3VycyA9IG1ha2VfaW52bGlzdCh0aGlzX3BsYXllcigpLCBhcm1vdXJzLCBtaW52KTsKKyAgICAgIGlmKGZsYWdzICYgKElfU09SVCB8IChJX1NPUlQgPDwgMSkpKQorICAgICAgICBhcm1vdXJzID0gc29ydF9hcnJheShhcm1vdXJzLCAjJ3NvcnRpbnYvKicqLyk7CisgICAgICBvdXRwdXQgKz0gKGFuc2k/QU5TSV9CT0xEOiIiKSAKKyAgICAgICAgICAgICAgKyAiS2xlaWR1bmcgJiBSdWVzdHVuZ2VuOiIgKyAoYW5zaT9BTlNJX05PUk1BTDoiIikrIlxuIgorICAgICAgICAgICAgICArIHNwcmludGYoIiUiK2Zvcm1hdCsiLTc4c1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGltcGxvZGUobWFwKGFybW91cnMsICMnY29sbGVjdGludi8qJyovKSwgIlxuIikpOworICAgIH0KKyAgICBpZihtaXNjICYmIHNpemVvZihtaXNjKSkKKyAgICB7CisgICAgICBtaXNjID0gbWFrZV9pbnZsaXN0KHRoaXNfcGxheWVyKCksIG1pc2MsIG1pbnYpOworICAgICAgaWYoZmxhZ3MgJiAoSV9TT1JUIHwgKElfU09SVCA8PCAxKSkpCisgICAgICAgIG1pc2MgPSBzb3J0X2FycmF5KG1pc2MsICMnc29ydGludi8qJyovKTsKKyAgICAgIG91dHB1dCArPSAoYW5zaT9BTlNJX0JPTEQ6IiIpICsgIlZlcnNjaGllZGVuZXM6IiArIChhbnNpP0FOU0lfTk9STUFMOiIiKSsiXG4iCisgICAgICAgICAgICAgICsgc3ByaW50ZigiJSIrZm9ybWF0KyItNzhzXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgaW1wbG9kZShtYXAobWlzYywgIydjb2xsZWN0aW52LyonKi8pLCAiXG4iKSk7CisgICAgfQorICB9CisKKyAgLy8gU3BpZWxlcnd1bnNjaDogJ2ludmVudGFyJyBzb2xsdGUgZG9jaCBkYXMgQmV6dWdzb2JqZWt0IGF1ZiBkZW4gU3BpZWxlcgorICAvLyBhZW5kZXJuLgorICBTZXRQcm9wKFBfUkVGRVJFTkNFX09CSkVDVCwgdGhpc19vYmplY3QoKSk7CisKKyAgaWYgKG91dHB1dD09IiIpIAorICAgIG91dHB1dCArPSAoYW5zaT9BTlNJX0JPTEQ6IiIpKyJEaWUgTGlzdGUgaXN0IGxlZXIuIisoYW5zaT9BTlNJX05PUk1BTDoiIik7CisgIE1vcmUob3V0cHV0KTsKKyAgcmV0dXJuIDE7Cit9CisKK3ByaXZhdGUgbm9zYXZlIGludCBleGFfY250OworcHJpdmF0ZSBub3NhdmUgaW50IGV4YV90aW1lOworcHJpdmF0ZSBub3NhdmUgc3RyaW5nICpleGE7CisKK3ZhcmFyZ3MgaW50IF9leGFtaW5lKHN0cmluZyBzdHIsIGludCBtb2RlKQoreworICBvYmplY3QgYmFzZSwgKm9ianMsIGVudjsKKyAgc3RyaW5nIHdoYXQsIGRldGFpbCwgcGFyZW50LCBvdXQsIGVycm9yOworICBpbnQgaSwgc2l6ZSwgZG9uZTsKKworICBpZihDYW5ub3RTZWUoKSkgcmV0dXJuIDE7CisKKyAgX25vdGlmeV9mYWlsKCJXYXMgd2lsbHN0IER1IGRlbm4gdW50ZXJzdWNoZW4/XG4iKTsKKyAgaWYgKCFzdHIpIHJldHVybiAwOworCisgIGlmIChtZW1iZXIoKHsiYm9kZW4iLCJkZWNrZSIsIndhbmQiLCJ3YWVuZGUifSksb2xkX2V4cGxvZGUoc3RyLCIgIilbMF0pID09IC0xKSB7CisgICAgZXhhX2NudCAtPSAodGltZSgpIC0gZXhhX3RpbWUpLzI7CisgICAgZXhhX3RpbWUgPSB0aW1lKCk7CisgICAgZXhhX2NudCsrOworICAgIGlmICghZXhhKQorICAgICAgZXhhID0gKHsgc3RyIH0pOworICAgIGVsc2UKKyAgICAgIGV4YSArPSAoeyBzdHIgfSk7CisgICAgaWYgKGV4YV9jbnQgPiAxMCkgeworICAgICAgbG9nX2ZpbGUoIkFSQ0gvTE9PSyIsIAorICAgICAgICAgIHNwcmludGYoIiVzOiAlcyBpbiAlc1xuJUBPXG4iLGR0aW1lKHRpbWUoKSksZ2V0dWlkKHRoaXNfb2JqZWN0KCkpLCAKKyAgICAgICAgICAgIGVudmlyb25tZW50KCkgPyBvYmplY3RfbmFtZShlbnZpcm9ubWVudCgpKSA6ICI/Pz8iLGV4YSksIDE1MDAwMCk7CisgICAgICBleGFfY250ID0gMDsKKyAgICAgIGV4YSA9ICh7fSk7CisgICAgfQorICAgIGVsc2UgaWYgKGV4YV9jbnQgPCAwKSB7CisgICAgICBleGFfY250ID0gMDsKKyAgICAgIGV4YSA9ICh7fSk7CisgICAgfQorICB9CisgIC8vIGRvIHdlIGxvb2sgYXQgYW4gb2JqZWN0IGluIG91ciBlbnZpcm9ubWVudCA/CisgIGlmIChzc2NhbmYoc3RyLCIlcyBpbiByYXVtIiwgd2hhdCkgfHwgc3NjYW5mKHN0ciwiJXMgaW0gcmF1bSIsIHdoYXQpKQorICAgICAgYmFzZSA9IGVudmlyb25tZW50KCk7CisgIC8vIGlzIHRoZSBvYmplY3QgaW5zaWRlIG9mIG1lIChpbnZlbnRvcnkpCisgIGVsc2UgaWYgKHNzY2FuZihzdHIsIiVzIGluIG1pciIsIHdoYXQpIHx8IHNzY2FuZihzdHIsIiVzIGluIGRpciIsIHdoYXQpKQorICAgICAgYmFzZSA9IHRoaXNfb2JqZWN0KCk7CisgIGVsc2UgeworICAgICAgd2hhdCA9IHN0cjsKKyAgICAgIC8vIGdldCB0aGUgbGFzdCBvYmplY3Qgd2UgbG9va2VkIGF0CisgICAgICBiYXNlID0gUXVlcnlQcm9wKFBfUkVGRVJFTkNFX09CSkVDVCk7CisgICAgICAKKyAgICAgIC8vIGlmIGEgcmVmZXJlbmNlIG9iamVjdCBleGlzdHMsIHRlc3QgZm9yIGl0cyBleGlzdGFuY2UgaW4gdGhlIHJvb20KKyAgICAgIC8vIG9yIGluIG91ciBpbnZlbnRvcnkKKyAgICAgIGlmIChvYmplY3RwKGJhc2UpKQorICAgICAgeworICAgICAgIGlmIChiYXNlID09IGVudmlyb25tZW50KCkgfHwgYmFzZT09dGhpc19vYmplY3QoKSkKKyAgICAgICAgeworICAgICAgICAgIC8vIFVtZ2VidW5nIG9kZXIgU3BpZWxlciBzZWxiZXIgc2luZCBhbHMgQmV6dWdzb2JqZWt0IGltbWVyIGluCisgICAgICAgICAgLy8gT3JkbnVuZywgbmljaHRzIG1hY2hlbi4KKyAgICAgICAgfQorICAgICAgICAvLyBEYXMgUmVmZXJlbnpvYmpla3QgZGFyZiBuaWNodCB1bnNpY2h0YmFyIHNlaW4uCisgICAgICAgIGVsc2UgaWYgKCFiYXNlLT5zaG9ydCgpKQorICAgICAgICAgIGJhc2UgPSAwOworICAgICAgICBlbHNlIGlmKG1lbWJlcihkZWVwX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSwgYmFzZSkgIT0gLTEpCisgICAgICAgIHsKKyAgICAgICAgICBmb3JlYWNoKGVudiA6IGFsbF9lbnZpcm9ubWVudChiYXNlKSkgeworICAgICAgICAgICAgLy8gSXN0IGVpbmUgVW1nZWJ1bmcgTGl2aW5nIG9kZXIgaW50cmFuc3BhcmVudGVyIENvbnRhaW5lciBvZGVyCisgICAgICAgICAgICAvLyB1bnNpY2h0YmFyPworICAgICAgICAgICAgaWYgKGxpdmluZyhlbnYpIHx8ICFlbnYtPlF1ZXJ5UHJvcChQX1RSQU5TUEFSRU5UKQorICAgICAgICAgICAgICAgIHx8ICFlbnYtPnNob3J0KCkpCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIC8vIGluIGRlbSBGYWxsIGlzdCBlbmRlLCBhYmVyIHdlbm4gZGFzIGdlZnVuZGVuZSBFbnYgbmljaHQKKyAgICAgICAgICAgICAgLy8gZGllc2VzIExpdmluZyBzZWxiZXIgb2RlciBzZWluIEVudiBpc3QsIHdpcmQgZGFzCisgICAgICAgICAgICAgIC8vIFJlZmVyZW56b2JqZWt0IHp1c2FldHpsaWNoIGdlbnVsbHQuCisgICAgICAgICAgICAgIGlmIChlbnYgIT0gdGhpc19vYmplY3QoKSAmJiBlbnYgIT0gZW52aXJvbm1lbnQoKSkKKyAgICAgICAgICAgICAgICBiYXNlID0gMDsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICBiYXNlID0gMDsgLy8gbmljaHQgaW0gUmF1bSBvZGVyIEludmVudG9yeQorICAgICAgfQorICB9CisKKyAgLy8gc2NhbiBpbnB1dCBpZiB3ZSB3YW50IGEgc3BlY2lmaWMgb2JqZWN0IHRvIGxvb2sgYXQKKyAgaWYoc3NjYW5mKHdoYXQsICIlcyBhbiAlcyIsIGRldGFpbCwgcGFyZW50KSA9PSAyIHx8CisgICAgIHNzY2FuZih3aGF0LCAiJXMgYW0gJXMiLCBkZXRhaWwsIHBhcmVudCkgPT0gMiB8fAorICAgICBzc2NhbmYod2hhdCwgIiVzIGluICVzIiwgZGV0YWlsLCBwYXJlbnQpID09IDIgfHwKKyAgICAgc3NjYW5mKHdoYXQsICIlcyBpbSAlcyIsIGRldGFpbCwgcGFyZW50KSA9PSAyKQorICB7CisgICAgLy8gaWYgYW4gcmVmIG9iamVjdCBleGlzdHMgZ2V0IGl0cyBpbnZlbnRvcnkuIChPYmVuIHd1cmRlIHNpY2hlcmdlc3RlbGx0LAorICAgIC8vIGRhc3MgZGFzIFJlZmVyZW56b2JqZWt0IGVpbnNlaGJhciBpc3QpCisgICAgaWYoYmFzZSkKKyAgICAgIG9ianMgPSBiYXNlLT5sb2NhdGVfb2JqZWN0cyhwYXJlbnQsIDEpIHx8ICh7fSk7CisgICAgZWxzZSB7CisgICAgICAvLyBlbHNlIGdldCBvdXIgaW52IGFuZCBlbnYKKyAgICAgIG9ianMgPSBlbnZpcm9ubWVudCgpLT5sb2NhdGVfb2JqZWN0cyhwYXJlbnQsIDEpCisgICAgICAgICAgICsgbG9jYXRlX29iamVjdHMocGFyZW50LCAxKTsKKyAgICB9CisgICAgb2JqcyA9IGZpbHRlcl9vYmplY3RzKG9ianMsICJzaG9ydCIpOyAvLyBudXIgc2ljaHRiYXJlLi4uCisgICAgaWYoc2l6ZW9mKG9ianMpID4gMSkKKyAgICAgIHJldHVybiAobm90aWZ5X2ZhaWwoIkVzIGdpYnQgbWVociBhbHMgZWluZShuKSAiK2NhcGl0YWxpemUocGFyZW50KSsiLlxuIiksIDApOworICAgIGVsc2UKKyAgICB7CisgICAgICBpZiAoc2l6ZW9mKG9ianMpKQorICAgICAgICBiYXNlID0gb2Jqc1swXTsKKyAgICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIChub3RpZnlfZmFpbCgiSGllciBpc3Qga2VpbihlKSAiK2NhcGl0YWxpemUocGFyZW50KSsiLlxuIiksIDApOworICAgIH0KKyAgICBvYmpzID0gMDsKKyAgfQorICBlbHNlIGRldGFpbCA9IHdoYXQ7CisKKyAgaW50IGJhc2Vfd2FzX2VudiA9IDE7CisgIGRvIHsKKyAgICAvLyBpZiBhIGJhc2UgZXhpc3RzIGdldCBpdHMgaW52ZW50b3J5LCBlbHNlIGdldCBvdXIgaW52IGFuZCBlbnYKKyAgICBpZiAoYmFzZSkKKyAgICB7CisgICAgICBpZiAgKGJhc2UgPT0gdGhpc19vYmplY3QoKSB8fCBiYXNlID09IGVudmlyb25tZW50KCkgfHwKKyAgICAgICAgICAoYmFzZS0+UXVlcnlQcm9wKFBfVFJBTlNQQVJFTlQpICYmICFsaXZpbmcoYmFzZSkpKQorICAgICAgeworICAgICAgICAvLyBpY2gga2FubiBpbiBiYXNlIHJlaW5ndWNrZW4uLi4KKyAgICAgICAgb2JqcyA9IGJhc2UtPmxvY2F0ZV9vYmplY3RzKGRldGFpbCwgMSkgfHwgKHt9KTsKKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgIHsKKyAgICAgICAgLy8gUmVmZXJlbnpvYmpla3QgZGEsIGFiZXIgbmljaHQgcmVpbmd1Y2tiYXIuIGJhc2UgYWJlciBuaWNodCBudWxsZW4sCisgICAgICAgIC8vIGRlbm4gZXMgaXN0IGphIG5vY2ggZ3VlbHRpZyBmdWVyIERldGFpbHN1Y2hlbiBhbiBiYXNlLi4uCisgICAgICAgIG9ianMgPSAoe30pOworICAgICAgfQorICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgb2JqcyA9IGVudmlyb25tZW50KCktPmxvY2F0ZV9vYmplY3RzKGRldGFpbCwgMSkKKyAgICAgICAgICAgKyBsb2NhdGVfb2JqZWN0cyhkZXRhaWwsIDEpOworICAgICAgYmFzZSA9IGVudmlyb25tZW50KCk7CisgICAgfQorICAgIG9ianMgPSBmaWx0ZXJfb2JqZWN0cyhvYmpzLCAic2hvcnQiKTsgLy8gbnVyIHNpY2h0YmFyZS4uLgorCisgICAgaWYoIXNpemVvZihvYmpzKSkKKyAgICB7CisgICAgICAvLyB3ZW5uIGtlaW5lIE9iamVrdGUgZ2VmdW5kZW4gd3VyZGVuLCB3aXJkIG5hY2ggRGV0YWlscyBnZXN1Y2h0Li4uCisgICAgICBpZigob3V0ID0gYmFzZS0+R2V0RGV0YWlsKGRldGFpbCwgUXVlcnlQcm9wKFBfUkVBTF9SQUNFKSxTRU5TRV9WSUVXKSkgfHwKKyAgICAgICAgIChvdXQgPSBiYXNlLT5HZXREb29yRGVzYyhkZXRhaWwpKSkKKyAgICAgIHsKKyAgICAgICAgU2V0UHJvcChQX1JFRkVSRU5DRV9PQkpFQ1QsIGJhc2UpOworICAgICAgICByZXR1cm4gKHdyaXRlKG91dCksIDEpOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgeworICAgICAgICAvLyB3ZW5uIGF1Y2gga2VpbmUgRGV0YWlscyBnZWZ1bmRlbiwgZGFubiBzY2hhdWVuLCBvYiBFbmRlIGlzdAorICAgICAgICAvLyAoYmFzZT09ZW52KSBvZGVyIHdpciBldnRsLiBub2NoIGltIGVudiBzdWNoZW4ga29lbm5lbi4KKyAgICAgICAgaWYgKGJhc2UgPT0gZW52aXJvbm1lbnQoKSkKKyAgICAgICAgeworICAgICAgICAgIGlmIChiYXNlX3dhc19lbnYpIHsKKyAgICAgICAgICAgIC8vIGluIGRpZXNlbSBGYWxsIHdhciBkYXMgRW52IGRhcyBCZXp1Z3NvYmpla3QgLSBkYWhlciB3ZWd3ZXJmZW4uCisgICAgICAgICAgICBTZXRQcm9wKFBfUkVGRVJFTkNFX09CSkVDVCwgMCk7CisgICAgICAgICAgICBfbm90aWZ5X2ZhaWwoIlNvd2FzIHNpZWhzdCBEdSBkYSBuaWNodCFcbiIpOworICAgICAgICAgIH0KKyAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIF9ub3RpZnlfZmFpbCgiU293YXMgc2llaHN0IER1IGF1Y2ggZGEgbmljaHQhXG4iKTsKKyAgICAgICAgICAgIC8vIGluIGRpZXNlbSBGYWxsIHdhciBuaWNodCBkYXMgRW52IGRhcyBCZXp1Z3NvYmpla3QgLSBlcyBzb2xsCisgICAgICAgICAgICAvLyBiZWhhbHRlbiB1bmQgbmljaHQgZ2Vsb2VzY2h0IHdlcmRlbi4KKyAgICAgICAgICB9CisgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgYmFzZV93YXNfZW52PTA7CisgICAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJEdSBmaW5kZXN0IGFuICIrYmFzZS0+bmFtZShXRU0pCisgICAgICAgICAgICAgICAgKyIga2VpbiBcIiIgKyBjYXBpdGFsaXplKGRldGFpbCkgKyAiXCIuIgorICAgICAgICAgICAgICAgICAiIERlaW4gQmxpY2sgd2VuZGV0IHNpY2ggZGVyIFVtZ2VidW5nIHp1LiIsNzgpKTsKKyAgICAgICAgICBiYXNlID0gMDsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgICBlbHNlICAvLyBPYmpla3RlIGdlZnVuZGVuIQorICAgICAgZG9uZSA9IDE7CisgIH0gd2hpbGUoIWRvbmUpOworCisgIC8vIEVzIG11c3MgbWluLiBlaW4gKHNpY2h0YmFyZXMpIE9iamVrdCBnZWJlbiwgc29uc3Qgd2FlcmUgbWFuIGhpZXIgbmljaHQKKyAgLy8gaGluZ2Vrb21tZW4uCisgIG9iamVjdCBvYiA9IG9ianNbMF07CisgIFNldFByb3AoUF9SRUZFUkVOQ0VfT0JKRUNULCBvYik7CisgIHRlbGxfb2JqZWN0KE1FLCBvYi0+bG9uZyhtb2RlKSk7CisgIHJldHVybiAxOworfQorCit2YXJhcmdzIGludCBfc2Vuc2VfZXhhKHN0cmluZyBzdHIpCit7CisgIG9iamVjdCBiYXNlLCAqb2JqcywgZW52OworICBzdHJpbmcgd2hhdCwgZGV0YWlsLCBwYXJlbnQsIG91dCwgZXJyb3I7CisgIGludCBzZW5zZTsKKworICBpZihtZW1iZXIoKHsicmllY2giLCJyaWVjaGUiLCJzY2hudXBwZXIiLCJzY2hudXBwZXJlIn0pLHF1ZXJ5X3ZlcmIoKSkhPS0xKQorICB7CisgICAgX25vdGlmeV9mYWlsKCJEdSBrYW5uc3QgbmljaHRzIEJlc29uZGVyZXMgcmllY2hlbi5cbiIpOworICAgIHNlbnNlID0gU0VOU0VfU01FTEw7CisgIH0KKyAgZWxzZSBpZihtZW1iZXIoKHsibGF1c2NoZSIsImxhdXNjaCIsImhvZXIiLCJob2VyZSJ9KSxxdWVyeV92ZXJiKCkpIT0tMSkKKyAgeworICAgIGlmKFF1ZXJ5UHJvcChQX0RFQUYpKQorICAgICAgcmV0dXJuIG5vdGlmeV9mYWlsKCJEdSBiaXN0IHRhdWIhXG4iKSwgMDsKKworICAgIF9ub3RpZnlfZmFpbCgiRHUga2FubnN0IG5pY2h0cyBCZXNvbmRlcmVzIGhvZXJlbi5cbiIpOworICAgIHNlbnNlID0gU0VOU0VfU09VTkQ7CisgIH0KKyAgZWxzZSBpZihtZW1iZXIoKHsidGFzdGUiLCJiZXJ1ZWhyZSIsImJlcnVlaHIifSkscXVlcnlfdmVyYigpKSE9LTEpCisgIHsKKyAgICBzZW5zZSA9IFNFTlNFX1RPVUNIOworICAgIC8vIGVpbiAiYWIiIGdhbnogYW0gRW5kZSB2b24gc3RyIHdpcmQgYWJnZXNjaG5pdHRlbiwgZXMgc29sbCBzb3dvaGwgInRhc3RlCisgICAgLy8geCBhYiIgYWxzIGF1Y2ggInRhc3RlIHgiIGZ1bmt0aW9uaWVyZW4uCisgICAgaWYgKHN0cikgeworICAgICAgX25vdGlmeV9mYWlsKCJTb3dhcyBrYW5uc3QgRHUgaGllciBuaWNodCBlcnRhc3RlbiFcbiIpOworICAgICAgc3RyaW5nICp0bXAgPSBleHBsb2RlKHN0ciwiICIpOworICAgICAgaWYgKHNpemVvZih0bXApID4gMSAmJiB0bXBbPDFdID09ICJhYiIpCisgICAgICAgIHN0ciA9IGltcGxvZGUodG1wWzAuLjwyXSwgIiAiKTsKKyAgICB9CisgICAgZWxzZQorICAgICAgX25vdGlmeV9mYWlsKCJXYXMgd2lsbHN0IER1IGRlbm4gYWJ0YXN0ZW4/XG4iKTsKKyAgfQorICBlbHNlIGlmIChtZW1iZXIoKHsibGllcyIsImxlc2UiLCJsZXMifSksIHF1ZXJ5X3ZlcmIoKSkgPiAtMSkKKyAgeworICAgIF9ub3RpZnlfZmFpbCgiV2FzIHdpbGxzdCBEdSBsZXNlbj9cbiIpOworICAgIGlmICggIXN0ciApIC8vIEtlaW4gU0VOU0VfREVGQVVMVCB6dWxhc3Nlbi4KKyAgICAgIHJldHVybiAwOworICAgIGlmICh0aGlzX29iamVjdCgpLT5DYW5ub3RTZWUoKSkgeworICAgICAgbm90aWZ5X2ZhaWwoIkR1IGthbm5zdCBuaWNodHMgc2VoZW4hXG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBzZW5zZSA9IFNFTlNFX1JFQUQ7CisgIH0KKworICBpZiAoIXN0cikgeworICAgIGlmKCFkZXRhaWwgPQorICAgICAgICBlbnZpcm9ubWVudCgpLT5HZXREZXRhaWwoU0VOU0VfREVGQVVMVCxRdWVyeVByb3AoUF9SRUFMX1JBQ0UpLHNlbnNlKSkKKyAgICAgIHJldHVybiAwOworICAgIHdyaXRlKGRldGFpbCk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgZWxzZSBpZihzc2NhbmYoc3RyLCJhbiAlcyIsd2hhdCk9PTEpCisgICAgc3RyPXdoYXQ7CisKKyAgLy8gZG8gd2UgbG9vayBhdCBhbiBvYmplY3QgaW4gb3VyIGVudmlyb25tZW50ID8KKyAgaWYgKHNzY2FuZihzdHIsIiVzIGluIHJhdW0iLCB3aGF0KSB8fCBzc2NhbmYoc3RyLCIlcyBpbSByYXVtIiwgd2hhdCkpCisgICAgICBiYXNlID0gZW52aXJvbm1lbnQoKTsKKyAgLy8gaXMgdGhlIG9iamVjdCBpbnNpZGUgb2YgbWUgKGludmVudG9yeSkKKyAgZWxzZSBpZiAoc3NjYW5mKHN0ciwiJXMgaW4gbWlyIiwgd2hhdCkgfHwgc3NjYW5mKHN0ciwiJXMgaW4gZGlyIiwgd2hhdCkpCisgICAgICBiYXNlID0gdGhpc19vYmplY3QoKTsKKyAgZWxzZSB7CisgICAgICB3aGF0ID0gc3RyOworICAgICAgLy8gZ2V0IHRoZSBsYXN0IG9iamVjdCB3ZSBsb29rZWQgYXQKKyAgICAgIGJhc2UgPSBRdWVyeVByb3AoUF9SRUZFUkVOQ0VfT0JKRUNUKTsKKyAgICAgIAorICAgICAgLy8gaWYgYSByZWZlcmVuY2Ugb2JqZWN0IGV4aXN0cywgdGVzdCBmb3IgaXRzIGV4aXN0YW5jZSBpbiB0aGUgcm9vbQorICAgICAgLy8gb3IgaW4gb3VyIGludmVudG9yeQorICAgICAgaWYgKG9iamVjdHAoYmFzZSkpCisgICAgICB7CisgICAgICAgIGlmIChiYXNlID09IGVudmlyb25tZW50KCkgfHwgYmFzZT09dGhpc19vYmplY3QoKSkKKyAgICAgICAgeworICAgICAgICAgIC8vIFVtZ2VidW5nIG9kZXIgU3BpZWxlciBzZWxiZXIgc2luZCBhbHMgQmV6dWdzb2JqZWt0IGltbWVyIGluCisgICAgICAgICAgLy8gT3JkbnVuZywgbmljaHRzIG1hY2hlbi4KKyAgICAgICAgfQorICAgICAgICAvLyBEYXMgUmVmZXJlbnpvYmpla3QgZGFyZiBuaWNodCB1bnNpY2h0YmFyIHNlaW4uCisgICAgICAgIGVsc2UgaWYgKCFiYXNlLT5zaG9ydCgpKQorICAgICAgICAgIGJhc2UgPSAwOworICAgICAgICBlbHNlIGlmKG1lbWJlcihkZWVwX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSwgYmFzZSkgIT0gLTEpCisgICAgICAgIHsKKyAgICAgICAgICBmb3JlYWNoKGVudiA6IGFsbF9lbnZpcm9ubWVudChiYXNlKSkgeworICAgICAgICAgICAgLy8gSXN0IGVpbmUgVW1nZWJ1bmcgTGl2aW5nIG9kZXIgaW50cmFuc3BhcmVudGVyIENvbnRhaW5lciBvZGVyCisgICAgICAgICAgICAvLyB1bnNpY2h0YmFyPworICAgICAgICAgICAgaWYgKGxpdmluZyhlbnYpIHx8ICFlbnYtPlF1ZXJ5UHJvcChQX1RSQU5TUEFSRU5UKQorICAgICAgICAgICAgICAgIHx8ICFlbnYtPnNob3J0KCkpCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgIC8vIGluIGRlbSBGYWxsIGlzdCBlbmRlLCBhYmVyIHdlbm4gZGFzIGdlZnVuZGVuZSBFbnYgbmljaHQKKyAgICAgICAgICAgICAgLy8gZGllc2VzIExpdmluZyBzZWxiZXIgb2RlciBzZWluIEVudiBpc3QsIHdpcmQgZGFzCisgICAgICAgICAgICAgIC8vIFJlZmVyZW56b2JqZWt0IHp1c2FldHpsaWNoIGdlbnVsbHQuCisgICAgICAgICAgICAgIGlmIChlbnYgIT0gdGhpc19vYmplY3QoKSAmJiBlbnYgIT0gZW52aXJvbm1lbnQoKSkKKyAgICAgICAgICAgICAgICBiYXNlID0gMDsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICBiYXNlID0gMDsgLy8gbmljaHQgaW0gUmF1bSBvZGVyIEludmVudG9yeQorICAgICAgfQorICB9CisKKyAgLy8gc2NhbiBpbnB1dCBpZiB3ZSB3YW50IGEgc3BlY2lmaWMgb2JqZWN0IHRvIGxvb2sgYXQKKyAgaWYoc3NjYW5mKHdoYXQsICIlcyBhbiAlcyIsIGRldGFpbCwgcGFyZW50KSA9PSAyIHx8CisgICAgIHNzY2FuZih3aGF0LCAiJXMgYW0gJXMiLCBkZXRhaWwsIHBhcmVudCkgPT0gMiB8fAorICAgICBzc2NhbmYod2hhdCwgIiVzIGluICVzIiwgZGV0YWlsLCBwYXJlbnQpID09IDIgfHwKKyAgICAgc3NjYW5mKHdoYXQsICIlcyBpbSAlcyIsIGRldGFpbCwgcGFyZW50KSA9PSAyKQorICB7CisgICAgLy8gaWYgYW4gcmVmIG9iamVjdCBleGlzdHMgZ2V0IGl0cyBpbnZlbnRvcnkuIChPYmVuIHd1cmRlIHNpY2hlcmdlc3RlbGx0LAorICAgIC8vIGRhc3MgZGFzIFJlZmVyZW56b2JqZWt0IGVpbnNlaGJhciBpc3QpCisKKyAgICBpZihiYXNlKQorICAgICAgb2JqcyA9IGJhc2UtPmxvY2F0ZV9vYmplY3RzKHBhcmVudCwgMSkgfHwgKHt9KTsKKyAgICBlbHNlCisgICAgeworICAgICAgLy8gZWxzZSBnZXQgb3VyIGludiBhbmQgZW52CisgICAgICBvYmpzID0gZW52aXJvbm1lbnQoKS0+bG9jYXRlX29iamVjdHMocGFyZW50LCAxKQorICAgICAgICAgICArIGxvY2F0ZV9vYmplY3RzKHBhcmVudCwgMSk7CisgICAgfQorICAgIG9ianMgPSBmaWx0ZXJfb2JqZWN0cyhvYmpzLCAic2hvcnQiKTsgLy8gbnVyIHNpY2h0YmFyZS4uLgorICAgIGlmKHNpemVvZihvYmpzKSA+IDEpCisgICAgICByZXR1cm4gKG5vdGlmeV9mYWlsKCJFcyBnaWJ0IG1laHIgYWxzIGVpbmUobikgIitjYXBpdGFsaXplKHBhcmVudCkrIi5cbiIpLCAwKTsKKyAgICBlbHNlCisgICAgeworICAgICAgaWYoc2l6ZW9mKG9ianMpKQorICAgICAgICAgIGJhc2UgPSBvYmpzWzBdOworICAgICAgZWxzZQorICAgICAgICAgIHJldHVybiAobm90aWZ5X2ZhaWwoIkhpZXIgaXN0IGtlaW4oZSkgIitjYXBpdGFsaXplKHBhcmVudCkrIi5cbiIpLCAwKTsKKyAgICB9CisgICAgb2JqcyA9IDA7CisgIH0KKyAgZWxzZSBkZXRhaWwgPSB3aGF0OworCisgIC8vIHdpZSBhdWNoIGltbWVyIGhhYmVuIHdpciBqZXR6dCBlaW4gQmV6dWdzb2JqZWt0LgorICBpbnQgbWF4dHJpZXM9MzsKKyAgZG8geworICAgIGludCBiYXNlX3dhc19lbnY9MTsKKyAgICAvLyBhbHMgZXJzdGVuIHdlcmRlbiBpbiBGcmFnZSBrb21tZW5kZSBPYmpla3RlIGdlc3VjaHQuIFdlbm4gYmFzZQorICAgIC8vIGV4aXN0aWVydCAoaWRSIG51ciBpbSBlcnN0ZW4gRHVyY2hsYXVmKSwgd2lyZCBkb3J0IGdlc3VjaHQsIHNvbnN0IGluCisgICAgLy8gRW52IHVuZCBJbnYuCisgICAgaWYgKGJhc2UpCisgICAgeworICAgICAgaWYgIChiYXNlID09IHRoaXNfb2JqZWN0KCkgfHwgYmFzZSA9PSBlbnZpcm9ubWVudCgpIHx8CisgICAgICAgICAgKGJhc2UtPlF1ZXJ5UHJvcChQX1RSQU5TUEFSRU5UKSAmJiAhbGl2aW5nKGJhc2UpKSkKKyAgICAgIHsKKyAgICAgICAgLy8gaWNoIGthbm4gaW4gYmFzZSByZWluZ3Vja2VuLi4uCisgICAgICAgIG9ianMgPSBiYXNlLT5sb2NhdGVfb2JqZWN0cyhkZXRhaWwsIDEpIHx8ICh7fSk7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIC8vIFJlZmVyZW56b2JqZWt0IGRhLCBhYmVyIG5pY2h0IHJlaW5ndWNrYmFyLiBiYXNlIGFiZXIgbmljaHQgbnVsbGVuLAorICAgICAgICAvLyBkZW5uIGVzIGlzdCBqYSBub2NoIGd1ZWx0aWcgZnVlciBEZXRhaWxzdWNoZW4gYW4gYmFzZS4uLgorICAgICAgICBvYmpzID0gKHt9KTsKKyAgICAgIH0KKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgIG9ianMgPSBlbnZpcm9ubWVudCgpLT5sb2NhdGVfb2JqZWN0cyhkZXRhaWwsIDEpCisgICAgICAgICAgICsgbG9jYXRlX29iamVjdHMoZGV0YWlsLCAxKTsKKyAgICAgIGJhc2UgPSBlbnZpcm9ubWVudCgpOworICAgIH0KKyAgICBvYmpzID0gZmlsdGVyX29iamVjdHMob2JqcywgInNob3J0Iik7IC8vIG51ciBzaWNodGJhcmUuLi4KKworICAgIGlmIChzaXplb2Yob2JqcykpCisgICAgeworICAgICAgLy8gT2JqZWt0ZSBnZWZ1bmRlbiwgbWFsIHNjaGF1ZW4sIG9iIGRpZSB0YXVnZW4gKGQuaC4gZnVlciBkZW4gamV3LiBTaW5uCisgICAgICAvLyBJbmZvcyBoYWJlbi4gV2VubiBuaWNodCwgbXVlc3NlbiB3aXIgd2VpdGVyc3VjaGVuLgorICAgICAgLy8gQWJlciBlcnN0bWFsIGRpZSBPYmpla3RlIGR1cmNobGF1ZmVuLgorICAgICAgZm9yZWFjaChvYmplY3Qgb2I6IG9ianMpCisgICAgICB7CisgICAgICAgIGlmIChzZW5zZSA9PSBTRU5TRV9SRUFEKQorICAgICAgICB7CisgICAgICAgICAgLy8gRXh0cmF3dXJzdDogUF9SRUFEX01TRyBhdWNoIG5vY2ggYWJmcmFnZW4uCisgICAgICAgICAgb3V0ID0gb2ItPlF1ZXJ5UHJvcChQX1JFQURfTVNHKTsKKyAgICAgICAgICBpZiAoIXN0cmluZ3Aob3V0KSkKKyAgICAgICAgICAgIG91dCA9IG9iLT5HZXREZXRhaWwoU0VOU0VfREVGQVVMVCxRdWVyeVByb3AoUF9SRUFMX1JBQ0UpLFNFTlNFX1JFQUQpOworICAgICAgICB9CisgICAgICAgIGVsc2UgCisgICAgICAgICAgb3V0PW9iLT5HZXREZXRhaWwoU0VOU0VfREVGQVVMVCxRdWVyeVByb3AoUF9SRUFMX1JBQ0UpLHNlbnNlKTsKKyAgICAgICAgaWYgKHN0cmluZ3Aob3V0KSkKKyAgICAgICAgeworICAgICAgICAgIFNldFByb3AoUF9SRUZFUkVOQ0VfT0JKRUNULCBvYik7CisgICAgICAgICAgdGVsbF9vYmplY3QoTUUsIG91dCk7CisgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICB9CisKKyAgICAvLyBLZWluZSBPYmpla3RlIGdlZnVuZGVuLCBkaWUgaW4gRnJhZ2Uga29tbWVuLiBOYWNoIERldGFpbHMgc3VjaGVuLgorICAgIGlmKG91dCA9IGJhc2UtPkdldERldGFpbChkZXRhaWwsIFF1ZXJ5UHJvcChQX1JFQUxfUkFDRSksc2Vuc2UpKQorICAgIHsKKyAgICAgIFNldFByb3AoUF9SRUZFUkVOQ0VfT0JKRUNULCBiYXNlKTsKKyAgICAgIHJldHVybiAod3JpdGUob3V0KSwgMSk7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICAvLyBBdWNoIGtlaW5lIERldGFpbHMgZ2VmdW5kZW4uLi4gV2VubiB3aXIgdW5zIG5vY2ggZGFzIEVudiBhbmd1Y2tlbgorICAgICAgLy8ga29lbm5lbiAod2VpbCBiYXNlICE9IGVudiksIGRhbm4gbWFjaGVuIHdpciBkYXMsIGFuc29uc3RlbiBpc3QKKyAgICAgIC8vIGpldHp0IGhpZXIgbGVpZGVyIEVuZGUuLi4KKyAgICAgIGlmKGJhc2UgPT0gZW52aXJvbm1lbnQoKSkKKyAgICAgIHsKKyAgICAgICAgaWYgKGJhc2Vfd2FzX2VudikKKyAgICAgICAgICBTZXRQcm9wKFBfUkVGRVJFTkNFX09CSkVDVCwgMCk7CisgICAgICAgIHJldHVybiAwOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgeworICAgICAgICAvLyBub2NobWFsIGltIG5hZWNoc3RlbiBTY2hsZWlmZW5kdXJjaGxhdWYgb2huZSBiYXNlIHByb2JpZXJlbi4KKyAgICAgICAgYmFzZSA9IDA7CisgICAgICAgIGJhc2Vfd2FzX2VudiA9IDA7IAorICAgICAgfQorICAgIH0KKyAgfSB3aGlsZSgtLW1heHRyaWVzKTsKKworICAvLyBuYWNoIGRpZXNlciBTY2hsZWlmZSBzb2xsdGUgbWFuIG5pZSBhbmtvbW1lbi4uLgorICByYWlzZV9lcnJvcihzcHJpbnRmKCJfc2Vuc2VfZXhhKCk6IHp1dmllbGUgVmVyc3VjaGUsIGV0d2FzIHp1IGZpbmRlbi4iKSk7CisKKyAgcmV0dXJuIDA7Cit9CisKK3ZhcmFyZ3MgaW50IGxvb2tfaW50byhzdHJpbmcgc3RyLGludCBtb2RlKQoreworICBvYmplY3QgKmZvdW5kX29iczsKKworICBpZiggQ2Fubm90U2VlKCkgKSByZXR1cm4gMTsKKyAgX25vdGlmeV9mYWlsKCJXbyB3aWxsc3QgRHUgZGVubiByZWluc2NoYXVlbiA/XG4iKTsKKyAgZm91bmRfb2JzPWZpbmRfb2JzKHN0cixQVVRfR0VUX05PTkUpOworICBpZiAoIWZvdW5kX29icykKKyAgeworICAgIGlmIChlbnZpcm9ubWVudCgpICYmCisgICAgICAgIChlbnZpcm9ubWVudCgpLT5HZXREZXRhaWwoc3RyLFF1ZXJ5UHJvcChQX1JFQUxfUkFDRSkpfHwKKyAgICAgICAgIGVudmlyb25tZW50KCktPkdldERvb3JEZXNjKHN0cikpKQorICAgICAgX25vdGlmeV9mYWlsKCJEYSBrYW5uc3QgRHUgc28gbmljaHQgcmVpbnNlaGVuLlxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgcmV0dXJuIF9leGFtaW5lKHN0ciwgbW9kZSk7Cit9CisKKy8qIEdlYmUgZGllIFVtZ2VidW5nIGRlcyBha3RpdmVuIFNwaWVsZXJzIHp1cnVlY2ssIGxhc3NlIGRhYmVpICAqLworLyogcmVrdXJzaXYgZ2VzY2hhY2h0ZWx0ZSBSYWV1bWUgenUuICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCisvKiBXZW5uIGFsbG93X3Nob3J0IDAgaXN0LCBzbyB3aXJkIGltbWVyIGRpZSBsb25nLWRlc2NyIGJlbnV0enQgKi8KK3ZhcmFyZ3Mgc3RyaW5nIGVudl9kZXNjcihpbnQgYWxsb3dfc2hvcnQsaW50IGZsYWdzLCBpbnQgZm9yY2Vfc2hvcnQgKQoreworICBvYmplY3QgZW52OworICBpbnQgYnJpZWY7CisKKyAgZW52ID0gZW52aXJvbm1lbnQoTUUpOworCisgIGlmKCFlbnYpCisgICAgcmV0dXJuICJEdSBzY2h3ZWJzdCBpbSBOaWNodHMgLi4uIER1IHNpZWhzdCBuaWNodHMsIHJlaW4gZ2FyIG5pY2h0cyAuLi5cbiI7CisKKyAgaWYgKCFmb3JjZV9zaG9ydCAmJiAoIWFsbG93X3Nob3J0IHx8ICFRdWVyeVByb3AoUF9CUklFRikpKQorICAgICAgcmV0dXJuIGVudi0+aW50X2xvbmcoTUUsTUUsZmxhZ3MpOworCisgIGlmICghZmxhZ3MgJiYgKChicmllZj1RdWVyeVByb3AoUF9CUklFRikpPj0yKSkKKyAgICAgIHJldHVybiAiIjsKKworICByZXR1cm4gZW52LT5pbnRfc2hvcnQoTUUsTUUpOworfQorCitpbnQgX2xvb2soc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nIHM7CisgIGludCBmbGFnOworCisgIGlmKENhbm5vdFNlZSgpKSByZXR1cm4gMTsKKworICBpZighc3RyKQorICB7CisgICAgU2V0UHJvcChQX1JFRkVSRU5DRV9PQkpFQ1QsIDApOworICAgIHdyaXRlKCBlbnZfZGVzY3IoKSApOworICAgIHJldHVybiAxOworICB9CisgIGlmKHN0cj09Ii1mIiB8fCBzdHI9PSJnZW5hdSIpCisgIHsKKyAgICBTZXRQcm9wKFBfUkVGRVJFTkNFX09CSkVDVCwgMCk7CisgICAgd3JpdGUoIGVudl9kZXNjcigwLDIpICk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYoc3RyPT0iLWsiIHx8IHN0cj09Imt1cnoiKQorICB7CisgICAgU2V0UHJvcChQX1JFRkVSRU5DRV9PQkpFQ1QsIDApOworICAgIHdyaXRlKCBlbnZfZGVzY3IoMSwyLDEpICk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYoc3RyWzAuLjJdPT0iLWYgIil7CisgICAgZmxhZz0yOworICAgIHN0cj1zdHJbMy4uXTsKKyAgfQorICBlbHNlIGlmKHN0clswLi41XT09ImdlbmF1ICIpeworICAgIGZsYWc9MjsKKyAgICBzdHI9c3RyWzYuLl07CisgIH0KKyAgZWxzZSBmbGFnID0gMDsKKyAgaWYgKHNzY2FuZihzdHIsIiVzIGFuIixzKSkgc3RyPXM7CisgIGlmIChzc2NhbmYoc3RyLCIlcyBpbiBtaXIiLHMpfHxzc2NhbmYoc3RyLCIlcyBpbiBkaXIiLHMpKSByZXR1cm4gX2V4YW1pbmUoc3RyLGZsYWcpOworICBpZiAoc3NjYW5mKHN0ciwiaW4gJXMiLHMpKSByZXR1cm4gbG9va19pbnRvKHMsZmxhZyk7CisgIHJldHVybiBfZXhhbWluZShzdHIsZmxhZyk7Cit9CisKK2ludCBfZXF1aXBtZW50KHN0cmluZyBhcmcpCit7CisgIGlmIChDYW5ub3RTZWUoKSkgcmV0dXJuIDE7CisgIGNhbGxfb3RoZXIoIi9zdGQvcGxheWVyL2ludm1hc3Rlci9pbnZtYXN0ZXIiLCAiU2hvd0ludiIsIE1FLCBhcmcpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIG1peGVkIF9xdWVyeV9sb2NhbGNtZHMoKQoreworICByZXR1cm4KKyAgICAoeyh7ImF1c3J1ZXN0dW5nIiwgIl9lcXVpcG1lbnQiLDAsMH0pLAorICAgICAgKHsiaSIsIl9pbnZlbnRvcnkiLDAsMH0pLAorICAgICAgKHsiaW52IiwiX2ludmVudG9yeSIsMCwwfSksCisgICAgICAoeyJpbnZlbnR1ciIsIl9pbnZlbnRvcnkiLDAsMH0pLAorICAgICAgKHsic2NoYXUiLCJfbG9vayIsMCwwfSksCisgICAgICAoeyJzY2hhdWUiLCJfbG9vayIsMCwwfSksCisgICAgICAoeyJ1bnQiLCJfZXhhbWluZSIsMCwwfSksCisgICAgICAoeyJ1bnRlcnN1Y2giLCJfZXhhbWluZSIsMCwwfSksCisgICAgICAoeyJiZXRyYWNodCIsIl9leGFtaW5lIiwwLDB9KSwKKyAgICAgICh7InVudGVyc3VjaGUiLCJfZXhhbWluZSIsMCwwfSksCisgICAgICAoeyJiZXRyYWNodGUiLCJfZXhhbWluZSIsMCwwfSksCisgICAgICAoeyJiZXRyIiwiX2V4YW1pbmUiLDAsMH0pLAorICAgICAgKHsibGF1c2NoZSIsIl9zZW5zZV9leGEiLDAsMH0pLAorICAgICAgKHsibGF1c2NoIiwiX3NlbnNlX2V4YSIsMCwwfSksCisgICAgICAoeyJob2VyIiwiX3NlbnNlX2V4YSIsMCwwfSksCisgICAgICAoeyJob2VyZSIsIl9zZW5zZV9leGEiLDAsMH0pLAorICAgICAgKHsibGllcyIsIl9zZW5zZV9leGEiLDAsMH0pLAorICAgICAgKHsibGVzZSIsIl9zZW5zZV9leGEiLDAsMH0pLAorICAgICAgKHsibGVzIiwiX3NlbnNlX2V4YSIsMCwwfSksCisgICAgICAoeyJzY2hudXBwZXIiLCJfc2Vuc2VfZXhhIiwwLDB9KSwKKyAgICAgICh7InNjaG51cHBlcmUiLCJfc2Vuc2VfZXhhIiwwLDB9KSwKKyAgICAgICh7InJpZWNoIiwiX3NlbnNlX2V4YSIsMCwwfSksCisgICAgICAoeyJyaWVjaGUiLCJfc2Vuc2VfZXhhIiwwLDB9KSwKKyAgICAgICh7InRhc3RlIiwiX3NlbnNlX2V4YSIsMCwwfSksCisgICAgICAoeyJiZXJ1ZWhyZSIsIl9zZW5zZV9leGEiLDAsMH0pLAorICAgICAgKHsiYmVydWVociIsIl9zZW5zZV9leGEiLDAsMH0pLAorICAgICAgKHsia3VyeiIsIl90b2dnbGVfYnJpZWYiLDAsMH0pLAorICAgICAgKHsibGFuZyIsIl90b2dnbGVfYnJpZWYiLDAsMH0pLAorICAgICAgKHsidWx0cmFrdXJ6IiwiX3RvZ2dsZV9icmllZiIsMCwwfSkgCisgICAgfSk7Cit9CmRpZmYgLS1naXQgYS9zdGQvcG9zdC5jIGIvc3RkL3Bvc3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMGRiYmIxCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Bvc3QuYwpAQCAtMCwwICsxLDQyIEBACisvKiBOZXVlIHN0ZC9wb3N0CisgICAoQykgMTk5MyBieSBMb2NvCisqLworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL3Jvb20iOworCisjaW5jbHVkZSAiL21haWwvcG9zdC5oIgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxyb29tcy5oPgorCit2b2lkIGNyZWF0ZSgpIHsKKyAgaW50IGk7CisgICg6OmNyZWF0ZSgpKTsKKyAgU2V0UHJvcChQX0lOVF9TSE9SVCwiUG9zdGFtdCIpOworICBTZXRQcm9wKFBfSU5UX0xPTkcsIlwKK0RpZXMgaXN0IGVpbiBUZXN0cG9zdGFtdC5cblwKK1ZvbiBoaWVyIGF1cyBrYW5uc3QgRHUgQnJpZWZlIGFuIERlaW5lIE1pdHNwaWVsZXIgc2NoaWNrZW4gdW5kIEJyaWVmZSB2b25cblwKK2lobmVuIGxlc2VuLiBXZW5uIER1IGRhcyB3aWxsc3QsIHRpcHBlICdwb3N0JyBvZGVyICdtYWlsJyxcblwKK2J6dy4gJ21haWwgPHNwaWVsZXI+Jy5cbiIpOworICBTZXRQcm9wKCBQX0xJR0hULCAxICk7CisgIEFkZENtZCgicG9zdCIsImRvX21haWwiKTsKKyAgQWRkQ21kKCJtYWlsIiwiZG9fbWFpbCIpOworICBTZXRQcm9wKFBfSU5ET09SUywxKTsKKyAgICBmb3IgKGk9MDtpPE5SQ0FCSU5TOysraSkgQWRkSXRlbShNQUlMQ0FCSU4sUkVGUkVTSF9SRU1PVkUpOworICAgIEFkZEl0ZW0oQ09VTlRFUixSRUZSRVNIX1JFTU9WRSk7Cit9CisKK2ludCBkb19tYWlsKHN0cmluZyBzdHIpIHsKKyAgb2JqZWN0IG1haWxlcjsKKyAgaWYgKHRoaXNfaW50ZXJhY3RpdmUoKSE9dGhpc19wbGF5ZXIoKSkgcmV0dXJuIDA7CisgIG1haWxlcj1jbG9uZV9vYmplY3QoTUFJTEVSKTsKKyAgbWFpbGVyLT5TZXRPZmZpY2VOYW1lKHNob3J0KCkpOworICBtYWlsZXItPmRvX21haWwoc3RyKTsKKyAgcmV0dXJuIDE7Cit9CisKKwpkaWZmIC0tZ2l0IGEvc3RkL3ByZWxvYWRfZmlsZSBiL3N0ZC9wcmVsb2FkX2ZpbGUKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTcxN2ZjYQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9wcmVsb2FkX2ZpbGUKQEAgLTAsMCArMSwzNiBAQAorL3NlY3VyZS9lcnJvcmQKKy9zZWN1cmUvbWF0ZXJpYWxkYgorL3AvZGFlbW9uL2V2ZW50ZAorL3AvZGFlbW9uL2NoYW5uZWxkCisvcm9vbS92b2lkCisvc3RkL3NoZWxscy9tYWdpZXIKKy9wL2RhZW1vbi9yb3V0aW5nZAorL3AvZGFlbW9uL3Nhc3RhdGQKKy9zdGQvc2hlbGxzL2VsZgorL3N0ZC9zaGVsbHMvaHVtYW4KKy9zdGQvc2hlbGxzL2R3YXJmCisvc3RkL3NoZWxscy9ob2JiaXQKKy9zdGQvc2hlbGxzL2ZlbGluZQorL3NlY3VyZS9sb2dpbgorL3NlY3VyZS9tYWlsZXIKKy9zZWN1cmUvY29tYmF0Cisvb2JqL3VocgorL29iai9tbGlzdGUKKy9zZWN1cmUvc2NvcmVtYXN0ZXIKKy9zZWN1cmUvZXhwbG9yYXRpb25tYXN0ZXIKKy9zZWN1cmUvcXVlc3RtYXN0ZXIKKy9zZWN1cmUvbGVwbWFzdGVyCisvc2VjdXJlL3BvdGlvbm1hc3RlcgorL2l0ZW1zL21vbmV5Cisvb2JqL3Rvb2xzL3h0b29sCisvb2JqL3Rvb2xzL2x1cGUKKy9zZWN1cmUvdWRwX21haWwKKy9zZWN1cmUvaW5ldGQKKy9zZWN1cmUvYXdtYXN0ZXIKKy9wL2RhZW1vbi90cmF2ZWxkCisvcC9kYWVtb24vbWFuZAorL3AvZGFlbW9uL3N2bjJuZXdzCisvcC9kYWVtb24vbW9uZXlsb2cKKy9wL2RhZW1vbi91cHRpbWVfbWFzdGVyCisvcGxheWVycy90aWFtYWsvd29ya3Jvb20KKy9zZWN1cmUvendlaXRpZXMKZGlmZiAtLWdpdCBhL3N0ZC9wdWIuYyBiL3N0ZC9wdWIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41M2IwMTlhCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3B1Yi5jCkBAIC0wLDAgKzEsNzUgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBwdWIuYyAtLSBBbGxlcywgd2FzIGVpbmUgS25laXBlIGJyYXVjaHQuCisvLworLy8gJElkOiBwdWIuYyA2NTcxIDIwMDctMTAtMjEgMTQ6NDE6MTBaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL3Jvb20iOworaW5oZXJpdCAiL3N0ZC9yb29tL3B1YiI7CisKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIHJvb206OmNyZWF0ZSgpOworICBwdWI6OmNyZWF0ZSgpOworICBTZXRQcm9wKFBfTElHSFQsMSk7CisgIFNldFByb3AoUF9JTkRPT1JTLDEpOworICBTZXRQcm9wKFBfSU5UX0xPTkcsCisgICAiRGVyIE1hZ2llciwgZGVyIGRpZXNlbiBQdWIgZXJzY2h1Ziwgd2FyIGxlaWRlciB6dSBmYXVsLCBlaW5lICIrCisgICAiQmVzY2hyZWlidW5nXG5kYWZ1ZXIgaGVyenVzdGVsbGVuLlxuIik7CisgIFNldFByb3AoUF9JTlRfU0hPUlQsImdlbmVyaWMgcHViIik7CisgIEFkZEl0ZW0oIi9vYmovdG9wbGlzdGUiLFJFRlJFU0hfUkVNT1ZFKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICAgICAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCit2b2lkIHJlc2V0KCkKK3sKKyAgIHJvb206OnJlc2V0KCk7CisgICBwdWI6OnJlc2V0KCk7Cit9CisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKKworCisKZGlmZiAtLWdpdCBhL3N0ZC9yYW5nZWRfd2VhcG9uLmMgYi9zdGQvcmFuZ2VkX3dlYXBvbi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU1Nzg0ODMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcmFuZ2VkX3dlYXBvbi5jCkBAIC0wLDAgKzEsMjc1IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcmFuZ2VkX3dlYXBvbi5jIC0tIFN0YW5kYXJkb2JqZWt0IGZ1ZXIgRmVybmthbXBmd2FmZmVuCisvLworLy8gJElkOiByYW5nZWRfd2VhcG9uLmMgODgyMCAyMDE0LTA1LTE0IDE5OjMxOjQ2WiBaZXNzdHJhICQKKworLy8gR2VicmF1Y2h0IHdpcmQgTXVuaXRpb24gbWl0IGVpbmVyIE1VTl8qIGlkLiBEaWVzZXMgT2JqZWt0IHNvbGx0ZSBhdXNzZXJkZW0KKy8vIFBfREFNX1RZUEUgc2V0emVuIHNvd2llIFBfU0hPT1RJTkdfV0MgdW5kIGdnZi4gUF9ISVRfRlVOQy4gSW4gZGVyIFJlZ2VsCisvLyBzb2xsdGVuIGRpZXNlIE9iamVrdGUgdW5pdHMgc2VpbiwgZGEgZ3JvZXNzZXJlIEFuemFobGVuIGRhdm9uIGdlYnJhdWNodAorLy8gd2VyZGVuLgorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCitpbmhlcml0ICIvc3RkL2xpdmluZy9za2lsbF91dGlscyI7Citpbmhlcml0ICIvc3RkL3dlYXBvbiI7CisKKyNpbmNsdWRlIDxyYW5nZWRfd2VhcG9uLmg+CisKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDx1bml0Lmg+CisKK3N0YXRpYyBpbnQgbGFzdF9zaG9vdDsKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgICA6OmNyZWF0ZSgpOworCisgICAgU2V0UHJvcChQX1dFQVBPTl9UWVBFLCBXVF9SQU5HRURfV0VBUE9OKTsKKyAgICBTZXRQcm9wKFBfU1RSRVRDSF9USU1FLCAxKTsKKyAgICBTZXRQcm9wKFBfQU1NVU5JVElPTiwgTVVOX0FSUk9XKTsKKyAgICBTZXRQcm9wKFBfU0hPT1RJTkdfV0MsIDcwKTsKKyAgICBTZXRQcm9wKFBfUkFOR0UsIDUwKTsKKyAgICBTZXRQcm9wKFBfSU5GTywgIlN5bnRheDogc2NoaWVzc2UgV0FTIGF1ZiBXRU4/XG4iKTsKKyAgICAvLyBmdWVyIGRlbiBGYWxsLCBkYXMgbWFuIGRlbiBCb2dlbiBhbHMgS251ZXBwZWwgbnV0enQuLi4KKyAgICBTZXRQcm9wKFBfV0MsIDMwKTsKKyAgICBTZXRQcm9wKFBfUVVBTElUWSwgMTAwKTsKKworICAgIEFkZENtZCggKHsic2NoaWVzcyIsICJzY2hpZXNzZSJ9KSwgImNtZF9zaG9vdCIpOworfQorICAgICAgCitzdGF0aWMgaW50IHNob290X2RhbShtYXBwaW5nIHNob290KQorLy8gYXVzZ2VnbGllZGVydCwgZGFtaXQgbWFuIGRpZXNlIEZ1bmt0aW9uIGdnZi4gdWViZXJzY2hyZWliZW4ga2Fubi4KK3sgICBtaXhlZCAgIHJlczsKKyAgICBvYmplY3QgIGhpdGZ1bmM7CisgICAgY2xvc3VyZSB1c2s7CisKKyAgICAvLyBkaWVzc2VsYmUgRm9ybWVsIHdpZSBiZWkgTmFoa2FtcGZ3YWZmZW4sIG51ciBkYXMgaGllciBERVggYW5zdGF0dCBTVFIKKyAgICAvLyBiZW51dHp0IHdpcmQsIHVuZCBkaWUgV0MgZGVyIE11bml0aW9uIG5vY2ggYWRkaWVydCB3aXJkCisgICAgc2hvb3RbU0lfU0tJTExEQU1BR0VdID0gcmFuZG9tKDErKCAyKihzaG9vdFtQX1dDXStzaG9vdFtQX1NIT09USU5HX1dDXSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIDEwKlBMLT5RdWVyeUF0dHJpYnV0ZShBX0RFWCkgKS8zKTsKKyAgICAvLyBIaXRGdW5jIGRlciBNdW5pdGlvbiBhZGRpZXJlbgorICAgIGlmICggb2JqZWN0cChoaXRmdW5jPShzaG9vdFtQX0FNTVVOSVRJT05dLT5RdWVyeVByb3AoUF9ISVRfRlVOQykpKSApCisgICAgICBzaG9vdFtTSV9TS0lMTERBTUFHRV0gKz0gKGhpdGZ1bmMtPkhpdEZ1bmMoc2hvb3RbU0lfRU5FTVldKSk7CisKKyAgICB1c2s9c3ltYm9sX2Z1bmN0aW9uKCJVc2VTa2lsbCIsUEwpOworCisgICAgLy8gU2NodXNzLVNraWxsIGRlciBHaWxkZSBmdWVyIGRpZXNlbiBNdW5pdGlvbnN0eXAgYW53ZW5kZW4KKyAgICBpZiAoIG1hcHBpbmdwKHJlcz1mdW5jYWxsKHVzayxTSE9PVChzaG9vdFtQX1dFQVBPTl9UWVBFXSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWVwX2NvcHkoc2hvb3QpKSkgKQorICAgICAgU2tpbGxSZXNUcmFuc2ZlcihyZXMsICZzaG9vdCk7CisKKyAgICAvLyBBbGxnZW1laW5lbiBTY2h1c3MtU2tpbGwgZGVyIEdpbGRlIGFud2VuZGVuCisgICAgaWYgKCBtYXBwaW5ncChyZXM9ZnVuY2FsbCh1c2ssU0tfU0hPT1QsZGVlcF9jb3B5KHNob290KSkpICkKKyAgICAgIFNraWxsUmVzVHJhbnNmZXIocmVzLCAmc2hvb3QpOworCisgICAgcmV0dXJuIHNob290W1NJX1NLSUxMREFNQUdFXTsKK30KKworc3RhdGljIHN0cmluZyBGaW5kUmFuZ2VkVGFyZ2V0KHN0cmluZyBzdHIsIG1hcHBpbmcgc2hvb3QpCit7ICAgc3RyaW5nIHdlbjsKKyAgICBtaXhlZCAgYXJlYTsKKyAgICBpbnQgICAgcHNyOworCisgICAgaWYgKCBzc2NhbmYoc3RyLCAiJXMgYXVmICVzIiwgc3RyLCB3ZW4pIT0yICkKKyAgICB7CisgICAgICAgIHNob290W1NJX0VORU1ZXT1QTC0+U2VsZWN0RmFyRW5lbXkoUEwtPlByZXNlbnRFbmVtaWVzKCksMSw0KTsKKyAgICAgICAgc3RyID0gc2hvb3RbUF9XRUFQT05fVFlQRV07CisgICAgfQorICAgIGVsc2UgaWYgKCBvYmplY3RwKHNob290W1NJX0VORU1ZXT1wcmVzZW50KHdlbiwgZW52aXJvbm1lbnQoUEwpKSkgKQorICAgIHsKKyAgICAgICAgcmV0dXJuIHN0cjsKKyAgICB9CisgICAgZWxzZSBpZiAoICggKGFyZWE9KGVudmlyb25tZW50KFBMKS0+UXVlcnlQcm9wKFBfVEFSR0VUX0FSRUEpKSkKKyAgICAgICAgICAgICAgIHx8IChhcmVhPWVudmlyb25tZW50KGVudmlyb25tZW50KFBMKSkpICkKKyAgICAgICAgICAgICAmJiAoIG9iamVjdHAoYXJlYSkKKyAgICAgICAgICAgICAgICAgfHwgKCBzdHJpbmdwKGFyZWEpCisgICAgICAgICAgICAgICAgICAgICAmJiBvYmplY3RwKGFyZWE9ZmluZF9vYmplY3QoYXJlYSkpICkgKQorICAgICAgICAgICAgICYmIChwc3I9ZW52aXJvbm1lbnQoUEwpLT5RdWVyeVByb3AoUF9TSE9PVElOR19BUkVBKSkgKQorICAgIHsKKyAgICAgICAgc2hvb3RbU0lfRU5FTVldPXByZXNlbnQod2VuLCBhcmVhKTsKKyAgICAgICAgaWYgKCBzaG9vdFtTSV9FTkVNWV0gJiYgKHBzcj5RdWVyeVByb3AoUF9SQU5HRSkpICkKKyAgICAgICAgeworICAgICAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKChzaG9vdFtTSV9FTkVNWV0tPk5hbWUoV0VSKSkrCisgICAgICAgICAgICAgICAgIiBpc3QgbGVpZGVyIGF1c3NlcmhhbGIgZGVyIFJlaWNod2VpdGUgIituYW1lKFdFU1NFTiwgMSkrIi4iLAorICAgICAgICAgICAgICAgNzgpKTsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgfSAgICAgICAgCisgICAgfQorCisgICAgaWYgKCAhc2hvb3RbU0lfRU5FTVldICkKKyAgICB7CisgICAgICAgIHdyaXRlKCJFcyBpc3Qga2VpbiBGZWluZCB2b3JoYW5kZW4gYXVmIGRlbiBEdSBzY2hpZXNzZW4ga29lbm50ZXN0LlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHJldHVybiBzdHI7Cit9CisKK3N0YXRpYyBpbnQgY21kX3Nob290KHN0cmluZyBzdHIpCit7ICAgaW50ICAgIGRhbTsKKyAgICBzdHJpbmcgbm9fYXQ7CisgICAgb2JqZWN0IHF1aXZlcjsKKyAgICBtYXBwaW5nIHNob290OworCisgICAgaWYgKCBQTC0+UXVlcnlQcm9wKFBfR0hPU1QpICkKKyAgICB7CisgICAgICAgIHdyaXRlKCJEZWluZSBpbW1hdGVyaWVsbGVuIEZpbmdlciBnbGVpdGVuIGR1cmNoIGRpZSBXYWZmZSBoaW5kdXJjaC5cbiIpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAKKyAgICBpZiAoICFRdWVyeVByb3AoUF9OT0dFVCkgKQorICAgIHsKKyAgICAgICAgLy8gS2F0YXB1bHRlIG9kZXIgYWVobmxpY2hlcyBkaWUgdm9uIE1hZ2llcm4gYXVmZ2VzdGVsbHQgd2VyZGVuCisgICAgICAgIC8vIG11ZXNzZW4gbmF0dWVybGljaCBuaWNodCBnZXp1ZWNrdCB3ZXJkZW4gOikuCisgICAgICAgIGlmICggIVF1ZXJ5UHJvcChQX1dJRUxERUQpICkKKyAgICAgICAgeworICAgICAgICAgICAgbm90aWZ5X2ZhaWwoYnJlYWtfc3RyaW5nKCJEdSBzb2xsdGVzdCAiK25hbWUoV0VOLCAxKSsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGRhenUgc2Nob24genVlY2tlbi4iLCA3OCkpOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICBpZiAoIChQTC0+SW5GaWdodCgpKSAmJiAoKFBMLT5QcmVzZW50UG9zaXRpb24oKSk8MikgKQorICAgICAgICB7CisgICAgICAgICAgICB3cml0ZShicmVha19zdHJpbmcoCisgICAgICAgICAgICAgICAgIkR1IHNvbGx0ZXN0IERpY2ggZXJzdCBldHdhcyB3ZWl0ZXIgenVydWVja3ppZWhlbiwgdW0gbWl0ICIrCisgICAgICAgICAgICAgICAgbmFtZShXRU0sIDEpKyIgc2NoaWVzc2VuIHp1IGtvZW5uZW4hIiwgNzgpKTsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKCAoIChRdWVyeVByb3AoUF9FUVVJUF9USU1FKStRdWVyeVByb3AoUF9TVFJFVENIX1RJTUUpKjIpID4gdGltZSgpICkKKyAgICAgICAgfHwgKCAobGFzdF9zaG9vdCtRdWVyeVByb3AoUF9TVFJFVENIX1RJTUUpKSA+IGFic29sdXRlX2hiX2NvdW50KCkgKSApCisgICAgeworICAgICAgICB3cml0ZShicmVha19zdHJpbmcoIkR1IGthbm5zdCBtaXQgIituYW1lKFdFTSwgMSkrCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiIG5vY2ggbmljaHQgd2llZGVyIHNjaGllc3Nlbi4iLCA3OCkpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICBpZiAoIChQTC0+UXVlcnlQcm9wKFBfRElTQUJMRV9BVFRBQ0spKT4wICkKKyAgICB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygiU29sYW5nZSBEdSBub2NoIGdlbGFlaG10IGJpc3QsIGthbm5zdCBEdSAiKworICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZShXRU4sIDEpKyIgbmljaHQgYmVudXR6ZW4hIiwgNzgpKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgaWYgKCBQTC0+UXVlcnlQcm9wKFBfQVRUQUNLX0JVU1kpICkKKyAgICB7CisgICAgICAgIHdyaXRlKCJOaWNodCBzbyBoZWt0aXNjaCEgU28gc2NobmVsbCBiaXN0IER1IG5pY2h0LlxuIik7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIC8vIFBfQVRUQUNLX0JVU1kgbmF0dWVybGljaCBhdWNoIHNldHplbi4uLgorICAgIFBMLT5TZXRQcm9wKFBfQVRUQUNLX0JVU1ksMSk7CisKKyAgICAvLyBJbmZvLU1hcHBpbmcgZXJ6ZXVnZW4KKyAgICBzaG9vdCA9IChbIFBfV0VBUE9OICAgICAgIDogTUUsCisgICAgICAgICAgICAgICBQX1dFQVBPTl9UWVBFICA6IFF1ZXJ5UHJvcChQX0FNTVVOSVRJT04pLAorICAgICAgICAgICAgICAgUF9TVFJFVENIX1RJTUUgOiBRdWVyeVByb3AoUF9TVFJFVENIX1RJTUUpLAorICAgICAgICAgICAgICAgUF9XQyAgICAgICAgICAgOiBRdWVyeVByb3AoUF9TSE9PVElOR19XQyksCisgICAgICAgICAgICAgICBTSV9TUEVMTCAgICAgICA6IDAKKyAgICAgICAgICAgIF0pOworCisgICAgaWYgKCAhc3RyaW5ncChzdHIpIHx8IHN0cj09IiIgKQorICAgICAgc3RyPXNob290W1BfV0VBUE9OX1RZUEVdOworICAgIGVsc2UgaWYgKHN0clswLi4zXT09Im1pdCAiKQorICAgICAgc3RyPXN0cls0Li5dOworICAgIGVsc2UgaWYgKHN0clswLi4zXT09ImF1ZiAiKQorICAgICAgc3RyPXNob290W1BfV0VBUE9OX1RZUEVdKyIgIitzdHI7CisKKyAgICBpZiAoICEoc3RyPUZpbmRSYW5nZWRUYXJnZXQoc3RyLHNob290KSkgKQorICAgICAgcmV0dXJuIDE7CisKKyAgICBpZiAoIHNob290W1NJX0VORU1ZXS0+UXVlcnlQcm9wKFBfR0hPU1QpICkKKyAgICB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygiQWJlciAiKyhzaG9vdFtTSV9FTkVNWV0tPm5hbWUoV0VSLCAxKSkrCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGlzdCBkb2NoIGVpbiBHZWlzdCEiLCA3OCkpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgZWxzZSBpZiAoIG5vX2F0PShzaG9vdFtTSV9FTkVNWV0tPlF1ZXJ5UHJvcChQX05PX0FUVEFDSykpICkKKyAgICB7CisgICAgICAgIGlmICggc3RyaW5ncChub19hdCkgKQorICAgICAgICAgIHdyaXRlKG5vX2F0KTsKKyAgICAgICAgZWxzZQorICAgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygiRHUga2FubnN0ICIrKHNob290W1NJX0VORU1ZXS0+bmFtZShXRU4sIDEpKSsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBuaWNodCBhbmdyZWlmZW4uIiwgNzgpKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIGVsc2UgaWYgKCBzaG9vdFtTSV9FTkVNWV09PVBMICkKKyAgICB7CisgICAgICAgIHdyaXRlKCJEdSBrYW5uc3QgZG9jaCBuaWNodCBhdWYgRGljaCBzZWxic3Qgc2NoaWVzc2VuIVxuIik7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIGlmICggIShzaG9vdFtQX0FNTVVOSVRJT05dPXByZXNlbnQoc3RyLCBQTCkpCisgICAgICAgICYmICggIW9iamVjdHAocXVpdmVyPVBMLT5RdWVyeUFybW91ckJ5VHlwZShBVF9RVUlWRVIpKQorICAgICAgICAgICAgfHwgIShzaG9vdFtQX0FNTVVOSVRJT05dPXByZXNlbnQoc3RyLCBxdWl2ZXIpKSApICkKKyAgICB7CisgICAgICAgIGlmICggc3RyPT1zaG9vdFtQX1dFQVBPTl9UWVBFXSApCisgICAgICAgICAgICB3cml0ZShicmVha19zdHJpbmcoIkR1IGhhc3Qga2VpbmUgcGFzc2VuZGUgTXVuaXRpb24gYmVpIERpciwgdW0gIisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWl0ICIrbmFtZShXRU0sIDEpKyIgc2NoaWVzc2VuIHp1IGtvZW5uZW4uIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA3OCkpOworICAgICAgICBlbHNlCisgICAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJEdSBoYXN0IGtlaW4gJyIrc3RyKyInIGJlaSBEaXIuIiwgNzgpKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgaWYgKCAhc2hvb3RbUF9BTU1VTklUSU9OXS0+aWQoc2hvb3RbUF9XRUFQT05fVFlQRV0pICkKKyAgICB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygoc2hvb3RbUF9BTU1VTklUSU9OXS0+TmFtZShXRVIpKSsiIGthbm5zdCBEdSBtaXQgIisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUoV0VNLCAxKSsiIG5pY2h0IHZlcnNjaGllc3Nlbi4iLCA3OCkpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICBzaG9vdFtQX0FNTVVOSVRJT05dLT5TZXRQcm9wKFVfUkVRLCAxKTsKKworICAgIHNob290W1NJX1NLSUxMREFNQUdFX01TR10gID0gc2hvb3RbU0lfU0tJTExEQU1BR0VfTVNHMl0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA9IHNob290W1BfQU1NVU5JVElPTl0tPm5hbWUoV0VOKTsKKyAgICBzaG9vdFtTSV9TS0lMTERBTUFHRV9UWVBFXSA9ICggc2hvb3RbUF9BTU1VTklUSU9OXS0+UXVlcnlQcm9wKFBfREFNX1RZUEUpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfHwgKHtEVF9QSUVSQ0V9KSApOworCisgICAgc2hvb3RbUF9TSE9PVElOR19XQ10gID0gc2hvb3RbUF9BTU1VTklUSU9OXS0+UXVlcnlQcm9wKFBfU0hPT1RJTkdfV0MpOworCisgICAgZGFtPXNob290X2RhbShzaG9vdCk7CisKKyAgICAvLyBUZXh0YXVzZ2FiZQorICAgIGlmIChzaG9vdFtTSV9FTkVNWV0pCisgICAgeworICAgICAgdGVsbF9vYmplY3QoUEwsYnJlYWtfc3RyaW5nKAorICAgICAgICAgICJEdSBzY2hpZXNzdCAiK3Nob290W1NJX1NLSUxMREFNQUdFX01TR10rIiBhdWYgIisKKyAgICAgICAgICBzaG9vdFtTSV9FTkVNWV0tPm5hbWUoV0VOLCAxKSsiLiIsIDc4KSApOworICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KFBMKSwgYnJlYWtfc3RyaW5nKAorICAgICAgICAgIFBMLT5OYW1lKFdFUikrIiBzY2hpZXNzdCAiK3Nob290W1NJX1NLSUxMREFNQUdFX01TRzJdKyIgYXVmICIrCisgICAgICAgICAgc2hvb3RbU0lfRU5FTVldLT5uYW1lKFdFTiwgMSkrIi4iLCA3OCksCisgICAgICAgICAgKHsgc2hvb3RbU0lfRU5FTVldLCBQTCB9KSApOworICAgICAgaWYgKCBlbnZpcm9ubWVudChQTCkhPWVudmlyb25tZW50KHNob290W1NJX0VORU1ZXSkgKQorICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoc2hvb3RbU0lfRU5FTVldKSxicmVha19zdHJpbmcoCisgICAgICAgICAgICBQTC0+TmFtZShXRVIpKyIgc2NoaWVzc3QgIitzaG9vdFtTSV9TS0lMTERBTUFHRV9NU0cyXSsiIGF1ZiAiKworICAgICAgICAgICAgc2hvb3RbU0lfRU5FTVldLT5uYW1lKFdFTiwgMSkrIi4iLCA3OCksCisgICAgICAgICAgICAoeyBzaG9vdFtTSV9FTkVNWV0gfSkgKTsKKyAgICAgIHRlbGxfb2JqZWN0KHNob290W1NJX0VORU1ZXSwgYnJlYWtfc3RyaW5nKAorICAgICAgICAgIFBMLT5OYW1lKFdFUikrIiBzY2hpZXNzdCAiK3Nob290W1NJX1NLSUxMREFNQUdFX01TRzJdKworICAgICAgICAgICIgYXVmIERpY2ggYWIuIiw3OCkgKTsKKworICAgICAgc2hvb3RbU0lfRU5FTVldLT5EZWZlbmQoZGFtLHNob290W1NJX1NLSUxMREFNQUdFX1RZUEVdLHNob290W1NJX1NQRUxMXSxQTCk7CisgICAgfQorICAgIC8vIE11bml0aW9uIHZlcmJyYXVjaGVuCisgICAgaWYgKCBzaG9vdFtQX0FNTVVOSVRJT05dLT5Jc1VuaXQoKSApCisgICAgICBzaG9vdFtQX0FNTVVOSVRJT05dLT5BZGRBbW91bnQoLTEpOworICAgIGVsc2UKKyAgICAgIHNob290W1BfQU1NVU5JVElPTl0tPnJlbW92ZSgpOworCisgICAgLy8gZXMgd2lyZCBhbiBkaWVzZXIgc3RlbGxlIGFic29sdXRlX2hiX2NvdW50IGFuc3RlbGxlIHZvbiB0aW1lKCkgYmVudXR6dAorICAgIC8vIHVtIGRlbSBTcGllbGVyIHdpcmtsaWNoIGRpZSB2b2xsZW4gMiBzZWsgWmVpdCB6dSBnZWJlbiB1bSB6dSByZWFnaWVyZW4KKyAgICAvLyBvaG5lIGRhcyBlciBkYWR1cmNoIGVpbmVuIFNjaGFkZW4gaGF0ICh3aWUgZXIgZXMgei5iLiBiZWkgdGltZSgpIGhhZXR0ZSkKKyAgICBsYXN0X3Nob290PWFic29sdXRlX2hiX2NvdW50KCk7CisKKyAgICByZXR1cm4gMTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3Jlc3RyaWN0aW9uX2NoZWNrZXIuYyBiL3N0ZC9yZXN0cmljdGlvbl9jaGVja2VyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjJkNDI0OAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9yZXN0cmljdGlvbl9jaGVja2VyLmMKQEAgLTAsMCArMSwzMjMgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyByZXN0cmljdGlvbl9jaGVja2VyLmMgLS0gQmVzY2hyYWVua3VuZ2VuIGluIEdpbGRlbiwgU3BlbGxzIHVuZCBTa2lsbHMKKy8vCisvLyAkSWQ6IHJlc3RyaWN0aW9uX2NoZWNrZXIuYyA4NzU0IDIwMTQtMDQtMjYgMTM6MTI6NThaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworLy8jcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX3NoYWRvdworCitpbmhlcml0ICIvc3RkL3V0aWwvZXhlY3V0ZXIiOworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPHF1ZXN0bWFzdGVyLmg+CisKKyNkZWZpbmUgREVCVUcoeCkgaWYgKGZpbmRfcGxheWVyKCJ6ZXNzdHJhIikpIHRlbGxfb2JqZWN0KGZpbmRfcGxheWVyKCJ6ZXNzdHJhIikseCkKKworLy8gZXJ3ZWl0ZXJ0IHVtIGRhcyA8cGw+IGFyZ3VtZW50IHVuZCBkaWUgZXh0cmEtQXJndW1lbnQsIGRpZSBiZXJlaXRzIGluIDxmdW4+CisvLyBhbmdlZ2ViZW4gd3VyZGVuLiAoKmdydW1tZWwqKQorcHJvdGVjdGVkIG1peGVkIGV4ZWN1dGVfYW55dGhpbmcobWl4ZWQgZnVuLCBvYmplY3QgcGwsIHZhcmFyZ3MgbWl4ZWQgYXJncykKK3sKKyAgLy9ERUJVRyhzcHJpbnRmKCJleF9hbnkoKTogRnVuOiAlTywgT2I6ICVPLCBhcmdzOiAlT1xuIixmdW4scGwsYXJncykpOworICAvLyB3ZW5uIGluIGZ1biBzY2hvbiBleHRyYWFyZ3VtZW50ZSBzdGVoZW4sIGRhbm4gcGwgZWluZnVlZ2VuIHVuZCBhcmdzCisgIC8vIGRyYW5oYWVuZ2VuLgorICBpZiAocG9pbnRlcnAoZnVuKSAmJiBzaXplb2YoZnVuKSA+IDIpCisgIHsKKyAgICAvLyBhcmdzIGthbm4gKHt9KSBzZWluLCB3ZW5uIGtlaW5lIEV4dHJhYXJndW1lbnRlIHVlYmVyZ2ViZW4gd3VyZGVuLCBtYWNodAorICAgIC8vIGFiZXIgbml4LgorICAgIGFyZ3MgPSAoe3BsfSkgKyBmdW5bMi4uXSArIGFyZ3M7CisgICAgZnVuID0gZnVuWzAuLjFdOworICAgIHJldHVybiA6OmV4ZWN1dGVfYW55dGhpbmcoZnVuLCBhcmdzLi4uKTsKKyAgfQorICAvLyBzLm8uCisgIHJldHVybiA6OmV4ZWN1dGVfYW55dGhpbmcoZnVuLCBwbCwgYXJncy4uLik7Cit9CisKK21hcHBpbmcgcmFjZV9tb2RpZmllcihvYmplY3QgcGwsIG1hcHBpbmcgbWFwX2xkZmllZCkgeworICBtYXBwaW5nIHJtYXAsaGVscDsKKworICBpZiAobWFwcGluZ3AobWFwX2xkZmllZCkgJiYgbWVtYmVyKG1hcF9sZGZpZWQsU01fUkFDRSkgJiYgb2JqZWN0cChwbCkgJiYKKyAgICAgIG1hcHBpbmdwKHJtYXA9bWFwX2xkZmllZFtTTV9SQUNFXSkpCisvLyAgICBpZiAobWFwcGluZ3AoaGVscD1ybWFwW3BsLT5fcXVlcnlfcmVhbF9yYWNlKCldKSkKKyAgICBpZiAobWFwcGluZ3AoaGVscD1ybWFwW3BsLT5RdWVyeVByb3AoUF9SRUFMX1JBQ0UpXSkpCisgICAgICAgIHJldHVybiBtYXBfbGRmaWVkK2hlbHA7CisgICAgZWxzZSBpZihtZW1iZXIocm1hcCwiKiIpICYmIG1hcHBpbmdwKGhlbHA9cm1hcFsiKiJdKSkKKyAgICAgICAgcmV0dXJuIG1hcF9sZGZpZWQraGVscDsKKyAgcmV0dXJuIG1hcF9sZGZpZWQ7Cit9CisKK3N0cmluZworY2hlY2tfcmVzdHJpY3Rpb25zKG9iamVjdCBwbCwgbWFwcGluZyByZXN0cikgeworICAvKiBGb2xnZW5kZSBFaW5zY2hyYWVua3VuZ2VuIGtvZW5uZW4gZ2VwcnVlZnQgd2VyZGVuOgorICAgKiAtIE1pbmRlc3R3ZXJ0ZSBiZWkgYWxsZW4gQXR0cmlidXRlbiB1bmQgUHJvcGVydGllcyBMZXZlbCwgUVAsIFhQCisgICAqIC0gYmVzdGltbXRlIFJhc3NlbiBrb2VubmVuIGF1c2dlc2NobG9zc2VuIHdlcmRlbiBiencuIGVybGF1YnQgd2VyZGVuCisgICAqICAgKFNSX0VYQ0xVREVfUkFDRSBpc3QgZWluIEFycmF5IHZvbiBhdXNnZXNjaGxvc3NlbmVuIFJhc3NlbiwKKyAgICogICAgU1JfSU5DTFVERV9SQUNFIGVpbmVzIG1pdCBlaW5nZXNjaGxvc3NlbmVuKQorICAgKiAtIFNSX1JBQ0Uga2FubiBlaW4gTWFwcGluZyBzZWluLCBkYXNzIFJhc3NlbiBlaW4gZWlnZW5lcworICAgKiAgIFJlc3RyaWN0aW9uLW1hcHBpbmcgenVvcmRuZXQuICIqIiBzdGVodCBmdWVyIGFsbGUgYW5kZXJlbiBSYXNzZW4uCisgICAqLworICBjbG9zdXJlIGNsLGNsMjsKKyAgc3RyaW5nIHJhY2UsIGd1aWxkOworCisgIGlmICghbWFwcGluZ3AocmVzdHIpIHx8ICFzaXplb2YocmVzdHIpKSByZXR1cm4gMDsgLy8gS2VpbmUgRWluc2NocmFlbmt1bmdlbgorICBpZiAoIW9iamVjdHAocGwpKSByZXR1cm4gIiI7CisgIGlmIChwbC0+UXVlcnlEaXNndWlzZSgpKQorICAgIHJldHVybiAiWmllaCBlcnN0IG1hbCBkZW4gVGFybmhlbG0gYXVzLlxuIjsKKworICByZXN0cj1yYWNlX21vZGlmaWVyKCZwbCwmcmVzdHIpOworCisgIGNsPXN5bWJvbF9mdW5jdGlvbigiUXVlcnlQcm9wIixwbCk7CisgIGNsMj1zeW1ib2xfZnVuY3Rpb24oIlF1ZXJ5QXR0cmlidXRlIixwbCk7CisKKyAgZm9yZWFjaChzdHJpbmcgdG9fY2hlY2ssIG1peGVkIGNvbmRpdGlvbjogcmVzdHIpCisgIHsKKyAgICBzd2l0Y2godG9fY2hlY2spCisgICAgeworICAgICAgY2FzZSBQX0xFVkVMOgorICAgICAgICBpZiAoZnVuY2FsbChjbCxQX0xFVkVMKSA8IGNvbmRpdGlvbikKKyAgICAgICAgICByZXR1cm4gIkRlaW5lIFN0dWZlIHJlaWNodCBkYWZ1ZXIgbmljaHQgYXVzLlxuIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFBfR1VJTERfTEVWRUw6CisgICAgICAgIGlmIChmdW5jYWxsKGNsLFBfR1VJTERfTEVWRUwpIDwgY29uZGl0aW9uKQorICAgICAgICAgIHJldHVybiAiRGVpbmUgR2lsZGVuc3R1ZmUgcmVpY2h0IGRhZnVlciBuaWNodCBhdXMuXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgU1JfU0VFUjogLy8gZGFzIG1hY2h0IG51biB3YWhybGljaCBudXIgYmVpIGludGVyYWN0aXZlcyBzaW5uISEhCisgICAgICAgIGlmIChjb25kaXRpb24gJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShwbCkgJiYgIUlTX1NFRVIocGwpKQorICAgICAgICAgIHJldHVybiAiRHUgbXVzc3QgZGF6dSBlcnN0IFNlaGVyIHdlcmRlbi5cbiI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBQX1hQOgorICAgICAgICBpZiAoZnVuY2FsbChjbCxQX1hQKSA8IGNvbmRpdGlvbikKKyAgICAgICAgICByZXR1cm4gIkR1IGhhc3QgbmljaHQgZ2VudWVnZW5kIEVyZmFocnVuZyBkYWZ1ZXIuXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgUF9RUDoKKyAgICAgICAgaWYgKGZ1bmNhbGwoY2wsUF9RUCkgPCBjb25kaXRpb24pCisgICAgICAgICAgcmV0dXJuICJEdSBoYXN0IG5pY2h0IGdlbnVlZ2VuZCBBdWZnYWJlbiBnZWxvZXN0LlxuIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFBfQUxDT0hPTDoKKyAgICAgICAgaWYgKGZ1bmNhbGwoY2wsUF9BTENPSE9MKSA+PSBjb25kaXRpb24pCisgICAgICAgICAgcmV0dXJuICJEdSBiaXN0IHp1IGJlc29mZmVuLlxuIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFBfRFJJTks6CisgICAgICAgIGlmIChmdW5jYWxsKGNsLFBfRFJJTkspID49IGNvbmRpdGlvbikKKyAgICAgICAgICByZXR1cm4gIkR1IGhhc3QgenV2aWVsIGdldHJ1bmtlbi5cbiI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBQX0ZPT0Q6CisgICAgICAgIGlmIChmdW5jYWxsKGNsLFBfRk9PRCkgPj0gY29uZGl0aW9uKQorICAgICAgICAgIHJldHVybiAiRHUgaGFzdCB6dXZpZWwgZ2VnZXNzZW4uXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgUF9ERUFGOgorICAgICAgICBpZiAoZnVuY2FsbChjbCxQX0RFQUYpKQorICAgICAgICAgIHJldHVybiAiRHUga2FubnN0IG5pY2h0cyBob2VyZW4uXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgUF9CTElORDoKKyAgICAgICAgaWYgKGZ1bmNhbGwoY2wsUF9CTElORCkpCisgICAgICAgICAgcmV0dXJuICJEdSBrYW5uc3QgbmljaHRzIHNlaGVuLlxuIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFBfRlJPRzoKKyAgICAgICAgaWYgKGZ1bmNhbGwoY2wsUF9GUk9HKSkKKyAgICAgICAgICByZXR1cm4gIkFscyBGcm9zY2gga2FubnN0IER1IGRhcyBsZWlkZXIgbmljaHQuXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgQV9JTlQ6CisgICAgICAgIGlmIChmdW5jYWxsKGNsMixBX0lOVCkgPCBjb25kaXRpb24pCisgICAgICAgICAgcmV0dXJuICJEZWluZSBJbnRlbGxpZ2VueiByZWljaHQgZGFmdWVyIG5pY2h0IGF1cy5cbiI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBBX0RFWDoKKyAgICAgICAgaWYgKGZ1bmNhbGwoY2wyLEFfREVYKSA8IGNvbmRpdGlvbikKKyAgICAgICAgICByZXR1cm4gIkRlaW5lIEdlc2NoaWNrbGljaGtlaXQgcmVpY2h0IGRhZnVlciBuaWNodCBhdXMuXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgQV9DT046CisgICAgICAgIGlmIChmdW5jYWxsKGNsMixBX0NPTikgPCBjb25kaXRpb24pCisgICAgICAgICAgcmV0dXJuICJEZWluZSBBdXNkYXVlciByZWljaHQgZGFmdWVyIG5pY2h0IGF1cy5cbiI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBBX1NUUjoKKyAgICAgICAgaWYgKGZ1bmNhbGwoY2wyLEFfU1RSKSA8IGNvbmRpdGlvbikKKyAgICAgICAgICByZXR1cm4gIkRlaW5lIFN0YWVya2UgcmVpY2h0IGRhZnVlciBuaWNodCBhdXMuXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgU1JfQkFEOgorICAgICAgICBpZiAoZnVuY2FsbChjbCxQX0FMSUdOKSA8IGNvbmRpdGlvbikKKyAgICAgICAgICByZXR1cm4gIkR1IGJpc3QgenUgYm9lc2UuXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgU1JfR09PRDoKKyAgICAgICAgaWYgKGZ1bmNhbGwoY2wsUF9BTElHTikgPiBjb25kaXRpb24pCisgICAgICAgICAgcmV0dXJuICJEdSBiaXN0IG5pY2h0IGJvZXNlIGdlbnVnLlxuIjsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFNSX01JTl9TSVpFOgorICAgICAgICBpZiAoZnVuY2FsbChjbCxQX1NJWkUpIDwgY29uZGl0aW9uKQorICAgICAgICAgIHJldHVybiAiRHUgYmlzdCBkYWZ1ZXIgenUga2xlaW4uXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgU1JfTUFYX1NJWkU6CisgICAgICAgIGlmIChmdW5jYWxsKGNsLFBfU0laRSkgPiBjb25kaXRpb24pCisgICAgICAgICAgcmV0dXJuICJEdSBiaXN0IGRhZnVlciB6dSBncm9zcy5cbiI7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSBTUl9GUkVFX0hBTkRTOgorICAgICAgICBpZiAoY29uZGl0aW9uID4gKGZ1bmNhbGwoY2wsUF9NQVhfSEFORFMpLWZ1bmNhbGwoY2wsUF9VU0VEX0hBTkRTKSkpCisgICAgICAgICAgcmV0dXJuICJEdSBoYXN0IG5pY2h0IGdlbnVnIGZyZWllIEhhZW5kZSBkYWZ1ZXIuXG4iOworICAgICAgICBicmVhazsKKyAgICAgIGNhc2UgU1JfRVhDTFVERV9SQUNFOgorICAgICAgICBpZiAoSVNfTEVBUk5FUihwbCkpCisgICAgICAgICAgcmFjZT1mdW5jYWxsKGNsLFBfUkFDRSk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICByYWNlPWZ1bmNhbGwoY2wsUF9SRUFMX1JBQ0UpOyAvL3JhY2U9cGwtPl9xdWVyeV9yZWFsX3JhY2UoKTsKKyAgICAgICAgaWYgKCBwb2ludGVycChjb25kaXRpb24pICYmIG1lbWJlcihjb25kaXRpb24scmFjZSk+PTAgKQorICAgICAgICAgIHJldHVybiAoIkFscyAiK3JhY2UrIiBrYW5uc3QgRHUgZGFzIG5pY2h0LlxuIik7CisgICAgICAgIGJyZWFrOworICAgICBjYXNlIFNSX0lOQ0xVREVfUkFDRToKKyAgICAgICAgaWYgKElTX0xFQVJORVIocGwpKQorICAgICAgICAgIHJhY2U9ZnVuY2FsbChjbCxQX1JBQ0UpOworICAgICAgICBlbHNlCisgICAgICAgICAgcmFjZT1mdW5jYWxsKGNsLFBfUkVBTF9SQUNFKTsgLy9yYWNlPXBsLT5fcXVlcnlfcmVhbF9yYWNlKCk7CisgICAgICAgIGlmIChwb2ludGVycChjb25kaXRpb24pICYmIG1lbWJlcihjb25kaXRpb24scmFjZSk8MCkKKyAgICAgICAgICByZXR1cm4gKCJBbHMgIityYWNlKyIga2FubnN0IER1IGRhcyBuaWNodC5cbiIpOworICAgICAgICBicmVhazsKKyAgICAgY2FzZSBTUl9FWENMVURFX0dVSUxEOgorICAgICAgICBndWlsZD1mdW5jYWxsKGNsLFBfR1VJTEQpOworICAgICAgICBpZiAocG9pbnRlcnAoY29uZGl0aW9uKSAmJiBtZW1iZXIoY29uZGl0aW9uLGd1aWxkKT49MCkKKyAgICAgICAgICByZXR1cm4gKCJNaXQgRGVpbmVyIEdpbGRlbnp1Z2Vob2VyaWdrZWl0IGthbm5zdCBEdSBkYXMgbmljaHQuXG4iKTsKKyAgICAgICAgYnJlYWs7CisgICAgICBjYXNlIFNSX0lOQ0xVREVfR1VJTEQ6CisgICAgICAgIGd1aWxkPWZ1bmNhbGwoY2wsUF9HVUlMRCk7CisgICAgICAgIGlmIChwb2ludGVycChjb25kaXRpb24pICYmIG1lbWJlcihjb25kaXRpb24sZ3VpbGQpPDApCisgICAgICAgICAgcmV0dXJuICgiTWl0IERlaW5lciBHaWxkZW56dWdlaG9lcmlna2VpdCBrYW5uc3QgRHUgZGFzIG5pY2h0LlxuIik7CisgICAgICAgIGJyZWFrOworICAgICBjYXNlIFNSX0ZVTjoKKyAgICAgICAgc3RyaW5nIHJlcz1leGVjdXRlX2FueXRoaW5nKGNvbmRpdGlvbiwgcGwpOworICAgICAgICBpZiAoc3RyaW5ncChyZXMpKQorICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgIGJyZWFrOworICAgICBjYXNlIFNSX1BST1A6CisgICAgICAgIGZvcmVhY2ggKCBzdHJpbmcgcHJvcG5hbWUsIG1peGVkIHZhbHVlLCBzdHJpbmcgbXNnOiBjb25kaXRpb24gKSB7CisgICAgICAgICAgaWYgKCBmdW5jYWxsKGNsLCBwcm9wbmFtZSkgIT0gdmFsdWUgKQorICAgICAgICAgICAgcmV0dXJuICggc3RyaW5ncChtc2cpICYmIHNpemVvZihtc2cpID8gbXNnIDoKKyAgICAgICAgICAgICAgIktvZW5udGUgZXMgc2VpbiwgZGFzcyBEdSB2ZXJnZXNzZW4gaGFzdCwgZXR3YXMgenUgIgorICAgICAgICAgICAgICAiZXJsZWRpZ2VuP1xuIik7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgIGNhc2UgU1JfUVVFU1Q6CisgICAgICAgIGlmIChwb2ludGVycChjb25kaXRpb24pKQorICAgICAgICB7CisgICAgICAgICAgLy8gZ2Vsb2VzdGUgUXVlc3RzIGF1cyBkZXIgTGlzdGUgZGVyIEJlZGluZ3VuZ2VuIGVudGZlcm5lbgorICAgICAgICAgIGNvbmRpdGlvbiAtPSBmaWx0ZXIoY29uZGl0aW9uLCAiUXVlcnlRdWVzdCIsIHBsKTsKKyAgICAgICAgICBpZiAoIHNpemVvZihjb25kaXRpb24pICkKKyAgICAgICAgICAgIHJldHVybiAoIkR1IG11c3N0IHp1ZXJzdCBkYXMgQWJlbnRldWVyICciK2NvbmRpdGlvblswXSsKKyAgICAgICAgICAgICAgIicgbG9lc2VuLlxuIik7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgIGNhc2UgU1JfTUlOSVFVRVNUOgorICAgICAgICBpZiAocG9pbnRlcnAoY29uZGl0aW9uKSkKKyAgICAgICAgeworICAgICAgICAgIGNsb3N1cmUgdW5zb2x2ZWRfTVFzID0gZnVuY3Rpb24gaW50IChtaXhlZCBtcV9udW0pCisgICAgICAgICAgICB7IHJldHVybiAhKFFNKS0+SGFzTWluaVF1ZXN0KHBsLCBtcV9udW0pOyB9OworICAgICAgICAgIGlmICggc2l6ZW9mKGZpbHRlcihjb25kaXRpb24sIHVuc29sdmVkX01RcykpICkKKyAgICAgICAgICAgIHJldHVybiAiRHUgaGFzdCBlaW5lIGJlbm9ldGlndGUgTWluaXF1ZXN0IG5vY2ggbmljaHQgZ2Vsb2VzdC5cbiI7CisgICAgICAgICAgICAvLyBEZXIgTmFtZSBkZXIgTVEgd2lyZCBhYnNpY2h0bGljaCBuaWNodCBleHBsaXppdCBhdXNnZWdlYmVuLgorICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0gLy8gc3dpdGNoCisgIH0gLy8gZm9yZWFjaAorICByZXR1cm4gMDsKK30KKwordmFyYXJncyBtaXhlZAorR2V0RGF0YShzdHJpbmcgZG5hbWUsIG1hcHBpbmcgbWFwX2xkZmllZCwgb2JqZWN0IHBsKSB7CisgIG1peGVkIGRhdCxyZXM7CisKKyAgaWYgKCFkbmFtZSB8fCAhbWFwcGluZ3AobWFwX2xkZmllZCkpIHJldHVybiAwOworICBpZiAoY2xvc3VyZXAoZGF0PW1hcF9sZGZpZWRbZG5hbWVdKSAmJiAocmVzPWZ1bmNhbGwoZGF0LHBsLG1hcF9sZGZpZWQpKSkKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgcmV0dXJuIGRhdDsKKworfQorCit2YXJhcmdzIGludAorR2V0VmFsdWUoc3RyaW5nIHZuYW1lLCBtYXBwaW5nIG1hcF9sZGZpZWQsIG9iamVjdCBwbCkgeworICBtaXhlZCBkYXQscmVzOworCisgIC8vIHByaW50ZigiR2V0VmFsdWUoJU8pOiAlT1xuIix2bmFtZSxtYXBfbGRmaWVkKTsKKyAgaWYgKCF2bmFtZSB8fCAhbWFwX2xkZmllZCkgcmV0dXJuIDA7CisgIGlmICgoZGF0PW1hcF9sZGZpZWRbdm5hbWVdKSAmJiAocmVzPWV4ZWN1dGVfYW55dGhpbmcoZGF0LHBsLG1hcF9sZGZpZWQpKSkKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgLy8gcHJpbnRmKCJWYWx1ZTogJU9cbiIsZGF0KTsKKyAgcmV0dXJuIGludHAoZGF0KSA/IGRhdCA6IDA7Cit9CisKK3ZhcmFyZ3MgaW50CitHZXRGYWN0b3Ioc3RyaW5nIGZuYW1lLCBtYXBwaW5nIG1hcF9sZGZpZWQsIG9iamVjdCBwbCkgeworICBtaXhlZCByZXM7CisKKyAgLy8gcHJpbnRmKCJHZXRGYWN0b3IoJU8pOlxuIixmbmFtZSk7CisgIGlmICghZm5hbWUgIHx8ICEocmVzPUdldFZhbHVlKEZBQ1RPUihmbmFtZSksbWFwX2xkZmllZCxwbCkpKQorICAgICAgICByZXR1cm4gMTAwOworICBpZiAocmVzPDEwKSByZXM9MTA7CisgIGVsc2UgaWYgKHJlcz4xMDAwKSByZXM9MTAwMDsKKyAgLy8gcHJpbnRmKCJGYWN0b3I6ICVPXG4iLHJlcyk7CisgIHJldHVybiByZXM7Cit9CisKK3ZhcmFyZ3MgaW50CitHZXRPZmZzZXQoc3RyaW5nIG9uYW1lLCBtYXBwaW5nIG1hcF9sZGZpZWQsIG9iamVjdCBwbCkgeworICBtaXhlZCByZXM7CisKKyAgLy8gcHJpbnRmKCJHZXRPZmZzZXQoJU8pOlxuIixvbmFtZSk7CisgIGlmICghb25hbWUgIHx8ICEocmVzPUdldFZhbHVlKE9GRlNFVChvbmFtZSksbWFwX2xkZmllZCxwbCkpKQorICAgICAgICByZXR1cm4gMDsKKyAgaWYgKHJlczwtMTAwMDApIHJlcz0tMTAwMDA7CisgIGVsc2UgaWYgKHJlcz4xMDAwMCkgcmVzPTEwMDAwOworICAvLyBwcmludGYoIk9mZnNldDogJU9cbiIscmVzKTsKKyAgcmV0dXJuIHJlczsKK30KKwordmFyYXJncyBpbnQKK0dldEZWYWx1ZShzdHJpbmcgdm5hbWUsIG1hcHBpbmcgbWFwX2xkZmllZCwgb2JqZWN0IHBsKSB7CisgIHJldHVybiAoR2V0VmFsdWUodm5hbWUsbWFwX2xkZmllZCxwbCkqR2V0RmFjdG9yKHZuYW1lLG1hcF9sZGZpZWQscGwpKS8xMDA7Cit9CisKK3ZhcmFyZ3MgaW50CitHZXRWYWx1ZU8oc3RyaW5nIHZuYW1lLCBtYXBwaW5nIG1hcF9sZGZpZWQsIG9iamVjdCBwbCkgeworICByZXR1cm4gR2V0VmFsdWUodm5hbWUsbWFwX2xkZmllZCxwbCkrR2V0T2Zmc2V0KHZuYW1lLG1hcF9sZGZpZWQscGwpOworfQorCit2YXJhcmdzIGludAorR2V0RlZhbHVlTyhzdHJpbmcgdm5hbWUsIG1hcHBpbmcgbWFwX2xkZmllZCwgb2JqZWN0IHBsKSB7CisgIHJldHVybiAoKEdldFZhbHVlKHZuYW1lLG1hcF9sZGZpZWQscGwpKkdldEZhY3Rvcih2bmFtZSxtYXBfbGRmaWVkLHBsKSkvMTAwCisgICAgICAgICAgICAgICAgICArIEdldE9mZnNldCh2bmFtZSxtYXBfbGRmaWVkLHBsKSk7Cit9CisKK3ZhcmFyZ3MgaW50CitHZXRSYW5kRlZhbHVlTyhzdHJpbmcgdm5hbWUsIG1hcHBpbmcgbWFwX2xkZmllZCwgb2JqZWN0IHBsKSB7CisgIHJldHVybiAocmFuZG9tKEdldFZhbHVlKHZuYW1lLG1hcF9sZGZpZWQscGwpKkdldEZhY3Rvcih2bmFtZSxtYXBfbGRmaWVkLHBsKSkvMTAwCisgICAgICAgICAgKyBHZXRPZmZzZXQodm5hbWUsbWFwX2xkZmllZCxwbCkpOworfQorCittYXBwaW5nIEFkZFNraWxsTWFwcGluZ3MobWFwcGluZyBvbGRtYXAsIG1hcHBpbmcgbmV3bWFwKSB7CisgIG1hcHBpbmcgcmVzLHQxLHQyOworICBtaXhlZCAqaW54LGluZDsKKyAgaW50IGk7CisKKyAgaWYgKCFtYXBwaW5ncChvbGRtYXApKSByZXR1cm4gbmV3bWFwOworICBpZiAoIW1hcHBpbmdwKG5ld21hcCkpIHJldHVybiBvbGRtYXA7CisgIGlueD0oe1NJX1NLSUxMUkVTVFJfTEVBUk4sU0lfU0tJTExSRVNUUl9VU0UsU01fUkFDRX0pOworICByZXM9b2xkbWFwK25ld21hcDsKKyAgZm9yIChpPXNpemVvZihpbngpO2ktLTspIHsKKyAgICAgICAgaW5kPWlueFtpXTsKKyAgICAgICAgdDE9b2xkbWFwW2luZF07CisgICAgICAgIHQyPW5ld21hcFtpbmRdOworICAgICAgICBpZiAodDEpIHsKKyAgICAgICAgICBpZiAodDIpCisgICAgICAgICAgICAgICAgcmVzW2luZF09dDErdDI7CisgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHJlc1tpbmRdPXQxOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgIGlmICh0MikKKyAgICAgICAgICAgICAgICByZXNbaW5kXT10MjsKKyAgICAgICAgfQorICB9CisgIHJldHVybiByZXM7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9yb29tLmMgYi9zdGQvcm9vbS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI5YWI1MDMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS5jCkBAIC0wLDAgKzEsMjM5IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcm9vbS5jIC0tIHJvb20gYmFzZSBvYmplY3QKKy8vCisvLyAkSWQ6IHJvb20uYyA5NDc1IDIwMTYtMDItMTkgMjE6MTY6MTdaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL3RoaW5nL3Byb3BlcnRpZXMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9sYW5ndWFnZSI7Citpbmhlcml0ICIvc3RkL2hvb2tfcHJvdmlkZXIiOworaW5oZXJpdCAiL3N0ZC9yb29tL2xpZ2h0IjsKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL2ludmVudG9yeSI7Citpbmhlcml0ICIvc3RkL3Jvb20vbW92aW5nIjsKK2luaGVyaXQgIi9zdGQvcm9vbS9yZXN0cmljdGlvbnMiOworaW5oZXJpdCAiL3N0ZC9yb29tL2Rlc2NyaXB0aW9uIjsKK2luaGVyaXQgIi9zdGQvcm9vbS9leGl0cyI7Citpbmhlcml0ICIvc3RkL3Jvb20vY29tbWFuZHMiOworaW5oZXJpdCAiL3N0ZC9yb29tL2l0ZW1zIjsKK2luaGVyaXQgIi9zdGQvcm9vbS9kb29ycyI7CisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8Y29uZmlnLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHJvb21zLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8ZG9vcnJvb20uaD4KKyNpbmNsdWRlIDxmdW5jdGlvbmxpc3QuaD4KKwordm9pZCByZXNldCgpCit7CisgIGl0ZW1zOjpyZXNldCgpOworICBleGl0czo6cmVzZXQoKTsKKyAgZG9vcnM6OnJlc2V0KCk7Cit9CisKK3N0YXRpYyBpbnQKK19xdWVyeV9ub2dldCgpCit7CisgIHJldHVybiAxOworfQorCisvLyNkZWZpbmUgREIoeCkgaWYgKGZpbmRfcGxheWVyKCJqb2YiKSkgdGVsbF9vYmplY3QoZmluZF9wbGF5ZXIoImpvZiIpLHgpOyBlbHNlIHdyaXRlKHgpCisvLyN1bmRlZiBEQgorLy8jZGVmaW5lIERCKHgpCit2b2lkIG1heWJlX3JlcGxhY2VfcHJvZ3JhbSgpCit7CisgIHN0cmluZyAqbGlzdCwgZmlyc3Q7CisgIG9iamVjdCBmaXJzdF9vYjsKKworLy8gRGVidWdrcmFtIGF1c2tvbW1lbnRpZXJ0LCBaZXNzdHJhLCAwNC4xMS4wNgorLy8gIERCKCJNQVlCRV9SRVBMQUNFX1BST0dSQU1cbiIpOworLy8gIERCKHNwcmludGYoIkZJTEVOQU1FOiAlT1xuIixvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSkpOworLy8gIERCKHNwcmludGYoIkZJUlNUX09COiAlT1xuIixpbmhlcml0X2xpc3QodGhpc19vYmplY3QoKSkpKTsKKy8vICBmaXJzdF9vYj1maW5kX29iamVjdChmaXJzdD0obGlzdD1pbmhlcml0X2xpc3QodGhpc19vYmplY3QoKSkpWzFdKTsKKy8vICBEQihzcHJpbnRmKCIlTyA/PSAlT1xuIixzaXplb2YobGlzdCksMStzaXplb2YoaW5oZXJpdF9saXN0KGZpcnN0X29iKSkpKTsKKy8vICBEQihzcHJpbnRmKCIlTyA/PSBzaXplb2YoJU8pXG4iLDEsbGlzdD1mdW5jdGlvbmxpc3QodGhpc19vYmplY3QoKSxSRVRVUk5fRlVOQ1RJT05fTkFNRXxOQU1FX0lOSEVSSVRFRCkpKTsKKyAgaWYgKG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpPT0iL3N0ZC9yb29tIiB8fAorICAgICAgIShmaXJzdF9vYj1maW5kX29iamVjdChmaXJzdD0obGlzdD1pbmhlcml0X2xpc3QodGhpc19vYmplY3QoKSkpWzFdKSkgfHwKKyAgICAgIChzaXplb2YobGlzdCkhPTErc2l6ZW9mKGluaGVyaXRfbGlzdChmaXJzdF9vYikpKSB8fAorICAgICAgKDEhPXNpemVvZihsaXN0PWZ1bmN0aW9ubGlzdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgICBSRVRVUk5fRlVOQ1RJT05fTkFNRXxOQU1FX0lOSEVSSVRFRCkpKSB8fAorICAgICAgbGlzdFswXSE9ImNyZWF0ZSIpCisgICAgcmV0dXJuOworLy8gIERCKCJSRVBMQUNJTkdcbiIpOworICByZXBsYWNlX3Byb2dyYW0oZmlyc3QpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBtYXliZV9yZXBsYWNlX3Byb2dyYW0oKTsKKyAgLyogU2V0IGVmZmVjdGl2ZSB1c2VyaWQgdG8gdXNlcmlkICovCisgIC8qIHNvIHRoYXQgd2UgbWF5IGNsb25lIG90aGVyIHRoaW5ncyAqLworICBzZXRldWlkKGdldHVpZCh0aGlzX29iamVjdCgpKSk7CisgIHByb3BlcnRpZXM6OmNyZWF0ZSgpOworICByZXN0cmljdGlvbnM6OmNyZWF0ZSgpOworICBjb21tYW5kczo6Y3JlYXRlKCk7CisgIGxpZ2h0OjpjcmVhdGUoKTsKKyAgZGVzY3JpcHRpb246OmNyZWF0ZSgpOworICBleGl0czo6Y3JlYXRlKCk7CisgIGl0ZW1zOjpjcmVhdGUoKTsKKyAgZG9vcnM6OmNyZWF0ZSgpOworCisgIFNldFByb3AoUF9OQU1FLDApOworICBTZXRQcm9wKFBfTkFNRV9BREosKHt9KSk7CisgIFNldChQX1NIT1JULDApOworICBTZXQoUF9MT05HLDApOworICBTZXQoUF9UUkFOU1BBUkVOVCwwKTsKKyAgU2V0KFBfQURKRUNUSVZFUywoe30pKTsKKyAgU2V0KFBfSURTLCh7fSkpOworICBTZXQoUF9XRUlHSFQsUFJPVEVDVEVELEZfTU9ERSk7CisgIFNldChQX1RPVEFMX1dFSUdIVCxQUk9URUNURUQsRl9NT0RFKTsKKyAgU2V0KCIgY2xlYW4gY291bnRlciAiLDIpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKworcHJpdmF0ZSBpbnQKK2NoZWNrX2NsZWFuX2NvdW50KCkKK3sKKyAgaW50IGNjOworCisgIGNjPVF1ZXJ5KCIgY2xlYW4gY291bnRlciAiKTsKKyAgaWYgKC0tY2M8PTApCisgICAgcmV0dXJuIDE7CisgIFNldCgiIGNsZWFuIGNvdW50ZXIgIixjYyk7CisgIHJldHVybiAwOworfQorCitpbnQKK2NsZWFuX3VwKGludCBhcmcpCit7CisgIG1peGVkIGl0ZW1hOworCisgIGlmKGFyZz4xKSByZXR1cm4gMTsgLy8gYmV0dGVyIG5vdCA7KQorCisgIGlmIChRdWVyeSgiIG5ldmVyIGNsZWFuICIpKSByZXR1cm4gMDsKKworICAvLyBpZiB0aGVyZSBhcmUgYW55IGl0ZW0gd2UgaGF2ZSBwcm9kdWNlZCBvdXJzZWxmZXMgY2hlY2sgdGhlbQorICBpZihwb2ludGVycChpdGVtYSA9IFF1ZXJ5UHJvcChQX0lURU1TKSkpCisgIHsKKyAgICBtaXhlZCBuYW1lczsKKyAgICBpbnQgaTsKKyAgICBpID0gc2l6ZW9mKG5hbWVzID0gYWxsX2ludmVudG9yeSh0aGlzX29iamVjdCgpKSk7CisgICAgd2hpbGUoaS0tKQorICAgIHsKKyAgICAgIGlmIChxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG5hbWVzW2ldKSkKKyAgICAgIHsKKwlTZXQoIiBjbGVhbiBjb3VudGVyICIsMik7CisJcmV0dXJuIDE7CisgICAgICB9CisgICAgICBpZihvYmplY3RwKG5hbWVzW2ldKSkgbmFtZXNbaV0gPSBleHBsb2RlKG9iamVjdF9uYW1lKG5hbWVzW2ldKSwiIyIpWzBdOworICAgIH0KKworICAgIGZvcihpID0gc2l6ZW9mKGl0ZW1hKS0xOyBpID49IDA7IGktLSkKKyAgICB7CisgICAgICAvLyBTZW1hbnRpazoKKyAgICAgIC8vIDEuIFdlbm4gUklURU1fT0JKRUNUIGVpbiBhcnJheSBpc3QsIGthbm4gZXZ0bCBnZSdjbGVhbidlZCB3ZXJkZW4uCisgICAgICAvLyAyLiBXZW5uIGVzIGVpbiBSRUZSRVNIX05PTkUgSXRlbSBpc3QgdW5kIGVzIGVudHdlZGVyIG5pY2h0IG1laHIgCisgICAgICAvLyAgICBleGlzdGllcnQgb2RlciBuaWNodCBpbiBkaWVzZW0gUmF1bSBpc3QsIGtlaW4gY2xlYW5fdXAgKGVzIHd1ZXJkZQorICAgICAgLy8gICAgYmVpbSBuZXVsYWRlbiBkZXMgUmF1bWVzIGphIHdpZWRlciBlcnpldWd0OworICAgICAgLy8gICAgZmFsbHMgZXMgYWJlciBoaWVyIGlzdCwgd2lyZCBlcyBtaXR2ZXJuaWNodGV0LCBkYW5uIGlzdHMgb2spCisgICAgICAvLyAzLiBXZW5uIGVzIGVpbiBSRUZSRVNIX0RFU1RSVUNUIGlzdCB1bmQgbm9jaCBleGlzdGllcnQsIGFiZXIgbmljaHQKKyAgICAgIC8vICAgIGhpZXIgaXN0LCBLRUlOIGNsZWFuX3VwLgorICAgICAgaWYgKCFwb2ludGVycChpdGVtYVtpXVtSSVRFTV9PQkpFQ1RdKSAKKwkgICYmICgoaXRlbWFbaV1bUklURU1fUkVGUkVTSF0gPT0gUkVGUkVTSF9OT05FIAorCSAgICAgICYmICghaXRlbWFbaV1bUklURU1fT0JKRUNUXSAKKwkJfHwgZW52aXJvbm1lbnQoaXRlbWFbaV1bUklURU1fT0JKRUNUXSkhPXRoaXNfb2JqZWN0KCkpKSAKKwkgICAgfHwgKGl0ZW1hW2ldW1JJVEVNX1JFRlJFU0hdID09IFJFRlJFU0hfREVTVFJVQ1QgCisJICAgICAgJiYgaXRlbWFbaV1bUklURU1fT0JKRUNUXSAKKwkgICAgICAmJiBlbnZpcm9ubWVudChpdGVtYVtpXVtSSVRFTV9PQkpFQ1RdKSAhPSB0aGlzX29iamVjdCgpKSkpCisJICByZXR1cm4gMTsKKyAgICAgIG5hbWVzIC09IChwb2ludGVycChpdGVtYVtpXVtSSVRFTV9GSUxFXSkgPworCSAgaXRlbWFbaV1bUklURU1fRklMRV0gOiAoeyBpdGVtYVtpXVtSSVRFTV9GSUxFXSB9KSk7CisgICAgfQorICAgIC8vIGlmIHRoZXJlIGFyZSBvYmplY3RzIGxlZnQgaW4gdGhlIHJvb20gZG8gbm90IGNsZWFuIHVwIGJ1dCB0cnkgYWdhaW4gbGF0ZXIKKyAgICBpZihzaXplb2YobmFtZXMpICYmICFjaGVja19jbGVhbl9jb3VudCgpKSByZXR1cm4gMTsKKyAgfQorICBlbHNlCisgICAgLy8gaXMgdGhlcmUgYW55IG9iamVjdCBseWluZyBhcm91bmQ/CisgICAgaWYoZmlyc3RfaW52ZW50b3J5KHRoaXNfb2JqZWN0KCkpICYmICFjaGVja19jbGVhbl9jb3VudCgpKSByZXR1cm4gMjsKKworICAvLyBkbyBjbGVhbl91cAorICAvL2xvZ19maWxlKCJjbGVhbl91cF9sb2ciLHNwcmludGYoCisgIC8vCSIlczolczogJU9cbiIsY3RpbWUodGltZSgpKVsxMS4uMThdLF9fSE9TVF9OQU1FX18sdGhpc19vYmplY3QoKSkpOworICAKKyAgcmVtb3ZlKCk7CisgIC8vIHdlbm4gZGVyIFJhdW0gc2ljaCBpbSByZW1vdmUoKSBuaWNodCB6ZXJzdG9lcnQsIGhhdCBlciBkYWZ1ZXIgdmVybXV0bGljaAorICAvLyBuZW4gR3J1bmQuIEV2dGwuIGtsYXBwdHMgamEgbmFlY2hzdGVzIE1hbC4KKworICByZXR1cm4oMSk7Cit9CisKKy8qIEluc3RlYWQgb2YgcHJpbnRpbmcgdGhlIGV4aXRzIHdpdGggdGhlIGxvbmcgZGVzY3JpcHRpb24sIHdlIGltcGxlbWVudCAqLworLyogdGhlIGNvbW1hbmQgImV4aXRzIiB0byBzaG93IHRoZW0uICovCitpbnQKK3Nob3dfZXhpdHMoKSB7CisgIG1peGVkIGV4OworICBpZiggdGhpc19wbGF5ZXIoKS0+Q2Fubm90U2VlKCkgKSByZXR1cm4gMTsKKyAgaWYgKChleD1RdWVyeVByb3AoUF9ISURFX0VYSVRTKSkgJiYgaW50cChleCkpIHJldHVybiAxOworICBpZiAoZXggPSBHZXRFeGl0cyh0aGlzX3BsYXllcigpKSkgd3JpdGUoZXgpOworICByZXR1cm4gMTsKK30KKworaW50Cit0b2dnbGVfZXhpdHMoc3RyaW5nIHN0cikKK3sKKyAgaW50IGV4OworCisgIC8qIE51ciBkYXMgYWt0dWVsbGUgRW52aXJvbm1lbnQgZGVzIFNwaWVsZXJzIGlzdCB6dXN0YWVuZGlnIGZ1ZXIgZGllCisgICAgIEF1Zmxpc3R1bmcgZGVyIEF1c2dhZW5nZS4gQW5kZXJlbmZhbGxzIHdpcmQgZGFzIEtvbW1hbmRvIHZvbiBSYWV1bWVuCisgICAgIGltIFJhdW0gKHouQi4gVHJhbnNwb3J0ZXJuKSBhYmdlZmFuZ2VuIHVuZCBlcyB3ZXJkZW4gZGVzc2VuIEF1c2dhZW5nZQorICAgICBhdWZnZWxpc3RldC4KKyAgICAgU3ByaWNoOiBrZWluZSBBdWZsaXN0dW5nIHZvbiBBdXNzZW4uICovCisgIGlmIChlbnZpcm9ubWVudCh0aGlzX3BsYXllcigpKSAhPSB0aGlzX29iamVjdCgpKSByZXR1cm4gMDsKKyAgaWYgKCFzdHIpIHJldHVybiBzaG93X2V4aXRzKCk7CisgIGlmIChzdHIhPSJhdXRvIikgcmV0dXJuIDA7CisgIGV4ID0gdGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfU0hPV19FWElUUyk7CisgIHRoaXNfcGxheWVyKCktPlNldFByb3AoUF9TSE9XX0VYSVRTLCAhZXgpOworICBpZiAoZXgpIHdyaXRlKCJBdXNnYWVuZ2Ugd2VyZGVuIG5pY2h0IG1laHIgYXV0b21hdGlzY2ggYW5nZXplaWd0LlxuIik7CisgIGVsc2Ugd3JpdGUoIkF1c2dhZW5nZSB3ZXJkZW4gYXV0b21hdGlzY2ggYW5nZXplaWd0LlxuIik7CisgIHJldHVybiAxOworfQorCit2b2lkCitpbml0KCkKK3sKKyAgU2V0KCIgY2xlYW4gY291bnRlciAiLDIpOworCisgIGV4aXRzOjppbml0KCk7CisgIGNvbW1hbmRzOjppbml0KCk7CisgIGRlc2NyaXB0aW9uOjppbml0KCk7CisgIGRvb3JzOjppbml0KCk7CisKKyAgYWRkX2FjdGlvbigidG9nZ2xlX2V4aXRzIiwgImV4aXRzIik7CisgIGFkZF9hY3Rpb24oInRvZ2dsZV9leGl0cyIsICJhdXNnYW5nIik7CisgIGFkZF9hY3Rpb24oInRvZ2dsZV9leGl0cyIsICJhdXNnYWVuZ2UiKTsKKyAgYWRkX2FjdGlvbigidG9nZ2xlX2V4aXRzIiwgImF1cyIpOworfQorCitpbnQgX3F1ZXJ5X3BhcmEoKXsKKyAgaW50IHJlOworICBpZihyZT1RdWVyeShQX1BBUkEpKXJldHVybiByZTsKKyAgaWYoc2l6ZW9mKHJlZ2V4cCgoe29iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpfSksIi4qXFxeMCQiKSkpCisgICAgICByZXR1cm4gLTE7CisgIHJldHVybiB0b19pbnQoCisgICAgcmVncmVwbGFjZShvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSwiLipcXF5cKFsxLTldWzAtOV0qXCkkIiwiXFwxIiwxKSk7Cit9CisKKy8vZGllcyBpc3QgZWluIFJhdW0sIHdhciBnZXd1ZW5zY2h0IHZvbiBtZWhyZXJlbiBMZXV0ZW4uCitzdGF0dXMgSXNSb29tKCkge3JldHVybigxKTt9CmRpZmYgLS1naXQgYS9zdGQvcm9vbS9jb21tYW5kcy5jIGIvc3RkL3Jvb20vY29tbWFuZHMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41YWE3NWMzCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Jvb20vY29tbWFuZHMuYwpAQCAtMCwwICsxLDM3IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcm9vbS9jb21tYW5kcy5jIC0tIHJvb20gY29tbWFuZHMgaGFuZGxpbmcKKy8vCisvLyAkSWQ6IGNvbW1hbmRzLmMgODIwMSAyMDEyLTExLTA3IDE3OjU1OjEyWiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorCitpbmhlcml0ICIvc3RkL3RoaW5nL2NvbW1hbmRzIjsKKworLy8jZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGNvbmZpZy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKwordm9pZCBpbml0KCkgCit7CisgIDo6aW5pdCgpOworCisgIGFkZF9hY3Rpb24oImltcG9zcyIsICJzdWNoIik7CisgIGFkZF9hY3Rpb24oImltcG9zcyIsICJzdWNoZSIpOworfQorCisvKiBGdWVyIGV0d2FzIGJlc3NlcmUgRmVobGVybWVsZHVuZ2VuIGFscyAnV2llIGJpdHRlPycgYmVpIGVpbmlnZW4gKi8KKy8qIGFsbGdlbWVpbmVuIEtvbW1hbmRvcy4JCQkJCSAgICovCitpbnQgaW1wb3NzKCkKK3sKKyAgX25vdGlmeV9mYWlsKCJEdSBzdWNoc3QsIGZpbmRlc3QgYWJlciBuaWNodHMuXG4iKTsKKyAgcmV0dXJuIDA7Cit9CmRpZmYgLS1naXQgYS9zdGQvcm9vbS9kZXNjcmlwdGlvbi5jIGIvc3RkL3Jvb20vZGVzY3JpcHRpb24uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42MGQzYjI4Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Jvb20vZGVzY3JpcHRpb24uYwpAQCAtMCwwICsxLDIyMiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHJvb20vZGVzY3JpcHRpb24uYyAtLSByb29tIGRlc2NyaXB0aW9uIGhhbmRsaW5nCisvLworLy8gJElkOiBkZXNjcmlwdGlvbi5jIDk0NjggMjAxNi0wMi0xOSAyMTowNzowNFogR2xvaW5zb24gJAorCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL2Rlc2NyaXB0aW9uIjsKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxkb29ycm9vbS5oPgorCit2b2lkIGNyZWF0ZSgpCit7CisgIDo6Y3JlYXRlKCk7CisgIFNldFByb3AoUF9OQU1FLCAiUmF1bSIpOworICBTZXRQcm9wKFBfSU5UX1NIT1JULCI8bmFtZW5sb3NlciBSYXVtPiIpOworICBTZXRQcm9wKFBfSU5UX0xPTkcsMCk7CisgIFNldFByb3AoUF9ST09NX01TRywgKHt9KSApOworICBTZXRQcm9wKFBfRlVOQ19NU0csIDApOworICBTZXRQcm9wKFBfTVNHX1BST0IsIDMwKTsKKyAgQWRkSWQoKHsicmF1bSIsICJoaWVyIn0pKTsKK30KKwordm9pZCBpbml0KCkKK3sKKyAgLy8gV2VubiBQX1JPT01fTVNHIGdlc2V0enQgb2RlciBQX0ZVTkNfTVNHIHVuZCBrZWluIENhbGxvdXQgbGFldWZ0LAorICAvLyBDYWxsb3V0IHN0YXJ0ZW4uCisgIG1peGVkIHJvb21tc2cgPSBRdWVyeVByb3AoUF9ST09NX01TRyk7CisgIGlmKCAoIChyb29tbXNnICYmIHNpemVvZihyb29tbXNnKSkgfHwKKyAgICAgICAgUXVlcnlQcm9wKFBfRlVOQ19NU0cpICkgJiYKKyAgICAgIChmaW5kX2NhbGxfb3V0KCJXcml0ZVJvb21NZXNzYWdlIik9PS0xKSkKKyAgICBjYWxsX291dCgiV3JpdGVSb29tTWVzc2FnZSIsIHJhbmRvbShRdWVyeVByb3AoUF9NU0dfUFJPQikpKTsKK30KKwordmFyYXJncyB2b2lkIEFkZFJvb21NZXNzYWdlKHN0cmluZyAqbWVzZywgaW50IHByb2IsIG1peGVkIGZ1bmMpCit7CisgIGlmIChtZXNnICYmICFwb2ludGVycChtZXNnKSkKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgIkFkZFJvb21NZXNzYWdlKCk6IHdyb25nIGFyZ3VtZW50IHR5cGUsIGV4cGVjdGVkIEFycmF5IG9yIDAsICIKKyAgICAgICJnb3QgJS4yME8iLG1lc2cpKTsKKworICAgU2V0UHJvcChQX1JPT01fTVNHLCBtZXNnKTsKKworICBpZiAocHJvYj4wKQorICAgIFNldFByb3AoUF9NU0dfUFJPQiwgcHJvYik7CisKKyAgaWYgKGZ1bmMpCisgICAgU2V0UHJvcChQX0ZVTkNfTVNHLCBmdW5jKTsKK30KKworc3RhdGljIHZvaWQgV3JpdGVSb29tTWVzc2FnZSgpCit7CisgIGludCB0aW0sIG1zZ2lkOworICBzdHJpbmcgKnJvb21fbXNnLGZ1bmM7CisgIG1peGVkICpmdW5jX21zZzsKKworICByb29tX21zZyA9IChzdHJpbmcgKilRdWVyeVByb3AoUF9ST09NX01TRyk7CisgIGZ1bmNfbXNnID0gUXVlcnlQcm9wKFBfRlVOQ19NU0cpOworICBpZiAoKCFyb29tX21zZyB8fCAhc2l6ZW9mKHJvb21fbXNnKSkgJiYgIWZ1bmNfbXNnKQorICAgIHJldHVybjsKKworICBpZiAocm9vbV9tc2cmJnNpemVvZihyb29tX21zZykpCisgIHsKKyAgICBtc2dpZCA9IHJhbmRvbShzaXplb2Yocm9vbV9tc2cpKTsKKyAgICAvLyBEZWZhdWx0d2VydGUgc2luZCBmdWVyIEFsdGNvZGUgc2Nod2llcmlnCisgICAgc2VuZF9yb29tKHRoaXNfb2JqZWN0KCksIHJvb21fbXNnW21zZ2lkXSwKKyAgICAgICAgICAgICAgTVRfTE9PS3xNVF9MSVNURU58TVRfRkVFTHxNVF9TTUVMTHwKKyAgICAgICAgICAgICAgTVNHX0RPTlRfU1RPUkV8TVNHX0RPTlRfQlVGRkVSfE1TR19ET05UX1dSQVApOworICB9CisKKyAgaWYgKGZ1bmNfbXNnKQorICB7CisgICAgaWYgKHN0cmluZ3AoZnVuY19tc2cpKQorICAgICAgZnVuYz0oc3RyaW5nKWZ1bmNfbXNnOworICAgIGVsc2UKKyAgICAgIGZ1bmM9ZnVuY19tc2dbcmFuZG9tKHNpemVvZihmdW5jX21zZykpXTsKKyAgICBpZiAoZnVuYyAmJiBmdW5jdGlvbl9leGlzdHMoZnVuYykpCisgICAgICBjYWxsX290aGVyICh0aGlzX29iamVjdCgpLCBmdW5jLCBtc2dpZCk7CisgIH0KKworICB3aGlsZSAocmVtb3ZlX2NhbGxfb3V0KCJXcml0ZVJvb21NZXNzYWdlIikhPS0xKTsKKyAgdGltPVF1ZXJ5UHJvcChQX01TR19QUk9CKTsKKyAgaWYodGhpc19vYmplY3QoKSAmJiBzaXplb2YoZmlsdGVyKAorICAgICAgIGRlZXBfaW52ZW50b3J5KHRoaXNfb2JqZWN0KCkpLCAjJ2ludGVyYWN0aXZlKSkpIC8vJykpKQorICAgIGNhbGxfb3V0KCJXcml0ZVJvb21NZXNzYWdlIiwgKHRpbTwxNSA/IDE1IDogdGltKSk7Cit9CisKK3ZhcmFyZ3Mgc3RyaW5nIGludF9sb25nKG1peGVkIHZpZXdlcixtaXhlZCB2aWV3cG9pbnQsaW50IGZsYWdzKQoreworICBzdHJpbmcgZGVzY3IsIGludl9kZXNjcjsKKworICBmbGFncyAmPSAzOworICBpZiggSVNfTEVBUk5FUih2aWV3ZXIpICYmIHZpZXdlci0+UXVlcnlQcm9wKCBQX1dBTlRTX1RPX0xFQVJOICkgKQorICAgIGRlc2NyID0gIlsiICsgb2JqZWN0X25hbWUoTUUpICsgIl1cbiI7CisgIGVsc2UKKyAgICBkZXNjciA9ICIiOworCisgIGRlc2NyICs9IHByb2Nlc3Nfc3RyaW5nKFF1ZXJ5UHJvcChQX0lOVF9MT05HKXx8IiIpOworICAKKyAgLy8gZ2dmLiBUdWVyZW4gaGluenVmdWVnZW4uCisgIGlmIChRdWVyeVByb3AoUF9ET09SX0lORk9TKSkgeworICAgIHN0cmluZyB0bXA9KChzdHJpbmcpY2FsbF9vdGhlcihET09SX01BU1RFUiwibG9va19kb29ycyIpKTsKKyAgICBpZiAoc3RyaW5ncCh0bXApICYmIHNpemVvZih0bXApKQorICAgICAgICBkZXNjciArPSB0bXA7CisgIH0KKyAgCisgIC8vIGdnZi4gQXVzZ2FlbmdlIGhpbnp1ZnVlZ2VuLgorICBpZiAoIHZpZXdlci0+UXVlcnlQcm9wKFBfU0hPV19FWElUUykgJiYgKCFRdWVyeVByb3AoUF9ISURFX0VYSVRTKSAKKwl8fCBwb2ludGVycChRdWVyeVByb3AoUF9ISURFX0VYSVRTKSkpICkKKyAgICBkZXNjciArPSBHZXRFeGl0cyh2aWV3ZXIpIHx8ICIiOworCisgIC8vIFZpZXdwb2ludCAoT2JqZWt0IG9kZXIgT2JqZWt0YXJyYXkpIHNpbmQgbmljaHQgc2ljaHRiYXIKKyAgaW52X2Rlc2NyID0gKHN0cmluZykgbWFrZV9pbnZsaXN0KHZpZXdlciwgYWxsX2ludmVudG9yeShNRSkgCisJCSAgLSAocG9pbnRlcnAodmlld3BvaW50KT92aWV3cG9pbnQ6KHt2aWV3cG9pbnR9KSkgLGZsYWdzKTsKKworICBpZiAoIGludl9kZXNjciAhPSAiIiApCisgICAgZGVzY3IgKz0gaW52X2Rlc2NyOworCisgIGlmKGVudmlyb25tZW50KCkgJiYgKGludl9kZXNjcj1RdWVyeVByb3AoUF9UUkFOU1BBUkVOVCkpKQorICB7CisgICAgaWYoc3RyaW5ncChpbnZfZGVzY3IpKSBkZXNjciArPSBpbnZfZGVzY3I7CisgICAgZWxzZSAgICAgICAgICAgICAgICAgICBkZXNjciArPSAiQXVzc2VyaGFsYiBzaWVoc3QgRHU6XG4iOworICAgICAgICAgICAgCisgICAgZGVzY3IgKz0gZW52aXJvbm1lbnQoKS0+aW50X3Nob3J0KHZpZXdlcixNRSk7CisgIH0KKyAgICAgICAgICAgICAgICAgIAorICByZXR1cm4gZGVzY3I7Cit9CisKK3N0cmluZyBpbnRfc2hvcnQobWl4ZWQgdmlld2VyLG1peGVkIHZpZXdwb2ludCkKK3sKKyAgc3RyaW5nIGRlc2NyLCBpbnZfZGVzY3I7CisKKyAgZGVzY3IgPSBwcm9jZXNzX3N0cmluZyggUXVlcnlQcm9wKFBfSU5UX1NIT1JUKXx8IiIpOworICBpZiggSVNfTEVBUk5FUih2aWV3ZXIpICYmIHZpZXdlci0+UXVlcnlQcm9wKCBQX1dBTlRTX1RPX0xFQVJOICkgKQorICAgIGRlc2NyICs9ICIgWyIgKyBvYmplY3RfbmFtZShNRSkgKyAiXS5cbiI7CisgIGVsc2UKKyAgICBkZXNjciArPSAiLlxuIjsKKworICBpZiAoICggdmlld2VyLT5RdWVyeVByb3AoUF9TSE9XX0VYSVRTKQorICAgICAgICAgfHwgKCBlbnZpcm9ubWVudCh2aWV3ZXIpID09IE1FICYmICF2aWV3ZXItPlF1ZXJ5UHJvcChQX0JSSUVGKSApICkKKyAgICAgICAmJiAoIVF1ZXJ5UHJvcChQX0hJREVfRVhJVFMpIHx8IHBvaW50ZXJwKFF1ZXJ5UHJvcChQX0hJREVfRVhJVFMpKSkgKQorICAgIGRlc2NyICs9IEdldEV4aXRzKHZpZXdlcikgfHwgIiI7CisgIAorICAvLyBWaWV3cG9pbnQgKE9iamVrdCBvZGVyIE9iamVrdGFycmF5KSBzaW5kIG5pY2h0IHNpY2h0YmFyCisgIGludl9kZXNjciA9IChzdHJpbmcpIG1ha2VfaW52bGlzdCggdmlld2VyLCBhbGxfaW52ZW50b3J5KE1FKSAKKwkJICAtIChwb2ludGVycCh2aWV3cG9pbnQpP3ZpZXdwb2ludDooe3ZpZXdwb2ludH0pKSApOworCisgIGlmICggaW52X2Rlc2NyICE9ICIiICkKKyAgICBkZXNjciArPSBpbnZfZGVzY3I7CisKKyAgcmV0dXJuIGRlc2NyOworfQorCisvKiogUm9vbW1lc3NhZ2VzIGFic2NoYWx0ZW4sIHdlbm4ga2VpbmUgSW50ZXJhY3RpdmVzIG1laHIgZGEgc2luZC4KKyAgKi8KKy8vIFRPRE86IElyZ2VuZHdhbm4gZGFzIHZhcmFyZ3MgbG9zd2VyZGVuLCB3ZW5uIGluIGRlciByZXN0bGljaGVuIE11ZGxpYgorLy8gVE9ETzo6ZXhpdCgpICdyaWNodGlnJyB1ZWJlcnNjaHJpZWJlbiB3aXJkLgordmFyYXJncyB2b2lkIGV4aXQob2JqZWN0IGxpdiwgb2JqZWN0IGRlc3QpIHsKKyAgLy8gZmFsbCBlcmJlbmRlIE9iamVrdGUgZGFzIGxpdiBuaWNodCB1ZWJlcmdlYmVuLiBQcnVlZnVuZyBudXIgYXVmCisgIC8vIHByZXZpb3VzX29iamVjdCgpLiBXZW5uIE1hZ2llciBkYSBub2NoIGlyZ2VuZHdlbGNoZSBTcGllbGNoZW4gbWl0CisgIC8vIGNhbGxfb3RoZXIoKSAmIENvIHRyZWliZW4sIGhhYmVuIHdpciBQZWNoIGdlaGFidCwgbWFjaHQgYWJlciBuaWNodCB2aWVsLAorICAvLyB3ZWlsIGRpZSBSYXVtbWVsZHVuZ2VuIGRhbm4gaW0gbmFlY2hzdGVuIGNhbGxvdXQgYWJnZXNjaGFsdGV0IHdlcmRlbi4KKyAgaWYgKCFsaXZpbmcobGl2PXByZXZpb3VzX29iamVjdCgpKSkgcmV0dXJuOworCisgIG9iamVjdCAqaW50ZXJhY3RpdmVzID0gZmlsdGVyKGFsbF9pbnZlbnRvcnkoKSwgIydpbnRlcmFjdGl2ZSk7CisgIC8vIGxpdiB3dXJkZSBub2NoIG5pY2h0IGJld2VndCwgZ2dmLiBiZXJ1ZWNrc2ljaHRpZ2VuLgorICBpZiAoICFzaXplb2YoaW50ZXJhY3RpdmVzKSB8fAorICAgICAgKGludGVyYWN0aXZlKGxpdikgJiYgc2l6ZW9mKGludGVyYWN0aXZlcykgPCAyKSApCisgICAgd2hpbGUgKHJlbW92ZV9jYWxsX291dCgiV3JpdGVSb29tTWVzc2FnZSIpIT0tMSk7Cit9CisKK3N0YXRpYyBzdHJpbmcgX3F1ZXJ5X2ludF9sb25nKCkge3JldHVybiBRdWVyeShQX0lOVF9MT05HLCBGX1ZBTFVFKTt9CisKKworLy8gUXVlcnltZXRob2RlIGZ1ZXIgUF9ET01BSU4gLSBnaWJ0IGRpZSBSZWdpb24gYW4sIGluIGRlciBSYXVtIGxpZWd0LCBzb2Zlcm4KKy8vIGVyIHVudGVyIC9kLyBsaWVndC4uLgorc3RhdGljIHN0cmluZyBfcXVlcnlfbGliX3BfZG9tYWluKCkKK3sKKyAgc3RyaW5nIGZuID0gb2JqZWN0X25hbWUoKTsKKyAgaWYgKHN0cnN0cihmbiwgIi9kLyIpID09IDApCisgIHsKKyAgICByZXR1cm4gY2FwaXRhbGl6ZShleHBsb2RlKGZuLCAiLyIpWzJdKTsKKyAgfQorCisgIHJldHVybiAidW5iZWthbm50IjsKK30KKworPHN0cmluZ3xzdHJpbmcqPiogX3NldF9oYXJib3VyX25hbWUoIDxzdHJpbmd8c3RyaW5nKj4qIGRlc2MpIAoreworICBpZiAoIHNpemVvZihkZXNjKSE9MiApCisgIHsKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJVbmFjY2VwdGFibGUgZGF0YSBpbiBQX0hBUkJPVVIsIHNpemVvZigpIHdhcyAlZCwgIgorICAgICAgImV4cGVjdGVkIDIuIiwgc2l6ZW9mKGRlc2MpKSk7CisgIH0KKyAgZWxzZSBpZiAoICFzdHJpbmdwKGRlc2NbMF0pICkKKyAgeworICAgIHJhaXNlX2Vycm9yKCJXcm9uZyBkYXRhIHR5cGUgaW4gUF9IQVJCT1VSWzBdOiBleHBlY3RlZCAnc3RyaW5nJy4iKTsKKyAgfQorICBlbHNlIGlmICggcG9pbnRlcnAoZGVzY1sxXSkgJiYgc2l6ZW9mKGRlc2NbMV0pPDEgKQorICB7CisgICAgcmFpc2VfZXJyb3IoIkluc3VmZmljaWVudCBkYXRhIGluIFBfSEFSQk9VUlsxXTogZXhwZWN0ZWQgJ3N0cmluZyonLCAiCisgICAgICAiZ290ICcoe30pJy4iKTsKKyAgfQorICBlbHNlIGlmICggc3RyaW5ncChkZXNjWzFdKSApCisgIHsKKyAgICBkZXNjWzFdID0gKHtkZXNjWzFdfSk7CisgIH0KKyAgcmV0dXJuIFNldChQX0hBUkJPVVIsIGRlc2MsIEZfVkFMVUUpOworfQorCmRpZmYgLS1naXQgYS9zdGQvcm9vbS9kb29ycy5jIGIvc3RkL3Jvb20vZG9vcnMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMDVmMDA5Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Jvb20vZG9vcnMuYwpAQCAtMCwwICsxLDE2MiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHJvb20vZG9vcnMuYyAtLSBuZXcgZG9vcnMsIG1hbmFnZWQgYnkgZG9vcm1hc3RlcgorLy8KKy8vICRJZDogZG9vcnMuYyA5MTM0IDIwMTUtMDItMDIgMTk6MjY6MDNaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisKKyNpbmNsdWRlIDxjb25maWcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8ZG9vcnJvb20uaD4KKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHJvb20vZXhpdHMuaD4KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgaWYgKG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpID09IF9fRklMRV9fWzAuLjwzXSkKKyAgeworICAgIHNldF9uZXh0X3Jlc2V0KC0xKTsKKyAgICByZXR1cm47CisgIH0KKyAgU2V0UHJvcChQX0RPT1JfSU5GT1MsMCk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCit2YXJhcmdzIGludCBOZXdEb29yKHN0cmluZ3xzdHJpbmcqIGNtZHMsIHN0cmluZyBkZXN0LCBzdHJpbmd8c3RyaW5nKiBpZHMsCisgICAgICAgICAgICAgICAgICAgIG1hcHBpbmd8PGludHxzdHJpbmd8c3RyaW5nKj4qIHByb3BzKQoreworLyoKKyAgY21kczogQmVmZWhsKGUpLCB1bSBkdXJjaCBkaWUgVHVlciB6dSBnZWhlbiAoU3RyaW5nIG9kZXIgQXJyYXkgdm9uIFN0cmluZ3MpCisgIGRlc3Q6IFppZWxyYXVtCisgIGlkczogIElkKHMpIGRlciBUdWVyLCBkZWZhdWx0ICJ0dWVyIiAoU3RyaW5nLCBBcnJheSB2b24gU3RyaW5ncyBvZGVyIDApCisgIHByb3BzOiBiZXNvbmRlcmUgRWlnZW5zY2hhZnRlbiBkZXIgVHVlciAob3B0aW9uYWwpCisgIEFycmF5IG1pdCBQYWFyZW4gTnVtbWVyIGRlciBFaWdlbnNjaGFmdCwgSW5oYWx0CisgIGRlZmluaWVydGUgUHJvcGVydGllcyBzaW5kOgorICBEX0ZMQUdTOiAgRmxhZ3Mgd2llIGJlaSBTaXIncyBUdWVyZW4KKyAgZGVmYXVsdDogRE9PUl9DTE9TRUQgfCBET09SX1JFU0VUX0NMCisgIEJlaSBTY2hsdWVzc2VsbiB3aXJkIGdldGVzdGV0LCBvYiBkZXIgU3RyaW5nLCBkZW4KKyAgUXVlcnlEb29yS2V5IHp1cnVlY2tsaWVmZXJ0LCBnbGVpY2gKKyAgInJhdW1uYW1lMTpyYXVtbmFtZTIiIGlzdCwgd29iZWkgcmF1bW5hbWUxLDIgZGllCisgIGtvbXBsZXR0ZW4gRmlsZW5hbWVuIGRlciBiZWlkZW4gUmFldW1lIGluIHNvcnRpZXJ0ZXIKKyAgUmVpaGVuZm9sZ2Ugc2luZC4KKyAgRF9MT05HOiAgIGxhbmdlIEJlc2NocmVpYnVuZyBkZXIgVHVlcgorICBkZWZhdWx0OiAiRWluZSBUdWVyLlxuIgorICBEX1NIT1JUOiAga3VyemUgQmVzY2hyZWlidW5nIGRlciBUdWVyLCB3aXJkIGFuIGRpZSBSYXVtYmVzY2hyZWlidW5nCisgIGFuZ2VmdWVndCwgd29iZWkgJXMgZHVyY2ggZ2VvZWZmbmV0IGJ6dy4gZ2VzY2hsb3NzZW4KKyAgZXJzZXR6dCB3aXJkLgorICBkZWZhdWx0OiAiRWluZSAlc2UgVHVlci4gIgorICBEX05BTUU6ICAgTmFtZSwgZGVyIGJlaW0gT2VmZm5lbi9TY2hsaWVzc2VuIHVuZCBiZWkgRmVobGVybWVsZHVuZ2VuCisgIGFuZ2V6ZWlndCB3aXJkLgorICBkZWZhdWx0OiAiVHVlciIKKyAgRF9HRU5ERVI6IGRlZmF1bHQ6IEZFTUFMRQorICBEX0ZVTkM6ICAgRnVua3Rpb24sIGRpZSBpbSBSYXVtIGF1ZmdlcnVmZW4gd2VyZGVuIHNvbGwsIHdlbm4gZGllCisgIFR1ZXIgZXJmb2xncmVpY2ggZHVyY2hzY2hyaXR0ZW4gd2lyZC4KKyAgZGVmYXVsdDogMAorICBEX01TR1M6ICAgRmFsbHMgU3RyaW5nOiBhdXNnZWdlYmVuZSBSaWNodHVuZyBmdWVyIG1vdmUKKyAgRmFsbHMgQXJyYXk6ICh7ZGlyZWN0aW9uLCB0ZXh0b3V0LCB0ZXh0aW59KSBmdWVyIG1vdmUKKyAgZGVmYXVsdDogMAorCisgIEJlaXNwaWVsOgorICBOZXdEb29yKCJub3JkZW4iLCIvcGxheWVycy9yb2NodXMvcm9vbS90ZXN0MiIsInBvcnRhbCIsCisgICh7RF9OQU1FLCJQb3J0YWwiLAorICBEX0dFTkRFUixORVVURVIsCisgIERfU0hPUlQsIkltIE5vcmRlbiBzaWVoc3QgRHUgZWluICVzZXMgUG9ydGFsLiAiLAorICBEX0xPTkcsIkRhcyBQb3J0YWwgaXN0IGVpbmZhY2ggbnVyIGdpZ2FudGlzY2guXG4iCisgIH0pKTsKKworKi8KKworICBpZiAoIWNtZHMgfHwgIWRlc3QpIHJldHVybiAwOworICByZXR1cm4gY2FsbF9vdGhlcihET09SX01BU1RFUiwiTmV3RG9vciIsY21kcyxkZXN0LGlkcyxwcm9wcyk7Cit9CisKK3ZvaWQgaW5pdCgpCit7CisgIG1peGVkICppbmZvOworICBzdHJpbmcgKmNtZHM7CisgIGludCBpLGo7CisKKyAgaWYgKCFwb2ludGVycChpbmZvPShtaXhlZCAqKVF1ZXJ5UHJvcChQX0RPT1JfSU5GT1MpKSkgcmV0dXJuOworICBhZGRfYWN0aW9uKCJvZWZmbmVuIiwib2VmZm5lIik7CisgIGFkZF9hY3Rpb24oInNjaGxpZXNzZW4iLCJzY2hsaWVzc2UiKTsKKyAgYWRkX2FjdGlvbigic2NobGllc3NlbiIsInNjaGxpZXNzIik7CisgIGZvciAoaT1zaXplb2YoaW5mbyktMTtpPj0wO2ktLSkgeworICAgIGNtZHM9KHN0cmluZyAqKShpbmZvW2ldW0RfQ01EU10pOworICAgIGZvciAoaj1zaXplb2YoY21kcyktMTtqPj0wO2otLSkKKyAgICAgIGFkZF9hY3Rpb24oImdvX2Rvb3IiLGNtZHNbal0pOworICAgIC8vIEJlZmVobGUgSU1NRVIgYW5mdWVnZW4sIGdlY2hlY2tlZCB3aXJkIHNvd2llc28gZXJzdCBiZWltIER1cmNoZ2VoZW4uCisgIH0KK30KKwordm9pZCByZXNldCgpCit7CisgIGlmIChRdWVyeVByb3AoUF9ET09SX0lORk9TKSkKKyAgICBjYWxsX290aGVyKERPT1JfTUFTVEVSLCJyZXNldF9kb29ycyIpOworfQorCitpbnQgb2VmZm5lbiAoc3RyaW5nIHN0cikKK3sKKyAgaWYgKCFzdHIgfHwgIVF1ZXJ5UHJvcChQX0RPT1JfSU5GT1MpKQorICAgIHJldHVybiAwOworICByZXR1cm4gKGludCkgY2FsbF9vdGhlcihET09SX01BU1RFUiwib2VmZm5lbiIsc3RyKTsKK30KKworaW50IHNjaGxpZXNzZW4gKHN0cmluZyBzdHIpCit7CisgIGlmICghc3RyIHx8ICFRdWVyeVByb3AoUF9ET09SX0lORk9TKSkKKyAgICByZXR1cm4gMDsKKyAgcmV0dXJuIChpbnQpIGNhbGxfb3RoZXIoRE9PUl9NQVNURVIsInNjaGxpZXNzZW4iLHN0cik7Cit9CisKK3ZhcmFyZ3MgaW50Citnb19kb29yIChzdHJpbmcgc3RyKQoreworICBpZiAoIVF1ZXJ5UHJvcChQX0RPT1JfSU5GT1MpKQorICAgIHJldHVybiAwOworICBpZiAoY2FsbF9vdGhlcihET09SX01BU1RFUiwiZ29fZG9vciIscXVlcnlfdmVyYigpKSkKKyAgICByZXR1cm4gMTsKKyAgcmV0dXJuIDA7Cit9CisKK2ludCBzZXRfZG9vcnMoc3RyaW5nICpjbWRzLGludCBvcGVuKQoreworICBpbnQgajsKKyAgCisgIGlmICghcHJldmlvdXNfb2JqZWN0KCkpCisgICAgcmV0dXJuIDA7CisgIGlmIChvYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSkhPURPT1JfTUFTVEVSKQorICAgIHJldHVybiAwOworICAvLyBBbmRlcmUgc29sbGVuIG5pY2h0IHJ1bXBmdXNjaGVuLgorICBpZiAoIXRoaXNfcGxheWVyKCkpIHJldHVybiAwOworICBpZiAoZW52aXJvbm1lbnQodGhpc19wbGF5ZXIoKSkhPXRoaXNfb2JqZWN0KCkpCisgICAgcmV0dXJuIDA7CisgIC8vIElzdCBzb3dpZXNvIGtlaW5lciBkYS4uLgorICBpZiAoIXBvaW50ZXJwKGNtZHMpKQorICAgIHJldHVybiAwOworICBpZiAob3BlbikKKyAgICBBZGRTcGVjaWFsRXhpdChjbWRzLCJnb19kb29yIik7CisgIGVsc2UKKyAgICBSZW1vdmVTcGVjaWFsRXhpdChjbWRzKTsKKyAgZm9yIChqPXNpemVvZihjbWRzKS0xO2o+PTA7ai0tKQorICAgIGFkZF9hY3Rpb24oImdvX2Rvb3IiLGNtZHNbal0pOworICByZXR1cm4gMTsKK30KKworLyogRnVlciBUdWVyZW4sIGRpZSBmbGV4aWJsZSBMYW5nYmVzY2hyZWlidW5nZW4gaGFiZW4sIHdpcmQgZWluIAorICogU3BlY2lhbERldGFpbCBlaW5nZWZ1ZWhydC4KKyAqLworCitzdHJpbmcgc3BlY2lhbF9kZXRhaWxfZG9vcnMoc3RyaW5nIGtleSl7CisgIHJldHVybiBET09SX01BU1RFUi0+c3BlY2lhbF9kZXRhaWxfZG9vcnMoa2V5KTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9yb29tL2V4aXRzLmMgYi9zdGQvcm9vbS9leGl0cy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRjNzI0YjgKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9leGl0cy5jCkBAIC0wLDAgKzEsMzM0IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcm9vbS9leGl0cy5jIC0tIHJvb20gZXhpdHMgaGFuZGxpbmcgCisvLworLy8gJElkOiBleGl0cy5jIDk0OTcgMjAxNi0wMi0yMSAxNDoyMDowM1ogWmVzc3RyYSAkCisKKy8qCisgKiBFeGl0cyBvZiB0aGUgcm9vbSAob2J2aW91cyBvbmVzLCBkb29ycywgYW5kIHNwZWNpYWwgb25lcykKKyAqIHdlIGRlZmluZSB0aGUgZm9sbG93aW5nIGZ1bmN0aW9uIGZvciBlYXN5IHJlZmVyZW5jZToKKyAqIEdldEV4aXRzKCkgLSByZXR1cm4gYSBzdHJpbmcgY29udGFpbmluZyBhbiAiT2J2aW91cyBFeGl0cyIgU3RhdGVtZW50CisgKgorICogVGhlIGV4aXRzIGFyZSBpbXBsZW1lbnRlZCBhcyBwcm9wZXJ0aWVzIFBfRVhJVFMKKyAqIFRoZXkgYXJlIHN0b3JlZCBsb2NhbGx5IChfc2V0X3h4LCBfcXVlcnlfeHgpCisgKiBhcyBtYXBwaW5nIHRvIHNwZWVkIHVwIHRoZSByb3V0aW5lcyBpbiB0aGlzIG1vZHVsZS4KKyAqCisgKi8KKworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxyb29tL2V4aXRzLmg+CisjaW5jbHVkZSA8aG9vay5oPgorI2luY2x1ZGUgPGV4cGxvcmF0aW9uLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDxzeXNfZGVidWcuaD4KKyNpbmNsdWRlIDxjb25maWcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPGRhZW1vbi5oPgorI2luY2x1ZGUgPGRvb3Jyb29tLmg+CisjaW5jbHVkZSA8cm91dGluZ2QuaD4KKworI2RlZmluZSBOVU1CRVJTICh7ICJ6d2VpIiwgImRyZWkiLCAidmllciIsICJmdWVuZiIsICJzZWNocyIsICJzaWViZW4iLCAiYWNodCIgfSkKKworCisvLyBIaWxmc2Z1bmt0aW9uLCBkaWUgYmVpIGthcHV0dGVuIEV4aXRzIGVpbmUgTm90cmV0dHVuZyBiZXRyZWlidCwgYWJlcgorLy8gdHJvdHpkZW0gYXVmIERlYnVnIGVpbmUgTWVsZHVuZyBtYWNodC4KK3N0YXRpYyBtYXBwaW5nIHJlc2N1ZUV4aXQoKQoreworICBjYXRjaChyYWlzZV9lcnJvcihzcHJpbnRmKAorCSAgInJvb20vZXhpdHMuYzogRm9yZ290dGVuIDo6Y3JlYXRlKCk/ICIKKwkgICJQX0VYSVRTIGluICVPIGlzIDAhXG4iLCB0aGlzX29iamVjdCgpKSk7cHVibGlzaCk7IAorCisgIHJldHVybiAoWzoyXSk7Cit9CisKKworc3RhdGljIG1hcHBpbmcgX3NldF9leGl0cyggbWFwcGluZyBtYXBfbGRmaWVkICkgCit7CisgICAgaWYoIG1hcHBpbmdwKG1hcF9sZGZpZWQpICkKKyAgICAgICAgcmV0dXJuIFNldCggUF9FWElUUywgbWFwX2xkZmllZCApOworICAgIHJldHVybiAwOworfQorCisKK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV9leGl0cygpIAoreworICAgIGlmKCAoIXByZXZpb3VzX29iamVjdCgpIHx8IG9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSAhPSBET09SX01BU1RFUikKKyAgICAgICAgJiYgUXVlcnlQcm9wKFBfRE9PUl9JTkZPUykgKQorICAgICAgICBjYWxsX290aGVyKCBET09SX01BU1RFUiwgImluaXRfZG9vcnMiICk7CisKKyAgICBtYXBwaW5nIGV4aXRzID0gUXVlcnkoUF9FWElUUykgfHwgcmVzY3VlRXhpdCgpOworCisgICAgcmV0dXJuIGZpbHRlcihleGl0cywgZnVuY3Rpb24gaW50IChzdHJpbmcga2V5LCBtaXhlZCB2YWwpCisgICAgICAgIHtyZXR1cm4gc3RyaW5ncCh2YWxbMF0pO30gKTsKK30KKworCitzdGF0aWMgaW50IF9zZXRfc3BlY2lhbF9leGl0cyggbWFwcGluZyBtYXBfbGRmaWVkICkKK3sKKyAgICByZXR1cm4gLTE7Cit9CisKKworc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X3NwZWNpYWxfZXhpdHMoKSAKK3sKKyAgICBtYXBwaW5nIGV4aXRzID0gUXVlcnkoUF9FWElUUykgfHwgcmVzY3VlRXhpdCgpOworCisgICAgcmV0dXJuIGZpbHRlcihleGl0cywgZnVuY3Rpb24gaW50IChzdHJpbmcga2V5LCBtaXhlZCB2YWwpCisgICAgICAgIHtyZXR1cm4gY2xvc3VyZXAodmFsWzBdKTt9ICk7Cit9CisKKwordm9pZCByZXNldCgpCit7fQorCisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIG9mZmVySG9vayhIX0hPT0tfRVhJVF9VU0UsIDEpOworICBTZXRQcm9wKCBQX0VYSVRTLCAoWzoyXSkgKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIF9BZGRFeGl0KHN0cmluZ3xzdHJpbmcqIGNtZCwgc3RyaW5nfGNsb3N1cmUgcm9vbSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyBtZXNzYWdlKQoreworICBtYXBwaW5nIGV4aXRhOworCisgIGV4aXRhID0gUXVlcnkoUF9FWElUUykgfHwgcmVzY3VlRXhpdCgpOworCisgIGlmICggIWNsb3N1cmVwKHJvb20pICkKKyAgeworICAgIG9iamVjdCByb3V0ZXI7CisKKyAgICByb29tID0gX01ha2VQYXRoKHJvb20pOworCisgICAgaWYgKCAhY2xvbmVwKHRoaXNfb2JqZWN0KCkpICYmIG9iamVjdHAocm91dGVyID0gZmluZF9vYmplY3QoUk9VVEVSKSkgKQorICAgIHsKKyAgICAgIHJvdXRlci0+UmVnaXN0ZXJFeGl0KCBvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSwgY21kLCByb29tICk7CisgICAgfQorICB9CisKKyAgaWYoIHN0cmluZ3AoY21kKSApCisgIHsKKyAgICBleGl0YSArPSAoWyBjbWQgOiByb29tOyBtZXNzYWdlIF0pOworICB9CisgIGVsc2UKKyAgeworICAgIGZvcmVhY2goc3RyaW5nIGMgOiBjbWQpCisgICAgeworICAgICAgaWYgKHN0cmluZ3AoYykpCisgICAgICAgIGV4aXRhICs9IChbIGMgOiByb29tOyBtZXNzYWdlIF0pOworICAgIH0KKyAgfQorCisgIFNldCggUF9FWElUUywgZXhpdGEgKTsKK30KKwordm9pZCBBZGRFeGl0KHN0cmluZ3xzdHJpbmcqIGNtZCwgY2xvc3VyZXxzdHJpbmcgZGVzdCkKK3sKKyAgc3RyaW5nIG1zZzsKKyAgaWYgKCBzdHJpbmdwKGRlc3QpICkKKyAgeworICAgIGludCBzOworICAgIGlmKCAocyA9IG1lbWJlcihkZXN0LCAnIycpKSAhPSAtMSApCisgICAgeworICAgICAgbXNnICA9IGRlc3RbMC4ucy0xXTsKKyAgICAgIGRlc3QgPSBkZXN0W3MrMS4uXTsKKyAgICB9CisgIH0KKyAgX0FkZEV4aXQoY21kLCBkZXN0LCBtc2cpOworfQorCit2b2lkIFJlbW92ZUV4aXQoc3RyaW5nfHN0cmluZyogY21kICkKK3sKKyAgICBtYXBwaW5nIGV4aXRhOworCisgICAgaWYgKCAhY21kICkgeworICAgICAgICBTZXRQcm9wKFBfRVhJVFMsIChbOjJdKSApOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKCBzdHJpbmdwKGNtZCkgKQorICAgICAgICBjbWQgPSAoeyBjbWQgfSk7CisKKyAgICBleGl0YSA9IFF1ZXJ5KFBfRVhJVFMsIEZfVkFMVUUpIHx8IHJlc2N1ZUV4aXQoKTsKKyAgICBmb3JlYWNoKHN0cmluZyBjIDogY21kKQorICAgICAgbV9kZWxldGUoIGV4aXRhLCBjICk7CisKKyAgICBTZXQoIFBfRVhJVFMsIGV4aXRhLCBGX1ZBTFVFICk7Cit9CisKKwordm9pZCBBZGRTcGVjaWFsRXhpdChzdHJpbmd8c3RyaW5nKiBjbWQsIHN0cmluZ3xjbG9zdXJlIGZ1bmN0aW9ubmFtZSApCit7CisKKyAgICBpZiAoIHN0cmluZ3AoZnVuY3Rpb25uYW1lKSApCisgICAgICAgIGZ1bmN0aW9ubmFtZSA9IHN5bWJvbF9mdW5jdGlvbiggZnVuY3Rpb25uYW1lLCB0aGlzX29iamVjdCgpICk7CisKKyAgICBpZiAoICFjbG9zdXJlcChmdW5jdGlvbm5hbWUpICkKKyAgICB7CisgICAgICAgIGNhdGNoKHJhaXNlX2Vycm9yKHNwcmludGYoICJtZXRob2QgJU8gZG9lc24ndCBleGlzdFxuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb25uYW1lKSk7IHB1Ymxpc2gpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgQWRkRXhpdCggY21kLCBmdW5jdGlvbm5hbWUgKTsKK30KKworCit2b2lkIFJlbW92ZVNwZWNpYWxFeGl0KHN0cmluZ3xzdHJpbmcqIGNtZCkKK3sKKyAgICBSZW1vdmVFeGl0KCBjbWQgKTsKK30KKworCit2YXJhcmdzIHN0cmluZyBHZXRFeGl0cyggb2JqZWN0IHZpZXdlciApIAoreworICAgIHN0cmluZyAqaW5kaWNlcywgKmhpZGRlbjsKKyAgICBzdHJpbmcgZXhpdHM7CisKKyAgICBpZiAoIFF1ZXJ5UHJvcChQX0RPT1JfSU5GT1MpICkKKyAgICAgICAgY2FsbF9vdGhlciggRE9PUl9NQVNURVIsICJpbml0X2Rvb3JzIiApOworCisgICAgaW5kaWNlcyA9IG1faW5kaWNlcyggUXVlcnkoUF9FWElUUykgfHwgcmVzY3VlRXhpdCgpICk7CisgICAgCisgICAgaWYgKCBwb2ludGVycChoaWRkZW4gPSBRdWVyeVByb3AoUF9ISURFX0VYSVRTKSkgKQorICAgICAgICBpbmRpY2VzIC09IGhpZGRlbjsKKworICAgIGludCBuPXNpemVvZihpbmRpY2VzKTsKKyAgICBzd2l0Y2ggKG4pIHsKKyAgICBjYXNlIDA6CisgICAgICAgIHJldHVybiAiRXMgZ2lidCBrZWluZSBzaWNodGJhcmVuIEF1c2dhZW5nZS5cbiI7CisgICAgICAgIAorICAgIGNhc2UgMToKKyAgICAgICAgcmV0dXJuICJFcyBnaWJ0IGVpbmVuIHNpY2h0YmFyZW4gQXVzZ2FuZzogIiArIGluZGljZXNbMF0gKyAiLlxuIjsKKyAgICAgICAgCisgICAgY2FzZSAyOiBjYXNlIDM6IGNhc2UgNDogY2FzZSA1OiBjYXNlIDY6IGNhc2UgNzogY2FzZSA4OgorICAgICAgICBleGl0cyA9ICJFcyBnaWJ0ICIgKyBOVU1CRVJTW24tMl0gKyAiIHNpY2h0YmFyZSBBdXNnYWVuZ2U6ICI7CisgICAgICAgIGJyZWFrOworICAgICAgICAKKyAgICBkZWZhdWx0OgorICAgICAgICBleGl0cyA9ICJFcyBnaWJ0IHZpZWxlIHNpY2h0YmFyZSBBdXNnYWVuZ2U6ICI7CisgICAgfQorICAgIGV4aXRzICs9IENvdW50VXAoaW5kaWNlcyk7CisgICAgcmV0dXJuIGJyZWFrX3N0cmluZyggZXhpdHMrIi4iLCA3OCApOworfQorCisKKy8vIFJpY2h0dW5nc2JlZmVobGUgbnVyIGludGVycHJldGllcmVuLCB3ZW5uIGRlciBTcGllbGVyICppbSogUmF1bSBzdGVodCB1bmQKKy8vIG5pY2h0IGRhdm9yIChUcmFuc3BvcnRlciBldGMuKS9vCit2b2lkIGluaXQoKQoreworICAgIGlmICggZW52aXJvbm1lbnQodGhpc19wbGF5ZXIoKSkgPT0gdGhpc19vYmplY3QoKSApCisgICAgICAgIGFkZF9hY3Rpb24oICJfbm9ybWFsZnVuY3Rpb24iLCAiIiwgMSApOworfQorCisKKy8qIG5vdCBvbmx5IG5vcm1hbCBleGl0cyBhcmUgaGFuZGxlZCBoZXJlICovCisKK2ludCBfbm9ybWFsZnVuY3Rpb24oKQoreworICBpbnQgcmV0OworICBtYXBwaW5nIGV4aXRzID0gUXVlcnkoUF9FWElUUywgRl9WQUxVRSkgfHwgKFs6M10pOworICBpZiAoIW1lbWJlcihleGl0cyxxdWVyeV92ZXJiKCkpKQorICAgIHJldHVybiAwOworCisgIHN0cmluZyB2ZXJiID0gcXVlcnlfdmVyYigpOworICBzdHJpbmcgZGVzdHJvb20gPSBleGl0c1txdWVyeV92ZXJiKCksMF07CisgIHN0cmluZyBtZXNzYWdlID0gZXhpdHNbcXVlcnlfdmVyYigpLDFdOworCisgIG1peGVkIGhyZXMgPSBIb29rRmxvdyhIX0hPT0tfRVhJVF9VU0UsICh7dmVyYiwgZGVzdHJvb20sIG1lc3NhZ2V9KSk7CisgIGlmKGhyZXMgJiYgcG9pbnRlcnAoaHJlcykgJiYgc2l6ZW9mKGhyZXMpPkhfUkVUREFUQSkKKyAgeworICAgIGlmKGhyZXNbSF9SRVRDT0RFXT09SF9DQU5DRUxMRUQpCisgICAgeworICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIGVsc2UgaWYoaHJlc1tIX1JFVENPREVdPT1IX0FMVEVSRUQKKyAgICAgICAgICAgICYmIHBvaW50ZXJwKGhyZXNbSF9SRVREQVRBXSkKKyAgICAgICAgICAgICYmIHNpemVvZihocmVzW0hfUkVUREFUQV0pID49IDMpCisgICAgeworICAgICAgPHN0cmluZ3xjbG9zdXJlPiogaGRhdGEgPSBocmVzW0hfUkVUREFUQV07CisgICAgICBpZiAoIXN0cmluZ3AoaGRhdGFbMF0pCisgICAgICAgICAgfHwgKCFzdHJpbmdwKGhkYXRhWzFdKSAmJiAhY2xvc3VyZXAoaGRhdGFbMV0pKQorICAgICAgICAgIHx8IChoZGF0YVsyXSAmJiAhc3RyaW5ncChoZGF0YVsyXSkpICkKKyAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiSW52YWxpZGUgRGF0ZW4gYXVzIEhfSE9PS19FWElUX1VTRTogJS4xNTBPXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhkYXRhKSk7CisgICAgICB2ZXJiID0gaGRhdGFbMF07CisgICAgICBkZXN0cm9vbSA9IGhkYXRhWzFdOworICAgICAgbWVzc2FnZSA9IGhkYXRhWzJdOworICAgIH0KKyAgfQorCisgIGlmKCBjbG9zdXJlcChkZXN0cm9vbSkgKQorICB7CisgICAgcmV0ID0gZnVuY2FsbCggZGVzdHJvb20sIHZlcmIgKTsKKworICAgIGlmKHJldD09TU9WRV9PSykKKyAgICB7CisgICAgICBHaXZlRVAoIEVQX0VYSVQsIHZlcmIgKTsKKyAgICB9CisKKyAgICByZXR1cm4gcmV0OworICB9CisKKyAgaWYgKCFzdHJpbmdwKG1lc3NhZ2UpKQorICB7CisgICAgaWYoIG1lbWJlciggKHsgInN1ZWRlbiIsICJzdWVkd2VzdGVuIiwgIndlc3RlbiIsIm5vcmR3ZXN0ZW4iLCAibm9yZGVuIiwKKyAgICAgICAgIm5vcmRvc3RlbiIsICJvc3RlbiIsInN1ZWRvc3RlbiIgfSksIHZlcmIgKSAhPSAtMSApCisgICAgeworICAgICAgbWVzc2FnZSA9ICJuYWNoICIgKyBjYXBpdGFsaXplKHZlcmIpOworICAgIH0KKyAgICBlbHNlIGlmICggbWVtYmVyKCAoeyAib2JlbiIsICJ1bnRlbiIgfSksIHZlcmIgKSAhPSAtMSApCisgICAgeworICAgICAgbWVzc2FnZSA9ICJuYWNoICIgKyB2ZXJiOworICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgbWVzc2FnZSA9IHZlcmI7CisgICAgfQorICB9CisKKyAgcmV0ID0gdGhpc19wbGF5ZXIoKS0+bW92ZSggZGVzdHJvb20sIE1fR08sIG1lc3NhZ2UgKTsKKworICBpZiAocmV0PT1NT1ZFX09LKQorICB7CisgICAgR2l2ZUVQKCBFUF9FWElULCB2ZXJiICk7CisgIH0KKworICByZXR1cm4gcmV0OworfQorCitzdGF0aWMgc3RyaW5nIF9NYWtlUGF0aCggc3RyaW5nIHN0ciApCit7CisgIHN0cmluZyAqY29tcDsKKworICBjb21wID0gZXhwbG9kZSggb2JqZWN0X25hbWUodGhpc19vYmplY3QoKSksICIvIiApIC0gKHsiIn0pOworICAKKyAgIHN3aXRjaCggc3RyWzBdICl7CisgICBjYXNlICcuJzoKKyAgICAgICBzdHIgPSAiLyIgKyBpbXBsb2RlKCBjb21wWzAuLjwyXSwgIi8iICkgKyAiLyIgKyBzdHI7CisgICAgICAgYnJlYWs7CisgICAgICAgCisgICBjYXNlICd+JzoKKyAgICAgICBzdHIgPSAiLyIgKyBjb21wWzBdICsgIi8iICsgKGNvbXBbMF0gPT0gImQiID8gY29tcFsxXSArICIvIiA6ICIiKQorICAgICAgICAgICArUkVBTF9VSUQodGhpc19vYmplY3QoKSkgKyBzdHJbMS4uXTsKKyAgICAgICBicmVhazsKKyAgIH0KKyAgIAorICAgcmV0dXJuIE1BU1RFUi0+X2dldF9wYXRoKCBzdHIsIGdldHVpZCh0aGlzX29iamVjdCgpKSApOworfQorCmRpZmYgLS1naXQgYS9zdGQvcm9vbS9pdGVtcy5jIGIvc3RkL3Jvb20vaXRlbXMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xZDQwMDVhCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Jvb20vaXRlbXMuYwpAQCAtMCwwICsxLDQyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcm9vbS9pdGVtcy5jIC0tIGNyZWF0aW5nIGV4dHJhIGl0ZW1zIGluIHJvb20KKy8vCisvLyAkSWQ6IGl0ZW1zLmMgOTUzOCAyMDE2LTAzLTIwIDIzOjQ2OjQxWiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorCitpbmhlcml0ICJzdGQvY29udGFpbmVyL2l0ZW1zIjsKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3ZvaWQgcmVzZXQoKSAKK3sKKyAgOjpyZXNldCgpOworCisgIG9iamVjdCAqaW5oID0gYWxsX2ludmVudG9yeSh0aGlzX29iamVjdCgpKTsKKyAgaWYgKCAhcG9pbnRlcnAoaW5oKSB8fCBzaXplb2YoaW5oKSA8IDEwICkKKyAgICByZXR1cm47CisgIC8vIG51ciB3ZW5uIGtlaW5lIFNwaWVsZXIgYW53ZXNlbmQgc2luZC4KKyAgaWYgKCAhc2l6ZW9mKGluaCAmIHVzZXJzKCkpICkKKyAgICByZW1vdmVfbXVsdGlwbGUoMyk7Cit9CisKKy8vIFBlciBEZWZhdWx0IG51ciBhbiBhbGxlIEl0ZW1zIGltIEludmVudGFyIHdlaXRlcmxlaXRlbi4KK3B1YmxpYyB2YXJhcmdzIGludCBSZWNlaXZlTXNnKHN0cmluZyBtc2csIGludCBtc2dfdHlwZSwgc3RyaW5nIG1zZ19hY3Rpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgbXNnX3ByZWZpeCwgb2JqZWN0IG9yaWdpbikKK3sKKyAgaW50ICpyZXMgPSBhbGxfaW52ZW50b3J5KCktPlJlY2VpdmVNc2cobXNnLCBtc2dfdHlwZSwgbXNnX2FjdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbXNnX3ByZWZpeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luIHx8IHByZXZpb3VzX29iamVjdCgpKTsKKyAgaWYgKHNpemVvZihyZXMpKQorICAgIHJldHVybiBtaW4ocmVzKTsKKyAgcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9yb29tL2tyYWV1dGVyLmMgYi9zdGQvcm9vbS9rcmFldXRlci5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjI0ZjUxOTMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9rcmFldXRlci5jCkBAIC0wLDAgKzEsMjQwIEBACisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8dGhpbmcvY29tbWFuZHMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxpdGVtcy9rcmFldXRlci9rcmFldXRlci5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxsaXZpbmcvY29tYmF0Lmg+IC8vIEZ1ZXIgUF9GUkVFX0hBTkRTCisKKy8vIFN0YW5kYXJkd2VydCB2b24gMiBoIGZ1ZXIgdm9sbHN0YWVuZGlnZSBSZWdlbmVyYXRpb24gZGVzIEtyYXV0ZXMuIAorLy8gRWluZmFjaGVzIE5hY2h3YWNoc2VuIGlzdCB0eXBpc2NoZXJ3ZWlzZSBkaWUgSGFlbGZ0ZSBkYXZvbi4KKyNkZWZpbmUgU1REX1dBQ0hTVFVNICA3MjAwCisjZGVmaW5lIEJTKHgpICAgICAgICAgYnJlYWtfc3RyaW5nKHgsIDc4KQorCisvLyBTdHJ1a3R1ciAoNiBFaW50cmFlZ2UgcHJvIEtyYXV0KToKKy8vIChbIGZpbGVuYW1lIDogKHsgWmVpdF9iaXNfbmFjaGdld2FjaHNlbiwgWmVpdF9iaXNfa29tcGxldHRfcmVnZW5lcmllcnQsCisvLyAgICAgICAgICAgICAgICAgIEtyYXV0LUlEcywgS3JhdXQtQWRqZWt0aXZlLCBLcmF1dC0+TmFtZShXRVIsMSksCisvLyAgICAgICAgICAgICAgICAgIElEX2Rlc19CZXdhY2hlci1OUENzIH0pIF0pCittYXBwaW5nIHBsYW50TWFwID0gKFtdKTsKKworLy8ga2FubiBiZW51dHp0IHdlcmRlbiB1bSBzY2huZWxsIHVuZCBlaW5mYWNoIGVpbmUgUGZsYW56ZSBpbiBlaW5lbSBSYXVtCisvLyBoaW56dXp1ZnVlZ2VuLiBCZWlzcGllbDogQWRkUGxhbnQoQkFFUkVOS0xBVSk7CisvLyBEaWVzZSBGdW5rdGlvbiBlcnpldWd0IGF1dG9tYXRpc2NoIGVpbiBBZGRDbWQoKSBmdWVyIGRhcyBQZmx1ZWNrZW4gdW5kCisvLyAoZmFsbHMgbm9jaCBuaWNodCB2b3JoYW5kZW4pIERldGFpbHMgZnVlciBkaWUgUGZsYW56ZS4KKy8vIFJ1ZWNrZ2FiZXdlcnRlOgorLy8gMSAtPiBFcmZvbGc7IC0xIC0+IGZpbGVuYW1lIHVuZ3VlbHRpZwordmFyYXJncyBpbnQgQWRkUGxhbnQoc3RyaW5nIGZpbGVuYW1lLCBzdHJpbmd8c3RyaW5nKiBucGNJZCkKK3sKKyAgbWl4ZWQgYXJyOworCisgIC8vIERhdGVpbmFtZSBuaWNodCB1ZWJlcmdlYmVuPyBEYW5uIHR1biB3aXIgZXJzdG1hbCBnYXIgbml4LgorICBpZiAoIXN0cmluZ3AoZmlsZW5hbWUpKSAKKyAgICByZXR1cm4gLTE7CisgIG9iamVjdCBvYj1sb2FkX29iamVjdChmaWxlbmFtZSk7CisgICAKKyAgLy8gV2VubiB3aXIgenUgZGVtIEtyYXV0IHNjaG9uIERhdGVuIGhhYmVuIChlcmtlbm5iYXIgYW4gPjIgRWludHJhZWdlbiksCisgIC8vIHdlcmZlbiB3aXIgZWluZW4gRmVobGVyLCBkYW1pdCBkYXMgYmVpbSBMYWRlbiBkZXMgUmF1bWVzIHNjaG9uCisgIC8vIGVya2FubnQgd2lyZC4KKyAgaWYgKHBvaW50ZXJwKGFycj1wbGFudE1hcFtmaWxlbmFtZV0pICYmIHNpemVvZihhcnIpPjIpCisgICAgcmFpc2VfZXJyb3IoIkFkZFBsYW50KCk6ICIrZmlsZW5hbWUrIiBhbHJlYWR5IGV4aXN0cy5cbiIpOworCisgIC8vIElEcyB1bmQgQWRqZWt0aXZlIHBhcnNlbiB1bmQgZGVuIERhdGVuc2F0eiB6dXNhbW1lbnN0ZWxsZW4KKyAgc3RyaW5nICppZHMgPSBvYi0+UXVlcnkoUF9JRFMsIEZfVkFMVUUpLSh7ICJEaW5nIiB9KTsKKyAgc3RyaW5nICphZGogPSBvYi0+UXVlcnkoUF9BREpFQ1RJVkVTLCBGX1ZBTFVFKTsKKyAgCisgIGlmICghcG9pbnRlcnAoYXJyKSB8fCBzaXplb2YoYXJyKTwyKSAKKyAgICBhcnIgPSAoezAsMH0pOworICBpZiAoICFucGNJZCApCisgICAgbnBjSWQgPSAoe30pOworICBlbHNlIGlmIChzdHJpbmdwKG5wY0lkKSkKKyAgICBucGNJZCA9ICh7bnBjSWR9KTsKKyAgcGxhbnRNYXBbZmlsZW5hbWVdPSh7YXJyWzBdLCBhcnJbMV0sIGlkcywgYWRqLCBvYi0+TmFtZShXRVIsIDEpLCBucGNJZCB9KTsKKyAgIAorICAvLyBEZXRhaWxzIGVyemV1Z2VuIGF1cyBBZGpla3RpdmVuIHVuZCBJRHMKKyAgYWRqID0gb2ItPlF1ZXJ5UHJvcChQX05BTUVfQURKKTsKKyAgCisgIC8vIGFrdHVlbGxlcyBHZXNjaGxlY2h0IHp3aXNjaGVuc3BlaWNoZXJuLCB3aXJkIHNwYWV0ZXIgd2llZGVyaGVyZ2VzdGVsbHQKKyAgaW50IGdlbmRlciA9IFF1ZXJ5KFBfR0VOREVSLCBGX1ZBTFVFKTsKKyAgU2V0KFBfR0VOREVSLCBvYi0+UXVlcnkoUF9HRU5ERVIsIEZfVkFMVUUpLCBGX1ZBTFVFKTsKKyAgCisgIC8vIGVyemV1Z3QgZnVlciBqZWRlIG1vZWdsaWNoZSBLb21iaW5hdGlvbiBhdXMgQWRqZWt0aXYgaW0gQWtrdXNhdGl2CisgIC8vIHVuZCBJRCBkZXMgS3JhdXRlcyBlaW4gRGV0YWlsLgorICBhZGogPSBtYXAoYWRqLCAjJ0RlY2xBZGosIFdFTiwgMCk7CisKKyAgc3RyaW5nICpkZXQ9KHt9KTsKKyAgZm9yZWFjaChzdHJpbmcgX2lkIDogaWRzKSB7CisgICAgZm9yZWFjaChzdHJpbmcgX2FkaiA6IGFkaikgeworICAgICAgZGV0ICs9ICh7IF9hZGogKyBfaWQgfSk7CisgICAgfQorICB9CisKKyAgZGV0ICs9IGlkczsKKyAgLy8ga2VpbmUgZXhpc3RpZXJlbmRlbiBEZXRhaWxzIHVlYmVyc2NocmVpYmVuCisgIGRldCAtPSBtX2luZGljZXMoUXVlcnkoUF9ERVRBSUxTLCBGX1ZBTFVFKSB8fCAoW10pKTsKKyAgaWYgKHNpemVvZihkZXQpKSAKKyAgICBBZGREZXRhaWwoZGV0LCBvYi0+UXVlcnkoUExBTlRfUk9PTURFVEFJTCwgRl9WQUxVRSkpOworICAKKyAgLy8gRWluZSBCZWZlaGxzZnVua3Rpb24gYnJhdWNoZW4gd2lyIG5hdHVlcmxpY2ggYXVjaC4KKyAgQWRkQ21kKCh7InBmbHVlY2siLCAicGZsdWVja2UiLCAiZXJudGUifSksICJfcGZsdWVja2VuIik7CisgIAorICByZXR1cm4gMTsKK30KKworLy8gV2VubiBqZW1hbmQgcGVyIEhhbmQgZGFzIFBsYW50ZGV0YWlsIGhpbnp1ZnVlZ2VuIG1vZWNodGUuLi4KKy8vIHouQi4gYmVpIFZlcndlbmR1bmcgdm9uIEdldFBsYW50KCkgYW5zdGVsbGUgdm9uIEFkZFBsYW50KCkKK3ZvaWQgQWRkUGxhbnREZXRhaWwoc3RyaW5nIGZpbGVuYW1lKQoreworICAvLyBQZmFkIGluIE9iamVrdHBvaW50ZXIgd2FuZGVsbgorICBvYmplY3Qgb2I9bG9hZF9vYmplY3QoZmlsZW5hbWUpOworICAgCisgIC8vIERldGFpbHMgZXJ6ZXVnZW4KKyAgc3RyaW5nICpkZXQgPSAoe30pOworICBzdHJpbmcgKmlkcyA9IG9iLT5RdWVyeShQX0lEUywgRl9WQUxVRSktKHsgIkRpbmciIH0pOworICBzdHJpbmcgKmFkaiA9IG9iLT5RdWVyeVByb3AoUF9OQU1FX0FESik7CisgIC8vIGFrdHVlbGxlcyBHZXNjaGxlY2h0IHp3aXNjaGVuc3BlaWNoZXJuLCB3aXJkIHNwYWV0ZXIgd2llZGVyaGVyZ2VzdGVsbHQKKyAgaW50IGdlbmRlcj1RdWVyeShQX0dFTkRFUiwgRl9WQUxVRSk7CisgIFNldChQX0dFTkRFUiwgb2ItPlF1ZXJ5KFBfR0VOREVSLCBGX1ZBTFVFKSk7CisgIC8vIGVyemV1Z3QgZnVlciBqZWRlIG1vZWdsaWNoZSBLb21iaW5hdGlvbiBhdXMgQWRqZWt0aXYgaW0gQWtrdXNhdGl2CisgIC8vIHVuZCBJRCBkZXMgS3JhdXRlcyBlaW4gRGV0YWlsLgorICBhZGogPSBtYXAoYWRqLCAjJ0RlY2xBZGosIFdFTiwgMCk7CisgIGZvcmVhY2goc3RyaW5nIF9pZCA6IGlkcykgeworICAgIGZvcmVhY2goc3RyaW5nIF9hZGogOiBhZGopIHsKKyAgICAgIGRldCArPSAoeyBfYWRqICsgX2lkIH0pOworICAgIH0KKyAgfQorICBBZGREZXRhaWwoZGV0K2lkcywgb2ItPlF1ZXJ5KFBMQU5UX1JPT01ERVRBSUwsIEZfVkFMVUUpKTsKKyAgLy8gR2VzY2hsZWNodCB6dXJ1ZWNrc2V0emVuCisgIFNldChQX0dFTkRFUiwgZ2VuZGVyLCBGX1ZBTFVFKTsKK30KKworLy8gUHJ1ZWZ0LCBvYiBkaWUgUGZsYW56ZSB6dSAiZmlsZW5hbWUiIGluIGRpZXNlbSBSYXVtIHNjaG9uIG5hY2hnZXdhY2hzZW4KKy8vIGlzdC4KK3Byb3RlY3RlZCBpbnQgQ2hlY2tQbGFudChzdHJpbmcgZmlsZW5hbWUpCit7CisgIG1peGVkIGFycj1wbGFudE1hcFtmaWxlbmFtZV07CisgIGlmICghcG9pbnRlcnAoYXJyKSB8fCBzaXplb2YoYXJyKTwyKSB7CisgICAgYXJyPXBsYW50TWFwW2ZpbGVuYW1lXT0oeyAwLCAwIH0pOworICB9CisgIC8vIFNvbGFuZ2UgZGllIFplaXQgYXJyWzBdIG5vY2ggbmljaHQgZXJyZWljaHQgaXN0LCBpc3QgZGFzIEtyYXV0IG5pY2h0IAorICAvLyBuYWNoZ2V3YWNoc2VuLCBkYW5uIGdpYnQgZXMgZ2FyIG5peC4KKyAgcmV0dXJuICh0aW1lKCk+YXJyWzBdKTsKK30KKworLy8gTW9lY2h0ZSBtYW4gQWRkUGxhbnQoKSBuaWNodCBiZW51dHplbiwgd2VpbCBtYW4gZGllIFBmbGFuemUgbmljaHQgZWluZmFjaAorLy8gcGZsdWVja2VuLCBzb25kZXJuIHZpZWxsZWljaHQgYWJzY2huZWlkZW4sIG9kZXIgYXVzZ3JhYmVuIHNvbGwsIHNvIGthbm4KKy8vIG1hbiBzaWNoIG1pdHRlbHMgR2V0UGxhbnQoZmlsZW5hbWUpIGRhcyBPYmpla3QgZXJ6ZXVnZW4gbGFzc2VuLiBHaWJ0CisvLyBHZXRQbGFudCgpIDAgenVydWVjaywgaXN0IGRpZSBQZmxhbnplIG5vY2ggbmljaHQgd2llZGVyIHdlaXQgZ2VudWcKKy8vIG5hY2hnZXdhY2hzZW4uCitvYmplY3QgR2V0UGxhbnQoc3RyaW5nIGZpbGVuYW1lKQoreworICBpbnQgKmFycj1wbGFudE1hcFtmaWxlbmFtZV07CisgIGlmICghcG9pbnRlcnAoYXJyKSB8fCBzaXplb2YoYXJyKTwyKQorICB7CisgICAgIGFycj1wbGFudE1hcFtmaWxlbmFtZV09KHsgMCwgMCB9KTsKKyAgfQorICAvLyBhcnJbMF0gZW50aGFlbHQgZGVuIFplaXRwdW5rdCwgd2FubiBkYXMgS3JhdXQgbmFjaGdld2FjaHNlbiBpc3QsCisgIGludCBuYWNoZ2V3YWNoc2VuID0gYXJyWzBdOworICAvLyBhcnJbMV0gZGVuamVuaWdlbiwgd2FubiBlcyB2b2xsc3RhZW5kaWcgcmVnZW5lcmllcnQgaXN0LgorICBpbnQgcmVnZW5lcmllcnQgPSBhcnJbMV07CisKKyAgLy8gVm9yIGRlbSBOYWNoZ2V3YWNoc2VuLVplaXRwdW5rdCBrYW5uIG1hbiBnYXIgbml4IGVybnRlbi4KKyAgaWYgKHRpbWUoKTxuYWNoZ2V3YWNoc2VuKSByZXR1cm4gMDsgLy8gbm9jaCBuaWNodCBuYWNoZ2V3YWNoc2VuCisKKyAgLy8gUmVzdHplaXQgYmlzIHp1ciB2b2xsc3RhZW5kaWdlbiBSZWdlbmVyYXRpb24uCisgIHJlZ2VuZXJpZXJ0LT10aW1lKCk7CisgIAorICAvLyBXZW5uIHZvbGxzdGFlbmRpZyByZWdlbmVyaWVydCwgaXN0IFNURF9XQUNIU1RVTSBkaWUgbmV1ZSBaZWl0IGJpcyB6dXIKKyAgLy8gUmVnZW5lcmF0aW9uLiBXZW5uIG5vY2ggbmljaHQgdm9sbHN0YWVuZGlnIHJlZ2VucmllcnQsIFJlc3R6ZWl0CisgIC8vIHZlcmRvcHBlbG4gdW5kIFNURF9XQUNIU1RVTSBub2NobWFsIGRyYXVmIGFkZGllcmVuLgorICByZWdlbmVyaWVydCA9IChyZWdlbmVyaWVydDw9MCA/IFNURF9XQUNIU1RVTSAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAocmVnZW5lcmllcnQqMikrU1REX1dBQ0hTVFVNKTsKKyAgLy8gbmFjaGdld2FjaHNlbiBpc3QgZGllIGhhbGJlIFJlZ2VuZXJhdGlvbnN6ZWl0CisgIGFyclswXT1uYWNoZ2V3YWNoc2VuPXRpbWUoKSsocmVnZW5lcmllcnQvMik7CisgIC8vIFplaXQgdm9lbGxpZ2VyIFJlZ2VuZXJhdGlvbgorICBhcnJbMV09cmVnZW5lcmllcnQrPXRpbWUoKTsKKyAgCisgIHJldHVybiBjbG9uZV9vYmplY3QoZmlsZW5hbWUpOworfQorCitzdGF0aWMgaW50IF9wZmx1ZWNrZW4oc3RyaW5nIHN0cikKK3sKKyAgaW50IHJlczsKKworICBpZiAoIW1hcHBpbmdwKHBsYW50TWFwKSkgcmV0dXJuIDA7CisgIF9ub3RpZnlfZmFpbCgiV0FTIG1vZWNodGVzdCBEdSBwZmx1ZWNrZW4/XG4iKTsKKworICAvLyBJRHMgdW5kIEFkamVrdGl2ZSB6d2lzY2hlbnNwZWljaGVybgorICBtaXhlZCBpZHMgPSBRdWVyeShQX0lEUywgRl9WQUxVRSk7CisgIG1peGVkIGFkaiA9IFF1ZXJ5KFBfQURKRUNUSVZFUywgRl9WQUxVRSk7CisKKyAgZm9yZWFjaChzdHJpbmcga2V5LCBtaXhlZCBrcmF1dGluZm8gOiBwbGFudE1hcCkgCisgIHsKKyAgICBpZiAoIHNpemVvZihrcmF1dGluZm8pICE9IDYgKQorICAgICAgY29udGludWU7CisgCisgICAgLy8gSURzIHVuZCBBZGpla3RpdmUgZGVzIEtyYXV0ZXMga29waWVyZW4gCisgICAgU2V0KFBfSURTLCBrcmF1dGluZm9bMl0sIEZfVkFMVUUpOworICAgIFNldChQX0FESkVDVElWRVMsIGtyYXV0aW5mb1szXSwgRl9WQUxVRSk7CisKKyAgICAvLyBTeW50YXhwcnVlZnVuZyB3aXJkIGRhbm4gbWl0IGlkKCkgZ2VtYWNodC4KKyAgICBpZiAoaWQoc3RyKSkgCisgICAgeworICAgICAgb2JqZWN0IG9iOworICAgICAgb2JqZWN0IGJld2FjaGVyOworICAgICAgcmVzPTE7CisKKyAgICAgIC8vIExpc3RlIGRlciBlaW5nZXRyYWdlbmVuIEJld2FjaGVyLUlEcyBkdXJjaGxhdWZlbiB1bmQgcHJ1ZWZlbiwgb2IKKyAgICAgIC8vIG1pbmRlc3RlbnMgZWluZXIgZGF2b24gYW53ZXNlbmQgaXN0LgorICAgICAgZm9yZWFjaCggc3RyaW5nIG5wY0lkIDoga3JhdXRpbmZvWzVdICkKKyAgICAgIHsKKyAgICAgICAgYmV3YWNoZXIgPSBwcmVzZW50KG5wY0lkLCBNRSk7CisgICAgICAgIGlmIChvYmplY3RwKGJld2FjaGVyKSkKKyAgICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIAorICAgICAgaWYgKCAhUEwtPlF1ZXJ5UHJvcChQX0ZSRUVfSEFORFMpICkgCisgICAgICB7CisgICAgICAgIHRlbGxfb2JqZWN0KFBMLCBCUygiRHUgaGFzdCBrZWluZSBIYW5kIGZyZWksIHVtIGV0d2FzIHBmbHVlY2tlbiAiCisgICAgICAgICAgInp1IGtvZW5uZW4uIikpOworICAgICAgfQorICAgICAgLy8gSXN0IGRlciBCZXdhY2hlciBhbndlc2VuZD8gRGFubiBrYW5uIG1hbiBkYXMgS3JhdXQgbmljaHQgcGZsdWVja2VuLgorICAgICAgZWxzZSBpZiAoIG9iamVjdHAoYmV3YWNoZXIpICkKKyAgICAgIHsKKyAgICAgICAgdGVsbF9vYmplY3QoUEwsIEJTKGJld2FjaGVyLT5OYW1lKFdFUiwgMikrIiBsYWVzc3QgRGljaCAiCisgICAgICAgICAgImxlaWRlciBuaWNodCBuYWggZ2VudWcgaGVyYW4uIElyZ2VuZHdpZSBtdXNzdCBEdSBEaWNoIHdvaGwgIgorICAgICAgICAgICJ6dW5hZWNoc3QgdW0gIitiZXdhY2hlci0+UXVlcnlQcm9ub3VuKFdFTikrIiBrdWVtbWVybi4iKSk7CisgICAgICB9CisgICAgICAvLyBXZW5uIEdldFBsYW50KCkgZWluIE9iamVrdCBsaWVmZXJ0LCBrYW5uIHdhcyBnZXBmbHVlY2t0IHdlcmRlbi4KKyAgICAgIGVsc2UgaWYgKCBvYmplY3RwKG9iPUdldFBsYW50KGtleSkpICkgCisgICAgICB7CisgICAgICAgIGlmICggb2ItPm1vdmUoUEwsIE1fR0VUKSA9PSBNT1ZFX09LICkKKyAgICAgICAgeworICAgICAgICAgIHdyaXRlKEJTKCJWb3JzaWNodGlnIHBmbHVlY2tzdCBEdSAiK29iLT5uYW1lKFdFTiwgMSkrCisgICAgICAgICAgICAiIHVuZCBuaW1tc3QgIitvYi0+UXVlcnlQcm9ub3VuKFdFTikrIiBhbiBEaWNoLiIpKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIAorICAgICAgICB7CisgICAgICAgICAgd3JpdGUoQlMoIlZvcnNpY2h0aWcgcGZsdWVja3N0IER1ICIrb2ItPm5hbWUoV0VOLCAxKSsiLCBrYW5uc3QgIisKKyAgICAgICAgICAgIG9iLT5RdWVyeVByb25vdW4oV0VOKSsiIGFiZXIgbmljaHQgbmVobWVuLiIpKTsKKyAgICAgICAgICBvYi0+bW92ZShlbnZpcm9ubWVudChQTCksIE1fR0VUKTsKKyAgICAgICAgfQorICAgICAgfQorICAgICAgLy8gV2VubiBhbGxlcyBuaWNodCwgZGFubiBpc3QgZGFzIEtyYXV0IG5vY2ggbmljaHQgd2llZGVyIGRhLgorICAgICAgZWxzZSAKKyAgICAgIHsKKyAgICAgICAgd3JpdGUoQlMoa3JhdXRpbmZvWzRdKyIgaXN0IG5vY2ggbmljaHQgcmVpZiBnZW51ZyAiCisgICAgICAgICAgKyJ1bmQgbXVzcyBlcnN0IG5vY2ggZXR3YXMgd2FjaHNlbi4iKSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgfQorICAgLy8gSURzIHVuZCBBZGpla3RpdmUgenVydWVja3NldHplbi4KKyAgU2V0KFBfSURTLCBpZHMsIEZfVkFMVUUpOworICBTZXQoUF9BREpFQ1RJVkVTLCBhZGosIEZfVkFMVUUpOworCisgIHJldHVybiByZXM7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9yb29tL2tyYWV1dGVybGFkZW4uYyBiL3N0ZC9yb29tL2tyYWV1dGVybGFkZW4uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jZjk5NzkzCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Jvb20va3JhZXV0ZXJsYWRlbi5jCkBAIC0wLDAgKzEsMTY3IEBACisvLyAoYykgMjAwMyBieSBQYWRyZWljIChwYWRyZWljQG1nLm11ZC5kZSkKKy8vIAorLy8gRXMga2FubiBiZXN0aW1tdGUgTGFlZGVuIHp1bSBIYW5kZWxuIHZvbiBLcmFldXRlcm4gZ2ViZW4uCisvLyBadW5hZWNoc3QgZWlubWFsIGdpYnQgZXMgZWluZW4gaW4gZGVyIER1bmtlbGVsZmVuZ2lsZGUuCisvLyBIaWVyIGtvZW5uZW4gS3JhZXV0ZXIgZ2UtIHVuZCB2ZXJrYXVmdCB3ZXJkZW4uCisvLyBHcnVuZHNhZXR6bGljaCBrYW5uIGVzIGJlbGllYmlnIHZpZWxlIGtyYWV1dGVya3VuZGlnZQorLy8gSGFlbmRsZXIgZ2ViZW4sIGVpbmUga3VyemUgQWJzcHJhY2hlIHdhZXJlIGplZG9jaCB2b24gVm9ydGVpbC4KKworLy8gRGVyIExhZGVuIGVyd2VpdGVydCBkaWUgcm9vbS9zaG9wIEZ1bmt0aW9uZW4uCisvLyBadXIgVmVyd2VuZHVuZyBtdXNzIGRpZXNlciBub2NoIG1pdCBlaW5lbSBzdGQvcm9vbSBrb21iaW5pZXJ0CisvLyB3ZXJkZW4uIERpZXMgZXJsYXVidCBkaWUgVmVyd2VuZHVuZyB2b24gZWlnZW5lbiBTdGFuZGFyZHJhZXVtZW4gb2RlcgorLy8gS29tYmluYXRpb24gbWl0IEtuZWlwZW4uCisKK2luaGVyaXQgIi9zdGQvcm9vbS9zaG9wIjsKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPGl0ZW1zL2tyYWV1dGVyL2tyYWV1dGVyLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCisvLyBGbGFnLCBkYXMgaW0gcmVzZXQoKSBkYXMgU3BlaWNoZXJuIGF1c2xvZXN0LCB3ZW5uIGVzIGdlc2V0enQgaXN0Lgorc3RhdGljICBpbnQgbmVlZF9zYXZlOyAgCitzdGF0aWMgIGludCBiYXNpc3ZhbHVlPTQwMDsgLy8gZ2lidCBkZW4gX0R1cmNoc2Nobml0dHN3ZXJ0XyBlaW5lcyBLcmF1dHMgYW4KK3N0YXRpYyAgaW50IG1heHZhbHVlPTEwMDAwOyAvLyBiZXN0aW1tdCBkZW4gbWF4LiBXZXJ0IGFsbGVyIEtyYWV1dGVyCisKKy8vIEVudGhhZWx0IGZ1ZXIgamVkZSBQbGFudElEIGVpbmVuIFphZWhsZXIsIGRlciBhbmdpYnQsIHdpZXZpZWwgdm9uIGRlbQorLy8gamV3ZWlsaWdlbiBLcmF1dCB2ZXJrYXVmdCB3dXJkZS4KKy8vIHByaXZhdGUgaW50ICpjb3VudD0oe30pOworCisvLyBTdW1tZSB1ZWJlciBhbGxlIEVpbnRyYWVnZSBpbiBjb3VudAorLy8gcHJpdmF0ZSBpbnQgc3VtOworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBpZiAob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bMC4uPDNdKQorICB7CisgICAgc2V0X25leHRfcmVzZXQoLTEpOworICAgIHJldHVybjsKKyAgfQorICA6OmNyZWF0ZSgpOworCisgIFNldFByb3AoUF9CVVlfT05MWV9QTEFOVFMsMSk7CisgIC8qCisgIHNldGV1aWQoZ2V0dWlkKCkpOyAvLyB3aXJkIHp1bSBzcGVpY2hlcm4gYmVu9nRpZ3QKKyAgaW50IHNpPXNpemVvZihjb3VudCk7CisgIC8vIGZ1ZXIgamVkZSBQbGFudElEIGVpbmVuIEVpbnRyYWcgYW5sZWdlbiwgZC5oLiB3ZW5uIGluIGNvdW50IG5vY2gKKyAgLy8gbmljaHQgZ2VudWcgdm9yaGFuZGVuIHNpbmQsIHdlcmRlbiBmZWhsZW5kZSBFaW50cmFlZ2UgZXJnYWVuenQuCisgIGlmIChzaTxQTEFOVENPVU5UKSAKKyAgICBjb3VudD1jb3VudCthbGxvY2F0ZShQTEFOVENPVU5ULXNpKTsKKyAgKi8KK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkKK3sKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCitzdGF0aWMgc3RyaW5nIHNlbGxfb2JqX29ubHlfcGxhbnRzKG9iamVjdCBvYiwgaW50IHNob3J0KQoreworICAgaWYgKCFJU19QTEFOVChvYikpCisgICAgICByZXR1cm4gIlR1dCBtaXIgbGVpZCwgZGFtaXQga2FubiBpY2ggbmljaHRzIGFuZmFuZ2VuLiI7CisgICAvLyBlcyB3ZXJkZW4gbnVyIEtyYWV1dGVyIGFuZ2VrYXVmdCwgZGllIGxlZ2FsIGdlY2xvbnQgd3VyZGVuLAorICAgLy8gZC5oLiBpbSBlbnRzcHJlY2hlbmRlbiBNYXN0ZXIgb3JkZW50bGljaCBlaW5nZXRyYWdlbiB3dXJkZW4hCisgICBpZiAob2ItPlF1ZXJ5UGxhbnRJZCgpPD0wKQorICAgICAgcmV0dXJuIG9iLT5OYW1lKFdFUiwgMikrIiBpc3QgaWxsZWdhbCBhdWYgZGllIFdlbHQgZ2Vrb21tZW4uIEljaCBkYXJmICIKKyAgICAgICAgICAgICtvYi0+UXVlcnlQcm9ub3VuKFdFTikrIiBsZWlkZXIgbmljaHQgYW5uZWhtZW4uIjsKKyAgIHJldHVybiA6OnNlbGxfb2JqKG9iLCBzaG9ydCk7Cit9CisKK3N0YXRpYyBzdHJpbmcgc2VsbF9vYmoob2JqZWN0IG9iLCBpbnQgc2hvcnQpCit7CisgICAvLyBlcyB3ZXJkZW4gbnVyIEtyYWV1dGVyIGFuZ2VrYXVmdCwgZGllIGxlZ2FsIGdlY2xvbnQgd3VyZGVuLAorICAgLy8gZC5oLiBpbSBlbnRzcHJlY2hlbmRlbiBNYXN0ZXIgb3JkZW50bGljaCBlaW5nZXRyYWdlbiB3dXJkZW4hCisgIGlmIChJU19QTEFOVChvYikgJiYgb2ItPlF1ZXJ5UGxhbnRJZCgpPD0wKQorICAgIHJldHVybiAiSG0sICIrb2ItPk5hbWUoV0VSLCAyKSsiIHN0YW1tdCBhYmVyIGF1cyBlaW5lciBzZWhyIGR1Ymlvc2VuICIKKyAgICAgICJRdWVsbGUuIEljaCBrYW5uICIrb2ItPlF1ZXJ5UHJvbm91bihXRU4pKyIgbGVpZGVyIG5pY2h0IGFubmVobWVuLiI7CisgIGlmIChRdWVyeVByb3AoUF9CVVlfT05MWV9QTEFOVFMpKQorICAgIHJldHVybiBzZWxsX29ial9vbmx5X3BsYW50cyhvYiwgc2hvcnQpOworICByZXR1cm4gOjpzZWxsX29iaihvYixzaG9ydCk7Cit9CisKKy8qCit2b2lkIHJlc2V0KCkKK3sKKyAgOjpyZXNldCgpOworICAvLyBEYXRlbiBzaW5kIG5pY2h0IHNvb28gd2ljaHRpZywgYWxzIGRhcyBiZWkgamVkZXIgQWVuZGVydW5nCisgIC8vIGdlc2F2ZXQgd2VyZGVuIG11ZXNzdGUuIERhaGVyIG51biBpbSByZXNldCBzcGVpY2hlcm4uCisgIGlmIChuZWVkX3NhdmUpIHsKKyAgICAvLyBiYXNpc3ZhbHVlL1BMQU5UQ09VTlQ6IER1cmNoc2Nobml0dHN3ZXJ0IGVpbmVzIGVpbnplbG5lbiBLcmF1dHMKKyAgICAvLyBzdW0gKyBQTEFOVENPVU5UOiBHZXNhbXR6YWhsIHZlcmthdWZ0ZXIgcGx1cyBaYWhsIGV4aXN0aWVyZW5kZXIKKyAgICAvLyAgICAgICAgICAgICAgICAgICBLcmFldXRlcgorICAgIC8vIFdlbm4gYWxzbyBkZXIgV2VydCBhbGwgZGllc2VyIEtyYWV1dGVyID4gMTBrIGlzdCwgd2lyZCBqZWRlcgorICAgIC8vIEVpbnplbHphZWhsZXIgYXVmIDkwJSBnZXN0dXR6dCwgZGFtaXQgZGllIFdlcnRlIG5pY2h0IGlucyBVZmVybG9zZQorICAgIC8vIHN0ZWlnZW4uCisgICAgaWYgKCgoc3VtK1BMQU5UQ09VTlQpKmJhc2lzdmFsdWUvUExBTlRDT1VOVCk+bWF4dmFsdWUpIHsKKyAgICAgIGludCBpLCBuZXdzdW07CisgICAgICBmb3IgKGk9c2l6ZW9mKGNvdW50KS0xOyBpPj0wOyBpLS0pIHsKKyAgICAgICAgY291bnRbaV0gPSBjb3VudFtpXSo5LzEwOworICAgICAgICBuZXdzdW0rPWNvdW50W2ldOworICAgICAgfQorICAgICAgc3VtPW5ld3N1bTsKKyAgICB9CisgICAgbmVlZF9zYXZlPTA7CisgIH0KK30KKworLy8gQWt0dWFsaXNpZXJ0IGRlbiBEYXRlbmJlc3RhbmQgYmVpbSBLYXVmZW4gb2RlciBWZXJrYXVmZW4gZWluZXMgT2JqZWt0cwordm9pZCBVcGRhdGVDb3VudGVyKG9iamVjdCBvYiwgaW50IG51bSkKK3sKKyAgIGludCBpZD1vYi0+UXVlcnlQbGFudElkKCk7CisgICBpZiAoaWQ+MCAmJiBpc19wbGFudChvYikpIHsKKyAgICAgIC8vIEthdWYgb2RlciBWZXJrYXVmIHZvbiBLcmFldXRlcm4sIHZlcmFlbmRlcnQgZGVuIFdlcnQgZGVyCisgICAgICAvLyBLcmFldXRlcgorICAgICAgLy8gWmFlaGxlciBpbiBkZXIgTGlzdGUgaG9jaHphZWhsZW4KKyAgICAgIGNvdW50W2lkXSs9bnVtOworICAgICAgaWYgKGNvdW50W2lkXTwwKSBjb3VudFtpZF09MDsgLy8gZGFyZiBhYmVyIGFuc2ljaCBuaWNoIHBhc3NpZXJlbgorICAgICAgLy8gR2VzYW10c3VtbWUgYWt0dWFsaXNpZXJlbgorICAgICAgc3VtKz1udW07CisgICAgICBuZWVkX3NhdmU9MTsKKyAgIH0KKyAgIDo6VXBkYXRlQ291bnRlcihvYiwgbnVtKTsKK30KKworLy8gRGllIFByZWlzZSBkaWUgaGllciBpbSBMYWJvciBmdWVyIEtyYWV1dGVyIGdlemFobHQgdW5kIHZlcmxhbmd0CisvLyB3ZXJkZW4sIHNpbmQgbmljaHQgZml4IHNvbmRlcm4gaGFlbmdlbiB2b24gQW5nZWJvdCB1bmQgTmFjaGZyYWdlIGFiLgorLy8gSGllciB3ZWlzcyBtYW4gdWViZXIgZGVuIHdhaHJlbiBXZXJ0IGRlciBlaW56ZWxuZW4gS3JhZXV0ZXIgYmVzY2hlaWQuCitzdGF0aWMgaW50IHJlYWxWYWx1ZShvYmplY3Qgb2IsIG9iamVjdCBwbGF5ZXIpCit7CisgICAvLyBQcmVpc2UgZnVlciBub3JtYWxlIEd1ZXRlciBnYW56IG5vcm1hbC4uLgorICAgaWYgKCFpc19wbGFudChvYikpCisgICAgICAgcmV0dXJuIG9iLT5RdWVyeVByb3AoUF9WQUxVRSk7CisKKyAgIC8vIGplZGUgS3JhZXV0ZXJrYXRlZ29yaWUgYmVrb21tdCBkZW4gZ2xlaWNoZW4gV2VydCB6dWdld2llc2VuLiAgIAorICAgLy8gdmFsIGVudHNwcmljaHQgZGVtIGFrdHVlbGxlbiAiRHVyY2hzY2huaXR0c3dlcnQiIGVpbmVzIEtyYXV0ZXMKKyAgIGludCB2YWw9KHN1bStQTEFOVENPVU5UKSpiYXNpc3ZhbHVlL1BMQU5UQ09VTlQ7CisKKyAgIC8vIGFiZXIgZGllc2VyIFdlcnQgdmVydGVpbHQgc2ljaCBhdWYgdW50ZXJzY2hpZWRsaWNoIHZpZWxlIEtyYWV1dGVyCisgICAvLyAoQU46IERpZXNlciBLb21tZW50YXIgZXJzY2hsaWVzc3Qgc2ljaCBtaXIgbmljaHQuKQorICAgaW50IGlkPW9iLT5RdWVyeVBsYW50SWQoKTsKKyAgIGlmIChpZDw9MCkgcmV0dXJuIDA7IC8vIGlsbGVnYWwgZ2VjbG9udCAtPiB3ZXJ0bG9zCisgICAvLyBnZ2YuIGRpZSBaYWVobGVybGlzdGUgdW0gZGllIGZlaGxlbmRlbiBFaW50cmFlZ2UgZXJ3ZWl0ZXJuLgorICAgaWYgKChpZC0xKT5zaXplb2YoY291bnQpKSAKKyAgICAgY291bnQ9Y291bnQrYWxsb2NhdGUoaWQtMS1zaXplb2YoY291bnQpKTsKKyAgIAorICAgLy8gIm1pdHRsZXJlbiBXZXJ0IiBkZXMgYWJnZWZyYWd0ZW4gS3JhdXRlcyBlcnJlY2huZW4gKERpdmlzaW9uIGR1cmNoCisgICAvLyBkZXNzZW4gdW1nZXNldHp0ZSBBbnphaGwpCisgICB2YWw9dmFsLyhjb3VudFtpZF0rMSk7CisgICAKKyAgIC8vIFdlcnQgcnVuZGVuIGF1ZiBuYWVjaHN0bmllZHJpZ2VyZW4gZ2xhdHQgZHVyY2ggMTAgdGVpbGJhcmVuIFdlcnQuCisgICByZXR1cm4gdmFsLXZhbCUxMDsgCit9CisKKy8vIGdpYnQgZGVuIFByZWlzIHp1cvxjaywgZGVyIHp1bSBBbmthdWYgZGVzIE9iamVrdGVzIHZlcndlbmRldCB3ZXJkZW4gc29sbAorc3RhdGljIHZhcmFyZ3MgaW50IFF1ZXJ5VmFsdWUob2JqZWN0IG9iLCBpbnQgdmFsdWUsIG9iamVjdCBwbGF5ZXIpCit7CisgICByZXR1cm4gOjpRdWVyeVZhbHVlKG9iLCByZWFsVmFsdWUob2IsIHBsYXllciksIHBsYXllcik7Cit9CisKKy8vIGdpYnQgZGVuIFByZWlzIGFuLCB6dSBkZW0gZGFzIE9iamVrdCB2ZXJrYXVmdCB3ZXJkZW4gc29sbC4KK3N0YXRpYyB2YXJhcmdzIGludCBRdWVyeUJ1eVZhbHVlKG1peGVkIG9iLCBvYmplY3QgcGxheWVyKQoreworICAgaWYgKG9iamVjdHAob2IpKQorICAgICAgcmV0dXJuIChyZWFsVmFsdWUob2IsIHBsYXllcikqUXVlcnlCdXlGYWN0KHBsYXllcikgKyA1MCkvMTAwOworICAgLy8gZml4ZWQgT2JqZWt0ZS4uLgorICAgcmV0dXJuIDo6UXVlcnlCdXlWYWx1ZShvYiwgcGxheWVyKTsKK30KKyovCmRpZmYgLS1naXQgYS9zdGQvcm9vbS9saWdodC5jIGIvc3RkL3Jvb20vbGlnaHQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hMzcyMDQ3Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Jvb20vbGlnaHQuYwpAQCAtMCwwICsxLDYxIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gY29udGFpbmVyL2xpZ2h0LmMgLS0gTGljaHRzeXN0ZW1rb21wb25lbnRlbiBmdWVyIFJhZXVtZQorLy8KKy8vICRJZDogZGVzY3JpcHRpb24uYyA2OTg2IDIwMDgtMDgtMjIgMjE6MzI6MTVaIFplc3N0cmEgJAorCitpbmhlcml0ICIvc3RkL2NvbnRhaW5lci9saWdodCI7CisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMscnR0X2NoZWNrcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8cm9vbS9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPGNvbnRhaW5lci5oPgorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICA6OmNyZWF0ZSgpOworICBTZXRQcm9wKFBfTElHSFRfQUJTT1JQVElPTiwgMSk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHtzZXRfbmV4dF9yZXNldCgtMSk7fQorCisvKgorICAgLy8gZGFzIHdpcmQgc2VsdGVuIGJlbnV0enQgdW5kIGlzdCB6dXIgemVpdCBmdW5rdGlvbnN1bmZhZWhpZywgZGEgZGllCisgICAvLyBpbnRlcm5lIFNwZWljaGVydW5nIGRlciBQcm9wIHNpY2ggZ2VhZW5kZXJ0IGhhdC4KK3N0YXRpYyBpbnQgX3NldF9pbnRfbGlnaHQoaW50ICpsaWdodCkKK3sKKyAgIGludCB0bXA7CisKKyAgIC8vIHp1ciBTaWNoZXJoZWl0CisgICBpZiAoIXBvaW50ZXJwKGxpZ2h0KSkgcmV0dXJuIC0xOworICAgaWYgKGxpZ2h0WzBdPlF1ZXJ5UHJvcChQX0xJR0hUKSkgeworICAgICAgLy8gTGljaHQgdmVybGFldWZ0IHNpY2ggaW4gZWluZW0gZ3Jvc3NlbiBSYXVtLCBkYWhlciBNb2RpZmllciBhYmZyYWdlbi4uLgorICAgICAgdG1wPWxpZ2h0WzBdLVF1ZXJ5UHJvcChQX0xJR0hUX0FCU09SUFRJT04pOworICAgICAgLy8gd2VubiBzaWNoIGRhcyBWb3J6ZWljaGVuIGdlYWVuZGVydCBoYXQsIGF1ZiAwIHNldHplbi4KKyAgICAgIGxpZ2h0WzBdPSgodG1wXmxpZ2h0WzBdKSAmIDB4ODAwMDAwMDAgPyAwIDogdG1wKTsKKyAgIH0KKyAgIGlmIChsaWdodFsxXTxRdWVyeVByb3AoUF9MSUdIVCkgJiYgbGlnaHRbMV08MCkgeworICAgICAgLy8gTGljaHQgdmVybGFldWZ0IHNpY2ggaW4gZWluZW0gZ3Jvc3NlbiBSYXVtLCBkYWhlciBNb2RpZmllciBhYmZyYWdlbi4uLgorICAgICAgdG1wPWxpZ2h0WzFdK1F1ZXJ5UHJvcChQX0xJR0hUX0FCU09SUFRJT04pOworICAgICAgLy8gd2VubiBzaWNoIGRhcyBWb3J6ZWljaGVuIGdlYWVuZGVydCBoYXQsIGF1ZiAwIHNldHplbi4KKyAgICAgIGxpZ2h0WzFdPSgodG1wXmxpZ2h0WzFdKSAmIDB4ODAwMDAwMDAgPyAwIDogdG1wKTsKKyAgIH0KKyAgIGxpZ2h0WzJdPWxpZ2h0WzBdK2xpZ2h0WzFdOworICAgU2V0KFBfSU5UX0xJR0hULCBsaWdodCwgRl9WQUxVRSk7CisgICAvLyBkaWVzZSBQcm9wIHNldHplbiBrYXVtIExldXRlIChvZmZpemllbGwgZ2VodHMgamEgYXVjaCBnYXIgbmljaHQuIEtlaW5lcgorICAgLy8gZGF2b24gZXJ3YXJ0ZXQgbmVuIFJ1ZWNrZ2FiZXdlcnQuIERhaGVyIHdpcmQgaGllciAwIHp1cnVlY2tnZWJlbiwgc3RhdHQKKyAgIC8vIGRlcyBhdWZ3YWVuZGlnIGJlcmVjaG5ldGVuIFF1ZXJ5UHJvcChQX0lOVF9MSUdIVCkuCisgICAvLyBBY2hqYS4gRGVyIFJ1ZWNrZ2FiZXdlcnQgdm9tIFNldCgpIHdhZXJlIGVpbiBpbnQqLCB3YXMgbmljaHQgZ2VodCwgd2VpbAorICAgLy8gZGllc2UgRnVua3Rpb24gbnVyIGludCB6dXJ1ZWNrZ2ViZW4gZGFyZi4KKyAgIHJldHVybiAwOworfQorKi8KZGlmZiAtLWdpdCBhL3N0ZC9yb29tL21vdmluZy5jIGIvc3RkL3Jvb20vbW92aW5nLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGY3YzJiMQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9yb29tL21vdmluZy5jCkBAIC0wLDAgKzEsMTcgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyByb29tL21vdmluZy5jIC0tIEVudGZlcm5lbiB2b24gUmFldW1lbgorLy8KKy8vICRJZDogbW92aW5nLmMgODA0MSAyMDEyLTAzLTE5IDE4OjM4OjIxWiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorCitwdWJsaWMgdmFyYXJncyBpbnQgcmVtb3ZlKGludCBzaWxlbnQpCit7CisgIGRlc3RydWN0KCB0aGlzX29iamVjdCgpICk7CisgIHJldHVybiAxOworfQpkaWZmIC0tZ2l0IGEvc3RkL3Jvb20vcGFyYS5jIGIvc3RkL3Jvb20vcGFyYS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjQ2NjY3ODIKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcm9vbS9wYXJhLmMKQEAgLTAsMCArMSwxOCBAQAorLy8gVGhpcyBtYXkgbG9vayBsaWtlIEMgY29kZSwgYnV0IGl0IGlzIHJlYWxseSAtKi0gQysrIC0qLQorCisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcm9vbS9wYXJhLmMgLS0gQmV0cmV0ZW4gZWluZXIgUGFyYWxsZWx3ZWx0CisvLworLy8gJElkOiBwYXJhLmMgNzUxMCAyMDEwLTAzLTI1IDIzOjM3OjE5WiBaZXNzdHJhICQKKworLy8gVmVyYWx0ZXQgLSB3aXJkIG5pY2h0IG1laHIgYmVub2V0aWd0LgorLy8gRGllIFp1b3JkbnVuZyBkZXIgJ3JpY2h0aWdlbicgV2VsdCB3aXJkIGpldHp0IGRpcmVrdCB2b24gbW92ZSgpIHVlYmVybm9tbWVuLgorCisjcHJhZ21hIHN0cm9uZ190eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisKK2RlcHJlY2F0ZWQgaW50IHBhcmFtb3ZlKCkgeyByZXR1cm4gMDsgfQpkaWZmIC0tZ2l0IGEvc3RkL3Jvb20vcHViLmMgYi9zdGQvcm9vbS9wdWIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMTVlMzNlCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Jvb20vcHViLmMKQEAgLTAsMCArMSw5ODkgQEAKKy8vCisvLyBwdWIuYyAtLSBBbGxlcywgd2FzIGVpbmUgS25laXBlIGJyYXVjaHQuCisvLworLy8gJElkOiBwdWIuYyA4Nzc4IDIwMTQtMDQtMzAgMjM6MDQ6MDZaIFplc3N0cmEgJAorLy8gc3BlbmRpZXJlIHVlYmVyYXJiZWl0ZXQsIDIyLjA1LjIwMDcgLSBNaXJpbAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL2NvbW1hbmRzLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorCisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPHJvb21zLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHJvdXRpbmdkLmg+CisjaW5jbHVkZSA8YmFuay5oPgorI2luY2x1ZGUgPGV4cGxvcmF0aW9uLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8cHViLmg+CisKKy8vIEFsbGUgbmljaHQtcHJpdmF0ZW4gd2VyZGVuIGluIGVyYmVuZW4gT2JqZWt0ZW4gdmVyd2VuZGV0LgorcHJpdmF0ZSBub3NhdmUgaW50ICAgICBtYXhfbGlzdDsKK3ByaXZhdGUgbm9zYXZlIGludCAgICAgcmVmcmVzaF9jb3VudDsKK3ByaXZhdGUgbm9zYXZlIGludCAgICAgc3VtOworcHJpdmF0ZSBub3NhdmUgbWFwcGluZyByZWZyZXNoX2xpc3Q7Citub3NhdmUgbWFwcGluZyBpZF9saXN0Oworbm9zYXZlIG1hcHBpbmcgbWVudV9saXN0Oworbm9zYXZlIG9iamVjdCAgKndhaXRpbmc7CisKKyNkZWZpbmUgUE1fUkFURV9QVUJNQVNURVIgICJyYXRlIgorI2RlZmluZSBQTV9ERUxBWV9QVUJNQVNURVIgImRlbGF5IgorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreyBvYmplY3Qgcm91dGVyOworCisgIFNldFByb3AoIFBfUk9PTV9UWVBFLCBRdWVyeVByb3AoUF9ST09NX1RZUEUpIHwgUlRfUFVCICk7CisKKyAgU2V0UHJvcCggUF9QVUJfTk9UX09OX01FTlUsCisgICAgIlR1dCBtaXIgbGVpZCwgZGFzIGZ1ZWhyZW4gd2lyIG5pY2h0ISBXaXIgc2luZCBlaW4gYW5zdGFlbmRpZ2VzICIrCisgICAgIkxva2FsIVxuIiApOworICBTZXRQcm9wKCBQX1BVQl9VTkFWQUlMQUJMRSwKKyAgICAiRGF2b24gaXN0IGxlaWRlciBuaWNodHMgbWVociBkYS5cbiIgKTsKKyAgU2V0UHJvcChQX1BVQl9OT19NT05FWSwKKyAgICAiRGFzIGtvc3RldCAlZCBHb2xkc3R1ZWNrZSwgdW5kIER1IGhhc3QgbmljaHQgc28gdmllbCFcbiIgKTsKKyAgU2V0UHJvcChQX1BVQl9OT19LRUVQRVIsCisgICAgIkVzIGlzdCBuaWVtYW5kIGFud2VzZW5kLCBkZXIgRGljaCBiZWRpZW5lbiBrb2VubnRlLlxuIik7CisKKyAgQWRkQ21kKCAibWVudWUiLCJtZW51ZSIgKTsKKyAgQWRkQ21kKCAoeyJrYXVmIiwia2F1ZmUiLCJiZXN0ZWxsIiwiYmVzdGVsbGUifSksImJlc3RlbGxlIiApOworICBBZGRDbWQoICh7InNwZW5kaWVyIiwic3BlbmRpZXJlIn0pLCJzcGVuZGllcmUiICk7CisgIEFkZENtZCggInB1YmluaXQiLCJwdWJpbml0IiApOworCisgIG1heF9saXN0PTA7CisgIHJlZnJlc2hfY291bnQ9MDsKKyAgd2FpdGluZyA9ICh7IH0pOworICBpZF9saXN0PShbXSk7CisgIG1lbnVfbGlzdD0oW10pOworICByZWZyZXNoX2xpc3Q9KFtdKTsKKworICBpZiAoICFjbG9uZXAoTUUpICYmIG9iamVjdHAocm91dGVyPWZpbmRfb2JqZWN0KFJPVVRFUikpICkKKyAgICByb3V0ZXItPlJlZ2lzdGVyVGFyZ2V0KFRBUkdFVF9QVUIsb2JqZWN0X25hbWUoTUUpKTsKKworICBjYWxsX291dCgiYWRkX3N0ZF9kcmlua3MiLDEpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKworLyogWnVyIFN5bnRheDoKKyAqCisgKiBtZW51ZXRleHQgLSBEZXIgVGV4dCBzdGVodCBpbSBNZW51ZQorICoKKyAqIGlkcyAgICAgICAtIEFycmF5IGRlciBOYW1lbiwgbWl0IGRlbmVuIGJlc3RlbGx0IHdlcmRlbiBrYW5uCisgKgorICogbWluZm8gICAgIC0gTWFwcGluZyBtaXQgRWludHJhZWdlbiBmdWVyOgorICogICAgICAgICAgICAgICAgIFBfSFAgKEhQLUhlaWx1bmcpLAorICogICAgICAgICAgICAgICAgIFBfU1AgKFNQLUhlaWx1bmcpLAorICogICAgICAgICAgICAgICAgIFBfRk9PRCAoU2FldHRpZ3VuZyksCisgKiAgICAgICAgICAgICAgICAgUF9EUklOSyAoRmx1ZXNzaWdrZWl0KQorICogICAgICAgICAgICAgICAgIFBfQUxDT0hPTCAoQWxrb2hvbGlzaWVydW5nKQorICogICAgICAgICAgICAgICAgIFBfVkFMVUUgKFByZWlzKQorICogICAgICAgICAgICAgRGllIEVpbnRyYWVnZSB3ZXJkZW4gdWViZXIgZXZhbF9hbnl0aGluZyBhdXNnZXdlcnRldAorICogICAgICAgICAgICAgKHNpZWhlIGRhKQorICoKKyAqIHJhdGUgICAgICAtIEhlaWxyYXRlIChhdWNoIHVlYmVyIGVhdmxfYW55dGhpbmcpIGluIFB1bmt0ZSAvIGhlYXJ0X2JlYXQoKQorICoKKyAqIG1zZyAgICAgICAtIE1lbGR1bmcgYmVpbSBFc3Nlbi4KKyAqICAgICAgICAgICAgIGEpIGNsb3N1cmUgKHdpcmQgbWl0IGZ1bmNhbGwobXNnLHphaGxlcixlbXBmYWVuZ2VyKQorICogICAgICAgICAgICAgICAgYXVzZ2V3ZXJ0ZXQpCisgKiAgICAgICAgICAgICBiKSBzdHJpbmcgKHdpZSBjbG9zdXJlOiBjYWxsX290aGVyKHRoaXNfb2JqZWN0Li4uKSkKKyAqICAgICAgICAgICAgIGMpIGFycmF5IG1pdCAyIHN0cmluZ3M6IDEpIGZ1ZXIgRXNzZW5kZW4sIDIpIGZ1ZXIgYW5kZXJlCisgKiAgICAgICAgICAgICAgICBzaWVoZSBhdWNoIG1lc3MoKQorICoKKyAqIHJlZnJlc2ggICAtIE1hcHBpbmcgbWl0IGRlbiBtb2VnbGljaGVuIEVpbnRyYWVnZW46CisgKiAgICAgICAgICAgICAgICAgUFJfVVNFUiA6IDxLb250aW5nZW50PiA7IDxVcGRhdGU+IChwcm8gU3BpZWxlcikKKyAqICAgICAgICAgICAgICAgICBQUl9BTEwgIDogPEtvbnRpbmdlbnQ+IDsgPFVwZGF0ZT4gKGZ1ZXIgYWxsZSkKKyAqICAgICAgICAgICAgIEVzIHdpcmQgenVuYWVjaHN0IGdlcHJ1ZWZ0LCBvYiBub2NoIGV0d2FzIGZ1ZXIgZGVuCisgKiAgICAgICAgICAgICAoemFobGVuZGVuISkgU3BpZWxlciBzZWxic3Qgdm9yaGFuZGVuIGlzdCB3ZW5uIG5laW4gd2lyZAorICogICAgICAgICAgICAgZ2VzY2hhdXQsIG9iIGRhcyBLb250aW5nZW50IGZ1ZXIgYWxsZSBzY2hvbiBlcnNjaG9lcGZ0IGlzdC4KKyAqICAgICAgICAgICAgIFNpbmQgYmVpZGUgS29udGluZ2VudGUgZXJzY2hvZXBmdCwga2FubiBkZXIgU3BpZWxlciBkYXMKKyAqICAgICAgICAgICAgIEJlc3RlbGx0ZSBuaWNodCBiZWtvbW1lbi4KKyAqICAgICAgICAgICAgIERpZSBLb250aW5nZW50ZSB3aXJkIGFsbGUgPFVwZGF0ZT4gcmVzZXQoKXMgImF1ZmdlZnJpc2NodCIuCisgKiAgICAgICAgICAgICA8S29udGluZ2VudD4gd2lyZCB1ZWJlciBldmFsX2FueXRoaW5nKCkgYXVzZ2V3ZXJ0ZXQuCisgKiAgICAgICAgICAgICBBbHRlcm5hdGl2IGthbm4gbWFuIGVpbmVuIEludC1XZXJ0IGFuZ2ViZW4uIERpZXNlciB3aXJkIHdpZQorICogICAgICAgICAgICAgKFsgUFJfQUxMIDogPHdlcnQ+IDsgMSBdKSBiZWhhbmRlbHQuCisgKgorICogZGVsYXkgICAgIC0gWmFobCBkZXIgU2VrdW5kZW4sIHVtIGRpZSB2ZXJ6b2VnZXJ0IGRpZSBIZWlsdW5nIGVpbnRyaXR0CisgKiAgICAgICAgICAgICB6LkIuIHdlaWwgZGFzIEVzc2VuIGVyc3QgenViZXJlaXRldCB3ZXJkZW4gbXVzcy4KKyAqICAgICAgICAgICAgIEViZW5mYWxscyB1ZWJlciBldmFsX2FueXRoaW5nKCkKKyAqCisgKiBkX21zZyAgICAgLSBNZWxkdW5nIGJlaW0gYmVzdGVsbGVuLCBmYWxscyBEZWxheS4gV2llIG1zZy4KKyAqLwordmFyYXJncyBzdHJpbmcgQWRkVG9NZW51KHN0cmluZyBtZW51ZXRleHQsIG1peGVkIGlkcywgbWFwcGluZyBtaW5mbywKKyAgICAgICAgICAgICAgICAgICAgICAgICBtaXhlZCByYXRlLCBtaXhlZCBtc2csIG1peGVkIHJlZnJlc2gsCisgICAgICAgICAgICAgICAgICAgICAgICAgbWl4ZWQgZGVsYXksIG1peGVkIGRfbXNnKQoreyBzdHJpbmcgaWRlbnQ7CisgIGludCBpOworCisgIGlmICggIXN0cmluZ3AobWVudWV0ZXh0KSB8fCAhaWRzIHx8ICFtYXBwaW5ncChtaW5mbykgKQorICAgIHJldHVybiAwOworCisgIGlmICggc3RyaW5ncChpZHMpICkKKyAgICBpZHMgPSAoeyBpZHMgfSk7CisgIGVsc2UgaWYgKCAhcG9pbnRlcnAoaWRzKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWRlbnQgPSBzcHJpbnRmKCJtZW51ZW50cnklZCIsbWF4X2xpc3QpOworICBtYXhfbGlzdCsrOworCisgIC8qIEZ1ZXIgc2NobmVsbGVzIE5hY2hzY2hsYWdlbiBlaW4gZWlnZW5lcyBNYXBwaW5nIGZ1ZXIgSWRzICovCisgIGZvciggaT1zaXplb2YoaWRzKS0xO2k+PTA7aS0tICkKKyAgICBpZF9saXN0ICs9IChbIGlkc1tpXSA6IGlkZW50IF0pOworCisgIGlmICggaW50cChyZWZyZXNoKSAmJiAocmVmcmVzaD4wKSApCisgICAgcmVmcmVzaCA9IChbIFBSX0FMTCA6IHJlZnJlc2g7IDEgXSk7CisgIGVsc2UgaWYgKCAhbWFwcGluZ3AocmVmcmVzaCkgKQorICAgIHJlZnJlc2ggPSAwOworCisgIG1lbnVfbGlzdCArPSAoWyBpZGVudCA6IG1lbnVldGV4dDsgbWluZm87IHJhdGU7IG1zZzsgcmVmcmVzaDsKKyAgICAgICAgICAgICAgICAgICBkZWxheTsgZF9tc2c7IGlkcyBdKTsKKyAgcmV0dXJuIGlkZW50OworfQorCisvLyBEaWVzZSBNZXRob2RlIGlzdCBudXIgbm9jaCBhdXMgS29tcGF0aWJpbGl0YWV0c2dydWVuZGVuIHZvcmhhbmRlbiB1bmQgZGFyZgorLy8gbmljaHQgbWVociB2ZXJ3ZW5kZXQgd2VyZGVuISEhCit2b2lkIEFkZEZvb2Qoc3RyaW5nIG5hbWVPZkZvb2QsIG1peGVkIGlkcywgaW50IHByaWNlLCBpbnQgaGVhbCwKKyAgICAgICAgICAgICBtaXhlZCBteUZ1bmN0aW9uKQoreworICBpZiAoICFuYW1lT2ZGb29kIHx8ICFpZHMgfHwgIXByaWNlKQorICAgIHJldHVybjsgLyogRm9vZCBub3QgaGVhbGluZyBpcyBvayAhICovCisKKyAgQWRkVG9NZW51KCBuYW1lT2ZGb29kLGlkcywKKyAgICAgICAgICAgICAoWyBQX1ZBTFVFIDogcHJpY2UsIFBfRk9PRCA6IGhlYWwsIFBfSFAgOiBoZWFsLCBQX1NQIDogaGVhbCBdKSwKKyAgICAgICAgICAgICAoKGhlYWw+NSk/NTpoZWFsKSwgbXlGdW5jdGlvbiwgMCwwLDApOworfQorCisvLyBEaWVzZSBNZXRob2RlIGlzdCBudXIgbm9jaCBhdXMgS29tcGF0aWJpbGl0YWV0c2dydWVuZGVuIHZvcmhhbmRlbiB1bmQgZGFyZgorLy8gbmljaHQgbWVociB2ZXJ3ZW5kZXQgd2VyZGVuISEhCit2b2lkIEFkZERyaW5rKHN0cmluZyBuYW1lT2ZEcmluaywgbWl4ZWQgaWRzLCBpbnQgcHJpY2UsIGludCBoZWFsLAorICAgICAgICAgICAgICBpbnQgc3RyZW5ndGgsIGludCBzb2FrLCBtaXhlZCBteUZ1bmN0aW9uKQoreworICBpZiAoICFuYW1lT2ZEcmluayB8fCAhaWRzIHx8ICFwcmljZSApCisgICAgcmV0dXJuOworCisgIGhlYWw9aGVhbC8yOworICAvKiBLbGVpbmUgS29ycmVrdHVyLCBkYW1pdCBtYW4gaW4gYWx0ZW4gUHVicyB1ZWJlcmhhdXB0IHRyaW5rZW4ga2FubiAqLworICBBZGRUb01lbnUobmFtZU9mRHJpbmssaWRzLAorICAgICAgICAgICAgIChbIFBfVkFMVUUgOiBwcmljZSwgUF9EUklOSyA6IHNvYWssIFBfQUxDT0hPTCA6IHN0cmVuZ3RoLAorICAgICAgICAgICAgICAgIFBfSFAgOiBoZWFsLCBQX1NQIDogaGVhbCBdKSwKKyAgICAgICAgICAgICAoKGhlYWw+NSk/NTpoZWFsKSwgbXlGdW5jdGlvbiwwLDAsMCk7Cit9CisKK2ludCBSZW1vdmVGcm9tTWVudShtaXhlZCBpZHMpIHsKKyAgaW50IHJldDsKKworICBpZiAoc3RyaW5ncChpZHMpKQorICAgIGlkcyA9ICh7aWRzfSk7CisKKyAgaWYgKHBvaW50ZXJwKGlkcykpIHsKKyAgICBmb3JlYWNoIChzdHJpbmcgaWQ6IGlkcykgeworICAgICAgLy8gbG9vayBpZiB0aGUgaWQgaGFzIGEgbWF0Y2hpbmcgaWRlbnQKKyAgICAgIHN0cmluZyBpZGVudCA9IGlkX2xpc3RbaWRdOworICAgICAgaWYgKHN0cmluZ3AoaWRlbnQpKSB7CisgICAgICAgIC8vIHJlbW92ZSB0aGlzIGlkZW50LWVudHJ5IGZyb20gdGhlIGlkLWxpc3QgLi4uCisgICAgICAgIG1fZGVsZXRlKGlkX2xpc3QsIGlkKTsKKyAgICAgICAgLy8gLi4uIGFuZCByZW1vdmUgYWxsIG90aGVycyBub3cgdG9vIChzbyBpdCB3b24ndCBidWcgbGF0ZXIsIGlmCisgICAgICAgIC8vICAgICB0aGUgd2l6YXJkIGNhbGxpbmcgdGhpcyBtZXRob2QgZm9yZ290IGFuIGlkKQorICAgICAgICBmb3JlYWNoIChzdHJpbmcgbGlzdGlkOiBtX2luZGljZXMoaWRfbGlzdCkpCisgICAgICAgICAgaWYgKGlkX2xpc3RbbGlzdGlkXSA9PSBpZGVudCkKKyAgICAgICAgICAgIG1fZGVsZXRlKGlkX2xpc3QsIGxpc3RpZCk7CisKKyAgICAgICAgLy8gbm93IHJlbW92ZSB0aGUgaWRlbnQgZnJvbSB0aGUgbWVudV9saXN0CisgICAgICAgIGlmIChtZW1iZXIobWVudV9saXN0LCBpZGVudCkpIHsKKyAgICAgICAgICByZXQrKzsKKyAgICAgICAgICBtX2RlbGV0ZShtZW51X2xpc3QsIGlkZW50KTsKKworICAgICAgICAgIC8vIGRlY3JlYXNlIHRoZSBpZGVudC1jb3VudGVyLCBpZiB0aGlzIGVudHJ5IHdhcyB0aGUgbGFzdCBvbmUKKyAgICAgICAgICBpbnQgb2xkbnVtOworICAgICAgICAgIGlmIChzc2NhbmYoaWRlbnQsICJtZW51ZW50cnklZCIsIG9sZG51bSkgPT0gMSAmJgorICAgICAgICAgICAgICBvbGRudW0gPT0gKG1heF9saXN0LTEpKQorICAgICAgICAgICAgbWF4X2xpc3QtLTsKKyAgICAgICAgfQorICAgICAgfQorICAgIH0KKyAgfQorICAvLyByZXR1cm4gcmVtb3ZlZCBlbnRyaWVzCisgIHJldHVybiByZXQ7Cit9CisKKy8qIFp1bSBBdXN3ZXJ0ZW4gZGVyIEVpbnRyYWVnZSBmdWVyIFByZWlzLCBSYXRlLCBIUC4uLgorICogYSkgaW50ZWdlci1XZXJ0ICAgIC0+IHdpcmQgZGlyZWt0IHVlYmVybm9tbWVuCisgKiBiKSBtYXBwaW5nICAgICAgICAgLT4gV2lyZCBhbHMgUmFjZU1vZGlmaWVyZSB2ZXJzdGFuZGVuLiBFcyB3aXJkIGRlcgorICogICAgICAgICAgICAgICAgICAgICAgIEVpbnRyYWcgZ2V3YWVobHQsIGRlciBkZXIgUmFzc2UgZGVzIFNwaWVsZXJzCisgKiAgICAgICAgICAgICAgICAgICAgICAgZW50c3ByaWNodCwgZmFsbHMgdm9yaGFuZGVuLCBhbnNvbnN0ZW4gZGVyIEVpbnRyYWcKKyAqICAgICAgICAgICAgICAgICAgICAgICBmdWVyIDAuCisgKiBjKSBBcnJheSAgICAgICAgICAgLT4gSW4gZXJzdGVtIEVsZW1lbnQgKG11c3MgT2JqZWt0IG9kZXIgZGVzc2VuIEZpbGVuYW1lCisgKiAgICAgICAgICAgICAgICAgICAgICAgc2Vpbikgd2lyZCBkaWUgRnVua3Rpb24gbWl0IGRlbSBOYW1lbiBpbSAyLkVsZW1lbnQKKyAqICAgICAgICAgICAgICAgICAgICAgICBhdWZnZXJ1ZmVuLgorICogZCkgU3RyaW5nICAgICAgICAgIC0+IERpZSBnZW5hbm50ZSBGdW5rdGlvbiB3aXJkIGluIGRlciBLbmVpcGUgc2VsYnN0CisgKiAgICAgICAgICAgICAgICAgICAgICAgYXVmZ2VydWZlbi4KKyAqIGUpIENsb3N1cmUgICAgICAgICAtPiBEaWUgQ2xvc3VyZSB3aXJkIGF1c2dld2VydGV0LgorICogQWxsZSBGdW5rdGlvbnNhdWZydWZlIGJla29tbWVuIGRlbiBlc3NlbmRlbiBTcGllbGVyIChiZWkgUHJpY2UgdW5kIERlbGF5CisgKiBkZW4gYmVzdGVsbGVuZGVuIFNwaWVsZXIpIGFscyBBcmd1bWVudCB1ZWJlcmdlYmVuLiBEaWUgQXVzd2VydHVuZyBlcmZvbGd0CisgKiBpbiBkZXIgYW5nZWdlYmVuZW4gUmVpaGVuZm9sZ2UuIEFtIEVuZGUgbXVzcyBlaW4gSW50ZXJnZXJ3ZXJ0IGhlcmF1c2tvbW1lbgorICovCitpbnQgZXZhbF9hbnl0aGluZyhtaXhlZCB3aGF0LCBvYmplY3QgcGwpCit7IG1peGVkIHJlOworCisgIGlmIChpbnRwKHdoYXQpKQorICAgIHJldHVybiB3aGF0OworCisgIGlmIChtYXBwaW5ncCh3aGF0KSAmJiBwbCkKKyAgeworICAgIHJlID0gd2hhdFtwbC0+UXVlcnlQcm9wKFBfUkFDRSldfHx3aGF0WzBdOworICB9CisKKyAgaWYgKHJlKQorICAgIHdoYXQ9cmU7CisKKyAgaWYgKCBwb2ludGVycCh3aGF0KSAmJiAoc2l6ZW9mKHdoYXQpPj0yKQorICAgICAgJiYgKCBvYmplY3RwKHdoYXRbMF0pIHx8IHN0cmluZ3Aod2hhdFswXSkgKQorICAgICAgJiYgc3RyaW5ncCh3aGF0WzFdKSApCisgICAgd2hhdCA9IGNhbGxfb3RoZXIod2hhdFswXSx3aGF0WzFdLHBsKTsKKworICBpZiAoIHN0cmluZ3Aod2hhdCkgJiYgZnVuY3Rpb25fZXhpc3RzKHdoYXQsTUUpICkKKyAgICB3aGF0ID0gY2FsbF9vdGhlcihNRSx3aGF0LHBsKTsKKworICBpZiAoIGNsb3N1cmVwKHdoYXQpICkKKyAgICB3aGF0ID0gZnVuY2FsbCh3aGF0LHBsKTsKKworICBpZiAoIGludHAod2hhdCkgKQorICAgIHJldHVybiB3aGF0OworCisgIHJldHVybiAwOworfQorCisvKiBEaWVzZSBGdW5rdGlvbiB1ZWJlcnBydWVmdCwgb2IgZGFzIEtvbnRpbmdlbnQgZWluZXMgTWVudWVlaW50cmFncworICogZnVlciBlaW5lbiBTcGllbGVyIGVyc2Nob2VwZnQgaXN0LgorICovCitzdHJpbmcgQ2hlY2tBdmFpbGFiaWxpdHkoc3RyaW5nIGlkZW50LCBvYmplY3QgemFobGVyKQoreyBzdHJpbmcgdWlkOworCisgIGlmICggIXN0cmluZ3AoaWRlbnQpIHx8ICFtZW1iZXIobWVudV9saXN0LGlkZW50KSB8fCAhb2JqZWN0cCh6YWhsZXIpICkKKyAgICByZXR1cm4gMDsKKyAgaWYgKCAhbWFwcGluZ3AobWVudV9saXN0W2lkZW50LFBNX1JFRlJFU0hdKSApCisgICAgcmV0dXJuIFBSX05PTkU7CisKKyAgaWYgKCAhbWVtYmVyKHJlZnJlc2hfbGlzdCxpZGVudCkgKQorICAgIHJlZnJlc2hfbGlzdCArPSAoWyBpZGVudCA6IChbIF0pIF0pOworCisgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh6YWhsZXIpICkKKyAgICB1aWQ9Z2V0dWlkKHphaGxlcik7CisgIGVsc2UKKyAgICB1aWQ9b2JqZWN0X25hbWUoemFobGVyKTsKKworICBpZiAoIG1lbWJlcihtZW51X2xpc3RbaWRlbnQsUE1fUkVGUkVTSF0sUFJfVVNFUikgKQorICB7CisgICAgaWYgKCAhbWVtYmVyKHJlZnJlc2hfbGlzdFtpZGVudF0sdWlkKSApCisgICAgeworICAgICAgcmVmcmVzaF9saXN0W2lkZW50XSArPSAoWyB1aWQgOiAwIDsgcmVmcmVzaF9jb3VudCBdKTsKKyAgICB9CisKKyAgICAvKiBLb250aW5nZW50IGRlcyBaYWhsZW5kZW4gcHJ1ZWZlbiAqLworICAgIGlmICggcmVmcmVzaF9saXN0W2lkZW50XVt1aWQsUFJWX0FNT1VOVF0gPAorICAgICAgICAgIGV2YWxfYW55dGhpbmcobWVudV9saXN0W2lkZW50LFBNX1JFRlJFU0hdW1BSX1VTRVIsUFJWX0FNT1VOVF0sCisgICAgICAgICAgICAgICAgICAgICAgICB6YWhsZXIpICkKKyAgICAgIHJldHVybiB1aWQ7CisgIH0KKworICBpZiAoIG1lbWJlcihtZW51X2xpc3RbaWRlbnQsUE1fUkVGUkVTSF0sUFJfQUxMKSApCisgIHsKKyAgICBpZiAoICFtZW1iZXIocmVmcmVzaF9saXN0W2lkZW50XSxQUl9ERUZBVUxUKSApCisgICAgeworICAgICAgcmVmcmVzaF9saXN0W2lkZW50XSArPSAoWyBQUl9ERUZBVUxUIDogMCA7IHJlZnJlc2hfY291bnQgXSk7CisgICAgfQorCisgICAgLyogS29udGluZ2VudCBkZXIgQWxsZ2VtZWluaGVpdCBwcnVlZmVuICovCisgICAgaWYgKCByZWZyZXNoX2xpc3RbaWRlbnRdW1BSX0RFRkFVTFQsUFJWX0FNT1VOVF0gPAorICAgICAgICAgIGV2YWxfYW55dGhpbmcobWVudV9saXN0W2lkZW50LFBNX1JFRlJFU0hdW1BSX0FMTCxQUlZfQU1PVU5UXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHphaGxlcikgKQorICAgICAgcmV0dXJuIFBSX0RFRkFVTFQ7CisgIH0KKworICByZXR1cm4gMDsKK30KKworLyogRGllc2UgRnVua3Rpb24gcmVkdXppZXJ0IGRhcyBLb250aW5nZW50IGRlcyBMZWJld2VzZW5zIHVpZCBiZWltCisgKiBNZW51ZWVpbnRyYWcgaWRlbnQgdW0gMQorICovCit2b2lkIERlY3JlYXNlQXZhaWxhYmlsaXR5KHN0cmluZyBpZGVudCwgc3RyaW5nIHVpZCkKK3sKKyAgaWYgKCAhc3RyaW5ncChpZGVudCkgfHwgIXN0cmluZ3AodWlkKSApCisgICAgcmV0dXJuOworICByZWZyZXNoX2xpc3RbaWRlbnRdW3VpZCxQUlZfQU1PVU5UXSsrOworfQorCisvKiBEaWVzZSBGdW5rdGlvbiBzb3JndCBkYWZ1ZXIsIGRhc3MgZGllIEtvbnRpbmdlbnRlIGFuIGxpbWl0aWVydGVuCisgKiBTYWNoZW4gaW4gcmVnZWxtYWVzc2lnZW4gQWJzdGFlbmRlbiB3aWVkZXJoZXJnZXN0ZWxsdCB3ZXJkZW4uCisgKi8KK3N0YXRpYyB2b2lkIFVwZGF0ZUF2YWlsYWJpbGl0eSgpCit7IGludCAgICBpMSxpMjsKKyAgc3RyaW5nICppbmQxLCppbmQyLGNoazsKKworICAvKiBLZWluZSBSZWZyZXNoLUVpbnRyYWVnZSwga2VpbiBVcGRhdGUgKi8KKyAgaWYgKCAhbWFwcGluZ3AocmVmcmVzaF9saXN0KQorICAgICAgfHwgKGkxPXNpemVvZihpbmQxPW1faW5kaWNlcyhyZWZyZXNoX2xpc3QpKSk8MSApCisgICAgcmV0dXJuOworCisgIC8qIEVzIG11c3MgamVkZXIgTWVudWVlaW50cmFnLCBkZXIgaW4gZGVyIHJlZnJlc2hfbGlzdCBzdGVodCwKKyAgICogZHVyY2hnZWdhbmdlbiB3ZXJkZW4uCisgICAqLworICBmb3IgKCAtLWkxIDsgaTE+PTAgOyBpMS0tICkKKyAgeworICAgIGlmICggIW1hcHBpbmdwKHJlZnJlc2hfbGlzdFtpbmQxW2kxXV0pCisgICAgICAgIHx8IChpMj1zaXplb2YoaW5kMj1tX2luZGljZXMocmVmcmVzaF9saXN0W2luZDFbaTFdXSkpKTwxICkKKyAgICAgIGNvbnRpbnVlOworCisgICAgLyogRnVlciBqZWRlbiBNZW51ZWVpbnRyYWcgbXVzcyBqZWRlciBTcGllbGVyZWludHJhZyBkdXJjaGdlZ2FuZ2VuCisgICAgICogd2VyZGVuLCBkZXIgaW4gZGVtIGVudHNwci4gbWFwcGluZyBzdGVodC4KKyAgICAgKi8KKyAgICBmb3IgKCAtLWkyIDsgaTI+PTAgOyBpMi0tICkgLy8gQWxsZSBTcGllbGVyCisgICAgeworICAgICAgaWYgKCBpbmQyW2kyXT09UFJfREVGQVVMVCApCisgICAgICAgIGNoayA9IFBSX0FMTDsKKyAgICAgIGVsc2UKKyAgICAgICAgY2hrID0gUFJfVVNFUjsKKworICAgICAgaWYgKCAoIHJlZnJlc2hfbGlzdFtpbmQxW2kxXV1baW5kMltpMl0sUFJWX1JFRlJFU0hdCisgICAgICAgICAgICArIG1lbnVfbGlzdFtpbmQxW2kxXSxQTV9SRUZSRVNIXVtjaGssUFJWX1JFRlJFU0hdICkKKyAgICAgICAgICA8PSByZWZyZXNoX2NvdW50ICkKKyAgICAgIHsKKyAgICAgICAgcmVmcmVzaF9saXN0W2luZDFbaTFdXVtpbmQyW2kyXSxQUlZfQU1PVU5UXT0wOworICAgICAgICByZWZyZXNoX2xpc3RbaW5kMVtpMV1dW2luZDJbaTJdLFBSVl9SRUZSRVNIXT1yZWZyZXNoX2NvdW50OworICAgICAgfQorICAgIH0KKyAgfQorfQorCittaXhlZCBEQkcobWl4ZWQgbykgeworICBpZihmaW5kX3BsYXllcigicnVtYXRhIikpCisgICAgdGVsbF9vYmplY3QoCisgICAgICAgIGZpbmRfcGxheWVyKCJydW1hdGEiKSwKKyAgICAgICAgc3ByaW50ZigiREJHOiAlT1xuIiwgbykKKyAgICApOworICByZXR1cm4gMDsKK30KKworLyogRXJ3ZWl0ZXJ0IHVtIGRpZSBNb2VnbGljaGtlaXQsIFNwZWlzZS0gb2RlciBHZXRyYWVua2UtS2FydGUgenUgc2VoZW4uICovCitzdHJpbmcgbWVudWVfdGV4dChzdHJpbmcgc3RyKQoreyBpbnQgaSxzZHIsc2ZvOworICBzdHJpbmcgaWRlbnQscmVzOworICBzdHJpbmcgKmZvPSh7fSksKmRyPSh7fSk7CisKKyAgaWYgKCAhbWF4X2xpc3QgKQorICAgIHJldHVybiAiSGllciBzY2hlaW50IGVzIGRlcnplaXQgbmljaHRzIHp1IGdlYmVuLlxuIjsKKworICBpZiAoICFzdHJpbmdwKHN0cikgfHwgc3RyPT0iIiApCisgICAgc3RyPSJhbGxlcyI7CisKKyAgLyogRnVlcnMgTWVudWUgZW50c2NoZWlkZW4gb2IgRHJpbmsgb2RlciBGb29kICovCisgIGZvcmVhY2goc3RyaW5nIGlkLCBzdHJpbmcgbWVudWV0ZXh0LCBtYXBwaW5nIG1pbmZvOiBtZW51X2xpc3QpCisgIHsKKyAgICBpZiAoZXZhbF9hbnl0aGluZyhtaW5mb1tQX0ZPT0RdLHRoaXNfcGxheWVyKCkpKQorICAgICAgZm8rPSh7IGlkIH0pOworICAgIGVsc2UKKyAgICAgIGRyKz0oeyBpZCB9KTsKKyAgfQorCisgIHNkciA9IHNpemVvZihkcik7CisgIHNmbyA9IHNpemVvZihmbyk7CisKKyAgaWYgKCBtZW1iZXIoKHsiYWxsZSIsImFsbGVzIn0pLHN0cikhPS0xKQorICB7CisgICAgaWYgKCAhc2ZvICkKKyAgICAgIHN0cj0iZHJpbmtzIjsKKyAgICBlbHNlIGlmICggIXNkciApCisgICAgICBzdHI9InNwZWlzZSI7CisgICAgZWxzZQorICAgIHsKKyAgICAgIC8qIEdlbWlzY2h0ZSBLYXJ0ZSAqLworICAgICAgcmVzID0gIkdldHJhZW5rZSAgICAgICAgICAgICAgICAgICAgUHJlaXMgYWxjIHwgIisKKyAgICAgICAgICAgICJTcGVpc2VuICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVpc1xuIisKKyAgICAgICAgICAgICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLSIrCisgICAgICAgICAgICAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CisKKyAgICAgIGZvciAoIGk9MCA7ICggaTxzZHIgfHwgaTxzZm8gKSA7IGkrKyApCisgICAgICB7CisgICAgICAgIGlmICggaTxzZHIgKQorICAgICAgICAgIHJlcyArPSBzcHJpbnRmKCIlLTI5LjI5cyU1LjVkICAlYyAgfCAiLAorICAgICAgICAgICAgICAgICAgIG1lbnVfbGlzdFtkcltpXSxQTV9URVhUXSwKKyAgICAgICAgICAgICAgICAgICBldmFsX2FueXRoaW5nKG1lbnVfbGlzdFtkcltpXSxQTV9JTkZPXVtQX1ZBTFVFXSxQTCksCisgICAgICAgICAgICAgICAgICAgKGV2YWxfYW55dGhpbmcobWVudV9saXN0W2RyW2ldLFBNX0lORk9dW1BfQUxDT0hPTF0sUEwpPjApID8gJ0onIDogJ04nKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgIHJlcyArPSAiICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAiOworCisgICAgICAgIGlmICggaTxzZm8gKQorICAgICAgICAgIHJlcyArPSBzcHJpbnRmKCIlLTMzLjMzcyU1LjVkIiwKKyAgICAgICAgICAgICAgICAgICBtZW51X2xpc3RbZm9baV0sUE1fVEVYVF0sCisgICAgICAgICAgICAgICAgICAgZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbZm9baV0sUE1fSU5GT11bUF9WQUxVRV0sUEwpKTsKKworICAgICAgICByZXMgKz0gIlxuIjsKKyAgICAgIH0KKworICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisgIH0KKworICAvKiBSZWluZSBHZXRyYWVua2VrYXJ0ZSAqLworICBpZiAoIG1lbWJlcigoeyJnZXRyYWVua2UiLCJkcmlua3MiLCJnZXRyYWVuayIsInRyaW5rZW4ifSksc3RyKSE9LTEgKQorICB7CisgICAgaWYgKCAhc2RyICkKKyAgICAgIHJldHVybiAiSGllciBnaWJ0IGVzIGxlaWRlciBuaWNodHMgenUgdHJpbmtlbi5cbiI7CisKKyAgICByZXMgPSAiR2V0cmFlbmtlICAgICAgICAgICAgICAgICAgICBQcmVpcyBhbGMgfCAiKworICAgICAgICAgICJHZXRyYWVua2UgICAgICAgICAgICAgICAgICAgIFByZWlzIGFsY1xuIisKKyAgICAgICAgICAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0iKworICAgICAgICAgICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuIjsKKworICAgIGZvciAoIGk9MCA7IGk8c2RyIDsgaSsrICkKKyAgICB7CisgICAgICBpZGVudCA9IGRyW2ldOworCisgICAgICBpZiAoICFldmFsX2FueXRoaW5nKG1lbnVfbGlzdFtpZGVudCxQTV9JTkZPXVtQX0ZPT0RdLCBQTCkgKQorICAgICAgICByZXMgKz0gc3ByaW50ZigiJS0yOS4yOXMlNS41ZCAgJWMlcyIsCisgICAgICAgICAgICAgICAgIG1lbnVfbGlzdFtpZGVudCxQTV9URVhUXSwKKyAgICAgICAgICAgICAgICAgZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbaWRlbnQsUE1fSU5GT11bUF9WQUxVRV0sUEwpLAorICAgICAgICAgICAgICAgICAoZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbaWRlbnQsUE1fSU5GT11bUF9BTENPSE9MXSxQTCk+MCkgPyAnSicgOiAnTicsCisgICAgICAgICAgICAgICAgICgoaSUyKT8iXG4iOiIgIHwgIikpOworICAgIH0KKworICAgIGlmICggcmVzWzwxLi48MV0hPSJcbiIgKQorICAgICAgcmVzICs9ICJcbiI7CisKKyAgICByZXR1cm4gcmVzOworICB9CisKKyAgLyogUmVpbmUgU3BlaXNla2FydGUgKi8KKyAgaWYgKCBtZW1iZXIoKHsic3BlaXNlIiwic3BlaXNlbiIsImVzc2VuIn0pLHN0cikhPS0xICkKKyAgeworICAgIGlmICggIXNmbyApCisgICAgICByZXR1cm4gIkhpZXIgZ2lidCBlcyBsZWlkZXIgbmljaHRzIHp1IGVzc2VuLlxuIjsKKworICAgIHJlcyA9ICJTcGVpc2VuICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVpcyB8ICIrCisgICAgICAgICAgIlNwZWlzZW4gICAgICAgICAgICAgICAgICAgICAgICAgIFByZWlzXG4iKworICAgICAgICAgICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0rLSIrCisgICAgICAgICAgIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iOworCisgICAgZm9yICggaT0wIDsgaTxzZm8gOyBpKysgKQorICAgIHsKKyAgICAgIGlkZW50ID0gZm9baV07CisgICAgICBpZiAoZXZhbF9hbnl0aGluZyhtZW51X2xpc3RbaWRlbnQsUE1fSU5GT11bUF9GT09EXSxQTCkgKQorICAgICAgICByZXMgKz0gc3ByaW50ZigiJS0zMy4zM3MlNS41ZCVzIiwKKyAgICAgICAgICAgICAgICAgbWVudV9saXN0W2lkZW50LFBNX1RFWFRdLAorICAgICAgICAgICAgICAgICBldmFsX2FueXRoaW5nKG1lbnVfbGlzdFtpZGVudCxQTV9JTkZPXVtQX1ZBTFVFXSxQTCksCisgICAgICAgICAgICAgICAgICgoaSUyKT8iXG4iOiIgfCAiKSk7CisgICAgfQorCisgICAgaWYgKCByZXNbPDEuLjwxXSE9IlxuIiApCisgICAgICByZXMgKz0gIlxuIjsKKworICAgIHJldHVybiByZXM7CisgIH0KKworICByZXR1cm4gMDsKK30KKworaW50IG1lbnVlKHN0cmluZyBzdHIpCit7IHN0cmluZyB0eHQ7CisKKyAgX25vdGlmeV9mYWlsKCJXZWxjaGVuIFRlaWwgZGVzIE1lbnVlcyBtb2VjaHRlc3QgRHUgc2VoZW4/XG4iKTsKKyAgaWYgKCAhc3RyaW5ncCh0eHQ9bWVudWVfdGV4dChzdHIpKSB8fCBzaXplb2YodHh0KTwxICkKKyAgICByZXR1cm4gMDsKKyAgd3JpdGUodHh0KTsKKyAgcmV0dXJuIDE7Cit9CisKKy8qIERpZXNlIEZ1bmt0aW9uIGthbm4vc29sbCBiZWkgQmVkYXJmIHVlYmVybGFkZW4gd2VyZGVuLCB1bSBzaW11bHRhbmUKKyAqIEFlbmRlcnVuZ2VuIGRlcyBNYXBwaW5ncyB6dSBlcm1vZWdsaWNoZW4gKHp1IEJlaXNwaWVsIHdpZSBlcyBpbiBndXRlbgorICogVGFnZW4gZ3JvZXNzZXIgUG9ydGlvbmVuIGdpYiwgSG9iYml0cyBwZXIgc2UgbWVociBrcmllZ2VuLCAuLi4KKyAqLworbWFwcGluZyBhZGp1c3RfaW5mbyhzdHJpbmcgaWRlbnQsIG1hcHBpbmcgbWluZm8sIG9iamVjdCB6YWhsZXIsCisgICAgICAgICAgICAgICAgICAgIG9iamVjdCBlbXBmYWVuZ2VyKQoreworICByZXR1cm4gMDsKK30KKworLyogSGllciBoYXRzIGplZGUgTWVuZ2UgbmV1ZSBQbGF0emhhbHRlciAqLworc3RyaW5nIG1lc3Moc3RyaW5nIHN0cixvYmplY3QgcGwpCit7CisgIHN0cmluZyBkdW1teTEsIGR1bW15MjsKKworICBpZiAoICFwbCApCisgICAgcGw9UEw7CisKKyAgaWYgKCAhc3RyaW5ncChzdHIpIHx8IHN0cj09IiIgKQorICAgIHJldHVybiBzdHI7CisKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiYmIikscGwtPm5hbWUoV0VSLDIpKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiYxJiIpLHBsLT5uYW1lKFdFUiwyKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImMiYiKSxwbC0+bmFtZShXRVNTRU4sMikpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjMmIikscGwtPm5hbWUoV0VNLDIpKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiY0JiIpLHBsLT5uYW1lKFdFTiwyKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImMSMiKSxjYXBpdGFsaXplKHBsLT5uYW1lKFdFUiwyKSkpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjIjIiksY2FwaXRhbGl6ZShwbC0+bmFtZShXRVNTRU4sMikpKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiYzIyIpLGNhcGl0YWxpemUocGwtPm5hbWUoV0VNLDIpKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImNCMiKSxjYXBpdGFsaXplKHBsLT5uYW1lKFdFTiwyKSkpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJiEiKSxwbC0+UXVlcnlQcm9ub3VuKFdFUikpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjUmIikscGwtPlF1ZXJ5UHJvbm91bihXRVIpKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiY2JiIpLHBsLT5RdWVyeVByb25vdW4oV0VTU0VOKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImNyYiKSxwbC0+UXVlcnlQcm9ub3VuKFdFTSkpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjgmIikscGwtPlF1ZXJ5UHJvbm91bihXRU4pKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiY1IyIpLGNhcGl0YWxpemUocGwtPlF1ZXJ5UHJvbm91bihXRVIpKSk7CisgIHN0cj1pbXBsb2RlKGV4cGxvZGUoc3RyLCImNiMiKSxjYXBpdGFsaXplKHBsLT5RdWVyeVByb25vdW4oV0VTU0VOKSkpOworICBzdHI9aW1wbG9kZShleHBsb2RlKHN0ciwiJjcjIiksY2FwaXRhbGl6ZShwbC0+UXVlcnlQcm9ub3VuKFdFTSkpKTsKKyAgc3RyPWltcGxvZGUoZXhwbG9kZShzdHIsIiY4IyIpLGNhcGl0YWxpemUocGwtPlF1ZXJ5UHJvbm91bihXRU4pKSk7CisKKyAgcmV0dXJuIGJyZWFrX3N0cmluZyhjYXBpdGFsaXplKHN0ciksNzgsIiIsIEJTX0xFQVZFX01ZX0xGUyk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIF9jb3B5X21lbnVsaXN0X3ZhbHVlcyhtYXBwaW5nIGVudHJ5aW5mbywgc3RyaW5nIGlkZW50KSB7CisgIC8qIEtvcGllcmVuIGFsbGVyIFdlcnRlIGlucyBtaW5mby1NYXBwaW5nLCB1bSBQcm9ibGVtZW4gYmVpIExvZXNjaHVuZworICAgICBhdXMgZGVtIFdlZyB6dSBnZWhlbi4gU2xvdyBhbmQgZGlydHkgKi8KKyAgZW50cnlpbmZvW1BNX1RFWFRdICAgICAgPSBkZWVwX2NvcHkobWVudV9saXN0W2lkZW50LCBQTV9URVhUXSk7CisgIC8vIFBNX0lORk8gaXMgYWxyZWFkeSBmbGF0IGluIGVudHJ5aW5mbworICBlbnRyeWluZm9bUE1fUkFURV9QVUJNQVNURVJdCisgICAgICAgICAgICAgICAgICAgICAgICAgID0gZGVlcF9jb3B5KG1lbnVfbGlzdFtpZGVudCwgUE1fUkFURV0pOworICBlbnRyeWluZm9bUE1fU0VSVkVfTVNHXSA9IGRlZXBfY29weShtZW51X2xpc3RbaWRlbnQsIFBNX1NFUlZFX01TR10pOworICBlbnRyeWluZm9bUE1fUkVGUkVTSF0gICA9IGRlZXBfY29weShtZW51X2xpc3RbaWRlbnQsIFBNX1JFRlJFU0hdKTsKKyAgLy8gUE1fREVMQVkgaXMgYWxyZWFkeSBldmFsdWF0ZWQgaW4gZW50cnlpbmZvCisgIGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddID0gZGVlcF9jb3B5KG1lbnVfbGlzdFtpZGVudCwgUE1fREVMQVlfTVNHXSk7CisgIGVudHJ5aW5mb1tQTV9JRFNdICAgICAgID0gZGVlcF9jb3B5KG1lbnVfbGlzdFtpZGVudCwgUE1fSURTXSk7Cit9CisKK2ludCBkb19kZWxpdmVyKHN0cmluZyBpZGVudCwgb2JqZWN0IHphaGxlciwgb2JqZWN0IGVtcGZhZW5nZXIsCisgICAgICAgICAgICAgICBtYXBwaW5nIGVudHJ5aW5mbykgeworICB3YWl0aW5nIC09ICh7IGVtcGZhZW5nZXIsMCB9KTsKKworICAvKiBFbXBmYWVuZ2VyIG11c3MgbmF0dWVybGljaCBub2NoIGRhIHNlaW4gKi8KKyAgaWYgKCAhb2JqZWN0cChlbXBmYWVuZ2VyKSB8fCAhcHJlc2VudChlbXBmYWVuZ2VyKSApCisgICAgcmV0dXJuIDA7CisKKyAgLyogWmFobGVyIHdpcmQgbnVyIHdlZ2VuIGRlciBBYndhZXJ0c2tvbXBhdGliaWxpdGFldCBnZWJyYXVjaHQgKi8KKyAgaWYgKCAhb2JqZWN0cCh6YWhsZXIpICkKKyAgICB6YWhsZXIgPSBlbXBmYWVuZ2VyOworCisgIC8vIGFsdGUgUHVicywgZGllIGRvX2RlbGl2ZXIgaXJnZW5kd2llIHNlbGJzdCBhdWZydWZlbiwgc29sbHRlbgorICAvLyBtaXQgZGVyIFplaXQga29ycmlnaWVydCB3ZXJkZW4KKyAgaWYoIW1hcHBpbmdwKGVudHJ5aW5mbykpCisgICAgcmFpc2VfZXJyb3IoIlB1YiBydWZ0IGRvX2RlbGl2ZXIoKSBvaG5lIHNpbm52b2xsZSBBcmd1bWVudGUgYXVmLlxuIik7CisgIGlmKCFtZW1iZXIoZW50cnlpbmZvLCBQTV9SQVRFX1BVQk1BU1RFUikpIHsKKyAgICBpZighbWVtYmVyKG1lbnVfbGlzdCwgaWRlbnQpKQorICAgICAgcmFpc2VfZXJyb3IoIlB1YiBydWZ0IGRvX2RlbGl2ZXIoKSBtaXQgZ2Vsb2VzY2h0ZW0gR2V0cmFlbmsgdW5kICIKKyAgICAgICAgICAgICAgICAgICJ0ZWlsd2Vpc2VuIEFyZ3VtZW50ZW4gYXVmIVxuIik7CisKKyAgICBfY29weV9tZW51bGlzdF92YWx1ZXMoZW50cnlpbmZvLCBpZGVudCk7CisgICAgY2FsbF9vdXQoIydyYWlzZV9lcnJvciwgMSwKKyAgICAgICAgICAgICAiUHViIHJ1ZnQgZG9fZGVsaXZlcigpIG51ciBtaXQgdGVpbHdlaXNlbiBBcmd1bWVudGVuIGF1Zi5cbiIpOworICB9CisKKyAgZW50cnlpbmZvW1BNX1JBVEVfUFVCTUFTVEVSXSA9IGV2YWxfYW55dGhpbmcoZW50cnlpbmZvW1BNX1JBVEVfUFVCTUFTVEVSXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW1wZmFlbmdlcik7CisgIGVudHJ5aW5mb1tQX0hQXSAgICAgICAgICAgICAgPSBldmFsX2FueXRoaW5nKGVudHJ5aW5mb1tQX0hQXSwgZW1wZmFlbmdlcik7CisgIGVudHJ5aW5mb1tQX1NQXSAgICAgICAgICAgICAgPSBldmFsX2FueXRoaW5nKGVudHJ5aW5mb1tQX1NQXSwgZW1wZmFlbmdlcik7CisKKyAgLyogVWViZXJwcnVlZmVuLCBvYiBIZWlsbW9lZ2xpY2hrZWl0IGxlZ2FsICovCisgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShlbXBmYWVuZ2VyKQorICAgICAgJiYgKChQVUJNQVNURVItPlJlZ2lzdGVySXRlbShlbnRyeWluZm9bUE1fVEVYVF0sIGVudHJ5aW5mbykpPDEpICkgeworICAgICB0ZWxsX29iamVjdChlbXBmYWVuZ2VyLAorICAgICAgICJNaXQgZGllc2VtIEdldHJhZW5rL0dlcmljaHQgc2NoZWludCBldHdhcyBuaWNodCBpbiBPcmRudW5nICIrCisgICAgICAgInp1IHNlaW4uXG5WZXJzdGFlbmRpZ2UgYml0dGUgZGVuIE1hZ2llciwgZGVyIGZ1ZXIgZGllc2VuICIrCisgICAgICAgIlJhdW0gdmVyYW50d29ydGxpY2ggaXN0LlxuIik7CisgICAgIHJldHVybiAtNDsKKyAgfQorCisgIGlmICggUXVlcnlQcm9wKFBfTlBDX0ZBU1RIRUFMKSAmJiAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShlbXBmYWVuZ2VyKSApIHsKKyAgICBlbnRyeWluZm9bSF9ESVNUUklCVVRJT05dID0gSERfSU5TVEFOVDsKKyAgfQorICBlbHNlIHsKKyAgICBlbnRyeWluZm9bSF9ESVNUUklCVVRJT05dID0gZW50cnlpbmZvW1BNX1JBVEVfUFVCTUFTVEVSXTsKKyAgfQorICBlbXBmYWVuZ2VyLT5jb25zdW1lKGVudHJ5aW5mbyk7CisKKyAgLyogTWVsZHVuZyBhdXNnZWJlbiAqLworICAvKiBIaW53ZWlzOiBEYSBkaWUgYXVzZnVlaHJlbmRlbiBGdW5rdGlvbmVuIGF1Y2ggaWRlbnQgdW5kIG1pbmZvCisgICAqIHVlYmVyZ2ViZW4gYmVrb21tZW4sIGthbm4gbWFuIGhpZXIgYXVjaCB1ZWJlciBhZGp1c3RfaW5mbyBvZGVyCisgICAqIGFuIGFuZGVyZXIgU3RlbGxlIHp1c2FldHpsaWNoZSBJbmZvcm1hdGlvbmVuIHVlYmVyZ2ViZW4uLi4KKyAgICovCisgIGlmIChjbG9zdXJlcChlbnRyeWluZm9bUE1fU0VSVkVfTVNHXSkgKQorICAgIGZ1bmNhbGwoZW50cnlpbmZvW1BNX1NFUlZFX01TR10sIHphaGxlciwgZW1wZmFlbmdlciwgaWRlbnQsIGVudHJ5aW5mbyk7CisgIGVsc2UgaWYgKHN0cmluZ3AoZW50cnlpbmZvW1BNX1NFUlZFX01TR10pICYmCisgICAgICAgICAgIGZ1bmN0aW9uX2V4aXN0cyhlbnRyeWluZm9bUE1fU0VSVkVfTVNHXSxNRSkpCisgICAgY2FsbF9vdGhlcihNRSwgZW50cnlpbmZvW1BNX1NFUlZFX01TR10sIHphaGxlciwgZW1wZmFlbmdlciwgaWRlbnQsCisgICAgICAgICAgICAgICAgICAgZW50cnlpbmZvKTsKKyAgZWxzZSBpZiAocG9pbnRlcnAoZW50cnlpbmZvW1BNX1NFUlZFX01TR10pICYmCisgICAgICAgICAgIHNpemVvZihlbnRyeWluZm9bUE1fU0VSVkVfTVNHXSk+PTIpICB7CisgICAgaWYgKHN0cmluZ3AoZW50cnlpbmZvW1BNX1NFUlZFX01TR11bMF0pICYmCisgICAgICAgIHNpemVvZihlbnRyeWluZm9bUE1fU0VSVkVfTVNHXVswXSkpCisgICAgICB0ZWxsX29iamVjdChlbXBmYWVuZ2VyLAorICAgICAgICBtZXNzKGVudHJ5aW5mb1tQTV9TRVJWRV9NU0ddWzBdKyJcbiIsIGVtcGZhZW5nZXIpKTsKKyAgICBpZiAoc3RyaW5ncChlbnRyeWluZm9bUE1fU0VSVkVfTVNHXVsxXSkgJiYKKyAgICAgICAgc2l6ZW9mKGVudHJ5aW5mb1tQTV9TRVJWRV9NU0ddWzFdKSkKKyAgICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbXBmYWVuZ2VyKXx8TUUsCisgICAgICAgIG1lc3MoZW50cnlpbmZvW1BNX1NFUlZFX01TR11bMV0rIlxuIixlbXBmYWVuZ2VyKSwKKyAgICAgICAgKHtlbXBmYWVuZ2VyfSkgKTsKKyAgfQorCisgIHJldHVybiAxOworfQorCisvKiBUZXN0ZXQsIG9iIGdlbnVnIEdlbGQgenVyIFZlcmZ1ZWd1bmcgc3RlaHQuCisgKiBGYWxscyBkaWUgQm9uaXRhZXQgYW5kZXJlbiBCZXNjaHJhZW5rdW5nZW4gdW50ZXJsaWVndCwgYWxzCisgKiBkYXNzIGRlciBaYWhsZXIgZ2VudWcgR2VsZCBkYWJlaSBoYXQsIG11c3MgZGllc2UgTWV0aG9kZQorICogdWViZXJzY2hyaWViZW4gd2VyZGVuLgorICogUnVlY2tnYWJld2VydGU6CisgKiAtMiA6IE91dCBvZiBNb25leQorICogIDAgOiBBbGxlcyBPSy4KKyAqIFJ1ZWNrZ2FiZXdlcnRlICE9IDAgZnVlaHJlbiB6dSBlaW5lbSBBYmJydWNoIGRlciBCZXN0ZWxsdW5nCisgKi8KK2ludCBDaGVja1NvbHZlbmN5KHN0cmluZyBpZGVudCwgb2JqZWN0IHphaGxlciwgb2JqZWN0IGVtcGZhZW5nZXIsCisgICAgICAgICAgICAgICAgICAgbWFwcGluZyBlbnRyeWluZm8pCit7CisgIGlmICggKHphaGxlci0+UXVlcnlNb25leSgpKTxlbnRyeWluZm9bUF9WQUxVRV0gKQorICB7CisgICAgc3RyaW5nIHJlczsKKyAgICBpZiAoICFzdHJpbmdwKHJlcz1RdWVyeVByb3AoUF9QVUJfTk9fTU9ORVkpKSApCisgICAgICByZXMgPSAiRGFzIGtvc3RldCAlZCBHb2xkc3R1ZWNrZSwgdW5kIER1IGhhc3QgbmljaHQgc28gdmllbCFcbiI7CisgICAgdGVsbF9vYmplY3QoemFobGVyLHNwcmludGYocmVzLCBlbnRyeWluZm9bUF9WQUxVRV0pKTsKKyAgICByZXR1cm4gLTI7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKy8qIEZ1ZWhydCBkaWUgQmV6YWhsdW5nIGR1cmNoLgorICogRmFsbHMgZGllIEJlemFobHVuZyBhbmRlcnMgZXJmb2xndCwgYWxzIGR1cmNoIEFienVnIGRlcyBHZWxkZXMgdm9tIFphaGxlciwKKyAqIG11c3MgZGllc2UgTWV0aG9kZSB1ZWJlcnNjaHJpZWJlbiB3ZXJkZW4KKyAqIFJ1ZWNrZ2FiZXdlcnRlOgorICogQW56YWhsIGRlciBNdWVuemVuLCBkaWUgaW0gUHViIGxhbmRlbiB1bmQgYmVpIFJlc2V0IGluIGRpZSBaZW50cmFsYmFuaworICogZWluZ2V6YWhsdCB3ZXJkZW4KKyAqLworaW50IERvUGF5KHN0cmluZyBpZGVudCwgb2JqZWN0IHphaGxlciwgb2JqZWN0IGVtcGZhZW5nZXIsIG1hcHBpbmcgZW50cnlpbmZvKQoreworICB6YWhsZXItPkFkZE1vbmV5KC1lbnRyeWluZm9bUF9WQUxVRV0pOworICByZXR1cm4gZW50cnlpbmZvW1BfVkFMVUVdOworfQorCisvKiBSdWVja2dhYmV3ZXJ0ZToKKyAqIC02IDogTmljaHQgdm9ycmFldGlnCisgKiAtNSA6IFdpcnQgbmljaHQgYW53ZXNlbmQKKyAqIC00IDogSWxsZWdhbGVzIEdldHJhZW5rL0dlcmljaHQuIEF1c2dhYmUgdmVyd2VpZ2VydC4KKyAqICAgICAgTnVyIGJlaSBzb2ZvcnRpZ2VyIExpZWZlcnVuZy4uLgorICogLTMgOiBFbXBmYWVuZ2VyIGJlcmVpdHMgdm9sbAorICogLTIgOiBPdXQgb2YgTW9uZXkKKyAqIC0xIDogc3BlbmRpZXJlbiBpZ25vcmllcnQKKyAqICAwIDogRW1wZmFlbmdlciBhdXNnZWZsb2dlbiAoc29sbHRlIGVpZ2VudGxpY2ggbmljaHQgcGFzc2llcmVuKQorICogIDEgOiBBbGxlcyBPSy4KKyAqLworaW50IGNvbnN1bWVfc29tZXRoaW5nKHN0cmluZyBpZGVudCwgb2JqZWN0IHphaGxlciwgb2JqZWN0IGVtcGZhZW5nZXIpIHsKKyAgaWYgKCAhb2JqZWN0cCh6YWhsZXIpICkKKyAgICB6YWhsZXI9UEw7CisKKyAgaWYgKCAhb2JqZWN0cChlbXBmYWVuZ2VyKSApCisgICAgZW1wZmFlbmdlcj1QTDsKKworICAvKiBEaWUgQWJmcmFnZSBhdWYgYW53ZXNlbmRlbiBXaXJ0IGVyZm9sZ3QgTlVSIGFuIGRpZXNlciBTdGVsbGUsIGRhbWl0ICovCisgIC8qIGtlaW4gU3BpZWxlciBkYXJ1bnRlciBsZWlkZW4gbXVzcywgd2VubiBqZW1hbmQgYW5kZXJlcyB6d2lzY2hlbiAgICAgKi8KKyAgLyogQmVzdGVsbHVuZyB1bmQgTGllZmVydW5nIGRlbiBXaXJ0IG1ldWNoZWx0LiAgICAgICAgICAgICAgICAgICAgICAgICAqLworICBpZiAoIHN0cmluZ3AoUXVlcnlQcm9wKFBfS0VFUEVSKSkgJiYgIXByZXNlbnQoUXVlcnlQcm9wKFBfS0VFUEVSKSwgTUUpKQorICB7CisgICAgc3RyaW5nIHJlcyA9IFF1ZXJ5UHJvcChQX1BVQl9OT19LRUVQRVIpOworICAgIGlmICggIXN0cmluZ3AocmVzKSApIHsKKyAgICAgIHJlcyA9ICJFcyBpc3QgbmllbWFuZCBhbndlc2VuZCwgZGVyIERpY2ggYmVkaWVuZW4ga29lbm50ZS5cbiI7CisgICAgfQorICAgIHRlbGxfb2JqZWN0KHphaGxlcixyZXMpOworICAgIHJldHVybiAtNTsKKyAgfQorCisgIC8qIFNwZW5kaWVydCB1bmQgaWdub3JpZXJ0PyAqLworICBpZiAoIHphaGxlciE9ZW1wZmFlbmdlciApCisgIHsKKyAgICBtaXhlZCByZXMgPSAoeyJzcGVuZGllcmUifSk7CisgICAgaWYgKCBldmFsX2FueXRoaW5nKG1lbnVfbGlzdFtpZGVudCxQTV9JTkZPXVtQX0RSSU5LXSxlbXBmYWVuZ2VyKSApCisgICAgICByZXMgKz0gKHsic3BlbmRpZXJlLmdldHJhZW5rZSJ9KTsKKyAgICBpZiAoIGV2YWxfYW55dGhpbmcobWVudV9saXN0W2lkZW50LFBNX0lORk9dW1BfRk9PRF0sZW1wZmFlbmdlcikgKQorICAgICAgcmVzICs9ICh7InNwZW5kaWVyZS5lc3NlbiJ9KTsKKyAgICBpZiAoIGV2YWxfYW55dGhpbmcobWVudV9saXN0W2lkZW50LFBNX0lORk9dW1BfQUxDT0hPTF0sZW1wZmFlbmdlcikgKQorICAgICAgcmVzICs9ICh7InNwZW5kaWVyZS5hbGtvaG9sIn0pOworICAgIGlmICggZW1wZmFlbmdlci0+VGVzdElnbm9yZVNpbXBsZShyZXMpICkKKyAgICB7CisgICAgICB0ZWxsX29iamVjdCh6YWhsZXIsCisgICAgICAgIGVtcGZhZW5nZXItPk5hbWUoV0VSKSsiIHdpbGwgZGFzIG5pY2h0LlxuIik7CisgICAgICByZXR1cm4gLTE7CisgICAgfQorICB9CisKKyAgLyogSGllciBrYW5uIGRhcyBJbmZvLU1hcHBpbmcgZXJzdCBtYWwgYWxzIGdhbnplcyBhbmdlcGFzc3Qgd2VyZGVuLiAqLworICBtYXBwaW5nIHhpbmZvOworICBtYXBwaW5nIGVudHJ5aW5mbyA9IGRlZXBfY29weShtZW51X2xpc3RbaWRlbnQsIFBNX0lORk9dKTsKKyAgaWYgKCAoeGluZm89YWRqdXN0X2luZm8oaWRlbnQsZW50cnlpbmZvLHphaGxlcixlbXBmYWVuZ2VyKSkgJiYKKyAgICAgICBtYXBwaW5ncCh4aW5mbykgKQorICAgIGVudHJ5aW5mbyArPSB4aW5mbzsKKworICAvKiBHZW51ZyBHZWxkIHZvcmhhbmRlbj8gKi8KKyAgZW50cnlpbmZvW1BfVkFMVUVdID0gZXZhbF9hbnl0aGluZyhlbnRyeWluZm9bUF9WQUxVRV0sIHphaGxlcik7CisgIHsKKyAgICBpbnQgcmVzID0gQ2hlY2tTb2x2ZW5jeShpZGVudCwgemFobGVyLCBlbXBmYWVuZ2VyLCBlbnRyeWluZm8pOworICAgIGlmIChyZXMgIT0gMCkgcmV0dXJuIHJlczsKKyAgfQorCisgIHN0cmluZyBhdmI7CisgIGlmICggIXN0cmluZ3AoYXZiPUNoZWNrQXZhaWxhYmlsaXR5KGlkZW50LCB6YWhsZXIpKSApCisgIHsKKyAgICBzdHJpbmcgcmVzID0gUXVlcnlQcm9wKFBfUFVCX1VOQVZBSUxBQkxFKTsKKyAgICBpZiAoICFzdHJpbmdwKHJlcykgKQorICAgICAgcmVzID0gIkRhdm9uIGlzdCBsZWlkZXIgbmljaHRzIG1laHIgZGEuXG4iOworICAgIHRlbGxfb2JqZWN0KHphaGxlcixyZXMpOworICAgIHJldHVybiAtNjsKKyAgfQorCisgIC8qIFRleHRhdXNnYWJlIGJlaW0gc3BlbmRpZXJlbiAqLworICBpZiAoIGVtcGZhZW5nZXIhPXphaGxlcikKKyAgeworICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudChlbXBmYWVuZ2VyKXx8TUUsCisgICAgICB6YWhsZXItPk5hbWUoV0VSKSsiIHNwZW5kaWVydCAiK2VtcGZhZW5nZXItPm5hbWUoV0VNKSsiIGV0d2FzLlxuIiwKKyAgICAgICh7emFobGVyLCBlbXBmYWVuZ2VyfSkgKTsKKyAgICB0ZWxsX29iamVjdChlbXBmYWVuZ2VyLAorICAgICAgemFobGVyLT5OYW1lKFdFUikrIiBzcGVuZGllcnQgRGlyIGV0d2FzLlxuIik7CisgICAgdGVsbF9vYmplY3QoemFobGVyLAorICAgICAgIkR1IHNwZW5kaWVyc3QgIitlbXBmYWVuZ2VyLT5uYW1lKFdFTSkrIiBldHdhcy5cbiIpOworICB9CisKKyAgLyogVGVzdGVuLCBvYiBtYW5zIG5vY2ggZXNzZW4gLyB0cmlua2VuIGthbm4gKi8KKyAgLyogRGllIGludC1XZXJ0ZSB3ZXJkZW4gaW4gbWluZm8gdWViZXJub21tZW4gZnVlciBkaWUgQXVzd2VydHVuZyAqLworICAvKiBpbSBQdWJtYXN0ZXIuICovCisgIGVudHJ5aW5mb1tQX0ZPT0RdICAgID0gZXZhbF9hbnl0aGluZyhlbnRyeWluZm9bUF9GT09EXSwgICBlbXBmYWVuZ2VyKTsKKyAgZW50cnlpbmZvW1BfQUxDT0hPTF0gPSBldmFsX2FueXRoaW5nKGVudHJ5aW5mb1tQX0FMQ09IT0xdLGVtcGZhZW5nZXIpOworICBlbnRyeWluZm9bUF9EUklOS10gICA9IGV2YWxfYW55dGhpbmcoZW50cnlpbmZvW1BfRFJJTktdLCAgZW1wZmFlbmdlcik7CisKKyAgaW50IHJlc3VsdCA9IGVtcGZhZW5nZXItPmNvbnN1bWUoZW50cnlpbmZvLCAxKTsKKyAgaWYgKHJlc3VsdCA8IDApIHsKKyAgICBpZiAocmVzdWx0ICYgSENfTUFYX0ZPT0RfUkVBQ0hFRCkKKyAgICAgIHRlbGxfb2JqZWN0KGVtcGZhZW5nZXIsCisgICAgICAgICAgICAgICAgICAiRHUgYmlzdCB6dSBzYXR0LCBkYXMgc2NoYWZmc3QgRHUgbmljaHQgbWVoci5cbiIpOworICAgIGVsc2UgaWYgKHJlc3VsdCAmIEhDX01BWF9EUklOS19SRUFDSEVEKQorICAgICAgdGVsbF9vYmplY3QoZW1wZmFlbmdlciwKKyAgICAgICAgICAgICAgICAgICJTbyB2aWVsIGthbm5zdCBEdSBpbSBNb21lbnQgbmljaHQgdHJpbmtlbi5cbiIpOworICAgIGVsc2UgaWYgKHJlc3VsdCAmIEhDX01BWF9BTENPSE9MX1JFQUNIRUQpCisgICAgICB0ZWxsX29iamVjdChlbXBmYWVuZ2VyLAorICAgICAgICAgICAgICAgICAgIlNvdmllbCBBbGtvaG9sIHZlcnRyYWVnc3QgRHUgbmljaHQgbWVoci5cbiIpOworICAgIHJldHVybiAtMzsKKyAgfQorCisgIC8qIEdlemFobHQgd2lyZCBhdWNoIHNvZm9ydCAqLworICBzdW0gKz0gRG9QYXkoaWRlbnQsIHphaGxlciwgZW1wZmFlbmdlciwgZW50cnlpbmZvKTsKKworICAvKiBGUHMgZ2lidHMgYXVjaCBzb2ZvcnQgKi8KKyAgaWYgKHphaGxlciA9PSBlbXBmYWVuZ2VyKQorICAgIEdpdmVFUChFUF9QVUIsbWVudV9saXN0W2lkZW50LFBNX0lEU11bMF0pOworCisgIC8qIEZhbGxzIGRpZSBBbnphaGwgZGVzIEJlc3RlbGx0ZW4gYmVzY2hyYWVua3QgaXN0LCBtdXNzIGRpZXNlIG5hdHVlcmxpY2gKKyAgICogYW5nZXBhc3N0IHdlcmRlbi4KKyAgICovCisgIGlmICggYXZiIT1QUl9OT05FICkKKyAgICBEZWNyZWFzZUF2YWlsYWJpbGl0eShpZGVudCxhdmIpOworCisgIC8qIEdpYnQgZXMgZWluZSBaZWl0dmVyem9lZ2VydW5nIHp3aXNjaGVuIEJlc3RlbGxlbiB1bmQgU2VydmllcmVuPyAqLworICBlbnRyeWluZm9bUE1fREVMQVlfUFVCTUFTVEVSXSA9IGV2YWxfYW55dGhpbmcobWVudV9saXN0W2lkZW50LCBQTV9ERUxBWV0sIHphaGxlcik7CisKKyAgLy8gYWxsZSBmdWVyIGVpbmVuIERyaW5rIG5vdHdlbmRpZ2VuIFdlcnRlIGtvcGllcmVuCisgIF9jb3B5X21lbnVsaXN0X3ZhbHVlcyhlbnRyeWluZm8sIGlkZW50KTsKKworICBpZiAoZW50cnlpbmZvW1BNX0RFTEFZX1BVQk1BU1RFUl08PTApCisgICAgcmV0dXJuIGRvX2RlbGl2ZXIoaWRlbnQsemFobGVyLGVtcGZhZW5nZXIsZW50cnlpbmZvKTsKKworICAvKiBCZXN0ZWxsLU1lbGR1bmcgYXVzZ2ViZW4gKi8KKyAgaWYgKGNsb3N1cmVwKGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddKSkKKyAgICBmdW5jYWxsKGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddLCB6YWhsZXIsIGVtcGZhZW5nZXIsaWRlbnQsIGVudHJ5aW5mbyk7CisgIGVsc2UgaWYgKHN0cmluZ3AoZW50cnlpbmZvW1BNX0RFTEFZX01TR10pICYmCisgICAgICAgICAgIGZ1bmN0aW9uX2V4aXN0cyhlbnRyeWluZm9bUE1fREVMQVlfTVNHXSxNRSkpCisgICAgY2FsbF9vdGhlcihNRSwgZW50cnlpbmZvW1BNX0RFTEFZX01TR10sIHphaGxlciwgZW1wZmFlbmdlciwgaWRlbnQsCisgICAgICAgICAgICAgICBlbnRyeWluZm8pOworICBlbHNlIGlmIChwb2ludGVycChlbnRyeWluZm9bUE1fREVMQVlfTVNHXSkgJiYKKyAgICAgICAgICAgc2l6ZW9mKGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddKT49MikgeworICAgIGlmIChzdHJpbmdwKGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddWzBdKSAmJgorICAgICAgIHNpemVvZihlbnRyeWluZm9bUE1fREVMQVlfTVNHXVswXSkpCisgICAgICB0ZWxsX29iamVjdChlbXBmYWVuZ2VyLAorICAgICAgICBtZXNzKGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddWzBdKyJcbiIsZW1wZmFlbmdlcikpOworICAgIGlmIChzdHJpbmdwKGVudHJ5aW5mb1tQTV9ERUxBWV9NU0ddWzFdKSAmJgorICAgICAgICBzaXplb2YoZW50cnlpbmZvW1BNX0RFTEFZX01TR11bMV0pKQorICAgICAgdGVsbF9yb29tKGVudmlyb25tZW50KGVtcGZhZW5nZXIpfHxNRSwKKyAgICAgICAgbWVzcyhlbnRyeWluZm9bUE1fREVMQVlfTVNHXVsxXSsiXG4iLGVtcGZhZW5nZXIpLAorICAgICAgICAoe2VtcGZhZW5nZXJ9KSApOworICB9CisKKyAgd2FpdGluZyArPSAoeyBlbXBmYWVuZ2VyIH0pOworICBjYWxsX291dCgiZG9fZGVsaXZlciIsIGVudHJ5aW5mb1tQTV9ERUxBWV9QVUJNQVNURVJdLAorICAgICAgICAgICBpZGVudCwgemFobGVyLCBlbXBmYWVuZ2VyLCBlbnRyeWluZm8pOworCisgIHJldHVybiAxOworfQorCisvKiBSdWVja2dhYmV3ZXJlOiAwOiBOaWNodCBpbSBNZW51ZSBnZWZ1bmRlLCAxIHNvbnN0ICovCitpbnQgc2VhcmNoX3doYXQoc3RyaW5nIHN0cixvYmplY3QgemFobGVyLG9iamVjdCBlbXBmYWVuZ2VyKQoreyBzdHJpbmcgaWRlbnQ7CisKKyAgaWYgKCBtZW1iZXIod2FpdGluZyxlbXBmYWVuZ2VyKSE9LTEgKQorICB7CisgICAgaWYgKCBQTD09ZW1wZmFlbmdlciApCisgICAgICB3cml0ZSgiRHUgd2FydGVzdCBkb2NoIG5vY2ggYXVmIGV0d2FzIVxuIik7CisgICAgZWxzZQorICAgICAgd3JpdGUoZW1wZmFlbmdlci0+TmFtZShXRVIsMikrIiB3YXJ0ZXQgbm9jaCBhdWYgZXR3YXMuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIHN0ciA9IGxvd2VyX2Nhc2Uoc3RyKTsKKyAgaWYgKCBpZGVudD1pZF9saXN0W3N0cl0gKQorICB7CisgICAgY29uc3VtZV9zb21ldGhpbmcoaWRlbnQsemFobGVyLGVtcGZhZW5nZXIpOworICAgIHJldHVybiAxOworICB9CisKKyAgcmV0dXJuIDA7Cit9CisKKy8vIE5ldWUgVmVyc2lvbiB2b24gTWVzaToKK2ludCBzcGVuZGllcmUoc3RyaW5nIHN0cikKK3sKKyAgIF9ub3RpZnlfZmFpbCgic3BlbmRpZXJlIDxzcGllbGVyPiA8ZHJpbms+XG4iKTsKKworICAgaWYgKCAhc3RyaW5ncChzdHIpIHx8IHN0cj09IiIgKQorICAgICByZXR1cm4gMDsKKworICAgc3RyaW5nIHdobyx3aGF0OworICAgaW50IHdob2lkeDsKKworICAgaWYgKHNzY2FuZihzdHIsIiVzICVkICVzIix3aG8sd2hvaWR4LHdoYXQpIT0zCisgICAgJiYgc3NjYW5mKHN0ciwiJXMgJXMiLHdobyx3aGF0KSE9MikKKyAgICAgIHJldHVybiAwOworICBvYmplY3QgdGFyZ2V0PXByZXNlbnQod2hvLCB3aG9pZHgpOworICBpZighdGFyZ2V0ICYmIHRoaXNfcGxheWVyKCkpIHRhcmdldD1wcmVzZW50KHdobywgd2hvaWR4LCB0aGlzX3BsYXllcigpKTsKKyAgIGlmICggIXRhcmdldCB8fCAhbGl2aW5nKHRhcmdldCkgKQorICAgeworICAgICB3cml0ZSgiRGFzIExlYmV3ZXNlbiBpc3QgbmljaHQgaGllci4uLlxuIik7CisgICAgIHJldHVybiAxOworICAgfQorCisgICBub3RpZnlfZmFpbCgoc3RyaW5nKVF1ZXJ5UHJvcChQX1BVQl9OT1RfT05fTUVOVSl8fCJTbyBldHdhcyBnaWJ0IGVzIGhpZXIgbmljaHQhXG4iKTsKKworICAgcmV0dXJuIHNlYXJjaF93aGF0KHdoYXQsUEwsdGFyZ2V0KTsKK30KKworaW50IGJlc3RlbGxlKHN0cmluZyBzdHIpCit7CisgIG5vdGlmeV9mYWlsKChzdHJpbmcpUXVlcnlQcm9wKFBfUFVCX05PVF9PTl9NRU5VKSk7CisKKyAgaWYgKCAhc3RyaW5ncChzdHIpICkKKyAgICByZXR1cm4gMDsKKworICByZXR1cm4gc2VhcmNoX3doYXQoc3RyLFBMLFBMKTsKK30KKworaW50IHB1YmluaXQoKQoreyBzdHJpbmcgICpsaXN0ZSxpZGVudCxmbjsKKyAgaW50ICAgICBzaSxlcmcsbWF4OworICBtYXBwaW5nIG1pbmZvLHhpbmZvOworCisgIGlmICggIVBMIHx8ICFJU19XSVpBUkQoUEwpICkKKyAgICByZXR1cm4gMDsKKworICBzaT1zaXplb2YobGlzdGU9c29ydF9hcnJheShtX2luZGljZXMobWVudV9saXN0KSwjJzwpKTsKKyAgaWYgKCBzaTwxICkKKyAgICByZXR1cm4gbm90aWZ5X2ZhaWwoIktlaW5lIEdlcmljaHRlL0dldHJhZW5rZSB2b3JoYW5kZW4uXG4iKSwwOworCisgIGZuPW9sZF9leHBsb2RlKG9iamVjdF9uYW1lKE1FKSwiIyIpWzBdOworICBwcmludGYoIlxuJSdfJ3wzMHMgJTNzICUzcyAlM3MgJTVzICUycyAlMnMgJTNzICUzcyAlNHMgJTNzXG4iLAorICAgICJJVEVNIiwiQUxDIiwiRFJJIiwiRk9PIiwiVkFMVUUiLCJSVCIsIkRMIiwiX0hQIiwiX1NQIiwiVEVTVCIsIk1BWCIpOworICBmb3IgKCAtLXNpIDsgc2k+PTAgOyBzaS0tICkKKyAgeworICAgIGlkZW50PWxpc3RlW3NpXTsKKyAgICBtaW5mbz1kZWVwX2NvcHkobWVudV9saXN0W2lkZW50LFBNX0lORk9dKTsKKworICAgIGlmICggKHhpbmZvPWFkanVzdF9pbmZvKGlkZW50LG1pbmZvLFBMLFBMKSkgJiYgbWFwcGluZ3AoeGluZm8pICkKKyAgICAgIG1pbmZvKz14aW5mbzsKKworICAgIG1pbmZvW1BfVkFMVUVdICAgPSBldmFsX2FueXRoaW5nKG1pbmZvW1BfVkFMVUVdLCAgICAgICAgICAgIFBMKTsKKyAgICBtaW5mb1tQX0ZPT0RdICAgID0gZXZhbF9hbnl0aGluZyhtaW5mb1tQX0ZPT0RdLCAgICAgICAgICAgICBQTCk7CisgICAgbWluZm9bUF9BTENPSE9MXSA9IGV2YWxfYW55dGhpbmcobWluZm9bUF9BTENPSE9MXSwgICAgICAgICAgUEwpOworICAgIG1pbmZvW1BfRFJJTktdICAgPSBldmFsX2FueXRoaW5nKG1pbmZvW1BfRFJJTktdLCAgICAgICAgICAgIFBMKTsKKyAgICBtaW5mb1tQTV9ERUxBWV9QVUJNQVNURVJdCisgICAgICAgICAgICAgICAgICAgICA9IGV2YWxfYW55dGhpbmcobWVudV9saXN0W2lkZW50LFBNX0RFTEFZXSwgUEwpOworICAgIG1pbmZvW1BNX1JBVEVfUFVCTUFTVEVSXQorICAgICAgICAgICAgICAgICAgICAgPSBldmFsX2FueXRoaW5nKG1lbnVfbGlzdFtpZGVudCxQTV9SQVRFXSwgIFBMKTsKKyAgICBtaW5mb1tQX0hQXSAgICAgID0gZXZhbF9hbnl0aGluZyhtaW5mb1tQX0hQXSwgICAgICAgICAgICAgICBQTCk7CisgICAgbWluZm9bUF9TUF0gICAgICA9IGV2YWxfYW55dGhpbmcobWluZm9bUF9TUF0sICAgICAgICAgICAgICAgUEwpOworICAgIGVyZz1QVUJNQVNURVItPlJlZ2lzdGVySXRlbShtZW51X2xpc3RbaWRlbnQsMF0sbWluZm8pOworICAgIG1heD1QVUJNQVNURVItPkNhbGNNYXgobWluZm8sZm4pOworCisgICAgcHJpbnRmKCIlLScuLiczMC4zMHMgJTNkICUzZCAlM2QgJTVkICUyZCAlMmQgJTNkICUzZCAlfDRzICUzZFxuIiwKKyAgICAgIG1lbnVfbGlzdFtpZGVudCxQTV9URVhUXSwKKyAgICAgIG1pbmZvW1BfQUxDT0hPTF0sIG1pbmZvW1BfRFJJTktdLCBtaW5mb1tQX0ZPT0RdLAorICAgICAgbWluZm9bUF9WQUxVRV0sCisgICAgICBtaW5mb1tQTV9SQVRFX1BVQk1BU1RFUl0sCisgICAgICBtaW5mb1tQTV9ERUxBWV9QVUJNQVNURVJdLAorICAgICAgbWluZm9bUF9IUF0sIG1pbmZvW1BfU1BdLAorICAgICAgKCBlcmcgPyAiT0siIDogIkZBSUwiICksbWF4KTsKKyAgfQorICB3cml0ZSgiRG9uZS5cbiIpOworICByZXR1cm4gMTsKK30KKwordm9pZCByZXNldCgpCit7CisgIGlmICggc3VtPjAgKQorICAgIFpFTlRSQUxCQU5LLT5QYXlJbihzdW0pOworICBzdW09MDsKKyAgcmVmcmVzaF9jb3VudCsrOworICBVcGRhdGVBdmFpbGFiaWxpdHkoKTsKK30KKwordm9pZCBhZGRfZ2x1ZWh3ZWluKCkKK3sKKyAgaWYgKCBjdGltZSh0aW1lKCkpWzQuLjZdPT0iRGVjIiApCisgICAgQWRkVG9NZW51KCAiR2x1ZWh3ZWluIiwoeyJnbHVlaHdlaW4ifSksKFsKKyAgICAgIFBfVkFMVUUgICA6IDgwLAorICAgICAgUF9EUklOSyAgIDogIDUsCisgICAgICBQX0FMQ09IT0wgOiAyMCwKKyAgICAgIFBfSFAgICAgICA6IDE1LAorICAgICAgUF9TUCAgICAgIDogMTUgXSksMiwoeworICAgICAgKCJEdSB0cmlua3N0IGVpbiBHbGFzIEdsdWVod2VpbiwgYW4gZGVtIER1IERpciBiZWluYWhlIGRpZSBadW5nZSAiKworICAgICAgICJ2ZXJicmVubnN0LlxuIiksCisgICAgICAoIiYmIGJlc3RlbGx0IGVpbiBHbGFzIEdsdWVod2VpbiB1bmQgdmVyYnJlbm50IHNpY2ggYmVpbVxuIisKKyAgICAgICAiVHJpbmtlbiBiZWluYWhlIGRpZSBadW5nZS5cbiIpIH0pLCAwLCAwLCAwKTsKK30KKwordm9pZCBhZGRfc3RkX2RyaW5rcygpCit7CisgIGlmICggUXVlcnlQcm9wKFBfTk9fU1REX0RSSU5LKSApCisgICAgcmV0dXJuIDsKKyAgYWRkX2dsdWVod2VpbigpOworfQorCittYXBwaW5nIHF1ZXJ5X21lbnVsaXN0KCkKK3sKKyAgcmV0dXJuIGRlZXBfY29weShtZW51X2xpc3QpOworfQorCitzdHJpbmcgKnF1ZXJ5X2RyaW5rcygpCit7CisgIHN0cmluZyAqZHI9KHt9KTsKKyAgZm9yZWFjaCggc3RyaW5nIGlkZW50LCBzdHJpbmcgbWVudWV0ZXh0LCBtYXBwaW5nIG1pbmZvOiBtZW51X2xpc3QpIHsKKyAgICBpZiAoZXZhbF9hbnl0aGluZyhtaW5mb1tQX0RSSU5LXSwgMCkpCisgICAgICBkciArPSAoeyBpZGVudCB9KTsKKyAgfQorICByZXR1cm4gZHI7Cit9CisKK3N0cmluZyAqcXVlcnlfZm9vZCgpCit7CisgIHN0cmluZyAqZm89KHt9KTsKKyAgZm9yZWFjaCggc3RyaW5nIGlkZW50LCBzdHJpbmcgbWVudWV0ZXh0LCBtYXBwaW5nIG1pbmZvOiBtZW51X2xpc3QpIHsKKyAgICBpZiAoZXZhbF9hbnl0aGluZyhtaW5mb1tQX0ZPT0RdLCAwKSkKKyAgICAgIGZvICs9ICh7IGlkZW50IH0pOworICB9CisgIHJldHVybiBmbzsKK30KZGlmZiAtLWdpdCBhL3N0ZC9yb29tL3Jlc3RyaWN0aW9ucy5jIGIvc3RkL3Jvb20vcmVzdHJpY3Rpb25zLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWE1MGM5ZQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9yb29tL3Jlc3RyaWN0aW9ucy5jCkBAIC0wLDAgKzEsNjEgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyByb29tL3Jlc3RyaWN0aW9ucy5jIC0tIHdlaWdodCBwcm9wZXJ0eSBoYW5kbGluZyBmb3Igcm9vbXMKKy8vCisvLyAkSWQ6IHJlc3RyaWN0aW9ucy5jIDkwMjAgMjAxNS0wMS0xMCAyMTo0OTo0MVogWmVzc3RyYSAkCisKK2luaGVyaXQgInN0ZC9jb250YWluZXIvcmVzdHJpY3Rpb25zIjsKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKworLy8jZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKworc3RhdGljIGludCBfc2V0X3dlaWdodChpbnQgdyk7CitzdGF0aWMgaW50IF9xdWVyeV93ZWlnaHQoKTsKK3N0YXRpYyBpbnQgX3NldF90b3RhbF93ZWlnaHQoaW50IHcpOworc3RhdGljIGludCBfcXVlcnlfdG90YWxfd2VpZ2h0KCk7CisKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgU2V0KFBfV0VJR0hULFBST1RFQ1RFRCxGX01PREUpOworICBTZXQoUF9UT1RBTF9XRUlHSFQsUFJPVEVDVEVELEZfTU9ERSk7Cit9CisKK2ludCBNYXlBZGRXZWlnaHQoaW50IHcpCit7CisgIHJldHVybiAwOworfQorCitpbnQgTWF5QWRkT2JqZWN0KG9iamVjdCBvYikKK3sgIHJldHVybiAxOyAgfQorCitpbnQgUHJldmVudEluc2VydChvYmplY3Qgb2IpCit7CisgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50IF9zZXRfd2VpZ2h0KGludCB3KQoreworICByZXR1cm4gMDsKK30KKworc3RhdGljIGludCBfcXVlcnlfd2VpZ2h0KCkKK3sKKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgX3NldF90b3RhbF93ZWlnaHQoaW50IHcpCit7CisgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50IF9xdWVyeV90b3RhbF93ZWlnaHQoKQoreworICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL3N0ZC9yb29tL3Nob3AuYyBiL3N0ZC9yb29tL3Nob3AuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNDI5MTI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3Jvb20vc2hvcC5jCkBAIC0wLDAgKzEsMTExMCBAQAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorCitpbmhlcml0ICIvc3RkL3RyYWRpbmdfcHJpY2UiOworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL2NvbW1hbmRzLmg+CisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cm9vbXMuaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPHJvdXRpbmdkLmg+CisjaW5jbHVkZSA8YmFuay5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPGlucHV0X3RvLmg+CisjaW5jbHVkZSA8dW5pdC5oPgorI2luY2x1ZGUgPG1vbmV5Lmg+CisKKy8vIFRPRE86IHBydWVmZW4sIHVtIGRpZSBWYXJpYWJsZW4gcHJpdmF0ZSBzZWluIGtvZW5uZW4uCisKKy8vIGFsbGdlbWVpbiBiZW5vZXRpZ2UgVmFyaWFibGVuCitub3NhdmUgc3RyaW5nIHN0b3JhZ2U7IC8vIEZpbGVuYW1lIGRlcyBTdG9yZXMgaW4gZGVtIGRpZSBPYmpla3RlIGxhZ2Vybi4uLgorbm9zYXZlIG1hcHBpbmcgb2JfYW56OyAvLyB3aWUgb2Z0IGlzdCBlaW4gT2JqZWt0IGltIExhZGVuIHZvcmhhbmRlbj8KKworLy8gSmV0enQgVmFyaWFibGVuIGZ1ZXIgc3RhZW5kaWcgdmVyZnVlZ2JhcmUgT2JqZWt0ZToKK25vc2F2ZSBzdHJpbmcgKmZpeGVkX29iajsgLy8gTGlzdGUgZGVyIHN0YWVuZGlnIHZlcmZ1ZWdiYXJlbiBPYmpla3RlCitub3NhdmUgbWFwcGluZyBmaXhlZF92YWx1ZTsgLy8gUHJlaXNlIGJlaSBTb25kZXJhbmdlYm90ZW4KK25vc2F2ZSBtYXBwaW5nIGZpeGVkX2lkczsgICAvLyBJZHMKKwordmFyYXJncyB2b2lkIEFkZEZpeGVkT2JqZWN0KHN0cmluZyBzdHIsIGludCB2YWwsIHN0cmluZ3xzdHJpbmcqIGlkcykKK3sKKyAgaW50IGk7CisKKyAgLy8gQWNodHVuZywgYmVpIHNvbGNoZW4gT2JqZWt0ZW4gbXVzcyBkaWUgQmx1ZXByaW50IGluaXRpYWxpc2llcnQgd2VyZGVuIQorICBpZiAoIXN0cikgcmV0dXJuOworICBpZiAoIXZhbCkgdmFsPXN0ci0+UXVlcnlQcm9wKFBfVkFMVUUpOworICBpZiAoIWlkcykKKyAgeworICAgIGlmIChzdHItPlF1ZXJ5UHJvcCgidV9pZHMiKSkgLy8gdW5pdHMgaGFiZW4ga2VpbmUgUF9JRFMKKyAgICAgIGlkcz1zdHItPlF1ZXJ5UHJvcCgidV9pZHMiKVswXTsKKyAgICBlbHNlCisgICAgICBpZHM9c3RyLT5RdWVyeVByb3AoUF9JRFMpOworICB9CisgIGlmICghcG9pbnRlcnAoaWRzKSkKKyAgeworICAgIGlmIChzdHJpbmdwKGlkcykpCisgICAgICBpZHM9KHtpZHN9KTsKKyAgICBlbHNlCisgICAgICBpZHM9KHt9KTsKKyAgfQorCisgIGZpeGVkX29iaiArPSAoe3N0cn0pOworICBmaXhlZF92YWx1ZVtzdHJdID0gdmFsOworICAvLyBBbGxlIElEcyBlbnRmZXJuZW4sIGRpZSBTb25kZXJ6ZWljaGVuIGVudGhhbHRlbi4gRGllIGtvZW5udGUgZWluIFNwaWVsZXIKKyAgLy8gYmVpICJrYXVmZSIgb2huZWhpbiBuaWNodCBlaW5nZWJlbi4KKyAgaWRzIC09IHJlZ2V4cChpZHMsICJbXGJcblxyXHRdIik7CisgIGZvcmVhY2goc3RyaW5nIGlkIDogaWRzKQorICB7CisgICAgLy8gTnVyIElEcyBhdWZuZWhtZW4sIGRpZSBrZWluZSBHcm9zc2J1Y2hzdGFiZW4gZW50aGFsdGVuLCBkYSBTcGllbGVyCisgICAgLy8gZGllc2UgZWJlbmZhbGxzIG5pY2h0IGVpbmdlYmVuIGtvZW5udGUuCisgICAgaWYgKCBsb3dlcnN0cmluZyhpZCkgPT0gaWQgKQorICAgICAgZml4ZWRfaWRzW2lkXT1zdHI7CisgIH0KK30KKwordm9pZCBSZW1vdmVGaXhlZE9iamVjdChzdHJpbmcgZmlsZW5hbWUpCit7CisgIGlmKCAhc3RyaW5ncChmaWxlbmFtZSkgfHwgIXNpemVvZihmaXhlZF9vYmopKQorICAgIHJldHVybjsKKyAgaWYoIG1lbWJlcihmaXhlZF9vYmosIGZpbGVuYW1lKT09LTEgKQorICAgIHJldHVybjsKKworICBmaXhlZF9vYmogLT0gKHsgZmlsZW5hbWUgfSk7CisgIG1fZGVsZXRlKGZpeGVkX3ZhbHVlLCBmaWxlbmFtZSk7CisKKyAgZm9yZWFjaChzdHJpbmcgaWQsIHN0cmluZyBmaWxlIDogZml4ZWRfaWRzKQorICB7CisgICAgaWYgKCBmaWxlID09IGZpbGVuYW1lICkKKyAgICAgIG1fZGVsZXRlKGZpeGVkX2lkcywgaWQpOworICB9Cit9CisKK3N0YXRpYyBzdHJpbmcgU2V0U3RvcmFnZVJvb20oc3RyaW5nIHN0cikKK3sKKyAgaWYgKHN0ciAmJiBzdHJpbmdwKHN0cikpIHJldHVybiBzdG9yYWdlPXN0cjsKKyAgcmV0dXJuIDA7Cit9CisKK3N0cmluZyBRdWVyeVN0b3JhZ2VSb29tKCkKK3sgICByZXR1cm4gc3RvcmFnZTsgICB9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIG9iamVjdCByb3V0ZXI7CisgIAorICBpZiAob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bMC4uPDNdKQorICB7CisgICAgc2V0X25leHRfcmVzZXQoLTEpOworICAgIHJldHVybjsKKyAgfQorCisgIHRyYWRpbmdfcHJpY2U6OmNyZWF0ZSgpOworCisgIFNldFByb3AoIFBfTkFNRSwgIkhhZW5kbGVyIiApOworICBTZXRQcm9wKCBQX0dFTkRFUiwgTUFMRSApOworICBTZXRQcm9wKCBQX1JPT01fVFlQRSwgUXVlcnlQcm9wKFBfUk9PTV9UWVBFKSB8IFJUX1NIT1AgKTsKKworICBBZGRDbWQoInplaWdlIiwibGlzdCIpOworICBBZGRDbWQoKHsia2F1ZiIsImthdWZlIiwiYmVzdGVsbCIsImJlc3RlbGxlIn0pLCJidXkiKTsKKyAgQWRkQ21kKCh7InZlcmthdWYiLCJ2ZXJrYXVmZSIsInZlcmsifSksInNlbGwiKTsKKyAgQWRkQ21kKCh7InZlcnNldHoiLCJ2ZXJzZXR6ZSJ9KSwiZm9yY2Vfc2VsbCIpOworICBBZGRDbWQoKHsic2NoYWV0eiIsInNjaGFldHplIn0pLCJldmFsdWF0ZSIpOworICBBZGRDbWQoKHsidW50ZXJzdWNoZSIsInVudCJ9KSwgInNob3dfb2JqIik7CisKKyAgU2V0VHJhZGluZ0RhdGEoNTAwMDAsMzAwLDMpOworCisgIG9iX2Fuej0oW10pOworICBmaXhlZF9vYmo9KHt9KTtmaXhlZF92YWx1ZT0oW10pO2ZpeGVkX2lkcz0oW10pOworCisgIEFkZEZpeGVkT2JqZWN0KEJPRVJTRSwgODAsKHsgImJvZXJzZSIsImdlbGRib2Vyc2UifSkpOworCisgIGlmICghY2xvbmVwKE1FKSAmJiBvYmplY3RwKHJvdXRlcj1maW5kX29iamVjdChST1VURVIpKSkKKyAgICByb3V0ZXItPlJlZ2lzdGVyVGFyZ2V0KFRBUkdFVF9TSE9QLG9iamVjdF9uYW1lKE1FKSk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCisvLyBMZWdhY3ktVmVyc2lvbiB2b24gR2V0U2hvcEl0ZW1zKCkgZnVlciBkaWUgZXJiZW5kZW4gTGFlZGVuLCBkaWUgYXVmCisvLyBkaWUgRnVua3Rpb24gaW4gZGllc2VyIEZvcm0gYW5nZXdpZXNlbiBzaW5kLgorc3RhdGljIG1peGVkICpHZXRMaXN0KCkKK3sKKyAgb2JqZWN0IHN0b3JlID0gbG9hZF9vYmplY3Qoc3RvcmFnZSk7CisgIHN0b3JlLT5fcmVnaXN0ZXJfc2hvcChNRSk7CisKKyAgbWl4ZWQgKm91dHB1dD0oe30pOworICBpZiAoIW9iamVjdHAoc3RvcmUpKQorICAgIHJldHVybiBvdXRwdXQ7CisKKyAgbWl4ZWQgdG1wID0gbWFwKGZpeGVkX29iaiwgIydsb2FkX29iamVjdCkrYWxsX2ludmVudG9yeShzdG9yZSk7CisgIG1hcHBpbmcgdG1wMiA9IChbXSk7CisgIG1peGVkIHN0cjsKKyAgc3RyaW5nIGNvbXA7CisgIGludCBpOworICBpbnQgcz0xOworCisgIGZvciAoaT1zaXplb2YodG1wKS0xIDsgaT49MCA7IGktLSkKKyAgeworICAgIHN0ciA9ICh7ICh7IHNwcmludGYoIiUtMjUuMjVzJTcuN2QiLAorICAgICAgICAgICAgICAgICAgICAgICAgKHRtcFtpXS0+c2hvcnQoKXx8Ij8/PyIpWzAuLjwzXSwKKyAgICAgICAgICAgICAgICAgICAgICAgIFF1ZXJ5QnV5VmFsdWUodG1wW2ldLCBQTCkpLAorICAgICAgICAgICAgICAgIHRtcFtpXSB9KSB9KTsKKyAgICBjb21wPXN0clswXVswXVswLi4yNV07CisgICAgaWYgKCF0bXAyW2NvbXBdKQorICAgIHsKKyAgICAgIHRtcDJbY29tcF0gPSBzKys7CisgICAgICBvdXRwdXQgKz0gc3RyOworICAgIH0KKyAgICBlbHNlIG91dHB1dFt0bXAyW2NvbXBdLTFdWzBdID0gc3RyWzBdWzBdOworICB9CisgIHJldHVybiBvdXRwdXQ7Cit9CisKKy8vIExlZ2FjeS1WZXJzaW9uIHZvbiBQcmludExpc3QoKSBmdWVyIGRpZSBlcmJlbmRlbiBMYWVkZW4sIGRpZSBhdWYKKy8vIGRpZSBGdW5rdGlvbiBpbiBkaWVzZXIgRm9ybSBhbmdld2llc2VuIHNpbmQuCitzdGF0aWMgaW50IERvTGlzdChzdHJpbmcgcXVlcnlfZnVuKQoreworICBtaXhlZCogb3V0cHV0PUdldExpc3QoKTsKKyAgaW50IHNpID0gc2l6ZW9mKG91dHB1dCk7CisgIGlmICghc2kpCisgIHsKKyAgICB3cml0ZSgiSW0gTW9tZW50IHNpbmQgd2lyIGxlaWRlciBWT0VMTElHIGF1c3ZlcmthdWZ0IVxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgc3RyaW5nIG91dD0iIjsKKyAgaW50IGk7CisgIGludCBpbmRlbnQ7CisgIGZvciAoaT0wOyBpPHNpOyBpKyspCisgIHsKKyAgICBpZiAoY2FsbF9vdGhlcihNRSwgcXVlcnlfZnVuLCBvdXRwdXRbaV1bMV0pKQorICAgIHsKKyAgICAgIGluZGVudCA9ICFpbmRlbnQ7CisgICAgICBvdXQgKz0gc3ByaW50ZigiJTNkLiAlcyIsIGkrMSwgb3V0cHV0W2ldWzBdKTsKKyAgICAgIGlmICghaW5kZW50KQorICAgICAgICBvdXQgKz0gIlxuIjsKKyAgICAgIGVsc2Ugb3V0ICs9ICIgfCAiOworICAgIH0KKyAgfQorICBpZiAoaW5kZW50KQorICAgIG91dCs9IlxuIjsKKyAgUEwtPk1vcmUob3V0KTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vIExpZWZlcnQgZWluZSBMaXN0ZSBkZXIgT2JqZWt0ZSB6dXJ1ZWNrLCBkaWUgZ2VyYWRlIGltIFN0b3JhZ2UgbGllZ2VuLAorLy8gcHJvIEJsdWVwcmludCBqZXdlaWxzIGVpbnMuCitwcm90ZWN0ZWQgb2JqZWN0KiBHZXRTaG9wSXRlbXMoKQoreworICBvYmplY3Qgc3RvcmUgPSBsb2FkX29iamVjdChzdG9yYWdlKTsKKyAgc3RvcmUtPl9yZWdpc3Rlcl9zaG9wKE1FKTsKKyAgb2JqZWN0KiBvdXRwdXQgPSAoe30pOworICBvYmplY3QqIGFsbF9pdGVtcyA9IGFsbF9pbnZlbnRvcnkoc3RvcmUpOworCisgIC8vIFdpciBicmF1Y2hlbiBlaW5lIExpc3RlLCBkaWUgdm9uIGplZGVyIEJsdWVwcmludCBudXIgZWluZW4gQ2xvbmUKKyAgLy8gZW50aGFlbHQuIERhaGVyIHdlcmRlbiBkaWUgTGFkZW5hbWVuIGRlciBPYmpla3RlIGFscyBLZXlzIGltIE1hcHBpbmcKKyAgLy8gPGl0ZW1zPiB2ZXJ3ZW5kZXQgdW5kIGpld2VpbHMgZGVyIGFrdHVlbGxlIENsb25lIGFscyBWYWx1ZSB6dWdlb3JkbmV0LgorICBtYXBwaW5nIGl0ZW1zID0gbV9hbGxvY2F0ZShzaXplb2YoYWxsX2l0ZW1zKSk7CisgIGZvcmVhY2gob2JqZWN0IG9iOiBhbGxfaXRlbXMpCisgIHsKKyAgICBpdGVtc1tsb2FkX25hbWUob2IpXSA9IG9iOworICB9CisgIC8vIERpZSBGaXhlZCBPYmplY3RzIHdlcmRlbiBhbnMgRW5kZSBhbmdlaGFlbmd0LCBkYW1pdCBpbiBkZW0gRmFsbCwgZGFzcworICAvLyBlaW4gQ2xvbmUgZWluZXMgc29sY2hlbiBPYmpla3RlcyBpbSBMYWdlciBsaWVndCwgZGllc2VyIHp1ZXJzdCB2ZXJrYXVmdAorICAvLyB3aXJkIHVuZCBuaWNodCBpbW1lciB3aWVkZXIgZWluIG5ldWVyIGVyc3RlbGx0IHdpcmQuCisgIHJldHVybiBtX3ZhbHVlcyhpdGVtcykgKyBtYXAoZml4ZWRfb2JqLCAjJ2xvYWRfb2JqZWN0KTsKK30KKworI2RlZmluZSBMSVNUX0xPTkcgIDEKKyNkZWZpbmUgTElTVF9TSE9SVCAwCisKKy8vIEt1ZW1tZXJ0IHNpY2ggdW0gZGllIExpc3RlbmF1c2dhYmUgZnVlciBkZW4gQmVmZWhsICJ6ZWlnZSIKK3ZhcmFyZ3MgcHJvdGVjdGVkIGludCBQcmludExpc3Qoc3RyaW5nIGZpbHRlcl9mdW4sIGludCBsaXN0c3R5bGUpCit7CisgIC8vIEFsbGUgSXRlbXMgaW0gTGFnZXIgaG9sZW4uIFdlbm4ga2VpbmUgdm9yaGFuZGVuLCB0dXQgdW5zIGRhcyBsZWlkLgorICBvYmplY3QgKml0ZW1zX2luX3N0b3JlID0gR2V0U2hvcEl0ZW1zKCk7CisgIGlmICggIXNpemVvZihpdGVtc19pbl9zdG9yZSkgKSB7CisgICAgd3JpdGUoIkltIE1vbWVudCBzaW5kIHdpciBsZWlkZXIgVk9FTExJRyBhdXN2ZXJrYXVmdCFcbiIpOworICAgIHJldHVybiAxOworICB9CisKKyAgLy8gRGFzIExpc3RlbmZvcm1hdCBpc3Qgdm9uIGRlciBTcGllbGVyZWluZ2FiZSBhYmhhZW5naWcuIFd1cmRlICJsYW5nIgorICAvLyBhbmdlZm9yZGVydCwgZ2ViZW4gd2lyIGVpbnNwYWx0aWcgYXVzIG1pdCBncm9lc3NlcmVyIFNwYWx0ZW5icmVpdGUuCisgIC8vIERpZSBTcGFsdGVuYnJlaXRlIHdpcmQgZGFiZWkgdm9uIGRlbSBJdGVtIG1pdCBkZW0gbGFlbmdzdGVuIE5hbWVuIGltCisgIC8vIGdlc2FtdGVuIFNob3AtSW52ZW50YXIgYmVzdGltbXQsIGRhbWl0IG5pY2h0IGJlaSBqZWRlciBUZWlsbGlzdGUKKyAgLy8gKFdhZmZlbiwgUnVlc3R1bmdlbiwgVmVyc2NoaWVkZW5lcykgdW50ZXJzY2hpZWRsaWNoZSBCcmVpdGVuIHJhdXNrb21tZW4uCisgIC8vCisgIC8vIERlciBlcnN0ZSBQYXJhbWV0ZXIgZW50aGFlbHQgZGllIEthdGFsb2dudW1tZXIgZGVzIEl0ZW1zLCBkZXIgendlaXRlCisgIC8vIGRpZSBLdXJ6YmVzY2hyZWlidW5nLCBkZXIgZHJpdHRlIGRlbiBQcmVpcy4KKyAgc3RyaW5nIGxpc3Rmb3JtYXQgPSAiJTNkLiAlLTI1LjI1cyAlNi42ZCI7CisgIGlmICggbGlzdHN0eWxlID09IExJU1RfTE9ORyApCisgIHsKKyAgICBzdHJpbmcqIG5hbWVzID0gc29ydF9hcnJheSgKKyAgICAgICAgICAgICAgICAgICAgICBpdGVtc19pbl9zdG9yZS0+c2hvcnQoKSwKKyAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBpbnQgKHN0cmluZyBzMSwgc3RyaW5nIHMyKSB7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gKHNpemVvZihzMSkgPCBzaXplb2YoczIpKTsKKyAgICAgICAgICAgICAgICAgICAgICB9KTsKKyAgICAvLyBXZW5uIGVpbnNwYWx0aWcgYXVzZ2VnZWJlbiB3aXJkLCBzb2xsIGRpZSBMaXN0ZSBuaWNodCBiZWxpZWJpZyBicmVpdAorICAgIC8vIHdlcmRlbi4gRGFoZXIgd2lyZCBkaWUgU2hvcnQgYXVmIDY1IFplaWNoZW4gbGltaXRpZXJ0LgorICAgIGludCBsZW4gPSA2NTsKKyAgICBpZiAoIHNpemVvZihuYW1lcykgKQorICAgICAgbGVuID0gbWluKGxlbiwgc2l6ZW9mKG5hbWVzWzBdKSk7CisgICAgbGlzdGZvcm1hdCA9ICIlM2QuICUtIitsZW4rIi4iK2xlbisicyAlNi42ZCI7CisgIH0KKworICBzdHJpbmcgb3V0PSIiOworICAvLyBWYXJpYWJsZW4sIGRpZSBpbm5lcmhhbGIgZGVyIFNjaGxlaWZlIGJlbm9ldGlndCB3ZXJkZW4uCisgIHN0cmluZyBrdXJ6OworICBpbnQgaW5kZW50LCBwcmVpczsKKyAgb2JqZWN0IGl0ZW07CisgIC8vIFVlYmVyIGRpZSBMaXN0ZSBsYXVmZW4uIDxpPiB3aXJkIGJlbm9ldGlndCwgdW0gZGllIGF1c2dlZ2ViZW5lIExpc3RlCisgIC8vIGtvbnNpc3RlbnQgbnVtZXJpZXJlbiB6dSBrb2VubmVuLCBkYW1pdCBrYXVmZSA8bnI+IGZ1bmt0aW9uaWVydC4KKyAgZm9yZWFjaChpbnQgaSA6IHNpemVvZihpdGVtc19pbl9zdG9yZSkpCisgIHsKKyAgICBpdGVtID0gaXRlbXNfaW5fc3RvcmVbaV07CisgICAgaWYgKCBjYWxsX290aGVyKE1FLCBmaWx0ZXJfZnVuLCBpdGVtKSApCisgICAgeworICAgICAgLy8gS3VyemJlc2NocmVpYnVuZyB1bmQgUHJlaXMgZXJtaXR0ZWxuLiBJdGVtcyBvaG5lIFNob3J0IHdlcmRlbgorICAgICAgLy8gYWxzICI/IiBhbmdlemVpZ3QuCisgICAgICBrdXJ6ID0gKGl0ZW0tPnNob3J0KCkgfHwgIj8/PyIpWzAuLjwzXTsKKyAgICAgIHByZWlzID0gUXVlcnlCdXlWYWx1ZShpdGVtLCBQTCk7CisgICAgICAvLyBCZXNjaHJlaWJ1bmcgZGVzIEl0ZW1zIGFuZnVlZ2VuLgorICAgICAgb3V0ICs9IHNwcmludGYobGlzdGZvcm1hdCwgaSsxLCBrdXJ6LCBwcmVpcyk7CisgICAgICBpbmRlbnQgPSAhaW5kZW50OworICAgICAgLy8gV2VubiBpbmRlbnQgZ2VzZXR6dCBpc3QsIGhhbmRlbHQgZXMgc2ljaCB1bSBkYXMgbGlua2UgSXRlbSBpbiBkZXIKKyAgICAgIC8vIHp3ZWlzcGFsdGlnZW4gTGlzdGUsIGRhbm4gZnVlZ2VuIHdpciBlaW5lbiBTcGFsdGVudHJlbm5lciBhbiwKKyAgICAgIC8vIGFuc29uc3RlbiBpc3QgZXMgZGFzIHJlY2h0ZSwgZGFubiBicmVjaGVuIHdpciB1bS4KKyAgICAgIC8vIEdpbHQgbmF0dWVybGljaCBudXIgZnVlciBrdXJ6ZSBMaXN0ZW4uCisgICAgICBvdXQgKz0gKChpbmRlbnQgJiYgbGlzdHN0eWxlPT1MSVNUX1NIT1JUKT8gIiB8ICIgOiAiXG4iKTsKKyAgICB9CisgIH0KKyAgLy8gV2VubiBkaWUgTGlzdGUgZWluZSB1bmdlcmFkZSBaYWhsIEl0ZW1zIGVudGhhZWx0LCBpc3QgaW4gZGVyIGxldHp0ZW4KKyAgLy8gWmVpbGUgbGlua3MgZWluIEl0ZW0gYXVmZ2VmdWVocnQsIGRhaGVyIG11c3MgZGFuYWNoIHVtYnJvY2hlbiB3ZXJkZW4uCisgIC8vIEdpbHQgbmF0dWVybGljaCBudXIgZnVlciBrdXJ6ZSBMaXN0ZW4KKyAgaWYgKGluZGVudCAmJiBsaXN0c3R5bGU9PUxJU1RfU0hPUlQpCisgICAgb3V0Kz0iXG4iOworCisgIC8vIFZvciBkZW4gTGlzdGVuIHdpcmQgZWluZSBJbmZvLVplaWxlIGF1c2dlZ2ViZW4sIHVtIGdlZmlsdGVydGUgTGlzdGVuCisgIC8vIGtlbm50bGljaCB6dSBtYWNoZW4uIFdpcmQgbmFjaCBkZXIgRmlsdGVydW5nIGRlcyBJbnZlbnRhcnMgZXJ6ZXVndCwKKyAgLy8gdW0gZWluZSBsZWVyZSBNZWxkdW5nIGF1c2dlYmVuIHp1IGtvZW5uZW4sIHdlbm4gbmFjaCBGaWx0ZXJ1bmcgbmljaHRzCisgIC8vIG1laHIgdWVicmlnYmxlaWJ0LgorICBzdHJpbmcgd2FzOworICBzd2l0Y2goZmlsdGVyX2Z1bikKKyAgeworICAgIGNhc2UgIklzQXJtb3VyIjogd2FzID0gIlJ1ZXN0dW5nZW4iOyBicmVhazsKKyAgICBjYXNlICJJc1dlYXBvbiI6IHdhcyA9ICJXYWZmZW4iOyBicmVhazsKKyAgICBjYXNlICJOb1dlYXBvbk5vQXJtb3VyIjoKKyAgICAgICAgIHdhcyA9IChvdXQ9PSIiPyJzb25zdGlnZW4gV2FyZW4iOiJzb25zdGlnZSBXYXJlbiIpOyBicmVhazsKKyAgICBkZWZhdWx0OiB3YXMgPSAiV2FyZW4iOyBicmVhazsKKyAgfQorICAvLyA8b3V0PiBpc3QgZWluIExlZXJzdHJpbmcsIHdlbm4ga2VpbmUgV2FyZW4gZGEgc2luZCwgZGllIGRlbSBGaWx0ZXJrcmktCisgIC8vIHRlcml1bSBlbnRzcHJlY2hlbi4gRGFubiBnaWJ0J3MgZWluZSBlbnRzcHJlY2hlbmRlIE1lbGR1bmcuCisgIGlmICggb3V0ID09ICIiICkKKyAgICBvdXQgPSBzcHJpbnRmKCJMZWlkZXIgc2luZCBtb21lbnRhbiBrZWluZSAlcyBpbSBBbmdlYm90LlxuIiwgd2FzKTsKKyAgZWxzZQorICAgIG91dCA9IHNwcmludGYoIkZvbGdlbmRlICVzIGthbm5zdCBEdSBoaWVyIGthdWZlbjpcbiIsd2FzKSArIG91dDsKKworICBQTC0+TW9yZShvdXQpOworICByZXR1cm4gMTsKK30KKworLy8gSGlsZnNmdW5rdGlvbmVuIHp1bSBGaWx0ZXJuIGRlcyBMYWRlbmludmVudGFycyBmdWVyIGRlbiAiemVpZ2UiLUJlZmVobAorc3RhdGljIGludCBBbHdheXNUcnVlKG9iamVjdCBvYikKK3sgICByZXR1cm4gMTsgICB9CisKK3N0YXRpYyBzdHJpbmcgSXNXZWFwb24ob2JqZWN0IG9iKQoreyAgcmV0dXJuIG9iLT5RdWVyeVByb3AoUF9XRUFQT05fVFlQRSk7ICB9CisKK3N0YXRpYyBzdHJpbmcgSXNBcm1vdXIob2JqZWN0IG9iKQoreyAgcmV0dXJuIG9iLT5RdWVyeVByb3AoUF9BUk1PVVJfVFlQRSk7ICB9CisKK3N0YXRpYyBpbnQgTm9XZWFwb25Ob0FybW91cihvYmplY3Qgb2IpCit7IHJldHVybiAoIW9iLT5RdWVyeVByb3AoUF9XRUFQT05fVFlQRSkgJiYgIW9iLT5RdWVyeVByb3AoUF9BUk1PVVJfVFlQRSkpOyB9CisKKworLy8gRGllc2UgRnVua3Rpb24gaXN0IG9lZmZlbnRsaWNoLCBmYWxscyBNYWdpZXIgYWJmcmFnZW4gd29sbGVuLCBvYiBlaW4gbGFkZW4KKy8vIGVpbiBPYmpla3QgemVyc3RvZXJlbiB3dWVyZGUuIEFiZXI6IEJlbnV0enVuZyBhdWYgZWlnZW5lcyBSaXNpa28hIEVzIHdpcmQKKy8vIG5pY2h0IGdhcmFudGllcnQsIGRhc3MgZGllc2UgRnVua3Rpb24gYnp3LiBpaHIgSW50ZXJmYWNlIHNpY2ggbmljaHQKKy8vIGFlbmRlcnQuCitwdWJsaWMgaW50IENoZWNrRm9yRGVzdHJ1Y3Qob2JqZWN0IG9iKSAvLyBQcnVlZmVuLCBvYiB6ZXJzdG9lcnQgd2VyZGVuIHNvbGwKK3sKKyAgc3RyaW5nIHN0cjsKKyAgLyoKKyAgICogUF9OT0JVWSAtIE9iamVrdGUgYXVmIGplZGVuIEZhbGwgemVyc3RvZXJlbgorICAgKi8KKyAgaWYob2ItPlF1ZXJ5UHJvcChQX05PQlVZKSkgcmV0dXJuIDE7CisgIC8qCisgICAqIEJlc2NoYWVkaWd0ZSBPYmpla3RlIHdlcmRlbiBlYmVuZmFsbHMgemVyc3RvZXJ0CisgICAqLworICBpZihvYi0+UXVlcnlQcm9wKFBfREFNQUdFRCkpIHJldHVybiAxOworICAvKgorICAgKiBSdWVzdHVuZ2VuIHdlbm4gc2llIGEpIGVpbmUgRGVmZW5kRnVuYyBkZWZpbmllcnQgaGFiZW4gb2RlcgorICAgKiAgICAgICAgICAgICAgICAgICAgIGIpIHVlYmVyIGRlciBpbiBLRUVQX0FSTU9VUl9DTEFTUyBkZWZpbmllcnRlbiBBQworICAgKiAgICAgICAgICAgICAgICAgICAgICAgIGxpZWdlbiAoc2llaGUgL3N5cy9jb21iYXQuaCkKKyAgICovCisgIGlmKHN0ciA9IElzQXJtb3VyKG9iKSkKKyAgeworICAgIGlmKG9iamVjdHAob2ItPlF1ZXJ5UHJvcChQX0RFRkVORF9GVU5DKSkpIHJldHVybiAxOworICAgIGlmKG9iLT5RdWVyeVByb3AoUF9BQykgPj0gS0VFUF9BUk1PVVJfQ0xBU1Nbc3RyXSkgcmV0dXJuIDE7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgLyoKKyAgICogV2FmZmVuIHdlbm4gc2llIGEpIDEtaGFlbmRpZyBzaW5kIHVuZCBlaW5lIFdDID4gMTIwIGJlc2l0emVuIG9kZXIKKyAgICogICAgICAgICAgICAgICAgIGIpIDItaGFlbmRpZyBzaW5kIHVuZCBlaW5lIFdDID4gMTUwIGJlc2l0emVuIG9kZXIgYWJlcgorICAgKiAgICAgICAgICAgICAgICAgYykgZWluZSBIaXRGdW5jIGRlZmluaWVydCBoYWJlbgorICAgKi8KKyAgaWYoc3RyID0gSXNXZWFwb24ob2IpKQorICB7CisgICAgaWYob2ItPlF1ZXJ5UHJvcChQX05SX0hBTkRTKSA+IDEgJiYgb2ItPlF1ZXJ5UHJvcChQX1dDKSA+IDE1MCkgcmV0dXJuIDE7CisgICAgaWYob2ItPlF1ZXJ5UHJvcChQX05SX0hBTkRTKSA8IDIgJiYgb2ItPlF1ZXJ5UHJvcChQX1dDKSA+IDEyMCkgcmV0dXJuIDE7CisgICAgaWYob2JqZWN0cChvYi0+UXVlcnlQcm9wKFBfSElUX0ZVTkMpKSkgcmV0dXJuIDE7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgbGlzdChzdHJpbmcgc3RyKQoreworICBfbm90aWZ5X2ZhaWwoCisgICAgIkJpdHRlICd6ZWlnZScsICd6ZWlnZSB3YWZmZW4nLCAnemVpZ2UgcnVlc3R1bmdlbicgb2RlclxuIgorICAgICInemVpZ2UgdmVyc2NoaWVkZW5lcycgZWluZ2ViZW4uIFdlbm4gRHUgZGFzIFNjaGx1ZXNzZWx3b3J0ICdsYW5nJ1xuIgorICAgICJvZGVyICctMScgYW5oYWVuZ3N0LCB3aXJkIGRpZSBMaXN0ZSBlaW5zcGFsdGlnIGF1c2dlZ2ViZW4uXG4iKTsKKworICBpZiAoIXN0cmluZ3Aoc3RyKSB8fCAhc2l6ZW9mKHN0cikgKQorICAgIHJldHVybiBQcmludExpc3QoIkFsd2F5c1RydWUiKTsKKyAgaWYgKCBzdHIgPT0gImxhbmciIHx8IHN0ciA9PSAiLTEiICkKKyAgICByZXR1cm4gUHJpbnRMaXN0KCJBbHdheXNUcnVlIiwgTElTVF9MT05HKTsKKworICBzdHJpbmcgKnBhcmFtcyA9IGV4cGxvZGUoc3RyLCIgIik7CisgIGlmIChzaXplb2YocGFyYW1zWzBdKTwzKQorICAgIHJldHVybiAwOworCisgIGludCBsaXN0c3R5bGUgPSBMSVNUX1NIT1JUOworICBpZiAoIHNpemVvZihwYXJhbXMpPjEgJiYgcGFyYW1zWzFdID09ICJsYW5nIiApCisgICAgbGlzdHN0eWxlID0gTElTVF9MT05HOworCisgIHN0cj1wYXJhbXNbMF1bMC4uMl07CisgIGlmIChzdHI9PSJ3YWYiKQorICAgIHJldHVybiBQcmludExpc3QoIklzV2VhcG9uIiwgbGlzdHN0eWxlKTsKKyAgaWYgKHN0cj09InZlciIpCisgICAgcmV0dXJuIFByaW50TGlzdCgiTm9XZWFwb25Ob0FybW91ciIsIGxpc3RzdHlsZSk7CisgIGlmIChzdHI9PSJydWUiKQorICAgIHJldHVybiBQcmludExpc3QoIklzQXJtb3VyIiwgbGlzdHN0eWxlKTsKKyAgcmV0dXJuIDA7Cit9CisvKgorc3RhdGljIHZhcmFyZ3MgaW50IFF1ZXJ5QnV5VmFsdWUobWl4ZWQgb2IsIG9iamVjdCBjbGllbnQpCit7CisgIGlmIChvYmplY3RwKG9iKSkKKyAgICByZXR1cm4gdHJhZGluZ19wcmljZTo6UXVlcnlCdXlWYWx1ZShvYiwgY2xpZW50KTsKKyAgcmV0dXJuIChmaXhlZF92YWx1ZVtvYl0qUXVlcnlCdXlGYWN0KGNsaWVudCkpLzEwMDsKK30KKyovCisKK3N0YXRpYyB2YXJhcmdzIGludCBRdWVyeUJ1eVZhbHVlKG9iamVjdCBvYiwgb2JqZWN0IGNsaWVudCkKK3sKKyAgaW50IGZwcmljZSA9IGZpeGVkX3ZhbHVlW2xvYWRfbmFtZShvYildOworCisgIHJldHVybiAoZnByaWNlPjApID8gCisgICAgICAgICBmcHJpY2UqUXVlcnlCdXlGYWN0KGNsaWVudCkvMTAwIDogCisgICAgICAgICB0cmFkaW5nX3ByaWNlOjpRdWVyeUJ1eVZhbHVlKG9iLCBjbGllbnQpOworfQorCitzdGF0aWMgdm9pZCBVcGRhdGVDb3VudGVyKG9iamVjdCBvYiwgaW50IG51bSkKK3sKKyAgc3RyaW5nIHRtcDsKKworICBpZiAoIW51bSB8fCAhb2JqZWN0cChvYikpIHJldHVybjsKKyAgdG1wPUJMVUVfTkFNRShvYik7CisgIGlmICh0bXBbMC4uMl0hPSIvZC8iICYmIHRtcFswLi44XSE9Ii9wbGF5ZXJzLyIpCisgICAgdG1wPW9iLT5zaG9ydCgpK3RtcDsKKyAgb2JfYW56W3RtcF0gKz0gbnVtOworICBpZiAob2JfYW56W3RtcF0gPD0gMCkKKyAgICBtX2RlbGV0ZShvYl9hbnosdG1wKTsKK30KKworcHJvdGVjdGVkIG9iamVjdCBGaW5kSW5TdG9yZShzdHJpbmd8aW50IHgpCit7CisgIG9iamVjdCogbGlzdCA9IEdldFNob3BJdGVtcygpOworICBpZiAoIGludHAoeCkgJiYgeD4wICYmIHg8PXNpemVvZihsaXN0KSApIHsKKyAgICByZXR1cm4gbGlzdFt4LTFdOworICB9CisgIGlmIChzdHJpbmdwKHgpKQorICB7CisgICAgaWYgKCBmaXhlZF9pZHNbeF0gKQorICAgICAgcmV0dXJuIGxvYWRfb2JqZWN0KGZpeGVkX2lkc1t4XSk7CisgICAgbGlzdCA9IGZpbHRlcl9vYmplY3RzKGxpc3QsICJpZCIsIHgpOworICAgIGlmICggc2l6ZW9mKGxpc3QpICkKKyAgICAgIHJldHVybiBsaXN0WzBdOworICAgIC8vIFdlbm4gbml4IGltIFN0b3JlIGdlZnVuZGVuIChkYXMgc2NobGllc3N0IGVpZ2VudGxpY2h0IHNjaG9uIGRpZSBCUHMgZGVyCisgICAgLy8gZml4ZW4gT2JqZWt0ZSBlaW4sIGFiZXIgbmljaHQsIHdlbm4gZGllc2UgbmljaHQga29uZmlndXJpZXJ0IHNpbmQuIEQuaC4KKyAgICAvLyBkaWVzZSBQcnVlZnVuZyBpc3QgZnVlciBuaWNodC1rb25maWd1cmllcnRlIEJQcyksIExpc3RlIGRlcgorICAgIC8vIEZpeGVkT2JqZWN0cyBwcnVlZmVuIHVuZGUgc28gZGllIGV2ZW50dWVsbCBtYW51ZWxsIGluCisgICAgLy8gQWRkRml4ZWRPYmplY3QoKSBhbmdlZ2ViZW5lIExpc3RlIHZvbiBJRHMgYmVydWVja3NpY2h0aWdlbi4KKyAgICBlbHNlIGlmICggZml4ZWRfaWRzW3hdICkKKyAgICAgIHJldHVybiBsb2FkX29iamVjdChmaXhlZF9pZHNbeF0pOworICB9CisgIHJldHVybiAwOworfQorCitzdGF0aWMgc3RyaW5nIGJ1eV9vYmoobWl4ZWQgb2IsIGludCBzaG9ydCkKK3sgcmV0dXJuIDA7IH0KKworcHJpdmF0ZSB2b2lkIHJlYWxseV9idXkoaW50IHZhbCwgb2JqZWN0IHBsLCBvYmplY3Qgb2IsIGludCB1X3JlcSkKK3sKKyAgLy8gU3RhZW5kaWcgdmVyZnVlZ2JhcmUgT2JqZWt0ZSAoZml4ZWRfb2JqKSBzaW5kIGRhcmFuIGVya2VubmJhciwgZGFzcyBzaWUKKyAgLy8gbmljaHQgaW0gTGFnZXIgbGllZ2VuLiBEYWhlciBoaWVyIGVpbmVuIENsb25lIGVyc3RlbGxlbiwgZGVyIGRhbm4gCisgIC8vIHN0YXR0ZGVzc2VuIHJhdXNnZWdlYmVuIHdpcmQuCisgIGlmICggIXByZXNlbnQob2IsIGZpbmRfb2JqZWN0KHN0b3JhZ2UpKSApCisgICAgb2IgPSBjbG9uZV9vYmplY3Qob2IpOworCisgIC8vIEluIFVuaXRvYmpla3RlbiBVX1JFUSAod2llZGVyKSBzZXR6ZW4gKHdlZ2VuIGlucHV0X3RvIChiZWkgZGVtIHNpY2ggZGFzCisgIC8vIEtvbW1hbmRvdmVyYiBhZW5kZXJ0IHVuZCBkZXN3ZWdlbiBVX1JFUSBnZWxvZXNjaHQgd2lyZCksIHVuZCB3ZWdlbgorICAvLyBLYXVmZW5zIHZvbiBGaXhlZC1PYmpla3QtVW5pdG9iamVrdGVuIChiZWkgZGllc2VuIG11c3MgVV9SRVEgX25hY2hfIGRlbQorICAvLyBDbG9uZW4gaW0gQ2xvbmUgZ2VzZXR6dCB3ZXJkZW4sIG5pY2h0IGF1dG9tYWdpc2NoIGluIGRlciBCUCBkdXJjaCBkZW4KKyAgLy8gQXVmcnVmIHZvbiBpZCgpIHdlaXRlciB2b3JoZXIpLgorICBpZiAodV9yZXE+MCkKKyAgeworICAgIC8vIERhcyBRdWVyeVByb3AoKSBpc3QgbmljaHQgdW5ub2V0aWcuIEJlaSBkZXIgQWJmcmFnZSB2b24gVV9SRVEgd2lyZAorICAgIC8vIFVfUkVRIGdlbnVsbHQsIHdlbm4gZGFzIGFrdHVlbGxlIHF1ZXJ5X3ZlcmIoKSAhPSBkZW0gbGV0enRlbiBpc3QuCisgICAgLy8gQmVpIGRlciBlcnN0ZW4gQWJmcmFnZSB3dWVyZGUgYWxzIGRhcyBoaWVyIGdlc2V0enQgVV9SRVEgd2llZGVyCisgICAgLy8gZ2Vsb2VzY2h0LiBEYWhlciBtdXNzIGRhcyBqZXR6dCBoaWVyIGFscyBlcnN0ZXMgZWlubWFsIGFiZ2VmcmFndAorICAgIC8vIHdlcmRlbi4uLgorICAgICAgb2ItPlF1ZXJ5UHJvcChVX1JFUSk7CisgICAgICBvYi0+U2V0UHJvcChVX1JFUSwgdV9yZXEpOworICB9CisKKyAgcGwtPkFkZE1vbmV5KC12YWwpOworICBfYWRkX21vbmV5KHZhbCk7CisKKyAgaWYgKG9iLT5tb3ZlKHBsLE1fR0VUKSAhPSBNT1ZFX09LKSAvLyBLYW5uIGRlciBTcGllbGVyIGRhcyBPYmpla3QgdHJhZ2VuPworICB7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJEdSBrYW5uc3QgIitvYi0+bmFtZShXRU4sMSkrIiBuaWNodCBtZWhyIHRyYWdlbi4gIgorICAgICAiSWNoIGxlZ2UgIitvYi0+UXVlcnlQcm9ub3VuKFdFTikrIiBoaWVyIGF1ZiBkZW4gQm9kZW4uIiw3OCwKKyAgICAgTmFtZShXRVIpKyIgc2FndDogIikpOworICAgIG9iLT5tb3ZlKE1FLE1fTk9DSEVDSyk7ICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE5laW4gOi0pCisgIH0KKyAgZWxzZQorICB7CisgICAgLy8gRmFsbHMgZGFzIE9iamVrdCBzaWNoIHZlcmVpbmlndCBoYXQsIG11c3MgamV0enQgd2llZGVyIFVfUkVRCisgICAgLy8gcmVzdGF1cmllcnQgd2VyZGVuLgorICAgIG9iLT5TZXRQcm9wKFVfUkVRLCB1X3JlcSk7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJEdSBrYXVmc3QgIitvYi0+bmFtZShXRU4sMSkrIi4iLCA3OCkpOworICB9CisKKyAgc2F5KGJyZWFrX3N0cmluZyhQTC0+TmFtZShXRVIpKyIga2F1ZnQgIitvYi0+bmFtZShXRU4pKyIuIiw3OCksICh7UEx9KSk7CisgIFVwZGF0ZUNvdW50ZXIob2IsLTEpOworfQorCitzdGF0aWMgdm9pZCBhc2tfYnV5KHN0cmluZyBzdHIsIGludCB2YWwsIG9iamVjdCBwbCwgb2JqZWN0IG9iLCBpbnQgdV9yZXEpCit7CisgIF9ub3RpZnlfZmFpbChicmVha19zdHJpbmcoIkd1dCwgRHUga2FubnN0IGVzIERpciBqYSBqZWRlcnplaXQgIgorICAgIm5vY2ggYW5kZXJzIHVlYmVybGVnZW4uIiw3OCxOYW1lKFdFUikrIiBzYWd0OiAiKSk7CisKKyAgaWYoIXN0ciB8fCAhc3RyaW5ncChzdHIpIHx8IHN0ciA9PSAibmVpbiIgfHwgc3RyID09ICJuIikKKyAgeworICAgIHJldHVybjsKKyAgfQorICBpZihzdHIgIT0gImphIiAmJiBzdHIgIT0gImoiKQorICB7CisgICAgcmV0dXJuOworICB9CisgIHJlYWxseV9idXkodmFsLCBwbCwgb2IsIHVfcmVxKTsKK30KKworc3RhdGljIGludCBidXkoc3RyaW5nIHN0cikKK3sKKyAgaW50IGksIHZhbCwgcGFyLCBkZXg7CisgIG1peGVkIG9iLCByZXM7CisgIHN0cmluZyBkdW1teTsKKworICBpZiAoIXN0cikgeworICAgIHdyaXRlKCJXYXMgd2lsbHN0IER1IGthdWZlbj9cbiIpOworICAgIHJldHVybiAxOworICB9CisKKyAgaWYgKHN0cmluZ3AoUXVlcnlQcm9wKFBfS0VFUEVSKSkgJiYgIXByZXNlbnQoUXVlcnlQcm9wKFBfS0VFUEVSKSwgTUUpKSB7CisgICAgd3JpdGUoIkVzIGlzdCBuaWVtYW5kIGRhLCBkZXIgRGljaCBiZWRpZW5lbiBrb2VubnRlLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBfbm90aWZ5X2ZhaWwoYnJlYWtfc3RyaW5nKCJEYXMga2FubiBpY2ggaW4gbWVpbmVtIExhZ2VyIG5pY2h0IGZpbmRlbi4iLDc4LAorICAgTmFtZShXRVIpKyIgc2FndDogIikpOworCisgIC8vIFVtIGF1Y2ggVGVpbGUgdm9uIFVuaXQtU3RhY2tzIGthdWZlbiB6dSBrb2VubmVuLCB6LkIuICJrYXVmZSA1IHBoaW9sZW4iLAorICAvLyBkYXJmIGhpZXIgenVzYWV0emxpY2ggPGR1bW15PiBudXIgZWluIExlZXJzdHJpbmcgc2Vpbiwgc29uc3QgdmVyendlaWd0CisgIC8vIGRpZSBTeW50YXhwcnVlZnVuZyBoaWVyaGluIHVuZCBlcyB3aXJkIGRhcyA1LiBJdGVtIGRlciBMaXN0ZSBnZWthdWZ0LgorICBpZiAoc3NjYW5mKHN0ciwiJWQlcyIsaSxkdW1teSk+MCAmJiBpPjAgJiYgIXNpemVvZihkdW1teSkpIHsKKyAgICBvYj1GaW5kSW5TdG9yZShpKTsKKyAgfQorICBlbHNlIG9iPUZpbmRJblN0b3JlKHN0cik7CisKKyAgaWYgKCFvYikgcmV0dXJuIDA7CisKKyAgaWYgKHN0ciA9IGJ1eV9vYmoob2IsMCkpIAorICB7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKHN0ciw3OCxOYW1lKFdFUikrIiBzYWd0OiAiKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICB2YWwgPSBRdWVyeUJ1eVZhbHVlKG9iLFBMKTsKKworICBpZiAoUEwtPlF1ZXJ5TW9uZXkoKSA8IHZhbCkKKyAgeworICAgIHdyaXRlKGJyZWFrX3N0cmluZyhjYXBpdGFsaXplKG9iLT5RdWVyeVByb25vdW4oV0VSKSkrIiB3dWVyZGUgIit2YWwrCisgICAgICIgTXVlbnplbiBrb3N0ZW4sIHVuZCBEdSBoYXN0IG51ciAiK1BMLT5RdWVyeU1vbmV5KCkrIi4iLDc4LAorICAgICBOYW1lKFdFUikrIiBiZWRhdWVydDogIikpOworICAgIHJldHVybiAxOworICB9CisKKyAgLy8gQW56YWhsIGRlciBhbmdlZm9yZGVydGVuIEVpbmhlaXRlbiB2b3IgZGVtIEJld2VnZW4gendpc2NoZW5zcGVpY2hlcm4uCisgIC8vIFdlaWwgZGFiZWkgaW0gRmFsbCB2b24gVW5pdHMgZWluZSBWZXJlaW5pZ3VuZyBtaXQgYmVyZWl0cyBpbSBJbnZlbnRhcgorICAvLyBiZWZpbmRsaWNoZW4gRWluaGVpdGVuIHN0YXR0ZmluZGV0LCBtdXNzIGRhcyBnZ2YuIG5hY2ggQmV3ZWdlbgorICAvLyB6dXJ1ZWNrZ2VzZXR6dCB3ZXJkZW4uCisgIGludCB1X3JlcSA9IG9iLT5RdWVyeVByb3AoVV9SRVEpOworCisgIGlmICgocmVzID0gb2ItPlF1ZXJ5UHJvcChQX1JFU1RSSUNUSU9OUykpICYmIG1hcHBpbmdwKHJlcykgJiYKKyAgICAgIChyZXMgPSBjYWxsX290aGVyKCIvc3RkL3Jlc3RyaWN0aW9uX2NoZWNrZXIiLAorICAgICAgICAgICAgICAgICAgICAgICAgImNoZWNrX3Jlc3RyaWN0aW9ucyIsUEwscmVzKSkgJiYKKyAgICAgIHN0cmluZ3AocmVzKSkKKyAgeworICAgIF9ub3RpZnlfZmFpbChicmVha19zdHJpbmcoIkR1IGtvZW5udGVzdCAiK29iLT5uYW1lKFdFTiwyKSsiIG5pY2h0ICIKKyAgICAgInZlcndlbmRlbi4gR3J1bmQ6ICIrcmVzKyJNb2VjaHRlc3QgRHUgIitvYi0+UXVlcnlQcm9ub3VuKFdFTikrCisgICAgICIgZGVubm9jaCBrYXVmZW4/Iiw3OCxOYW1lKFdFUikrIiBzYWd0OiAiKSk7CisKKyAgICBpbnB1dF90bygiYXNrX2J1eSIsSU5QVVRfUFJPTVBULCAiKGphL25laW4pICIsIHZhbCxQTCxvYix1X3JlcSk7CisgICAgcmV0dXJuIDA7CisgIH0KKworICBwYXIgPSAoaW50KW9iLT5RdWVyeVByb3AoUF9QQVJSWSk7CisgIGRleCA9IChpbnQpUEwtPlF1ZXJ5QXR0cmlidXRlKEFfREVYKTsKKworICBpZiAoKCgocGFyIDwgUEFSUllfT05MWSkgJiYgKChkZXggKyA4KSAqIDEwKSA8IG9iLT5RdWVyeVByb3AoUF9XQykpIHx8CisgICAgICAgKChwYXIgPiBQQVJSWV9OT1QpICAmJiAoKGRleCArIDUpICogIDIpIDwgb2ItPlF1ZXJ5UHJvcChQX0FDKSkpICYmCisgICAgICBWQUxJRF9XRUFQT05fVFlQRShvYikpCisgIHsKKyAgICBfbm90aWZ5X2ZhaWwoYnJlYWtfc3RyaW5nKCJEdSBrb2VubnRlc3QgIitvYi0+bmFtZShXRU4sMikrIiBuaWNodCAiCisgICAgICJ6dWVja2VuLCBkYSBEZWluZSBHZXNjaGlja2xpY2hrZWl0IGRhZnVlciBuaWNodCBhdXNyZWljaHQuIE1vZWNodGVzdCAiCisgICAgICJEdSAiK29iLT5RdWVyeVByb25vdW4oV0VOKSsiIGRlbm5vY2gga2F1ZmVuPyIsNzgsCisgICAgIE5hbWUoV0VSKSsiIHNhZ3Q6ICIpKTsKKworICAgIGlucHV0X3RvKCJhc2tfYnV5IixJTlBVVF9QUk9NUFQsICIoamEvbmVpbikgIiwgdmFsLFBMLG9iLHVfcmVxKTsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIHJlYWxseV9idXkodmFsLCBQTCwgb2IsIHVfcmVxKTsKKworICByZXR1cm4gMTsKK30KKworcHJpdmF0ZSB2b2lkIGdpdmVfbW9uZXkoaW50IHZhbHVlKQorLy8gR2VsZCBndXRzY2hyZWliZW4uLi4KK3sKKyAgaWYgKCF2YWx1ZSkgcmV0dXJuOworICB3cml0ZShicmVha19zdHJpbmcoTmFtZShXRVIsIDEpKyIgemFobHQgRGlyICIrdmFsdWUrIiBHb2xkc3R1ZWNrIgorICAgICAgICAgICAgICAgICAgICArKHZhbHVlPT0xPyIuIjoiZS4iKSwgNzgpKTsKKyAgaWYgKChQTC0+QWRkTW9uZXkodmFsdWUpKTw9MCkgeworICAgICBvYmplY3QgbW9uOworCisgICAgIHdyaXRlKCJEdSBrYW5uc3QgZGFzIEdlbGQgbmljaHQgbWVociB0cmFnZW4hXG4iKTsKKyAgICAgbW9uPWNsb25lX29iamVjdChHRUxEKTsKKyAgICAgbW9uLT5TZXRQcm9wKFBfQU1PVU5ULHZhbHVlKTsKKyAgICAgbW9uLT5tb3ZlKE1FLE1fTU9WRV9BTEx8TV9OT0NIRUNLKTsKKyAgfQorfQorCitzdGF0aWMgaW50IG1ha2VfdG9fbW9uZXkob2JqZWN0IG9iLCBpbnQgdmFsdWUpCisvLyBJbnRlcm5lIEZ1bmt0aW9uLCBkaWUgb2IgdmVyc3VjaHQgaW4gZGFzIExhZ2VyIHp1IHVlYmVyZnVlaHJlbiB1bmQgZGFzCisvLyBHZWxkIGRhcyBkYWJlaSBmdWVyIGRlbiBTcGllbGVyIGFiZmFlbGx0IHp1cnVlY2tsaWVmZXJ0LgoreworICBzdHJpbmcgc3RyOworICBpbnQgcmV0OworCisgIGlmICghb2JqZWN0cChvYikgfHwgZW52aXJvbm1lbnQob2IpPT1maW5kX29iamVjdChzdG9yYWdlKSkgeworICAgIHdyaXRlKGJyZWFrX3N0cmluZyhOYW1lKFdFUiwgMSkrIiB3dW5kZXJ0IHNpY2ggdWViZXIgRGljaC4iLCA3OCkpOworICAgIHJldHVybiAwOworICB9CisgIGlmICh2YWx1ZT5RdWVyeVByb3AoUF9DVVJSRU5UX01PTkVZKSkgeworICAgIHdyaXRlKGJyZWFrX3N0cmluZygiSWNoIGhhYiBkYXMgR2VsZCBsZWlkZXIgbmljaHQgbWVoci4iLCA3OCwKKyAgICAgICAgICAgICAgICAgICAgICAgTmFtZShXRVIsIDEpKyIgc2FndDogIikpOworICAgIHJldHVybiAwOworICB9CisgIC8vIFVfUkVRIG1lcmtlbiwgZmFsbHMgc2ljaCBPYmpla3RlIHZlcmVpbmlnZW4uIFNvbnN0IHN0aW1tdCBuaWNodCBudXIgZGVyCisgIC8vIE5hbWUsIHNvbmRlcm4gZXMgd2VyZGVuIGdnZi4gYXVjaCBkaWUgZmFsc2NoZSBBbnphaGwgemVyc3RvZXJ0LgorICAvL1RPT086IE9kZXIgVW5pdHMgZW50c29yZ2VuIHVuZCBhbHMgRmVhdHVyZSBkZWtsYXJpZXJlbj8KKyAgaW50IHJlcSA9IG9iLT5RdWVyeVByb3AoVV9SRVEpOworICBpZiAoQ2hlY2tGb3JEZXN0cnVjdChvYikgPiAwKSAgLy8gc29sbCBvYiB6ZXJzdG9lcnQgd2VyZGVuPworICB7CisgICAgcmV0ID0gb2ItPm1vdmUoc3RvcmFnZSxNX1BVVHxNX0dFVCk7CisgICAgLy8gRmFsbHMgZGFzIE9iamVrdCBzaWNoIHZlcmVpbmlndCBoYXQgKFVuaXRzKSwgbXVlc3NlbiBkaWUgZ2V3dWVuc2NodGVuCisgICAgLy8gRWluaGVpdGVuIHJlc3RhdXJpZXJ0IHdlcmRlbi4KKyAgICAvLyBQcm9ibGVtOiBmYWxscyBkYXMgdmVya2F1ZnRlIE9iamVrdCBVbml0cyBoYXQsIGJlc2NoYWVkaWd0IGlzdCB1bmQgc2ljaAorICAgIC8vIHZlcmVpbmlndCBoYXQsIHNpbmQgamV0enQgbGVpZGVyIGFsbGUgRWluaGVpdGVuIGltIExhZ2VyIGJlc2NoYWVkaWd0LgorICAgIC8vIERhcyBpc3QgdW5zY2hvZW4gLSBhYmVyIG1pciBqZXR6dCB6dXZpZWwgQVVmd2FuZCwgZGFzIGtvcnJla3QgenUgYmF1ZW4sCisgICAgLy8gd2VpbCBlcyBudXIgc2VociBzZWx0ZW4gdm9ya29tbXQuIChIaW50OiBzZXBhcmF0ZXIgTXVlbGxyYXVtKQorICAgIG9iLT5TZXRQcm9wKFVfUkVRLCByZXEpOworICAgIGlmIChyZXQgPiAwKSAvLyBTb25zdCB3ZXJkZW4gYXVjaCBTYWNoZW4gemVyc3RvZXJ0LCBkaWUgbWFuIG5pY2h0CisgICAgeyAgICAgICAgICAgICAgICAgLy8gd2VnbGVnZW4ga2FubgorICAgICAgc2F5KGJyZWFrX3N0cmluZyhQTC0+TmFtZSgpKyIgdmVya2F1ZnQgIitvYi0+bmFtZShXRU4pKyIuIiwgNzgpKTsKKyAgICAgIGlmKG9iLT5RdWVyeVByb3AoUF9EQU1BR0VEKSkgIC8vIEFuZGVyZSBNZWxkdW5nIGJlaSBiZXNjaGFlZGlndGVuCisgICAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBPYmpla3RlbiAuLi4KKyAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKE5hbWUoV0VSLDEpKyIgZmluZGV0IHp3YXIga2VpbmVuIEdlZmFsbGVuIGFuICIKKyAgICAgICAgICtvYi0+bmFtZShXRU0sMSkrIiwgbmltbXQgIitvYi0+UXVlcnlQcm9ub3VuKFdFTikrIiBEaXIgenVsaWViZSAiCisgICAgICAgICAiYWJlciB0cm90emRlbS4iLDc4KSk7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhOYW1lKFdFUiwgMSkrIiBmaW5kZXQgR2VmYWxsZW4gYW4gIgorICAgICAgICAgICArb2ItPm5hbWUoV0VNLCAxKSArICIgdW5kIGxlZ3QgIitvYi0+UXVlcnlQcm9ub3VuKFdFTikKKyAgICAgICAgICAgKyIgenUgIisoUXVlcnlQcm9wKFBfR0VOREVSKT09RkVNQUxFPyJpaHJlbiI6InNlaW5lbiIpCisgICAgICAgICAgICsiIFByaXZhdHNhY2hlbi4iLCA3OCkpOworICAgICAgfQorICAgICAgLyogRXIgemFobHQgRGlyICIrdmFsdWUrIiBNdWVuemUiKyh2YWx1ZT09MT8iIjoibiIpKyIgZGFmdWVyLiIsIDc4KSk7ICovCisgICAgICBfYWRkX21vbmV5KC12YWx1ZSk7CisgICAgICBfYWRkX21vbmV5KHZhbHVlKlF1ZXJ5UHJvcChQX1NIT1BfUEVSQ0VOVF9MRUZUKS8xMDApOyAvLyBXZWdlbiBaZXJzdG9lcnVuZyBkZXMgT2JqZWt0ZXMKKyAgICAgIFVwZGF0ZUNvdW50ZXIob2IsMSk7CisgICAgICBvYi0+cmVtb3ZlKDEpOworICAgICAgcmV0dXJuIHZhbHVlOworICAgIH0KKyAgICBlbHNlIGlmIChyZXQgPT0gTUVfQ0FOVF9CRV9EUk9QUEVEKSB7CisgICAgICBpZiAoKHN0cj1vYi0+UXVlcnlQcm9wKFBfTk9EUk9QKSkgJiYgc3RyaW5ncChzdHIpKSB7CisgICAgICAgIHdyaXRlKHN0cik7CisgICAgICAgIHJldHVybiAwOworICAgICAgfQorICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJEdSBrYW5uc3QgIitvYi0+bmFtZShXRU4sMSkrIiBuaWNodCB2ZXJrYXVmZW4hIiwgNzgpKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBlbHNlCisgICAgICB3cml0ZShicmVha19zdHJpbmcob2ItPk5hbWUoV0VSKSsiIGludGVyZXNzaWVydCBtaWNoIG5pY2h0LiIsIDc4LAorICAgICAgICAgICAgICAgTmFtZShXRVIsIDEpKyIgc2FndDogIikpOworICB9CisgIGVsc2UgaWYgKChyZXQ9KG9iLT5tb3ZlKHN0b3JhZ2UsTV9QVVR8TV9HRVQpKSk+MCkKKyAgeworICAgIC8vIEZhbGxzIGRhcyBPYmpla3Qgc2ljaCB2ZXJlaW5pZ3QgaGF0IChVbml0cyksIG11ZXNzZW4gZGllIGdld3VlbnNjaHRlbgorICAgIC8vIEVpbmhlaXRlbiByZXN0YXVyaWVydCB3ZXJkZW4uCisgICAgb2ItPlNldFByb3AoVV9SRVEsIHJlcSk7CisgICAgc2F5KGJyZWFrX3N0cmluZyhQTC0+TmFtZShXRVIpKyIgdmVya2F1ZnQgIitvYi0+bmFtZShXRU4pKyIuIiwgNzgpKTsKKyAgICBfYWRkX21vbmV5KC12YWx1ZSk7CisgICAgVXBkYXRlQ291bnRlcihvYiwxKTsKKyAgICByZXR1cm4gdmFsdWU7CisgIH0KKyAgZWxzZSBpZiAocmV0ID09IE1FX0NBTlRfQkVfRFJPUFBFRCkgeworICAgIGlmICgoc3RyPW9iLT5RdWVyeVByb3AoUF9OT0RST1ApKSAmJiBzdHJpbmdwKHN0cikpCisgICAgICAgd3JpdGUoc3RyKTsKKyAgICBlbHNlIHdyaXRlKGJyZWFrX3N0cmluZygiRHUga2FubnN0ICIrb2ItPm5hbWUoV0VOLDEpKyIgbmljaHQgdmVya2F1ZmVuISIsIDc4KSk7CisgIH0KKyAgZWxzZSB3cml0ZShicmVha19zdHJpbmcoIkR1IGthbm5zdCAiK29iLT5uYW1lKFdFTiwxKSsiIG5pY2h0IHZlcmthdWZlbiEiLCA3OCkpOworICByZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQgYXNrX3NlbGwoc3RyaW5nIHN0ciwgb2JqZWN0IG9iLCBpbnQgdmFsLCBpbnQgdV9yZXEpCisvLyBXZW5uIGVpbiBlaW56ZWxuZW4gU3R1ZWNrIHVudGVyIFdlcnQgdmVya2F1ZnQgd2VyZGVuIHNvbGwsIHdpcmQgbmFjaGdlZnJhZ3QKKy8vIHVfcmVxIGlzdCBiZWkgVW5pdG9iamVrdGVuIGRpZSBBbnphaGwgYW4genUgdmVya2F1ZmVuZGVuIEVpbmhlaXRlbi4gQmVpCisvLyBub3JtYWxlbiBPYmpla3RlbiBpc3QgdV9yZXEgMC4KK3sKKyAgc3RyPWxvd2VyX2Nhc2Uoc3RyfHwiIik7CisgIGlmIChzdHI9PSJqYSJ8fHN0cj09ImoiKQorICB7CisgICAgIC8vIEluIFVuaXRvYmpla3RlbiBVX1JFUSAod2llZGVyKSBzZXR6ZW4uCisgICAgIGlmICh1X3JlcT4wKQorICAgICB7CisgICAgICAgLy8gRGFzIFF1ZXJ5UHJvcCgpIGlzdCBuaWNodCB1bm5vZXRpZy4gQmVpIGRlciBBYmZyYWdlIHZvbiBVX1JFUSB3aXJkCisgICAgICAgLy8gVV9SRVEgZ2VudWxsdCwgd2VubiBkYXMgYWt0dWVsbGUgcXVlcnlfdmVyYigpICE9IGRlbSBsZXR6dGVuIGlzdC4KKyAgICAgICAvLyBCZWkgZGVyIGVyc3RlbiBBYmZyYWdlIHd1ZXJkZSBhbHMgZGFzIGhpZXIgZ2VzZXR6dCBVX1JFUSB3aWVkZXIKKyAgICAgICAvLyBnZWxvZXNjaHQuIERhaGVyIG11c3MgZGFzIGpldHp0IGhpZXIgYWxzIGVyc3RlcyBlaW5tYWwgYWJnZWZyYWd0CisgICAgICAgLy8gd2VyZGVuLi4uCisgICAgICAgICBvYi0+UXVlcnlQcm9wKFVfUkVRKTsKKyAgICAgICAgIG9iLT5TZXRQcm9wKFVfUkVRLCB1X3JlcSk7CisgICAgIH0KKyAgICAgZ2l2ZV9tb25leShtYWtlX3RvX21vbmV5KG9iLHZhbCkpOworICB9CisgIGVsc2UKKyAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJPaywgZGFubiBiZWhhbHRzISIsIDc4LAorICAgICAgICAgICAgIE5hbWUoV0VSLCAxKSsiIHNhZ3Q6ICIpKTsKK30KKworc3RhdGljIHN0cmluZyBzZWxsX29iaihvYmplY3Qgb2IsIGludCBzaG9ydCkKKy8vIElzdCBkZXIgSGFlbmRsZXIgYmVyZWl0IG9iIHp1IGthdWZlbj8gd2VubiBuZWluLCBSdWVja2dhYmUgZWluZXIgTWVsZHVuZywKKy8vIGRpZSBkZXIgSGFlbmRsZXIgc2FnZW4gc29sbC4KK3sgIG1peGVkIG5vc2VsbDsKKworICAgaWYgKEJMVUVfTkFNRShvYik9PUdFTEQpCisgICAgICByZXR1cm4gIkRhcyB3YWVyZSBqYSB3b2hsIFVuc2lubiwgb2RlciAuLi4/IjsKKyAgIGlmIChub3NlbGw9b2ItPlF1ZXJ5UHJvcChQX05PU0VMTCkpCisgICB7CisgICAgIGlmIChzdHJpbmdwKG5vc2VsbCkpCisgICAgICAgcmV0dXJuIG5vc2VsbDsKKyAgICAgcmV0dXJuICgiRHUga2FubnN0ICIrb2ItPm5hbWUoV0VOLDEpKyIgbmljaHQgdmVya2F1ZmVuISIpOworICAgfQorICAgaWYgKG9iLT5RdWVyeVByb3AoUF9DVVJTRUQpKQorICAgICByZXR1cm4gb2ItPk5hbWUoV0VSLDEpCisgICAgICAgICArIiBpc3QgbWlyIGlyZ2VuZHdpZSB1bmdlaGV1ZXIhIERhcyBrYW5uc3QgRHUgbmljaHQgdmVya2F1ZmVuISI7CisgICAvLyBtYW4gc29sbHRlIGtlaW5lIENPbnRhaW5lciBtaXQgSW5oYWx0IHZlcmthdWZlbiBrb2VubmVuLCBnZ2YuIGthdWZ0IHNpZQorICAgLy8gZGFubiBlaW4gYW5kZXJlciBTcGllbGVyLgorICAgaWYgKGZpcnN0X2ludmVudG9yeShvYikpCisgICB7CisgICAgIHJldHVybiBvYi0+TmFtZShXRVIsIDEpICsgIiBpc3QgbmljaHQgbGVlciEiOworICAgfQorICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2YXJhcmdzIGludCBzZWxsKHN0cmluZyBzdHIsIGludCBmKQoreworICBpbnQgaSwgdmFsLCBvdmFsLCB0bXA7CisgIG9iamVjdCAqb2JzOworCisgIGlmIChzdHJpbmdwKFF1ZXJ5UHJvcChQX0tFRVBFUikpICYmICFwcmVzZW50KFF1ZXJ5UHJvcChQX0tFRVBFUiksTUUpKSB7CisgICAgIHdyaXRlKCJFcyBpc3QgbmllbWFuZCBkYSwgZGVyIERpY2ggYmVkaWVuZW4ga29lbm50ZS5cbiIpOworICAgICByZXR1cm4gMTsKKyAgfQorICAKKyAgaWYgKCFzdHIpIHsKKyAgICAgbm90aWZ5X2ZhaWwoIldhcyBtb2VjaHRlc3QgRHUgZGVubiB2ZXJrYXVmZW4/XG4iKTsKKyAgICAgcmV0dXJuIDA7CisgIH0KKyAgCisgIC8qIEVyZ2VibmlzIHZvbiBmaW5kX29icygpIHNvbGx0ZSB1bmlmaXppZXJ0IHdlcmRlbiwgZGFtaXQgZWluIG1laHJmYWNoCisgICAgIGdlZnVuZGVuZXMgT2JqZWt0IG5pY2h0IG1laHJmYWNoIHZlcnN1Y2h0IHdpcmQgenUgdmVya2F1ZmVuLgorICAgICBCZWlzcGllbDogT2JqZWt0IGhhdCBQX05PQlVZIGdlc2V0enQgdW5kIG1laHJlcmUgSURzIGdlc2V0enQuIFdlbm4KKyAgICAgZWluIFNwaWVsZXIgZXMgbWl0ICJ2ZXJrYXVmZSBJRDEgdW5kIElEMiIgdmVyc3VjaHQgenUgdmVya2F1ZmVuLAorICAgICB3dWVyZGUgZGFzIGVpbmVuIEJ1ZyBhdXNsb2VzZW4uIERlcnNlbGJlIEJ1ZyBlbnRzdGVodCwgd2VubiBtYW4gbWl0CisgICAgICJ2ZXJrYXVmZSBJRDEgdW5kIElEMSIgdmVya2F1ZnQuICovCisgIG9icyA9IFBMLT5maW5kX29icyhzdHIsIFBVVF9HRVRfRFJPUCk7CisgIC8qIEVyc3QgaW0gSW52ZW50YXIgc2NoYXVlbiwgZGFubiBpbSBFbnZpcm9ubWVudC4gZmluZF9vYnMoKSBvaG5lIDIuCisgICAgIFBhcmFtZXRlciBtYWNodCBkYXMgc3RhbmRhcmRtYWVzc2lnIGFuZGVyc2hlcnVtLgorICAgICBUT0RPOiBBZW5kZXJ1bmcgdWViZXJwcnVlZmVuLCBzb2JhbGQgZGFzIG5ldWUgcHV0X2FuZF9nZXQuYyAKKyAgICAgZWluZ2ViYXV0IHd1cmRlLiAqLworICBpZiAoICFzaXplb2Yob2JzKSApCisgICAgb2JzID0gUEwtPmZpbmRfb2JzKHN0ciwgUFVUX0dFVF9UQUtFKSB8fCAoe30pOworICBvYnMgPSBtX2luZGljZXMobWttYXBwaW5nKG9icykpOworICBpZiAoIWk9c2l6ZW9mKG9icykpIHsKKyAgICAgbm90aWZ5X2ZhaWwoIldhcyBtb2VjaHRlc3QgRHUgZGVubiB2ZXJrYXVmZW4/XG4iKTsKKyAgICAgcmV0dXJuIDA7CisgIH0KKyAgY2FsbF9vdGhlcihzdG9yYWdlLCAiX3JlZ2lzdGVyX3Nob3AiLCBNRSk7CisgIGlmIChpPT0xKSB7CisgICAgIGlmIChzdHI9c2VsbF9vYmoob2JzWzBdLCAwKSkgeworICAgICAgICB3cml0ZShicmVha19zdHJpbmcoc3RyLCA3OCwgTmFtZShXRVIsIDEpKyIgc2FndDogIikpOworICAgICAgICByZXR1cm4gMTsKKyAgICAgfQorICAgICBpZiAoKG92YWw9b2JzWzBdLT5RdWVyeVByb3AoUF9WQUxVRSkpPD0wKSB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhvYnNbMF0tPk5hbWUoV0VSKQorICAgICAgICAgICAgICArKG9ic1swXS0+UXVlcnlQcm9wKFBfUExVUkFMKSA/ICIgaGFiZW4iIDogIiBoYXQiKQorICAgICAgICAgICAgICArIiBrZWluZW4gbWF0ZXJpZWxsZW4gV2VydCwgdHV0IG1pciBsZWlkLiIsIDc4LAorICAgICAgICAgICAgICBOYW1lKFdFUiwgMSkrIiBzYWd0OiAiKSk7CisgICAgICAgIHJldHVybiAxOworICAgICB9CisgICAgIHZhbD1RdWVyeVNlbGxWYWx1ZShvYnNbMF0sIFBMKTsKKyAgICAgaWYgKCF2YWwpIHsKKyAgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJJY2ggYmluIGFic29sdXQgcGxlaXRlLiBUdXQgbWlyIGF1ZnJpY2h0aWcgbGVpZC4iLAorICAgICAgICAgICAgICA3OCwgTmFtZShXRVIsIDEpKyIgc2FndDogIikpOworICAgICAgICByZXR1cm4gMTsKKyAgICAgfQorICAgICBpZiAodmFsPT1vdmFsIHx8IGYpIHsKKyAgICAgICAgZ2l2ZV9tb25leShtYWtlX3RvX21vbmV5KG9ic1swXSwgdmFsKSk7CisgICAgICAgIHJldHVybiAxOworICAgICB9CisgICAgIGlmIChzdHI9b2JzWzBdLT5RdWVyeVByb3AoUF9OT0RST1ApKSB7CisgICAgICAgIGlmIChzdHJpbmdwKHN0cikpCisgICAgICAgICAgIHdyaXRlKHN0cik7CisgICAgICAgIGVsc2Ugd3JpdGUoYnJlYWtfc3RyaW5nKCJEdSBrYW5uc3QgIitvYnNbMF0tPm5hbWUoV0VOLDEpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyIgbmljaHQgdmVya2F1ZmVuISIsIDc4KSk7CisgICAgICAgIHJldHVybiAxOworICAgICB9CisKKyAgICAgaWYgKG9ic1swXS0+UXVlcnlQcm9wKFBfREFNQUdFRCkpICAvLyBCZWkgYmVzY2hhZWRpZ3RlbiBPYmpla3RlbiBnaWJ0CisgICAgIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZXMgYXVjaCBoaWVyIGVpbmUgYW5kZXJlIE1lbGR1bmcKKyAgICAgICB3cml0ZShicmVha19zdHJpbmcoIkRhICIrb2JzWzBdLT5uYW1lKFdFUikrIiBiZXNjaGFlZGlndCAiCisgICAgICAgICsob2JzWzBdLT5RdWVyeVByb3AoUF9QTFVSQUwpPyJzaW5kIjoiaXN0IikrIiwga2FubiBpY2ggRGlyICIKKyAgICAgICAgIm51ciAiK3ZhbCsiIE11ZW56ZSIrKHZhbCA9PSAxPyIiOiJuIikrIiBkYWZ1ZXIgYmlldGVuLiBVbmQgIgorICAgICAgICAiZGFtaXQgbWFjaGUgaWNoIG5vY2ggVmVybHVzdCEgTmltbXN0IER1IG1laW4gQW5nZWJvdCBhbj8gIgorICAgICAgICAiKGphL25laW4pIiw3OCxOYW1lKFdFUiwxKSsiIHNhZ3Q6ICIpKTsKKyAgICAgfQorICAgICBlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRGVmYXVsdAorICAgICB7CisgICAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKE5hbWUoV0VSLCAxKSsiIHNhZ3Q6ICIKKyAgICAgICAgICArIk5hY2ggZGVyIGFrdHVlbGxlbiBNYXJrdGxhZ2Uga2FubiBpY2ggRGlyIGRhZnVlciBudXIgIgorICAgICAgICAgICt2YWwrIiBNdWVuemUiKyh2YWw9PTE/IiI6Im4iKSsiIGJpZXRlbiwgb2J3b2hsICIKKyAgICAgICAgICArb2JzWzBdLT5uYW1lKFdFUikrIiBlaWdlbnRsaWNoICIrb3ZhbCsiIE11ZW56ZSIKKyAgICAgICAgICArKG92YWw9PTE/IiI6Im4iKSsiIHdlcnQgd2FlcmUuIFdpbGxzdCBEdSAiCisgICAgICAgICAgKyhRdWVyeVByb3AoUF9QTFVSQUwpID8gInNpZSIgOiAiZXMiKQorICAgICAgICAgICsiIG1pciBkYWZ1ZXIgdWViZXJsYXNzZW4/IiwgNzgpKTsKKyAgICAgfQorICAgICAvLyBpbiBhc2tfc2VsbCgpIGdpYnQgZXMgZGFzIHF1ZXJ5X3ZlcmIoKSBuaWNodCBtZWhyLCB3ZXN3ZWdlbiBVX1JFUSBpbgorICAgICAvLyBVbml0b2JqZWt0ZW4genVydWVja2dlc2V0enQgd2lyZC4gRGFtaXQgZ2VodCBkaWUgaW5mbyB2ZXJsb3JlbiwKKyAgICAgLy8gd2lldmllbGUgT2JqZWt0ZSBkZXIgU3BpZWxlciBhbmdlZ2ViZW4gaGF0LiBEaWVzZSBtdXNzIGdlcmV0dGV0IHVuZAorICAgICAvLyB2aWEgYXNrX3NlbGwoKSBpbiBtYWtlX3RvX21vbmV5KCkgYW5rb21tZW4uIEluIG5vcm1hbGVuIE9iamVrdGVuIGlzdAorICAgICAvLyBVX1JFUSAwLgorICAgICBpbnB1dF90bygiYXNrX3NlbGwiLElOUFVUX1BST01QVCwgIihqYS9uZWluKSAiLG9ic1swXSwgdmFsLAorICAgICAgICAgICAgICAob2JzWzBdKS0+UXVlcnlQcm9wKFVfUkVRKSApOworICAgICByZXR1cm4gMTsKKyAgfQorICBmb3IgKC0taTsgaT49MCAmJiBnZXRfZXZhbF9jb3N0KCk+NTAwMDA7IGktLSkgeworICAgICBpZiAob3ZhbD1vYnNbaV0tPlF1ZXJ5UHJvcChQX1ZBTFVFKSkgeworICAgICAgICBpZiAob2JzW2ldLT5RdWVyeVByb3AoUF9LRUVQX09OX1NFTEwpPT1nZXR1aWQoUEwpCisgICAgICAgICAgICB8fCBvYnNbaV0tPlF1ZXJ5UHJvcChQX1dPUk4pIHx8IG9ic1tpXS0+UXVlcnlQcm9wKFBfV0lFTERFRCkpCisgICAgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhvYnNbaV0tPk5hbWUoV0VSKSsiOiBEdSBiZWhhZWx0c3QgIgorICAgICAgICAgICAgICAgICtvYnNbaV0tPm5hbWUoV0VOKSsiLiIsIDc4KSk7CisgICAgICAgIGVsc2UgaWYgKHN0cj1zZWxsX29iaihvYnNbaV0sIDEpKQorICAgICAgICAgICB3cml0ZShicmVha19zdHJpbmcob2JzW2ldLT5OYW1lKFdFUikrIjogIitzdHIsIDc4KSk7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICB0bXA9UXVlcnlTZWxsVmFsdWUob2JzW2ldLCBQTCk7CisgICAgICAgICAgIGlmICghdG1wKSB7CisgICAgICAgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygKKyAgICAgICAgICAgICAgICAgICAgIkljaCBiaW4gYWJzb2x1dCBwbGVpdGUuIFR1dCBtaXIgYXVmcmljaHRpZyBsZWlkLiIsIDc4LAorICAgICAgICAgICAgICAgICAgICBOYW1lKFdFUiwgMSkrIiBzYWd0OiAiKSk7CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICB9CisgICAgICAgICAgIGVsc2UgaWYgKCFmICYmIHRtcCoxMDxvdmFsKQorICAgICAgICAgICAgICB3cml0ZShicmVha19zdHJpbmcob2JzW2ldLT5OYW1lKFdFUikrIjogIitOYW1lKFdFUiwgMSkKKyAgICAgICAgICAgICAgICAgICAgKyIgYmlldGV0IERpciBhYmVyIG51ciAiK3RtcCsiIEdvbGRzdHVlY2siCisgICAgICAgICAgICAgICAgICAgICsodG1wPjEgPyAiZSIgOiAiIikrIiBkYWZ1ZXIuIiwgNzgpKTsKKyAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgIHN0cj0ob2JzW2ldLT5OYW1lKFdFUikpOworICAgICAgICAgICAgICBpZiAodG1wPW1ha2VfdG9fbW9uZXkob2JzW2ldLCB0bXApKSB7CisgICAgICAgICAgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZyhzdHIrIjogIitOYW1lKFdFUiwgMSkKKyAgICAgICAgICAgICAgICAgICAgICArIiBnaWJ0IERpciBkYWZ1ZXIgIit0bXArIiBHb2xkc3R1ZWNrIgorICAgICAgICAgICAgICAgICAgICAgICsodG1wPT0xPyIuIjoiZS4iKSwgNzgpKTsKKyAgICAgICAgICAgICAgICAgdmFsKz10bXA7CisgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgfQorICAgICAgICB9CisgICAgIH0KKyAgfQorICBpZiAoIXZhbCkKKyAgICAgd3JpdGUoYnJlYWtfc3RyaW5nKCJIbW1tLCBEdSBoYXN0IGFiZXIgbmljaHQgYmVzb25kZXJzIHZpZWwgenUgYmlldGVuLi4uIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIDc4LCBOYW1lKFdFUikrIiBzYWd0OiAiKSk7CisgIGVsc2UgZ2l2ZV9tb25leSh2YWwpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBmb3JjZV9zZWxsKHN0cmluZyBzdHIpCit7ICByZXR1cm4gc2VsbChzdHIsIDEpOyAgfQorCitzdGF0aWMgaW50IGV2YWx1YXRlKHN0cmluZyBzdHIpCit7CisgIG9iamVjdCBvYjsKKyAgaW50IHZhbCxydmFsOworCisgIGlmICghc3RyKSByZXR1cm4gMDsKKyAgaWYoc3RyaW5ncChRdWVyeVByb3AoUF9LRUVQRVIpKSAmJiAhcHJlc2VudChRdWVyeVByb3AoUF9LRUVQRVIpLCBNRSkpIHsKKyAgICB3cml0ZSgiRXMgaXN0IG5pZW1hbmQgZGEsIGRlciBEaWNoIGJlZGllbmVuIGtvZW5udGUuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIG9iPXByZXNlbnQoc3RyLCBNRSk7CisgIGlmICghb2IpIG9iPWRlZXBfcHJlc2VudChzdHIsUEwpOworICBpZiAoIW9iKSB7CisgICAgd3JpdGUoIkhtPyAiK2NhcGl0YWxpemUoc3RyKSsiPyBXb3ZvbiByZWRlc3QgRHU/XG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAobGl2aW5nKG9iKSkgeworICAgIF9ub3RpZnlfZmFpbCgiTmFudSwgc2VpdCB3YW5uIHdlcmRlbiBoaWVyIExlYmV3ZXNlbiB2ZXJrYXVmdD9cbiIpOworICAgIHJldHVybiAwOworICB9CisgIGlmIChzdHI9c2VsbF9vYmoob2IsIDApKSB7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKHN0ciwgNzgsIE5hbWUoV0VSKSsiIHNhZ3Q6ICIpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBydmFsPW9iLT5RdWVyeVByb3AoUF9WQUxVRSk7CisgIGlmIChydmFsKSB7CisgICAgdmFsPVF1ZXJ5U2VsbFZhbHVlKG9iLCBQTCk7CisgICAgaWYgKHJ2YWw9PXZhbCkgeworICAgICAgdGVsbF9vYmplY3QodGhpc19wbGF5ZXIoKSxicmVha19zdHJpbmcoCisgICAgICAgICAiTmFqYSwgaWNoIGRlbmtlLCAiICt2YWwrICIgTXVlbnplIgorICAgICAgICAgKyAodmFsPT0xID8gIiIgOiAibiIpCisgICAgICAgICArICIgd2FlcmUiKyhvYi0+UXVlcnlQcm9wKFBfQU1PVU5UKT4xPyJuICI6IiAiKQorICAgICAgICAgKyAob2ItPlF1ZXJ5UHJvbm91bihXRVIpKSsiIHNjaG9uIHdlcnQuXG4iLDc4KSk7CisgICAgfQorICAgIGVsc2UgaWYgKHZhbCkgeworICAgICAgICB0ZWxsX29iamVjdCh0aGlzX3BsYXllcigpLGJyZWFrX3N0cmluZygKKyAgICAgICAgICAiT2gsIG5hY2ggZGVyIGFrdHVlbGxlbiBNYXJrdGxhZ2Uga2FubiBpY2ggbnVyICIrdmFsKyIgTXVlbnplIisKKyAgICAgICAgICAodmFsPT0xPyIiOiJuIikrIiBiZXphaGxlbiwgb2J3b2hsICIKKyAgICAgICAgICArIChRdWVyeVByb3AoUF9QTFVSQUwpID8gInNpZSIgOiAiZXMiKQorICAgICAgICAgICsgIiBlaWdlbnRsaWNoICIrcnZhbAorICAgICAgICAgICsgIiBNdWVuemUiKyhydmFsPT0xPyIiOiJuIikrIiB3ZXJ0IGlzdC5cbiIsNzgpKTsKKyAgICB9CisgICAgZWxzZSB3cml0ZSgiSWNoIGJpbiB2b2xsa29tbWVuIHBsZWl0ZS4gVHV0IG1pciBsZWlkLlxuIik7CisgIH0KKyAgZWxzZSB3cml0ZSgiRGFzIGlzdCB2b2VsbGlnIHdlcnRsb3MuXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgc2hvd19vYmooc3RyaW5nIHN0cikKK3sKKyAgaW50IGk7CisgIHN0cmluZyB3YXM7CisgIG1peGVkIG9iOworCisgIGlmICghc3RyKSByZXR1cm4gMDsKKyAgaWYgKHNzY2FuZihzdHIsIiVzIGltIGxhZGVuIix3YXMpPjAgfHwgc3NjYW5mKHN0ciwiJXMgaW4gbGFkZW4iLHdhcyk+MCkgeworICAgIF9ub3RpZnlfZmFpbCgiRGFzIGthbm4gaWNoIGltIExhZ2VyIG5pY2h0IGZpbmRlbi5cbiIpOworICAgIG9iPUZpbmRJblN0b3JlKHdhcyk7CisgIH0gZWxzZSBpZiAoc3NjYW5mKHN0ciwiJWQiLGkpPjAgJiYgaT4wKSB7CisgICAgX25vdGlmeV9mYWlsKCJEYXMga2FubiBpY2ggaW0gTGFnZXIgbmljaHQgZmluZGVuLlxuIik7CisgICAgb2I9RmluZEluU3RvcmUoaSk7CisgIH0KKyAgaWYgKCFvYikgcmV0dXJuIDA7CisgIHdyaXRlKG9iLT5OYW1lKFdFUikrIjpcbiIrb2ItPmxvbmcoKStjYXBpdGFsaXplKG9iLT5RdWVyeVByb25vdW4oKSkKKyAgICAgICArIiBrb3N0ZXQgIitRdWVyeUJ1eVZhbHVlKG9iLFBMKSsiIE11ZW56ZW4uXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vIGJlbnV0enQgdm9uIHRyYWRpbmdfcHJpY2U6OlF1ZXJ5VmFsdWUob2JqZWN0LCBpbnQsIG9iamVjdCkKK3N0YXRpYyBpbnQgT2JqZWN0Q291bnQob2JqZWN0IG9iKQoreworICBzdHJpbmcgdG1wOworCisgIGlmICghb2JqZWN0cChvYikpIHJldHVybiAwOworICB0bXAgPSBCTFVFX05BTUUob2IpOworICBpZiAodG1wWzAuLjJdIT0iL2QvIiAmJiB0bXBbMC4uOF0hPSIvcGxheWVycy8iKSB0bXA9b2ItPnNob3J0KCkrdG1wOworICByZXR1cm4gb2JfYW56W3RtcF07Cit9CisKKy8vIGJlbnV0enQgdm9uIHRyYWRpbmdfcHJpY2U6OlF1ZXJ5U2VsbFZhbHVlKG9iamVjdCwgb2JqZWN0KQorc3RhdGljIHZhcmFyZ3MgaW50IFF1ZXJ5VmFsdWUob2JqZWN0IG9iLCBpbnQgdmFsdWUsIG9iamVjdCBjbGllbnQpCit7CisgIGludCBuZXdfdmFsdWUsIG15bW9uZXk7CisKKyAgaWYgKCFvYmplY3RwKG9iKSkgcmV0dXJuIDA7CisgIGlmIChRdWVyeSgibGFkZW46OmNvbXBhdCIpKSB7CisgICAgbmV3X3ZhbHVlPSh2YWx1ZT4xMDAwPzEwMDA6dmFsdWUpOworICAgIG15bW9uZXkgPSBRdWVyeVByb3AoUF9DVVJSRU5UX01PTkVZKTsKKyAgICBpZiAobmV3X3ZhbHVlPm15bW9uZXkpCisgICAgICByZXR1cm4gKG15bW9uZXk+MD9teW1vbmV5OjApOworICAgIGVsc2UgcmV0dXJuIG5ld192YWx1ZTsKKyAgfQorICByZXR1cm4gOjpRdWVyeVZhbHVlKG9iLCB2YWx1ZSwgY2xpZW50KTsKK30KKwordm9pZCByZXNldCgpCit7CisgIG1peGVkICprZXlzOworICBpbnQgaTsKKworICB0cmFkaW5nX3ByaWNlOjpyZXNldCgpOworCisgIGlmICghbWFwcGluZ3Aob2JfYW56KSkKKyAgICByZXR1cm47CisgIGtleXM9bV9pbmRpY2VzKG9iX2Fueik7CisgIGZvciAoaT1zaXplb2Yoa2V5cyktMTtpPj0wO2ktLSkgeworICAgIG9iX2FueltrZXlzW2ldXT1vYl9hbnpba2V5c1tpXV0qNy84OworICAgIGlmICghb2JfYW56W2tleXNbaV1dKQorICAgICAgIG1fZGVsZXRlKG9iX2FueixrZXlzW2ldKTsKKyAgfQorfQorCit2YXJhcmdzIGludCBDaGVja0ZpbmRSZXN0cmljdGlvbnMob2JqZWN0IG9iLCBtaXhlZCByZXN0ciwgY2xvc3VyZSBxcCkgeworICByZXR1cm4gMDsKK30KKworaW50IEV2YWxXZWFwb24ob2JqZWN0IG9iLCBjbG9zdXJlIHFwKSB7CisgIGludCB3Yyx2YWw7CisKKyAgd2M9ZnVuY2FsbChxcCxQX1dDKTsKKyAgdmFsPWZ1bmNhbGwocXAsUF9FRkZFQ1RJVkVfV0MpOworICBpZiAodmFsPndjKSB3Yz12YWw7CisgIHJldHVybiB3YzsKK30KKwordmFyYXJncyBvYmplY3QgRmluZEJlc3RXZWFwb24obWl4ZWQgdHlwZSwgaW50IG1heG1vbiwgaW50IG1heHcsIGludCBoYW5kcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBiZXN0d2MsIG1peGVkIHJlc3RyKSB7CisgIG9iamVjdCBiZXN0b2Isb2I7CisgIHN0cmluZyBvdHlwZTsKKyAgaW50IHdjLGJlc3R2YWwsdmFsLHcsYmVzdHc7CisgIGNsb3N1cmUgcXA7CisKKyAgaWYgKCFzdHJpbmdwKHN0b3JhZ2UpIHx8ICFvYmplY3RwKG9iPWZpbmRfb2JqZWN0KHN0b3JhZ2UpKSkgcmV0dXJuIDA7CisgIGlmICghbWF4bW9uKSBtYXhtb249MTAwMDAwOworICBpZiAoIW1heHcpIG1heHc9NzUwMDA7CisgIGlmICghaGFuZHMpIGhhbmRzPTI7CisgIGlmICh2YWw9UXVlcnlCdXlGYWN0KCkpIG1heG1vbj0obWF4bW9uKjEwMCkvdmFsOworICBpZiAodHlwZSAmJiAhcG9pbnRlcnAodHlwZSkgJiYgIW1hcHBpbmdwKHR5cGUpKSB0eXBlPSh7dHlwZX0pOworCisgIGZvciAob2I9Zmlyc3RfaW52ZW50b3J5KG9iKTtvYjtvYj1uZXh0X2ludmVudG9yeShvYikpIHsKKyAgICBxcD1zeW1ib2xfZnVuY3Rpb24oIlF1ZXJ5UHJvcCIsb2IpOworICAgIGlmICghb3R5cGU9ZnVuY2FsbChxcCxQX1dFQVBPTl9UWVBFKSkgY29udGludWU7CisgICAgaWYgKHR5cGUgJiYgbWVtYmVyKHR5cGUsb3R5cGUpPDApIGNvbnRpbnVlOworICAgIHdjPUV2YWxXZWFwb24ob2IscXApOworICAgIGlmICh3YzxiZXN0d2MpIGNvbnRpbnVlOworICAgIGlmIChmdW5jYWxsKHFwLFBfTlJfSEFORFMpPmhhbmRzKSBjb250aW51ZTsKKyAgICB3PWZ1bmNhbGwocXAsUF9XRUlHSFQpOworICAgIGlmICh3Pm1heHcpIGNvbnRpbnVlOworICAgIHZhbD1mdW5jYWxsKHFwLFBfVkFMVUUpOworICAgIGlmICh2YWw+bWF4bW9uKSBjb250aW51ZTsKKyAgICBpZiAoYmVzdG9iICYmIHdjPD1iZXN0d2MpIHsKKyAgICAgIGlmICh2YWw+YmVzdHZhbCkgY29udGludWU7CisgICAgICBlbHNlIGlmICh2YWw9PWJlc3R2YWwgJiYgdz5iZXN0dykgY29udGludWU7CisgICAgfQorICAgIGlmICh2YWw+YmVzdHZhbCAmJiBiZXN0b2IgJiYgd2M8PWJlc3R3YykgY29udGludWU7CisgICAgaWYgKENoZWNrRmluZFJlc3RyaWN0aW9ucyhvYixyZXN0cixxcCkpIGNvbnRpbnVlOworICAgIGJlc3RvYj1vYjsKKyAgICBiZXN0d2M9d2M7CisgICAgYmVzdHZhbD12YWw7CisgICAgYmVzdHc9dzsKKyAgfQorICByZXR1cm4gYmVzdG9iOworfQorCitpbnQgRXZhbEFybW91cihvYmplY3Qgb2IsY2xvc3VyZSBxcCkgeworICBpbnQgYWMsdmFsOworCisgIGFjPWZ1bmNhbGwocXAsUF9BQyk7CisgIHZhbD1mdW5jYWxsKHFwLFBfRUZGRUNUSVZFX0FDKTsKKyAgaWYgKHZhbD5hYykgYWM9dmFsOworICByZXR1cm4gYWM7Cit9CisKK3ZhcmFyZ3MgbWFwcGluZyBGaW5kQmVzdEFybW91cnNUKG1peGVkIHR5cGUsIGludCBtYXhtb24sIGludCBtYXh3LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwcGluZyBiZXN0YWMsIG1peGVkIHJlc3RyKSB7CisgIG9iamVjdCBvYjsKKyAgc3RyaW5nIG90eXBlOworICBpbnQgYWMsdmFsLHN1bSx3LHdzdW07CisgIG1hcHBpbmcgYmVzdG9iLGJlc3R2YWwsYmVzdHc7CisgIGNsb3N1cmUgcXA7CisKKyAgaWYgKCFzdHJpbmdwKHN0b3JhZ2UpIHx8ICFvYmplY3RwKG9iPWZpbmRfb2JqZWN0KHN0b3JhZ2UpKSkgcmV0dXJuIChbXSk7CisgIGlmICghbWF4bW9uKSBtYXhtb249MTAwMDAwOworICBpZiAoIW1heHcpIG1heHc9NzUwMDA7CisgIGlmICh2YWw9UXVlcnlCdXlGYWN0KCkpIG1heG1vbj0obWF4bW9uKjEwMCkvdmFsOworICBpZiAodHlwZSAmJiAhcG9pbnRlcnAodHlwZSkgJiYgIW1hcHBpbmdwKHR5cGUpKSB0eXBlPSh7dHlwZX0pOworICBpZiAoIW1hcHBpbmdwKGJlc3RhYykpIGJlc3RhYz0oW10pOworICBiZXN0b2I9KFtdKTtiZXN0dmFsPShbXSk7YmVzdHc9KFtdKTsKKworICBmb3IgKG9iPWZpcnN0X2ludmVudG9yeShvYik7b2I7b2I9bmV4dF9pbnZlbnRvcnkob2IpKSB7CisgICAgcXA9c3ltYm9sX2Z1bmN0aW9uKCJRdWVyeVByb3AiLG9iKTsKKyAgICBpZiAoIW90eXBlPWZ1bmNhbGwocXAsUF9BUk1PVVJfVFlQRSkpIGNvbnRpbnVlOworICAgIGlmICh0eXBlICYmIG1lbWJlcih0eXBlLG90eXBlKTwwKSBjb250aW51ZTsKKyAgICBhYz1FdmFsQXJtb3VyKG9iLHFwKTsKKyAgICBpZiAoYWM8YmVzdGFjW290eXBlXSkgY29udGludWU7CisgICAgdz1mdW5jYWxsKHFwLFBfV0VJR0hUKTsKKyAgICBpZiAod3N1bS1iZXN0d1tvdHlwZV0rdz5tYXh3KSBjb250aW51ZTsKKyAgICB2YWw9ZnVuY2FsbChxcCxQX1ZBTFVFKTsKKyAgICBpZiAoc3VtLWJlc3R2YWxbb3R5cGVdK3ZhbD5tYXhtb24pIGNvbnRpbnVlOworICAgIGlmIChiZXN0b2Jbb3R5cGVdICYmIGFjPD1iZXN0YWNbb3R5cGVdKSB7CisgICAgICBpZiAodmFsPmJlc3R2YWxbb3R5cGVdKSBjb250aW51ZTsKKyAgICAgIGVsc2UgaWYgKHZhbD09YmVzdHZhbFtvdHlwZV0gJiYgdz5iZXN0d1tvdHlwZV0pIGNvbnRpbnVlOworICAgIH0KKyAgICBpZiAoQ2hlY2tGaW5kUmVzdHJpY3Rpb25zKG9iLHJlc3RyLHFwKSkgY29udGludWU7CisgICAgc3VtPXN1bS1iZXN0dmFsW290eXBlXSt2YWw7CisgICAgd3N1bT13c3VtLWJlc3R3W290eXBlXSt3OworICAgIGJlc3RvYltvdHlwZV09b2I7CisgICAgYmVzdGFjW290eXBlXT1hYzsKKyAgICBiZXN0dmFsW290eXBlXT12YWw7CisgICAgYmVzdHdbb3R5cGVdPXc7CisgIH0KKyAgcmV0dXJuIGJlc3RvYjsKK30KKwordmFyYXJncyBvYmplY3QgKkZpbmRCZXN0QXJtb3VycyhtaXhlZCB0eXBlLCBpbnQgbWF4bW9uLCBpbnQgbWF4dywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmcgYmVzdGFjLCBtaXhlZCByZXN0cikgeworICByZXR1cm4gbV92YWx1ZXMoRmluZEJlc3RBcm1vdXJzVCh0eXBlLG1heG1vbixtYXh3LGJlc3RhYyxyZXN0cikpOworfQpkaWZmIC0tZ2l0IGEvc3RkL3NlY3VyZV90aGluZy5jIGIvc3RkL3NlY3VyZV90aGluZy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcyMTk1MjkKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvc2VjdXJlX3RoaW5nLmMKQEAgLTAsMCArMSwzNCBAQAorLyoKKyAqIHRoaW5nLmMgZnVlciBPYmpla3RlLCBkaWUgc2ljaGVyaGVpdHNyZWxldmFudCBzaW5kLgorICogU29sbHRlIHZvbiBEaW5nZW4gYXVzIC9zZWN1cmUgb2RlciBNYWdpZXJ0b29scyBhdWYgamVkZW4KKyAqIEZhbGwgc3RhdHQgL3N0ZC90aGluZyBpbmhlcml0ZWQgd2VyZGVuLgorICoKKyAqIERlciBVbnRlcnNjaGllZCB6dSAvc3RkL3RoaW5nIGJlc3RlaHQgZGFyaW4sIHBvdGVudGllbGwgdW5zaWNoZXJlCisgKiBBdXN3ZXJ0dW5nZW4gd2llIHByb2Nlc3Nfc3RyaW5nKCkgKEBAZnVuQEApIHp1IHZlcmhpbmRlcm4gLSBhbnNvbnN0ZW4KKyAqIGtvZW5udGUgamVtYW5kIE1hZ2llcm4gQ29kZSB1bnRlcnNjaGllYmVuLgorICoKKyAqLworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBub19zaGFkb3cKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC90aGluZyI7CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCisvLyBpbnQgc2VjdXJlX2xldmVsKCkgLy8gaXN0IG51biBpbiBzaW11bF9lZnVuCisKK3ZhcmFyZ3Mgc3RyaW5nIGxvbmcoaW50IG1vZGUpCit7CisgIHJldHVybiBmdW5jYWxsKFF1ZXJ5UHJvcChQX0xPTkcpKTsKK30KKworc3RyaW5nIHNob3J0KCkKK3sKKyAgc3RyaW5nIHNoOworICBpZiggc2g9UXVlcnlQcm9wKFBfU0hPUlQpICkKKyAgICByZXR1cm4gZnVuY2FsbChzaCkrIi5cbiI7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9zaGVsbHMvYmF1bS5jIGIvc3RkL3NoZWxscy9iYXVtLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTIyZjNmZQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvYmF1bS5jCkBAIC0wLDAgKzEsMTEzIEBACisvLyBBdXRvcjogUnVtYXRhQGdteC5kZQorLy8gLi4uIHNvenVzYWdlbiBtZWluZSBwcml2YXRlIHJhc3NlIC4uLgorLy8KKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBzaGVsbHMvbWFnaWVyLmMgLS0gbWFnaWVyIHNoZWxsCisvLworLy8gJElkOiBiYXVtLmMgODY3NSAyMDE0LTAyLTE4IDIwOjM5OjU0WiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJvbmdfdHlwZXMsc2F2ZV90eXBlcworCitpbmhlcml0ICIvc3RkL3NoZWxscy9tYWdpZXIiOworCisvLyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8YXR0cmlidXRlcy5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxhbnNpLmg+CisjaW5jbHVkZSA8dWRwLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorCitzdGF0aWMgaW50IF93dXJ6ZWw7CisKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgaWYgKCFjbG9uZXAoKSB8fCBvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSA9PSBfX0ZJTEVfX1swLi48M10pIHsKKyAgICAgIHNldF9uZXh0X3Jlc2V0KC0xKTsgICAgCisgICAgICByZXR1cm47CisgIH0KKworICA6OmNyZWF0ZSgpOworCV93dXJ6ZWwgPSAtMTsKK30KKworc3RhdGljIGludCB3dXJ6ZWxfYW4oIHN0cmluZyBhcmcgKSB7CisJc3RyaW5nIG51bTsKKwlpbnQgY291bnQ7CisKKwlpZiggdGhpc19vYmplY3QoKSAhPSB0aGlzX2ludGVyYWN0aXZlKCkgKSByZXR1cm4gMDsKKwlub3RpZnlfZmFpbCggIldBUyB3aWxsc3QgRHUgc2NobGFnZW4/XG4iICk7CisJaWYoICFhcmcgfHwgc3NjYW5mKCBhcmcsICJ3dXJ6ZWwlcyIsIG51bSApID09IDAgKSByZXR1cm4gMDsKKworCWlmKCBzc2NhbmYoIG51bSwgIiAlZCIsIGNvdW50ICkgPT0gMCApIHsKKwkJbm90aWZ5X2ZhaWwoICJzY2hhZ2Ugd3VyemVsIDx6YWhsPlxuIiApOworCQlyZXR1cm4gMDsKKwl9CisKKwlfd3VyemVsID0gY291bnQ7CisJc2F5KCBOYW1lKFdFUikgKyAiIHNjaGxhZWd0IGhpZXIgV3VyemVsbi5cbiIgKTsKKwl3cml0ZSggIkR1IHNjaGxhZWdzdCBudW4gV3VyemVsbi5cbiIgKTsKKwlyZXR1cm4gMTsKK30KKworc3RhdGljIGludCB3dXJ6ZWxfYXVzKCBzdHJpbmcgYXJnICkgeworCQorCWlmKCB0aGlzX29iamVjdCgpICE9IHRoaXNfaW50ZXJhY3RpdmUoKSApIHJldHVybiAwOworCW5vdGlmeV9mYWlsKCAiV0FTIHdpbGxzdCBkdSBsb2VzZW4/XG4iICk7CisJaWYoICFhcmcgKSByZXR1cm4gMDsKKwlpZiggbWVtYmVyKCAoeyJ3dXJ6ZWwiLCJ3dXJ6ZWxuIn0pLAlhcmcgKSA9PSAtMSApIHJldHVybiAwOworCQorCV93dXJ6ZWwgPSAtMTsKKwlzYXkoIE5hbWUoV0VSKSArICIgbG9lc3QgIiArIFF1ZXJ5UHJvbm91bihGRU1BTEUsV0VOLFBMVVJBTCkKKwkJCSArICIgV3VyemVsbiBhdXMgZGVtIEJvZGVuLlxuIiApOworCXdyaXRlKCAiRHUgbG9lc3QgRGVpbmUgV3VyemVsbiBhdXMgZGVtIEJvZGVuLlxuIiApOworCXJldHVybiAxOworfQorCitpbnQgd3VyemVsX2luZm8oIHN0cmluZyBhcmcgKSB7CisJaWYoIHRoaXNfb2JqZWN0KCkgIT0gdGhpc19pbnRlcmFjdGl2ZSgpICkgcmV0dXJuIDA7CisJc3dpdGNoKCBfd3VyemVsICkgeworCWNhc2UgLTE6CisJCXdyaXRlKCAiRGVpbmUgV3VyemVsbiBzaW5kIGxvc2UuXG4iICk7CisJCWJyZWFrOworCWNhc2UgMDoKKwkJd3JpdGUoICJEZWluZSBXdXJ6ZWxuIHNpdHplbiBmZXN0LlxuIiApOworCQlicmVhazsKKwljYXNlIDE6CisJCXdyaXRlKCAiTm9jaCBlaW5lIEJld2VndW5nIHVuZCBEdSBzaXR6dCBmZXN0LlxuIiApOworCQlicmVhazsKKwlkZWZhdWx0OgorCQlwcmludGYoICJOb2NoICVkIEJld2VndW5nZW4sIHVuZCBEdSBzaXR6dCBmZXN0LlxuIiwgX3d1cnplbCApOworCX0KKwlyZXR1cm4gMTsKK30KKworc3RhdGljIG1peGVkIF9xdWVyeV9sb2NhbGNtZHMoKSB7CisJcmV0dXJuIDo6X3F1ZXJ5X2xvY2FsY21kcygpICsgKHsKKwkJKHsgInNjaGxhZyIgICAgLCAid3VyemVsX2FuIiAgLDEsQVJDSF9MVkwgfSksCisJCSh7ICJsb2VzIiAgICAgICwgInd1cnplbF9hdXMiICwxLEFSQ0hfTFZMIH0pLAorCQkoeyAid3VyemVsaW5mbyIsICJ3dXJ6ZWxfaW5mbyIsMCxBUkNIX0xWTCB9KQorCX0pOworfQorCit2YXJhcmdzIGludCBtb3ZlKCBtaXhlZCBkZXN0LCBpbnQgbWV0aG9kLCBzdHJpbmcgZGlyLAorCQkJCQkJCQkJc3RyaW5nIHRleHRvdXQsIHN0cmluZyB0ZXh0aW4gKQoreworCWlmKCBfd3VyemVsID09IDAgKSB7CisJCXJldHVybiBNRV9UT09fSEVBVlk7CisJfQorCWlmKCBfd3VyemVsID4gMCApIHsgX3d1cnplbC0tOyB9CisJcmV0dXJuIDo6bW92ZSggZGVzdCwgbWV0aG9kLCBkaXIsIHRleHRvdXQsIHRleHRpbiApOworfQorCitzdGF0aWMgaW50IG5ld19xdWl0KCkgeworCV93dXJ6ZWwgPSAtMTsKKwlyZXR1cm4gOjpuZXdfcXVpdCgpOworfQpkaWZmIC0tZ2l0IGEvc3RkL3NoZWxscy9kYXJrZWxmLmMgYi9zdGQvc2hlbGxzL2RhcmtlbGYuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40NWUzN2ZiCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3NoZWxscy9kYXJrZWxmLmMKQEAgLTAsMCArMSwyNzAgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBzaGVsbHMvZGFya2VsZi5jIC0tIERhcmtlbGYgU2hlbGwKKy8vCisvLyAkSWQ6IGRhcmtlbGYuYyA4Njc1IDIwMTQtMDItMTggMjA6Mzk6NTRaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cm9uZ190eXBlcyxzYXZlX3R5cGVzCisKK2luaGVyaXQgIi9zdGQvcGxheWVyL2Jhc2UiOworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGF0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxoZWFsdGguaD4KKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8ZGVmdWVsLmg+CisjaW5jbHVkZSA8ZXJyb3JkLmg+CisKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgaWYgKCFjbG9uZXAoKSB8fCBvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSA9PSBfX0ZJTEVfX1swLi48M10pIHsKKyAgICBzZXRfbmV4dF9yZXNldCgtMSk7CisgICAgcmV0dXJuOworICB9CisgIGJhc2U6OmNyZWF0ZSgpOworICBTZXREZWZhdWx0SG9tZSgiL2dpbGRlbi9kdW5rZWxlbGZlbiIpOworICBTZXREZWZhdWx0UHJheVJvb20oIi9kL3VudGVyd2VsdC9jYWRyYS9yb29tL3Rvd24vdGVtcGxlbWFpbiIpOworICBTZXRQcm9wKFBfQVZFUkFHRV9TSVpFLDE3NSk7CisgIFNldFByb3AoUF9BVkVSQUdFX1dFSUdIVCw3MDAwMCk7CisgIFNldFByb3AoUF9BTElHTiwgLTUwMCk7CisgIFNldFByb3AoUF9TS0lMTF9BVFRSSUJVVEVfT0ZGU0VUUywoW1NBX0VORU1ZX1NBVkU6MTEwXSkpOworICBTZXRQcm9wKFBfQVRUUklCVVRFU19PRkZTRVRTLChbQV9JTlQ6NCxBX0RFWDoyXSkpOworICBTZXRQcm9wKFBfTUFURVJJQUxfS05PV0xFREdFLChbTUFUR1JPVVBfVU5IT0xZOiAxMDAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQVRHUk9VUF9NQUdJQzogICA3MCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BVEdST1VQX0RFQUQ6ICAgIDUwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFUR1JPVVBfTUVUQUw6ICAgMzBdKSApOworICBTZXRQcm9wKFBfUkVTSVNUQU5DRV9TVFJFTkdUSFMsCisgICAgICAgICAgICAoWyBEVF9IT0xZIDogICAgMC4yNSwKKyAgICAgICAgICAgICAgIERUX1VOSE9MWSA6IC0wLjE1LAorICAgICAgICAgICAgICAgRFRfVEVSUk9SIDogLTAuMDUgXSkpOworICBTZXRQcm9wKFBfTUFYX0ZPT0QsODApOworICBTZXRQcm9wKFBfTUFYX0RSSU5LLDE1MCk7CisgIFNldFByb3AoUF9NQVhfQUxDT0hPTCw3MCk7CisKKyAgU2V0UHJvcChQX1NQX0RFTEFZLCBIRUFMX0RFTEFZLTIpOyAvLyBkYWZ1ZXIgcmVnZW5lcmllcnQgbWFuIGltIGZyZWllbgorICBTZXRQcm9wKFBfSFBfREVMQVksIEhFQUxfREVMQVktMSk7IC8vIHdpcmtsaWNoIF9uaWNodHNfCisgIFNldFByb3AoUF9GT09EX0RFTEFZLEZPT0RfREVMQVkrMSk7CisgIFNldFByb3AoUF9EUklOS19ERUxBWSxEUklOS19ERUxBWS0yKTsKKyAgU2V0UHJvcChQX0FMQ09IT0xfREVMQVksQUxDT0hPTF9ERUxBWSsxKTsKKworICBTZXRQcm9wKFBfTUFHSUNfUkVTSVNUQU5DRV9PRkZTRVQsCisgICAgICAgIChbIE1UX0lMTFVTSU9OICAgIDogMjAwLAorICAgICAgICAgICBNVF9BTkdSSUZGICAgICA6IDUwMCwKKwkgICBNVF9CRUhFUlJTQ0hVTkc6IDUwMCwKKwkgICBNVF9QU1lDSE8gICAgICA6IDgwMCBdKSk7CisKKyAgLyogR3JvZXNzZSB3aXJkIG51ciBlaW5tYWwgZ2VzZXR6dCAqLworICBpZighUXVlcnlQcm9wKFBfU0laRSkpIHsKKyAgICBTZXRQcm9wKFBfU0laRSwxNTArcmFuZG9tKDUwKSk7CisgICAgU2V0KFBfU0laRSxTQVZFLEZfTU9ERV9BUyk7CisgIH0KKworICAvKiBEaXRvIEdld2ljaHQgKi8KKyAgaWYoIVF1ZXJ5UHJvcChQX1dFSUdIVCkgfHwgKFF1ZXJ5UHJvcChQX1dFSUdIVCkgPT0gNzUwMDApKXsKKyAgICBTZXRQcm9wKFBfV0VJR0hULDYwMDAwK3JhbmRvbSgyMDAwMSkpOworICAgIGlmKFF1ZXJ5UHJvcChQX0dFTkRFUik9PUZFTUFMRSkKKyAgICAgIFNldFByb3AoUF9XRUlHSFQsUXVlcnlQcm9wKFBfV0VJR0hUKS01MDAwKTsKKyAgICBTZXQoUF9XRUlHSFQsU0FWRSxGX01PREVfQVMpOworICB9CisgIFNldFByb3AoUF9ERUZVRUxfTElNSVRfRk9PRCw0MCk7CisgIFNldFByb3AoUF9ERUZVRUxfTElNSVRfRFJJTkssMzApOworICBTZXRQcm9wKFBfREVGVUVMX1RJTUVfRk9PRCw0MDApOworICBTZXRQcm9wKFBfREVGVUVMX1RJTUVfRFJJTkssMjUwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9BTU9VTlRfRk9PRCwwLjQ1KTsKKyAgU2V0UHJvcChQX0RFRlVFTF9BTU9VTlRfRFJJTkssMC40KTsKK30KKworc3RhdGljIHZvaWQgRmluYWxTZXR1cCgpCit7CisgICBpZiAoIVF1ZXJ5U2tpbGwoU0tfTklHSFRWSVNJT04pKQorICAgICAgTW9kaWZ5U2tpbGwoU0tfTklHSFRWSVNJT04sIDUwMDAsIDAsICJBTlkiKTsKK30KKworc3RyaW5nIF9xdWVyeV9yYWNlKCkKKy8vIG5pY2h0IHN0YXRpYywgZGEgc2llIG1hbmNobWFsIGF1Y2ggc28gYXVmZ2VydWZlbiB3aXJkLi4uCit7CisgIHJldHVybiAiRHVua2VsZWxmIjsKK30KKworc3RyaW5nIF9xdWVyeV9yZWFsX3JhY2UoKQoreworICByZXR1cm4gIkR1bmtlbGVsZiI7Cit9CisKK3N0YXRpYyBzdHJpbmcgX3F1ZXJ5X3JhY2VkZXNjcigpCit7CisJICByZXR1cm4KKyJcCitEYXMgVm9sayBkZXIgRHVua2VsZWxmZW4gbGVidCBpbiBlaW5lciBncm9zc2VuIEhvZWhsZW5zdGFkdCBndXQgdmVyc3RlY2t0XG5cCitoaW50ZXIgZWluZW0gV2Fzc2VyZmFsbC4gVWViZXIga2F1bSBlaW4gYW5kZXJlcyBWb2xrIGdpYnQgZXMgc292aWVsZVxuXAorVm9ydXJ0ZWlsZSB3aWUgdWViZXIgZGllIER1bmtlbGVsZmVuLCB1bmQgc28gd2VyZGVuIHNpZSB2b24gYWxsZW4gbWlzc3RyYXVpc2NoXG5cCitiZWFldWd0IG9kZXIgc29nYXIgYmVrYWVtcGZ0LiBJbiBkaWVzZW0gS2FtcGYsIGluc2Jlc29uZGVyZSBnZWdlbiBkaWUgRWxmZW4sXG5cCitzaW5kIHNpZSB2b2VsbGlnIGF1ZiBzaWNoIGFsbGVpbiBnZXN0ZWxsdCwgdW5kIHNvIGhhdCBzaWNoIGVpbmUgbWVociBvZGVyXG5cCittaW5kZXIgYXV0YXJrZSBHZXNlbGxzY2hhZnQgZW50d2lja2VsdC4gRGllIER1bmtlbGVsZmVuIGhhYmVuIGVpbmUgZWlnZW5lXG5cCitLdWx0dXIgdW5kIGVpbmUgZWlnZW5lIEdvZXR0aW4sIGRlciBzaWUgaHVsZGlnZW4uIFdpZSBhdWNoIGRpZSBFbGZlblxuXAordmVyZnVlZ2VuIHNpZSB1ZWJlciBhdXNzZXJvcmRlbmxpY2ggZ3Jvc3NlIG1hZ2lzY2hlIEZhZWhpZ2tlaXRlbiwgYXVjaCB3ZW5uXG5cCitzaWUgc2ljaCBtZWhyIGF1ZiBkaWUgc2Nod2FyemUgU2VpdGUgZGVyIE1hZ2llIHNwZXppYWxpc2llcnQgaGFiZW4uXG4iOworfQorCisvLyBpbnQgUXVlcnlBbGxvd1NlbGVjdCgpIHsgcmV0dXJuIDA7IH0KKy8vIEFrdGl2aWVydCBhbSAyOC4wNy4wMywgQXJrLgoraW50IFF1ZXJ5QWxsb3dTZWxlY3QoKSB7IHJldHVybiAxOyB9CisKK3N0cmluZyAqX3F1ZXJ5X3JhY2VzdHJpbmcoKQoreworICBpZiAoUXVlcnlQcm9wKFBfR0VOREVSKT09MikKKyAgICByZXR1cm4gKHsiRHVua2VsZWxmZSIsIkR1bmtlbGVsZmUiLCJEdW5rZWxlbGZlIiwiRHVua2VsZWxmZSJ9KTsKKyAgcmV0dXJuICh7IkR1bmtlbGVsZiIsIkR1bmtlbGVsZmVuIiwiRHVua2VsZWxmIiwiRHVua2VsZWxmIn0pOworfQorCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9kZWZhdWx0X2d1aWxkKCkKK3sKKyAgcmV0dXJuICJkdW5rZWxlbGZlbiI7Cit9CisKK3N0YXRpYyBpbnQgc3VuX2luX3Jvb20ob2JqZWN0IHJvb20pCit7CisgIGlmICghcm9vbSkgcmV0dXJuIDA7CisgIGNsb3N1cmUgcXA9c3ltYm9sX2Z1bmN0aW9uKCJRdWVyeVByb3AiLCByb29tKTsKKyAgaW50IGx0PWZ1bmNhbGwocXAsIFBfTElHSFRfVFlQRSk7CisgIC8vIChsdCAmIExUX1NVTikgaXN0IGhpZXIgenVuYWVjaHN0IF90ZXN0d2Vpc2VfIGRyaW4uIERpZSBSYXNzZSB3dXJkZQorICAvLyBhbmRlcnMgZ2VuZWhtaWd0LiBTb2xsdGUgZGFzIGltIE1HIHVlYmVyaGFuZCBuZWhtZW4gdW5kIGplZGVyIEtlbGxlcgorICAvLyBudW4gc29ubmVuZHVyY2hmbHV0ZXQgc2VpbiwgZGFubiB3aXJkIGRhcyB3aWVkZXIgYXVzZ2ViYXV0IQorICAvLyAyNy4wNi4wNCBQYWRyZWljCisgIHJldHVybiAoIChmdW5jYWxsKHFwLCBQX0lOVF9MSUdIVCk+MCkgJiYKKyAgICAgICAgICAoKGx0ICYgTFRfU1VOKSB8fCAoKGx0PT1MVF9NSVNDKSAmJiAhZnVuY2FsbChxcCwgUF9JTkRPT1JTKSkpKTsKK30KKworcHJvdGVjdGVkIHZvaWQgaGVhcnRfYmVhdCgpCit7CisgIDo6aGVhcnRfYmVhdCgpOworICBpZiAoc3VuX2luX3Jvb20oZW52aXJvbm1lbnQoKSkgJiYKKyAgICAgIFF1ZXJ5UHJvcCgiRHVua2VsZWxmZW46T3V0ZG9vciIpPHJhbmRvbSgxMDApICYmICFRdWVyeVByb3AoUF9HSE9TVCkpIHsKKyAgICAgaW50IGhwOworICAgICBocD1RdWVyeVByb3AoUF9IUCktMTsKKyAgICAgU2V0UHJvcChQX0hQLCBocCk7CisgICAgIGlmIChocDwwKSB7CisgICAgICAgdGVsbF9vYmplY3QoTUUsCisgICAgICAgICAiRGFzIHdhciB3b2hsIHp1dmllbCBmdWVyIERpY2guIERhcyBuYWVjaHN0ZSBtYWwgc29sbHRlc3QgRHUgRGljaCAiCisgICAgICAgICsid29obCBiZXNzZXJcbmdlZ2VuIGRpZSBTb25uZSBzY2h1ZXR6ZW4uXG4iKTsKKyAgICAgICBTZXRQcm9wKFBfS0lMTF9OQU1FLCJadXZpZWwgU29ubmUiKTsKKyAgICAgICBkb19kYW1hZ2UoOTk5LE1FKTsKKyAgICAgICBTZXRQcm9wKFBfS0lMTF9OQU1FLDApOworICAgICB9CisgICAgIGVsc2UgdGVsbF9vYmplY3QoTUUsIC8qIGRpZSBJbmZvIG11c3N0ZSBpcmdlbmR3aWUgaW4gZWluZSBaZWlsZSAqLworICAgICAgICAgICAiRGllIFNvbm5lIHNjaGVpbnQgZ25hZGVubG9zIGF1ZiBEZWluIEhhdXB0IHVuZCBzY2h3YWVjaHQgRGljaC5cbiIpOworICB9Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X25vX3JlZ2VuZXJhdGlvbigpCit7CisgIGlmIChzdW5faW5fcm9vbShlbnZpcm9ubWVudCgpKSkKKyAgICAgcmV0dXJuIE5PX1JFRzsKKyAgcmV0dXJuIFF1ZXJ5KFBfTk9fUkVHRU5FUkFUSU9OKTsKK30KKworaW50IFN0ZFNraWxsX05pZ2h0dmlzaW9uKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtaXhlZCBzaW5mbykKK3sKKyAgaW50IGxhc3QsIGxpZ2h0OworCisgIGlmICghc2luZm8gfHwgIWVudmlyb25tZW50KCkpIHJldHVybiAwOworICBpZiAoaW50cChzaW5mbykpIHNpbmZvPShbU0lfU0tJTExBQklMSVRZOnNpbmZvXSk7CisgIGlmICghbWFwcGluZ3Aoc2luZm8pKSByZXR1cm4gMDsKKyAgbGlnaHQ9KFF1ZXJ5UHJvcChQX1BMQVlFUl9MSUdIVCk8PTAgPyAtMSA6IDEpOworICBpZiAobGFzdD1zaW5mb1tTSV9VU1JdKSB7IC8vIGxldHp0ZXMgTGljaHRsZXZlbCAhPSAwCisgICAgIGlmIChsaWdodD09bGFzdCkgeworICAgICAgIGlmIChzaW5mb1tTSV9MQVNUTElHSFRdPD10aW1lKCkpCisgICAgICAgICAgcmV0dXJuIHNpbmZvW1NJX1NLSUxMQUJJTElUWV0rMTsKKyAgICAgICByZXR1cm4gLTE7CisgICAgIH0KKyAgICAgZWxzZSB7CisgICAgICAgbGFzdD0oIE1BWF9BQklMSVRZIC0gc2luZm9bU0lfU0tJTExBQklMSVRZXSApOworICAgICAgIGxhc3Q9KGxhc3QvMTAwMCkgKyAobGFzdCUxMDAwID4gcmFuZG9tKDEwMDEpID8gMSA6IDApOworICAgICAgIGlmIChsaWdodDwwKSBsYXN0Lz0yOyAvLyBhbiBEdW5rZWxrZWl0IHNjaG5lbGxlciBnZXdvZWhuZW4uLi4KKyAgICAgICBpZighdGhpc19pbnRlcmFjdGl2ZSgpIHx8IHRoaXNfaW50ZXJhY3RpdmUoKT09dGhpc19vYmplY3QoKSkKKyAgICAgICB7CisJICAgICAgIE1vZGlmeVNraWxsKHNuYW1lLCAoW1NJX1VTUjogbGlnaHQsIFNJX0xBU1RMSUdIVDogdGltZSgpK2xhc3RdKSwKKyAgICAgICAgCSAgICAgICAgICAgMCwgc2luZm9bU0lfR1VJTERdKTsKKyAgICAgICB9CisgICAgICAgaWYgKGxhc3Q8PTApCisgICAgICAgICAgcmV0dXJuIHNpbmZvW1NJX1NLSUxMQUJJTElUWV0rMTsKKyAgICAgICByZXR1cm4gLTE7CisgICAgIH0KKyAgfQorICBlbHNlIHsgLy8gU3RhcnR3ZXJ0Li4uCisgICAgaWYoIXRoaXNfaW50ZXJhY3RpdmUoKSB8fCB0aGlzX2ludGVyYWN0aXZlKCk9PXRoaXNfb2JqZWN0KCkpCisgICAgeworICAgIAlNb2RpZnlTa2lsbChzbmFtZSwgKFtTSV9VU1I6IGxpZ2h0LCBTSV9MQVNUTElHSFQ6IDBdKSwgMCwgc2luZm9bU0lfR1VJTERdKTsKKyAgICB9CisgICAgcmV0dXJuIHNpbmZvW1NJX1NLSUxMQUJJTElUWV0rMTsKKyAgfQorICByZXR1cm4gMDsKK30KKwordmFyYXJncyBpbnQgQ2Fubm90U2VlKGludCBzaWxlbnQpCit7CisgIHN0cmluZyBpc19ibGluZDsKKworICBpZiAoIGlzX2JsaW5kID0gUXVlcnlQcm9wKCBQX0JMSU5EICkgKSB7CisgICAgIGlmICghc2lsZW50KSB7CisgICAgICAgaWYgKHN0cmluZ3AoaXNfYmxpbmQpKSB3cml0ZShpc19ibGluZCk7CisgICAgICAgZWxzZSB3cml0ZSgiRHUgYmlzdCBibGluZCFcbiIpOworICAgICB9CisgICAgIHJldHVybiAxOworICB9CisgIGlmIChlbnZpcm9ubWVudCgpICYmICghSVNfTEVBUk5FUihNRSkgfHwgIVF1ZXJ5KFBfV0FOVFNfVE9fTEVBUk4pKSkgeworICAgICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgICAgIGlmIChTdGRTa2lsbF9OaWdodHZpc2lvbihNRSwgU0tfTklHSFRWSVNJT04sIFF1ZXJ5U2tpbGwoU0tfTklHSFRWSVNJT04pKT4wKQorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgIH0KKyAgICAgZWxzZSBpZiAoVXNlU2tpbGwoU0tfTklHSFRWSVNJT04pPjApIHJldHVybiAwOworICAgICBpZiAoIXNpbGVudCkgeworICAgICAgICBpZiAoUXVlcnlQcm9wKFBfUExBWUVSX0xJR0hUKTw9MCkKKyAgICAgICAgICB3cml0ZSgiRHUga2FubnN0IG5pY2h0cyBzZWhlbiwgZGEgc2ljaCBEZWluZSBBdWdlbiBub2NoIG5pY2h0IGFuIGRpZSBEdW5rZWxoZWl0XG4iCisgICAgICAgICAgICAgICArImdld29laG50IGhhYmVuIVxuIik7CisgICAgICAgIGVsc2Ugd3JpdGUoIkR1IGJpc3Qgdm9uIGRlbSBoZWxsZW4gTGljaHQgdG90YWwgZ2VibGVuZGV0IHVuZCBEdSBtdXNzdCBEaWNoIGVyc3QgbGFuZ3NhbVxuIgorICAgICAgICAgICAgICAgICAgKyJkYXJhbiBnZXdvZWhuZW4uXG4iKTsKKyAgICAgfQorICAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworCisvKgorICogMjAwMy0xMS0wNSwgWm9vazoKKyAqCisgKiAgIFRlbXBvcmFlcmUgRnVua3Rpb24sIGRpZSBkZW4gRGVsZmVuIGVzIGVybW9lZ2xpY2h0LCBlaW5lbgorICogICBtb2VnbGljaGVyd2Vpc2UgZmFsc2NoZW4gUmF1bSAoSW5kb29yL091dGRvb3IpIHp1IG1lbGRlbi4KKyAqCisgKi8KKworc3RhdGljIGludCBfaW5kb29yYnVnKHN0cmluZyBrZXkpCit7CisgIGlmICghc3RyaW5ncChrZXkpKQorICAgIGtleT0gIiI7CisKKyAgRVJST1JELT5Mb2dSZXBvcnRlZEVycm9yKAorICAgICAgKFsgRl9QUk9HOiAidW5iZWthbm50IiwKKyAgICAgICAgIEZfTElORTogMCwKKyAgICAgICAgIEZfTVNHOiAiU29ubmVuZmVobGVyOiAiICsga2V5LAorICAgICAgICAgRl9PQko6IGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpCisgICAgICBdKQorICAgICAgKTsKKworICB3cml0ZSgiRHUgaGFzdCBlaW5lbiBmZWhsZXJoYWZ0ZW4gSW5uZW4tL0F1c3Nlbi0vU29ubmVubGljaHRyYXVtIGdlbWVsZGV0LlxuIik7CisKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfbG9jYWxjbWRzKCkKK3sKKyAgcmV0dXJuICh7ICh7InNvbm5lbmZlaGxlciIsICJfaW5kb29yYnVnIiwgMCwgMCB9KSB9KQorICAgICAgICAgICAgKyBiYXNlOjpfcXVlcnlfbG9jYWxjbWRzKCk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC9zaGVsbHMvZHdhcmYuYyBiL3N0ZC9zaGVsbHMvZHdhcmYuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43YTY5NmRjCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3NoZWxscy9kd2FyZi5jCkBAIC0wLDAgKzEsMTU2IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gc2hlbGxzL2R3YXJmLmMgLS0gRHdhcnZlbiBTaGVsbAorLy8KKy8vICRJZDogZHdhcmYuYyx2IDMuMTQgMjAwNC8xMi8xMyAxMjo1NDozMSBab29rIEV4cCAkCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzLHNhdmVfdHlwZXMKKworaW5oZXJpdCAic3RkL3BsYXllci9iYXNlIjsKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxhdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8aGVhbHRoLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8ZGVmdWVsLmg+CisKKwordm9pZCBjcmVhdGUoKXsKKyAgaWYgKCFjbG9uZXAoKSB8fCBvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSA9PSBfX0ZJTEVfX1swLi48M10pIHsKKyAgICAgIHNldF9uZXh0X3Jlc2V0KC0xKTsgICAgCisgICAgICByZXR1cm47CisgIH0KKworICBtaXhlZCByZXM7CisKKyAgYmFzZTo6Y3JlYXRlKCk7CisgIFNldERlZmF1bHRIb21lKCIvZC9nZWJpcmdlL3Jvb20vemthcGVsbGUiKTsKKyAgU2V0RGVmYXVsdFByYXlSb29tKCIvZC9nZWJpcmdlL3Jvb20vemthcGVsbGUiKTsKKyAgU2V0UHJvcChQX0FUVFJJQlVURVNfT0ZGU0VUUywoW0FfU1RSOjIsQV9ERVg6MSxBX0NPTjozXSkpOworICBTZXRQcm9wKFBfU0tJTExfQVRUUklCVVRFX09GRlNFVFMsKFtTQV9EVVJBVElPTjoxMTBdKSk7CisgIFNldFByb3AoUF9BVkVSQUdFX1NJWkUsMTIwKTsKKyAgU2V0UHJvcChQX0FWRVJBR0VfV0VJR0hULDc1MDAwKTsKKyAgU2V0UHJvcChQX01BVEVSSUFMX0tOT1dMRURHRSwoW01BVEdST1VQX1NUT05FOjMwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFUR1JPVVBfTUVUQUw6MzAsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFUR1JPVVBfUFJFQ0lPVVNfTUVUQUw6IDQwLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BVF9HT0xEOjEwMF0pKTsKKyAgU2V0UHJvcChQX1JFU0lTVEFOQ0VfU1RSRU5HVEhTLAorCSAgKFsgRFRfRklSRSA6IC0wLjIsCisJICAgRFRfV0FURVIgOiAwLjQgXSkpOworICBTZXRQcm9wKFBfTUFYX0FMQ09IT0wsMjAwKTsKKyAgU2V0UHJvcChQX01BWF9GT09ELDE2MCk7CisKKyAgU2V0UHJvcChQX1NQX0RFTEFZLEhFQUxfREVMQVkrMSk7CisgIFNldFByb3AoUF9QT0lTT05fREVMQVksUE9JU09OX0RFTEFZKzEpOworICBTZXRQcm9wKFBfRk9PRF9ERUxBWSxGT09EX0RFTEFZLTEpOworICBTZXRQcm9wKFBfQUxDT0hPTF9ERUxBWSxBTENPSE9MX0RFTEFZLTEpOworCisgIFNldFByb3AoUF9NQUdJQ19SRVNJU1RBTkNFX09GRlNFVCwKKyAgICAgICAgICAoWyBNVF9BTkdSSUZGIDogMjAwLAorCSAgIE1UX0lMTFVTSU9OIDogLTUwMCwKKyAgICAgICAgICAgTVRfQkVIRVJSU0NIVU5HIDogMTAwMCwKKwkgICBNVF9WRVJXQU5ETFVORyA6IDUwMCBdKSk7CisKKyAgaWYoIUlTX1NFRVIodGhpc19vYmplY3QoKSkpeworICAgIFNldFByb3AoUF9NU0dJTiwic3RhcGZ0IGhlcmVpbiIpOworICAgIFNldFByb3AoUF9NU0dPVVQsInN0YXBmdCIpOworICB9CisKKyAgaWYoIShyZXM9UXVlcnlQcm9wKFBfSEFORFMpKSB8fCAhcG9pbnRlcnAocmVzKSB8fCAoc2l6ZW9mKHJlcyk8MykpCisgICAgcmVzPSh7IiBtaXQgYmxvc3NlbiBIYWVuZGVuIiwzNSwoe0RUX0JMVURHRU9OfSkgfSk7CisgIHJlc1sxXT0zNTsKKyAgU2V0UHJvcChQX0hBTkRTLHJlcyk7CisgIFNldFByb3AoUF9CT0RZLDEwKTsKKworICAvKiBHcm9lc3NlIHdpcmQgbnVyIGVpbm1hbCBnZXNldHp0ICovCisgIGlmKCFRdWVyeVByb3AoUF9TSVpFKSl7CisgICAgU2V0UHJvcChQX1NJWkUsMTEwK3JhbmRvbSgyMSkpOworICAgIFNldChQX1NJWkUsU0FWRSxGX01PREVfQVMpOworICB9CisKKyAgLyogRGl0byBHZXdpY2h0ICovCisgIGlmKCFRdWVyeVByb3AoUF9XRUlHSFQpIHx8IChRdWVyeVByb3AoUF9XRUlHSFQpID09IDc1MDAwKSl7CisgICAgU2V0UHJvcChQX1dFSUdIVCw2NTAwMCtyYW5kb20oMjAwMDEpKTsKKyAgICBpZihRdWVyeVByb3AoUF9HRU5ERVIpPT1GRU1BTEUpCisgICAgICBTZXRQcm9wKFBfV0VJR0hULFF1ZXJ5UHJvcChQX1dFSUdIVCktNTAwMCk7CisgICAgU2V0KFBfV0VJR0hULFNBVkUsRl9NT0RFX0FTKTsKKyAgfQorCisgIFNldFByb3AoUF9ERUZVRUxfTElNSVRfRk9PRCw3MCk7CisgIFNldFByb3AoUF9ERUZVRUxfTElNSVRfRFJJTkssNTApOworICBTZXRQcm9wKFBfREVGVUVMX1RJTUVfRk9PRCw1MzUpOworICBTZXRQcm9wKFBfREVGVUVMX1RJTUVfRFJJTkssNTAwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9BTU9VTlRfRk9PRCwwLjgpOworICBTZXRQcm9wKFBfREVGVUVMX0FNT1VOVF9EUklOSywwLjYpOworCit9CisKK3N0cmluZyBfcXVlcnlfcmFjZSgpCit7CisgIHJldHVybiAiWndlcmciOworfQorCitzdHJpbmcgX3F1ZXJ5X3JlYWxfcmFjZSgpCit7CisgIHJldHVybiAiWndlcmciOworfQorCitzdHJpbmcgX3F1ZXJ5X3JhY2VkZXNjcigpCit7CisgIHJldHVybgorICAiWndlcmdlIHNpbmQga2xlaW5lIGFiZXIga3JhZWZ0aWdlIEdlYmlyZ3NiZXdvaG5lciwgbmljaHQgc2VociBnZXNwcmFlY2hpZyxcbiIKKyAgICArImxlaWNodCBlcnp1ZXJudCwgYWJlciBlaW5lIHNjaGxhZ2tyYWVmdGlnZSBVbnRlcnN0dWV0enVuZyBmdWVyIGlocmUgRnJldW5kZS4iCisgICAgKyJcbiIKKyAgICArIklociBNdXQgdW5kIGlocmUgU3RhbmRmZXN0aWdrZWl0IGlzdCB3ZWl0IHVuZCBicmVpdCBiZXJ1ZWhtdCwgYXVjaCBpaHJcbiIKKyAgICArIkdlc2NoaWNrIGltIFVtZ2FuZyBtaXQgWndlcmdlbndhZmZlbiB2ZXJsZWlodCBpaG5lbiB6dXNhZXR6bGljaGUgS3JhZnQuXG4iCisgICAgKyJMZWlkZXIgc2luZCBad2VyZ2UgbmljaHQgYWxsenUgc2NobGF1LCBzaWUgdmVybGFzc2VuIHNpY2ggbGllYmVyIGF1ZlxuIgorICAgICsiaWhyZSBLcmFmdCBhbHMgYXVmIGlociBHZWhpcm4uXG4iOworfQorCitpbnQgUXVlcnlBbGxvd1NlbGVjdCgpIHsgcmV0dXJuIDE7IH0KKworc3RyaW5nICpfcXVlcnlfcmFjZXN0cmluZygpCit7CisgIGlmIChRdWVyeVByb3AoUF9HRU5ERVIpPT0yKQorICAgIHJldHVybiAoeyJad2VyZ2luIiwiWndlcmdpbiIsIlp3ZXJnaW4iLCJad2VyZ2luIn0pOworICByZXR1cm4gKHsiWndlcmciLCJad2VyZ2VzIiwiWndlcmciLCJad2VyZyJ9KTsKK30KK2ludCBfcXVlcnlfaHBfZGVsYXkoKXsKKyAgaW50IHJlOworICByZSA9IFF1ZXJ5KFBfSFBfREVMQVkpOworICBpZiAoZW52aXJvbm1lbnQoKSAmJiBlbnZpcm9ubWVudCgpLT5RdWVyeVByb3AoUF9JTkRPT1JTKSkKKyAgICByZS0tOworICBlbHNlCisgICAgcmUrKzsKKyAgcmV0dXJuIHJlOworfQoraW50IF9xdWVyeV9zcF9kZWxheSgpeworICBpbnQgcmU7CisgIHJlID0gUXVlcnkoUF9TUF9ERUxBWSk7CisgIGlmIChlbnZpcm9ubWVudCgpICYmIGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX0lORE9PUlMpKQorICAgIHJlLS07CisgIGVsc2UKKyAgICByZSsrOworICByZXR1cm4gcmU7Cit9CisKK3N0cmluZyBfcXVlcnlfZGVmYXVsdF9ndWlsZCgpeworICByZXR1cm4gImFiZW50ZXVyZXIiOworfQorCittaXhlZCBSYWNlRGVmYXVsdChzdHJpbmcgYXJnKQoreworICBpZiAoIWFyZykKKyAgICByZXR1cm4gMDsKKyAgc3dpdGNoKGFyZykKKyAgeworICAgIGNhc2UgUF9IQU5EUyA6CisgICAgICByZXR1cm4gKHsiIG1pdCBibG9zc2VuIEhhZW5kZW4iLDM1LCh7RFRfQkxVREdFT059KSB9KTsKKyAgICBjYXNlIFBfQk9EWSA6CisgICAgICByZXR1cm4gMTA7CisgIH0KKyAgcmV0dXJuIDA7Cit9CmRpZmYgLS1naXQgYS9zdGQvc2hlbGxzL2VsZi5jIGIvc3RkL3NoZWxscy9lbGYuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZWM0MTE4Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3NoZWxscy9lbGYuYwpAQCAtMCwwICsxLDE1NCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHNoZWxscy9lbGYuYyAtLSBFbHZlbiBTaGVsbAorLy8KKy8vICRJZDogZWxmLmMgODkyOCAyMDE0LTA5LTA4IDE2OjE4OjQxWiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJvbmdfdHlwZXMsc2F2ZV90eXBlcworCitpbmhlcml0ICJzdGQvcGxheWVyL2Jhc2UiOworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGF0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxoZWFsdGguaD4KKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxjb21iYXQuaD4KKyNpbmNsdWRlIDxkZWZ1ZWwuaD4KKworCisKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgaWYgKCFjbG9uZXAoKSB8fCBvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSA9PSBfX0ZJTEVfX1swLi48M10pIHsKKyAgICAgIHNldF9uZXh0X3Jlc2V0KC0xKTsgICAgCisgICAgICByZXR1cm47CisgIH0KKworICBiYXNlOjpjcmVhdGUoKTsKKyAgU2V0RGVmYXVsdEhvbWUoIi9kL3dhbGQvcm9vbS9lc19taXR0ZSIpOworICBTZXREZWZhdWx0UHJheVJvb20oIi9kL3dhbGQvcm9vbS9lc19taXR0ZSIpOworICBTZXRQcm9wKFBfQVZFUkFHRV9TSVpFLDE5NSk7CisgIFNldFByb3AoUF9BVkVSQUdFX1dFSUdIVCw3MDAwMCk7CisgIFNldFByb3AoUF9TS0lMTF9BVFRSSUJVVEVfT0ZGU0VUUywoW1NBX0VORU1ZX1NBVkU6MTEwXSkpOworICBTZXRQcm9wKFBfQVRUUklCVVRFU19PRkZTRVRTLChbQV9JTlQ6MyxBX0RFWDoyLEFfQ09OOjFdKSk7CisgIFNldFByb3AoUF9NQVRFUklBTF9LTk9XTEVER0UsKFtNQVRHUk9VUF9XT09EOjMwLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BVEdST1VQX0hFUkJBTDozMCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQVRHUk9VUF9MSVZJTkc6MjBdKSk7CisKKyAgU2V0UHJvcChQX01BWF9GT09ELDgwKTsKKyAgU2V0UHJvcChQX01BWF9EUklOSywxNTApOworICBTZXRQcm9wKFBfTUFYX0FMQ09IT0wsNzApOworCisgIFNldFByb3AoUF9TUF9ERUxBWSxIRUFMX0RFTEFZLTEpOworICBTZXRQcm9wKFBfRk9PRF9ERUxBWSxGT09EX0RFTEFZKzEpOworICBTZXRQcm9wKFBfRFJJTktfREVMQVksRFJJTktfREVMQVktMik7CisgIFNldFByb3AoUF9BTENPSE9MX0RFTEFZLEFMQ09IT0xfREVMQVkrMSk7CisKKyAgU2V0UHJvcChQX01BR0lDX1JFU0lTVEFOQ0VfT0ZGU0VULAorICAgICAgICAgIChbIE1UX0lMTFVTSU9OIDogODAwLAorICAgICAgICAgICBNVF9BTkdSSUZGIDogMjAwLAorCSAgIE1UX1ZFUldBTkRMVU5HIDogNDAwLAorCSAgIE1UX1BTWUNITyA6IDUwMCBdKSk7CisKKyAgLy8gRWxmZW4ga3JpZWdlbiBkaWUgRWJlbmUgZGVyIFdpcGZlbGxhZXVmZXIgcGVyIGRlZmF1bHQuIChadSBkaWVzZW0KKyAgLy8gWmVpdHB1bmt0IHN0ZWhlbiBpbiBQX0NIQU5ORUxTIG51ciBkaWUgZGVmYXVsdCBjaGFubmVsIGRyaW4sIHdpcmQgZGFubgorICAvLyB1ZWJlciBkYXMgRWlubGVzZW4gZGVzIFNhdmVmaWxlcyBnZ2YuIHVlYmVyc2NocmllYmVuLikKKyAgU2V0UHJvcChQX0NIQU5ORUxTLCBRdWVyeVByb3AoUF9DSEFOTkVMUykgKyAoeyJ3aXBmZWxsYWV1ZmVyIn0pKTsKKworICBpZighSVNfU0VFUih0aGlzX29iamVjdCgpKSl7CisgICAgU2V0UHJvcChQX01TR0lOLCJ3YW5kZWx0IGhlcmVpbiIpOworICAgIFNldFByb3AoUF9NU0dPVVQsIndhbmRlbHQiKTsKKyAgfQorCisgIC8qIEdyb2Vzc2Ugd2lyZCBudXIgZWlubWFsIGdlc2V0enQgKi8KKyAgaWYoIVF1ZXJ5UHJvcChQX1NJWkUpKXsKKyAgICBTZXRQcm9wKFBfU0laRSwxODUrcmFuZG9tKDIxKSk7CisgICAgU2V0KFBfU0laRSxTQVZFLEZfTU9ERV9BUyk7CisgIH0KKworICAvKiBEaXRvIEdld2ljaHQgKi8KKyAgaWYoIVF1ZXJ5UHJvcChQX1dFSUdIVCkgfHwgKFF1ZXJ5UHJvcChQX1dFSUdIVCkgPT0gNzUwMDApKXsKKyAgICBTZXRQcm9wKFBfV0VJR0hULDYwMDAwK3JhbmRvbSgyMDAwMSkpOworICAgIGlmKFF1ZXJ5UHJvcChQX0dFTkRFUik9PUZFTUFMRSkKKyAgICAgIFNldFByb3AoUF9XRUlHSFQsUXVlcnlQcm9wKFBfV0VJR0hUKS01MDAwKTsKKyAgICBTZXQoUF9XRUlHSFQsU0FWRSxGX01PREVfQVMpOworICB9CisgIFNldFByb3AoUF9ERUZVRUxfTElNSVRfRk9PRCw0MCk7CisgIFNldFByb3AoUF9ERUZVRUxfTElNSVRfRFJJTkssMjApOworICBTZXRQcm9wKFBfREVGVUVMX1RJTUVfRk9PRCw0MDApOworICBTZXRQcm9wKFBfREVGVUVMX1RJTUVfRFJJTkssMjAwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9BTU9VTlRfRk9PRCwwLjQpOworICBTZXRQcm9wKFBfREVGVUVMX0FNT1VOVF9EUklOSywwLjM1KTsKKworfQorCitzdHJpbmcgX3F1ZXJ5X3JhY2UoKQoreworICByZXR1cm4gIkVsZiI7Cit9CisKK3N0cmluZyBfcXVlcnlfcmVhbF9yYWNlKCkKK3sKKyAgcmV0dXJuICJFbGYiOworfQorCitzdHJpbmcgX3F1ZXJ5X3JhY2VkZXNjcigpCit7CisgIHJldHVybiAKKyJcCitBbHMgRWxmZW4gYmV6ZWljaG5ldCBtYW4gaW4gZGVyIFJlZ2VsIGplbmUgaGFnZXJlbiBIaW50ZXJ3YWVsZGxlciwgZGVyZW5cblwKK2RlbW9uc3RyYXRpdmVzIE5hdHVyZ2VoYWJlIGluIGRlciBSZWdlbCBudXIgZHVyY2ggaWhyZSBMaWViZSB6dSBraXRzY2hpZ2VuXG5cCitHZWRpY2h0ZW4gdW5kIGF1c3NjaHdlaWZlbmRlbSBHZXNjaGxlY2h0c2xlYmVuIGluIGRlbiBTY2hhdHRlbiBnZXN0ZWxsdCB3aXJkLlxuXAorRWluZW4gRWxmIGthbm4gbWFuIGltIGFsbGdlbWVpbmVuIG5pY2h0IG51ciBhbiBhZXVzc2VyZW4gTWlzc2JpbGR1bmdlblxuXAorKHNwaXR6ZSBPaHJlbiwgc3BpbmRlbGR1ZXJyZSBHZXN0YWx0LCBibG9uZGUgSGFhcmUpIGVya2VubmVuLCBzb25kZXJuIGF1Y2hcblwKK2FuIHNlaW5lciBhdWZkcmluZ2xpY2hlbiBBcnQsIHVlYmVyIGplZGVuIHVuZCBhbGxlcyBoZW1tdW5nc2xvcyBpbnMgR3J1ZW5lXG5cCitsb3N6dXBoaWxvc29waGllcmVuLlxuIjsKKworfQorCitpbnQgUXVlcnlBbGxvd1NlbGVjdCgpIHsgcmV0dXJuIDE7IH0KKworc3RyaW5nICpfcXVlcnlfcmFjZXN0cmluZygpCit7CisgIGlmIChRdWVyeVByb3AoUF9HRU5ERVIpPT0yKQorICAgIHJldHVybiAoeyJFbGZlIiwiRWxmZSIsIkVsZmUiLCJFbGZlIn0pOworICByZXR1cm4gKHsiRWxmIiwiRWxmZW4iLCJFbGYiLCJFbGYifSk7Cit9CitpbnQgX3F1ZXJ5X2hwX2RlbGF5KCl7CisgIGludCByZTsKKyAgcmUgPSBRdWVyeShQX0hQX0RFTEFZKTsKKyAgaWYgKGVudmlyb25tZW50KCkgJiYgZW52aXJvbm1lbnQoKS0+UXVlcnlQcm9wKFBfSU5ET09SUykpCisgICAgcmUrKzsKKyAgZWxzZQorICAgIHJlLS07CisgIHJldHVybiByZTsKK30KK2ludCBfcXVlcnlfc3BfZGVsYXkoKXsKKyAgaW50IHJlOworICByZSA9IFF1ZXJ5KFBfU1BfREVMQVkpOworICBpZiAoZW52aXJvbm1lbnQoKSAmJiBlbnZpcm9ubWVudCgpLT5RdWVyeVByb3AoUF9JTkRPT1JTKSkKKyAgICByZSsrOworICBlbHNlCisgICAgcmUtLTsKKyAgcmV0dXJuIHJlOworfQorCitzdHJpbmcgX3F1ZXJ5X2RlZmF1bHRfZ3VpbGQoKXsKKyAgcmV0dXJuICJ3aXBmZWxsYWV1ZmVyIjsKK30KKworc3RhdGljIHZvaWQgRmluYWxTZXR1cCgpCit7CisgIGlmKFF1ZXJ5UHJvcChQX0dVSUxEKSAhPSAiY2hhb3MiKQorICAgIFNldFByb3AoUF9SRVNJU1RBTkNFX1NUUkVOR1RIUywKKyAgICAgICAgICAgIChbIERUX01BR0lDIDogLTAuMiwKKyAgICAgICAgICAgICAgIERUX0hPTFkgOiAwLjEsCisgICAgICAgICAgICAgICBEVF9VTkhPTFkgOiAwLjMgXSkpOworICBlbHNlCisgICAgU2V0UHJvcChQX1JFU0lTVEFOQ0VfU1RSRU5HVEhTLAorICAgICAgICAgICAgKFsgRFRfTUFHSUMgOiAtMC4yLAorICAgICAgICAgICAgICAgRFRfVU5IT0xZIDogMC4xLAorICAgICAgICAgICAgICAgRFRfSE9MWSA6IDAuMyBdKSk7Cit9CmRpZmYgLS1naXQgYS9zdGQvc2hlbGxzL2ZlbGluZS5jIGIvc3RkL3NoZWxscy9mZWxpbmUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNTkwZmFiCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3NoZWxscy9mZWxpbmUuYwpAQCAtMCwwICsxLDI1OSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHNoZWxscy9mZWxpbmUuYyAtLSBGZWxpbmUgU2hlbGwKKy8vCisvLyAkSWQ6IGZlbGluZS5jIDg0ODcgMjAxMy0wNS0yMSAxOToxNTo1MlogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzLHNhdmVfdHlwZXMKKworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvYmFzZSI7CisKKyNpbmNsdWRlIDxhdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8aGVhbHRoLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGRlZnVlbC5oPgorCisKK3ZvaWQgY3JlYXRlKCkKK3sgICAKKyAgICBpZiAoIWNsb25lcCgpIHx8IG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpID09IF9fRklMRV9fWzAuLjwzXSkgeworICAgICAgc2V0X25leHRfcmVzZXQoLTEpOyAgICAKKyAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBpbnQgICBpLGc7CisgICAgbWl4ZWQgaDsKKworICAgIGJhc2U6OmNyZWF0ZSgpOworCisvLyBTdGFydHJhdW0vS2FwZWxsZSBzZXR6ZW4KKyAgICBTZXREZWZhdWx0SG9tZSgiL2QvZHNjaHVuZ2VsL3BhcmFjZWxzdXMvcm9vbS9ma2FwZWxsZSIpOworICAgIFNldERlZmF1bHRQcmF5Um9vbSgiL2QvZHNjaHVuZ2VsL3BhcmFjZWxzdXMvcm9vbS9ma2FwZWxsZSIpOworCisvLyBCZXNvbmRlcmUgcmFzc2Vuc3BlemlmaXNjaGUgUHJvcGVydGllcyAoYmVpIGRlbmVuIGVzIG5pY2h0cyBtYWNodCwgd2VubgorLy8gc2llIG5hY2ggamVkZW0gRWlubG9nZ2VuIG5ldSBnZXNldHp0IHdlcmRlbik6CisKKyAgICBTZXRQcm9wKFBfQVRUUklCVVRFU19PRkZTRVRTLCAvLyBTdW1tZSA0IHN0YXR0IDYgd2cuIFNBX1NQRUVECisgICAgKFsKKyAgICAgICAgQV9TVFIgOiAgMSwKKyAgICAgICAgQV9JTlQgOiAgMiwKKyAgICAgICAgQV9ERVggOiAgMiwKKyAgICAgICAgQV9DT04gOiAtMSAKKyAgICBdKSApOworICAgIFNldFByb3AoUF9BVkVSQUdFX1NJWkUsMjAwKTsKKyAgICBTZXRQcm9wKFBfQVZFUkFHRV9XRUlHSFQsODUwMDApOworICAgIFNldFByb3AoUF9CT0RZLDE1KTsKKyAgICBTZXRQcm9wKFBfU0tJTExfQVRUUklCVVRFX09GRlNFVFMsKFtTQV9TUEVFRDoxMjBdKSk7CisgICAgU2V0UHJvcChQX01BVEVSSUFMX0tOT1dMRURHRSwKKyAgICAoWworICAgICAgICBNQVRHUk9VUF9XT09EICAgIDogIDYwLAorICAgICAgICBNQVRHUk9VUF9KRVdFTCAgIDogMTAwLAorICAgICAgICBNQVRHUk9VUF9FQVRBQkxFIDogIDMwCisgICAgXSkgKTsKKworICAgIFNldFByb3AoUF9NQUdJQ19SRVNJU1RBTkNFX09GRlNFVCwKKyAgICAoWworICAgICAgICBNVF9BTkdSSUZGICAgICA6ICAyMDAsCisgICAgICAgIE1UX0lMTFVTSU9OICAgIDogLTUwMCwKKyAgICAgICAgTVRfVkVSV0FORExVTkcgOiAgNTAwLAorICAgICAgICBNVF9QU1lDSE8gICAgICA6IDEwMDAgCisgICAgXSkgKTsKKworICAgIFNldFByb3AoUF9SRVNJU1RBTkNFX1NUUkVOR1RIUywKKyAgICAoWworICAgICAgICBEVF9XQVRFUiA6IC0wLjEsCisgICAgICAgIERUX0FDSUQgIDogIDAuMSwKKyAgICAgICAgRFRfQ09MRCAgOiAgMC4xIAorICAgIF0pICk7CisKKy8vIExlYmVuc3B1bmt0ZSB3ZXJkZW4gbGFuZ3NhbWVyIGFscyBub3JtYWwgcmVnZW5lcmllcnQKKyAgICBTZXRQcm9wKFBfSFBfREVMQVksSEVBTF9ERUxBWSsxKTsKKworLy8gTWFnaWVwdW5rdGUgd2VyZGVuIHNjaG5lbGxlciBhbHMgbm9ybWFsIHJlZ2VuZXJpZXJ0CisgICAgU2V0UHJvcChQX1NQX0RFTEFZLEhFQUxfREVMQVktMSk7CisKKy8vIEdpZnQgd2lya3QgZXR3YXMgbGFuZ3NhbWVyIGFscyBub3JtYWwKKyAgICBTZXRQcm9wKFBfUE9JU09OX0RFTEFZLFBPSVNPTl9ERUxBWSsxKTsKKworLy8gR2V0cmFlbmtlIHdlcmRlbiBldHdhcyBzY2huZWxsZXIgYWxzIG5vcm1hbCBhYmdlYmF1dAorICAgIFNldFByb3AoUF9EUklOS19ERUxBWSxEUklOS19ERUxBWS0xKTsKKworLy8gRXNzZW4gd2lyZCBldHdhcyBzY2huZWxsZXIgYWxzIG5vcm1hbCBhYmdlYmF1dCAuLi4KKyAgICBTZXRQcm9wKFBfRk9PRF9ERUxBWSxGT09EX0RFTEFZLTEpOworICAgIFNldFByb3AoUF9NQVhfRk9PRCwxNDApOworCisvLyBFcyBnaWJ0IGVpbmlnZSBTYWNoZW4sIGRpZSBzb2xsZW4gbnVyIGJlaW0gZXJzdGVuIEVpbmxvZ2dlbiBnZXNldHp0IHdlcmRlbi4KKy8vIEFuZGVyZSBtdWVzc2VuIG5hY2h0cmFlZ2xpY2ggLSBhYmVyIG51ciBlaW5tYWwgLSBnZW1hY2h0IHdlcmRlbiwgd2VpbCBzaWNoCisvLyBldHdhcyBnZWFlbmRlcnQgaGF0LgorICAgIHN3aXRjaCggUXVlcnlQcm9wKFBfU0hFTExfVkVSU0lPTikgKQorICAgIHsKKyAgICAgICAgY2FzZSAwIDoKKworICAgICAgICAgICAgZz1RdWVyeVByb3AoUF9HRU5ERVIpOworCisgICAgICAgICAgICBpZiAoICEoaT1RdWVyeVByb3AoUF9TSVpFKSkgfHwgKGk8KGc9PUZFTUFMRT8xNjU6MTcwKSkgCisgICAgICAgICAgICAgICAgfHwgKGk+KGc9PUZFTUFMRT8yMjU6MjMwKSkgKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIFNldFByb3AoUF9TSVpFLCAoZz09RkVNQUxFPzE5NToyMDApCisgICAgICAgICAgICAgICAgICAgICsgcmFuZG9tKDE2KSAtIHJhbmRvbSgxNikgKyByYW5kb20oMTYpIC0gcmFuZG9tKDE2KSApOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiggIShpPVF1ZXJ5UHJvcChQX1dFSUdIVCkpIHx8IChpPChnPT1GRU1BTEU/NzAwMDA6NzcwMDApKSAKKyAgICAgICAgICAgICAgIHx8IChpPihnPT1GRU1BTEU/ODgwMDA6OTUwMDApKSB8fCAoaT09NzUwMDApICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBTZXRQcm9wKFBfV0VJR0hULCAoZz09RkVNQUxFPzcwMDAwOjc3MDAwKQorICAgICAgICAgICAgICAgICAgICArIHJhbmRvbSg0NTAxKSArIHJhbmRvbSg0NTAxKSArIHJhbmRvbSg0NTAxKSArIHJhbmRvbSg0NTAxKSApOworICAgICAgICAgICAgfQorCisKKyAgICAgICAgICAgIFNldFByb3AoUF9NQVRFUklBTCwoWworICAgICAgICAgICAgICAgIE1BVF9NSVNDX0xJVklORyA6IDkwLAorICAgICAgICAgICAgICAgIE1BVF9QRUxUICAgICAgICA6ICA4LAorICAgICAgICAgICAgICAgIE1BVF9IT1JOICAgICAgICA6ICAyCisgICAgICAgICAgICBdKSApOworCisgICAgICAgICAgICBpZiAoICFJU19TRUVSKHRoaXNfb2JqZWN0KCkpICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBTZXRQcm9wKFBfTVNHSU4sInNjaGxlaWNodCBoZXJlaW4iKTsKKyAgICAgICAgICAgICAgICBTZXRQcm9wKFBfTVNHT1VULCJzY2hsZWljaHQiKTsKKyAgICAgICAgICAgICAgICBTZXRQcm9wKFBfTU1TR0lOLCJlcnNjaGVpbnQgbWl0IGVpbmVtIGdyZWxsZW4gQmxpdHoiKTsKKyAgICAgICAgICAgICAgICBTZXRQcm9wKFBfTU1TR09VVCwidmVyc2Nod2luZGV0IG1pdCBlaW5lbSBncmVsbGVuIEJsaXR6Iik7CisgICAgICAgICAgICAgICAgU2V0UHJvcChQX0hBTkRTLCh7IiBtaXQgc2NoYXJmZW4gS3JhbGxlbiIsNDAsICh7RFRfUklQfSkgfSkpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIGlmICggIXBvaW50ZXJwKGg9UXVlcnlQcm9wKFBfSEFORFMpKSB8fCAoc2l6ZW9mKGgpPDEpICkKKyAgICAgICAgICAgICAgICAgICAgaCA9ICh7IiBtaXQgc2NoYXJmZW4gS3JhbGxlbiIsNDAsICh7RFRfUklQfSkgfSk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBoID0gKHtoWzBdLDQwLCAoe0RUX1JJUH0pIH0pOworICAgICAgICAgICAgICAgIFNldFByb3AoUF9IQU5EUywgaCk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGlmICggIXBvaW50ZXJwKGg9UXVlcnlQcm9wKFBfQ0hBTk5FTFMpKSApCisgICAgICAgICAgICAgICAgU2V0UHJvcChQX0NIQU5ORUxTLCh7ImthdHplbmtyaWVnZXIifSkpOworICAgICAgICAgICAgZWxzZSBpZiAoIG1lbWJlcihoLCJrYXR6ZW5rcmllZ2VyIik9PS0xICkKKyAgICAgICAgICAgICAgICBTZXRQcm9wKFBfQ0hBTk5FTFMsIGggKyAoeyJrYXR6ZW5rcmllZ2VyIn0pICk7CisKKyAgICAgICAgICAgIFNldChQX1NJWkUsU0FWRSxGX01PREVfQVMpOworICAgICAgICAgICAgU2V0KFBfTUFURVJJQUwsU0FWRSxGX01PREVfQVMpOworICAgICAgICAgICAgU2V0KFBfV0VJR0hULFNBVkUsRl9NT0RFX0FTKTsKKworICAgICAgICBkZWZhdWx0IDoKKworICAgICAgICAgICAgU2V0UHJvcChQX1NIRUxMX1ZFUlNJT04sMSk7CisgICAgfQorICBTZXRQcm9wKFBfREVGVUVMX0xJTUlUX0ZPT0QsNzApOworICBTZXRQcm9wKFBfREVGVUVMX0xJTUlUX0RSSU5LLDQwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9USU1FX0ZPT0QsNDAwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9USU1FX0RSSU5LLDMwMCk7CisgIFNldFByb3AoUF9ERUZVRUxfQU1PVU5UX0ZPT0QsMC41NSk7CisgIFNldFByb3AoUF9ERUZVRUxfQU1PVU5UX0RSSU5LLDAuNCk7CisKK30KKworLy8gRGllc2UgUmFzc2Uga2FubiBkZXJ6ZWl0IGdld2FlaGx0IHdlcmRlbjoKK2ludCBRdWVyeUFsbG93U2VsZWN0KCkgeyByZXR1cm4gMTsgfQorCisvLyBSYXNzZW5iZXplaWNobnVuZworc3RyaW5nIF9xdWVyeV9yYWNlKCkKK3sKKyAgICByZXR1cm4gIkZlbGluZSI7Cit9CisKK3N0cmluZyBfcXVlcnlfcmVhbF9yYWNlKCkKK3sKKyAgICByZXR1cm4gIkZlbGluZSI7Cit9CisKKy8vIERpZSBSYXNzZW5iZXNjaHJlaWJ1bmcsIGRpZSBtYW4gYmVpbSBlcnN0ZW4gRWlubG9nZ2VuIGFicnVmZW4ga2Fubi4KK3N0cmluZyBfcXVlcnlfcmFjZWRlc2NyKCkKK3sKKyAgICByZXR1cm4gYnJlYWtfc3RyaW5nKAorICAgICAgICAiRmVsaW5lbiBzaW5kIGF1ZnJlY2h0IGdlaGVuZGUgS2F0emVud2VzZW4uXG4iKworICAgICAgICAiSWhyZSBIZWltYXQgaXN0IGRlciBEc2NodW5nZWwuIEthdW0gamVtYW5kIGR1ZXJmdGUgc2ljaCBkb3J0ICIrCisgICAgICAgICJiZXNzZXIgenVyZWNodGZpbmRlbiBhbHMgc2llLiBCZWRpbmd0IGR1cmNoIGRpZXNlIFVtZ2VidW5nICIrCisgICAgICAgICJoYWJlbiBzaWUgaW0gTGF1ZmUgZGVyIFplaXQgZWluZSBWb3JsaWViZSBmdWVyIGVsZWdhbnRlIEhvZWx6ZXIgIisKKyAgICAgICAgInVuZCBmdW5rZWxuZGUgRWRlbHN0ZWluZSBlbnR3aWNrZWx0LiBTaWUgc2luZCB6d2FyIG5pY2h0IHNvICIrCisgICAgICAgICIncmFmZmdpZXJpZycgd2llIFp3ZXJnZSwgYWJlciBkZW5ub2NoIHNvbGx0ZSBtYW4gYmVzc2VyIG5pY2h0ICIrCisgICAgICAgICJ2ZXJzdWNoZW4sIGVpbmVtIEZlbGluZW4gZWluZW4gRWRlbHN0ZWluIHdlZ3p1bmVobWVuLiBTaWUgIisKKyAgICAgICAgImJlbnV0emVuIGRpZSBFZGVsc3RlaW5lIHNlaHIgZ2VybmUsIHVtIHNpY2ggZGFtaXQgenUgc2NobXVlY2tlbi4gIisKKyAgICAgICAgIkZlbGluZW4gYmV0cmVpYmVuIHNvZ2FyIGVpbmVuIHJlZ2VscmVjaHRlbiBLb2VycGVya3VsdCwgIisKKyAgICAgICAgImluc2Jlc29uZGVyZSB3ZW5uIGVzIGRhcnVtIGdlaHQsIGRhcyBGZWxsIG9kZXIgZGllIEtyYWxsZW4genUgIisKKyAgICAgICAgImZhZXJiZW4uIEVkZWxzdGVpbmUga29tbWVuIGRhIGFscyBBY2Nlc3NvaXJlcyBnZXJhZGUgcmVjaHQuXG4iKworICAgICAgICAiQXVjaCBpbSBLYW1wZiBnZWdlbiBlaW5lbiBGZWxpbmVuIHNvbGx0ZSBtYW4gc2VociB2b3JzaWNodGlnICIrCisgICAgICAgICJzZWluLCBkYSBGZWxpbmVuIGlocmUgZ2VyaW5nZSBBdXNkYXVlciBkdXJjaCBlaW5lIGhvaGUgIisKKyAgICAgICAgIkdlc2Nod2luZGlna2VpdCBzb3dpZSBHZXNjaGljayB1bmQgSW50ZWxsaWdlbnogd2V0dG1hY2hlbi4gIisKKyAgICAgICAgIkF1Y2ggZGllIFNwaXR6ZW4gS3JhbGxlbiBzaW5kIGRhIG5pY2h0IHp1IHZlcmFjaHRlbiB1bmQgc28gIisKKyAgICAgICAgIm1hbmNoZXIgR2VnbmVyIG11c3N0ZSBzY2hvbiBhbHMgRXJzYXR6IGZ1ZXIgZWluZW4gS3JhdHpiYXVtICIrCisgICAgICAgICJoZXJoYWx0ZW4uIiw3OCwwLDEpOworfQorCisvLyBHZXNjaGxlY2h0c2FiaGFlbmdpZ2VzIFJhc3NlbmJlemVpY2hudW5ncy1BcnJheQorc3RyaW5nICpfcXVlcnlfcmFjZXN0cmluZygpCit7CisgICAgaWYgKFF1ZXJ5UHJvcChQX0dFTkRFUik9PTIpCisgICAgICAgIHJldHVybiAoeyJGZWxpbmluIiwiRmVsaW5pbiIsIkZlbGluaW4iLCJGZWxpbmluIn0pOworICAgIHJldHVybiAoeyJGZWxpbmUiLCJGZWxpbmVuIiwiRmVsaW5lbiIsIkZlbGluZW4ifSk7Cit9CisKKy8vIFJlZ2VuZXJhdGlvbiBkZXIgTGViZW5zcHVua3RlIGlzdCB2b24gZGVyIFVtZ2VidW5nIGFiaGFlbmdpZworLy8gSW0gV2FsZCB1bmQgRHNjaHVuZ2VsIGdlaHQgZXMgc2NobmVsbGVyLCBpbiBkZXIgV3Vlc3RlIHVuZCBpbQorLy8gUG9sYXJnZWJpZXQgZGFnZWdlbiBsYW5nc2FtZXIuCitpbnQgX3F1ZXJ5X2hwX2RlbGF5KCkKK3sKKyAgICBpbnQgcmU7CisgICAgc3RyaW5nIGZuOworCisgICAgcmUgPSBRdWVyeShQX0hQX0RFTEFZKTsKKyAgICBpZiAoZW52aXJvbm1lbnQoKSAmJiAhKGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX0lORE9PUlMpKSAmJgorICAgICAgICBmbj1vYmplY3RfbmFtZShlbnZpcm9ubWVudCgpKSkKKyAgICB7CisgICAgICAgIGlmIChmblswLi4xMl09PSIvZC9kc2NodW5nZWwvIiB8fCBmblswLi43XT09Ii9kL3dhbGQvIikKKyAgICAgICAgICAgIHJlLS07CisgICAgICAgIGVsc2UgaWYgKGZuWzAuLjldPT0iL2Qvd3Vlc3RlLyIgfHwgZm5bMC4uOF09PSIvZC9wb2xhci8iKQorICAgICAgICAgICAgcmUrKzsKKyAgICB9CisgICAgcmV0dXJuIHJlOworfQorCisvLyBSZWdlbmVyYXRpb24gZGVyIE1hZ2llcHVua3RlIGlzdCB2b24gZGVyIFVtZ2VidW5nIGFiaGFlbmdpZworLy8gSW0gV2FsZCB1bmQgRHNjaHVuZ2VsIGdlaHQgZXMgc2NobmVsbGVyLCBpbiBkZXIgV3Vlc3RlIHVuZCBpbQorLy8gUG9sYXJnZWJpZXQgZGFnZWdlbiBsYW5nc2FtZXIuCitpbnQgX3F1ZXJ5X3NwX2RlbGF5KCkKK3sKKyAgICBpbnQgcmU7CisgICAgc3RyaW5nIGZuOworCisgICAgcmUgPSBRdWVyeShQX1NQX0RFTEFZKTsKKyAgICBpZiAoZW52aXJvbm1lbnQoKSAmJiAhKGVudmlyb25tZW50KCktPlF1ZXJ5UHJvcChQX0lORE9PUlMpKSAmJgorICAgICAgICBmbj1vYmplY3RfbmFtZShlbnZpcm9ubWVudCgpKSkKKyAgICB7CisgICAgICAgIGlmIChmblswLi4xMl09PSIvZC9kc2NodW5nZWwvIiB8fCBmblswLi43XT09Ii9kL3dhbGQvIikKKyAgICAgICAgICAgIHJlLS07CisgICAgICAgIGVsc2UgaWYgKGZuWzAuLjldPT0iL2Qvd3Vlc3RlLyIgfHwgZm5bMC4uOF09PSIvZC9wb2xhci8iKQorICAgICAgICAgICAgcmUrKzsKKyAgICB9CisgICAgcmV0dXJuIHJlOworfQorCitzdHJpbmcgX3F1ZXJ5X2RlZmF1bHRfZ3VpbGQoKXsKKyAgcmV0dXJuICJrYXR6ZW5rcmllZ2VyIjsKK30KKworbWl4ZWQgUmFjZURlZmF1bHQoc3RyaW5nIGFyZykKK3sKKyAgICBpZiAoIWFyZykKKyAgICAgIHJldHVybiAwOworICAgIHN3aXRjaChhcmcpCisgICAgeworICAgICAgICBjYXNlIFBfSEFORFMgOgorICAgICAgICAgICAgcmV0dXJuICh7IiBtaXQgc2NoYXJmZW4gS3JhbGxlbiIsNDAsICh7RFRfUklQfSkgfSk7CisgICAgICAgIGNhc2UgUF9CT0RZIDoKKyAgICAgICAgICAgIHJldHVybiAxNTsKKyAgICB9CisgICAgcmV0dXJuIGJhc2U6OlJhY2VEZWZhdWx0KGFyZyk7Cit9CmRpZmYgLS1naXQgYS9zdGQvc2hlbGxzL2dvYmxpbi5jIGIvc3RkL3NoZWxscy9nb2JsaW4uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lZDY5NGIzCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3NoZWxscy9nb2JsaW4uYwpAQCAtMCwwICsxLDIxMyBAQAorLyoKKyAqIEdvYmxpbi1SYXNzZW5zaGVsbAorICogWy9zdGQvc2hlbGxzL2dvYmxpbi5jXQorICogKGMpIDIwMDcgbmliZWxAbWcubXVkLmRlCisgKgorICogV2VydGUgdm9uIEFyayBhYmdlc2VnbmV0IGFtIDExLjEyLjIwMDcKKyAqLworCisjcHJhZ21hIHN0cm9uZ190eXBlcyxzYXZlX3R5cGVzCisKKyNpbmNsdWRlIDxhdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8aGVhbHRoLmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxkZWZ1ZWwuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKworaW5oZXJpdCAiL3N0ZC9wbGF5ZXIvYmFzZS5jIjsKKworc3RhdGljIHZhcmFyZ3MgaW50IEdvYmxpbkNtZFdhYWFnaChzdHJpbmcgYXJnKTsKKworcHVibGljIHZvaWQgY3JlYXRlKCkgeworICBtaXhlZCByZXM7CisgIGJhc2U6OmNyZWF0ZSgpOworCisgIFNldERlZmF1bHRIb21lKCIvZC93YWxkL2tlc3NhL3dhYWFnaC9yb29tL3N0YXJ0aHV0L2h1dFsiICsgCisgICAgZ2V0dWlkKHRoaXNfb2JqZWN0KCkpICsiXSIpOworICBTZXREZWZhdWx0UHJheVJvb20oIi9kL3dhbGQvbmliZWwvbGljaHR1bmcvcm9vbS9saWNodHVuZ180NSIpOworICAKKyAgU2V0UHJvcChQX0FWRVJBR0VfU0laRSwgODApOworICBTZXRQcm9wKFBfQVZFUkFHRV9XRUlHSFQsIDMyMDAwKTsKKyAgU2V0UHJvcChQX01BVEVSSUFMX0tOT1dMRURHRSwgKFtNQVRHUk9VUF9FQVRBQkxFOjIwLCBNQVRHUk9VUF9EUlVHOjQwLAorICAgIE1BVEdST1VQX1BSRUNJT1VTX01FVEFMOjI1LCBNQVRHUk9VUF9KRVdFTDoyNV0pKTsKKworICBTZXRQcm9wKFBfQk9EWSwgMTUpOworICBTZXRQcm9wKFBfQVRUUklCVVRFU19PRkZTRVRTLCAoW0FfU1RSOjAsIEFfSU5UOjEsIEFfREVYOjIsIEFfQ09OOjJdKSk7CisgIFNldFByb3AoUF9SRVNJU1RBTkNFX1NUUkVOR1RIUywgKFtEVF9GSVJFOi0wLjE1LCBEVF9MSUdIVE5JTkc6LTAuMTUsCisgICAgRFRfU09VTkQ6MC4xLCBEVF9IT0xZOjAuMSwgRFRfQUlSOjAuMSwgRFRfQUNJRDowLjFdKSk7CisgIFNldFByb3AoUF9NQUdJQ19SRVNJU1RBTkNFX09GRlNFVCwgKFtNVF9BTkdSSUZGOjYwMCwgTVRfSUxMVVNJT046NTAwLAorICAgIE1UX1ZFUldBTkRMVU5HOi0zMDAsIE1UX0hFTExTSUNIVDotNzUwLCBNVF9CRUhFUlJTQ0hVTkc6MjUwXSkpOworICBTZXRQcm9wKFBfU0tJTExfQVRUUklCVVRFX09GRlNFVFMsIChbU0FfRU5FTVlfU0FWRToxMDMsIFNBX0RBTUFHRToxMDddKSk7CisKKyAgU2V0UHJvcChQX1NQX0RFTEFZLCBIRUFMX0RFTEFZICsgMik7CisgIFNldFByb3AoUF9IUF9ERUxBWSwgSEVBTF9ERUxBWSAtIDEpOworICBTZXRQcm9wKFBfQUxDT0hPTF9ERUxBWSwgQUxDT0hPTF9ERUxBWSAtIDEpOworCisgIHN3aXRjaChRdWVyeVByb3AoUF9TSEVMTF9WRVJTSU9OKSkgeworICAgIGNhc2UgMDoKKyAgICAgIGlmKCFRdWVyeVByb3AoUF9TSVpFKSkgLy8gTWFlbm5sZWluIHVuZCBXZWlibGVpbiBzaW5kIGdsZWljaCAiZ3Jvc3MiCisgICAgICAgIFNldFByb3AoUF9TSVpFLCA3NSArIHJhbmRvbSgxMSkpOworICAgICAgaWYoUXVlcnlQcm9wKFBfV0VJR0hUKSA9PSA3NTAwMCkgLy8gRGl0byBHZXdpY2h0CisgICAgICAgIFNldFByb3AoUF9XRUlHSFQsIChRdWVyeVByb3AoUF9TSVpFKSAqIDM5MCkgKworICAgICAgICAgIHJhbmRvbShRdWVyeVByb3AoUF9TSVpFKSAqIDEwKSk7CisgICAgICBTZXRQcm9wKFBfTUFURVJJQUwsKFtNQVRfTUlTQ19MSVZJTkc6MTAwXSkpOworICAgICAgICAgIAorICAgICAgU2V0KFBfU0laRSwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgICAgIFNldChQX1dFSUdIVCwgU0FWRSwgRl9NT0RFX0FTKTsKKyAgICAgIFNldChQX01BVEVSSUFMLCBTQVZFLCBGX01PREVfQVMpOworCisgICAgICBpZighcG9pbnRlcnAocmVzID0gUXVlcnlQcm9wKFBfSEFORFMpKSB8fCBzaXplb2YocmVzKSA8IDMpCisgICAgICAgIHJlcyA9ICh7IiBtaXQga2xlaW5lbiBGYWV1c3RjaGVuIiwgMzAsICh7IERUX0JMVURHRU9OIH0pfSk7CisgICAgICBTZXRQcm9wKFBfSEFORFMsIHJlcyk7CisKKyAgICAgIGlmKCFJU19TRUVSKHRoaXNfb2JqZWN0KCkpKSB7CisgICAgICAgIFNldFByb3AoUF9NU0dJTiwgImZsaXR6dCBoZXJlaW4iKTsKKyAgICAgICAgU2V0UHJvcChQX01TR09VVCwgImZsaXR6dCIpOworICAgICAgfQorICAgICAgU2V0UHJvcChQX1NIRUxMX1ZFUlNJT04sIDEpOworICAgIGNhc2UgMToKKyAgICAgIC8vIC9zdGQvcGxheWVyL2Jhc2Ugc2V0enQgamEgc2Nob24gUF9XRUlHSFQuLi4KKyAgICAgIGlmKFF1ZXJ5UHJvcChQX1dFSUdIVCkgPT0gNzUwMDApIHsKKyAgICAgICAgU2V0UHJvcChQX1dFSUdIVCwgKFF1ZXJ5UHJvcChQX1NJWkUpICogMzkwKSArCisgICAgICAgICAgcmFuZG9tKFF1ZXJ5UHJvcChQX1NJWkUpICogMTApKTsKKyAgICAgIH0KKyAgICAgIFNldFByb3AoUF9TSEVMTF9WRVJTSU9OLCAyKTsKKyAgICBkZWZhdWx0OiBicmVhazsKKyAgfQorICAKKyAgU2V0UHJvcChQX01BWF9GT09ELCAxMTApOworICBTZXRQcm9wKFBfTUFYX0RSSU5LLCA4MCk7CisgIFNldFByb3AoUF9NQVhfQUxDT0hPTCwgMTI1KTsKKyAgU2V0UHJvcChQX0RFRlVFTF9MSU1JVF9GT09ELCA2MCk7CisgIFNldFByb3AoUF9ERUZVRUxfTElNSVRfRFJJTkssIDYwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9USU1FX0ZPT0QsIDQwMCk7CisgIFNldFByb3AoUF9ERUZVRUxfVElNRV9EUklOSywgMzYwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9BTU9VTlRfRk9PRCwgMC41KTsKKyAgU2V0UHJvcChQX0RFRlVFTF9BTU9VTlRfRFJJTkssIDAuNCk7Cit9CisKK3N0YXRpYyB2b2lkIEZpbmFsU2V0dXAoKSB7CisgIG9iamVjdCBvOworICBpZihRdWVyeVByb3AoUF9MRVZFTCkgPiA1IHx8IHByZXNlbnQoIlxuaWJlbDp3YWxkbGljaHR1bmdza2FydGUiLAorICAgIHRoaXNfb2JqZWN0KCkpKSByZXR1cm47CisgIGlmKCFjYXRjaChvID0gY2xvbmVfb2JqZWN0KCIvZC93YWxkL25pYmVsL2xpY2h0dW5nL29iai9rYXJ0ZSIpKSkKKyAgICBvLT5tb3ZlKHRoaXNfb2JqZWN0KCksIE1fTk9DSEVDSyk7Cit9CisKK3B1YmxpYyBpbnQgUXVlcnlBbGxvd1NlbGVjdCgpIHsgcmV0dXJuIDE7IH0KKworcHVibGljIHN0cmluZyBfcXVlcnlfcmFjZSgpIHsgcmV0dXJuICJHb2JsaW4iOyB9CitwdWJsaWMgc3RyaW5nIF9xdWVyeV9yZWFsX3JhY2UoKSB7IHJldHVybiAiR29ibGluIjsgfQorCitwdWJsaWMgc3RyaW5nIF9xdWVyeV9yYWNlZGVzY3IoKSB7CisgIHJldHVybiBicmVha19zdHJpbmcoIkdvYmxpbnMgc2luZCB3aW56aWdlLCBncnVlbmhhZXV0aWdlIFdlc2VuLCBzb2dhciAiCisgICAgIm5vY2gga2xlaW5lciBhbHMgSG9iYml0cy4gQW4gaWhyZW4genUgZGljayBnZXJhdGVuZW4gS29lcGZjaGVuICIKKyAgICAiYmVmaW5kZW4gc2ljaCBsYW5nZSwgc2VsdGVuIHJlZ2xvc2UsIE9ocmVuIHVuZCBlaW5lIGdyb3NzZSwga3J1bW1lICIKKyAgICAiTmFzZS4gSWhyZSBrbGVpbmUgU3RhdHVyIHNvbGx0ZSBqZWRvY2ggbmljaHQgdGFldXNjaGVuLCBkZW5uIGlocmUgIgorICAgICJmZWhsZW5kZSBLcmFmdCBtYWNoZW4gc2llIG1pdCBHZXNjaHdpbmRpZ2tlaXQsIFByYWV6aXNpb24gdW5kIG5pY2h0ICIKKyAgICAienVsZXR6dCBpaHJlciB1bmJlc3RyaXR0ZW5lbiBSdWNobG9zaWdrZWl0IGFsbGV3ZWlsIHdldHQuIE9id29obCAiCisgICAgImZ1ZXIgc2llIFBsdWVuZGVybiwgbGF1dGVzIEhlcnVtYnJ1ZWxsZW4gdW5kIGRpZSBnZW1laW5zdGVuIFN0cmVpY2hlICIKKyAgICAic3BpZWxlbiB6dW0gQWxsdGFnIGdlaG9lcnQsIHd1ZXJkZSBzaWUgbmllbWFuZCBhbHMgYm9lc2FydGlnICIKKyAgICAiYmV6ZWljaG5lbi4gRGVubiBHb2JsaW5zIHNpbmQgdmllbGVzLCBhYmVyIHNpY2hlcmxpY2ggbmljaHQgZGllICIKKyAgICAiaW50ZWxsaWdlbnRlc3RlbiBLcmVhdHVyZW4uIER1cmNoIGlocmVuIHphZWhlbiBXaWxsZW4gdW5kIGRpZSBkaWNrZSwgIgorICAgICJsZWRlcm5lIEhhdXQgc2luZCBzaWUgYXVzc2VyZ2V3b2VobmxpY2ggd2lkZXJzdGFuZHNmYWVoaWcsIHVuZCwgIgorICAgICJzb2Zlcm4gZnVua2VsbmRlIEJldXRlIHdpbmt0LCBmdWVyIGplZGVzIEFiZW50ZXVlciB6dSBoYWJlbi4iLCA3OCk7Cit9CisKK3B1YmxpYyBzdHJpbmcgKl9xdWVyeV9yYWNlc3RyaW5nKCkgeworICBpZihRdWVyeVByb3AoUF9HRU5ERVIpID09IEZFTUFMRSkKKyAgICByZXR1cm4gKHsiR29ibGluZnJhdSIsICJHb2JsaW5mcmF1IiwgIkdvYmxpbmZyYXUiLCAiR29ibGluZnJhdSJ9KTsKKyAgcmV0dXJuICh7IkdvYmxpbiIsICJHb2JsaW5zIiwgIkdvYmxpbiIsICJHb2JsaW4ifSk7Cit9CisKK3B1YmxpYyBzdHJpbmcgX3F1ZXJ5X2RlZmF1bHRfZ3VpbGQoKSB7cmV0dXJuICJhYmVudGV1cmVyIjt9CisKK3B1YmxpYyBzdHJpbmcgX3F1ZXJ5X3Zpc2libGVfZ3VpbGQoKSB7CisgIHN3aXRjaChsb3dlcl9jYXNlKFF1ZXJ5UHJvcChQX0dVSUxEKSkpIHsKKyAgICBjYXNlICJhYmVudGV1cmVyIjogcmV0dXJuICJhYmVudG9pcmEiOworICAgIGNhc2UgIndpcGZlbGxhZXVmZXIiOiByZXR1cm4gIndpZmZlbGxvaWZhIjsKKyAgICBjYXNlICJjaGFvcyI6IHJldHVybiAia2FvcyI7CisgICAgY2FzZSAiemF1YmVyZXIiOiByZXR1cm4gInphdWJhcmEiOworICAgIGNhc2UgImJpZXJzY2h1ZXR0bGVyIjogcmV0dXJuICJiaWFzY2h1ZXR0bGEiOworICAgIGNhc2UgImthdHplbmtyaWVnZXIiOiByZXR1cm4gImthem5rcmllZ2EiOworCSAgY2FzZSAidGFuamlhbiI6IHJldHVybiAidGFuc2NoYW4iOworCSAgY2FzZSAia2xlcnVzIjogcmV0dXJuICJrbGVyaWthZSI7CSAgCQorCSAgY2FzZSAiZHVua2VsZWxmZW4iOiByZXR1cm4gImR1bmtsZWxmbiI7CisJICBjYXNlICJrYWVtcGZlciI6IHJldHVybiAia2FlbXBmYSI7CisJICBjYXNlICJrYXJhdGUiOiByZXR1cm4gImthcmF0YWUiOworCSAgY2FzZSAid2Vyd29lbGZlIjogcmV0dXJuICJ3ZWF3b2VsZiI7CisJICBjYXNlICJtYWd1cyI6IHJldHVybiAibWFnaWEiOworICAgIGNhc2UgInVydWtoYWkiOiByZXR1cm4gInVydWdhaSI7CisgIH0KKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX0dVSUxEKTsKK30KKworcHVibGljIG1peGVkIFJhY2VEZWZhdWx0KHN0cmluZyBhcmcpIHsKKyAgaWYoIWFyZykgcmV0dXJuIDA7CisgIHN3aXRjaChhcmcpIHsKKyAgICBjYXNlIFBfSEFORFM6CisgICAgICByZXR1cm4gKHsiIG1pdCBrbGVpbmVuIEZhZXVzdGNoZW4iLCAzMCwgKHsgIERUX0JMVURHRU9OIH0pfSk7CisgICAgY2FzZSBQX0JPRFk6CisgICAgICByZXR1cm4gMTU7CisgIH0KKyAgcmV0dXJuIGJhc2U6OlJhY2VEZWZhdWx0KGFyZyk7Cit9CisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfbG9jYWxjbWRzKCkgeworICByZXR1cm4gKHsoeyJ3YWFhZ2giLCAiR29ibGluQ21kV2FhYWdoIiwgMCwgMH0pfSkgKworICAgIGJhc2U6Ol9xdWVyeV9sb2NhbGNtZHMoKTsKK30KKworLy8gImtudWRkZWwgYWxsZSIgaXN0IGRldXRsaWNoIHRldXJlciBhbHNvIHdobyBjYXJlcyA6LSkKK3N0YXRpYyB2YXJhcmdzIGludCBHb2JsaW5DbWRXYWFhZ2goc3RyaW5nIGFyZykgeworICBvYmplY3QgKm9iczsKKyAgc3RyaW5nIHMsIHc7CisgIAorICBpZighb2JqZWN0cChlbnZpcm9ubWVudCgpKSkgcmV0dXJuIDA7CisgIG9icyA9IGZpbHRlcihhbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpIC0gKHt0aGlzX29iamVjdCgpfSksICMnbGl2aW5nKTsKKyAgb2JzID0gb2JzIC0gZmlsdGVyX29iamVjdHMob2JzLCAiUXVlcnlQcm9wIiwgUF9JTlZJUyk7CisgIC8vIGxldmVsYWJoYWVuZ2lnZSBBbnphaGwgYWFhYWFhYSdzCisgIHcgPSAiVyIrIHNwcmludGYoIiUnYSciKyAoUXVlcnlQcm9wKFBfTEVWRUwpIC8gMTAgKyAzKSArInMiLCAiYWFhIikgKyJnaCEiOworCisgIGZvcmVhY2gob2JqZWN0IG8gOiBvYnMpCisgIHsKKyAgICBzdHJpbmcgc3RyPShicmVha19zdHJpbmcoTmFtZShXRVIpICsiIGJhbGx0IGRpZSBGYWV1c3RjaGVuIHVuZCAiCisgICAgICAia3JlaXNjaHQgbGF1dDogIisgdyArIlxuIgorICAgICAgKyBjYXBpdGFsaXplKG8tPlF1ZXJ5RHUoV0VSKSkgKyAiIHp1Y2tzdCBlcnNjaHJvY2tlbiB6dXNhbW1lbi4iLAorICAgICAgNzgsIDAsIEJTX0xFQVZFX01ZX0xGUykpOworCisgICAgaW50IHJlcz1vLT5SZWNlaXZlTXNnKHN0cixNVF9MSVNURU4sTUFfRU1PVEUsMCx0aGlzX29iamVjdCgpKTsKKyAgICBpZiAocmVzPDApCisgICAgeworICAgICAgb2JzLT0oe299KTsgLy8gdW50ZW4gbmljaHQgbWVociBtaXQgYW56ZWlnZW4uCisgICAgICBpZiAocmVzPT1NU0dfU0VOU0VfQkxPQ0spCisgICAgICAgIFJlY2VpdmVNc2coby0+TmFtZShXRVIpICsiIGthbm4gRGljaCBuaWNodCBob2VyZW4uIiwKKyAgICAgICAgICAgICAgICAgICBNVF9OT1RJRklDQVRJT058TVNHX0RPTlRfSUdOT1JFfE1TR19ET05UX1NUT1JFLAorICAgICAgICAgICAgICAgICAgIE1BX0VNT1RFLDAsdGhpc19vYmplY3QoKSk7CisgICAgICBlbHNlCisgICAgICAgIFJlY2VpdmVNc2coby0+TmFtZShXRVIpICsiIGlnbm9yaWVydCBEaWNoIG9kZXIgZGllc2VuIEJlZmVobC4iLAorICAgICAgICAgICAgICAgICAgIE1UX05PVElGSUNBVElPTnxNU0dfRE9OVF9JR05PUkV8TVNHX0RPTlRfU1RPUkUsCisgICAgICAgICAgICAgICAgICAgTUFfRU1PVEUsMCx0aGlzX29iamVjdCgpKTsKKyAgICB9CisgIH0KKyAgaW50IGFuemFobD1zaXplb2Yob2JzKTsKKyAgaWYoIWFuemFobCkKKyAgeworICAgIFJlY2VpdmVNc2coIkR1IGJhbGxzdCBkaWUgRmFldXN0Y2hlbiB1bmQga3JlaXNjaHN0IGxhdXQ6ICIKKyAgICAgICAgICAgICAgICsgdywgTVRfTk9USUZJQ0FUSU9OfE1TR19ET05UX0lHTk9SRSxNQV9FTU9URSwwLHRoaXNfb2JqZWN0KCkpOworICB9CisgIGVsc2UKKyAgeworICAgIHMgPSBDb3VudFVwKG1hcF9vYmplY3RzKG9icywgIm5hbWUiLCBXRVIpKTsKKyAgICBSZWNlaXZlTXNnKGJyZWFrX3N0cmluZygiRHUgYmFsbHN0IGRpZSBGYWV1c3RjaGVuIHVuZCBrcmVpc2Noc3QgbGF1dDogIgorICAgICAgICAgICAgICAgKyB3ICsiXG4iKyBjYXBpdGFsaXplKHMpICsiIHp1Y2siCisgICAgICAgICAgICAgICArKGFuemFobCA+IDEgPyAiZW4iIDogInQiKSArIiBlcnNjaHJvY2tlbiB6dXNhbW1lbi4iLAorICAgICAgICAgICAgICAgNzgsIDAsIEJTX0xFQVZFX01ZX0xGUyksCisgICAgICAgICAgICAgICBNVF9OT1RJRklDQVRJT058TVNHX0RPTlRfU1RPUkV8TVNHX0RPTlRfSUdOT1JFLAorICAgICAgICAgICAgICAgTUFfRU1PVEUsMCx0aGlzX29iamVjdCgpKTsKKyAgfQorICByZXR1cm4gMTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3NoZWxscy9ob2JiaXQuYyBiL3N0ZC9zaGVsbHMvaG9iYml0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYjYyNmIwNgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvaG9iYml0LmMKQEAgLTAsMCArMSwxMzkgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBzaGVsbHMvaG9iYml0LmMgLS0gSG9iYml0IFNoZWxsCisvLworLy8gICA5LkFwcmlsIDE5OTUgIFYxLjAgR3VuZHVyCisvLworLy8gICAxNS5KdW5pIHByYXlyb29tIHVuZCBkZWZIb21lIGF1ZiBIb2JiaXRkb3JmIGdlc2V0enQgdm9uIEd1bmR1cgorLy8KKy8vICRJZDogaG9iYml0LmMgODkyMCAyMDE0LTA5LTAyIDIwOjE4OjM4WiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJvbmdfdHlwZXMsc2F2ZV90eXBlcworCitpbmhlcml0ICJzdGQvcGxheWVyL2Jhc2UiOworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGF0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxoZWFsdGguaD4KKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxjb21iYXQuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxkZWZ1ZWwuaD4KKworCisKK3ZvaWQgY3JlYXRlKCl7CisgIGlmICghY2xvbmVwKCkgfHwgb2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bMC4uPDNdKSB7CisgICAgICBzZXRfbmV4dF9yZXNldCgtMSk7ICAgIAorICAgICAgcmV0dXJuOworICB9CisKKyAgbWl4ZWQgcmVzOworCisgIGJhc2U6OmNyZWF0ZSgpOworICBTZXREZWZhdWx0SG9tZSgiL2Qvd2FsZC9ndW5kdXIvaG9iYml0ZG9yZi9zY2hyZWluIik7CisgIFNldERlZmF1bHRQcmF5Um9vbSgiL2Qvd2FsZC9ndW5kdXIvaG9iYml0ZG9yZi9zY2hyZWluIik7CisgIFNldFByb3AoUF9BVFRSSUJVVEVTX09GRlNFVFMsKFtBX0RFWDo0LEFfQ09OOjJdKSk7CisgIFNldFByb3AoUF9BVkVSQUdFX1NJWkUsIDEwNSk7CisgIFNldFByb3AoUF9BVkVSQUdFX1dFSUdIVCwgNjAwMDApOworICBTZXRQcm9wKFBfTUFURVJJQUxfS05PV0xFREdFLChbTUFUR1JPVVBfRUFUQUJMRTozMCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQVRHUk9VUF9EUlVHOjMwLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BVEdST1VQX1BPSVNPTk9VUzoxMF0pKTsKKyAgU2V0UHJvcChQX1JFU0lTVEFOQ0VfU1RSRU5HVEhTLAorCSAgKFsgRFRfVEVSUk9SIDogLTAuMSwKKwkgICBEVF9NQUdJQyA6IC0wLjEsCisJICAgRFRfU09VTkQgOiAwLjIsCisJICAgRFRfTElHSFROSU5HIDogMC4xLAorCSAgIERUX1BPSVNPTiA6IDAuMSBdKSk7CisgIFNldFByb3AoUF9NQVhfRk9PRCwyNTApOworICBTZXRQcm9wKFBfTUFYX0RSSU5LLDEwMCk7CisgIFNldFByb3AoUF9NQVhfQUxDT0hPTCwxNTApOworCisgIFNldFByb3AoUF9TUF9ERUxBWSxIRUFMX0RFTEFZKzEpOworICBTZXRQcm9wKFBfUE9JU09OX0RFTEFZLFBPSVNPTl9ERUxBWS0xKTsKKyAgU2V0UHJvcChQX0ZPT0RfREVMQVksRk9PRF9ERUxBWS0yKTsKKyAgU2V0UHJvcChQX0FMQ09IT0xfREVMQVksQUxDT0hPTF9ERUxBWSsxKTsKKworICBTZXRQcm9wKFBfTUFHSUNfUkVTSVNUQU5DRV9PRkZTRVQsCisgICAgICAgICAgKFsgTVRfQU5HUklGRiA6IDUwMCwKKwkgICBNVF9IRUxMU0lDSFQgOiAtNTAwLAorCSAgIE1UX1BTWUNITyA6IC01MDAgXSkpOworCisgIGlmKCEocmVzPVF1ZXJ5UHJvcChQX0hBTkRTKSkgfHwgIXBvaW50ZXJwKHJlcykgfHwgKHNpemVvZihyZXMpPDMpKQorICAgIHJlcz0oeyIgbWl0IHBlbHppZ2VuIEhhZW5kZW4iLDI1LCh7RFRfQkxVREdFT059KX0pOworICByZXNbMV09MjU7CisgIFNldFByb3AoUF9IQU5EUyxyZXMpOworICBTZXRQcm9wKFBfQk9EWSwxNSk7CisKKyAgLyogR3JvZXNzZSB3aXJkIG51ciBlaW5tYWwgZ2VzZXR6dCAqLworICBpZighUXVlcnlQcm9wKFBfU0laRSkpeworICAgIFNldFByb3AoUF9TSVpFLDk1K3JhbmRvbSgyMSkpOworICAgIFNldChQX1NJWkUsU0FWRSxGX01PREVfQVMpOworICB9CisKKyAgLyogRGl0byBHZXdpY2h0ICovCisgIGlmKCFRdWVyeVByb3AoUF9XRUlHSFQpIHx8IChRdWVyeVByb3AoUF9XRUlHSFQpID09IDc1MDAwKSl7CisgICAgU2V0UHJvcChQX1dFSUdIVCw1MDAwMCtyYW5kb20oMjAwMDEpKTsKKyAgICBpZihRdWVyeVByb3AoUF9HRU5ERVIpPT1GRU1BTEUpCisgICAgICBTZXRQcm9wKFBfV0VJR0hULFF1ZXJ5UHJvcChQX1dFSUdIVCktNTAwMCk7CisgICAgU2V0KFBfV0VJR0hULFNBVkUsRl9NT0RFX0FTKTsKKyAgfQorICBTZXRQcm9wKFBfREVGVUVMX0xJTUlUX0ZPT0QsMTQwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9MSU1JVF9EUklOSyw1MCk7CisgIFNldFByb3AoUF9ERUZVRUxfVElNRV9GT09ELDg1MCk7CisgIFNldFByb3AoUF9ERUZVRUxfVElNRV9EUklOSyw0NTApOworICBTZXRQcm9wKFBfREVGVUVMX0FNT1VOVF9GT09ELDAuOCk7CisgIFNldFByb3AoUF9ERUZVRUxfQU1PVU5UX0RSSU5LLDAuNik7CisKK30KKworc3RyaW5nIF9xdWVyeV9yYWNlKCkKK3sKKyAgcmV0dXJuICJIb2JiaXQiOworfQorCitzdHJpbmcgX3F1ZXJ5X3JlYWxfcmFjZSgpCit7CisgIHJldHVybiAiSG9iYml0IjsKK30KKworc3RyaW5nIF9xdWVyeV9yYWNlZGVzY3IoKQoreworICByZXR1cm4gIkhvYmJpdHMgc2luZCBrbGVpbmUgV2VzZW4sIGRpZSBhbSBlaGVzdGVuIGRlbiBNZW5zY2hlbiBhZWhuZWxuLlxuIisKKyAgICAiU2llIHplaWNobmVuIHNpY2ggdHJvdHogSWhyZXIgR3JvZXNzZSBkdXJjaCBpaHJlbiBNdXQgdW5kIFN0YW5kZmVzdGlna2VpdCAiKworCSJhdXMuXG5PYndvaGwgc2llIHZpZWwgbGllYmVyIHp1aGF1c2Ugdm9ybSB3YXJtZW4gS2FtaW4gc2l0emVuLCBzaW5kIHNpZSAiKworCSJpbW1lclxuZnVlciBlaW4gQWJlbnRldWVyIHp1IGhhYmVuLlxuIjsKK30KKworaW50IFF1ZXJ5QWxsb3dTZWxlY3QoKSB7IHJldHVybiAxOyB9CisKK3N0cmluZyAqX3F1ZXJ5X3JhY2VzdHJpbmcoKXsKKyAgaWYgKFF1ZXJ5UHJvcChQX0dFTkRFUikgPT0gRkVNQUxFKQorICAgIHJldHVybiAoeyJIb2JiaXRmcmF1IiwiSG9iYml0ZnJhdSIsIkhvYmJpdGZyYXUiLCJIb2JiaXRmcmF1In0pOworICByZXR1cm4gKHsiSG9iYml0IiwiSG9iYml0cyIsIkhvYmJpdCIsIkhvYmJpdCJ9KTsKK30KKworc3RyaW5nIF9xdWVyeV9kZWZhdWx0X2d1aWxkKCl7CisgIHJldHVybiAiYWJlbnRldXJlciI7Cit9CisKK3ZvaWQgRmluYWxTZXR1cCgpIHsKKyAgaWYoIXByZXNlbnQoInBmZWlmY2hlbiIsdGhpc19vYmplY3QoKSkpCisgICAgY2xvbmVfb2JqZWN0KCIvaXRlbXMvcGZlaWZjaGVuIiktPm1vdmUodGhpc19vYmplY3QoKSxNX05PQ0hFQ0spOworfQorCittaXhlZCBSYWNlRGVmYXVsdChzdHJpbmcgYXJnKQoreworICBpZiAoIWFyZykKKyAgICByZXR1cm4gMDsKKyAgc3dpdGNoKGFyZykKKyAgeworICAgIGNhc2UgUF9IQU5EUyA6CisgICAgICByZXR1cm4gKHsiIG1pdCBwZWx6aWdlbiBIYWVuZGVuIiwyNSwoe0RUX0JMVURHRU9OfSkgfSk7CisgICAgY2FzZSBQX0JPRFkgOgorICAgICAgcmV0dXJuIDE1OworICB9CisgIHJldHVybiBiYXNlOjpSYWNlRGVmYXVsdChhcmcpOworfQpkaWZmIC0tZ2l0IGEvc3RkL3NoZWxscy9odW1hbi5jIGIvc3RkL3NoZWxscy9odW1hbi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmMxOGRmMmQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvc2hlbGxzL2h1bWFuLmMKQEAgLTAsMCArMSwxMTMgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBzaGVsbHMvaHVtYW4uYyAtLSBIdW1hbiBTaGVsbAorLy8KKy8vICRJZDogaHVtYW4uYyA5MDIyIDIwMTUtMDEtMTAgMjE6NTA6NTBaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cm9uZ190eXBlcyxzYXZlX3R5cGVzCisKK2luaGVyaXQgIi9zdGQvcGxheWVyL2Jhc2UiOworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGF0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxoZWFsdGguaD4KKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxkZWZ1ZWwuaD4KKworCisKK3ZvaWQgY3JlYXRlKCkgeworICBpZiAoIWNsb25lcCgpIHx8IG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpID09IF9fRklMRV9fWzAuLjwzXSkgeworICAgICAgc2V0X25leHRfcmVzZXQoLTEpOyAgICAKKyAgICAgIHJldHVybjsKKyAgfQorCisgIGJhc2U6OmNyZWF0ZSgpOworICBTZXREZWZhdWx0SG9tZSgiL2dpbGRlbi9hYmVudGV1cmVyIik7CisgIFNldERlZmF1bHRQcmF5Um9vbSgiL2QvZWJlbmUvcm9vbS9Qb3J0VmFpbi9wcmF5X3Jvb20iKTsKKyAgU2V0UHJvcChQX0FUVFJJQlVURVNfT0ZGU0VUUywoW0FfSU5UOjEsQV9TVFI6MSxBX0NPTjoxLEFfREVYOjNdKSk7CisgIFNldFByb3AoUF9BVkVSQUdFX1NJWkUsMTcwKTsKKyAgU2V0UHJvcChQX0FWRVJBR0VfV0VJR0hULDc1MDAwKTsKKyAgU2V0UHJvcChQX01BVEVSSUFMX0tOT1dMRURHRSwoW01BVEdST1VQX1dPT0Q6MjAsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFUR1JPVVBfTUVUQUw6MjAsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTUFUR1JPVVBfRUxFTUVOVEFMOjIwLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BVEdST1VQX0NMT1RIOjIwXSkpOworCisgIFNldFByb3AoUF9NQVhfRk9PRCwxMjApOworICBTZXRQcm9wKFBfTUFYX0RSSU5LLDEyMCk7CisgIFNldFByb3AoUF9NQVhfQUxDT0hPTCwxMjApOworCisgIFNldFByb3AoUF9NQUdJQ19SRVNJU1RBTkNFX09GRlNFVCwKKyAgICAgICAgICAoWyBNVF9BTkdSSUZGIDogNTAwLAorCSAgIE1UX0lMTFVTSU9OIDogNzAwLAorICAgICAgICAgICBNVF9CRUhFUlJTQ0hVTkcgOiA1MDAsCisJICAgTVRfSEVMTFNJQ0hUIDogMTAwMCwKKwkgICBNVF9WRVJXQU5ETFVORyA6IC01MDAsCisJICAgTVRfUFNZQ0hPIDogLTUwMCBdKSk7CisKKyAgLy8gWnVrdWVuZnRpZyAwLCBuaWNodCBtZWhyIC01LiBBcmssIDA0LjAxLjA4LgorICBTZXRQcm9wKFBfQk9EWSwwKTsKKworICAvKiBHcm9lc3NlIHdpcmQgbnVyIGVpbm1hbCBnZXNldHp0ICovCisgIGlmKCFRdWVyeVByb3AoUF9TSVpFKSl7CisgICAgU2V0UHJvcChQX1NJWkUsMTYwK3JhbmRvbSgyMSkpOworICAgIFNldChQX1NJWkUsU0FWRSxGX01PREVfQVMpOworICB9CisKKyAgLyogRGl0byBHZXdpY2h0ICovCisgIGlmKCFRdWVyeVByb3AoUF9XRUlHSFQpIHx8IChRdWVyeVByb3AoUF9XRUlHSFQpID09IDc1MDAwKSl7CisgICAgU2V0UHJvcChQX1dFSUdIVCw2NTAwMCtyYW5kb20oMjAwMDEpKTsKKyAgICBpZihRdWVyeVByb3AoUF9HRU5ERVIpPT1GRU1BTEUpCisgICAgICBTZXRQcm9wKFBfV0VJR0hULFF1ZXJ5UHJvcChQX1dFSUdIVCktNTAwMCk7CisgICAgU2V0KFBfV0VJR0hULFNBVkUsRl9NT0RFX0FTKTsKKyAgfQorICBTZXRQcm9wKFBfREVGVUVMX0xJTUlUX0ZPT0QsNjApOworICBTZXRQcm9wKFBfREVGVUVMX0xJTUlUX0RSSU5LLDUwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9USU1FX0ZPT0QsNTAwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9USU1FX0RSSU5LLDI0NSk7CisgIFNldFByb3AoUF9ERUZVRUxfQU1PVU5UX0ZPT0QsMC43NSk7CisgIFNldFByb3AoUF9ERUZVRUxfQU1PVU5UX0RSSU5LLDAuNSk7CisKK30KKworc3RyaW5nIF9xdWVyeV9yYWNlKCkKK3sKKyAgcmV0dXJuICJNZW5zY2giOworfQorCitzdHJpbmcgX3F1ZXJ5X3JlYWxfcmFjZSgpCit7CisgIHJldHVybiAiTWVuc2NoIjsKK30KKworc3RyaW5nICpfcXVlcnlfcmFjZXN0cmluZygpCit7CisgIGlmIChRdWVyeVByb3AoUF9HRU5ERVIpPT0yKQorICAgIHJldHVybiAoeyJNZW5zY2hlbmZyYXUiLCJNZW5zY2hlbmZyYXUiLCJNZW5zY2hlbmZyYXUiLCJNZW5zY2hlbmZyYXUifSk7CisgIHJldHVybiAoeyJNZW5zY2giLCJNZW5zY2hlbiIsIk1lbnNjaCIsIk1lbnNjaGVuIn0pOworfQorCitzdHJpbmcgX3F1ZXJ5X3JhY2VkZXNjcigpCit7CisgIHJldHVybiAiRGllIFN0YWVya2UgZGVzIE1lbnNjaGVuIGlzdCBzZWluZSBWaWVsc2VpdGlna2VpdC5cbiIrCisgICAgIkRlciBNZW5zY2gga2FubiB6d2FyIG5pY2h0cyBiZXNvbmRlcnMgZ3V0IC0gZGFmdWVyIGFiZXIgZWlnZW50bGljaCBhbGxlcy5cbiI7Cit9CisKK2ludCBRdWVyeUFsbG93U2VsZWN0KCkgeyByZXR1cm4gMTsgfQorCit2b2lkIEZpbmFsU2V0dXAoKQoreworICAvLyBJbSBNRyBnaWJ0IGZ1ZXIga2xlaW5lIFNwaWVsZXIgZWluZSBLYXJ0ZSB2b24gUG9ydCBWYWluLiBEaWUgZ2lidCBlcworICAvLyB3b2FuZGVycyBtZWlzdCBuaWNodC4KKyNpZiBNVUROQU1FID09ICJNb3JnZW5HcmF1ZW4iCisgIGlmIChRdWVyeVByb3AoUF9MRVZFTCk8PTMgJiYgIXByZXNlbnQoInBvcnR2YWlua2FydGUiLHRoaXNfb2JqZWN0KCkpKQorICAgIGNsb25lX29iamVjdCgiL2QvZWJlbmUvb2JqL3B2IiktPm1vdmUodGhpc19vYmplY3QoKSxNX05PQ0hFQ0spOworI2VuZGlmCit9CisKK3N0cmluZyBfcXVlcnlfZGVmYXVsdF9ndWlsZCgpeworICByZXR1cm4gImFiZW50ZXVyZXIiOworfQpkaWZmIC0tZ2l0IGEvc3RkL3NoZWxscy9tYWdpZXIuYyBiL3N0ZC9zaGVsbHMvbWFnaWVyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGMyYTE1MAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvbWFnaWVyLmMKQEAgLTAsMCArMSwzMjYgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBzaGVsbHMvbWFnaWVyLmMgLS0gbWFnaWVyIHNoZWxsCisvLworLy8gJElkOiBtYWdpZXIuYyA5MjMxIDIwMTUtMDUtMjcgMjE6NTM6MzJaIFplc3N0cmEgJAorCisvLworLy8gTWFnaWVyc2hlbGwgQmFzaXNmaWxlCisvLworLy8gVWViZXJhcmJlaXR1bmcgYWJnZXNjaGxvc3NlbiBhbSAxOC4xMi4yMDAyCisvLworLy8gRGFuayBhbiBad2lyY2hAUEssIFJpa3VzQE1HLCBab3JhbkBQSywgVmFuaW9uQE1HCisvLyB1bmQgdmllbGUgYW5kZXJlLCBkaWUgaWNoIHZlcmdlc3NlbiBoYWJlLgorLy8KKy8vIEZyYWdlbiB1bmQgQnVnaGlud2Vpc2UgYW4gTWFuZHJhZ29uQE1HIG9kZXIgZWluZW4KKy8vIEVyem1hZ2llciBEZWluZXIgV2FobC4KKy8vCisvLyBadXIgU2hlbGwgZ2Vob2VyZW4gYXVzc2VyIGRpZXNlciBEYXRlaToKKy8vIGFkbWluLmM6ICAgICAgQWRtaW5pc3RyYXRpdmUgQmVmZWhsZQorLy8gY29tbS5jOiAgICAgICBLb21tdW5pa2F0aW9uc2JlZmVobGUKKy8vIGZpbGVlZGl0LmM6ICAgQmVmZWhsZSB6dW0gVmVyYWVuZGVybiB2b24gRGF0ZWllbgorLy8gZmlsZXZpZXcuYzogICBCZWZlaGxlIHp1bSBMZXNlbiB2b24gRGF0ZWllbgorLy8gbWFnaWVyX2V4dC5jOiBHZW5lcmVsbGUgTWFnaWVyYmVmZWhsZQorLy8gbW92aW5nLmM6ICAgICBCZXdlZ3VuZ3NiZWZlaGxlCisvLyBvYmplY3RzLmM6ICAgIEVyemV1Z2VuIHVuZCB6ZXJzdG9lcmVuIHZvbiBPYmpla3RlbgorLy8gcGFyc2luZy5jICAgICBBdXN3ZXJ0dW5nIHZvbiBQZmFkYW5nYWJlbiB1bmQgV2lsZGNhcmRzCisvLyBwbGF5ZXJzLmM6ICAgIEJlZmVobGUgenVyIEJlZWluZmx1c3N1bmcgdm9uIFNwaWVsZXJuCisvLyB0b2RvLmM6ICAgICAgIEltcGxlbWVudGF0aW9uIGRlciBUb2RvbGlzdGUKKy8vIHVwZC5jOiAgICAgICAgRGVyIEJlZmVobCB1cGQKKy8vIG1hZ2llci5oICAgICAgR2VuZXJlbGxlIEhlYWRlci1EYXRlaQorLy8KKworI3ByYWdtYSBzdHJpY3RfdHlwZXMsc2F2ZV90eXBlcworCitpbmhlcml0ICIvc3RkL3BsYXllci9iYXNlIjsKK2luaGVyaXQgIi9zdGQvc2hlbGxzL21hZ2llci9tYWdpZXJfZXh0IjsKKworI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisjaW5jbHVkZSA8Y29uZmlnLmg+CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIGlmICghY2xvbmVwKCkgfHwgb2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bMC4uPDNdKSB7CisgICAgICBzZXRfbmV4dF9yZXNldCgtMSk7CisgICAgICByZXR1cm47CisgIH0KKworICBiYXNlOjpjcmVhdGUoKTsKKworICBTZXQoUF9SQUNFLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9aQVBfTVNHLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9UUkFOS19GSU5ERU4sIFNBVkUsIEZfTU9ERSk7CisgIFNldChQX0hBTkRTLCBTQVZFLCBGX01PREUpOworICBTZXQoUF9SQUNFU1RSSU5HLCBTQVZFLCBGX01PREUpOworICBTZXREZWZhdWx0SG9tZSgiL2dpbGRlbi9hYmVudGV1cmVyIik7CisgIFNldFByb3AoUF9FTkVNWV9ERUFUSF9TRVFVRU5DRSwKKyAgICAoWzE3OiJEZXIgVG9kIHNjaHVldHRlbHQgdmVyc3RhZW5kbmlzbG9zIGRlbiBLb3BmLlxuXG4iLAorICAgICAgMTg6IkRlciBUb2Qgc2FndDogV0lFU08gTVVTU1RFU1QgRFUgRElDSCBBVUNIIFVOQkVESU5HVCAiCisgICAgICAiTUlUIEVJTkVNIE1BR0lFUiBBTkxFR0VOP1xuXG4iXSkpOworICBTZXRQcm9wKFBfQVRUUklCVVRFU19PRkZTRVRTLChbXSkpOworICBTZXRQcm9wKFBfQVZFUkFHRV9TSVpFLDE4NSk7CisgIGlmKCFRdWVyeVByb3AoUF9ERUZBVUxUX0dVSUxEKSkgU2V0UHJvcChQX0RFRkFVTFRfR1VJTEQsImFiZW50ZXVyZXIiKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKKworcHJvdGVjdGVkIHZvaWQgaGVhcnRfYmVhdCgpCit7CisgIG1peGVkICplbjsKKworICBpZiAoIVF1ZXJ5UHJvcChQX1dBTlRTX1RPX0xFQVJOKXx8KChlbj1RdWVyeUVuZW1pZXMoKSkmJnNpemVvZihlblswXSkpKQorICAgIGJhc2U6OmhlYXJ0X2JlYXQoKTsKKyAgZWxzZSBpZiAoIUNoZWNrVGVsbmV0S2VlcEFsaXZlKCkpIHsKKyAgICAvLyBXZW5uIGRlciBNYWdpZXIga2VpbiBUZWxuZXQgS2VlcC1BbGl2ZSB3dWVuc2NodCwga2FubiBkZXIgSEIgZ2FuegorICAgIC8vIGFiZ2VzY2hhbHRldCB3ZXJkZW4uIFNvbnN0IG11c3MgZXIgYWJlciB3ZWl0ZXJsYXVmZW4sIGRhbWl0CisgICAgLy8gQ2hlY2tUZWxuZXRLZWVwQWxpdmUoKSByZWdlbG1hZXNzaWcgZ2VydWZlbiB3aXJkLgorICAgIHNldF9oZWFydF9iZWF0KDApOworICB9Cit9CisKKworcHVibGljIHZhcmFyZ3MgaW50IHJlbW92ZShpbnQgc2lsZW50KQoreworICBzdHJpbmcgd29ya3Jvb207CisKKyAgaWYgKElTX1dJWkFSRCh0aGlzX29iamVjdCgpKSkKKyAgICB3b3Jrcm9vbSA9ICIvcGxheWVycy8iK2dldHVpZCgpKyIvd29ya3Jvb20iOworICBlbHNlCisgICAgd29ya3Jvb20gPSAiL3NlY3VyZS9tZXJsaW4iOworICBpZiggIWVudmlyb25tZW50KCkgfHwgb2JqZWN0X25hbWUoZW52aXJvbm1lbnQoKSkgIT0gd29ya3Jvb20gKQorICAgIGNhdGNoKG1vdmUod29ya3Jvb20sIE1fR08sICJuYWNoIEhhdXNlIikpOworICByZXR1cm4gYmFzZTo6cmVtb3ZlKHNpbGVudCk7Cit9CisKK3B1YmxpYyBzdHJpbmcgTm90aWZ5RGVzdHJ1Y3Qob2JqZWN0IGNhbGxlcikgeworCisgIGlmIChwcmV2aW91c19vYmplY3QoKSAhPSBtYXN0ZXIoKQorICAgICAgfHwgb2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bLi48M10pCisgICAgcmV0dXJuIDA7CisgIAorICAvLyBOaWNodC1FTXMgc29sbGVuIGtlaW5lIEVNcyB6ZXJzdG9lcmVuIGtvZW5uZW4sIHdvcmF1ZmhpbiBhdWNoIGV2dGwuCisgIC8vIEVNLVRvb2xzIHJ1bWxpZWdlbiBrb2VubnRlbi4KKyAgaWYgKCBJU19BUkNIKHRoaXNfb2JqZWN0KCkpICYmIGNhbGxlciAhPSB0aGlzX29iamVjdCgpIAorICAgICAgJiYgZ2V0dWlkKGNhbGxlcikgIT0gUk9PVElECisgICAgICAmJiAocHJvY2Vzc19jYWxsKCkgfHwgIUFSQ0hfU0VDVVJJVFkpICkKKyAgICByZXR1cm4gIkRhcyBaZXJzdG9lcmVuIHZvbiBFTXMgaXN0IGVpbiBGZWhsZXIuIDstKVxuIjsKKworICByZXR1cm4gOjpOb3RpZnlEZXN0cnVjdChjYWxsZXIpOworfQorCit2b2lkIHJlc2V0KCkKK3sKKyAgaWYgKCFpbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKSkKKyAgeworICAgIHF1aXQoKTsKKyAgICBpZiAodGhpc19vYmplY3QoKSkKKyAgICAgIHJlbW92ZSgpOworICAgIGlmICh0aGlzX29iamVjdCgpKQorICAgICAgICBkZXN0cnVjdCh0aGlzX29iamVjdCgpKTsKKyAgICByZXR1cm47CisgIH0KK30KKworLy8gICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMgUXVlcnktRnVua3Rpb25lbiAjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjCisKK3ZhcmFyZ3MgaW50IGlkIChzdHJpbmcgc3RyKSB7CisgIGlmIChRdWVyeVByb3AoUF9JTlZJUykgJiYKKyAgICAgICghdGhpc19pbnRlcmFjdGl2ZSgpIHx8IUlTX0xFQVJORVIodGhpc19pbnRlcmFjdGl2ZSgpKSkpCisgICAgcmV0dXJuIDA7CisgIHJldHVybiA6OmlkKHN0cik7Cit9CisKKworc3RhdGljIHN0cmluZyAqX3F1ZXJ5X3JhY2VzdHJpbmcoKQoreworICBpZiAocG9pbnRlcnAoUXVlcnkoUF9SQUNFU1RSSU5HKSkpCisgICAgcmV0dXJuIFF1ZXJ5KFBfUkFDRVNUUklORyk7CisgIGVsc2UKKyAgICByZXR1cm4KKyAgICAoe1F1ZXJ5UHJvcChQX1JBQ0UpLFF1ZXJ5UHJvcChQX1JBQ0UpLAorICAgICAgUXVlcnlQcm9wKFBfUkFDRSksUXVlcnlQcm9wKFBfUkFDRSl9KTsKK30KKworCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9kZWZhdWx0X2d1aWxkKCkKK3sKKyAgICByZXR1cm4gKFF1ZXJ5KFBfREVGQVVMVF9HVUlMRCl8fCJhYmVudGV1cmVyIik7Cit9CisKKworc3RhdGljIHN0cmluZyBfcXVlcnlfcmFjZWRlc2NyKCkKK3sKKyAgcmV0dXJuICJNYWdpZXIga29lbm5lbiBlaW5mYWNoIGFsbGVzLiBBYmVyIG1hbmNoZSBNYWdpZXIga29lbm5lbiBtZWhyLlxuIjsKK30KKworCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9yYWNlKCkKK3sKKyAgaWYgKHByZXZpb3VzX29iamVjdCgpICYmIHByZXZpb3VzX29iamVjdCgpLT5xdWVyeV9sb2dpbl9vYmplY3QoKSkKKyAgICByZXR1cm4gMDsKKworICByZXR1cm4gUXVlcnkoUF9SQUNFKSA/IFF1ZXJ5KFBfUkFDRSkgOiBTZXQoUF9SQUNFLCAiTWFnaWVyIik7Cit9CisKKworc3RhdGljIG1peGVkIF9xdWVyeV9sb2NhbGNtZHMoKQoreworICByZXR1cm4KKyAgICBiYXNlOjpfcXVlcnlfbG9jYWxjbWRzKCkKKyAgICArbWFnaWVyX2V4dDo6X3F1ZXJ5X2xvY2FsY21kcygpOworfQorCisKK3N0YXRpYyB2b2lkIHVwZF9teV9hZ2UoKQoreworICBhZ2U9X2FnZSthYnNvbHV0ZV9oYl9jb3VudCgpLV9oYnN0b3A7CisgIF9hZ2U9YWdlOworICBfaGJzdG9wPWFic29sdXRlX2hiX2NvdW50KCk7CisgIHJldHVybjsKK30KKworCitzdGF0aWMgaW50IF9xdWVyeV9hZ2UoKQoreworICB1cGRfbXlfYWdlKCk7CisgIHJldHVybiBhZ2U7Cit9CisKK3N0YXRpYyBpbnQgX3NldF9lYXJtdWZmcyhpbnQgbGV2ZWwpCit7CisgIGludCBtYXhsPTErcXVlcnlfd2l6X2xldmVsKHRoaXNfb2JqZWN0KCkpOworICBtYXhsID0gbWF4KG1heGwsOTkpOworICByZXR1cm4gU2V0KFBfRUFSTVVGRlMsbWluKG1heGwsbGV2ZWwpKTsKK30KKworCisvLyAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIEludGVybmUgU2hlbGwtRnVua3Rpb25lbiAjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworCitpbnQgTWF5QWRkV2VpZ2h0KGludCB3KSB7IHJldHVybiAwO30KK2ludCBNYXlBZGRPYmplY3Qob2JqZWN0IG9iKSB7IHJldHVybiAxOyB9CisKKworc3RhdGljIHZvaWQgaW5pdGlhbGl6ZSgpCit7CisgIG1hZ2llcl9leHQ6OmluaXRpYWxpemUoKTsKKyAgcmV0dXJuOworfQorCisKK3N0YXRpYyB2b2lkIEZpbmFsU2V0dXAoKQoreworICBTZXRQcm9wKFBfQ1VSUkVOVERJUiwiL3BsYXllcnMvIitnZXR1aWQoKSk7CisgIGluaXRpYWxpemUoKTsKKyAgaWYgKElTX0xFQVJORVIodGhpc19wbGF5ZXIoKSkpIGNhdCgiL2V0Yy9XSVpORVdTIik7CisgIF9hZ2U9YWdlOworICBfaGJzdG9wPWFic29sdXRlX2hiX2NvdW50KCk7CisgIHJldHVybjsKK30KKworCit2b2lkIHNhdmVfbWUoaW50IGkpCit7CisgIHVwZF9teV9hZ2UoKTsKKyAgYmFzZTo6c2F2ZV9tZShpKTsKKyAgcmV0dXJuOworfQorCisKK3ZhcmFyZ3Mgdm9pZCBSZWNvbm5lY3QoaW50IHNpbGVudCxzdHJpbmcgbXlfaXApCit7CisgIGJhc2U6OlJlY29ubmVjdChzaWxlbnQsbXlfaXApOworICBtYWdpZXJfZXh0OjpyZWNvbm5lY3QoKTsKKyAgcmV0dXJuOworfQorCisKK3ZvaWQgbm90aWZ5X3BsYXllcl9jaGFuZ2Uoc3RyaW5nIHdobywgaW50IHJlaW4sIGludCBpbnZpcykKK3sKKyAgc3RyaW5nICpsaXN0LG5hbWU7CisgIG1peGVkIG1saXN0OworICBpbnQgdmlzX2NoYW5nZTsKKworICBpZiAoaW52aXMpIG5hbWU9IigiK3dobysiKSI7CisgICAgZWxzZSBuYW1lPXdobzsKKworICBpZihxdWVyeV92ZXJiKCkgJiYgKHF1ZXJ5X3ZlcmIoKT09InZpcyIgfHwgcXVlcnlfdmVyYigpPT0iaW52aXMiKSkKKyAgICB2aXNfY2hhbmdlPTE7CisKKyAgaWYgKFF1ZXJ5KFBfSU5GT1JNTUUpICYmICF2aXNfY2hhbmdlKQorICB7CisgICAgaWYgKHJlaW4pIAorICAgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwKKyAgICAgICAgICAgICAgICAgIHNwcmludGYoIiVzIGlzdCBnZXJhZGUgaW5zICJNVUROQU1FIiBnZWtvbW1lbi5cbiIsbmFtZSkpOworICAgIGVsc2UKKyAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgICAgICAgICBzcHJpbnRmKCIlcyBoYXQgZ2VyYWRlIGRhcyAiTVVETkFNRSIgdmVybGFzc2VuLlxuIixuYW1lKSk7CisgIH0KKworICBpZihRdWVyeShQX1dBSVRGT1JfRkxBR1MpICYgKDB4MDEpKXJldHVybiA7CisKKyAgaWYgKHBvaW50ZXJwKGxpc3Q9UXVlcnkoUF9XQUlURk9SKSkmJnNpemVvZihsaXN0KSkKKyAgICBpZiAobWVtYmVyKGxpc3Qsd2hvKSE9LTEpCisgICAgICBkZWxheWVkX3dyaXRlKAorICAgICAgICAgKHsKKyAgICAgICAgICAgKHtzcHJpbnRmKCIlcyVzICAgSSBTIFQgICBKIEUgVCBaIFQgICAlcyAhISFcbiIsCisgICAgICAgICAgICAgICAgICAgICAoUXVlcnlQcm9wKFBfVklTVUFMQkVMTCkgPyAiIiA6IHNwcmludGYoIiVjIiw3KSksCisgICAgICAgICAgICAgICAgICAgICBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgKHZpc19jaGFuZ2U/CisgICAgICAgICAgICAgICAgICAgICAgIChyZWluPyJTIEkgQyBIIFQgQiBBIFIiOiJVIE4gUyBJIEMgSCBUIEIgQSBSIik6CisgICAgICAgICAgICAgICAgICAgICAgIChyZWluPyJEIEEiOiJOIEkgQyBIIFQgICBNIEUgSCBSICAgRCBBIikpKSwKKyAgICAgICAgICAgMH0pCisgICAgICAgICB9KSk7CisKKyAgaWYgKHJlaW4gJiYgKHNpemVvZihtbGlzdD1RdWVyeVByb3AoUF9XQUlURk9SX1JFQVNPTikpKSAmJgorICAgICAobWFwcGluZ3AobWxpc3QpKSAmJiAobWxpc3Rbd2hvXSkpCisgICAgICAgIFNob3dfV2FpdEZvcl9SZWFzb24od2hvLGludmlzKTsKKyAgcmV0dXJuOworfQorCittaXhlZCBtb2RpZnlfY29tbWFuZChzdHJpbmcgc3RyKSB7CisgIGlmIChwcmV2aW91c19vYmplY3QoKSAmJgorICAgICAgKHByZXZpb3VzX29iamVjdCgpIT10aGlzX29iamVjdCgpIHx8IHByb2Nlc3NfY2FsbCgpKSApCisgIHsKKyAgICBpZiAoSVNfQVJDSCh0aGlzX29iamVjdCgpKSkKKyAgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksCisgICAgICAgIHNwcmludGYoIklsbGVnYWwgbW9kaWZ5X2NvbW1hbmQoJXMpIGZyb20gJU9cbiIsCisgICAgICAgIHN0ciwgcHJldmlvdXNfb2JqZWN0KCkpKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vCisgIC8vIE1hZ2llci1Fc2NhcGUtS29tbWFuZG9zIHdlcmRlbiBiZWhhbmRlbHQgCisgIGlmIChzdHI9PSJcXEVTQ0FQRSIgJiYgSVNfTE9SRCh0aGlzX29iamVjdCgpKSkKKyAgeworICAgIF9fc2V0X2Vudmlyb25tZW50KHRoaXNfb2JqZWN0KCksIi9yb29tL3ZvaWQiKTsKKyAgICBlbnZpcm9ubWVudCgpLT5pbml0KCk7CisgICAgcHJpbnRmKCJZb3UgZXNjYXBlZC5cbiIpOworICAgIHJldHVybiAiIjsKKyAgfQorICBpZiAoc3RyWzAuLjJdPT0iXFxcXFxcIiAmJiBJU19MT1JEKHRoaXNfb2JqZWN0KCkpKQorICB7CisgICAgc3RyID0gX3JldHVybl9hcmdzKHN0cik7CisgICAgc3RyaW5nKiBpbnB1dCA9IGV4cGxvZGUoc3RyWzMuLl0sIiAiKTsKKyAgICBzdHJpbmcgdmVyYiA9IGlucHV0WzBdOworICAgIGlmICh2ZXJiICYmIHZlcmIhPSIiKQorICAgIHsKKyAgICAgIHN0cmluZyBjbWQgPSBpbXBsb2RlKGlucHV0WzEuLl0sIiAiKTsKKyAgICAgIGlmICghX19hdXN3ZXJ0ZW4oY21kLHZlcmIpKQorICAgICAgICBTb3VsQ29tbShjbWQsdmVyYik7CisgICAgfQorICAgIHJldHVybiAxOworICB9CisgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8KKworICByZXR1cm4gOjptb2RpZnlfY29tbWFuZChzdHIpOworfQorCmRpZmYgLS1naXQgYS9zdGQvc2hlbGxzL21hZ2llci9hZG1pbi5jIGIvc3RkL3NoZWxscy9tYWdpZXIvYWRtaW4uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNDFkMWI3Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3NoZWxscy9tYWdpZXIvYWRtaW4uYwpAQCAtMCwwICsxLDQyOCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGFkbWluLmMKKy8vCisvLyAkSWQ6IGFkbWluLmMgODc1NSAyMDE0LTA0LTI2IDEzOjEzOjQwWiBaZXNzdHJhICQKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2luY2x1ZGUgPHVkcC5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGlucHV0X3RvLmg+CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8bWFnaWVyLmg+CisjaW5jbHVkZSA8cGxheWVyLmg+CisKK2luaGVyaXQgIi9zdGQvdXRpbC9jaWRyIjsKKworbWl4ZWQgX3F1ZXJ5X2xvY2FsY21kcygpCit7CisgIHJldHVybiAoeyh7InVkcHEiLCJfdWRwcSIsMCxMRUFSTkVSX0xWTH0pLAorICAgICAgICAgICAoeyJzaHV0ZG93biIsInNodXRfZG93bl9nYW1lIiwwLEFSQ0hfTFZMfSksCisgICAgICAgICAgICh7ImFkZG1hc3RlciIsIl9hZGRtYXN0ZXIiLDAsR09EX0xWTH0pLAorICAgICAgICAgICAoeyJyZW1vdmVtYXN0ZXIiLCJfcmVtb3ZlbWFzdGVyIiwwLEdPRF9MVkx9KSwKKyAgICAgICAgICAgKHsiYWRkZ3VpbGRtYXN0ZXIiLCAiX2FkZGd1aWxkbWFzdGVyIiwgMCwgR09EX0xWTH0pLAorICAgICAgICAgICAoeyJyZW1vdmVndWlsZG1hc3RlciIsICJfcmVtb3ZlZ3VpbGRtYXN0ZXIiLCAwLCBHT0RfTFZMfSksCisgICAgICAgICAgICh7InN1ZW5kZXIiLCJzaW5uZXJzIiwwLFdJWkFSRF9MVkx9KSwKKyAgICAgICAgICAgKHsiYmFuaXNoIiwiYmFuaXNoIiwgMCwgV0laQVJEX0xWTH0pLAorICAgICAgICAgICAoeyJtYmFuaXNoIiwibWJhbmlzaCIsIDAsIFdJWkFSRF9MVkx9KSwKKyAgICAgICAgICAgKHsidGJhbmlzaCIsInRiYW5pc2giLCAwLCBXSVpBUkRfTFZMfSksCisgICAgICAgICAgICh7InNiYW5pc2giLCJzYmFuaXNoIiwgMCwgV0laQVJEX0xWTH0pfSk7Cit9CisKK3N0YXRpYyBpbnQgX3VkcHEoc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nIHJldCwgbXVkLCB0eXBlOworCisgIGlmICghKHN0cj1fdW5wYXJzZWRfYXJncygpKSB8fCBzdHI9PSIiIHx8IHNzY2FuZihzdHIsIiVzICVzIixtdWQsdHlwZSk8MikKKyAgeworICAgIHdyaXRlKCJTeW50YXg6IHVkcHEgbXVkIHR5cGVcbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmIChtZW1iZXIoKHsiY29tbWFuZHMiLCJlbWFpbCIsImhvc3RzIiwiaW5ldGQiLCJsaXN0IiwibXVkX3BvcnQiLCJ0aW1lIiwKKyAgICAgICAgICJ2ZXJzaW9uIn0pLHR5cGUpPT0tMSkKKyAgICB3cml0ZSgiVFlQRXM6IGNvbW1hbmRzLCBlbWFpbCwgaG9zdHMsIGluZXRkLCBsaXN0LCBtdWRfcG9ydCwgdGltZSwgdmVyc2lvblxuIik7CisgIGlmIChyZXQ9KHN0cmluZylJTkVURC0+X3NlbmRfdWRwKG11ZCwoW1NFTkRFUjpnZXR1aWQoKSwgUkVRVUVTVDpRVUVSWSwgREFUQTp0eXBlXSksMSkpCisgICAgd3JpdGUocmV0KTsKKyAgZWxzZQorICAgIHdyaXRlKCJBbmZyYWdlIGFiZ2VzY2hpY2t0LlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IHNodXRfZG93bl9nYW1lKHN0cmluZyBzdHIpCit7CisgIGlmICghSVNfQVJDSCh0aGlzX29iamVjdCgpKSB8fCB0aGlzX29iamVjdCgpIT10aGlzX2ludGVyYWN0aXZlKCkpCisgICAgcmV0dXJuIDA7CisgIF9ub3RpZnlfZmFpbCgiRHUgbXVzc3QgZWluZW4gR3J1bmQgZGFmdWVyIGFuZ2ViZW4uXG4iKTsKKyAgaWYgKCFzdHIpIHJldHVybiAwOworICB3cml0ZSggIkRpcmVrdGVyIHNodXRkb3duIG1pdCBHcnVuZCBcIiIrc3RyKyJcIj9cbiIgKTsKKyAgaW5wdXRfdG8oInNodXRfZG93bl9nYW1lXzIiLElOUFVUX1BST01QVCwgIihqYS9uZWluKSA6Iiwgc3RyKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgc2h1dF9kb3duX2dhbWVfMihzdHJpbmcgYXJnLHN0cmluZyBzdHIpCit7CisgIGlmICghSVNfQVJDSCh0aGlzX29iamVjdCgpKSB8fCB0aGlzX29iamVjdCgpIT10aGlzX2ludGVyYWN0aXZlKCkpCisgICAgcmV0dXJuIDA7CisgIGlmKCBhcmchPSJqYSIgKSB7CisgICAgd3JpdGUoICJTaHV0ZG93biBhYmdlYnJvY2hlbi5cbiIgKTsKKyAgfSBlbHNlIHsKKyAgICBzaHV0ZG93bihzdHIpOworICB9CisgIHJldHVybiAxOworfQorCisKK3N0YXRpYyBpbnQgX2FkZG1hc3RlcihzdHJpbmcgc3RyKQoreworICBzdHJpbmcgbWFzdGVyLCBkb21haW47CisKKyAgaWYgKCFHT0RfU0VDVVJJVFkpCisgIHsKKyAgICB3cml0ZSgiRGFzIGRhcmZzdCBEdSBuaWNodCFcbiIpOworICAgIHJldHVybiAxOworICB9CisgIF9ub3RpZnlfZmFpbCgiU3ludGF4OiBhZGRtYXN0ZXIgPHVzZXI+IDxkb21haW4+XG4iKTsKKyAgaWYgKCFzdHIpIHJldHVybiAwOworICBpZiAoc3NjYW5mKHN0ciwiJXMgJXMiLG1hc3Rlcixkb21haW4pIT0yKSByZXR1cm4gMDsKKyAgaWYgKCFtYXN0ZXIgfHwgIWRvbWFpbikgcmV0dXJuIDA7CisgIGlmICghIi9zZWN1cmUvbWFzdGVyIi0+YWRkX2RvbWFpbl9tYXN0ZXIobWFzdGVyLGRvbWFpbikpCisgICAgd3JpdGUoIkhhdCBuaWNodCBmdW5rdGlvbmllcnQuXG4iKTsKKyAgZWxzZQorICAgIHdyaXRlKCJPay5cbiIpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBfcmVtb3ZlbWFzdGVyKHN0cmluZyBzdHIpCit7CisgIHN0cmluZyBtYXN0ZXIsIGRvbWFpbjsKKworICBpZiAoIUdPRF9TRUNVUklUWSkKKyAgeworICAgIHdyaXRlKCJEYXMgZGFyZnN0IER1IG5pY2h0IVxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgX25vdGlmeV9mYWlsKCJTeW50YXg6IHJlbW92ZW1hc3RlciA8dXNlcj4gPGRvbWFpbj5cbiIpOworICBpZiAoIXN0cikgcmV0dXJuIDA7CisgIGlmIChzc2NhbmYoc3RyLCIlcyAlcyIsbWFzdGVyLGRvbWFpbikhPTIpIHJldHVybiAwOworICBpZiAoIW1hc3RlciB8fCAhZG9tYWluKSByZXR1cm4gMDsKKyAgaWYgKCEiL3NlY3VyZS9tYXN0ZXIiLT5yZW1vdmVfZG9tYWluX21hc3RlcihtYXN0ZXIsZG9tYWluKSkKKyAgICB3cml0ZSgiSGF0IG5pY2h0IGZ1bmt0aW9uaWVydC5cbiIpOworICBlbHNlCisgICAgd3JpdGUoIk9rLlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IF9hZGRndWlsZG1hc3RlcihzdHJpbmcgc3RyKQoreworICBzdHJpbmcgbWFzdGVyLCBndWlsZDsKKyAgCisgIGlmICghR09EX1NFQ1VSSVRZKQorICB7CisgICAgd3JpdGUgKCJEYXMgZGFyZnN0IER1IG5pY2h0IVxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBfbm90aWZ5X2ZhaWwoIlN5bmF0eDogYWRkZ3VpbGRtYXN0ZXIgPHVzZXI+IDxndWlsZD5cbiIpOworICBpZiAoIXN0cikgcmV0dXJuIDA7CisgIGlmIChzc2NhbmYoc3RyLCAiJXMgJXMiLCBtYXN0ZXIsIGd1aWxkKSE9MikgcmV0dXJuIDA7CisgIGlmICghbWFzdGVyIHx8ICFndWlsZCkgcmV0dXJuIDA7CisgIGlmICghIi9zZWN1cmUvbWFzdGVyIi0+YWRkX2d1aWxkX21hc3RlcihtYXN0ZXIsZ3VpbGQpKQorICAgIHdyaXRlKCJIYXQgbmljaHQgZnVua3Rpb25pZXJ0LlxuIik7CisgIGVsc2UKKyAgICB3cml0ZSAoIk9rLlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IF9yZW1vdmVndWlsZG1hc3RlcihzdHJpbmcgc3RyKQoreworICBzdHJpbmcgbWFzdGVyLCBndWlsZDsKKyAgCisgIGlmICghR09EX1NFQ1VSSVRZKQorICB7CisgICAgd3JpdGUgKCJEYXMgZGFyZnN0IER1IG5pY2h0IVxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgX25vdGlmeV9mYWlsKCJTeW50YXg6IHJlbW92ZWd1aWxkbWFzdGVyIDx1c2VyPiA8Z3VpbGQ+XG4iKTsKKyAgaWYgKCFzdHIpIHJldHVybiAwOworICBpZiAoc3NjYW5mKHN0ciwgIiVzICVzIiwgbWFzdGVyLCBndWlsZCkhPTIpIHJldHVybiAwOworICBpZiAoIW1hc3RlciB8fCAhZ3VpbGQpIHJldHVybiAwOworICBpZiAoISIvc2VjdXJlL21hc3RlciItPnJlbW92ZV9ndWlsZF9tYXN0ZXIobWFzdGVyLGd1aWxkKSkKKyAgICB3cml0ZSgiSGF0IG5pY2h0IGZ1bmt0aW9uaWVydC5cbiIpOworICBlbHNlCisgICAgd3JpdGUoIk9rLlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IHNpbm5lcnMoc3RyaW5nIGFyZykKK3sgICBzdHJpbmcgKnBhcnRzOworICAgIGludCAgICBpOworCisgICAgaWYgKCAhSVNfREVQVVRZKHRoaXNfb2JqZWN0KCkpICkKKyAgICAgIHJldHVybiAwOworCisgICAgYXJnPV91bnBhcnNlZF9hcmdzKCl8fGFyZzsKKworICAgIG5vdGlmeV9mYWlsKAorICAgICAgICAiU3ludGF4OiBzdWVuZGVyID8gICAgICAgICAgICAgID0+IExpc3RlIGFsbGVyIEVpbmdldHJhZ2VuZW5cbiIrCisgICAgICAgICIgICAgICAgIHN1ZW5kZXIgPG5hbWU+ICAgICAgICAgPT4gRWludHJhZWdlIGxlc2VuXG4iKworICAgICAgICAiICAgICAgICBzdWVuZGVyICs8bmFtZT4gPHRleHQ+ID0+IEVpbnRyYWcgaGluenVmdWVnZW5cbiIrCisgICAgICAgICIgICAgICAgIHN1ZW5kZXIgLTxuYW1lPiA8bnI+ICAgPT4gRWludHJhZyBsb2VzY2hlblxuIisKKyAgICAgICAgIiAgICAgICAgc3VlbmRlciAhICAgICAgICAgICAgICA9PiBBbGxlIEVpbnRyYWVnZSBkdW1wZW5cbiIrCisgICAgICAgICIgICAgICAgIHN1ZW5kZXIgKiAgICAgICAgICAgICAgPT4gQWxsZSBFaW50cmFlZ2UgYW56ZWlnZW5cbiIpOworCisgICAgaWYgKCAhc3RyaW5ncChhcmcpIHx8IChzaXplb2YoYXJnKTwxKSApCisgICAgICByZXR1cm4gMDsKKworICAgIGlmICggYXJnPT0iPyIgKQorICAgIHsKKyAgICAgICAgd3JpdGUoY2FsbF9vdGhlcigiL3NlY3VyZS9zaW5tYXN0ZXIiLCJMaXN0U2lubmVycyIpKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIGlmICggYXJnPT0iISIgKQorICAgIHsKKyAgICAgICAgd3JpdGUoY2FsbF9vdGhlcigiL3NlY3VyZS9zaW5tYXN0ZXIiLCJEdW1wIikpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgaWYgKCBhcmc9PSIqIiApCisgICAgeworICAgICAgICBNb3JlKChzdHJpbmcpY2FsbF9vdGhlcigiL3NlY3VyZS9zaW5tYXN0ZXIiLCJEdW1wIiwxKSk7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIGlmICggKGk9c2l6ZW9mKHBhcnRzPWV4cGxvZGUoYXJnLCIgIikpKTwxICkKKyAgICAgIHJldHVybiAwOworCisgICAgaWYgKCBwYXJ0c1swXVswLi4wXT09Ii0iICkKKyAgICB7CisgICAgICBpZiAoIGk8MiApCisgICAgICAgIHJldHVybiAwOworICAgICAgd3JpdGUoY2FsbF9vdGhlcigiL3NlY3VyZS9zaW5tYXN0ZXIiLCJSZW1vdmVTaW4iLAorICAgICAgICAgICAgbG93ZXJzdHJpbmcocGFydHNbMF1bMS4uXSksCisgICAgICAgICAgICB0b19pbnQocGFydHNbMV0pKSk7CisgICAgfQorICAgIGVsc2UgaWYgKCBwYXJ0c1swXVswLi4wXT09IisiICkKKyAgICB7CisgICAgICBpZiAoIGk8MiApCisgICAgICAgIHJldHVybiAwOworICAgICAgd3JpdGUoY2FsbF9vdGhlcigiL3NlY3VyZS9zaW5tYXN0ZXIiLCJBZGRTaW4iLAorICAgICAgICAgICAgbG93ZXJzdHJpbmcocGFydHNbMF1bMS4uXSksCisgICAgICAgICAgICBpbXBsb2RlKHBhcnRzWzEuLl0sIiAiKSkpOworICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgaWYgKCBpPjEgKQorICAgICAgICByZXR1cm4gMDsKKyAgICAgIHdyaXRlKGNhbGxfb3RoZXIoIi9zZWN1cmUvc2lubWFzdGVyIiwiTGlzdFNpbnMiLAorICAgICAgICAgICAgbG93ZXJzdHJpbmcocGFydHNbMF0pKSk7CisgICAgfQorICAgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IGJhbmlzaChzdHJpbmcgc3RyKQoreworICBzdHJpbmcgZ3J1bmQsIG5hbWU7CisgIGludCBmb3JjZTsKKworICBpZiAoICFMT1JEX1NFQ1VSSVRZICYmICFJU19ERVBVVFkoc2VjdXJlX2V1aWQoKSkgKQorICAgICAgcmV0dXJuIDA7CisKKyAgaWYgKCAhc3RyIHx8ICFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpICkgeworICAgICAgd3JpdGUoIlN5bnRheDogYmFuaXNoIFstZl0gPG5hbWU+IFs8Z3J1bmQ+XVxuIik7CisgICAgICByZXR1cm4gMTsKKyAgfQorCisgIHN0ciA9IF91bnBhcnNlZF9hcmdzKCk7CisKKyAgaWYgKCBleHBsb2RlKHN0ciwgIiAiKVswXSA9PSAiLWYiICl7CisgICAgICBzdHIgPSBpbXBsb2RlKCBleHBsb2RlKHN0ciwgIiAiKVsxLi5dLCAiICIgKTsKKyAgICAgIGZvcmNlID0gMTsKKyAgfQorCisgIGlmICggc3NjYW5mKCBzdHIsICIlcyAlcyIsIG5hbWUsIGdydW5kICkgIT0gMiApCisgICAgICBuYW1lPXN0cjsKKworICBpZiAoICFuYW1lIHx8ICFzaXplb2YobmFtZSkgKXsKKyAgICB3cml0ZSgiU3ludGF4OiBiYW5pc2ggWy1mXSA8bmFtZT4gWzxncnVuZD5dXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIG5hbWU9bG93ZXJfY2FzZShuYW1lKTsKKyAgIi9zZWN1cmUvbWFzdGVyIi0+QmFuaXNoTmFtZSggbmFtZSwgZ3J1bmQsIGZvcmNlICk7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IG1iYW5pc2goc3RyaW5nIHN0cikKK3sKKyAgICBzdHJpbmcgZ3J1bmQsIG5hbWUsICpuYW1lbiwgdHh0LCAqZHVtbXk7CisgICAgbWFwcGluZyBsaXN0OworICAgIGludCBpOworCisgICAgaWYgKCAhSVNfREVQVVRZKHNlY3VyZV9ldWlkKCkpICkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBfbm90aWZ5X2ZhaWwoICJTeW50YXg6IG1iYW5pc2ggPG5hbWU+IFs8Z3J1bmQ+XVxuIiApOworCisgICAgaWYgKCAhc3RyIHx8ICFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpICl7CisgICAgICAgIGlmICggIW1hcHBpbmdwKGxpc3QgPSAobWFwcGluZykiL3NlY3VyZS9tZXJsaW4iLT5NQmFuaXNoTGlzdCgpKSB8fAorICAgICAgICAgICAgICEoaSA9IHNpemVvZihsaXN0KSkgKXsKKyAgICAgICAgICAgIHdyaXRlKCAiTW9tZW50YW4gaXN0IGtlaW4gU3BpZWxlciBhdWYgZGVyIG1iYW5pc2gtTGlzdGUuXG4iICk7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorCisgICAgICAgIHR4dCA9ICIgICAgICBOYW1lICAgICB8IGdlYmFuaXNodCB2b24gfCAgICAgICAgICAgICAgICAgICAgR3J1bmRcbiIgKworICAgICAgICAgICAgIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iICsKKyAgICAgICAgICAgICI9PT09PT09PT09PT09PT09PT1cbiI7CisKKyAgICAgICAgbmFtZW4gPSBzb3J0X2FycmF5KCBtX2luZGljZXMobGlzdCksICMnPC8qJyovICk7CisKKyAgICAgICAgZm9yICggOyBpLS07ICl7CisgICAgICAgICAgICBkdW1teSA9IGV4cGxvZGUoIGJyZWFrX3N0cmluZyggbGlzdFtuYW1lbltpXSwwXSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICItLSBrZWluZSBCZWdydWVuZHVuZyAtLSIsIDQ1ICksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJcbiIgKSAtICh7IiJ9KTsKKworICAgICAgICAgICAgdHh0ICs9IHNwcmludGYoICIgICUtMTFzICB8ICAlLTExcyAgfCAgJXNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZSggbmFtZW5baV0gKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKCBsaXN0W25hbWVuW2ldLDFdIHx8ICIiICksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZSggaW1wbG9kZSggZHVtbXksICJcbiAgICAgICAgICAgICAgIHwiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgICAgICAgICAgICAgIHwgICIgKSApICk7CisgICAgICAgIH0KKworICAgICAgICBNb3JlKHR4dCk7CisKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgaWYgKCBzc2NhbmYoIHN0ciwgIiVzICVzIiwgbmFtZSwgZ3J1bmQgKSAhPTIgKQorICAgICAgICBuYW1lID0gc3RyOworCisgICAgaWYgKCAhbmFtZSB8fCAhc2l6ZW9mKG5hbWUpICkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBuYW1lID0gbG93ZXJfY2FzZShuYW1lKTsKKworICAgIGlmICggIWdydW5kIHx8ICFzdHJpbmdwKGdydW5kKSB8fCBsb3dlcl9jYXNlKGdydW5kKSAhPSAibG9lc2NoZW4iICl7CisgICAgICAgICIvc2VjdXJlL21lcmxpbiItPk1CYW5pc2hJbnNlcnQoIG5hbWUsIGdydW5kLCB0aGlzX2ludGVyYWN0aXZlKCkgKTsKKyAgICAgICAgd3JpdGUoICJEdSBzZXR6dCAiK2NhcGl0YWxpemUobmFtZSkrIiBhdWYgZGllIE1CYW5pc2gtTGlzdGUuXG4iICk7CisgICAgfQorICAgIGVsc2V7CisgICAgICAgIGlmICggIUFSQ0hfU0VDVVJJVFkgKXsKKyAgICAgICAgICAgIHdyaXRlKCAiRGFzIGR1ZXJmZW4gbnVyIEVyem1hZ2llci5cbiIgKTsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgICAgICIvc2VjdXJlL21lcmxpbiItPk1CYW5pc2hEZWxldGUoIG5hbWUgKTsKKyAgICAgICAgd3JpdGUoICJEdSBsb2VzY2h0ICIrY2FwaXRhbGl6ZShuYW1lKSsiIHZvbiBkZXIgTUJhbmlzaC1MaXN0ZS5cbiIgKTsKKyAgICB9CisKKyAgICByZXR1cm4gMTsKK30KKworCitzdGF0aWMgaW50IHRiYW5pc2goIHN0cmluZyBzdHIgKQoreworICBzdHJpbmcgbmFtZTsKKyAgaW50IGRheXM7CisKKyAgaWYgKCAhSVNfREVQVVRZKHNlY3VyZV9ldWlkKCkpICkKKyAgICAgIHJldHVybiAwOworCisgIF9ub3RpZnlfZmFpbCgiU3ludGF4OiB0YmFuaXNoIDxuYW1lPiA8dGFnZT5cbiIpOworCisgIGlmICggIXN0ciB8fCAhc3RyaW5ncChzdHIpIHx8ICFzaXplb2Yoc3RyKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCBzc2NhbmYoc3RyLCIlcyAlZCIsbmFtZSxkYXlzKSAhPSAyICkKKyAgICAgIHJldHVybiAwOworCisgIGlmICggIW5hbWUgfHwgIXNpemVvZihuYW1lKSApCisgICAgcmV0dXJuIDA7CisKKyAgbmFtZSA9IGxvd2VyX2Nhc2UobmFtZSk7CisKKyAgaWYgKCAhIi9zZWN1cmUvbWFzdGVyIi0+VEJhbmlzaE5hbWUoIG5hbWUsIGRheXMgKSApCisgICAgICByZXR1cm4gMTsKKworICBpZiAoICFkYXlzICkKKyAgICAgIHdyaXRlKCAiT2theSwga2VpbmUgU3BpZWxwYXVzZSBmdWVyICIrY2FwaXRhbGl6ZShuYW1lKSsiIG1laHIuXG4iICk7CisgIGVsc2UKKyAgICAgIHdyaXRlKCAiRHUgdmVycGFzc3QgIitjYXBpdGFsaXplKG5hbWUpKyIgZWluZSBTcGllbHBhdXNlIGZ1ZXIgIisKKyAgICAgICAgICAgICAoZGF5cz4wID8gZGF5cysiIFRhZ2UiIDogImxhYWFhbmdlIFplaXQiKSsiLlxuIiApOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBzYmFuaXNoKCBzdHJpbmcgc3RyICkKK3sKKyAgICBzdHJpbmcgaXA7CisgICAgaW50IGRheXM7CisgICAgbWFwcGluZyBzaXRlczsKKworICAgIC8vIE1pbmRlc3RlbnMgTDI2IGZ1ZXIgZGllc2VuIEJlZmVobAorICAgIGlmICggc2VjdXJlX2xldmVsKCkgPD0gRE9NQUlOTUVNQkVSX0xWTCApCisgICAgICAgIHJldHVybiAwOworCisgICAgaWYgKCAhc3RyIHx8ICFzdHJpbmdwKHN0cikgfHwgIXNpemVvZihzdHIpICl7CisgICAgICAgIGlmICggIXNpemVvZihzaXRlcyA9IChtYXBwaW5nKU1BU1RFUi0+U2l0ZUJhbmlzaCggMCwgMCApKSApeworICAgICAgICAgICAgd3JpdGUoICJFcyBzaW5kIHp1ciBaZWl0IGtlaW5lIEFkcmVzc2VuIGdlc3BlcnJ0IVxuIiApOworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKworICAgICAgICBpcCA9ICIgICAgICBBZHJlc3NlICAgICAgfCAgZ2VzcGVycnQgYmlzICAgICAgICAgICAgICAgICB8ICBnZXNwZXJydCAiCisgICAgICAgICAgICArICJkdXJjaFxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iCisgICAgICAgICAgICArICI9PT09PT09PT09PT09PVxuIjsKKworICAgICAgICBpbnQgKmtleXMgPSBzb3J0X2FycmF5KCBtX2luZGljZXMoc2l0ZXMpLCAjJzwvKicqLyApOworCisgICAgICAgIGZvcmVhY2goaW50IGtleSA6IGtleXMpIHsKKyAgICAgICAgICAgIGlwICs9IHNwcmludGYoICIgICU6MTUtcyAgfCAgJToyNy1zICB8ICAlLXNcbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBJUHY0X2ludDJhZGRyKGtleSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXRlc1trZXldID4gMCA/IGR0aW1lKHNpdGVzW2tleV0pIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJTdC4gTmltbWVybGVpbnN0YWciLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoc2l0ZXNba2V5LCAxXSkgKTsKKyAgICAgICAgfQorICAgICAgICB3cml0ZSggaXAgKyAiXG4iICk7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIF9ub3RpZnlfZmFpbCgiU3ludGF4OiBzYmFuaXNoIDxudW1lcmlzY2hlIGlwPiA8dGFnZT5cbiIpOworCisgICAgaWYgKCBzc2NhbmYoIHRoaXNfcGxheWVyKCktPl91bnBhcnNlZF9hcmdzKCksICIlcyAlZCIsIGlwLCBkYXlzICkgIT0gMiApCisgICAgICAgIHJldHVybiAwOworCisgICAgaWYgKCAhaXAgfHwgIXNpemVvZihpcCkgKQorICAgICAgICByZXR1cm4gMDsKKworLy8gICAgX25vdGlmeV9mYWlsKCAiVW5ndWVsdGlnZXMgQWRyZXNzLUZvcm1hdCFcbiIgKTsKKworICAgIGlmICggIWRheXMgKXsKKyAgICAgICAgaW50IHJlcz0oaW50KU1BU1RFUi0+U2l0ZUJhbmlzaChpcCwgMCk7CisgICAgICAgIGlmICggcmVzID09IDEgKQorICAgICAgICAgICAgIHByaW50ZiggIkRpZSBBZHJlc3NlICclcycgaXN0IGpldHp0IG5pY2h0IG1laHIgZ2VzcGVycnQuXG4iLAorICAgICAgICAgICAgICAgICAgICAgaXAgKTsKKyAgICAgICAgZWxzZSBpZiAoIHJlcyA9PSAwICkKKyAgICAgICAgICAgICBwcmludGYoICJEaWUgQWRyZXNzZSAnJXMnIHdhciBnYXIgbmljaHQgZ2VzcGVycnQhXG4iLAorICAgICAgICAgICAgICAgICAgICAgaXAgKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcHJpbnRmKCAiRHUgZGFyZnN0IG51ciBlaWdlbmUgU3BlcnJ1bmdlbiB3aWVkZXIgYXVmaGViZW4hXG4iICk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpbnQgcmVzOworICAgICAgICBpZiAoIGRheXMgIT0gMSAmJiAhSVNfREVQVVRZKHNlY3VyZV9ldWlkKCkpICkKKyAgICAgICAgICAgIHdyaXRlKCAiRHUgZGFyZnN0IEFkcmVzc2VuIG51ciBmdWVyIGVpbmVuIFRhZyBzcGVycmVuIVxuIiApOworICAgICAgICBlbHNlIGlmICggKHJlcyA9IChpbnQpTUFTVEVSLT5TaXRlQmFuaXNoKGlwLCBkYXlzKSkgPT0gMSApCisgICAgICAgICAgICAgcHJpbnRmKCAiRGllIEFkcmVzc2UgJyVzJyBpc3QgamV0enQgZnVlciAlcyBnZXNwZXJydC5cbiIsCisgICAgICAgICAgICAgICAgICAgICBpcCwgKGRheXMgPiAxID8gc3ByaW50ZiggIiVkIFRhZ2UiLCBkYXlzICkgOgorICAgICAgICAgICAgICAgICAgICAgIChkYXlzID4gMCA/ICJlaW5lbiBUYWciIDogImltbWVyIikpICk7CisgICAgICAgIGVsc2UgaWYgKCByZXMgPT0gLTEgKQorICAgICAgICAgICAgd3JpdGUoICJEdSBkYXJmc3QgIiArIChMT1JEX1NFQ1VSSVRZID8gIjI1NSBJUC1BZHJlc3NlbiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAibnVyIGVpbnplbG5lIElQLUFkcmVzc2VuIikgKyAiIHNwZXJyZW4hXG4iICk7CisgICAgICAgIGVsc2UgaWYgKCByZXMgPT0gLTIgKQorICAgICAgICAgICAgd3JpdGUoICJEdSBoYXN0IHNjaG9uIGdlbnVnIEFkcmVzc2VuIGdlc3BlcnJ0IVxuIiApOworICAgIH0KKworICAgIHJldHVybiAxOworfQorCmRpZmYgLS1naXQgYS9zdGQvc2hlbGxzL21hZ2llci9jb21tLmMgYi9zdGQvc2hlbGxzL21hZ2llci9jb21tLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGNiZDI2NgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvbWFnaWVyL2NvbW0uYwpAQCAtMCwwICsxLDE0OSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIGNvbW0uYworLy8KKy8vICRJZDogY29tbS5jIDg3NTUgMjAxNC0wNC0yNiAxMzoxMzo0MFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxtYWdpZXIuaD4KKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8cGxheWVyLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBFQ0hPQUxMICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjCisKK3N0YXRpYyBpbnQgX2VjaG9hbGwoc3RyaW5nIHN0cikKK3sKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpKQorICAgIHJldHVybiBVU0FHRSgiZWNob2FsbCA8dGV4dD5cbiIpOworICBzdHI9YnJlYWtfc3RyaW5nKHN0cik7CisgIHNob3V0KHN0cik7CisgIHByaW50ZihzdHIpOworICByZXR1cm4gMTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgRUNIT1RPICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjCisKK3N0YXRpYyBpbnQgX2VjaG90byhzdHJpbmcgc3RyKQoreworICBvYmplY3Qgb2I7CisgIHN0cmluZyB3aG87CisgIHN0cmluZyBtc2c7CisKKyAgaWYgKCEoc3RyPV91bnBhcnNlZF9hcmdzKCkpfHxzc2NhbmYoc3RyLCAiJXMgJXMiLCB3aG8sIG1zZykgIT0gMikKKyAgICByZXR1cm4gVVNBR0UoImVjaG90byA8c3BpZWxlcj4gPHRleHQ+XG4iKTsKKyAgb2IgPSBmaW5kX3BsYXllcihsb3dlcl9jYXNlKHdobykpOworICBpZiAoIW9iKQorICB7CisgICAgcHJpbnRmKCJlY2hvdG86IEVzIGlzdCBrZWluIFNwaWVsZXIgJyVzJyBlaW5nZWxvZ2d0LlxuIix3aG8pOworICAgIHJldHVybiAxOworICB9CisgIG1zZz1icmVha19zdHJpbmcobXNnLDc4KTsKKyAgdGVsbF9vYmplY3Qob2IsbXNnKTsKKyAgcHJpbnRmKCIlcy0+JXMiLG9iLT5OYW1lKFdFTiksbXNnKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgTUVDSE8gIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMKKworc3RhdGljIGludCBfbWVjaG8oc3RyaW5nIHN0cikgIHsKKyAgb2JqZWN0ICp3aG87CisgIGludCBpOworCisgIGlmICghc2l6ZW9mKHN0cj1fdW5wYXJzZWRfYXJncygpKSkKKyAgICByZXR1cm4gVVNBR0UoIm1lY2hvIDx0ZXh0PlxuIik7CisgIHdobz11c2VycygpOworICBpPXNpemVvZih3aG8pOworICB3aGlsZShpLS0paWYgKElTX0xFQVJORVIod2hvW2ldKSkKKyAgICAgIHRlbGxfb2JqZWN0KHdob1tpXSwgYnJlYWtfc3RyaW5nKHN0ciw3OCkpOworICByZXR1cm4gMTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgUElORyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIworCitzdGF0aWMgaW50IF9waW5nKHN0cmluZyBzdHIpCit7CisgIG9iamVjdCBwbDsKKworICBpZiAoIXNpemVvZihzdHIpKQorICAgIHJldHVybiBVU0FHRSgicGluZyA8c3BpZWxlcm5hbWU+XG4iKTsKKyAgaWYgKCEocGw9ZmluZF9wbGF5ZXIobG93ZXJfY2FzZShzdHIpKSkpCisgICAgcmV0dXJuCisgICAgICBfbm90aWZ5X2ZhaWwoc3ByaW50ZigicGluZzogU3BpZWxlciAlcyBuaWNodCBnZWZ1bmRlbi5cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKHN0cikpKSwwOworICB0ZWxsX29iamVjdChwbCxzcHJpbnRmKCIlcyBwaW5ndCBEaWNoIGFuLlxhXG4iLGNhcGl0YWxpemUoZ2V0dWlkKCkpKSk7CisgIHJldHVybiBwcmludGYoIlBJTkdHR0dHR0chIERBUyBzb2xsdGUgJXMgYXVmIERpY2ggYXVmbWVya3NhbSAiCisgICAgICAgICAgICAgICAgImdlbWFjaHQgaGFiZW4uXG4iLGNhcGl0YWxpemUoZ2V0dWlkKHBsKSkpLDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIE9ST1BBWCAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIworCitpbnQgX29yb3BheChzdHJpbmcgY21kbGluZSkKK3sKKyAgaW50IGxldmVsLG9sZCxuZXc7CisKKyAgY21kbGluZT1fdW5wYXJzZWRfYXJncygpOworICBvbGQ9UXVlcnlQcm9wKFBfRUFSTVVGRlMpOworICBpZiAoIXNpemVvZihjbWRsaW5lKXx8Y21kbGluZT09IjAiKQorICB7CisgICAgaWYgKG9sZCkKKyAgICB7CisgICAgICBwcmludGYoIkR1IG5pbW1zdCBkYXMgT3JvcGF4IGF1cyBEZWluZW4gT2hyZW4gdW5kIGhvZXJzdCAiCisgICAgICAgICAgICAgIndpZWRlciBhbGxlbiBhbmRlcmVuIHp1LlxuIik7CisgICAgICBTZXRQcm9wKFBfRUFSTVVGRlMsIDApOworICAgIH0KKyAgICBlbHNlCisgICAgICBwcmludGYoIkR1IGhhc3QgZG9jaCBnYXIga2VpbiBPcm9wYXggaW4gZGVuIE9ocmVuLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKHNzY2FuZihjbWRsaW5lLCAiJWQiLCBsZXZlbCkgPT0gMCB8fCBsZXZlbCA8IDEpCisgICAgcmV0dXJuIFVTQUdFKCJvcm9wYXggWzxtYWdpZXJsZXZlbD5dXG4iKTsKKyAgaWYgKChuZXc9U2V0UHJvcChQX0VBUk1VRkZTLCBsZXZlbCkpPT1sZXZlbCkKKyAgeworICAgIGlmIChuZXc9PW9sZCkKKyAgICAgIHJldHVybiBwcmludGYoIkR1IGhhdHRlc3QgRGVpbmUgT3JvcGF4bWVuZ2Ugc2Nob24gYXVmIE1hZ2llcmxldmVsICIKKyAgICAgICAgICAgICAgICAgICAgIiVkIGFuZ2VwYXNzdC5cbiIsbGV2ZWwpLDE7CisgICAgaWYgKG5ldz5vbGQpCisgICAgICByZXR1cm4gcHJpbnRmKCJEdSBzdG9wZnN0IERpciBzb3ZpZWwgT3JvcGF4IGluIGRpZSBPaHJlbiwgZGFzcyAiCisgICAgICAgICAgICAgICAgICAgICJEdSBudXIgbm9jaCAlcyBhYlxuTGV2ZWwgJWQgaG9lcnN0LlxuIiwKKyAgICAgICAgICAgICAgICAgICAgbGV2ZWw+PUxFQVJORVJfTFZMPyJNYWdpZXIiOiJTZWhlciIsbGV2ZWwpLDE7CisgICAgcmV0dXJuIHByaW50ZigiRHUgbmltbXN0IHNvdmllbCBPcm9wYXggYXVzIGRlbiBPaHJlbiwgZGFzcyBEdSBhYiAiCisgICAgICAgICAgICAgICAgICAic29mb3J0IHdpZWRlciAlcyBhYlxuTGV2ZWwgJWQgdmVyc3RlaHN0LlxuIiwKKyAgICAgICAgICAgICAgICAgIGxldmVsPj1MRUFSTkVSX0xWTD8iTWFnaWVyIjoiU2VoZXIiLGxldmVsKSwxOworICB9CisgIHJldHVybiBwcmludGYoIkR1IHN0b3Bmc3QgdW5kIHN0b3Bmc3QsIGJpcyBEaXIgZGFzIE9yb3BheCB3aWVkZXIgenVyICIKKyAgICAgICAgICAgICAgICAiTmFzZSBoZXJhdXNrb21tdC5cbkxlaWRlciBtdXNzdCBEdSBkYW1pdCBNYWdpZXIgYWIgTGV2ZWwgIgorICAgICAgICAgICAgICAgICIlZCB3ZWl0ZXJoaW4gaG9lcmVuLlxuIixuZXcpLDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgSU5JVElBTElTSUVSVU5HICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjCisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfbG9jYWxjbWRzKCkKK3sKKyAgcmV0dXJuCisgICAgKHsoeyJvcm9wYXgiLCJfb3JvcGF4IiwwLExFQVJORVJfTFZMfSksCisgICAgICAoeyJlY2hvdG8iLCJfZWNob3RvIiwwLExFQVJORVJfTFZMfSksCisgICAgICAoeyJlY2hvYWxsIiwiX2VjaG9hbGwiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAgICh7Im1lY2hvIiwiX21lY2hvIiwwLExFQVJORVJfTFZMfSksCisgICAgICAoeyJwaW5nIiwiX3BpbmciLDAsTEVBUk5FUl9MVkx9KX0pOworfQpkaWZmIC0tZ2l0IGEvc3RkL3NoZWxscy9tYWdpZXIvZmlsZWVkaXQuYyBiL3N0ZC9zaGVsbHMvbWFnaWVyL2ZpbGVlZGl0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjRkZjBhNQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvbWFnaWVyL2ZpbGVlZGl0LmMKQEAgLTAsMCArMSw3MTggQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvL2ZpbGVlZGl0LmMKKy8vCisvLyAkSWQ6IGZpbGVlZGl0LmMgOTE0MiAyMDE1LTAyLTA0IDIyOjE3OjI5WiBaZXNzdHJhICQKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKy8vI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8aW5wdXRfdG8uaD4KKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxtYWdpZXIuaD4KKyNpbmNsdWRlIDxwbGF5ZXIuaD4KKyNpbmNsdWRlIDxmaWxlcy5oPgorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBJTklUSUFMSVNJRVJVTkcgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIworCittaXhlZCBfcXVlcnlfbG9jYWxjbWRzKCkKK3sKKyAgcmV0dXJuICh7ICh7ImNwIiwiX2NwIiwwLFdJWkFSRF9MVkx9KSwKKyAgICAgICAgICAgICh7Im12IiwiX2NwIiwwLFdJWkFSRF9MVkx9KSwKKyAgICAgICAgICAgICh7InJtIiwiX3JtIiwwLFdJWkFSRF9MVkx9KSwKKyAgICAgICAgICAgICh7InJtZGlyIiwiX3JtZGlyIiwwLFdJWkFSRF9MVkx9KSwKKyAgICAgICAgICAgICh7Im1rZGlyIiwiX21rZGlyIiwwLFdJWkFSRF9MVkx9KSwKKyAgICAgICAgICAgICh7ImVkIiwiX2VkIiwwLFdJWkFSRF9MVkx9KX0pOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgRUQgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIworCisKKy8vCisvLyBfZWRfZmlsZTogTWVocmVyZSBGaWxlcyBoaW50ZXJlaW5hbmRlciBlZGl0aWVyZW4KKy8vCisKK3ByaXZhdGUgbm9zYXZlIHN0cmluZyAqX2VkX2NhY2hlOworCitwcml2YXRlIHZvaWQgX2VkX2ZpbGUoKQoreworICBpZiAoIXNpemVvZihfZWRfY2FjaGUpKSByZXR1cm47CisgIHByaW50ZigiZWQ6IE5hZWNoc3RlIERhdGVpOiAlc1xuIixfZWRfY2FjaGVbMF0pOworICBlZChfZWRfY2FjaGVbMF0sIl9lZF9maWxlIik7CisgIF9lZF9jYWNoZT1fZWRfY2FjaGVbMS4uXTsKKyAgcmV0dXJuOworfQorCisjaWYgX19WRVJTSU9OX18gPCAiMy4yLjkiCitwcml2YXRlIG1peGVkIF9lZF9zaXplX2ZpbHRlcihtaXhlZCAqYXJnKQoreworICBpZiAoYXJnW0ZJTEVTSVpFXT49LTEpIHJldHVybiBhcmdbRlVMTE5BTUVdOworICBwcmludGYoIiVzIGlzdCBlaW4gVmVyemVpY2huaXMuXG4iLGFyZ1tGVUxMTkFNRV0pOworICByZXR1cm4gMDsKK30KKyNlbmRpZgorCisvLworLy8gX21vcmU6IERhdGVpZW4gYW56ZWlnZW4KKy8vIGNtZGxpbmU6IEtvbW1hbmRvemVpbGUKKy8vCisKK3N0YXRpYyBpbnQgX2VkKHN0cmluZyBjbWRsaW5lKQoreworICBtaXhlZCAqYXJncywqYXJnczI7CisgIGludCBmbGFncyxpLGFyZ19zaXplOworICBjbWRsaW5lPV91bnBhcnNlZF9hcmdzKCk7CisgIGFyZ3M9cGFyc2VhcmdzKGNtZGxpbmUsJmZsYWdzLCIiLDEpOworICBpZiAoZmxhZ3M9PS0xfHwhKGFyZ19zaXplPXNpemVvZihhcmdzKSkpCisgICAgcmV0dXJuIFVTQUdFKCJlZCA8ZGF0ZWk+IFs8ZGF0ZWkyPi4uXSIpOworICB3aGlsZShhcmdfc2l6ZS0tKQorICB7CisgICAgaWYgKHNpemVvZihhcmdzMj1maWxlX2xpc3QoYXJnc1thcmdfc2l6ZS4uYXJnX3NpemVdLE1PREVfRUQsMCwiLyIpKSkKKyAgICAgIGFyZ3NbYXJnX3NpemUuLmFyZ19zaXplXT1hcmdzMjsKKyAgICBlbHNlCisgICAgICBhcmdzW2FyZ19zaXplXT0oeyAiIiAsIC0xLCAwICwgKHN0cmluZykKKyAgICAgICAgICAgICAgY2FsbF9vdGhlcihtYXN0ZXIoKSwiX2dldF9wYXRoIixhcmdzW2FyZ19zaXplXSwKKyAgICAgICAgICAgICAgICAgIGdldHVpZCgpKX0pOworICB9CisjaWYgX19WRVJTSU9OX18gPCAiMy4yLjkiCisgIGFyZ3M9bWFwKGFyZ3MsIydfZWRfc2l6ZV9maWx0ZXIpLSh7MH0pOworI2Vsc2UKKyAgYXJncz1tYXAoYXJncywoOgorICAgICAgICAgIGlmICgkMVtGSUxFU0laRV0+PS0xKSByZXR1cm4gJDFbRlVMTE5BTUVdOworICAgICAgICAgIHByaW50ZigiJXMgaXN0IGVpbiBWZXJ6ZWljaG5pcy5cbiIsJDFbRlVMTE5BTUVdKTsKKyAgICAgICAgICByZXR1cm4gMDsgOikpLSh7MH0pOworI2VuZGlmCisgIGlmIChmbGFncz09LTF8fCFzaXplb2YoYXJncykpIHJldHVybiBVU0FHRSgiZWQgPGRhdGVpPiBbPGRhdGVpMj4uLl0iKTsKKyAgX2VkX2NhY2hlPWFyZ3M7CisgIF9lZF9maWxlKCk7CisgIHJldHVybiAxOworfQorCisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ1AgJiBNViAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjCisKK3N0YXRpYyB2b2lkIF9jcF9hc2tfY29weShtaXhlZCAqZmlsZWRhdGEsaW50IGR1bW15LCBpbnQgZmxhZ3MpOworc3RhdGljIHZvaWQgX2NwX2Fza19vdmVyd3JpdGUobWl4ZWQgKmZpbGVkYXRhLCBpbnQgbW9kZSwgaW50IGZsYWdzKTsKK3N0YXRpYyB2b2lkIF9tdl9hc2tfb3ZlcndyaXRlKG1peGVkICpmaWxlZGF0YSwgaW50IG1vZGUsIGludCBmbGFncyk7CisKK3N0YXRpYyBtaXhlZCBjcF9maWxlKG1peGVkIGZpbGVkYXRhLGludCBtb3ZlLGludCBmbGFncywgbWl4ZWQgKmRvX2RlbGV0ZSkKK3sKKyAgc3RyaW5nIHNvdXJjZSxkZXN0OworICBzb3VyY2U9KHN0cmluZylmaWxlZGF0YVtGVUxMTkFNRV07CisgIGRlc3Q9KHN0cmluZylmaWxlZGF0YVtERVNUTkFNRV07CisgIGlmIChzb3VyY2U9PWRlc3QpIHJldHVybiBFUlJPUihTQU1FX0ZJTEUsc291cmNlLFJFVF9GQUlMKTsKKyAgaWYgKCFNQVlfUkVBRChzb3VyY2UpKSByZXR1cm4gRVJST1IoTk9fUkVBRCxzb3VyY2UsUkVUX0pVTVApOworICBpZiAoIU1BWV9XUklURShkZXN0KSkgcmV0dXJuIEVSUk9SKE5PX1dSSVRFLGRlc3QsUkVUX0pVTVApOworICBpZiAoZmlsZWRhdGFbRklMRVNJWkVdPT0tMSkgcmV0dXJuIEVSUk9SKERPRVNOVF9FWElTVCxzb3VyY2UsUkVUX0pVTVApOworICBpZiAoZmlsZWRhdGFbRklMRVNJWkVdPT0tMikgLy8gUXVlbGxlIGlzdCBWZXJ6ZWljaG5pcworICB7CisgICAgc3dpdGNoKGZpbGVfc2l6ZShkZXN0KSkKKyAgICB7CisgICAgICBjYXNlIC0xOgorICAgICAgICBpZiAobW92ZSkKKyAgICAgICAgeworICAgICAgICAgIGlmIChyZW5hbWUoc291cmNlLGRlc3QpKSByZXR1cm4gRVJST1IoTk9fQ1JFQVRFX0RJUixkZXN0LFJFVF9KVU1QKTsKKyAgICAgICAgICBpZiAoZmxhZ3MmQ1BfVikgcHJpbnRmKEZJTEVfTU9WRUQsc291cmNlKTsKKyAgICAgICAgICByZXR1cm4gUkVUX0pVTVA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFta2RpcihkZXN0KSkgcmV0dXJuIEVSUk9SKE5PX0NSRUFURV9ESVIsZGVzdCxSRVRfSlVNUCk7CisgICAgICAgIGlmIChmbGFncyZDUF9WKSBwcmludGYoRElSX0NSRUFURUQsZGVzdCk7CisgICAgICBjYXNlIC0yOgorICAgICAgICBpZiAoIW1vdmUpIHJldHVybiBSRVRfT0s7CisgICAgICAgIGlmIChmaWxlZGF0YVtTVUJESVJTSVpFXT4wKSByZXR1cm4gUkVUX0RFTEVURTsKKyAgICAgICAgaWYgKCFybWRpcihzb3VyY2UpKSByZXR1cm4gRVJST1IoTk9fREVMRVRFLHNvdXJjZSxSRVRfRkFJTCk7CisgICAgICAgIGlmIChmbGFncyZNVl9WKSBwcmludGYoIm12OiAlczogUXVlbGx2ZXJ6ZWljaG5pcyB3dXJkZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImdlbG9lc2NodC5cbiIsc291cmNlKTsKKyAgICAgICAgcmV0dXJuIFJFVF9PSzsgICAgCisgICAgICBkZWZhdWx0OiAgcmV0dXJuIEVSUk9SKE5PX0RJUlMsZGVzdCxSRVRfSlVNUCk7CisgICAgfQorICB9CisgIHN3aXRjaChmaWxlX3NpemUoZGVzdCkpCisgIHsKKyAgICBjYXNlIC0yOiByZXR1cm4gRVJST1IoREVTVF9JU19ESVIsZGVzdCxSRVRfRkFJTCk7CisgICAgZGVmYXVsdDoKKyAgICAgIGlmIChmbGFncyZDUF9GKQorICAgICAgeworICAgICAgICBpZiAoIXJtKGRlc3QpKSByZXR1cm4gRVJST1IoREVTVF9OT19ERUxFVEUsZGVzdCxSRVRfRkFJTCk7CisgICAgICAgIGlmIChmbGFncyZDUF9WKSBwcmludGYoRklMRV9ERUxFVEVELGRlc3QpOworICAgICAgfQorICAgICAgZWxzZQorICAgICAgeworICAgICAgICBpZiAobW92ZSkgcmV0dXJuICMnX212X2Fza19vdmVyd3JpdGU7CisgICAgICAgIGVsc2UgcmV0dXJuICMnX2NwX2Fza19vdmVyd3JpdGU7CisgICAgICB9CisgICAgY2FzZSAtMToKKyAgICAgIGlmIChtb3ZlKQorICAgICAgeworICAgICAgICBpZiAocmVuYW1lKHNvdXJjZSxkZXN0KSkgcmV0dXJuIEVSUk9SKE5PX01PVkUsc291cmNlLFJFVF9GQUlMKTsKKyAgICAgICAgaWYgKGZsYWdzJkNQX1YpIHByaW50ZihGSUxFX01PVkVELHNvdXJjZSk7CisgICAgICAgIHJldHVybiBSRVRfT0s7CisgICAgICB9CisgICAgICBpZiAoY29weV9maWxlKHNvdXJjZSxkZXN0KSkgcmV0dXJuIEVSUk9SKE5PX0NPUFksc291cmNlLFJFVF9GQUlMKTsKKyAgICAgIGlmIChmbGFncyZDUF9WKSBwcmludGYoRklMRV9DT1BJRUQsc291cmNlKTsKKyAgICAgIHJldHVybiBSRVRfT0s7CisgIH0KKyAgcmV0dXJuIDA7IC8vIG5vdC1yZWFjaGVkCit9CisKK3N0YXRpYyB2b2lkIF9jcF9hc2tfb3ZlcndyaXRlMihzdHJpbmcgaW5wdXQsIG1peGVkICpmaWxlZGF0YSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgaW50ZXJhY3RpdmUsaW50IGZsYWdzLGludCBtb3ZlKQoreworICBpZiAoIXNpemVvZihpbnB1dCkpIGlucHV0PSIgIjsKKyAgaW5wdXQ9bG93ZXJfY2FzZShpbnB1dCk7CisgIHN3aXRjaChpbnB1dFswXSkKKyAgeworICAgIGNhc2UgJ3EnOgorICAgICAgcHJpbnRmKCIlcyBhYmdlYnJvY2hlbiFcbiIsbW92ZT8iQmV3ZWdlbiI6IktvcGllcmVuIik7CisgICAgICByZXR1cm47CisgICAgY2FzZSAnYSc6CisgICAgICBmbGFnc3w9Q1BfRjsKKyAgICAgIGlmICghKGZsYWdzJkNQX0kpKQorICAgICAgeworICAgICAgICBhc3luY2hyb24oZmlsZWRhdGEsIydjcF9maWxlLG1vdmUsZmxhZ3MsMCk7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICBjYXNlICd5JzoKKyAgICBjYXNlICdqJzoKKyAgICAgIGlmICghcm0oZmlsZWRhdGFbMF1bREVTVE5BTUVdKSkKKyAgICAgICAgcHJpbnRmKERFU1RfTk9fREVMRVRFICJVZWJlcmdlaGUgRGF0ZWkuLi5cbiIsZmlsZWRhdGFbMF1bREVTVE5BTUVdKTsKKyAgICAgIGVsc2UKKyAgICAgIHsKKyAgICAgICAgaWYgKGZsYWdzJkNQX1YpIHByaW50ZihGSUxFX0RFTEVURUQsZmlsZWRhdGFbMF1bREVTVE5BTUVdKTsKKyAgICAgICAgaWYgKG1vdmUpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAocmVuYW1lKGZpbGVkYXRhWzBdW0ZVTExOQU1FXSxmaWxlZGF0YVswXVtERVNUTkFNRV0pKQorICAgICAgICAgICAgcHJpbnRmKE5PX01PVkUgIlVlYmVyZ2VoZSBEYXRlaS4uLlxuIixmaWxlZGF0YVswXVtGVUxMTkFNRV0pOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgIGlmIChjb3B5X2ZpbGUoZmlsZWRhdGFbMF1bRlVMTE5BTUVdLGZpbGVkYXRhWzBdW0RFU1ROQU1FXSkpCisgICAgICAgICAgICBwcmludGYoTk9fQ09QWSAiVWViZXJnZWhlIERhdGVpLi4uXG4iLGZpbGVkYXRhWzBdW0ZVTExOQU1FXSk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICBjYXNlICduJzoKKyAgICAgIGlmIChmbGFncyZDUF9JKQorICAgICAgICBfY3BfYXNrX2NvcHkoZmlsZWRhdGFbMStmaWxlZGF0YVswXVtTVUJESVJTSVpFXS4uXSxtb3ZlLGZsYWdzKTsKKyAgICAgIGVsc2UKKyAgICAgICAgYXN5bmNocm9uKGZpbGVkYXRhWzErZmlsZWRhdGFbMF1bU1VCRElSU0laRV0uLl0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIydjcF9maWxlLG1vdmUsZmxhZ3MsMCk7CisgICAgICByZXR1cm47CisgICAgZGVmYXVsdDoKKyAgICAgIHByaW50ZigiS29tbWFuZG8gbmljaHQgdmVyc3RhbmRlbi5cbiIpOworICAgICAgX2NwX2Fza19vdmVyd3JpdGUoZmlsZWRhdGEsaW50ZXJhY3RpdmUsZmxhZ3MpOworICAgICAgcmV0dXJuOworICB9CisKK30KKworc3RhdGljIHZvaWQgX2NwX2Fza19vdmVyd3JpdGUobWl4ZWQgKmZpbGVkYXRhLCBpbnQgaW50ZXJhY3RpdmUsIGludCBmbGFncykKK3sKKyAgcHJpbnRmKCJEaWUgRGF0ZWkgJyVzJyBleGlzdGllcnQgc2Nob24uXG4iLAorICAgICAgICAgZmlsZWRhdGFbMF1bREVTVE5BTUVdKTsKKyAgaW5wdXRfdG8oIl9jcF9hc2tfb3ZlcndyaXRlMiIsSU5QVVRfUFJPTVBULCJVZWJlcnNjaHJlaWJlbj8gKGosbixhLHEpOiAiLAorICAgICAgZmlsZWRhdGEsaW50ZXJhY3RpdmUsZmxhZ3MsMCk7CisgIHJldHVybjsKK30KKworc3RhdGljIHZvaWQgX212X2Fza19vdmVyd3JpdGUobWl4ZWQgKmZpbGVkYXRhLCBpbnQgaW50ZXJhY3RpdmUsIGludCBmbGFncykKK3sKKyAgcHJpbnRmKCJEaWUgRGF0ZWkgJyVzJyBleGlzdGllcnQgc2Nob24uIiwKKyAgICAgICAgIGZpbGVkYXRhWzBdW0RFU1ROQU1FXSk7CisgIGlucHV0X3RvKCJfY3BfYXNrX292ZXJ3cml0ZTIiLElOUFVUX1BST01QVCwiVWViZXJzY2hyZWliZW4/IChqLG4sYSxxKTogIiwKKyAgICAgIGZpbGVkYXRhLGludGVyYWN0aXZlLGZsYWdzLDEpOworICByZXR1cm47Cit9CisKK3N0YXRpYyB2b2lkIF9jcF9hc2tfY29weTIoc3RyaW5nIGlucHV0LG1peGVkICpmaWxlZGF0YSxpbnQgbW9kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmbGFncyxpbnQgbW92ZSkKK3sKKyAgaWYgKCFzaXplb2YoaW5wdXQpKSBpbnB1dD0iICI7CisgIGlucHV0PWxvd2VyX2Nhc2UoaW5wdXQpOworICBzd2l0Y2goaW5wdXRbMF0pCisgIHsKKyAgICBjYXNlICd5JzoKKyAgICBjYXNlICdqJzoKKyAgICAgIGlmIChtb2RlPT0xKQorICAgICAgeworICAgICAgICBpZiAoIShmbGFncyZDUF9GKSkKKyAgICAgICAgeworICAgICAgICAgIGlmIChtb3ZlKSBfbXZfYXNrX292ZXJ3cml0ZShmaWxlZGF0YSwxLGZsYWdzKTsKKyAgICAgICAgICBlbHNlICAgICAgX2NwX2Fza19vdmVyd3JpdGUoZmlsZWRhdGEsMSxmbGFncyk7CisgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgICAgIGlmICghcm0oZmlsZWRhdGFbMF1bREVTVE5BTUVdKSkKKyAgICAgICAgeworICAgICAgICAgIHByaW50ZihERVNUX05PX0RFTEVURSAiVWViZXJnZWhlIERhdGVpLi4uXG4iLAorICAgICAgICAgICAgICAgICBmaWxlZGF0YVswXVtERVNUTkFNRV0pOworICAgICAgICAgIF9jcF9hc2tfY29weShmaWxlZGF0YVsxLi5dLG1vdmUsZmxhZ3MpOworICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoZmxhZ3MmQ1BfVikgcHJpbnRmKEZJTEVfREVMRVRFRCxmaWxlZGF0YVswXVtERVNUTkFNRV0pOworICAgICAgfQorICAgICAgaWYgKG1vZGU8MikKKyAgICAgIHsKKyAgICAgICAgaWYgKG1vdmUpIHJlbmFtZShmaWxlZGF0YVswXVtGVUxMTkFNRV0sZmlsZWRhdGFbMF1bREVTVE5BTUVdKTsKKyAgICAgICAgZWxzZSBjb3B5X2ZpbGUoZmlsZWRhdGFbMF1bRlVMTE5BTUVdLGZpbGVkYXRhWzBdW0RFU1ROQU1FXSk7CisgICAgICAgIF9jcF9hc2tfY29weShmaWxlZGF0YVsxLi5dLG1vdmUsZmxhZ3MpOworICAgICAgICByZXR1cm47CisgICAgICB9CisgICAgICBpZiAobW9kZT09MikKKyAgICAgIHsKKyAgICAgICAgaWYgKG1vdmUpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAocmVuYW1lKGZpbGVkYXRhWzBdW0ZVTExOQU1FXSxmaWxlZGF0YVswXVtERVNUTkFNRV0pKQorICAgICAgICAgICAgcHJpbnRmKE5PX01PVkUgIlVlYmVyZ2VoZSBWZXJ6ZWljaG5pcy4uLlxuIiwKKyAgICAgICAgICAgICAgICAgICBmaWxlZGF0YVswXVtGVUxMTkFNRV0pOworICAgICAgICAgIF9jcF9hc2tfY29weShmaWxlZGF0YVsxK2ZpbGVkYXRhWzBdW1NVQkRJUlNJWkVdLi5dLG1vdmUsZmxhZ3MpOworICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAobWtkaXIoZmlsZWRhdGFbMF1bREVTVE5BTUVdKSkKKyAgICAgICAgeworICAgICAgICAgIF9jcF9hc2tfY29weShmaWxlZGF0YVsxLi5dLDAsZmxhZ3MpOworICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBwcmludGYoTk9fQ1JFQVRFX0RJUiAiVWViZXJnZWhlIFZlcnplaWNobmlzLi4uXG4iLAorICAgICAgICAgICAgICAgZmlsZWRhdGFbMF1bREVTVE5BTUVdKTsKKyAgICAgIH0KKyAgICBjYXNlICduJzoKKyAgICAgIF9jcF9hc2tfY29weShmaWxlZGF0YVsoMStmaWxlZGF0YVswXVtTVUJESVJTSVpFXSkuLl0sMCxmbGFncyk7CisgICAgICByZXR1cm47CisgICAgY2FzZSAncSc6CisgICAgICBwcmludGYoIktvcGllcmVuIGFiZ2Vicm9jaGVuIVxuIik7CisgICAgICByZXR1cm47CisgICAgY2FzZSAnYSc6CisgICAgICBmbGFncyY9fkNQX0k7CisgICAgICBhc3luY2hyb24oZmlsZWRhdGEsIydjcF9maWxlLG1vdmUsZmxhZ3MsMCk7CisgICAgICByZXR1cm47CisgICAgZGVmYXVsdDoKKyAgICAgIHByaW50ZigiS29tbWFuZG8gbmljaHQgdmVyc3RhbmRlbi5cbiIpOworICAgICAgX2NwX2Fza19jb3B5KGZpbGVkYXRhLDAsZmxhZ3MpOworICAgICAgcmV0dXJuOworICB9Cit9CisKK3N0YXRpYyB2b2lkIF9jcF9hc2tfY29weShtaXhlZCAqZmlsZWRhdGEsaW50IG1vdmUsIGludCBmbGFncykKK3sKKyAgbWl4ZWQgZGF0YTsKKyAgc3RyaW5nIGRlc3Qsc291cmNlOworICBpbnQgZGVsZXRlX3N1YnMsanVtcDsKKworICBpZighc2l6ZW9mKGZpbGVkYXRhKSkKKyAgeworICAgIHByaW50ZigiJXM6IGFiZ2VzY2hsb3NzZW4uXG4iLG1vdmU/Im12IjoiY3AiKTsKKyAgICByZXR1cm47IAorICB9CisgIGRlc3Q9ZmlsZWRhdGFbMF1bREVTVE5BTUVdOworICBzb3VyY2U9ZmlsZWRhdGFbMF1bRlVMTE5BTUVdOworICBzd2l0Y2goMCkgICAvLyBicmVhayB3aXJrdCBkYW1pdCB3aWUgZWluIGdvdG8gZW5kX29mX3N3aXRjaAorICB7CisgICAgZGVmYXVsdDoKKyAgICBjYXNlIDA6IC8vIFNpbm5sb3MsIGFiZXIgZXIgY29tcGlsaWVydCBzb25zdCBuaWNodCA6KAorICAgICAganVtcD1maWxlZGF0YVswXVtTVUJESVJTSVpFXTsKKyAgICAgIGlmIChzb3VyY2U9PWRlc3QpCisgICAgICB7CisgICAgICAgIHByaW50ZihTQU1FX0ZJTEUsc291cmNlKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBpZiAoIU1BWV9SRUFEKHNvdXJjZSkpCisgICAgICB7CisgICAgICAgIHByaW50ZihOT19SRUFELHNvdXJjZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaWYgKCFNQVlfV1JJVEUoZGVzdCkpCisgICAgICB7CisgICAgICAgIHByaW50ZihOT19XUklURSxkZXN0KTsKKyAgICAgICAganVtcD0wOworICAgICAgICBicmVhazsKKyAgICAgIH0KKyAgICAgIGlmIChmaWxlZGF0YVswXVtGSUxFU0laRV09PS0xKQorICAgICAgeworICAgICAgICBwcmludGYoRE9FU05UX0VYSVNULHNvdXJjZSk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgaWYgKGZpbGVkYXRhWzBdW0ZJTEVTSVpFXT09LTIpIC8vIFF1ZWxsZSBpc3QgVmVyemVpY2huaXMKKyAgICAgIHsKKyAgICAgICAgaWYgKGZpbGVfc2l6ZShkZXN0KT4tMSkKKyAgICAgICAgeworICAgICAgICAgIHByaW50ZihOT19ESVJTLGRlc3QpOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlmIChmaWxlX3NpemUoZGVzdCk9PS0yKQorICAgICAgICB7CisgICAgICAgICAganVtcD0wOworICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHByaW50ZigiVmVyemVpY2huaXMgJyVzJyAlcz9cbiIsc291cmNlLAorICAgICAgICAgICAgICAgbW92ZT8iYmV3ZWdlbiI6ImtvcGllcmVuIik7CisgICAgICAgIGlucHV0X3RvKCJfY3BfYXNrX2NvcHkyIixJTlBVVF9QUk9NUFQsICIoaixuLGEscSkgIiwKKyAgICAgICAgICAgIGZpbGVkYXRhLDIsZmxhZ3MsbW92ZSk7CisgICAgICAgIHJldHVybjsKKyAgICAgIH0KKyAgICAgIGlmIChmaWxlX3NpemUoZGVzdCk9PS0yKQorICAgICAgeworICAgICAgICBwcmludGYoREVTVF9JU19ESVIsZGVzdCk7CisgICAgICAgIGJyZWFrOworICAgICAgfQorICAgICAgcHJpbnRmKCInJXMnICVzP1xuIixzb3VyY2UsbW92ZT8iYmV3ZWdlbiI6ImtvcGllcmVuIik7CisgICAgICBpbnB1dF90bygiX2NwX2Fza19jb3B5MiIsSU5QVVRfUFJPTVBULCAiKGosbixhLHEpICIsCisgICAgICAgICAgZmlsZWRhdGEsKGZpbGVfc2l6ZShkZXN0KSE9LTEpLGZsYWdzLG1vdmUpOworICAgICAgcmV0dXJuOworICB9CisgIF9jcF9hc2tfY29weShmaWxlZGF0YVsxK2p1bXAuLl0sbW92ZSxmbGFncyk7CisgIHJldHVybjsKK30KKworCitzdGF0aWMgaW50IF9jcChzdHJpbmcgY21kbGluZSkKK3sKKyAgbWl4ZWQgKmFyZ3M7CisgIGludCBmbGFnczsKKyAgc3RyaW5nIG1hc2s7CisgIHN0cmluZyBkZXN0LCpkZXN0MjsKKyAgY21kbGluZT1fdW5wYXJzZWRfYXJncygpOworICBhcmdzPXBhcnNlYXJncyhjbWRsaW5lLCZmbGFncyxDUF9PUFRTLDApOworICBpZiAoZmxhZ3M9PS0xfHwhc2l6ZW9mKGFyZ3MpKQorICAgIHJldHVybiBVU0FHRShxdWVyeV92ZXJiKCkrIiBbLSIgQ1BfT1BUUworICAgICAgICAgICAgICAgICAiXSA8ZGF0ZWkvdmVyej4gWzxkYXRlaTIvdmVyejI+IC4uLiBdIDx6aWVsPiBbPG1hc2tlPl0iKTsKKyAgaWYgKGZsYWdzJkNQX00pCisgIHsKKyAgICBtYXNrPWFyZ3NbPDFdOworICAgIGFyZ3M9YXJnc1swLi48Ml07CisgIH0KKyAgaWYgKCFkZXN0PXRvX2ZpbGVuYW1lKGFyZ3NbPDFdKSkKKyAgICAgcmV0dXJuIFVTQUdFKHF1ZXJ5X3ZlcmIoKSsiIFstIiBDUF9PUFRTCisgICAgICAgICAgIl0gPGRhdGVpL3Zlcno+IFs8ZGF0ZWkyL3ZlcnoyPiAuLi4gXSA8emllbD4gWzxtYXNrZT5dIik7CisgIGlmIChmaWxlX3NpemUoZGVzdCk9PS0xKQorICB7CisgICAgZGVzdDI9ZXhwbG9kZShkZXN0LCIvIik7CisgICAgaWYgKGZpbGVfc2l6ZShpbXBsb2RlKGRlc3QyWzAuLjwyXSwiLyIpKT09LTIpCisgICAgeworICAgICAgaWYgKGRlc3QyWzwxXT09IioiKQorICAgICAgICBkZXN0PWltcGxvZGUoZGVzdDJbMC4uPDJdLCIvIik7CisgICAgICBlbHNlCisgICAgICAgIGlmIChtZW1iZXIoZGVzdDJbPDFdLCcqJyk+LTF8fAorICAgICAgICAgICAgbWVtYmVyKGRlc3QyWzwxXSwnPycpPi0xKQorICAgICAgICAgcmV0dXJuIG5vdGlmeV9mYWlsKAorICAgICAgICAgIHNwcmludGYoIiVzOiBLZWluZSAqIHVuZCA/IGltIFppZWxuYW1lbiBlcmxhdWJ0LlxuIixxdWVyeV92ZXJiKCkpKSwwOworICAgIH0KKyAgICBlbHNlCisgICAgICByZXR1cm4gbm90aWZ5X2ZhaWwoCisgICAgICAgIHNwcmludGYoIiVzOiBEZXIgYW5nZWdlYmVuZSBaaWVscGZhZCBleGlzdGllcnQgbmljaHQuXG4iLAorICAgICAgICAgICAgICAgIHF1ZXJ5X3ZlcmIoKSkpLDA7CisgIH0KKyAgYXJncz1hcmdzWzAuLjwyXTsKKyAgaWYgKGZpbGVfc2l6ZShkZXN0KSE9LTImJnNpemVvZihhcmdzKT4xKQorICAgIHJldHVybiBub3RpZnlfZmFpbCgKKyAgICAgICAgc3ByaW50ZigiJXM6IEJlaSBtZWhyZXJlbiBRdWVsbGVuIG11c3MgZGFzIFppZWwgZWluIFZlcnplaWNobmlzICIKKyAgICAgICAgICAgICAgICAic2Vpbi5cbiIscXVlcnlfdmVyYigpKSksMDsKKyAgaWYgKCFzaXplb2YoYXJncz1tYXAoYXJncywjJ3RvX2ZpbGVuYW1lKS0oezB9KSkpCisgICAgcmV0dXJuIFVTQUdFKHF1ZXJ5X3ZlcmIoKSsiIFstIiBDUF9PUFRTCisgICAgICAgICAgIl0gPGRhdGVpL3Zlcno+IFs8ZGF0ZWkyL3ZlcnoyPiAuLi4gXSA8emllbD4gWzxtYXNrZT5dIik7CisgIC8vIERFQlVHKCJERVNUOiAiICsgZGVzdCArICIgOiBGTEFHUzogIiArIGZsYWdzKTsKKyAgYXJncz1maWxlX2xpc3QoYXJncyxNT0RFX0NQLChmbGFncyZDUF9SKSxkZXN0KyIvIixtYXNrKTsKKyAgaWYgKCFzaXplb2YoYXJncykpCisgICAgcmV0dXJuIG5vdGlmeV9mYWlsKHNwcmludGYoIiVzOiBLZWluZSBwYXNzZW5kZW4gRGF0ZWllbiBnZWZ1bmRlbi5cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcXVlcnlfdmVyYigpKSksMDsKKworICBpZiAoc2l6ZW9mKGFyZ3MpPjEmJihhcmdzWzBdW0ZJTEVTSVpFXT49MCkmJmZpbGVfc2l6ZShkZXN0KSE9LTIpCisgICAgICByZXR1cm4gbm90aWZ5X2ZhaWwoCisgICAgICAgIHNwcmludGYoIiVzOiBCZWkgbWVocmVyZW4gUXVlbGxlbiBtdXNzIGRhcyBaaWVsIGVpbiBWZXJ6ZWljaG5pcyAiCisgICAgICAgICAgICAgICAgInNlaW4uXG4iLHF1ZXJ5X3ZlcmIoKSkpLDA7CisgIGlmIChzaXplb2YoYXJncyk9PTEmJmZpbGVfc2l6ZShkZXN0KSE9LTIpCisgICAgYXJnc1swXVtERVNUTkFNRV09ZGVzdDsKKyAgaWYgKCEoZmxhZ3MmQ1BfSSkpCisgIHsKKyAgICBhc3luY2hyb24oYXJncywjJ2NwX2ZpbGUsKHF1ZXJ5X3ZlcmIoKT09Im12IiksZmxhZ3MsMCk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKHF1ZXJ5X3ZlcmIoKT09ImNwIikKKyAgICBfY3BfYXNrX2NvcHkoYXJncywwLGZsYWdzKTsKKyAgZWxzZQorICAgIF9jcF9hc2tfY29weShhcmdzLDEsZmxhZ3MpOworICByZXR1cm4gMTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBSTURJUiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjCisKKworLy8KKy8vIF9ybWRpcjogVmVyemVpY2huaXMgbG9lc2NoZW4KKy8vIGNtZGxpbmU6IEtvbW1hbmRvemVpbGVuYXJndW1lbnRlCisvLworCisKKyNpZiBfX1ZFUlNJT05fXyA8ICIzLjIuOSIKKworcHJpdmF0ZSBpbnQgX2Rpcl9maWx0ZXIobWl4ZWQgYXJnKQoreworICByZXR1cm4gKGFyZ1tGSUxFU0laRV09PS0yKTsKK30KKworI2VuZGlmCisKK3N0YXRpYyBpbnQgX3JtZGlyKHN0cmluZyBjbWRsaW5lKQoreworICBzdHJpbmcgZGVzdCx0bXA7CisgIGludCBmbGFnczsKKyAgbWl4ZWQgKmFyZ3M7CisgIAorICBjbWRsaW5lPV91bnBhcnNlZF9hcmdzKCk7CisgIGFyZ3M9cGFyc2VhcmdzKGNtZGxpbmUsJmZsYWdzLFJNRElSX09QVFMsMSk7CisgIGlmIChmbGFncz09LTF8fCFzaXplb2YoYXJncykpCisgICAgcmV0dXJuIFVTQUdFKCJybWRpciBbLSIgUk1ESVJfT1BUUyAiXSA8VmVyemVpY2huaXM+Iik7CisgIGlmIChzaXplb2YoYXJncyk+MSkKKyAgICByZXR1cm4KKyAgICBub3RpZnlfZmFpbCgiTWl0ICdybWRpcicga2FubiBudXIgamV3ZWlscyBFSU4gVmVyemVpY2huaXMgZ2Vsb2VzY2h0ICIKKyAgICAgICAgICJ3ZXJkZW4uXG5EZXIgQmVmZWhsICdybScgYmlldGV0IGVyd2VpdGVydGUgTW9lZ2xpY2hrZWl0ZW4uXG4iKSwwOworICBkZXN0PWFyZ3NbMF07CisgIGlmIChkZXN0IT0iLyIpCisgIHsKKyAgICBhcmdzPWZpbGVfbGlzdCgoe2Rlc3R9KSxNT0RFX1JNRElSLDAsIi8iKTsKKyNpZiBfX1ZFUlNJT05fXyA8ICIzLjIuOSIKKyAgICBhcmdzPWZpbHRlcihhcmdzLCMnX2Rpcl9maWx0ZXIpOworI2Vsc2UKKyAgICBhcmdzPWZpbHRlcihhcmdzLCg6ICgkMVtGSUxFU0laRV09PS0yKSA6KSk7CisjZW5kaWYKKyAgICBpZiAoIXNpemVvZihhcmdzKSkKKyAgICAgIHJldHVybiBub3RpZnlfZmFpbCgKKyAgICAgICAgc3ByaW50Zigicm1kaXI6ICVzOiBLZWluIHNvbGNoZXMgVmVyemVpY2huaXMgZ2VmdW5kZW4uXG4iLGRlc3QpKSwwOworICAgIGlmIChzaXplb2YoYXJncyk+MSkKKyAgICAgIHJldHVybiBub3RpZnlfZmFpbCgKKyAgICAgICAgICAgICAgICBzcHJpbnRmKCJybWRpcjogJXM6IE1hc2tlIGlzdCBuaWNodCBlaW5kZXV0aWcuXG4iLGRlc3QpKSwwOworICAgIGRlc3Q9YXJnc1swXVtGVUxMTkFNRV07CisgICAgaWYgKCFNQVlfV1JJVEUoZGVzdCkpIHJldHVybiBFUlJPUihOT19XUklURSxkZXN0LDEpOworICAgIGlmICghcm1kaXIoZGVzdCkpCisgICAgeworICAgICAgaWYgKHNpemVvZigoZ2V0X2RpcihkZXN0KyIvKiIpfHwoe30pKS0oeyIuIiwiLi4ifSkpKQorICAgICAgICBwcmludGYoInJtZGlyOiAlczogVmVyemVpY2huaXMgaXN0IG5pY2h0IGxlZXIuXG4iLGRlc3QpOworICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgaWYgKGZsYWdzJiZSTURJUl9WKSBwcmludGYoRklMRV9ERUxFVEVELGRlc3QpOworICAgIH0KKyAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gRVJST1IoTk9fREVMRVRFLGRlc3QsMSk7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgTUtESVIgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIworCisKKy8vCisvLyBfbWtkaXI6IFZlcnplaWNobmlzIGVyc3RlbGxlbgorLy8gY21kbGluZTogS29tbWFuZG96ZWlsZW5hcmd1bWVudGUKKy8vCisKK3N0YXRpYyBpbnQgX21rZGlyKHN0cmluZyBjbWRsaW5lKQoreworICBzdHJpbmcgZGVzdCx0bXA7CisgIGludCBmbGFncyxpOworICBzdHJpbmcgKmFyZ3M7CisgIAorICBjbWRsaW5lPV91bnBhcnNlZF9hcmdzKCk7CisgIGFyZ3M9cGFyc2VhcmdzKGNtZGxpbmUsJmZsYWdzLE1LRElSX09QVFMsMSk7CisgIGlmIChmbGFncz09LTEpIHJldHVybiAwOworICBpZiAoIXNpemVvZihhcmdzKSkKKyAgICByZXR1cm4gVVNBR0UoIm1rZGlyIFstIiBNS0RJUl9PUFRTICJdIDxWZXJ6ZWljaG5pcz4iKTsKKyAgaWYgKHNpemVvZihhcmdzKT4xKQorICAgIHJldHVybiBub3RpZnlfZmFpbCgiTWl0ICdta2Rpcicga2FubiBudXIgamV3ZWlscyBFSU4gVmVyemVpY2huaXMgIgorICAgICAgICAgICAgICAgICAgICAgICAiZXJzdGVsbHQgd2VyZGVuLlxuIiksMDsKKyAgZGVzdD1hcmdzWzBdOworICAKKyAgaWYgKChpPWZpbGVfc2l6ZShpbXBsb2RlKChhcmdzPWV4cGxvZGUoZGVzdCwiLyIpKVswLi48Ml0sIi8iKSkpPT1GU0laRV9ESVIpCisgIHsKKyAgICBpZiAoIW1rZGlyKGRlc3QpKSByZXR1cm4gRVJST1IoTk9fQ1JFQVRFX0RJUixkZXN0LDEpOworICAgIGlmIChmbGFncyZNS0RJUl9WKSBwcmludGYoRElSX0NSRUFURUQsZGVzdCwxKTsKKyAgICBwcmludGYoIm1rZGlyOiBhYmdlc2NobG9zc2VuLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgCisgIGlmIChpPT1GU0laRV9OT0ZJTEUpCisgIHsKKyAgICBpZiAoZmxhZ3MmTUtESVJfUikKKyAgICB7CisgICAgICBpZiAobWtkaXJwKGRlc3QpICE9IDEpCisgICAgICAgIHJldHVybiBFUlJPUihOT19DUkVBVEVfRElSLGRlc3QsMSk7CisgICAgICBpZiAoZmxhZ3MmTUtESVJfVikKKyAgICAgICAgcHJpbnRmKERJUl9DUkVBVEVELGltcGxvZGUoYXJnc1swLi5pXSwiLyIpKTsKKyAgICAgIHByaW50ZigibWtkaXI6IGFiZ2VzY2hsb3NzZW4uXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICByZXR1cm4gRVJST1IoRE9FU05UX0VYSVNULGltcGxvZGUoYXJnc1swLi48Ml0sIi8iKSwxKTsKKyAgfQorICByZXR1cm4gRVJST1IoQUxSRUFEWV9FWElTVFMsZGVzdCwxKTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFJNICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMKKworcHJpdmF0ZSB2b2lkIF9ybV9hc2tfZGVsZXRlKG1peGVkICpmaWxlZGF0YSwgaW50IGZsYWdzKTsKKworc3RhdGljIHZvaWQgX3JtX2Fza19kZWxldGUyKHN0cmluZyBpbnB1dCxtaXhlZCAqZmlsZWRhdGEsaW50IGZsYWdzKQoreworICBpbnQgaTsKKyAgaWYgKCFzaXplb2YoaW5wdXQpKSBpbnB1dD0iICI7CisgIGlucHV0PWxvd2VyX2Nhc2UoaW5wdXQpOworICBzd2l0Y2goaW5wdXRbMF0pCisgIHsKKyAgICBjYXNlICdxJzoKKyAgICAgIHByaW50ZigiTG9lc2NoZW4gYWJnZWJyb2NoZW4hXG4iKTsKKyAgICAgIHJldHVybjsKKyAgICBjYXNlICd5JzoKKyAgICBjYXNlICdqJzoKKyAgICAgIGlmIChmaWxlZGF0YVswXVtGSUxFU0laRV09PS0yKQorICAgICAgeworICAgICAgICBpZiAoaT1maWxlZGF0YVswXVtTVUJESVJTSVpFXSkgLy8gRGlyLUVpbnRyYWcgbmFjaCBoaW50ZW4gc2NoaWViZW4KKyAgICAgICAgeworICAgICAgICAgIG1peGVkIHRlbXA7CisgICAgICAgICAgaW50IGo7CisgICAgICAgICAgdGVtcD1maWxlZGF0YVswXTsKKyAgICAgICAgICB0ZW1wW1NVQkRJUlNJWkVdPTA7CisgICAgICAgICAgZm9yKGo9MDtqPGk7aisrKSBmaWxlZGF0YVtqXT1maWxlZGF0YVtqKzFdOworICAgICAgICAgIGZpbGVkYXRhW2pdPXRlbXA7CisgICAgICAgICAgX3JtX2Fza19kZWxldGUoZmlsZWRhdGEsZmxhZ3MpOworICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXJtZGlyKGZpbGVkYXRhWzBdW0ZVTExOQU1FXSkpCisgICAgICAgICAgcHJpbnRmKE5PX0RFTEVURSxmaWxlZGF0YVswXVtGVUxMTkFNRV0pOworICAgICAgICBlbHNlIGlmIChmbGFncyZSTV9WKSBwcmludGYoRklMRV9ERUxFVEVELGZpbGVkYXRhWzBdW0ZVTExOQU1FXSk7CisgICAgICB9CisgICAgICBlbHNlIC8vIERhdGVpIGV4aXN0aWVydAorICAgICAgeworICAgICAgICBpZiAoIXJtKGZpbGVkYXRhWzBdW0ZVTExOQU1FXSkpCisgICAgICAgICAgcHJpbnRmKERFU1RfTk9fREVMRVRFICJVZWJlcmdlaGUgRGF0ZWkuLi5cbiIsCisgICAgICAgICAgICAgICAgIGZpbGVkYXRhWzBdW0ZVTExOQU1FXSk7CisgICAgICAgIGVsc2UgaWYgKGZsYWdzJlJNX1YpIHByaW50ZihGSUxFX0RFTEVURUQsZmlsZWRhdGFbMF1bRlVMTE5BTUVdKTsKKyAgICAgICAgCisgICAgICB9CisgICAgY2FzZSAnbic6CisgICAgICBfcm1fYXNrX2RlbGV0ZShmaWxlZGF0YVsxK2ZpbGVkYXRhWzBdW1NVQkRJUlNJWkVdLi5dLGZsYWdzKTsKKyAgICAgIHJldHVybjsKKyAgICBkZWZhdWx0OgorICAgICAgcHJpbnRmKCJLb21tYW5kbyBuaWNodCB2ZXJzdGFuZGVuLlxuIik7CisgICAgICBfcm1fYXNrX2RlbGV0ZShmaWxlZGF0YSxmbGFncyk7CisgICAgICByZXR1cm47CisgIH0KKyAgcmV0dXJuOworfQorCitwcml2YXRlIHZvaWQgX3JtX2Fza19kZWxldGUobWl4ZWQgKmZpbGVkYXRhLCBpbnQgZmxhZ3MpCit7CisgIGludCBpOworICBtaXhlZCB0ZW1wOworICBpZiAoIXNpemVvZihmaWxlZGF0YSkpCisgIHsKKyAgICBwcmludGYoInJtOiBhYmdlc2NobG9zc2VuLlxuIik7CisgICAgcmV0dXJuOworICB9CisgIHN3aXRjaChmaWxlZGF0YVswXVtGSUxFU0laRV0pCisgIHsKKyAgICBjYXNlIC0xOgorICAgICAgaWYgKGZsYWdzJlJNX1YpIHByaW50ZihET0VTTlRfRVhJU1QsZmlsZWRhdGFbMF1bRlVMTE5BTUVdKTsKKyAgICAgIF9ybV9hc2tfZGVsZXRlKGZpbGVkYXRhWzEuLl0sZmxhZ3MpOworICAgICAgcmV0dXJuOworICAgIGNhc2UgLTI6CisgICAgICBpZiAoaT1maWxlZGF0YVswXVtTVUJESVJTSVpFXSkKKyAgICAgICAgcHJpbnRmKCJJbnMgVmVyemVpY2huaXMgJyVzJyBoaW5hYnN0ZWlnZW4/XG4iLAorICAgICAgICAgIGZpbGVkYXRhWzBdW0ZVTExOQU1FXSk7CisgICAgICBlbHNlCisgICAgICAgIHByaW50ZigiVmVyemVpY2huaXMgJyVzJyBsb2VzY2hlbj9cbiIsCisgICAgICAgICAgICAgICBmaWxlZGF0YVswXVtGVUxMTkFNRV0pOworICAgICAgaW5wdXRfdG8oIl9ybV9hc2tfZGVsZXRlMiIsSU5QVVRfUFJPTVBULCAiKGosbixxKSAiLAorICAgICAgICAgIGZpbGVkYXRhLGZsYWdzKTsKKyAgICAgIHJldHVybjsKKyAgICBkZWZhdWx0OgorICAgICAgcHJpbnRmKCInJXMnIGxvZXNjaGVuPyAoaixuLHEpXG4iLAorICAgICAgICAgZmlsZWRhdGFbMF1bRlVMTE5BTUVdKTsKKyAgICAgIGlucHV0X3RvKCJfcm1fYXNrX2RlbGV0ZTIiLElOUFVUX1BST01QVCwgIihqLG4scSkgIiwKKyAgICAgICAgICBmaWxlZGF0YSxmbGFncyk7CisgICAgICByZXR1cm47CisgIH0KK30KKworCitwcml2YXRlIHZvaWQgcm1fZmlsZShtaXhlZCBmaWxlZGF0YSwgbWl4ZWQgbm90dXNlZCwgaW50IGZsYWdzKQoreworICBzdHJpbmcgZGVzdDsKKyAgZGVzdD1maWxlZGF0YVtGVUxMTkFNRV07CisgIGlmICghTUFZX1dSSVRFKGRlc3QpKQorICB7CisgICAgcHJpbnRmKE5PX1dSSVRFLGRlc3QpOworICAgIHJldHVybjsKKyAgfQorICBzd2l0Y2goZmlsZWRhdGFbRklMRVNJWkVdKQorICB7CisgICAgY2FzZSAtMToKKyAgICAgIGlmIChmbGFncyZSTV9WKSBwcmludGYoRE9FU05UX0VYSVNULGRlc3QpOworICAgICAgcmV0dXJuOworICAgIGNhc2UgLTI6CisgICAgICBpZiAoIXJtZGlyKGRlc3QpKSBwcmludGYoREVTVF9OT19ERUxFVEUsZGVzdCk7CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIGlmIChmbGFncyZSTV9WKSBwcmludGYoRklMRV9ERUxFVEVELGRlc3QpOworICAgICAgfQorICAgICAgcmV0dXJuOworICAgIGRlZmF1bHQ6CisgICAgICBpZiAoIXJtKGRlc3QpKSBwcmludGYoREVTVF9OT19ERUxFVEUsZGVzdCk7CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIGlmIChmbGFncyZSTV9WKSBwcmludGYoRklMRV9ERUxFVEVELGRlc3QpOworICAgICAgfQorICAgICAgcmV0dXJuOworICB9Cit9CisKK3N0YXRpYyBpbnQgX3JtKHN0cmluZyBjbWRsaW5lKQoreworICBtaXhlZCAqYXJncywqYXJnczI7CisgIGludCBmbGFncyxpOworICBzdHJpbmcgbWFzazsKKyAgCisgIGNtZGxpbmU9X3VucGFyc2VkX2FyZ3MoKTsKKyAgYXJncz1wYXJzZWFyZ3MoY21kbGluZSwmZmxhZ3MsUk1fT1BUUywwKTsKKyAgaWYgKGZsYWdzPT0tMXx8IXNpemVvZihhcmdzKSkKKyAgICByZXR1cm4gVVNBR0UoInJtIFstIiBSTV9PUFRTCisgICAgICAgICAgICAgICAgICJdIDxkYXRlaS92ZXJ6PiBbPGRhdGVpMi92ZXJ6Mj4gLi4uIF0gWzxtYXNrZT5dIik7CisgIGlmIChmbGFncyZSTV9NKQorICB7CisgICAgbWFzaz1hcmdzWzwxXTsKKyAgICBhcmdzPWFyZ3NbMC4uPDJdOworICB9CisgIGFyZ3M9bWFwKGFyZ3MsIyd0b19maWxlbmFtZSktKHswfSk7CisgIGFyZ3M9ZmlsZV9saXN0KGFyZ3MsTU9ERV9STSwoZmxhZ3MmUk1fUiksIi8iLG1hc2spOworICBpZiAoIShpPXNpemVvZihhcmdzKSkpCisgICAgcmV0dXJuIHByaW50ZigiS2VpbmUgcGFzc2VuZGUgRGF0ZWkgZ2VmdW5kZW4uXG4iKSwxOworICBpZiAoIShmbGFncyZSTV9JKSkKKyAgeworICAgIGlmIChpPjEpIC8vIFVtZHJlaGVuCisgICAgeworICAgICAgbWl4ZWQgdGVtcDsKKyAgICAgIGk+Pj0xOworICAgICAgd2hpbGUoaSkKKyAgICAgIHsKKyAgICAgICAgdGVtcD1hcmdzWzwoaS0tKV07CisgICAgICAgIGFyZ3NbPChpKzEpXT1hcmdzW2ldOworICAgICAgICBhcmdzW2ldPXRlbXA7CisgICAgICB9CisgICAgfQorICAgIGFzeW5jaHJvbihhcmdzLCMncm1fZmlsZSxhcmdzLGZsYWdzLDApOworICAgIHJldHVybiAxOworICB9CisgIF9ybV9hc2tfZGVsZXRlKGFyZ3MsZmxhZ3MpOworICByZXR1cm4gMTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9zaGVsbHMvbWFnaWVyL2ZpbGV2aWV3LmMgYi9zdGQvc2hlbGxzL21hZ2llci9maWxldmlldy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczMWRlNWEKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvc2hlbGxzL21hZ2llci9maWxldmlldy5jCkBAIC0wLDAgKzEsNzI4IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gZmlsZXZpZXcuYworLy8KKy8vICRJZDogZmlsZXZpZXcuYyA5MTQyIDIwMTUtMDItMDQgMjI6MTc6MjlaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworLy8jcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDxhbnNpLmg+CisjaW5jbHVkZSA8cGxheWVyL2Jhc2UuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxzaGVsbHMuaD4KKyNpbmNsdWRlIDxkYWVtb24vbWFuZC5oPgorI2luY2x1ZGUgPHVkcC5oPgorI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxtYWdpZXIuaD4KKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cGxheWVyLmg+CisKK3ByaXZhdGUgbm9zYXZlIG1hcHBpbmcgY29sb3JzdHJpbmdzOworcHJpdmF0ZSBub3NhdmUgbWFwcGluZyBvbGRtYW5fcmVzdWx0OworCisvLyAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBJTklUSUFMSVNJRVJVTkcgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIworCittaXhlZCBfcXVlcnlfbG9jYWxjbWRzKCkKK3sKKyAgcmV0dXJuICh7KHsibHMiLCJfbHMiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAgICAgICAgKHsibW9yZSIsIl9tb3JlIiwwLExFQVJORVJfTFZMfSksCisgICAgICAgICAgICh7ImNhdCIsIl9jYXQiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAgICAgICAgKHsiaGVhZCIsIl9jYXQiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAgICAgICAgKHsidGFpbCIsIl9jYXQiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAgICAgICAgKHsibWFuIiwiX21hbiIsMCxMRUFSTkVSX0xWTH0pLAorICAgICAgICAgICAoeyJybWFuIiwiX3JtYW4iLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAgICAgICAgKHsic2hvd3Byb3BzIiwiX3Nob3dwcm9wcyIsMCxXSVpBUkRfTFZMfSksCisgICAgICAgICAgICh7ImdyZXAiLCJfZ3JlcCIsMCxMRUFSTkVSX0xWTH0pfSk7Cit9CisKKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIExTICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMKKworLy8KKy8vIF9sczogRGVyIGxzLUJlZmVobDogVmVyemVpY2huaXNzZSB1bmQgRGF0ZWllbiBhbnplaWdlbgorLy8gY21kbGluZTogS29tbWFuZG96ZWlsZQorLy8KKworLy8KKy8vIEZ1bmt0aW9uZW4genVtIFNvcnRpZXJlbiB1bmQgZnVlciBmaWx0ZXJfbGRmaWVkL21hcF9sZGZpZWQKKy8vCisKKworcHJpdmF0ZSBzdHJpbmcgX2dldF9jb2xvcihzdHJpbmcgY29sb3IpCit7CisgIHJldHVybiBDT0xPUlNbbG93ZXJfY2FzZShjb2xvcildOworfQorCisKK3ByaXZhdGUgdm9pZCBTZXRDb2xvcnN0cmluZ3MoKQoreworICBzdHJpbmcgdG1wLHRlcm07CisgIG1hcHBpbmcgdmFyczsKKyAgdmFycz1RdWVyeVByb3AoUF9WQVJJQUJMRVMpOworICBjb2xvcnN0cmluZ3M9bV9hbGxvY2F0ZSgwLDIpOworICBzd2l0Y2godGVybT1RdWVyeVByb3AoUF9UVFkpKQorICB7CisgICAgY2FzZSAidnQxMDAiOgorICAgIGNhc2UgImFuc2kiOgorICAgICAgaWYoc3RyaW5ncCh2YXJzWyJMU19ESVIiXSkpCisgICAgICAgIHRtcD1pbXBsb2RlKG1hcChleHBsb2RlKHZhcnNbIkxTX0RJUiJdLCIrIiksIydfZ2V0X2NvbG9yKSwKKyAgICAgICAgICAgICAgICAgICAgIiIpOworICAgICAgZWxzZQorICAgICAgICB0bXAgPSAodGVybSA9PSAiYW5zaSIpID8gQU5TSV9CTFVFK0FOU0lfQk9MRDogQU5TSV9CT0xEOworICAgICAgY29sb3JzdHJpbmdzW0RJUl0gPSB0bXArIiVzIisodGVybSA9PSAidnQxMDAiPyIvIjoiIikrQU5TSV9OT1JNQUw7CisgICAgICBpZih0ZXJtID09ICJ2dDEwMCIpIGNvbG9yc3RyaW5nc1tESVIsIDFdID0gMTsKKyAgICAgIGlmKHN0cmluZ3AodmFyc1siTFNfT0JKIl0pKQorICAgICAgICB0bXA9aW1wbG9kZShtYXAoZXhwbG9kZSh2YXJzWyJMU19PQkoiXSwiKyIpLCMnX2dldF9jb2xvciksCisgICAgICAgICAgICAgICAgICAgICIiKTsKKyAgICAgIGVsc2UKKyAgICAgICAgdG1wID0gKHRlcm0gPT0gImFuc2kiKSA/IEFOU0lfUkVEIDogQU5TSV9JTlZFUlM7CisgICAgICBjb2xvcnN0cmluZ3NbT0JKXSA9IHRtcCsiJXMiK0FOU0lfTk9STUFMOworICAgICAgaWYoc3RyaW5ncCh2YXJzWyJMU19WQyJdKSkKKyAgICAgICAgdG1wPWltcGxvZGUobWFwKGV4cGxvZGUodmFyc1siTFNfVkMiXSwiKyIpLCMnX2dldF9jb2xvciksCisgICAgICAgICAgICAgICAgICAgICIiKTsKKyAgICAgIGVsc2UKKyAgICAgICAgdG1wID0gKHRlcm0gPT0gImFuc2kiKSA/IEFOU0lfUFVSUExFIDogQU5TSV9JTlZFUlM7CisgICAgICBjb2xvcnN0cmluZ3NbVkNdID0gdG1wKyIlcyIrQU5TSV9OT1JNQUw7CisgICAgICBicmVhazsKKyAgICBjYXNlICJkdW1iIjoKKyAgICAgIGNvbG9yc3RyaW5nc1tESVJdID0gIiVzLyI7IGNvbG9yc3RyaW5nc1tESVIsIDFdID0gMTsKKyAgICAgIGNvbG9yc3RyaW5nc1tPQkpdID0gIiVzKiI7IGNvbG9yc3RyaW5nc1tPQkosIDFdID0gMTsKKyAgICAgIGNvbG9yc3RyaW5nc1tWQ10gID0gIiVzKiI7IGNvbG9yc3RyaW5nc1tWQyAsIDFdID0gMTsKKyAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICBjb2xvcnN0cmluZ3NbRElSXSA9ICIlcyI7CisgICAgICBjb2xvcnN0cmluZ3NbT0JKXSA9ICIlcyI7CisgICAgICBjb2xvcnN0cmluZ3NbVkNdICA9ICIlcyI7CisgIH0KKyAgcmV0dXJuOworfQorCisKK3ByaXZhdGUgc3RyaW5nIF9sc19vdXRwdXRfc2hvcnQobWl4ZWQgZmlsZWRhdGEsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtYXhsZW4saW50IGNvdW50ZXIsaW50IG1heGNvdW50KQoreworICBzdHJpbmcgdG1wOworICB0bXA9ZmlsZWRhdGFbQkFTRU5BTUVdOworICBtYXhsZW4tPXNpemVvZih0bXApOworICBzd2l0Y2goZmlsZWRhdGFbRklMRVNJWkVdKQorICB7CisgICAgY2FzZSAtMjogdG1wPXNwcmludGYoY29sb3JzdHJpbmdzW0RJUl0sdG1wKTsKKyAgICAgICAgICAgICBtYXhsZW4tPWNvbG9yc3RyaW5nc1tESVIsMV07IGJyZWFrOworICAgIGNhc2UgLTE6IHRtcD1zcHJpbnRmKGNvbG9yc3RyaW5nc1tWQ10sdG1wKTsKKyAgICAgICAgICAgICBtYXhsZW4tPWNvbG9yc3RyaW5nc1tWQywxXTsgYnJlYWs7CisgICAgZGVmYXVsdDogaWYgKGZpbmRfb2JqZWN0KGZpbGVkYXRhW0ZVTExOQU1FXSkpCisgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgbWF4bGVuLT1jb2xvcnN0cmluZ3NbT0JKLDFdOworICAgICAgICAgICAgICAgdG1wPXNwcmludGYoY29sb3JzdHJpbmdzW09CSl0sdG1wKTsgYnJlYWs7CisgICAgICAgICAgICAgfQorICB9CisgIGlmICghbWF4Y291bnQpIHJldHVybiB0bXArIlxuIjsKKyAgcmV0dXJuIHNwcmludGYoIiUtKnMlcyIsKG1heGxlbitzaXplb2YodG1wKSksdG1wLAorCSgoY291bnRlcisrKT09bWF4Y291bnQ/KGNvdW50ZXI9MCwiXG4iKToiICAiKSk7Cit9CisKK3ByaXZhdGUgaW50IF9sc19tYXhsZW4obWl4ZWQgZmlsZWRhdGEsaW50IGZsYWdzLGludCBtYXhsZW4pCit7CisgIHN0cmluZyBiYXNlOworICBpbnQgc2l6ZTsKKyAgYmFzZT1maWxlZGF0YVtCQVNFTkFNRV07CisgIGlmICghKGZsYWdzJkxTX0EpJiYoYmFzZVswXT09Jy4nKSkgcmV0dXJuIDA7CisjaWYgX19WRVJTSU9OX18gPCAiMy4yLjkiCisgIGlmIChzaXplb2YoYmFzZSk+bWF4bGVuKSBtYXhsZW49c2l6ZW9mKGJhc2UpOworI2Vsc2UKKyAgbWF4bGVuPW1heChtYXhsZW4sc2l6ZW9mKGJhc2UpKTsKKyNlbmRpZgorICByZXR1cm4gMTsKK30KKworcHJpdmF0ZSBzdHJpbmcgX2xzX291dHB1dF9sb25nKG1peGVkIGZpbGVkYXRhLCBpbnQgZmxhZ3MsY2xvc3VyZSB2YWxpZF9yZWFkLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb3N1cmUgdmFsaWRfd3JpdGUsY2xvc3VyZSBjcmVhdG9yX2ZpbGUpCit7CisgIHN0cmluZyAqdG1wLGZ1bGwsYmFzZSxwYXRoLGRhdGUsY3JlYXRvcixncm91cDsKKyAgaW50IHNpemUsZGlyLGZ0aW1lOworICBvYmplY3Qgb2I7CisgIAorICBiYXNlPWZpbGVkYXRhW0JBU0VOQU1FXTsKKyAgaWYgKCEoc2l6ZW9mKGJhc2UpKXx8KCghKGZsYWdzJkxTX0EpKSYmKGJhc2VbMF09PScuJykpKQorICAgIHJldHVybiAwOworICBzaXplPWZpbGVkYXRhW0ZJTEVTSVpFXTsKKyAgcGF0aD1maWxlZGF0YVtQQVRITkFNRV07CisgIHRtcD0oc3RyaW5nICopY2FsbF9vdGhlcihtYXN0ZXIoKSwiZnVsbF9wYXRoX2FycmF5IiwKKyAgICAgICAgICAgICAgICAgZmlsZWRhdGFbRlVMTE5BTUVdLGdldHVpZCgpKTsKKyAgZnVsbD1zcHJpbnRmKCIvJXMiLGltcGxvZGUodG1wLCIvIikpOworICBkaXI9KHNpemU9PS0yKTsKKyAgb2I9ZmluZF9vYmplY3QoZnVsbCk7CisgIGZ0aW1lPWZpbGVkYXRhW0ZJTEVEQVRFXTsKKyAgZGF0ZT1kdGltZShmdGltZSk7CisgIGRhdGU9c3ByaW50ZigiJXMgJXMgJXMiLGRhdGVbOS4uMTFdLGRhdGVbNS4uNl0sCisgICAgICAgICAgICAgICAoKHRpbWUoKS1mdGltZSk8MzE1MzYwMDA/ZGF0ZVsxOS4uMjNdOigiICIrZGF0ZVsxMy4uMTZdKSkpOworICBjcmVhdG9yPSIiOworICBncm91cD0iIjsKKyAgaWYgKGZsYWdzJkxTX1UpCisgIHsKKyAgICBjcmVhdG9yPShzdHJpbmcpY2FsbF9vdGhlcihtYXN0ZXIoKSwiY3JlYXRvcl9maWxlIixmdWxsKTsKKyAgICBzd2l0Y2goY3JlYXRvcikKKyAgICB7CisgICAgICBjYXNlIFJPT1RJRDogY3JlYXRvcj0icm9vdCI7IGJyZWFrOworICAgICAgY2FzZSBCQUNLQk9ORUlEOiBjcmVhdG9yPSJkYWVtb24iOyBicmVhazsKKyAgICAgIGRlZmF1bHQ6IGlmKCFjcmVhdG9yKSBjcmVhdG9yPSJub25lIjsgYnJlYWs7CisgICAgfQorICB9CisgIGlmIChmbGFncyZMU19HKQorICB7CisgICAgaWYgKHNpemVvZih0bXApKQorICAgIHsKKyAgICAgIHN3aXRjaCh0bXBbMF0pCisgICAgICB7CisgICAgICBjYXNlIFdJWkFSRERJUjogZ3JvdXA9Im1hZ2llciI7IGJyZWFrOworICAgICAgY2FzZSAibmV3cyI6IGdyb3VwPSJuZXdzIjsgYnJlYWs7CisgICAgICBjYXNlICJtYWlsIjogZ3JvdXA9Im1haWwiOyBicmVhazsKKyAgICAgIGNhc2UgIm9wZW4iOiBncm91cD0icHVibGljIjsgYnJlYWs7CisgICAgICBjYXNlICJwIjogZ3JvdXA9InByb2plY3QiOyBicmVhazsKKyAgICAgIGNhc2UgRE9NQUlORElSOiBpZiAoc2l6ZW9mKHRtcCk+MSkgeyBncm91cD10bXBbMV07IGJyZWFrOyB9CisgICAgICBkZWZhdWx0OiBncm91cD0ibXVkIjsgYnJlYWs7CisgICAgICB9CisgICAgfQorICAgIGVsc2UgZ3JvdXA9Im11ZCI7CisgIH0KKyAgaWYgKGRpcikgYmFzZT1zcHJpbnRmKGNvbG9yc3RyaW5nc1tESVJdLGJhc2UpOworICBlbHNlCisgIHsKKyAgICBpZiAob2IpCisgICAgeworICAgICAgaWYgKHNpemU9PS0xKQorICAgICAgICBiYXNlPXNwcmludGYoY29sb3JzdHJpbmdzW1ZDXSxiYXNlKTsKKyAgICAgIGVsc2UKKyAgICAgICAgYmFzZT1zcHJpbnRmKGNvbG9yc3RyaW5nc1tPQkpdLGJhc2UpOworICAgIH0KKyAgfQorICByZXR1cm4gc3ByaW50ZigoIiVjJWMlYyVjICUzZCIrKChmbGFncyZMU19VKT8iICUtMjQuMjRzIjoiJS0wLjFzIikrCisgICAgICAgICAgICAgICAgICgoZmxhZ3MmTFNfRyk/IiAlLTguOHMiOiIlMC4xcyIpKyIgJThzICVzICVzXG4iKSwKKyAgICAgICAgICAgICAgICAgKGRpcj8nZCc6Jy0nKSwKKyAgICAgICAgICAgICAgICAgKCFmdW5jYWxsKHZhbGlkX3JlYWQsZnVsbCxnZXR1aWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZWFkX2ZpbGUiLHRoaXNfb2JqZWN0KCkpPyctJzoncicpLAorICAgICAgICAgICAgICAgICAoIWZ1bmNhbGwodmFsaWRfd3JpdGUsZnVsbCxnZXR1aWQoKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3cml0ZV9maWxlIix0aGlzX29iamVjdCgpKT8nLSc6J3cnKSwKKyAgICAgICAgICAgICAgICAgKG9iPyd4JzonLScpLAorICAgICAgICAgICAgICAgICAoZGlyPyhzaXplb2YoKGdldF9kaXIoZnVsbCsiLyoiKXx8KHt9KSktKHsiLiIsIi4uIn0pKSk6MCksCisgICAgICAgICAgICAgICAgIGNyZWF0b3IsZ3JvdXAsKGRpcj8iLSI6c2l6ZT09LTE/Ijx2Yz4iOnRvX3N0cmluZyhzaXplKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRlLGJhc2UpOworfQorCisKK3N0YXRpYyBpbnQgX2xzKHN0cmluZyBjbWRsaW5lKQoreworICBpbnQgZmxhZ3MsY21wLGksYXJnX3NpemUsc2l6ZTsKKyAgaW50IG1heGxlbixjb3VudGVyLG1heGNvdW50OworICBzdHJpbmcgKmFyZ3Msb3V0cHV0OworICBtaXhlZCAqdG1wOworICBjbG9zdXJlIG91dHB1dF9mdW4sdl9yZWFkLHZfd3JpdGUsY3JlYXRvcixzb3J0X2Z1bjsKKyAgCisgIGNtZGxpbmU9X3VucGFyc2VkX2FyZ3MoKXx8IiI7CisgIGFyZ3M9cGFyc2VhcmdzKGNtZGxpbmUsJmZsYWdzLExTX09QVFMsMSk7CisgIGlmIChmbGFncz09LTEpCisgICAgcmV0dXJuIFVTQUdFKCJscyBbLSIgTFNfT1BUUyAiXSBbPFZlcnplaWNobmlzPl0gWzxWZXJ6ZWljaG5pczI+IC4uXSIpOworICBTZXRDb2xvcnN0cmluZ3MoKTsKKyAgb3V0cHV0PSIiOworICBpZiAoIXNpemVvZihhcmdzKSkgYXJncz0oeyBRdWVyeVByb3AoUF9DVVJSRU5URElSKSB9KTsKKyAgaWYgKCFzaXplb2YoYXJncz1maWxlX2xpc3QoYXJncyxNT0RFX0xTQSwwLCIvIikpKQorICAgIHJldHVybiBub3RpZnlfZmFpbCgibHM6IEtlaW5lIHBhc3NlbmRlbiBWZXJ6ZWljaG5pc3NlIGdlZnVuZGVuLlxuIiksIDA7CisvLyBGaWxlcyBzb3J0aWVyZW4gZGllIGVyc3RlCisgIGlmIChmbGFncyZMU19UKSBjbXA9RklMRURBVEU7CisgIGVsc2UgaWYgKGZsYWdzJkxTX1MpIGNtcD1GSUxFU0laRTsKKyAgZWxzZSBjbXA9QkFTRU5BTUU7IC8vID0wIDotKQorICBzb3J0X2Z1bj1sYW1iZGEoKHsgJ2EsJ2IgfSksKHsKKyAgICAoKCFjbXAmJiEoZmxhZ3MmTFNfUikpfHwoY21wJiYoZmxhZ3MmTFNfUikpPyMnPjojJzwpLAorICAgICh7IydbLCdhLGNtcH0pLCh7IydbLCdiLGNtcH0pfSkpOworICBhcmdzPXNvcnRfYXJyYXkoYXJncyxzb3J0X2Z1bik7CisvLyBBdXNnYWJlZm9ybWF0IGJlc3RpbW1lbgorICBpZiAoZmxhZ3MmTFNfTCkKKyAgeworICAgIHZfcmVhZD1WQUxJRF9SRUFEX0NMOworICAgIHZfd3JpdGU9VkFMSURfV1JJVEVfQ0w7CisgICAgY3JlYXRvcj1DUkVBVE9SX0NMOworICB9CisgIGFyZ19zaXplPXNpemVvZihhcmdzKTsKKyAgaWYgKGFyZ19zaXplPjF8fChhcmdfc2l6ZSYmYXJnc1swXVtGSUxFU0laRV0+PTApKQorICB7CisgICAgaWYgKGZsYWdzJkxTX0wpCisgICAgICB0bXA9bWFwKGFyZ3MsIydfbHNfb3V0cHV0X2xvbmcsZmxhZ3Msdl9yZWFkLAorICAgICAgICAgICAgICAgICAgICB2X3dyaXRlLGNyZWF0b3IpLSh7MH0pOworICAgIGVsc2UKKyAgICB7CisgICAgICBjb3VudGVyPTA7bWF4bGVuPTA7CisgICAgICB0bXA9ZmlsdGVyKGFyZ3MsIydfbHNfbWF4bGVuLGZsYWdzLCZtYXhsZW4pOworICAgICAgaWYgKG1heGxlbj43NikgbWF4bGVuPTc2OworICAgICAgbWF4Y291bnQ9KDc4LyhtYXhsZW4rMikpLTE7CisgICAgICB0bXA9bWFwKHRtcCwjJ19sc19vdXRwdXRfc2hvcnQsbWF4bGVuLCZjb3VudGVyLG1heGNvdW50KTsKKyAgICB9CisgICAgb3V0cHV0PXNwcmludGYoIlxuJWQgRGF0ZWllbi9VbnRlcnZlcnplaWNobmlzc2U6XG4lc1xuIiwKKyAgICAgICAgICAgICAgICAgICBzaXplb2YodG1wKSxpbXBsb2RlKHRtcCwiIikpOworICB9CisgIGZvcihpPTA7aTxhcmdfc2l6ZTtpKyspCisgIHsKKyAgICB0bXA9KHt9KTsKKyAgICBzaXplPWFyZ3NbaV1bRklMRVNJWkVdOworICAgIGlmIChzaXplPT0tMikKKyAgICB7CisgICAgICB0bXA9ZmlsZV9saXN0KCh7YXJnc1tpXVtGVUxMTkFNRV0rIi8qIn0pLE1PREVfTFNCLDAsIi8iKTsKKyAgICAgIHRtcD1zb3J0X2FycmF5KHRtcCxzb3J0X2Z1bik7CisgICAgICBpZiAoZmxhZ3MmTFNfTCkKKyAgICAgICAgdG1wPW1hcCh0bXAsIydfbHNfb3V0cHV0X2xvbmcsZmxhZ3Msdl9yZWFkLAorICAgICAgICAgICAgICAgICAgICAgIHZfd3JpdGUsY3JlYXRvciktKHswfSk7CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIGNvdW50ZXI9MDttYXhsZW49MDsKKyAgICAgICAgdG1wPWZpbHRlcih0bXAsIydfbHNfbWF4bGVuLGZsYWdzLCZtYXhsZW4pOworICAgICAgICBtYXhjb3VudD0oNzgvKG1heGxlbisyKSk7CisgICAgICAgIGlmIChtYXhjb3VudCkgbWF4Y291bnQtLTsKKyAgICAgICAgdG1wPW1hcCh0bXAsIydfbHNfb3V0cHV0X3Nob3J0LG1heGxlbiwmY291bnRlcixtYXhjb3VudCk7CisgICAgICB9CisgICAgICBpZiAoc2l6ZW9mKHRtcCkpCisgICAgICB7CisgICAgICAgIG91dHB1dCs9c3ByaW50ZigiXG4lczogVmVyemVpY2huaXMsICVkIERhdGVpZW4vVW50ZXJ2ZXJ6ZWljaG5pc3NlOlxuIiwKKyAgICAgICAgICAgICAgICAgICAgICBhcmdzW2ldW0ZVTExOQU1FXSxzaXplb2YodG1wKSk7CisgICAgICAgIG91dHB1dCs9KGltcGxvZGUodG1wLCIiKSsoKHN0cmluZykodG1wWzwxXVs8MS4uPDFdKT09IlxuIj8iIjoiXG4iKSk7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIG91dHB1dCs9c3ByaW50ZigiXG4lczogTGVlcmVzIFZlcnplaWNobmlzLlxuIixhcmdzW2ldW0ZVTExOQU1FXSk7CisgICAgICB9CisgICAgfQorICB9CisgIE1vcmUob3V0cHV0KTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBNT1JFICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjCisvLworLy8gX21vcmVfZmlsZTogTWVocmVyZSBGaWxlcyBoaW50ZXJlaW5hbmRlciBhdXNnZWJlbgorLy8KKworcHJpdmF0ZSB2b2lkIF9tb3JlX2ZpbGUoc3RyaW5nICphcmcpCit7CisgIGlmICghc2l6ZW9mKGFyZykpIHJldHVybjsKKyAgcHJpbnRmKCJtb3JlOiBOYWVjaHN0ZSBEYXRlaTogJXNcbiIsYXJnWzBdKTsKKyAgTW9yZShhcmdbMF0sMSwjJ19tb3JlX2ZpbGUsKHsgYXJnWzEuLl19KSk7CisgIHJldHVybjsKK30KKworCitwcml2YXRlIG1peGVkIF9zaXplX2ZpbHRlcihtaXhlZCAqYXJnKQoreworICBpZiAoYXJnW0ZJTEVTSVpFXT4wKSByZXR1cm4gYXJnW0ZVTExOQU1FXTsKKyAgaWYgKGFyZ1tGSUxFU0laRV09PTApCisgIHsKKyAgICBwcmludGYoIiVzOiAlczogTGVlcmUgRGF0ZWkuXG4iLHF1ZXJ5X3ZlcmIoKXx8Im1vcmUiLGFyZ1tGVUxMTkFNRV0pOworICAgIHJldHVybiAwOworICB9CisgIGlmIChhcmdbRklMRVNJWkVdPT0tMikKKyAgICBwcmludGYoIiVzOiAlcyBpc3QgZWluIFZlcnplaWNobmlzLlxuIixxdWVyeV92ZXJiKCl8fCJtb3JlIixhcmdbRlVMTE5BTUVdKTsKKyAgZWxzZQorICAgIHByaW50ZigiJXM6ICVzOiBEYXRlaSBleGlzdGllcnQgbmljaHQuXG4iLCBxdWVyeV92ZXJiKCl8fCJtb3JlIiwKKyAgICAgICAgICAgYXJnW0ZVTExOQU1FXSk7CisgIHJldHVybiAwOworfQorCisKKy8vCisvLyBfbW9yZTogRGF0ZWllbiBhbnplaWdlbgorLy8gY21kbGluZTogS29tbWFuZG96ZWlsZQorLy8KKworc3RhdGljIGludCBfbW9yZShzdHJpbmcgY21kbGluZSkKK3sKKyAgbWl4ZWQgKmFyZ3M7CisgIGludCBmbGFnczsKKyAgY21kbGluZT1fdW5wYXJzZWRfYXJncygpOworICBhcmdzPXBhcnNlYXJncyhjbWRsaW5lLCZmbGFncywiIiwxKTsKKyAgaWYgKGZsYWdzPT0tMXx8IXNpemVvZihhcmdzKSkgcmV0dXJuIFVTQUdFKCJtb3JlIDxkYXRlaT4gWzxkYXRlaTI+Li5dIik7CisgIGFyZ3M9ZmlsZV9saXN0KGFyZ3MsTU9ERV9NT1JFLDAsIi8iKTsKKyAgaWYgKCFzaXplb2YoYXJncykpCisgICAgcmV0dXJuIHByaW50ZigibW9yZTogJXM6IEtlaW5lIHBhc3NlbmRlIERhdGVpIGdlZnVuZGVuLlxuIixjbWRsaW5lKSwxOworICBhcmdzPW1hcChhcmdzLCMnX3NpemVfZmlsdGVyKS0oezB9KTsKKyAgaWYgKHNpemVvZihhcmdzKSkgX21vcmVfZmlsZShhcmdzKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgSEVBRCwgVEFJTCwgQ0FUICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjCisKK3N0YXRpYyBpbnQgX2NhdChzdHJpbmcgY21kbGluZSkKK3sKKyAgbWl4ZWQgKmFyZ3M7CisgIGludCBmbGFnczsKKyAgY21kbGluZT1fdW5wYXJzZWRfYXJncygpOworICBhcmdzPXBhcnNlYXJncyhjbWRsaW5lLCZmbGFncywiIiwxKTsKKyAgaWYoZmxhZ3M9PS0xfHwhc2l6ZW9mKGFyZ3MpKQorICAgIHJldHVybiBVU0FHRShxdWVyeV92ZXJiKCkrIiA8ZGF0ZWluYW1lPiBbPGRhdGVpMj4uLl0iKTsKKyAgYXJncz1maWxlX2xpc3QoYXJncyxNT0RFX0NBVCwwLCIvIik7CisgIGlmICghc2l6ZW9mKGFyZ3MpKQorICAgIHJldHVybiBwcmludGYoIiVzOiAlczogS2VpbmUgcGFzc2VuZGUgRGF0ZWkgZ2VmdW5kZW4uXG4iLHF1ZXJ5X3ZlcmIoKSwKKyAgICAgICAgICAgICAgICBjbWRsaW5lKSwxOworICBhcmdzPW1hcChhcmdzLCMnX3NpemVfZmlsdGVyKS0oezB9KTsKKyAgaWYgKCFzaXplb2YoYXJncykpIHJldHVybiAxOworICB3aGlsZShzaXplb2YoYXJncykpCisgIHsKKyAgICBzd2l0Y2gocXVlcnlfdmVyYigpKQorICAgIHsKKyAgICAgIGNhc2UgImNhdCI6CisgICAgICAgIGlmICghY2F0KGFyZ3NbMF0pKQorICAgICAgICAgIHByaW50ZigiY2F0OiAlcyBrb25udGUgbmljaHQgYW5nZXplaWd0IHdlcmRlbi5cbiIsYXJnc1swXSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAiaGVhZCI6CisgICAgICAgIGlmICghY2F0KGFyZ3NbMF0sMCwxMCkpCisgICAgICAgICAgcHJpbnRmKCJoZWFkOiAlcyBrb25udGUgbmljaHQgYW5nZXplaWd0IHdlcmRlbi5cbiIsYXJnc1swXSk7CisgICAgICAgIGJyZWFrOworICAgICAgY2FzZSAidGFpbCI6IHRhaWwoYXJnc1swXSk7IGJyZWFrOworICAgIH0KKyAgICBhcmdzPWFyZ3NbMS4uXTsKKyAgfQorICByZXR1cm4gMTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgTUFOICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMKKworc3RhdGljIGludCBfbWFuKHN0cmluZyBjbWRsaW5lKQoreworICBtaXhlZCAqYXJnczsKKyAgaW50IGksIGZsYWdzOworICBzdHJpbmcgKnRtcCwgKnRtcDI7CisKKyAgY21kbGluZT1fdW5wYXJzZWRfYXJncygpOworICBhcmdzPXBhcnNlYXJncyhjbWRsaW5lLCZmbGFncyxNQU5fT1BUUywwKTsKKyAgCisgIGlmIChmbGFncz09LTEgfHwKKyAgICAgIChzaXplb2YoYXJncykhPTEgJiYKKyAgICAgICAoc2l6ZW9mKGFyZ3MpPDIgfHwgc2l6ZW9mKGFyZ3NbMV0pPjEgfHwgIShpPXRvX2ludChhcmdzWzFdKSkpKSkKKyAgICByZXR1cm4gVVNBR0UoIm1hbiBbLSIgTUFOX09QVFMgIl0gPGhpbGZlc2VpdGU+Iik7CisgIHRtcD1leHBsb2RlKGFyZ3NbMF0sIi8iKTsKKworICBpZiAob2xkbWFuX3Jlc3VsdCAmJiBzaXplb2YodG1wKT09MSAmJiBzaXplb2YoYXJncyk9PTEgJiYKKyAgICAgIHNpemVvZih0bXBbMF0pPT0xICYmIChpPXRvX2ludCh0bXBbMF0pKSAmJiBtZW1iZXIob2xkbWFuX3Jlc3VsdCxpKSkgeworICAgdG1wPSh7b2xkbWFuX3Jlc3VsdFtpLDBdLG9sZG1hbl9yZXN1bHRbaSwxXX0pOworICAgaT0wOworICB9CisgIGVsc2UgaWYgKCEoZmxhZ3MmKE1BTl9NfE1BTl9SKSkmJnNpemVvZih0bXApPjEpCisgIHsKKyAgICBpZiAoZmlsZV9zaXplKE1BTkRfRE9DRElSK2FyZ3NbMF0pPj0wKQorICAgICAgdG1wPSh7dG1wWzwxXSxhcmdzWzBdfSk7CisgICAgZWxzZQorICAgICAgdG1wPSh7fSk7CisgIH0KKyAgZWxzZQorICB7CisgICAgaWYgKGZsYWdzJk1BTl9SKQorICAgIHsKKyAgICAgIGZsYWdzJj0ofk1BTl9NKTsKKyAgICAgIGlmIChjYXRjaChyZWdleHAoKHsiIn0pLGFyZ3NbMF0pKXx8CisgICAgICAgICAgIXJlZ2V4cCgoeyIifSksYXJnc1swXSkpCisgICAgICAgIHJldHVybiBwcmludGYoIm1hbjogVW5ndWVsdGlnZXIgQXVzZHJ1Y2sgaW4gTWFza2UuXG4iKSwxOworICAgIH0KKyAgICB0bXA9KHN0cmluZyAqKWNhbGxfb3RoZXIoTUFORCwibG9jYXRlIixhcmdzWzBdLGZsYWdzJihNQU5fTXxNQU5fUikpOworICB9CisKKyAgb2xkbWFuX3Jlc3VsdD0obWFwcGluZykwOworICBpZihpICYmIHNpemVvZih0bXApPjIgJiYgc2l6ZW9mKHRtcCk+PShpPDwxKSkKKyAgICB0bXA9dG1wWygoaTw8MSktMikuLigoaTw8MSktMSldOworICBzd2l0Y2goc2l6ZW9mKHRtcCkpCisgIHsKKyAgICBjYXNlIDA6CisgICAgICBwcmludGYoIktlaW5lIEhpbGZlc2VpdGUgZ2VmdW5kZW4gZnVlciAnJXMnLlxuIixhcmdzWzBdKTsKKyAgICAgIGJyZWFrOworICAgIGNhc2UgMjoKKyAgICAgICAvKgorICAgICAgICAgaWYgKGZsYWdzJk1BTl9JKQorICAgICAgICAgeworICAgICAgICAgLy8gQlJBTkNIIFRPIE1BTlVBTEQKKyAgICAgICAgIHJldHVybiAxOworICAgICAgICAgfQorICAgICAgICovCisgICAgICBwcmludGYoIkZvbGdlbmRlIEhpbGZlc2VpdGUgd3VyZGUgZ2VmdW5kZW46ICVzXG4iLHRtcFsxXSk7CisgICAgICBNb3JlKE1BTkRfRE9DRElSK3RtcFsxXSwxKTsKKyAgICAgIHJldHVybiAxOworICAgIGRlZmF1bHQ6CisgICAgICBpPXNpemVvZih0bXApPj4xOworICAgICAgdG1wMj1hbGxvY2F0ZShpKTsKKyAgICAgIG9sZG1hbl9yZXN1bHQ9bV9hbGxvY2F0ZShpLDIpOworICAgICAgd2hpbGUoaSkKKyAgICAgIHsKKyAgICAgICAgdG1wMlsoaS0xKV09c3ByaW50ZigiJWQ6ICIsaSkrdG1wWyhpPDwxKS0yXTsKKwlvbGRtYW5fcmVzdWx0W2ksMF09dG1wWyhpPDwxKS0yXTsKKwlvbGRtYW5fcmVzdWx0W2ksMV09dG1wWyhpPDwxKS0xXTsKKyAgICAgICAgaS0tOworICAgICAgfQorICAgICAgcHJpbnRmKCJFcyB3dXJkZW4gZm9sZ2VuZGUgcG90ZW50aWVsbCBwYXNzZW5kZW4gU2VpdGVuIGdlZnVuZGVuOlxuIgorICAgICAgICAgICAgICIlJy0nNzguNzhzXG4lcyUnLSc3OC43OHNcbiIsIiIsCisgICAgICAgICAgICAgYnJlYWtfc3RyaW5nKGltcGxvZGUodG1wMiwiICIpLDc4KSwiIik7CisgICAgICBicmVhazsKKyAgfQorICByZXR1cm4gMTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFJNQU4gIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIworCitzdGF0aWMgaW50IF9ybWFuKHN0cmluZyBzdHIpCit7CisgIGludCBmbGFnczsKKyAgc3RyaW5nICphcmdzOworICAKKyAgc3RyPV91bnBhcnNlZF9hcmdzKCk7CisgIGFyZ3M9cGFyc2VhcmdzKHN0ciwmZmxhZ3MsIiIsMCk7CisgIGlmIChmbGFncz09LTF8fHNpemVvZihhcmdzKSE9MikKKyAgICByZXR1cm4gVVNBR0UoInJtYW4gPGhpbGZlc2VpdGU+IDxtdWRuYW1lPiIpOworICB3cml0ZSgibWFuOiAiICsKKyAgICAgICAgKHN0cmluZyljYWxsX290aGVyKFVEUF9DTURfRElSKyJtYW4iLCJzZW5kX3JlcXVlc3QiLGFyZ3NbMV0sYXJnc1swXSkpOworICByZXR1cm4gMTsKK30KKworCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFNIT1dQUk9QUyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjCisKKy8vCisvLyBfc2hvd3Byb3BzOiBaZWlndCBQcm9wZXJ0aWVzIHp1IGVpbmVtIE9iamVrdCBhbgorLy8KKworc3RhdGljIGludCBfc2hvd3Byb3BzKHN0cmluZyBzdHIpCit7CisgICBpbnQgaTsKKyAgIHN0cmluZyAqbGlzdCwgYXVzZ2FiZTsKKworICAgaWYgKHN0cikgeworICAgICAgaWYgKHN0clswXSE9Jy8nKSBzdHI9Ii8iK3N0cjsKKyAgICAgIGlmIChzdHJbMC4uNF0hPSIvc3RkLyIpCisgICAgICB7CisgICAgICAgICBwcmludGYoInNob3dwcm9wczogRXMga29lbm5lbiBudXIgUHJvcGVydGllcyB2b24gT2JqZWt0ZW4gIgorICAgICAgICAgICAgICAgICJhdXMgL3N0ZC8gYW5nZXplaWd0IHdlcmRlbi5cbiIpOworICAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgICBpZiAoc3RyWzwxXT09Jy4nKSBzdHIrPSJjIjsKKyAgICAgIGlmIChzdHJbPDIuLjwxXSE9Ii5jIikgc3RyKz0iLmMiOworICAgICAgaWYgKGZpbGVfc2l6ZShzdHIpPDApCisgICAgICB7CisgICAgICAgIHByaW50Zigic2hvd3Byb3BzOiAlczogRXMgZ2lidCBrZWluIE9iamVrdCBkaWVzZW4gTmFtZW5zLlxuIixzdHJbMC4uPDNdKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgICBpZiAoY2F0Y2goY2FsbF9vdGhlcihzdHJbMC4uPDNdLCAiPz8/IikpKQorICAgICAgeworICAgICAgICBwcmludGYoInNob3dwcm9wczogJXM6IERhdGVpIGtvbm50ZSBuaWNodCBnZWxhZGVuIHdlcmRlbi5cbiIsc3RyKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICB9CisgICBpZiAoIXN0ciB8fCAhZmluZF9vYmplY3Qoc3RyKSkgeworICAgICAgbm90aWZ5X2ZhaWwoIldlbGNoZSBQcm9wZXJ0aWVzIG1vZWNodGVzdCBEdSBzZWhlbj8iCisgICAgICAgICAgICAgICAgICAiIEJzcC46IDxzaG93cHJvcHMgL3N0ZC9ucGM+XG4iKTsKKyAgICAgIHJldHVybiAwOworICAgfQorICAgbGlzdD1pbmhlcml0X2xpc3QoZmluZF9vYmplY3Qoc3RyKSk7CisjaWYgX19WRVJTSU9OX18gPCAiMy4yLjkiCisgICBsaXN0PW1hcChsaXN0LGxhbWJkYSgoeyd4fSksKHsjJ2V4dHJhY3QsJ3gsNCwtMn0pKSk7CisgICBsaXN0Kz1tYXAobGlzdCxsYW1iZGEoKHsneH0pLCh7IydbPCwoeyMnb2xkX2V4cGxvZGUsJ3gsIi8ifSksMX0pKSk7CisgICBsaXN0PW1hcChtX2luZGljZXMobWttYXBwaW5nKGxpc3QpKSxsYW1iZGEoKHsneH0pLCh7IycrLCh7IycrLCIvc3lzLyIsJ3h9KSwiaCJ9KSkpOworICAgbGlzdD1maWx0ZXIobGlzdCxsYW1iZGEoKHsneH0pLCh7Iyc+LCh7IydmaWxlX3NpemUsJ3h9KSwwfSkpICk7CisjZWxzZQorICAgbGlzdD1tYXAobGlzdCwoOiByZXR1cm4gJDFbNS4uPDJdKyJoIjsgOikpOworICAgbGlzdCs9bWFwKGxpc3QsKDogcmV0dXJuIGV4cGxvZGUoJDEsIi8iKVs8MV07IDopKTsKKyAgIGxpc3Q9bWFwKG1faW5kaWNlcyhta21hcHBpbmcobGlzdCkpLCg6IHJldHVybiAiL3N5cy8iKyQxOyA6KSk7CisgICBsaXN0PWZpbHRlcihsaXN0LCg6IHJldHVybiBmaWxlX3NpemUoJDEpPjA7IDopKTsKKyNlbmRpZgorICAgbGlzdD1zb3J0X2FycmF5KGxpc3QsICMnPCk7CisgICBhdXNnYWJlPSIiOworICAgZm9yIChpPXNpemVvZihsaXN0KTtpLS07KQorICAgeworI2lmIF9fVkVSU0lPTl9fIDwgIjMuMi45IgorICAgICBzdHI9aW1wbG9kZShmaWx0ZXIob2xkX2V4cGxvZGUocmVhZF9maWxlKGxpc3RbaV0pLCAiXG4iKSwKKyAgICAgICAgbGFtYmRhKCAoeyAneCB9KSwgKHsjJz09LCAoeyMnZXh0cmFjdCwgJ3gsIDAsIDl9KSwgIiNkZWZpbmUgUF8ifSkgKSkKKyAgICAgICAgICAgICAgICAgLCAiXG4iKTsKKyNlbHNlCisgICAgIHN0cj1pbXBsb2RlKGZpbHRlcihleHBsb2RlKHJlYWRfZmlsZShsaXN0W2ldKSwiXG4iKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICg6IHJldHVybiAkMVswLi45XT09IiNkZWZpbmUgUF8iOzopKSwiXG4iKTsKKyNlbmRpZgorICAgICBpZiAoc3RyIT0iIikgYXVzZ2FiZSs9c3ByaW50ZigiJXNcbiVzXG5cbiIsIGxpc3RbaV0sIHN0cik7CisgICB9CisgICBpZiAoYXVzZ2FiZSE9IiIpCisgICAgIE1vcmUoYXVzZ2FiZSk7CisgICBlbHNlCisgICAgIHByaW50ZigiS2VpbmUgUHJvcGVydHktRGVmaW5pdGlvbmVuIHp1IGRpZXNlbSBPYmpla3QgZ2VmdW5kZW4hXG4iKTsKKyAgIHJldHVybiAxOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgR1JFUCAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIworCisjaWYgX19WRVJTSU9OX18gPCAiMy4yLjkiCisKK3ByaXZhdGUgaW50IF9ncmVwX2ZpbHRlcihzdHJpbmcgZmlsZW5hbWUpCit7CisgIHJldHVybiAoY2FsbF9vdGhlcigidmFsaWRfd3JpdGUiLGZpbGVuYW1lLGdldHVpZCh0aGlzX29iamVjdCgpKSwKKyAgICAgICAgICAgICAgICAgICAgICAid3JpdGVfZmlsZSIsdGhpc19vYmplY3QoKSkhPTApOworfQorCisjZW5kaWYKKworLy8KKy8vIGdyZXBfZmlsZTogRGF0ZWkgZ3JlcHBlbgorLy8gcmV4cHI6IFJlZ3VsYXIgRXhwcmVzc2lvbgorLy8gZmxhZ3M6IEZsYWdzCisvLworCitwcml2YXRlIGludCBncmVwX2ZpbGUobWl4ZWQgZmlsZWRhdGEsIHN0cmluZyByZXhwciwgaW50IGZsYWdzKQoreworICBzdHJpbmcgZnVsbG5hbWUsZGF0YSxjYXJyeSwqbGluZXMsKmxpbmVzX29yaWcsKnRtcCwqcmVzdWx0OworICBpbnQgcHRyLGNvdW50LGksbm9sLG1hdGNoLGluZGV4OworICBmdWxsbmFtZT1maWxlZGF0YVtGVUxMTkFNRV07CisgIGlmICgoZmxhZ3MmR1JFUF9GKSYmZnVsbG5hbWU9PSIvcGxheWVycy8iK2dldHVpZCgpKyIvZ3JlcC5vdXQiKQorICB7CSAKKwl3cml0ZV9maWxlKCIvcGxheWVycy8iK2dldHVpZCgpKyIvZ3JlcC5vdXQiLAorICAgICAgICAgICAgICAgICAgICJVZWJlcmdlaGUgZ3JlcC5vdXQgLi4uXG4iKTsKKwlyZXR1cm4gUkVUX0ZBSUw7CisgIH0KKyAgc3dpdGNoKGZpbGVkYXRhW0ZJTEVTSVpFXSkKKyAgeworICAgIGNhc2UgLTI6IHJldHVybiBSRVRfRkFJTDsKKyAgICBjYXNlIC0xOiByZXR1cm4gRVJST1IoRE9FU05UX0VYSVNULGZ1bGxuYW1lLFJFVF9GQUlMKTsKKyAgICBjYXNlIDA6ICByZXR1cm4gUkVUX0ZBSUw7CisgICAgZGVmYXVsdDogYnJlYWs7CisgIH0KKyAgaWYgKCFNQVlfUkVBRChmdWxsbmFtZSkpIHJldHVybiBFUlJPUihOT19SRUFELGZ1bGxuYW1lLFJFVF9GQUlMKTsKKyAgY2Fycnk9IiI7IHJlc3VsdD0oe30pOworICBpZiAoZmxhZ3MmR1JFUF9JKQorICAgIHJleHByPWxvd2VyX2Nhc2UocmV4cHIpOworICBkbworICB7CisgICAgZGF0YT1yZWFkX2J5dGVzKGZ1bGxuYW1lLHB0cixNQVhMRU4pfHwiIjsKKyAgICBwdHIrPU1BWExFTjsKKyAgICBsaW5lcz1leHBsb2RlKGNhcnJ5K2RhdGEsIlxuIik7CisgICAgc3dpdGNoKHNpemVvZihsaW5lcykpCisgICAgeworICAgICAgY2FzZSAwOiBjb250aW51ZTsKKyAgICAgIGNhc2UgMToKKyAgICAgICAgY2Fycnk9IiI7CisgICAgICAgIGJyZWFrOworICAgICAgZGVmYXVsdDoKKyAgICAgICAgY2Fycnk9bGluZXNbPDFdOworICAgICAgICBsaW5lcz1saW5lc1swLi48Ml07CisgICAgICAgIGJyZWFrOworICAgIH0KKyAgICBsaW5lc19vcmlnPWxpbmVzOworICAgIGlmIChmbGFncyZHUkVQX0kpCisgICAgICBsaW5lcz1tYXAobGluZXMsIydsb3dlcl9jYXNlKTsKKyAgICBub2w9c2l6ZW9mKGxpbmVzKTsKKyAgICBmb3IgKGk9MDtpPG5vbDtpKyspCisgICAgeworICAgICAgbWF0Y2g9c2l6ZW9mKHJlZ2V4cChsaW5lc1tpLi5pXSxyZXhwcikpOworICAgICAgaWYgKGZsYWdzJkdSRVBfVikgbWF0Y2g9IW1hdGNoOworICAgICAgaWYgKG1hdGNoKQorICAgICAgeworICAgICAgICBpZiAoIShmbGFncyZHUkVQX0MpKQorICAgICAgICB7CisgICAgICAgICAgaWYgKGZsYWdzJkdSRVBfTikKKyAgICAgICAgICAgIHJlc3VsdCs9KHsgc3ByaW50ZigiJTRkICVzIixpbmRleCtpKzEsbGluZXNfb3JpZ1tpXSl9KTsKKyAgICAgICAgICBlbHNlCisgICAgICAgICAgICByZXN1bHQrPWxpbmVzX29yaWdbaS4uaV07CisgICAgICAgIH0KKyAgICAgICAgY291bnQrKzsKKyAgICAgIH0KKyAgICB9CisgICAgaW5kZXgrPW5vbDsKKyAgfQorICB3aGlsZShzaXplb2YoZGF0YSk9PU1BWExFTik7CisgIGlmIChjYXJyeSE9IiIpCisgIHsKKyAgICBpZiAoZmxhZ3MmR1JFUF9JKSBjYXJyeT1sb3dlcl9jYXNlKGNhcnJ5KTsKKyAgICBtYXRjaD1zaXplb2YocmVnZXhwKCh7IGNhcnJ5IH0pLHJleHByKSk7CisgICAgaWYgKGZsYWdzJkdSRVBfVikgbWF0Y2g9IW1hdGNoOworICAgIGlmIChtYXRjaCkKKyAgICB7CisgICAgICBpZighKGZsYWdzJkdSRVBfQykpCisgICAgICB7CisgICAgICAgIGlmKGZsYWdzJkdSRVBfTikKKyAgICAgICAgICAgcmVzdWx0Kz0oeyBzcHJpbnRmKCIlNGQgJXMiLGluZGV4KzEsY2FycnkpIH0pOworICAgICAgICBlbHNlCisgICAgICAgICAgIHJlc3VsdCs9KHtjYXJyeX0pOworICAgICAgfQorICAgICAgY291bnQrKzsKKyAgICB9CisgIH0KKyAgY2Fycnk9IiI7CisgIGlmIChjb3VudCkKKyAgeworICAgIGlmIChmbGFncyZHUkVQX0wpIGNhcnJ5PXNwcmludGYoIiVzXG4iLGZ1bGxuYW1lKTsKKyAgICBlbHNlIGlmIChmbGFncyZHUkVQX0gpIGRhdGE9IiI7CisgICAgZWxzZSBkYXRhPXNwcmludGYoIiAlczoiLGZ1bGxuYW1lKTsKKyAgICBpZiAoZmxhZ3MmR1JFUF9DKSBjYXJyeT1zcHJpbnRmKCIlcyAlZCBwYXNzZW5kZSBaZWlsZSVzLlxuIixkYXRhLGNvdW50LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY291bnQ9PTE/IiI6Im4iKSk7CisgICAgZWxzZQorICAgICAgY2Fycnk9KGRhdGErIlxuIitpbXBsb2RlKHJlc3VsdCwiXG4iKSsiXG4iKTsKKyAgfQorICBpZiAoZmxhZ3MmR1JFUF9GKQorICAgIHJldHVybiB3cml0ZV9maWxlKCIvcGxheWVycy8iK2dldHVpZCgpKyIvZ3JlcC5vdXQiLGNhcnJ5KTsKKyAgd3JpdGUoY2FycnkpOworICByZXR1cm4gUkVUX09LOworfQorCitzdGF0aWMgaW50IF9ncmVwKHN0cmluZyBjbWRsaW5lKQoreworICBzdHJpbmcgcmV4cHIsbWFzazsKKyAgbWl4ZWQgKmFyZ3M7CisgIGludCBmbGFnczsKKyAgY21kbGluZT1fdW5wYXJzZWRfYXJncygpOworICBhcmdzPXBhcnNlYXJncyhjbWRsaW5lLCZmbGFncyxHUkVQX09QVFMsMCk7CisgIGlmICgoZmxhZ3M9PS0xKXx8IXNpemVvZihhcmdzKSkKKyAgICByZXR1cm4gVVNBR0UoImdyZXAgWy0iIEdSRVBfT1BUUworICAgICAgICAgICJdIDxyZWdleHA+IDxkYXRlaS92ZXJ6PiBbPGRhdGVpMj4gLi4uIF0gWzxtYXNrZT5dIik7CisgIHJleHByPWFyZ3NbMF07CisgIGlmIChjYXRjaChyZWdleHAoKHsiIn0pLHJleHByKSl8fCFyZWdleHAoKHsiIn0pLHJleHByKSkKKyAgICByZXR1cm4gcHJpbnRmKCJncmVwOiBVbmd1ZWx0aWdlciBTdWNoYXVzZHJ1Y2s6ICVzXG4iLHJleHByKSAsMTsKKyAgYXJncz1hcmdzWzEuLl07CisgIGlmIChmbGFncyZHUkVQX00pCisgIHsKKyAgICBtYXNrPWFyZ3NbPDFdOworICAgIGFyZ3M9YXJnc1swLi48Ml07CisgIH0KKyAgaWYgKCFzaXplb2YoYXJncykpCisgICAgICByZXR1cm4gVVNBR0UoImdyZXAgWy0iIEdSRVBfT1BUUworICAgICAgICAgICJdIDxyZWdleHA+IDxkYXRlaS92ZXJ6PiBbPGRhdGVpMj4gLi4uIF0gWzxtYXNrZT5dIik7CisgIGFyZ3M9bWFwKGFyZ3MsIyd0b19maWxlbmFtZSktKHswfSk7CisgIC8qCisjaWYgX19WRVJTSU9OX18gPCAiMy4yLjkiCisgIGFyZ3M9ZmlsdGVyKGFyZ3MsIydfZ3JlcF9maWx0ZXIpOworI2Vsc2UKKyAgYXJncz1maWx0ZXIoYXJncywoOiByZXR1cm4gKHZhbGlkX3dyaXRlKCQxLAorICAgICAgICAgICAgZ2V0dWlkKHRoaXNfb2JqZWN0KCkpLCJ3cml0ZV9maWxlIix0aGlzX29iamVjdCgpKSE9MCk6KSk7CisjZW5kaWYKKyAgKi8KKyAgYXJncz1maWxlX2xpc3QoYXJncyxNT0RFX0dSRVAsKGZsYWdzJkdSRVBfUj8xOjApLCIvIixtYXNrKTsKKyAgaWYgKCFzaXplb2YoYXJncykpCisgICAgcmV0dXJuIHByaW50ZigiS2VpbmUgcGFzc2VuZGVuIERhdGVpZW4gZ2VmdW5kZW4uXG4iKSwxOworICBpZiAoZmxhZ3MmR1JFUF9JKSByZXhwcj1sb3dlcl9jYXNlKHJleHByKTsKKyAgaWYgKGZsYWdzJkdSRVBfRikKKyAgeworICAgIGlmIChmaWxlX3NpemUoIi9wbGF5ZXJzLyIrZ2V0dWlkKCkrIi9ncmVwLm91dCIpPT0tMnx8CisJICAhTUFZX1dSSVRFKCIvcGxheWVycy8iK2dldHVpZCgpKyIvZ3JlcC5vdXQiKSkKKyAgICAgIHJldHVybiBwcmludGYoImdyZXA6IERhdGVpIC9wbGF5ZXJzLyVzL2dyZXAub3V0IGthbm4gbmljaHQgIgorCQkgICAgICAiZ2VzY2hyaWViZW4gd2VyZGVuLlxuIixnZXR1aWQoKSksMTsKKyAgICBlbHNlCisgICAgICB3cml0ZV9maWxlKCIvcGxheWVycy8iK2dldHVpZCgpKyIvZ3JlcC5vdXQiLAorICAgICAgICAgICAgICAgICAiQXVzZ2FiZSB2b24gXCJncmVwICIgKyBfdW5wYXJzZWRfYXJncygpICsgIlwiOlxuIik7IAorICB9CisgIGFzeW5jaHJvbihhcmdzLCMnZ3JlcF9maWxlLHJleHByLGZsYWdzLDApOworICByZXR1cm4gMTsKK30KZGlmZiAtLWdpdCBhL3N0ZC9zaGVsbHMvbWFnaWVyL21hZ2llcl9leHQuYyBiL3N0ZC9zaGVsbHMvbWFnaWVyL21hZ2llcl9leHQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hNWQzMGIyCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3NoZWxscy9tYWdpZXIvbWFnaWVyX2V4dC5jCkBAIC0wLDAgKzEsNzMzIEBACisvLyAkSWQ6IG1hZ2llcl9leHQuYyA5NTU1IDIwMTYtMDUtMDMgMjA6NDI6NDZaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworLy8jcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxsb2dnaW5nLmg+CisjaW5jbHVkZSA8bWFnaWVyLmg+CisjaW5jbHVkZSA8c25vb3BpbmcuaD4KKyNpbmNsdWRlIDxkcml2ZXJfaW5mby5oPgorI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwbGF5ZXIvdGVsbmV0bmVnLmg+CisjaW5jbHVkZSA8cGxheWVyL2Jhc2UuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8ZmlsZXMuaD4KKyNpbmNsdWRlIDxldmVudHMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIvY29tbS5oPgorCitpbmhlcml0ICIvc3RkL3NoZWxscy9tYWdpZXIvcGFyc2luZyI7Citpbmhlcml0ICIvc3RkL3NoZWxscy9tYWdpZXIvdXBkIjsKK2luaGVyaXQgIi9zdGQvc2hlbGxzL21hZ2llci9maWxldmlldyI7Citpbmhlcml0ICIvc3RkL3NoZWxscy9tYWdpZXIvb2JqZWN0cyI7Citpbmhlcml0ICIvc3RkL3NoZWxscy9tYWdpZXIvZmlsZWVkaXQiOworLy9pbmhlcml0ICIvc3RkL3NoZWxscy9tYWdpZXIvdG9kbyI7Citpbmhlcml0ICIvc3RkL3NoZWxscy9tYWdpZXIvcGxheWVycyI7Citpbmhlcml0ICIvc3RkL3NoZWxscy9tYWdpZXIvYWRtaW4iOworaW5oZXJpdCAiL3N0ZC9zaGVsbHMvbWFnaWVyL21vdmluZyI7Citpbmhlcml0ICIvc3RkL3NoZWxscy9tYWdpZXIvY29tbSI7CisKKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgU0VUICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjCisKKworLy8KKy8vIF9zZXQoKTogU2hlbGwtQmVmZWhsICdzZXQnCisvLyBhcmdzOiAgIEtvbW1hbmRvemVpbGVuYXJndW1lbnRlCisvLworCitzdGF0aWMgaW50IF9zZXQobWl4ZWQgYXJncykKK3sKKyAgaW50IHBvczsKKyAgc3RyaW5nIHZhcjsKKyAgbWl4ZWQgdmFsOworICBtYXBwaW5nIHZhcnM7CisKKyAgaWYoIWFyZ3M9X3VucGFyc2VkX2FyZ3MoKSkKKyAgeworICAgIGlmKCFzaXplb2YodmFycz1RdWVyeVByb3AoUF9WQVJJQUJMRVMpKSkgCisgICAgICBwcmludGYoIkR1IGhhc3Qgbm9jaCBrZWluZSBWYXJpYWJsZW4gZGVmaW5pZXJ0IVxuIik7CisgICAgZWxzZQorICAgIHsKKyAgICAgIHByaW50ZigiRHUgaGFzdCBkaWUgZm9sZ2VuZGVuIFZhcmlhYmxlbiBkZWZpbmllcnQ6XG4iKTsKKyAgICAgIHdhbGtfbWFwcGluZyh2YXJzLCgoOiBwcmludGYoIiAlLTIwcyA9ICVzXG4iLCQxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9pbnRlcnAoJDIpP2ltcGxvZGUoJDIsIjoiKTokMikgOikpKTsKKworICAgIH0KKyAgICByZXR1cm4gMTsKKyAgfQorICBwb3MgPSBtZW1iZXIoYXJncywnICcpOworICBpZihwb3MgPT0gLTEpCisgICAgaWYoc2l6ZW9mKGFyZ3MpKQorICAgICAgeworICAgICAgICBtX2RlbGV0ZShRdWVyeVByb3AoUF9WQVJJQUJMRVMpLCBhcmdzKTsKKyAgICAgICAgcHJpbnRmKCJWYXJpYWJsZSAlcyB3dXJkZSBnZWxvZXNjaHQuXG4iLGFyZ3MpOworICAgICAgICByZXR1cm4gMTsKKyAgICAgIH0KKyAgICBlbHNlIHJldHVybiBVU0FHRSgic2V0IDx2YXJpYWJsZT4gPHdlcnQ+Iik7CisgIHZhciA9IGFyZ3NbMC4ucG9zLTFdOworICB2YWwgPSAobWVtYmVyKGFyZ3NbcG9zKzEuLl0sJzonKT4tMT8KKyAgICAgICAgIGV4cGxvZGUoYXJnc1twb3MrMS4uXSwgIjoiKSA6CisgICAgICAgICBhcmdzW3BvcysxLi5dKTsKKyAgdmFycz1RdWVyeVByb3AoUF9WQVJJQUJMRVMpOworICB2YXJzKz0gKFt2YXIgOiB2YWxdKTsKKyAgcHJpbnRmKCJWYXJpYWJsZSBnZXNldHp0OiAlcyA9ICVzXG4iLHZhcixhcmdzW3BvcysxLi5dKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBDRCArIFBXRCAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjCisKK3N0YXRpYyBpbnQgX3B3ZCgpCit7CisgIHByaW50ZigiQWt0dWVsbGVzIFZlcnplaWNobmlzOiAlc1xuIixRdWVyeVByb3AoUF9DVVJSRU5URElSKSk7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IF9jZDIoc3RyaW5nIGNtZGxpbmUpCit7CisgIHN0cmluZyBkZXN0LHRtcDsKKyAgaW50IGZsYWdzOworICBtaXhlZCAqYXJnczsKKyAgCisgIGFyZ3M9cGFyc2VhcmdzKGNtZGxpbmUsJmZsYWdzLENEX09QVFMsMSk7CisgIGlmIChmbGFncz09LTEpIHJldHVybiAwOworICBpZihmbGFncyZDRF9CKQorICB7CisgICAgZGVzdD1RdWVyeVByb3AoUF9MQVNURElSKTsKKyAgfQorICBpZiAoc2l6ZW9mKGFyZ3MpPjEpCisgICAgcmV0dXJuIG5vdGlmeV9mYWlsKCJNYW4ga2FubiBzaWNoIChsZWlkZXIpIG51ciBpbiBlaW5lbSAiCisgICAgICAgICAgICAgICAgICAgICAgICJWZXJ6ZWljaG5pcyBnbGVpY2h6ZWl0aWcgYmVmaW5kZW4uXG4iKSwwOworICBpZighZGVzdCkKKyAgeworICAgIGlmICghc2l6ZW9mKGFyZ3MpKQorICAgIHsKKyAgICAgIGlmIChJU19XSVpBUkQodGhpc19vYmplY3QoKSkpCisgICAgICAgIGRlc3Q9Ii9wbGF5ZXJzLyIrZ2V0dWlkKHRoaXNfb2JqZWN0KCkpOworICAgICAgZWxzZQorICAgICAgICBkZXN0PSIvZG9jIjsKKyAgICB9CisgICAgZWxzZQorICAgIHsKKyAgICAgIGRlc3Q9YXJnc1swXTsKKyAgICB9CisgIH0KKyAgCisgIGlmIChkZXN0IT0iLyIpCisgIHsKKyAgICBhcmdzPWZpbGVfbGlzdCgoe2Rlc3R9KSxNT0RFX0NELDAsIi8iKTsKKyAgICBhcmdzID0gZmlsdGVyKGFyZ3MsIGZ1bmN0aW9uIGludCAobWl4ZWQgYXJyKQorICAgICAgICB7IHJldHVybiBhcnJbRklMRVNJWkVdID09IEZTSVpFX0RJUjsgfSApOworCisgICAgaWYgKCFzaXplb2YoYXJncykpCisgICAgICByZXR1cm4gbm90aWZ5X2ZhaWwoImNkOiAiK2Rlc3QrCisgICAgICAgICAgICAgICAgICAgICAgICI6IEtlaW4gc29sY2hlcyBWZXJ6ZWljaG5pcyBnZWZ1bmRlbi5cbiIpLDA7CisgICAgaWYgKHNpemVvZihhcmdzKT4xKQorICAgICAgcmV0dXJuIG5vdGlmeV9mYWlsKCJjZDogIitkZXN0KyI6IE1hc2tlIGlzdCBuaWNodCBlaW5kZXV0aWcuXG4iKSwwOworICAgIGRlc3Q9YXJnc1swXVtGVUxMTkFNRV07CisgIH0KKyAgaWYgKCFJU19XSVpBUkQodGhpc19vYmplY3QoKSkmJmRlc3RbMC4uM10hPSIvZG9jIikgZGVzdD0iL2RvYyI7CisgIFNldFByb3AoUF9MQVNURElSLFF1ZXJ5UHJvcChQX0NVUlJFTlRESVIpKTsKKyAgcHJpbnRmKCJBa3R1ZWxsZXMgVmVyemVpY2huaXMgaXN0IGpldHp0OiAlc1xuIixTZXRQcm9wKFBfQ1VSUkVOVERJUixkZXN0KSk7CisgIHRtcD0iIjsKKyAgaWYgKCgoZmxhZ3MmQ0RfTCl8fAorICAgICAgICgoIW1fY29udGFpbnMoJnRtcCxRdWVyeVByb3AoUF9WQVJJQUJMRVMpLCJDRF9TSE9SVCIpfHwKKyAgICAgICAgIHRtcCE9IjEiKSYmKCEoZmxhZ3MmQ0RfUykpKSkpCisgICAgdGVsbF9vYmplY3QodGhpc19vYmplY3QoKSwKKyAgICAgICAgICAgICAgICByZWFkX2ZpbGUoZGVzdCsoZGVzdFs8MV09PScvJz8iLnJlYWRtZSI6Ii8ucmVhZG1lIikpfHwiIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IF9jZChzdHJpbmcgY21kbGluZSkKK3sKKyAgcmV0dXJuIF9jZDIoX3VucGFyc2VkX2FyZ3MoKSk7Cit9CisKK3N0YXRpYyBzdHJpbmcgX3NldF9jdXJyZW50ZGlyKHN0cmluZyBwYXRoKQoreworICBTZXQoUF9DVVJSRU5URElSLCBwYXRoKTsKKyAgdGhpc19vYmplY3QoKS0+bW9kaWZ5X3Byb21wdCgpOyAgLy8gUHJvbXB0IG1pdCBuZXVlbSBQZmFkIHNldHplbiwgdGVsbmV0bmVnCisgIHJldHVybiBwYXRoOworfQorCitwcml2YXRlIHN0cmluZyBfcXVlcnlfY3VycmVudGRpcigpCit7CisgIHN0cmluZyBjOworICBpZighYz1RdWVyeShQX0NVUlJFTlRESVIpKQorICAgIHJldHVybiBTZXQoUF9DVVJSRU5URElSLCAiL3BsYXllcnMvIitnZXR1aWQodGhpc19vYmplY3QoKSksRl9WQUxVRSk7CisgIHJldHVybiBjOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBQUk9NUFQgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMKKworLy8KKy8vIF9wcm9tcHRfc3Vic3Q6IE11ZG5hbWVuLCBVc2VybmFtZW4sIFplaWxlbnZvcnNjaHViIGluIEVpbmdhYmVhdWYtCisvLyAgICAgICAgICAgICAgICBmb3JkZXJ1bmcgZWluYmF1ZW4KKy8vIHN0cjogICAgICAgICAgIFVlYmVyZ2ViZW5lciBLb21tYW5kb3plaWxlbmFic2Nobml0dAorLy8KKworcHJpdmF0ZSBzdHJpbmcgX3Byb21wdF9zdWJzdChzdHJpbmcgc3RyKQoreworICBzd2l0Y2goc3RyKQorICB7CisgICAgY2FzZSAiXFxoIjogcmV0dXJuIHNpemVvZihNVUROQU1FKT9NVUROQU1FOiJNdWQgb2huZSBOYW1lbiI7CisgICAgY2FzZSAiXFx1IjogcmV0dXJuIGNhcGl0YWxpemUoZ2V0dWlkKHRoaXNfb2JqZWN0KCkpKTsKKyAgICBjYXNlICJcXG4iOiByZXR1cm4gIlxuIjsKKyAgICBjYXNlICJcXHQiOiByZXR1cm4gIlx0IjsKKyAgICBjYXNlICJcXHciOiByZXR1cm4gIlx3IjsKKyAgfQorICByZXR1cm4gc3RyOworfQorCisKKy8vCisvLyBfcHJvbXB0OiBFaW5nYWJlYXVmZm9yZGVydW5nIHNldHplbgorLy8gYXJnOiAgICAgS29tbWFuZG96ZWlsZQorLy8KKworc3RhdGljIGludCBfcHJvbXB0KHN0cmluZyBhcmdzKQoreworICBzdHJpbmcgKnBhcmdzOworCisgIGFyZ3M9KGV4dGVybl9jYWxsKCk/X3VucGFyc2VkX2FyZ3MoKTphcmdzKTsKKyAgaWYgKCFzaXplb2YoYXJncykpIGFyZ3M9Ij4gIjsKKyAgaWYgKGFyZ3NbMF09PSciJykgYXJncz1hcmdzWzEuLjwyXTsgICAgIC8vIik7CisgIGlmKCFzaXplb2YocGFyZ3MgPSByZWdleHBsb2RlKGFyZ3MsICJcXFxcW3RodXduXSIpKSkKKyAgICByZXR1cm4gVVNBR0UoInByb21wdCBcIjxFaW5nYWJlYXVmZm9yZGVydW5nc2RlZmluaXRpb24+XCIiKTsKKyAgcGFyZ3M9bWFwKHBhcmdzLCMnX3Byb21wdF9zdWJzdCk7CisKKyAgU2V0UHJvcChQX1BST01QVCxpbXBsb2RlKHBhcmdzLCIiKSk7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgc3RyaW5nIF9zZXRfcHJvbXB0KHN0cmluZyBwcm9tcHQpIHsKKyAgU2V0KFBfUFJPTVBULCBwcm9tcHQsIEZfVkFMVUUpOworICB0aGlzX29iamVjdCgpLT5tb2RpZnlfcHJvbXB0KCk7IC8vIG5ldWVuIFByb21wdCBzZXR6ZW4gKHRlbG5ldG5lZy5jKQorICByZXR1cm4gcHJvbXB0OworfQorCisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBTSE9XUFJFU0FZICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMKKworc3RhdGljIGludCBfc2hvd3ByZXNheShzdHJpbmcgY21kbGluZSkKK3sKKyAgaW50IHByZXNheTsKKyAgcHJlc2F5PVF1ZXJ5UHJvcChQX0NBTl9GTEFHUykmQ0FOX1BSRVNBWTsKKyAgY21kbGluZT1fdW5wYXJzZWRfYXJncygwKTsKKyAgaWYgKCFzaXplb2YoY21kbGluZSkpCisgIHsKKyAgICBwcmludGYoIkRlaW4gUHJlc2F5IHdpcmQgaW0gTW9tZW50ICVzYW5nZXplaWd0LlxuIgorICAgICAgICAgICAiJXNzY2hhbHRlbiBtaXQgXCdzaG93cHJlc2F5ICVzXCcuXG4iLAorICAgICAgICAgICBwcmVzYXk/IiI6Im5pY2h0ICIscHJlc2F5PyJBdXMiOiJFaW4iLAorICAgICAgICAgICBwcmVzYXk/ImF1cyI6ImVpbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmIChjbWRsaW5lPT0iZWluInx8Y21kbGluZT09ImFuIikKKyAgeworICAgIHByaW50ZigiRGVpbiBQcmVzYXkgd2lyZCBqZXR6dCBhbmdlemVpZ3QuXG4iKTsKKyAgICBTZXRQcm9wKFBfQ0FOX0ZMQUdTLFF1ZXJ5UHJvcChQX0NBTl9GTEFHUyl8Q0FOX1BSRVNBWSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKGNtZGxpbmU9PSJhdXMiKQorICB7CisgICAgcHJpbnRmKCJEZWluIFByZXNheSB3aXJkIGpldHp0IG5pY2h0IG1laHIgYW5nZXplaWd0LlxuIik7CisgICAgU2V0UHJvcChQX0NBTl9GTEFHUyxRdWVyeVByb3AoUF9DQU5fRkxBR1MpJn5DQU5fUFJFU0FZKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gVVNBR0UoInNob3dwcmVzYXkgW2VpbnxhbnxhdXNdIik7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBFWEVDICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMKKworc3RhdGljIGludCBfZXhlYyhzdHJpbmcgZmlsZW5hbWUpCit7CisgIG9iamVjdCBvYjsKKyAgaWYgKCFJU19MT1JEKHRoaXNfb2JqZWN0KCkpKSByZXR1cm4gMDsKKyAgaWYgKHRoaXNfcGxheWVyKCkhPXRoaXNfaW50ZXJhY3RpdmUoKSkgcmV0dXJuIDA7CisgIGlmICh0aGlzX3BsYXllcigpIT10aGlzX29iamVjdCgpKSByZXR1cm4gMDsKKyAgaWYgKCEoZmlsZW5hbWU9X3VucGFyc2VkX2FyZ3MoKSkpIHJldHVybiBVU0FHRSgiZXhlYyA8b2JqZWt0bmFtZT4iKTsKKyAgZmlsZW5hbWU9KHN0cmluZykic2VjdXJlL21hc3RlciItPl9nZXRfcGF0aChmaWxlbmFtZSxnZXR1aWQoKSk7CisgIGlmIChmaWxlX3NpemUoZmlsZW5hbWUpPDAmJighdG9fZmlsZW5hbWUoZmlsZW5hbWUrIi5jIikpfHwKKyAgICAgIGZpbGVfc2l6ZSh0b19maWxlbmFtZShmaWxlbmFtZSsiLmMiKSk8MCkKKyAgeworICAgIHByaW50ZigiZXhlYzogJXM6IERhdGVpIG5pY2h0IHZvcmhhbmRlbiBvZGVyIGVpbiBWZXJ6ZWljaG5pcy5cbiIsZmlsZW5hbWUpOworICAgIHJldHVybiAxOworICB9CisgIGlmIChjYXRjaChjYWxsX290aGVyKGZpbGVuYW1lLCI/Pz8/IikpKSAKKyAgeworICAgIHByaW50ZigiZXhlYzogRmVobGVyIGJlaW0gTGFkZW4gdm9uICVzLlxuIixmaWxlbmFtZSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKCEob2I9Y2xvbmVfb2JqZWN0KGZpbGVuYW1lKSkpIHJldHVybiAwOworICBpZiAoZ2V0dWlkKG9iKSAhPSBnZXR1aWQodGhpc19vYmplY3QoKSkpCisgIHsKKyAgICBwcmludGYoImV4ZWM6IFVJRC1Lb25mbGlrdDogJXMgPC0+ICVzLlxuIixnZXR1aWQob2IpLAorICAgICAgICAgICBnZXR1aWQodGhpc19vYmplY3QoKSkpOworICAgIGRlc3RydWN0KG9iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBsb2dfZmlsZShTSEVMTExPRygiRVhFQyIpLAorICAgICAgICAgc3ByaW50ZigiJTEyLjEycyAlNDAuNDBzICUyNS4yNXNcbiIsCisgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKHRoaXNfb2JqZWN0KCkpKSxmaWxlbmFtZSxkdGltZSh0aW1lKCkpWzQuLl0pKTsKKyAgZGlzYWJsZV9jb21tYW5kcygpOworICBleGVjKG9iLHRoaXNfb2JqZWN0KCkpOworICBpZiAoaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSl8fCFpbnRlcmFjdGl2ZShvYikpCisgIHsKKyAgICBlbmFibGVfY29tbWFuZHMoKTsKKyAgICBwcmludGYoIkZlaGxlciBiZWkgRVhFQzogVWViZXJ0cmFndW5nIGRlciBTaGVsbCAiCisgICAgICAgICAgICJuaWNodCBtb2VnbGljaC5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIG9iLT5zdGFydF9wbGF5ZXIoY2FwaXRhbGl6ZShnZXR1aWQodGhpc19vYmplY3QoKSkpKTsKKyAgcmVtb3ZlKCk7CisgIHJldHVybiAxOworfQorLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFNOT09QSU5HICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIworCitwcml2YXRlIG5vc2F2ZSBzdHJpbmcgc25vb3BfYWxsb3dlZDsKK3ByaXZhdGUgbm9zYXZlIG9iamVjdCBzbm9vcGVlOworCitub21hc2sgaW50IFF1ZXJ5QWxsb3dTbm9vcChvYmplY3Qgd2hvKQoreworICByZXR1cm4gKGdldHVpZCh3aG8pID09IHNub29wX2FsbG93ZWQpOworfQorCitzdGF0aWMgaW50IF9zYWxsb3coc3RyaW5nIHN0cikKK3sKKyAgb2JqZWN0IG9iOworCisgIGlmICghc2l6ZW9mKHN0cikpCisgIHsKKyAgICBpZiAoIXNub29wX2FsbG93ZWQpIHJldHVybiBVU0FHRSgic2FsbG93IFs8bmFtZT5dXG4iKTsKKyAgICBzdHI9c25vb3BfYWxsb3dlZDsKKyAgICBzbm9vcF9hbGxvd2VkPTA7CisgICAgcHJpbnRmKCJEdSBlbnR6aWVoc3QgJXMgZGllIEVybGF1Ym5pcyB6dW0gU25vb3Blbi5cbiIsY2FwaXRhbGl6ZShzdHIpKTsKKyAgICBvYj1xdWVyeV9zbm9vcCh0aGlzX3BsYXllcigpKTsKKyAgICBpZiAoIW9ifHwoZ2V0dWlkKG9iKSE9c3RyKSkgcmV0dXJuIDE7CisgICAgdGVsbF9vYmplY3Qob2IsYnJlYWtfc3RyaW5nKHNwcmludGYoIiVzIGVudHppZWh0IERpciBkaWUgIgorICAgICAgICAgICAgIkVybGF1Ym5pcyB6dW0gc25vb3BlbiB1bmQgendpbmd0IERpY2ggc28gZGF6dSwgbWl0ICIKKyAgICAgICAgICAgICJkZW0gU25vb3BlbiBhdWZ6dWhvZXJlbi5cbiIsY2FwaXRhbGl6ZShnZXR1aWQoKSkpKSk7CisgICAgc25vb3Aob2IpOworICAgIHJldHVybiAxOworICB9CisgIGlmIChzbm9vcF9hbGxvd2VkKSBfc2FsbG93KCIiKTsgLy8gRXJzdG1hbCBhYnNjaGFsdGVuCisgIG9iPWZpbmRfcGxheWVyKGxvd2VyX2Nhc2Uoc3RyKSk7CisgIHN0cj1jYXBpdGFsaXplKHN0cik7CisgIGlmICghb2IpIHJldHVybgorICAgICAgcHJpbnRmKCJzYWxsb3c6IFNwaWVsZXIgJXMga29ubnRlIG5pY2h0IGdlZnVuZGVuIHdlcmRlbi5cbiIsc3RyKSwxOworICBpZiAocXVlcnlfd2l6X2dycChvYik+cXVlcnlfd2l6X2dycCh0aGlzX3BsYXllcigpKSkKKyAgICByZXR1cm4gcHJpbnRmKCJzYWxsb3c6ICVzIGhhdCBlaW5lbiBob2VoZXJlbiBSYW5nIGFscyBEdSB1bmQga2FubiAiCisgICAgICAgICAgICAgICAgICAiRGljaCBkYWhlciBvaG5laGluIHNub29wZW4uXG4iLHN0ciksMTsKKyAgc25vb3BfYWxsb3dlZD1nZXR1aWQob2IpOworICByZXR1cm4gcHJpbnRmKCJzYWxsb3c6IER1IGVybGF1YnN0ICVzLCBEaWNoIHp1IHNub29wZW4uXG4iLHN0ciksMTsKK30KKworc3RhdGljIGludCBfc25vb3Aoc3RyaW5nIGNtZGxpbmUpCit7CisgIG9iamVjdCBvYjsKKyAgaW50IGZsYWdzOworICBzdHJpbmcgKmFyZ3M7CisKKyAgaWYgKCFzaXplb2YoY21kbGluZT1fdW5wYXJzZWRfYXJncygpKXx8CisgICAgICBzaXplb2YoYXJncz1wYXJzZWFyZ3MoY21kbGluZSwmZmxhZ3MsU05PT1BfT1BUUywwKSkhPTF8fGZsYWdzPT0tMSkKKyAgeworICAgIGlmICghc25vb3AodGhpc19vYmplY3QoKSkpIHJldHVybiBVU0FHRSgic25vb3AgWy0iIFNOT09QX09QVFMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIl0gWzxzcGllbGVyPl1cbiIpOworICAgIGlmIChzbm9vcGVlKQorICAgICAgcHJpbnRmKCJEdSBzbm9vcHN0ICVzIGpldHp0IG5pY2h0IG1laHIuXG4iLGNhcGl0YWxpemUoZ2V0dWlkKHNub29wZWUpKSk7CisgICAgZWxzZQorICAgIHsKKyAgICAgIHByaW50ZigiRHUgaG9lcnN0IGF1ZiB6dSBzbm9vcGVuLlxuIik7CisgICAgLy8gZXZ0bC4gaXJnZW5kZXR3YXMgbG9nZ2VuIC4uLiBzb2xsdGUgZWlnZW50bGljaCBuaWNodCBwYXNzaWVyZW4uCisgICAgfQorICAgIHNub29wZWU9KG9iamVjdCkwOworICAgIHJldHVybiAxOworICB9CisgIFNldFByb3AoUF9TTk9PUEZMQUdTLGZsYWdzKTsgLy8gRlVOS1RJT05JRVJUIE5VUiwgV0VOTiBtYWdpZXIuaCB1bmQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzbm9vcGluZy5oIGFiZ2VnbGljaGVuIHNpbmQKKyAgaWYgKCEob2IgPSBmaW5kX3BsYXllcihhcmdzWzBdKSkpCisgICAgcmV0dXJuIHByaW50Zigic25vb3A6IEtvbm50ZSBrZWluZW4gU3BpZWxlciAnJXMnIGZpbmRlbi5cbiIsCisgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKGFyZ3NbMF0pKSwxOworICBpZiAoIXNub29wKHRoaXNfcGxheWVyKCksb2IpKQorICAgIHJldHVybiBwcmludGYoInNub29wOiBEZXIgVmVyc3VjaCwgJXMgenUgc25vb3BlbiwgaXN0ICIKKyAgICAgICAgICAgICAgICAgICJmZWhsZ2VzY2hsYWdlbi5cbiVzIixjYXBpdGFsaXplKGFyZ3NbMF0pLAorICAgICAgICAgICAgICAgICAgKCh+ZmxhZ3MpJlNOT09QX0YpPyJFdmVudHVlbGwgZnVua3Rpb25pZXJ0IGVzIG1pdCBkZW0gIgorICAgICAgICAgICAgICAgICAgIkZsYWcgJy1mJy5cbiI6IiIpLDE7CisgIHNub29wZWU9b2I7CisgIHJldHVybiBwcmludGYoIkR1IHNub29wc3QgamV0enQgJXMuXG4iLGNhcGl0YWxpemUoZ2V0dWlkKG9iKSkpLDE7Cit9CisKKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgTVNDSEFVICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjCisKK3N0YXRpYyBpbnQgX21zY2hhdShzdHJpbmcgc3RyKQoreworICBpZiAodGhpc19pbnRlcmFjdGl2ZSgpIT10aGlzX29iamVjdCgpKSByZXR1cm4gMDsKKyAgaWYgKHN0cj09ImphInx8c3RyPT0iYW4ifHxzdHI9PSJlaW4iKQorICB7CisgICAgaWYgKCBRdWVyeVByb3AoUF9XQU5UU19UT19MRUFSTikgKQorICAgICAgcHJpbnRmKCJEdSBoYXN0IGRlbiBNYWdpZXItTW9kdXMgZG9jaCBzY2hvbiBlaW5nZXNjaGFsdGV0IVxuIik7CisgICAgZWxzZQorICAgIHsKKyAgICAgIHByaW50ZigiRHUgaGFzdCBqZXR6dCBkZW4gTWFnaWVyLU1vZHVzIGVpbmdlc2NoYWx0ZXQuXG4iICk7CisgICAgICBTZXRQcm9wKFBfV0FOVFNfVE9fTEVBUk4sIDEpOworICAgIH0KKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoc3RyPT0ibmVpbiJ8fHN0cj09ImF1cyIpCisgIHsKKyAgICBpZiAoUXVlcnlQcm9wKFBfV0FOVFNfVE9fTEVBUk4pKQorICAgIHsKKyAgICAgIHByaW50ZiggIkR1IHNjaGFsdGVzdCBkZW4gTWFnaWVyLU1vZHVzIGF1cy5cbiIpOworICAgICAgc2V0X2hlYXJ0X2JlYXQoMSk7CisgICAgICBTZXRQcm9wKFBfV0FOVFNfVE9fTEVBUk4sMCk7CisgICAgfQorICAgIGVsc2UKKyAgICAgIHByaW50ZigiRHUgaGFzdCBkZW4gTWFnaWVyLU1vZHVzIGRvY2ggc2Nob24gYXVzZ2VzY2hhbHRldC5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIGlmIChzdHI9PSIrZGVidWciKQorICB7CisgICAgcHJpbnRmKCJEdSBuaW1tc3QgamV0enQgRGVidWdhdXNnYWJlbiB3YWhyLlxuIik7CisgICAgU2V0UHJvcChQX1dJWl9ERUJVRywxKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoc3RyPT0iLWRlYnVnIikKKyAgeworICAgIHByaW50ZigiRHUgbmltbXN0IGpldHp0IGtlaW5lIERlYnVnYXVzZ2FiZW4gbWVociB3YWhyLlxuIik7CisgICAgU2V0UHJvcChQX1dJWl9ERUJVRywwKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gVVNBR0UoIm1zY2hhdSBbYW58ZWlufGphfGF1c3xuZWlufCtkZWJ1Z3wtZGVidWddXG4iKTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFBST1RFQ1QgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMKKworc3RhdGljIGludCBfcHJvdGVjdChzdHJpbmcgc3RyKQoreworIAorICBpZiAodGhpc19vYmplY3QoKSE9dGhpc19pbnRlcmFjdGl2ZSgpKSByZXR1cm4gMDsKKyAgaWYgKCFzaXplb2Yoc3RyKSkKKyAgICByZXR1cm4gVVNBR0UoInByb3RlY3QgPHByb3BlcnR5bmFtZT5cbiIpOworICBTZXQoc3RyLCBQUk9URUNURUQsIEZfTU9ERSk7CisgIHJldHVybiBwcmludGYoIkRlaW5lIFByb3BlcnR5ICVzIGlzdCBqZXR6dCAlc2dlc2NodWV0enQuXG4iLAorICAgICAgICAgICAgICAgIHN0ciwoUXVlcnkoc3RyLEZfTU9ERSkgJiBQUk9URUNURUQ/IiI6Im5pY2h0IG1laHIgIikpLDE7Cit9CisKKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFZJUyArIElOVklTICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjCisKK3N0YXRpYyBpbnQgX2hic3RvcDsKK3N0YXRpYyBpbnQgX2FnZTsKKworc3RhdGljIGludCBfaW52aXMoc3RyaW5nIGluZm9ybSkKK3sKKworICBpZiAoUXVlcnlQcm9wKFBfSU5WSVMpKQorICAgIHJldHVybiBwcmludGYoIkR1IGJpc3QgZG9jaCBzY2hvbiB1bnNpY2h0YmFyIVxuIiksMTsKKyAgdGVsbF9yb29tKGVudmlyb25tZW50KCksc3ByaW50ZigiJXMgJXMuXG4iLGNhcGl0YWxpemUoTmFtZSgpKSwKKyAgICAgICAgICAgIFF1ZXJ5UHJvcChQX01NU0dPVVQpKSwoeyB0aGlzX29iamVjdCgpIH0pKTsKKyAgaWYgKGluZm9ybT09ImUiKSB7CisgICAgLy8gTG9nb3V0LWV2ZW50IGF1c2xvZXNlbgorICAgIEVWRU5URC0+VHJpZ2dlckV2ZW50KEVWVF9MSUJfTE9HT1VULCAoWworICAgICAgICAgICAgRV9PQkpFQ1Q6IHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgICBFX1BMTkFNRTogZ2V0dWlkKHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgICAgRV9FTlZJUk9OTUVOVDogZW52aXJvbm1lbnQoKSBdKSApOworCisgICAgY2FsbF9ub3RpZnlfcGxheWVyX2NoYW5nZSgwKTsKKyAgfQorCisgIFNldFByb3AoUF9JTlZJUywgUXVlcnlQcm9wKFBfQUdFKSk7CisgIHByaW50ZigiRHUgYmlzdCBqZXR6dCB1bnNpY2h0YmFyLlxuIik7CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IF92aXMoc3RyaW5nIGluZm9ybSkKK3sKKyAgaWYgKCFRdWVyeVByb3AoUF9JTlZJUykpCisgICAgcmV0dXJuIHByaW50ZigiRHUgYmlzdCBkb2NoIHNjaG9uIHNpY2h0YmFyLlxuIiksMTsKKyAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCgpLHNwcmludGYoIiVzICVzLlxuIixjYXBpdGFsaXplKE5hbWUoKSksCisgICAgICAgICAgICBRdWVyeVByb3AoUF9NTVNHSU4pKSwoeyB0aGlzX29iamVjdCgpIH0pKTsKKyAgU2V0UHJvcChQX0lOVklTLCAwKTsKKyAgaWYgKGluZm9ybT09ImUiKSB7CisgICAgLy8gTG9naW4tZXZlbnQgYXVzbG9lc2VuCisgICAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoRVZUX0xJQl9MT0dJTiwgKFsKKyAgICAgICAgICBFX09CSkVDVDogdGhpc19vYmplY3QoKSwKKyAgICAgICAgICBFX1BMTkFNRTogZ2V0dWlkKHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgIEVfRU5WSVJPTk1FTlQ6IGVudmlyb25tZW50KCkgXSkgKTsKKworICAgIGNhbGxfbm90aWZ5X3BsYXllcl9jaGFuZ2UoMSk7CisgIH0KKyAgcHJpbnRmKCJEdSBiaXN0IGpldHp0IHNpY2h0YmFyLlxuIik7CisgIHJldHVybiAxOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBMT0NBTENNRCAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjCisKKworc3RhdGljIGludCBfbG9jYWxjbWQoKQoreworICBpbnQgc2l6ZSxtb3JlOworICBzdHJpbmcgKnZlcmJzLHJlc3VsdDsKKworICAvLyBQZXIgVW13ZWcgdWViZXIgTWFwcGluZyBkb3BwZWx0ZSBXZXJ0ZSBlaW5zdGFtcGZlbgorICBzaXplPXNpemVvZih2ZXJicz1tX2luZGljZXMobWttYXBwaW5nKHF1ZXJ5X2FjdGlvbnModGhpc19vYmplY3QoKSkpKSk7CisgIHZlcmJzLT0oeyIifSk7CisgIG1vcmU9KHNpemU+c2l6ZW9mKHZlcmJzKSk7CisgIGlmICghc2l6ZW9mKHZlcmJzKSkKKyAgeworICAgIGlmIChtb3JlKQorICAgICAgcHJpbnRmKCJEaWUgdm9yaGFuZGVuZW4gQmVmZWhsZSBrb2VubmVuIG5pY2h0IGFuZ2V6ZWlndCB3ZXJkZW4sICIKKyAgICAgICAgICAgICAiZGEgc2llIHBlciAnYWRkX2FjdGlvbihcImZ1bmt0aW9uXCIsXCJcIiwxKScgZGVmaW5pZXJ0ICIKKyAgICAgICAgICAgICAid3VyZGVuLlxuIik7CisgICAgZWxzZQorICAgICAgcHJpbnRmKCJEaXIgc3RlaGVuIGtlaW5lIEJlZmVobGUgenVyIFZlcmZ1ZWd1bmcgLi4uIGVpZ2VuYXJ0aWchXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICB2ZXJicz1zb3J0X2FycmF5KHZlcmJzLCMnPik7CisgIHJlc3VsdD1icmVha19zdHJpbmcoc3ByaW50ZigiXCclc1wnIixpbXBsb2RlKHZlcmJzLCInICciKSksNzgpOworICByZXR1cm4gcHJpbnRmKCJcbiUnLSc3OC43OHNcbkRpZSBmdWVyIERpY2ggYWt0dWVsbCB2ZXJmdWVnYmFyZW4gIgorICAgICAgICAgICAgICAgICJCZWZlaGxlIHNpbmQ6XG5cbiVzXG4lcyUnLSc3OC43OHNcbiIsIiIscmVzdWx0LAorICAgICAgICAgICAgICAgIG1vcmU/Ilp1ZGVtIHd1cmRlbiBCZWZlaGxlIHBlciAnYWRkX2FjdGlvbigiCisgICAgICAgICAgICAgICAgIlwiZnVua3Rpb25cIixcIlwiLDEpJyBkZWZpbmllcnQuXG4iOiIiLCIiKSwxOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgVFJBRU5LRSAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIworCitzdGF0aWMgaW50IF90cmFlbmtlKHN0cmluZyBzdHIpCit7CisgIGlmKFNldFByb3AoUF9UUkFOS19GSU5ERU4sICFRdWVyeVByb3AoUF9UUkFOS19GSU5ERU4pKSkKKyAgICB3cml0ZSgiRHUga2FubnN0IGpldHp0IFphdWJlcnRyYWVua2UgZmluZGVuLlxuIik7CisgIGVsc2UKKyAgICB3cml0ZSgiRHUgZmluZGVzdCBqZXR6dCBrZWluZSBaYXViZXJ0cmFlbmtlIG1laHIuXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgbm9ybV9ydXNhZ2UoKSB7CisJbWl4ZWQqIHI7CisgIHIgPSBydXNhZ2UoKTsKKyAgcmV0dXJuIHJbMF0vMTAwICsgclsxXS8xMDA7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIEFTWU5DSFJPTiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIworCisvLworLy8gYXN5bmNocm9uKCk6IEFzeW5jaHJvbmUgQWJhcmJlaXR1bmcgZWluZXMgQXJyYXlzCisvLyBhcnJheTogICAgIFp1IGJlYXJiZWl0ZW5kZXMgQXJyYXkKKy8vIGNtZDogICAgICAgQXVzenVmdWVocmVuZGUgQ2xvc3VyZQorLy8gZGF0YTogICAgICBFeHRyYWFyZ3VtZW50ZQorLy8gZmxhZ3M6ICAgICBadXNhdHpkYXRlbiAobm9ybWFsZXJ3ZWlzZSBGbGFncykKKy8vIGM6ICAgICAgICAgc2Nob24gYXN5bmNocm9uPworLy8KKworc3RhdGljIHZhcmFyZ3Mgdm9pZCBhc3luY2hyb24obWl4ZWQqIGFycmF5LCBjbG9zdXJlIGNtZCwgbWl4ZWQgZGF0YSwgbWl4ZWQgZmxhZ3MsaW50IGMpCit7CisgIGludCBpLCBqLCBrOworICBtaXhlZCByZXRfdmFsOworICBzdHJpbmcgY21kX3N0cmluZzsKKworICBrID0gbm9ybV9ydXNhZ2UoKSs1OworICBqID0gc2l6ZW9mKGFycmF5KTsKKyAgaT0wOworICAKKyAgc3dpdGNoIChjbWRfc3RyaW5nPWV4cGxvZGUoc3ByaW50ZigiJU8iLGNtZCksIi0+IilbMV0pCisgIHsKKyAgICBjYXNlICJfbWFrZSI6ICAgICBjbWRfc3RyaW5nPShkYXRhJlVQRF9MT0FEPyJsb2FkIjoidXBkIik7YnJlYWs7CisgICAgY2FzZSAiY3BfZmlsZSI6ICAgY21kX3N0cmluZyA9KGRhdGE/Im12IjoiY3AiKTsgYnJlYWs7CisgICAgY2FzZSAiZ3JlcF9maWxlIjogY21kX3N0cmluZyA9ICJncmVwIjsgYnJlYWs7CisgICAgY2FzZSAicm1fZmlsZSI6ICAgY21kX3N0cmluZyA9ICJybSI7IGJyZWFrOworICAgIGRlZmF1bHQ6IGJyZWFrOworICB9CisgIAorICB3aGlsZShpIDwgaiAmJiBnZXRfZXZhbF9jb3N0KCkgPiAyMDAwMDAgJiYgbm9ybV9ydXNhZ2UoKTxrKQorICAgIC8vIFNvd29obCBUb28tTG9uZy1FdmFsIGFscyBhdWNoIExhZyB2ZXJoaW5kZXJuCisgIHsKKyAgICByZXRfdmFsPWFwcGx5KGNtZCxhcnJheVtpXSxkYXRhLCBmbGFncyk7CisgICAgaWYgKGNsb3N1cmVwKHJldF92YWwpKQorICAgIHsKKyAgICAgIGlmKGMpIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgICAgICBzcHJpbnRmKCIlczogVmVybGFzc2UgQXN5bmNocm9uZW4gTW9kdXMuXG4iLGNtZF9zdHJpbmcpKTsKKyAgICAgIGZ1bmNhbGwocmV0X3ZhbCxhcnJheVtpLi5dLGRhdGEsZmxhZ3MpOworICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAocmV0X3ZhbD09UkVUX0RFTEVURSkKKyAgICB7CisgICAgICBhcnJheVtpK2FycmF5W2ldW1NVQkRJUlNJWkVdKzEuLmkrYXJyYXlbaV1bU1VCRElSU0laRV1dPQorICAgICAgICAoeyAoYXJyYXlbaV1bMC4uNV0rKHswfSkpIH0pOworICAgIH0KKyAgICBpZiAocmV0X3ZhbD09UkVUX0pVTVApIGkrPWFycmF5W2ldW1NVQkRJUlNJWkVdOworICAgIGkrKzsKKyAgfQorICBpZihzaXplb2YoYXJyYXkgPSBhcnJheVtpLi5dKSkgCisgIHsgIAorICAgIGlmKCFjKSB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgICAgICBzcHJpbnRmKCIlczogQXN5bmNocm9uZXIgTW9kdXMgYWt0aXZpZXJ0IVxuIiwgY21kX3N0cmluZykpOworICAgIGNhbGxfb3V0KCMnYXN5bmNocm9uLCAxLCBhcnJheSwgY21kLCBkYXRhLGZsYWdzLCAxKTsKKyAgfQorICBlbHNlCisgIHsKKyAgICBpZihjKSB0ZWxsX29iamVjdCh0aGlzX29iamVjdCgpLAorICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoIiVzOiBhYmdlc2NobG9zc2VuLlxuIixjbWRfc3RyaW5nKSk7CisgICAgICBlbHNlIGlmIChxdWVyeV92ZXJiKCkpIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksCisgICAgICAgICAgICBzcHJpbnRmKCIlczogYWJnZXNjaGxvc3Nlbi5cbiIscXVlcnlfdmVyYigpKSk7CisgIH0KKyAgcmV0dXJuOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKK30KKworLy8KKy8vICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBEcml2ZXIgU3RhdHVzIEluZm9zICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLworc3RhdGljIGludCBfZHJpdmVyX21hbGxvYyhzdHJpbmcgc3RyKQoreworICAgIGlmKCFzaXplb2Yoc3RyKSkKKyAgICB7CisgICAgICAgIHdyaXRlKGVmdW46OmRyaXZlcl9pbmZvKERJX1NUQVRVU19URVhUX01BTExPQykpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgaWYoc3RyID09ICJleHRzdGF0cyIpCisgICAgeworICAgICAgICB3cml0ZShlZnVuOjpkcml2ZXJfaW5mbyhESV9TVEFUVVNfVEVYVF9NQUxMT0NfRVhURU5ERUQpKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50IF9kcml2ZXJfZHVtcGFsbG9iaihzdHJpbmcgc3RyKQoreworICAgIHdyaXRlKCJEdW1waW5nIHRvIC9PQkpfRFVNUCAuLi4gIik7CisgICAgZWZ1bjo6ZHVtcF9kcml2ZXJfaW5mbyhERElfT0JKRUNUUyk7CisgICAgZWZ1bjo6ZHVtcF9kcml2ZXJfaW5mbyhERElfT0JKRUNUU19ERVNUUlVDVEVEKTsKKyAgICB3cml0ZSgiZG9uZVxuIik7CisgICAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgX2RyaXZlcl9vcGNkdW1wKHN0cmluZyBzdHIpCit7CisgICAgZWZ1bjo6ZHVtcF9kcml2ZXJfaW5mbyhERElfT1BDT0RFUyk7CisgICAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQgX2RyaXZlcl9zdGF0dXMoc3RyaW5nIHN0cikKK3sKKyAgICBpbnQgb3B0OworCisgICAgc3dpdGNoKHN0ciB8fCAiIikKKyAgICB7CisgICAgICAgIGNhc2UgIiI6CisgICAgICAgICAgICBvcHQgPSBESV9TVEFUVVNfVEVYVF9NRU1PUlk7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlICJ0YWJsZXMiOgorICAgICAgICBjYXNlICIgdGFibGVzIjoKKyAgICAgICAgICAgIG9wdCA9IERJX1NUQVRVU19URVhUX1RBQkxFUzsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgInN3YXAiOgorICAgICAgICBjYXNlICIgc3dhcCI6CisgICAgICAgICAgICBvcHQgPSBESV9TVEFUVVNfVEVYVF9TV0FQOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSAibWFsbG9jIjoKKyAgICAgICAgY2FzZSAiIG1hbGxvYyI6CisgICAgICAgICAgICBvcHQgPSBESV9TVEFUVVNfVEVYVF9NQUxMT0M7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlICJtYWxsb2MgZXh0c3RhdHMiOgorICAgICAgICBjYXNlICIgbWFsbG9jIGV4dHN0YXRzIjoKKyAgICAgICAgICAgIG9wdCA9IERJX1NUQVRVU19URVhUX01BTExPQ19FWFRFTkRFRDsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgd3JpdGUoZWZ1bjo6ZHJpdmVyX2luZm8ob3B0KSk7CisgICAgcmV0dXJuIDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgSU5JVElBTElTSUVSVU5HICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjCisKKy8vCisvLyBfcXVlcnlfbG9jYWxjbWRzOiBXZWxjaGUgS29tbWFuZG9zIHdlcmRlbiBpbiBkaWVzZXIgRGF0ZWkgaW1wbGVtZW50aWVydD8KKy8vCisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfbG9jYWxjbWRzKCkKK3sKKyAgcmV0dXJuICh7CisgICAgKHsic2V0IiwiX3NldCIsMCxMRUFSTkVSX0xWTH0pLAorICAgICh7InB3ZCIsIl9wd2QiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAoeyJjZCIsIl9jZCIsMCxMRUFSTkVSX0xWTH0pLAorICAgICh7InByb21wdCIsIl9wcm9tcHQiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAoeyJzaG93cHJlc2F5IiwiX3Nob3dwcmVzYXkiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAoeyJleGVjIiwiX2V4ZWMiLDAsQVJDSF9MVkx9KSwKKyAgICAoeyJzYWxsb3ciLCJfc2FsbG93IiwwLExFQVJORVJfTFZMfSksCisgICAgKHsic25vb3AiLCJfc25vb3AiLDAsV0laQVJEX0xWTH0pLAorICAgICh7Im1zY2hhdSIsIl9tc2NoYXUiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAoeyJwcm90ZWN0IiwiX3Byb3RlY3QiLDAsV0laQVJEX0xWTH0pLAorICAgICh7ImludmlzIiwiX2ludmlzIiwwLExFQVJORVJfTFZMfSksCisgICAgKHsidmlzIiwiX3ZpcyIsMCxMRUFSTkVSX0xWTH0pLAorICAgICh7ImxvY2FsY21kIiwiX2xvY2FsY21kIiwwLExFQVJORVJfTFZMfSksCisgICAgKHsidHJhZW5rZSIsIl90cmFlbmtlIiwwLERPTUFJTk1FTUJFUl9MVkx9KSwKKyAgICAoeyJtYWxsb2MiLCJfZHJpdmVyX21hbGxvYyIsMCxMRUFSTkVSX0xWTH0pLAorICAgICh7ImR1bXBhbGxvYmoiLCJfZHJpdmVyX2R1bXBhbGxvYmoiLDAsQVJDSF9MVkx9KSwKKyAgICAoeyJvcGNkdW1wIiwiX2RyaXZlcl9vcGNkdW1wIiwwLEFSQ0hfTFZMfSksCisgICAgKHsic3RhdHVzIiwiX2RyaXZlcl9zdGF0dXMiLDAsTEVBUk5FUl9MVkx9KSwKKyAgfSkKKyAgICArZmlsZXZpZXc6Ol9xdWVyeV9sb2NhbGNtZHMoKQorICAgICt1cGQ6Ol9xdWVyeV9sb2NhbGNtZHMoKQorICAgICtvYmplY3RzOjpfcXVlcnlfbG9jYWxjbWRzKCkKKyAgICArZmlsZWVkaXQ6Ol9xdWVyeV9sb2NhbGNtZHMoKQorLy8gICAgK3RvZG86Ol9xdWVyeV9sb2NhbGNtZHMoKQorICAgICtwbGF5ZXJzOjpfcXVlcnlfbG9jYWxjbWRzKCkKKyAgICArYWRtaW46Ol9xdWVyeV9sb2NhbGNtZHMoKQorICAgICttb3Zpbmc6Ol9xdWVyeV9sb2NhbGNtZHMoKQorICAgICtjb21tOjpfcXVlcnlfbG9jYWxjbWRzKCk7Cit9CisKKy8vCisvLyBpbml0aWFsaXplOiBJbml0aWFsaXNpZXJ1bmcgZGVyIFNoZWxsCisvLworCitzdGF0aWMgdm9pZCBpbml0aWFsaXplKCkKK3sKKyAgU2V0KFBfUFJPTVBULCBTQVZFLCBGX01PREVfQVMpOworICBTZXQoUF9WQVJJQUJMRVMsU0FWRSxGX01PREVfQVMpOworICBTZXQoImZpbGVzeXMiLFNBVkUsRl9NT0RFX0FEKTsgICAvLyBQX0ZJTEVTWVMgaXN0IG9ic29sZXQKKyAgU2V0KCJzaG9ydF9jd2QiLFNBVkUsRl9NT0RFX0FEKTsgLy8gUF9TSE9SVF9DV0QgYXVjaAorICBpZighbWFwcGluZ3AoUXVlcnlQcm9wKFBfVkFSSUFCTEVTKSkpCisgICAgU2V0UHJvcChQX1ZBUklBQkxFUywgKFtdKSk7CisgIF9wcm9tcHQoUXVlcnlQcm9wKFBfUFJPTVBUKSk7CisvLyAgdG9kbzo6aW5pdGlhbGl6ZSgpOworICBfY2QyKCIiKTsKKyAgcmV0dXJuOworfQorCitzdGF0aWMgdm9pZCByZWNvbm5lY3QoKSB7IF9jZChRdWVyeVByb3AoUF9DVVJSRU5URElSKSk7IH0KZGlmZiAtLWdpdCBhL3N0ZC9zaGVsbHMvbWFnaWVyL21vdmluZy5jIGIvc3RkL3NoZWxscy9tYWdpZXIvbW92aW5nLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzA5NWEzZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvbWFnaWVyL21vdmluZy5jCkBAIC0wLDAgKzEsMjMyIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gbW92aW5nLmMKKy8vCisvLyAkSWQ6IG1vdmluZy5jIDkxNDIgMjAxNS0wMi0wNCAyMjoxNzoyOVogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8bWFnaWVyLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGxpdmluZy9tb3ZpbmcuaD4KKyNpbmNsdWRlIDxwbGF5ZXIuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisKK3ByaXZhdGUgbWl4ZWQgdmVyZm9sZ2VyKCkKK3sKKyAgbWl4ZWQgKnB1cjsKKworICBpZiAoIXBvaW50ZXJwKHB1cj1RdWVyeVByb3AoUF9QVVJTVUVSUykpKSByZXR1cm4gMDsKKyAgZWxzZSByZXR1cm4gcHVyWzBdOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgSU4rQVQgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjCisKK3N0YXRpYyBpbnQgX21vdmVfYmFzZShvYmplY3QgdGFyZ2V0LCBvYmplY3Qgb2xkX3Jvb20sIHN0cmluZyBjbWQpCit7CisgIGlmIChlbnZpcm9ubWVudCgpIT10YXJnZXQpCisgICAgaWYgKElTX0FSQ0godGhpc19vYmplY3QoKSkpCisgICAgeworICAgICAgX19zZXRfZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSx0YXJnZXQpOworICAgICAgcHJpbnRmKCIlczogQmV3ZWd1bmcgaGF0IG5pY2h0IGdla2xhcHB0LiBWZXJzdWNoZSBlcyBtaXQgIgorICAgICAgICAgICAgICJzZXRfZW52aXJvbm1lbnQuLi4gJXMuXG4uIixxdWVyeV92ZXJiKCksCisgICAgICAgICAgICAgZW52aXJvbm1lbnQoKT09dGFyZ2V0PyJoYXQgZ2VrbGFwcHQiOiJlcmZvbGdsb3MiKTsKKyAgICB9CisgIGVsc2UKKyAgICBwcmludGYoIiVzOiBCZXdlZ3VuZyBoYXQgbmljaHQgZ2VrbGFwcHQuXG4iLHF1ZXJ5X3ZlcmIoKSk7CisgIGlmIChlbnZpcm9ubWVudCgpIT10YXJnZXQpIHJldHVybiAxOworICBjb21tYW5kKGNtZCk7CisgIGlmIChvbGRfcm9vbSkgbW92ZV9vYmplY3Qob2xkX3Jvb20pOworICBlbHNlCisgICAgcmV0dXJuIHByaW50ZigiJXM6IFVyc3BydW5nc3JhdW0gd3VyZGUgemVyc3RvZXJ0LlxuIixxdWVyeV92ZXJiKCkpLDE7ICAKKyAgaWYgKGVudmlyb25tZW50KCkhPW9sZF9yb29tKQorICB7CisgICAgaWYgKElTX0FSQ0godGhpc19vYmplY3QoKSkpCisgICAgeworICAgICAgX19zZXRfZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSxvbGRfcm9vbSk7CisgICAgICBwcmludGYoIiVzOiBadXJ1ZWNrYmV3ZWdlbiBoYXQgbmljaHQgZ2VrbGFwcHQuIFZlcnN1Y2hlIGVzIG1pdCAiCisgICAgICAgICAgICAgInNldF9lbnZpcm9ubWVudCAuLi4gJXMuXG4iLHF1ZXJ5X3ZlcmIoKSwKKyAgICAgICAgICAgICBlbnZpcm9ubWVudCgpPT1vbGRfcm9vbT8iaGF0IGdla2xhcHB0IjoiZXJmb2xnbG9zIik7CisgICAgfQorICAgIGVsc2UKKyAgICAgIHByaW50ZigiYXQ6IFp1cnVlY2tiZXdlZ2VuIGhhdCBuaWNodCBnZWtsYXBwdC5cbiIpOworICB9CisgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50IF9pbl9yb29tKHN0cmluZyBzdHIpCit7CisgIHN0cmluZyByb29tO2ludCBzaXplOworICBvYmplY3Qgb2xkX3Jvb207CisgIHN0cmluZyBjbWQsZXJyOworCisgIGlmICghc2l6ZW9mKHN0cj1fdW5wYXJzZWRfYXJncygpKSB8fAorICAgICAgIXNpemVvZihzdHI9cmVncmVwbGFjZShzdHIsIl4gKiIsIiIsMSkpIHx8CisgICAgICBzc2NhbmYoc3RyLCAiJXMgJXMiLCByb29tLCBjbWQpICE9IDIpCisgICAgcmV0dXJuIFVTQUdFKCJpbiA8cmF1bT4gPGJlZmVobD5cbiIpOworICBvbGRfcm9vbSA9IGVudmlyb25tZW50KCk7CisgIHJvb209KHN0cmluZyljYWxsX290aGVyKG1hc3RlcigpLCJfZ2V0X3BhdGgiLHJvb20sZ2V0dWlkKCkpOworICBpZiAoZXJyPWNhdGNoKG1vdmVfb2JqZWN0KHJvb20pKSkKKyAgeworICAgIGlmIChjYXRjaChzaXplPWZpbGVfc2l6ZShyb29tKyIuYyIpKXx8c2l6ZTwxKQorICAgICAgcHJpbnRmKCIlczogJXMuYzogRGF0ZWkgbmljaHQgdm9yaGFuZGVuLlxuIixxdWVyeV92ZXJiKCkscm9vbSk7CisgICAgZWxzZQorICAgICAgcHJpbnRmKCIlczogQmV3ZWd1bmcgbmFjaCAlcyBoYXQgbmljaHQgZnVua3Rpb25pZXJ0OiAlc1xuIiwKKyAgICAgICAgICAgICBxdWVyeV92ZXJiKCkscm9vbSxlcnIpOworICAgIHJldHVybiAxOworICB9CisgIHJldHVybiBfbW92ZV9iYXNlKGZpbmRfb2JqZWN0KHJvb20pLG9sZF9yb29tLGNtZCk7Cit9CisKK3N0YXRpYyBpbnQgX2F0X3BsYXllcihzdHJpbmcgZGVzdCkKK3sKKyAgb2JqZWN0IG9iLG9sZF9yb29tOworICBtaXhlZCB0bXA7CisgIHN0cmluZyBjbWQ7CisKKyAgaWYgKCFzaXplb2YoZGVzdD1fdW5wYXJzZWRfYXJncygpKSB8fAorICAgICAgIXNpemVvZihkZXN0PXJlZ3JlcGxhY2UoZGVzdCwiXiAqIiwiIiwxKSkgfHwKKyAgICAgIHNzY2FuZihkZXN0LCAiJXMgJXMiLCBkZXN0LCBjbWQpICE9IDIpCisgICAgcmV0dXJuIFVTQUdFKCJhdCA8bGViZXdlc2VuPiA8YmVmZWhsPlxuIik7CisgIGlmICghKG9iPWZpbmRfbGl2aW5nKGRlc3QpKSkKKyAgeworICAgIHRtcD1tYXRjaF9saXZpbmcoZGVzdCwxKTsKKyAgICBpZiAoc3RyaW5ncCh0bXApKSBvYiA9IGZpbmRfbGl2aW5nKHRtcCk7CisgIH0KKyAgaWYgKCFvYnx8IShvYj1lbnZpcm9ubWVudChvYikpKQorICAgIHJldHVybiBfbm90aWZ5X2ZhaWwoc3ByaW50ZigiYXQ6IExlYmV3ZXNlbiBcJyVzXCcgbmljaHQgZ2VmdW5kZW4uXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXN0KSksMDsKKyAgb2xkX3Jvb209ZW52aXJvbm1lbnQoKTsKKyAgbW92ZV9vYmplY3Qob2IpOworICByZXR1cm4gX21vdmVfYmFzZShvYixvbGRfcm9vbSxjbWQpOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgR09UTyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjCisKK3N0YXRpYyBvYmplY3QgZmluZF9saXZpbmdfbnIoc3RyaW5nIHN0cikKK3sgc3RyaW5nIG5hbWUsY2hlY2s7CisgIGludCBucjsKKyAgb2JqZWN0KmxpdmluZ3M7CisgIGlmKHNzY2FuZihzdHIsIiVzICVkJXMiLG5hbWUsbnIsY2hlY2spPDJ8fHNpemVvZihjaGVjaykpCisgICAgcmV0dXJuIGZpbmRfbGl2aW5nKHN0cik7CisgIGlmKCFzaXplb2YobGl2aW5ncz1maWx0ZXIoKGZpbmRfbGl2aW5ncyhuYW1lKXx8KHt9KSksIydlbnZpcm9ubWVudCkpCisgICAgIHx8bnI8MXx8c2l6ZW9mKGxpdmluZ3MpPG5yKQorICAgIHJldHVybiAwOworICByZXR1cm4gbGl2aW5nc1tuci0xXTsKK30KKworc3RhdGljIGludCBfZ290byhzdHJpbmcgZGVzdCl7CisgIG1peGVkIHRhcmdldDsKKyAgc3RyaW5nIHRhcmdldDIsZXJyOworCisgIGlmICghc2l6ZW9mKGRlc3Q9X3VucGFyc2VkX2FyZ3MoKSkpCisgICAgcmV0dXJuIFVTQUdFKCJnb3RvIFtsZWJld2VzZW58ZmlsZW5hbWVdXG4iKTsKKyAgaWYgKCEoKHRhcmdldD1maW5kX2xpdmluZ19ucihkZXN0KSkgJiYgKHRhcmdldD1lbnZpcm9ubWVudCh0YXJnZXQpKSkpCisgIHsKKyAgICAgdGFyZ2V0Mj10YXJnZXQ9KG1peGVkKWNhbGxfb3RoZXIobWFzdGVyKCksIl9nZXRfcGF0aCIsZGVzdCxnZXR1aWQoKSk7CisgICAgIGlmICghZmluZF9vYmplY3QodGFyZ2V0KSkKKyAgICAgeworICAgICAgIGlmICh0YXJnZXQyWzwxXT09Jy4nKSB0YXJnZXQyKz0iYyI7CisgICAgICAgaWYgKHRhcmdldDJbPDIuLjwxXSE9Ii5jIikgdGFyZ2V0Mis9Ii5jIjsKKyAgICAgICBub3RpZnlfZmFpbChzcHJpbnRmKCJnb3RvOiBEYXRlaSAlTyBuaWNodCB2b3JoYW5kZW4uXG4iLHRhcmdldCkpOworICAgICAgIGlmICghKGZpbGVfc2l6ZSh0YXJnZXQyKT4tMXx8CisgICAgICAgICAgIGZpbGVfc2l6ZShpbXBsb2RlKGV4cGxvZGUodGFyZ2V0LCIvIilbMC4uPDJdLCIvIikrCisgICAgICAgICAgICAgICAiL3ZpcnR1YWxfY29tcGlsZXIuYyIpPi0xKXx8KGVycj1jYXRjaChjYWxsX290aGVyKHRhcmdldCwiPyIpKSkpCisgICAgICAgeworICAgICAgICAgaWYgKGVycikKKyAgICAgICAgICAgICAgbm90aWZ5X2ZhaWwoc3ByaW50ZigiZ290bzogRmVobGVyIGJlaW0gVGVsZXBvcnQgbmFjaCAlTzpcbiVzXG4iLAorICAgICAgICAgICAgICAgICAgICAgIGRlc3QsaW1wbG9kZShleHBsb2RlKGVyciwiXG4iKSwiICIpKSk7CisgICAgICAgICB0YXJnZXQ9bWF0Y2hfbGl2aW5nKGRlc3QsMSk7CisgICAgICAgICBpZiAoIShzdHJpbmdwKHRhcmdldCkmJih0YXJnZXQ9ZmluZF9saXZpbmcodGFyZ2V0KSkmJgorICAgICAgICAgICAgICAgKHRhcmdldD1lbnZpcm9ubWVudCh0YXJnZXQpKSkpCisgICAgICAgICAgIHJldHVybiAwOworICAgICAgIH0KKyAgICAgfQorICB9CisgIGlmICh2ZXJmb2xnZXIoKSkgX3ZlcmZvbGdlKCIiKTsKKyAgaWYgKG1vdmUodGFyZ2V0LE1fVFBPUlR8TV9OT0NIRUNLKTwwKQorICAgIHByaW50ZigiQmV3ZWd1bmcgZmVobGdlc2NobGFnZW4hXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBIT01FICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMKKworc3RhdGljIGludCBfaG9tZSgpCit7CisgIHN0cmluZyBkZXN0OworICBpZiAodmVyZm9sZ2VyKCkpIF92ZXJmb2xnZSgiIik7CisgIGRlc3Q9Ii9wbGF5ZXJzLyIgKyBnZXR1aWQoKSArICIvd29ya3Jvb20iOworICBpZiAoZmlsZV9zaXplKGRlc3QrIi5jIik8MXx8Y2F0Y2goY2FsbF9vdGhlcihkZXN0LCI/Pz8iKSkpCisgIHsKKyAgICBwcmludGYoIkZlaGxlciBiZWltIExhZGVuIERlaW5lcyBXb3Jrcm9vbXMuXG4iCisgICAgICAgICAgICJHZWhlIHp1bSBNYWdpZXJ0cmVmZi5cbiIpOworICAgIGRlc3Q9Ii9zZWN1cmUvbWVybGluIjsKKyAgfQorICAKKyAgaWYgKG1vdmUoZGVzdCxNX1RQT1JUfE1fTk9DSEVDSyk8MCkKKyAgICBwcmludGYoIkJld2VndW5nIGZlaGxnZXNjaGxhZ2VuIVxuIik7CisgIHJldHVybiAxOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjICtNQUdJRVJOQU1FICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIworCitzdGF0aWMgaW50IF9nb193aXpfaG9tZShzdHJpbmcgc3RyKQoreworICBfbm90aWZ5X2ZhaWwoIlN5bnRheDogJyttYWdpZXJuYW1lJ1xuIik7CisgIGlmKHNpemVvZihxdWVyeV92ZXJiKCkpPjEpIHN0cj1xdWVyeV92ZXJiKClbMS4uXTsKKyAgaWYoIXNpemVvZihzdHIpKSByZXR1cm4gMDsKKyAgaWYocXVlcnlfdmVyYigpWzBdIT0nKycpIHJldHVybiAwOworICBzdHI9KG9sZF9leHBsb2RlKHN0ciwiICIpLSh7MH0pKVswXTsKKyAgaWYoIXNpemVvZihzdHIpKSByZXR1cm4gMDsKKyAgc3RyPWxvd2VyX2Nhc2Uoc3RyKTsKKyAgaWYgKHN0cj09Im1lcmxpbiIpCisgIHsKKyAgICBtb3ZlKCIvc2VjdXJlL21lcmxpbiIsTV9UUE9SVHxNX05PQ0hFQ0spOworICAgIHJldHVybiAxOworICB9CisgIGlmICgoIWNhbGxfb3RoZXIobWFzdGVyKCksImdldF91c2VyaW5mbyIsc3RyKSl8fAorICAgICAgIUlTX0xFQVJORVIoc3RyKSkKKyAgeworICAgIHByaW50ZigiRXMgZ2lidCBrZWluZW4gTWFnaWVyIG5hbWVucyAlcy5cbiIsCisgICAgICAgICAgIGNhcGl0YWxpemUoc3RyKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKGZpbGVfc2l6ZSgiL3BsYXllcnMvIitzdHIrIi93b3Jrcm9vbS5jIik8MSkKKyAgeworICAgIHByaW50ZigiJXMgaGF0IGtlaW5lbiBXb3Jrcm9vbS5cbiIsY2FwaXRhbGl6ZShzdHIpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoY2F0Y2goY2FsbF9vdGhlcigiL3BsYXllcnMvIitzdHIrIi93b3Jrcm9vbSIsIj8/PyIpKSkKKyAgeworICAgIHByaW50ZigiRGVyIFdvcmtyb29tIHZvbiAlcyBoYXQgRmVobGVyLlxuIixjYXBpdGFsaXplKHN0cikpOworICAgIHJldHVybiAxOworICB9CisgIG1vdmUoIi9wbGF5ZXJzLyIrc3RyKyIvd29ya3Jvb20iLE1fVFBPUlR8TV9OT0NIRUNLKTsKKyAgcmV0dXJuIDE7Cit9CisKKworc3RhdGljIG1peGVkIF9xdWVyeV9sb2NhbGNtZHMoKQoreworICByZXR1cm4KKyAgICAoeyh7ImdvdG8iLCJfZ290byIsMCxMRUFSTkVSX0xWTH0pLAorICAgICAgKHsiaW4iLCJfaW5fcm9vbSIsMCxMRUFSTkVSX0xWTH0pLAorICAgICAgKHsiYXQiLCJfYXRfcGxheWVyIiwwLExFQVJORVJfTFZMfSksCisgICAgICAoeyJob21lIiwiX2hvbWUiLDAsV0laQVJEX0xWTH0pLAorICAgICAgKHsiKyIsIl9nb193aXpfaG9tZSIsMSxMRUFSTkVSX0xWTH0pfSk7Cit9CmRpZmYgLS1naXQgYS9zdGQvc2hlbGxzL21hZ2llci9vYmplY3RzLmMgYi9zdGQvc2hlbGxzL21hZ2llci9vYmplY3RzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWQ3NGY1NgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvbWFnaWVyL29iamVjdHMuYwpAQCAtMCwwICsxLDE2OCBAQAorLy8gJElkOiBvYmplY3RzLmMgODg0OCAyMDE0LTA2LTExIDIyOjA1OjA0WiBaZXNzdHJhICQKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPGxpdmluZy9wdXRfYW5kX2dldC5oPgorI2luY2x1ZGUgPHBsYXllci5oPgorI2luY2x1ZGUgPG1hZ2llci5oPgorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBJTklUSUFMSVNJRVJVTkcgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIworCisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfbG9jYWxjbWRzKCkKK3sKKyAgcmV0dXJuICh7KHsiY2xvbmUiLCJfY2xvbmUiLDAsV0laQVJEX0xWTH0pLAorICAgICAgICAgICAoeyJzZXRjbXNnIiwiX3NldGNtc2ciLDAsV0laQVJEX0xWTH0pLAorICAgICAgICAgICAoeyJzZXRkbXNnIiwiX3NldGRtc2ciLDAsV0laQVJEX0xWTH0pLAorICAgICAgICAgICAoeyJkZXN0cnVjdCIsIl9kZXN0cnVjdCIsMCxXSVpBUkRfTFZMfSksCisgICAgICAgICAgfSk7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgQ0xPTkUgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIworCitzdGF0aWMgaW50IF9jbG9uZShzdHJpbmcgY21kbGluZSkKK3sKKyAgbWl4ZWQgKnRtcDsKKyAgaW50IGZsYWdzOworICBvYmplY3Qgb2I7CisgIHN0cmluZyAqYXJncywqYXJnczIsZXJyOworICAKKyAgY21kbGluZT1fdW5wYXJzZWRfYXJncygpOworICBhcmdzPXBhcnNlYXJncyhjbWRsaW5lLCZmbGFncyxDTE9ORV9PUFRTLDEpOworICBpZiAoZmxhZ3M9PS0xfHxzaXplb2YoYXJncykhPTEpCisgICAgcmV0dXJuIFVTQUdFKCJjbG9uZSBbLSIgQ0xPTkVfT1BUUyAiXSA8b2JqZWt0bmFtZT4iKTsKKyAgaWYgKGZsYWdzJkNMT05FX0YpCisgICAgY21kbGluZT1hcmdzWzBdOworICBlbHNlCisgIHsKKyAgICAvLyBldHdhcyB1bXN0YWVuZGxpY2gsIGFiZXIgc28ga2FubiBtYW4gYXVjaCBEYXRlaWVuIGNsb25lbiwKKyAgICAvLyB3ZW5uIG1hbiBrZWluZSBMZXNlcmVjaHRlIGhhdC4gTWFuIG11c3MgYWJlciBpbSBWZXJ6ZWljaG5pcworICAgIC8vIGxlc2VuIGtvZW5uZW4KKyAgICBhcmdzMj1leHBsb2RlKGFyZ3NbMF0sIi8iKTsKKyAgICBpZiAoYXJnczJbPDFdWzwxXT09Jy4nKSBhcmdzMls8MV0rPSJjIjsKKyAgICBlbHNlIGlmIChhcmdzMls8MV1bPDIuLjwxXSE9Ii5jIikgYXJnczJbPDFdKz0iLmMiOworICAgIHRtcD1maWxlX2xpc3QoKHtpbXBsb2RlKGFyZ3MyWzAuLjwyXSwiLyIpKyIvKiJ9KSxNT0RFX0NMT05FLDAsIiIsCisgICAgICAgICAgICAgICAgICBhcmdzMls8MV0pOworICAgIGlmICghc2l6ZW9mKHRtcCl8fHRtcFswXVtGSUxFU0laRV08MCkKKyAgICAgIHJldHVybiBwcmludGYoImNsb25lOiAlczogRGF0ZWkgZXhpc3RpZXJ0IG5pY2h0LlxuIixhcmdzWzBdKSwxOworICAgIGNtZGxpbmU9dG1wWzBdW0ZVTExOQU1FXTsKKyAgfQorCisgIGlmIChlcnI9Y2F0Y2gob2I9Y2xvbmVfb2JqZWN0KGNtZGxpbmUpKXx8IW9iKQorICAgIHJldHVybiBwcmludGYoImNsb25lOiAlczogT2JqZWt0IGtvbm50ZSBuaWNodCBlcnpldWd0IHdlcmRlbi5cbiIKKyAgICAgICAgICAgICAgICAgICJHcnVuZDogJU8iLAorICAgICAgICAgICAgICAgICAgYXJnc1swXSxlcnJ8fCJ1bmJla2FubnQiKSwxOworICBpZiAoIW9iamVjdHAob2IpKQorICAgIHJldHVybiBwcmludGYoImNsb25lOiAlczogT2JqZWt0IGJlaW0gRXJ6ZXVnZW4gemVyc3RvZXJ0LlxuIiwKKyAgICAgICAgICAgICAgICAgIGFyZ3NbMF0pLDE7CisgIGlmICgob2ItPm1vdmUodGhpc19vYmplY3QoKSxNX0dFVCk+MCkgfHwgCisgICAgICAoIW9iamVjdHAob2IpfHxvYi0+bW92ZShlbnZpcm9ubWVudCgpLE1fTk9DSEVDSyk+MCl8fCFvYmplY3RwKG9iKSkKKyAgeworICAgIGlmICghb2JqZWN0cChvYikpCisgICAgICByZXR1cm4gcHJpbnRmKCJjbG9uZTogJXM6IE9iamVrdCBiZWltIEVyemV1Z2VuIHplcnN0b2VydC5cbiIsCisgICAgICAgICAgICAgICAgICBhcmdzWzBdKSwxOworICAgIHByaW50ZigiQ2xvbmU6ICVzIGVyemV1Z3QuXG4iLG9iamVjdF9uYW1lKG9iKSk7CisgICAgdGVsbF9yb29tKGVudmlyb25tZW50KHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgICAgICBzcHJpbnRmKCIlcyAlcy5cbiIsTmFtZShXRVIsMSksUXVlcnlQcm9wKFBfQ0xPTkVfTVNHKSksCisgICAgICAgICAgICAgICAgICAgICAgKHsgdGhpc19vYmplY3QoKX0pKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgICBzcHJpbnRmKCIlcyBtYWx0IHdpbGRlIFplaWNoZW4gaW4gZGllIEx1ZnQgdW5kICIKKyAgICAgICAgICAgICAgICAgICAgIm11cm1lbHQgdm9yIHNpY2ggaGluLCBhYmVyIG5pY2h0cyAiCisgICAgICAgICAgICAgICAgICAgICJwYXNzaWVydC4uLlxuIixOYW1lKFdFUiwxKSksCisgICAgICAgICAgICAoeyB0aGlzX29iamVjdCgpfSkpOworICBkZXN0cnVjdChvYik7CisgIHByaW50ZigiQ2xvbmU6ICVzOiBPYmpla3Qga29ubnRlIG5pY2h0IGJld2VndCB3ZXJkZW4uIixhcmdzWzBdKTsKKyAgcmV0dXJuIDE7Cit9CisKKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIERFU1RSVUNUICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjCisKKy8vCisvLyBfZGVzdHJ1Y3Q6IE9iamVrdGUgemVyc3RvZXJlbgorLy8KKworc3RhdGljIGludCBfZGVzdHJ1Y3Qoc3RyaW5nIGNtZGxpbmUpCit7CisgIGludCBmbGFnczsKKyAgbWl4ZWQgKmFyZ3M7CisgIG9iamVjdCBvYjsKKworICBpZiAoIXNpemVvZihjbWRsaW5lPV91bnBhcnNlZF9hcmdzKCkpKQorICAgIHJldHVybiBVU0FHRShxdWVyeV92ZXJiKCkrIiA8b2JqZWt0bmFtZT4iKTsKKyAgYXJncz1maW5kX29icyhsb3dlcl9jYXNlKGNtZGxpbmUpLFBVVF9HRVRfTk9ORSk7CisgIGlmICghYXJnc3x8IXNpemVvZihhcmdzKSkKKyAgeworICAgIGlmICghKG9iPWZpbmRfb2JqZWN0KGNtZGxpbmUpKSkKKyAgICB7CisgICAgICBub3RpZnlfZmFpbChxdWVyeV92ZXJiKCkrIjogT2JqZWt0IFwiIiArY21kbGluZSsKKyAgICAgICAgICAgICAgICAgICJcIiBuaWNodCBnZWZ1bmRlbi5cbiIpOworICAgICAgcmV0dXJuIDA7CisgICAgfQorICB9CisgIGVsc2UKKyAgICBvYj1hcmdzWzBdOworICBjbWRsaW5lPWNhcGl0YWxpemUodG9fc3RyaW5nKG9iLT5uYW1lKFdFUikpKTsKKyAgZmxhZ3M9KGludClvYi0+UXVlcnlQcm9wKFBfUExVUkFMKTsgLy8gTWlzc2JyYXVjaCB2b24gZmxhZ3MgOm8pCisgIGlmIChxdWVyeV92ZXJiKCk9PSJkZXN0cnVjdCIpCisgIHsKKyAgICBpZiAoIW9iLT5yZW1vdmUoKSkKKyAgICB7CisgICAgICBub3RpZnlfZmFpbChjbWRsaW5lKyIgd2lsbCBuaWNodCB6ZXJzdG9lcnQgd2VyZGVuIVxuIik7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgIH0KKyAgZWxzZSBkZXN0cnVjdChvYik7CisgIGlmICghb2IpCisgIHsKKyAgICBpZiAoIVF1ZXJ5UHJvcChQX0lOVklTKSkKKyAgICB7CisgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQodGhpc19vYmplY3QoKSksCisgICAgICAgICAgICAgICAgc3ByaW50ZigiJXMgJXMuXG4iLGNtZGxpbmUsUXVlcnlQcm9wKFBfREVTVFJVQ1RfTVNHKSksCisgICAgICAgICAgICAgICAgKHsgdGhpc19vYmplY3QoKSB9KSk7CisgICAgfQorICAgIHByaW50ZigiJXMgdyVzIHZvbiBEaXIgemVyc3RhZXVidC5cbiIsY21kbGluZSwoZmxhZ3M/ImVyZGVuIjoiaXJkIikpOworICB9CisgIGVsc2UKKyAgICBwcmludGYoIiVzIGthbm4gbmljaHQgemVyc3RvZXJ0IHdlcmRlbi5cbiIsY21kbGluZSk7CisgIHJldHVybiAxOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgU2V0Q01zZywgU2V0RE1zZyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjCisKK3N0YXRpYyBpbnQgX3NldGNtc2coc3RyaW5nIHN0cikKK3sKKyAgcHJpbnRmKCJCZWltIENsb25lbiB2b24gT2JqZWt0ZW4gc2VoZW4gZGllIEFuZGVyZW4gbnVuOlxuIgorICAgICAgICAgIjxEZWluIE5hbWU+ICVzLlxuIiwKKyAgICAgICAgIChTZXRQcm9wKFBfQ0xPTkVfTVNHLCBfdW5wYXJzZWRfYXJncygpfHwiemF1YmVydCBldHdhcyBhdXMgIgorICAgICAgICAgICsgUXVlcnlQb3NzUHJvbm91bihNQUxFLFdFTSkgKyAiIEFlcm1lbCBoZXJ2b3IiKSkpOworICByZXR1cm4gMTsKK30KKworc3RhdGljIGludCBfc2V0ZG1zZyhzdHJpbmcgc3RyKQoreworICBwcmludGYoIkJlaW0gWmVyc3RvZXJlbiB2b24gT2JqZWt0ZW4gc2VoZW4gZGllIEFuZGVyZW4gbnVuOlxuIgorICAgICAgICAgIjxPYmpla3Q+ICVzLlxuIiwKKyAgICAgICAgIFNldFByb3AoUF9ERVNUUlVDVF9NU0csIF91bnBhcnNlZF9hcmdzKCl8fCJ3aXJkIHZvbiAiICsgbmFtZShXRVIsMSkKKyAgICAgICAgICArICIgemVyc3RhZXVidCIpKTsKKyAgcmV0dXJuIDE7Cit9CmRpZmYgLS1naXQgYS9zdGQvc2hlbGxzL21hZ2llci9wYXJzaW5nLmMgYi9zdGQvc2hlbGxzL21hZ2llci9wYXJzaW5nLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTU1MzMyZAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvbWFnaWVyL3BhcnNpbmcuYwpAQCAtMCwwICsxLDM3MCBAQAorLy8gJElkOiBwYXJzaW5nLmMgOTE0MiAyMDE1LTAyLTA0IDIyOjE3OjI5WiBaZXNzdHJhICQKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKy8vI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjaW5jbHVkZSA8ZmlsZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxsb2dnaW5nLmg+CisjaW5jbHVkZSA8cmVnZXhwLmg+CisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPG1hZ2llci5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxwbGF5ZXIuaD4KKworLy8KKy8vIGdsb2IycmVnZXhwOiBBcmd1bWVudCB2b24gZ2xvYiBpbiBSZWdleHAgdW13YW5kZWxuCisvLyBzdHI6IEFyZ3VtZW50IChhbHMgUmVmZXJlbnopCisvLworCitzdGF0aWMgc3RyaW5nIGdsb2IycmVnZXhwKHN0cmluZyBzdHIpCit7CisgIHN0cj1yZWdyZXBsYWNlKHN0ciwiKFtcXC5cXF5cXCRcXFtcXF1cXChcXCldKSIsIlxcXFxcXDEiLFJFX1RSQURJVElPTkFMfDEpOworICBzdHI9cmVncmVwbGFjZShzdHIsIlxcKiIsIi4qIixSRV9UUkFESVRJT05BTHwxKTsKKyAgcmV0dXJuIHNwcmludGYoIl4lcyQiLHJlZ3JlcGxhY2Uoc3RyLCI/IiwiLiIsUkVfVFJBRElUSU9OQUx8MSkpOworfQorCisvLworLy8gdG9fZmlsZW5hbWU6IEFyZ3VtZW50IGluIERhdGVpbmFtZW4gdW13YW5kZWxuCisvLyBzdHI6ICBBcmd1bWVudAorLy8gUnVlY2tnYWJlOiBEYXRlaW5hbWUKKy8vCisKK3N0YXRpYyBtaXhlZCB0b19maWxlbmFtZShzdHJpbmcgc3RyKQoreworICBzdHJpbmcgKnRtcCxwLG5ld2ZuOworICBpbnQgaTsKKy8vIFRlc3RlbiBvYiAuLiBpbiBlaW5lbSBGaWxlbmFtZW5hYnNjaG5pdHQsIGZhbGxzIFZlcnNpb24gPDMuMi41CisgIHRtcD1leHBsb2RlKHN0ciwiLyIpOworLy8gVGVzdGVuIGF1ZiBQZmFkdmFyaWFibGUKKyAgaWYgKHNpemVvZih0bXBbMF0pICYmIHRtcFswXVswXT09JyQnIAorICAgICAgJiYgbV9jb250YWlucygmcCxRdWVyeVByb3AoUF9WQVJJQUJMRVMpLHRtcFswXVsxLi5dKSkKKyAgICB0bXBbMF09cDsKKy8vIFBmYWQgYWJzb2x1dCBtYWNoZW4gKEhhdCBkYW5hY2ggbm9jaCBXaWxkY2FyZHMgZHJpbm5lbikgb2RlciBhdWNoIG5pY2h0CisgIHJldHVybiBtYXN0ZXIoKS0+bWFrZV9wYXRoX2Fic29sdXRlKGltcGxvZGUodG1wLCIvIikpOworfQorCisKKy8vCisvLyBfcGFyc2VhcmdzKCk6IEtvbW1hbmRvemVpbGVuYWJzY2huaXR0IHBhcnNlbgorLy8gc3RyOiAgICAgICAgIEtvbW1hbmRvemVpbGVuYWJzY2huaXR0CisvLyBsaW5lOiAgICAgICAgQXJyYXkgdm9uIGdlcGFyc3RlbiBLb21tYW5kb3plaWxlbmFic2Nobml0dGVuIChSZWZlcmVueikKKy8vIGZsYWdzOiAgICAgICBBbHMgUmVmZXJlbnogdWViZXJnZWJlbmVyIEZsYWctV2VydAorLy8gb3B0czogICAgICAgIEVybGF1YnRlIEZsYWdzCisvLyBidWlsZF9mbjogICAgRmlsZW5hbWVuIGFlbmRlcm4KKy8vCisKK3ByaXZhdGUgdm9pZCBfcGFyc2VhcmdzKHN0cmluZyBzdHIsIHN0cmluZyAqbGluZSxpbnQgZmxhZ3Msc3RyaW5nIG9wdHMsCisgICAgICAgICAgICAgICAgICAgICBpbnQgYnVpbGRfZm4gKQoreworCisvLyBTdHJpbmdzIGluICIiIGVyaGFsdGVuCisgIGlmKHN0clswXSA9PSAiXCIiWzBdKSAgCisgIHsgCisgICAgbGluZSArPSAoeyBzdHJbMS4uPDJdIH0pOworICAgIHJldHVybjsgCisgIH0gIAorLy8gIEZsYWdzIHBhcnNlbgorICBpZihzdHJbMF0gPT0gJy0nKSAgCisgIHsgCisgICAgaW50IGksajsKKyAgICBpPXNpemVvZihzdHIpOworICAgIHdoaWxlKGktLSkKKyAgICAgIGlmIChzdHJbaV0hPSctJykKKyAgICAgIHsKKyAgICAgICAgaWYoKGogPSBtZW1iZXIob3B0cywgc3RyW2ldKSkgIT0gLTEpCisgICAgICAgICAgZmxhZ3MgfD0gKDEgPDwgaik7CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgIGZsYWdzPS0xOworICAgICAgICAgIHByaW50ZigiRGFzIEZsYWcgJy0lYycgd2lyZCB2b24gZGVtIEJlZmVobCAnJXMnIG5pY2h0ICIKKyAgICAgICAgICAgICAgICAgInVudGVyc3R1ZXR6dC5cbiIsc3RyW2ldLHF1ZXJ5X3ZlcmIoKXx8IiIpOworICAgICAgICB9CisgICAgICB9CisgICAgcmV0dXJuOworICB9CisgIGlmIChidWlsZF9mbikKKyAgeworICAgIGlmIChzdHI9KHN0cmluZyl0b19maWxlbmFtZShzdHIpKSBsaW5lKz0oeyBzdHIgfSk7CisgIH0gCisgIGVsc2UKKyAgICBsaW5lKz0gKHsgc3RyIH0pOworfQorCisKKy8vCisvLyBwYXJzZWFyZ3MoKSAtIHplcmxlZ3QgS29tbWFuZG96ZWlsZSBpbiBlaW4gQXJyYXk6CisvLyBjbWRsaW5lOiAgICAgS29tbWFuZG96ZWlsZQorLy8gZmxhZ3M6ICAgICAgIEFscyBSZWZlcmVueiB1ZWJlcmdlYmVuZXIgbGVlcmVyIEludGVnZXJ3ZXJ0LiBFbnRoYWVsdCBkYW5hY2gKKy8vICAgICAgICAgICAgICBkaWUgRmxhZ3MKKy8vIG9wdHM6ICAgICAgICBTdHJpbmcgbWl0IGVybGF1YnRlbiBPcHRpb25lbgorLy8gYnVpbGRfZm46ICAgIEZpbGVuYW1lbiB1bWJhdWVuPworLy8gUnVlY2tnYWJlOiBBcnJheSBkZXIgS29tbWFuZG96ZWlsZW5hcmd1bWVudGUgKGF1c3NlciBGbGFncykKKy8vCisKK3N0YXRpYyBzdHJpbmcgKnBhcnNlYXJncyhzdHJpbmcgY21kbGluZSxpbnQgZmxhZ3MsIHN0cmluZyBvcHRzLGludCBidWlsZF9mbikKK3sKKyAgaW50IGk7CisgIHN0cmluZyAqbGluZTsKKyAgbGluZT0oe30pOworICBpZiAoIXNpemVvZihjbWRsaW5lKSkgcmV0dXJuICh7fSk7CisgIG1hcChyZWdleHBsb2RlKGNtZGxpbmUsIltcIl1bXlwiXSpbXCJdfCAiLCBSRV9UUkFESVRJT05BTCktKHsiICIsICIifSksCisgICAgICAgICAgICAjJ19wYXJzZWFyZ3MsICZsaW5lLCAmZmxhZ3Msb3B0cywgYnVpbGRfZm4pOworICByZXR1cm4gbGluZSAtICh7IiJ9KTsKK30KKworLy8KKy8vIF92Y19tYXA6IFZDLU9iamVrdG5hbWVuIHp1IEFycmF5cyB1bXdhbmRlbG4gKHsgbmFtZSwgLTEsIHByb2dyYW1fdGltZSgpIH0pCisvLworCitwcml2YXRlIGludCAqX3ZjX21hcChvYmplY3Qgb2IsbWl4ZWQgKmxpc3QpCit7CisgIGxpc3QrPSh7IGV4cGxvZGUob2JqZWN0X25hbWUob2IpLCIvIilbPDFdLC0xLHByb2dyYW1fdGltZShvYikgfSk7CisgIHJldHVybiAwOworfQorCisKKy8vCisvLyBfZ2V0X2ZpbGVzOiBGaWxlZGF0ZW4gYmVpbSBSZWt1cnNpdmVuIGtvcGllcmVuIGVyc3RlbGxlbgorLy8gZGlybmFtZTogICAgQmVhcmJlaXRldGVzIFZlcnplaWNobmlzCisvLyBtYXNrOiAgICAgICBNYXNrZSwgZGVyIERhdGVpbmFtZW4gZ2VudWVnZW4gbXVlc3NlbgorLy8gbW9kZTogICAgICAgV2VsY2hlIERhdGVuIHdlcmRlbiBiZW5vZXRpZ3Q/IChzaWVoZSBtYWdpZXIuaCkKKy8vIGRlc3Q6ICAgICAgIEluIHdlbGNoZXMgVmVyemVpY2huaXMgc29sbCBrb3BpZXJ0IHdlcmRlbj8KKy8vIFJ1ZWNrZ2FiZTogIEFsaXN0IG1pdCBkZW4gRGF0ZWlpbmZvcm1hdGlvbmVuCisvLworCitwcml2YXRlIHZhcmFyZ3MgbWl4ZWQgKl9nZXRfZmlsZXMoc3RyaW5nIGRpcm5hbWUsc3RyaW5nIG1hc2ssaW50IG1vZGUsc3RyaW5nIGRlc3QpCit7CisgIG1peGVkICpmaWxlcywqdG1wLCpkYXRhOworICBzdHJpbmcgZnVsbG5hbWUsYmFzZTsKKworICAvL0RFQlVHKCJfR0Y6IERJUk5BTUUgIiArIGRpcm5hbWUpOworICBkYXRhPWdldF9kaXIoZGlybmFtZSsiKiIsNyk7CisgIGlmKCFzaXplb2YoZGF0YSkpIHJldHVybiAoe30pOworICBmaWxlcz0oe30pOworIAorICB3aGlsZShzaXplb2YoZGF0YSkpCisgIHsKKyAgICB0bXA9KHt9KTsKKyAgICBiYXNlPWRhdGFbQkFTRU5BTUVdOworICAgIGZ1bGxuYW1lPWRpcm5hbWUrYmFzZTsKKyAgICBpZiAoYmFzZSE9Ii4iJiZiYXNlIT0iLi4iJiYoIShtb2RlPT1NT0RFX0dSRVAmJmJhc2U9PSJSQ1MiKSkmJgorICAgICAgICAoKGRhdGFbRklMRVNJWkVdPT0tMiYmCisgICAgICAgc2l6ZW9mKHRtcD1fZ2V0X2ZpbGVzKGZ1bGxuYW1lKyIvIixtYXNrLG1vZGUsCisgICAgICBkZXN0K2Jhc2UrIi8iKSkmJm1vZGUhPU1PREVfUk0pfHwhbWFza3x8c2l6ZW9mKHJlZ2V4cCgoeyBiYXNlIH0pLG1hc2ssIFJFX1RSQURJVElPTkFMKSkpKQorICAgIHsKKyAgICAgIC8vREVCVUcoIl9HRjogQURESU5HIEZJTEUgIiArIGZ1bGxuYW1lKTsKKyAgICAgIGZpbGVzKz0gKHsgZGF0YVswLi4yXSsoeyBmdWxsbmFtZSxkaXJuYW1lLGRlc3QrYmFzZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YodG1wKSB9KSB9KTsKKyAgICB9CisgICAgaWYgKHNpemVvZihmaWxlcykrc2l6ZW9mKHRtcCk+TUFYX0FSUkFZX1NJWkUpCisgICAgICAgcmFpc2VfZXJyb3IoIlp1IHZpZWxlIEZpbGVzICg+MzAwMCkhISBBYmdlYnJvY2hlbiFcbiIpOworICAgIGZpbGVzKz10bXA7CisgICAgZGF0YT1kYXRhWzMuLl07CisgIH0KKyAgCisgIGlmKHNpemVvZihmaWxlcyk+MzAwJiYhSVNfQVJDSCh0aGlzX29iamVjdCgpKSkKKyAgICAvLyBUb2QgYWxsZW4gTGFnZ2VybiA6bykKKyAgICByYWlzZV9lcnJvcigiWnUgdmllbGUgRmlsZXMgKD4zMDApISEgQWJnZWJyb2NoZW4hXG4iKTsKKyAgcmV0dXJuIGZpbGVzOworfQorIAorCisvLworLy8gX2dldF9tYXRjaGluZzogUmVrdXJzaXZlIEZ1bmt0aW9uIHp1bSBlcm1pdHRlbG4gZGVyIEZpbGVzLCB3ZW5uIG1pdCBNYXNrZQorLy8gICAgICAgICAgICAgICAgZ2VhcmJlaXRldCB3aXJkICh6LkIuIGNwIC1tIC9ibGEvKi8qIC96aWVsICouYykKKy8vIHBhdGhtYXNrOiBBcnJheSwgZGFzIGRpZSBlaW56ZWxuZW4gRWxlbWVudGUgZGVyIE1hc2tlIChBcmcxKSBlbnRoYWVsdAorLy8gICAgICAgICAgICAgICAgICAgKHBlciBlZnVuOm9sZF9leHBsb2RlKGFyZzEsIi8iKSkKKy8vIGRlcHRoOiAgICAgQWt0dWVsbGVzIEVsZW1lbnQgdm9uIHBhdGhtYXNrCisvLyBwYXRoOiAgICAgIGltcGxvZGUocGF0aG1hc2tbMC4uZGVwdGhdLCIvIik7CisvLyBtb2RlOiAgICAgIFdlbGNoZSBEYXRlbiB3ZXJkZW4gYmVub2V0aWd0PyAoc2llaGUgbWFnaWVyLmgpCisvLyBmbGFnczogICAgIFdlbGNoZSBGbGFncyB3dXJkZW4gZ2VzZXR6dD8KKy8vIGRlc3Q6ICAgICAgWmllbHZlcnplaWNobmlzIChiZWltIGtvcGllcmVuL21vdmVuKQorLy8gZmlsZW1hc2s6ICBNYXNrZSwgZGVyIGRpZSBGaWxlcyBnZW51ZWdlbiBtdWVzc2VuCisvLyBSdWVja2dhYmU6IEFsaXN0IG1pdCBkZW4gRGF0ZWlpbmZvcm1hdGlvbmVuCisvLworCitwcml2YXRlIG1peGVkICpfZ2V0X21hdGNoaW5nKHN0cmluZyAqcGF0aG1hc2ssIGludCBkZXB0aCwgc3RyaW5nIHBhdGgsIAorICAgICAgICAgICAgICAgICAgICBpbnQgbW9kZSwgaW50IHJlY3Vyc2l2ZSwgc3RyaW5nIGRlc3Qsc3RyaW5nIGZpbGVtYXNrKQoreworICBtaXhlZCAqZGF0YSwqdG1wLCpmaWxlczsKKyAgc3RyaW5nIGJhc2UsZnVsbDsKKworICAvL0RFQlVHKCJfR006IFBNOiAiICsgcGF0aG1hc2tbZGVwdGhdKTsKKyAgLy9ERUJVRygiX0dNOiBGTTogIiArIGZpbGVtYXNrKTsKKyAgZGF0YT1nZXRfZGlyKHBhdGgrcGF0aG1hc2tbZGVwdGgrK10sR0VURElSX05BTUVTfEdFVERJUl9TSVpFU3xHRVRESVJfREFURVMpfHwoe30pOworICBpZiAoIXNpemVvZihkYXRhKSkgcmV0dXJuICh7fSk7CisgIGZpbGVzPSh7fSk7CisgIHdoaWxlKHNpemVvZihkYXRhKSkKKyAgeworICAgIGlmICgoYmFzZT1kYXRhW0JBU0VOQU1FXSk9PSIuInx8YmFzZT09Ii4uIikKKyAgICB7CisgICAgICBkYXRhPWRhdGFbMy4uXTsKKyAgICAgIGNvbnRpbnVlOworICAgIH0KKyAgICBmdWxsPXBhdGgrYmFzZTsKKyAgICAvL0RFQlVHKCJfR006IEZVTEw6ICIgKyBmdWxsKTsKKyAgICBpZiAoKGRhdGFbRklMRVNJWkVdPT0tMikmJihzaXplb2YocGF0aG1hc2spPmRlcHRoKSYmCisgICAgICAgICghKG1vZGU9PU1PREVfR1JFUCYmYmFzZT09IlJDUyIpKSkKKyAgICB7CisgICAgICAvL0RFQlVHKCJERVNDRU5EIElOVE8gIiArIGZ1bGwpOworICAgICAgdG1wPV9nZXRfbWF0Y2hpbmcocGF0aG1hc2ssZGVwdGgsZnVsbCsiLyIsbW9kZSxyZWN1cnNpdmUsCisgICAgICAgICAgICAgICAgICAgICAgICAocmVjdXJzaXZlP2Rlc3QrYmFzZSsiLyI6ZGVzdCksZmlsZW1hc2spOworICAgIH0KKyAgICBlbHNlIHRtcD0oe30pOworICAgIC8vREVCVUcoIkRFUFRIOiAiICsgZGVwdGggKyAiIDogIiArIHNpemVvZihwYXRobWFzaykpOworICAgIGlmKCghZmlsZW1hc2smJihkZXB0aD09c2l6ZW9mKHBhdGhtYXNrKSkpfHwKKyAgICAgICAgKGZpbGVtYXNrJiYoZGVwdGgrMj5zaXplb2YocGF0aG1hc2spKSYmCisgICAgICAgIHNpemVvZihyZWdleHAoKHsgYmFzZSB9KSxmaWxlbWFzayxSRV9UUkFESVRJT05BTCkpKXx8CisgICAgICAgKChtb2RlPT1NT0RFX0NQfHxtb2RlPT1NT0RFX01WfHwoZmlsZW1hc2smJgorICAgICAgICAobW9kZT09TU9ERV9STSkmJnNpemVvZihyZWdleHAoKHsgYmFzZX0pLGZpbGVtYXNrLFJFX1RSQURJVElPTkFMKSkpKSYmCisgICAgICAgIHNpemVvZih0bXApKSkKKyAgICB7CisgICAgICAvL0RFQlVHKCJBRERJTkc6ICIgKyBiYXNlKyAiIDogIisgZnVsbCApOworICAgICAgZmlsZXMrPSh7IGRhdGFbMC4uMl0rKHsgZnVsbCwgcGF0aCwgZGVzdCtiYXNlLHNpemVvZih0bXApfSkgfSk7CisgICAgfQorICAgIGlmIChzaXplb2YoZmlsZXMpK3NpemVvZih0bXApPk1BWF9BUlJBWV9TSVpFKQorICAgICAgIHJhaXNlX2Vycm9yKCJadSB2aWVsZSBGaWxlcyAoPjMwMDApISEgQWJnZWJyb2NoZW4hXG4iKTsKKyAgICBmaWxlcys9dG1wOworICAgIGRhdGE9ZGF0YVszLi5dOworICB9CisgIGlmKHNpemVvZihmaWxlcyk+MzAwJiYhSVNfQVJDSCh0aGlzX29iamVjdCgpKSkKKyAgICAvLyBUb2QgYWxsZW4gTGFnZ2VybiEKKyAgICByYWlzZV9lcnJvcigiWnUgdmllbGUgRmlsZXMgKD4zMDApISEgQWJnZWJyb2NoZW4hXG4iKTsKKyAgcmV0dXJuIGZpbGVzOworfQorCisKKy8vCisvLyBnZXRfZmlsZXM6IEJhc2lzcm91dGluZSB6dW0gRXJtaXR0ZWxuIGRlciB6dSBiZWFyYmVpdGVuZGVuIERhdGVpZW4KKy8vIGZpbGVuYW1lOiAgUGZhZG1hc2tlLCBWZXJ6ZWljaG5pc25hbWUsIERhdGVpbmFtZSwgZGVyIGJlYXJiZWl0ZXQgd2VyZGVuCisvLyAgICAgICAgICAgIHNvbGwKKy8vIG1vZGU6ICAgICAgV2VsY2hlIERhdGVuIHdlcmRlbiBiZW5vZXRpZ3Q/IChzaWVoZSBtYWdpZXIuaCkKKy8vIHJlY3Vyc2l2ZTogQXVjaCBVbnRlcnZlcnplaWNobmlzc2UgYmVhcmJlaXRlbj8KKy8vIGRlc3Q6ICAgICAgV2VubiBrb3BpZXJ0IHdlcmRlbiBzb2xsOiB3b2hpbj8KKy8vIGZpbGVtYXNrOiAgTWFza2UsIGRlciBkaWUgRGF0ZWluYW1lbiBnZW51ZWdlbiBtdWVzc2VuCisvLyBSdWVja2dhYmU6IEFsaXN0IG1pdCBkZW4gRGF0ZWlpbmZvcm1hdGlvbmVuCisvLworCitzdGF0aWMgdmFyYXJncyBtaXhlZCAqZ2V0X2ZpbGVzKHN0cmluZyBmaWxlbmFtZSwgaW50IG1vZGUsIGludCByZWN1cnNpdmUsIHN0cmluZyBkZXN0LCBzdHJpbmcgZmlsZW1hc2spCit7IAorICBzdHJpbmcgZnVsbCxwYXRoLGJhc2UsKnBhdGhhcnJheSwqdnJvb21zLGRlc3QyOworICBvYmplY3QgdmNvbXBpbGVyOworICBtaXhlZCAqZmlsZXMsKmRhdGE7CisKKyAgLy8gREVCVUcoIkdGOiAiICsgZmlsZW5hbWUpOworICAvLyBERUJVRygiUkVDOiAiICsgcmVjdXJzaXZlICsgIiBNT0RFOiAiICsgbW9kZSk7CisgIC8vIGlmIChkZXN0WzwxLi48MV0hPSIvIikgREVCVUcoIkRFU1Q6ICIgKyBkZXN0KTsKKyAgaWYgKGZpbGVuYW1lPT0iLyIpCisgICAgeworICAgICAgc3dpdGNoIChtb2RlKQorICAgICAgeworICAgICAgICBjYXNlIE1PREVfTFNBOiByZXR1cm4gKHsoeyAiIiwgLTIsIDAsIiIsIiIsIiIsMCB9KX0pOworICAgICAgICBkZWZhdWx0OiBpZiAoIXJlY3Vyc2l2ZSkgcmV0dXJuICh7fSk7CisgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgfQorICAgIH0KKyAgcGF0aGFycmF5PWV4cGxvZGUoZmlsZW5hbWUsIi8iKTsKKyAgaWYoIXNpemVvZihkYXRhPWdldF9kaXIoZmlsZW5hbWUsNyl8fCh7fSkpJiYKKyAgICAgKG1vZGU9PU1PREVfVVBEfHxtb2RlPT1NT0RFX01PUkV8fG1vZGU9PU1PREVfRUQpKQorICAgIGRhdGE9Z2V0X2RpcihmaWxlbmFtZSsiLmMiLDcpfHwoe30pOworICBpZiAoKG1vZGU9PU1PREVfTFNBfHxtb2RlPT1NT0RFX0xTQikmJgorICAgICAgKHZjb21waWxlciA9IGZpbmRfb2JqZWN0KGltcGxvZGUocGF0aGFycmF5WzAuLjwyXSwiLyIpKyIvdmlydHVhbF9jb21waWxlciIpKSAmJgorICAgICAgcG9pbnRlcnAodnJvb21zPShtaXhlZCAqKXZjb21waWxlci0+UXVlcnlPYmplY3RzKCkpKQorICAgIG1hcCh2cm9vbXMsIydfdmNfbWFwLCZkYXRhKTsKKyAgZmlsZXM9KHt9KTsKKyAgaWYgKHNpemVvZihkYXRhKSkgLy8gcGFzc2VuZGUgZmlsZXMKKyAgeworICAgIG1peGVkICpzdWJmaWxlczsKKyAgICBzdWJmaWxlcz0oe30pOworICAgIHBhdGg9aW1wbG9kZShwYXRoYXJyYXlbMC4uPDJdLCIvIikrIi8iOworICAgIHdoaWxlIChzaXplb2YoZGF0YSkpCisgICAgeworICAgICAgc3ViZmlsZXM9KHt9KTsKKyAgICAgIGJhc2U9ZGF0YVtCQVNFTkFNRV07CisgICAgICBpZiAobW9kZT09TU9ERV9MU0J8fChiYXNlIT0iLiImJmJhc2UhPSIuLiIpKQorICAgICAgeworICAgICAgICAvL0RFQlVHKCJQQVRIOiAiICsgcGF0aCsiIEJBU0U6ICIgKyBiYXNlICsgIiBNT0RFOiAiICsgbW9kZSk7CisgICAgICAgIGZ1bGw9cGF0aCtiYXNlOworICAgICAgICBkZXN0Mj0oKGRlc3Q9PSIvInx8ZmlsZV9zaXplKGRlc3RbMC4uPDJdKT09LTIpPworICAgICAgICAgICAgICAgKGRlc3QrYmFzZSk6KGRlc3Q9PSIvIj8iLyI6ZGVzdFswLi48Ml0pKTsKKyAgICAgICAgLy9ERUJVRygiREVTVDogIiArIGRlc3QpOworICAgICAgICBpZiAocmVjdXJzaXZlJiZkYXRhW0ZJTEVTSVpFXT09LTIpIC8vIFZlcnplaWNobmlzLCBSZWt1cnNpdgorICAgICAgICAgIHN1YmZpbGVzPV9nZXRfZmlsZXMoZnVsbCsiLyIsZmlsZW1hc2ssbW9kZSxkZXN0MisiLyIpOworICAgICAgICBpZiAoIShmaWxlbWFzayYmIXNpemVvZihzdWJmaWxlcykmJiFzaXplb2YocmVnZXhwKCh7IGJhc2UgfSksZmlsZW1hc2ssUkVfVFJBRElUSU9OQUwpKSkpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoIWZpbGVtYXNrfHxtb2RlIT1NT0RFX1JNKQorICAgICAgICAgICAgZmlsZXMrPSh7IGRhdGFbMC4uMl0rKHsgZnVsbCwgcGF0aCwgZGVzdDIsc2l6ZW9mKHN1YmZpbGVzKX0pIH0pOworICAgICAgICAgIGlmIChzaXplb2YoZmlsZXMpK3NpemVvZihzdWJmaWxlcyk+TUFYX0FSUkFZX1NJWkUpCisgICAgICAgICAgICByYWlzZV9lcnJvcigiWnUgdmllbGUgRmlsZXMgKD4zMDAwKSEhIEFiZ2Vicm9jaGVuIVxuIik7CisgICAgICAgICAgZmlsZXMrPXN1YmZpbGVzOworICAgICAgICB9CisgICAgICB9CisgICAgICBkYXRhPWRhdGFbMy4uXTsKKyAgICB9CisgICAgcmV0dXJuIGZpbGVzOworICB9CisvLyBGaWxlIGV4aXN0aWVydCBuaWNodCAtPiBXaWxkY2FyZCBvZGVyIHRhdHNhZWNobGljaCBuaWNodCBleGlzdGVudAorLy8gQmVoYW5kZWxuIGplIG5hY2ggbW9kZQorICBzd2l0Y2gobW9kZSkKKyAgeworICAgIGNhc2UgTU9ERV9DUDoKKyAgICBjYXNlIE1PREVfTVY6CisgICAgY2FzZSBNT0RFX0NEOgorICAgIGNhc2UgTU9ERV9MU0E6CisgICAgICBmaWxlcz1fZ2V0X21hdGNoaW5nKHBhdGhhcnJheSsoZmlsZW1hc2s/KHsgIioiIH0pOih7fSkpLDEsIi8iLG1vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICByZWN1cnNpdmUsZGVzdCxmaWxlbWFzayk7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OiBicmVhazsgCisgIH0KKyAgcmV0dXJuIGZpbGVzOworfQorCisKKy8vCisvLyBmaWxlX2xpc3QoKTogTGlzdGUgZGVyIEZpbGVpbmZvcm1hdGlvbmVuCisvLyBmaWxlczogICAgIEFycmF5IGRlciBGaWxlbmFtZW4gTUlUIFdpbGRjYXJkcworLy8gbW9kZTogICAgICBXZWxjaGUgRGF0ZW4gd2VyZGVuIGJlbm9ldGlndAorLy8gcmVjdXJzaXZlOiBSZWt1cnNpdiBsaXN0ZW4/CisvLyBkZXN0OiAgICAgIFppZWx2ZXJ6ZWljaG5pcworLy8gbWFzazogICAgICBNYXNrZSAocmVnZXhwLCB3ZW5uIGRlZmluaWVydCkKKy8vIFJ1ZWNrZ2FiZTogTGlzdGUgZGVyIGJldHJvZmZlbmVuIEZpbGVzCisvLworCitzdGF0aWMgdmFyYXJncyBtaXhlZCAqZmlsZV9saXN0KHN0cmluZyAqZmlsZXMsIGludCBtb2RlLCBpbnQgcmVjdXJzaXZlLCBzdHJpbmcgZGVzdCwgc3RyaW5nIG1hc2spCit7CisgIHN0cmluZyAqbGlzdCxlcnIsKnJlc3VsdDsKKyAgaW50IGksajsKKyAgbGlzdD0oe30pOworICBpZiAobWFzaykgbWFzaz1nbG9iMnJlZ2V4cChtYXNrKTsKKyAgaj1zaXplb2YoZmlsZXMpOworICBmb3IoaT0wO2k8ajtpKyspCisgIHsKKyAgICAvLyBBYnNjaGxpZXNzZW5kZW4gLyB2b24gUGZhZG5hbWVuIGFic2NobmVpZGVuLCB3ZWlsIGluIGRpZXNlbSBGYWxsIAorICAgIC8vIGRpZSBJbmhhbHRlIGRlciBlcnN0ZW4gVW50ZXJ2ZXJ6ZWljaG5pc2ViZW5lIG1pdCBhdXNnZWdlYmVuCisgICAgLy8gd3VyZGVuLiBVcnNhY2hlIGhpZXJmdWVyIGlzdCBlaW4gRml4IGFuIGZ1bGxfcGF0aF9hcnJheSgpIGltIAorICAgIC8vIE1hc3Rlcm9iamVrdCwgZGVyIGRhenUgZnVlaHJ0ZSwgZGFzcyBnZXRfZGlyKCkgZGVuIGFic2NobGllc3NlbmRlbiAvCisgICAgLy8gZGVzIHVlYmVyZ2ViZW5lbiBQZmFkZXMgamV0enQga29ycmVrdCBiZWhhbmRlbHQuIFxvLworICAgIGlmICggc2l6ZW9mKGZpbGVzW2ldKSA+IDEgJiYgZmlsZXNbaV1bPDFdID09ICcvJyApCisgICAgeworICAgICAgZmlsZXNbaV0gPSBmaWxlc1tpXVswLi48Ml07CisgICAgICBpZiAoICFzaXplb2YoZmlsZXNbaV0pICkKKyAgICAgICAgY29udGludWU7CisgICAgfQorICAgIGlmIChlcnI9Y2F0Y2gobGlzdCs9Z2V0X2ZpbGVzKGZpbGVzW2ldLG1vZGUscmVjdXJzaXZlLGRlc3QsbWFzaykpKQorICAgIHsKKyAgICAgIHByaW50ZigiRmVobGVyIGF1ZmdldHJldGVuOiAlc1xuIixlcnIpOworICAgICAgbG9nX2ZpbGUoU0hFTExMT0coIkZJTEVfTElTVCIpLAorICAgICAgICAgICAgICAgc3ByaW50ZigiJXMgZnVlaHJ0ZSBmb2xnZW5kZXMgS29tbWFuZG8gYXVzOiAoWmVpdDogJXMpXG4iCisgICAgICAgICAgICAgICAgICAgICAgICIgID4+JXMgJXM8PFxuIgorICAgICAgICAgICAgICAgICAgICAgICAiICBGb2xnZW5kZXIgRmVobGVyIHRyYXQgZGFiZWkgYXVmOlxuIgorICAgICAgICAgICAgICAgICAgICAgICAiICAlc1xuXG4iLAorICAgICAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKGdldHVpZCgpKXx8IjxVbmJla2FubnQ+IixkdGltZSh0aW1lKCkpLAorICAgICAgICAgICAgICAgICAgICAgICBxdWVyeV92ZXJiKCl8fCIqIixfdW5wYXJzZWRfYXJncygpfHwiKiIsZXJyfHwiKiIpKTsKKyAgICAgIHJldHVybiAoe30pOworICAgIH0KKyAgfQorICAgcmV0dXJuIGxpc3Q7Cit9CmRpZmYgLS1naXQgYS9zdGQvc2hlbGxzL21hZ2llci9wbGF5ZXJzLmMgYi9zdGQvc2hlbGxzL21hZ2llci9wbGF5ZXJzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzU2M2Q5ZAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvbWFnaWVyL3BsYXllcnMuYwpAQCAtMCwwICsxLDUyOSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHBsYXllcnMuYworLy8KKy8vICRJZDogcGxheWVycy5jIDk1NTEgMjAxNi0wNC0yMCAyMjo1NDo1OFogQXJhdGhvcm4gJAorI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisjaW5jbHVkZSA8YW5zaS5oPgorI2luY2x1ZGUgPGxvZ2dpbmcuaD4KKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8bWFnaWVyLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8bGl2aW5nL2NvbW0uaD4KKyNpbmNsdWRlIDxwbGF5ZXIuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfbG9jYWxjbWRzKCkKK3sKKyAgcmV0dXJuICh7KHsiemFwIiwiX3phcCIsMCxXSVpBUkRfTFZMfSksCisgICAgICAgICAgICh7InZlcmZvbGdlIiwiX3ZlcmZvbGdlIiwwLExFQVJORVJfTFZMfSksCisgICAgICAgICAgICh7InRyYW5zIiwiX3RyYW5zIiwwLExFQVJORVJfTFZMfSksCisgICAgICAgICAgICh7InBlYWNlIiwiX2ZyaWVkZW4iLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAgICAgICAgKHsiZnJpZWRlbiIsIl9mcmllZGVuIiwwLExFQVJORVJfTFZMfSksCisgICAgICAgICAgICh7InB3aG8iLCJfcHdobyIsMCxXSVpBUkRfTFZMfSksCisgICAgICAgICAgICh7Inp3aW5nZSIsIl96d2luZ2UiLDAsV0laQVJEX0xWTH0pLAorICAgICAgICAgICAoeyJoZWFsIiwiX2hlaWxlIiwwLFdJWkFSRF9MVkx9KSwKKyAgICAgICAgICAgKHsiaGVpbCIsIl9oZWlsZSIsMSxXSVpBUkRfTFZMfSksCisgICAgICAgICAgICh7InBlb3BsZSIsIl9wZW9wbGUiLDAsTEVBUk5FUl9MVkx9KSwKKyAgICAgICAgICAgKHsic3BpZWxlciIsIl9zcGllbGVyIiwwLFdJWkFSRF9MVkx9KX0pOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFpBUCAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjCisKK3ByaXZhdGUgc3RyaW5nIF96YXBfbWVzc2FnZShzdHJpbmcgc3RyLCBvYmplY3Qgb2JqKQoreworICBzdHI9cmVncmVwbGFjZShzdHIsIkBAd2VyQEAiLChzdHJpbmcpb2JqLT5uYW1lKFdFUiwyKSwxKTsKKyAgc3RyPXJlZ3JlcGxhY2Uoc3RyLCJAQHdlc3NlbkBAIiwoc3RyaW5nKW9iai0+bmFtZShXRVNTRU4sMiksMSk7CisgIHN0cj1yZWdyZXBsYWNlKHN0ciwiQEB3ZW1AQCIsKHN0cmluZylvYmotPm5hbWUoV0VNLDIpLDEpOworICBzdHI9cmVncmVwbGFjZShzdHIsIkBAd2VuQEAiLChzdHJpbmcpb2JqLT5uYW1lKFdFTiwyKSwxKTsKKyAgc3RyPXJlZ3JlcGxhY2Uoc3RyLCJAQGljaEBAIixuYW1lKFdFUiwyKSwxKTsKKyAgcmV0dXJuIGNhcGl0YWxpemUoc3RyKTsKK30KKworc3RhdGljIGludCBfemFwKHN0cmluZyBzdHIpCit7CisgICAgb2JqZWN0IG9wZmVyOworICAgIHN0cmluZyAqbWVzc2FnZSwgZHVtbXk7CisgICAgaW50IHNwaWVsZXI7CisKKyAgICBpZiAoIXN0cikgcmV0dXJuIFVTQUdFKCJ6YXAgPG5hbWU+Iik7CisgICAgaWYgKHNzY2FuZiggc3RyLCAic3BpZWxlciAlcyIsIGR1bW15ICkpCisgICAgeworICAgICAgc3RyID0gZHVtbXk7CisgICAgICBzcGllbGVyID0gMTsKKyAgICB9CisgICAgaWYgKG9wZmVyPXByZXNlbnQoc3RyLGVudmlyb25tZW50KCkpKQorICAgIHsKKyAgICAgIGlmICggIWxpdmluZyhvcGZlcikgKQorICAgICAgeworICAgICAgICBwcmludGYoIiVzIGlzdCBkb2NoIGdhciBrZWluIExlYmV3ZXNlbiFcbiIsY2FwaXRhbGl6ZShzdHIpICk7CisgICAgICAgIHJldHVybiAxOworICAgICAgfQorICAgICAgaWYgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob3BmZXIpJiYhc3BpZWxlciApCisgICAgICB7CisgICAgICAgIHByaW50ZiggIlNwaWVsZXIga2FubnN0IER1IG51ciBtaXQgZGVyIFN5bnRheCAnemFwIHNwaWVsZXIgPG5hbWU+JyAiCisgICAgICAgICAgICAgICAgInRvZXRlbiFcbiIgKTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICAgIGlmICggIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob3BmZXIpICYmIHNwaWVsZXIgKQorICAgICAgICB7CisgICAgICAgICAgcHJpbnRmKCAiQWJlciAlcyBpc3QgZG9jaCBnYXIga2VpbiBTcGllbGVyIVxuIixjYXBpdGFsaXplKHN0cikpOworICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisKKyAgICAgIG1lc3NhZ2UgPSBRdWVyeVByb3AoUF9aQVBfTVNHKTsKKworICAgICAgaWYgKCAhcG9pbnRlcnAobWVzc2FnZSkgfHwgc2l6ZW9mKG1lc3NhZ2UpICE9IDMgKXsKKyAgICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoKSxzcHJpbnRmKCIlcyBiZXNjaHdvZXJ0IGVpbmVuIEJsaXR6ICIKKyAgICAgICAgICAgICAgICAidm9tIEhpbW1lbC5cbiIsY2FwaXRhbGl6ZShnZXR1aWQoKSkpLCh7IHRoaXNfb2JqZWN0KCkgfSkpOworICAgICAgICAgIHByaW50ZigiRHUgdG9ldGVzdCAlcy5cbiIsb3BmZXItPm5hbWUoIFdFTiwyKSk7CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIHByaW50ZihfemFwX21lc3NhZ2UobWVzc2FnZVswXSxvcGZlcikpOworICAgICAgICB0ZWxsX3Jvb20oZW52aXJvbm1lbnQoKSxfemFwX21lc3NhZ2UobWVzc2FnZVsxXSxvcGZlciksCisgICAgICAgICAgICAgKHt0aGlzX3BsYXllcigpLG9wZmVyfSkpOworICAgICAgICB0ZWxsX29iamVjdChvcGZlcixfemFwX21lc3NhZ2UobWVzc2FnZVsyXSxvcGZlcikpOworICAgICAgfQorCisgICAgICBvcGZlci0+ZGllKCk7CisgICAgICByZXR1cm4gMTsKKyAgfQorICBlbHNleworICAgICAgcHJpbnRmKCJTb3dhcyBzaWVoc3QgRHUgaGllciBuaWNodC5cbiIpOworICAgICAgcmV0dXJuIDE7CisgIH0KK30KKworCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBWRVJGT0xHRSAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIworCitzdGF0aWMgaW50IF92ZXJmb2xnZShzdHJpbmcgc3RyKQoreworICAvLyBXZW5uIG5pY2h0cyBlaW5nZWdlYmVuIHd1cmRlLCB3aXJkIHZlciBWZXJmb2xndW5nc21vZHVzIGJlZW5kZXQsIHNvZmVybgorICAvLyBlciB6dXZvciBlaW5nZXNjaGFsdGV0IHdhci4gQW5zb25zdGVuIHdpcmQgZWluZSBGZWhsZXJtZWxkdW5nIAorICAvLyBhdXNnZWdlYmVuLgorICBpZiAoIXNpemVvZihzdHIpKQorICB7CisgICAgbWl4ZWQgKnB1ciA9IFF1ZXJ5KFBfUFVSU1VFUlMpOworICAgIGlmICggcG9pbnRlcnAocHVyKSAmJiBzaXplb2YocHVyKSAmJiBvYmplY3RwKHB1clswXSkgKQorICAgIHsKKyAgICAgIHB1clswXS0+UmVtb3ZlUHVyc3Vlcih0aGlzX29iamVjdCgpKTsKKyAgICAgIFJlY2VpdmVNc2coIlZlcmZvbGd1bmdzbW9kdXMgYWJnZXNjaGFsdGV0LiIsIE1UX05PVElGSUNBVElPTik7CisgICAgfQorICAgIGVsc2UKKyAgICB7CisgICAgICBSZWNlaXZlTXNnKCJEdSB2ZXJmb2xnc3QgZG9jaCB1ZWJlcmhhdXB0IG5pZW1hbmRlbi4iLCBNVF9OT1RJRklDQVRJT04pOworICAgIH0KKyAgICByZXR1cm4gMTsKKyAgfQorICBzdHI9bG93ZXJfY2FzZShzdHIpOworICAKKyAgLy8gbWF0Y2hfbGl2aW5nKCkgZXJsYXVidCBkaWUgUHJ1ZWZ1bmcsIG9iIGRpZSBBbmdhYmUgZWluZGV1dGlnIHdhci4KKyAgaW50fHN0cmluZyBsdiA9IG1hdGNoX2xpdmluZyhzdHIpOworICBpZiAoIGludHAobHYpICkKKyAgeworICAgIGlmICggbHYgPT0gLTIgKQorICAgICAgUmVjZWl2ZU1zZygiS2VpbiBzb2xjaGVzIFdlc2VuIGdlZnVuZGVuLiIsIE1UX05PVElGSUNBVElPTik7CisgICAgZWxzZQorICAgICAgUmVjZWl2ZU1zZyhzcHJpbnRmKCJ2ZXJmb2xnZTogJyVzJyBpc3QgbmljaHQgZWluZGV1dGlnLlxuIiwgc3RyKSwKKyAgICAgICAgTVRfTk9USUZJQ0FUSU9OKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICAKKyAgLy8gU3BpZWxlciB6dWVyc3QgYXVzd2FlaGxlbiwgZGFuYWNoIGltIFJhdW0gYW53ZXNlbmRlIExlYmV3ZXNlbi4KKyAgb2JqZWN0IHppZWwgPSBmaW5kX3BsYXllcihsdikgfHwgcHJlc2VudChsdiwgZW52aXJvbm1lbnQodGhpc19wbGF5ZXIoKSkpOworICAKKyAgLy8gV3VyZGUga2VpbiBMZWJld2VzZW4gZ2VmdW5kZW4sIHdpcmQgZGFzIGVyc3RlIEVsZW1lbnQgYXVzIGRlciBMaXN0ZSBkZXIKKyAgLy8gTGViZXdlc2VuIGRpZXNlcyBOYW1lbnMgZ2V3YWVobHQsIGZhbGxzIHZvcmhhbmRlbi4gTnVyIExlYmV3ZXNlbiBtaXQKKyAgLy8gRW52aXJvbm1lbnQga29tbWVuIGluIEZyYWdlLCBkZW5uIHNvbnN0IGdpYnQgZXMga2VpbmVuIFJhdW0sIGluIGRlbiBkZXIKKyAgLy8gbmV1ZSBWZXJmb2xnZXIgYmV3ZWd0IHdlcmRlbiBrb2VubnRlLgorICBpZiAoICFvYmplY3RwKHppZWwpICkgeworICAgIG9iamVjdCogZWxpZ2libGVfbGl2aW5ncyA9IGZpbHRlcihmaW5kX2xpdmluZ3MobHYpLCAjJ2Vudmlyb25tZW50KTsKKyAgICBpZiAoc2l6ZW9mKGVsaWdpYmxlX2xpdmluZ3MpKQorICAgICAgemllbCA9IGVsaWdpYmxlX2xpdmluZ3NbMF07CisgIH0KKyAgCisgIC8vIEVuZGxpY2ggZXR3YXMgZ2VmdW5kZW4/IERhbm4gVmVyZm9sZ2VyIGVpbnRyYWdlbiB1bmQgenVtIFppZWwgYmV3ZWdlbi4KKyAgaWYgKCBvYmplY3RwKHppZWwpICkKKyAgeworICAgIGlmICggemllbCA9PSB0aGlzX3BsYXllcigpICkgCisgICAgeworICAgICAgUmVjZWl2ZU1zZygiRHUga2FubnN0IERpY2ggbmljaHQgc2VsYnN0IHZlcmZvbGdlbi4iLCBNVF9OT1RJRklDQVRJT04pOworICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgUmVjZWl2ZU1zZyhzcHJpbnRmKAorICAgICAgICAiRHUgdmVyZm9sZ3N0IGpldHp0ICVzLiBbJXNdIiwgemllbC0+bmFtZShXRU4pLCBvYmplY3RfbmFtZSh6aWVsKSksCisgICAgICAgIE1UX05PVElGSUNBVElPTiwgTUFfTU9WRSk7CisgICAgICB6aWVsLT5BZGRQdXJzdWVyKHRoaXNfb2JqZWN0KCkpOworICAgICAgemllbC0+VGFrZUZvbGxvd2VycygpOworICAgIH0KKyAgfQorICBlbHNlCisgIHsKKyAgICBSZWNlaXZlTXNnKCJLZWluIFdlc2VuIG1pdCBkZW0gTmFtZW4gJyIrbHYrIicgZ2VmdW5kZW4sIG9kZXIgbnVyICIKKyAgICAgICJzb2xjaGUgb2huZSBFbnZpcm9ubWVudC4iLCBNVF9OT1RJRklDQVRJT04sIDAsICJ2ZXJmb2xnZTogIik7CisgIH0KKyAgcmV0dXJuIDE7Cit9CisKKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBUUkFOUyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjCisKK3N0YXRpYyBpbnQgX3RyYW5zKHN0cmluZyBzdHIpCit7CisgIG9iamVjdCBsaXZpbmc7CisKKyAgaWYgKCFzaXplb2Yoc3RyKSkKKyAgICByZXR1cm4gX25vdGlmeV9mYWlsKCJTeW50YXg6IHRyYW5zIDxzcGllbGVybmFtZT5cbiIpLDA7CisgIHN0cj1tYXRjaF9saXZpbmcoc3RyLDApOworICBpZiAoaW50cChzdHIpKQorICAgIHN3aXRjaCAoc3RyKQorICAgIHsKKyAgICAgIGNhc2UgLTE6IHdyaXRlKCJEYXMgd2FyIG5pY2h0IGVpbmRldXRpZy5cbiIpOyByZXR1cm4gMTsKKyAgICAgIGNhc2UgLTI6IHdyaXRlKCJTbyBlaW4gV2VzZW4gZ2lidCBlcyBuaWNodC5cbiIpOyByZXR1cm4gMTsKKyAgICB9CisgIGlmKGxpdmluZz1maW5kX2xpdmluZyhzdHIpKQorICB7CisgICAgaWYgKGxpdmluZy0+bW92ZShvYmplY3RfbmFtZShlbnZpcm9ubWVudCgpKSwKKyAgICAgICAgICAgICAgICAgICAgIE1fVFBPUlR8TV9OT0NIRUNLKTw9MCkKKyAgICB7CisgICAgICBwcmludGYoIlRlbGVwb3J0aWVyZW4gdm9uICVzIGZlaGxnZXNjaGxhZ2VuLlxuIixsaXZpbmctPk5hbWUoV0VNKSk7CisgICAgICBpZiAoSVNfTEVBUk5FUihsaXZpbmcpKQorICAgICAgICB0ZWxsX29iamVjdChsaXZpbmcsc3ByaW50ZigiJXMgd29sbHRlIERpY2ggdGVsZXBvcnRpZXJlbiwgIgorICAgICAgICAgICAgICJoYXQgYWJlciB2ZXJzYWd0IVxuIixjYXBpdGFsaXplKGdldHVpZCgpKSkpOworICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIHRlbGxfb2JqZWN0KGxpdmluZyxzcHJpbnRmKAorICAgICJFaW4gc2VsdHNhbWVzIEdlZnVlaGwgdWViZXJrb21tdCBEaWNoIC4uLlxuIgorICAgICJEdSB2ZXJsaWVyc3QgZGllIE9yaWVudGllcnVuZyAuLi5cbiIKKyAgICArKFF1ZXJ5UHJvcChQX0lOVklTKT8iIjoiJXMgaG9sdCBEaWNoIHp1IHNpY2guXG4iKSwKKyAgICBjYXBpdGFsaXplKGdldHVpZCgpKSkpOworICAgIHByaW50ZigiJXMgd3VyZGUgaGVyYmVpeml0aWVydC5cbiIsbGl2aW5nLT5OYW1lKFdFUikpOworICAgIHJldHVybiAxOworICB9CisgIHByaW50ZigiRGFzIExlYmV3ZXNlbiAnJXMnIGtvbm50ZSBuaWNodCBnZWZ1bmRlbiB3ZXJkZW4uXG4iLAorICAgICAgICAgY2FwaXRhbGl6ZShzdHIpKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgRlJJRURFTiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIworCitzdGF0aWMgaW50IF9mcmllZGVuKHN0cmluZyBzbmFtZSkKK3sKKyAgb2JqZWN0ICplbmVtLG9iajsKKyAgaW50IGk7CisgIHN0cmluZyBoaW07CisgIAorICBpZiAoIXNuYW1lKQorICB7CisgICAgZW5lbT1hbGxfaW52ZW50b3J5KGVudmlyb25tZW50KCkpOworICAgIG1hcF9vYmplY3RzKGVuZW0sIlN0b3BIdW50aW5nTW9kZSIpOworICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCgpLHNwcmludGYoIiVzIHN0aWZ0ZXQgRnJpZWRlbi5cbiIsY2FwaXRhbGl6ZShnZXR1aWQoKSkpLAorICAgICAgICAgICAgICAoeyB0aGlzX29iamVjdCgpfSkpOworICAgIHByaW50ZigiRHUgc3RpZnRlc3QgRnJpZWRlbi5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIGVsc2UKKyAgeworICAgIGlmICghb2JqPWZpbmRfbGl2aW5nKHNuYW1lKSkKKyAgICAgIHJldHVybiBwcmludGYoIktlaW4gc29sY2hlcyBMZWJld2VzZW4gaW0gU3BpZWwuXG4iKSwxOworICAgIGhpbT0oc3RyaW5nKW9iai0+bmFtZShXRU0pOworICAgIGk9c2l6ZW9mKGVuZW09KG9iamVjdCAqKSgoKG1peGVkICopb2JqLT5TdG9wSHVudGluZ01vZGUoKSlbMF0pKTsKKyAgICAvLyBNaXN0ZHJpdmVyIC4uLiBvYmplY3QqKiB3YWVyZSByaWNodGlnIGdld2VzZW4gLi4uICpzZXVmeioKKyAgICB3aGlsZShpLS0pCisgICAgeworICAgICAgZW5lbVtpXS0+U3RvcEh1bnRGb3Iob2JqKTsKKyAgICAgIHRlbGxfb2JqZWN0KG9iaixzcHJpbnRmKCIlcyBiZWVuZGV0IERlaW5lbiBLYW1wZiBtaXQgJXMuXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShnZXR1aWQoKSksZW5lbVtpXS0+TmFtZShXRU0pKSk7CisgICAgICB0ZWxsX29iamVjdChlbmVtWzBdLHNwcmludGYoIiVzIGJlZW5kZXQgRGVpbmVuIEthbXBmIG1pdCAlcy5cbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShnZXR1aWQoKSksaGltKSk7CisgICAgfQorICB9CisgIHByaW50ZigiJXMgdW5kIGFsbGUgR2VnbmVyIHd1cmRlbiBiZWZyaWVkZXQuXG4iLG9iai0+TmFtZShXRVIpKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBQV0hPICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMKKworI2lmIF9fVkVSU0lPTl9fIDwgIjMuMi45IgorcHJpdmF0ZSBpbnQgX3B3aG9fbGVhcm5lcl90ZXN0KG9iamVjdCBvYikKK3sKKyAgcmV0dXJuICFJU19MRUFSTkVSKG9iKTsKK30KKyNlbmRpZgorCitzdGF0aWMgaW50IF9wd2hvKCkKK3sKKyAgbWl4ZWQqIHNwaWVsZXIsIHJlcywgKmhhbmRzOworICBpbnQgaTsKKyNpZiBfX1ZFUlNJT05fXyA8ICIzLjIuOSIKKyAgc3BpZWxlciA9IGZpbHRlcih1c2VycygpLCMnX3B3aG9fbGVhcm5lcl90ZXN0KTsKKyNlbHNlCisgIHNwaWVsZXIgPSBmaWx0ZXIodXNlcnMoKSwoOiByZXR1cm4gIUlTX0xFQVJORVIoJDEpOyA6KSk7CisjZW5kaWYKKyAgc3BpZWxlciA9IHNvcnRfYXJyYXkoc3BpZWxlciwgZnVuY3Rpb24gaW50IChvYmplY3QgYSwgb2JqZWN0IGIpCisgICAgICB7IHJldHVybiBhLT5RdWVyeVByb3AoUF9MRVZFTCkgPiBiLT5RdWVyeVByb3AoUF9MRVZFTCk7IH0gKTsKKyAgCisgIHJlcyA9ICJMdmwgTmFtZSAgICAgICAgIEVyZmFocnVuZyAgIFFQICBJbnQgU3RyIERleCBDb24gV0MgICAiCisgICAgIkFDICAgSEFORFMgSFAgIChtYXgpXG4iCisgICAgIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIgorICAgICItLS0tLS0tLS0tLS0tLS0tLVxuIjsKKyAgZm9yIChpPXNpemVvZihzcGllbGVyKS0xOyBpPj0wOyBpLS0pCisgICAgcmVzICs9IHNwcmludGYoIiUzZCAlLTEycyAlOWQgJTVkICUzZCAlM2QgJTNkICUzZCAlNGQgJTRkICAlNWQgIgorICAgICAgICAgICAgICAgICAgICIlNGQgKCU0ZClcbiIsCisgICAgIHNwaWVsZXJbaV0tPlF1ZXJ5UHJvcChQX0xFVkVMKSwKKyAgICAgY2FwaXRhbGl6ZShnZXR1aWQoc3BpZWxlcltpXSkpLAorICAgICBzcGllbGVyW2ldLT5RdWVyeVByb3AoUF9YUCksCisgICAgIHNwaWVsZXJbaV0tPlF1ZXJ5UHJvcChQX1FQKSwKKyAgICAgc3BpZWxlcltpXS0+UXVlcnlBdHRyaWJ1dGUoQV9JTlQpLAorICAgICBzcGllbGVyW2ldLT5RdWVyeUF0dHJpYnV0ZShBX1NUUiksCisgICAgIHNwaWVsZXJbaV0tPlF1ZXJ5QXR0cmlidXRlKEFfREVYKSwKKyAgICAgc3BpZWxlcltpXS0+UXVlcnlBdHRyaWJ1dGUoQV9DT04pLAorICAgICBzcGllbGVyW2ldLT5RdWVyeVByb3AoUF9UT1RBTF9XQyksCisgICAgIHNwaWVsZXJbaV0tPlF1ZXJ5UHJvcChQX1RPVEFMX0FDKSwKKyAgICAgKHNpemVvZihoYW5kcz0oKGludCAqKXNwaWVsZXJbaV0tPlF1ZXJ5UHJvcChQX0hBTkRTKSkpP2hhbmRzWzFdOjApLAorICAgICBzcGllbGVyW2ldLT5RdWVyeVByb3AoUF9IUCksCisgICAgIHNwaWVsZXJbaV0tPlF1ZXJ5UHJvcChQX01BWF9IUCkpOworICBNb3JlKHJlcyk7CisgIHJldHVybiAxOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgWldJTkdFICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMKKworc3RhdGljIGludCBfendpbmdlKHN0cmluZyBzdHIpCit7CisgIG9iamVjdCBsaXZpbmc7CisgIHN0cmluZyB3aGF0LCByZXN0OworICBzdHJpbmcgbGl2aW5nX25hbWU7CisKKyAgc3RyID0gX3VucGFyc2VkX2FyZ3MoKTsKKyAgaWYoIXN0cnx8IHNzY2FuZiggc3RyLCAiJXMgJXMiLCBsaXZpbmdfbmFtZSwgd2hhdCApICE9IDIgKQorICAgIHJldHVybiBfbm90aWZ5X2ZhaWwoIlp3aW5nZSBXRU4genUgV0FTP1xuIiksMDsKKyAgaWYoIHNzY2FuZiggd2hhdCwgInp1ICVzIiwgcmVzdCApID09IDEgKSB3aGF0ID0gcmVzdDsKKyAgaWYgKCEobGl2aW5nID0gZmluZF9saXZpbmcobGl2aW5nX25hbWUpKSkKKyAgICByZXR1cm4gcHJpbnRmICgiRWluIExlYmV3ZXNlbiBuYW1lbnMgJyVzJyBrb25udGUgbmljaHQgZ2VmdW5kZW4gd2VyZGVuIVxuIiwKKyAgICAgICAgICAgICAgICAgICBjYXBpdGFsaXplKGxpdmluZ19uYW1lKSksMTsKKyAgaWYgKGxpdmluZy0+Y29tbWFuZF9tZSh3aGF0KSkKKyAgeworICAgIHByaW50ZigiRHUgendpbmdzdCAlcyB6dSBcIiVzXCIuXG4iLGNhcGl0YWxpemUobGl2aW5nX25hbWUpLHdoYXQpOworICAgIGlmICghSVNfQVJDSCh0aGlzX29iamVjdCgpKSYmZ2V0dWlkKCkhPShzdHJpbmcpbGl2aW5nLT5RdWVyeVByb3AoUF9URVNUUExBWUVSKSkKKyAgICAgIGxvZ19maWxlKFNIRUxMTE9HKCJaV0lOR0UiKSwKKyAgICAgICAgICAgICAgIHNwcmludGYoIiVzIHp3aW5ndCAlcyAoJXMpIHp1ICVzIFslc11cbiIsCisgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKCkpLGxpdmluZy0+TmFtZSgpLGNhcGl0YWxpemUoZ2V0dWlkKGxpdmluZykpLAorICAgICAgICAgICAgICAgICAgICAgICB3aGF0LGR0aW1lKHRpbWUoKSkpKTsKKyAgfQorICBlbHNlCisgICAgd3JpdGUoIkhhdCBsZWlkZXIgbmljaHQgZ2VrbGFwcHQhXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgSEVJTEUgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIworCitzdGF0aWMgaW50IF9oZWlsZShzdHJpbmcgbmFtZSkKK3sKKyAgb2JqZWN0IG9iOworICBpbnQgbHB2LCBtcHY7CisKKyAgaWYgKCFuYW1lKSByZXR1cm4gVVNBR0UoImhlaWxlIDxuYW1lPiIpOworICBuYW1lID0gbG93ZXJfY2FzZShuYW1lKTsKKyAgaWYgKCghKG9iID0gcHJlc2VudChuYW1lLGVudmlyb25tZW50KCkpKSkKKyAgICAgIHx8IWxpdmluZyhvYikpCisgICAgb2IgPSBmaW5kX2xpdmluZyhuYW1lKTsKKyAgaWYgKCFvYikKKyAgeworICAgIHByaW50ZigiJyVzJyBpc3QgbW9tZW50YW4gbmljaHQgZGEuXG4iLGNhcGl0YWxpemUobmFtZSkpOworICAgIHJldHVybiAxOworICB9CisgIGxwdiA9IChpbnQpb2ItPlF1ZXJ5UHJvcChQX0hQKTsKKyAgbXB2ID0gKGludClvYi0+UXVlcnlQcm9wKFBfU1ApOworICBvYi0+aGVhbF9zZWxmKDEwMDAwMDApOworICBpZiAoIUlTX0xFQVJORVIob2IpICYmICghb2ItPlF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpfHwKKyAgICAgICAgICAoKChzdHJpbmcpb2ItPlF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpKVs8NS4uPDFdPT0iR2lsZGUiKSkpCisgICAgbG9nX2ZpbGUoU0hFTExMT0coIkhFQUwiKSwKKyAgICAgICBzcHJpbnRmKCIlcyBoZWlsdCAlcyAoJXMpICVzIChMUDogJWQgLT4gJWQsIE1QOiAlZCAtPiAlZClcbiIsCisgICAgICAgICBjYXBpdGFsaXplKGdldGV1aWQodGhpc19wbGF5ZXIoKSkpLAorICAgICAgICAgY2FsbF9vdGhlcihvYiwibmFtZSIpLCBjYXBpdGFsaXplKGdldGV1aWQob2IpKSwKKyAgICAgICAgIGR0aW1lKHRpbWUoKSksIGxwdiwgKGludClvYi0+UXVlcnlQcm9wKFBfSFApLAorICAgICAgICAgICAgICAgbXB2LChpbnQpb2ItPlF1ZXJ5UHJvcChQX1NQKSkpOworICB0ZWxsX29iamVjdChvYiwgUXVlcnlQcm9wKFBfTkFNRSkgKyAiIGhlaWx0IERpY2guXG4iKTsKKyAgcHJpbnRmKCJEdSBoZWlsc3QgJXMuXG4iLGNhcGl0YWxpemUobmFtZSkpOworICByZXR1cm4gMTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFBFT1BMRSAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjCisKK3ByaXZhdGUgc3RyaW5nIF9wZW9wbGVfZmlsZW5hbWUob2JqZWN0IG9iaikKK3sKKyAgc3RyaW5nIHN0cjsKKyAgc3RyPW9iamVjdF9uYW1lKGVudmlyb25tZW50KG9iaikpOworICBpZiAoIXN0cikgcmV0dXJuIDA7CisgIGlmIChzdHJbMC4uMl0gPT0gIi9kLyIpIHJldHVybiBzcHJpbnRmKCIrJXMiLHN0clszLi48MV0pOworICBpZiAoc3RyWzAuLjhdID09ICIvcGxheWVycy8iKSByZXR1cm4gc3ByaW50ZigifiVzIixzdHJbOS4uPDFdKTsKKyAgcmV0dXJuIHN0cjsKK30KKworc3RhdGljIGludCBfcGVvcGxlKCkKK3sKKyAgbWl4ZWQgKmxpc3QsIHJlczsKKyAgaW50IGksaiwgYTsKKyAgc3RyaW5nIGFfYWdlLGFfaXBudW0sYV9uYW1lLGFfbGV2ZWwsYV9pZGxlLGFfcm9vbSxhX2VuZCwgYV90aXRsZTsKKworICBzd2l0Y2goUXVlcnlQcm9wKCJ0dHkiKSkKKyAgeworICAgIGNhc2UgInZ0MTAwIjoKKyAgICAgIGFfaXBudW0gPSAiIjsgYV9uYW1lID0gQU5TSV9CT0xEOworICAgICAgYV9sZXZlbCA9IEFOU0lfTk9STUFMOyBhX2lkbGUgPSBBTlNJX0JMSU5LOworICAgICAgYV9yb29tID0gQU5TSV9OT1JNQUw7IGFfZW5kID0gQU5TSV9OT1JNQUw7CisgICAgICBhX3RpdGxlID0gQU5TSV9JTlZFUlM7IGFfYWdlID0gQU5TSV9OT1JNQUw7CisgICAgICBicmVhazsKKyAgICBjYXNlICJhbnNpIjoKKyAgICAgIGFfaXBudW0gPSBBTlNJX0JMVUU7IGFfbmFtZSA9IEFOU0lfQk9MRDsKKyAgICAgIGFfbGV2ZWwgPSBBTlNJX1JFRDsgYV9pZGxlID0gQU5TSV9CTEFDSytBTlNJX0JPTEQ7CisgICAgICBhX3Jvb20gPSBBTlNJX0JPTEQrQU5TSV9CTFVFOyBhX2VuZCA9IEFOU0lfTk9STUFMOworICAgICAgYV90aXRsZSA9IEFOU0lfSU5WRVJTOyBhX2FnZSA9IEFOU0lfUFVSUExFOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIGFfdGl0bGUgPSBhX2lwbnVtID0gYV9uYW1lID0gYV9sZXZlbCA9IGFfaWRsZSA9IGFfcm9vbSA9IGFfZW5kID0gIiI7CisgICAgICBhX2FnZSA9ICIiOworICB9CisgIGxpc3QgPSBzb3J0X2FycmF5KHVzZXJzKCksIGZ1bmN0aW9uIGludCAob2JqZWN0IGEsIG9iamVjdCBiKSB7CisgICAgICByZXR1cm4gcXVlcnlfaXBfbnVtYmVyKGEpPnF1ZXJ5X2lwX251bWJlcihiKTt9ICk7IAorCisgIGo9c2l6ZW9mKGxpc3QpOworICBhPTA7cmVzPSIiOworICBmb3IoaT0wOyBpPHNpemVvZihsaXN0KTsgaSsrKSB7CisgICAgc3RyaW5nIG5hbWVfOyAKKyAgICBuYW1lXyA9IGNhcGl0YWxpemUobGlzdFtpXS0+cXVlcnlfcmVhbF9uYW1lKCl8fCI8bG9nb24+Iik7CisgICAgcmVzICs9IHNwcmludGYoICIlcyUtMTVzJXMgJXMlLTEzcyVzICVzJTNkJXMgJXMgJXMgJXMlcyVzJXMgJXMlc1xuIiwKKyAgICAgICAgICAgICAgICAgICAgYV9pcG51bSwgcXVlcnlfaXBfbnVtYmVyKGxpc3RbaV0pLGFfZW5kLGFfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgKGxpc3RbaV0tPlF1ZXJ5UHJvcChQX0lOVklTKT8iKCIrbmFtZV8rIikiOm5hbWVfKSwKKyAgICAgICAgICAgICAgICAgICAgYV9lbmQsYV9sZXZlbCwgTUFTVEVSLT5nZXRfd2l6X2xldmVsKGdldHVpZChsaXN0W2ldKSksCisgICAgICAgICAgICAgICAgICAgIGFfZW5kLGFfYWdlLAorICAgICAgICAgICAgICAgICAgICB0aW1lMnN0cmluZygiJTR4ICUwWCIsKChpbnQpbGlzdFtpXS0+UXVlcnlQcm9wKFBfQUdFKSkqMiksCisgICAgICAgICAgICAgICAgICAgIHF1ZXJ5X2lkbGUobGlzdFtpXSk+PTMwMD8oYSsrLChhX2lkbGUrIkkiKSk6IiAiLAorICAgICAgICAgICAgICAgICAgICBhX2VuZCwKKyAgICAgICAgICAgICAgICAgICAgcXVlcnlfZWRpdGluZyhsaXN0W2ldKT9hX2lkbGUrIkUiK2FfZW5kOiIgIiwKKyAgICAgICAgICAgICAgICAgICAgcXVlcnlfaW5wdXRfcGVuZGluZyhsaXN0W2ldKT9hX2lkbGUrIk0iK2FfZW5kOiIgIiwKKyAgICAgICAgICAgICAgICAgICAgZW52aXJvbm1lbnQobGlzdFtpXSk/YV9yb29tK19wZW9wbGVfZmlsZW5hbWUobGlzdFtpXSk6IiIsCisgICAgICAgICAgICAgICAgICAgIGFfZW5kKTsKKyAgfQorICBpZiAoYSkKKyAgICByZXMgPSBzcHJpbnRmKCIlcyVkIFNwaWVsZXIgYW53ZXNlbmQgKCVkIGFrdGl2KS4gJXMlc1xuIixhX3RpdGxlLGosCisgICAgICAgICAgICAgICAgICAoai1hKSxxdWVyeV9sb2FkX2F2ZXJhZ2UoKSxhX2VuZCkrcmVzOworICBlbHNlCisgICAgcmVzID0gc3ByaW50ZigiJXMlZCBTcGllbGVyIGFud2VzZW5kLiAlcyVzXG4iLGFfdGl0bGUsaiwKKyAgICAgICAgICAgICAgICAgIHF1ZXJ5X2xvYWRfYXZlcmFnZSgpLGFfZW5kKStyZXM7CisgIE1vcmUocmVzKTsKKworICByZXR1cm4gMTsKK30KKworCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFNQSUVMRVIgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMKKworcHJpdmF0ZSBzdHJpbmcgX3NwaWVsZXJfdGltZTJzdHJpbmcoaW50IHRpbWUpCit7CisgIHN0cmluZyByZXQ7CisKKyAgcmV0PSIiOworICBpZiAodGltZT49ODY0MDApCisgIHsKKyAgICByZXQrPXRpbWUvODY0MDArImQgIjsKKyAgICB0aW1lJT04NjQwMDsKKyAgfQorICBpZih0aW1lPDM2MDAwKSByZXQrPSIwIjsKKyAgcmV0Kz10aW1lLzM2MDArIjoiOworICB0aW1lJT0zNjAwOworICBpZih0aW1lPDYwMCkgcmV0Kz0iMCI7CisgIHJldCs9dGltZS82MCsiOiI7CisgIHRpbWUlPTYwOworICBpZih0aW1lPDEwKSByZXQrPSIwIjsKKyAgcmV0Kz10aW1lKyIiOworICByZXR1cm4gcmV0OworfQorCisKK3N0YXRpYyBpbnQgX3NwaWVsZXIoc3RyaW5nIGFyZykKK3sKKyAgc3RyaW5nIGR1bW15LGlwOworICBvYmplY3QgKnNwaWVsZXIscGw7CisgIGludCBpOworICAKKyAgYXJnPV91bnBhcnNlZF9hcmdzKCk7CisgIGlmKCFzaXplb2YoYXJnKSB8fCBzc2NhbmYoYXJnLCJhdXMgaXAgJXMiLGR1bW15KSE9MSkKKyAgICByZXR1cm4gVVNBR0UoInNwaWVsZXIgYXVzIGlwIFt2b24gPHNwaWVsZXI+fDxpcD5dIik7CisgIGFyZz1kdW1teTsKKyAgaWYgKHNzY2FuZihhcmcsInZvbiAlcyIsZHVtbXkpPT0xKQorICB7CisgICAgZHVtbXk9bG93ZXJfY2FzZShkdW1teSk7CisgICAgaWYgKCEocGw9ZmluZF9wbGF5ZXIoZHVtbXkpKSkKKyAgICAgIHJldHVybiBub3RpZnlfZmFpbChzcHJpbnRmKCJTcGllbGVyICclcycga29ubnRlIG5pY2h0IGdlZnVuZGVuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3ZXJkZW4uXG4iLGNhcGl0YWxpemUoZHVtbXkpKSksMDsKKyAgICBpcD1xdWVyeV9pcF9udW1iZXIocGwpOworICB9CisgIGVsc2UgaXA9YXJnOworICBpcD1pbXBsb2RlKChleHBsb2RlKGlwLCIuIiktKHsiIn0pKyh7IioiLCIqIiwiKiIsIioifSkpWzAuLjNdLCIuIik7CitpZiAoY2F0Y2goCisgIHNwaWVsZXI9ZmlsdGVyKHVzZXJzKCksCisgICAgKDogcmV0dXJuIHNpemVvZihyZWdleHAoKHtxdWVyeV9pcF9udW1iZXIoJDEpfSksJDIpKTsgOiksIl4iK2dsb2IycmVnZXhwKGlwKSsiJCIpCisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkKKyAgcmV0dXJuIHByaW50ZigiSW4gZGVyIElQIGR1ZXJmZW4gbnVyIFphaGxlbigwLTI1NSksIFB1bmt0ZSAoLikgdW5kICIKKyAgICAgICAgICAgICAgICAiU3Rlcm5lICgqKSB2b3Jrb21tZW4uXG4iKSwxOworICBpZiAoIXNpemVvZihzcGllbGVyKSkKKyAgICByZXR1cm4gcHJpbnRmKCJFcyBrb25udGUga2VpbiBTcGllbGVyIG1pdCBkZXIgSVAgJyVzJyBnZWZ1bmRlbiAiCisgICAgICAgICAgICAgICAgICAid2VyZGVuLlxuIixpcCksMTsKKyAgYXJnPXNwcmludGYoIlxuRm9sZ2VuZGUgU3BpZWxlciBoYWJlbiBkaWUgSVAgJXM6XG4iCisgICAgICAgIj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iCisgICAgICAgICAgICAgICI9PT09PT09PT09PVxuIgorICAgICAgICJOYW1lOiAgICAgICBad2VpdGllIHZvbjogICAgICBFaW5nZWxvZ2d0OiAgICAgICAgICAgICAgICAgICIKKyAgICAgICAgICAgICAgIklkbGUgc2VpdDpcbiIKKyAgICAgICAiLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSIKKyAgICAgICAgICAgICAgIi0tLS0tLS0tLS0tXG4iLGlwKTsKKyAgaT1zaXplb2Yoc3BpZWxlcik7CisgIHdoaWxlKGktLSkKKyAgeworICAgIGFyZys9c3ByaW50ZigiJS0xMXMgJS0xN3MgJTI2cyAgJS0xNXNcbiIsCisgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKHNwaWVsZXJbaV0pKSwKKyAgICAgICAgICAgICAgICAgKChkdW1teT0oc3RyaW5nKXNwaWVsZXJbaV0tPlF1ZXJ5UHJvcChQX1NFQ09ORCkpPworICAgICAgICAgICAgICAgICAgKHNpemVvZigobWl4ZWQgKiljYWxsX290aGVyKG1hc3RlcigpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnZXRfdXNlcmluZm8iLGR1bW15KSk/CisgICAgICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShkdW1teSk6Iip1bmd1ZWx0aWcqIik6IiIpLAorICAgICAgICAgICAgICAgICBkdGltZShzcGllbGVyW2ldLT5RdWVyeVByb3AoUF9MQVNUX0xPR0lOKSksCisgICAgICAgICAgICAgICAgIF9zcGllbGVyX3RpbWUyc3RyaW5nKHF1ZXJ5X2lkbGUoc3BpZWxlcltpXSkpKTsKKyAgfQorICBhcmcrPSI9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0iCisgICAgIj09PT09PT09PT09PVxuXG4iOworICBNb3JlKGFyZyk7CisgIHJldHVybiAxOworfQpkaWZmIC0tZ2l0IGEvc3RkL3NoZWxscy9tYWdpZXIvdG9kby5jIGIvc3RkL3NoZWxscy9tYWdpZXIvdG9kby5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY0MTIwZTcKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvc2hlbGxzL21hZ2llci90b2RvLmMKQEAgLTAsMCArMSwyMjIgQEAKKy8vICRJZDogdG9kby5jIDkxNDIgMjAxNS0wMi0wNCAyMjoxNzoyOVogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPG1hZ2llci5oPgorI2luY2x1ZGUgPHBsYXllci5oPgorCisjZGVmaW5lIFNBVkVGSUxFTkFNRSBzcHJpbnRmKCIvcGxheWVycy8lcy8udG9kb2xpc3RlIixnZXR1aWQoKSkKKworcHJpdmF0ZSBub3NhdmUgc3RhdHVzIHRvZG9faW5pdGlhbGl6ZWQ7Citwcml2YXRlIG5vc2F2ZSBtaXhlZCAqdG9kb19kYXRhOworbWl4ZWQgKnRvZG9fZGF0YV9wdWJsaWM7CitzdGF0aWMgbWl4ZWQgX3F1ZXJ5X2xvY2FsY21kcygpCit7CisgIHJldHVybiAoeworICAgICh7InRvZG8iLCJfdG9kbyIsMCxXSVpBUkRfTFZMfSl9KTsKK30KKworcHJpdmF0ZSB2b2lkIHRvZG9fc2F2ZSgpCit7CisKKyAgaW50IGksajsKKyAgc3RyaW5nIGEsYjsKKyAgYT1TQVZFRklMRU5BTUUrIi5vIjsKKyAgcm0oYSk7CisgIGlmIChqPXNpemVvZih0b2RvX2RhdGEpKQorICB7CisjaWYgIV9fRUZVTl9ERUZJTkVEX18oc2F2ZV92YWx1ZSkgICAKKyAgICB3cml0ZV9maWxlKGEsIiMwOjBcbnRvZG9fZGF0YV9wdWJsaWMgKHsiKTsKKyAgICBmb3IgKGk9MDtpPGo7aSsrKQorICAgIHsKKyAgICAgIGI9cmVncmVwbGFjZSh0b2RvX2RhdGFbaV1bMV0sIlwiIiwiXFxcIiIsMSk7CisgICAgICBiPXJlZ3JlcGxhY2UoYiwiXG4iLCJcXG4iLDEpOworICAgICAgd3JpdGVfZmlsZShhLHNwcmludGYoIih7JWQsXCIlc1wiLH0pLCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICB0b2RvX2RhdGFbaV1bMF0sYikpOworICAgIH0KKyAgICB3cml0ZV9maWxlKGEsIn0pXG4iKTsKKyNlbHNlCisgICAgdG9kb19kYXRhX3B1YmxpYz10b2RvX2RhdGE7CisgICAgd3JpdGVfZmlsZShhLHNhdmVfdmFsdWUodG9kb19kYXRhX3B1YmxpYykpOworICAgIHRvZG9fZGF0YV9wdWJsaWM9MDsKKyNlbmRpZgorICB9CisgIHJldHVybjsKKworfQorCitzdGF0aWMgdm9pZCBpbml0aWFsaXplKCkKK3sKKyAgaWYoIUlTX1dJWkFSRCh0aGlzX29iamVjdCgpKSkgcmV0dXJuOworICBpZiAoIXJlc3RvcmVfb2JqZWN0KFNBVkVGSUxFTkFNRSkpIHRvZG9fZGF0YT0oe30pOworICBlbHNlCisgICAgeworICAgICAgdG9kb19kYXRhPXRvZG9fZGF0YV9wdWJsaWM7CisgICAgICB0b2RvX2RhdGFfcHVibGljPTA7CisgICAgfQorICByZXR1cm47Cit9CisKK3N0YXRpYyB2b2lkIF90b2RvX25ldTIoc3RyaW5nIGlucHV0LHN0cmluZyBjYXJyeSkKK3sKKyAgaWYgKGlucHV0PT0icSJ8fChpbnB1dD09Ii4iJiYhc2l6ZW9mKGNhcnJ5KSkpCisgIHsKKyAgICBwcmludGYoIkFiYnJ1Y2ghIik7CisgICAgcmV0dXJuOworICB9CisgIGlmIChpbnB1dCE9Ii4iKQorICB7CisgICAgcHJpbnRmKCJdIik7CisgICAgaW5wdXRfdG8oIl90b2RvX25ldTIiLDAsY2FycnkraW5wdXQrIlxuIik7CisgICAgcmV0dXJuOworICB9CisgIHRvZG9fZGF0YSs9KHsgKHsgdGltZSgpLCBjYXJyeSB9KSB9KTsKKyAgdG9kb19zYXZlKCk7CisgIHByaW50ZigiRWludHJhZyBhbmdlbGVndC4gTGF1ZmVuZGUgTnVtbWVyIGlzdCAlZC5cbiIsc2l6ZW9mKHRvZG9fZGF0YSkpOworICByZXR1cm47Cit9CisKK3ByaXZhdGUgaW50IF90b2RvX25ldShzdHJpbmcgY21kbGluZSkKK3sKKyAgaWYgKGNtZGxpbmUhPSJuZXUiKSByZXR1cm4gMDsKKyAgcHJpbnRmKCJXYXMgbXVzc3QgRHUgbm9jaCBtYWNoZW4/IChBYmJydWNoIG1pdCAncScsICIKKyAgICAgICAgICJFbmRlIG1pdCAnLicpXG5dIik7CisgIGlucHV0X3RvKCJfdG9kb19uZXUyIiwwLCIiKTsKKyAgcmV0dXJuIDE7Cit9CisKK3ByaXZhdGUgaW50IF90b2RvX2xvZXNjaGVuKHN0cmluZyBjbWRsaW5lKQoreworICBpbnQgbnI7CisgIGlmICghc3NjYW5mKGNtZGxpbmUsImxvZXNjaGVuICVkIixucikpCisgICAgcmV0dXJuIG5vdGlmeV9mYWlsKCJXZWxjaGVuIEVpbnRyYWcgbW9lY2h0ZXN0IER1IGxvZXNjaGVuP1xuIiksMDsKKyAgaWYgKCFzaXplb2YodG9kb19kYXRhKSkKKyAgICByZXR1cm4gbm90aWZ5X2ZhaWwoIkRlaW5lIFRvZG8tTGlzdGUgaGF0IGphIHVlYmVyaGF1cHQga2VpbmVuICIKKyAgICAgICAgICAgICAgICAgICAgICAgIkVpbnRyYWchXG4iKSwwOworICBpZiAobnI+c2l6ZW9mKHRvZG9fZGF0YSkpCisgIHsKKyAgICBwcmludGYoIkRlaW5lIFRvZG8tTGlzdGUgaGF0IG51ciAlZCBFaW50cmElcy5cbiIsc2l6ZW9mKHRvZG9fZGF0YSksCisgICAgICAgICAgIChzaXplb2YodG9kb19kYXRhKT09MT8iZyI6ImVnZSIpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICB0b2RvX2RhdGFbbnItMV09MDsKKyAgdG9kb19kYXRhLT0oezB9KTsKKyAgdG9kb19zYXZlKCk7CisgIHByaW50ZigiRWludHJhZyBOdW1tZXIgJWQgd3VyZGUgZ2Vsb2VzY2h0LiBEYSBoYXN0IER1IGphIG9yZGVudGxpY2ggIgorICAgICAgICAgIndhcyBnZXNjaGFmZnQuLi5cbm9kZXIgZ2VzY2hpY2t0IGRlbGVnaWVydCA7LSlcbiIsbnIpOworICByZXR1cm4gMTsKK30KKworcHJpdmF0ZSBpbnQgX3RvZG9fYW56ZWlnZW4oc3RyaW5nIGNtZGxpbmUpCit7CisgIGludCBucjEsbnIyOworICBzdHJpbmcgb3V0cHV0OworICBpZiAoIXNpemVvZih0b2RvX2RhdGEpKQorICAgIHJldHVybiBub3RpZnlfZmFpbCgiRGVpbmUgVG9kby1MaXN0ZSBoYXQga2VpbmUgRWludHJhZWdlLlxuIiksMDsKKyAgc3dpdGNoKHNzY2FuZihjbWRsaW5lLCJhbnplaWdlbiAlZCBiaXMgJWQiLG5yMSxucjIpKSAKKyAgeworICBjYXNlIDA6IG5yMT0xOyBucjI9c2l6ZW9mKHRvZG9fZGF0YSk7IGJyZWFrOworICBjYXNlIDE6IG5yMj1ucjE7IGJyZWFrOworICBjYXNlIDI6IGJyZWFrOworICB9CisgIGlmIChucjE8MCkgbnIxPXNpemVvZih0b2RvX2RhdGEpK25yMSsxOworICBpZiAobnIyPDApIG5yMj1zaXplb2YodG9kb19kYXRhKStucjIrMTsKKyAgaWYgKG5yMTwxfHxucjI8MXx8bnIxPnNpemVvZih0b2RvX2RhdGEpfHxucjI+c2l6ZW9mKHRvZG9fZGF0YSkpCisgICAgcmV0dXJuIG5vdGlmeV9mYWlsKHNwcmludGYoIkRlaW5lIFRvZG8tTGlzdGUgaGF0IChnbHVlY2tsaWNoZXJ3ZWlzZSkgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJudXIgJWQgRWludHJhJXMuXG4iLHNpemVvZih0b2RvX2RhdGEpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzaXplb2YodG9kb19kYXRhKT4xPyJlZ2UiOiJnIikpKSwwOworICBvdXRwdXQ9IlxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiI7CisgIGlmIChucjE+bnIyKSAvLyBSdWVja3dhZXJ0cworICB7CisgICAgd2hpbGUobnIxPj1ucjIpCisgICAgICBvdXRwdXQrPXNwcmludGYoIkVpbnRyYWcgTnIuICVkIHZvbiAlczpcbiVzXG5cbiIsbnIxLS0sCisgICAgICAgICAgIGR0aW1lKHRvZG9fZGF0YVtucjFdWzBdKSxicmVha19zdHJpbmcodG9kb19kYXRhW25yMV1bMV0sNzgsNSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJTX0xFQVZFX01ZX0xGUykpOworICB9CisgIGVsc2UKKyAgeworICAgIG5yMS0tOworICAgIHdoaWxlIChucjE8bnIyKQorICAgICAgb3V0cHV0Kz1zcHJpbnRmKCJcbkVpbnRyYWcgTnIuICVkIHZvbiAlczpcbiVzXG4iLChucjErMSksCisgICAgICAgICAgIGR0aW1lKHRvZG9fZGF0YVtucjFdWzBdKSxicmVha19zdHJpbmcodG9kb19kYXRhW25yMSsrXVsxXSw3OCw1LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQlNfTEVBVkVfTVlfTEZTKSk7CisgIH0KKyAgTW9yZShvdXRwdXQrIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKK3ByaXZhdGUgaW50IF90b2RvX3ZlcnNjaGllYmVuKHN0cmluZyBjbWRsaW5lKQoreworICBpbnQgZnJvbTsKKyAgbWl4ZWQgdG8sZHVtbXk7CisgIGlmICghKHNzY2FuZihjbWRsaW5lLCJ2ZXJzY2hpZWJlbiAlZCBuYWNoICVkIixmcm9tLHRvKT09Mnx8CisgICAgICAgIHNzY2FuZihjbWRsaW5lLCJ2ZXJzY2hpZWJlbiAlZCBuYWNoICVzIixmcm9tLHRvKT09MikpCisgICAgcmV0dXJuIDA7CisgIGZyb20tLTsKKyAgaWYgKHN0cmluZ3AodG8pKQorICB7CisgICAgc3dpdGNoKHRvKQorICAgIHsKKyAgICAgIGNhc2UgIm9iZW4iOiB0bz1mcm9tLTE7IGJyZWFrOworICAgICAgY2FzZSAidW50ZW4iOiB0bz1mcm9tKzE7IGJyZWFrOworICAgICAgZGVmYXVsdDogcmV0dXJuIDA7CisgICAgfQorICB9CisgIGVsc2UgdG8tLTsKKyAgaWYgKHRvPT1mcm9tKSByZXR1cm4gbm90aWZ5X2ZhaWwoIkRhIGlzdCBkZXIgRWludHJhZyBqYSBzY2hvbiFcbiIpLDA7CisgIGlmIChmcm9tPDB8fGZyb20+PXNpemVvZih0b2RvX2RhdGEpKSByZXR1cm4gbm90aWZ5X2ZhaWwoCisgICAgICAgICJXaWUgd2lsbHN0IER1IGVpbmVuIG5pY2h0IGV4aXN0ZW50ZW4gRWludHJhZyB2ZXJzY2hpZWJlbj9cbiIpLDA7CisgIGlmICh0bzwwfHx0bz49c2l6ZW9mKHRvZG9fZGF0YSkpIHJldHVybiBub3RpZnlfZmFpbCgKKyAgICAgICAgIkRhaGluIGthbm5zdCBEdSBkZW4gRWludHJhZyBuaWNodCB2ZXJzY2hpZWJlbi5cbiIpLDA7CisgIGR1bW15PXRvZG9fZGF0YVtmcm9tXTsKKyAgaWYgKHRvPmZyb20pCisgICAgd2hpbGUgKGZyb20rKzx0bykgdG9kb19kYXRhW2Zyb20tMV09dG9kb19kYXRhW2Zyb21dOworICBlbHNlCisgICAgd2hpbGUoZnJvbS0tPnRvKSB0b2RvX2RhdGFbZnJvbSsxXT10b2RvX2RhdGFbZnJvbV07CisgIHRvZG9fZGF0YVt0b109ZHVtbXk7CisgIHByaW50ZigiRWludHJhZyB3dXJkZSB2ZXJzY2hvYmVuLlxuIik7CisgIHJldHVybiAxOworfQorCitwcml2YXRlIGludCBfdG9kb19oaWxmZSgpCit7CisgIHByaW50ZigKKyAgIi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuIgorICAiIERpZSBUb2RvLUxpc3RlIGxhZXNzdCBzaWNoIG1pdCBkZW4gZm9sZ2VuZGVuIEJlZmVobGVuIHN0ZXVlcm46XG5cbiIKKyAgIiB0b2RvIG5ldSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBMZWd0IGVpbmVuIG5ldWVuIEVpbnRyYWcgYW4uXG4iCisgICIgdG9kbyBsb2VzY2hlbiA8bnVtbWVyPiAgICAgICAgICAgICAgICAgIC0gTG9lc2NodCBlaW5lbiBFaW50cmFnLlxuIgorICAiIHRvZG8gYW56ZWlnZW4gWzxudW1tZXI+IFtiaXMgPG51bW1lcj5dXSAtIFplaWd0IGRpZSBUb2RvLUxpc3RlIGFuLlxuIgorICAiIHRvZG8gdmVyc2NoaWViZW4gPG51bW1lcj4gbmFjaCA8emllbD4gICAtIFZlcnNjaGllYnQgZWluZW4gRWludHJhZy5cblxuIgorICAiIDx6aWVsPiBrYW5uIGVpbmUgWmFobCBvZGVyIGRpZSBXb3J0ZSAnb2Jlbicgb2RlciAndW50ZW4nIHNlaW4uXG4iCisgICItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKKworc3RhdGljIGludCBfdG9kbyhzdHJpbmcgY21kbGluZSkKK3sKKyAgc3RyaW5nICphcmdzOworICAKKyAgY21kbGluZT1fdW5wYXJzZWRfYXJncygxKTsKKyAgbm90aWZ5X2ZhaWwoIkZhbHNjaGUgU3ludGF4LiAndG9kbyBoaWxmZScgemVpZ3QgZWluZSBIaWxmZSBhbi5cbiIpOworICBpZiAoc2l6ZW9mKGNtZGxpbmUpKQorICB7CisgICAgYXJncz1leHBsb2RlKGNtZGxpbmUsIiAiKTsKKyAgICBzd2l0Y2goYXJnc1swXSkKKyAgICB7CisgICAgICBjYXNlICJuZXUiOiAgICAgICAgIHJldHVybiBfdG9kb19uZXUoY21kbGluZSk7CisgICAgICBjYXNlICJsb2VzY2hlbiI6ICAgIHJldHVybiBfdG9kb19sb2VzY2hlbihjbWRsaW5lKTsKKyAgICAgIGNhc2UgImFuemVpZ2VuIjogICAgcmV0dXJuIF90b2RvX2FuemVpZ2VuKGNtZGxpbmUpOworICAgICAgY2FzZSAidmVyc2NoaWViZW4iOiByZXR1cm4gX3RvZG9fdmVyc2NoaWViZW4oY21kbGluZSk7CisgICAgICBjYXNlICJoaWxmZSI6ICAgICAgIHJldHVybiBfdG9kb19oaWxmZSgpOworICAgICBkZWZhdWx0OiAgICAgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgfQorICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL3N0ZC9zaGVsbHMvbWFnaWVyL3VwZC5jIGIvc3RkL3NoZWxscy9tYWdpZXIvdXBkLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjA5ZWE5YQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvbWFnaWVyL3VwZC5jCkBAIC0wLDAgKzEsNTYzIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdXBkLmMKKy8vCisvLyAkSWQ6IHVwZC5jIDg4NTAgMjAxNC0wNi0xMyAyMTozNDo0NFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8bWFnaWVyLmg+CisjaW5jbHVkZSA8cGxheWVyLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8ZGVidWdfaW5mby5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxsb2dnaW5nLmg+CisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorCit2YXJhcmdzIHN0YXRpYyBpbnQgX21ha2Uoc3RyaW5nIGZpbGUsIGludCBmbGFncywgaW50IHJlY3Vyc2l2ZSk7CisKK3N0YXRpYyBtaXhlZCBfcXVlcnlfbG9jYWxjbWRzKCkKK3sKKyAgcmV0dXJuICh7KHsidXBkIiwiX3VwZCIsMCxMRUFSTkVSX0xWTH0pLAorICAgICAgICAgICAoeyJsb2FkIiwiX2xvYWQiLDAsTEVBUk5FUl9MVkx9KX0pOworfQorCisvLworLy8gX3NhdmUoKTogU3BpZWxlciBpbiBSZXR0dW5nc3JhdW0gcmV0dGVuCisvLyBvYmo6ICAgICAgU3BpZWxlcm9iamVrdCg/KQorLy8gaW52X3NhdmU6IFJldHR1bmdzcmF1bW5hbWUgCisvLyBSdWVja2dhYmU6IDAgd2VubiBrZWluIFNwaWVsZXJvYmpla3QKKy8vICAgICAgICAgICAgU3BpZWxlcm9iamVrdCwgZmFsbHMgZG9jaAorLy8KKworc3RhdGljIG1peGVkIF9zYXZlKCBvYmplY3Qgb2JqLCBvYmplY3QgaW52X3NhdmVyICkKK3sgCisgICAgaWYgKCBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iaikgKQorICAgICAgeyAKKyAgICAgICAgb2JqLT5tb3ZlKCBpbnZfc2F2ZXIsIE5PX0NIRUNLICk7CisgICAgICAgIHJldHVybiBvYmo7CisgICAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKKworLy8KKy8vIF9yZWxvYWQoKTogT2JqZWt0IGxhZGVuCisvLyBmaWxlOiAgRmlsZW5hbWUuIE11c3MgaW4gZGVyIEZvcm0gL3h4L3h4L3h4LmMgdm9ybGllZ2VuCisvLyBjbG9uZTogID4gMCAtPiBFcyBzb2xsIGdlY2xvbnQgd2VyZGVuLCBlbnRoYWVsdCBPYmpla3RudW1tZXIgZGVzCisvLyAgICAgICAgICAgICAgICBWb3JnYWVuZ2Vyb2JqZWt0ZXMKKy8vIGZsYWdzOiBLb21tYW5kb3plaWxlbm9wdGlvbmVuCisvLyBlcnI6ICAgTGVlcnN0cmluZyBhbHMgUmVmZXJlbnogdWViZXJnZWJlbi4gRW50aGFlbHQgbmFjaCBkZW0KKy8vICAgICAgICBBdWZydWYgdm9tIF9yZWxvYWQoKSBkaWUgRmVobGVybWVsZHVuZ2VuIGFscyBTdHJpbmcuCisvLyBSdWVja2dhYmU6IERhcyBuZXUgZXJ6ZXVndGUgT2JqZWt0IGJ6dy4gZGFzIHNjaG9uIHZvcmhhbmRlbmUgT2JqZWt0CisvLyAgICAgICAgICAgIGJ6dy4gMCwgd2VubiBGZWhsZXIgYXVmdHJhdC4KKy8vCisKK3ByaXZhdGUgb2JqZWN0IF9yZWxvYWQoc3RyaW5nIGZpbGUsIGludCBjbG9uZSwgaW50IGZsYWdzLCBzdHJpbmcgZXJyKQoreworICBvYmplY3Qgb2JqOworICAKKyAgaWYgKCFvYmo9ZmluZF9vYmplY3QoZmlsZVswLi48M10rKGNsb25lPygiIyIrY2xvbmUpOiIiKSkpCisgIHsKKyAgICBpbnQgcG9zLHBvczI7CisgICAgc3RyaW5nIGJ0OworCisgICAgaWYoZmlsZV9zaXplKGZpbGUpPDApCisgICAgeworICAgICAgaWYgKGZpbGVfc2l6ZShmaWxlKT09LTEpCisgICAgICAgIGVyciA9IHNwcmludGYoInVwZDogJXM6IERhdGVpIGV4aXN0aWVydCBuaWNodC5cbiIsIGZpbGUpOworICAgICAgZWxzZSAvLyBkaXJlY3RvcnkKKyAgICAgICAgZXJyID0gc3ByaW50ZigidXBkOiAlczogVmVyemVpY2huaXNzZSBrb2VubmVuIG5pY2h0IGdlbGFkZW4gIgorICAgICAgICAgICAgICAgICAgICAgICJ3ZXJkZW4uXG4iLGZpbGUpOworICAgICAgcmV0dXJuIG9iajsgLy8gMAorICAgIH0KKyAgICBwb3MgPSBtYXgoZmlsZV9zaXplKF9fREVCVUdfTE9HX18pLDApOworCisgICAgaWYgKChlcnIgPSAoY2xvbmU/Y2F0Y2gob2JqID0gY2xvbmVfb2JqZWN0KGZpbGUpKToKKyAgICAgICAgICAgICAgICBjYXRjaChsb2FkX29iamVjdChmaWxlKSkgKSkgJiYgKGZsYWdzICYgVVBEX0IpKSAgICAgICAgCisgICAgeyAgICAgCisgICAgICBpZiAoKCBwb3MyPWZpbGVfc2l6ZShfX0RFQlVHX0xPR19fKSkgPiBwb3MgKQorICAgICAgICBlcnIrPXNwcmludGYoIlxuQmFja3RyYWNlOlxuJXMiLAorICAgICAgICAgICAgICAgICAgICAgcmVhZF9ieXRlcyhfX0RFQlVHX0xPR19fLHBvcywgcG9zMi1wb3MgKSk7CisgICAgICBlbHNlCisgICAgICAgIGVycis9c3ByaW50ZigiXG5LRUlOIEJBQ0tUUkFDRSBWRVJGVUVHQkFSIVxuIik7CisgICAgfQorICAgIGlmICghZXJyJiYhb2JqJiYoIW9iaiA9IGZpbmRfb2JqZWN0KGZpbGVbMC4uPDNdKSkpCisgICAgICBlcnIgKz0gc3ByaW50ZiggInVwZDogJXM6IEJsdWVwcmludCBuYWNoIGRlbSBMYWRlbiB6ZXJzdG9lcnQuXG4iLGZpbGUgKTsKKyAgfQorICBlbHNlCisgICAgZXJyPXNwcmludGYoInVwZDogT2JqZWt0IGV4aXN0aWVydCBzY2hvbjogJU9cbiIsb2JqKTsKKyAgcmV0dXJuIG9iajsKK30KKworCisvLworLy8gX3VwZGF0ZSgpOiBGaWxlIHVwZGF0ZW4gLT4gQmx1ZXByaW50IGRlc3RydWN0ZW4KKy8vIGZpbGU6ICBGaWxlbmFtZQorLy8gZHVtbXk6IHNpbXVsaWVyZW4/ICgxLT53aXJkIG5pY2h0IGFrdHVhbGlzaWVydCkKKy8vIGZsYWdzOiBLb21tYW5kb3plaWxlbm9wdGlvbmVuCisvLyBSdWVja2dhYmU6IC0xOiBLZWluZSBWb2xsenVncmlmZgorLy8gICAgICAgICAgICAgMDogT2JqZWt0IGlzdCBuaWNodCBnZWxhZGVuCisvLyAgICAgICAgICAgICAxOiBPcGVyYXRpb24gd2lyZCBkdXJjaGdlZnVlaHJ0CisvLworCitwcml2YXRlIHZhcmFyZ3MgaW50IF91cGRhdGUoc3RyaW5nIGZpbGUsIGludCBkdW1teSwgaW50IGZsYWdzKQoreworICBvYmplY3Qgb2JqOworICBzdHJpbmcgZXJyOworICBpZiAoIWR1bW15ICYmICFvYmplY3RwKG9iaiA9IGZpbmRfb2JqZWN0KGZpbGUpKSkgcmV0dXJuIDA7CisgIGlmICghSVNfQVJDSCh0aGlzX29iamVjdCgpKSkKKyAgeworICAgIC8vIFNjaHJlaWJyZWNodGUgbnVyIHBydWVmZW4sIHdlbm4gZWNodCBha3R1YWxpc2llcnQgd2VyZGVuIHNvbGwuCisgICAgaWYoIWR1bW15ICYmICFNQVlfV1JJVEUoZmlsZSkpCisgICAgICByZXR1cm4gKHByaW50ZigidXBkOqAlczogS2VpbmUgU2NocmVpYnJlY2h0ZSFcbiIsZmlsZSksIC0xKTsKKyAgICBpZighTUFZX1JFQUQoZmlsZSkpIAorICAgICAgcmV0dXJuIChwcmludGYoInVwZDogJXM6IEtlaW5lIExlc2VyZWNodGUhXG4iLCBmaWxlKSwgLTEpOworICB9CisgIGlmIChkdW1teSkgcmV0dXJuIDE7CisgIAorICBpZiAoIGZsYWdzICYgVVBEX0QgKQorICB7CisgICAgb2JqZWN0ICppbnY7CisgICAgaWYgKHNpemVvZihpbnYgPSBkZWVwX2ludmVudG9yeShvYmopKSkKKyAgICB7CisgICAgICBwcmludGYoInVwZDogJXM6IEVudGZlcm5lIE9iamVrdGUgaW0gSW52ZW50YXJcbiIsIGZpbGUgKTsKKyAgICAgIGlmICghKGZsYWdzJlVQRF9IKSkKKyAgICAgIHsKKyAgICAgICAgaWYoZXJyPWNhdGNoKGZpbHRlcl9vYmplY3RzKCBpbnYsICJyZW1vdmUiLCAxICkpKQorICAgICAgICAgIHByaW50ZigidXBkOiAlczogRmVobGdlc2NobGFnZW4uIEdydW5kOlxuJXNcbiIsCisgICAgICAgICAgICAgICAgIGZpbGUsZXJyKTsKKyAgICAgIH0KKyAgICAgIGlmIChzaXplb2YoaW52ID0gZGVlcF9pbnZlbnRvcnkob2JqKSkpCisgICAgICAgIGZpbHRlcihpbnYsIGZ1bmN0aW9uIHZvaWQgKG9iamVjdCBvYikKKyAgICAgICAgICAgIHtkZXN0cnVjdChvYik7fSk7CisgICAgfQorICB9CisgIGlmICghKGZsYWdzJlVQRF9IKSkKKyAgeworICAgIGlmKGVyciA9IGNhdGNoKG9iai0+cmVtb3ZlKCkpKQorICAgICAgcHJpbnRmKCJ1cGQ6ICVzOiByZW1vdmUoKSBmZWhsZ2VzY2hsYWdlbi4gQXVmcnVmIHZvbiAiICsKKyAgICAgICAgICAgICAiZGVzdHJ1Y3QoKS5cbiIsZmlsZSk7CisgIH0KKyAgaWYob2JqZWN0cChvYmopKSBkZXN0cnVjdChvYmopOworICByZXR1cm4gMTsKK30KKworCisvLworLy8gX2luc3RhbmNlX3VwZCgpOiBBbGxlIE9iamVrdGUgbmFjaCBDbG9uZXMgZGVzIE9iamVrdHMgZHVyY2hzdWNoZW4KKy8vIGZpbGU6ICBGaWxlbmFtZSBkZXMgT2JqZWt0ZXMKKy8vIGZsYWdzOiBLb21tYW5kb3plaWxlbmFyZ3VtZW50ZQorLy8gb2JqOiAgIEFrdHVlbGxlcyBPYmpla3QKKy8vIGluc3RhbmNlczogWmFobCBkZXIgZ2VmdW5kZW5lbiBJbnN0YW56ZW4KKy8vCisKK3ByaXZhdGUgdm9pZCBfaW5zdGFuY2VfdXBkKHN0cmluZyBmaWxlLCBpbnQgZmxhZ3MsIG1peGVkIG9iaiwgaW50IGluc3RhbmNlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBmaXJzdGNhbGwpCit7CisgaW50IGk7CisgaWYgKGZpcnN0Y2FsbCkKKyAgICBwcmludGYoInVwZDogJXM6ICVzIEluc3Rhbnplbi5cbiIsZmlsZSxmbGFncyZVUERfQT8iQWt0dWFsaXNpZXJlIjoiU3VjaGUiKTsKKyAgCisgIHdoaWxlIChnZXRfZXZhbF9jb3N0KCk+MjIwMDAwICYmIGkgPCBzaXplb2Yob2JqKSkKKyAgeworICAgIGlmICghb2JqZWN0cChvYmpbaV0pKQorICAgICAgaW5zdGFuY2VzLS07CisgICAgZWxzZQorICAgIHsKKyAgICAgIGlmIChmbGFncyZVUERfRiYmIShmbGFncyZVUERfUykpCisgICAgICAgIHByaW50ZiggInVwZDogJU8gZ2VmdW5kZW4gaW4gJXNcbiIsIG9ialtpXSwKKyAgICAgICAgICAgICAgICBlbnZpcm9ubWVudChvYmpbaV0pP29iamVjdF9uYW1lKGVudmlyb25tZW50KG9ialtpXSkpIAorICAgICAgICAgICAgICAgIDogImtlaW5lciBVbWdlYnVuZyIgKTsKKyAgICAgIGlmIChmbGFncyZVUERfQSkgX21ha2Uob2JqZWN0X25hbWUob2JqW2ldKSwgZmxhZ3MgJiB+KFVQRF9BfFVQRF9GKSwxICk7CisgICAgfQorICAgIGkrKzsKKyAgfQorICBpZiAoaSA8IHNpemVvZihvYmopKSAKKyAgICBjYWxsX291dCggIydfaW5zdGFuY2VfdXBkLyonKi8sMixmaWxlLGZsYWdzLG9ialtpLi5dLGluc3RhbmNlcywwKTsKKyAgZWxzZQorICAgIHByaW50ZiggInVwZDogJXM6ICVkIEluc3RhbnplbiAlc1xuIiwgZmlsZSwgaW5zdGFuY2VzLAorICAgICAgICAgICAgKGZsYWdzICYgVVBEX0EpID8gImFrdHVhbGlzaWVydCIgOiAiZ2VmdW5kZW4iICk7CisgIHJldHVybjsKK30KKyAgCisgIAorLy8KKy8vIF9kb19tYWtlKCk6IEFsbGUgZ2VlcmJ0ZW4gT2JqZWt0ZSBiZWFyYmVpdGVuIChmdWVyIC1tLy12KQorLy8gZmlsZTogIE5hbWUgZGVzIEZpbGVzCisvLyBjbG9uZTogMCwgd2VubiBibHVlcHJpbnQsIGFuc29uc3RlbiBDbG9uZW51bW1lcgorLy8gZmxhZ3M6IEtvbW1hbmRvemVpbGVucGFyYW1ldGVyCisvLyBkZXA6ICAgZ2VzY2hhY2h0ZWx0ZXMgQXJyYXkgbWl0IE1lbGR1bmdlbiAod2cuIFJla3Vyc2lvbikKKy8vIHJlYWR5OiBBcnJheSBkZXIgc2Nob24gYmVhcmJlaXRldGVuIE9iamVrdGUgKHdnLiBSZWt1cnNpb24pCisvLyBSdWVja2dhYmU6IEFycmF5IGRlciBPYmpla3RuYW1lbiwgZGllIGJlYXJiZWl0ZXQgd3VyZGVuCisvLyAgICAgICAgICAgIChBcnJheSBpbiBBcnJheSBpbiAuLi4pCisvLyAKKwordmFyYXJncyBwcml2YXRlIGludCBfZG9fbWFrZSggc3RyaW5nIGZpbGUsaW50IGNsb25lLGludCBmbGFncyxtaXhlZCBkZXAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmcgKnJlYWR5ICkKK3sKKyAgb2JqZWN0IG9iajsKKyAgc3RyaW5nIGVycjsKKyAgc3RyaW5nICppbGlzdDsKKyAgbWl4ZWQgZG93bmRlcHM7CisgIGludCByZXQ7CisgIAorICBpZiAoIXBvaW50ZXJwKHJlYWR5KSkgcmVhZHkgPSAoe30pOworICByZWFkeSArPSAoeyBmaWxlIH0pOworICAKKyAgaWYgKCAhKG9iaiA9IF9yZWxvYWQoZmlsZSxjbG9uZSxmbGFncywmZXJyKSkpCisgIHsKKyAgICBkZXAgKz0gKHsgZXJyIH0pOworICAgIHJldHVybiAwOworICB9CisgIAorICBpbGlzdCA9IGluaGVyaXRfbGlzdChvYmopLXJlYWR5OworICAKKyAgZG93bmRlcHMgPSAoe30pOworICAKKyAgd2hpbGUgKHNpemVvZihpbGlzdCkpCisgIHsKKyAgICByZXQgPSBfZG9fbWFrZSggaWxpc3RbMF0sMCxmbGFncywgJmRvd25kZXBzLCAmcmVhZHkgKXx8cmV0OworICAgIGlsaXN0WzAuLjBdID0gKHt9KTsKKyAgICBpbGlzdCAtPSByZWFkeTsKKyAgfQorICAKKyAgaWYgKCByZXR8fGZpbGVfdGltZShmaWxlKT5wcm9ncmFtX3RpbWUob2JqKXx8KGZsYWdzICZVUERfSSkpCisgICAgaWYgKCBfbWFrZSggZmlsZSwgZmxhZ3MgJiB+KFVQRF9NfFVQRF9JKSAsMSkgPCAwICkgCisgICAgICBkZXAgPSAoeyAieyIgKyBleHBsb2RlKGZpbGUsIi8iKVs8MV0gKyAifSIsIGRvd25kZXBzIH0pOworICAgIGVsc2V7CisgICAgICBkZXAgPSAoeyAiWyIgKyBleHBsb2RlKGZpbGUsIi8iKVs8MV0gKyAiXSIsIGRvd25kZXBzIH0pOworICAgICAgcmV0ID0gMTsKKyAgICB9CisgIGVsc2UgaWYgKGZsYWdzJlVQRF9WKSBkZXAgKz0gKHsgZXhwbG9kZShmaWxlLCIvIilbPDFdLCBkb3duZGVwcyB9KTsKKyAgcmV0dXJuIHJldDsKK30KKworCisvLworLy8gX21ha2VfZGVwKCk6IEF1c2dhYmUgZGVzIEVyZXJidW5nc2JhdW1lcworLy8gT2JqZWt0ZSBpbSBBcnJheSBkZXAKKy8vIHByZWZpeCBlbnRoYWVsdCBaZWlsZW5hbmZhbmcgKGZ1ZXIgUmVrdXJzaW9uKQorLy8gUnVlY2tnYWJlOiBTdHJpbmcgbWl0IGRlbSBWZXJlcmJ1bmdzYmF1bSBkZXMgT2JqZWt0ZXMKKy8vCisKK3ByaXZhdGUgc3RyaW5nIF9tYWtlX2RlcCggbWl4ZWQgZGVwLCBzdHJpbmcgcHJlZml4ICkKK3sKKyAgc3RyaW5nIHJldDsKKyAgaW50IGksIHNpemU7CisgIAorICByZXQ9IiI7CisgIHNpemU9c2l6ZW9mKGRlcCk7CisgIGZvciAoaT0wOyBpPHNpemU7aSsrKQorICAgIGlmIChwb2ludGVycChkZXBbaV0pKQorICAgICAgcmV0ICs9IF9tYWtlX2RlcChkZXBbaV0scHJlZml4ICsgKGkgPCAoc2l6ZS0xKSA/ICJ8ICI6IiAiKSk7CisgICAgZWxzZSAKKyAgICAgIHJldCArPSBwcmVmaXggKyAiKy0iICsgZGVwW2ldICsgIlxuIjsKKyAgcmV0dXJuIHJldDsKK30KKworCisvLworLy8gX2lsbGVnYWxfY2xvc3VyZSgpOiBpc3QgY2xvc3VyZSBpbiBhcmcgYW4gb2JqZWt0IGdlYnVuZGVuPworLy8gYXJnOiBjbG9zdXJlKC1hcnJheS9tYXBwaW5nKQorLy8gUnVlY2tnYWJlOiAwIHdlbm4gYWxsZXMgb2theQorLy8gICAgICAgICAgICAxIHdlbm4gY2xvc3VyZSBnZWxvZXNjaHQgd2VyZGVuIG11c3MKKy8vCisKK3ByaXZhdGUgaW50IF9pbGxlZ2FsX2Nsb3N1cmUoIG1peGVkIGFyZyApCit7CisgIGludCBpLCBqOworICBzdHJpbmcgKmluZGljZXM7CisgIAorICBpZiAoIGNsb3N1cmVwKGFyZykgJiYgIW9iamVjdHAocXVlcnlfY2xvc3VyZV9vYmplY3QoYXJnKSkgKQorICAgIHJldHVybiAxOworICAKKyAgaWYgKCBwb2ludGVycChhcmcpICl7CisgICAgZm9yICggaSA9IHNpemVvZihhcmcpOyBpLS07ICkKKyAgICAgIGlmICggX2lsbGVnYWxfY2xvc3VyZShhcmdbaV0pICkKKyAgICAgICAgcmV0dXJuIDE7CisgIH0KKyAgZWxzZSBpZiAoIG1hcHBpbmdwKGFyZykgKXsKKyAgICBpbmRpY2VzID0gbV9pbmRpY2VzKGFyZyk7CisgICAgZm9yICggaSA9IHNpemVvZihpbmRpY2VzKTsgaS0tOyApCisgICAgICBmb3IgKCBqID0gZ2V0X3R5cGVfaW5mbyggYXJnLCAxICk7IGotLTsgKQorICAgICAgICBpZiAoIF9pbGxlZ2FsX2Nsb3N1cmUoYXJnW2luZGljZXNbaV0sIGpdKSApCisgICAgICAgICAgcmV0dXJuIDE7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKKy8vCisvLyBfbWFrZSgpOiBVcGRhdGUgZmlsZQorLy8gZmlsZTogIEZpbGVuYW1lCisvLyBmbGFnczogS29tbWFuZG96ZWlsZW5hcmd1bWVudGUKKy8vCisKK3ZhcmFyZ3Mgc3RhdGljIGludCBfbWFrZShzdHJpbmcgZmlsZSwgaW50IGZsYWdzLGludCByZWN1cnNpdmUpCit7CisgIHN0cmluZyBtc2csIGVyciwgYmx1ZTsKKyAgaW50IGluc3Q7CisgIG9iamVjdCBvYmosIGludl9zYXZlcjsKKyAgbWl4ZWQgdG1wOworICAKKyAgbXNnID0gIiI7CisKKyAgaWYgKCFmaWxlKSByZXR1cm4gcHJpbnRmKCAidXBkOiBLZWluIEZpbGVuYW1lIHVlYmVyZ2ViZW4hXG4iICksIFJFVF9GQUlMOworICAgIAorLy8gRmlsZW5hbWUgaW4gQmx1ZSwgT2JqZWt0bmFtZSBpbiBibHVlLCBJbnN0YW56bnVtbWVyIGluIGluc3QKKworICBpZiAoc3NjYW5mKGZpbGUsIiVzIyVkIixibHVlLGluc3QpPT0yKSBibHVlICs9ICIuYyI7CisgIGVsc2UgYmx1ZSA9IGZpbGUgKyAoZmlsZVs8Mi4uXT09Ii5jIiA/ICIiIDogIi5jIik7CisKKy8vIEFsbGUgSW5zdGFuemVuIGR1cmNoc3VjaGVuIGltIEZhbGxlIHZvbiAtYSBvZGVyIC1mIAorCisgIGlmICgoZmxhZ3MgJiBVUERfTE9BRCkmJmZpbmRfb2JqZWN0KGZpbGUpKQorICAgIHJldHVybiBwcmludGYoImxvYWQ6ICVzOiBPYmpla3QgaXN0IHNjaG9uIGdlbGFkZW4uXG4iLGZpbGUpLFJFVF9PSzsKKyAgCisgIGlmICggZmxhZ3MgJiAoVVBEX0Z8VVBEX0EpKQorICB7CisgICAgaWYgKGluc3QpIHJldHVybiBwcmludGYoICJ1cGQ6ICVzOiBFaW5lIEluc3Rhbnoga2FubiBrZWluZSAiICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNsb25lcyBoYWJlbi5cbiIsZmlsZSApLCBSRVRfRkFJTDsKKyAgICBpZiAoKHRtcD1fdXBkYXRlKGZpbGUsIDEsZmxhZ3MpKT09LTEpIAorICAgICAgcmV0dXJuIHByaW50ZiggInVwZDogJXM6IEtlaW4gVm9sbHp1Z3JpZmYgYXVmIGRpZSAiICsKKyAgICAgICAgICAgICAgICAgICAgICJEYXRlaSBlcmxhdWJ0LlxuIixmaWxlKSwgUkVUX0ZBSUw7CisgICAgaWYgKHRtcD09MCkgcmV0dXJuIFJFVF9GQUlMOworCisgICB0bXA9Y2xvbmVzKGJsdWVbMC4uPDNdLDIpOworICAgIGlmIChzaXplb2YodG1wKSkKKyAgICAgIGNhbGxfb3V0KCAjJ19pbnN0YW5jZV91cGQvKicqLywgMCwgZmlsZSxmbGFncyx0bXAsc2l6ZW9mKHRtcCksMSk7CisgICAgZWxzZQorICAgICAgcHJpbnRmKCAidXBkOiAlczogS2VpbmUgQ2xvbmVzIHZvcmhhbmRlbiFcbiIsIGJsdWVbMC4uPDNdKTsKKworICAgIGlmICggKGZsYWdzICYgVVBEX0YpICYmICEoZmxhZ3MgJihVUERfUnxVUERfTHxVUERfTE9BRCkpKSByZXR1cm4gUkVUX09LOyAKKyAgICAvLyBOaWNodHMgbGFkZW4gLT4gQXVjaCBrZWluIEJhY2t1cAorICB9CisKKy8vIEJhY2t1cHJhdW0gZmVzdGxlZ2VuCisgICAKKyAgaWYoIGJsdWU9PUlOVl9TQVZFICkgeworICAgICAgICAgICAgICAgIHByaW50ZigidXBkOiBBY2h0dW5nOiBSYXVtIHp1bSBad2lzY2hlbnNwZWljaGVybiBzb2xsIGdlbGFkZW4gd2VyZGVuPyFcbiIpOworICAgICAgICB9IAorICBpZiAoICEoaW52X3NhdmVyPWxvYWRfb2JqZWN0KElOVl9TQVZFKSkgKQorICB7CisgICAgcHJpbnRmKCJ1cGQ6ICVzOiBSYXVtIHp1bSBad2lzY2hlbnNwZWljaGVybiBkZXMgIiArCisgICAgICAgICAgICJSYXVtaW5oYWx0cyBpc3QgbmljaHQgbGFkYmFyLlxuIiArCisgICAgICAgICAgICIgICAgICAgICAlc1xuIixmaWxlLElOVl9TQVZFKTsKKyAgICByZXR1cm4gUkVUX0ZBSUw7CisgIH0KKworLy8gV2VubiBkYXMgT2JqZWt0IGV4aXN0aWVydCBiencuIERlZXAgYWt0dWFsaXNpZXJ0IHdlcmRlbiBzb2xsCisKKyAgaWYgKCAoIShmbGFncyZVUERfTE9BRCkpJiYKKyAgICAgICAoKG9iaiA9IGZpbmRfb2JqZWN0KGZpbGUpKSB8fCAoZmxhZ3MgJiAoVVBEX018VVBEX0kpKSkpCisgIHsKKyAgICBvYmplY3QgKmludiwgZW52LCAqcGxfaW52OworICAgIG1hcHBpbmcgcHJvOworICAgIGludCBpOworICAgIG1peGVkIGNvbmZpZ2RhdGE7CisgICAgaW50IHJlc3RvcmVfY29uZmlnOworCisgICAgLy8gV2VubiBPYmpla3QgZXhpc3RpZXJ0LCBkYW5uIEluaGFsdCB1bmQgZ2dmLiBEYXRlbiBhdXMgQ29uZmlndXJlKCkgb2RlcgorICAgIC8vIFByb3BzIHNpY2hlcm46CisgICAgaWYgKG9iaikKKyAgICB7CisgICAgICAvLyBpbSBGYWxsIFVQRF9DIGVyZm9sZ3QgX2tlaW5fIEF1c2xlc2VuIHVuZCBfa2VpbmVfIFJlc3RhdXJhdGlvbgorICAgICAgLy8gbWl0dGVscyBDb25maWd1cmUoKQorICAgICAgaWYgKCAhIChmbGFncyAmIFVQRF9DICkgKQorICAgICAgeworICAgICAgICBjYXRjaChyZXN0b3JlX2NvbmZpZz0obWl4ZWQpY2FsbF9yZXNvbHZlZCgmY29uZmlnZGF0YSxvYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb25maWd1cmUiLDApOworICAgICAgICAgICAgICBwdWJsaXNoKTsKKyAgICAgICAgLy8gV2VubiBVUERfQ09ORiBnZXNldHp0IHdpcmQsIF9tdXNzXyBkYXMgT2JqZWt0IGVpbiBvZWZmZW50bGljaGVzCisgICAgICAgIC8vIENvbmZpZ3VyZSgpIGRlZmluaWVyZW4sIHNvbnN0IGVyZm9sZ3QgQWJicnVjaC4KKyAgICAgICAgaWYgKChmbGFncyAmIFVQRF9DT05GKSAmJiAhcmVzdG9yZV9jb25maWcpCisgICAgICAgIHsKKyAgICAgICAgICBwcmludGYoInVwZDogJXM6IGhhdCBrZWluIENvbmZpZ3VyZSgpLCBaZXJzdG9lcnVuZyBhYmdlYnJvY2hlbi5cbiIsZmlsZSk7CisgICAgICAgICAgcmV0dXJuIFJFVF9GQUlMOworICAgICAgICB9CisgICAgICB9CisgICAgICBpZiAoIShmbGFncyZVUERfRCkmJihmbGFncyYoVVBEX0x8VVBEX1IpKSkKKyAgICAgIHsKKyAgICAgICAgaWYgKGk9c2l6ZW9mKGludj0oYWxsX2ludmVudG9yeShvYmopLSh7MH0pKSkpCisgICAgICAgIHsKKyAgICAgICAgICBtaXhlZCBpdGVtczsKKyAgICAgICAgICAvLyBIZXJhdXNiZWtvbW1lbiwgb2IgaGllciBJdGVtcyBleGlzdGllcmVuLCBkaWUgcGVyIEFkZEl0ZW0gCisgICAgICAgICAgLy8gZXJ6ZXVndCB3ZXJkZW4uIERpZSBkdWVyZmVuIG5pY2h0IGdlc2ljaGVydCB3ZXJkZW4uCisgICAgICAgICAgaXRlbXM9KG1peGVkKW9iai0+UXVlcnlQcm9wKFBfSVRFTVMpOyAvLyBtaXhlZCwgZGEgYXJyYXkgb2YgYXJyYXlzCisgICAgICAgICAgaWYgKHBvaW50ZXJwKGl0ZW1zKSYmc2l6ZW9mKGl0ZW1zKSkKKyAgICAgICAgICB7CisgICAgICAgICAgICBpdGVtcz10cmFuc3Bvc2VfYXJyYXkoaXRlbXMpWzBdOworICAgICAgICAgICAgd2hpbGUgKGktLSkKKyAgICAgICAgICAgICAgaWYgKG1lbWJlcihpdGVtcywgaW52W2ldKT09LTEpCisgICAgICAgICAgICAgICAgICAgIGludltpXS0+bW92ZShpbnZfc2F2ZXIsTk9fQ0hFQ0spOworICAgICAgICAgIH0KKyAgICAgICAgICBlbHNlIC8vIEluIGRpZXNlbSBPYmpla3Qgc2luZCBrZWluZSBJdGVtcyBnZXNldHp0LgorICAgICAgICAgICAgd2hpbGUgKGktLSkgaW52W2ldLT5tb3ZlKGludl9zYXZlcixOT19DSEVDSyk7CisgICAgICAgIH0KKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgIHsKKyAgICAgICAgaW52PW1hcCggZGVlcF9pbnZlbnRvcnkob2JqKSwgIydfc2F2ZS8qJyovLCBpbnZfc2F2ZXIgKS0oezB9KTsKKyAgICAgIH0KKyAgICAgIGVudiA9IGVudmlyb25tZW50KG9iaik7CisgICAgICBpZiAoIGZsYWdzICYgVVBEX0MgKQorICAgICAgeworICAgICAgICBwcm8gPSAobWFwcGluZykob2JqLT5RdWVyeVByb3BlcnRpZXMoKSk7CisgICAgICB9CisgICAgfQorICAgIGVsc2UgaW52ID0gKHt9KTsKKworLy8gRXJlcmJ0ZSBPYmpla3RlIGR1cmNoc3VjaGVuLgorICAgIGlmICggZmxhZ3MgJiAoVVBEX018VVBEX0kpICkKKyAgICB7CisgICAgICBtaXhlZCBkZXA7CisgICAgICBkZXAgPSAoe30pOworICAgICAgX2RvX21ha2UoIGJsdWUsIGluc3QsIGZsYWdzICYgfihVUERfTXxVUERfTHxVUERfUnxVUERfRnxVUERfQSksICZkZXAgKTsKKyAgICAgIHByaW50ZiggX21ha2VfZGVwKCBkZXAsICIiICkgKyAiXG4iICk7CisgICAgfQorICAgCisvLyBUYXRzYWVjaGxpY2hlbiBVcGRhdGUgZHVyY2hmdWVocmVuCisgICAKKyAgICBpZiAoIF91cGRhdGUoZmlsZSwgMCwgZmxhZ3MpPCAwKSByZXR1cm4gUkVUX0ZBSUw7CisgICAgbXNnICs9IChpbnN0ID8gInplcnN0b2VydCIgOiAiYWt0dWFsaXNpZXJ0Iik7CisgICAgCisvLyBOZXUgbGFkZW4gPz8KKyAgICBpZiAoIGZsYWdzICYgKFVQRF9SfFVQRF9MKSApCisgICAgeworICAgICAgaWYgKCBvYmogPSBfcmVsb2FkKCBibHVlLGluc3QsZmxhZ3MsICZlcnIgKSApCisgICAgICAgIG1zZyArPSAiLCAiICsgKGluc3QgPyAibmV1IGdlY2xvbnQiIDogIm5ldSBnZWxhZGVuIik7CisgICAgIAorLy8gTmV1IGdlbGFkZW46IFByb3BlcnRpZXMgd2llZGVyaGVyc3RlbGxlbiwgQ2xvc3VyZXMgZmlsdGVybiAKKyAgICAgIGlmICghZXJyKQorICAgICAgeworICAgICAgICBpZiAoIW9iaikgb2JqID0gZmluZF9vYmplY3QoZmlsZSk7CisgICAgICAgIC8vIFdlbm4gZ2V3dWVuc2NodCwgUHJvcHMgenVydWVja3NjaHJlaWJlbiAoaGF0IFByaW9yaXRhZXQgdm9yCisgICAgICAgIC8vIENvbmZpZ3VyZSgpLCB3ZWlsIGV4cGxpeml0IHZvbSBNYWdpZXIgYW5nZWZvcmRlcnQpLgorICAgICAgICBpZiAoIHBybyAmJiAoZmxhZ3MgJiBVUERfQykgKQorICAgICAgICB7CisgICAgICAgICAgc3RyaW5nICpuYW1lczsKKyAgICAgICAgICAKKyAgICAgICAgICBuYW1lcyA9IG1faW5kaWNlcyhwcm8pOworICAgICAgICAgIAorICAgICAgICAgIC8vIENsb3N1cmVzIGluIChtaXR0bGVyd2VpbGUpIHplcnN0b2VydGVuIE9iamVrdGVuCisgICAgICAgICAgLy8gcmF1c2ZpbHRlcm4sIGRhbWl0IGRpZSAoaG9mZmVudGxpY2gga29ycmVrdGVuKSBDbG9zdXJlcworICAgICAgICAgIC8vIGltIG5ldSBnZWNsb250ZW4gT2JqZWt0IGVyaGFsdGVuIGJsZWliZW4KKyAgICAgICAgICBmb3IgKCBpID0gc2l6ZW9mKG5hbWVzKTsgaS0tOyApCisgICAgICAgICAgICBpZiAoIF9pbGxlZ2FsX2Nsb3N1cmUocHJvW25hbWVzW2ldLCBGX1ZBTFVFXSkgfHwKKyAgICAgICAgICAgICAgICAgX2lsbGVnYWxfY2xvc3VyZShwcm9bbmFtZXNbaV0sIEZfUVVFUllfTUVUSE9EXSkgfHwKKyAgICAgICAgICAgICAgICAgX2lsbGVnYWxfY2xvc3VyZShwcm9bbmFtZXNbaV0sIEZfU0VUX01FVEhPRF0pICkKKyAgICAgICAgICAgICAgbV9kZWxldGUoIHBybywgbmFtZXNbaV0gKTsKKyAgICAgICAgICAKKyAgICAgICAgICBvYmotPlNldFByb3BlcnRpZXMocHJvKTsKKyAgICAgICAgICBtc2cgKz0gIiwgUHJvcGVydGllcyBnZXNldHp0IjsKKyAgICAgICAgfQorICAgICAgICAvLyBXZW5uIGtlaW4gVVBEX0MsIHdpcmQgZ2dmLiBkYXMgRXJnZWJuaXMgdm9uIENvbmZpZ3VyZSgpIHdpZWRlcgorICAgICAgICAvLyB1ZWJlcmdlYmVuLgorICAgICAgICBlbHNlIGlmIChyZXN0b3JlX2NvbmZpZykKKyAgICAgICAgeworICAgICAgICAgIGludCBjb25mX3JlczsKKyAgICAgICAgICBpZiAoIWNhdGNoKGNvbmZfcmVzPShpbnQpb2JqLT5Db25maWd1cmUoY29uZmlnZGF0YSk7IHB1Ymxpc2gpCisgICAgICAgICAgICAgICYmIGNvbmZfcmVzID09IDEpCisgICAgICAgICAgeworICAgICAgICAgICAgbXNnICs9ICIsIChyZS0pa29uZmlndXJpZXJ0IjsKKyAgICAgICAgICB9CisgICAgICAgICAgZWxzZQorICAgICAgICAgIHsKKyAgICAgICAgICAgIG1zZyArPSAiLCAoUmUtKUtvbmZpZ3VyYXRpb24gZmVobGdlc2NobGFnZW4iOworICAgICAgICAgICAgaWYgKGZsYWdzICYgVVBEX0NPTkYpCisgICAgICAgICAgICAgIHByaW50ZigidXBkOiBEYXRlbiB2b24gJXMga29ubnRlbiBuaWNodCByZWtvbmZpZ3VyaWVydCB3ZXJkZW46ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICIlT1xuIiwgZmlsZSwgY29uZmlnZGF0YSk7CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChlbnYpCisgICAgICAgIHsKKyAgICAgICAgICBpZiAoIG9iai0+bW92ZSggZW52LCBOT19DSEVDSyApIDw9IDAgKQorICAgICAgICAgICAgcHJpbnRmKCAidXBkOiAvJU8ga29ubnRlIG5pY2h0IGluIC8lTyB6dXJ1ZWNrYmV3ZWd0IHdlcmRlblxuIiwKKyAgICAgICAgICAgICAgICAgICAgb2JqLCBlbnYgKTsKKyAgICAgICAgICBlbHNlCisgICAgICAgICAgICBtc2cgKz0gIiwgYmV3ZWd0IjsKKyAgICAgICAgfQorICAgICAgICBpZiAoaT1zaXplb2YoaW52KSkKKyAgICAgICAgeworICAgICAgICAgIHdoaWxlKGktLSkgaWYgKGludltpXSkgaW52W2ldLT5tb3ZlKG9iaiwgTk9fQ0hFQ0sgKTsKKyAgICAgICAgICBtc2cgKz0gIiwgSW5oYWx0IHp1cnVlY2tiZXdlZ3QiOworICAgICAgICB9CisgICAgICB9CisgICAgICBlbHNlIAorICAgICAgICByZXR1cm4gcHJpbnRmKCAidXBkOiAlczogJXMiLCBmaWxlLCBlcnIgKSwgUkVUX0ZBSUw7CisgICAgfQorICB9CisgIGVsc2UgCisgICAgaWYgKCAhX3VwZGF0ZShmaWxlLCAwLCBmbGFncykgJiYgKGZsYWdzICYgKFVQRF9MfFVQRF9MT0FEKSkgKQorICAgICAgaWYgKCAhX3JlbG9hZCggYmx1ZSwgaW5zdCwgZmxhZ3MsICZlcnIgKSApCisgICAgICAgIHJldHVybiBwcmludGYoICIlczogJXM6ICVzIiwgKGZsYWdzJlVQRF9MT0FEPyJsb2FkIjoidXBkIiksZmlsZSwgZXJyICksCisgICAgICAgICAgUkVUX0ZBSUw7CisgICAgICBlbHNlCisgICAgICAgIG1zZyArPSAiZ2VsYWRlbiI7CisgIAorICBpZiAoIHNpemVvZihtc2cpJiYhKGZsYWdzJlVQRF9TJiZyZWN1cnNpdmUpICkKKyAgICBwcmludGYoIiVzOiAlczogJXMuXG4iLChmbGFncyZVUERfTE9BRD8ibG9hZCI6InVwZCIpLGZpbGUsbXNnKTsKKyAgcmV0dXJuIFJFVF9PSzsKK30KKworLy8KKy8vIF91cGQ6IE9iamVrdGUgbGFkZW4sIHplcnN0b2VyZW4gdW5kIGFrdHVhbGlzaWVyZW4KKy8vCisKK3N0YXRpYyBpbnQgX3VwZChzdHJpbmcgY21kbGluZSkKK3sKKyAgaW50IGZsYWdzOworICBtaXhlZCAqYXJnczsKKworICBjbWRsaW5lPV91bnBhcnNlZF9hcmdzKCk7CisgIGFyZ3M9cGFyc2VhcmdzKGNtZGxpbmUsJmZsYWdzLFVQRF9PUFRTLDEpOworICBpZihmbGFncz09LTF8fCFzaXplb2YoYXJncykpCisgICAgcmV0dXJuIFVTQUdFKCJ1cGQgWy0iK1VQRF9PUFRTKyJdIDxkYXRlaT4gWzxkYXRlaT4gLi5dIik7CisgIGlmICgoZmxhZ3MgJiBVUERfQykgJiYgKGZsYWdzICYgVVBEX0NPTkYpKQorICB7CisgICAgcHJpbnRmKCJ1cGQ6IC1jIHVuZCAtQyBnbGVpY2h6ZWl0aWcgd2VyZGVuIG5pY2h0IHVudGVyc3R1ZXR6dC5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIGFyZ3M9ZmlsZV9saXN0KGFyZ3MsTU9ERV9VUEQsMCwiLyIpOworICBpZighc2l6ZW9mKGFyZ3MpKSByZXR1cm4gcHJpbnRmKCJ1cGQ6IEtlaW5lIHBhc3NlbmRlIERhdGVpIGdlZnVuZGVuIVxuIiksMTsKKworICBhcmdzPW1hcChhcmdzLCg6ICQxW0ZVTExOQU1FXSA6KSktKHswfSk7CisKKyAgaWYoIXNpemVvZihhcmdzKSkKKyAgeworICAgIHByaW50ZigidXBkOiBWZXJ6ZWljaG5pc3NlIGtvZW5uZW4gbmljaHQgYWt0dWFsaXNpZXJ0IHdlcmRlbiFcbiIpOworICAgIHJldHVybiAxOworICB9CisgIGFzeW5jaHJvbihhcmdzLCMnX21ha2UsZmxhZ3MsMCwwKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vCisvLyBfbG9hZDogT2JqZWt0ZSBsYWRlbgorLy8KKworc3RhdGljIGludCBfbG9hZChzdHJpbmcgY21kbGluZSkKK3sKKyAgaW50IGZsYWdzOworICBtaXhlZCAqYXJnczsKKworICBjbWRsaW5lPV91bnBhcnNlZF9hcmdzKCk7CisgIGFyZ3M9cGFyc2VhcmdzKGNtZGxpbmUsJmZsYWdzLCIiLDEpOworICBpZihmbGFncz09LTF8fCFzaXplb2YoYXJncykpCisgICAgcmV0dXJuIFVTQUdFKCJsb2FkIDxkYXRlaT4gWzxkYXRlaT4gLi5dIik7CisgIGFyZ3M9ZmlsZV9saXN0KGFyZ3MsTU9ERV9VUEQsMCwiLyIpOworICBpZighc2l6ZW9mKGFyZ3MpKSByZXR1cm4gcHJpbnRmKCJsb2FkOiBLZWluZSBwYXNzZW5kZSBEYXRlaSBnZWZ1bmRlbiFcbiIpLDE7CisgIGFyZ3M9bWFwKGFyZ3MsKDogKCgkMVtGSUxFU0laRV0hPS0yfHxmaW5kX29iamVjdCgkMVtGVUxMTkFNRV0pKT8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgJDFbRlVMTE5BTUVdOjApIDopKS0oezB9KTsKKworICBpZighc2l6ZW9mKGFyZ3MpKQorICAgIHJldHVybiBwcmludGYoImxvYWQ6IFZlcnplaWNobmlzc2Uga29lbm5lbiBuaWNodCBnZWxhZGVuIHdlcmRlbiFcbiIpLDE7CisgIGFzeW5jaHJvbihhcmdzLCMnX21ha2UsVVBEX0xPQUQsMCwwKTsKKyAgcmV0dXJuIDE7Cit9CmRpZmYgLS1naXQgYS9zdGQvc2hlbGxzL29yYy5jIGIvc3RkL3NoZWxscy9vcmMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NWM3M2Y2Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3NoZWxscy9vcmMuYwpAQCAtMCwwICsxLDIwMyBAQAorI3ByYWdtYSBzdHJvbmdfdHlwZXMsc2F2ZV90eXBlcworCitpbmhlcml0ICJzdGQvcGxheWVyL2Jhc2UiOworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGF0dHJpYnV0ZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxoZWFsdGguaD4KKyNpbmNsdWRlIDxuZXdfc2tpbGxzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxjb21iYXQuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8ZGVmdWVsLmg+CisKKy8qCisgKiBPcmtzOgorICogT3JrcyBzaW5kIGVpZ2VudGxpY2ggYm9lc2UgdW5kIGJsdXRydWVuc3RpZywgd2FzIGF1Y2ggb2Z0IGdlbnVnIHp1bSAKKyAqIFZvcnNjaGVpbiB0cml0dCA6KSBXZW5uIGVpbiBPcmsgenUgaGVmdGlnIGZvcnNjaHQsIHF1ZW5nZWx0IGVyIHJ1bSAKKyAqIHVuZCB3ZWlnZXJ0IHNpY2gsIGJpcyBlciBuaWNodCB3aWVkZXIgZWluIGJpc3NjaGVuIEJsdXQgdmVyc3ByaXR6dAorICogaGF0LAorKi8gCisjZGVmaW5lIEZfTUFYIDUwMAorI2RlZmluZSBGX0RFRyAzIAorI2RlZmluZSBOT19FWEFNSU5FICh7IFwKKyAgICAiRHUga251cnJzdDogSWNoIHdpbGwgQmx1dCwga2VpbmUgQmx1ZW1jaGVuLiIsIFwKKyAgICAiRHUgZ3J1bW1lbHN0OiBCaW4gaWNoIGVpbiBGb3JzY2hlciwgb2RlciB3YXM/IiBcCisgICAgfSkKKworc3RhdGljIGludCBmX2NudCwgZl9kZWc7CisKK2ludCAKK1F1ZXJ5RkNudCgpIHsKKyAgcmV0dXJuIGZfY250OworfQorCitpbnQgCitTZXRGQ250KGludCBmYykgeworICBpZihmYyA+IC0xICYmIGZjIDwgRl9NQVgpCisgICAgZl9jbnQgPSBmYzsKKyAgcmV0dXJuIGZfY250OworfQorICAKK2ludAorUXVlcnlGRGVnKCkgeworICByZXR1cm4gZl9kZWc7Cit9CisKK3ZvaWQgCitjcmVhdGUoKSB7CisgIGlmICghY2xvbmVwKCkgfHwgb2JqZWN0X25hbWUodGhpc19vYmplY3QoKSkgPT0gX19GSUxFX19bMC4uPDNdKSB7CisgICAgICBzZXRfbmV4dF9yZXNldCgtMSk7ICAgIAorICAgICAgcmV0dXJuOworICB9CisKKyAgbWl4ZWQgcmVzOworCisgIGJhc2U6OmNyZWF0ZSgpOworCisgIGZfY250PTA7CisgIGZfZGVnPUZfREVHOworICAKKyAgU2V0RGVmYXVsdEhvbWUoIi9kL3ZsYW5kL21vcmdvdGgvcm9vbS9jaXR5L3JhdGhhbGxlIik7CisgIFNldERlZmF1bHRQcmF5Um9vbSgiL2QvdmxhbmQvbW9yZ290aC9yb29tL2NpdHkvYzA2MDYiKTsKKyAgU2V0UHJvcChQX0FUVFJJQlVURVNfT0ZGU0VUUywoW0FfU1RSOjMsQV9JTlQ6LTEsQV9DT046Ml0pKTsKKyAgLyogS2xlaW5lIGFlaCBncm9zc2UgTXVza2VscGFrZXRlICovCisgIFNldFByb3AoUF9TS0lMTF9BVFRSSUJVVEVfT0ZGU0VUUywoW1NBX0RBTUFHRToxMTBdKSk7CisgIFNldFByb3AoUF9BVkVSQUdFX1NJWkUsMTk1KTsKKyAgU2V0UHJvcChQX0FWRVJBR0VfV0VJR0hULDEyNTAwMCk7IC8vIHppZW1saWNoIHNjaHdlciwgdmllbGUgTXVza2VsbgorICBTZXRQcm9wKFBfTUFURVJJQUxfS05PV0xFREdFLChbTUFUR1JPVVBfREVBRDo2MCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BVEdST1VQX0JJTzo0MCwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQVRHUk9VUF9FTEVNRU5UQUw6IDIwLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1BVF9CTE9PRDoxMDBdKSk7CisgIFNldFByb3AoUF9DSEFOTkVMUywgUXVlcnlQcm9wKFBfQ0hBTk5FTFMpICsgKHsiVXJ1ay1IYWkifSkpOworICBTZXRQcm9wKFBfUkVTSVNUQU5DRV9TVFJFTkdUSFMsCisJICAoWyAKKyAgICAgRFRfRklSRSA6IC0wLjIsCisgICAgIERUX0hPTFkgOjAuMywKKyAgICAgRFRfVU5IT0xZIDogLTAuMiwKKwkgICBEVF9BQ0lEIDogMC4yIF0pKTsKKworICBTZXRQcm9wKFBfTUFYX0ZPT0QsMTEwKTsKKyAgU2V0UHJvcChQX01BWF9EUklOSywxMTApOworICBTZXRQcm9wKFBfTUFYX0FMQ09IT0wsMTUwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9MSU1JVF9GT09ELDUwKTsKKyAgU2V0UHJvcChQX0RFRlVFTF9MSU1JVF9EUklOSyw3MCk7CisgIFNldFByb3AoUF9ERUZVRUxfVElNRV9GT09ELDMwMCk7CisgIFNldFByb3AoUF9ERUZVRUxfVElNRV9EUklOSyw0MDApOworICBTZXRQcm9wKFBfREVGVUVMX0FNT1VOVF9GT09ELDAuNCk7CisgIFNldFByb3AoUF9ERUZVRUxfQU1PVU5UX0RSSU5LLDAuMzUpOworCisgIC8qIFNQIHJlZ2VuZXJpZXJlbiBzaWUgbmljaCBnYW56IHNvIHNjaG5lbGwsIGRhZnVlciBzaW5kIHNpZQorICAgKiBlaW4gYmlzY2hlbiBzY2huZWxsZXIgYmVpIEdpZnQgdW5kIEZ1dHRlciAqLworICBTZXRQcm9wKFBfU1BfREVMQVksSEVBTF9ERUxBWSsxKTsKKyAgU2V0UHJvcChQX1BPSVNPTl9ERUxBWSxQT0lTT05fREVMQVktMSk7CisgIFNldFByb3AoUF9GT09EX0RFTEFZLEZPT0RfREVMQVktMSk7CisKKyAgU2V0UHJvcChQX01BR0lDX1JFU0lTVEFOQ0VfT0ZGU0VULAorICAgICAgICAgIChbIE1UX0FOR1JJRkYgOiA1MDAsCisgICAgICAgIAkgICBNVF9JTExVU0lPTiA6IC0yNTAsCisgICAgICAgICAgICAgTVRfQkVIRVJSU0NIVU5HIDogLTI1MCwKKyAgICAgICAgCSAgIE1UX1ZFUldBTkRMVU5HIDogNTAwIF0pKTsKKworCisgIGlmKCEocmVzPVF1ZXJ5UHJvcChQX0hBTkRTKSkgfHwgIXBvaW50ZXJwKHJlcykgfHwgKHNpemVvZihyZXMpPDMpKQorICAgIHJlcz0oeyIgbWl0IHN0YXJrZW4gSGFlbmRlbiIsMzUsKHtEVF9CTFVER0VPTiwgRFRfUklQfSkgfSk7CisgIFNldFByb3AoUF9IQU5EUyxyZXMpOworICAvKiBPcmtzIGhhYmVuIGRpY2tlIEhhdXQgKi8KKyAgU2V0UHJvcChQX0JPRFksMjApOworCisgIC8qIEdyb2Vzc2Ugd2lyZCBudXIgZWlubWFsIGdlc2V0enQgKi8KKyAgaWYoIVF1ZXJ5UHJvcChQX1NJWkUpKXsKKyAgICBTZXRQcm9wKFBfU0laRSwxODArcmFuZG9tKDMxKSk7CisgICAgU2V0KFBfU0laRSxTQVZFLEZfTU9ERV9BUyk7CisgIH0KKworICAvKiBEaXRvIEdld2ljaHQgKi8KKyAgaWYoIVF1ZXJ5UHJvcChQX1dFSUdIVCkgfHwgKFF1ZXJ5UHJvcChQX1dFSUdIVCkgPT0gNzUwMDApKXsKKyAgICBTZXRQcm9wKFBfV0VJR0hULDEwMDAwMCtyYW5kb20oMjUwMDEpK3JhbmRvbSgyNTAwMSkpOworICAgIFNldChQX1dFSUdIVCxTQVZFLEZfTU9ERV9BUyk7CisgIH0KK30KKworc3RyaW5nIAorX3F1ZXJ5X3JhY2UoKSB7CisgIHJldHVybiAiT3JrIjsKK30KKworc3RyaW5nIAorX3F1ZXJ5X3JlYWxfcmFjZSgpIHsKKyAgcmV0dXJuICJPcmsiOworfQorCitzdHJpbmcgCitfcXVlcnlfcmFjZWRlc2NyKCkgeworICByZXR1cm4gYnJlYWtfc3RyaW5nKCJFaW4gT3JrLiBEaWUgYnJ1dGFsZSBNYWNodCBkZXMgQm9lc2VuLiBFaW4gIgorICAgICAgImVyYml0dGVydGVyIEthZW1wZmVyLCBvaG5lIEZ1cmNodCB2b3IgZGVtIFRvZC4gU28gc3RlbGxzdCBEdSAiCisgICAgICAiRGlyIGVpbmVuIE9yayB2b3IuXG5EaWVzZSBPcmtzIHNlaGVuIHZpZWxsZWljaHQgYXVzc2VybGljaCBzbyAiCisgICAgICAiYXVzOiBFaW5lIGRpY2tlIHVuZCBkdW5rbGUsIGxlZGVyYXJ0aWdlIEhhdXQsIGRpZSBzaWNoZXIgIgorICAgICAgImVpbmlnZXMgYW4gU2NobGFlZ2VuIGFiaGFlbHQuIExhbmdlIEVja3phZWhuZSwgZGllIHNpY2hlciBib2VzZSAiCisgICAgICAiV3VuZGVuIHJlaXNzZW4ga29lbm5lbi5cbkR1IHNwdWVyc3QsIGRhc3MgZGllc2UgT3JrcyBoaWVyIGVpbiAiCisgICAgICAid2VuaWcgYW5kZXJzIHNpbmQuIElocmVuIERyYW5nIG5hY2ggZGVtIEJsdXQgaWhyZXIgRmVpbmRlIHNjaGVpbmVuICIKKyAgICAgICJzaWUgcmVjaHQgZ3V0IHVudGVyIEtvbnRyb2xsZSB6dSBoYWJlbiwgZGllIG1laXN0ZSBaZWl0IHp1bWluZGVzdC4gIgorICAgICAgIlNpZSBzaW5kIGluIGRlciBMYWdlLCBmcmllZGxpY2ggendpc2NoZW4gZGVuIGFuZGVyZW4gUmFzc2VuIHp1ICIKKyAgICAgICJ3YW5kZWxuLiBEZW5ub2NoIHNpbmQgdm9yIGFsbGVtIGRpZSBVcnVrLUhhaSBPcmtzIGFscyBHZWduZXIgbmljaHQgIgorICAgICAgInp1IHVudGVyc2NoYWV0emVuLCBzb2xsdGUgZXMgZG9jaCBlaW5tYWwgenUgZWluZW0gS2FtcGYga29tbWVuLiIsCisgICAgICA3OCwwLEJTX0xFQVZFX01ZX0xGUyk7Cit9CisKK2ludCAKK1F1ZXJ5QWxsb3dTZWxlY3QoKSB7IAorICByZXR1cm4gMTsgCit9CisKK3N0cmluZyAKKypfcXVlcnlfcmFjZXN0cmluZygpIHsKKyAgaWYgKFF1ZXJ5UHJvcChQX0dFTkRFUik9PUZFTUFMRSkKKyAgICByZXR1cm4gKHsiT3JraW4iLCJPcmtpbiIsIk9ya2luIiwiT3JraW4ifSk7CisgIHJldHVybiAoeyJPcmsiLCJPcmtlcyIsIk9yayIsIk9yayJ9KTsKK30KKworc3RyaW5nIAorX3F1ZXJ5X2RlZmF1bHRfZ3VpbGQoKXsKKyAgcmV0dXJuICJ1cnVraGFpIjsKK30KKworbWl4ZWQgCitSYWNlRGVmYXVsdChzdHJpbmcgYXJnKSB7CisgIGlmICghYXJnKQorICAgIHJldHVybiAwOworICBzd2l0Y2goYXJnKSB7CisgICAgY2FzZSBQX0hBTkRTIDoKKyAgICAgIHJldHVybiAoeyIgbWl0IHN0YXJrZW4gSGFlbmRlbiIsMzUsKHtEVF9CTFVER0VPTixEVF9SSVB9KSB9KTsKKyAgICBjYXNlIFBfQk9EWSA6CisgICAgICByZXR1cm4gMjU7CisgIH0KKyAgcmV0dXJuIGJhc2U6OlJhY2VEZWZhdWx0KGFyZyk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGhlYXJ0X2JlYXQoKSB7CisgIDo6aGVhcnRfYmVhdCgpOworCisgIGlmKGZfY250ID4gMCAmJiAhLS1mX2RlZykgeworICAgIGZfY250LS07CisgICAgZl9kZWc9Rl9ERUc7CisgIH0KK30KKwordm9pZAorQXR0YWNrKG9iamVjdCBlbmVteSkgeworICBpZihmX2NudCA+IDApCisgICAgZl9jbnQtLTsKKyAgcmV0dXJuIDo6QXR0YWNrKGVuZW15KTsKK30KKwordmFyYXJncyBpbnQgCitfZXhhbWluZShzdHJpbmcgc3RyLCBpbnQgbW9kZSkgeworCisgIGlmKCsrZl9jbnQgPiBGX01BWCkgeworICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksYnJlYWtfc3RyaW5nKE5PX0VYQU1JTkVbcmFuZG9tKHNpemVvZihOT19FWEFNSU5FKSldLDc4KSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgcmV0dXJuIDo6X2V4YW1pbmUoc3RyLG1vZGUpOworfQpkaWZmIC0tZ2l0IGEvc3RkL3NoZWxscy90ZXN0aWUuYyBiL3N0ZC9zaGVsbHMvdGVzdGllLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMThjNDJhZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zaGVsbHMvdGVzdGllLmMKQEAgLTAsMCArMSw2IEBACisjcHJhZ21hIHN0cm9uZ190eXBlcyxzYXZlX3R5cGVzCisKK2luaGVyaXQgIi9zdGQvc2hlbGxzL2h1bWFuIjsKKworaW50IFF1ZXJ5QWxsb3dTZWxlY3QoKSB7IHJldHVybiAwOyB9CisKZGlmZiAtLWdpdCBhL3N0ZC9zaG9wLmMgYi9zdGQvc2hvcC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQ0Y2Y2OTAKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvc2hvcC5jCkBAIC0wLDAgKzEsMzggQEAKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC9yb29tIjsKK2luaGVyaXQgIi9zdGQvcm9vbS9zaG9wIjsKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgaWYgKG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpID09IF9fRklMRV9fWzAuLjwzXSkKKyAgeworICAgIHNldF9uZXh0X3Jlc2V0KC0xKTsKKyAgICByZXR1cm47CisgIH0KKyAgcm9vbTo6Y3JlYXRlKCk7CisgIHNob3A6OmNyZWF0ZSgpOworCisgIFNldFByb3AoUF9MSUdIVCwgMSk7CisgIFNldFByb3AoUF9JTkRPT1JTLDEpOworICBTZXRQcm9wKFBfSU5UX1NIT1JULCAiU3RkTGFkZW4iKTsKKyAgU2V0UHJvcChQX0lOVF9MT05HLAorICAgIkRlciBNYWdpZXIsIGRlciBkaWVzZW4gTGFkZW4gZXJzY2h1ZiwgZmFuZCBrZWluZSBCZXNjaHJlaWJ1bmcgZGFmdWVyLlxuIik7CisgIEFkZEl0ZW0oIi9vYmovZW50c29yZyIsUkVGUkVTSF9SRU1PVkUpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKwordm9pZCByZXNldCgpCit7CisgIHJvb206OnJlc2V0KCk7CisgIHNob3A6OnJlc2V0KCk7Cit9CmRpZmYgLS1naXQgYS9zdGQvc3BlbGxib29rLmMgYi9zdGQvc3BlbGxib29rLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjRmODI0ZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC9zcGVsbGJvb2suYwpAQCAtMCwwICsxLDc4NSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHNwZWxsYm9vay5jIC0tIEdydW5kbGVnZW5kZSBGdW5rdGlvbmVuIGZ1ZXIgWmF1YmVyc3BydWVjaGUKKy8vCisvLyAkSWQ6IHNwZWxsYm9vay5jIDkxNDIgMjAxNS0wMi0wNCAyMjoxNzoyOVogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIG5vX3NoYWRvdworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCisvLyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCitpbmhlcml0ICIvc3RkL3RoaW5nIjsKK2luaGVyaXQgIi9zdGQvcmVzdHJpY3Rpb25fY2hlY2tlciI7Citpbmhlcml0ICIvc3RkL3BsYXllci9wa2xvZyI7CisKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKyNpbmNsdWRlIDxzcGVsbGJvb2suaD4KKyNkZWZpbmUgTUUgdGhpc19vYmplY3QoKQorCit2b2lkIGNyZWF0ZSgpIHsKKyAgc2V0ZXVpZChnZXR1aWQoKSk7CisgIC8vIGRpZXNlIFByb3Agc29sbHRlIHZvbiBhdXNzZW4gbmljaHQgZGlyZWt0IGdlYWVuZGVydCB3ZXJkZW4ga29lbm5lbi4KKyAgU2V0KFBfU0JfU1BFTExTLChbXSksRl9WQUxVRSk7CisgIFNldChQX1NCX1NQRUxMUyxQUk9URUNURUQsRl9NT0RFX0FTKTsKKworICA6OmNyZWF0ZSgpOworfQorCittYXBwaW5nIF9xdWVyeV9zYl9zcGVsbHMoKSB7CisgICAgLy8gS29waWUgbGllZmVybiwgZGEgc29uc3QgdmVyc2VoZW50bGljaCBzY2huZWxsIGVpbmUgQWVuZGVydW5nIGRlcworICAgIC8vIG9yaWdpbmFsZW4gTWFwcGluZ3MgaGllciBwYXNzaWVyZW4ga2Fubi4KKyAgICByZXR1cm4oZGVlcF9jb3B5KFF1ZXJ5KFBfU0JfU1BFTExTLCBGX1ZBTFVFKSkpOworfQorCittYXBwaW5nIFF1ZXJ5U3BlbGwoc3RyaW5nIHNwZWxsKSB7CisgIG1hcHBpbmcgc3BpOworCisgIC8vUXVlcnktTWV0aG9kZSB1bWdlaGVuLCBkYW1pdCBudXIgZWluIFNwZWxsbWFwcGluZyBrb3BpZXJ0IHdlcmRlbiBtdXNzIHVuZAorICAvL25pY2h0IGRhcyBnYW56ZW4gTWFwcGluZyBtaXQgYWxsZW4gU3BlbGxzLgorICBpZiAoIXNwZWxsCisgICAgICB8fCAhKHNwaT1RdWVyeShQX1NCX1NQRUxMUykpCisgICAgICB8fCAhKHNwaT1zcGlbc3BlbGxdKSkKKyAgICByZXR1cm4gMDsKKyAgcmV0dXJuIGRlZXBfY29weShzcGkpOworfQorCit2YXJhcmdzIGludAorQWRkU3BlbGwoc3RyaW5nIHZlcmIsIGludCBrb3N0ZW4sIG1peGVkIHNraSkgeworICBpbnQgbGV2ZWw7CisgIG1hcHBpbmcgc3BlbGxzOworCisgIGlmICghdmVyYiB8fCBrb3N0ZW48MCkKKyAgICByZXR1cm4gMDsKKyAgCisgIHZlcmI9bG93ZXJfY2FzZSh2ZXJiKTsKKyAgbGV2ZWw9KGludHAoc2tpKSk/c2tpOjA7CisKKyAgaWYgKCFtYXBwaW5ncChza2kpKSBza2k9KFtdKTsKKyAgLy8gWnVyIFNpY2hlcmhlaXQgZWluZSBLb3BpZSBtYWNoZW4sIHdlciB3ZWlzcywgd2FzIGRhIHVlYmVyZ2ViZW4gd2lyZCwgYnp3LgorICAvLyB3YXMgZGVyIFNldHplbmRlIG1pdCBza2kgaGludGVyaGVyIG5vY2ggbWFjaHQuCisgIGVsc2Ugc2tpPWRlZXBfY29weShza2kpOworCisgIHNraT1BZGRTa2lsbE1hcHBpbmdzKFF1ZXJ5UHJvcChQX0dMT0JBTF9TS0lMTFBST1BTKSxza2kpOworICBza2krPShbU0lfU1BFTExDT1NUOmtvc3Rlbl0pOworICAvLyBTSV9TUEVMTC1TdWJtYXBwaW5nIGhpbnp1ZnVlZ2VuLCB3ZW5uIG5pY2h0IGRhLgorICBpZiAoIW1lbWJlcihza2ksU0lfU1BFTEwpKQorICAgICAgc2tpKz0oW1NJX1NQRUxMOihbXSkgXSk7CisgIC8vIHNraVtTSV9TUEVMTF1bU1BfTkFNRV0gZXJnYWVuemVuLCBnZ2YuIGF1cyBza2kgdmVyc2NoaWViZW4KKyAgaWYgKCFzdHJpbmdwKHNraVtTSV9TUEVMTF1bU1BfTkFNRV0pICYmIHN0cmluZ3Aoc2tpW1NQX05BTUVdKSkgeworICAgICAgc2tpW1NJX1NQRUxMXVtTUF9OQU1FXSA9IHNraVtTUF9OQU1FXTsKKyAgICAgIG1fZGVsZXRlKHNraSwgU1BfTkFNRSk7CisgIH0KKyAgZWxzZSBpZiAoIXN0cmluZ3Aoc2tpW1NJX1NQRUxMXVtTUF9OQU1FXSkpIHsKKyAgICAgIHNraVtTSV9TUEVMTF1bU1BfTkFNRV0gPSB2ZXJiOworICB9CisgIGlmIChzdHJpbmdwKHNraVtTUF9OQU1FXSkpIHsKKyAgICAgIG1fZGVsZXRlKHNraSwgU1BfTkFNRSk7CisgIH0KKworICBpZiAobGV2ZWwpCisgICAgc2tpPUFkZFNraWxsTWFwcGluZ3Moc2tpLChbU0lfU0tJTExSRVNUUl9MRUFSTjooW1BfTEVWRUw6bGV2ZWxdKV0pKTsKKyAgCisgIC8vIEFiZnJhZ2UgcGVyIFF1ZXJ5KCksIHVtIGRhcyBNYXBwaW5nIGFscyBSZWZlcmVueiwgbmljaHQgYWxzIEtvcGllIHp1CisgIC8vIGJla29tbWVuLCBkYXMgc3BhcnQgZXR3YXMgWmVpdC4KKyAgaWYgKCEoc3BlbGxzPVF1ZXJ5KFBfU0JfU1BFTExTLEZfVkFMVUUpKSkgeworICAgIHNwZWxscz0oW10pOworICAgIFNldFByb3AoUF9TQl9TUEVMTFMsc3BlbGxzKTsKKyAgfQorICAvLyBTcGVsbCBzZXR6ZW4uLi4KKyAgc3BlbGxzW3ZlcmJdPXNraTsKKyAgLy8gU2V0KCkgbmljaHQgbm9ldGlnLCBkYSBRdWVyeSgpIGFuIHNwZWxsIGRhcyBPcmlnaW5hbG1hcHBpbmcgZ2VsaWVmZXJ0IGhhdAorICAvLyB1bmQgZGllc2VzIGJlcmVpdHMgamV0enQgZ2VhZW5kZXJ0IHd1cmRlLiA7LSkKKyAgLy9TZXQoUF9TQl9TUEVMTFMsc3BlbGxzKyhbdmVyYjpza2ldKSxGX1ZBTFVFKTsKKworICAvLyBoYXQgd29obCBnZWtsYXBwdC4uLgorICByZXR1cm4oMSk7Cit9CisKK2ludAorVHJ5QXR0YWNrU3BlbGwob2JqZWN0IHZpY3RpbSwgaW50IGRhbWFnZSwgbWl4ZWQgZHR5cGVzLAorICAgICAgICAgICAgICAgbWl4ZWQgaXNfc3BlbGwsIG9iamVjdCBjYXN0ZXIsIG1hcHBpbmcgc2luZm8pIHsKKyAgbWl4ZWQgbm9fYXR0YWNrOworICBpbnQgbm9tYWc7CisKKyAgaWYgKG5vX2F0dGFjayA9IChtaXhlZCl2aWN0aW0tPlF1ZXJ5UHJvcChQX05PX0FUVEFDSykpIHsKKyAgICBpZiAoc3RyaW5ncChub19hdHRhY2spKQorICAgICAgd3JpdGUobm9fYXR0YWNrKTsKKyAgICBlbHNlCisgICAgICB3cml0ZSh2aWN0aW0tPk5hbWUoV0VSLDEpKyIgbGFlc3N0IHNpY2ggbmljaHQgYW5ncmVpZmVuIVxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKHZpY3RpbS0+UXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgd3JpdGUodmljdGltLT5OYW1lKFdFUiwxKSsiIGlzdCBlaW4gR2Vpc3QhXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIGRhbWFnZT0oZGFtYWdlKihpbnQpY2FzdGVyLT5RdWVyeVNraWxsQXR0cmlidXRlKFNBX0RBTUFHRSkpLzEwMDsKKworICAvLyBnZ2YuIExvZ2dlbiB2b24gUEstVmVyc3VjaGVuIHVuZCBnZ2YuIGF1c3NlcmRlbSBBbmdyaWZmIGFiYnJlY2hlbi4KKyAgLy8gQlRXOiBBdWZydWYgdm9uIEluc2VydEVuZW15KCkgZ2lidCAwIHp1cnVlY2ssIHdlbm4gZGVyIEdlZ25lciBuaWNodAorICAvLyBlaW5nZXRyYWdlbiB3dXJkZS4gQWxsZXJkaW5ncyB0dXQgZXMgZGFzIGF1Y2gsIHdlbm4gZGVyIEdlZ25lciBzY2hvbgorICAvLyBGZWluZCB3YXIuIERhaGVyIG11c3Mgbm9jaCBnZXBydWVmdCB3ZXJkZW4sIG9iIG5hY2ggZGVtIEluc2VydEVuZW15KCkgZGllCisgIC8vIGJlaWRlbiBTcGllbGVyIEZlaW5kZSBzaW5kLiBXZW5uIG5pY2h0LCB3aXJkIGRlciBTcGVsbCBhdWNoIGFiZ2Vicm9jaGVuCisgIC8vIHVuZCBlaW5lIE1lbGR1bmcgYXVzZ2VnZWJlbi4KKyAgaWYgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoY2FzdGVyKSAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHZpY3RpbSkKKyAgICAgICYmIENoZWNrUGxheWVyQXR0YWNrKGNhc3RlciwgdmljdGltLCAKKyAgICAgICAgc3ByaW50ZigiU3BlbGxib29rOiAlTywgU3BlbGw6ICVPXG4iLAorICAgICAgICAgICAgICAgIG9iamVjdF9uYW1lKHRoaXNfb2JqZWN0KCkpLAorICAgICAgICAgICAgICAgICgobWFwcGluZ3Aoc2luZm8pICYmIGlzX3NwZWxsKSA/IHNpbmZvW1NQX05BTUVdICA6ICIiKSkpCisgICAgICAmJiAhY2FzdGVyLT5Jc0VuZW15KHZpY3RpbSkKKyAgICAgICYmICFjYXN0ZXItPkluc2VydEVuZW15KHZpY3RpbSkKKyAgICAgICkKKyAgeworICAgIHRlbGxfb2JqZWN0KE1FLCAiRWluIGdvZXR0bGljaGVyIEVpbmZsdXNzIHNjaHVldHp0IERlaW5lbiBHZWduZXIuXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorCisgIG5vbWFnPShpbnQpdmljdGltLT5RdWVyeVByb3AoUF9OT01BR0lDKTsKKyAgaWYgKChzaW5mb1tTSV9OT01BR0lDXSA8IG5vbWFnKSAmJgorICAgICAgbm9tYWcqMTAwID4gcmFuZG9tKDEwMCkqKGludCljYXN0ZXItPlF1ZXJ5U2tpbGxBdHRyaWJ1dGUoU0FfRU5FTVlfU0FWRSkpIHsKKyAgICBwcmludGYoIiVzIHdlaHJ0IERlaW5lbiBaYXViZXIgYWIuXG4iLCBjYXBpdGFsaXplKChzdHJpbmcpdmljdGltLT5uYW1lKFdFUiwgMSkpKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBlbHNlIHsKKyAgICByZXR1cm4gKGludCl2aWN0aW0tPkRlZmVuZChkYW1hZ2UsIGR0eXBlcywgaXNfc3BlbGwsIGNhc3Rlcik7CisgIH0KK30KKwordmFyYXJncyBpbnQKK1RyeURlZmF1bHRBdHRhY2tTcGVsbChvYmplY3QgdmljdGltLCBvYmplY3QgY2FzdGVyLCBtYXBwaW5nIHNpbmZvLCAKKyAgICAgICAgICAgICAgICAgICAgICBtaXhlZCBzaV9zcGVsbCkgeworICBvYmplY3QgdGVhbTsKKyAgaW50IHJvdzsKKyAgCisgIGlmICghc2lfc3BlbGwpIHNpX3NwZWxsPXNpbmZvW1NJX1NQRUxMXTsKKyAgLy8gV2VubiBkZXIgU3BpZWxlciBpbiBlaW5lbSBUZWFtIGlzdCwgZGllIFRlYW1yZWloZW4tQm9uaQorICAvLyBiZXJ1ZWNrc2ljaHRpZ2VuLiBXZW5uIG5pY2h0LCBlYmVuIG5pY2h0LgorICBpZiAoIXRlYW09KChvYmplY3QpY2FzdGVyLT5RdWVyeVByb3AoUF9URUFNKSkpCisgIHJldHVybiBUcnlBdHRhY2tTcGVsbCh2aWN0aW0sCisgICAgICAgICAgICAgICAgICAgICAgICBHZXRSYW5kRlZhbHVlTyhTSV9TS0lMTERBTUFHRSxzaW5mbyxjYXN0ZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgR2V0RGF0YShTSV9TS0lMTERBTUFHRV9UWVBFLHNpbmZvLGNhc3RlciksCisgICAgICAgICAgICAgICAgICAgICAgICBzaV9zcGVsbCwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNhc3RlciwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNpbmZvKTsKKyAgZWxzZQorICB7CisJICByb3c9KGludCljYXN0ZXItPlByZXNlbnRQb3NpdGlvbigpOworCSAgcmV0dXJuIFRyeUF0dGFja1NwZWxsKHZpY3RpbSwKKwkJICBHZXRSYW5kRlZhbHVlTyhTSV9TS0lMTERBTUFHRSxzaW5mbyxjYXN0ZXIpKworCQkgIC8vIE51ciB3ZW5uIFNJX1NLSUxMREFNQUdFX0JZX1JPVyBlaW4gbWFwcGluZyBpc3QsIAorCQkgIC8vIHJhbmRvbWlzaWVydCBhZGRpZXJlbgorCQkgIChtYXBwaW5ncChzaW5mb1tTSV9TS0lMTERBTUFHRV9CWV9ST1ddKT8KKwkJICAgcmFuZG9tKHNpbmZvW1NJX1NLSUxMREFNQUdFX0JZX1JPV11bcm93XSk6MCkrCisJCSAgLy8gTnVyIHdlbm4gZGFzIE9GRlNFVCBkYXZvbiBlaW4gbWFwcGluZyBpc3QsCisJCSAgLy8gbmljaHQgcmFuZG9taXNpZXJ0IGFkZGllcmVuLgorCQkgIChtYXBwaW5ncChzaW5mb1tPRkZTRVQoU0lfU0tJTExEQU1BR0VfQllfUk9XKV0pPworCQkgICBzaW5mb1tPRkZTRVQoU0lfU0tJTExEQU1BR0VfQllfUk9XKV1bcm93XSA6IDApLAorCQkgICBHZXREYXRhKFNJX1NLSUxMREFNQUdFX1RZUEUsc2luZm8sY2FzdGVyKSwKKwkJICAgc2lfc3BlbGwsY2FzdGVyLHNpbmZvKTsKKyAgIH0KK30KKworI2RlZmluZSBTTVVMKHgseSkgKCh4PDAgJiYgeTwwKT8oLTEqeCp5KTooeCp5KSkKK2ludAorU3BlbGxTdWNjZXNzKG9iamVjdCBjYXN0ZXIsIG1hcHBpbmcgc2luZm8pIHsKKyAgaW50IGN2YWwsYWJpbCxyZXM7CisKKyAgYWJpbD1zaW5mb1tTSV9TS0lMTEFCSUxJVFldOworICBjdmFsPShpbnQpY2FzdGVyLT5Vc2VTa2lsbChTS19DQVNUSU5HKTsKKyAgcmVzPWFiaWwgKyAoU01VTChhYmlsLGN2YWwpKSAvIE1BWF9BQklMSVRZIC0gcmFuZG9tKE1BWF9BQklMSVRZKTsKKyAgaWYgKGN2YWwgJiYgcmVzPk1BWF9BQklMSVRZKSAvLyBiZXNvbmRlcnMgZ3V0IGdlbHVuZ2VuPworICAgIGNhc3Rlci0+TGVhcm5Ta2lsbChTS19DQVNUSU5HLDErKHJlcy1NQVhfQUJJTElUWSkvMjAwMCk7CisgIHJldHVybiByZXM7Cit9CisKK2ludAorQ2FuVHJ5U3BlbGwob2JqZWN0IGNhc3RlciwgbWFwcGluZyBzaW5mbykgeworICBtYXBwaW5nIHJtYXA7CisgIHN0cmluZyByZXM7CisKKyAgaWYgKGNhc3Rlci0+UXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgd3JpdGUoIkFscyBHZWlzdCBrYW5uc3QgRHUgbmljaHQgemF1YmVybi5cbiIpOworICAgIHJldHVybiAwOworICB9CisgIGlmICgocm1hcD1zaW5mb1tTSV9TS0lMTFJFU1RSX1VTRV0pCisgICAgICAmJiAocmVzPWNoZWNrX3Jlc3RyaWN0aW9ucyhjYXN0ZXIscm1hcCkpKSB7CisgICAgd3JpdGUocmVzKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICByZXR1cm4gMTsKK30KKwordm9pZAorTGVhcm4ob2JqZWN0IGNhc3Rlciwgc3RyaW5nIHNwZWxsLCBtYXBwaW5nIHNpbmZvKSB7CisgIGludCB2YWwsZGlmZixhdHR2YWw7CisgIG1hcHBpbmcgYXR0cjsKKyAKKyAgLy8gZ2FyIG5pY2h0IGxlcm5lbj8KKyAgaWYgKHNpbmZvW1NJX05PX0xFQVJOXSkKKyAgICByZXR1cm47CisKKyAvLyBBdHRyaWJ1dCBzb2xsdGUgaW50IHNlaW4sIHdlbm4gbmljaHQgYW5kZXJzIGFuZ2VnZWJlbgorIGlmIChtYXBwaW5ncChzaW5mb1tTSV9MRUFSTl9BVFRSSUJVVEVdKSkKKyB7CisJYXR0cj1zaW5mb1tTSV9MRUFSTl9BVFRSSUJVVEVdOworCS8vIERpcmVrdCBpbiBlaW5lbSBkdXJjaCBiZXJlY2huZW4uCisJLy8gSWNoIGdlaGUgZGF2b24gYXVzLCBkYXNzIHdpciBuaWUgbmllIG5pZQorCS8vIGVpbiB3ZWl0ZXJlcyBBdHRyaWJ1dCBpbnMgTUcgZWluZnVlZ2VuLgorCS8vIFdpciBiZXJlY2huZW4gZGVuIE1pdHRlbHdlcnQKKwlhdHR2YWw9KChpbnQpY2FzdGVyLT5RdWVyeUF0dHJpYnV0ZShBX0lOVCkqYXR0cltBX0lOVF0rCisJCShpbnQpY2FzdGVyLT5RdWVyeUF0dHJpYnV0ZShBX0RFWCkqYXR0cltBX0RFWF0rCisJCShpbnQpY2FzdGVyLT5RdWVyeUF0dHJpYnV0ZShBX1NUUikqYXR0cltBX1NUUl0rCisJCShpbnQpY2FzdGVyLT5RdWVyeUF0dHJpYnV0ZShBX0NPTikqYXR0cltBX0NPTl0pCisJCS8oYXR0cltBX0NPTl0rYXR0cltBX0lOVF0rYXR0cltBX1NUUl0rYXR0cltBX0RFWF0pOworCQkKKwkgCisgfSBlbHNlIHsKKwkgYXR0dmFsPShpbnQpY2FzdGVyLT5RdWVyeUF0dHJpYnV0ZShBX0lOVCk7CisgfQorCisgIAorICB2YWw9KChhdHR2YWwvMikqR2V0RlZhbHVlKFNJX1NLSUxMTEVBUk4sc2luZm8sY2FzdGVyKSsKKyAgICAgICBHZXRPZmZzZXQoU0lfU0tJTExMRUFSTixzaW5mbyxjYXN0ZXIpKTsKKyAgaWYgKCEoZGlmZj1HZXRGVmFsdWVPKFNJX0RJRkZJQ1VMVFksc2luZm8sY2FzdGVyKSkpCisgICAgZGlmZj1HZXRGVmFsdWVPKFNJX1NQRUxMQ09TVCxzaW5mbyxjYXN0ZXIpOworICBjYXN0ZXItPkxlYXJuU2tpbGwoc3BlbGwsdmFsLGRpZmYpOworfQorCit2b2lkCitFcmZvbGcob2JqZWN0IGNhc3Rlciwgc3RyaW5nIHNwZWxsLCBtYXBwaW5nIHNpbmZvKSB7CisgIG9iamVjdCBlbnY7CisgIGlmKGVudj1lbnZpcm9ubWVudChjYXN0ZXIpKQorICAgICBlbnYtPlNwZWxsSW5mb3JtKGNhc3RlcixzcGVsbCxzaW5mbyk7Cit9CisKK3ZvaWQKK01pc3NlcmZvbGcob2JqZWN0IGNhc3Rlciwgc3RyaW5nIHNwZWxsLCBtYXBwaW5nIHNpbmZvKSB7CisgIHdyaXRlKCJEZXIgWmF1YmVyc3BydWNoIGlzdCBtaXNzZ2x1ZWNrdC5cbiIpOworICB3cml0ZSgiRHUgbGVybnN0IGF1cyBEZWluZW0gRmVobGVyLlxuIik7CisgIExlYXJuKGNhc3RlcixzcGVsbCxzaW5mbyk7Cit9CisKK3N0cmluZworU2VsZWN0U3BlbGwoc3RyaW5nIHNwZWxsLCBtYXBwaW5nIHNpbmZvKSB7CisgIGlmIChzaW5mbyAmJiBzaW5mb1tTSV9TS0lMTEZVTkNdKQorICAgIHJldHVybiBzaW5mb1tTSV9TS0lMTEZVTkNdOworICByZXR1cm4gc3BlbGw7Cit9CisKK3ZhcmFyZ3Mgdm9pZAorcHJlcGFyZV9zcGVsbChvYmplY3QgY2FzdGVyLCBzdHJpbmcgc3BlbGwsIG1hcHBpbmcgc2luZm8pIHsKKyAgc3RyaW5nIHR4dDsKKworICBpZiAoIWNhc3RlciB8fCAhc3BlbGwpIHJldHVybiA7CisgIGlmICghbWFwcGluZ3Aoc2luZm8pIHx8ICFzdHJpbmdwKHR4dD1zaW5mb1tTSV9QUkVQQVJFX01TR10pKQorICAgIHR4dD0iRHUgYmVyZWl0ZXN0IERpY2ggYXVmIGRlbiBTcHJ1Y2ggYGAlcycnIHZvci5cbiI7CisgIHRlbGxfb2JqZWN0KGNhc3RlcixzcHJpbnRmKHR4dCxzcGVsbCkpOworfQorCit2YXJhcmdzIGludAorVXNlU3BlbGwob2JqZWN0IGNhc3Rlciwgc3RyaW5nIHNwZWxsLCBtYXBwaW5nIHNpbmZvKSB7CisgIG1hcHBpbmcgc2tpLHRtcDsKKyAgc3RyaW5nIHNwZWxsYm9vayxzbmFtZSxmbmFtZSx0eHQ7CisgIGludCByZXMsZmF0LGNvc3Q7CisgIG1peGVkIHBzOworCisgIGlmICghY2FzdGVyIHx8ICFzcGVsbCkKKyAgICByZXR1cm4gMDsKKyAgLy8gU3BlbGwga2FubiBpbiBkZXIgR2lsZGUgYW5kZXJlbiBOYW1lbiBoYWJlbgorICBzbmFtZT1TZWxlY3RTcGVsbChzcGVsbCxzaW5mbyk7CisgIGlmICghKHNraT1RdWVyeVNwZWxsKHNuYW1lKSkpIC8vIEV4aXN0aWVydCBkaWVzZXIgU3BlbGw/CisgICAgcmV0dXJuIDA7CisgIC8vIEdpbGRlbmVpZ2Vuc2NoYWZ0ZW4gc29sbGVuIFNwZWxsZWlnZW5zY2hhZnRlbiB1ZWJlcnNjaHJlaWJlbiBrb2VubmVuCisgIHNraT1BZGRTa2lsbE1hcHBpbmdzKHNraSxzaW5mbyk7CisgIC8vIEZ1ZXIgdmVyc2NoaWVkZW5lIFJhc3NlbiB1bnRlcnNjaGllZGxpY2hlIEVpZ2Vuc2NoYWZ0ZW4KKyAgc2tpPXJhY2VfbW9kaWZpZXIoY2FzdGVyLHNraSk7CisKKyAgLy8gcHJpbnRmKCJTcGVsbGluZm86ICVPXG4iLHNraSk7CisKKyAgaWYgKCFDYW5UcnlTcGVsbChjYXN0ZXIsIHNraSkpCisgICAgcmV0dXJuIDE7CisKKyAgaWYgKGNhc3Rlci0+UXVlcnlQcm9wKFBfU1ApIDwgKGNvc3Q9R2V0RlZhbHVlTyhTSV9TUEVMTENPU1Qsc2tpLGNhc3RlcikpKSB7CisgICAgaWYodHh0PXNraVtTSV9TUF9MT1dfTVNHXSl3cml0ZSh0eHQpOworICAgIGVsc2Ugd3JpdGUoIkR1IGhhc3QgenUgd2VuaWcgWmF1YmVycHVua3RlIGZ1ZXIgZGllc2VuIFNwcnVjaC5cbiIpOworICAgIHJldHVybiAxOworICB9CisgIC8vIHByaW50ZigiY29zdDogJWRcbiIsY29zdCk7CisKKyAgaWYgKG1hcHBpbmdwKHNraVtTSV9YX1NQRUxMRkFUSUdVRV0pKSB7CisgICAgLy8gZnVlciBqZWRlbiBLZXkgZGllIFNwZWxsZmF0aWd1ZSBwcnVlZmVuLCB3ZW5uIGRhcyBNYXBwaW5nIGhpbnRlcmhlcgorICAgIC8vIG5pY2h0IGxlZXIgaXN0LCBpc3QgbWFuIHp1IGVyc2Nob2VwZnQuCisgICAgdG1wID0gZmlsdGVyKHNraVtTSV9YX1NQRUxMRkFUSUdVRV0sCisgICAgICAgIGZ1bmN0aW9uIGludCAoc3RyaW5nIGtleSwgaW50IHZhbCkKKyAgICAgICAgeyByZXR1cm4gKGludCljYXN0ZXItPkNoZWNrU3BlbGxGYXRpZ3VlKGtleSk7IH0gKTsKKyAgICBpZiAoc2l6ZW9mKHRtcCkpIHsKKyAgICAgICAgd3JpdGUoc2tpW1NJX1RJTUVfTVNHXSB8fAorICAgICAgICAgICAgIkR1IGJpc3Qgbm9jaCB6dSBlcnNjaG9lcGZ0IHZvbiBEZWluZW0gbGV0enRlbiBTcHJ1Y2guXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgfQorICBlbHNlIHsKKyAgICBpZiAoY2FzdGVyLT5DaGVja1NwZWxsRmF0aWd1ZSgpKSB7CisgICAgICAgIHdyaXRlKHNraVtTSV9USU1FX01TR10gfHwKKyAgICAgICAgICAgICJEdSBiaXN0IG5vY2ggenUgZXJzY2hvZXBmdCB2b24gRGVpbmVtIGxldHp0ZW4gU3BydWNoLlxuIik7CisgICAgICByZXR1cm4gMTsKKyAgICB9CisgIH0KKworICBpZiAoIShza2lbU0lfTk9fQVRUQUNLX0JVU1ldJk5PX0FUVEFDS19CVVNZX1FVRVJZKSAmJgorICAgICAgY2FzdGVyLT5RdWVyeVByb3AoUF9BVFRBQ0tfQlVTWSkpIHsKKyAgICBpZiAodHh0PXNraVtTSV9BVFRBQ0tfQlVTWV9NU0ddKSB3cml0ZSh0eHQpOworICAgIGVsc2Ugd3JpdGUoIkR1IGJpc3Qgc2Nob24genUgc2VociBiZXNjaGFlZnRpZ3QuXG4iKTsKKyAgICByZXR1cm4gMTsKKyAgfQorCisgIC8vIFNwcnVjaHZvcmJlcmVpdHVuZworICBpZiAocG9pbnRlcnAocHM9KG1peGVkKWNhc3Rlci0+UXVlcnlQcm9wKFBfUFJFUEFSRURfU1BFTEwpKSAvLyBBdXNzdGVoZW5kZXIgU3BydWNoCisgICAgICAmJiBzaXplb2YocHMpPj0zICYmIGludHAocHNbMF0gJiYgc3RyaW5ncChwc1sxXSkpKSB7CisgICAgaWYgKHBzWzFdPT1zcGVsbCkgeyAvLyBEaWVzZXIgU3BydWNoIHdpcmQgbm9jaCB2b3JiZXJlaXRldAorICAgICAgaWYgKHRpbWUoKTxwc1swXSkgeworICAgICAgICBpZiAoIXN0cmluZ3AodHh0PXNraVtTSV9QUkVQQVJFX0JVU1lfTVNHXSkpCisgICAgICAgICAgdHh0PSJEdSBiaXN0IG5vY2ggbWl0IGRlciBTcHJ1Y2h2b3JiZXJlaXR1bmcgYmVzY2hhZWZ0aWd0LlxuIjsKKyAgICAgICAgd3JpdGUodHh0KTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgICB9CisgICAgfQorICAgIGVsc2UgeyAvLyBBbmRlcmUgU3BydWVjaGUgYnJlY2hlbiBkaWUgVm9yYmVyZWl0dW5nIGFiCisgICAgICBpZiAoIW1hcHBpbmdwKHRtcD1RdWVyeVNwZWxsKHBzWzFdKSkgfHwgLy8gcmljaHRpZ2UgTWVsZHVuZyBob2xlbi4uLgorICAgICAgICAgICFzdHJpbmdwKHR4dD10bXBbU0lfUFJFUEFSRV9BQk9SVF9NU0ddKSkKKyAgICAgICAgdHh0PSJEdSBicmljaHN0IGRpZSBTcHJ1Y2h2b3JiZXJlaXR1bmcgZnVlciBgJXMnIGFiLlxuIjsKKyAgICAgIHByaW50Zih0eHQscHNbMV0pOworICAgICAgaWYgKGZhdD1HZXRWYWx1ZShTSV9QUkVQQVJFX1RJTUUsc2tpLGNhc3RlcikpIHsKKyAgICAgICAgLy8gU3BydWNoIGJyYXVjaHQgdm9yYmVyZWl0dW5nc3plaXQKKyAgICAgICAgY2FzdGVyLT5TZXRQcm9wKFBfUFJFUEFSRURfU1BFTEwsKHt0aW1lKCkrZmF0LHNwZWxsLHNraVtTSV9TS0lMTEFSR119KSk7CisgICAgICAgIHByZXBhcmVfc3BlbGwoY2FzdGVyLHNwZWxsLHNraSk7CisgICAgICAgIHJldHVybiAxOworICAgICAgfQorICAgIH0KKyAgfQorICBlbHNlIHsKKyAgICBpZiAoZmF0PUdldFZhbHVlKFNJX1BSRVBBUkVfVElNRSxza2ksY2FzdGVyKSkgeworICAgICAgLy8gU3BydWNoIGJyYXVjaHQgdm9yYmVyZWl0dW5nc3plaXQKKyAgICAgIGNhc3Rlci0+U2V0UHJvcChQX1BSRVBBUkVEX1NQRUxMLCh7dGltZSgpK2ZhdCxzcGVsbCxza2lbU0lfU0tJTExBUkddfSkpOworICAgICAgcHJlcGFyZV9zcGVsbChjYXN0ZXIsc3BlbGwsc2tpKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgfQorICBpZiAocHMpCisgICAgY2FzdGVyLT5TZXRQcm9wKFBfUFJFUEFSRURfU1BFTEwsMCk7CisgIAorICAvLyBGdW5rdGlvbiBrYW5uIGFuZGVyZW4gTmFtZW4gaGFiZW4gYWxzIFNwZWxsCisgIGlmICghKGZuYW1lPXNpbmZvW1NJX1NLSUxMRlVOQ10pKQorICAgIGZuYW1lPXNuYW1lOworCisgIGlmKChza2lbU0lfTk9NQUdJQ10gPCBlbnZpcm9ubWVudChjYXN0ZXIpLT5RdWVyeVByb3AoUF9OT01BR0lDKSkgJiYKKyAgICAgIHJhbmRvbSgxMDApIDwgZW52aXJvbm1lbnQoY2FzdGVyKS0+UXVlcnlQcm9wKFBfTk9NQUdJQykpIHsKKyAgICBpZiAodHh0PXNraVtTSV9OT01BR0lDX01TR10pCisgICAgICB3cml0ZSh0eHQpOworICAgIGVsc2UKKyAgICAgIHdyaXRlKCJEZWluIFphdWJlcnNwcnVjaCB2ZXJwdWZmdCBpbSBOaWNodHMuXG4iKTsKKyAgICByZXM9QUJHRVdFSFJUOworICB9CisgIGVsc2UgeworICAgIC8vIFNwcnVjaCBhdXNmdWVocmVuLgorICAgIHJlcz0oaW50KWNhbGxfb3RoZXIodGhpc19vYmplY3QoKSxmbmFtZSxjYXN0ZXIsc2tpKTsKKyAgfQorICAvLyBUT0RPOiBXZW5uIGRpZSBhdXNnZWZ1ZWhydGUgU3BlbGxmdW5rdGlvbiBlaW5lIDAgenVydWVja2dpYnQsIHNvbGxlbiBqZXR6dAorICAvLyBub2NoIG5vdGlmeV9mYWlscyB6dW0gWnVnZSBrb21tZW4ga29lbm5lbi4gRGFoZXIgaW4gZGllc2VtIEZhbGwgYXVjaCAwCisgIC8vIHp1cnVlY2tnZWJlbi4KKyAgaWYgKCFyZXMgfHwgIWNhc3RlcikKKyAgICByZXR1cm4gMTsKKworICBpZiAoIShza2lbU0lfTk9fQVRUQUNLX0JVU1ldJk5PX0FUVEFDS19CVVNZX1FVRVJZKSkKKyAgCXsKKwlpZiAoIXNraVtTSV9BVFRBQ0tfQlVTWV9BTU9VTlRdKSAgCisgICAgCQljYXN0ZXItPlNldFByb3AoUF9BVFRBQ0tfQlVTWSwxKTsKKwllbHNlCisJCWNhc3Rlci0+U2V0UHJvcChQX0FUVEFDS19CVVNZLHNraVtTSV9BVFRBQ0tfQlVTWV9BTU9VTlRdKTsKKyAgCX0KKworICBjYXN0ZXItPnJlc3RvcmVfc3BlbGxfcG9pbnRzKC0xKmNvc3QpOworCisgIGlmIChtYXBwaW5ncChza2lbU0lfWF9TUEVMTEZBVElHVUVdKSkgeworICAgIC8vIGZ1ZXIgamVkZW4gS2V5IGRpZSBTcGVsbGZhdGlndWUgc2V0emVuLiBLZXlzIG1pdCBEYXVlciAwIGxvZXNlbiBrZWluZQorICAgIC8vIFNwZWxsZmF0aWd1ZSBhdXMuCisgICAgZmlsdGVyKHNraVtTSV9YX1NQRUxMRkFUSUdVRV0sCisgICAgICAgIGZ1bmN0aW9uIGludCAoc3RyaW5nIGtleSwgaW50IHZhbCkKKyAgICAgICAgeyByZXR1cm4gKGludCljYXN0ZXItPlNldFNwZWxsRmF0aWd1ZSh2YWwsIGtleSk7IH0gKTsKKyAgfQorICBlbHNlIHsKKyAgICBpZiAoKGZhdD1HZXRGVmFsdWVPKFNJX1NQRUxMRkFUSUdVRSxza2ksY2FzdGVyKSk8MCkKKyAgICAgIGZhdD0xOworICAgIGNhc3Rlci0+U2V0U3BlbGxGYXRpZ3VlKGZhdCk7CisgIH0KKworCisgIGlmIChyZXM9PUVSRk9MRykKKyAgICBFcmZvbGcoY2FzdGVyLHNwZWxsLHNraSk7CisgIGVsc2UKKyAgaWYgKHJlcz09TUlTU0VSRk9MRykKKyAgICBNaXNzZXJmb2xnKGNhc3RlcixzcGVsbCxza2kpOworICByZXR1cm4gMTsKK30KKworb2JqZWN0ICoKK0ZpbmRHcm91cChvYmplY3QgcGwsIGludCB3aG8pIHsKKyAgb2JqZWN0ICpyZXMsb2IsZW52LHRlYW07CisgIGludCBwMSxwMjsKKyAgY2xvc3VyZSBxcDsKKworICByZXM9KHt9KTsKKyAgaWYgKCFwbCB8fCAhKGVudj1lbnZpcm9ubWVudChwbCkpKSByZXR1cm4gcmVzOworICBwMSA9IHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUocGwpID8gMSA6IC0xOworICB0ZWFtPShvYmplY3QpcGwtPlF1ZXJ5UHJvcChQX1RFQU0pOworICBmb3IgKG9iPWZpcnN0X2ludmVudG9yeShlbnYpO29iO29iPW5leHRfaW52ZW50b3J5KG9iKSkgeworICAgIGlmICghbGl2aW5nKG9iKSkgY29udGludWU7CisgICAgcXA9c3ltYm9sX2Z1bmN0aW9uKCJRdWVyeVByb3AiLG9iKTsKKyAgICBpZiAocGwtPklzRW5lbXkob2IpKSAvLyBGZWluZGUgc2luZCBpbW1lciBHZWduZXIKKyAgICAgIHAyPS0xKnAxOworICAgIGVsc2UgaWYgKG9iamVjdHAodGVhbSkgJiYgZnVuY2FsbChxcCxQX1RFQU0pPT10ZWFtKQorICAgICAgcDI9cDE7IC8vIFRlYW1taXRnbGllZGVyIHNpbmQgaW1tZXIgYXVmIFNlaXRlIGRlcyBTcGllbGVycworICAgIGVsc2UKKyAgICAgIHAyID0gKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUob2IpfHxmdW5jYWxsKHFwLFBfRlJJRU5EKSkgPyAxIDogLTE7CisgICAgaWYgKHAyPjAgJiYgIWludGVyYWN0aXZlKG9iKSAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKG9iKSkKKyAgICAgIGNvbnRpbnVlOyAvLyBrZWluZSBOZXR6dG90ZW4uCisgICAgaWYgKGZ1bmNhbGwocXAsUF9HSE9TVCkpCisgICAgICBjb250aW51ZTsKKyAgICBpZiAoIHdobzwwICYmIChmdW5jYWxsKHFwLFBfTk9fQVRUQUNLKSB8fCBmdW5jYWxsKHFwLFBfTk9fR0xPQkFMX0FUVEFDSykpICkKKyAgICAgIGNvbnRpbnVlOworICAgIGlmIChJU19MRUFSTklORyhvYikgJiYKKyAgICAgICAgKGZ1bmNhbGwocXAsUF9JTlZJUykgfHwgKHdobzwwICYmICFwbC0+SXNFbmVteShvYikpKSkKKyAgICAgIGNvbnRpbnVlOworICAgIGlmIChwMSpwMip3aG8gPj0wKQorICAgICAgcmVzKz0oe29ifSk7CisgIH0KKyAgcmV0dXJuIHJlczsKK30KKworb2JqZWN0ICoKK0ZpbmRHcm91cE4ob2JqZWN0IHBsLCBpbnQgd2hvLCBpbnQgbikgeworICBpZiAoIXBsKSByZXR1cm4gKHt9KTsKKyAgbj0obiooaW50KXBsLT5RdWVyeVNraWxsQXR0cmlidXRlKFNBX0VYVEVOU0lPTikpLzEwMDsKKyAgaWYgKG48MSkgbj0xOworICByZXR1cm4gRmluZEdyb3VwKHBsLHdobylbMC4uKG4tMSldOworfQorCitvYmplY3QgKgorRmluZEdyb3VwUChvYmplY3QgcGwsIGludCB3aG8sIGludCBwcikgeworICBvYmplY3QgKnJlcywqbnJlczsKKyAgaW50IGk7CisKKyAgbnJlcz0oe30pOworICBpZiAoIXBsKSByZXR1cm4gbnJlczsKKyAgcHI9KHByKihpbnQpcGwtPlF1ZXJ5U2tpbGxBdHRyaWJ1dGUoU0FfRVhURU5TSU9OKSkvMTAwOworICBpZiAocHI8MCkgcmV0dXJuIG5yZXM7CisgIHJlcz1GaW5kR3JvdXAocGwsd2hvKTsKKyAgZm9yIChpPXNpemVvZihyZXMpLTE7aT49MDtpLS0pCisgICAgaWYgKHByPj1yYW5kb20oMTAwKSkKKyAgICAgIG5yZXMrPSh7cmVzW2ldfSk7CisgIHJldHVybiBucmVzOworfQorCisvLyBGaW5kZXQgZmVpbmRsaWNoZSB1bmQgZnJldW5kbGljaGUgR1JVUFBFTiBpbSBhbmdlZ2ViZW5lbiBCZXJlaWNoLgordmFyYXJncyBtaXhlZAorRmluZERpc3RhbnRHcm91cHMob2JqZWN0IHBsLCBpbnQgZGlzdCwgaW50IGR5LCBpbnQgZHgpIHsKKyAgbWFwcGluZyBwb3M7CisgIG9iamVjdCBvYixlbnRlYW0sbXl0ZWFtOworICBpbnQgcDEsbWluLG1heCxpOworICBtaXhlZCAqYl9yb3dzLHg7CisgIGNsb3N1cmUgaXNfZW5lbXksIHFwOworCisgIGlmICghb2JqZWN0cChwbCkgfHwgIWVudmlyb25tZW50KHBsKSkKKyAgICByZXR1cm4gKHsoe30pLCh7fSl9KTsKKyAgaWYgKCFkeSkgZHk9MTAwOworICBpZiAoIWR4KSBkeD1NQVhfVEVBTV9ST1dMRU4qMTAwOworICB4PShpbnQpcGwtPlF1ZXJ5U2tpbGxBdHRyaWJ1dGUoU0FfRVhURU5TSU9OKTsKKyAgZHg9KGR4KngpLzEwMDtkeT0oZHkqeCkvMTAwOworICBkaXN0PShkaXN0KihpbnQpcGwtPlF1ZXJ5U2tpbGxBdHRyaWJ1dGUoU0FfUkFOR0UpKS8xMDA7CisgIG1pbj1kaXN0LWR5LzI7CisgIG1heD1kaXN0K2R5LzI7CisKKyAgcG9zPShbXSk7CisgIHAxPXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUocGwpID8gMSA6IC0xOworICBpc19lbmVteT1zeW1ib2xfZnVuY3Rpb24oIklzRW5lbXkiLHBsKTsgLy8genVyIEJlc2NobGV1bmlndW5nCisgIG15dGVhbT0ob2JqZWN0KXBsLT5RdWVyeVByb3AoUF9URUFNKTsKKyAgZm9yIChvYj1maXJzdF9pbnZlbnRvcnkoZW52aXJvbm1lbnQocGwpKTtvYjtvYj1uZXh0X2ludmVudG9yeShvYikpIHsKKyAgICBpZiAoIWxpdmluZyhvYikpIGNvbnRpbnVlOworICAgIHFwPXN5bWJvbF9mdW5jdGlvbigiUXVlcnlQcm9wIixvYik7IC8vIHp1ciBCZXNjaGxldW5pZ3VuZworCisgICAgLy8gWnVlcnN0IG1hbCBkaWUgUG9zaXRpb24gZmVzdHN0ZWxsZW46CisgICAgaWYgKCFvYmplY3RwKGVudGVhbT1mdW5jYWxsKHFwLFBfVEVBTSkpKQorICAgICAgcG9zW29iXT0xOworICAgIGVsc2UgaWYgKCFwb3Nbb2JdICYmIG1hcHBpbmdwKHg9KG1hcHBpbmcpb2ItPlByZXNlbnRUZWFtUG9zaXRpb25zKCkpKQorICAgICAgcG9zKz14OworICAgIC8vIFByZXNlbnRUZWFtUG9zaXRpb25zIHdpcmQgbnVyIGVpbm1hbCBwcm8gVGVhbSBhdXNnZXJlY2huZXQsIHdlaWwKKyAgICAvLyBhbnNjaGxpZXNzZW5kIGplZGVzIGFud2VzZW5kZSBUZWFtbWl0Z2xpZWQgcG9zW29iXSE9MCBoYXQuCisKKyAgICBwb3Nbb2JdPSgyKnBvc1tvYl0pLTE7CisgICAgLy8gUmVpaGVuIHNvbGxlbiBBYnN0YW5kIDIgaGFiZW4sIGF1Y2ggUmVpaGVuIDEgdW5kIC0xIChuYWNoIFVtcmVjaG51bmcpCisKKyAgICAvLyBGZWluZGxpY2hlIFJlaWhlbiBhbiBZLUFjaHNlIHNwaWVnZWxuLCBhbHNvIGdlZ2VudWViZXIgaGluc3RlbGxlbjoKKyAgICBpZiAoZnVuY2FsbChpc19lbmVteSxvYikpCisgICAgICBwb3Nbb2JdKj0tMTsgLy8gSXN0IGF1ZiBqZWRlbiBGYWxsIEZlaW5kCisgICAgZWxzZSBpZiAob2JqZWN0cChteXRlYW0pICYmIG15dGVhbT09ZW50ZWFtKQorICAgICAgICA7ICAgICAgICAgICAgLy8gVGVhbW1pdGdsaWVkZXIgc2luZCBpbW1lciBhdWYgZWlnZW5lciBTZWl0ZQorICAgIGVsc2UKKyAgICAgIHBvc1tvYl0qPShwMSooKGludCkocXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvYil8fAorICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jYWxsKHFwLFBfRlJJRU5EKSk/MTotMSkpOworCisgICAgLy8gRGVuIFNwaWVsZXIgYXVmIGtlaW5lbiBGYWxsIGVudGZlcm5lbgorICAgIGlmIChvYj09cGwpCisgICAgICBjb250aW51ZTsKKyAgICAvLyBOZXR6dG90ZSwgR2Vpc3RlciAgdW5kIHVuc2ljaHRiYXJlIE1hZ2llciBuaWNodCBiZXJ1ZWNrc2ljaHRpZ2VuLAorICAgIC8vIG5pY2h0IChnbG9iYWwpIGFuZ3JlaWZiYXJlIE1vbnN0ZXIgdW5kIG5pY2h0LWZlaW5kbGljaGUgTWFnaWVyCisgICAgLy8gdm9uIGZlaW5kbGljaGVyIFNlaXRlIGVudGZlcm5lbi4KKyAgICBpZiAoKCFpbnRlcmFjdGl2ZShvYikgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvYikpIC8vIE5ldHp0b3RlIHJhdXMKKyAgICAgICAgfHwgZnVuY2FsbChxcCxQX0dIT1NUKQorICAgICAgICB8fCAoSVNfTEVBUk5JTkcob2IpICYmIGZ1bmNhbGwocXAsUF9JTlZJUykpICAgLy8gQmluIG5pY2h0IGRhIDotKQorICAgICAgICB8fCAocG9zW29iXTwwICYmIChmdW5jYWxsKHFwLFBfTk9fR0xPQkFMX0FUVEFDSykgLy8gTmljaHQgYW5ncmVpZmVuCisgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IGZ1bmNhbGwocXAsUF9OT19BVFRBQ0spCisgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IChJU19MRUFSTklORyhvYikgJiYgIWZ1bmNhbGwoaXNfZW5lbXksb2IpKSkpKQorICAgICAgbV9kZWxldGUocG9zLG9iKTsKKyAgfQorCisgIC8vIFJlaWhlbiBhdWZzdGVsbGVuCisgIC8vIEthbXBmcmVpaGU6IHwgICA1ICAgICA0ICAgICAzICAgICAyICAgICAxIHx8ICAxICAgICAyICAgICAzICAgICA0ICAgICA1fAorICAvLyBBcnJheXM6ICAgICB8MCAgMSAgMiAgMyAgNCAgNSAgNiAgNyAgOCAgOSAxMCAxMSAxMiAxMyAxNCAxNSAxNiAxNyAxOCAxOXwKKyAgLy8gICAgICAgICAgICAgfDwtLS0tLS0tLS0tLSBGcmV1bmRlIC0tLS0tLS0+fHw8LS0tLS0tLS0tIEZlaW5kZSAtLS0tLS0tLT58CisgIGJfcm93cz1FTVBUWV9URUFNQVJSQVkrRU1QVFlfVEVBTUFSUkFZK0VNUFRZX1RFQU1BUlJBWStFTVBUWV9URUFNQVJSQVk7CisgIHg9bV9pbmRpY2VzKHBvcyk7CisgIGZvciAoaT1zaXplb2YoeCktMTtpPj0wO2ktLSkgeworICAgIHAxPTIqTUFYX1RFQU1ST1dTLXBvc1tvYj14W2ldXTsKKyAgICBwb3Nbb2JdPXAxOworICAgIGlmIChwMT49MCAmJiBwMTw0Kk1BWF9URUFNUk9XUykgeworICAgICAgaWYgKHJhbmRvbSgxMDApPDUwKSAgICAgICAgICAgICAvLyBEYW1pdCBndXQgZ2VtaXNjaHQgd2lyZC4uLgorICAgICAgICBiX3Jvd3NbcDFdPWJfcm93c1twMV0rKHtvYn0pOyAvLyB6dWZhZWxsaWcgaGludGVuIGFuZnVlZ2VuCisgICAgICBlbHNlCisgICAgICAgIGJfcm93c1twMV09KHtvYn0pK2Jfcm93c1twMV07IC8vIG9kZXIgdm9ybmUgYW5mdWVnZW4uCisgICAgfQorICB9CisKKyAgLy8gVW1yZWNobnVuZyB2b24gTWluLCBNYXggYXVmIFJlaWhlbgorICAvLyAuLi4gLTI6IC0xMjQuLi03NSwgLTE6LTc0Li4tMjUsIDA6LTI0Li4yNCwgMToyNS4uNzQgMjo3NS4uMTI0IC4uLgorICAvLyBEYXMgbXVzcyBtYW4gbWFjaGVuLCB3ZW5uIG1hbiBrZWluZSB2ZXJudWVuZnRpZ2UgUnVuZHVuZ3NmdW5rdGlvbiBoYXQ6CisgIGlmIChtaW48MCkgbWluPS0xKigoMjUtbWluKS81MCk7IGVsc2UgbWluPSgyNSttaW4pLzUwOworICBpZiAobWF4PDApIG1heD0tMSooKDI1LW1heCkvNTApOyBlbHNlIG1heD0oMjUrbWF4KS81MDsKKyAgLy8gUmVsYXRpdiB6dXIgUG9zaXRpb24gZGVzIFNwaWVsZXJzIHZlcnNjaGllYmVuOgorICBwMT1wb3NbcGxdO21pbis9cDE7bWF4Kz1wMTsKKyAgLy8gVW1yZWNobnVuZyB2b24gQnJlaXRlIGF1ZiBBbnphaGw6CisgIGR4PSgoZHgrNTApLzEwMCktMTtpZiAoZHg8MCkgZHg9MDsKKworICB4PSh7KHt9KSwoe30pfSk7CisgIGZvciAoaT0wO2k8MipNQVhfVEVBTVJPV1M7aSsrKQorICAgIGlmIChpPj1taW4gJiYgaTw9bWF4KQorICAgICAgeFsxXSs9Yl9yb3dzW2ldWzAuLmR4XTsgLy8gRnJldW5kZQorICBmb3IgKGk9MipNQVhfVEVBTVJPV1MrMTtpPDQqTUFYX1RFQU1ST1dTO2krKykKKyAgICBpZiAoaT49bWluICYmIGk8PW1heCkKKyAgICAgIHhbMF0rPWJfcm93c1tpXVswLi5keF07IC8vIEZlaW5kZQorCisgIHJldHVybiB4OworfQorCisvLyBGaW5kZXQgZmVpbmRsaWNoZSBvZGVyIGZyZXVuZGxpY2hlIEdydXBwZSAob2RlciBTdW1tZSBiZWlkZXIpIGltCisvLyBhbmdlZ2ViZW5lbiBCZXJlaWNoLgordmFyYXJncyBvYmplY3QgKgorRmluZERpc3RhbnRHcm91cChvYmplY3QgcGwsIGludCB3aG8sIGludCBkaXN0LCBpbnQgZHksIGludCBkeCkgeworICBtaXhlZCAqeDsKKworICB4PUZpbmREaXN0YW50R3JvdXBzKHBsLGRpc3QsZHksZHgpOworICBpZiAod2hvPDApCisgICAgcmV0dXJuIHhbMF07CisgIGVsc2UgaWYgKHdobz4wKQorICAgIHJldHVybiB4WzFdOworICByZXR1cm4geFswXSt4WzFdOworfQorCisKK3N0YXRpYyB2YXJhcmdzIG9iamVjdAorZmluZF92aWN0aW0oc3RyaW5nIHdlbiwgb2JqZWN0IHBsKSB7CisgIG9iamVjdCB2aWN0aW07CisKKyAgaWYgKCFwbCkgcmV0dXJuIDA7CisgIGlmICghc2l6ZW9mKHdlbikpIHsKKyAgICBpZiAodmljdGltID0gKG9iamVjdClwbC0+U2VsZWN0RW5lbXkoKSkKKyAgICAgIHJldHVybiB2aWN0aW07CisgICAgZWxzZQorICAgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKHZpY3RpbSA9IHByZXNlbnQod2VuLCBlbnZpcm9ubWVudChwbCkpKQorICAgIHJldHVybiB2aWN0aW07CisgIGVsc2UgaWYgKHZpY3RpbSA9IHByZXNlbnQod2VuLCBwbCkpCisgICAgcmV0dXJuIHZpY3RpbTsKKyAgZWxzZQorICAgIHJldHVybiAwOworfQordmFyYXJncyBvYmplY3QKK0ZpbmRWaWN0aW0oc3RyaW5nIHdlbiwgb2JqZWN0IHBsLCBzdHJpbmcgbXNnKSB7CisgIG9iamVjdCB2aWM7CisKKyAgaWYgKCEodmljPWZpbmRfdmljdGltKHdlbixwbCkpICYmIG1zZykKKyAgICB3cml0ZShtc2cpOworICByZXR1cm4gdmljOworfQordmFyYXJncyBvYmplY3QKK0ZpbmRMaXZpbmdWaWN0aW0oc3RyaW5nIHdlbiwgb2JqZWN0IHBsLCBzdHJpbmcgbXNnKSB7CisgIG9iamVjdCB2aWM7CisKKyAgaWYgKCEodmljPUZpbmRWaWN0aW0od2VuLHBsLG1zZykpKQorICAgIHJldHVybiAwOworICBpZiAoIWxpdmluZyh2aWMpIHx8IHZpYy0+UXVlcnlQcm9wKFBfR0hPU1QpKSB7CisgICAgcHJpbnRmKCIlcyBsZWJ0IGRvY2ggbmljaHQhXG4iLCBjYXBpdGFsaXplKChzdHJpbmcpdmljLT5uYW1lKCkpKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICByZXR1cm4gdmljOworfQorCitwcml2YXRlIHZhcmFyZ3Mgb2JqZWN0CitEb0ZpbmRFbmVteVZpY3RpbShzdHJpbmcgd2VuLCBvYmplY3QgcGwsIHN0cmluZyBtc2csCisgICAgICAgICAgICAgICAgICBtaXhlZCBmdW5jLCBpbnQgbWluLCBpbnQgbWF4KSB7CisgIG9iamVjdCB2aWM7CisgIG1peGVkIG5vX2F0dGFjazsKKyAgaW50IHJvdzsKKworICBpZiAoISh2aWM9RmluZExpdmluZ1ZpY3RpbSh3ZW4scGwsbXNnKSkpIHsKKyAgICBpZiAoKHN0cmluZ3Aod2VuKSAmJiB3ZW4hPSIiKSB8fCAhb2JqZWN0cChwbCkpCisgICAgICByZXR1cm4gMDsKKyAgICBpZiAocG9pbnRlcnAoZnVuYykpIHsgLy8gU29sbCBlaW5lciBESUVTRVIgR2VnbmVyIGdlbm9tbWVuIHdlcmRlbj8KKyAgICAgIGlmICghKHZpYz0ob2JqZWN0KXBsLT5TZWxlY3RFbmVteShmdW5jKSkpIC8vIERhbm4gZGFyYXVzIGF1c3dhZWhsZW4KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfSBlbHNlIHsKKyAgICAgIGlmICghc3RyaW5ncChmdW5jKSkKKyAgICAgICAgZnVuYz0iU2VsZWN0RW5lbXkiOworICAgICAgaWYgKCEodmljPShvYmplY3QpY2FsbF9vdGhlcihwbCxmdW5jLDAsbWluLG1heCkpKQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZnVuYz0wOyAvLyBrZWluIHp3ZWl0ZXMgTWFsIHBydWVmZW4uCisgIH0KKyAgaWYgKG5vX2F0dGFjayA9IChtaXhlZCl2aWMtPlF1ZXJ5UHJvcChQX05PX0FUVEFDSykpIHsKKyAgICBpZiAoc3RyaW5ncChub19hdHRhY2spKQorICAgICAgd3JpdGUobm9fYXR0YWNrKTsKKyAgICBlbHNlCisgICAgICB3cml0ZSh2aWMtPk5hbWUoV0VSLDEpKyIgbGFlc3N0IHNpY2ggbmljaHQgYW5ncmVpZmVuLlxuIik7CisgICAgcmV0dXJuIDA7CisgIH0KKyAgaWYgKHZpYz09cGwpIHsKKyAgICB3cml0ZSgiRHUga29lbm50ZXN0IERpciBkYWJlaSB3ZWh0dW4uXG4iKTsKKyAgICByZXR1cm4gMDsKKyAgfQorICBpZiAoc3RyaW5ncChmdW5jKSkgeworICAgIHN3aXRjaChmdW5jKSB7CisgICAgY2FzZSAiU2VsZWN0TmVhckVuZW15IjoKKyAgICAgIGlmIChwbC0+UHJlc2VudFBvc2l0aW9uKCk+MSkgeworICAgICAgICB3cml0ZSgiRHUgc3RlaHN0IG5pY2h0IGluIGRlciBlcnN0ZW4gS2FtcGZyZWloZS5cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICAgIH0KKyAgICAgIGlmICh2aWMtPlByZXNlbnRQb3NpdGlvbigpPjEpIHsKKyAgICAgICAgd3JpdGUodmljLT5OYW1lKFdFUiwxKSsiIGlzdCBpbiBlaW5lciBoaW50ZXJlbiBLYW1wZnJlaWhlLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgICAgfQorICAgICAgYnJlYWs7CisgICAgY2FzZSAiU2VsZWN0RmFyRW5lbXkiOgorICAgICAgaWYgKHJvdz0oaW50KXZpYy0+UHJlc2VudFBvc2l0aW9uKCkpCisgICAgICAgIHJvdy0tOworICAgICAgaWYgKHJvdz49bWluICYmIHJvdzw9bWF4KQorICAgICAgICBicmVhazsKKyAgICAgIGlmIChyb3c8bWluKQorICAgICAgICB3cml0ZSh2aWMtPk5hbWUoV0VSLDEpKyIgaXN0IHp1IG5haGUuXG4iKTsKKyAgICAgIGVsc2UgaWYgKHJvdz5tYXgpCisgICAgICAgIHdyaXRlKHZpYy0+TmFtZShXRVIsMSkrIiBpc3QgenUgd2VpdCB3ZWcuXG4iKTsKKyAgICAgIGVsc2UKKyAgICAgICAgd3JpdGUodmljLT5OYW1lKFdFUiwxKSsiIGlzdCB1bmVycmVpY2hiYXIuXG4iKTsKKyAgICAgIHJldHVybiAwOworICAgIGRlZmF1bHQ6OworICAgIH0KKyAgfSBlbHNlIGlmIChwb2ludGVycChmdW5jKSkgeworICAgIGlmIChtZW1iZXIoZnVuYyx2aWMpPDApIHsKKyAgICAgIHdyaXRlKHZpYy0+TmFtZShXRVIsMSkrIiBpc3QgdW5lcnJlaWNoYmFyLlxuIik7CisgICAgICByZXR1cm4gMDsKKyAgICB9CisgIH0KKworICBpZiAoIXBsLT5Jc0VuZW15KHZpYykpIC8vIFdhciBlcyBiaXNoZXIga2VpbiBGZWluZD8KKyAgICBwbC0+S2lsbCh2aWMpOyAgICAgICAvLyBEYW5uIGlzdCBlcyBqZXR6dCBlaW5lci4KKyAgcmV0dXJuIHZpYzsKK30KKwordmFyYXJncyBvYmplY3QKK0ZpbmRFbmVteVZpY3RpbShzdHJpbmcgd2VuLCBvYmplY3QgcGwsIHN0cmluZyBtc2cpIHsKKyAgcmV0dXJuIERvRmluZEVuZW15VmljdGltKHdlbixwbCxtc2csIlNlbGVjdEVuZW15Iik7Cit9CisKKy8vIFdpZSBGaW5kRW5lbXlWaWN0aW0sIGFiZXIgbnVyIGltIE5haGthbXBmIGVycmVpY2hiYXJlIEZlaW5kZSB3ZXJkZW4KKy8vIGdlZnVuZGVuLgordmFyYXJncyBvYmplY3QKK0ZpbmROZWFyRW5lbXlWaWN0aW0oc3RyaW5nIHdlbiwgb2JqZWN0IHBsLCBzdHJpbmcgbXNnKSB7CisgIHJldHVybiBEb0ZpbmRFbmVteVZpY3RpbSh3ZW4scGwsbXNnLCJTZWxlY3ROZWFyRW5lbXkiKTsKK30KKworLy8gV2llIEZpbmRFbmVteVZpY3RpbSwgYWJlciBudXIgRmVpbmRlIGltIEJlcmVpY2ggZGVyIGFuZ2VnZWJlbmVuIFJlaWhlbgorLy8gKG1pbixtYXgpIHdlcmRlbiBnZWZ1bmRlbi4KK3ZhcmFyZ3Mgb2JqZWN0CitGaW5kRmFyRW5lbXlWaWN0aW0oc3RyaW5nIHdlbiwgb2JqZWN0IHBsLCBzdHJpbmcgbXNnLAorICAgICAgICAgICAgICAgICAgIGludCBtaW4sIGludCBtYXgpIHsKKyAgcmV0dXJuIERvRmluZEVuZW15VmljdGltKHdlbixwbCxtc2csIlNlbGVjdEZhckVuZW15IixtaW4sbWF4KTsKK30KKworLy8gV2llIEZpbmRFbmVteVZpY3RpbSwgZmluZGV0IGFiZXIgbnVyIEZlaW5kZSBpbgorLy8gRmluZERpc3RhbnRHcm91cChHRUdORVIsZW50ZmVybnVuZyxhYndlaWNodW5nKQordmFyYXJncyBvYmplY3QKK0ZpbmREaXN0YW50RW5lbXlWaWN0aW0oc3RyaW5nIHdlbiwgb2JqZWN0IHBsLCBzdHJpbmcgbXNnLAorICAgICAgICAgICAgICAgICAgICAgICBpbnQgZGlzdCwgaW50IGR5KSB7CisgIHJldHVybiBEb0ZpbmRFbmVteVZpY3RpbSh3ZW4scGwsbXNnLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgRmluZERpc3RhbnRHcm91cChwbCwtMSxkaXN0LGR5LDEwMDAwKSk7Cit9CisKK3ZhcmFyZ3MgaW50CitUcnlHbG9iYWxBdHRhY2tTcGVsbChvYmplY3QgY2FzdGVyLCBtYXBwaW5nIHNpbmZvLCBpbnQgc3VjLAorICAgICAgICAgICAgICAgICAgICAgaW50IGRhbWFnZSwgbWl4ZWQgZHQsIG1peGVkIGlzX3NwZWxsLAorICAgICAgICAgICAgICAgICAgICAgaW50IGRpc3QsIGludCBkZXB0aCwgaW50IHdpZHRoKSB7CisgIGludCBpOworICBtaXhlZCB4LGNvbGRhbTsKKyAgb2JqZWN0ICpvYnMsb2I7CisKKyAgaWYgKCFzdWMpIHN1Yz1yYW5kb20oc2luZm9bU0lfU0tJTExBQklMSVRZXSk7CisgIGlmICghZHQpIGR0PUdldERhdGEoU0lfU0tJTExEQU1BR0VfVFlQRSxzaW5mbyxjYXN0ZXIpOworICBpZiAoIWlzX3NwZWxsKSBpc19zcGVsbD1HZXREYXRhKFNJX1NQRUxMLHNpbmZvLGNhc3Rlcik7CisgIGlmICghZGlzdCkgZGlzdD1HZXRSYW5kRlZhbHVlTyhTSV9ESVNUQU5DRSxzaW5mbyxjYXN0ZXIpOworICBpZiAoIWRlcHRoKSBkZXB0aD1HZXRSYW5kRlZhbHVlTyhTSV9ERVBUSCxzaW5mbyxjYXN0ZXIpOworICBpZiAoIXdpZHRoKSB3aWR0aD1HZXRSYW5kRlZhbHVlTyhTSV9XSURUSCxzaW5mbyxjYXN0ZXIpOworCisgIGlmICghZGVwdGggJiYgd2lkdGgpIGRlcHRoPXdpZHRoOworICBpZiAoIXdpZHRoICYmIGRlcHRoKSB3aWR0aD1kZXB0aDsKKyAgaWYgKCFtYXBwaW5ncChpc19zcGVsbCkpIGlzX3NwZWxsPShbXSk7CisgIGlzX3NwZWxsW1NQX0dMT0JBTF9BVFRBQ0tdPTE7CisKKyAgeD1GaW5kRGlzdGFudEdyb3VwcyhjYXN0ZXIsZGlzdCxkZXB0aCx3aWR0aCk7CisgIHNpbmZvW1NJX05VTUJFUl9FTkVNSUVTXT1zaXplb2YoeFswXSk7CisgIHNpbmZvW1NJX05VTUJFUl9GUklFTkRTXT1zaXplb2YoeFsxXSk7CisKKyAgb2JzPXhbMF07CisgIGZvciAoaT1zaXplb2Yob2JzKS0xO2k+PTA7aS0tKQorICAgIGlmIChvYmplY3RwKG9iPW9ic1tpXSkgJiYgc3VjPj1vYi0+U3BlbGxEZWZlbmQoY2FzdGVyLHNpbmZvKSkKKyAgICAgIFRyeUF0dGFja1NwZWxsKG9iLChkYW1hZ2U/cmFuZG9tKGRhbWFnZSk6CisgICAgICAgICAgICAgICAgICAgICAgICAgR2V0UmFuZEZWYWx1ZU8oU0lfU0tJTExEQU1BR0Usc2luZm8sY2FzdGVyKSksCisgICAgICAgICAgICAgICAgICAgICBkdCxpc19zcGVsbCxjYXN0ZXIsc2luZm8pOworCisgIGlmICghaW50cChjb2xkYW09c2luZm9bU0lfQ09MTEFURVJBTF9EQU1BR0VdKSB8fCAhY29sZGFtKQorICAgIHJldHVybiAxOworICBvYnM9eFsxXTsKKyAgZm9yIChpPXNpemVvZihvYnMpLTE7aT49MDtpLS0pCisgICAgaWYgKG9iamVjdHAob2I9b2JzW2ldKSAmJiBzdWM+PW9iLT5TcGVsbERlZmVuZChjYXN0ZXIsc2luZm8pKQorICAgICAgb2ItPnJlZHVjZV9oaXRfcG9pbnRzKCgoZGFtYWdlP3JhbmRvbShkYW1hZ2UpOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgR2V0UmFuZEZWYWx1ZU8oU0lfU0tJTExEQU1BR0Usc2luZm8sY2FzdGVyKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmNvbGRhbSkvMTApOworICAvLyAxMCBzdGF0dCAxMDAgaXN0IEFic2ljaHQsIHdlaWwgcmVkdWNlX2hpdF9wb2ludHMgc2Nob24gdW0gRmFrdG9yCisgIC8vIDEwIHN0YWVya2VyIHdpcmt0IGFscyBEZWZlbmQuCisKKyAgcmV0dXJuIDE7Cit9CmRpZmYgLS1naXQgYS9zdGQvc3RvcmUuYyBiL3N0ZC9zdG9yZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM1MTExMDUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvc3RvcmUuYwpAQCAtMCwwICsxLDE2NiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHN0b3JlLmMgLS0gRGFzIExhZ2VyIGVpbmVzIExhZGVucworLy8KKy8vICRJZDogc3RvcmUuYyA3MTAwIDIwMDktMDItMDEgMDk6MjQ6NDNaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIEFOWiAzCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGJhbmsuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisKK2luaGVyaXQgIi9zdGQvdGhpbmcvcHJvcGVydGllcyI7Citpbmhlcml0ICIvc3RkL3Jvb20vaXRlbXMiOworCitwcml2YXRlIG5vc2F2ZSBvYmplY3QgKmFsbDsKK3ByaXZhdGUgbm9zYXZlIG1hcHBpbmcgYWxsMjsKK3ByaXZhdGUgbm9zYXZlIG9iamVjdCBzaG9wOworcHJpdmF0ZSBub3NhdmUgaW50IHN1bTsKK3ByaXZhdGUgbm9zYXZlIGludCBzdG9yZV9wZXJjZW50X2xlZnQ7CisKK3N0YXRpYyBpbnQgX3NldF9zdG9yZV9wZXJjZW50X2xlZnQoKQoreworICByZXR1cm4gc3RvcmVfcGVyY2VudF9sZWZ0PVpFTlRSQUxCQU5LLT5fcXVlcnlfc3RvcmVfcGVyY2VudF9sZWZ0KCk7Cit9CisKK3B1YmxpYyB2b2lkIF9yZWdpc3Rlcl9zaG9wKG9iamVjdCBvYikKK3sKKyAgc2hvcD1vYjsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgc2V0ZXVpZChnZXR1aWQoKSk7CisgIHByb3BlcnRpZXM6OmNyZWF0ZSgpOworICBpdGVtczo6Y3JlYXRlKCk7CisgIF9zZXRfc3RvcmVfcGVyY2VudF9sZWZ0KCk7CisgIFNldFByb3AoUF9NSU5fU1RPQ0ssIDIwKTsgLy8gaW1tZXIgZWluZSBSZXNlcnZlIGZ1ZXIgdW5zZXJlIEFuZmFlbmdlci4uLgorfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgICAgICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKK3B1YmxpYyBpbnQgTWF5QWRkT2JqZWN0KG9iamVjdCBvYikKK3sgICByZXR1cm4gMTsgICB9CisKK3Byb3RlY3RlZCB2YXJhcmdzIHZvaWQgcmVtb3ZlX211bHRpcGxlKGludCBsaW1pdCwgbWl4ZWQgZnVuKSB7fQorCitzdGF0aWMgaW50IF9xdWVyeV9zdG9yZV9jb25zdW1lKCkKKy8vIGRhIDAgPSAyMCBpc3QsIGlzdCBrZWluIGRlZmF1bHQgaW5pdGlhbGlzaWVyZW4gaW0gY3JlYXRlIG5vZXRpZyEhIQoreworICBpbnQgY29uc3VtOworICBjb25zdW09MTAwLVF1ZXJ5KFBfU1RPUkVfQ09OU1VNRSk7CisgIGlmIChjb25zdW08MCB8fCBjb25zdW0gPj0xMDApIC8vIGNvbnN1bSA9IDEwMCwgd2VubiBQX1NUT1JFX0NPTlNVTSA9IDAKKyAgICByZXR1cm4gNzA7CisgIHJldHVybiBjb25zdW07Cit9CisKK3N0YXRpYyBpbnQgX3NldF9zdG9yZV9jb25zdW1lKGludCBjb25zdW0pICAgICAvKiAxIDw9IGNvbnN1bSA8PSAxMDAgKi8KK3sKKyAgaWYgKGNvbnN1bTwxIHx8IGNvbnN1bT4xMDApIHJldHVybiAtMTsKKyAgcmV0dXJuICgxMDAtKGludClTZXQoUF9TVE9SRV9DT05TVU1FLCBjb25zdW0pKTsKK30KKworc3RhdGljIGludCBfcXVlcnlfbWluX3N0b2NrKCkKK3sKKyAgaW50IHN0b2NrOworICBzdG9jaz1RdWVyeShQX01JTl9TVE9DSyk7CisgIGlmIChzdG9jazwwKSByZXR1cm4gMDsKKyAgcmV0dXJuIHN0b2NrOworfQorCitwcml2YXRlIHZvaWQgdXBkYXRlX21vbmV5KCkgeworICBpZiAoc3VtKSB7CisgICAgaWYgKCFzaG9wKQorICAgICAgWkVOVFJBTEJBTkstPlBheUluKHN1bSk7CisgICAgZWxzZQorICAgICAgc2hvcC0+X2FkZF9tb25leShzdW0pOworICB9CisgIHN1bT0wOworfQorCitwcm90ZWN0ZWQgdm9pZCBSZW1vdmVPYmplY3RGcm9tU3RvcmUob2JqZWN0IG9iKSB7CisgIC8vIEFsbGUgRnVua3Rpb25lbiBkaWUgYXVzc2VyaGFsYiBhdWZnZXJ1ZmVuIHdlcmRlbiwgd2VyZGVuICJnZWNhdGNodCIKKyAgY2F0Y2goc3VtKz1vYi0+UXVlcnlQcm9wKFBfVkFMVUUpKnN0b3JlX3BlcmNlbnRfbGVmdC8xMDA7IHB1Ymxpc2gpOworICBjYXRjaChvYi0+cmVtb3ZlKCk7IHB1Ymxpc2gpOworICBpZiAob2IpIGRlc3RydWN0KG9iKTsgIC8vIE9iamVrdCBhdWYgamVkZW4gRmFsbCB6ZXJzdG9lcmVuCit9CisKK3Byb3RlY3RlZCB2b2lkIGF1ZnJhZXVtZW4oKSB7CisgIGludCBpLCBzaXplOworICBvYmplY3Qgb2I7CisgIHN0cmluZyBlbGVtZW50OworCisgIGlmICghcG9pbnRlcnAoYWxsKSkgcmV0dXJuOworICBpZiAoIW1hcHBpbmdwKGFsbDIpKSBhbGwyPShbXSk7CisgIHNpemU9c2l6ZW9mKGFsbCk7CisgIGZvciAoaT0oc2l6ZTw9NTAgPyAwIDogc2l6ZS01MCk7IGk8c2l6ZTsgaSsrKSB7CisgICAgaWYgKCFvYmplY3RwKG9iPWFsbFtpXSkpIGNvbnRpbnVlOworICAgIGlmIChvYmplY3RfbmFtZShvYilbMC4uMl09PSIvZC8iIHx8IG9iamVjdF9uYW1lKG9iKVswLi44XT09Ii9wbGF5ZXJzLyIpCisgICAgICBlbGVtZW50PUJMVUVfTkFNRShvYik7CisgICAgZWxzZQorICAgICAgY2F0Y2goZWxlbWVudD1vYi0+c2hvcnQoKStCTFVFX05BTUUob2IpOyBwdWJsaXNoKTsKKyAgICBpZiAoYWxsMltlbGVtZW50XSsrPkFOWikKKyAgICAgIFJlbW92ZU9iamVjdEZyb21TdG9yZShvYik7CisgIH0KKyAgaWYgKHNpemU8PTUwKSB7CisgICAgYWxsPTA7ICAvLyBTcGVpY2hlciBmcmVpZ2ViZW4uLi4KKyAgICBhbGwyPTA7CisgICAgdXBkYXRlX21vbmV5KCk7CisgIH0gZWxzZSB7CisgICAgYWxsPWFsbFswLi5zaXplLTUxXTsKKyAgICBjYWxsX291dCgjJ2F1ZnJhZXVtZW4sMik7CisgIH0KK30KKwordm9pZCByZXNldCgpIHsKKyAgaW50IGksIHRvLCBzdG9jazsKKyAgbWl4ZWQgKml0ZW1saXN0OworICAKKyAgaXRlbXM6OnJlc2V0KCk7CisgIF9zZXRfc3RvcmVfcGVyY2VudF9sZWZ0KCk7CisKKyAgaWYgKCEoYWxsPWFsbF9pbnZlbnRvcnkoKSkgfHwgIXNpemVvZihhbGwpKSB7CisgICAgYWxsPTA7IC8vIFNwZWljaGVyIGZyZWlnZWJlbgorICAgIHJldHVybjsKKyAgfQorICBpZiAoc2l6ZW9mKGl0ZW1saXN0PVF1ZXJ5UHJvcChQX0lURU1TKSkpIHsKKyAgICBpdGVtbGlzdD1maWx0ZXIoaXRlbWxpc3QsICMnWywgMCk7CisgICAgYWxsLT1pdGVtbGlzdDsKKyAgICBpZiAoIXNpemVvZihhbGwpKSB7CisgICAgICBhbGw9MDsgLy8gU3BlaWNoZXIgZnJlaWdlYmVuCisgICAgICByZXR1cm47CisgICAgfQorICB9CisKKyAgaT1zaXplb2YoYWxsKS0xOworICB0bz1pKlF1ZXJ5UHJvcChQX1NUT1JFX0NPTlNVTUUpLzEwMDsKKyAgaWYgKCB0byA8IChzdG9jaz1RdWVyeVByb3AoUF9NSU5fU1RPQ0spKSApCisgICAgdG89c3RvY2s7CisgIGVsc2UKKyAgICBzdG9jaz0wOworCisgIC8vIEhpbnRlcmVyIFRlaWwgZGVzIEludmVudG9yaWVzIHdpcmQgemVyc3RvZXJ0LCBhbHNvIGFsbGUgYWVsdGVyZW4KKyAgLy8gdW5kIHNvbWl0IHZlcm11dGxpY2ggc2VsdGVuIGdla2F1ZnRlIE9iamVrdGUKKyAgZm9yICg7aT49dG87aS0tKQorICAgIFJlbW92ZU9iamVjdEZyb21TdG9yZShhbGxbaV0pOworICBhbGwyPShbXSk7CisgIGNhbGxfb3V0KCMnYXVmcmFldW1lbixyYW5kb20oMTApKTsKKyAgdXBkYXRlX21vbmV5KCk7Cit9CisKKy8vZGllc2VyIFJhdW0gd2lyZCBzaWNoIG5pZSBwZXIgY2xlYW5fdXAoKSB6ZXJzdG9lcmVuLCBkYWhlciBnZWJlbiB3aXIKKy8vMCB6dXJ1ZWNrLCBkYW1pdCBkZXIgRHJpdmVyIGNsZWFuX3VwKCkgbmljaHQgbWVociBydWZ0LgoraW50IGNsZWFuX3VwKGludCByZWZjb3VudCkgeyByZXR1cm4gMDsgfQorCitzdGF0aWMgaW50IF9xdWVyeV9jdXJyZW50X21vbmV5KCkKK3sKKyAgcmV0dXJuIHN1bTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3RoaW5nLmMgYi9zdGQvdGhpbmcuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45MDhiNmMxCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3RoaW5nLmMKQEAgLTAsMCArMSw0NSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHRoaW5nLmMgLS0gc3RhbmRhcmQgb2JqZWN0CisvLworLy8gJElkOiB0aGluZy5jIDc4MDQgMjAxMS0wNy0xMCAyMDozNzo1MlogWmVzc3RyYSAkICAgICAgICAgICAgICAgICAgICAgIAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHBlZGFudGljCisjcHJhZ21hIHJhbmdlX2NoZWNrCisvLyNwcmFnbWEgbm9fY2xvbmUKKworaW5oZXJpdCAiL3N0ZC90aGluZy9wcm9wZXJ0aWVzIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvbGlnaHQiOworaW5oZXJpdCAiL3N0ZC90aGluZy9kZXNjcmlwdGlvbiI7Citpbmhlcml0ICIvc3RkL3RoaW5nL21vdmluZyI7Citpbmhlcml0ICIvc3RkL3RoaW5nL2xhbmd1YWdlIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvY29tbWFuZHMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9yZXN0cmljdGlvbnMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9lbnZjaGsiOworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBzZXRldWlkKGdldHVpZCgpKTsKKyAgcHJvcGVydGllczo6Y3JlYXRlKCk7CisgIGxpZ2h0OjpjcmVhdGUoKTsKKyAgY29tbWFuZHM6OmNyZWF0ZSgpOworICBkZXNjcmlwdGlvbjo6Y3JlYXRlKCk7CisgIHJlc3RyaWN0aW9uczo6Y3JlYXRlKCk7CisgIGVudmNoazo6Y3JlYXRlKCk7CisgIEFkZElkKCJEaW5nIik7CisKKyAgcmV0dXJuOworfQorCisvLyB3aXJkIGdlcnVmZW4sIHdlbm4gaW1wbGl6aXQgcGVyIGluaGVyaXQgZ2VsYWRlbi4gSW4gZGllc2VtIEZhbGwgd2lyZCBrZWluCisvLyBSZXNldCBiZW5vZXRpZ3QsIHdlaWwgZGFzIE9iamVrdCBuaWNodCBrb25maWd1cmllcnQgaXN0IHVuZCBudXIgZGFzCisvLyBQcm9ncmFtbSB3aWNodGlnIGlzdC4KK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCisvLyBEYW1pdCBtYW4gaW4gQUxMRU4gU3RhbmRhcmRvYmpla3RlbiA6OnJlc2V0IGF1ZnJ1ZmVuIGthbm4uCit2b2lkIHJlc2V0KCkge30KKwpkaWZmIC0tZ2l0IGEvc3RkL3RoaW5nL2NvbW1hbmRzLmMgYi9zdGQvdGhpbmcvY29tbWFuZHMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzQ1YjY3Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3RoaW5nL2NvbW1hbmRzLmMKQEAgLTAsMCArMSw1MzIgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB0aGluZy9jb21tYW5kcy5jIC0tIHRoaW5nIGRlc2NyaXB0aW9uCisvLworLy8gJElkOiBjb21tYW5kcy5jIDk1MTQgMjAxNi0wMi0yMyAyMDozMzowOVogR2xvaW5zb24gJAorLy8KKy8vIEF1cyBSZWdlbmJvZ2VuIE1VRExpYgorLy8gYXVzIEd1ZWxkZW5sYW5kL1d1bmRlcmxhbmQgTVVEbGliIChNb3JnZW5ncmF1ZW4gTVVEbGliKQorLy8KKy8vIFBfQ09NTUFORFMgZGF0YS1zdHJ1Y3R1cmU6CisvLworLy8gQWRkQ21kKHZlcmIsZnVuMSwxKTsKKy8vIEFkZENtZCh2ZXJiK3N5bjFhfHN5bjFiJnN5bjJhfHN5bjJifHN5bjJjLGZ1bjIsCisvLwkgICBlcnJvcjFfbm90aWZ5fGVycm9yMl9ub3RpZnleZXJyb3IyX3dyaXRlKTsKKy8vIC0tPgorLy8gKFt2ZXJiOih7ZnVuMSxmdW4yfSk7CQkJCQkvLyBmdW5zCisvLwkgICh7MSwoe2Vycm9yMV9ub3RpZnksIGVycm9yMl93cml0ZV5lcnJvcjJfc2F5LCAxfSl9KTsgIC8vIGZsYWdzCisvLyAgICAgICAgKHswLCh7KHtzeW4xYSxzeW4xYn0pLCh7c3luMmEsc3luMmIsc3luMmN9KX0pfSk7CS8vIHJ1bGVzCisvLyAgICAgICAgMF0pCQkJCQkJCS8vIElEcworLy8KKy8vIFJ1bGVzOiAoezxSZWdlbHNhdHogZnVlciBmdW4xPiwgKHs8MS4gU3lub255bWdydXBwZT4sCisvLwkJCQkgICAgIDwyLiBTeW5vbnltZ3J1cHBlLCAuLi59KSwgLi4ufSkKKy8vIEZsYWdzOiAoezxGbGFnIGZ1ZXIgZnVuMT4sICh7PEZlaGxlcm1lbGR1bmcgMS4gU3lub255bWdydXBwZT4sIC4uLiAsCisvLwkJCQlbLCBJbmRleCBmdWVyIHdyaXRlIGFuc3RhdHQgbm90aWZ5X2ZhaWxdfSksCisvLwkgICAgLi4uIH0pCisvLyBJRHM6ICAgMCBvZGVyICh7PElEIGZ1ZXIgZnVuMT59KSBvZGVyICh7MCwgPElEIGZ1ZXIgZnVuMj59KSAuLi4KKy8vCisvLyBJREVBOiBzYXZlIG5vIDBzIGluIHJ1bGVzL2ZsYWdzIGlmIHBvc3NpYmxlIChhcyBpbiBJRHMpCisvLyAgICAgICAoYWRyZXNzaW5nIGVzcGVjaWFsbHkgb2xkLXN0eWxlLUFkZENtZC1NVURzKQorI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8dGhpbmcvbGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxleHBsb3JhdGlvbi5oPgorCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8dGhpbmcvY29tbWFuZHMuaD4KKyN1bmRlZiBORUVEX1BST1RPVFlQRVMKKworI2lmZGVmIERCRworI3VuZGVmIERCRworI2VuZGlmCisjZGVmaW5lIERCRyh4KSBwcmludGYoIk9iamVjdCAlTyB0bXBzdHI9JXNcbiIsIGV4cGxvZGUob2JqZWN0X25hbWUodGhpc19vYmplY3QoKSksIiMiKVsxXSwgeCk7CisKK3ByaXZhdGUgbm9zYXZlIG1hcHBpbmcgYWRkZWRfY21kczsKKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9ICAgICAKKwordmFyYXJncyB2b2lkIEFkZENtZChtaXhlZCBjbWQsIG1peGVkIGZ1bmMsIG1peGVkIGZsYWcsIG1peGVkIGNtZGlkKSB7CisgaW50IGksajsKKyBjbG9zdXJlIGNsOworIG1peGVkICpydWxlOworCisgLy8gcG90ZW50aWVsbGUgQWRkQ21kIG1pdCBSZWdlbD8KKyBpZihzdHJpbmdwKGNtZCkpIHsKKyAgLy8gZWluZSBSZWdlbD8gLSBhdWZzcGxpdHRlbgorICBpZigoaT1tZW1iZXIoY21kLCcmJykpPjApIHsKKyAgIC8vIC4uLiBpbiBBcnJheSBtaXQgVmVya251ZXBmdW5nc2VsZW1lbnRlbgorICAgcnVsZT1leHBsb2RlKGNtZFsoaSsxKS4uXSwiJiIpOworICAgaj1zaXplb2YocnVsZSk7CisgICAvLyAuLi4gaW4gQXJyYXkgbWl0IEFycmF5cyBtaXQgQWx0ZXJuYXRpdmVsZW1lbnRlbjoKKyAgIC8vICJwfHEmcnxzIiAtPiAoeyAoeyJwIiwicSJ9KSwgKHsiciIsInMifX0gfSkKKyAgIHdoaWxlKGotLSkKKyAgICBydWxlW2pdPWV4cGxvZGUocnVsZVtqXSwifCIpOworCisgICAvLyBSZWdlbG4gdm9uIEtvbW1hbmRvdmVyYmVuIGFic2NobmVpZGVuCisgICBjbWQ9Y21kWzAuLihpLTEpXTsKKyAgfQorICAvLyBLb21tYW5kb3ZlcmJlbiBleHRyYWhpZXJlbgorICBjbWQ9ZXhwbG9kZShjbWQsInwiKTsKKworICAvLyBTYXR6IHZvbiBSZWdlbG4gZXhpc3RpZXJ0OiBBdWZzcGxpdHRlbiB2b24gRmVobGVybWVsZHVuZ2VuCisgIGlmKHJ1bGUpCisgICBpZihzdHJpbmdwKGZsYWcpKSB7CisgICAgbWl4ZWQgKmZhaWw7CisgICAgLy8gaW4gZWluZmFjaGVzIEFycmF5IG1pdCBqZXdlaWxpZ2VuIEZlaGxlcm1lbGR1bmdlbgorICAgIGZhaWw9ZXhwbG9kZShmbGFnLCJ8Iik7CisgICAgaj0wOworICAgIGk9c2l6ZW9mKGZhaWwpOworICAgIHdoaWxlKGo8aSkgeworICAgICAvLyB3cml0ZSAtIEZlaGxlcm1lbGR1bmcgZW50ZGVja3QgLSBQb3NpdGlvbiBnZ2YuIGVpbnRyYWdlbgorICAgICBpZihtZW1iZXIoZmFpbFtqXSwnXicpPj0wICYmICFpbnRwKGZhaWxbPDFdKSkKKyAgICAgIGZhaWwrPSh7an0pOworICAgICBpZihtZW1iZXIoZmFpbFtqXSwnQCcpPj0wKSB7CisgICAgICBpbnQgczsKKyAgICAgIGZsYWc9cmVnZXhwbG9kZShmYWlsW2pdLCAiQFdFW0EtU1VdKlswLTldIik7CisgICAgICBzPXNpemVvZihmbGFnKTsKKyAgICAgIHdoaWxlKChzLT0yKT4wKSB7CisgICAgICAgaW50IHRtcGludDsKKyAgICAgICB0bXBpbnQ9ZmxhZ1tzXVs8MV0tJzEnOworICAgICAgIGlmKHRtcGludDwwIHx8IHRtcGludD5qKQorICAgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAorICAgICAgICAgIkFkZENtZDogZXJyb3ItbWVzc2FnZSAlZCBjb250YWlucyBvdXQtb2YtYm91bmRzIEBXRXh4LXJ1bGUuXG4iLGorMSkpOworICAgICAgfQorICAgICB9CisgICAgIGorKzsKKyAgICB9CisgICAgLy8gIldhcz98V2llIGRhcz8iIC0+ICh7Ildhcz8iLCJXaWUgZGFzPyJ9KQorICAgIC8vICJXYXM/fFdpZSBkYXM/XnxXb21pdCBkYXM/fFdvcmF1ZiBkYXM/XkBXRVIxIG1hY2h0IHdhcy4iIC0+CisgICAgLy8gICh7Ildhcz8iLAorICAgIC8vICAgICJXaWUgZGFzP15Xb21pdCBkYXM/IiwKKyAgICAvLwkgICJXb3JhdWYgZGFzP15AV0VSMSBtYWNodCB3YXMuIiwxfSkKKyAgICBmbGFnPXNpemVvZihmYWlsKTsKKyAgICBpZihmbGFnICYmIGZsYWc8c2l6ZW9mKHJ1bGUpKQorICAgICByYWlzZV9lcnJvcigKKyAgICAgICJBZGRDbWQ6IG51bWJlciBvZiBlcnJvci1tZXNzYWdlcyBkb2VzIG5vdCBtYXRjaCBudW1iZXIgb2YgcnVsZXMuXG4iKTsKKyAgICBmbGFnPWZhaWw7IC8vIHVlYmVyc2NocmVpYmVuIG1pdCBkZW4gcGFyc2VmcmV1bmRsaWNoZW4gRm9ybWF0CisgIH0gZWxzZSBpZihmbGFnKQorICAgcmFpc2VfZXJyb3IoIkFkZENtZDogcnVsZXMgZXhpc3QgYnV0IGZsYWdzIGFyZSBub3QgYW4gZXJyb3Itc3RyaW5nLlxuIik7CisgfSAvLyBlbmQgaWYoc3RyaW5ncChjbWQpKSAuLi4ga2VpbiBSZWdlbHN0cmluZyB2b3JoYW5kZW4KKworIC8vIGtlaW4gS29tbWFuZG9hcnJheSBnZXdlc2VuIG5vY2ggZXJ6ZXVndD8KKyBpZighcG9pbnRlcnAoY21kKSkKKyAgIHJhaXNlX2Vycm9yKCJBZGRDbWQ6IG1pc3Npbmcgc3RyaW5nL3BvaW50ZXItcGFyYW1ldGVyIGZvciBjb21tYW5kLlxuIik7CisKKyAvLyBDbG9zdXJlIGF1cyBlaW5lbSBTdHJpbmcgZXJ6ZXVnZW4sIHdlbm4gbW9lZ2xpY2ggdW5kIHNpY2hlcgorIC8vIChmdW5jdGlvbl9leGlzdHMoKSBmaWx0ZXJ0IHVubm9ldGlnZXJ3ZWlzZSBhdWNoIHJlaW5lICJzdGF0aWMiIGZ1bnMsCisgLy8gIGRpZSBnZW5hdWUgUHJ1ZWZ1bmcgdWViZXIgZnVuY3Rpb25saXN0KCkga29zdGV0IGplZG9jaCB6dXZpZWwpCisgaWYoc3RyaW5ncChmdW5jKSAmJgorICAgICghZXh0ZXJuX2NhbGwoKSB8fCBmdW5jdGlvbl9leGlzdHMoZnVuYyx0aGlzX29iamVjdCgpKSkgJiYKKyAgICBjbG9zdXJlcChjbD1zeW1ib2xfZnVuY3Rpb24oZnVuYyx0aGlzX29iamVjdCgpKSkpCisgIGZ1bmM9Y2w7CisKKyAvLyBqZWRlcyBlaW56ZWxuZSBWZXJiIG1pdCBzZWluZW4gUmVnZWxuIHVuZCBGdW5rdGlvbmVuIGVpbnRyYWdlbgorIGk9c2l6ZW9mKGNtZCk7CisgaWYoIWFkZGVkX2NtZHMpIGFkZGVkX2NtZHM9bV9hbGxvY2F0ZShpLDQpOworIHdoaWxlKGktLSkgeworICBzdHJpbmcgc3RyOworICBzdHI9Y21kW2ldOworICBpZighZnVuYykKKyAgIGlmKGV4dGVybl9jYWxsKCkpIGZ1bmM9cHJldmlvdXNfb2JqZWN0KCk7CisgICBlbHNlIGZ1bmM9dGhpc19vYmplY3QoKTsKKyAgaWYoIW1lbWJlcihhZGRlZF9jbWRzLHN0cikpCisgICBhZGRlZF9jbWRzKz0oW3N0cjphbGxvY2F0ZSgwKTthbGxvY2F0ZSgwKTthbGxvY2F0ZSgwKTswXSk7CisgIC8vIGV4aXN0aWVyZW5kZXMgVmVyYiBlcmdhZW56ZW4KKyAgYWRkZWRfY21kc1tzdHIsMF0rPSh7ZnVuY30pOworICBhZGRlZF9jbWRzW3N0ciwxXSs9KHtmbGFnfSk7CisgIGFkZGVkX2NtZHNbc3RyLDJdKz0oe3J1bGV9KTsKKyAgLy8gZ2dmLiBpZCBpbiBkYXMgSUQtTWFwcGluZyBlaW50cmFnZW4KKyAgaWYoY21kaWQpIHsKKyAgIG1peGVkICp0bXA7CisgICBqPXNpemVvZigoc3RyaW5nKilhZGRlZF9jbWRzW3N0ciwwXSk7CisgICB0bXA9YWRkZWRfY21kc1tzdHIsM118fGFsbG9jYXRlKGopOworICAgaWYoc2l6ZW9mKHRtcCk8aikgdG1wKz1hbGxvY2F0ZShqLXNpemVvZih0bXApKTsKKyAgIHRtcFs8MV09Y21kaWQ7CisgICBhZGRlZF9jbWRzW3N0ciwzXT10bXA7CisgIH0KKyB9Cit9CisKKy8vIEF1c3dlcnR1bmcgZnVlciBlaW4gVmVyYiBsb2VzY2hlbgordmFyYXJncyBpbnQgUmVtb3ZlQ21kKG1peGVkIGNtZCwgaW50IGRlbF9ub3J1bGUsIG1peGVkIG9ubHlpZCkgeworIGludCByZXQ7CisKKyAvLyBGYWxscyBNYWdpZXIgZGFzIFJlbW92ZUNtZCBmYWxzY2ggbnV0emVuICh6LkIuIGFuYWxvZyB6dSBBZGRDbWQpCisgLy8gd2lyZCBkYXMgUmVnZWxzeXN0ZW0gdmVyd2lycnQuIERhIGRhcyBkZWxfbm9ydWxlIG51ciBpbnQgc2VpbiBkYXJmLAorIC8vIGdpYnQgZXMgaGllciBlaW5lIGd1dGUgQ2hhbmNlIGRlbiBGZWhsZXIgYWJ3YWVydHNrb21wYXRpYmVsIHp1IGVudC0KKyAvLyBkZWNrZW4uIERhbWl0IFNwaWVsZXIgZGVuIEZlaGxlciBuaWNodCBtaXRiZWtvbW1lbiwgd2lyZCBoaWVyIGF1ZgorIC8vIGVpbiByYWlzZV9lcnJvciB2ZXJ6aWNodGV0LCB1bmQgc3RhdHQgZGVzc2VuIGluIGVpbiBMb2dmaWxlIGdlLQorIC8vIHNjaHJpZWJlbi4KKyBpZiAoIWludHAoZGVsX25vcnVsZSkpCisgeworICAgbG9nX2ZpbGUoIlJFTU9WRV9DTUQiLAorICAgICBzcHJpbnRmKCJcbi0tICVzIC0tXG5JbGxlZ2FsIFJlbW92ZUNvbW1hbmQoKSBpbiBPYmplY3QgWyVPXTpcbiAlT1xuIiwKKyAgICAgICBkdGltZSh0aW1lKCkpLCB0aGlzX29iamVjdCgpLCBjbWQpKTsKKyAgIGRlbF9ub3J1bGU9MDsKKyAgIG9ubHlpZD0wOworIH0KKyAKKyBpZighYWRkZWRfY21kcyB8fCAoIWNtZCAmJiAhZGVsX25vcnVsZSAmJiAhb25seWlkKSkKKyAgYWRkZWRfY21kcz0obWFwcGluZykwOyAKKyBlbHNlIHsKKyAgaW50IGksIGo7CisgIG1peGVkICpydWxlLCAqZmxhZywgKmZ1biwgKmRlbHJ1bGUsICppZHM7CisKKyAgaWYoc3RyaW5ncChjbWQpKSB7CisgICAvLyBSZWdlbG4gZW50ZGVja3QgLSBaZXJsZWdlbiAod2llIEFkZENtZCkKKyAgIGlmKChpPW1lbWJlcihjbWQsJyYnKSk+MCkgeworICAgIGRlbHJ1bGU9ZXhwbG9kZShjbWRbKGkrMSkuLl0sIiYiKTsKKyAgICBqPXNpemVvZihkZWxydWxlKTsKKyAgICB3aGlsZShqLS0pCisgICAgIGRlbHJ1bGVbal09ZXhwbG9kZShkZWxydWxlW2pdLCJ8Iik7CisgICAgY21kPWNtZFswLi4oaS0xKV07CisgICB9CisgICBjbWQ9ZXhwbG9kZShjbWQsInwiKTsKKyAgfSBlbHNlIGlmKGRlbF9ub3J1bGUgfHwgb25seWlkKSBjbWQ9bV9pbmRpY2VzKGFkZGVkX2NtZHMpOworCisgIGlmKCFwb2ludGVycChjbWQpKQorICAgcmFpc2VfZXJyb3IoIlJlbW92ZUNtZDogbWlzc2luZyBzdHJpbmcvcG9pbnRlci1wYXJhbWV0ZXIuXG4iKTsKKyAgaT1zaXplb2YoY21kKTsKKworICB3aGlsZShpLS0pIHsKKyAgIC8vIGtlaW5lIFJlZ2VsbiBkYSB1bmQgUmVnZWxuIGxvZXNjaGVuIGVybGF1YnQ6IGFsbGVzIGxvZXNjaGVuCisgICBpZighZGVscnVsZSAmJiAhZGVsX25vcnVsZSAmJiAhb25seWlkKSBtX2RlbGV0ZShhZGRlZF9jbWRzLGNtZFtpXSk7CisgICBlbHNlIGlmKG1fY29udGFpbnMoJmZ1biwgJmZsYWcsICZydWxlLCAmaWRzLCBhZGRlZF9jbWRzLCBjbWRbaV0pKSB7CisgICAgaj1zaXplb2YoZnVuKTsKKyAgICB3aGlsZShqLS0pIHsKKyAgICAgaW50IGs7CisgICAgIC8vIERCRyhydWxlW2pdKTsKKyAgICAJLy8gUmVnZWxuIG5pY2h0IGz2c2NoZW4gdW5kIFJlZ2VsPworICAgICBpZighKGRlbF9ub3J1bGUgJiYgcG9pbnRlcnAocnVsZVtqXSkpICYmCisgICAgICAgIC8vIG51ciBiZXN0aW1tdGUgSUQgbPZzY2hlbiB1bmQgSUQgcGFzc3QgbmljaHQ/CisgICAgICAgICEob25seWlkICYmICghcG9pbnRlcnAoaWRzKSB8fCBzaXplb2YoaWRzKTw9aiB8fCBpZHNbal0hPW9ubHlpZCkpICYmCisgICAgICAgIC8vIEz2c2NocmVnZWwgZXhpc3RpZXJ0IHVuZCBwYXNzdCBuaWNodCBhdWYgUmVnZWw/CisgICAgICAgICEoZGVscnVsZSAmJiAoaz1zaXplb2YocnVsZVtqXSkpIT1zaXplb2YoZGVscnVsZSkpKSB7CisgICAgICAvLyBwYXJ0aWVsbGVzIFRlc3RlbiBlaW5lciBM9nNjaHJlZ2VsIC4uLgorICAgICAgaWYoZGVscnVsZSkgeworICAgICAgIHdoaWxlKGstLSkKKyAgICAgICAgaWYoIXNpemVvZihydWxlW2pdW2tdJmRlbHJ1bGVba10pKSBicmVhazsKKyAgICAgICBpZihrPj0wKSBjb250aW51ZTsKKyAgICAgIH0KKyAgICAgIC8vIGFsbGVzIGtvcnJla3Q6IEz2c2NoZW4hCisgICAgICAvLyAoQXJyYXliZXJlaWNoIGR1cmNoIGxlZXJlcyBBcnJheSBsb2VzY2hlbikKKyAgICAgIGZsYWdbai4ual0gID0gYWxsb2NhdGUoMCk7CisgICAgICBmdW5bai4ual0gICA9IGFsbG9jYXRlKDApOworICAgICAgcnVsZVtqLi5qXSAgPSBhbGxvY2F0ZSgwKTsKKyAgICAgIGlmKGlkcykgeworICAgICAgIGlkc1tqLi5qXSA9IGFsbG9jYXRlKDApOworICAgICAgIGlmKCFzaXplb2YoaWRzLWFsbG9jYXRlKDEpKSkgaWRzPShtaXhlZCopMDsKKyAgICAgIH0KKyAgICAgIHJldCsrOworICAgICB9CisgICAgfSAvLyBlbmQgd2hpbGUoai0tKSB7CisgICB9CisgICAvLyBGdW5rdGlvbnMvUmVnZWxsaXN0ZSB1cGRhdGUgb2RlciBnZ2YuIEtvbW1hbmRvIHZvZWxsaWcgbG9lc2NoZW4KKyAgIGlmKHNpemVvZihydWxlKSkgeworICAgIGFkZGVkX2NtZHNbY21kW2ldLDBdPWZ1bjsKKyAgICBhZGRlZF9jbWRzW2NtZFtpXSwxXT1mbGFnOworICAgIGFkZGVkX2NtZHNbY21kW2ldLDJdPXJ1bGU7CisgICAgYWRkZWRfY21kc1tjbWRbaV0sM109aWRzOworICAgfSBlbHNlIG1fZGVsZXRlKGFkZGVkX2NtZHMsY21kW2ldKTsKKyAgfQorICBpZighc2l6ZW9mKGFkZGVkX2NtZHMpKSBhZGRlZF9jbWRzPShtYXBwaW5nKTA7CisgfQorIHJldHVybiByZXQ7Cit9CisKKy8vIEF1c2Z1ZWhyZW4gc2FtdCBnZXBhcnN0ZW0gSW5wdXRzdHJpbmcgdW5kIGdldHJpZ2dlcnRlbiBQYXJzZXJlcmdlYm5pc3Nlbgorc3RhdGljIGludCBfZXhlY3V0ZShtaXhlZCBmdW4sIHN0cmluZyBzdHIsIG1peGVkICpwYXJzZWQpIHsKKyBpZihjbG9zdXJlcChmdW4pKQorICByZXR1cm4gKChpbnQpZnVuY2FsbChmdW4sc3RyLCZwYXJzZWQpKTsKKyBpZihzdHJpbmdwKGZ1bikpCisgIHJldHVybiAoKGludCljYWxsX290aGVyKHRoaXNfb2JqZWN0KCksZnVuLHN0ciwmcGFyc2VkKSk7CisgcmV0dXJuIDA7Cit9CisKKyNkZWZpbmUgQ0hFQ0tfUFJFU0VOVCAgICAgMQorI2RlZmluZSBDSEVDS19JRCAgICAgICAgICAyCisjZGVmaW5lIENIRUNLX1BVVEdFVE5PTkUgIDQKKyNkZWZpbmUgQ0hFQ0tfUFVUR0VURFJPUCAgOAorI2RlZmluZSBDSEVDS19QVVRHRVRUQUtFICAxNgorI2RlZmluZSBDSEVDS19QVVRHRVQgICAgICAoQ0hFQ0tfUFVUR0VUTk9ORXxDSEVDS19QVVRHRVREUk9QfENIRUNLX1BVVEdFVFRBS0UpCisKKy8vIFdlcnQgZnVlciBGZWhsc2NobGFnLCBGYWxsYmFjay1XZXJ0IGRlciBiZW51dHp0ZW4gd2hpbGUtLSAtIFNjaGxlaWZlbgorI2RlZmluZSBOT01BVENIRk9VTkQgICAgICAtMQorCisvLyBSZWdlbG4gZnVlciBlaW4gKG51biB1bndpY2h0aWdlcykgVmVyYiB0cmlnZ2Vybgorc3RhdGljIGludCBfcHJvY2Vzc19jb21tYW5kKHN0cmluZyBzdHIsIHN0cmluZyAqbm9wYXJzZXN0ciwKKwkJCSAgICAgbWl4ZWQgZnVuLCBtaXhlZCBmbGFnLCBtaXhlZCBydWxlKSB7CisgbWl4ZWQgKnBhcnNlZCwgKm9iam1hdGNoZXM7CisKKyAvLyBlaW5lIFJlZ2VsIC4uLiBhdXN3ZXJ0ZW4gLi4uCisgaWYocG9pbnRlcnAocnVsZSkpIHsKKyAgaW50IG5ydWw7CisgIHBhcnNlZD1vYmptYXRjaGVzPWFsbG9jYXRlKDApOworICBpbnQgbGFzdG1hdGNocG9zPU5PTUFUQ0hGT1VORDsKKworICAvLyBBYmdsZWljaGVuIGRlciBnZXNwbGl0dGV0ZW4gRWluZ2FiZSBtaXQgUmVnZWxuOgorICAvLyB2b3J3YWVydHMgZHVyY2ggZGllIFN5bm9ueW1ncnVwcGVuCisgIGludCBycz1zaXplb2YocnVsZSk7CisgIHdoaWxlKG5ydWw8cnMpIHsKKyAgIGludCBtYXRjaHBvczsKKyAgIHN0cmluZyAqc3lub255bTsKKyAgIG1peGVkIG1hdGNoc3RyOworCisgICBtYXRjaHBvcz1OT01BVENIRk9VTkQ7CisgICBtYXRjaHN0cj0wOworCisgICAvLyBTeW5vbnltZSBleHRyYWhpZXJlbgorICAgaW50IG5yc3lub255bXM9c2l6ZW9mKHN5bm9ueW09cnVsZVtucnVsXSk7CisKKyAgIC8vIGVnYWwgd2llIGR1cmNoIFN5bm9ueW1lIGJpcyBNYXRjaCAtIEFiZ2xlaWNoIG1pdCBFaW5nYWJlCisgICB3aGlsZShucnN5bm9ueW1zLS0pIHsKKyAgICBpbnQgdG1wcG9zID0gbWVtYmVyKG5vcGFyc2VzdHIsc3lub255bVtucnN5bm9ueW1zXSk7CisgICAgLy8gaXN0IFN5bm9ueW0gaW0gRWluZ2FiZXN0cmluZyB1bmQga29tbXQgc3BhZXRlciBhbHMgdm9yaGVyaWdlcyBTeW5vbnltPworICAgIGlmKHRtcHBvcz49MCAmJiB0bXBwb3M+bGFzdG1hdGNocG9zKSB7CisgICAgIC8vIEVyZm9sZzogbWVya2VuIGRlciBQb3NpdGlvbiBpbSBFaW5nYWJlc3RyaW5nIHVuZCBkZW4gbWF0Y2hlbmRlbiBTdHJpbmcKKyAgICAgbWF0Y2hwb3M9dG1wcG9zOworICAgICBtYXRjaHN0cj1ub3BhcnNlc3RyW3RtcHBvc107CisgICAgIGJyZWFrOworICAgIH0KKyAgIH0KKworICAgLy8ga2VpbiBNYXRjaCBkdXJjaCBTeW5vbnltZT8gUHJ1ZWZlIGRpZSBALVNwZXppYWx2YXJpYWJsZW4uCisgICBpZihtYXRjaHBvcyA9PSBOT01BVENIRk9VTkQpIHsKKyAgICBpbnQgY2hlY2tfcHJlc2VudDsKKyAgICAvLyBpc3QgQWJwcnVlZmVuIHZvbiBJRC9QUkVTRU5UIGluIGRlciBTeW5vbnltZ3J1cHBlIHZlcmxhbmd0CisgICAgLy8gYmVpIHByZXNlbnQoKS9maW5kX29icyBnbGVpY2ggVm9yYXVzc2V0enVuZyBndWVsdGlnZXIgVFAgbWl0cHJ1ZmVuCisgICAgaWYobWVtYmVyKHN5bm9ueW0sIkBJRCIpPj0wKSBjaGVja19wcmVzZW50PUNIRUNLX0lEOworICAgIGlmKHRoaXNfcGxheWVyKCkpIHsKKyAgICAgaWYobWVtYmVyKHN5bm9ueW0sIkBQUkVTRU5UIik+PTApIGNoZWNrX3ByZXNlbnR8PUNIRUNLX1BSRVNFTlQ7CisgICAgIGVsc2UgaWYobWVtYmVyKHN5bm9ueW0sIkBQVVRfR0VUX05PTkUiKT49MCkKKwkJY2hlY2tfcHJlc2VudHw9Q0hFQ0tfUFVUR0VUTk9ORTsKKyAgICAgZWxzZSBpZihtZW1iZXIoc3lub255bSwiQFBVVF9HRVRfVEFLRSIpPj0wKQorCQljaGVja19wcmVzZW50fD1DSEVDS19QVVRHRVREUk9QOworICAgICBlbHNlIGlmKG1lbWJlcihzeW5vbnltLCJAUFVUX0dFVF9EUk9QIik+PTApCisJCWNoZWNrX3ByZXNlbnR8PUNIRUNLX1BVVEdFVFRBS0U7CisgICAgfQorCisgICAgaWYoY2hlY2tfcHJlc2VudCkgeworICAgICAvLyB3aXIgZmFuZ2VuIGhpbnRlciBkZW0gbGV0enRlbiBNYXRjaCBhbgorICAgICBpbnQgcV9zdGFydD1sYXN0bWF0Y2hwb3MrMTsKKyAgICAgaW50IHJfZW5kPXNpemVvZihub3BhcnNlc3RyKS0xOworCisgICAgIGludCByYW5nZTsKKyAgICAgd2hpbGUoKHJhbmdlPXJfZW5kLXFfc3RhcnQpPj0wKSB7CisgICAgICBtaXhlZCB0bXBvYmo7CisKKyAgICAgIC8vIHdpZSB3ZWl0IHdvbGxlbiB3aXIgenVy/GNrZ2VoZW4/CisgICAgICBpZihyYW5nZSkKKyAgICAgICAgaWYoIShjaGVja19wcmVzZW50JkNIRUNLX1BVVEdFVCkpCisgICAgICAgICAgcmFuZ2U9cmFuZ2U+Mj8yOnJhbmdlOyAvLyAzIEZyYWdtZW50ZSBmdWVyIEBJRC9AUFJFU0VOVCAoQWR2ZXJiL05yKQorICAgICAgICBlbHNlIGlmKHJhbmdlPjQpCisgICAgICAgICAgcmFuZ2U9NDsgICAgICAgICAgICAgICAvLyA1IEZyYWdtZW50ZSBmdWVyIEBQVVRfWFhYIAorCisgICAgICAvLyB1bmQgamV0enQgZGllIFN1YnN0cmluZ3MgcHJ1ZWZlbgorICAgICAgd2hpbGUocmFuZ2U+PTAgJiYgIW1hdGNoc3RyKSB7CisgICAgICAgc3RyaW5nIHRtcHN0cjsKKworICAgICAgIC8vIHp1IHBydWVmZW5kZW4gU3RyaW5nIGF1cyBkZW4gVGVpbGVuIHp1c2FtbWVuc2V0emVuCisgICAgICAgaWYocmFuZ2UpIHRtcHN0cj1pbXBsb2RlKG5vcGFyc2VzdHJbcV9zdGFydC4uKHFfc3RhcnQrcmFuZ2UpXSwiICIpOworICAgICAgIGVsc2UgdG1wc3RyPW5vcGFyc2VzdHJbcV9zdGFydF07CisKKyAgICAgICAvL0RCRyh0bXBzdHIpOworICAgICAgIGlmKGNoZWNrX3ByZXNlbnQmQ0hFQ0tfUFJFU0VOVCAmJgkJCS8vIFBSRVNFTlQgPworICAgICAgICAgICgodG1wb2JqPXByZXNlbnQodG1wc3RyLHRoaXNfcGxheWVyKCkpKSB8fAorICAgICAgICAgICAodG1wb2JqPXByZXNlbnQodG1wc3RyLGVudmlyb25tZW50KHRoaXNfcGxheWVyKCkpKSkpKQorICAgICAgICBtYXRjaHN0cj10bXBvYmo7CisgICAgICAgZWxzZSBpZihjaGVja19wcmVzZW50JkNIRUNLX0lEICYmIGlkKHRtcHN0cikpCS8vIElEID8KKyAgICAgICAgbWF0Y2hzdHI9dGhpc19vYmplY3QoKTsKKyAgICAgICBlbHNlIGlmKChjaGVja19wcmVzZW50JkNIRUNLX1BVVEdFVCkgJiYJLy8gUFVUX0dFVF8/Pz8gPworICAgICAgICAgICAgICAgKHRtcG9iaj0ob2JqZWN0KikKKyAgICAgICAgICAgICAgICAgIHRoaXNfcGxheWVyKCktPmZpbmRfb2JzKHRtcHN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAoW0NIRUNLX1BVVEdFVE5PTkU6UFVUX0dFVF9OT05FLAorICAgICAgICAgICAgICAgICAgICAgICAgQ0hFQ0tfUFVUR0VURFJPUDpQVVRfR0VUX1RBS0UsCisgICAgICAgICAgICAgICAgICAgICAgICBDSEVDS19QVVRHRVRUQUtFOlBVVF9HRVRfRFJPUF0pCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW0NIRUNLX1BVVEdFVCZjaGVja19wcmVzZW50XSkpICYmCisgICAgICAgICAgICAgICBzaXplb2YodG1wb2JqKSkgeworICAgICAgICBpZihzaXplb2YodG1wb2JqKT09MSkgbWF0Y2hzdHI9dG1wb2JqWzBdOworICAgICAgICBlbHNlIHsJLy8gQXJyYXlzIHdlcmRlbiB6d2lzY2hlbmdlc3BlaWNoZXJ0IC4uLgorICAgICAgICAgb2JqbWF0Y2hlcys9KHtzaXplb2YocGFyc2VkKSx0bXBvYmp9KTsKKyAgICAgICAgIG1hdGNoc3RyPXRtcHN0cjsKKyAgICAgICAgfQorICAgICAgIH0gZWxzZSB7IC8vIGRpZXNlciBTdWJzdHJpbmcgaGF0IG5pY2h0IGdlbWF0Y2h0CisgICAgICAgIC8vIGFiIHdlbmlnZXIgYWxzIDMgVGVpbGVuIGlzdCBkYXMgTmljaHRtYXRjaGluZyBlaW5lcyBTdWJzdHJpbmdzIG1pdAorICAgICAgICAvLyBiZWVuZGVuZGVtIE51bWVyYWwgS3JpdGVyaXVtIGZ1ZXIgQWJicnVjaCAoIm9iamVrdCAyIiBzb2xsIG1hdGNoZW4pCisgICAgICAgIHN0cmluZyBudW1lcmFsY2hlY2s7CisgICAgICAgIGlmKHJhbmdlICYmIHJhbmdlPD0yICYmCisgICAgICAgICAgIHNpemVvZihudW1lcmFsY2hlY2s9bm9wYXJzZXN0cltxX3N0YXJ0K3JhbmdlXSkgJiYKKyAgICAgICAgICAgdG9fc3RyaW5nKHRvX2ludChudW1lcmFsY2hlY2spKT09bnVtZXJhbGNoZWNrKQorICAgICAgICAgIGJyZWFrOworCisgICAgICAgIC8vIFN1YnN0cmluZ2xhZW5nZSB2ZXJrdWVyemVuIHVuZCB3ZWl0ZXIKKyAgICAgICAgcmFuZ2UtLTsKKyAgICAgICB9CisgICAgICB9CisKKyAgICAgIC8vIE1hdGNoIGdlZnVuZGVuIQorICAgICAgaWYobWF0Y2hzdHIpIHsKKyAgICAgICBtYXRjaHBvcz1yYW5nZStxX3N0YXJ0OworICAgICAgIC8vIERCRyhtYXRjaHBvcyk7CisgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICBxX3N0YXJ0Kys7CisgICAgIH0gLy8gZW5kIHdoaWxlCisgICAgfQorICAgfQorCisgICAvLyBGZWhsZXJtZWxkdW5nIGZ1ZXIgZGllc2UgZmVobGdlc2NobGFnZW5lIFN5bm9ueW1ncnVwcGUgc2V0emVuCisgICBpZihtYXRjaHBvcyA9PSBOT01BVENIRk9VTkQpIHsKKyAgICAvLyBGZWhsZXJtZWxkdW5nZW4gdW5kIGVpbiBFaW50cmFnIGFuIGRlciBGZWhsZXJzdGVsbGU/CisgICAgaWYocG9pbnRlcnAoZmxhZykgJiYgc2l6ZW9mKGZsYWcpPm5ydWwpIHsKKworICAgICBtYXRjaHN0cj1mbGFnW25ydWxdOworCisgICAgIGlmKHN0cmluZ3AobWF0Y2hzdHIpICYmIHNpemVvZihtYXRjaHN0cikpIHsKKyAgICAgIGlmKG1lbWJlcihtYXRjaHN0ciwnQCcpPj0wKSB7CisgICAgICAgbWF0Y2hzdHI9cmVwbGFjZV9wZXJzb25hbCgmbWF0Y2hzdHIsKHt0aGlzX3BsYXllcigpfSkrcGFyc2VkLDEpOworICAgICAgIHN0cmluZyBzdGFtbT0oKHF1ZXJ5X3ZlcmIoKVs8MV1eJ2UnKT9xdWVyeV92ZXJiKCk6cXVlcnlfdmVyYigpWzAuLjwyXSk7CisgICAgICAgbWF0Y2hzdHI9cmVncmVwbGFjZShtYXRjaHN0ciwiQFZFUkIiLGNhcGl0YWxpemUoc3RhbW0pLDEpOworICAgICAgIG1hdGNoc3RyPXJlZ3JlcGxhY2UobWF0Y2hzdHIsIkB2ZXJiIixzdGFtbSwxKTsKKyAgICAgIH0KKworICAgICAgLy8gaXN0IEZlaGxlcm1lbGR1bmcgZWluIFdSSVRFPworICAgICAgLy8gZGFubiByZXR1cm4gMSAhCisgICAgICBpZihpbnRwKGZsYWdbPDFdKSAmJiBmbGFnWzwxXTw9bnJ1bCkgeworICAgICAgIGlmKG1lbWJlcihtYXRjaHN0ciwnXicpPj0wKSB7CisgICAgICAgIG1hdGNoc3RyPWV4cGxvZGUobWF0Y2hzdHIsIl4iKTsKKyAgICAgICAgd3JpdGUoY2FwaXRhbGl6ZShicmVha19zdHJpbmcobWF0Y2hzdHJbMF0sNzgsMCwxKSkpOworICAgICAgICBpZihzaXplb2YobWF0Y2hzdHJbMV0pKQorICAgICAgICAgc2F5KGNhcGl0YWxpemUoYnJlYWtfc3RyaW5nKG1hdGNoc3RyWzFdLDc4LDAsMSkpLCh7dGhpc19wbGF5ZXIoKX0pICk7CisgICAgICAgfSBlbHNlIHdyaXRlKGNhcGl0YWxpemUoYnJlYWtfc3RyaW5nKG1hdGNoc3RyLDc4LDAsMSkpKTsKKyAgICAgICByZXR1cm4gMTsKKyAgICAgIH0gZWxzZSBub3RpZnlfZmFpbChjYXBpdGFsaXplKGJyZWFrX3N0cmluZyhtYXRjaHN0ciw3OCwwLDEpKSk7CisgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIDA7CisgICB9CisKKyAgIC8vIFVwZGF0ZW4gZGVyIEhpbGZzdmFyaWFibGVuCisgICBwYXJzZWQrPSh7bWF0Y2hzdHJ9KTsKKyAgIGxhc3RtYXRjaHBvcz1tYXRjaHBvczsKKyAgIG5ydWwrKzsKKyAgfSAvLyBlbmQgd2hpbGUobnJ1bDxycykgLi4uIEVyZm9sZyAuLi4gYWIgenVtIG5hZWNoc3RlbiBSZWdlbHRlaWwKKyB9CisKKyAvLyBBcnJheXMgZGVyIEAtT2JqZWN0bWF0Y2hlcyBpbiBQYXJhbWV0ZXIgZnVlciBNZXRob2RlIHJlc3Vic3RpdHVpZXJlbgorIGludCBvYmpzaXplOworIGlmKChvYmpzaXplPXNpemVvZihvYmptYXRjaGVzKSkpCisgIHdoaWxlKChvYmpzaXplLT0yKT49MCkKKyAgIHBhcnNlZFtvYmptYXRjaGVzW29ianNpemVdXT1vYmptYXRjaGVzW29ianNpemUrMV07CisKKyAvLyBlcmZvbGdyZWljaCBNZXRob2RlIGdlZnVuZGVuL2VpbmUgUmVnZWwgYmlzIHp1bSBFbmRlIGR1cmNoZ2VwYXJzdDoKKyByZXR1cm4oX2V4ZWN1dGUoJmZ1biwmc3RyLCZwYXJzZWQpKTsKK30KKworLy8gQXVzd2VydHVuZyAtIGFkZF9hY3Rpb24tRnVuIAorcHVibGljIGludCBfY2woc3RyaW5nIHN0cikgeworIGludCBuaW5kZXg7Cisgc3RyaW5nICprZXlzOworIG1peGVkICpmbGFnOworIC8vIFZlcmIgZXhpc3RpZXJ0LCBLb21tYW5kb3MgYXVjaCwgRWludHJhZyBmdWVyIFZlcmIgZ2VmdW5kZW4KKyBpZihtYXBwaW5ncChhZGRlZF9jbWRzKSAmJiBxdWVyeV92ZXJiKCkpIHsKKyAgbWl4ZWQgKmZ1biwgKnJ1bGUsICppZHM7CisKKyAgLy8gaXN0IGRhcyBWZXJiIGVpbiBLZXkgaW0gS29tbWFuZG9tYXBwaW5nPworICBpZihtX2NvbnRhaW5zKCZmdW4sICZmbGFnLCAmcnVsZSwgJmlkcywgYWRkZWRfY21kcywgcXVlcnlfdmVyYigpKSkgeworICAgc3RyaW5nICpub3BhcnNlc3RyOworICAgbmluZGV4PXNpemVvZihmdW4pOworICAgbm9wYXJzZXN0cj1leHBsb2RlKChzdHJ8fCIiKSwiICIpLSh7IiJ9KTsKKyAgIC8vIGRhbm4gbWF0Y2hlIHVuZ2VwYXJzdGVuIElucHV0IGdlZ2VuIGV0d2FpZ2UgUmVnZWxuCisgICAvLyAtLSBuaWNodCBhZW5kZXJuOiBuZXVlIEtvbW1hbmRvcyBzb2xsZW4gYWx0ZSAidWViZXJzY2hyZWliZW4iIGtvZW5uZW4KKyAgIHdoaWxlKG5pbmRleC0tKQorICAgIGlmKF9wcm9jZXNzX2NvbW1hbmQoJnN0ciwgbm9wYXJzZXN0ciwKKwkJICAgICAgIGZ1bltuaW5kZXhdLCBmbGFnW25pbmRleF0sIHJ1bGVbbmluZGV4XSkpCisgICAgeworICAgICAgR2l2ZUVQKEVQX0NNRCwgcXVlcnlfdmVyYigpKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgfQorCisgIC8vIGtlaW5lIFJlZ2VsIHBhc3N0ZSwgdW5zY2hhcmZlIEF1c3dlcnR1bmcgYXVmIGFsbGUKKyAgLy8gQWRkQ21kdmVyYmVuIGF1c2RlaG5lbgorICBrZXlzPW1faW5kaWNlcyhhZGRlZF9jbWRzKTsKKyAgbmluZGV4PXNpemVvZihrZXlzKTsKKyAgd2hpbGUobmluZGV4LS0pCisgICBpZighc3Ryc3RyKHF1ZXJ5X3ZlcmIoKSxrZXlzW25pbmRleF0pICYmCisgICAgICBtZW1iZXIoKGZsYWc9YWRkZWRfY21kc1trZXlzW25pbmRleF0sMV0pLDEpPj0wKSB7CisgICAgaW50IGkscmV0OworICAgIGk9c2l6ZW9mKGZsYWcpOworICAgIC8vIFJlaWhlbmZvbGdlIG5pY2h0IGFlbmRlcm4gIQorICAgIHdoaWxlKGktLSkKKyAgICAgIGlmKGZsYWdbaV09PTEpIHsKKyAgICAgICAgbWl4ZWQgKmV4ZWMgPSBhZGRlZF9jbWRzW2tleXNbbmluZGV4XSwwXTsKKyAgICAgICAgaWYoIXBvaW50ZXJwKGV4ZWMpIHx8IHNpemVvZihleGVjKTw9aSkKKyAgICAgICAgICBjYXRjaChyYWlzZV9lcnJvcigKKyAgICAgICAgICAgICJBZGRDbWQtQXVzd2VydHVuZzogQ2F0Y2hBbGwtS29tbWFuZG8gXCIiK2tleXNbbmluZGV4XSsiXCIiCisgICAgICAgICAgICAiIHd1cmRlIHdhZWhyZW5kIGRlciBBdXNmdWVocnVuZyB2ZXJhZW5kZXJ0IG9kZXIgZ2Vsb2VzY2h0LiAiCisgICAgICAgICAgICAiS2xhcnRleHQ6IERhcyBpc3Qgc2NobGVjaHQuIFN1Y2h0IGVpbiBSZW1vdmVDbWQ/ICIpOworICAgICAgICAgICAgcHVibGlzaCk7CisgICAgICAgIGVsc2UgaWYoX2V4ZWN1dGUoZXhlY1tpXSxzdHIsMCkpIHsKKyAgICAgICAgICBHaXZlRVAoRVBfQ01ELCBxdWVyeV92ZXJiKCkpOworICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgICB9CisgICB9CisgfQorIHJldHVybiAwOworfQorCit2b2lkIGluaXQoKSB7CisgYWRkX2FjdGlvbigiX2NsIiwiIiwxKTsKK30KKworCitzdGF0aWMgdm9pZCBfY2hlY2tfY29weV9jb21tYW5kcyhzdHJpbmcgaW5kLCBtaXhlZCAqZnVuLAorCQkJCSAgbWl4ZWQgKmZsYWcsIG1peGVkICpydWxlKSB7CisgaWYocG9pbnRlcnAoZnVuKSkgYWRkZWRfY21kc1tpbmQsMF09ZnVuK2FsbG9jYXRlKDApOworIGVsc2UgYWRkZWRfY21kc1tpbmQsMF09KHtmdW59KTsKKyBpZihwb2ludGVycChmbGFnKSkgYWRkZWRfY21kc1tpbmQsMV09ZmxhZythbGxvY2F0ZSgwKTsKKyBlbHNlIGlmKGZsYWcpIGFkZGVkX2NtZHNbaW5kLDFdPSh7ZmxhZ30pOworIGVsc2UgYWRkZWRfY21kc1tpbmQsMV09YWxsb2NhdGUoc2l6ZW9mKGFkZGVkX2NtZHNbaW5kXSkpOworIGlmKHBvaW50ZXJwKHJ1bGUpKSBhZGRlZF9jbWRzW2luZCwyXT1ydWxlK2FsbG9jYXRlKDApOworIGVsc2UgYWRkZWRfY21kc1tpbmQsMl09YWxsb2NhdGUoc2l6ZW9mKGFkZGVkX2NtZHNbaW5kXSkpOworCisgaWYoc2l6ZW9mKGFkZGVkX2NtZHNbaW5kXSkhPXNpemVvZihhZGRlZF9jbWRzW2luZCwxXSkgfHwKKyAgICBzaXplb2YoYWRkZWRfY21kc1tpbmRdKSE9c2l6ZW9mKGFkZGVkX2NtZHNbaW5kLDJdKSkgeworICBhZGRlZF9jbWRzPShtYXBwaW5nKTA7CisgIHJhaXNlX2Vycm9yKCJTZXRQcm9wKFBfQ09NTUFORFMpOiBjb3JydXB0IGNvbW1hbmRzLW1hcHBpbmcuXG4iKTsKKyB9Cit9CisKK3N0YXRpYyBtYXBwaW5nIF9zZXRfY29tbWFuZHMobWFwcGluZyBjb21tYW5kcykgeworIGlmKCFjb21tYW5kcykgYWRkZWRfY21kcz0obWFwcGluZykwOworIGVsc2UgaWYobWFwcGluZ3AoY29tbWFuZHMpKSB7CisgIGFkZGVkX2NtZHM9bV9hbGxvY2F0ZShzaXplb2YoY29tbWFuZHMpLDQpOworICB3YWxrX21hcHBpbmcoY29tbWFuZHMsIydfY2hlY2tfY29weV9jb21tYW5kcyk7CisgfQorIGlmIChtYXBwaW5ncChhZGRlZF9jbWRzKSkKKyAgIHJldHVybihkZWVwX2NvcHkoYWRkZWRfY21kcykpOworIGVsc2UKKyAgIHJldHVybiAobWFwcGluZykwOworfQorCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfY29tbWFuZHMoKSB7CisgaWYgKG1hcHBpbmdwKGFkZGVkX2NtZHMpKQorICAgcmV0dXJuKGRlZXBfY29weShhZGRlZF9jbWRzKSk7CisgZWxzZQorICAgcmV0dXJuIChtYXBwaW5nKTA7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC90aGluZy9kZXNjcmlwdGlvbi5jIGIvc3RkL3RoaW5nL2Rlc2NyaXB0aW9uLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNDdiZmIwZQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC90aGluZy9kZXNjcmlwdGlvbi5jCkBAIC0wLDAgKzEsODUxIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdGhpbmcvZGVzY3JpcHRpb24uYyAtLSBkZXNjcmlwdGlvbiBoYW5kbGluZyBmb3Igc3RhbmRhcmQgb2JqZWN0cworLy8KKy8vICRJZDogZGVzY3JpcHRpb24uYyA5NTYxIDIwMTYtMDUtMjUgMTk6MzM6MjJaIFplc3N0cmEgJAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDx0bHMuaD4KKyNpbmNsdWRlIDx0aGluZy9kZXNjcmlwdGlvbi5oPgorI2luY2x1ZGUgPHRoaW5nL21hdGVyaWFsLmg+CisjaW5jbHVkZSA8dGhpbmcvbGlnaHR0eXBlcy5oPgorI2luY2x1ZGUgPGV4cGxvcmF0aW9uLmg+ICAgICAgICAgICAgICAgICAgLy8gd2VnZW4gRVBNQVNURVIKKyNpbmNsdWRlIDxjbGFzcy5oPgorCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDx0aGluZy9sYW5ndWFnZS5oPgorCisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCisvLyBWYXJpYWJsZSB1bSBkZW4gRlAgYWJ6dXNwZWljaGVybiAKK3ByaXZhdGUgbm9zYXZlIG1peGVkICpleHBsb3JlOworCisvLyBQcm90b3R5cGVuCitwdWJsaWMgc3RyaW5nIHNob3J0KCk7CitwdWJsaWMgdmFyYXJncyBzdHJpbmcgbG9uZyhpbnQgbW9kZSk7CisKKy8vICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFN5c3RlbS1GdW5rdGlvbmVuICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKworLy8gT2JqZWt0IGVyemV1Z2VuCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBzdHJpbmcgcG9pZCwgdHBpZDsKKyAgb2JqZWN0IHRwOworCisgIFNldFByb3AoIFBfTkFNRSwgIkRpbmciICk7CisgIFNldFByb3AoIFBfU0hPUlQsICJOaWNodHMgYmVzb25kZXJlcyIgKTsKKyAgU2V0UHJvcCggUF9MT05HLCAwICk7CisKKyAgU2V0KCBQX0FESkVDVElWRVMsICh7fSkgKTsKKyAgU2V0KCBQX05BTUVfQURKLCAoe30pICk7CisgIFNldCggUF9JRFMsICh7fSkgKTsKKyAgU2V0KCBQX0NMQVNTLCAoe30pICk7CisKKyAgU2V0KCBQX1JFQURfREVUQUlMUywgKFtdKSwgRl9WQUxVRSk7CisgIFNldCggUF9SRUFEX0RFVEFJTFMsIFNFQ1VSRUR8Tk9TRVRNRVRIT0QsIEZfTU9ERV9BUyk7CisKKyAgU2V0KCBQX0RFVEFJTFMsIChbXSksIEZfVkFMVUUpOworICBTZXQoIFBfREVUQUlMUywgU0VDVVJFRHxOT1NFVE1FVEhPRCwgRl9NT0RFX0FTICk7CisKKyAgU2V0KCBQX1NNRUxMUywgKFtdKSwgRl9WQUxVRSk7CisgIFNldCggUF9TTUVMTFMsIFNFQ1VSRUR8Tk9TRVRNRVRIT0QsIEZfTU9ERV9BUyApOworCisgIFNldCggUF9TT1VORFMsIChbXSksIEZfVkFMVUUpOworICBTZXQoIFBfU09VTkRTLCBTRUNVUkVEfE5PU0VUTUVUSE9ELCBGX01PREVfQVMgKTsKKworICBTZXQoIFBfVE9VQ0hfREVUQUlMUywgKFtdKSwgRl9WQUxVRSk7CisgIFNldCggUF9UT1VDSF9ERVRBSUxTLCBTRUNVUkVEfE5PU0VUTUVUSE9ELCBGX01PREVfQVMgKTsKKworICAvLyBBZW5kZXJ1bmdlbiBhbiBkaWVzZXIgUHJvcCBzaW5kIHRhYnUuCisgIFNldCggUF9DTE9ORV9USU1FLCBOT1NFVE1FVEhPRHxTRUNVUkVELCBGX01PREVfQVMgKTsKKworICAvLyBJZCBkZXMgQ2xvbmVycyB1bmQgZGVzIEJlc2l0emVycyBrb21tZW4gbmFjaCBQX0NMT05FUgorICBpZiAob2JqZWN0cCggdHA9dGhpc19pbnRlcmFjdGl2ZSgpfHx0aGlzX3BsYXllcigpICkpCisgIHsKKyAgICB0cGlkPWdldGV1aWQodHApOworICAgIGlmICghKHRwaWQ9Z2V0ZXVpZCh0cCkpKSB0cGlkPWdldHVpZCh0cCk7CisgIH0KKyAgZWxzZQorICAgIHRwaWQ9IlVOS05PV04iOworCisgIGlmIChwcmV2aW91c19vYmplY3QoKSkKKyAgeworICAgIGlmICghKHBvaWQgPSBnZXRldWlkKHByZXZpb3VzX29iamVjdCgpKSkpCisgICAgICBwb2lkID0gZ2V0dWlkKHByZXZpb3VzX29iamVjdCgpKTsKKyAgfQorICBlbHNlCisgICAgcG9pZD0iVU5LTk9XTiI7CisKKyAgU2V0KCBQX0NMT05FUiwgKHBvaWQgIT0gdHBpZCA/IHBvaWQrIjoiK3RwaWQ6IHRwaWQpICk7CisgIFNldCggUF9DTE9ORVIsIE5PU0VUTUVUSE9EfFNFQ1VSRUQsIEZfTU9ERV9BUyApOworCisgIC8vIEdpYnQgZXMgRlBzID8KKyAgZXhwbG9yZSA9IChtaXhlZCAqKUVQTUFTVEVSLT5RdWVyeUV4cGxvcmUoKTsKKworICByZXR1cm47Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIEZvcnNjaGVycHVua3RlICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMKKworLy8gRlAgdmVyZ2ViZW4KK3N0YXRpYyB2b2lkIEdpdmVFUCggaW50IHR5cGUsIHN0cmluZyBrZXkgKQoreworICAvL0FiYnJ1Y2gsIHdlbm4gdmVyZ2ViZW5kZXMgT2JqZWt0IHNjaG9uIHplcnN0b2VydCBpc3QuIEFDSFRVTkc6IEF1Y2gKKyAgLy9kaWVzZSBBYmZyYWdlIHd1ZXJkZSBrZWluIEZQIHZlcmdlYmVuIHdlcmRlbiwgd2VubiBzaWNoIGRhcyBPYmpla3QgaW0KKyAgLy92ZXJnZWJlbmRlbiBLb21tYW5kbyB6ZXJzdG9lcnQsIGRhIGRlciBEcml2ZXIgY2FsbF9vdGhlcigpIHZvbiB6ZXJzdG9lcnRlbgorICAvL09iamVrdGVuIGlnbm9yaWVydCEKKyAgaWYgKCFvYmplY3RwKHRoaXNfb2JqZWN0KCkpKSByZXR1cm47CisgIGlmICh0aGlzX3BsYXllcigpKSB0aGlzX3BsYXllcigpLT5jb3VudENtZHMoIHR5cGUsIGtleSApOworICAKKyAgaWYgKGV4cGxvcmUmJiFleHRlcm5fY2FsbCgpJiYKKyAgICAgIChleHBsb3JlWzBdID09IHR5cGUpICYmIChtZW1iZXIoZXhwbG9yZVsxXSwga2V5KSA+PSAwKSApCisgICAgRVBNQVNURVItPkdpdmVFeHBsb3JhdGlvblBvaW50KGtleSk7CisgIHJldHVybjsKK30KKworLy8gTWFuY2hlIE9iamVrdGUga29lbm5lbiBtaXQgcmVuYW1lX29iamVjdCBlaW5lbiBuZXVlbiBGaWxlbmFtZW4gYmVrb21tZW4uCisvLyBEYW5hY2ggc29sbHRlIGRlciBFUE1BU1RFUiBuZXUgbmFjaCBkZW4gRGV0YWlscyBiZWZyYWd0IHdlcmRlbi4KK3ZvaWQgX19yZWxvYWRfZXhwbG9yZSgpCit7CisgIGV4cGxvcmUgPSAobWl4ZWQgKilFUE1BU1RFUi0+UXVlcnlFeHBsb3JlKCk7CisgIHJldHVybjsKK30KKworLy8gICAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgSUQtTWFuYWdlbWVudCAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjCisKKy8vIEdpYnQgZWluZSBJRCB6dXJ1ZWNrLCBkaWUgZGVuIExhZGVuYW1lbiwgZGllIGFrdHVlbGxlIEt1cnpiZXNjaHJlaWJ1bmcgdW5kCisvLyBkaWUgYWt0dWVsbGUgTGFuZ2Jlc2NocmVpYnVuZyBiZXJ1ZWNrc2ljaHRpZ3QuIERpZXNlIElEIGlzdCBlaW4gSGFzaHdlcnQuCitwdWJsaWMgc3RyaW5nIGRlc2NyaXB0aW9uX2lkKCkgeworICByZXR1cm4gaGFzaChUTFNfSEFTSF9NRDUsIGxvYWRfbmFtZSgpICsgc2hvcnQoKSArIGxvbmcoKSk7Cit9CisKKy8qIElkcyBtdWVzc2VuIHVlYmVyZ2ViZW4gd2VyZGVuLCBkYSB1bml0IG1hY2htYWwgbWl0IHBsdXJhbC1JZHMsICovCisvKiBhbHNvIGFuZGVyZW4gYWxzIGRlbiBub3JtYWxlbiBhcmJlaXRlbiBtdXNzLiAqLworaW50IG1hdGNoX2l0ZW0oIHN0cmluZyBzdHIsIHN0cmluZyAqaWRzICkKK3sKKyAgc3RyaW5nICpvYmosKmFkczsKKyAgaW50IGxlbiwgaTsKKyAgCisgIC8vIFBhcmFtZXRlciBmYWxzY2g/IFBhc3N0IG5pY2h0IC4uLgorICBpZighc3RyKSAgICAgICAgICAgcmV0dXJuIDA7CisgIGlmKCFwb2ludGVycChpZHMpKSByZXR1cm4gMDsKKyAgaWYoIXNpemVvZihpZHMpKSAgIHJldHVybiAwOworICAKKyAgLy8gSXN0IHNjaG9uIHNvIGRhYmVpPyBOYSBLbGFzc2UgOi0pCisgIGlmKG1lbWJlcihpZHMsc3RyKT4tMSkgcmV0dXJuIDE7CisgIAorICAvLyBLZWluZSBBZGpla3RpdmUgdm9yaGFuZGVuIC4uLiBwYXNzdCBuaWNodC4KKyAgaWYgKCEoYWRzPVF1ZXJ5UHJvcChQX0FESkVDVElWRVMpKSkgcmV0dXJuIDA7CisgIGlmICghc2l6ZW9mKGFkcykpICAgICAgICAgICAgICAgICAgIHJldHVybiAwOworICAKKyAgLy8gTnVyIGVpbiBXb3J0PyBEYW5uIHBhc3N0IGVzIG5pY2h0CisgIG9iaj1leHBsb2RlKHN0ciwiICIpOworICBpZiAoIShsZW49c2l6ZW9mKG9iaiktMSkpIHJldHVybiAwOworICAKKyAgLy8gQWRqZWt0aXZlIHN0ZWhlbiBhbSBBbmZhbmcuIFNvYmFsZCBlcyBuaWNodCBtZWhyIHBhc3N0LAorICAvLyBtdXNzIGVzIGRhcyBPYmpla3RpdiBzZWluLgorICB3aGlsZShpPGxlbiYmbWVtYmVyKGFkcyxvYmpbaV0pPi0xKSBpKys7CisKKyAgcmV0dXJuIChtZW1iZXIoaWRzLGltcGxvZGUob2JqW2kuLmxlbl0sIiAiKSk+LTEpOworfQorCisvLyBXaXJkIHZvbSBHYW1lZHJpdmVyIGF1ZmdlcnVmZW4gKHByZXNlbnQpCisvLyBIYXQgZGllc2VyIEdlZ2Vuc3RhbmQgZGllIElEIHN0cj8KKy8vIGx2bCB3aXJkIGlnbm9yaWVydAordmFyYXJncyBpbnQgaWQoIHN0cmluZyBzdHIsIGludCBsdmwgKSAKK3sgCisgIHN0cmluZyBzdHIyLCB0bXA7CisgIGludCBjb3VudDsJCisgIHN0cmluZ3xzdHJpbmcqIGlkczsKKworICAvLyBLZWluIEFyZ3VtZW50PyBEYW5uIHBhc3N0IGVzIG5pY2h0IC4uLgorICBpZiAoIXN0cmluZ3Aoc3RyKSkgcmV0dXJuIDA7CisKKyAgLy8gS2VpbmUgSURzPyBBdWNoIG5pY2h0IGd1dCAuLi4KKyAgaWYgKCFwb2ludGVycChpZHM9UXVlcnlQcm9wKFBfSURTKSkpIHJldHVybiAwOworICBpZiAoIXNpemVvZihpZHMpKSByZXR1cm4gMDsKKworICBpZHMgKz0gKHsgKCJcbiIgKyBvYmplY3RfbmFtZSgpKSwKKyAgICAgICAgICAgICgiXG4iICsgZXhwbG9kZShvYmplY3RfbmFtZSgpLCIjIilbMF0pIH0pOworCisgIC8vIElkIHBhc3N0PyBBbGxlcyBrbGFyIDotKQorICBpZiAobWF0Y2hfaXRlbSggc3RyLCBpZHMgKSkgcmV0dXJuIDE7CisKKyAgLy8gRGllIGlkIGhhdCBlaW5lIFphaGwgZHJpbi4gV2VubiBaYWhsIGRpZSBSb2hpZCBwYXNzdCwKKyAgLy8gZGFubiBndWNrZW4sIG9iIG1hbiBzZWxiZXIgZGFzIG50ZSBFbGVtZW50IGlzdC4KKyAgaWYgKHNzY2FuZiggc3RyLCAiJXMgJWQlcyIsIHN0cjIsIGNvdW50LCB0bXApPDIpIHJldHVybiAwOworICBpZiAoY291bnQ8MSkgcmV0dXJuIDA7CisgIGlmIChzaXplb2YodG1wKSkgcmV0dXJuIDA7CisgIGlmICghbWF0Y2hfaXRlbSggc3RyMiwgaWRzICkpIHJldHVybiAwOworICBpZiAoIWVudmlyb25tZW50KCkpIHJldHVybiAwOworICByZXR1cm4gcHJlc2VudChzdHIyLGNvdW50LGVudmlyb25tZW50KCkpPT10aGlzX29iamVjdCgpOworfQorCisvLyBHbGVpY2ggZWluZSBnYW56ZSBMaXN0ZSB2b24gaWRzIHRlc3RlbgoraW50IG1hdGNoX2lkcyhzdHJpbmcgKmxpc3QpCit7CisgIHN0cmluZyAqaWRzOworCisgIC8vIFVuZ3VlbHRpZ2UgUGFyYW1ldGVyPyBXZWcgaGllciAuLi4gIAorICBpZiAoIXBvaW50ZXJwKGxpc3QpKSByZXR1cm4gMDsKKyAgaWYgKCFwb2ludGVycChpZHM9UXVlcnlQcm9wKFBfSURTKSkpIHJldHVybiAwOworCisgIGlkcyArPSAoeyAoIlxuIiArIG9iamVjdF9uYW1lKCkpLAorICAgICAgICAgICAgKCJcbiIgKyBleHBsb2RlKG9iamVjdF9uYW1lKCksIiMiKVswXSkgfSk7CisKKyAgcmV0dXJuIHNpemVvZiggbGlzdCAmIGlkcyApOworfQorCisvLyBJRCBoaW56dWZ1ZWdlbgordm9pZCBBZGRJZCggc3RyaW5nfHN0cmluZyogc3RyICkKK3sKKyAgaWYgKHN0cmluZ3Aoc3RyKSkgc3RyID0gKHsgc3RyIH0pOworICBpZiAocG9pbnRlcnAoc3RyKSkKKyAgICAvLyBEb3BwZWx0ZSBlbGltaW5pZXJlbgorICAgIFNldCggUF9JRFMsIFF1ZXJ5KFBfSURTLCBGX1ZBTFVFKS1zdHIrc3RyLCBGX1ZBTFVFKTsKKyAgcmV0dXJuOworfQorCisvLyBJRCBlbnRmZXJuZW4KK3ZvaWQgUmVtb3ZlSWQoc3RyaW5nfHN0cmluZyogc3RyKQoreworICBpZiAoc3RyaW5ncChzdHIpKSBzdHIgPSAoeyBzdHIgfSk7CisgIGlmIChwb2ludGVycChzdHIpKQorICAgIFNldChQX0lEUyxRdWVyeShQX0lEUywgRl9WQUxVRSktc3RyLCBGX1ZBTFVFKTsKKyAgcmV0dXJuOworfQorCisvLyBBbGxlIElkcyBhdWYgZWlubWFsIHNldHplbgorc3RhdGljIHN0cmluZyogX3NldF9pZHMoIHN0cmluZyogaWRzICkKK3sKKyAgICBTZXQoIFBfSURTLCh7fSkpOworICAgIEFkZElkKGlkcyk7CisgICAgcmV0dXJuIFF1ZXJ5KFBfSURTLCBGX1ZBTFVFKTsKK30KKworLy8gQWRqZWt0aXYgaGluenVmdWVnZW4KK3ZvaWQgQWRkQWRqZWN0aXZlKHN0cmluZ3xzdHJpbmcqIHN0cikKK3sKKyAgaWYgKHN0cmluZ3Aoc3RyKSkgc3RyID0gKHsgc3RyIH0pOworICBpZiAocG9pbnRlcnAoc3RyKSkKKyAgICAvLyBEb3BwZWx0ZSBlbGltaW5pZXJlbgorICAgICAgU2V0KCBQX0FESkVDVElWRVMsIFF1ZXJ5KFBfQURKRUNUSVZFUywgRl9WQUxVRSktc3RyK3N0ciwgRl9WQUxVRSApOworICByZXR1cm47Cit9CisKKy8vIEFkamVrdGl2IGVudGZlcm5lbgordm9pZCBSZW1vdmVBZGplY3RpdmUoc3RyaW5nfHN0cmluZyogc3RyKQoreworICBpZiAoc3RyaW5ncChzdHIpKSBzdHIgPSAoeyBzdHIgfSk7CisgIGlmIChwb2ludGVycChzdHIpKQorICAgIFNldCggUF9BREpFQ1RJVkVTLCBRdWVyeShQX0FESkVDVElWRVMsIEZfVkFMVUUpIC0gc3RyLCBGX1ZBTFVFICk7CisgIHJldHVybjsKK30KKworLy8gQWxsZSBBZGpla3RpdmUgYXVmIGVpbm1hbCBzZXR6ZW4KK3N0YXRpYyBzdHJpbmcqIF9zZXRfYWRqZWN0aXZlcyhzdHJpbmcqIGFkamVjdGl2ZXMpCit7CisgIFNldCggUF9BREpFQ1RJVkVTLCh7fSksIEZfVkFMVUUpOworICBBZGRBZGplY3RpdmUoYWRqZWN0aXZlcyk7CisgIHJldHVybiBRdWVyeShQX0FESkVDVElWRVMsIEZfVkFMVUUpOworfQorCisKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMKKy8vIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgTmFtZW5zZ2VidW5nICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKKy8vICAgICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMKKworLy8gSW0gRmFsbCB2b24gbWVocmVyZW4gQWRqZWt0aXZlbiBtdWVzc2VuIGRpZXNlIG1pdCBrb21tYQorLy8genVzYW1lbmdlYmF1dCB3ZXJkZW4sIGRhenUgbXVzcyBpY2ggZGFzIGxlZXJ6ZWljaGVuIGFiZXIgZXJzdG1hbAorLy8gYWJzY2huZWlkZW4gdW5kIHNvIHdlaXRlciAuLi4KK3ByaXZhdGUgc3RyaW5nIGRlcG9pbnRlcl9hZGooIHN0cmluZyogYWRqLCBpbnQgY2FzdXMsIGludCBkZW1vbiApIHsKKyAgc3RyaW5nIG1zZzsKKyAgaW50IHN0YXJ0OworICBzdHJpbmcgcmVzLGE7CisJYWRqID0gbWFwKCBhZGosICMnRGVjbEFkaiwgY2FzdXMsIGRlbW9uICk7CisgIHN0YXJ0ID0gMTsKKyAgcmVzID0gIiI7CisgIGZvcmVhY2goIGE6IGFkaiApIHsKKyAgICByZXMgKz0gKHN0YXJ0ID8gIiIgOiAiLCAiKSArIGFbMC4uPDJdOworICAgIHN0YXJ0ID0gMDsKKyAgfQorICByZXR1cm4gcmVzICsgIiAiOworfQorCisvLyBXaWUgbGF1dGV0IGRlciBOYW1lIGRlcyBPYmpla3RzPwordmFyYXJncyBzdHJpbmcgbmFtZShpbnQgY2FzdXMsaW50IGRlbW9uKQoreworICBtaXhlZCBzaCwgYWRqOworICBpbnQgYXJ0LCBwbHVyYWw7CisKKyAgYXJ0ID0gUXVlcnlQcm9wKFBfQVJUSUNMRSk7CisKKyAgLy8gUkFXOiBkaXJla3QgenVydWVja2dlYmVuIG9obmUgVmVyYXJiZWl0dW5nCisgIGlmIChjYXN1cyA9PSBSQVcgKQorICB7CisgICAgaWYocG9pbnRlcnAoUXVlcnlQcm9wKFBfTkFNRSkpKQorICAgICAgcmV0dXJuIFF1ZXJ5UHJvcChQX05BTUUpW1dFUl07CisgICAgcmV0dXJuIFF1ZXJ5UHJvcChQX05BTUUpOworICB9CisKKyAgLy8gVW5zaWNodGJhcjogRXR3YXMKKyAgaWYgKFF1ZXJ5UHJvcChQX0lOVklTKSkKKyAgICByZXR1cm4gKHsgImV0d2FzIiwgInZvbiBldHdhcyIsICJldHdhcyIsICJldHdhcyIgfSlbY2FzdXNdOworCisgIC8vIEtlaW4gTmFtZT8gU2NoYWRlIC4uLgorICBpZiAoIShzaD1RdWVyeVByb3AoUF9OQU1FKSkgfHwKKyAgICAgIChzdHJpbmdwKHNoKSAmJiAhc2l6ZW9mKHNoKSkpIHJldHVybiAwOworCisgIC8vIFBfTkFNRSBwcnVlZmVuLgorICBpZiAocG9pbnRlcnAoc2gpICYmIHNpemVvZihzaCkgIT0gNCkKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIlVuZ3VlbHRpZ2UgQXJyYXlncm9lc3NlIGluIFBfTkFNRTogJWRcbiIsCisgICAgICAgICAgICBzaXplb2Yoc2gpKSk7CisKKyAgLy8gUGx1cmFsIC4uIE5hbWVuIHZlcnd1cnN0ZW4KKyAgaWYgKHBsdXJhbCA9IFF1ZXJ5UHJvcChQX1BMVVJBTCkpCisgIHsKKyAgICAvLyBTZWxiZXIgQXJ0aWtlbCBzdWNoZW4gaXN0IG5pY2h0IC4uLgorICAgIGlmIChkZW1vbj09Mnx8IWFydCkgZGVtb24gPSAwOworCisgICAgLy8gZmFsbHMgUF9OQU1FIGVpbiBBcnJheSBtaXQgRmFlbGxlbiBlbnRoYWVsdCwgZGVuIHJpY2h0aWdlbgorICAgIC8vIGV4dHJhaGllcmVuLi4uCisgICAgaWYgKHBvaW50ZXJwKHNoKSkgeworICAgICAgICBzaCA9IHNoW2Nhc3VzXTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8vIHNvbnN0IHZlcnN1Y2hlbiwgenUgZGVrbGluaWVyZW4uCisgICAgICAgIGludCBsYXN0ID0gc2hbPDFdOworICAgICAgICBpZiAoY2FzdXMgPT0gV0VNJiZsYXN0IT0ncycmJmxhc3QhPSduJykgc2ggPSBzaCArICJuIjsKKyAgICB9CisKKyAgICAvLyBTaW5kIEFkamVrdGl2ZSB2b3JoYW5kZW4/CisgICAgaWYgKCBwb2ludGVycChhZGogPSBRdWVyeVByb3AoUF9OQU1FX0FESikpICYmIHNpemVvZihhZGopKQorICAgICAgICBhZGogPSBkZXBvaW50ZXJfYWRqKGFkaixjYXN1cyxkZW1vbik7CisgICAgaWYgKCFzdHJpbmdwKGFkaikpIGFkaiA9ICIiOworCisgICAgcmV0dXJuIHNwcmludGYoIiVzJXMlcyVzIixRdWVyeUFydGljbGUoY2FzdXMsZGVtb24sMCksYWRqLAorICAgICAgICAgICAgICAgICAgIChwbHVyYWwgPCAyID8gIiI6KHBsdXJhbCA8IDggPworICAgICAgICAgICAgICAgICAgICAoeyAiendlaSAiLCAiZHJlaSAiLCAidmllciAiLCAiZnVlbmYgIiwgInNlY2hzICIsCisgICAgICAgICAgICAgICAgICAgICAgICJzaWViZW4gIiB9KVtwbHVyYWwtMl0gOiB0b19zdHJpbmcocGx1cmFsKSsiICIpKSxzaCk7CisgIH0KKworICAvLyBOYW1lIGlzdCBQb2ludGVyOiBFaW5mYWNoIGRlbiByaWNodGlnZW4gYXVzd2FlaGxlbgorICBpZiAocG9pbnRlcnAoc2gpKQorICAgIHNoID0gc2hbY2FzdXNdOworCisgIC8vIEFuc29uc3RlbiBkb2NoIHdpZWRlciB2ZXJ3dXJzdGVuIC4uLgorICBlbHNlIGlmIChzdHJpbmdwKHNoKSkKKyAgeworICAgIGludCBsYXN0ID0gc2hbPDFdOworCisgICAgc3dpdGNoKGNhc3VzKQorICAgIHsKKyAgICAgIGNhc2UgV0VNOgorICAgICAgY2FzZSBXRU46CisgICAgICAgIGlmICggYXJ0ICYmIGxhc3Q9PSdlJyYmUXVlcnlQcm9wKFBfR0VOREVSKSA9PSBNQUxFKQorICAgICAgICAgIHNoID0gKHN0cmluZylzaCArICJuIjsKKyAgICAgICAgYnJlYWs7CisKKyAgICAgIGNhc2UgV0VTU0VOOgorICAgICAgICBpZiggIWFydCApCisgICAgICAgIHsKKyAgICAgICAgICBzd2l0Y2gobGFzdCkKKyAgICAgICAgICB7CisgICAgICAgICAgICBjYXNlICd4JzoKKyAgICAgICAgICAgIGNhc2UgJ3MnOgorICAgICAgICAgICAgY2FzZSAneic6CisgICAgICAgICAgICAgIHNoID0gKHN0cmluZylzaCArICInIjsKKyAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgc2ggPSAoc3RyaW5nKXNoICsgInMiOworICAgICAgICAgIH0KKyAgICAgICAgfSAKKyAgICAgICAgZWxzZQorICAgICAgICB7CisgICAgICAgICAgc3dpdGNoKGxhc3QpCisgICAgICAgICAgeworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgaWYgKFF1ZXJ5UHJvcChQX0dFTkRFUikhPUZFTUFMRSkKKyAgICAgICAgICAgICAgICBzaD0oc3RyaW5nKXNoKyJzIjsKKyAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICdlJzoKKyAgICAgICAgICAgICAgaWYgKFF1ZXJ5UHJvcChQX0dFTkRFUik9PU1BTEUpCisgICAgICAgICAgICAgICAgc2g9KHN0cmluZylzaCsibiI7CisgICAgICAgICAgICBjYXNlICd4JzoKKyAgICAgICAgICAgIGNhc2UgJ3MnOgorICAgICAgICAgICAgY2FzZSAneic6CisgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgIH0gLyogc3dpdGNoIChsYXN0KSAqLworICAgICAgICB9IC8qIGlmKCAhYXJ0ICkgZWxzZSAqLworICAgIH0gLyogc3dpdGNoKCBjYXN1cyApICovCisgIH0gLyogcG9pbnRlcnAoc2gpICovCisKKyAgLy8gUkFXPyBEYW5uIG1hbCB6dXJ1ZWNrCisgIGlmIChkZW1vbiA9PSBSQVcpIHJldHVybiAoc3RyaW5nKXNoOworCisgIC8vIFNlbGJlciBBcnRpa2VsIHN1Y2hlbiAuLi4KKyAgaWYgKGRlbW9uPT0yKQorICB7CisgICAgaWYgKGFydCkKKyAgICAgIGRlbW9uID0gU3VnZ2VzdEFydGljbGUoKTsKKyAgICBlbHNlCisgICAgICBkZW1vbj0wOyAvLyBLZWluIEFydGlrZWw6IGVnYWwgKFN1Z2dlc3RBcnRpY2xlIGlzdCB6ZWl0YXVmd2VuZGlnKQorICB9CisKKyAgaWYgKHBvaW50ZXJwKGFkaiA9IFF1ZXJ5UHJvcChQX05BTUVfQURKKSkgJiYgc2l6ZW9mKGFkaikpCisgICAgYWRqID0gZGVwb2ludGVyX2FkaihhZGosY2FzdXMsZGVtb24pOworCisgIGlmICghc3RyaW5ncChhZGopKSAgYWRqID0gIiI7CisKKyAgcmV0dXJuIFF1ZXJ5QXJ0aWNsZSggY2FzdXMsIGRlbW9uICkrYWRqK3NoOworfQorCisvLyBHcm9zc2dlc2NocmllYmVuZW4gTmFtZW4genVydWVja2dlYmVuCit2YXJhcmdzIHN0cmluZyBOYW1lKCBpbnQgY2FzdXMsIGludCBkZW1vbiApCit7CisgICAgcmV0dXJuIGNhcGl0YWxpemUobmFtZSggY2FzdXMsIGRlbW9uICl8fCIiKTsKK30KKworLy8gTGFuZ2Jlc2NocmVpYnVuZyBhbnplaWdlbgorcHVibGljIHZhcmFyZ3Mgc3RyaW5nIGxvbmcoaW50IG1vZGUpCit7CisgICAgcmV0dXJuIHByb2Nlc3Nfc3RyaW5nKCBRdWVyeVByb3AoUF9MT05HKSApOworfQorCisvLyBLdXJ6YmVzY2hyZWlidW5nIGFuemVpZ2VuLCBmYWxscyBuaWNodCB1bnNpY2h0YmFyCitwdWJsaWMgc3RyaW5nIHNob3J0KCkKK3sKKyAgc3RyaW5nIHNoOworCisgIC8vIFVuc2ljaHRiYXI/IERhbm4gZ2lidHMgbmljaHRzIHp1IHNlaGVuIC4uLgorICBpZiAoUXVlcnlQcm9wKFBfSU5WSVMpfHwhKHNoPVF1ZXJ5UHJvcChQX1NIT1JUKSkpCisgICAgcmV0dXJuIDA7CisgIAorICByZXR1cm4gcHJvY2Vzc19zdHJpbmcoc2gpKyIuXG4iOworfQorCisvLyBOYW1lbnMtQWRqZWt0aXZlIHNldHplbgorc3RhdGljIHN0cmluZyogX3NldF9uYW1lX2FkaihzdHJpbmd8c3RyaW5nKiBhZGplY3RpdmVzKQoreworICBpZiAoIWFkamVjdGl2ZXMpCisgICAgICBhZGplY3RpdmVzPSh7fSk7CisgIC8vIEluIEFycmF5IHVtd2FuZGVsbgorICBlbHNlIGlmICggIXBvaW50ZXJwKGFkamVjdGl2ZXMpKSAKKyAgICAgIGFkamVjdGl2ZXMgPSAoeyB0b19zdHJpbmcoYWRqZWN0aXZlcykgfSk7CisgIHJldHVybiBTZXQoIFBfTkFNRV9BREosIGFkamVjdGl2ZXMgKTsKK30KKworLy8gICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyBEZXRhaWxzLCBHZXJ1ZWNoZSwgTGFlcm0gIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworCisvLyBMb3ctbGV2ZWwgRnVua3Rpb24genVtIEVyZ2FlbnplbiB2b24gRGV0YWlscywgd2lyZCB2b24gZGVuIGRpdi4gQWRkLi4uKCkKKy8vIGdlcnVmZW4sIGRpZSBkYXMgcmljaHRpZ2UgTWFwcGluZyB1ZWJlcmdlYmVuLgorLy8gQWVuZGVydCBkYXMgTWFwcGluZyA8ZGV0YWlscz4gZGlyZWt0LgorcHJpdmF0ZSB2b2lkIF9hZGRfZGV0YWlscyhzdHJpbmd8c3RyaW5nKiBrZXlzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmd8c3RyaW5nKnxtYXBwaW5nfGNsb3N1cmUgZGVzY3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmcgZGV0YWlscyApCit7CisgIGlmIChzdHJpbmdwKGtleXMpKQorICAgIGRldGFpbHNba2V5c109ZGVzY3I7CisgIGVsc2UgaWYgKHBvaW50ZXJwKGtleXMpKQorICB7CisgICAgZm9yZWFjaChzdHJpbmcga2V5IDoga2V5cykKKyAgICAgIGRldGFpbHNbbG93ZXJfY2FzZShrZXkpXT1kZXNjcjsKKyAgfQorICBlbHNlCisgICAgcmFpc2VfZXJyb3IoIldyb25nIHR5cGUgdG8gYXJndW1lbnQgMSwgZXhwZWN0ZWQgc3RyaW5nfHN0cmluZyouXG4iKTsKK30KKworLy8gTG93LWxldmVsIEZ1bmt0aW9uIHp1bSBFbnRmZXJuZW4gdm9uIERldGFpbHMsIHdpcmQgdm9uIGRlbiBkaXYuIFJlbW92ZS4uLigpCisvLyBnZXJ1ZmVuLCBkaWUgZGFzIHJpY2h0aWdlIE1hcHBpbmcgdWViZXJnZWJlbi4KKy8vIEFlbmRlcnQgZGFzIE1hcHBpbmcgPGRldGFpbHM+IGRpcmVrdC4KK3ByaXZhdGUgdm9pZCBfcmVtb3ZlX2RldGFpbHMoc3RyaW5nfHN0cmluZyoga2V5cywgbWFwcGluZyBkZXRhaWxzICkKK3sKKyAgaWYgKHN0cmluZ3Aoa2V5cykpCisgICAgZGV0YWlscyAtPSAoW2tleXNdKTsKKyAgZWxzZSBpZiAocG9pbnRlcnAoa2V5cykpCisgICAgZGV0YWlscyAtPSBta21hcHBpbmcoa2V5cyk7CisgIGVsc2UKKyAgICByYWlzZV9lcnJvcigiV3JvbmcgdHlwZSB0byBhcmd1bWVudCAxLCBleHBlY3RlZCBzdHJpbmd8c3RyaW5nKi5cbiIpOworfQorCisvLyBEZXRhaWwocykgaGluenVmdWVnZW4KK3ZvaWQgQWRkRGV0YWlsKHN0cmluZ3xzdHJpbmcqIGtleXMsIHN0cmluZ3xzdHJpbmcqfG1hcHBpbmd8Y2xvc3VyZSBkZXNjcikKK3sKKyAgICBpbnQgaTsKKyAgICBtYXBwaW5nIGRldGFpbHM7CisKKyAgICBkZXRhaWxzID0gUXVlcnkoUF9ERVRBSUxTLCBGX1ZBTFVFKTsKKworICAgIC8vIF9hZGRfZGV0YWlscygpIGFlbmRlcm4gZGFzIE1hcHBpbmcgZGlyZWt0LCBTZXQgZXRjLiBuaWNodCBub2V0aWcuCisgICAgcmV0dXJuIF9hZGRfZGV0YWlscyhrZXlzLCBkZXNjciwgZGV0YWlscyk7Cit9CisKKy8vIERldGFpbChzKSBlbnRmZXJuZW4KK3ZhcmFyZ3Mgdm9pZCBSZW1vdmVEZXRhaWwoc3RyaW5nfHN0cmluZyoga2V5cyApCit7CisgIC8vIEFsbGUgbG9lc2NoZW4gZ2VodCBkaXJla3QgLi4uCisgIGlmICgha2V5cyApCisgICAgU2V0KFBfREVUQUlMUywgKFtdKSwgRl9WQUxVRSk7CisgIGVsc2UKKyAgICAvLyBfcmVtb3ZlX2RldGFpbHMoKSBhZW5kZXJuIGRhcyBNYXBwaW5nIGRpcmVrdCwgU2V0IGV0Yy4gbmljaHQgbm9ldGlnLgorICAgIF9yZW1vdmVfZGV0YWlscyhrZXlzLCBRdWVyeShQX0RFVEFJTFMsIEZfVkFMVUUpKTsKK30KKworLy8gU3BlY2lhbERldGFpbCBoaW56dWZ1ZWdlbgordm9pZCBBZGRTcGVjaWFsRGV0YWlsKHN0cmluZ3xzdHJpbmcqIGtleXMsIHN0cmluZyBmdW5jdGlvbm5hbWUgKQoreworICAgIGNsb3N1cmUgY2w7CisKKyAgICAvLyBBYnNpY2hlcm4hIFNvbnN0IGtvZW5udGUgamVkZXIgaW50ZXJuZSBGdW5rdGlvbmVuIGF1ZnJ1ZmVuCisgICAgaWYgKGV4dGVybl9jYWxsKCkgJiYKKyAgICAgICAgKGdldGV1aWQocHJldmlvdXNfb2JqZWN0KCkpICE9IGdldGV1aWQoKSB8fCBwcm9jZXNzX2NhbGwoKSkgJiYKKyAgICAgICAgIShvYmplY3RfbmFtZShwcmV2aW91c19vYmplY3QoKSkgPT0gIi9vYmovZG9vcm1hc3RlciIgJiYKKyAgICAgICAgICBmdW5jdGlvbm5hbWUgPT0gInNwZWNpYWxfZGV0YWlsX2Rvb3JzIikgKQorICAgICAgcmFpc2VfZXJyb3IoICJJbGxlZ2FsIHVzZSBvZiBBZGRTcGVjaWFsRGV0YWlsIVxuIiApOworCisgICAgLy8gQ2xvc3VyZSBnZW5lcmllcmVuCisgICAgaWYgKCAhc3RyaW5ncChmdW5jdGlvbm5hbWUpfHwKKyAgICAgICAgICEoY2wgPSBzeW1ib2xfZnVuY3Rpb24oIGZ1bmN0aW9ubmFtZSwgdGhpc19vYmplY3QoKSkpICkKKyAgICAgIHJldHVybjsKKworICAgIC8vIERldGFpbCBoaW56dWZ1ZWdlbgorICAgIEFkZERldGFpbCgga2V5cywgY2wgKTsKKyAgICByZXR1cm47Cit9CisKKy8vIFNwZWNpYWxEZXRhaWwocykgZW50ZmVybmVuCit2b2lkIFJlbW92ZVNwZWNpYWxEZXRhaWwoc3RyaW5nfHN0cmluZyoga2V5cyApCit7CisgIC8vIFJlbW92ZVNwZWNpYWxEZXRhaWwoMCkgd3VlcmRlIHNvbnN0IEFMTEUgRGV0YWlscyAoYXVjaCBkaWUKKyAgLy8gJ25vcm1hbGVuJykgbG9lc2NoZW4KKyAgaWYgKHBvaW50ZXJwKGtleXMpfHxzdHJpbmdwKGtleXMpKQorICAgIFJlbW92ZURldGFpbChrZXlzKTsKKyAgcmV0dXJuOworfQorCisvLyBMZXNiYXJlcyBEZXRhaWwgZWluZnVlZ2VuCit2b2lkIEFkZFJlYWREZXRhaWwoc3RyaW5nfHN0cmluZyoga2V5cywKKyAgICAgICAgICAgICAgICAgICBzdHJpbmd8c3RyaW5nKnxtYXBwaW5nfGNsb3N1cmUgZGVzY3IgKQoreworICAvLyBfYWRkX2RldGFpbHMoKSBhZW5kZXJuIGRhcyBNYXBwaW5nIGRpcmVrdCwgU2V0IGV0Yy4gbmljaHQgbm9ldGlnLgorICByZXR1cm4gX2FkZF9kZXRhaWxzKGtleXMsIGRlc2NyLCBRdWVyeShQX1JFQURfREVUQUlMUywgRl9WQUxVRSkpOworfQorCisvLyBMZXNiYXJlKHMpIERldGFpbChzKSBlbnRmZXJuZW4KK3ZhcmFyZ3Mgdm9pZCBSZW1vdmVSZWFkRGV0YWlsKHN0cmluZ3xzdHJpbmcqIGtleXMgKQoreworICAvLyBBbGxlIGxvZXNjaGVuIGdlaHQgZGlyZWt0IC4uLgorICBpZiAoIWtleXMgKQorICAgIFNldChQX1JFQURfREVUQUlMUywgKFtdKSwgRl9WQUxVRSk7CisgIGVsc2UKKyAgICAvLyBfcmVtb3ZlX2RldGFpbHMoKSBhZW5kZXJuIGRhcyBNYXBwaW5nIGRpcmVrdCwgU2V0IGV0Yy4gbmljaHQgbm9ldGlnLgorICAgIF9yZW1vdmVfZGV0YWlscyhrZXlzLCBRdWVyeShQX1JFQURfREVUQUlMUywgRl9WQUxVRSkpOworfQorCisvLyBHZXJhZXVzY2goZSkgZGF6dWZ1ZWdlbgordm9pZCBBZGRTb3VuZHMoc3RyaW5nfHN0cmluZyoga2V5cywKKyAgICAgICAgICAgICAgIHN0cmluZ3xzdHJpbmcqfG1hcHBpbmd8Y2xvc3VyZSBkZXNjciApCit7CisgIC8vIF9hZGRfZGV0YWlscygpIGFlbmRlcm4gZGFzIE1hcHBpbmcgZGlyZWt0LCBTZXQgZXRjLiBuaWNodCBub2V0aWcuCisgIHJldHVybiBfYWRkX2RldGFpbHMoa2V5cywgZGVzY3IsIFF1ZXJ5KFBfU09VTkRTLCBGX1ZBTFVFKSk7Cit9CisKKy8vIEdlcmFldXNjaChlKSBlbnRmZXJuZW4KK3ZhcmFyZ3Mgdm9pZCBSZW1vdmVTb3VuZHMoc3RyaW5nfHN0cmluZyoga2V5cyApCit7CisgIC8vIEFsbGUgbG9lc2NoZW4gZ2VodCBkaXJla3QgLi4uCisgIGlmICgha2V5cyApCisgICAgU2V0KFBfU09VTkRTLCAoW10pLCBGX1ZBTFVFKTsKKyAgZWxzZQorICAgIC8vIF9yZW1vdmVfZGV0YWlscygpIGFlbmRlcm4gZGFzIE1hcHBpbmcgZGlyZWt0LCBTZXQgZXRjLiBuaWNodCBub2V0aWcuCisgICAgX3JlbW92ZV9kZXRhaWxzKGtleXMsIFF1ZXJ5KFBfU09VTkRTLCBGX1ZBTFVFKSk7Cit9CisKKy8vIEdlcnUoZSljaChlKSBoaW56dWZ1ZWdlbgordm9pZCBBZGRTbWVsbHMoc3RyaW5nfHN0cmluZyoga2V5cywKKyAgICAgICAgICAgICAgIHN0cmluZ3xzdHJpbmcqfG1hcHBpbmd8Y2xvc3VyZSBkZXNjciApCit7CisgIC8vIF9hZGRfZGV0YWlscygpIGFlbmRlcm4gZGFzIE1hcHBpbmcgZGlyZWt0LCBTZXQgZXRjLiBuaWNodCBub2V0aWcuCisgIHJldHVybiBfYWRkX2RldGFpbHMoa2V5cywgZGVzY3IsIFF1ZXJ5KFBfU01FTExTLCBGX1ZBTFVFKSk7Cit9CisKKy8vIEdlcnUoZSljaChlKSBlbnRmZXJuZW4KK3ZhcmFyZ3Mgdm9pZCBSZW1vdmVTbWVsbHMoc3RyaW5nfHN0cmluZyoga2V5cyApCit7CisgIC8vIEFsbGUgbG9lc2NoZW4gZ2VodCBkaXJla3QgLi4uCisgIGlmICgha2V5cyApCisgICAgU2V0KFBfU01FTExTLCAoW10pLCBGX1ZBTFVFKTsKKyAgZWxzZQorICAgIC8vIF9yZW1vdmVfZGV0YWlscygpIGFlbmRlcm4gZGFzIE1hcHBpbmcgZGlyZWt0LCBTZXQgZXRjLiBuaWNodCBub2V0aWcuCisgICAgX3JlbW92ZV9kZXRhaWxzKGtleXMsIFF1ZXJ5KFBfU01FTExTLCBGX1ZBTFVFKSk7Cit9CisKKy8vIFRhc3RiYXJlKHMpIERldGFpbChzKSBoaW56dWZ1ZWdlbgordm9pZCBBZGRUb3VjaERldGFpbChzdHJpbmd8c3RyaW5nKiBrZXlzLAorICAgICAgICAgICAgICAgICAgICBzdHJpbmd8c3RyaW5nKnxtYXBwaW5nfGNsb3N1cmUgZGVzY3IgKQoreworICAvLyBfYWRkX2RldGFpbHMoKSBhZW5kZXJuIGRhcyBNYXBwaW5nIGRpcmVrdCwgU2V0IGV0Yy4gbmljaHQgbm9ldGlnLgorICByZXR1cm4gX2FkZF9kZXRhaWxzKGtleXMsIGRlc2NyLCBRdWVyeShQX1RPVUNIX0RFVEFJTFMsIEZfVkFMVUUpKTsKK30KKworLy8gVGFzdGJhcmUocykgRGV0YWlsKHMpIGVudGZlcm5lbgordmFyYXJncyB2b2lkIFJlbW92ZVRvdWNoRGV0YWlscyhzdHJpbmd8c3RyaW5nKiBrZXlzICkKK3sKKyAgLy8gQWxsZSBsb2VzY2hlbiBnZWh0IGRpcmVrdCAuLi4KKyAgaWYgKCFrZXlzICkKKyAgICBTZXQoUF9UT1VDSF9ERVRBSUxTLCAoW10pLCBGX1ZBTFVFKTsKKyAgZWxzZQorICAgIC8vIF9yZW1vdmVfZGV0YWlscygpIGFlbmRlcm4gZGFzIE1hcHBpbmcgZGlyZWt0LCBTZXQgZXRjLiBuaWNodCBub2V0aWcuCisgICAgX3JlbW92ZV9kZXRhaWxzKGtleXMsIFF1ZXJ5KFBfVE9VQ0hfREVUQUlMUywgRl9WQUxVRSkpOworfQorCisvLyBEZXRhaWxpbmZvcyBmdWVyIERldGFpbCBrZXksIFNwaWVsZXIgaGF0IGRpZSBSYXNzZSByYWNlCisvLyB1bmQgYmVudXR6dCBzZWluZW4gU2lubiBzZW5zZQordmFyYXJncyBzdHJpbmcgR2V0RGV0YWlsKHN0cmluZyBrZXksIHN0cmluZyByYWNlLCBpbnQgc2Vuc2UpCit7CisgIHN0cmluZ3xzdHJpbmcqfG1hcHBpbmd8Y2xvc3VyZSBkZXRhaWw7CisgIAorICBpZiAoc3RyaW5ncChyYWNlKSkgcmFjZSA9IGxvd2VyX2Nhc2UocmFjZSk7CisgIAorICBzd2l0Y2goc2Vuc2UpCisgIHsKKyAgICBjYXNlIFNFTlNFX1NNRUxMOiBkZXRhaWw9UXVlcnkoUF9TTUVMTFMsIEZfVkFMVUUpW2tleV07CisgICAgICAgICAgICAgICAgICAgICAgc2Vuc2U9RVBfU01FTEw7IGJyZWFrOworICAgIGNhc2UgU0VOU0VfU09VTkQ6IGRldGFpbD1RdWVyeShQX1NPVU5EUywgRl9WQUxVRSlba2V5XTsKKyAgICAgICAgICAgICAgICAgICAgICBzZW5zZT1FUF9TT1VORDsgYnJlYWs7CisgICAgY2FzZSBTRU5TRV9UT1VDSDogZGV0YWlsPVF1ZXJ5KFBfVE9VQ0hfREVUQUlMUywgRl9WQUxVRSlba2V5XTsKKyAgICAgICAgICAgICAgICAgICAgICBzZW5zZT1FUF9UT1VDSDsgYnJlYWs7CisgICAgY2FzZSBTRU5TRV9SRUFEOiAgZGV0YWlsPVF1ZXJ5KFBfUkVBRF9ERVRBSUxTLCBGX1ZBTFVFKVtrZXldOworICAgICAgICAgICAgICAgICAgICAgIHNlbnNlPUVQX1JERVQ7CisgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICBkZWZhdWx0OiAgICAgICAgICBkZXRhaWw9UXVlcnkoUF9ERVRBSUxTLCBGX1ZBTFVFKVtrZXldOworICAgICAgICAgICAgICAgICAgICAgIHNlbnNlPUVQX0RFVEFJTDsgYnJlYWs7CisgIH0KKworICBpZiAoIXN0cmluZ3AoZGV0YWlsKSkKKyAgeworICAgIGlmIChjbG9zdXJlcChkZXRhaWwpKQorICAgICAgZGV0YWlsID0gKHN0cmluZylmdW5jYWxsKGRldGFpbCxrZXkpOworICAgIGVsc2UgaWYgKG1hcHBpbmdwKGRldGFpbCkpCisgICAgICBkZXRhaWwgPSAoc3RyaW5nKShkZXRhaWxbcmFjZV18fGRldGFpbFswXSk7CisgICAgZWxzZSBpZiAocG9pbnRlcnAoZGV0YWlsKSkKKyAgICAgIGRldGFpbCA9IChzdHJpbmcpKGRldGFpbFtyYW5kb20oc2l6ZW9mKGRldGFpbCkpXSk7CisgIH0KKworICAvLyBGUCB2ZXJnZWJlbiAoc28gdm9yaGFuZGVuIDstKSApCisgIGlmIChkZXRhaWwpIEdpdmVFUChzZW5zZSxrZXkpOworCisgIHJldHVybiBkZXRhaWw7Cit9CisKKy8vIFRPRE86IE9CU09MRVQgKExpYmdyZXAgbm90d2VuZGlnKQordm9pZCByZWFkKCBzdHJpbmcgc3RyICkgeworICByYWlzZV9lcnJvcigiRGllc2UgRnVua3Rpb24gZXhpc3RpZXJ0IG5pY2h0IG1laHIuXG4iKTsKK30KKworCisvLyAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIFp1Z3JpZmZzZnVua3Rpb25lbiAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisKKy8vIERpZW5lbiBkYXp1LCBkaWUgZGlyZWt0ZSBNYW5pcHVsYXRpb24gZGVyIFByb3BzIHZvbiBhdXNzZW4genUgZXJzY2h3ZXJlbi4KKworLy8gRmlsdGVyLCB1bSBTcGVjaWFsZGV0YWlscyB6dSBlbGltaW5pZXJlbgorLy8gZXJzdGVsbHQgYXVzc2VyZGVtIG5lIEtvcGllIHZvbSBNYXBwaW5nLiAoV2ljaHRpZyEpCisvLyBXaXJkIHZvciBhbGxlbSBiZW5vZXRpZ3QsIHVtIFBfREVUQUlMUyBpbiBQX0RFVEFJTFMgdW5kIAorLy8gUF9TUEVDSUFMX0RFVEFJTFMgenUgdHJlZmZlbi4KK3ByaXZhdGUgaW50IF9jbG9zdXJlcyhzdHJpbmcgeCwgbWFwcGluZyBkZXRhaWxzLCBpbnQgeWVzICkgCit7IAorICAgIHJldHVybiB5ZXMgPyBjbG9zdXJlcChkZXRhaWxzW3hdKSA6ICFjbG9zdXJlcChkZXRhaWxzW3hdKTsgCit9CisKK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV9kZXRhaWxzKCkKK3sKKyAgcmV0dXJuIGZpbHRlcl9pbmRpY2VzKFF1ZXJ5KFBfREVUQUlMUywgRl9WQUxVRSksICMnX2Nsb3N1cmVzLAorICAgICAgUXVlcnkoUF9ERVRBSUxTLCBGX1ZBTFVFKSwwKTsKK30KKworc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X3NwZWNpYWxfZGV0YWlscygpCit7CisgIHJldHVybiBmaWx0ZXJfaW5kaWNlcyhRdWVyeShQX0RFVEFJTFMsIEZfVkFMVUUpLCMnX2Nsb3N1cmVzLAorICAgICAgUXVlcnkoUF9ERVRBSUxTLCBGX1ZBTFVFKSwxKTsKK30KKworc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X3JlYWRfZGV0YWlscygpIHsKKyAgcmV0dXJuIGRlZXBfY29weShRdWVyeShQX1JFQURfREVUQUlMUywgRl9WQUxVRSkpOworfQorCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfc291bmRfZGV0YWlscygpIHsKKyAgcmV0dXJuIGRlZXBfY29weShRdWVyeShQX1NPVU5EUywgRl9WQUxVRSkpOworfQorCitzdGF0aWMgbWFwcGluZyBfcXVlcnlfc21lbGxfZGV0YWlscygpIHsKKyAgcmV0dXJuIGRlZXBfY29weShRdWVyeShQX1NNRUxMUywgRl9WQUxVRSkpOworfQorCisKKy8vICAgICAgICAgICAgICAgICAgICAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMgS2xhc3Nlbi1NaXRnbGllZHNjaGFmdCAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisKKy8vIEtsYXNzZSBoaW56dWZ1ZWdlbgorcHVibGljIHZvaWQgQWRkQ2xhc3Moc3RyaW5nfHN0cmluZyogc3RyKQoreworICBpZiAoc3RyaW5ncChzdHIpKSAKKyAgICAgIHN0ciA9ICh7IHN0ciB9KTsKKyAgLy8gQWxpYXNlIGF1ZmxvZXNlbiB1bmQgaW1wbGl6aXRlIEtsYXNzZW4gYWRkaWVyZW4uCisgIHN0ciA9IChzdHJpbmcqKUNMQVNTREItPkFkZEltcGxpY2l0Q2xhc3NlcyhzdHIpOworICAvLyBTdW1tZSBtaXQgYWx0ZW4gS2xhc3NlbiBiaWxkZW4gdW5kIERvcHBlbHRlIGVsaW1pbmllcmVuCisgIHN0ciA9IHN0ciArIFF1ZXJ5KFBfQ0xBU1MsIEZfVkFMVUUpOworICBTZXQoIFBfQ0xBU1MsIG1faW5kaWNlcyhta21hcHBpbmcoc3RyKSksIEZfVkFMVUUpOworCisgIHJldHVybjsKK30KKworLy8gS2xhc3NlIGVudGZlcm5lbgordm9pZCBSZW1vdmVDbGFzcyhzdHJpbmd8c3RyaW5nKiBzdHIpCit7CisgaWYgKHN0cmluZ3Aoc3RyKSkgCisgICAgICBzdHIgPSAoeyBzdHIgfSk7CisKKyAgLy8gQWxpYXNlIGF1ZmxvZXNlbiB1bmQgaW1wbGl6aXRlIEtsYXNzZW4gYWRkaWVyZW4uCisgIHN0ciA9IChzdHJpbmcqKUNMQVNTREItPkFkZEltcGxpY2l0Q2xhc3NlcyhzdHIpOworCisgIC8vIFVuZCBhbGxlIC0gaW5rbHVzaXZlIGltcGxpeml0ZXIgS2xhc3NlbiAtIGVudGZlcm5lbgorICAvLyBUT0RPOiBQcnVlZmVuLCBvYiBkaWVzIGRpZSByaWNodGlnZSBFbnRzY2hlaWR1bmcgaXN0LgorICBTZXQoIFBfQ0xBU1MsIFF1ZXJ5KFBfQ0xBU1MsIEZfVkFMVUUpLXN0ciwgRl9WQUxVRSk7CisKKyAgcmV0dXJuOworfQorCisvLyBJc3QgZGFzIE9iamVrdCBNaXRnbGllZCBkZXIgS2xhc3NlIHN0cj8KK2ludCBpc19jbGFzc19tZW1iZXIoc3RyaW5nfHN0cmluZyogc3RyKQoreworICAvLyBLZWluZSBLbGFzc2UsIGtlaW5lIE1pdGdsaWVkc2NoYWZ0IC4uLgorICBpZiAoIXN0ciB8fCBzdHI9PSIiKSAKKyAgICAgIHJldHVybiAwOworCisgIC8vIEVzIHNvbGx0ZSBzY2hvbiBlaW4gQXJyYXkgc2VpbgorICBpZiAoc3RyaW5ncChzdHIpKSAKKyAgICAgIHN0ciA9ICh7IHN0ciB9KTsKKworICAvLyBLbGFzc2VuIHVuZCBJZHMgaW5zIEFycmF5CisgIHN0cmluZyAqY2xhc3Nlcz1RdWVyeVByb3AoUF9DTEFTUyk7CisgIGlmICghcG9pbnRlcnAoY2xhc3NlcykpCisgICAgcmV0dXJuIDA7CisKKyAgLy8gLi4gdW5kIHRlc3RlbgorICBmb3JlYWNoKHN0cmluZyBjbGFzcyA6IHN0cikKKyAgICBpZiAobWVtYmVyKGNsYXNzZXMsY2xhc3MpID4gLTEgKSByZXR1cm4gMTsKKworICByZXR1cm4gMDsKK30KKworLy8gS2xhc3NlIGRpcmVrdCBzZXR6ZW4gYWJmYW5nZW4KK3N0YXRpYyBzdHJpbmcqIF9zZXRfY2xhc3Moc3RyaW5nKiBjbGFzc2VzICkKK3sKKyAgU2V0KCBQX0NMQVNTLCAoe30pLCBGX1ZBTFVFICk7CisgIEFkZENsYXNzKGNsYXNzZXMpOworICByZXR1cm4gUXVlcnlQcm9wKFBfQ0xBU1MpOworfQorCisvLyAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyBNYXRlcmlhbC1IYW5kbGluZyAjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisvLyAgICAgICAgICAgICAgICAgICAgICAgIyMjIyMjIyMjIyMjIyMjIyMjIyMjCisKKy8vIE1hdGVyaWFsIHNldHplbgorc3RhdGljIG1hcHBpbmcgX3NldF9tYXRlcmlhbChtYXBwaW5nfHN0cmluZ3xzdHJpbmcqIG1hdCApCit7CisgIG1hcHBpbmcgbWF0cyA9IChbXSk7CisgIAorICBpZiAobWFwcGluZ3AobWF0KSkgCisgIHsKKyAgICBpZiggIXNpemVvZihtYXQpIHx8ICF3aWR0aG9mKG1hdCkgKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiUF9NQVRFUklBTDogZXhwZWN0ZWQgbWFwcGluZyB3aXRoIGF0IGxlYXN0IG9uZSAiCisgICAgICAgICJrZXkgYW5kIG9uZSB2YWx1ZSwgZ290ICUuNTBPXG4iLG1hdCkpOworICAgIGVsc2UgCisgICAgICBtYXRzID0gbWF0OworICB9CisgIGVsc2UgaWYgKHN0cmluZ3AobWF0KSkKKyAgICBtYXRzW21hdF09MTAwOworICBlbHNlCisgIHsKKyAgICBpbnQgc3ogPSBzaXplb2YobWF0KTsKKyAgICAvLyBLb21tdCBkYW5uIHZvciwgd2VubiA8bWF0PiAwIG9kZXIgKHt9KSBpc3QuCisgICAgaWYgKCAhc3ogKQorICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiUF9NQVRFUklBTDogZXhwZWN0ZWQgc3RyaW5nIG9yIG5vbi1lbXB0eSAiCisgICAgICAgICJtYXBwaW5nfHN0cmluZyosIGdvdCAlLjUwTy5cbiIsIG1hdCkpOworICAgIG1hdHMgPSBta21hcHBpbmcobWF0LCBhbGxvY2F0ZShzeiwgMTAwL3N6KSk7CisgIH0gCisgIHJldHVybiBTZXQoIFBfTUFURVJJQUwsIG1hdHMsIEZfVkFMVUUgKTsKK30KKworLy8gV29yYXVzIGJlc3RlaHQgZGFzIE9iamVrdD8KK3N0YXRpYyBtYXBwaW5nIF9xdWVyeV9tYXRlcmlhbCgpCit7CisgIG1peGVkIHJlczsKKyAgCisgIGlmICggIW1hcHBpbmdwKHJlcyA9IFF1ZXJ5KFBfTUFURVJJQUwsIEZfVkFMVUUpKSApCisgICAgcmV0dXJuIChbTUFUX01JU0M6MTAwXSk7CisgIAorICByZXR1cm4gcmVzOworfQorCisvLyBBbnRlaWwgdm9uIG1hdCBhbSBPYmpla3Q/CitpbnQgUXVlcnlNYXRlcmlhbCggc3RyaW5nIG1hdCApCit7CisgIG1hcHBpbmcgbWF0czsKKyAgCisgIGlmICggIW1hcHBpbmdwKG1hdHMgPSBRdWVyeVByb3AoUF9NQVRFUklBTCkpICkKKyAgICByZXR1cm4gMDsKKyAgCisgIHJldHVybiBtYXRzW21hdF07Cit9CisKKy8vIEFudGVpbCBkZXIgR3J1cHBlIGFtIE9iamVrdAoraW50IFF1ZXJ5TWF0ZXJpYWxHcm91cCggc3RyaW5nIG1hdGdyb3VwICkKK3sKKyAgcmV0dXJuIChpbnQpY2FsbF9vdGhlciggTUFURVJJQUxEQiwgIk1hdGVyaWFsR3JvdXAiLAorICAgICAgICAgICAgICAgICAgICAgICAgICBRdWVyeVByb3AoUF9NQVRFUklBTCksIG1hdGdyb3VwICk7Cit9CisKKworc3RyaW5nIE1hdGVyaWFsTGlzdCggaW50IGNhc3VzLCBtaXhlZCBpZGluZiApCit7CisgIHJldHVybiAoc3RyaW5nKWNhbGxfb3RoZXIoIE1BVEVSSUFMREIsICJDb252TWF0ZXJpYWxMaXN0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUXVlcnlQcm9wKFBfTUFURVJJQUwpLCBjYXN1cywgaWRpbmYgKTsKK30KKworc3RhdGljIGludCBfc2V0X3NpemUoaW50IHN6KSB7CisvL0dyb2Vzc2UgbXVzcyA+IDAgc2VpbiwgYWxsZXMgYW5kZXJlIGlzdCB1bnNpbm5pZyEgKDAgdW5kIG5lZy4gR3JvZXNzZW4KKy8vaGFiZW4ga2VpbmUgcGh5cy4gUmVsZXZhbnogdW5kIG1hY2hlbiB1LlUuIFByb2JsZW1lIG1pdCBPYmpla3RlbiwgZGllCisvL1NjaGFkZW4gaW4gQWJoYWVuZ2lna2VpdCBkZXIgR3JvZXNzZSBtYWNoZW4pCisgIGlmIChzej4wKQorICAgIFNldChQX1NJWkUsc3osRl9WQUxVRSk7CisgIHJldHVybihRdWVyeShQX1NJWkUsRl9WQUxVRSkpOworfQorCisvLyBQX0NMT05FX1RJTUUKK3N0YXRpYyBpbnQgX3F1ZXJ5X2Nsb25lX3RpbWUoKSB7IHJldHVybiBvYmplY3RfdGltZSgpOyB9CisKZGlmZiAtLWdpdCBhL3N0ZC90aGluZy9lbnZjaGsuYyBiL3N0ZC90aGluZy9lbnZjaGsuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNmNlMTNiCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3RoaW5nL2VudmNoay5jCkBAIC0wLDAgKzEsMzYgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyBlbnZjaGsuYyAtLSB2ZXJoaW5kZXJuLCBkYXNzIG9iamVrdGUgb2huZSBlbnYgaGVydW1mbGllZ2VuCisvLworLy8gJElkOiB0aGluZy5jIDYyODMgMjAwNy0wNS0wOSAyMTozMDozM1ogWmVzc3RyYSAkICAgICAgICAgICAgICAgICAgICAgIAorCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvbW92aW5nLmg+CisKK3Byb3RlY3RlZCB2b2lkIGNoZWNrX2Zvcl9lbnZpcm9ubWVudChzdHJpbmcgY2xvbmVyKQoreworICAvLyBDbG9uZXMsIGRpZSBpbm5lcmhhbGIgdm9uIDEwIFNla3VuZGVuIGtlaW4gRW52aXJvbm1lbnQgaGFiZW4sCisgIC8vIHNvbGxlbiBhdWYgLWRlYnVnIHNjcm9sbGVuLgorICBpZiAoIGNsb25lcCgpICYmICFlbnZpcm9ubWVudCgpICkgeworICAgIC8vIG1hbCBpbiBkZW4gTXVlbGxyYXVtIGJld2VnZW4sIGRhbWl0IGRpZXNlIE9iamVrdGUgendhciBuaWNodCB6ZXJzdG9lcnQKKyAgICAvLyB3ZXJkZW4sIGFiZXIgenVtaW5kZXN0IGhpbnRlcmhlciBub2NoIGVpbmZhY2ggYXVmZmluZGJhciBzaW5kLiAoVW5kCisgICAgLy8gZW50d2VkZXIgcGVyIGhhbmQgb2RlciBhdXRvbWF0aXNjaCBhdWZnZXJhZXVtdCB3ZXJkZW4ga29lbm5lbi4pCisgICAgbW92ZSgiL3Jvb20vbXVlbGxyYXVtIixNX05PQ0hFQ0t8TV9TSUxFTlQpOworICAgIGlmICggIXN0cmluZ3AoY2xvbmVyKSB8fCAhc2l6ZW9mKGNsb25lcikgKQorICAgICAgY2xvbmVyID0gIjxVbmJla2FubnQ+IjsKKyAgICByYWlzZV9lcnJvcigiT2JqZWt0IGhhdCBrZWluIEVudmlyb25tZW50LiBDbG9uZXI6IFsiK2Nsb25lcisiXSAiKTsKKyAgfQorfQorCit2b2lkIGNyZWF0ZSgpCit7CisJaWYoIGNsb25lcCgpICkgCisgICAgY2FsbF9vdXQoIydjaGVja19mb3JfZW52aXJvbm1lbnQsIDMsIG9iamVjdF9uYW1lKHByZXZpb3VzX29iamVjdCgpKSk7Cit9CmRpZmYgLS1naXQgYS9zdGQvdGhpbmcvbGFuZ3VhZ2UuYyBiL3N0ZC90aGluZy9sYW5ndWFnZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRhM2Q2ZjkKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdGhpbmcvbGFuZ3VhZ2UuYwpAQCAtMCwwICsxLDE5OSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHRoaW5nL2xhbmd1YWdlLmMgLS0gbGFuZ3VhZ2UgaGFuZGxpbmcgb2JqZWN0CisvLworLy8gJElkOiBsYW5ndWFnZS5jIDgzNTkgMjAxMy0wMi0wOSAxMTo0MzozOVogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2luY2x1ZGUgPHRoaW5nL2xhbmd1YWdlLmg+CisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisKKy8vIEtlaW4gY3JlYXRlKCkKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgcmV0dXJuOworfQorCisvL0ludmVyc2lvbiwgZGFtaXQgRGVmYXVsdHdlcnQgdm9uIDAgZWluZW4gQXJ0aWtlbCBhdXNnaWJ0CitzdGF0aWMgaW50IF9xdWVyeV9hcnRpY2xlKCkgeyByZXR1cm4gIVF1ZXJ5KFBfQVJUSUNMRSk7IH0KKworc3RhdGljIGludCBfc2V0X2FydGljbGUoaW50IGFydCkgeyByZXR1cm4gIVNldChQX0FSVElDTEUsIWFydCk7IH0KKworLy8gQmVzdGltbXRlbiBBcnRpa2VsIGJlc3RpbW1lbgorcHJpdmF0ZSBzdHJpbmcgcXVlcnlfY19hcnRpY2xlKGludCBjYXN1cykKK3sKKyAgaWYgKFF1ZXJ5UHJvcChQX1BMVVJBTCkpCisgICAgcmV0dXJuICh7ICJkaWUgIiwgImRlciAiLCAiZGVuICIsICJkaWUgIn0pW2Nhc3VzXTsKKworICByZXR1cm4gKHsgKHsgImRhcyAiLCAiZGVzICIsICJkZW0gIiwgImRhcyAiIH0pLAorICAgICAgICAgICAgKHsgImRlciAiLCAiZGVzICIsICJkZW0gIiwgImRlbiAiIH0pLAorICAgICAgICAgICAgKHsgImRpZSAiLCAiZGVyICIsICJkZXIgIiwgImRpZSAiIH0pIH0pCisgICAgWyhpbnQpUXVlcnlQcm9wKFBfR0VOREVSKV1bY2FzdXNdOworfQorCisvLyBFbmRlIGZ1ZXIgQXJ0aWtlbCB1bmQgQWRqZWt0aXZlCitwcml2YXRlIHZhcmFyZ3Mgc3RyaW5nIHF1ZXJ5X2dfc3VmZml4KGludCBnZW4sIGludCBjYXN1cywgaW50IGFuemFobCkKK3sKKyAgcmV0dXJuICh7ICh7ICh7ICIiLCJlIn0pLCAoeyJlcyIsImVyIn0pLCAoeyJlbSIsImVuIn0pLCAoeyAgIiIsImUifSkgfSksCisJICAgICh7ICh7ICIiLCJlIn0pLCAoeyJlcyIsImVyIn0pLCAoeyJlbSIsImVuIn0pLCAoeyJlbiIsImUifSkgfSksCisJICAgICh7ICh7ImUiLCJlIn0pLCAoeyJlciIsImVyIn0pLCAoeyJlciIsImVuIn0pLCAoeyAiZSIsImUifSkgfSkgfSkKKyAgICBbZ2VuXVtjYXN1c11bYW56YWhsXTsKK30KKworLy8gQXJ0aWtlbCB2b3JzY2hsYWdlbjogZ2lidCBlcyBub2NoIG1laHIgT2JqZWt0ZSBpbSBpbnY/Cit2YXJhcmdzIGludCBTdWdnZXN0QXJ0aWNsZShzdHJpbmcgaWQpCit7CisgIG9iamVjdCBvYiwqb2JzOworCisgIC8vIFJhdW0gb2RlciBNYXN0ZXI6IEJlc3RpbW10LgorICBpZiAoIWVudmlyb25tZW50KCkpIHJldHVybiAxOworCisgIC8vIEtlaW5lIGlkPyBEYW5uIHJhdXMKKyAgaWYgKCFpZCkgcmV0dXJuIDE7CisKKyAgLy8gT2JqZWt0IG1pdCBnbGVpY2hlbSBOYW1lbiBpbSBlbnY/IERhbm4gdW5iZXN0aW1tdAorICBmb3IgKCBvYj1maXJzdF9pbnZlbnRvcnkoZW52aXJvbm1lbnQoKSkgOyBvYiA7IG9iPW5leHRfaW52ZW50b3J5KG9iKSApCisgICAgaWYgKCBvYiE9dGhpc19vYmplY3QoKSYmIGlkPT0oc3RyaW5nKW9iLT5RdWVyeVByb3AoUF9OQU1FKSApCisgICAgICByZXR1cm4gMDsKKworICAvLyBzb25zdCBiZXN0aW1tdAorICByZXR1cm4gMTsKK30KKworLy8gQXJ0aWtlbCBiZXN0aW1tZW4KK3ZhcmFyZ3Mgc3RyaW5nIFF1ZXJ5QXJ0aWNsZShpbnQgY2FzdXMsIGludCBkZW0sIGludCBmb3JjZSkKK3sKKyAgLy8gS2VpbiBBcnRpa2VsCisgIGlmICghZm9yY2UgJiYhKFF1ZXJ5UHJvcChQX0FSVElDTEUpKSkgcmV0dXJuICIiOworCisgIC8vIEFydGlrZWxhcnQgYXVzc3VjaGVuCisgIGlmICggZGVtPT0yICkgZGVtID0gU3VnZ2VzdEFydGljbGUoUXVlcnlQcm9wKFBfTkFNRSkpOworCisgIC8vIEJlc3RpbW10ZXIgQXJ0aWtlbAorICBpZiAoZGVtKSByZXR1cm4gcXVlcnlfY19hcnRpY2xlKGNhc3VzKTsKKworICAvLyBVbmJlc3RpbW10ZXIgQXJ0aWtlbAorICBpZiAoUXVlcnlQcm9wKFBfUExVUkFMKSkgcmV0dXJuICIiOworICAKKyAgcmV0dXJuIHNwcmludGYoImVpbiVzICIscXVlcnlfZ19zdWZmaXgoKGludClRdWVyeVByb3AoUF9HRU5ERVIpLGNhc3VzKSk7Cit9CisKKy8vIEJlc2l0emFuemVpZ2VyIGZ1ZXIgT2JqZWt0IGJlc3RpbW1lbgordmFyYXJncyBzdHJpbmcgUXVlcnlPd24oaW50IGNhc3VzKQoreworICByZXR1cm4gc3ByaW50ZigiRGVpbiVzIixxdWVyeV9nX3N1ZmZpeChRdWVyeVByb3AoUF9HRU5ERVIpLGNhc3VzKSk7Cit9CisKKy8vIFBvc3Nlc3NpdnByb25vbWVuIGJlc3RpbW1lbgordmFyYXJncyBzdHJpbmcgUXVlcnlQb3NzUHJvbm91bihtaXhlZCB3aGF0LCBpbnQgY2FzdXMsIGludCBudW1iZXIpCit7CisgIGludCBnZW4yOworCisgIC8vIEdlc2NobGVjaHQgZXJtaXR0ZWxuCisgIGdlbjIgPSAob2JqZWN0cCh3aGF0KT8oaW50KXdoYXQtPlF1ZXJ5UHJvcChQX0dFTkRFUik6KGludCl3aGF0KTsKKworICAvLyBQbHVyYWwgaXN0IHNjaG9lbiBlaW5mYWNoCisgIGlmIChRdWVyeVByb3AoUF9QTFVSQUwpKSByZXR1cm4gImlociIrcXVlcnlfZ19zdWZmaXgoZ2VuMiwgY2FzdXMsIG51bWJlcik7CisKKyAgcmV0dXJuICgoKCgoaW50KVF1ZXJ5UHJvcCggUF9HRU5ERVIgKSk9PUZFTUFMRSApPyAiaWhyIjoic2VpbiIpKworICAgICAgICAgIHF1ZXJ5X2dfc3VmZml4KGdlbjIlMywgY2FzdXMsIG51bWJlcikpOworfQorCisvLyBQcm9ub21lbiBiZXN0aW1tZW4gbmFjaCBLTkcKK3ZhcmFyZ3Mgc3RyaW5nIFF1ZXJ5UHJvbm91bihpbnQgY2FzdXMpCit7CisgIGludCBnZW5kZXI7CisKKyAgLy8gUGx1cmFsIGlzdCBpbW1lciBlaW5mYWNoIC4uLgorICBpZiAoUXVlcnlQcm9wKFBfUExVUkFMKSkgCisgIHsKKyAgICAgaWYgKGNhc3VzPT1XRU0pIHJldHVybiAiaWhuZW4iOworICAgICByZXR1cm4gInNpZSI7CisgIH0KKworICBzd2l0Y2goUXVlcnlQcm9wKFBfR0VOREVSKSkKKyAgeworICAgIGNhc2UgRkVNQUxFOgorICAgICAgaWYgKGNhc3VzPT1XRVNTRU4pIHJldHVybiAiaWhyZXIiOworICAgICAgaWYgKGNhc3VzPT1XRU0pIHJldHVybiAiaWhyIjsKKyAgICAgIHJldHVybiAic2llIjsKKworICAgIGNhc2UgTUFMRToKKyAgICAgIGlmIChjYXN1cz09V0VSKSByZXR1cm4gImVyIjsKKyAgICAgIGlmIChjYXN1cz09V0VTU0VOKSByZXR1cm4gInNlaW5lciI7CisgICAgICBpZiAoY2FzdXM9PVdFTSkgcmV0dXJuICJpaG0iOworICAgICAgcmV0dXJuICJpaG4iOworICB9ICAgIAorICBpZiAoY2FzdXM9PVdFU1NFTikgcmV0dXJuICJzZWluZXIiOworICBpZiAoY2FzdXM9PVdFTSkgcmV0dXJuICJpaG0iOworICByZXR1cm4gImVzIjsgLy9mYWxsLXRocm91Z2gKK30KKworLy8gQW5yZWRlIGZ1ZXIgU3BpZWxlciBiZXN0aW1tZW4KK3ZhcmFyZ3Mgc3RyaW5nIFF1ZXJ5RHUoaW50IGNhc3VzLGludCBnZW5kZXIsaW50IHphaGwpCit7CisgIHJldHVybgorICAgICh7ICh7KHsgICAgImR1IiwgICAiaWhyIn0pLCh7ICAgICJkdSIsICAgImlociJ9KSwoeyAgICAiZHUiLCAgICJpaHIifSl9KSwKKyAgICAgICAoeyh7ImRlaW5lciIsICAiZXVlciJ9KSwoeyJkZWluZXIiLCAgImV1ZXIifSksKHsiZGVpbmVyIiwgICJldWVyIn0pfSksCisgICAgICAgKHsoeyAgICJkaXIiLCAgImV1Y2gifSksKHsgICAiZGlyIiwgICJldWNoIn0pLCh7ICAgImRpciIsICAiZXVjaCJ9KX0pLAorICAgICAgICh7KHsgICJkaWNoIiwgICJldWNoIn0pLCh7ICAiZGljaCIsICAiZXVjaCJ9KSwoeyAgImRpY2giLCAgImV1Y2gifSl9KQorICAgICB9KVtjYXN1c11bZ2VuZGVyXVt6YWhsXTsKK30KKworLy8gV2VsY2hlcyBHZXNjaGxlY2h0IGhhdCBkYXMgT2JqZWt0IGFscyBTdHJpbmc/CitzdHJpbmcgUXVlcnlHZW5kZXJTdHJpbmcoKQoreworICBzd2l0Y2goIChpbnQpUXVlcnlQcm9wKCBQX0dFTkRFUiApKQorICB7CisgICAgY2FzZSBNQUxFOiAgIHJldHVybiAibWFlbm5saWNoIjsKKyAgICBjYXNlIEZFTUFMRTogcmV0dXJuICJ3ZWlibGljaCI7CisgIH0KKyAgcmV0dXJuKCJzYWVjaGxpY2giKTsgLy9mYWxsLXRocm91Z2gKK30KKworLy8gQXJ0aWtlbCBkdXJjaGRla2xpbmllcmVuIG5hY2ggS2FzdXMsIE51bWVydXMsIEdlbnVzIHVuZCBBcnQKKy8vIGRlcyBBcnRpa2VscyAoZGVtb249PWJlc3RpbW10KQordmFyYXJncyBzdHJpbmcgRGVjbEFkaihtaXhlZCBhZGosIGludCBjYXN1cywgaW50IGRlbW9uKQoreworCS8vIFVucmVnZWxtYWVzc2lnZSBBZGpla3RpdmUKKwlpZiggcG9pbnRlcnAoYWRqKSApIHJldHVybiBhZGpbY2FzdXNdKyIgIjsKKworICAvLyBGYWxzY2hlciBUeXA/IFVuZCBUc2NodWVzcyAuLi4KKyAgaWYgKCFzdHJpbmdwKGFkaikpIHJldHVybiAiIjsKKworICAvLyBQbHVyYWwgaXN0IGVpbmZhY2gKKyAgaWYgKFF1ZXJ5UHJvcChQX1BMVVJBTCkpCisgIHsKKyAgICAvLyBCZXN0aW1tdAorICAgIGlmIChkZW1vbikgcmV0dXJuIGFkaisiZW4gIjsKKworICAgIC8vIFVuYmVzdGltbXQKKyAgICByZXR1cm4gYWRqICsgKHsgImUgIiwgImVyICIsICJlbiAiLCAiZSAiIH0pW2Nhc3VzXTsKKyAgfQorICAKKyAgaWYgKCBkZW1vbiApCisgICAgcmV0dXJuIGFkaiArICh7ICh7ICJlICIgLCAiZW4gIiwgImVuICIsICJlICIgIH0pLAorCQkgICAgKHsgImUgIiAsICJlbiAiLCAiZW4gIiwgImVuICIgfSksCisJCSAgICAoeyAiZSAiICwgImVuICIsICJlbiAiLCAiZSAiICB9KSB9KQorICAgICAgWyhpbnQpUXVlcnlQcm9wKCBQX0dFTkRFUiApXVtjYXN1c107CisgIGVsc2UKKyAgICByZXR1cm4gYWRqICsgKHsgKHsgImVzICIsICJlbiAiLCAiZW4gIiwgImVzICIgfSksCisJCSAgICAoeyAiZXIgIiwgImVuICIsICJlbiAiLCAiZW4gIiB9KSwKKwkJICAgICh7ICJlICIgLCAiZW4gIiwgImVuICIsICJlICIgIH0pIH0pCisgICAgICBbKGludClRdWVyeVByb3AoIFBfR0VOREVSICldW2Nhc3VzXTsKK30KKworLy8gUF9HRU5ERVIgc2V0emVuLiBFcyBzaW5kIG51ciAwLDEgdW5kIDIgKE1BTEUsRkVNQUxFLE5FVVRFUikgZXJsYXVidAorc3RhdGljIGludCBfc2V0X2dlbmRlcihpbnQgaSkKK3sKKyAgaWYgKGk+LTEmJmk8MykgcmV0dXJuIFNldChQX0dFTkRFUixpKTsKKyAgcmV0dXJuIFF1ZXJ5KFBfR0VOREVSKTsKK30KZGlmZiAtLWdpdCBhL3N0ZC90aGluZy9saWdodC5jIGIvc3RkL3RoaW5nL2xpZ2h0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzY0MTFiNAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC90aGluZy9saWdodC5jCkBAIC0wLDAgKzEsNjIgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB0aGluZy9kZXNjcmlwdGlvbi5jIC0tIExpY2h0c3lzdGVta29tcG9uZW50ZW4gZnVlciBTdGFuZGFyZG9iamVrdGUKKy8vCisvLyAkSWQ6IGRlc2NyaXB0aW9uLmMgNzYzNSAyMDEwLTA4LTE5IDIxOjIxOjMwWiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcyxydHRfY2hlY2tzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHRoaW5nL2xhbmd1YWdlLmg+CisjaW5jbHVkZSA8aG9vay5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8dGhpbmcvbGlnaHR0eXBlcy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKworLy8gICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMgU3lzdGVtLUZ1bmt0aW9uZW4gIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIworLy8gICAgICAgICAgICAgICAgICAgICAgICMjIyMjIyMjIyMjIyMjIyMjIyMjIworCisvLyBPYmpla3QgZXJ6ZXVnZW4KK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZSgpCit7CisgIFNldCggUF9MSUdIVCwgMCApOworICBTZXQoIFBfTElHSFRfVFlQRSwgTFRfTUlTQyk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfSAgICAgCisKKy8vIExpY2h0c3kgLi4uIHN5cyAuLi4KK3N0YXRpYyBpbnQgX3F1ZXJ5X3RvdGFsX2xpZ2h0KCkgeyByZXR1cm4gUXVlcnlQcm9wKFBfTElHSFQpOyB9CisKK3N0YXRpYyBpbnQgX3NldF9saWdodCggaW50IGxpZ2h0ICkKK3sKKyAgICBvYmplY3QgZW52ID0gdGhpc19vYmplY3QoKTsKKworICAgIC8vIFRPRE86IFRlbXBvcmFlciBMaWNodGxldmVsIGluIGdlZWlnbmV0ZSBXZXJ0ZWZlbnN0ZXIgendpbmdlbi4KKyAgICBpZiAobGlnaHQgPiAxMDApCisgICAgICBsaWdodCA9IDEwMDsKKyAgICBlbHNlIGlmIChsaWdodCA8IC0xMDApCisgICAgICBsaWdodCA9IC0xMDA7CisgICAKKyAgICB3aGlsZSAoIG9iamVjdHAoZW52ID0gZW52aXJvbm1lbnQoZW52KSkgKQorICAgICAgICAvLyBKYS4gTWFuIHJ1ZnQgZGllIF9zZXRfeHh4KCktRnVua3Rpb25lbiBlaWdlbnRsaWNoIG5pY2h0IGRpcmVrdCBhdWYuCisgICAgICAgIC8vIEFiZXIgZGFzIExpY2h0c3lzdGVtIGlzdCBzY2hvbiAqc28qIHJlY2hlbmludGVuc2l2IHVuZCBnZXJhZGUgZGVyCisgICAgICAgIC8vIFBfTEFTVF9DT05URU5UX0NIQU5HRS1DYWNoZSB3aXJkICpzbyogb2Z0IGJlbm9ldGlndCwgZGFzcyBlcyBtaXIKKyAgICAgICAgLy8gZGEgdW0gamVkZXMgYmlzc2NoZW4gUmVjaGVuemVpdCBnZWh0LgorICAgICAgICAvLyBEZXIgWndlY2sgaGVpbGlndCBqYSBiZWthbm50bGljaCBkaWUgTWl0dGVsLiA7LSkKKyAgICAgICAgLy8KKyAgICAgICAgLy8gVGlhbWFrCisgICAgICAgIGVudi0+X3NldF9sYXN0X2NvbnRlbnRfY2hhbmdlKCk7CisgICAgCisgICAgcmV0dXJuIFNldCggUF9MSUdIVCwgbGlnaHQsIEZfVkFMVUUpOworfQorCmRpZmYgLS1naXQgYS9zdGQvdGhpbmcvbW92aW5nLmMgYi9zdGQvdGhpbmcvbW92aW5nLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzgwYWM0MQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC90aGluZy9tb3ZpbmcuYwpAQCAtMCwwICsxLDIwMSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHRoaW5nL21vdmluZy5jIC0tIG9iamVjdCBtb3ZpbmcKKy8vCisvLyAkSWQ6IG1vdmluZy5jIDg4OTIgMjAxNC0wOC0wNCAxOTo0ODoyOFogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKworLy8gRGFzIE9iamVrdCBiZXdlZ2VuLgorLy8gUnVlY2tnYWJlIDEgaXN0IEVyZm9sZywgPD0wIGlzdCBGZWhsZXIKKworLy8gYSkgUF9OT0RST1AvUF9OT0dFVC1CZWhhbmRsdW5nLgorLy8gYikgenVtIFVlYmVyc2NocmVpYmVuCitwcm90ZWN0ZWQgaW50IFByZXZlbnRNb3ZlKG9iamVjdCBkZXN0LCBvYmplY3Qgb2xkZW52LCBpbnQgbWV0aG9kKSB7CisgIGludCB0bXA7CisgIAorICAvLyBNX05PQ0hFQ0s/IC0+IEJld2VndW5nIGVoIGVybGF1YnQgKHVuZCBSdWVja2dhYmV3ZXJ0IHd1ZXJkZSBpZ25vcmllcnQpCisgIGlmICgobWV0aG9kJk1fTk9DSEVDSykpIHsKKyAgICAvLyBCZWkgTV9OT0NIRUNLIHp3YXIgUHJldmVudCogYXVmcnVmZW4sIGFiZXIgZGFzIFJlc3VsdGF0IGlnbm9yaWVyZW4KKyAgICBpZiAob2xkZW52KSBvbGRlbnYtPlByZXZlbnRMZWF2ZSh0aGlzX29iamVjdCgpLGRlc3QpOworICAgIGRlc3QtPlByZXZlbnRJbnNlcnQodGhpc19vYmplY3QoKSk7CisKKyAgICByZXR1cm4gMDsgLy8gZGFzIHdhcnMsIHJlc3QgaXN0IGVnYWwuCisgIH0KKworICAvLyBQX05PRFJPUCB2ZXJoaW5kZXJ0IHdlZ2dlYmVuCisgIGlmICgobWV0aG9kICYgKE1fUFVUfE1fR0lWRSkpICYmIFF1ZXJ5UHJvcChQX05PRFJPUCkpCisgICAgICByZXR1cm4gTUVfQ0FOVF9CRV9EUk9QUEVEOworCisgIC8vIFBfTk9HRVQgdmVyaGluZGVydCBuZWhtZW4KKyAgaWYgKChtZXRob2QgJiAoTV9HRVR8TV9HSVZFKSkgJiYgUXVlcnlQcm9wKFBfTk9HRVQpKQorICAgICAgcmV0dXJuIE1FX0NBTlRfQkVfVEFLRU47CisKKyAgLy8gR2V3aWNodCBlcm1pdHRlbG4KKyAgaWYgKCAhKHRtcCA9IChpbnQpUXVlcnlQcm9wKFBfVE9UQUxfV0VJR0hUKSkgKQorICAgICAgdG1wID0gKGludClRdWVyeVByb3AoUF9XRUlHSFQpOworICAgICAgICAKKyAgLy8gSXN0IGRhcyBPYmpla3QgbmljaHQgenUgc2Nod2VyPworICBpZiAoICh0bXAgPSAoaW50KWRlc3QtPk1heUFkZFdlaWdodCh0bXApKSA8IDApIHsKKyAgICAgIGlmICggdG1wID09IC0yICkgcmV0dXJuIE1FX1RPT19IRUFWWV9GT1JfRU5WOworICAgICAgcmV0dXJuIE1FX1RPT19IRUFWWTsKKyAgfQorCisgIC8vIElzdCBkYXMgWmllbG9iamVrdCBzY2hvbiB2b2xsPworICBpZiAoICFkZXN0LT5NYXlBZGRPYmplY3QodGhpc19vYmplY3QoKSkgKQorICAgICAgcmV0dXJuIFRPT19NQU5ZX09CSkVDVFM7CisKKyAgLy8gRGFyZiBoaW5hdXNiZXdlZ3Qgd2VyZGVuPworICBpZiAoIG9sZGVudiAmJiBvbGRlbnYtPlByZXZlbnRMZWF2ZSh0aGlzX29iamVjdCgpLCBkZXN0KSApCisgICAgICByZXR1cm4gTUVfQ0FOVF9MRUFWRV9FTlY7CisKKyAgLy8gRGFyZiBoaW5laW5iZXdlZ3Qgd2VyZGVuPworICBpZiAoIGRlc3QtPlByZXZlbnRJbnNlcnQodGhpc19vYmplY3QoKSkgKQorICAgICAgcmV0dXJuIE1FX0NBTlRfQkVfSU5TRVJURUQ7CisKKyAgcmV0dXJuKDApOworfQorCisvLyB6dW0gVWViZXJzY2hyZWliZW4uLi4KK3Byb3RlY3RlZCB2b2lkIE5vdGlmeU1vdmUob2JqZWN0IGRlc3QsIG9iamVjdCBvbGRlbnYsIGludCBtZXRob2QpIHsKK30KKwordmFyYXJncyBpbnQgbW92ZSggb2JqZWN0fHN0cmluZyBkZXN0LCBpbnQgbWV0aG9kICkKK3sKKyAgb2JqZWN0IG9sZGVudjsKKyAgaW50IHRtcDsKKyAgc3RyaW5nIGZuLHZjOworICBtaXhlZCBzZW5zOworCisgIGlmICghb2JqZWN0cChkZXN0KSAmJiAhc3RyaW5ncChkZXN0KSkKKyAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoIldyb25nIGFyZ3VtZW50IDEgdG8gbW92ZSgpLiAnZGVzdCcgbXVzdCBiZSBhICIKKyAgICAgICAgICAgICJzdHJpbmcgb3Igb2JqZWN0ISBBcmd1bWVudCB3YXM6ICUuMTAwT1xuIiwKKyAgICAgICAgICAgIGRlc3QpKTsKKworICAvLyBKZXR6aWdlIFVtZ2VidW5nIG1lcmtlbgorICBvbGRlbnYgPSBlbnZpcm9ubWVudCgpOworCisgIC8vIEJld2VndW5nIGluIFBhcmEtV2VsdC1SYWV1bWU/CisgIC8vIHRtcCBpc3QgZGllIFppZWwtUGFyYWxsZWx3ZWx0bnVtbWVyCisgIGlmICghZW52aXJvbm1lbnQoKXx8IWxpdmluZyhlbnZpcm9ubWVudCgpKXx8CisgICAgICAhaW50cCh0bXAgPShpbnQpZW52aXJvbm1lbnQoKS0+UXVlcnkoUF9QQVJBKSkpCisgICAgdG1wPTA7CisgICAgCisgIC8vIFdlbm4gZGFzIE9iamVrdCB2b24gZWluZW0gaW4gZGVyIFBhcmF3ZWx0IGJlZmluZGxpY2hlbiBTcGllbGVyCisgIC8vIG9kZXIgTlBDIGJld2VndCB3aXJkLCBzb2xsdGUgZXMgYXVjaCB3aWVkZXIgaW4gZGVyIFBhcmF3ZWx0IGxhbmRlbi4KKyAgLy8gVW0gUmVjaGVuemVpdCB6dSBzcGFyZW4sIHdpcmQgYW5nZW5vbW1lbiwgZGFzcyBiZWkgQmV3ZWd1bmdlbiBpbgorICAvLyBkYXMgSW52IG9kZXIgRW52IGRlcyBTcGllbGVycyAnZGVzdCcgYWxzIE9iamVrdCB1ZWJlcmdlYmVuIHdpcmQsCisgIC8vIHdvaGluZ2VnZW4gYmVpIEJld2VndW5nZW4gaW4gTmFjaGJhcnJhZXVtZSAoZGllIGVpZ2VudGxpY2ggbnVyCisgIC8vIGludGVyZXNzYW50IHNpbmQpICdkZXN0JyBhbHMgRmlsZW5hbWUgYW5nZWdlYmVuIHdpcmQuCisgIGlmICh0bXAmJiFvYmplY3RwKGRlc3QpJiYhZW52aXJvbm1lbnQoZGVzdCkpIHsKKyAgICAgIC8vIEZhbGxzIGRlciBaaWVscmF1bSBuaWNodCBzY2hvbiBleHBsaXppdCBpbiBkZXIgUGFyYWxsZWx3ZWx0IGlzdCwKKyAgICAgIC8vIG5ldWVuIFppZWxyYXVtIHN1Y2hlbi4gQWJlciBudXIsIHdlbm4gZGFzIFppZWwga2VpbiBDbG9uZSBpc3QuIFNvbnN0CisgICAgICAvLyBidWdndCwgd2VubiBtYW4gdmVyc3VjaHQsIG5hY2ggcmF1bSM0Ml5wYXJhIHp1IGJld2VnZW4uCisgICAgICBpZiAoIUlTX1BBUkEoZGVzdCkgJiYgc3RycnN0cihkZXN0LCIjIik9PS0xKSB7CisgICAgICAgIGZuPWRlc3QrIl4iK3RtcDsKKworICAgICAgICAvLyBEZXIgUGFyYXdlbHQtUmF1bSB3aXJkIG51ciB6dW0gWmllbCwgd2VubiBlciBhKSBleGlzdGllcnQKKyAgICAgICAgLy8gdW5kIGIpIGF1Y2ggdm9uIFNwaWVsZXJuIGJldHJldGVuIHdlcmRlbiBkYXJmLiBMZXR6dGVyZXMKKyAgICAgICAgLy8gS3JpdGVyaXVtIGthbm4gbnVyIG1pdCBpbSBPYmpla3QgZ2VzZXR6dGVyIFByb3BlcnR5CisgICAgICAgIC8vIFBfVEVTVFBMQVlFUiB1bWdhbmdlbiB3ZXJkZW4uCisgICAgICAgICAgaWYgKCAoZmluZF9vYmplY3QoZm4pIHx8ICgoZmlsZV9zaXplKGZuKyIuYyIpPjB8fAorICAgICAgICAgICAgICAgICAgKGZpbGVfc2l6ZSh2Yz1pbXBsb2RlKGV4cGxvZGUoZm4sIi8iKVswLi48Ml0sIi8iKSsKKyAgICAgICAgICAgICAgICAgICIvdmlydHVhbF9jb21waWxlci5jIik+MCAmJgorICAgICAgICAgICAgICAgICAgIWNhdGNoKHRtcD0oaW50KWNhbGxfb3RoZXIodmMsIlF1ZXJ5VmFsaWRPYmplY3QiLGZuKTsKKyAgICAgICAgICAgICAgICAgICAgcHVibGlzaCkgJiYgdG1wPjApKSAmJgorICAgICAgICAgICAgICAgICAgIWNhdGNoKGxvYWRfb2JqZWN0KCBmbiApO3B1Ymxpc2gpKSkgJiYKKyAgICAgICAgICAgICAgKCFmbi0+UXVlcnlQcm9wKFBfTk9fUExBWUVSUykgfHwgUXVlcnlQcm9wKFBfVEVTVFBMQVlFUikpICkKKyAgICAgICAgICAgZGVzdCA9IGZuOworICAgICAgfQorICB9CisgICAgCisgIC8vIGRlc3QgYXVmIE9iamVrdCBub3JtaWVyZW4uCisgIGlmIChzdHJpbmdwKGRlc3QpKQorICAgICAgZGVzdCA9IGxvYWRfb2JqZWN0KGRlc3QpOworICAgIAorICAvLyB0ZXN0ZW4sIG9iIGRhcyBPYmpla3QgYmV3ZWd0IHdlcmRlbiB3aWxsCisgIGlmICh0bXA9UHJldmVudE1vdmUoZGVzdCwgb2xkZW52LCBtZXRob2QpKSB7CisgICAgICAvLyBhdWYgZ3VlbHRpZ2VuIEZlaGxlciBwcnVlZmVuLCB3ZXIgd2Vpc3MsIHdhcyBNYWdpZXIgZGEgZXZ0bC4KKyAgICAgIC8vIHZlcnNlaGVudGxpY2hlIHp1cnVlY2tnZWJlbi4KKyAgICAgIGlmIChWQUxJRF9NT1ZFX0VSUk9SKHRtcCkpCisgICAgICAgIHJldHVybih0bXApOworICAgICAgZWxzZQorICAgICAgICByZXR1cm4oTUVfRE9OVF9XQU5UX1RPX0JFX01PVkVEKTsKKyAgfQorCisgIC8vIFNlbnNpdGl2ZSBPYmpla3RlIG11ZXNzZW4gZW50ZmVybnQgd2VyZGVuCisgIHNlbnMgPSBRdWVyeVByb3AoUF9TRU5TSVRJVkUpOworCisgIGlmIChzZW5zICYmIGVudmlyb25tZW50KCkpCisgIHsKKyAgICBlbnZpcm9ubWVudCgpLT5SZW1vdmVTZW5zaXRpdmVPYmplY3QoIHRoaXNfb2JqZWN0KCkgKTsKKyAgICBpZiAoIW9iamVjdHAoTUUpKQorICAgICAgcmV0dXJuIE1FX1dBU19ERVNUUlVDVEVEOworICB9CisgIC8vIEJld2VnZW4KKyAgbW92ZV9vYmplY3QoTUUsIGRlc3QpOworCisgIC8vZmFsbHMgKHNpY2gpIGRhcyBvYmpla3QgaW0gaW5pdCgpIHplcnN0b2VydCAod3VyZGUpLiAoRGllIHUuIHN0ZWhlbmRlbgorICAvL0Z1bmt0aW9uc2F1ZnJ1ZmUgd2VyZGVuIGRhbm4gdm9tIERyaXZlciBlaCBncm9lc3N0ZW50ZWlscyBpZ25vcmllcnQuKQorICBpZiAoIW9iamVjdHAodGhpc19vYmplY3QoKSkpIHJldHVybihNRV9XQVNfREVTVFJVQ1RFRCk7CisKKyAgLy8gT2JqZWt0IGluZm9ybWllcmVuLiA7LSkKKyAgTm90aWZ5TW92ZShlbnZpcm9ubWVudCgpLCBvbGRlbnYsIG1ldGhvZCk7CisKKyAgLy8gQWx0ZSBVbWdlYnVuZyBpbmZvcm1pZXJlbgorICBpZiAob2xkZW52KSBvbGRlbnYtPk5vdGlmeUxlYXZlKHRoaXNfb2JqZWN0KCksIGRlc3QpOworCisgIC8vIFdlbm4gZGFzIE9iamVrdCBlaW5lIFVtZ2VidW5nIGhhdCwgc2VsYmlnZSBpbmZvcm1pZXJlbgorICBpZiAoZW52aXJvbm1lbnQoKSkgeworICAgIGlmIChzZW5zKQorICAgIHsKKyAgICAgIGVudmlyb25tZW50KCktPkluc2VydFNlbnNpdGl2ZU9iamVjdCh0aGlzX29iamVjdCgpLHNlbnMpOworICAgICAgaWYgKCFvYmplY3RwKE1FKSkgcmV0dXJuIE1FX1dBU19ERVNUUlVDVEVEOworICAgIH0KKyAgICBlbnZpcm9ubWVudCgpLT5Ob3RpZnlJbnNlcnQodGhpc19vYmplY3QoKSwgb2xkZW52KTsKKyAgfQorICAvL3d1cmRlIGRhcyBPYmpla3QgdmllbGxlaWNodCBub2NoIHplcnN0b2VydD8KKyAgaWYgKCFvYmplY3RwKE1FKSkgcmV0dXJuKE1FX1dBU19ERVNUUlVDVEVEKTsKKyAgCisgIC8vc2NoZWludCB3b2hsIGFsbGVzIG9rIHp1IHNlaW4uCisgIHJldHVybiBNT1ZFX09LOworfQorCisvLyBEYXMgT2JqZWt0IHplcnN0b2VyZW4KK3ZhcmFyZ3MgaW50IHJlbW92ZShpbnQgc2lsZW50KQoreyAKKyAgICBpZiAoZW52aXJvbm1lbnQoKSApIHsKKyAgICAgICAgaWYoUXVlcnlQcm9wKFBfU0VOU0lUSVZFKSkKKyAgICAgICAgICAgICAgICBlbnZpcm9ubWVudCgpLT5SZW1vdmVTZW5zaXRpdmVPYmplY3QodGhpc19vYmplY3QoKSk7CisgICAgICAgIGVudmlyb25tZW50KCktPk5vdGlmeVJlbW92ZSh0aGlzX29iamVjdCgpKTsKKyAgICB9CisgICAgaWYgKG9iamVjdHAodGhpc19vYmplY3QoKSkpCisgICAgICAgIGRlc3RydWN0KHRoaXNfb2JqZWN0KCkpOworICAgIHJldHVybiAxOworfQorCitwdWJsaWMgc3RyaW5nIE5vdGlmeURlc3RydWN0KG9iamVjdCBjYWxsZXIpIHsKKyAgLy8gTGljaHRzeXN0ZW0gbWl0IGRlciBhZW5kZXJ1bmcgdmVyc29yZ2VuLiA6LS8KKyAgZm9yZWFjaChvYmplY3QgZW52IDogYWxsX2Vudmlyb25tZW50KCkgfHwgKHt9KSkgeworICAgICAgLy8gSmEuIE1hbiBydWZ0IGRpZSBfc2V0X3h4eCgpLUZ1bmt0aW9uZW4gZWlnZW50bGljaCBuaWNodCBkaXJla3QgYXVmLgorICAgICAgLy8gQWJlciBkYXMgTGljaHRzeXN0ZW0gaXN0IHNjaG9uICpzbyogcmVjaGVuaW50ZW5zaXYgdW5kIGdlcmFkZSBkZXIKKyAgICAgIC8vIFBfTEFTVF9DT05URU5UX0NIQU5HRS1DYWNoZSB3aXJkICpzbyogb2Z0IGJlbm9ldGlndCwgZGFzcyBlcyBtaXIKKyAgICAgIC8vIGRhIHVtIGplZGVzIGJpc3NjaGVuIFJlY2hlbnplaXQgZ2VodC4KKyAgICAgIC8vIERlciBad2VjayBoZWlsaWd0IGphIGJla2FubnRsaWNoIGRpZSBNaXR0ZWwuIDstKQorICAgICAgLy8KKyAgICAgIC8vIFRpYW1haworICAgICAgZW52LT5fc2V0X2xhc3RfY29udGVudF9jaGFuZ2UoKTsKKyAgfQorICByZXR1cm4gMDsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3RoaW5nL3Byb3BlcnRpZXMuYyBiL3N0ZC90aGluZy9wcm9wZXJ0aWVzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDY1OTJiZgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC90aGluZy9wcm9wZXJ0aWVzLmMKQEAgLTAsMCArMSwzMjYgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB0aGluZy9wcm9wZXJ0aWVzLmMgLS0gbW9zdCBnZW5lcmFsIGNsYXNzIChwcm9wZXJ0eSBoYW5kbGluZykKKy8vCisvLyAkSWQ6IHByb3BlcnRpZXMuYyA2OTUxIDIwMDgtMDgtMDkgMjM6MDg6MzFaIFplc3N0cmEgJAorCisvLyBQcm9wZXJ0aWVzLmMgLS0gUHJvcGVydHl2ZXJ3YWx0dW5nCisvLyAoYykgMTk5MyBIYXRlQE1vcmdlbkdyYXVlbiwgTWF0ZWVzZUBOaWdodEZhbGwKKy8vICAgICAgICAgIElkZWEgYW5kIENvZGUgICAgICBGbGFtZXMgYW5kIERlc3RydWN0aW9ucworLy8gLT4gKmdyaW4qIHRoYXRzIHRoZSBwb2ludCBhY3R1YWxseSA6KSAKKy8vCisvLyBVZWJlcmFyYmVpdGV0IHZvbiBKb2YgICAgICAgYW0gMTIuMDYuMTk5NAorLy8gVWViZXJhcmJlaXRldCB2b24gTWFuZHJhZ29uIGFtIDExLjA1LjIwMDMKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSAiL3N5cy90aGluZy9wcm9wZXJ0aWVzLmgiCisjaW5jbHVkZSAiL3NlY3VyZS93aXpsZXZlbHMuaCIKKworCisvLyB0aGUgbWFwcGluZyB3aGVyZSB0aGUgYWN0dWFsIHByb3BlcnRpZXMgYXJlIHN0b3JlZC4gRGlyZWN0IGluaXRpYWxpemF0aW9uLgorcHJpdmF0ZSBub3NhdmUgbWFwcGluZyAqcHJvcCA9ICh7IChbXSksIChbXSksIChbXSksIChbXSkgfSk7CisKKy8vIHRoZSBtYXBwaW5nIHRoYXQgaXMgdXNlZCBmb3Igc2F2aW5nCitwcml2YXRlIG1hcHBpbmcgcHJvcGVydGllczsKKworLy8gc2VjdXJpdHktZmxhZworcHJpdmF0ZSBub3NhdmUgaW50IGNsb3N1cmVfY2FsbDsKKworLy8gSW5pdGlhbGlzaWVydW5nIGRlciBQcm9wcy4gS2FubiBsZWlkZXIgbW9tZW50YW4gbmljaHQgcHJpdmF0ZSBzZWluLCB3ZWlsCisvLyBQYWRyZWljIHNvbiBrb21pc2NoZXMgT2JqZWt0IGhhdCwgd2FzIGRpZSBGdW5rdGlvbiBoaWVyIHJ1ZnQuCisvLyBUT0RPOiBpcmdlbmR3YW5uIG1hbCBwcml2YXRlIG1hY2hlbi4KKy8vIFRPRE86IERhIHByb3BzIGpldHp0IGVpbmZhY2ggYmVpIGRlciBEZWtsYXJhdGlvbiBpbml0bGlzaWVydCB3aXJkLAorLy8gZXJ1ZWJyaWd0IHNpY2ggZGllc2UgRnVua3Rpb24gZWlnZW50bGljaC4gQmlzIGF1ZiBQYWRyZWljcyBPYmpla3QuLi4KK3Byb3RlY3RlZCB2b2lkIEluaXRpYWxpemVQcm9wZXJ0aWVzKCkgeworICBwcm9wID0gKHsgKFtdKSwgKFtdKSwgKFtdKSwgKFtdKSB9KTsKKyAgcmV0dXJuOworfQorCisvLyBQcm9wcyBudXIgZGFubiBpbml0aWFsaXNpZXJlbiwgd2VubiBzaWUgZXMgbm9jaCBuaWNodCBzaW5kCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKSB7CisgIC8vIEJsdWVwcmludHMgaW4gL3N0ZCBiZW5vZXRpZ2Vua2VpbmVuIFJlc2V0IC4uLi4KKyAgaWYgKG9iamVjdF9uYW1lKCk9PSIvc3RkL3RoaW5nL3Byb3BlcnRpZXMiKQorICAgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlX3N1cGVyKCkgeworICBzZXRfbmV4dF9yZXNldCgtMSk7Cit9CisKKy8vIFdlbGNoZSBleHRlcm5lbiBPYmpla3RlIGR1ZXJmZW4genVncmVpZmVuPworbm9tYXNrIHByaXZhdGUgaW50IGFsbG93ZWQoKQoreworICAgIGlmICggKHByZXZpb3VzX29iamVjdCgpICYmIElTX0FSQ0goZ2V0dWlkKHByZXZpb3VzX29iamVjdCgpKSkgJiYKKyAgICAgICAgICB0aGlzX2ludGVyYWN0aXZlKCkgJiYgSVNfQVJDSCh0aGlzX2ludGVyYWN0aXZlKCkpKSB8fAorICAgICAgICAgKHByZXZpb3VzX29iamVjdCgpICYmIGdldHVpZChwcmV2aW91c19vYmplY3QoKSkgPT0gUk9PVElEICYmCisgICAgICAgICAgZ2V0ZXVpZChwcmV2aW91c19vYmplY3QoKSkgPT0gUk9PVElEKSApCisgICAgICAgIHJldHVybiAxOworICAgIHJldHVybiAwOworfQorCisKKy8vIFNldCgpIC0tIHByb3ZpZGVzIGRpcmVjdCBhY2Nlc3MgdG8gYSBwcm9wZXJ0eSwgbm8gZmlsdGVycworcHVibGljIHZhcmFyZ3MgbWl4ZWQgU2V0KCBzdHJpbmcgbmFtZSwgbWl4ZWQgVmFsdWUsIGludCBUeXBlLCBpbnQgZXh0ZXJuICkKK3sKKworICBpZiAoIW9iamVjdHAodGhpc19vYmplY3QoKSkpCisgICAgcmV0dXJuIDA7CisKKyAgLy8gUHJvcGVydGllcywgZGllIFNFQ1VSRUQgb2RlciBQUk9URUNURUQgc2luZCwgZHVlcmZlbiBudXIgdm9tIE9iamVrdAorICAvLyBzZWxiZXIsIEVNKyBvZGVyIFJPT1QgdmVyYWVuZGVydCB3ZXJkZW4KKyAgaWYgKChwcm9wW0ZfTU9ERV1bbmFtZV0mKFBST1RFQ1RFRHxTRUNVUkVEKSkmJgorICAgICAgKGNsb3N1cmVfY2FsbHx8ZXh0ZXJufHxleHRlcm5fY2FsbCgpKSAmJgorICAgICAgIHByZXZpb3VzX29iamVjdCgpICE9IHRoaXNfb2JqZWN0KCkgJiYgIWFsbG93ZWQoKSkKKyAgICByZXR1cm4gLTE7CisgIAorICAvLyBEYXMgU0VDVVJFRC1GbGFnIGRhcmYgYmVpIFByb3BlcnRpZXMgbmljaHQgbWVociBnZWxvZXNjaHQgd2VyZGVuCisgIGlmICgocHJvcFtGX01PREVdW25hbWVdJlNFQ1VSRUQpJiYKKyAgICAgIChUeXBlPT1GX01PREV8fFR5cGU9PUZfTU9ERV9BRCkmJihWYWx1ZSAmIFNFQ1VSRUQpKQorICAgIHJldHVybiAtMjsKKyAgCisgIC8vIFNldHplbiBkdWVyZmVuIGRhcyBTRUNVUkVELUZsYWcgbnVyIGRhcyBPYmpla3Qgc2VsYmVyLCBFTSsgb2RlciBST09UCisgIGlmICgoVHlwZT09Rl9NT0RFfHxUeXBlPT1GX01PREVfQVMpJiYoVmFsdWUmU0VDVVJFRCkmJgorICAgICAgKGNsb3N1cmVfY2FsbCB8fGV4dGVybiB8fCBleHRlcm5fY2FsbCgpKSAmJgorICAgICAgIHByZXZpb3VzX29iamVjdCgpICE9IHRoaXNfb2JqZWN0KCkgJiYgIWFsbG93ZWQoKSApCisgICAgcmV0dXJuIC0zOworCisgIHN3aXRjaChUeXBlKQorICB7CisgICAgLy8gSmUgbmFjaCBNb2R1cyBGbGFncyB2ZXJhZW5kZXJuCisgICAgY2FzZSBGX01PREVfQVM6ICBwcm9wW0ZfTU9ERV1bbmFtZV18PSBWYWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9wW0ZfTU9ERV1bbmFtZV07CisgICAgY2FzZSBGX01PREVfQUQ6ICBwcm9wW0ZfTU9ERV1bbmFtZV0mPSB+VmFsdWU7CisgICAgICAgICAgICAgICAgICAgICBpZiAoIXByb3BbRl9NT0RFXVtuYW1lXSkgcHJvcFtGX01PREVdLT0oW25hbWVdKTsKKyAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9wW0ZfTU9ERV1bbmFtZV07CisgICAgY2FzZSBGX01PREU6ICAgICBwcm9wW0ZfTU9ERV1bbmFtZV1ePSBWYWx1ZTsKKyAgICAgICAgICAgICAgICAgICAgIGlmICghcHJvcFtGX01PREVdW25hbWVdKSBwcm9wW0ZfTU9ERV0tPShbbmFtZV0pOworICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHByb3BbRl9NT0RFXVtuYW1lXTsKKyAgICBjYXNlIEZfU0VUX01FVEhPRDoKKyAgICAgIC8vIC0xIGFscyBTZXR6LU1ldGhvZGU6IE5vc2V0bWV0aG9kIHNldHplbgorICAgICAgaWYgKFZhbHVlID09IC0xKQorICAgICAgeworICAgICAgICBwcm9wW0ZfU0VUX01FVEhPRF0tPShbbmFtZV0pOworICAgICAgICBwcm9wW0ZfTU9ERV1bbmFtZV0gfD0gTk9TRVRNRVRIT0Q7CisgICAgICAgIHJldHVybiAwOworICAgICAgfQorICAgICAgLy8gS2VpbiBicmVhayEKKyAgICBjYXNlIEZfUVVFUllfTUVUSE9EOgorICAgICAgLy8gVW5nZWJ1bmRlbmUgTGFtYmRhX0Nsb3N1cmU/IEJpbmRlbiEKKyAgICAgIGlmIChjbG9zdXJlcChWYWx1ZSkmJiFxdWVyeV9jbG9zdXJlX29iamVjdChWYWx1ZSkpCisgICAgICB7CisgICAgICAgIGlmIChleHRlcm5fY2FsbCgpICYmCisgICAgICAgICAgICAgKGdldHVpZChwcmV2aW91c19vYmplY3QoKSkgIT0gZ2V0dWlkKCl8fAorICAgICAgICAgICAgICBnZXRldWlkKHByZXZpb3VzX29iamVjdCgpKSAhPSBnZXRldWlkKCkpKQorICAgICAgICAgIHJldHVybiBwcm9wW1R5cGVdW25hbWVdOworICAgICAgICAKKyAgICAgICAgVmFsdWUgPSBiaW5kX2xhbWJkYSggVmFsdWUsdGhpc19vYmplY3QoKSk7CisgICAgICB9CisgICAgICAvLyBLZWluIGJyZWFrIQorICAgIGRlZmF1bHQ6CisgICAgICBpZiAoIVZhbHVlKSBwcm9wW1R5cGVdLT0oW25hbWVdKTsKKyAgICAgIGVsc2UgcHJvcFtUeXBlXVtuYW1lXSA9IFZhbHVlOworICB9CisKKyAgLy8gR2VzYW10d2VydCB6dXJ1ZWNrZ2ViZW4KKyAgcmV0dXJuIHByb3BbVHlwZV1bbmFtZV07Cit9CisKKworLy8gRGlyZWt0ZXMgQXVzbGVzZW4gZGVyIFByb3BlcnR5IG9obmUgRmlsdGVyIC4uLgorcHVibGljIHZhcmFyZ3MgbWl4ZWQgUXVlcnkoIHN0cmluZyBuYW1lLCBpbnQgVHlwZSApCit7CisgICAgaWYgKHBvaW50ZXJwKHByb3ApKSByZXR1cm4gcHJvcFtUeXBlXVtuYW1lXTsKKyAgICByZXR1cm4gMDsKK30KKworLy8gUHJvcGVydHkgc2V0emVuIHVudGVyIFZlcndlbmR1bmcgZXZ0bC4gdm9yaGFuZGVuZXIgWnVncmlmZnNmdW5rdGlvbmVuCitwdWJsaWMgbWl4ZWQgU2V0UHJvcCggc3RyaW5nIG5hbWUsIG1peGVkIFZhbHVlICkKK3sKKyAgY2xvc3VyZSBmdW5jOworICBtaXhlZCByZXN1bHQ7CisgICAKKyAgLy8gbnVyIGZ1ZXIgaGV1dGUKKyAgaWYgKCFvYmplY3RwKHRoaXNfb2JqZWN0KCkpKQorICAgIHJldHVybiAwOworCisgIC8vIE5PU0VUTUVUSE9EOiBEYXJmIG5pY2h0IGdlc2V0enQgd2VyZGVuCisgIGlmIChwcm9wW0ZfTU9ERV1bbmFtZV0gJiBOT1NFVE1FVEhPRCApIHJldHVybiAtMTsKKworICAvLyBTZXQtTWV0aG9kIGFiZnJhZ2VuLCBzbyB2b3JoYW5kZW4KKyAgaWYgKGZ1bmM9cHJvcFtGX1NFVF9NRVRIT0RdW25hbWVdKQorICB7CisgICAgaW50IGZsYWc7CisKKyAgICAvLyBXZXJ0IGFscyBTZXQtTWV0aG9kPyBnbGVpY2ggenVydWVja2dlYmVuCisgICAgaWYgKCFjbG9zdXJlcChmdW5jKSkgcmV0dXJuIGZ1bmM7CisKKyAgICAvLyBBbiBkaWVzZXIgU3RlbGxlIG11c3MgZnVuYyBlaW5lIENsb3N1cmUgc2Vpbi4gRGEgU2V0KCkgdW5nZWJ1bmRlbmUKKyAgICAvLyBMYW1iZGFzIGJpbmRldCwga2FubiBlcyBhdWNoIG51ciBlaW5lIGdlYnVuZGVuZSBDbG9zdXJlIHNlaW4gdW5kIGRhcworICAgIC8vIE9iamVrdCBleGlzdGllcnQgYXVjaCBub2NoIChzb25zdCB3YWVyZSBmdW5jID09IDApLgorCisgICAgLy8gY2xvc3VyZV9jYWxsIHNldHplbiwgZmFsbHMgbm9jaCBuaWNodCBnZXNldHp0CisgICAgaWYgKChmbGFnPWNsb3N1cmVfY2FsbDx0aW1lKCkpKQorICAgICAgY2xvc3VyZV9jYWxsID0gdGltZSgpKzU5OworCisgICAgLy8gRGFubiBtYWwgZGllIENsb3N1cmUgYXVmcnVmZW4uIEJlaSBGZWhsZXIgc2VsYmlnZSBsb2VzY2hlbgorICAgIGlmIChjYXRjaChyZXN1bHQ9ZnVuY2FsbChmdW5jLCBWYWx1ZSwgbmFtZSk7cHVibGlzaCkpCisgICAgeworICAgICAgcHJvcFtGX1NFVF9NRVRIT0RdLT0oW25hbWVdKTsKKyAgICB9CisgICAgICAKKyAgICAvLyBXZW5uIGNsb3N1cmVfY2FsbCBnZXNldHp0IHd1cmRlLCB3aWVkZXIgbG9lc2NoZW4KKyAgICBpZiAoZmxhZykgY2xvc3VyZV9jYWxsID0gMDsKKworICAgIC8vIFVuZCB6dXJ1ZWNrZ2ViZW4KKyAgICByZXR1cm4gcmVzdWx0OyAKKyAgfQorCisgIC8vIF9zZXRfKi1NZXRob2RlIHZvcmhhbmRlbj8gZmFsbHMgamEsIGF1ZnJ1ZmVuLmkKKyAgLy8gVE9ETzogQ2xvc3VyZWNhY2hlIGVpbmZ1ZWhyZW4gdW5kIEZ1bmt0aW9uYXVmcnVmIG51ciBub2NoIG1hY2hlbiwgd2VubiBlcworICAvLyBkaWUgX3NldF8qIGF1Y2ggZ2lidD8KKyAgaWYgKGNhbGxfcmVzb2x2ZWQoJnJlc3VsdCx0aGlzX29iamVjdCgpLCJfc2V0XyIrbmFtZSxWYWx1ZSApKQorICAgICAgICByZXR1cm4gcmVzdWx0OworCisgIC8vIExldHp0ZSBNb2VnbGljaGtlaXQ6IE11c3MgZWluZSAnbm9ybWFsZScgUHJvcGVydHkgc2VpbgorICByZXR1cm4gU2V0KCBuYW1lLCBWYWx1ZSwgRl9WQUxVRSwgZXh0ZXJuX2NhbGwoKSApOworfQorCisKKy8vIFByb3BlcnR5IGF1c2xlc2VuIHVudGVyIFZlcndlbmR1bmcgZXZ0bC4gdm9yaGFuZGVuZXIgWnVncmlmZnNmdW5rdGlvbmVuCitwdWJsaWMgbWl4ZWQgUXVlcnlQcm9wKCBzdHJpbmcgbmFtZSApCit7CisgIGNsb3N1cmUgZnVuYzsKKyAgbWl4ZWQgcmVzdWx0OworIAorICAvLyBudXIgZnVlciBoZXV0ZQorICBpZiAoIW9iamVjdHAodGhpc19vYmplY3QoKSkpCisgICAgcmV0dXJuOworCisgIC8vIFF1ZXJ5LU1ldGhvZGUgdm9yaGFuZGVuPworICBpZiAoIGZ1bmMgPSBwcm9wW0ZfUVVFUllfTUVUSE9EXVtuYW1lXSApCisgIHsKKyAgICBpbnQgZmxhZzsKKworICAgIC8vIFdlcnQgYWxzIFF1ZXJ5LU1ldGhvZD8gR2xlaWNoIHp1cnVlY2tnZWJlbiAuLi4KKyAgICBpZiAoIWNsb3N1cmVwKGZ1bmMpKSByZXR1cm4gZnVuYzsKKyAKKyAgICAvLyBBbiBkaWVzZXIgU3RlbGxlIG11c3MgZnVuYyBlaW5lIENsb3N1cmUgc2Vpbi4gRGEgU2V0KCkgdW5nZWJ1bmRlbmUKKyAgICAvLyBMYW1iZGFzIGJpbmRldCwga2FubiBlcyBhdWNoIG51ciBlaW5lIGdlYnVuZGVuZSBDbG9zdXJlIHNlaW4gdW5kIGRhcworICAgIC8vIE9iamVrdCBleGlzdGllcnQgYXVjaCBub2NoIChzb25zdCB3YWVyZSBmdW5jID09IDApLgorICAgCisgICAgLy8gY2xvc3VyZV9jYWxsIHNldHplbiwgZmFsbHMgbm9jaCBuaWNodCBnZXNldHp0CisgICAgaWYgKChmbGFnPWNsb3N1cmVfY2FsbDx0aW1lKCkpKQorICAgICAgY2xvc3VyZV9jYWxsID0gdGltZSgpKzU5OworICAgIAorICAgIC8vIERhbm4gTWFsIGRpZSBDbG9zdXJlIGF1ZnJ1ZmVuLiBCZWkgRmVobGVyIHNlbGJpZ2UgbG9lc2NoZW4KKyAgICBpZiAoY2F0Y2gocmVzdWx0PWZ1bmNhbGwoZnVuYyk7cHVibGlzaCkpCisgICAgeworICAgICAgcHJvcFtGX1FVRVJZX01FVEhPRF0tPShbbmFtZV0pOworICAgIH0KKyAgICAvLyBXZW5uIGNsb3N1cmVfY2FsbCBnZXNldHp0IHd1cmRlLCB3aWVkZXIgbG9lc2NoZW4gICAgCisgICAgaWYgKGZsYWcpIGNsb3N1cmVfY2FsbCA9IDA7CisgICAgCisgICAgLy8gVW5kIHp1cnVlY2tnZWJlbgorICAgIHJldHVybiByZXN1bHQ7CisgIH0KKyAgCisgIC8vIF9xdWVyeV8qLU1ldGhvZGUgdm9yaGFuZGVuPyBmYWxscyBqYSwgYXVmcnVmZW4uCisgIC8vIFRPRE86IENsb3N1cmVjYWNoZSB1bmQgbnVyIHJ1ZmVuLCB3ZW5uIGVzIF9xdWVyeV8qIGF1Y2ggZ2lidD8KKyAgaWYgKGNhbGxfcmVzb2x2ZWQoJnJlc3VsdCx0aGlzX29iamVjdCgpLCJfcXVlcnlfIituYW1lKSkKKyAgICByZXR1cm4gcmVzdWx0OworICAKKyAgLy8gSGlsZnQgYWxsZXMgbmljaHRzLiBFcyBpc3QgZWluZSAnbm9ybWFsZScgUHJvcGVydHkgLi4uCisgIHJldHVybiBwcm9wW0ZfVkFMVUVdW25hbWVdOworfQorCisKKy8vIERhcyBnZXNhbXRlIFByb3BlcnR5LU1hcHBpbmcgYXVmIGVpbmVuIFNjaGxhZyBzZXR6ZW4KK3B1YmxpYyB2b2lkIFNldFByb3BlcnRpZXMoIG1hcHBpbmcgcHJvcHMgKQoreworICBzdHJpbmcgKm5hbWVzOworICBpbnQgaSwgaiwgc2FtZV9vYmplY3Q7CisgCisgIC8vIEtlaW4gTWFwcGluZz8gU2NobGVjaHQgLi4uCisgIGlmKCFtYXBwaW5ncChwcm9wcykpIHJldHVybjsKKworICAvLyBTZXR6ZW4gd2lyIHNlbGJlcj8KKyAgc2FtZV9vYmplY3QgPSAoIWNsb3N1cmVfY2FsbCAmJgorICAgICAgICAgICAgICAgICAoIWV4dGVybl9jYWxsKCl8fHByZXZpb3VzX29iamVjdCgpPT10aGlzX29iamVjdCgpfHwKKyAgICAgICAgICAgICAgICAgIGFsbG93ZWQoKSkpOworICBuYW1lcyA9IG1faW5kaWNlcyhwcm9wcyk7CisgIAorICAvLyBEYXMgU0VDVVJFRC1GbGFnIGRhcmYgbnVyIGR1cmNoIGRhcyBPYmpla3Qgc2VsYmVyIGdlc2V0enQgd2VyZGVuOgorICAvLyBBbGxlIFNFQ1VSRUQtRmxhZ3MgYXVzIHByb3BzIGxvZXNjaGVuCisgIGlmICghc2FtZV9vYmplY3QpCisgIHsKKyAgICBqPXNpemVvZihuYW1lcyk7CisgICAgd2hpbGUoai0tKSBwcm9wc1tuYW1lc1tqXSwgRl9NT0RFXSAmPSB+U0VDVVJFRDsKKyAgfQorCisgIGo9c2l6ZW9mKG5hbWVzKTsKKyAgd2hpbGUoai0tKQorICB7CisgICAgLy8gUHJvcGVydGllcywgZGllIHNjaG9uIFNFQ1VSRUQgb2RlciBQUk9URUNURUQgc2luZCwgZHVlcmZlbgorICAgIC8vIG51ciB2b20gT2JqZWt0IHNlbGJlciBtYW5pcHVsaWVydCB3ZXJkZW4KKyAgICBpZiAoc2FtZV9vYmplY3R8fCEocHJvcFtGX01PREVdW25hbWVzW2pdXSAmIChQUk9URUNURUR8U0VDVVJFRCkpICkKKyAgICB7CisgICAgICBpPTQ7CisgICAgICB3aGlsZShpLS0pCisgICAgICB7CisgICAgICAgIGlmKHByb3BzW25hbWVzW2pdLGldKQorICAgICAgICAgIHByb3BbaV1bbmFtZXNbal1dID0gcHJvcHNbbmFtZXNbal0sIGldOworICAgICAgICBlbHNlCisgICAgICAgICAgcHJvcFtpXS09KFtuYW1lc1tqXV0pOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm47Cit9CisKKworLy8gRWluIE1hcHBpbmcgbWl0IGFsbGVuIFByb3BlcnRpZXMgenVydWVja2dlYmVuCitwdWJsaWMgbWFwcGluZyBRdWVyeVByb3BlcnRpZXMoKQoreworICBtYXBwaW5nIHByb3BzOworICBpbnQgaSwgajsKKyAgc3RyaW5nICpuYW1lczsKKworICBwcm9wcyA9IG1fYWxsb2NhdGUoIDAsIDQgKTsKKyAgCisgIGlmIChwb2ludGVycChwcm9wKSkKKyAgeworICAgIGk9NDsKKyAgICB3aGlsZShpLS0pCisgICAgeworICAgICAgbmFtZXMgPSBtX2luZGljZXMocHJvcFtpXSk7CisgICAgICBqPXNpemVvZihuYW1lcyk7CisgICAgICB3aGlsZShqLS0pIHByb3BzW25hbWVzW2pdLCBpXSA9IHByb3BbaV1bbmFtZXNbal1dOworICAgIH0KKyAgfQorICByZXR1cm4gcHJvcHM7Cit9CisKKy8vIERpZSBQcm9wZXJ0aWVzIGFscyB1cnNwcnVlbmdsaWNoZXMgQXJyYXkgenVydWVja2dlYmVuCitwdWJsaWMgbWl4ZWQgKl9fcXVlcnlfcHJvcGVydGllcygpCit7CisgIGlmICggcG9pbnRlcnAocHJvcCkgKQorICAgIHJldHVybihkZWVwX2NvcHkocHJvcCkpOworICBlbHNlCisgICAgcmV0dXJuICh7IChbXSksKFtdKSwoW10pLChbXSkgfSk7Cit9CisKKworLy8gbWFwcGluZyBQcm9wZXJ0aWVzIHNldHplbiB6dW0gU3BlaWNoZXJuIChwZXIgc2F2ZV9vYmplY3QoKSkKKy8vIEF1ZnJ1ZiBudXIgYXVzIHNpbXVsX2VmdW4gaGVyYXVzCitwdWJsaWMgdm9pZCAgX3NldF9zYXZlX2RhdGEobWl4ZWQgZGF0YSkgeyBwcm9wZXJ0aWVzID0gZGF0YTsgfQorCisvLyBtYXBwaW5nIFByb3BlcnRpZXMgenVtIFJlc3RvcmVuIHp1cnVlY2tnZWJlbgorcHVibGljIG1peGVkIF9nZXRfc2F2ZV9kYXRhKCkgICAgICAgICAgIHsgcmV0dXJuIHByb3BlcnRpZXM7IH0KKwpkaWZmIC0tZ2l0IGEvc3RkL3RoaW5nL3Jlc3RyaWN0aW9ucy5jIGIvc3RkL3RoaW5nL3Jlc3RyaWN0aW9ucy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU4ZDBmODMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdGhpbmcvcmVzdHJpY3Rpb25zLmMKQEAgLTAsMCArMSwxNDIgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB0aGluZy9yZXN0cmljdGlvbnMuYyAtLSBHZXdpY2h0IHUuYWUuIGVpbmVzIE9iamVrdHMKKy8vCisvLyAkSWQ6IHJlc3RyaWN0aW9ucy5jIDY4MDkgMjAwOC0wMy0yOSAyMTo1NDowNFogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTIAorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKworLy8gR2V3aWNodCBpc3QgMWtnLCB3ZW5uIG5pY2h0IGFuZGVycyBiZXN0aW1tdAorcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkgCit7ICAKKyAgU2V0UHJvcChQX1dFSUdIVCwgMTAwMCk7Cit9CisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfSAgICAgCisKKy8vIFBfVE9UQUxfV0VJR0hUIGJlaSBOaWNodC1Db250YWluZXJuIGF1ZiBQX1dFSUdIVCB1bWxlaXRlbgorc3RhdGljIGludCBfc2V0X3dlaWdodChpbnQgd2VpZ2h0KSB7CisgIHJldHVybiBTZXRQcm9wKFBfVE9UQUxfV0VJR0hULAorCSAgU2V0KFBfV0VJR0hULCB3ZWlnaHQsIEZfVkFMVUUpICk7Cit9CisKKy8vIFBfWF9BVFRSX01PRCBhZW5kZXJuIChBdHRyaWJ1dGFlbmRlcnVuZ2VuIGR1cmNoIEF1c3J1ZXN0dW5nKQorc3RhdGljIG1hcHBpbmcgX3NldF9leHRlcm5fYXR0cmlidXRlc19tb2RpZmllcihtYXBwaW5nIHhtb2QpIAoreworICBtYXBwaW5nIHJlczsKKworICAvLyB3ZW5uIE11ZWxsIG9kZXIgZWluIGxlZXJlcyBNYXBwaW5nIHVlYmVyZ2ViZW4gd3VyZGUsIHdpcmQgZGllIHByb3AKKyAgLy8gZ2Vsb2VzY2h0IHVuZCBnZ2YuIGRhcyBPYmpla3QgaW0gTGl2aW5nIGFiZ2VtZWxkZXQuCisgIGlmICghbWFwcGluZ3AoeG1vZCkpIHhtb2Q9KFtdKTsKKyAgCisgIGlmICghc2l6ZW9mKHhtb2QpKSB7CisgCisgICAgcmVzPVNldChQX1hfQVRUUl9NT0QsIHhtb2QpOworICAKKyAgICAvLyB3ZW5uIFByb3AgZ2Vsb2VzY2h0IHdpcmQsIGthbm4gbWFuIGRhcyBJdGVtIGF1Y2ggYXVzIGRlciBMaXN0ZSBkZXIKKyAgICAvLyBTdGF0bW9kaWZpemllcmVyIGRlcyBMZWJld2VzZW5zIGF1c3RyYWdlbi4KKyAgICBpZiAobGl2aW5nKGVudmlyb25tZW50KCkpKSB7ICAKKyAgICAgIGVudmlyb25tZW50KCktPmRlcmVnaXN0ZXJfbW9kaWZpZXIoTUUpOworICAgICAgZW52aXJvbm1lbnQoKS0+VXBkYXRlQXR0cmlidXRlcygpOworICAgIH0KKyAgfQorICBlbHNlIHsKKyAgICAvLyBvaywgUHJvcCB3aXJkIGF1ZiBuZW4gaW50ZXJlc3NhbnRlbiBXZXJ0IGdlc2V0enQuIDstKQorCisgICAgLy8gRGFtaXQgSW5zZXJ0L1JlbW92ZVNlbnNpdGl2ZU9iamVjdCBiZWltIE1vdmUgYXVmZ2VydWZlbiB3aXJkLAorICAgIC8vIG11c3MgUF9TRU5TSVRJVkUgZ2VzZXR6dCBzZWluCisgICAgaWYgKCFRdWVyeVByb3AoUF9TRU5TSVRJVkUpKSBTZXRQcm9wKFBfU0VOU0lUSVZFLCh7fSkpOworICAKKyAgICBpZiAobGl2aW5nKGVudmlyb25tZW50KCkpICYmIAorICAgICAgICAoIW1hcHBpbmdwKHJlcz1RdWVyeVByb3AoUF9YX0FUVFJfTU9EKSkgfHwgIXNpemVvZihyZXMpKSkgeworICAgICAgLy8gV2VubiBkaWVzZXMgT2JqZWt0IGluIGVpbmVtIExpdmluZyBpc3QgdW5kIGJpc2hlciBkaWUgcHJvcCBuaWNodAorICAgICAgLy8gZ2VzZXR6dCB3YXIsIG11c3Mgc2ljaCBkYXMgT2JqZWt0IG5vY2ggaW0gTGl2aW5nIGFscyBTdGF0bW9kaWZpemllcmVyCisgICAgICAvLyByZWdpc3RyaWVyZW4uCisgICAgICByZXM9U2V0KFBfWF9BVFRSX01PRCwgeG1vZCk7CisgICAgICBlbnZpcm9ubWVudCgpLT5yZWdpc3Rlcl9tb2RpZmllcihNRSk7CisgICAgICBlbnZpcm9ubWVudCgpLT5VcGRhdGVBdHRyaWJ1dGVzKE1FKTsKKyAgICB9CisgICAgZWxzZSBpZiAobGl2aW5nKGVudmlyb25tZW50KCkpKXsKKyAgICAgIC8vIHNvbnN0IHJlaWNodCBlaW4gZWluZmFjaGVzIFVwZGF0ZUF0dHJpYnV0ZXMoKSB1bSBkYXMgTGViZXdlc2VuIHp1CisgICAgICAvLyBpbmZvcm1pZXJlbi4KKyAgICAgIHJlcz1TZXQoUF9YX0FUVFJfTU9ELCB4bW9kKTsKKyAgICAgIGVudmlyb25tZW50KCktPlVwZGF0ZUF0dHJpYnV0ZXMoKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAvLyB3ZW5uIGtlaW4gbGViZW5kZXMgRW52LCByZWljaHQgZWluZmFjaGVzIFNldHplbi4KKyAgICAgIHJlcz1TZXQoUF9YX0FUVFJfTU9ELHhtb2QpOworICAgIH0KKyAgfQorCisgIHJldHVybiByZXM7Cit9CisKKy8vIFBfWF9IRUFMVEhfTU9EIGFlbmRlcm4gKExQL0tQLUFlbmRlcnVuZyBkdXJjaCBBdXNydWVzdHVuZykKK3N0YXRpYyBtYXBwaW5nIF9zZXRfZXh0ZXJuX2hlYWx0aF9tb2RpZmllcihtYXBwaW5nIHhtb2QpIHsKKyAgbWFwcGluZyByZXM7CisKKyAgLy8gd2VubiBNdWVsbCBvZGVyIGVpbiBsZWVyZXMgTWFwcGluZyB1ZWJlcmdlYmVuIHd1cmRlLCB3aXJkIGRpZSBwcm9wCisgIC8vIGdlbG9lc2NodCB1bmQgZ2dmLiBkYXMgT2JqZWt0IGltIExpdmluZyBhYmdlbWVsZGV0LgorICBpZiAoIW1hcHBpbmdwKHhtb2QpKSB4bW9kPShbXSk7CisgIAorICBpZiAoIXNpemVvZih4bW9kKSkgeworIAorICAgIHJlcz1TZXQoUF9YX0hFQUxUSF9NT0QsIHhtb2QpOworICAKKyAgICAvLyB3ZW5uIFByb3AgZ2Vsb2VzY2h0IHdpcmQsIGthbm4gbWFuIGRhcyBJdGVtIGF1Y2ggYXVzIGRlciBMaXN0ZSBkZXIKKyAgICAvLyBTdGF0bW9kaWZpemllcmVyIGRlcyBMZWJld2VzZW5zIGF1c3RyYWdlbi4KKyAgICBpZiAobGl2aW5nKGVudmlyb25tZW50KCkpKSB7ICAKKyAgICAgIGVudmlyb25tZW50KCktPmRlcmVnaXN0ZXJfbW9kaWZpZXIoTUUpOworICAgICAgZW52aXJvbm1lbnQoKS0+VXBkYXRlQXR0cmlidXRlcygpOworICAgIH0KKyAgfQorICBlbHNlIHsKKyAgICAvLyBvaywgUHJvcCB3aXJkIGF1ZiBuZW4gaW50ZXJlc3NhbnRlbiBXZXJ0IGdlc2V0enQuIDstKQorCisgICAgLy8gRGFtaXQgSW5zZXJ0L1JlbW92ZVNlbnNpdGl2ZU9iamVjdCBiZWltIE1vdmUgYXVmZ2VydWZlbiB3aXJkLAorICAgIC8vIG11c3MgUF9TRU5TSVRJVkUgZ2VzZXR6dCBzZWluCisgICAgaWYgKCFRdWVyeVByb3AoUF9TRU5TSVRJVkUpKSBTZXRQcm9wKFBfU0VOU0lUSVZFLCh7fSkpOworICAKKyAgICBpZiAobGl2aW5nKGVudmlyb25tZW50KCkpICYmIAorICAgICAgICAoIW1hcHBpbmdwKHJlcz1RdWVyeVByb3AoUF9YX0hFQUxUSF9NT0QpKSB8fCAhc2l6ZW9mKHJlcykpKSB7CisgICAgICAvLyBXZW5uIGRpZXNlcyBPYmpla3QgaW4gZWluZW0gTGl2aW5nIGlzdCB1bmQgYmlzaGVyIGRpZSBwcm9wIG5pY2h0CisgICAgICAvLyBnZXNldHp0IHdhciwgbXVzcyBzaWNoIGRhcyBPYmpla3Qgbm9jaCBpbSBMaXZpbmcgYWxzIFN0YXRtb2RpZml6aWVyZXIKKyAgICAgIC8vIHJlZ2lzdHJpZXJlbi4KKyAgICAgIHJlcz1TZXQoUF9YX0hFQUxUSF9NT0QsIHhtb2QpOworICAgICAgZW52aXJvbm1lbnQoKS0+cmVnaXN0ZXJfbW9kaWZpZXIoTUUpOworICAgICAgZW52aXJvbm1lbnQoKS0+VXBkYXRlQXR0cmlidXRlcyhNRSk7CisgICAgfQorICAgIGVsc2UgaWYgKGxpdmluZyhlbnZpcm9ubWVudCgpKSl7CisgICAgICAvLyBzb25zdCByZWljaHQgZWluIGVpbmZhY2hlcyBVcGRhdGVBdHRyaWJ1dGVzKCkgdW0gZGFzIExlYmV3ZXNlbiB6dQorICAgICAgLy8gaW5mb3JtaWVyZW4uCisgICAgICByZXM9U2V0KFBfWF9IRUFMVEhfTU9ELCB4bW9kKTsKKyAgICAgIGVudmlyb25tZW50KCktPlVwZGF0ZUF0dHJpYnV0ZXMoKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAvLyB3ZW5uIGtlaW4gbGViZW5kZXMgRW52LCByZWljaHQgZWluZmFjaGVzIFNldHplbi4KKyAgICAgIHJlcz1TZXQoUF9YX0hFQUxUSF9NT0QseG1vZCk7CisgICAgfQorICB9CisKKyAgcmV0dXJuIHJlczsKKworfQorCisvLyBQX1gvTV9BVFRSX01PRCB3ZXJkZW4gbmljaHQgYmVydWVja3NpY2h0aWd0LCBkYSBDVU1VTEFUSVZFX0FUVFJfTElNSVQKKy8vIHVlYmVyc2Nocml0dGVuIGlzdAordm9pZCBOb3RpZnlYTUF0dHJNb2RMaW1pdFZpb2xhdGlvbigpCit7Cit9CisgIApkaWZmIC0tZ2l0IGEvc3RkL3RoaW5nL3NvY2tldHMuYyBiL3N0ZC90aGluZy9zb2NrZXRzLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjRkOTg5OQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC90aGluZy9zb2NrZXRzLmMKQEAgLTAsMCArMSwyNTQgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8qKiBAZmlsZQorKiBJbXBsZW1lbnRhdGlvbiBmdWVyIFNvY2tlbGl0ZW1zLgorKiBMYW5nYmVzY2hyZWlidW5nLi4uIFRPRE8KKyogQGF1dGhvciBaZXNzdHJhICsgQXJhdGhvcm4KKyogQGRhdGUgeHguMDUuMjAwOAorKiBAdmVyc2lvbiAkSWQkCisqLworCisvKiBDaGFuZ2Vsb2c6CisqLworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBub19zaGFkb3cKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9zb2NrZXRzLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPGxwY3R5cGVzLmg+CisKKyNpZm5kZWYgREVCVUcKKy8qKiBPdXRwdXRzIGRlYnVnIG1lc3NhZ2UgdG8gTWFpbnRhaW5lciwgaWYgTWFpbnRhaW5lciBpcyBsb2dnZWQgaW4uIAorKi8KKyNkZWZpbmUgREVCVUcoeCkgX19kZWJ1Z19tc2dfXyh4KQorI2VuZGlmCisKKworcHJpdmF0ZSB2b2lkIF9fZGVidWdfbXNnX18oc3RyaW5nIHgpIHsKKyAgaWYgKGZpbmRfcGxheWVyKCJ6ZXNzdHJhIikpCisgICAgICB0ZWxsX29iamVjdChmaW5kX3BsYXllcigiemVzc3RyYSIpLCJTREJHOiAiK3grIlxuIik7Cit9CisKKy8qKiBTZXR6dCBcYSBpdGVtIGluIGVpbmVuIHBhc3NlbmRlbiBTb2NrZWwgZWluLgorICBXaXJkIHZvbSBIYW5kd2Vya2VyIGdlcnVmZW4uIFNvZmVybiBkaWUgUHJ1ZWZ1bmcgbWl0dGVscyBUZXN0U29ja2V0SXRlbSgpCisgIGVyZm9sZ3JlaWNoIGlzdCwgd2VyZGVuIGRpZSBQcm9wcyBkaWVzZXMgT2JqZWt0IGR1cmNoIGRpZSBpbSBJdGVtCisgIGdlc3BlaWNoZXJ0ZW4gaW4gUF9TT0NLRVRfUFJPUFMgZXJnYWVuenQsIGdnZi4gUF9SRVNUUklDVElPTiBnZWFlbmRlcnQgdW5kCisgIE5hbWUgZGVyIEJsdWVwcmludCwgTmFtZSB1bmQgUF9TT0NLRVRfUFJPUFMgaW4gUF9TT0NLRVRTIGdlc3BlaWNoZXJ0LCB1bQorICBzcGFldGVyIG5hY2h2b2xsemllaGVuIHp1IGtvZW5uZW4sIHdpZSBkaWVzZXMgT2JqZWt0IGJlcmVpdHMgbW9kaWZpemllcnQKKyAgd3VyZGUuCisgIEBhdHRlbnRpb24gQW0gRW5kZSBkZXIgRnVua3Rpb24gd2lyZCBcYSBpdGVtIHplcnN0b2VydCB1bmQgZGFyZiBuaWNodCBtZWhyCisgIGJlbnV0enQgd2VyZGVuIQorICBAcGFyYW1baW5dIGl0ZW0gT2JqZWt0LCB3ZWxjaGVzIGluIGVpbmVuIHBhc3NlbmRlbiBTb2NrZXQgZWluZ2VzZXR6dCB3ZXJkZW4KKyAgc29sbC4KKyAgQHJldHVybiAxLCBmYWxscyBFaW5zZXR6ZW4gZXJmb2xncmVpY2gsIDwwIHdlbm4gbmljaHQuCisgIEBzYSBUZXN0U29ja2V0SXRlbShvYmplY3QpCisgKi8KK3B1YmxpYyBpbnQgTW91bnRTb2NrZXRJdGVtKG9iamVjdCBpdGVtKSB7CisgIGlmICghb2JqZWN0cChpdGVtKSkgcmV0dXJuIFNPQ0tFVF9OT19PQkpFQ1Q7CisgIGlmICgoaW50IHJlcz1UZXN0U29ja2V0SXRlbShpdGVtKSkgIT0gU09DS0VUX09LKQorICAgIHJldHVybiByZXM7CisgIG1hcHBpbmcgaWRhdGE9KG1hcHBpbmcpaXRlbS0+UXVlcnlQcm9wKFBfU09DS0VUX1BST1BTKTsKKyAgLy8gVE9ETzogU3BlemlhbGJlaGFuZGx1bmcgZnVlciBQcm9wcywgYmVpIGRlbmVuIGRhcyBPYmpla3QgZXJoYWx0ZW4gYmxlaWJlbgorICAvLyBtdXNzLiAoei5CLiBQX0RFRkVORF9GVU5DKS4KKworICAvLyB6dSBtb2RpZml6aWVyZW5kZSBQcm9wcyBhZGRpZXJlbgorICBmb3JlYWNoKHN0cmluZyBwcm9wbmFtZSwgbWl4ZWQgcHZhbDogaWRhdGEpIHsKKyAgICBTZXRQcm9wKHByb3BuYW1lLCBBZGRUb0VudGl0eShRdWVyeVByb3AocHJvcG5hbWUpLCBwdmFsKSApOworICB9CisgIC8vIFJlc3RyaWN0aW9ucyBoaW56dWZ1ZWdlbi4KKyAgU2V0UHJvcChQX1JFU1RSSUNUSU9OUywgCisgICAgICBBZGRUb0VudGl0eShRdWVyeVByb3AoUF9SRVNUUklDVElPTlMpLCAKKwlpdGVtLT5RdWVyeVByb3AoUF9TT0NLRVRfUkVTVFJfVVNFKSkgKTsKKworICAvLyBEYXRlbiB1ZWJlciBkaWVzZXMgU29ja2V0aXRlbSBhYnNwZWljaGVybi4KKyAgbWl4ZWQgc29ja2V0cz1RdWVyeVByb3AoUF9TT0NLRVRTKVtpdGVtLT5RdWVyeVByb3AoUF9TT0NLRVRfVFlQRSldOworICAvLyBmcmVpZXIgU29ja2VsIG11c3MgZXhpc3RpZXJlbiAoLT5UZXN0U29ja2V0SXRlbSgpKQorICBpbnQgaW5kZXg9bWVtYmVyKHNvY2tldHMsIFNPQ0tFVF9GUkVFKTsKKyAgc29ja2V0c1tpbmRleF0gPSBpZGF0YSArIChbIkJMVUVfTkFNRSI6IGxvYWRfbmFtZShpdGVtKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJERVNDUklQVElPTiI6IGl0ZW0tPm5hbWUoV0VSKSBdKTsKKworICAvLyBnZ2YuIEJlc2NocmVpYnVuZyBha3R1YWxpc2llcmVuPworICAvLyBnZ2YuIFNvbmRlcmJlaGFuZGx1bmcgZnVlciBQcm9wcywgYmVpIGRlbmVuIGRhcyBPYmpla3Qgbm9jaCBnZWJyYXVjaHQKKyAgLy8gd2lyZCAoei5CLiBQX0RFRkVORF9JTkZPKQorCisgIC8vIFByb3Agc2NodWV0emVuLCBzb2JhbGQgRGF0ZW4gZHJpbiBzdGVoZW4uCisgIFNldChQX1NPQ0tFVFMsIFBST1RFQ1RFRHxOT1NFVE1FVEhPRCwgRl9NT0RFX0FTKTsKKworICAvLyBpdGVtIGVudHNvcmdlbgorICBpZiAoIWl0ZW0tPnJlbW92ZSgxKSkKKyAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJNb3VudFNvY2tldEl0ZW0oKSBpbiAlTzogJU8gaGF0IEF1c2Z1ZWhydW5nIHZvbiAiCisJICAicmVtb3ZlKCkgdmVyd2VpZ2VydC5cbiIsIE1FLCBpdGVtKSk7CisgIHJldHVybiBTT0NLRVRfT0s7Cit9CisKKy8qKiBQcnVlZnQsIG9iIFxhIGl0ZW0gaW4gZWluZW4gU29ja2VsIGVpbmdlc2V0enQgd2VyZGVuIGthbm4uCisgIFBydWVmdCwgb2IgZXMgZnVlciBkYXMgSXRlbSBlaW5lbiBwYXNzZW5kZW4gU29ja2VsIGdpYnQgdW5kIG9iIAorICBlcyBkaWUgZm9ybWFsZW4gQW5mb3JkZXJ1bmdlbiBlcmZ1ZWxsdCwgZG9ydCBlaW5nZXNldHp0IHp1IHdlcmRlbi4gCisgIEthbm4gdm9tIEhhbmR3ZXJrZXIgdm9yIGRlbSBlY2h0ZW4gRWluc2V0emVuIGdlcnVmZW4gd2VyZGVuLgorICBXaXJkIGF1Y2ggdm9uIE1vdW50U29ja2V0SXRlbShvYmplY3QpIGdlcnVmZW4uCisgIEBwYXJhbVtpbl0gaXRlbSBPYmpla3QsIHdlbGNoZXMgYXVmIEVpZ251bmcgenVtIEVpbnNldHplbiBpbiBlaW5lbiBTb2NrZWwKKyAgZ2V0ZXN0ZXQgd2VyZGVuIHNvbGwuCisgIEByZXR1cm4gMSwgZmFsbHMgZWluIHBhc3NlbmRlciB1bmQgZnJlaWVyIFNvY2tlbCBleGlzdGllcnQsIDAgc29uc3QuCisgIEBzYSBNb3VudFNvY2tldChvYmplY3QpCisqLworcHVibGljIGludCBUZXN0U29ja2V0SXRlbShvYmplY3QgaXRlbSkgeworCisgIGlmICghb2JqZWN0cChpdGVtKSkgcmV0dXJuIFNPQ0tFVF9OT19PQkpFQ1Q7CisgIAorICAvLyBpc3QgZXMgZWluIFNvY2tlbGl0ZW0gdW5kIGhhdCBlcyBlaW5lbiBndWVsdGlnZW4gVHlwPworICBtYXBwaW5nIGlkYXRhID0gKG1hcHBpbmcpaXRlbS0+UXVlcnlQcm9wKFBfU09DS0VUX1BST1BTKTsKKyAgaWYgKCFtYXBwaW5ncChpZGF0YSkgfHwgIXNpemVvZihpZGF0YSkpCisgICAgcmV0dXJuIFNPQ0tFVF9OT19EQVRBOworICBzdHJpbmcgc3R5cD0oc3RyaW5nKWl0ZW0tPlF1ZXJ5UHJvcChQX1NPQ0tFVF9UWVBFKTsKKyAgaWYgKCFzdHJpbmdwKHN0eXApCisgICAgICB8fCBtZW1iZXIoVkFMSURfU09DS0VUX1RZUEVTLCBzdHlwKSA9PSAtMSkKKyAgICByZXR1cm4gU09DS0VUX0lOVkFMSURfVFlQRTsKKworICAvLyBIYXQgZGllc2VzIEl0ZW0gdWViZXJoYXVwdCBTb2NrZWw/IFVuZCB3ZW5uIGphLCBoYWJlbiB3aXIgbmVuIGZyZWllbgorICAvLyBTb2NrZSBmdWVyIGRlbiBiZXRyZWZmZW5kZW4gVHlwPworICBtYXBwaW5nIG15c29ja2V0cyA9IFF1ZXJ5UHJvcChQX1NPQ0tFVFMpOworICBpZiAoIW1hcHBpbmdwKG15c29ja2V0cykgfHwgIXNpemVvZihteXNvY2tldHMpKSAKKyAgICByZXR1cm4gU09DS0VUX05PX1NPQ0tFVFM7CisgIGlmICghbWVtYmVyKG15c29ja2V0cywgc3R5cCkKKyAgICAgIHx8ICFtZW1iZXIobXlzb2NrZXRzW3N0eXBdLCBTT0NLRVRfRlJFRSkgPT0gLTEgKQorICAgIHJldHVybiBTT0NLRVRfTk9ORV9BVkFJTEFCTEU7CisKKyAgLy8gSGFuZHdlcmtlciBwcnVlZmVuLgorICAvLyBUT0RPOiBTb2xsIGRpZSBGZWhsZXJtZWxkdW5nIGtvbXBsZXR0IHZvbSBBdWZydWZlciBlcmxlZGlndCB3ZXJkZW4gb2RlcgorICAvLyBzb2xsIGVzIGVpbmVuIEhlaW53ZWlzIGdlYmVuLCB3YXJ1bSBkZXIgSGFuZHdlcmtlciBuaWNodCBnZWVpZ25ldCBpc3Q/CisgIG9iamVjdCBjcmFmdHNtYW4gPSBwcmV2aW91c19vYmplY3QoKTsKKyAgbWFwcGluZyByZXN0ciA9IChtYXBwaW5nKWl0ZW0tPlF1ZXJ5UHJvcChQX1NPQ0tFVF9SRVNUUl9NT1VOVCk7CisgIGlmICghb2JqZWN0cChjcmFmdHNtYW4pCisgICAgICB8fCAobWFwcGluZ3AocmVzdHIpCisJJiYgIi9zdGQvcmVzdHJpY3Rpb25fY2hlY2tlciItPmNoZWNrX3Jlc3RyaWN0aW9ucyhjcmFmdHNtYW4sCisJICByZXN0cikpKQorICAgIHJldHVybiBTT0NLRVRfTk9fRVhQRVJUSVNFOworCisgIC8vIGRhIFBfUkVTVFJJQ1RJT04gbnVyIGJlaW0gQW56aWVoZW4vWnVlY2tlbiBnZXBydWVmdCB3aXJkLCBkYXJmIG1hbiBlaW4KKyAgLy8gSXRlbSBuaWNodCBpbiBnZXRyYWdlbmVtIFp1c3RhbmQgbW9kaWZpemllcmVuLgorICBpZiAob2JqZWN0cCgob2JqZWN0KWl0ZW0tPlF1ZXJ5UHJvcChQX1dJRUxERUQpKQorICAgICAgfHwgb2JqZWN0cCgob2JqZWN0KWl0ZW0tPlF1ZXJ5UHJvcChQX1dPUk4pKSkKKyAgICByZXR1cm4gU09DS0VUX0lURU1fSU5VU0U7CisKKyAgcmV0dXJuIFNPQ0tFVF9PSzsKK30KKworLyoqIExpZWZlcnQgSW5mb3MgdWViZXIgZGllIFNvY2tldHMgKFR5cCwgd2FzIGRyaW4gaXN0LCBldGMuXCApLgorICBQcmltYWVyIGZ1ZXIgR2lsZGVuIGdlZGFjaHQuCisqLworcHVibGljIG1peGVkIEdldFNvY2tldEluZm8oKSB7Cit9CisKKy8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKiogcHJpdmF0ZSAqKioqKioqKioqKioqKioqKioqKioqKioqICovCisKKy8qKiBBZGRpZXJ0IHp3ZWkgVmFyaWFibGVuLCBzb2Zlcm4gc2llIGtvbXBhdGliZWwgc2luZC4KKyAgTGFzc2VuIHNpY2ggZGllIGJlaWRlbiBEYXRlbnR5cGVuIG5pY2h0IHNpbm52b2xsIGFkZGllcmVuLCBlcmZvbGd0IGtlaW5lCisgIEFkZGl0aW9uIHVuZCBcYSBvbGQgd2lyZCB6dXJ1ZWNrIGdlbGllZmVydCAoei5CLiBiZWkgT2JqZWt0ZW4sIENsb3N1cmVzKS4KKyAgSGllcmJlaSBlcmZvbGd0IHouQi4gYmVpIE1hcHBpbmdzIGVpbmUgd2VydHdlaXNlIEFkZGl0aW9uLCBrZWluZSBibG9zc2UKKyAgRXJzZXR6dW5nIGRlciBLZXlzIHdpZSBiZWkgZGVyIG5vcm1hbGVuIE1hcHBpbmctQWRkaXRpb24uCisgIEBwYXJhbVtpbixvdXRdIG9sZCBEYXR1bSwgenUgZGVtIGFkZGllcnQgd2VyZGVuIHNvbGwuIFdpcmQgYmVpIE1hcHBpbmdzCisgIGdlYWVuZGVydC4KKyAgQHBhcmFtW2luXSBuZXcgRGF0dW0sIHdlbGNoZXMgYWRkaWVydGVuIHNvbGwuCisgIEByZXR1cm4gU3VtbWUgdm9uIG9sZCB1bmQgbmV3LCBmYWxscyBkaWUgRGF0ZW50eXBlbiBrb21wYXRpYmVsIHNpbmQuIEZhbGxzCisgIG5pY2h0LCBrYW5uIG9sZCB6dXJ1ZWNrZ2VnZWJlbiB3ZXJkZW4uIERlciBEYXRlbnR5cCB2b24gCisgIEBhdHRlbnRpb24gXGIgUmVrdXJzaXYhIEthbm4gdGV1ZXIgd2VyZGVuLlxuCisgICAgS2FubiAobW9kaWZpemllcnRlKSBcYSBvbGQgb2RlciBcYSBuZXcgb2RlciBnYW56IG5ldWVzIERhdHVtIAorICAgIHp1cnVlY2tsaWVmZXJuLCBkLmguIGRlciB6dXJ1ZWNrZ2VsaWVmZXJ0ZSBEYXRlbnR5cCBtdXNzIG5pY2h0IGRlbQorICAgIERhdGVudHlwIHZvbiBvbGQgZW50c3ByZWNoZW4uIEViZW5zbyBlcnpldWd0IHouQi4gZGllIEFkZGl0aW9uIHp3ZWllcgorICAgIEFycmF5cyBlaW4gbmV1ZXMgQXJyYXkuCisgICAgV2VubiBkaWUga29ycmVzcG9uZGllcmVuZGVuIFdlcnRlIG5pY2h0IGRlbiBnbGVpY2hlbiBEYXRlbnR5cCBoYWJlbiwKKyAgICBmaW5kZXQgdS5VLiBrZWluZSBBZGRpdGlvbiBzdGF0dCBvZGVyIGVzIHdpcmQgZWluZSBEYXRlbnR5cC1VbXdhbmRsdW5nCisgICAgZHVyY2hnZWZ1ZWhydCwgei5CLiBJbnQgKyBGbG9hdCA9PSBGbG9hdC5cbgorICAqLworcHJpdmF0ZSBtaXhlZCBBZGRUb0VudGl0eShtaXhlZCBvbGQsIG1peGVkIG5ldykgeworCisgIC8vIGVpbmZhY2hzdGUgRmFlbGxlOgorICBpZiAoIW9sZCkKKyAgICByZXR1cm4gbmV3OworICBlbHNlIGlmICghbmV3KQorICAgIHJldHVybiBvbGQ7CisKKyAgLy8gVHlwIGJlc3RpbW1lbgorICBpbnQgb2xkdHlwZSA9IHR5cGVvZihvbGQpOworICBpbnQgbmV3dHlwZSA9IHR5cGVvZihuZXcpOworICAvLyBWYXJpYWJsZW4gZ2xlaWNoZW4gVHlwcyBzaW5kIGVpbmZhY2guCisgIGlmIChvbGR0eXBlID09IG5ld3R5cGUpIHsKKyAgICBzd2l0Y2ggKG9sZHR5cGUpIHsKKyAgICAgIC8vIGVpbmlnZSBUeXBlbiB3ZXJkZW4gc3R1bXBmIGFkZGllcnQuCisgICAgICBjYXNlIFRfTlVNQkVSOgorICAgICAgY2FzZSBUX1NUUklORzoKKyAgICAgIGNhc2UgVF9GTE9BVDoKKyAgICAgIGNhc2UgVF9QT0lOVEVSOiAvLyBUT0RPOiBhbmRlcmVzIFZlcmhhbHRlbj8KKwlyZXR1cm4gb2xkK25ldzsKKyAgICAgIC8vIE1hcHBpbmdzIHdlcmRlbiB3ZXJ0d2Vpc2UgYWRkaWVydC4KKyAgICAgIGNhc2UgVF9NQVBQSU5HOgorCS8vIG51ciB3ZW5uIGRpZSBCcmVpdGUgZGVzIDIuIFN1bW1hbmRlbiA8PSBkZXIgZGVzIDEuIFN1bW1hbmRlbiBpc3QsCisJLy8gbGFzc2VuIHNpY2ggTWFwcGluZ3MgaGllcm1pdCBhZGRpZXJlbi4KKwlpZiAod2lkdGhvZihuZXcpID4gd2lkdGhvZihvbGQpKQorCSAgcmV0dXJuIG9sZDsKKwkvLyBuZXcgYXVmIG9sZCBhZGRpZXJlbi4gS2V5cyB3ZXJkZW4gbmljaHQgZXJzZXR6dCwgc29uZGVybiBuYWNoCisJLy8gTW9lZ2xpY2hrZWl0IGRpZSB3ZXJ0ZSB1bnRlciBkZW4ga2V5cyBqZXdlaWxzIGFkZGllcnQuCisJLy8gbWFwKCkgbnVyIHp1bSBVZWJlcmdlYmVuIGFsbGVyIEtleXMrVmFsdWUuIEFkZFRvTWFwcGluZyBhZW5kZXJ0CisJLy8gZGlyZWt0IGRhcyB1ZWJlcmdlYmVuZSBNYXBwaW5nIG9sZC4KKwltYXAobmV3LCAjJ0FkZFRvTWFwcGluZywgb2xkKTsgCisJLy8gYWxsZXMgaGllciBuaWNodCBhdWZnZWZ1ZWhydGUga2FubiBuaWNodCBhZGRpZXJ0IHdlcmRlbi4KKyAgICAgIGRlZmF1bHQ6IHJldHVybiBvbGQ7CisgICAgfQorICB9CisgIC8vIEludHMgdW5kIEZsb2F0cyBzaW5kIGF1Y2ggbm9jaCBndXQgYWRkaWVyYmFyLgorICBlbHNlIGlmICgob2xkdHlwZSA9PSBUX0ZMT0FUICYmIG5ld3R5cGUgPT0gVF9OVU1CRVIpIHx8CisgICAgICAgICAgIChvbGR0eXBlID09IFRfTlVNQkVSICYmIG5ld3R5cGUgPT0gVF9GTE9BVCkgKQorICAgIHJldHVybiBvbGQgKyBuZXc7CisgIC8vIEFycmF5cyBsYXNzZW4gc2ljaCBhdWNoIGd1dCB2ZXJ3dXJzdGVuIChuZXcga2FubiBrZWluIEFycmF5IHNlaW4pLgorICAvLyBVbWdla2VocnRlciBGYWxsIHdhZXJlIGF1Y2ggbWVvZ2xpY2gsIGFiZXIgZGVyIERhdGVudHlwIHZvbiBvbGQgd2FlcmUKKyAgLy8gc2VociBkZXV0bGljaCB1bnRlcnNjaGllZGxpY2ggdm9tIHVyc3BydWVuZ2xpY2hlbi4KKyAgZWxzZSBpZiAob2xkdHlwZSA9PSBUX1BPSU5URVIpCisgICAgcmV0dXJuIG9sZCsoe25ld30pOworICAvLyBTdHJpbmdzIHVuZCBaZWljaGVubGl0ZXJhbGUgKEludHMpIHNpbmQgQW5zaWNodHNzYWNoZS4KKyAgZWxzZSBpZiAob2xkdHlwZSA9PSBUX1NUUklORyAmJiBuZXd0eXBlID09IFRfTlVNQkVSKQorICAgIHJldHVybiBzcHJpbnRmKCIlcyVjIixvbGQsbmV3KTsKKyAgZWxzZSBpZiAob2xkdHlwZSA9PSBUX05VTUJFUiAmJiBuZXd0eXBlID09IFRfU1RSSU5HKQorICAgIHJldHVybiBzcHJpbnRmKCIlYyVzIixvbGQsbmV3KTsKKworICAvLyBGYWxsLXRocm91Z2gKKyAgcmV0dXJuIG9sZDsKK30KKworLyoqIEFkZGllcnQgZWluZW4gU2NobHVlc3NlbCB1bmQgc2VpbmUgV2VydGUgenUgZWluZW0gTWFwcGluZywgZ2dmLlwgYXVmIGRpZQorICogYmVzdGVoZW5kZW4gV2VydGUgZGVzIE1hcHBpbmdzIFxhIG9sZC4KKyAqIERlciBLZXkgdW5kIHNlaW5lIFdlcnRlIGVyc2V0emVuIGJlc3RlaGVuZGUgV2VydGUgaW4gXGEgb2xkIG5pY2h0LCB3aWUgZXMKKyAqIGRpZSBub3JtYWxlIE1hcHBpbmctQWRkaXRpb24gZGVzIERyaXZlciBtYWNodC4gU3RhdHRkZXNzZW4gd2lyZCB2ZXJzdWNodCwKKyAqIGRpZSBuZXVlbiBXZXJ0ZSBhdWYgZGllIGVudHNwcmVjaGVuZGVuIGFsdGVuIFdlcnRlIHp1IGFkZGllcmVuLiBGYWxscyBkaWUKKyAqIERhdGVudHlwZW4gendlaWVyIFdlcnRlIGlua29tcGF0aWJlbCBzaW5kLCBlcmZvbGd0IGtlaW5lIEFkZGl0aW9uIHVuZCBkZXIKKyAqIGFsdGUgV2VydGUgaGF0IEJlc3RhbmQuCisgIEBwYXJhbVtpbl0ga2V5IChtaXhlZCkgV2VydCwgZGVyIGluIGRhcyBNYXBwaW5nIGFkZGllcnQgd2lyZC4KKyAgQHBhcmFtW2luXSB2YWx1ZXMgKG1peGVkKQorICBAcGFyYW1baW4sb3V0XSBvbGQgTWFwcGluZywgaW4gZGFzIGFkZGllcnQgd2lyZC4KKyAgQGF0dGVudGlvbiBEaWUgQnJlaXRlcyBkZXMgMi4gU3VtbWFuZGVuIGRhcmYgXGIgbmljaHQgZ3JvZXNzZXIgc2VpbiBhbHMgZGllCisgIEJyZWl0ZSBkZXMgMSwgU3VtbWFuZGVuISBcbgorICAgIERpZSBrb3JyZXNwb25kaWVyZW4gV2VydGUgc29sbHRlbiBkZW4gZ2xlaWNoZW4gRGF0ZW50eXAgaGFiZW4sIHNvbnN0CisgICAgZmluZGV0IHUuVS4ga2VpbmUgQWRkaXRpb24gc3RhdHQgb2RlciBlcyB3aXJkIGVpbmUgRGF0ZW50eXAtVW13YW5kbHVuZworICAgIGR1cmNoZ2VmdWVocnQsIHouQi4gSW50ICsgRmxvYXQgPT0gRmxvYXQuXG4KKyAgKi8KK3ByaXZhdGUgdm9pZCBBZGRUb01hcHBpbmcobWl4ZWQga2V5LCBtaXhlZCB2YWx1ZXMsIG1hcHBpbmcgb2xkKSB7CisgIGlmICghbWFwcGluZ3Aob2xkKSkgcmV0dXJuOworICBpZiAoIXBvaW50ZXJwKHZhbHVlcykpIHZhbHVlcyA9ICh7dmFsdWVzfSk7CisKKyAgLy8gd2VubiBkZXIgS2V5IG5vY2ggbmljaHQgZXhpc3RpZXJ0LCBpc3RzIGVpbmZhY2guCisgIGlmICghbWVtYmVyKG9sZCwga2V5KSkKKyAgICBtX2FkZChvbGQsIGtleSwgdmFsdWVzLi4uKTsgLy8gZmxhdHRlbiBvcGVyYXRvciAuLi4gY29vbC4gOy0pCisgIGVsc2UgeworICAgIC8vIHNvbnN0IG11ZXNzZW4gd2lyIHRldXJlIGhhbmRhcmJlaXQgbWFjaGVuLiBJbnNiLiB3ZWlsIGRpZSBWYWx1ZXMgZWluZW4KKyAgICAvLyBiZWxpZWJpZ2VuIERhdGVudHlwIGhhYmVuIGtvZW5uZW4sIHUuYS4gTWFwcGluZ3MsIHdlc3dlZ2VuIHdpciB3aWVkZXIKKyAgICAvLyByZWt1cnNpdiBBZGRUb0VudGl0eSgpIHJ1ZmVuIG11ZXNzZW4uCisgICAgZm9yKGludCBpPXNpemVvZih2YWx1ZXMpIDsgaS0tIDsgKSB7CisgICAgICBvbGRba2V5LGldID0gQWRkVG9FbnRpdHkob2xkW2tleSxpXSwgdmFsdWVzW2ldKTsKKyAgICB9CisgIH0KK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3RoaW5nL3V0aWwuYyBiL3N0ZC90aGluZy91dGlsLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDQzNDY0MgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC90aGluZy91dGlsLmMKQEAgLTAsMCArMSwxMTEgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB0aGluZy91dGlsLmMgLS0gVXRpbGl0aWVzCisvLworLy8gJElkOiB1dGlsLmMgNjM2NiAyMDA3LTA3LTE1IDIxOjA2OjI0WiBaZXNzdHJhICQKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlICIvc3lzL3RoaW5nL3V0aWwuaCIKKyNpbmNsdWRlICIvc3lzL3RoaW5nL3Byb3BlcnRpZXMuaCIKKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitwdWJsaWMgdm9pZCBTaG93UHJvcExpc3Qoc3RyaW5nICpwcm9wcykgCit7CisgIGludCBpLGo7CisKKyAgaj1zaXplb2YocHJvcHMpOworCisgIGZvciAoIGk9MDsgaTxqIDsgaSsrKSAKKyAgeworICAgIHdyaXRlKCIqIitwcm9wc1tpXSsiOiAiKTsKKyAgICBQcmV0dHlEdW1wKFF1ZXJ5UHJvcChwcm9wc1tpXSkpOworICAgIHdyaXRlKCJcbiIpOworICB9Cit9CisKK3N0YXRpYyB2b2lkIFByZXR0eUR1bXAobWl4ZWQgeCkgCit7CisgIGlmIChwb2ludGVycCh4KSkgCisgIHsKKyAgICBEdW1wQXJyYXkoeCk7CisgIH0KKyAgZWxzZSBpZiAobWFwcGluZ3AoeCkpCisgIHsKKyAgICBEdW1wTWFwcGluZyh4KTsKKyAgfQorICBlbHNlIGlmIChvYmplY3RwKHgpKSAKKyAgeworICAgIHdyaXRlICgiT0JKKCIrb2JqZWN0X25hbWUoeCkrIikiKTsKKyAgfQorICBlbHNlIGlmIChzdHJpbmdwKHgpKQorICB7CisgICAgd3JpdGUoIlwiIit4KyJcIiIpOworICB9CisgIGVsc2UKKyAgeworICAgIHdyaXRlICh4KTsKKyAgfQorfQorCitzdGF0aWMgdm9pZCBEdW1wQXJyYXkobWl4ZWQgKngpIAoreworICBpbnQgaSxqOworCisgIHdyaXRlICgiKHsgIik7CisgIGlmICggKGo9c2l6ZW9mKHgpKT4wICkKKyAgeworICAgIGZvciAoIGk9MCA7IGk8KGotMSkgOyBpKyspIAorICAgIHsKKyAgICAgIFByZXR0eUR1bXAoeFtpXSk7CisgICAgICB3cml0ZSgiLCAiKTsKKyAgICB9CisgICAgUHJldHR5RHVtcCh4W2ldKTsKKyAgICB3cml0ZSgiICIpOworICB9CisgIHdyaXRlICgifSkiKTsKK30KKworc3RhdGljIHZvaWQgRHVtcE1hcHBpbmcobWFwcGluZyB4KQoreworICBpbnQgICBpLCBjLCBzOworICBtaXhlZCAqaW5kOworCisgIHdyaXRlKCIoWyAiKTsKKworICBpZiAoIChjPXNpemVvZihpbmQ9bV9pbmRpY2VzKHgpKSk8MSApCisgIHsKKyAgICB3cml0ZSgiIF0pIik7CisgICAgcmV0dXJuOworICB9CisKKyAgcz1nZXRfdHlwZV9pbmZvKHgsMSk7CisKKyAgRHVtcEtleVZhbFBhaXIoeCwgaW5kWzBdLCBzKTsKKyAgZm9yICggaT0xIDsgaTxjIDsgaSsrICkKKyAgeworICAgIHdyaXRlKCIsICIpOworICAgIER1bXBLZXlWYWxQYWlyKHgsIGluZFtpXSwgcyk7CisgIH0KKyAgd3JpdGUoIiBdKSIpOworfQorCisvLyBMYWNodCBuaWNodCB1ZWJlciBkZW4gTmFtZW4hISEgLUJvaW5nCisvLyBOZWluLCB1ZWJlciBkZW4gTmFtZW4gbGFjaGUgaWNoIG5pY2h0IC4uLiAtUGFyYWNlbHN1cworc3RhdGljIHZvaWQgRHVtcEtleVZhbFBhaXIobWFwcGluZyB4LCBtaXhlZCBrZXksIGludCBzaXplKQoreyBpbnQgaiwgdmM7CisKKyAgUHJldHR5RHVtcChrZXkpOworICB3cml0ZSgiIDogIik7CisgIFByZXR0eUR1bXAoeFtrZXksMF0pOworCisgIGZvciAoIGo9MTsgajxzaXplOyBqKyspCisgIHsKKyAgICB3cml0ZSgiOyAiKTsKKyAgICBQcmV0dHlEdW1wKHhba2V5LCBqXSk7CisgIH0KK30KZGlmZiAtLWdpdCBhL3N0ZC90cmFkaW5nX3ByaWNlLmMgYi9zdGQvdHJhZGluZ19wcmljZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjRiZmM5NmMKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdHJhZGluZ19wcmljZS5jCkBAIC0wLDAgKzEsMTc0IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdHJhZGluZ19wcmljZS5jIC0tIFByZWlzdmVyaGFsdGVuIHZvbiBMYWVkZW4gdW5kIEhhZW5kbGVybgorLy8KKy8vICRJZDogdHJhZGluZ19wcmljZS5jLHYgMy4zIDIwMDIvMDYvMDkgMTk6NTE6NDAgVGlsbHkgRXhwICQKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDx0aGluZy9wcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8YmFuay5oPgorCisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCisvLyBUT0RPOiBsYW5nZnJpc3RpZyB6dSBwcml2YXRlIGFlbmRlcm4/Citub3NhdmUgaW50IGJ1eWZhY3QsIHNob3BfcGVyY2VudF9sZWZ0LCBteW1vbmV5LCB3YW50dG8sIGxhc3Q7Citwcml2YXRlIG5vc2F2ZSBpbnQgd2FudHRocmVzaCwgbWF4bnVtOworCit2YXJhcmdzIGludCBTZXRUcmFkaW5nRGF0YShpbnQgbW9uZXksIGludCBmYWN0b3IsIGludCBtYXhvYnMpCit7CisgIGlmIChleHRlcm5fY2FsbCgpICYmIHByZXZpb3VzX29iamVjdCgpICE9IHRoaXNfb2JqZWN0KCkpCisgICAgbG9nX2ZpbGUoIlpFTlRSQUxCQU5LIixzcHJpbnRmKCJJTklUSUFMSVpFOiAlTyBnb3QgKCVkLCVkLCVkKSBmcm9tICVPICglTylcbiIsCisJCQkJICAgdGhpc19vYmplY3QoKSwgbW9uZXksZmFjdG9yLG1heG9icywKKwkJCQkgICBwcmV2aW91c19vYmplY3QoKSx0aGlzX3BsYXllcigpKSk7CisKKyAgaWYgKG1vbmV5IDwgMTAwMCkKKyAgICBtb25leSA9IDEwMDA7CisKKyAgbGFzdD13YW50dG89bXltb25leT1tb25leTsKKyAgd2FudHRocmVzaD13YW50dG8vMjsKKyAgaWYgKHdhbnR0aHJlc2ggPCA1MDAwKQorICAgIHdhbnR0aHJlc2ggPSA1MDAwOworCisgIGlmIChmYWN0b3IgPCAxMDApCisgICAgYnV5ZmFjdCA9IDMwMDsKKyAgZWxzZQorICAgIGJ1eWZhY3QgPSBmYWN0b3I7CisgIAorICBpZiAobWF4b2JzIDwgMSkKKyAgICBtYXhudW09MzsKKyAgZWxzZQorICAgIG1heG51bT1tYXhvYnM7CisgIAorICByZXR1cm4gbXltb25leTsKK30KKwordm9pZCBTZXRCdXlGYWN0KGludCBpKQoreworICBidXlmYWN0PWkqMTAwOworfQorCit2YXJhcmdzIGludCBRdWVyeUJ1eUZhY3Qob2JqZWN0IGNsaWVudCkKK3sKKyAgcmV0dXJuIGJ1eWZhY3Q7Cit9CisKK2ludCBJbmZsYXRlU2VsbFZhbHVlKGludCB2YWx1ZSwgaW50IGNudCkKK3sKKyAgY250LT1tYXhudW07CisgIGlmIChjbnQ8MCkgY250PTA7CisgIHJldHVybiB2YWx1ZS0odmFsdWUqY250KS8oY250KzI1KTsKK30KKworaW50IFRydW5jYXRlU2VsbFZhbHVlKGludCB2YWx1ZSkKK3sKKyAgaWYgKHZhbHVlID4gNTAwKSB7CisgICAgdmFsdWUtPTUwMDsKKyAgICB2YWx1ZSA9ICgoMTAwMCp2YWx1ZSkvKHZhbHVlKzEwMDApKSs1MDA7CisgIH0KKyAgcmV0dXJuIHZhbHVlOworfQorCitpbnQgT2JqZWN0Q291bnQob2JqZWN0IG9iKQoreworICByZXR1cm4gb2JqZWN0cChvYik7IC8vIDAgb2RlciAxCit9CisKK3ZhcmFyZ3MgaW50IFF1ZXJ5VmFsdWUob2JqZWN0IG9iLCBpbnQgdmFsdWUsIG9iamVjdCBjbGllbnQpCit7CisgIHZhbHVlPVRydW5jYXRlU2VsbFZhbHVlKEluZmxhdGVTZWxsVmFsdWUodmFsdWUsT2JqZWN0Q291bnQob2IpKSk7CisgIGlmICgzKnZhbHVlPm15bW9uZXkpCisgIHsKKyAgICBsb2dfZmlsZSgiTEFERU4iLHNwcmludGYoIk91dCBvZiBtb25leTogJU8gZm9yICVPICglcylcbiIsdGhpc19vYmplY3QoKSwKKwkJCSAgICAgdGhpc19wbGF5ZXIoKSxkdGltZSh0aW1lKCkpWzUuLl0pKTsKKyAgICB2YWx1ZT1teW1vbmV5LzM7CisgIH0KKyAgaWYgKHZhbHVlPDApIHZhbHVlPTA7CisgIAorICAvKiAgIFByZWlzdmVyZmFsbCB2b24gYmVzY2hhZWRpZ3Rlbk9iamVrdGVuIGdsZWljaCBoaWVyIGZlc3RsZWdlbiAgKi8KKworICBpZih2YWx1ZSAmJiBvYi0+UXVlcnlQcm9wKFBfREFNQUdFRCkpICAKKyAgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCisgICAgaWYob2ItPlF1ZXJ5UHJvcChQX1dDKSB8fCBvYi0+UXVlcnlQcm9wKFBfQUMpKQorICAgIHsKKyAgICAgIHZhbHVlID0gKDYgKiAodmFsdWUgLyAxMCkpOworICAgIH0KKyAgICBlbHNlCisgICAgeworICAgICAgdmFsdWUgPSAoNCAqICh2YWx1ZSAvIDEwKSk7CisgICAgfQorICB9CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKKyAgcmV0dXJuIHZhbHVlOworfQorCit2YXJhcmdzIGludCBRdWVyeVNlbGxWYWx1ZShvYmplY3Qgb2IsIG9iamVjdCBjbGllbnQpCit7CisgIHJldHVybiBRdWVyeVZhbHVlKG9iLG9iLT5RdWVyeVByb3AoUF9WQUxVRSksY2xpZW50KTsKK30KKwordmFyYXJncyBpbnQgUXVlcnlCdXlWYWx1ZShtaXhlZCBvYiwgb2JqZWN0IGNsaWVudCkKK3sKKyAgLy8gTWl0IFJ1bmRlbi4KKyAgcmV0dXJuIChvYi0+UXVlcnlQcm9wKFBfVkFMVUUpKlF1ZXJ5QnV5RmFjdChjbGllbnQpICsgNTApLzEwMDsKK30KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgU2V0UHJvcChQX1NIT1BfUEVSQ0VOVF9MRUZULCAwKTsKKyAgU2V0VHJhZGluZ0RhdGEoNTAwMDAsMzAwLDMpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKwordm9pZCByZXNldCgpCit7CisgIFNldFByb3AoUF9TSE9QX1BFUkNFTlRfTEVGVCwgMCk7CisKKyAgaWYgKGxhc3QvMz5teW1vbmV5KQorICAgIHdhbnR0bz13YW50dG8qMTEwLzEwMDsKKyAgZWxzZQorICAgIGlmIChsYXN0LzI8bXltb25leSkKKyAgICAgIHdhbnR0bz13YW50dG8qODUvMTAwOworICBpZiAod2FudHRvPHdhbnR0aHJlc2gpIHdhbnR0bz13YW50dGhyZXNoKzUwMDsKKyAgaWYgKHdhbnR0bz4xNTAwMDAwKSB3YW50dG89MTUwMDAwMDsKKyAgaWYgKHdhbnR0bzxteW1vbmV5KQorICB7CisgICAgWkVOVFJBTEJBTkstPlBheUluKG15bW9uZXktd2FudHRvKTsKKyAgICBteW1vbmV5PXdhbnR0bzsKKyAgfSBlbHNlCisgICAgbXltb25leSs9WkVOVFJBTEJBTkstPldpdGhEcmF3KHdhbnR0by1teW1vbmV5KTsKKyAgbGFzdD1teW1vbmV5OworfQorCit2b2lkIF9hZGRfbW9uZXkoaW50IGkpIHsKKyAgaWYgKGV4dGVybl9jYWxsKCkgJiYgcHJldmlvdXNfb2JqZWN0KCkgIT0gdGhpc19vYmplY3QoKSkKKyAgICBsb2dfZmlsZSgiWkVOVFJBTEJBTksiLHNwcmludGYoIiVzOiBUUkFOU0ZFUjogJU8gZ290ICVkIGZyb20gJU9cbiIsCisJc3RyZnRpbWUoIiVIOiVNIiksIHRoaXNfb2JqZWN0KCksIGksIHByZXZpb3VzX29iamVjdCgpKSk7CisgIG15bW9uZXkrPWk7Cit9CisKK2ludCBfc2V0X3Nob3BfcGVyY2VudF9sZWZ0KGludCBkdW1teSkgeworICByZXR1cm4gc2hvcF9wZXJjZW50X2xlZnQ9WkVOVFJBTEJBTkstPl9xdWVyeV9zaG9wX3BlcmNlbnRfbGVmdCgpOworfQorCitpbnQgX3F1ZXJ5X3Nob3BfcGVyY2VudF9sZWZ0KCkgeworICByZXR1cm4gc2hvcF9wZXJjZW50X2xlZnQ7Cit9CisKK2ludCBfcXVlcnlfY3VycmVudF9tb25leSgpIHsKKyAgcmV0dXJuIG15bW9uZXk7Cit9CisKK2ludCBfcXVlcnlfd2FudHRvKCkgeworICByZXR1cm4gd2FudHRvOworfQorCisKZGlmZiAtLWdpdCBhL3N0ZC90cmFuc3BvcnQuYyBiL3N0ZC90cmFuc3BvcnQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mZmZlMWUwCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3RyYW5zcG9ydC5jCkBAIC0wLDAgKzEsNTIxIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdHJhbnNwb3J0LmMgLS0gQmFzaXNrbGFzc2UgZnVlciBTY2hpZmZlIHVuZCBhZWhubGljaGUgVHJhbnNwb3J0ZXIKKy8vCisvLyAkSWQ6IHRyYW5zcG9ydC5jIDk0MDAgMjAxNS0xMi0xMSAyMTo1NjoxNFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcworLy8jcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC90aGluZy9tb3ZpbmciOworaW5oZXJpdCAiL3N0ZC9yb29tIjsKKworI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDx0cmFuc3BvcnQuaD4KKyNpbmNsdWRlIDxyZWdleHAuaD4KKworLyogdHJhbnNwb3J0LmMKKyAqIAorICogVWViZXJhcmJlaXRldGUgdW5kIAorICogZXJ3ZWl0ZXJ0ZSBWZXJzaW9uIDogVGlsbHlATW9yZ2VuR3JhdWVuLCAxMC4wMS4wMgorICogQmFzaWVyZW5kIGF1ZiAgICAgIDogdHJhbnNwb3J0LmNAU2lsYmVyTGFuZCAoV29vZHlAU2lsYmVyTGFuZCksIDA1LjEyLjk5CisgKiBCYXNpZXJlbmQgYXVmICAgICAgOiBIYXRlcyB1bmQgUnVtYXRhcyBnZW5lcmlzY2hlcyBUcmFuc3BvcnQgT2JqZWt0CisgKiAgICAgICAgICAgICAgICAgICAgICBNb3JnZW5HcmF1ZW4gMTUuMDIuOTMKKyAqLworICAgICAKKy8qCisgKioqKioqKioqKioqKioqKioqKioqIFZhcmlhYmxlbiAqKioqKioqKioqKioqKioqKioqKioKKyAqLworCisvLyBUT0RPOiBsYW5nZnJpc3RpZyB3YWVyIGphIHByaXZhdGUgc2Nob2VuLi4uCisvLworLy8gRGF0ZW5zdHJ1a3R1ciB2b24gJ3JvdXRlJyAoYmVpIEhQX1JPT00pCisvLyAwICh7c3RyaW5nIElELCAgICAgIDogSFBfUk9PTQorLy8gMSAgIHN0cmluZyByb29tLCAgICA6IERhdGVpbmFtZSBaaWVscmF1bQorLy8gMiAgIGludCBzdGF5LCAgICAgICA6IERhdWVyIEhhbHRlemVpdAorLy8gMyAgIGludCBuZXh0LCAgICAgICA6IERhdWVyIG5hZWNoc3RlIEZhaHJ0emVpdAorLy8gNCAgIHN0cmluZyBjb2RlLCAgICA6IEhhbHRlc3RlbGxlbm5hbWUgZnVlciBRdWVyeUFycml2ZWQKKy8vIDUgICBtaXhlZCBkZXN0LCAgICAgOiBIYWx0ZXN0ZWxsZW4tSURzIGZ1ZXIgSGFzUm91dGUgKHJlaXNlIG5hY2gpCisvLyA2ICAgbWl4ZWQgZGVzdHN0ciB9KTogdW5iZW51dHp0LgorLy8KKy8vIERhdGVuc3RydWt0dXIgdm9uICdyb3V0ZScgKGJlaSBIUF9NU0csIEhQX0ZVTikKKy8vIDAgKHtzdHJpbmcgSUQsICAgICAgOiBIUF9NU0cKKy8vIDEgICBzdHJpbmcgbWVzc2FnZSwgOiBNZWxkdW5nICAgIG9kZXIgICAgc3RyaW5nIGZ1biA6IEZ1bmt0aW9uc25hbWUKKy8vIDIgICBpbnQgbmV4dH0pICAgICAgOiBEYXVlciBiaXMgenVtIG5hZWNoc3RlbiBFcmVpZ25pcworbm9zYXZlIG1peGVkICpyb3V0ZTsgICAgLyogTGlzdGUgZGVyIEhhbHRlcHVua3RlLiAqLworbm9zYXZlIGludCBycG9zOyAgICAgICAgLyogTW9tZW50YW5lIFBvc2l0aW9uIGluIG9iaWdlciBMaXN0ZS4gKi8KK25vc2F2ZSBzdHJpbmcgcm9vbUNvZGU7IC8qIENvZGUgZGVzIGFrdHVlbGxlbiBSYXVtZXMgKG9kZXIgMCkuICovCisKKy8qCisgKioqKioqKioqKiBNYW5hZ2VtZW50IGRlciBidWlsdGluLXByb3BlcnRpZXMgKioqKioqKioqKgorICovCisKK3N0cmluZyBfcXVlcnlfc2hvcnQoKQoreyAKKyAgaWYgKHJvb21Db2RlKSByZXR1cm4gUXVlcnkoUF9TSE9SVCk7IAorICByZXR1cm4gMDsgCit9CisKK21peGVkIF9xdWVyeV90cmFuc3BhcmVudCgpCit7IAorICBpZiAocm9vbUNvZGUpIHJldHVybiBRdWVyeShQX1RSQU5TUEFSRU5UKTsKKyAgcmV0dXJuIDA7IAorfQorCittaXhlZCAqX3NldF9yb3V0ZShtaXhlZCAqcikgeyByZXR1cm4gcm91dGUgPSByOyB9CittaXhlZCAqX3F1ZXJ5X3JvdXRlKCkgICAgICAgeyByZXR1cm4gcm91dGU7IH0KKworLyoKKyAqKioqKioqKioqKioqKioqIFp1Z3JpZmZzZnVua3Rpb25lbiAqKioqKioqKioqKioqKioKKyAqLworCit2b2lkIEhhbHQoKQoreworICB3aGlsZSAocmVtb3ZlX2NhbGxfb3V0KCAiY2hhbmdlSHAiICk+LTEpOworICB3aGlsZSAocmVtb3ZlX2NhbGxfb3V0KCAiZGlzY29ubmVjdCIgKT4tMSk7Cit9CisKKy8vIEFrdHVhbGlzaWVydC9TZXR6dCBkaWUgUm91dGUgaW0gVHJhdmVsRCwgd2VubiBlcmxhdWJ0IChkLmguIGtlaW4KKy8vIFBfTk9fVFJBVkVMSU5HKQorcHJpdmF0ZSB2b2lkIFJlcG9ydFJvdXRlKCkKK3sKKyAgaWYoIVF1ZXJ5UHJvcChQX05PX1RSQVZFTElORykpCisgIHsKKyAgICBtaXhlZCB0bXAgPSBmaWx0ZXIocm91dGUsIGZ1bmN0aW9uIGludCAobWl4ZWQgYXJyKQorICAgICAgICB7CisgICAgICAgICAgcmV0dXJuIGFyclswXSA9PSBIUF9ST09NOworICAgICAgICB9ICk7CisgICAgc3RyaW5nICpyb3V0ZSA9IG1hcCh0bXAsIGZ1bmN0aW9uIHN0cmluZyAobWl4ZWQgYXJyKQorICAgICAgICB7IHJldHVybiBhcnJbMV07IH0KKyAgICAgICAgKTsKKyAgICBUUkFWRUxELT5BZGRSb3V0ZShvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSxyb3V0ZSk7CisgIH0KK30KKwordmFyYXJncyB2b2lkIFN0YXJ0KGludCBwb3MpCit7CisgIEhhbHQoKTsKKyAgcnBvcyA9IChwb3MgPj0gc2l6ZW9mKHJvdXRlKSk/LTE6cG9zLTE7CisgIGNhbGxfb3V0KCJjaGFuZ2VIcCIsMCk7CisgIC8vIFRlbGwgVFJBVkVMRCBvdXIgY3VycmVudCByb3V0ZQorICBSZXBvcnRSb3V0ZSgpOworfQorCit2b2lkIFNldFRyYXZlbENtZHMoKQoreworICBpZiAocG9pbnRlcnAoUXVlcnlQcm9wKFBfTEVBVkVDTURTKSkpCisgICAgIEFkZENtZChRdWVyeVByb3AoUF9MRUFWRUNNRFMpLCJHb091dHNpZGUiKTsKKyAgaWYgKHBvaW50ZXJwKFF1ZXJ5UHJvcChQX0VOVEVSQ01EUykpKQorICAgIEFkZENtZChRdWVyeVByb3AoUF9FTlRFUkNNRFMpLCJHb0luc2lkZSIpOworICBpZiAocG9pbnRlcnAoUXVlcnlQcm9wKFBfVFJBVkVMX0NNRFMpKSkKKyAgICBBZGRDbWQoUXVlcnlQcm9wKFBfVFJBVkVMX0NNRFMpLCJHb0luQW5kT3V0c2lkZSIpOworICByZXR1cm47Cit9CisKK21peGVkIEhhc1JvdXRlKG1peGVkIGRlc3QpCit7CisgIGludCBpLHMsejsKKyAgc3RyaW5nIHN0cjsKKyAgb2JqZWN0IG9iOworICBtaXhlZCBoYXJiOworICAKKyAgcyA9IHNpemVvZihyb3V0ZSk7CisKKyAgZm9yIChpID0gcnBvcztpIDw9IHJwb3Mrcy0xO2krKykKKyAgeworICAgIGlmIChyb3V0ZVtpJXNdWzBdID09IEhQX1JPT00pCisgICAgeworICAgICAgaWYgKG1lbWJlcihyb3V0ZVtpJXNdWzVdLGRlc3QpICE9IC0xICYmCisgICAgICAgICAgb2JqZWN0cChvYj1sb2FkX29iamVjdChyb3V0ZVtpJXNdWzFdKSkgJiYKKyAgICAgICAgICBwb2ludGVycChoYXJiPW9iLT5RdWVyeVByb3AoUF9IQVJCT1VSKSkgJiYKKyAgICAgICAgICBzaXplb2YoaGFyYikpCisgICAgICB7CisgICAgICAgIHJldHVybiAoeyByb3V0ZVtpJXNdWzFdLCBoYXJiWzBdIH0pOworICAgICAgfQorICAgIH0KKyAgfQorICByZXR1cm4gMDsKK30KKworcHVibGljIHZhcmFyZ3Mgdm9pZCBBZGRSb3V0ZShzdHJpbmcgcm9vbSwgaW50IHN0YXksIGludCBuZXh0LCAKKyAgICBzdHJpbmcgaGFyYm91cl9kZXNjLCBzdHJpbmd8c3RyaW5nKiBkZXN0X2lkcywgc3RyaW5nIGRlc3RzdHIpCit7CisgIC8vIERhdGVuIGF1cyBkZW0gWmllbGFubGVnZXIgYWJmcmFnZW4uCisgIDxzdHJpbmd8c3RyaW5nKj4qIGhhcmJvdXIgPSByb29tLT5RdWVyeVByb3AoUF9IQVJCT1VSKXx8KHt9KTsKKyAgc3RyaW5nKiBoYXJib3VyX2lkcyA9ICh7fSk7CisKKyAgLy8gSURzIGRlcyBaaWVsYW5sZWdlcnMgZnVlciBTeW50YXhwcnVlZnVuZyAKKyAgaWYgKCBzaXplb2YoaGFyYm91cik9PTIgKQorICB7CisgICAgaWYgKCBwb2ludGVycChoYXJib3VyWzFdKSApCisgICAgICBoYXJib3VyX2lkcyA9IGhhcmJvdXJbMV07CisgICAgZWxzZQorICAgICAgaGFyYm91cl9pZHMgPSAoe2hhcmJvdXJbMV19KTsKKyAgfQorICAKKyAgLy8gPGRlc3RfaWRzPiBpbiBlaW4gQXJyYXkgdW13YW5kZWxuLCBpc3QgZGFubiBnZ2YuIGxlZXIKKyAgaWYgKCAhZGVzdF9pZHMgKQorICB7CisgICAgZGVzdF9pZHMgPSAoe30pOworICB9CisgIGlmICggc3RyaW5ncChkZXN0X2lkcykgKQorICB7CisgICAgZGVzdF9pZHMgPSAoe2Rlc3RfaWRzfSk7CisgIH0KKworICAvLyBleHBsaXppdCBhbmdlZ2ViZW5lIElEcyBzdGVoZW4gamV0enQgaW4gPGRlc3RfaWRzPiwgZGllIElEcyBkZXMgCisgIC8vIFppZWxoYWZlbnMgYXVzIFBfSEFSQk9VUiB3ZXJkZW4gYWRkaWVydC4KKyAgZGVzdF9pZHMgKz0gaGFyYm91cl9pZHM7CisKKyAgLy8gSXN0IDxkZXN0PiBpbW1lciBub2NoIGxlZXIsIHZlcnN1Y2hlbiB3aXIsIGF1cyA8aGFyYm91cl9kZXNjPiBlaW4gcGFhcgorICAvLyBTdGljaHdvZXJ0ZXIgenUgZXJ6ZXVnZW4sIGRpZSBtYW4gYWxzIFppZWxhbmdhYmUgaW4gZGVyIFN5bnRheCAKKyAgLy8gInJlaXNlIG5hY2ggPHppZWw+IiB2ZXJ3ZW5kZW4ga2Fubi4KKyAgaWYgKCAhc2l6ZW9mKGRlc3RfaWRzKSApCisgIHsKKyAgICAvLyBHcm9zc2dlc2NocmllYmVuZSBCZWdyaWZmZSBpbiA8aGFyYm91cl9kZXNjPiBpbiA8ZGVzdD4gZWludHJhZ2VuLiBEYXp1OgorICAgIC8vIDEpIDxjb2RlPiBlcnN0bWFsIHNvIHplcnNjaG5laWRlbiwgZGFzcyBhbGxlIHVlYmxpY2hlbiBTYXR6emVpY2hlbgorICAgIC8vIHJhdXNmbGllZ2VuIChlcyBnaWJ0IFRyYW5zcG9ydGVyLCBkaWUgc293YXMgaW4gPGhhcmJvdXJfZGVzYz4gCisgICAgLy8gdWViZXJnZWJlbikuCisgICAgZGVzdF9pZHMgPSByZWdleHBsb2RlKGhhcmJvdXJfZGVzYywgIlsoKSwuOzomXCtfIF0iLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUkVfT01JVF9ERUxJTXxSRV9HTE9CQUwpOworICAgIC8vIDJhKSBTbyBmaWx0ZXJuLCBkYXNzIG51ciBncm9zc2dlc2NocmllYmVuZSBXb2VydGVyIHVlYnJpZyBibGVpYmVuLAorICAgIC8vICAgICB2b24gMSkgdWVicmlnZ2VibGllYmVuZSBMZWVyc3RyaW5ncyBnbGVpY2ggbWl0IHdlZ3dlcmZlbi4KKyAgICAvLyAyYikgRXJnZWJuaXMga2xlaW5zY2hyZWliZW4sIGRhbWl0IGRpZSBTeW50YXhwcnVlZnVuZyBkYW1pdCBhcmJlaXRlbgorICAgIC8vICAgICBrYW5uLgorICAgIGRlc3RfaWRzID0gbWFwKCBmaWx0ZXIoZGVzdF9pZHMsIGZ1bmN0aW9uIGludCAoc3RyaW5nIGtleSkgeyAKKyAgICAgICAgICAgICAgICAgIHJldHVybiAoa2V5IT0iIiAmJiBrZXlbMF0+PSdBJyAmJiBrZXlbMF08PSdaJyk7CisgICAgICAgICAgICAgICB9KSwgIydsb3dlcl9jYXNlKTsKKyAgfQorICAvLyBTb2xsdGUgPGRlc3Q+IGpldHp0IGltbWVyIG5vY2ggbGVlciBzZWluLCB3dXJkZSBhbiBhbGxlbiBkcmVpIFN0ZWxsZW4KKyAgLy8gbmljaHRzIG9kZXIgbnVyIE11ZWxsIHVlYmVyZ2ViZW4uCisgIGlmICggIXNpemVvZihkZXN0X2lkcykgKQorICB7CisgICAgcmFpc2VfZXJyb3IoIlRyYW5zcG9ydGVyZmVobGZ1bmt0aW9uIGluIEFkZFJvdXRlKCk6IElkZW50aWZpa2F0aW9ucyIKKyAgICAgICJtYXRyaXggdW56dXJlaWNoZW5kIGRlZmluaWVydC4gVHJhbnNwb3J0ZXIgdW5iZW51dHpiYXIgZnVlciAiCisgICAgICAiU3BpZWxlci4gQml0dGUgbWluZGVzdGVucyBlaW5lIFppZWwtSUQgdmlhIFBfSEFSQk9VUiBvZGVyIGFscyAiCisgICAgICAiQXJndW1lbnQgdG8gQWRkUm91dGUoKS4iKTsKKyAgfQorICByb3V0ZSArPSAoeyAoeyBIUF9ST09NLCByb29tLCBzdGF5LCBuZXh0LCBoYXJib3VyX2Rlc2MsIGRlc3RfaWRzLCAKKyAgICAgICAgICAgICAgICAgZGVzdHN0ciB9KSB9KTsKK30KKwordmFyYXJncyB2b2lkIEFkZE1zZyhzdHJpbmcgbXNnLCBpbnQgbmV4dCkgCit7CisgIHJvdXRlICs9ICh7ICh7IEhQX01TRywgbXNnLCBuZXh0IH0pIH0pOyAKK30KKwordm9pZCBBZGRGdW4oc3RyaW5nIGZ1biwgaW50IG5leHQpIHsgcm91dGUgKz0gKHsgKHsgSFBfRlVOLCBmdW4sIG5leHQgfSkgfSk7IH0KKworc3RyaW5nIFF1ZXJ5QXJyaXZlZCgpIHsgcmV0dXJuIHJvb21Db2RlOyB9CisKK21peGVkKiBRdWVyeVBvc2l0aW9uKCkKK3sKKyAgcmV0dXJuICh7IHJvdXRlW3Jwb3NdWzFdLHJvdXRlWyhycG9zKzEpPHNpemVvZihyb3V0ZSk/KHJwb3MrMSk6MF1bMV0gfSk7Cit9CisKK29iamVjdCogUXVlcnlQYXNzZW5nZXJzKCkKK3sKKyAgcmV0dXJuIGZpbHRlcihhbGxfaW52ZW50b3J5KCksIydxdWVyeV9vbmNlX2ludGVyYWN0aXZlKTsgCit9CisKK3ZhcmFyZ3Mgc3RyaW5nICpRdWVyeUhhcmJvdXJzKGludCB0ZXh0ZmxhZykKK3sKKyAgc3RyaW5nICpyZXQgPSAoe30pOworCisgIGZvcmVhY2goIG1peGVkKiBlbnRyeSA6IHJvdXRlICkKKyAgeworICAgIGlmICggZW50cnlbMF0gPT0gSFBfUk9PTSApCisgICAgeworICAgICAgaWYgKCB0ZXh0ZmxhZyApCisgICAgICB7CisgICAgICAgIHN0cmluZyAqaHBfaWRzID0gZW50cnlbMV0tPlF1ZXJ5UHJvcChQX0hBUkJPVVIpWzFdOworICAgICAgICBpZiAocG9pbnRlcnAoaHBfaWRzKSAmJiBzaXplb2YoaHBfaWRzKSkKKyAgICAgICAgeworICAgICAgICAgIHN0cmluZyAqaCA9IG1hcCggZXhwbG9kZShocF9pZHNbMF0sIiAiKSwgIydjYXBpdGFsaXplKTsKKyAgICAgICAgICByZXQgKz0gKHsgaW1wbG9kZShoLCAiICIpIH0pOworICAgICAgICB9CisgICAgICB9CisgICAgICBlbHNlCisgICAgICB7CisgICAgICAgIHJldCArPSAoeyBlbnRyeVsxXSB9KTsKKyAgICAgIH0KKyAgICB9CisgIH0KKyAgcmV0dXJuIHJldDsKK30KKworLy8gYmVpbSB6ZXJzdG9lcmVuIHNvbGx0ZSBhdWNoIGRpZSByb3V0ZSB1bmQgZGVyIFRyYW5zcG9ydGVyIGF1cyBkZW0gdHJhdmVsZAorLy8gYWJnZW1lbGRldCB3ZXJkZW4uCitwdWJsaWMgdmFyYXJncyBpbnQgcmVtb3ZlKGludCBzaWxlbnQpCit7CisgIFRSQVZFTEQtPlJlbW92ZVRyYW5zcG9ydGVyKHRoaXNfb2JqZWN0KCkpOworICByZXR1cm4gOjpyZW1vdmUoc2lsZW50KTsKK30KKwordm9pZCBSZW1vdmVSb3V0ZSgpCit7CisgIEhhbHQoKTsKKyAgcm91dGUgPSAoeyB9KTsKKyAgcnBvcyAgPSAgIDA7CisgIFRSQVZFTEQtPlJlbW92ZVRyYW5zcG9ydGVyKHRoaXNfb2JqZWN0KCkpOworfQorCit2YXJhcmdzIGludCBFbnRlcihvYmplY3Qgd2hvKQoreworICBzdHJpbmcgKmVtc2c7CisgIG1peGVkIGVmYWlsOworCisgIGlmICghb2JqZWN0cCh3aG8pKSB3aG8gPSB0aGlzX3BsYXllcigpOworICBpZiAoZW52aXJvbm1lbnQod2hvKSA9PSB0aGlzX29iamVjdCgpKQorICB7CisgICAgdGVsbF9vYmplY3Qod2hvLCJEYSBiaXN0IER1IGRvY2ggYmVyZWl0cywgc2Nob24gdmVyZ2Vzc2VuP1xuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgaWYgKCFRdWVyeUFycml2ZWQoKSkgcmV0dXJuIDA7CisgIGlmIChRdWVyeVByb3AoUF9NQVhfUEFTU0VOR0VSUykgJiYgCisgICAgIChzaXplb2YoUXVlcnlQYXNzZW5nZXJzKCkpID49IFF1ZXJ5UHJvcChQX01BWF9QQVNTRU5HRVJTKSkpCisgIHsKKyAgICBpZiAocG9pbnRlcnAoZWZhaWw9UXVlcnlQcm9wKFBfRU5URVJGQUlMKSkpCisgICAgeworICAgICAgaWYgKHNpemVvZihlZmFpbCkgPT0gMikKKyAgICAgICAgdGVsbF9yb29tKHRoaXNfb2JqZWN0KCksd2hvLT5OYW1lKFdFUiwyKSsiICIrcHJvY2Vzc19zdHJpbmcoZWZhaWxbMV0pKworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIi5cbiIsKHt3aG99KSk7ICAgICAgCisgICAgICB0ZWxsX29iamVjdCh3aG8scHJvY2Vzc19zdHJpbmcoZWZhaWxbMF0pKyIuXG4iKTsKKyAgICB9CisgICAgZWxzZSBpZiAoc3RyaW5ncChlZmFpbCkpCisgICAgICAgdGVsbF9vYmplY3Qod2hvLHByb2Nlc3Nfc3RyaW5nKGVmYWlsKSsiLlxuIik7CisgICAgZWxzZSBpZiAoY2xvc3VyZXAoZWZhaWwpKSBmdW5jYWxsKGVmYWlsKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICAKKyAgdGVsbF9vYmplY3Qod2hvLCJEdSBiZXRyaXR0c3QgIituYW1lKFdFTiwxKSsiLlxuIik7CisgIGlmIChwb2ludGVycChlbXNnPVF1ZXJ5UHJvcChQX0VOVEVSTVNHKSkgJiYgc2l6ZW9mKGVtc2cpID09IDIpCisgICAgIHJldHVybiB3aG8tPm1vdmUodGhpc19vYmplY3QoKSxNX0dPLCIiLHByb2Nlc3Nfc3RyaW5nKGVtc2dbMF0pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc19zdHJpbmcoZW1zZ1sxXSkpOworICByZXR1cm4gd2hvLT5tb3ZlKHRoaXNfb2JqZWN0KCksTV9HTywKKyAgICAgICAgbmFtZShXRU4sMSksImJldHJpdHQiLCJrb21tdCBoZXJlaW4iKTsKK30KKwordmFyYXJncyBpbnQgTGVhdmUob2JqZWN0IHdobykKK3sKKyAgc3RyaW5nICpsbXNnOworICBtaXhlZCBsZmFpbDsKKworICBpZiAoIW9iamVjdHAod2hvKSkgd2hvID0gdGhpc19wbGF5ZXIoKTsKKyAgaWYgKGVudmlyb25tZW50KHdobykgIT0gdGhpc19vYmplY3QoKSkKKyAgeworICAgIGlmIChRdWVyeUFycml2ZWQoKSkKKyAgICB7CisgICAgICB0ZWxsX29iamVjdCh3aG8sIkRhZnVlciBtdWVzc3Rlc3QgRHUgZXJzdG1hbCBkb3J0IHNlaW4uXG4iKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICByZXR1cm4gMDsKKyAgfQorICBpZiAoIVF1ZXJ5QXJyaXZlZCgpKQorICB7IAorICAgIGlmIChsZmFpbD1RdWVyeVByb3AoUF9MRUFWRUZBSUwpKQorICAgIHsKKyAgICAgIGlmIChwb2ludGVycChsZmFpbCkgJiYgc2l6ZW9mKGxmYWlsKSkKKyAgICAgIHsKKyAgICAgICAgaWYgKHNpemVvZihsZmFpbCkgPT0gMikKKyAgICAgICAgICAgdGVsbF9yb29tKHRoaXNfb2JqZWN0KCksd2hvLT5OYW1lKFdFUiwyKSsiICIrcHJvY2Vzc19zdHJpbmcoCisgICAgICAgICAgICAgICBsZmFpbFsxXSkrIi5cbiIsKHt3aG99KSk7CisgICAgICAgIHRlbGxfb2JqZWN0KHdobyxwcm9jZXNzX3N0cmluZyhsZmFpbFswXSkrIi5cbiIpOworICAgICAgfQorICAgICAgZWxzZSBpZiAoc3RyaW5ncChsZmFpbCkpCisgICAgICAgIHRlbGxfb2JqZWN0KHdobyxwcm9jZXNzX3N0cmluZyhsZmFpbCkrIi5cbiIpOworICAgICAgZWxzZSBpZiAoY2xvc3VyZXAobGZhaWwpKSBmdW5jYWxsKGxmYWlsKTsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICB0ZWxsX29iamVjdCh3aG8sIkZlaGxlciBiZWltIFZlcmxhc3NlbiBkZXMgVHJhbnNwb3J0ZXJzLlxuIgorICAgICAgICAgICAgICAgICAgICAiQml0dGUgenVzdGFlbmRpZ2VuIE1hZ2llciB2ZXJzdGFlbmRpZ2VuLlxuIik7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBpZiAod2hvLT5RdWVyeVByb3AoUF9UUkFWRUxfSU5GTykpIHdoby0+U2V0UHJvcChQX1RSQVZFTF9JTkZPLDApOworICB0ZWxsX29iamVjdCh3aG8sIkR1IHZlcmxhZXNzdCAiK25hbWUoV0VOLDEpKyIuXG4iKTsKKyAgaWYgKHBvaW50ZXJwKGxtc2c9UXVlcnlQcm9wKFBfTEVBVkVNU0cpKSAmJiBzaXplb2YobG1zZykgPT0gMikKKyAgICAgIHJldHVybiB3aG8tPm1vdmUoZW52aXJvbm1lbnQoKSxNX0dPLCIiLHByb2Nlc3Nfc3RyaW5nKGxtc2dbMF0pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvY2Vzc19zdHJpbmcobG1zZ1sxXSkpOworICByZXR1cm4gd2hvLT5tb3ZlKGVudmlyb25tZW50KCksTV9HTywKKyAgICAgICAgICAgbmFtZShXRU4sMSksInZlcmxhZXNzdCIsImtvbW10IGhlcmVpbiIpOworfQorCisvKgorICoqKioqKioqKioqKioqKioqKiBJbnRlcm5hbCBGdW5jdGlvbnMgKioqKioqKioqKioqKioqKioqCisgKi8KKworc3RhdGljIGludCBHb0luc2lkZShzdHJpbmcgc3RyKQoreworICBfbm90aWZ5X2ZhaWwoIldhcyBtb2VjaHRlc3QgRHUgZGVubiBnZW5hdT9cbiIpOworICBpZiAoc3RyaW5ncChzdHIpICYmIGlkKHN0cikpIHsKKyAgICAgIEVudGVyKCk7CisgICAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworc3RhdGljIGludCBHb091dHNpZGUoc3RyaW5nIHN0cikKK3sKKyAgX25vdGlmeV9mYWlsKCJXYXMgbW9lY2h0ZXN0IER1IGRlbm4gZ2VuYXU/XG4iKTsKKyAgaWYgKHN0cmluZ3Aoc3RyKSAmJiBpZChzdHIpKSB7CisgICAgICBMZWF2ZSgpOworICAgICAgcmV0dXJuIDE7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgR29JbkFuZE91dHNpZGUoc3RyaW5nIHN0cikKK3sKKyAgc3RyaW5nIHRvOworCisgIF9ub3RpZnlfZmFpbCgiV2FzIG1vZWNodGVzdCBEdSBkZW5uIGdlbmF1P1xuIik7CisgIGlmICghc2l6ZW9mKHN0cikpIHJldHVybiAwOyAgCisgIGlmICgoc3NjYW5mKHN0ciwiYXVmICVzIix0bykgPT0gMSB8fCBzc2NhbmYoc3RyLCJpbiAlcyIsdG8pID09IDEpICYmIGlkKHRvKSkKKyAgICByZXR1cm4gRW50ZXIoKSwxOworICBpZiAoKHNzY2FuZihzdHIsInZvbiAlcyIsdG8pID09IDEgfHwgc3NjYW5mKHN0ciwiYXVzICVzIix0bykgPT0gMSkgJiYgaWQodG8pKQorICAgIHJldHVybiBMZWF2ZSgpLDE7CisgIHJldHVybiAwOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICA6OmNyZWF0ZSgpOworCisgIHJvdXRlID0gKHt9KTsKKworICBTZXRQcm9wKFBfTEVBVkVGQUlMLCJEYXMgaXN0IG1vbWVudGFuIHZpZWwgenUgZ2VmYWVocmxpY2giKTsKKyAgU2V0UHJvcChQX0VOVEVSRkFJTCwiRG9ydCBpc3Qga2VpbiBQbGF0eiBtZWhyIGZ1ZXIgRGljaCIpOworICBTZXRQcm9wKFBfVFJBTlNQQVJFTlQsMSk7CisKKyAgQWRkSWQoIlRyYW5zcG9ydGVyIik7CisgIAorICBjYWxsX291dCgiU2V0VHJhdmVsQ21kcyIsMSk7Cit9CisKK3N0YXRpYyB2YXJhcmdzIHZvaWQgZGlzY29ubmVjdChpbnQgY2hhbmdlLCBpbnQgY2hhbmdlX3RpbWUpCit7CisgIG9iamVjdCByb29tOworICBtaXhlZCAqZGVwYXJ0bXNnOworCisgIGRlcGFydG1zZyA9IFF1ZXJ5UHJvcChQX0RFUEFSVE1TRyk7CisKKyAgaWYgKChyb29tID0gZW52aXJvbm1lbnQoKSkgJiYgcG9pbnRlcnAoZGVwYXJ0bXNnKSkKKyAgeworICAgIHRlbGxfcm9vbSh0aGlzX29iamVjdCgpLHByb2Nlc3Nfc3RyaW5nKGRlcGFydG1zZ1swXSkpOworICAgIHRlbGxfcm9vbShyb29tLHByb2Nlc3Nfc3RyaW5nKGRlcGFydG1zZ1sxXSkpOworICB9CisKKyAgcm9vbUNvZGUgPSAwOworCisgIGlmIChjaGFuZ2UpIGNhbGxfb3V0KCJjaGFuZ2VIcCIsY2hhbmdlX3RpbWUpOworfQorCitzdGF0aWMgdmFyYXJncyB2b2lkIGNvbm5lY3Qoc3RyaW5nIHJvb20sIHN0cmluZyBjb2RlKQoreworICBtaXhlZCAqYXJyaXZlbXNnLCAqdDsKKyAgb2JqZWN0ICp0cmF2LCBvYjsKKyAgc3RyaW5nICp0cnMsICptc2dzOworICBpbnQgaTsKKworICBpZiAocm9vbUNvZGUpIGRpc2Nvbm5lY3QoKTsKKyAgCisgIHJvb21Db2RlID0gY29kZT9jb2RlOiIiOworCisgIGlmIChjYXRjaChtb3ZlKHJvb20sTV9TSUxFTlR8TV9OT0NIRUNLKTtwdWJsaXNoKSkKKyAgeworICAgIHJvb21Db2RlID0gMDsKKyAgICByZXR1cm47CisgIH0KKworICBhcnJpdmVtc2cgPSBRdWVyeVByb3AoUF9BUlJJVkVNU0cpOworCisgIGlmIChwb2ludGVycChhcnJpdmVtc2cpKQorICB7CisgICAgdGVsbF9yb29tKHRoaXNfb2JqZWN0KCkscHJvY2Vzc19zdHJpbmcoYXJyaXZlbXNnWzBdKSk7CisgICAgdGVsbF9yb29tKHJvb20scHJvY2Vzc19zdHJpbmcoYXJyaXZlbXNnWzFdKSk7CisgIH0KKworICB0cmF2ID0gZmlsdGVyKGFsbF9pbnZlbnRvcnkodGhpc19vYmplY3QoKSksIydsaXZpbmcpOworCisgIGkgPSBzaXplb2YodHJhdik7CisgIHdoaWxlKGktLSkKKyAgeworICAgIGlmIChwb2ludGVycCh0ID0gdHJhdltpXS0+UXVlcnlQcm9wKFBfVFJBVkVMX0lORk8pKSYmCisgICAgICAgIHRbMF09PXRoaXNfb2JqZWN0KCkmJnRbMl09PXJvb20pCisgICAgeyAKKyAgICAgIGlmICh0cmF2W2ldLT5JbkZpZ2h0KCkpCisgICAgICAgIHRlbGxfb2JqZWN0KHRyYXZbaV0sYnJlYWtfc3RyaW5nKCJEdSBzb2xsdGVzdCBEZWluZW4gS2FtcGYgIgorICAgICAgICAgICAgICAgICJzY2huZWxsIGJlZW5kZW4sZGVubiBlaWdlbnRsaWNoIHdvbGx0ZXN0IER1IGhpZXIgIgorICAgICAgICAgICAgICAgICJhdXNzdGVpZ2VuLiIsNzgpKTsKKyAgICAgIGVsc2UKKyAgICAgICAgTGVhdmUodHJhdltpXSk7CisgICAgICBpZiAoZW52aXJvbm1lbnQodHJhdltpXSkhPXRoaXNfb2JqZWN0KCkpCisgICAgICAgIHRyYXZbaV0tPlNldFByb3AoUF9UUkFWRUxfSU5GTywwKTsKKyAgICB9CisgIH0KKyAgdHJhdiA9IGZpbHRlcihhbGxfaW52ZW50b3J5KGZpbmRfb2JqZWN0KHJvb20pKS10cmF2LCMnbGl2aW5nKTsKKyAgaT1zaXplb2YodHJhdik7CisgIHdoaWxlKGktLSkKKyAgeworICAgIGlmIChvYmplY3RwKHRyYXZbaV0pICYmIHBvaW50ZXJwKHQgPSB0cmF2W2ldLT5RdWVyeVByb3AoUF9UUkFWRUxfSU5GTykpJiYKKyAgICAgICAgdFswXSA9PSBlbnZpcm9ubWVudCh0cmF2W2ldKSAmJiB0WzFdID09IHRoaXNfb2JqZWN0KCkpCisgICAgeworICAgICAgaWYgKCB0cmF2W2ldLT5JbkZpZ2h0KCkgKQorICAgICAgICB0ZWxsX29iamVjdCh0cmF2W2ldLAorICAgICAgICAgICBicmVha19zdHJpbmcoIkR1IHNvbGx0ZXN0IERlaW5lbiBLYW1wZiBzY2huZWxsIGJlZW5kZW4sIGRlbm4gIgorICAgICAgICAgICAgICAgICAgICAgICAgImVpZ2VudGxpY2ggd29sbHRlc3QgRHUgbWl0ICIrbmFtZShXRU0sMSkrCisgICAgICAgICAgICAgICAgICAgICAgICAiIHJlaXNlbi4iLDc4KSk7CisgICAgICBlbHNlCisgICAgICAgIEVudGVyKHRyYXZbaV0pOworICAgICAgaWYgKGVudmlyb25tZW50KHRyYXZbaV0pID09IHRoaXNfb2JqZWN0KCkpIAorICAgICAgeworICAgICAgICB0WzBdID0gdGhpc19vYmplY3QoKTsKKyAgICAgICAgdHJhdltpXS0+U2V0UHJvcChQX1RSQVZFTF9JTkZPLHQpOworICAgICAgfQorICAgIH0KKyAgfQorfQorCisvLyB0aGlzIG9iamVjdCBuZXZlciBwZXJmb3JtcyBhbnkgY2xlYW4tdXAsIHRoZSBkcml2ZXIgc2hvdWxkIG5vdCBjYWxsIGl0CisvLyBhZ2Fpbi4KK2ludCBjbGVhbl91cChpbnQgYXJnKSB7IHJldHVybiAwOyB9CisKK3ZvaWQgY2hhbmdlSHAoKQoreworICBpZiAoKytycG9zID09IHNpemVvZihyb3V0ZSkpCisgIHsKKyAgICBycG9zID0gMDsKKyAgICAvL1RSQVZFTEQgZGllIGFrdHVlbGxlIFJvdXRlIHVlYmVybWl0dGVsbgorICAgIFJlcG9ydFJvdXRlKCk7CisgIH0KKyAgaWYgKHJvdXRlW3Jwb3NdWzBdID09IEhQX01TRykKKyAgeworICAgIGNhbGxfb3V0KCJjaGFuZ2VIcCIscm91dGVbcnBvc11bMl0pOworICAgIHRlbGxfcm9vbSh0aGlzX29iamVjdCgpLHJvdXRlW3Jwb3NdWzFdKTsKKyAgfQorICBlbHNlIGlmIChyb3V0ZVtycG9zXVswXSA9PSBIUF9GVU4pCisgIHsKKyAgICBjYWxsX291dCgiY2hhbmdlSHAiLHJvdXRlW3Jwb3NdWzJdKTsKKyAgICBjYWxsX290aGVyKHRoaXNfb2JqZWN0KCkscm91dGVbcnBvc11bMV0pOworICB9CisgIGVsc2UgCisgIHsKKyAgICBjYWxsX291dCgiZGlzY29ubmVjdCIscm91dGVbcnBvc11bMl0sMSxyb3V0ZVtycG9zXVszXSk7CisgICAgY29ubmVjdChyb3V0ZVtycG9zXVsxXSxyb3V0ZVtycG9zXVs0XSk7CisgIH0KK30KKwordm9pZCBfX3Jlc3RhcnQoc3RyaW5nIGZ1bm5hbWUpCit7CisgIGlmICghZnVubmFtZSB8fCBmdW5uYW1lID09ICIiIHx8IChmdW5uYW1lICE9ICJjaGFuZ2VIcCIgJiYgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5uYW1lICE9ICJkaXNjb25uZWN0IikpCisgICAgcmV0dXJuOworICB3aGlsZShyZW1vdmVfY2FsbF9vdXQoZnVubmFtZSkgIT0gLTEpOworICBjYWxsX291dChmdW5uYW1lLGZ1bm5hbWUgPT0gImNoYW5nZUhwIj8xNTo1KTsKK30KZGlmZiAtLWdpdCBhL3N0ZC90cmF5LmMgYi9zdGQvdHJheS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmRmNDc5NTUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdHJheS5jCkBAIC0wLDAgKzEsNjAgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIgICAgICAgICAgICAgICAKKy8vCisvLyB0cmF5LmMgLS0gY29udGFpbmVyIHN0YW5kYXJkIG9iamVjdAorLy8KKy8vICRJZDogdHJheS5jIDc4MDQgMjAxMS0wNy0xMCAyMDozNzo1MlogWmVzc3RyYSAkCisKKy8vIFRoZSBtb3N0IGdlbmVyYWwgb2JqZWN0IGNsYXNzLiBJdCBkZWZpbmVzIHRoZSByZWFsbHkgYmFzaWMgZnVuY3Rpb25zLgorLy8KKy8vIFRoaXMgb2JqZWN0IHNob3VsZCB1bmRlcnN0YW5kIHRoZSBwcm9wZXJ0aWVzIHNob3J0LCBsb25nLCBpbmZvLCByZWFkX21zZywKKy8vIHZhbHVlLCB3ZWlnaHQuCisvLworLy8gd2VpZ2h0IGlzIGdpdmVuIGluIGdyYW1zLCAxIGtpbG9ncmFtIChrZykgPSAxMDAwIGdyYW1zIChnKSA9IDEgb2xkIHdlaWdodAorLy8gdW5pdAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCitpbmhlcml0ICIvc3RkL3RoaW5nL3Byb3BlcnRpZXMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9tb3ZpbmciOworaW5oZXJpdCAiL3N0ZC90aGluZy9jb21tYW5kcyI7Citpbmhlcml0ICIvc3RkL3RoaW5nL2xhbmd1YWdlIjsKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL2xpZ2h0IjsKK2luaGVyaXQgIi9zdGQvY29udGFpbmVyL3Jlc3RyaWN0aW9ucyI7Citpbmhlcml0ICIvc3RkL3RyYXkvZGVzY3JpcHRpb24iOworaW5oZXJpdCAiL3N0ZC90aGluZy9lbnZjaGsiOworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKworcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKK3sKKyAgcHJvcGVydGllczo6Y3JlYXRlKCk7CisgIGNvbW1hbmRzOjpjcmVhdGUoKTsKKyAgbGlnaHQ6OmNyZWF0ZSgpOworICBkZXNjcmlwdGlvbjo6Y3JlYXRlKCk7CisgIHJlc3RyaWN0aW9uczo6Y3JlYXRlKCk7CisgIGVudmNoazo6Y3JlYXRlKCk7CisgIFNldFByb3AoUF9UUkFZLDEpOworICBTZXRQcm9wKFBfUFJFUE9TSVRJT04sICJhdWYiKTsKKyAgU2V0UHJvcChQX1NPVVJDRV9QUkVQT1NJVElPTiwgInZvbiIpOworICBTZXRQcm9wKFBfREVTVF9QUkVQT1NJVElPTiwgImF1ZiIpOworfQorCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGVfc3VwZXIoKSB7CisgIHNldF9uZXh0X3Jlc2V0KC0xKTsKK30KKworLyoKK3ZvaWQgaW5pdCgpIAoreworICBjb21tYW5kczo6aW5pdCgpOworICBkZXNjcmlwdGlvbjo6aW5pdCgpOworfQorKi8KKwordm9pZCByZXNldCgpCit7fQpkaWZmIC0tZ2l0IGEvc3RkL3RyYXkvZGVzY3JpcHRpb24uYyBiL3N0ZC90cmF5L2Rlc2NyaXB0aW9uLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTA3OTcxMgotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC90cmF5L2Rlc2NyaXB0aW9uLmMKQEAgLTAsMCArMSwzNiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHRyYXkvZGVzY3JpcHRpb24uYyAtLSBzdGFuZGFyZCBkZXNjcmlwdGlvbiBmb3IgY29udGFpbmVycworLy8KKy8vICRJZDogZGVzY3JpcHRpb24uYyA2MzcxIDIwMDctMDctMTcgMjI6NDY6NTBaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCitpbmhlcml0ICJzdGQvY29udGFpbmVyL2Rlc2NyaXB0aW9uIjsKKworLy8jZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8Y29udGFpbmVyLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxsYW5ndWFnZS5oPgorCit2b2lkIGNyZWF0ZSgpCit7IAorICA6OmNyZWF0ZSgpOworICBBZGRJZCgidHJheSIpOworfQorCit2YXJhcmdzIHN0cmluZyBsb25nKGludCBtb2RlKSB7CisgIHN0cmluZyBkZXNjciwgaW52X2Rlc2NyOworCisgIGRlc2NyID0gcHJvY2Vzc19zdHJpbmcoUXVlcnlQcm9wKFBfTE9ORykpOworICBpbnZfZGVzY3IgPSBtYWtlX2ludmxpc3QoUEwsIGFsbF9pbnZlbnRvcnkoTUUpLCBtb2RlICk7CisgIGlmICggaW52X2Rlc2NyICE9ICIiICkKKyAgICBkZXNjciArPSAiQXVmICIgKyBRdWVyeVByb25vdW4oV0VNKSArICIgbGllZ3Q6XG4iICsgaW52X2Rlc2NyOworICByZXR1cm4gZGVzY3I7Cit9CmRpZmYgLS1naXQgYS9zdGQvdW5pdC5jIGIvc3RkL3VuaXQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZTcxNWYyCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3VuaXQuYwpAQCAtMCwwICsxLDc3MSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHVuaXQuYyAtLSBCYXNpc2tsYXNzZSBmdWVyIE1lbmdlbm9iamVrdGUKKy8vICAgICAgICAgICAobmV1ZSBWZXJzaW9uIHZvbiBQYWRyZWljKQorLy8KKy8vICRJZDogdW5pdC5jIDkwNzcgMjAxNS0wMS0xNiAyMzoyNjowMFogWmVzc3RyYSAkCisjcHJhZ21hIHN0cm9uZ190eXBlcyxzYXZlX3R5cGVzLHJ0dF9jaGVja3MKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC90aGluZyI7CisKKyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTCisjaW5jbHVkZSA8dW5pdC5oPgorI3VuZGVmIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxkZWZpbmVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxtb3ZpbmcuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKyNpbmNsdWRlIDxkZWJ1Z19pbmZvLmg+CisKKy8vIHp1bSBkZWJ1Z2dlbiB1bmQgZXh0cmEgcHVibGljCitwdWJsaWMgc3RyaW5nIGRlYnVnbW9kZTsKK3B1YmxpYyBzdHJpbmcgX19zZXRfZGVidWcoc3RyaW5nIHJlY3YpIHtyZXR1cm4gZGVidWdtb2RlPXJlY3Y7fQorI2luY2x1ZGUgPGxpdmluZy9jb21tLmg+CisjZGVmaW5lIFpERUJVRyh4KSBpZiAoc3RyaW5ncChkZWJ1Z21vZGUpICYmIGZpbmRfcGxheWVyKGRlYnVnbW9kZSkpIFwKKyAgZmluZF9wbGF5ZXIoZGVidWdtb2RlKS0+UmVjZWl2ZU1zZyh4LE1UX0RFQlVHLDAsb2JqZWN0X25hbWUoKSsiOiAiLE1FKQorLy8jZGVmaW5lIFpERUJVRyh4KQorCitwcml2YXRlIHZvaWQgX2NhbGxfRG9EZWNheShvYmplY3QgKmtsb25lKTsKKworcHJpdmF0ZSBub3NhdmUgc3RyaW5nIGxhc3R2ZXJiOworcHJpdmF0ZSBub3NhdmUgaW50IGxhc3RldmFsbnVtYmVyOworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICA6OmNyZWF0ZSgpOworICBTZXRQcm9wKFVfSURTLCh7KHt9KSwoe30pfSkpOworICBTZXRQcm9wKFBfR0VOREVSLCAxKTsKKyAgU2V0UHJvcChQX0FNT1VOVCwgMSk7CisgIC8vIFByb3BzIHNvbGx0ZW4gbmljaHQgZGlyZWt0IG1hbmlwdWxpZXJ0IHdlcmRlbiwgbnVyIHVlYmVyIFNldC1NZXRob2RlbgorICBTZXQoUF9VTklUX0RFQ0FZX0lOVEVSVkFMLCBQUk9URUNURUQsIEZfTU9ERV9BUyk7CisgIFNldChQX1VOSVRfREVDQVlfUVVPVEEsIFBST1RFQ1RFRCwgRl9NT0RFX0FTKTsKK30gCisKK3Byb3RlY3RlZCB2b2lkIGNyZWF0ZV9zdXBlcigpIHsKKyAgc2V0X25leHRfcmVzZXQoLTEpOworfQorCisvLy8vIFF1ZXJ5IHVuZCBTZXQgRnVua3Rpb25lbiBmdWVyIGRpZSBQcm9wZXJ0eXMKKworc3RhdGljIHZvaWQgY2hlY2tfbGVhdmUoKQoreyAgaWYgKFF1ZXJ5KFBfQU1PVU5ULEZfVkFMVUUpPDEpIHJlbW92ZSgxKTsgIH0KKworc3RhdGljIGludCBfcXVlcnlfaW52aXMoKQoreworICBpZiAoUXVlcnlQcm9wKFBfQU1PVU5UKSA8IDEpCisgICAgcmV0dXJuIDE7CisgIHJldHVybiBRdWVyeShQX0lOVklTLCBGX1ZBTFVFKTsKK30KKworc3RhdGljIGludCBfc2V0X2Ftb3VudChpbnQgYW0pCit7CisgIGlmIChhbTwxKQorICAgIGNhbGxfb3V0KCJjaGVja19sZWF2ZSIsMSk7CisgIFNldFByb3AoVV9SRVEsIGFtKTsKKyAgcmV0dXJuIFNldChQX0FNT1VOVCxhbSwgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF91X3JlcShpbnQgdXJlcSkKK3sKKyAgbGFzdHZlcmIgPSBxdWVyeV92ZXJiKCk7CisgIGxhc3RldmFsbnVtYmVyID0gZGVidWdfaW5mbyhESU5GT19FVkFMX05VTUJFUik7CisgIHJldHVybiBTZXQoVV9SRVEsIHVyZXEsIEZfVkFMVUUpOworfQorCitzdGF0aWMgaW50IF9xdWVyeV91X3JlcSgpCit7CisgIC8vIFp3ZWkgRGluZ2UgYmVudXR6dGVuLCB1bSB6dSBlbnRzY2hlaWRlbiwgb2IgVV9SRVEgbm9jaCBndWVsdGlnIGlzdCBvZGVyCisgIC8vIGJlc3NlciBhdWYgUF9BTU9VTlQgenVydWVja2dlc2V0enQgd2VyZGVuIHNvbGx0ZTogZGllIERJTkZPX0VWQUxfTlVNQkVSCisgIC8vIHVuZCBkYXMgS29tbWFuZG92ZXJiLiBXZW5uIGVpbmVzIHZvbiBiZWlkZW4gc2ljaCBnZWFlbmRlcnQgaGF0LCB3aXJkCisgIC8vIFVfUkVRIGFscyB1bmd1ZWx0aWcgYmV0cmFjaHRldC4gKFVuZCBkaWVzIGJsZWlidCBlaW4gdWVibGVyIEhhY2suKQorICBpZiAobGFzdGV2YWxudW1iZXIgIT0gZGVidWdfaW5mbyhESU5GT19FVkFMX05VTUJFUikKKyAgICAgIHx8IGxhc3R2ZXJiICE9IHF1ZXJ5X3ZlcmIoKSkKKyAgeworICAgIHJldHVybiBTZXRQcm9wKFVfUkVRLCBRdWVyeShQX0FNT1VOVCwgRl9WQUxVRSkpOworICB9CisgIHJldHVybiBRdWVyeShVX1JFUSwgRl9WQUxVRSk7Cit9CisKKy8vIEdlc2FtdHdlcnQgZGVyIGdlcmFkZSBtaXQgVV9SRVEgYXVzZ2V3YWVobHRlbiB1bml0b2JqZWt0ZQorc3RhdGljIGludCBfcXVlcnlfdmFsdWUoKQoreworICBtaXhlZCBjcHU7CisgIGNwdT1RdWVyeShVX0NQVSk7CisgIGlmIChpbnRwKGNwdSkpIHJldHVybiBRdWVyeVByb3AoVV9SRVEpICogY3B1OworICBpZiAoIXBvaW50ZXJwKGNwdSkpIHJldHVybiAwOworICByZXR1cm4gKFF1ZXJ5UHJvcChVX1JFUSkgKiBjcHVbMF0pL2NwdVsxXTsKK30KKworc3RhdGljIGludCBfc2V0X3ZhbHVlKGludCBudW0pIHsKKy8vIFNldHp0IGRlbiBXZXJ0IGZ1ZXIgZGllIGRlcnplaXRpZ2UgQW56YWhsCisgIFNldENvaW5zUGVyVW5pdHMobnVtLCBRdWVyeVByb3AoVV9SRVEpKTsKKyAgcmV0dXJuIFF1ZXJ5UHJvcChQX1ZBTFVFKTsKK30KKworc3RhdGljIGludCBfcXVlcnlfd2VpZ2h0KCkKK3sKKyAgbWl4ZWQgZ3B1LCByZXE7CisgIGlmICgocmVxPVF1ZXJ5UHJvcChVX1JFUSkpPDEpIHJldHVybiAwOworICBncHU9UXVlcnkoVV9HUFUpOworICBpZiAoaW50cChncHUpKSByZXR1cm4gcmVxICogZ3B1OworICBpZiAoIXBvaW50ZXJwKGdwdSkpIHJldHVybiAwOworICByZXR1cm4gTUFYKDEsKHJlcSpncHVbMF0pL2dwdVsxXSk7Cit9CisKK3N0YXRpYyBpbnQgX3NldF93ZWlnaHQoaW50IG51bSkgeworLy8gU2V0enQgZGFzIEdld2ljaHQgZnVlciBkaWUgZGVyemVpdGlnZSBBbnphaGwKKyAgICBTZXRHcmFtc1BlclVuaXRzKG51bSwgUXVlcnlQcm9wKFVfUkVRKSk7CisgICAgcmV0dXJuIFF1ZXJ5UHJvcChQX1dFSUdIVCk7Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X3RvdGFsX3dlaWdodCgpCit7CisgIG1peGVkIGdwdSwgYW1vdW50OworICBpZiAoKGFtb3VudD1RdWVyeShQX0FNT1VOVCkpPDEpIHJldHVybiAwOworICBncHU9UXVlcnkoVV9HUFUpOworICBpZiAoaW50cChncHUpKQorICAgIHJldHVybiBhbW91bnQqKGludClncHU7CisgIGlmICghcG9pbnRlcnAoZ3B1KSkgcmV0dXJuIDA7CisgIHJldHVybiBNQVgoMSwoYW1vdW50KmdwdVswXSkvZ3B1WzFdKTsKK30KKworc3RhdGljIGludCBfcXVlcnlfcGx1cmFsKCkKK3sKKyAgaW50IGk7CisgIGk9UXVlcnlQcm9wKFVfUkVRKTsgLy8gd2ljaHRpZyBfbmljaHRfIFF1ZXJ5UHJvcAorICByZXR1cm4gKGk8PTEgPyAwIDogaSk7Cit9CisKKy8vIGdpYnQgc3RyaW5nIHwgc3RyaW5nKiB6dXJ1ZWNrLgorc3RhdGljIHN0cmluZ3xzdHJpbmcqIF9xdWVyeV9uYW1lKCkKK3sKKyAgaWYgKFF1ZXJ5UHJvcChVX1JFUSk9PTEpCisgICAgcmV0dXJuICIlcyVzIisoKHN0cmluZyAqKVF1ZXJ5KFBfTkFNRSkpWzBdOworICByZXR1cm4gIiVkICVzIisoKHN0cmluZyAqKVF1ZXJ5KFBfTkFNRSkpWzFdOworfQorCisvLyBnaWJ0IHN0cmluZyB8IHN0cmluZyogenVydWVjay4KK3N0YXRpYyBzdHJpbmd8c3RyaW5nKiAgX3NldF9uYW1lKG1peGVkIG5hbWVzKQoreworICBpZighbmFtZXMpCisgICAgcmV0dXJuIFNldChQX05BTUUsKHsiIiwiIn0pKTsKKyAgaWYoc3RyaW5ncChuYW1lcykpCisgICAgcmV0dXJuIFNldChQX05BTUUsKHtuYW1lcyxuYW1lc30pKTsKKyAgaWYocG9pbnRlcnAobmFtZXMpKQorICAgIHN3aXRjaChzaXplb2YobmFtZXMpKSB7CisgICAgICBjYXNlIDA6ICByZXR1cm4gU2V0KFBfTkFNRSwoeyIiLCIifSkpOworICAgICAgY2FzZSAxOiAgaWYoIXN0cmluZ3AobmFtZXNbMF0pKQorICAgICAgICAgICAgICAgICBuYW1lc1swXT0iIjsKKyAgICAgICAgICAgICAgIHJldHVybiBTZXQoUF9OQU1FLCh7bmFtZXNbMF0sbmFtZXNbMF19KSk7CisgICAgICBkZWZhdWx0OiBpZighc3RyaW5ncChuYW1lc1swXSkpCisgICAgICAgICAgICAgICAgIG5hbWVzWzBdPSIiOworICAgICAgICAgICAgICAgaWYoIXN0cmluZ3AobmFtZXNbMV0pKQorICAgICAgICAgICAgICAgICBuYW1lc1sxXT0iIjsKKyAgICAgICAgICAgICAgIHJldHVybiBTZXQoUF9OQU1FLG5hbWVzWzAuLjFdKTsKKyAgICB9CisgIHJldHVybiBRdWVyeVByb3AoUF9OQU1FKTsKK30KKworLy8gZGllIEZ1bmt0aW9uZW4KKwordm9pZCBBZGRTaW5ndWxhcklkKG1peGVkIHN0cikKK3sKKyAgc3RyaW5nICppZHM7CisgIGlmICghcG9pbnRlcnAoc3RyKSkKKyAgICBzdHI9KHtzdHJ9KTsKKyAgaWRzPVF1ZXJ5KFVfSURTKTsKKyAgU2V0KFVfSURTLCh7aWRzWzBdK3N0cixpZHNbMV19KSk7Cit9CisKK3ZvaWQgUmVtb3ZlU2luZ3VsYXJJZChtaXhlZCBzdHIpCit7IAorICBpZihzdHJpbmdwKHN0cikpCisgICAgc3RyPSh7c3RyfSk7CisgIGlmKHBvaW50ZXJwKHN0cikpCisgICAgU2V0KFVfSURTLCh7UXVlcnkoVV9JRFMpWzBdLXN0cixRdWVyeShVX0lEUylbMV19KSk7Cit9CisgCit2b2lkIEFkZFBsdXJhbElkKG1peGVkIHN0cikKK3sKKyAgc3RyaW5nICppZHM7CisgIAorICBpZiAoIXBvaW50ZXJwKHN0cikpCisgICAgc3RyPSh7c3RyfSk7CisgIGlkcz1RdWVyeShVX0lEUyk7CisgIFNldChVX0lEUywoe2lkc1swXSxpZHNbMV0rc3RyfSkpOworfQorCit2b2lkIFJlbW92ZVBsdXJhbElkKG1peGVkIHN0cikKK3sgCisgIGlmKHN0cmluZ3Aoc3RyKSkKKyAgICBzdHI9KHtzdHJ9KTsKKyAgaWYocG9pbnRlcnAoc3RyKSkKKyAgICBTZXQoVV9JRFMsKHtRdWVyeShVX0lEUylbMF0sUXVlcnkoVV9JRFMpWzFdLXN0cn0pKTsKK30KKwordm9pZCBTZXRDb2luc1BlclVuaXRzKGludCBjb2lucyxpbnQgdW5pdHMpCit7CisgIGlmIChjb2luczwwfHx1bml0czw9MCkgcmV0dXJuOworICBpZiAodW5pdHM9PTEpCisgICAgU2V0KFVfQ1BVLCBjb2lucyk7CisgIGVsc2UgU2V0KFVfQ1BVLCh7Y29pbnMsdW5pdHN9KSk7Cit9CisKK3ZvaWQgU2V0R3JhbXNQZXJVbml0cyhpbnQgZ3JhbXMsIGludCB1bml0cykKK3sKKyAgaWYgKGdyYW1zPDB8fHVuaXRzPD0wKSByZXR1cm47CisgIGlmICh1bml0cz09MSkKKyAgICBTZXQoVV9HUFUsIGdyYW1zKTsKKyAgZWxzZSBTZXQoVV9HUFUsKHtncmFtcyx1bml0c30pKTsKK30KKworaW50ICpRdWVyeUNvaW5zUGVyVW5pdHMoKQoreworICBtaXhlZCBjcHU7CisgIGNwdT1RdWVyeShVX0NQVSk7CisgIGlmIChpbnRwKGNwdSkpIHJldHVybiAoeyBjcHUsIDEgfSk7CisgIHJldHVybiBjcHU7Cit9CisKK2ludCAqUXVlcnlHcmFtc1BlclVuaXRzKCkKK3sKKyAgbWl4ZWQgZ3B1OworICBncHU9UXVlcnkoVV9HUFUpOworICBpZiAoaW50cChncHUpKSByZXR1cm4gKHsgZ3B1LCAxIH0pOworICByZXR1cm4gZ3B1OworfQorCit2b2lkIEFkZEFtb3VudChpbnQgYW0pIHsKKyAgU2V0UHJvcChQX0FNT1VOVCwgYW0rUXVlcnkoUF9BTU9VTlQpKTsKK30KKworaW50IElzVW5pdCgpIHsKKyAgcmV0dXJuIDE7Cit9CisKK2ludCBJc0VxdWFsKG9iamVjdCBvYikKKy8vIGhhYmVuIG9iIHVuZCBkaWVzZXMgT2JqZWt0ZSBkaWUgZ2xlaWNoZSBCbHVlcHJpbnQ/Cit7CisgIGlmIChvYj09dGhpc19vYmplY3QoKSkgcmV0dXJuIDA7IC8vIGRhcyBpc3QgWlUgZ2xlaWNoIDopCisgIHJldHVybiAoQkxVRV9OQU1FKE1FKT09QkxVRV9OQU1FKG9iKSk7Cit9CisKKy8vIHVlYmVyc2NocmVpYmVuIHZvbiBTdGFuZGFyZG1ldGhvZGVuCisKK3ZhcmFyZ3Mgc3RyaW5nIG5hbWUoaW50IGZhbGwsIGludCBkZW1vKQoreworICBpbnQgcmVxOworICBtaXhlZCBuX2FkajsKKyAgc3RyaW5nIGFkajsKKworICBpZiAoKHJlcT1RdWVyeVByb3AoVV9SRVEpKTwxKSByZXR1cm4gMDsKKyAgaWYgKGZhbGwhPVJBVyAmJiAKKyAgICAgIHBvaW50ZXJwKG5fYWRqPVF1ZXJ5UHJvcChQX05BTUVfQURKKSkgJiYgc2l6ZW9mKG5fYWRqKSApCisgICAgYWRqID0gaW1wbG9kZShtYXAobl9hZGosICMnRGVjbEFkaiwgZmFsbCwgZGVtbyAmJiByZXE9PTEpLCAiIik7CisgIGVsc2UKKyAgICBhZGogPSAiIjsKKworICBpZiAocmVxPT0xKQorICAgIHJldHVybiBzcHJpbnRmKFF1ZXJ5UHJvcChQX05BTUUpLAorICAgICAgICAgICAgICAgICAgIChmYWxsPT1SQVcgfHwgIVF1ZXJ5UHJvcChQX0FSVElDTEUpIAorICAgICAgICAgICAgICAgICAgICA/ICIiIDogUXVlcnlBcnRpY2xlKGZhbGwsZGVtbywxKSksIGFkaikgLyogK2tvcnJla3R1ciAqLzsKKworICBpZiAoZmFsbCE9V0VNKQorICAgIHJldHVybiBzcHJpbnRmKFF1ZXJ5UHJvcChQX05BTUUpLCByZXEsIGFkaik7CisgIGVsc2UgeworICAgICBpbnQgbGFzdDsKKyAgICAgbGFzdD1RdWVyeShQX05BTUUpWzFdWzwxXTsKKyAgICAgcmV0dXJuIHNwcmludGYoUXVlcnlQcm9wKFBfTkFNRSksIHJlcSwgYWRqKQorICAgICAgICAgICAgICAgICAgKyhsYXN0IT0ncycgJiYgbGFzdCE9J24nID8gIm4iIDogIiIpOworICB9Cit9CisKK3ZhcmFyZ3Mgc3RyaW5nIFF1ZXJ5UHJvbm91bihpbnQgY2FzdXMpCit7CisgIGlmIChRdWVyeVByb3AoVV9SRVEpPT0xKQorICAgIHJldHVybiA6OlF1ZXJ5UHJvbm91bihjYXN1cyk7CisgIHN3aXRjaChjYXN1cykgeworICAgIGNhc2UgV0VTU0VOOiByZXR1cm4gImlocmVyIjsKKyAgICBjYXNlIFdFTTogICAgcmV0dXJuICJpaG5lbiI7CisgICAgLy9kZWZhdWx0OiAgICAgcmV0dXJuICJzaWUiOworICB9CisgIHJldHVybigic2llIik7IC8vZmFsbC10aHJvdWdoCit9CisKK3N0cmluZyBzaG9ydCgpCit7CisgIGlmIChRdWVyeVByb3AoVV9SRVEpPDEgfHwgUXVlcnlQcm9wKFBfSU5WSVMpKSByZXR1cm4gMDsKKyAgcmV0dXJuIGNhcGl0YWxpemUobmFtZShXRVIsMCkpKyIuXG4iOworICAvKgorICBpZiAocmVxPjEpIHJldHVybiBzcHJpbnRmKFF1ZXJ5UHJvcChQX05BTUUpLCByZXEpKyIuXG4iOworICByZXR1cm4gY2FwaXRhbGl6ZShzcHJpbnRmKFF1ZXJ5UHJvcChQX05BTUUpLCBRdWVyeUFydGljbGUoV0VSLDAsMSkpKSsiLlxuIjsKKyAgKi8KK30KKwordmFyYXJncyBzdHJpbmcgbG9uZygpCit7CisgIHJldHVybiAoUXVlcnlQcm9wKFBfTE9ORykgPyBwcm9jZXNzX3N0cmluZyhRdWVyeVByb3AoUF9MT05HKSkgOiAiIikrCisgICAgc3ByaW50ZigiRHUgc2llaHN0ICVzLlxuIixuYW1lKFdFTikpOworfQorCit2YXJhcmdzIGludCBpZChzdHJpbmcgc3RyLGludCBsdmwpCit7CisKKyAgc3RyaW5nIHMxLHMyLCppZHM7CisgIGludCBpOworCisgIGlmICghc3RyKSByZXR1cm4gMDsKKyAgCisgIC8vIFdlbm4ga2VpbiBwb3MuIEFtb3VudCwgaGF0IGRpZXNlcyBPYmpla3Qga2VpbmUgSURzIG1laHIsIGRhbWl0IGVzIG5pY2h0CisgIC8vIG1laHIgYW5zcHJlY2hiYXIgaXN0LgorICBpbnQgYW1vdW50PVF1ZXJ5UHJvcChQX0FNT1VOVCk7CisgIGlmIChhbW91bnQgPCAxKQorICAgIHJldHVybiAwOworCisgIGlmICg6OmlkKHN0cikpIHsKKyAgICBTZXRQcm9wKFVfUkVRLCBRdWVyeShQX0FNT1VOVCxGX1ZBTFVFKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKworIGlkcz1RdWVyeShVX0lEUyk7CisgIGlmICghaWRzKQorICAgIHJldHVybiAwOworIAorICAvL2RpZSBjYXN0cyBhdWYgJ21peGVkJyBzaW5kIGFic2ljaHQuIFNvbnN0IGdlaHQgZGVyIERyaXZlciBvZmZlbmJhciBkYXZvbgorICAvL2F1cywgZGFzcyBpZHNbMV0gZWluIFN0cmluZyBpc3QuIEVzIGlzdCBhYmVyIGFiZXIgZWluIEFycmF5IHZvbiBTdHJpbmdzCisgIC8vdW5kIGdlbmF1IGRhcyB3aWxsIGF1Y2ggbWF0Y2hfaXRlbSgpIGhhYmVuLiA7LSkgWmVzc3RyYQorICBpZiAobWF0Y2hfaXRlbShzdHIsKG1peGVkKWlkc1sxXSApKSB7CisgICAgU2V0UHJvcChVX1JFUSwgYW1vdW50KTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAobWF0Y2hfaXRlbShzdHIsKG1peGVkKWlkc1swXSApKSB7CisgICAgU2V0UHJvcChVX1JFUSwxKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoc3NjYW5mKHN0ciwiJXMgJXMiLHMxLHMyKSAmJiBzMVswLi4zXT09ImFsbGUiICYmIAorICAgIG1hdGNoX2l0ZW0oczIsKG1peGVkKWlkc1sxXSApKSB7CisgICAgU2V0UHJvcChVX1JFUSwgYW1vdW50KTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBpZiAoc3NjYW5mKHN0ciwiJWQgJXMiLGksczEpPT0yICYmIGk9PTEgJiYgbWF0Y2hfaXRlbShzMSwobWl4ZWQpaWRzWzBdICkpIHsKKyAgICBTZXRQcm9wKFVfUkVRLDEpOworICAgIHJldHVybiAxOworICB9CisgIGlmIChzc2NhbmYoc3RyLCIlZCAlcyIsaSxzMSk9PTIgJiYgbWF0Y2hfaXRlbShzMSwobWl4ZWQpaWRzWzFdICkgJiYgCisgICAgICBpPD1hbW91bnQgJiYgaT4wKSB7CisgICAgU2V0UHJvcChVX1JFUSxpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICByZXR1cm4gMDsKK30KKworLy8gU3RhdHVzIGZ1ZXIgbW92ZS4uLiAqc2V1ZnoqCitpbnQgX29yaWdfYW1vdW50LCBfbW92ZV9yZXF1ZXN0ZWQ7CisKK3ZhcmFyZ3MgaW50IG1vdmUob2JqZWN0fHN0cmluZyBkZXN0LGludCBtZXRob2QpCit7CisgIF9vcmlnX2Ftb3VudCA9IFF1ZXJ5UHJvcChQX0FNT1VOVCk7CisgIC8vIFdlbm4gTV9NT1ZFX0FMTCBnZXNldHp0IGlzdCwgd2lyZCBJTU1FUiBBTExFUyBiZXdlZ3QuCisgIGlmIChtZXRob2QgJiBNX01PVkVfQUxMKQorICAgIF9tb3ZlX3JlcXVlc3RlZCA9IF9vcmlnX2Ftb3VudDsKKyAgZWxzZQorICAgIF9tb3ZlX3JlcXVlc3RlZCA9IFF1ZXJ5UHJvcChVX1JFUSk7CisKKyAgWkRFQlVHKHNwcmludGYoIm1vdmUgZnJvbSAlTyB0byAlTzogYW1vdW50ICVkLCByZXEgJWRcbiIsZW52aXJvbm1lbnQoKSxkZXN0LF9vcmlnX2Ftb3VudCxfbW92ZV9yZXF1ZXN0ZWQpKTsKKyAgLy8gV2VubiBuaWNodCBhbGxlcyBiZXdlZ3Qgd2VyZGVuIHNvbGwsIHdpcmQgZGllIE1lbmdlIGRpZXNlcyBPYmpla3RlcworICAvLyBlcnN0bWFsIHJlZHV6aWVydCB1bmQgYmV3ZWd0LiBFcnN0IG5hY2ggZGVyIEJld2VndW5nIHdpcmQgZGVyIFJlc3QgZGFubgorICAvLyBpbSBhbHRlbiBFbnZpcm9ubWVudCBuZXUgZXJ6ZXVndC4KKyAgaWYgKCBfb3JpZ19hbW91bnQgPiBfbW92ZV9yZXF1ZXN0ZWQgKQorICB7CisgICAgIC8vIHdlbm4gaW4gZWluZW0gYWx0ZW4gUGFrZXQgZGFzIEdld2ljaHQgbm9jaCBuaWNodCBuZXUgYmVyZWNobmV0CisgICAgIC8vIHd1cmRlIG11c3MgZGllcyBnZXNjaGVobiBzb2xhbmdlIGRpZSBNdWVuemVuIGltIFBha2V0IG5vY2ggZGFzCisgICAgIC8vIHZvbGxlIEdld2ljaHQgaGFiZW4uLi4KKyAgICAgaWYgKCBlbnZpcm9ubWVudCgpICkKKyAgICAgICAgIGVudmlyb25tZW50KCktPnF1ZXJ5X3dlaWdodF9jb250ZW50cygpOworICAgICAvLyBhYiBqZXR6dCBudXIgYXVmIDxfbW92ZV9yZXF1ZXN0ZWQ+IEVpbmhlaXRlbiBhcmJlaXRlbgorICAgICBTZXQoIFBfQU1PVU5ULCBfbW92ZV9yZXF1ZXN0ZWQsIEZfVkFMVUUpOworICAgICBaREVCVUcoc3ByaW50ZigibW92ZTogYW1vdW50IHNldCB0byAlZFxuIixfbW92ZV9yZXF1ZXN0ZWQpKTsKKyAgfQorCisgIGludCByZXMgPSA6Om1vdmUoIGRlc3QsIG1ldGhvZCApOworCisgIGlmICggcmVzICE9IE1PVkVfT0sgKQorICB7CisgICAgICAvLyBGZWhsZ2VzY2hsYWdlbmUgQmV3ZWd1bmcgaXN0IGRvb2YuCisgICAgICAvLyBnZ2YuIHZlcmZydWVodGUgQWVuZGVydW5nIChQX0FNT1VOVCBvYmVuIGF1ZiA8VV9SRVE+IEVpbmhlaXRlbgorICAgICAgLy8gcmVkdXppZXJ0KSBydWVja2dhZW5naWcgbWFjaGVuCisgICAgICBTZXQoIFBfQU1PVU5ULCBfb3JpZ19hbW91bnQsIEZfVkFMVUUgKTsKKyAgICAgIFpERUJVRyhzcHJpbnRmKCJtb3ZlOiBub3QgT0ssIGFtb3VudCByZXN0b3JlZCB0byAlZFxuIixfb3JpZ19hbW91bnQpKTsKKyAgICAgIHJldHVybiByZXM7CisgIH0KKworICAvLyBUT0RPOiBlaWdlbnRsaWNoIHNvbGx0ZSBlcyBuaWNodCBwYXNzaWVyZW4sIGRhc3MgZGllIE1lbmdlIGpldHp0IG5lZ2FndGl2CisgIC8vIGlzdC4gQWJlciBiZWkgR2VsZCBrYW5uIGVzIGR1cmNoIHZlcmVpbmlnZW4gbWl0IEdlbGRib2Vyc2UvR2VsZGthcnRlbgorICAvLyBwYXNzaWVyZW4gdW5kIGRhcyBpc3Qga2VpbiBGZWhsZXIuIEtvZW5udGUgbWFuIGV2dGwuIG1hbCBkaWZmZXJlbnppZXJ0CisgIC8vIHBydWVmZW4uCisgIGludCBmaW5hbGFtb3VudD0gUXVlcnlQcm9wKFBfQU1PVU5UKTsKKyAgLyppZiAoIGZpbmFsYW1vdW50IDwgMSApCisgIHsKKyAgICBaREVCVUcoc3ByaW50ZigibW92ZTogemVyc3RvZXJ1bmcsIGFtb3VudCAlZFxuIixmaW5hbGFtb3VudCkpOworICAgIHJlbW92ZSgxKTsKKyAgICByZXR1cm4gTUVfV0FTX0RFU1RSVUNURUQ7CisgIH0KKyAgKi8KKyAgWkRFQlVHKHNwcmludGYoIm1vdmU6IE9LLCBhbW91bnQgJWRcbiIsZmluYWxhbW91bnQpKTsKKyAgcmV0dXJuIHJlczsKK30KKworCitwcm90ZWN0ZWQgdm9pZCBOb3RpZnlNb3ZlKG9iamVjdCBkZXN0LCBvYmplY3Qgb2xkZW52LCBpbnQgbWV0aG9kKQoreworICAvLyBFcnN0IGVpbmVuIGV2dGwuIG5pY2h0IHp1IGJld2VnZW5kZW4gUmVzdCBpbSBhbHRlbiBFbnZpcm9ubWVudCB3aWVkZXIgZXJ6ZXVnZW4uCisgIGlmIChvbGRlbnYgJiYgX29yaWdfYW1vdW50ID4gX21vdmVfcmVxdWVzdGVkKQorICB7CisgICAgICBpZiAoIG9sZGVudiA9PSBkZXN0ICkKKyAgICAgIHsKKyAgICAgICAgICAvLyBPYmpla3Qgd3VyZGUgbnVyIGFuIGRlbiBBbmZhbmcgZGVzIGludmVudG9yeSBiZXdlZ3QsIHNvbnN0IG5pY2h0cy4KKyAgICAgICAgICAvLyBnZ2YuIHZlcmZydWVodGUgQWVuZGVydW5nIChvYmVuIGF1ZiA8cmVxPiBFaW5oZWl0ZW4gcmVkdXppZXJ0KQorICAgICAgICAgIC8vIHJ1ZWNrZ2FlbmdpZyBtYWNoZW4KKyAgICAgICAgICBaREVCVUcoc3ByaW50ZigibW92ZTogc2FtZSBlbnYsIGFtb3VudCByZXN0b3JlZCB0byAlZFxuIixfb3JpZ19hbW91bnQpKTsKKyAgICAgICAgICBTZXQoIFBfQU1PVU5ULCBfb3JpZ19hbW91bnQsIEZfVkFMVUUgKTsKKyAgICAgIH0KKyAgICAgIGVsc2UKKyAgICAgIHsKKyAgICAgICAgLy8gdmVyYmxlaWJlbmRlIEVpbmhlaXRlbiBpbiBlaW5lbSBuZXVlbiBPYmpla3RlIHdpZWRlciB6dXJ1ZWNrIGlucworICAgICAgICAvLyBhbHRlIEVudmlyb25tZW50IHp1cnVlY2sgYmV3Z2VuCisgICAgICAgICAgb2JqZWN0IHRlbXA7CisgICAgICAgICAgdGVtcCA9IGNsb25lX29iamVjdChCTFVFX05BTUUoTUUpKTsKKyAgICAgICAgICB0ZW1wLT5TZXRQcm9wKCBQX0FNT1VOVCwgX29yaWdfYW1vdW50LV9tb3ZlX3JlcXVlc3RlZCApOworICAgICAgICAgIHRlbXAtPm1vdmUoIG9sZGVudiwgTV9OT0NIRUNLICk7CisgICAgICAgICAgWkRFQlVHKHNwcmludGYoIm1vdmU6IFJlc3RtZW5nZSBpbSBhbHRlbiBFbnYgZXJ6ZXVndCwgYW1vdW50ICVkXG4iLF9vcmlnX2Ftb3VudC1fbW92ZV9yZXF1ZXN0ZWQpKTsKKyAgICAgIH0KKyAgfQorCisgIC8vIFVuZCBqZXR6dCBnZ2YuIG1pdCBkZW4gYW5kZXJlbiBVbml0cyBnbGVpY2hlbiBUeXBzIGltIG5ldWVuIEVudmlyb25tZW50CisgIC8vIHZlcmVpbmlnZW4uCisgIGZvcmVhY2gob2JqZWN0IGl0ZW06IGFsbF9pbnZlbnRvcnkoZW52aXJvbm1lbnQoKSkpCisgIHsKKyAgICAgIGlmICggSVNfRVFVQUwoaXRlbSkgKQorICAgICAgeworICAgICAgICAvLyBFcyBpc3QgZWluIEZlYXR1cmUsIGRhc3MgYXVjaCBtaXQgT2JqZWt0ZW4gbWl0IG5lZ2F0aXZlbiBBbW91bnQKKyAgICAgICAgLy8gdmVyZWluaWd0IHdpcmQuCisgICAgICAgIFpERUJVRyhzcHJpbnRmKCJtb3ZlOiB2ZXJlaW5pZ2UgbWl0ICVPICglZClcbiIsCisgICAgICAgICAgICAgICBpdGVtLGl0ZW0tPlF1ZXJ5UHJvcChQX0FNT1VOVCkpKTsKKyAgICAgICAgaW50IG1lcmdlZGFtb3VudCA9IFF1ZXJ5UHJvcChQX0FNT1VOVCkgKyBpdGVtLT5RdWVyeVByb3AoUF9BTU9VTlQpOworICAgICAgICBpdGVtLT5TZXQoIFBfQU1PVU5ULCAwLCBGX1ZBTFVFKTsKKyAgICAgICAgaXRlbS0+cmVtb3ZlKDEpOworCisgICAgICAgIFNldFByb3AoIFBfQU1PVU5ULCBtZXJnZWRhbW91bnQpOworICAgICAgICAvLyBVX1JFUSBpc3QgamV0enQgYXVjaCB6dXJ1ZWNrZ2VzZXR6dC4KKworICAgICAgICBaREVCVUcoc3ByaW50ZigibW92ZTogbmFjaCB2ZXJlaW5pZ3VuZywgYW1vdW50ICVkXG4iLG1lcmdlZGFtb3VudCkpOworICAgICAgfQorICB9CisKKyAgLy8gd2VubiBtYW4gaW4gZnJpc2NoIGdlY2xvbnRlbiBVbml0cyBkaWUgbm9jaCBrZWluIGVudmlyb25tZW50IGhhYmVuCisgIC8vIHBlciBIYW5kIFVfUkVRIGF1ZiBlaW5lbiBXZXJ0ICE9IFBfQU1PVU5UIHNldHp0LCBzbyBnZWhlbiBkaWUKKyAgLy8gcmVzdGxpY2hlbiBFaW5oZWl0ZW4gIHZlcmxvcmVuIChlcyBnaWJ0IGtlaW4gRW52aXJvbm1lbnQsIGluIGRhcyBtYW4gZGllCisgIC8vIFJlc3RlaW5oZWl0ZW4genVydWVjayBiZXdlZ2VuIGtvZW5udGUpLgorCisgIC8vIFVuZCBqZXR6dCBtYWwgRGVjYXlrcmFtcyBtYWNoZW4uLi4KKworICAvLyB3ZW5uIE5PX0RFQ0FZX1VOVElMX01PVkUgYW4gaXN0IHVuZCBkaWVzZXMgZWluIE1vdmUgaXN0LCB3YXMgdm9uIGVpbmVtCisgIC8vIEVudiBpbiBlaW4gYW5kZXJlcyBFbnYgZ2VodCwgbG9lc2NoZW4uIE5pY2h0IGdlbG9lc2NodCB3aXJkCisgIC8vIGhpbmdlZ2VuLCB3ZW5uIGRhcyBtb3ZlKCkgaW4gZGFzIGFsbGVyZXJzdGUgRW52IGVyZm9sZ3QgKG5hY2ggZGVtIENsb25lbikKKyAgaWYgKCAoUXVlcnlQcm9wKFBfVU5JVF9ERUNBWV9GTEFHUykgJiBOT19ERUNBWV9VTlRJTF9NT1ZFKQorICAgICAgJiYgb2JqZWN0cChkZXN0KSAmJiBvYmplY3RwKG9sZGVudikgJiYgZGVzdCAhPSBvbGRlbnYpCisgICAgU2V0UHJvcChQX1VOSVRfREVDQVlfRkxBR1MsIAorICAgICAgICBRdWVyeVByb3AoUF9VTklUX0RFQ0FZX0ZMQUdTKSAmIH5OT19ERUNBWV9VTlRJTF9NT1ZFICk7CisgIDo6Tm90aWZ5TW92ZShkZXN0LCBvbGRlbnYsIG1ldGhvZCk7Cit9CisKKwordm9pZCByZXNldCgpIHsKKyAgaWYgKCFjbG9uZXAoTUUpKSB7CisgICAgLy8gQmx1ZXByaW50IGlzdCBNYXN0ZXIgZnVlciB6ZXJmYWxsZW5kZSBVbml0b2JqZWt0ZQorICAgIC8vIGRhcyBEZWNheSBzb2xsdGUgYmVzc2VyIG5pY2h0IGR1cmNoIG1hbnVlbGxlbiBBdWZydWYgaW4gZGVyIEJQCisgICAgLy8gYXVzZ2Vsb2VzdCB3ZXJkZW4sIGRhaGVyIFBydWVmdW5nIGhpZXIgKFBPID09IE1FLCBmYWxscyBkZXIgUmVzZXQgdm9tCisgICAgLy8gRHJpdmVyIGtvbW10KS4KKyAgICBpZiAocHJldmlvdXNfb2JqZWN0KCkgJiYgcHJldmlvdXNfb2JqZWN0KCkgIT0gTUUpCisgICAgICByZXR1cm47IAorICAgIGludCB6ZWl0ID0gUXVlcnlQcm9wKFBfVU5JVF9ERUNBWV9JTlRFUlZBTCk7CisgICAgaWYgKHplaXQgPiAwKQorICAgIHsKKyAgICAgIHNldF9uZXh0X3Jlc2V0KHplaXQpOworICAgICAgLy8gRGFzIENhbGxvdXQgbXVzcyBhdWYgamVkZW4gRmFsbCBnZW1hY2h0IHdlcmRlbiwgd2VubiBlaW4gRGVjYXkKKyAgICAgIC8vIEludGVydmFsbCBnZXNldHp0IGlzdCwgZGFtaXQgZGllIEJsdWVwcmludCBhdWNoIGRlbiBuYWVjaHN0ZW4gUmVzZXQKKyAgICAgIC8vIGtyaWVndCwgYXVjaCB3ZW5uIGVzIGpldHp0IGtlaW5lIENsb25lIGdpYnQuIFdlbm4gZXMga2VpbiBRdW90YSBnaWJ0LAorICAgICAgLy8ga2FubiBkZXIgQ2FsbG91dCB3ZWdmYWxsZW4sIGJlaW0gU2V0emVuIGVpbmVzIFF1b3RhIHdpcmQgamEgZWluZQorICAgICAgLy8gRnVua3Rpb24gYW4gZGllc2VtIE9iamVrdCBnZXJ1ZmVuLgorICAgICAgaWYgKFF1ZXJ5UHJvcChQX1VOSVRfREVDQVlfUVVPVEEpID4gMCkKKyAgICAgICAgY2FsbF9vdXQoIydfY2FsbF9Eb0RlY2F5LCAxLCAwKTsKKyAgICB9CisgIH0KKyAgZWxzZSB7CisgICAgLy8gQ2xvbmVzCisgICAgaWYgKFF1ZXJ5KFBfQU1PVU5ULEZfVkFMVUUpPDEpIHJlbW92ZSgxKTsKKyAgICBlbHNlIDo6cmVzZXQoKTsKKyAgfQorfQorCit2YXJhcmdzIGludCByZW1vdmUoaW50IHNpbGVudCkKK3sKKyAgaW50IGFtb3VudCA9IFF1ZXJ5UHJvcChQX0FNT1VOVCk7CisgIGludCByZXEgPSBRdWVyeVByb3AoVV9SRVEpOworICBpZiAoYW1vdW50ID4gcmVxKQorICB7CisgICAgWkRFQlVHKHNwcmludGYoInJlbW92ZTogcmVkdXppZXJlIGFtb3VudCAlZCB1bSAlZCAtPiAlZFxuIiwKKyAgICAgICAgICAgYW1vdW50LCByZXEsIGFtb3VudC1yZXEgKSk7CisgICAgU2V0UHJvcChQX0FNT1VOVCwgYW1vdW50IC0gcmVxKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBaREVCVUcoc3ByaW50ZigicmVtb3ZlOiByZXN0bG9zIHdlZy5cbiIpKTsKKyAgcmV0dXJuIDo6cmVtb3ZlKHNpbGVudCk7Cit9CisKKy8vIHNvbGx0ZSBuaWNodCB2b24gYXVzc2VuIGdlcnVmZW4gd2VyZGVuLgorcHJpdmF0ZSB2b2lkIF9jYWxsX0RvRGVjYXkob2JqZWN0ICprbG9uZSkgeworICBaREVCVUcoc3ByaW50ZigiY2FsbF9Eb0RlY2F5KCkgaW4gJU9cbiIsTUUpKTsKKyAgLy8gQ2xvbmUgb2RlciBrZWluIERlY2F5IGtvbmZpZ3VyaWVydD8KKyAgaWYgKGNsb25lcCgpCisgICAgICB8fCBRdWVyeVByb3AoUF9VTklUX0RFQ0FZX0ZMQUdTKSAmIE5PX0RFQ0FZKQorICAgIHJldHVybjsKKworICBpZiAoIXBvaW50ZXJwKGtsb25lKSkKKyAgICBrbG9uZSA9IGNsb25lcygyKTsKKyAgLy8gS2xvbmUgZGE/CisgIGludCBpPXNpemVvZihrbG9uZSk7CisgIGlmICghaSkKKyAgICByZXR1cm47CisKKyAgLy8gaW4gYWxsZW4gS2xvbmVuIERvRGVjYXkgcnVmZW4KKyAgd2hpbGUoZ2V0X2V2YWxfY29zdCgpID4gX19NQVhfRVZBTF9DT1NUX18vMiAmJiBpLS0pIHsKKyAgICBpZiAob2JqZWN0cChrbG9uZVtpXSkpCisgICAgICBjYXRjaChjYWxsX290aGVyKGtsb25lW2ldLCJEb0RlY2F5IiwgMCk7cHVibGlzaCk7CisgIH0KKyAgLy8gZGFzIGkgaXN0IHNjaG9uIGFiZ2VhcmJlaXRldC4KKyAgaS0tOworICAvLyBub2NoIHdhcyB1ZWJyaWc/CisgIGlmIChpID49IDApCisgICAgY2FsbF9vdXQoIydfY2FsbF9Eb0RlY2F5LCA0LCBrbG9uZVswLi5pXSk7Cit9CisKKy8vIHplcnN0b2VydCBxdW90YSBQcm96ZW50IGRlciB2b3JoYW5kZW5lbiBVbml0cywgbGllZmVydCBkaWUgUmVzdG1lbmdlCisvLyB6dXJ1ZWNrLiBSdWZ0IGdnZi4gRG9EZWNheU1lc3NhZ2UoKQorcHVibGljIGludCBEb0RlY2F5KGludCBzaWxlbnQpIHsKKyAgLy8gbnVyIGZ1ZXIgQ2xvbmVzCisgIGlmICghY2xvbmVwKCkpCisgICAgcmV0dXJuIDA7CisgIFpERUJVRyhzcHJpbnRmKCJEb0RlY2F5KCkgaW4gJU9cbiIsTUUpKTsKKworICAvLyB3ZW5uIGRhcyBPYmpla3QgTk9fREVDQVkgb2RlciBOT19ERUNBWV9VTlRJTF9NT1ZFIGluIGRlbiBGbGFncworICAvLyB6ZXJmYWVsbHQgbml4LgorICBpbnQgZmxhZ3MgPSBRdWVyeVByb3AoUF9VTklUX0RFQ0FZX0ZMQUdTKTsKKyAgaWYgKChmbGFncyAmIE5PX0RFQ0FZKSB8fCAoZmxhZ3MgJiBOT19ERUNBWV9VTlRJTF9NT1ZFKSApCisgICAgcmV0dXJuIFF1ZXJ5UHJvcChQX0FNT1VOVCk7CisKKyAgaW50IHF1b3RhID0gUXVlcnlQcm9wKFBfVU5JVF9ERUNBWV9RVU9UQSk7CisKKyAgLy8gWnVnZXdpbm4gaXN0IG5pY2h0LiBBdXNzZXJkZW0ga2FubiBuaWNodCBtZWhyIHplcmZhbGxlbiwgYWxzIGRhIGlzdC4uLgorICAvLyBBbHNvIG9obmUgZ3VlbHRpZ2VzIFF1b3RhIHJhdXMuIE51ciBiZWkgYWJzLiBaZXJmYWxsIHNpbmQgWmFobGVuID4gMTAwMDAKKyAgLy8gZXJsYXVidCwgYmVpIHJlbGF0aXZlbiBaZXJmYWxsIHdhZXJlIGRhcyBzaW5ubG9zLgorICBpZiAocXVvdGEgPD0gMCB8fCAKKyAgICAgIChxdW90YSA+IDEwMDAwICYmICEoZmxhZ3MgJiBBQlNPTFVURV9ERUNBWSkgKSApIAorICAgIHJldHVybiBRdWVyeVByb3AoUF9BTU9VTlQpOworICAKKyAgaW50IGFtb3VudCA9IFF1ZXJ5UHJvcChQX0FNT1VOVCk7CisgIGludCBtaW5pbXVtID0gUXVlcnlQcm9wKFBfVU5JVF9ERUNBWV9NSU4pOworICAvLyBaZXJmYWxsIG51ciwgd2VubiBtYW4gbWVociBhbHMgZGFzIE1pbmltdW0gaGF0LgorICBpZiAoYW1vdW50ID4gbWluaW11bSkgeworICAgIGludCB6ZXJmYWxsOworICAgIGlmIChmbGFncyAmIEFCU09MVVRFX0RFQ0FZKSB7CisgICAgICAvLyBEZWNheSBRdW90YSBzb2xsIGVpbmZhY2ggYWxzIGFicy4gWmFobCBhdWZnZWZhc3N0IHdlcmRlbjoKKyAgICAgIHplcmZhbGwgPSBxdW90YTsKKyAgICB9CisgICAgZWxzZSBpZiAoZmxhZ3MgJiBJTkFDQ1VSQVRFX0RFQ0FZKSB7CisgICAgICAvLyBSdW5kdW5nc2ZlaGxlciBpZ25vcmllcmVuIHVuZCBkYWZ1ZXIgaW1tZXIgbWluLiBlaW5lIEVpbmhlaXQKKyAgICAgIC8vIHplcmZhbGxlbiBsYXNzZWluCisgICAgICB6ZXJmYWxsID0gKGFtb3VudCAqIHF1b3RhKSAvIDEwMDAwOworICAgICAgaWYgKHplcmZhbGwgPD0gMCkgemVyZmFsbCA9IDE7CisgICAgfQorICAgIGVsc2UgeworICAgICAgLy8gU3RhbmRhcmRmYWxsOgorICAgICAgLy8gbmljaHQtZ2FuenphaGxpZ2VuIFJlc3QgYWxzIFdhaHJzY2hlaW5saWNoa2VpdCBmdWVyIGRlbiBaZXJmYWxsIGVpbmVyCisgICAgICAvLyBFaW5oZWl0IGF1ZmZhc3NlbgorICAgICAgZmxvYXQgdG1wID0gYW1vdW50ICogcXVvdGEgLyAxMDAwMC4wOworICAgICAgemVyZmFsbCA9IHRvX2ludCh0bXApOworICAgICAgdG1wIC09IHplcmZhbGw7IC8vIFJlc3QgaW4gdG1wCisgICAgICAvLyB0bXAqbiBpc3QgZWluZSBaYWhsIHp3aXNjaGVuIDAgdW5kIG4sIHdlbm4gdG1wKm4gPiByYW5kb20obikrMSwKKyAgICAgIC8vIGRhbm4gemVyZmFlbGx0IGVpbmUgRWluaGVpdCBleHRyYS4gRGEgZGFzIFJhbmRvbSBmdWVyIGdyb3NzZSBaYWhsZW4KKyAgICAgIC8vIGJlc3NlciB2ZXJ0ZWlsdCBpc3QsIG5laG0gaWNoIG4gPSBfX0lOVF9NQVhfXworICAgICAgaWYgKGNlaWwodG1wICogX19JTlRfTUFYX18pID4gcmFuZG9tKF9fSU5UX01BWF9fKSArIDEpCisgICAgICAgIHplcmZhbGwrKzsKKyAgICB9CisKKyAgICAvLyBuaWNodCB1bnRlciBNaW5pbXVtIHplcmZhbGxlbgorICAgIGlmIChhbW91bnQgLSB6ZXJmYWxsIDwgbWluaW11bSkKKyAgICAgIHplcmZhbGwgPSBhbW91bnQgLSBtaW5pbXVtOworCisgICAgLy8gZXJzdCBnZ2YuIE1lbGR1bmcgYXVzZ2ViZW4uCisgICAgaWYgKCFzaWxlbnQgJiYgemVyZmFsbCA+IDApCisgICAgICBEb0RlY2F5TWVzc2FnZShhbW91bnQsIHplcmZhbGwpOworICAgIC8vIGRhbm4gcnVudGVyc2V0emVuLgorICAgIFNldFByb3AoUF9BTU9VTlQsIGFtb3VudCAtIHplcmZhbGwpOworICAgIFpERUJVRyhzcHJpbnRmKCIlTyBkZWNheWVkIGJ5ICVkXG4iLE1FLCB6ZXJmYWxsKSk7CisgICAgcmV0dXJuIGFtb3VudC16ZXJmYWxsOworICB9CisgIGVsc2UgaWYgKGFtb3VudCA8IDApCisgICAgcmV0dXJuIDA7IC8vIG5lZy4gQW56YWhsIGdpbHQgYWxzICIwIHVlYnJpZyIuCisgIAorICAvLyBzb25zdCBpc3RzIHdvaGwgendpc2NoZW4gMCB1bmQgbWluaW11bSwgbml4IGFlbmRlcnQgc2ljaC4KKyAgcmV0dXJuIGFtb3VudDsKK30KKworLy8gZ2lidCBkaWUgWmVyZmFsbHNtZWxkdW5nIGF1cy4gV2VubiBtYW4gbWl0IGRlciBTdGFuZGFyZG1lbGR1bmcgbmljaHQgenVmcmllZGVuCisvLyBpc3QgKGR1ZXJmdGUgZGVyIE5vcm1hbGZhbGwgc2VpbiksIHNvbGx0ZSBtYW4gZGllc2UgRnVua3Rpb24KKy8vIHVlYmVyc2NocmVpYmVuLiBCZWtvbW10IGJpc2hlcmlnZSB1bmQgamV0enQgZ2VyYWRlIHplcmZhbGxlbmUgTWVuZ2UKKy8vIHVlYmVyZ2ViZW4uIFdpY2h0aWc6IHp1IGRpZXNlbSBaZWl0cHVua3QgaGF0IHNpY2ggYW4gZGVyIFVuaXQgbm9jaCBuaXggKCEpCisvLyBnZWFlbmRlcnQhCitwcm90ZWN0ZWQgdm9pZCBEb0RlY2F5TWVzc2FnZShpbnQgb2xkYW1vdW50LCBpbnQgemVyZmFsbCkgeworICBzdHJpbmcgbXNnOworICBpZiAob2xkYW1vdW50ID09IHplcmZhbGwpIHsKKyAgICBpZiAobGl2aW5nKGVudmlyb25tZW50KCkpKSB7CisgICAgICB0ZWxsX29iamVjdChlbnZpcm9ubWVudCgpLCBicmVha19zdHJpbmcoc3ByaW50ZigKKyAgICAgICAgICAiQXVmIGVpbm1hbCAlcyVzIHp1IFN0YXViISIsCisgICAgICAgICAgKG9sZGFtb3VudD4xPyJ6ZXJmYWxsZW4gRGVpbmUgIjoiemVyZmFlbGx0IEQiKSwgbmFtZShXRVIpKSw3OCkpOworICAgIH0KKyAgICAvLyBkYXMgdGVsbF9yb29tKCkgbXVzcyBhdWYgamVkZW4gZmFsbCBzZWluLCB3ZWlsIGVzICJsZWJlbmRlIiBSYWV1bWUKKyAgICAvLyBnaWJ0LiBMaWVndCBkZXIgS1JhbSBpbiBlaW5lbSBzb2xjaGVuIHd1ZXJkZW4gZGllIExpdmluZ3MgaW4gZGllc2VtIFJhdW0KKyAgICAvLyBzb25zdCBrZWluZSBtZWxkdW5nIGtyaWVnZW4uCisgICAgdGVsbF9yb29tKGVudmlyb25tZW50KCksIGJyZWFrX3N0cmluZyhzcHJpbnRmKAorICAgICAgICAgICJBdWYgZWlubWFsICVzICVzIHp1IFN0YXViISIsCisgICAgICAgICAgKG9sZGFtb3VudD4xPyJ6ZXJmYWxsZW4iOiJ6ZXJmYWVsbHQiKSwgbmFtZShXRVIpKSw3OCksCisgICAgICAgICh7ZW52aXJvbm1lbnQoKX0pKTsKKyAgfQorICBlbHNlIHsKKyAgICAgaWYgKGxpdmluZyhlbnZpcm9ubWVudCgpKSkgeworICAgICAgdGVsbF9vYmplY3QoZW52aXJvbm1lbnQoKSwgYnJlYWtfc3RyaW5nKHNwcmludGYoCisgICAgICAgICAgIkF1ZiBlaW5tYWwgJXMgJWQgRGVpbmVyICVzIHp1IFN0YXViISIsCisgICAgICAgICAgKHplcmZhbGw+MT8iemVyZmFsbGVuIjoiemVyZmFlbGx0IiksCisgICAgICAgICAgemVyZmFsbCwgUXVlcnkoUF9OQU1FKVsxXSksNzgpKTsKKyAgICB9CisgICAgLy8gZGFzIHRlbGxfcm9vbSgpIG11c3MgYXVmIGplZGVuIGZhbGwgc2Vpbiwgd2VpbCBlcyAibGViZW5kZSIgUmFldW1lCisgICAgLy8gZ2lidC4gTGllZ3QgZGVyIEtSYW0gaW4gZWluZW0gc29sY2hlbiB3dWVyZGVuIGRpZSBMaXZpbmdzIGluIGRpZXNlbSBSYXVtCisgICAgLy8gc29uc3Qga2VpbmUgbWVsZHVuZyBrcmllZ2VuLgorICAgIHRlbGxfcm9vbShlbnZpcm9ubWVudCgpLCBicmVha19zdHJpbmcoc3ByaW50ZigKKyAgICAgICAgICAiQXVmIGVpbm1hbCAlcyAlZCAlcyB6dSBTdGF1YiEiLAorICAgICAgICAgICh6ZXJmYWxsPjE/InplcmZhbGxlbiI6InplcmZhZWxsdCIpLAorICAgICAgICAgIHplcmZhbGwsIFF1ZXJ5KFBfTkFNRSlbMV0pLDc4KSwgKHtlbnZpcm9ubWVudCgpfSkgKTsgCisgIH0KK30KKworc3RhdGljIGludCBfcXVlcnlfdW5pdF9kZWNheV9pbnRlcnZhbCgpIHsKKyAgaWYgKGNsb25lcCgpKSB7CisgICAgLy8gZnVlciBjbG9uZXMgZGVuIFdlcnQgYXVzIGRlciBCUCBsaWVmZXJuLCBkZXIgV2VydCBpbiBDbG9uZXMgaXN0IGVoCisgICAgLy8gdW5pbnRlcmVzc2FudC4KKyAgICBpZiAob2JqZWN0cChibHVlcHJpbnQoKSkpCisgICAgICByZXR1cm4gYmx1ZXByaW50KCktPlF1ZXJ5UHJvcChQX1VOSVRfREVDQVlfSU5URVJWQUwpOworICAgIGVsc2UKKyAgICAgIHJldHVybiBsb2FkX29iamVjdChsb2FkX25hbWUoKSktPlF1ZXJ5UHJvcChQX1VOSVRfREVDQVlfSU5URVJWQUwpOworICB9CisgIHJldHVybiBRdWVyeShQX1VOSVRfREVDQVlfSU5URVJWQUwpOworfQorCitzdGF0aWMgaW50IF9zZXRfdW5pdF9kZWNheV9pbnRlcnZhbChpbnQgemVpdCkgeworICAvLyBmdWVyIENsb25lcyBpc3QgZGllIFByb3Agc2lubmxvcyB1bmQga2FubiBuaWNodCBnZXNldHp0IHdlcmRlbi4KKyAgaWYgKGNsb25lcCgpKSB7CisgICAgaWYgKG9iamVjdHAoYmx1ZXByaW50KCkpKQorICAgICAgcmV0dXJuIGJsdWVwcmludCgpLT5RdWVyeVByb3AoUF9VTklUX0RFQ0FZX0lOVEVSVkFMKTsKKyAgICBlbHNlCisgICAgICByZXR1cm4gbG9hZF9vYmplY3QobG9hZF9uYW1lKCkpLT5RdWVyeVByb3AoUF9VTklUX0RFQ0FZX0lOVEVSVkFMKTsKKyAgfQorICAvLyB1ZWJlciBkaWVzZSBQcm9wIGxpZXNzZSBzaWNoIGRlciBSZXNldCByZWxhdGl2IGJlbGllYmlnIHZlcmFlbmRlcm4sCisgIC8vIHZlcmhpbmRlcm4sIGV0Yy4gRGFoZXIgZGFyZiBzaWUgbnVyIHZvbiBkaWVzZW0gT2JqZWt0IGdlc2V0enQgd2VyZGVuLCB2b24KKyAgLy8gV2Vpc2VuKyBvZGVyIGVpbmVzIE9iamVrdGVzLCBkYXMgZGllIGdsZWljaGUgVUlEIGhhdCB3aWUgZGllc2VzIGhpZXIgb2RlcgorICAvLyBkZXMgUHJvZ3JhbW1pZXJlcyBkaWVzZXMgT2JqZWt0cyBvZGVyIGVpbmVzIE1hZ2llcnMsIGRlciBiZXJlY2h0aWd0IGZ1ZXIKKyAgLy8gZGllIGpld2VpbGlnZSBVSUQgaXN0LiBMZXR6dGVyZSBiZWlkZW4gd2VyZGVuIHVlYmVyIGRlbiBSdWYgdm9uCisgIC8vIFF1ZXJ5VUlEc0ZvcldpemFyZCgpIGVybWl0dGVsdC4KKyAgLy8gZXJzdGVzIGZyZW1kZXMgT2JqZWt0IGZpbmRlbiB1bmQgcHJ1ZWZlbi4KKyAgZm9yZWFjaChvYmplY3QgcG86IGNhbGxlcl9zdGFjaygxKSkgeworICAgIGlmIChwbyAhPSBNRSkgeworICAgICAgLy8gZnJlbWRlbiBBdWZydWZlciBnZWZ1bmRlbgorICAgICAgaWYgKGdldHVpZChwbykgIT0gZ2V0dWlkKE1FKSAKKyAgICAgICAgICAmJiBtZW1iZXIobWFzdGVyKCktPlF1ZXJ5VUlEc0ZvcldpemFyZChnZXR1aWQocG8pKSxnZXR1aWQoTUUpKSA9PSAtMQorICAgICAgICAgICYmICghdGhpc19pbnRlcmFjdGl2ZSgpIHx8ICFJU19FTERFUih0aGlzX2ludGVyYWN0aXZlKCkpICkgKQorICAgICAgICAvLyB1bmJlcmVjaHRpZ3QsIEFiYnJ1Y2gKKyAgICAgICAgcmV0dXJuIFF1ZXJ5UHJvcChQX1VOSVRfREVDQVlfSU5URVJWQUwpOworICAgICAgZWxzZQorICAgICAgICAvLyBudXIgZGFzIGVyc3RlIGV4dC4gT2JqZWt0IGluIGRlciBDYWxsa2V0dGUgd2lyZCBnZXBydWVmdCwgcmF1cy4KKyAgICAgICAgYnJlYWs7CisgICAgfQorICB9CisgIHNldF9uZXh0X3Jlc2V0KHplaXQpOworICAvLyBmYWxscyBkaWVzIGF1cyBkZW0gY3JlYXRlKCkgZ2VzZXR6dCB3aXJkLCBtdXNzIHplaXR2ZXJ6b2VnZXJ0IGVpbmUKKyAgLy8gRnVua3Rpb24gdm9uIGF1c3NlbiBhbSBPYmpla3QgZ2VydWZlbiB3ZXJkZW4sIGRhIG5hY2ggZWluZW0gY3JlYXRlKCkgZGFzCisgIC8vIE9iamVrdCBhbHMgcmVzZXR0ZXQgZ2lsdCB1bmQgc29uc3Qga2VpbmVuIFJlc2V0IGtyaWVndC4KKyAgY2FsbF9vdXQoIl9xdWVyeV91bml0X2RlY2F5X2ludGVydmFsIiwxKTsKKyAgcmV0dXJuIFNldChQX1VOSVRfREVDQVlfSU5URVJWQUwsIHplaXQsIEZfVkFMVUUpOworfQorCitzdGF0aWMgaW50IF9xdWVyeV91bml0X2RlY2F5X3F1b3RhKCkgeworICBpZiAoY2xvbmVwKCkpIHsKKyAgICAvLyBoYXQgZGllc2VzIE9iamVrdCBlaW5lbiBlaWdlbmVuIHdlcnQgZ2VzcGVpY2hlcnQ/CisgICAgaW50IHF1b3RhPVF1ZXJ5KFBfVU5JVF9ERUNBWV9RVU9UQSwgRl9WQUxVRSk7CisgICAgaWYgKHF1b3RhKQorICAgICAgcmV0dXJuIHF1b3RhOworICAgIC8vIHNvbnN0IGRlbiBXZXJ0IGF1cyBkZXIgQmx1ZXByaW50CisgICAgaWYgKG9iamVjdHAoYmx1ZXByaW50KCkpKQorICAgICAgcmV0dXJuIGJsdWVwcmludCgpLT5RdWVyeVByb3AoUF9VTklUX0RFQ0FZX1FVT1RBKTsKKyAgICBlbHNlCisgICAgICByZXR1cm4gbG9hZF9vYmplY3QobG9hZF9uYW1lKCkpLT5RdWVyeVByb3AoUF9VTklUX0RFQ0FZX1FVT1RBKTsKKyAgfQorICByZXR1cm4gUXVlcnkoUF9VTklUX0RFQ0FZX1FVT1RBLCBGX1ZBTFVFKTsKK30KKworc3RhdGljIGludCBfc2V0X3VuaXRfZGVjYXlfcXVvdGEoaW50IHF1b3RhKSB7IAorICAvLyBtb21lbnRhbiBudXIgcXVvdGEgendpc2NoZW4gMCB1bmQgMTAwMDAKKyAgaWYgKHF1b3RhID49IDAgJiYgcXVvdGEgPD0xMDAwMCkKKyAgICByZXR1cm4gU2V0KFBfVU5JVF9ERUNBWV9RVU9UQSwgcXVvdGEsIEZfVkFMVUUpOworICBlbHNlCisgICAgcmV0dXJuIFF1ZXJ5KFBfVU5JVF9ERUNBWV9RVU9UQSwgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X3VuaXRfZGVjYXlfbWluKCkgeworICBpZiAoY2xvbmVwKCkpIHsKKyAgICAvLyBoYXQgZGllc2VzIE9iamVrdCBlaW5lbiBlaWdlbmVuIHdlcnQgZ2VzcGVpY2hlcnQ/CisgICAgaW50IG1pbmltdW09UXVlcnkoUF9VTklUX0RFQ0FZX01JTiwgRl9WQUxVRSk7CisgICAgaWYgKG1pbmltdW0pCisgICAgICByZXR1cm4gbWluaW11bTsKKyAgICAvLyBzb25zdCBkZW4gV2VydCBhdXMgZGVyIEJsdWVwcmludAorICAgIGlmIChvYmplY3RwKGJsdWVwcmludCgpKSkKKyAgICAgIHJldHVybiBibHVlcHJpbnQoKS0+UXVlcnlQcm9wKFBfVU5JVF9ERUNBWV9NSU4pOworICAgIGVsc2UKKyAgICAgIHJldHVybiBsb2FkX29iamVjdChsb2FkX25hbWUoKSktPlF1ZXJ5UHJvcChQX1VOSVRfREVDQVlfTUlOKTsKKyAgfQorICByZXR1cm4gUXVlcnkoUF9VTklUX0RFQ0FZX01JTiwgRl9WQUxVRSk7Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X3VuaXRfZGVjYXlfZmxhZ3MoKSB7CisgIGlmIChjbG9uZXAoKSkgeworICAgIC8vIGhhdCBkaWVzZXMgT2JqZWt0IGVpbmVuIGVpZ2VuZW4gd2VydCBnZXNwZWljaGVydD8KKyAgICBpbnQgZmxhZ3M9UXVlcnkoUF9VTklUX0RFQ0FZX0ZMQUdTLCBGX1ZBTFVFKTsKKyAgICBpZiAoZmxhZ3MpCisgICAgICByZXR1cm4gZmxhZ3M7CisgICAgLy8gc29uc3QgZGVuIFdlcnQgYXVzIGRlciBCbHVlcHJpbnQKKyAgICBpZiAob2JqZWN0cChibHVlcHJpbnQoKSkpCisgICAgICByZXR1cm4gYmx1ZXByaW50KCktPlF1ZXJ5UHJvcChQX1VOSVRfREVDQVlfRkxBR1MpOworICAgIGVsc2UKKyAgICAgIHJldHVybiBsb2FkX29iamVjdChsb2FkX25hbWUoKSktPlF1ZXJ5UHJvcChQX1VOSVRfREVDQVlfRkxBR1MpOworICB9CisgIC8vIERpZSBCUCBsaWVmZXJ0IGRlbiBXZXJ0IGF1ZiBqZWRlbiBGYWxsIG9obmUgTk9fREVDQVlfVU5USUxfTU9WRSB6dXJ1ZWNrLAorICAvLyB3ZWlsIGRpZXNlcyBGbGFnIGltIEZhbGxlIGRlciBCUCBuaWNodCB6dXJ1ZWNrZ2VzZXR6dCB3aXJkIHVuZCBiZWkgQ2xpZW50cyAKKyAgLy8gb2huZSBlaWdlbmUgRmxhZ3MgZGVyIFplcmZhbGwgc3RvcHBlbiB3dWVyZGUuCisgIHJldHVybiBRdWVyeShQX1VOSVRfREVDQVlfRkxBR1MsIEZfVkFMVUUpICYgfk5PX0RFQ0FZX1VOVElMX01PVkU7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC91c2VyX2ZpbHRlci5jIGIvc3RkL3VzZXJfZmlsdGVyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTQxOTBjOAotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC91c2VyX2ZpbHRlci5jCkBAIC0wLDAgKzEsNDM1IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdXNlcl9maWx0ZXIuYyAtLSBIaWxmc21vZHVsIGZ1ZXIgZGllIHdlci1MaXN0ZQorLy8KKy8vICRJZDogdXNlcl9maWx0ZXIuYyA4NzU1IDIwMTQtMDQtMjYgMTM6MTM6NDBaIFplc3N0cmEgJAorI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPGxhbmd1YWdlLmg+CisKKyNkZWZpbmUgTUUgdGhpc19vYmplY3QoKQorCitzdGF0aWMgaW50IGlzX2luICggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgcmV0dXJuIChzdHJzdHIoIGxvd2VyX2Nhc2UoY291bnRyeShvYikpLCB4ICkgIT0gLTEgfHwKKyAgICAgICAgICBzdHJzdHIoIGxvd2VyX2Nhc2Uob2ItPlF1ZXJ5KFBfTE9DQVRJT04pIHx8ICIiKSwgeCApICE9IC0xKTsKK30KKworc3RhdGljIGludCBpc19hdCggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgcmV0dXJuIGVudmlyb25tZW50KG9iKSA9PSB4OworfQorCitzdGF0aWMgaW50IGlzX3dpel9sZXZlbF9sdCggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgcmV0dXJuIHF1ZXJ5X3dpel9sZXZlbChvYikgPCB4OworfQorCitzdGF0aWMgaW50IGlzX3dpel9sZXZlbF9nZSggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgcmV0dXJuIHF1ZXJ5X3dpel9sZXZlbChvYikgPj0geDsKK30KKworc3RhdGljIGludCBpc19wcm9wX3NldCggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgcmV0dXJuIChtaXhlZClvYi0+UXVlcnlQcm9wKHgpICE9IDA7Cit9CisKK3N0YXRpYyBpbnQgaXNfc2Vjb25kKCBvYmplY3Qgb2IsIG1peGVkIHggKQoreworICByZXR1cm4gb2ItPlF1ZXJ5UHJvcChQX1NFQ09ORCkgJiYgb2ItPlF1ZXJ5UHJvcChQX1NFQ09ORF9NQVJLKSA+IHg7Cit9CisKK3N0YXRpYyBpbnQgaXNfbWFnZV9zZWNvbmQoIG9iamVjdCBvYiApCit7CisgIHJldHVybiBvYi0+UXVlcnlQcm9wKFBfU0VDT05EKSAmJiBJU19MRUFSTkVSKG9iLT5RdWVyeVByb3AoUF9TRUNPTkQpKTsKK30KKworc3RhdGljIGludCBpc19pbl9naWxkZSggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgc3RyaW5nIHN0cjsKKworICAvLyBudXIgTWFnaWVyIGtvZW5uZW4gZWluZSBhbmRlcmUgR2lsZGUgcGVyIFBfVklTSUJMRV9HVUlMRCBpbiB3ZXJsaXN0ZW4KKyAgLy8gZXRjLiB2b3J0YWV1c2NoZW4uCisgIGlmIChJU19MRUFSTkVSKG9iKSkgeworICAgIC8vIFF1ZXJ5bWV0aG9kZSB2b24gUF9WSVNJQkxFX0dVSUxEIGZyYWd0IGdnZi4gYXVjaCBQX0dVSUxEIGFiLgorICAgIGlmICggIXN0cmluZ3Aoc3RyID0gKHN0cmluZylvYi0+UXVlcnlQcm9wKFBfVklTSUJMRV9HVUlMRCkpICkKKyAgICAgIHJldHVybiAwOworICB9CisgIGVsc2UgeworICAgICAgc3RyID0gKHN0cmluZylvYi0+UXVlcnlQcm9wKFBfR1VJTEQpOworICB9CisgIGlmICghc3RyaW5ncChzdHIpKSByZXR1cm4gMDsgLy8gbG9naW4gaGF0IHouQi4ga2VpbmUgR2lsZGUuCisgIHJldHVybiBzdHJzdHIobG93ZXJfY2FzZShzdHIpLHgpID09IDA7Cit9CisKK3N0YXRpYyBpbnQgaXNfaW5fdGVhbSggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgb2JqZWN0IHRlYW07CisgIAorICBpZiAoICFvYmplY3RwKHRlYW0gPSAob2JqZWN0KW9iLT5RdWVyeVByb3AoUF9URUFNKSkgKQorICAgIHJldHVybiB4ID09ICIiOworICAKKyAgcmV0dXJuIGxvd2VyX2Nhc2UoKHN0cmluZyl0ZWFtLT5OYW1lKCkpID09IHg7Cit9CisKK3N0YXRpYyBpbnQgaXNfbmFtZV9pbiggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgcmV0dXJuIG1lbWJlciggeCwgY2FwaXRhbGl6ZShnZXRldWlkKG9iKSkgKSA+PSAwOworfQorCitzdGF0aWMgaW50IGlzX2luX3JlZ2lvbiggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgcmV0dXJuIGVudmlyb25tZW50KG9iKSAmJgorICAgIChvYmplY3RfbmFtZShlbnZpcm9ubWVudChvYikpWzAuLihzaXplb2YoeCktMSldID09IHgpOworfQorCitzdGF0aWMgaW50IGlzX3JlZ2lvbl9tZW1iZXIoIG9iamVjdCBvYiwgbWl4ZWQgeCApCit7CisgIHJldHVybiAoaW50KW1hc3RlcigpLT5kb21haW5fbWVtYmVyKCBnZXRldWlkKG9iKSwgeCApOworfQorCitzdGF0aWMgaW50IGlzX3JlZ2lvbl9tYXN0ZXIoIG9iamVjdCBvYiwgbWl4ZWQgeCApCit7CisgIHJldHVybiAoaW50KW1hc3RlcigpLT5kb21haW5fbWFzdGVyKCBnZXRldWlkKG9iKSwgeCApOworfQorCitzdGF0aWMgaW50IGlzX2d1aWxkX21hc3RlcihvYmplY3Qgb2IsIG1peGVkIHgpCit7CisgIHJldHVybiAoaW50KW1hc3RlcigpLT5ndWlsZF9tYXN0ZXIoZ2V0ZXVpZChvYiksIHgpOworfQorCitzdGF0aWMgaW50IGlzX2dlbmRlciggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgcmV0dXJuIG9iLT5RdWVyeVByb3AoUF9HRU5ERVIpID09IHg7Cit9CisKK3N0YXRpYyBpbnQgaXNfcmFjZSggb2JqZWN0IG9iLCBtaXhlZCB4ICkKK3sKKyAgcmV0dXJuIG9iLT5RdWVyeVByb3AoUF9SQUNFKSA9PSB4OworfQorCitzdGF0aWMgaW50IGlzX3VubWFycmllZCggb2JqZWN0IG9iICkKK3sKKyAgcmV0dXJuIG9iLT5RdWVyeVByb3AoUF9NQVJSSUVEKSA9PSAwOworfQorCitzdGF0aWMgaW50IGlzX2lkbGUoIG9iamVjdCBvYiwgbWl4ZWQgeCApCit7CisgIHJldHVybiBxdWVyeV9pZGxlKG9iKSA+PSB4OworfQorCitzdGF0aWMgaW50IGlzX2hjKCBvYmplY3Qgb2IpCit7CisgIHJldHVybiBvYi0+cXVlcnlfaGNfcGxheSgpPjA7Cit9CisKK3N0YXRpYyBpbnQgaXNfZ2hvc3QoIG9iamVjdCBvYikKK3sKKyAgcmV0dXJuIChpbnQpb2ItPlF1ZXJ5UHJvcChQX0dIT1NUKTsKK30KKworc3RhdGljIGludCB1c2VzX3NzbChvYmplY3Qgb2IpCit7CisgIGlmKCF0aGlzX2ludGVyYWN0aXZlKCkgfHwgIUlTX0xFQVJORVIodGhpc19pbnRlcmFjdGl2ZSgpKSkKKyAgICByZXR1cm4gMDsKKyNpZiBfX0VGVU5fREVGSU5FRF9fKHRsc19xdWVyeV9jb25uZWN0aW9uX2luZm8pCisgIHJldHVybiB0bHNfcXVlcnlfY29ubmVjdGlvbl9pbmZvKG9iKSAhPSAwOworI2Vsc2UKKyAgcmV0dXJuIDA7CisjZW5kaWYKK30KKworcHJvdGVjdGVkIGludCBpc19hY3RpdmVfZ3VpZGUob2JqZWN0IG9iKSB7CisgICAgaW50IGNpYz0oaW50KW9iLT5RdWVyeVByb3AoUF9ORVdCSUVfR1VJREUpOworICAgIGlmICghaW50cChjaWMpIHx8IGNpYyA8PSAwKQorICAgICAgcmV0dXJuIDA7CisgICAgZWxzZSBpZiAoY2ljIDwgNjApCisgICAgICByZXR1cm4gMTsgLy8ga2xlaW5lciA2MHMgaW4gZGVyIFByb3AgLT4gaW1tZXIgYWt0aXYuCisgICAgZWxzZSBpZiAoY2ljIDw9IDg2NDAwKSB7CisgICAgICAvLyB3ZW5uIGxhZW5nZXIgaWRsZSBhbHMgY2ljIC0+IGluYWt0aXYKKyAgICAgIGlmIChxdWVyeV9pZGxlKG9iKSA+IGNpYykKKwlyZXR1cm4gMDsKKyAgICAgIHJldHVybiAxOworICAgIH0KKyAgICAvLyB1bmd1ZWx0aWdlciBXZXJ0ZWJlcmVpY2ggLT4gaW5ha3Rpdi4KKyAgICByZXR1cm4gMDsKK30KKworb2JqZWN0ICpmaWx0ZXJfdXNlcnMoIHN0cmluZyBzdHIgKQoreworICBvYmplY3QgKnJlcywgKm9yaWcsICp6d2k7CisgIHN0cmluZyAqd29yZHM7CisgIGludCBpLCBzeiwgZiwgbCx0OworICBtaXhlZCB4OworICAKKyAgb3JpZyA9IHVzZXJzKCk7CisgIAorICBpZiAoIXN0cikKKyAgICByZXR1cm4gb3JpZzsKKyAgCisgIHJlcyA9ICh7fSk7CisgIHdvcmRzID0gb2xkX2V4cGxvZGUoIGxvd2VyX2Nhc2Uoc3RyKSwgIiAiICk7CisgIHN6ID0gc2l6ZW9mKHdvcmRzKTsKKyAgCisgIGZvciAoIGkgPSAwOyBpIDwgc3o7IGkrKyApeworICAgIHp3aSA9ICh7fSk7CisgICAgCisgICAgc3dpdGNoICh3b3Jkc1tpXSkgeworICAgIGNhc2UgImF1c3NlciI6CisgICAgY2FzZSAib2huZSI6CisgICAgY2FzZSAibmljaHQiOgorICAgICAgZj0tMTsKKyAgICAgIGlmICghaSkgcmVzPW9yaWc7CisgICAgICBjb250aW51ZTsKKyAgICAgIAorICAgIGNhc2UgIm9kZXIiOgorICAgICAgZj0wOworICAgICAgY29udGludWU7CisgICAgICAKKyAgICBjYXNlICJ1bmQiOgorICAgICAgZj0xOworICAgICAgY29udGludWU7CisgICAgICAKKyAgICBjYXNlICJhbGxlIjoKKyAgICAgIHp3aSA9IG9yaWc7CisgICAgICBicmVhazsKKworICAgIGNhc2UgImluIjoKKyAgICBjYXNlICJhdXMiOgorICAgICAgaWYgKCArK2kgPj0gc3ogKQorICAgICAgICBicmVhazsKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX2luIiwgTUUsIHdvcmRzW2ldICk7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgInJlZ2lvbiI6CisgICAgICBpZiAoICsraSA+PSBzeiApCisgICAgICAgIGJyZWFrOworICAgICAgendpID0gZmlsdGVyKCBvcmlnLCAiaXNfaW5fcmVnaW9uIiwgTUUsICIvZC8iICsgd29yZHNbaV0gKTsKKyAgICAgIGJyZWFrOworICAgICAgCisgICAgY2FzZSAibWl0YXJiZWl0ZXIiOgorICAgIGNhc2UgInJlZ2lvbnNtaXRhcmJlaXRlciI6CisgICAgICBpZiAoICsraSA+PSBzeiApCisgICAgICAgIGJyZWFrOworICAgICAgendpID0gZmlsdGVyKCBvcmlnLCAiaXNfcmVnaW9uX21lbWJlciIsIE1FLCB3b3Jkc1tpXSApOworICAgICAgYnJlYWs7CisgICAgICAKKyAgICBjYXNlICJyZWdpb25zbWFnaWVyIjoKKyAgICAgIGlmICggKytpID49IHN6ICkKKyAgICAgICAgYnJlYWs7CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19yZWdpb25fbWFzdGVyIiwgTUUsIHdvcmRzW2ldICk7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgImdpbGRlbm1hZ2llciI6CisgICAgICBpZiAoICsraSA+PSBzeiApCisJYnJlYWs7CisgICAgICB6d2kgPSBmaWx0ZXIgKG9yaWcsICJpc19ndWlsZF9tYXN0ZXIiLCBNRSwgd29yZHNbaV0gKTsKKyAgICAgIGJyZWFrOworICAgICAgCisgICAgY2FzZSAiZ2lsZGUiOgorICAgICAgaWYgKCArK2kgPj0gc3ogKQorICAgICAgICBicmVhazsKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX2luX2dpbGRlIiwgTUUsIHdvcmRzW2ldICk7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgInRlYW0iOgorICAgICAgaWYgKCArK2kgPj0gc3ogKQorICAgICAgICBicmVhazsKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX2luX3RlYW0iLCBNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbG93ZXJfY2FzZSgidGVhbSAiICsgd29yZHNbaV0pICk7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgImJlaSI6CisgICAgICBpZiAoICsraSA+PSBzeiApCisgICAgICAgIGJyZWFrOworICAgICAgaWYgKCAhb2JqZWN0cCh4ID0gZmluZF9wbGF5ZXIod29yZHNbaV0pICkgJiYKKyAgICAgICAgICAgIW9iamVjdHAoeCA9IGZpbmRfbGl2aW5nKHdvcmRzW2ldKSkgKQorICAgICAgICBicmVhazsKKyAgICAgIGlmICggeC0+UXVlcnlQcm9wKFBfSU5WSVMpICkKKyAgICAgICAgYnJlYWs7CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19hdCIsIE1FLCBlbnZpcm9ubWVudCh4KSApOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlICJnb2V0dGVyIjoKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX3dpel9sZXZlbF9nZSIsIE1FLCBHT0RfTFZMICk7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgImVyem1hZ2llciI6CisgICAgY2FzZSAiZXJ6aSI6CisgICAgY2FzZSAiZXJ6aXMiOgorICAgICAgendpID0gZmlsdGVyKCBvcmlnLCAiaXNfd2l6X2xldmVsX2dlIiwgTUUsIEFSQ0hfTFZMICk7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgIm1hZ2llciI6CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc193aXpfbGV2ZWxfZ2UiLCBNRSwgTEVBUk5FUl9MVkwgKTsKKyAgICAgIGJyZWFrOworICAgICAgCisgICAgY2FzZSAic3BpZWxlciI6CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc193aXpfbGV2ZWxfbHQiLCBNRSwgU0VFUl9MVkwgKTsKKyAgICAgIGJyZWFrOworICAgICAgCisgICAgY2FzZSAic2VoZXIiOgorICAgICAgendpID0gZmlsdGVyKCBmaWx0ZXIoIG9yaWcsICJpc193aXpfbGV2ZWxfbHQiLCBNRSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMRUFSTkVSX0xWTCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICJpc193aXpfbGV2ZWxfZ2UiLCBNRSwgU0VFUl9MVkwgKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAibWFlbm5saWNoIjoKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX2dlbmRlciIsIE1FLCBNQUxFICk7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgIndlaWJsaWNoIjoKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX2dlbmRlciIsIE1FLCBGRU1BTEUgKTsKKyAgICAgIGJyZWFrOworICAgICAgCisgICAgY2FzZSAibGVkaWciOgorICAgICAgendpID0gZmlsdGVyKCBvcmlnLCAiaXNfdW5tYXJyaWVkIiApOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlICJzc2wiOgorICAgIGNhc2UgInN0dW5uZWwiOgorICAgICAgendpID0gZmlsdGVyKG9yaWcsInVzZXNfc3NsIik7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgImhhcmRjb3JlIjoKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX2hjIiApOworICAgICAgYnJlYWs7CisgICAgICAKKyAgICBjYXNlICJnZWlzdCI6CisgICAgY2FzZSAidG90IjoKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX2dob3N0IiApOworICAgICAgYnJlYWs7CisgICAgICAKKyAgICBjYXNlICJtZW5zY2giOgorICAgICAgendpID0gZmlsdGVyKCBvcmlnLCAiaXNfcmFjZSIsIE1FLCAiTWVuc2NoIiApOworICAgICAgYnJlYWs7CisgICAgICAKKyAgICBjYXNlICJ6d2VyZyI6CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19yYWNlIiwgTUUsICJad2VyZyIgKTsKKyAgICAgIGJyZWFrOworICAgICAgCisgICAgY2FzZSAiZWxmIjoKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX3JhY2UiLCBNRSwgIkVsZiIgKTsKKyAgICAgIGJyZWFrOworICAgICAgCisgICAgY2FzZSAiZmVsaW5lIiA6CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19yYWNlIiwgTUUsICJGZWxpbmUiICk7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgImhvYmJpdCI6CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19yYWNlIiwgTUUsICJIb2JiaXQiICk7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgImR1bmtlbGVsZiI6CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19yYWNlIiwgTUUsICJEdW5rZWxlbGYiICk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgImdvYmxpbiI6CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19yYWNlIiwgTUUsICJHb2JsaW4iICk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgIm9yayI6CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19yYWNlIiwgTUUsICJPcmsiICk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgImZyb3NjaCI6CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19wcm9wX3NldCIsIE1FLCBQX0ZST0cgKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAid2VnIjoKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX3Byb3Bfc2V0IiwgTUUsIFBfQVdBWSApOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlICJpZGxlIjoKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX2lkbGUiLCBNRSwgMTIwICk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgImlkbGV6ZWl0IjoKKyAgICAgIGlmICggKytpID49IHN6ICkKKyAgICAgICAgYnJlYWs7CisgICAgICBzc2NhbmYod29yZHNbaV0sIiVkIix0KTsKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX2lkbGUiLCBNRSwgNjAqdCApOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlICJjaWNlcm9uZSI6CisgICAgY2FzZSAiY2ljZXJvbmVzIjoKKyAgICAgIC8vIGlzX2FjdGl2ZV9ndWlkZSgpIGlzdCBpbiAvc3RkL3BsYXllci9ndWlkZS5jCisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICMnaXNfYWN0aXZlX2d1aWRlKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAidGVzdGllIjoKKyAgICBjYXNlICJ0ZXN0aWVzIjoKKyAgICBjYXNlICJ0ZXN0c3BpZWxlciI6CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19wcm9wX3NldCIsIE1FLCBQX1RFU1RQTEFZRVIgKTsKKyAgICAgIGJyZWFrOworICAgICAgCisgICAgY2FzZSAiendlaXRpZSI6CisgICAgY2FzZSAiendlaXRpZXMiOgorICAgIGNhc2UgInp3ZWl0c3BpZWxlciI6CisgICAgICAgIGlmIChJU19MRUFSTkVSKHRoaXNfcGxheWVyKCkpKQorICAgICAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX3NlY29uZCIsIE1FLCAtMiApOworICAgICAgICBlbHNlCisgICAgICAgICAgendpID0gZmlsdGVyKCBvcmlnLCAiaXNfc2Vjb25kIiwgTUUsIC0xICk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgIm1hZ2llcnp3ZWl0aWUiOgorICAgIGNhc2UgIm1hZ2llcnp3ZWl0aWVzIjoKKyAgICBjYXNlICJtYWdpZXJ6d2VpdHNwaWVsZXIiOgorICAgICAgICBpZiAoSVNfQVJDSCh0aGlzX3BsYXllcigpKSkKKyAgICAgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19tYWdlX3NlY29uZCIpOworICAgICAgYnJlYWs7CisKKyAgICBjYXNlICJlcndhcnRldGUiOgorICAgICAgaWYgKCBpIDwgKHN6LTEpICYmIHdvcmRzW2krMV0gPT0gIndlZ2VuIiApIHsKKyAgICAgICAgaSsrOworCisgICAgICAgIGlmICggIW1hcHBpbmdwKHggPSAobWl4ZWQpdGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfV0FJVEZPUl9SRUFTT04pKSB8fAorICAgICAgICAgICAgICFwb2ludGVycCh4ID0gbV9pbmRpY2VzKHgpKSApCisgICAgICAgICAgYnJlYWs7CisgICAgICAgIAorICAgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19uYW1lX2luIiwgTUUsIHggKTsKKyAgICAgICAgYnJlYWs7CisgICAgICB9CisgICAgICAKKyAgICAgIGlmICggIXBvaW50ZXJwKHggPSAobWl4ZWQpdGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfV0FJVEZPUikpICkKKyAgICAgICAgYnJlYWs7CisgICAgICB6d2kgPSBmaWx0ZXIoIG9yaWcsICJpc19uYW1lX2luIiwgTUUsIHggKTsKKyAgICAgIGJyZWFrOworCisgICAgY2FzZSAiaWNxIjoKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX3Byb3Bfc2V0IiwgTUUsIFBfSUNRICk7CisgICAgICBicmVhazsKKworICAgIGNhc2UgInVybCI6CisgICAgY2FzZSAid3d3IjoKKyAgICAgIHp3aSA9IGZpbHRlciggb3JpZywgImlzX3Byb3Bfc2V0IiwgTUUsIFBfSE9NRVBBR0UgKTsKKyAgICAgIGJyZWFrOworICAgICAgICAgIAorICAgIGRlZmF1bHQ6CisgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgCisgICAgc3dpdGNoIChmKSB7CisgICAgY2FzZSAtMToKKyAgICAgIHJlcyAtPSB6d2k7CisgICAgICBicmVhazsKKyAgICAgIAorICAgIGNhc2UgMToKKyAgICAgIHJlcyAmPSB6d2k7CisgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICByZXMgKz0gendpOworICAgIH0KKyAgfQorICAKKyAgcmV0dXJuIHJlczsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3V0aWwvY2lkci5jIGIvc3RkL3V0aWwvY2lkci5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg1YTAwZTUKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdXRpbC9jaWRyLmMKQEAgLTAsMCArMSwyNiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLyoqIFxmaWxlIC9zdGQvdXRpbC9jaWRyLmMKKyogRnVua3Rpb25lbiB6dXIgSW50ZXJwcmV0YXRpb24gdW5kIFVtcmVjaG51bmcgdm9uIElQLUFkcmVzc2VuIGluIENJRFItTm90YXRpb24uCisqIFxhdXRob3IgWmVzc3RyYQorKiBcZGF0ZSAwNS4wMi4yMDEwCisqIFx2ZXJzaW9uICRJZCQKKyovCisvKiBDaGFuZ2Vsb2c6CisqLworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBub19zaGFkb3cKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworLy8gTmV2ZXIgZG8gdGhpcyBhdCBob21lLiA7LSkKKy8vIERlciBIaW50ZXJncnVuZCBpc3QsIGRhc3MgZGVyIE1hc3RlciBtb2VnbGljaHN0IHdlbmlnIENvZGUgdm9uIGF1c3NlcmhhbGIKKy8vIC9zZWN1cmUvIGVyYmVuL2lua2x1ZGllcmVuIHNvbGx0ZSwgaWNoIGFiZXIgbnVyIGFuIGVpbmVyIFN0ZWxsZSBBZW5kZXJ1bmdlbgorLy8gdm9ybmVobWVuIG1vZWNodGUuLi4KKyNkZWZpbmUgcHJpdmF0ZSBwdWJsaWMKKyNpbmNsdWRlICIvc2VjdXJlL21hc3Rlci9jaWRyLmMiCisjdW5kZWYgcHJpdmF0ZQorCisvL3N0cmluZyBJUHY0X3Rlc3Qoc3RyaW5nIGFkZHIpIHtyZXR1cm4gKElQdjRfaW50MmFkZHIoSVB2NF9hZGRyMmludChhZGRyKSkpO30KKwpkaWZmIC0tZ2l0IGEvc3RkL3V0aWwvZXguYyBiL3N0ZC91dGlsL2V4LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZWFlOWUyNwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC91dGlsL2V4LmMKQEAgLTAsMCArMSwyOTMgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB1dGlsL2V4LmMgLS0gZXggY29tcGF0aWJsZSBlZGl0b3IKKy8vCisvLyAkSWQ6IGV4LmMgOTE0MiAyMDE1LTAyLTA0IDIyOjE3OjI5WiBaZXNzdHJhICQKKworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorCitpbmhlcml0ICIvc3RkL3V0aWwvaW5wdXQiOworCitwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIGN0cmwgPSAoW10pOworcHJpdmF0ZSBub3NhdmUgbWl4ZWQgYnVmOworCisjaW5jbHVkZSA8c3lzX2RlYnVnLmg+CisjdW5kZWYgQVJHUworI2luY2x1ZGUgPHdpemxldmVscy5oPgorI2luY2x1ZGUgPHBsYXllci5oPgorCisjZGVmaW5lIE1PREUJMAorIyAgZGVmaW5lIENNRAkJMAorIyAgZGVmaW5lIElOUAkJMQorI2RlZmluZSBURVhUCTEKKyNkZWZpbmUgTElORQkyCisjZGVmaW5lIEZVTkMJMworI2RlZmluZSBBUkdTCTQKKyNkZWZpbmUgRkxBRwk1CisjICBkZWZpbmUgTlVNCQkxCisjZGVmaW5lIENIRwk2CisKKyNkZWZpbmUgWUFOSwkiQFlBTksiCisKK2ludCBldmFsdWF0ZShzdHJpbmcgaW4pOworCit2YXJhcmdzIGludCBlcnJvcihzdHJpbmcgbXNnLCBzdHJpbmcgYXJnKQoreworICBpZihzdHJpbmdwKGFyZykpIHdyaXRlKGFyZysiOiAiK21zZysiXG4iKTsKKyAgZWxzZSB3cml0ZShtc2crIlxuIik7Cit9CisKK3N0cmluZyBzdWJzdGl0dXRlKHN0cmluZyBzLCBzdHJpbmcgcmVnZXgsIHN0cmluZyBuLCBzdHJpbmcgZXh0cmEpCit7CisgIG1peGVkIGRlbDsgaW50IGk7CisgIGlmKChpID0gc2l6ZW9mKGRlbCA9IHJlZ2V4cGxvZGUocywgcmVnZXgpKSkgPCAyKSByZXR1cm4gczsKKyAgaWYobWVtYmVyKGV4dHJhLCAnZycpID09IC0xKSBpID0gMTsKKyAgZWxzZSBpIC09IDI7CisgIHdoaWxlKGk+MCkgeworICAgIGRlbFtpXSA9IG47CisgICAgaSAtPSAyOworICB9CisgIHJldHVybiBpbXBsb2RlKGRlbCwgIiIpOworfQorCisvLyBzYXZlVGV4dCgpIC0tIHNhdmUgZWRpdGVkIHRleHQKKy8vCitpbnQgc2F2ZVRleHQoKQoreworICBzdHJpbmcgdGV4dDsKKyAgdGV4dCA9IGltcGxvZGUoY3RybFtidWZdW1RFWFRdWzEuLl0sICJcbiIpKyJcbiI7CisgIGVycm9yKHNwcmludGYoIiVPLCAlZCBaZWlsZW4sICVkIFplaWNoZW4iLCAKKwkgICAgICAgYnVmID8gYnVmIDogIiIsIHNpemVvZihjdHJsW2J1Zl1bVEVYVF0pLTEsCisJICAgICAgIHNpemVvZih0ZXh0KSkpOworICBpZihjdHJsW2J1Zl1bRlVOQ10pIGFwcGx5KGN0cmxbYnVmXVtGVU5DXSwgY3RybFtidWZdW0FSR1NdLCB0ZXh0KTsKKyAgY3RybCA9IG1fY29weV9kZWxldGUoY3RybCwgYnVmKTsKKyAgY3RybCA9IG1fY29weV9kZWxldGUoY3RybCwgYnVmKyIhIik7CisgIGJ1ZiA9IDA7CisgIHJldHVybiAxOworfQorCisvLyBjbWRQcm9tcHQoKSAtLSBjcmVhdGUgY29tbWFuZCBwcm9tcHQKKy8vCitzdHJpbmcgY21kUHJvbXB0KGludCBtb2RlLCBtaXhlZCB0ZXh0LCBpbnQgbGluZSwgaW50IG1heGwpCit7CisgIHJldHVybiAiOiI7Cit9CisKKy8vIGlucHV0UHJvbXB0KCkgLS0gY3JlYXRlIGlucHV0IHByb21wdAorLy8KK3N0cmluZyBpbnB1dFByb21wdCgpCit7CisgIGlmKGN0cmxbYnVmXVtGTEFHXSAmIE5VTSkgcmV0dXJuIHNwcmludGYoIlslMDJkXSAiLCBjdHJsW2J1Zl1bTElORV0pOworICByZXR1cm4gIiI7Cit9CisKK3N0cmluZyBBZGROdW0oc3RyaW5nIHMpCit7CisgIHN0cmluZyByOworICByID0gaW5wdXRQcm9tcHQoKStzOworICBjdHJsW2J1Zl1bTElORV0rKzsKKyAgcmV0dXJuIHI7Cit9CisKK3ZvaWQgc2hvd0xpbmVzKGludCBmcm9tLCBpbnQgdG8pCit7CisgIHdyaXRlKGltcGxvZGUobWFwKGN0cmxbYnVmXVtURVhUXVtmcm9tLi50b10sICMnQWRkTnVtKSwgIlxuIikrIlxuIik7CisgIGN0cmxbYnVmXVtMSU5FXSA9IGZyb207Cit9CisKKy8vIGNvbW1hbmRNb2RlKCkgLS0gaGFuZGxlIGNvbW1hbmRzCisvLworaW50IGNvbW1hbmRNb2RlKHN0cmluZyBpbikKK3sKKyAgaW50IGZyb20sIHRvLCBzd2FwOworICBzdHJpbmcgY21kOworCisgIGlmKCFpbikgcmV0dXJuIDA7CisgIGlmKGluWzAuLjFdID09ICJzZSIpIHsKKyAgICBjdHJsW2J1Zl1bRkxBR10gXj0gTlVNOworICAgIHJldHVybiAwOworICB9CisgICAgCisgIGlmKHNzY2FuZihpbiwgIiVkLCVkJXMiLCBmcm9tLCB0bywgY21kKSAhPSAzKQorICAgIGlmKHNzY2FuZihpbiwgIiVkJXMiLCBmcm9tLCBjbWQpICE9IDIpCisgICAgICBpZighc3RyaW5ncChpbikpIHJldHVybiBlcnJvcigiS2VpbiBFZGl0b3Jrb21tYW5kbyIsIGluKTsKKyAgICAgIGVsc2UgeyBjbWQgPSBpbjsgZnJvbSA9IHRvID0gY3RybFtidWZdW0xJTkVdOyB9CisgICAgZWxzZSB0byA9IGZyb207CisKKyAgaWYoZnJvbSA8IDApIGZyb20gPSBzaXplb2YoY3RybFtidWZdW1RFWFRdKS0xK2Zyb207CisgIGlmKHRvIDwgMSkgdG8gPSBzaXplb2YoY3RybFtidWZdW1RFWFRdKS0xK3RvOworICBpZih0byAmJiB0byA8IGZyb20pIHJldHVybiBlcnJvcigiRXJzdGUgQWRyZXNzZSBncm9lc3NlciBhbHMgZGllIFp3ZWl0ZSIpOworICBpZihmcm9tKSBjdHJsW2J1Zl1bTElORV0gPSBmcm9tOworICBpZihmcm9tID4gc2l6ZW9mKGN0cmxbYnVmXVtURVhUXSktMSB8fAorICAgICB0byA+IHNpemVvZihjdHJsW2J1Zl1bVEVYVF0pLTEpIAorICAgIHJldHVybiBlcnJvcigiTmljaHQgc28gdmllbGUgWmVpbGVuIGltIFNwZWljaGVyIik7CisgIGlmKCF0bykgdG8gPSBmcm9tOworICBzd2l0Y2goY21kWzBdKQorICB7CisgIGNhc2UgJ2gnOgorICAgIHdyaXRlKCJleDogS29tbWFuZG9oaWxmZVxuXG4iCisJICJBbGxlIEtvbW1hbmRvcyBmdW5rdGlvbmllcmVuIG5hY2ggZm9sZ2VuZGVtIFByaW56aXA6XG4iCisJICJBZHJlc3NlIEtvbW1hbmRvIEFyZ3VtZW50ZVxuIgorCSAiQWRyZXNzZW4gd2VyZGVuIGdlYmlsZGV0IGR1cmNoOiBaZWlsZVZvbixaZWlsZUJpc1xuIgorCSAiKFplaWxlQmlzIGthbm4gd2VnZ2VsYXNzZW4gd2VyZGVuLCBzYW10IEtvbW1hKVxuIgorCSAiS29tbWFuZG9zOlxuIgorCSAiICBxLHggLS0gRWRpdG9yIHZlcmxhc3NlblxuIgorCSAiICByICAgLS0gRGF0ZWkgZWluZnVlZ2VuXG4iCisJICIgICAgICAgICByPGRhdGVpPlxuIgorCSAiICBhICAgLS0gVGV4dCBoaW50ZXIgZGVyIGFrdHVlbGxlbiBaZWlsZSBlaW5mdWVnZW5cbiIKKwkgIiAgaSAgIC0tIFRleHQgdm9yIGRlciBha3R1ZWxsZW4gWmVpbGUgZWluZnVlZ2VuXG4iCisJICIgIGQgICAtLSBaZWlsZW4gbG9lc2NoZW5cbiIKKwkgIiAgeSAgIC0tIFplaWxlbiB6d2lzY2hlbnNwZWljaGVyblxuIgorCSAiICBwdSAgLS0gWndpc2NoZW5nZXNwZWljaGVydGUgWmVpbGVuIGVpbmZ1ZWdlblxuIgorCSAiICBzICAgLS0gU3Vic3RpdHV0aW9uIHZvbiBUZXh0IGluIFplaWxlblxuIgorCSAiICAgICAgICAgcy9BbHRlclRleHQvTmV1ZXJUZXh0L1xuIgorICAgICAgICAgICIgIHAsbCAtLSBaZWlsZW4gYW56ZWlnZW5cbiIKKwkgIiAgeiAgIC0tIEVpbmUgU2VpdGUgYW56ZWlnZW5cbiIpOworICAgIGJyZWFrOworICBjYXNlICdxJzoKKyAgICBpZihjdHJsW2J1Zl1bQ0hHXSkKKyAgICAgIGlmKCEoc2l6ZW9mKGNtZCkgPiAxICYmIGNtZFsxXT09JyEnKSkKKyAgICAgICAgcmV0dXJuIGVycm9yKCJEYXRlaSB3dXJkZSBnZWFlbmRlcnQhIEFiYnJlY2hlbiBtaXQgcSEiKTsKKyAgICAgIGVsc2UgY3RybFtidWZdID0gY3RybFtidWYrIiEiXTsKKyAgY2FzZSAneCc6CisgICAgaWYoc2F2ZVRleHQoKSkgcmV0dXJuIDE7CisgIGNhc2UgJ3InOgorICAgIGlmKCFJU19XSVpBUkQodGhpc19wbGF5ZXIoKSkpCisgICAgICByZXR1cm4gZXJyb3IoIktvbW1hbmRvIGdlc3BlcnJ0IiwgY21kWzAuLjBdKTsKKyAgICBpZihmaWxlX3NpemUoY21kWzEuLl0pIDwgMCkgCisgICAgICByZXR1cm4gZXJyb3IoIkRhdGVpIG5pY2h0IGdlZnVuZGVuIiwgIlwiIitjbWRbMS4uXSsiXCIiKTsKKyAgICBjdHJsW2J1Zl1bVEVYVF0gPSBjdHJsW2J1Zl1bVEVYVF1bMC4uZnJvbV0gCisJCSAgKyBleHBsb2RlKHJlYWRfZmlsZShjbWRbMS4uXSksICJcbiIpCisJICAgICAgICAgICArIGN0cmxbYnVmXVtURVhUXVsoZnJvbSA9PSB0byA/IHRvKzEgOiB0bykuLl07CisgICAgY3RybFtidWZdW0NIR10gPSAxOworICAgIGJyZWFrOworICBjYXNlICdhJzoKKyAgICBjdHJsW2J1Zl1bTU9ERV0gPSBJTlA7CisgICAgd3JpdGUoIlRleHRlaW5nYWJlOiAoLiBiZWVuZGV0IHp1bSBLb21tYW5kb21vZHVzLCAqKiBiZWVuZGV0IGdhbnopXG4iKTsKKyAgICBpbnB1dCgjJ2lucHV0UHJvbXB0LCAwLCAjJ2V2YWx1YXRlKTsgCisgICAgY3RybFtidWZdW0NIR10gPSAxOworICAgIHJldHVybiAxOworICBjYXNlICdpJzoKKyAgICBjdHJsW2J1Zl1bTU9ERV0gPSBJTlA7CisgICAgY3RybFtidWZdW0xJTkVdLS07CisgICAgd3JpdGUoIlRleHRlaW5nYWJlOiAoLiBiZWVuZGV0IHp1bSBLb21tYW5kb21vZHVzLCAqKiBiZWVuZGV0IGdhbnopXG4iKTsKKyAgICBpbnB1dCgjJ2lucHV0UHJvbXB0LCAwLCAjJ2V2YWx1YXRlKTsKKyAgICBjdHJsW2J1Zl1bQ0hHXSA9IDE7CisgICAgcmV0dXJuIDE7CisgIGNhc2UgJ2QnOgorICAgIGN0cmxbYnVmXVtURVhUXVtmcm9tLi50b10gPSAoe30pOworICAgIGN0cmxbYnVmXVtDSEddID0gMTsKKyAgICBicmVhazsKKyAgY2FzZSAneSc6CisgICAgY3RybFtZQU5LXSA9IGN0cmxbYnVmXVtURVhUXVtmcm9tLi50b107CisgICAgaWYodG8gLSBmcm9tKSBlcnJvcih0by1mcm9tKzErIiBaZWlsZW4gZ2VzcGVpY2hlcnQiKTsKKyAgICBicmVhazsKKyAgY2FzZSAncyc6CisgIHsKKyAgICBtaXhlZCByZWcsIG5ldywgZXh0cmEsIHNjbWQ7CisgICAgaWYoc2l6ZW9mKHNjbWQgPSBvbGRfZXhwbG9kZShjbWRbMS4uXSwgY21kWzEuLjFdKSkgPCAyKQorICAgICAgcmV0dXJuIGVycm9yKCJTdWJzdGl0dXRpb24gZmVobGdlc2NobGFnZW4iKTsKKyAgICByZWcgPSBzY21kWzBdOyBuZXcgPSBzY21kWzFdOworICAgIGlmKHNpemVvZihzY21kKSA+IDIpIGV4dHJhID0gc2NtZFsyXTsKKyAgICBlbHNlIGV4dHJhID0gIiI7CisgICAgY3RybFtidWZdW1RFWFRdW2Zyb20uLnRvXSA9IG1hcChjdHJsW2J1Zl1bVEVYVF1bZnJvbS4udG9dLCAKKwkJCQkgICAgICAjJ3N1YnN0aXR1dGUsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnLCBuZXcsIGV4dHJhKTsKKyAgICBzaG93TGluZXMoZnJvbSwgdG8pOworICAgIGN0cmxbYnVmXVtDSEddID0gMTsKKyAgICBicmVhazsKKyAgfQorICBjYXNlICd6JzoKKyAgICBzaG93TGluZXMoY3RybFtidWZdW0xJTkVdLCAKKwkgICAgIGN0cmxbYnVmXVtMSU5FXSt0aGlzX3BsYXllcigpLT5RdWVyeVByb3AoUF9TQ1JFRU5TSVpFKSk7CisgICAgY3RybFtidWZdW0xJTkVdICs9IHRoaXNfcGxheWVyKCktPlF1ZXJ5UHJvcChQX1NDUkVFTlNJWkUpOworICAgIGJyZWFrOworICBjYXNlICdwJzoKKyAgICBpZihzaXplb2YoY21kKSA+IDEgJiYgY21kWzFdID09ICd1JykKKyAgICB7CisgICAgICBpZighcG9pbnRlcnAoY3RybFtZQU5LXSkpIHJldHVybiBlcnJvcigiS2VpbmUgWmVpbGVuIGltIFNwZWljaGVyIik7CisgICAgICBpZihmcm9tID49IGN0cmxbYnVmXVtMSU5FXSkgY3RybFtidWZdW1RFWFRdICs9IGN0cmxbWUFOS107CisgICAgICBlbHNlCisgICAgICAgIGN0cmxbYnVmXVtURVhUXVswLi5mcm9tXSArIGN0cmxbWUFOS10gKyBjdHJsW2J1Zl1bVEVYVF1bZnJvbSsxLi5dOworICAgICAgY3RybFtidWZdW0xJTkVdICs9IHNpemVvZihjdHJsW1lBTktdKTsKKyAgICAgIGN0cmxbWUFOS10gPSAwOworICAgICAgc2hvd0xpbmVzKGN0cmxbYnVmXVtMSU5FXSwgY3RybFtidWZdW0xJTkVdKTsKKyAgICAgIGJyZWFrOworICAgIH0KKyAgY2FzZSAnbCc6CisgIGRlZmF1bHQ6CisgICAgaWYoIWZyb20pIAorICAgIHsKKyAgICAgIGVycm9yKCJLZWluIEVkaXRvcmtvbW1hbmRvIiwgc3ByaW50ZigiJWMiLCBjbWRbMF0pKTsKKyAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBzaG93TGluZXMoZnJvbSwgdG8pOworICB9CisgIGlucHV0KCMnY21kUHJvbXB0LCAwLCAjJ2V2YWx1YXRlKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vIGlucHV0TW9kZSgpIC0tIGhhbmRsZSBpbnB1dCBtb2RlIGNvbW1hbmRzCisvLworaW50IGlucHV0TW9kZShzdHJpbmcgaW4pCit7CisgIHN3aXRjaChpbikKKyAgeworICBjYXNlICIuIjogCisgICAgY3RybFtidWZdW01PREVdID0gQ01EOworICAgIGN0cmxbYnVmXVtMSU5FXS0tOworICAgIGlucHV0KCMnY21kUHJvbXB0LCAwLCAjJ2V2YWx1YXRlKTsKKyAgICBicmVhazsKKyAgY2FzZSAiKioiOgorICAgIHJldHVybiBzYXZlVGV4dCgpOworICBkZWZhdWx0OgorICAgIGlmKCFpbikgLyogZG8gbm90aGluZyBub3cgKi87CisgICAgaWYoY3RybFtidWZdW0xJTkVdIDwgc2l6ZW9mKGN0cmxbYnVmXVtURVhUXSktMSkKKyAgICAgIGN0cmxbYnVmXVtURVhUXSA9IGN0cmxbYnVmXVtURVhUXVswLi5jdHJsW2J1Zl1bTElORV0tMV0gKyAoeyBpbiB9KSAKKwkgICAgICAgICsgY3RybFtidWZdW1RFWFRdW2N0cmxbYnVmXVtMSU5FXS4uXTsKKyAgICBlbHNlIGN0cmxbYnVmXVtURVhUXSArPSAoeyBpbiB9KTsKKyAgICBjdHJsW2J1Zl1bTElORV0rKzsKKyAgICBpbnB1dCgjJ2lucHV0UHJvbXB0LCAwLCAjJ2V2YWx1YXRlKTsKKyAgICBicmVhazsKKyAgfQorICByZXR1cm4gMTsKK30KKworLy8gZXZhbHVhdGUoKSAtLSBldmFsdWF0ZSBpbnB1dCAoaW4pIGluIGNvbnRleHQgKGN0cmxbYnVmXSkKKy8vCitpbnQgZXZhbHVhdGUoc3RyaW5nIGluKQoreworICBzd2l0Y2goY3RybFtidWZdW01PREVdKQorICB7CisgICAgY2FzZSBJTlA6IHJldHVybiBpbnB1dE1vZGUoaW4pOworICAgIGNhc2UgQ01EOiByZXR1cm4gY29tbWFuZE1vZGUoaW4pOworICAgIGRlZmF1bHQgOiByZXR1cm4gMDsKKyAgfQorfQorCit2b2lkIFN0YXJ0RVgoc3RyaW5nIGluLCBtaXhlZCBjKQoreworICBpZighaW4gfHwgaW4gPT0gImoiIHx8IGluID09ICJKIikgY3RybFtidWZdID0gYzsKKyAgZWxzZSBpZihpbiAmJiAoaW4gIT0gIm4iICB8fCBpbiAhPSAiTiIpKQorICAgIHJldHVybiAwOworICBjdHJsW2J1ZisiISJdID0gY3RybFtidWZdOworICBpbnB1dCgjJ2NtZFByb21wdCwgMCwgIydldmFsdWF0ZSk7Cit9CisKK3ZhcmFyZ3MgaW50IGV4KG1peGVkIHRleHQsIGNsb3N1cmUgZnVuYywgbWl4ZWQgZmFyZ3MsIHN0cmluZyBidWZmZXIpCit7CisgIGludCBjLCBsOworICBtaXhlZCBjdDsKKyAgaWYoIXRleHQpIHRleHQgPSAiIjsKKyAgYyA9IHNpemVvZih0ZXh0KTsKKyAgbCA9IHNpemVvZih0ZXh0ID0gZXhwbG9kZSh0ZXh0LCAiXG4iKSkgLSAxOworICBjdCA9ICh7IENNRCwgdGV4dCwgMCwgZnVuYywgZmFyZ3MsIDAsIDB9KTsKKyAgaWYoIWN0cmxbYnVmZmVyXSkgU3RhcnRFWCgwLCBjdCk7CisgIGVsc2UgaW5wdXQoc3ByaW50ZigiRXMgZXhpc3RpZXJ0IGJlcmVpdHMgVGV4dCEgVmVyd2VyZmVuPyBbal0iKSwKKwkgICAgMCwgIydTdGFydEVYLCBjdCk7CisgIHJldHVybiAxOworfQpkaWZmIC0tZ2l0IGEvc3RkL3V0aWwvZXhlY3V0ZXIuYyBiL3N0ZC91dGlsL2V4ZWN1dGVyLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNGUwZjcwNwotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC91dGlsL2V4ZWN1dGVyLmMKQEAgLTAsMCArMSwzOSBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHV0aWxzL2V4ZWN1dGVyLmMgLSBIZWxmZXIgenVtIEF1c2Z1ZWhyZW4gdm9tIEtyYW0KKy8vCisvLyAkSWQ6IHNraWxscy5jIDY2NzMgMjAwOC0wMS0wNSAyMDo1Nzo0M1ogWmVzc3RyYSAkCisjcHJhZ21hIHN0cmljdF90eXBlcworI3ByYWdtYSBzYXZlX3R5cGVzCisjcHJhZ21hIHJhbmdlX2NoZWNrCisjcHJhZ21hIG5vX2Nsb25lCisjcHJhZ21hIHBlZGFudGljCisKK3Byb3RlY3RlZCBtaXhlZCBleGVjdXRlX2FueXRoaW5nKG1peGVkIGZ1biwgdmFyYXJncyBtaXhlZCBhcmdzKQoreworICBpZiAoIGNsb3N1cmVwKGZ1bikgJiYgb2JqZWN0cChxdWVyeV9jbG9zdXJlX29iamVjdChmdW4pKSApCisgICAgcmV0dXJuIGFwcGx5KGZ1biwgYXJncyk7CisKKyAgaWYgKHN0cmluZ3AoZnVuKSkKKyAgICByZXR1cm4gY2FsbF9vdGhlcih0aGlzX29iamVjdCgpLCBmdW4sIGFyZ3MuLi4pOworCisgIGlmICggcG9pbnRlcnAoZnVuKSAmJiBzaXplb2YoZnVuKT09MiApCisgIHsKKyAgICBvYmplY3Qgb2I7CisgICAgaWYgKHNpemVvZihmdW4pPjIpCisgICAgICByYWlzZV9lcnJvcihzcHJpbnRmKCJleGVjdXRlX2FueXRoaW5nKCk6IGZpcnN0IGFyZ3VtZW50IG1heSBvbmx5ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiaGF2ZSAyIGVsZW1lbnRzIGlmIGFycmF5LlxuIikpOworCisgICAgaWYgKCBzdHJpbmdwKGZ1blswXSkgKQorICAgICAgb2I9ZmluZF9vYmplY3QoZnVuWzBdKTsKKyAgICBlbHNlCisgICAgICBvYj1mdW5bMF07CisKKyAgICBpZiAoICFvYmplY3RwKG9iKSB8fCAhc3RyaW5ncChmdW5bMV0pICkKKyAgICAgIHJldHVybiAwOworCisgICAgcmV0dXJuIGNhbGxfb3RoZXIob2IsIGZ1blsxXSwgYXJncy4uLik7CisgIH0KKyAgcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC91dGlsL2lucHV0LmMgYi9zdGQvdXRpbC9pbnB1dC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2NWJjODQKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvdXRpbC9pbnB1dC5jCkBAIC0wLDAgKzEsMzEgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB1dGlsL2lucHV0LmMgLS0gZ2VuZXJpYyBpbnB1dCBoYW5kbGluZworLy8KKy8vICRJZDogaW5wdXQuYyA4MzQ5IDIwMTMtMDItMDQgMjE6MTU6MjhaIFplc3N0cmEgJAorCisjaW5jbHVkZSA8aW5wdXRfdG8uaD4KKworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorCit2YXJhcmdzIHZvaWQgaW5wdXQobWl4ZWQgcHJvbXB0LCBtaXhlZCBwYXJncywgbWl4ZWQgY3RybCwgbWl4ZWQgY3RybGFyZ3MpCit7CisgIG1peGVkIHByb21wdHRleHQ7CisgIGlmKGNsb3N1cmVwKHByb21wdCkpCisgICAgcHJvbXB0dGV4dCA9IGFwcGx5KHByb21wdCwgcG9pbnRlcnAocGFyZ3MpID8gcGFyZ3MgOiAoe30pKTsKKyAgZWxzZSBwcm9tcHR0ZXh0ID0gcHJvbXB0OworICBpZiAoIXN0cmluZ3AocHJvbXB0dGV4dCkpIHByb21wdHRleHQ9IiI7CisgIGlucHV0X3RvKCJkb25lIiwgSU5QVVRfUFJPTVBULCBwcm9tcHR0ZXh0LCBwcm9tcHQsIHBhcmdzLCBjdHJsLCBjdHJsYXJncyk7Cit9CisKK3ZvaWQgZG9uZShzdHJpbmcgaW4sIG1peGVkIHByb21wdCwgbWl4ZWQgcGFyZ3MsIG1peGVkIGN0cmwsIG1peGVkIGN0cmxhcmdzKQoreworICBpZihjbG9zdXJlcChjdHJsKSAmJgorICAgICBhcHBseShjdHJsLCAoeyBpbiB9KSArIChwb2ludGVycChjdHJsYXJncykgPyBjdHJsYXJncyA6ICh7fSkpKSkgCisgICAgcmV0dXJuOworICBpbnB1dChwcm9tcHQsIHBhcmdzLCBjdHJsLCBjdHJsYXJncyk7Cit9CmRpZmYgLS1naXQgYS9zdGQvdXRpbC9wYWdlci5jIGIvc3RkL3V0aWwvcGFnZXIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZDcxYjg1Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3V0aWwvcGFnZXIuYwpAQCAtMCwwICsxLDE0MiBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHV0aWwvcGFnZXIuYyAtLSBnZW5lcmljIHBhZ2VyCisvLworLy8gJElkOiBwYWdlci5jIDg3NTUgMjAxNC0wNC0yNiAxMzoxMzo0MFogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKworaW5oZXJpdCAiL3N0ZC91dGlsL2lucHV0IjsKKworI2luY2x1ZGUgPHBhZ2VyLmg+CisjaW5jbHVkZSA8c3lzX2RlYnVnLmg+CisjaW5jbHVkZSA8d2l6bGV2ZWxzLmg+CisKK3N0cmluZyBwcm9tcHQobWl4ZWQgcGluZm8sIHN0cmluZyBhZGQpCit7CisgIHJldHVybiBzcHJpbnRmKE1TR19QUk9NUFQrIiVzIiwgc3RyaW5ncChhZGQpP2FkZDoiIik7Cit9CisKK3N0cmluZyBmcmVhZChtaXhlZCBwaW5mbywgaW50IGJlZ2luLCBpbnQgYykKK3sKKyAgaWYoYmVnaW4gPiBwaW5mb1tNQVhMXSB8fCBiZWdpbiA8IDEpIHJldHVybiAwOworICBpZihwaW5mb1tGSUxFXSkgcmV0dXJuIHJlYWRfZmlsZShwaW5mb1tURVhUXSwgYmVnaW4sIGMpOworICBlbHNlCisgIHsKKyAgICBpbnQgc3RhcnQsIGVuZCwgbCwgeDsKKworICAgIGlmKG1lbWJlcihwaW5mb1tKVU5LXSwgYmVnaW4pKSAKKyAgICB7CisgICAgICBzdGFydCA9IHBpbmZvW0pVTktdW2JlZ2luXTsKKyAgICAgIGlmKCEoZW5kID0gcGluZm9bSlVOS11bYmVnaW4rY10pKQorICAgICAgICBlbmQgPSBzaXplb2YocGluZm9bVEVYVF0pOworICAgICAgZWxzZSBlbmQtLTsKKyAgICAgIHJldHVybiBwaW5mb1tURVhUXVtzdGFydC4uZW5kXTsKKyAgICB9CisgICAgcmV0dXJuIDA7CisgIH0KK30KKworbWl4ZWQgY2FsbChjbG9zdXJlIGN0cmwsIG1peGVkIGN0cmxhcmdzKQoreworICBpZiAoIWN0cmx8fCFjbG9zdXJlcChjdHJsKSkgcmV0dXJuIDA7CisgIGlmKCFwb2ludGVycChjdHJsYXJncykpIHJldHVybiBmdW5jYWxsKGN0cmwpOworICByZXR1cm4gYXBwbHkoY3RybCwgY3RybGFyZ3MpOworfQorCisgCit2YXJhcmdzIGludCBldmFsX2NvbW1hbmQobWl4ZWQgaW4sIG1peGVkIHBpbmZvKQoreworICBzdHJpbmcgY3Byb21wdCwgdG1wOworICBjcHJvbXB0ID0gIiI7CisgIGlmKGluID09ICJxIiB8fCBpbiA9PSAieCIpCisgIHsKKyAgICBpZihjbG9zdXJlcChwaW5mb1tDVFJMXSkpIGFwcGx5KHBpbmZvW0NUUkxdLCBwaW5mb1tDQVJHXSk7CisgICAgcmV0dXJuIDE7CisgIH0KKyAgZWxzZQorICAgIGlmKCFpbiB8fCAoc3RyaW5ncChpbikgJiYgIXNpemVvZihpbikpKSBwaW5mb1tDVVJMXSArPSBwaW5mb1tQQUdFXTsKKyAgICBlbHNlIGlmKGluICE9IC0xKSByZXR1cm4gMDsKKworICBpZihwaW5mb1tDVVJMXSA+PSBwaW5mb1tNQVhMXSkgCisgICAgcmV0dXJuIChjYWxsKHBpbmZvW0NUUkxdLCBwaW5mb1tDQVJHXSksIDEpOyAKKyAgaWYocGluZm9bQ1VSTF0gPD0gMCkgcGluZm9bQ1VSTF0gPSAxOworICBpZihwaW5mb1tDVVJMXSA9PSAxKSBjcHJvbXB0ID0gTVNHX1RPUDsKKyAgaWYocGluZm9bQ1VSTF0gKyBwaW5mb1tQQUdFXSA+PSBwaW5mb1tNQVhMXSkgY3Byb21wdCA9IE1TR19CT1RUT007CisgIGlmKCF0bXAgPSBmcmVhZChwaW5mbywgcGluZm9bQ1VSTF0sIHBpbmZvW1BBR0VdKSkKKyAgICByZXR1cm4gMDsgLyogKHdyaXRlKE1TR19PT1BTKyJcbiIpLCAwKTsgKi8KKyAgaWYgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkpCisgICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksIHRtcCk7CisgIGVsc2Ugd3JpdGUodG1wKTsKKyAgaWYoIShwaW5mb1tGTEFHXSAmIEVfUFJPTVBUKSAmJgorICAgICAocGluZm9bQ1VSTF0gKyBwaW5mb1tQQUdFXSA+PSBwaW5mb1tNQVhMXSB8fCAhcGluZm9bUEFHRV0pKQorICAgIHJldHVybiAoY2FsbChwaW5mb1tDVFJMXSwgcGluZm9bQ0FSR10pLCAxKTsKKyAgaWYoIShwaW5mb1tGTEFHXSAmIEVfQ0FUKSAmJgorICAgICAocGluZm9bTUFYTF0gPiBwaW5mb1tQQUdFXSB8fCAocGluZm9bRkxBR10gJiBFX1BST01QVCkpKQorICAgIGlucHV0KCMncHJvbXB0LCAoeyBwaW5mbywgY3Byb21wdCB9KSwgIydldmFsX2NvbW1hbmQsICh7IHBpbmZvIH0pKTsKKyAgcmV0dXJuIDE7Cit9CisKK3ZhcmFyZ3MgcHVibGljIHZvaWQgTW9yZShzdHJpbmcgdHh0LCBpbnQgZmlsZSwKKwkJCSBtaXhlZCBjdHJsLCBtaXhlZCBjdHJsYXJncywKKwkJCSBpbnQgZmxhZ3MpCit7CisgIGludCBqOworICBtaXhlZCB0bXAsIHBpbmZvOworICBpZighdHh0KSByZXR1cm4gY2FsbChjdHJsLCBjdHJsYXJncyk7CisgIC8vICAgICAgICAgVEVYVCwgRklMRSwgQ1VSTCwgTUFYTCwgUkVHWCwgUEFHRSwgQ1RSTCwgQ0FSRworICBwaW5mbyA9ICh7IHR4dCwgZmlsZSwgMSwgMSwgMjAsIDAsIGN0cmwsIGN0cmxhcmdzLCBmbGFncyB9KTsKKworICBpZiAocGluZm9bRklMRV0pCisgIHsgCisgICAgIGlmIChmaWxlX3NpemUocGluZm9bVEVYVF0pPDUwMDAwKQorICAgICB7CisgICAgICAgcGluZm9bVEVYVF09cmVhZF9maWxlKHBpbmZvW1RFWFRdKTsKKyAgICAgICBpZiAoIXBpbmZvW1RFWFRdKQorICAgICAgIHsgCisgICAgICAgICBjYWxsKGN0cmwsIGN0cmxhcmdzKTsKKyAgICAgICAgIHJldHVybjsKKyAgICAgICB9ICAKKyAgICAgICBwaW5mb1tGSUxFXT0wOworICAgICB9CisgICAgIGVsc2UgaWYgKGZpbGVfc2l6ZShwaW5mb1tURVhUXSk+MTA0ODU3NikKKyAgICAgeworCXRlbGxfb2JqZWN0KHRoaXNfcGxheWVyKCl8fHRoaXNfb2JqZWN0KCksYnJlYWtfc3RyaW5nKHNwcmludGYoCisgICAgICAgICAgICAgICAiRGllIERhdGVpICclcycga2FubiBuaWNodCBhbmdlemVpZ3Qgd2VyZGVuLCBkYSAiIAorICAgICAgICAgICAgICAgInNpZSBncm9lc3NlciBhbHMgMSBNQiBpc3QuICVzIixwaW5mb1tURVhUXSwKKyAgICAgICAgICAgICAgIElTX0xFQVJORVIodGhpc19wbGF5ZXIoKXx8dGhpc19vYmplY3QoKSk/IiI6IkJpdHRlIHZlcnN0YWVuZGlnZSAiCisgICAgICAgICAgICAgICAiZGllc2JlenVlZ2xpY2ggdW1nZWhlbmQgZWluZW4gTWFnaWVyLiIpLDc4KSk7CisJY2FsbChjdHJsLGN0cmxhcmdzKTsKKyAgICAgICAgcmV0dXJuOworICAgICB9CisgIH0KKworICBpZighcGluZm9bRklMRV0gJiYgcGluZm9bVEVYVF1bPDEuLjwxXSAhPSAiXG4iKSBwaW5mb1tURVhUXSArPSAiXG4iOworICBwaW5mbyArPSAoeyAoWzE6MF0pIH0pOworICBpZighcGluZm9bRklMRV0pIAorICAgIHdoaWxlKChqID0gc3Ryc3RyKHBpbmZvW1RFWFRdLCAiXG4iLCBqKzEpKSAhPSAtMSkKKyAgCXBpbmZvW0pVTktdWysrcGluZm9bTUFYTF1dID0gaisxOworICBlbHNlCisgICAgd2hpbGUodG1wID0gcmVhZF9maWxlKHBpbmZvW1RFWFRdLCBwaW5mb1tNQVhMXSwgTUFYX0xJTkVfUkVBRCkpCisgICAgICBwaW5mb1tNQVhMXSArPSBzaXplb2YoZXhwbG9kZSh0bXAsICJcbiIpKSsxOworICBwaW5mb1tQQUdFXSA9IFBBR0VMRU5HVEg7CisgIGlmKCFwaW5mb1tQQUdFXSkgcGluZm9bRkxBR10gfD0gRV9DQVQ7CisgIGlmICgodGhpc19pbnRlcmFjdGl2ZSgpICYmIChqPShpbnQpdGhpc19pbnRlcmFjdGl2ZSgpLT5RdWVyeVByb3AoUF9NT1JFX0ZMQUdTKSkpIHx8CisgICAgICAodGhpc19wbGF5ZXIoKSAmJiBpbnRlcmFjdGl2ZSh0aGlzX3BsYXllcigpKSAmJgorICAgICAgIChqPShpbnQpdGhpc19wbGF5ZXIoKS0+UXVlcnlQcm9wKFBfTU9SRV9GTEFHUykpKSkKKyAgICBwaW5mb1tGTEFHXSB8PSBqOworICAKKyAgcGluZm9bQ1VSTF0gPSAxOworICBldmFsX2NvbW1hbmQoLTEsIHBpbmZvKTsKKyAgcmV0dXJuOworfQorCisKKworCisKKwpkaWZmIC0tZ2l0IGEvc3RkL3V0aWwvcGxfaXRlcmF0b3IuYyBiL3N0ZC91dGlsL3BsX2l0ZXJhdG9yLmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNTU1YTc1ZQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC91dGlsL3BsX2l0ZXJhdG9yLmMKQEAgLTAsMCArMSw1MyBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLyoqIFxmaWxlIC9maWxlLmMKKyogS3VyemJlc2NocmVpYnVuZy4KKyogTGFuZ2Jlc2NocmVpYnVuZy4uLgorKiBcYXV0aG9yIDxBdXRvcj4KKyogXGRhdGUgPGRhdGU+CisqIFx2ZXJzaW9uICRJZCQKKyovCisvKiBDaGFuZ2Vsb2c6CisqLworI3ByYWdtYSBzdHJvbmdfdHlwZXMsIHNhdmVfdHlwZXMsIHJ0dF9jaGVja3MKKyNwcmFnbWEgbm9fY2xvbmUsIG5vX3NoYWRvdworI3ByYWdtYSBwZWRhbnRpYywgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgd2Fybl9kZXByZWNhdGVkCisKK3ByaXZhdGUgdm9pZCBjaGVja19hbGxfcGxheWVyKG1hcHBpbmcgYWxscGxheWVyLCBjbG9zdXJlIGNoZWNrX2NsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9zdXJlIGZpbmlzaF9jbCwgaW50IHJlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyYXJncyBtaXhlZCBleHRyYSkKK3sKKyAgLy8gb2ZmZW5iYXIgZmVydGlnIG1pdCBhbGxlbiBTcGllbGVybiwgQXVmcnVmZXIgaW5mb3JtaWVyZW4uCisgIGlmICghc2l6ZW9mKGFsbHBsYXllcikpCisgIHsKKyAgICBmdW5jYWxsKGZpbmlzaF9jbCwgZXh0cmEuLi4pOworICAgIHJldHVybjsKKyAgfQorCisgIHN0cmluZyBkaXI9bV9pbmRpY2VzKGFsbHBsYXllcilbMF07CisgIHN0cmluZyAqcGxzPWFsbHBsYXllcltkaXJdOworICBmb3JlYWNoKHN0cmluZyBwbDogJnBscykKKyAgeworICAgIGlmIChnZXRfZXZhbF9jb3N0KCkgPCByZXMpCisgICAgICBicmVhazsgLy8gc3BhZXRlciB3ZWl0ZXJtYWNoZW4KKyAgICBjYXRjaChmdW5jYWxsKGNoZWNrX2NsLCBwbCwgZXh0cmEuLi4pIDsgcHVibGlzaCk7CisgICAgcGwgPSAwOworICB9CisgIHBscy09KHswfSk7CisgIGFsbHBsYXllcltkaXJdID0gcGxzOworCisgIGlmICghc2l6ZW9mKGFsbHBsYXllcltkaXJdKSkKKyAgICBtX2RlbGV0ZShhbGxwbGF5ZXIsZGlyKTsKKworICBjYWxsX291dCgjJ2NoZWNrX2FsbF9wbGF5ZXIsMiwgYWxscGxheWVyLCBjaGVja19jbCwgZmluaXNoX2NsLCByZXMsIGV4dHJhLi4uKTsKK30KKworcHJvdGVjdGVkIGludCBzdGFydF9wbGF5ZXJfY2hlY2soY2xvc3VyZSBjaGVja19jbCwgY2xvc3VyZSBmaW5pc2hfY2wsIGludCByZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcmFyZ3MgbWl4ZWQgZXh0cmEpCit7CisgIHJlcyB8fD0gMTI1MDAwMDsKKyAgbWFwcGluZyBhbGxwbGF5ZXI9KG1hcHBpbmcpbWFzdGVyKCktPmdldF9hbGxfcGxheWVycygpOworICBjYWxsX291dCgjJ2NoZWNrX2FsbF9wbGF5ZXIsMiwgYWxscGxheWVyLCBjaGVja19jbCwgZmluaXNoX2NsLCByZXMsIGV4dHJhLi4uKTsKKyAgcmV0dXJuIDE7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC91dGlsL3JhbmQtZ2xmc3IuYyBiL3N0ZC91dGlsL3JhbmQtZ2xmc3IuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YmQ2MjRjCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3V0aWwvcmFuZC1nbGZzci5jCkBAIC0wLDAgKzEsMTU1IEBACisvKiBEaWVzZXMgRmlsZSBpbXBsZW1lbnRpZXJ0IGVpbmVuIFBzZXVkby1adWZhbGxzemFobGVuZ2VuZXJhdG9yIG1pdCBlaW5lbQorICogTGluZWFyIEZlZWRiYWNrIFNoaWZ0IFJlZ2lzdGVyIGluIGRlciBHYWxvaXMtVmFyaWFudGUuCisgKiBEaWVzZXMgUFJORyBpc3Qgc2NobGVjaHRlciB1bmQgdmllbCBpbmVmZml6aWVudGVyIGFscyBkZXIgaW0gRHJpdmVyCisgKiBlaW5nZWJhdXRlLgorICogRGllIGVpbnppZ2Ugc2lubnZvbGxlIEFud2VuZHVuZyBpc3QsIHdlbm4gbWFuIGF1cyBpcmdlbmRlaW5lbSBHcnVuZCBkYXMKKyAqIHNlZWQgc2VsYmVyIHdhZWhsZW4gbXVzcywgZGFtaXQgbWFuIGRpZSBTZXF1ZW56IHZvbiBQc2V1ZG96dWZhbGwgaW1tZXIKKyAqIHdpZWRlciByZXByb2R1emllcmVuIGthbm4uCisgKgorICogRGFzIFNlZWQgdm9uIGRlciBCbHVlcHJpbnQgd2lyZCB2ZXJtdXRsaWNoIHN0YWVuZGlnIHZlcmFlbmRlcnQgKGQuaC4KKyAqIHZlcmxhc3N0IGV1Y2ggbmljaHQgZHJhdWYsIGRhc3MgZXMga29uc3RhbnQgYmxlaWJ0KSwgd29sbHQgaWhyIGVpbmUKKyAqICdwcml2YXRlJyBJbnN0YW56IG1pdCBldXJlbSBTZWVkLCBjbG9udCBkYXMgT2JqZWt0IChhYmVyIHZlcmxpZXJ0IGRlbiBDbG9uZQorICogbmljaHQpLgorICoKKyAqIEVzIHdpcmQgc3RhbmRhcmRtYWVzc2lnIGVpbiBQb2x5bm9tIGZ1ZXIgZWluZSBQZXJpb2RlbmxhZW5nZSB2b24gMl4zMiAtIDEKKyAqIHZlcndlbmRldC4KKyAqIAorICogSW0gTmV0eiBmaW5kZW4gc2ljaCBJbmZvcyB1ZWJlciBMRlNScyB1bmQgVGFiZWxsZW4gZnVlciBtYXhpbXVtLWxlbmd0aAorICogZmVlZGJhY2sgcG9seW5vbWlhbHMgKE0tU2VxdWVuY2UgRmVlZGJhY2sgVGFwcyksIGZhbGxzIGplbWFuZCBicmF1Y2h0LgorICoKKyovCisjcHJhZ21hIHN0cm9uZ190eXBlcyxydHRfY2hlY2tzLHBlZGFudGljCisKKyNpbmNsdWRlIDx0bHMuaD4KKworLy8gRGVmYXVsdC1Qb2x5bm9tIGlzdCBkYXM6CisvLyB4XjMyICsgeF4zMSArIHheMjggKyB4XjI3ICsgeF4yNCArIHheMjMgKyB4XjIwICsgeF4xOSArIHheMTYgKyB4XjE1ICsgeF4xMgorLy8gICAgICArIHheMTEgKyB4XjggKyB4XjcgKyB4XjUgKyB4XjMgKyAxCisvLyBUYXBzOiAzMiwgMzEsIDI4LCAyNywgMjQsIDIzLCAyMCwgMTksIDE2LCAxNSwgMTIsIDExLCA4LCA3LCA1LCAzCisvLyBCaW5hcnk6IDExMDAxMTAwMTEwMDExMDAxMTAwMTEwMDExMDEwMTAwMAorI2RlZmluZSBERUZBVUxUUCAweDE5OTk5OTlhOAorLy8gQW5kZXJlIGdlYnJhZXVjaGxpY2hlOgorLy8geF4zMiArIHheMzAgKyB4XjI2ICsgeF4yNSArIDEsCisvLyBUYXBzIDMyLCAzMCwgMjYsIDI1CisvLyBCaW5hcnk6IDEwMTAwMDExMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAorLy8jZGVmaW5lIERFRkFVTFRQIDB4MTQ2MDAwMDAwCisvLyB4XjE2ICsgeF4xNCArIHheMTMgKyB4XjExICsgMQorLy8gVGFwcyAxNiwgMTQsIDEzLCAxMQorLy8gQmluYXJ5OiAxMDExMDEwMDAwMDAwMDAwCisvLyNkZWZpbmUgREVGQVVMVFAgMHhCNDAwCisKK3ByaXZhdGUgaW50IHBvbHlub20gPSBERUZBVUxUUDsKK3ByaXZhdGUgaW50IHN0YXRlID0gMjU1MzY0NzIyMzsKKy8vcHJpdmF0ZSBpbnQgcGVyaW9kOworCitwdWJsaWMgdmFyYXJncyB2b2lkIGluaXQoaW50IHNlZWQsIGludCBuZXdwKQoreworICBpZiAoIXNlZWQpCisgICAgcmFpc2VfZXJyb3IoIklsbGVnYWwgc2VlZCAwXG4iKTsKKyAgLy8gRXMgZGFyZiBudXIgZWluIDMyIGJpdCBicmVpdGVyIFNlZWQgdmVyd2VuZGV0IHdlcmRlbi4gRGllIG9iZXJlbiAzMiBiaXQKKyAgLy8gd2VyZGVuIG1pdCBkZW4gdW50ZXJlbiAzMiBiaXQgWE9SLXJ0IChhbHNvLCBlaW5tYWwgZGllIG9iZXJlbiAzMiBzaGlmdGVuCisgIC8vIHVuZCBlaW5tYWwgZGllIG9iZXJlbiAzMiB3ZWdtYXNraWVyZW4uCisgIHNlZWQgPSAoKHNlZWQ+PjMyKSAmIDB4ZmZmZmZmZmYpIF4gKHNlZWQgJiAweGZmZmZmZmZmKTsKKyAgLy9wcmludGYoIlNlZWQ6ICUwNjRiIC0gMHgleFxuIixzZWVkLHNlZWQpOworICAKKyAgaWYgKCFzZWVkKQorICAgIHJhaXNlX2Vycm9yKCJJbGxlZ2FsIHJlZHVjZWQgc2VlZDogMFxuIik7CisKKyAgc3RhdGUgPSBzZWVkOworICBwb2x5bm9tID0gbmV3cCB8fCBERUZBVUxUUDsKK30KKworcHVibGljIHZvaWQgSW5pdFdpdGhVVUlEKHN0cmluZyB1dWlkKQoreworICBzdHJpbmcgbWQ1aGFzaCA9IGhhc2goVExTX0hBU0hfTUQ1LCB1dWlkKTsKKyAgaW50IHNlZWQ7CisgIC8vIDggQnl0ZXMgYXVzIGRlbSBIYXNoIGVybWl0dGVsbgorICBmb3JlYWNoKGludCBiOiAxNikKKyAgeworICAgIC8vIEpld2VpbHMgendlaSBaZWljaGVuIGhlcmF1c3NjaG5laWRlbiB1bmQgYWxzIEhleGFkZXppbWFsemFobAorICAgIC8vIGludGVycHJldGllcmVuLCB3YXMgamV3ZWlscyBlaW4gYnl0ZSAoOCBiaXQpIGdpYnQuIAorICAgIGludCB0bXAgPSB0b19pbnQoIjB4IittZDVoYXNoW2IqMi4uYioyKzFdKTsKKyAgICAvLyBkaWVzZSB3ZXJkZW4gZGFubiBpbiBlaW5lIDY0IGJpdCBicmVpdGUgWmFobCB6dXNhbW1lbmdlZmFzc3QuIERhcworICAgIC8vIGdlcmFkZSBlcm1pdHRlbHRlIEJ5dGUgd2lyZCBuYWNoIGxpbmtzIGdlc2hpZnRldCB1bmQgbWl0IGRlbSwgd2FzIGRhCisgICAgLy8gZ2dmLiBzY2hvbiBzdGVodCwgWE9ScmVkLiBJc3QgZGVyIGludCB2b2xsLCBmYWVuZ3QgbWFuIHdlZ2VuIE1vZHVsbyA2NAorICAgIC8vIHdpZWRlciByZWNodHMgYW4uCisgICAgLy9wcmludGYoIlM6ICUwNjRiIC0gJTA4YlxuIixzZWVkLHRtcCk7CisgICAgc2VlZCA9IHNlZWQgXiAodG1wIDw8ICgoYio4KSU2NCkpOworICAgIC8vcHJpbnRmKCJTOiAlMDY0YiAtIDB4JXhcbiIsc2VlZCwgc2VlZCk7CisgIH0KKyAgLy9wcmludGYoIlNlZWQ6IDB4JXggLSAlYlxuIixzZWVkLHNlZWQpOworICBpbml0KHNlZWQpOworfQorCitwdWJsaWMgaW50IG5leHRiaXQoKQoreworICAvLyBHZXQgTFNCIChpLmUuLCB0aGUgb3V0cHV0IGJpdCkuCisgIGludCBsc2IgPSBzdGF0ZSAmIDE7CisgIC8vIFNoaWZ0IHJlZ2lzdGVyIGJ5IG9uZSBiaXQKKyAgc3RhdGUgPj49IDE7CisgIC8vIEFwcGx5IGEgdG9nZ2xlIG1hc2ssIHdoaWNoIGZsaXBzIGFsbCB0aGUgdGFwIGJpdHMsIF9pZl8gdGhlIG91dHB1dCBiaXQgaXMKKyAgLy8gMS4gVGhlIG1hc2sgaGFzIDEgYXQgYml0cyBjb3JyZXNwb25kaW5nIHRvIHRhcHMsIDAgZWxzZXdoZXJlLiBJbiBvdGhlcgorICAvLyB3b3JkcywgdGhlIHBvbHlub20gZnJvbSBhYm92ZS4KKyAgaWYgKGxzYikKKyAgICAgIHN0YXRlIF49IHBvbHlub207CisgIC8vIGRlYnVnIGNoZWNrIDstKQorICBpZiAoIXN0YXRlKQorICAgIHJhaXNlX2Vycm9yKCJTdGF0ZSBtdXN0IG5vdCBiZSB6ZXJvLCBidXQgaXQgaXMuXG4iKTsKKyAgLy8rK3BlcmlvZDsgCisgIC8vcHJpbnRmKCJTdGF0ZTogJTAzMmIgKFBlcmlvZDogJWQpXG4iLHN0YXRlLHBlcmlvZCk7CisgIHJldHVybiBsc2I7Cit9CisKK3B1YmxpYyBpbnQgbmV4dGJpdHMoaW50IGNvdW50KQoreworICBpbnQgcmVzdWx0OworICBpZiAoY291bnQ+NjQpCisgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigiQ291bnQgaXMgJWQsIGJ1dCBtdXN0IGJlIDw9IDY0LlxuIixjb3VudCkpOworICBmb3JlYWNoKGludCBpOiBjb3VudCkKKyAgICByZXN1bHQgPSAocmVzdWx0IDw8IDEpIHwgbmV4dGJpdCgpOworICByZXR1cm4gcmVzdWx0OworfQorCitwdWJsaWMgaW50IG5leHRieXRlKCkKK3sKKyAgcmV0dXJuIG5leHRiaXRzKDgpOworfQorCitwdWJsaWMgaW50IHJhbmRvbShpbnQgbikKK3sKKyAgaW50IHJuZCA9IG5leHRiaXRzKDMyKTsKKyAgLy9nZW5lcmF0ZXMgYSByYW5kb20gbnVtYmVyIG9uIFswLDEpLXJlYWwtaW50ZXJ2YWwgCisgIGZsb2F0IHRtcCA9IHJuZCAqICgxLjAvNDI5NDk2NzI5Ni4wKTsKKyAgLy8gU2thbGllcmVuIGF1ZiBbMCxuKQorICByZXR1cm4gdG9faW50KHRtcCAqIG4pOworfQorCisvLyBKdXN0IHNraXAgc29tZSBiaXRzIGFuZCBkaXNjYXJkIHRoZW0uCitwdWJsaWMgdm9pZCBza2lwYml0cyhpbnQgY291bnQpCit7CisgIGZvcmVhY2goaW50IGk6IGNvdW50KQorICAgIG5leHRiaXQoKTsKK30KKworCitwdWJsaWMgdm9pZCBkdW1wc3RyZWFtKHN0cmluZyBmaWxlLCBpbnQgYnl0ZXMpCit7CisgIGludCAqc3RyZWFtID0gYWxsb2NhdGUoYnl0ZXMpOworICBmb3JlYWNoKGludCBpOiBieXRlcykKKyAgeworICAgIHN0cmVhbVtpXSA9IG5leHRiaXRzKDgpOworICB9CisgIHdyaXRlX2ZpbGUoZmlsZSwgc3ByaW50ZigiJUBjIixzdHJlYW0pKTsKK30KKworcHVibGljIGludCBDb25maWd1cmUoaW50IGRhdGEpCit7CisgIGlmICghZGF0YSkKKyAgICByZXR1cm4gc3RhdGU7CisgIAorICBpZiAoIWludHAoZGF0YSkpCisgICAgcmV0dXJuIDA7CisgIHN0YXRlID0gZGF0YTsKKyAgcmV0dXJuIDE7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC91dGlsL3JpbmdidWZmZXIuYyBiL3N0ZC91dGlsL3JpbmdidWZmZXIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xOTMzOGUxCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3V0aWwvcmluZ2J1ZmZlci5jCkBAIC0wLDAgKzEsMjEwIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvKiogXGZpbGUgL3N0ZC91dGlsL3JpbmdidWZmZXIuYworKiBJbXBsbWVudGllcnQgZWluZW4gUmluZ2J1ZmZlciBpbiBMUEMuCisqIEFiIHVuZCBhbiBoYXQgbWFuIGRlbiBGYWxsLCBkYXNzIG1hbiBFcmVpZ25pc3NlL01lbGR1bmdlbiBvLmFlLiBoYXQsIHZvbgorKiBkZW5lbiBtYW4gaW1tZXIgZ2VuYXUgZGllIGxldHp0ZW4geCBnZXNwZWljaGVydCB1bmQgYWJydWZiYXIgdm9yaGFsdGVuCisqIG1vZWNodGUuIERpZXNlcyBGaWxlIHN0ZWxsdCBlaW5lIERhdGVuc3RydWt0dXIgdW5kIGRhenVnZWhvZXJpZ2UKKyogVmVyd2FsdHVuZ3NmdW5rdGlvbmVuIHp1IFZlcmZ1ZWd1bmcsIG1pdCBkZW5lbiBkaWVzIGVmZml6aWVudCBtb2VnbGljaCBpc3QuCisqIEluc2Jlc29uZGVyZSB1bWdlaGVuIGRpZXNlIGRhcyBzdGFlbmRpZ2UgU2xpY2luZyB2b24gQXJyYXlzLCBtaXQgZGVuZW4KKyogaGFldWZpZyBSaW5ncHVmZmVyIGdlYmF1dCB3ZXJkZW4uIEhpZXJiZWkgd2lyZCBkYXMgU2NocmVpYmVuIGluIGRlbiBQdWZmZXIKKyogYmlsbGlnZXIsIGRhcyBBYnJ1ZmVuIGRlciBEYXRlbiBhbGxlcmRpbmdzIHRldXJlci4gV2lyZCBkZXIgUHVmZmVyIGhhZXVmaWdlcgorKiBhYmdlZnJhZ3QgYWxzIGJlc2NocmllYmVuLCBpc3QgZGllcyBrZWluZSBlZmZpemllbnRlIExvZXN1bmcuCisqIAorKiBcYXV0aG9yIFplc3N0cmEKKyogXGRhdGUgMjIuMDUuMjAwOAorKiBcdmVyc2lvbiAkSWQkCisqLworLyogQ2hhbmdlbG9nOgorKi8KKyNwcmFnbWEgc3Ryb25nX3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgbm9faW5oZXJpdAorI3ByYWdtYSBub19zaGFkb3cKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworI2luY2x1ZGUgPHV0aWwvcmluZ2J1ZmZlci5oPgorCisvKiogU3RhbmRhcmRncm9lc3NlIGZ1ZXIgUmluZ2J1ZmZlci4KKyAgKi8KKyNkZWZpbmUgTUFYQ09VTlQgMzAKKworCisvKiogU3RydWt0dXIsIGRpZSBlaW5lbiBSaW5ncHVmZmVyIHNwZWljaGVydC4KKyAgRGVyIFB1ZmZlciBzZWxiZXIgaXN0IGltIHdlc2VudGxpY2hlbiBlaW4gQXJyYXkuIEhpbnp1IGtvbW10IG5vY2ggZWluCisgIFphZWhsZXIsIGRlciBkZW4gbmFlY2hzdGVuIHp1IHVlYmVyc2NocmVpYmVuZGVuIFdlcnQgaW5kaXppZXJ0IHNvd2llIGVpbmVuCisgIE1vZHVzLCBkZXIgZGllIFJlaWhlbmZvbGdlIGJlaW0gQWJydWZlbiBiZXNocmVpYnQ6CisgIE1PREVfRklGTzogRmlyc3QtaW4tRmlyc3Qtb3V0IChkZWZhdWx0KQorICBNT0RFX0xJRk86IExhc3QtaW4tRmlyc3Qtb3V0CisgICovCitzdHJ1Y3Qgc3RkX3JpbmdidWZmZXIgeworICAgIG1peGVkIHJidWZmZXI7CisgICAgaW50IG1vZGU7CisgICAgaW50IG5leHQ7Cit9OworCisvKiogRXJ6ZXVndCBlaW5lbiBuZXVlbiBSaW5nYnVmZmVyIHVuZCBsaWVmZXJ0IGlobiB6dXJ1ZWNrLgorICBEaWUgRnVua3Rpb24gZXJ6ZXVndCBlaW5lbiBuZXVlbiwgbGVlcmVuIFJpbmdidWZmZXIgZGVyIEdyb2Vzc2UgXGEgc2l6ZQorICB1bmQgbWl0IEF1c2dhYmVtb2R1cyBcYSBuZXdtb2RlIHVuZCBsaWVmZXJ0IGRpZSBlbnRzcHJlY2hlbmRlCisgIFJpbmdidWZmZXItU3RydWt0dXIgenVydWVjay4KKyAgXGF0dGVudGlvbiBEaWUgenVydWVja2dlbGllZmVydGUgRGF0ZW5zdHJ1a3R1ciBiaXR0ZSBuaWNodCBwZXIgSGFuZAorICBtYW5pcHVsaWVyZW4uCisgIFxwYXJhbVtpbl0gc2l6ZSBHcm9lc3NlIGRlcyB6dSBlcnpldWdlbmRlbiBSaW5nYnVmZmVycy4gRGVmYXVsdDogMzAKKyAgXHBhcmFtW2luXSBuZXdtb2RlIEF1c2dhYmVtb2R1cyBkZXMgUmluZ2J1ZmZlcnM6IFxhIE1PREVfRklGTyBvZGVyCisgIFxhIE1PREVfTElGTy4gRGVmYXVsdDogTU9ERV9GSUZPCisgIFxyZXR1cm4gRGVyIGVyemV1Z3RlIFJpbmdidWZmZXIgKHN0cnVjdCB2b20gVHlwIHN0ZF9yaW5nYnVmZmVyKS4KKyAgXHNhIFJlc2l6ZVJpbmdCdWZmZXIsIFJpbmdCdWZmZXJQdXQsIFJpbmdCdWZmZXJHZXQKKyAgKi8KK3Byb3RlY3RlZCBzdHJ1Y3Qgc3RkX3JpbmdidWZmZXIgQ3JlYXRlUmluZ0J1ZmZlcihpbnQgc2l6ZSwgaW50IG5ld21vZGUpIHsKKyAgCisgIHN0cnVjdCBzdGRfcmluZ2J1ZmZlciBidWZmZXIgPSAoPHN0ZF9yaW5nYnVmZmVyPgorICAgICAgIHJidWZmZXI6IGFsbG9jYXRlKHNpemV8fE1BWENPVU5ULCAwKSwgCisgICAgICAgbW9kZTogbmV3bW9kZSB8fCBNT0RFX0ZJRk8sIAorICAgICAgIG5leHQ6IDAgKTsKKworICAvLyBCZWkgTElGTyB2b24gb2JlbiBhbmZhbmdlbi4KKyAgaWYgKG5ld21vZGU9PU1PREVfTElGTykKKyAgICBidWZmZXItPm5leHQgPSBzaXplb2YoYnVmZmVyLT5yYnVmZmVyKTsKKyAgCisgIHJldHVybiBidWZmZXI7Cit9CisKKy8qKiBTY2hyZWlidCBlaW5lbiBuZXVlbiBXZXJ0IGluIGRlbiBSaW5nYnVmZmVyLgorICBEaWVzZSBGdW5rdGlvbiBzY2hyZWlidCBlaW5lbiBuZXVlbiBXZXJ0IGluIGRlbiBSaW5nYnVmZmVyIFxhIGJ1ZmZlciB1bmQKKyAgbG9lc2NodCBkYWJlaSBnZ2YuIGRlbiBhZWx0ZXN0ZW4gV2VydCBpbSBQdWZmZXIuCisgIFxwYXJhbVtpbixvdXRdIGJ1ZmZlciB6dSBhZW5kZXJuZGVyIFJpbmdidWZmZXIKKyAgXHBhcmFtW2luXSB2YWwgaGluenV6dWZ1ZWdlbmRlciBXZXJ0CisgIFxzYSBDcmVhdGVSaW5nQnVmZmVyLCBSZXNpemVSaW5nQnVmZmVyLCBSaW5nQnVmZmVyR2V0CisgICovCitwcm90ZWN0ZWQgdm9pZCBSaW5nQnVmZmVyUHV0KHN0cnVjdCBzdGRfcmluZ2J1ZmZlciBidWZmZXIsIG1peGVkIHZhbCkgeworICBpbnQgbmV4dCA9IGJ1ZmZlci0+bmV4dDsKKyAgLy8gamUgbmFjaCBBdXNnYWJlbW9kdXMgdm9uIG9iZW4gbmFjaCB1bnRlbiBvZGVyIHZvbiB1bnRlbiBuYWNoIG9iZW4gZGllCisgIC8vIFdlcnRlIHJlaW5zY2hyZWliZW4uCisgIHN3aXRjaChidWZmZXItPm1vZGUpIHsKKyAgICBjYXNlIE1PREVfTElGTzoKKyAgICAgIC8vIG5leHQgaXN0IGhpZXIgZWlnZW50bGljaCBlaW4gJ2xhc3QnLiBEZWtyZW1lbnRpZXJlbiB1bmQgZGFubiB6dW0KKyAgICAgIC8vIEluZGl6aWVyZW4gYmVudXR6ZW4uCisgICAgICBidWZmZXItPnJidWZmZXJbLS1uZXh0XSA9IHZhbDsKKyAgICAgIC8vIHdlbm4gbWFuIGdlcmFkZSBpbiBFbGVtZW50IDAgZ2VzY2hyaWViZW4gaGF0LCBpc3QgbmFlY2hzdGVzIEVsZW1lbnQKKyAgICAgIC8vIHNpemVvZigpLTEsIGQuaC4gc2l6ZW9mKCkgYWxzIG5leHQgdmVybWVya2VuLgorICAgICAgbmV4dCB8fD0gc2l6ZW9mKGJ1ZmZlci0+cmJ1ZmZlcik7CisgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgLy8gV2VydCBzY2hyZWliZW4gdW5kIG5leHQgaW5rcmVtZW50aWVyZW4uCisgICAgICBidWZmZXItPnJidWZmZXJbbmV4dCsrXSA9IHZhbDsKKyAgICAgIC8vIHdpcmQgc2l6ZW9mKCkgZXJyZWljaHQsIGlzdCBkYXMgbmFlY2hzdGUgRWxlbWVudCAwLiBFdHdhcyBzY2huZWxsZXIKKyAgICAgIC8vIHdhZXJlIGVpbiBNb2R1bG8gbWl0IGRlciBCdWZmZXJncm9lc3NlIGRpcmVrdCBiZWkgZGVyIEluZGl6aWVydW5nCisgICAgICAvLyBvYmVuLCBhYmVyIGRhbm4ga2FubiBlcyB1LlUuIGR1cmNoIGVpbmVuIG51bWVyaXNjaGVuIE92ZXJmbG93IGJ1Z2dlbi4KKyAgICAgIGlmIChuZXh0PT1zaXplb2YoYnVmZmVyLT5yYnVmZmVyKSkKKwluZXh0ID0gMDsKKyAgfQorICBidWZmZXItPm5leHQgPSBuZXh0OworfQorCisvKiogTGllZmVydCBlaW4gQXJyYXkgbWl0IGFsbGVuIFdlcnRlbiBkZXMgUmluZ2J1ZmZlcnMgXGEgYnVmZmVyLgorICBEYXMgenVydWVja2dlbGllZmVydGUgQXJyYXkgZW50aGFlbHQgYWxsZSBEYXRlbiBkZXMgUmluZ2J1ZmZlcnMgaW4gZGVyCisgIGJlaW0gRXJzdGVsbGVuIGRlcyBQdWZmZXJzIGdld3VlbnNjaHRlbiBSZWloZW5mb2xnZSAocy4gTU9ERV9GSUZPLAorICBNT0RFX0xJRk8pLgorICBJc3QgZGVyIFB1ZmZlciBub2NoIG5pY2h0IHZvbGxzdGFlbmRpZyBnZWZ1ZWxsdCwgZW50aGFsdGVuIGRpZSBiaXNoZXIgbm9jaAorICBuaWUgYmVzY2hyaWViZW5lbiBFbGVtZW50ZSAwLgorICBccGFyYW1baW5dIGJ1ZmZlciBSaW5ncHVmZmVyLCBkZXNzZW4gRGF0ZW4gYXVzZ2ViZW4gd2VyZGVuIHNvbGxlbi4KKyAgXHJldHVybiBBcnJheSBtaXQgRGF0ZW4gZGVzIFB1ZmZlcnMuCisgIFxzYSBDcmVhdGVSaW5nQnVmZmVyLCBSaW5nQnVmZmVyUHV0LCBSZXNpemVSaW5nQnVmZmVyCisgICovCitwcm90ZWN0ZWQgbWl4ZWQgUmluZ0J1ZmZlckdldChzdHJ1Y3Qgc3RkX3JpbmdidWZmZXIgYnVmZmVyKSB7CisgIGludCBzaXplID0gc2l6ZW9mKGJ1ZmZlci0+cmJ1ZmZlcik7CisgIGludCBuZXh0ID0gYnVmZmVyLT5uZXh0OworICBtaXhlZCByYnVmZmVyID0gYnVmZmVyLT5yYnVmZmVyOworCisgIHN3aXRjaChidWZmZXItPm1vZGUpIHsKKyAgICBjYXNlIE1PREVfTElGTzoKKyAgICAgIC8vIGRlciBoaW50ZXJlIFRlaWwgZW50aGFlbHQgZGllIG5ldWVyZW4gRGF0ZW4uIERpZSBrb21tZW4genVlcnN0LgorICAgICAgLy8gV2VubiBuZXh0ID09IHNpemVvZigpLCBkYW5uIGthbm4gZGFzIGludGVybmUgQXJyYXkgZWluZmFjaCBrb3BpZXJ0CisgICAgICAvLyB3ZXJkZW4uCisgICAgICBpZiAobmV4dCA9PSBzaXplKQorCXJldHVybiBjb3B5KHJidWZmZXIpOworICAgICAgZWxzZQorCXJldHVybiByYnVmZmVyW25leHQgLi4gc2l6ZS0xXSArIHJidWZmZXJbMCAuLiBuZXh0LTFdOworICAgIGRlZmF1bHQ6CisgICAgICAvLyBkZXIgdm9yZGVyZSBUZWlsIGVudGhhZWx0IGRpZSBuZXVlcmVuIERhdGVuLiBBbHNvIHp1ZXJzdCBkZW4gaGludGVyZW4KKyAgICAgIC8vIGF1c2dlYmVuLCBkYW5uIGRlbiB2b3JkZXJlbi4KKyAgICAgIC8vIFdlbm4gbmV4dCAwLCBrYW5uIGRhcyBpbnRlcm5lIEFycmF5IGVpbmZhY2gga29waWVydCB3ZXJkZW4uIFNvbnN0CisgICAgICAvLyBtdXNzIGVzIHp1c2FtbWVuZ2VzZXR6dCB3ZXJkZW4uCisgICAgICBpZiAobmV4dCkKKwlyZXR1cm4gcmJ1ZmZlcltuZXh0IC4uIHNpemUtMV0gKyByYnVmZmVyWzAgLi4gbmV4dC0xXTsKKyAgICAgIGVsc2UKKwlyZXR1cm4gY29weShyYnVmZmVyKTsKKyAgfQorICByZXR1cm4gMDsKK30KKworLyoqIEVyemV1Z3QgZWluZW4gbmV1ZW4gUmluZ2J1ZmZlciBkZXIgR3JvZXNzZSBcYSBzaXplIHVuZCBkZW0gZ2xlaWNoZW4gTW9kdXMKKyAqIHdpZSBcYSBidWYsIGRlciBkaWVzZWxiZW4gRGF0ZW4gZW50aGFlbHQgd2llIFxhIGJ1Zi4KKyAqIERpZXNlIEZ1bmt0aW9uIGVyemV1Z3QgZWluZW4gbmV1ZW4gUmluZ2J1ZmZlciB1bmQga29waWVydCBhbGxlIERhdGVuIGF1cworICogZGVtIGFsdGVuIFB1ZmZlciBpbiBkZW4gbmV1ZW4gdW0uCisgXHBhcmFtW2luXSBidWYgYWx0ZXIgUmluZ2J1ZmZlcgorIFxwYXJhbVtpbl0gc2l6ZSBnZXd1ZW5zY2h0ZSBuZXVlIEdyb2Vzc2UKKyBccmV0dXJuIExpZWZlcnQgbmV1ZW4gUmluZ2J1ZmZlciBtaXQgZ2V3dWVuc2NodGVuIEdyb2Vzc2UuCisgXHNhIENyZWF0ZVJpbmdCdWZmZXIsIFJpbmdCdWZmZXJQdXQsIFJpbmdCdWZmZXJHZXQKKyBcYXR0ZW50aW9uIFdpcmQgZGVyIFJpbmdidWZmZXIgdmVya2xlaW5lcnQsIGtvbW10IGVzIHp1bSBWZXJsdXN0IGRlcgorIGFlbHRlc3RlbiBEYXRlbiwgZGllIG5pY2h0IG1laHIgaW4gZGVuIG5ldWVuIGhpbmVpbnBhc3Nlbi4KKyBcdG9kbyBFZmZpemllbnRlcmUgSW1wbGVtZW50YXRpb24uCisgKi8KK3Byb3RlY3RlZCBzdHJ1Y3Qgc3RkX3JpbmdidWZmZXIgUmVzaXplUmluZ0J1ZmZlcihzdHJ1Y3Qgc3RkX3JpbmdidWZmZXIgYnVmLCAKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2l6ZSkgeworICAvLyBuZXVlbiBSaW5nYnVmZmVyIGFubGVnZW4uCisgIHN0cnVjdCBzdGRfcmluZ2J1ZmZlciBuYnVmID0gQ3JlYXRlUmluZ0J1ZmZlcihzaXplLCBidWYtPm1vZGUpOworICAvLyB1bmQgYWxsZSBkYXRlbiBhdXMgZGVtIGFsdGVuIHdpZWRlciByZWluc3RvcGZlbi4KKyAgLy8gamEsIGRhcyBnZWh0IGVmZml6aWVudGVyLCBoYWIgaWNoIGdlcmFkZSBhYmVyIGtlaW5lbiBCb2NrIGRyYXVmLiBEaWUKKyAgLy8gRnVua3Rpb24gd2lyZCB2ZXJtdXRsaWNoIGVoIHNlaHIgc2VsdGVuIGdlcnVmZW4uCisgIGZvcmVhY2gobWl4ZWQgdmFsOiBSaW5nQnVmZmVyR2V0KGJ1ZikpCisgICAgUmluZ0J1ZmZlclB1dChuYnVmLCB2YWwpOworICAvLyBuZXVlbiBCdWZmZXIgenVydWVja2dlYmVuLiBEZXIgYWx0ZSBibGVpYnQgdW52ZXJhZW5kZXJ0IQorICByZXR1cm4gbmJ1ZjsKK30KKworLyogaGFsYmZlcnRpZ2UgSW1wbGVtZW50YXRpb24gbWl0IEFycmF5cy4KKyNkZWZpbmUgUkJVRkZFUiAgIDAKKyNkZWZpbmUgTU9ERSAgICAgIDEKKyNkZWZpbmUgQ09VTlRFUiAgIDIKKworcHJvdGVjdGVkIG1peGVkIENyZWF0ZVJpbmdCdWZmZXIoaW50IHNpemUsIGludCBtb2RlKSB7CisgIG1peGVkIGJ1ZmZlciA9ICh7IGFsbG9jYXRlKHNpemV8fE1BWENPVU5ULCAwKSwgCisgICAgICAgICAgICAgICAgICAgIG1vZGUgfHwgTU9ERV9GSUZPLCAKKwkgICAgICAgICAgICAwIH0pOworICBpZiAobW9kZT09TU9ERV9MSUZPKQorICAgIGJ1ZmZlcltDT1VOVEVSXSA9IHNpemVvZihidWZmZXJbUkJVRkZFUl0pOworICByZXR1cm4gYnVmZmVyOworfQorCitwcm90ZWN0ZWQgdm9pZCBSaW5nQnVmZmVyUHV0KG1peGVkIGJ1ZmZlciwgbWl4ZWQgdmFsKSB7CisgIGludCBjb3VudGVyID0gYnVmZmVyW0NPVU5URVJdOworICBzd2l0Y2gobW9kZSkgeworICAgIGNhc2UgTU9ERV9MSUZPOgorICAgICAgcmJ1ZmZlclstLWNvdW50ZXJdID0gdmFsOworICAgICAgY291bnRlciB8fD0gc2l6ZW9mKHJidWZmZXIpOworICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgIHJidWZmZXJbKGNvdW50ZXIrKyklc2l6ZW9mKHJidWZmZXIpXSA9IHZhbDsKKyAgfQorICBidWZmZXJbQ09VTlRFUl09Y291bnRlcjsKK30KKworcHJvdGVjdGVkIG1peGVkIFJpbmdCdWZmZXJHZXQobWl4ZWQgYnVmZmVyKSB7CisgIGludCBzaXplPXNpemVvZihyYnVmZmVyKTsKKworICBzd2l0Y2gobW9kZSkgeworICAgIGNhc2UgTU9ERV9MSUZPOgorICAgICAgcmV0dXJuIHJidWZmZXJbY291bnRlci4uc2l6ZV0gKyByYnVmZmVyWzAuLmNvdW50ZXItMV07CisgICAgZGVmYXVsdDoKKyAgICAgIGlmIChjb3VudGVyJXNpemUpCisJcmV0dXJuIHJidWZmZXJbKGNvdW50ZXIlc2l6ZSkgLi4gc2l6ZS0xXSAKKwkgICAgICAgKyByYnVmZmVyWzAuLihjb3VudGVyJXNpemUpLTFdOworICAgICAgZWxzZQorCXJldHVybiBjb3B5KHJidWZmZXIpOworICB9Cit9CisKK3Byb3RlY3RlZCBtaXhlZCB0ZXN0KCkge3JldHVybiByYnVmZmVyO30KKyovCmRpZmYgLS1naXQgYS9zdGQvdXRpbC90ZXN0ZWRpdC5jIGIvc3RkL3V0aWwvdGVzdGVkaXQuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mMzFmNmVkCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3V0aWwvdGVzdGVkaXQuYwpAQCAtMCwwICsxLDI1IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdXRpbC90ZXN0ZWRpdC5jIC0tIFRyYWdiYXJlciBFZGl0b3IKKy8vCisvLyAkSWQ6IHRlc3RlZGl0LmMgNjM3MSAyMDA3LTA3LTE3IDIyOjQ2OjUwWiBaZXNzdHJhICQKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKworaW5oZXJpdCAiL3N0ZC90aGluZyI7Citpbmhlcml0ICIvc3RkL3V0aWwvZXgiOworCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorCit2b2lkIGNyZWF0ZSgpCit7CisgIDo6Y3JlYXRlKCk7CisgIEFkZElkKCJleCIpOworICBTZXRQcm9wKFBfTkFNRSwgIkVkaXRvciIpOworICBTZXRQcm9wKFBfU0hPUlQsICJFaW4gVGVzdGVkaXRvciIpOworICBTZXRQcm9wKFBfTE9ORywgIlRlc3RlZGl0b3I6IEtvbW1hbmRvOiBleFxuIik7CisgIEFkZENtZCgiZXgiLCAiZXgiKTsKK30KZGlmZiAtLWdpdCBhL3N0ZC92aXJ0dWFsL3ZfY29tcGlsZXIuYyBiL3N0ZC92aXJ0dWFsL3ZfY29tcGlsZXIuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44MGViMzcwCi0tLSAvZGV2L251bGwKKysrIGIvc3RkL3ZpcnR1YWwvdl9jb21waWxlci5jCkBAIC0wLDAgKzEsMTY1IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gdmlydHVhbC92X2NvbXBpbGVyLmMgLS0gYSBnZW5lcmFsIHZpcnR1YWwgY29tcGlsZXIgb2JqZWN0CisvLworLy8gJElkOiB2X2NvbXBpbGVyLmMgOTE0MiAyMDE1LTAyLTA0IDIyOjE3OjI5WiBaZXNzdHJhICQKKworLy8gcHJpbmNpcGxlOgorLy8gIC0gaW5oZXJpdCB0aGlzIG9iamVjdCBpbnRvIHlvdXIgb3duICd2aXJ0dWFsX2NvbXBpbGVyLmMnCisvLyAgLSBjdXN0b21pemUgVmFsaWRhdGUoKSBhbmQgQ3VzdG9taXplT2JqZWN0KCkgZm9yIHlvdSBvd24gc2FrZQorLy8gIAorLy8gICogVmFsaWRhdGUoKSBjaGVja3MgaWYgYSByb29tIGZpbGVuYW1lIGdpdmVuIGFzIGFyZ3VtZW50ICh3aXRob3V0IHBhdGgpCisvLyAgICBpcyB2YWxpZCBhbmQgcmV0dXJucyB0aGlzIGZpbGVuYW1lIHdpdGggc3RyaXBwZWQgJy5jJyEhCisvLyAgKiBDdXN0b21pemVPYmplY3QoKSB1c2VzIHRoZSBwcmV2aW91c19vYmplY3QoKS0+RnVuY3Rpb24oKSBzdHJhdGVneSB0bworLy8gICAgY3VzdG9taXplIHRoZSBzdGFuZGFyZCBvYmplY3QgKGZvciBleGFtcGxlIHRvIHNldCBhIGRlc2NyaXB0aW9uKQorLy8KKy8vIFByb3BlcnRpZXM6IFBfU1REX09CSkVDVCwgUF9DT01QSUxFUl9QQVRICisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKworaW5oZXJpdCAiL3N0ZC90aGluZy9wcm9wZXJ0aWVzIjsKKworLy8jZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKyNpbmNsdWRlIDx2X2NvbXBpbGVyLmg+CisjaW5jbHVkZSA8ZXhwbG9yYXRpb24uaD4KKyNpbmNsdWRlIDxzeXNfZGVidWcuaD4KKyNpbmNsdWRlIDxsaXZpbmcvZGVzY3JpcHRpb24uaD4gLy9mdWVyIFBfUEFSQQorCisvLyBEZXIgVkMgYnJhdWNodCBkYXMgJ2FsdGUnIG9iamVjdF9uYW1lKCktYmFzaWVydGUgQkxVRV9OQU1FLCBkYSBzb25zdCBkYXMKKy8vIEtvbmZpZ3VyaWVyZW4gZGVyIHZvbiBlaW5lbSBWQy1PYmpla3QgZ2VjbG9udGVuIENsb25lcyB2aWEKKy8vIEN1c3RvbWl6ZU9iamVjdCgpIG5pY2h0IGZ1bmt0aW9uaWVydCAobG9hZF9uYW1lKCkgZXJtaXR0ZWx0IGRlbiBOYW1lbiBkZXMKKy8vIFZDLVN0YW5kYXJkb2JqZWt0ZXMpCisjaWZkZWYgQkxVRV9OQU1FCisjdW5kZWYgQkxVRV9OQU1FCisjZW5kaWYKKyNkZWZpbmUgQkxVRV9OQU1FKG9iKSAoZXhwbG9kZShvYmplY3RfbmFtZShvYiksIiMiKVswXSkKKworcHJpdmF0ZSBub3NhdmUgc3RyaW5nIGxhc3RfbG9hZGVkX2ZpbGU7Citwcml2YXRlIG5vc2F2ZSBtYXBwaW5nIG9iamVjdHM7CisKK3ZvaWQgY3JlYXRlKCkKK3sKKyAgOjpjcmVhdGUoKTsKKyAgc2V0ZXVpZChnZXR1aWQoKSk7CisgIFNldFByb3AoUF9TVERfT0JKRUNULCAiL3N0ZC9yb29tIik7CisgIFNldFByb3AoUF9DT01QSUxFUl9QQVRILCBzcHJpbnRmKCIvJXMvIiwKKyAgICAgICAgaW1wbG9kZShvbGRfZXhwbG9kZShvYmplY3RfbmFtZSh0aGlzX29iamVjdCgpKSwgIi8iKVswLi48Ml0sICIvIikpKTsKKyAgU2V0UHJvcChQX1BBUkEsICh7fSkgKTsgLy8ga2VpbmUgUGFyYS1WQy1PYmpla3RlCisgIG9iamVjdHMgPSAoW10pOworfQorCisvLyB2b24gZGVuIGVyYmVuZW4gVkNzIHp1IHVlYmVyc2NocmVpYmVuLi4uCisvLyBUT0RPOiBhdXMgU3RhbmRhcmRvYmpla3QgZW50ZmVybmVuLCB3ZWlsIGR1cmNoIFBfUEFSQSB1bmQgUXVlcnlWYWxpZE9iamVjdAorLy8gb2Jzb2xldC4gCitpbnQgTm9QYXJhT2JqZWN0cygpIHsgcmV0dXJuIDA7IH0KKworc3RyaW5nIFZhbGlkYXRlKHN0cmluZyBmaWxlKQoreworICBpZighZmlsZSkgcmV0dXJuIDA7CisgIGlmKGZpbGVbPDIuLl0gPT0gIi5jIikgZmlsZSA9IGZpbGVbMC4uPDNdOworICBFUE1BU1RFUi0+UHJlcGFyZVZDUXVlcnkoZmlsZSk7CisgIHJldHVybiBmaWxlOworfQorCisvLyBEaWUgRnVua3Rpb24gYmVrb21tdCBlaW5lbiBPYmpla3RuYW1lbiB1ZWJlcmdlYmVuIHVuZCBtdXNzIGVudHNjaGVpZGVuLCBvYgorLy8gZGllc2VyIFZDIGRhZnVlciB6dXN0YWVuZGlnIGlzdCwgZGFzIE9iamVrdCB6dSBnZW5lcmllcmVuLiBKZWRlciBXZXJ0ICE9IDAKKy8vIHphZWhsdCBhbHMgJ3p1c3RhZW5kaWcnLiBFcyBpc3QgZWluZSBBcnQgZ2VuZXJhbGlzaWVydGVtIFZhbGlkYXRlKCkuIEZ1ZXIKKy8vIG1heGltYWxlIE51ZXR6bGljaGtlaXQgbXVzcyBkaWVzZSBGdW5rdGlvbiB2b24gZGVuIGVyYmVuZGVuIFZDcworLy8gdWViZXJzY2hyaWViZW4gd2VyZGVuLgorcHVibGljIGludCBRdWVyeVZhbGlkT2JqZWN0KHN0cmluZyBvbmFtZSkgeworICAgIHN0cmluZyBmbmFtZSwgcGF0aCwgKnBlbGVtOworICAgIGludCBwYXJhOworICAgIG1peGVkIHBwYXJhOworCisgICAgLy9lcnN0bWFsIFZhbGlkYXRlIGZyYWdlbgorICAgIHBlbGVtPWV4cGxvZGUob25hbWUsIi8iKTsKKyAgICBmbmFtZT1wZWxlbVs8MV07CisgICAgaWYgKCFmbmFtZT1WYWxpZGF0ZShmbmFtZSkpCisgICAgICAgIHJldHVybigwKTsgLy9uaWNodCB6dXN0YWVuZGlnCisgICAgLy8gbmljaHQgaW0gcmljaHRpZ2VuIFBmYWQ/CisgICAgcGF0aD1zcHJpbnRmKCIlcy8iLGltcGxvZGUocGVsZW1bMC4uPDJdLCIvIikpOworICAgIGlmIChwYXRoIT1RdWVyeVByb3AoUF9DT01QSUxFUl9QQVRIKSkKKyAgICAgICAgcmV0dXJuKDApOworICAgIC8vIFBhcmEtT2JqZWt0PworICAgIGlmIChzc2NhbmYoZm5hbWUsIiVzXiVkIixmbmFtZSxwYXJhKSA+IDEpIHsKKyAgICAgICAgaWYgKE5vUGFyYU9iamVjdHMoKSkKKyAgICAgICAgICAgIHJldHVybigwKTsgLy9kaXJla3QgenVydWVjaywga2VpbmUgUGFyYS1PYmpla3RlCisgICAgICAgIC8vIGJlc3RpbW10ZSBQYXJhLURpbWVuc2lvbmVuIGV4cGxpeml0IGVybGF1YnQ/IChXZW5uIFBfUEFSQSBuaWNodAorICAgICAgICAvLyBnZXNldHp0IGlzdCwgc2luZCBhbGxlIGVybGF1YnQhKQorICAgICAgICBpZiAocHBhcmE9UXVlcnlQcm9wKFBfUEFSQSkpIHsKKyAgICAgICAgICAgIGlmIChwb2ludGVycChwcGFyYSkgJiYgbWVtYmVyKHBwYXJhLHBhcmEpIT0tMSkKKyAgICAgICAgICAgICAgICByZXR1cm4oMSk7CisgICAgICAgICAgICBlbHNlIGlmIChpbnRwKHBhcmEpICYmIHBwYXJhPT1wYXJhKQorICAgICAgICAgICAgICAgIHJldHVybigxKTsKKyAgICAgICAgICAgIC8vIFBfUEFSQSBnZXNldHp0LCBhYmVyIGdld3VlbnNjaHRlcyBQYXJhIG5pY2h0IGVudGhhbHRlbi4uLgorICAgICAgICAgICAgZWxzZSByZXR1cm4oMCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuKDEpOyAvL2ZhbGwtdGhyb3VnaCwgb2ZmZW5iYXIgenVzdGFlbmRpZy4KK30KKworbWl4ZWQgQ3VzdG9taXplT2JqZWN0KCkKK3sKKyAgc3RyaW5nIGZpbGU7CisKKyAgaWYoIWNsb25lcChwcmV2aW91c19vYmplY3QoKSkpCisgICAgcmV0dXJuIFZhbGlkYXRlKGV4cGxvZGUoQkxVRV9OQU1FKHByZXZpb3VzX29iamVjdCgpKSwgIi8iKVs8MV0pOworICBpZihzdHJpbmdwKGxhc3RfbG9hZGVkX2ZpbGUpKSBmaWxlID0gbGFzdF9sb2FkZWRfZmlsZTsKKyAgZWxzZSBmaWxlID0gVmFsaWRhdGUoZXhwbG9kZShCTFVFX05BTUUocHJldmlvdXNfb2JqZWN0KCkpLCAiLyIpWzwxXSk7CisgIGlmKCFmaWxlKSByZXR1cm4gMDsKKyAgbGFzdF9sb2FkZWRfZmlsZSA9IDA7CisgIHJldHVybiBmaWxlOworfQorCisvLyBhZGQgYSBuZXcgb2JqZWN0IHRvIHRoZSBvYmplY3QgbGlzdCBpZiBpdCBjb21waWxlcworcHJpdmF0ZSBtaXhlZCBBZGRPYmplY3Qoc3RyaW5nIGZpbGUpCit7CisgIG9iamVjdCBvYjsKKyAgc3RyaW5nIGVycjsKKworICAvLyBjbGVhbiB1cCB0aGUgb2JqZWN0IGxpc3QKKyAgb2JqZWN0cyA9IGZpbHRlcl9pbmRpY2VzKG9iamVjdHMsIGZ1bmN0aW9uIGludCAoc3RyaW5nIGYpIHsKKyAgICAgIHJldHVybiAob2JqZWN0cChvYmplY3RzW2ZdKSk7IH0gKTsKKworICBsYXN0X2xvYWRlZF9maWxlID0gZmlsZTsKKyAgLy8gcmVnaXN0ZXIgbmV3IG9iamVjdAorICBpZihvYiA9IGNsb25lX29iamVjdChRdWVyeVByb3AoUF9TVERfT0JKRUNUKSkpCisgICAgb2JqZWN0c1tmaWxlXSA9IG9iOworICByZXR1cm4gb2I7Cit9CisKKy8vIHRyeSB0byBjcmVhdGUgYW4gb2JqZWN0IGZvciB0aGUgd2FudGVkIGZpbGUKK21peGVkIGNvbXBpbGVfb2JqZWN0KHN0cmluZyBmaWxlKQoreworICAvLyB2YWxpZGF0ZSBpZiB0aGUgZmlsZSBuYW1lIGlzIGEgY29ycmVjdCBvbmUKKyAgaWYoZmlsZSA9IFZhbGlkYXRlKGZpbGUpKQorICAgIHJldHVybiBBZGRPYmplY3QoZmlsZSk7CisgIHJldHVybiAwOworfSAgCisKKy8vIHJldHVybiBhbGwgY2xvbmVkIHZpcnR1YWwgb2JqZWN0cworbWl4ZWQgUXVlcnlPYmplY3RzKCkKK3sKKyAgcmV0dXJuIG1fdmFsdWVzKG9iamVjdHMpLSh7MH0pOworfQorCisvLyBjbGVhbiB1cCByb29tcyB0aGF0IGhhdmUgbm90IGJlZW4gZGVzdHJ1Y3RlZCB5ZXQKK2ludCByZW1vdmUoKSB7CisKKyAgaWYoIW1hcHBpbmdwKG9iamVjdHMpKSByZXR1cm4gMDsKKworICAvL2ZvcihvYiA9IFF1ZXJ5T2JqZWN0cygpOyBzaXplb2Yob2IpOyBvYiA9IG9iWzEuLl0pCisgIGZvcmVhY2gob2JqZWN0IG9iOiBRdWVyeU9iamVjdHMoKSkgeworICAgICAgb2ItPnJlbW92ZSgpOworICAgICAgaWYob2JqZWN0cChvYikpIGRlc3RydWN0KG9iKTsKKyAgfQorICByZXR1cm4gMTsKK30KKwpkaWZmIC0tZ2l0IGEvc3RkL3dlYXBvbi5jIGIvc3RkL3dlYXBvbi5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjdjMWY5N2MKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvd2VhcG9uLmMKQEAgLTAsMCArMSw1NCBAQAorLy8gTW9yZ2VuR3JhdWVuIE1VRGxpYgorLy8KKy8vIHdlYXBvbi5jIC0tIHdlYXBvbiBzdGFuZGFyZCBvYmplY3QKKy8vCisvLyAkSWQ6IHdlYXBvbi5jIDc4MDQgMjAxMS0wNy0xMCAyMDozNzo1MlogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKy8vI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCitpbmhlcml0ICIvc3RkL3RoaW5nL3Byb3BlcnRpZXMiOworaW5oZXJpdCAiL3N0ZC90aGluZy9sYW5ndWFnZSI7Citpbmhlcml0ICIvc3RkL3RoaW5nL2NvbW1hbmRzIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvcmVzdHJpY3Rpb25zIjsKK2luaGVyaXQgIi9zdGQvdGhpbmcvbGlnaHQiOworaW5oZXJpdCAiL3N0ZC93ZWFwb24vbW92aW5nIjsKK2luaGVyaXQgIi9zdGQvd2VhcG9uL2NvbWJhdCI7Citpbmhlcml0ICIvc3RkL3dlYXBvbi9kZXNjcmlwdGlvbiI7Citpbmhlcml0ICIvc3RkL3RoaW5nL2VudmNoayI7CisKKy8vI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKworI2RlZmluZSA8dGhpbmcvcHJvcGVydGllcy5oPgorCisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPGRlZmluZXMuaD4KKwordm9pZCBjcmVhdGUoKQoreworICBzZXRldWlkKGdldHVpZCgpKTsKKyAgcHJvcGVydGllczo6Y3JlYXRlKCk7CisgIGNvbW1hbmRzOjpjcmVhdGUoKTsKKyAgbGlnaHQ6OmNyZWF0ZSgpOworICByZXN0cmljdGlvbnM6OmNyZWF0ZSgpOworICBjb21iYXQ6OmNyZWF0ZSgpOworICBkZXNjcmlwdGlvbjo6Y3JlYXRlKCk7CisgIGVudmNoazo6Y3JlYXRlKCk7CisgIEFkZElkKCh7IkRpbmciLCJ3YWZmZSJ9KSk7Cit9CisKKy8qCit2b2lkIGluaXQoKQoreworICBjb21tYW5kczo6aW5pdCgpOworICBkZXNjcmlwdGlvbjo6aW5pdCgpOworfQorKi8KKwordm9pZCByZXNldCgpICAvLyBNYW4ga2FubiBpbiBBTExFTiBTdGFuZGFyZG9iamVrdGVuIDo6cmVzZXQgYXVmcnVmZW4hCit7IH0KKwpkaWZmIC0tZ2l0IGEvc3RkL3dlYXBvbi9jb21iYXQuYyBiL3N0ZC93ZWFwb24vY29tYmF0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2IxMGZmNQotLS0gL2Rldi9udWxsCisrKyBiL3N0ZC93ZWFwb24vY29tYmF0LmMKQEAgLTAsMCArMSw4MTkgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB3ZWFwb24vY29tYmF0LmMgLS0gY29tYmF0IHBhcnQgb2YgdGhlIHdlYXBvbiBzdGFuZGFyZCBvYmplY3QKKy8vCisvLyAkSWQ6IGNvbWJhdC5jIDk0MjUgMjAxNi0wMS0wMiAxODoxOTo0MFogWmVzc3RyYSAkCisKKyNpbmNsdWRlIDxzeXNfZGVidWcuaD4KKworI3ByYWdtYSBzdHJpY3RfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworI3ByYWdtYSByYW5nZV9jaGVjaworCisjZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHRoaW5nL2NvbW1hbmRzLmg+CisjaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bGFuZ3VhZ2UuaD4KKyNpbmNsdWRlIDxjb21iYXQuaD4KKyNpbmNsdWRlIDxhdHRyaWJ1dGVzLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorI2luY2x1ZGUgPG1vdmluZy5oPgorI2luY2x1ZGUgPG5ld19za2lsbHMuaD4KKworLy8gR2xvYmFsZSBWYXJpYWJsZW4KKyAgICAgICAgICAgICAgIGludCAgICAgZnRpbWUsIGZsYXc7Citwcml2YXRlIG5vc2F2ZSBpbnQgICAgIGxvZ2dlZDsKK3ByaXZhdGUgbm9zYXZlIGNsb3N1cmUgZGVmZW5kX2NsLCBoaXRfY2w7CisKK3ZvaWQgY3JlYXRlKCkgCit7CisgICAgLy8gVmFyaWFibGVuIGluaXRpYWxpc2llcmVuCisgICAgbG9nZ2VkPWZ0aW1lPWZsYXc9MDsKKyAgICBkZWZlbmRfY2w9MDsKKyAgICBoaXRfY2w9MDsKKworICAgIC8vIEVpbmlnZSBHcnVuZHdlcnRlIHNldHplbgorICAgIFNldFByb3AoUF9XRUFQT05fVFlQRSwgV1RfQ0xVQik7CisgICAgU2V0UHJvcChQX0RBTV9UWVBFLCAoe0RUX0JMVURHRU9OfSkpOworICAgIFNldFByb3AoUF9OUl9IQU5EUywgMik7CisgICAgU2V0UHJvcChQX1BBUlJZLFBBUlJZX05PVCk7CisgICAgU2V0UHJvcChQX0FDLDApOworICAgIFNldChQX1JFU1RSSUNUSU9OUywoW10pLEZfVkFMVUUpOworICAgIFNldChQX0xBU1RfVVNFLHRpbWUoKSxGX1ZBTFVFKTsKKworICAgIC8vIEVpbmlnZSBQcm9wZXJ0aWVzIHNvbGx0ZW4gbmljaHQgdm9uIGF1c3NlbiBnZXNldHp0IHdlcmRlbiBrb2VubmVuCisgICAgU2V0KFBfUEFSUlksICAgUFJPVEVDVEVELCBGX01PREVfQVMpOworICAgIFNldChQX1dJRUxERUQsIFBST1RFQ1RFRCwgRl9NT0RFX0FTKTsKKyAgICBTZXQoUF9MQVNUX1VTRSxQUk9URUNURUQsIEZfTU9ERV9BUyk7CisgICAgCisgICAgLy8gRGllc2Uga2FubiB2b24gYXVzc2VuIGdlc2V0enQgd2VyZGVuIChub2NoKSwgYWJlciBiaXR0ZSBudXIgdWViZXIgZGllCisgICAgLy8gaGllciBkZWZpbmllcnRlIFNldG1ldGhvZGUuCisgICAgU2V0KFBfREFNQUdFRCwgUFJPVEVDVEVELCBGX01PREVfQVMpOworCisgICAgLy8gRWluZSBXYWZmZSBiZW5vZXRpZ3QgS29tbWFuZG9zLCBtaXQgZGVuZW4gbWFuIHNpZSB6dWVja2VuIAorICAgIC8vIHVuZCB3ZWdzdGVja2VuIGthbm4KKyAgICBBZGRDbWQoICh7Inp1ZWNrIiwienVlY2tlIiwiemllaCIsInppZWhlIn0pLCAid2llbGQiICk7CisgICAgQWRkQ21kKCAoeyJzdGVjayIsInN0ZWNrZSJ9KSwgInVud2llbGQiICk7Cit9CisKKy8vIGFrdHVlbGxlcyBMZWJld2VzZW4sIHdhcyBkaWVzZSBXYWZmZSB6dXIgWmVpdCBnZXp1ZWNrdCBoYXQuCitwdWJsaWMgb2JqZWN0IFF1ZXJ5VXNlcigpCit7CisgIHJldHVybiBRdWVyeVByb3AoUF9XSUVMREVEKTsKK30KKworLyoKKyAqIEF1c2dhYmUgZWluZXIgTWVsZHVuZyBiZWltIFp1ZWNrZW4gZ2VodCBudXIgYW4gU3BpZWxlciwgbmljaHQgYW4gTlBDLgorICogRGllIFVtZ2VidW5nIGJla29tbXQgbmF0dWVybGljaCBpbW1lciBlaW5lIE1lbGR1bmcuCisgKi8KK3ZvaWQgZG9XaWVsZE1lc3NhZ2UoKQoreworICBzdHJpbmcgKnN0ciwgczE7CisgIAorICBpZihRdWVyeVByb3AoUF9XSUVMRF9NU0cpKSAgLy8gSXN0IGVpbmUgV2llbGRNc2cgZ2VzZXR6dD8KKyAgeworICAgIGlmKGNsb3N1cmVwKFF1ZXJ5UHJvcChQX1dJRUxEX01TRykpKSAgLy8gU29nYXIgYWxzIGVpZ2VuZSBGa3QuPworICAgIHsKKyAgICAgIHN0ciA9IGZ1bmNhbGwoUXVlcnlQcm9wKFBfV0lFTERfTVNHKSx0aGlzX3BsYXllcigpKTsKKworICAgICAgaWYoaW50ZXJhY3RpdmUodGhpc19wbGF5ZXIoKSkpCisgICAgICB7CisgICAgICAgIHRoaXNfcGxheWVyKCktPlJlY2VpdmVNc2coc3RyWzBdLAorICAgICAgICAgICAgTVRfTk9USUZJQ0FUSU9OfE1TR19CU19MRUFWRV9MRlMsIE1BX1dJRUxELCAwLAorICAgICAgICAgICAgdGhpc19wbGF5ZXIoKSk7CisgICAgICB9CisgICAgCisgICAgICBpZiAoIG9iamVjdHAoZW52aXJvbm1lbnQoKSkgJiYgb2JqZWN0cChlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSkgKQorICAgICAgICAgIHNlbmRfcm9vbShlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSwKKyAgICAgICAgICAgICAgc3RyWzFdLAorICAgICAgICAgICAgICBNVF9MT09LfE1TR19CU19MRUFWRV9MRlMsCisgICAgICAgICAgICAgIE1BX1dJRUxELCAwLCAoe3RoaXNfcGxheWVyKCl9KSwgZW52aXJvbm1lbnQoKSk7CisgICAgICByZXR1cm47CisgICAgfQorICAgIGVsc2UgaWYoaW50ZXJhY3RpdmUodGhpc19wbGF5ZXIoKSkpCisgICAgeworICAgICAgczEgPSByZXBsYWNlX3BlcnNvbmFsKHNwcmludGYoUXVlcnlQcm9wKFBfV0lFTERfTVNHKVswXSwiQFdFTjIiKSwKKwkJICAgICAgKHt0aGlzX3BsYXllcigpLHRoaXNfb2JqZWN0KCl9KSwgMSk7CisKKyAgICAgIHRoaXNfcGxheWVyKCktPlJlY2VpdmVNc2coczEsCisgICAgICAgICAgTVRfTk9USUZJQ0FUSU9OfE1TR19CU19MRUFWRV9MRlMsIE1BX1dJRUxELCAwLAorICAgICAgICAgIHRoaXNfcGxheWVyKCkpOyAKKyAgICB9CisKKyAgICAvLyBBYndhZXJ0c2tvbXBhdGliZWw6IERhcyBlcnN0ZSAlcyB3aXJkIHp1IFdFTjEsIGRhcyB6d2VpdGUgenUgV0VOMgorICAgIHMxID0gcmVwbGFjZV9wZXJzb25hbChzcHJpbnRmKFF1ZXJ5UHJvcChQX1dJRUxEX01TRylbMV0sIkBXRU4xIiwiQFdFTjIiKSwKKwkJICAgICh7dGhpc19wbGF5ZXIoKSwgdGhpc19vYmplY3QoKX0pLCAxKTsKKyAgICAgICAgCisgICAgaWYgKCBvYmplY3RwKGVudmlyb25tZW50KCkpICYmIG9iamVjdHAoZW52aXJvbm1lbnQoZW52aXJvbm1lbnQoKSkpICkKKyAgICAgICAgc2VuZF9yb29tKGVudmlyb25tZW50KGVudmlyb25tZW50KCkpLAorICAgICAgICAgICAgICBzMSwKKyAgICAgICAgICAgICAgTVRfTE9PS3xNU0dfQlNfTEVBVkVfTEZTLAorICAgICAgICAgICAgICBNQV9XSUVMRCwgMCwgKHt0aGlzX3BsYXllcigpfSksIGVudmlyb25tZW50KCkpOworICAgIHJldHVybjsKKyAgfQorICAvKgorICAgKiBLZWluZSBXaWVsZE1zZyBnZXNldHp0LCBBdXNnYWJlIGRlciBEZWZhdWx0LU1lbGR1bmdlbi4KKyAgICovCisgIGVsc2UgaWYoaW50ZXJhY3RpdmUodGhpc19wbGF5ZXIoKSkpCisgIHsKKyAgICB0aGlzX3BsYXllcigpLT5SZWNlaXZlTXNnKAorICAgICAgICAiRHUgenVlY2tzdCAiK25hbWUoV0VOLDEpKyIuIiwKKyAgICAgICAgTVRfTk9USUZJQ0FUSU9OLCBNQV9XSUVMRCwgMCwgdGhpc19wbGF5ZXIoKSk7CisgIH0KKyAgCisgIC8vcy5vLiBlcnNldHp0IGR1cmNoIHRlbGxfcm9vbSgpCisgIC8vc2F5KGJyZWFrX3N0cmluZyh0aGlzX3BsYXllcigpLT5OYW1lKFdFUikrIiB6dWVja3QgIgorICAvLyArbmFtZShXRU4sMCkrIi4iLDc4KSwoeyB0aGlzX3BsYXllcigpIH0pKTsKKyAgaWYgKCBvYmplY3RwKGVudmlyb25tZW50KCkpICYmIG9iamVjdHAoZW52aXJvbm1lbnQoZW52aXJvbm1lbnQoKSkpICkKKyAgICAgIHNlbmRfcm9vbShlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSwgICAgCisgICAgICAgICAgdGhpc19wbGF5ZXIoKS0+TmFtZShXRVIpKyIgenVlY2t0ICIrbmFtZShXRU4sMCkrIi4iLAorICAgICAgICAgIE1UX0xPT0ssCisgICAgICAgICAgTUFfV0lFTEQsIDAsICh7dGhpc19wbGF5ZXIoKX0pLCBlbnZpcm9ubWVudCgpKTsKK30KKworLyoKKyAqIEF1c2dhYmUgZWluZXIgTWVsZHVuZyBiZWltIFdlZ3N0ZWNrZW4gZ2VodCBudXIgYW4gU3BpZWxlciwgbmljaHQgYW4gTlBDLgorICogRGllIFVtZ2VidW5nIGJla29tbXQgaW1tZXIgZWluZSBNZWxkdW5nLgorICovCit2b2lkIGRvVW53aWVsZE1lc3NhZ2Uob2JqZWN0IHdpZWxkZWRfYnkpCit7CisgIHN0cmluZyAqc3RyLHMxOworCisgIGlmKCFvYmplY3RwKHdpZWxkZWRfYnkpKSAgLy8gSG9vcHMhIEdhciBuaWNodCBnZXp1ZWNrdD8gQWJicnVjaCEKKyAgeworICAgIHJldHVybjsKKyAgfQorCisgIGlmKFF1ZXJ5UHJvcChQX1VOV0lFTERfTVNHKSkgIC8vIEhpZXIgZ2lidCBlcyBlaW5lIFVud2llbGRNc2cuCisgIHsKKyAgICBpZihjbG9zdXJlcChRdWVyeVByb3AoUF9VTldJRUxEX01TRykpKSAgLy8gU29nYXIgYWxzIENsb3N1cmUsIHdvdyA6LSkKKyAgICB7CisgICAgICBzdHIgPSBmdW5jYWxsKFF1ZXJ5UHJvcChQX1VOV0lFTERfTVNHKSx3aWVsZGVkX2J5KTsKKworICAgICAgaWYoaW50ZXJhY3RpdmUod2llbGRlZF9ieSkpCisgICAgICB7IAorICAgICAgICB3aWVsZGVkX2J5LT5SZWNlaXZlTXNnKHN0clswXSwKKyAgICAgICAgICBNVF9OT1RJRklDQVRJT058TVNHX0JTX0xFQVZFX0xGUywgTUFfVU5XSUVMRCwgMCwgd2llbGRlZF9ieSk7CisgICAgICB9CisgICAgICBpZiAoIG9iamVjdHAoZW52aXJvbm1lbnQoKSkgJiYgb2JqZWN0cChlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSkgKQorICAgICAgICAgIHNlbmRfcm9vbShlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSwKKyAgICAgICAgICAgICAgc3RyWzFdLAorICAgICAgICAgICAgICBNVF9MT09LfE1TR19CU19MRUFWRV9MRlMsCisgICAgICAgICAgICAgIE1BX1VOV0lFTEQsIDAsICh7d2llbGRlZF9ieX0pLCBlbnZpcm9ubWVudCgpKTsKKyAgICAgIHJldHVybjsKKyAgICB9CisgIAorICAgIGVsc2UgaWYoaW50ZXJhY3RpdmUod2llbGRlZF9ieSkpCisgICAgeworICAgICAgczEgPSByZXBsYWNlX3BlcnNvbmFsKHNwcmludGYoUXVlcnlQcm9wKFBfVU5XSUVMRF9NU0cpWzBdLCJAV0VOMiIpLAorCQkgICAgICAoe3RoaXNfcGxheWVyKCksdGhpc19vYmplY3QoKX0pLCAxKTsgCisgICAgICB3aWVsZGVkX2J5LT5SZWNlaXZlTXNnKHMxLAorICAgICAgICAgIE1UX05PVElGSUNBVElPTnxNU0dfQlNfTEVBVkVfTEZTLCBNQV9VTldJRUxELCAwLCB3aWVsZGVkX2J5KTsKKyAgICB9CisKKyAgICBzMSA9IHJlcGxhY2VfcGVyc29uYWwoc3ByaW50ZihRdWVyeVByb3AoUF9VTldJRUxEX01TRylbMV0sIkBXRU4xIiwiQFdFTjIiKSwKKwkJICAgICh7d2llbGRlZF9ieSwgdGhpc19vYmplY3QoKX0pLCAxKTsKKyAgICAKKyAgICBpZiAoIG9iamVjdHAoZW52aXJvbm1lbnQoKSkgJiYgb2JqZWN0cChlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSkgKQorICAgICAgICAgIHNlbmRfcm9vbShlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSwKKyAgICAgICAgICAgICAgczEsCisgICAgICAgICAgICAgIE1UX0xPT0t8TVNHX0JTX0xFQVZFX0xGUywKKyAgICAgICAgICAgICAgTUFfVU5XSUVMRCwgMCwgKHt3aWVsZGVkX2J5fSksIGVudmlyb25tZW50KCkpOworICAgIHJldHVybjsKKyAgfQorICAvKgorICAgKiBLZWluZSBVbndpZWxkTXNnLCBhbHNvIERlZmF1bHQtTWVsZHVuZ2VuIGF1c2dlYmVuLgorICAgKi8KKyAgZWxzZSBpZihpbnRlcmFjdGl2ZSh3aWVsZGVkX2J5KSkKKyAgeworICAgIHdpZWxkZWRfYnktPlJlY2VpdmVNc2coCisgICAgICAgICJEdSBzdGVja3N0ICIrbmFtZShXRU4sMSkrIiB6dXJ1ZWNrLiIsCisgICAgICAgIE1UX05PVElGSUNBVElPTiwgTUFfVU5XSUVMRCwgMCwgd2llbGRlZF9ieSk7CisgIH0KKyAgaWYgKCBvYmplY3RwKGVudmlyb25tZW50KCkpICYmIG9iamVjdHAoZW52aXJvbm1lbnQoZW52aXJvbm1lbnQoKSkpICkKKyAgICAgIHNlbmRfcm9vbShlbnZpcm9ubWVudChlbnZpcm9ubWVudCgpKSwKKyAgICAgICAgICAgICAgd2llbGRlZF9ieS0+TmFtZShXRVIpICsiIHN0ZWNrdCAiK25hbWUoV0VOLDApKyIgenVydWVjay4iLAorICAgICAgICAgICAgICBNVF9MT09LLAorICAgICAgICAgICAgICBNQV9VTldJRUxELCAwLCAoe3dpZWxkZWRfYnl9KSwgZW52aXJvbm1lbnQoKSk7IAorfQorCisvLyBEaWVzZSBGdW5rdGlvbiB3aXJkIGF1ZmdlcnVmZW4sIHdlbm4gZGllIFdhZmZlIHdpcmtsaWNoIGdlenVlY2t0IHdpcmQKK3Byb3RlY3RlZCB2b2lkIEluZm9ybVdpZWxkKG9iamVjdCBwbCwgaW50IHNpbGVudCkKK3sKKyAgICByZXR1cm47Cit9CisgICAgIAorLy8gRGllc2UgRnVua3Rpb24gd2lyZCBhdWZnZXJ1ZmVuLCB3ZW5uIGRpZSBXYWZmZSB3aXJrbGljaCB3ZWdnZXN0ZWNrdAorLy8gd2lyZAorcHJvdGVjdGVkIHZvaWQgSW5mb3JtVW53aWVsZChvYmplY3QgcGwsIGludCBzaWxlbnQpIAoreworICAgIHJldHVybjsKK30KKworCisvLyB3aWVsZF9tZSBzb2xsIGtuYWxsZW4uIAordmFyYXJncyBpbnQgd2llbGRfbWUoaW50IHNpbGVudCkgCit7CisgIHJhaXNlX2Vycm9yKCJ3aWVsZF9tZSgpIGlzdCB2ZXJhbHRldC4gQml0dGUgbnV0emUgRG9XaWVsZCgpXG4iKTsKKyAgcmV0dXJuIDE7Cit9CisKKy8vIERpZSBGdW5rdGlvbiwgZGllIGRhcyBlaWdlbnRsaWNoZSBadWVja2VuIGR1cmNoZnVlaHJ0LgordmFyYXJncyBpbnQgRG9XaWVsZChpbnQgc2lsZW50KSAKK3sgICBpbnQgICAgIGRleCwgcGFycnk7CisgICAgY2xvc3VyZSBjbDsKKyAgICBtaXhlZCAgIHJlczsKKyAgCisgICAgLy8gTWFuIGthbm4gbnVyIFdhZmZlbiB6dWVja2VuLCBkaWUgbWFuIGF1Y2ggaW0gSW52ZW50b3J5IGhhdC4KKyAgICBpZiAoZW52aXJvbm1lbnQoKSE9UEwpIAorICAgIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCBicmVha19zdHJpbmcoCisgICAgICAgICAgICAiRHUgbXVzc3QgIituYW1lKFdFTiwxKSsiIHNjaG9uIGVyc3QgbmVobWVuISIsNzgpICk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8vIEVpbmUgZ2V6dWVja3RlIFdhZmZlIGthbm4gbWFuIG5hdHVlcmxpY2ggbmljaHQgbm9jaG1hbCB6dWVja2VuCisgICAgaWYgKFF1ZXJ5UHJvcChQX1dJRUxERUQpKSAKKyAgICB7CisgICAgICAgIG5vdGlmeV9mYWlsKCJEYXMgaGFzdCBEdSBzY2hvbiBnZW1hY2h0IVxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8vIFdhZmZlbiwgZGllIGVpbiBvZGVyIG1laHJlcmUgQXR0cmlidXQgdmVyYWVuZGVybiB1bmQgZ2VnZW4KKyAgICAvLyBkYXMgZ2VzZXR6dGUgTGltaXQgdmVyc3Rvc3NlbiwgaGFiZW4ga2VpbmUgV2lya3VuZyBiZXp1ZWdsaWNoIGRlcgorICAgIC8vIEF0dHJpYnV0ZS4KKyAgICBpZiAoIG1hcHBpbmdwKHJlcz1RdWVyeVByb3AoUF9NX0FUVFJfTU9EKSkgJiYgUEwtPlRlc3RMaW1pdFZpb2xhdGlvbihyZXMpICkKKyAgICB7CisgICAgICAgIHdyaXRlKGJyZWFrX3N0cmluZygKKyAgICAgICAgICAgICJJcmdlbmRldHdhcyBhbiBEZWluZXIgQXVzcnVlc3R1bmcgdmVyaGluZGVydCwgZGFzcyBEdSBEaWNoIG1pdCAiKworICAgICAgICAgICAgbmFtZShXRU0sMSkrIiBzbyByaWNodGlnIHdvaGwgZnVlaGxzdC4iLDc4KSk7CisgICAgfQorCisgICAgLy8gVWViZXIgUF9SRVNUUklDVElPTlMga2FubiBtYW4gZWluaWdlIFJlc3RyaWt0aW9uZW4gZGVmaW5pZXJlbiwgb2huZQorICAgIC8vIGdsZWljaCBhdWYgZWluZSBXaWVsZEZ1bmMgenVydWVja2dyZWlmZW4genUgbXVlc3Nlbi4KKyAgICAvLyBEaWUgQXVzd2VydHVuZyBlcmZvbGd0IHVlYmVyIGRlbiBSZXN0cmljdGlvbkNoZWNrZXIKKyAgICBpZiAoIChyZXM9UXVlcnlQcm9wKFBfUkVTVFJJQ1RJT05TKSkgJiYgbWFwcGluZ3AocmVzKSAmJgorICAgICAgICAgKHJlcz0oc3RyaW5nKWNhbGxfb3RoZXIoIi9zdGQvcmVzdHJpY3Rpb25fY2hlY2tlciIsImNoZWNrX3Jlc3RyaWN0aW9ucyIsCisgICAgICAgICAgICAgUEwscmVzKSkgJiYgc3RyaW5ncChyZXMpICkgCisgICAgeworICAgICAgICBub3RpZnlfZmFpbChyZXMpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBwYXJyeT0oaW50KVF1ZXJ5UHJvcChQX1BBUlJZKTsKKyAgICBkZXg9KGludClQTC0+UXVlcnlBdHRyaWJ1dGUoQV9ERVgpOworCisgICAgLy8gVGVzdGVuLCBvYiBkZXIgU3BpZWxlciBkaWUgbm9ldGlnZSBHZXNjaGlja2xpY2hrZWl0IGJlc2l0enQsIHVtCisgICAgLy8gbWl0IGRpZXNlciAoUGFyaWVyKVdhZmZlIHVtZ2VoZW4genUga29lbm5lbgorICAgIGlmICggKChwYXJyeTxQQVJSWV9PTkxZKSAmJiAoKGRleCs4KSoxMCk8UXVlcnlQcm9wKFBfV0MpKSB8fCAKKyAgICAgICAgICgocGFycnk+UEFSUllfTk9UKSAgJiYgKChkZXgrNSkqMiApPFF1ZXJ5UHJvcChQX0FDKSkgKQorICAgIHsKKyAgICAgICAgbm90aWZ5X2ZhaWwoCisgICAgICAgICAgICAiRHUgYmlzdCBuaWNodCBnZXNjaGlja3QgZ2VudWcsIHVtIG1pdCBkaWVzZXIgV2FmZmUgdW16dWdlaGVuLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8vIEVpbmUgR2V6dWVja3RlIFdhZmZlIG11c3MgbmF0dWVybGljaCBlcnN0IG1hbCB3ZWdnZXN0ZWNrdCB3ZXJkZW4uCisgICAgaWYgKCAocGFycnk8UEFSUllfT05MWSkgJiYgb2JqZWN0cChyZXM9KG9iamVjdClQTC0+UXVlcnlQcm9wKFBfV0VBUE9OKSkgKQorICAgIHsKKyAgICAgICAgaWYgKCAocmVzLT5Eb1Vud2llbGQoc2lsZW50KSkgJiYgISgob2JqZWN0KVBMLT5RdWVyeVByb3AoUF9XRUFQT04pKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIFdlbm4gZGllIGFsdGUgV2FmZmUgd2VnZ2VzdGVja3Qgd2VyZGVuIGtvbm50ZSwgbm9jaG1hbAorICAgICAgICAgICAgLy8gdmVyc3VjaGVuIHp1IHp1ZWNrZW4KKyAgICAgICAgICAgIHJldHVybiBEb1dpZWxkKHNpbGVudCk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSAKKyAgICAgICAgeworICAgICAgICAgICAgLy8gU29uc3QgTWVsZHVuZyBhdXNnZWJlbgorICAgICAgICAgICAgbm90aWZ5X2ZhaWwoIkRhcyBnZWh0IG5pY2h0LCBzb2xhbmdlIER1IG5vY2ggZWluZSBhbmRlcmUgIisKKyAgICAgICAgICAgICAgICAgIldhZmZlIGdlenVlY2t0IGhhc3QuXG4iKTsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorICAgIC8vIERhcyBnbGVpY2hlIGdpbHQgbmF0dWVybGljaCBmdWVyIFBhcmllcndhZmZlbgorICAgIGlmICggKHBhcnJ5PlBBUlJZX05PVCkgJiYgb2JqZWN0cChyZXM9KG9iamVjdClQTC0+UXVlcnlQcm9wKFBfUEFSUllfV0VBUE9OKSkgKQorICAgIHsKKyAgICAgICAgaWYgKCAocmVzLT5Eb1Vud2llbGQoc2lsZW50KSkgJiYgIShQTC0+UXVlcnlQcm9wKFBfUEFSUllfV0VBUE9OKSkgKQorICAgICAgICB7CisgICAgICAgICAgICAvLyBXZW5uIGRpZSBhbHRlIFBhcmllcndhZmZlIHdlZ2dlc3RlY2t0IHdlcmRlbiBrb25udGUsIG5vY2htYWwKKyAgICAgICAgICAgIC8vIHZlcnN1Y2hlbiB6dSB6dWVja2VuCisgICAgICAgICAgICByZXR1cm4gRG9XaWVsZChzaWxlbnQpOworICAgICAgICB9CisgICAgICAgIGVsc2UgCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIFNvbnN0IE1lbGR1bmcgYXVzZ2ViZW4KKyAgICAgICAgICAgIG5vdGlmeV9mYWlsKCJEYXMgZ2VodCBuaWNodCwgc29sYW5nZSBEdSBub2NoIGVpbmUgYW5kZXJlICIrCisgICAgICAgICAgICAgICAgICJQYWllcndhZmZlIGdlenVlY2t0IGhhc3QuXG4iKTsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gSXN0IGVpbmUgV2llbGRGdW5jIGdlc2V0enQsIHdpcmQgZGllc2UgYXVmZ2VydWZlbi4KKyAgICBpZiAob2JqZWN0cChyZXM9UXVlcnlQcm9wKFBfV0lFTERfRlVOQykpIAorCSYmICEocmVzLT5XaWVsZEZ1bmMoTUUsc2lsZW50LGVudmlyb25tZW50KCkpKSkKKyAgICB7CisgICAgICAgIC8vIEVpbmUgTWVsZHVuZyBzb2xsdGUgc2Nob24gdm9uIGRlciBXaWVsZEZ1bmMgYXVzZ2VnZWJlbiB3ZXJkZW4uCisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIC8vIERpZSB6dWxhZXNzaWdlbiBIb2VjaHN0d2VydGUgZHVlcmZlbiBuYXR1ZXJsaWNoIG5pY2h0CisgICAgLy8gdWViZXJzY2hyaXR0ZW4gd2VyZGVuLgorICAgIGlmICggKHBhcnJ5PFBBUlJZX09OTFkpICYmIChRdWVyeVByb3AoUF9XQyk+TUFYX1dFQVBPTl9DTEFTUykgKQorICAgIHsKKyAgICAgICAgbm90aWZ5X2ZhaWwoCisgICAgICAgICAgICAiVW5ndWVsdGlnZSBXYWZmZW5rbGFzc2UsIGJpdHRlIEVyem1hZ2llciB2ZXJzdGFlbmRpZ2VuLlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpZiAoIChwYXJyeT5QQVJSWV9OT1QpICYmIChRdWVyeVByb3AoUF9BQyk+TUFYX1BBUlJZX0NMQVNTKSApCisgICAgeworICAgICAgICBub3RpZnlfZmFpbCgKKyAgICAgICAgICAgICJVbmd1ZWx0aWdlIFBhcmllcmtsYXNzZSwgYml0dGUgRXJ6bWFnaWVyIHZlcnN0YWVuZGlnZW4uXG4iKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLy8gVGVzdGVuLCBvYiBkZXIgWnVlY2tlciBnZW51ZyBIYWVuZGUgZnJlaSBoYXQuICAKKyAgICBpZiAoIShQTC0+VXNlSGFuZHMoTUUsUXVlcnlQcm9wKFBfTlJfSEFORFMpKSkpCisgICAgeworICAgICAgICBub3RpZnlfZmFpbCgiRHUgaGFzdCBrZWluZSBIYW5kIG1laHIgZnJlaS5cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvLyBPaywgamV0enQgaXN0IGFsbGVzIGtsYXIsIGRpZSAoUGFyaWVyKVdhZmZlIHdpcmQgZ2V6dWVja3QKKyAgICBTZXRQcm9wKFBfV0lFTERFRCwgUEwpOworICAgIFNldFByb3AoUF9FUVVJUF9USU1FLHRpbWUoKSk7CisKKyAgICBjbD1zeW1ib2xfZnVuY3Rpb24oIlNldFByb3AiLFBMKTsKKworICAgIGlmIChwYXJyeTxQQVJSWV9PTkxZKQorICAgIHsKKyAgICAgICAgLy8gRGllc2VzIE9iamVrdCBhbHMgV2FmZmUgc2V0emVuCisgICAgICAgIGZ1bmNhbGwoY2wsUF9XRUFQT04sIE1FICk7CisgICAgfQorICAgIGlmIChwYXJyeT5QQVJSWV9OT1QpCisgICAgeworICAgICAgICAvLyBEaWVzZXMgT2JqZWt0IGFscyBQYXJpZXJ3YWZmZSBzZXR6ZW4KKyAgICAgICAgZnVuY2FsbChjbCxQX1BBUlJZX1dFQVBPTiwgTUUgKTsKKyAgICB9CisKKyAgICAvLyBXYWZmZW4ga29lbm5lbiBBdHRyaWJ1dGUgYWVuZGVybi9ibG9ja2llcmVuLiBBbHNvIG11ZXNzZW4gZGllc2UKKyAgICAvLyBuYWNoIGRlbSBadWVja2VuIGFrdHVhbGlzaWVydCB3ZXJkZW4KKyAgICBQTC0+cmVnaXN0ZXJfbW9kaWZpZXIoTUUpOworICAgIFBMLT5VcGRhdGVBdHRyaWJ1dGVzKCk7CisKKyAgICAvLyBQX1RPVEFMX0FDL1BfVE9UQUxfV0MgaW0gU3BpZWxlciBha3R1YWxpc2llcmVuLiBEYSBkb3J0IEF0dHJpYnV0ZQorICAgIC8vIGVpbmdlaGVuLCBrYW5uIGRhcyBlcnN0IGhpZXIgZ2VtYWNodCB3ZXJkZW4uCisgICAgaWYgKHBhcnJ5PFBBUlJZX09OTFkpCisgICAgeworICAgICAgICBQTC0+UXVlcnlQcm9wKFBfVE9UQUxfV0MpOworICAgIH0KKyAgICBpZiAocGFycnk+UEFSUllfTk9UKQorICAgIHsKKyAgICAgICAgUEwtPlF1ZXJ5UHJvcChQX1RPVEFMX0FDKTsKKyAgICB9CisKKyAgICAvLyBadWVjay1NZWxkdW5nIGF1c2dlYmVuLCB3ZW5uIGRhcyBzaWxlbnQtRmxhZyBuaWNodCBnZXNldHp0IGlzdAorICAgIGlmICghc2lsZW50KQorICAgIHsKKyAgICAgICAgZG9XaWVsZE1lc3NhZ2UoKTsKKyAgICB9CisKKyAgICAvLyBBbGxlIFdhZmZlbiB3ZXJkZW4gaW0gYXdtYXN0ZXIgcmVnaXN0cmllcnQsIHNvYmFsZCBzaWUgdm9uIGVpbmVtCisgICAgLy8gU3BpZWxlciBnZXp1ZWNrdCB3ZXJkZW4KKyAgICBpZiAoIWxvZ2dlZCAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKFBMKSkgCisgICAgeworICAgICAgICBjYWxsX290aGVyKCIvc2VjdXJlL2F3bWFzdGVyIiwiUmVnaXN0ZXJXZWFwb24iLE1FKTsKKyAgICAgICAgbG9nZ2VkPTE7CisgICAgfQorCisgICAgLy8gSW5mb3JtLUZ1bmt0aW9uIGF1ZnJ1ZmVuCisgICAgSW5mb3JtV2llbGQoUEwsc2lsZW50KTsKKworICAgIC8vIEZlcnRpZyBtaXQgZGVtIFp1ZWNrZW4KKyAgICByZXR1cm4gMTsKK30KKworLy8gRGllIEZ1bmt0aW9uLCBkaWUgZGFzIGVpZ2VudGxpY2hlIFdlZ3N0ZWNrZW4gZHVyY2hmdWVocnQuCit2YXJhcmdzIGludCBEb1Vud2llbGQoaW50IHNpbGVudCkgCit7ICAgY2xvc3VyZSBjbDsKKyAgICBpbnQgICAgIHBhcnJ5OworICAgIG1peGVkICAgcmVzOworICAgIG9iamVjdCAgd2llbGRlZF9ieTsKKworICAgIC8vIFdhZmZlbiwgZGllIG5pY2h0IGdlenVlY2t0IHNpbmQsIGthbm4gbWFuIG5hdHVlcmxpY2ggbmljaHQKKyAgICAvLyB3ZWdzdGVja2VuCisgICAgaWYgKCFvYmplY3RwKHdpZWxkZWRfYnk9UXVlcnlQcm9wKFBfV0lFTERFRCkpKQorICAgIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLy8gSXN0IGVpbmUgVW53aWVsZEZ1bmMgZ2VzZXR6dCwgd2lyZCBkaWVzZSBhdWZnZXJ1ZmVuCisgICAgaWYgKCBvYmplY3RwKHJlcz1RdWVyeVByb3AoUF9VTldJRUxEX0ZVTkMpKSAmJgorICAgICAgICAgIShyZXMtPlVud2llbGRGdW5jKE1FLHNpbGVudCx3aWVsZGVkX2J5KSkgKSAKKyAgICB7CisgICAgICAgIC8vIEVpbmUgTWVsZHVuZyBtdXNzIGRpZSBVbndpZWxkRnVuYyBzY2hvbiBzZWxic3QgYXVzZ2ViZW4uCisgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIC8vIEVpbmUgdmVyZmx1Y2h0ZSBXYWZmZSBrYW5uIG1hbiBuYXR1ZXJsaWNoIG5pY2h0IHdlZ3N0ZWNrZW4gLSBhYmVyCisgICAgLy8gYXVjaCBkYSBnaWJ0cyBBdXNuYWhtZWZhZWxsZSwgd2llIHouQi4gZGVuIFRvZCBlaW5lcyBTcGllbGVycworICAgIGlmICgocmVzPVF1ZXJ5UHJvcChQX0NVUlNFRCkpICYmICEoc2lsZW50Jk1fTk9DSEVDSykpIAorICAgIHsKKyAgICAgICAgaWYgKHN0cmluZ3AocmVzKSkKKyAgICAgICAgeworICAgICAgICAgICAgLy8gU3RhbmQgaW4gUF9DVVJTRUQgZWluIFN0cmluZz8gRGFubiBkaWVzZW4gYXVzZ2ViZW4KKyAgICAgICAgICAgIHRlbGxfb2JqZWN0KHdpZWxkZWRfYnksIAorICAgICAgICAgICAgICAgIChyZXNbPDFdPT0nXG4nID8gcmVzIDogYnJlYWtfc3RyaW5nKHJlcyw3OCkpKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIFNvbnN0IGVpbmUgU3RhbmRhcmQtTWVsZHVuZyBhdXNnZWJlbgorICAgICAgICAgICAgdGVsbF9vYmplY3Qod2llbGRlZF9ieSwgYnJlYWtfc3RyaW5nKAorICAgICAgICAgICAgICAgICJEdSBrYW5uc3QgIituYW1lKFdFTikrIiBuaWNodCB3ZWdzdGVja2VuLiIsNzgpKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICAvLyBPaywgamV0enQgaXN0IGFsbGVzIGtsYXIsIGRpZSAoUGFyaWVyKVdhZmZlIHdpcmQgd2VnZ2VzdGVja3QKKyAgICBwYXJyeT1RdWVyeVByb3AoUF9QQVJSWSk7CisgICAgY2w9c3ltYm9sX2Z1bmN0aW9uKCJTZXRQcm9wIix3aWVsZGVkX2J5KTsKKworICAgIGlmIChwYXJyeTxQQVJSWV9PTkxZKQorICAgIHsKKyAgICAgICAgLy8gRWludHJhZyBhbHMgV2FmZmUgaW0gU3BpZWxlciBsb2VzY2hlbgorICAgICAgICBmdW5jYWxsKGNsLFBfV0VBUE9OLCAwKTsKKyAgICB9CisgICAgaWYgKHBhcnJ5PlBBUlJZX05PVCkKKyAgICB7CisgICAgICAgIC8vIEVpbnRyYWcgYWxzIFBhcmllcndhZmZlIGltIFNwaWVsZXIgbG9lc2NoZW4KKyAgICAgICAgZnVuY2FsbChjbCxQX1BBUlJZX1dFQVBPTiwgMCk7CisgICAgfQorCisgICAgLy8gSW0gU3BpZWxlciBkaWUgWmVpdCBzZXR6ZW4sIHp1IGRlciBlciB6dWxldHp0IGVpbmUgV2FmZmUgd2VnZ2VzdGVja3QKKyAgICAvLyBoYXQuCisgICAgZnVuY2FsbChjbCxQX1VOV0lFTERfVElNRSx0aW1lKCkpOworCisgICAgLy8gTWVsZHVuZyBhdXNnZWJlbiwgd2VubiBzaWxlbnQtRmxhZyBuaWNodCBnZXNldHp0IGlzdAorICAgIGlmICghc2lsZW50KSAKKyAgICB7CisgICAgICAgIGRvVW53aWVsZE1lc3NhZ2Uod2llbGRlZF9ieSk7CisgICAgfSAKKworICAgIC8vIERpZSBIYWVuZGUsIGRpZSBiaXNoZXIgdm9uIGRlciBXYWZmZSBiZW51dHp0IHd1cmRlbiwgZnJlaWdlYmVuCisgICAgd2llbGRlZF9ieS0+RnJlZUhhbmRzKE1FKTsKKyAgICBTZXRQcm9wKFBfV0lFTERFRCwgMCk7CisKKyAgICAvLyBXYWZmZW4ga29lbm5lbiBBdHRyaWJ1dGUgYWVuZGVybi9ibG9ja2llcmVuLiBBbHNvIG11ZXNzZW4gZGllc2UKKyAgICAvLyBuYWNoIGRlbSBXZWdzdGVja2VuIGFrdHVhbGlzaWVydCB3ZXJkZW4KKyAgICB3aWVsZGVkX2J5LT5kZXJlZ2lzdGVyX21vZGlmaWVyKE1FKTsKKyAgICB3aWVsZGVkX2J5LT5VcGRhdGVBdHRyaWJ1dGVzKCk7CisKKyAgICAvLyBQX1RPVEFMX0FDL1BfVE9UQUxfV0MgaW0gU3BpZWxlciBha3R1YWxpc2llcmVuLiBEYSBkb3J0IEF0dHJpYnV0ZQorICAgIC8vIGVpbmdlaGVuLCBrYW5uIGRhcyBlcnN0IGhpZXIgZ2VtYWNodCB3ZXJkZW4uCisgICAgaWYgKHBhcnJ5PFBBUlJZX09OTFkpCisgICAgeworICAgICAgICB3aWVsZGVkX2J5LT5RdWVyeVByb3AoUF9UT1RBTF9XQyk7CisgICAgfQorICAgIGlmIChwYXJyeT5QQVJSWV9OT1QpCisgICAgeworICAgICAgICB3aWVsZGVkX2J5LT5RdWVyeVByb3AoUF9UT1RBTF9BQyk7CisgICAgfQorCisgICAgLy8gSW5mb3JtLUZ1bmt0aW9uIGF1ZnJ1ZmVuCisgICAgSW5mb3JtVW53aWVsZCh3aWVsZGVkX2J5LCBzaWxlbnQpOworCisgICAgLy8gRmVydGlnIG1pdCBkZW0gV2Vnc3RlY2tlbgorICAgIHJldHVybiAxOworfQorCisvLyBEaWUgRnVua3Rpb24sIGRpZSBkYXMgInp1ZWNrZW4iLUtvbW1hbmRvIGF1c3dlcnRldAordmFyYXJncyBpbnQgd2llbGQoc3RyaW5nIHN0ciwgaW50IHNpbGVudCkgCit7CisgICAgaWYgKCAhc3RyaW5ncChzdHIpIHx8CisgICAgICAgICAocXVlcnlfdmVyYigpWzAuLjNdPT0iemllaCIgJiYgc3NjYW5mKHN0ciwiJXMgaGVydm9yIixzdHIpIT0xKSApCisgICAgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAoIWlkKHN0cikpIAorICAgIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJEdSBoYXN0IHNvd2FzIG5pY2h0LlxuIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHJldHVybiBEb1dpZWxkKHNpbGVudCk7Cit9CisKKy8vIERpZSBGdW5rdGlvbiwgZGllIGRhcyAid2Vnc3RlY2tlbiItS29tbWFuZG8gYXVzd2VydGV0CitpbnQgdW53aWVsZChzdHJpbmcgc3RyKSAKK3sgICBpbnQgICAgcGFycnk7CisgICAgc3RyaW5nIGR1bW15OworCisgICAgLy8gRXJzdG1hbCBkaWUgRWluZ2FiZSBhdXN3ZXJ0ZW4uIElzdCBkaWVzIHdpcmtsaWNoIGVpbiBLb21tYW5kbworICAgIC8vIHp1bSBXZWdzdGVja2VuPworICAgIGlmICggIXN0cmluZ3Aoc3RyKSB8fCAoc3NjYW5mKHN0ciwiJXMgd2VnIiwgICAgIGR1bW15KSE9MSAgJiYgCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzc2NhbmYoc3RyLCIlcyBlaW4iLCAgICAgZHVtbXkpIT0xICAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgc3NjYW5mKHN0ciwiJXMgenVydWVjayIsIGR1bW15KSE9MSApICkKKyAgICB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHN0ciA9IGR1bW15OworICAgIHBhcnJ5PVF1ZXJ5UHJvcChQX1BBUlJZKTsKKworICAgIC8vIElzdCB3aXJrbGljaCBkaWVzZSBXYWZmZSBnZW1laW50PworICAgIGlmICggIXN0cmluZ3Aoc3RyKSB8fCAhaWQoc3RyKSB8fAorICAgICAgICAgKChwYXJyeTxQQVJSWV9PTkxZKSYmKChvYmplY3QpUEwtPlF1ZXJ5UHJvcChQX1dFQVBPTikhPU1FKSkgfHwKKyAgICAgICAgICgocGFycnk+UEFSUllfTk9UKSYmKChvYmplY3QpUEwtPlF1ZXJ5UHJvcChQX1BBUlJZX1dFQVBPTikhPU1FKSkgKQorICAgIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLy8gTWFuIGthbm4gbnVyIFdhZmZlbiB3ZWdzdGVja2VuLCBkaWUgbWFuIGF1Y2ggYmVpIHNpY2ggaGF0CisgICAgaWYgKGVudmlyb25tZW50KCkgIT0gUEwpIAorICAgIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJEaWVzZSBXYWZmZSBnZWhvZXJ0IERpciBuaWNodCFcbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvLyBVbmQgbmF0dWVybGljaCBnZWh0IGRhcyBhdWNoIG51ciwgd2VubiBkaWUgV2FmZmUgZ2V6dWVja3QgaXN0LgorICAgIGlmICghUXVlcnlQcm9wKFBfV0lFTERFRCkpIAorICAgIHsKKyAgICAgICAgX25vdGlmeV9mYWlsKCJEaWVzZSBXYWZmZSBoYXN0IER1IGdhciBuaWNodCBnZXp1ZWNrdCAuLi5cbiIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICByZXR1cm4gRG9VbndpZWxkKCk7Cit9CisKKy8vIERpZSBGdW5rdGlvbiwgZGllIGRlbiBTY2hhZGVuIGJlcmVjaG5ldCwgZGVuIGRpZSBXYWZmZSB2ZXJ1cnNhY2h0CitpbnQgUXVlcnlEYW1hZ2Uob2JqZWN0IGVuZW15KQoreyAgIGludCAgICBkYW07CisgICAgbWl4ZWQgIGhpdF9mdW5jOworICAgIG9iamVjdCB3aWVsZGVyOworCisgICAgLy8gTnVyIGdlenVlY2t0ZSBXYWZmZW4gbWFjaGVuIFNjaGFkZW4KKyAgICBpZiAoIW9iamVjdHAod2llbGRlcj1RdWVyeVByb3AoUF9XSUVMREVEKSkpCisgICAgICAgIHJldHVybiAwOworCisgICAgLy8gRGVuIEJhc2lzLVNjaGFkZW4gYmVyZWNobmVuLiBEaWUgU3RhZXJrZSBkZXMgQmVudXR6ZXJzIHdpcmQKKyAgICAvLyBoaWVyIGJlcnVlY2tzaWNodGlndC4KKyAgICBkYW0gPSAoMipRdWVyeVByb3AoUF9XQykrMTAqKChpbnQpd2llbGRlci0+UXVlcnlBdHRyaWJ1dGUoQV9TVFIpKSkvMzsKKworICAgIC8vIFdpZSBndXQgbWFuIGdldHJvZmZlbiBoYXQsIHdpcmQgdWViZXIgZWluIHJhbmRvbSgpIHNpbXVsaWVydAorICAgIGRhbSA9IHJhbmRvbSgxK2RhbSk7CisKKyAgICAvLyBJc3QgZWluZSBIaXRGdW5jIGdlc2V0enQsIGRhbm4gd2lyZCBkaWVzZSBhdXNnZXdlcnRldC4gRGVyIAorICAgIC8vIFJ1ZWNrZ2FiZS1XZXJ0IHdpcmQgenVtIFNjaGFkZW4gYWRkaWVydAorICAgIGlmICghaGl0X2NsIHx8ICFnZXRfdHlwZV9pbmZvKGhpdF9jbCwyKSkKKyAgICB7CisgICAgICAgIGlmIChvYmplY3RwKGhpdF9mdW5jPVF1ZXJ5UHJvcChQX0hJVF9GVU5DKSkpCisgICAgICAgIHsKKyAgICAgICAgICAgIGhpdF9jbD1zeW1ib2xfZnVuY3Rpb24oIkhpdEZ1bmMiLGhpdF9mdW5jKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoaGl0X2NsICYmIGdldF90eXBlX2luZm8oaGl0X2NsLDIpKQorICAgIHsKKyAgICAgICAgZGFtICs9IGZ1bmNhbGwoaGl0X2NsLGVuZW15KTsKKyAgICB9CisKKyAgICAvLyBaZWl0cHVua3QgZGVyIGxldHp0ZW4gQmVudXR6dW5nIGF1c2dlYmVuCisgICAgU2V0UHJvcChQX0xBU1RfVVNFLHRpbWUoKSk7CisKKyAgICAvLyBCZXJlY2huZXRlbiBTY2hhZGVuIHp1cnVlY2tnZWJlbgorICAgIHJldHVybiBkYW07Cit9CisKKy8vIERpZSBGdW5rdGlvbiwgZGllIGJlaSBQYXJpZXJ3YWZmZW4gZGVuIFNjaHV0endlcnQgYmVyZWNobmV0LgoraW50IFF1ZXJ5RGVmZW5kKHN0cmluZyogZGFtX3R5cGUsIG1peGVkIHNwZWxsLCBvYmplY3QgZW5lbXkpIAoreyAgIGludCAgICAgcHJvdDsKKyAgICBtaXhlZCAgIGRlZl9mdW5jOworICAgIG9iamVjdCAgcGw7CisKKyAgICBwcm90ID0gMDsKKworICAgIC8vIFJ1ZXN0dW5nZW4gc2NodWV0emVuIG51ciBnZWdlbiBwaHlzaWthbGlzY2hlbiBTY2hhZGVuCisgICAgaWYgKCFzcGVsbCB8fCAobWFwcGluZ3Aoc3BlbGwpICYmIHNwZWxsW1NQX1BIWVNJQ0FMX0FUVEFDS10pKQorICAgIHsKKyAgICAgICAgaWYgKHNpemVvZihmaWx0ZXIoZGFtX3R5cGUsUEhZU0lDQUxfREFNQUdFX1RZUEVTKSkpCisgICAgICAgIHsKKyAgICAgICAgICAgIHByb3QgPSByYW5kb20oMStRdWVyeVByb3AoUF9BQykpOworICAgICAgICB9CisgICAgfQorCisgICAgLy8gSXN0IGVpbmUgRGVmZW5kRnVuYyBnZXNldHp0LCB3aXJkIGRpZXNlIGF1c2dld2VydGV0CisgICAgaWYgKCFkZWZlbmRfY2wgfHwgIWdldF90eXBlX2luZm8oZGVmZW5kX2NsLDIpKQorICAgIHsKKyAgICAgICAgaWYgKG9iamVjdHAoZGVmX2Z1bmM9UXVlcnlQcm9wKFBfREVGRU5EX0ZVTkMpKSkgCisgICAgICAgIHsKKyAgICAgICAgICAgIGRlZmVuZF9jbD1zeW1ib2xfZnVuY3Rpb24oIkRlZmVuZEZ1bmMiLGRlZl9mdW5jKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAvL0JlaSBOZXR6dG90ZW4ga2VpbmUgKHp1cnVlY2tzY2hsYWdlbmRlKSBEZWZlbmRGdW5jCisgICAgaWYgKGRlZmVuZF9jbCAmJiBnZXRfdHlwZV9pbmZvKGRlZmVuZF9jbCwyKSAmJgorICAgICAgICBvYmplY3RwKHBsPVF1ZXJ5UHJvcChQX1dJRUxERUQpKSAmJiAoIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUocGwpIHx8CisgICAgICAgIGludGVyYWN0aXZlKHBsKSkgKQorICAgIHsKKyAgICAgICAgLy8gRGVyIFJ1ZWNrZ2FiZXdlcnQgZGVyIERlZmVuZEZ1bmMgd2lyZCB6dW0gU2NodXR6IGFkZGllcnQKKyAgICAgICAgcHJvdCArPSBmdW5jYWxsKGRlZmVuZF9jbCwgZGFtX3R5cGUsIHNwZWxsLCBlbmVteSk7CisgICAgfQorCisgICAgLy8gWmVpdHB1bmt0IGRlciBsZXR6dGVuIEJlbnV0enVuZyBhdXNnZWJlbgorICAgIFNldFByb3AoUF9MQVNUX1VTRSx0aW1lKCkpOworCisgICAgLy8gQmVyZWNobmV0ZW4gU2NodXR6IHp1cnVlY2tnZWJlbgorICAgIHJldHVybiBwcm90OworfQorCisvLyBEaWUgQW56YWhsIGRlciB2b24gZWluZXIgV2FmZmUgYmVub2V0aWd0ZW4gSGFlbmRlIGRhcmYgbmF0dWVybGljaCBuaWNodAorLy8ga2xlaW5lciBhbHMgMSBzZWluLgoraW50IF9zZXRfbnJfaGFuZHMoaW50IGFyZykKK3sKKyAgICBpZiAoIWludHAoYXJnKSB8fCAoYXJnPDEpICkKKyAgICAgICAgcmV0dXJuIFF1ZXJ5KFBfTlJfSEFORFMsIEZfVkFMVUUpOworICAgIHJldHVybiBTZXQoUF9OUl9IQU5EUywgYXJnLCBGX1ZBTFVFKTsKK30KKworLy8gRGVyIFNjaGFkZW5zdHlwIGVpbmVyIFdhZmZlIGRhcmYgendhciBhbHMgc3RyaW5nIGFuZ2VnZWJlbiB3ZXJkZW4sIHdpcmQKKy8vIGludGVybiBhYmVyIGltbWVyIGFscyBhcnJheSBnZXNwZWljaGVydAorbWl4ZWQgX3NldF9kYW1fdHlwZShtaXhlZCBhcmcpCit7CisgICAgaWYgKHBvaW50ZXJwKGFyZykpCisgICAgeworICAgICAgICByZXR1cm4gU2V0KFBfREFNX1RZUEUsIGFyZywgRl9WQUxVRSk7CisgICAgfQorICAgIGVsc2UgaWYgKHN0cmluZ3AoYXJnKSkKKyAgICB7CisgICAgICAgIHJldHVybiBTZXQoUF9EQU1fVFlQRSwgKHsgYXJnIH0pLCBGX1ZBTFVFKTsKKyAgICB9CisgICAgcmV0dXJuIFF1ZXJ5KFBfREFNX1RZUEUsIEZfVkFMVUUpOworfQorCisvLyBPYmpla3RlLCBkaWUgZGllIEJlc2NoYWVkaWd1bmcgZWluZXIgV2FmZmUgZHVyY2ggZGlyZWt0ZXMgU2V0emVuIHZvbgorLy8gUF9EQU1BR0VEIGR1cmNoZnVlaHJlbiwgd2VyZGVuIGltIGF3bWFzdGVyIGdlbG9nZ3QKK21peGVkIF9zZXRfaXRlbV9kYW1hZ2VkKG1peGVkIGFyZykKK3sKKyAgICBpZiAoYXJnICYmICFpbnRwKGFyZykpCisgICAgeworICAgICAgICByZXR1cm4gUXVlcnkoUF9EQU1BR0VELCBGX1ZBTFVFKTsKKyAgICB9CisKKyAgICBpZiAocHJldmlvdXNfb2JqZWN0KDEpKQorICAgICAgY2FsbF9vdGhlcigiL3NlY3VyZS9hd21hc3RlciIsIlJlZ2lzdGVyRGFtYWdlciIsCisgICAgICAgICAgICBwcmV2aW91c19vYmplY3QoMSksUXVlcnlQcm9wKFBfREFNQUdFRCksYXJnKTsKKyAgICAKKyAgICByZXR1cm4gU2V0KFBfREFNQUdFRCxhcmcsRl9WQUxVRSk7Cit9CisKKy8vIFdpcmQgZXR3YXMgYW4gUF9ISVRfRlVOQyBnZWFlbmRlcnQsIG11c3MgZGllIHp1Z2Vob2VyaWdlIGNsb3N1cmUKKy8vIGVyc3RtYWwgZ2Vsb2VzY2h0IHdlcmRlbi4KK21peGVkIF9zZXRfaGl0X2Z1bmMobWl4ZWQgYXJnKQoreworICAgIGhpdF9jbD0wOworICAgIHJldHVybiBTZXQoUF9ISVRfRlVOQywgYXJnLCBGX1ZBTFVFKTsKK30KKworLy8gV2lyZCBldHdhcyBhbiBQX0RFRkVORF9GVU5DIGdlYWVuZGVydCwgbXVzcyBkaWUgenVnZWhvZXJpZ2UgY2xvc3VyZQorLy8gZXJzdG1hbCBnZWxvZXNjaHQgd2VyZGVuLgorbWl4ZWQgX3NldF9kZWZlbmRfZnVuYyhtaXhlZCBhcmcpCit7CisgICAgZGVmZW5kX2NsPTA7CisgICAgcmV0dXJuIFNldChQX0RFRkVORF9GVU5DLCBhcmcsIEZfVkFMVUUpOworfQorCisvLyBEaWUgbWF4aW1hbGUgV2FmZmVua2xhc3NlIGVpbmVyIFdhZmZlIGJlcmVjaG5ldCBzaWNoIG5hdHVlcmxpY2ggYXVzCisvLyBkZXIgYWt0dWVsbGVuIFdhZmZlbmtsYXNzZSB1bmQgZGVyIEJlc2NoYWVkaWd1bmcuIEVpbmUgQXVzbmFobWUgYmlsZGVuCisvLyBoaWVyIFdhZmZlbiwgZGVyZW4gZWZmZWt0aXZlIFdhZmZlbmtsYXNzZSBncm9lc3NlciBpc3QgYWxzIGRpZXNlIFN1bW1lCitpbnQgIF9xdWVyeV9tYXhfd2MoKSAKK3sgICBpbnQgYSxiOworCisgICAgYT1RdWVyeVByb3AoUF9XQykrUXVlcnlQcm9wKFBfREFNQUdFRCk7CisgICAgYj1RdWVyeVByb3AoUF9FRkZFQ1RJVkVfV0MpOworICAgIGlmIChiPmEpCisgICAgICAgIHJldHVybiBiOworICAgIHJldHVybiBhOworfQorCisvLyBXaWxsIG1hbiBlaW5lIFdhZmZlIGJlc2NoYWVkaWdlbiBvZGVyIHJlcGFyaWVyZW4sIHNvIG1hY2h0IG1hbiBkYXMKKy8vIGFtIGJlc3RlbiB1ZWJlciBkaWUgRnVua3Rpb24gRGFtYWdlKGFyZ3VtZW50KS4gUG9zaXRpdmUgQXJndW1lbnRlCisvLyBiZWRldXRlbiBlaW5lIEJlc2NoYWVkaWd1bmcsIG5lZ2F0aXZlIGVpbmUgUmVwYXJhdHVyLiBEZXIgUnVlY2tnYWJld2VydAorLy8gaXN0IGRpZSB3aXJrbGljaCBkdXJjaGdlZnVlaHJ0ZSBBZW5kZXJ1bmcgZGVzIEJlc2NoYWVkaWd1bmdzd2VydGVzCitpbnQgRGFtYWdlKGludCBuZXdfZGFtKQoreyAgIGludCAgICB3YyxvbGRfZGFtOworICAgIG9iamVjdCB3OworCisgICAgLy8gVWViZXJnZWJlbmVzIEFyZ3VtZW50IHBydWVmZW4KKyAgICBpZiAoIW5ld19kYW0gfHwgIWludHAobmV3X2RhbSkpCisgICAgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvLyBCZWkgV2FmZmVuLCBkaWUgbmljaHQgYXVzc2NobGllc3NsaWNoIHp1ciBQYXJhZGUgZWluZ2VzZXR6dCB3ZXJkZW4sCisgICAgLy8gZ2VodCBkaWUgQmVzY2hhZWRpZ3VuZyBhdWYgZGllIEthbXBma3JhZnQsIHNwcmljaDogUF9XQworICAgIGlmIChRdWVyeVByb3AoUF9QQVJSWSk8UEFSUllfT05MWSkKKyAgICB7CisgICAgICAgIGlmICgod2M9UXVlcnlQcm9wKFBfV0MpKTw9TUlOX1dFQVBPTl9DTEFTUyAmJiBuZXdfZGFtPjApCisgICAgICAgIHsKKyAgICAgICAgICAgIC8vIFNvbnN0IHd1ZXJkZSBCZXNjaGFlZGlndW5nIHp1ciBSZXBhcmF0dXIgZnVlaHJlbgorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgICAgICAvLyBNaW4tV0MgdW5kIE1heC1XQyBiZWFjaHRlbgorICAgICAgICBpZiAoKHdjLW5ld19kYW0pIDwgTUlOX1dFQVBPTl9DTEFTUykKKyAgICAgICAgeworICAgICAgICAgICAgbmV3X2RhbSA9IHdjLU1JTl9XRUFQT05fQ0xBU1M7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoKHdjLW5ld19kYW0pID4gTUFYX1dFQVBPTl9DTEFTUykKKyAgICAgICAgeworICAgICAgICAgICAgbmV3X2RhbSA9IHdjLU1BWF9XRUFQT05fQ0xBU1M7CisgICAgICAgIH0KKworICAgICAgICAvLyBOaWUgbWVociBhbHMgMTAwJSByZXBhcmllcmVuCisgICAgICAgIGlmICgoKG9sZF9kYW09UXVlcnlQcm9wKFBfREFNQUdFRCkpPC1uZXdfZGFtKSAmJiBuZXdfZGFtPDApCisgICAgICAgIHsKKyAgICAgICAgICAgIG5ld19kYW09LW9sZF9kYW07CisgICAgICAgIH0KKworICAgICAgICAvLyBBZW5kZXJ1bmdlbiBhbiBkZXIgV2FmZmVua2xhc3NlIHVuZCBkZXIgZGVtIEJlc2NoYWVkaWd1bmdzd2VydAorICAgICAgICAvLyBkdXJjaGZ1ZWhyZW4KKyAgICAgICAgU2V0UHJvcChQX1dDLCh3Yy1uZXdfZGFtKSk7CisgICAgICAgIC8vIEF1c25haG1ld2Vpc2UgU2V0LCB1bSBkaWUgbG9nZ2VuZGUgU2V0bWV0aG9kZSB6dSB1bWdlaGVuLgorCS8vIFRPRE86IFNldFByb3AsIHNvYmFsZCBkaXJla3RlcyBCZXNjaGFlZGlnZW4gcmF1cyBpc3QuCisJU2V0KFBfREFNQUdFRCwgb2xkX2RhbStuZXdfZGFtLCBGX1ZBTFVFKTsKKworICAgICAgICAvLyBQX1RPVEFMX1dDIGltIFRyYWVnZXIgdXBkYXRlbiwgc28gdm9yaGFuZGVuCisgICAgICAgIGlmIChvYmplY3RwKHc9UXVlcnlQcm9wKFBfV0lFTERFRCkpKQorICAgICAgICAgICAgdy0+UXVlcnlQcm9wKFBfVE9UQUxfV0MpOworCisgICAgICAgIC8vIFJ1ZWNrZ2FiZXdlcnQ6IER1cmNoZ2VmdWVocnRlIEFlbmRlcnVuZyBhbiBQX0RBTUFHRQorICAgICAgICByZXR1cm4gbmV3X2RhbTsKKyAgICB9CisKKyAgICAvLyBCZWkgcmVpbmVuIFBhcmllcndhZmZlbiBnZWh0IGRpZSBCZXNjaGFlZGlndW5nIGF1ZiBkaWUKKyAgICAvLyBTY2h1dHp3aXJrdW5nLCBzcHJpY2g6IFBfQUMKKworICAgIGlmICgod2M9UXVlcnlQcm9wKFBfQUMpKTw9MCAmJiBuZXdfZGFtPjApCisgICAgeworICAgICAgICAvLyBTb25zdCB3dWVyZGUgQmVzY2hhZWRpZ3VuZyB6dXIgUmVwYXJhdHVyIGZ1ZWhyZW4KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIAorICAgIC8vIE1pbi1BQz0wIHVuZCBNYXgtQUMgYmVhY2h0ZW4KKyAgICBpZiAoKHdjLW5ld19kYW0pIDwgTUlOX1BBUlJZX0NMQVNTKQorICAgIHsKKyAgICAgICAgbmV3X2RhbSA9IHdjLU1JTl9QQVJSWV9DTEFTUzsKKyAgICB9CisgICAgZWxzZSBpZiAoKHdjLW5ld19kYW0pID4gTUFYX1BBUlJZX0NMQVNTKQorICAgIHsKKyAgICAgICAgbmV3X2RhbSA9IHdjLU1BWF9QQVJSWV9DTEFTUzsKKyAgICB9CisgCisgICAgLy8gTmllIG1laHIgYWxzIDEwMCUgcmVwYXJpZXJlbgorICAgIGlmICgoKG9sZF9kYW09UXVlcnlQcm9wKFBfREFNQUdFRCkpPC1uZXdfZGFtKSAmJiBuZXdfZGFtPDApCisgICAgeworICAgICAgICBuZXdfZGFtPS1vbGRfZGFtOworICAgIH0KKworICAgIC8vIEFlbmRlcnVuZ2VuIGFuIGRlciBSdWVzdHVuZ3NrbGFzc2UgdW5kIGRlbSBCZXNjaGFlZGlndW5nc3dlcnQKKyAgICAvLyBkdXJjaGZ1ZWhyZW4KKyAgICBTZXRQcm9wKFBfQUMsd2MtbmV3X2RhbSk7CisgICAgLy8gQXVzbmFobWV3ZWlzZSBTZXQsIHVtIGRpZSBsb2dnZW5kZSBTZXRtZXRob2RlIHp1IHVtZ2VoZW4uCisgICAgLy8gVE9ETzogU2V0UHJvcCwgc29iYWxkIGRpcmVrdGVzIEJlc2NoYWVkaWdlbiByYXVzIGlzdC4KKyAgICBTZXQoUF9EQU1BR0VELG9sZF9kYW0rbmV3X2RhbSwgRl9WQUxVRSk7CisKKyAgICAvLyBQX1RPVEFMX0FDIGltIFRyYWVnZXIgdXBkYXRlbiwgc28gdm9yaGFuZGVuCisgICAgaWYgKG9iamVjdHAodz1RdWVyeVByb3AoUF9XSUVMREVEKSkpCisgICAgICAgIHctPlF1ZXJ5UHJvcChQX1RPVEFMX0FDKTsKKyAgICAKKyAgICAvLyBSdWVja2dhYmV3ZXJ0OiBEdXJjaGdlZnVlaHJ0ZSBBZW5kZXJ1bmcgYW4gUF9EQU1BR0UKKyAgICByZXR1cm4gbmV3X2RhbTsKK30KKworLy8gV2lyZCBkaWUgV2FmZmUgZWluZXIgQmVsYXN0dW5nIGF1c2dlc2V0enQgKHouQi4gd2VubiBtYW4gZGFtaXQKKy8vIHp1c2NobGFlZ3QpLCBkYW5uIHdpcmQgVGFrZUZsYXcoKSBhdWZnZXJ1ZmVuLgordmFyYXJncyB2b2lkIFRha2VGbGF3KG9iamVjdCBlbmVteSkKK3sgICBpbnQgYzsKKworICAgIC8vIEZsYXctV2VydCBlcmhvZWhlbgorICAgIGZsYXcrKzsKKworICAgIC8vIElzdCBkZXIgV2FmZmUgZWluZSBRdWFsaXRhZXQgZ2VzZXR6dCB3b3JkZW4sIHNvIGthbm4gZXMgenUgZWluZXIKKyAgICAvLyBhbGxtYWVobGljaGVuIEJlc2NoYWVkaWd1bmcgZGVyIFdhZmZlIGtvbW1lbgorICAgIGlmICgoYz1RdWVyeVByb3AoUF9RVUFMSVRZKSkgJiYgIShmbGF3JWMpKQorICAgICAgICBEYW1hZ2UoMSk7CisKKyAgICAvLyBaZWl0cHVua3QgZGVzIGVyc3RlbiBBdWZydWZlcyBmZXN0aGFsdGVuCisgICAgaWYgKCFmdGltZSkKKyAgICAgICAgZnRpbWU9dGltZSgpOworfQorCisvLyBEaWUgRmxhdy1EYXRlbiBrb2VubmVuIG5hdHVlcmxpY2ggYXVjaCBhYmdlcnVmZW4gd2VyZGVuCittaXhlZCAqUXVlcnlGbGF3KCkKK3sKKyAgICByZXR1cm4oe2ZsYXcsZnRpbWUsZHRpbWUoZnRpbWUpfSk7Cit9CisKZGlmZiAtLWdpdCBhL3N0ZC93ZWFwb24vZGVzY3JpcHRpb24uYyBiL3N0ZC93ZWFwb24vZGVzY3JpcHRpb24uYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hYWQyOTM4Ci0tLSAvZGV2L251bGwKKysrIGIvc3RkL3dlYXBvbi9kZXNjcmlwdGlvbi5jCkBAIC0wLDAgKzEsMTA4IEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gd2VhcG9uL2Rlc2NyaXB0aW9uLmMgLS0gd2VhcG9uIGRlc2NyaXB0aW9uIGhhbmRsaW5nCisvLworLy8gJElkOiBkZXNjcmlwdGlvbi5jIDY0NzUgMjAwNy0wOS0xOSAyMDo1Njo0MFogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworLy8jZGVmaW5lIE5FRURfUFJPVE9UWVBFUworCisjaW5jbHVkZSA8dGhpbmcvcHJvcGVydGllcy5oPgorI2luY2x1ZGUgPHRoaW5nL2Rlc2NyaXB0aW9uLmg+CisjaW5jbHVkZSA8cHJvcGVydGllcy5oPgorI2luY2x1ZGUgPGNvbWJhdC5oPgorI2luY2x1ZGUgPHRoaW5nL21hdGVyaWFsLmg+CisKK2luaGVyaXQgIi9zdGQvdGhpbmcvZGVzY3JpcHRpb24iOworCit2b2lkIGNyZWF0ZSgpCit7CisgIDo6Y3JlYXRlKCk7CisgIFNldFByb3AoUF9EQU1fREVTQyxERkxUX0RBTV9ERVNDKTsKK30KKworc3RyaW5nIGRhbV9kZXNjcigpCit7ICAgc3RyaW5nIHJlOworICAgIG1peGVkIGRlc2M7CisgICAgaW50IG1heCxkYW0scG9zOworCisgICAgaWYgKCFRdWVyeVByb3AoUF9OQU1FKSB8fCAhUXVlcnlQcm9wKFBfREFNQUdFRCkgfHwgIVF1ZXJ5UHJvcChQX1NIT1JUKSB8fAorICAgICAgICAhKGRlc2M9UXVlcnlQcm9wKFBfREFNX0RFU0MpKSB8fCAoIXN0cmluZ3AoZGVzYykgJiYgIXBvaW50ZXJwKGRlc2MpKSkKKyAgICAgICAgcmV0dXJuICIiOworICAgIHJlID0gY2FwaXRhbGl6ZShuYW1lKFdFUiwyKSkrIiAiOworICAgIG1heCA9IFF1ZXJ5UHJvcChQX1dDKSsoZGFtPVF1ZXJ5UHJvcChQX0RBTUFHRUQpKTsKKyAgICAvLyBCZWkgcmVpbmVuIFBhcmllcndhZmZlbiBkZW4gQUMgYWxzIG1heCBuZWhtZW4hCisgICAgaWYgKFF1ZXJ5UHJvcChQX1BBUlJZKT09UEFSUllfT05MWSkKKyAgICB7CisJICAgIG1heD1RdWVyeVByb3AoUF9BQykrZGFtOworICAgIH0KKyAgICBpZiAoc3RyaW5ncChkZXNjKSkKKyAgICAgICAgcmV0dXJuIChkYW0+KG1heC8yKSk/KHJlK2Rlc2MrIi5cbiIpOiIiOworICAgIHBvcyA9IChzaXplb2YoZGVzYykqZGFtL21heCk7CisgICAgLy8gU29uc3Qga29lbm5lbiBQYXJpZXJ3YWZmZW4sIGRpZSBTY2hyb3R0IHNpbmQsIGJ1Z2dlbgorICAgIGlmIChwb3M9PXNpemVvZihkZXNjKSkgcG9zLS07CisgICAgaWYgKHN0cmluZ3AoZGVzY1twb3NdKSkKKyAgICAgICAgcmV0dXJuIChyZStkZXNjW3Bvc10rIi5cbiIpOworICAgIHJldHVybiAiIjsKK30KKworc3RyaW5nIHNob3J0KCkKK3sgICBzdHJpbmcgczsKKworICAgIGlmICghKHM9UXVlcnlQcm9wKFBfU0hPUlQpKSkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgcmV0dXJuIHMgKyAoUXVlcnlQcm9wKFBfV0lFTERFRCk/IiAoZ2V6dWVja3QpLlxuIjoiLlxuIik7Cit9CisKK3ZhcmFyZ3Mgc3RyaW5nIGxvbmcoKQoreyAgIAorICAgIHJldHVybiAocHJvY2Vzc19zdHJpbmcoUXVlcnlQcm9wKFBfTE9ORyl8fCIiKSArIChkYW1fZGVzY3IoKXx8IiIpKTsKK30KKworbWl4ZWQgX3F1ZXJ5X3NpemUoKSB7CisgIG1peGVkIHJlcywgd3Q7CisgIGlmIChpbnRwKHJlcz1RdWVyeShQX1NJWkUpKSAmJiAocmVzPjApKQorICAgIHJldHVybiByZXM7CisgIHd0PVF1ZXJ5UHJvcChQX1dFQVBPTl9UWVBFKTsKKyAgc3dpdGNoICh3dCkgeworICAgIGNhc2UgV1RfU1dPUkQgIDogcmV0dXJuIDEwMDsgIC8vIGRlZmF1bHQ6IExhbmdzY2h3ZXJ0CisgICAgY2FzZSBXVF9BWEUgICAgOiByZXR1cm4gIDgwOworICAgIGNhc2UgV1RfQ0xVQiAgIDogcmV0dXJuICA4MDsKKyAgICBjYXNlIFdUX1NQRUFSICA6IHJldHVybiAxODA7CisgICAgY2FzZSBXVF9LTklGRSAgOiByZXR1cm4gIDIwOworICAgIGNhc2UgV1RfV0hJUCAgIDogcmV0dXJuIDIwMDsKKyAgICBjYXNlIFdUX1NUQUZGICA6IHJldHVybiAxNTA7CisgIH0KKyAgcmV0dXJuIDEwOyAgLy8gYWxsZXMgYW5kZXJlCit9CisKK21hcHBpbmcgX3F1ZXJ5X21hdGVyaWFsKCkgeworICBtaXhlZCByZXMsd3Q7CisKKyAgaWYgKG1hcHBpbmdwKHJlcz1RdWVyeShQX01BVEVSSUFMKSkpCisgICAgcmV0dXJuIHJlczsKKyAgd3Q9UXVlcnlQcm9wKFBfV0VBUE9OX1RZUEUpOworICBzd2l0Y2god3QpIHsKKyAgICBjYXNlIFdUX1NXT1JEOgorICAgIHJldHVybiAoW01BVF9NSVNDX01FVEFMOjEwMF0pOworICAgIGNhc2UgV1RfS05JRkU6CisgICAgcmV0dXJuIChbTUFUX01JU0NfTUVUQUw6ODAsTUFUX01JU0NfV09PRDoyMF0pOworICAgIGNhc2UgV1RfQVhFOgorICAgIHJldHVybiAoW01BVF9NSVNDX01FVEFMOjUwLE1BVF9NSVNDX1dPT0Q6NTBdKTsKKyAgICBjYXNlIFdUX1NQRUFSOgorICAgIHJldHVybiAoW01BVF9NSVNDX01FVEFMOjIwLE1BVF9NSVNDX1dPT0Q6ODBdKTsKKyAgICBjYXNlIFdUX1NUQUZGOgorICAgIGNhc2UgV1RfQ0xVQjoKKyAgICByZXR1cm4gKFtNQVRfTUlTQ19XT09EOjEwMF0pOworICB9CisgIHJldHVybiAoW01BVF9NSVNDX01FVEFMOjEwMF0pOworfQorCisvLyBQX0JBTEFOQ0VEX1dFQVBPTiB1bmQgUF9URUNITklRVUUgc2luZCBtYW5nZWxzIHVtZ2VzZXR6dGVtIEtvbnplcHQgZHVyY2gKKy8vIEVNLUJlc2NobHVzcyBmdWVyIG9ic29sZXQgZXJrbGFlcnQgd29yZGVuLiBaZXNzdHJhLiAyNi4wNi4yMDA3CisKZGlmZiAtLWdpdCBhL3N0ZC93ZWFwb24vbW92aW5nLmMgYi9zdGQvd2VhcG9uL21vdmluZy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNlODE3NzAKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvd2VhcG9uL21vdmluZy5jCkBAIC0wLDAgKzEsMzYgQEAKKy8vIE1vcmdlbkdyYXVlbiBNVURsaWIKKy8vCisvLyB3ZWFwb24vbW92aW5nLmMgLS0gQmV3ZWdlbi9aZXJzdG9lcmVuIHZvbiBXYWZmZW4KKy8vCisvLyAkSWQ6IG1vdmluZy5jIDYzMTIgMjAwNy0wNS0yMCAyMjo0MDo1MVogWmVzc3RyYSAkCisKKyNwcmFnbWEgc3RyaWN0X3R5cGVzCisjcHJhZ21hIHNhdmVfdHlwZXMKKyNwcmFnbWEgbm9fY2xvbmUKKyNwcmFnbWEgcGVkYW50aWMKKyNwcmFnbWEgcmFuZ2VfY2hlY2sKKworaW5oZXJpdCAiL3N0ZC90aGluZy9tb3ZpbmciOworCisvLyNkZWZpbmUgTkVFRF9QUk9UT1RZUEVTIDEKKworI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxwcm9wZXJ0aWVzLmg+CisjaW5jbHVkZSA8bW92aW5nLmg+CisjaW5jbHVkZSA8ZGVmaW5lcy5oPgorCit2YXJhcmdzIGludCBEb1Vud2llbGQoaW50IHNpbGVudCk7CisKK3ZhcmFyZ3MgaW50IG1vdmUobWl4ZWQgZGVzdCwgaW50IG1ldGhvZCkKK3sKKyAgRG9VbndpZWxkKCBtZXRob2QgJiAoTV9TSUxFTlR8TV9OT0NIRUNLKSk7CisgIGlmICgobWV0aG9kICYgTV9OT0NIRUNLKSB8fCAoIVF1ZXJ5UHJvcChQX1dJRUxERUQpKSkKKyAgICByZXR1cm4gOjptb3ZlKGRlc3QsIG1ldGhvZCApOworfQorCit2YXJhcmdzIGludCByZW1vdmUoaW50IHNpbGVudCApCit7CisgIERvVW53aWVsZCggc2lsZW50ICk7CisgIGlmICghUXVlcnlQcm9wKFBfV0lFTERFRCkpCisgICAgcmV0dXJuIDo6cmVtb3ZlKCBzaWxlbnQgKTsKK30K