Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoQml0bWFwLmgKLy8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vCi8vIE1vZGlmaWVkIHVuZGVyIHRoZSBQb3BwbGVyIHByb2plY3QgLSBodHRwOi8vcG9wcGxlci5mcmVlZGVza3RvcC5vcmcKLy8KLy8gQWxsIGNoYW5nZXMgbWFkZSB1bmRlciB0aGUgUG9wcGxlciBwcm9qZWN0IHRvIHRoaXMgZmlsZSBhcmUgbGljZW5zZWQKLy8gdW5kZXIgR1BMIHZlcnNpb24gMiBvciBsYXRlcgovLwovLyBDb3B5cmlnaHQgKEMpIDIwMDcgSWxtYXJpIEhlaWtraW5lbiA8aWxtYXJpLmhlaWtraW5lbkBnbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAwOSBTaGVuIExpYW5nIDxzaGVuemh1eGlAZ21haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMDksIDIwMTIsIDIwMTggQWxiZXJ0IEFzdGFscyBDaWQgPGFhY2lkQGtkZS5vcmc+Ci8vIENvcHlyaWdodCAoQykgMjAwOSBTdGVmYW4gVGhvbWFzIDx0aG9tYXNAZWxvYWQyNC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMCwgMjAxNyBBZHJpYW4gSm9obnNvbiA8YWpvaG5zb25AcmVkbmVvbi5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMCBIYXJyeSBSb2JlcnRzIDxoYXJyeS5yb2JlcnRzQG1pZG5pZ2h0LWxhYnMub3JnPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgQ2hyaXN0aWFuIEZldWVyc+RuZ2VyIDxjZmV1ZXJzYWVuZ2VyQGdvb2dsZW1haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgV2lsbGlhbSBCYWRlciA8d2lsbGlhbWJhZGVyQGhvdG1haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTIgVGhvbWFzIEZyZWl0YWcgPFRob21hcy5GcmVpdGFnQGFsZmEuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAxNSBBZGFtIFJlaWNob2xkIDxhZGFtcmVpY2hvbGRAbXlvcGVyYS5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxNiBLZW5qaSBVbm8gPGt1QGRpZ2l0YWxkb2xwaGlucy5qcD4KLy8gQ29weXJpZ2h0IChDKSAyMDE4IE1hcnRpbiBQYWNrbWFuIDxnemxpc3RAZ29vZ2xlbWFpbC5jb20+Ci8vCi8vIFRvIHNlZSBhIGRlc2NyaXB0aW9uIG9mIHRoZSBjaGFuZ2VzIHBsZWFzZSBzZWUgdGhlIENoYW5nZWxvZyBmaWxlIHRoYXQKLy8gY2FtZSB3aXRoIHlvdXIgdGFyYmFsbCBvciB0eXBlIG1ha2UgQ2hhbmdlTG9nIGlmIHlvdSBhcmUgYnVpbGRpbmcgZnJvbSBnaXQKLy8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpZm5kZWYgU1BMQVNIQklUTUFQX0gKI2RlZmluZSBTUExBU0hCSVRNQVBfSAoKI2luY2x1ZGUgIlNwbGFzaFR5cGVzLmgiCiNpbmNsdWRlICJwb3BwbGVyL0dmeFN0YXRlLmgiCiNpbmNsdWRlIDxzdGRpby5oPgoKY2xhc3MgSW1nV3JpdGVyOwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gU3BsYXNoQml0bWFwCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpjbGFzcyBTcGxhc2hCaXRtYXAgewpwdWJsaWM6CgogIC8vIENyZWF0ZSBhIG5ldyBiaXRtYXAuICBJdCB3aWxsIGhhdmUgPHdpZHRoQT4geCA8aGVpZ2h0QT4gcGl4ZWxzIGluCiAgLy8gY29sb3IgbW9kZSA8bW9kZUE+LiAgUm93cyB3aWxsIGJlIHBhZGRlZCBvdXQgdG8gYSBtdWx0aXBsZSBvZgogIC8vIDxyb3dQYWQ+IGJ5dGVzLiAgSWYgPHRvcERvd24+IGlzIGZhbHNlLCB0aGUgYml0bWFwIHdpbGwgYmUgc3RvcmVkCiAgLy8gdXBzaWRlLWRvd24sIGkuZS4sIHdpdGggdGhlIGxhc3Qgcm93IGZpcnN0IGluIG1lbW9yeS4KICBTcGxhc2hCaXRtYXAoaW50IHdpZHRoQSwgaW50IGhlaWdodEEsIGludCByb3dQYWQsCgkgICAgICAgU3BsYXNoQ29sb3JNb2RlIG1vZGVBLCBib29sIGFscGhhQSwKCSAgICAgICBib29sIHRvcERvd24gPSB0cnVlLCBHb29MaXN0PEdmeFNlcGFyYXRpb25Db2xvclNwYWNlKj4gKnNlcGFyYXRpb25MaXN0ID0gbnVsbHB0cik7CiAgc3RhdGljIFNwbGFzaEJpdG1hcCAqY29weShTcGxhc2hCaXRtYXAgKnNyYyk7CgogIH5TcGxhc2hCaXRtYXAoKTsKCiAgU3BsYXNoQml0bWFwKGNvbnN0IFNwbGFzaEJpdG1hcCAmKSA9IGRlbGV0ZTsKICBTcGxhc2hCaXRtYXAmIG9wZXJhdG9yPShjb25zdCBTcGxhc2hCaXRtYXAgJikgPSBkZWxldGU7CgogIGludCBnZXRXaWR0aCgpIHsgcmV0dXJuIHdpZHRoOyB9CiAgaW50IGdldEhlaWdodCgpIHsgcmV0dXJuIGhlaWdodDsgfQogIGludCBnZXRSb3dTaXplKCkgeyByZXR1cm4gcm93U2l6ZTsgfQogIGludCBnZXRBbHBoYVJvd1NpemUoKSB7IHJldHVybiB3aWR0aDsgfQogIGludCBnZXRSb3dQYWQoKSB7IHJldHVybiByb3dQYWQ7IH0KICBTcGxhc2hDb2xvck1vZGUgZ2V0TW9kZSgpIHsgcmV0dXJuIG1vZGU7IH0KICBTcGxhc2hDb2xvclB0ciBnZXREYXRhUHRyKCkgeyByZXR1cm4gZGF0YTsgfQogIHVuc2lnbmVkIGNoYXIgKmdldEFscGhhUHRyKCkgeyByZXR1cm4gYWxwaGE7IH0KICBHb29MaXN0PEdmeFNlcGFyYXRpb25Db2xvclNwYWNlKj4gKmdldFNlcGFyYXRpb25MaXN0KCkgeyByZXR1cm4gc2VwYXJhdGlvbkxpc3Q7IH0KCiAgU3BsYXNoRXJyb3Igd3JpdGVQTk1GaWxlKGNoYXIgKmZpbGVOYW1lKTsKICBTcGxhc2hFcnJvciB3cml0ZVBOTUZpbGUoRklMRSAqZik7CiAgU3BsYXNoRXJyb3Igd3JpdGVBbHBoYVBHTUZpbGUoY2hhciAqZmlsZU5hbWUpOwoKICBzdHJ1Y3QgV3JpdGVJbWdQYXJhbXMKICB7CiAgICBpbnQganBlZ1F1YWxpdHkgPSAtMTsKICAgIGJvb2wganBlZ1Byb2dyZXNzaXZlID0gZmFsc2U7CiAgICBHb29TdHJpbmcgdGlmZkNvbXByZXNzaW9uOwogICAgYm9vbCBqcGVnT3B0aW1pemUgPSBmYWxzZTsKICB9OwoKICBTcGxhc2hFcnJvciB3cml0ZUltZ0ZpbGUoU3BsYXNoSW1hZ2VGaWxlRm9ybWF0IGZvcm1hdCwgY29uc3QgY2hhciAqZmlsZU5hbWUsIGludCBoRFBJLCBpbnQgdkRQSSwgV3JpdGVJbWdQYXJhbXMqIHBhcmFtcyA9IG51bGxwdHIpOwogIFNwbGFzaEVycm9yIHdyaXRlSW1nRmlsZShTcGxhc2hJbWFnZUZpbGVGb3JtYXQgZm9ybWF0LCBGSUxFICpmLCBpbnQgaERQSSwgaW50IHZEUEksIFdyaXRlSW1nUGFyYW1zKiBwYXJhbXMgPSBudWxscHRyKTsKICBTcGxhc2hFcnJvciB3cml0ZUltZ0ZpbGUoSW1nV3JpdGVyICp3cml0ZXIsIEZJTEUgKmYsIGludCBoRFBJLCBpbnQgdkRQSSwgU3BsYXNoQ29sb3JNb2RlIGltYWdlV3JpdGVyRm9ybWF0KTsKCiAgZW51bSBDb252ZXJzaW9uTW9kZQogIHsKICAgICAgY29udmVyc2lvbk9wYXF1ZSwKICAgICAgY29udmVyc2lvbkFscGhhLAogICAgICBjb252ZXJzaW9uQWxwaGFQcmVtdWx0aXBsaWVkCiAgfTsKCiAgYm9vbCBjb252ZXJ0VG9YQkdSKENvbnZlcnNpb25Nb2RlIGNvbnZlcnNpb25Nb2RlID0gY29udmVyc2lvbk9wYXF1ZSk7CgogIHZvaWQgZ2V0UGl4ZWwoaW50IHgsIGludCB5LCBTcGxhc2hDb2xvclB0ciBwaXhlbCk7CiAgdm9pZCBnZXRSR0JMaW5lKGludCB5LCBTcGxhc2hDb2xvclB0ciBsaW5lKTsKICB2b2lkIGdldFhCR1JMaW5lKGludCB5LCBTcGxhc2hDb2xvclB0ciBsaW5lLCBDb252ZXJzaW9uTW9kZSBjb252ZXJzaW9uTW9kZSA9IGNvbnZlcnNpb25PcGFxdWUpOwojaWZkZWYgU1BMQVNIX0NNWUsKICB2b2lkIGdldENNWUtMaW5lKGludCB5LCBTcGxhc2hDb2xvclB0ciBsaW5lKTsKI2VuZGlmCiAgdW5zaWduZWQgY2hhciBnZXRBbHBoYShpbnQgeCwgaW50IHkpOwoKICAvLyBDYWxsZXIgdGFrZXMgb3duZXJzaGlwIG9mIHRoZSBiaXRtYXAgZGF0YS4gIFRoZSBTcGxhc2hCaXRtYXAKICAvLyBvYmplY3QgaXMgbm8gbG9uZ2VyIHZhbGlkIC0tIHRoZSBuZXh0IGNhbGwgc2hvdWxkIGJlIHRvIHRoZQogIC8vIGRlc3RydWN0b3IuCiAgU3BsYXNoQ29sb3JQdHIgdGFrZURhdGEoKTsKCnByaXZhdGU6CgogIGludCB3aWR0aCwgaGVpZ2h0OwkJLy8gc2l6ZSBvZiBiaXRtYXAKICBpbnQgcm93UGFkOwogIGludCByb3dTaXplOwkJCS8vIHNpemUgb2Ygb25lIHJvdyBvZiBkYXRhLCBpbiBieXRlcwoJCQkJLy8gICAtIG5lZ2F0aXZlIGZvciBib3R0b20tdXAgYml0bWFwcwogIFNwbGFzaENvbG9yTW9kZSBtb2RlOwkJLy8gY29sb3IgbW9kZQogIFNwbGFzaENvbG9yUHRyIGRhdGE7CQkvLyBwb2ludGVyIHRvIHJvdyB6ZXJvIG9mIHRoZSBjb2xvciBkYXRhCiAgdW5zaWduZWQgY2hhciAqYWxwaGE7CQkvLyBwb2ludGVyIHRvIHJvdyB6ZXJvIG9mIHRoZSBhbHBoYSBkYXRhCgkJCQkvLyAgIChhbHdheXMgdG9wLWRvd24pCiAgR29vTGlzdDxHZnhTZXBhcmF0aW9uQ29sb3JTcGFjZSo+ICpzZXBhcmF0aW9uTGlzdDsgLy8gbGlzdCBvZiBzcG90IGNvbG9yYW50cyBhbmQgdGhlaXIgbWFwcGluZyBmdW5jdGlvbnMKCiAgZnJpZW5kIGNsYXNzIFNwbGFzaDsKCiAgdm9pZCBzZXRKcGVnUGFyYW1zKEltZ1dyaXRlciAqd3JpdGVyLCBXcml0ZUltZ1BhcmFtcyogcGFyYW1zKTsKfTsKCiNlbmRpZgo=