LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgoqCiogICBDb3B5cmlnaHQgKEMpIDE5OTktMjAwMCwgSW50ZXJuYXRpb25hbCBCdXNpbmVzcyBNYWNoaW5lcwoqICAgQ29ycG9yYXRpb24gYW5kIG90aGVycy4gIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCioKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLy8KLy8gdWNvbnYgZGVtb25zdHJhdGlvbiBleGFtcGxlIG9mIElDVSBhbmQgY29kZXBhZ2UgY29udmVyc2lvbgovLyBQdXJwb3NlIGlzIHRvIGJlIGEgc2ltaWxhciB0b29sIGFzIHRoZSBVTklYIGljb252IHByb2dyYW0uCi8vCi8vIFVzYWdlOiB1Y29udiBbZmxhZ10gW2ZpbGVdCi8vIC1mIFtjb2Rlc2V0XSAgQ29udmVydCBmaWxlIGZyb20gdGhpcyBjb2Rlc2V0Ci8vIC10IFtjb2Rlc2V0XSAgQ29udmVydCBmaWxlIHRvIHRoaXMgY29kZSBzZXQKLy8gLWwgICAgICAgICAgICBEaXNwbGF5IGFsbCBhdmFpbGFibGUgY29udmVydGVycwovLyAteCBbdHJhbnNsaXRlcmF0b3JdICBSdW4gZXZlcnl0aGluZyB0aHJvdWdoIGEgdHJhbnNsaXRlcmF0b3IKLy8gLUwgICAgICAgICAgICBEaXNwbGF5IGFsbCBhdmFpbGFibGUgdHJhbnNsaXRlcmF0b3JzCi8vIElmIG5vIGZpbGUgaXMgZ2l2ZW4sIHVjb252IHRyaWVzIHRvIHJlYWQgZnJvbSBzdGRpbgovLyAKLy8gVG8gY29tcGlsZTogYysrIC1vIHVjb252IC1JJHtJQ1VIT01FfS9pbmNsdWRlIC1XYWxsIC1nIHVjb252LmNwcCAtTCR7SUNVSE9NRX0vbGliIC1saWN1LXVjIC1saWN1LWkxOG4KLy8KLy8gT3JpZ2luYWwgY29udHJpYnV0b3Igd2FzIEpvbmFzIFV0dGVyc3Ry9m0gPGpvbmFzLnV0dGVyc3Ryb21Adml0dHJhbi5ub3Jybm9kLnNlPiBpbiAxOTk5Ci8vIFBlcm1pc3Npb24gaXMgZ3JhbnRlZCB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZQovLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNpbmNsdWRlICJjbWVtb3J5LmgiCgovLyBUaGlzIGlzIHRoZSBVbmljb2RlQ29udmVydGVyIGhlYWRlcmZpbGUKI2luY2x1ZGUgInVuaWNvZGUvY29udmVydC5oIgoKLy8gVGhpcyBpcyB0aGUgVW5pY29kZVN0cmluZyBoZWFkZXJmaWxlCiNpbmNsdWRlICJ1bmljb2RlL3VuaXN0ci5oIgoKLy8gT3VyIG1lc3NhZ2UgcHJpbnRlci4uCiNpbmNsdWRlICJ1bmljb2RlL3V3bXNnLmgiCgojaWZkZWYgV0lOMzIKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8aW8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNlbmRpZgoKI2lmZGVmIFVTRV9UUkFOU0xJVAojIGluY2x1ZGUgInVuaWNvZGUvdHJhbnNsaXQuaCIKI2VuZGlmCgpzdGF0aWMgY29uc3Qgc2l6ZV90IGJ1ZmZzaXplID0gNDA5NjsKCnN0YXRpYyBVUmVzb3VyY2VCdW5kbGUgKmdCdW5kbGUgPSAwOwoKc3RhdGljIHZvaWQgaW5pdE1zZyhjb25zdCBjaGFyICpwbmFtZSkgewogICAgc3RhdGljIGludCBwcyA9IDA7CgogICAgaWYgKCFwcykgewogICAgICAgIGNoYXIgZGF0YVBhdGhbNTAwXTsKICAgICAgICBVRXJyb3JDb2RlIGVyciA9IFVfWkVST19FUlJPUjsKCiAgICAgICAgcHMgPSAxOwoKICAgICAgICAvKiBHZXQgbWVzc2FnZXMuICovCiAgICAgICAgCiAgICAgICAgc3RyY3B5KGRhdGFQYXRoLCB1X2dldERhdGFEaXJlY3RvcnkoKSk7CiAgICAgICAgc3RyY2F0KGRhdGFQYXRoLCAidWNvbnZtc2ciKTsKICAgICAgICAKICAgICAgICBnQnVuZGxlID0gdV93bXNnX3NldFBhdGgoZGF0YVBhdGgsICZlcnIpOwogICAgICAgIGlmKFVfRkFJTFVSRShlcnIpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIiVzOiB3YXJuaW5nOiBjb3VsZG4ndCBvcGVuIHJlc291cmNlIGJ1bmRsZSAlczogJXNcbiIsIAogICAgICAgICAgICAgICAgICAgICAgICBwbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVBhdGgsCiAgICAgICAgICAgICAgICAgICAgICAgIHVfZXJyb3JOYW1lKGVycikpOwogICAgICAgICAgICB9CiAgICB9Cn0KCi8vIFByaW50IGFsbCBhdmFpbGFibGUgY29kZXBhZ2UgY29udmVydGVycwpzdGF0aWMgaW50IHByaW50QWxsQ29udmVydGVycyhjb25zdCBjaGFyICpwbmFtZSwgaW50IGNhbm9uKQp7CiAgICBVRXJyb3JDb2RlIGVyciA9IFVfWkVST19FUlJPUjsKICAgIGludDMyX3QgbnVtID0gdWNudl9jb3VudEF2YWlsYWJsZSgpOwogICAgdWludDE2X3QgbnVtX3N0ZHMgPSB1Y252X2NvdW50U3RhbmRhcmRzKCk7CiAgICBjb25zdCBjaGFyICoqIHN0ZHMgPSAoY29uc3QgY2hhciAqKikgdXBydl9tYWxsb2MobnVtX3N0ZHMgKiBzaXplb2YoKnN0ZHMpKTsKCiAgICBpZiAoIXN0ZHMpIHsKICAgICAgdV93bXNnKCJjYW50R2V0VGFnIiwgdV93bXNnX2Vycm9yTmFtZShVX01FTU9SWV9BTExPQ0FUSU9OX0VSUk9SKSk7CiAgICAgIHJldHVybiAtMTsKICAgIH0gZWxzZSB7CiAgICAgICAgdWludDE2X3QgczsKCiAgICAgICAgZm9yIChzID0gMDsgcyA8IG51bV9zdGRzOyArK3MpIHsKICAgICAgICAgICAgc3Rkc1tzXSA9IHVjbnZfZ2V0U3RhbmRhcmQocywgJmVycik7CiAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgICAgICAgICAgdV93bXNnKCJjYW50R2V0VGFnIiwgdV93bXNnX2Vycm9yTmFtZShlcnIpKTsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiNpZiAwCiAgICBzaXplX3QgbnVtcHJpbnQgPSAwOwogICAgc3RhdGljIGNvbnN0IHNpemVfdCBtYXhsaW5lID0gNzA7CiNlbmRpZgoKICAgIGlmIChudW0gPD0gMCkKICAgIHsKICAgICAgaW5pdE1zZyhwbmFtZSk7ICAgCiAgICAgIHVfd21zZygiY2FudEdldE5hbWVzIik7CiAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBmb3IgKGludDMyX3QgaSA9IDA7IGk8bnVtOyBpKyspCiAgICB7CiAgICAgICAgLy8gdWNudl9nZXRBdmFpbGFibGVOYW1lIGdldHMgdGhlIGNvZGVwYWdlIG5hbWUgYXQgYSBzcGVjaWZpYwogICAgICAgIC8vIGluZGV4CgogICAgICAgIGNvbnN0IGNoYXIgKm5hbWUgPSB1Y252X2dldEF2YWlsYWJsZU5hbWUoaSk7CiAgICAgICAgdWludDE2X3QgbnVtX2FsaWFzZXM7CgojaWYgMAogICAgICAgIG51bXByaW50ICs9IHByaW50ZigiJS0yMHMiLCBuYW1lKTsKICAgICAgICBpZiAobnVtcHJpbnQ+bWF4bGluZSkKICAgICAgICB7CiAgICAgICAgICAgIHB1dGNoYXIoJ1xuJyk7CiAgICAgICAgICAgIG51bXByaW50ID0gMDsKICAgICAgICB9CiNlbHNlCiAgICAgICAgZXJyID0gVV9aRVJPX0VSUk9SOwogICAgICAgIG51bV9hbGlhc2VzID0gdWNudl9jb3VudEFsaWFzZXMobmFtZSwgJmVycik7CiAgICAgICAgaWYgKFVfRkFJTFVSRShlcnIpKSB7CiAgICAgICAgICAgIHByaW50ZigiJXMiLCBuYW1lKTsKCiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKG5hbWUpOwogICAgICAgICAgICBwdXRjaGFyKCdcdCcpOwogICAgICAgICAgICB1X3dtc2coImNhbnRHZXRBbGlhc2VzIiwgc3RyLmdldEJ1ZmZlcigpLCB1X3dtc2dfZXJyb3JOYW1lKGVycikpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdWludDE2X3QgYSwgcywgdDsKICAgICAgICAgICAgCiAgICAgICAgICAgIGZvciAoYSA9IDA7IGEgPCBudW1fYWxpYXNlczsgKythKSB7CiAgICAgICAgICAgICAgICBjb25zdCBjaGFyICphbGlhcyA9IHVjbnZfZ2V0QWxpYXMobmFtZSwgYSwgJmVycik7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKG5hbWUpOwogICAgICAgICAgICAgICAgICAgIHB1dGNoYXIoJ1x0Jyk7CiAgICAgICAgICAgICAgICAgICAgdV93bXNnKCJjYW50R2V0QWxpYXNlcyIsIHN0ci5nZXRCdWZmZXIoKSwgdV93bXNnX2Vycm9yTmFtZShlcnIpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIHByaW50ZigiJXMiLCBhbGlhcyk7CiAgICAgICAgIAogICAgICAgICAgICAgICAgLyogTG9vayAoc2xvd2x5KSBmb3IgYSB0YWcuICovCgogICAgICAgICAgICAgICAgaWYgKGNhbm9uKSB7CiAgICAgICAgICAgICAgICAgICAgZm9yIChzID0gdCA9IDA7IHMgPCBudW1fc3RkczsgKytzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnN0YW5kYXJkID0gdWNudl9nZXRTdGFuZGFyZE5hbWUobmFtZSwgc3Rkc1tzXSwgJmVycik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChVX1NVQ0NFU1MoZXJyKSAmJiBzdGFuZGFyZCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFzdHJjbXAoc3RhbmRhcmQsIGFsaWFzKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludGYoIiB7Iik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQgPSAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludGYoIiAlcyIsIHN0ZHNbc10pOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiIH0iKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyogTW92ZSBvbi4gKi8KCiAgICAgICAgICAgICAgICBpZiAoYSA8IG51bV9hbGlhc2VzIC0gMSkgewogICAgICAgICAgICAgICAgICAgIHB1dGNoYXIoYSB8fCAhY2Fub24gPyAnICcgOiAnXHQnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoY2Fub24pIHsKICAgICAgICAgICAgcHV0Y2hhcignXG4nKTsKICAgICAgICB9IGVsc2UgaWYgKGkgPCBudW0gLSAxKSB7CiAgICAgICAgICAgIHB1dGNoYXIoJyAnKTsKICAgICAgICB9IAoKI2VuZGlmCiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCi8vIENvbnZlcnQgYSBmaWxlIGZyb20gb25lIGVuY29kaW5nIHRvIGFub3RoZXIKc3RhdGljIFVCb29sIGNvbnZlcnRGaWxlKGNvbnN0IGNoYXIqIGZyb21jcGFnZSwgCiAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdG9jcGFnZSwgCiAgICAgICAgICAgICAgICAgRklMRSogaW5maWxlLCAKICAgICAgICAgICAgICAgICBGSUxFKiBvdXRmaWxlKQp7CiAgVUJvb2wgcmV0ID0gVFJVRTsKICAgIFVuaWNvZGVDb252ZXJ0ZXIqIGNvbnZmcm9tID0gMDsKICAgIFVuaWNvZGVDb252ZXJ0ZXIqIGNvbnZ0byA9IDA7CiAgICBVRXJyb3JDb2RlIGVyciA9IFVfWkVST19FUlJPUjsKICAgIFVCb29sICBmbHVzaDsKICAgIGNvbnN0IGNoYXIqIGNidWZmaXRlcjsKICAgIGNoYXIqIGJ1ZmZpdGVyOwogICAgY29uc3Qgc2l6ZV90IHJlYWRzaXplID0gYnVmZnNpemUtMTsKICAgIGNoYXIqIGJ1ZmYgPSAwOwoKICAgIGNvbnN0IFVDaGFyKiBjdW5paXRlcjsKICAgIFVDaGFyKiB1bmlpdGVyOwogICAgVUNoYXIqIHVuaWJ1ZmYgPSAwOwoKICAgIHNpemVfdCByZCwgdG90YnVmZnNpemU7CgojaWYgVVNFX1RSQU5TTElUCiAgICBjb25zdCBjaGFyICp0cmFuc2xpdDsKCiAgICBUcmFuc2xpdGVyYXRvciAqdCA9IE5VTEw7CgogICAgdHJhbnNsaXQgPSBnZXRlbnYoIlRSQU5TTElUIik7CiAgICBpZih0cmFuc2xpdCAhPSBOVUxMICYmICp0cmFuc2xpdCkKICAgICAgewogICAgICAgIHQgPSBUcmFuc2xpdGVyYXRvcjo6Y3JlYXRlSW5zdGFuY2UoVW5pY29kZVN0cmluZyh0cmFuc2xpdCwgIiIpKTsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIk9wZW5pbmcgdHJhbnNsaXRlcmF0b3I6ICVzXG4iLCB0cmFuc2xpdCwgdCk7CiAgICAgIH0KI2VuZGlmCgogICAgLy8gQ3JlYXRlIGNvZGVwYWdlIGNvbnZlcnRlci4gSWYgdGhlIGNvZGVwYWdlIG9yIGl0cyBhbGlhc2VzIHdlcmVuJ3QKICAgIC8vIGF2YWlsYWJsZSwgaXQgcmV0dXJucyBOVUxMIGFuZCBhIGZhaWx1cmUgY29kZQogICAgY29udmZyb20gPSBuZXcgVW5pY29kZUNvbnZlcnRlcihmcm9tY3BhZ2UsIGVycik7CiAgICBpZiAoVV9GQUlMVVJFKGVycikpCiAgICB7CiAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKGZyb21jcGFnZSwiIik7CiAgICAgIHVfd21zZygiY2FudE9wZW5Gcm9tQ29kZXNldCIsc3RyLmdldEJ1ZmZlcigpLAogICAgICAgICAgICAgdV93bXNnX2Vycm9yTmFtZShlcnIpKTsKICAgICAgZ290byBlcnJvcl9leGl0OwogICAgfQoKICAgIGNvbnZ0byA9IG5ldyBVbmljb2RlQ29udmVydGVyKHRvY3BhZ2UsIGVycik7CgogICAgaWYgKFVfRkFJTFVSRShlcnIpKQogICAgewogICAgICBVbmljb2RlU3RyaW5nIHN0cih0b2NwYWdlLCIiKTsKICAgICAgdV93bXNnKCJjYW50T3BlblRvQ29kZXNldCIsc3RyLmdldEJ1ZmZlcigpLAogICAgICAgICAgICAgdV93bXNnX2Vycm9yTmFtZShlcnIpKTsKICAgICAgZ290byBlcnJvcl9leGl0OwogICAgfQoKICAgIC8vIFRvIGVuc3VyZSB0aGF0IHRoZSBidWZmZXIgYWx3YXlzIGlzIG9mIGVub3VnaCBzaXplLCB3ZQogICAgLy8gbXVzdCB0YWtlIHRoZSB3b3JzdCBjYXNlIHNjZW5hcmlvLCB0aGF0IGlzIHRoZSBjaGFyYWN0ZXIgaW4gdGhlIGNvZGVwYWdlCiAgICAvLyB0aGF0IHVzZXMgdGhlIG1vc3QgYnl0ZXMgYW5kIG11bHRpcGx5IGl0IGFnYWluc3QgdGhlIGJ1ZmZzaXplCiAgICB0b3RidWZmc2l6ZSA9IGJ1ZmZzaXplKmNvbnZ0by0+Z2V0TWF4Qnl0ZXNQZXJDaGFyKCk7CiAgICBidWZmID0gbmV3IGNoYXJbdG90YnVmZnNpemVdOwogICAgdW5pYnVmZiA9IG5ldyBVQ2hhcltidWZmc2l6ZV07CiAgICAgICAgCiAgICBkbyAgCiAgICB7CiAgICAgICAgcmQgPSBmcmVhZChidWZmLCAxLCByZWFkc2l6ZSwgaW5maWxlKTsKICAgICAgICBpZiAoZmVycm9yKGluZmlsZSkgIT0gMCkKICAgICAgICB7CiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKHN0cmVycm9yKGVycm5vKSwgIiIpOwogICAgICAgICAgICB1X3dtc2coImNhbnRSZWFkIixzdHIuZ2V0QnVmZmVyKCkpOwogICAgICAgICAgICBnb3RvIGVycm9yX2V4aXQ7CiAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAvLyBDb252ZXJ0IHRoZSByZWFkIGJ1ZmZlciBpbnRvIHRoZSBuZXcgY29kaW5nCiAgICAgICAgLy8gQWZ0ZXIgdGhlIGNhbGwgJ3VuaWl0ZXInIHdpbGwgYmUgcGxhY2VkIG9uIHRoZSBsYXN0IGNoYXJhY3RlciB0aGF0IHdhcyBjb252ZXJ0ZWQKICAgICAgICAvLyBpbiB0aGUgJ3VuaWJ1ZmYnLiAKICAgICAgICAvLyBBbHNvIHRoZSAnY2J1ZmZpdGVyJyBpcyBwb3NpdGlvbmVkIG9uIHRoZSBsYXN0IGNvbnZlcnRlZCBjaGFyYWN0ZXIuCiAgICAgICAgLy8gQXQgdGhlIGxhc3QgY29udmVyc2lvbiBpbiB0aGUgZmlsZSwgZmx1c2ggc2hvdWxkIGJlIHNldCB0byB0cnVlIHNvIHRoYXQKICAgICAgICAvLyB3ZSBnZXQgYWxsIGNoYXJhY3RlcnMgY29udmVydGVkCiAgICAgICAgLy8KICAgICAgICAvLyBUaGUgY29udmVydGVyIG11c3QgYmUgZmx1c2hlZCBhdCB0aGUgZW5kIG9mIGNvbnZlcnNpb24gc28gdGhhdCBjaGFyYWN0ZXJzCiAgICAgICAgLy8gb24gaG9sZCBhbHNvIHdpbGwgYmUgd3JpdHRlbgogICAgICAgIHVuaWl0ZXIgPSB1bmlidWZmOwogICAgICAgIGNidWZmaXRlciA9IGJ1ZmY7CiAgICAgICAgZmx1c2ggPSByZCE9cmVhZHNpemU7ICAgICAgICAKICAgICAgICBjb252ZnJvbS0+dG9Vbmljb2RlKHVuaWl0ZXIsIHVuaWl0ZXIrYnVmZnNpemUsIGNidWZmaXRlciwgY2J1ZmZpdGVyK3JkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIGZsdXNoLCBlcnIpOwogICAgICAgICAgICAKICAgICAgICBpZiAoVV9GQUlMVVJFKGVycikpCiAgICAgICAgewogICAgICAgICAgICB1X3dtc2coInByb2JsZW1DdnRUb1UiLCB1X3dtc2dfZXJyb3JOYW1lKGVycikpOwogICAgICAgICAgICBnb3RvIGVycm9yX2V4aXQ7CiAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAvLyBBdCB0aGUgbGFzdCBjb252ZXJzaW9uLCB0aGUgY29udmVydGVkIGNoYXJhY3RlcnMgc2hvdWxkIGJlIGVxdWFsIHRvIG51bWJlcgogICAgICAgIC8vIG9mIGNoYXJzIHJlYWQuCiAgICAgICAgaWYgKGZsdXNoICYmIGNidWZmaXRlciE9KGJ1ZmYrcmQpKQogICAgICAgIHsKICAgICAgICAgICAgdV93bXNnKCJwcmVtRW5kSW5wdXQiKTsKICAgICAgICAgICAgZ290byBlcnJvcl9leGl0OwogICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgLy8gQ29udmVydCB0aGUgVW5pY29kZSBidWZmZXIgaW50byB0aGUgZGVzdGluYXRpb24gY29kZXBhZ2UKICAgICAgICAvLyBBZ2FpbiAnYnVmZml0ZXInIHdpbGwgYmUgcGxhY2VkIG9uIHRoZSBsYXN0IGNvbnZlcnRlZCBjaGFyYWN0ZXIKICAgICAgICAvLyBBbmQgJ2N1bmlpdGVyJyB3aWxsIGJlIHBsYWNlZCBvbiB0aGUgbGFzdCBjb252ZXJ0ZWQgdW5pY29kZSBjaGFyYWN0ZXIKICAgICAgICAvLyBBdCB0aGUgbGFzdCBjb252ZXJzaW9uIGZsdXNoIHNob3VsZCBiZSBzZXQgdG8gdHJ1ZSB0byBlbnN1cmUgdGhhdCAKICAgICAgICAvLyBhbGwgY2hhcmFjdGVycyBsZWZ0IGdldCBjb252ZXJ0ZWQKCiAgICAgICAgVW5pY29kZVN0cmluZyB1KHVuaWJ1ZmYsIHVuaWl0ZXItdW5pYnVmZik7CiAgICAgICAgYnVmZml0ZXIgPSBidWZmOwogICAgICAgIGN1bmlpdGVyID0gdW5pYnVmZjsKCiNpZmRlZiBVU0VfVFJBTlNMSVQKICAgICAgICBpZih0KSAKICAgICAgICAgIHsKICAgICAgICAgICAgdC0+dHJhbnNsaXRlcmF0ZSh1KTsKICAgICAgICAgICAgdS5leHRyYWN0KDAsIHUubGVuZ3RoKCksIHVuaWJ1ZmYsIDApOwogICAgICAgICAgICB1bmlpdGVyID0gdW5pYnVmZiArIHUubGVuZ3RoKCk7CiAgICAgICAgICAgIAogICAgICAgICAgfQojZW5kaWYKCiAgICAgICAgY29udnRvLT5mcm9tVW5pY29kZShidWZmaXRlciwgYnVmZml0ZXIrdG90YnVmZnNpemUsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBjdW5paXRlciwgY3VuaWl0ZXIrKHNpemVfdCkodW5paXRlci11bmlidWZmKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgZmx1c2gsIGVycik7CiAgICAgICAgICAgIAogICAgICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkKICAgICAgICB7CiAgICAgICAgICAgdV93bXNnKCJwcm9ibGVtQ3Z0RnJvbVUiLCB1X3dtc2dfZXJyb3JOYW1lKGVycikpOwogICAgICAgICAgIGdvdG8gZXJyb3JfZXhpdDsKICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgIC8vIEF0IHRoZSBsYXN0IGNvbnZlcnNpb24sIHRoZSBjb252ZXJ0ZWQgY2hhcmFjdGVycyBzaG91bGQgYmUgZXF1YWwgdG8gbnVtYmVyCiAgICAgICAgLy8gb2YgY29uc3VtZWQgY2hhcmFjdGVycy4KICAgICAgICBpZiAoZmx1c2ggJiYgY3VuaWl0ZXIhPSh1bmlidWZmKyhzaXplX3QpKHVuaWl0ZXItdW5pYnVmZikpKQogICAgICAgIHsKICAgICAgICAgIHVfd21zZygicHJlbUVuZCIpOwogICAgICAgICAgZ290byBlcnJvcl9leGl0OwogICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgLy8gRmluYWxseSwgd3JpdGUgdGhlIGNvbnZlcnRlZCBidWZmZXIgdG8gdGhlIG91dHB1dCBmaWxlCiAgICAgICAgcmQgPSAgKHNpemVfdCkoYnVmZml0ZXItYnVmZik7CiAgICAgICAgaWYgKGZ3cml0ZShidWZmLCAxLCByZCwgb3V0ZmlsZSkgIT0gcmQpCiAgICAgICAgewogICAgICAgICAgVW5pY29kZVN0cmluZyBzdHIoc3RyZXJyb3IoZXJybm8pLCIiKTsKICAgICAgICAgIHVfd21zZygiY2FudFdyaXRlIiwgc3RyLmdldEJ1ZmZlcigpKTsKICAgICAgICAgICAgZ290byBlcnJvcl9leGl0OwogICAgICAgIH0KICAgICAgICAKICAgIH0gd2hpbGUgKCFmbHVzaCk7IC8vIFN0b3Agd2hlbiB3ZSBoYXZlIGZsdXNoZWQgdGhlIGNvbnZlcnRlcnMgKHRoaXMgbWVhbnMgdGhhdCBpdCdzIHRoZSBlbmQgb2Ygb3V0cHV0KQoKICAgIGdvdG8gbm9ybWFsX2V4aXQ7CiAgZXJyb3JfZXhpdDoKICAgIHJldCA9IFRSVUU7CiAgbm9ybWFsX2V4aXQ6CiAgICBpZiAoY29udmZyb20pIGRlbGV0ZSBjb252ZnJvbTsKICAgIGlmIChjb252dG8pIGRlbGV0ZSBjb252dG87CgojaWZkZWYgVVNFX1RSQU5TTElUCiAgICBpZiAoIHQgKSBkZWxldGUgdDsKI2VuZGlmCgogICAgLy8gQ2xvc2UgdGhlIGNyZWF0ZWQgY29udmVydGVycwogICAgaWYgKGJ1ZmYpIGRlbGV0ZSBbXSBidWZmOwogICAgaWYgKHVuaWJ1ZmYpIGRlbGV0ZSBbXSB1bmlidWZmOwogICAgcmV0dXJuIHJldDsKfQoKc3RhdGljIHZvaWQgdXNhZ2UoY29uc3QgY2hhciAqcG5hbWUsIGludCBlY29kZSkKewogIGNvbnN0IFVDaGFyICptc2c7CiAgaW50MzJfdCAgICAgIG1zZ0xlbjsKICBVRXJyb3JDb2RlICBlcnIgPSBVX1pFUk9fRVJST1I7CiAgIAogIGluaXRNc2cocG5hbWUpOwogIG1zZyA9IHVyZXNfZ2V0U3RyaW5nQnlLZXkoZ0J1bmRsZSwgZWNvZGUgPyAibGNVc2FnZVdvcmQiIDogInVjVXNhZ2VXb3JkIiwgJm1zZ0xlbiwgJmVycik7CiAgVW5pY29kZVN0cmluZyB1cG5hbWUocG5hbWUpOwogIFVuaWNvZGVTdHJpbmcgbW5hbWUobXNnLCBtc2dMZW4pOwoKICB1X3dtc2coInVzYWdlIiwgbW5hbWUuZ2V0QnVmZmVyKCksIHVwbmFtZS5nZXRCdWZmZXIoKSk7CiAgaWYgKCFlY29kZSkgewogICAgcHV0Y2hhcignXG4nKTsKICAgIHVfd21zZygiaGVscCIpOwogIH0KCiAgZXhpdChlY29kZSk7Cn0KCmludCBtYWluKGludCBhcmdjLCBjaGFyKiogYXJndikKewogICAgRklMRSogZmlsZSA9IDA7CiAgICBGSUxFKiBpbmZpbGU7CiAgICBpbnQgICByZXQgPSAwOwogICAgY29uc3QgY2hhciogZnJvbWNwYWdlID0gMDsKICAgIGNvbnN0IGNoYXIqIHRvY3BhZ2UgPSAwOwogICAgY29uc3QgY2hhciogaW5maWxlc3RyID0gMDsKCiAgICBjaGFyKiogaXRlciA9IGFyZ3YrMTsKICAgIGNoYXIqKiBlbmQgPSBhcmd2K2FyZ2M7ICAgIAoKICAgIGNvbnN0IGNoYXIgKnBuYW1lID0gKmFyZ3Y7CgogICAgaW50IHByaW50Q29udnMgPSAwLCBwcmludENhbm9uID0gMDsKCiAgICAvLyBGaXJzdCwgZ2V0IHRoZSBhcmd1bWVudHMgZnJvbSBjb21tYW5kLWxpbmUKICAgIC8vIHRvIGtub3cgdGhlIGNvZGVwYWdlcyB0byBjb252ZXJ0IGJldHdlZW4KICAgIGZvciAoOyBpdGVyIT1lbmQ7IGl0ZXIrKykKICAgIHsKICAgICAgICAvLyBDaGVjayBmb3IgZnJvbSBjaGFyc2V0CiAgICAgICAgaWYgKHN0cmNtcCgiLWYiLCAqaXRlcikgPT0gMCB8fCAhc3RyY21wKCItLWZyb20tY29kZSIsICppdGVyKSkKICAgICAgICB7CiAgICAgICAgICAgIGl0ZXIrKzsKICAgICAgICAgICAgaWYgKGl0ZXIhPWVuZCkKICAgICAgICAgICAgICAgIGZyb21jcGFnZSA9ICppdGVyOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzdHJjbXAoIi10IiwgKml0ZXIpID09IDAgfHwgIXN0cmNtcCgiLS10by1jb2RlIiwgKml0ZXIpKQogICAgICAgIHsKICAgICAgICAgICAgaXRlcisrOwogICAgICAgICAgICBpZiAoaXRlciE9ZW5kKQogICAgICAgICAgICAgICAgdG9jcGFnZSA9ICppdGVyOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChzdHJjbXAoIi1sIiwgKml0ZXIpID09IDAgfHwgIXN0cmNtcCgiLS1saXN0IiwgKml0ZXIpKQogICAgICAgIHsKICAgICAgICAgICAgcHJpbnRDb252cyA9IDE7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKHN0cmNtcCgiLWMiLCAqaXRlcikgPT0gMCkgewogICAgICAgICAgICBwcmludENhbm9uID0gMTsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoc3RyY21wKCItaCIsICppdGVyKSA9PSAwIHx8ICFzdHJjbXAoIi0/IiwgKml0ZXIpfHwgIXN0cmNtcCgiLS1oZWxwIiwgKml0ZXIpKQogICAgICAgIHsKICAgICAgICAgICAgdXNhZ2UocG5hbWUsIDApOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmICgqKml0ZXIgPT0gJy0nICYmICgqaXRlcilbMV0pIHsKICAgICAgICAgICAgdXNhZ2UocG5hbWUsIDEpOwogICAgICAgIH0gZWxzZSBpZiAoIWluZmlsZXN0cikgewogICAgICAgICAgICBpbmZpbGVzdHIgPSAqaXRlcjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChwcmludENvbnZzKSB7CiAgICAgICAgcmV0dXJuIHByaW50QWxsQ29udmVydGVycyhwbmFtZSwgcHJpbnRDYW5vbikgPyAyIDogMDsKICAgIH0KCiAgICBpZiAoZnJvbWNwYWdlPT0wICYmIHRvY3BhZ2U9PTApCiAgICB7CiAgICAgICAgdXNhZ2UocG5hbWUsIDEpOwogICAgfQoKICAgIGlmIChmcm9tY3BhZ2U9PTApCiAgICB7CiAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICB1X3dtc2coIm5vRnJvbUNvZGVzZXQiKTsKICAgICAgLy8iTm8gY29udmVyc2lvbiBmcm9tIGNvZGVzZXQgZ2l2ZW4gKHVzZSAtZilcbiIpOwogICAgICAgIGdvdG8gZXJyb3JfZXhpdDsKICAgIH0KICAgIGlmICh0b2NwYWdlPT0wKQogICAgewogICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgdV93bXNnKCJub1RvQ29kZXNldCIpOwogICAgICAvLyAiTm8gY29udmVyc2lvbiB0byBjb2Rlc2V0IGdpdmVuICh1c2UgLXQpXG4iKTsKICAgICAgZ290byBlcnJvcl9leGl0OwogICAgfQoKICAgIC8vIE9wZW4gdGhlIGNvcnJlY3QgaW5wdXQgZmlsZSBvciBjb25uZWN0IHRvIHN0ZGluIGZvciByZWFkaW5nIGlucHV0CiAgICBpZiAoaW5maWxlc3RyIT0wICYmIHN0cmNtcChpbmZpbGVzdHIsICItIikpCiAgICB7CiAgICAgICAgZmlsZSA9IGZvcGVuKGluZmlsZXN0ciwgInJiIik7CiAgICAgICAgaWYgKGZpbGU9PTApCiAgICAgICAgewogICAgICAgICAgVW5pY29kZVN0cmluZyBzdHIxKGluZmlsZXN0ciwiIik7CiAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cjIoc3RyZXJyb3IoZXJybm8pLCIiKTsKICAgICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgICAgdV93bXNnKCJjYW50T3BlbklucHV0RiIsIAogICAgICAgICAgICAgICAgIHN0cjEuZ2V0QnVmZmVyKCksCiAgICAgICAgICAgICAgICAgc3RyMi5nZXRCdWZmZXIoKSk7CiAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgaW5maWxlID0gZmlsZTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGluZmlsZSA9IHN0ZGluOwojaWZkZWYgV0lOMzIKICAgICAgICBpZiggc2V0bW9kZSggZmlsZW5vICggc3RkaW4gKSwgT19CSU5BUlkgKSA9PSAtMSApIHsKICAgICAgICAgICAgICAgIHBlcnJvciAoICJDYW5ub3Qgc2V0IHN0ZGluIHRvIGJpbmFyeSBtb2RlIiApOwogICAgICAgICAgICAgICAgZXhpdCgtMSk7CiAgICAgICAgfQojZW5kaWYKICAgIH0KI2lmZGVmIFdJTjMyCiAgaWYoIHNldG1vZGUoIGZpbGVubyAoIHN0ZG91dCApLCBPX0JJTkFSWSApID09IC0xICkgewogICAgICAgICAgcGVycm9yICggIkNhbm5vdCBzZXQgc3Rkb3V0IHRvIGJpbmFyeSBtb2RlIiApOwogICAgICAgICAgZXhpdCgtMSk7CiAgfQojZW5kaWYKICAgIGlmICghY29udmVydEZpbGUoZnJvbWNwYWdlLCB0b2NwYWdlLCBpbmZpbGUsIHN0ZG91dCkpCiAgICAgICAgZ290byBlcnJvcl9leGl0OwoKICAgIGdvdG8gbm9ybWFsX2V4aXQ7CiAgZXJyb3JfZXhpdDoKICAgIHJldCA9IDE7CiAgbm9ybWFsX2V4aXQ6CgogICAgaWYgKGZpbGUhPTApCiAgICAgICAgZmNsb3NlKGZpbGUpOwogICAgcmV0dXJuIHJldDsKfQoKCi8qCiAqIEhleSwgRW1hY3MsIHBsZWFzZSBzZXQgdGhlIGZvbGxvd2luZzoKICoKICogTG9jYWwgVmFyaWFibGVzOgogKiBpbmRlbnQtdGFicy1tb2RlOiBuaWwKICogRW5kOgogKgogKi8K