LyogICAgICAgIERpcmVjdERyYXcgQmFzZSBGdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTctMTk5OSBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqCiAqIFRoaXMgZmlsZSBjb250YWlucyB0aGUgKGludGVybmFsKSBkcml2ZXIgcmVnaXN0cmF0aW9uIGZ1bmN0aW9ucywKICogZHJpdmVyIGVudW1lcmF0aW9uIEFQSXMgYW5kIERpcmVjdERyYXcgY3JlYXRpb24gZnVuY3Rpb25zLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJkM2QuaCIKCiNpbmNsdWRlICJkZHJhd19wcml2YXRlLmgiCgp0eXBlZGVmIElXaW5lRDNEKiAoV0lOQVBJICpmbldpbmVEaXJlY3QzRENyZWF0ZSkoVUlOVCwgVUlOVCwgSVVua25vd24gKik7CgpzdGF0aWMgSE1PRFVMRSBoV2luZUQzRCA9IChITU9EVUxFKSAtMTsKc3RhdGljIGZuV2luZURpcmVjdDNEQ3JlYXRlIHBXaW5lRGlyZWN0M0RDcmVhdGU7CgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkZHJhdyk7CgovKiBUaGUgY29uZmlndXJlZCBkZWZhdWx0IHN1cmZhY2UgKi8KV0lORUQzRFNVUkZUWVBFIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfVU5LTk9XTjsKCi8qIEREcmF3IGxpc3QgYW5kIGNyaXRpY2FsIHNlY3Rpb24gKi8Kc3RhdGljIHN0cnVjdCBsaXN0IGdsb2JhbF9kZHJhd19saXN0ID0gTElTVF9JTklUKGdsb2JhbF9kZHJhd19saXN0KTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGRkcmF3X2xpc3RfY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGRkcmF3X2xpc3RfY3NfZGVidWcgPQp7CiAgICAwLCAwLCAmZGRyYXdfbGlzdF9jcywKICAgIHsgJmRkcmF3X2xpc3RfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgCiAgICAmZGRyYXdfbGlzdF9jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGRkcmF3X2xpc3RfY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGRkcmF3X2xpc3RfY3MgPSB7ICZkZHJhd19saXN0X2NzX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEhlbHBlciBmdW5jdGlvbiBmb3IgRGlyZWN0RHJhd0NyZWF0ZSBhbmQgZnJpZW5kcwogKiBDcmVhdGVzIGEgbmV3IEREcmF3IGludGVyZmFjZSB3aXRoIHRoZSBnaXZlbiBSRUZJSUQKICoKICogSW50ZXJmYWNlcyB0aGF0IGNhbiBiZSBjcmVhdGVkOgogKiAgSURpcmVjdERyYXcsIElEaXJlY3REcmF3MiwgSURpcmVjdERyYXc0LCBJRGlyZWN0RHJhdzcKICogIElEaXJlY3QzRCwgSURpcmVjdDNEMiwgSURpcmVjdDNEMywgSURpcmVjdDNENy4gKERvZXMgV2luZG93cyByZXR1cm4KICogIElEaXJlY3QzRCBpbnRlcmZhY2VzPykKICoKICogQXJndW1lbnRzOgogKiAgZ3VpZDogSUQgb2YgdGhlIHJlcXVlc3RlZCBkcml2ZXIsIE5VTEwgZm9yIHRoZSBkZWZhdWx0IGRyaXZlci4KICogICAgICAgIFRoZSBHVUlEIGNhbiBiZSBxdWVyaWVkIHdpdGggRGlyZWN0RHJhd0VudW1lcmF0ZShFeClBL1cKICogIEREOiBVc2VkIHRvIHJldHVybiB0aGUgcG9pbnRlciB0byB0aGUgY3JlYXRlZCBvYmplY3QKICogIFVua091dGVyOiBGb3IgYWdncmVnYXRpb24sIHdoaWNoIGlzIHVuc3VwcG9ydGVkLiBNdXN0IGJlIE5VTEwKICogIGlpZDogcmVxdWVzdGVkIHZlcnNpb24gSUQuCiAqCiAqIFJldHVybnM6CiAqICBERF9PSyBpZiB0aGUgSW50ZXJmYWNlIHdhcyBjcmVhdGVkIHN1Y2Nlc3NmdWxseQogKiAgQ0xBU1NfRV9OT0FHR1JFR0FUSU9OIGlmIFVua091dGVyIGlzIG5vdCBOVUxMCiAqICBFX09VVE9GTUVNT1JZIGlmIHNvbWUgYWxsb2NhdGlvbiBmYWlsZWQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApERFJBV19DcmVhdGUoY29uc3QgR1VJRCAqZ3VpZCwKICAgICAgICAgICAgIHZvaWQgKipERCwKICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlciwKICAgICAgICAgICAgIFJFRklJRCBpaWQpCnsKICAgIElEaXJlY3REcmF3SW1wbCAqVGhpcyA9IE5VTEw7CiAgICBIUkVTVUxUIGhyOwogICAgSVdpbmVEM0QgKndpbmVEM0QgPSBOVUxMOwogICAgSVdpbmVEM0REZXZpY2UgKndpbmVEM0REZXZpY2UgPSBOVUxMOwogICAgSERDIGhEQzsKICAgIFdJTkVEM0RERVZUWVBFIGRldmljZXR5cGU7CgogICAgVFJBQ0UoIiglcywlcCwlcClcbiIsIGRlYnVnc3RyX2d1aWQoZ3VpZCksIERELCBVbmtPdXRlcik7CgogICAgKkREID0gTlVMTDsKCiAgICAvKiBXZSBkb24ndCBjYXJlIGFib3V0IHRoaXMgZ3VpZHMuIFdlbGwsIHRoZXJlJ3Mgbm8gc3BlY2lhbCBndWlkIGFueXdheQogICAgICogT0ssIHdlIGNvdWxkCiAgICAgKi8KICAgIGlmIChndWlkID09IChHVUlEICopIEREQ1JFQVRFX0VNVUxBVElPTk9OTFkpCiAgICB7CiAgICAgICAgLyogVXNlIHRoZSByZWZlcmVuY2UgZGV2aWNlIGlkLiBUaGlzIGRvZXNuJ3QgYWN0dWFsbHkgY2hhbmdlIGFueXRoaW5nLAogICAgICAgICAqIFdpbmVEM0QgYWx3YXlzIHVzZXMgT3BlbkdMIGZvciBEM0QgcmVuZGVyaW5nLiBPbmUgY291bGQgbWFrZSBpdCByZXF1ZXN0CiAgICAgICAgICogaW5kaXJlY3QgcmVuZGVyaW5nCiAgICAgICAgICovCiAgICAgICAgZGV2aWNldHlwZSA9IFdJTkVEM0RERVZUWVBFX1JFRjsKICAgIH0KICAgIGVsc2UgaWYoZ3VpZCA9PSAoR1VJRCAqKSBERENSRUFURV9IQVJEV0FSRU9OTFkpCiAgICB7CiAgICAgICAgZGV2aWNldHlwZSA9IFdJTkVEM0RERVZUWVBFX0hBTDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBkZXZpY2V0eXBlID0gMDsKICAgIH0KCiAgICAvKiBERHJhdyBkb2Vzbid0IHN1cHBvcnQgYWdncmVnYXRpb24sIGFjY29yZGluZyB0byBtc2RuICovCiAgICBpZiAoVW5rT3V0ZXIgIT0gTlVMTCkKICAgICAgICByZXR1cm4gQ0xBU1NfRV9OT0FHR1JFR0FUSU9OOwoKICAgIC8qIERpcmVjdERyYXcgY3JlYXRpb24gY29tZXMgaGVyZSAqLwogICAgVGhpcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSURpcmVjdERyYXdJbXBsKSk7CiAgICBpZighVGhpcykKICAgIHsKICAgICAgICBFUlIoIk91dCBvZiBtZW1vcnkgd2hlbiBjcmVhdGluZyBEaXJlY3REcmF3XG4iKTsKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKICAgIH0KCiAgICAvKiBUaGUgaW50ZXJmYWNlczoKICAgICAqIElEaXJlY3REcmF3IGFuZCBJRGlyZWN0M0QgYXJlIHRoZSBzYW1lIG9iamVjdCwKICAgICAqIFF1ZXJ5SW50ZXJmYWNlIGlzIHVzZWQgdG8gZ2V0IG90aGVyIGludGVyZmFjZXMuCiAgICAgKi8KICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXcsICBJRGlyZWN0RHJhdzFfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3MiwgSURpcmVjdERyYXcyX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzMsIElEaXJlY3REcmF3M19WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc0LCBJRGlyZWN0RHJhdzRfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3NywgSURpcmVjdERyYXc3X1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QsICBJRGlyZWN0M0QxX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QyLCBJRGlyZWN0M0QyX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0QzLCBJRGlyZWN0M0QzX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0Q3LCBJRGlyZWN0M0Q3X1Z0YmwpOwoKICAgIC8qIFNlZSBjb21tZW50cyBpbiBJRGlyZWN0RHJhd0ltcGxfQ3JlYXRlTmV3U3VyZmFjZSBmb3IgYSBkZXNjcmlwdGlvbgogICAgICogb2YgdGhpcyBtZW1iZXIuCiAgICAgKiBSZWFkIGZyb20gYSByZWdpc3RyeSBrZXksIHNob3VsZCBhZGQgYSB3aW5lY2ZnIG9wdGlvbiBsYXRlcgogICAgICovCiAgICBUaGlzLT5JbXBsVHlwZSA9IERlZmF1bHRTdXJmYWNlVHlwZTsKCiAgICAvKiBHZXQgdGhlIGN1cnJlbnQgc2NyZWVuIHNldHRpbmdzICovCiAgICBoREMgPSBHZXREQygwKTsKICAgIFRoaXMtPm9yaWdfYnBwID0gR2V0RGV2aWNlQ2FwcyhoREMsIEJJVFNQSVhFTCkgKiBHZXREZXZpY2VDYXBzKGhEQywgUExBTkVTKTsKICAgIFJlbGVhc2VEQygwLCBoREMpOwogICAgVGhpcy0+b3JpZ193aWR0aCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1hTQ1JFRU4pOwogICAgVGhpcy0+b3JpZ19oZWlnaHQgPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NZU0NSRUVOKTsKCiAgICBpZiAoaFdpbmVEM0QgPT0gKEhNT0RVTEUpIC0xKQogICAgewogICAgICAgIGhXaW5lRDNEID0gTG9hZExpYnJhcnlBKCJ3aW5lZDNkIik7CiAgICAgICAgaWYgKGhXaW5lRDNEKQogICAgICAgIHsKICAgICAgICAgICAgcFdpbmVEaXJlY3QzRENyZWF0ZSA9IChmbldpbmVEaXJlY3QzRENyZWF0ZSkgR2V0UHJvY0FkZHJlc3MoaFdpbmVEM0QsICJXaW5lRGlyZWN0M0RDcmVhdGUiKTsKICAgICAgICAgICAgcFdpbmVEaXJlY3QzRENyZWF0ZUNsaXBwZXIgPSAoZm5XaW5lRGlyZWN0M0RDcmVhdGVDbGlwcGVyKSBHZXRQcm9jQWRkcmVzcyhoV2luZUQzRCwgIldpbmVEaXJlY3QzRENyZWF0ZUNsaXBwZXIiKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCFoV2luZUQzRCkKICAgIHsKICAgICAgICBFUlIoIkNvdWxkbid0IGxvYWQgV2luZUQzRCAtIE9wZW5HTCBsaWJzIG5vdCBwcmVzZW50P1xuIik7CiAgICAgICAgaHIgPSBEREVSUl9OT0RJUkVDVERSQVdTVVBQT1JUOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KCiAgICAvKiBJbml0aWFsaXplIFdpbmVEM0QKICAgICAqCiAgICAgKiBBbGwgUmVuZGVyaW5nICgyRCBhbmQgM0QpIGlzIHJlbGF5ZWQgdG8gV2luZUQzRCwKICAgICAqIGJ1dCBEaXJlY3REcmF3IHNwZWNpZmljIG1hbmFnZW1lbnQsIGxpa2UgRERTVVJGQUNFREVTQyBhbmQgRERQSVhFTEZPUk1BVAogICAgICogc3RydWN0dXJlIGhhbmRsaW5nIGlzIGhhbmRsZWQgaW4gdGhpcyBsaWIuCiAgICAgKi8KICAgIHdpbmVEM0QgPSBwV2luZURpcmVjdDNEQ3JlYXRlKDAgLyogU0RLVmVyc2lvbiAqLywgNyAvKiBEWFZlcnNpb24gKi8sIChJVW5rbm93biAqKSBUaGlzIC8qIFBhcmVudCAqLyk7CiAgICBpZighd2luZUQzRCkKICAgIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBpbml0aWFsaXNlIFdpbmVEM0RcbiIpOwogICAgICAgIGhyID0gRV9PVVRPRk1FTU9SWTsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CiAgICBUaGlzLT53aW5lRDNEID0gd2luZUQzRDsKICAgIFRSQUNFKCJXaW5lRDNEIGNyZWF0ZWQgYXQgJXBcbiIsIHdpbmVEM0QpOwoKICAgIC8qIEluaXRpYWxpemVkIG1lbWJlci4uLgogICAgICoKICAgICAqIEl0IGlzIHNldCB0byBmYWxzZSBhdCBjcmVhdGlvbiB0aW1lLCBhbmQgc2V0IHRvIHRydWUgaW4KICAgICAqIElEaXJlY3REcmF3Nzo6SW5pdGlhbGl6ZS4gSXRzIHNvbGUgcHVycG9zZSBpcyB0byByZXR1cm4gRERfT0sgb24KICAgICAqIGluaXRpYWxpemUgb25seSBvbmNlCiAgICAgKi8KICAgIFRoaXMtPmluaXRpYWxpemVkID0gRkFMU0U7CgogICAgLyogSW5pdGlhbGl6ZSBXaW5lRDNERGV2aWNlCiAgICAgKgogICAgICogSXQgaXMgdXNlZCBmb3Igc2NyZWVuIHNldHVwLCBzdXJmYWNlIGFuZCBwYWxldHRlIGNyZWF0aW9uCiAgICAgKiBXaGVuIGEgRGlyZWN0M0REZXZpY2U3IGlzIGNyZWF0ZWQsIHRoZSBEM0QgY2FwYWJpbGl0aWVzIG9mIFdpbmVEM0QgYXJlCiAgICAgKiBpbml0aWFsaXplZAogICAgICovCiAgICBociA9IElXaW5lRDNEX0NyZWF0ZURldmljZSh3aW5lRDNELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCAvKkQzRF9BREFQVEVSX0RFRkFVTFQqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZXR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAvKiBGb2N1c1dpbmRvdywgZG9uJ3Qga25vdyB5ZXQgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIC8qIEJlaGF2aW9yRmxhZ3MgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ3aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKElVbmtub3duICopIElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3NykpOwogICAgaWYoRkFJTEVEKGhyKSkKICAgIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBjcmVhdGUgYSB3aW5lRDNERGV2aWNlLCByZXN1bHQgPSAleFxuIiwgaHIpOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KICAgIFRoaXMtPndpbmVEM0REZXZpY2UgPSB3aW5lRDNERGV2aWNlOwogICAgVFJBQ0UoIndpbmVEM0REZXZpY2UgY3JlYXRlZCBhdCAlcFxuIiwgVGhpcy0+d2luZUQzRERldmljZSk7CgogICAgLyogUmVnaXN0ZXIgdGhlIHdpbmRvdyBjbGFzcwogICAgICoKICAgICAqIEl0IGlzIHVzZWQgdG8gY3JlYXRlIGEgaGlkZGVuIHdpbmRvdyBmb3IgRDNECiAgICAgKiByZW5kZXJpbmcsIGlmIHRoZSBhcHBsaWNhdGlvbiBkaWRuJ3QgcGFzcyBvbmUuCiAgICAgKiBJdCBjYW4gYWxzbyBiZSB1c2VkIGZvciBDcmVhdGluZyBhIGRldmljZSB3aW5kb3cKICAgICAqIGZyb20gU2V0Q29vcGVyYXRpdmVMZXZlbAogICAgICoKICAgICAqIFRoZSBuYW1lOiBERFJBV188YWRkcmVzcz4uIFRoZSBjbGFzc25hbWUgaXMKICAgICAqIDMyIGJpdCBsb25nLCBzbyBhIDY0IGJpdCBhZGRyZXNzIHdpbGwgZml0IG5pY2VseQogICAgICogKFdpbGwgdGhpcyBiZSBjb21waWxlZCBmb3IgNjQgYml0IGFueXdheT8pCiAgICAgKgogICAgICovCiAgICBzcHJpbnRmKFRoaXMtPmNsYXNzbmFtZSwgIkREUkFXXyVwIiwgVGhpcyk7CgogICAgbWVtc2V0KCZUaGlzLT53bmRfY2xhc3MsIDAsIHNpemVvZihUaGlzLT53bmRfY2xhc3MpKTsKICAgIFRoaXMtPnduZF9jbGFzcy5zdHlsZSA9IENTX0hSRURSQVcgfCBDU19WUkVEUkFXOwogICAgVGhpcy0+d25kX2NsYXNzLmxwZm5XbmRQcm9jID0gRGVmV2luZG93UHJvY0E7CiAgICBUaGlzLT53bmRfY2xhc3MuY2JDbHNFeHRyYSA9IDA7CiAgICBUaGlzLT53bmRfY2xhc3MuY2JXbmRFeHRyYSA9IDA7CiAgICBUaGlzLT53bmRfY2xhc3MuaEluc3RhbmNlID0gR2V0TW9kdWxlSGFuZGxlQSgwKTsKICAgIFRoaXMtPnduZF9jbGFzcy5oSWNvbiA9IDA7CiAgICBUaGlzLT53bmRfY2xhc3MuaEN1cnNvciA9IDA7CiAgICBUaGlzLT53bmRfY2xhc3MuaGJyQmFja2dyb3VuZCA9IChIQlJVU0gpIEdldFN0b2NrT2JqZWN0KEJMQUNLX0JSVVNIKTsKICAgIFRoaXMtPnduZF9jbGFzcy5scHN6TWVudU5hbWUgPSBOVUxMOwogICAgVGhpcy0+d25kX2NsYXNzLmxwc3pDbGFzc05hbWUgPSBUaGlzLT5jbGFzc25hbWU7CiAgICBpZighUmVnaXN0ZXJDbGFzc0EoJlRoaXMtPnduZF9jbGFzcykpCiAgICB7CiAgICAgICAgRVJSKCJSZWdpc3RlckNsYXNzQSBmYWlsZWQhXG4iKTsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CgogICAgLyogR2V0IHRoZSBhbW91bnQgb2YgdmlkZW8gbWVtb3J5ICovCiAgICBUaGlzLT50b3RhbF92aWRtZW0gPSBJV2luZUQzRERldmljZV9HZXRBdmFpbGFibGVUZXh0dXJlTWVtKFRoaXMtPndpbmVEM0REZXZpY2UpOwoKICAgIC8qIEluaXRpYWxpemUgdGhlIGNhcHMgKi8KICAgIFRoaXMtPmNhcHMuZHdTaXplID0gc2l6ZW9mKFRoaXMtPmNhcHMpOwovKiBkbyBub3QgcmVwb3J0IEREQ0FQU19PVkVSTEFZIGFuZCBmcmllbmRzIHNpbmNlIHdlIGRvbid0IHN1cHBvcnQgb3ZlcmxheXMgKi8KI2RlZmluZSBCTElUX0NBUFMgKEREQ0FQU19CTFQgfCBERENBUFNfQkxUQ09MT1JGSUxMIHwgRERDQVBTX0JMVERFUFRIRklMTCBcCiAgICAgICAgICB8IEREQ0FQU19CTFRTVFJFVENIIHwgRERDQVBTX0NBTkJMVFNZU01FTSB8IEREQ0FQU19DQU5DTElQCSAgXAogICAgICAgICAgfCBERENBUFNfQ0FOQ0xJUFNUUkVUQ0hFRCB8IEREQ0FQU19DT0xPUktFWQkJCSAgXAogICAgICAgICAgfCBERENBUFNfQ09MT1JLRVlIV0FTU0lTVCB8IEREQ0FQU19BTElHTkJPVU5EQVJZU1JDICkKI2RlZmluZSBDS0VZX0NBUFMgKEREQ0tFWUNBUFNfREVTVEJMVCB8IEREQ0tFWUNBUFNfU1JDQkxUKQojZGVmaW5lIEZYX0NBUFMgKERERlhDQVBTX0JMVEFMUEhBIHwgRERGWENBUFNfQkxUTUlSUk9STEVGVFJJR0hUCVwKICAgICAgICAgICAgICAgIHwgRERGWENBUFNfQkxUTUlSUk9SVVBET1dOIHwgRERGWENBUFNfQkxUUk9UQVRJT045MAlcCiAgICAgICAgICAgICAgICB8IERERlhDQVBTX0JMVFNIUklOS1ggfCBEREZYQ0FQU19CTFRTSFJJTktYTgkJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRTSFJJTktZIHwgRERGWENBUFNfQkxUU0hSSU5LWE4JCVwKICAgICAgICAgICAgICAgIHwgRERGWENBUFNfQkxUU1RSRVRDSFggfCBEREZYQ0FQU19CTFRTVFJFVENIWE4JCVwKICAgICAgICAgICAgICAgIHwgRERGWENBUFNfQkxUU1RSRVRDSFkgfCBEREZYQ0FQU19CTFRTVFJFVENIWU4pCiAgICBUaGlzLT5jYXBzLmR3Q2FwcyB8PSBERENBUFNfR0RJIHwgRERDQVBTX1BBTEVUVEUgfCBCTElUX0NBUFM7CgogICAgVGhpcy0+Y2Fwcy5kd0NhcHMyIHw9IEREQ0FQUzJfQ0VSVElGSUVEIHwgRERDQVBTMl9OT1BBR0VMT0NLUkVRVUlSRUQgfAogICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0FQUzJfUFJJTUFSWUdBTU1BIHwgRERDQVBTMl9XSURFU1VSRkFDRVMgfAogICAgICAgICAgICAgICAgICAgICAgICAgIEREQ0FQUzJfQ0FOUkVOREVSV0lORE9XRUQ7CiAgICBUaGlzLT5jYXBzLmR3Q0tleUNhcHMgfD0gQ0tFWV9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd0ZYQ2FwcyB8PSBGWF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1BhbENhcHMgfD0gRERQQ0FQU184QklUIHwgRERQQ0FQU19QUklNQVJZU1VSRkFDRTsKICAgIFRoaXMtPmNhcHMuZHdWaWRNZW1Ub3RhbCA9IFRoaXMtPnRvdGFsX3ZpZG1lbTsKICAgIFRoaXMtPmNhcHMuZHdWaWRNZW1GcmVlID0gVGhpcy0+dG90YWxfdmlkbWVtOwogICAgVGhpcy0+Y2Fwcy5kd1NWQkNhcHMgfD0gQkxJVF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1NWQkNLZXlDYXBzIHw9IENLRVlfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTVkJGWENhcHMgfD0gRlhfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdWU0JDYXBzIHw9IEJMSVRfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdWU0JDS2V5Q2FwcyB8PSBDS0VZX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3VlNCRlhDYXBzIHw9IEZYX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3U1NCQ2FwcyB8PSBCTElUX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3U1NCQ0tleUNhcHMgfD0gQ0tFWV9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1NTQkZYQ2FwcyB8PSBGWF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kZHNDYXBzLmR3Q2FwcyB8PSBERFNDQVBTX0FMUEhBIHwgRERTQ0FQU19CQUNLQlVGRkVSIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19GTElQIHwgRERTQ0FQU19GUk9OVEJVRkZFUiB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfT0ZGU0NSRUVOUExBSU4gfCBERFNDQVBTX1BBTEVUVEUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX1BSSU1BUllTVVJGQUNFIHwgRERTQ0FQU19TWVNURU1NRU1PUlkgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX1ZJREVPTUVNT1JZIHwgRERTQ0FQU19WSVNJQkxFOwogICAgLyogSGFja3MgZm9yIEQzRCBjb2RlICovCiAgICAvKiBUT0RPOiBDaGVjayBpZiBXaW5lRDNEIGhhcyAzRCBlbmFibGVkCiAgICAgICBOZWVkIG9wZW5nbCBzdXJmYWNlcyBvciBhdXRvIGZvciAzRAogICAgICovCiAgICBpZihUaGlzLT5JbXBsVHlwZSA9PSAwIHx8IFRoaXMtPkltcGxUeXBlID09IFNVUkZBQ0VfT1BFTkdMKQogICAgewogICAgICAgIFRoaXMtPmNhcHMuZHdDYXBzIHw9IEREQ0FQU18zRDsKICAgICAgICBUaGlzLT5jYXBzLmRkc0NhcHMuZHdDYXBzIHw9IEREU0NBUFNfM0RERVZJQ0UgfCBERFNDQVBTX01JUE1BUCB8IEREU0NBUFNfVEVYVFVSRSB8IEREU0NBUFNfWkJVRkZFUjsKICAgIH0KICAgIFRoaXMtPmNhcHMuZGRzT2xkQ2Fwcy5kd0NhcHMgPSBUaGlzLT5jYXBzLmRkc0NhcHMuZHdDYXBzOwoKI3VuZGVmIEJMSVRfQ0FQUwojdW5kZWYgQ0tFWV9DQVBTCiN1bmRlZiBGWF9DQVBTCgogICAgbGlzdF9pbml0KCZUaGlzLT5zdXJmYWNlX2xpc3QpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19saXN0X2NzKTsKICAgIGxpc3RfYWRkX2hlYWQoJmdsb2JhbF9kZHJhd19saXN0LCAmVGhpcy0+ZGRyYXdfbGlzdF9lbnRyeSk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfbGlzdF9jcyk7CgogICAgVGhpcy0+ZGVjbHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgMCk7CiAgICBpZighVGhpcy0+ZGVjbHMpCiAgICB7CiAgICAgICAgRVJSKCJFcnJvciBhbGxvY2F0aW5nIGFuIGVtcHR5IGFycmF5IGZvciB0aGUgY29udmVydGVkIHZlcnRleCBkZWNsc1xuIik7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQoKICAgIC8qIENhbGwgUXVlcnlJbnRlcmZhY2UgdG8gZ2V0IHRoZSBwb2ludGVyIHRvIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLiBUaGlzIGFsc28gaW5pdGlhbGl6ZXMKICAgICAqIFRoZSByZXF1aXJlZCByZWZjb3VudAogICAgICovCiAgICBociA9IElEaXJlY3REcmF3N19RdWVyeUludGVyZmFjZSggSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwgaWlkLCBERCk7CiAgICBpZihTVUNDRUVERUQoaHIpKSByZXR1cm4gRERfT0s7CgplcnJfb3V0OgogICAgLyogTGV0J3MgaG9wZSB3ZSBuZXZlciBuZWVkIHRoaXMgOykgKi8KICAgIGlmKHdpbmVEM0REZXZpY2UpIElXaW5lRDNERGV2aWNlX1JlbGVhc2Uod2luZUQzRERldmljZSk7CiAgICBpZih3aW5lRDNEKSBJV2luZUQzRF9SZWxlYXNlKHdpbmVEM0QpOwogICAgaWYoVGhpcykgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+ZGVjbHMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3Q3JlYXRlIChERFJBVy5AKQogKgogKiBDcmVhdGVzIGxlZ2FjeSBEaXJlY3REcmF3IEludGVyZmFjZXMuIENhbid0IGNyZWF0ZSBJRGlyZWN0RHJhdzcKICogaW50ZXJmYWNlcyBpbiB0aGVvcnkKICoKICogQXJndW1lbnRzLCByZXR1cm4gdmFsdWVzOiBTZWUgRERSQVdfQ3JlYXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKRGlyZWN0RHJhd0NyZWF0ZShHVUlEICpHVUlELAogICAgICAgICAgICAgICAgIElEaXJlY3REcmF3ICoqREQsCiAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyKQp7CiAgICBUUkFDRSgiKCVzLCVwLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChHVUlEKSwgREQsIFVua091dGVyKTsKCiAgICByZXR1cm4gRERSQVdfQ3JlYXRlKEdVSUQsICh2b2lkICoqKSBERCwgVW5rT3V0ZXIsICZJSURfSURpcmVjdERyYXcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0NyZWF0ZUV4IChERFJBVy5AKQogKgogKiBPbmx5IGNyZWF0ZXMgbmV3IElEaXJlY3REcmF3NyBpbnRlcmZhY2VzLCBzdXBwb3NlZCB0byBmYWlsIGlmIGxlZ2FjeQogKiBpbnRlcmZhY2VzIGFyZSByZXF1ZXN0ZWQuCiAqCiAqIEFyZ3VtZW50cywgcmV0dXJuIHZhbHVlczogU2VlIEREUkFXX0NyZWF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdDcmVhdGVFeChHVUlEICpHVUlELAogICAgICAgICAgICAgICAgICAgdm9pZCAqKkRELAogICAgICAgICAgICAgICAgICAgUkVGSUlEIGlpZCwKICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlcikKewogICAgVFJBQ0UoIiglcywlcCwlcywlcClcbiIsIGRlYnVnc3RyX2d1aWQoR1VJRCksIERELCBkZWJ1Z3N0cl9ndWlkKGlpZCksIFVua091dGVyKTsKCiAgICBpZiAoIUlzRXF1YWxHVUlEKGlpZCwgJklJRF9JRGlyZWN0RHJhdzcpKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIHJldHVybiBERFJBV19DcmVhdGUoR1VJRCwgREQsIFVua091dGVyLCBpaWQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0VudW1lcmF0ZUEgKEREUkFXLkApCiAqCiAqIEVudW1lcmF0ZXMgbGVnYWN5IGRkcmF3IGRyaXZlcnMsIGFzY2lpIHZlcnNpb24uIFdlIG9ubHkgaGF2ZSBvbmUKICogZHJpdmVyLCB3aGljaCByZWxheXMgdG8gV2luZUQzRC4gSWYgd2Ugd2VyZSBzdWZmaWNpZW50bHkgY29vbCwKICogd2UgY291bGQgb2ZmZXIgdmFyaW91cyBpbnRlcmZhY2VzLCB3aGljaCB1c2UgYSBkaWZmZXJlbnQgZGVmYXVsdCBzdXJmYWNlCiAqIGltcGxlbWVudGF0aW9uLCBidXQgSSB0aGluayBpdCdzIGJldHRlciB0byBvZmZlciB0aGlzIGNob2ljZSBpbgogKiB3aW5lY2ZnLCBiZWNhdXNlIHNvbWUgYXBwcyB1c2UgdGhlIGRlZmF1bHQgZHJpdmVyLCBzbyB3ZSB3b3VsZCBuZWVkCiAqIGEgd2luZWNmZyBvcHRpb24gYW55d2F5LCBhbmQgdGhlcmUgc2hvdWxkbid0IGJlIDIgd2F5cyB0byBzZXQgb25lIHNldHRpbmcKICoKICogQXJndW1lbnRzOgogKiAgQ2FsbGJhY2s6IENhbGxiYWNrIGZ1bmN0aW9uIGZyb20gdGhlIGFwcAogKiAgQ29udGV4dDogQXJndW1lbnQgdG8gdGhlIGNhbGwgYmFjay4KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIEVfSU5WQUxJREFSRyBpZiB0aGUgQ2FsbGJhY2sgY2F1c2VkIGEgcGFnZSBmYXVsdAogKgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdFbnVtZXJhdGVBKExQRERFTlVNQ0FMTEJBQ0tBIENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICB2b2lkICpDb250ZXh0KQp7CiAgICBCT09MIHN0b3AgPSBGQUxTRTsKCiAgICBUUkFDRSgiIEVudW1lcmF0aW5nIGRlZmF1bHQgRGlyZWN0RHJhdyBIQUwgaW50ZXJmYWNlXG4iKTsKICAgIC8qIFdlIG9ubHkgaGF2ZSBvbmUgZHJpdmVyICovCiAgICBfX1RSWQogICAgewogICAgICAgIHN0YXRpYyBDSEFSIGRyaXZlcl9kZXNjW10gPSAiRGlyZWN0RHJhdyBIQUwiLAogICAgICAgIGRyaXZlcl9uYW1lW10gPSAiZGlzcGxheSI7CgogICAgICAgIHN0b3AgPSAhQ2FsbGJhY2soTlVMTCwgZHJpdmVyX2Rlc2MsIGRyaXZlcl9uYW1lLCBDb250ZXh0KTsKICAgIH0KICAgIF9fRVhDRVBUX1BBR0VfRkFVTFQKICAgIHsKICAgICAgICByZXR1cm4gRV9JTlZBTElEQVJHOwogICAgfQogICAgX19FTkRUUlkKCiAgICBUUkFDRSgiIEVuZCBvZiBlbnVtZXJhdGlvblxuIik7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3RW51bWVyYXRlRXhBIChERFJBVy5AKQogKgogKiBFbnVtZXJhdGVzIERpcmVjdERyYXc3IGRyaXZlcnMsIGFzY2lpIHZlcnNpb24uIFNlZQogKiB0aGUgY29tbWVudHMgYWJvdmUgRGlyZWN0RHJhd0VudW1lcmF0ZUEgZm9yIG1vcmUgZGV0YWlscy4KICoKICogVGhlIEZsYWcgbWVtYmVyIGlzIG5vdCBzdXBwb3J0ZWQgcmlnaHQgbm93LgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdFbnVtZXJhdGVFeEEoTFBEREVOVU1DQUxMQkFDS0VYQSBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpDb250ZXh0LAogICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzKQp7CiAgICBCT09MIHN0b3AgPSBGQUxTRTsKICAgIFRSQUNFKCJFbnVtZXJhdGluZyBkZWZhdWx0IERpcmVjdERyYXcgSEFMIGludGVyZmFjZVxuIik7CgogICAgLyogV2Ugb25seSBoYXZlIG9uZSBkcml2ZXIgYnkgbm93ICovCiAgICBfX1RSWQogICAgewogICAgICAgIHN0YXRpYyBDSEFSIGRyaXZlcl9kZXNjW10gPSAiRGlyZWN0RHJhdyBIQUwiLAogICAgICAgIGRyaXZlcl9uYW1lW10gPSAiZGlzcGxheSI7CgogICAgICAgIC8qIFF1aWNrVGltZSBleHBlY3RzIHRoZSBkZXNjcmlwdGlvbiAiRGlyZWN0RHJhdyBIQUwiICovCiAgICAgICAgc3RvcCA9ICFDYWxsYmFjayhOVUxMLCBkcml2ZXJfZGVzYywgZHJpdmVyX25hbWUsIENvbnRleHQsIDApOwogICAgfQogICAgX19FWENFUFRfUEFHRV9GQVVMVAogICAgewogICAgICAgIHJldHVybiBFX0lOVkFMSURBUkc7CiAgICB9CiAgICBfX0VORFRSWTsKCiAgICBUUkFDRSgiRW5kIG9mIGVudW1lcmF0aW9uXG4iKTsKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdFbnVtZXJhdGVXIChERFJBVy5AKQogKgogKiBFbnVtZXJhdGVzIGxlZ2FjeSBkcml2ZXJzLCB1bmljb2RlIHZlcnNpb24uIFNlZQogKiB0aGUgY29tbWVudHMgYWJvdmUgRGlyZWN0RHJhd0VudW1lcmF0ZUEgZm9yIG1vcmUgZGV0YWlscy4KICoKICogVGhlIEZsYWcgbWVtYmVyIGlzIG5vdCBzdXBwb3J0ZWQgcmlnaHQgbm93LgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0VudW1lcmF0ZUV4VyAoRERSQVcuQCkKICoKICogRW51bWVyYXRlcyBEaXJlY3REcmF3NyBkcml2ZXJzLCB1bmljb2RlIHZlcnNpb24uIFNlZQogKiB0aGUgY29tbWVudHMgYWJvdmUgRGlyZWN0RHJhd0VudW1lcmF0ZUEgZm9yIG1vcmUgZGV0YWlscy4KICoKICogVGhlIEZsYWcgbWVtYmVyIGlzIG5vdCBzdXBwb3J0ZWQgcmlnaHQgbm93LgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ2xhc3NmYWN0b3J5IGltcGxlbWVudGF0aW9uLgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ0ZfQ3JlYXRlRGlyZWN0RHJhdwogKgogKiBERHJhdyBjcmVhdGlvbiBmdW5jdGlvbiBmb3IgdGhlIGNsYXNzIGZhY3RvcnkKICoKICogUGFyYW1zOgogKiAgVW5rT3V0ZXI6IFNldCB0byBOVUxMCiAqICBpaWQ6IElEIG9mIHRoZSB3YW50ZWQgaW50ZXJmYWNlCiAqICBvYmo6IEFkZHJlc3MgdG8gcGFzcyB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYmFjawogKgogKiBSZXR1cm5zCiAqICBERF9PSyAvIERERVJSKiwgc2VlIEREUkFXX0NyZWF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCkNGX0NyZWF0ZURpcmVjdERyYXcoSVVua25vd24qIFVua091dGVyLCBSRUZJSUQgaWlkLAogICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIEhSRVNVTFQgaHI7CgogICAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFVua091dGVyLCBkZWJ1Z3N0cl9ndWlkKGlpZCksIG9iaik7CgogICAgaHIgPSBERFJBV19DcmVhdGUoTlVMTCwgb2JqLCBVbmtPdXRlciwgaWlkKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENGX0NyZWF0ZURpcmVjdERyYXcKICoKICogQ2xpcHBlciBjcmVhdGlvbiBmdW5jdGlvbiBmb3IgdGhlIGNsYXNzIGZhY3RvcnkKICoKICogUGFyYW1zOgogKiAgVW5rT3V0ZXI6IFNldCB0byBOVUxMCiAqICBpaWQ6IElEIG9mIHRoZSB3YW50ZWQgaW50ZXJmYWNlCiAqICBvYmo6IEFkZHJlc3MgdG8gcGFzcyB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYmFjawogKgogKiBSZXR1cm5zCiAqICBERF9PSyAvIERERVJSKiwgc2VlIEREUkFXX0NyZWF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCkNGX0NyZWF0ZURpcmVjdERyYXdDbGlwcGVyKElVbmtub3duKiBVbmtPdXRlciwgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIEhSRVNVTFQgaHI7CiAgICBJRGlyZWN0RHJhd0NsaXBwZXIgKkNsaXA7CgogICAgaHIgPSBEaXJlY3REcmF3Q3JlYXRlQ2xpcHBlcigwLCAmQ2xpcCwgVW5rT3V0ZXIpOwogICAgaWYgKGhyICE9IEREX09LKSByZXR1cm4gaHI7CgogICAgaHIgPSBJRGlyZWN0RHJhd0NsaXBwZXJfUXVlcnlJbnRlcmZhY2UoQ2xpcCwgcmlpZCwgb2JqKTsKICAgIElEaXJlY3REcmF3Q2xpcHBlcl9SZWxlYXNlKENsaXApOwogICAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IG9iamVjdF9jcmVhdGlvbl9pbmZvIG9iamVjdF9jcmVhdGlvbltdID0KewogICAgeyAmQ0xTSURfRGlyZWN0RHJhdywgICAgICAgIENGX0NyZWF0ZURpcmVjdERyYXcgfSwKICAgIHsgJkNMU0lEX0RpcmVjdERyYXc3LCAgICAgICBDRl9DcmVhdGVEaXJlY3REcmF3IH0sCiAgICB7ICZDTFNJRF9EaXJlY3REcmF3Q2xpcHBlciwgQ0ZfQ3JlYXRlRGlyZWN0RHJhd0NsaXBwZXIgfQp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdDbGFzc0ZhY3Rvcnk6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIFF1ZXJ5SW50ZXJmYWNlIGZvciB0aGUgY2xhc3MgZmFjdG9yeQogKgogKiBQQVJBTVMKICogICAgcmlpZCAgIFJlZmVyZW5jZSB0byBpZGVudGlmaWVyIG9mIHF1ZXJpZWQgaW50ZXJmYWNlCiAqICAgIHBwdiAgICBBZGRyZXNzIHRvIHJldHVybiB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYXQKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTX09LCiAqICAgIEZhaWx1cmU6IEVfTk9JTlRFUkZBQ0UKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfUXVlcnlJbnRlcmZhY2UoSUNsYXNzRmFjdG9yeSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSUNsYXNzRmFjdG9yeUltcGwsIElDbGFzc0ZhY3RvcnksIGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgb2JqKTsKCiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lDbGFzc0ZhY3RvcnkpKQogICAgewogICAgICAgIElDbGFzc0ZhY3RvcnlfQWRkUmVmKGlmYWNlKTsKICAgICAgICAqb2JqID0gVGhpczsKICAgICAgICByZXR1cm4gU19PSzsKICAgIH0KCiAgICBXQVJOKCIoJXApLT4oJXMsJXApLG5vdCBmb3VuZFxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmlpZCksb2JqKTsKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeTo6QWRkUmVmCiAqCiAqIEFkZFJlZiBmb3IgdGhlIGNsYXNzIGZhY3RvcnkKICoKICogUkVUVVJOUwogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfQWRkUmVmKElDbGFzc0ZhY3RvcnkgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJQ2xhc3NGYWN0b3J5SW1wbCwgSUNsYXNzRmFjdG9yeSwgaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogICAgVFJBQ0UoIiglcCktPigpIGluY3JlbWVudGluZyBmcm9tICVkLlxuIiwgVGhpcywgcmVmIC0gMSk7CgogICAgcmV0dXJuIHJlZjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdDbGFzc0ZhY3Rvcnk6OlJlbGVhc2UKICoKICogUmVsZWFzZSBmb3IgdGhlIGNsYXNzIGZhY3RvcnkuIElmIHRoZSByZWZjb3VudCBmYWxscyB0byAwLCB0aGUgb2JqZWN0CiAqIGlzIGRlc3Ryb3llZAogKgogKiBSRVRVUk5TCiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9SZWxlYXNlKElDbGFzc0ZhY3RvcnkgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJQ2xhc3NGYWN0b3J5SW1wbCwgSUNsYXNzRmFjdG9yeSwgaWZhY2UpOwogICAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CiAgICBUUkFDRSgiKCVwKS0+KCkgZGVjcmVtZW50aW5nIGZyb20gJWQuXG4iLCBUaGlzLCByZWYrMSk7CgogICAgaWYgKHJlZiA9PSAwKQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMpOwoKICAgIHJldHVybiByZWY7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeTo6Q3JlYXRlSW5zdGFuY2UKICoKICogV2hhdCBpcyB0aGlzPyBTZWVtcyB0byBjcmVhdGUgRGlyZWN0RHJhdyBvYmplY3RzLi4uCiAqCiAqIFBhcmFtcwogKiAgVGhlIHVzdXNhbCB0aGluZ3M/Pz8KICoKICogUkVUVVJOUwogKiAgPz8/CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0NyZWF0ZUluc3RhbmNlKElDbGFzc0ZhY3RvcnkgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBJQ09NX1RISVNfRlJPTShJQ2xhc3NGYWN0b3J5SW1wbCwgSUNsYXNzRmFjdG9yeSwgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXMsJXApXG4iLFRoaXMsVW5rT3V0ZXIsZGVidWdzdHJfZ3VpZChyaWlkKSxvYmopOwoKICAgIHJldHVybiBUaGlzLT5wZm5DcmVhdGVJbnN0YW5jZShVbmtPdXRlciwgcmlpZCwgb2JqKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdDbGFzc0ZhY3Rvcnk6OkxvY2tTZXJ2ZXIKICoKICogV2hhdCBpcyB0aGlzPwogKgogKiBQYXJhbXMKICogID8/PwogKgogKiBSRVRVUk5TCiAqICBTX09LLCBiZWNhdXNlIGl0J3MgYSBzdHViCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0xvY2tTZXJ2ZXIoSUNsYXNzRmFjdG9yeSAqaWZhY2UsQk9PTCBkb2xvY2spCnsKICAgIElDT01fVEhJU19GUk9NKElDbGFzc0ZhY3RvcnlJbXBsLCBJQ2xhc3NGYWN0b3J5LCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCVkKSxzdHViIVxuIixUaGlzLGRvbG9jayk7CiAgICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIGNsYXNzIGZhY3RvcnkgVlRhYmxlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgY29uc3QgSUNsYXNzRmFjdG9yeVZ0YmwgSUNsYXNzRmFjdG9yeV9WdGJsID0KewogICAgSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0FkZFJlZiwKICAgIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9SZWxlYXNlLAogICAgSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0NyZWF0ZUluc3RhbmNlLAogICAgSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0xvY2tTZXJ2ZXIKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERsbEdldENsYXNzT2JqZWN0IFtERFJBVy5AXQogKiBSZXRyaWV2ZXMgY2xhc3Mgb2JqZWN0IGZyb20gYSBETEwgb2JqZWN0CiAqCiAqIE5PVEVTCiAqICAgIERvY3Mgc2F5IHJldHVybnMgU1REQVBJCiAqCiAqIFBBUkFNUwogKiAgICByY2xzaWQgW0ldIENMU0lEIGZvciB0aGUgY2xhc3Mgb2JqZWN0CiAqICAgIHJpaWQgICBbSV0gUmVmZXJlbmNlIHRvIGlkZW50aWZpZXIgb2YgaW50ZXJmYWNlIGZvciBjbGFzcyBvYmplY3QKICogICAgcHB2ICAgIFtPXSBBZGRyZXNzIG9mIHZhcmlhYmxlIHRvIHJlY2VpdmUgaW50ZXJmYWNlIHBvaW50ZXIgZm9yIHJpaWQKICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTX09LCiAqICAgIEZhaWx1cmU6IENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEUsIEVfT1VUT0ZNRU1PUlksIEVfSU5WQUxJREFSRywKICogICAgICAgICAgICAgRV9VTkVYUEVDVEVECiAqLwpIUkVTVUxUIFdJTkFQSSBEbGxHZXRDbGFzc09iamVjdChSRUZDTFNJRCByY2xzaWQsIFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogICAgdW5zaWduZWQgaW50IGk7CiAgICBJQ2xhc3NGYWN0b3J5SW1wbCAqZmFjdG9yeTsKCiAgICBUUkFDRSgiKCVzLCVzLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHYpOwoKICAgIGlmICggIUlzRXF1YWxHVUlEKCAmSUlEX0lDbGFzc0ZhY3RvcnksIHJpaWQgKQoJICYmICEgSXNFcXVhbEdVSUQoICZJSURfSVVua25vd24sIHJpaWQpICkKCXJldHVybiBFX05PSU5URVJGQUNFOwoKICAgIGZvciAoaT0wOyBpIDwgc2l6ZW9mKG9iamVjdF9jcmVhdGlvbikvc2l6ZW9mKG9iamVjdF9jcmVhdGlvblswXSk7IGkrKykKICAgIHsKCWlmIChJc0VxdWFsR1VJRChvYmplY3RfY3JlYXRpb25baV0uY2xzaWQsIHJjbHNpZCkpCgkgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGkgPT0gc2l6ZW9mKG9iamVjdF9jcmVhdGlvbikvc2l6ZW9mKG9iamVjdF9jcmVhdGlvblswXSkpCiAgICB7CglGSVhNRSgiJXM6IG5vIGNsYXNzIGZvdW5kLlxuIiwgZGVidWdzdHJfZ3VpZChyY2xzaWQpKTsKCXJldHVybiBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFOwogICAgfQoKICAgIGZhY3RvcnkgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCpmYWN0b3J5KSk7CiAgICBpZiAoZmFjdG9yeSA9PSBOVUxMKSByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKGZhY3RvcnksIElDbGFzc0ZhY3RvcnksIElDbGFzc0ZhY3RvcnlfVnRibCk7CiAgICBmYWN0b3J5LT5yZWYgPSAxOwoKICAgIGZhY3RvcnktPnBmbkNyZWF0ZUluc3RhbmNlID0gb2JqZWN0X2NyZWF0aW9uW2ldLnBmbkNyZWF0ZUluc3RhbmNlOwoKICAgICpwcHYgPSBJQ09NX0lOVEVSRkFDRShmYWN0b3J5LCBJQ2xhc3NGYWN0b3J5KTsKICAgIHJldHVybiBTX09LOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGxsQ2FuVW5sb2FkTm93IFtERFJBVy5AXSAgRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBETEwgaXMgaW4gdXNlLgogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFNfT0sKICogICAgRmFpbHVyZTogU19GQUxTRQogKi8KSFJFU1VMVCBXSU5BUEkgRGxsQ2FuVW5sb2FkTm93KHZvaWQpCnsKICAgIEZJWE1FKCIodm9pZCk6IHN0dWJcbiIpOwogICAgcmV0dXJuIFNfRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERlc3Ryb3lDYWxsYmFjawogKgogKiBDYWxsYmFjayBmdW5jdGlvbiBmb3IgdGhlIEVudW1TdXJmYWNlcyBjYWxsIGluIERsbE1haW4uCiAqIER1bXBzIHNvbWUgc3VyZmFjZSBpbmZvIGFuZCByZWxlYXNlcyB0aGUgc3VyZmFjZQogKgogKiBQYXJhbXM6CiAqICBzdXJmOiBUaGUgZW51bWVyYXRlZCBzdXJmYWNlCiAqICBkZXNjOiBpdCdzIGRlc2NyaXB0aW9uCiAqICBjb250ZXh0OiBQb2ludGVyIHRvIHRoZSBkZHJhdyBpbXBsCiAqCiAqIFJldHVybnM6CiAqICBEREVOVU1SRVRfT0s7CiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKRGVzdHJveUNhbGxiYWNrKElEaXJlY3REcmF3U3VyZmFjZTcgKnN1cmYsCiAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiAqZGVzYywKICAgICAgICAgICAgICAgIHZvaWQgKmNvbnRleHQpCnsKICAgIElEaXJlY3REcmF3U3VyZmFjZUltcGwgKkltcGwgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBzdXJmKTsKICAgIElEaXJlY3REcmF3SW1wbCAqZGRyYXcgPSAoSURpcmVjdERyYXdJbXBsICopIGNvbnRleHQ7CiAgICBVTE9ORyByZWY7CgogICAgcmVmID0gSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKHN1cmYpOyAgLyogRm9yIHRoZSBFbnVtU3VyZmFjZXMgKi8KICAgIFdBUk4oIlN1cmZhY2UgJXAgaGFzIGFuIHJlZmVyZW5jZSBjb3VudCBvZiAlZFxuIiwgSW1wbCwgcmVmKTsKCiAgICAvKiBTa2lwIHN1cmZhY2VzIHdoaWNoIGFyZSBhdHRhY2hlZCBzb21ld2hlcmUgb3Igd2hpY2ggYXJlCiAgICAgKiBwYXJ0IG9mIGEgY29tcGxleCBjb21wb3VuZC4gVGhleSB3aWxsIGdldCByZWxlYXNlZCB3aGVuIGRlc3Ryb3lpbmcKICAgICAqIHRoZSByb290CiAgICAgKi8KICAgIGlmKCAoIUltcGwtPmlzX2NvbXBsZXhfcm9vdCkgfHwgKEltcGwtPmZpcnN0X2F0dGFjaGVkICE9IEltcGwpICkKICAgICAgICByZXR1cm4gRERFTlVNUkVUX09LOwogICAgLyogU2tpcCBvdXIgZGVwdGggc3RlbmNpbCBzdXJmYWNlLCBpdCB3aWxsIGJlIHJlbGVhc2VkIHdpdGggdGhlIHJlbmRlciB0YXJnZXQgKi8KICAgIGlmKCBJbXBsID09IGRkcmF3LT5EZXB0aFN0ZW5jaWxCdWZmZXIpCiAgICAgICAgcmV0dXJuIERERU5VTVJFVF9PSzsKCiAgICAvKiBEZXN0cm95IHRoZSBzdXJmYWNlICovCiAgICB3aGlsZShyZWYpIHJlZiA9IElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShzdXJmKTsKCiAgICByZXR1cm4gRERFTlVNUkVUX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogZ2V0X2NvbmZpZ19rZXkKICoKICogUmVhZHMgYSBjb25maWcga2V5IGZyb20gdGhlIHJlZ2lzdHJ5LiBUYWtlbiBmcm9tIFdpbmVEM0QKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgaW5saW5lIERXT1JEIGdldF9jb25maWdfa2V5KEhLRVkgZGVma2V5LCBIS0VZIGFwcGtleSwgY29uc3QgY2hhciogbmFtZSwgY2hhciogYnVmZmVyLCBEV09SRCBzaXplKQp7CiAgICBpZiAoMCAhPSBhcHBrZXkgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoIGFwcGtleSwgbmFtZSwgMCwgTlVMTCwgKExQQllURSkgYnVmZmVyLCAmc2l6ZSApKSByZXR1cm4gMDsKICAgIGlmICgwICE9IGRlZmtleSAmJiAhUmVnUXVlcnlWYWx1ZUV4QSggZGVma2V5LCBuYW1lLCAwLCBOVUxMLCAoTFBCWVRFKSBidWZmZXIsICZzaXplICkpIHJldHVybiAwOwogICAgcmV0dXJuIEVSUk9SX0ZJTEVfTk9UX0ZPVU5EOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGxsTWFpbiAoRERSQVcuMCkKICoKICogQ291bGQgYmUgdXNlZCB0byByZWdpc3RlciBEaXJlY3REcmF3IGRyaXZlcnMsIGlmIHdlIGhhdmUgbW9yZSB0aGFuCiAqIG9uZS4gQWxzbyB1c2VkIHRvIGRlc3Ryb3kgYW55IG9iamVjdHMgbGVmdCBhdCB1bmxvYWQgaWYgdGhlCiAqIGFwcCBkaWRuJ3QgcmVsZWFzZSB0aGVtIHByb3Blcmx5KEdvdGhpYyAyLCBEaWFibG8gMiwgTW90byByYWNlciwgLi4uKQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkJPT0wgV0lOQVBJCkRsbE1haW4oSElOU1RBTkNFIGhJbnN0RExMLAogICAgICAgIERXT1JEIFJlYXNvbiwKICAgICAgICB2b2lkICpscHYpCnsKICAgIFRSQUNFKCIoJXAsJXgsJXApXG4iLCBoSW5zdERMTCwgUmVhc29uLCBscHYpOwogICAgaWYgKFJlYXNvbiA9PSBETExfUFJPQ0VTU19BVFRBQ0gpCiAgICB7CiAgICAgICAgY2hhciBidWZmZXJbTUFYX1BBVEgrMTBdOwogICAgICAgIERXT1JEIHNpemUgPSBzaXplb2YoYnVmZmVyKTsKICAgICAgICBIS0VZIGhrZXkgPSAwOwogICAgICAgIEhLRVkgYXBwa2V5ID0gMDsKICAgICAgICBEV09SRCBsZW47CgogICAgICAgLyogQEAgV2luZSByZWdpc3RyeSBrZXk6IEhLQ1VcU29mdHdhcmVcV2luZVxEaXJlY3QzRCAqLwogICAgICAgaWYgKCBSZWdPcGVuS2V5QSggSEtFWV9DVVJSRU5UX1VTRVIsICJTb2Z0d2FyZVxcV2luZVxcRGlyZWN0M0QiLCAmaGtleSApICkgaGtleSA9IDA7CgogICAgICAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVBKCAwLCBidWZmZXIsIE1BWF9QQVRIICk7CiAgICAgICBpZiAobGVuICYmIGxlbiA8IE1BWF9QQVRIKQogICAgICAgewogICAgICAgICAgICBIS0VZIHRtcGtleTsKICAgICAgICAgICAgLyogQEAgV2luZSByZWdpc3RyeSBrZXk6IEhLQ1VcU29mdHdhcmVcV2luZVxBcHBEZWZhdWx0c1xhcHAuZXhlXERpcmVjdDNEICovCiAgICAgICAgICAgIGlmICghUmVnT3BlbktleUEoIEhLRVlfQ1VSUkVOVF9VU0VSLCAiU29mdHdhcmVcXFdpbmVcXEFwcERlZmF1bHRzIiwgJnRtcGtleSApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjaGFyICpwLCAqYXBwbmFtZSA9IGJ1ZmZlcjsKICAgICAgICAgICAgICAgIGlmICgocCA9IHN0cnJjaHIoIGFwcG5hbWUsICcvJyApKSkgYXBwbmFtZSA9IHAgKyAxOwogICAgICAgICAgICAgICAgaWYgKChwID0gc3RycmNociggYXBwbmFtZSwgJ1xcJyApKSkgYXBwbmFtZSA9IHAgKyAxOwogICAgICAgICAgICAgICAgc3RyY2F0KCBhcHBuYW1lLCAiXFxEaXJlY3QzRCIgKTsKICAgICAgICAgICAgICAgIFRSQUNFKCJhcHBuYW1lID0gWyVzXVxuIiwgYXBwbmFtZSk7CiAgICAgICAgICAgICAgICBpZiAoUmVnT3BlbktleUEoIHRtcGtleSwgYXBwbmFtZSwgJmFwcGtleSApKSBhcHBrZXkgPSAwOwogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoIHRtcGtleSApOwogICAgICAgICAgICB9CiAgICAgICB9CgogICAgICAgaWYgKCAwICE9IGhrZXkgfHwgMCAhPSBhcHBrZXkgKQogICAgICAgewogICAgICAgICAgICBpZiAoICFnZXRfY29uZmlnX2tleSggaGtleSwgYXBwa2V5LCAiRGlyZWN0RHJhd1JlbmRlcmVyIiwgYnVmZmVyLCBzaXplKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3RyY21wKGJ1ZmZlciwiZ2RpIikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkRlZmF1bHRpbmcgdG8gR0RJIHN1cmZhY2VzXG4iKTsKICAgICAgICAgICAgICAgICAgICBEZWZhdWx0U3VyZmFjZVR5cGUgPSBTVVJGQUNFX0dESTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoYnVmZmVyLCJvcGVuZ2wiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiRGVmYXVsdGluZyB0byBvcGVuZ2wgc3VyZmFjZXNcbiIpOwogICAgICAgICAgICAgICAgICAgIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfT1BFTkdMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEVSUigiVW5rbm93biBkZWZhdWx0IHN1cmZhY2UgdHlwZS4gU3VwcG9ydGVkIGFyZTpcbiBnZGksIG9wZW5nbFxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoaEluc3RETEwpOwogICAgfQogICAgZWxzZSBpZiAoUmVhc29uID09IERMTF9QUk9DRVNTX0RFVEFDSCkKICAgIHsKICAgICAgICBpZighbGlzdF9lbXB0eSgmZ2xvYmFsX2RkcmF3X2xpc3QpKQogICAgICAgIHsKICAgICAgICAgICAgc3RydWN0IGxpc3QgKmVudHJ5LCAqZW50cnkyOwogICAgICAgICAgICBXQVJOKCJUaGVyZSBhcmUgc3RpbGwgZXhpc3RpbmcgRGlyZWN0RHJhdyBpbnRlcmZhY2VzLiBXaW5lIGJ1ZyBvciBidWdneSBhcHBsaWNhdGlvbj9cbiIpOwoKICAgICAgICAgICAgLyogV2UgcmVtb3ZlIGVsZW1ldHMgZnJvbSB0aGlzIGxvb3AgKi8KICAgICAgICAgICAgTElTVF9GT1JfRUFDSF9TQUZFKGVudHJ5LCBlbnRyeTIsICZnbG9iYWxfZGRyYXdfbGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSFJFU1VMVCBocjsKICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyIGRlc2M7CiAgICAgICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbCAqZGRyYXcgPSBMSVNUX0VOVFJZKGVudHJ5LCBJRGlyZWN0RHJhd0ltcGwsIGRkcmF3X2xpc3RfZW50cnkpOwoKICAgICAgICAgICAgICAgIFdBUk4oIkREcmF3ICVwIGhhcyBhIHJlZmNvdW50IG9mICVkXG4iLCBkZHJhdywgZGRyYXctPnJlZjcgKyBkZHJhdy0+cmVmNCArIGRkcmF3LT5yZWYzICsgZGRyYXctPnJlZjIgKyBkZHJhdy0+cmVmMSk7CgogICAgICAgICAgICAgICAgLyogQWRkIHJlZmVyZW5jZXMgdG8gZWFjaCBpbnRlcmZhY2UgdG8gYXZvaWQgZnJlZWluZyB0aGVtIHVuZXhwZWN0YWRlbHkgKi8KICAgICAgICAgICAgICAgIElEaXJlY3REcmF3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXcpKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3Ml9BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3MikpOwogICAgICAgICAgICAgICAgSURpcmVjdERyYXczX0FkZFJlZihJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXczKSk7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhdzRfQWRkUmVmKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzQpKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3N19BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3NykpOwoKICAgICAgICAgICAgICAgIC8qIERvZXMgYSBEM0QgZGV2aWNlIGV4aXN0PyBEZXN0cm95IGl0CiAgICAgICAgICAgICAgICAgICAgKiBUT0RPOiBEZXN0cm95IGFsbCBWZXJ0ZXggYnVmZmVycywgTGlnaHRzLCBNYXRlcmlhbHMKICAgICAgICAgICAgICAgICAgICAqIGFuZCBleGVjdHVyZSBidWZmZXJzIHRvbwogICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZihkZHJhdy0+ZDNkZGV2aWNlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkREcmF3ICVwIGhhcyBkM2RkZXZpY2UgJXAgYXR0YWNoZWRcbiIsIGRkcmF3LCBkZHJhdy0+ZDNkZGV2aWNlKTsKICAgICAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0M0REZXZpY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGRyYXctPmQzZGRldmljZSwgSURpcmVjdDNERGV2aWNlNykpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBUcnkgdG8gcmVsZWFzZSB0aGUgb2JqZWN0cwogICAgICAgICAgICAgICAgICAgICogRG8gYW4gRW51bVN1cmZhY2VzIHRvIGZpbmQgYW55IGhhbmdpbmcgc3VyZmFjZXMKICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgbWVtc2V0KCZkZXNjLCAwLCBzaXplb2YoZGVzYykpOwogICAgICAgICAgICAgICAgZGVzYy5kd1NpemUgPSBzaXplb2YoZGVzYyk7CiAgICAgICAgICAgICAgICBmb3IoaSA9IDA7IGkgPD0gMTsgaSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGhyID0gSURpcmVjdERyYXc3X0VudW1TdXJmYWNlcyhJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXc3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERERU5VTVNVUkZBQ0VTX0FMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKikgZGRyYXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXN0cm95Q2FsbGJhY2spOwogICAgICAgICAgICAgICAgICAgIGlmKGhyICE9IEQzRF9PSykKICAgICAgICAgICAgICAgICAgICAgICAgRVJSKCIoJXApIEVudW1TdXJmYWNlcyBmYWlsZWQsIHByZXBhcmUgZm9yIHRyb3VibGVcbiIsIGRkcmF3KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBDaGVjayB0aGUgc3VyZmFjZSBjb3VudCAqLwogICAgICAgICAgICAgICAgaWYoZGRyYXctPnN1cmZhY2VzID4gMCkKICAgICAgICAgICAgICAgICAgICBFUlIoIkREcmF3ICVwIHN0aWxsIGhhcyAlZCBzdXJmYWNlcyBhdHRhY2hlZFxuIiwgZGRyYXcsIGRkcmF3LT5zdXJmYWNlcyk7CgogICAgICAgICAgICAgICAgLyogUmVsZWFzZSBhbGwgaGFuZ2luZyByZWZlcmVuY2VzIHRvIGRlc3Ryb3kgdGhlIG9iamVjdHMuIFRoaXMKICAgICAgICAgICAgICAgICAgICAqIHJlc3RvcmVzIHRoZSBzY3JlZW4gbW9kZSB0b28KICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgd2hpbGUoSURpcmVjdERyYXdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXcpKSk7CiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhdzJfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXcyKSkpOwogICAgICAgICAgICAgICAgd2hpbGUoSURpcmVjdERyYXczX1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3MykpKTsKICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3REcmF3NF9SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzQpKSk7CiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhdzdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXc3KSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBUUlVFOwp9Cgp2b2lkCnJlbW92ZV9kZHJhd19vYmplY3QoSURpcmVjdERyYXdJbXBsICpkZHJhdykKewogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2xpc3RfY3MpOwogICAgbGlzdF9yZW1vdmUoJmRkcmF3LT5kZHJhd19saXN0X2VudHJ5KTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19saXN0X2NzKTsKfQo=