Ly89PT0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gc3RkZXhjZXB0LmNwcCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tPT09Ly8KLy8KLy8gysrKysrKysrKysrKysrKysrKyspUaGUgTExWTSBDb21waWxlciBJbmZyYXN0cnVjdHVyZQovLwovLyBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIFVuaXZlcnNpdHkgb2YgSWxsaW5vaXMgT3BlbiBTb3VyY2UKLy8gTGljZW5zZS4gU2VlIExJQ0VOU0UuVFhUIGZvciBkZXRhaWxzLgovLwovLz09PS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS09PT0vLwoKI2luY2x1ZGUgInN0ZGV4Y2VwdCIKI2luY2x1ZGUgIm5ldyIKI2luY2x1ZGUgInN0cmluZyIKI2luY2x1ZGUgPGNzdGRsaWI+CiNpbmNsdWRlIDxjc3RyaW5nPgojaW5jbHVkZSA8Y3N0ZGludD4KI2luY2x1ZGUgPGNzdGRkZWY+CiNpbmNsdWRlICJzeXN0ZW1fZXJyb3IiCiNpbmNsdWRlIDxsaWJrZXJuL09TQXRvbWljLmg+CgovLyBOb3RlOiAgb3B0aW1pemUgZm9yIHNpemUKCiNwcmFnbWEgR0NDIHZpc2liaWxpdHkgcHVzaChoaWRkZW4pCgpuYW1lc3BhY2UKewoKY2xhc3MgX19saWJjcHBfbm1zdHIKewpwcml2YXRlOgogICAgY29uc3QgY2hhciogc3RyXzsKCiAgICB0eXBlZGVmIHN0ZDo6c2l6ZV90IHVudXNlZF90OwogICAgdHlwZWRlZiBzdGQ6OmludDMyX3QgY291bnRfdDsKCiAgICBzdGF0aWMgY29uc3Qgc3RkOjpwdHJkaWZmX3Qgb2Zmc2V0ID0gc3RhdGljX2Nhc3Q8c3RkOjpwdHJkaWZmX3Q+KDIqc2l6ZW9mKHVudXNlZF90KSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGNvdW50X3QpKTsKCiAgICBjb3VudF90JiBjb3VudCgpIGNvbnN0IHRocm93KCkge3JldHVybiAoY291bnRfdCYpKCooc3RyXyAtIHNpemVvZihjb3VudF90KSkpO30KcHVibGljOgogICAgZXhwbGljaXQgX19saWJjcHBfbm1zdHIoY29uc3QgY2hhciogbXNnKTsKICAgIF9fbGliY3BwX25tc3RyKGNvbnN0IF9fbGliY3BwX25tc3RyJiBzKSBfTElCQ1BQX0NBTlRUSFJPVzsKICAgIF9fbGliY3BwX25tc3RyJiBvcGVyYXRvcj0oY29uc3QgX19saWJjcHBfbm1zdHImIHMpIF9MSUJDUFBfQ0FOVFRIUk9XOwogICAgfl9fbGliY3BwX25tc3RyKCkgX0xJQkNQUF9DQU5UVEhST1c7CiAgICBjb25zdCBjaGFyKiBjX3N0cigpIGNvbnN0IHRocm93KCkge3JldHVybiBzdHJfO30KfTsKCl9fbGliY3BwX25tc3RyOjpfX2xpYmNwcF9ubXN0cihjb25zdCBjaGFyKiBtc2cpCnsKICAgIHN0ZDo6c2l6ZV90IGxlbiA9IHN0cmxlbihtc2cpOwogICAgc3RyXyA9IG5ldyBjaGFyW2xlbiArIDEgKyBvZmZzZXRdOwogICAgdW51c2VkX3QqIGMgPSAodW51c2VkX3QqKXN0cl87CiAgICBjWzBdID0gY1sxXSA9IGxlbjsKICAgIHN0cl8gKz0gb2Zmc2V0OwogICAgY291bnQoKSA9IDA7CiAgICBzdGQ6OnN0cmNweShjb25zdF9jYXN0PGNoYXIqPihjX3N0cigpKSwgbXNnKTsKfQoKaW5saW5lCl9fbGliY3BwX25tc3RyOjpfX2xpYmNwcF9ubXN0cihjb25zdCBfX2xpYmNwcF9ubXN0ciYgcykKICAgIDogc3RyXyhzLnN0cl8pCnsKICAgIE9TQXRvbWljSW5jcmVtZW50MzJCYXJyaWVyKCZjb3VudCgpKTsKfQoKX19saWJjcHBfbm1zdHImCl9fbGliY3BwX25tc3RyOjpvcGVyYXRvcj0oY29uc3QgX19saWJjcHBfbm1zdHImIHMpCnsKICAgIGNvbnN0IGNoYXIqIHAgPSBzdHJfOwogICAgc3RyXyA9IHMuc3RyXzsKICAgIE9TQXRvbWljSW5jcmVtZW50MzJCYXJyaWVyKCZjb3VudCgpKTsKICAgIGlmIChPU0F0b21pY0RlY3JlbWVudDMyKChjb3VudF90KikocC1zaXplb2YoY291bnRfdCkpKSA8IDApCiAgICAgICAgZGVsZXRlIFtdIChwLW9mZnNldCk7CiAgICByZXR1cm4gKnRoaXM7Cn0KCmlubGluZQpfX2xpYmNwcF9ubXN0cjo6fl9fbGliY3BwX25tc3RyKCkKewogICAgaWYgKE9TQXRvbWljRGVjcmVtZW50MzIoJmNvdW50KCkpIDwgMCkKICAgICAgICBkZWxldGUgW10gKHN0cl8gLSBvZmZzZXQpOwp9Cgp9CgojcHJhZ21hIEdDQyB2aXNpYmxpdHkgcG9wCgpuYW1lc3BhY2Ugc3RkICAvLyBwdXJwb3NlZnVsbHkgbm90IHVzaW5nIHZlcnNpb25pbmcgbmFtZXNwYWNlCnsKCmxvZ2ljX2Vycm9yOjpsb2dpY19lcnJvcihjb25zdCBzdHJpbmcmIG1zZykKewogICAgX19saWJjcHBfbm1zdHImIHMgPSAoX19saWJjcHBfbm1zdHImKV9faW1wXzsKICAgIDo6bmV3KCZzKSBfX2xpYmNwcF9ubXN0cihtc2cuY19zdHIoKSk7Cn0KCmxvZ2ljX2Vycm9yOjpsb2dpY19lcnJvcihjb25zdCBjaGFyKiBtc2cpCnsKICAgIF9fbGliY3BwX25tc3RyJiBzID0gKF9fbGliY3BwX25tc3RyJilfX2ltcF87CiAgICA6Om5ldygmcykgX19saWJjcHBfbm1zdHIobXNnKTsKfQoKbG9naWNfZXJyb3I6OmxvZ2ljX2Vycm9yKGNvbnN0IGxvZ2ljX2Vycm9yJiBsZSkgdGhyb3coKQp7CiAgICBfX2xpYmNwcF9ubXN0ciYgcyA9IChfX2xpYmNwcF9ubXN0ciYpX19pbXBfOwogICAgOjpuZXcoJnMpIF9fbGliY3BwX25tc3RyKChjb25zdCBfX2xpYmNwcF9ubXN0ciYpbGUuX19pbXBfKTsKfQoKbG9naWNfZXJyb3ImCmxvZ2ljX2Vycm9yOjpvcGVyYXRvcj0oY29uc3QgbG9naWNfZXJyb3ImIGxlKSB0aHJvdygpCnsKICAgIF9fbGliY3BwX25tc3RyJiBzMSA9IChfX2xpYmNwcF9ubXN0ciYpX19pbXBfOwogICAgY29uc3QgX19saWJjcHBfbm1zdHImIHMyID0gKGNvbnN0IF9fbGliY3BwX25tc3RyJilsZS5fX2ltcF87CiAgICBzMSA9IHMyOwogICAgcmV0dXJuICp0aGlzOwp9Cgpsb2dpY19lcnJvcjo6fmxvZ2ljX2Vycm9yKCkgdGhyb3coKQp7CiAgICBfX2xpYmNwcF9ubXN0ciYgcyA9IChfX2xpYmNwcF9ubXN0ciYpX19pbXBfOwogICAgcy5+X19saWJjcHBfbm1zdHIoKTsKfQoKY29uc3QgY2hhcioKbG9naWNfZXJyb3I6OndoYXQoKSBjb25zdCB0aHJvdygpCnsKICAgIF9fbGliY3BwX25tc3RyJiBzID0gKF9fbGliY3BwX25tc3RyJilfX2ltcF87CiAgICByZXR1cm4gcy5jX3N0cigpOwp9CgpydW50aW1lX2Vycm9yOjpydW50aW1lX2Vycm9yKGNvbnN0IHN0cmluZyYgbXNnKQp7CiAgICBfX2xpYmNwcF9ubXN0ciYgcyA9IChfX2xpYmNwcF9ubXN0ciYpX19pbXBfOwogICAgOjpuZXcoJnMpIF9fbGliY3BwX25tc3RyKG1zZy5jX3N0cigpKTsKfQoKcnVudGltZV9lcnJvcjo6cnVudGltZV9lcnJvcihjb25zdCBjaGFyKiBtc2cpCnsKICAgIF9fbGliY3BwX25tc3RyJiBzID0gKF9fbGliY3BwX25tc3RyJilfX2ltcF87CiAgICA6Om5ldygmcykgX19saWJjcHBfbm1zdHIobXNnKTsKfQoKcnVudGltZV9lcnJvcjo6cnVudGltZV9lcnJvcihjb25zdCBydW50aW1lX2Vycm9yJiBsZSkgdGhyb3coKQp7CiAgICBfX2xpYmNwcF9ubXN0ciYgcyA9IChfX2xpYmNwcF9ubXN0ciYpX19pbXBfOwogICAgOjpuZXcoJnMpIF9fbGliY3BwX25tc3RyKChjb25zdCBfX2xpYmNwcF9ubXN0ciYpbGUuX19pbXBfKTsKfQoKcnVudGltZV9lcnJvciYKcnVudGltZV9lcnJvcjo6b3BlcmF0b3I9KGNvbnN0IHJ1bnRpbWVfZXJyb3ImIGxlKSB0aHJvdygpCnsKICAgIF9fbGliY3BwX25tc3RyJiBzMSA9IChfX2xpYmNwcF9ubXN0ciYpX19pbXBfOwogICAgY29uc3QgX19saWJjcHBfbm1zdHImIHMyID0gKGNvbnN0IF9fbGliY3BwX25tc3RyJilsZS5fX2ltcF87CiAgICBzMSA9IHMyOwogICAgcmV0dXJuICp0aGlzOwp9CgpydW50aW1lX2Vycm9yOjp+cnVudGltZV9lcnJvcigpIHRocm93KCkKewogICAgX19saWJjcHBfbm1zdHImIHMgPSAoX19saWJjcHBfbm1zdHImKV9faW1wXzsKICAgIHMufl9fbGliY3BwX25tc3RyKCk7Cn0KCmNvbnN0IGNoYXIqCnJ1bnRpbWVfZXJyb3I6OndoYXQoKSBjb25zdCB0aHJvdygpCnsKICAgIF9fbGliY3BwX25tc3RyJiBzID0gKF9fbGliY3BwX25tc3RyJilfX2ltcF87CiAgICByZXR1cm4gcy5jX3N0cigpOwp9Cgpkb21haW5fZXJyb3I6On5kb21haW5fZXJyb3IoKSB0aHJvdygpIHt9CmludmFsaWRfYXJndW1lbnQ6On5pbnZhbGlkX2FyZ3VtZW50KCkgdGhyb3coKSB7fQpsZW5ndGhfZXJyb3I6On5sZW5ndGhfZXJyb3IoKSB0aHJvdygpIHt9Cm91dF9vZl9yYW5nZTo6fm91dF9vZl9yYW5nZSgpIHRocm93KCkge30KCnJhbmdlX2Vycm9yOjp+cmFuZ2VfZXJyb3IoKSB0aHJvdygpIHt9Cm92ZXJmbG93X2Vycm9yOjp+b3ZlcmZsb3dfZXJyb3IoKSB0aHJvdygpIHt9CnVuZGVyZmxvd19lcnJvcjo6fnVuZGVyZmxvd19lcnJvcigpIHRocm93KCkge30KCn0gIC8vIHN0ZAo=