Ly8KLy8gQ29weXJpZ2h0IKkgMjAxMiBMaW5hcm8gTGltaXRlZAovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiB0aGUgZ2xtYXJrMiBPcGVuR0wgKEVTKSAyLjAgYmVuY2htYXJrLgovLwovLyBnbG1hcmsyIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQgdW5kZXIgdGhlCi8vIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUKLy8gRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMyBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIKLy8gdmVyc2lvbi4KLy8KLy8gZ2xtYXJrMiBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQgV0lUSE9VVCBBTlkKLy8gV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUwovLyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlCi8vIGRldGFpbHMuCi8vCi8vIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFsb25nIHdpdGgKLy8gZ2xtYXJrMi4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi4KLy8KLy8gQXV0aG9yczoKLy8gIEplc3NlIEJhcmtlcgovLwojaW5jbHVkZSAic2NlbmUuaCIKI2luY2x1ZGUgIm1vZGVsLmgiCiNpbmNsdWRlICJ1dGlsLmgiCiNpbmNsdWRlICJsb2cuaCIKI2luY2x1ZGUgInNoYWRlci1zb3VyY2UuaCIKI2luY2x1ZGUgInN0YWNrLmgiCgp1c2luZyBzdGQ6OnN0cmluZzsKdXNpbmcgc3RkOjp2ZWN0b3I7CnVzaW5nIHN0ZDo6bWFwOwp1c2luZyBMaWJNYXRyaXg6OlN0YWNrNDsKdXNpbmcgTGliTWF0cml4OjptYXQ0Owp1c2luZyBMaWJNYXRyaXg6OnZlYzQ7CnVzaW5nIExpYk1hdHJpeDo6dmVjMzsKCnN0YXRpYyBjb25zdCB2ZWM0IGxpZ2h0UG9zaXRpb24oMC4wZiwgMy4wZiwgMi4wZiwgMS4wZik7CgovLwovLyBUbyBjcmVhdGUgYSBzaGFkb3cgbWFwLCB3ZSBuZWVkIGEgZnJhbWVidWZmZXIgb2JqZWN0IHNldCB1cCBmb3IgYSAKLy8gZGVwdGgtb25seSBwYXNzLiAgVGhlIHJlbmRlciB0YXJnZXQgY2FuIHRoZW4gYmUgYm91bmQgYXMgYSB0ZXh0dXJlLAovLyBhbmQgdGhlIGRlcHRoIHZhbHVlcyBzYW1wbGVkIGZyb20gdGhhdCB0ZXh0dXJlIGNhbiBiZSB1c2VkIGluIHRoZQovLyBkaXN0YW5jZS1mcm9tLWxpZ2h0IGNvbXB1dGF0aW9ucyB3aGVuIHJlbmRlcmluZyB0aGUgc2hhZG93IG9uIHRoZQovLyBncm91bmQgYmVsb3cgdGhlIHJlbmRlcmVkIG9iamVjdC4KLy8KY2xhc3MgRGVwdGhSZW5kZXJUYXJnZXQKewogICAgUHJvZ3JhbSBwcm9ncmFtXzsKICAgIHVuc2lnbmVkIGludCBjYW52YXNfd2lkdGhfOwogICAgdW5zaWduZWQgaW50IGNhbnZhc19oZWlnaHRfOwogICAgdW5zaWduZWQgaW50IHdpZHRoXzsKICAgIHVuc2lnbmVkIGludCBoZWlnaHRfOwogICAgdW5zaWduZWQgaW50IHRleF87CiAgICB1bnNpZ25lZCBpbnQgZmJvXzsKcHVibGljOgogICAgRGVwdGhSZW5kZXJUYXJnZXQoKSA6CiAgICAgICAgY2FudmFzX3dpZHRoXygwKSwKICAgICAgICBjYW52YXNfaGVpZ2h0XygwKSwKICAgICAgICB3aWR0aF8oMCksCiAgICAgICAgaGVpZ2h0XygwKSwKICAgICAgICB0ZXhfKDApLAogICAgICAgIGZib18oMCkge30KICAgIH5EZXB0aFJlbmRlclRhcmdldCgpIHt9CiAgICBib29sIHNldHVwKHVuc2lnbmVkIGludCB3aWR0aCwgdW5zaWduZWQgaW50IGhlaWdodCk7CiAgICB2b2lkIHRlYXJkb3duKCk7CiAgICB2b2lkIGVuYWJsZShjb25zdCBtYXQ0JiBtdnApOwogICAgdm9pZCBkaXNhYmxlKCk7CiAgICB1bnNpZ25lZCBpbnQgZGVwdGhUZXh0dXJlKCkgeyByZXR1cm4gdGV4XzsgfQogICAgUHJvZ3JhbSYgcHJvZ3JhbSgpIHsgcmV0dXJuIHByb2dyYW1fOyB9Cn07Cgpib29sCkRlcHRoUmVuZGVyVGFyZ2V0OjpzZXR1cCh1bnNpZ25lZCBpbnQgd2lkdGgsIHVuc2lnbmVkIGludCBoZWlnaHQpCnsKICAgIGNhbnZhc193aWR0aF8gPSB3aWR0aDsKICAgIGNhbnZhc19oZWlnaHRfID0gaGVpZ2h0OwogICAgd2lkdGhfID0gY2FudmFzX3dpZHRoXyAqIDI7CiAgICBoZWlnaHRfID0gY2FudmFzX2hlaWdodF8gKiAyOwoKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgdnR4X3NoYWRlcl9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2RlcHRoLnZlcnQiKTsKICAgIHN0YXRpYyBjb25zdCBzdHJpbmcgZnJnX3NoYWRlcl9maWxlbmFtZShHTE1BUktfREFUQV9QQVRIIi9zaGFkZXJzL2RlcHRoLmZyYWciKTsKCiAgICBTaGFkZXJTb3VyY2UgdnR4X3NvdXJjZSh2dHhfc2hhZGVyX2ZpbGVuYW1lKTsKICAgIFNoYWRlclNvdXJjZSBmcmdfc291cmNlKGZyZ19zaGFkZXJfZmlsZW5hbWUpOwoKICAgIGlmICghU2NlbmU6OmxvYWRfc2hhZGVyc19mcm9tX3N0cmluZ3MocHJvZ3JhbV8sIHZ0eF9zb3VyY2Uuc3RyKCksIGZyZ19zb3VyY2Uuc3RyKCkpKSB7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIGdsR2VuVGV4dHVyZXMoMSwgJnRleF8pOwogICAgZ2xCaW5kVGV4dHVyZShHTF9URVhUVVJFXzJELCB0ZXhfKTsKICAgIGdsVGV4UGFyYW1ldGVyaShHTF9URVhUVVJFXzJELCBHTF9URVhUVVJFX01JTl9GSUxURVIsIEdMX05FQVJFU1QpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfTUFHX0ZJTFRFUiwgR0xfTkVBUkVTVCk7CiAgICBnbFRleFBhcmFtZXRlcmkoR0xfVEVYVFVSRV8yRCwgR0xfVEVYVFVSRV9XUkFQX1MsIEdMX0NMQU1QX1RPX0VER0UpOwogICAgZ2xUZXhQYXJhbWV0ZXJpKEdMX1RFWFRVUkVfMkQsIEdMX1RFWFRVUkVfV1JBUF9ULCBHTF9DTEFNUF9UT19FREdFKTsKICAgIGdsVGV4SW1hZ2UyRChHTF9URVhUVVJFXzJELCAwLCBHTF9ERVBUSF9DT01QT05FTlQsIHdpZHRoXywgaGVpZ2h0XywgMCwKICAgICAgICAgICAgICAgICBHTF9ERVBUSF9DT01QT05FTlQsIEdMX1VOU0lHTkVEX0lOVCwgMCk7CiAgICBnbEJpbmRUZXh0dXJlKEdMX1RFWFRVUkVfMkQsIDApOwoKICAgIGdsR2VuRnJhbWVidWZmZXJzKDEsICZmYm9fKTsKICAgIGdsQmluZEZyYW1lYnVmZmVyKEdMX0ZSQU1FQlVGRkVSLCBmYm9fKTsKICAgIGdsRnJhbWVidWZmZXJUZXh0dXJlMkQoR0xfRlJBTUVCVUZGRVIsIEdMX0RFUFRIX0FUVEFDSE1FTlQsIEdMX1RFWFRVUkVfMkQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleF8sIDApOwogICAgdW5zaWduZWQgaW50IHN0YXR1cyA9IGdsQ2hlY2tGcmFtZWJ1ZmZlclN0YXR1cyhHTF9GUkFNRUJVRkZFUik7CiAgICBpZiAoc3RhdHVzICE9IEdMX0ZSQU1FQlVGRkVSX0NPTVBMRVRFKSB7CiAgICAgICAgTG9nOjplcnJvcigiRGVwdGhSZW5kZXJTdGF0ZTo6c2V0dXA6IGdsQ2hlY2tGcmFtZWJ1ZmZlclN0YXR1cyBmYWlsZWQgKDB4JXgpXG4iLCBzdGF0dXMpOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGdsQmluZEZyYW1lYnVmZmVyKEdMX0ZSQU1FQlVGRkVSLCAwKTsKCiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApEZXB0aFJlbmRlclRhcmdldDo6dGVhcmRvd24oKQp7CiAgICBwcm9ncmFtXy5zdG9wKCk7CiAgICBwcm9ncmFtXy5yZWxlYXNlKCk7CiAgICBpZiAodGV4XykgewogICAgICAgIGdsRGVsZXRlVGV4dHVyZXMoMSwgJnRleF8pOwogICAgICAgIHRleF8gPSAwOwogICAgfQogICAgaWYgKGZib18pIHsKICAgICAgICBnbERlbGV0ZUZyYW1lYnVmZmVycygxLCAmZmJvXyk7CiAgICAgICAgZmJvXyA9IDA7CiAgICB9Cn0KCnZvaWQKRGVwdGhSZW5kZXJUYXJnZXQ6OmVuYWJsZShjb25zdCBtYXQ0JiBtdnApCnsKICAgIHByb2dyYW1fLnN0YXJ0KCk7CiAgICBwcm9ncmFtX1siTW9kZWxWaWV3UHJvamVjdGlvbk1hdHJpeCJdID0gbXZwOwogICAgZ2xCaW5kRnJhbWVidWZmZXIoR0xfRlJBTUVCVUZGRVIsIGZib18pOwogICAgZ2xGcmFtZWJ1ZmZlclRleHR1cmUyRChHTF9GUkFNRUJVRkZFUiwgR0xfREVQVEhfQVRUQUNITUVOVCwgR0xfVEVYVFVSRV8yRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4XywgMCk7CiAgICBnbFZpZXdwb3J0KDAsIDAsIHdpZHRoXywgaGVpZ2h0Xyk7CiAgICBnbENvbG9yTWFzayhHTF9GQUxTRSwgR0xfRkFMU0UsIEdMX0ZBTFNFLCBHTF9GQUxTRSk7CiAgICBnbENsZWFyKEdMX0RFUFRIX0JVRkZFUl9CSVQpOwp9Cgp2b2lkIERlcHRoUmVuZGVyVGFyZ2V0OjpkaXNhYmxlKCkKewogICAgZ2xCaW5kRnJhbWVidWZmZXIoR0xfRlJBTUVCVUZGRVIsIDApOwogICAgZ2xWaWV3cG9ydCgwLCAwLCBjYW52YXNfd2lkdGhfLCBjYW52YXNfaGVpZ2h0Xyk7CiAgICBnbENvbG9yTWFzayhHTF9UUlVFLCBHTF9UUlVFLCBHTF9UUlVFLCBHTF9UUlVFKTsKfQoKY2xhc3MgU2hhZG93UHJpdmF0ZQp7CiAgICBDYW52YXMmIGNhbnZhc187CiAgICBEZXB0aFJlbmRlclRhcmdldCBkZXB0aFRhcmdldF87CiAgICBQcm9ncmFtIHByb2dyYW1fOwogICAgU3RhY2s0IG1vZGVsdmlld187CiAgICBTdGFjazQgcHJvamVjdGlvbl87CiAgICBNZXNoIG1lc2hfOwogICAgdmVjMyBjZW50ZXJWZWNfOwogICAgZmxvYXQgcmFkaXVzXzsKICAgIGZsb2F0IHJvdGF0aW9uXzsKICAgIGZsb2F0IHJvdGF0aW9uU3BlZWRfOwogICAgYm9vbCB1c2VWYm9fOwogICAgCnB1YmxpYzoKICAgIFNoYWRvd1ByaXZhdGUoQ2FudmFzJiBjYW52YXMpIDoKICAgICAgICBjYW52YXNfKGNhbnZhcyksCiAgICAgICAgcmFkaXVzXygwLjApLAogICAgICAgIHJvdGF0aW9uXygwLjApLAogICAgICAgIHJvdGF0aW9uU3BlZWRfKDM2LjApLAogICAgICAgIHVzZVZib18odHJ1ZSkge30KICAgIH5TaGFkb3dQcml2YXRlKCkge30KCiAgICBib29sIHNldHVwKG1hcDxzdHJpbmcsIFNjZW5lOjpPcHRpb24+JiBvcHRpb25zKTsKICAgIHZvaWQgdGVhcmRvd24oKTsKICAgIHZvaWQgdXBkYXRlKGRvdWJsZSBlbGFwc2VkVGltZSk7CiAgICB2b2lkIGRyYXcoKTsKfTsKCmJvb2wKU2hhZG93UHJpdmF0ZTo6c2V0dXAobWFwPHN0cmluZywgU2NlbmU6Ok9wdGlvbj4mIG9wdGlvbnMpCnsKICAgIC8vIFByb2dyYW0gb2JqZWN0IHNldHVwCiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIHZ0eF9zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9saWdodC1iYXNpYy52ZXJ0Iik7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIGZyZ19zaGFkZXJfZmlsZW5hbWUoR0xNQVJLX0RBVEFfUEFUSCIvc2hhZGVycy9saWdodC1iYXNpYy5mcmFnIik7CiAgICBzdGF0aWMgY29uc3QgdmVjNCBtYXRlcmlhbERpZmZ1c2UoMS4wZiwgMS4wZiwgMS4wZiwgMS4wZik7CgogICAgU2hhZGVyU291cmNlIHZ0eF9zb3VyY2UodnR4X3NoYWRlcl9maWxlbmFtZSk7CiAgICBTaGFkZXJTb3VyY2UgZnJnX3NvdXJjZShmcmdfc2hhZGVyX2ZpbGVuYW1lKTsKCiAgICB2dHhfc291cmNlLmFkZF9jb25zdCgiTGlnaHRTb3VyY2VQb3NpdGlvbiIsIGxpZ2h0UG9zaXRpb24pOwogICAgdnR4X3NvdXJjZS5hZGRfY29uc3QoIk1hdGVyaWFsRGlmZnVzZSIsIG1hdGVyaWFsRGlmZnVzZSk7CgogICAgaWYgKCFTY2VuZTo6bG9hZF9zaGFkZXJzX2Zyb21fc3RyaW5ncyhwcm9ncmFtXywgdnR4X3NvdXJjZS5zdHIoKSwgZnJnX3NvdXJjZS5zdHIoKSkpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgLy8gTW9kZWwgc2V0dXAKICAgIE1vZGVsOjpmaW5kX21vZGVscygpOwogICAgTW9kZWwgbW9kZWw7CiAgICBib29sIG1vZGVsTG9hZGVkID0gbW9kZWwubG9hZCgiaG9yc2UiKTsKCiAgICBpZighbW9kZWxMb2FkZWQpIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgbW9kZWwuY2FsY3VsYXRlX25vcm1hbHMoKTsKCiAgICAvLyBNZXNoIHNldHVwCiAgICB2ZWN0b3I8c3RkOjpwYWlyPE1vZGVsOjpBdHRyaWJUeXBlLCBpbnQ+ID4gYXR0cmliczsKICAgIGF0dHJpYnMucHVzaF9iYWNrKHN0ZDo6cGFpcjxNb2RlbDo6QXR0cmliVHlwZSwgaW50PihNb2RlbDo6QXR0cmliVHlwZVBvc2l0aW9uLCAzKSk7CiAgICBhdHRyaWJzLnB1c2hfYmFjayhzdGQ6OnBhaXI8TW9kZWw6OkF0dHJpYlR5cGUsIGludD4oTW9kZWw6OkF0dHJpYlR5cGVOb3JtYWwsIDMpKTsKICAgIG1vZGVsLmNvbnZlcnRfdG9fbWVzaChtZXNoXywgYXR0cmlicyk7CgogICAgdXNlVmJvXyA9IChvcHRpb25zWyJ1c2UtdmJvIl0udmFsdWUgPT0gInRydWUiKTsKICAgIGJvb2wgaW50ZXJsZWF2ZSA9IChvcHRpb25zWyJpbnRlcmxlYXZlIl0udmFsdWUgPT0gInRydWUiKTsKICAgIG1lc2hfLnZib191cGRhdGVfbWV0aG9kKE1lc2g6OlZCT1VwZGF0ZU1ldGhvZE1hcCk7CiAgICBtZXNoXy5pbnRlcmxlYXZlKGludGVybGVhdmUpOwoKICAgIGlmICh1c2VWYm9fKSB7CiAgICAgICAgbWVzaF8uYnVpbGRfdmJvKCk7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBtZXNoXy5idWlsZF9hcnJheSgpOwogICAgfQoKICAgIC8vIENhbGN1bGF0ZSBhIHByb2plY3Rpb24gbWF0cml4IHRoYXQgaXMgYSBnb29kIGZpdCBmb3IgdGhlIG1vZGVsCiAgICB2ZWMzIG1heFZlYyA9IG1vZGVsLm1heFZlYygpOwogICAgdmVjMyBtaW5WZWMgPSBtb2RlbC5taW5WZWMoKTsKICAgIHZlYzMgZGlmZlZlYyA9IG1heFZlYyAtIG1pblZlYzsKICAgIGNlbnRlclZlY18gPSBtYXhWZWMgKyBtaW5WZWM7CiAgICBjZW50ZXJWZWNfIC89IDIuMDsKICAgIGZsb2F0IGRpYW1ldGVyID0gZGlmZlZlYy5sZW5ndGgoKTsKICAgIHJhZGl1c18gPSBkaWFtZXRlciAvIDI7CiAgICBmbG9hdCBmb3Z5ID0gMi4wICogYXRhbmYocmFkaXVzXyAvICgyLjAgKyByYWRpdXNfKSk7CiAgICBmb3Z5IC89IE1fUEk7CiAgICBmb3Z5ICo9IDE4MC4wOwogICAgZmxvYXQgYXNwZWN0KHN0YXRpY19jYXN0PGZsb2F0PihjYW52YXNfLndpZHRoKCkpL3N0YXRpY19jYXN0PGZsb2F0PihjYW52YXNfLmhlaWdodCgpKSk7CiAgICBwcm9qZWN0aW9uXy5wZXJzcGVjdGl2ZShmb3Z5LCBhc3BlY3QsIDIuMCwgMi4wICsgZGlhbWV0ZXIpOwoKICAgIGlmICghZGVwdGhUYXJnZXRfLnNldHVwKGNhbnZhc18ud2lkdGgoKSwgY2FudmFzXy5oZWlnaHQoKSkpIHsKICAgICAgICBMb2c6OmVycm9yKCJGYWlsZWQgdG8gc2V0IHVwIHRoZSByZW5kZXIgdGFyZ2V0IGZvciB0aGUgZGVwdGggcGFzc1xuIik7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHJldHVybiB0cnVlOwp9CgoKdm9pZApTaGFkb3dQcml2YXRlOjp0ZWFyZG93bigpCnsKICAgIGRlcHRoVGFyZ2V0Xy50ZWFyZG93bigpOwogICAgcHJvZ3JhbV8uc3RvcCgpOwogICAgcHJvZ3JhbV8ucmVsZWFzZSgpOwogICAgbWVzaF8ucmVzZXQoKTsKfQoKdm9pZApTaGFkb3dQcml2YXRlOjp1cGRhdGUoZG91YmxlIGVsYXBzZWRUaW1lKQp7CiAgICByb3RhdGlvbl8gPSByb3RhdGlvblNwZWVkXyAqIGVsYXBzZWRUaW1lOwp9Cgp2b2lkClNoYWRvd1ByaXZhdGU6OmRyYXcoKQp7CiAgICAvLyBUbyBwZXJmb3JtIHRoZSBkZXB0aCBwYXNzLCBzZXQgdXAgdGhlIG1vZGVsLXZpZXcgdHJhbnNmb3JtYXRpb24gc28KICAgIC8vIHRoYXQgd2UncmUgbG9va2luZyBhdCB0aGUgaG9yc2UgZnJvbSB0aGUgbGlnaHQgcG9zaXRpb24uICBUaGF0IHdpbGwKICAgIC8vIGdpdmUgdXMgdGhlIGFwcHJvcHJpYXRlIHZpZXcgZm9yIHRoZSBzaGFkb3cuCiAgICBtb2RlbHZpZXdfLnB1c2goKTsKICAgIG1vZGVsdmlld18ubG9hZElkZW50aXR5KCk7CiAgICBtb2RlbHZpZXdfLmxvb2tBdChsaWdodFBvc2l0aW9uLngoKSwgbGlnaHRQb3NpdGlvbi55KCksIGxpZ2h0UG9zaXRpb24ueigpLAogICAgICAgICAgICAgICAgICAgICAgMC4wLCAwLjAsIDAuMCwKICAgICAgICAgICAgICAgICAgICAgIDAuMCwgMS4wLCAwLjApOwogICAgbW9kZWx2aWV3Xy5yb3RhdGUocm90YXRpb25fLCAwLjBmLCAxLjBmLCAwLjBmKTsKICAgIG1hdDQgbXZwKHByb2plY3Rpb25fLmdldEN1cnJlbnQoKSk7CiAgICBtdnAgKj0gbW9kZWx2aWV3Xy5nZXRDdXJyZW50KCk7CiAgICBtb2RlbHZpZXdfLnBvcCgpOwoKICAgIC8vIEVuYWJsZSB0aGUgZGVwdGggcmVuZGVyIHRhcmdldCB3aXRoIG91ciB0cmFuc2Zvcm1hdGlvbiBhbmQgcmVuZGVyLgogICAgZGVwdGhUYXJnZXRfLmVuYWJsZShtdnApOwogICAgdmVjdG9yPEdMaW50PiBhdHRyaWJfbG9jYXRpb25zOwogICAgYXR0cmliX2xvY2F0aW9ucy5wdXNoX2JhY2soZGVwdGhUYXJnZXRfLnByb2dyYW0oKVsicG9zaXRpb24iXS5sb2NhdGlvbigpKTsKICAgIGF0dHJpYl9sb2NhdGlvbnMucHVzaF9iYWNrKGRlcHRoVGFyZ2V0Xy5wcm9ncmFtKClbIm5vcm1hbCJdLmxvY2F0aW9uKCkpOwogICAgbWVzaF8uc2V0X2F0dHJpYl9sb2NhdGlvbnMoYXR0cmliX2xvY2F0aW9ucyk7CiAgICBpZiAodXNlVmJvXykgewogICAgICAgIG1lc2hfLnJlbmRlcl92Ym8oKTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIG1lc2hfLnJlbmRlcl9hcnJheSgpOwogICAgfQogICAgZGVwdGhUYXJnZXRfLmRpc2FibGUoKTsKCiAgICAvLyBUT0RPOiBHcm91bmQgcmVuZGVyaW5nIHVzaW5nIHRoZSBhYm92ZSBnZW5lcmF0ZWQgdGV4dHVyZS4uLgoKICAgIC8vIERyYXcgdGhlICJub3JtYWwiIHZpZXcgb2YgdGhlIGhvcnNlCiAgICBtb2RlbHZpZXdfLnB1c2goKTsKICAgIG1vZGVsdmlld18udHJhbnNsYXRlKC1jZW50ZXJWZWNfLngoKSwgLWNlbnRlclZlY18ueSgpLCAtKGNlbnRlclZlY18ueigpICsgMi4wICsgcmFkaXVzXykpOwogICAgbW9kZWx2aWV3Xy5yb3RhdGUocm90YXRpb25fLCAwLjBmLCAxLjBmLCAwLjBmKTsKICAgIG12cCA9IHByb2plY3Rpb25fLmdldEN1cnJlbnQoKTsKICAgIG12cCAqPSBtb2RlbHZpZXdfLmdldEN1cnJlbnQoKTsKCiAgICBwcm9ncmFtXy5zdGFydCgpOwogICAgcHJvZ3JhbV9bIk1vZGVsVmlld1Byb2plY3Rpb25NYXRyaXgiXSA9IG12cDsKCiAgICAvLyBMb2FkIHRoZSBOb3JtYWxNYXRyaXggdW5pZm9ybSBpbiB0aGUgc2hhZGVyLiBUaGUgTm9ybWFsTWF0cml4IGlzIHRoZQogICAgLy8gaW52ZXJzZSB0cmFuc3Bvc2Ugb2YgdGhlIG1vZGVsIHZpZXcgbWF0cml4LgogICAgTGliTWF0cml4OjptYXQ0IG5vcm1hbF9tYXRyaXgobW9kZWx2aWV3Xy5nZXRDdXJyZW50KCkpOwogICAgbm9ybWFsX21hdHJpeC5pbnZlcnNlKCkudHJhbnNwb3NlKCk7CiAgICBwcm9ncmFtX1siTm9ybWFsTWF0cml4Il0gPSBub3JtYWxfbWF0cml4OwogICAgYXR0cmliX2xvY2F0aW9ucy5jbGVhcigpOwogICAgYXR0cmliX2xvY2F0aW9ucy5wdXNoX2JhY2socHJvZ3JhbV9bInBvc2l0aW9uIl0ubG9jYXRpb24oKSk7CiAgICBhdHRyaWJfbG9jYXRpb25zLnB1c2hfYmFjayhwcm9ncmFtX1sibm9ybWFsIl0ubG9jYXRpb24oKSk7CiAgICBtZXNoXy5zZXRfYXR0cmliX2xvY2F0aW9ucyhhdHRyaWJfbG9jYXRpb25zKTsKICAgIGlmICh1c2VWYm9fKSB7CiAgICAgICAgbWVzaF8ucmVuZGVyX3ZibygpOwogICAgfQogICAgZWxzZSB7CiAgICAgICAgbWVzaF8ucmVuZGVyX2FycmF5KCk7CiAgICB9CgogICAgLy8gUGVyLWZyYW1lIGNsZWFudXAKICAgIG1vZGVsdmlld18ucG9wKCk7Cn0KClNjZW5lU2hhZG93OjpTY2VuZVNoYWRvdyhDYW52YXMmIGNhbnZhcykgOgogICAgU2NlbmUoY2FudmFzLCAic2hhZG93IiksCiAgICBwcml2XygwKQp7CiAgICBvcHRpb25zX1sidXNlLXZibyJdID0gU2NlbmU6Ok9wdGlvbigidXNlLXZibyIsICJ0cnVlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXaGV0aGVyIHRvIHVzZSBWQk9zIGZvciByZW5kZXJpbmciLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZhbHNlLHRydWUiKTsKICAgIG9wdGlvbnNfWyJpbnRlcmxlYXZlIl0gPSBTY2VuZTo6T3B0aW9uKCJpbnRlcmxlYXZlIiwgImZhbHNlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJXaGV0aGVyIHRvIGludGVybGVhdmUgdmVydGV4IGF0dHJpYnV0ZSBkYXRhIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmYWxzZSx0cnVlIik7Cn0KClNjZW5lU2hhZG93Ojp+U2NlbmVTaGFkb3coKQp7CiAgICBkZWxldGUgcHJpdl87Cn0KCmJvb2wKU2NlbmVTaGFkb3c6OnN1cHBvcnRlZChib29sIHNob3dfZXJyb3JzKQp7CiAgICBzdGF0aWMgY29uc3Qgc3RyaW5nIG9lc19kZXB0aF90ZXh0dXJlKCJHTF9PRVNfZGVwdGhfdGV4dHVyZSIpOwogICAgc3RhdGljIGNvbnN0IHN0cmluZyBhcmJfZGVwdGhfdGV4dHVyZSgiR0xfQVJCX2RlcHRoX3RleHR1cmUiKTsKICAgIGlmICghR0xFeHRlbnNpb25zOjpzdXBwb3J0KG9lc19kZXB0aF90ZXh0dXJlKSAmJgogICAgICAgICFHTEV4dGVuc2lvbnM6OnN1cHBvcnQoYXJiX2RlcHRoX3RleHR1cmUpKSB7CiAgICAgICAgaWYgKHNob3dfZXJyb3JzKSB7CiAgICAgICAgICAgIExvZzo6ZXJyb3IoIldlIGRvIG5vdCBoYXZlIHRoZSBkZXB0aCB0ZXh0dXJlIGV4dGVuc2lvbiEhIVxuIik7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQoKYm9vbApTY2VuZVNoYWRvdzo6bG9hZCgpCnsKICAgIHJ1bm5pbmdfID0gZmFsc2U7CiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApTY2VuZVNoYWRvdzo6dW5sb2FkKCkKewp9Cgpib29sClNjZW5lU2hhZG93OjpzZXR1cCgpCnsKICAgIC8vIElmIHRoZSBzY2VuZSBpc24ndCBzdXBwb3J0ZWQsIGRvbid0IGJvdGhlciB0byBnbyB0aHJvdWdoIHNldHVwLgogICAgaWYgKCFzdXBwb3J0ZWQoZmFsc2UpIHx8ICFTY2VuZTo6c2V0dXAoKSkKICAgIHsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CgogICAgcHJpdl8gPSBuZXcgU2hhZG93UHJpdmF0ZShjYW52YXNfKTsKICAgIGlmICghcHJpdl8tPnNldHVwKG9wdGlvbnNfKSkgewogICAgICAgIGRlbGV0ZSBwcml2XzsKICAgICAgICBwcml2XyA9IDA7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIC8vIFNldCBjb3JlIHNjZW5lIHRpbWluZyBhZnRlciBhY3R1YWwgaW5pdGlhbGl6YXRpb24gc28gd2UgZG9uJ3QgbWVhc3VyZQogICAgLy8gc2V0IHVwIHRpbWUuCiAgICBzdGFydFRpbWVfID0gVXRpbDo6Z2V0X3RpbWVzdGFtcF91cygpIC8gMTAwMDAwMC4wOwogICAgbGFzdFVwZGF0ZVRpbWVfID0gc3RhcnRUaW1lXzsKICAgIHJ1bm5pbmdfID0gdHJ1ZTsKCiAgICByZXR1cm4gdHJ1ZTsKfQoKdm9pZApTY2VuZVNoYWRvdzo6dGVhcmRvd24oKQp7CiAgICAvLyBBZGQgc2NlbmUtc3BlY2lmaWMgdGVhcmRvd24gaGVyZQogICAgcHJpdl8tPnRlYXJkb3duKCk7CiAgICBTY2VuZTo6dGVhcmRvd24oKTsKfQoKdm9pZApTY2VuZVNoYWRvdzo6dXBkYXRlKCkKewogICAgU2NlbmU6OnVwZGF0ZSgpOwogICAgLy8gQWRkIHNjZW5lLXNwZWNpZmljIHVwZGF0ZSBoZXJlCiAgICBwcml2Xy0+dXBkYXRlKGxhc3RVcGRhdGVUaW1lXyAtIHN0YXJ0VGltZV8pOwp9Cgp2b2lkClNjZW5lU2hhZG93OjpkcmF3KCkKewogICAgcHJpdl8tPmRyYXcoKTsKfQoKU2NlbmU6OlZhbGlkYXRpb25SZXN1bHQKU2NlbmVTaGFkb3c6OnZhbGlkYXRlKCkKewogICAgcmV0dXJuIFNjZW5lOjpWYWxpZGF0aW9uVW5rbm93bjsKfQo=