LyogICAgICAgIERpcmVjdERyYXcgQmFzZSBGdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTctMTk5OSBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqIENvcHlyaWdodCAyMDA4IERlbnZlciBHaW5nZXJpY2gKICoKICogVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSAoaW50ZXJuYWwpIGRyaXZlciByZWdpc3RyYXRpb24gZnVuY3Rpb25zLAogKiBkcml2ZXIgZW51bWVyYXRpb24gQVBJcyBhbmQgRGlyZWN0RHJhdyBjcmVhdGlvbiBmdW5jdGlvbnMuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgoKI2RlZmluZSBDT0JKTUFDUk9TCgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2luZ2RpLmgiCiNpbmNsdWRlICJ3aW5lL2V4Y2VwdGlvbi5oIgojaW5jbHVkZSAid2lucmVnLmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKCnR5cGVkZWYgSVdpbmVEM0QqIChXSU5BUEkgKmZuV2luZURpcmVjdDNEQ3JlYXRlKShVSU5ULCBVSU5ULCBJVW5rbm93biAqKTsKCnN0YXRpYyBITU9EVUxFIGhXaW5lRDNEID0gKEhNT0RVTEUpIC0xOwpzdGF0aWMgZm5XaW5lRGlyZWN0M0RDcmVhdGUgcFdpbmVEaXJlY3QzRENyZWF0ZTsKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KTsKCi8qIFRoZSBjb25maWd1cmVkIGRlZmF1bHQgc3VyZmFjZSAqLwpXSU5FRDNEU1VSRlRZUEUgRGVmYXVsdFN1cmZhY2VUeXBlID0gU1VSRkFDRV9VTktOT1dOOwoKLyogRERyYXcgbGlzdCBhbmQgY3JpdGljYWwgc2VjdGlvbiAqLwpzdGF0aWMgc3RydWN0IGxpc3QgZ2xvYmFsX2RkcmF3X2xpc3QgPSBMSVNUX0lOSVQoZ2xvYmFsX2RkcmF3X2xpc3QpOwoKc3RhdGljIENSSVRJQ0FMX1NFQ1RJT05fREVCVUcgZGRyYXdfY3NfZGVidWcgPQp7CiAgICAwLCAwLCAmZGRyYXdfY3MsCiAgICB7ICZkZHJhd19jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0LAogICAgJmRkcmF3X2NzX2RlYnVnLlByb2Nlc3NMb2Nrc0xpc3QgfSwKICAgIDAsIDAsIHsgKERXT1JEX1BUUikoX19GSUxFX18gIjogZGRyYXdfY3MiKSB9Cn07CkNSSVRJQ0FMX1NFQ1RJT04gZGRyYXdfY3MgPSB7ICZkZHJhd19jc19kZWJ1ZywgLTEsIDAsIDAsIDAsIDAgfTsKCi8qIHZhbHVlIG9mIEZvcmNlUmVmcmVzaFJhdGUgKi8KRFdPUkQgZm9yY2VfcmVmcmVzaF9yYXRlID0gMDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBIZWxwZXIgZnVuY3Rpb24gZm9yIERpcmVjdERyYXdDcmVhdGUgYW5kIGZyaWVuZHMKICogQ3JlYXRlcyBhIG5ldyBERHJhdyBpbnRlcmZhY2Ugd2l0aCB0aGUgZ2l2ZW4gUkVGSUlECiAqCiAqIEludGVyZmFjZXMgdGhhdCBjYW4gYmUgY3JlYXRlZDoKICogIElEaXJlY3REcmF3LCBJRGlyZWN0RHJhdzIsIElEaXJlY3REcmF3NCwgSURpcmVjdERyYXc3CiAqICBJRGlyZWN0M0QsIElEaXJlY3QzRDIsIElEaXJlY3QzRDMsIElEaXJlY3QzRDcuIChEb2VzIFdpbmRvd3MgcmV0dXJuCiAqICBJRGlyZWN0M0QgaW50ZXJmYWNlcz8pCiAqCiAqIEFyZ3VtZW50czoKICogIGd1aWQ6IElEIG9mIHRoZSByZXF1ZXN0ZWQgZHJpdmVyLCBOVUxMIGZvciB0aGUgZGVmYXVsdCBkcml2ZXIuCiAqICAgICAgICBUaGUgR1VJRCBjYW4gYmUgcXVlcmllZCB3aXRoIERpcmVjdERyYXdFbnVtZXJhdGUoRXgpQS9XCiAqICBERDogVXNlZCB0byByZXR1cm4gdGhlIHBvaW50ZXIgdG8gdGhlIGNyZWF0ZWQgb2JqZWN0CiAqICBVbmtPdXRlcjogRm9yIGFnZ3JlZ2F0aW9uLCB3aGljaCBpcyB1bnN1cHBvcnRlZC4gTXVzdCBiZSBOVUxMCiAqICBpaWQ6IHJlcXVlc3RlZCB2ZXJzaW9uIElELgogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgaWYgdGhlIEludGVyZmFjZSB3YXMgY3JlYXRlZCBzdWNjZXNzZnVsbHkKICogIENMQVNTX0VfTk9BR0dSRUdBVElPTiBpZiBVbmtPdXRlciBpcyBub3QgTlVMTAogKiAgRV9PVVRPRk1FTU9SWSBpZiBzb21lIGFsbG9jYXRpb24gZmFpbGVkCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKRERSQVdfQ3JlYXRlKGNvbnN0IEdVSUQgKmd1aWQsCiAgICAgICAgICAgICB2b2lkICoqREQsCiAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIsCiAgICAgICAgICAgICBSRUZJSUQgaWlkKQp7CiAgICBJRGlyZWN0RHJhd0ltcGwgKlRoaXMgPSBOVUxMOwogICAgSFJFU1VMVCBocjsKICAgIElXaW5lRDNEICp3aW5lRDNEID0gTlVMTDsKICAgIElXaW5lRDNERGV2aWNlICp3aW5lRDNERGV2aWNlID0gTlVMTDsKICAgIEhEQyBoREM7CiAgICBXSU5FRDNEREVWVFlQRSBkZXZpY2V0eXBlOwoKICAgIFRSQUNFKCIoJXMsJXAsJXApXG4iLCBkZWJ1Z3N0cl9ndWlkKGd1aWQpLCBERCwgVW5rT3V0ZXIpOwoKICAgICpERCA9IE5VTEw7CgogICAgLyogV2UgZG9uJ3QgY2FyZSBhYm91dCB0aGlzIGd1aWRzLiBXZWxsLCB0aGVyZSdzIG5vIHNwZWNpYWwgZ3VpZCBhbnl3YXkKICAgICAqIE9LLCB3ZSBjb3VsZAogICAgICovCiAgICBpZiAoZ3VpZCA9PSAoR1VJRCAqKSBERENSRUFURV9FTVVMQVRJT05PTkxZKQogICAgewogICAgICAgIC8qIFVzZSB0aGUgcmVmZXJlbmNlIGRldmljZSBpZC4gVGhpcyBkb2Vzbid0IGFjdHVhbGx5IGNoYW5nZSBhbnl0aGluZywKICAgICAgICAgKiBXaW5lRDNEIGFsd2F5cyB1c2VzIE9wZW5HTCBmb3IgRDNEIHJlbmRlcmluZy4gT25lIGNvdWxkIG1ha2UgaXQgcmVxdWVzdAogICAgICAgICAqIGluZGlyZWN0IHJlbmRlcmluZwogICAgICAgICAqLwogICAgICAgIGRldmljZXR5cGUgPSBXSU5FRDNEREVWVFlQRV9SRUY7CiAgICB9CiAgICBlbHNlIGlmKGd1aWQgPT0gKEdVSUQgKikgRERDUkVBVEVfSEFSRFdBUkVPTkxZKQogICAgewogICAgICAgIGRldmljZXR5cGUgPSBXSU5FRDNEREVWVFlQRV9IQUw7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgZGV2aWNldHlwZSA9IDA7CiAgICB9CgogICAgLyogRERyYXcgZG9lc24ndCBzdXBwb3J0IGFnZ3JlZ2F0aW9uLCBhY2NvcmRpbmcgdG8gbXNkbiAqLwogICAgaWYgKFVua091dGVyICE9IE5VTEwpCiAgICAgICAgcmV0dXJuIENMQVNTX0VfTk9BR0dSRUdBVElPTjsKCiAgICAvKiBEaXJlY3REcmF3IGNyZWF0aW9uIGNvbWVzIGhlcmUgKi8KICAgIFRoaXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElEaXJlY3REcmF3SW1wbCkpOwogICAgaWYoIVRoaXMpCiAgICB7CiAgICAgICAgRVJSKCJPdXQgb2YgbWVtb3J5IHdoZW4gY3JlYXRpbmcgRGlyZWN0RHJhd1xuIik7CiAgICAgICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CiAgICB9CgogICAgLyogVGhlIGludGVyZmFjZXM6CiAgICAgKiBJRGlyZWN0RHJhdyBhbmQgSURpcmVjdDNEIGFyZSB0aGUgc2FtZSBvYmplY3QsCiAgICAgKiBRdWVyeUludGVyZmFjZSBpcyB1c2VkIHRvIGdldCBvdGhlciBpbnRlcmZhY2VzLgogICAgICovCiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3LCAgSURpcmVjdERyYXcxX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzIsIElEaXJlY3REcmF3Ml9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXczLCBJRGlyZWN0RHJhdzNfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3NCwgSURpcmVjdERyYXc0X1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcsIElEaXJlY3REcmF3N19WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNELCAgSURpcmVjdDNEMV9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEMiwgSURpcmVjdDNEMl9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNEMywgSURpcmVjdDNEM19WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdDNENywgSURpcmVjdDNEN19WdGJsKTsKCiAgICAvKiBTZWUgY29tbWVudHMgaW4gSURpcmVjdERyYXdJbXBsX0NyZWF0ZU5ld1N1cmZhY2UgZm9yIGEgZGVzY3JpcHRpb24KICAgICAqIG9mIHRoaXMgbWVtYmVyLgogICAgICogUmVhZCBmcm9tIGEgcmVnaXN0cnkga2V5LCBzaG91bGQgYWRkIGEgd2luZWNmZyBvcHRpb24gbGF0ZXIKICAgICAqLwogICAgVGhpcy0+SW1wbFR5cGUgPSBEZWZhdWx0U3VyZmFjZVR5cGU7CgogICAgLyogR2V0IHRoZSBjdXJyZW50IHNjcmVlbiBzZXR0aW5ncyAqLwogICAgaERDID0gR2V0REMoMCk7CiAgICBUaGlzLT5vcmlnX2JwcCA9IEdldERldmljZUNhcHMoaERDLCBCSVRTUElYRUwpICogR2V0RGV2aWNlQ2FwcyhoREMsIFBMQU5FUyk7CiAgICBSZWxlYXNlREMoMCwgaERDKTsKICAgIFRoaXMtPm9yaWdfd2lkdGggPSBHZXRTeXN0ZW1NZXRyaWNzKFNNX0NYU0NSRUVOKTsKICAgIFRoaXMtPm9yaWdfaGVpZ2h0ID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWVNDUkVFTik7CgogICAgaWYgKGhXaW5lRDNEID09IChITU9EVUxFKSAtMSkKICAgIHsKICAgICAgICBoV2luZUQzRCA9IExvYWRMaWJyYXJ5QSgid2luZWQzZCIpOwogICAgICAgIGlmIChoV2luZUQzRCkKICAgICAgICB7CiAgICAgICAgICAgIHBXaW5lRGlyZWN0M0RDcmVhdGUgPSAoZm5XaW5lRGlyZWN0M0RDcmVhdGUpIEdldFByb2NBZGRyZXNzKGhXaW5lRDNELCAiV2luZURpcmVjdDNEQ3JlYXRlIik7CiAgICAgICAgICAgIHBXaW5lRGlyZWN0M0RDcmVhdGVDbGlwcGVyID0gKGZuV2luZURpcmVjdDNEQ3JlYXRlQ2xpcHBlcikgR2V0UHJvY0FkZHJlc3MoaFdpbmVEM0QsICJXaW5lRGlyZWN0M0RDcmVhdGVDbGlwcGVyIik7CiAgICAgICAgfQogICAgfQoKICAgIGlmICghaFdpbmVEM0QpCiAgICB7CiAgICAgICAgRVJSKCJDb3VsZG4ndCBsb2FkIFdpbmVEM0QgLSBPcGVuR0wgbGlicyBub3QgcHJlc2VudD9cbiIpOwogICAgICAgIGhyID0gRERFUlJfTk9ESVJFQ1REUkFXU1VQUE9SVDsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CgogICAgLyogSW5pdGlhbGl6ZSBXaW5lRDNECiAgICAgKgogICAgICogQWxsIFJlbmRlcmluZyAoMkQgYW5kIDNEKSBpcyByZWxheWVkIHRvIFdpbmVEM0QsCiAgICAgKiBidXQgRGlyZWN0RHJhdyBzcGVjaWZpYyBtYW5hZ2VtZW50LCBsaWtlIEREU1VSRkFDRURFU0MgYW5kIEREUElYRUxGT1JNQVQKICAgICAqIHN0cnVjdHVyZSBoYW5kbGluZyBpcyBoYW5kbGVkIGluIHRoaXMgbGliLgogICAgICovCiAgICB3aW5lRDNEID0gcFdpbmVEaXJlY3QzRENyZWF0ZSgwIC8qIFNES1ZlcnNpb24gKi8sIDcgLyogRFhWZXJzaW9uICovLCAoSVVua25vd24gKikgVGhpcyAvKiBQYXJlbnQgKi8pOwogICAgaWYoIXdpbmVEM0QpCiAgICB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gaW5pdGlhbGlzZSBXaW5lRDNEXG4iKTsKICAgICAgICBociA9IEVfT1VUT0ZNRU1PUlk7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQogICAgVGhpcy0+d2luZUQzRCA9IHdpbmVEM0Q7CiAgICBUUkFDRSgiV2luZUQzRCBjcmVhdGVkIGF0ICVwXG4iLCB3aW5lRDNEKTsKCiAgICAvKiBJbml0aWFsaXplZCBtZW1iZXIuLi4KICAgICAqCiAgICAgKiBJdCBpcyBzZXQgdG8gZmFsc2UgYXQgY3JlYXRpb24gdGltZSwgYW5kIHNldCB0byB0cnVlIGluCiAgICAgKiBJRGlyZWN0RHJhdzc6OkluaXRpYWxpemUuIEl0cyBzb2xlIHB1cnBvc2UgaXMgdG8gcmV0dXJuIEREX09LIG9uCiAgICAgKiBpbml0aWFsaXplIG9ubHkgb25jZQogICAgICovCiAgICBUaGlzLT5pbml0aWFsaXplZCA9IEZBTFNFOwoKICAgIC8qIEluaXRpYWxpemUgV2luZUQzRERldmljZQogICAgICoKICAgICAqIEl0IGlzIHVzZWQgZm9yIHNjcmVlbiBzZXR1cCwgc3VyZmFjZSBhbmQgcGFsZXR0ZSBjcmVhdGlvbgogICAgICogV2hlbiBhIERpcmVjdDNERGV2aWNlNyBpcyBjcmVhdGVkLCB0aGUgRDNEIGNhcGFiaWxpdGllcyBvZiBXaW5lRDNEIGFyZQogICAgICogaW5pdGlhbGl6ZWQKICAgICAqLwogICAgaHIgPSBJV2luZUQzRF9DcmVhdGVEZXZpY2Uod2luZUQzRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAgLypEM0RfQURBUFRFUl9ERUZBVUxUKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2V0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgLyogRm9jdXNXaW5kb3csIGRvbid0IGtub3cgeWV0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAvKiBCZWhhdmlvckZsYWdzICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmd2luZUQzRERldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChJVW5rbm93biAqKSBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpKTsKICAgIGlmKEZBSUxFRChocikpCiAgICB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gY3JlYXRlIGEgd2luZUQzRERldmljZSwgcmVzdWx0ID0gJXhcbiIsIGhyKTsKICAgICAgICBnb3RvIGVycl9vdXQ7CiAgICB9CiAgICBUaGlzLT53aW5lRDNERGV2aWNlID0gd2luZUQzRERldmljZTsKICAgIFRSQUNFKCJ3aW5lRDNERGV2aWNlIGNyZWF0ZWQgYXQgJXBcbiIsIFRoaXMtPndpbmVEM0REZXZpY2UpOwoKICAgIC8qIFJlZ2lzdGVyIHRoZSB3aW5kb3cgY2xhc3MKICAgICAqCiAgICAgKiBJdCBpcyB1c2VkIHRvIGNyZWF0ZSBhIGhpZGRlbiB3aW5kb3cgZm9yIEQzRAogICAgICogcmVuZGVyaW5nLCBpZiB0aGUgYXBwbGljYXRpb24gZGlkbid0IHBhc3Mgb25lLgogICAgICogSXQgY2FuIGFsc28gYmUgdXNlZCBmb3IgQ3JlYXRpbmcgYSBkZXZpY2Ugd2luZG93CiAgICAgKiBmcm9tIFNldENvb3BlcmF0aXZlTGV2ZWwKICAgICAqCiAgICAgKiBUaGUgbmFtZTogRERSQVdfPGFkZHJlc3M+LiBUaGUgY2xhc3NuYW1lIGlzCiAgICAgKiAzMiBiaXQgbG9uZywgc28gYSA2NCBiaXQgYWRkcmVzcyB3aWxsIGZpdCBuaWNlbHkKICAgICAqIChXaWxsIHRoaXMgYmUgY29tcGlsZWQgZm9yIDY0IGJpdCBhbnl3YXk/KQogICAgICoKICAgICAqLwogICAgc3ByaW50ZihUaGlzLT5jbGFzc25hbWUsICJERFJBV18lcCIsIFRoaXMpOwoKICAgIG1lbXNldCgmVGhpcy0+d25kX2NsYXNzLCAwLCBzaXplb2YoVGhpcy0+d25kX2NsYXNzKSk7CiAgICBUaGlzLT53bmRfY2xhc3Muc3R5bGUgPSBDU19IUkVEUkFXIHwgQ1NfVlJFRFJBVzsKICAgIFRoaXMtPnduZF9jbGFzcy5scGZuV25kUHJvYyA9IERlZldpbmRvd1Byb2NBOwogICAgVGhpcy0+d25kX2NsYXNzLmNiQ2xzRXh0cmEgPSAwOwogICAgVGhpcy0+d25kX2NsYXNzLmNiV25kRXh0cmEgPSAwOwogICAgVGhpcy0+d25kX2NsYXNzLmhJbnN0YW5jZSA9IEdldE1vZHVsZUhhbmRsZUEoMCk7CiAgICBUaGlzLT53bmRfY2xhc3MuaEljb24gPSAwOwogICAgVGhpcy0+d25kX2NsYXNzLmhDdXJzb3IgPSAwOwogICAgVGhpcy0+d25kX2NsYXNzLmhickJhY2tncm91bmQgPSAoSEJSVVNIKSBHZXRTdG9ja09iamVjdChCTEFDS19CUlVTSCk7CiAgICBUaGlzLT53bmRfY2xhc3MubHBzek1lbnVOYW1lID0gTlVMTDsKICAgIFRoaXMtPnduZF9jbGFzcy5scHN6Q2xhc3NOYW1lID0gVGhpcy0+Y2xhc3NuYW1lOwogICAgaWYoIVJlZ2lzdGVyQ2xhc3NBKCZUaGlzLT53bmRfY2xhc3MpKQogICAgewogICAgICAgIEVSUigiUmVnaXN0ZXJDbGFzc0EgZmFpbGVkIVxuIik7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQoKICAgIC8qIEdldCB0aGUgYW1vdW50IG9mIHZpZGVvIG1lbW9yeSAqLwogICAgVGhpcy0+dG90YWxfdmlkbWVtID0gSVdpbmVEM0REZXZpY2VfR2V0QXZhaWxhYmxlVGV4dHVyZU1lbShUaGlzLT53aW5lRDNERGV2aWNlKTsKCiAgICAvKiBJbml0aWFsaXplIHRoZSBjYXBzICovCiAgICBUaGlzLT5jYXBzLmR3U2l6ZSA9IHNpemVvZihUaGlzLT5jYXBzKTsKLyogZG8gbm90IHJlcG9ydCBERENBUFNfT1ZFUkxBWSBhbmQgZnJpZW5kcyBzaW5jZSB3ZSBkb24ndCBzdXBwb3J0IG92ZXJsYXlzICovCiNkZWZpbmUgQkxJVF9DQVBTIChERENBUFNfQkxUIHwgRERDQVBTX0JMVENPTE9SRklMTCB8IEREQ0FQU19CTFRERVBUSEZJTEwgXAogICAgICAgICAgfCBERENBUFNfQkxUU1RSRVRDSCB8IEREQ0FQU19DQU5CTFRTWVNNRU0gfCBERENBUFNfQ0FOQ0xJUAkgIFwKICAgICAgICAgIHwgRERDQVBTX0NBTkNMSVBTVFJFVENIRUQgfCBERENBUFNfQ09MT1JLRVkJCQkgIFwKICAgICAgICAgIHwgRERDQVBTX0NPTE9SS0VZSFdBU1NJU1QgfCBERENBUFNfQUxJR05CT1VOREFSWVNSQyApCiNkZWZpbmUgQ0tFWV9DQVBTIChERENLRVlDQVBTX0RFU1RCTFQgfCBERENLRVlDQVBTX1NSQ0JMVCkKI2RlZmluZSBGWF9DQVBTIChEREZYQ0FQU19CTFRBTFBIQSB8IERERlhDQVBTX0JMVE1JUlJPUkxFRlRSSUdIVAlcCiAgICAgICAgICAgICAgICB8IERERlhDQVBTX0JMVE1JUlJPUlVQRE9XTiB8IERERlhDQVBTX0JMVFJPVEFUSU9OOTAJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRTSFJJTktYIHwgRERGWENBUFNfQkxUU0hSSU5LWE4JCVwKICAgICAgICAgICAgICAgIHwgRERGWENBUFNfQkxUU0hSSU5LWSB8IERERlhDQVBTX0JMVFNIUklOS1hOCQlcCiAgICAgICAgICAgICAgICB8IERERlhDQVBTX0JMVFNUUkVUQ0hYIHwgRERGWENBUFNfQkxUU1RSRVRDSFhOCQlcCiAgICAgICAgICAgICAgICB8IERERlhDQVBTX0JMVFNUUkVUQ0hZIHwgRERGWENBUFNfQkxUU1RSRVRDSFlOKQogICAgVGhpcy0+Y2Fwcy5kd0NhcHMgfD0gRERDQVBTX0dESSB8IEREQ0FQU19QQUxFVFRFIHwgQkxJVF9DQVBTOwoKICAgIFRoaXMtPmNhcHMuZHdDYXBzMiB8PSBERENBUFMyX0NFUlRJRklFRCB8IEREQ0FQUzJfTk9QQUdFTE9DS1JFUVVJUkVEIHwKICAgICAgICAgICAgICAgICAgICAgICAgICBERENBUFMyX1BSSU1BUllHQU1NQSB8IEREQ0FQUzJfV0lERVNVUkZBQ0VTIHwKICAgICAgICAgICAgICAgICAgICAgICAgICBERENBUFMyX0NBTlJFTkRFUldJTkRPV0VEOwogICAgVGhpcy0+Y2Fwcy5kd0NLZXlDYXBzIHw9IENLRVlfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdGWENhcHMgfD0gRlhfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdQYWxDYXBzIHw9IEREUENBUFNfOEJJVCB8IEREUENBUFNfUFJJTUFSWVNVUkZBQ0U7CiAgICBUaGlzLT5jYXBzLmR3VmlkTWVtVG90YWwgPSBUaGlzLT50b3RhbF92aWRtZW07CiAgICBUaGlzLT5jYXBzLmR3VmlkTWVtRnJlZSA9IFRoaXMtPnRvdGFsX3ZpZG1lbTsKICAgIFRoaXMtPmNhcHMuZHdTVkJDYXBzIHw9IEJMSVRfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTVkJDS2V5Q2FwcyB8PSBDS0VZX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3U1ZCRlhDYXBzIHw9IEZYX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3VlNCQ2FwcyB8PSBCTElUX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3VlNCQ0tleUNhcHMgfD0gQ0tFWV9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1ZTQkZYQ2FwcyB8PSBGWF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1NTQkNhcHMgfD0gQkxJVF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1NTQkNLZXlDYXBzIHw9IENLRVlfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTU0JGWENhcHMgfD0gRlhfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU19BTFBIQSB8IEREU0NBUFNfQkFDS0JVRkZFUiB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfRkxJUCB8IEREU0NBUFNfRlJPTlRCVUZGRVIgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX09GRlNDUkVFTlBMQUlOIHwgRERTQ0FQU19QQUxFVFRFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19QUklNQVJZU1VSRkFDRSB8IEREU0NBUFNfU1lTVEVNTUVNT1JZIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19WSURFT01FTU9SWSB8IEREU0NBUFNfVklTSUJMRTsKICAgIC8qIEhhY2tzIGZvciBEM0QgY29kZSAqLwogICAgLyogVE9ETzogQ2hlY2sgaWYgV2luZUQzRCBoYXMgM0QgZW5hYmxlZAogICAgICAgTmVlZCBvcGVuZ2wgc3VyZmFjZXMgb3IgYXV0byBmb3IgM0QKICAgICAqLwogICAgaWYoVGhpcy0+SW1wbFR5cGUgPT0gMCB8fCBUaGlzLT5JbXBsVHlwZSA9PSBTVVJGQUNFX09QRU5HTCkKICAgIHsKICAgICAgICBUaGlzLT5jYXBzLmR3Q2FwcyB8PSBERENBUFNfM0Q7CiAgICAgICAgVGhpcy0+Y2Fwcy5kZHNDYXBzLmR3Q2FwcyB8PSBERFNDQVBTXzNEREVWSUNFIHwgRERTQ0FQU19NSVBNQVAgfCBERFNDQVBTX1RFWFRVUkUgfCBERFNDQVBTX1pCVUZGRVI7CiAgICB9CiAgICBUaGlzLT5jYXBzLmRkc09sZENhcHMuZHdDYXBzID0gVGhpcy0+Y2Fwcy5kZHNDYXBzLmR3Q2FwczsKCiN1bmRlZiBCTElUX0NBUFMKI3VuZGVmIENLRVlfQ0FQUwojdW5kZWYgRlhfQ0FQUwoKICAgIGxpc3RfaW5pdCgmVGhpcy0+c3VyZmFjZV9saXN0KTsKICAgIGxpc3RfYWRkX2hlYWQoJmdsb2JhbF9kZHJhd19saXN0LCAmVGhpcy0+ZGRyYXdfbGlzdF9lbnRyeSk7CgogICAgLyogQ2FsbCBRdWVyeUludGVyZmFjZSB0byBnZXQgdGhlIHBvaW50ZXIgdG8gdGhlIHJlcXVlc3RlZCBpbnRlcmZhY2UuIFRoaXMgYWxzbyBpbml0aWFsaXplcwogICAgICogVGhlIHJlcXVpcmVkIHJlZmNvdW50CiAgICAgKi8KICAgIGhyID0gSURpcmVjdERyYXc3X1F1ZXJ5SW50ZXJmYWNlKCBJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzcpLCBpaWQsIEREKTsKICAgIGlmKFNVQ0NFRURFRChocikpIHJldHVybiBERF9PSzsKCmVycl9vdXQ6CiAgICAvKiBMZXQncyBob3BlIHdlIG5ldmVyIG5lZWQgdGhpcyA7KSAqLwogICAgaWYod2luZUQzRERldmljZSkgSVdpbmVEM0REZXZpY2VfUmVsZWFzZSh3aW5lRDNERGV2aWNlKTsKICAgIGlmKHdpbmVEM0QpIElXaW5lRDNEX1JlbGVhc2Uod2luZUQzRCk7CiAgICBpZihUaGlzKSBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5kZWNscyk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdDcmVhdGUgKEREUkFXLkApCiAqCiAqIENyZWF0ZXMgbGVnYWN5IERpcmVjdERyYXcgSW50ZXJmYWNlcy4gQ2FuJ3QgY3JlYXRlIElEaXJlY3REcmF3NwogKiBpbnRlcmZhY2VzIGluIHRoZW9yeQogKgogKiBBcmd1bWVudHMsIHJldHVybiB2YWx1ZXM6IFNlZSBERFJBV19DcmVhdGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpEaXJlY3REcmF3Q3JlYXRlKEdVSUQgKkdVSUQsCiAgICAgICAgICAgICAgICAgTFBESVJFQ1REUkFXICpERCwKICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVzLCVwLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChHVUlEKSwgREQsIFVua091dGVyKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBERFJBV19DcmVhdGUoR1VJRCwgKHZvaWQgKiopIERELCBVbmtPdXRlciwgJklJRF9JRGlyZWN0RHJhdyk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0NyZWF0ZUV4IChERFJBVy5AKQogKgogKiBPbmx5IGNyZWF0ZXMgbmV3IElEaXJlY3REcmF3NyBpbnRlcmZhY2VzLCBzdXBwb3NlZCB0byBmYWlsIGlmIGxlZ2FjeQogKiBpbnRlcmZhY2VzIGFyZSByZXF1ZXN0ZWQuCiAqCiAqIEFyZ3VtZW50cywgcmV0dXJuIHZhbHVlczogU2VlIEREUkFXX0NyZWF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdDcmVhdGVFeChHVUlEICpHVUlELAogICAgICAgICAgICAgICAgICAgTFBWT0lEICpERCwKICAgICAgICAgICAgICAgICAgIFJFRklJRCBpaWQsCiAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIpCnsKICAgIEhSRVNVTFQgaHI7CiAgICBUUkFDRSgiKCVzLCVwLCVzLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChHVUlEKSwgREQsIGRlYnVnc3RyX2d1aWQoaWlkKSwgVW5rT3V0ZXIpOwoKICAgIGlmICghSXNFcXVhbEdVSUQoaWlkLCAmSUlEX0lEaXJlY3REcmF3NykpCiAgICAgICAgcmV0dXJuIERERVJSX0lOVkFMSURQQVJBTVM7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gRERSQVdfQ3JlYXRlKEdVSUQsIERELCBVbmtPdXRlciwgaWlkKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3RW51bWVyYXRlQSAoRERSQVcuQCkKICoKICogRW51bWVyYXRlcyBsZWdhY3kgZGRyYXcgZHJpdmVycywgYXNjaWkgdmVyc2lvbi4gV2Ugb25seSBoYXZlIG9uZQogKiBkcml2ZXIsIHdoaWNoIHJlbGF5cyB0byBXaW5lRDNELiBJZiB3ZSB3ZXJlIHN1ZmZpY2llbnRseSBjb29sLAogKiB3ZSBjb3VsZCBvZmZlciB2YXJpb3VzIGludGVyZmFjZXMsIHdoaWNoIHVzZSBhIGRpZmZlcmVudCBkZWZhdWx0IHN1cmZhY2UKICogaW1wbGVtZW50YXRpb24sIGJ1dCBJIHRoaW5rIGl0J3MgYmV0dGVyIHRvIG9mZmVyIHRoaXMgY2hvaWNlIGluCiAqIHdpbmVjZmcsIGJlY2F1c2Ugc29tZSBhcHBzIHVzZSB0aGUgZGVmYXVsdCBkcml2ZXIsIHNvIHdlIHdvdWxkIG5lZWQKICogYSB3aW5lY2ZnIG9wdGlvbiBhbnl3YXksIGFuZCB0aGVyZSBzaG91bGRuJ3QgYmUgMiB3YXlzIHRvIHNldCBvbmUgc2V0dGluZwogKgogKiBBcmd1bWVudHM6CiAqICBDYWxsYmFjazogQ2FsbGJhY2sgZnVuY3Rpb24gZnJvbSB0aGUgYXBwCiAqICBDb250ZXh0OiBBcmd1bWVudCB0byB0aGUgY2FsbCBiYWNrLgogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRV9JTlZBTElEQVJHIGlmIHRoZSBDYWxsYmFjayBjYXVzZWQgYSBwYWdlIGZhdWx0CiAqCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKRGlyZWN0RHJhd0VudW1lcmF0ZUEoTFBEREVOVU1DQUxMQkFDS0EgQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgIExQVk9JRCBDb250ZXh0KQp7CiAgICBCT09MIHN0b3AgPSBGQUxTRTsKCiAgICBUUkFDRSgiIEVudW1lcmF0aW5nIGRlZmF1bHQgRGlyZWN0RHJhdyBIQUwgaW50ZXJmYWNlXG4iKTsKICAgIC8qIFdlIG9ubHkgaGF2ZSBvbmUgZHJpdmVyICovCiAgICBfX1RSWQogICAgewogICAgICAgIHN0YXRpYyBDSEFSIGRyaXZlcl9kZXNjW10gPSAiRGlyZWN0RHJhdyBIQUwiLAogICAgICAgIGRyaXZlcl9uYW1lW10gPSAiZGlzcGxheSI7CgogICAgICAgIHN0b3AgPSAhQ2FsbGJhY2soTlVMTCwgZHJpdmVyX2Rlc2MsIGRyaXZlcl9uYW1lLCBDb250ZXh0KTsKICAgIH0KICAgIF9fRVhDRVBUX1BBR0VfRkFVTFQKICAgIHsKICAgICAgICByZXR1cm4gRV9JTlZBTElEQVJHOwogICAgfQogICAgX19FTkRUUlkKCiAgICBUUkFDRSgiIEVuZCBvZiBlbnVtZXJhdGlvblxuIik7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3RW51bWVyYXRlRXhBIChERFJBVy5AKQogKgogKiBFbnVtZXJhdGVzIERpcmVjdERyYXc3IGRyaXZlcnMsIGFzY2lpIHZlcnNpb24uIFNlZQogKiB0aGUgY29tbWVudHMgYWJvdmUgRGlyZWN0RHJhd0VudW1lcmF0ZUEgZm9yIG1vcmUgZGV0YWlscy4KICoKICogVGhlIEZsYWcgbWVtYmVyIGlzIG5vdCBzdXBwb3J0ZWQgcmlnaHQgbm93LgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdFbnVtZXJhdGVFeEEoTFBEREVOVU1DQUxMQkFDS0VYQSBDYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgQ29udGV4dCwKICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncykKewogICAgQk9PTCBzdG9wID0gRkFMU0U7CiAgICBUUkFDRSgiRW51bWVyYXRpbmcgZGVmYXVsdCBEaXJlY3REcmF3IEhBTCBpbnRlcmZhY2VcbiIpOwoKICAgIC8qIFdlIG9ubHkgaGF2ZSBvbmUgZHJpdmVyIGJ5IG5vdyAqLwogICAgX19UUlkKICAgIHsKICAgICAgICBzdGF0aWMgQ0hBUiBkcml2ZXJfZGVzY1tdID0gIkRpcmVjdERyYXcgSEFMIiwKICAgICAgICBkcml2ZXJfbmFtZVtdID0gImRpc3BsYXkiOwoKICAgICAgICAvKiBRdWlja1RpbWUgZXhwZWN0cyB0aGUgZGVzY3JpcHRpb24gIkRpcmVjdERyYXcgSEFMIiAqLwogICAgICAgIHN0b3AgPSAhQ2FsbGJhY2soTlVMTCwgZHJpdmVyX2Rlc2MsIGRyaXZlcl9uYW1lLCBDb250ZXh0LCAwKTsKICAgIH0KICAgIF9fRVhDRVBUX1BBR0VfRkFVTFQKICAgIHsKICAgICAgICByZXR1cm4gRV9JTlZBTElEQVJHOwogICAgfQogICAgX19FTkRUUlk7CgogICAgVFJBQ0UoIkVuZCBvZiBlbnVtZXJhdGlvblxuIik7CiAgICByZXR1cm4gRERfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3RW51bWVyYXRlVyAoRERSQVcuQCkKICoKICogRW51bWVyYXRlcyBsZWdhY3kgZHJpdmVycywgdW5pY29kZSB2ZXJzaW9uLiBTZWUKICogdGhlIGNvbW1lbnRzIGFib3ZlIERpcmVjdERyYXdFbnVtZXJhdGVBIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFRoZSBGbGFnIG1lbWJlciBpcyBub3Qgc3VwcG9ydGVkIHJpZ2h0IG5vdy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdFbnVtZXJhdGVFeFcgKEREUkFXLkApCiAqCiAqIEVudW1lcmF0ZXMgRGlyZWN0RHJhdzcgZHJpdmVycywgdW5pY29kZSB2ZXJzaW9uLiBTZWUKICogdGhlIGNvbW1lbnRzIGFib3ZlIERpcmVjdERyYXdFbnVtZXJhdGVBIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFRoZSBGbGFnIG1lbWJlciBpcyBub3Qgc3VwcG9ydGVkIHJpZ2h0IG5vdy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENsYXNzZmFjdG9yeSBpbXBsZW1lbnRhdGlvbi4KICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENGX0NyZWF0ZURpcmVjdERyYXcKICoKICogRERyYXcgY3JlYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBjbGFzcyBmYWN0b3J5CiAqCiAqIFBhcmFtczoKICogIFVua091dGVyOiBTZXQgdG8gTlVMTAogKiAgaWlkOiBJRCBvZiB0aGUgd2FudGVkIGludGVyZmFjZQogKiAgb2JqOiBBZGRyZXNzIHRvIHBhc3MgdGhlIGludGVyZmFjZSBwb2ludGVyIGJhY2sKICoKICogUmV0dXJucwogKiAgRERfT0sgLyBEREVSUiosIHNlZSBERFJBV19DcmVhdGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApDRl9DcmVhdGVEaXJlY3REcmF3KElVbmtub3duKiBVbmtPdXRlciwgUkVGSUlEIGlpZCwKICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBIUkVTVUxUIGhyOwoKICAgIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBVbmtPdXRlciwgZGVidWdzdHJfZ3VpZChpaWQpLCBvYmopOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IEREUkFXX0NyZWF0ZShOVUxMLCBvYmosIFVua091dGVyLCBpaWQpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENGX0NyZWF0ZURpcmVjdERyYXcKICoKICogQ2xpcHBlciBjcmVhdGlvbiBmdW5jdGlvbiBmb3IgdGhlIGNsYXNzIGZhY3RvcnkKICoKICogUGFyYW1zOgogKiAgVW5rT3V0ZXI6IFNldCB0byBOVUxMCiAqICBpaWQ6IElEIG9mIHRoZSB3YW50ZWQgaW50ZXJmYWNlCiAqICBvYmo6IEFkZHJlc3MgdG8gcGFzcyB0aGUgaW50ZXJmYWNlIHBvaW50ZXIgYmFjawogKgogKiBSZXR1cm5zCiAqICBERF9PSyAvIERERVJSKiwgc2VlIEREUkFXX0NyZWF0ZQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCkNGX0NyZWF0ZURpcmVjdERyYXdDbGlwcGVyKElVbmtub3duKiBVbmtPdXRlciwgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIEhSRVNVTFQgaHI7CiAgICBJRGlyZWN0RHJhd0NsaXBwZXIgKkNsaXA7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gRGlyZWN0RHJhd0NyZWF0ZUNsaXBwZXIoMCwgJkNsaXAsIFVua091dGVyKTsKICAgIGlmIChociAhPSBERF9PSykKICAgIHsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICBociA9IElEaXJlY3REcmF3Q2xpcHBlcl9RdWVyeUludGVyZmFjZShDbGlwLCByaWlkLCBvYmopOwogICAgSURpcmVjdERyYXdDbGlwcGVyX1JlbGVhc2UoQ2xpcCk7CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBvYmplY3RfY3JlYXRpb25faW5mbyBvYmplY3RfY3JlYXRpb25bXSA9CnsKICAgIHsgJkNMU0lEX0RpcmVjdERyYXcsICAgICAgICBDRl9DcmVhdGVEaXJlY3REcmF3IH0sCiAgICB7ICZDTFNJRF9EaXJlY3REcmF3NywgICAgICAgQ0ZfQ3JlYXRlRGlyZWN0RHJhdyB9LAogICAgeyAmQ0xTSURfRGlyZWN0RHJhd0NsaXBwZXIsIENGX0NyZWF0ZURpcmVjdERyYXdDbGlwcGVyIH0KfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5OjpRdWVyeUludGVyZmFjZQogKgogKiBRdWVyeUludGVyZmFjZSBmb3IgdGhlIGNsYXNzIGZhY3RvcnkKICoKICogUEFSQU1TCiAqICAgIHJpaWQgICBSZWZlcmVuY2UgdG8gaWRlbnRpZmllciBvZiBxdWVyaWVkIGludGVyZmFjZQogKiAgICBwcHYgICAgQWRkcmVzcyB0byByZXR1cm4gdGhlIGludGVyZmFjZSBwb2ludGVyIGF0CiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogU19PSwogKiAgICBGYWlsdXJlOiBFX05PSU5URVJGQUNFCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX1F1ZXJ5SW50ZXJmYWNlKElDbGFzc0ZhY3RvcnkgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElDbGFzc0ZhY3RvcnlJbXBsLCBJQ2xhc3NGYWN0b3J5LCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcCktPiglcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmlpZCksIG9iaik7CgogICAgaWYgKElzRXF1YWxHVUlEKHJpaWQsICZJSURfSVVua25vd24pCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JQ2xhc3NGYWN0b3J5KSkKICAgIHsKICAgICAgICBJQ2xhc3NGYWN0b3J5X0FkZFJlZihpZmFjZSk7CiAgICAgICAgKm9iaiA9IFRoaXM7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CgogICAgV0FSTigiKCVwKS0+KCVzLCVwKSxub3QgZm91bmRcbiIsVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CiAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdDbGFzc0ZhY3Rvcnk6OkFkZFJlZgogKgogKiBBZGRSZWYgZm9yIHRoZSBjbGFzcyBmYWN0b3J5CiAqCiAqIFJFVFVSTlMKICogIFRoZSBuZXcgcmVmY291bnQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX0FkZFJlZihJQ2xhc3NGYWN0b3J5ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSUNsYXNzRmFjdG9yeUltcGwsIElDbGFzc0ZhY3RvcnksIGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwoKICAgIFRSQUNFKCIoJXApLT4oKSBpbmNyZW1lbnRpbmcgZnJvbSAlZC5cbiIsIFRoaXMsIHJlZiAtIDEpOwoKICAgIHJldHVybiByZWY7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5OjpSZWxlYXNlCiAqCiAqIFJlbGVhc2UgZm9yIHRoZSBjbGFzcyBmYWN0b3J5LiBJZiB0aGUgcmVmY291bnQgZmFsbHMgdG8gMCwgdGhlIG9iamVjdAogKiBpcyBkZXN0cm95ZWQKICoKICogUkVUVVJOUwogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfUmVsZWFzZShJQ2xhc3NGYWN0b3J5ICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSUNsYXNzRmFjdG9yeUltcGwsIElDbGFzc0ZhY3RvcnksIGlmYWNlKTsKICAgIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwogICAgVFJBQ0UoIiglcCktPigpIGRlY3JlbWVudGluZyBmcm9tICVkLlxuIiwgVGhpcywgcmVmKzEpOwoKICAgIGlmIChyZWYgPT0gMCkKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKCiAgICByZXR1cm4gcmVmOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdDbGFzc0ZhY3Rvcnk6OkNyZWF0ZUluc3RhbmNlCiAqCiAqIFdoYXQgaXMgdGhpcz8gU2VlbXMgdG8gY3JlYXRlIERpcmVjdERyYXcgb2JqZWN0cy4uLgogKgogKiBQYXJhbXMKICogIFRoZSB1c3VzYWwgdGhpbmdzPz8/CiAqCiAqIFJFVFVSTlMKICogID8/PwogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9DcmVhdGVJbnN0YW5jZShJQ2xhc3NGYWN0b3J5ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElVbmtub3duICpVbmtPdXRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSUNsYXNzRmFjdG9yeUltcGwsIElDbGFzc0ZhY3RvcnksIGlmYWNlKTsKCiAgICBUUkFDRSgiKCVwKS0+KCVwLCVzLCVwKVxuIixUaGlzLFVua091dGVyLGRlYnVnc3RyX2d1aWQocmlpZCksb2JqKTsKCiAgICByZXR1cm4gVGhpcy0+cGZuQ3JlYXRlSW5zdGFuY2UoVW5rT3V0ZXIsIHJpaWQsIG9iaik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5OjpMb2NrU2VydmVyCiAqCiAqIFdoYXQgaXMgdGhpcz8KICoKICogUGFyYW1zCiAqICA/Pz8KICoKICogUkVUVVJOUwogKiAgU19PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9Mb2NrU2VydmVyKElDbGFzc0ZhY3RvcnkgKmlmYWNlLEJPT0wgZG9sb2NrKQp7CiAgICBJQ09NX1RISVNfRlJPTShJQ2xhc3NGYWN0b3J5SW1wbCwgSUNsYXNzRmFjdG9yeSwgaWZhY2UpOwogICAgRklYTUUoIiglcCktPiglZCksc3R1YiFcbiIsVGhpcyxkb2xvY2spOwogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBjbGFzcyBmYWN0b3J5IFZUYWJsZQogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGNvbnN0IElDbGFzc0ZhY3RvcnlWdGJsIElDbGFzc0ZhY3RvcnlfVnRibCA9CnsKICAgIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9RdWVyeUludGVyZmFjZSwKICAgIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9BZGRSZWYsCiAgICBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfUmVsZWFzZSwKICAgIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9DcmVhdGVJbnN0YW5jZSwKICAgIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9Mb2NrU2VydmVyCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxHZXRDbGFzc09iamVjdCBbRERSQVcuQF0KICogUmV0cmlldmVzIGNsYXNzIG9iamVjdCBmcm9tIGEgRExMIG9iamVjdAogKgogKiBOT1RFUwogKiAgICBEb2NzIHNheSByZXR1cm5zIFNUREFQSQogKgogKiBQQVJBTVMKICogICAgcmNsc2lkIFtJXSBDTFNJRCBmb3IgdGhlIGNsYXNzIG9iamVjdAogKiAgICByaWlkICAgW0ldIFJlZmVyZW5jZSB0byBpZGVudGlmaWVyIG9mIGludGVyZmFjZSBmb3IgY2xhc3Mgb2JqZWN0CiAqICAgIHBwdiAgICBbT10gQWRkcmVzcyBvZiB2YXJpYWJsZSB0byByZWNlaXZlIGludGVyZmFjZSBwb2ludGVyIGZvciByaWlkCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogU19PSwogKiAgICBGYWlsdXJlOiBDTEFTU19FX0NMQVNTTk9UQVZBSUxBQkxFLCBFX09VVE9GTUVNT1JZLCBFX0lOVkFMSURBUkcsCiAqICAgICAgICAgICAgIEVfVU5FWFBFQ1RFRAogKi8KSFJFU1VMVCBXSU5BUEkgRGxsR2V0Q2xhc3NPYmplY3QoUkVGQ0xTSUQgcmNsc2lkLCBSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpCnsKICAgIHVuc2lnbmVkIGludCBpOwogICAgSUNsYXNzRmFjdG9yeUltcGwgKmZhY3Rvcnk7CgogICAgVFJBQ0UoIiglcywlcywlcClcbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSwgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHB2KTsKCiAgICBpZiAoICFJc0VxdWFsR1VJRCggJklJRF9JQ2xhc3NGYWN0b3J5LCByaWlkICkKCSAmJiAhIElzRXF1YWxHVUlEKCAmSUlEX0lVbmtub3duLCByaWlkKSApCglyZXR1cm4gRV9OT0lOVEVSRkFDRTsKCiAgICBmb3IgKGk9MDsgaSA8IHNpemVvZihvYmplY3RfY3JlYXRpb24pL3NpemVvZihvYmplY3RfY3JlYXRpb25bMF0pOyBpKyspCiAgICB7CglpZiAoSXNFcXVhbEdVSUQob2JqZWN0X2NyZWF0aW9uW2ldLmNsc2lkLCByY2xzaWQpKQoJICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChpID09IHNpemVvZihvYmplY3RfY3JlYXRpb24pL3NpemVvZihvYmplY3RfY3JlYXRpb25bMF0pKQogICAgewoJRklYTUUoIiVzOiBubyBjbGFzcyBmb3VuZC5cbiIsIGRlYnVnc3RyX2d1aWQocmNsc2lkKSk7CglyZXR1cm4gQ0xBU1NfRV9DTEFTU05PVEFWQUlMQUJMRTsKICAgIH0KCiAgICBmYWN0b3J5ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZigqZmFjdG9yeSkpOwogICAgaWYgKGZhY3RvcnkgPT0gTlVMTCkgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogICAgSUNPTV9JTklUX0lOVEVSRkFDRShmYWN0b3J5LCBJQ2xhc3NGYWN0b3J5LCBJQ2xhc3NGYWN0b3J5X1Z0YmwpOwogICAgZmFjdG9yeS0+cmVmID0gMTsKCiAgICBmYWN0b3J5LT5wZm5DcmVhdGVJbnN0YW5jZSA9IG9iamVjdF9jcmVhdGlvbltpXS5wZm5DcmVhdGVJbnN0YW5jZTsKCiAgICAqcHB2ID0gSUNPTV9JTlRFUkZBQ0UoZmFjdG9yeSwgSUNsYXNzRmFjdG9yeSk7CiAgICByZXR1cm4gU19PSzsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERsbENhblVubG9hZE5vdyBbRERSQVcuQF0gIERldGVybWluZXMgd2hldGhlciB0aGUgRExMIGlzIGluIHVzZS4KICoKICogUkVUVVJOUwogKiAgICBTdWNjZXNzOiBTX09LCiAqICAgIEZhaWx1cmU6IFNfRkFMU0UKICovCkhSRVNVTFQgV0lOQVBJIERsbENhblVubG9hZE5vdyh2b2lkKQp7CiAgICBIUkVTVUxUIGhyOwogICAgRklYTUUoIih2b2lkKTogc3R1YlxuIik7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gU19GQUxTRTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CgogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZXN0cm95Q2FsbGJhY2sKICoKICogQ2FsbGJhY2sgZnVuY3Rpb24gZm9yIHRoZSBFbnVtU3VyZmFjZXMgY2FsbCBpbiBEbGxNYWluLgogKiBEdW1wcyBzb21lIHN1cmZhY2UgaW5mbyBhbmQgcmVsZWFzZXMgdGhlIHN1cmZhY2UKICoKICogUGFyYW1zOgogKiAgc3VyZjogVGhlIGVudW1lcmF0ZWQgc3VyZmFjZQogKiAgZGVzYzogaXQncyBkZXNjcmlwdGlvbgogKiAgY29udGV4dDogUG9pbnRlciB0byB0aGUgZGRyYXcgaW1wbAogKgogKiBSZXR1cm5zOgogKiAgRERFTlVNUkVUX09LOwogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCkRlc3Ryb3lDYWxsYmFjayhJRGlyZWN0RHJhd1N1cmZhY2U3ICpzdXJmLAogICAgICAgICAgICAgICAgRERTVVJGQUNFREVTQzIgKmRlc2MsCiAgICAgICAgICAgICAgICB2b2lkICpjb250ZXh0KQp7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpJbXBsID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdERyYXdTdXJmYWNlNywgc3VyZik7CiAgICBJRGlyZWN0RHJhd0ltcGwgKmRkcmF3ID0gKElEaXJlY3REcmF3SW1wbCAqKSBjb250ZXh0OwogICAgVUxPTkcgcmVmOwoKICAgIHJlZiA9IElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShzdXJmKTsgIC8qIEZvciB0aGUgRW51bVN1cmZhY2VzICovCiAgICBXQVJOKCJTdXJmYWNlICVwIGhhcyBhbiByZWZlcmVuY2UgY291bnQgb2YgJWRcbiIsIEltcGwsIHJlZik7CgogICAgLyogU2tpcCBzdXJmYWNlcyB3aGljaCBhcmUgYXR0YWNoZWQgc29tZXdoZXJlIG9yIHdoaWNoIGFyZQogICAgICogcGFydCBvZiBhIGNvbXBsZXggY29tcG91bmQuIFRoZXkgd2lsbCBnZXQgcmVsZWFzZWQgd2hlbiBkZXN0cm95aW5nCiAgICAgKiB0aGUgcm9vdAogICAgICovCiAgICBpZiggKCFJbXBsLT5pc19jb21wbGV4X3Jvb3QpIHx8IChJbXBsLT5maXJzdF9hdHRhY2hlZCAhPSBJbXBsKSApCiAgICAgICAgcmV0dXJuIERERU5VTVJFVF9PSzsKICAgIC8qIFNraXAgb3VyIGRlcHRoIHN0ZW5jaWwgc3VyZmFjZSwgaXQgd2lsbCBiZSByZWxlYXNlZCB3aXRoIHRoZSByZW5kZXIgdGFyZ2V0ICovCiAgICBpZiggSW1wbCA9PSBkZHJhdy0+RGVwdGhTdGVuY2lsQnVmZmVyKQogICAgICAgIHJldHVybiBEREVOVU1SRVRfT0s7CgogICAgLyogRGVzdHJveSB0aGUgc3VyZmFjZSAqLwogICAgd2hpbGUocmVmKSByZWYgPSBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2Uoc3VyZik7CgogICAgcmV0dXJuIERERU5VTVJFVF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGdldF9jb25maWdfa2V5CiAqCiAqIFJlYWRzIGEgY29uZmlnIGtleSBmcm9tIHRoZSByZWdpc3RyeS4gVGFrZW4gZnJvbSBXaW5lRDNECiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIGlubGluZSBEV09SRCBnZXRfY29uZmlnX2tleShIS0VZIGRlZmtleSwgSEtFWSBhcHBrZXksIGNvbnN0IGNoYXIqIG5hbWUsIGNoYXIqIGJ1ZmZlciwgRFdPUkQgc2l6ZSkKewogICAgaWYgKDAgIT0gYXBwa2V5ICYmICFSZWdRdWVyeVZhbHVlRXhBKCBhcHBrZXksIG5hbWUsIDAsIE5VTEwsIChMUEJZVEUpIGJ1ZmZlciwgJnNpemUgKSkgcmV0dXJuIDA7CiAgICBpZiAoMCAhPSBkZWZrZXkgJiYgIVJlZ1F1ZXJ5VmFsdWVFeEEoIGRlZmtleSwgbmFtZSwgMCwgTlVMTCwgKExQQllURSkgYnVmZmVyLCAmc2l6ZSApKSByZXR1cm4gMDsKICAgIHJldHVybiBFUlJPUl9GSUxFX05PVF9GT1VORDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERsbE1haW4gKEREUkFXLjApCiAqCiAqIENvdWxkIGJlIHVzZWQgdG8gcmVnaXN0ZXIgRGlyZWN0RHJhdyBkcml2ZXJzLCBpZiB3ZSBoYXZlIG1vcmUgdGhhbgogKiBvbmUuIEFsc28gdXNlZCB0byBkZXN0cm95IGFueSBvYmplY3RzIGxlZnQgYXQgdW5sb2FkIGlmIHRoZQogKiBhcHAgZGlkbid0IHJlbGVhc2UgdGhlbSBwcm9wZXJseShHb3RoaWMgMiwgRGlhYmxvIDIsIE1vdG8gcmFjZXIsIC4uLikKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpCT09MIFdJTkFQSQpEbGxNYWluKEhJTlNUQU5DRSBoSW5zdERMTCwKICAgICAgICBEV09SRCBSZWFzb24sCiAgICAgICAgTFBWT0lEIGxwdikKewogICAgVFJBQ0UoIiglcCwleCwlcClcbiIsIGhJbnN0RExMLCBSZWFzb24sIGxwdik7CiAgICBpZiAoUmVhc29uID09IERMTF9QUk9DRVNTX0FUVEFDSCkKICAgIHsKICAgICAgICBjaGFyIGJ1ZmZlcltNQVhfUEFUSCsxMF07CiAgICAgICAgRFdPUkQgc2l6ZSA9IHNpemVvZihidWZmZXIpOwogICAgICAgIEhLRVkgaGtleSA9IDA7CiAgICAgICAgSEtFWSBhcHBrZXkgPSAwOwogICAgICAgIERXT1JEIGxlbjsKCiAgICAgICAvKiBAQCBXaW5lIHJlZ2lzdHJ5IGtleTogSEtDVVxTb2Z0d2FyZVxXaW5lXERpcmVjdDNEICovCiAgICAgICBpZiAoIFJlZ09wZW5LZXlBKCBIS0VZX0NVUlJFTlRfVVNFUiwgIlNvZnR3YXJlXFxXaW5lXFxEaXJlY3QzRCIsICZoa2V5ICkgKSBoa2V5ID0gMDsKCiAgICAgICBsZW4gPSBHZXRNb2R1bGVGaWxlTmFtZUEoIDAsIGJ1ZmZlciwgTUFYX1BBVEggKTsKICAgICAgIGlmIChsZW4gJiYgbGVuIDwgTUFYX1BBVEgpCiAgICAgICB7CiAgICAgICAgICAgIEhLRVkgdG1wa2V5OwogICAgICAgICAgICAvKiBAQCBXaW5lIHJlZ2lzdHJ5IGtleTogSEtDVVxTb2Z0d2FyZVxXaW5lXEFwcERlZmF1bHRzXGFwcC5leGVcRGlyZWN0M0QgKi8KICAgICAgICAgICAgaWYgKCFSZWdPcGVuS2V5QSggSEtFWV9DVVJSRU5UX1VTRVIsICJTb2Z0d2FyZVxcV2luZVxcQXBwRGVmYXVsdHMiLCAmdG1wa2V5ICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNoYXIgKnAsICphcHBuYW1lID0gYnVmZmVyOwogICAgICAgICAgICAgICAgaWYgKChwID0gc3RycmNociggYXBwbmFtZSwgJy8nICkpKSBhcHBuYW1lID0gcCArIDE7CiAgICAgICAgICAgICAgICBpZiAoKHAgPSBzdHJyY2hyKCBhcHBuYW1lLCAnXFwnICkpKSBhcHBuYW1lID0gcCArIDE7CiAgICAgICAgICAgICAgICBzdHJjYXQoIGFwcG5hbWUsICJcXERpcmVjdDNEIiApOwogICAgICAgICAgICAgICAgVFJBQ0UoImFwcG5hbWUgPSBbJXNdXG4iLCBhcHBuYW1lKTsKICAgICAgICAgICAgICAgIGlmIChSZWdPcGVuS2V5QSggdG1wa2V5LCBhcHBuYW1lLCAmYXBwa2V5ICkpIGFwcGtleSA9IDA7CiAgICAgICAgICAgICAgICBSZWdDbG9zZUtleSggdG1wa2V5ICk7CiAgICAgICAgICAgIH0KICAgICAgIH0KCiAgICAgICBpZiAoIDAgIT0gaGtleSB8fCAwICE9IGFwcGtleSApCiAgICAgICB7CiAgICAgICAgICAgIGlmICggIWdldF9jb25maWdfa2V5KCBoa2V5LCBhcHBrZXksICJEaXJlY3REcmF3UmVuZGVyZXIiLCBidWZmZXIsIHNpemUpICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCFzdHJjbXAoYnVmZmVyLCJnZGkiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiRGVmYXVsdGluZyB0byBHREkgc3VyZmFjZXNcbiIpOwogICAgICAgICAgICAgICAgICAgIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfR0RJOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoIXN0cmNtcChidWZmZXIsIm9wZW5nbCIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJEZWZhdWx0aW5nIHRvIG9wZW5nbCBzdXJmYWNlc1xuIik7CiAgICAgICAgICAgICAgICAgICAgRGVmYXVsdFN1cmZhY2VUeXBlID0gU1VSRkFDRV9PUEVOR0w7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJVbmtub3duIGRlZmF1bHQgc3VyZmFjZSB0eXBlLiBTdXBwb3J0ZWQgYXJlOlxuIGdkaSwgb3BlbmdsXG4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogT24gV2luZG93cyBvbmUgY2FuIGZvcmNlIHRoZSByZWZyZXNoIHJhdGUgdGhhdCBEaXJlY3REcmF3IHVzZXMgYnkKICAgICAgICAgKiBzZXR0aW5nIGFuIG92ZXJyaWRlIHZhbHVlIGluIGR4ZGlhZy4gIFRoaXMgaXMgZG9jdW1lbnRlZCBpbiBLQjMxNTYxNAogICAgICAgICAqIChtYWluIGFydGljbGUpLCBLQjIzMDAwMiwgYW5kIEtCMjE3MzQ4LiAgQnkgY29tcGFyaW5nIHJlZ2lzdHJ5IGR1bXBzCiAgICAgICAgICogYmVmb3JlIGFuZCBhZnRlciBzZXR0aW5nIHRoZSBvdmVycmlkZSwgd2Ugc2VlIHRoYXQgdGhlIG92ZXJyaWRlIHZhbHVlCiAgICAgICAgICogaXMgc3RvcmVkIGluIEhLTE1cU29mdHdhcmVcTWljcm9zb2Z0XERpcmVjdERyYXdcRm9yY2VSZWZyZXNoUmF0ZSBhcyBhCiAgICAgICAgICogRFdPUkQgdGhhdCByZXByZXNlbnRzIHRoZSByZWZyZXNoIHJhdGUgdG8gZm9yY2UuICBXZSB1c2UgdGhpcwogICAgICAgICAqIHJlZ2lzdHJ5IGVudHJ5IHRvIG1vZGlmeSB0aGUgYmVoYXZpb3Igb2YgU2V0RGlzcGxheU1vZGUgc28gdGhhdCBXaW5lCiAgICAgICAgICogdXNlcnMgY2FuIG92ZXJyaWRlIHRoZSByZWZyZXNoIHJhdGUgaW4gYSBXaW5kb3dzLWNvbXBhdGlibGUgd2F5LgogICAgICAgICAqCiAgICAgICAgICogZHhkaWFnIHdpbGwgbm90IGFjY2VwdCBhIHJlZnJlc2ggcmF0ZSBsb3dlciB0aGFuIDQwIG9yIGhpZ2hlciB0aGFuCiAgICAgICAgICogMTIwIHNvIHRoaXMgdmFsdWUgc2hvdWxkIGJlIHdpdGhpbiB0aGF0IHJhbmdlLiAgSXQgaXMsIG9mIGNvdXJzZSwKICAgICAgICAgKiBwb3NzaWJsZSBmb3IgYSB1c2VyIHRvIHNldCB0aGUgcmVnaXN0cnkgZW50cnkgdmFsdWUgZGlyZWN0bHkgc28gdGhhdAogICAgICAgICAqIGFzc3VtcHRpb24gbWlnaHQgbm90IGhvbGQuCiAgICAgICAgICoKICAgICAgICAgKiBUaGVyZSBpcyBubyBjdXJyZW50IG1lY2hhbmlzbSBmb3Igc2V0dGluZyB0aGlzIHZhbHVlIHRocm91Z2ggdGhlIFdpbmUKICAgICAgICAgKiBHVUkuICBJdCB3b3VsZCBiZSBtb3N0IGFwcHJvcHJpYXRlIHRvIHNldCB0aGlzIHZhbHVlIHRocm91Z2ggYSBkeGRpYWcKICAgICAgICAgKiBjbG9uZSwgYnV0IGl0IG1heSBiZSBzdWZmaWNpZW50IHRvIHVzZSB3aW5lY2ZnLgogICAgICAgICAqCiAgICAgICAgICogVE9ETzogQ3JlYXRlIGEgbWVjaGFuaXNtIGZvciBzZXR0aW5nIHRoaXMgdmFsdWUgdGhyb3VnaCB0aGUgV2luZSBHVUkuCiAgICAgICAgICovCiAgICAgICAgaWYgKCAhUmVnT3BlbktleUEoIEhLRVlfTE9DQUxfTUFDSElORSwgIlNvZnR3YXJlXFxNaWNyb3NvZnRcXERpcmVjdERyYXciLCAmaGtleSApICkKICAgICAgICB7CiAgICAgICAgICAgIERXT1JEIHR5cGUsIGRhdGE7CiAgICAgICAgICAgIHNpemUgPSBzaXplb2YoZGF0YSk7CiAgICAgICAgICAgIGlmICghUmVnUXVlcnlWYWx1ZUV4QSggaGtleSwgIkZvcmNlUmVmcmVzaFJhdGUiLCBOVUxMLCAmdHlwZSwgKExQQllURSkmZGF0YSwgJnNpemUgKSAmJiB0eXBlID09IFJFR19EV09SRCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgVFJBQ0UoIkZvcmNlUmVmcmVzaFJhdGUgc2V0OyBvdmVycmlkaW5nIHJlZnJlc2ggcmF0ZSB0byAlZCBIelxuIiwgZGF0YSk7CiAgICAgICAgICAgICAgICBmb3JjZV9yZWZyZXNoX3JhdGUgPSBkYXRhOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFJlZ0Nsb3NlS2V5KCBoa2V5ICk7CiAgICAgICAgfQoKICAgICAgICBEaXNhYmxlVGhyZWFkTGlicmFyeUNhbGxzKGhJbnN0RExMKTsKICAgIH0KICAgIGVsc2UgaWYgKFJlYXNvbiA9PSBETExfUFJPQ0VTU19ERVRBQ0gpCiAgICB7CiAgICAgICAgaWYoIWxpc3RfZW1wdHkoJmdsb2JhbF9kZHJhd19saXN0KSkKICAgICAgICB7CiAgICAgICAgICAgIHN0cnVjdCBsaXN0ICplbnRyeSwgKmVudHJ5MjsKICAgICAgICAgICAgV0FSTigiVGhlcmUgYXJlIHN0aWxsIGV4aXN0aW5nIERpcmVjdERyYXcgaW50ZXJmYWNlcy4gV2luZSBidWcgb3IgYnVnZ3kgYXBwbGljYXRpb24/XG4iKTsKCiAgICAgICAgICAgIC8qIFdlIHJlbW92ZSBlbGVtZXRzIGZyb20gdGhpcyBsb29wICovCiAgICAgICAgICAgIExJU1RfRk9SX0VBQ0hfU0FGRShlbnRyeSwgZW50cnkyLCAmZ2xvYmFsX2RkcmF3X2xpc3QpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEhSRVNVTFQgaHI7CiAgICAgICAgICAgICAgICBERFNVUkZBQ0VERVNDMiBkZXNjOwogICAgICAgICAgICAgICAgaW50IGk7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd0ltcGwgKmRkcmF3ID0gTElTVF9FTlRSWShlbnRyeSwgSURpcmVjdERyYXdJbXBsLCBkZHJhd19saXN0X2VudHJ5KTsKCiAgICAgICAgICAgICAgICBXQVJOKCJERHJhdyAlcCBoYXMgYSByZWZjb3VudCBvZiAlZFxuIiwgZGRyYXcsIGRkcmF3LT5yZWY3ICsgZGRyYXctPnJlZjQgKyBkZHJhdy0+cmVmMyArIGRkcmF3LT5yZWYyICsgZGRyYXctPnJlZjEpOwoKICAgICAgICAgICAgICAgIC8qIEFkZCByZWZlcmVuY2VzIHRvIGVhY2ggaW50ZXJmYWNlIHRvIGF2b2lkIGZyZWVpbmcgdGhlbSB1bmV4cGVjdGFkZWx5ICovCiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhd19BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3KSk7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhdzJfQWRkUmVmKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzIpKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3M19BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3MykpOwogICAgICAgICAgICAgICAgSURpcmVjdERyYXc0X0FkZFJlZihJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXc0KSk7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhdzdfQWRkUmVmKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzcpKTsKCiAgICAgICAgICAgICAgICAvKiBEb2VzIGEgRDNEIGRldmljZSBleGlzdD8gRGVzdHJveSBpdAogICAgICAgICAgICAgICAgICAgICogVE9ETzogRGVzdHJveSBhbGwgVmVydGV4IGJ1ZmZlcnMsIExpZ2h0cywgTWF0ZXJpYWxzCiAgICAgICAgICAgICAgICAgICAgKiBhbmQgZXhlY3R1cmUgYnVmZmVycyB0b28KICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYoZGRyYXctPmQzZGRldmljZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBXQVJOKCJERHJhdyAlcCBoYXMgZDNkZGV2aWNlICVwIGF0dGFjaGVkXG4iLCBkZHJhdywgZGRyYXctPmQzZGRldmljZSk7CiAgICAgICAgICAgICAgICAgICAgd2hpbGUoSURpcmVjdDNERGV2aWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LT5kM2RkZXZpY2UsIElEaXJlY3QzRERldmljZTcpKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyogVHJ5IHRvIHJlbGVhc2UgdGhlIG9iamVjdHMKICAgICAgICAgICAgICAgICAgICAqIERvIGFuIEVudW1TdXJmYWNlcyB0byBmaW5kIGFueSBoYW5naW5nIHN1cmZhY2VzCiAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIG1lbXNldCgmZGVzYywgMCwgc2l6ZW9mKGRlc2MpKTsKICAgICAgICAgICAgICAgIGRlc2MuZHdTaXplID0gc2l6ZW9mKGRlc2MpOwogICAgICAgICAgICAgICAgZm9yKGkgPSAwOyBpIDw9IDE7IGkrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBociA9IElEaXJlY3REcmF3N19FbnVtU3VyZmFjZXMoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3NyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEREVOVU1TVVJGQUNFU19BTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZGVzYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICopIGRkcmF3LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVzdHJveUNhbGxiYWNrKTsKICAgICAgICAgICAgICAgICAgICBpZihociAhPSBEM0RfT0spCiAgICAgICAgICAgICAgICAgICAgICAgIEVSUigiKCVwKSBFbnVtU3VyZmFjZXMgZmFpbGVkLCBwcmVwYXJlIGZvciB0cm91YmxlXG4iLCBkZHJhdyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyogQ2hlY2sgdGhlIHN1cmZhY2UgY291bnQgKi8KICAgICAgICAgICAgICAgIGlmKGRkcmF3LT5zdXJmYWNlcyA+IDApCiAgICAgICAgICAgICAgICAgICAgRVJSKCJERHJhdyAlcCBzdGlsbCBoYXMgJWQgc3VyZmFjZXMgYXR0YWNoZWRcbiIsIGRkcmF3LCBkZHJhdy0+c3VyZmFjZXMpOwoKICAgICAgICAgICAgICAgIC8qIFJlbGVhc2UgYWxsIGhhbmdpbmcgcmVmZXJlbmNlcyB0byBkZXN0cm95IHRoZSBvYmplY3RzLiBUaGlzCiAgICAgICAgICAgICAgICAgICAgKiByZXN0b3JlcyB0aGUgc2NyZWVuIG1vZGUgdG9vCiAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3REcmF3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3KSkpOwogICAgICAgICAgICAgICAgd2hpbGUoSURpcmVjdERyYXcyX1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3MikpKTsKICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3REcmF3M19SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzMpKSk7CiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhdzRfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXc0KSkpOwogICAgICAgICAgICAgICAgd2hpbGUoSURpcmVjdERyYXc3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3NykpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gVFJVRTsKfQo=