LyogICAgICAgIERpcmVjdERyYXcgQmFzZSBGdW5jdGlvbnMKICoKICogQ29weXJpZ2h0IDE5OTctMTk5OSBNYXJjdXMgTWVpc3NuZXIKICogQ29weXJpZ2h0IDE5OTggTGlvbmVsIFVsbWVyCiAqIENvcHlyaWdodCAyMDAwLTIwMDEgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYy4KICogQ29weXJpZ2h0IDIwMDYgU3RlZmFuIET2c2luZ2VyCiAqCiAqIFRoaXMgZmlsZSBjb250YWlucyB0aGUgKGludGVybmFsKSBkcml2ZXIgcmVnaXN0cmF0aW9uIGZ1bmN0aW9ucywKICogZHJpdmVyIGVudW1lcmF0aW9uIEFQSXMgYW5kIERpcmVjdERyYXcgY3JlYXRpb24gZnVuY3Rpb25zLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2luZS9leGNlcHRpb24uaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgImRkcmF3LmgiCiNpbmNsdWRlICJkM2QuaCIKCiNpbmNsdWRlICJkZHJhd19wcml2YXRlLmgiCgp0eXBlZGVmIElXaW5lRDNEKiAoV0lOQVBJICpmbldpbmVEaXJlY3QzRENyZWF0ZSkoVUlOVCwgVUlOVCwgSVVua25vd24gKik7CgpzdGF0aWMgSE1PRFVMRSBoV2luZUQzRCA9IChITU9EVUxFKSAtMTsKc3RhdGljIGZuV2luZURpcmVjdDNEQ3JlYXRlIHBXaW5lRGlyZWN0M0RDcmVhdGU7CgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkZHJhdyk7CgovKiBUaGUgY29uZmlndXJlZCBkZWZhdWx0IHN1cmZhY2UgKi8KV0lORUQzRFNVUkZUWVBFIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfVU5LTk9XTjsKCi8qIEREcmF3IGxpc3QgYW5kIGNyaXRpY2FsIHNlY3Rpb24gKi8Kc3RhdGljIHN0cnVjdCBsaXN0IGdsb2JhbF9kZHJhd19saXN0ID0gTElTVF9JTklUKGdsb2JhbF9kZHJhd19saXN0KTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGRkcmF3X2NzX2RlYnVnID0KewogICAgMCwgMCwgJmRkcmF3X2NzLAogICAgeyAmZGRyYXdfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwKICAgICZkZHJhd19jc19kZWJ1Zy5Qcm9jZXNzTG9ja3NMaXN0IH0sCiAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGRkcmF3X2NzIikgfQp9OwpDUklUSUNBTF9TRUNUSU9OIGRkcmF3X2NzID0geyAmZGRyYXdfY3NfZGVidWcsIC0xLCAwLCAwLCAwLCAwIH07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogSGVscGVyIGZ1bmN0aW9uIGZvciBEaXJlY3REcmF3Q3JlYXRlIGFuZCBmcmllbmRzCiAqIENyZWF0ZXMgYSBuZXcgRERyYXcgaW50ZXJmYWNlIHdpdGggdGhlIGdpdmVuIFJFRklJRAogKgogKiBJbnRlcmZhY2VzIHRoYXQgY2FuIGJlIGNyZWF0ZWQ6CiAqICBJRGlyZWN0RHJhdywgSURpcmVjdERyYXcyLCBJRGlyZWN0RHJhdzQsIElEaXJlY3REcmF3NwogKiAgSURpcmVjdDNELCBJRGlyZWN0M0QyLCBJRGlyZWN0M0QzLCBJRGlyZWN0M0Q3LiAoRG9lcyBXaW5kb3dzIHJldHVybgogKiAgSURpcmVjdDNEIGludGVyZmFjZXM/KQogKgogKiBBcmd1bWVudHM6CiAqICBndWlkOiBJRCBvZiB0aGUgcmVxdWVzdGVkIGRyaXZlciwgTlVMTCBmb3IgdGhlIGRlZmF1bHQgZHJpdmVyLgogKiAgICAgICAgVGhlIEdVSUQgY2FuIGJlIHF1ZXJpZWQgd2l0aCBEaXJlY3REcmF3RW51bWVyYXRlKEV4KUEvVwogKiAgREQ6IFVzZWQgdG8gcmV0dXJuIHRoZSBwb2ludGVyIHRvIHRoZSBjcmVhdGVkIG9iamVjdAogKiAgVW5rT3V0ZXI6IEZvciBhZ2dyZWdhdGlvbiwgd2hpY2ggaXMgdW5zdXBwb3J0ZWQuIE11c3QgYmUgTlVMTAogKiAgaWlkOiByZXF1ZXN0ZWQgdmVyc2lvbiBJRC4KICoKICogUmV0dXJuczoKICogIEREX09LIGlmIHRoZSBJbnRlcmZhY2Ugd2FzIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5CiAqICBDTEFTU19FX05PQUdHUkVHQVRJT04gaWYgVW5rT3V0ZXIgaXMgbm90IE5VTEwKICogIEVfT1VUT0ZNRU1PUlkgaWYgc29tZSBhbGxvY2F0aW9uIGZhaWxlZAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUCkREUkFXX0NyZWF0ZShjb25zdCBHVUlEICpndWlkLAogICAgICAgICAgICAgdm9pZCAqKkRELAogICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyLAogICAgICAgICAgICAgUkVGSUlEIGlpZCkKewogICAgSURpcmVjdERyYXdJbXBsICpUaGlzID0gTlVMTDsKICAgIEhSRVNVTFQgaHI7CiAgICBJV2luZUQzRCAqd2luZUQzRCA9IE5VTEw7CiAgICBJV2luZUQzRERldmljZSAqd2luZUQzRERldmljZSA9IE5VTEw7CiAgICBIREMgaERDOwogICAgV0lORUQzRERFVlRZUEUgZGV2aWNldHlwZTsKCiAgICBUUkFDRSgiKCVzLCVwLCVwKVxuIiwgZGVidWdzdHJfZ3VpZChndWlkKSwgREQsIFVua091dGVyKTsKCiAgICAqREQgPSBOVUxMOwoKICAgIC8qIFdlIGRvbid0IGNhcmUgYWJvdXQgdGhpcyBndWlkcy4gV2VsbCwgdGhlcmUncyBubyBzcGVjaWFsIGd1aWQgYW55d2F5CiAgICAgKiBPSywgd2UgY291bGQKICAgICAqLwogICAgaWYgKGd1aWQgPT0gKEdVSUQgKikgRERDUkVBVEVfRU1VTEFUSU9OT05MWSkKICAgIHsKICAgICAgICAvKiBVc2UgdGhlIHJlZmVyZW5jZSBkZXZpY2UgaWQuIFRoaXMgZG9lc24ndCBhY3R1YWxseSBjaGFuZ2UgYW55dGhpbmcsCiAgICAgICAgICogV2luZUQzRCBhbHdheXMgdXNlcyBPcGVuR0wgZm9yIEQzRCByZW5kZXJpbmcuIE9uZSBjb3VsZCBtYWtlIGl0IHJlcXVlc3QKICAgICAgICAgKiBpbmRpcmVjdCByZW5kZXJpbmcKICAgICAgICAgKi8KICAgICAgICBkZXZpY2V0eXBlID0gV0lORUQzRERFVlRZUEVfUkVGOwogICAgfQogICAgZWxzZSBpZihndWlkID09IChHVUlEICopIEREQ1JFQVRFX0hBUkRXQVJFT05MWSkKICAgIHsKICAgICAgICBkZXZpY2V0eXBlID0gV0lORUQzRERFVlRZUEVfSEFMOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGRldmljZXR5cGUgPSAwOwogICAgfQoKICAgIC8qIEREcmF3IGRvZXNuJ3Qgc3VwcG9ydCBhZ2dyZWdhdGlvbiwgYWNjb3JkaW5nIHRvIG1zZG4gKi8KICAgIGlmIChVbmtPdXRlciAhPSBOVUxMKQogICAgICAgIHJldHVybiBDTEFTU19FX05PQUdHUkVHQVRJT047CgogICAgLyogRGlyZWN0RHJhdyBjcmVhdGlvbiBjb21lcyBoZXJlICovCiAgICBUaGlzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJRGlyZWN0RHJhd0ltcGwpKTsKICAgIGlmKCFUaGlzKQogICAgewogICAgICAgIEVSUigiT3V0IG9mIG1lbW9yeSB3aGVuIGNyZWF0aW5nIERpcmVjdERyYXdcbiIpOwogICAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwogICAgfQoKICAgIC8qIFRoZSBpbnRlcmZhY2VzOgogICAgICogSURpcmVjdERyYXcgYW5kIElEaXJlY3QzRCBhcmUgdGhlIHNhbWUgb2JqZWN0LAogICAgICogUXVlcnlJbnRlcmZhY2UgaXMgdXNlZCB0byBnZXQgb3RoZXIgaW50ZXJmYWNlcy4KICAgICAqLwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdywgIElEaXJlY3REcmF3MV9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXcyLCBJRGlyZWN0RHJhdzJfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3MywgSURpcmVjdERyYXczX1Z0YmwpOwogICAgSUNPTV9JTklUX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhdzQsIElEaXJlY3REcmF3NF9WdGJsKTsKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3LCBJRGlyZWN0RHJhdzdfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRCwgIElEaXJlY3QzRDFfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDIsIElEaXJlY3QzRDJfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDMsIElEaXJlY3QzRDNfVnRibCk7CiAgICBJQ09NX0lOSVRfSU5URVJGQUNFKFRoaXMsIElEaXJlY3QzRDcsIElEaXJlY3QzRDdfVnRibCk7CgogICAgLyogU2VlIGNvbW1lbnRzIGluIElEaXJlY3REcmF3SW1wbF9DcmVhdGVOZXdTdXJmYWNlIGZvciBhIGRlc2NyaXB0aW9uCiAgICAgKiBvZiB0aGlzIG1lbWJlci4KICAgICAqIFJlYWQgZnJvbSBhIHJlZ2lzdHJ5IGtleSwgc2hvdWxkIGFkZCBhIHdpbmVjZmcgb3B0aW9uIGxhdGVyCiAgICAgKi8KICAgIFRoaXMtPkltcGxUeXBlID0gRGVmYXVsdFN1cmZhY2VUeXBlOwoKICAgIC8qIEdldCB0aGUgY3VycmVudCBzY3JlZW4gc2V0dGluZ3MgKi8KICAgIGhEQyA9IEdldERDKDApOwogICAgVGhpcy0+b3JpZ19icHAgPSBHZXREZXZpY2VDYXBzKGhEQywgQklUU1BJWEVMKSAqIEdldERldmljZUNhcHMoaERDLCBQTEFORVMpOwogICAgUmVsZWFzZURDKDAsIGhEQyk7CiAgICBUaGlzLT5vcmlnX3dpZHRoID0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFNDUkVFTik7CiAgICBUaGlzLT5vcmlnX2hlaWdodCA9IEdldFN5c3RlbU1ldHJpY3MoU01fQ1lTQ1JFRU4pOwoKICAgIGlmIChoV2luZUQzRCA9PSAoSE1PRFVMRSkgLTEpCiAgICB7CiAgICAgICAgaFdpbmVEM0QgPSBMb2FkTGlicmFyeUEoIndpbmVkM2QiKTsKICAgICAgICBpZiAoaFdpbmVEM0QpCiAgICAgICAgewogICAgICAgICAgICBwV2luZURpcmVjdDNEQ3JlYXRlID0gKGZuV2luZURpcmVjdDNEQ3JlYXRlKSBHZXRQcm9jQWRkcmVzcyhoV2luZUQzRCwgIldpbmVEaXJlY3QzRENyZWF0ZSIpOwogICAgICAgICAgICBwV2luZURpcmVjdDNEQ3JlYXRlQ2xpcHBlciA9IChmbldpbmVEaXJlY3QzRENyZWF0ZUNsaXBwZXIpIEdldFByb2NBZGRyZXNzKGhXaW5lRDNELCAiV2luZURpcmVjdDNEQ3JlYXRlQ2xpcHBlciIpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoIWhXaW5lRDNEKQogICAgewogICAgICAgIEVSUigiQ291bGRuJ3QgbG9hZCBXaW5lRDNEIC0gT3BlbkdMIGxpYnMgbm90IHByZXNlbnQ/XG4iKTsKICAgICAgICBociA9IERERVJSX05PRElSRUNURFJBV1NVUFBPUlQ7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQoKICAgIC8qIEluaXRpYWxpemUgV2luZUQzRAogICAgICoKICAgICAqIEFsbCBSZW5kZXJpbmcgKDJEIGFuZCAzRCkgaXMgcmVsYXllZCB0byBXaW5lRDNELAogICAgICogYnV0IERpcmVjdERyYXcgc3BlY2lmaWMgbWFuYWdlbWVudCwgbGlrZSBERFNVUkZBQ0VERVNDIGFuZCBERFBJWEVMRk9STUFUCiAgICAgKiBzdHJ1Y3R1cmUgaGFuZGxpbmcgaXMgaGFuZGxlZCBpbiB0aGlzIGxpYi4KICAgICAqLwogICAgd2luZUQzRCA9IHBXaW5lRGlyZWN0M0RDcmVhdGUoMCAvKiBTREtWZXJzaW9uICovLCA3IC8qIERYVmVyc2lvbiAqLywgKElVbmtub3duICopIFRoaXMgLyogUGFyZW50ICovKTsKICAgIGlmKCF3aW5lRDNEKQogICAgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGluaXRpYWxpc2UgV2luZUQzRFxuIik7CiAgICAgICAgaHIgPSBFX09VVE9GTUVNT1JZOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KICAgIFRoaXMtPndpbmVEM0QgPSB3aW5lRDNEOwogICAgVFJBQ0UoIldpbmVEM0QgY3JlYXRlZCBhdCAlcFxuIiwgd2luZUQzRCk7CgogICAgLyogSW5pdGlhbGl6ZWQgbWVtYmVyLi4uCiAgICAgKgogICAgICogSXQgaXMgc2V0IHRvIGZhbHNlIGF0IGNyZWF0aW9uIHRpbWUsIGFuZCBzZXQgdG8gdHJ1ZSBpbgogICAgICogSURpcmVjdERyYXc3OjpJbml0aWFsaXplLiBJdHMgc29sZSBwdXJwb3NlIGlzIHRvIHJldHVybiBERF9PSyBvbgogICAgICogaW5pdGlhbGl6ZSBvbmx5IG9uY2UKICAgICAqLwogICAgVGhpcy0+aW5pdGlhbGl6ZWQgPSBGQUxTRTsKCiAgICAvKiBJbml0aWFsaXplIFdpbmVEM0REZXZpY2UKICAgICAqCiAgICAgKiBJdCBpcyB1c2VkIGZvciBzY3JlZW4gc2V0dXAsIHN1cmZhY2UgYW5kIHBhbGV0dGUgY3JlYXRpb24KICAgICAqIFdoZW4gYSBEaXJlY3QzRERldmljZTcgaXMgY3JlYXRlZCwgdGhlIEQzRCBjYXBhYmlsaXRpZXMgb2YgV2luZUQzRCBhcmUKICAgICAqIGluaXRpYWxpemVkCiAgICAgKi8KICAgIGhyID0gSVdpbmVEM0RfQ3JlYXRlRGV2aWNlKHdpbmVEM0QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qRDNEX0FEQVBURVJfREVGQVVMVCovLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNldHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIC8qIEZvY3VzV2luZG93LCBkb24ndCBrbm93IHlldCAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgLyogQmVoYXZpb3JGbGFncyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoSVVua25vd24gKikgSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSk7CiAgICBpZihGQUlMRUQoaHIpKQogICAgewogICAgICAgIEVSUigiRmFpbGVkIHRvIGNyZWF0ZSBhIHdpbmVEM0REZXZpY2UsIHJlc3VsdCA9ICV4XG4iLCBocik7CiAgICAgICAgZ290byBlcnJfb3V0OwogICAgfQogICAgVGhpcy0+d2luZUQzRERldmljZSA9IHdpbmVEM0REZXZpY2U7CiAgICBUUkFDRSgid2luZUQzRERldmljZSBjcmVhdGVkIGF0ICVwXG4iLCBUaGlzLT53aW5lRDNERGV2aWNlKTsKCiAgICAvKiBSZWdpc3RlciB0aGUgd2luZG93IGNsYXNzCiAgICAgKgogICAgICogSXQgaXMgdXNlZCB0byBjcmVhdGUgYSBoaWRkZW4gd2luZG93IGZvciBEM0QKICAgICAqIHJlbmRlcmluZywgaWYgdGhlIGFwcGxpY2F0aW9uIGRpZG4ndCBwYXNzIG9uZS4KICAgICAqIEl0IGNhbiBhbHNvIGJlIHVzZWQgZm9yIENyZWF0aW5nIGEgZGV2aWNlIHdpbmRvdwogICAgICogZnJvbSBTZXRDb29wZXJhdGl2ZUxldmVsCiAgICAgKgogICAgICogVGhlIG5hbWU6IEREUkFXXzxhZGRyZXNzPi4gVGhlIGNsYXNzbmFtZSBpcwogICAgICogMzIgYml0IGxvbmcsIHNvIGEgNjQgYml0IGFkZHJlc3Mgd2lsbCBmaXQgbmljZWx5CiAgICAgKiAoV2lsbCB0aGlzIGJlIGNvbXBpbGVkIGZvciA2NCBiaXQgYW55d2F5PykKICAgICAqCiAgICAgKi8KICAgIHNwcmludGYoVGhpcy0+Y2xhc3NuYW1lLCAiRERSQVdfJXAiLCBUaGlzKTsKCiAgICBtZW1zZXQoJlRoaXMtPnduZF9jbGFzcywgMCwgc2l6ZW9mKFRoaXMtPnduZF9jbGFzcykpOwogICAgVGhpcy0+d25kX2NsYXNzLnN0eWxlID0gQ1NfSFJFRFJBVyB8IENTX1ZSRURSQVc7CiAgICBUaGlzLT53bmRfY2xhc3MubHBmblduZFByb2MgPSBEZWZXaW5kb3dQcm9jQTsKICAgIFRoaXMtPnduZF9jbGFzcy5jYkNsc0V4dHJhID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5jYlduZEV4dHJhID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5oSW5zdGFuY2UgPSBHZXRNb2R1bGVIYW5kbGVBKDApOwogICAgVGhpcy0+d25kX2NsYXNzLmhJY29uID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5oQ3Vyc29yID0gMDsKICAgIFRoaXMtPnduZF9jbGFzcy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSCkgR2V0U3RvY2tPYmplY3QoQkxBQ0tfQlJVU0gpOwogICAgVGhpcy0+d25kX2NsYXNzLmxwc3pNZW51TmFtZSA9IE5VTEw7CiAgICBUaGlzLT53bmRfY2xhc3MubHBzekNsYXNzTmFtZSA9IFRoaXMtPmNsYXNzbmFtZTsKICAgIGlmKCFSZWdpc3RlckNsYXNzQSgmVGhpcy0+d25kX2NsYXNzKSkKICAgIHsKICAgICAgICBFUlIoIlJlZ2lzdGVyQ2xhc3NBIGZhaWxlZCFcbiIpOwogICAgICAgIGdvdG8gZXJyX291dDsKICAgIH0KCiAgICAvKiBHZXQgdGhlIGFtb3VudCBvZiB2aWRlbyBtZW1vcnkgKi8KICAgIFRoaXMtPnRvdGFsX3ZpZG1lbSA9IElXaW5lRDNERGV2aWNlX0dldEF2YWlsYWJsZVRleHR1cmVNZW0oVGhpcy0+d2luZUQzRERldmljZSk7CgogICAgLyogSW5pdGlhbGl6ZSB0aGUgY2FwcyAqLwogICAgVGhpcy0+Y2Fwcy5kd1NpemUgPSBzaXplb2YoVGhpcy0+Y2Fwcyk7Ci8qIGRvIG5vdCByZXBvcnQgRERDQVBTX09WRVJMQVkgYW5kIGZyaWVuZHMgc2luY2Ugd2UgZG9uJ3Qgc3VwcG9ydCBvdmVybGF5cyAqLwojZGVmaW5lIEJMSVRfQ0FQUyAoRERDQVBTX0JMVCB8IEREQ0FQU19CTFRDT0xPUkZJTEwgfCBERENBUFNfQkxUREVQVEhGSUxMIFwKICAgICAgICAgIHwgRERDQVBTX0JMVFNUUkVUQ0ggfCBERENBUFNfQ0FOQkxUU1lTTUVNIHwgRERDQVBTX0NBTkNMSVAJICBcCiAgICAgICAgICB8IEREQ0FQU19DQU5DTElQU1RSRVRDSEVEIHwgRERDQVBTX0NPTE9SS0VZCQkJICBcCiAgICAgICAgICB8IEREQ0FQU19DT0xPUktFWUhXQVNTSVNUIHwgRERDQVBTX0FMSUdOQk9VTkRBUllTUkMgKQojZGVmaW5lIENLRVlfQ0FQUyAoRERDS0VZQ0FQU19ERVNUQkxUIHwgRERDS0VZQ0FQU19TUkNCTFQpCiNkZWZpbmUgRlhfQ0FQUyAoRERGWENBUFNfQkxUQUxQSEEgfCBEREZYQ0FQU19CTFRNSVJST1JMRUZUUklHSFQJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRNSVJST1JVUERPV04gfCBEREZYQ0FQU19CTFRST1RBVElPTjkwCVwKICAgICAgICAgICAgICAgIHwgRERGWENBUFNfQkxUU0hSSU5LWCB8IERERlhDQVBTX0JMVFNIUklOS1hOCQlcCiAgICAgICAgICAgICAgICB8IERERlhDQVBTX0JMVFNIUklOS1kgfCBEREZYQ0FQU19CTFRTSFJJTktYTgkJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRTVFJFVENIWCB8IERERlhDQVBTX0JMVFNUUkVUQ0hYTgkJXAogICAgICAgICAgICAgICAgfCBEREZYQ0FQU19CTFRTVFJFVENIWSB8IERERlhDQVBTX0JMVFNUUkVUQ0hZTikKICAgIFRoaXMtPmNhcHMuZHdDYXBzIHw9IEREQ0FQU19HREkgfCBERENBUFNfUEFMRVRURSB8IEJMSVRfQ0FQUzsKCiAgICBUaGlzLT5jYXBzLmR3Q2FwczIgfD0gRERDQVBTMl9DRVJUSUZJRUQgfCBERENBUFMyX05PUEFHRUxPQ0tSRVFVSVJFRCB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgRERDQVBTMl9QUklNQVJZR0FNTUEgfCBERENBUFMyX1dJREVTVVJGQUNFUyB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgRERDQVBTMl9DQU5SRU5ERVJXSU5ET1dFRDsKICAgIFRoaXMtPmNhcHMuZHdDS2V5Q2FwcyB8PSBDS0VZX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3RlhDYXBzIHw9IEZYX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3UGFsQ2FwcyB8PSBERFBDQVBTXzhCSVQgfCBERFBDQVBTX1BSSU1BUllTVVJGQUNFOwogICAgVGhpcy0+Y2Fwcy5kd1ZpZE1lbVRvdGFsID0gVGhpcy0+dG90YWxfdmlkbWVtOwogICAgVGhpcy0+Y2Fwcy5kd1ZpZE1lbUZyZWUgPSBUaGlzLT50b3RhbF92aWRtZW07CiAgICBUaGlzLT5jYXBzLmR3U1ZCQ2FwcyB8PSBCTElUX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3U1ZCQ0tleUNhcHMgfD0gQ0tFWV9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1NWQkZYQ2FwcyB8PSBGWF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1ZTQkNhcHMgfD0gQkxJVF9DQVBTOwogICAgVGhpcy0+Y2Fwcy5kd1ZTQkNLZXlDYXBzIHw9IENLRVlfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdWU0JGWENhcHMgfD0gRlhfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTU0JDYXBzIHw9IEJMSVRfQ0FQUzsKICAgIFRoaXMtPmNhcHMuZHdTU0JDS2V5Q2FwcyB8PSBDS0VZX0NBUFM7CiAgICBUaGlzLT5jYXBzLmR3U1NCRlhDYXBzIHw9IEZYX0NBUFM7CiAgICBUaGlzLT5jYXBzLmRkc0NhcHMuZHdDYXBzIHw9IEREU0NBUFNfQUxQSEEgfCBERFNDQVBTX0JBQ0tCVUZGRVIgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBERFNDQVBTX0ZMSVAgfCBERFNDQVBTX0ZST05UQlVGRkVSIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRERTQ0FQU19PRkZTQ1JFRU5QTEFJTiB8IEREU0NBUFNfUEFMRVRURSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UgfCBERFNDQVBTX1NZU1RFTU1FTU9SWSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEREU0NBUFNfVklERU9NRU1PUlkgfCBERFNDQVBTX1ZJU0lCTEU7CiAgICAvKiBIYWNrcyBmb3IgRDNEIGNvZGUgKi8KICAgIC8qIFRPRE86IENoZWNrIGlmIFdpbmVEM0QgaGFzIDNEIGVuYWJsZWQKICAgICAgIE5lZWQgb3BlbmdsIHN1cmZhY2VzIG9yIGF1dG8gZm9yIDNECiAgICAgKi8KICAgIGlmKFRoaXMtPkltcGxUeXBlID09IDAgfHwgVGhpcy0+SW1wbFR5cGUgPT0gU1VSRkFDRV9PUEVOR0wpCiAgICB7CiAgICAgICAgVGhpcy0+Y2Fwcy5kd0NhcHMgfD0gRERDQVBTXzNEOwogICAgICAgIFRoaXMtPmNhcHMuZGRzQ2Fwcy5kd0NhcHMgfD0gRERTQ0FQU18zRERFVklDRSB8IEREU0NBUFNfTUlQTUFQIHwgRERTQ0FQU19URVhUVVJFIHwgRERTQ0FQU19aQlVGRkVSOwogICAgfQogICAgVGhpcy0+Y2Fwcy5kZHNPbGRDYXBzLmR3Q2FwcyA9IFRoaXMtPmNhcHMuZGRzQ2Fwcy5kd0NhcHM7CgojdW5kZWYgQkxJVF9DQVBTCiN1bmRlZiBDS0VZX0NBUFMKI3VuZGVmIEZYX0NBUFMKCiAgICBsaXN0X2luaXQoJlRoaXMtPnN1cmZhY2VfbGlzdCk7CiAgICBsaXN0X2FkZF9oZWFkKCZnbG9iYWxfZGRyYXdfbGlzdCwgJlRoaXMtPmRkcmF3X2xpc3RfZW50cnkpOwoKICAgIC8qIENhbGwgUXVlcnlJbnRlcmZhY2UgdG8gZ2V0IHRoZSBwb2ludGVyIHRvIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLiBUaGlzIGFsc28gaW5pdGlhbGl6ZXMKICAgICAqIFRoZSByZXF1aXJlZCByZWZjb3VudAogICAgICovCiAgICBociA9IElEaXJlY3REcmF3N19RdWVyeUludGVyZmFjZSggSUNPTV9JTlRFUkZBQ0UoVGhpcywgSURpcmVjdERyYXc3KSwgaWlkLCBERCk7CiAgICBpZihTVUNDRUVERUQoaHIpKSByZXR1cm4gRERfT0s7CgplcnJfb3V0OgogICAgLyogTGV0J3MgaG9wZSB3ZSBuZXZlciBuZWVkIHRoaXMgOykgKi8KICAgIGlmKHdpbmVEM0REZXZpY2UpIElXaW5lRDNERGV2aWNlX1JlbGVhc2Uod2luZUQzRERldmljZSk7CiAgICBpZih3aW5lRDNEKSBJV2luZUQzRF9SZWxlYXNlKHdpbmVEM0QpOwogICAgaWYoVGhpcykgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+ZGVjbHMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3Q3JlYXRlIChERFJBVy5AKQogKgogKiBDcmVhdGVzIGxlZ2FjeSBEaXJlY3REcmF3IEludGVyZmFjZXMuIENhbid0IGNyZWF0ZSBJRGlyZWN0RHJhdzcKICogaW50ZXJmYWNlcyBpbiB0aGVvcnkKICoKICogQXJndW1lbnRzLCByZXR1cm4gdmFsdWVzOiBTZWUgRERSQVdfQ3JlYXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKRGlyZWN0RHJhd0NyZWF0ZShHVUlEICpHVUlELAogICAgICAgICAgICAgICAgIExQRElSRUNURFJBVyAqREQsCiAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyKQp7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcywlcCwlcClcbiIsIGRlYnVnc3RyX2d1aWQoR1VJRCksIERELCBVbmtPdXRlcik7CgogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIGhyID0gRERSQVdfQ3JlYXRlKEdVSUQsICh2b2lkICoqKSBERCwgVW5rT3V0ZXIsICZJSURfSURpcmVjdERyYXcpOwogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERpcmVjdERyYXdDcmVhdGVFeCAoRERSQVcuQCkKICoKICogT25seSBjcmVhdGVzIG5ldyBJRGlyZWN0RHJhdzcgaW50ZXJmYWNlcywgc3VwcG9zZWQgdG8gZmFpbCBpZiBsZWdhY3kKICogaW50ZXJmYWNlcyBhcmUgcmVxdWVzdGVkLgogKgogKiBBcmd1bWVudHMsIHJldHVybiB2YWx1ZXM6IFNlZSBERFJBV19DcmVhdGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpEaXJlY3REcmF3Q3JlYXRlRXgoR1VJRCAqR1VJRCwKICAgICAgICAgICAgICAgICAgIExQVk9JRCAqREQsCiAgICAgICAgICAgICAgICAgICBSRUZJSUQgaWlkLAogICAgICAgICAgICAgICAgICAgSVVua25vd24gKlVua091dGVyKQp7CiAgICBIUkVTVUxUIGhyOwogICAgVFJBQ0UoIiglcywlcCwlcywlcClcbiIsIGRlYnVnc3RyX2d1aWQoR1VJRCksIERELCBkZWJ1Z3N0cl9ndWlkKGlpZCksIFVua091dGVyKTsKCiAgICBpZiAoIUlzRXF1YWxHVUlEKGlpZCwgJklJRF9JRGlyZWN0RHJhdzcpKQogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IEREUkFXX0NyZWF0ZShHVUlELCBERCwgVW5rT3V0ZXIsIGlpZCk7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIGhyOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0VudW1lcmF0ZUEgKEREUkFXLkApCiAqCiAqIEVudW1lcmF0ZXMgbGVnYWN5IGRkcmF3IGRyaXZlcnMsIGFzY2lpIHZlcnNpb24uIFdlIG9ubHkgaGF2ZSBvbmUKICogZHJpdmVyLCB3aGljaCByZWxheXMgdG8gV2luZUQzRC4gSWYgd2Ugd2VyZSBzdWZmaWNpZW50bHkgY29vbCwKICogd2UgY291bGQgb2ZmZXIgdmFyaW91cyBpbnRlcmZhY2VzLCB3aGljaCB1c2UgYSBkaWZmZXJlbnQgZGVmYXVsdCBzdXJmYWNlCiAqIGltcGxlbWVudGF0aW9uLCBidXQgSSB0aGluayBpdCdzIGJldHRlciB0byBvZmZlciB0aGlzIGNob2ljZSBpbgogKiB3aW5lY2ZnLCBiZWNhdXNlIHNvbWUgYXBwcyB1c2UgdGhlIGRlZmF1bHQgZHJpdmVyLCBzbyB3ZSB3b3VsZCBuZWVkCiAqIGEgd2luZWNmZyBvcHRpb24gYW55d2F5LCBhbmQgdGhlcmUgc2hvdWxkbid0IGJlIDIgd2F5cyB0byBzZXQgb25lIHNldHRpbmcKICoKICogQXJndW1lbnRzOgogKiAgQ2FsbGJhY2s6IENhbGxiYWNrIGZ1bmN0aW9uIGZyb20gdGhlIGFwcAogKiAgQ29udGV4dDogQXJndW1lbnQgdG8gdGhlIGNhbGwgYmFjay4KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIEVfSU5WQUxJREFSRyBpZiB0aGUgQ2FsbGJhY2sgY2F1c2VkIGEgcGFnZSBmYXVsdAogKgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCkhSRVNVTFQgV0lOQVBJCkRpcmVjdERyYXdFbnVtZXJhdGVBKExQRERFTlVNQ0FMTEJBQ0tBIENhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICBMUFZPSUQgQ29udGV4dCkKewogICAgQk9PTCBzdG9wID0gRkFMU0U7CgogICAgVFJBQ0UoIiBFbnVtZXJhdGluZyBkZWZhdWx0IERpcmVjdERyYXcgSEFMIGludGVyZmFjZVxuIik7CiAgICAvKiBXZSBvbmx5IGhhdmUgb25lIGRyaXZlciAqLwogICAgX19UUlkKICAgIHsKICAgICAgICBzdGF0aWMgQ0hBUiBkcml2ZXJfZGVzY1tdID0gIkRpcmVjdERyYXcgSEFMIiwKICAgICAgICBkcml2ZXJfbmFtZVtdID0gImRpc3BsYXkiOwoKICAgICAgICBzdG9wID0gIUNhbGxiYWNrKE5VTEwsIGRyaXZlcl9kZXNjLCBkcml2ZXJfbmFtZSwgQ29udGV4dCk7CiAgICB9CiAgICBfX0VYQ0VQVF9QQUdFX0ZBVUxUCiAgICB7CiAgICAgICAgcmV0dXJuIEVfSU5WQUxJREFSRzsKICAgIH0KICAgIF9fRU5EVFJZCgogICAgVFJBQ0UoIiBFbmQgb2YgZW51bWVyYXRpb25cbiIpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0VudW1lcmF0ZUV4QSAoRERSQVcuQCkKICoKICogRW51bWVyYXRlcyBEaXJlY3REcmF3NyBkcml2ZXJzLCBhc2NpaSB2ZXJzaW9uLiBTZWUKICogdGhlIGNvbW1lbnRzIGFib3ZlIERpcmVjdERyYXdFbnVtZXJhdGVBIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFRoZSBGbGFnIG1lbWJlciBpcyBub3Qgc3VwcG9ydGVkIHJpZ2h0IG5vdy4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpEaXJlY3REcmF3RW51bWVyYXRlRXhBKExQRERFTlVNQ0FMTEJBQ0tFWEEgQ2FsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgTFBWT0lEIENvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgRmxhZ3MpCnsKICAgIEJPT0wgc3RvcCA9IEZBTFNFOwogICAgVFJBQ0UoIkVudW1lcmF0aW5nIGRlZmF1bHQgRGlyZWN0RHJhdyBIQUwgaW50ZXJmYWNlXG4iKTsKCiAgICAvKiBXZSBvbmx5IGhhdmUgb25lIGRyaXZlciBieSBub3cgKi8KICAgIF9fVFJZCiAgICB7CiAgICAgICAgc3RhdGljIENIQVIgZHJpdmVyX2Rlc2NbXSA9ICJEaXJlY3REcmF3IEhBTCIsCiAgICAgICAgZHJpdmVyX25hbWVbXSA9ICJkaXNwbGF5IjsKCiAgICAgICAgLyogUXVpY2tUaW1lIGV4cGVjdHMgdGhlIGRlc2NyaXB0aW9uICJEaXJlY3REcmF3IEhBTCIgKi8KICAgICAgICBzdG9wID0gIUNhbGxiYWNrKE5VTEwsIGRyaXZlcl9kZXNjLCBkcml2ZXJfbmFtZSwgQ29udGV4dCwgMCk7CiAgICB9CiAgICBfX0VYQ0VQVF9QQUdFX0ZBVUxUCiAgICB7CiAgICAgICAgcmV0dXJuIEVfSU5WQUxJREFSRzsKICAgIH0KICAgIF9fRU5EVFJZOwoKICAgIFRSQUNFKCJFbmQgb2YgZW51bWVyYXRpb25cbiIpOwogICAgcmV0dXJuIEREX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGlyZWN0RHJhd0VudW1lcmF0ZVcgKEREUkFXLkApCiAqCiAqIEVudW1lcmF0ZXMgbGVnYWN5IGRyaXZlcnMsIHVuaWNvZGUgdmVyc2lvbi4gU2VlCiAqIHRoZSBjb21tZW50cyBhYm92ZSBEaXJlY3REcmF3RW51bWVyYXRlQSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgRmxhZyBtZW1iZXIgaXMgbm90IHN1cHBvcnRlZCByaWdodCBub3cuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEaXJlY3REcmF3RW51bWVyYXRlRXhXIChERFJBVy5AKQogKgogKiBFbnVtZXJhdGVzIERpcmVjdERyYXc3IGRyaXZlcnMsIHVuaWNvZGUgdmVyc2lvbi4gU2VlCiAqIHRoZSBjb21tZW50cyBhYm92ZSBEaXJlY3REcmF3RW51bWVyYXRlQSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBUaGUgRmxhZyBtZW1iZXIgaXMgbm90IHN1cHBvcnRlZCByaWdodCBub3cuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDbGFzc2ZhY3RvcnkgaW1wbGVtZW50YXRpb24uCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDRl9DcmVhdGVEaXJlY3REcmF3CiAqCiAqIEREcmF3IGNyZWF0aW9uIGZ1bmN0aW9uIGZvciB0aGUgY2xhc3MgZmFjdG9yeQogKgogKiBQYXJhbXM6CiAqICBVbmtPdXRlcjogU2V0IHRvIE5VTEwKICogIGlpZDogSUQgb2YgdGhlIHdhbnRlZCBpbnRlcmZhY2UKICogIG9iajogQWRkcmVzcyB0byBwYXNzIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBiYWNrCiAqCiAqIFJldHVybnMKICogIEREX09LIC8gRERFUlIqLCBzZWUgRERSQVdfQ3JlYXRlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKQ0ZfQ3JlYXRlRGlyZWN0RHJhdyhJVW5rbm93biogVW5rT3V0ZXIsIFJFRklJRCBpaWQsCiAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSFJFU1VMVCBocjsKCiAgICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgVW5rT3V0ZXIsIGRlYnVnc3RyX2d1aWQoaWlkKSwgb2JqKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaHIgPSBERFJBV19DcmVhdGUoTlVMTCwgb2JqLCBVbmtPdXRlciwgaWlkKTsKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBDRl9DcmVhdGVEaXJlY3REcmF3CiAqCiAqIENsaXBwZXIgY3JlYXRpb24gZnVuY3Rpb24gZm9yIHRoZSBjbGFzcyBmYWN0b3J5CiAqCiAqIFBhcmFtczoKICogIFVua091dGVyOiBTZXQgdG8gTlVMTAogKiAgaWlkOiBJRCBvZiB0aGUgd2FudGVkIGludGVyZmFjZQogKiAgb2JqOiBBZGRyZXNzIHRvIHBhc3MgdGhlIGludGVyZmFjZSBwb2ludGVyIGJhY2sKICoKICogUmV0dXJucwogKiAgRERfT0sgLyBEREVSUiosIHNlZSBERFJBV19DcmVhdGUKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVApDRl9DcmVhdGVEaXJlY3REcmF3Q2xpcHBlcihJVW5rbm93biogVW5rT3V0ZXIsIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBIUkVTVUxUIGhyOwogICAgSURpcmVjdERyYXdDbGlwcGVyICpDbGlwOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IERpcmVjdERyYXdDcmVhdGVDbGlwcGVyKDAsICZDbGlwLCBVbmtPdXRlcik7CiAgICBpZiAoaHIgIT0gRERfT0spCiAgICB7CiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgaHIgPSBJRGlyZWN0RHJhd0NsaXBwZXJfUXVlcnlJbnRlcmZhY2UoQ2xpcCwgcmlpZCwgb2JqKTsKICAgIElEaXJlY3REcmF3Q2xpcHBlcl9SZWxlYXNlKENsaXApOwoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3Qgb2JqZWN0X2NyZWF0aW9uX2luZm8gb2JqZWN0X2NyZWF0aW9uW10gPQp7CiAgICB7ICZDTFNJRF9EaXJlY3REcmF3LCAgICAgICAgQ0ZfQ3JlYXRlRGlyZWN0RHJhdyB9LAogICAgeyAmQ0xTSURfRGlyZWN0RHJhdzcsICAgICAgIENGX0NyZWF0ZURpcmVjdERyYXcgfSwKICAgIHsgJkNMU0lEX0RpcmVjdERyYXdDbGlwcGVyLCBDRl9DcmVhdGVEaXJlY3REcmF3Q2xpcHBlciB9Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeTo6UXVlcnlJbnRlcmZhY2UKICoKICogUXVlcnlJbnRlcmZhY2UgZm9yIHRoZSBjbGFzcyBmYWN0b3J5CiAqCiAqIFBBUkFNUwogKiAgICByaWlkICAgUmVmZXJlbmNlIHRvIGlkZW50aWZpZXIgb2YgcXVlcmllZCBpbnRlcmZhY2UKICogICAgcHB2ICAgIEFkZHJlc3MgdG8gcmV0dXJuIHRoZSBpbnRlcmZhY2UgcG9pbnRlciBhdAogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFNfT0sKICogICAgRmFpbHVyZTogRV9OT0lOVEVSRkFDRQogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9RdWVyeUludGVyZmFjZShJQ2xhc3NGYWN0b3J5ICppZmFjZSwKICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICB2b2lkICoqb2JqKQp7CiAgICBJQ09NX1RISVNfRlJPTShJQ2xhc3NGYWN0b3J5SW1wbCwgSUNsYXNzRmFjdG9yeSwgaWZhY2UpOwoKICAgIFRSQUNFKCIoJXApLT4oJXMsJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBvYmopOwoKICAgIGlmIChJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lVbmtub3duKQogICAgICAgIHx8IElzRXF1YWxHVUlEKHJpaWQsICZJSURfSUNsYXNzRmFjdG9yeSkpCiAgICB7CiAgICAgICAgSUNsYXNzRmFjdG9yeV9BZGRSZWYoaWZhY2UpOwogICAgICAgICpvYmogPSBUaGlzOwogICAgICAgIHJldHVybiBTX09LOwogICAgfQoKICAgIFdBUk4oIiglcCktPiglcywlcCksbm90IGZvdW5kXG4iLFRoaXMsZGVidWdzdHJfZ3VpZChyaWlkKSxvYmopOwogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5OjpBZGRSZWYKICoKICogQWRkUmVmIGZvciB0aGUgY2xhc3MgZmFjdG9yeQogKgogKiBSRVRVUk5TCiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3Q2xhc3NGYWN0b3J5SW1wbF9BZGRSZWYoSUNsYXNzRmFjdG9yeSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElDbGFzc0ZhY3RvcnlJbXBsLCBJQ2xhc3NGYWN0b3J5LCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKS0+KCkgaW5jcmVtZW50aW5nIGZyb20gJWQuXG4iLCBUaGlzLCByZWYgLSAxKTsKCiAgICByZXR1cm4gcmVmOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeTo6UmVsZWFzZQogKgogKiBSZWxlYXNlIGZvciB0aGUgY2xhc3MgZmFjdG9yeS4gSWYgdGhlIHJlZmNvdW50IGZhbGxzIHRvIDAsIHRoZSBvYmplY3QKICogaXMgZGVzdHJveWVkCiAqCiAqIFJFVFVSTlMKICogIFRoZSBuZXcgcmVmY291bnQKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBVTE9ORyBXSU5BUEkKSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX1JlbGVhc2UoSUNsYXNzRmFjdG9yeSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElDbGFzc0ZhY3RvcnlJbXBsLCBJQ2xhc3NGYWN0b3J5LCBpZmFjZSk7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKICAgIFRSQUNFKCIoJXApLT4oKSBkZWNyZW1lbnRpbmcgZnJvbSAlZC5cbiIsIFRoaXMsIHJlZisxKTsKCiAgICBpZiAocmVmID09IDApCiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CgogICAgcmV0dXJuIHJlZjsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3Q2xhc3NGYWN0b3J5OjpDcmVhdGVJbnN0YW5jZQogKgogKiBXaGF0IGlzIHRoaXM/IFNlZW1zIHRvIGNyZWF0ZSBEaXJlY3REcmF3IG9iamVjdHMuLi4KICoKICogUGFyYW1zCiAqICBUaGUgdXN1c2FsIHRoaW5ncz8/PwogKgogKiBSRVRVUk5TCiAqICA/Pz8KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfQ3JlYXRlSW5zdGFuY2UoSUNsYXNzRmFjdG9yeSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biAqVW5rT3V0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElDbGFzc0ZhY3RvcnlJbXBsLCBJQ2xhc3NGYWN0b3J5LCBpZmFjZSk7CgogICAgVFJBQ0UoIiglcCktPiglcCwlcywlcClcbiIsVGhpcyxVbmtPdXRlcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLG9iaik7CgogICAgcmV0dXJuIFRoaXMtPnBmbkNyZWF0ZUluc3RhbmNlKFVua091dGVyLCByaWlkLCBvYmopOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeTo6TG9ja1NlcnZlcgogKgogKiBXaGF0IGlzIHRoaXM/CiAqCiAqIFBhcmFtcwogKiAgPz8/CiAqCiAqIFJFVFVSTlMKICogIFNfT0ssIGJlY2F1c2UgaXQncyBhIHN0dWIKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfTG9ja1NlcnZlcihJQ2xhc3NGYWN0b3J5ICppZmFjZSxCT09MIGRvbG9jaykKewogICAgSUNPTV9USElTX0ZST00oSUNsYXNzRmFjdG9yeUltcGwsIElDbGFzc0ZhY3RvcnksIGlmYWNlKTsKICAgIEZJWE1FKCIoJXApLT4oJWQpLHN0dWIhXG4iLFRoaXMsZG9sb2NrKTsKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgY2xhc3MgZmFjdG9yeSBWVGFibGUKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBjb25zdCBJQ2xhc3NGYWN0b3J5VnRibCBJQ2xhc3NGYWN0b3J5X1Z0YmwgPQp7CiAgICBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfQWRkUmVmLAogICAgSURpcmVjdERyYXdDbGFzc0ZhY3RvcnlJbXBsX1JlbGVhc2UsCiAgICBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfQ3JlYXRlSW5zdGFuY2UsCiAgICBJRGlyZWN0RHJhd0NsYXNzRmFjdG9yeUltcGxfTG9ja1NlcnZlcgp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGxsR2V0Q2xhc3NPYmplY3QgW0REUkFXLkBdCiAqIFJldHJpZXZlcyBjbGFzcyBvYmplY3QgZnJvbSBhIERMTCBvYmplY3QKICoKICogTk9URVMKICogICAgRG9jcyBzYXkgcmV0dXJucyBTVERBUEkKICoKICogUEFSQU1TCiAqICAgIHJjbHNpZCBbSV0gQ0xTSUQgZm9yIHRoZSBjbGFzcyBvYmplY3QKICogICAgcmlpZCAgIFtJXSBSZWZlcmVuY2UgdG8gaWRlbnRpZmllciBvZiBpbnRlcmZhY2UgZm9yIGNsYXNzIG9iamVjdAogKiAgICBwcHYgICAgW09dIEFkZHJlc3Mgb2YgdmFyaWFibGUgdG8gcmVjZWl2ZSBpbnRlcmZhY2UgcG9pbnRlciBmb3IgcmlpZAogKgogKiBSRVRVUk5TCiAqICAgIFN1Y2Nlc3M6IFNfT0sKICogICAgRmFpbHVyZTogQ0xBU1NfRV9DTEFTU05PVEFWQUlMQUJMRSwgRV9PVVRPRk1FTU9SWSwgRV9JTlZBTElEQVJHLAogKiAgICAgICAgICAgICBFX1VORVhQRUNURUQKICovCkhSRVNVTFQgV0lOQVBJIERsbEdldENsYXNzT2JqZWN0KFJFRkNMU0lEIHJjbHNpZCwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIElDbGFzc0ZhY3RvcnlJbXBsICpmYWN0b3J5OwoKICAgIFRSQUNFKCIoJXMsJXMsJXApXG4iLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCksIGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdik7CgogICAgaWYgKCAhSXNFcXVhbEdVSUQoICZJSURfSUNsYXNzRmFjdG9yeSwgcmlpZCApCgkgJiYgISBJc0VxdWFsR1VJRCggJklJRF9JVW5rbm93biwgcmlpZCkgKQoJcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CgogICAgZm9yIChpPTA7IGkgPCBzaXplb2Yob2JqZWN0X2NyZWF0aW9uKS9zaXplb2Yob2JqZWN0X2NyZWF0aW9uWzBdKTsgaSsrKQogICAgewoJaWYgKElzRXF1YWxHVUlEKG9iamVjdF9jcmVhdGlvbltpXS5jbHNpZCwgcmNsc2lkKSkKCSAgICBicmVhazsKICAgIH0KCiAgICBpZiAoaSA9PSBzaXplb2Yob2JqZWN0X2NyZWF0aW9uKS9zaXplb2Yob2JqZWN0X2NyZWF0aW9uWzBdKSkKICAgIHsKCUZJWE1FKCIlczogbm8gY2xhc3MgZm91bmQuXG4iLCBkZWJ1Z3N0cl9ndWlkKHJjbHNpZCkpOwoJcmV0dXJuIENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7CiAgICB9CgogICAgZmFjdG9yeSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoKmZhY3RvcnkpKTsKICAgIGlmIChmYWN0b3J5ID09IE5VTEwpIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIElDT01fSU5JVF9JTlRFUkZBQ0UoZmFjdG9yeSwgSUNsYXNzRmFjdG9yeSwgSUNsYXNzRmFjdG9yeV9WdGJsKTsKICAgIGZhY3RvcnktPnJlZiA9IDE7CgogICAgZmFjdG9yeS0+cGZuQ3JlYXRlSW5zdGFuY2UgPSBvYmplY3RfY3JlYXRpb25baV0ucGZuQ3JlYXRlSW5zdGFuY2U7CgogICAgKnBwdiA9IElDT01fSU5URVJGQUNFKGZhY3RvcnksIElDbGFzc0ZhY3RvcnkpOwogICAgcmV0dXJuIFNfT0s7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxDYW5VbmxvYWROb3cgW0REUkFXLkBdICBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIERMTCBpcyBpbiB1c2UuCiAqCiAqIFJFVFVSTlMKICogICAgU3VjY2VzczogU19PSwogKiAgICBGYWlsdXJlOiBTX0ZBTFNFCiAqLwpIUkVTVUxUIFdJTkFQSSBEbGxDYW5VbmxvYWROb3codm9pZCkKewogICAgSFJFU1VMVCBocjsKICAgIEZJWE1FKCIodm9pZCk6IHN0dWJcbiIpOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICBociA9IFNfRkFMU0U7CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwoKICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRGVzdHJveUNhbGxiYWNrCiAqCiAqIENhbGxiYWNrIGZ1bmN0aW9uIGZvciB0aGUgRW51bVN1cmZhY2VzIGNhbGwgaW4gRGxsTWFpbi4KICogRHVtcHMgc29tZSBzdXJmYWNlIGluZm8gYW5kIHJlbGVhc2VzIHRoZSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIHN1cmY6IFRoZSBlbnVtZXJhdGVkIHN1cmZhY2UKICogIGRlc2M6IGl0J3MgZGVzY3JpcHRpb24KICogIGNvbnRleHQ6IFBvaW50ZXIgdG8gdGhlIGRkcmF3IGltcGwKICoKICogUmV0dXJuczoKICogIERERU5VTVJFVF9PSzsKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpEZXN0cm95Q2FsbGJhY2soSURpcmVjdERyYXdTdXJmYWNlNyAqc3VyZiwKICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyICpkZXNjLAogICAgICAgICAgICAgICAgdm9pZCAqY29udGV4dCkKewogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqSW1wbCA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTcsIHN1cmYpOwogICAgSURpcmVjdERyYXdJbXBsICpkZHJhdyA9IChJRGlyZWN0RHJhd0ltcGwgKikgY29udGV4dDsKICAgIFVMT05HIHJlZjsKCiAgICByZWYgPSBJRGlyZWN0RHJhd1N1cmZhY2U3X1JlbGVhc2Uoc3VyZik7ICAvKiBGb3IgdGhlIEVudW1TdXJmYWNlcyAqLwogICAgV0FSTigiU3VyZmFjZSAlcCBoYXMgYW4gcmVmZXJlbmNlIGNvdW50IG9mICVkXG4iLCBJbXBsLCByZWYpOwoKICAgIC8qIFNraXAgc3VyZmFjZXMgd2hpY2ggYXJlIGF0dGFjaGVkIHNvbWV3aGVyZSBvciB3aGljaCBhcmUKICAgICAqIHBhcnQgb2YgYSBjb21wbGV4IGNvbXBvdW5kLiBUaGV5IHdpbGwgZ2V0IHJlbGVhc2VkIHdoZW4gZGVzdHJveWluZwogICAgICogdGhlIHJvb3QKICAgICAqLwogICAgaWYoICghSW1wbC0+aXNfY29tcGxleF9yb290KSB8fCAoSW1wbC0+Zmlyc3RfYXR0YWNoZWQgIT0gSW1wbCkgKQogICAgICAgIHJldHVybiBEREVOVU1SRVRfT0s7CiAgICAvKiBTa2lwIG91ciBkZXB0aCBzdGVuY2lsIHN1cmZhY2UsIGl0IHdpbGwgYmUgcmVsZWFzZWQgd2l0aCB0aGUgcmVuZGVyIHRhcmdldCAqLwogICAgaWYoIEltcGwgPT0gZGRyYXctPkRlcHRoU3RlbmNpbEJ1ZmZlcikKICAgICAgICByZXR1cm4gRERFTlVNUkVUX09LOwoKICAgIC8qIERlc3Ryb3kgdGhlIHN1cmZhY2UgKi8KICAgIHdoaWxlKHJlZikgcmVmID0gSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKHN1cmYpOwoKICAgIHJldHVybiBEREVOVU1SRVRfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBnZXRfY29uZmlnX2tleQogKgogKiBSZWFkcyBhIGNvbmZpZyBrZXkgZnJvbSB0aGUgcmVnaXN0cnkuIFRha2VuIGZyb20gV2luZUQzRAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBpbmxpbmUgRFdPUkQgZ2V0X2NvbmZpZ19rZXkoSEtFWSBkZWZrZXksIEhLRVkgYXBwa2V5LCBjb25zdCBjaGFyKiBuYW1lLCBjaGFyKiBidWZmZXIsIERXT1JEIHNpemUpCnsKICAgIGlmICgwICE9IGFwcGtleSAmJiAhUmVnUXVlcnlWYWx1ZUV4QSggYXBwa2V5LCBuYW1lLCAwLCBOVUxMLCAoTFBCWVRFKSBidWZmZXIsICZzaXplICkpIHJldHVybiAwOwogICAgaWYgKDAgIT0gZGVma2V5ICYmICFSZWdRdWVyeVZhbHVlRXhBKCBkZWZrZXksIG5hbWUsIDAsIE5VTEwsIChMUEJZVEUpIGJ1ZmZlciwgJnNpemUgKSkgcmV0dXJuIDA7CiAgICByZXR1cm4gRVJST1JfRklMRV9OT1RfRk9VTkQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEbGxNYWluIChERFJBVy4wKQogKgogKiBDb3VsZCBiZSB1c2VkIHRvIHJlZ2lzdGVyIERpcmVjdERyYXcgZHJpdmVycywgaWYgd2UgaGF2ZSBtb3JlIHRoYW4KICogb25lLiBBbHNvIHVzZWQgdG8gZGVzdHJveSBhbnkgb2JqZWN0cyBsZWZ0IGF0IHVubG9hZCBpZiB0aGUKICogYXBwIGRpZG4ndCByZWxlYXNlIHRoZW0gcHJvcGVybHkoR290aGljIDIsIERpYWJsbyAyLCBNb3RvIHJhY2VyLCAuLi4pCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KQk9PTCBXSU5BUEkKRGxsTWFpbihISU5TVEFOQ0UgaEluc3RETEwsCiAgICAgICAgRFdPUkQgUmVhc29uLAogICAgICAgIExQVk9JRCBscHYpCnsKICAgIFRSQUNFKCIoJXAsJXgsJXApXG4iLCBoSW5zdERMTCwgUmVhc29uLCBscHYpOwogICAgaWYgKFJlYXNvbiA9PSBETExfUFJPQ0VTU19BVFRBQ0gpCiAgICB7CiAgICAgICAgY2hhciBidWZmZXJbTUFYX1BBVEgrMTBdOwogICAgICAgIERXT1JEIHNpemUgPSBzaXplb2YoYnVmZmVyKTsKICAgICAgICBIS0VZIGhrZXkgPSAwOwogICAgICAgIEhLRVkgYXBwa2V5ID0gMDsKICAgICAgICBEV09SRCBsZW47CgogICAgICAgLyogQEAgV2luZSByZWdpc3RyeSBrZXk6IEhLQ1VcU29mdHdhcmVcV2luZVxEaXJlY3QzRCAqLwogICAgICAgaWYgKCBSZWdPcGVuS2V5QSggSEtFWV9DVVJSRU5UX1VTRVIsICJTb2Z0d2FyZVxcV2luZVxcRGlyZWN0M0QiLCAmaGtleSApICkgaGtleSA9IDA7CgogICAgICAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVBKCAwLCBidWZmZXIsIE1BWF9QQVRIICk7CiAgICAgICBpZiAobGVuICYmIGxlbiA8IE1BWF9QQVRIKQogICAgICAgewogICAgICAgICAgICBIS0VZIHRtcGtleTsKICAgICAgICAgICAgLyogQEAgV2luZSByZWdpc3RyeSBrZXk6IEhLQ1VcU29mdHdhcmVcV2luZVxBcHBEZWZhdWx0c1xhcHAuZXhlXERpcmVjdDNEICovCiAgICAgICAgICAgIGlmICghUmVnT3BlbktleUEoIEhLRVlfQ1VSUkVOVF9VU0VSLCAiU29mdHdhcmVcXFdpbmVcXEFwcERlZmF1bHRzIiwgJnRtcGtleSApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjaGFyICpwLCAqYXBwbmFtZSA9IGJ1ZmZlcjsKICAgICAgICAgICAgICAgIGlmICgocCA9IHN0cnJjaHIoIGFwcG5hbWUsICcvJyApKSkgYXBwbmFtZSA9IHAgKyAxOwogICAgICAgICAgICAgICAgaWYgKChwID0gc3RycmNociggYXBwbmFtZSwgJ1xcJyApKSkgYXBwbmFtZSA9IHAgKyAxOwogICAgICAgICAgICAgICAgc3RyY2F0KCBhcHBuYW1lLCAiXFxEaXJlY3QzRCIgKTsKICAgICAgICAgICAgICAgIFRSQUNFKCJhcHBuYW1lID0gWyVzXVxuIiwgYXBwbmFtZSk7CiAgICAgICAgICAgICAgICBpZiAoUmVnT3BlbktleUEoIHRtcGtleSwgYXBwbmFtZSwgJmFwcGtleSApKSBhcHBrZXkgPSAwOwogICAgICAgICAgICAgICAgUmVnQ2xvc2VLZXkoIHRtcGtleSApOwogICAgICAgICAgICB9CiAgICAgICB9CgogICAgICAgaWYgKCAwICE9IGhrZXkgfHwgMCAhPSBhcHBrZXkgKQogICAgICAgewogICAgICAgICAgICBpZiAoICFnZXRfY29uZmlnX2tleSggaGtleSwgYXBwa2V5LCAiRGlyZWN0RHJhd1JlbmRlcmVyIiwgYnVmZmVyLCBzaXplKSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghc3RyY21wKGJ1ZmZlciwiZ2RpIikpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIkRlZmF1bHRpbmcgdG8gR0RJIHN1cmZhY2VzXG4iKTsKICAgICAgICAgICAgICAgICAgICBEZWZhdWx0U3VyZmFjZVR5cGUgPSBTVVJGQUNFX0dESTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoYnVmZmVyLCJvcGVuZ2wiKSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiRGVmYXVsdGluZyB0byBvcGVuZ2wgc3VyZmFjZXNcbiIpOwogICAgICAgICAgICAgICAgICAgIERlZmF1bHRTdXJmYWNlVHlwZSA9IFNVUkZBQ0VfT1BFTkdMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEVSUigiVW5rbm93biBkZWZhdWx0IHN1cmZhY2UgdHlwZS4gU3VwcG9ydGVkIGFyZTpcbiBnZGksIG9wZW5nbFxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIERpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMoaEluc3RETEwpOwogICAgfQogICAgZWxzZSBpZiAoUmVhc29uID09IERMTF9QUk9DRVNTX0RFVEFDSCkKICAgIHsKICAgICAgICBpZighbGlzdF9lbXB0eSgmZ2xvYmFsX2RkcmF3X2xpc3QpKQogICAgICAgIHsKICAgICAgICAgICAgc3RydWN0IGxpc3QgKmVudHJ5LCAqZW50cnkyOwogICAgICAgICAgICBXQVJOKCJUaGVyZSBhcmUgc3RpbGwgZXhpc3RpbmcgRGlyZWN0RHJhdyBpbnRlcmZhY2VzLiBXaW5lIGJ1ZyBvciBidWdneSBhcHBsaWNhdGlvbj9cbiIpOwoKICAgICAgICAgICAgLyogV2UgcmVtb3ZlIGVsZW1ldHMgZnJvbSB0aGlzIGxvb3AgKi8KICAgICAgICAgICAgTElTVF9GT1JfRUFDSF9TQUZFKGVudHJ5LCBlbnRyeTIsICZnbG9iYWxfZGRyYXdfbGlzdCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSFJFU1VMVCBocjsKICAgICAgICAgICAgICAgIEREU1VSRkFDRURFU0MyIGRlc2M7CiAgICAgICAgICAgICAgICBpbnQgaTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3SW1wbCAqZGRyYXcgPSBMSVNUX0VOVFJZKGVudHJ5LCBJRGlyZWN0RHJhd0ltcGwsIGRkcmF3X2xpc3RfZW50cnkpOwoKICAgICAgICAgICAgICAgIFdBUk4oIkREcmF3ICVwIGhhcyBhIHJlZmNvdW50IG9mICVkXG4iLCBkZHJhdywgZGRyYXctPnJlZjcgKyBkZHJhdy0+cmVmNCArIGRkcmF3LT5yZWYzICsgZGRyYXctPnJlZjIgKyBkZHJhdy0+cmVmMSk7CgogICAgICAgICAgICAgICAgLyogQWRkIHJlZmVyZW5jZXMgdG8gZWFjaCBpbnRlcmZhY2UgdG8gYXZvaWQgZnJlZWluZyB0aGVtIHVuZXhwZWN0YWRlbHkgKi8KICAgICAgICAgICAgICAgIElEaXJlY3REcmF3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXcpKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3Ml9BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3MikpOwogICAgICAgICAgICAgICAgSURpcmVjdERyYXczX0FkZFJlZihJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXczKSk7CiAgICAgICAgICAgICAgICBJRGlyZWN0RHJhdzRfQWRkUmVmKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzQpKTsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3N19BZGRSZWYoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3NykpOwoKICAgICAgICAgICAgICAgIC8qIERvZXMgYSBEM0QgZGV2aWNlIGV4aXN0PyBEZXN0cm95IGl0CiAgICAgICAgICAgICAgICAgICAgKiBUT0RPOiBEZXN0cm95IGFsbCBWZXJ0ZXggYnVmZmVycywgTGlnaHRzLCBNYXRlcmlhbHMKICAgICAgICAgICAgICAgICAgICAqIGFuZCBleGVjdHVyZSBidWZmZXJzIHRvbwogICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZihkZHJhdy0+ZDNkZGV2aWNlKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFdBUk4oIkREcmF3ICVwIGhhcyBkM2RkZXZpY2UgJXAgYXR0YWNoZWRcbiIsIGRkcmF3LCBkZHJhdy0+ZDNkZGV2aWNlKTsKICAgICAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0M0REZXZpY2U3X1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGRyYXctPmQzZGRldmljZSwgSURpcmVjdDNERGV2aWNlNykpKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBUcnkgdG8gcmVsZWFzZSB0aGUgb2JqZWN0cwogICAgICAgICAgICAgICAgICAgICogRG8gYW4gRW51bVN1cmZhY2VzIHRvIGZpbmQgYW55IGhhbmdpbmcgc3VyZmFjZXMKICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgbWVtc2V0KCZkZXNjLCAwLCBzaXplb2YoZGVzYykpOwogICAgICAgICAgICAgICAgZGVzYy5kd1NpemUgPSBzaXplb2YoZGVzYyk7CiAgICAgICAgICAgICAgICBmb3IoaSA9IDA7IGkgPD0gMTsgaSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGhyID0gSURpcmVjdERyYXc3X0VudW1TdXJmYWNlcyhJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXc3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERERU5VTVNVUkZBQ0VTX0FMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkZXNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKikgZGRyYXcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZXN0cm95Q2FsbGJhY2spOwogICAgICAgICAgICAgICAgICAgIGlmKGhyICE9IEQzRF9PSykKICAgICAgICAgICAgICAgICAgICAgICAgRVJSKCIoJXApIEVudW1TdXJmYWNlcyBmYWlsZWQsIHByZXBhcmUgZm9yIHRyb3VibGVcbiIsIGRkcmF3KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBDaGVjayB0aGUgc3VyZmFjZSBjb3VudCAqLwogICAgICAgICAgICAgICAgaWYoZGRyYXctPnN1cmZhY2VzID4gMCkKICAgICAgICAgICAgICAgICAgICBFUlIoIkREcmF3ICVwIHN0aWxsIGhhcyAlZCBzdXJmYWNlcyBhdHRhY2hlZFxuIiwgZGRyYXcsIGRkcmF3LT5zdXJmYWNlcyk7CgogICAgICAgICAgICAgICAgLyogUmVsZWFzZSBhbGwgaGFuZ2luZyByZWZlcmVuY2VzIHRvIGRlc3Ryb3kgdGhlIG9iamVjdHMuIFRoaXMKICAgICAgICAgICAgICAgICAgICAqIHJlc3RvcmVzIHRoZSBzY3JlZW4gbW9kZSB0b28KICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgd2hpbGUoSURpcmVjdERyYXdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXcpKSk7CiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhdzJfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXcyKSkpOwogICAgICAgICAgICAgICAgd2hpbGUoSURpcmVjdERyYXczX1JlbGVhc2UoSUNPTV9JTlRFUkZBQ0UoZGRyYXcsIElEaXJlY3REcmF3MykpKTsKICAgICAgICAgICAgICAgIHdoaWxlKElEaXJlY3REcmF3NF9SZWxlYXNlKElDT01fSU5URVJGQUNFKGRkcmF3LCBJRGlyZWN0RHJhdzQpKSk7CiAgICAgICAgICAgICAgICB3aGlsZShJRGlyZWN0RHJhdzdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShkZHJhdywgSURpcmVjdERyYXc3KSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBUUlVFOwp9Cg==