ZGlmZiAtLWdpdCBhL3N0ZC9wbGF5ZXIvc2tpbGxzLmMgYi9zdGQvcGxheWVyL3NraWxscy5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUwM2RhOTcKLS0tIC9kZXYvbnVsbAorKysgYi9zdGQvcGxheWVyL3NraWxscy5jCkBAIC0wLDAgKzEsNjIxIEBACisvLyBNb3JnZW5HcmF1ZW4gTVVEbGliCisvLworLy8gcGxheWVyL3NraWxscy5jIC0tIFNwaWVsZXJza2lsbHMKKy8vCisvLyAkSWQ6IHNraWxscy5jIDg4MDkgMjAxNC0wNS0wOCAxOTo1Mjo0OFogWmVzc3RyYSAkCisKKy8vCisvLyAyMDAzLTAxLTIwOiBOdW4gWm9va3MgQmF1c3RlbGxlCisvLworI3ByYWdtYSBzdHJvbmdfdHlwZXMKKyNwcmFnbWEgc2F2ZV90eXBlcworI3ByYWdtYSByYW5nZV9jaGVjaworI3ByYWdtYSBub19jbG9uZQorI3ByYWdtYSBwZWRhbnRpYworCitpbmhlcml0ICIvc3RkL2xpdmluZy9za2lsbHMiOworCisjaW5jbHVkZSA8Y29tYmF0Lmg+CisjaW5jbHVkZSA8bmV3X3NraWxscy5oPgorI2luY2x1ZGUgPHByb3BlcnRpZXMuaD4KKyNpbmNsdWRlIDxicmVha19zdHJpbmcuaD4KKyNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KKworI2RlZmluZSBORUVEX1BST1RPVFlQRVMKKyNpbmNsdWRlIDxwbGF5ZXIvYmFzZS5oPgorI2luY2x1ZGUgPHBsYXllci9nbWNwLmg+CisjdW5kZWYgTkVFRF9QUk9UT1RZUEVTCisKKy8vIERpZXNlcyBNYXBwaW5nIHNwZWljaGVydCBkaWUgZGVha3RpdmllcnRlbiBTa2lsbHMgZGVyIGVpbnplbG5lbiBHaWxkZW4KKy8vIERpZXNlIHdlcmRlbiBpbiBkZW4gR2lsZGVuIHVlYmVyIFBfR1VJTERfREVBQ1RJVkFURURfU0tJTEwgZ2VzZXR6dC4KK25vc2F2ZSBtYXBwaW5nIGRlYWN0aXZhdGVkX3NraWxscyA9IChbXSk7CisKKy8vIEZsYWcgZnVlciBkZW4gS29tcGF0aWJpbGl0YWV0c21vZHVzIGRlcyBLYW1wZnMgKEVtdWxhdGlvbiB2b24KKy8vIDJzLUFsYXJtemVpdCkuIFdlbm4gIT0gMCBzcGVpY2hlcnQgZGFzIEZsYWcgZ2xlaWNoemVpdGlnIGRpZSBaZWl0IGRlcworLy8gbGV0enRlbiBIZWFydGJlYXRzLiBBdWYgZGllc2UgWmVpdCB3aXJkIGRlciBTdGFydHB1bmt0IGVpbmVzIFNwZWxsZmF0aWd1ZXMKKy8vIGdnZi4genVydWVja2RhdGllcnQuIChtYXguIGVpbmUgU2VrdW5kZSkKK2ludCBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlOworCisvLyBFaW4gY3JlYXRlKCkgZnVlciBkYXMgTWFwcGluZworCitwcm90ZWN0ZWQgdm9pZCBjcmVhdGUoKQoreworICBtYXBwaW5nIGFjdDsKKworICA6OmNyZWF0ZSgpOworCisgIC8vIFdpciBob2xlbiBkaWUgR2lsZGVuIGF1cyBkZW0gR2lsZGVubWFzdGVyIAorICBmb3JlYWNoKHN0cmluZyBndWlsZDoKKyAgICAgIChzdHJpbmcgKiljYWxsX290aGVyKEdVSUxETUFTVEVSLCJRdWVyeVByb3AiLFBfVkFMSURfR1VJTERTKSkKKyAgeworICAgIGlmKGNhdGNoKGFjdD1jYWxsX290aGVyKCIvZ2lsZGVuLyIrZ3VpbGQsIlF1ZXJ5UHJvcCIsCisgICAgICAgIFBfR1VJTERfREVBQ1RJVkFURV9TS0lMTFMpOyBwdWJsaXNoICkpCisgICAgICAgIGxvZ19maWxlKCJXRUFQT05fU0tJTExTIiwgc3ByaW50ZiAoIiVzOiBHaWxkZSBuaWNodCBsYWRiYXI6ICIKKyAgICAgICAgICAgICAgKyJUUDogJU8sIFRJOiAlTywgUE86ICVPLCBHaWxkZTogJXNcbiIsIGR0aW1lKHRpbWUoKSksCisgICAgICAgICAgICAgIHRoaXNfcGxheWVyKCksIHRoaXNfaW50ZXJhY3RpdmUoKSwgcHJldmlvdXNfb2JqZWN0KCksIGd1aWxkKSk7CisgICAgZWxzZSBpZiAoYWN0KSAvLyB3ZW5uIGFjdCwgaW5zIE1hcHBpbmcgYXVmbmVobWVuLgorICAgICAgICBkZWFjdGl2YXRlZF9za2lsbHMrPShbZ3VpbGQ6YWN0XSk7CisgIH0KKyAgLy8ga2VpbmUgZWNodGUgUHJvcCBtZWhyLCBTYXZlLU1vZHVzIHVubm9ldGlnLgorICBTZXQoUF9ORVhUX1NQRUxMX1RJTUUsU0FWRSxGX01PREVfQUQpOworCisgIFNldChQX1NLSUxMU1ZFUlNJT04sIFNBVkV8U0VDVVJFRCwgRl9NT0RFX0FTKTsKK30KKworLy8gRGFzIE1hcHBpbmcga2FubiBtYW4gYXVjaCBhYmZyYWdlbgorCitwdWJsaWMgbWFwcGluZyBHZXREZWFjdGl2YXRlZFNraWxscygpCit7CisgICAgcmV0dXJuIGNvcHkoZGVhY3RpdmF0ZWRfc2tpbGxzKTsKK30KKworLy8gRnVua3Rpb24sIGRpZSBzYWd0IG9iIGVpbiBBTlktU2tpbGwgZGVha3RpdmllcnQgaXN0LgorcHVibGljIGludCBpc19kZWFjdGl2YXRlZF9za2lsbChzdHJpbmcgc25hbWUsc3RyaW5nIGd1aWxkKQoreworICAgICAgICBpZiAoZGVhY3RpdmF0ZWRfc2tpbGxzW2d1aWxkXSkgICAgICAgIAorICAgICAgICAgICAgICAgIHJldHVybiBkZWFjdGl2YXRlZF9za2lsbHNbZ3VpbGRdW3NuYW1lXTsKKyAgICAgICAgcmV0dXJuIDA7Cit9CisKKworLy8gRnVua3Rpb24gZnVlciBkaWUgV2FmZmVuc2tpbGxzCisvLyB0cmFlZ3QgZGllIGFsbGcuIFdhZmZlbnNraWxscyBlaW4uIFdpcmQgZ2dmLiB2b24gRml4U2tpbGxzKCkgZ2VydWZlbi4KKy8vIChEYXMgRWludHJhZ2VuIGJlZGV1dGV0IG5pY2h0LCBkYXNzIGRpZSBha3RpdiBzaW5kISBBYmVyIGJlaSBHaWxkZW53ZWNoc2VsCisvLyB3ZXJkZW4gc2llIG5pY2h0IGVpbmdldHJhZ2VuKS4KK3ByaXZhdGUgdm9pZCBzZXRfd2VhcG9uX3NraWxscygpIHsKKworICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfU1dPUkQpKTw9MCkgICAgICAgICAgICAgICAgCisgICAgICBNb2RpZnlTa2lsbChGSUdIVChXVF9TV09SRCksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7ICAgIAorICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfQVhFKSk8PTApICAgICAgICAgICAgICAgIAorICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfQVhFKSwoW1NJX1NLSUxMQUJJTElUWTowXSksMTUwLCJBTlkiKTsgICAgICAgICAgCisgIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9TUEVBUikpPD0wKSAgICAgICAgCisgICAgICBNb2RpZnlTa2lsbChGSUdIVChXVF9TUEVBUiksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7ICAgICAgICAgIAorICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfV0hJUCkpPD0wKQorICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfV0hJUCksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7CisgIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9LTklGRSkpPD0wKSAgICAgICAgICAgICAgICAKKyAgICAgIE1vZGlmeVNraWxsKEZJR0hUKFdUX0tOSUZFKSwoW1NJX1NLSUxMQUJJTElUWTowXSksMTUwLCJBTlkiKTsgICAgICAgICAgCisgIGlmIChRdWVyeVNraWxsQWJpbGl0eShGSUdIVChXVF9DTFVCKSk8PTApICAgICAgICAgICAgICAgIAorICAgICAgTW9kaWZ5U2tpbGwoRklHSFQoV1RfQ0xVQiksKFtTSV9TS0lMTEFCSUxJVFk6MF0pLDE1MCwiQU5ZIik7ICAgICAgICAgIAorICBpZiAoUXVlcnlTa2lsbEFiaWxpdHkoRklHSFQoV1RfU1RBRkYpKTw9MCkKKyAgICAgIE1vZGlmeVNraWxsKEZJR0hUKFdUX1NUQUZGKSwoW1NJX1NLSUxMQUJJTElUWTowXSksMTUwLCJBTlkiKTsKK30gCisKKy8vIGluaXRpYWxpc2llcnQgZGllIFNraWxscyBmdWVyIFNwaWVsZXIgKG1vbWVudGFuOiBhbGxnLiBXYWZmZW5za2lsbHMgc2V0emVuCisvLyB1bmQgUF9TS0lMTFNfVkVSU0lPTikKK3Byb3RlY3RlZCB2b2lkIEluaXRTa2lsbHMoKSB7CisgIG1hcHBpbmcgc2tpOworICAvLyBzY2hvbm1hbCBpbml0aWFsaXNpZXJ0PworICBpZiAobWFwcGluZ3Aoc2tpPVF1ZXJ5KFBfTkVXU0tJTExTLCBGX1ZBTFVFKSkgJiYgc2l6ZW9mKHNraSkpCisgICAgcmV0dXJuOworCisgIC8vIGFsbGcuIFdhZmZlbnNraWxscyBha3RpdmllcmVuCisgIHNldF93ZWFwb25fc2tpbGxzKCk7CisKKyAgLy8gVmVyc2lvbiBzZXR6ZW4KKyAgU2V0UHJvcChQX1NLSUxMU1ZFUlNJT04sIENVUlJFTlRfU0tJTExfVkVSU0lPTik7CisgIFNldChQX1NLSUxMU1ZFUlNJT04sIFNBVkV8U0VDVVJFRCwgRl9NT0RFX0FTKTsKK30KKworLy8gVXBkYXRlZCBTa2lsbHMgYXVzIFZlcnNpb24gMCB1bmQgMSBoZXJhdXMuCitwcml2YXRlIHZvaWQgRml4U2tpbGxWMShzdHJpbmcgc2tpbGxuYW1lLCBtaXhlZCBzaW5mbykgeworICAvLyBhbHRlIFNraWxscyBhdWYgbWFwcGluZ3Mgbm9ybWllcmVuCisgIGlmIChpbnRwKHNpbmZvKSkgeworICAgIHNpbmZvID0gKFtTSV9TS0lMTEFCSUxJVFk6IHNpbmZvIF0pOworICB9CisgIC8vIEVpbmUgUmVpaGUgdm9uIERhdGVuIHdlcmRlbiBnZWxvZXNjaHQsIGRhIGRpZSBEYXRlbiBhdXMgZGVyCisgIC8vIEdpbGRlL1NwZWxsYm9vayBmcmlzY2gga29tbWVuIHNvbGx0ZW4gdW5kIHNpZSBuaWNodCBzcGllbGVyLWluZGl2aWR1ZWxsCisgIC8vIHNpbmQ6IFNJX0NMT1NVUkUgKHdpcmQgb250aGVmbHkga29ycmVrdCBuZXUgZXJ6ZXVndCksIFNJX1NLSUxMQVJHLAorICAvLyBTSV9OVU1CRVJfRU5FTUlFUywgU0lfTlVNQkVSX0ZSSUVORFMsIFNJX0RJU1RBTkNFLCBTSV9XSURUSCwgU0lfREVQVEgsCisgIC8vIFNJX1RFU1RGTEFHLCBTSV9FTkVNWSwgU0lfRlJJRU5ELgorICAvLyBBdXNzZXJkZW0gc2luZCBhbGxlIFNQXyogaW0gdG9wbGV2ZWwgZmFsc2NoLCBkaWUgbXVlc3NlbiBhKSBpbiBTSV9TUEVMTAorICAvLyB1bmQgc29sbHRlbiBiKSBuaWNodCBpbSBTcGllbGVyIGdlc3BlaWNoZXJ0IHdlcmRlbiwgc29uZGVybiB2b24KKyAgLy8gR2lsZGVuL1NwZWxsYm9vayBqZXdlaWxzIGZyaXNjaCBrb21tZW4uCisgIC8vIGFsbCBkaWVzZXMgWmV1ZyBsYW5kZXRlIGluIGFsdGVuIFNwaWVsZXJuIGltIFNhdmVmaWxlLgorICBpZiAobWFwcGluZ3Aoc2luZm8pKQorICAgIHNpbmZvIC09IChbU0lfQ0xPU1VSRSwgU0lfU0tJTExBUkcsIFNJX05VTUJFUl9FTkVNSUVTLCBTSV9OVU1CRVJfRlJJRU5EUywKKyAgICAgICAgICAgICBTSV9ESVNUQU5DRSwgU0lfV0lEVEgsIFNJX0RFUFRILCBTSV9URVNURkxBRywgU0lfRU5FTVksCisgICAgICAgICAgICAgU0lfRlJJRU5ELCBTUF9OQU1FLCBTUF9TSE9XX0RBTUFHRSwgU1BfUkVEVUNFX0FSTU9VUiwKKyAgICAgICAgICAgICBTUF9QSFlTSUNBTF9BVFRBQ0ssIFNQX1JFQ1VSU0lWRSwgU1BfTk9fRU5FTVksCisgICAgICAgICAgICAgU1BfTk9fQUNUSVZFX0RFRkVOU0UsIFNQX0dMT0JBTF9BVFRBQ0sgXSk7CisgIGVsc2UKKyAgeworICAgIHRlbGxfb2JqZWN0KHRoaXNfb2JqZWN0KCksc3ByaW50ZigKKyAgICAgICJcbioqKiogQUNIVFVORyAtIEZFSExFUiAqKipcbiIgCisgICAgICAiRGVpbmUgU2tpbGxzIGVudGhhbHRlbiBlaW5lbiBkZWZla3RlbiBTa2lsbCAlTzpcbiIKKyAgICAgICJCaXR0ZSBsYXNzIGRpZXMgdm9uIGVpbmVtIEVyem1hZ2llciB1ZWJlcnBydWVmZW4uXG4iLAorICAgICAgc2tpbGxuYW1lKSk7CisgIH0KK30KKworLy8gVXBkYXRldCB1bmQgcmVwYXJpZXJ0IGdnZi4gU2tpbGxtYXBwaW5ncyBpbiBTcGllbGVybgorcHJvdGVjdGVkIHZvaWQgRml4U2tpbGxzKCkgeworCisgIC8vIG51ciBiZWkgZ2VudWcgcmVjaGVuemVpdCBsb3NsZWdlbgorICBpZiAoZ2V0X2V2YWxfY29zdCgpIDwgNzUwMDAwKSB7CisgICAgY2FsbF9vdXQoIydGaXhTa2lsbHMsIDEpOworICAgIHJldHVybjsKKyAgfQorICAvLyB3ZW5uIGdhciBrZWluZSBTa2lsbHMgZGEgKD8pOiBJbml0U2tpbGxzKCkgcnVmZW4uCisgIG1hcHBpbmcgYWxsc2tpbGxzID0gUXVlcnkoUF9ORVdTS0lMTFMsIEZfVkFMVUUpOworICBpZiAoIW1hcHBpbmdwKGFsbHNraWxscykgfHwgIXNpemVvZihhbGxza2lsbHMpKSB7CisgICAgICBJbml0U2tpbGxzKCk7CisgICAgICByZXR1cm47CisgIH0KKworICAvLyBEaWUgRmFsbHRocm91Z2hzIGluIGRpZXNlbSBzd2l0Y2ggc2luZCB2b2xsIEFic2ljaHQhCisgIHN3aXRjaChRdWVyeVByb3AoUF9TS0lMTFNWRVJTSU9OKSkgeworICAgIC8vIGJlaSBWZXJzaW9uIDAgdW5kIDEgZGFzIGdsZWljaGUgdHVuCisgICAgY2FzZSAwOiAvLyB2b24gMCBhdWYgMQorICAgIGNhc2UgMTogLy8gdm9uIDEgYXVmIDIKKyAgICAgIGZvcmVhY2goc3RyaW5nIGdpbGRlLCBtYXBwaW5nIHNraWxsczogYWxsc2tpbGxzKSB7CisgICAgICAgIGlmICghc3RyaW5ncChnaWxkZSkpIHsKKyAgICAgICAgICAvLyBzb2xsdGUgbmljaHQgdm9ya29tbWVuIC0gdGF0IGFiZXIuLi4gKnNldWZ6KgorICAgICAgICAgIG1fZGVsZXRlKHNraWxscywgZ2lsZGUpOworICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIHdhbGtfbWFwcGluZyhza2lsbHMsICMnRml4U2tpbGxWMSk7CisgICAgICB9CisgICAgICAvLyBhbGxnLiBXYWZmZW5za2lsbHMgYWt0aXZpZXJlbiwgZWluaWdlIGFsdGUgU3BpZWxlciBoYWJlbiBkaWUgbm9jaAorICAgICAgLy8gbmljaHQuCisgICAgICBzZXRfd2VhcG9uX3NraWxscygpOworICAgICAgLy8gU3BlaWNoZXJmbGFnIGZ1ZXIgZGllIFZlcnNpb25zcHJvcCBtdXNzIG5vY2ggZ2VzZXR6dCB3ZXJkZW4uCisgICAgICBTZXQoUF9TS0lMTFNWRVJTSU9OLCBTQVZFfFNFQ1VSRUQsIEZfTU9ERV9BUyk7CisgICAgICAvLyBWZXJzaW9uIGlzdCBqZXR6dCAyLgorICAgICAgU2V0UHJvcChQX1NLSUxMU1ZFUlNJT04sIDIpOworICAgICAgLy8gRmFsbC10aHJvdWdoCisgICBjYXNlIDI6CisgICAgICAvLyBnaWJ0IGVzIG5vY2ggbmljaHQsIG5pY2h0cyBtYWNoZW4uCisgICAgICAvL1NldFByb3AoUF9TS0lMTFNWRVJTSU9OLCAzKTsKKyAgICAgIC8vIEZhbGwtdGhyb3VnaCwgYXVzc2VyIGVzIHNpbmQgenV3ZW5pZyBUaWNrcyBkYSEKKyAgICAgIGlmIChnZXRfZXZhbF9jb3N0KCkgPCA3NTAwMDApCisgICAgICAgIGJyZWFrOyAKKyAgfQorICAvLyBGYWxscyBub2NoIG5pY2h0IGF1ZiBkZXIgYWt0dWVsbGVuIFZlcnNpb24gYW5nZWtvbW1lbiwgbmV1ZXIgY2FsbG91dAorICBpZiAoUXVlcnlQcm9wKFBfU0tJTExTVkVSU0lPTikgPCBDVVJSRU5UX1NLSUxMX1ZFUlNJT04pCisgICAgICBjYWxsX291dCgjJ0ZpeFNraWxscywgMik7Cit9CisKK3Byb3RlY3RlZCB2b2lkIHVwZGF0ZXNfYWZ0ZXJfcmVzdG9yZShpbnQgbmV3ZmxhZykgeworICAvL0FsbGdlbWVpbmUgV2FmZmVuc2tpbGxzIGFrdGl2aWVyZW4sIHdlbm4gbm9ldGlnCisgIC8vIFdpcmQgbnVuIHZvbiBJbml0U2tpbGxzIGJ6dy4gRml4U2tpbGxzIHVlYmVybm9tbWVuLCBmYWxscyBub2V0aWcuCisgIGlmIChuZXdmbGFnKSB7CisgICAgSW5pdFNraWxscygpOworICB9CisgIGVsc2UgaWYgKFF1ZXJ5UHJvcChQX1NLSUxMU1ZFUlNJT04pIDwgQ1VSUkVOVF9TS0lMTF9WRVJTSU9OKSB7CisgICAgLy8gRmFsbHMgbm9ldGlnLCBTa2lsbHMgZml4ZW4vdXBkYXRlbi4gKmdydW1tZWwqCisgICAgRml4U2tpbGxzKCk7CisgIH0KKyAgLy8gUHJvcCBnaWJ0IGVzIG5pY2h0IG1laHIuIFNBVkUtU3RhdHVzIGxvZXNjaGVuLiAKKyAgU2V0KFBfR1VJTERfUFJFVkVOVFNfUkFDRVNLSUxMLFNBVkUsRl9NT0RFX0FEKTsKK30KKworLy8gU3RhbmRhcmRpc2llcnRlIE5haGthbXBmLUZ1bmt0aW9uIGZ1ZXIgYWxsZSBOYWhrYW1wZi1XYWZmZW5hcnRlbgorcHJvdGVjdGVkIG1hcHBpbmcgU2hvcnRSYW5nZVNraWxsKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKSAKK3sgCisgIGludCB2YWwsIHc7CisgIG9iamVjdCBlbmVteTsKKyAgCisgIGlmICghbWFwcGluZ3Aoc2luZm8pIHx8ICFvYmplY3RwKHNpbmZvW1BfV0VBUE9OXSkpCisgICAgcmV0dXJuIDA7CisKKyAgdyA9IChbV1RfS05JRkUgOiA4LAorICAgICAgICBXVF9TV09SRCA6IDUsCisgICAgICAgIFdUX0FYRSAgIDogNCwKKyAgICAgICAgV1RfU1BFQVIgOiA2LAorICAgICAgICBXVF9DTFVCICA6IDEsCisgICAgICAgIFdUX1dISVAgIDogOSwKKyAgICAgICAgV1RfU1RBRkYgOiA3XSlbc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9XRUFQT05fVFlQRSldOworICAgICAgCisKKyAgdmFsID0gc2luZm9bU0lfU0tJTExBQklMSVRZXSooc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9XQykqCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh3KlF1ZXJ5QXR0cmlidXRlKEFfREVYKSsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxMC13KSpRdWVyeUF0dHJpYnV0ZShBX1NUUikpLzcwMCkKKyAgICAgICAgL01BWF9BQklMSVRZOworCisgIGlmICh2YWwgPiA4NSkgeworICAgIGxvZ19maWxlKCJXRUFQT05fU0tJTExTIiwgc3ByaW50ZigiJXM6IFp1IGhvaGVyIFNjaGFkZW4gdm9uOiAiCisgICAgKyJUTzogJU8sIFRJOiAlTywgUE86ICVPLCB2YWw6ICVkLCBBX0RFWDogJWQsIEFfU1RSOiAlZCwgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIlBfV0VBUE9OOiAlTywgUF9XQzogJWRcbiIsIGR0aW1lKHRpbWUoKSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXNfb2JqZWN0KCksIHRoaXNfaW50ZXJhY3RpdmUoKSwgCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzX29iamVjdCgpLCB2YWwsIAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBRdWVyeUF0dHJpYnV0ZShBX0RFWCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFF1ZXJ5QXR0cmlidXRlKEFfU1RSKSwgc2luZm9bUF9XRUFQT05dLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaW5mb1tQX1dFQVBPTl0tPlF1ZXJ5UHJvcChQX1dDKSkpOworICAgIHZhbCA9IDg1OworICB9CisKKyAgLyoKKyAgICBEZXIgenVz5HR6bGljaGUgU2NoYWRlbiBkZXIgYWxsZ2VtZWluZW4gV2FmZmVuc2tpbGxzIGJlcmVjaG5ldAorICAgIHNpY2ggd2llIGZvbGd0OiAKKworICAgIHNpbmZvW1NJX1NLSUxMQUJJTElUWSkqIChQX1dDICogKCBYICkgLyA4MDApIC8gTUFYX0FCSUxJVFkKKworICAgIERhYmVpIGJlcnVlY2tzaWNodGlndCBYIGplIG5hY2ggV2FmZmVudHlwIGluIHVudGVyc2NoaWVkbGljaGVyCisgICAgR2V3aWNodHVuZyBkaWUgV2VydGUgZnVlciBHZXNjaGlja2xpY2hrZWl0IHVuZCBTdGFlcmtlLiAKKworICAgICBYID09IAorCisgICAgICAgTWVzc2VyICAgOiA4KkFfREVYICsgMipBX1NUUgorICAgICAgIFNjaHdlcnQgIDogNSpBX0RFWCArIDUqQV9TVFIKKyAgICAgICBBeHQgICAgICA6IDQqQV9ERVggKyA2KkFfU1RSIAorICAgICAgIFNwZWVyICAgIDogNipBX0RFWCArIDQqQV9TVFIKKyAgICAgICBLZXVsZSAgICA6IDEqQV9ERVggKyA5KkFfU1RSCisgICAgICAgUGVpdHNjaGUgOiA5KkFfREVYICsgMSpBX1NUUgorICAqLworCisgIHNpbmZvW1NJX1NLSUxMREFNQUdFXSs9dmFsOworCisKKyAgLyogTGVybmVuOiBXaXJkIGltbWVyIHNjaHdpZXJpZ2VyLCBudXIgYmVpIGplZGVtIDIwLiBTY2hsYWcgaW0gU2Nobml0dCwKKyAgICogdW5kIG51ciBkYW5uLCB3ZW5uIGRlciBHZWduZXIgYXVjaCBYUCBnaWJ0LiAqLworICBpZiAocmFuZG9tKE1BWF9BQklMSVRZKzEpPnNpbmZvW1NJX1NLSUxMQUJJTElUWV0gJiYgIXJhbmRvbSgxMCkpCisgIHsKKyAgICAgICAgIGVuZW15PXNpbmZvW1NJX0VORU1ZXTsKKyAgICAgICAgIGlmIChvYmplY3RwKGVuZW15KSAmJiAoZW5lbXktPlF1ZXJ5UHJvcChQX1hQKT4wKSkKKyAgICAgICAgIHsKKyAgICAgICAgICAgb2JqZWN0IGF1c2JpbGRlcjsKKyAgICAgICAgLy8gICAgICAgICBsb2dfZmlsZSgiaHVtbmkvbG9nX3d1cm0iLCJIYXV0OiAlcyB1bmQgendhciAlcywgbWl0IHhwICVkXG4iLGdldGV1aWQodGhpc19vYmplY3QoKSksdG9fc3RyaW5nKGVuZW15KSxlbmVteS0+UXVlcnlQcm9wKFBfWFApKTsKKyAgICAgICAgICAgIExlYXJuU2tpbGwoc25hbWUsIHJhbmRvbSg1KSwgMTUwKTsKKyAgICAgICAgLy8gR2lidCBlcyBlaW5lbiBBdXNiaWxkZXI/CisgICAgICAgIGlmIChRdWVyeVByb3AoUF9XRUFQT05fVEVBQ0hFUikgJiYgCisgICAgICAgICAgICAgICAgICAgICAgICBhdXNiaWxkZXI9ZmluZF9wbGF5ZXIoUXVlcnlQcm9wKFBfV0VBUE9OX1RFQUNIRVIpKSkKKyAgICAgICAgICB7CisgICAgICAgICAgICAvLyBJc3QgZGVyIEF1c2JpbGRlciBhbndlc2VuZD8KKyAgICAgICAgICAgIGlmIChwcmVzZW50KGF1c2JpbGRlcixlbnZpcm9ubWVudCgpKSkKKyAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAvLyBBdXNiaWxkZXIgdW5kIEF6dWJpIG11ZXNzZW4gZGllc2VsYmUgV2FmZmUgaGFiZW4uCisgICAgICAgICAgICAgIC8vc3RyaW5nIHd0X2F1cyx3dF9henU7CisgICAgICAgICAgICAgIG9iamVjdCB3YWZfYXVzLHdhZl9henU7CisKKyAgICAgICAgICAgICAgd2FmX2F6dT1RdWVyeVByb3AoUF9XRUFQT04pOworICAgICAgICAgICAgICB3YWZfYXVzPWNhbGxfb3RoZXIoYXVzYmlsZGVyLCJRdWVyeVByb3AiLFBfV0VBUE9OKTsKKworICAgICAgICAgICAgICAvL3d0X2F6dT1jYWxsX290aGVyKHdhZl9henUsIlF1ZXJ5UHJvcCIsUF9XRUFQT05fVFlQRSk7CisgICAgICAgICAgICAgIC8vd3RfYXVzPWNhbGxfb3RoZXIod2FmX2F1cywiUXVlcnlQcm9wIixQX1dFQVBPTl9UWVBFKTsKKyAgICAgICAgICAgICAgLy9pZiAod3RfYXp1PT13dF9hdXMpCisgICAgICAgICAgICAgIGlmIChvYmplY3RwKHdhZl9hdXMpICYmIG9iamVjdHAod2FmX2F6dSkgJiYKKyAgICAgICAgICAgICAgICAgIChzdHJpbmcpd2FmX2F1cy0+UXVlcnlQcm9wKFBfV0VBUE9OX1RZUEUpCisgICAgICAgICAgICAgICAgICAgICA9PSAoc3RyaW5nKXdhZl9henUtPlF1ZXJ5UHJvcChQX1dFQVBPTl9UWVBFKSkgCisgICAgICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIC8vIEJvbnVzIHZvbiBiaXMgenUgNSBQdW5rdGVuCisgICAgICAgICAgICAgICAgLy9sb2dfZmlsZSgiaHVtbmkvbG9nX2F6dWJpIiwKKyAgICAgICAgICAgICAgICAgIC8vIHNwcmludGYoIkF6dWJpICVPIHVuZCBBdXNiaWxkZXIgJU8gOiBXYWZmZW50eXBlbiAlcyB1bmQgJXMsIGdlbGVybnRcbiIsdGhpc19vYmplY3QoKSwKKyAgICAgICAgICAgICAgICAgICAgLy8gICBhdXNiaWxkZXIsIHd0X2F6dSwgd3RfYXVzKSk7CisgICAgICAgICAgICAgICAgTGVhcm5Ta2lsbChzbmFtZSxyYW5kb20oNiksMTUwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICB9CisKKyAgLyogCisgICAgIERpZSBTY2h3aWVyaWdrZWl0IGxpZWd0IGJlaSAxNTAsIHNvIGRhc3MgCisgICAgIGVpbiBMdmwuIDEgU3BpZWxlciBtYXhpbWFsIDE1JSBTa2lsbCAKKyAgICAgdXN3Li4uCisgICAgIGxlcm5lbiBrYW5uLiAoR2VuYXVlIFRhYmVsbGUgaW4gL3N0ZC9saXZpbmcvc2tpbGxzIGJlaSBMaW1pdEFiaWxpdHkpCisgICovICAgICAgICAgCisKKyAgcmV0dXJuIHNpbmZvOworfQorCisKKy8vIFN0YW5kYXJkaXNpZXJ0ZSBGZXJua2FtcGYtRnVua3Rpb24gZnVlciBhbGxlIEZlcm5rYW1wZi1XYWZmZW5hcnRlbgorCisvLyAqKiogbm9jaCBkZWFrdGl2aWVydCAqKioKKworcHJvdGVjdGVkIG1hcHBpbmcgTG9uZ1JhbmdlU2tpbGwob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8sIGludCBkYW0pIAoreyBpbnQgYWJpbCx2YWw7CisKKyAgaWYgKCFtYXBwaW5ncChzaW5mbykgfHwgIWRhbSB8fCAhb2JqZWN0cChzaW5mb1tQX1dFQVBPTl0pIHx8CisgICAgICAoc2luZm9bUF9XRUFQT05dLT5RdWVyeVByb3AoUF9TSE9PVElOR19XQykpPDUpCisgICAgcmV0dXJuIDA7CisKKyAgYWJpbD1zaW5mb1tTSV9TS0lMTEFCSUxJVFldK3NpbmZvW09GRlNFVChTSV9TS0lMTEFCSUxJVFkpXTsgCisgIHZhbD1kYW0qYWJpbC9NQVhfQUJJTElUWTsKKyAgdmFsPXZhbC8yK3JhbmRvbSh2YWwvMisxKTsKKyAgdmFsPSh2YWwqUXVlcnlTa2lsbEF0dHJpYnV0ZShTQV9EQU1BR0UpKS8xMDA7CisgIHNpbmZvW1NJX1NLSUxMREFNQUdFXSs9dmFsOworCisgIGlmIChyYW5kb20oTUFYX0FCSUxJVFkrMSk+c2luZm9bU0lfU0tJTExBQklMSVRZXSAmJiByYW5kb20oNTApPT00MikKKyAgICBMZWFyblNraWxsKHNuYW1lLCAxLCAxNTApOworCisgIHJldHVybiBzaW5mbzsKK30KKworCisKKy8vIERpZSBlaW56ZWxuZW4gV2FmZmVuc2tpbGxzIHJ1ZmVuIGRhbm4gbnVyIGRpZSBTdGFuZGFyZC1GdW5rdGlvbiBhdWYuCisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X2F4ZShvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKK3sKKyAgcmV0dXJuIFNob3J0UmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvKTsKK30KKworcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfY2x1YihvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKK3sKKyAgcmV0dXJuIFNob3J0UmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvKTsKK30KKworcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfRmlnaHRfa25pZmUob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCit7CisgIHJldHVybiBTaG9ydFJhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbyk7Cit9CisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X3NwZWFyKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQoreworICByZXR1cm4gU2hvcnRSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8pOworfQorCitwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9GaWdodF9zd29yZChvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykgCit7CisgIHJldHVybiBTaG9ydFJhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbyk7Cit9CisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X3doaXAob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCit7CisgIHJldHVybiBTaG9ydFJhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbyk7Cit9CisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX0ZpZ2h0X3N0YWZmKG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQoreworICByZXR1cm4gU2hvcnRSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8pOworfQorCisKKworCisvLyBEaWUgRmVybndhZmZlbnNraWxscyBzaW5kIE11bml0aW9uc2FiaGFlbmdpZworCisvLyAqKiogbm9jaCBkZWFrdGl2aWVydCAqKioKKworcHJvdGVjdGVkIG1hcHBpbmcgU3RkU2tpbGxfU2hvb3RfYXJyb3cob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCit7CisgIHJldHVybiBMb25nUmFuZ2VTa2lsbChtZSwgc25hbWUsIHNpbmZvLCA0MCk7Cit9CisKK3Byb3RlY3RlZCBtYXBwaW5nIFN0ZFNraWxsX1Nob290X2JvbHQob2JqZWN0IG1lLCBzdHJpbmcgc25hbWUsIG1hcHBpbmcgc2luZm8pCit7IAorICByZXR1cm4gTG9uZ1JhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbywgNDApOworfQorCitwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9TaG9vdF9kYXJ0KG9iamVjdCBtZSwgc3RyaW5nIHNuYW1lLCBtYXBwaW5nIHNpbmZvKQoreworICByZXR1cm4gTG9uZ1JhbmdlU2tpbGwobWUsIHNuYW1lLCBzaW5mbywgMjApOworfQorCitwcm90ZWN0ZWQgbWFwcGluZyBTdGRTa2lsbF9TaG9vdF9zdG9uZShvYmplY3QgbWUsIHN0cmluZyBzbmFtZSwgbWFwcGluZyBzaW5mbykKK3sKKyAgcmV0dXJuIExvbmdSYW5nZVNraWxsKG1lLCBzbmFtZSwgc2luZm8sIDQwKTsKK30KKworcHJvdGVjdGVkIG1peGVkIF9xdWVyeV9sb2NhbGNtZHMoKSB7CisgICAgcmV0dXJuICh7ICh7InNwcnVjaGVybXVlZHVuZyIsImVuYWJsZV9zcGVsbF9mYXRpZ3VlX2NvbXBhdCIsMCwwfSkgfSk7Cit9CisKKworCisvLyAqKiogS29tcGF0aWJpbGl0YWV0c21vZHVzIGZ1ZXIgU3BlbGxmYXRpZ3VlcyAoRW11bGF0aW9uIDJzLUFsYXJtemVpdCkgKioqCisKKy8qKiBTcGVpY2hlcnQgZWluZSBTcGVsbGZhdGlndWUgdm9uIDxkdXJhdGlvbj4gU2VrdW5kZW4gZnVlciA8a2V5Pi4KKyAqIElzdCBoaWVyIG51ciBmdWVyIGRlbiBTcGVsbGZhdGlndWUtQ29tcGF0LW1vZGUuCisgKiA8a2V5PiBkYXJmIDAgc2VpbiB1bmQgYmV6ZWljaG5ldCBkYXMgZ2xvYmFsZSBTcGVsbGZhdGlndWUuCisgKiBSdWVja2dhYmV3ZXJ0OiBBYmxhdWZ6ZWl0IGRlciBnZXNldHp0ZW4gU3BlcnJlCisgICAgICAgICAgICAgICAgICAtMSwgd2VubiBub2NoIGVpbmUgbmljaHQtYWJnZWxhdWZlbmUgU3BlcnJlIGF1ZiBkZW0gPGtleT4gbGFnLgorICAgICAgICAgICAgICAgICAgMCwgd2VubiBkdXJhdGlvbiAwIGlzdC4KKyAqLworcHVibGljIHZhcmFyZ3MgaW50IFNldFNwZWxsRmF0aWd1ZShpbnQgZHVyYXRpb24sIHN0cmluZyBrZXkpIHsKKworICAvLyAwIHNvbGx0ZSBuaWUgZWluZSBTcGVycmUgYmV3aXJrZW4sIGF1Y2ggbmljaHQgaW0gY29tcGF0IG1vZGUuCisgIGlmICghZHVyYXRpb24pIHJldHVybiAwOworCisgIGlmIChzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlKSB7CisgICAgLy8gU3BlbGwtRmF0aWd1ZXMgYXVmIEhCcyBzeW5jaHJvbmlzaWVyZW4gKDJzLUFsYXJtemVpdC1FbXVsYXRpb24pLgorICAgIC8vIEF1ZnJ1bmRlbiBhdWYgZ2FuenphaGxpZ2UgVmllbGZhY2hlIHZvbiBfX0hFQVJUX0JFQVRfSU5URVJWQUxfXworICAgIGlmIChkdXJhdGlvbiAlIF9fSEVBUlRfQkVBVF9JTlRFUlZBTF9fKQorICAgICAgICArK2R1cmF0aW9uOworCisgICAgLy8gU3RhcnRwdW5rdCBkZXMgRGVsYXkgc29sbCBCZWdpbm4gZGVyIGFrdHVlbGxlbiBLYW1wZnJ1bmRlIChIQi1aeWtsdXMpCisgICAgLy8gc2VpbiwgZ2dmLiB1bSBtYXguIGVpbmUgU2VrdW5kZSB6dXJ1ZWNrZGF0aWVyZW4uCisgICAgLy8gKHNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGUgaGF0IGRpZSBaZWl0IGRlcyBsZXR6dGVuIEhCLUF1ZnJ1ZnMpCisgICAgLy8gRmFsbHMgZHVyY2ggaXJnZW5kZWluIFByb2JsZW0gKHouQi4gc2VociBob2hlIExhc3QpLCBkZXIgbGV0enRlIEhCCisgICAgLy8gbGFlbmdlciBhbHMgMXMgenVydWVja2xpZWd0LCBmdW5rdGlvbmllcnQgZGFzIG5hdHVlcmxpY2ggbmljaHQsIGFiZXIKKyAgICAvLyBiZWkgZmF0aWd1ZSs9c3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSBrYW5uIGRlciBTcGllbGVyIHp1dmllbCBaZWl0CisgICAgLy8gZWluc3BhcmVuLgorICAgIGlmICh0aW1lKCkgPiBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlKQorICAgICAgICAtLWR1cmF0aW9uOyAgLy8xcyB6dXJ1ZWNrZGF0aWVyZW4KKyAgfQorCisgIHJldHVybiA6OlNldFNwZWxsRmF0aWd1ZShkdXJhdGlvbiwga2V5KTsKK30KKworLyoqIEJlZmVobHNmdW5rdGlvbiBmdWVyIFNwaWVsZXIgdW0gZGVuIFNwZWxsZmF0aWd1ZS1Lb21wYXRpYmlsaXRhZXRzbW9kdXMKKyAqIHVtenVzY2hhbHRlbi4KKyAqLworcHVibGljIGludCBlbmFibGVfc3BlbGxfZmF0aWd1ZV9jb21wYXQoc3RyaW5nIGNtZCkgeworICBpZiAoUXVlcnlQcm9wKFBfTEFTVF9DT01CQVRfVElNRSkgKyA2MDAgPiB0aW1lKCkpIHsKKyAgICB3cml0ZShicmVha19zdHJpbmcoCisgICAgICAiSW0gS2FtcGYgb2RlciBrdXJ6IG5hY2ggZWluZW0gS2FtcGYga2FubnN0IER1IG5pY2h0IHp3aXNjaGVuICIKKyAgICAgICJhbHRlciB1bmQgbmV1ZXIgU3BydWNoZXJtdWVkdW5nIHVtc2NoYWx0ZW4uXG4iCisgICAgICAiTW9tZW50YW4gYmVudXR6dCBEdSBkaWUgIgorICAgICAgKyAoc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSA/ICJhbHRlICh1bmdlbmF1ZXJlKSIgOiAibmV1ZSAobm9ybWFsZSkiKQorICAgICAgKyAiIFNwcnVjaGVybXVlZHVuZy4iLDc4LDAsQlNfTEVBVkVfTVlfTEZTKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBpZiAoY21kPT0iYWx0IikgeworICAgIHNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGU9dGltZSgpOworICAgIHdyaXRlKGJyZWFrX3N0cmluZygKKyAgICAgICJBbHRlIFNwcnVjaGVybXVlZHVuZyB3dXJkZSBlaW5nZXNjaGFsdGV0LiBBbGxlIEVybXVlZHVuZ3NwYXVzZW4gIgorICAgICAgInp3aXNjaGVuIFNwcnVlY2hlbiB3ZXJkZW4gYXVmIFZpZWxmYWNoZSB2b24gMnMgYXVmZ2VydW5kZXQgdW5kICIKKyAgICAgICJiZWdpbm5lbiBpbiBkZXIgUmVnZWwgYW0gQW5mYW5nIERlaW5lciBLYW1wZnJ1bmRlLiIpKTsKKyAgICByZXR1cm4gMTsKKyAgfQorICBlbHNlIGlmIChjbWQ9PSJuZXUiIHx8IGNtZD09Im5vcm1hbCIpIHsKKyAgICBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlPTA7CisgICAgd3JpdGUoYnJlYWtfc3RyaW5nKAorICAgICAgIk5vcm1hbGUgU3BydWNoZXJtdWVkdW5nIHd1cmRlIGVpbmdlc2NoYWx0ZXQuIEFsbGUgRXJtdWVkdW5nc3BhdXNlbiAiCisgICAgICAiendpc2NoZW4gU3BydWVjaGVuIHdlcmRlbiBzZWt1bmRlbmdlbmF1IGJlcmVjaG5ldC4iKSk7CisgICAgcmV0dXJuIDE7CisgIH0KKworICBub3RpZnlfZmFpbChicmVha19zdHJpbmcoCisgICAgICAiTW9lY2h0ZXN0IER1IGRpZSBhbHRlIG9kZXIgZGllIG5ldWUgU3BydWNoZXJtdWVkdW5nP1xuIgorICAgICAgIk1vbWVudGFuIGJlbnV0enQgRHUgZGllICIKKyAgICAgICsgKHNwZWxsX2ZhdGlndWVfY29tcGF0X21vZGUgPyAiYWx0ZSAodW5nZW5hdWVyZSkiIDogIm5ldWUgKG5vcm1hbGUpIikKKyAgICAgICsgIiBTcHJ1Y2hlcm11ZWR1bmcuIiw3OCwwLEJTX0xFQVZFX01ZX0xGUykpOworICByZXR1cm4gMDsKK30KKworLyoqIFNwZWljaGVydCBkaWUgWmVpdCBkZXMgbGV0enRlcyBIZWFydGJlYXRzLgorICovCitwcm90ZWN0ZWQgdm9pZCBoZWFydF9iZWF0KCkgeworICBpZiAoc3BlbGxfZmF0aWd1ZV9jb21wYXRfbW9kZSkKKyAgICBzcGVsbF9mYXRpZ3VlX2NvbXBhdF9tb2RlID0gdGltZSgpOworfQorCitzdGF0aWMgaW50IF9zZXRfZ3VpbGRfbGV2ZWwoaW50IG51bSkKK3sgc3RyaW5nIGdpbGRlOworICBtYXBwaW5nIGxldmVsczsKKworICBpZiAoICEoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCAhbWFwcGluZ3AobGV2ZWxzPVF1ZXJ5KFBfR1VJTERfTEVWRUwpKSApCisgICAgbGV2ZWxzPShbXSk7CisKKyAgbGV2ZWxzW2dpbGRlXT1udW07CisgIFNldChQX0dVSUxEX0xFVkVMLGxldmVscyk7CisgIEdNQ1BfQ2hhciggKFtQX0dVSUxEX0xFVkVMOiBudW1dKSApOworCisgIHJldHVybiBudW07Cit9CisKK3N0YXRpYyBpbnQgX3F1ZXJ5X2d1aWxkX2xldmVsKCkKK3sgc3RyaW5nICBnaWxkZTsKKyAgbWFwcGluZyBsZXZlbHM7CisKKyAgaWYgKCAhKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgKQorICAgIHJldHVybiAwOworCisgIGlmICggIW1hcHBpbmdwKGxldmVscz1RdWVyeShQX0dVSUxEX0xFVkVMKSkgKQorICAgICAgcmV0dXJuIDA7CisKKyAgcmV0dXJuIGxldmVsc1tnaWxkZV07Cit9CisKK3N0YXRpYyBzdHJpbmcgX3NldF9ndWlsZF90aXRsZShzdHJpbmcgdCkKK3sgc3RyaW5nIGdpbGRlOworICBtYXBwaW5nIHRpdGxlczsKKworICBpZiAoICEoZ2lsZGU9UXVlcnlQcm9wKFBfR1VJTEQpKSApCisgICAgcmV0dXJuIDA7CisKKyAgaWYgKCAhbWFwcGluZ3AodGl0bGVzPVF1ZXJ5KFBfR1VJTERfVElUTEUpKSApCisgICAgdGl0bGVzPShbXSk7CisKKyAgdGl0bGVzW2dpbGRlXT10OworICBTZXQoUF9HVUlMRF9USVRMRSx0aXRsZXMpOworICBHTUNQX0NoYXIoIChbUF9HVUlMRF9USVRMRTogdF0pICk7CisgIHJldHVybiB0OworfQorCitzdGF0aWMgc3RyaW5nIF9xdWVyeV9ndWlsZF90aXRsZSgpCit7IHN0cmluZyBnaWxkZSx0OworICBvYmplY3QgZzsKKyAgbWFwcGluZyB0aXRsZXM7CisKKyAgaWYgKCAhKGdpbGRlPVF1ZXJ5UHJvcChQX0dVSUxEKSkgKQorICAgIHJldHVybiAwOworCisgIGlmICggIW1hcHBpbmdwKHRpdGxlcz1RdWVyeShQX0dVSUxEX1RJVExFKSkgKQorICAgIHRpdGxlcz0oW10pOworCisgIHQ9dGl0bGVzW2dpbGRlXTsKKyAgaWYgKCAhdCAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKHRoaXNfb2JqZWN0KCkpCisgICAgICAmJiBvYmplY3RwKGc9ZmluZF9vYmplY3QoIi9naWxkZW4vIitnaWxkZSkpICkKKyAgeworICAgIGctPmFkanVzdF90aXRsZSh0aGlzX29iamVjdCgpKTsKKyAgICBTZXRQcm9wKFBfVElUTEUsMCk7CisKKyAgICBpZiAoICFtYXBwaW5ncCh0aXRsZXM9UXVlcnkoUF9HVUlMRF9USVRMRSkpICkKKyAgICAgIHJldHVybiAwOworCisgICAgdD10aXRsZXNbZ2lsZGVdOworICB9CisKKyAgcmV0dXJuIHQ7Cit9CisKKworc3RhdGljIHN0cmluZyBfc2V0X2d1aWxkKHN0cmluZyBnaWxkZW5uYW1lKQoreyBvYmplY3QgcHJlOworCisgIGlmICghb2JqZWN0cChwcmU9cHJldmlvdXNfb2JqZWN0KCkpKQorICAgIHJldHVybiAwOworCisgIGlmICggcHJlIT10aGlzX29iamVjdCgpIC8vIERhcyBMZWJld2VzZW4gc2VsYmVyIGRhcmYgZGllIEdpbGRlIHNldHplbiwKKyAgICAgICYmIG9iamVjdF9uYW1lKHByZSkhPUdVSUxETUFTVEVSICAvLyBkZXIgR2lsZGVubWFzdGVyIGF1Y2gKKyAgICAgICYmICghdGhpc19wbGF5ZXIoKQorICAgICAgICAgIHx8IHRoaXNfcGxheWVyKCkgIT0gdGhpc19pbnRlcmFjdGl2ZSgpCisgICAgICAgICAgfHwgIUlTX0FSQ0godGhpc19wbGF5ZXIoKSkKKyAgICAgICAgICkKKyAgICAgICkKKyAgICByZXR1cm4gMDsKKworICBTZXQoUF9HVUlMRCxnaWxkZW5uYW1lKTsKKyAgR01DUF9DaGFyKCAoW1BfR1VJTEQ6IGdpbGRlbm5hbWVdKSApOworICByZXR1cm4gZ2lsZGVubmFtZTsKK30KKworc3RhdGljIHN0cmluZyBfcXVlcnlfZ3VpbGQoKQoreyBzdHJpbmcgcmVzOworCisgIGlmICggIShyZXM9UXVlcnkoUF9HVUlMRCkpICYmIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkgKQorICB7CisgICAgLy8gU3BpZWxlciwgZGllIGtlaW5lciBHaWxkZSBhbmdlaG9lcmVuLCBnZWhvZXJlbiB6dXIgQWJlbnRldXJlcmdpbGRlCisgICAgaWYgKCAhKHJlcz1RdWVyeVByb3AoUF9ERUZBVUxUX0dVSUxEKSkgKQorICAgICAgcmV0dXJuIERFRkFVTFRfR1VJTEQ7CisgICAgZWxzZQorICAgICAgU2V0KFBfR1VJTEQscmVzKTsKKyAgICByZXR1cm4gcmVzOworICB9CisKKyAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIHN0cmluZyBfcXVlcnlfdGl0bGUoKQoreyBzdHJpbmcgdGk7CisKKyAgaWYgKCBzdHJpbmdwKHRpPVF1ZXJ5KFBfVElUTEUpKSApCisgICAgcmV0dXJuIHRpOworCisgIHJldHVybiBRdWVyeVByb3AoUF9HVUlMRF9USVRMRSk7Cit9CisKK3N0YXRpYyBzdHJpbmcgX3NldF90aXRsZShzdHJpbmcgdCkKK3sKKyAgU2V0KFBfVElUTEUsIHQsIEZfVkFMVUUpOworICBHTUNQX0NoYXIoIChbUF9USVRMRTogdF0pICk7CisgIHJldHVybiB0OworfQorCg==