LyoKICogT0xFMzIgY2FsbG91dHMsIENPTSBpbnRlcmZhY2UgbWFyc2hhbGxpbmcKICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqCiAqIFRPRE86CiAqICAtIGZpeCB0aGUgd2lyZS1wcm90b2NvbCB0byBtYXRjaCBNUy9SUEMKICogIC0gZmluaXNoIFJwY1N0cmVhbV9WdGJsCiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCiNkZWZpbmUgTk9OQU1FTEVTU1VOSU9OCiNkZWZpbmUgTk9OQU1FTEVTU1NUUlVDVAoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKCiNpbmNsdWRlICJvYmpiYXNlLmgiCgojaW5jbHVkZSAibmRyX21pc2MuaCIKI2luY2x1ZGUgInJwY25kci5oIgojaW5jbHVkZSAicnBjcHJveHkuaCIKI2luY2x1ZGUgIndpbmUvcnBjZmMuaCIKI2luY2x1ZGUgImNwc2YuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKc3RhdGljIEhNT0RVTEUgaE9MRTsKCnN0YXRpYyBIUkVTVUxUIChXSU5BUEkgKkNPTV9HZXRNYXJzaGFsU2l6ZU1heCkoVUxPTkcgKixSRUZJSUQsTFBVTktOT1dOLERXT1JELExQVk9JRCxEV09SRCk7CnN0YXRpYyBIUkVTVUxUIChXSU5BUEkgKkNPTV9NYXJzaGFsSW50ZXJmYWNlKShMUFNUUkVBTSxSRUZJSUQsTFBVTktOT1dOLERXT1JELExQVk9JRCxEV09SRCk7CnN0YXRpYyBIUkVTVUxUIChXSU5BUEkgKkNPTV9Vbm1hcnNoYWxJbnRlcmZhY2UpKExQU1RSRUFNLFJFRklJRCxMUFZPSUQqKTsKc3RhdGljIEhSRVNVTFQgKFdJTkFQSSAqQ09NX1JlbGVhc2VNYXJzaGFsRGF0YSkoTFBTVFJFQU0pOwpzdGF0aWMgSFJFU1VMVCAoV0lOQVBJICpDT01fR2V0Q2xhc3NPYmplY3QpKFJFRkNMU0lELERXT1JELENPU0VSVkVSSU5GTyAqLFJFRklJRCxMUFZPSUQgKik7CnN0YXRpYyBIUkVTVUxUIChXSU5BUEkgKkNPTV9HZXRQU0Nsc2lkKShSRUZJSUQsQ0xTSUQgKik7CnN0YXRpYyBMUFZPSUQgKFdJTkFQSSAqQ09NX01lbUFsbG9jKShVTE9ORyk7CnN0YXRpYyB2b2lkIChXSU5BUEkgKkNPTV9NZW1GcmVlKShMUFZPSUQpOwoKc3RhdGljIEhNT0RVTEUgTG9hZENPTSh2b2lkKQp7CiAgaWYgKGhPTEUpIHJldHVybiBoT0xFOwogIGhPTEUgPSBMb2FkTGlicmFyeUEoIk9MRTMyLkRMTCIpOwogIGlmICghaE9MRSkgcmV0dXJuIDA7CiAgQ09NX0dldE1hcnNoYWxTaXplTWF4ICA9IChMUFZPSUQpR2V0UHJvY0FkZHJlc3MoaE9MRSwgIkNvR2V0TWFyc2hhbFNpemVNYXgiKTsKICBDT01fTWFyc2hhbEludGVyZmFjZSAgID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29NYXJzaGFsSW50ZXJmYWNlIik7CiAgQ09NX1VubWFyc2hhbEludGVyZmFjZSA9IChMUFZPSUQpR2V0UHJvY0FkZHJlc3MoaE9MRSwgIkNvVW5tYXJzaGFsSW50ZXJmYWNlIik7CiAgQ09NX1JlbGVhc2VNYXJzaGFsRGF0YSA9IChMUFZPSUQpR2V0UHJvY0FkZHJlc3MoaE9MRSwgIkNvUmVsZWFzZU1hcnNoYWxEYXRhIik7CiAgQ09NX0dldENsYXNzT2JqZWN0ICAgICA9IChMUFZPSUQpR2V0UHJvY0FkZHJlc3MoaE9MRSwgIkNvR2V0Q2xhc3NPYmplY3QiKTsKICBDT01fR2V0UFNDbHNpZCAgICAgICAgID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29HZXRQU0Nsc2lkIik7CiAgQ09NX01lbUFsbG9jID0gKExQVk9JRClHZXRQcm9jQWRkcmVzcyhoT0xFLCAiQ29UYXNrTWVtQWxsb2MiKTsKICBDT01fTWVtRnJlZSAgPSAoTFBWT0lEKUdldFByb2NBZGRyZXNzKGhPTEUsICJDb1Rhc2tNZW1GcmVlIik7CiAgcmV0dXJuIGhPTEU7Cn0KCi8qIENvTWFyc2hhbEludGVyZmFjZS9Db1VubWFyc2hhbEludGVyZmFjZSB3b3JrcyBvbiBzdHJlYW1zLAogKiBzbyBpbXBsZW1lbnQgYSBzaW1wbGUgc3RyZWFtIG9uIHRvcCBvZiB0aGUgUlBDIGJ1ZmZlcgogKiAod2hpY2ggYWxzbyBpbXBsZW1lbnRzIHRoZSBNSW50ZXJmYWNlUG9pbnRlciBzdHJ1Y3R1cmUpICovCnR5cGVkZWYgc3RydWN0IFJwY1N0cmVhbUltcGwKewogIGNvbnN0IElTdHJlYW1WdGJsICpscFZ0Ymw7CiAgTE9ORyBSZWZDb3VudDsKICBQTUlETF9TVFVCX01FU1NBR0UgcE1zZzsKICBMUERXT1JEIHNpemU7CiAgdW5zaWduZWQgY2hhciAqZGF0YTsKICBEV09SRCBwb3M7Cn0gUnBjU3RyZWFtSW1wbDsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNTdHJlYW1fUXVlcnlJbnRlcmZhY2UoTFBTVFJFQU0gaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqb2JqKQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpcyA9IChScGNTdHJlYW1JbXBsICopaWZhY2U7CiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSVNlcXVlbnRpYWxTdHJlYW0sIHJpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSVN0cmVhbSwgcmlpZCkpIHsKICAgICpvYmogPSBUaGlzOwogICAgSW50ZXJsb2NrZWRJbmNyZW1lbnQoICZUaGlzLT5SZWZDb3VudCApOwogICAgcmV0dXJuIFNfT0s7CiAgfQogIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJwY1N0cmVhbV9BZGRSZWYoTFBTVFJFQU0gaWZhY2UpCnsKICBScGNTdHJlYW1JbXBsICpUaGlzID0gKFJwY1N0cmVhbUltcGwgKilpZmFjZTsKICByZXR1cm4gSW50ZXJsb2NrZWRJbmNyZW1lbnQoICZUaGlzLT5SZWZDb3VudCApOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIFJwY1N0cmVhbV9SZWxlYXNlKExQU1RSRUFNIGlmYWNlKQp7CiAgUnBjU3RyZWFtSW1wbCAqVGhpcyA9IChScGNTdHJlYW1JbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoICZUaGlzLT5SZWZDb3VudCApOwogIGlmICghcmVmKSB7CiAgICBUUkFDRSgic2l6ZT0lZFxuIiwgKlRoaXMtPnNpemUpOwogICAgVGhpcy0+cE1zZy0+QnVmZmVyID0gVGhpcy0+ZGF0YSArICpUaGlzLT5zaXplOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwwLFRoaXMpOwogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNTdHJlYW1fUmVhZChMUFNUUkVBTSBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqcHYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGNiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyAqcGNiUmVhZCkKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogIEhSRVNVTFQgaHIgPSBTX09LOwogIGlmIChUaGlzLT5wb3MgKyBjYiA+ICpUaGlzLT5zaXplKQogIHsKICAgIGNiID0gKlRoaXMtPnNpemUgLSBUaGlzLT5wb3M7CiAgICBociA9IFNfRkFMU0U7CiAgfQogIGlmIChjYikgewogICAgbWVtY3B5KHB2LCBUaGlzLT5kYXRhICsgVGhpcy0+cG9zLCBjYik7CiAgICBUaGlzLT5wb3MgKz0gY2I7CiAgfQogIGlmIChwY2JSZWFkKSAqcGNiUmVhZCA9IGNiOwogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIFJwY1N0cmVhbV9Xcml0ZShMUFNUUkVBTSBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnB2LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgY2IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVTE9ORyAqcGNiV3JpdHRlbikKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogIGlmIChUaGlzLT5kYXRhICsgY2IgPiAodW5zaWduZWQgY2hhciAqKVRoaXMtPnBNc2ctPlJwY01zZy0+QnVmZmVyICsgVGhpcy0+cE1zZy0+QnVmZmVyTGVuZ3RoKQogICAgcmV0dXJuIFNUR19FX01FRElVTUZVTEw7CiAgbWVtY3B5KFRoaXMtPmRhdGEgKyBUaGlzLT5wb3MsIHB2LCBjYik7CiAgVGhpcy0+cG9zICs9IGNiOwogIGlmIChUaGlzLT5wb3MgPiAqVGhpcy0+c2l6ZSkgKlRoaXMtPnNpemUgPSBUaGlzLT5wb3M7CiAgaWYgKHBjYldyaXR0ZW4pICpwY2JXcml0dGVuID0gY2I7CiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNTdHJlYW1fU2VlayhMUFNUUkVBTSBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTEFSR0VfSU5URUdFUiBtb3ZlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBvcmlnaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMQVJHRV9JTlRFR0VSICpuZXdQb3MpCnsKICBScGNTdHJlYW1JbXBsICpUaGlzID0gKFJwY1N0cmVhbUltcGwgKilpZmFjZTsKICBzd2l0Y2ggKG9yaWdpbikgewogIGNhc2UgU1RSRUFNX1NFRUtfU0VUOgogICAgVGhpcy0+cG9zID0gbW92ZS51Lkxvd1BhcnQ7CiAgICBicmVhazsKICBjYXNlIFNUUkVBTV9TRUVLX0NVUjoKICAgIFRoaXMtPnBvcyA9IFRoaXMtPnBvcyArIG1vdmUudS5Mb3dQYXJ0OwogICAgYnJlYWs7CiAgY2FzZSBTVFJFQU1fU0VFS19FTkQ6CiAgICBUaGlzLT5wb3MgPSAqVGhpcy0+c2l6ZSArIG1vdmUudS5Mb3dQYXJ0OwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIHJldHVybiBTVEdfRV9JTlZBTElERlVOQ1RJT047CiAgfQogIGlmIChuZXdQb3MpIHsKICAgIG5ld1Bvcy0+dS5Mb3dQYXJ0ID0gVGhpcy0+cG9zOwogICAgbmV3UG9zLT51LkhpZ2hQYXJ0ID0gMDsKICB9CiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBScGNTdHJlYW1fU2V0U2l6ZShMUFNUUkVBTSBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxBUkdFX0lOVEVHRVIgbmV3U2l6ZSkKewogIFJwY1N0cmVhbUltcGwgKlRoaXMgPSAoUnBjU3RyZWFtSW1wbCAqKWlmYWNlOwogICpUaGlzLT5zaXplID0gbmV3U2l6ZS51Lkxvd1BhcnQ7CiAgcmV0dXJuIFNfT0s7Cn0KCnN0YXRpYyBjb25zdCBJU3RyZWFtVnRibCBScGNTdHJlYW1fVnRibCA9CnsKICBScGNTdHJlYW1fUXVlcnlJbnRlcmZhY2UsCiAgUnBjU3RyZWFtX0FkZFJlZiwKICBScGNTdHJlYW1fUmVsZWFzZSwKICBScGNTdHJlYW1fUmVhZCwKICBScGNTdHJlYW1fV3JpdGUsCiAgUnBjU3RyZWFtX1NlZWssCiAgUnBjU3RyZWFtX1NldFNpemUsCiAgTlVMTCwgLyogQ29weVRvICovCiAgTlVMTCwgLyogQ29tbWl0ICovCiAgTlVMTCwgLyogUmV2ZXJ0ICovCiAgTlVMTCwgLyogTG9ja1JlZ2lvbiAqLwogIE5VTEwsIC8qIFVubG9ja1JlZ2lvbiAqLwogIE5VTEwsIC8qIFN0YXQgKi8KICBOVUxMICAvKiBDbG9uZSAqLwp9OwoKc3RhdGljIExQU1RSRUFNIFJwY1N0cmVhbV9DcmVhdGUoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCBCT09MIGluaXQpCnsKICBScGNTdHJlYW1JbXBsICpUaGlzOwogIFRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSxIRUFQX1pFUk9fTUVNT1JZLHNpemVvZihScGNTdHJlYW1JbXBsKSk7CiAgaWYgKCFUaGlzKSByZXR1cm4gTlVMTDsKICBUaGlzLT5scFZ0YmwgPSAmUnBjU3RyZWFtX1Z0Ymw7CiAgVGhpcy0+UmVmQ291bnQgPSAxOwogIFRoaXMtPnBNc2cgPSBwU3R1Yk1zZzsKICBUaGlzLT5zaXplID0gKExQRFdPUkQpcFN0dWJNc2ctPkJ1ZmZlcjsKICBUaGlzLT5kYXRhID0gKHVuc2lnbmVkIGNoYXIqKShUaGlzLT5zaXplICsgMSk7CiAgVGhpcy0+cG9zID0gMDsKICBpZiAoaW5pdCkgKlRoaXMtPnNpemUgPSAwOwogIFRSQUNFKCJpbml0IHNpemU9JWRcbiIsICpUaGlzLT5zaXplKTsKICByZXR1cm4gKExQU1RSRUFNKVRoaXM7Cn0KCnN0YXRpYyBjb25zdCBJSUQqIGdldF9pcF9paWQoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCB1bnNpZ25lZCBjaGFyICpwTWVtb3J5LCBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgY29uc3QgSUlEICpyaWlkOwogIGlmICghcEZvcm1hdCkgcmV0dXJuICZJSURfSVVua25vd247CiAgVFJBQ0UoImZvcm1hdD0lMDJ4ICUwMnhcbiIsIHBGb3JtYXRbMF0sIHBGb3JtYXRbMV0pOwogIGlmIChwRm9ybWF0WzBdICE9IFJQQ19GQ19JUCkgRklYTUUoImZvcm1hdD0lZFxuIiwgcEZvcm1hdFswXSk7CiAgaWYgKHBGb3JtYXRbMV0gPT0gUlBDX0ZDX0NPTlNUQU5UX0lJRCkgewogICAgcmlpZCA9IChjb25zdCBJSUQgKikmcEZvcm1hdFsyXTsKICB9IGVsc2UgewogICAgQ29tcHV0ZUNvbmZvcm1hbmNlKHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KzIsIDApOwogICAgcmlpZCA9IChjb25zdCBJSUQgKilwU3R1Yk1zZy0+TWF4Q291bnQ7CiAgfQogIGlmICghcmlpZCkgcmlpZCA9ICZJSURfSVVua25vd247CiAgVFJBQ0UoImdvdCAlc1xuIiwgZGVidWdzdHJfZ3VpZChyaWlkKSk7CiAgcmV0dXJuIHJpaWQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRySW50ZXJmYWNlUG9pbnRlck1hcnNoYWxsIFtSUENSVDQuQF0KICovCnVuc2lnbmVkIGNoYXIgKiBXSU5BUEkgTmRySW50ZXJmYWNlUG9pbnRlck1hcnNoYWxsKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpwTWVtb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICBjb25zdCBJSUQgKnJpaWQgPSBnZXRfaXBfaWlkKHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICBMUFNUUkVBTSBzdHJlYW07CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICBwU3R1Yk1zZy0+TWF4Q291bnQgPSAwOwogIGlmICghTG9hZENPTSgpKSByZXR1cm4gTlVMTDsKICBpZiAocFN0dWJNc2ctPkJ1ZmZlciArIHNpemVvZihEV09SRCkgPD0gKHVuc2lnbmVkIGNoYXIgKilwU3R1Yk1zZy0+UnBjTXNnLT5CdWZmZXIgKyBwU3R1Yk1zZy0+QnVmZmVyTGVuZ3RoKSB7CiAgICBzdHJlYW0gPSBScGNTdHJlYW1fQ3JlYXRlKHBTdHViTXNnLCBUUlVFKTsKICAgIGlmIChzdHJlYW0pIHsKICAgICAgaWYgKHBNZW1vcnkpCiAgICAgICAgaHIgPSBDT01fTWFyc2hhbEludGVyZmFjZShzdHJlYW0sIHJpaWQsIChMUFVOS05PV04pcE1lbW9yeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBTdHViTXNnLT5kd0Rlc3RDb250ZXh0LCBwU3R1Yk1zZy0+cHZEZXN0Q29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1TSExGTEFHU19OT1JNQUwpOwogICAgICBlbHNlCiAgICAgICAgaHIgPSBTX09LOwoKICAgICAgSVN0cmVhbV9SZWxlYXNlKHN0cmVhbSk7CiAgICAgIGlmIChGQUlMRUQoaHIpKQogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKGhyKTsKICAgIH0KICB9CiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRySW50ZXJmYWNlUG9pbnRlclVubWFyc2hhbGwgW1JQQ1JUNC5AXQogKi8KdW5zaWduZWQgY2hhciAqIFdJTkFQSSBOZHJJbnRlcmZhY2VQb2ludGVyVW5tYXJzaGFsbChQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICoqcHBNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBmTXVzdEFsbG9jKQp7CiAgTFBTVFJFQU0gc3RyZWFtOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXAsJWQpXG4iLCBwU3R1Yk1zZywgcHBNZW1vcnksIHBGb3JtYXQsIGZNdXN0QWxsb2MpOwogIGlmICghTG9hZENPTSgpKSByZXR1cm4gTlVMTDsKICAqKExQVk9JRCopcHBNZW1vcnkgPSBOVUxMOwogIGlmIChwU3R1Yk1zZy0+QnVmZmVyICsgc2l6ZW9mKERXT1JEKSA8ICh1bnNpZ25lZCBjaGFyICopcFN0dWJNc2ctPlJwY01zZy0+QnVmZmVyICsgcFN0dWJNc2ctPkJ1ZmZlckxlbmd0aCkgewogICAgc3RyZWFtID0gUnBjU3RyZWFtX0NyZWF0ZShwU3R1Yk1zZywgRkFMU0UpOwogICAgaWYgKCFzdHJlYW0pIFJwY1JhaXNlRXhjZXB0aW9uKEVfT1VUT0ZNRU1PUlkpOwogICAgaWYgKCooKFJwY1N0cmVhbUltcGwgKilzdHJlYW0pLT5zaXplICE9IDApCiAgICAgIGhyID0gQ09NX1VubWFyc2hhbEludGVyZmFjZShzdHJlYW0sICZJSURfTlVMTCwgKExQVk9JRCopcHBNZW1vcnkpOwogICAgZWxzZQogICAgICBociA9IFNfT0s7CiAgICBJU3RyZWFtX1JlbGVhc2Uoc3RyZWFtKTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKGhyKTsKICB9CiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRySW50ZXJmYWNlUG9pbnRlckJ1ZmZlclNpemUgW1JQQ1JUNC5AXQogKi8Kdm9pZCBXSU5BUEkgTmRySW50ZXJmYWNlUG9pbnRlckJ1ZmZlclNpemUoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgKnBNZW1vcnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogIGNvbnN0IElJRCAqcmlpZCA9IGdldF9pcF9paWQocFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogIFVMT05HIHNpemUgPSAwOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBwU3R1Yk1zZywgcE1lbW9yeSwgcEZvcm1hdCk7CiAgaWYgKCFMb2FkQ09NKCkpIHJldHVybjsKICBociA9IENPTV9HZXRNYXJzaGFsU2l6ZU1heCgmc2l6ZSwgcmlpZCwgKExQVU5LTk9XTilwTWVtb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcFN0dWJNc2ctPmR3RGVzdENvbnRleHQsIHBTdHViTXNnLT5wdkRlc3RDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTVNITEZMQUdTX05PUk1BTCk7CiAgVFJBQ0UoInNpemU9JWRcbiIsIHNpemUpOwogIHBTdHViTXNnLT5CdWZmZXJMZW5ndGggKz0gc2l6ZW9mKERXT1JEKSArIHNpemU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRySW50ZXJmYWNlUG9pbnRlck1lbW9yeVNpemUgW1JQQ1JUNC5AXQogKi8KVUxPTkcgV0lOQVBJIE5kckludGVyZmFjZVBvaW50ZXJNZW1vcnlTaXplKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICBVTE9ORyBzaXplOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgcFN0dWJNc2csIHBGb3JtYXQpOwoKICBzaXplID0gKihVTE9ORyAqKXBTdHViTXNnLT5CdWZmZXI7CiAgcFN0dWJNc2ctPkJ1ZmZlciArPSA0OwogIHBTdHViTXNnLT5NZW1vcnlTaXplICs9IDQ7CgogIHBTdHViTXNnLT5CdWZmZXIgKz0gc2l6ZTsKCiAgcmV0dXJuIHBTdHViTXNnLT5NZW1vcnlTaXplOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckludGVyZmFjZVBvaW50ZXJGcmVlIFtSUENSVDQuQF0KICovCnZvaWQgV0lOQVBJIE5kckludGVyZmFjZVBvaW50ZXJGcmVlKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpwTWVtb3J5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICBMUFVOS05PV04gcFVuayA9IChMUFVOS05PV04pcE1lbW9yeTsKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgcFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogIGlmIChwVW5rKSBJVW5rbm93bl9SZWxlYXNlKHBVbmspOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kck9sZUFsbG9jYXRlIFtSUENSVDQuQF0KICovCnZvaWQgKiBXSU5BUEkgTmRyT2xlQWxsb2NhdGUoc2l6ZV90IFNpemUpCnsKICBpZiAoIUxvYWRDT00oKSkgcmV0dXJuIE5VTEw7CiAgcmV0dXJuIENPTV9NZW1BbGxvYyhTaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBOZHJPbGVGcmVlIFtSUENSVDQuQF0KICovCnZvaWQgV0lOQVBJIE5kck9sZUZyZWUodm9pZCAqTm9kZVRvRnJlZSkKewogIGlmICghTG9hZENPTSgpKSByZXR1cm47CiAgQ09NX01lbUZyZWUoTm9kZVRvRnJlZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBIZWxwZXIgZnVuY3Rpb24gdG8gY3JlYXRlIGEgc3R1Yi4KICogVGhpcyBwcm9iYWJseSBsb29rcyB2ZXJ5IG11Y2ggbGlrZSBOZHJwQ3JlYXRlU3R1Yi4KICovCkhSRVNVTFQgY3JlYXRlX3N0dWIoUkVGSUlEIGlpZCwgSVVua25vd24gKnBVbmssIElScGNTdHViQnVmZmVyICoqcHBzdHViKQp7CiAgICBDTFNJRCBjbHNpZDsKICAgIElQU0ZhY3RvcnlCdWZmZXIgKnBzZmFjOwogICAgSFJFU1VMVCByOwoKICAgIGlmKCFMb2FkQ09NKCkpIHJldHVybiBFX0ZBSUw7CgogICAgciA9IENPTV9HZXRQU0Nsc2lkKCBpaWQsICZjbHNpZCApOwogICAgaWYoRkFJTEVEKHIpKSByZXR1cm4gcjsKCiAgICByID0gQ09NX0dldENsYXNzT2JqZWN0KCAmY2xzaWQsIENMU0NUWF9JTlBST0NfU0VSVkVSLCBOVUxMLCAmSUlEX0lQU0ZhY3RvcnlCdWZmZXIsICh2b2lkKiopJnBzZmFjICk7CiAgICBpZihGQUlMRUQocikpIHJldHVybiByOwoKICAgIHIgPSBJUFNGYWN0b3J5QnVmZmVyX0NyZWF0ZVN0dWIocHNmYWMsIGlpZCwgcFVuaywgcHBzdHViKTsKCiAgICBJUFNGYWN0b3J5QnVmZmVyX1JlbGVhc2UocHNmYWMpOwogICAgcmV0dXJuIHI7Cn0K