LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAzIE1pa2UgSGVhcm4KICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqIENvcHlyaWdodCAyMDA2IENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2ludGVybmwuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgoKI2luY2x1ZGUgInJwYy5oIgojaW5jbHVkZSAicnBjbmRyLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgInJwY19iaW5kaW5nLmgiCiNpbmNsdWRlICJycGNfYXNzb2MuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKHJwYyk7CgpMUFNUUiBSUENSVDRfc3RybmR1cEEoTFBDU1RSIHNyYywgSU5UIHNsZW4pCnsKICBEV09SRCBsZW47CiAgTFBTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgaWYgKHNsZW4gPT0gLTEpIHNsZW4gPSBzdHJsZW4oc3JjKTsKICBsZW4gPSBzbGVuOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKzEpOwogIG1lbWNweShzLCBzcmMsIGxlbik7CiAgc1tsZW5dID0gMDsKICByZXR1cm4gczsKfQoKTFBTVFIgUlBDUlQ0X3N0cmR1cFd0b0EoTFBDV1NUUiBzcmMpCnsKICBEV09SRCBsZW47CiAgTFBTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3JjLCAtMSwgcywgbGVuLCBOVUxMLCBOVUxMKTsKICByZXR1cm4gczsKfQoKTFBXU1RSIFJQQ1JUNF9zdHJkdXBBdG9XKExQQ1NUUiBzcmMpCnsKICBEV09SRCBsZW47CiAgTFBXU1RSIHM7CiAgaWYgKCFzcmMpIHJldHVybiBOVUxMOwogIGxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzcmMsIC0xLCBOVUxMLCAwKTsKICBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbipzaXplb2YoV0NIQVIpKTsKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3JjLCAtMSwgcywgbGVuKTsKICByZXR1cm4gczsKfQoKc3RhdGljIExQV1NUUiBSUENSVDRfc3RybmR1cEF0b1coTFBDU1RSIHNyYywgSU5UIHNsZW4pCnsKICBEV09SRCBsZW47CiAgTFBXU1RSIHM7CiAgaWYgKCFzcmMpIHJldHVybiBOVUxMOwogIGxlbiA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzcmMsIHNsZW4sIE5VTEwsIDApOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzcmMsIHNsZW4sIHMsIGxlbik7CiAgcmV0dXJuIHM7Cn0KCkxQV1NUUiBSUENSVDRfc3RybmR1cFcoTFBDV1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQV1NUUiBzOwogIGlmICghc3JjKSByZXR1cm4gTlVMTDsKICBpZiAoc2xlbiA9PSAtMSkgc2xlbiA9IHN0cmxlblcoc3JjKTsKICBsZW4gPSBzbGVuOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKICBtZW1jcHkocywgc3JjLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgc1tsZW5dID0gMDsKICByZXR1cm4gczsKfQoKdm9pZCBSUENSVDRfc3RyZnJlZShMUFNUUiBzcmMpCnsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmMpOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfQWxsb2NCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBCT09MIHNlcnZlcikKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIE5ld0JpbmRpbmcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY0JpbmRpbmcpKTsKICBOZXdCaW5kaW5nLT5yZWZzID0gMTsKICBOZXdCaW5kaW5nLT5zZXJ2ZXIgPSBzZXJ2ZXI7CgogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfQ3JlYXRlQmluZGluZ0EoUnBjQmluZGluZyoqIEJpbmRpbmcsIEJPT0wgc2VydmVyLCBMUENTVFIgUHJvdHNlcSkKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIFJQQ1JUNF9BbGxvY0JpbmRpbmcoJk5ld0JpbmRpbmcsIHNlcnZlcik7CiAgTmV3QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBBKFByb3RzZXEpOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfQ3JlYXRlQmluZGluZ1coUnBjQmluZGluZyoqIEJpbmRpbmcsIEJPT0wgc2VydmVyLCBMUENXU1RSIFByb3RzZXEpCnsKICBScGNCaW5kaW5nKiBOZXdCaW5kaW5nOwoKICBSUENSVDRfQWxsb2NCaW5kaW5nKCZOZXdCaW5kaW5nLCBzZXJ2ZXIpOwogIE5ld0JpbmRpbmctPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwV3RvQShQcm90c2VxKTsKCiAgVFJBQ0UoImJpbmRpbmc6ICVwXG4iLCBOZXdCaW5kaW5nKTsKICAqQmluZGluZyA9IE5ld0JpbmRpbmc7CgogIHJldHVybiBSUENfU19PSzsKfQoKc3RhdGljIFJQQ19TVEFUVVMgUlBDUlQ0X0NvbXBsZXRlQmluZGluZ0EoUnBjQmluZGluZyogQmluZGluZywgTFBDU1RSIE5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgRW5kcG9pbnQsIExQQ1NUUiBOZXR3b3JrT3B0aW9ucykKewogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBUUkFDRSgiKFJwY0JpbmRpbmcgPT0gXiVwLCBOZXR3b3JrQWRkciA9PSAlcywgRW5kUG9pbnQgPT0gJXMsIE5ldHdvcmtPcHRpb25zID09ICVzKVxuIiwgQmluZGluZywKICAgZGVidWdzdHJfYShOZXR3b3JrQWRkciksIGRlYnVnc3RyX2EoRW5kcG9pbnQpLCBkZWJ1Z3N0cl9hKE5ldHdvcmtPcHRpb25zKSk7CgogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPk5ldHdvcmtBZGRyKTsKICBCaW5kaW5nLT5OZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJkdXBBKE5ldHdvcmtBZGRyKTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5FbmRwb2ludCk7CiAgaWYgKEVuZHBvaW50KSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKEVuZHBvaW50KTsKICB9IGVsc2UgewogICAgQmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQSgiIik7CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEJpbmRpbmctPk5ldHdvcmtPcHRpb25zKTsKICBCaW5kaW5nLT5OZXR3b3JrT3B0aW9ucyA9IFJQQ1JUNF9zdHJkdXBBdG9XKE5ldHdvcmtPcHRpb25zKTsKICBpZiAoIUJpbmRpbmctPkVuZHBvaW50KSBFUlIoIm91dCBvZiBtZW1vcnk/XG4iKTsKCiAgc3RhdHVzID0gUlBDUlQ0X0dldEFzc29jaWF0aW9uKEJpbmRpbmctPlByb3RzZXEsIEJpbmRpbmctPk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaW5kaW5nLT5FbmRwb2ludCwgQmluZGluZy0+TmV0d29ya09wdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZCaW5kaW5nLT5Bc3NvYyk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgcmV0dXJuIHN0YXR1czsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfQ29tcGxldGVCaW5kaW5nVyhScGNCaW5kaW5nKiBCaW5kaW5nLCBMUENXU1RSIE5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIEVuZHBvaW50LCBMUENXU1RSIE5ldHdvcmtPcHRpb25zKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCIoUnBjQmluZGluZyA9PSBeJXAsIE5ldHdvcmtBZGRyID09ICVzLCBFbmRQb2ludCA9PSAlcywgTmV0d29ya09wdGlvbnMgPT0gJXMpXG4iLCBCaW5kaW5nLCAKICAgZGVidWdzdHJfdyhOZXR3b3JrQWRkciksIGRlYnVnc3RyX3coRW5kcG9pbnQpLCBkZWJ1Z3N0cl93KE5ldHdvcmtPcHRpb25zKSk7CgogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPk5ldHdvcmtBZGRyKTsKICBCaW5kaW5nLT5OZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJkdXBXdG9BKE5ldHdvcmtBZGRyKTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5FbmRwb2ludCk7CiAgaWYgKEVuZHBvaW50KSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBXdG9BKEVuZHBvaW50KTsKICB9IGVsc2UgewogICAgQmluZGluZy0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQSgiIik7CiAgfQogIGlmICghQmluZGluZy0+RW5kcG9pbnQpIEVSUigib3V0IG9mIG1lbW9yeT9cbiIpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEJpbmRpbmctPk5ldHdvcmtPcHRpb25zKTsKICBCaW5kaW5nLT5OZXR3b3JrT3B0aW9ucyA9IFJQQ1JUNF9zdHJkdXBXKE5ldHdvcmtPcHRpb25zKTsKCiAgc3RhdHVzID0gUlBDUlQ0X0dldEFzc29jaWF0aW9uKEJpbmRpbmctPlByb3RzZXEsIEJpbmRpbmctPk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaW5kaW5nLT5FbmRwb2ludCwgQmluZGluZy0+TmV0d29ya09wdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZCaW5kaW5nLT5Bc3NvYyk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgcmV0dXJuIHN0YXR1czsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9SZXNvbHZlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBMUENTVFIgRW5kcG9pbnQpCnsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgVFJBQ0UoIihScGNCaW5kaW5nID09IF4lcCwgRW5kUG9pbnQgPT0gXCIlc1wiXG4iLCBCaW5kaW5nLCBFbmRwb2ludCk7CgogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKEVuZHBvaW50KTsKCiAgUnBjQXNzb2NfUmVsZWFzZShCaW5kaW5nLT5Bc3NvYyk7CiAgQmluZGluZy0+QXNzb2MgPSBOVUxMOwogIHN0YXR1cyA9IFJQQ1JUNF9HZXRBc3NvY2lhdGlvbihCaW5kaW5nLT5Qcm90c2VxLCBCaW5kaW5nLT5OZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQmluZGluZy0+RW5kcG9pbnQsIEJpbmRpbmctPk5ldHdvcmtPcHRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmQmluZGluZy0+QXNzb2MpOwogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICAgIHJldHVybiBzdGF0dXM7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfU2V0QmluZGluZ09iamVjdChScGNCaW5kaW5nKiBCaW5kaW5nLCBjb25zdCBVVUlEKiBPYmplY3RVdWlkKQp7CiAgVFJBQ0UoIigqUnBjQmluZGluZyA9PSBeJXAsIFVVSUQgPT0gJXMpXG4iLCBCaW5kaW5nLCBkZWJ1Z3N0cl9ndWlkKE9iamVjdFV1aWQpKTsgCiAgaWYgKE9iamVjdFV1aWQpIEJpbmRpbmctPk9iamVjdFV1aWQgPSAqT2JqZWN0VXVpZDsKICBlbHNlIFV1aWRDcmVhdGVOaWwoJkJpbmRpbmctPk9iamVjdFV1aWQpOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfTWFrZUJpbmRpbmcoUnBjQmluZGluZyoqIEJpbmRpbmcsIFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pCnsKICBScGNCaW5kaW5nKiBOZXdCaW5kaW5nOwogIFRSQUNFKCIoUnBjQmluZGluZyA9PSBeJXAsIENvbm5lY3Rpb24gPT0gXiVwKVxuIiwgQmluZGluZywgQ29ubmVjdGlvbik7CgogIFJQQ1JUNF9BbGxvY0JpbmRpbmcoJk5ld0JpbmRpbmcsIENvbm5lY3Rpb24tPnNlcnZlcik7CiAgTmV3QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBBKHJwY3J0NF9jb25uX2dldF9uYW1lKENvbm5lY3Rpb24pKTsKICBOZXdCaW5kaW5nLT5OZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJkdXBBKENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyKTsKICBOZXdCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICBOZXdCaW5kaW5nLT5Gcm9tQ29ubiA9IENvbm5lY3Rpb247CgogIFRSQUNFKCJiaW5kaW5nOiAlcFxuIiwgTmV3QmluZGluZyk7CiAgKkJpbmRpbmcgPSBOZXdCaW5kaW5nOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0V4cG9ydEJpbmRpbmcoUnBjQmluZGluZyoqIEJpbmRpbmcsIFJwY0JpbmRpbmcqIE9sZEJpbmRpbmcpCnsKICBJbnRlcmxvY2tlZEluY3JlbWVudCgmT2xkQmluZGluZy0+cmVmcyk7CiAgKkJpbmRpbmcgPSBPbGRCaW5kaW5nOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfRGVzdHJveUJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZykKewogIGlmIChJbnRlcmxvY2tlZERlY3JlbWVudCgmQmluZGluZy0+cmVmcykpCiAgICByZXR1cm4gUlBDX1NfT0s7CgogIFRSQUNFKCJiaW5kaW5nOiAlcFxuIiwgQmluZGluZyk7CiAgaWYgKEJpbmRpbmctPkFzc29jKSBScGNBc3NvY19SZWxlYXNlKEJpbmRpbmctPkFzc29jKTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5FbmRwb2ludCk7CiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+TmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPlByb3RzZXEpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEJpbmRpbmctPk5ldHdvcmtPcHRpb25zKTsKICBpZiAoQmluZGluZy0+QXV0aEluZm8pIFJwY0F1dGhJbmZvX1JlbGVhc2UoQmluZGluZy0+QXV0aEluZm8pOwogIGlmIChCaW5kaW5nLT5RT1MpIFJwY1F1YWxpdHlPZlNlcnZpY2VfUmVsZWFzZShCaW5kaW5nLT5RT1MpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEJpbmRpbmcpOwogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfT3BlbkJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZywgUnBjQ29ubmVjdGlvbioqIENvbm5lY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJQQ19TWU5UQVhfSURFTlRJRklFUiAqVHJhbnNmZXJTeW50YXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJQQ19TWU5UQVhfSURFTlRJRklFUiAqSW50ZXJmYWNlSWQpCnsKICBUUkFDRSgiKEJpbmRpbmcgPT0gXiVwKVxuIiwgQmluZGluZyk7CgogIGlmICghQmluZGluZy0+c2VydmVyKSB7CiAgICAgcmV0dXJuIFJwY0Fzc29jX0dldENsaWVudENvbm5lY3Rpb24oQmluZGluZy0+QXNzb2MsIEludGVyZmFjZUlkLAogICAgICAgICBUcmFuc2ZlclN5bnRheCwgQmluZGluZy0+QXV0aEluZm8sIEJpbmRpbmctPlFPUywgQ29ubmVjdGlvbik7CiAgfSBlbHNlIHsKICAgIC8qIHdlIGFscmVhZHkgaGF2ZSBhIGNvbm5lY3Rpb24gd2l0aCBhY2NlcHRhYmxlIGJpbmRpbmcsIHNvIHVzZSBpdCAqLwogICAgaWYgKEJpbmRpbmctPkZyb21Db25uKSB7CiAgICAgICpDb25uZWN0aW9uID0gQmluZGluZy0+RnJvbUNvbm47CiAgICAgIHJldHVybiBSUENfU19PSzsKICAgIH0gZWxzZSB7CiAgICAgICBFUlIoIm5vIGNvbm5lY3Rpb24gaW4gYmluZGluZ1xuIik7CiAgICAgICByZXR1cm4gUlBDX1NfSU5URVJOQUxfRVJST1I7CiAgICB9CiAgfQp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DbG9zZUJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZywgUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQmluZGluZyA9PSBeJXApXG4iLCBCaW5kaW5nKTsKICBpZiAoIUNvbm5lY3Rpb24pIHJldHVybiBSUENfU19PSzsKICBpZiAoQmluZGluZy0+c2VydmVyKSB7CiAgICAvKiBkb24ndCBkZXN0cm95IGEgY29ubmVjdGlvbiB0aGF0IGlzIGNhY2hlZCBpbiB0aGUgYmluZGluZyAqLwogICAgaWYgKEJpbmRpbmctPkZyb21Db25uID09IENvbm5lY3Rpb24pCiAgICAgIHJldHVybiBSUENfU19PSzsKICAgIHJldHVybiBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oQ29ubmVjdGlvbik7CiAgfQogIGVsc2UgewogICAgUnBjQXNzb2NfUmVsZWFzZUlkbGVDb25uZWN0aW9uKEJpbmRpbmctPkFzc29jLCBDb25uZWN0aW9uKTsKICAgIHJldHVybiBSUENfU19PSzsKICB9Cn0KCi8qIHV0aWxpdHkgZnVuY3Rpb25zIGZvciBzdHJpbmcgY29tcG9zaW5nIGFuZCBwYXJzaW5nICovCnN0YXRpYyB1bnNpZ25lZCBSUENSVDRfc3RyY29weUEoTFBTVFIgZGF0YSwgTFBDU1RSIHNyYykKewogIHVuc2lnbmVkIGxlbiA9IHN0cmxlbihzcmMpOwogIG1lbWNweShkYXRhLCBzcmMsIGxlbipzaXplb2YoQ0hBUikpOwogIHJldHVybiBsZW47Cn0KCnN0YXRpYyB1bnNpZ25lZCBSUENSVDRfc3RyY29weVcoTFBXU1RSIGRhdGEsIExQQ1dTVFIgc3JjKQp7CiAgdW5zaWduZWQgbGVuID0gc3RybGVuVyhzcmMpOwogIG1lbWNweShkYXRhLCBzcmMsIGxlbipzaXplb2YoV0NIQVIpKTsKICByZXR1cm4gbGVuOwp9CgpzdGF0aWMgTFBTVFIgUlBDUlQ0X3N0cmNvbmNhdEEoTFBTVFIgZHN0LCBMUENTVFIgc3JjKQp7CiAgRFdPUkQgbGVuID0gc3RybGVuKGRzdCksIHNsZW4gPSBzdHJsZW4oc3JjKTsKICBMUFNUUiBuZHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0LCAobGVuK3NsZW4rMikqc2l6ZW9mKENIQVIpKTsKICBpZiAoIW5kc3QpCiAgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0KTsKICAgIHJldHVybiBOVUxMOwogIH0KICBuZHN0W2xlbl0gPSAnLCc7CiAgbWVtY3B5KG5kc3QrbGVuKzEsIHNyYywgc2xlbisxKTsKICByZXR1cm4gbmRzdDsKfQoKc3RhdGljIExQV1NUUiBSUENSVDRfc3RyY29uY2F0VyhMUFdTVFIgZHN0LCBMUENXU1RSIHNyYykKewogIERXT1JEIGxlbiA9IHN0cmxlblcoZHN0KSwgc2xlbiA9IHN0cmxlblcoc3JjKTsKICBMUFdTVFIgbmRzdCA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGRzdCwgKGxlbitzbGVuKzIpKnNpemVvZihXQ0hBUikpOwogIGlmICghbmRzdCkgCiAgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0KTsKICAgIHJldHVybiBOVUxMOwogIH0KICBuZHN0W2xlbl0gPSAnLCc7CiAgbWVtY3B5KG5kc3QrbGVuKzEsIHNyYywgKHNsZW4rMSkqc2l6ZW9mKFdDSEFSKSk7CiAgcmV0dXJuIG5kc3Q7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlQShSUENfQ1NUUiBPYmpVdWlkLCBSUENfQ1NUUiBQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX0NTVFIgTmV0d29ya0FkZHIsIFJQQ19DU1RSIEVuZHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX0NTVFIgT3B0aW9ucywgUlBDX0NTVFIgKlN0cmluZ0JpbmRpbmcgKQp7CiAgRFdPUkQgbGVuID0gMTsKICBMUFNUUiBkYXRhOwoKICBUUkFDRSggIiglcywlcywlcywlcywlcywlcClcbiIsCiAgICAgICAgZGVidWdzdHJfYSggKGNoYXIqKU9ialV1aWQgKSwgZGVidWdzdHJfYSggKGNoYXIqKVByb3RzZXEgKSwKICAgICAgICBkZWJ1Z3N0cl9hKCAoY2hhciopTmV0d29ya0FkZHIgKSwgZGVidWdzdHJfYSggKGNoYXIqKUVuZHBvaW50ICksCiAgICAgICAgZGVidWdzdHJfYSggKGNoYXIqKU9wdGlvbnMgKSwgU3RyaW5nQmluZGluZyApOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgbGVuICs9IHN0cmxlbigoY2hhciopT2JqVXVpZCkgKyAxOwogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSBsZW4gKz0gc3RybGVuKChjaGFyKilQcm90c2VxKSArIDE7CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikgbGVuICs9IHN0cmxlbigoY2hhciopTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIGxlbiArPSBzdHJsZW4oKGNoYXIqKUVuZHBvaW50KSArIDI7CiAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIGxlbiArPSBzdHJsZW4oKGNoYXIqKU9wdGlvbnMpICsgMjsKCiAgZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4pOwogICpTdHJpbmdCaW5kaW5nID0gKHVuc2lnbmVkIGNoYXIqKWRhdGE7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCAoY2hhciopT2JqVXVpZCk7CiAgICAqZGF0YSsrID0gJ0AnOwogIH0KICBpZiAoUHJvdHNlcSAmJiAqUHJvdHNlcSkgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgKGNoYXIqKVByb3RzZXEpOwogICAgKmRhdGErKyA9ICc6JzsKICB9CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIChjaGFyKilOZXR3b3JrQWRkcik7CgogIGlmICgoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB8fAogICAgICAoT3B0aW9ucyAmJiAqT3B0aW9ucykpIHsKICAgICpkYXRhKysgPSAnWyc7CiAgICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB7CiAgICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIChjaGFyKilFbmRwb2ludCk7CiAgICAgIGlmIChPcHRpb25zICYmICpPcHRpb25zKSAqZGF0YSsrID0gJywnOwogICAgfQogICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgKGNoYXIqKU9wdGlvbnMpOwogICAgfQogICAgKmRhdGErKyA9ICddJzsKICB9CiAgKmRhdGEgPSAwOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZVcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VXKCBSUENfV1NUUiBPYmpVdWlkLCBSUENfV1NUUiBQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19XU1RSIE5ldHdvcmtBZGRyLCBSUENfV1NUUiBFbmRwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfV1NUUiBPcHRpb25zLCBSUENfV1NUUiogU3RyaW5nQmluZGluZyApCnsKICBEV09SRCBsZW4gPSAxOwogIFJQQ19XU1RSIGRhdGE7CgogIFRSQUNFKCIoJXMsJXMsJXMsJXMsJXMsJXApXG4iLAogICAgICAgZGVidWdzdHJfdyggT2JqVXVpZCApLCBkZWJ1Z3N0cl93KCBQcm90c2VxICksCiAgICAgICBkZWJ1Z3N0cl93KCBOZXR3b3JrQWRkciApLCBkZWJ1Z3N0cl93KCBFbmRwb2ludCApLAogICAgICAgZGVidWdzdHJfdyggT3B0aW9ucyApLCBTdHJpbmdCaW5kaW5nKTsKCiAgaWYgKE9ialV1aWQgJiYgKk9ialV1aWQpIGxlbiArPSBzdHJsZW5XKE9ialV1aWQpICsgMTsKICBpZiAoUHJvdHNlcSAmJiAqUHJvdHNlcSkgbGVuICs9IHN0cmxlblcoUHJvdHNlcSkgKyAxOwogIGlmIChOZXR3b3JrQWRkciAmJiAqTmV0d29ya0FkZHIpIGxlbiArPSBzdHJsZW5XKE5ldHdvcmtBZGRyKTsKICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSBsZW4gKz0gc3RybGVuVyhFbmRwb2ludCkgKyAyOwogIGlmIChPcHRpb25zICYmICpPcHRpb25zKSBsZW4gKz0gc3RybGVuVyhPcHRpb25zKSArIDI7CgogIGRhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogICpTdHJpbmdCaW5kaW5nID0gZGF0YTsKCiAgaWYgKE9ialV1aWQgJiYgKk9ialV1aWQpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIE9ialV1aWQpOwogICAgKmRhdGErKyA9ICdAJzsKICB9CiAgaWYgKFByb3RzZXEgJiYgKlByb3RzZXEpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIFByb3RzZXEpOwogICAgKmRhdGErKyA9ICc6JzsKICB9CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgTmV0d29ya0FkZHIpOwogIH0KICBpZiAoKEVuZHBvaW50ICYmICpFbmRwb2ludCkgfHwKICAgICAgKE9wdGlvbnMgJiYgKk9wdGlvbnMpKSB7CiAgICAqZGF0YSsrID0gJ1snOwogICAgaWYgKEVuZHBvaW50ICYmICpFbmRwb2ludCkgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBFbmRwb2ludCk7CiAgICAgIGlmIChPcHRpb25zICYmICpPcHRpb25zKSAqZGF0YSsrID0gJywnOwogICAgfQogICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgT3B0aW9ucyk7CiAgICB9CiAgICAqZGF0YSsrID0gJ10nOwogIH0KICAqZGF0YSA9IDA7CgogIHJldHVybiBSUENfU19PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nUGFyc2VBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1N0cmluZ0JpbmRpbmdQYXJzZUEoIFJQQ19DU1RSIFN0cmluZ0JpbmRpbmcsIFJQQ19DU1RSICpPYmpVdWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfQ1NUUiAqUHJvdHNlcSwgUlBDX0NTVFIgKk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfQ1NUUiAqRW5kcG9pbnQsIFJQQ19DU1RSICpPcHRpb25zKQp7CiAgQ0hBUiAqZGF0YSwgKm5leHQ7CiAgc3RhdGljIGNvbnN0IGNoYXIgZXBfb3B0W10gPSAiZW5kcG9pbnQ9IjsKICBCT09MIGVuZHBvaW50X2FscmVhZHlfZm91bmQgPSBGQUxTRTsKCiAgVFJBQ0UoIiglcywlcCwlcCwlcCwlcCwlcClcbiIsIGRlYnVnc3RyX2EoKGNoYXIqKVN0cmluZ0JpbmRpbmcpLAogICAgICAgT2JqVXVpZCwgUHJvdHNlcSwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zKTsKCiAgaWYgKE9ialV1aWQpICpPYmpVdWlkID0gTlVMTDsKICBpZiAoUHJvdHNlcSkgKlByb3RzZXEgPSBOVUxMOwogIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gTlVMTDsKICBpZiAoRW5kcG9pbnQpICpFbmRwb2ludCA9IE5VTEw7CiAgaWYgKE9wdGlvbnMpICpPcHRpb25zID0gTlVMTDsKCiAgZGF0YSA9IChjaGFyKikgU3RyaW5nQmluZGluZzsKCiAgbmV4dCA9IHN0cmNocihkYXRhLCAnQCcpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSAodW5zaWduZWQgY2hhciopUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgfQoKICBuZXh0ID0gc3RyY2hyKGRhdGEsICc6Jyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9ICh1bnNpZ25lZCBjaGFyKilSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHIoZGF0YSwgJ1snKTsKICBpZiAobmV4dCkgewogICAgQ0hBUiAqY2xvc2UsICpvcHQ7CgogICAgaWYgKE5ldHdvcmtBZGRyKSAqTmV0d29ya0FkZHIgPSAodW5zaWduZWQgY2hhciopUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgICBjbG9zZSA9IHN0cmNocihkYXRhLCAnXScpOwogICAgaWYgKCFjbG9zZSkgZ290byBmYWlsOwoKICAgIC8qIHRva2VuaXplIG9wdGlvbnMgKi8KICAgIHdoaWxlIChkYXRhIDwgY2xvc2UpIHsKICAgICAgbmV4dCA9IHN0cmNocihkYXRhLCAnLCcpOwogICAgICBpZiAoIW5leHQgfHwgbmV4dCA+IGNsb3NlKSBuZXh0ID0gY2xvc2U7CiAgICAgIC8qIEZJWE1FOiB0aGlzIGlzIGtpbmQgb2YgaW5lZmZpY2llbnQgKi8KICAgICAgb3B0ID0gUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgICAgZGF0YSA9IG5leHQrMTsKCiAgICAgIC8qIHBhcnNlIG9wdGlvbiAqLwogICAgICBuZXh0ID0gc3RyY2hyKG9wdCwgJz0nKTsKICAgICAgaWYgKCFuZXh0KSB7CiAgICAgICAgLyogbm90IGFuIG9wdGlvbiwgbXVzdCBiZSBhbiBlbmRwb2ludCAqLwogICAgICAgIGlmIChlbmRwb2ludF9hbHJlYWR5X2ZvdW5kKSBnb3RvIGZhaWw7CiAgICAgICAgaWYgKEVuZHBvaW50KSAqRW5kcG9pbnQgPSAodW5zaWduZWQgY2hhciopIG9wdDsKICAgICAgICBlbHNlIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgZW5kcG9pbnRfYWxyZWFkeV9mb3VuZCA9IFRSVUU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHN0cm5jbXAob3B0LCBlcF9vcHQsIHN0cmxlbihlcF9vcHQpKSA9PSAwKSB7CiAgICAgICAgICAvKiBlbmRwb2ludCBvcHRpb24gKi8KICAgICAgICAgIGlmIChlbmRwb2ludF9hbHJlYWR5X2ZvdW5kKSBnb3RvIGZhaWw7CiAgICAgICAgICBpZiAoRW5kcG9pbnQpICpFbmRwb2ludCA9ICh1bnNpZ25lZCBjaGFyKikgUlBDUlQ0X3N0cmR1cEEobmV4dCsxKTsKICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgICBlbmRwb2ludF9hbHJlYWR5X2ZvdW5kID0gVFJVRTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogbmV0d29yayBvcHRpb24gKi8KICAgICAgICAgIGlmIChPcHRpb25zKSB7CiAgICAgICAgICAgIGlmICgqT3B0aW9ucykgewogICAgICAgICAgICAgIC8qIEZJWE1FOiB0aGlzIGlzIGtpbmQgb2YgaW5lZmZpY2llbnQgKi8KICAgICAgICAgICAgICAqT3B0aW9ucyA9ICh1bnNpZ25lZCBjaGFyKikgUlBDUlQ0X3N0cmNvbmNhdEEoIChjaGFyKikqT3B0aW9ucywgb3B0KTsKICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAqT3B0aW9ucyA9ICh1bnNpZ25lZCBjaGFyKikgb3B0OwogICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgZGF0YSA9IGNsb3NlKzE7CiAgICBpZiAoKmRhdGEpIGdvdG8gZmFpbDsKICB9CiAgZWxzZSBpZiAoTmV0d29ya0FkZHIpIAogICAgKk5ldHdvcmtBZGRyID0gKHVuc2lnbmVkIGNoYXIqKVJQQ1JUNF9zdHJkdXBBKGRhdGEpOwoKICByZXR1cm4gUlBDX1NfT0s7CgpmYWlsOgogIGlmIChPYmpVdWlkKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKU9ialV1aWQpOwogIGlmIChQcm90c2VxKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKVByb3RzZXEpOwogIGlmIChOZXR3b3JrQWRkcikgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50KSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKUVuZHBvaW50KTsKICBpZiAoT3B0aW9ucykgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilPcHRpb25zKTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9TVFJJTkdfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ1BhcnNlVyggUlBDX1dTVFIgU3RyaW5nQmluZGluZywgUlBDX1dTVFIgKk9ialV1aWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19XU1RSICpQcm90c2VxLCBSUENfV1NUUiAqTmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19XU1RSICpFbmRwb2ludCwgUlBDX1dTVFIgKk9wdGlvbnMpCnsKICBXQ0hBUiAqZGF0YSwgKm5leHQ7CiAgc3RhdGljIGNvbnN0IFdDSEFSIGVwX29wdFtdID0geydlJywnbicsJ2QnLCdwJywnbycsJ2knLCduJywndCcsJz0nLDB9OwogIEJPT0wgZW5kcG9pbnRfYWxyZWFkeV9mb3VuZCA9IEZBTFNFOwoKICBUUkFDRSgiKCVzLCVwLCVwLCVwLCVwLCVwKVxuIiwgZGVidWdzdHJfdyhTdHJpbmdCaW5kaW5nKSwKICAgICAgIE9ialV1aWQsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9ucyk7CgogIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IE5VTEw7CiAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gTlVMTDsKICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9IE5VTEw7CiAgaWYgKEVuZHBvaW50KSAqRW5kcG9pbnQgPSBOVUxMOwogIGlmIChPcHRpb25zKSAqT3B0aW9ucyA9IE5VTEw7CgogIGRhdGEgPSBTdHJpbmdCaW5kaW5nOwoKICBuZXh0ID0gc3RyY2hyVyhkYXRhLCAnQCcpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHJXKGRhdGEsICc6Jyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9IFJQQ1JUNF9zdHJuZHVwVyhkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNoclcoZGF0YSwgJ1snKTsKICBpZiAobmV4dCkgewogICAgV0NIQVIgKmNsb3NlLCAqb3B0OwoKICAgIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cm5kdXBXKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgICBjbG9zZSA9IHN0cmNoclcoZGF0YSwgJ10nKTsKICAgIGlmICghY2xvc2UpIGdvdG8gZmFpbDsKCiAgICAvKiB0b2tlbml6ZSBvcHRpb25zICovCiAgICB3aGlsZSAoZGF0YSA8IGNsb3NlKSB7CiAgICAgIG5leHQgPSBzdHJjaHJXKGRhdGEsICcsJyk7CiAgICAgIGlmICghbmV4dCB8fCBuZXh0ID4gY2xvc2UpIG5leHQgPSBjbG9zZTsKICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICBvcHQgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgICBkYXRhID0gbmV4dCsxOwoKICAgICAgLyogcGFyc2Ugb3B0aW9uICovCiAgICAgIG5leHQgPSBzdHJjaHJXKG9wdCwgJz0nKTsKICAgICAgaWYgKCFuZXh0KSB7CiAgICAgICAgLyogbm90IGFuIG9wdGlvbiwgbXVzdCBiZSBhbiBlbmRwb2ludCAqLwogICAgICAgIGlmIChlbmRwb2ludF9hbHJlYWR5X2ZvdW5kKSBnb3RvIGZhaWw7CiAgICAgICAgaWYgKEVuZHBvaW50KSAqRW5kcG9pbnQgPSBvcHQ7CiAgICAgICAgZWxzZSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgIGVuZHBvaW50X2FscmVhZHlfZm91bmQgPSBUUlVFOwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChzdHJuY21wVyhvcHQsIGVwX29wdCwgc3RybGVuVyhlcF9vcHQpKSA9PSAwKSB7CiAgICAgICAgICAvKiBlbmRwb2ludCBvcHRpb24gKi8KICAgICAgICAgIGlmIChlbmRwb2ludF9hbHJlYWR5X2ZvdW5kKSBnb3RvIGZhaWw7CiAgICAgICAgICBpZiAoRW5kcG9pbnQpICpFbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBXKG5leHQrMSk7CiAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgICAgZW5kcG9pbnRfYWxyZWFkeV9mb3VuZCA9IFRSVUU7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIC8qIG5ldHdvcmsgb3B0aW9uICovCiAgICAgICAgICBpZiAoT3B0aW9ucykgewogICAgICAgICAgICBpZiAoKk9wdGlvbnMpIHsKICAgICAgICAgICAgICAvKiBGSVhNRTogdGhpcyBpcyBraW5kIG9mIGluZWZmaWNpZW50ICovCiAgICAgICAgICAgICAgKk9wdGlvbnMgPSBSUENSVDRfc3RyY29uY2F0VygqT3B0aW9ucywgb3B0KTsKICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAqT3B0aW9ucyA9IG9wdDsKICAgICAgICAgIH0gZWxzZQogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgIH0KICAgICAgfQogICAgfQoKICAgIGRhdGEgPSBjbG9zZSsxOwogICAgaWYgKCpkYXRhKSBnb3RvIGZhaWw7CiAgfSBlbHNlIGlmIChOZXR3b3JrQWRkcikgCiAgICAqTmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwVyhkYXRhKTsKCiAgcmV0dXJuIFJQQ19TX09LOwoKZmFpbDoKICBpZiAoT2JqVXVpZCkgUnBjU3RyaW5nRnJlZVcoT2JqVXVpZCk7CiAgaWYgKFByb3RzZXEpIFJwY1N0cmluZ0ZyZWVXKFByb3RzZXEpOwogIGlmIChOZXR3b3JrQWRkcikgUnBjU3RyaW5nRnJlZVcoTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCkgUnBjU3RyaW5nRnJlZVcoRW5kcG9pbnQpOwogIGlmIChPcHRpb25zKSBScGNTdHJpbmdGcmVlVyhPcHRpb25zKTsKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9TVFJJTkdfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdGcmVlIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdGcmVlKCBSUENfQklORElOR19IQU5ETEUqIEJpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgVFJBQ0UoIiglcCkgPSAlcFxuIiwgQmluZGluZywgKkJpbmRpbmcpOwogIHN0YXR1cyA9IFJQQ1JUNF9EZXN0cm95QmluZGluZygqQmluZGluZyk7CiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykgKkJpbmRpbmcgPSAwOwogIHJldHVybiBzdGF0dXM7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdWZWN0b3JGcmVlIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdWZWN0b3JGcmVlKCBSUENfQklORElOR19WRUNUT1IqKiBCaW5kaW5nVmVjdG9yICkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIHVuc2lnbmVkIGxvbmcgYzsKCiAgVFJBQ0UoIiglcClcbiIsIEJpbmRpbmdWZWN0b3IpOwogIGZvciAoYz0wOyBjPCgqQmluZGluZ1ZlY3RvciktPkNvdW50OyBjKyspIHsKICAgIHN0YXR1cyA9IFJwY0JpbmRpbmdGcmVlKCYoKkJpbmRpbmdWZWN0b3IpLT5CaW5kaW5nSFtjXSk7CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsICpCaW5kaW5nVmVjdG9yKTsKICAqQmluZGluZ1ZlY3RvciA9IE5VTEw7CiAgcmV0dXJuIFJQQ19TX09LOwp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nSW5xT2JqZWN0IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdJbnFPYmplY3QoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBVVUlEKiBPYmplY3RVdWlkICkKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoIiglcCwlcCkgPSAlc1xuIiwgQmluZGluZywgT2JqZWN0VXVpZCwgZGVidWdzdHJfZ3VpZCgmYmluZC0+T2JqZWN0VXVpZCkpOwogICpPYmplY3RVdWlkID0gYmluZC0+T2JqZWN0VXVpZDsKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nU2V0T2JqZWN0IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdTZXRPYmplY3QoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBVVUlEKiBPYmplY3RVdWlkICkKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoIiglcCwlcylcbiIsIEJpbmRpbmcsIGRlYnVnc3RyX2d1aWQoT2JqZWN0VXVpZCkpOwogIGlmIChiaW5kLT5zZXJ2ZXIpIHJldHVybiBSUENfU19XUk9OR19LSU5EX09GX0JJTkRJTkc7CiAgcmV0dXJuIFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KEJpbmRpbmcsIE9iamVjdFV1aWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdBKCBSUENfQ1NUUiBTdHJpbmdCaW5kaW5nLCBSUENfQklORElOR19IQU5ETEUqIEJpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgUnBjQmluZGluZyogYmluZCA9IE5VTEw7CiAgUlBDX0NTVFIgT2JqZWN0VXVpZCwgUHJvdHNlcSwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zOwogIFVVSUQgVXVpZDsKCiAgVFJBQ0UoIiglcywlcClcbiIsIGRlYnVnc3RyX2EoKGNoYXIqKVN0cmluZ0JpbmRpbmcpLCBCaW5kaW5nKTsKCiAgcmV0ID0gUnBjU3RyaW5nQmluZGluZ1BhcnNlQShTdHJpbmdCaW5kaW5nLCAmT2JqZWN0VXVpZCwgJlByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZOZXR3b3JrQWRkciwgJkVuZHBvaW50LCAmT3B0aW9ucyk7CiAgaWYgKHJldCAhPSBSUENfU19PSykgcmV0dXJuIHJldDsKCiAgcmV0ID0gVXVpZEZyb21TdHJpbmdBKE9iamVjdFV1aWQsICZVdWlkKTsKCiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9DcmVhdGVCaW5kaW5nQSgmYmluZCwgRkFMU0UsIChjaGFyKilQcm90c2VxKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoYmluZCwgJlV1aWQpOwogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ29tcGxldGVCaW5kaW5nQShiaW5kLCAoY2hhciopTmV0d29ya0FkZHIsIChjaGFyKilFbmRwb2ludCwgKGNoYXIqKU9wdGlvbnMpOwoKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZPcHRpb25zKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZFbmRwb2ludCk7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmTmV0d29ya0FkZHIpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJlByb3RzZXEpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk9iamVjdFV1aWQpOwoKICBpZiAocmV0ID09IFJQQ19TX09LKSAKICAgICpCaW5kaW5nID0gKFJQQ19CSU5ESU5HX0hBTkRMRSliaW5kOwogIGVsc2UgCiAgICBSUENSVDRfRGVzdHJveUJpbmRpbmcoYmluZCk7CgogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdGcm9tU3RyaW5nQmluZGluZ1coIFJQQ19XU1RSIFN0cmluZ0JpbmRpbmcsIFJQQ19CSU5ESU5HX0hBTkRMRSogQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICBScGNCaW5kaW5nKiBiaW5kID0gTlVMTDsKICBSUENfV1NUUiBPYmplY3RVdWlkLCBQcm90c2VxLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnM7CiAgVVVJRCBVdWlkOwoKICBUUkFDRSgiKCVzLCVwKVxuIiwgZGVidWdzdHJfdyhTdHJpbmdCaW5kaW5nKSwgQmluZGluZyk7CgogIHJldCA9IFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcoU3RyaW5nQmluZGluZywgJk9iamVjdFV1aWQsICZQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmV0d29ya0FkZHIsICZFbmRwb2ludCwgJk9wdGlvbnMpOwogIGlmIChyZXQgIT0gUlBDX1NfT0spIHJldHVybiByZXQ7CgogIHJldCA9IFV1aWRGcm9tU3RyaW5nVyhPYmplY3RVdWlkLCAmVXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ3JlYXRlQmluZGluZ1coJmJpbmQsIEZBTFNFLCBQcm90c2VxKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoYmluZCwgJlV1aWQpOwogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ29tcGxldGVCaW5kaW5nVyhiaW5kLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnMpOwoKICBScGNTdHJpbmdGcmVlVygmT3B0aW9ucyk7CiAgUnBjU3RyaW5nRnJlZVcoJkVuZHBvaW50KTsKICBScGNTdHJpbmdGcmVlVygmTmV0d29ya0FkZHIpOwogIFJwY1N0cmluZ0ZyZWVXKCZQcm90c2VxKTsKICBScGNTdHJpbmdGcmVlVygmT2JqZWN0VXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICAqQmluZGluZyA9IChSUENfQklORElOR19IQU5ETEUpYmluZDsKICBlbHNlCiAgICBSUENSVDRfRGVzdHJveUJpbmRpbmcoYmluZCk7CgogIHJldHVybiByZXQ7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdBKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX0NTVFIgKlN0cmluZ0JpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwogIFJQQ19DU1RSIE9iamVjdFV1aWQ7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBTdHJpbmdCaW5kaW5nKTsKCiAgcmV0ID0gVXVpZFRvU3RyaW5nQSgmYmluZC0+T2JqZWN0VXVpZCwgJk9iamVjdFV1aWQpOwogIGlmIChyZXQgIT0gUlBDX1NfT0spIHJldHVybiByZXQ7CgogIHJldCA9IFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlQShPYmplY3RVdWlkLCAodW5zaWduZWQgY2hhciopYmluZC0+UHJvdHNlcSwgKHVuc2lnbmVkIGNoYXIqKSBiaW5kLT5OZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGNoYXIqKSBiaW5kLT5FbmRwb2ludCwgTlVMTCwgU3RyaW5nQmluZGluZyk7CgogIFJwY1N0cmluZ0ZyZWVBKCZPYmplY3RVdWlkKTsKCiAgcmV0dXJuIHJldDsKfQogIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ1cgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ1coIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfV1NUUiAqU3RyaW5nQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICB1bnNpZ25lZCBjaGFyICpzdHIgPSBOVUxMOwogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBTdHJpbmdCaW5kaW5nKTsKICByZXQgPSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nQShCaW5kaW5nLCAmc3RyKTsKICAqU3RyaW5nQmluZGluZyA9IFJQQ1JUNF9zdHJkdXBBdG9XKChjaGFyKilzdHIpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJnN0cik7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIElfUnBjQmluZGluZ1NldEFzeW5jIChSUENSVDQuQCkKICogTk9URVMKICogIEV4aXN0cyBpbiB3aW45eCBhbmQgd2luTlQsIGJ1dCB3aXRoIGRpZmZlcmVudCBudW1iZXIgb2YgYXJndW1lbnRzCiAqICAoOXggdmVyc2lvbiBoYXMgMyBhcmd1bWVudHMsIE5UIGhhcyAyKS4KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjQmluZGluZ1NldEFzeW5jKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX0JMT0NLSU5HX0ZOIEJsb2NraW5nRm4pCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKUJpbmRpbmc7CgogIFRSQUNFKCAiKCVwLCVwKTogc3R1YlxuIiwgQmluZGluZywgQmxvY2tpbmdGbiApOwoKICBiaW5kLT5CbG9ja2luZ0ZuID0gQmxvY2tpbmdGbjsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0NvcHkgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBSUENfRU5UUlkgUnBjQmluZGluZ0NvcHkoCiAgUlBDX0JJTkRJTkdfSEFORExFIFNvdXJjZUJpbmRpbmcsCiAgUlBDX0JJTkRJTkdfSEFORExFKiBEZXN0aW5hdGlvbkJpbmRpbmcpCnsKICBScGNCaW5kaW5nICpEZXN0QmluZGluZzsKICBScGNCaW5kaW5nICpTcmNCaW5kaW5nID0gKFJwY0JpbmRpbmcqKVNvdXJjZUJpbmRpbmc7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCIoJXAsICVwKVxuIiwgU291cmNlQmluZGluZywgRGVzdGluYXRpb25CaW5kaW5nKTsKCiAgc3RhdHVzID0gUlBDUlQ0X0FsbG9jQmluZGluZygmRGVzdEJpbmRpbmcsIFNyY0JpbmRpbmctPnNlcnZlcik7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgcmV0dXJuIHN0YXR1czsKCiAgRGVzdEJpbmRpbmctPk9iamVjdFV1aWQgPSBTcmNCaW5kaW5nLT5PYmplY3RVdWlkOwogIERlc3RCaW5kaW5nLT5CbG9ja2luZ0ZuID0gU3JjQmluZGluZy0+QmxvY2tpbmdGbjsKICBEZXN0QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJuZHVwQShTcmNCaW5kaW5nLT5Qcm90c2VxLCAtMSk7CiAgRGVzdEJpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cm5kdXBBKFNyY0JpbmRpbmctPk5ldHdvcmtBZGRyLCAtMSk7CiAgRGVzdEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cm5kdXBBKFNyY0JpbmRpbmctPkVuZHBvaW50LCAtMSk7CiAgRGVzdEJpbmRpbmctPk5ldHdvcmtPcHRpb25zID0gUlBDUlQ0X3N0cmR1cFcoU3JjQmluZGluZy0+TmV0d29ya09wdGlvbnMpOwogIGlmIChTcmNCaW5kaW5nLT5Bc3NvYykgU3JjQmluZGluZy0+QXNzb2MtPnJlZnMrKzsKICBEZXN0QmluZGluZy0+QXNzb2MgPSBTcmNCaW5kaW5nLT5Bc3NvYzsKCiAgaWYgKFNyY0JpbmRpbmctPkF1dGhJbmZvKSBScGNBdXRoSW5mb19BZGRSZWYoU3JjQmluZGluZy0+QXV0aEluZm8pOwogIERlc3RCaW5kaW5nLT5BdXRoSW5mbyA9IFNyY0JpbmRpbmctPkF1dGhJbmZvOwogIGlmIChTcmNCaW5kaW5nLT5RT1MpIFJwY1F1YWxpdHlPZlNlcnZpY2VfQWRkUmVmKFNyY0JpbmRpbmctPlFPUyk7CiAgRGVzdEJpbmRpbmctPlFPUyA9IFNyY0JpbmRpbmctPlFPUzsKCiAgKkRlc3RpbmF0aW9uQmluZGluZyA9IERlc3RCaW5kaW5nOwogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0ltcGVyc29uYXRlQ2xpZW50IChSUENSVDQuQCkKICoKICogSW1wZXJzb25hdGVzIHRoZSBjbGllbnQgY29ubmVjdGVkIHZpYSBhIGJpbmRpbmcgaGFuZGxlIHNvIHRoYXQgc2VjdXJpdHkKICogY2hlY2tzIGFyZSBkb25lIGluIHRoZSBjb250ZXh0IG9mIHRoZSBjbGllbnQuCiAqCiAqIFBBUkFNUwogKiAgQmluZGluZ0hhbmRsZSBbSV0gSGFuZGxlIHRvIHRoZSBiaW5kaW5nIHRvIHRoZSBjbGllbnQuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFJQU19TX09LLgogKiAgRmFpbHVyZTogUlBDX1NUQVRVUyB2YWx1ZS4KICoKICogTk9URVMKICoKICogSWYgQmluZGluZ0hhbmRsZSBpcyBOVUxMIHRoZW4gdGhlIGZ1bmN0aW9uIGltcGVyc29uYXRlcyB0aGUgY2xpZW50CiAqIGNvbm5lY3RlZCB0byB0aGUgYmluZGluZyBoYW5kbGUgb2YgdGhlIGN1cnJlbnQgdGhyZWFkLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjSW1wZXJzb25hdGVDbGllbnQoUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmdIYW5kbGUpCnsKICAgIEZJWE1FKCIoJXApOiBzdHViXG4iLCBCaW5kaW5nSGFuZGxlKTsKICAgIEltcGVyc29uYXRlU2VsZihTZWN1cml0eUltcGVyc29uYXRpb24pOwogICAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjUmV2ZXJ0VG9TZWxmRXggKFJQQ1JUNC5AKQogKgogKiBTdG9wcyBpbXBlcnNvbmF0aW5nIHRoZSBjbGllbnQgY29ubmVjdGVkIHRvIHRoZSBiaW5kaW5nIGhhbmRsZSBzbyB0aGF0IHNlY3VyaXR5CiAqIGNoZWNrcyBhcmUgbm8gbG9uZ2VyIGRvbmUgaW4gdGhlIGNvbnRleHQgb2YgdGhlIGNsaWVudC4KICoKICogUEFSQU1TCiAqICBCaW5kaW5nSGFuZGxlIFtJXSBIYW5kbGUgdG8gdGhlIGJpbmRpbmcgdG8gdGhlIGNsaWVudC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogUlBTX1NfT0suCiAqICBGYWlsdXJlOiBSUENfU1RBVFVTIHZhbHVlLgogKgogKiBOT1RFUwogKgogKiBJZiBCaW5kaW5nSGFuZGxlIGlzIE5VTEwgdGhlbiB0aGUgZnVuY3Rpb24gc3RvcHMgaW1wZXJzb25hdGluZyB0aGUgY2xpZW50CiAqIGNvbm5lY3RlZCB0byB0aGUgYmluZGluZyBoYW5kbGUgb2YgdGhlIGN1cnJlbnQgdGhyZWFkLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjUmV2ZXJ0VG9TZWxmRXgoUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmdIYW5kbGUpCnsKICAgIEZJWE1FKCIoJXApOiBzdHViXG4iLCBCaW5kaW5nSGFuZGxlKTsKICAgIHJldHVybiBSUENfU19PSzsKfQoKc3RhdGljIGlubGluZSBCT09MIGhhc19udF9hdXRoX2lkZW50aXR5KFVMT05HIEF1dGhuTGV2ZWwpCnsKICAgIHN3aXRjaCAoQXV0aG5MZXZlbCkKICAgIHsKICAgIGNhc2UgUlBDX0NfQVVUSE5fR1NTX05FR09USUFURToKICAgIGNhc2UgUlBDX0NfQVVUSE5fV0lOTlQ6CiAgICBjYXNlIFJQQ19DX0FVVEhOX0dTU19LRVJCRVJPUzoKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQp9CgpzdGF0aWMgUlBDX1NUQVRVUyBScGNBdXRoSW5mb19DcmVhdGUoVUxPTkcgQXV0aG5MZXZlbCwgVUxPTkcgQXV0aG5TdmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDcmVkSGFuZGxlIGNyZWQsIFRpbWVTdGFtcCBleHAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyBjYk1heFRva2VuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX0FVVEhfSURFTlRJVFlfSEFORExFIGlkZW50aXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUnBjQXV0aEluZm8gKipyZXQpCnsKICAgIFJwY0F1dGhJbmZvICpBdXRoSW5mbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKkF1dGhJbmZvKSk7CiAgICBpZiAoIUF1dGhJbmZvKQogICAgICAgIHJldHVybiBFUlJPUl9PVVRPRk1FTU9SWTsKCiAgICBBdXRoSW5mby0+cmVmcyA9IDE7CiAgICBBdXRoSW5mby0+QXV0aG5MZXZlbCA9IEF1dGhuTGV2ZWw7CiAgICBBdXRoSW5mby0+QXV0aG5TdmMgPSBBdXRoblN2YzsKICAgIEF1dGhJbmZvLT5jcmVkID0gY3JlZDsKICAgIEF1dGhJbmZvLT5leHAgPSBleHA7CiAgICBBdXRoSW5mby0+Y2JNYXhUb2tlbiA9IGNiTWF4VG9rZW47CiAgICBBdXRoSW5mby0+aWRlbnRpdHkgPSBpZGVudGl0eTsKICAgIEF1dGhJbmZvLT5zZXJ2ZXJfcHJpbmNpcGFsX25hbWUgPSBOVUxMOwoKICAgIC8qIGR1cGxpY2F0ZSB0aGUgU0VDX1dJTk5UX0FVVEhfSURFTlRJVFkgc3RydWN0dXJlLCBpZiBhcHBsaWNhYmxlLCB0bwogICAgICogZW5hYmxlIGJldHRlciBtYXRjaGluZyBpbiBScGNBdXRoSW5mb19Jc0VxdWFsICovCiAgICBpZiAoaWRlbnRpdHkgJiYgaGFzX250X2F1dGhfaWRlbnRpdHkoQXV0aG5TdmMpKQogICAgewogICAgICAgIGNvbnN0IFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1cgKm50X2lkZW50aXR5ID0gaWRlbnRpdHk7CiAgICAgICAgQXV0aEluZm8tPm50X2lkZW50aXR5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqQXV0aEluZm8tPm50X2lkZW50aXR5KSk7CiAgICAgICAgaWYgKCFBdXRoSW5mby0+bnRfaWRlbnRpdHkpCiAgICAgICAgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBBdXRoSW5mbyk7CiAgICAgICAgICAgIHJldHVybiBFUlJPUl9PVVRPRk1FTU9SWTsKICAgICAgICB9CgogICAgICAgIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+RmxhZ3MgPSBTRUNfV0lOTlRfQVVUSF9JREVOVElUWV9VTklDT0RFOwogICAgICAgIGlmIChudF9pZGVudGl0eS0+RmxhZ3MgJiBTRUNfV0lOTlRfQVVUSF9JREVOVElUWV9VTklDT0RFKQogICAgICAgICAgICBBdXRoSW5mby0+bnRfaWRlbnRpdHktPlVzZXIgPSBSUENSVDRfc3RybmR1cFcobnRfaWRlbnRpdHktPlVzZXIsIG50X2lkZW50aXR5LT5Vc2VyTGVuZ3RoKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+VXNlciA9IFJQQ1JUNF9zdHJuZHVwQXRvVygoY29uc3QgY2hhciAqKW50X2lkZW50aXR5LT5Vc2VyLCBudF9pZGVudGl0eS0+VXNlckxlbmd0aCk7CiAgICAgICAgQXV0aEluZm8tPm50X2lkZW50aXR5LT5Vc2VyTGVuZ3RoID0gbnRfaWRlbnRpdHktPlVzZXJMZW5ndGg7CiAgICAgICAgaWYgKG50X2lkZW50aXR5LT5GbGFncyAmIFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1VOSUNPREUpCiAgICAgICAgICAgIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+RG9tYWluID0gUlBDUlQ0X3N0cm5kdXBXKG50X2lkZW50aXR5LT5Eb21haW4sIG50X2lkZW50aXR5LT5Eb21haW5MZW5ndGgpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgQXV0aEluZm8tPm50X2lkZW50aXR5LT5Eb21haW4gPSBSUENSVDRfc3RybmR1cEF0b1coKGNvbnN0IGNoYXIgKiludF9pZGVudGl0eS0+RG9tYWluLCBudF9pZGVudGl0eS0+RG9tYWluTGVuZ3RoKTsKICAgICAgICBBdXRoSW5mby0+bnRfaWRlbnRpdHktPkRvbWFpbkxlbmd0aCA9IG50X2lkZW50aXR5LT5Eb21haW5MZW5ndGg7CiAgICAgICAgaWYgKG50X2lkZW50aXR5LT5GbGFncyAmIFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1VOSUNPREUpCiAgICAgICAgICAgIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+UGFzc3dvcmQgPSBSUENSVDRfc3RybmR1cFcobnRfaWRlbnRpdHktPlBhc3N3b3JkLCBudF9pZGVudGl0eS0+UGFzc3dvcmRMZW5ndGgpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgQXV0aEluZm8tPm50X2lkZW50aXR5LT5QYXNzd29yZCA9IFJQQ1JUNF9zdHJuZHVwQXRvVygoY29uc3QgY2hhciAqKW50X2lkZW50aXR5LT5QYXNzd29yZCwgbnRfaWRlbnRpdHktPlBhc3N3b3JkTGVuZ3RoKTsKICAgICAgICBBdXRoSW5mby0+bnRfaWRlbnRpdHktPlBhc3N3b3JkTGVuZ3RoID0gbnRfaWRlbnRpdHktPlBhc3N3b3JkTGVuZ3RoOwoKICAgICAgICBpZiAoKG50X2lkZW50aXR5LT5Vc2VyICYmICFBdXRoSW5mby0+bnRfaWRlbnRpdHktPlVzZXIpIHx8CiAgICAgICAgICAgIChudF9pZGVudGl0eS0+RG9tYWluICYmICFBdXRoSW5mby0+bnRfaWRlbnRpdHktPkRvbWFpbikgfHwKICAgICAgICAgICAgKG50X2lkZW50aXR5LT5QYXNzd29yZCAmJiAhQXV0aEluZm8tPm50X2lkZW50aXR5LT5QYXNzd29yZCkpCiAgICAgICAgewogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBBdXRoSW5mby0+bnRfaWRlbnRpdHktPlVzZXIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBBdXRoSW5mby0+bnRfaWRlbnRpdHktPkRvbWFpbik7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+UGFzc3dvcmQpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBBdXRoSW5mby0+bnRfaWRlbnRpdHkpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBBdXRoSW5mbyk7CiAgICAgICAgICAgIHJldHVybiBFUlJPUl9PVVRPRk1FTU9SWTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICAgICAgQXV0aEluZm8tPm50X2lkZW50aXR5ID0gTlVMTDsKICAgICpyZXQgPSBBdXRoSW5mbzsKICAgIHJldHVybiBSUENfU19PSzsKfQoKVUxPTkcgUnBjQXV0aEluZm9fQWRkUmVmKFJwY0F1dGhJbmZvICpBdXRoSW5mbykKewogICAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZBdXRoSW5mby0+cmVmcyk7Cn0KClVMT05HIFJwY0F1dGhJbmZvX1JlbGVhc2UoUnBjQXV0aEluZm8gKkF1dGhJbmZvKQp7CiAgICBVTE9ORyByZWZzID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJkF1dGhJbmZvLT5yZWZzKTsKCiAgICBpZiAoIXJlZnMpCiAgICB7CiAgICAgICAgRnJlZUNyZWRlbnRpYWxzSGFuZGxlKCZBdXRoSW5mby0+Y3JlZCk7CiAgICAgICAgaWYgKEF1dGhJbmZvLT5udF9pZGVudGl0eSkKICAgICAgICB7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+VXNlcik7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+RG9tYWluKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQXV0aEluZm8tPm50X2lkZW50aXR5LT5QYXNzd29yZCk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvLT5udF9pZGVudGl0eSk7CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvLT5zZXJ2ZXJfcHJpbmNpcGFsX25hbWUpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvKTsKICAgIH0KCiAgICByZXR1cm4gcmVmczsKfQoKQk9PTCBScGNBdXRoSW5mb19Jc0VxdWFsKGNvbnN0IFJwY0F1dGhJbmZvICpBdXRoSW5mbzEsIGNvbnN0IFJwY0F1dGhJbmZvICpBdXRoSW5mbzIpCnsKICAgIGlmIChBdXRoSW5mbzEgPT0gQXV0aEluZm8yKQogICAgICAgIHJldHVybiBUUlVFOwoKICAgIGlmICghQXV0aEluZm8xIHx8ICFBdXRoSW5mbzIpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmICgoQXV0aEluZm8xLT5BdXRobkxldmVsICE9IEF1dGhJbmZvMi0+QXV0aG5MZXZlbCkgfHwKICAgICAgICAoQXV0aEluZm8xLT5BdXRoblN2YyAhPSBBdXRoSW5mbzItPkF1dGhuU3ZjKSkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKEF1dGhJbmZvMS0+aWRlbnRpdHkgPT0gQXV0aEluZm8yLT5pZGVudGl0eSkKICAgICAgICByZXR1cm4gVFJVRTsKCiAgICBpZiAoIUF1dGhJbmZvMS0+aWRlbnRpdHkgfHwgIUF1dGhJbmZvMi0+aWRlbnRpdHkpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChoYXNfbnRfYXV0aF9pZGVudGl0eShBdXRoSW5mbzEtPkF1dGhuU3ZjKSkKICAgIHsKICAgICAgICBjb25zdCBTRUNfV0lOTlRfQVVUSF9JREVOVElUWV9XICppZGVudGl0eTEgPSBBdXRoSW5mbzEtPm50X2lkZW50aXR5OwogICAgICAgIGNvbnN0IFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1cgKmlkZW50aXR5MiA9IEF1dGhJbmZvMi0+bnRfaWRlbnRpdHk7CiAgICAgICAgLyogY29tcGFyZSB1c2VyIG5hbWVzICovCiAgICAgICAgaWYgKGlkZW50aXR5MS0+VXNlckxlbmd0aCAhPSBpZGVudGl0eTItPlVzZXJMZW5ndGggfHwKICAgICAgICAgICAgbWVtY21wKGlkZW50aXR5MS0+VXNlciwgaWRlbnRpdHkyLT5Vc2VyLCBpZGVudGl0eTEtPlVzZXJMZW5ndGgpKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgLyogY29tcGFyZSBkb21haW4gbmFtZXMgKi8KICAgICAgICBpZiAoaWRlbnRpdHkxLT5Eb21haW5MZW5ndGggIT0gaWRlbnRpdHkyLT5Eb21haW5MZW5ndGggfHwKICAgICAgICAgICAgbWVtY21wKGlkZW50aXR5MS0+RG9tYWluLCBpZGVudGl0eTItPkRvbWFpbiwgaWRlbnRpdHkxLT5Eb21haW5MZW5ndGgpKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgLyogY29tcGFyZSBwYXNzd29yZHMgKi8KICAgICAgICBpZiAoaWRlbnRpdHkxLT5QYXNzd29yZExlbmd0aCAhPSBpZGVudGl0eTItPlBhc3N3b3JkTGVuZ3RoIHx8CiAgICAgICAgICAgIG1lbWNtcChpZGVudGl0eTEtPlBhc3N3b3JkLCBpZGVudGl0eTItPlBhc3N3b3JkLCBpZGVudGl0eTEtPlBhc3N3b3JkTGVuZ3RoKSkKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQogICAgZWxzZQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICByZXR1cm4gVFJVRTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgUnBjUXVhbGl0eU9mU2VydmljZV9DcmVhdGUoY29uc3QgUlBDX1NFQ1VSSVRZX1FPUyAqcW9zX3NyYywgQk9PTCB1bmljb2RlLCBScGNRdWFsaXR5T2ZTZXJ2aWNlICoqcW9zX2RzdCkKewogICAgUnBjUXVhbGl0eU9mU2VydmljZSAqcW9zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqcW9zKSk7CgogICAgaWYgKCFxb3MpCiAgICAgICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CgogICAgcW9zLT5yZWZzID0gMTsKICAgIHFvcy0+cW9zID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqcW9zLT5xb3MpKTsKICAgIGlmICghcW9zLT5xb3MpIGdvdG8gZXJyb3I7CiAgICBxb3MtPnFvcy0+VmVyc2lvbiA9IHFvc19zcmMtPlZlcnNpb247CiAgICBxb3MtPnFvcy0+Q2FwYWJpbGl0aWVzID0gcW9zX3NyYy0+Q2FwYWJpbGl0aWVzOwogICAgcW9zLT5xb3MtPklkZW50aXR5VHJhY2tpbmcgPSBxb3Nfc3JjLT5JZGVudGl0eVRyYWNraW5nOwogICAgcW9zLT5xb3MtPkltcGVyc29uYXRpb25UeXBlID0gcW9zX3NyYy0+SW1wZXJzb25hdGlvblR5cGU7CiAgICBxb3MtPnFvcy0+QWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGUgPSAwOwoKICAgIGlmIChxb3Nfc3JjLT5WZXJzaW9uID49IDIpCiAgICB7CiAgICAgICAgY29uc3QgUlBDX1NFQ1VSSVRZX1FPU19WMl9XICpxb3Nfc3JjMiA9IChjb25zdCBSUENfU0VDVVJJVFlfUU9TX1YyX1cgKilxb3Nfc3JjOwogICAgICAgIHFvcy0+cW9zLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSA9IHFvc19zcmMyLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZTsKICAgICAgICBpZiAocW9zX3NyYzItPkFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlID09IFJQQ19DX0FVVEhOX0lORk9fVFlQRV9IVFRQKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgUlBDX0hUVFBfVFJBTlNQT1JUX0NSRURFTlRJQUxTX1cgKmh0dHBfY3JlZGVudGlhbHNfc3JjID0gcW9zX3NyYzItPnUuSHR0cENyZWRlbnRpYWxzOwogICAgICAgICAgICBSUENfSFRUUF9UUkFOU1BPUlRfQ1JFREVOVElBTFNfVyAqaHR0cF9jcmVkZW50aWFsc19kc3Q7CgogICAgICAgICAgICBodHRwX2NyZWRlbnRpYWxzX2RzdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoKmh0dHBfY3JlZGVudGlhbHNfZHN0KSk7CiAgICAgICAgICAgIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscyA9IGh0dHBfY3JlZGVudGlhbHNfZHN0OwogICAgICAgICAgICBpZiAoIWh0dHBfY3JlZGVudGlhbHNfZHN0KSBnb3RvIGVycm9yOwogICAgICAgICAgICBodHRwX2NyZWRlbnRpYWxzX2RzdC0+VHJhbnNwb3J0Q3JlZGVudGlhbHMgPSBOVUxMOwogICAgICAgICAgICBodHRwX2NyZWRlbnRpYWxzX2RzdC0+RmxhZ3MgPSBodHRwX2NyZWRlbnRpYWxzX3NyYy0+RmxhZ3M7CiAgICAgICAgICAgIGh0dHBfY3JlZGVudGlhbHNfZHN0LT5BdXRoZW50aWNhdGlvblRhcmdldCA9IGh0dHBfY3JlZGVudGlhbHNfc3JjLT5BdXRoZW50aWNhdGlvblRhcmdldDsKICAgICAgICAgICAgaHR0cF9jcmVkZW50aWFsc19kc3QtPk51bWJlck9mQXV0aG5TY2hlbWVzID0gaHR0cF9jcmVkZW50aWFsc19zcmMtPk51bWJlck9mQXV0aG5TY2hlbWVzOwogICAgICAgICAgICBodHRwX2NyZWRlbnRpYWxzX2RzdC0+QXV0aG5TY2hlbWVzID0gTlVMTDsKICAgICAgICAgICAgaHR0cF9jcmVkZW50aWFsc19kc3QtPlNlcnZlckNlcnRpZmljYXRlU3ViamVjdCA9IE5VTEw7CiAgICAgICAgICAgIGlmIChodHRwX2NyZWRlbnRpYWxzX3NyYy0+VHJhbnNwb3J0Q3JlZGVudGlhbHMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1cgKmNyZWRfZHN0OwogICAgICAgICAgICAgICAgY3JlZF9kc3QgPSBodHRwX2NyZWRlbnRpYWxzX2RzdC0+VHJhbnNwb3J0Q3JlZGVudGlhbHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpjcmVkX2RzdCkpOwogICAgICAgICAgICAgICAgaWYgKCFjcmVkX2RzdCkgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgIGNyZWRfZHN0LT5GbGFncyA9IFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1VOSUNPREU7CiAgICAgICAgICAgICAgICBpZiAodW5pY29kZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBTRUNfV0lOTlRfQVVUSF9JREVOVElUWV9XICpjcmVkX3NyYyA9IGh0dHBfY3JlZGVudGlhbHNfc3JjLT5UcmFuc3BvcnRDcmVkZW50aWFsczsKICAgICAgICAgICAgICAgICAgICBjcmVkX2RzdC0+VXNlckxlbmd0aCA9IGNyZWRfc3JjLT5Vc2VyTGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGNyZWRfZHN0LT5QYXNzd29yZExlbmd0aCA9IGNyZWRfc3JjLT5QYXNzd29yZExlbmd0aDsKICAgICAgICAgICAgICAgICAgICBjcmVkX2RzdC0+RG9tYWluTGVuZ3RoID0gY3JlZF9zcmMtPkRvbWFpbkxlbmd0aDsKICAgICAgICAgICAgICAgICAgICBjcmVkX2RzdC0+VXNlciA9IFJQQ1JUNF9zdHJuZHVwVyhjcmVkX3NyYy0+VXNlciwgY3JlZF9zcmMtPlVzZXJMZW5ndGgpOwogICAgICAgICAgICAgICAgICAgIGNyZWRfZHN0LT5QYXNzd29yZCA9IFJQQ1JUNF9zdHJuZHVwVyhjcmVkX3NyYy0+UGFzc3dvcmQsIGNyZWRfc3JjLT5QYXNzd29yZExlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgY3JlZF9kc3QtPkRvbWFpbiA9IFJQQ1JUNF9zdHJuZHVwVyhjcmVkX3NyYy0+RG9tYWluLCBjcmVkX3NyYy0+RG9tYWluTGVuZ3RoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBTRUNfV0lOTlRfQVVUSF9JREVOVElUWV9BICpjcmVkX3NyYyA9IChjb25zdCBTRUNfV0lOTlRfQVVUSF9JREVOVElUWV9BICopaHR0cF9jcmVkZW50aWFsc19zcmMtPlRyYW5zcG9ydENyZWRlbnRpYWxzOwogICAgICAgICAgICAgICAgICAgIGNyZWRfZHN0LT5Vc2VyTGVuZ3RoID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChjaGFyICopY3JlZF9zcmMtPlVzZXIsIGNyZWRfc3JjLT5Vc2VyTGVuZ3RoLCBOVUxMLCAwKTsKICAgICAgICAgICAgICAgICAgICBjcmVkX2RzdC0+RG9tYWluTGVuZ3RoID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChjaGFyICopY3JlZF9zcmMtPkRvbWFpbiwgY3JlZF9zcmMtPkRvbWFpbkxlbmd0aCwgTlVMTCwgMCk7CiAgICAgICAgICAgICAgICAgICAgY3JlZF9kc3QtPlBhc3N3b3JkTGVuZ3RoID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChjaGFyICopY3JlZF9zcmMtPlBhc3N3b3JkLCBjcmVkX3NyYy0+UGFzc3dvcmRMZW5ndGgsIE5VTEwsIDApOwogICAgICAgICAgICAgICAgICAgIGNyZWRfZHN0LT5Vc2VyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNyZWRfZHN0LT5Vc2VyTGVuZ3RoICogc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgICAgICAgICAgICAgY3JlZF9kc3QtPlBhc3N3b3JkID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNyZWRfZHN0LT5QYXNzd29yZExlbmd0aCAqIHNpemVvZihXQ0hBUikpOwogICAgICAgICAgICAgICAgICAgIGNyZWRfZHN0LT5Eb21haW4gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY3JlZF9kc3QtPkRvbWFpbkxlbmd0aCAqIHNpemVvZihXQ0hBUikpOwogICAgICAgICAgICAgICAgICAgIGlmICghY3JlZF9kc3QgfHwgIWNyZWRfZHN0LT5QYXNzd29yZCB8fCAhY3JlZF9kc3QtPkRvbWFpbikgZ290byBlcnJvcjsKICAgICAgICAgICAgICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgKGNoYXIgKiljcmVkX3NyYy0+VXNlciwgY3JlZF9zcmMtPlVzZXJMZW5ndGgsIGNyZWRfZHN0LT5Vc2VyLCBjcmVkX2RzdC0+VXNlckxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChjaGFyICopY3JlZF9zcmMtPkRvbWFpbiwgY3JlZF9zcmMtPkRvbWFpbkxlbmd0aCwgY3JlZF9kc3QtPkRvbWFpbiwgY3JlZF9kc3QtPkRvbWFpbkxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIChjaGFyICopY3JlZF9zcmMtPlBhc3N3b3JkLCBjcmVkX3NyYy0+UGFzc3dvcmRMZW5ndGgsIGNyZWRfZHN0LT5QYXNzd29yZCwgY3JlZF9kc3QtPlBhc3N3b3JkTGVuZ3RoKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaHR0cF9jcmVkZW50aWFsc19zcmMtPk51bWJlck9mQXV0aG5TY2hlbWVzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBodHRwX2NyZWRlbnRpYWxzX2RzdC0+QXV0aG5TY2hlbWVzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGh0dHBfY3JlZGVudGlhbHNfc3JjLT5OdW1iZXJPZkF1dGhuU2NoZW1lcyAqIHNpemVvZigqaHR0cF9jcmVkZW50aWFsc19kc3QtPkF1dGhuU2NoZW1lcykpOwogICAgICAgICAgICAgICAgaWYgKCFodHRwX2NyZWRlbnRpYWxzX2RzdC0+QXV0aG5TY2hlbWVzKSBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgbWVtY3B5KGh0dHBfY3JlZGVudGlhbHNfZHN0LT5BdXRoblNjaGVtZXMsIGh0dHBfY3JlZGVudGlhbHNfc3JjLT5BdXRoblNjaGVtZXMsIGh0dHBfY3JlZGVudGlhbHNfc3JjLT5OdW1iZXJPZkF1dGhuU2NoZW1lcyAqIHNpemVvZigqaHR0cF9jcmVkZW50aWFsc19kc3QtPkF1dGhuU2NoZW1lcykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChodHRwX2NyZWRlbnRpYWxzX3NyYy0+U2VydmVyQ2VydGlmaWNhdGVTdWJqZWN0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAodW5pY29kZSkKICAgICAgICAgICAgICAgICAgICBodHRwX2NyZWRlbnRpYWxzX2RzdC0+U2VydmVyQ2VydGlmaWNhdGVTdWJqZWN0ID0KICAgICAgICAgICAgICAgICAgICAgICAgUlBDUlQ0X3N0cm5kdXBXKGh0dHBfY3JlZGVudGlhbHNfc3JjLT5TZXJ2ZXJDZXJ0aWZpY2F0ZVN1YmplY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJsZW5XKGh0dHBfY3JlZGVudGlhbHNfc3JjLT5TZXJ2ZXJDZXJ0aWZpY2F0ZVN1YmplY3QpKTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBodHRwX2NyZWRlbnRpYWxzX2RzdC0+U2VydmVyQ2VydGlmaWNhdGVTdWJqZWN0ID0KICAgICAgICAgICAgICAgICAgICAgICAgUlBDUlQ0X3N0cmR1cEF0b1coKGNoYXIgKilodHRwX2NyZWRlbnRpYWxzX3NyYy0+U2VydmVyQ2VydGlmaWNhdGVTdWJqZWN0KTsKICAgICAgICAgICAgICAgIGlmICghaHR0cF9jcmVkZW50aWFsc19kc3QtPlNlcnZlckNlcnRpZmljYXRlU3ViamVjdCkgZ290byBlcnJvcjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgICpxb3NfZHN0ID0gcW9zOwogICAgcmV0dXJuIFJQQ19TX09LOwoKZXJyb3I6CiAgICBpZiAocW9zLT5xb3MpCiAgICB7CiAgICAgICAgaWYgKHFvcy0+cW9zLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSA9PSBSUENfQ19BVVRITl9JTkZPX1RZUEVfSFRUUCAmJgogICAgICAgICAgICBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMpCiAgICAgICAgewogICAgICAgICAgICBpZiAocW9zLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzLT5UcmFuc3BvcnRDcmVkZW50aWFscykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzLT5UcmFuc3BvcnRDcmVkZW50aWFscy0+VXNlcik7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPlRyYW5zcG9ydENyZWRlbnRpYWxzLT5Eb21haW4pOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzLT5UcmFuc3BvcnRDcmVkZW50aWFscy0+UGFzc3dvcmQpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzLT5UcmFuc3BvcnRDcmVkZW50aWFscyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzLT5BdXRoblNjaGVtZXMpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPlNlcnZlckNlcnRpZmljYXRlU3ViamVjdCk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscyk7CiAgICAgICAgfQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcy0+cW9zKTsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcyk7CiAgICByZXR1cm4gUlBDX1NfT1VUX09GX1JFU09VUkNFUzsKfQoKVUxPTkcgUnBjUXVhbGl0eU9mU2VydmljZV9BZGRSZWYoUnBjUXVhbGl0eU9mU2VydmljZSAqcW9zKQp7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJnFvcy0+cmVmcyk7Cn0KClVMT05HIFJwY1F1YWxpdHlPZlNlcnZpY2VfUmVsZWFzZShScGNRdWFsaXR5T2ZTZXJ2aWNlICpxb3MpCnsKICAgIFVMT05HIHJlZnMgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmcW9zLT5yZWZzKTsKCiAgICBpZiAoIXJlZnMpCiAgICB7CiAgICAgICAgaWYgKHFvcy0+cW9zLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSA9PSBSUENfQ19BVVRITl9JTkZPX1RZUEVfSFRUUCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPlRyYW5zcG9ydENyZWRlbnRpYWxzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPlRyYW5zcG9ydENyZWRlbnRpYWxzLT5Vc2VyKTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscy0+VHJhbnNwb3J0Q3JlZGVudGlhbHMtPkRvbWFpbik7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPlRyYW5zcG9ydENyZWRlbnRpYWxzLT5QYXNzd29yZCk7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPlRyYW5zcG9ydENyZWRlbnRpYWxzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPkF1dGhuU2NoZW1lcyk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscy0+U2VydmVyQ2VydGlmaWNhdGVTdWJqZWN0KTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzKTsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zLT5xb3MpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcyk7CiAgICB9CiAgICByZXR1cm4gcmVmczsKfQoKQk9PTCBScGNRdWFsaXR5T2ZTZXJ2aWNlX0lzRXF1YWwoY29uc3QgUnBjUXVhbGl0eU9mU2VydmljZSAqcW9zMSwgY29uc3QgUnBjUXVhbGl0eU9mU2VydmljZSAqcW9zMikKewogICAgaWYgKHFvczEgPT0gcW9zMikKICAgICAgICByZXR1cm4gVFJVRTsKCiAgICBpZiAoIXFvczEgfHwgIXFvczIpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIFRSQUNFKCJxb3MxID0geyAlbGQgJWxkICVsZCAlbGQgfSwgcW9zMiA9IHsgJWxkICVsZCAlbGQgJWxkIH1cbiIsCiAgICAgICAgcW9zMS0+cW9zLT5DYXBhYmlsaXRpZXMsIHFvczEtPnFvcy0+SWRlbnRpdHlUcmFja2luZywKICAgICAgICBxb3MxLT5xb3MtPkltcGVyc29uYXRpb25UeXBlLCBxb3MxLT5xb3MtPkFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlLAogICAgICAgIHFvczItPnFvcy0+Q2FwYWJpbGl0aWVzLCBxb3MyLT5xb3MtPklkZW50aXR5VHJhY2tpbmcsCiAgICAgICAgcW9zMi0+cW9zLT5JbXBlcnNvbmF0aW9uVHlwZSwgcW9zMi0+cW9zLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSk7CgogICAgaWYgKChxb3MxLT5xb3MtPkNhcGFiaWxpdGllcyAhPSBxb3MyLT5xb3MtPkNhcGFiaWxpdGllcykgfHwKICAgICAgICAocW9zMS0+cW9zLT5JZGVudGl0eVRyYWNraW5nICE9IHFvczItPnFvcy0+SWRlbnRpdHlUcmFja2luZykgfHwKICAgICAgICAocW9zMS0+cW9zLT5JbXBlcnNvbmF0aW9uVHlwZSAhPSBxb3MyLT5xb3MtPkltcGVyc29uYXRpb25UeXBlKSB8fAogICAgICAgIChxb3MxLT5xb3MtPkFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlICE9IHFvczItPnFvcy0+QWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGUpKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAocW9zMS0+cW9zLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSA9PSBSUENfQ19BVVRITl9JTkZPX1RZUEVfSFRUUCkKICAgIHsKICAgICAgICBjb25zdCBSUENfSFRUUF9UUkFOU1BPUlRfQ1JFREVOVElBTFNfVyAqaHR0cF9jcmVkZW50aWFsczEgPSBxb3MxLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzOwogICAgICAgIGNvbnN0IFJQQ19IVFRQX1RSQU5TUE9SVF9DUkVERU5USUFMU19XICpodHRwX2NyZWRlbnRpYWxzMiA9IHFvczItPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHM7CgogICAgICAgIGlmIChodHRwX2NyZWRlbnRpYWxzMS0+RmxhZ3MgIT0gaHR0cF9jcmVkZW50aWFsczItPkZsYWdzKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgICAgIGlmIChodHRwX2NyZWRlbnRpYWxzMS0+QXV0aGVudGljYXRpb25UYXJnZXQgIT0gaHR0cF9jcmVkZW50aWFsczItPkF1dGhlbnRpY2F0aW9uVGFyZ2V0KQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgICAgIC8qIGF1dGhlbnRpY2F0aW9uIHNjaGVtZXMgYW5kIHNlcnZlciBjZXJ0aWZpY2F0ZSBzdWJqZWN0IG5vdCBjdXJyZW50bHkgdXNlZCAqLwoKICAgICAgICBpZiAoaHR0cF9jcmVkZW50aWFsczEtPlRyYW5zcG9ydENyZWRlbnRpYWxzICE9IGh0dHBfY3JlZGVudGlhbHMyLT5UcmFuc3BvcnRDcmVkZW50aWFscykKICAgICAgICB7CiAgICAgICAgICAgIGNvbnN0IFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1cgKmlkZW50aXR5MSA9IGh0dHBfY3JlZGVudGlhbHMxLT5UcmFuc3BvcnRDcmVkZW50aWFsczsKICAgICAgICAgICAgY29uc3QgU0VDX1dJTk5UX0FVVEhfSURFTlRJVFlfVyAqaWRlbnRpdHkyID0gaHR0cF9jcmVkZW50aWFsczItPlRyYW5zcG9ydENyZWRlbnRpYWxzOwoKICAgICAgICAgICAgaWYgKCFpZGVudGl0eTEgfHwgIWlkZW50aXR5MikKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICAgICAgICAgIC8qIGNvbXBhcmUgdXNlciBuYW1lcyAqLwogICAgICAgICAgICBpZiAoaWRlbnRpdHkxLT5Vc2VyTGVuZ3RoICE9IGlkZW50aXR5Mi0+VXNlckxlbmd0aCB8fAogICAgICAgICAgICAgICAgbWVtY21wKGlkZW50aXR5MS0+VXNlciwgaWRlbnRpdHkyLT5Vc2VyLCBpZGVudGl0eTEtPlVzZXJMZW5ndGgpKQogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICAvKiBjb21wYXJlIGRvbWFpbiBuYW1lcyAqLwogICAgICAgICAgICBpZiAoaWRlbnRpdHkxLT5Eb21haW5MZW5ndGggIT0gaWRlbnRpdHkyLT5Eb21haW5MZW5ndGggfHwKICAgICAgICAgICAgICAgIG1lbWNtcChpZGVudGl0eTEtPkRvbWFpbiwgaWRlbnRpdHkyLT5Eb21haW4sIGlkZW50aXR5MS0+RG9tYWluTGVuZ3RoKSkKICAgICAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAgICAgLyogY29tcGFyZSBwYXNzd29yZHMgKi8KICAgICAgICAgICAgaWYgKGlkZW50aXR5MS0+UGFzc3dvcmRMZW5ndGggIT0gaWRlbnRpdHkyLT5QYXNzd29yZExlbmd0aCB8fAogICAgICAgICAgICAgICAgbWVtY21wKGlkZW50aXR5MS0+UGFzc3dvcmQsIGlkZW50aXR5Mi0+UGFzc3dvcmQsIGlkZW50aXR5MS0+UGFzc3dvcmRMZW5ndGgpKQogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1JldmVydFRvU2VsZiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNSZXZlcnRUb1NlbGYodm9pZCkKewogICAgRklYTUUoInN0dWJcbiIpOwogICAgUmV2ZXJ0VG9TZWxmKCk7CiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNNZ210U2V0Q29tVGltZW91dCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNNZ210U2V0Q29tVGltZW91dChSUENfQklORElOR19IQU5ETEUgQmluZGluZ0hhbmRsZSwgdW5zaWduZWQgaW50IFRpbWVvdXQpCnsKICAgIEZJWE1FKCIoJXAsICVkKTogc3R1YlxuIiwgQmluZGluZ0hhbmRsZSwgVGltZW91dCk7CiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nSW5xQXV0aEluZm9FeEEgKFJQQ1JUNC5AKQogKi8KUlBDUlRBUEkgUlBDX1NUQVRVUyBSUENfRU5UUlkKUnBjQmluZGluZ0lucUF1dGhJbmZvRXhBKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX0NTVFIgKlNlcnZlclByaW5jTmFtZSwgVUxPTkcgKkF1dGhuTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgKkF1dGhuU3ZjLCBSUENfQVVUSF9JREVOVElUWV9IQU5ETEUgKkF1dGhJZGVudGl0eSwgVUxPTkcgKkF1dGh6U3ZjLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIFJwY1Fvc1ZlcnNpb24sIFJQQ19TRUNVUklUWV9RT1MgKlNlY3VyaXR5UU9TICkKewogICAgRklYTUUoIiVwICVwICVwICVwICVwICVwICV1ICVwXG4iLCBCaW5kaW5nLCBTZXJ2ZXJQcmluY05hbWUsIEF1dGhuTGV2ZWwsCiAgICAgICAgICBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2YywgUnBjUW9zVmVyc2lvbiwgU2VjdXJpdHlRT1MpOwogICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdJbnFBdXRoSW5mb0V4VyAoUlBDUlQ0LkApCiAqLwpSUENSVEFQSSBSUENfU1RBVFVTIFJQQ19FTlRSWQpScGNCaW5kaW5nSW5xQXV0aEluZm9FeFcoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfV1NUUiAqU2VydmVyUHJpbmNOYW1lLCBVTE9ORyAqQXV0aG5MZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyAqQXV0aG5TdmMsIFJQQ19BVVRIX0lERU5USVRZX0hBTkRMRSAqQXV0aElkZW50aXR5LCBVTE9ORyAqQXV0aHpTdmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgUnBjUW9zVmVyc2lvbiwgUlBDX1NFQ1VSSVRZX1FPUyAqU2VjdXJpdHlRT1MgKQp7CiAgICBGSVhNRSgiJXAgJXAgJXAgJXAgJXAgJXAgJXUgJXBcbiIsIEJpbmRpbmcsIFNlcnZlclByaW5jTmFtZSwgQXV0aG5MZXZlbCwKICAgICAgICAgIEF1dGhuU3ZjLCBBdXRoSWRlbnRpdHksIEF1dGh6U3ZjLCBScGNRb3NWZXJzaW9uLCBTZWN1cml0eVFPUyk7CiAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0lucUF1dGhJbmZvQSAoUlBDUlQ0LkApCiAqLwpSUENSVEFQSSBSUENfU1RBVFVTIFJQQ19FTlRSWQpScGNCaW5kaW5nSW5xQXV0aEluZm9BKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX0NTVFIgKlNlcnZlclByaW5jTmFtZSwgVUxPTkcgKkF1dGhuTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HICpBdXRoblN2YywgUlBDX0FVVEhfSURFTlRJVFlfSEFORExFICpBdXRoSWRlbnRpdHksIFVMT05HICpBdXRoelN2YyApCnsKICAgIEZJWE1FKCIlcCAlcCAlcCAlcCAlcCAlcFxuIiwgQmluZGluZywgU2VydmVyUHJpbmNOYW1lLCBBdXRobkxldmVsLAogICAgICAgICAgQXV0aG5TdmMsIEF1dGhJZGVudGl0eSwgQXV0aHpTdmMpOwogICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdJbnFBdXRoSW5mb1cgKFJQQ1JUNC5AKQogKi8KUlBDUlRBUEkgUlBDX1NUQVRVUyBSUENfRU5UUlkKUnBjQmluZGluZ0lucUF1dGhJbmZvVyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFJQQ19XU1RSICpTZXJ2ZXJQcmluY05hbWUsIFVMT05HICpBdXRobkxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyAqQXV0aG5TdmMsIFJQQ19BVVRIX0lERU5USVRZX0hBTkRMRSAqQXV0aElkZW50aXR5LCBVTE9ORyAqQXV0aHpTdmMgKQp7CiAgICBGSVhNRSgiJXAgJXAgJXAgJXAgJXAgJXBcbiIsIEJpbmRpbmcsIFNlcnZlclByaW5jTmFtZSwgQXV0aG5MZXZlbCwKICAgICAgICAgIEF1dGhuU3ZjLCBBdXRoSWRlbnRpdHksIEF1dGh6U3ZjKTsKICAgIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nU2V0QXV0aEluZm9FeEEgKFJQQ1JUNC5AKQogKi8KUlBDUlRBUEkgUlBDX1NUQVRVUyBSUENfRU5UUlkKUnBjQmluZGluZ1NldEF1dGhJbmZvRXhBKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX0NTVFIgU2VydmVyUHJpbmNOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIEF1dGhuTGV2ZWwsIFVMT05HIEF1dGhuU3ZjLAogICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19BVVRIX0lERU5USVRZX0hBTkRMRSBBdXRoSWRlbnRpdHksIFVMT05HIEF1dGh6U3ZyLAogICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19TRUNVUklUWV9RT1MgKlNlY3VyaXR5UW9zICkKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKICBTRUNVUklUWV9TVEFUVVMgcjsKICBDcmVkSGFuZGxlIGNyZWQ7CiAgVGltZVN0YW1wIGV4cDsKICBVTE9ORyBwYWNrYWdlX2NvdW50OwogIFVMT05HIGk7CiAgUFNlY1BrZ0luZm9BIHBhY2thZ2VzOwogIFVMT05HIGNiTWF4VG9rZW47CgogIFRSQUNFKCIlcCAlcyAldSAldSAlcCAldSAlcFxuIiwgQmluZGluZywgZGVidWdzdHJfYSgoY29uc3QgY2hhciopU2VydmVyUHJpbmNOYW1lKSwKICAgICAgICBBdXRobkxldmVsLCBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2ciwgU2VjdXJpdHlRb3MpOwoKICBpZiAoU2VjdXJpdHlRb3MpCiAgewogICAgICBSUENfU1RBVFVTIHN0YXR1czsKCiAgICAgIFRSQUNFKCJTZWN1cml0eVFvcyB7IFZlcnNpb249JWxkLCBDYXBhYmlsdGllcz0weCVseCwgSWRlbnRpdHlUcmFja2luZz0lbGQsIEltcGVyc29uYXRpb25MZXZlbD0lbGQiLAogICAgICAgICAgICBTZWN1cml0eVFvcy0+VmVyc2lvbiwgU2VjdXJpdHlRb3MtPkNhcGFiaWxpdGllcywgU2VjdXJpdHlRb3MtPklkZW50aXR5VHJhY2tpbmcsIFNlY3VyaXR5UW9zLT5JbXBlcnNvbmF0aW9uVHlwZSk7CiAgICAgIGlmIChTZWN1cml0eVFvcy0+VmVyc2lvbiA+PSAyKQogICAgICB7CiAgICAgICAgICBjb25zdCBSUENfU0VDVVJJVFlfUU9TX1YyX0EgKlNlY3VyaXR5UW9zMiA9IChjb25zdCBSUENfU0VDVVJJVFlfUU9TX1YyX0EgKilTZWN1cml0eVFvczsKICAgICAgICAgIFRSQUNFKCIsIEFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlPSVsZCIsIFNlY3VyaXR5UW9zMi0+QWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGUpOwogICAgICAgICAgaWYgKFNlY3VyaXR5UW9zMi0+QWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGUgPT0gUlBDX0NfQVVUSE5fSU5GT19UWVBFX0hUVFApCiAgICAgICAgICAgICAgVFJBQ0UoIiwgeyAlcCwgMHglbHgsICVsZCwgJWxkLCAlcCwgJXMgfSIsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+VHJhbnNwb3J0Q3JlZGVudGlhbHMsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+QXV0aGVudGljYXRpb25UYXJnZXQsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+TnVtYmVyT2ZBdXRoblNjaGVtZXMsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+QXV0aG5TY2hlbWVzLAogICAgICAgICAgICAgICAgICAgIFNlY3VyaXR5UW9zMi0+dS5IdHRwQ3JlZGVudGlhbHMtPlNlcnZlckNlcnRpZmljYXRlU3ViamVjdCk7CiAgICAgIH0KICAgICAgVFJBQ0UoIn1cbiIpOwogICAgICBzdGF0dXMgPSBScGNRdWFsaXR5T2ZTZXJ2aWNlX0NyZWF0ZShTZWN1cml0eVFvcywgRkFMU0UsICZiaW5kLT5RT1MpOwogICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgICAgcmV0dXJuIHN0YXR1czsKICB9CiAgZWxzZQogIHsKICAgICAgaWYgKGJpbmQtPlFPUykgUnBjUXVhbGl0eU9mU2VydmljZV9SZWxlYXNlKGJpbmQtPlFPUyk7CiAgICAgIGJpbmQtPlFPUyA9IE5VTEw7CiAgfQoKICBpZiAoQXV0aG5TdmMgPT0gUlBDX0NfQVVUSE5fREVGQVVMVCkKICAgIEF1dGhuU3ZjID0gUlBDX0NfQVVUSE5fV0lOTlQ7CgogIC8qIEZJWE1FOiB0aGUgbWFwcGluZyBzaG91bGQgcHJvYmFibHkgYmUgcmV0cmlldmVkIHVzaW5nIFNTUEkgc29tZWhvdyAqLwogIGlmIChBdXRobkxldmVsID09IFJQQ19DX0FVVEhOX0xFVkVMX0RFRkFVTFQpCiAgICBBdXRobkxldmVsID0gUlBDX0NfQVVUSE5fTEVWRUxfTk9ORTsKCiAgaWYgKChBdXRobkxldmVsID09IFJQQ19DX0FVVEhOX0xFVkVMX05PTkUpIHx8IChBdXRoblN2YyA9PSBSUENfQ19BVVRITl9OT05FKSkKICB7CiAgICBpZiAoYmluZC0+QXV0aEluZm8pIFJwY0F1dGhJbmZvX1JlbGVhc2UoYmluZC0+QXV0aEluZm8pOwogICAgYmluZC0+QXV0aEluZm8gPSBOVUxMOwogICAgcmV0dXJuIFJQQ19TX09LOwogIH0KCiAgaWYgKEF1dGhuTGV2ZWwgPiBSUENfQ19BVVRITl9MRVZFTF9QS1RfUFJJVkFDWSkKICB7CiAgICBGSVhNRSgidW5rbm93biBBdXRobkxldmVsICV1XG4iLCBBdXRobkxldmVsKTsKICAgIHJldHVybiBSUENfU19VTktOT1dOX0FVVEhOX0xFVkVMOwogIH0KCiAgaWYgKEF1dGh6U3ZyKQogIHsKICAgIEZJWE1FKCJ1bnN1cHBvcnRlZCBBdXRoelN2ciAldVxuIiwgQXV0aHpTdnIpOwogICAgcmV0dXJuIFJQQ19TX1VOS05PV05fQVVUSFpfU0VSVklDRTsKICB9CgogIHIgPSBFbnVtZXJhdGVTZWN1cml0eVBhY2thZ2VzQSgmcGFja2FnZV9jb3VudCwgJnBhY2thZ2VzKTsKICBpZiAociAhPSBTRUNfRV9PSykKICB7CiAgICBFUlIoIkVudW1lcmF0ZVNlY3VyaXR5UGFja2FnZXNBIGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4eFxuIiwgcik7CiAgICByZXR1cm4gUlBDX1NfU0VDX1BLR19FUlJPUjsKICB9CgogIGZvciAoaSA9IDA7IGkgPCBwYWNrYWdlX2NvdW50OyBpKyspCiAgICBpZiAocGFja2FnZXNbaV0ud1JQQ0lEID09IEF1dGhuU3ZjKQogICAgICAgIGJyZWFrOwoKICBpZiAoaSA9PSBwYWNrYWdlX2NvdW50KQogIHsKICAgIEZJWE1FKCJ1bnN1cHBvcnRlZCBBdXRoblN2YyAldVxuIiwgQXV0aG5TdmMpOwogICAgRnJlZUNvbnRleHRCdWZmZXIocGFja2FnZXMpOwogICAgcmV0dXJuIFJQQ19TX1VOS05PV05fQVVUSE5fU0VSVklDRTsKICB9CgogIFRSQUNFKCJmb3VuZCBwYWNrYWdlICVzIGZvciBzZXJ2aWNlICV1XG4iLCBwYWNrYWdlc1tpXS5OYW1lLCBBdXRoblN2Yyk7CiAgciA9IEFjcXVpcmVDcmVkZW50aWFsc0hhbmRsZUEoTlVMTCwgcGFja2FnZXNbaV0uTmFtZSwgU0VDUEtHX0NSRURfT1VUQk9VTkQsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQXV0aElkZW50aXR5LCBOVUxMLCBOVUxMLCAmY3JlZCwgJmV4cCk7CiAgY2JNYXhUb2tlbiA9IHBhY2thZ2VzW2ldLmNiTWF4VG9rZW47CiAgRnJlZUNvbnRleHRCdWZmZXIocGFja2FnZXMpOwogIGlmIChyID09IEVSUk9SX1NVQ0NFU1MpCiAgewogICAgUnBjQXV0aEluZm8gKm5ld19hdXRoX2luZm87CiAgICByID0gUnBjQXV0aEluZm9fQ3JlYXRlKEF1dGhuTGV2ZWwsIEF1dGhuU3ZjLCBjcmVkLCBleHAsIGNiTWF4VG9rZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1dGhJZGVudGl0eSwgJm5ld19hdXRoX2luZm8pOwogICAgaWYgKHIgPT0gUlBDX1NfT0spCiAgICB7CiAgICAgIG5ld19hdXRoX2luZm8tPnNlcnZlcl9wcmluY2lwYWxfbmFtZSA9IFJQQ1JUNF9zdHJkdXBBdG9XKChjaGFyICopU2VydmVyUHJpbmNOYW1lKTsKICAgICAgaWYgKG5ld19hdXRoX2luZm8tPnNlcnZlcl9wcmluY2lwYWxfbmFtZSkKICAgICAgewogICAgICAgIGlmIChiaW5kLT5BdXRoSW5mbykgUnBjQXV0aEluZm9fUmVsZWFzZShiaW5kLT5BdXRoSW5mbyk7CiAgICAgICAgYmluZC0+QXV0aEluZm8gPSBuZXdfYXV0aF9pbmZvOwogICAgICB9CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIFJwY0F1dGhJbmZvX1JlbGVhc2UobmV3X2F1dGhfaW5mbyk7CiAgICAgICAgciA9IEVSUk9SX09VVE9GTUVNT1JZOwogICAgICB9CiAgICB9CiAgICBlbHNlCiAgICAgIEZyZWVDcmVkZW50aWFsc0hhbmRsZSgmY3JlZCk7CiAgICByZXR1cm4gcjsKICB9CiAgZWxzZQogIHsKICAgIEVSUigiQWNxdWlyZUNyZWRlbnRpYWxzSGFuZGxlQSBmYWlsZWQgd2l0aCBlcnJvciAweCUwOHhcbiIsIHIpOwogICAgcmV0dXJuIFJQQ19TX1NFQ19QS0dfRVJST1I7CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1NldEF1dGhJbmZvRXhXIChSUENSVDQuQCkKICovClJQQ1JUQVBJIFJQQ19TVEFUVVMgUlBDX0VOVFJZClJwY0JpbmRpbmdTZXRBdXRoSW5mb0V4VyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFJQQ19XU1RSIFNlcnZlclByaW5jTmFtZSwgVUxPTkcgQXV0aG5MZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyBBdXRoblN2YywgUlBDX0FVVEhfSURFTlRJVFlfSEFORExFIEF1dGhJZGVudGl0eSwgVUxPTkcgQXV0aHpTdnIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NFQ1VSSVRZX1FPUyAqU2VjdXJpdHlRb3MgKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwogIFNFQ1VSSVRZX1NUQVRVUyByOwogIENyZWRIYW5kbGUgY3JlZDsKICBUaW1lU3RhbXAgZXhwOwogIFVMT05HIHBhY2thZ2VfY291bnQ7CiAgVUxPTkcgaTsKICBQU2VjUGtnSW5mb1cgcGFja2FnZXM7CiAgVUxPTkcgY2JNYXhUb2tlbjsKCiAgVFJBQ0UoIiVwICVzICV1ICV1ICVwICV1ICVwXG4iLCBCaW5kaW5nLCBkZWJ1Z3N0cl93KChjb25zdCBXQ0hBUiopU2VydmVyUHJpbmNOYW1lKSwKICAgICAgICBBdXRobkxldmVsLCBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2ciwgU2VjdXJpdHlRb3MpOwoKICBpZiAoU2VjdXJpdHlRb3MpCiAgewogICAgICBSUENfU1RBVFVTIHN0YXR1czsKCiAgICAgIFRSQUNFKCJTZWN1cml0eVFvcyB7IFZlcnNpb249JWxkLCBDYXBhYmlsdGllcz0weCVseCwgSWRlbnRpdHlUcmFja2luZz0lbGQsIEltcGVyc29uYXRpb25MZXZlbD0lbGQiLAogICAgICAgICAgICBTZWN1cml0eVFvcy0+VmVyc2lvbiwgU2VjdXJpdHlRb3MtPkNhcGFiaWxpdGllcywgU2VjdXJpdHlRb3MtPklkZW50aXR5VHJhY2tpbmcsIFNlY3VyaXR5UW9zLT5JbXBlcnNvbmF0aW9uVHlwZSk7CiAgICAgIGlmIChTZWN1cml0eVFvcy0+VmVyc2lvbiA+PSAyKQogICAgICB7CiAgICAgICAgICBjb25zdCBSUENfU0VDVVJJVFlfUU9TX1YyX1cgKlNlY3VyaXR5UW9zMiA9IChjb25zdCBSUENfU0VDVVJJVFlfUU9TX1YyX1cgKilTZWN1cml0eVFvczsKICAgICAgICAgIFRSQUNFKCIsIEFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlPSVsZCIsIFNlY3VyaXR5UW9zMi0+QWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGUpOwogICAgICAgICAgaWYgKFNlY3VyaXR5UW9zMi0+QWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGUgPT0gUlBDX0NfQVVUSE5fSU5GT19UWVBFX0hUVFApCiAgICAgICAgICAgICAgVFJBQ0UoIiwgeyAlcCwgMHglbHgsICVsZCwgJWxkLCAlcCwgJXMgfSIsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+VHJhbnNwb3J0Q3JlZGVudGlhbHMsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+RmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+QXV0aGVudGljYXRpb25UYXJnZXQsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+TnVtYmVyT2ZBdXRoblNjaGVtZXMsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+QXV0aG5TY2hlbWVzLAogICAgICAgICAgICAgICAgICAgIGRlYnVnc3RyX3coU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+U2VydmVyQ2VydGlmaWNhdGVTdWJqZWN0KSk7CiAgICAgIH0KICAgICAgVFJBQ0UoIn1cbiIpOwogICAgICBzdGF0dXMgPSBScGNRdWFsaXR5T2ZTZXJ2aWNlX0NyZWF0ZShTZWN1cml0eVFvcywgVFJVRSwgJmJpbmQtPlFPUyk7CiAgICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICAgICAgICByZXR1cm4gc3RhdHVzOwogIH0KICBlbHNlCiAgewogICAgICBpZiAoYmluZC0+UU9TKSBScGNRdWFsaXR5T2ZTZXJ2aWNlX1JlbGVhc2UoYmluZC0+UU9TKTsKICAgICAgYmluZC0+UU9TID0gTlVMTDsKICB9CgogIGlmIChBdXRoblN2YyA9PSBSUENfQ19BVVRITl9ERUZBVUxUKQogICAgQXV0aG5TdmMgPSBSUENfQ19BVVRITl9XSU5OVDsKCiAgLyogRklYTUU6IHRoZSBtYXBwaW5nIHNob3VsZCBwcm9iYWJseSBiZSByZXRyaWV2ZWQgdXNpbmcgU1NQSSBzb21laG93ICovCiAgaWYgKEF1dGhuTGV2ZWwgPT0gUlBDX0NfQVVUSE5fTEVWRUxfREVGQVVMVCkKICAgIEF1dGhuTGV2ZWwgPSBSUENfQ19BVVRITl9MRVZFTF9OT05FOwoKICBpZiAoKEF1dGhuTGV2ZWwgPT0gUlBDX0NfQVVUSE5fTEVWRUxfTk9ORSkgfHwgKEF1dGhuU3ZjID09IFJQQ19DX0FVVEhOX05PTkUpKQogIHsKICAgIGlmIChiaW5kLT5BdXRoSW5mbykgUnBjQXV0aEluZm9fUmVsZWFzZShiaW5kLT5BdXRoSW5mbyk7CiAgICBiaW5kLT5BdXRoSW5mbyA9IE5VTEw7CiAgICByZXR1cm4gUlBDX1NfT0s7CiAgfQoKICBpZiAoQXV0aG5MZXZlbCA+IFJQQ19DX0FVVEhOX0xFVkVMX1BLVF9QUklWQUNZKQogIHsKICAgIEZJWE1FKCJ1bmtub3duIEF1dGhuTGV2ZWwgJXVcbiIsIEF1dGhuTGV2ZWwpOwogICAgcmV0dXJuIFJQQ19TX1VOS05PV05fQVVUSE5fTEVWRUw7CiAgfQoKICBpZiAoQXV0aHpTdnIpCiAgewogICAgRklYTUUoInVuc3VwcG9ydGVkIEF1dGh6U3ZyICV1XG4iLCBBdXRoelN2cik7CiAgICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRIWl9TRVJWSUNFOwogIH0KCiAgciA9IEVudW1lcmF0ZVNlY3VyaXR5UGFja2FnZXNXKCZwYWNrYWdlX2NvdW50LCAmcGFja2FnZXMpOwogIGlmIChyICE9IFNFQ19FX09LKQogIHsKICAgIEVSUigiRW51bWVyYXRlU2VjdXJpdHlQYWNrYWdlc0EgZmFpbGVkIHdpdGggZXJyb3IgMHglMDh4XG4iLCByKTsKICAgIHJldHVybiBSUENfU19TRUNfUEtHX0VSUk9SOwogIH0KCiAgZm9yIChpID0gMDsgaSA8IHBhY2thZ2VfY291bnQ7IGkrKykKICAgIGlmIChwYWNrYWdlc1tpXS53UlBDSUQgPT0gQXV0aG5TdmMpCiAgICAgICAgYnJlYWs7CgogIGlmIChpID09IHBhY2thZ2VfY291bnQpCiAgewogICAgRklYTUUoInVuc3VwcG9ydGVkIEF1dGhuU3ZjICV1XG4iLCBBdXRoblN2Yyk7CiAgICBGcmVlQ29udGV4dEJ1ZmZlcihwYWNrYWdlcyk7CiAgICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRITl9TRVJWSUNFOwogIH0KCiAgVFJBQ0UoImZvdW5kIHBhY2thZ2UgJXMgZm9yIHNlcnZpY2UgJXVcbiIsIGRlYnVnc3RyX3cocGFja2FnZXNbaV0uTmFtZSksIEF1dGhuU3ZjKTsKICByID0gQWNxdWlyZUNyZWRlbnRpYWxzSGFuZGxlVyhOVUxMLCBwYWNrYWdlc1tpXS5OYW1lLCBTRUNQS0dfQ1JFRF9PVVRCT1VORCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdXRoSWRlbnRpdHksIE5VTEwsIE5VTEwsICZjcmVkLCAmZXhwKTsKICBjYk1heFRva2VuID0gcGFja2FnZXNbaV0uY2JNYXhUb2tlbjsKICBGcmVlQ29udGV4dEJ1ZmZlcihwYWNrYWdlcyk7CiAgaWYgKHIgPT0gRVJST1JfU1VDQ0VTUykKICB7CiAgICBScGNBdXRoSW5mbyAqbmV3X2F1dGhfaW5mbzsKICAgIHIgPSBScGNBdXRoSW5mb19DcmVhdGUoQXV0aG5MZXZlbCwgQXV0aG5TdmMsIGNyZWQsIGV4cCwgY2JNYXhUb2tlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgQXV0aElkZW50aXR5LCAmbmV3X2F1dGhfaW5mbyk7CiAgICBpZiAociA9PSBSUENfU19PSykKICAgIHsKICAgICAgbmV3X2F1dGhfaW5mby0+c2VydmVyX3ByaW5jaXBhbF9uYW1lID0gUlBDUlQ0X3N0cmR1cFcoU2VydmVyUHJpbmNOYW1lKTsKICAgICAgaWYgKCFTZXJ2ZXJQcmluY05hbWUgfHwgbmV3X2F1dGhfaW5mby0+c2VydmVyX3ByaW5jaXBhbF9uYW1lKQogICAgICB7CiAgICAgICAgaWYgKGJpbmQtPkF1dGhJbmZvKSBScGNBdXRoSW5mb19SZWxlYXNlKGJpbmQtPkF1dGhJbmZvKTsKICAgICAgICBiaW5kLT5BdXRoSW5mbyA9IG5ld19hdXRoX2luZm87CiAgICAgIH0KICAgICAgZWxzZQogICAgICB7CiAgICAgICAgUnBjQXV0aEluZm9fUmVsZWFzZShuZXdfYXV0aF9pbmZvKTsKICAgICAgICByID0gRVJST1JfT1VUT0ZNRU1PUlk7CiAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgICAgRnJlZUNyZWRlbnRpYWxzSGFuZGxlKCZjcmVkKTsKICAgIHJldHVybiByOwogIH0KICBlbHNlCiAgewogICAgRVJSKCJBY3F1aXJlQ3JlZGVudGlhbHNIYW5kbGVBIGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4eFxuIiwgcik7CiAgICByZXR1cm4gUlBDX1NfU0VDX1BLR19FUlJPUjsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nU2V0QXV0aEluZm9BIChSUENSVDQuQCkKICovClJQQ1JUQVBJIFJQQ19TVEFUVVMgUlBDX0VOVFJZClJwY0JpbmRpbmdTZXRBdXRoSW5mb0EoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfQ1NUUiBTZXJ2ZXJQcmluY05hbWUsIFVMT05HIEF1dGhuTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIEF1dGhuU3ZjLCBSUENfQVVUSF9JREVOVElUWV9IQU5ETEUgQXV0aElkZW50aXR5LCBVTE9ORyBBdXRoelN2ciApCnsKICAgIFRSQUNFKCIlcCAlcyAldSAldSAlcCAldVxuIiwgQmluZGluZywgZGVidWdzdHJfYSgoY29uc3QgY2hhciopU2VydmVyUHJpbmNOYW1lKSwKICAgICAgICAgIEF1dGhuTGV2ZWwsIEF1dGhuU3ZjLCBBdXRoSWRlbnRpdHksIEF1dGh6U3ZyKTsKICAgIHJldHVybiBScGNCaW5kaW5nU2V0QXV0aEluZm9FeEEoQmluZGluZywgU2VydmVyUHJpbmNOYW1lLCBBdXRobkxldmVsLCBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2ciwgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nU2V0QXV0aEluZm9XIChSUENSVDQuQCkKICovClJQQ1JUQVBJIFJQQ19TVEFUVVMgUlBDX0VOVFJZClJwY0JpbmRpbmdTZXRBdXRoSW5mb1coIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfV1NUUiBTZXJ2ZXJQcmluY05hbWUsIFVMT05HIEF1dGhuTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIEF1dGhuU3ZjLCBSUENfQVVUSF9JREVOVElUWV9IQU5ETEUgQXV0aElkZW50aXR5LCBVTE9ORyBBdXRoelN2ciApCnsKICAgIFRSQUNFKCIlcCAlcyAldSAldSAlcCAldVxuIiwgQmluZGluZywgZGVidWdzdHJfdygoY29uc3QgV0NIQVIqKVNlcnZlclByaW5jTmFtZSksCiAgICAgICAgICBBdXRobkxldmVsLCBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2cik7CiAgICByZXR1cm4gUnBjQmluZGluZ1NldEF1dGhJbmZvRXhXKEJpbmRpbmcsIFNlcnZlclByaW5jTmFtZSwgQXV0aG5MZXZlbCwgQXV0aG5TdmMsIEF1dGhJZGVudGl0eSwgQXV0aHpTdnIsIE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1NldE9wdGlvbiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nU2V0T3B0aW9uKFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nSGFuZGxlLCBVTE9ORyBPcHRpb24sIFVMT05HIE9wdGlvblZhbHVlKQp7CiAgICBGSVhNRSgiKCVwLCAlZCwgJWQpOiBzdHViXG4iLCBCaW5kaW5nSGFuZGxlLCBPcHRpb24sIE9wdGlvblZhbHVlKTsKICAgIHJldHVybiBSUENfU19PSzsKfQo=