Ly89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLy8KLy8gU3BsYXNoQml0bWFwLmgKLy8KLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vCi8vIE1vZGlmaWVkIHVuZGVyIHRoZSBQb3BwbGVyIHByb2plY3QgLSBodHRwOi8vcG9wcGxlci5mcmVlZGVza3RvcC5vcmcKLy8KLy8gQWxsIGNoYW5nZXMgbWFkZSB1bmRlciB0aGUgUG9wcGxlciBwcm9qZWN0IHRvIHRoaXMgZmlsZSBhcmUgbGljZW5zZWQKLy8gdW5kZXIgR1BMIHZlcnNpb24gMiBvciBsYXRlcgovLwovLyBDb3B5cmlnaHQgKEMpIDIwMDcgSWxtYXJpIEhlaWtraW5lbiA8aWxtYXJpLmhlaWtraW5lbkBnbWFpbC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAwOSBTaGVuIExpYW5nIDxzaGVuemh1eGlAZ21haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMDksIDIwMTIgQWxiZXJ0IEFzdGFscyBDaWQgPGFhY2lkQGtkZS5vcmc+Ci8vIENvcHlyaWdodCAoQykgMjAwOSBTdGVmYW4gVGhvbWFzIDx0aG9tYXNAZWxvYWQyNC5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMCBBZHJpYW4gSm9obnNvbiA8YWpvaG5zb25AcmVkbmVvbi5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxMCBIYXJyeSBSb2JlcnRzIDxoYXJyeS5yb2JlcnRzQG1pZG5pZ2h0LWxhYnMub3JnPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgQ2hyaXN0aWFuIEZldWVyc+RuZ2VyIDxjZmV1ZXJzYWVuZ2VyQGdvb2dsZW1haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTAgV2lsbGlhbSBCYWRlciA8d2lsbGlhbWJhZGVyQGhvdG1haWwuY29tPgovLyBDb3B5cmlnaHQgKEMpIDIwMTIgVGhvbWFzIEZyZWl0YWcgPFRob21hcy5GcmVpdGFnQGFsZmEuZGU+Ci8vIENvcHlyaWdodCAoQykgMjAxNSBBZGFtIFJlaWNob2xkIDxhZGFtcmVpY2hvbGRAbXlvcGVyYS5jb20+Ci8vIENvcHlyaWdodCAoQykgMjAxNiBLZW5qaSBVbm8gPGt1QGRpZ2l0YWxkb2xwaGlucy5qcD4KLy8KLy8gVG8gc2VlIGEgZGVzY3JpcHRpb24gb2YgdGhlIGNoYW5nZXMgcGxlYXNlIHNlZSB0aGUgQ2hhbmdlbG9nIGZpbGUgdGhhdAovLyBjYW1lIHdpdGggeW91ciB0YXJiYWxsIG9yIHR5cGUgbWFrZSBDaGFuZ2VMb2cgaWYgeW91IGFyZSBidWlsZGluZyBmcm9tIGdpdAovLwovLz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2lmbmRlZiBTUExBU0hCSVRNQVBfSAojZGVmaW5lIFNQTEFTSEJJVE1BUF9ICgojaWZkZWYgVVNFX0dDQ19QUkFHTUFTCiNwcmFnbWEgaW50ZXJmYWNlCiNlbmRpZgoKI2luY2x1ZGUgIlNwbGFzaFR5cGVzLmgiCiNpbmNsdWRlICJwb3BwbGVyL0dmeFN0YXRlLmgiCiNpbmNsdWRlIDxzdGRpby5oPgoKY2xhc3MgSW1nV3JpdGVyOwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gU3BsYXNoQml0bWFwCi8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpjbGFzcyBTcGxhc2hCaXRtYXAgewpwdWJsaWM6CgogIC8vIENyZWF0ZSBhIG5ldyBiaXRtYXAuICBJdCB3aWxsIGhhdmUgPHdpZHRoQT4geCA8aGVpZ2h0QT4gcGl4ZWxzIGluCiAgLy8gY29sb3IgbW9kZSA8bW9kZUE+LiAgUm93cyB3aWxsIGJlIHBhZGRlZCBvdXQgdG8gYSBtdWx0aXBsZSBvZgogIC8vIDxyb3dQYWQ+IGJ5dGVzLiAgSWYgPHRvcERvd24+IGlzIGZhbHNlLCB0aGUgYml0bWFwIHdpbGwgYmUgc3RvcmVkCiAgLy8gdXBzaWRlLWRvd24sIGkuZS4sIHdpdGggdGhlIGxhc3Qgcm93IGZpcnN0IGluIG1lbW9yeS4KICBTcGxhc2hCaXRtYXAoaW50IHdpZHRoQSwgaW50IGhlaWdodEEsIGludCByb3dQYWQsCgkgICAgICAgU3BsYXNoQ29sb3JNb2RlIG1vZGVBLCBHQm9vbCBhbHBoYUEsCgkgICAgICAgR0Jvb2wgdG9wRG93biA9IGdUcnVlLCBHb29MaXN0ICpzZXBhcmF0aW9uTGlzdCA9IE5VTEwpOwogIHN0YXRpYyBTcGxhc2hCaXRtYXAgKmNvcHkoU3BsYXNoQml0bWFwICpzcmMpOwoKICB+U3BsYXNoQml0bWFwKCk7CgogIGludCBnZXRXaWR0aCgpIHsgcmV0dXJuIHdpZHRoOyB9CiAgaW50IGdldEhlaWdodCgpIHsgcmV0dXJuIGhlaWdodDsgfQogIGludCBnZXRSb3dTaXplKCkgeyByZXR1cm4gcm93U2l6ZTsgfQogIGludCBnZXRBbHBoYVJvd1NpemUoKSB7IHJldHVybiB3aWR0aDsgfQogIGludCBnZXRSb3dQYWQoKSB7IHJldHVybiByb3dQYWQ7IH0KICBTcGxhc2hDb2xvck1vZGUgZ2V0TW9kZSgpIHsgcmV0dXJuIG1vZGU7IH0KICBTcGxhc2hDb2xvclB0ciBnZXREYXRhUHRyKCkgeyByZXR1cm4gZGF0YTsgfQogIEd1Y2hhciAqZ2V0QWxwaGFQdHIoKSB7IHJldHVybiBhbHBoYTsgfQogIEdvb0xpc3QgKmdldFNlcGFyYXRpb25MaXN0KCkgeyByZXR1cm4gc2VwYXJhdGlvbkxpc3Q7IH0KCiAgU3BsYXNoRXJyb3Igd3JpdGVQTk1GaWxlKGNoYXIgKmZpbGVOYW1lKTsKICBTcGxhc2hFcnJvciB3cml0ZVBOTUZpbGUoRklMRSAqZik7CiAgU3BsYXNoRXJyb3Igd3JpdGVBbHBoYVBHTUZpbGUoY2hhciAqZmlsZU5hbWUpOwogIAogIFNwbGFzaEVycm9yIHdyaXRlSW1nRmlsZShTcGxhc2hJbWFnZUZpbGVGb3JtYXQgZm9ybWF0LCBjaGFyICpmaWxlTmFtZSwgaW50IGhEUEksIGludCB2RFBJLCBjb25zdCBjaGFyICpjb21wcmVzc2lvblN0cmluZyA9ICIiKTsKICBTcGxhc2hFcnJvciB3cml0ZUltZ0ZpbGUoU3BsYXNoSW1hZ2VGaWxlRm9ybWF0IGZvcm1hdCwgRklMRSAqZiwgaW50IGhEUEksIGludCB2RFBJLCBjb25zdCBjaGFyICpjb21wcmVzc2lvblN0cmluZyA9ICIiKTsKICBTcGxhc2hFcnJvciB3cml0ZUltZ0ZpbGUoSW1nV3JpdGVyICp3cml0ZXIsIEZJTEUgKmYsIGludCBoRFBJLCBpbnQgdkRQSSwgU3BsYXNoQ29sb3JNb2RlIGltYWdlV3JpdGVyRm9ybWF0KTsKCiAgZW51bSBDb252ZXJzaW9uTW9kZQogIHsKICAgICAgY29udmVyc2lvbk9wYXF1ZSwKICAgICAgY29udmVyc2lvbkFscGhhLAogICAgICBjb252ZXJzaW9uQWxwaGFQcmVtdWx0aXBsaWVkCiAgfTsKCiAgR0Jvb2wgY29udmVydFRvWEJHUihDb252ZXJzaW9uTW9kZSBjb252ZXJzaW9uTW9kZSA9IGNvbnZlcnNpb25PcGFxdWUpOwoKICB2b2lkIGdldFBpeGVsKGludCB4LCBpbnQgeSwgU3BsYXNoQ29sb3JQdHIgcGl4ZWwpOwogIHZvaWQgZ2V0UkdCTGluZShpbnQgeSwgU3BsYXNoQ29sb3JQdHIgbGluZSk7CiAgdm9pZCBnZXRYQkdSTGluZShpbnQgeSwgU3BsYXNoQ29sb3JQdHIgbGluZSwgQ29udmVyc2lvbk1vZGUgY29udmVyc2lvbk1vZGUgPSBjb252ZXJzaW9uT3BhcXVlKTsKI2lmIFNQTEFTSF9DTVlLCiAgdm9pZCBnZXRDTVlLTGluZShpbnQgeSwgU3BsYXNoQ29sb3JQdHIgbGluZSk7CiNlbmRpZgogIEd1Y2hhciBnZXRBbHBoYShpbnQgeCwgaW50IHkpOwoKICAvLyBDYWxsZXIgdGFrZXMgb3duZXJzaGlwIG9mIHRoZSBiaXRtYXAgZGF0YS4gIFRoZSBTcGxhc2hCaXRtYXAKICAvLyBvYmplY3QgaXMgbm8gbG9uZ2VyIHZhbGlkIC0tIHRoZSBuZXh0IGNhbGwgc2hvdWxkIGJlIHRvIHRoZQogIC8vIGRlc3RydWN0b3IuCiAgU3BsYXNoQ29sb3JQdHIgdGFrZURhdGEoKTsKCnByaXZhdGU6CgogIGludCB3aWR0aCwgaGVpZ2h0OwkJLy8gc2l6ZSBvZiBiaXRtYXAKICBpbnQgcm93UGFkOwogIGludCByb3dTaXplOwkJCS8vIHNpemUgb2Ygb25lIHJvdyBvZiBkYXRhLCBpbiBieXRlcwoJCQkJLy8gICAtIG5lZ2F0aXZlIGZvciBib3R0b20tdXAgYml0bWFwcwogIFNwbGFzaENvbG9yTW9kZSBtb2RlOwkJLy8gY29sb3IgbW9kZQogIFNwbGFzaENvbG9yUHRyIGRhdGE7CQkvLyBwb2ludGVyIHRvIHJvdyB6ZXJvIG9mIHRoZSBjb2xvciBkYXRhCiAgR3VjaGFyICphbHBoYTsJCS8vIHBvaW50ZXIgdG8gcm93IHplcm8gb2YgdGhlIGFscGhhIGRhdGEKCQkJCS8vICAgKGFsd2F5cyB0b3AtZG93bikKICBHb29MaXN0ICpzZXBhcmF0aW9uTGlzdDsgLy8gbGlzdCBvZiBzcG90IGNvbG9yYW50cyBhbmQgdGhlaXIgbWFwcGluZyBmdW5jdGlvbnMKCiAgZnJpZW5kIGNsYXNzIFNwbGFzaDsKfTsKCiNlbmRpZgo=