LyoKICogQ29weXJpZ2h0IChjKSAyMDEyLTIwMTMgUXVhbGNvbW0gQXRoZXJvcywgSW5jLgogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiBRdWFsY29tbSBBdGhlcm9zIENvbmZpZGVudGlhbCBhbmQgUHJvcHJpZXRhcnkuCiAqLwovKio9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiAgCiAgXGZpbGUgIHdsYW5fcWN0X3BhbF9wYWNrZXQuYwogIAogIFxicmllZiBJbXBsZW1lbnRhdGlvbiBmb3IgUEFMIHBhY2tldC4gd3B0ID0gKFdsYW4gUGFsIFR5cGUpIHdwYWwgPSAoV2xhbiBQQUwpCiAgICAgICAgICAgICAgIAogICBEZWZpbml0aW9ucyBmb3IgcGxhdGZvcm0gd2l0aCBWT1NTIHBhY2tldCBzdXBwb3J0IGFuZCBMQS4KICAKICAgQ29weXJpZ2h0IDIwMTAgKGMpIFF1YWxjb21tLCBJbmNvcnBvcmF0ZWQuICBBbGwgUmlnaHRzIFJlc2VydmVkLgogICAKICAgUXVhbGNvbW0gQ29uZmlkZW50aWFsIGFuZCBQcm9wcmlldGFyeS4KICAKICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLwoKI2luY2x1ZGUgIndsYW5fcWN0X3BhbF9wYWNrZXQuaCIKI2luY2x1ZGUgIndsYW5fcWN0X3BhbF9hcGkuaCIKI2luY2x1ZGUgIndsYW5fcWN0X3BhbF90cmFjZS5oIgojaW5jbHVkZSAidm9zX3BhY2tldC5oIgojaW5jbHVkZSAidm9zX3RyYWNlLmgiCiNpbmNsdWRlICJ2b3NfbGlzdC5oIgoKI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgojaW5jbHVkZSAiZG1hLW1hcHBpbmcuaCIKCi8qUGVyIHNwZWMgZGVmaW5pdGlvbiovCiNkZWZpbmUgV1BBTF9FVEhFUk5FVF9QQUtDRVRfSEVBREVSX1NJWkUgICAgIDE0CgovKlBlciBzcGVjIGRlZmluaXRpb24gLSBub3QgaW5jbHVkaW5nIFFPUyBmaWVsZCovCiNkZWZpbmUgV1BBTF84MDJfMTFfUEFDS0VUX0hFQURFUl9TSVpFICAgIDI0IAoKLypwIGlzIGEgcG9pbnRlciB0byB3cHRfcGFja2V0Ki8KI2RlZmluZSBXUEFMX1RPX1ZPU19QS1QocCkgKCh2b3NfcGt0X3QgKikocCkpCgoKdHlwZWRlZiBzdHJ1Y3QKewogIHZvaWQqICAgICAgcFBoeUFkZHI7CiAgd3B0X3VpbnQzMiB1TGVuOwp9d3B0X2l0ZXJhdG9yX2luZm87CgovKiBTdG9yYWdlIGZvciBEWEUgQ0IgZnVuY3Rpb24gcG9pbnRlciAqLwpzdGF0aWMgd3BhbFBhY2tldExvd1BhY2tldENCIHdwYWxQYWNrZXRBdmFpbGFibGVDQjsKCi8qIFRlbXAgc3RvcmFnZSBmb3IgdHJhbnNwb3J0IGNoYW5uZWwgRElBRy9MT0cgaW5mb3JtYXRpb24KICogRWFjaCBjaGFubmVsIHdpbGwgdXBkYXRlIGluZm9ybWF0aW9uIHdpdGggZGlmZmVyZW50IGNvbnRleHQKICogQmVmb3JlIHNlbmQgc3RvcmVkIGRhdGUgdG8gRElBRywKICogdGVtcG9yYXJ5IGl0IHNob3VsZCBiZSBzdG9yZWQgKi8Kc3RhdGljIHdwdF9sb2dfZGF0YV9zdGFsbF90eXBlIHdwYWxUcmFzcG9ydFN0YWxsSW5mbzsKCi8qCiAgIHdwYWxQYWNrZXRJbml0IGlzIG5vLW9wIGZvciBWT1NTLXN1cHBvcnQgd3B0X3BhY2tldAoqLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRJbml0KHZvaWQgKnBQYWxDb250ZXh0KQp7CiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCgovKgogICB3cGFsUGFja2V0Q2xvc2UgaXMgbm8tb3AgZm9yIFZPU1Mtc3VwcG9ydCB3cHRfcGFja2V0CiovCndwdF9zdGF0dXMgd3BhbFBhY2tldENsb3NlKHZvaWQgKnBQYWxDb250ZXh0KQp7CiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0UlhMb3dSZXNvdXJjZUNCIJYgUlggUkFXIHBhY2tlciBDQiBmdW5jdGlvbgogICAgUGFyYW06IAogICAgICAgIHBQYWNrZXQgliBBdmFpbGFibGUgUlggcGFja2V0CiAgICAgICAgdXNlckRhdGEgLSBQQUwgQ2xpZW50IENvbnRleHQsIERYRQogICAgUmV0dXJuOgogICAgICAgIFN0YXR1cwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwpWT1NfU1RBVFVTIHdwYWxQYWNrZXRSWExvd1Jlc291cmNlQ0Iodm9zX3BrdF90ICpwUGFja2V0LCB2X1ZPSURfdCAqdXNlckRhdGEpCnsKICAgVk9TX1NUQVRVUyAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB2b2lkKiAgICAgICAgcERhdGEgICAgID0gTlVMTDsKCiAgIGlmIChOVUxMID09IHBQYWNrZXQpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgICAiR2V0IG5ldyBSWCBQQUwgcGFja2V0IGZhaWwiKTsKICAgICAgcmV0dXJuIFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB9CiAgIHZvc1N0YXR1cyA9IHZvc19wa3RfcmVzZXJ2ZV9oZWFkX2Zhc3QoIHBQYWNrZXQsICZwRGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVlBLVF9TSVpFX0JVRkZFUiApOwogICBpZihWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gdm9zU3RhdHVzKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgIlByZXBhcmUgUlggcGFja2V0IGZvciBEWEUgZmFpbCIpOwogICAgICByZXR1cm4gVk9TX1NUQVRVU19FX0ZBSUxVUkU7CiAgIH0KCiAgIGlmKChOVUxMID09IHdwYWxQYWNrZXRBdmFpbGFibGVDQikgfHwgKE5VTEwgPT0gdXNlckRhdGEpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgIkludmFsaWQgQVJHIGZvciBuZXcgUlggcGFja2V0Iik7CiAgICAgIHJldHVybiBWT1NfU1RBVFVTX0VfRkFJTFVSRTsKICAgfQoKICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCKCAod3B0X3BhY2tldCAqKXBQYWNrZXQsIHVzZXJEYXRhICk7CgogICByZXR1cm4gVk9TX1NUQVRVU19TVUNDRVNTOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldEFsbG9jIJYgQWxsb2NhdGUgYSB3cHRfcGFja2V0IGZyb20gUEFMLgogICAgUGFyYW06IAogICAgICAgIHBrdFR5cGUgliBzcGVjaWZ5IHRoZSB0eXBlIG9mIHdwdF9wYWNrZXQgdG8gYWxsb2NhdGUKICAgICAgICBuUGt0U2l6ZSAtIHBhY2tldCBzaXplCiAgICBSZXR1cm46CiAgICAgICAgQSBwb2ludGVyIHRvIHRoZSB3cHRfcGFja2V0LiBOVUxMIG1lYW5zIGZhaWwuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9wYWNrZXQgKiB3cGFsUGFja2V0QWxsb2Mod3B0X3BhY2tldF90eXBlIHBrdFR5cGUsIHdwdF91aW50MzIgblBrdFNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd3BhbFBhY2tldExvd1BhY2tldENCIHJ4TG93Q0IsIHZvaWQgKnVzckRhdGEpCnsKICAgVk9TX1NUQVRVUyAgIHZvc1N0YXR1cyA9IFZPU19TVEFUVVNfRV9GQUlMVVJFOwogICB3cHRfcGFja2V0KiAgcFBrdCAgICAgID0gTlVMTDsKICAgdm9zX3BrdF90KiAgIHBWb3NQa3QgICA9IE5VTEw7CiAgIHZvaWQqICAgICAgICBwRGF0YSAgICAgPSBOVUxMOwogICB2X1UxNl90ICAgICAgYWxsb2NMZW47CiAgIC8qLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCgogICBzd2l0Y2ggKHBrdFR5cGUpCiAgIHsKICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQ6CiAgICAgIHZvc1N0YXR1cyA9IHZvc19wa3RfZ2V0X3BhY2tldCgmcFZvc1BrdCwgVk9TX1BLVF9UWVBFX1RYXzgwMl8xMV9NR01ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuUGt0U2l6ZSwgMSwgVk9TX0ZBTFNFLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgTlVMTCAvKm5vIGNhbGxiYWNrKi8pOwogICAgICBicmVhazsKCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1JYX1JBVzoKICAgICAgLyogU2V0IHRoZSB3cGFsUGFja2V0QXZhaWxhYmxlQ0IgYmVmb3JlIHdlIHRyeSB0byBnZXQgYSBWT1MKICAgICAgICogcGFja2V0IGZyb20gdGhlICdmcmVlIGxpc3QnIGFuZCByZXNldCBpdCBpZiB2b3NfcGt0X2dldF9wYWNrZXQoKQogICAgICAgKiByZXR1cm5zIGEgdmFsaWQgcGFja2V0LiBUaGlzIG9yZGVyIGlzIHJlcXVpcmVkIHRvIGF2b2lkIHRoZQogICAgICAgKiByYWNlIGNvbmRpdGlvbjoKICAgICAgICogMS4gVGhlIGJlbG93IGNhbGwgdG8gdm9zX3BrdF9nZXRfcGFja2V0KCkgaW4gUlhfVGhyZWFkIGRldGVybWluZXMKICAgICAgICogICAgdGhhdCBubyBtb3JlIHBhY2tldHMgYXJlIGF2YWlsYWJsZSBpbiB0aGUgJ2ZyZWUgbGlzdCcgYW5kIHNldHMKICAgICAgICogICAgdGhlIGxvdyByZXNvdXJjZSBjYWxsYmFja3MuCiAgICAgICAqIDIuIGluIHBhcmFsbGVsIHZvc19wa3RfcmV0dXJuX3BhY2tldCgpIGlzIGNhbGxlZCBpbiBNQ19UaHJlYWQgZm9yIGEKICAgICAgICogICAgTWFuYWdlbWVudCBmcmFtZSBiZWZvcmUgd3BhbFBhY2tldEFsbG9jKCkgZ2V0cyBhIGNoYW5jZSB0byBzZXQKICAgICAgICogICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCIGFuZCBzaW5jZSB0aGUgJ2xvdyByZXNvdXJjZSBjYWxsYmFja3MnCiAgICAgICAqICAgIGFyZSBzZXQgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIC0gd3BhbFBhY2tldFJYTG93UmVzb3VyY2VDQiBpcwogICAgICAgKiAgICBleGVjdXRlZCxidXQgc2luY2Ugd3BhbFBhY2tldEF2YWlsYWJsZUNCIGlzIHN0aWxsIE5VTEwgdGhlIGxvdwogICAgICAgKiAgICByZXNvdXJjZSByZWNvdmVyeSBmYWlscy4KICAgICAgICovCiAgICAgIHdwYWxQYWNrZXRBdmFpbGFibGVDQiA9IHJ4TG93Q0I7CgogICAgICB2b3NTdGF0dXMgPSB2b3NfcGt0X2dldF9wYWNrZXQoJnBWb3NQa3QsIFZPU19QS1RfVFlQRV9SWF9SQVcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5Qa3RTaXplLCAxLCBWT1NfRkFMU0UsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cGFsUGFja2V0UlhMb3dSZXNvdXJjZUNCLCB1c3JEYXRhKTsKCiNpZm5kZWYgRkVBVFVSRV9SMzNECiAgICAgIC8qIFJlc2VydmUgdGhlIGVudGlyZSByYXcgcnggYnVmZmVyIGZvciBEWEUgKi8KICAgICAgaWYoIHZvc1N0YXR1cyA9PSBWT1NfU1RBVFVTX1NVQ0NFU1MgKQogICAgICB7CiAgICAgICAgd3BhbFBhY2tldEF2YWlsYWJsZUNCID0gTlVMTDsKICAgICAgICB2b3NTdGF0dXMgPSAgdm9zX3BrdF9yZXNlcnZlX2hlYWRfZmFzdCggcFZvc1BrdCwgJnBEYXRhLCBuUGt0U2l6ZSApOyAKICAgICAgfQojZW5kaWYgLyogRkVBVFVSRV9SMzNEICovCiAgICAgIGlmKChOVUxMICE9IHBWb3NQa3QpICYmIChWT1NfU1RBVFVTX0VfUkVTT1VSQ0VTICE9IHZvc1N0YXR1cykpCiAgICAgIHsKICAgICAgICAgdm9zX3BrdF9nZXRfcGFja2V0X2xlbmd0aChwVm9zUGt0LCAmYWxsb2NMZW4pOwogICAgICAgICBpZiAoblBrdFNpemUgIT0gYWxsb2NMZW4pCiAgICAgICAgIHsKICAgICAgICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgIlJYIHBhY2tldCBhbGxvYyBoYXMgcHJvYmxlbSwgZGlzY2FyZCB0aGlzIGZyYW1lLCBMZW4gJWQiLCBhbGxvY0xlbik7CiAgICAgICAgICAgIHZvc19wa3RfcmV0dXJuX3BhY2tldChwVm9zUGt0KTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgIGRlZmF1bHQ6CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICAgIiB0cnkgdG8gYWxsb2NhdGUgdW5zdXBwb3J0ZWQgcGFja2V0IHR5cGUgKCVkKSIsIHBrdFR5cGUpOwogICAgICBicmVhazsKICAgfQoKICAgaWYoVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc1N0YXR1cykpCiAgIHsKICAgICAgcFBrdCA9ICh3cHRfcGFja2V0ICopcFZvc1BrdDsKICAgfQoKCiAgIHJldHVybiBwUGt0Owp9Lyp3cGFsUGFja2V0QWxsb2MqLwoKCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldEZyZWUgliBGcmVlIGEgd3B0X3BhY2tldCBjaGFpbiBmb3Igb25lIHBhcnRpY3VsYXIgdHlwZS4KICAgIEZvciBvdXIgbGVnYWN5IFVNQUMsIGl0IGlzIG5vdCBuZWVkZWQgYmVjYXVzZSB2b3NfcGFja2V0IGNvbnRhaW5zIHBhbF9wYWNrZXQuCiAgICBQYXJhbTogCiAgICAgICAgcFBrdCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIC0gc3VjY2VzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRGcmVlKHdwdF9wYWNrZXQgKnBQa3QpCnsKICAgVk9TX1NUQVRVUyB2b3NTdGF0dXM7CgogICBpZihOVUxMICE9IHBQa3QtPnBJbnRlcm5hbERhdGEpCiAgIHsKICAgICAgd3BhbE1lbW9yeUZyZWUocFBrdC0+cEludGVybmFsRGF0YSk7CiAgIH0KICAgdm9zU3RhdHVzID0gdm9zX3BrdF9yZXR1cm5fcGFja2V0KFdQQUxfVE9fVk9TX1BLVChwUGt0KSk7CgogICAvL1dpdGggVk9TUyBzdXBwb3J0LCB3ZSBjYW4gY2FzdCBiZXR3ZWVuIHdwdF9zdGF0dXMgYW5kIFZPU19TVEFUVVMKICAgcmV0dXJuICh3cHRfc3RhdHVzKXZvc1N0YXR1czsKfS8qd3BhbFBhY2tldEZyZWUqLwoKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsUGFja2V0R2V0TGVuZ3RoIJYgR2V0IG51bWJlciBvZiBieXRlcyBpbiBhIHdwdF9wYWNrZXQuIEl0IGluY2x1ZGUgdGhlIAogICAgYnl0ZXMgaW4gYSBCRCBpZiBpdCBleGlzdC4KICAgIFBhcmFtOiAKICAgICAgICBwUGt0IC0gcG9pbnRlciB0byBhIHBhY2tldCB0byBiZSBmcmVlZC4KICAgIFJldHVybjoKICAgICAgICBMZW5ndGggb2YgdGhlIGRhdGEgaW5jbHVkZSBsYXllci0yIGhlYWRlcnMuIEZvciBleGFtcGxlLCBpZiB0aGUgZnJhbWUKICAgICAgICBpcyA4MDIuMywgdGhlIGxlbmd0aCBpbmNsdWRlcyB0aGUgZXRoZXJuZXQgaGVhZGVyLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfdWludDMyIHdwYWxQYWNrZXRHZXRMZW5ndGgod3B0X3BhY2tldCAqcFBrdCkKewogICB2X1UxNl90IGxlbiA9IDAsIHBrdExlbiA9IDA7CgogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBQa3QpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogTlVMTCBwYWNrZXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKCiAgIGlmKCBXUEFMX1BBQ0tFVF9HRVRfQkRfUE9JTlRFUihwUGt0KSApCiAgIHsKICAgICAgbGVuID0gV1BBTF9QQUNLRVRfR0VUX0JEX0xFTkdUSChwUGt0KTsKICAgfQogICBpZiggVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc19wa3RfZ2V0X3BhY2tldF9sZW5ndGgoV1BBTF9UT19WT1NfUEtUKHBQa3QpLCAmcGt0TGVuKSkgKQogICB7CiAgICAgIGxlbiArPSBwa3RMZW47CiAgIH0KICAgZWxzZQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAiJXMgIGZhaWxlZCIsCiAgICAgICAgIF9fZnVuY19fKTsKICAgfQoKICAgcmV0dXJuICgod3B0X3VpbnQzMilsZW4pOwp9Lyp3cGFsUGFja2V0R2V0TGVuZ3RoKi8KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldFJhd1RyaW1IZWFkIJYgTW92ZSB0aGUgc3RhcnRpbmcgb2Zmc2V0IGFuZCByZXR1cm4gdGhlIGhlYWQgcG9pbnRlcgogICAgICAgICAgYmVmb3JlIHRoZSBtb3ZpbmcuIFRoZSBmdW5jdGlvbiBjYW4gb25seSBiZSB1c2VkIHdpdGggcmF3IHBhY2tldHMsCiAgICAgICAgICB3aG9zZSBidWZmZXIgaXMgb25lIHBpZWNlIGFuZCBhbGxvY2F0ZWQgYnkgV0xBTiBkcml2ZXIuIFRoaXMgYWxzbwogICAgICAgICAgcmVkdWNlIHRoZSBsZW5ndGggb2YgdGhlIHBhY2tldC4KICAgIFBhcmFtOiAKICAgICAgICBwUGt0IC0gcG9pbnRlciB0byBhIHdwdF9wYWNrZXQuCiAgICAgICAgc2l6ZSCWIG51bWJlciBvZiBieXRlcyB0byB0YWtlIG9mZiB0aGUgaGVhZC4KICAgIFJldHVybjoKICAgICAgICBBIHBvaW50ZXIgdG8gdGhlIG9yaWdpbmFsIGJ1ZmZlciBoZWFkIGJlZm9yZSB0aGUgdHJpbW1pbmcuCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCndwdF9zdGF0dXMgd3BhbFBhY2tldFJhd1RyaW1IZWFkKHdwdF9wYWNrZXQgKnBQa3QsIHdwdF91aW50MzIgc2l6ZSkKewogICB3cHRfc3RhdHVzIHN0YXR1cyA9IGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBrdCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIHBhY2tldCBwb2ludGVyIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBpZiAoKGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfMTFfTUdNVCA9PSBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGt0KSkgfHwKICAgICAgICAgICAgICAgKGVXTEFOX1BBTF9QS1RfVFlQRV9SWF9SQVcgPT0gV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpKQogICB7CiAgICAgICAvLyBDb250aW51ZSB0byB0cmltIHRoZSBwYWNrZXQKICAgfQogICBlbHNlCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBuZWl0aGVyIDgwMjExIG1hbmFnbWVudCBwYWNrZXQgbm9yIFJBVyBwYWNrZXQiLCBfX2Z1bmNfXyk7CiAgICAgIFZPU19BU1NFUlQoMCk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIGlmKCAhVk9TX0lTX1NUQVRVU19TVUNDRVNTKHZvc19wa3RfdHJpbV9oZWFkKFdQQUxfVE9fVk9TX1BLVChwUGt0KSwgKHZfU0laRV90KXNpemUpKSApCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsICIlcyAgSW52YWxpZCB0cmltKCVkKSIsCiAgICAgICAgIF9fZnVuY19fLCBzaXplKTsKICAgICAgc3RhdHVzID0gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICByZXR1cm4gc3RhdHVzOwp9Lyp3cGFsUGFja2V0UmF3VHJpbUhlYWQqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxQYWNrZXRSYXdUcmltVGFpbCCWIHJlZHVjZSB0aGUgbGVuZ3RoIG9mIHRoZSBwYWNrZXQuCiAgICBQYXJhbTogCiAgICAgICAgcFBrdCAtIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0LgogICAgICAgIHNpemUgliBudW1iZXIgb2YgYnl0ZXMgdG8gdGFrZSBvZiB0aGUgcGFja2V0IGxlbmd0aAogICAgUmV0dXJuOgogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUyCWIHN1Y2Nlc3MuIE90aGVyd2lzZSBmYWlsLgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRSYXdUcmltVGFpbCh3cHRfcGFja2V0ICpwUGt0LCB3cHRfdWludDMyIHNpemUpCnsKICAgd3B0X3N0YXR1cyBzdGF0dXMgPSBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7CgogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBQa3QpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogTlVMTCBwYWNrZXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgaWYgKChlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQgPT0gV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpIHx8CiAgICAgICAgICAgICAgIChlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXID09IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSkKICAgewogICAgICAgLy8gQ29udGludWUgdG8gdHJpbSB0aGUgcGFja2V0CiAgIH0KICAgZWxzZQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogbmVpdGhlciA4MDIxMSBtYW5hZ21lbnQgcGFja2V0IG5vciBSQVcgcGFja2V0IiwgX19mdW5jX18pOwogICAgICBWT1NfQVNTRVJUKDApOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBpZiggIVZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NfcGt0X3RyaW1fdGFpbChXUEFMX1RPX1ZPU19QS1QocFBrdCksICh2X1NJWkVfdClzaXplKSkgKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAiJXMgIEludmFsaWQgdHJpbSglZCkiLAogICAgICAgICBfX2Z1bmNfXywgc2l6ZSk7CiAgICAgIHN0YXR1cyA9IGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgcmV0dXJuIHN0YXR1czsKfS8qd3BhbFBhY2tldFJhd1RyaW1UYWlsKi8KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbFBhY2tldEdldFJhd0J1ZiCWIFJldHVybiB0aGUgc3RhcnRpbmcgYnVmZmVyIHZpcnR1YWwgYWRkcmVzcyBmb3IgdGhlIFJBVyBmbGF0IGJ1ZmZlcgogICAgSXQgaXMgaW5saW5lIGluIGhvcGUgb2YgZmFzdGVyIGltcGxlbWVudGF0aW9uIGZvciBjZXJ0YWluIHBsYXRmb3JtLiBGb3IgV2lueHAsIGl0IAogICAgd2lsbCBiZSBzbG93LgogICAgUGFyYW06IAogICAgICAgIHBQa3QgLSBwb2ludGVyIHRvIGEgd3B0X3BhY2tldC4KICAgIFJldHVybjoKICAgICAgICBOVUxMIC0gZmFpbC4KICAgICAgICBPdGhlcndpc2UgdGhlIGFkZHJlc3Mgb2YgdGhlIHN0YXJ0aW5nIG9mIHRoZSBidWZmZXIKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3VpbnQ4ICp3cGFsUGFja2V0R2V0UmF3QnVmKHdwdF9wYWNrZXQgKnBQa3QpCnsKICAgd3B0X3VpbnQ4ICpwUmV0ID0gTlVMTDsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBrdCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIHBhY2tldCBwb2ludGVyIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gTlVMTDsKICAgfQoKICAgLy9TaW5jZSBpdCBpcyBhIGZsYXQgYnVmZmVyLCBhbGwgd2UgbmVlZCBpcyB0byBnZXQgb25lIGJ5dGUgb2Ygb2Zmc2V0IDAKICAgaWYoIChlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXID09IFdQQUxfUEFDS0VUX0dFVF9UWVBFKHBQa3QpKSB8fAogICAgICAgKGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfMTFfTUdNVCA9PSBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGt0KSkgKQogICB7CiAgICAgIHZvc19wa3RfcGVla19kYXRhKFdQQUxfVE9fVk9TX1BLVChwUGt0KSwgMCwgKHZfVk9JRF90KiopJnBSZXQsIDEpOwogICAgICBXUEFMX0FTU0VSVChOVUxMICE9IHBSZXQpOwogICB9ICAgICAgICAgICAgCgogICByZXR1cm4gcFJldDsKfS8qd3BhbFBhY2tldEdldFJhd0J1ZiovCgoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxQYWNrZXRTZXRSeExlbmd0aCCWIFNldCB0aGUgdmFsaWQgZGF0YSBsZW5ndGggb24gYSBSWCBwYWNrZXQuIFRoaXMgZnVuY3Rpb24gbXVzdCAKICAgIGJlIGNhbGxlZCBvbmNlIHBlciBSWCBwYWNrZXQgcGVyIHJlY2VpdmluZy4gSXQgaW5kaWNhdGVzIHRoZSBhdmFpbGFibGUgZGF0YSBsZW5ndGggZnJvbQogICAgdGhlIHN0YXJ0IG9mIHRoZSBidWZmZXIuCiAgICBQYXJhbTogCiAgICAgICAgcFBrdCAtIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0LgogICAgUmV0dXJuOgogICAgICAgIE5VTEwgLSBmYWlsLgogICAgICAgIE90aGVyd2lzZSB0aGUgYWRkcmVzcyBvZiB0aGUgc3RhcnRpbmcgb2YgdGhlIGJ1ZmZlcgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxQYWNrZXRTZXRSeExlbmd0aCh3cHRfcGFja2V0ICpwUGt0LCB3cHRfdWludDMyIGxlbikKewogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBQa3QpKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLAogICAgICAgICAgICAgICAgIiVzIDogTlVMTCBwYWNrZXQgcG9pbnRlciIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgLypPbmx5IGFsbG93ZWQgZm9yIFJYIFJhdyBwYWNrZXRzICovCiAgIGlmKCAoZVdMQU5fUEFMX1BLVF9UWVBFX1JYX1JBVyAhPSBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGt0KSkpCiAgIHsKICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgCiAgICAgICAgICAgICAgICAiJXMgIEludmFsaWQgcGFja2V0IHR5cGUoJWQpIiwgIF9fZnVuY19fLAogICAgICAgICAgICAgICAgV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBrdCkpOwogICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIGlmKFZPU19JU19TVEFUVVNfU1VDQ0VTUyh2b3NfcGt0X3NldF9yeF9sZW5ndGgoV1BBTF9UT19WT1NfUEtUKHBQa3QpLCBsZW4pKSkKICAgewogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTOwogICB9CiAgIGVsc2UKICAgewogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9Cn0vKndwYWxQYWNrZXRTZXRSeExlbmd0aCovCgovKgogIFNldCBvZiBoZWxwZXIgZnVuY3Rpb25zIHRoYXQgd2lsbCBwcmVwYXJlIHBhY2tldCBmb3IgRE1BIHRyYW5zZmVyLAogIGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRyYW5zZmVyIDogLSB0byBhbmQgZnJvbSB0aGUgZGV2aWNlCiAgLSBmb2xsb3dpbmcgdGhlc2UgY2FsbHMgdGhlIHBhY2tldCB3aWxsIGJlIGxvY2tlZCBmb3IgRE1BIG9ubHksCiAgQ1BVIHdpbGwgbm90IGJlIGFibGUgdG8gbW9kaWZ5IGl0ID0+IHRoZSBwYWNrZXQgbXVzdCBiZSBleHBsaWNpdGx5IHJldHVybmVkIHRvCiAgdGhlIENQVSBvbmNlIHRoZSBETUEgdHJhbnNmZXIgaXMgY29tcGxldGUKKi8KV1BUX1NUQVRJQyBXUFRfSU5MSU5FIHZvaWQqIGl0R2V0T1NQa3RBZGRyRm9yRGV2aWNlKCB3cHRfcGFja2V0ICpwUGFja2V0ICkKewogICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiOwogICAvKi0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtICovCiAgIGlmICggVk9TX1NUQVRVU19TVUNDRVNTICE9IAogICAgICAgIHZvc19wa3RfZ2V0X29zX3BhY2tldChXUEFMX1RPX1ZPU19QS1QocFBhY2tldCksICh2b2lkKiopJnNrYiwgVk9TX0ZBTFNFICkpCiAgIHsKICAgICByZXR1cm4gTlVMTDsKICAgfQogICBlbHNlCiAgIHsKICAgICAvKk1hcCBza2IgZGF0YSBpbnRvIGRtYS1hYmxlIG1lbW9yeSAKICAgICAgIChjaGFuZ2VzIHdpbGwgYmUgY29tbWl0ZWQgZnJvbSBjYWNoZSkgKi8KICAgICByZXR1cm4gKHZvaWQqKWRtYV9tYXBfc2luZ2xlKCBOVUxMLCBza2ItPmRhdGEsIHNrYi0+bGVuLCBETUFfVE9fREVWSUNFICk7CiAgIH0KfS8qaXRHZXRPU1BrdEFkZHJGb3JEZXZpY2UqLwoKV1BUX1NUQVRJQyBXUFRfSU5MSU5FIHZvaWQqIGl0R2V0T1NQa3RBZGRyRnJvbURldmljZSggd3B0X3BhY2tldCAqcFBhY2tldCApCnsKCiAgIHN0cnVjdCBza19idWZmICpza2I7CiAgIC8qLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gKi8KICAgaWYgKCBWT1NfU1RBVFVTX1NVQ0NFU1MgIT0gCiAgICAgICAgdm9zX3BrdF9nZXRfb3NfcGFja2V0KFdQQUxfVE9fVk9TX1BLVChwUGFja2V0KSwgKHZvaWQqKikmc2tiLCBWT1NfRkFMU0UgKSkKICAgewogICAgIHJldHVybiBOVUxMOwogICB9CiAgIGVsc2UKICAgewogICAgIC8qTWFwIHNrYiBkYXRhIGludG8gZG1hLWFibGUgbWVtb3J5IAogICAgICAgKGNoYW5nZXMgd2lsbCBiZSBjb21taXRlZCBmcm9tIGNhY2hlKSAqLwogICAgIHJldHVybiAodm9pZCopZG1hX21hcF9zaW5nbGUoIE5VTEwsIHNrYi0+ZGF0YSwgc2tiLT5sZW4sIERNQV9GUk9NX0RFVklDRSApOwogICB9Cn0vKml0R2V0T1NQa3RBZGRyRnJvbURldmljZSovCgovKgogIFNldCBvZiBoZWxwZXIgZnVuY3Rpb25zIHRoYXQgd2lsbCByZXR1cm4gYSBETUEtZWQgcGFja2V0IHRvIHRoZSBDUFUsCiAgYmFzZWQgb24gdGhlIHR5cGUgb2YgdHJhbnNmZXIgOiAtIHRvIGFuZCBmcm9tIHRoZSBkZXZpY2UKKi8KV1BUX1NUQVRJQyBXUFRfSU5MSU5FIHZvaWQgaXRSZXR1cm5PU1BrdEFkZHJGb3JEZXZpY2UoIHdwdF9wYWNrZXQgKnBQYWNrZXQsICB2b2lkKiBhZGRyLCB3cHRfdWludDMyIHNpemUgKQp7CiAKICAgZG1hX3VubWFwX3NpbmdsZSggTlVMTCwgKGRtYV9hZGRyX3QpYWRkciwgc2l6ZSwgRE1BX1RPX0RFVklDRSApOwp9CgpXUFRfU1RBVElDIFdQVF9JTkxJTkUgdm9pZCBpdFJldHVybk9TUGt0QWRkckZyb21EZXZpY2UoIHdwdF9wYWNrZXQgKnBQYWNrZXQsIHZvaWQqIGFkZHIsIHdwdF91aW50MzIgc2l6ZSAgKQp7CgogICBkbWFfdW5tYXBfc2luZ2xlKCBOVUxMLCAoZG1hX2FkZHJfdClhZGRyLCBzaXplLCBETUFfRlJPTV9ERVZJQ0UgKTsgCn0KCgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogICAgd3BhbEl0ZXJhdG9ySW5pdCCWIEluaXRpYWxpemUgYW4gaW50ZXJhdG9yIGJ5IHVwZGF0aW5nIHBDdXIgdG8gZmlyc3QgaXRlbS4KICAgIFBhcmFtOiAKICAgICAgICBwSXRlciCWIHBvaW50ZXIgdG8gYSBjYWxsZXIgYWxsb2NhdGVkIHdwdF9pdGVyYXRvcgogICAgICAgIHBQYWNrZXQgliBwb2ludGVyIHRvIGEgd3B0X3BhY2tldAogICAgUmV0dXJuOgogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUyAtIHN1Y2Nlc3MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsSXRlcmF0b3JJbml0KHdwdF9pdGVyYXRvciAqcEl0ZXIsIHdwdF9wYWNrZXQgKnBQYWNrZXQpCnsKICAgd3B0X3N0YXR1cyAgICAgICAgIHN0YXR1cyAgICAgPSBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7CiAgIHdwdF9pdGVyYXRvcl9pbmZvKiBwQ3VySW5mbyAgID0gTlVMTDsKICAgd3B0X2l0ZXJhdG9yX2luZm8qIHBOZXh0SW5mbyAgPSBOVUxMOwogICB3cHRfaXRlcmF0b3JfaW5mbyogcFBrdEluZm8gICA9IE5VTEw7CgogICAvLyBWYWxpZGF0ZSB0aGUgcGFyYW1ldGVyIHBvaW50ZXJzCiAgIGlmICh1bmxpa2VseSgoTlVMTCA9PSBwUGFja2V0KXx8KE5VTEw9PXBJdGVyKSkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXJzICVwICVwIiwgX19mdW5jX18sIHBQYWNrZXQsIHBJdGVyKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgcFBrdEluZm8gPSAod3B0X2l0ZXJhdG9yX2luZm8qKXBQYWNrZXQtPnBJbnRlcm5hbERhdGE7CiAgIGlmICh1bmxpa2VseShOVUxMID09IHBQa3RJbmZvKSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IEludmFsaWQgUGFja2V0IEluZm8iLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIC8vIGlmIHRoZXJlIGlzIE5PIEJEIG9uIHRoaXMgZnJhbWUsIHRoZW4gaW5pdGlhbGl6ZSB0aGUgbmV4dCBwb2ludGVyIHRvCiAgIC8vIHBvaW50IHRoZSBmaXJzdCBmcmFnbWVudC4KICAgaWYgKCBOVUxMID09IFdQQUxfUEFDS0VUX0dFVF9CRF9QSFlTKHBQYWNrZXQpICkKICAgewogICAgIHBDdXJJbmZvICAgPSBwUGt0SW5mbzsKICAgICBwTmV4dEluZm8gICAgICAgICAgID0gTlVMTDsKICAgfQogICBlbHNlCiAgIHsKICAgICAvKkFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIGN1cnJlbnQgaW5mbyovCiAgICAgcEN1ckluZm8gPSB3cGFsTWVtb3J5QWxsb2NhdGUoIHNpemVvZih3cHRfaXRlcmF0b3JfaW5mbykgKTsKCiAgICAgLy8gVmFsaWRhdGUgdGhlIG1lbW9yeSBhbGxvY2F0aW9uCiAgICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcEN1ckluZm8pKQogICAgIHsKICAgICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICAgIiVzIDogRmFpbGVkIHRvIGFsbG9jYXRlIG1lbW9yeSAiLCBfX2Z1bmNfXyk7CiAgICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgICB9CgogICAgIHBDdXJJbmZvLT5wUGh5QWRkciA9IFdQQUxfUEFDS0VUX0dFVF9CRF9QSFlTKHBQYWNrZXQpOwogICAgIHBDdXJJbmZvLT51TGVuICAgICA9IFdQQUxfUEFDS0VUX0dFVF9CRF9MRU5HVEgocFBhY2tldCk7CgogICAgIHBOZXh0SW5mbyAgICAgICAgICAgPSBwUGt0SW5mbzsKICAgfSAgICAgIAoKICAgcEl0ZXItPnBDdXIgICAgID0gKHZvaWQqKXBDdXJJbmZvOyAKICAgcEl0ZXItPnBOZXh0ICAgID0gKHZvaWQqKXBOZXh0SW5mbzsKICAgcEl0ZXItPnBDb250ZXh0ID0gTlVMTDsKCiAgIHJldHVybiBzdGF0dXM7Cn0vKndwYWxJdGVyYXRvckluaXQqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxJdGVyYXRvck5leHQgliBHZXQgdGhlIGFkZHJlc3MgZm9yIHRoZSBuZXh0IGl0ZW0KICAgIFBhcmFtOiAKICAgICAgICBwSXRlciCWIHBvaW50ZXIgdG8gYSBjYWxsZXIgYWxsb2NhdGVkIHdwdF9pdGVyYXRvcgogICAgICAgIHBQYWNrZXQgliBwb2ludGVyIHRvIGEgd3B0X3BhY2tldAogICAgICAgIHBwQWRkciCWIENhbGxlciBhbGxvY2F0ZWQgcG9pbnRlciB0byByZXR1cm4gdGhlIGFkZHJlc3Mgb2YgdGhlIGl0ZW0uCiAgICAgICAgRm9yIERNQS1hYmxlIGRldmljZXMsIHRoaXMgaXMgdGhlIHBoeXNpY2FsIGFkZHJlc3Mgb2YgdGhlIGl0ZW0uCiAgICAgICAgcExlbiCWIFRvIHJldHVybiB0aGUgbnVtYmVyIG9mIGJ5dGVzIGluIHRoZSBpdGVtLgogICAgUmV0dXJuOgogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUyAtIHN1Y2Nlc3MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsSXRlcmF0b3JOZXh0KHdwdF9pdGVyYXRvciAqcEl0ZXIsIHdwdF9wYWNrZXQgKnBQYWNrZXQsIHZvaWQgKipwcEFkZHIsIHdwdF91aW50MzIgKnBMZW4pCnsKICAgd3B0X2l0ZXJhdG9yX2luZm8qIHBDdXJJbmZvICA9IE5VTEw7CiAgIC8qLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0gLSAtIC0qLwogICAKICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgU2FuaXR5IGNoZWNrCiAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwogICBpZiAodW5saWtlbHkoKCBOVUxMID09IHBJdGVyICl8fCggTlVMTCA9PSBwUGFja2V0ICkgfHwgCiAgICAgICggTlVMTCA9PSBwcEFkZHIgKSB8fCAoIE5VTEwgPT0gcExlbiApKSkKICAgewogICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0VSUk9SLCAKICAgICAgICAgICAgICAgICIlcyAgSW52YWxpZCBpbnB1dCBwYXJhbWV0ZXJzIiwgIF9fZnVuY19fICk7CiAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgcEN1ckluZm8gPSAod3B0X2l0ZXJhdG9yX2luZm8qKXBJdGVyLT5wQ3VyOyAKICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAgSWYgY3VycmVudCBwb2ludGVyIGlzIE5VTEwgLSB0aGVyZSBpcyBubyBkYXRhIGluIHRoZSBwYWNrZXQgLSByZXR1cm4KICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCiAgIGlmKCBwSXRlci0+cEN1ciA9PSBOVUxMICkKICAgewogICAgICAqcHBBZGRyID0gTlVMTDsgCiAgICAgICpwTGVuICAgPSAwOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTOwogICB9CgogICAvKkFkZHJlc3MgYW5kIGxlbmd0aCBhcmUga2VwdCBpbiB0aGUgY3VycmVudCBmaWVsZCovCiAgICpwcEFkZHIgPSBwQ3VySW5mby0+cFBoeUFkZHI7IAogICAqcExlbiAgID0gcEN1ckluZm8tPnVMZW47CiAgICAKICAgaWYoIE5VTEwgPT0gcEl0ZXItPnBOZXh0ICkKICAgewogICAgIC8qU2F2ZSB0aGUgaXRlcmF0b3IgZm9yIGNsZWFudXAqLwogICAgIHBQYWNrZXQtPnBJbnRlcm5hbERhdGEgPSBwSXRlci0+cEN1cjsgCiAgICAgcEl0ZXItPnBDdXIgICAgICAgICAgICA9IE5VTEw7IAogICB9CiAgIGVsc2UKICAgewogICAgIC8qUmVsZWFzZSB0aGUgbWVtb3J5IHNhdmVkIGZvciBzdG9yaW5nIHRoZSBCRCBpbmZvcm1hdGlvbiovCiAgICAgd3BhbE1lbW9yeUZyZWUocEN1ckluZm8pOyAKICAKICAgICAvKkZvciBMQSAtIHRoZSBwYWNrZXQgaXMgcmVwcmVzZW50ZWQgYnkgbWF4aW11bSAyIGZpZWxkcyBvZiBkYXRhIAogICAgICAgLSBCRCBhbmQgYWN0dWFsIGRhdGEgZnJvbSBzayBidWZmICovCiAgICAgcEl0ZXItPnBDdXIgICAgID0gcEl0ZXItPnBOZXh0OwogICAgIHBJdGVyLT5wTmV4dCAgICA9IE5VTEw7CiAgIH0KICAgCiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICB3cGFsTG9ja1BhY2tldEZvclRyYW5zZmVyIJYgTWFwIHRoZSBkYXRhIGJ1ZmZlciBmcm9tIGRtYSBzbyB0aGF0IHRoZQogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSBpcyBjb21taXRlZCBmcm9tIGNhY2hlIGFuZCB0aGUgY3B1IHJlbGlucXVpc2hlcwogICAgICAgICAgICAgICAgICAgICAgICAgb3duZXJzaGlwIG9mIHRoZSBidWZmZXIKIAogICAgUGFyYW06IAogICAgICAgIHBQYWNrZXQgliBwb2ludGVyIHRvIGEgd3B0X3BhY2tldAogCiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIC0gc3VjY2VzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxMb2NrUGFja2V0Rm9yVHJhbnNmZXIoIHdwdF9wYWNrZXQgKnBQYWNrZXQpCnsKICAgdm9pZCogICAgICAgICAgICAgIHBQaHlEYXRhICAgPSBOVUxMOwogICB3cHRfaXRlcmF0b3JfaW5mbyogcEluZm8gICAgICA9IE5VTEw7CiAgIHZfVTE2X3QgICAgICAgICAgICB1TGVuRGF0YSAgID0gMDsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBhY2tldCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXIiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIHN3aXRjaChXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGFja2V0KSkKICAgewogICAgICAvKiBGb3IgbWFuYWdlbWVudCBmcmFtZXMsIEJEIGlzIGFsbG9jYXRlZCBieSBXREksIGhlYWRlciBpcyBpbiByYXcgYnVmZmVyLAogICAgICAgICByZXN0IG9mIHRoZSBmcmFtZSBpcyBhbHNvIGluIHJhdyBidWZmZXIgKi8KICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzExX01HTVQ6CiAgICAgIHsKICAgICAgICAgLypUWCBQYWNrZXRzIG5lZWQgdG8gYmUgRE1BLWVkIHRvIHRoZSBkZXZpY2UsIHBlcmZvcm0gRE1BIG1hcHBpbmcgCiAgICAgICAgICAgYWNjb3JkaW5nbHkgKi8KICAgICAgICAgcFBoeURhdGEgPSAodm9pZCopaXRHZXRPU1BrdEFkZHJGb3JEZXZpY2UoIHBQYWNrZXQgKTsgICAKICAgICAgfQogICAgICBicmVhazsKICAgICAgICAgLyogRGF0YSBwYWNrZXRzIC0gQkQgKGFsbG9jYXRlZCBieSBXREkpLCBoZWFkZXIgKGluIFZPU1MgaGVhZGVyKSwKICAgICAgICAgICAgcmVzdCBvZiB0aGUgcGFja2V0IChEU00gaXRlbXMpICovCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8xMV9EQVRBOgogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfM19EQVRBOgogICAgICB7CiAgICAgICAgIC8qVFggUGFja2V0cyBuZWVkIHRvIGJlIERNQS1lZCB0byB0aGUgZGV2aWNlLCBwZXJmb3JtIERNQSBtYXBwaW5nIAogICAgICAgICAgIGFjY29yZGluZ2x5ICovCiAgICAgICAgIHBQaHlEYXRhID0gKHZvaWQqKWl0R2V0T1NQa3RBZGRyRm9yRGV2aWNlKCBwUGFja2V0ICk7CiAgICAgIH0KICAgICAgYnJlYWs7CgogICAgICAvKiBGb3IgUmF3IFJYLCBCRCArIGhlYWRlciArIHJlc3Qgb2YgdGhlIHBhY2tldCBpcyBhbGwgY29udGFpbmVkIGluIHRoZSByYXcKICAgICAgICAgYnVmZmVyICovCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1JYX1JBVzoKICAgICAgewogICAgICAgICAvKlJYIFBhY2tldHMgbmVlZCB0byBiZSBETUEtZWQgZnJvbSB0aGUgZGV2aWNlLCBwZXJmb3JtIERNQSBtYXBwaW5nIAogICAgICAgICAgIGFjY29yZGluZ2x5ICovCiAgICAgICAgIHBQaHlEYXRhID0gKHZvaWQqKWl0R2V0T1NQa3RBZGRyRnJvbURldmljZSggcFBhY2tldCApOwogICAgICB9CiAgICAgIGJyZWFrOwoKICAgZGVmYXVsdDoKICAgICAgewogICAgICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwgCiAgICAgICAgICAgICAgICAgICAgIiBXTEFOX1BBTDogJXM6IEludmFsaWQgcGFja2V0IHR5cGUgJWQhIiwgIF9fZnVuY19fLCAKICAgICAgICAgICAgICAgICAgICBXUEFMX1BBQ0tFVF9HRVRfVFlQRShwUGFja2V0KSApOyAKICAgICAgICAgV1BBTF9BU1NFUlQoMCk7IAogICAgICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0ZBSUxVUkU7CiAgICAgIH0KICAgfQoKICAgLypHZXQgcGFja2V0IGxlbmd0aCovCiAgIHZvc19wa3RfZ2V0X3BhY2tldF9sZW5ndGgoV1BBTF9UT19WT1NfUEtUKHBQYWNrZXQpLCZ1TGVuRGF0YSk7CgogICAgLypBbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBjdXJyZW50IGluZm8qLwogICBwSW5mbyA9IHdwYWxNZW1vcnlBbGxvY2F0ZSggc2l6ZW9mKHdwdF9pdGVyYXRvcl9pbmZvKSApOwoKICAgLy8gVmFsaWRhdGUgdGhlIG1lbW9yeSBhbGxvY2F0aW9uCiAgIGlmICh1bmxpa2VseShOVUxMID09IHBJbmZvKSkKICAgewogICAgICBXUEFMX1RSQUNFKGVXTEFOX01PRFVMRV9QQUwsIGVXTEFOX1BBTF9UUkFDRV9MRVZFTF9FUlJPUiwKICAgICAgICAgICAgICAgICIlcyA6IEZhaWxlZCB0byBhbGxvY2F0ZSBtZW1vcnkgIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBwSW5mby0+cFBoeUFkZHIgPSBwUGh5RGF0YTsKICAgcEluZm8tPnVMZW4gICAgID0gdUxlbkRhdGE7CgogICBwUGFja2V0LT5wSW50ZXJuYWxEYXRhID0gcEluZm87CiAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0vKndwYWxMb2NrUGFja2V0Rm9yVHJhbnNmZXIqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxVbmxvY2tQYWNrZXQgliBVbm1hcCB0aGUgZGF0YSBidWZmZXIgZnJvbSBkbWEgc28gdGhhdCBjcHUgY2FuIHJlZ2FpbgogICAgICAgICAgICAgICAgICAgICAgICAgIG93bmVyc2hpcCBvbiBpdAogICAgUGFyYW06IAogICAgICAgIHBQYWNrZXQgliBwb2ludGVyIHRvIGEgd3B0X3BhY2tldAogCiAgICBSZXR1cm46CiAgICAgICAgZVdMQU5fUEFMX1NUQVRVU19TVUNDRVNTIC0gc3VjY2VzcwotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxVbmxvY2tQYWNrZXQoIHdwdF9wYWNrZXQgKnBQYWNrZXQpCnsKCiAgIHdwdF9pdGVyYXRvcl9pbmZvKiBwSW5mbzsKCiAgIC8vIFZhbGlkYXRlIHRoZSBwYXJhbWV0ZXIgcG9pbnRlcnMKICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcFBhY2tldCkpCiAgIHsKICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXIgcFBhY2tldCIsIF9fZnVuY19fKTsKICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTDsKICAgfQoKICAgcEluZm8gID0gKHdwdF9pdGVyYXRvcl9pbmZvKilwUGFja2V0LT5wSW50ZXJuYWxEYXRhOwoKICAgLy8gVmFsaWRhdGUgcEluZm8KICAgaWYgKHVubGlrZWx5KE5VTEwgPT0gcEluZm8pKQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX0ZBVEFMLAogICAgICAgICAgICAgICAgIiVzIDogTlVMTCBpbnB1dCBwb2ludGVyIHBJbmZvIiwgX19mdW5jX18pOwogICAgICByZXR1cm4gZVdMQU5fUEFMX1NUQVRVU19FX0lOVkFMOwogICB9CgogICBzd2l0Y2goV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBhY2tldCkpCiAgIHsKICAgICAgLyogRm9yIG1hbmFnZW1lbnQgZnJhbWVzLCBCRCBpcyBhbGxvY2F0ZWQgYnkgV0RJLCBoZWFkZXIgaXMgaW4gcmF3IGJ1ZmZlciwKICAgICAgICAgcmVzdCBvZiB0aGUgZnJhbWUgaXMgYWxzbyBpbiByYXcgYnVmZmVyICovCiAgIGNhc2UgZVdMQU5fUEFMX1BLVF9UWVBFX1RYXzgwMl8xMV9NR01UOgogICAgICB7CiAgICAgICAgIC8qVFggUGFja2V0cyBuZWVkIHRvIGJlIERNQS1lZCB0byB0aGUgZGV2aWNlLCBwZXJmb3JtIERNQSBtYXBwaW5nIAogICAgICAgICAgIGFjY29yZGluZ2x5ICovCiAgICAgICAgaXRSZXR1cm5PU1BrdEFkZHJGb3JEZXZpY2UocFBhY2tldCwgcEluZm8tPnBQaHlBZGRyLCBwSW5mby0+dUxlbik7ICAgCiAgICAgIH0KICAgICAgYnJlYWs7CiAgICAgICAgIC8qIERhdGEgcGFja2V0cyAtIEJEIChhbGxvY2F0ZWQgYnkgV0RJKSwgaGVhZGVyIChpbiBWT1NTIGhlYWRlciksCiAgICAgICAgICAgIHJlc3Qgb2YgdGhlIHBhY2tldCAoRFNNIGl0ZW1zKSAqLwogICBjYXNlIGVXTEFOX1BBTF9QS1RfVFlQRV9UWF84MDJfMTFfREFUQToKICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfVFhfODAyXzNfREFUQToKICAgICAgewogICAgICAgICAvKlRYIFBhY2tldHMgbmVlZCB0byBiZSBETUEtZWQgdG8gdGhlIGRldmljZSwgcGVyZm9ybSBETUEgbWFwcGluZyAKICAgICAgICAgICBhY2NvcmRpbmdseSAqLwogICAgICAgICBpdFJldHVybk9TUGt0QWRkckZvckRldmljZShwUGFja2V0LCBwSW5mby0+cFBoeUFkZHIsIHBJbmZvLT51TGVuKTsgICAKICAgICAgfQogICAgICBicmVhazsKCiAgICAgIC8qIEZvciBSYXcgUlgsIEJEICsgaGVhZGVyICsgcmVzdCBvZiB0aGUgcGFja2V0IGlzIGFsbCBjb250YWluZWQgaW4gdGhlIHJhdwogICAgICAgICBidWZmZXIgKi8KICAgY2FzZSBlV0xBTl9QQUxfUEtUX1RZUEVfUlhfUkFXOgogICAgICB7CiAgICAgICAgIC8qUlggUGFja2V0cyBuZWVkIHRvIGJlIERNQS1lZCBmcm9tIHRoZSBkZXZpY2UsIHBlcmZvcm0gRE1BIG1hcHBpbmcgCiAgICAgICAgICAgYWNjb3JkaW5nbHkgKi8KICAgICAgICAgaWYoTlVMTCA9PSBwSW5mby0+cFBoeUFkZHIpCiAgICAgICAgIHsKICAgICAgICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgICAgICAgICIgV0xBTl9QQUw6ICVzOiBSWCBmcmFtZSB3YXMgbm90IGxvY2tlZCBwcm9wZXJseSIsICBfX2Z1bmNfXyk7IAogICAgICAgICB9CiAgICAgICAgIGVsc2UKICAgICAgICAgewogICAgICAgICAgICBpdFJldHVybk9TUGt0QWRkckZyb21EZXZpY2UocFBhY2tldCwgcEluZm8tPnBQaHlBZGRyLCBwSW5mby0+dUxlbik7ICAgCiAgICAgICAgIH0KICAgICAgfQogICAgICBicmVhazsKCiAgIGRlZmF1bHQ6CiAgICAgIHsKICAgICAgICAgV1BBTF9UUkFDRShlV0xBTl9NT0RVTEVfUEFMLCBlV0xBTl9QQUxfVFJBQ0VfTEVWRUxfRVJST1IsIAogICAgICAgICAgICAgICAgICAgICIgV0xBTl9QQUw6ICVzOiBJbnZhbGlkIHBhY2tldCB0eXBlICVkISIsICBfX2Z1bmNfXywgCiAgICAgICAgICAgICAgICAgICAgV1BBTF9QQUNLRVRfR0VUX1RZUEUocFBhY2tldCkgKTsgCiAgICAgICAgIFdQQUxfQVNTRVJUKDApOyAKICAgICAgICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfRV9GQUlMVVJFOwogICAgICB9CiAgIH0KCiAgd3BhbE1lbW9yeUZyZWUocEluZm8pOwogIHBQYWNrZXQtPnBJbnRlcm5hbERhdGEgPSBOVUxMOwogIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1M7Cn0vKndwYWxVbmxvY2tQYWNrZXQqLwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxJc1BhY2tldExvY2tlZCCWICBDaGVjayB3aGV0aGVyIHRoZSBQYWNrZXQgaXMgbG9ja2VkIGZvciBETUEuCiAgICBQYXJhbTogCiAgICAgICAgcFBhY2tldCCWIHBvaW50ZXIgdG8gYSB3cHRfcGFja2V0CiAKICAgIFJldHVybjoKICAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MKICAgICAgICBlV0xBTl9QQUxfU1RBVFVTX0VfRkFJTFVSRQogICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfRV9JTlZBTAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp3cHRfc3RhdHVzIHdwYWxJc1BhY2tldExvY2tlZCggd3B0X3BhY2tldCAqcFBhY2tldCkKewoKICAgd3B0X2l0ZXJhdG9yX2luZm8qIHBJbmZvOwoKICAgLyogVmFsaWRhdGUgdGhlIHBhcmFtZXRlciBwb2ludGVycyAqLwogICBpZiAoTlVMTCA9PSBwUGFja2V0KQogICB7CiAgICAgIFdQQUxfVFJBQ0UoZVdMQU5fTU9EVUxFX1BBTCwgZVdMQU5fUEFMX1RSQUNFX0xFVkVMX1dBUk4sCiAgICAgICAgICAgICAgICAiJXMgOiBOVUxMIGlucHV0IHBvaW50ZXIiLCBfX2Z1bmNfXyk7CiAgICAgIHJldHVybiBlV0xBTl9QQUxfU1RBVFVTX0VfSU5WQUw7CiAgIH0KCiAgIC8qIFZhbGlkYXRlIHBJbnRlcm5hbERhdGEgKi8KICAgcEluZm8gID0gKHdwdF9pdGVyYXRvcl9pbmZvKilwUGFja2V0LT5wSW50ZXJuYWxEYXRhOwogICByZXR1cm4gKE5VTEwgPT0gcEluZm8pPyBlV0xBTl9QQUxfU1RBVFVTX0VfRkFJTFVSRSA6IAogICAgICAgICAgICAgICAgICAgIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfS8qd3BhbElzUGFja2V0TG9ja2VkKi8KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgIHdwYWxHZXROdW1SeFJhd1BhY2tldCAgIFF1ZXJ5IGF2YWlsYWJsZSBSWCBSQVcgdG90YWwgYnVmZmVyIGNvdW50CiAgIHBhcmFtOgogICAgICAgbnVtUnhSZXNvdXJjZSAgcG9pbnRlciBvZiBxdWVyaWVkIHZhbHVlCgogICByZXR1cm46CiAgICAgICBlV0xBTl9QQUxfU1RBVFVTX1NVQ0NFU1MKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8Kd3B0X3N0YXR1cyB3cGFsR2V0TnVtUnhSYXdQYWNrZXQod3B0X3VpbnQzMiAqbnVtUnhSZXNvdXJjZSkKewogICAqbnVtUnhSZXNvdXJjZSA9ICh3cHRfdWludDMyKXZvc19wa3RfZ2V0X251bV9vZl9yeF9yYXdfcGt0cygpOwoKICAgcmV0dXJuIGVXTEFOX1BBTF9TVEFUVVNfU1VDQ0VTUzsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxQYWNrZXRTdGFsbFVwZGF0ZUluZm8gliBVcGRhdGUgZWFjaCBjaGFubmVsIGluZm9ybWF0aW9uIHdoZW4gc3RhbGwKICAgICAgIGRldGVjdGVkLCBhbHNvIHBvd2VyIHN0YXRlIGFuZCBmcmVlIHJlc291cmNlIGNvdW50CgogICAgUGFyYW06CiAgICAgICBwb3dlclN0YXRlICA/IFdMQU4gc3lzdGVtIHBvd2VyIHN0YXRlIHdoZW4gc3RhbGwgZGV0ZWN0ZWQKICAgICAgIG51bUZyZWVCZCAgID8gTnVtYmVyIG9mIGZyZWUgcmVzb3VyY2UgY291bnQgaW4gSFcKICAgICAgIGNoYW5uZWxJbmZvID8gRWFjaCBjaGFubmVsIHNwZWNpZmljIGluZm9ybWF0aW9uIHdoZW4gc3RhbGwgaGFwcGVuCiAgICAgICBjaGFubmVsTnVtICA/IENoYW5uZWwgbnVtYmVyIHVwZGF0ZSBpbmZvcm1hdGlvbgoKICAgIFJldHVybjoKICAgICAgIE5PTkUKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgd3BhbFBhY2tldFN0YWxsVXBkYXRlSW5mbwooCiAgIHZfVTMyX3QgICAgICAgICAgICAgICAgICAgICAgICAgKnBvd2VyU3RhdGUsCiAgIHZfVTMyX3QgICAgICAgICAgICAgICAgICAgICAgICAgKm51bUZyZWVCZCwKICAgd3B0X2xvZ19kYXRhX3N0YWxsX2NoYW5uZWxfdHlwZSAqY2hhbm5lbEluZm8sCiAgIHZfVThfdCAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxOdW0KKQp7CiAgIC8qIFVwZGF0ZSBwb3dlciBzdGF0ZSB3aGVuIHN0YWxsIGRldGVjdGVkICovCiAgIGlmKE5VTEwgIT0gcG93ZXJTdGF0ZSkKICAgewogICAgICB3cGFsVHJhc3BvcnRTdGFsbEluZm8uUG93ZXJTdGF0ZSA9ICpwb3dlclN0YXRlOwogICB9CgogICAvKiBVcGRhdGUgSFcgZnJlZSByZXNvdXJjZSBjb3VudCAqLwogICBpZihOVUxMICE9IG51bUZyZWVCZCkKICAgewogICAgICB3cGFsVHJhc3BvcnRTdGFsbEluZm8ubnVtRnJlZUJkICA9ICpudW1GcmVlQmQ7CiAgIH0KCiAgIC8qIFVwZGF0ZSBjaGFubmVsIGluZm9ybWF0aW9uICovCiAgIGlmKE5VTEwgIT0gY2hhbm5lbEluZm8pCiAgIHsKICAgICAgd3BhbE1lbW9yeUNvcHkoJndwYWxUcmFzcG9ydFN0YWxsSW5mby5keGVDaGFubmVsSW5mb1tjaGFubmVsTnVtXSwKICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbEluZm8sCiAgICAgICAgICAgICAgICAgICAgIHNpemVvZih3cHRfbG9nX2RhdGFfc3RhbGxfY2hhbm5lbF90eXBlKSk7CiAgIH0KCiAgIHJldHVybjsKfQoKI2lmZGVmIEZFQVRVUkVfV0xBTl9ESUFHX1NVUFBPUlQKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICAgIHdwYWxQYWNrZXRTdGFsbER1bXBMb2cgliBUcmlnZ2VyIHRvIHNlbmQgbG9nIHBhY2tldCB0byBESUFHCiAgICAgICBVcGRhdGVkIHRyYW5zcG9ydCBzeXN0ZW0gaW5mb3JtYXRpb24gd2lsbCBiZSBzZW50IHRvIERJQUcKCiAgICBQYXJhbToKICAgICAgICBOT05FCgogICAgUmV0dXJuOgogICAgICAgIE5PTkUKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnZvaWQgd3BhbFBhY2tldFN0YWxsRHVtcExvZwooCiAgIHZvaWQKKQp7CiAgIHZvc19sb2dfZGF0YV9zdGFsbF90eXBlICAqbG9nX3B0ciA9IE5VTEw7CgogICBXTEFOX1ZPU19ESUFHX0xPR19BTExPQyhsb2dfcHRyLCB2b3NfbG9nX2RhdGFfc3RhbGxfdHlwZSwgTE9HX1RSU1BfREFUQV9TVEFMTF9DKTsKICAgaWYobG9nX3B0cikKICAgewogICAgICBsb2dfcHRyLT5Qb3dlclN0YXRlID0gd3BhbFRyYXNwb3J0U3RhbGxJbmZvLlBvd2VyU3RhdGU7CiAgICAgIGxvZ19wdHItPm51bUZyZWVCZCAgPSB3cGFsVHJhc3BvcnRTdGFsbEluZm8ubnVtRnJlZUJkOwogICAgICB3cGFsTWVtb3J5Q29weSgmbG9nX3B0ci0+ZHhlQ2hhbm5lbEluZm9bMF0sCiAgICAgICAgICAgICAgICAgICAgICZ3cGFsVHJhc3BvcnRTdGFsbEluZm8uZHhlQ2hhbm5lbEluZm9bMF0sCiAgICAgICAgICAgICAgICAgICAgIFdQVF9OVU1fVFJQVF9DSEFOTkVMICogc2l6ZW9mKHZvc19sb2dfZGF0YV9zdGFsbF9jaGFubmVsX3R5cGUpKTsKICAgICAgcHJfaW5mbygiU3RhbGwgbG9nIGR1bXAiKTsKICAgICAgV0xBTl9WT1NfRElBR19MT0dfUkVQT1JUKGxvZ19wdHIpOwogICB9CgogICByZXR1cm47Cn0KI2VuZGlmIC8qIEZFQVRVUkVfV0xBTl9ESUFHX1NVUFBPUlQgKi8K