Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoQml0bWFwLmgKLy8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vCi8vIE1vZGlmaWVkIHVuZGVyIHRoZSBQb3BwbGVyIHByb2plY3QgLSBodHRwOi8vcG9wcGxlci5mcmVlZGVza3RvcC5vcmcKLy8KLy8gQWxsIGNoYW5nZXMgbWFkZSB1bmRlciB0aGUgUG9wcGxlciBwcm9qZWN0IHRvIHRoaXMgZmlsZSBhcmUgbGljZW5zZWQKLy8gdW5kZXIgR1BMIHZlcnNpb24gMiBvciBsYXRlcgovLwovLyBDb3B5cmlnaHQgKEMpIDIwMDcgSWxtYXJpIEhlaWtraW5lbiA8aWxtYXJpLmhlaWtraW5lbkBnbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAwOSBTaGVuIExpYW5nIDxzaGVuemh1eGlAZ21haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMDksIDIwMTIsIDIwMTggQWxiZXJ0IEFzdGFscyBDaWQgPGFhY2lkQGtkZS5vcmc+Ci8vIENvcHlyaWdodCAoQykgMjAwOSBTdGVmYW4gVGhvbWFzIDx0aG9tYXNAZWxvYWQyNC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMCwgMjAxNyBBZHJpYW4gSm9obnNvbiA8YWpvaG5zb25AcmVkbmVvbi5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMCBIYXJyeSBSb2JlcnRzIDxoYXJyeS5yb2JlcnRzQG1pZG5pZ2h0LWxhYnMub3JnPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgQ2hyaXN0aWFuIEZldWVyc+RuZ2VyIDxjZmV1ZXJzYWVuZ2VyQGdvb2dsZW1haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgV2lsbGlhbSBCYWRlciA8d2lsbGlhbWJhZGVyQGhvdG1haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTIgVGhvbWFzIEZyZWl0YWcgPFRob21hcy5GcmVpdGFnQGFsZmEuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAxNSBBZGFtIFJlaWNob2xkIDxhZGFtcmVpY2hvbGRAbXlvcGVyYS5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxNiBLZW5qaSBVbm8gPGt1QGRpZ2l0YWxkb2xwaGlucy5qcD4KLy8gQ29weXJpZ2h0IChDKSAyMDE4IE1hcnRpbiBQYWNrbWFuIDxnemxpc3RAZ29vZ2xlbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxOSBPbGl2ZXIgU2FuZGVyIDxvbGl2ZXIuc2FuZGVyQHR1LWRyZXNkZW4uZGU+Ci8vCi8vIFRvIHNlZSBhIGRlc2NyaXB0aW9uIG9mIHRoZSBjaGFuZ2VzIHBsZWFzZSBzZWUgdGhlIENoYW5nZWxvZyBmaWxlIHRoYXQKLy8gY2FtZSB3aXRoIHlvdXIgdGFyYmFsbCBvciB0eXBlIG1ha2UgQ2hhbmdlTG9nIGlmIHlvdSBhcmUgYnVpbGRpbmcgZnJvbSBnaXQKLy8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpZm5kZWYgU1BMQVNIQklUTUFQX0gKI2RlZmluZSBTUExBU0hCSVRNQVBfSAoKI2luY2x1ZGUgIlNwbGFzaFR5cGVzLmgiCiNpbmNsdWRlICJwb3BwbGVyL0dmeFN0YXRlLmgiCiNpbmNsdWRlIDxzdGRpby5oPgoKY2xhc3MgSW1nV3JpdGVyOwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gU3BsYXNoQml0bWFwCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpjbGFzcyBTcGxhc2hCaXRtYXAgewpwdWJsaWM6CgogIC8vIENyZWF0ZSBhIG5ldyBiaXRtYXAuICBJdCB3aWxsIGhhdmUgPHdpZHRoQT4geCA8aGVpZ2h0QT4gcGl4ZWxzIGluCiAgLy8gY29sb3IgbW9kZSA8bW9kZUE+LiAgUm93cyB3aWxsIGJlIHBhZGRlZCBvdXQgdG8gYSBtdWx0aXBsZSBvZgogIC8vIDxyb3dQYWQ+IGJ5dGVzLiAgSWYgPHRvcERvd24+IGlzIGZhbHNlLCB0aGUgYml0bWFwIHdpbGwgYmUgc3RvcmVkCiAgLy8gdXBzaWRlLWRvd24sIGkuZS4sIHdpdGggdGhlIGxhc3Qgcm93IGZpcnN0IGluIG1lbW9yeS4KICBTcGxhc2hCaXRtYXAoaW50IHdpZHRoQSwgaW50IGhlaWdodEEsIGludCByb3dQYWQsCgkgICAgICAgU3BsYXNoQ29sb3JNb2RlIG1vZGVBLCBib29sIGFscGhhQSwKCSAgICAgICBib29sIHRvcERvd24gPSB0cnVlLCBzdGQ6OnZlY3RvcjxHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSo+ICpzZXBhcmF0aW9uTGlzdCA9IG51bGxwdHIpOwogIHN0YXRpYyBTcGxhc2hCaXRtYXAgKmNvcHkoU3BsYXNoQml0bWFwICpzcmMpOwoKICB+U3BsYXNoQml0bWFwKCk7CgogIFNwbGFzaEJpdG1hcChjb25zdCBTcGxhc2hCaXRtYXAgJikgPSBkZWxldGU7CiAgU3BsYXNoQml0bWFwJiBvcGVyYXRvcj0oY29uc3QgU3BsYXNoQml0bWFwICYpID0gZGVsZXRlOwoKICBpbnQgZ2V0V2lkdGgoKSB7IHJldHVybiB3aWR0aDsgfQogIGludCBnZXRIZWlnaHQoKSB7IHJldHVybiBoZWlnaHQ7IH0KICBpbnQgZ2V0Um93U2l6ZSgpIHsgcmV0dXJuIHJvd1NpemU7IH0KICBpbnQgZ2V0QWxwaGFSb3dTaXplKCkgeyByZXR1cm4gd2lkdGg7IH0KICBpbnQgZ2V0Um93UGFkKCkgeyByZXR1cm4gcm93UGFkOyB9CiAgU3BsYXNoQ29sb3JNb2RlIGdldE1vZGUoKSB7IHJldHVybiBtb2RlOyB9CiAgU3BsYXNoQ29sb3JQdHIgZ2V0RGF0YVB0cigpIHsgcmV0dXJuIGRhdGE7IH0KICB1bnNpZ25lZCBjaGFyICpnZXRBbHBoYVB0cigpIHsgcmV0dXJuIGFscGhhOyB9CiAgc3RkOjp2ZWN0b3I8R2Z4U2VwYXJhdGlvbkNvbG9yU3BhY2UqPiAqZ2V0U2VwYXJhdGlvbkxpc3QoKSB7IHJldHVybiBzZXBhcmF0aW9uTGlzdDsgfQoKICBTcGxhc2hFcnJvciB3cml0ZVBOTUZpbGUoY2hhciAqZmlsZU5hbWUpOwogIFNwbGFzaEVycm9yIHdyaXRlUE5NRmlsZShGSUxFICpmKTsKICBTcGxhc2hFcnJvciB3cml0ZUFscGhhUEdNRmlsZShjaGFyICpmaWxlTmFtZSk7CgogIHN0cnVjdCBXcml0ZUltZ1BhcmFtcwogIHsKICAgIGludCBqcGVnUXVhbGl0eSA9IC0xOwogICAgYm9vbCBqcGVnUHJvZ3Jlc3NpdmUgPSBmYWxzZTsKICAgIEdvb1N0cmluZyB0aWZmQ29tcHJlc3Npb247CiAgICBib29sIGpwZWdPcHRpbWl6ZSA9IGZhbHNlOwogIH07CgogIFNwbGFzaEVycm9yIHdyaXRlSW1nRmlsZShTcGxhc2hJbWFnZUZpbGVGb3JtYXQgZm9ybWF0LCBjb25zdCBjaGFyICpmaWxlTmFtZSwgaW50IGhEUEksIGludCB2RFBJLCBXcml0ZUltZ1BhcmFtcyogcGFyYW1zID0gbnVsbHB0cik7CiAgU3BsYXNoRXJyb3Igd3JpdGVJbWdGaWxlKFNwbGFzaEltYWdlRmlsZUZvcm1hdCBmb3JtYXQsIEZJTEUgKmYsIGludCBoRFBJLCBpbnQgdkRQSSwgV3JpdGVJbWdQYXJhbXMqIHBhcmFtcyA9IG51bGxwdHIpOwogIFNwbGFzaEVycm9yIHdyaXRlSW1nRmlsZShJbWdXcml0ZXIgKndyaXRlciwgRklMRSAqZiwgaW50IGhEUEksIGludCB2RFBJLCBTcGxhc2hDb2xvck1vZGUgaW1hZ2VXcml0ZXJGb3JtYXQpOwoKICBlbnVtIENvbnZlcnNpb25Nb2RlCiAgewogICAgICBjb252ZXJzaW9uT3BhcXVlLAogICAgICBjb252ZXJzaW9uQWxwaGEsCiAgICAgIGNvbnZlcnNpb25BbHBoYVByZW11bHRpcGxpZWQKICB9OwoKICBib29sIGNvbnZlcnRUb1hCR1IoQ29udmVyc2lvbk1vZGUgY29udmVyc2lvbk1vZGUgPSBjb252ZXJzaW9uT3BhcXVlKTsKCiAgdm9pZCBnZXRQaXhlbChpbnQgeCwgaW50IHksIFNwbGFzaENvbG9yUHRyIHBpeGVsKTsKICB2b2lkIGdldFJHQkxpbmUoaW50IHksIFNwbGFzaENvbG9yUHRyIGxpbmUpOwogIHZvaWQgZ2V0WEJHUkxpbmUoaW50IHksIFNwbGFzaENvbG9yUHRyIGxpbmUsIENvbnZlcnNpb25Nb2RlIGNvbnZlcnNpb25Nb2RlID0gY29udmVyc2lvbk9wYXF1ZSk7CiNpZmRlZiBTUExBU0hfQ01ZSwogIHZvaWQgZ2V0Q01ZS0xpbmUoaW50IHksIFNwbGFzaENvbG9yUHRyIGxpbmUpOwojZW5kaWYKICB1bnNpZ25lZCBjaGFyIGdldEFscGhhKGludCB4LCBpbnQgeSk7CgogIC8vIENhbGxlciB0YWtlcyBvd25lcnNoaXAgb2YgdGhlIGJpdG1hcCBkYXRhLiAgVGhlIFNwbGFzaEJpdG1hcAogIC8vIG9iamVjdCBpcyBubyBsb25nZXIgdmFsaWQgLS0gdGhlIG5leHQgY2FsbCBzaG91bGQgYmUgdG8gdGhlCiAgLy8gZGVzdHJ1Y3Rvci4KICBTcGxhc2hDb2xvclB0ciB0YWtlRGF0YSgpOwoKcHJpdmF0ZToKCiAgaW50IHdpZHRoLCBoZWlnaHQ7CQkvLyBzaXplIG9mIGJpdG1hcAogIGludCByb3dQYWQ7CiAgaW50IHJvd1NpemU7CQkJLy8gc2l6ZSBvZiBvbmUgcm93IG9mIGRhdGEsIGluIGJ5dGVzCgkJCQkvLyAgIC0gbmVnYXRpdmUgZm9yIGJvdHRvbS11cCBiaXRtYXBzCiAgU3BsYXNoQ29sb3JNb2RlIG1vZGU7CQkvLyBjb2xvciBtb2RlCiAgU3BsYXNoQ29sb3JQdHIgZGF0YTsJCS8vIHBvaW50ZXIgdG8gcm93IHplcm8gb2YgdGhlIGNvbG9yIGRhdGEKICB1bnNpZ25lZCBjaGFyICphbHBoYTsJCS8vIHBvaW50ZXIgdG8gcm93IHplcm8gb2YgdGhlIGFscGhhIGRhdGEKCQkJCS8vICAgKGFsd2F5cyB0b3AtZG93bikKICBzdGQ6OnZlY3RvcjxHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSo+ICpzZXBhcmF0aW9uTGlzdDsgLy8gbGlzdCBvZiBzcG90IGNvbG9yYW50cyBhbmQgdGhlaXIgbWFwcGluZyBmdW5jdGlvbnMKCiAgZnJpZW5kIGNsYXNzIFNwbGFzaDsKCiAgdm9pZCBzZXRKcGVnUGFyYW1zKEltZ1dyaXRlciAqd3JpdGVyLCBXcml0ZUltZ1BhcmFtcyogcGFyYW1zKTsKfTsKCiNlbmRpZgo=