LyoqCiogQ29weXJpZ2h0IChDKSAyMDEzIGthbmdsaXFpYW5nICxrYW5nbGlxQDE2My5jb20KKgoqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOwoqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKKgoqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKKgoqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAoqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgoqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKi8KI2luY2x1ZGUgIk1lc3NhZ2VEZWNvZGVyLmgiCgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzc3RyZWFtPgojaW5jbHVkZSAiTWVzc2FnZUV4dC5oIgojaW5jbHVkZSAiTWVzc2FnZVN5c0ZsYWcuaCIKI2luY2x1ZGUgIlV0aWxBbGwuaCIKCm5hbWVzcGFjZSBybXEKewoKY29uc3QgY2hhciBNZXNzYWdlRGVjb2Rlcjo6TkFNRV9WQUxVRV9TRVBBUkFUT1IgPSAxOwpjb25zdCBjaGFyIE1lc3NhZ2VEZWNvZGVyOjpQUk9QRVJUWV9TRVBBUkFUT1IgPSAyOwpjb25zdCBpbnQgTWVzc2FnZURlY29kZXI6Ok1TR19JRF9MRU5HVEggPSA4ICsgODsKCmludCBNZXNzYWdlRGVjb2Rlcjo6TWVzc2FnZU1hZ2ljQ29kZVBvc3Rpb24gPSA0OwppbnQgTWVzc2FnZURlY29kZXI6Ok1lc3NhZ2VGbGFnUG9zdGlvbiA9IDE2OwppbnQgTWVzc2FnZURlY29kZXI6Ok1lc3NhZ2VQaHlzaWNPZmZzZXRQb3N0aW9uID0gMjg7CmludCBNZXNzYWdlRGVjb2Rlcjo6TWVzc2FnZVN0b3JlVGltZXN0YW1wUG9zdGlvbiA9IDU2OwoKc3RkOjpzdHJpbmcgTWVzc2FnZURlY29kZXI6OmNyZWF0ZU1lc3NhZ2VJZChzb2NrYWRkciYgYWRkciwgbG9uZyBsb25nIG9mZnNldCkKewogICAgc3RydWN0IHNvY2thZGRyX2luIHNhOwogICAgbWVtY3B5KCZzYSwgJmFkZHIsIHNpemVvZihzb2NrYWRkcikpOwogICAgc2Euc2luX2ZhbWlseSA9IEFGX0lORVQ7CgogICAgaW50IHBvcnQgPSBudG9ocyhzYS5zaW5fcG9ydCk7CiAgICBwb3J0ID0gaHRvbmwocG9ydCk7CiAgICBpbnQgaXAgPSBzYS5zaW5fYWRkci5zX2FkZHI7CgogICAgdW5zaWduZWQgY2hhciogYnVmID0gbmV3IHVuc2lnbmVkIGNoYXJbTVNHX0lEX0xFTkdUSF07CiAgICBvZmZzZXQgPSBoMm5sbChvZmZzZXQpOwogICAgbWVtY3B5KGJ1ZiwgJmlwLCA0KTsKICAgIG1lbWNweShidWYgKyA0LCAmcG9ydCwgNCk7CiAgICBtZW1jcHkoYnVmICsgOCwgJm9mZnNldCwgOCk7CgogICAgY2hhciogc3RyID0gbmV3IGNoYXJbMiAqIE1TR19JRF9MRU5HVEggKyAxXTsKICAgIG1lbXNldChzdHIsIDAsIDIgKiBNU0dfSURfTEVOR1RIICsgMSk7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBNU0dfSURfTEVOR1RIOyBpKyspCiAgICB7CiAgICAgICAgY2hhciB0bXBbM107CiAgICAgICAgdG1wWzJdID0gMDsKCiAgICAgICAgc25wcmludGYodG1wLCBzaXplb2YodG1wKSwgIiUwMlgiLCBidWZbaV0pOwogICAgICAgIHN0cm5jYXQoc3RyLCB0bXAsIHNpemVvZih0bXApKTsKICAgIH0KCiAgICBzdGQ6OnN0cmluZyByZXQgPSBzdHI7CgogICAgZGVsZXRlW10gYnVmOwogICAgZGVsZXRlW10gc3RyOwoKICAgIHJldHVybiByZXQ7Cn0KCk1lc3NhZ2VJZCBNZXNzYWdlRGVjb2Rlcjo6ZGVjb2RlTWVzc2FnZUlkKGNvbnN0IHN0ZDo6c3RyaW5nJiBtc2dJZCkKewogICAgc3RkOjpzdHJpbmcgaXBzdHIgPSBtc2dJZC5zdWJzdHIoMCwgOCk7CiAgICBzdGQ6OnN0cmluZyBwb3J0c3RyID0gbXNnSWQuc3Vic3RyKDgsIDgpOwogICAgc3RkOjpzdHJpbmcgb2Zmc2V0c3RyID0gbXNnSWQuc3Vic3RyKDE2KTsKCiAgICBjaGFyKiBlbmQ7CiAgICBpbnQgaXBpbnQgPSBzdHJ0b3VsKGlwc3RyLmNfc3RyKCksICZlbmQsIDE2KTsKICAgIGludCBwb3J0aW50ID0gc3RydG91bChwb3J0c3RyLmNfc3RyKCksICZlbmQsIDE2KTsKCiAgICBsb25nIGxvbmcgb2Zmc2V0ID0gVXRpbEFsbDo6aGV4c3RyMnVsbChvZmZzZXRzdHIuY19zdHIoKSk7CgogICAgb2Zmc2V0ID0gbjJobGwob2Zmc2V0KTsKCiAgICBwb3J0aW50ID0gbnRvaGwocG9ydGludCk7CiAgICBzaG9ydCBwb3J0ID0gcG9ydGludDsKCiAgICBzdHJ1Y3Qgc29ja2FkZHJfaW4gc2E7CiAgICBzYS5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgIHNhLnNpbl9wb3J0ID0gaHRvbnMocG9ydCk7CiAgICBzYS5zaW5fYWRkci5zX2FkZHIgPSBpcGludDsKCiAgICBzb2NrYWRkciBhZGRyOwogICAgbWVtY3B5KCZhZGRyLCAmc2EsIHNpemVvZihzb2NrYWRkcikpOwoKICAgIE1lc3NhZ2VJZCBpZChhZGRyLCBvZmZzZXQpOwoKICAgIHJldHVybiBpZDsKfQoKTWVzc2FnZUV4dCogTWVzc2FnZURlY29kZXI6OmRlY29kZShjb25zdCBjaGFyKiBwRGF0YSwgaW50IGxlbiwgaW50JiBvZmZzZXQpCnsKICAgIHJldHVybiBkZWNvZGUocERhdGEsIGxlbiwgb2Zmc2V0LCB0cnVlKTsKfQoKTWVzc2FnZUV4dCogTWVzc2FnZURlY29kZXI6OmRlY29kZShjb25zdCBjaGFyKiBwRGF0YSwgaW50IGxlbiwgaW50JiBvZmZzZXQsIGJvb2wgcmVhZEJvZHkpCnsKCU1lc3NhZ2VFeHQqIG1zZ0V4dCA9IE5VTEw7CgogICAgdHJ5CiAgICB7CiAgICAgICAgbXNnRXh0ID0gbmV3IE1lc3NhZ2VFeHQoKTsKCiAgICAgICAgLy8gMSBUT1RBTFNJWkUKICAgICAgICBpbnQgc3RvcmVTaXplOwogICAgICAgIG1lbWNweSgmc3RvcmVTaXplLCBwRGF0YSwgNCk7CiAgICAgICAgc3RvcmVTaXplID0gbnRvaGwoc3RvcmVTaXplKTsKCiAgICAgICAgbXNnRXh0LT5zZXRTdG9yZVNpemUoc3RvcmVTaXplKTsKCiAgICAgICAgLy8gMiBNQUdJQ0NPREUgc2l6ZW9mKGludCkKCiAgICAgICAgLy8gMyBCT0RZQ1JDCiAgICAgICAgaW50IGJvZHlDUkM7CiAgICAgICAgbWVtY3B5KCZib2R5Q1JDLCBwRGF0YSArIDIgKiBzaXplb2YoaW50KSwgNCk7CiAgICAgICAgYm9keUNSQyA9IG50b2hsKGJvZHlDUkMpOwogICAgICAgIG1zZ0V4dC0+c2V0Qm9keUNSQyhib2R5Q1JDKTsKCiAgICAgICAgLy8gNCBRVUVVRUlECiAgICAgICAgaW50IHF1ZXVlSWQ7CiAgICAgICAgbWVtY3B5KCZxdWV1ZUlkLCBwRGF0YSArIDMgKiBzaXplb2YoaW50KSwgNCk7CiAgICAgICAgcXVldWVJZCA9IG50b2hsKHF1ZXVlSWQpOwogICAgICAgIG1zZ0V4dC0+c2V0UXVldWVJZChxdWV1ZUlkKTsKCiAgICAgICAgLy8gNSBGTEFHCiAgICAgICAgaW50IGZsYWcgOwoKICAgICAgICBtZW1jcHkoJmZsYWcsIHBEYXRhICsgNCAqIHNpemVvZihpbnQpLCA0KTsKICAgICAgICBmbGFnID0gbnRvaGwoZmxhZyk7CgogICAgICAgIG1zZ0V4dC0+c2V0RmxhZyhmbGFnKTsKCiAgICAgICAgLy8gNiBRVUVVRU9GRlNFVAogICAgICAgIGxvbmcgbG9uZyBxdWV1ZU9mZnNldDsKICAgICAgICBtZW1jcHkoJnF1ZXVlT2Zmc2V0LCBwRGF0YSArIDUgKiBzaXplb2YoaW50KSwgOCk7CiAgICAgICAgcXVldWVPZmZzZXQgPSBuMmhsbChxdWV1ZU9mZnNldCk7CiAgICAgICAgbXNnRXh0LT5zZXRRdWV1ZU9mZnNldChxdWV1ZU9mZnNldCk7CgogICAgICAgIC8vIDcgUEhZU0lDQUxPRkZTRVQKICAgICAgICBsb25nIGxvbmcgcGh5c2ljT2Zmc2V0OwoKICAgICAgICBtZW1jcHkoJnBoeXNpY09mZnNldCwgcERhdGEgKyA3ICogc2l6ZW9mKGludCksIDgpOwogICAgICAgIHBoeXNpY09mZnNldCA9IG4yaGxsKHBoeXNpY09mZnNldCk7CiAgICAgICAgbXNnRXh0LT5zZXRDb21taXRMb2dPZmZzZXQocGh5c2ljT2Zmc2V0KTsKCiAgICAgICAgLy8gOCBTWVNGTEFHCiAgICAgICAgaW50IHN5c0ZsYWc7CgogICAgICAgIG1lbWNweSgmc3lzRmxhZywgcERhdGEgKyA5ICogc2l6ZW9mKGludCksIDQpOwogICAgICAgIHN5c0ZsYWcgPSBudG9obChzeXNGbGFnKTsKICAgICAgICBtc2dFeHQtPnNldFN5c0ZsYWcoc3lzRmxhZyk7CgogICAgICAgIC8vIDkgQk9STlRJTUVTVEFNUAogICAgICAgIGxvbmcgbG9uZyBib3JuVGltZVN0YW1wOwogICAgICAgIG1lbWNweSgmYm9yblRpbWVTdGFtcCwgcERhdGEgKyAxMCAqIHNpemVvZihpbnQpLCA4KTsKICAgICAgICBib3JuVGltZVN0YW1wID0gbjJobGwoYm9yblRpbWVTdGFtcCk7CgogICAgICAgIG1zZ0V4dC0+c2V0Qm9yblRpbWVzdGFtcChib3JuVGltZVN0YW1wKTsKCiAgICAgICAgLy8gMTAgQk9STkhPU1QKICAgICAgICBpbnQgYm9ybkhvc3Q7Ly9jMCBhOCAwMCA2OCAgMTkyLjE2OC4wLjEwNCBjMCBhOCAwMCA2OCAwMCAwMCBjNCAwNAogICAgICAgIG1lbWNweSgmYm9ybkhvc3QsIHBEYXRhICsgMTIgKiBzaXplb2YoaW50KSwgNCk7CgogICAgICAgIGludCBwb3J0OwogICAgICAgIG1lbWNweSgmcG9ydCwgcERhdGEgKyAxMyAqIHNpemVvZihpbnQpLCA0KTsKICAgICAgICBwb3J0ID0gbnRvaGwocG9ydCk7CgogICAgICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBzYTsKICAgICAgICBzYS5zaW5fZmFtaWx5ID0gQUZfSU5FVDsKICAgICAgICBzYS5zaW5fcG9ydCA9IGh0b25zKHBvcnQpOwogICAgICAgIHNhLnNpbl9hZGRyLnNfYWRkciA9IGJvcm5Ib3N0OwoKICAgICAgICBzb2NrYWRkciBib3JuQWRkcjsKICAgICAgICBtZW1jcHkoJmJvcm5BZGRyLCAmc2EsIHNpemVvZihzb2NrYWRkcikpOwogICAgICAgIG1zZ0V4dC0+c2V0Qm9ybkhvc3QoYm9ybkFkZHIpOwoKICAgICAgICAvLyAxMSBTVE9SRVRJTUVTVEFNUAogICAgICAgIGxvbmcgbG9uZyBzdG9yZVRpbWVzdGFtcDsKICAgICAgICBtZW1jcHkoJnN0b3JlVGltZXN0YW1wLCBwRGF0YSArIDE0ICogc2l6ZW9mKGludCksIDgpOwogICAgICAgIHN0b3JlVGltZXN0YW1wID0gbjJobGwoc3RvcmVUaW1lc3RhbXApOwogICAgICAgIG1zZ0V4dC0+c2V0U3RvcmVUaW1lc3RhbXAoc3RvcmVUaW1lc3RhbXApOwoKICAgICAgICAvLyAxMiBTVE9SRUhPU1QKICAgICAgICBpbnQgc3RvcmVIb3N0OwogICAgICAgIG1lbWNweSgmc3RvcmVIb3N0LCBwRGF0YSArIDE2ICogc2l6ZW9mKGludCksIDQpOwogICAgICAgIG1lbWNweSgmcG9ydCwgcERhdGEgKyAxNyAqIHNpemVvZihpbnQpLCA0KTsKICAgICAgICBwb3J0ID0gbnRvaGwocG9ydCk7CgogICAgICAgIHNhLnNpbl9mYW1pbHkgPSBBRl9JTkVUOwogICAgICAgIHNhLnNpbl9wb3J0ID0gaHRvbnMocG9ydCk7CiAgICAgICAgc2Euc2luX2FkZHIuc19hZGRyID0gc3RvcmVIb3N0OwoKICAgICAgICBzb2NrYWRkciBzdG9yZUFkZHI7CiAgICAgICAgbWVtY3B5KCZzdG9yZUFkZHIsICZzYSwgc2l6ZW9mKHNvY2thZGRyKSk7CgogICAgICAgIG1zZ0V4dC0+c2V0U3RvcmVIb3N0KHN0b3JlQWRkcik7CgogICAgICAgIC8vIDEzIFJFQ09OU1VNRVRJTUVTCiAgICAgICAgaW50IHJlY29uc3VtZVRpbWVzOwogICAgICAgIG1lbWNweSgmcmVjb25zdW1lVGltZXMsIHBEYXRhICsgMTggKiBzaXplb2YoaW50KSwgNCk7CiAgICAgICAgcmVjb25zdW1lVGltZXMgPSBudG9obChyZWNvbnN1bWVUaW1lcyk7CiAgICAgICAgbXNnRXh0LT5zZXRSZWNvbnN1bWVUaW1lcyhyZWNvbnN1bWVUaW1lcyk7CgogICAgICAgIC8vIDE0IFByZXBhcmVkIFRyYW5zYWN0aW9uIE9mZnNldAogICAgICAgIGxvbmcgbG9uZyBwcmVwYXJlZFRyYW5zYWN0aW9uT2Zmc2V0OwogICAgICAgIG1lbWNweSgmcHJlcGFyZWRUcmFuc2FjdGlvbk9mZnNldCwgcERhdGEgKyAxOSAqIHNpemVvZihpbnQpLCA4KTsKICAgICAgICBwcmVwYXJlZFRyYW5zYWN0aW9uT2Zmc2V0ID0gbjJobGwocHJlcGFyZWRUcmFuc2FjdGlvbk9mZnNldCk7CiAgICAgICAgbXNnRXh0LT5zZXRQcmVwYXJlZFRyYW5zYWN0aW9uT2Zmc2V0KHByZXBhcmVkVHJhbnNhY3Rpb25PZmZzZXQpOwoKICAgICAgICAvLyAxNSBCT0RZCiAgICAgICAgaW50IGJvZHlMZW4gPSAwOwogICAgICAgIG1lbWNweSgmYm9keUxlbiwgcERhdGEgKyAyMSAqIHNpemVvZihpbnQpLCA0KTsKICAgICAgICBib2R5TGVuID0gbnRvaGwoYm9keUxlbik7CgogICAgICAgIGlmIChib2R5TGVuID4gMCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChyZWFkQm9keSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29uc3QgY2hhciogYm9keSA9IHBEYXRhICsgMjIgKiBzaXplb2YoaW50KTsKICAgICAgICAgICAgICAgIGludCBuZXdCb2R5TGVuID0gYm9keUxlbjsKCiAgICAgICAgICAgICAgICAvLyB1bmNvbXByZXNzIGJvZHkKICAgICAgICAgICAgICAgIGlmICgoc3lzRmxhZyAmIE1lc3NhZ2VTeXNGbGFnOjpDb21wcmVzc2VkRmxhZykgPT0gTWVzc2FnZVN5c0ZsYWc6OkNvbXByZXNzZWRGbGFnKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIqIHBPdXQ7CiAgICAgICAgICAgICAgICAgICAgaW50IG91dExlbjsKCiAgICAgICAgICAgICAgICAgICAgaWYgKFV0aWxBbGw6OmRlY29tcHJlc3MoYm9keSwgYm9keUxlbiwgJnBPdXQsICZvdXRMZW4pKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgbXNnRXh0LT5zZXRCb2R5KChjaGFyKilwT3V0LCBvdXRMZW4pOwogICAgICAgICAgICAgICAgICAgICAgICBmcmVlKHBPdXQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBtc2dFeHQtPnNldEJvZHkoYm9keSwgbmV3Qm9keUxlbik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIG1zZ0V4dC0+c2V0Qm9keShib2R5LCBuZXdCb2R5TGVuKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKCiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIC8vIDE2IFRPUElDCiAgICAgICAgaW50IHRvcGljTGVuID0gKihwRGF0YSArIDIyICogc2l6ZW9mKGludCkgKyBib2R5TGVuKTsKCiAgICAgICAgY2hhciogdG1wID0gbmV3IGNoYXJbdG9waWNMZW4gKyAxXTsKCiAgICAgICAgbWVtY3B5KHRtcCwgcERhdGEgKyAyMiAqIHNpemVvZihpbnQpICsgYm9keUxlbiArIDEsIHRvcGljTGVuKTsKICAgICAgICB0bXBbdG9waWNMZW5dID0gMDsKICAgICAgICBzdGQ6OnN0cmluZyB0b3BpYyA9IHRtcDsKCiAgICAgICAgZGVsZXRlW10gdG1wOwoKICAgICAgICBtc2dFeHQtPnNldFRvcGljKHRvcGljKTsKCiAgICAgICAgLy8gMTcgcHJvcGVydGllcwogICAgICAgIHNob3J0IHByb3BlcnRpZXNMZW5ndGg7CiAgICAgICAgbWVtY3B5KCZwcm9wZXJ0aWVzTGVuZ3RoLCBwRGF0YSArIDIyICogc2l6ZW9mKGludCkgKyBib2R5TGVuICsgMSArIHRvcGljTGVuLCAyKTsKICAgICAgICBwcm9wZXJ0aWVzTGVuZ3RoID0gbnRvaHMocHJvcGVydGllc0xlbmd0aCk7CgogICAgICAgIGlmIChwcm9wZXJ0aWVzTGVuZ3RoID4gMCkKICAgICAgICB7CiAgICAgICAgICAgIGNoYXIqIHByb3BlcnRpZXMgPSBuZXcgY2hhcltwcm9wZXJ0aWVzTGVuZ3RoICsgMV07CiAgICAgICAgICAgIG1lbWNweShwcm9wZXJ0aWVzLCBwRGF0YSArIDIyICogc2l6ZW9mKGludCkgKyBib2R5TGVuICsgMSArIHRvcGljTGVuICsgMiwgcHJvcGVydGllc0xlbmd0aCk7CiAgICAgICAgICAgIHByb3BlcnRpZXNbcHJvcGVydGllc0xlbmd0aF0gPSAwOwogICAgICAgICAgICBzdGQ6OnN0cmluZyBwcm9wZXJ0aWVzU3RyaW5nID0gcHJvcGVydGllczsKICAgICAgICAgICAgc3RkOjptYXA8c3RkOjpzdHJpbmcsIHN0ZDo6c3RyaW5nPiBtYXA7CiAgICAgICAgICAgIHN0cmluZzJtZXNzYWdlUHJvcGVydGllcyhtYXAsIHByb3BlcnRpZXNTdHJpbmcpOwogICAgICAgICAgICBtc2dFeHQtPnNldFByb3BlcnRpZXMobWFwKTsKICAgICAgICAgICAgZGVsZXRlW10gcHJvcGVydGllczsKICAgICAgICB9CgogICAgICAgIG9mZnNldCA9IDIyICogc2l6ZW9mKGludCkgKyBib2R5TGVuICsgMSArIHRvcGljTGVuICsgMiArIHByb3BlcnRpZXNMZW5ndGg7CgogICAgICAgIC8vIM/7z6JJRAogICAgICAgIHN0ZDo6c3RyaW5nIG1zZ0lkID0gIGNyZWF0ZU1lc3NhZ2VJZChzdG9yZUFkZHIsIHBoeXNpY09mZnNldCk7CiAgICAgICAgbXNnRXh0LT5zZXRNc2dJZChtc2dJZCk7CgogICAgICAgIHJldHVybiBtc2dFeHQ7CiAgICB9CiAgICBjYXRjaCAoLi4uKQogICAgewogICAgCVJNUV9FUlJPUigiZGVjb2RlIGV4Y2VwdGlvbiIpOwoJCWlmIChtc2dFeHQpCgkJewoJCQlkZWxldGUgbXNnRXh0OwoJCQltc2dFeHQgPSBOVUxMOwoJCX0KICAgIH0KCiAgICByZXR1cm4gTlVMTDsKfQoKc3RkOjpsaXN0PE1lc3NhZ2VFeHQqPiBNZXNzYWdlRGVjb2Rlcjo6ZGVjb2Rlcyhjb25zdCBjaGFyKiBwRGF0YSwgaW50IGxlbikKewogICAgcmV0dXJuIGRlY29kZXMocERhdGEsIGxlbiwgdHJ1ZSk7Cn0KCnN0ZDo6bGlzdDxNZXNzYWdlRXh0Kj4gTWVzc2FnZURlY29kZXI6OmRlY29kZXMoY29uc3QgY2hhciogcERhdGEsIGludCBsZW4sIGJvb2wgcmVhZEJvZHkpCnsKICAgIHN0ZDo6bGlzdDxNZXNzYWdlRXh0Kj4gbGlzdDsKCiAgICBpbnQgb2Zmc2V0ID0gMDsKICAgIHdoaWxlIChvZmZzZXQgPCBsZW4pCiAgICB7CiAgICAgICAgaW50IHRtcDsKICAgICAgICBNZXNzYWdlRXh0KiBtc2cgPSBkZWNvZGUocERhdGEgKyBvZmZzZXQsIGxlbiwgdG1wKTsKICAgICAgICBsaXN0LnB1c2hfYmFjayhtc2cpOwogICAgICAgIG9mZnNldCArPSB0bXA7CiAgICB9CgogICAgcmV0dXJuIGxpc3Q7Cn0KCnN0ZDo6c3RyaW5nIE1lc3NhZ2VEZWNvZGVyOjptZXNzYWdlUHJvcGVydGllczJTdHJpbmcoY29uc3Qgc3RkOjptYXA8c3RkOjpzdHJpbmcsIHN0ZDo6c3RyaW5nPiYgcHJvcGVydGllcykKewogICAgc3RkOjpzdHJpbmdzdHJlYW0gc3M7CgogICAgc3RkOjptYXA8c3RkOjpzdHJpbmcsIHN0ZDo6c3RyaW5nPjo6Y29uc3RfaXRlcmF0b3IgaXQgPSBwcm9wZXJ0aWVzLmJlZ2luKCk7CgogICAgZm9yICg7IGl0ICE9IHByb3BlcnRpZXMuZW5kKCk7IGl0KyspCiAgICB7CiAgICAgICAgc3MgPDwgaXQtPmZpcnN0IDw8IE5BTUVfVkFMVUVfU0VQQVJBVE9SIDw8IGl0LT5zZWNvbmQgPDwgUFJPUEVSVFlfU0VQQVJBVE9SOwogICAgfQoKICAgIHJldHVybiBzcy5zdHIoKTsKfQoKdm9pZCBNZXNzYWdlRGVjb2Rlcjo6c3RyaW5nMm1lc3NhZ2VQcm9wZXJ0aWVzKHN0ZDo6bWFwPHN0ZDo6c3RyaW5nLCBzdGQ6OnN0cmluZz4mIHByb3BlcnRpZXMsCiAgICAgICAgc3RkOjpzdHJpbmcmIHByb3BlcnRpZXNTdHJpbmcpCnsKICAgIHN0ZDo6dmVjdG9yPHN0ZDo6c3RyaW5nPiBvdXQ7CiAgICBVdGlsQWxsOjpTcGxpdChvdXQsIHByb3BlcnRpZXNTdHJpbmcsIFBST1BFUlRZX1NFUEFSQVRPUik7CgogICAgZm9yIChzaXplX3QgaSA9IDA7IGkgPCBvdXQuc2l6ZSgpOyBpKyspCiAgICB7CiAgICAgICAgc3RkOjp2ZWN0b3I8c3RkOjpzdHJpbmc+IG91dFZhbHVlOwogICAgICAgIFV0aWxBbGw6OlNwbGl0KG91dFZhbHVlLCBvdXRbaV0sIE5BTUVfVkFMVUVfU0VQQVJBVE9SKTsKCiAgICAgICAgaWYgKG91dFZhbHVlLnNpemUoKSA9PSAyKQogICAgICAgIHsKICAgICAgICAgICAgcHJvcGVydGllc1tvdXRWYWx1ZVswXV0gPSBvdXRWYWx1ZVsxXTsKICAgICAgICB9CiAgICB9Cn0KCn0K