Ly8gTW9yZ2VuR3JhdWVuIE1VRGxpYgovLwovLyBsaXZpbmcvbGlmZS5jIC0tIGxpZmUgdmFyaWFibGVzCi8vCi8vICRJZDogbGlmZS5jIDk0MjYgMjAxNi0wMS0wMyAxMDowMjo1N1ogWmVzc3RyYSAkCgovLyBsaXZpbmcgb2JqZWN0IGxpZmUgdmFyaWFibGVzCi8vCi8vICBQX0FMSUdOICAgICAgICAgLS0gYWxpZ25tZW50IHZhbHVlCi8vICBQX05QQyAgICAgICAgICAgLS0gaWYgbGl2aW5nIGlzIGFuIE5QQwovLyAgUF9IUCAgICAgICAgICAgIC0tIEhpdFBvaW50cwovLyAgUF9TUCAgICAgICAgICAgIC0tIFNwZWxsUG9pbnRzCi8vICBQX0FMQ09IT0wgICAgICAgLS0gdmFsdWUgb2YgaW50b3hpY2F0aW9uCi8vICBQX0RSSU5LICAgICAgICAgLS0gdmFsdWUgb2Ygc29ha25lc3MKLy8gIFBfRk9PRCAgICAgICAgICAtLSB2YWx1ZSBvZiBzdHVmZm5lc3MKLy8gIFBfWFAgICAgICAgICAgICAtLSBleHBlcmllbmNlCi8vICBQX1BPSVNPTiAgICAgICAgLS0gbGV2ZWwgb2YgcG9pc29uCi8vICBQX0NPUlBTRSAgICAgICAgLS0gY29ycHNlLW9iamVjdAovLyAgUF9ERUFGICAgICAgICAgIC0tIGlmIGxpdmluZyBpcyBkZWFmCiNwcmFnbWEgc3Ryb25nX3R5cGVzLHNhdmVfdHlwZXMscnR0X2NoZWNrcwojcHJhZ21hIHJhbmdlX2NoZWNrCiNwcmFnbWEgbm9fY2xvbmUKI3ByYWdtYSBwZWRhbnRpYwoKI2RlZmluZSBORUVEX1BST1RPVFlQRVMKI2luY2x1ZGUgPGhvb2suaD4KI2luY2x1ZGUgPGxpdmluZy9za2lsbHMuaD4KI2luY2x1ZGUgPHRoaW5nL3Byb3BlcnRpZXMuaD4KI2luY2x1ZGUgPGxpdmluZy9saWZlLmg+CiNpbmNsdWRlIDxsaXZpbmcvbW92aW5nLmg+CiNpbmNsdWRlIDxsaXZpbmcvY29tYmF0Lmg+CiNpbmNsdWRlIDxsaXZpbmcvYXR0cmlidXRlcy5oPgojaW5jbHVkZSA8dGhpbmcvZGVzY3JpcHRpb24uaD4KI2luY2x1ZGUgPHRoaW5nL2xhbmd1YWdlLmg+CiN1bmRlZiBORUVEX1BST1RPVFlQRVMKI2luY2x1ZGUgPGhlYWx0aC5oPgojaW5jbHVkZSA8ZGVmaW5lcy5oPgojaW5jbHVkZSA8bmV3X3NraWxscy5oPgojaW5jbHVkZSA8c2NvcmVtYXN0ZXIuaD4KI2luY2x1ZGUgPGRlZnVlbC5oPgojaW5jbHVkZSA8cHJvcGVydGllcy5oPgojaW5jbHVkZSA8ZXZlbnRzLmg+CiNpbmNsdWRlIDx3aXpsZXZlbHMuaD4KCiNkZWZpbmUgQUxDT0hPTF9WQUxVRShuKSBuCgojaW5jbHVkZSA8ZGVidWdfaW5mby5oPiAvL3ZvcnVlYmVyZ2VoZW5kCgoKLy8gJ3ByaXZhdGUnLVByb3RvdHlwZW4KcHJpdmF0ZSB2b2lkIERpc3RyaWJ1dGVFeHAob2JqZWN0IGVuZW15LCBpbnQgZXhwX3RvX2dpdmUpOwoKLy8gVmFyaWFibGVuCm5vc2F2ZSBpbnQgZGVsYXlfYWxjb2hvbDsgLyogdGltZSB1bnRpbCBuZXh0IGFsY29ob2wgZWZmZWN0ICovCm5vc2F2ZSBpbnQgZGVsYXlfZHJpbms7ICAgLyogdGltZSB1bnRpbCBuZXh0IGRyaW5rIGVmZmVjdCAqLwpub3NhdmUgaW50IGRlbGF5X2Zvb2Q7ICAgIC8qIHRpbWUgdW50aWwgbmV4dCBmb29kIGVmZmVjdCAqLwpub3NhdmUgaW50IGRlbGF5X2hlYWw7ICAgIC8qIHRpbWUgdW50aWwgbmV4dCBoZWFsIGVmZmVjdCAqLwpub3NhdmUgaW50IGRlbGF5X3NwOyAgICAgIC8qIHRpbWUgdW50aWwgbmV4dCBzcCByZWdlbmVyYXRpb24gKi8Kbm9zYXZlIGludCBkZWxheV9wb2lzb247ICAvKiB0aW1lIHVudGlsIG5leHQgcG9pc29uIGVmZmVjdCAqLwpub3NhdmUgaW50IGRyb3BfcG9pc29uOwpub3NhdmUgbWFwcGluZyBlbmVteV9kYW1hZ2U7Cm5vc2F2ZSBtYXBwaW5nIGhwX2J1ZmZlcjsKbm9zYXZlIG1hcHBpbmcgc3BfYnVmZmVyOwpub3NhdmUgaW50IHJlbW92ZV9tZTsKaW50IG5leHRkZWZ1ZWx0aW1lZm9vZDsKaW50IG5leHRkZWZ1ZWx0aW1lZHJpbms7CgoKcHJvdGVjdGVkIHZvaWQgY3JlYXRlKCkKewogIFNldChQX0dIT1NULCBTQVZFLCBGX01PREUpOwogIFNldChQX0ZST0csIFNBVkUsIEZfTU9ERSk7CiAgU2V0KFBfQUxJR04sIFNBVkUsIEZfTU9ERSk7CiAgU2V0KFBfSFAsIFNBVkUsIEZfTU9ERSk7CiAgU2V0KFBfU1AsIFNBVkUsIEZfTU9ERSk7CiAgU2V0KFBfWFAsIFNBVkUsIEZfTU9ERSk7CiAgU2V0KCBQX0xBU1RfWFAsICh7ICIiLCAwIH0pICk7CiAgU2V0KCBQX0xBU1RfWFAsIFBST1RFQ1RFRCwgRl9NT0RFX0FTICk7CgogIFNldChQX0FMQ09IT0wsIFNBVkUsIEZfTU9ERSk7CiAgU2V0KFBfRFJJTkssIFNBVkUsIEZfTU9ERSk7CiAgU2V0KFBfRk9PRCwgU0FWRSwgRl9NT0RFKTsKICBTZXQoUF9QT0lTT04sIFNBVkUsIEZfTU9ERSk7CiAgU2V0KFBfREVBRiwgU0FWRSwgRl9NT0RFKTsKCiAgU2V0UHJvcChQX0ZPT0RfREVMQVksIEZPT0RfREVMQVkpOwogIFNldFByb3AoUF9EUklOS19ERUxBWSwgRFJJTktfREVMQVkpOwogIFNldFByb3AoUF9BTENPSE9MX0RFTEFZLCBBTENPSE9MX0RFTEFZKTsKICBTZXRQcm9wKFBfSFBfREVMQVksSEVBTF9ERUxBWSk7CiAgU2V0UHJvcChQX1NQX0RFTEFZLEhFQUxfREVMQVkpOwogIFNldFByb3AoUF9QT0lTT05fREVMQVksUE9JU09OX0RFTEFZKTsKICAvLyBkZWZhdWx0IGZ1ZXIgYWxsZSBMZWJld2VzZW4gKE5QQyArIFNwaWVsZXIpOgogIFNldFByb3AoUF9NQVhfUE9JU09OLCAxMCk7CiAgU2V0UHJvcChQX0NPUlBTRSwgIi9zdGQvY29ycHNlIik7CgogIG5leHRkZWZ1ZWx0aW1lZm9vZD10aW1lKCkrUXVlcnlQcm9wKFBfREVGVUVMX1RJTUVfRk9PRCk7CiAgbmV4dGRlZnVlbHRpbWVkcmluaz10aW1lKCkrUXVlcnlQcm9wKFBfREVGVUVMX1RJTUVfRFJJTkspOwoKICBlbmVteV9kYW1hZ2U9KFs6MiBdKTsKICBocF9idWZmZXI9KFtdKTsKICBzcF9idWZmZXI9KFtdKTsKCiAgU2V0UHJvcChQX0RFRlVFTF9MSU1JVF9GT09ELDEpOwogIFNldFByb3AoUF9ERUZVRUxfTElNSVRfRFJJTkssMSk7CiAgU2V0UHJvcChQX0RFRlVFTF9USU1FX0ZPT0QsMSk7CiAgU2V0UHJvcChQX0RFRlVFTF9USU1FX0RSSU5LLDEpOwogIFNldFByb3AoUF9ERUZVRUxfQU1PVU5UX0ZPT0QsMSk7CiAgU2V0UHJvcChQX0RFRlVFTF9BTU9VTlRfRFJJTkssMSk7CgogIG9mZmVySG9vayhIX0hPT0tfRElFLDEpOwoKICBvZmZlckhvb2soSF9IT09LX0ZPT0QsMSk7CiAgb2ZmZXJIb29rKEhfSE9PS19EUklOSywxKTsKICBvZmZlckhvb2soSF9IT09LX0FMQ09IT0wsMSk7CiAgb2ZmZXJIb29rKEhfSE9PS19QT0lTT04sMSk7CiAgb2ZmZXJIb29rKEhfSE9PS19DT05TVU1FLDEpOwp9CgovLyBXZW5uIGRlciBsZXR6dGUgS2FtcGYgbGFuZyBoZXIgaXN0IHVuZCBkYXMgTGViZXdlc2VuIHdpZWRlciB2b2xsZ2VoZWlsdAovLyBpc3QsIHdpcmQgUF9FTkVNWV9EQU1BR0UgenVydWVja2dlc2V0enQuCnByb3RlY3RlZCB2b2lkIFJlc2V0RW5lbXlEYW1hZ2UoKSB7CiAgaWYgKHRpbWUoKSA+IFF1ZXJ5UHJvcChQX0xBU1RfQ09NQkFUX1RJTUUpICsgX19SRVNFVF9USU1FX18gKiA0CiAgICAgICYmIFF1ZXJ5UHJvcChQX0hQKSA9PSBRdWVyeVByb3AoUF9NQVhfSFApKQogICAgZW5lbXlfZGFtYWdlPShbOjIgXSk7Cn0KCnByaXZhdGUgdm9pZCBEaXN0cmlidXRlRXhwKG9iamVjdCBlbmVteSwgaW50IGV4cF90b19naXZlKSB7CiAgaW50IHRvdGFsX2RhbWFnZSwgdG1wLCBleDsKICBtYXBwaW5nIHByZXNlbnRfZW5lbWllczsKCiAgaWYgKCBleHBfdG9fZ2l2ZTw9MCApCiAgICByZXR1cm47CgogIG1hcHBpbmcgZW5kbWc9ZGVlcF9jb3B5KGVuZW15X2RhbWFnZSk7CgogIC8vIE1pdGdsaWVkZXIgaW0gVGVhbSBkZXMgS2lsbGVycyBiZWtvbW1lbjoKICAvLwogIC8vICAgICAgICAgICAgICAgICAgR2VzYW10YW50ZWlsIGRlcyBUZWFtcwogIC8vIEVpZ2VuZW4gQW50ZWlsICsgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vICAgICAgICAgICAgICAgICAgQW56YWhsICBUZWFtbWl0Z2xpZWRlcgogIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogIC8vICAgICAgICAgICAgICAgIDIKICAvLwogIG9iamVjdCAqaW52ID0gZW5lbXktPlRlYW1NZW1iZXJzKCk7CiAgaWYgKCBwb2ludGVycChpbnYpICkKICB7CiAgICBwcmVzZW50X2VuZW1pZXM9bV9hbGxvY2F0ZShzaXplb2YoaW52KSwgMSk7CiAgICBmb3JlYWNoKG9iamVjdCBvYjogaW52KQogICAgewogICAgICBpZiAoIG9iamVjdHAob2IpICYmIChlbnZpcm9ubWVudChvYik9PWVudmlyb25tZW50KCkpICkKICAgICAgewogICAgICAgIHRtcD1lbmRtZ1tvYmplY3RfbmFtZShvYildOwogICAgICAgIHRvdGFsX2RhbWFnZSs9dG1wOwogICAgICAgIHByZXNlbnRfZW5lbWllc1tvYl0gPSB0bXAvMjsKICAgICAgICBtX2RlbGV0ZShlbmRtZyxvYmplY3RfbmFtZShvYikpOyAvL3MudS4KICAgICAgfQogICAgfQogICAgaW50IG1pdGdsaWVkZXIgPSBzaXplb2YocHJlc2VudF9lbmVtaWVzKTsKICAgIGlmICggbWl0Z2xpZWRlciApCiAgICB7CiAgICAgIHRtcD10b3RhbF9kYW1hZ2UvKDIqbWl0Z2xpZWRlcik7CiAgICAgIGZvcmVhY2gob2JqZWN0IG9iLCBpbnQgcHVua3RlOiAmcHJlc2VudF9lbmVtaWVzKQogICAgICAgIHB1bmt0ZSArPSB0bXA7CiAgICB9CiAgfQogIGVsc2UgewogICAgLy8gb2huZSBUZWFtIHdpcmQgdHJvdHpkZW0gZWluIE1hcHBpbmcgZ2VicmF1Y2h0LiBEYSBHcm9lc3NlbnZlcmFlbmRlcnVuZwogICAgLy8gcmVsLiB0ZXVlciBzaW5kLCBrYW5uIGVpbmZhY2ggbWFsIGZ1ZXIgMyBFaW50cmFlZ2UgUGxhdHogcmVzZXJ2aWVyZW4uCiAgICBwcmVzZW50X2VuZW1pZXM9bV9hbGxvY2F0ZSgzLCAxKTsKICB9CiAgLy8gVW5kIG5vY2ggZGllIExlYmV3ZXNlbiBpbSBSYXVtIG9obmUgVGVhbS4KICBmb3JlYWNoKG9iamVjdCBvYjogYWxsX2ludmVudG9yeShlbnZpcm9ubWVudCgpKSkKICB7CiAgICBpZiAoIHRtcD1lbmRtZ1tvYmplY3RfbmFtZShvYildICkKICAgIHsKICAgICAgdG90YWxfZGFtYWdlICs9IHRtcDsKICAgICAgcHJlc2VudF9lbmVtaWVzW29iXSA9IHRtcDsKICAgICAgbV9kZWxldGUoZW5kbWcsb2JqZWN0X25hbWUob2IpKTsgLy8gTnVyIGVpbm1hbCBwcm8gTGViZW4gUHVua3RlIDopCiAgICB9CiAgfQogIGlmICggIXRvdGFsX2RhbWFnZSApCiAgewogICAgZW5lbXktPkFkZEV4cChleHBfdG9fZ2l2ZSk7CiAgfQogIGVsc2UKICB7CiAgICBmb3JlYWNoKG9iamVjdCBvYiwgaW50IGRhbWFnZTogcHJlc2VudF9lbmVtaWVzKQogICAgewogICAgICBpZiAoICFvYmplY3RwKG9iKSApCiAgICAgICAgY29udGludWU7CiAgICAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShvYikgJiYgKCAhaW50ZXJhY3RpdmUob2IpCiAgICAgICAgICAgICAgfHwgKHF1ZXJ5X2lkbGUob2IpPjYwMCkgKSApCiAgICAgICAgY29udGludWU7CiAgICAgIC8vZXhwX3RvX2dpdmUqcHJlc2VudF9lbmVtaWVzW2ldWzFdL3RvdGFsX2RhbWFnZSBnaWJ0IGJlaSB2aWVsIFNjaGFkZW4KICAgICAgLy9laW5lbiBudW1lcmljYWwgb3ZlcmZsb3cuIERhaGVyIG11ZXNzZW4gd2lyIGhpZXIgd29obCBkb2NoCiAgICAgIC8vendpc2NoZW56ZWl0bGljaCBtaXQgZmxvYXRzIHJlY2huZW4sIGF1Y2ggd2VubiBkYXMgMC0xIFhQIFZlcmx1c3QKICAgICAgLy9kdXJjaCBmbG9hdC0+aW50LUtvbnZlcnNpb24gZ2lidC4gKGNlaWwoKSBsb2hudCBzaWNoIElNSE8gbmljaHQuKQogICAgICBleCA9IChpbnQpKGV4cF90b19naXZlKigoZmxvYXQpZGFtYWdlLyhmbG9hdCl0b3RhbF9kYW1hZ2UpKTsKICAgICAgb2ItPkFkZEV4cChleCk7CiAgICB9CiAgfQp9CgovKgogKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBmcm9tIG90aGVyIHBsYXllcnMgd2hlbiB0aGV5IHdhbnQgdG8gbWFrZQogKiBkYW1hZ2UgdG8gdXMuIEJ1dCBpdCB3aWxsIG9ubHkgYmUgY2FsbGVkIGluZGlyZWN0bHkuCiAqIFdlIHJldHVybiBob3cgbXVjaCBkYW1hZ2Ugd2UgcmVjZWl2ZWQsIHdoaWNoIHdpbGwKICogY2hhbmdlIHRoZSBhdHRhY2tlcnMgc2NvcmUuIFRoaXMgcm91dGluZSBpcyBwcm9iYWJseSBjYWxsZWQgZnJvbQogKiBoZWFydF9iZWF0KCkgZnJvbSBhbm90aGVyIHBsYXllci4KICogQ29tcGFyZSB0aGlzIGZ1bmN0aW9uIHRvIHJlZHVjZV9oaXRfcG9pbnRzKGRhbSkuCiAqLwpwdWJsaWMgaW50IGRvX2RhbWFnZShpbnQgZGFtLCBvYmplY3QgZW5lbXkpCnsgaW50IGhpdF9wb2ludCxhbCxhbDI7CgogIGlmICggZXh0ZXJuX2NhbGwoKQogICAgICAmJiBvYmplY3RwKGVuZW15KQogICAgICAmJiBsaXZpbmcoZW5lbXkpCiAgICAgICYmICFRdWVyeVByb3AoUF9FTkFCTEVfSU5fQVRUQUNLX09VVCkpCiAgewogICAgYWw9dGltZSgpLWVuZW15LT5RdWVyeVByb3AoUF9MQVNUX01PVkUpOwogICAgaWYgKGFsPDMpICAgICAgLy8gRXJzdGUgS2FtcGZydW5kZSBuYWNoIEJldHJldGVuIGRlcyBSYXVtZXM/CiAgICAgIGRhbS89KDQtYWwpOyAvLyBHZWdlbiBSZWluLUZldWVyYmFsbC1SYXVzLVRha3RpawogIH0KCiAgaWYgKCBRdWVyeVByb3AoUF9HSE9TVCkgfHwgUXVlcnlQcm9wKFBfTk9fQVRUQUNLKSB8fCAoZGFtPD0wKQogICAgICB8fCAoIG9iamVjdHAoZW5lbXkpCiAgICAgICAgICAmJiAoIGVuZW15LT5RdWVyeVByb3AoUF9HSE9TVCkKICAgICAgICAgICAgICB8fCBlbmVteS0+UXVlcnlQcm9wKFBfTk9fQVRUQUNLKSApICkgKQogICAgcmV0dXJuIDA7CgogIGhpdF9wb2ludCA9IFF1ZXJ5UHJvcChQX0hQKS1kYW07CgogIGlmICggUXVlcnlQcm9wKFBfWFApICYmIG9iamVjdHAoZW5lbXkpICkKICB7CiAgICBpZiAoICFRdWVyeVByb3AoUF9OT19YUCkgKQogICAgICBlbmVteS0+QWRkRXhwKGRhbSooaW50KVF1ZXJ5UHJvcChQX1RPVEFMX1dDKS8xMCk7CiAgfQoKICBpZiAobGl2aW5nKGVuZW15KSkgewogICAgICBzdHJpbmcgZW5uYW1lID0gb2JqZWN0X25hbWUoZW5lbXkpOwogICAgICAvLyBIbXBmLiBCbHVlcHJpbnRzIHNpbmQgZG9vZi4gRGllIENoYW5jZSBpc3QgendhciBnZXJpbmcsIGFiZXIga29lbm50ZQogICAgICAvLyBzZWluLCBkYXNzIGVpbiBVbmlxdWUtTlBDIG1pdCB6d2VpIHZlcnNjaGllZGVuZW4gU3BpZWxlcm4gYW0gZ2xlaWNoZW4KICAgICAgLy8gTlBDIG1ldHplbHQuCiAgICAgIC8vIFRPRE86IE1IbW0uIHdpZSBncm9zcyBpc3QgZGFzIFJpc2lrbyB3aXJrbGljaD8KICAgICAgLy9pZiAoIWNsb25lcChlbmVteSkpCiAgICAgIC8vICAgIGVubmFtZSA9IGVubmFtZSArICJfIiArIHRvX3N0cmluZyhvYmplY3RfdGltZShlbmVteSkpOwogICAgICAvLyBudXIgd2VubiBnZWduZXIgTlBDIGlzdCB1bmQgbm9jaCBuaWNodCBkcmluc3RlaHQ6IERhdGVuIGF1cwogICAgICAvLyBQX0hFTFBFUl9OUEMgYXVzd2VydGVuCiAgICAgIGlmICghbWVtYmVyKGVuZW15X2RhbWFnZSxlbmVteSkgJiYgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoZW5lbXkpKSB7CiAgICAgICAgICBtaXhlZCBoZWxwZXIgPSBlbmVteS0+UXVlcnlQcm9wKFBfSEVMUEVSX05QQyk7CiAgICAgICAgICBpZiAocG9pbnRlcnAoaGVscGVyKSAmJiBvYmplY3RwKGhlbHBlclswXSkpCiAgICAgICAgICAgICAgZW5lbXlfZGFtYWdlW2VubmFtZSwxXSA9IGhlbHBlclswXTsKICAgICAgfQogICAgICBlbmVteV9kYW1hZ2VbZW5uYW1lLDBdKz1kYW07CiAgfQoKICBTZXRQcm9wKFBfSFAsIGhpdF9wb2ludCk7CgogIGlmICggaGl0X3BvaW50PDAgKQogIHsKICAgIC8vVE9ETzogV2FydW0gbmljaHQgZGFzIGdhbnplIFpldWcgaW5zIGRpZSgpIHZlcmxlZ2VuPwogICAgaWYgKCBlbmVteSApCiAgICB7CiAgICAgIGVuZW15LT5TdG9wSHVudEZvcihNRSwxKTsKICAgICAgaWYgKCAhUXVlcnlQcm9wKFBfTk9fWFApICkKICAgICAgICBEaXN0cmlidXRlRXhwKGVuZW15LFF1ZXJ5UHJvcChQX1hQKS8xMDApOwogICAgICBpZiAoICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApCiAgICAgICAgbG9nX2ZpbGUgKCJOUENfWFAiLCBzcHJpbnRmKAoJICAgICJbJXNdICVzLCBYUDogJWQsIEhQKldDOiAlZCwgS2lsbGVyOiAlc1xuIiwKCSAgICBkdGltZSh0aW1lKCkpLCBvYmplY3RfbmFtZShNRSksIChRdWVyeVByb3AoUF9YUCkvMTAwKSwKICAgICAgICAgICAgICAgICAgUXVlcnlQcm9wKFBfVE9UQUxfV0MpKlF1ZXJ5UHJvcChQX01BWF9IUCkvMTAsCiAgICAgICAgICAgICAgICAgIGVuZW15LT5uYW1lKCl8fCJOb05hbWUiICkpOwogICAgICBhbCA9IFF1ZXJ5UHJvcChQX0FMSUdOKS81MCArIGVuZW15LT5RdWVyeVByb3AoUF9BTElHTikvMjAwOwogICAgICBpZiAoYWw+MjApCiAgICAgICAgYWw9MjA7CiAgICAgIGVsc2UgaWYoYWw8LTIwKQogICAgICAgIGFsPS0yMDsKICAgICAgZW5lbXktPlNldFByb3AoUF9BTElHTixlbmVteS0+UXVlcnlQcm9wKFBfQUxJR04pLWFsKTsKICAgIH0KICAgIFNldFByb3AoUF9LSUxMRVIsIGVuZW15KTsKICAgIAogICAgZGllKCk7CiAgfQogIHJldHVybiBkYW07Cn0KCgpwcml2YXRlIHZvaWQgX3RyYW5zZmVyKCBvYmplY3QgKm9icywgc3RyaW5nfG9iamVjdCBkZXN0LCBpbnQgZmxhZyApCnsgICBpbnQgaTsKCiAgICBpID0gc2l6ZW9mKG9icyk7CgogICAgLy8gRWluZSBTY2hsZWlmZSBpc3QgendhciBsYW5nc2FtZXIgYWxzIGZpbHRlcigpIG8uYWUuLCBhYmVyCiAgICAvLyBzZWxic3QgbWl0IGVpbmVyIG5vY2ggc28gc2NobmVsbGVuIExvZXN1bmcga2FubiBsZWlkZXIgbmljaHQKICAgIC8vIGF1c2dlc2NobG9zc2VuIHdlcmRlbiwgZGFzcyBpcmdlbmR3byBlaW4gdG9vLWxvbmctZXZhbC1CdWcgZGF6d2lzY2hlbgogICAgLy8ga29tbXQuIERhenUgc2luZCBkaWUgS2FlbXBmZSBtaXQgR2lsZGVuLU5QQ3MgZXRjLiBlaW5mYWNoIHp1IHRldWVyIC4uLgogICAgLy8gUHJ1ZWZ1bmcgYXVmIHplcnN0b2VydGUgT2JqZWt0ZSwgZGEgZWluaWdlIHNpY2ggZXZ0bC4gaW0gTm90aWZ5UGxheWVyRGVhdGgoKSAKICAgIC8vIHplcnN0b2VyZW4uCiAgIHdoaWxlICggaSAmJiBnZXRfZXZhbF9jb3N0KCkgPiAzMDAwMDAgKQogICAgICAgIGlmICggb2JqZWN0cChvYnNbLS1pXSkgJiYgIW9ic1tpXS0+UXVlcnlQcm9wKFBfTkVWRVJEUk9QKSApCiAgICAgICAgLy8gSmV0enQgd2lyZCdzIG5vY2ggZXR3YXMgdGV1cmVyIG1pdCBjYXRjaCgpIC0gYWJlciBtYW5jaGUgU2FjaGVuCiAgICAgICAgLy8gZHVlcmZlbiBlaW5mYWNoIG5pY2h0IGJ1Z2dlbgogICAgICAgICAgICBjYXRjaCggb2JzW2ldLT5tb3ZlKCBkZXN0LCBmbGFnICk7cHVibGlzaCApOwoKICAgIGlmICggaSA+IDAgKQogICAgICAgIC8vIFp1dmllbCBSZWNoZW56ZWl0IHZlcmJyYXRlbiwgZXMgbXVlc3NlbiBub2NoIE9iamVrdGUgYmV3ZWd0IHdlcmRlbgogICAgICAgIGNhbGxfb3V0KCAjJ190cmFuc2ZlciwgMCwgb2JzWzAuLmktMV0sIGRlc3QsIGZsYWcgKTsKICAgIGVsc2UgewogICAgICAgIGlmICggcmVtb3ZlX21lICkKICAgICAgICAgICAgcmVtb3ZlKCk7CiAgICB9Cn0KCgpwdWJsaWMgdmFyYXJncyB2b2lkIHRyYW5zZmVyX2FsbF90byggc3RyaW5nfG9iamVjdCBkZXN0LCBpbnQgaXNucGMgKSB7CiAgICBpbnQgZmxhZ3M7CiAgICBvYmplY3QgKm9iczsKCiAgICBpZiAoICFvYmplY3RwKE1FKSApCiAgICAgICAgcmV0dXJuOwoKICAgIC8vIERhcyBGbGFnICJpc25wYyIgaXN0IGZ1ZXIgTlBDcyBnZWRhY2h0LiBEZXJlbiBBdXNydWVzdHVuZyBkYXJmIG5pY2h0CiAgICAvLyBtaXQgTV9OT0NIRUNLIGJld2VndCB3ZXJkZW4sIGRhIFNwaWVsZXIgZGFzIGJlaSBOaWNodC1TdGFuZGFyZC1MZWljaGVuCiAgICAvLyBzb25zdCB1LlUuIGF1c251dHplbiBrb2VubnRlbi4KICAgIGlmICggaXNucGMgKQogICAgICAgIGZsYWdzID0gTV9TSUxFTlQ7CiAgICBlbHNlCiAgICAgICAgZmxhZ3MgPSBNX1NJTEVOVHxNX05PQ0hFQ0s7CgogICAgb2JzID0gYWxsX2ludmVudG9yeShNRSkgfHwgKHt9KTsKCiAgICAvLyB1bm5vZXRpZywgd2VpbCBfdHJhbnNmZXIoKSBhdWNoIGF1ZiBQX05FVkVSRFJPUCBwcnVlZnQuIFplc3N0cmEKICAgIC8vb2JzIC09IGZpbHRlcl9vYmplY3RzKCBvYnMsICJRdWVyeVByb3AiLCBQX05FVkVSRFJPUCApOwoKICAgIF90cmFuc2Zlciggb2JzLCBkZXN0LCBmbGFncyApOwp9CgoKcHJvdGVjdGVkIHZhcmFyZ3Mgdm9pZCBjcmVhdGVfa2lsbF9sb2dfZW50cnkoc3RyaW5nIGtpbGxlciwgb2JqZWN0IGVuZW15KSB7CiAgaW50IGxldmVsLGxvc3RfZXhwOwoKICBpZiAoIChsZXZlbD1RdWVyeVByb3AoUF9MRVZFTCkpPDIwIHx8ICFJU19TRUVSKE1FKSApCiAgICBsb3N0X2V4cCA9IFF1ZXJ5UHJvcChQX1hQKS8zOwogIGVsc2UKICAgIGxvc3RfZXhwID0gUXVlcnlQcm9wKFBfWFApLyhsZXZlbC0xNyk7CiAgCiAgbG9nX2ZpbGUoIktJTExTIixzcHJpbnRmKCIlcyAlcyAoJWQsJWQpICVzXG4iLCBzdHJmdGltZSgiJWUgJWIgJUg6JU0iKSwKICAgICAgICAgICAgICAgY2FwaXRhbGl6ZShSRUFMX1VJRChNRSkpLCBsZXZlbCwgbG9zdF9leHAvMTAwMCwga2lsbGVyKSk7IAp9CgovLyBMaWVmZXJ0IGltIFRvZCAobmFjaCBkZW0gdG9ldGVuZGVuIGRvX2RhbWFnZSgpKSBkYXMgU3BpZWxlcm9iamVrdCwgd2FzIGRlbgovLyBUb2Qgd29obCB6dSB2ZXJhbnR3b3J0ZW4gaGF0LCBmYWxscyBlcyBlcm1pdHRlbHQgd2VyZGVuIGthbm4uIEVzIHdlcmRlbiB2b3IKLy8gYWxsZW0gcmVnaXN0cmllcnRlIEhlbGZlci1OUEMgdW5kIGVpbmlnZSBTb25kZXJvYmpla3RlIGJlcnVlY2tzaWNodGlndC4KcHJvdGVjdGVkIG9iamVjdCBnZXRfa2lsbGluZ19wbGF5ZXIoKQp7CiAgb2JqZWN0IGtpbGxlcj1RdWVyeVByb3AoUF9LSUxMRVIpOwogIC8vIGtvZW5udGUgc2Vpbiwgd2VubiBhdXNzZXJoYWxiIGRlcyBUb2RlcyBnZXJ1ZmVuIG9kZXIgZWluZSBWZXJnaWZ0dW5nIHVucwogIC8vIHVtZ2VicmFjaHQgaGF0LgogIGlmICghb2JqZWN0cChraWxsZXIpKQogICAgcmV0dXJuIDA7CgogIHdoaWxlIChraWxsZXIgJiYgIXF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoa2lsbGVyKSkKICAgIGtpbGxlciA9IGtpbGxlci0+UXVlcnlVc2VyKCk7CgogIHJldHVybiBraWxsZXI7Cn0KCnByb3RlY3RlZCBvYmplY3QgR2l2ZUtpbGxTY29yZShvYmplY3QgcGwsIGludCBucGNudW0pCnsKICAvLyBTdHVmZW5wdW5rdCBmdWVyIGRlbiBLaWxsIHZlcmdlYmVuLgogIC8vIEZhbGxzIGRlciBLaWxsZXIgZGVuIFB1bmt0IHNjaG9uIGhhdCwgd2lyZAogIC8vIHp1ZmFlbGxpZyBlaW4gTWl0Z2xpZWQgc2VpbmVzIFRlYW1zIGF1c2dld2FlaGx0CiAgLy8gdW5kIGRpZXNlbSBkZXIgUHVua3QgZ2VnZWJlbi4KICBvYmplY3QgKm9icyxvYjsKICBtaXhlZCAqZnI7CiAgaW50IGksaixzejsKCiAgaWYgKCBwb2ludGVycChvYnM9cGwtPlRlYW1NZW1iZXJzKCkpICYmIChtZW1iZXIob2JzLHBsKT49MCkgKQogIHsKICAgIGlmICggIXBvaW50ZXJwKGZyPXBsLT5QcmVzZW50VGVhbVJvd3MoKSkKICAgICAgICB8fCAhc2l6ZW9mKGZyKQogICAgICAgIHx8ICFwb2ludGVycChmcj1mclswXSkpIC8vIEVyc3RlIFJlaWhlIGRlcyBUZWFtcwogICAgICBmcj0oe30pOwogICAgZnItPSh7cGwsMH0pOwogICAgb2JzLT0oe3BsLDB9KTsKICAgIG9icy09ZnI7CiAgICBpPXN6PXNpemVvZihvYnMpOyAvLyByZXN0bGljaGUgVGVhbW1pdGdsaWVkZXIgaW4genVmYWVsbGlnZXIgUmVpaGVuZm9sZ2U6CiAgICBmb3IgKCAtLWkgOyBpPj0wIDsgaS0tICkKICAgIHsKICAgICAgaj1yYW5kb20oc3opOwogICAgICBvYj1vYnNbal07CiAgICAgIG9ic1tqXT1vYnNbMF07CiAgICAgIG9ic1swXT1vYjsKICAgIH0KICAgIGk9c3o9c2l6ZW9mKGZyKTsgIC8vIEVyc3RlIFJlaWhlIGluIHp1ZmFlbGxpZ2VyIFJlaWhlbmZvbGdlOgogICAgZm9yICggLS1pIDsgaT49MCA7IGktLSApCiAgICB7CiAgICAgIGo9cmFuZG9tKHN6KTsKICAgICAgb2I9ZnJbal07CiAgICAgIGZyW2pdPWZyWzBdOwogICAgICBmclswXT1vYjsKICAgIH0KCiAgICBvYnMrPWZyOyAgICAgLy8gRXJzdGUgUmVpaGUgd2lyZCB2b3IgUmVzdCBnZXRlc3RldAogICAgb2JzKz0oe3BsfSk7IC8vIEtpbGxlciB3aXJkIGFscyBlcnN0ZXMgZ2V0ZXN0ZXQKICB9CiAgZWxzZQogIHsKICAgIG9icz0oe3BsfSk7CiAgfQogIGZvciAoIGk9c2l6ZW9mKG9icyktMSA7IGk+PTAgOyBpLS0gKQogICAgaWYgKCBvYmplY3RwKG9iPW9ic1tpXSApCiAgICAgICAgJiYgaW50ZXJhY3RpdmUob2IpICAgICAvLyBOdXIgbmV0enRvdCBkYWJlaSBzdGVoZW4gZ2lsdCBuaWNodCA6KQogICAgICAgICYmIHF1ZXJ5X2lkbGUob2IpPDYwMCAgLy8gZ2VnZW4gTGV1dGUgZGllIHNpY2ggbnVyIG1pdHNjaGxlcHBlbiBsYXNzZW4KICAgICAgICAmJiBlbnZpcm9ubWVudChvYik9PWVudmlyb25tZW50KHBsKSAvLyBOdXIgYW53ZXNlbmRlIFRlYW1taXRnbGllZGVyCiAgICAgICAgJiYgIUlTX0xFQVJORVIob2IpCi8vICAgICAgICAmJiAhb2ItPlF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpCiAgICAgICAgJiYgIShTQ09SRU1BU1RFUi0+SGFzS2lsbChvYixNRSkpICkKICAgICAgcmV0dXJuIFNDT1JFTUFTVEVSLT5HaXZlS2lsbChvYixucGNudW0pLG9iOwoKICByZXR1cm4gU0NPUkVNQVNURVItPkdpdmVLaWxsKHBsLG5wY251bSkscGw7Cn0KCi8vIHp1bSB1ZWJlcnNjaHJlaWJlbiBpbiBTcGllbGVybgpwdWJsaWMgaW50IGRlYXRoX3N1ZmZlcmluZygpIHsKICByZXR1cm4gMDsgLy8gTlBDIGhhYmVuIGtlaW5lIFRvZGVzZm9sZ2VuCn0KCi8vIGtlaW4gMi4gTGViZW4gZnVlciBOaWNodC1TcGllbGVyLiA7LSkKdmFyYXJncyBwcm90ZWN0ZWQgaW50IHNlY29uZF9saWZlKCBvYmplY3QgY29ycHNlICkgewogICAgcmV0dXJuIDA7Cn0KCnB1YmxpYyB2YXJhcmdzIHZvaWQgZGllKCBpbnQgcG9pc29uZGVhdGgsIGludCBleHRlcm4gKQp7ICAgb2JqZWN0IGNvcnBzZTsKICAgIHN0cmluZyBkaWVfbXNnLCB0bXA7CiAgICBtaXhlZCByZXM7CiAgICBtaXhlZCBob29rRGF0YTsKICAgIG1peGVkIGhvb2tSZXM7CgogICAgaWYgKCAhb2JqZWN0cCh0aGlzX29iamVjdCgpKSB8fCBRdWVyeVByb3AoUF9HSE9TVCkgKQogICAgICAgIHJldHVybjsgLy8gR2hvc3RzIGRvbnQgZGllIC4uLgoKICAgIC8vIGRpcmVrdCB2b24gZXh0ZXJuIGF1ZmdlcnVmZW4gdW5kIG5pY2h0IHVlYmVyIGhlYXJ0X2JlYXQoKSBvZGVyCiAgICAvLyBkb19kYW1hZ2UoKSBoaWVyaGVyIGdlbGFuZ3Q/CiAgICBpZiAoZXh0ZXJuX2NhbGwoKSAmJiBwcmV2aW91c19vYmplY3QoKSAhPSB0aGlzX29iamVjdCgpKSB7CiAgICAgIGV4dGVybj0xOwogICAgICBTZXRQcm9wKFBfS0lMTEVSLCBwcmV2aW91c19vYmplY3QoKSk7CiAgICB9CgogICAgaWYgKCByZXMgPSBRdWVyeVByb3AoUF9UTVBfRElFX0hPT0spICl7CiAgICAgICAgaWYgKCBwb2ludGVycChyZXMpICYmIHNpemVvZihyZXMpPj0zCiAgICAgICAgICAgICYmIGludHAocmVzWzBdKSAmJiB0aW1lKCk8cmVzWzBdCiAgICAgICAgICAgICYmIG9iamVjdHAocmVzWzFdKSAmJiBzdHJpbmdwKHJlc1syXSkgKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCByZXMgPSBjYWxsX290aGVyKCByZXNbMV0sIHJlc1syXSwgcG9pc29uZGVhdGggKSApIHsKICAgICAgICAgICAgICBTZXRQcm9wKFBfS0lMTEVSLDApOwogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIFNldFByb3AoUF9UTVBfRElFX0hPT0ssMCk7CiAgICB9CgogICAgLy8gdHJpZ2dlciBkaWUgaG9vawogICAgaG9va0RhdGE9cG9pc29uZGVhdGg7CiAgICBob29rUmVzPUhvb2tGbG93KEhfSE9PS19ESUUsaG9va0RhdGEpOwogICAgaWYgKHBvaW50ZXJwKGhvb2tSZXMpICYmIHNpemVvZihob29rUmVzKT5IX1JFVERBVEEpewogICAgICBpZihob29rUmVzW0hfUkVUQ09ERV09PUhfQ0FOQ0VMTEVEKSB7CiAgICAgICAgU2V0UHJvcChQX0tJTExFUiwwKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgZWxzZSBpZiAoaG9va1Jlc1tIX1JFVENPREVdPT1IX0FMVEVSRUQpCiAgICAgICAgICBwb2lzb25kZWF0aCA9IGhvb2tSZXNbSF9SRVREQVRBXTsKICAgIH0KCiAgICBpZiAoIElTX0xFQVJOSU5HKE1FKSAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApewogICAgICAgdGVsbF9vYmplY3QoIE1FLCAiU2VpIGZyb2ggZGFzcyBEdSB1bnN0ZXJibGljaCBiaXN0LCBzb25zdCB3YWVyZSBlcyAiCiAgICAgICAgICAgICAgICAgICAgICAgICJlYmVuIERlaW4gRW5kZSBnZXdlc2VuLlxuIik7CiAgICAgICBTZXRQcm9wKFBfS0lMTEVSLDApOwogICAgICAgcmV0dXJuOwogICAgfQoKICAgIC8vIEdlZ25lciBiZWZyaWVkZW4uCiAgICBtYXBfb2JqZWN0cyggUXVlcnlFbmVtaWVzKClbMF0sICJTdG9wSHVudEZvciIsIE1FLCAxICk7CiAgICBTdG9wSHVudGluZ01vZGUoMSk7CgogICAgLy8gRmFsbHMgZGllKCkgZGlyZWt0IGF1ZmdlcnVmZW4gd3VyZGUgdW5kIGRpZXMgZWluIFNwaWVsZXIgaXN0LCBtdXNzIGRhcwogICAgLy8gZGllKCkgbm9jaCBFaW50cmFlZ2UgaW4gL2xvZy9LSUxMUyB2aWEgY3JlYXRlX2tpbGxfbG9nX2VudHJ5IGJ6dy4gaW4KICAgIC8vIC9sb2cvS0lMTEVSIGVyc3RlbGxlbi4KICAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgJiYgZXh0ZXJuICkKICAgIHsKICAgICAgb2JqZWN0IGtpbGxlciA9IFF1ZXJ5UHJvcChQX0tJTExFUikgCiAgICAgICAgICAgICAgICAgICAgIHx8IHByZXZpb3VzX29iamVjdCgpIHx8IHRoaXNfaW50ZXJhY3RpdmUoKSB8fCB0aGlzX3BsYXllcigpOwogICAgICBpZiAoIGtpbGxlciAmJiAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShraWxsZXIpICkKICAgICAgewogICAgICAgICAgdG1wID0gZXhwbG9kZSggb2JqZWN0X25hbWUoa2lsbGVyKSwgIiMiKVswXSArICIgKGRpcmVrdCAhKSI7CgogICAgICAgICAgY3JlYXRlX2tpbGxfbG9nX2VudHJ5KCB0bXAgKyAiICgiICsgUkVBTF9VSUQoa2lsbGVyKSArICIpIiwga2lsbGVyICk7CiAgICAgIH0KICAgICAgZWxzZSBpZiAoIGtpbGxlciAmJiAhUXVlcnlQcm9wKFBfVEVTVFBMQVlFUikgJiYgIUlTX0xFQVJORVIoTUUpICkKICAgICAgewogICAgICAgICAgbG9nX2ZpbGUoICJLSUxMRVIiLCBzcHJpbnRmKCAiJXMgJXMgKCVkLyVkKSB0b2V0ZXRlICVzICglZC8lZClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN0aW1lKHRpbWUoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKGtpbGxlcikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdWVyeV93aXpfbGV2ZWwoa2lsbGVyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2lsbGVyLT5RdWVyeVByb3AoUF9MRVZFTCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhcGl0YWxpemUoZ2V0dWlkKE1FKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXJ5X3dpel9sZXZlbChNRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFF1ZXJ5UHJvcChQX0xFVkVMKSApICk7CgogICAgICAgICAga2lsbGVyLT5TZXRQcm9wKCBQX0tJTExTLCAtMSApOwogICAgICB9CiAgICB9CgogIC8vIEJlaSBOUEMgRUtzIHZlcmdlYmVuIHVuZCBnZ2YuIGluIGRlciBHaWxkZSBkZXMgS2lsbGVycyB1bmQgaW0gUmF1bQogIC8vIE5QQ19LaWxsZWRfQnkoKSBydWZlbi4KICBpZiAoICFxdWVyeV9vbmNlX2ludGVyYWN0aXZlKE1FKSApCiAgewogICAgb2JqZWN0IGtpbGxlciA9ICgob2JqZWN0KSBRdWVyeVByb3AoUF9LSUxMRVIpKSB8fCBwcmV2aW91c19vYmplY3QoKSB8fAogICAgICB0aGlzX2ludGVyYWN0aXZlKCkgfHwgdGhpc19wbGF5ZXIoKTsKCiAgICBpZiAoIGtpbGxlciAmJiBxdWVyeV9vbmNlX2ludGVyYWN0aXZlKGtpbGxlcikgKQogICAgewogICAgICBpZiAoc3RyaW5ncChyZXM9a2lsbGVyLT5RdWVyeVByb3AoUF9HVUlMRCkpCiAgICAgICAgICAmJiBvYmplY3RwKHJlcz1maW5kX29iamVjdCgiL2dpbGRlbi8iK3JlcykpKQogICAgICAgIHJlcy0+TlBDX0tpbGxlZF9CeShraWxsZXIpOwoKICAgICAgaWYgKGVudmlyb25tZW50KCkpCiAgICAgICAgICBlbnZpcm9ubWVudCgpLT5OUENfS2lsbGVkX0J5KGtpbGxlcik7CgogICAgICByZXMgPSBRdWVyeVByb3AoUF9YUCk7CiAgICAgIHJlcyA9IChyZXMgPCBTQ09SRV9MT1dfTUFSSykgPyAwIDogKChyZXMgPiBTQ09SRV9ISUdIX01BUkspID8gMiA6IDEpOwogICAgICBpZiAoICFRdWVyeVByb3AoUF9OT19TQ09SRSkgJiYgIUlTX0xFQVJORVIoa2lsbGVyKSAmJgogICAgICAgICAgIC8vICFraWxsZXItPlF1ZXJ5UHJvcChQX1RFU1RQTEFZRVIpICYmCiAgICAgICAgICAgcG9pbnRlcnAoIHJlcyA9IFNDT1JFTUFTVEVSLT5RdWVyeU5QQyhyZXMpKSApCiAgICAgICAgR2l2ZUtpbGxTY29yZSgga2lsbGVyLCByZXNbMF0gKTsKICAgIH0KICB9CgogIGlmKCAhKGRpZV9tc2cgPSBRdWVyeVByb3AoUF9ESUVfTVNHKSkgKQogICAgaWYgKFF1ZXJ5UHJvcChQX1BMVVJBTCkpCiAgICAgIGRpZV9tc2cgPSAiIGZhbGxlbiB0b3QgenUgQm9kZW4uXG4iOwogICAgZWxzZQogICAgICBkaWVfbXNnID0gIiBmYWVsbHQgdG90IHp1IEJvZGVuLlxuIjsKCiAgaWYgKCBwb2lzb25kZWF0aCApCiAgewogICAgICBTZXQoIFBfTEFTVF9EQU1UWVBFUywgKHsgRFRfUE9JU09OIH0pICk7CiAgICAgIFNldCggUF9MQVNUX0RBTVRJTUUsIHRpbWUoKSApOwogICAgICBTZXQoIFBfTEFTVF9EQU1BR0UsIDEgKTsKICAgICAgZGllX21zZyA9ICIgd2lyZCB2b24gR2lmdCBoaW53ZWdnZXJhZmZ0IHVuZCBraXBwdCB1bS5cbiI7CiAgfQoKICBzYXkoIGNhcGl0YWxpemUobmFtZShXRVIsMSkpICsgZGllX21zZyApOwoKICAvLyBXZW5uIGtlaW5lIExlaWNoZSwgZGFubiBLcmFtIGlucyBFbnYgbGVnZW4uCiAgaWYgKCBRdWVyeVByb3AoUF9OT0NPUlBTRSkgfHwgISh0bXAgPSBRdWVyeVByb3AoUF9DT1JQU0UpKQogICAgICB8fCBjYXRjaChjb3Jwc2UgPSBjbG9uZV9vYmplY3QodG1wKTtwdWJsaXNoKSAKICAgICAgfHwgIW9iamVjdHAoY29ycHNlKSApCiAgewogICAgICAvLyBNYWdpZXIgb2RlciBUZXN0c3BpZWxlciBiZWhhbHRlbiBpaHJlIEF1c3J1ZXN0dW5nLgogICAgICAvLyBTb25zdCBrYWVtZW4gdS5VLiBTcGllbGVyIGFuIE1hZ2llcnRvb2xzIGV0Yy4gaGVyYW4KICAgICAgaWYgKCAhKElTX0xFQVJORVIoTUUpIHx8ICh0bXAgPSBRdWVyeShQX1RFU1RQTEFZRVIpKSAmJgogICAgICAgICAgICAgKCFzdHJpbmdwKHRtcCkgfHwgSVNfTEVBUk5FUiggbG93ZXJfY2FzZSh0bXApICkpKSApCiAgICAgICAgICB0cmFuc2Zlcl9hbGxfdG8oIGVudmlyb25tZW50KCksIDAgKTsKICAgICAgZWxzZQogICAgICAgICAgLy8gQWJlciBzaWUgemllaGVuIHNpY2ggYXVzLgogICAgICAgICAgZmlsdGVyX29iamVjdHMoUXVlcnlQcm9wKFBfQVJNT1VSUyksIkRvVW53ZWFyIixNX05PQ0hFQ0ssMCk7CiAgfQogIGVsc2UKICAvLyBzb25zdCBpbiBkaWUgTGVpY2hlIGxlZ2VuLgogIHsKICAgICAgY29ycHNlLT5JZGVudGlmeShNRSk7CiAgICAgIGNvcnBzZS0+bW92ZSggZW52aXJvbm1lbnQoKSwgTV9OT0NIRUNLfE1fU0lMRU5UICk7CiAgICAgIC8vIE1hZ2llciBvZGVyIFRlc3RzcGllbGVyIGJlaGFsdGVuIGlocmUgQXVzcnVlc3R1bmcuCiAgICAgIC8vIFNvbnN0IGthZW1lbiB1LlUuIFNwaWVsZXIgYW4gTWFnaWVydG9vbHMgZXRjLiBoZXJhbgogICAgICBpZiAoICEoSVNfTEVBUk5FUihNRSkgfHwgKHRtcCA9IFF1ZXJ5KFBfVEVTVFBMQVlFUikpICYmCiAgICAgICAgICAgICAoIXN0cmluZ3AodG1wKSB8fCBJU19MRUFSTkVSKCBsb3dlcl9jYXNlKHRtcCkgKSkpICkKICAgICAgICAgIHRyYW5zZmVyX2FsbF90byggY29ycHNlLCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKTsKICAgICAgZWxzZQogICAgICAgICAgLy8gQWJlciBzaWUgemllaGVuIHNpY2ggYXVzLgogICAgICAgICAgZmlsdGVyX29iamVjdHMoUXVlcnlQcm9wKFBfQVJNT1VSUyksIkRvVW53ZWFyIixNX05PQ0hFQ0ssMCk7CiAgfQoKICBpZiAoIHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUoTUUpICkgewogICAgICBTZXQoIFBfREVBRFMsIFF1ZXJ5KFBfREVBRFMpICsgMSApOwogICAgICAvLyBTcGllbGVyLVRvZC1ldmVudCBhdXNsb2VzZW4KICAgICAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoRVZUX0xJQl9QTEFZRVJfREVBVEgsIChbCiAgICAgIEVfT0JKRUNUOiBNRSwgRV9QTE5BTUU6IGdldHVpZChNRSksCiAgICAgIEVfRU5WSVJPTk1FTlQ6IGVudmlyb25tZW50KCksIEVfVElNRTogdGltZSgpLAogICAgICBQX0tJTExFUjogUXVlcnlQcm9wKFBfS0lMTEVSKSwKICAgICAgUF9MQVNUX0RBTUFHRTogUXVlcnlQcm9wKFBfTEFTVF9EQU1BR0UpLAogICAgICBQX0xBU1RfREFNVFlQRVM6IGNvcHkoUXVlcnlQcm9wKFBfTEFTVF9EQU1UWVBFUykpLAogICAgICBFX0VYVEVSTkFMX0RFQVRIOiBleHRlcm4sCiAgICAgIEVfUE9JU09OX0RFQVRIOiBwb2lzb25kZWF0aCwgCiAgICAgIEVfQ09SUFNFOiAob2JqZWN0cChjb3Jwc2UpP2NvcnBzZTowKSBdKSApOwogIH0KICBlbHNlIHsKICAgICAgLy8gTlBDLVRvZGVzLUV2ZW50IGF1c2xvZXNlbi4gRGl2LiBNYXBwaW5ncy9BcnJheXMgd2VyZGVuIG5pY2h0IGtvcGllcnQsCiAgICAgIC8vIHdlaWwgZGVyIE5QQyBqYSBqZXR6dCBlaCB6ZXJzdG9lcnQgd2lyZC4KICAgICAgbWFwcGluZyBkYXRhID0gKFsKICAgICAgICAgICAgRV9PQk5BTUU6IG9iamVjdF9uYW1lKE1FKSwKICAgICAgICAgICAgRV9FTlZJUk9OTUVOVDogZW52aXJvbm1lbnQoKSwgRV9USU1FOiB0aW1lKCksCiAgICAgICAgICAgIFBfTkFNRTogUXVlcnlQcm9wKFBfTkFNRSksCiAgICAgICAgICAgIFBfS0lMTEVSOiBRdWVyeVByb3AoUF9LSUxMRVIpLAogICAgICAgICAgICBQX0VORU1ZX0RBTUFHRTogUXVlcnlQcm9wKFBfRU5FTVlfREFNQUdFKSwKICAgICAgICAgICAgUF9MQVNUX0RBTUFHRTogUXVlcnlQcm9wKFBfTEFTVF9EQU1BR0UpLAogICAgICAgICAgICBQX0xBU1RfREFNVFlQRVM6IFF1ZXJ5UHJvcChQX0xBU1RfREFNVFlQRVMpLAogICAgICAgICAgICBFX0VYVEVSTkFMX0RFQVRIOiBleHRlcm4sCiAgICAgICAgICAgIEVfUE9JU09OX0RFQVRIOiBwb2lzb25kZWF0aCwKICAgICAgICAgICAgRV9DT1JQU0U6IChvYmplY3RwKGNvcnBzZSk/Y29ycHNlOjApLAogICAgICAgICAgICBQX1hQOiBRdWVyeVByb3AoUF9YUCksCiAgICAgICAgICAgIFBfQVRUUklCVVRFUzogUXVlcnlQcm9wKFBfQVRUUklCVVRFUyksCiAgICAgICAgICAgIFBfTUFYX0hQOiBRdWVyeVByb3AoUF9NQVhfSFApLAogICAgICAgICAgICBQX0hBTkRTOiBRdWVyeVByb3AoUF9IQU5EUyksCiAgICAgICAgICAgIFBfQUxJR046IFF1ZXJ5UHJvcChQX0FMSUdOKSwKICAgICAgICAgICAgUF9SQUNFOiBRdWVyeVByb3AoUF9SQUNFKSwKICAgICAgICAgICAgUF9DTEFTUzogUXVlcnlQcm9wKFBfQ0xBU1MpLAogICAgICAgICAgICBdKTsKICAgICAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoRVZUX0xJQl9OUENfREVBVEgoIiIpLCBkYXRhKTsKICAgICAgRVZFTlRELT5UcmlnZ2VyRXZlbnQoCiAgICAgICAgICBFVlRfTElCX05QQ19ERUFUSChsb2FkX25hbWUoTUUpKSwgZGF0YSk7CiAgfQoKICAvLyB0cmFuc2Zlcl9hbGxfdG8oKSBpc3QgZXZ0bC4gKHdlbm4genV2aWVsZSBPYmpla3RlIGJld2VndCB3ZXJkZW4gbXVzc3RlbikKICAvLyBub2NoIG5pY2h0IGdhbnogZmVydGlnIHVuZCB3aXJkIHBlciBjYWxsX291dCgpIGRlbiBSZXN0IGVybGVkaWdlbi4KICAvLyBTb2xsdGUgZGllIExlaWNoZSBkYW5uIG5pY2h0IG1laHIgZXhpc3RpZXJlbiwgdmVyYmxlaWJlbiBkaWUgcmVzdGxpY2hlbgogIC8vIE9iamVrdGUgaW0gU3BpZWxlci4KICAvLyBFcyBibGVpYmVuIGFiZXIgYXVmIGplZGVuIEZhbGwgbm9jaCBydW5kIDMwMGsgRXZhbC1UaWNrcyB1ZWJlciwgZGFtaXQKICAvLyBrZWluIFNwaWVsZXIgZGFuayAiZXZhbGNvc3QgdG9vIGhpZ2giIHVuZ2VzY2hvcmVuIGRhdm9uIGtvbW10LgogIGlmICggIShzZWNvbmRfbGlmZShjb3Jwc2UpKSApCiAgewogICAgICBTZXQoIFBfR0hPU1QsIDEgKTsgLy8gRnVlciBrb3JyZWt0ZSBBdXNnYWJlIGF1ZiBUZWFta2FuYWwuCgogICAgICBpZiAoIGZpbmRfY2FsbF9vdXQoIydfdHJhbnNmZXIpID09IC0xICkKICAgICAgICAgIC8vIEZhbGxzIGtlaW4gY2FsbF9vdXQoKSBtZWhyIGxhZXVmdCwgc29mb3J0IGRlc3RydWN0ZW4gLi4uCiAgICAgICAgICByZW1vdmUoKTsKICAgICAgZWxzZQogICAgICAgICAgLy8gLi4uIGFuc29uc3RlbiB2b3JtZXJrZW4KICAgICAgICAgIHJlbW92ZV9tZSA9IDE7CiAgfQp9CgpwdWJsaWMgdm9pZCBoZWFsX3NlbGYoaW50IGgpCnsKICBpZiAoIGg8PTAgKQogICAgcmV0dXJuOwogIFNldFByb3AoUF9IUCwgUXVlcnlQcm9wKFBfSFApK2gpOwogIFNldFByb3AoUF9TUCwgUXVlcnlQcm9wKFBfU1ApK2gpOwp9CgoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLwovLyAgIGludCBkZWZ1ZWxfZm9vZCggLyogdm9pZCAqLyApCi8vCi8vICAgRW50dGFua3QgZGVuIFNwaWVsZXIgdW0gZWluZW4gZ2V3aXNzZW4gRXNzZW5zLVdlcnQuCi8vICAgU29sbHRlIG51ciB2b24gVG9pbGV0dGVuIGF1ZmdlcnVmZW4gd2VyZGVuLgovLwovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCnB1YmxpYyBpbnQgZGVmdWVsX2Zvb2QoKQp7CiAgaW50IGZvb2Q7CgogIGZvb2Q9UXVlcnlQcm9wKFBfRk9PRCk7CgovLyB3ZW5uIHNwaWVsZXIga2VpbiBmb29kIGhhdDogcmV0dXJuIDAKICBpZiAoICFmb29kICkKICAgcmV0dXJuIE5PX0RFRlVFTDsKCi8vIHdlbm4gc3BpZWxlciB1bnRlciBlbnR0YW5rLWdyZW56ZTogcmV0dXJuIC0xCiAgaWYgKCBmb29kIDwgUXVlcnlQcm9wKFBfREVGVUVMX0xJTUlUX0ZPT0QpICkKICAgcmV0dXJuIERFRlVFTF9UT09fTE9XOwoKLy8gd2VubiBsZXR6dGVzIGVudHRhbmtlbiBuaWNodCBsYW5nZSBnZW51ZyB6dXJ1ZWNrbGllZ3Q6IHJldHVybiAtMgogIGlmICggdGltZSgpIDwgbmV4dGRlZnVlbHRpbWVmb29kICkKICAgcmV0dXJuIERFRlVFTF9UT09fU09PTjsKCiAgZm9vZD10b19pbnQoKChmb29kKlF1ZXJ5UHJvcChQX0RFRlVFTF9BTU9VTlRfRk9PRCkpLzIpKTsKICBmb29kKz1yYW5kb20oZm9vZCk7CgovLyBzaWNoZXJoZWl0c2hhbGJlcgogIGlmICggZm9vZCA+IFF1ZXJ5UHJvcChQX0ZPT0QpICkKICAgZm9vZD1RdWVyeVByb3AoUF9GT09EKTsKCiAgU2V0UHJvcChQX0ZPT0QsKFF1ZXJ5UHJvcChQX0ZPT0QpLWZvb2QpKTsKCiAgbmV4dGRlZnVlbHRpbWVmb29kPXRpbWUoKStRdWVyeVByb3AoUF9ERUZVRUxfVElNRV9GT09EKTsKCiAgcmV0dXJuIGZvb2Q7Cn0KCgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vCi8vICAgaW50IGRlZnVlbF9kcmluayggLyogdm9pZCAqLyApCi8vCi8vICAgRW50dGFua3QgZGVuIFNwaWVsZXIgdW0gZWluZW4gZ2V3aXNzZW4gRmx1ZXNzaWdrZWl0cy1XZXJ0LgovLyAgIEdsZWljaHplaXRpZyB3aXJkIGVpbmUgZ2V3aXNzZSBNZW5nZSBBbGtvaG9sIHJlZHV6aWVydC4KLy8gICBTb2xsdGUgbnVyIHZvbiBUb2lsZXR0ZW4gYXVmZ2VydWZlbiB3ZXJkZW4uCi8vCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KcHVibGljIGludCBkZWZ1ZWxfZHJpbmsoKQp7CiAgaW50IGFsYywgZHJpbms7CgogIGRyaW5rPVF1ZXJ5UHJvcChQX0RSSU5LKTsKCi8vIHdlbm4gc3BpZWxlciBrZWluIGRyaW5rIGhhdDogcmV0dXJuIDAKICBpZiAoICFkcmluayApCiAgIHJldHVybiBOT19ERUZVRUw7CgovLyB3ZW5uIHNwaWVsZXIgdW50ZXIgZW50dGFuay1ncmVuemU6IHJldHVybiAtMQogIGlmICggZHJpbmsgPCBRdWVyeVByb3AoUF9ERUZVRUxfTElNSVRfRFJJTkspICkKICAgcmV0dXJuIERFRlVFTF9UT09fTE9XOwoKLy8gd2VubiBsZXR6dGVzIGVudHRhbmtlbiBuaWNodCBsYW5nZSBnZW51ZyB6dXJ1ZWNrbGllZ3Q6IHJldHVybiAtMgogIGlmICggdGltZSgpIDwgbmV4dGRlZnVlbHRpbWVkcmluayApCiAgIHJldHVybiBERUZVRUxfVE9PX1NPT047CiAgICAKICBkcmluaz10b19pbnQoKChkcmluaypRdWVyeVByb3AoUF9ERUZVRUxfQU1PVU5UX0RSSU5LKSkvMikpOwogIGRyaW5rKz1yYW5kb20oZHJpbmspOwoKLy8gc2ljaGVyaGVpdHNoYWxiZXIKICBpZiAoIGRyaW5rID4gUXVlcnlQcm9wKFBfRFJJTkspICkKICAgZHJpbms9UXVlcnlQcm9wKFBfRFJJTkspOwoKICBTZXRQcm9wKFBfRFJJTkssKFF1ZXJ5UHJvcChQX0RSSU5LKS1kcmluaykpOwoKLy8gamVkZXMgZmx1ZXNzaWdlIEVudHRhbmtlbiBtYWNodCBhdWNoIGV0d2FzIG51ZWNodGVybmVyIDpeKQovLyBiZWkgc2VociBrbGVpbmVuIE1lbmdlbiBlbnR0YW5rdCBtYW4ga2VpbmVuIEFsa29ob2wKLy8gYW5zb25zdGVuIGluIEFiaGFlbmdpZ2tlaXQgdm9uIGVudHRhbmt0ZXIgTWVuZ2UsIFBfQUxDT0hPTCB1bmQgUF9XRUlHSFQKCiAgaWYgKCBkcmluayA+IDkgJiYgUXVlcnlQcm9wKFBfQUxDT0hPTCkgPiAwICkKICAgewogICAgYWxjPSh0b19pbnQoZXhwKGxvZygxLjEpKihkcmluaykpKSoKICAgICAgICAgdG9faW50KGV4cChsb2coMC42NykqKFF1ZXJ5UHJvcChQX0FMQ09IT0wpKSkpKS8KICAgICAgICAgKFF1ZXJ5UHJvcChQX01BWF9EUklOSykqUXVlcnlQcm9wKFBfTUFYX0FMQ09IT0wpKSoKICAgICAgICAgKHRvX2ludChRdWVyeVByb3AoUF9XRUlHSFQpLzEwMDApKTsKCiAgICAgU2V0UHJvcChQX0FMQ09IT0wsUXVlcnlQcm9wKFBfQUxDT0hPTCktKGFsYytyYW5kb20oYWxjKSkpOwogICB9CgogIG5leHRkZWZ1ZWx0aW1lZHJpbms9dGltZSgpK1F1ZXJ5UHJvcChQX0RFRlVFTF9USU1FX0RSSU5LKTsKIAogIHJldHVybiBkcmluazsKfQoKCnB1YmxpYyB2b2lkIHJlZHVjZV9zcGVsbF9wb2ludHMoaW50IGgpCnsKICBTZXRQcm9wKFBfU1AsIFF1ZXJ5UHJvcChQX1NQKS1oKTsKfQoKcHVibGljIHZvaWQgcmVzdG9yZV9zcGVsbF9wb2ludHMoaW50IGgpCnsKICBTZXRQcm9wKFBfU1AsIFF1ZXJ5UHJvcChQX1NQKStoKTsKfQoKLyogUmVkdWNlIGhpdHBvaW50cy4gTG9nIHdobyBpcyBkb2luZyBpdC4gKi8KcHVibGljIGludCByZWR1Y2VfaGl0X3BvaW50cyhpbnQgZGFtKQp7IG9iamVjdCBvOwogIGludCBpOwoKI2lmZGVmIExPR19SRURVQ0VfSFAKICBpZiAodGhpc19wbGF5ZXIoKSE9TUUpCiAgewogICAgbG9nX2ZpbGUoIlJFRFVDRV9IUCIsIG5hbWUoKSsiIGJ5ICIpOwogICAgaWYoIXRoaXNfcGxheWVyKCkpIGxvZ19maWxlKCJSRURVQ0VfSFAiLCI/XG4iKTsKICAgIGVsc2UgewogICAgICBsb2dfZmlsZSgiUkVEVUNFX0hQIix0aGlzX3BsYXllcigpLT5uYW1lKCkpOwogICAgICBvPXByZXZpb3VzX29iamVjdCgpOwogICAgICBpZiAobykKICAgICAgICBsb2dfZmlsZSgiUkVEVUNFX0hQIiwgIiAiICsgb2JqZWN0X25hbWUobykgKyAiLCAiICsKICAgICAgICAgICAgICAgICBvLT5uYW1lKFdFUiwwKSArICIgKCIgKyBjcmVhdG9yKG8pICsgIilcbiIpOwogICAgICBlbHNlCiAgICAgICAgbG9nX2ZpbGUoIlJFRFVDRV9IUCIsICIgPz9cbiIpOwogICAgfQogIH0KI2VuZGlmCiAgaWYgKChpPVF1ZXJ5UHJvcChQX0hQKSkgPD0gZGFtKQogICAgcmV0dXJuIFNldFByb3AoUF9IUCwxKTsKICByZXR1cm4gU2V0UHJvcChQX0hQLCBpIC0gZGFtKTsKfQoKcHVibGljIGludCByZXN0b3JlX2hpdF9wb2ludHMoaW50IGhlYWwpCnsKICByZXR1cm4gcmVkdWNlX2hpdF9wb2ludHMoLWhlYWwpOwp9CgpwdWJsaWMgdmFyYXJncyBpbnQgZHJpbmtfYWxjb2hvbChpbnQgc3RyZW5ndGgsaW50IHRlc3Rvbmx5LCBzdHJpbmcgbXl0ZXh0KQp7IGludCBhbGMsYWRkLHJlczsKCiAgYWRkPUFMQ09IT0xfVkFMVUUoc3RyZW5ndGgpOwogIHJlcz1Vc2VTa2lsbChTS19CT09aRSwoWwogICAgICBTSV9TS0lMTEFSRyA6IGFkZCwKICAgICAgU0lfVEVTVEZMQUcgOiAxXSkpOyAvLyBLYW5uIGRlciBTcGllbGVyIGd1dCBzYXVmZW4/CiAgaWYgKGludHAocmVzKSAmJiByZXM+MCkgYWRkPXJlczsKICBhbGM9UXVlcnlQcm9wKFBfQUxDT0hPTCkrYWRkOwogIGlmICgoYWxjID49IFF1ZXJ5UHJvcChQX01BWF9BTENPSE9MKSkgJiYgIUlTX0xFQVJOSU5HKHRoaXNfb2JqZWN0KCkpKXsKICAgIGlmKCF0ZXN0b25seSkKICAgICAgdGVsbF9vYmplY3QoTUUsbXl0ZXh0fHwiU28gZWluIFBlY2gsIER1IGhhc3QgYWxsZXMgdmVyc2NodWV0dGV0LlxuIik7CiAgICByZXR1cm4gMDsKICB9CiAgaWYodGVzdG9ubHkpcmV0dXJuIDE7CiAgVXNlU2tpbGwoU0tfQk9PWkUsKFsgU0lfU0tJTExBUkcgOiBBTENPSE9MX1ZBTFVFKHN0cmVuZ3RoKSBdKSk7CiAgaWYoYWxjIDwgMCkgYWxjID0gMDsKICBpZighYWxjKSB0ZWxsX29iamVjdChNRSwgIkR1IGJpc3Qgc3RvY2tudWVjaHRlcm4uXG4iKTsKICBTZXRQcm9wKFBfQUxDT0hPTCwgYWxjKTsKICByZXR1cm4gMTsKfQoKcHVibGljIHZhcmFyZ3MgaW50IGRyaW5rX3NvZnQoaW50IHN0cmVuZ3RoLCBpbnQgdGVzdG9ubHksIHN0cmluZyBteXRleHQpCnsgaW50IHNvYWtlZDsKCiAgc29ha2VkID0gUXVlcnlQcm9wKFBfRFJJTkspOwogIGlmKChzb2FrZWQgKyBzdHJlbmd0aCA+IFF1ZXJ5UHJvcChQX01BWF9EUklOSykpICYmCiAgICAgIUlTX0xFQVJOSU5HKHRoaXNfb2JqZWN0KCkpKXsKICAgIGlmKCF0ZXN0b25seSkKICAgICB0ZWxsX29iamVjdChNRSwgbXl0ZXh0fHwKICAgICAgICJOZWUsIHNvIHZpZWwga2FubnN0IER1IG1vbWVudGFuIGVjaHQgbmljaHQgdHJpbmtlbi5cbiIgKTsKICAgIHJldHVybiAwOwogIH0KICBpZih0ZXN0b25seSlyZXR1cm4gMTsKICBpZigoc29ha2VkICs9IERSSU5LX1ZBTFVFKHN0cmVuZ3RoKSkgPCAwKSBzb2FrZWQgPSAwOwogIGlmKCFzb2FrZWQpIHRlbGxfb2JqZWN0KE1FLCAiRGlyIGtsZWJ0IGRpZSBadW5nZSBhbSBHYXVtZW4uXG4iKTsKICBTZXRQcm9wKFBfRFJJTkssIHNvYWtlZCk7CiAgcmV0dXJuIDE7Cn0KCnB1YmxpYyB2YXJhcmdzIGludCBlYXRfZm9vZChpbnQgc3RyZW5ndGgsIGludCB0ZXN0b25seSwgc3RyaW5nIG15dGV4dCkKeyBpbnQgc3R1ZmZlZDsKCiAgc3R1ZmZlZCA9IFF1ZXJ5UHJvcChQX0ZPT0QpOwogIGlmICgoc3R1ZmZlZCArIHN0cmVuZ3RoID4gUXVlcnlQcm9wKFBfTUFYX0ZPT0QpKSAmJgogICAgICAhSVNfTEVBUk5JTkcodGhpc19vYmplY3QoKSkpCiAgewogICAgaWYoIXRlc3Rvbmx5KQogICAgICAgIHRlbGxfb2JqZWN0KE1FLAogICAgICAgICAgICBteXRleHQgfHwgIkRhcyBpc3QgdmllbCB6dSB2aWVsIGZ1ZXIgRGljaCEgV2llIHdhZXJzIG1pdCBldHdhcyAiCiAgICAgICAgICAgICJsZWljaHRlcmVtP1xuIik7CiAgICByZXR1cm4gMDsKICB9CiAgaWYodGVzdG9ubHkpcmV0dXJuIDE7CiAgc3R1ZmZlZCArPSBGT09EX1ZBTFVFKHN0cmVuZ3RoKTsKICBpZihzdHVmZmVkIDwgMCkgc3R1ZmZlZCA9IDA7CiAgaWYoIXN0dWZmZWQpIHRlbGxfb2JqZWN0KE1FLCAiV2FzIHJ1bXBlbHQgZGVubiBkYSBpbiBEZWluZW0gQmF1Y2g/XG4iKTsKICBTZXRQcm9wKFBfRk9PRCwgc3R1ZmZlZCk7CiAgcmV0dXJuIDE7Cn0KCnB1YmxpYyBpbnQgYnVmZmVyX2hwKGludCB2YWwsaW50IHJhdGUpCnsKICBpbnQgZGlmOwoKICBpZih2YWw8PTAgfHwgcmF0ZTw9MClyZXR1cm4gMDsKICBpZih2YWwgPCByYXRlKXJhdGUgPSB2YWw7CiAgaWYocmF0ZT4yMCkgcmF0ZT0yMDsKCiAgLyogQ2hlY2sgZm9yIEJ1ZmZlck92ZXJmbG93ICovCiAgaWYoKGRpZj0oaHBfYnVmZmVyWzBdK3ZhbCktUXVlcnlQcm9wKFBfTUFYX0hQKSkgPiAwKXZhbC09ZGlmOwogIGlmKHZhbDw9MClyZXR1cm4gMDsKCiAgaHBfYnVmZmVyWzBdICs9IHZhbDsKICBocF9idWZmZXJbMStyYXRlXSArPSB2YWw7CiAgaWYocmF0ZSA+IGhwX2J1ZmZlclsxXSlocF9idWZmZXJbMV0gPSByYXRlOwoKICByZXR1cm4gaHBfYnVmZmVyWzBdOwp9CgpwdWJsaWMgaW50IGJ1ZmZlcl9zcChpbnQgdmFsLGludCByYXRlKQp7CiAgaW50IGRpZjsKCiAgaWYodmFsPD0wIHx8IHJhdGU8PTApcmV0dXJuIDA7CiAgaWYodmFsIDwgcmF0ZSlyYXRlID0gdmFsOwogIGlmKHJhdGU+MjApIHJhdGU9MjA7CgogIC8qIENoZWNrIGZvciBCdWZmZXJPdmVyZmxvdyAqLwogIGlmKChkaWY9KHNwX2J1ZmZlclswXSt2YWwpLVF1ZXJ5UHJvcChQX01BWF9TUCkpID4gMCl2YWwtPWRpZjsKICBpZih2YWw8PTApcmV0dXJuIDA7CgogIHNwX2J1ZmZlclswXSArPSB2YWw7CiAgc3BfYnVmZmVyWzErcmF0ZV0gKz0gdmFsOwogIGlmKHJhdGUgPiBzcF9idWZmZXJbMV0pc3BfYnVmZmVyWzFdID0gcmF0ZTsKCiAgcmV0dXJuIHNwX2J1ZmZlclswXTsKfQoKcHJvdGVjdGVkIHZvaWQgdXBkYXRlX2J1ZmZlcnMoKQp7IGludCBpLCByYXRlLCBtYXg7CgogIHJhdGU9MDsKICBtYXg9MDsKICBmb3IoaT0xO2k8PTIwO2krKyl7CiAgICBpZihtZW1iZXIoaHBfYnVmZmVyLCBpKzEpKQogICAgICBpZihocF9idWZmZXJbaSsxXTw9MCkKICAgICAgICBocF9idWZmZXIgPSBtX2RlbGV0ZShocF9idWZmZXIsaSsxKTsKICAgICAgZWxzZXsKICAgICAgICBtYXgrPWhwX2J1ZmZlcltpKzFdOwogICAgICAgIHJhdGU9aTsKICAgICAgfQogIH0KCiAgaHBfYnVmZmVyWzBdPW1heDsKICBocF9idWZmZXJbMV09cmF0ZTsKICByYXRlPTA7CiAgbWF4PTA7CiAgZm9yKGk9MTtpPD0yMDtpKyspewogICAgaWYobWVtYmVyKHNwX2J1ZmZlciwgaSsxKSkKICAgICAgaWYoc3BfYnVmZmVyW2krMV08PTApCiAgICAgICAgc3BfYnVmZmVyID0gbV9kZWxldGUoc3BfYnVmZmVyLGkrMSk7CiAgICAgIGVsc2V7CiAgICAgICAgbWF4Kz1zcF9idWZmZXJbaSsxXTsKICAgICAgICByYXRlPWk7CiAgICAgIH0KICB9CiAgc3BfYnVmZmVyWzBdPW1heDsKICBzcF9idWZmZXJbMV09cmF0ZTsKfQoKcHVibGljIGludCBjaGVja190aW1lZF9rZXkoc3RyaW5nIGtleSkgewoKICAvLyBrZWluZSAwIGFscyBrZXkgKFR5cCB3aXJkIHBlciBSVFRDIGdlcHJ1ZWZ0KQogIGlmICgha2V5KQogICAgcmV0dXJuIDA7CiAgbWFwcGluZyB0bWFwPVF1ZXJ5KFBfVElNSU5HX01BUCwgRl9WQUxVRSk7CiAgaWYgKCFtYXBwaW5ncCh0bWFwKSkgewogICAgdG1hcD0oW10pOwogICAgU2V0KFBfVElNSU5HX01BUCwgdG1hcCwgRl9WQUxVRSk7CiAgfQogIC8vIFdlbm4ga2V5IG5vY2ggbmljaHQgYWJnZWxhdWZlbiwgQWJsYXVmemVpdHB1bmt0IHp1cnVlY2tnZWJlbi4KICAvLyBTb25zdCAwIChrZXkgZnJlaSkKICByZXR1cm4gKHRpbWUoKSA8IHRtYXBba2V5XSkgJiYgdG1hcFtrZXldOwp9CgpwdWJsaWMgaW50IGNoZWNrX2FuZF91cGRhdGVfdGltZWRfa2V5KGludCBkdXJhdGlvbixzdHJpbmcga2V5KSB7CgogIC8vIHdlbm4ga2V5IG5vY2ggZ2VzcGVycnQsIGRpZSB6ZWl0IGRlciBuYWVjaHN0ZW4gVmVyZnVlZ2JhcmtlaXQKICAvLyB6dXJ1ZWNrZ2ViZW4uCiAgaW50IHJlcyA9IGNoZWNrX3RpbWVkX2tleShrZXkpOwogIGlmIChyZXMpIHsKICAgIHJldHVybiByZXM7CiAgfQoKICAvLyBkdXJhdGlvbiA8PSAwIGlzdCB1bnNpbm5pZy4gQWJlciBrZXkgaXN0IG5pY2h0IG1laHIgZ2VzcGVycnQsIGQuaC4gdGltZSgpCiAgLy8gaXN0IGVpbiBzaW5udm9sbGVyIFJ1ZWNrZ2FiZXdlcnQuCiAgaWYgKGR1cmF0aW9uIDw9IDApCiAgICByZXR1cm4gdGltZSgpOwogCiAgbWFwcGluZyB0bWFwID0gUXVlcnkoUF9USU1JTkdfTUFQLEZfVkFMVUUpOwogIHRtYXBba2V5XT10aW1lKCkrZHVyYXRpb247CiAgCiAgLy8gc3BlaWNoZXJuIHBlciBTZXRQcm9wKCkgdW5ub2V0aWcsIGRhIG1hbiBkYXMgTWFwcGluZyBkaXJla3QgYWVuZGVydCwKICAvLyBrZWluZSBLb3BpZS4KICAvL1NldFByb3AoUF9USU1JTkdfTUFQLCB0bWFwKTsKICAKICByZXR1cm4gLTE7IC8vIEVyZm9sZy4KfQoKcHJvdGVjdGVkIHZvaWQgZXhwaXJlX3RpbWluZ19tYXAoKSB7CiAgCiAgbWFwcGluZyB0bWFwID0gUXVlcnkoUF9USU1JTkdfTUFQLCBGX1ZBTFVFKTsKICBpZiAoIW1hcHBpbmdwKHRtYXApIHx8ICFzaXplb2YodG1hcCkpCiAgICByZXR1cm47CiAgZm9yZWFjaChzdHJpbmcga2V5LCBpbnQgZW5kdGltZTogdG1hcCkgewogICAgaWYgKGVuZHRpbWUgPCB0aW1lKCkpCiAgICAgIG1fZGVsZXRlKHRtYXAsIGtleSk7CiAgfQogIC8vIHNwZWljaGVybiBwZXIgU2V0UHJvcCgpIHVubm9ldGlnLCBkYSBtYW4gZGFzIE1hcHBpbmcgZGlyZWt0IGFlbmRlcnQsCiAgLy8ga2VpbmUgS29waWUuCn0KCnByb3RlY3RlZCB2b2lkIGhlYXJ0X2JlYXQoKQp7CiAgICBpZiAoICF0aGlzX29iamVjdCgpICkKICAgICAgICByZXR1cm47CgogICAgYXR0cmlidXRlX2hiKCk7CgogICAgLy8gQWxzIEdlaXN0IGxlaWRldCBtYW4gbmljaHQgdW50ZXIgc28gd2VsdGxpY2hlbiBEaW5nZW4gd2llCiAgICAvLyBBbGtvaG9sLCBHaWZ0JkNvIC4uLgogICAgaWYgKCBRdWVyeVByb3AoUF9HSE9TVCkgKQogICAgICAgIHJldHVybjsKCiAgICBpbnQgaHBvaXNvbiA9IFF1ZXJ5UHJvcChQX1BPSVNPTik7CiAgICBpbnQgcmxvY2sgPSBRdWVyeVByb3AoUF9OT19SRUdFTkVSQVRJT04pOwogICAgaW50IGhwID0gUXVlcnlQcm9wKFBfSFApOwogICAgaW50IHNwID0gUXVlcnlQcm9wKFBfU1ApOwogICAgaW50IGFsYzsKCiAgICAvLyBXZW5uIEFsa29ob2wgZ2V0cnVua2VuOiBBbGtvaG9sYXVzd2lya3VuZ2VuPwogICAgaWYgKCAoYWxjID0gUXVlcnlQcm9wKFBfQUxDT0hPTCkpICYmICFyYW5kb20oNDApICl7CiAgICAgICAgaW50IG47CiAgICAgICAgc3RyaW5nIGdpbGRlOwogICAgICAgIG9iamVjdCBvYjsKCiAgICAgICAgbiA9IHJhbmRvbSggNSAqIChhbGMgLSAxKS9RdWVyeVByb3AoUF9NQVhfQUxDT0hPTCkgKTsKCiAgICAgICAgc3dpdGNoIChuKXsKICAgICAgICBjYXNlIEFMQ19FRkZFQ1RfSElDSzoKICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoIFdFUiwgMSApKSArICIgc2FndDogPEhpY2s+IVxuIiApOwogICAgICAgICAgICB3cml0ZSggIjxIaWNrPiEgT2gsIFRzY2h1bGRpZ3VuZy5cbiIgKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIAogICAgICAgIGNhc2UgQUxDX0VGRkVDVF9TVFVNQkxFOgogICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZSggV0VSLCAxICkpICsgIiBzdG9scGVydCB1ZWJlciAiICsKICAgICAgICAgICAgICAgICBRdWVyeVBvc3NQcm9ub3VuKCBGRU1BTEUsIFdFTiApICsgIiBGdWVzc2UuXG4iICk7CiAgICAgICAgICAgIHdyaXRlKCAiRHUgc3RvbHBlcnN0LlxuIiApOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgCiAgICAgICAgY2FzZSBBTENfRUZGRUNUX0xPT0tEUlVOSzoKICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoIFdFUiwgMSApKSArICIgc2llaHQgYmV0cnVua2VuIGF1cy5cbiIgKTsKICAgICAgICAgICAgd3JpdGUoICJEdSBmdWVobHN0IERpY2ggYmVub21tZW4uXG4iICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAKICAgICAgICBjYXNlIEFMQ19FRkZFQ1RfUlVFTFBTOgogICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZSggV0VSLCAxICkpICsgIiBydWVscHN0LlxuIiApOwogICAgICAgICAgICB3cml0ZSggIkR1IHJ1ZWxwc3QuXG4iICk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgIAogICAgICAgIC8vIEdpbGRlIHVuZCBFbnZpcm9ubWVudCBpbmZvcm1pZXJlbiB1ZWJlciBBbGtvaG9sYXVzd2lya3VuZy4KICAgICAgICBpZiAoIHN0cmluZ3AoZ2lsZGUgPSBRdWVyeVByb3AoUF9HVUlMRCkpCiAgICAgICAgICAgICAmJiBvYmplY3RwKG9iID0gZmluZF9vYmplY3QoICIvZ2lsZGVuLyIgKyBnaWxkZSApKSApCiAgICAgICAgICAgIG9iLT5JbmZvcm1BbGNvaG9sRWZmZWN0KCBNRSwgbiwgQUxDX0VGRkVDVF9BUkVBX0dVSUxEICk7CiAgICAgICAgCiAgICAgICAgaWYgKCBlbnZpcm9ubWVudCgpICkKICAgICAgICAgICAgZW52aXJvbm1lbnQoKS0+SW5mb3JtQWxjb2hvbEVmZmVjdCggTUUsIG4sIEFMQ19FRkZFQ1RfQVJFQV9FTlYgKTsKICAgIH0KICAgIAogICAgLy8gQWxrb2hvbCBhYmJhdWVuIHVuZCBldHdhcyBleHRyYSBoZWlsZW4sIGZhbGxzIGVybGF1YnQuCiAgICBpZiAoIGFsYyAmJiAoLS1kZWxheV9hbGNvaG9sIDwgMCkKICAgICAgICAgJiYgIShybG9jayAmIE5PX1JFR19BTENPSE9MKSApewoKICAgICAgICBTZXRQcm9wKCBQX0FMQ09IT0wsIGFsYyAtIDEgKTsKICAgICAgICAKICAgICAgICBpZiAoICFocG9pc29uICl7CiAgICAgICAgICAgIGhwKys7CiAgICAgICAgICAgIHNwKys7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIGRlbGF5X2FsY29ob2wgPSBRdWVyeVByb3AoUF9BTENPSE9MX0RFTEFZKTsKICAgIH0KCiAgICAvLyBQX0RSSU5LIHJlZHV6aWVyZW4sIGZhbGxzIGVybGF1YnQuCiAgICBpZiAoICgtLWRlbGF5X2RyaW5rIDwgMCkgJiYgIShybG9jayAmIE5PX1JFR19EUklOSykgKXsKICAgICAgICBkZWxheV9kcmluayA9IFF1ZXJ5UHJvcChQX0RSSU5LX0RFTEFZKTsKICAgICAgICBTZXRQcm9wKCBQX0RSSU5LLCBRdWVyeVByb3AoUF9EUklOSykgLSAxICk7CiAgICB9CgogICAgLy8gUF9GT09EIHJlZHV6aWVyZW4sIGZhbGxzIGVybGF1YnQuCiAgICBpZiAoICgtLWRlbGF5X2Zvb2QgPCAwKSAmJiAhKHJsb2NrICYgTk9fUkVHX0ZPT0QpICl7CiAgICAgICAgZGVsYXlfZm9vZCA9IFF1ZXJ5UHJvcChQX0ZPT0RfREVMQVkpOwogICAgICAgIFNldFByb3AoIFBfRk9PRCwgUXVlcnlQcm9wKFBfRk9PRCkgLSAxICk7CiAgICB9CgogICAgLy8gUmVnZW5lcmF0aW9uIGF1cyBkZW0gSFAtUHVmZmVyCiAgICAvLyBIaWVyYmVpIHdpcmQgendhciBudXIgZ2VoZWlsdCwgd2VubiBkYXMgZXJsYXVidCBpc3QsIGFiZXIgZGVyIFB1ZmZlcgogICAgLy8gbXVzcyB0cm90emRlbSBhYmdlYXJiZWl0ZXQvcmVkdXppZXJ0IHdlcmRlbiwgZGEgRGVsZmVuIHNvbnN0IGVpbmUKICAgIC8vIG1vYmlsZSBUYW5rZSBrcmllZ2VuLiAoS2VpbmUgSGVpbHVuZyBpbSBIZWxsZW4sIFB1ZmZlciBibGVpYnQgc29uc3QKICAgIC8vIGtvbnN0YW50IHVuZCBrYW5uIGJlaSBCZWRhcmYgdWViZXIgZHVua2VsbWFjaGVuZGUgSXRlbXMgYWJnZXJ1ZmVuCiAgICAvLyB3ZXJkZW4uKQogICAgaW50IHZhbDsKICAgIGlmIChocF9idWZmZXJbMF0pIHsKICAgICAgICBpbnQgcmF0ZSA9IGhwX2J1ZmZlclsxXTsKICAgICAgICB2YWwgPSBocF9idWZmZXJbcmF0ZSArIDFdOwogICAgCiAgICAgICAgaWYgKCB2YWwgPiByYXRlICkKICAgICAgICAgICAgdmFsID0gcmF0ZTsKICAgICAgICBocF9idWZmZXJbMF0gLT0gdmFsOwogICAgICAgIGhwX2J1ZmZlcltyYXRlICsgMV0gLT0gdmFsOwogICAgICAgIGlmICggaHBfYnVmZmVyW3JhdGUgKyAxXSA8PSAwICkKICAgICAgICAgICAgdXBkYXRlX2J1ZmZlcnMoKTsKICAgIH0KICAgIC8vIEpldHp0IFJlZ2VuZXJhdGlvbiBhdXMgZGVtIFB1ZmZlciBkdXJjaGZ1ZWhyZW4sIGFiZXIgbnVyIHdlbm4gZXJsYXVidC4KICAgIGlmICggdmFsICYmICEocmxvY2sgJiBOT19SRUdfQlVGRkVSX0hQKSApCiAgICAgICAgaHAgKz0gdmFsOyAKICAgIC8vIG5vcm1hbGVzIEhlaWxlbiwgZmFsbHMga2VpbmUgUmVnZW5lcmF0aW9uIGF1cyBkZW0gUHVmZmVyIGVyZm9sZ3RlIHVuZAogICAgLy8gZXMgZXJsYXVidCBpc3QuCiAgICBlbHNlIGlmICggKC0tZGVsYXlfaGVhbCA8IDApICYmICEocmxvY2sgJiBOT19SRUdfSFApICl7CiAgICAgICAgZGVsYXlfaGVhbCA9IFF1ZXJ5UHJvcChQX0hQX0RFTEFZKTsKICAgICAgICBpZiAoICFocG9pc29uICkKICAgICAgICAgICAgaHArKzsKICAgIH0KCiAgICAvLyBHbGVpY2hlcyBTcGllbCBqZXR6dCBmdWVyIGRlbiBTUC1QdWZmZXIgKHMuby4pCiAgICB2YWw9MDsKICAgIGlmICggc3BfYnVmZmVyWzBdICkgewogICAgICAgIGludCByYXRlID0gc3BfYnVmZmVyWzFdOwogICAgICAgIHZhbCA9IHNwX2J1ZmZlcltyYXRlICsgMV07CiAgICAgICAgCiAgICAgICAgaWYgKCB2YWwgPiByYXRlICkKICAgICAgICAgICAgdmFsID0gcmF0ZTsKICAgICAgICAKICAgICAgICBzcF9idWZmZXJbMF0gLT0gdmFsOwogICAgICAgIHNwX2J1ZmZlcltyYXRlICsgMV0gLT0gdmFsOwogCiAgICAgICAgaWYgKCBzcF9idWZmZXJbcmF0ZSArIDFdIDw9IDAgKQogICAgICAgICAgICB1cGRhdGVfYnVmZmVycygpOwogICAgfQogICAgLy8gUmVnZW5lcmF0aW9uIGVybGF1YnQ/CiAgICBpZiAoIHZhbCAmJiAhKHJsb2NrICYgTk9fUkVHX0JVRkZFUl9TUCkgKQogICAgICAgICBzcCArPSB2YWw7CiAgICAvLyBXZW5uIG5pY2h0LCBub3JtYWxlcyBIb2NoaWRlbG4gdmVyc3VjaGVuLgogICAgZWxzZSBpZiAoICgtLWRlbGF5X3NwIDwgMCkgJiYgIShybG9jayAmIE5PX1JFR19TUCkgKXsKICAgICAgICBkZWxheV9zcCA9IFF1ZXJ5UHJvcChQX1NQX0RFTEFZKTsKICAgICAgICBpZiAoICFocG9pc29uICkKICAgICAgICAgICAgc3ArKzsKICAgIH0KCiAgICBpZiAoIGhwb2lzb24gJiYgKGludGVyYWN0aXZlKE1FKSB8fCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkpICl7CiAgICAgICAgLy8gVmFuaW9uLCAyNi4xMC4wMwogICAgICAgIC8vIFdlbm4gX3NldF9wb2lzb24oKSBwZXIgU0VUX01FVEhPRCB1ZWJlcnNjaHJpZWJlbiB3aXJkLCBrYW5uCiAgICAgICAgLy8gbmljaHQgc2ljaGVyZ2VzdGVsbHQgd2VyZGVuLCBkYXNzIHBvaXNvbiBpbW1lciBncm9lc3NlciAwIGlzdAogICAgICAgIC8vIERhaGVyIG11c3MgaGllciBlaW4gVGVzdCByZWluLCBzbyB0ZXVlciBkYXMgYXVjaCBpc3QgOigKICAgICAgICBpZiAoLS1ocG9pc29uIDwgMCkKICAgICAgICAgIGhwb2lzb249MDsKICAgICAgICAKICAgICAgICBpZiAoIC0tZGVsYXlfcG9pc29uIDwgMCApewogICAgICAgICAgICBkZWxheV9wb2lzb24gPSBRdWVyeVByb3AoUF9QT0lTT05fREVMQVkpCiAgICAgICAgICAgICAgICArIHJhbmRvbShQT0lTT05fTUVSQ1lfREVMQVkpOwogICAgICAgICAgICBocCAtPSBocG9pc29uOwoKICAgICAgICAgICAgaWYgKCBocCA8IDAgKXsKICAgICAgICAgICAgICAgIHRlbGxfb2JqZWN0KCBNRSwgIk9oIHdlaCAtIGRhcyBHaWZ0IHdhciB6dXZpZWwgZnVlciBEaWNoIVxuIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgIkR1IHN0aXJic3QuXG4iICk7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmICggcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKXsKICAgICAgICAgICAgICAgICAgICBjcmVhdGVfa2lsbF9sb2dfZW50cnkoICJWZXJnaWZ0dW5nIiwgMCApOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIC8vIEJlaW0gR2lmdHRvZCBnaWJ0IGVzIGtlaW5lbiBLaWxsZXIuIEFiZXIgYXVmIGRpZXNlIEFydAogICAgICAgICAgICAgICAgICAgIC8vIGVya2VubnQgZGVyIFRvZGVzcmF1bSBkaWUgVXJzYWNoZSBrb3JyZWt0IHVuZCBnaWJ0IGRpZQogICAgICAgICAgICAgICAgICAgIC8vIHJpY2h0aWdlIE1lbGR1bmcgYXVzLgogICAgICAgICAgICAgICAgICAgIFNldFByb3AoIFBfS0lMTEVSLCAiZ2lmdCIgKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgZGllKDEpOwogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoIChocG9pc29uIDwgMyB8fCAhcXVlcnlfb25jZV9pbnRlcmFjdGl2ZShNRSkgKQogICAgICAgICAgICAgICAgICYmIC0tZHJvcF9wb2lzb24gPCAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvLyBHaWZ0bGV2ZWwgZWlucyByZWR1emllcmVuLiBocG9pc29uIHd1cmRlIG9iZW4gc2Nob24KICAgICAgICAgICAgICAgIC8vIHJlZHV6aWVydCwgZC5oLiBlaW5mYWNoIGhwb2lzb24gaW4gUF9QT0lTT04gc2NocmVpYmVuLgogICAgICAgICAgICAgICAgLy8gZGFiZWkgd2lyZCBkYW5uIGF1Y2ggZ2dmLiBkcm9wX3BvaXNvbiByaWNodGlnIGdlc2V0enQuCiAgICAgICAgICAgICAgICBTZXRQcm9wKCBQX1BPSVNPTiwgaHBvaXNvbiApOwogICAgICAgICAgICAgICAgaWYgKCAhaHBvaXNvbiApCiAgICAgICAgICAgICAgICAgICAgdGVsbF9vYmplY3QoIE1FLCAiRHUgc2NoZWluc3QgZGllIFZlcmdpZnR1bmcgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVlYmVyd3VuZGVuIHp1IGhhYmVuLlxuIiApOyAgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYgKCBocG9pc29uICYmICFyYW5kb20oMTUpICkKICAgICAgICAgICAgc3dpdGNoICggaHAqMTAwL1F1ZXJ5UHJvcChQX01BWF9IUCkgKXsKICAgICAgICAgICAgY2FzZSA3MS4uMTAwIDoKICAgICAgICAgICAgICAgIHdyaXRlKCAiRHUgZnVlaGxzdCBEaWNoIG5pY2h0IGd1dC5cbiIgKTsKICAgICAgICAgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKFdFUikpICsKICAgICAgICAgICAgICAgICAgICAgIiBzaWVodCBldHdhcyBiZW5vbW1lbiBhdXMuXG4iICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICBjYXNlIDQ2Li43MCA6CiAgICAgICAgICAgICAgICB3cml0ZSggIkRpciBpc3Qgc2Nod2luZGxpZyB1bmQgRGVpbiBNYWdlbiByZXZvbHRpZXJ0LlxuIiApOwogICAgICAgICAgICAgICAgc2F5KCBjYXBpdGFsaXplKG5hbWUoV0VSKSkgKyAiIHRhdW1lbHQgZWluIHdlbmlnLlxuIiApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgY2FzZSAyNi4uNDUgOgogICAgICAgICAgICAgICAgd3JpdGUoICJEaXIgaXN0IGhlaXNzLiBEdSBmdWVobHN0IERpY2ggc2Nod2FjaC4gS29wZndlaCAiCiAgICAgICAgICAgICAgICAgICAgICAgImhhc3QgRHUgYXVjaC5cbiIgKTsKICAgICAgICAgICAgICAgIHNheSggY2FwaXRhbGl6ZShuYW1lKFdFUikpICsgIiBnbHVlaHQgZGlyZWt0IHVuZCBzY2hlaW50ICIKICAgICAgICAgICAgICAgICAgICAgImdyb3NzZSBTY2h3aWVyaWdrZWl0ZW4genUgaGFiZW4uXG4iICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICBjYXNlIDExLi4yNSA6CiAgICAgICAgICAgICAgICB3cml0ZSggIkR1IGZ1ZWhsc3QgRGljaCBiZXNjaGlzc2VuLiBBbGxlcyB0dXQgd2VoLCB1bmQgRHUgIgogICAgICAgICAgICAgICAgICAgICAgICJzaWVoc3QgbnVyIG5vY2ggdW5zY2hhcmYuXG4iICk7CiAgICAgICAgICAgICAgICBzYXkoIGNhcGl0YWxpemUobmFtZShXRVIpKSArICIgdGF1bWVsdCB1bmQgc3RvZWhudCB1bmQgIgogICAgICAgICAgICAgICAgICAgICAia2FubiBnZXJhZGUgbm9jaCB2ZXJtZWlkZW4sIGhpbnp1ZmFsbGVuLlxuIiApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgY2FzZSAwLi4xMCA6CiAgICAgICAgICAgICAgICB3cml0ZSggYnJlYWtfc3RyaW5nKCAiRHUgc2llaHN0IGZhc3QgbmljaHRzIG1laHIgdW5kIGthbm5zdCAiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiRGljaCBudXIgbm9jaCB1bnRlciBncm9lc3N0ZW4gU2NobWVyemVuICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJiZXdlZ2VuLiBBYmVyIGJhbGQgdHV0IG5pY2h0cyBtZWhyIHdlaCIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIuLi4iLCA3OCApICk7CiAgICAgICAgICAgICAgICBzYXkoIGJyZWFrX3N0cmluZyggY2FwaXRhbGl6ZShuYW1lKFdFUikpICsgIiBnbHVlaHQgd2llICIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW0gRmllYmVyLCBrYW5uIHNpY2gga2F1bSBub2NoIHJ1ZWhyZW4gIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmQgaGF0IGVpbiBzY2htZXJ6dmVyemVycnRlcyBHZXNpY2h0LlxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA3OCApICk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgfQoKICAgIFNldFByb3AoIFBfSFAsIGhwICk7CiAgICBTZXRQcm9wKCBQX1NQLCBzcCApOwp9CgpwdWJsaWMgaW50IEFkZEV4cCggaW50IGUgKQp7CiAgaW50IGV4cGVyaWVuY2U7CiAgc3RyaW5nIGZuOwogIG1peGVkIGxhc3Q7CgogIGV4cGVyaWVuY2UgPSBRdWVyeVByb3AoUF9YUCk7CgogIGlmICggUXVlcnlQcm9wKFBfS0lMTFMpID4gMSAmJiBlID4gMCApCiAgICAgIHJldHVybiBleHBlcmllbmNlOwoKICBmbiA9IGltcGxvZGUoIGV4cGxvZGUoIG9iamVjdF9uYW1lKCBlbnZpcm9ubWVudCgpIHx8IHRoaXNfb2JqZWN0KCkgKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIvIiApWzAuLjwyXSwgIi8iICk7CgogIGlmICggcG9pbnRlcnAobGFzdCA9IFF1ZXJ5KFBfTEFTVF9YUCkpICYmIHNpemVvZihsYXN0KSA9PSAyICYmIGxhc3RbMF0gPT0gZm4gKQogICAgICBTZXQoIFBfTEFTVF9YUCwgKHsgZm4sIGxhc3RbMV0rZSB9KSApOwogIGVsc2UKICAgICAgU2V0KCBQX0xBU1RfWFAsICh7IGZuLCBlIH0pICk7CgogIGlmICggKGV4cGVyaWVuY2UgKz0gZSkgPCAwICkKICAgICAgZXhwZXJpZW5jZSA9IDA7CgogIHJldHVybiBTZXRQcm9wKCBQX1hQLCBleHBlcmllbmNlICk7Cn0KCnN0YXRpYyA8c3RyaW5nfGludD4qIF9zZXRfbGFzdF94cCggPGludHxzdHJpbmc+KiBsYXN0ICkKewogICAgaWYgKCAhcG9pbnRlcnAobGFzdCkgfHwgc2l6ZW9mKGxhc3QpICE9IDIgfHwgIXN0cmluZ3AobGFzdFswXSkgfHwKICAgICAgICAgIWludHAobGFzdFsxXSkgKQogICAgICAgIHJldHVybiBRdWVyeShQX0xBU1RfWFApOwogICAgZWxzZQogICAgICAgIHJldHVybiBTZXQoIFBfTEFTVF9YUCwgbGFzdCApOwp9CgoKc3RhdGljIGludCBfc2V0X2FsaWduKGludCBhKQp7CiAgaWYgKGE8LTEwMDApIGEgPSAtMTAwMDsKICBpZiAoYT4xMDAwKSBhID0gMTAwMDsKICByZXR1cm4gU2V0KFBfQUxJR04sIGEpOwp9CgoKc3RhdGljIGludCBfc2V0X2hwKCBpbnQgaHAgKQp7CiAgICBpZiAoIFF1ZXJ5UHJvcChQX0dIT1NUKSApCiAgICAgICAgcmV0dXJuIFF1ZXJ5UHJvcChQX0hQKTsKCiAgICBpZiAoIGhwIDwgMCApCiAgICAgICAgcmV0dXJuIFNldCggUF9IUCwgMCApOwoKICAgIGlmICggaHAgPiBRdWVyeVByb3AoUF9NQVhfSFApICkKICAgICAgICByZXR1cm4gU2V0KCBQX0hQLCBRdWVyeVByb3AoUF9NQVhfSFApLCBGX1ZBTFVFICk7CgogICAgcmV0dXJuIFNldCggUF9IUCwgaHAsIEZfVkFMVUUgKTsKfQoKc3RhdGljIGludCBfc2V0X3NwKCBpbnQgc3AgKQp7CiAgICAvL2VpbmlnZSBMZXV0ZSBzY2hyZWliZW4gZmxvYXRzIGluIGRpZSBQX0hQLiA6LSgKICAgIGlmICghaW50cChzcCkpIHsKCXNwPXRvX2ludChzcCk7CgkvL2phLCBlcyBpc3QgdGV1ZXIuIEFiZXIgaWNoIHdpbGwgd2lzc2VuLCB3ZXJzIGlzdC4gS2FubiB2b3IKCS8vbmFlY2hzdGVtIFJlYm9vdCB3aWVkZXIgcmF1cy4KCWxvZ19maWxlKCJJTExFR0FMX1RZUEUubG9nIixzcHJpbnRmKAoJICAgICAgIlZlcnN1Y2gsIGVpbmVuIG5pY2h0LWludCBpbiBQX1NQIGluICVPIHp1IHNjaHJlaWJlbjogXG4lT1xuIiwKCSAgICAgIHRoaXNfb2JqZWN0KCksCgkgICAgICBkZWJ1Z19pbmZvKERJTkZPX1RSQUNFLERJVF9TVFJfQ1VSUkVOVCkpKTsKICAgIH0KCiAgICBpZiAoIFF1ZXJ5UHJvcChQX0dIT1NUKSApCiAgICAgICAgUXVlcnlQcm9wKFBfU1ApOwoKICAgIGlmICggc3AgPCAwICkKICAgICAgICByZXR1cm4gU2V0KCBQX1NQLCAwICk7CgogICAgaWYgKCBzcCA+IFF1ZXJ5UHJvcChQX01BWF9TUCkgKQogICAgICAgIHJldHVybiBTZXQoIFBfU1AsIFF1ZXJ5UHJvcChQX01BWF9TUCksIEZfVkFMVUUgKTsKCiAgICByZXR1cm4gU2V0KCBQX1NQLCBzcCwgRl9WQUxVRSApOwp9CgpzdGF0aWMgaW50IF9zZXRfYWxjb2hvbChpbnQgbikKewogIGlmKCFpbnRwKG4pKQogICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAogICAgICAgICJfc2V0X2FsY29ob2woKTogZXhwZWN0ZWQgPGludD4sIGdvdCAlLjUwT1xuIiwgbikpOwoKICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKQogICAgcmV0dXJuIFF1ZXJ5KFBfQUxDT0hPTCwgRl9WQUxVRSk7CgogIC8vIG51ciDEbmRlcnVuZ2VuIHVuZCBXZXJ0ZSA+PTAgd2VyZGVuIGdlc2V0enQuLi4KICBuID0gbiA8IDAgPyAwIDogbjsKICBpbnQgb2xkID0gUXVlcnkoUF9BTENPSE9MLCBGX1ZBTFVFKTsKICBpZiAoIG9sZCA9PSBuKQogICAgcmV0dXJuIG9sZDsKCiAgLy8gSG9va3MgYXVmcnVmZW4KICBpbnQgKnJldCA9IEhvb2tGbG93KEhfSE9PS19BTENPSE9MLCBuKTsKICAvLyBCZWkgQWJicnVjaCBhbHRlbiBXZXJ0IHp1cnVlY2tnZWJlbgogIHN3aXRjaCAocmV0W0hfUkVUQ09ERV0pIHsKICAgIGNhc2UgSF9DQU5DRUxMRUQ6CiAgICAgIHJldHVybiBvbGQ7CiAgICBjYXNlIEhfQUxURVJFRDoKICAgICAgLy8gc29uc3QgbmV1ZW4gV2VydCBzZXR6ZW4KICAgICAgaWYoIWludHAocmV0W0hfUkVUREFUQV0pKQogICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgIl9zZXRfYWxjb2hvbCgpOiBkYXRhIGZyb20gSG9va0Zsb3coKSAhPSA8aW50PjogJS41ME9cbiIsCiAgICAgICAgICAgIHJldFtIX1JFVERBVEFdKSk7CiAgICAgIG4gPSByZXRbSF9SRVREQVRBXTsKICAgICAgbiA9IG4gPCAwID8gMCA6IG47CgogICAgLy8gSF9OT19NT0QgaXMgZmFsbHRocm91Z2gKICB9CgogIHJldHVybiBTZXQoUF9BTENPSE9MLCBuLCBGX1ZBTFVFKTsKfQoKc3RhdGljIGludCBfc2V0X2RyaW5rKGludCBuKQp7CiAgaWYoIWludHAobikpCiAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCiAgICAgICAgIl9zZXRfZHJpbmsoKTogZXhwZWN0ZWQgPGludD4sIGdvdCAlLjUwT1xuIiwgbikpOwoKICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKQogICAgcmV0dXJuIFF1ZXJ5KFBfRFJJTkssIEZfVkFMVUUpOwoKICAvLyBudXIgxG5kZXJ1bmdlbiB1bmQgV2VydGUgPj0wIHdlcmRlbiBnZXNldHp0Li4uCiAgbiA9IG4gPCAwID8gMCA6IG47CiAgaW50IG9sZCA9IFF1ZXJ5KFBfRFJJTkssIEZfVkFMVUUpOwogIGlmICggb2xkID09IG4pCiAgICByZXR1cm4gb2xkOwoKICAvLyBIb29rcyBhdWZydWZlbgogIGludCAqcmV0ID0gSG9va0Zsb3coSF9IT09LX0RSSU5LLCBuKTsKICAvLyBCZWkgQWJicnVjaCBhbHRlbiBXZXJ0IHp1cnVlY2tnZWJlbgogIHN3aXRjaCAocmV0W0hfUkVUQ09ERV0pIHsKICAgIGNhc2UgSF9DQU5DRUxMRUQ6CiAgICAgIHJldHVybiBvbGQ7CiAgICBjYXNlIEhfQUxURVJFRDoKICAgICAgLy8gc29uc3QgbmV1ZW4gV2VydCBzZXR6ZW4KICAgICAgaWYoIWludHAocmV0W0hfUkVUREFUQV0pKQogICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgIl9zZXRfZHJpbmsoKTogZGF0YSBmcm9tIEhvb2tGbG93KCkgIT0gPGludD46ICUuNTBPXG4iLAogICAgICAgICAgICByZXRbSF9SRVREQVRBXSkpOwogICAgICBuID0gcmV0W0hfUkVUREFUQV07CiAgICAgIG4gPSBuIDwgMCA/IDAgOiBuOwoKICAgIC8vIEhfTk9fTU9EIGlzIGZhbGx0aHJvdWdoCiAgfQoKICByZXR1cm4gU2V0KFBfRFJJTkssIG4sIEZfVkFMVUUpOwp9CgpzdGF0aWMgaW50IF9zZXRfZm9vZChpbnQgbikKewogIGlmKCFpbnRwKG4pKQogICAgICByYWlzZV9lcnJvcihzcHJpbnRmKAogICAgICAgICJfc2V0X2Zvb2QoKTogZXhwZWN0ZWQgPGludD4sIGdvdCAlLjUwT1xuIiwgbikpOwoKICBpZiAoUXVlcnlQcm9wKFBfR0hPU1QpKQogICAgcmV0dXJuIFF1ZXJ5KFBfRk9PRCwgRl9WQUxVRSk7CgogIC8vIG51ciDEbmRlcnVuZ2VuIHVuZCBXZXJ0ZSA+PTAgd2VyZGVuIGdlc2V0enQuLi4KICBuID0gbiA8IDAgPyAwIDogbjsKICBpbnQgb2xkID0gUXVlcnkoUF9GT09ELCBGX1ZBTFVFKTsKICBpZiAoIG9sZCA9PSBuKQogICAgcmV0dXJuIG9sZDsKCiAgLy8gSG9va3MgYXVmcnVmZW4KICBpbnQgKnJldCA9IEhvb2tGbG93KEhfSE9PS19GT09ELCBuKTsKICAvLyBCZWkgQWJicnVjaCBhbHRlbiBXZXJ0IHp1cnVlY2tnZWJlbgogIHN3aXRjaCAocmV0W0hfUkVUQ09ERV0pIHsKICAgIGNhc2UgSF9DQU5DRUxMRUQ6CiAgICAgIHJldHVybiBvbGQ7CiAgICBjYXNlIEhfQUxURVJFRDoKICAgICAgLy8gc29uc3QgbmV1ZW4gV2VydCBzZXR6ZW4KICAgICAgaWYoIWludHAocmV0W0hfUkVUREFUQV0pKQogICAgICAgICAgcmFpc2VfZXJyb3Ioc3ByaW50ZigKICAgICAgICAgICAgIl9zZXRfZm9vZCgpOiBkYXRhIGZyb20gSG9va0Zsb3coKSAhPSA8aW50PjogJS41ME9cbiIsCiAgICAgICAgICAgIHJldFtIX1JFVERBVEFdKSk7CiAgICAgIG4gPSByZXRbSF9SRVREQVRBXTsKICAgICAgbiA9IG4gPCAwID8gMCA6IG47CgogICAgLy8gSF9OT19NT0QgaXMgZmFsbHRocm91Z2gKICB9CgogIHJldHVybiBTZXQoUF9GT09ELCBuLCBGX1ZBTFVFKTsKfQoKc3RhdGljIGludCBfc2V0X3BvaXNvbihpbnQgbikKewogICAgaWYoIWludHAobikpCiAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCiAgICAgICAgIl9zZXRfcG9pc29uKCk6IGV4cGVjdGVkIDxpbnQ+LCBnb3QgJS41ME9cbiIsIG4pKTsKCiAgaWYgKFF1ZXJ5UHJvcChQX0dIT1NUKSkKICAgIHJldHVybiBRdWVyeShQX1BPSVNPTiwgRl9WQUxVRSk7CgogIGludCBtcCA9IFF1ZXJ5UHJvcChQX01BWF9QT0lTT04pOwogIG4gPSAobjwwID8gMCA6IChuPm1wID8gbXAgOiBuKSk7CgogIC8vIG51ciA+PTAgenVsYXNzZW4uCiAgbiA9IG4gPCAwID8gMCA6IG47CgogIGludCBvbGQgPSBRdWVyeShQX1BPSVNPTiwgRl9WQUxVRSk7CiAgaWYgKCBvbGQgPT0gMCAmJiBuID09IDApCiAgICByZXR1cm4gb2xkOwoKICAvLyBIb29rcyBhdWZydWZlbgogIGludCAqcmV0ID0gSG9va0Zsb3coSF9IT09LX1BPSVNPTiwgbik7CiAgLy8gQmVpIEFiYnJ1Y2ggYWx0ZW4gV2VydCB6dXJ1ZWNrZ2ViZW4KICBzd2l0Y2ggKHJldFtIX1JFVENPREVdKSB7CiAgICBjYXNlIEhfQ0FOQ0VMTEVEOgogICAgICByZXR1cm4gb2xkOwogICAgY2FzZSBIX0FMVEVSRUQ6CiAgICAgIC8vIHNvbnN0IG5ldWVuIFdlcnQgc2V0emVuCiAgICAgIGlmKCFpbnRwKHJldFtIX1JFVERBVEFdKSkKICAgICAgICAgIHJhaXNlX2Vycm9yKHNwcmludGYoCiAgICAgICAgICAgICJfc2V0X3BvaXNvbigpOiBkYXRhIGZyb20gSG9va0Zsb3coKSAhPSA8aW50PjogJS41ME9cbiIsCiAgICAgICAgICAgIHJldFtIX1JFVERBVEFdKSk7CiAgICAgIG4gPSByZXRbSF9SRVREQVRBXTsKICAgICAgbiA9IG4gPCAwID8gMCA6IG47CgogICAgLy8gSF9OT19NT0QgaXMgZmFsbHRocm91Z2gKICB9CgogIC8vIEZ1ZXIgZGllIFNlbGJzdGhlaWx1bmcuCiAgc3dpdGNoKG4pIHsKICBjYXNlIDE6CiAgICBkcm9wX3BvaXNvbiA9IDQwK3JhbmRvbSgxNik7CiAgICBicmVhazsKICBjYXNlIDI6CiAgICBkcm9wX3BvaXNvbiA9IDI1K3JhbmRvbSg4KTsKICAgIGJyZWFrOwogIGNhc2UgMzoKICAgIGRyb3BfcG9pc29uID0gMTgrcmFuZG9tKDQpOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIC8vIG51ciByZWxldmFudCBmdWVyIE5QQywgZGEgU3BpZWxlciBiZWkgPjMgR2lmdCBuaWNodCBtZWhyIHJlZ2VnZW5pZXJlbi4KICAgIGRyb3BfcG9pc29uID0gMjIgLSAyKm4gKyByYW5kb20oNDMgLSAzKm4pOwogICAgYnJlYWs7CiAgfQoKICAvLyBmdWVyIFNldHplbiBkZXIgUHJvcCB2b24gYXVzc2VuIGVpbiBMb2cgc2NocmVpYmVuCiAgaWYgKHByZXZpb3VzX29iamVjdCgxKSAhPSBNRSkKICAgIGxvZ19maWxlKCJQT0lTT04iLCBzcHJpbnRmKCIlcyAtICVzOiAlZCB2b24gJU8gKCVzKVxuIiwKICAgICAgICAgICBkdGltZSh0aW1lKCkpWzUuLl0sCiAgICAgICAgICAgKHF1ZXJ5X29uY2VfaW50ZXJhY3RpdmUodGhpc19vYmplY3QoKSkgPwogICAgICAgICAgICAgY2FwaXRhbGl6ZShnZXRldWlkKHRoaXNfb2JqZWN0KCkpKSA6CiAgICAgICAgICAgICBjYXBpdGFsaXplKG5hbWUoV0VSKSkpLAogICAgICAgICAgIG4sCiAgICAgICAgICAgKHByZXZpb3VzX29iamVjdCgyKSA/IHByZXZpb3VzX29iamVjdCgyKSA6IHByZXZpb3VzX29iamVjdCgxKSksCiAgICAgICAgICAgKHRoaXNfcGxheWVyKCkgPyBjYXBpdGFsaXplKGdldGV1aWQodGhpc19wbGF5ZXIoKSkpIDogIj8/PyIpKSk7CgogIHJldHVybiBTZXQoUF9QT0lTT04sIG4sIEZfVkFMVUUpOwp9CgpzdGF0aWMgaW50IF9zZXRfeHAoaW50IHhwKSB7IHJldHVybiBTZXQoUF9YUCwgeHAgPCAwID8gMCA6IHhwLCBGX1ZBTFVFKTsgfQoKc3RhdGljIG1peGVkIF9zZXRfZGllX2hvb2sobWl4ZWQgaG9vaykKewogIGlmKGhvb2sgJiYgcXVlcnlfb25jZV9pbnRlcmFjdGl2ZSh0aGlzX29iamVjdCgpKSkKICAgIGxvZ19maWxlKCJESUVfSE9PSyIsCiAgICAgICAgICAgICBzcHJpbnRmKCIlcyA6IERJRV9IT09LIGdlc2V0enQgdm9uICVPIGluICVPICglcylcbiIsCiAgICAgICAgICAgICAgICAgICAgIGR0aW1lKHRpbWUoKSlbNS4uXSwKICAgICAgICAgICAgICAgICAgICAgKHByZXZpb3VzX29iamVjdCgyKSA/IHByZXZpb3VzX29iamVjdCgyKTpwcmV2aW91c19vYmplY3QoMSkpLAogICAgICAgICAgICAgICAgICAgICB0aGlzX29iamVjdCgpLGdldHVpZCh0aGlzX29iamVjdCgpKSkpOwogIHJldHVybiBTZXQoUF9UTVBfRElFX0hPT0ssaG9vaywgRl9WQUxVRSk7Cn0KCnN0YXRpYyBtYXBwaW5nIF9xdWVyeV9lbmVteV9kYW1hZ2UoKQp7CiAgcmV0dXJuIGNvcHkoZW5lbXlfZGFtYWdlKTsKfQoKLy8gbnVyIG5lIEtvcGllIGxpZWZlcm4sIHNvbnN0IGthbm4gZGFzIGplZGVyIHZvbiBhdXNzZW4gYWVuZGVybi4Kc3RhdGljIG1hcHBpbmcgX3F1ZXJ5X3RpbWluZ19tYXAoKSB7CiAgcmV0dXJuIGNvcHkoUXVlcnkoUF9USU1JTkdfTUFQKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENvbnN1bWUtRnVua3Rpb24sIHVtIHplbnRyYWwgZHVyY2gga29uc3VtaWVyYmFyZSBEaW5nZSBhdXNnZWxvZXN0ZQogKiBBZW5kZXJ1bmdlbiBkZXMgR2VzdW5kaGVpdHN6dXN0YW5kZXMgaGVyYmVpenVmdWVocmVuLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogS29uc3VtaWVydCBldHdhcwogKgogKiBSdWVja2dhYmV3ZXJ0CiAqICAgICAgMSAgICAgICBlcmZvbGdyZWljaCBrb25zdW1pZXJ0CiAqICAgICAgMCAgICAgICBmZWhsZW5kZSBvZGVyIGZhbHNjaGUgUGFyYW1ldGVyCiAqICAgICA8MCAgICAgICBCZWRpbmd1bmcgZnVlciBrb25zdW1pZXJlbiBuaWNodCBlcmZ1ZWxsdCwgQml0c2V0IGF1czoKICogICAgICAxICAgICAgIEthbm4gbmljaHRzIG1laHIgZXNzZW4KICogICAgICAyICAgICAgIEthbm4gbmljaHRzIG1laHIgdHJpbmtlbgogKiAgICAgIDQgICAgICAgS2FubiBuaWNodHMgbWVociBzYXVmZW4KICogICAgICA4ICAgICAgIEFiZ2Vicm9jaGVuIGR1cmNoIEhvb2sgSF9IT09LX0NPTlNVTUUKICovCnB1YmxpYyB2YXJhcmdzIGludCBjb25zdW1lKG1hcHBpbmcgY2luZm8sIGludCB0ZXN0b25seSkKewogIGludCByZXR2YWwgPSAwOwogIC8vIG51ciB3YXMgdHVuLCB3ZW5uIGF1Y2ggSW5mb3MgcmVpbmtvbW1lbgogIGlmIChtYXBwaW5ncChjaW5mbykgJiYgc2l6ZW9mKGNpbmZvKSkgewogICAgLy8gSG9va3MgYXVmcnVmZW4sIHNpZSBhZW5kZXJuIGdnZi4gbm9jaCB3YXMgaW4gY2luZm8uCiAgICBtaXhlZCAqaHJldCA9IEhvb2tGbG93KEhfSE9PS19DT05TVU1FLCAoe2NpbmZvLCB0ZXN0b25seX0pICk7CiAgICBzd2l0Y2goaHJldFtIX1JFVENPREVdKQogICAgewogICAgICAgIGNhc2UgSF9DQU5DRUxMRUQ6CiAgICAgICAgICByZXR1cm4gLUhDX0hPT0tfQ0FOQ0VMTEFUSU9OOwogICAgICAgIGNhc2UgSF9BTFRFUkVEOgogICAgICAgICAgLy8gdGVzdG9ubHkga2FubiBuaWNodCBnZWFlbmRlcnQgd2VyZGVuLgogICAgICAgICAgY2luZm8gPSBocmV0W0hfUkVUREFUQV1bMF07CiAgICB9CiAgICAvLyBMZWdhY3ktTWFwcGluZ3MgKGZsYWNoZSkgbmViZW4gc3RydWt0dXJpZXJ0ZW4gTWFwcGluZ3MgenVsYXNzZW4KICAgIC8vIGZsYWNoZSBLb3BpZW4gZXJ6ZXVnZW4gKFRPRE8/OiB1bmQgZnVlciBUZWlsbWFwcGluZ3MgbmljaHQgcmVsZXZhbnRlCiAgICAvLyBFaW50cmFlZ2UgbG9lc2NoZW4pCiAgICBtYXBwaW5nIGNvbmRpdGlvbnM7CiAgICBpZiAobWFwcGluZ3AoY2luZm9bSF9DT05ESVRJT05TXSkpIHsKICAgICAgY29uZGl0aW9ucyA9IGNvcHkoY2luZm9bSF9DT05ESVRJT05TXSk7CiAgICB9IGVsc2UgewogICAgICBjb25kaXRpb25zID0gY29weShjaW5mbyk7CiAgICB9CiAgICBtYXBwaW5nIGVmZmVjdHM7CiAgICBpZiAobWFwcGluZ3AoY2luZm9bSF9FRkZFQ1RTXSkpIHsKICAgICAgZWZmZWN0cyA9IGZpbHRlcihjaW5mb1tIX0VGRkVDVFNdLCAoOiBtZW1iZXIoSF9BTExPV0VEX0VGRkVDVFMsICQxKSA+IC0xIDopKTsKICAgIH0gZWxzZSB7CiAgICAgIGVmZmVjdHMgPSBmaWx0ZXIoY2luZm8sICg6IG1lbWJlcihIX0FMTE9XRURfRUZGRUNUUywgJDEpID4gLTEgOikpOwogICAgfQoKICAgIC8vIEJlZGluZ3VuZ2VuIHBydWVmZW4KICAgIGlmIChtYXBwaW5ncChjb25kaXRpb25zKSAmJiBzaXplb2YoY29uZGl0aW9ucykpIHsKICAgICAgLy8gQmVkaW5ndW5nZW4gZnVlciBLb25zdW0gYXVzd2VydGVuCiAgICAgIGlmIChjb25kaXRpb25zW1BfRk9PRF0gJiYgIWVhdF9mb29kKGNvbmRpdGlvbnNbUF9GT09EXSwgMSkpCiAgICAgICAgcmV0dmFsIHw9IEhDX01BWF9GT09EX1JFQUNIRUQ7CiAgICAgIGVsc2UgaWYgKGNvbmRpdGlvbnNbUF9EUklOS10gJiYgIWRyaW5rX3NvZnQoY29uZGl0aW9uc1tQX0RSSU5LXSwgMSkpCiAgICAgICAgcmV0dmFsIHw9IEhDX01BWF9EUklOS19SRUFDSEVEOwogICAgICBlbHNlIGlmIChjb25kaXRpb25zW1BfQUxDT0hPTF0gJiYgIWRyaW5rX2FsY29ob2woY29uZGl0aW9uc1tQX0FMQ09IT0xdLCAxKSkKICAgICAgICByZXR2YWwgfD0gSENfTUFYX0FMQ09IT0xfUkVBQ0hFRDsKICAgICAgLy8gcmV0dmFsIG5lZ2F0aXYgbWFjaGVuLCBkYW1pdCBGZWhsZXIgbGVpY2h0IGVya2VubmJhciBpc3QKICAgICAgcmV0dmFsID0gLXJldHZhbDsKICAgIH0KICAgIC8vIEJlZGluZ3VuZ2VuIHd1cmRlbiBhYmdlYXJiZWl0ZXQsIGpldHp0IGRpZSBIZWlsdW5nIGR1cmNoZnVlaHJlbgogICAgaWYgKCFyZXR2YWwpIHsKICAgICAgaWYgKCF0ZXN0b25seSkgewogICAgICAgIC8vIEJlZGluZ3VuZ2VuIGVyZnVlbGxlbiwgd2VubiBhbGxlcyBwYXNzdCB1bmQga2VpbiBUZXN0CiAgICAgICAgaWYgKGNvbmRpdGlvbnNbUF9BTENPSE9MXSkKICAgICAgICAgIGRyaW5rX2FsY29ob2woY29uZGl0aW9uc1tQX0FMQ09IT0xdKTsKICAgICAgICBpZiAoY29uZGl0aW9uc1tQX0RSSU5LXSkKICAgICAgICAgIGRyaW5rX3NvZnQoY29uZGl0aW9uc1tQX0RSSU5LXSk7CiAgICAgICAgaWYgKGNvbmRpdGlvbnNbUF9GT09EXSkKICAgICAgICAgIGVhdF9mb29kKGNvbmRpdGlvbnNbUF9GT09EXSk7CiAgICAgICAgLy8gVW5kIGpldHp0IGRpZSBXaXJrdW5nZW4KICAgICAgICBpZiAoZWZmZWN0c1tQX1BPSVNPTl0pCiAgICAgICAgICBTZXRQcm9wKFBfUE9JU09OLCBRdWVyeVByb3AoUF9QT0lTT04pICsgZWZmZWN0c1tQX1BPSVNPTl0pOwogICAgICAgIC8vIFVuZCBudW4gd2lya2xpY2ggaGVpbGVuCiAgICAgICAgc3dpdGNoIChjaW5mb1tIX0RJU1RSSUJVVElPTl0pIHsKICAgICAgICBjYXNlIEhEX0lOU1RBTlQ6CiAgICAgICAgICBtYXAoZWZmZWN0cywgKDogU2V0UHJvcCgkMSwgUXVlcnlQcm9wKCQxKSArICQyKSA6KSk7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDEuLjUwOgogICAgICAgICAgYnVmZmVyX2hwKGVmZmVjdHNbUF9IUF0sIGNpbmZvW0hfRElTVFJJQlVUSU9OXSk7CiAgICAgICAgICBidWZmZXJfc3AoZWZmZWN0c1tQX1NQXSwgY2luZm9bSF9ESVNUUklCVVRJT05dKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICBidWZmZXJfaHAoZWZmZWN0c1tQX0hQXSwgSERfU1RBTkRBUkQpOwogICAgICAgICAgYnVmZmVyX3NwKGVmZmVjdHNbUF9TUF0sIEhEX1NUQU5EQVJEKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR2YWwgPSAxOwogICAgfQogIH0KICByZXR1cm4gcmV0dmFsOwp9Cg==