LyoKICogUlBDIGJpbmRpbmcgQVBJCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBhIHdob2xlIGxvdAogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKCiNpbmNsdWRlICJycGMuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSAicnBjX2JpbmRpbmcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7CgpzdGF0aWMgUnBjQ29ubmVjdGlvbiogY29ubl9jYWNoZTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGNvbm5fY2FjaGVfY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGNyaXRzZWN0X2RlYnVnID0KewogICAgMCwgMCwgJmNvbm5fY2FjaGVfY3MsCiAgICB7ICZjcml0c2VjdF9kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LCAmY3JpdHNlY3RfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IDAsIChEV09SRCkoX19GSUxFX18gIjogY29ubl9jYWNoZV9jcyIpIH0KfTsKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT04gY29ubl9jYWNoZV9jcyA9IHsgJmNyaXRzZWN0X2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKTFBTVFIgUlBDUlQ0X3N0cm5kdXBBKExQQ1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQU1RSIHM7CiAgaWYgKCFzcmMpIHJldHVybiBOVUxMOwogIGlmIChzbGVuID09IC0xKSBzbGVuID0gc3RybGVuKHNyYyk7CiAgbGVuID0gc2xlbjsKICBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbisxKTsKICBtZW1jcHkocywgc3JjLCBsZW4pOwogIHNbbGVuXSA9IDA7CiAgcmV0dXJuIHM7Cn0KCkxQU1RSIFJQQ1JUNF9zdHJkdXBXdG9BKExQV1NUUiBzcmMpCnsKICBEV09SRCBsZW47CiAgTFBTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKTsKICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgc3JjLCAtMSwgcywgbGVuLCBOVUxMLCBOVUxMKTsKICByZXR1cm4gczsKfQoKTFBXU1RSIFJQQ1JUNF9zdHJkdXBBdG9XKExQU1RSIHNyYykKewogIERXT1JEIGxlbjsKICBMUFdTVFIgczsKICBpZiAoIXNyYykgcmV0dXJuIE5VTEw7CiAgbGVuID0gTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHNyYywgLTEsIE5VTEwsIDApOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzcmMsIC0xLCBzLCBsZW4pOwogIHJldHVybiBzOwp9CgpMUFdTVFIgUlBDUlQ0X3N0cm5kdXBXKExQV1NUUiBzcmMsIElOVCBzbGVuKQp7CiAgRFdPUkQgbGVuOwogIExQV1NUUiBzOwogIGlmICghc3JjKSByZXR1cm4gTlVMTDsKICBpZiAoc2xlbiA9PSAtMSkgc2xlbiA9IHN0cmxlblcoc3JjKTsKICBsZW4gPSBzbGVuOwogIHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgKGxlbisxKSpzaXplb2YoV0NIQVIpKTsKICBtZW1jcHkocywgc3JjLCBsZW4qc2l6ZW9mKFdDSEFSKSk7CiAgc1tsZW5dID0gMDsKICByZXR1cm4gczsKfQoKdm9pZCBSUENSVDRfc3RyZnJlZShMUFNUUiBzcmMpCnsKICBpZiAoc3JjKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzcmMpOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBCT09MIHNlcnZlciwgTFBTVFIgUHJvdHNlcSwgTFBTVFIgTmV0d29ya0FkZHIsIExQU1RSIEVuZHBvaW50LCBMUFNUUiBOZXR3b3JrT3B0aW9ucywgUnBjQmluZGluZyogQmluZGluZykKewogIFJwY0Nvbm5lY3Rpb24qIE5ld0Nvbm5lY3Rpb247CgogIE5ld0Nvbm5lY3Rpb24gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY0Nvbm5lY3Rpb24pKTsKICBOZXdDb25uZWN0aW9uLT5zZXJ2ZXIgPSBzZXJ2ZXI7CiAgTmV3Q29ubmVjdGlvbi0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBBKFByb3RzZXEpOwogIE5ld0Nvbm5lY3Rpb24tPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoTmV0d29ya0FkZHIpOwogIE5ld0Nvbm5lY3Rpb24tPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIE5ld0Nvbm5lY3Rpb24tPlVzZWQgPSBCaW5kaW5nOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY29ubl9jYWNoZV9jcyk7CiAgTmV3Q29ubmVjdGlvbi0+TmV4dCA9IGNvbm5fY2FjaGU7CiAgY29ubl9jYWNoZSA9IE5ld0Nvbm5lY3Rpb247CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmNvbm5fY2FjaGVfY3MpOwoKICBUUkFDRSgiY29ubmVjdGlvbjogJXBcbiIsIE5ld0Nvbm5lY3Rpb24pOwogICpDb25uZWN0aW9uID0gTmV3Q29ubmVjdGlvbjsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgUnBjQ29ubmVjdGlvbiogUHJldkNvbm5lY3Rpb247CgogIFRSQUNFKCJjb25uZWN0aW9uOiAlcFxuIiwgQ29ubmVjdGlvbik7CiAgaWYgKENvbm5lY3Rpb24tPlVzZWQpIEVSUigiY29ubmVjdGlvbiBpcyBzdGlsbCBpbiB1c2VcbiIpOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmY29ubl9jYWNoZV9jcyk7CiAgUHJldkNvbm5lY3Rpb24gPSBjb25uX2NhY2hlOwogIHdoaWxlIChQcmV2Q29ubmVjdGlvbiAmJiBQcmV2Q29ubmVjdGlvbi0+TmV4dCAhPSBDb25uZWN0aW9uKQogICAgUHJldkNvbm5lY3Rpb24gPSBQcmV2Q29ubmVjdGlvbi0+TmV4dDsKICBpZiAoUHJldkNvbm5lY3Rpb24pIFByZXZDb25uZWN0aW9uLT5OZXh0ID0gQ29ubmVjdGlvbi0+TmV4dDsKICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY29ubl9jYWNoZV9jcyk7CgogIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oQ29ubmVjdGlvbik7CiAgUlBDUlQ0X3N0cmZyZWUoQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIFJQQ1JUNF9zdHJmcmVlKENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyKTsKICBSUENSVDRfc3RyZnJlZShDb25uZWN0aW9uLT5Qcm90c2VxKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBDb25uZWN0aW9uKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0dldENvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbioqIENvbm5lY3Rpb24sIEJPT0wgc2VydmVyLCBMUFNUUiBQcm90c2VxLCBMUFNUUiBOZXR3b3JrQWRkciwgTFBTVFIgRW5kcG9pbnQsIExQU1RSIE5ldHdvcmtPcHRpb25zLCBScGNCaW5kaW5nKiBCaW5kaW5nKQp7CiAgUnBjQ29ubmVjdGlvbiogTmV3Q29ubmVjdGlvbjsKCiAgaWYgKCFzZXJ2ZXIpIHsKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZjb25uX2NhY2hlX2NzKTsKICAgIGZvciAoTmV3Q29ubmVjdGlvbiA9IGNvbm5fY2FjaGU7IE5ld0Nvbm5lY3Rpb247IE5ld0Nvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uLT5OZXh0KSB7CiAgICAgIGlmIChOZXdDb25uZWN0aW9uLT5Vc2VkKSBjb250aW51ZTsKICAgICAgaWYgKE5ld0Nvbm5lY3Rpb24tPnNlcnZlciAhPSBzZXJ2ZXIpIGNvbnRpbnVlOwogICAgICBpZiAoUHJvdHNlcSAmJiBzdHJjbXAoTmV3Q29ubmVjdGlvbi0+UHJvdHNlcSwgUHJvdHNlcSkpIGNvbnRpbnVlOwogICAgICBpZiAoTmV0d29ya0FkZHIgJiYgc3RyY21wKE5ld0Nvbm5lY3Rpb24tPk5ldHdvcmtBZGRyLCBOZXR3b3JrQWRkcikpIGNvbnRpbnVlOwogICAgICBpZiAoRW5kcG9pbnQgJiYgc3RyY21wKE5ld0Nvbm5lY3Rpb24tPkVuZHBvaW50LCBFbmRwb2ludCkpIGNvbnRpbnVlOwogICAgICAvKiB0aGlzIGNvbm5lY3Rpb24gZml0cyB0aGUgYmlsbCAqLwogICAgICBOZXdDb25uZWN0aW9uLT5Vc2VkID0gQmluZGluZzsKICAgICAgYnJlYWs7CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmY29ubl9jYWNoZV9jcyk7CiAgICBpZiAoTmV3Q29ubmVjdGlvbikgewogICAgICBUUkFDRSgiY2FjaGVkIGNvbm5lY3Rpb246ICVwXG4iLCBOZXdDb25uZWN0aW9uKTsKICAgICAgKkNvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uOwogICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICB9CiAgfQogIHJldHVybiBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbihDb25uZWN0aW9uLCBzZXJ2ZXIsIFByb3RzZXEsIE5ldHdvcmtBZGRyLCBFbmRwb2ludCwgTmV0d29ya09wdGlvbnMsIEJpbmRpbmcpOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9SZWxlYXNlQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoImNvbm5lY3Rpb246ICVwXG4iLCBDb25uZWN0aW9uKTsKICBDb25uZWN0aW9uLT5Vc2VkID0gTlVMTDsKICBpZiAoIUNvbm5lY3Rpb24tPnNlcnZlcikgewogICAgLyogY2FjaGUgdGhlIG9wZW4gY29ubmVjdGlvbiBmb3IgcmV1c2UgbGF0ZXIgKi8KICAgIC8qIEZJWE1FOiB3ZSBzaG91bGQgcHJvYmFibHkgY2xlYW4gdGhlIGNhY2hlIHNvbWVkYXkgKi8KICAgIHJldHVybiBSUENfU19PSzsKICB9CiAgcmV0dXJuIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihDb25uZWN0aW9uKTsKfQoKUlBDX1NUQVRVUyBSUENSVDRfT3BlbkNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKICBpZiAoIUNvbm5lY3Rpb24tPmNvbm4pIHsKICAgIGlmIChDb25uZWN0aW9uLT5zZXJ2ZXIpIHsgLyogc2VydmVyICovCiAgICAgIC8qIHByb3RzZXE9bmNhbHJwYzogc3VwcG9zZWQgdG8gdXNlIE5UIExQQyBwb3J0cywKICAgICAgICogYnV0IHdlJ2xsIGltcGxlbWVudCBpdCB3aXRoIG5hbWVkIHBpcGVzIGZvciBub3cgKi8KICAgICAgaWYgKHN0cmNtcChDb25uZWN0aW9uLT5Qcm90c2VxLCAibmNhbHJwYyIpID09IDApIHsKICAgICAgICBzdGF0aWMgTFBDU1RSIHByZWZpeCA9ICJcXFxcLlxccGlwZVxcbHJwY1xcIjsKICAgICAgICBMUFNUUiBwbmFtZTsKICAgICAgICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICAgICAgICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgICAgICAgVFJBQ0UoImxpc3RlbmluZyBvbiAlc1xuIiwgcG5hbWUpOwogICAgICAgIENvbm5lY3Rpb24tPmNvbm4gPSBDcmVhdGVOYW1lZFBpcGVBKHBuYW1lLCBQSVBFX0FDQ0VTU19EVVBMRVggfCBGSUxFX0ZMQUdfT1ZFUkxBUFBFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBQSVBFX1VOTElNSVRFRF9JTlNUQU5DRVMsIDAsIDAsIDUwMDAsIE5VTEwpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKICAgICAgICBtZW1zZXQoJkNvbm5lY3Rpb24tPm92bCwgMCwgc2l6ZW9mKENvbm5lY3Rpb24tPm92bCkpOwogICAgICAgIENvbm5lY3Rpb24tPm92bC5oRXZlbnQgPSBDcmVhdGVFdmVudEEoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogICAgICAgIGlmICghQ29ubmVjdE5hbWVkUGlwZShDb25uZWN0aW9uLT5jb25uLCAmQ29ubmVjdGlvbi0+b3ZsKSkgewogICAgICAgICAgRFdPUkQgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgICBpZiAoZXJyID09IEVSUk9SX1BJUEVfQ09OTkVDVEVEKSB7CiAgICAgICAgICAgIFNldEV2ZW50KENvbm5lY3Rpb24tPm92bC5oRXZlbnQpOwogICAgICAgICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gZXJyOwogICAgICAgIH0KICAgICAgfQogICAgICAvKiBwcm90c2VxPW5jYWNuX25wOiBuYW1lZCBwaXBlcyAqLwogICAgICBlbHNlIGlmIChzdHJjbXAoQ29ubmVjdGlvbi0+UHJvdHNlcSwgIm5jYWNuX25wIikgPT0gMCkgewogICAgICAgIHN0YXRpYyBMUENTVFIgcHJlZml4ID0gIlxcXFwuIjsKICAgICAgICBMUFNUUiBwbmFtZTsKICAgICAgICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICAgICAgICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgICAgICAgVFJBQ0UoImxpc3RlbmluZyBvbiAlc1xuIiwgcG5hbWUpOwogICAgICAgIENvbm5lY3Rpb24tPmNvbm4gPSBDcmVhdGVOYW1lZFBpcGVBKHBuYW1lLCBQSVBFX0FDQ0VTU19EVVBMRVggfCBGSUxFX0ZMQUdfT1ZFUkxBUFBFRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCBQSVBFX1VOTElNSVRFRF9JTlNUQU5DRVMsIDAsIDAsIDUwMDAsIE5VTEwpOwogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKICAgICAgICBtZW1zZXQoJkNvbm5lY3Rpb24tPm92bCwgMCwgc2l6ZW9mKENvbm5lY3Rpb24tPm92bCkpOwogICAgICAgIENvbm5lY3Rpb24tPm92bC5oRXZlbnQgPSBDcmVhdGVFdmVudEEoTlVMTCwgVFJVRSwgRkFMU0UsIE5VTEwpOwogICAgICAgIGlmICghQ29ubmVjdE5hbWVkUGlwZShDb25uZWN0aW9uLT5jb25uLCAmQ29ubmVjdGlvbi0+b3ZsKSkgewogICAgICAgICAgRFdPUkQgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgICBpZiAoZXJyID09IEVSUk9SX1BJUEVfQ09OTkVDVEVEKSB7CiAgICAgICAgICAgIFNldEV2ZW50KENvbm5lY3Rpb24tPm92bC5oRXZlbnQpOwogICAgICAgICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gZXJyOwogICAgICAgIH0KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBFUlIoInByb3RzZXEgJXMgbm90IHN1cHBvcnRlZFxuIiwgQ29ubmVjdGlvbi0+UHJvdHNlcSk7CiAgICAgICAgcmV0dXJuIFJQQ19TX1BST1RTRVFfTk9UX1NVUFBPUlRFRDsKICAgICAgfQogICAgfQogICAgZWxzZSB7IC8qIGNsaWVudCAqLwogICAgICAvKiBwcm90c2VxPW5jYWxycGM6IHN1cHBvc2VkIHRvIHVzZSBOVCBMUEMgcG9ydHMsCiAgICAgICAqIGJ1dCB3ZSdsbCBpbXBsZW1lbnQgaXQgd2l0aCBuYW1lZCBwaXBlcyBmb3Igbm93ICovCiAgICAgIGlmIChzdHJjbXAoQ29ubmVjdGlvbi0+UHJvdHNlcSwgIm5jYWxycGMiKSA9PSAwKSB7CiAgICAgICAgc3RhdGljIExQQ1NUUiBwcmVmaXggPSAiXFxcXC5cXHBpcGVcXGxycGNcXCI7CiAgICAgICAgTFBTVFIgcG5hbWU7CiAgICAgICAgSEFORExFIGNvbm47CiAgICAgICAgRFdPUkQgZXJyOwoKICAgICAgICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICAgICAgICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgICAgICAgVFJBQ0UoImNvbm5lY3RpbmcgdG8gJXNcbiIsIHBuYW1lKTsKICAgICAgICB3aGlsZSAoVFJVRSkgewogICAgICAgICAgaWYgKFdhaXROYW1lZFBpcGVBKHBuYW1lLCBOTVBXQUlUX1dBSVRfRk9SRVZFUikpIHsKICAgICAgICAgICAgY29ubiA9IENyZWF0ZUZpbGVBKHBuYW1lLCBHRU5FUklDX1JFQUR8R0VORVJJQ19XUklURSwgMCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9QRU5fRVhJU1RJTkcsIEZJTEVfRkxBR19PVkVSTEFQUEVELCAwKTsKICAgICAgICAgICAgaWYgKGNvbm4gIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIGJyZWFrOwogICAgICAgICAgICBlcnIgPSBHZXRMYXN0RXJyb3IoKTsKICAgICAgICAgICAgaWYgKGVyciA9PSBFUlJPUl9QSVBFX0JVU1kpIGNvbnRpbnVlOwogICAgICAgICAgICBUUkFDRSgiY29ubmVjdGlvbiBmYWlsZWQsIGVycm9yPSVseFxuIiwgZXJyKTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgICAgICByZXR1cm4gZXJyOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICAgICAgICAgIFRSQUNFKCJjb25uZWN0aW9uIGZhaWxlZCwgZXJyb3I9JWx4XG4iLCBlcnIpOwogICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwbmFtZSk7CiAgICAgICAgICAgIHJldHVybiBlcnI7CiAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKiBzdWNjZXNzICovCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgIG1lbXNldCgmQ29ubmVjdGlvbi0+b3ZsLCAwLCBzaXplb2YoQ29ubmVjdGlvbi0+b3ZsKSk7CiAgICAgICAgQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCA9IENyZWF0ZUV2ZW50QShOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgQ29ubmVjdGlvbi0+Y29ubiA9IGNvbm47CiAgICAgIH0KICAgICAgLyogcHJvdHNlcT1uY2Fjbl9ucDogbmFtZWQgcGlwZXMgKi8KICAgICAgZWxzZSBpZiAoc3RyY21wKENvbm5lY3Rpb24tPlByb3RzZXEsICJuY2Fjbl9ucCIpID09IDApIHsKICAgICAgICBzdGF0aWMgTFBDU1RSIHByZWZpeCA9ICJcXFxcLiI7CiAgICAgICAgTFBTVFIgcG5hbWU7CiAgICAgICAgSEFORExFIGNvbm47CiAgICAgICAgRFdPUkQgZXJyOwoKICAgICAgICBwbmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHJsZW4ocHJlZml4KSArIHN0cmxlbihDb25uZWN0aW9uLT5FbmRwb2ludCkgKyAxKTsKICAgICAgICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBDb25uZWN0aW9uLT5FbmRwb2ludCk7CiAgICAgICAgVFJBQ0UoImNvbm5lY3RpbmcgdG8gJXNcbiIsIHBuYW1lKTsKICAgICAgICBjb25uID0gQ3JlYXRlRmlsZUEocG5hbWUsIEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFLCAwLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICBPUEVOX0VYSVNUSU5HLCBGSUxFX0ZMQUdfT1ZFUkxBUFBFRCwgMCk7CiAgICAgICAgaWYgKGNvbm4gPT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIHsKICAgICAgICAgIGVyciA9IEdldExhc3RFcnJvcigpOwogICAgICAgICAgLyogd2UgZG9uJ3QgbmVlZCB0byBoYW5kbGUgRVJST1JfUElQRV9CVVNZIGhlcmUsCiAgICAgICAgICAgKiB0aGUgZG9jIHNheXMgdGhhdCBpdCBpcyByZXR1cm5lZCB0byB0aGUgYXBwICovCiAgICAgICAgICBUUkFDRSgiY29ubmVjdGlvbiBmYWlsZWQsIGVycm9yPSVseFxuIiwgZXJyKTsKICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBuYW1lKTsKICAgICAgICAgIHJldHVybiBlcnI7CiAgICAgICAgfQoKICAgICAgICAvKiBzdWNjZXNzICovCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcG5hbWUpOwogICAgICAgIG1lbXNldCgmQ29ubmVjdGlvbi0+b3ZsLCAwLCBzaXplb2YoQ29ubmVjdGlvbi0+b3ZsKSk7CiAgICAgICAgQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCA9IENyZWF0ZUV2ZW50QShOVUxMLCBUUlVFLCBGQUxTRSwgTlVMTCk7CiAgICAgICAgQ29ubmVjdGlvbi0+Y29ubiA9IGNvbm47CiAgICAgIH0gZWxzZSB7CiAgICAgICAgRVJSKCJwcm90c2VxICVzIG5vdCBzdXBwb3J0ZWRcbiIsIENvbm5lY3Rpb24tPlByb3RzZXEpOwogICAgICAgIHJldHVybiBSUENfU19QUk9UU0VRX05PVF9TVVBQT1JURUQ7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCIoQ29ubmVjdGlvbiA9PSBeJXApXG4iLCBDb25uZWN0aW9uKTsKICBpZiAoQ29ubmVjdGlvbi0+Y29ubikgewogICAgQ2FuY2VsSW8oQ29ubmVjdGlvbi0+Y29ubik7CiAgICBDbG9zZUhhbmRsZShDb25uZWN0aW9uLT5jb25uKTsKICAgIENvbm5lY3Rpb24tPmNvbm4gPSAwOwogIH0KICBpZiAoQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCkgewogICAgQ2xvc2VIYW5kbGUoQ29ubmVjdGlvbi0+b3ZsLmhFdmVudCk7CiAgICBDb25uZWN0aW9uLT5vdmwuaEV2ZW50ID0gMDsKICB9CiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9TcGF3bkNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbioqIENvbm5lY3Rpb24sIFJwY0Nvbm5lY3Rpb24qIE9sZENvbm5lY3Rpb24pCnsKICBScGNDb25uZWN0aW9uKiBOZXdDb25uZWN0aW9uOwogIFJQQ19TVEFUVVMgZXJyID0gUlBDUlQ0X0NyZWF0ZUNvbm5lY3Rpb24oJk5ld0Nvbm5lY3Rpb24sIE9sZENvbm5lY3Rpb24tPnNlcnZlciwgT2xkQ29ubmVjdGlvbi0+UHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9sZENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyLCBPbGRDb25uZWN0aW9uLT5FbmRwb2ludCwgTlVMTCwgTlVMTCk7CiAgaWYgKGVyciA9PSBSUENfU19PSykgewogICAgLyogYmVjYXVzZSBvZiB0aGUgd2F5IG5hbWVkIHBpcGVzIHdvcmssIHdlJ2xsIHRyYW5zZmVyIHRoZSBjb25uZWN0ZWQgcGlwZQogICAgICogdG8gdGhlIGNoaWxkLCB0aGVuIHJlb3BlbiB0aGUgc2VydmVyIGJpbmRpbmcgdG8gY29udGludWUgbGlzdGVuaW5nICovCiAgICBOZXdDb25uZWN0aW9uLT5jb25uID0gT2xkQ29ubmVjdGlvbi0+Y29ubjsKICAgIE5ld0Nvbm5lY3Rpb24tPm92bCA9IE9sZENvbm5lY3Rpb24tPm92bDsKICAgIE9sZENvbm5lY3Rpb24tPmNvbm4gPSAwOwogICAgbWVtc2V0KCZPbGRDb25uZWN0aW9uLT5vdmwsIDAsIHNpemVvZihPbGRDb25uZWN0aW9uLT5vdmwpKTsKICAgICpDb25uZWN0aW9uID0gTmV3Q29ubmVjdGlvbjsKICAgIFJQQ1JUNF9PcGVuQ29ubmVjdGlvbihPbGRDb25uZWN0aW9uKTsKICB9CiAgcmV0dXJuIGVycjsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQWxsb2NCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBCT09MIHNlcnZlcikKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIE5ld0JpbmRpbmcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKFJwY0JpbmRpbmcpKTsKICBOZXdCaW5kaW5nLT5yZWZzID0gMTsKICBOZXdCaW5kaW5nLT5zZXJ2ZXIgPSBzZXJ2ZXI7CgogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVCaW5kaW5nQShScGNCaW5kaW5nKiogQmluZGluZywgQk9PTCBzZXJ2ZXIsIExQU1RSIFByb3RzZXEpCnsKICBScGNCaW5kaW5nKiBOZXdCaW5kaW5nOwoKICBSUENSVDRfQWxsb2NCaW5kaW5nKCZOZXdCaW5kaW5nLCBzZXJ2ZXIpOwogIE5ld0JpbmRpbmctPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwQShQcm90c2VxKTsKCiAgVFJBQ0UoImJpbmRpbmc6ICVwXG4iLCBOZXdCaW5kaW5nKTsKICAqQmluZGluZyA9IE5ld0JpbmRpbmc7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ3JlYXRlQmluZGluZ1coUnBjQmluZGluZyoqIEJpbmRpbmcsIEJPT0wgc2VydmVyLCBMUFdTVFIgUHJvdHNlcSkKewogIFJwY0JpbmRpbmcqIE5ld0JpbmRpbmc7CgogIFJQQ1JUNF9BbGxvY0JpbmRpbmcoJk5ld0JpbmRpbmcsIHNlcnZlcik7CiAgTmV3QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBXdG9BKFByb3RzZXEpOwoKICBUUkFDRSgiYmluZGluZzogJXBcbiIsIE5ld0JpbmRpbmcpOwogICpCaW5kaW5nID0gTmV3QmluZGluZzsKCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9Db21wbGV0ZUJpbmRpbmdBKFJwY0JpbmRpbmcqIEJpbmRpbmcsIExQU1RSIE5ldHdvcmtBZGRyLCAgTFBTVFIgRW5kcG9pbnQsICBMUFNUUiBOZXR3b3JrT3B0aW9ucykKewogIFRSQUNFKCIoUnBjQmluZGluZyA9PSBeJXAsIE5ldHdvcmtBZGRyID09IFwiJXNcIiwgRW5kUG9pbnQgPT0gXCIlc1wiLCBOZXR3b3JrT3B0aW9ucyA9PSBcIiVzXCIpXG4iLCBCaW5kaW5nLAogICBkZWJ1Z3N0cl9hKE5ldHdvcmtBZGRyKSwgZGVidWdzdHJfYShFbmRwb2ludCksIGRlYnVnc3RyX2EoTmV0d29ya09wdGlvbnMpKTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+TmV0d29ya0FkZHIpOwogIEJpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoTmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBpZiAoRW5kcG9pbnQpIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIH0gZWxzZSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKCIiKTsKICB9CiAgaWYgKCFCaW5kaW5nLT5FbmRwb2ludCkgRVJSKCJvdXQgb2YgbWVtb3J5P1xuIik7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ29tcGxldGVCaW5kaW5nVyhScGNCaW5kaW5nKiBCaW5kaW5nLCBMUFdTVFIgTmV0d29ya0FkZHIsIExQV1NUUiBFbmRwb2ludCwgTFBXU1RSIE5ldHdvcmtPcHRpb25zKQp7CiAgVFJBQ0UoIihScGNCaW5kaW5nID09IF4lcCwgTmV0d29ya0FkZHIgPT0gXCIlc1wiLCBFbmRQb2ludCA9PSBcIiVzXCIsIE5ldHdvcmtPcHRpb25zID09IFwiJXNcIilcbiIsIEJpbmRpbmcsIAogICBkZWJ1Z3N0cl93KE5ldHdvcmtBZGRyKSwgZGVidWdzdHJfdyhFbmRwb2ludCksIGRlYnVnc3RyX3coTmV0d29ya09wdGlvbnMpKTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+TmV0d29ya0FkZHIpOwogIEJpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cFd0b0EoTmV0d29ya0FkZHIpOwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBpZiAoRW5kcG9pbnQpIHsKICAgIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cFd0b0EoRW5kcG9pbnQpOwogIH0gZWxzZSB7CiAgICBCaW5kaW5nLT5FbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKCIiKTsKICB9CiAgaWYgKCFCaW5kaW5nLT5FbmRwb2ludCkgRVJSKCJvdXQgb2YgbWVtb3J5P1xuIik7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfUmVzb2x2ZUJpbmRpbmcoUnBjQmluZGluZyogQmluZGluZywgTFBTVFIgRW5kcG9pbnQpCnsKICBUUkFDRSgiKFJwY0JpbmRpbmcgPT0gXiVwLCBFbmRQb2ludCA9PSBcIiVzXCJcbiIsIEJpbmRpbmcsIEVuZHBvaW50KTsKCiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+RW5kcG9pbnQpOwogIEJpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoUnBjQmluZGluZyogQmluZGluZywgVVVJRCogT2JqZWN0VXVpZCkKewogIFRSQUNFKCIoKlJwY0JpbmRpbmcgPT0gXiVwLCBVVUlEID09ICVzKVxuIiwgQmluZGluZywgZGVidWdzdHJfZ3VpZChPYmplY3RVdWlkKSk7IAogIGlmIChPYmplY3RVdWlkKSBtZW1jcHkoJkJpbmRpbmctPk9iamVjdFV1aWQsIE9iamVjdFV1aWQsIHNpemVvZihVVUlEKSk7CiAgZWxzZSBVdWlkQ3JlYXRlTmlsKCZCaW5kaW5nLT5PYmplY3RVdWlkKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X01ha2VCaW5kaW5nKFJwY0JpbmRpbmcqKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgUnBjQmluZGluZyogTmV3QmluZGluZzsKICBUUkFDRSgiKCpScGNCaW5kaW5nID09IF4lcCwgQ29ubmVjdGlvbiA9PSBeJXApXG4iLCAqQmluZGluZywgQ29ubmVjdGlvbik7CgogIFJQQ1JUNF9BbGxvY0JpbmRpbmcoJk5ld0JpbmRpbmcsIENvbm5lY3Rpb24tPnNlcnZlcik7CiAgTmV3QmluZGluZy0+UHJvdHNlcSA9IFJQQ1JUNF9zdHJkdXBBKENvbm5lY3Rpb24tPlByb3RzZXEpOwogIE5ld0JpbmRpbmctPk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cEEoQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIpOwogIE5ld0JpbmRpbmctPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIE5ld0JpbmRpbmctPkZyb21Db25uID0gQ29ubmVjdGlvbjsKCiAgVFJBQ0UoImJpbmRpbmc6ICVwXG4iLCBOZXdCaW5kaW5nKTsKICAqQmluZGluZyA9IE5ld0JpbmRpbmc7CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfRXhwb3J0QmluZGluZyhScGNCaW5kaW5nKiogQmluZGluZywgUnBjQmluZGluZyogT2xkQmluZGluZykKewogIEludGVybG9ja2VkSW5jcmVtZW50KCZPbGRCaW5kaW5nLT5yZWZzKTsKICAqQmluZGluZyA9IE9sZEJpbmRpbmc7CiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9EZXN0cm95QmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nKQp7CiAgaWYgKEludGVybG9ja2VkRGVjcmVtZW50KCZCaW5kaW5nLT5yZWZzKSkKICAgIHJldHVybiBSUENfU19PSzsKCiAgVFJBQ0UoImJpbmRpbmc6ICVwXG4iLCBCaW5kaW5nKTsKICAvKiBGSVhNRTogcmVsZWFzZSBjb25uZWN0aW9ucyAqLwogIFJQQ1JUNF9zdHJmcmVlKEJpbmRpbmctPkVuZHBvaW50KTsKICBSUENSVDRfc3RyZnJlZShCaW5kaW5nLT5OZXR3b3JrQWRkcik7CiAgUlBDUlQ0X3N0cmZyZWUoQmluZGluZy0+UHJvdHNlcSk7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgQmluZGluZyk7CiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9PcGVuQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiogQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb24qIE5ld0Nvbm5lY3Rpb247CiAgVFJBQ0UoIihCaW5kaW5nID09IF4lcClcbiIsIEJpbmRpbmcpOwogIGlmIChCaW5kaW5nLT5Gcm9tQ29ubikgewogICAgKkNvbm5lY3Rpb24gPSBCaW5kaW5nLT5Gcm9tQ29ubjsKICAgIHJldHVybiBSUENfU19PSzsKICB9CgogIFJQQ1JUNF9HZXRDb25uZWN0aW9uKCZOZXdDb25uZWN0aW9uLCBCaW5kaW5nLT5zZXJ2ZXIsIEJpbmRpbmctPlByb3RzZXEsIEJpbmRpbmctPk5ldHdvcmtBZGRyLCBCaW5kaW5nLT5FbmRwb2ludCwgTlVMTCwgQmluZGluZyk7CiAgKkNvbm5lY3Rpb24gPSBOZXdDb25uZWN0aW9uOwogIHJldHVybiBSUENSVDRfT3BlbkNvbm5lY3Rpb24oTmV3Q29ubmVjdGlvbik7Cn0KClJQQ19TVEFUVVMgUlBDUlQ0X0Nsb3NlQmluZGluZyhScGNCaW5kaW5nKiBCaW5kaW5nLCBScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoIihCaW5kaW5nID09IF4lcClcbiIsIEJpbmRpbmcpOwogIGlmICghQ29ubmVjdGlvbikgcmV0dXJuIFJQQ19TX09LOwogIGlmIChCaW5kaW5nLT5Gcm9tQ29ubiA9PSBDb25uZWN0aW9uKSByZXR1cm4gUlBDX1NfT0s7CiAgcmV0dXJuIFJQQ1JUNF9SZWxlYXNlQ29ubmVjdGlvbihDb25uZWN0aW9uKTsKfQoKLyogdXRpbGl0eSBmdW5jdGlvbnMgZm9yIHN0cmluZyBjb21wb3NpbmcgYW5kIHBhcnNpbmcgKi8Kc3RhdGljIHVuc2lnbmVkIFJQQ1JUNF9zdHJjb3B5QShMUFNUUiBkYXRhLCBMUENTVFIgc3JjKQp7CiAgdW5zaWduZWQgbGVuID0gc3RybGVuKHNyYyk7CiAgbWVtY3B5KGRhdGEsIHNyYywgbGVuKnNpemVvZihDSEFSKSk7CiAgcmV0dXJuIGxlbjsKfQoKc3RhdGljIHVuc2lnbmVkIFJQQ1JUNF9zdHJjb3B5VyhMUFdTVFIgZGF0YSwgTFBDV1NUUiBzcmMpCnsKICB1bnNpZ25lZCBsZW4gPSBzdHJsZW5XKHNyYyk7CiAgbWVtY3B5KGRhdGEsIHNyYywgbGVuKnNpemVvZihXQ0hBUikpOwogIHJldHVybiBsZW47Cn0KCnN0YXRpYyBMUFNUUiBSUENSVDRfc3RyY29uY2F0QShMUFNUUiBkc3QsIExQQ1NUUiBzcmMpCnsKICBEV09SRCBsZW4gPSBzdHJsZW4oZHN0KSwgc2xlbiA9IHN0cmxlbihzcmMpOwogIExQU1RSIG5kc3QgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QsIChsZW4rc2xlbisyKSpzaXplb2YoQ0hBUikpOwogIGlmICghbmRzdCkKICB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCBzbGVuKzEpOwogIHJldHVybiBuZHN0Owp9CgpzdGF0aWMgTFBXU1RSIFJQQ1JUNF9zdHJjb25jYXRXKExQV1NUUiBkc3QsIExQQ1dTVFIgc3JjKQp7CiAgRFdPUkQgbGVuID0gc3RybGVuVyhkc3QpLCBzbGVuID0gc3RybGVuVyhzcmMpOwogIExQV1NUUiBuZHN0ID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZHN0LCAobGVuK3NsZW4rMikqc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKCFuZHN0KSAKICB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBkc3QpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIG5kc3RbbGVuXSA9ICcsJzsKICBtZW1jcHkobmRzdCtsZW4rMSwgc3JjLCAoc2xlbisxKSpzaXplb2YoV0NIQVIpKTsKICByZXR1cm4gbmRzdDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZUEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBKCBMUFNUUiBPYmpVdWlkLCBMUFNUUiBQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgTmV0d29ya0FkZHIsIExQU1RSIEVuZHBvaW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgT3B0aW9ucywgTFBTVFIqIFN0cmluZ0JpbmRpbmcgKQp7CiAgRFdPUkQgbGVuID0gMTsKICBMUFNUUiBkYXRhOwoKICBUUkFDRSggIiglcywlcywlcywlcywlcywlcClcbiIsCiAgICAgICAgZGVidWdzdHJfYSggT2JqVXVpZCApLCBkZWJ1Z3N0cl9hKCBQcm90c2VxICksCiAgICAgICAgZGVidWdzdHJfYSggTmV0d29ya0FkZHIgKSwgZGVidWdzdHJfYSggRW5kcG9pbnQgKSwKICAgICAgICBkZWJ1Z3N0cl9hKCBPcHRpb25zICksIFN0cmluZ0JpbmRpbmcgKTsKCiAgaWYgKE9ialV1aWQgJiYgKk9ialV1aWQpIGxlbiArPSBzdHJsZW4oT2JqVXVpZCkgKyAxOwogIGlmIChQcm90c2VxICYmICpQcm90c2VxKSBsZW4gKz0gc3RybGVuKFByb3RzZXEpICsgMTsKICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKSBsZW4gKz0gc3RybGVuKE5ldHdvcmtBZGRyKTsKICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSBsZW4gKz0gc3RybGVuKEVuZHBvaW50KSArIDI7CiAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIGxlbiArPSBzdHJsZW4oT3B0aW9ucykgKyAyOwoKICBkYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbik7CiAgKlN0cmluZ0JpbmRpbmcgPSBkYXRhOwoKICBpZiAoT2JqVXVpZCAmJiAqT2JqVXVpZCkgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgT2JqVXVpZCk7CiAgICAqZGF0YSsrID0gJ0AnOwogIH0KICBpZiAoUHJvdHNlcSAmJiAqUHJvdHNlcSkgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgUHJvdHNlcSk7CiAgICAqZGF0YSsrID0gJzonOwogIH0KICBpZiAoTmV0d29ya0FkZHIgJiYgKk5ldHdvcmtBZGRyKQogICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgTmV0d29ya0FkZHIpOwoKICBpZiAoKEVuZHBvaW50ICYmICpFbmRwb2ludCkgfHwKICAgICAgKE9wdGlvbnMgJiYgKk9wdGlvbnMpKSB7CiAgICAqZGF0YSsrID0gJ1snOwogICAgaWYgKEVuZHBvaW50ICYmICpFbmRwb2ludCkgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5QShkYXRhLCBFbmRwb2ludCk7CiAgICAgIGlmIChPcHRpb25zICYmICpPcHRpb25zKSAqZGF0YSsrID0gJywnOwogICAgfQogICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weUEoZGF0YSwgT3B0aW9ucyk7CiAgICB9CiAgICAqZGF0YSsrID0gJ10nOwogIH0KICAqZGF0YSA9IDA7CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY1N0cmluZ0JpbmRpbmdDb21wb3NlVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNTdHJpbmdCaW5kaW5nQ29tcG9zZVcoIExQV1NUUiBPYmpVdWlkLCBMUFdTVFIgUHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgTmV0d29ya0FkZHIsIExQV1NUUiBFbmRwb2ludCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgT3B0aW9ucywgTFBXU1RSKiBTdHJpbmdCaW5kaW5nICkKewogIERXT1JEIGxlbiA9IDE7CiAgTFBXU1RSIGRhdGE7CgogIFRSQUNFKCIoJXMsJXMsJXMsJXMsJXMsJXApXG4iLAogICAgICAgZGVidWdzdHJfdyggT2JqVXVpZCApLCBkZWJ1Z3N0cl93KCBQcm90c2VxICksCiAgICAgICBkZWJ1Z3N0cl93KCBOZXR3b3JrQWRkciApLCBkZWJ1Z3N0cl93KCBFbmRwb2ludCApLAogICAgICAgZGVidWdzdHJfdyggT3B0aW9ucyApLCBTdHJpbmdCaW5kaW5nKTsKCiAgaWYgKE9ialV1aWQgJiYgKk9ialV1aWQpIGxlbiArPSBzdHJsZW5XKE9ialV1aWQpICsgMTsKICBpZiAoUHJvdHNlcSAmJiAqUHJvdHNlcSkgbGVuICs9IHN0cmxlblcoUHJvdHNlcSkgKyAxOwogIGlmIChOZXR3b3JrQWRkciAmJiAqTmV0d29ya0FkZHIpIGxlbiArPSBzdHJsZW5XKE5ldHdvcmtBZGRyKTsKICBpZiAoRW5kcG9pbnQgJiYgKkVuZHBvaW50KSBsZW4gKz0gc3RybGVuVyhFbmRwb2ludCkgKyAyOwogIGlmIChPcHRpb25zICYmICpPcHRpb25zKSBsZW4gKz0gc3RybGVuVyhPcHRpb25zKSArIDI7CgogIGRhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuKnNpemVvZihXQ0hBUikpOwogICpTdHJpbmdCaW5kaW5nID0gZGF0YTsKCiAgaWYgKE9ialV1aWQgJiYgKk9ialV1aWQpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIE9ialV1aWQpOwogICAgKmRhdGErKyA9ICdAJzsKICB9CiAgaWYgKFByb3RzZXEgJiYgKlByb3RzZXEpIHsKICAgIGRhdGEgKz0gUlBDUlQ0X3N0cmNvcHlXKGRhdGEsIFByb3RzZXEpOwogICAgKmRhdGErKyA9ICc6JzsKICB9CiAgaWYgKE5ldHdvcmtBZGRyICYmICpOZXR3b3JrQWRkcikgewogICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgTmV0d29ya0FkZHIpOwogIH0KICBpZiAoKEVuZHBvaW50ICYmICpFbmRwb2ludCkgfHwKICAgICAgKE9wdGlvbnMgJiYgKk9wdGlvbnMpKSB7CiAgICAqZGF0YSsrID0gJ1snOwogICAgaWYgKEVuZHBvaW50ICYmICpFbmRwb2ludCkgewogICAgICBkYXRhICs9IFJQQ1JUNF9zdHJjb3B5VyhkYXRhLCBFbmRwb2ludCk7CiAgICAgIGlmIChPcHRpb25zICYmICpPcHRpb25zKSAqZGF0YSsrID0gJywnOwogICAgfQogICAgaWYgKE9wdGlvbnMgJiYgKk9wdGlvbnMpIHsKICAgICAgZGF0YSArPSBSUENSVDRfc3RyY29weVcoZGF0YSwgT3B0aW9ucyk7CiAgICB9CiAgICAqZGF0YSsrID0gJ10nOwogIH0KICAqZGF0YSA9IDA7CgogIHJldHVybiBSUENfU19PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nUGFyc2VBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1N0cmluZ0JpbmRpbmdQYXJzZUEoIExQU1RSIFN0cmluZ0JpbmRpbmcsIExQU1RSICpPYmpVdWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiAqUHJvdHNlcSwgTFBTVFIgKk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiAqRW5kcG9pbnQsIExQU1RSICpPcHRpb25zKQp7CiAgQ0hBUiAqZGF0YSwgKm5leHQ7CiAgc3RhdGljIGNvbnN0IGNoYXIgZXBfb3B0W10gPSAiZW5kcG9pbnQ9IjsKCiAgVFJBQ0UoIiglcywlcCwlcCwlcCwlcCwlcClcbiIsIGRlYnVnc3RyX2EoU3RyaW5nQmluZGluZyksCiAgICAgICBPYmpVdWlkLCBQcm90c2VxLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnMpOwoKICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSBOVUxMOwogIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9IE5VTEw7CiAgaWYgKE5ldHdvcmtBZGRyKSAqTmV0d29ya0FkZHIgPSBOVUxMOwogIGlmIChFbmRwb2ludCkgKkVuZHBvaW50ID0gTlVMTDsKICBpZiAoT3B0aW9ucykgKk9wdGlvbnMgPSBOVUxMOwoKICBkYXRhID0gU3RyaW5nQmluZGluZzsKCiAgbmV4dCA9IHN0cmNocihkYXRhLCAnQCcpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSBSUENSVDRfc3RybmR1cEEoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHIoZGF0YSwgJzonKTsKICBpZiAobmV4dCkgewogICAgaWYgKFByb3RzZXEpICpQcm90c2VxID0gUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgfQoKICBuZXh0ID0gc3RyY2hyKGRhdGEsICdbJyk7CiAgaWYgKG5leHQpIHsKICAgIENIQVIgKmNsb3NlLCAqb3B0OwoKICAgIGlmIChOZXR3b3JrQWRkcikgKk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgICBjbG9zZSA9IHN0cmNocihkYXRhLCAnXScpOwogICAgaWYgKCFjbG9zZSkgZ290byBmYWlsOwoKICAgIC8qIHRva2VuaXplIG9wdGlvbnMgKi8KICAgIHdoaWxlIChkYXRhIDwgY2xvc2UpIHsKICAgICAgbmV4dCA9IHN0cmNocihkYXRhLCAnLCcpOwogICAgICBpZiAoIW5leHQgfHwgbmV4dCA+IGNsb3NlKSBuZXh0ID0gY2xvc2U7CiAgICAgIC8qIEZJWE1FOiB0aGlzIGlzIGtpbmQgb2YgaW5lZmZpY2llbnQgKi8KICAgICAgb3B0ID0gUlBDUlQ0X3N0cm5kdXBBKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgICAgZGF0YSA9IG5leHQrMTsKCiAgICAgIC8qIHBhcnNlIG9wdGlvbiAqLwogICAgICBuZXh0ID0gc3RyY2hyKG9wdCwgJz0nKTsKICAgICAgaWYgKCFuZXh0KSB7CiAgICAgICAgLyogbm90IGFuIG9wdGlvbiwgbXVzdCBiZSBhbiBlbmRwb2ludCAqLwogICAgICAgIGlmICgqRW5kcG9pbnQpIGdvdG8gZmFpbDsKICAgICAgICAqRW5kcG9pbnQgPSBvcHQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKHN0cm5jbXAob3B0LCBlcF9vcHQsIHN0cmxlbihlcF9vcHQpKSA9PSAwKSB7CiAgICAgICAgICAvKiBlbmRwb2ludCBvcHRpb24gKi8KICAgICAgICAgIGlmICgqRW5kcG9pbnQpIGdvdG8gZmFpbDsKICAgICAgICAgICpFbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBBKG5leHQrMSk7CiAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvKiBuZXR3b3JrIG9wdGlvbiAqLwogICAgICAgICAgaWYgKCpPcHRpb25zKSB7CiAgICAgICAgICAgIC8qIEZJWE1FOiB0aGlzIGlzIGtpbmQgb2YgaW5lZmZpY2llbnQgKi8KICAgICAgICAgICAgKk9wdGlvbnMgPSBSUENSVDRfc3RyY29uY2F0QSgqT3B0aW9ucywgb3B0KTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3B0KTsKICAgICAgICAgIH0gZWxzZSAKCSAgICAqT3B0aW9ucyA9IG9wdDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBkYXRhID0gY2xvc2UrMTsKICAgIGlmICgqZGF0YSkgZ290byBmYWlsOwogIH0KICBlbHNlIGlmIChOZXR3b3JrQWRkcikgCiAgICAqTmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwQShkYXRhKTsKCiAgcmV0dXJuIFJQQ19TX09LOwoKZmFpbDoKICBpZiAoT2JqVXVpZCkgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilPYmpVdWlkKTsKICBpZiAoUHJvdHNlcSkgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilQcm90c2VxKTsKICBpZiAoTmV0d29ya0FkZHIpIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopTmV0d29ya0FkZHIpOwogIGlmIChFbmRwb2ludCkgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKilFbmRwb2ludCk7CiAgaWYgKE9wdGlvbnMpIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopT3B0aW9ucyk7CiAgcmV0dXJuIFJQQ19TX0lOVkFMSURfU1RSSU5HX0JJTkRJTkc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNTdHJpbmdCaW5kaW5nUGFyc2VXIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcoIExQV1NUUiBTdHJpbmdCaW5kaW5nLCBMUFdTVFIgKk9ialV1aWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQV1NUUiAqUHJvdHNlcSwgTFBXU1RSICpOZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSICpFbmRwb2ludCwgTFBXU1RSICpPcHRpb25zKQp7CiAgV0NIQVIgKmRhdGEsICpuZXh0OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBlcF9vcHRbXSA9IHsnZScsJ24nLCdkJywncCcsJ28nLCdpJywnbicsJ3QnLCc9JywwfTsKCiAgVFJBQ0UoIiglcywlcCwlcCwlcCwlcCwlcClcbiIsIGRlYnVnc3RyX3coU3RyaW5nQmluZGluZyksCiAgICAgICBPYmpVdWlkLCBQcm90c2VxLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnMpOwoKICBpZiAoT2JqVXVpZCkgKk9ialV1aWQgPSBOVUxMOwogIGlmIChQcm90c2VxKSAqUHJvdHNlcSA9IE5VTEw7CiAgaWYgKE5ldHdvcmtBZGRyKSAqTmV0d29ya0FkZHIgPSBOVUxMOwogIGlmIChFbmRwb2ludCkgKkVuZHBvaW50ID0gTlVMTDsKICBpZiAoT3B0aW9ucykgKk9wdGlvbnMgPSBOVUxMOwoKICBkYXRhID0gU3RyaW5nQmluZGluZzsKCiAgbmV4dCA9IHN0cmNoclcoZGF0YSwgJ0AnKTsKICBpZiAobmV4dCkgewogICAgaWYgKE9ialV1aWQpICpPYmpVdWlkID0gUlBDUlQ0X3N0cm5kdXBXKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgIGRhdGEgPSBuZXh0KzE7CiAgfQoKICBuZXh0ID0gc3RyY2hyVyhkYXRhLCAnOicpOwogIGlmIChuZXh0KSB7CiAgICBpZiAoUHJvdHNlcSkgKlByb3RzZXEgPSBSUENSVDRfc3RybmR1cFcoZGF0YSwgbmV4dCAtIGRhdGEpOwogICAgZGF0YSA9IG5leHQrMTsKICB9CgogIG5leHQgPSBzdHJjaHJXKGRhdGEsICdbJyk7CiAgaWYgKG5leHQpIHsKICAgIFdDSEFSICpjbG9zZSwgKm9wdDsKCiAgICBpZiAoTmV0d29ya0FkZHIpICpOZXR3b3JrQWRkciA9IFJQQ1JUNF9zdHJuZHVwVyhkYXRhLCBuZXh0IC0gZGF0YSk7CiAgICBkYXRhID0gbmV4dCsxOwogICAgY2xvc2UgPSBzdHJjaHJXKGRhdGEsICddJyk7CiAgICBpZiAoIWNsb3NlKSBnb3RvIGZhaWw7CgogICAgLyogdG9rZW5pemUgb3B0aW9ucyAqLwogICAgd2hpbGUgKGRhdGEgPCBjbG9zZSkgewogICAgICBuZXh0ID0gc3RyY2hyVyhkYXRhLCAnLCcpOwogICAgICBpZiAoIW5leHQgfHwgbmV4dCA+IGNsb3NlKSBuZXh0ID0gY2xvc2U7CiAgICAgIC8qIEZJWE1FOiB0aGlzIGlzIGtpbmQgb2YgaW5lZmZpY2llbnQgKi8KICAgICAgb3B0ID0gUlBDUlQ0X3N0cm5kdXBXKGRhdGEsIG5leHQgLSBkYXRhKTsKICAgICAgZGF0YSA9IG5leHQrMTsKCiAgICAgIC8qIHBhcnNlIG9wdGlvbiAqLwogICAgICBuZXh0ID0gc3RyY2hyVyhvcHQsICc9Jyk7CiAgICAgIGlmICghbmV4dCkgewogICAgICAgIC8qIG5vdCBhbiBvcHRpb24sIG11c3QgYmUgYW4gZW5kcG9pbnQgKi8KICAgICAgICBpZiAoKkVuZHBvaW50KSBnb3RvIGZhaWw7CiAgICAgICAgKkVuZHBvaW50ID0gb3B0OwogICAgICB9IGVsc2UgewogICAgICAgIGlmIChzdHJuY21wVyhvcHQsIGVwX29wdCwgc3RybGVuVyhlcF9vcHQpKSA9PSAwKSB7CiAgICAgICAgICAvKiBlbmRwb2ludCBvcHRpb24gKi8KICAgICAgICAgIGlmICgqRW5kcG9pbnQpIGdvdG8gZmFpbDsKICAgICAgICAgICpFbmRwb2ludCA9IFJQQ1JUNF9zdHJkdXBXKG5leHQrMSk7CiAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvcHQpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvKiBuZXR3b3JrIG9wdGlvbiAqLwogICAgICAgICAgaWYgKCpPcHRpb25zKSB7CiAgICAgICAgICAgIC8qIEZJWE1FOiB0aGlzIGlzIGtpbmQgb2YgaW5lZmZpY2llbnQgKi8KICAgICAgICAgICAgKk9wdGlvbnMgPSBSUENSVDRfc3RyY29uY2F0VygqT3B0aW9ucywgb3B0KTsKICAgICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3B0KTsKICAgICAgICAgIH0gZWxzZSAKCSAgICAqT3B0aW9ucyA9IG9wdDsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCiAgICBkYXRhID0gY2xvc2UrMTsKICAgIGlmICgqZGF0YSkgZ290byBmYWlsOwogIH0gZWxzZSBpZiAoTmV0d29ya0FkZHIpIAogICAgKk5ldHdvcmtBZGRyID0gUlBDUlQ0X3N0cmR1cFcoZGF0YSk7CgogIHJldHVybiBSUENfU19PSzsKCmZhaWw6CiAgaWYgKE9ialV1aWQpIFJwY1N0cmluZ0ZyZWVXKE9ialV1aWQpOwogIGlmIChQcm90c2VxKSBScGNTdHJpbmdGcmVlVyhQcm90c2VxKTsKICBpZiAoTmV0d29ya0FkZHIpIFJwY1N0cmluZ0ZyZWVXKE5ldHdvcmtBZGRyKTsKICBpZiAoRW5kcG9pbnQpIFJwY1N0cmluZ0ZyZWVXKEVuZHBvaW50KTsKICBpZiAoT3B0aW9ucykgUnBjU3RyaW5nRnJlZVcoT3B0aW9ucyk7CiAgcmV0dXJuIFJQQ19TX0lOVkFMSURfU1RSSU5HX0JJTkRJTkc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nRnJlZSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nRnJlZSggUlBDX0JJTkRJTkdfSEFORExFKiBCaW5kaW5nICkKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIFRSQUNFKCIoJXApID0gJXBcbiIsIEJpbmRpbmcsICpCaW5kaW5nKTsKICBzdGF0dXMgPSBSUENSVDRfRGVzdHJveUJpbmRpbmcoKkJpbmRpbmcpOwogIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spICpCaW5kaW5nID0gMDsKICByZXR1cm4gc3RhdHVzOwp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nVmVjdG9yRnJlZSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nVmVjdG9yRnJlZSggUlBDX0JJTkRJTkdfVkVDVE9SKiogQmluZGluZ1ZlY3RvciApCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICB1bnNpZ25lZCBsb25nIGM7CgogIFRSQUNFKCIoJXApXG4iLCBCaW5kaW5nVmVjdG9yKTsKICBmb3IgKGM9MDsgYzwoKkJpbmRpbmdWZWN0b3IpLT5Db3VudDsgYysrKSB7CiAgICBzdGF0dXMgPSBScGNCaW5kaW5nRnJlZSgmKCpCaW5kaW5nVmVjdG9yKS0+QmluZGluZ0hbY10pOwogIH0KICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCAqQmluZGluZ1ZlY3Rvcik7CiAgKkJpbmRpbmdWZWN0b3IgPSBOVUxMOwogIHJldHVybiBSUENfU19PSzsKfQogIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0lucU9iamVjdCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nSW5xT2JqZWN0KCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgVVVJRCogT2JqZWN0VXVpZCApCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKUJpbmRpbmc7CgogIFRSQUNFKCIoJXAsJXApID0gJXNcbiIsIEJpbmRpbmcsIE9iamVjdFV1aWQsIGRlYnVnc3RyX2d1aWQoJmJpbmQtPk9iamVjdFV1aWQpKTsKICBtZW1jcHkoT2JqZWN0VXVpZCwgJmJpbmQtPk9iamVjdFV1aWQsIHNpemVvZihVVUlEKSk7CiAgcmV0dXJuIFJQQ19TX09LOwp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nU2V0T2JqZWN0IChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdTZXRPYmplY3QoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBVVUlEKiBPYmplY3RVdWlkICkKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoIiglcCwlcylcbiIsIEJpbmRpbmcsIGRlYnVnc3RyX2d1aWQoT2JqZWN0VXVpZCkpOwogIGlmIChiaW5kLT5zZXJ2ZXIpIHJldHVybiBSUENfU19XUk9OR19LSU5EX09GX0JJTkRJTkc7CiAgcmV0dXJuIFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KEJpbmRpbmcsIE9iamVjdFV1aWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nQSAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdBKCBMUFNUUiBTdHJpbmdCaW5kaW5nLCBSUENfQklORElOR19IQU5ETEUqIEJpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgUnBjQmluZGluZyogYmluZCA9IE5VTEw7CiAgTFBTVFIgT2JqZWN0VXVpZCwgUHJvdHNlcSwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zOwogIFVVSUQgVXVpZDsKCiAgVFJBQ0UoIiglcywlcClcbiIsIGRlYnVnc3RyX2EoU3RyaW5nQmluZGluZyksIEJpbmRpbmcpOwoKICByZXQgPSBScGNTdHJpbmdCaW5kaW5nUGFyc2VBKFN0cmluZ0JpbmRpbmcsICZPYmplY3RVdWlkLCAmUHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk5ldHdvcmtBZGRyLCAmRW5kcG9pbnQsICZPcHRpb25zKTsKICBpZiAocmV0ICE9IFJQQ19TX09LKSByZXR1cm4gcmV0OwoKICByZXQgPSBVdWlkRnJvbVN0cmluZ0EoT2JqZWN0VXVpZCwgJlV1aWQpOwoKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NyZWF0ZUJpbmRpbmdBKCZiaW5kLCBGQUxTRSwgUHJvdHNlcSk7CiAgaWYgKHJldCA9PSBSUENfU19PSykKICAgIHJldCA9IFJQQ1JUNF9TZXRCaW5kaW5nT2JqZWN0KGJpbmQsICZVdWlkKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X0NvbXBsZXRlQmluZGluZ0EoYmluZCwgTmV0d29ya0FkZHIsIEVuZHBvaW50LCBPcHRpb25zKTsKCiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmT3B0aW9ucyk7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmRW5kcG9pbnQpOwogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk5ldHdvcmtBZGRyKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZQcm90c2VxKTsKICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZPYmplY3RVdWlkKTsKCiAgaWYgKHJldCA9PSBSUENfU19PSykgCiAgICAqQmluZGluZyA9IChSUENfQklORElOR19IQU5ETEUpYmluZDsKICBlbHNlIAogICAgUlBDUlQ0X0Rlc3Ryb3lCaW5kaW5nKGJpbmQpOwoKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjQmluZGluZ0Zyb21TdHJpbmdCaW5kaW5nVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nRnJvbVN0cmluZ0JpbmRpbmdXKCBMUFdTVFIgU3RyaW5nQmluZGluZywgUlBDX0JJTkRJTkdfSEFORExFKiBCaW5kaW5nICkKewogIFJQQ19TVEFUVVMgcmV0OwogIFJwY0JpbmRpbmcqIGJpbmQgPSBOVUxMOwogIExQV1NUUiBPYmplY3RVdWlkLCBQcm90c2VxLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnM7CiAgVVVJRCBVdWlkOwoKICBUUkFDRSgiKCVzLCVwKVxuIiwgZGVidWdzdHJfdyhTdHJpbmdCaW5kaW5nKSwgQmluZGluZyk7CgogIHJldCA9IFJwY1N0cmluZ0JpbmRpbmdQYXJzZVcoU3RyaW5nQmluZGluZywgJk9iamVjdFV1aWQsICZQcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmV0d29ya0FkZHIsICZFbmRwb2ludCwgJk9wdGlvbnMpOwogIGlmIChyZXQgIT0gUlBDX1NfT0spIHJldHVybiByZXQ7CgogIHJldCA9IFV1aWRGcm9tU3RyaW5nVyhPYmplY3RVdWlkLCAmVXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ3JlYXRlQmluZGluZ1coJmJpbmQsIEZBTFNFLCBQcm90c2VxKTsKICBpZiAocmV0ID09IFJQQ19TX09LKQogICAgcmV0ID0gUlBDUlQ0X1NldEJpbmRpbmdPYmplY3QoYmluZCwgJlV1aWQpOwogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICByZXQgPSBSUENSVDRfQ29tcGxldGVCaW5kaW5nVyhiaW5kLCBOZXR3b3JrQWRkciwgRW5kcG9pbnQsIE9wdGlvbnMpOwoKICBScGNTdHJpbmdGcmVlVygmT3B0aW9ucyk7CiAgUnBjU3RyaW5nRnJlZVcoJkVuZHBvaW50KTsKICBScGNTdHJpbmdGcmVlVygmTmV0d29ya0FkZHIpOwogIFJwY1N0cmluZ0ZyZWVXKCZQcm90c2VxKTsKICBScGNTdHJpbmdGcmVlVygmT2JqZWN0VXVpZCk7CgogIGlmIChyZXQgPT0gUlBDX1NfT0spCiAgICAqQmluZGluZyA9IChSUENfQklORElOR19IQU5ETEUpYmluZDsKICBlbHNlCiAgICBSUENSVDRfRGVzdHJveUJpbmRpbmcoYmluZCk7CgogIHJldHVybiByZXQ7Cn0KICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdBIChSUENSVDQuQCkKICovClJQQ19TVEFUVVMgV0lOQVBJIFJwY0JpbmRpbmdUb1N0cmluZ0JpbmRpbmdBKCBSUENfQklORElOR19IQU5ETEUgQmluZGluZywgTFBTVFIqIFN0cmluZ0JpbmRpbmcgKQp7CiAgUlBDX1NUQVRVUyByZXQ7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilCaW5kaW5nOwogIExQU1RSIE9iamVjdFV1aWQ7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBTdHJpbmdCaW5kaW5nKTsKCiAgcmV0ID0gVXVpZFRvU3RyaW5nQSgmYmluZC0+T2JqZWN0VXVpZCwgKHVuc2lnbmVkIGNoYXIqKikmT2JqZWN0VXVpZCk7CiAgaWYgKHJldCAhPSBSUENfU19PSykgcmV0dXJuIHJldDsKCiAgcmV0ID0gUnBjU3RyaW5nQmluZGluZ0NvbXBvc2VBKE9iamVjdFV1aWQsIGJpbmQtPlByb3RzZXEsIGJpbmQtPk5ldHdvcmtBZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiaW5kLT5FbmRwb2ludCwgTlVMTCwgU3RyaW5nQmluZGluZyk7CgogIFJwY1N0cmluZ0ZyZWVBKCh1bnNpZ25lZCBjaGFyKiopJk9iamVjdFV1aWQpOwoKICByZXR1cm4gcmV0Owp9CiAgCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nVyAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nVyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIExQV1NUUiogU3RyaW5nQmluZGluZyApCnsKICBSUENfU1RBVFVTIHJldDsKICBMUFNUUiBzdHIgPSBOVUxMOwogIFRSQUNFKCIoJXAsJXApXG4iLCBCaW5kaW5nLCBTdHJpbmdCaW5kaW5nKTsKICByZXQgPSBScGNCaW5kaW5nVG9TdHJpbmdCaW5kaW5nQShCaW5kaW5nLCAmc3RyKTsKICAqU3RyaW5nQmluZGluZyA9IFJQQ1JUNF9zdHJkdXBBdG9XKHN0cik7CiAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmc3RyKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgSV9ScGNCaW5kaW5nU2V0QXN5bmMgKFJQQ1JUNC5AKQogKiBOT1RFUwogKiAgRXhpc3RzIGluIHdpbjl4IGFuZCB3aW5OVCwgYnV0IHdpdGggZGlmZmVyZW50IG51bWJlciBvZiBhcmd1bWVudHMKICogICg5eCB2ZXJzaW9uIGhhcyAzIGFyZ3VtZW50cywgTlQgaGFzIDIpLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNCaW5kaW5nU2V0QXN5bmMoIFJQQ19CSU5ESU5HX0hBTkRMRSBCaW5kaW5nLCBSUENfQkxPQ0tJTkdfRk4gQmxvY2tpbmdGbikKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoICIoJXAsJXApOiBzdHViXG4iLCBCaW5kaW5nLCBCbG9ja2luZ0ZuICk7CgogIGJpbmQtPkJsb2NraW5nRm4gPSBCbG9ja2luZ0ZuOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0K