LyoJCURpcmVjdERyYXcgLSBJRGlyZWN0UGFsZXR0ZSBiYXNlIGludGVyZmFjZQogKgogKiBDb3B5cmlnaHQgMjAwNiBTdGVmYW4gRPZzaW5nZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojaW5jbHVkZSAiZGRyYXdfcHJpdmF0ZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoZGRyYXcpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3UGFsZXR0ZTo6UXVlcnlJbnRlcmZhY2UKICoKICogQSB1c3VhbCBRdWVyeUludGVyZmFjZSBpbXBsZW1lbnRhdGlvbi4gQ2FuIG9ubHkgUXVlcnkgSVVua25vd24gYW5kCiAqIElEaXJlY3REcmF3UGFsZXR0ZQogKgogKiBQYXJhbXM6CiAqICByZWZpaWQ6IFRoZSBpbnRlcmZhY2UgaWQgcXVlcmllZCBmb3IKICogIG9iajogQWRkcmVzcyB0byByZXR1cm4gdGhlIGludGVyZmFjZSBwb2ludGVyIGF0CiAqCiAqIFJldHVybnM6CiAqICBTX09LIG9uIHN1Y2Nlc3MKICogIEVfTk9JTlRFUkZBQ0UgaWYgdGhlIHJlcXVlc3RlZCBpbnRlcmZhY2Ugd2Fzbid0IGZvdW5kCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3UGFsZXR0ZUltcGxfUXVlcnlJbnRlcmZhY2UoSURpcmVjdERyYXdQYWxldHRlICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmVmaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3UGFsZXR0ZUltcGwsIElEaXJlY3REcmF3UGFsZXR0ZSwgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksb2JqKTsKCiAgICBpZiAoSXNFcXVhbEdVSUQocmVmaWlkLCAmSUlEX0lVbmtub3duKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJlZmlpZCwgJklJRF9JRGlyZWN0RHJhd1BhbGV0dGUpKQogICAgewogICAgICAgICpvYmogPSBpZmFjZTsKICAgICAgICBJRGlyZWN0RHJhd1BhbGV0dGVfQWRkUmVmKGlmYWNlKTsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAqb2JqID0gTlVMTDsKICAgICAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3UGFsZXR0ZUltcGw6OkFkZFJlZgogKgogKiBJbmNyZWFzZXMgdGhlIHJlZmNvdW50LgogKgogKiBSZXR1cm5zOgogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdQYWxldHRlSW1wbF9BZGRSZWYoSURpcmVjdERyYXdQYWxldHRlICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdQYWxldHRlSW1wbCwgSURpcmVjdERyYXdQYWxldHRlLCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKS0+KCkgaW5jcmVtZW50aW5nIGZyb20gJWx1LlxuIiwgVGhpcywgcmVmIC0gMSk7CgogICAgcmV0dXJuIHJlZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3UGFsZXR0ZUltcGw6OlJlbGVhc2UKICoKICogUmVkdWNlcyB0aGUgcmVmY291bnQuIElmIHRoZSByZWZjb3VudCBmYWxscyB0byAwLCB0aGUgb2JqZWN0IGlzIGRlc3Ryb3llZAogKgogKiBSZXR1cm5zOgogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdQYWxldHRlSW1wbF9SZWxlYXNlKElEaXJlY3REcmF3UGFsZXR0ZSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3UGFsZXR0ZUltcGwsIElEaXJlY3REcmF3UGFsZXR0ZSwgaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgVFJBQ0UoIiglcCktPigpIGRlY3JlbWVudGluZyBmcm9tICVsdS5cbiIsIFRoaXMsIHJlZiArIDEpOwoKICAgIGlmIChyZWYgPT0gMCkKICAgIHsKICAgICAgICBJV2luZUQzRFBhbGV0dGVfUmVsZWFzZShUaGlzLT53aW5lRDNEUGFsZXR0ZSk7CiAgICAgICAgaWYoVGhpcy0+aWZhY2VUb1JlbGVhc2UpCiAgICAgICAgewogICAgICAgICAgICBJVW5rbm93bl9SZWxlYXNlKFRoaXMtPmlmYWNlVG9SZWxlYXNlKTsKICAgICAgICB9CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICB9CgogICAgcmV0dXJuIHJlZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3UGFsZXR0ZTo6SW5pdGlhbGl6ZQogKgogKiBJbml0aWFsaXplcyB0aGUgcGFsZXR0ZS4gQXMgd2Ugc3RhcnQgaW5pdGlhbGl6ZWQsIHJldHVybgogKiBEREVSUl9BTFJFQURZSU5JVElBTElaRUQKICoKICogUGFyYW1zOgogKiAgREQ6IERpcmVjdERyYXcgaW50ZXJmYWNlIHRoaXMgcGFsZXR0ZSBpcyBhc2lnbmVkIHRvCiAqICBGbGFnczogU29tZSBmbGFncywgYXMgdXN1YWwKICogIENvbG9yVGFibGU6IFRoZSBzdGFydHVwIGNvbG9yIHRhYmxlCiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9BTFJFQURZSU5JVElBTElaRUQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdQYWxldHRlSW1wbF9Jbml0aWFsaXplKElEaXJlY3REcmF3UGFsZXR0ZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0RHJhdyAqREQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBTEVUVEVFTlRSWSAqQ29sb3JUYWJsZSkKewogICAgVFJBQ0UoIiglcCktPiglcCwlbHgsJXApXG4iLCBpZmFjZSwgREQsIEZsYWdzLCBDb2xvclRhYmxlKTsKICAgIHJldHVybiBEREVSUl9BTFJFQURZSU5JVElBTElaRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1BhbGV0dGU6OkdldENhcHMKICoKICogUmV0dXJucyB0aGUgcGFsZXR0ZSBkZXNjcmlwdGlvbgogKgogKiBQYXJhbXM6CiAqICBDYXBzOiBBZGRyZXNzIHRvIHN0b3JlIHRoZSBjYXBzIGF0CiAqCiAqIFJldHVybnM6CiAqICBEM0RfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBDYXBzIGlzIE5VTEwKICogIEZvciBtb3JlIGRldGFpbHMsIHNlZSBJV2luZUQzRFBhbGV0dGU6OkdldENhcHMKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdQYWxldHRlSW1wbF9HZXRDYXBzKElEaXJlY3REcmF3UGFsZXR0ZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCAqQ2FwcykKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdQYWxldHRlSW1wbCwgSURpcmVjdERyYXdQYWxldHRlLCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKTogUmVsYXlcbiIsIFRoaXMsIENhcHMpOwoKICAgIHJldHVybiBJV2luZUQzRFBhbGV0dGVfR2V0Q2FwcyhUaGlzLT53aW5lRDNEUGFsZXR0ZSwgQ2Fwcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd1BhbGV0dGU6OlNldEVudHJpZXMKICoKICogU2V0cyB0aGUgcGFsZXR0ZSBlbnRyaWVzIGZyb20gYSBQQUxFVFRFRU5UUlkgc3RydWN0dXJlLiBXaW5lRDNEIHRha2VzCiAqIGNhcmUgZm9yIHVwZGF0aW5nIHRoZSBzdXJmYWNlLgogKgogKiBQYXJhbXM6CiAqICBGbGFnczogRmxhZ3MsIGFzIHVzdWFsCiAqICBTdGFydDogRmlyc3QgcGFsZXR0ZSBlbnRyeSB0byBzZXQKICogIENvdW50OiBOdW1iZXIgb2YgZW50cmllcyB0byBzZXQKICogIFBhbEVudDogU291cmNlIGVudHJpZXMKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFBhbEVudCBpcyBOVUxMCiAqICBGb3IgZGV0YWlscywgc2VlIElXaW5lRDNERGV2aWNlOjpTZXRFbnRyaWVzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3UGFsZXR0ZUltcGxfU2V0RW50cmllcyhJRGlyZWN0RHJhd1BhbGV0dGUgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFMRVRURUVOVFJZICpQYWxFbnQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3UGFsZXR0ZUltcGwsIElEaXJlY3REcmF3UGFsZXR0ZSwgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglbHgsJWxkLCVsZCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBGbGFncywgU3RhcnQsIENvdW50LCBQYWxFbnQpOwoKICAgIGlmKCFQYWxFbnQpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgcmV0dXJuIElXaW5lRDNEUGFsZXR0ZV9TZXRFbnRyaWVzKFRoaXMtPndpbmVEM0RQYWxldHRlLCBGbGFncywgU3RhcnQsIENvdW50LCBQYWxFbnQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdQYWxldHRlOjpHZXRFbnRyaWVzCiAqCiAqIFJldHVybnMgdGhlIGVudHJpZXMgc3RvcmVkIGluIHRoaXMgaW50ZXJmYWNlLgogKgogKiBQYXJhbXM6CiAqICBGbGFnczogRmxhZ3MgOikKICogIFN0YXJ0OiBGaXJzdCBlbnRyeSB0byByZXR1cm4KICogIENvdW50OiBUaGUgbnVtYmVyIG9mIGVudHJpZXMgdG8gcmV0dXJuCiAqICBQYWxFbnQ6IFBBTEVUVEVFTlRSWSBzdHJ1Y3R1cmUgdG8gd3JpdGUgdGhlIGVudHJpZXMgdG8KICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEREVSUl9JTlZBTElEUEFSQU1TIGlmIFBhbEVudCBpcyBOVUxMCiAqICBGb3IgZGV0YWlscywgc2VlIElXaW5lRDNERGV2aWNlOjpTZXRFbnRyaWVzCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3UGFsZXR0ZUltcGxfR2V0RW50cmllcyhJRGlyZWN0RHJhd1BhbGV0dGUgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIENvdW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFMRVRURUVOVFJZICpQYWxFbnQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3UGFsZXR0ZUltcGwsIElEaXJlY3REcmF3UGFsZXR0ZSwgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglbHgsJWxkLCVsZCwlcCk6IFJlbGF5XG4iLCBUaGlzLCBGbGFncywgU3RhcnQsIENvdW50LCBQYWxFbnQpOwoKICAgIGlmKCFQYWxFbnQpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgcmV0dXJuIElXaW5lRDNEUGFsZXR0ZV9HZXRFbnRyaWVzKFRoaXMtPndpbmVEM0RQYWxldHRlLCBGbGFncywgU3RhcnQsIENvdW50LCBQYWxFbnQpOwp9Cgpjb25zdCBJRGlyZWN0RHJhd1BhbGV0dGVWdGJsIElEaXJlY3REcmF3UGFsZXR0ZV9WdGJsID0KewogICAgLyoqKiBJVW5rbm93biAqKiovCiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSURpcmVjdERyYXdQYWxldHRlSW1wbF9BZGRSZWYsCiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsX1JlbGVhc2UsCiAgICAvKioqIElEaXJlY3REcmF3UGFsZXR0ZSAqKiovCiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsX0dldENhcHMsCiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsX0dldEVudHJpZXMsCiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsX0luaXRpYWxpemUsCiAgICBJRGlyZWN0RHJhd1BhbGV0dGVJbXBsX1NldEVudHJpZXMKfTsK