Ly8KLy8gQ29weXJpZ2h0IKkgMjAxMiBMaW5hcm8gTGltaXRlZAovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgZ2xtYXJrMiBPcGVuR0wgKEVTKSAyLjAgYmVuY2htYXJrLgovLwovLyBnbG1hcmsyIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlCi8vIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKLy8gRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIKLy8gdmVyc2lvbi4KLy8KLy8gZ2xtYXJrMiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKLy8gV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUwovLyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCi8vIGRldGFpbHMuCi8vCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGgKLy8gZ2xtYXJrMi4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KLy8KLy8gQXV0aG9yczoKLy8gIEplc3NlIEJhcmtlcgovLwojaW5jbHVkZSAiZWdsLXN0YXRlLmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgIm9wdGlvbnMuaCIKI2luY2x1ZGUgImxpbWl0cy5oIgojaW5jbHVkZSA8aW9tYW5pcD4KI2luY2x1ZGUgPHNzdHJlYW0+Cgp1c2luZyBzdGQ6OnZlY3RvcjsKdXNpbmcgc3RkOjpzdHJpbmc7CgpFZ2xDb25maWc6OkVnbENvbmZpZyhFR0xEaXNwbGF5IGRweSwgRUdMQ29uZmlnIGNvbmZpZykgOgogICAgaGFuZGxlXyhjb25maWcpLAogICAgYnVmZmVyU2l6ZV8oMCksCiAgICByZWRTaXplXygwKSwKICAgIGdyZWVuU2l6ZV8oMCksCiAgICBibHVlU2l6ZV8oMCksCiAgICBsdW1pbmFuY2VTaXplXygwKSwKICAgIGFscGhhU2l6ZV8oMCksCiAgICBhbHBoYU1hc2tTaXplXygwKSwKICAgIGJ1ZmZlclR5cGVfKEVHTF9SR0JfQlVGRkVSKSwKICAgIGNhdmVhdF8oMCksCiAgICBjb25maWdJRF8oMCksCiAgICBkZXB0aFNpemVfKDApLAogICAgbmF0aXZlSURfKDApLAogICAgbmF0aXZlVHlwZV8oMCksCiAgICBuYXRpdmVSZW5kZXJhYmxlXyhmYWxzZSksCiAgICBzYW1wbGVCdWZmZXJzXygwKSwKICAgIHNhbXBsZXNfKDApLAogICAgc3RlbmNpbFNpemVfKDApLAogICAgc3VyZmFjZVR5cGVfKDApLAogICAgeHBhcmVudFR5cGVfKDApLAogICAgeHBhcmVudFJlZFZhbHVlXygwKSwKICAgIHhwYXJlbnRHcmVlblZhbHVlXygwKSwKICAgIHhwYXJlbnRCbHVlVmFsdWVfKDApCnsKICAgIHZlY3RvcjxzdHJpbmc+IGJhZEF0dHJpYlZlYzsKICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX0NPTkZJR19JRCwgJmNvbmZpZ0lEXykpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX0NPTkZJR19JRCIpOwogICAgfQogICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfQ09ORklHX0NBVkVBVCwgJmNhdmVhdF8pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9DT05GSUdfQ0FWRUFUIik7CiAgICB9CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9DT0xPUl9CVUZGRVJfVFlQRSwgJmJ1ZmZlclR5cGVfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfQ09MT1JfQlVGRkVSX1RZUEUiKTsKICAgIH0KICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX0JVRkZFUl9TSVpFLCAmYnVmZmVyU2l6ZV8pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9CVUZGRVJfU0laRSIpOwogICAgfQoKICAgIGlmIChidWZmZXJUeXBlXyA9PSBFR0xfUkdCX0JVRkZFUikKICAgIHsKICAgICAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9SRURfU0laRSwgJnJlZFNpemVfKSkKICAgICAgICB7CiAgICAgICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9SRURfU0laRSIpOwogICAgICAgIH0KICAgICAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9HUkVFTl9TSVpFLCAmZ3JlZW5TaXplXykpCiAgICAgICAgewogICAgICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfR1JFRU5fU0laRSIpOwogICAgICAgIH0KICAgICAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9CTFVFX1NJWkUsICZibHVlU2l6ZV8pKQogICAgICAgIHsKICAgICAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX0JMVUVfU0laRSIpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9MVU1JTkFOQ0VfU0laRSwgJmx1bWluYW5jZVNpemVfKSkKICAgICAgICB7CiAgICAgICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9MVU1JTkFOQ0VfU0laRSIpOwogICAgICAgIH0KICAgIH0KICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX0FMUEhBX1NJWkUsICZhbHBoYVNpemVfKSkKICAgIHsKICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfQUxQSEFfU0laRSIpOwogICAgfQogICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfREVQVEhfU0laRSwgJmRlcHRoU2l6ZV8pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9ERVBUSF9TSVpFIik7CiAgICB9CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9TVEVOQ0lMX1NJWkUsICZzdGVuY2lsU2l6ZV8pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9TVEVOQ0lMX1NJWkUiKTsKICAgIH0KICAgIEVHTGludCBkb05hdGl2ZShFR0xfRkFMU0UpOwogICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfTkFUSVZFX1JFTkRFUkFCTEUsICZkb05hdGl2ZSkpCiAgICB7CiAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX05BVElWRV9SRU5ERVJBQkxFIik7CiAgICB9CiAgICBpZiAoZG9OYXRpdmUgPT0gRUdMX1RSVUUpCiAgICB7CiAgICAgICAgbmF0aXZlUmVuZGVyYWJsZV8gPSB0cnVlOwogICAgfQogICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfTkFUSVZFX1ZJU1VBTF9UWVBFLCAmbmF0aXZlVHlwZV8pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9OQVRJVkVfVklTVUFMX1RZUEUiKTsKICAgIH0KICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX05BVElWRV9WSVNVQUxfSUQsICZuYXRpdmVJRF8pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9OQVRJVkVfVklTVUFMX0lEIik7CiAgICB9CiAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9TVVJGQUNFX1RZUEUsICZzdXJmYWNlVHlwZV8pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9TVVJGQUNFX1RZUEUiKTsKICAgIH0KICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX1NBTVBMRV9CVUZGRVJTLCAmc2FtcGxlQnVmZmVyc18pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9TQU1QTEVfQlVGRkVSUyIpOwogICAgfQogICAgaWYgKHNhbXBsZUJ1ZmZlcnNfKQogICAgewogICAgICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX1NBTVBMRVMsICZzYW1wbGVzXykpCiAgICAgICAgewogICAgICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfU0FNUExFUyIpOwogICAgICAgIH0gICAgICAgIAogICAgfSAgICAKICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX1RSQU5TUEFSRU5UX1RZUEUsICZ4cGFyZW50VHlwZV8pKQogICAgewogICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9UUkFOU1BBUkVOVF9UWVBFIik7CiAgICB9CiAgICAvL2lmICh4cGFyZW50VHlwZV8gIT0gRUdMX05PTkUpCiAgICB7CiAgICAgICAgaWYgKCFlZ2xHZXRDb25maWdBdHRyaWIoZHB5LCBoYW5kbGVfLCBFR0xfVFJBTlNQQVJFTlRfUkVEX1ZBTFVFLCAmeHBhcmVudFJlZFZhbHVlXykpCiAgICAgICAgewogICAgICAgICAgICBiYWRBdHRyaWJWZWMucHVzaF9iYWNrKCJFR0xfVFJBTlNQQVJFTlRfUkVEX1ZBTFVFIik7CiAgICAgICAgfQogICAgICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGRweSwgaGFuZGxlXywgRUdMX1RSQU5TUEFSRU5UX0dSRUVOX1ZBTFVFLCAmeHBhcmVudEdyZWVuVmFsdWVfKSkKICAgICAgICB7CiAgICAgICAgICAgIGJhZEF0dHJpYlZlYy5wdXNoX2JhY2soIkVHTF9UUkFOU1BBUkVOVF9HUkVFTl9WQUxVRSIpOwogICAgICAgIH0KICAgICAgICBpZiAoIWVnbEdldENvbmZpZ0F0dHJpYihkcHksIGhhbmRsZV8sIEVHTF9UUkFOU1BBUkVOVF9CTFVFX1ZBTFVFLCAmeHBhcmVudEJsdWVWYWx1ZV8pKQogICAgICAgIHsKICAgICAgICAgICAgYmFkQXR0cmliVmVjLnB1c2hfYmFjaygiRUdMX1RSQU5TUEFSRU5UX0JMVUVfVkFMVUUiKTsKICAgICAgICB9CiAgICB9CgogICAgaWYgKCFiYWRBdHRyaWJWZWMuZW1wdHkoKSkKICAgIHsKICAgICAgICBMb2c6OmVycm9yKCJGYWlsZWQgdG8gZ2V0IHRoZSBmb2xsb3dpbmcgY29uZmlnIGF0dHJpYnV0ZXMgZm9yIGNvbmZpZyAweCV4OlxuIiwKICAgICAgICAgICAgICAgICAgICBjb25maWcpOwogICAgICAgIGZvciAodmVjdG9yPHN0cmluZz46OmNvbnN0X2l0ZXJhdG9yIGF0dHJpYkl0ID0gYmFkQXR0cmliVmVjLmJlZ2luKCk7CiAgICAgICAgICAgICBhdHRyaWJJdCAhPSBiYWRBdHRyaWJWZWMuZW5kKCk7CiAgICAgICAgICAgICBhdHRyaWJJdCsrKQogICAgICAgIHsKICAgICAgICAgICAgTG9nOjplcnJvcigiJXNcbiIsIGF0dHJpYkl0LT5jX3N0cigpKTsKICAgICAgICB9CiAgICB9Cn0KCnZvaWQKRWdsQ29uZmlnOjpwcmludF9oZWFkZXIoKQp7CiAgICBMb2c6OmRlYnVnKCJcbiIpOwogICAgTG9nOjpkZWJ1ZygiICAgIGNmZyBidWYgIHJnYiAgY29sb3JidWZmZXIgZHAgc3QgY29uZmlnIG5hdGl2ZSBzdXBwb3J0IHN1cmZhY2Ugc2FtcGxlXG4iKTsKICAgIExvZzo6ZGVidWcoIiAgICAgaWQgIHN6ICBsdW0gIHIgIGcgIGIgIGEgIHRoIGNsIGNhdmVhdCByZW5kZXIgIHZpc2lkICAgIHR5cGUgIGJ1ZiBuc1xuIik7CiAgICBMb2c6OmRlYnVnKCItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiIpOwp9Cgp2b2lkCkVnbENvbmZpZzo6cHJpbnQoKSBjb25zdAp7CiAgICBzdGQ6Om9zdHJpbmdzdHJlYW0gczsKICAgIHMuc2V0ZihzdGQ6Omlvczo6c2hvd2Jhc2UpOwogICAgcy5maWxsKCcgJyk7CiAgICBzIDw8IHN0ZDo6c2V0dyg3KSA8PCBzdGQ6OmhleCA8PCBjb25maWdJRF87CiAgICBzIDw8IHN0ZDo6c2V0dyg0KSA8PCBzdGQ6OmRlYyA8PCBidWZmZXJTaXplXzsKICAgIGlmIChidWZmZXJUeXBlXyA9PSBFR0xfUkdCX0JVRkZFUikKICAgIHsKICAgICAgICBzIDw8IHN0ZDo6c2V0dyg1KSA8PCAicmdiIjsKICAgICAgICBzIDw8IHN0ZDo6c2V0dygzKSA8PCByZWRTaXplXzsKICAgICAgICBzIDw8IHN0ZDo6c2V0dygzKSA8PCBncmVlblNpemVfOwogICAgICAgIHMgPDwgc3RkOjpzZXR3KDMpIDw8IGJsdWVTaXplXzsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzIDw8IHN0ZDo6c2V0dyg1KSA8PCAibHVtIjsKICAgICAgICBzIDw8IHN0ZDo6c2V0dygzKSA8PCBsdW1pbmFuY2VTaXplXzsKICAgICAgICBzIDw8IHN0ZDo6c2V0dygzKSA8PCAwOwogICAgICAgIHMgPDwgc3RkOjpzZXR3KDMpIDw8IDA7CiAgICB9CiAgICBzIDw8IHN0ZDo6c2V0dygzKSA8PCBhbHBoYVNpemVfOwogICAgcyA8PCBzdGQ6OnNldHcoNCkgPDwgZGVwdGhTaXplXzsKICAgIHMgPDwgc3RkOjpzZXR3KDMpIDw8IHN0ZW5jaWxTaXplXzsKICAgIHN0cmluZyBjYXZlYXQoIk5vbmUiKTsKICAgIHN3aXRjaCAoY2F2ZWF0XykKICAgIHsKICAgICAgICBjYXNlIEVHTF9TTE9XX0NPTkZJRzoKICAgICAgICAgICAgY2F2ZWF0ID0gc3RyaW5nKCJTbG93Iik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRUdMX05PTl9DT05GT1JNQU5UX0NPTkZJRzoKICAgICAgICAgICAgY2F2ZWF0ID0gc3RyaW5nKCJOY29uIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgRUdMX05PTkU6CiAgICAgICAgICAgIC8vIEluaXRpYWxpemVkIHRvIG5vbmUuCiAgICAgICAgICAgIGJyZWFrOwogICAgfQogICAgcyA8PCBzdGQ6OnNldHcoNykgPDwgY2F2ZWF0OwogICAgc3RyaW5nIGRvTmF0aXZlKG5hdGl2ZVJlbmRlcmFibGVfID8gInRydWUiIDogImZhbHNlIik7CiAgICBzIDw8IHN0ZDo6c2V0dyg3KSA8PCBkb05hdGl2ZTsKICAgIHMgPDwgc3RkOjpzZXR3KDgpIDw8IHN0ZDo6aGV4IDw8IG5hdGl2ZUlEXzsKICAgIHMgPDwgc3RkOjpzZXR3KDgpIDw8IHN0ZDo6aGV4IDw8IHN1cmZhY2VUeXBlXzsKICAgIHMgPDwgc3RkOjpzZXR3KDQpIDw8IHN0ZDo6ZGVjIDw8IHNhbXBsZUJ1ZmZlcnNfOwogICAgcyA8PCBzdGQ6OnNldHcoMykgPDwgc3RkOjpkZWMgPDwgc2FtcGxlc187CiAgICBMb2c6OmRlYnVnKCIlc1xuIiwgcy5zdHIoKS5jX3N0cigpKTsKfQoKCmJvb2wKRUdMU3RhdGU6OmluaXRfZGlzcGxheShFR0xOYXRpdmVEaXNwbGF5VHlwZSBuYXRpdmVfZGlzcGxheSwgR0xWaXN1YWxDb25maWcmIHZpc3VhbF9jb25maWcpCnsKICAgIG5hdGl2ZV9kaXNwbGF5XyA9IG5hdGl2ZV9kaXNwbGF5OwogICAgdmlzdWFsX2NvbmZpZ18gPSB2aXN1YWxfY29uZmlnOwoKICAgIHJldHVybiBnb3RWYWxpZERpc3BsYXkoKTsKfQoKYm9vbApFR0xTdGF0ZTo6aW5pdF9zdXJmYWNlKEVHTE5hdGl2ZVdpbmRvd1R5cGUgbmF0aXZlX3dpbmRvdykKewogICAgbmF0aXZlX3dpbmRvd18gPSByZWludGVycHJldF9jYXN0PEVHTE5hdGl2ZVdpbmRvd1R5cGU+KG5hdGl2ZV93aW5kb3cpOwoKICAgIHJldHVybiBnb3RWYWxpZFN1cmZhY2UoKTsKfQoKdm9pZApFR0xTdGF0ZTo6c3dhcCgpCnsKICAgIGVnbFN3YXBCdWZmZXJzKGVnbF9kaXNwbGF5XywgZWdsX3N1cmZhY2VfKTsKfQoKYm9vbApFR0xTdGF0ZTo6Z290VmFsaWREaXNwbGF5KCkKewogICAgaWYgKGVnbF9kaXNwbGF5XykKICAgICAgICByZXR1cm4gdHJ1ZTsKCiAgICBlZ2xfZGlzcGxheV8gPSBlZ2xHZXREaXNwbGF5KG5hdGl2ZV9kaXNwbGF5Xyk7CiAgICBpZiAoIWVnbF9kaXNwbGF5XykgewogICAgICAgIExvZzo6ZXJyb3IoImVnbEdldERpc3BsYXkoKSBmYWlsZWQgd2l0aCBlcnJvcjogMHgleFxuIiwgZWdsR2V0RXJyb3IoKSk7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaW50IGVnbF9tYWpvcigtMSk7CiAgICBpbnQgZWdsX21pbm9yKC0xKTsKICAgIGlmICghZWdsSW5pdGlhbGl6ZShlZ2xfZGlzcGxheV8sICZlZ2xfbWFqb3IsICZlZ2xfbWlub3IpKSB7CiAgICAgICAgTG9nOjplcnJvcigiZWdsSW5pdGlhbGl6ZSgpIGZhaWxlZCB3aXRoIGVycm9yOiAweCV4XG4iLCBlZ2xHZXRFcnJvcigpKTsKICAgICAgICBlZ2xfZGlzcGxheV8gPSAwOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiNpZiBVU0VfR0xFU3YyCiAgICBFR0xlbnVtIGFwaVR5cGUoRUdMX09QRU5HTF9FU19BUEkpOwojZWxpZiBVU0VfR0wKICAgIEVHTGVudW0gYXBpVHlwZShFR0xfT1BFTkdMX0FQSSk7CiNlbmRpZgogICAgaWYgKCFlZ2xCaW5kQVBJKGFwaVR5cGUpKSB7CiAgICAgICAgTG9nOjplcnJvcigiRmFpbGVkIHRvIGJpbmQgYXBpIEVHTF9PUEVOR0xfRVNfQVBJXG4iKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcmV0dXJuIHRydWU7Cn0KCnZvaWQKRUdMU3RhdGU6OmdldF9nbHZpc3VhbGNvbmZpZyhFR0xDb25maWcgY29uZmlnLCBHTFZpc3VhbENvbmZpZyYgdmlzdWFsX2NvbmZpZykKewogICAgZWdsR2V0Q29uZmlnQXR0cmliKGVnbF9kaXNwbGF5XywgY29uZmlnLCBFR0xfQlVGRkVSX1NJWkUsICZ2aXN1YWxfY29uZmlnLmJ1ZmZlcik7CiAgICBlZ2xHZXRDb25maWdBdHRyaWIoZWdsX2Rpc3BsYXlfLCBjb25maWcsIEVHTF9SRURfU0laRSwgJnZpc3VhbF9jb25maWcucmVkKTsKICAgIGVnbEdldENvbmZpZ0F0dHJpYihlZ2xfZGlzcGxheV8sIGNvbmZpZywgRUdMX0dSRUVOX1NJWkUsICZ2aXN1YWxfY29uZmlnLmdyZWVuKTsKICAgIGVnbEdldENvbmZpZ0F0dHJpYihlZ2xfZGlzcGxheV8sIGNvbmZpZywgRUdMX0JMVUVfU0laRSwgJnZpc3VhbF9jb25maWcuYmx1ZSk7CiAgICBlZ2xHZXRDb25maWdBdHRyaWIoZWdsX2Rpc3BsYXlfLCBjb25maWcsIEVHTF9BTFBIQV9TSVpFLCAmdmlzdWFsX2NvbmZpZy5hbHBoYSk7CiAgICBlZ2xHZXRDb25maWdBdHRyaWIoZWdsX2Rpc3BsYXlfLCBjb25maWcsIEVHTF9ERVBUSF9TSVpFLCAmdmlzdWFsX2NvbmZpZy5kZXB0aCk7Cn0KCkVHTENvbmZpZwpFR0xTdGF0ZTo6c2VsZWN0X2Jlc3RfY29uZmlnKHN0ZDo6dmVjdG9yPEVHTENvbmZpZz4mIGNvbmZpZ3MpCnsKICAgIGludCBiZXN0X3Njb3JlKElOVF9NSU4pOwogICAgRUdMQ29uZmlnIGJlc3RfY29uZmlnKDApOwoKICAgIC8qCiAgICAgKiBHbyB0aHJvdWdoIGFsbCB0aGUgY29uZmlncyBhbmQgY2hvb3NlIHRoZSBvbmUgd2l0aCB0aGUgYmVzdCBzY29yZSwKICAgICAqIGkuZS4sIHRoZSBvbmUgYmV0dGVyIG1hdGNoaW5nIHRoZSByZXF1ZXN0ZWQgY29uZmlnLgogICAgICovCiAgICBmb3IgKHN0ZDo6dmVjdG9yPEVHTENvbmZpZz46OmNvbnN0X2l0ZXJhdG9yIGl0ZXIgPSBjb25maWdzLmJlZ2luKCk7CiAgICAgICAgIGl0ZXIgIT0gY29uZmlncy5lbmQoKTsKICAgICAgICAgaXRlcisrKQogICAgewogICAgICAgIGNvbnN0IEVHTENvbmZpZyBjb25maWcoKml0ZXIpOwogICAgICAgIEdMVmlzdWFsQ29uZmlnIHZjOwogICAgICAgIGludCBzY29yZTsKCiAgICAgICAgZ2V0X2dsdmlzdWFsY29uZmlnKGNvbmZpZywgdmMpOwoKICAgICAgICBzY29yZSA9IHZjLm1hdGNoX3Njb3JlKHZpc3VhbF9jb25maWdfKTsKCiAgICAgICAgaWYgKHNjb3JlID4gYmVzdF9zY29yZSkgewogICAgICAgICAgICBiZXN0X3Njb3JlID0gc2NvcmU7CiAgICAgICAgICAgIGJlc3RfY29uZmlnID0gY29uZmlnOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gYmVzdF9jb25maWc7Cn0KCmJvb2wKRUdMU3RhdGU6OmdvdFZhbGlkQ29uZmlnKCkKewogICAgaWYgKGVnbF9jb25maWdfKQogICAgICAgIHJldHVybiB0cnVlOwoKICAgIGlmICghZ290VmFsaWREaXNwbGF5KCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIGNvbnN0IEVHTGludCBjb25maWdfYXR0cmlic1tdID0gewogICAgICAgIEVHTF9SRURfU0laRSwgdmlzdWFsX2NvbmZpZ18ucmVkLAogICAgICAgIEVHTF9HUkVFTl9TSVpFLCB2aXN1YWxfY29uZmlnXy5ncmVlbiwKICAgICAgICBFR0xfQkxVRV9TSVpFLCB2aXN1YWxfY29uZmlnXy5ibHVlLAogICAgICAgIEVHTF9BTFBIQV9TSVpFLCB2aXN1YWxfY29uZmlnXy5hbHBoYSwKICAgICAgICBFR0xfREVQVEhfU0laRSwgdmlzdWFsX2NvbmZpZ18uZGVwdGgsCiNpZiBVU0VfR0xFU3YyCiAgICAgICAgRUdMX1JFTkRFUkFCTEVfVFlQRSwgRUdMX09QRU5HTF9FUzJfQklULAojZWxpZiBVU0VfR0wKICAgICAgICBFR0xfUkVOREVSQUJMRV9UWVBFLCBFR0xfT1BFTkdMX0JJVCwKI2VuZGlmCiAgICAgICAgRUdMX05PTkUKICAgIH07CgogICAgLy8gRmluZCBvdXQgaG93IG1hbnkgY29uZmlncyBtYXRjaCB0aGUgYXR0cmlidXRlcy4KICAgIEVHTGludCBudW1fY29uZmlncygwKTsKICAgIGlmICghZWdsQ2hvb3NlQ29uZmlnKGVnbF9kaXNwbGF5XywgY29uZmlnX2F0dHJpYnMsIDAsIDAsICZudW1fY29uZmlncykpIHsKICAgICAgICBMb2c6OmVycm9yKCJlZ2xDaG9vc2VDb25maWcoKSAoY291bnQgcXVlcnkpIGZhaWxlZCB3aXRoIGVycm9yOiAlZFxuIiwKICAgICAgICAgICAgICAgICAgIGVnbEdldEVycm9yKCkpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBpZiAobnVtX2NvbmZpZ3MgPT0gMCkgewogICAgICAgIExvZzo6ZXJyb3IoImVnbENob29zZUNvbmZpZygpIGRpZG4ndCByZXR1cm4gYW55IGNvbmZpZ3NcbiIpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvLyBHZXQgYWxsIHRoZSBtYXRjaGluZyBjb25maWdzCiAgICB2ZWN0b3I8RUdMQ29uZmlnPiBjb25maWdzKG51bV9jb25maWdzKTsKICAgIGlmICghZWdsQ2hvb3NlQ29uZmlnKGVnbF9kaXNwbGF5XywgY29uZmlnX2F0dHJpYnMsICZjb25maWdzLmZyb250KCksCiAgICAgICAgICAgICAgICAgICAgICAgICBudW1fY29uZmlncywgJm51bV9jb25maWdzKSkKICAgIHsKICAgICAgICBMb2c6OmVycm9yKCJlZ2xDaG9vc2VDb25maWcoKSBmYWlsZWQgd2l0aCBlcnJvcjogJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgIGVnbEdldEVycm9yKCkpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICAvLyBTZWxlY3QgdGhlIGJlc3QgbWF0Y2hpbmcgY29uZmlnCiAgICBlZ2xfY29uZmlnXyA9IHNlbGVjdF9iZXN0X2NvbmZpZyhjb25maWdzKTsKCiAgICB2ZWN0b3I8RWdsQ29uZmlnPiBjb25maWdWZWM7CiAgICBmb3IgKHZlY3RvcjxFR0xDb25maWc+Ojpjb25zdF9pdGVyYXRvciBjb25maWdJdCA9IGNvbmZpZ3MuYmVnaW4oKTsKICAgICAgICAgY29uZmlnSXQgIT0gY29uZmlncy5lbmQoKTsKICAgICAgICAgY29uZmlnSXQrKykKICAgIHsKICAgICAgICBFZ2xDb25maWcgY2ZnKGVnbF9kaXNwbGF5XywgKmNvbmZpZ0l0KTsKICAgICAgICBjb25maWdWZWMucHVzaF9iYWNrKGNmZyk7CiAgICAgICAgaWYgKCpjb25maWdJdCA9PSBlZ2xfY29uZmlnXykgewogICAgICAgICAgICBiZXN0X2NvbmZpZ18gPSBjZmc7CiAgICAgICAgfQogICAgfSAKCiAgICAvLyBQcmludCBvdXQgdGhlIGNvbmZpZyBpbmZvcm1hdGlvbiwgYW5kIGxldCB0aGUgdXNlciBrbm93IHRoZSBkZWNpc2lvbgogICAgLy8gYWJvdXQgdGhlICJiZXN0IiBvbmUgd2l0aCByZXNwZWN0IHRvIHRoZSBvcHRpb25zLgogICAgdW5zaWduZWQgaW50IGxpbmVOdW1iZXIoMCk7CiAgICBMb2c6OmRlYnVnKCJHb3QgJXUgc3VpdGFibGUgRUdMQ29uZmlnczpcbiIsIG51bV9jb25maWdzKTsKICAgIGZvciAodmVjdG9yPEVnbENvbmZpZz46OmNvbnN0X2l0ZXJhdG9yIGNvbmZpZ0l0ID0gY29uZmlnVmVjLmJlZ2luKCk7CiAgICAgICAgIGNvbmZpZ0l0ICE9IGNvbmZpZ1ZlYy5lbmQoKTsKICAgICAgICAgY29uZmlnSXQrKywgbGluZU51bWJlcisrKQogICAgewogICAgICAgIGlmICghKGxpbmVOdW1iZXIgJSAzMikpCiAgICAgICAgewogICAgICAgICAgICBjb25maWdJdC0+cHJpbnRfaGVhZGVyKCk7CiAgICAgICAgfQogICAgICAgIGNvbmZpZ0l0LT5wcmludCgpOwogICAgfQogICAgTG9nOjpkZWJ1ZygiXG4iKTsKICAgIExvZzo6ZGVidWcoIkJlc3QgRUdMQ29uZmlnIElEOiAweCV4XG4iLCBiZXN0X2NvbmZpZ18uY29uZmlnSUQoKSk7CgogICAgcmV0dXJuIHRydWU7Cn0KCmJvb2wKRUdMU3RhdGU6OmdvdFZhbGlkU3VyZmFjZSgpCnsKICAgIGlmIChlZ2xfc3VyZmFjZV8pCiAgICAgICAgcmV0dXJuIHRydWU7CgogICAgaWYgKCFnb3RWYWxpZERpc3BsYXkoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgaWYgKCFnb3RWYWxpZENvbmZpZygpKQogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICBlZ2xfc3VyZmFjZV8gPSBlZ2xDcmVhdGVXaW5kb3dTdXJmYWNlKGVnbF9kaXNwbGF5XywgZWdsX2NvbmZpZ18sIG5hdGl2ZV93aW5kb3dfLCAwKTsKICAgIGlmICghZWdsX3N1cmZhY2VfKSB7CiAgICAgICAgTG9nOjplcnJvcigiZWdsQ3JlYXRlV2luZG93U3VyZmFjZSBmYWlsZWQgd2l0aCBlcnJvcjogMHgleFxuIiwgZWdsR2V0RXJyb3IoKSk7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHJldHVybiB0cnVlOwp9Cgpib29sCkVHTFN0YXRlOjpnb3RWYWxpZENvbnRleHQoKQp7CiAgICBpZiAoZWdsX2NvbnRleHRfKQogICAgICAgIHJldHVybiB0cnVlOwoKICAgIGlmICghZ290VmFsaWREaXNwbGF5KCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIGlmICghZ290VmFsaWRDb25maWcoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgc3RhdGljIGNvbnN0IEVHTGludCBjb250ZXh0X2F0dHJpYnNbXSA9IHsKI2lmZGVmIFVTRV9HTEVTdjIKICAgICAgICBFR0xfQ09OVEVYVF9DTElFTlRfVkVSU0lPTiwgMiwKI2VuZGlmCiAgICAgICAgRUdMX05PTkUKICAgIH07CgogICAgZWdsX2NvbnRleHRfID0gZWdsQ3JlYXRlQ29udGV4dChlZ2xfZGlzcGxheV8sIGVnbF9jb25maWdfLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFR0xfTk9fQ09OVEVYVCwgY29udGV4dF9hdHRyaWJzKTsKICAgIGlmICghZWdsX2NvbnRleHRfKSB7CiAgICAgICAgTG9nOjplcnJvcigiZWdsQ3JlYXRlQ29udGV4dCgpIGZhaWxlZCB3aXRoIGVycm9yOiAweCV4XG4iLAogICAgICAgICAgICAgICAgICAgZWdsR2V0RXJyb3IoKSk7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHJldHVybiB0cnVlOwp9Cgpib29sCkVHTFN0YXRlOjp2YWxpZCgpCnsKICAgIGlmICghZ290VmFsaWREaXNwbGF5KCkpCiAgICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIGlmICghZ290VmFsaWRDb25maWcoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgaWYgKCFnb3RWYWxpZFN1cmZhY2UoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgaWYgKCFnb3RWYWxpZENvbnRleHQoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgaWYgKGVnbF9jb250ZXh0XyA9PSBlZ2xHZXRDdXJyZW50Q29udGV4dCgpKQogICAgICAgIHJldHVybiB0cnVlOwoKICAgIGlmICghZWdsTWFrZUN1cnJlbnQoZWdsX2Rpc3BsYXlfLCBlZ2xfc3VyZmFjZV8sIGVnbF9zdXJmYWNlXywgZWdsX2NvbnRleHRfKSkgewogICAgICAgIExvZzo6ZXJyb3IoImVnbE1ha2VDdXJyZW50IGZhaWxlZCB3aXRoIGVycm9yOiAweCV4XG4iLCBlZ2xHZXRFcnJvcigpKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgaWYgKCFlZ2xTd2FwSW50ZXJ2YWwoZWdsX2Rpc3BsYXlfLCAwKSkgewogICAgICAgIExvZzo6aW5mbygiKiogRmFpbGVkIHRvIHNldCBzd2FwIGludGVydmFsLiBSZXN1bHRzIG1heSBiZSBib3VuZGVkIGFib3ZlIGJ5IHJlZnJlc2ggcmF0ZS5cbiIpOwogICAgfQoKICAgIHJldHVybiB0cnVlOwp9Cgpib29sCkVHTFN0YXRlOjpnb3ROYXRpdmVDb25maWcoaW50JiB2aWQpCnsKICAgIGlmICghZ290VmFsaWRDb25maWcoKSkKICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgRUdMaW50IG5hdGl2ZV9pZDsKICAgIGlmICghZWdsR2V0Q29uZmlnQXR0cmliKGVnbF9kaXNwbGF5XywgZWdsX2NvbmZpZ18sIEVHTF9OQVRJVkVfVklTVUFMX0lELAogICAgICAgICZuYXRpdmVfaWQpKQogICAgewogICAgICAgIExvZzo6ZGVidWcoIkZhaWxlZCB0byBnZXQgbmF0aXZlIHZpc3VhbCBpZCBmb3IgRUdMQ29uZmlnIDB4JXhcbiIsIGVnbF9jb25maWdfKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgdmlkID0gbmF0aXZlX2lkOwogICAgcmV0dXJuIHRydWU7Cn0KCmJvb2wKRUdMU3RhdGU6OnJlc2V0KCkKewogICAgaWYgKCFnb3RWYWxpZERpc3BsYXkoKSkgewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KCiAgICBpZiAoIWVnbF9jb250ZXh0XykgewogICAgICAgIHJldHVybiB0cnVlOwogICAgfQoKICAgIGlmIChFR0xfRkFMU0UgPT0gZWdsRGVzdHJveUNvbnRleHQoZWdsX2Rpc3BsYXlfLCBlZ2xfY29udGV4dF8pKSB7CiAgICAgICAgTG9nOjpkZWJ1ZygiZWdsRGVzdHJveUNvbnRleHQgZmFpbGVkIHdpdGggZXJyb3I6IDB4JXhcbiIsIGVnbEdldEVycm9yKCkpOwogICAgfQoKICAgIGVnbF9jb250ZXh0XyA9IDA7CgogICAgcmV0dXJuIHRydWU7Cn0K