Ly8gLSotIEMrKyAtKi0KLy89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdGhyZWFkIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KLy8KLy8gysrKysrKysrKysrKysrKysrKyspUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQovLwovLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgovLwovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwoKI2lmbmRlZiBfTElCQ1BQX1RIUkVBRAojZGVmaW5lIF9MSUJDUFBfVEhSRUFECgovKgoKICAgIHRocmVhZCBzeW5vcHNpcwoKI2RlZmluZSBfX1NURENQUF9USFJFQURTIF9fY3BsdXNwbHVzCgpuYW1lc3BhY2Ugc3RkCnsKCmNsYXNzIHRocmVhZAp7CnB1YmxpYzoKICAgIGNsYXNzIGlkOwogICAgdHlwZWRlZiBwdGhyZWFkX3QgbmF0aXZlX2hhbmRsZV90eXBlOwoKICAgIHRocmVhZCgpOwogICAgdGVtcGxhdGUgPGNsYXNzIEYsIGNsYXNzIC4uLkFyZ3M+IGV4cGxpY2l0IHRocmVhZChGJiYgZiwgQXJncyYmLi4uIGFyZ3MpOwogICAgfnRocmVhZCgpOwoKICAgIHRocmVhZChjb25zdCB0aHJlYWQmKSA9IGRlbGV0ZTsKICAgIHRocmVhZCh0aHJlYWQmJiB0KTsKCiAgICB0aHJlYWQmIG9wZXJhdG9yPShjb25zdCB0aHJlYWQmKSA9IGRlbGV0ZTsKICAgIHRocmVhZCYgb3BlcmF0b3I9KHRocmVhZCYmIHQpOwoKICAgIHZvaWQgc3dhcCh0aHJlYWQmIHQpOwoKICAgIGJvb2wgam9pbmFibGUoKSBjb25zdDsKICAgIHZvaWQgam9pbigpOwogICAgdm9pZCBkZXRhY2goKTsKICAgIGlkIGdldF9pZCgpIGNvbnN0OwogICAgbmF0aXZlX2hhbmRsZV90eXBlIG5hdGl2ZV9oYW5kbGUoKTsKCiAgICBzdGF0aWMgdW5zaWduZWQgaGFyZHdhcmVfY29uY3VycmVuY3koKTsKfTsKCnZvaWQgc3dhcCh0aHJlYWQmIHgsIHRocmVhZCYgeSk7CgpjbGFzcyB0aHJlYWQ6OmlkCnsKcHVibGljOgogICAgaWQoKTsKfTsKCmJvb2wgb3BlcmF0b3I9PSh0aHJlYWQ6OmlkIHgsIHRocmVhZDo6aWQgeSk7CmJvb2wgb3BlcmF0b3IhPSh0aHJlYWQ6OmlkIHgsIHRocmVhZDo6aWQgeSk7CmJvb2wgb3BlcmF0b3I8ICh0aHJlYWQ6OmlkIHgsIHRocmVhZDo6aWQgeSk7CmJvb2wgb3BlcmF0b3I8PSh0aHJlYWQ6OmlkIHgsIHRocmVhZDo6aWQgeSk7CmJvb2wgb3BlcmF0b3I+ICh0aHJlYWQ6OmlkIHgsIHRocmVhZDo6aWQgeSk7CmJvb2wgb3BlcmF0b3I+PSh0aHJlYWQ6OmlkIHgsIHRocmVhZDo6aWQgeSk7Cgp0ZW1wbGF0ZTxjbGFzcyBjaGFyVCwgY2xhc3MgdHJhaXRzPgpiYXNpY19vc3RyZWFtPGNoYXJULCB0cmFpdHM+JgpvcGVyYXRvcjw8KGJhc2ljX29zdHJlYW08Y2hhclQsIHRyYWl0cz4mIG91dCwgdGhyZWFkOjppZCBpZCk7CgpuYW1lc3BhY2UgdGhpc190aHJlYWQKewoKdGhyZWFkOjppZCBnZXRfaWQoKTsKCnZvaWQgeWllbGQoKTsKCnRlbXBsYXRlIDxjbGFzcyBDbG9jaywgY2xhc3MgRHVyYXRpb24+CnZvaWQgc2xlZXBfdW50aWwoY29uc3QgY2hyb25vOjp0aW1lX3BvaW50PENsb2NrLCBEdXJhdGlvbj4mIGFic190aW1lKTsKCnRlbXBsYXRlIDxjbGFzcyBSZXAsIGNsYXNzIFBlcmlvZD4Kdm9pZCBzbGVlcF9mb3IoY29uc3QgY2hyb25vOjpkdXJhdGlvbjxSZXAsIFBlcmlvZD4mIHJlbF90aW1lKTsKCn0gIC8vIHRoaXNfdGhyZWFkCgp9ICAvLyBzdGQKCiovCgojaW5jbHVkZSA8X19jb25maWc+CiNpbmNsdWRlIDxpb3Nmd2Q+CiNpbmNsdWRlIDxfX2Z1bmN0aW9uYWxfYmFzZT4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8Y3N0ZGRlZj4KI2luY2x1ZGUgPGZ1bmN0aW9uYWw+CiNpbmNsdWRlIDxtZW1vcnk+CiNpbmNsdWRlIDxzeXN0ZW1fZXJyb3I+CiNpbmNsdWRlIDxjaHJvbm8+CiNpbmNsdWRlIDxfX211dGV4X2Jhc2U+CiNpbmNsdWRlIDxwdGhyZWFkLmg+CgojcHJhZ21hIEdDQyBzeXN0ZW1faGVhZGVyCgojZGVmaW5lIF9fU1REQ1BQX1RIUkVBRFMgX19jcGx1c3BsdXMKCl9MSUJDUFBfQkVHSU5fTkFNRVNQQUNFX1NURAoKY2xhc3MgdGhyZWFkOwpjbGFzcyBfX3RocmVhZF9pZDsKCm5hbWVzcGFjZSB0aGlzX3RocmVhZAp7CgpfX3RocmVhZF9pZCBnZXRfaWQoKTsKCn0gIC8vIHRoaXNfdGhyZWFkCgpjbGFzcyBfX3RocmVhZF9pZAp7CiAgICBwdGhyZWFkX3QgX19pZF87CgpwdWJsaWM6CiAgICBfX3RocmVhZF9pZCgpIDogX19pZF8oMCkge30KCiAgICBmcmllbmQgYm9vbCBvcGVyYXRvcj09KF9fdGhyZWFkX2lkIF9feCwgX190aHJlYWRfaWQgX195KQogICAgICAgIHtyZXR1cm4gX194Ll9faWRfID09IF9feS5fX2lkXzt9CiAgICBmcmllbmQgYm9vbCBvcGVyYXRvciE9KF9fdGhyZWFkX2lkIF9feCwgX190aHJlYWRfaWQgX195KQogICAgICAgIHtyZXR1cm4gIShfX3ggPT0gX195KTt9CiAgICBmcmllbmQgYm9vbCBvcGVyYXRvcjwgKF9fdGhyZWFkX2lkIF9feCwgX190aHJlYWRfaWQgX195KQogICAgICAgIHtyZXR1cm4gX194Ll9faWRfIDwgX195Ll9faWRfO30KICAgIGZyaWVuZCBib29sIG9wZXJhdG9yPD0oX190aHJlYWRfaWQgX194LCBfX3RocmVhZF9pZCBfX3kpCiAgICAgICAge3JldHVybiAhKF9feSA8IF9feCk7fQogICAgZnJpZW5kIGJvb2wgb3BlcmF0b3I+IChfX3RocmVhZF9pZCBfX3gsIF9fdGhyZWFkX2lkIF9feSkKICAgICAgICB7cmV0dXJuICAgX195IDwgX194IDt9CiAgICBmcmllbmQgYm9vbCBvcGVyYXRvcj49KF9fdGhyZWFkX2lkIF9feCwgX190aHJlYWRfaWQgX195KQogICAgICAgIHtyZXR1cm4gIShfX3ggPCBfX3kpO30KCiAgICB0ZW1wbGF0ZTxjbGFzcyBfQ2hhclQsIGNsYXNzIF9UcmFpdHM+CiAgICBmcmllbmQKICAgIGJhc2ljX29zdHJlYW08X0NoYXJULCBfVHJhaXRzPiYKICAgIG9wZXJhdG9yPDwoYmFzaWNfb3N0cmVhbTxfQ2hhclQsIF9UcmFpdHM+JiBfX29zLCBfX3RocmVhZF9pZCBfX2lkKQogICAgICAgIHtyZXR1cm4gX19vcyA8PCBfX2lkLl9faWRfO30KCnByaXZhdGU6CiAgICBfX3RocmVhZF9pZChwdGhyZWFkX3QgX19pZCkgOiBfX2lkXyhfX2lkKSB7fQoKICAgIGZyaWVuZCBfX3RocmVhZF9pZCB0aGlzX3RocmVhZDo6Z2V0X2lkKCk7CiAgICBmcmllbmQgY2xhc3MgdGhyZWFkOwp9OwoKdGVtcGxhdGU8Y2xhc3MgX1RwPiBzdHJ1Y3QgaGFzaDsKCnRlbXBsYXRlPD4Kc3RydWN0IGhhc2g8X190aHJlYWRfaWQ+CiAgICA6IHB1YmxpYyB1bmFyeV9mdW5jdGlvbjxfX3RocmVhZF9pZCwgc2l6ZV90Pgp7CiAgICBzaXplX3Qgb3BlcmF0b3IoKShfX3RocmVhZF9pZCBfX3YpIGNvbnN0CiAgICB7CiAgICAgICAgY29uc3Qgc2l6ZV90KiBjb25zdCBfX3AgPSByZWludGVycHJldF9jYXN0PGNvbnN0IHNpemVfdCo+KCZfX3YpOwogICAgICAgIHJldHVybiAqX19wOwogICAgfQp9OwoKbmFtZXNwYWNlIHRoaXNfdGhyZWFkCnsKCmlubGluZQpfX3RocmVhZF9pZApnZXRfaWQoKQp7CiAgICByZXR1cm4gcHRocmVhZF9zZWxmKCk7Cn0KCn0gIC8vIHRoaXNfdGhyZWFkCgpjbGFzcyB0aHJlYWQKewogICAgcHRocmVhZF90IF9fdF87CgojaWZuZGVmIF9MSUJDUFBfTU9WRQogICAgdGhyZWFkKGNvbnN0IHRocmVhZCYpOyAvLyA9IGRlbGV0ZTsKICAgIHRocmVhZCYgb3BlcmF0b3I9KGNvbnN0IHRocmVhZCYpOyAvLyA9IGRlbGV0ZTsKI2VuZGlmCnB1YmxpYzoKICAgIHR5cGVkZWYgX190aHJlYWRfaWQgaWQ7CiAgICB0eXBlZGVmIHB0aHJlYWRfdCBuYXRpdmVfaGFuZGxlX3R5cGU7CgogICAgdGhyZWFkKCkgOiBfX3RfKDApIHt9CiNpZm5kZWYgX0xJQkNQUF9IQVNfTk9fVkFSSUFESUNTCiAgICB0ZW1wbGF0ZSA8Y2xhc3MgX0YsIGNsYXNzIC4uLl9BcmdzLAogICAgICAgICAgICAgIGNsYXNzID0gdHlwZW5hbWUgZW5hYmxlX2lmCiAgICAgICAgICAgICAgPAogICAgICAgICAgICAgICAgICAgIWlzX3NhbWU8dHlwZW5hbWUgZGVjYXk8X0Y+Ojp0eXBlLCB0aHJlYWQ+Ojp2YWx1ZQogICAgICAgICAgICAgID46OnR5cGUKICAgICAgICAgICAgID4KICAgICAgICBleHBsaWNpdCB0aHJlYWQoX0YmJiBfX2YsIF9BcmdzJiYuLi4gX19hcmdzKTsKI2Vsc2UKICAgIHRlbXBsYXRlIDxjbGFzcyBfRj4gZXhwbGljaXQgdGhyZWFkKF9GIF9fZik7CiNlbmRpZgogICAgfnRocmVhZCgpOwoKI2lmZGVmIF9MSUJDUFBfTU9WRQogICAgdGhyZWFkKGNvbnN0IHRocmVhZCYpID0gZGVsZXRlOwogICAgdGhyZWFkKHRocmVhZCYmIF9fdCkgOiBfX3RfKF9fdC5fX3RfKSB7X190Ll9fdF8gPSAwO30KICAgIHRocmVhZCYgb3BlcmF0b3I9KGNvbnN0IHRocmVhZCYpID0gZGVsZXRlOwogICAgdGhyZWFkJiBvcGVyYXRvcj0odGhyZWFkJiYgX190KTsKI2VuZGlmCgogICAgdm9pZCBzd2FwKHRocmVhZCYgX190KSB7X1NURDo6c3dhcChfX3RfLCBfX3QuX190Xyk7fQoKICAgIGJvb2wgam9pbmFibGUoKSBjb25zdCB7cmV0dXJuIF9fdF8gIT0gbnVsbHB0cjt9CiAgICB2b2lkIGpvaW4oKTsKICAgIHZvaWQgZGV0YWNoKCk7CiAgICBpZCBnZXRfaWQoKSBjb25zdCB7cmV0dXJuIF9fdF87fQogICAgbmF0aXZlX2hhbmRsZV90eXBlIG5hdGl2ZV9oYW5kbGUoKSB7cmV0dXJuIF9fdF87fQoKICAgIHN0YXRpYyB1bnNpZ25lZCBoYXJkd2FyZV9jb25jdXJyZW5jeSgpOwp9OwoKdGVtcGxhdGUgPGNsYXNzIF9GPgp2b2lkKgpfX3RocmVhZF9wcm94eSh2b2lkKiBfX3ZwKQp7CiAgICBzdGQ6OnVuaXF1ZV9wdHI8X0Y+IF9fcChzdGF0aWNfY2FzdDxfRio+KF9fdnApKTsKICAgICgqX19wKSgpOwogICAgcmV0dXJuIG51bGxwdHI7Cn0KCiNpZm5kZWYgX0xJQkNQUF9IQVNfTk9fVkFSSUFESUNTCgp0ZW1wbGF0ZSA8Y2xhc3MgX0YsIGNsYXNzIC4uLl9BcmdzLAogICAgICAgICAgY2xhc3MKICAgICAgICAgPgp0aHJlYWQ6OnRocmVhZChfRiYmIF9fZiwgX0FyZ3MmJi4uLiBfX2FyZ3MpCnsKICAgIHR5cGVkZWYgZGVjbHR5cGUoYmluZChzdGQ6OmZvcndhcmQ8X0Y+KF9fZiksIHN0ZDo6Zm9yd2FyZDxfQXJncz4oX19hcmdzKS4uLikpIF9HOwogICAgc3RkOjp1bmlxdWVfcHRyPF9HPiBfX3AobmV3IF9HKGJpbmQoc3RkOjpmb3J3YXJkPF9GPihfX2YpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGQ6OmZvcndhcmQ8X0FyZ3M+KF9fYXJncykuLi4pKSk7CiAgICBpbnQgX19lYyA9IHB0aHJlYWRfY3JlYXRlKCZfX3RfLCAwLCAmX190aHJlYWRfcHJveHk8X0c+LCBfX3AuZ2V0KCkpOwogICAgaWYgKF9fZWMgPT0gMCkKICAgICAgICBfX3AucmVsZWFzZSgpOwogICAgZWxzZQogICAgICAgIF9fdGhyb3dfc3lzdGVtX2Vycm9yKF9fZWMsICJ0aHJlYWQgY29uc3RydWN0b3IgZmFpbGVkIik7Cn0KCiNlbHNlCgp0ZW1wbGF0ZSA8Y2xhc3MgX0Y+CnRocmVhZDo6dGhyZWFkKF9GIF9fZikKewogICAgc3RkOjp1bmlxdWVfcHRyPF9GPiBfX3AobmV3IF9GKF9fZikpOwogICAgaW50IF9fZWMgPSBwdGhyZWFkX2NyZWF0ZSgmX190XywgMCwgJl9fdGhyZWFkX3Byb3h5PF9GPiwgX19wLmdldCgpKTsKICAgIGlmIChfX2VjID09IDApCiAgICAgICAgX19wLnJlbGVhc2UoKTsKICAgIGVsc2UKICAgICAgICBfX3Rocm93X3N5c3RlbV9lcnJvcihfX2VjLCAidGhyZWFkIGNvbnN0cnVjdG9yIGZhaWxlZCIpOwp9CgojZW5kaWYKCiNpZmRlZiBfTElCQ1BQX01PVkUKCmlubGluZQp0aHJlYWQmCnRocmVhZDo6b3BlcmF0b3I9KHRocmVhZCYmIF9fdCkKewogICAgaWYgKF9fdF8gIT0gbnVsbHB0cikKICAgICAgICB0ZXJtaW5hdGUoKTsKICAgIF9fdF8gPSBfX3QuX190XzsKICAgIF9fdC5fX3RfID0gbnVsbHB0cjsKICAgIHJldHVybiAqdGhpczsKfQoKI2VuZGlmCgppbmxpbmUKdm9pZCBzd2FwKHRocmVhZCYgX194LCB0aHJlYWQmIF9feSkge19feC5zd2FwKF9feSk7fQoKCm5hbWVzcGFjZSB0aGlzX3RocmVhZAp7Cgp2b2lkIHNsZWVwX2Zvcihjb25zdCBjaHJvbm86Om5hbm9zZWNvbmRzJiBucyk7Cgp0ZW1wbGF0ZSA8Y2xhc3MgX1JlcCwgY2xhc3MgX1BlcmlvZD4Kdm9pZApzbGVlcF9mb3IoY29uc3QgY2hyb25vOjpkdXJhdGlvbjxfUmVwLCBfUGVyaW9kPiYgX19kKQp7CiAgICB1c2luZyBuYW1lc3BhY2UgY2hyb25vOwogICAgbmFub3NlY29uZHMgX19ucyA9IGR1cmF0aW9uX2Nhc3Q8bmFub3NlY29uZHM+KF9fZCk7CiAgICBpZiAoX19ucyA8IF9fZCkKICAgICAgICArK19fbnM7CiAgICBzbGVlcF9mb3IoX19ucyk7Cn0KCnRlbXBsYXRlIDxjbGFzcyBfQ2xvY2ssIGNsYXNzIF9EdXJhdGlvbj4Kdm9pZApzbGVlcF91bnRpbChjb25zdCBjaHJvbm86OnRpbWVfcG9pbnQ8X0Nsb2NrLCBfRHVyYXRpb24+JiBfX3QpCnsKICAgIHVzaW5nIG5hbWVzcGFjZSBjaHJvbm87CiAgICBtdXRleCBfX211dDsKICAgIGNvbmRpdGlvbl92YXJpYWJsZSBfX2N2OwogICAgdW5pcXVlX2xvY2s8bXV0ZXg+IF9fbGsoX19tdXQpOwogICAgd2hpbGUgKF9DbG9jazo6bm93KCkgPCBfX3QpCiAgICAgICAgX19jdi53YWl0X3VudGlsKF9fbGssIF9fdCk7Cn0KCnRlbXBsYXRlIDxjbGFzcyBfRHVyYXRpb24+CmlubGluZQp2b2lkCnNsZWVwX3VudGlsKGNvbnN0IGNocm9ubzo6dGltZV9wb2ludDxjaHJvbm86Om1vbm90b25pY19jbG9jaywgX0R1cmF0aW9uPiYgX190KQp7CiAgICB1c2luZyBuYW1lc3BhY2UgY2hyb25vOwogICAgc2xlZXBfZm9yKF9fdCAtIG1vbm90b25pY19jbG9jazo6bm93KCkpOwp9CgppbmxpbmUKdm9pZCB5aWVsZCgpIHtzY2hlZF95aWVsZCgpO30KCn0gIC8vIHRoaXNfdGhyZWFkCgpfTElCQ1BQX0VORF9OQU1FU1BBQ0VfU1RECgojZW5kaWYgIC8vIF9MSUJDUFBfVEhSRUFECg==