LyoKICogT0xFMzIgY2FsbG91dHMsIENPTSBpbnRlcmZhY2UgbWFyc2hhbGxpbmcKICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqCiAqIFRPRE86CiAqICAtIGZpZ3VyZSBvdXQgd2hldGhlciB3ZSAqcmVhbGx5KiBnb3QgdGhpcyByaWdodAogKiAgLSBjaGVjayBmb3IgZXJyb3JzIGFuZCB0aHJvdyBleGNlcHRpb25zCiAqICAtIHdoYXQgYXJlIHRoZSBtYXJzaGFsbGluZyBmdW5jdGlvbnMgc3VwcG9zZWQgdG8gcmV0dXJuPwogKiAgLSBmaW5pc2ggUnBjU3RyZWFtX1Z0YmwKICovCgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KI2RlZmluZSBOT05BTUVMRVNTU1RSVUNUCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2lucmVnLmgiCgojaW5jbHVkZSAib2JqYmFzZS5oIgoKI2luY2x1ZGUgIm5kcl9taXNjLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKI2luY2x1ZGUgIndpbmUvcnBjZmMuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKc3RhdGljIEhNT0RVTEUgaE9MRTsKCnN0YXRpYyBIUkVTVUxUIChXSU5BUEkgKkNPTV9HZXRNYXJzaGFsU2l6ZU1heCkoVUxPTkcgKixSRUZJSUQsTFBVTktOT1dOLERXT1JELExQVk9JRCxEV09SRCk7CnN0YXRpYyBIUkVTVUxUIChXSU5BUEkgKkNPTV9NYXJzaGFsSW50ZXJmYWNlKShMUFNUUkVBTSxSRUZJSUQsTFBVTktOT1dOLERXT1JELExQVk9JRCxEV09SRCk7CnN0YXRpYyBIUkVTVUxUIChXSU5BUEkgKkNPTV9Vbm1hcnNoYWxJbnRlcmZhY2UpKExQU1RSRUFNLFJFRklJRCxMUFZPSUQqKTsKc3RhdGljIEhSRVNVTFQgKFdJTkFQSSAqQ09NX1JlbGVhc2VNYXJzaGFsRGF0YSkoTFBTVFJFQU0pOwpzdGF0aWMgSFJFU1VMVCAoV0lOQVBJICpDT01fR2V0Q2xhc3NPYmplY3QpKFJFRkNMU0lELERXT1JELENPU0VSVkVSSU5GTyAqLFJFRklJRCxMUFZPSUQgKik7CnN0YXRpYyBIUkVTVUxUIChXSU5BUEkgKkNPTV9HZXRQU0Nsc2lkKShSRUZJSUQsQ0xTSUQgKik7CnN0YXRpYyBMUFZPSUQgKFdJTkFQSSAqQ09NX01lbUFsbG9jKShVTE9ORyk7CnN0YXRpYyB2b2lkIChXSU5BUEkgKkNPTV9NZW1GcmVlKShMUFZPSUQpOwoKc3RhdGljIEhNT0RVTEUgTG9hZENPTSh2b2lkKQp7CiAgaWYgKGhPTEUpIHJldHVybiBoT0xFOwogIGhPTEUgPSBMb2FkTGlicmFyeUEoIk9MRTMyLkRMTCIpOwogIGlmICghaE9MRSkgcmV0dXJuIDA7CiAgQ09NX0dldE1hcnNoYWxTaXplTWF4ICA9IChMUFZPSUQpR2V0UHJvY0FkZHJlc3MoaE9MRSwgIkNvR2V0TWFyc2hhbFNpemVNYXgiKTsKICBDT01fTWFyc2hhbEludGVyZmFjZSAgID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29NYXJzaGFsSW50ZXJmYWNlIik7CiAgQ09NX1VubWFyc2hhbEludGVyZmFjZSA9IChMUFZPSUQpR2V0UHJvY0FkZHJlc3MoaE9MRSwgIkNvVW5tYXJzaGFsSW50ZXJmYWNlIik7CiAgQ09NX1JlbGVhc2VNYXJzaGFsRGF0YSA9IChMUFZPSUQpR2V0UHJvY0FkZHJlc3MoaE9MRSwgIkNvUmVsZWFzZU1hcnNoYWxEYXRhIik7CiAgQ09NX0dldENsYXNzT2JqZWN0ICAgICA9IChMUFZPSUQpR2V0UHJvY0FkZHJlc3MoaE9MRSwgIkNvR2V0Q2xhc3NPYmplY3QiKTsKICBDT01fR2V0UFNDbHNpZCAgICAgICAgID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29HZXRQU0Nsc2lkIik7CiAgQ09NX01lbUFsbG9jID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29UYXNrTWVtQWxsb2MiKTsKICBDT01fTWVtRnJlZSAgPSAoTFBWT0lEKUdldFByb2NBZGRyZXNzKGhPTEUsICJDb1Rhc2tNZW1GcmVlIik7CiAgcmV0dXJuIGhPTEU7Cn0KCi8qIENvTWFyc2hhbEludGVyZmFjZS9Db1VubWFyc2hhbEludGVyZmFjZSB3b3JrcyBvbiBzdHJlYW1zLAogKiBzbyBpbXBsZW1lbnQgYSBzaW1wbGUgc3RyZWFtIG9uIHRvcCBvZiB0aGUgUlBDIGJ1ZmZlcgogKiAod2hpY2ggYWxzbyBpbXBsZW1lbnRzIHRoZSBNSW50ZXJmYWNlUG9pbnRlciBzdHJ1Y3R1cmUpICovCnR5cGVkZWYgc3RydWN0IFJwY1N0cmVhbUltcGwKewogIGNvbnN0IElTdHJlYW1WdGJsICpscFZ0Ymw7CiAgRFdPUkQgUmVmQ291bnQ7CiAgUE1JRExfU1RVQl9NRVNTQUdFIHBNc2c7CiAgTFBEV09SRCBzaXplOwogIGNoYXIgKmRhdGE7CiAgRFdPUkQgcG9zOwp9IFJwY1N0cmVhbUltcGw7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjU3RyZWFtX1F1ZXJ5SW50ZXJmYWNlKExQU1RSRUFNIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKm9iaikKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lTZXF1ZW50aWFsU3RyZWFtLCByaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lTdHJlYW0sIHJpaWQpKSB7CiAgICAqb2JqID0gVGhpczsKICAgIFRoaXMtPlJlZkNvdW50Kys7CiAgICByZXR1cm4gU19PSzsKICB9CiAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUnBjU3RyZWFtX0FkZFJlZihMUFNUUkVBTSBpZmFjZSkKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogIHJldHVybiArKyhUaGlzLT5SZWZDb3VudCk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgUnBjU3RyZWFtX1JlbGVhc2UoTFBTVFJFQU0gaWZhY2UpCnsKICBScGNTdHJlYW1JbXBsICpUaGlzID0gKFJwY1N0cmVhbUltcGwgKilpZmFjZTsKICBpZiAoIS0tKFRoaXMtPlJlZkNvdW50KSkgewogICAgVFJBQ0UoInNpemU9JWxkXG4iLCAqVGhpcy0+c2l6ZSk7CiAgICBUaGlzLT5wTXNnLT5CdWZmZXIgPSAodW5zaWduZWQgY2hhciopVGhpcy0+ZGF0YSArICpUaGlzLT5zaXplOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiBUaGlzLT5SZWZDb3VudDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJwY1N0cmVhbV9SZWFkKExQU1RSRUFNIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpwdiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgY2IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HICpwY2JSZWFkKQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpcyA9IChScGNTdHJlYW1JbXBsICopaWZhY2U7CiAgSFJFU1VMVCBociA9IFNfT0s7CiAgaWYgKFRoaXMtPnBvcyArIGNiID4gKlRoaXMtPnNpemUpCiAgewogICAgY2IgPSAqVGhpcy0+c2l6ZSAtIFRoaXMtPnBvczsKICAgIGhyID0gU19GQUxTRTsKICB9CiAgaWYgKGNiKSB7CiAgICBtZW1jcHkocHYsIFRoaXMtPmRhdGEgKyBUaGlzLT5wb3MsIGNiKTsKICAgIFRoaXMtPnBvcyArPSBjYjsKICB9CiAgaWYgKHBjYlJlYWQpICpwY2JSZWFkID0gY2I7CiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgUnBjU3RyZWFtX1dyaXRlKExQU1RSRUFNIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqcHYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyBjYiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HICpwY2JXcml0dGVuKQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpcyA9IChScGNTdHJlYW1JbXBsICopaWZhY2U7CiAgaWYgKFRoaXMtPmRhdGEgKyBjYiA+IChjaGFyICopVGhpcy0+cE1zZy0+QnVmZmVyRW5kKQogICAgcmV0dXJuIFNUR19FX01FRElVTUZVTEw7CiAgbWVtY3B5KFRoaXMtPmRhdGEgKyBUaGlzLT5wb3MsIHB2LCBjYik7CiAgVGhpcy0+cG9zICs9IGNiOwogIGlmIChUaGlzLT5wb3MgPiAqVGhpcy0+c2l6ZSkgKlRoaXMtPnNpemUgPSBUaGlzLT5wb3M7CiAgaWYgKHBjYldyaXR0ZW4pICpwY2JXcml0dGVuID0gY2I7CiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNTdHJlYW1fU2VlayhMUFNUUkVBTSBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTEFSR0VfSU5URUdFUiBtb3ZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBvcmlnaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMQVJHRV9JTlRFR0VSICpuZXdQb3MpCnsKICBScGNTdHJlYW1JbXBsICpUaGlzID0gKFJwY1N0cmVhbUltcGwgKilpZmFjZTsKICBzd2l0Y2ggKG9yaWdpbikgewogIGNhc2UgU1RSRUFNX1NFRUtfU0VUOgogICAgVGhpcy0+cG9zID0gbW92ZS51Lkxvd1BhcnQ7CiAgICBicmVhazsKICBjYXNlIFNUUkVBTV9TRUVLX0NVUjoKICAgIFRoaXMtPnBvcyA9IFRoaXMtPnBvcyArIG1vdmUudS5Mb3dQYXJ0OwogICAgYnJlYWs7CiAgY2FzZSBTVFJFQU1fU0VFS19FTkQ6CiAgICBUaGlzLT5wb3MgPSAqVGhpcy0+c2l6ZSArIG1vdmUudS5Mb3dQYXJ0OwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIHJldHVybiBTVEdfRV9JTlZBTElERlVOQ1RJT047CiAgfQogIGlmIChuZXdQb3MpIHsKICAgIG5ld1Bvcy0+dS5Mb3dQYXJ0ID0gVGhpcy0+cG9zOwogICAgbmV3UG9zLT51LkhpZ2hQYXJ0ID0gMDsKICB9CiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNTdHJlYW1fU2V0U2l6ZShMUFNUUkVBTSBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxBUkdFX0lOVEVHRVIgbmV3U2l6ZSkKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogICpUaGlzLT5zaXplID0gbmV3U2l6ZS51Lkxvd1BhcnQ7CiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBjb25zdCBJU3RyZWFtVnRibCBScGNTdHJlYW1fVnRibCA9CnsKICBScGNTdHJlYW1fUXVlcnlJbnRlcmZhY2UsCiAgUnBjU3RyZWFtX0FkZFJlZiwKICBScGNTdHJlYW1fUmVsZWFzZSwKICBScGNTdHJlYW1fUmVhZCwKICBScGNTdHJlYW1fV3JpdGUsCiAgUnBjU3RyZWFtX1NlZWssCiAgUnBjU3RyZWFtX1NldFNpemUsCiAgTlVMTCwgLyogQ29weVRvICovCiAgTlVMTCwgLyogQ29tbWl0ICovCiAgTlVMTCwgLyogUmV2ZXJ0ICovCiAgTlVMTCwgLyogTG9ja1JlZ2lvbiAqLwogIE5VTEwsIC8qIFVubG9ja1JlZ2lvbiAqLwogIE5VTEwsIC8qIFN0YXQgKi8KICBOVUxMICAvKiBDbG9uZSAqLwp9OwoKc3RhdGljIExQU1RSRUFNIFJwY1N0cmVhbV9DcmVhdGUoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCBCT09MIGluaXQpCnsKICBScGNTdHJlYW1JbXBsICpUaGlzOwogIFRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihScGNTdHJlYW1JbXBsKSk7CiAgaWYgKCFUaGlzKSByZXR1cm4gTlVMTDsKICBUaGlzLT5scFZ0YmwgPSAmUnBjU3RyZWFtX1Z0Ymw7CiAgVGhpcy0+UmVmQ291bnQgPSAxOwogIFRoaXMtPnBNc2cgPSBwU3R1Yk1zZzsKICBUaGlzLT5zaXplID0gKExQRFdPUkQpcFN0dWJNc2ctPkJ1ZmZlcjsKICBUaGlzLT5kYXRhID0gKGNoYXIqKShUaGlzLT5zaXplICsgMSk7CiAgVGhpcy0+cG9zID0gMDsKICBpZiAoaW5pdCkgKlRoaXMtPnNpemUgPSAwOwogIFRSQUNFKCJpbml0IHNpemU9JWxkXG4iLCAqVGhpcy0+c2l6ZSk7CiAgcmV0dXJuIChMUFNUUkVBTSlUaGlzOwp9CgpzdGF0aWMgY29uc3QgSUlEKiBnZXRfaXBfaWlkKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogIGNvbnN0IElJRCAqcmlpZDsKICBpZiAoIXBGb3JtYXQpIHJldHVybiAmSUlEX0lVbmtub3duOwogIFRSQUNFKCJmb3JtYXQ9JTAyeCAlMDJ4XG4iLCBwRm9ybWF0WzBdLCBwRm9ybWF0WzFdKTsKICBpZiAocEZvcm1hdFswXSAhPSBSUENfRkNfSVApIEZJWE1FKCJmb3JtYXQ9JWRcbiIsIHBGb3JtYXRbMF0pOwogIGlmIChwRm9ybWF0WzFdID09IFJQQ19GQ19DT05TVEFOVF9JSUQpIHsKICAgIHJpaWQgPSAoY29uc3QgSUlEICopJnBGb3JtYXRbMl07CiAgfSBlbHNlIHsKICAgIENvbXB1dGVDb25mb3JtYW5jZShwU3R1Yk1zZywgcE1lbW9yeSwgcEZvcm1hdCsyLCAwKTsKICAgIHJpaWQgPSAoY29uc3QgSUlEICopcFN0dWJNc2ctPk1heENvdW50OwogIH0KICBpZiAoIXJpaWQpIHJpaWQgPSAmSUlEX0lVbmtub3duOwogIFRSQUNFKCJnb3QgJXNcbiIsIGRlYnVnc3RyX2d1aWQocmlpZCkpOwogIHJldHVybiByaWlkOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckludGVyZmFjZVBvaW50ZXJNYXJzaGFsbCBbUlBDUlQ0LkBdCiAqLwp1bnNpZ25lZCBjaGFyICogV0lOQVBJIE5kckludGVyZmFjZVBvaW50ZXJNYXJzaGFsbChQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgY29uc3QgSUlEICpyaWlkID0gZ2V0X2lwX2lpZChwU3R1Yk1zZywgcE1lbW9yeSwgcEZvcm1hdCk7CiAgTFBTVFJFQU0gc3RyZWFtOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwU3R1Yk1zZywgcE1lbW9yeSwgcEZvcm1hdCk7CiAgcFN0dWJNc2ctPk1heENvdW50ID0gMDsKICBpZiAoIUxvYWRDT00oKSkgcmV0dXJuIE5VTEw7CiAgaWYgKHBTdHViTXNnLT5CdWZmZXIgKyBzaXplb2YoRFdPUkQpIDwgKHVuc2lnbmVkIGNoYXIgKilwU3R1Yk1zZy0+UnBjTXNnLT5CdWZmZXIgKyBwU3R1Yk1zZy0+QnVmZmVyTGVuZ3RoKSB7CiAgICBzdHJlYW0gPSBScGNTdHJlYW1fQ3JlYXRlKHBTdHViTXNnLCBUUlVFKTsKICAgIGlmIChzdHJlYW0pIHsKICAgICAgaHIgPSBDT01fTWFyc2hhbEludGVyZmFjZShzdHJlYW0sIHJpaWQsIChMUFVOS05PV04pcE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwU3R1Yk1zZy0+ZHdEZXN0Q29udGV4dCwgcFN0dWJNc2ctPnB2RGVzdENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTVNITEZMQUdTX05PUk1BTCk7CiAgICAgIElTdHJlYW1fUmVsZWFzZShzdHJlYW0pOwogICAgICBpZiAoRkFJTEVEKGhyKSkgewogICAgICAgIElVbmtub3duX1JlbGVhc2UoKExQVU5LTk9XTilwTWVtb3J5KTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihocik7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRySW50ZXJmYWNlUG9pbnRlclVubWFyc2hhbGwgW1JQQ1JUNC5AXQogKi8KdW5zaWduZWQgY2hhciAqIFdJTkFQSSBOZHJJbnRlcmZhY2VQb2ludGVyVW5tYXJzaGFsbChQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICoqcHBNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBmTXVzdEFsbG9jKQp7CiAgTFBTVFJFQU0gc3RyZWFtOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXAsJWQpXG4iLCBwU3R1Yk1zZywgcHBNZW1vcnksIHBGb3JtYXQsIGZNdXN0QWxsb2MpOwogIGlmICghTG9hZENPTSgpKSByZXR1cm4gTlVMTDsKICAqKExQVk9JRCopcHBNZW1vcnkgPSBOVUxMOwogIGlmIChwU3R1Yk1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKSA8ICh1bnNpZ25lZCBjaGFyICopcFN0dWJNc2ctPlJwY01zZy0+QnVmZmVyICsgcFN0dWJNc2ctPkJ1ZmZlckxlbmd0aCkgewogICAgc3RyZWFtID0gUnBjU3RyZWFtX0NyZWF0ZShwU3R1Yk1zZywgRkFMU0UpOwogICAgaWYgKHN0cmVhbSkgewogICAgICBociA9IENPTV9Vbm1hcnNoYWxJbnRlcmZhY2Uoc3RyZWFtLCAmSUlEX05VTEwsIChMUFZPSUQqKXBwTWVtb3J5KTsKICAgICAgSVN0cmVhbV9SZWxlYXNlKHN0cmVhbSk7CiAgICAgIGlmIChGQUlMRUQoaHIpKQogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKGhyKTsKICAgIH0KICB9CiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRySW50ZXJmYWNlUG9pbnRlckJ1ZmZlclNpemUgW1JQQ1JUNC5AXQogKi8Kdm9pZCBXSU5BUEkgTmRySW50ZXJmYWNlUG9pbnRlckJ1ZmZlclNpemUoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnBNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogIGNvbnN0IElJRCAqcmlpZCA9IGdldF9pcF9paWQocFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogIFVMT05HIHNpemUgPSAwOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwU3R1Yk1zZywgcE1lbW9yeSwgcEZvcm1hdCk7CiAgaWYgKCFMb2FkQ09NKCkpIHJldHVybjsKICBociA9IENPTV9HZXRNYXJzaGFsU2l6ZU1heCgmc2l6ZSwgcmlpZCwgKExQVU5LTk9XTilwTWVtb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcFN0dWJNc2ctPmR3RGVzdENvbnRleHQsIHBTdHViTXNnLT5wdkRlc3RDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTVNITEZMQUdTX05PUk1BTCk7CiAgVFJBQ0UoInNpemU9JWxkXG4iLCBzaXplKTsKICBwU3R1Yk1zZy0+QnVmZmVyTGVuZ3RoICs9IHNpemVvZihEV09SRCkgKyBzaXplOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckludGVyZmFjZVBvaW50ZXJNZW1vcnlTaXplIFtSUENSVDQuQF0KICovCnVuc2lnbmVkIGxvbmcgV0lOQVBJIE5kckludGVyZmFjZVBvaW50ZXJNZW1vcnlTaXplKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgRklYTUUoIiglcCwlcCk6IHN0dWJcbiIsIHBTdHViTXNnLCBwRm9ybWF0KTsKICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJJbnRlcmZhY2VQb2ludGVyRnJlZSBbUlBDUlQ0LkBdCiAqLwp2b2lkIFdJTkFQSSBOZHJJbnRlcmZhY2VQb2ludGVyRnJlZShQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgTFBVTktOT1dOIHBVbmsgPSAoTFBVTktOT1dOKXBNZW1vcnk7CiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICBpZiAocFVuaykgSVVua25vd25fUmVsZWFzZShwVW5rKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJPbGVBbGxvY2F0ZSBbUlBDUlQ0LkBdCiAqLwp2b2lkICogV0lOQVBJIE5kck9sZUFsbG9jYXRlKHNpemVfdCBTaXplKQp7CiAgaWYgKCFMb2FkQ09NKCkpIHJldHVybiBOVUxMOwogIHJldHVybiBDT01fTWVtQWxsb2MoU2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyT2xlRnJlZSBbUlBDUlQ0LkBdCiAqLwp2b2lkIFdJTkFQSSBOZHJPbGVGcmVlKHZvaWQgKk5vZGVUb0ZyZWUpCnsKICBpZiAoIUxvYWRDT00oKSkgcmV0dXJuOwogIENPTV9NZW1GcmVlKE5vZGVUb0ZyZWUpOwp9CgovKiBpbnRlcm5hbCAqLwpIUkVTVUxUIFJQQ1JUNF9HZXRQU0ZhY3RvcnkoUkVGSUlEIHJpaWQsIExQUFNGQUNUT1JZQlVGRkVSICpwUFMpCnsKICBIUkVTVUxUIGhyOwogIENMU0lEIGNsc2lkOwoKICBpZiAoIUxvYWRDT00oKSkgcmV0dXJuIFJQQ19FX1VORVhQRUNURUQ7CiAgaHIgPSBDT01fR2V0UFNDbHNpZChyaWlkLCAmY2xzaWQpOwogIGlmIChGQUlMRUQoaHIpKSByZXR1cm4gaHI7CiAgaHIgPSBDT01fR2V0Q2xhc3NPYmplY3QoJmNsc2lkLCBDTFNDVFhfSU5QUk9DX1NFUlZFUiwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAmSUlEX0lQU0ZhY3RvcnlCdWZmZXIsIChMUFZPSUQgKilwUFMpOwogIHJldHVybiBocjsKfQo=