LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAzIE1pa2UgSGVhcm4KICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqIENvcHlyaWdodCAyMDA2IENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2ludGVybmwuaCIKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgoKI2luY2x1ZGUgInJwYy5oIgojaW5jbHVkZSAicnBjbmRyLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgInJwY19iaW5kaW5nLmgiCiNpbmNsdWRlICJycGNfbWVzc2FnZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocnBjKTsKCkxQU1RSIFJQQ1JUNF9zdHJuZHVwQShMUENTVFIgc3JjLCBJTlQgc2xlbikKewogIERXT1JEIGxlbjsKICBMUFNUUiBzOwogIGlmICghc3JjKSByZXR1cm4gTlVMTDsKICBpZiAoc2xlbiA9PSAtMSkgc2xlbiA9IHN0cmxlbihzcmMpOwogIGxlbiA9IHNsZW47CiAgcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4rMSk7CiAgbWVtY3B5KHMsIHNyYywgbGVuKTsKICBzW2xlbl0gPSAwOwogIHJldHVybiBzOwp9CgpMUFNUUiBSUENSVDRfc3RyZHVwV3RvQShMUENXU1RSIHNyYykKewogIERXT1JEIGxlbjsKICBMUFNUUiBzOwogIGlmICghc3JjKSByZXR1cm4gTlVMTDsKICBsZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3JjLCAtMSwgTlVMTCwgMCwgTlVMTCwgTlVMTCk7CiAgcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4pOwogIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBzcmMsIC0xLCBzLCBsZW4sIE5VTEwsIE5VTEwpOwogIHJldHVybiBzOwp9CgpMUFdTVFIgUlBDUlQ0X3N0cmR1cEF0b1coTFBDU1RSIHNyYykKewogIERXT1JEIGxlbjsKICBMUFdTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDApOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzcmMsIC0xLCBzLCBsZW4pOwogIHJldHVybiBzOwp9CgpzdGF0aWMgTFBXU1RSIFJQQ1JUNF9zdHJuZHVwQXRvVyhMUENTVFIgc3JjLCBJTlQgc2xlbikKewogIERXT1JEIGxlbjsKICBMUFdTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHNyYywgc2xlbiwgTlVMTCwgMCk7CiAgcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHNyYywgc2xlbiwgcywgbGVuKTsKICByZXR1cm4gczsKfQoKTFBXU1RSIFJQQ1JUNF9zdHJuZHVwVyhMUENXU1RSIHNyYywgSU5UIHNsZW4pCnsKICBEV09SRCBsZW47CiAgTFBXU1RSIHM7CiAgaWYgKCFzcmMpIHJldHVybiBOVUxMOwogIGlmIChzbGVuID09IC0xKSBzbGVuID0gc3RybGVuVyhzcmMpOwogIGxlbiA9IHNsZW47CiAgcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCAobGVuKzEpKnNpemVvZihXQ0hBUikpOwogIG1lbWNweShzLCBzcmMsIGxlbipzaXplb2YoV0NIQVIpKTsKICBzW2xlbl0gPSAwOwogIHJldHVybiBzOwp9Cgp2b2lkIFJQQ1JUNF9zdHJmcmVlKExQU1RSIHNyYykKewogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHNyYyk7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUNF9BbGxvY0JpbmRpbmcoUnBjQmluZGluZyoqIEJpbmRpbmcsIEJPT0wgc2VydmVyKQp7CiAgUnBjQmluZGluZyogTmV3QmluZGluZzsKCiAgTmV3QmluZGluZyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoUnBjQmluZGluZykpOwogIE5ld0JpbmRpbmctPnJlZnMgPSAxOwogIE5ld0JpbmRpbmctPnNlcnZlciA9IHNlcnZlcjsKCiAgKkJpbmRpbmcgPSBOZXdCaW5kaW5nOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVCaW5kaW5nQShScGNCaW5kaW5nKiogQmluZGluZywgQk9PTCBzZXJ2ZXIsIExQQ1NUUiBQcm90c2VxKQp7CiAgUnBjQmluZGluZyogTmV3QmluZGluZzsKCiAgUlBDUlQ0X0FsbG9jQmluZGluZygmTmV3QmluZGluZywgc2VydmVyKTsKICBOZXdCaW5kaW5nLT5Qcm90c2VxID0gUlBDUlQ0X3N0cmR1cEEoUHJvdHNlcSk7CgogIFRSQUNFKCJiaW5kaW5nOiAlcFxuIiwgTmV3QmluZGluZyk7CiAgKkJpbmRpbmcgPSBOZXdCaW5kaW5nOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVCaW5kaW5nVyhScGNCaW5kaW5nKiogQmluZGluZywgQk9PTCBzZXJ2ZXIsIExQQ1dTVFIgUHJvdHNlcSkKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIFJQQ1JUNF9BbGxvY0JpbmRpbmcoJk5ld0JpbmRpbmcsIHNlcnZlcik7CiAgTmV3QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBXdG9BKFByb3RzZXEpOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfQ29tcGxldGVCaW5kaW5nQShScGNCaW5kaW5nKiBCaW5kaW5nLCBMUENTVFIgTmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1NUUiBFbmRwb2ludCwgTFBDU1RSIE5ldHdvcmtPcHRpb25zKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCIoUnBjQmluZGluZyA9PSBeJXAsIE5ldHdvcmtBZGRyID09ICVzLCBFbmRQb2ludCA9PSAlcywgTmV0d29ya09wdGlvbnMgPT0gJXMpXG4iLCBCaW5kaW5nLAogICBkZWJ1Z3N0cl9hKE5ldHdvcmtBZGRyKSwgZGVidWdzdHJfYShFbmRwb2ludCksIGRlYnVnc3RyX2EoTmV0d29ya09wdGlvbnMpKTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+TmV0d29ya0FkZHIpOwogIEJpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoTmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBpZiAoRW5kcG9pbnQpIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIH0gZWxzZSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKCIiKTsKICB9CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQmluZGluZy0+TmV0d29ya09wdGlvbnMpOwogIEJpbmRpbmctPk5ldHdvcmtPcHRpb25zID0gUlBDUlQ0X3N0cmR1cEF0b1coTmV0d29ya09wdGlvbnMpOwogIGlmICghQmluZGluZy0+RW5kcG9pbnQpIEVSUigib3V0IG9mIG1lbW9yeT9cbiIpOwoKICBzdGF0dXMgPSBSUENSVDRfR2V0QXNzb2NpYXRpb24oQmluZGluZy0+UHJvdHNlcSwgQmluZGluZy0+TmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpbmRpbmctPkVuZHBvaW50LCBCaW5kaW5nLT5OZXR3b3JrT3B0aW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJkJpbmRpbmctPkFzc29jKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICByZXR1cm4gc3RhdHVzOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUNF9Db21wbGV0ZUJpbmRpbmdXKFJwY0JpbmRpbmcqIEJpbmRpbmcsIExQQ1dTVFIgTmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgRW5kcG9pbnQsIExQQ1dTVFIgTmV0d29ya09wdGlvbnMpCnsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgVFJBQ0UoIihScGNCaW5kaW5nID09IF4lcCwgTmV0d29ya0FkZHIgPT0gJXMsIEVuZFBvaW50ID09ICVzLCBOZXR3b3JrT3B0aW9ucyA9PSAlcylcbiIsIEJpbmRpbmcsIAogICBkZWJ1Z3N0cl93KE5ldHdvcmtBZGRyKSwgZGVidWdzdHJfdyhFbmRwb2ludCksIGRlYnVnc3RyX3coTmV0d29ya09wdGlvbnMpKTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+TmV0d29ya0FkZHIpOwogIEJpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cFd0b0EoTmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBpZiAoRW5kcG9pbnQpIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cFd0b0EoRW5kcG9pbnQpOwogIH0gZWxzZSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKCIiKTsKICB9CiAgaWYgKCFCaW5kaW5nLT5FbmRwb2ludCkgRVJSKCJvdXQgb2YgbWVtb3J5P1xuIik7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQmluZGluZy0+TmV0d29ya09wdGlvbnMpOwogIEJpbmRpbmctPk5ldHdvcmtPcHRpb25zID0gUlBDUlQ0X3N0cmR1cFcoTmV0d29ya09wdGlvbnMpOwoKICBzdGF0dXMgPSBSUENSVDRfR2V0QXNzb2NpYXRpb24oQmluZGluZy0+UHJvdHNlcSwgQmluZGluZy0+TmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJpbmRpbmctPkVuZHBvaW50LCBCaW5kaW5nLT5OZXR3b3JrT3B0aW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJkJpbmRpbmctPkFzc29jKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgICByZXR1cm4gc3RhdHVzOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X1Jlc29sdmVCaW5kaW5nKFJwY0JpbmRpbmcqIEJpbmRpbmcsIExQQ1NUUiBFbmRwb2ludCkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBUUkFDRSgiKFJwY0JpbmRpbmcgPT0gXiVwLCBFbmRQb2ludCA9PSBcIiVzXCJcbiIsIEJpbmRpbmcsIEVuZHBvaW50KTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwoKICBScGNBc3NvY19SZWxlYXNlKEJpbmRpbmctPkFzc29jKTsKICBCaW5kaW5nLT5Bc3NvYyA9IE5VTEw7CiAgc3RhdHVzID0gUlBDUlQ0X0dldEFzc29jaWF0aW9uKEJpbmRpbmctPlByb3RzZXEsIEJpbmRpbmctPk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCaW5kaW5nLT5FbmRwb2ludCwgQmluZGluZy0+TmV0d29ya09wdGlvbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZCaW5kaW5nLT5Bc3NvYyk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgcmV0dXJuIHN0YXR1czsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KFJwY0JpbmRpbmcqIEJpbmRpbmcsIGNvbnN0IFVVSUQqIE9iamVjdFV1aWQpCnsKICBUUkFDRSgiKCpScGNCaW5kaW5nID09IF4lcCwgVVVJRCA9PSAlcylcbiIsIEJpbmRpbmcsIGRlYnVnc3RyX2d1aWQoT2JqZWN0VXVpZCkpOyAKICBpZiAoT2JqZWN0VXVpZCkgbWVtY3B5KCZCaW5kaW5nLT5PYmplY3RVdWlkLCBPYmplY3RVdWlkLCBzaXplb2YoVVVJRCkpOwogIGVsc2UgVXVpZENyZWF0ZU5pbCgmQmluZGluZy0+T2JqZWN0VXVpZCk7CiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9NYWtlQmluZGluZyhScGNCaW5kaW5nKiogQmluZGluZywgUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CiAgVFJBQ0UoIihScGNCaW5kaW5nID09IF4lcCwgQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBCaW5kaW5nLCBDb25uZWN0aW9uKTsKCiAgUlBDUlQ0X0FsbG9jQmluZGluZygmTmV3QmluZGluZywgQ29ubmVjdGlvbi0+c2VydmVyKTsKICBOZXdCaW5kaW5nLT5Qcm90c2VxID0gUlBDUlQ0X3N0cmR1cEEocnBjcnQ0X2Nvbm5fZ2V0X25hbWUoQ29ubmVjdGlvbikpOwogIE5ld0JpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIpOwogIE5ld0JpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIE5ld0JpbmRpbmctPkZyb21Db25uID0gQ29ubmVjdGlvbjsKCiAgVFJBQ0UoImJpbmRpbmc6ICVwXG4iLCBOZXdCaW5kaW5nKTsKICAqQmluZGluZyA9IE5ld0JpbmRpbmc7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfRXhwb3J0QmluZGluZyhScGNCaW5kaW5nKiogQmluZGluZywgUnBjQmluZGluZyogT2xkQmluZGluZykKewogIEludGVybG9ja2VkSW5jcmVtZW50KCZPbGRCaW5kaW5nLT5yZWZzKTsKICAqQmluZGluZyA9IE9sZEJpbmRpbmc7CiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9EZXN0cm95QmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nKQp7CiAgaWYgKEludGVybG9ja2VkRGVjcmVtZW50KCZCaW5kaW5nLT5yZWZzKSkKICAgIHJldHVybiBSUENfU19PSzsKCiAgVFJBQ0UoImJpbmRpbmc6ICVwXG4iLCBCaW5kaW5nKTsKICBpZiAoQmluZGluZy0+QXNzb2MpIFJwY0Fzc29jX1JlbGVhc2UoQmluZGluZy0+QXNzb2MpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5OZXR3b3JrQWRkcik7CiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+UHJvdHNlcSk7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQmluZGluZy0+TmV0d29ya09wdGlvbnMpOwogIGlmIChCaW5kaW5nLT5BdXRoSW5mbykgUnBjQXV0aEluZm9fUmVsZWFzZShCaW5kaW5nLT5BdXRoSW5mbyk7CiAgaWYgKEJpbmRpbmctPlFPUykgUnBjUXVhbGl0eU9mU2VydmljZV9SZWxlYXNlKEJpbmRpbmctPlFPUyk7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQmluZGluZyk7CiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9PcGVuQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpUcmFuc2ZlclN5bnRheCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpJbnRlcmZhY2VJZCkKewogIFRSQUNFKCIoQmluZGluZyA9PSBeJXApXG4iLCBCaW5kaW5nKTsKCiAgaWYgKCFCaW5kaW5nLT5zZXJ2ZXIpIHsKICAgICByZXR1cm4gUnBjQXNzb2NfR2V0Q2xpZW50Q29ubmVjdGlvbihCaW5kaW5nLT5Bc3NvYywgSW50ZXJmYWNlSWQsCiAgICAgICAgIFRyYW5zZmVyU3ludGF4LCBCaW5kaW5nLT5BdXRoSW5mbywgQmluZGluZy0+UU9TLCBDb25uZWN0aW9uKTsKICB9IGVsc2UgewogICAgLyogd2UgYWxyZWFkeSBoYXZlIGEgY29ubmVjdGlvbiB3aXRoIGFjY2VwdGFibGUgYmluZGluZywgc28gdXNlIGl0ICovCiAgICBpZiAoQmluZGluZy0+RnJvbUNvbm4pIHsKICAgICAgKkNvbm5lY3Rpb24gPSBCaW5kaW5nLT5Gcm9tQ29ubjsKICAgICAgcmV0dXJuIFJQQ19TX09LOwogICAgfSBlbHNlIHsKICAgICAgIEVSUigibm8gY29ubmVjdGlvbiBpbiBiaW5kaW5nXG4iKTsKICAgICAgIHJldHVybiBSUENfU19JTlRFUk5BTF9FUlJPUjsKICAgIH0KICB9Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Nsb3NlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoIihCaW5kaW5nID09IF4lcClcbiIsIEJpbmRpbmcpOwogIGlmICghQ29ubmVjdGlvbikgcmV0dXJuIFJQQ19TX09LOwogIGlmIChCaW5kaW5nLT5zZXJ2ZXIpIHsKICAgIC8qIGRvbid0IGRlc3Ryb3kgYSBjb25uZWN0aW9uIHRoYXQgaXMgY2FjaGVkIGluIHRoZSBiaW5kaW5nICovCiAgICBpZiAoQmluZGluZy0+RnJvbUNvbm4gPT0gQ29ubmVjdGlvbikKICAgICAgcmV0dXJuIFJQQ19TX09LOwogICAgcmV0dXJuIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihDb25uZWN0aW9uKTsKICB9CiAgZWxzZSB7CiAgICBScGNBc3NvY19SZWxlYXNlSWRsZUNvbm5lY3Rpb24oQmluZGluZy0+QXNzb2MsIENvbm5lY3Rpb24pOwogICAgcmV0dXJuIFJQQ19TX09LOwogIH0KfQoKLyogdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHN0cmluZyBjb21wb3NpbmcgYW5kIHBhcnNpbmcgKi8Kc3RhdGljIHVuc2lnbmVkIFJQQ1JUNF9zdHJjb3B5QShMUFNUUiBkYXRhLCBMUENTVFIgc3JjKQp7CiAgdW5zaWduZWQgbGVuID0gc3RybGVuKHNyYyk7CiAgbWVtY3B5KGRhdGEsIHNyYywgbGVuKnNpemVvZihDSEFSKSk7CiAgcmV0dXJuIGxlbjsKfQoKc3RhdGljIHVuc2lnbmVkIFJQQ1JUNF9zdHJjb3B5VyhMUFdTVFIgZGF0YSwgTFBDV1NUUiBzcmMpCnsKICB1bnNpZ25lZCBsZW4gPSBzdHJsZW5XKHNyYyk7CiAgbWVtY3B5KGRhdGEsIHNyYywgbGVuKnNpemVvZihXQ0hBUikpOwogIHJldHVybiBsZW47Cn0KCnN0YXRpYyBMUFNUUiBSUENSVDRfc3RyY29uY2F0QShMUFNUUiBkc3QsIExQQ1NUUiBzcmMpCnsKICBEV09SRCBsZW4gPSBzdHJsZW4oZHN0KSwgc2xlbiA9IHN0cmxlbihzcmMpOwogIExQU1RSIG5kc3QgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QsIChsZW4rc2xlbisyKSpzaXplb2YoQ0hBUikpOwogIGlmICghbmRzdCkKICB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCBzbGVuKzEpOwogIHJldHVybiBuZHN0Owp9CgpzdGF0aWMgTFBXU1RSIFJQQ1JUNF9zdHJjb25jYXRXKExQV1NUUiBkc3QsIExQQ1dTVFIgc3JjKQp7CiAgRFdPUkQgbGVuID0gc3RybGVuVyhkc3QpLCBzbGVuID0gc3RybGVuVyhzcmMpOwogIExQV1NUUiBuZHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0LCAobGVuK3NsZW4rMikqc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKCFuZHN0KSAKICB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCAoc2xlbisxKSpzaXplb2YoV0NIQVIpKTsKICByZXR1cm4gbmRzdDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZUEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBKFJQQ19DU1RSIE9ialV1aWQsIFJQQ19DU1RSIFByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfQ1NUUiBOZXR3b3JrQWRkciwgUlBDX0NTVFIgRW5kcG9pbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfQ1NUUiBPcHRpb25zLCBSUENfQ1NUUiAqU3RyaW5nQmluZGluZyApCnsKICBEV09SRCBsZW4gPSAxOwogIExQU1RSIGRhdGE7CgogIFRSQUNFKCAiKCVzLCVzLCVzLCVzLCVzLCVwKVxuIiwKICAgICAgICBkZWJ1Z3N0cl9hKCAoY2hhciopT2JqVXVpZCApLCBkZWJ1Z3N0cl9hKCAoY2hhciopUHJvdHNlcSApLAogICAgICAgIGRlYnVnc3RyX2EoIChjaGFyKilOZXR3b3JrQWRkciApLCBkZWJ1Z3N0cl9hKCAoY2hhciopRW5kcG9pbnQgKSwKICAgICAgICBkZWJ1Z3N0cl9hKCAoY2hhciopT3B0aW9ucyApLCBTdHJpbmdCaW5kaW5nICk7CgogIGlmIChPYmpVdWlkICYmICpPYmpVdWlkKSBsZW4gKz0gc3RybGVuKChjaGFyKilPYmpVdWlkKSArIDE7CiAgaWYgKFByb3RzZXEgJiYgKlByb3RzZXEpIGxlbiArPSBzdHJsZW4oKGNoYXIqKVByb3RzZXEpICsgMTsKICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKSBsZW4gKz0gc3RybGVuKChjaGFyKilOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50ICYmICpFbmRwb2ludCkgbGVuICs9IHN0cmxlbigoY2hhciopRW5kcG9pbnQpICsgMjsKICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgbGVuICs9IHN0cmxlbigoY2hhciopT3B0aW9ucykgKyAyOwoKICBkYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbik7CiAgKlN0cmluZ0JpbmRpbmcgPSAodW5zaWduZWQgY2hhciopZGF0YTsKCiAgaWYgKE9ialV1aWQgJiYgKk9ialV1aWQpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlBKGRhdGEsIChjaGFyKilPYmpVdWlkKTsKICAgICpkYXRhKysgPSAnQCc7CiAgfQogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCAoY2hhciopUHJvdHNlcSk7CiAgICAqZGF0YSsrID0gJzonOwogIH0KICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKQogICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgKGNoYXIqKU5ldHdvcmtBZGRyKTsKCiAgaWYgKChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIHx8CiAgICAgIChPcHRpb25zICYmICpPcHRpb25zKSkgewogICAgKmRhdGErKyA9ICdbJzsKICAgIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgKGNoYXIqKUVuZHBvaW50KTsKICAgICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpICpkYXRhKysgPSAnLCc7CiAgICB9CiAgICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCAoY2hhciopT3B0aW9ucyk7CiAgICB9CiAgICAqZGF0YSsrID0gJ10nOwogIH0KICAqZGF0YSA9IDA7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZVcoIFJQQ19XU1RSIE9ialV1aWQsIFJQQ19XU1RSIFByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1dTVFIgTmV0d29ya0FkZHIsIFJQQ19XU1RSIEVuZHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19XU1RSIE9wdGlvbnMsIFJQQ19XU1RSKiBTdHJpbmdCaW5kaW5nICkKewogIERXT1JEIGxlbiA9IDE7CiAgUlBDX1dTVFIgZGF0YTsKCiAgVFJBQ0UoIiglcywlcywlcywlcywlcywlcClcbiIsCiAgICAgICBkZWJ1Z3N0cl93KCBPYmpVdWlkICksIGRlYnVnc3RyX3coIFByb3RzZXEgKSwKICAgICAgIGRlYnVnc3RyX3coIE5ldHdvcmtBZGRyICksIGRlYnVnc3RyX3coIEVuZHBvaW50ICksCiAgICAgICBkZWJ1Z3N0cl93KCBPcHRpb25zICksIFN0cmluZ0JpbmRpbmcpOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgbGVuICs9IHN0cmxlblcoT2JqVXVpZCkgKyAxOwogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSBsZW4gKz0gc3RybGVuVyhQcm90c2VxKSArIDE7CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikgbGVuICs9IHN0cmxlblcoTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCAmJiAqRW5kcG9pbnQpIGxlbiArPSBzdHJsZW5XKEVuZHBvaW50KSArIDI7CiAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIGxlbiArPSBzdHJsZW5XKE9wdGlvbnMpICsgMjsKCiAgZGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgKlN0cmluZ0JpbmRpbmcgPSBkYXRhOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgT2JqVXVpZCk7CiAgICAqZGF0YSsrID0gJ0AnOwogIH0KICBpZiAoUHJvdHNlcSAmJiAqUHJvdHNlcSkgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgUHJvdHNlcSk7CiAgICAqZGF0YSsrID0gJzonOwogIH0KICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKSB7CiAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBOZXR3b3JrQWRkcik7CiAgfQogIGlmICgoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB8fAogICAgICAoT3B0aW9ucyAmJiAqT3B0aW9ucykpIHsKICAgICpkYXRhKysgPSAnWyc7CiAgICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSB7CiAgICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIEVuZHBvaW50KTsKICAgICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpICpkYXRhKysgPSAnLCc7CiAgICB9CiAgICBpZiAoT3B0aW9ucyAmJiAqT3B0aW9ucykgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBPcHRpb25zKTsKICAgIH0KICAgICpkYXRhKysgPSAnXSc7CiAgfQogICpkYXRhID0gMDsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1N0cmluZ0JpbmRpbmdQYXJzZUEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ1BhcnNlQSggUlBDX0NTVFIgU3RyaW5nQmluZGluZywgUlBDX0NTVFIgKk9ialV1aWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19DU1RSICpQcm90c2VxLCBSUENfQ1NUUiAqTmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19DU1RSICpFbmRwb2ludCwgUlBDX0NTVFIgKk9wdGlvbnMpCnsKICBDSEFSICpkYXRhLCAqbmV4dDsKICBzdGF0aWMgY29uc3QgY2hhciBlcF9vcHRbXSA9ICJlbmRwb2ludD0iOwoKICBUUkFDRSgiKCVzLCVwLCVwLCVwLCVwLCVwKVxuIiwgZGVidWdzdHJfYSgoY2hhciopU3RyaW5nQmluZGluZyksCiAgICAgICBPYmpVdWlkLCBQcm90c2VxLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnMpOwoKICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSBOVUxMOwogIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9IE5VTEw7CiAgaWYgKE5ldHdvcmtBZGRyKSAqTmV0d29ya0FkZHIgPSBOVUxMOwogIGlmIChFbmRwb2ludCkgKkVuZHBvaW50ID0gTlVMTDsKICBpZiAoT3B0aW9ucykgKk9wdGlvbnMgPSBOVUxMOwoKICBkYXRhID0gKGNoYXIqKSBTdHJpbmdCaW5kaW5nOwoKICBuZXh0ID0gc3RyY2hyKGRhdGEsICdAJyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9ICh1bnNpZ25lZCBjaGFyKilSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHIoZGF0YSwgJzonKTsKICBpZiAobmV4dCkgewogICAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gKHVuc2lnbmVkIGNoYXIqKVJQQ1JUNF9zdHJuZHVwQShkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNocihkYXRhLCAnWycpOwogIGlmIChuZXh0KSB7CiAgICBDSEFSICpjbG9zZSwgKm9wdDsKCiAgICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9ICh1bnNpZ25lZCBjaGFyKilSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICAgIGNsb3NlID0gc3RyY2hyKGRhdGEsICddJyk7CiAgICBpZiAoIWNsb3NlKSBnb3RvIGZhaWw7CgogICAgLyogdG9rZW5pemUgb3B0aW9ucyAqLwogICAgd2hpbGUgKGRhdGEgPCBjbG9zZSkgewogICAgICBuZXh0ID0gc3RyY2hyKGRhdGEsICcsJyk7CiAgICAgIGlmICghbmV4dCB8fCBuZXh0ID4gY2xvc2UpIG5leHQgPSBjbG9zZTsKICAgICAgLyogRklYTUU6IHRoaXMgaXMga2luZCBvZiBpbmVmZmljaWVudCAqLwogICAgICBvcHQgPSBSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgICBkYXRhID0gbmV4dCsxOwoKICAgICAgLyogcGFyc2Ugb3B0aW9uICovCiAgICAgIG5leHQgPSBzdHJjaHIob3B0LCAnPScpOwogICAgICBpZiAoIW5leHQpIHsKICAgICAgICAvKiBub3QgYW4gb3B0aW9uLCBtdXN0IGJlIGFuIGVuZHBvaW50ICovCiAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICpFbmRwb2ludCA9ICh1bnNpZ25lZCBjaGFyKikgb3B0OwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChzdHJuY21wKG9wdCwgZXBfb3B0LCBzdHJsZW4oZXBfb3B0KSkgPT0gMCkgewogICAgICAgICAgLyogZW5kcG9pbnQgb3B0aW9uICovCiAgICAgICAgICBpZiAoKkVuZHBvaW50KSBnb3RvIGZhaWw7CiAgICAgICAgICAqRW5kcG9pbnQgPSAodW5zaWduZWQgY2hhciopIFJQQ1JUNF9zdHJkdXBBKG5leHQrMSk7CiAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvKiBuZXR3b3JrIG9wdGlvbiAqLwogICAgICAgICAgaWYgKCpPcHRpb25zKSB7CiAgICAgICAgICAgIC8qIEZJWE1FOiB0aGlzIGlzIGtpbmQgb2YgaW5lZmZpY2llbnQgKi8KICAgICAgICAgICAgKk9wdGlvbnMgPSAodW5zaWduZWQgY2hhciopIFJQQ1JUNF9zdHJjb25jYXRBKCAoY2hhciopKk9wdGlvbnMsIG9wdCk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgICB9IGVsc2UgCgkgICAgKk9wdGlvbnMgPSAodW5zaWduZWQgY2hhciopIG9wdDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBkYXRhID0gY2xvc2UrMTsKICAgIGlmICgqZGF0YSkgZ290byBmYWlsOwogIH0KICBlbHNlIGlmIChOZXR3b3JrQWRkcikgCiAgICAqTmV0d29ya0FkZHIgPSAodW5zaWduZWQgY2hhciopUlBDUlQ0X3N0cmR1cEEoZGF0YSk7CgogIHJldHVybiBSUENfU19PSzsKCmZhaWw6CiAgaWYgKE9ialV1aWQpIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopT2JqVXVpZCk7CiAgaWYgKFByb3RzZXEpIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopUHJvdHNlcSk7CiAgaWYgKE5ldHdvcmtBZGRyKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKU5ldHdvcmtBZGRyKTsKICBpZiAoRW5kcG9pbnQpIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopRW5kcG9pbnQpOwogIGlmIChPcHRpb25zKSBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKU9wdGlvbnMpOwogIHJldHVybiBSUENfU19JTlZBTElEX1NUUklOR19CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjU3RyaW5nQmluZGluZ1BhcnNlVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTdHJpbmdCaW5kaW5nUGFyc2VXKCBSUENfV1NUUiBTdHJpbmdCaW5kaW5nLCBSUENfV1NUUiAqT2JqVXVpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1dTVFIgKlByb3RzZXEsIFJQQ19XU1RSICpOZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1dTVFIgKkVuZHBvaW50LCBSUENfV1NUUiAqT3B0aW9ucykKewogIFdDSEFSICpkYXRhLCAqbmV4dDsKICBzdGF0aWMgY29uc3QgV0NIQVIgZXBfb3B0W10gPSB7J2UnLCduJywnZCcsJ3AnLCdvJywnaScsJ24nLCd0JywnPScsMH07CgogIFRSQUNFKCIoJXMsJXAsJXAsJXAsJXAsJXApXG4iLCBkZWJ1Z3N0cl93KFN0cmluZ0JpbmRpbmcpLAogICAgICAgT2JqVXVpZCwgUHJvdHNlcSwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zKTsKCiAgaWYgKE9ialV1aWQpICpPYmpVdWlkID0gTlVMTDsKICBpZiAoUHJvdHNlcSkgKlByb3RzZXEgPSBOVUxMOwogIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gTlVMTDsKICBpZiAoRW5kcG9pbnQpICpFbmRwb2ludCA9IE5VTEw7CiAgaWYgKE9wdGlvbnMpICpPcHRpb25zID0gTlVMTDsKCiAgZGF0YSA9IFN0cmluZ0JpbmRpbmc7CgogIG5leHQgPSBzdHJjaHJXKGRhdGEsICdAJyk7CiAgaWYgKG5leHQpIHsKICAgIGlmIChPYmpVdWlkKSAqT2JqVXVpZCA9IFJQQ1JUNF9zdHJuZHVwVyhkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogIH0KCiAgbmV4dCA9IHN0cmNoclcoZGF0YSwgJzonKTsKICBpZiAobmV4dCkgewogICAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gUlBDUlQ0X3N0cm5kdXBXKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgfQoKICBuZXh0ID0gc3RyY2hyVyhkYXRhLCAnWycpOwogIGlmIChuZXh0KSB7CiAgICBXQ0hBUiAqY2xvc2UsICpvcHQ7CgogICAgaWYgKE5ldHdvcmtBZGRyKSAqTmV0d29ya0FkZHIgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICAgIGNsb3NlID0gc3RyY2hyVyhkYXRhLCAnXScpOwogICAgaWYgKCFjbG9zZSkgZ290byBmYWlsOwoKICAgIC8qIHRva2VuaXplIG9wdGlvbnMgKi8KICAgIHdoaWxlIChkYXRhIDwgY2xvc2UpIHsKICAgICAgbmV4dCA9IHN0cmNoclcoZGF0YSwgJywnKTsKICAgICAgaWYgKCFuZXh0IHx8IG5leHQgPiBjbG9zZSkgbmV4dCA9IGNsb3NlOwogICAgICAvKiBGSVhNRTogdGhpcyBpcyBraW5kIG9mIGluZWZmaWNpZW50ICovCiAgICAgIG9wdCA9IFJQQ1JUNF9zdHJuZHVwVyhkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICAgIGRhdGEgPSBuZXh0KzE7CgogICAgICAvKiBwYXJzZSBvcHRpb24gKi8KICAgICAgbmV4dCA9IHN0cmNoclcob3B0LCAnPScpOwogICAgICBpZiAoIW5leHQpIHsKICAgICAgICAvKiBub3QgYW4gb3B0aW9uLCBtdXN0IGJlIGFuIGVuZHBvaW50ICovCiAgICAgICAgaWYgKCpFbmRwb2ludCkgZ290byBmYWlsOwogICAgICAgICpFbmRwb2ludCA9IG9wdDsKICAgICAgfSBlbHNlIHsKICAgICAgICBpZiAoc3RybmNtcFcob3B0LCBlcF9vcHQsIHN0cmxlblcoZXBfb3B0KSkgPT0gMCkgewogICAgICAgICAgLyogZW5kcG9pbnQgb3B0aW9uICovCiAgICAgICAgICBpZiAoKkVuZHBvaW50KSBnb3RvIGZhaWw7CiAgICAgICAgICAqRW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwVyhuZXh0KzEpOwogICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3B0KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgLyogbmV0d29yayBvcHRpb24gKi8KICAgICAgICAgIGlmICgqT3B0aW9ucykgewogICAgICAgICAgICAvKiBGSVhNRTogdGhpcyBpcyBraW5kIG9mIGluZWZmaWNpZW50ICovCiAgICAgICAgICAgICpPcHRpb25zID0gUlBDUlQ0X3N0cmNvbmNhdFcoKk9wdGlvbnMsIG9wdCk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG9wdCk7CiAgICAgICAgICB9IGVsc2UgCgkgICAgKk9wdGlvbnMgPSBvcHQ7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgZGF0YSA9IGNsb3NlKzE7CiAgICBpZiAoKmRhdGEpIGdvdG8gZmFpbDsKICB9IGVsc2UgaWYgKE5ldHdvcmtBZGRyKSAKICAgICpOZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJkdXBXKGRhdGEpOwoKICByZXR1cm4gUlBDX1NfT0s7CgpmYWlsOgogIGlmIChPYmpVdWlkKSBScGNTdHJpbmdGcmVlVyhPYmpVdWlkKTsKICBpZiAoUHJvdHNlcSkgUnBjU3RyaW5nRnJlZVcoUHJvdHNlcSk7CiAgaWYgKE5ldHdvcmtBZGRyKSBScGNTdHJpbmdGcmVlVyhOZXR3b3JrQWRkcik7CiAgaWYgKEVuZHBvaW50KSBScGNTdHJpbmdGcmVlVyhFbmRwb2ludCk7CiAgaWYgKE9wdGlvbnMpIFJwY1N0cmluZ0ZyZWVXKE9wdGlvbnMpOwogIHJldHVybiBSUENfU19JTlZBTElEX1NUUklOR19CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0ZyZWUgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ0ZyZWUoIFJQQ19CSU5ESU5HX0hBTkRMRSogQmluZGluZyApCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICBUUkFDRSgiKCVwKSA9ICVwXG4iLCBCaW5kaW5nLCAqQmluZGluZyk7CiAgc3RhdHVzID0gUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKCpCaW5kaW5nKTsKICBpZiAoc3RhdHVzID09IFJQQ19TX09LKSAqQmluZGluZyA9IDA7CiAgcmV0dXJuIHN0YXR1czsKfQogIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1ZlY3RvckZyZWUgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ1ZlY3RvckZyZWUoIFJQQ19CSU5ESU5HX1ZFQ1RPUioqIEJpbmRpbmdWZWN0b3IgKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgdW5zaWduZWQgbG9uZyBjOwoKICBUUkFDRSgiKCVwKVxuIiwgQmluZGluZ1ZlY3Rvcik7CiAgZm9yIChjPTA7IGM8KCpCaW5kaW5nVmVjdG9yKS0+Q291bnQ7IGMrKykgewogICAgc3RhdHVzID0gUnBjQmluZGluZ0ZyZWUoJigqQmluZGluZ1ZlY3RvciktPkJpbmRpbmdIW2NdKTsKICB9CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKkJpbmRpbmdWZWN0b3IpOwogICpCaW5kaW5nVmVjdG9yID0gTlVMTDsKICByZXR1cm4gUlBDX1NfT0s7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdJbnFPYmplY3QgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ0lucU9iamVjdCggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFVVSUQqIE9iamVjdFV1aWQgKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwoKICBUUkFDRSgiKCVwLCVwKSA9ICVzXG4iLCBCaW5kaW5nLCBPYmplY3RVdWlkLCBkZWJ1Z3N0cl9ndWlkKCZiaW5kLT5PYmplY3RVdWlkKSk7CiAgbWVtY3B5KE9iamVjdFV1aWQsICZiaW5kLT5PYmplY3RVdWlkLCBzaXplb2YoVVVJRCkpOwogIHJldHVybiBSUENfU19PSzsKfQogIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1NldE9iamVjdCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nU2V0T2JqZWN0KCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgVVVJRCogT2JqZWN0VXVpZCApCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKUJpbmRpbmc7CgogIFRSQUNFKCIoJXAsJXMpXG4iLCBCaW5kaW5nLCBkZWJ1Z3N0cl9ndWlkKE9iamVjdFV1aWQpKTsKICBpZiAoYmluZC0+c2VydmVyKSByZXR1cm4gUlBDX1NfV1JPTkdfS0lORF9PRl9CSU5ESU5HOwogIHJldHVybiBSUENSVDRfU2V0QmluZGluZ09iamVjdChCaW5kaW5nLCBPYmplY3RVdWlkKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdGcm9tU3RyaW5nQmluZGluZ0EgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nQSggUlBDX0NTVFIgU3RyaW5nQmluZGluZywgUlBDX0JJTkRJTkdfSEFORExFKiBCaW5kaW5nICkKewogIFJQQ19TVEFUVVMgcmV0OwogIFJwY0JpbmRpbmcqIGJpbmQgPSBOVUxMOwogIFJQQ19DU1RSIE9iamVjdFV1aWQsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgT3B0aW9uczsKICBVVUlEIFV1aWQ7CgogIFRSQUNFKCIoJXMsJXApXG4iLCBkZWJ1Z3N0cl9hKChjaGFyKilTdHJpbmdCaW5kaW5nKSwgQmluZGluZyk7CgogIHJldCA9IFJwY1N0cmluZ0JpbmRpbmdQYXJzZUEoU3RyaW5nQmluZGluZywgJk9iamVjdFV1aWQsICZQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmV0d29ya0FkZHIsICZFbmRwb2ludCwgJk9wdGlvbnMpOwogIGlmIChyZXQgIT0gUlBDX1NfT0spIHJldHVybiByZXQ7CgogIHJldCA9IFV1aWRGcm9tU3RyaW5nQShPYmplY3RVdWlkLCAmVXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ3JlYXRlQmluZGluZ0EoJmJpbmQsIEZBTFNFLCAoY2hhciopUHJvdHNlcSk7CiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KGJpbmQsICZVdWlkKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NvbXBsZXRlQmluZGluZ0EoYmluZCwgKGNoYXIqKU5ldHdvcmtBZGRyLCAoY2hhciopRW5kcG9pbnQsIChjaGFyKilPcHRpb25zKTsKCiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmT3B0aW9ucyk7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmRW5kcG9pbnQpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk5ldHdvcmtBZGRyKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZQcm90c2VxKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZPYmplY3RVdWlkKTsKCiAgaWYgKHJldCA9PSBSUENfU19PSykgCiAgICAqQmluZGluZyA9IChSUENfQklORElOR19IQU5ETEUpYmluZDsKICBlbHNlIAogICAgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKGJpbmQpOwoKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdXKCBSUENfV1NUUiBTdHJpbmdCaW5kaW5nLCBSUENfQklORElOR19IQU5ETEUqIEJpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgUnBjQmluZGluZyogYmluZCA9IE5VTEw7CiAgUlBDX1dTVFIgT2JqZWN0VXVpZCwgUHJvdHNlcSwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zOwogIFVVSUQgVXVpZDsKCiAgVFJBQ0UoIiglcywlcClcbiIsIGRlYnVnc3RyX3coU3RyaW5nQmluZGluZyksIEJpbmRpbmcpOwoKICByZXQgPSBScGNTdHJpbmdCaW5kaW5nUGFyc2VXKFN0cmluZ0JpbmRpbmcsICZPYmplY3RVdWlkLCAmUHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk5ldHdvcmtBZGRyLCAmRW5kcG9pbnQsICZPcHRpb25zKTsKICBpZiAocmV0ICE9IFJQQ19TX09LKSByZXR1cm4gcmV0OwoKICByZXQgPSBVdWlkRnJvbVN0cmluZ1coT2JqZWN0VXVpZCwgJlV1aWQpOwoKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NyZWF0ZUJpbmRpbmdXKCZiaW5kLCBGQUxTRSwgUHJvdHNlcSk7CiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KGJpbmQsICZVdWlkKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NvbXBsZXRlQmluZGluZ1coYmluZCwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zKTsKCiAgUnBjU3RyaW5nRnJlZVcoJk9wdGlvbnMpOwogIFJwY1N0cmluZ0ZyZWVXKCZFbmRwb2ludCk7CiAgUnBjU3RyaW5nRnJlZVcoJk5ldHdvcmtBZGRyKTsKICBScGNTdHJpbmdGcmVlVygmUHJvdHNlcSk7CiAgUnBjU3RyaW5nRnJlZVcoJk9iamVjdFV1aWQpOwoKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgKkJpbmRpbmcgPSAoUlBDX0JJTkRJTkdfSEFORExFKWJpbmQ7CiAgZWxzZQogICAgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKGJpbmQpOwoKICByZXR1cm4gcmV0Owp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nQSggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFJQQ19DU1RSICpTdHJpbmdCaW5kaW5nICkKewogIFJQQ19TVEFUVVMgcmV0OwogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKICBSUENfQ1NUUiBPYmplY3RVdWlkOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgQmluZGluZywgU3RyaW5nQmluZGluZyk7CgogIHJldCA9IFV1aWRUb1N0cmluZ0EoJmJpbmQtPk9iamVjdFV1aWQsICZPYmplY3RVdWlkKTsKICBpZiAocmV0ICE9IFJQQ19TX09LKSByZXR1cm4gcmV0OwoKICByZXQgPSBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZUEoT2JqZWN0VXVpZCwgKHVuc2lnbmVkIGNoYXIqKWJpbmQtPlByb3RzZXEsICh1bnNpZ25lZCBjaGFyKikgYmluZC0+TmV0d29ya0FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBjaGFyKikgYmluZC0+RW5kcG9pbnQsIE5VTEwsIFN0cmluZ0JpbmRpbmcpOwoKICBScGNTdHJpbmdGcmVlQSgmT2JqZWN0VXVpZCk7CgogIHJldHVybiByZXQ7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdXKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX1dTVFIgKlN0cmluZ0JpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgdW5zaWduZWQgY2hhciAqc3RyID0gTlVMTDsKICBUUkFDRSgiKCVwLCVwKVxuIiwgQmluZGluZywgU3RyaW5nQmluZGluZyk7CiAgcmV0ID0gUnBjQmluZGluZ1RvU3RyaW5nQmluZGluZ0EoQmluZGluZywgJnN0cik7CiAgKlN0cmluZ0JpbmRpbmcgPSBSUENSVDRfc3RyZHVwQXRvVygoY2hhciopc3RyKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZzdHIpOwogIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBJX1JwY0JpbmRpbmdTZXRBc3luYyAoUlBDUlQ0LkApCiAqIE5PVEVTCiAqICBFeGlzdHMgaW4gd2luOXggYW5kIHdpbk5ULCBidXQgd2l0aCBkaWZmZXJlbnQgbnVtYmVyIG9mIGFyZ3VtZW50cwogKiAgKDl4IHZlcnNpb24gaGFzIDMgYXJndW1lbnRzLCBOVCBoYXMgMikuCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY0JpbmRpbmdTZXRBc3luYyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFJQQ19CTE9DS0lOR19GTiBCbG9ja2luZ0ZuKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwoKICBUUkFDRSggIiglcCwlcCk6IHN0dWJcbiIsIEJpbmRpbmcsIEJsb2NraW5nRm4gKTsKCiAgYmluZC0+QmxvY2tpbmdGbiA9IEJsb2NraW5nRm47CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdDb3B5IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgUlBDX0VOVFJZIFJwY0JpbmRpbmdDb3B5KAogIFJQQ19CSU5ESU5HX0hBTkRMRSBTb3VyY2VCaW5kaW5nLAogIFJQQ19CSU5ESU5HX0hBTkRMRSogRGVzdGluYXRpb25CaW5kaW5nKQp7CiAgUnBjQmluZGluZyAqRGVzdEJpbmRpbmc7CiAgUnBjQmluZGluZyAqU3JjQmluZGluZyA9IChScGNCaW5kaW5nKilTb3VyY2VCaW5kaW5nOwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBUUkFDRSgiKCVwLCAlcClcbiIsIFNvdXJjZUJpbmRpbmcsIERlc3RpbmF0aW9uQmluZGluZyk7CgogIHN0YXR1cyA9IFJQQ1JUNF9BbGxvY0JpbmRpbmcoJkRlc3RCaW5kaW5nLCBTcmNCaW5kaW5nLT5zZXJ2ZXIpOwogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHJldHVybiBzdGF0dXM7CgogIERlc3RCaW5kaW5nLT5PYmplY3RVdWlkID0gU3JjQmluZGluZy0+T2JqZWN0VXVpZDsKICBEZXN0QmluZGluZy0+QmxvY2tpbmdGbiA9IFNyY0JpbmRpbmctPkJsb2NraW5nRm47CiAgRGVzdEJpbmRpbmctPlByb3RzZXEgPSBSUENSVDRfc3RybmR1cEEoU3JjQmluZGluZy0+UHJvdHNlcSwgLTEpOwogIERlc3RCaW5kaW5nLT5OZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJuZHVwQShTcmNCaW5kaW5nLT5OZXR3b3JrQWRkciwgLTEpOwogIERlc3RCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJuZHVwQShTcmNCaW5kaW5nLT5FbmRwb2ludCwgLTEpOwogIERlc3RCaW5kaW5nLT5OZXR3b3JrT3B0aW9ucyA9IFJQQ1JUNF9zdHJkdXBXKFNyY0JpbmRpbmctPk5ldHdvcmtPcHRpb25zKTsKICBpZiAoU3JjQmluZGluZy0+QXNzb2MpIFNyY0JpbmRpbmctPkFzc29jLT5yZWZzKys7CiAgRGVzdEJpbmRpbmctPkFzc29jID0gU3JjQmluZGluZy0+QXNzb2M7CgogIGlmIChTcmNCaW5kaW5nLT5BdXRoSW5mbykgUnBjQXV0aEluZm9fQWRkUmVmKFNyY0JpbmRpbmctPkF1dGhJbmZvKTsKICBEZXN0QmluZGluZy0+QXV0aEluZm8gPSBTcmNCaW5kaW5nLT5BdXRoSW5mbzsKICBpZiAoU3JjQmluZGluZy0+UU9TKSBScGNRdWFsaXR5T2ZTZXJ2aWNlX0FkZFJlZihTcmNCaW5kaW5nLT5RT1MpOwogIERlc3RCaW5kaW5nLT5RT1MgPSBTcmNCaW5kaW5nLT5RT1M7CgogICpEZXN0aW5hdGlvbkJpbmRpbmcgPSBEZXN0QmluZGluZzsKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNJbXBlcnNvbmF0ZUNsaWVudCAoUlBDUlQ0LkApCiAqCiAqIEltcGVyc29uYXRlcyB0aGUgY2xpZW50IGNvbm5lY3RlZCB2aWEgYSBiaW5kaW5nIGhhbmRsZSBzbyB0aGF0IHNlY3VyaXR5CiAqIGNoZWNrcyBhcmUgZG9uZSBpbiB0aGUgY29udGV4dCBvZiB0aGUgY2xpZW50LgogKgogKiBQQVJBTVMKICogIEJpbmRpbmdIYW5kbGUgW0ldIEhhbmRsZSB0byB0aGUgYmluZGluZyB0byB0aGUgY2xpZW50LgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBSUFNfU19PSy4KICogIEZhaWx1cmU6IFJQQ19TVEFUVVMgdmFsdWUuCiAqCiAqIE5PVEVTCiAqCiAqIElmIEJpbmRpbmdIYW5kbGUgaXMgTlVMTCB0aGVuIHRoZSBmdW5jdGlvbiBpbXBlcnNvbmF0ZXMgdGhlIGNsaWVudAogKiBjb25uZWN0ZWQgdG8gdGhlIGJpbmRpbmcgaGFuZGxlIG9mIHRoZSBjdXJyZW50IHRocmVhZC4KICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0ltcGVyc29uYXRlQ2xpZW50KFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nSGFuZGxlKQp7CiAgICBGSVhNRSgiKCVwKTogc3R1YlxuIiwgQmluZGluZ0hhbmRsZSk7CiAgICBJbXBlcnNvbmF0ZVNlbGYoU2VjdXJpdHlJbXBlcnNvbmF0aW9uKTsKICAgIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1JldmVydFRvU2VsZkV4IChSUENSVDQuQCkKICoKICogU3RvcHMgaW1wZXJzb25hdGluZyB0aGUgY2xpZW50IGNvbm5lY3RlZCB0byB0aGUgYmluZGluZyBoYW5kbGUgc28gdGhhdCBzZWN1cml0eQogKiBjaGVja3MgYXJlIG5vIGxvbmdlciBkb25lIGluIHRoZSBjb250ZXh0IG9mIHRoZSBjbGllbnQuCiAqCiAqIFBBUkFNUwogKiAgQmluZGluZ0hhbmRsZSBbSV0gSGFuZGxlIHRvIHRoZSBiaW5kaW5nIHRvIHRoZSBjbGllbnQuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFJQU19TX09LLgogKiAgRmFpbHVyZTogUlBDX1NUQVRVUyB2YWx1ZS4KICoKICogTk9URVMKICoKICogSWYgQmluZGluZ0hhbmRsZSBpcyBOVUxMIHRoZW4gdGhlIGZ1bmN0aW9uIHN0b3BzIGltcGVyc29uYXRpbmcgdGhlIGNsaWVudAogKiBjb25uZWN0ZWQgdG8gdGhlIGJpbmRpbmcgaGFuZGxlIG9mIHRoZSBjdXJyZW50IHRocmVhZC4KICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1JldmVydFRvU2VsZkV4KFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nSGFuZGxlKQp7CiAgICBGSVhNRSgiKCVwKTogc3R1YlxuIiwgQmluZGluZ0hhbmRsZSk7CiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KCnN0YXRpYyBpbmxpbmUgQk9PTCBoYXNfbnRfYXV0aF9pZGVudGl0eShVTE9ORyBBdXRobkxldmVsKQp7CiAgICBzd2l0Y2ggKEF1dGhuTGV2ZWwpCiAgICB7CiAgICBjYXNlIFJQQ19DX0FVVEhOX0dTU19ORUdPVElBVEU6CiAgICBjYXNlIFJQQ19DX0FVVEhOX1dJTk5UOgogICAgY2FzZSBSUENfQ19BVVRITl9HU1NfS0VSQkVST1M6CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KfQoKc3RhdGljIFJQQ19TVEFUVVMgUnBjQXV0aEluZm9fQ3JlYXRlKFVMT05HIEF1dGhuTGV2ZWwsIFVMT05HIEF1dGhuU3ZjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ3JlZEhhbmRsZSBjcmVkLCBUaW1lU3RhbXAgZXhwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgY2JNYXhUb2tlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19BVVRIX0lERU5USVRZX0hBTkRMRSBpZGVudGl0eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJwY0F1dGhJbmZvICoqcmV0KQp7CiAgICBScGNBdXRoSW5mbyAqQXV0aEluZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpBdXRoSW5mbykpOwogICAgaWYgKCFBdXRoSW5mbykKICAgICAgICByZXR1cm4gRVJST1JfT1VUT0ZNRU1PUlk7CgogICAgQXV0aEluZm8tPnJlZnMgPSAxOwogICAgQXV0aEluZm8tPkF1dGhuTGV2ZWwgPSBBdXRobkxldmVsOwogICAgQXV0aEluZm8tPkF1dGhuU3ZjID0gQXV0aG5TdmM7CiAgICBBdXRoSW5mby0+Y3JlZCA9IGNyZWQ7CiAgICBBdXRoSW5mby0+ZXhwID0gZXhwOwogICAgQXV0aEluZm8tPmNiTWF4VG9rZW4gPSBjYk1heFRva2VuOwogICAgQXV0aEluZm8tPmlkZW50aXR5ID0gaWRlbnRpdHk7CgogICAgLyogZHVwbGljYXRlIHRoZSBTRUNfV0lOTlRfQVVUSF9JREVOVElUWSBzdHJ1Y3R1cmUsIGlmIGFwcGxpY2FibGUsIHRvCiAgICAgKiBlbmFibGUgYmV0dGVyIG1hdGNoaW5nIGluIFJwY0F1dGhJbmZvX0lzRXF1YWwgKi8KICAgIGlmIChpZGVudGl0eSAmJiBoYXNfbnRfYXV0aF9pZGVudGl0eShBdXRoblN2YykpCiAgICB7CiAgICAgICAgY29uc3QgU0VDX1dJTk5UX0FVVEhfSURFTlRJVFlfVyAqbnRfaWRlbnRpdHkgPSBpZGVudGl0eTsKICAgICAgICBBdXRoSW5mby0+bnRfaWRlbnRpdHkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpBdXRoSW5mby0+bnRfaWRlbnRpdHkpKTsKICAgICAgICBpZiAoIUF1dGhJbmZvLT5udF9pZGVudGl0eSkKICAgICAgICB7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvKTsKICAgICAgICAgICAgcmV0dXJuIEVSUk9SX09VVE9GTUVNT1JZOwogICAgICAgIH0KCiAgICAgICAgQXV0aEluZm8tPm50X2lkZW50aXR5LT5GbGFncyA9IFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1VOSUNPREU7CiAgICAgICAgaWYgKG50X2lkZW50aXR5LT5GbGFncyAmIFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1VOSUNPREUpCiAgICAgICAgICAgIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+VXNlciA9IFJQQ1JUNF9zdHJuZHVwVyhudF9pZGVudGl0eS0+VXNlciwgbnRfaWRlbnRpdHktPlVzZXJMZW5ndGgpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgQXV0aEluZm8tPm50X2lkZW50aXR5LT5Vc2VyID0gUlBDUlQ0X3N0cm5kdXBBdG9XKChjb25zdCBjaGFyICopbnRfaWRlbnRpdHktPlVzZXIsIG50X2lkZW50aXR5LT5Vc2VyTGVuZ3RoKTsKICAgICAgICBBdXRoSW5mby0+bnRfaWRlbnRpdHktPlVzZXJMZW5ndGggPSBudF9pZGVudGl0eS0+VXNlckxlbmd0aDsKICAgICAgICBpZiAobnRfaWRlbnRpdHktPkZsYWdzICYgU0VDX1dJTk5UX0FVVEhfSURFTlRJVFlfVU5JQ09ERSkKICAgICAgICAgICAgQXV0aEluZm8tPm50X2lkZW50aXR5LT5Eb21haW4gPSBSUENSVDRfc3RybmR1cFcobnRfaWRlbnRpdHktPkRvbWFpbiwgbnRfaWRlbnRpdHktPkRvbWFpbkxlbmd0aCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBBdXRoSW5mby0+bnRfaWRlbnRpdHktPkRvbWFpbiA9IFJQQ1JUNF9zdHJuZHVwQXRvVygoY29uc3QgY2hhciAqKW50X2lkZW50aXR5LT5Eb21haW4sIG50X2lkZW50aXR5LT5Eb21haW5MZW5ndGgpOwogICAgICAgIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+RG9tYWluTGVuZ3RoID0gbnRfaWRlbnRpdHktPkRvbWFpbkxlbmd0aDsKICAgICAgICBpZiAobnRfaWRlbnRpdHktPkZsYWdzICYgU0VDX1dJTk5UX0FVVEhfSURFTlRJVFlfVU5JQ09ERSkKICAgICAgICAgICAgQXV0aEluZm8tPm50X2lkZW50aXR5LT5QYXNzd29yZCA9IFJQQ1JUNF9zdHJuZHVwVyhudF9pZGVudGl0eS0+UGFzc3dvcmQsIG50X2lkZW50aXR5LT5QYXNzd29yZExlbmd0aCk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBBdXRoSW5mby0+bnRfaWRlbnRpdHktPlBhc3N3b3JkID0gUlBDUlQ0X3N0cm5kdXBBdG9XKChjb25zdCBjaGFyICopbnRfaWRlbnRpdHktPlBhc3N3b3JkLCBudF9pZGVudGl0eS0+UGFzc3dvcmRMZW5ndGgpOwogICAgICAgIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+UGFzc3dvcmRMZW5ndGggPSBudF9pZGVudGl0eS0+UGFzc3dvcmRMZW5ndGg7CgogICAgICAgIGlmICghQXV0aEluZm8tPm50X2lkZW50aXR5LT5Vc2VyIHx8CiAgICAgICAgICAgICFBdXRoSW5mby0+bnRfaWRlbnRpdHktPkRvbWFpbiB8fAogICAgICAgICAgICAhQXV0aEluZm8tPm50X2lkZW50aXR5LT5QYXNzd29yZCkKICAgICAgICB7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+VXNlcik7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvLT5udF9pZGVudGl0eS0+RG9tYWluKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQXV0aEluZm8tPm50X2lkZW50aXR5LT5QYXNzd29yZCk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvLT5udF9pZGVudGl0eSk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEF1dGhJbmZvKTsKICAgICAgICAgICAgcmV0dXJuIEVSUk9SX09VVE9GTUVNT1JZOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgICAgICBBdXRoSW5mby0+bnRfaWRlbnRpdHkgPSBOVUxMOwogICAgKnJldCA9IEF1dGhJbmZvOwogICAgcmV0dXJuIFJQQ19TX09LOwp9CgpVTE9ORyBScGNBdXRoSW5mb19BZGRSZWYoUnBjQXV0aEluZm8gKkF1dGhJbmZvKQp7CiAgICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJkF1dGhJbmZvLT5yZWZzKTsKfQoKVUxPTkcgUnBjQXV0aEluZm9fUmVsZWFzZShScGNBdXRoSW5mbyAqQXV0aEluZm8pCnsKICAgIFVMT05HIHJlZnMgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmQXV0aEluZm8tPnJlZnMpOwoKICAgIGlmICghcmVmcykKICAgIHsKICAgICAgICBGcmVlQ3JlZGVudGlhbHNIYW5kbGUoJkF1dGhJbmZvLT5jcmVkKTsKICAgICAgICBpZiAoQXV0aEluZm8tPm50X2lkZW50aXR5KQogICAgICAgIHsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQXV0aEluZm8tPm50X2lkZW50aXR5LT5Vc2VyKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQXV0aEluZm8tPm50X2lkZW50aXR5LT5Eb21haW4pOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBBdXRoSW5mby0+bnRfaWRlbnRpdHktPlBhc3N3b3JkKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQXV0aEluZm8tPm50X2lkZW50aXR5KTsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQXV0aEluZm8pOwogICAgfQoKICAgIHJldHVybiByZWZzOwp9CgpCT09MIFJwY0F1dGhJbmZvX0lzRXF1YWwoY29uc3QgUnBjQXV0aEluZm8gKkF1dGhJbmZvMSwgY29uc3QgUnBjQXV0aEluZm8gKkF1dGhJbmZvMikKewogICAgaWYgKEF1dGhJbmZvMSA9PSBBdXRoSW5mbzIpCiAgICAgICAgcmV0dXJuIFRSVUU7CgogICAgaWYgKCFBdXRoSW5mbzEgfHwgIUF1dGhJbmZvMikKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKChBdXRoSW5mbzEtPkF1dGhuTGV2ZWwgIT0gQXV0aEluZm8yLT5BdXRobkxldmVsKSB8fAogICAgICAgIChBdXRoSW5mbzEtPkF1dGhuU3ZjICE9IEF1dGhJbmZvMi0+QXV0aG5TdmMpKQogICAgICAgIHJldHVybiBGQUxTRTsKCiAgICBpZiAoQXV0aEluZm8xLT5pZGVudGl0eSA9PSBBdXRoSW5mbzItPmlkZW50aXR5KQogICAgICAgIHJldHVybiBUUlVFOwoKICAgIGlmICghQXV0aEluZm8xLT5pZGVudGl0eSB8fCAhQXV0aEluZm8yLT5pZGVudGl0eSkKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgaWYgKGhhc19udF9hdXRoX2lkZW50aXR5KEF1dGhJbmZvMS0+QXV0aG5TdmMpKQogICAgewogICAgICAgIGNvbnN0IFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1cgKmlkZW50aXR5MSA9IEF1dGhJbmZvMS0+bnRfaWRlbnRpdHk7CiAgICAgICAgY29uc3QgU0VDX1dJTk5UX0FVVEhfSURFTlRJVFlfVyAqaWRlbnRpdHkyID0gQXV0aEluZm8yLT5udF9pZGVudGl0eTsKICAgICAgICAvKiBjb21wYXJlIHVzZXIgbmFtZXMgKi8KICAgICAgICBpZiAoaWRlbnRpdHkxLT5Vc2VyTGVuZ3RoICE9IGlkZW50aXR5Mi0+VXNlckxlbmd0aCB8fAogICAgICAgICAgICBtZW1jbXAoaWRlbnRpdHkxLT5Vc2VyLCBpZGVudGl0eTItPlVzZXIsIGlkZW50aXR5MS0+VXNlckxlbmd0aCkpCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAvKiBjb21wYXJlIGRvbWFpbiBuYW1lcyAqLwogICAgICAgIGlmIChpZGVudGl0eTEtPkRvbWFpbkxlbmd0aCAhPSBpZGVudGl0eTItPkRvbWFpbkxlbmd0aCB8fAogICAgICAgICAgICBtZW1jbXAoaWRlbnRpdHkxLT5Eb21haW4sIGlkZW50aXR5Mi0+RG9tYWluLCBpZGVudGl0eTEtPkRvbWFpbkxlbmd0aCkpCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKICAgICAgICAvKiBjb21wYXJlIHBhc3N3b3JkcyAqLwogICAgICAgIGlmIChpZGVudGl0eTEtPlBhc3N3b3JkTGVuZ3RoICE9IGlkZW50aXR5Mi0+UGFzc3dvcmRMZW5ndGggfHwKICAgICAgICAgICAgbWVtY21wKGlkZW50aXR5MS0+UGFzc3dvcmQsIGlkZW50aXR5Mi0+UGFzc3dvcmQsIGlkZW50aXR5MS0+UGFzc3dvcmRMZW5ndGgpKQogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIHJldHVybiBUUlVFOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBScGNRdWFsaXR5T2ZTZXJ2aWNlX0NyZWF0ZShjb25zdCBSUENfU0VDVVJJVFlfUU9TICpxb3Nfc3JjLCBCT09MIHVuaWNvZGUsIFJwY1F1YWxpdHlPZlNlcnZpY2UgKipxb3NfZHN0KQp7CiAgICBScGNRdWFsaXR5T2ZTZXJ2aWNlICpxb3MgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpxb3MpKTsKCiAgICBpZiAoIXFvcykKICAgICAgICByZXR1cm4gUlBDX1NfT1VUX09GX1JFU09VUkNFUzsKCiAgICBxb3MtPnJlZnMgPSAxOwogICAgcW9zLT5xb3MgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpxb3MtPnFvcykpOwogICAgaWYgKCFxb3MtPnFvcykgZ290byBlcnJvcjsKICAgIHFvcy0+cW9zLT5WZXJzaW9uID0gcW9zX3NyYy0+VmVyc2lvbjsKICAgIHFvcy0+cW9zLT5DYXBhYmlsaXRpZXMgPSBxb3Nfc3JjLT5DYXBhYmlsaXRpZXM7CiAgICBxb3MtPnFvcy0+SWRlbnRpdHlUcmFja2luZyA9IHFvc19zcmMtPklkZW50aXR5VHJhY2tpbmc7CiAgICBxb3MtPnFvcy0+SW1wZXJzb25hdGlvblR5cGUgPSBxb3Nfc3JjLT5JbXBlcnNvbmF0aW9uVHlwZTsKICAgIHFvcy0+cW9zLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSA9IDA7CgogICAgaWYgKHFvc19zcmMtPlZlcnNpb24gPj0gMikKICAgIHsKICAgICAgICBjb25zdCBSUENfU0VDVVJJVFlfUU9TX1YyX1cgKnFvc19zcmMyID0gKGNvbnN0IFJQQ19TRUNVUklUWV9RT1NfVjJfVyAqKXFvc19zcmM7CiAgICAgICAgcW9zLT5xb3MtPkFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlID0gcW9zX3NyYzItPkFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlOwogICAgICAgIGlmIChxb3Nfc3JjMi0+QWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGUgPT0gUlBDX0NfQVVUSE5fSU5GT19UWVBFX0hUVFApCiAgICAgICAgewogICAgICAgICAgICBjb25zdCBSUENfSFRUUF9UUkFOU1BPUlRfQ1JFREVOVElBTFNfVyAqaHR0cF9jcmVkZW50aWFsc19zcmMgPSBxb3Nfc3JjMi0+dS5IdHRwQ3JlZGVudGlhbHM7CiAgICAgICAgICAgIFJQQ19IVFRQX1RSQU5TUE9SVF9DUkVERU5USUFMU19XICpodHRwX2NyZWRlbnRpYWxzX2RzdDsKCiAgICAgICAgICAgIGh0dHBfY3JlZGVudGlhbHNfZHN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqaHR0cF9jcmVkZW50aWFsc19kc3QpKTsKICAgICAgICAgICAgcW9zLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzID0gaHR0cF9jcmVkZW50aWFsc19kc3Q7CiAgICAgICAgICAgIGlmICghaHR0cF9jcmVkZW50aWFsc19kc3QpIGdvdG8gZXJyb3I7CiAgICAgICAgICAgIGh0dHBfY3JlZGVudGlhbHNfZHN0LT5UcmFuc3BvcnRDcmVkZW50aWFscyA9IE5VTEw7CiAgICAgICAgICAgIGh0dHBfY3JlZGVudGlhbHNfZHN0LT5GbGFncyA9IGh0dHBfY3JlZGVudGlhbHNfc3JjLT5GbGFnczsKICAgICAgICAgICAgaHR0cF9jcmVkZW50aWFsc19kc3QtPkF1dGhlbnRpY2F0aW9uVGFyZ2V0ID0gaHR0cF9jcmVkZW50aWFsc19zcmMtPkF1dGhlbnRpY2F0aW9uVGFyZ2V0OwogICAgICAgICAgICBodHRwX2NyZWRlbnRpYWxzX2RzdC0+TnVtYmVyT2ZBdXRoblNjaGVtZXMgPSBodHRwX2NyZWRlbnRpYWxzX3NyYy0+TnVtYmVyT2ZBdXRoblNjaGVtZXM7CiAgICAgICAgICAgIGh0dHBfY3JlZGVudGlhbHNfZHN0LT5BdXRoblNjaGVtZXMgPSBOVUxMOwogICAgICAgICAgICBodHRwX2NyZWRlbnRpYWxzX2RzdC0+U2VydmVyQ2VydGlmaWNhdGVTdWJqZWN0ID0gTlVMTDsKICAgICAgICAgICAgaWYgKGh0dHBfY3JlZGVudGlhbHNfc3JjLT5UcmFuc3BvcnRDcmVkZW50aWFscykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU0VDX1dJTk5UX0FVVEhfSURFTlRJVFlfVyAqY3JlZF9kc3Q7CiAgICAgICAgICAgICAgICBjcmVkX2RzdCA9IGh0dHBfY3JlZGVudGlhbHNfZHN0LT5UcmFuc3BvcnRDcmVkZW50aWFscyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKmNyZWRfZHN0KSk7CiAgICAgICAgICAgICAgICBpZiAoIWNyZWRfZHN0KSBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgY3JlZF9kc3QtPkZsYWdzID0gU0VDX1dJTk5UX0FVVEhfSURFTlRJVFlfVU5JQ09ERTsKICAgICAgICAgICAgICAgIGlmICh1bmljb2RlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNvbnN0IFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX1cgKmNyZWRfc3JjID0gaHR0cF9jcmVkZW50aWFsc19zcmMtPlRyYW5zcG9ydENyZWRlbnRpYWxzOwogICAgICAgICAgICAgICAgICAgIGNyZWRfZHN0LT5Vc2VyTGVuZ3RoID0gY3JlZF9zcmMtPlVzZXJMZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgY3JlZF9kc3QtPlBhc3N3b3JkTGVuZ3RoID0gY3JlZF9zcmMtPlBhc3N3b3JkTGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGNyZWRfZHN0LT5Eb21haW5MZW5ndGggPSBjcmVkX3NyYy0+RG9tYWluTGVuZ3RoOwogICAgICAgICAgICAgICAgICAgIGNyZWRfZHN0LT5Vc2VyID0gUlBDUlQ0X3N0cm5kdXBXKGNyZWRfc3JjLT5Vc2VyLCBjcmVkX3NyYy0+VXNlckxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgY3JlZF9kc3QtPlBhc3N3b3JkID0gUlBDUlQ0X3N0cm5kdXBXKGNyZWRfc3JjLT5QYXNzd29yZCwgY3JlZF9zcmMtPlBhc3N3b3JkTGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICBjcmVkX2RzdC0+RG9tYWluID0gUlBDUlQ0X3N0cm5kdXBXKGNyZWRfc3JjLT5Eb21haW4sIGNyZWRfc3JjLT5Eb21haW5MZW5ndGgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNvbnN0IFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX0EgKmNyZWRfc3JjID0gKGNvbnN0IFNFQ19XSU5OVF9BVVRIX0lERU5USVRZX0EgKilodHRwX2NyZWRlbnRpYWxzX3NyYy0+VHJhbnNwb3J0Q3JlZGVudGlhbHM7CiAgICAgICAgICAgICAgICAgICAgY3JlZF9kc3QtPlVzZXJMZW5ndGggPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgKGNoYXIgKiljcmVkX3NyYy0+VXNlciwgY3JlZF9zcmMtPlVzZXJMZW5ndGgsIE5VTEwsIDApOwogICAgICAgICAgICAgICAgICAgIGNyZWRfZHN0LT5Eb21haW5MZW5ndGggPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgKGNoYXIgKiljcmVkX3NyYy0+RG9tYWluLCBjcmVkX3NyYy0+RG9tYWluTGVuZ3RoLCBOVUxMLCAwKTsKICAgICAgICAgICAgICAgICAgICBjcmVkX2RzdC0+UGFzc3dvcmRMZW5ndGggPSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgKGNoYXIgKiljcmVkX3NyYy0+UGFzc3dvcmQsIGNyZWRfc3JjLT5QYXNzd29yZExlbmd0aCwgTlVMTCwgMCk7CiAgICAgICAgICAgICAgICAgICAgY3JlZF9kc3QtPlVzZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY3JlZF9kc3QtPlVzZXJMZW5ndGggKiBzaXplb2YoV0NIQVIpKTsKICAgICAgICAgICAgICAgICAgICBjcmVkX2RzdC0+UGFzc3dvcmQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY3JlZF9kc3QtPlBhc3N3b3JkTGVuZ3RoICogc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgICAgICAgICAgICAgY3JlZF9kc3QtPkRvbWFpbiA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjcmVkX2RzdC0+RG9tYWluTGVuZ3RoICogc2l6ZW9mKFdDSEFSKSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFjcmVkX2RzdCB8fCAhY3JlZF9kc3QtPlBhc3N3b3JkIHx8ICFjcmVkX2RzdC0+RG9tYWluKSBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCAoY2hhciAqKWNyZWRfc3JjLT5Vc2VyLCBjcmVkX3NyYy0+VXNlckxlbmd0aCwgY3JlZF9kc3QtPlVzZXIsIGNyZWRfZHN0LT5Vc2VyTGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgKGNoYXIgKiljcmVkX3NyYy0+RG9tYWluLCBjcmVkX3NyYy0+RG9tYWluTGVuZ3RoLCBjcmVkX2RzdC0+RG9tYWluLCBjcmVkX2RzdC0+RG9tYWluTGVuZ3RoKTsKICAgICAgICAgICAgICAgICAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgKGNoYXIgKiljcmVkX3NyYy0+UGFzc3dvcmQsIGNyZWRfc3JjLT5QYXNzd29yZExlbmd0aCwgY3JlZF9kc3QtPlBhc3N3b3JkLCBjcmVkX2RzdC0+UGFzc3dvcmRMZW5ndGgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChodHRwX2NyZWRlbnRpYWxzX3NyYy0+TnVtYmVyT2ZBdXRoblNjaGVtZXMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGh0dHBfY3JlZGVudGlhbHNfZHN0LT5BdXRoblNjaGVtZXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaHR0cF9jcmVkZW50aWFsc19zcmMtPk51bWJlck9mQXV0aG5TY2hlbWVzICogc2l6ZW9mKCpodHRwX2NyZWRlbnRpYWxzX2RzdC0+QXV0aG5TY2hlbWVzKSk7CiAgICAgICAgICAgICAgICBpZiAoIWh0dHBfY3JlZGVudGlhbHNfZHN0LT5BdXRoblNjaGVtZXMpIGdvdG8gZXJyb3I7CiAgICAgICAgICAgICAgICBtZW1jcHkoaHR0cF9jcmVkZW50aWFsc19kc3QtPkF1dGhuU2NoZW1lcywgaHR0cF9jcmVkZW50aWFsc19zcmMtPkF1dGhuU2NoZW1lcywgaHR0cF9jcmVkZW50aWFsc19zcmMtPk51bWJlck9mQXV0aG5TY2hlbWVzICogc2l6ZW9mKCpodHRwX2NyZWRlbnRpYWxzX2RzdC0+QXV0aG5TY2hlbWVzKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGh0dHBfY3JlZGVudGlhbHNfc3JjLT5TZXJ2ZXJDZXJ0aWZpY2F0ZVN1YmplY3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh1bmljb2RlKQogICAgICAgICAgICAgICAgICAgIGh0dHBfY3JlZGVudGlhbHNfZHN0LT5TZXJ2ZXJDZXJ0aWZpY2F0ZVN1YmplY3QgPQogICAgICAgICAgICAgICAgICAgICAgICBSUENSVDRfc3RybmR1cFcoaHR0cF9jcmVkZW50aWFsc19zcmMtPlNlcnZlckNlcnRpZmljYXRlU3ViamVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlblcoaHR0cF9jcmVkZW50aWFsc19zcmMtPlNlcnZlckNlcnRpZmljYXRlU3ViamVjdCkpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGh0dHBfY3JlZGVudGlhbHNfZHN0LT5TZXJ2ZXJDZXJ0aWZpY2F0ZVN1YmplY3QgPQogICAgICAgICAgICAgICAgICAgICAgICBSUENSVDRfc3RyZHVwQXRvVygoY2hhciAqKWh0dHBfY3JlZGVudGlhbHNfc3JjLT5TZXJ2ZXJDZXJ0aWZpY2F0ZVN1YmplY3QpOwogICAgICAgICAgICAgICAgaWYgKCFodHRwX2NyZWRlbnRpYWxzX2RzdC0+U2VydmVyQ2VydGlmaWNhdGVTdWJqZWN0KSBnb3RvIGVycm9yOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgKnFvc19kc3QgPSBxb3M7CiAgICByZXR1cm4gUlBDX1NfT0s7CgplcnJvcjoKICAgIGlmIChxb3MtPnFvcykKICAgIHsKICAgICAgICBpZiAocW9zLT5xb3MtPkFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlID09IFJQQ19DX0FVVEhOX0lORk9fVFlQRV9IVFRQICYmCiAgICAgICAgICAgIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscykKICAgICAgICB7CiAgICAgICAgICAgIGlmIChxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPlRyYW5zcG9ydENyZWRlbnRpYWxzKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPlRyYW5zcG9ydENyZWRlbnRpYWxzLT5Vc2VyKTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscy0+VHJhbnNwb3J0Q3JlZGVudGlhbHMtPkRvbWFpbik7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPlRyYW5zcG9ydENyZWRlbnRpYWxzLT5QYXNzd29yZCk7CiAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPlRyYW5zcG9ydENyZWRlbnRpYWxzKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMtPkF1dGhuU2NoZW1lcyk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscy0+U2VydmVyQ2VydGlmaWNhdGVTdWJqZWN0KTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzKTsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zLT5xb3MpOwogICAgfQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zKTsKICAgIHJldHVybiBSUENfU19PVVRfT0ZfUkVTT1VSQ0VTOwp9CgpVTE9ORyBScGNRdWFsaXR5T2ZTZXJ2aWNlX0FkZFJlZihScGNRdWFsaXR5T2ZTZXJ2aWNlICpxb3MpCnsKICAgIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmcW9zLT5yZWZzKTsKfQoKVUxPTkcgUnBjUXVhbGl0eU9mU2VydmljZV9SZWxlYXNlKFJwY1F1YWxpdHlPZlNlcnZpY2UgKnFvcykKewogICAgVUxPTkcgcmVmcyA9IEludGVybG9ja2VkRGVjcmVtZW50KCZxb3MtPnJlZnMpOwoKICAgIGlmICghcmVmcykKICAgIHsKICAgICAgICBpZiAocW9zLT5xb3MtPkFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlID09IFJQQ19DX0FVVEhOX0lORk9fVFlQRV9IVFRQKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscy0+VHJhbnNwb3J0Q3JlZGVudGlhbHMpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscy0+VHJhbnNwb3J0Q3JlZGVudGlhbHMtPlVzZXIpOwogICAgICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzLT5UcmFuc3BvcnRDcmVkZW50aWFscy0+RG9tYWluKTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscy0+VHJhbnNwb3J0Q3JlZGVudGlhbHMtPlBhc3N3b3JkKTsKICAgICAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscy0+VHJhbnNwb3J0Q3JlZGVudGlhbHMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHFvcy0+cW9zLT51Lkh0dHBDcmVkZW50aWFscy0+QXV0aG5TY2hlbWVzKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zLT5xb3MtPnUuSHR0cENyZWRlbnRpYWxzLT5TZXJ2ZXJDZXJ0aWZpY2F0ZVN1YmplY3QpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHMpOwogICAgICAgIH0KICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBxb3MtPnFvcyk7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcW9zKTsKICAgIH0KICAgIHJldHVybiByZWZzOwp9CgpCT09MIFJwY1F1YWxpdHlPZlNlcnZpY2VfSXNFcXVhbChjb25zdCBScGNRdWFsaXR5T2ZTZXJ2aWNlICpxb3MxLCBjb25zdCBScGNRdWFsaXR5T2ZTZXJ2aWNlICpxb3MyKQp7CiAgICBpZiAocW9zMSA9PSBxb3MyKQogICAgICAgIHJldHVybiBUUlVFOwoKICAgIGlmICghcW9zMSB8fCAhcW9zMikKICAgICAgICByZXR1cm4gRkFMU0U7CgogICAgVFJBQ0UoInFvczEgPSB7ICVsZCAlbGQgJWxkICVsZCB9LCBxb3MyID0geyAlbGQgJWxkICVsZCAlbGQgfVxuIiwKICAgICAgICBxb3MxLT5xb3MtPkNhcGFiaWxpdGllcywgcW9zMS0+cW9zLT5JZGVudGl0eVRyYWNraW5nLAogICAgICAgIHFvczEtPnFvcy0+SW1wZXJzb25hdGlvblR5cGUsIHFvczEtPnFvcy0+QWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGUsCiAgICAgICAgcW9zMi0+cW9zLT5DYXBhYmlsaXRpZXMsIHFvczItPnFvcy0+SWRlbnRpdHlUcmFja2luZywKICAgICAgICBxb3MyLT5xb3MtPkltcGVyc29uYXRpb25UeXBlLCBxb3MyLT5xb3MtPkFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlKTsKCiAgICBpZiAoKHFvczEtPnFvcy0+Q2FwYWJpbGl0aWVzICE9IHFvczItPnFvcy0+Q2FwYWJpbGl0aWVzKSB8fAogICAgICAgIChxb3MxLT5xb3MtPklkZW50aXR5VHJhY2tpbmcgIT0gcW9zMi0+cW9zLT5JZGVudGl0eVRyYWNraW5nKSB8fAogICAgICAgIChxb3MxLT5xb3MtPkltcGVyc29uYXRpb25UeXBlICE9IHFvczItPnFvcy0+SW1wZXJzb25hdGlvblR5cGUpIHx8CiAgICAgICAgKHFvczEtPnFvcy0+QWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGUgIT0gcW9zMi0+cW9zLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSkpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmIChxb3MxLT5xb3MtPkFkZGl0aW9uYWxTZWN1cml0eUluZm9UeXBlID09IFJQQ19DX0FVVEhOX0lORk9fVFlQRV9IVFRQKQogICAgewogICAgICAgIGNvbnN0IFJQQ19IVFRQX1RSQU5TUE9SVF9DUkVERU5USUFMU19XICpodHRwX2NyZWRlbnRpYWxzMSA9IHFvczEtPnFvcy0+dS5IdHRwQ3JlZGVudGlhbHM7CiAgICAgICAgY29uc3QgUlBDX0hUVFBfVFJBTlNQT1JUX0NSRURFTlRJQUxTX1cgKmh0dHBfY3JlZGVudGlhbHMyID0gcW9zMi0+cW9zLT51Lkh0dHBDcmVkZW50aWFsczsKCiAgICAgICAgaWYgKGh0dHBfY3JlZGVudGlhbHMxLT5GbGFncyAhPSBodHRwX2NyZWRlbnRpYWxzMi0+RmxhZ3MpCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICAgICAgaWYgKGh0dHBfY3JlZGVudGlhbHMxLT5BdXRoZW50aWNhdGlvblRhcmdldCAhPSBodHRwX2NyZWRlbnRpYWxzMi0+QXV0aGVudGljYXRpb25UYXJnZXQpCiAgICAgICAgICAgIHJldHVybiBGQUxTRTsKCiAgICAgICAgLyogYXV0aGVudGljYXRpb24gc2NoZW1lcyBhbmQgc2VydmVyIGNlcnRpZmljYXRlIHN1YmplY3Qgbm90IGN1cnJlbnRseSB1c2VkICovCgogICAgICAgIGlmIChodHRwX2NyZWRlbnRpYWxzMS0+VHJhbnNwb3J0Q3JlZGVudGlhbHMgIT0gaHR0cF9jcmVkZW50aWFsczItPlRyYW5zcG9ydENyZWRlbnRpYWxzKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgU0VDX1dJTk5UX0FVVEhfSURFTlRJVFlfVyAqaWRlbnRpdHkxID0gaHR0cF9jcmVkZW50aWFsczEtPlRyYW5zcG9ydENyZWRlbnRpYWxzOwogICAgICAgICAgICBjb25zdCBTRUNfV0lOTlRfQVVUSF9JREVOVElUWV9XICppZGVudGl0eTIgPSBodHRwX2NyZWRlbnRpYWxzMi0+VHJhbnNwb3J0Q3JlZGVudGlhbHM7CgogICAgICAgICAgICBpZiAoIWlkZW50aXR5MSB8fCAhaWRlbnRpdHkyKQogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgICAgICAgICAgLyogY29tcGFyZSB1c2VyIG5hbWVzICovCiAgICAgICAgICAgIGlmIChpZGVudGl0eTEtPlVzZXJMZW5ndGggIT0gaWRlbnRpdHkyLT5Vc2VyTGVuZ3RoIHx8CiAgICAgICAgICAgICAgICBtZW1jbXAoaWRlbnRpdHkxLT5Vc2VyLCBpZGVudGl0eTItPlVzZXIsIGlkZW50aXR5MS0+VXNlckxlbmd0aCkpCiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgICAgIC8qIGNvbXBhcmUgZG9tYWluIG5hbWVzICovCiAgICAgICAgICAgIGlmIChpZGVudGl0eTEtPkRvbWFpbkxlbmd0aCAhPSBpZGVudGl0eTItPkRvbWFpbkxlbmd0aCB8fAogICAgICAgICAgICAgICAgbWVtY21wKGlkZW50aXR5MS0+RG9tYWluLCBpZGVudGl0eTItPkRvbWFpbiwgaWRlbnRpdHkxLT5Eb21haW5MZW5ndGgpKQogICAgICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgICAgICAvKiBjb21wYXJlIHBhc3N3b3JkcyAqLwogICAgICAgICAgICBpZiAoaWRlbnRpdHkxLT5QYXNzd29yZExlbmd0aCAhPSBpZGVudGl0eTItPlBhc3N3b3JkTGVuZ3RoIHx8CiAgICAgICAgICAgICAgICBtZW1jbXAoaWRlbnRpdHkxLT5QYXNzd29yZCwgaWRlbnRpdHkyLT5QYXNzd29yZCwgaWRlbnRpdHkxLT5QYXNzd29yZExlbmd0aCkpCiAgICAgICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjUmV2ZXJ0VG9TZWxmIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1JldmVydFRvU2VsZih2b2lkKQp7CiAgICBGSVhNRSgic3R1YlxuIik7CiAgICBSZXZlcnRUb1NlbGYoKTsKICAgIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY01nbXRTZXRDb21UaW1lb3V0IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY01nbXRTZXRDb21UaW1lb3V0KFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nSGFuZGxlLCB1bnNpZ25lZCBpbnQgVGltZW91dCkKewogICAgRklYTUUoIiglcCwgJWQpOiBzdHViXG4iLCBCaW5kaW5nSGFuZGxlLCBUaW1lb3V0KTsKICAgIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdJbnFBdXRoSW5mb0V4QSAoUlBDUlQ0LkApCiAqLwpSUENSVEFQSSBSUENfU1RBVFVTIFJQQ19FTlRSWQpScGNCaW5kaW5nSW5xQXV0aEluZm9FeEEoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfQ1NUUiAqU2VydmVyUHJpbmNOYW1lLCBVTE9ORyAqQXV0aG5MZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyAqQXV0aG5TdmMsIFJQQ19BVVRIX0lERU5USVRZX0hBTkRMRSAqQXV0aElkZW50aXR5LCBVTE9ORyAqQXV0aHpTdmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgUnBjUW9zVmVyc2lvbiwgUlBDX1NFQ1VSSVRZX1FPUyAqU2VjdXJpdHlRT1MgKQp7CiAgICBGSVhNRSgiJXAgJXAgJXAgJXAgJXAgJXAgJXUgJXBcbiIsIEJpbmRpbmcsIFNlcnZlclByaW5jTmFtZSwgQXV0aG5MZXZlbCwKICAgICAgICAgIEF1dGhuU3ZjLCBBdXRoSWRlbnRpdHksIEF1dGh6U3ZjLCBScGNRb3NWZXJzaW9uLCBTZWN1cml0eVFPUyk7CiAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0lucUF1dGhJbmZvRXhXIChSUENSVDQuQCkKICovClJQQ1JUQVBJIFJQQ19TVEFUVVMgUlBDX0VOVFJZClJwY0JpbmRpbmdJbnFBdXRoSW5mb0V4VyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFJQQ19XU1RSICpTZXJ2ZXJQcmluY05hbWUsIFVMT05HICpBdXRobkxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HICpBdXRoblN2YywgUlBDX0FVVEhfSURFTlRJVFlfSEFORExFICpBdXRoSWRlbnRpdHksIFVMT05HICpBdXRoelN2YywKICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyBScGNRb3NWZXJzaW9uLCBSUENfU0VDVVJJVFlfUU9TICpTZWN1cml0eVFPUyApCnsKICAgIEZJWE1FKCIlcCAlcCAlcCAlcCAlcCAlcCAldSAlcFxuIiwgQmluZGluZywgU2VydmVyUHJpbmNOYW1lLCBBdXRobkxldmVsLAogICAgICAgICAgQXV0aG5TdmMsIEF1dGhJZGVudGl0eSwgQXV0aHpTdmMsIFJwY1Fvc1ZlcnNpb24sIFNlY3VyaXR5UU9TKTsKICAgIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nSW5xQXV0aEluZm9BIChSUENSVDQuQCkKICovClJQQ1JUQVBJIFJQQ19TVEFUVVMgUlBDX0VOVFJZClJwY0JpbmRpbmdJbnFBdXRoSW5mb0EoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfQ1NUUiAqU2VydmVyUHJpbmNOYW1lLCBVTE9ORyAqQXV0aG5MZXZlbCwKICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgKkF1dGhuU3ZjLCBSUENfQVVUSF9JREVOVElUWV9IQU5ETEUgKkF1dGhJZGVudGl0eSwgVUxPTkcgKkF1dGh6U3ZjICkKewogICAgRklYTUUoIiVwICVwICVwICVwICVwICVwXG4iLCBCaW5kaW5nLCBTZXJ2ZXJQcmluY05hbWUsIEF1dGhuTGV2ZWwsCiAgICAgICAgICBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2Yyk7CiAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0lucUF1dGhJbmZvVyAoUlBDUlQ0LkApCiAqLwpSUENSVEFQSSBSUENfU1RBVFVTIFJQQ19FTlRSWQpScGNCaW5kaW5nSW5xQXV0aEluZm9XKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX1dTVFIgKlNlcnZlclByaW5jTmFtZSwgVUxPTkcgKkF1dGhuTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HICpBdXRoblN2YywgUlBDX0FVVEhfSURFTlRJVFlfSEFORExFICpBdXRoSWRlbnRpdHksIFVMT05HICpBdXRoelN2YyApCnsKICAgIEZJWE1FKCIlcCAlcCAlcCAlcCAlcCAlcFxuIiwgQmluZGluZywgU2VydmVyUHJpbmNOYW1lLCBBdXRobkxldmVsLAogICAgICAgICAgQXV0aG5TdmMsIEF1dGhJZGVudGl0eSwgQXV0aHpTdmMpOwogICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdTZXRBdXRoSW5mb0V4QSAoUlBDUlQ0LkApCiAqLwpSUENSVEFQSSBSUENfU1RBVFVTIFJQQ19FTlRSWQpScGNCaW5kaW5nU2V0QXV0aEluZm9FeEEoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfQ1NUUiBTZXJ2ZXJQcmluY05hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgQXV0aG5MZXZlbCwgVUxPTkcgQXV0aG5TdmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX0FVVEhfSURFTlRJVFlfSEFORExFIEF1dGhJZGVudGl0eSwgVUxPTkcgQXV0aHpTdnIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NFQ1VSSVRZX1FPUyAqU2VjdXJpdHlRb3MgKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwogIFNFQ1VSSVRZX1NUQVRVUyByOwogIENyZWRIYW5kbGUgY3JlZDsKICBUaW1lU3RhbXAgZXhwOwogIFVMT05HIHBhY2thZ2VfY291bnQ7CiAgVUxPTkcgaTsKICBQU2VjUGtnSW5mb0EgcGFja2FnZXM7CiAgVUxPTkcgY2JNYXhUb2tlbjsKCiAgVFJBQ0UoIiVwICVzICV1ICV1ICVwICV1ICVwXG4iLCBCaW5kaW5nLCBkZWJ1Z3N0cl9hKChjb25zdCBjaGFyKilTZXJ2ZXJQcmluY05hbWUpLAogICAgICAgIEF1dGhuTGV2ZWwsIEF1dGhuU3ZjLCBBdXRoSWRlbnRpdHksIEF1dGh6U3ZyLCBTZWN1cml0eVFvcyk7CgogIGlmIChTZWN1cml0eVFvcykKICB7CiAgICAgIFJQQ19TVEFUVVMgc3RhdHVzOwoKICAgICAgVFJBQ0UoIlNlY3VyaXR5UW9zIHsgVmVyc2lvbj0lbGQsIENhcGFiaWx0aWVzPTB4JWx4LCBJZGVudGl0eVRyYWNraW5nPSVsZCwgSW1wZXJzb25hdGlvbkxldmVsPSVsZCIsCiAgICAgICAgICAgIFNlY3VyaXR5UW9zLT5WZXJzaW9uLCBTZWN1cml0eVFvcy0+Q2FwYWJpbGl0aWVzLCBTZWN1cml0eVFvcy0+SWRlbnRpdHlUcmFja2luZywgU2VjdXJpdHlRb3MtPkltcGVyc29uYXRpb25UeXBlKTsKICAgICAgaWYgKFNlY3VyaXR5UW9zLT5WZXJzaW9uID49IDIpCiAgICAgIHsKICAgICAgICAgIGNvbnN0IFJQQ19TRUNVUklUWV9RT1NfVjJfQSAqU2VjdXJpdHlRb3MyID0gKGNvbnN0IFJQQ19TRUNVUklUWV9RT1NfVjJfQSAqKVNlY3VyaXR5UW9zOwogICAgICAgICAgVFJBQ0UoIiwgQWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGU9JWxkIiwgU2VjdXJpdHlRb3MyLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSk7CiAgICAgICAgICBpZiAoU2VjdXJpdHlRb3MyLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSA9PSBSUENfQ19BVVRITl9JTkZPX1RZUEVfSFRUUCkKICAgICAgICAgICAgICBUUkFDRSgiLCB7ICVwLCAweCVseCwgJWxkLCAlbGQsICVwLCAlcyB9IiwKICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5UcmFuc3BvcnRDcmVkZW50aWFscywKICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5GbGFncywKICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5BdXRoZW50aWNhdGlvblRhcmdldCwKICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5OdW1iZXJPZkF1dGhuU2NoZW1lcywKICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5BdXRoblNjaGVtZXMsCiAgICAgICAgICAgICAgICAgICAgU2VjdXJpdHlRb3MyLT51Lkh0dHBDcmVkZW50aWFscy0+U2VydmVyQ2VydGlmaWNhdGVTdWJqZWN0KTsKICAgICAgfQogICAgICBUUkFDRSgifVxuIik7CiAgICAgIHN0YXR1cyA9IFJwY1F1YWxpdHlPZlNlcnZpY2VfQ3JlYXRlKFNlY3VyaXR5UW9zLCBGQUxTRSwgJmJpbmQtPlFPUyk7CiAgICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICAgICAgICByZXR1cm4gc3RhdHVzOwogIH0KICBlbHNlCiAgewogICAgICBpZiAoYmluZC0+UU9TKSBScGNRdWFsaXR5T2ZTZXJ2aWNlX1JlbGVhc2UoYmluZC0+UU9TKTsKICAgICAgYmluZC0+UU9TID0gTlVMTDsKICB9CgogIGlmIChBdXRoblN2YyA9PSBSUENfQ19BVVRITl9ERUZBVUxUKQogICAgQXV0aG5TdmMgPSBSUENfQ19BVVRITl9XSU5OVDsKCiAgLyogRklYTUU6IHRoZSBtYXBwaW5nIHNob3VsZCBwcm9iYWJseSBiZSByZXRyaWV2ZWQgdXNpbmcgU1NQSSBzb21laG93ICovCiAgaWYgKEF1dGhuTGV2ZWwgPT0gUlBDX0NfQVVUSE5fTEVWRUxfREVGQVVMVCkKICAgIEF1dGhuTGV2ZWwgPSBSUENfQ19BVVRITl9MRVZFTF9OT05FOwoKICBpZiAoKEF1dGhuTGV2ZWwgPT0gUlBDX0NfQVVUSE5fTEVWRUxfTk9ORSkgfHwgKEF1dGhuU3ZjID09IFJQQ19DX0FVVEhOX05PTkUpKQogIHsKICAgIGlmIChiaW5kLT5BdXRoSW5mbykgUnBjQXV0aEluZm9fUmVsZWFzZShiaW5kLT5BdXRoSW5mbyk7CiAgICBiaW5kLT5BdXRoSW5mbyA9IE5VTEw7CiAgICByZXR1cm4gUlBDX1NfT0s7CiAgfQoKICBpZiAoQXV0aG5MZXZlbCA+IFJQQ19DX0FVVEhOX0xFVkVMX1BLVF9QUklWQUNZKQogIHsKICAgIEZJWE1FKCJ1bmtub3duIEF1dGhuTGV2ZWwgJXVcbiIsIEF1dGhuTGV2ZWwpOwogICAgcmV0dXJuIFJQQ19TX1VOS05PV05fQVVUSE5fTEVWRUw7CiAgfQoKICBpZiAoQXV0aHpTdnIpCiAgewogICAgRklYTUUoInVuc3VwcG9ydGVkIEF1dGh6U3ZyICV1XG4iLCBBdXRoelN2cik7CiAgICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRIWl9TRVJWSUNFOwogIH0KCiAgciA9IEVudW1lcmF0ZVNlY3VyaXR5UGFja2FnZXNBKCZwYWNrYWdlX2NvdW50LCAmcGFja2FnZXMpOwogIGlmIChyICE9IFNFQ19FX09LKQogIHsKICAgIEVSUigiRW51bWVyYXRlU2VjdXJpdHlQYWNrYWdlc0EgZmFpbGVkIHdpdGggZXJyb3IgMHglMDh4XG4iLCByKTsKICAgIHJldHVybiBSUENfU19TRUNfUEtHX0VSUk9SOwogIH0KCiAgZm9yIChpID0gMDsgaSA8IHBhY2thZ2VfY291bnQ7IGkrKykKICAgIGlmIChwYWNrYWdlc1tpXS53UlBDSUQgPT0gQXV0aG5TdmMpCiAgICAgICAgYnJlYWs7CgogIGlmIChpID09IHBhY2thZ2VfY291bnQpCiAgewogICAgRklYTUUoInVuc3VwcG9ydGVkIEF1dGhuU3ZjICV1XG4iLCBBdXRoblN2Yyk7CiAgICBGcmVlQ29udGV4dEJ1ZmZlcihwYWNrYWdlcyk7CiAgICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRITl9TRVJWSUNFOwogIH0KCiAgVFJBQ0UoImZvdW5kIHBhY2thZ2UgJXMgZm9yIHNlcnZpY2UgJXVcbiIsIHBhY2thZ2VzW2ldLk5hbWUsIEF1dGhuU3ZjKTsKICByID0gQWNxdWlyZUNyZWRlbnRpYWxzSGFuZGxlQSgoU0VDX0NIQVIgKilTZXJ2ZXJQcmluY05hbWUsIHBhY2thZ2VzW2ldLk5hbWUsIFNFQ1BLR19DUkVEX09VVEJPVU5ELCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1dGhJZGVudGl0eSwgTlVMTCwgTlVMTCwgJmNyZWQsICZleHApOwogIGNiTWF4VG9rZW4gPSBwYWNrYWdlc1tpXS5jYk1heFRva2VuOwogIEZyZWVDb250ZXh0QnVmZmVyKHBhY2thZ2VzKTsKICBpZiAociA9PSBFUlJPUl9TVUNDRVNTKQogIHsKICAgIGlmIChiaW5kLT5BdXRoSW5mbykgUnBjQXV0aEluZm9fUmVsZWFzZShiaW5kLT5BdXRoSW5mbyk7CiAgICBiaW5kLT5BdXRoSW5mbyA9IE5VTEw7CiAgICByID0gUnBjQXV0aEluZm9fQ3JlYXRlKEF1dGhuTGV2ZWwsIEF1dGhuU3ZjLCBjcmVkLCBleHAsIGNiTWF4VG9rZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1dGhJZGVudGl0eSwgJmJpbmQtPkF1dGhJbmZvKTsKICAgIGlmIChyICE9IFJQQ19TX09LKQogICAgICBGcmVlQ3JlZGVudGlhbHNIYW5kbGUoJmNyZWQpOwogICAgcmV0dXJuIFJQQ19TX09LOwogIH0KICBlbHNlCiAgewogICAgRVJSKCJBY3F1aXJlQ3JlZGVudGlhbHNIYW5kbGVBIGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4eFxuIiwgcik7CiAgICByZXR1cm4gUlBDX1NfU0VDX1BLR19FUlJPUjsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nU2V0QXV0aEluZm9FeFcgKFJQQ1JUNC5AKQogKi8KUlBDUlRBUEkgUlBDX1NUQVRVUyBSUENfRU5UUlkKUnBjQmluZGluZ1NldEF1dGhJbmZvRXhXKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgUlBDX1dTVFIgU2VydmVyUHJpbmNOYW1lLCBVTE9ORyBBdXRobkxldmVsLAogICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIEF1dGhuU3ZjLCBSUENfQVVUSF9JREVOVElUWV9IQU5ETEUgQXV0aElkZW50aXR5LCBVTE9ORyBBdXRoelN2ciwKICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfU0VDVVJJVFlfUU9TICpTZWN1cml0eVFvcyApCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKUJpbmRpbmc7CiAgU0VDVVJJVFlfU1RBVFVTIHI7CiAgQ3JlZEhhbmRsZSBjcmVkOwogIFRpbWVTdGFtcCBleHA7CiAgVUxPTkcgcGFja2FnZV9jb3VudDsKICBVTE9ORyBpOwogIFBTZWNQa2dJbmZvVyBwYWNrYWdlczsKICBVTE9ORyBjYk1heFRva2VuOwoKICBUUkFDRSgiJXAgJXMgJXUgJXUgJXAgJXUgJXBcbiIsIEJpbmRpbmcsIGRlYnVnc3RyX3coKGNvbnN0IFdDSEFSKilTZXJ2ZXJQcmluY05hbWUpLAogICAgICAgIEF1dGhuTGV2ZWwsIEF1dGhuU3ZjLCBBdXRoSWRlbnRpdHksIEF1dGh6U3ZyLCBTZWN1cml0eVFvcyk7CgogIGlmIChTZWN1cml0eVFvcykKICB7CiAgICAgIFJQQ19TVEFUVVMgc3RhdHVzOwoKICAgICAgVFJBQ0UoIlNlY3VyaXR5UW9zIHsgVmVyc2lvbj0lbGQsIENhcGFiaWx0aWVzPTB4JWx4LCBJZGVudGl0eVRyYWNraW5nPSVsZCwgSW1wZXJzb25hdGlvbkxldmVsPSVsZCIsCiAgICAgICAgICAgIFNlY3VyaXR5UW9zLT5WZXJzaW9uLCBTZWN1cml0eVFvcy0+Q2FwYWJpbGl0aWVzLCBTZWN1cml0eVFvcy0+SWRlbnRpdHlUcmFja2luZywgU2VjdXJpdHlRb3MtPkltcGVyc29uYXRpb25UeXBlKTsKICAgICAgaWYgKFNlY3VyaXR5UW9zLT5WZXJzaW9uID49IDIpCiAgICAgIHsKICAgICAgICAgIGNvbnN0IFJQQ19TRUNVUklUWV9RT1NfVjJfVyAqU2VjdXJpdHlRb3MyID0gKGNvbnN0IFJQQ19TRUNVUklUWV9RT1NfVjJfVyAqKVNlY3VyaXR5UW9zOwogICAgICAgICAgVFJBQ0UoIiwgQWRkaXRpb25hbFNlY3VyaXR5SW5mb1R5cGU9JWxkIiwgU2VjdXJpdHlRb3MyLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSk7CiAgICAgICAgICBpZiAoU2VjdXJpdHlRb3MyLT5BZGRpdGlvbmFsU2VjdXJpdHlJbmZvVHlwZSA9PSBSUENfQ19BVVRITl9JTkZPX1RZUEVfSFRUUCkKICAgICAgICAgICAgICBUUkFDRSgiLCB7ICVwLCAweCVseCwgJWxkLCAlbGQsICVwLCAlcyB9IiwKICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5UcmFuc3BvcnRDcmVkZW50aWFscywKICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5GbGFncywKICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5BdXRoZW50aWNhdGlvblRhcmdldCwKICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5OdW1iZXJPZkF1dGhuU2NoZW1lcywKICAgICAgICAgICAgICAgICAgICBTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5BdXRoblNjaGVtZXMsCiAgICAgICAgICAgICAgICAgICAgZGVidWdzdHJfdyhTZWN1cml0eVFvczItPnUuSHR0cENyZWRlbnRpYWxzLT5TZXJ2ZXJDZXJ0aWZpY2F0ZVN1YmplY3QpKTsKICAgICAgfQogICAgICBUUkFDRSgifVxuIik7CiAgICAgIHN0YXR1cyA9IFJwY1F1YWxpdHlPZlNlcnZpY2VfQ3JlYXRlKFNlY3VyaXR5UW9zLCBUUlVFLCAmYmluZC0+UU9TKTsKICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgICAgIHJldHVybiBzdGF0dXM7CiAgfQogIGVsc2UKICB7CiAgICAgIGlmIChiaW5kLT5RT1MpIFJwY1F1YWxpdHlPZlNlcnZpY2VfUmVsZWFzZShiaW5kLT5RT1MpOwogICAgICBiaW5kLT5RT1MgPSBOVUxMOwogIH0KCiAgaWYgKEF1dGhuU3ZjID09IFJQQ19DX0FVVEhOX0RFRkFVTFQpCiAgICBBdXRoblN2YyA9IFJQQ19DX0FVVEhOX1dJTk5UOwoKICAvKiBGSVhNRTogdGhlIG1hcHBpbmcgc2hvdWxkIHByb2JhYmx5IGJlIHJldHJpZXZlZCB1c2luZyBTU1BJIHNvbWVob3cgKi8KICBpZiAoQXV0aG5MZXZlbCA9PSBSUENfQ19BVVRITl9MRVZFTF9ERUZBVUxUKQogICAgQXV0aG5MZXZlbCA9IFJQQ19DX0FVVEhOX0xFVkVMX05PTkU7CgogIGlmICgoQXV0aG5MZXZlbCA9PSBSUENfQ19BVVRITl9MRVZFTF9OT05FKSB8fCAoQXV0aG5TdmMgPT0gUlBDX0NfQVVUSE5fTk9ORSkpCiAgewogICAgaWYgKGJpbmQtPkF1dGhJbmZvKSBScGNBdXRoSW5mb19SZWxlYXNlKGJpbmQtPkF1dGhJbmZvKTsKICAgIGJpbmQtPkF1dGhJbmZvID0gTlVMTDsKICAgIHJldHVybiBSUENfU19PSzsKICB9CgogIGlmIChBdXRobkxldmVsID4gUlBDX0NfQVVUSE5fTEVWRUxfUEtUX1BSSVZBQ1kpCiAgewogICAgRklYTUUoInVua25vd24gQXV0aG5MZXZlbCAldVxuIiwgQXV0aG5MZXZlbCk7CiAgICByZXR1cm4gUlBDX1NfVU5LTk9XTl9BVVRITl9MRVZFTDsKICB9CgogIGlmIChBdXRoelN2cikKICB7CiAgICBGSVhNRSgidW5zdXBwb3J0ZWQgQXV0aHpTdnIgJXVcbiIsIEF1dGh6U3ZyKTsKICAgIHJldHVybiBSUENfU19VTktOT1dOX0FVVEhaX1NFUlZJQ0U7CiAgfQoKICByID0gRW51bWVyYXRlU2VjdXJpdHlQYWNrYWdlc1coJnBhY2thZ2VfY291bnQsICZwYWNrYWdlcyk7CiAgaWYgKHIgIT0gU0VDX0VfT0spCiAgewogICAgRVJSKCJFbnVtZXJhdGVTZWN1cml0eVBhY2thZ2VzQSBmYWlsZWQgd2l0aCBlcnJvciAweCUwOHhcbiIsIHIpOwogICAgcmV0dXJuIFJQQ19TX1NFQ19QS0dfRVJST1I7CiAgfQoKICBmb3IgKGkgPSAwOyBpIDwgcGFja2FnZV9jb3VudDsgaSsrKQogICAgaWYgKHBhY2thZ2VzW2ldLndSUENJRCA9PSBBdXRoblN2YykKICAgICAgICBicmVhazsKCiAgaWYgKGkgPT0gcGFja2FnZV9jb3VudCkKICB7CiAgICBGSVhNRSgidW5zdXBwb3J0ZWQgQXV0aG5TdmMgJXVcbiIsIEF1dGhuU3ZjKTsKICAgIEZyZWVDb250ZXh0QnVmZmVyKHBhY2thZ2VzKTsKICAgIHJldHVybiBSUENfU19VTktOT1dOX0FVVEhOX1NFUlZJQ0U7CiAgfQoKICBUUkFDRSgiZm91bmQgcGFja2FnZSAlcyBmb3Igc2VydmljZSAldVxuIiwgZGVidWdzdHJfdyhwYWNrYWdlc1tpXS5OYW1lKSwgQXV0aG5TdmMpOwogIHIgPSBBY3F1aXJlQ3JlZGVudGlhbHNIYW5kbGVXKChTRUNfV0NIQVIgKilTZXJ2ZXJQcmluY05hbWUsIHBhY2thZ2VzW2ldLk5hbWUsIFNFQ1BLR19DUkVEX09VVEJPVU5ELCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1dGhJZGVudGl0eSwgTlVMTCwgTlVMTCwgJmNyZWQsICZleHApOwogIGNiTWF4VG9rZW4gPSBwYWNrYWdlc1tpXS5jYk1heFRva2VuOwogIEZyZWVDb250ZXh0QnVmZmVyKHBhY2thZ2VzKTsKICBpZiAociA9PSBFUlJPUl9TVUNDRVNTKQogIHsKICAgIGlmIChiaW5kLT5BdXRoSW5mbykgUnBjQXV0aEluZm9fUmVsZWFzZShiaW5kLT5BdXRoSW5mbyk7CiAgICBiaW5kLT5BdXRoSW5mbyA9IE5VTEw7CiAgICByID0gUnBjQXV0aEluZm9fQ3JlYXRlKEF1dGhuTGV2ZWwsIEF1dGhuU3ZjLCBjcmVkLCBleHAsIGNiTWF4VG9rZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEF1dGhJZGVudGl0eSwgJmJpbmQtPkF1dGhJbmZvKTsKICAgIGlmIChyICE9IFJQQ19TX09LKQogICAgICBGcmVlQ3JlZGVudGlhbHNIYW5kbGUoJmNyZWQpOwogICAgcmV0dXJuIFJQQ19TX09LOwogIH0KICBlbHNlCiAgewogICAgRVJSKCJBY3F1aXJlQ3JlZGVudGlhbHNIYW5kbGVBIGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4eFxuIiwgcik7CiAgICByZXR1cm4gUlBDX1NfU0VDX1BLR19FUlJPUjsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nU2V0QXV0aEluZm9BIChSUENSVDQuQCkKICovClJQQ1JUQVBJIFJQQ19TVEFUVVMgUlBDX0VOVFJZClJwY0JpbmRpbmdTZXRBdXRoSW5mb0EoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfQ1NUUiBTZXJ2ZXJQcmluY05hbWUsIFVMT05HIEF1dGhuTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIEF1dGhuU3ZjLCBSUENfQVVUSF9JREVOVElUWV9IQU5ETEUgQXV0aElkZW50aXR5LCBVTE9ORyBBdXRoelN2ciApCnsKICAgIFRSQUNFKCIlcCAlcyAldSAldSAlcCAldVxuIiwgQmluZGluZywgZGVidWdzdHJfYSgoY29uc3QgY2hhciopU2VydmVyUHJpbmNOYW1lKSwKICAgICAgICAgIEF1dGhuTGV2ZWwsIEF1dGhuU3ZjLCBBdXRoSWRlbnRpdHksIEF1dGh6U3ZyKTsKICAgIHJldHVybiBScGNCaW5kaW5nU2V0QXV0aEluZm9FeEEoQmluZGluZywgU2VydmVyUHJpbmNOYW1lLCBBdXRobkxldmVsLCBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2ciwgTlVMTCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nU2V0QXV0aEluZm9XIChSUENSVDQuQCkKICovClJQQ1JUQVBJIFJQQ19TVEFUVVMgUlBDX0VOVFJZClJwY0JpbmRpbmdTZXRBdXRoSW5mb1coIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfV1NUUiBTZXJ2ZXJQcmluY05hbWUsIFVMT05HIEF1dGhuTGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIEF1dGhuU3ZjLCBSUENfQVVUSF9JREVOVElUWV9IQU5ETEUgQXV0aElkZW50aXR5LCBVTE9ORyBBdXRoelN2ciApCnsKICAgIFRSQUNFKCIlcCAlcyAldSAldSAlcCAldVxuIiwgQmluZGluZywgZGVidWdzdHJfdygoY29uc3QgV0NIQVIqKVNlcnZlclByaW5jTmFtZSksCiAgICAgICAgICBBdXRobkxldmVsLCBBdXRoblN2YywgQXV0aElkZW50aXR5LCBBdXRoelN2cik7CiAgICByZXR1cm4gUnBjQmluZGluZ1NldEF1dGhJbmZvRXhXKEJpbmRpbmcsIFNlcnZlclByaW5jTmFtZSwgQXV0aG5MZXZlbCwgQXV0aG5TdmMsIEF1dGhJZGVudGl0eSwgQXV0aHpTdnIsIE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ1NldE9wdGlvbiAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nU2V0T3B0aW9uKFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nSGFuZGxlLCBVTE9ORyBPcHRpb24sIFVMT05HIE9wdGlvblZhbHVlKQp7CiAgICBGSVhNRSgiKCVwLCAlZCwgJWQpOiBzdHViXG4iLCBCaW5kaW5nSGFuZGxlLCBPcHRpb24sIE9wdGlvblZhbHVlKTsKICAgIHJldHVybiBSUENfU19PSzsKfQo=