LyogSGVscGVyIGxpYnJhcnkgZm9yIE1TSSBjcmVhdGlvbiB3aXRoIFB5dGhvbi4KICogQ29weXJpZ2h0IChDKSAyMDA1IE1hcnRpbiB2LiBM9ndpcwogKiBMaWNlbnNlZCB0byBQU0YgdW5kZXIgYSBjb250cmlidXRvciBhZ3JlZW1lbnQuCiAqLwoKI2luY2x1ZGUgPFB5dGhvbi5oPgojaW5jbHVkZSA8ZmNpLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8d2luZG93cy5oPgojaW5jbHVkZSA8bXNpLmg+CiNpbmNsdWRlIDxtc2lxdWVyeS5oPgojaW5jbHVkZSA8bXNpZGVmcy5oPgojaW5jbHVkZSA8cnBjLmg+CgpzdGF0aWMgUHlPYmplY3QgKk1TSUVycm9yOwoKc3RhdGljIFB5T2JqZWN0Kgp1dWlkY3JlYXRlKFB5T2JqZWN0KiBvYmosIFB5T2JqZWN0KmFyZ3MpCnsKICAgIFVVSUQgcmVzdWx0OwogICAgY2hhciAqY3Jlc3VsdDsKICAgIFB5T2JqZWN0ICpvcmVzdWx0OwoKICAgIC8qIE1heSByZXR1cm4gb2ssIGxvY2FsIG9ubHksIGFuZCBubyBhZGRyZXNzLgogICAgICAgRm9yIGxvY2FsIG9ubHksIHRoZSBkb2N1bWVudGF0aW9uIHNheXMgd2Ugc3RpbGwgZ2V0IGEgdXVpZC4KICAgICAgIEZvciBSUENfU19VVUlEX05PX0FERFJFU1MsIGl0J3Mgbm90IGNsZWFyIHdoZXRoZXIgd2UgY2FuCiAgICAgICB1c2UgdGhlIHJlc3VsdC4gKi8KICAgIGlmIChVdWlkQ3JlYXRlKCZyZXN1bHQpID09IFJQQ19TX1VVSURfTk9fQUREUkVTUykgewogICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19Ob3RJbXBsZW1lbnRlZEVycm9yLCAicHJvY2Vzc2luZyAnbm8gYWRkcmVzcycgcmVzdWx0Iik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKFV1aWRUb1N0cmluZygmcmVzdWx0LCAmY3Jlc3VsdCkgPT0gUlBDX1NfT1VUX09GX01FTU9SWSkgewogICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19NZW1vcnlFcnJvciwgIm91dCBvZiBtZW1vcnkgaW4gdXVpZGdlbiIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIG9yZXN1bHQgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKGNyZXN1bHQpOwogICAgUnBjU3RyaW5nRnJlZSgmY3Jlc3VsdCk7CiAgICByZXR1cm4gb3Jlc3VsdDsKCn0KCi8qIEZDSSBjYWxsYmFjayBmdW5jdGlvbnMgKi8KCnN0YXRpYyBGTkZDSUFMTE9DKGNiX2FsbG9jKQp7CiAgICByZXR1cm4gbWFsbG9jKGNiKTsKfQoKc3RhdGljIEZORkNJRlJFRShjYl9mcmVlKQp7CiAgICBmcmVlKG1lbW9yeSk7Cn0KCnN0YXRpYyBGTkZDSU9QRU4oY2Jfb3BlbikKewogICAgaW50IHJlc3VsdCA9IF9vcGVuKHBzekZpbGUsIG9mbGFnLCBwbW9kZSk7CiAgICBpZiAocmVzdWx0ID09IC0xKQogICAgICAgICplcnIgPSBlcnJubzsKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBGTkZDSVJFQUQoY2JfcmVhZCkKewogICAgVUlOVCByZXN1bHQgPSAoVUlOVClfcmVhZChoZiwgbWVtb3J5LCBjYik7CiAgICBpZiAocmVzdWx0ICE9IGNiKQogICAgICAgICplcnIgPSBlcnJubzsKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBGTkZDSVdSSVRFKGNiX3dyaXRlKQp7CiAgICBVSU5UIHJlc3VsdCA9IChVSU5UKV93cml0ZShoZiwgbWVtb3J5LCBjYik7CiAgICBpZiAocmVzdWx0ICE9IGNiKQogICAgICAgICplcnIgPSBlcnJubzsKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBGTkZDSUNMT1NFKGNiX2Nsb3NlKQp7CiAgICBpbnQgcmVzdWx0ID0gX2Nsb3NlKGhmKTsKICAgIGlmIChyZXN1bHQgIT0gMCkKICAgICAgICAqZXJyID0gZXJybm87CiAgICByZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgRk5GQ0lTRUVLKGNiX3NlZWspCnsKICAgIGxvbmcgcmVzdWx0ID0gKGxvbmcpX2xzZWVrKGhmLCBkaXN0LCBzZWVrdHlwZSk7CiAgICBpZiAocmVzdWx0ID09IC0xKQogICAgICAgICplcnIgPSBlcnJubzsKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBGTkZDSURFTEVURShjYl9kZWxldGUpCnsKICAgIGludCByZXN1bHQgPSByZW1vdmUocHN6RmlsZSk7CiAgICBpZiAocmVzdWx0ICE9IDApCiAgICAgICAgKmVyciA9IGVycm5vOwogICAgcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIEZORkNJRklMRVBMQUNFRChjYl9maWxlcGxhY2VkKQp7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZORkNJR0VUVEVNUEZJTEUoY2JfZ2V0dGVtcGZpbGUpCnsKICAgIGNoYXIgKm5hbWUgPSBfdGVtcG5hbSgiIiwgInRtcCIpOwogICAgaWYgKChuYW1lICE9IE5VTEwpICYmICgoaW50KXN0cmxlbihuYW1lKSA8IGNiVGVtcE5hbWUpKSB7CiAgICAgICAgc3RyY3B5KHBzelRlbXBOYW1lLCBuYW1lKTsKICAgICAgICBmcmVlKG5hbWUpOwogICAgICAgIHJldHVybiBUUlVFOwogICAgfQoKICAgIGlmIChuYW1lKSBmcmVlKG5hbWUpOwogICAgcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgRk5GQ0lTVEFUVVMoY2Jfc3RhdHVzKQp7CiAgICBpZiAocHYpIHsKICAgICAgICBQeU9iamVjdCAqcmVzdWx0ID0gUHlPYmplY3RfQ2FsbE1ldGhvZChwdiwgInN0YXR1cyIsICJpaWkiLCB0eXBlU3RhdHVzLCBjYjEsIGNiMik7CiAgICAgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIEZORkNJR0VUTkVYVENBQklORVQoY2JfZ2V0bmV4dGNhYmluZXQpCnsKICAgIGlmIChwdikgewogICAgICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBQeU9iamVjdF9DYWxsTWV0aG9kKHB2LCAiZ2V0bmV4dGNhYmluZXQiLCAiaSIsIHBjY2FiLT5pQ2FiKTsKICAgICAgICBpZiAocmVzdWx0ID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKHJlc3VsdCkpIHsKICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKICAgICAgICAgICAgICAgICJJbmNvcnJlY3QgcmV0dXJuIHR5cGUgJXMgZnJvbSBnZXRuZXh0Y2FiaW5ldCIsCiAgICAgICAgICAgICAgICByZXN1bHQtPm9iX3R5cGUtPnRwX25hbWUpOwogICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgICAgICBzdHJuY3B5KHBjY2FiLT5zekNhYiwgUHlTdHJpbmdfQXNTdHJpbmcocmVzdWx0KSwgc2l6ZW9mKHBjY2FiLT5zekNhYikpOwogICAgICAgIHJldHVybiBUUlVFOwogICAgfQogICAgcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgRk5GQ0lHRVRPUEVOSU5GTyhjYl9nZXRvcGVuaW5mbykKewogICAgQllfSEFORExFX0ZJTEVfSU5GT1JNQVRJT04gYmhmaTsKICAgIEZJTEVUSU1FIGZpbGV0aW1lOwogICAgSEFORExFIGhhbmRsZTsKCiAgICAvKiBOZWVkIFdpbjMyIGhhbmRsZSB0byBnZXQgdGltZSBzdGFtcHMgKi8KICAgIGhhbmRsZSA9IENyZWF0ZUZpbGUocHN6TmFtZSwgR0VORVJJQ19SRUFELCBGSUxFX1NIQVJFX1JFQUQsIE5VTEwsCiAgICAgICAgT1BFTl9FWElTVElORywgRklMRV9BVFRSSUJVVEVfTk9STUFMLCBOVUxMKTsKICAgIGlmIChoYW5kbGUgPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpCiAgICAgICAgcmV0dXJuIC0xOwoKICAgIGlmIChHZXRGaWxlSW5mb3JtYXRpb25CeUhhbmRsZShoYW5kbGUsICZiaGZpKSA9PSBGQUxTRSkKICAgIHsKICAgICAgICBDbG9zZUhhbmRsZShoYW5kbGUpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBGaWxlVGltZVRvTG9jYWxGaWxlVGltZSgmYmhmaS5mdExhc3RXcml0ZVRpbWUsICZmaWxldGltZSk7CiAgICBGaWxlVGltZVRvRG9zRGF0ZVRpbWUoJmZpbGV0aW1lLCBwZGF0ZSwgcHRpbWUpOwoKICAgICpwYXR0cmlicyA9IChpbnQpKGJoZmkuZHdGaWxlQXR0cmlidXRlcyAmCiAgICAgICAgKF9BX1JET05MWSB8IF9BX1NZU1RFTSB8IF9BX0hJRERFTiB8IF9BX0FSQ0gpKTsKCiAgICBDbG9zZUhhbmRsZShoYW5kbGUpOwoKICAgIHJldHVybiBfb3Blbihwc3pOYW1lLCBfT19SRE9OTFkgfCBfT19CSU5BUlkpOwp9CgpzdGF0aWMgUHlPYmplY3QqIGZjaWNyZWF0ZShQeU9iamVjdCogb2JqLCBQeU9iamVjdCogYXJncykKewogICAgY2hhciAqY2FibmFtZSwgKnA7CiAgICBQeU9iamVjdCAqZmlsZXM7CiAgICBDQ0FCIGNjYWI7CiAgICBIRkNJIGhmY2k7CiAgICBFUkYgZXJmOwogICAgUHlfc3NpemVfdCBpOwoKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInNPOkZDSUNyZWF0ZSIsICZjYWJuYW1lLCAmZmlsZXMpKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICghUHlMaXN0X0NoZWNrKGZpbGVzKSkgewogICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJGQ0lDcmVhdGUgZXhwZWN0cyBhIGxpc3QiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBjY2FiLmNiID0gSU5UX01BWDsgLyogbm8gbmVlZCB0byBzcGxpdCBDQUIgaW50byBtdWx0aXBsZSBtZWRpYSAqLwogICAgY2NhYi5jYkZvbGRlclRocmVzaCA9IDEwMDAwMDA7IC8qIGZsdXNoIGRpcmVjdG9yeSBhZnRlciB0aGlzIG1hbnkgYnl0ZXMgKi8KICAgIGNjYWIuY2JSZXNlcnZlQ0ZEYXRhID0gMDsKICAgIGNjYWIuY2JSZXNlcnZlQ0ZGb2xkZXIgPSAwOwogICAgY2NhYi5jYlJlc2VydmVDRkhlYWRlciA9IDA7CgogICAgY2NhYi5pQ2FiID0gMTsKICAgIGNjYWIuaURpc2sgPSAxOwoKICAgIGNjYWIuc2V0SUQgPSAwOwogICAgY2NhYi5zekRpc2tbMF0gPSAnXDAnOwoKICAgIGZvciAoaSA9IDAsIHAgPSBjYWJuYW1lOyAqcDsgcCA9IENoYXJOZXh0KHApKQogICAgICAgIGlmICgqcCA9PSAnXFwnIHx8ICpwID09ICcvJykKICAgICAgICAgICAgaSA9IHAgLSBjYWJuYW1lICsgMTsKCiAgICBpZiAoaSA+PSBzaXplb2YoY2NhYi5zekNhYlBhdGgpIHx8CiAgICAgICAgc3RybGVuKGNhYm5hbWUraSkgPj0gc2l6ZW9mKGNjYWIuc3pDYWIpKSB7CiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJwYXRoIG5hbWUgdG9vIGxvbmciKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBpZiAoaSA+IDApIHsKICAgICAgICBtZW1jcHkoY2NhYi5zekNhYlBhdGgsIGNhYm5hbWUsIGkpOwogICAgICAgIGNjYWIuc3pDYWJQYXRoW2ldID0gJ1wwJzsKICAgICAgICBzdHJjcHkoY2NhYi5zekNhYiwgY2FibmFtZStpKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc3RyY3B5KGNjYWIuc3pDYWJQYXRoLCAiLlxcIik7CiAgICAgICAgc3RyY3B5KGNjYWIuc3pDYWIsIGNhYm5hbWUpOwogICAgfQoKICAgIGhmY2kgPSBGQ0lDcmVhdGUoJmVyZiwgY2JfZmlsZXBsYWNlZCwgY2JfYWxsb2MsIGNiX2ZyZWUsCiAgICAgICAgY2Jfb3BlbiwgY2JfcmVhZCwgY2Jfd3JpdGUsIGNiX2Nsb3NlLCBjYl9zZWVrLCBjYl9kZWxldGUsCiAgICAgICAgY2JfZ2V0dGVtcGZpbGUsICZjY2FiLCBOVUxMKTsKCiAgICBpZiAoaGZjaSA9PSBOVUxMKSB7CiAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsICJGQ0kgZXJyb3IgJWQiLCBlcmYuZXJmT3Blcik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgZm9yIChpPTA7IGkgPCBQeUxpc3RfR0VUX1NJWkUoZmlsZXMpOyBpKyspIHsKICAgICAgICBQeU9iamVjdCAqaXRlbSA9IFB5TGlzdF9HRVRfSVRFTShmaWxlcywgaSk7CiAgICAgICAgY2hhciAqZmlsZW5hbWUsICpjYWJuYW1lOwogICAgICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShpdGVtLCAic3MiLCAmZmlsZW5hbWUsICZjYWJuYW1lKSkKICAgICAgICAgICAgZ290byBlcnI7CiAgICAgICAgaWYgKCFGQ0lBZGRGaWxlKGhmY2ksIGZpbGVuYW1lLCBjYWJuYW1lLCBGQUxTRSwKICAgICAgICAgICAgY2JfZ2V0bmV4dGNhYmluZXQsIGNiX3N0YXR1cywgY2JfZ2V0b3BlbmluZm8sCiAgICAgICAgICAgIHRjb21wVFlQRV9NU1pJUCkpCiAgICAgICAgICAgIGdvdG8gZXJyOwogICAgfQoKICAgIGlmICghRkNJRmx1c2hDYWJpbmV0KGhmY2ksIEZBTFNFLCBjYl9nZXRuZXh0Y2FiaW5ldCwgY2Jfc3RhdHVzKSkKICAgICAgICBnb3RvIGVycjsKCiAgICBpZiAoIUZDSURlc3Ryb3koaGZjaSkpCiAgICAgICAgZ290byBlcnI7CgogICAgUHlfSU5DUkVGKFB5X05vbmUpOwogICAgcmV0dXJuIFB5X05vbmU7CmVycjoKICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLCAiRkNJIGVycm9yICVkIiwgZXJmLmVyZk9wZXIpOyAvKiBYWFggYmV0dGVyIGVycm9yIHR5cGUgKi8KICAgIEZDSURlc3Ryb3koaGZjaSk7CiAgICByZXR1cm4gTlVMTDsKfQoKdHlwZWRlZiBzdHJ1Y3QgbXNpb2JqewogICAgUHlPYmplY3RfSEVBRAogICAgTVNJSEFORExFIGg7Cn1tc2lvYmo7CgpzdGF0aWMgdm9pZAptc2lvYmpfZGVhbGxvYyhtc2lvYmoqIG1zaWRiKQp7CiAgICBNc2lDbG9zZUhhbmRsZShtc2lkYi0+aCk7CiAgICBtc2lkYi0+aCA9IDA7Cn0KCnN0YXRpYyBQeU9iamVjdCoKbXNpb2JqX2Nsb3NlKG1zaW9iaiogbXNpZGIsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBNc2lDbG9zZUhhbmRsZShtc2lkYi0+aCk7CiAgICBtc2lkYi0+aCA9IDA7CiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKc3RhdGljIFB5T2JqZWN0Kgptc2llcnJvcihpbnQgc3RhdHVzKQp7CiAgICBpbnQgY29kZTsKICAgIGNoYXIgYnVmWzIwMDBdOwogICAgY2hhciAqcmVzID0gYnVmOwogICAgRFdPUkQgc2l6ZSA9IHNpemVvZihidWYpOwogICAgTVNJSEFORExFIGVyciA9IE1zaUdldExhc3RFcnJvclJlY29yZCgpOwoKICAgIGlmIChlcnIgPT0gMCkgewogICAgICAgIHN3aXRjaChzdGF0dXMpIHsKICAgICAgICBjYXNlIEVSUk9SX0FDQ0VTU19ERU5JRUQ6CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhNU0lFcnJvciwgImFjY2VzcyBkZW5pZWQiKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgY2FzZSBFUlJPUl9GVU5DVElPTl9GQUlMRUQ6CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhNU0lFcnJvciwgImZ1bmN0aW9uIGZhaWxlZCIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICBjYXNlIEVSUk9SX0lOVkFMSURfREFUQToKICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKE1TSUVycm9yLCAiaW52YWxpZCBkYXRhIik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIGNhc2UgRVJST1JfSU5WQUxJRF9IQU5ETEU6CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhNU0lFcnJvciwgImludmFsaWQgaGFuZGxlIik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIGNhc2UgRVJST1JfSU5WQUxJRF9TVEFURToKICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKE1TSUVycm9yLCAiaW52YWxpZCBzdGF0ZSIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICBjYXNlIEVSUk9SX0lOVkFMSURfUEFSQU1FVEVSOgogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoTVNJRXJyb3IsICJpbnZhbGlkIHBhcmFtZXRlciIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBQeUVycl9Gb3JtYXQoTVNJRXJyb3IsICJ1bmtub3duIGVycm9yICV4Iiwgc3RhdHVzKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIGNvZGUgPSBNc2lSZWNvcmRHZXRJbnRlZ2VyKGVyciwgMSk7IC8qIFhYWCBjb2RlICovCiAgICBpZiAoTXNpRm9ybWF0UmVjb3JkKDAsIGVyciwgcmVzLCAmc2l6ZSkgPT0gRVJST1JfTU9SRV9EQVRBKSB7CiAgICAgICAgcmVzID0gbWFsbG9jKHNpemUrMSk7CiAgICAgICAgTXNpRm9ybWF0UmVjb3JkKDAsIGVyciwgcmVzLCAmc2l6ZSk7CiAgICAgICAgcmVzW3NpemVdPSdcMCc7CiAgICB9CiAgICBNc2lDbG9zZUhhbmRsZShlcnIpOwogICAgUHlFcnJfU2V0U3RyaW5nKE1TSUVycm9yLCByZXMpOwogICAgaWYgKHJlcyAhPSBidWYpCiAgICAgICAgZnJlZShyZXMpOwogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKiogUmVjb3JkIG9iamVjdHMgKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBQeU9iamVjdCoKcmVjb3JkX2dldGZpZWxkY291bnQobXNpb2JqKiByZWNvcmQsIFB5T2JqZWN0KiBhcmdzKQp7CiAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoTXNpUmVjb3JkR2V0RmllbGRDb3VudChyZWNvcmQtPmgpKTsKfQoKc3RhdGljIFB5T2JqZWN0KgpyZWNvcmRfZ2V0aW50ZWdlcihtc2lvYmoqIHJlY29yZCwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIHVuc2lnbmVkIGludCBmaWVsZDsKICAgIGludCBzdGF0dXM7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJJOkdldEludGVnZXIiLCAmZmllbGQpKQogICAgICAgIHJldHVybiBOVUxMOwogICAgc3RhdHVzID0gTXNpUmVjb3JkR2V0SW50ZWdlcihyZWNvcmQtPmgsIGZpZWxkKTsKICAgIGlmIChzdGF0dXMgPT0gTVNJX05VTExfSU5URUdFUil7CiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKE1TSUVycm9yLCAiY291bGQgbm90IGNvbnZlcnQgcmVjb3JkIGZpZWxkIHRvIGludGVnZXIiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHJldHVybiBQeUludF9Gcm9tTG9uZygobG9uZykgc3RhdHVzKTsKfQoKc3RhdGljIFB5T2JqZWN0KgpyZWNvcmRfZ2V0c3RyaW5nKG1zaW9iaiogcmVjb3JkLCBQeU9iamVjdCogYXJncykKewogICAgdW5zaWduZWQgaW50IGZpZWxkOwogICAgdW5zaWduZWQgaW50IHN0YXR1czsKICAgIGNoYXIgYnVmWzIwMDBdOwogICAgY2hhciAqcmVzID0gYnVmOwogICAgRFdPUkQgc2l6ZSA9IHNpemVvZihidWYpOwogICAgUHlPYmplY3QqIHN0cmluZzsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIkk6R2V0U3RyaW5nIiwgJmZpZWxkKSkKICAgICAgICByZXR1cm4gTlVMTDsKICAgIHN0YXR1cyA9IE1zaVJlY29yZEdldFN0cmluZyhyZWNvcmQtPmgsIGZpZWxkLCByZXMsICZzaXplKTsKICAgIGlmIChzdGF0dXMgPT0gRVJST1JfTU9SRV9EQVRBKSB7CiAgICAgICAgcmVzID0gKGNoYXIqKSBtYWxsb2Moc2l6ZSArIDEpOwogICAgICAgIGlmIChyZXMgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CiAgICAgICAgc3RhdHVzID0gTXNpUmVjb3JkR2V0U3RyaW5nKHJlY29yZC0+aCwgZmllbGQsIHJlcywgJnNpemUpOwogICAgfQogICAgaWYgKHN0YXR1cyAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBtc2llcnJvcigoaW50KSBzdGF0dXMpOwogICAgc3RyaW5nID0gUHlTdHJpbmdfRnJvbVN0cmluZyhyZXMpOwogICAgaWYgKGJ1ZiAhPSByZXMpCiAgICAgICAgZnJlZShyZXMpOwogICAgcmV0dXJuIHN0cmluZzsKfQoKc3RhdGljIFB5T2JqZWN0KgpyZWNvcmRfY2xlYXJkYXRhKG1zaW9iaiogcmVjb3JkLCBQeU9iamVjdCAqYXJncykKewogICAgaW50IHN0YXR1cyA9IE1zaVJlY29yZENsZWFyRGF0YShyZWNvcmQtPmgpOwogICAgaWYgKHN0YXR1cyAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgpzdGF0aWMgUHlPYmplY3QqCnJlY29yZF9zZXRzdHJpbmcobXNpb2JqKiByZWNvcmQsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwogICAgaW50IGZpZWxkOwogICAgY2hhciAqZGF0YTsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImlzOlNldFN0cmluZyIsICZmaWVsZCwgJmRhdGEpKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICgoc3RhdHVzID0gTXNpUmVjb3JkU2V0U3RyaW5nKHJlY29yZC0+aCwgZmllbGQsIGRhdGEpKSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgpzdGF0aWMgUHlPYmplY3QqCnJlY29yZF9zZXRzdHJlYW0obXNpb2JqKiByZWNvcmQsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwogICAgaW50IGZpZWxkOwogICAgY2hhciAqZGF0YTsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImlzOlNldFN0cmVhbSIsICZmaWVsZCwgJmRhdGEpKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICgoc3RhdHVzID0gTXNpUmVjb3JkU2V0U3RyZWFtKHJlY29yZC0+aCwgZmllbGQsIGRhdGEpKSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgpzdGF0aWMgUHlPYmplY3QqCnJlY29yZF9zZXRpbnRlZ2VyKG1zaW9iaiogcmVjb3JkLCBQeU9iamVjdCAqYXJncykKewogICAgaW50IHN0YXR1czsKICAgIGludCBmaWVsZDsKICAgIGludCBkYXRhOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiaWk6U2V0SW50ZWdlciIsICZmaWVsZCwgJmRhdGEpKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICgoc3RhdHVzID0gTXNpUmVjb3JkU2V0SW50ZWdlcihyZWNvcmQtPmgsIGZpZWxkLCBkYXRhKSkgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgICByZXR1cm4gbXNpZXJyb3Ioc3RhdHVzKTsKCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKCgpzdGF0aWMgUHlNZXRob2REZWYgcmVjb3JkX21ldGhvZHNbXSA9IHsKICAgIHsgIkdldEZpZWxkQ291bnQiLCAoUHlDRnVuY3Rpb24pcmVjb3JkX2dldGZpZWxkY291bnQsIE1FVEhfTk9BUkdTLAogICAgICAgIFB5RG9jX1NUUigiR2V0RmllbGRDb3VudCgpIC0+IGludFxuV3JhcHMgTXNpUmVjb3JkR2V0RmllbGRDb3VudCIpfSwKICAgIHsgIkdldEludGVnZXIiLCAoUHlDRnVuY3Rpb24pcmVjb3JkX2dldGludGVnZXIsIE1FVEhfVkFSQVJHUywKICAgIFB5RG9jX1NUUigiR2V0SW50ZWdlcihmaWVsZCkgLT4gaW50XG5XcmFwcyBNc2lSZWNvcmRHZXRJbnRlZ2VyIil9LAogICAgeyAiR2V0U3RyaW5nIiwgKFB5Q0Z1bmN0aW9uKXJlY29yZF9nZXRzdHJpbmcsIE1FVEhfVkFSQVJHUywKICAgIFB5RG9jX1NUUigiR2V0U3RyaW5nKGZpZWxkKSAtPiBzdHJpbmdcbldyYXBzIE1zaVJlY29yZEdldFN0cmluZyIpfSwKICAgIHsgIlNldFN0cmluZyIsIChQeUNGdW5jdGlvbilyZWNvcmRfc2V0c3RyaW5nLCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJTZXRTdHJpbmcoZmllbGQsc3RyKSAtPiBOb25lXG5XcmFwcyBNc2lSZWNvcmRTZXRTdHJpbmciKX0sCiAgICB7ICJTZXRTdHJlYW0iLCAoUHlDRnVuY3Rpb24pcmVjb3JkX3NldHN0cmVhbSwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiU2V0U3RyZWFtKGZpZWxkLGZpbGVuYW1lKSAtPiBOb25lXG5XcmFwcyBNc2lSZWNvcmRTZXRJbnRlZ2VyIil9LAogICAgeyAiU2V0SW50ZWdlciIsIChQeUNGdW5jdGlvbilyZWNvcmRfc2V0aW50ZWdlciwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiU2V0SW50ZWdlcihmaWVsZCxpbnQpIC0+IE5vbmVcbldyYXBzIE1zaVJlY29yZFNldEludGVnZXIiKX0sCiAgICB7ICJDbGVhckRhdGEiLCAoUHlDRnVuY3Rpb24pcmVjb3JkX2NsZWFyZGF0YSwgTUVUSF9OT0FSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJDbGVhckRhdGEoKSAtPiBpbnRcbldyYXBzIE1zaVJlY29yZEdDbGVhckRhdGEiKX0sCiAgICB7IE5VTEwsIE5VTEwgfQp9OwoKc3RhdGljIFB5VHlwZU9iamVjdCByZWNvcmRfVHlwZSA9IHsKICAgICAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoTlVMTCwgMCkKICAgICAgICAiX21zaS5SZWNvcmQiLCAgICAgICAgICAvKnRwX25hbWUqLwogICAgICAgIHNpemVvZihtc2lvYmopLCAvKnRwX2Jhc2ljc2l6ZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVtc2l6ZSovCiAgICAgICAgLyogbWV0aG9kcyAqLwogICAgICAgIChkZXN0cnVjdG9yKW1zaW9ial9kZWFsbG9jLCAvKnRwX2RlYWxsb2MqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcHJpbnQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZ2V0YXR0ciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9zZXRhdHRyKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2NvbXBhcmUqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcmVwciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19udW1iZXIqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfc2VxdWVuY2UqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfbWFwcGluZyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9oYXNoKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2NhbGwqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfc3RyKi8KICAgICAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwvKnRwX2dldGF0dHJvKi8KICAgICAgICBQeU9iamVjdF9HZW5lcmljU2V0QXR0ciwvKnRwX3NldGF0dHJvKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX2J1ZmZlciovCiAgICAgICAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgLyp0cF9mbGFncyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kb2MqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfdHJhdmVyc2UqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2xlYXIqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcmljaGNvbXBhcmUqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfd2Vha2xpc3RvZmZzZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVybmV4dCovCiAgICAgICAgcmVjb3JkX21ldGhvZHMsICAgICAgICAgICAvKnRwX21ldGhvZHMqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfbWVtYmVycyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9nZXRzZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYmFzZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kaWN0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Rlc2NyX2dldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kZXNjcl9zZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGljdG9mZnNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pbml0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FsbG9jKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX25ldyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9mcmVlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2lzX2djKi8KfTsKCnN0YXRpYyBQeU9iamVjdCoKcmVjb3JkX25ldyhNU0lIQU5ETEUgaCkKewogICAgbXNpb2JqICpyZXN1bHQgPSBQeU9iamVjdF9ORVcoc3RydWN0IG1zaW9iaiwgJnJlY29yZF9UeXBlKTsKCiAgICBpZiAoIXJlc3VsdCkgewogICAgICAgIE1zaUNsb3NlSGFuZGxlKGgpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHJlc3VsdC0+aCA9IGg7CiAgICByZXR1cm4gKFB5T2JqZWN0KilyZXN1bHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKiogU3VtbWFyeUluZm9ybWF0aW9uIG9iamVjdHMgKioqKioqKioqKioqKiovCgpzdGF0aWMgUHlPYmplY3QqCnN1bW1hcnlfZ2V0cHJvcGVydHkobXNpb2JqKiBzaSwgUHlPYmplY3QgKmFyZ3MpCnsKICAgIGludCBzdGF0dXM7CiAgICBpbnQgZmllbGQ7CiAgICBQeU9iamVjdCAqcmVzdWx0OwogICAgVUlOVCB0eXBlOwogICAgSU5UIGl2YWw7CiAgICBGSUxFVElNRSBmdmFsOwogICAgY2hhciBzYnVmWzEwMDBdOwogICAgY2hhciAqc3ZhbCA9IHNidWY7CiAgICBEV09SRCBzc2l6ZSA9IHNpemVvZihzdmFsKTsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImk6R2V0UHJvcGVydHkiLCAmZmllbGQpKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHN0YXR1cyA9IE1zaVN1bW1hcnlJbmZvR2V0UHJvcGVydHkoc2ktPmgsIGZpZWxkLCAmdHlwZSwgJml2YWwsCiAgICAgICAgJmZ2YWwsIHN2YWwsICZzc2l6ZSk7CiAgICBpZiAoc3RhdHVzID09IEVSUk9SX01PUkVfREFUQSkgewogICAgICAgIHN2YWwgPSBtYWxsb2Moc3NpemUpOwogICAgICAgIHN0YXR1cyA9IE1zaVN1bW1hcnlJbmZvR2V0UHJvcGVydHkoc2ktPmgsIGZpZWxkLCAmdHlwZSwgJml2YWwsCiAgICAgICAgICAgICZmdmFsLCBzdmFsLCAmc3NpemUpOwogICAgfQoKICAgIHN3aXRjaCh0eXBlKSB7CiAgICAgICAgY2FzZSBWVF9JMjogY2FzZSBWVF9JNDoKICAgICAgICAgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKGl2YWwpOwogICAgICAgIGNhc2UgVlRfRklMRVRJTUU6CiAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19Ob3RJbXBsZW1lbnRlZEVycm9yLCAiRklMRVRJTUUgcmVzdWx0Iik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIGNhc2UgVlRfTFBTVFI6CiAgICAgICAgICAgIHJlc3VsdCA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKHN2YWwsIHNzaXplKTsKICAgICAgICAgICAgaWYgKHN2YWwgIT0gc2J1ZikKICAgICAgICAgICAgICAgIGZyZWUoc3ZhbCk7CiAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CiAgICB9CiAgICBQeUVycl9Gb3JtYXQoUHlFeGNfTm90SW1wbGVtZW50ZWRFcnJvciwgInJlc3VsdCBvZiB0eXBlICVkIiwgdHlwZSk7CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIFB5T2JqZWN0KgpzdW1tYXJ5X2dldHByb3BlcnR5Y291bnQobXNpb2JqKiBzaSwgUHlPYmplY3QgKmFyZ3MpCnsKICAgIGludCBzdGF0dXM7CiAgICBVSU5UIHJlc3VsdDsKCiAgICBzdGF0dXMgPSBNc2lTdW1tYXJ5SW5mb0dldFByb3BlcnR5Q291bnQoc2ktPmgsICZyZXN1bHQpOwogICAgaWYgKHN0YXR1cyAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhyZXN1bHQpOwp9CgpzdGF0aWMgUHlPYmplY3QqCnN1bW1hcnlfc2V0cHJvcGVydHkobXNpb2JqKiBzaSwgUHlPYmplY3QgKmFyZ3MpCnsKICAgIGludCBzdGF0dXM7CiAgICBpbnQgZmllbGQ7CiAgICBQeU9iamVjdCogZGF0YTsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImlPOlNldFByb3BlcnR5IiwgJmZpZWxkLCAmZGF0YSkpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKFB5U3RyaW5nX0NoZWNrKGRhdGEpKSB7CiAgICAgICAgc3RhdHVzID0gTXNpU3VtbWFyeUluZm9TZXRQcm9wZXJ0eShzaS0+aCwgZmllbGQsIFZUX0xQU1RSLAogICAgICAgICAgICAwLCBOVUxMLCBQeVN0cmluZ19Bc1N0cmluZyhkYXRhKSk7CiAgICB9IGVsc2UgaWYgKFB5SW50X0NoZWNrKGRhdGEpKSB7CiAgICAgICAgc3RhdHVzID0gTXNpU3VtbWFyeUluZm9TZXRQcm9wZXJ0eShzaS0+aCwgZmllbGQsIFZUX0k0LAogICAgICAgICAgICBQeUludF9Bc0xvbmcoZGF0YSksIE5VTEwsIE5VTEwpOwogICAgfSBlbHNlIHsKICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAidW5zdXBwb3J0ZWQgdHlwZSIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmIChzdGF0dXMgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgICByZXR1cm4gbXNpZXJyb3Ioc3RhdHVzKTsKCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKCnN0YXRpYyBQeU9iamVjdCoKc3VtbWFyeV9wZXJzaXN0KG1zaW9iaiogc2ksIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwoKICAgIHN0YXR1cyA9IE1zaVN1bW1hcnlJbmZvUGVyc2lzdChzaS0+aCk7CiAgICBpZiAoc3RhdHVzICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIG1zaWVycm9yKHN0YXR1cyk7CiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKc3RhdGljIFB5TWV0aG9kRGVmIHN1bW1hcnlfbWV0aG9kc1tdID0gewogICAgeyAiR2V0UHJvcGVydHkiLCAoUHlDRnVuY3Rpb24pc3VtbWFyeV9nZXRwcm9wZXJ0eSwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiR2V0UHJvcGVydHkocHJvcGlkKSAtPiB2YWx1ZVxuV3JhcHMgTXNpU3VtbWFyeUluZm9HZXRQcm9wZXJ0eSIpfSwKICAgIHsgIkdldFByb3BlcnR5Q291bnQiLCAoUHlDRnVuY3Rpb24pc3VtbWFyeV9nZXRwcm9wZXJ0eWNvdW50LCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkdldFByb3BlcnR5KCkgLT4gaW50XG5XcmFwcyBNc2lTdW1tYXJ5SW5mb0dldFByb3BlcnR5Q291bnQiKX0sCiAgICB7ICJTZXRQcm9wZXJ0eSIsIChQeUNGdW5jdGlvbilzdW1tYXJ5X3NldHByb3BlcnR5LCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJTZXRQcm9wZXJ0eSh2YWx1ZSkgLT4gTm9uZVxuV3JhcHMgTXNpU3VtbWFyeUluZm9Qcm9wZXJ0eSIpfSwKICAgIHsgIlBlcnNpc3QiLCAoUHlDRnVuY3Rpb24pc3VtbWFyeV9wZXJzaXN0LCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIlBlcnNpc3QoKSAtPiBOb25lXG5XcmFwcyBNc2lTdW1tYXJ5SW5mb1BlcnNpc3QiKX0sCiAgICB7IE5VTEwsIE5VTEwgfQp9OwoKc3RhdGljIFB5VHlwZU9iamVjdCBzdW1tYXJ5X1R5cGUgPSB7CiAgICAgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKE5VTEwsIDApCiAgICAgICAgIl9tc2kuU3VtbWFyeUluZm9ybWF0aW9uIiwgICAgICAgICAgICAgIC8qdHBfbmFtZSovCiAgICAgICAgc2l6ZW9mKG1zaW9iaiksIC8qdHBfYmFzaWNzaXplKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2l0ZW1zaXplKi8KICAgICAgICAvKiBtZXRob2RzICovCiAgICAgICAgKGRlc3RydWN0b3IpbXNpb2JqX2RlYWxsb2MsIC8qdHBfZGVhbGxvYyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9wcmludCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9nZXRhdHRyKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX3NldGF0dHIqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY29tcGFyZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9yZXByKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX251bWJlciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19zZXF1ZW5jZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19tYXBwaW5nKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2hhc2gqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2FsbCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9zdHIqLwogICAgICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLC8qdHBfZ2V0YXR0cm8qLwogICAgICAgIFB5T2JqZWN0X0dlbmVyaWNTZXRBdHRyLC8qdHBfc2V0YXR0cm8qLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfYnVmZmVyKi8KICAgICAgICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAvKnRwX2ZsYWdzKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RvYyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF90cmF2ZXJzZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9jbGVhciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9yaWNoY29tcGFyZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF93ZWFrbGlzdG9mZnNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVyKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2l0ZXJuZXh0Ki8KICAgICAgICBzdW1tYXJ5X21ldGhvZHMsICAgICAgICAvKnRwX21ldGhvZHMqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfbWVtYmVycyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9nZXRzZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYmFzZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kaWN0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Rlc2NyX2dldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kZXNjcl9zZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGljdG9mZnNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pbml0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FsbG9jKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX25ldyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9mcmVlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2lzX2djKi8KfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKiogVmlldyBvYmplY3RzICoqKioqKioqKioqKioqLwoKc3RhdGljIFB5T2JqZWN0Kgp2aWV3X2V4ZWN1dGUobXNpb2JqICp2aWV3LCBQeU9iamVjdCphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwogICAgTVNJSEFORExFIHBhcmFtcyA9IDA7CiAgICBQeU9iamVjdCAqb3BhcmFtcyA9IFB5X05vbmU7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPOkV4ZWN1dGUiLCAmb3BhcmFtcykpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKG9wYXJhbXMgIT0gUHlfTm9uZSkgewogICAgICAgIGlmIChvcGFyYW1zLT5vYl90eXBlICE9ICZyZWNvcmRfVHlwZSkgewogICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiRXhlY3V0ZSBhcmd1bWVudCBtdXN0IGJlIGEgcmVjb3JkIik7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICBwYXJhbXMgPSAoKG1zaW9iaiopb3BhcmFtcyktPmg7CiAgICB9CgogICAgc3RhdHVzID0gTXNpVmlld0V4ZWN1dGUodmlldy0+aCwgcGFyYW1zKTsKICAgIGlmIChzdGF0dXMgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgICByZXR1cm4gbXNpZXJyb3Ioc3RhdHVzKTsKCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKc3RhdGljIFB5T2JqZWN0Kgp2aWV3X2ZldGNoKG1zaW9iaiAqdmlldywgUHlPYmplY3QqYXJncykKewogICAgaW50IHN0YXR1czsKICAgIE1TSUhBTkRMRSByZXN1bHQ7CgogICAgaWYgKChzdGF0dXMgPSBNc2lWaWV3RmV0Y2godmlldy0+aCwgJnJlc3VsdCkpICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIG1zaWVycm9yKHN0YXR1cyk7CgogICAgcmV0dXJuIHJlY29yZF9uZXcocmVzdWx0KTsKfQoKc3RhdGljIFB5T2JqZWN0Kgp2aWV3X2dldGNvbHVtbmluZm8obXNpb2JqICp2aWV3LCBQeU9iamVjdCAqYXJncykKewogICAgaW50IHN0YXR1czsKICAgIGludCBraW5kOwogICAgTVNJSEFORExFIHJlc3VsdDsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgImk6R2V0Q29sdW1uSW5mbyIsICZraW5kKSkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBpZiAoKHN0YXR1cyA9IE1zaVZpZXdHZXRDb2x1bW5JbmZvKHZpZXctPmgsIGtpbmQsICZyZXN1bHQpKSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIHJldHVybiByZWNvcmRfbmV3KHJlc3VsdCk7Cn0KCnN0YXRpYyBQeU9iamVjdCoKdmlld19tb2RpZnkobXNpb2JqICp2aWV3LCBQeU9iamVjdCAqYXJncykKewogICAgaW50IGtpbmQ7CiAgICBQeU9iamVjdCAqZGF0YTsKICAgIGludCBzdGF0dXM7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJpTzpNb2RpZnkiLCAma2luZCwgJmRhdGEpKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmIChkYXRhLT5vYl90eXBlICE9ICZyZWNvcmRfVHlwZSkgewogICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJNb2RpZnkgZXhwZWN0cyBhIHJlY29yZCBvYmplY3QiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoKHN0YXR1cyA9IE1zaVZpZXdNb2RpZnkodmlldy0+aCwga2luZCwgKChtc2lvYmoqKWRhdGEpLT5oKSkgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgICByZXR1cm4gbXNpZXJyb3Ioc3RhdHVzKTsKCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKc3RhdGljIFB5T2JqZWN0Kgp2aWV3X2Nsb3NlKG1zaW9iaiAqdmlldywgUHlPYmplY3QqYXJncykKewogICAgaW50IHN0YXR1czsKCiAgICBpZiAoKHN0YXR1cyA9IE1zaVZpZXdDbG9zZSh2aWV3LT5oKSkgIT0gRVJST1JfU1VDQ0VTUykKICAgICAgICByZXR1cm4gbXNpZXJyb3Ioc3RhdHVzKTsKCiAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CiAgICByZXR1cm4gUHlfTm9uZTsKfQoKc3RhdGljIFB5TWV0aG9kRGVmIHZpZXdfbWV0aG9kc1tdID0gewogICAgeyAiRXhlY3V0ZSIsIChQeUNGdW5jdGlvbil2aWV3X2V4ZWN1dGUsIE1FVEhfVkFSQVJHUywKICAgICAgICBQeURvY19TVFIoIkV4ZWN1dGUocGFyYW1zPU5vbmUpIC0+IE5vbmVcbldyYXBzIE1zaVZpZXdFeGVjdXRlIil9LAogICAgeyAiR2V0Q29sdW1uSW5mbyIsIChQeUNGdW5jdGlvbil2aWV3X2dldGNvbHVtbmluZm8sIE1FVEhfVkFSQVJHUywKICAgICAgICBQeURvY19TVFIoIkdldENvbHVtbkluZm8oKSAtPiByZXN1bHRcbldyYXBzIE1zaUdldENvbHVtbkluZm8iKX0sCiAgICB7ICJGZXRjaCIsIChQeUNGdW5jdGlvbil2aWV3X2ZldGNoLCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkZldGNoKCkgLT4gcmVzdWx0XG5XcmFwcyBNc2lWaWV3RmV0Y2giKX0sCiAgICB7ICJNb2RpZnkiLCAoUHlDRnVuY3Rpb24pdmlld19tb2RpZnksIE1FVEhfVkFSQVJHUywKICAgICAgICBQeURvY19TVFIoIk1vZGlmeShtb2RlLHJlY29yZCkgLT4gTm9uZVxuV3JhcHMgTXNpVmlld01vZGlmeSIpfSwKICAgIHsgIkNsb3NlIiwgKFB5Q0Z1bmN0aW9uKXZpZXdfY2xvc2UsIE1FVEhfTk9BUkdTLAogICAgICAgIFB5RG9jX1NUUigiQ2xvc2UoKSAtPiByZXN1bHRcbldyYXBzIE1zaVZpZXdDbG9zZSIpfSwKICAgIHsgTlVMTCwgTlVMTCB9Cn07CgpzdGF0aWMgUHlUeXBlT2JqZWN0IG1zaXZpZXdfVHlwZSA9IHsKICAgICAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoTlVMTCwgMCkKICAgICAgICAiX21zaS5WaWV3IiwgICAgICAgICAgICAvKnRwX25hbWUqLwogICAgICAgIHNpemVvZihtc2lvYmopLCAvKnRwX2Jhc2ljc2l6ZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVtc2l6ZSovCiAgICAgICAgLyogbWV0aG9kcyAqLwogICAgICAgIChkZXN0cnVjdG9yKW1zaW9ial9kZWFsbG9jLCAvKnRwX2RlYWxsb2MqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcHJpbnQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZ2V0YXR0ciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9zZXRhdHRyKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2NvbXBhcmUqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcmVwciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19udW1iZXIqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfc2VxdWVuY2UqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfbWFwcGluZyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9oYXNoKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2NhbGwqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfc3RyKi8KICAgICAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwvKnRwX2dldGF0dHJvKi8KICAgICAgICBQeU9iamVjdF9HZW5lcmljU2V0QXR0ciwvKnRwX3NldGF0dHJvKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX2J1ZmZlciovCiAgICAgICAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgLyp0cF9mbGFncyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kb2MqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfdHJhdmVyc2UqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2xlYXIqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcmljaGNvbXBhcmUqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfd2Vha2xpc3RvZmZzZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVybmV4dCovCiAgICAgICAgdmlld19tZXRob2RzLCAgICAgICAgICAgLyp0cF9tZXRob2RzKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX21lbWJlcnMqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZ2V0c2V0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Jhc2UqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGljdCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kZXNjcl9nZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGVzY3Jfc2V0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RpY3RvZmZzZXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaW5pdCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hbGxvYyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9uZXcqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZnJlZSovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pc19nYyovCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqIERhdGFiYXNlIG9iamVjdHMgKioqKioqKioqKioqKiovCgpzdGF0aWMgUHlPYmplY3QqCm1zaWRiX29wZW52aWV3KG1zaW9iaiAqbXNpZGIsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwogICAgY2hhciAqc3FsOwogICAgTVNJSEFORExFIGhWaWV3OwogICAgbXNpb2JqICpyZXN1bHQ7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJzOk9wZW5WaWV3IiwgJnNxbCkpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgaWYgKChzdGF0dXMgPSBNc2lEYXRhYmFzZU9wZW5WaWV3KG1zaWRiLT5oLCBzcWwsICZoVmlldykpICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIG1zaWVycm9yKHN0YXR1cyk7CgogICAgcmVzdWx0ID0gUHlPYmplY3RfTkVXKHN0cnVjdCBtc2lvYmosICZtc2l2aWV3X1R5cGUpOwogICAgaWYgKCFyZXN1bHQpIHsKICAgICAgICBNc2lDbG9zZUhhbmRsZShoVmlldyk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmVzdWx0LT5oID0gaFZpZXc7CiAgICByZXR1cm4gKFB5T2JqZWN0KilyZXN1bHQ7Cn0KCnN0YXRpYyBQeU9iamVjdCoKbXNpZGJfY29tbWl0KG1zaW9iaiAqbXNpZGIsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBpbnQgc3RhdHVzOwoKICAgIGlmICgoc3RhdHVzID0gTXNpRGF0YWJhc2VDb21taXQobXNpZGItPmgpKSAhPSBFUlJPUl9TVUNDRVNTKQogICAgICAgIHJldHVybiBtc2llcnJvcihzdGF0dXMpOwoKICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKICAgIHJldHVybiBQeV9Ob25lOwp9CgpzdGF0aWMgUHlPYmplY3QqCm1zaWRiX2dldHN1bW1hcnlpbmZvcm1hdGlvbihtc2lvYmogKmRiLCBQeU9iamVjdCAqYXJncykKewogICAgaW50IHN0YXR1czsKICAgIGludCBjb3VudDsKICAgIE1TSUhBTkRMRSByZXN1bHQ7CiAgICBtc2lvYmogKm9yZXN1bHQ7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJpOkdldFN1bW1hcnlJbmZvcm1hdGlvbiIsICZjb3VudCkpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgc3RhdHVzID0gTXNpR2V0U3VtbWFyeUluZm9ybWF0aW9uKGRiLT5oLCBOVUxMLCBjb3VudCwgJnJlc3VsdCk7CiAgICBpZiAoc3RhdHVzICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIG1zaWVycm9yKHN0YXR1cyk7CgogICAgb3Jlc3VsdCA9IFB5T2JqZWN0X05FVyhzdHJ1Y3QgbXNpb2JqLCAmc3VtbWFyeV9UeXBlKTsKICAgIGlmICghcmVzdWx0KSB7CiAgICAgICAgTXNpQ2xvc2VIYW5kbGUocmVzdWx0KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBvcmVzdWx0LT5oID0gcmVzdWx0OwogICAgcmV0dXJuIChQeU9iamVjdCopb3Jlc3VsdDsKfQoKc3RhdGljIFB5TWV0aG9kRGVmIGRiX21ldGhvZHNbXSA9IHsKICAgIHsgIk9wZW5WaWV3IiwgKFB5Q0Z1bmN0aW9uKW1zaWRiX29wZW52aWV3LCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJPcGVuVmlldyhzcWwpIC0+IHZpZXdvYmpcbldyYXBzIE1zaURhdGFiYXNlT3BlblZpZXciKX0sCiAgICB7ICJDb21taXQiLCAoUHlDRnVuY3Rpb24pbXNpZGJfY29tbWl0LCBNRVRIX05PQVJHUywKICAgICAgICBQeURvY19TVFIoIkNvbW1pdCgpIC0+IE5vbmVcbldyYXBzIE1zaURhdGFiYXNlQ29tbWl0Iil9LAogICAgeyAiR2V0U3VtbWFyeUluZm9ybWF0aW9uIiwgKFB5Q0Z1bmN0aW9uKW1zaWRiX2dldHN1bW1hcnlpbmZvcm1hdGlvbiwgTUVUSF9WQVJBUkdTLAogICAgICAgIFB5RG9jX1NUUigiR2V0U3VtbWFyeUluZm9ybWF0aW9uKHVwZGF0ZUNvdW50KSAtPiB2aWV3b2JqXG5XcmFwcyBNc2lHZXRTdW1tYXJ5SW5mb3JtYXRpb24iKX0sCiAgICB7IE5VTEwsIE5VTEwgfQp9OwoKc3RhdGljIFB5VHlwZU9iamVjdCBtc2lkYl9UeXBlID0gewogICAgICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVChOVUxMLCAwKQogICAgICAgICJfbXNpLkRhdGFiYXNlIiwgICAgICAgICAgICAgICAgLyp0cF9uYW1lKi8KICAgICAgICBzaXplb2YobXNpb2JqKSwgLyp0cF9iYXNpY3NpemUqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlbXNpemUqLwogICAgICAgIC8qIG1ldGhvZHMgKi8KICAgICAgICAoZGVzdHJ1Y3Rvciltc2lvYmpfZGVhbGxvYywgLyp0cF9kZWFsbG9jKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX3ByaW50Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2dldGF0dHIqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfc2V0YXR0ciovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9jb21wYXJlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX3JlcHIqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfbnVtYmVyKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX3NlcXVlbmNlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX21hcHBpbmcqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaGFzaCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9jYWxsKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX3N0ciovCiAgICAgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsLyp0cF9nZXRhdHRybyovCiAgICAgICAgUHlPYmplY3RfR2VuZXJpY1NldEF0dHIsLyp0cF9zZXRhdHRybyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19idWZmZXIqLwogICAgICAgIFB5X1RQRkxBR1NfREVGQVVMVCwgICAgIC8qdHBfZmxhZ3MqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZG9jKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX3RyYXZlcnNlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2NsZWFyKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX3JpY2hjb21wYXJlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX3dlYWtsaXN0b2Zmc2V0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2l0ZXIqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlcm5leHQqLwogICAgICAgIGRiX21ldGhvZHMsICAgICAgICAgICAgIC8qdHBfbWV0aG9kcyovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9tZW1iZXJzKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2dldHNldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9iYXNlKi8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RpY3QqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGVzY3JfZ2V0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Rlc2NyX3NldCovCiAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kaWN0b2Zmc2V0Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2luaXQqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYWxsb2MqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfbmV3Ki8KICAgICAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2ZyZWUqLwogICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXNfZ2MqLwp9OwoKI2RlZmluZSBQeV9OT1RfUEVSU0lTVCh4LCBmbGFnKSAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgICh4ICE9IChpbnQpKGZsYWcpICYmICAgICAgICAgICAgICAgICAgICAgIFwKICAgIHggIT0gKChpbnQpKGZsYWcpIHwgTVNJREJPUEVOX1BBVENIRklMRSkpCgojZGVmaW5lIFB5X0lOVkFMSURfUEVSU0lTVCh4KSAgICAgICAgICAgICAgICBcCiAgICAoUHlfTk9UX1BFUlNJU1QoeCwgTVNJREJPUEVOX1JFQURPTkxZKSAmJiAgXAogICAgUHlfTk9UX1BFUlNJU1QoeCwgTVNJREJPUEVOX1RSQU5TQUNUKSAmJiAgIFwKICAgIFB5X05PVF9QRVJTSVNUKHgsIE1TSURCT1BFTl9ESVJFQ1QpICYmICAgICBcCiAgICBQeV9OT1RfUEVSU0lTVCh4LCBNU0lEQk9QRU5fQ1JFQVRFKSAmJiAgICAgXAogICAgUHlfTk9UX1BFUlNJU1QoeCwgTVNJREJPUEVOX0NSRUFURURJUkVDVCkpCgpzdGF0aWMgUHlPYmplY3QqIG1zaW9wZW5kYihQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqYXJncykKewogICAgaW50IHN0YXR1czsKICAgIGNoYXIgKnBhdGg7CiAgICBpbnQgcGVyc2lzdDsKICAgIE1TSUhBTkRMRSBoOwogICAgbXNpb2JqICpyZXN1bHQ7CiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInNpOk1TSU9wZW5EYXRhYmFzZSIsICZwYXRoLCAmcGVyc2lzdCkpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAvKiBXZSBuZWVkIHRvIHZhbGlkYXRlIHRoYXQgcGVyc2lzdCBpcyBhIHZhbGlkIE1TSURCT1BFTl8qIHZhbHVlLiBPdGhlcndpc2UsCiAgICAgICBNc2lPcGVuRGF0YWJhc2UgbWF5IHRyZWF0IHRoZSB2YWx1ZSBhcyBhIHBvaW50ZXIsIGxlYWRpbmcgdG8gdW5leHBlY3RlZAogICAgICAgYmVoYXZpb3IuICovCiAgICBpZiAoUHlfSU5WQUxJRF9QRVJTSVNUKHBlcnNpc3QpKQogICAgICAgIHJldHVybiBtc2llcnJvcihFUlJPUl9JTlZBTElEX1BBUkFNRVRFUik7CiAgICBzdGF0dXMgPSBNc2lPcGVuRGF0YWJhc2UocGF0aCwgKExQQ1NUUilwZXJzaXN0LCAmaCk7CiAgICBpZiAoc3RhdHVzICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIG1zaWVycm9yKHN0YXR1cyk7CgogICAgcmVzdWx0ID0gUHlPYmplY3RfTkVXKHN0cnVjdCBtc2lvYmosICZtc2lkYl9UeXBlKTsKICAgIGlmICghcmVzdWx0KSB7CiAgICAgICAgTXNpQ2xvc2VIYW5kbGUoaCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICByZXN1bHQtPmggPSBoOwogICAgcmV0dXJuIChQeU9iamVjdCopcmVzdWx0Owp9CgpzdGF0aWMgUHlPYmplY3QqCmNyZWF0ZXJlY29yZChQeU9iamVjdCAqbywgUHlPYmplY3QgKmFyZ3MpCnsKICAgIGludCBjb3VudDsKICAgIE1TSUhBTkRMRSBoOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiaTpDcmVhdGVSZWNvcmQiLCAmY291bnQpKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGggPSBNc2lDcmVhdGVSZWNvcmQoY291bnQpOwogICAgaWYgKGggPT0gMCkKICAgICAgICByZXR1cm4gbXNpZXJyb3IoMCk7CgogICAgcmV0dXJuIHJlY29yZF9uZXcoaCk7Cn0KCgpzdGF0aWMgUHlNZXRob2REZWYgbXNpX21ldGhvZHNbXSA9IHsKICAgICAgICB7IlV1aWRDcmVhdGUiLCAoUHlDRnVuY3Rpb24pdXVpZGNyZWF0ZSwgTUVUSF9OT0FSR1MsCiAgICAgICAgICAgICAgICBQeURvY19TVFIoIlV1aWRDcmVhdGUoKSAtPiBzdHJpbmciKX0sCiAgICAgICAgeyJGQ0lDcmVhdGUiLCAgIChQeUNGdW5jdGlvbilmY2ljcmVhdGUsIE1FVEhfVkFSQVJHUywKICAgICAgICAgICAgICAgIFB5RG9jX1NUUigiZmNpY3JlYXRlKGNhYm5hbWUsZmlsZXMpIC0+IE5vbmUiKX0sCiAgICAgICAgeyJPcGVuRGF0YWJhc2UiLCAoUHlDRnVuY3Rpb24pbXNpb3BlbmRiLCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJPcGVuRGF0YWJhc2UobmFtZSwgZmxhZ3MpIC0+IGRib2JqXG5XcmFwcyBNc2lPcGVuRGF0YWJhc2UiKX0sCiAgICAgICAgeyJDcmVhdGVSZWNvcmQiLCAoUHlDRnVuY3Rpb24pY3JlYXRlcmVjb3JkLCBNRVRIX1ZBUkFSR1MsCiAgICAgICAgUHlEb2NfU1RSKCJPcGVuRGF0YWJhc2UobmFtZSwgZmxhZ3MpIC0+IGRib2JqXG5XcmFwcyBNc2lDcmVhdGVSZWNvcmQiKX0sCiAgICAgICAge05VTEwsICAgICAgICAgIE5VTEx9ICAgICAgICAgICAvKiBzZW50aW5lbCAqLwp9OwoKc3RhdGljIGNoYXIgbXNpX2RvY1tdID0gIkRvY3VtZW50YXRpb24iOwoKUHlNT0RJTklUX0ZVTkMKaW5pdF9tc2kodm9pZCkKewogICAgUHlPYmplY3QgKm07CgogICAgbSA9IFB5X0luaXRNb2R1bGUzKCJfbXNpIiwgbXNpX21ldGhvZHMsIG1zaV9kb2MpOwogICAgaWYgKG0gPT0gTlVMTCkKICAgICAgICByZXR1cm47CgogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSURCT1BFTl9DUkVBVEVESVJFQ1QiLCAoaW50KU1TSURCT1BFTl9DUkVBVEVESVJFQ1QpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSURCT1BFTl9DUkVBVEUiLCAoaW50KU1TSURCT1BFTl9DUkVBVEUpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSURCT1BFTl9ESVJFQ1QiLCAoaW50KU1TSURCT1BFTl9ESVJFQ1QpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSURCT1BFTl9SRUFET05MWSIsIChpbnQpTVNJREJPUEVOX1JFQURPTkxZKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJNU0lEQk9QRU5fVFJBTlNBQ1QiLCAoaW50KU1TSURCT1BFTl9UUkFOU0FDVCk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiTVNJREJPUEVOX1BBVENIRklMRSIsIChpbnQpTVNJREJPUEVOX1BBVENIRklMRSk7CgogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSUNPTElORk9fTkFNRVMiLCBNU0lDT0xJTkZPX05BTUVTKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJNU0lDT0xJTkZPX1RZUEVTIiwgTVNJQ09MSU5GT19UWVBFUyk7CgogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9TRUVLIiwgTVNJTU9ESUZZX1NFRUspOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9SRUZSRVNIIiwgTVNJTU9ESUZZX1JFRlJFU0gpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9JTlNFUlQiLCBNU0lNT0RJRllfSU5TRVJUKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJNU0lNT0RJRllfVVBEQVRFIiwgTVNJTU9ESUZZX1VQREFURSk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiTVNJTU9ESUZZX0FTU0lHTiIsIE1TSU1PRElGWV9BU1NJR04pOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9SRVBMQUNFIiwgTVNJTU9ESUZZX1JFUExBQ0UpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9NRVJHRSIsIE1TSU1PRElGWV9NRVJHRSk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiTVNJTU9ESUZZX0RFTEVURSIsIE1TSU1PRElGWV9ERUxFVEUpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9JTlNFUlRfVEVNUE9SQVJZIiwgTVNJTU9ESUZZX0lOU0VSVF9URU1QT1JBUlkpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9WQUxJREFURSIsIE1TSU1PRElGWV9WQUxJREFURSk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiTVNJTU9ESUZZX1ZBTElEQVRFX05FVyIsIE1TSU1PRElGWV9WQUxJREFURV9ORVcpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIk1TSU1PRElGWV9WQUxJREFURV9GSUVMRCIsIE1TSU1PRElGWV9WQUxJREFURV9GSUVMRCk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiTVNJTU9ESUZZX1ZBTElEQVRFX0RFTEVURSIsIE1TSU1PRElGWV9WQUxJREFURV9ERUxFVEUpOwoKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfQ09ERVBBR0UiLCBQSURfQ09ERVBBR0UpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9USVRMRSIsIFBJRF9USVRMRSk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiUElEX1NVQkpFQ1QiLCBQSURfU1VCSkVDVCk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiUElEX0FVVEhPUiIsIFBJRF9BVVRIT1IpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9LRVlXT1JEUyIsIFBJRF9LRVlXT1JEUyk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiUElEX0NPTU1FTlRTIiwgUElEX0NPTU1FTlRTKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfVEVNUExBVEUiLCBQSURfVEVNUExBVEUpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9MQVNUQVVUSE9SIiwgUElEX0xBU1RBVVRIT1IpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9SRVZOVU1CRVIiLCBQSURfUkVWTlVNQkVSKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfTEFTVFBSSU5URUQiLCBQSURfTEFTVFBSSU5URUQpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9DUkVBVEVfRFRNIiwgUElEX0NSRUFURV9EVE0pOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9MQVNUU0FWRV9EVE0iLCBQSURfTEFTVFNBVkVfRFRNKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfUEFHRUNPVU5UIiwgUElEX1BBR0VDT1VOVCk7CiAgICBQeU1vZHVsZV9BZGRJbnRDb25zdGFudChtLCAiUElEX1dPUkRDT1VOVCIsIFBJRF9XT1JEQ09VTlQpOwogICAgUHlNb2R1bGVfQWRkSW50Q29uc3RhbnQobSwgIlBJRF9DSEFSQ09VTlQiLCBQSURfQ0hBUkNPVU5UKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfQVBQTkFNRSIsIFBJRF9BUFBOQU1FKTsKICAgIFB5TW9kdWxlX0FkZEludENvbnN0YW50KG0sICJQSURfU0VDVVJJVFkiLCBQSURfU0VDVVJJVFkpOwoKICAgIE1TSUVycm9yID0gUHlFcnJfTmV3RXhjZXB0aW9uICgiX21zaS5NU0lFcnJvciIsIE5VTEwsIE5VTEwpOwogICAgaWYgKCFNU0lFcnJvcikKICAgICAgICByZXR1cm47CiAgICBQeU1vZHVsZV9BZGRPYmplY3QobSwgIk1TSUVycm9yIiwgTVNJRXJyb3IpOwp9Cg==