LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCioKKiAgIENvcHlyaWdodCAoQykgMTk5OS0yMDAzLCBJbnRlcm5hdGlvbmFsIEJ1c2luZXNzIE1hY2hpbmVzCiogICBDb3Jwb3JhdGlvbiBhbmQgb3RoZXJzLiAgQWxsIFJpZ2h0cyBSZXNlcnZlZC4KKgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKgogKiB1Y29udigxKTogYW4gaWNvbnYoMSktbGlrZSBjb252ZXJ0ZXIgdXNpbmcgSUNVLgogKgogKiBPcmlnaW5hbCBjb2RlIGJ5IEpvbmFzIFV0dGVyc3Ry9m0gPGpvbmFzLnV0dGVyc3Ryb21Adml0dHJhbi5ub3Jybm9kLnNlPgogKiBjb250cmlidXRlZCBpbiAxOTk5LgogKgogKiBDb252ZXJzaW9uIHRvIHRoZSBDIGNvbnZlcnNpb24gQVBJIGFuZCBtYW55IGltcHJvdmVtZW50cyBieQogKiBZdmVzIEFycm91eWUgPHl2ZXNAcmVhbG5hbWVzLmNvbT4sIGN1cnJlbnQgbWFpbnRhaW5lci4KICoKICogTWFya3VzIFNjaGVyZXIgbWFpbnRhaW5lciBmcm9tIDIwMDMuCiAqIFNlZSBzb3VyY2UgY29kZSByZXBvc2l0b3J5IGhpc3RvcnkgZm9yIGNoYW5nZXMuCiAqLwoKI2luY2x1ZGUgPHVuaWNvZGUvdXR5cGVzLmg+CiNpbmNsdWRlIDx1bmljb2RlL3VjbnYuaD4KI2luY2x1ZGUgPHVuaWNvZGUvdWVudW0uaD4KI2luY2x1ZGUgPHVuaWNvZGUvdW5pc3RyLmg+CiNpbmNsdWRlIDx1bmljb2RlL3RyYW5zbGl0Lmg+CiNpbmNsdWRlIDx1bmljb2RlL3VzZXQuaD4KI2luY2x1ZGUgPHVuaWNvZGUvdWNsZWFuLmg+CgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgoKI2luY2x1ZGUgImNtZW1vcnkuaCIKI2luY2x1ZGUgImNzdHJpbmcuaCIKI2luY2x1ZGUgInVzdHJmbXQuaCIKCiNpbmNsdWRlICJ1bmljb2RlL3V3bXNnLmgiCgojaWZkZWYgV0lOMzIKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8aW8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNlbmRpZgoKI2lmZGVmIFVDT05WTVNHX0xJTksKLyogYmVsb3cgZnJvbSB0aGUgUkVBRE1FICovCiNpbmNsdWRlICJ1bmljb2RlL3V0eXBlcy5oIgojaW5jbHVkZSAidW5pY29kZS91ZGF0YS5oIgpVX0NGVU5DIGNoYXIgdWNvbnZtc2dfZGF0W107CiNlbmRpZgoKI2RlZmluZSBMRU5HVEhPRihhcnJheSkgKGludDMyX3QpKHNpemVvZihhcnJheSkvc2l6ZW9mKChhcnJheSlbMF0pKQoKI2RlZmluZSBERUZBVUxUX0JVRlNaICAgNDA5NgojZGVmaW5lIFVDT05WTVNHICJ1Y29udm1zZyIKCnN0YXRpYyBVUmVzb3VyY2VCdW5kbGUgKmdCdW5kbGUgPSAwOyAgICAvKiBCdW5kbGUgY29udGFpbmluZyBtZXNzYWdlcy4gKi8KCi8qCiAqIEluaXRpYWxpemUgdGhlIG1lc3NhZ2UgYnVuZGxlIHNvIHRoYXQgbWVzc2FnZSBzdHJpbmdzIGNhbiBiZSBmZXRjaGVkCiAqIGJ5IHVfd21zZygpLgogKgogKi8KCnN0YXRpYyB2b2lkIGluaXRNc2coY29uc3QgY2hhciAqcG5hbWUpIHsKICAgIHN0YXRpYyBpbnQgcHMgPSAwOwoKICAgIGlmICghcHMpIHsKICAgICAgICBjaGFyIGRhdGFQYXRoWzIwNDhdOyAgICAgICAgLyogWFhYIFNsb3BweTogc2hvdWxkIGJlIFBBVEhfTUFYLiAqLwogICAgICAgIFVFcnJvckNvZGUgZXJyID0gVV9aRVJPX0VSUk9SOwoKICAgICAgICBwcyA9IDE7CgogICAgICAgIC8qIFNldCB1cCBvdXIgc3RhdGljIGRhdGEgLSBpZiBhbnkgKi8KI2lmZGVmIFVDT05WTVNHX0xJTksKICAgICAgICB1ZGF0YV9zZXRBcHBEYXRhKFVDT05WTVNHLCAoY29uc3Qgdm9pZCopIHVjb252bXNnX2RhdCwgJmVycik7CiAgICAgICAgaWYgKFVfRkFJTFVSRShlcnIpKSB7CiAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIiVzOiB3YXJuaW5nLCBwcm9ibGVtIGluc3RhbGxpbmcgb3VyIHN0YXRpYyByZXNvdXJjZSBidW5kbGUgZGF0YSB1Y29udm1zZzogJXMgLSB0cnlpbmcgYW55d2F5cy5cbiIsCiAgICAgICAgICAgICAgICAgIHBuYW1lLCB1X2Vycm9yTmFtZShlcnIpKTsKICAgICAgICAgIGVyciA9IFVfWkVST19FUlJPUjsgLyogSXQgbWF5IHN0aWxsIGZhaWwgKi8KICAgICAgICB9CiNlbmRpZgoKICAgICAgICAvKiBHZXQgbWVzc2FnZXMuICovCiAgICAgICAgZ0J1bmRsZSA9IHVfd21zZ19zZXRQYXRoKFVDT05WTVNHLCAmZXJyKTsKICAgICAgICBpZiAoVV9GQUlMVVJFKGVycikpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgIiVzOiB3YXJuaW5nOiBjb3VsZG4ndCBvcGVuIGJ1bmRsZSAlczogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgcG5hbWUsIFVDT05WTVNHLCB1X2Vycm9yTmFtZShlcnIpKTsKI2lmZGVmIFVDT05WTVNHX0xJTksKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgIiVzOiBzZXRBcHBEYXRhIHdhcyBjYWxsZWQsIGludGVybmFsIGRhdGEgJXMgZmFpbGVkIHRvIGxvYWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHBuYW1lLCBVQ09OVk1TRyk7CiNlbmRpZgogCiAgICAgICAgICAgIGVyciA9IFVfWkVST19FUlJPUjsKICAgICAgICAgICAgLyogdGhhdCB3YXMgdHJ5ICMxLCB0cnkgYWdhaW4gd2l0aCBhIHBhdGggKi8KICAgICAgICAgICAgdXBydl9zdHJjcHkoZGF0YVBhdGgsIHVfZ2V0RGF0YURpcmVjdG9yeSgpKTsKICAgICAgICAgICAgdXBydl9zdHJjYXQoZGF0YVBhdGgsIFVfRklMRV9TRVBfU1RSSU5HKTsKICAgICAgICAgICAgdXBydl9zdHJjYXQoZGF0YVBhdGgsIFVDT05WTVNHKTsKCiAgICAgICAgICAgIGdCdW5kbGUgPSB1X3dtc2dfc2V0UGF0aChkYXRhUGF0aCwgJmVycik7CiAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgIiVzOiB3YXJuaW5nOiBzdGlsbCBjb3VsZG4ndCBvcGVuIGJ1bmRsZSAlczogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgcG5hbWUsIGRhdGFQYXRoLCB1X2Vycm9yTmFtZShlcnIpKTsKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiJXM6IHdhcm5pbmc6IG1lc3NhZ2VzIHdpbGwgbm90IGJlIGRpc3BsYXllZFxuIiwgcG5hbWUpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9CgovKiBNYXBwaW5nIG9mIGNhbGxiYWNrIG5hbWVzIHRvIHRoZSBjYWxsYmFja3MgcGFzc2VkIHRvIHRoZSBjb252ZXJ0ZXIKICAgQVBJLiAqLwoKc3RhdGljIHN0cnVjdCBjYWxsYmFja19lbnQgewogICAgY29uc3QgY2hhciAqbmFtZTsKICAgIFVDb252ZXJ0ZXJGcm9tVUNhbGxiYWNrIGZyb211OwogICAgY29uc3Qgdm9pZCAqZnJvbXVjdHh0OwogICAgVUNvbnZlcnRlclRvVUNhbGxiYWNrIHRvdTsKICAgIGNvbnN0IHZvaWQgKnRvdWN0eHQ7Cn0gdHJhbnNjb2RlX2NhbGxiYWNrc1tdID0gewogICAgeyAic3Vic3RpdHV0ZSIsCiAgICAgIFVDTlZfRlJPTV9VX0NBTExCQUNLX1NVQlNUSVRVVEUsIDAsCiAgICAgIFVDTlZfVE9fVV9DQUxMQkFDS19TVUJTVElUVVRFLCAwIH0sCiAgICB7ICJza2lwIiwKICAgICAgVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfU0tJUCwgMCwKICAgICAgVUNOVl9UT19VX0NBTExCQUNLX1NLSVAsIDAgfSwKICAgIHsgInN0b3AiLAogICAgICBVQ05WX0ZST01fVV9DQUxMQkFDS19TVE9QLCAwLAogICAgICBVQ05WX1RPX1VfQ0FMTEJBQ0tfU1RPUCwgMCB9LAogICAgeyAiZXNjYXBlIiwKICAgICAgVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfRVNDQVBFLCAwLAogICAgICBVQ05WX1RPX1VfQ0FMTEJBQ0tfRVNDQVBFLCAwfSwKICAgIHsgImVzY2FwZS1pY3UiLAogICAgICBVQ05WX0ZST01fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX0lDVSwKICAgICAgVUNOVl9UT19VX0NBTExCQUNLX0VTQ0FQRSwgVUNOVl9FU0NBUEVfSUNVIH0sCiAgICB7ICJlc2NhcGUtamF2YSIsCiAgICAgIFVDTlZfRlJPTV9VX0NBTExCQUNLX0VTQ0FQRSwgVUNOVl9FU0NBUEVfSkFWQSwKICAgICAgVUNOVl9UT19VX0NBTExCQUNLX0VTQ0FQRSwgVUNOVl9FU0NBUEVfSkFWQSB9LAogICAgeyAiZXNjYXBlLWMiLAogICAgICBVQ05WX0ZST01fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX0MsCiAgICAgIFVDTlZfVE9fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX0MgfSwKICAgIHsgImVzY2FwZS14bWwiLAogICAgICBVQ05WX0ZST01fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX1hNTF9IRVgsCiAgICAgIFVDTlZfVE9fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX1hNTF9IRVggfSwKICAgIHsgImVzY2FwZS14bWwtaGV4IiwKICAgICAgVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfRVNDQVBFLCBVQ05WX0VTQ0FQRV9YTUxfSEVYLAogICAgICBVQ05WX1RPX1VfQ0FMTEJBQ0tfRVNDQVBFLCBVQ05WX0VTQ0FQRV9YTUxfSEVYIH0sCiAgICB7ICJlc2NhcGUteG1sLWRlYyIsCiAgICAgIFVDTlZfRlJPTV9VX0NBTExCQUNLX0VTQ0FQRSwgVUNOVl9FU0NBUEVfWE1MX0RFQywKICAgICAgVUNOVl9UT19VX0NBTExCQUNLX0VTQ0FQRSwgVUNOVl9FU0NBUEVfWE1MX0RFQyB9LAogICAgeyAiZXNjYXBlLXVuaWNvZGUiLCBVQ05WX0ZST01fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX1VOSUNPREUsCiAgICAgIFVDTlZfVE9fVV9DQUxMQkFDS19FU0NBUEUsIFVDTlZfRVNDQVBFX1VOSUNPREUgfQp9OwoKLyogUmV0dXJuIGEgcG9pbnRlciB0byBhIGNhbGxiYWNrIHJlY29yZCBnaXZlbiBpdHMgbmFtZS4gKi8KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgY2FsbGJhY2tfZW50ICpmaW5kQ2FsbGJhY2soY29uc3QgY2hhciAqbmFtZSkgewogICAgaW50IGksIGNvdW50ID0KICAgICAgICBzaXplb2YodHJhbnNjb2RlX2NhbGxiYWNrcykgLyBzaXplb2YoKnRyYW5zY29kZV9jYWxsYmFja3MpOwoKICAgIC8qIFdlJ2xsIGRvIGEgbGluZWFyIHNlYXJjaCwgdGhlcmUgYXJlbid0IG1hbnkgb2YgdGhlbSBhbmQgYnNlYXJjaCgpCiAgICAgICBtYXkgbm90IGJlIHRoYXQgcG9ydGFibGUuICovCgogICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyArK2kpIHsKICAgICAgICBpZiAoIXVwcnZfc3RyaWNtcChuYW1lLCB0cmFuc2NvZGVfY2FsbGJhY2tzW2ldLm5hbWUpKSB7CiAgICAgICAgICAgIHJldHVybiAmdHJhbnNjb2RlX2NhbGxiYWNrc1tpXTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCi8qIFByaW50IGNvbnZlcnRlciBpbmZvcm1hdGlvbi4gSWYgbG9va2ZvciBpcyBzZXQsIG9ubHkgdGhhdCBjb252ZXJ0ZXIgd2lsbAogICBiZSBwcmludGVkLCBvdGhlcndpc2UgYWxsIGNvbnZlcnRlcnMgd2lsbCBiZSBwcmludGVkLiBJZiBjYW5vbiBpcyBub24KICAgemVybywgdGFncyBhbmQgYWxpYXNlcyBmb3IgZWFjaCBjb252ZXJ0ZXIgYXJlIHByaW50ZWQgdG9vLCBpbiB0aGUgZm9ybWF0CiAgIGV4cGVjdGVkIGZvciBjb252cnRlcnMudHh0KDUpLiAqLwoKc3RhdGljIGludCBwcmludENvbnZlcnRlcnMoY29uc3QgY2hhciAqcG5hbWUsIGNvbnN0IGNoYXIgKmxvb2tmb3IsCiAgICBVQm9vbCBjYW5vbikKewogICAgVUVycm9yQ29kZSBlcnIgPSBVX1pFUk9fRVJST1I7CiAgICBpbnQzMl90IG51bTsKICAgIHVpbnQxNl90IG51bV9zdGRzOwogICAgY29uc3QgY2hhciAqKnN0ZHM7CgogICAgLyogSWYgdGhlcmUgaXMgYSBzcGVjaWZpZWQgbmFtZSwganVzdCBoYW5kbGUgdGhhdCBub3cuICovCgogICAgaWYgKGxvb2tmb3IpIHsKICAgICAgICBpZiAoIWNhbm9uKSB7CiAgICAgICAgICAgIHByaW50ZigiJXNcbiIsIGxvb2tmb3IpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9IGVsc2UgewogICAgICAgIC8qICBCZWNhdXNlIHdlIGFyZSBwcmludGluZyBhIGNhbm9uaWNhbCBuYW1lLCB3ZSBuZWVkIHRoZQogICAgICAgICAgICB0cnVlIGNvbnZlcnRlciBuYW1lLiBXZSd2ZSBkb25lIHRoYXQgYWxyZWFkeSBleGNlcHQgZm9yCiAgICAgICAgICAgIHRoZSBkZWZhdWx0IG5hbWUgKGJlY2F1c2Ugd2Ugd2FudCB0byBwcmludCB0aGUgZXhhY3QKICAgICAgICAgICAgbmFtZSBvbmUgd291bGQgZ2V0IHdoZW4gY2FsbGluZyB1Y252X2dldERlZmF1bHROYW1lKCkKICAgICAgICAgICAgaW4gbm9uLWNhbm9uIG1vZGUpLiBCdXQgc2luY2Ugd2UgZG8gbm90IGtub3cgYXQgdGhpcwogICAgICAgICAgICBwb2ludCBpZiB3ZSBoYXZlIHRoZSBkZWZhdWx0IG5hbWUgb3Igc29tZXRoaW5nIGVsc2UsIHdlCiAgICAgICAgICAgIG5lZWQgdG8gbm9ybWFsaXplIGFnYWluIHRvIHRoZSBjYW5vbmljYWwgY29udmVydGVyCiAgICAgICAgICAgIG5hbWUuICovCgogICAgICAgICAgICBjb25zdCBjaGFyICp0cnVlbmFtZSA9IHVjbnZfZ2V0QWxpYXMobG9va2ZvciwgMCwgJmVycik7CiAgICAgICAgICAgIGlmIChVX1NVQ0NFU1MoZXJyKSkgewogICAgICAgICAgICAgICAgbG9va2ZvciA9IHRydWVuYW1lOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZXJyID0gVV9aRVJPX0VSUk9SOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qIFByaW50IGNvbnZlcnRlciBuYW1lcy4gV2UgY29tZSBoZXJlIGZvciBvbmUgb2YgdHdvIHJlYXNvbnM6IHdlCiAgICAgICBhcmUgcHJpbnRpbmcgYWxsIHRoZSBuYW1lcyAobG9va2ZvciB3YXMgbnVsbCksIG9yIHdlIGhhdmUgYQogICAgICAgc2luZ2xlIGNvbnZlcnRlciB0byBwcmludCBidXQgaW4gY2Fub24gbW9kZSwgaGVuY2Ugd2UgbmVlZCB0bwogICAgICAgZ2V0IHRvIGl0IGluIG9yZGVyIHRvIHByaW50IGV2ZXJ5dGhpbmcuICovCgogICAgbnVtID0gdWNudl9jb3VudEF2YWlsYWJsZSgpOwogICAgaWYgKG51bSA8PSAwKSB7CiAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgdV93bXNnKHN0ZGVyciwgImNhbnRHZXROYW1lcyIpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIGlmIChsb29rZm9yKSB7CiAgICAgICAgbnVtID0gMTsgICAgICAgICAgICAgICAgLyogV2Uga25vdyB3aGVyZSB3ZSB3YW50IHRvIGJlLiAqLwogICAgfQoKICAgIG51bV9zdGRzID0gdWNudl9jb3VudFN0YW5kYXJkcygpOwogICAgc3RkcyA9IChjb25zdCBjaGFyICoqKSB1cHJ2X21hbGxvYyhudW1fc3RkcyAqIHNpemVvZigqc3RkcykpOwogICAgaWYgKCFzdGRzKSB7CiAgICAgICAgdV93bXNnKHN0ZGVyciwgImNhbnRHZXRUYWciLCB1X3dtc2dfZXJyb3JOYW1lKFVfTUVNT1JZX0FMTE9DQVRJT05fRVJST1IpKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9IGVsc2UgewogICAgICAgIHVpbnQxNl90IHM7CgogICAgICAgIGlmIChjYW5vbikgewogICAgICAgICAgICBwcmludGYoInsgIik7CiAgICAgICAgfQogICAgICAgIGZvciAocyA9IDA7IHMgPCBudW1fc3RkczsgKytzKSB7CiAgICAgICAgICAgIHN0ZHNbc10gPSB1Y252X2dldFN0YW5kYXJkKHMsICZlcnIpOwogICAgICAgICAgICBpZiAoY2Fub24pIHsKICAgICAgICAgICAgICAgIHByaW50ZigiJXMgIiwgc3Rkc1tzXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKFVfRkFJTFVSRShlcnIpKSB7CiAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudEdldFRhZyIsIHVfd21zZ19lcnJvck5hbWUoZXJyKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGNhbm9uKSB7CiAgICAgICAgICAgIHB1dHMoIn0iKTsKICAgICAgICB9CiAgICB9CgogICAgZm9yIChpbnQzMl90IGkgPSAwOyBpIDwgbnVtOyBpKyspIHsKICAgICAgICBjb25zdCBjaGFyICpuYW1lOwogICAgICAgIHVpbnQxNl90IG51bV9hbGlhc2VzOwoKICAgICAgICAvKiBTZXQgdGhlIG5hbWUgZWl0aGVyIHRvIHdoYXQgd2UgYXJlIGxvb2tpbmcgZm9yLCBvcgogICAgICAgIHRvIHRoZSBjdXJyZW50IGNvbnZlcnRlciBuYW1lLiAqLwoKICAgICAgICBpZiAobG9va2ZvcikgewogICAgICAgICAgICBuYW1lID0gbG9va2ZvcjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBuYW1lID0gdWNudl9nZXRBdmFpbGFibGVOYW1lKGkpOwogICAgICAgIH0KCiAgICAgICAgLyogR2V0IGFsbCB0aGUgYWxpYXNlcyBhc3NvY2lhdGVkIHRvIHRoZSBuYW1lLiAqLwoKICAgICAgICBlcnIgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgbnVtX2FsaWFzZXMgPSB1Y252X2NvdW50QWxpYXNlcyhuYW1lLCAmZXJyKTsKICAgICAgICBpZiAoVV9GQUlMVVJFKGVycikpIHsKICAgICAgICAgICAgcHJpbnRmKCIlcyIsIG5hbWUpOwoKICAgICAgICAgICAgVW5pY29kZVN0cmluZyBzdHIobmFtZSwgIiIpOwogICAgICAgICAgICBwdXRjaGFyKCdcdCcpOwogICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudEdldEFsaWFzZXMiLCBzdHIuZ2V0VGVybWluYXRlZEJ1ZmZlcigpLAogICAgICAgICAgICAgICAgdV93bXNnX2Vycm9yTmFtZShlcnIpKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHVpbnQxNl90IGEsIHMsIHQ7CgogICAgICAgICAgICAvKiBXcml0ZSBhbGwgdGhlIGFsaWFzZXMgYW5kIHRoZWlyIHRhZ3MuICovCgogICAgICAgICAgICBmb3IgKGEgPSAwOyBhIDwgbnVtX2FsaWFzZXM7ICsrYSkgewogICAgICAgICAgICAgICAgY29uc3QgY2hhciAqYWxpYXMgPSB1Y252X2dldEFsaWFzKG5hbWUsIGEsICZlcnIpOwoKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKG5hbWUsICIiKTsKICAgICAgICAgICAgICAgICAgICBwdXRjaGFyKCdcdCcpOwogICAgICAgICAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50R2V0QWxpYXNlcyIsIHN0ci5nZXRUZXJtaW5hdGVkQnVmZmVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHVfd21zZ19lcnJvck5hbWUoZXJyKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIFByaW50IHRoZSBjdXJyZW50IGFsaWFzIHNvIHRoYXQgaXQgbG9va3MgcmlnaHQuICovCiAgICAgICAgICAgICAgICBwcmludGYoIiVzJXMlcyIsIChjYW5vbiA/IChhID09IDA/ICIiIDogIlx0IiApIDogIiIpICwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxpYXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjYW5vbiA/ICIiIDogIiAiKSk7CgogICAgICAgICAgICAgICAgLyogTG9vayAoc2xvd2x5LCBsaW5lYXIgc2VhcmNoaW5nKSBmb3IgYSB0YWcuICovCgogICAgICAgICAgICAgICAgaWYgKGNhbm9uKSB7CiAgICAgICAgICAgICAgICAgICAgLyogLTEgdG8gc2tpcCB0aGUgbGFzdCBzdGFuZGFyZCAqLwogICAgICAgICAgICAgICAgICAgIGZvciAocyA9IHQgPSAwOyBzIDwgbnVtX3N0ZHMtMTsgKytzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIFVFbnVtZXJhdGlvbiAqbmFtZUVudW0gPSB1Y252X29wZW5TdGFuZGFyZE5hbWVzKG5hbWUsIHN0ZHNbc10sICZlcnIpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoVV9TVUNDRVNTKGVycikpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIExpc3QgdGhlIHN0YW5kYXJkIHRhZ3MgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnN0YW5kYXJkTmFtZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVCb29sIGlzRmlyc3QgPSBUUlVFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSBlbnVtRXJyb3IgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoKHN0YW5kYXJkTmFtZSA9IHVlbnVtX25leHQobmFtZUVudW0sIE5VTEwsICZlbnVtRXJyb3IpKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNlZSBpZiB0aGlzIGFsaWFzIGlzIHN1cHBvcnRlZCBieSB0aGlzIHN0YW5kYXJkLiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghc3RyY21wKHN0YW5kYXJkTmFtZSwgYWxpYXMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCIgeyIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdCA9IDE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogUHJpbnQgYSAqIGFmdGVyIHRoZSBkZWZhdWx0IHN0YW5kYXJkIG5hbWUgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKCIgJXMlcyIsIHN0ZHNbc10sIChpc0ZpcnN0ID8gIioiIDogIiIpKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNGaXJzdCA9IEZBTFNFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICh0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ZigiIH0iKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAvKiBUZXJtaW5hdGUgdGhpcyBlbnRyeS4gKi8KICAgICAgICAgICAgICAgIGlmIChjYW5vbikgewogICAgICAgICAgICAgICAgICAgIHB1dHMoIiIpOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8qIE1vdmUgb24uICovCiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogVGVybWluYXRlIHRoaXMgZW50cnkuICovCiAgICAgICAgICAgIGlmICghY2Fub24pIHsKICAgICAgICAgICAgICAgIHB1dHMoIiIpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qIEZyZWUgdGVtcG9yYXJ5IGRhdGEuICovCgogICAgdXBydl9mcmVlKHN0ZHMpOwoKICAgIC8qIFN1Y2Nlc3MuICovCgogICAgcmV0dXJuIDA7Cn0KCi8qIFByaW50IGFsbCBhdmFpbGFibGUgdHJhbnNsaXRlcmF0b3JzLiBJZiBjYW5vbiBpcyBub24gemVybywgcHJpbnQKICAgb25lIHRyYW5zbGl0ZXJhdG9yIHBlciBsaW5lLiAqLwoKc3RhdGljIGludCBwcmludFRyYW5zbGl0ZXJhdG9ycyhVQm9vbCBjYW5vbikKewojaWYgVUNPTkZJR19OT19UUkFOU0xJVEVSQVRJT04KICAgIHByaW50Zigibm8gdHJhbnNsaXRlcmF0b3JzIGF2YWlsYWJsZSBiZWNhdXNlIG9mIFVDT05GSUdfTk9fVFJBTlNMSVRFUkFUSU9OLCBzZWUgdWNvbmZpZy5oXG4iKTsKICAgIHJldHVybiAxOwojZWxzZQogICAgaW50MzJfdCBudW10cmFucyA9IHV0cmFuc19jb3VudEF2YWlsYWJsZUlEcygpLCBpOwogICAgaW50IGJ1ZmxlbiA9IDUxMjsKICAgIGNoYXIgKmJ1ZiA9IChjaGFyICopIHVwcnZfbWFsbG9jKGJ1Zmxlbik7CiAgICBjaGFyIHN0YXRpY2J1Zls1MTJdOwoKICAgIGNoYXIgc2VwY2hhciA9IGNhbm9uID8gJ1xuJyA6ICcgJzsKCiAgICBpZiAoIWJ1ZikgewogICAgICAgIGJ1ZiA9IHN0YXRpY2J1ZjsKICAgICAgICBidWZsZW4gPSBzaXplb2Yoc3RhdGljYnVmKTsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtdHJhbnM7ICsraSkgewogICAgICAgIGludDMyX3QgbGVuID0gdXRyYW5zX2dldEF2YWlsYWJsZUlEKGksIGJ1ZiwgYnVmbGVuKTsKICAgICAgICBpZiAobGVuID49IGJ1ZmxlbiAtIDEpIHsKICAgICAgICAgICAgaWYgKGJ1ZiAhPSBzdGF0aWNidWYpIHsKICAgICAgICAgICAgICAgIGJ1ZmxlbiA8PD0gMTsKICAgICAgICAgICAgICAgIGlmIChidWZsZW4gPCBsZW4pIHsKICAgICAgICAgICAgICAgICAgICBidWZsZW4gPSBsZW4gKyA2NDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJ1ZiA9IChjaGFyICopIHVwcnZfcmVhbGxvYyhidWYsIGJ1Zmxlbik7CiAgICAgICAgICAgICAgICBpZiAoIWJ1ZikgewogICAgICAgICAgICAgICAgICAgIGJ1ZiA9IHN0YXRpY2J1ZjsKICAgICAgICAgICAgICAgICAgICBidWZsZW4gPSBzaXplb2Yoc3RhdGljYnVmKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB1dHJhbnNfZ2V0QXZhaWxhYmxlSUQoaSwgYnVmLCBidWZsZW4pOwogICAgICAgICAgICBpZiAobGVuID49IGJ1ZmxlbikgewogICAgICAgICAgICAgICAgdXBydl9zdHJjcHkoYnVmICsgYnVmbGVuIC0gNCwgIi4uLiIpOyAvKiBUcnVuY2F0ZSB0aGUgbmFtZS4gKi8KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcHJpbnRmKCIlcyIsIGJ1Zik7CiAgICAgICAgaWYgKGkgPCBudW10cmFucyAtIDEpIHsKICAgICAgICAgICAgcHV0Y2hhcihzZXBjaGFyKTsKICAgICAgICB9CiAgICB9CgogICAgLyogQWRkIGEgdGVybWluYXRpbmcgbmV3bGluZSBpZiBuZWVkZWQuICovCgogICAgaWYgKHNlcGNoYXIgIT0gJ1xuJykgewogICAgICAgIHB1dGNoYXIoJ1xuJyk7CiAgICB9CgogICAgLyogRnJlZSB0ZW1wb3JhcnkgZGF0YS4gKi8KCiAgICBpZiAoYnVmICE9IHN0YXRpY2J1ZikgewogICAgICAgIHVwcnZfZnJlZShidWYpOwogICAgfQoKICAgIC8qIFN1Y2Nlc3MuICovCgogICAgcmV0dXJuIDA7CiNlbmRpZgp9CgplbnVtIHsKICAgIHVTUCA9IDB4MjAsICAgICAgICAgLy8gc3BhY2UKICAgIHVDUiA9IDB4ZCwgICAgICAgICAgLy8gY2FycmlhZ2UgcmV0dXJuCiAgICB1TEYgPSAweGEsICAgICAgICAgIC8vIGxpbmUgZmVlZAogICAgdU5MID0gMHg4NSwgICAgICAgICAvLyBuZXdsaW5lCiAgICB1TFMgPSAweDIwMjgsICAgICAgIC8vIGxpbmUgc2VwYXJhdG9yCiAgICB1UFMgPSAweDIwMjksICAgICAgIC8vIHBhcmFncmFwaCBzZXBhcmF0b3IKICAgIHVTaWcgPSAweGZlZmYgICAgICAgLy8gc2lnbmF0dXJlL0JPTSBjaGFyYWN0ZXIKfTsKCnN0YXRpYyBpbmxpbmUgaW50MzJfdApnZXRDaHVua0xpbWl0KGNvbnN0IFVuaWNvZGVTdHJpbmcgJnByZXYsIGNvbnN0IFVuaWNvZGVTdHJpbmcgJnMpIHsKICAgIC8vIGZpbmQgb25lIG9mCiAgICAvLyBDUiwgTEYsIENSTEYsIE5MLCBMUywgUFMKICAgIC8vIGZvciBwYXJhZ3JhcGggZW5kcyAoc2VlIFVBWCAjMTMvVW5pY29kZSA0KQogICAgLy8gYW5kIGluY2x1ZGUgaXQgaW4gdGhlIGNodW5rCiAgICAvLyBhbGwgb2YgdGhlc2UgY2hhcmFjdGVycyBhcmUgb24gdGhlIEJNUAogICAgLy8gZG8gbm90IGluY2x1ZGUgRkYgb3IgVlQgaW4gY2FzZSB0aGV5IGFyZSBwYXJ0IG9mIGEgcGFyYWdyYXBoCiAgICAvLyAoaW1wb3J0YW50IGZvciBiaWRpIGNvbnRleHRzKQogICAgc3RhdGljIGNvbnN0IFVDaGFyIHBhcmFFbmRzW10gPSB7CiAgICAgICAgMHhkLCAweGEsIDB4ODUsIDB4MjAyOCwgMHgyMDI5CiAgICB9OwogICAgZW51bSB7CiAgICAgICAgaUNSLCBpTEYsIGlOTCwgaUxTLCBpUFMsIGlDb3VudAogICAgfTsKCiAgICAvLyBmaXJzdCwgc2VlIGlmIHRoZXJlIGlzIGEgQ1JMRiBzcGxpdCBiZXR3ZWVuIHByZXYgYW5kIHMKICAgIGlmIChwcmV2LmVuZHNXaXRoKHBhcmFFbmRzICsgaUNSLCAxKSkgewogICAgICAgIGlmIChzLnN0YXJ0c1dpdGgocGFyYUVuZHMgKyBpTEYsIDEpKSB7CiAgICAgICAgICAgIHJldHVybiAxOyAvLyBzcGxpdCBDUkxGLCBpbmNsdWRlIHRoZSBMRgogICAgICAgIH0gZWxzZSBpZiAoIXMuaXNFbXB0eSgpKSB7CiAgICAgICAgICAgIHJldHVybiAwOyAvLyBjb21wbGV0ZSB0aGUgbGFzdCBjaHVuawogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiAtMTsgLy8gd2FpdCBmb3IgYWN0dWFsIGZ1cnRoZXIgY29udGVudHMgdG8gYXJyaXZlCiAgICAgICAgfQogICAgfQoKICAgIGNvbnN0IFVDaGFyICp1ID0gcy5nZXRCdWZmZXIoKSwgKmxpbWl0ID0gdSArIHMubGVuZ3RoKCk7CiAgICBVQ2hhciBjOwoKICAgIHdoaWxlICh1IDwgbGltaXQpIHsKICAgICAgICBjID0gKnUrKzsKICAgICAgICBpZiAoCiAgICAgICAgICAgICgoYyA8IHVTUCkgJiYgKGMgPT0gdUNSIHx8IGMgPT0gdUxGKSkgfHwKICAgICAgICAgICAgKGMgPT0gdU5MKSB8fAogICAgICAgICAgICAoKGMgJiB1TFMpID09IHVMUykKICAgICAgICApIHsKICAgICAgICAgICAgaWYgKGMgPT0gdUNSKSB7CiAgICAgICAgICAgICAgICAvLyBjaGVjayBmb3IgQ1JMRgogICAgICAgICAgICAgICAgaWYgKHUgPT0gbGltaXQpIHsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7IC8vIExGIG1heSBiZSBpbiB0aGUgbmV4dCBjaHVuawogICAgICAgICAgICAgICAgfSBlbHNlIGlmICgqdSA9PSB1TEYpIHsKICAgICAgICAgICAgICAgICAgICArK3U7IC8vIGluY2x1ZGUgdGhlIExGIGluIHRoaXMgY2h1bmsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gKGludDMyX3QpKHUgLSBzLmdldEJ1ZmZlcigpKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIC0xOyAvLyBjb250aW51ZSBjb2xsZWN0aW5nIHRoZSBjaHVuawp9CgplbnVtIHsKICAgIENOVl9OT19GRUZGLCAgICAvLyBjYW5ub3QgY29udmVydCB0aGUgVStGRUZGIFVuaWNvZGUgc2lnbmF0dXJlIGNoYXJhY3RlciAoQk9NKQogICAgQ05WX1dJVEhfRkVGRiwgIC8vIGNhbiBjb252ZXJ0IHRoZSBVK0ZFRkYgc2lnbmF0dXJlIGNoYXJhY3RlcgogICAgQ05WX0FERFNfRkVGRiAgIC8vIGF1dG9tYXRpY2FsbHkgYWRkcy9kZXRlY3RzIHRoZSBVK0ZFRkYgc2lnbmF0dXJlIGNoYXJhY3Rlcgp9OwoKc3RhdGljIGlubGluZSBVQ2hhcgpuaWJibGVUb0hleCh1aW50OF90IG4pIHsKICAgIG4gJj0gMHhmOwogICAgcmV0dXJuCiAgICAgICAgbiA8PSA5ID8KICAgICAgICAgICAgKFVDaGFyKSgweDMwICsgbikgOgogICAgICAgICAgICAoVUNoYXIpKCgweDYxIC0gMTApICsgbik7Cn0KCi8vIGNoZWNrIHRoZSBjb252ZXJ0ZXIncyBVbmljb2RlIHNpZ25hdHVyZSBwcm9wZXJ0aWVzOwovLyB0aGUgZnJvbVVuaWNvZGUgc2lkZSBvZiB0aGUgY29udmVydGVyIG11c3QgYmUgaW4gaXRzIGluaXRpYWwgc3RhdGUKLy8gYW5kIHdpbGwgYmUgcmVzZXQgYWdhaW4gaWYgaXQgd2FzIHVzZWQKc3RhdGljIGludDMyX3QKY252U2lnVHlwZShVQ29udmVydGVyICpjbnYpIHsKICAgIFVFcnJvckNvZGUgZXJyOwogICAgaW50MzJfdCByZXN1bHQ7CgogICAgLy8gdGVzdCBpZiB0aGUgb3V0cHV0IGNoYXJzZXQgY2FuIGNvbnZlcnQgVStGRUZGCiAgICBVU2V0ICpzZXQgPSB1c2V0X29wZW4oMSwgMCk7CiAgICBlcnIgPSBVX1pFUk9fRVJST1I7CiAgICB1Y252X2dldFVuaWNvZGVTZXQoY252LCBzZXQsIFVDTlZfUk9VTkRUUklQX1NFVCwgJmVycik7CiAgICBpZiAoVV9TVUNDRVNTKGVycikgJiYgdXNldF9jb250YWlucyhzZXQsIHVTaWcpKSB7CiAgICAgICAgcmVzdWx0ID0gQ05WX1dJVEhfRkVGRjsKICAgIH0gZWxzZSB7CiAgICAgICAgcmVzdWx0ID0gQ05WX05PX0ZFRkY7IC8vIGFuIGVycm9yIG9jY3VycmVkIG9yIFUrRkVGRiBjYW5ub3QgYmUgY29udmVydGVkCiAgICB9CiAgICB1c2V0X2Nsb3NlKHNldCk7CgogICAgaWYgKHJlc3VsdCA9PSBDTlZfV0lUSF9GRUZGKSB7CiAgICAgICAgLy8gdGVzdCBpZiB0aGUgb3V0cHV0IGNoYXJzZXQgZW1pdHMgYSBzaWduYXR1cmUgYW55d2F5CiAgICAgICAgY29uc3QgVUNoYXIgYVsxXSA9IHsgMHg2MSB9OyAvLyAiYSIKICAgICAgICBjb25zdCBVQ2hhciAqaW47CgogICAgICAgIGNoYXIgYnVmZmVyWzIwXTsKICAgICAgICBjaGFyICpvdXQ7CgogICAgICAgIGluID0gYTsKICAgICAgICBvdXQgPSBidWZmZXI7CiAgICAgICAgZXJyID0gVV9aRVJPX0VSUk9SOwogICAgICAgIHVjbnZfZnJvbVVuaWNvZGUoY252LAogICAgICAgICAgICAmb3V0LCBidWZmZXIgKyBzaXplb2YoYnVmZmVyKSwKICAgICAgICAgICAgJmluLCBhICsgMSwKICAgICAgICAgICAgTlVMTCwgVFJVRSwgJmVycik7CiAgICAgICAgdWNudl9yZXNldEZyb21Vbmljb2RlKGNudik7CgogICAgICAgIGlmIChOVUxMICE9IHVjbnZfZGV0ZWN0VW5pY29kZVNpZ25hdHVyZShidWZmZXIsIChpbnQzMl90KShvdXQgLSBidWZmZXIpLCBOVUxMLCAmZXJyKSAmJgogICAgICAgICAgICBVX1NVQ0NFU1MoZXJyKQogICAgICAgICkgewogICAgICAgICAgICByZXN1bHQgPSBDTlZfQUREU19GRUZGOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVzdWx0Owp9CgpjbGFzcyBDb252ZXJ0RmlsZSB7CnB1YmxpYzoKICAgIENvbnZlcnRGaWxlKCkgOgogICAgICAgIGJ1ZihOVUxMKSwgb3V0YnVmKE5VTEwpLCBmcm9tb2Zmc2V0cyhOVUxMKSwKICAgICAgICBidWZzeigwKSwgc2lnbmF0dXJlKDApIHt9CgogICAgdm9pZAogICAgc2V0QnVmZmVyU2l6ZShzaXplX3QgYnVmZmVyU2l6ZSkgewogICAgICAgIGJ1ZnN6ID0gYnVmZmVyU2l6ZTsKCiAgICAgICAgYnVmID0gbmV3IGNoYXJbMiAqIGJ1ZnN6XTsKICAgICAgICBvdXRidWYgPSBidWYgKyBidWZzejsKCiAgICAgICAgLy8gKzEgZm9yIGFuIGFkZGVkIFUrRkVGRiBpbiB0aGUgaW50ZXJtZWRpYXRlIFVuaWNvZGUgYnVmZmVyCiAgICAgICAgZnJvbW9mZnNldHMgPSBuZXcgaW50MzJfdFtidWZzeiArIDFdOwogICAgfQoKICAgIH5Db252ZXJ0RmlsZSgpIHsKICAgICAgICBkZWxldGUgW10gYnVmOwogICAgICAgIGRlbGV0ZSBbXSBmcm9tb2Zmc2V0czsKICAgIH0KCiAgICBVQm9vbCBjb252ZXJ0RmlsZShjb25zdCBjaGFyICpwbmFtZSwKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmZyb21jcGFnZSwKICAgICAgICAgICAgICAgICAgICAgIFVDb252ZXJ0ZXJUb1VDYWxsYmFjayB0b3VjYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKnRvdWN0eHQsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b2NwYWdlLAogICAgICAgICAgICAgICAgICAgICAgVUNvbnZlcnRlckZyb21VQ2FsbGJhY2sgZnJvbXVjYWxsYmFjaywKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKmZyb211Y3R4dCwKICAgICAgICAgICAgICAgICAgICAgIFVCb29sIGZhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqdHJhbnNsaXQsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICppbmZpbGVzdHIsCiAgICAgICAgICAgICAgICAgICAgICBGSUxFICogb3V0ZmlsZSwgaW50IHZlcmJvc2UpOwpwcml2YXRlOgogICAgZnJpZW5kIGludCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndik7CgogICAgY2hhciAqYnVmLCAqb3V0YnVmOwogICAgaW50MzJfdCAqZnJvbW9mZnNldHM7CgogICAgc2l6ZV90IGJ1ZnN6OwogICAgaW50OF90IHNpZ25hdHVyZTsgLy8gYWRkICgxKSBvciByZW1vdmUgKC0xKSBhIFUrRkVGRiBVbmljb2RlIHNpZ25hdHVyZSBjaGFyYWN0ZXIKfTsKCi8vIENvbnZlcnQgYSBmaWxlIGZyb20gb25lIGVuY29kaW5nIHRvIGFub3RoZXIKVUJvb2wKQ29udmVydEZpbGU6OmNvbnZlcnRGaWxlKGNvbnN0IGNoYXIgKnBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZnJvbWNwYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgVUNvbnZlcnRlclRvVUNhbGxiYWNrIHRvdWNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqdG91Y3R4dCwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnRvY3BhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICBVQ29udmVydGVyRnJvbVVDYWxsYmFjayBmcm9tdWNhbGxiYWNrLAogICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqZnJvbXVjdHh0LAogICAgICAgICAgICAgICAgICAgICAgICAgVUJvb2wgZmFsbGJhY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0cmFuc2xpdCwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmluZmlsZXN0ciwKICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEUgKiBvdXRmaWxlLCBpbnQgdmVyYm9zZSkKewogICAgRklMRSAqaW5maWxlOwogICAgVUJvb2wgcmV0ID0gVFJVRTsKICAgIFVDb252ZXJ0ZXIgKmNvbnZmcm9tID0gMDsKICAgIFVDb252ZXJ0ZXIgKmNvbnZ0byA9IDA7CiAgICBVRXJyb3JDb2RlIGVyciA9IFVfWkVST19FUlJPUjsKICAgIFVCb29sIGZsdXNoOwogICAgY29uc3QgY2hhciAqY2J1ZnAsICpwcmV2YnVmcDsKICAgIGNoYXIgKmJ1ZnA7CgogICAgdWludDMyX3QgaW5mb2Zmc2V0ID0gMCwgb3V0Zm9mZnNldCA9IDA7ICAgLyogV2hlcmUgd2UgYXJlIGluIHRoZSBmaWxlLCBmb3IgZXJyb3IgcmVwb3J0aW5nLiAqLwoKICAgIGNvbnN0IFVDaGFyICp1bmlidWYsICp1bmlidWZicDsKICAgIFVDaGFyICp1bmlidWZwOwoKICAgIHNpemVfdCByZCwgd3I7CgojaWYgIVVDT05GSUdfTk9fVFJBTlNMSVRFUkFUSU9OCiAgICBUcmFuc2xpdGVyYXRvciAqdCA9IDA7ICAgICAgLy8gVHJhbnNsaXRlcmF0b3IgYWN0aW5nIG9uIFVuaWNvZGUgZGF0YS4KICAgIFVuaWNvZGVTdHJpbmcgY2h1bms7ICAgICAgICAvLyBPbmUgY2h1bmsgb2YgdGhlIHRleHQgYmVpbmcgY29sbGVjdGVkIGZvciB0cmFuc2Zvcm1hdGlvbi4KI2VuZGlmCiAgICBVbmljb2RlU3RyaW5nIHU7ICAgICAgICAgICAgLy8gU3RyaW5nIHRvIGRvIHRoZSB0cmFuc2xpdGVyYXRpb24uCiAgICBpbnQzMl90IHVsZW47CgogICAgLy8gdXNlIGNvbnZlcnNpb24gb2Zmc2V0cyBmb3IgZXJyb3IgbWVzc2FnZXMKICAgIC8vIHVubGVzcyBhIHRyYW5zbGl0ZXJhdG9yIGlzIHVzZWQgLQogICAgLy8gYSB0ZXh0IHRyYW5zZm9ybWF0aW9uIHdpbGwgcmVvcmRlciBjaGFyYWN0ZXJzIGluIHVucHJlZGljdGFibGUgd2F5cwogICAgVUJvb2wgdXNlT2Zmc2V0cyA9IFRSVUU7CgogICAgLy8gT3BlbiB0aGUgY29ycmVjdCBpbnB1dCBmaWxlIG9yIGNvbm5lY3QgdG8gc3RkaW4gZm9yIHJlYWRpbmcgaW5wdXQKCiAgICBpZiAoaW5maWxlc3RyICE9IDAgJiYgc3RyY21wKGluZmlsZXN0ciwgIi0iKSkgewogICAgICAgIGluZmlsZSA9IGZvcGVuKGluZmlsZXN0ciwgInJiIik7CiAgICAgICAgaWYgKGluZmlsZSA9PSAwKSB7CiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyMShpbmZpbGVzdHIsICIiKTsKICAgICAgICAgICAgc3RyMS5hcHBlbmQoKFVDaGFyMzIpIDApOwogICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cjIoc3RyZXJyb3IoZXJybm8pLCAiIik7CiAgICAgICAgICAgIHN0cjIuYXBwZW5kKChVQ2hhcjMyKSAwKTsKICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50T3BlbklucHV0RiIsIHN0cjEuZ2V0QnVmZmVyKCksIHN0cjIuZ2V0QnVmZmVyKCkpOwogICAgICAgICAgICByZXR1cm4gRkFMU0U7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBpbmZpbGVzdHIgPSAiLSI7CiAgICAgICAgaW5maWxlID0gc3RkaW47CiNpZmRlZiBXSU4zMgogICAgICAgIGlmIChzZXRtb2RlKGZpbGVubyhzdGRpbiksIE9fQklOQVJZKSA9PSAtMSkgewogICAgICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgImNhbnRTZXRJbkJpbk1vZGUiKTsKICAgICAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgICAgIH0KI2VuZGlmCiAgICB9CgogICAgaWYgKHZlcmJvc2UpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIiVzOlxuIiwgaW5maWxlc3RyKTsKICAgIH0KCiNpZiAhVUNPTkZJR19OT19UUkFOU0xJVEVSQVRJT04KICAgIC8vIENyZWF0ZSB0cmFuc2xpdGVyYXRvciBhcyBuZWVkZWQuCgogICAgaWYgKHRyYW5zbGl0ICE9IE5VTEwgJiYgKnRyYW5zbGl0KSB7CiAgICAgICAgVVBhcnNlRXJyb3IgcGFyc2U7CiAgICAgICAgVW5pY29kZVN0cmluZyBzdHIodHJhbnNsaXQpLCBwZXN0cjsKCiAgICAgICAgLyogQ3JlYXRlIGZyb20gcnVsZXMgb3IgYnkgSUQgYXMgbmVlZGVkLiAqLwoKICAgICAgICBwYXJzZS5saW5lID0gLTE7CgogICAgICAgIGlmICh1cHJ2X3N0cmNocih0cmFuc2xpdCwgJzonKSB8fCB1cHJ2X3N0cmNocih0cmFuc2xpdCwgJz4nKSB8fCB1cHJ2X3N0cmNocih0cmFuc2xpdCwgJzwnKSB8fCB1cHJ2X3N0cmNocih0cmFuc2xpdCwgJz4nKSkgewogICAgICAgICAgICB0ID0gVHJhbnNsaXRlcmF0b3I6OmNyZWF0ZUZyb21SdWxlcygiVWNvbnYiLCBzdHIsIFVUUkFOU19GT1JXQVJELCBwYXJzZSwgZXJyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0ID0gVHJhbnNsaXRlcmF0b3I6OmNyZWF0ZUluc3RhbmNlKHRyYW5zbGl0LCBVVFJBTlNfRk9SV0FSRCwgZXJyKTsKICAgICAgICB9CgogICAgICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgICAgICBzdHIuYXBwZW5kKChVQ2hhcjMyKSAwKTsKICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CgogICAgICAgICAgICBpZiAocGFyc2UubGluZSA+PSAwKSB7CiAgICAgICAgICAgICAgICBVQ2hhciBsaW5lYnVmWzIwXSwgb2Zmc2V0YnVmWzIwXTsKICAgICAgICAgICAgICAgIHVwcnZfaXRvdShsaW5lYnVmLCAyMCwgcGFyc2UubGluZSwgMTAsIDApOwogICAgICAgICAgICAgICAgdXBydl9pdG91KG9mZnNldGJ1ZiwgMjAsIHBhcnNlLm9mZnNldCwgMTAsIDApOwogICAgICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgImNhbnRDcmVhdGVUcmFuc2xpdFBhcnNlRXJyIiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSwKICAgICAgICAgICAgICAgICAgICB1X3dtc2dfZXJyb3JOYW1lKGVyciksIGxpbmVidWYsIG9mZnNldGJ1Zik7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudENyZWF0ZVRyYW5zbGl0Iiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSwKICAgICAgICAgICAgICAgICAgICB1X3dtc2dfZXJyb3JOYW1lKGVycikpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAodCkgewogICAgICAgICAgICAgICAgZGVsZXRlIHQ7CiAgICAgICAgICAgICAgICB0ID0gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBnb3RvIGVycm9yX2V4aXQ7CiAgICAgICAgfQoKICAgICAgICB1c2VPZmZzZXRzID0gRkFMU0U7CiAgICB9CiNlbmRpZgoKICAgIC8vIENyZWF0ZSBjb2RlcGFnZSBjb252ZXJ0ZXIuIElmIHRoZSBjb2RlcGFnZSBvciBpdHMgYWxpYXNlcyB3ZXJlbid0CiAgICAvLyBhdmFpbGFibGUsIGl0IHJldHVybnMgTlVMTCBhbmQgYSBmYWlsdXJlIGNvZGUuIFdlIGFsc28gc2V0IHRoZQogICAgLy8gY2FsbGJhY2tzLCBhbmQgcmV0dXJuIGVycm9ycyBpbiB0aGUgc2FtZSB3YXkuCgogICAgY29udmZyb20gPSB1Y252X29wZW4oZnJvbWNwYWdlLCAmZXJyKTsKICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKGZyb21jcGFnZSwgIiIpOwogICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50T3BlbkZyb21Db2Rlc2V0Iiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSwKICAgICAgICAgICAgdV93bXNnX2Vycm9yTmFtZShlcnIpKTsKICAgICAgICBnb3RvIGVycm9yX2V4aXQ7CiAgICB9CiAgICB1Y252X3NldFRvVUNhbGxCYWNrKGNvbnZmcm9tLCB0b3VjYWxsYmFjaywgdG91Y3R4dCwgMCwgMCwgJmVycik7CiAgICBpZiAoVV9GQUlMVVJFKGVycikpIHsKICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudFNldENhbGxiYWNrIiwgdV93bXNnX2Vycm9yTmFtZShlcnIpKTsKICAgICAgICBnb3RvIGVycm9yX2V4aXQ7CiAgICB9CgogICAgY29udnRvID0gdWNudl9vcGVuKHRvY3BhZ2UsICZlcnIpOwogICAgaWYgKFVfRkFJTFVSRShlcnIpKSB7CiAgICAgICAgVW5pY29kZVN0cmluZyBzdHIodG9jcGFnZSwgIiIpOwogICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50T3BlblRvQ29kZXNldCIsIHN0ci5nZXRUZXJtaW5hdGVkQnVmZmVyKCksCiAgICAgICAgICAgIHVfd21zZ19lcnJvck5hbWUoZXJyKSk7CiAgICAgICAgZ290byBlcnJvcl9leGl0OwogICAgfQogICAgdWNudl9zZXRGcm9tVUNhbGxCYWNrKGNvbnZ0bywgZnJvbXVjYWxsYmFjaywgZnJvbXVjdHh0LCAwLCAwLCAmZXJyKTsKICAgIGlmIChVX0ZBSUxVUkUoZXJyKSkgewogICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50U2V0Q2FsbGJhY2siLCB1X3dtc2dfZXJyb3JOYW1lKGVycikpOwogICAgICAgIGdvdG8gZXJyb3JfZXhpdDsKICAgIH0KICAgIHVjbnZfc2V0RmFsbGJhY2soY29udnRvLCBmYWxsYmFjayk7CgogICAgVUJvb2wgd2lsbGV4aXQsIGZyb21TYXdFbmRPZkJ5dGVzLCB0b1Nhd0VuZE9mVW5pY29kZTsKICAgIGludDhfdCBzaWc7CgogICAgLy8gT0ssIHdlIGNhbiBjb252ZXJ0IG5vdy4KICAgIHNpZyA9IHNpZ25hdHVyZTsKICAgIHJkID0gMDsKCiAgICBkbyB7CiAgICAgICAgd2lsbGV4aXQgPSBGQUxTRTsKCiAgICAgICAgLy8gaW5wdXQgZmlsZSBvZmZzZXQgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbmV4dCBidWZmZXIKICAgICAgICBpbmZvZmZzZXQgKz0gcmQ7CgogICAgICAgIHJkID0gZnJlYWQoYnVmLCAxLCBidWZzeiwgaW5maWxlKTsKICAgICAgICBpZiAoZmVycm9yKGluZmlsZSkgIT0gMCkgewogICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cihzdHJlcnJvcihlcnJubykpOwogICAgICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgImNhbnRSZWFkIiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSk7CiAgICAgICAgICAgIGdvdG8gZXJyb3JfZXhpdDsKICAgICAgICB9CgogICAgICAgIC8vIENvbnZlcnQgdGhlIHJlYWQgYnVmZmVyIGludG8gdGhlIG5ldyBlbmNvZGluZyB2aWEgVW5pY29kZS4KICAgICAgICAvLyBBZnRlciB0aGUgY2FsbCAndW5pYnVmcCcgd2lsbCBiZSBwbGFjZWQgYmVoaW5kIHRoZSBsYXN0CiAgICAgICAgLy8gY2hhcmFjdGVyIHRoYXQgd2FzIGNvbnZlcnRlZCBpbiB0aGUgJ3VuaWJ1ZicuCiAgICAgICAgLy8gQWxzbyB0aGUgJ2NidWZwJyBpcyBwb3NpdGlvbmVkIGJlaGluZCB0aGUgbGFzdCBjb252ZXJ0ZWQKICAgICAgICAvLyBjaGFyYWN0ZXIuCiAgICAgICAgLy8gQXQgdGhlIGxhc3QgY29udmVyc2lvbiBpbiB0aGUgZmlsZSwgZmx1c2ggc2hvdWxkIGJlIHNldCB0bwogICAgICAgIC8vIHRydWUgc28gdGhhdCB3ZSBnZXQgYWxsIGNoYXJhY3RlcnMgY29udmVydGVkLgogICAgICAgIC8vCiAgICAgICAgLy8gVGhlIGNvbnZlcnRlciBtdXN0IGJlIGZsdXNoZWQgYXQgdGhlIGVuZCBvZiBjb252ZXJzaW9uIHNvCiAgICAgICAgLy8gdGhhdCBjaGFyYWN0ZXJzIG9uIGhvbGQgYWxzbyB3aWxsIGJlIHdyaXR0ZW4uCgogICAgICAgIGNidWZwID0gYnVmOwogICAgICAgIGZsdXNoID0gKFVCb29sKShyZCAhPSBidWZzeik7CgogICAgICAgIC8vIGNvbnZlcnQgdW50aWwgdGhlIGlucHV0IGlzIGNvbnN1bWVkCiAgICAgICAgZG8gewogICAgICAgICAgICAvLyByZW1lbWJlciB0aGUgc3RhcnQgb2YgdGhlIGN1cnJlbnQgYnl0ZS10by1Vbmljb2RlIGNvbnZlcnNpb24KICAgICAgICAgICAgcHJldmJ1ZnAgPSBjYnVmcDsKCiAgICAgICAgICAgIHVuaWJ1ZiA9IHVuaWJ1ZnAgPSB1LmdldEJ1ZmZlcigoaW50MzJfdClidWZzeik7CgogICAgICAgICAgICAvLyBVc2UgYnVmc3ogaW5zdGVhZCBvZiB1LmdldENhcGFjaXR5KCkgZm9yIHRoZSB0YXJnZXRMaW1pdAogICAgICAgICAgICAvLyBzbyB0aGF0IHdlIGRvbid0IG92ZXJmbG93IGZyb21vZmZzZXRzW10uCiAgICAgICAgICAgIHVjbnZfdG9Vbmljb2RlKGNvbnZmcm9tLCAmdW5pYnVmcCwgdW5pYnVmICsgYnVmc3osICZjYnVmcCwKICAgICAgICAgICAgICAgIGJ1ZiArIHJkLCB1c2VPZmZzZXRzID8gZnJvbW9mZnNldHMgOiBOVUxMLCBmbHVzaCwgJmVycik7CgogICAgICAgICAgICB1bGVuID0gKGludDMyX3QpKHVuaWJ1ZnAgLSB1bmlidWYpOwogICAgICAgICAgICB1LnJlbGVhc2VCdWZmZXIodWxlbik7CgogICAgICAgICAgICAvLyBmcm9tU2F3RW5kT2ZCeXRlcyBpbmRpY2F0ZXMgdGhhdCB1Y252X3RvVW5pY29kZSgpIGlzIGRvbmUKICAgICAgICAgICAgLy8gY29udmVydGluZyBhbGwgb2YgdGhlIGlucHV0IGJ5dGVzLgogICAgICAgICAgICAvLyBJdCB3b3JrcyBsaWtlIHRoaXMgYmVjYXVzZSB1Y252X3RvVW5pY29kZSgpIHJldHVybnMgb25seSB1bmRlciB0aGUKICAgICAgICAgICAgLy8gZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAgICAgICAgICAgIC8vIC0gYW4gZXJyb3Igb2NjdXJyZWQgZHVyaW5nIGNvbnZlcnNpb24gKGFuIGVycm9yIGNvZGUgaXMgc2V0KQogICAgICAgICAgICAvLyAtIHRoZSB0YXJnZXQgYnVmZmVyIGlzIGZpbGxlZCAodGhlIGVycm9yIGNvZGUgaW5kaWNhdGVzIGFuIG92ZXJmbG93KQogICAgICAgICAgICAvLyAtIHRoZSBzb3VyY2UgaXMgY29uc3VtZWQKICAgICAgICAgICAgLy8gVGhhdCBpcywgaWYgdGhlIGVycm9yIGNvZGUgZG9lcyBub3QgaW5kaWNhdGUgYSBmYWlsdXJlLAogICAgICAgICAgICAvLyBub3QgZXZlbiBhbiBvdmVyZmxvdywgdGhlbiB0aGUgc291cmNlIG11c3QgYmUgY29uc3VtZWQgZW50aXJlbHkuCiAgICAgICAgICAgIGZyb21TYXdFbmRPZkJ5dGVzID0gKFVCb29sKVVfU1VDQ0VTUyhlcnIpOwoKICAgICAgICAgICAgaWYgKGVyciA9PSBVX0JVRkZFUl9PVkVSRkxPV19FUlJPUikgewogICAgICAgICAgICAgICAgZXJyID0gVV9aRVJPX0VSUk9SOwogICAgICAgICAgICB9IGVsc2UgaWYgKFVfRkFJTFVSRShlcnIpKSB7CiAgICAgICAgICAgICAgICBjaGFyIHBvc1szMl0sIGVycm9yQnl0ZXNbMzJdOwogICAgICAgICAgICAgICAgaW50OF90IGksIGxlbmd0aCwgZXJyb3JMZW5ndGg7CgogICAgICAgICAgICAgICAgVUVycm9yQ29kZSBsb2NhbEVycm9yID0gVV9aRVJPX0VSUk9SOwogICAgICAgICAgICAgICAgZXJyb3JMZW5ndGggPSAoaW50OF90KXNpemVvZihlcnJvckJ5dGVzKTsKICAgICAgICAgICAgICAgIHVjbnZfZ2V0SW52YWxpZENoYXJzKGNvbnZmcm9tLCBlcnJvckJ5dGVzLCAmZXJyb3JMZW5ndGgsICZsb2NhbEVycm9yKTsKICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUobG9jYWxFcnJvcikgfHwgZXJyb3JMZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgIGVycm9yTGVuZ3RoID0gMTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBwcmludCB0aGUgaW5wdXQgZmlsZSBvZmZzZXQgb2YgdGhlIHN0YXJ0IG9mIHRoZSBlcnJvciBieXRlczoKICAgICAgICAgICAgICAgIC8vIGlucHV0IGZpbGUgb2Zmc2V0IG9mIHRoZSBjdXJyZW50IGJ5dGUgYnVmZmVyICsKICAgICAgICAgICAgICAgIC8vIGxlbmd0aCBvZiB0aGUganVzdCBjb25zdW1lZCBieXRlcyAtCiAgICAgICAgICAgICAgICAvLyBsZW5ndGggb2YgdGhlIGVycm9yIGJ5dGVzCiAgICAgICAgICAgICAgICBsZW5ndGggPQogICAgICAgICAgICAgICAgICAgIChpbnQ4X3Qpc3ByaW50Zihwb3MsICIlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpKGluZm9mZnNldCArIChjYnVmcCAtIGJ1ZikgLSBlcnJvckxlbmd0aCkpOwoKICAgICAgICAgICAgICAgIC8vIG91dHB1dCB0aGUgYnl0ZXMgdGhhdCBjYXVzZWQgdGhlIGVycm9yCiAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cjsKICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBlcnJvckxlbmd0aDsgKytpKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGkgPiAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQoKFVDaGFyKXVTUCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQobmliYmxlVG9IZXgoKHVpbnQ4X3QpZXJyb3JCeXRlc1tpXSA+PiA0KSk7CiAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChuaWJibGVUb0hleCgodWludDhfdCllcnJvckJ5dGVzW2ldKSk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAicHJvYmxlbUN2dFRvVSIsCiAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcocG9zLCBsZW5ndGgsICIiKS5nZXRUZXJtaW5hdGVkQnVmZmVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5nZXRUZXJtaW5hdGVkQnVmZmVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgIHVfd21zZ19lcnJvck5hbWUoZXJyKSk7CgogICAgICAgICAgICAgICAgd2lsbGV4aXQgPSBUUlVFOwogICAgICAgICAgICAgICAgZXJyID0gVV9aRVJPX0VSUk9SOyAvKiByZXNldCB0aGUgZXJyb3IgZm9yIHRoZSByZXN0IG9mIHRoZSBjb252ZXJzaW9uLiAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBSZXBsYWNlZCBhIGNoZWNrIGZvciB3aGV0aGVyIHRoZSBpbnB1dCB3YXMgY29uc3VtZWQgYnkKICAgICAgICAgICAgLy8gbG9vcGluZyB1bnRpbCBpdCBpczsgbWVzc2FnZSBrZXkgInByZW1FbmRJbnB1dCIgbm93IG9ic29sZXRlLgoKICAgICAgICAgICAgaWYgKHVsZW4gPT0gMCkgewogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIHJlbW92ZSBhIFUrRkVGRiBVbmljb2RlIHNpZ25hdHVyZSBjaGFyYWN0ZXIgaWYgcmVxdWVzdGVkCiAgICAgICAgICAgIGlmIChzaWcgPCAwKSB7CiAgICAgICAgICAgICAgICBpZiAodS5jaGFyQXQoMCkgPT0gdVNpZykgewogICAgICAgICAgICAgICAgICAgIHUucmVtb3ZlKDAsIDEpOwoKICAgICAgICAgICAgICAgICAgICAvLyBhY2NvdW50IGZvciB0aGUgcmVtb3ZlZCBVQ2hhciBhbmQgb2Zmc2V0CiAgICAgICAgICAgICAgICAgICAgLS11bGVuOwoKICAgICAgICAgICAgICAgICAgICBpZiAodXNlT2Zmc2V0cykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyByZW1vdmUgYW4gb2Zmc2V0IGZyb20gZnJvbW9mZnNldHNbXSBhcyB3ZWxsCiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRvIGtlZXAgdGhlIGFycmF5IHBhcmFsbGVsIHdpdGggdGhlIFVDaGFycwogICAgICAgICAgICAgICAgICAgICAgICBtZW1tb3ZlKGZyb21vZmZzZXRzLCBmcm9tb2Zmc2V0cyArIDEsIHVsZW4gKiA0KTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc2lnID0gMDsKICAgICAgICAgICAgfQoKI2lmICFVQ09ORklHX05PX1RSQU5TTElURVJBVElPTgogICAgICAgICAgICAvLyBUcmFuc2xpdGVyYXRlL3RyYW5zZm9ybSBpZiBuZWVkZWQuCgogICAgICAgICAgICAvLyBGb3IgdHJhbnNmb3JtYXRpb24sIHdlIHVzZSBjaHVua2luZyBjb2RlIC0KICAgICAgICAgICAgLy8gY29sbGVjdCBVbmljb2RlIGlucHV0IHVudGlsLCBmb3IgZXhhbXBsZSwgYW4gZW5kLW9mLWxpbmUsCiAgICAgICAgICAgIC8vIHRoZW4gdHJhbnNmb3JtIGFuZCBvdXRwdXQtY29udmVydCB0aGF0IGFuZCBjb250aW51ZSBjb2xsZWN0aW5nLgogICAgICAgICAgICAvLyBUaGlzIG1ha2VzIHRoZSB0cmFuc2Zvcm1hdGlvbiByZXN1bHQgaW5kZXBlbmRlbnQgb2YgdGhlIGJ1ZmZlciBzaXplCiAgICAgICAgICAgIC8vIHdoaWxlIGF2b2lkaW5nIHRoZSBzbG93ZXIga2V5Ym9hcmQgbW9kZS4KICAgICAgICAgICAgLy8gVGhlIGVuZC1vZi1jaHVuayBjaGFyYWN0ZXJzIGFyZSBjb21wbGV0ZWx5IGluY2x1ZGVkIGluIHRoZQogICAgICAgICAgICAvLyB0cmFuc2Zvcm1lZCBzdHJpbmcgaW4gY2FzZSB0aGV5IGFyZSB0byBiZSB0cmFuc2Zvcm1lZCB0aGVtc2VsdmVzLgogICAgICAgICAgICBpZiAodCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIG91dDsKICAgICAgICAgICAgICAgIGludDMyX3QgY2h1bmtMaW1pdDsKCiAgICAgICAgICAgICAgICBkbyB7CiAgICAgICAgICAgICAgICAgICAgY2h1bmtMaW1pdCA9IGdldENodW5rTGltaXQoY2h1bmssIHUpOwogICAgICAgICAgICAgICAgICAgIGlmIChjaHVua0xpbWl0IDwgMCAmJiBmbHVzaCAmJiBmcm9tU2F3RW5kT2ZCeXRlcykgewogICAgICAgICAgICAgICAgICAgICAgICAvLyB1c2UgYWxsIG9mIHRoZSByZXN0IGF0IHRoZSBlbmQgb2YgdGhlIHRleHQKICAgICAgICAgICAgICAgICAgICAgICAgY2h1bmtMaW1pdCA9IHUubGVuZ3RoKCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmIChjaHVua0xpbWl0ID49IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29tcGxldGUgdGhlIGNodW5rIGFuZCB0cmFuc2Zvcm0gaXQKICAgICAgICAgICAgICAgICAgICAgICAgY2h1bmsuYXBwZW5kKHUsIDAsIGNodW5rTGltaXQpOwogICAgICAgICAgICAgICAgICAgICAgICB1LnJlbW92ZSgwLCBjaHVua0xpbWl0KTsKICAgICAgICAgICAgICAgICAgICAgICAgdC0+dHJhbnNsaXRlcmF0ZShjaHVuayk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBhcHBlbmQgdGhlIHRyYW5zZm9ybWF0aW9uIHJlc3VsdCB0byB0aGUgcmVzdWx0IGFuZCBlbXB0eSB0aGUgY2h1bmsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0LmFwcGVuZChjaHVuayk7CiAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLnJlbW92ZSgpOwogICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnRpbnVlIGNvbGxlY3RpbmcgdGhlIGNodW5rCiAgICAgICAgICAgICAgICAgICAgICAgIGNodW5rLmFwcGVuZCh1KTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSB3aGlsZSAoIXUuaXNFbXB0eSgpKTsKCiAgICAgICAgICAgICAgICB1ID0gb3V0OwogICAgICAgICAgICAgICAgdWxlbiA9IHUubGVuZ3RoKCk7CiAgICAgICAgICAgIH0KI2VuZGlmCgogICAgICAgICAgICAvLyBhZGQgYSBVK0ZFRkYgVW5pY29kZSBzaWduYXR1cmUgY2hhcmFjdGVyIGlmIHJlcXVlc3RlZAogICAgICAgICAgICAvLyBhbmQgcG9zc2libGUvbmVjZXNzYXJ5CiAgICAgICAgICAgIGlmIChzaWcgPiAwKSB7CiAgICAgICAgICAgICAgICBpZiAodS5jaGFyQXQoMCkgIT0gdVNpZyAmJiBjbnZTaWdUeXBlKGNvbnZ0bykgPT0gQ05WX1dJVEhfRkVGRikgewogICAgICAgICAgICAgICAgICAgIHUuaW5zZXJ0KDAsIChVQ2hhcil1U2lnKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHVzZU9mZnNldHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gaW5zZXJ0IGEgcHNldWRvLW9mZnNldCBpbnRvIGZyb21vZmZzZXRzW10gYXMgd2VsbAogICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBrZWVwIHRoZSBhcnJheSBwYXJhbGxlbCB3aXRoIHRoZSBVQ2hhcnMKICAgICAgICAgICAgICAgICAgICAgICAgbWVtbW92ZShmcm9tb2Zmc2V0cyArIDEsIGZyb21vZmZzZXRzLCB1bGVuICogNCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGZyb21vZmZzZXRzWzBdID0gLTE7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAvLyBhY2NvdW50IGZvciB0aGUgYWRkaXRpb25hbCBVQ2hhciBhbmQgb2Zmc2V0CiAgICAgICAgICAgICAgICAgICAgKyt1bGVuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc2lnID0gMDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgVW5pY29kZSBidWZmZXIgaW50byB0aGUgZGVzdGluYXRpb24gY29kZXBhZ2UKICAgICAgICAgICAgLy8gQWdhaW4gJ2J1ZnAnIHdpbGwgYmUgcGxhY2VkIGJlaGluZCB0aGUgbGFzdCBjb252ZXJ0ZWQgY2hhcmFjdGVyCiAgICAgICAgICAgIC8vIEFuZCAndW5pYnVmcCcgd2lsbCBiZSBwbGFjZWQgYmVoaW5kIHRoZSBsYXN0IGNvbnZlcnRlZCB1bmljb2RlIGNoYXJhY3RlcgogICAgICAgICAgICAvLyBBdCB0aGUgbGFzdCBjb252ZXJzaW9uIGZsdXNoIHNob3VsZCBiZSBzZXQgdG8gdHJ1ZSB0byBlbnN1cmUgdGhhdAogICAgICAgICAgICAvLyBhbGwgY2hhcmFjdGVycyBsZWZ0IGdldCBjb252ZXJ0ZWQKCiAgICAgICAgICAgIHVuaWJ1ZiA9IHVuaWJ1ZmJwID0gdS5nZXRCdWZmZXIoKTsKCiAgICAgICAgICAgIGRvIHsKICAgICAgICAgICAgICAgIGJ1ZnAgPSBvdXRidWY7CgogICAgICAgICAgICAgICAgLy8gVXNlIGZyb21TYXdFbmRPZkJ5dGVzIGluIGFkZGl0aW9uIHRvIHRoZSBmbHVzaCBmbGFnIC0KICAgICAgICAgICAgICAgIC8vIGl0IGluZGljYXRlcyB3aGV0aGVyIHRoZSBpbnRlcm1lZGlhdGUgVW5pY29kZSBzdHJpbmcKICAgICAgICAgICAgICAgIC8vIGNvbnRhaW5zIHRoZSB2ZXJ5IGxhc3QgVUNoYXJzIGZvciB0aGUgdmVyeSBsYXN0IGlucHV0IGJ5dGVzLgogICAgICAgICAgICAgICAgdWNudl9mcm9tVW5pY29kZShjb252dG8sICZidWZwLCBvdXRidWYgKyBidWZzeiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnVuaWJ1ZmJwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmlidWYgKyB1bGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAoVUJvb2wpKGZsdXNoICYmIGZyb21TYXdFbmRPZkJ5dGVzKSwgJmVycik7CgogICAgICAgICAgICAgICAgLy8gdG9TYXdFbmRPZlVuaWNvZGUgaW5kaWNhdGVzIHRoYXQgdWNudl9mcm9tVW5pY29kZSgpIGlzIGRvbmUKICAgICAgICAgICAgICAgIC8vIGNvbnZlcnRpbmcgYWxsIG9mIHRoZSBpbnRlcm1lZGlhdGUgVUNoYXJzLgogICAgICAgICAgICAgICAgLy8gU2VlIGNvbW1lbnQgZm9yIGZyb21TYXdFbmRPZkJ5dGVzLgogICAgICAgICAgICAgICAgdG9TYXdFbmRPZlVuaWNvZGUgPSAoVUJvb2wpVV9TVUNDRVNTKGVycik7CgogICAgICAgICAgICAgICAgaWYgKGVyciA9PSBVX0JVRkZFUl9PVkVSRkxPV19FUlJPUikgewogICAgICAgICAgICAgICAgICAgIGVyciA9IFVfWkVST19FUlJPUjsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoVV9GQUlMVVJFKGVycikpIHsKICAgICAgICAgICAgICAgICAgICBVQ2hhciBlcnJvclVDaGFyc1s0XTsKICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJ0YWc7CiAgICAgICAgICAgICAgICAgICAgY2hhciBwb3NbMzJdOwogICAgICAgICAgICAgICAgICAgIFVDaGFyMzIgYzsKICAgICAgICAgICAgICAgICAgICBpbnQ4X3QgaSwgbGVuZ3RoLCBlcnJvckxlbmd0aDsKCiAgICAgICAgICAgICAgICAgICAgVUVycm9yQ29kZSBsb2NhbEVycm9yID0gVV9aRVJPX0VSUk9SOwogICAgICAgICAgICAgICAgICAgIGVycm9yTGVuZ3RoID0gKGludDhfdClMRU5HVEhPRihlcnJvclVDaGFycyk7CiAgICAgICAgICAgICAgICAgICAgdWNudl9nZXRJbnZhbGlkVUNoYXJzKGNvbnZ0bywgZXJyb3JVQ2hhcnMsICZlcnJvckxlbmd0aCwgJmxvY2FsRXJyb3IpOwogICAgICAgICAgICAgICAgICAgIGlmIChVX0ZBSUxVUkUobG9jYWxFcnJvcikgfHwgZXJyb3JMZW5ndGggPT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAvLyBuZWVkIGF0IGxlYXN0IDEgc28gdGhhdCB3ZSBkb24ndCBhY2Nlc3MgYmV5b25kIHRoZSBsZW5ndGggb2YgZnJvbW9mZnNldHNbXQogICAgICAgICAgICAgICAgICAgICAgICBlcnJvckxlbmd0aCA9IDE7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBpbnQzMl90IGZlcnJvZmZzZXQ7CgogICAgICAgICAgICAgICAgICAgIGlmICh1c2VPZmZzZXRzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVuaWNvZGUgYnVmZmVyIG9mZnNldCBvZiB0aGUgc3RhcnQgb2YgdGhlIGVycm9yIFVDaGFycwogICAgICAgICAgICAgICAgICAgICAgICBmZXJyb2Zmc2V0ID0gKGludDMyX3QpKCh1bmlidWZicCAtIHVuaWJ1ZikgLSBlcnJvckxlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChmZXJyb2Zmc2V0IDwgMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYXBwcm94aW1hdGlvbiAtIHRoZSBjaGFyYWN0ZXIgc3RhcnRlZCBpbiB0aGUgcHJldmlvdXMgVW5pY29kZSBidWZmZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlcnJvZmZzZXQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvLyBnZXQgdGhlIGNvcnJlc3BvbmRpbmcgYnl0ZSBvZmZzZXQgb3V0IG9mIGZyb21vZmZzZXRzW10KICAgICAgICAgICAgICAgICAgICAgICAgLy8gZ28gYmFjayBpZiB0aGUgb2Zmc2V0IGlzIG5vdCBrbm93biBmb3Igc29tZSBvZiB0aGUgVUNoYXJzCiAgICAgICAgICAgICAgICAgICAgICAgIGludDMyX3QgZnJvbW9mZnNldDsKICAgICAgICAgICAgICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbW9mZnNldCA9IGZyb21vZmZzZXRzW2ZlcnJvZmZzZXRdOwogICAgICAgICAgICAgICAgICAgICAgICB9IHdoaWxlIChmcm9tb2Zmc2V0IDwgMCAmJiAtLWZlcnJvZmZzZXQgPj0gMCk7CgogICAgICAgICAgICAgICAgICAgICAgICAvLyB0b3RhbCBpbnB1dCBmaWxlIG9mZnNldCA9CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlucHV0IGZpbGUgb2Zmc2V0IG9mIHRoZSBjdXJyZW50IGJ5dGUgYnVmZmVyICsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gYnl0ZSBidWZmZXIgb2Zmc2V0IG9mIHdoZXJlIHRoZSBjdXJyZW50IFVuaWNvZGUgYnVmZmVyIGlzIGNvbnZlcnRlZCBmcm9tICsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gZnJvbW9mZnNldHNbVW5pY29kZSBvZmZzZXRdCiAgICAgICAgICAgICAgICAgICAgICAgIGZlcnJvZmZzZXQgPSBpbmZvZmZzZXQgKyAocHJldmJ1ZnAgLSBidWYpICsgZnJvbW9mZnNldDsKICAgICAgICAgICAgICAgICAgICAgICAgZXJydGFnID0gInByb2JsZW1DdnRGcm9tVSI7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgLy8gRG8gbm90IHVzZSBmcm9tb2Zmc2V0cyBpZiAodCAhPSBOVUxMKSBiZWNhdXNlIHRoZSBVbmljb2RlIHRleHQgbWF5CiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlIGRpZmZlcmVudCBmcm9tIHdoYXQgdGhlIG9mZnNldHMgcmVmZXIgdG8uCgogICAgICAgICAgICAgICAgICAgICAgICAvLyBvdXRwdXQgZmlsZSBvZmZzZXQKICAgICAgICAgICAgICAgICAgICAgICAgZmVycm9mZnNldCA9IChpbnQzMl90KShvdXRmb2Zmc2V0ICsgKGJ1ZnAgLSBvdXRidWYpKTsKICAgICAgICAgICAgICAgICAgICAgICAgZXJydGFnID0gInByb2JsZW1DdnRGcm9tVU91dCI7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSAoaW50OF90KXNwcmludGYocG9zLCAiJXUiLCBmZXJyb2Zmc2V0KTsKCiAgICAgICAgICAgICAgICAgICAgLy8gb3V0cHV0IHRoZSBjb2RlIHBvaW50cyB0aGF0IGNhdXNlZCB0aGUgZXJyb3IKICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cjsKICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgZXJyb3JMZW5ndGg7KSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpID4gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZCgoVUNoYXIpdVNQKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBVMTZfTkVYVChlcnJvclVDaGFycywgaSwgZXJyb3JMZW5ndGgsIGMpOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYyA+PSAweDEwMDAwMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChuaWJibGVUb0hleCgodWludDhfdCkoYyA+PiAyMCkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYyA+PSAweDEwMDAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKG5pYmJsZVRvSGV4KCh1aW50OF90KShjID4+IDE2KSkpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQobmliYmxlVG9IZXgoKHVpbnQ4X3QpKGMgPj4gMTIpKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0ci5hcHBlbmQobmliYmxlVG9IZXgoKHVpbnQ4X3QpKGMgPj4gOCkpKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3RyLmFwcGVuZChuaWJibGVUb0hleCgodWludDhfdCkoYyA+PiA0KSkpOwogICAgICAgICAgICAgICAgICAgICAgICBzdHIuYXBwZW5kKG5pYmJsZVRvSGV4KCh1aW50OF90KWMpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgICAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsIGVycnRhZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcocG9zLCBsZW5ndGgsICIiKS5nZXRUZXJtaW5hdGVkQnVmZmVyKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIuZ2V0VGVybWluYXRlZEJ1ZmZlcigpLAogICAgICAgICAgICAgICAgICAgICAgICAgICB1X3dtc2dfZXJyb3JOYW1lKGVycikpOwogICAgICAgICAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJlcnJvclVuaWNvZGUiLCBzdHIuZ2V0VGVybWluYXRlZEJ1ZmZlcigpKTsKCiAgICAgICAgICAgICAgICAgICAgd2lsbGV4aXQgPSBUUlVFOwogICAgICAgICAgICAgICAgICAgIGVyciA9IFVfWkVST19FUlJPUjsgLyogcmVzZXQgdGhlIGVycm9yIGZvciB0aGUgcmVzdCBvZiB0aGUgY29udmVyc2lvbi4gKi8KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBSZXBsYWNlZCBhIGNoZWNrIGZvciB3aGV0aGVyIHRoZSBpbnRlcm1lZGlhdGUgVW5pY29kZSBjaGFyYWN0ZXJzIHdlcmUgYWxsIGNvbnN1bWVkIGJ5CiAgICAgICAgICAgICAgICAvLyBsb29waW5nIHVudGlsIHRoZXkgYXJlOyBtZXNzYWdlIGtleSAicHJlbUVuZCIgbm93IG9ic29sZXRlLgoKICAgICAgICAgICAgICAgIC8vIEZpbmFsbHksIHdyaXRlIHRoZSBjb252ZXJ0ZWQgYnVmZmVyIHRvIHRoZSBvdXRwdXQgZmlsZQogICAgICAgICAgICAgICAgc2l6ZV90IG91dGxlbiA9IChzaXplX3QpIChidWZwIC0gb3V0YnVmKTsKICAgICAgICAgICAgICAgIG91dGZvZmZzZXQgKz0gKGludDMyX3QpKHdyID0gZndyaXRlKG91dGJ1ZiwgMSwgb3V0bGVuLCBvdXRmaWxlKSk7CiAgICAgICAgICAgICAgICBpZiAod3IgIT0gb3V0bGVuKSB7CiAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBzdHIoc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAiY2FudFdyaXRlIiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSk7CiAgICAgICAgICAgICAgICAgICAgd2lsbGV4aXQgPSBUUlVFOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmICh3aWxsZXhpdCkgewogICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3JfZXhpdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSB3aGlsZSAoIXRvU2F3RW5kT2ZVbmljb2RlKTsKICAgICAgICB9IHdoaWxlICghZnJvbVNhd0VuZE9mQnl0ZXMpOwogICAgfSB3aGlsZSAoIWZsdXNoKTsgICAgICAgICAgIC8vIFN0b3Agd2hlbiB3ZSBoYXZlIGZsdXNoZWQgdGhlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29udmVydGVycyAodGhpcyBtZWFucyB0aGF0IGl0J3MKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgZW5kIG9mIG91dHB1dCkKCiAgICBnb3RvIG5vcm1hbF9leGl0OwoKZXJyb3JfZXhpdDoKICAgIHJldCA9IEZBTFNFOwoKbm9ybWFsX2V4aXQ6CiAgICAvLyBDbGVhbnVwLgoKICAgIHVjbnZfY2xvc2UoY29udmZyb20pOwogICAgdWNudl9jbG9zZShjb252dG8pOwoKI2lmICFVQ09ORklHX05PX1RSQU5TTElURVJBVElPTgogICAgZGVsZXRlIHQ7CiNlbmRpZgoKICAgIGlmIChpbmZpbGUgIT0gc3RkaW4pIHsKICAgICAgICBmY2xvc2UoaW5maWxlKTsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgdm9pZCB1c2FnZShjb25zdCBjaGFyICpwbmFtZSwgaW50IGVjb2RlKSB7CiAgICBjb25zdCBVQ2hhciAqbXNnOwogICAgaW50MzJfdCBtc2dMZW47CiAgICBVRXJyb3JDb2RlIGVyciA9IFVfWkVST19FUlJPUjsKICAgIEZJTEUgKmZwID0gZWNvZGUgPyBzdGRlcnIgOiBzdGRvdXQ7CiAgICBpbnQgcmVzOwoKICAgIGluaXRNc2cocG5hbWUpOwogICAgbXNnID0KICAgICAgICB1cmVzX2dldFN0cmluZ0J5S2V5KGdCdW5kbGUsIGVjb2RlID8gImxjVXNhZ2VXb3JkIiA6ICJ1Y1VzYWdlV29yZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbXNnTGVuLCAmZXJyKTsKICAgIFVuaWNvZGVTdHJpbmcgdXBuYW1lKHBuYW1lLCAoaW50MzJfdCkodXBydl9zdHJsZW4ocG5hbWUpICsgMSkpOwogICAgVW5pY29kZVN0cmluZyBtbmFtZShtc2csIG1zZ0xlbiArIDEpOwoKICAgIHJlcyA9IHVfd21zZyhmcCwgInVzYWdlIiwgbW5hbWUuZ2V0QnVmZmVyKCksIHVwbmFtZS5nZXRCdWZmZXIoKSk7CiAgICBpZiAoIWVjb2RlKSB7CiAgICAgICAgaWYgKCFyZXMpIHsKICAgICAgICAgICAgZnB1dGMoJ1xuJywgZnApOwogICAgICAgIH0KICAgICAgICBpZiAoIXVfd21zZyhmcCwgImhlbHAiKSkgewogICAgICAgICAgICAvKiBOb3cgZHVtcCBjYWxsYmFja3MgYW5kIGZpbmlzaC4gKi8KCiAgICAgICAgICAgIGludCBpLCBjb3VudCA9CiAgICAgICAgICAgICAgICBzaXplb2YodHJhbnNjb2RlX2NhbGxiYWNrcykgLyBzaXplb2YoKnRyYW5zY29kZV9jYWxsYmFja3MpOwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7ICsraSkgewogICAgICAgICAgICAgICAgZnByaW50ZihmcCwgIiAlcyIsIHRyYW5zY29kZV9jYWxsYmFja3NbaV0ubmFtZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZnB1dGMoJ1xuJywgZnApOwogICAgICAgIH0KICAgIH0KCiAgICBleGl0KGVjb2RlKTsKfQoKZXh0ZXJuIGludAptYWluKGludCBhcmdjLCBjaGFyICoqYXJndikKewogICAgRklMRSAqb3V0ZmlsZTsKICAgIGludCByZXQgPSAwOwoKICAgIHNpemVfdCBidWZzeiA9IERFRkFVTFRfQlVGU1o7CgogICAgY29uc3QgY2hhciAqZnJvbWNwYWdlID0gMDsKICAgIGNvbnN0IGNoYXIgKnRvY3BhZ2UgPSAwOwogICAgY29uc3QgY2hhciAqdHJhbnNsaXQgPSAwOwogICAgY29uc3QgY2hhciAqb3V0ZmlsZXN0ciA9IDA7CiAgICBVQm9vbCBmYWxsYmFjayA9IEZBTFNFOwoKICAgIFVDb252ZXJ0ZXJGcm9tVUNhbGxiYWNrIGZyb211Y2FsbGJhY2sgPSBVQ05WX0ZST01fVV9DQUxMQkFDS19TVE9QOwogICAgY29uc3Qgdm9pZCAqZnJvbXVjdHh0ID0gMDsKICAgIFVDb252ZXJ0ZXJUb1VDYWxsYmFjayB0b3VjYWxsYmFjayA9IFVDTlZfVE9fVV9DQUxMQkFDS19TVE9QOwogICAgY29uc3Qgdm9pZCAqdG91Y3R4dCA9IDA7CgogICAgY2hhciAqKml0ZXIsICoqcmVtYWluQXJndiwgKipyZW1haW5Bcmd2TGltaXQ7CiAgICBjaGFyICoqZW5kID0gYXJndiArIGFyZ2M7CgogICAgY29uc3QgY2hhciAqcG5hbWU7CgogICAgVUJvb2wgcHJpbnRDb252cyA9IEZBTFNFLCBwcmludENhbm9uID0gRkFMU0UsIHByaW50VHJhbnNsaXRzID0gRkFMU0U7CiAgICBjb25zdCBjaGFyICpwcmludE5hbWUgPSAwOwoKICAgIFVCb29sIHZlcmJvc2UgPSBGQUxTRTsKICAgIFVFcnJvckNvZGUgc3RhdHVzID0gVV9aRVJPX0VSUk9SOwoKICAgIENvbnZlcnRGaWxlIGNmOwoKICAgIC8qIEluaXRpYWxpemUgSUNVICovCiAgICB1X2luaXQoJnN0YXR1cyk7CiAgICBpZiAoVV9GQUlMVVJFKHN0YXR1cykpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIiVzOiBjYW4gbm90IGluaXRpYWxpemUgSUNVLiAgc3RhdHVzID0gJXNcbiIsCiAgICAgICAgICAgIGFyZ3ZbMF0sIHVfZXJyb3JOYW1lKHN0YXR1cykpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgogICAgLy8gR2V0IGFuZCBwcmV0dGlmeSBwbmFtZS4KICAgIHBuYW1lID0gdXBydl9zdHJyY2hyKCphcmd2LCBVX0ZJTEVfU0VQX0NIQVIpOwojaWZkZWYgV0lOMzIKICAgIGlmICghcG5hbWUpIHsKICAgICAgICBwbmFtZSA9IHVwcnZfc3RycmNocigqYXJndiwgJy8nKTsKICAgIH0KI2VuZGlmCiAgICBpZiAoIXBuYW1lKSB7CiAgICAgICAgcG5hbWUgPSAqYXJndjsKICAgIH0gZWxzZSB7CiAgICAgICAgKytwbmFtZTsKICAgIH0KCiAgICAvLyBGaXJzdCwgZ2V0IHRoZSBhcmd1bWVudHMgZnJvbSBjb21tYW5kLWxpbmUKICAgIC8vIHRvIGtub3cgdGhlIGNvZGVwYWdlcyB0byBjb252ZXJ0IGJldHdlZW4KCiAgICByZW1haW5Bcmd2ID0gcmVtYWluQXJndkxpbWl0ID0gYXJndiArIDE7CiAgICBmb3IgKGl0ZXIgPSBhcmd2ICsgMTsgaXRlciAhPSBlbmQ7IGl0ZXIrKykgewogICAgICAgIC8vIENoZWNrIGZvciBmcm9tIGNoYXJzZXQKICAgICAgICBpZiAoc3RyY21wKCItZiIsICppdGVyKSA9PSAwIHx8ICFzdHJjbXAoIi0tZnJvbS1jb2RlIiwgKml0ZXIpKSB7CiAgICAgICAgICAgIGl0ZXIrKzsKICAgICAgICAgICAgaWYgKGl0ZXIgIT0gZW5kKQogICAgICAgICAgICAgICAgZnJvbWNwYWdlID0gKml0ZXI7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHVzYWdlKHBuYW1lLCAxKTsKICAgICAgICB9IGVsc2UgaWYgKHN0cmNtcCgiLXQiLCAqaXRlcikgPT0gMCB8fCAhc3RyY21wKCItLXRvLWNvZGUiLCAqaXRlcikpIHsKICAgICAgICAgICAgaXRlcisrOwogICAgICAgICAgICBpZiAoaXRlciAhPSBlbmQpCiAgICAgICAgICAgICAgICB0b2NwYWdlID0gKml0ZXI7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHVzYWdlKHBuYW1lLCAxKTsKICAgICAgICB9IGVsc2UgaWYgKHN0cmNtcCgiLXgiLCAqaXRlcikgPT0gMCkgewogICAgICAgICAgICBpdGVyKys7CiAgICAgICAgICAgIGlmIChpdGVyICE9IGVuZCkKICAgICAgICAgICAgICAgIHRyYW5zbGl0ID0gKml0ZXI7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHVzYWdlKHBuYW1lLCAxKTsKICAgICAgICB9IGVsc2UgaWYgKCFzdHJjbXAoIi0tZmFsbGJhY2siLCAqaXRlcikpIHsKICAgICAgICAgICAgZmFsbGJhY2sgPSBUUlVFOwogICAgICAgIH0gZWxzZSBpZiAoIXN0cmNtcCgiLS1uby1mYWxsYmFjayIsICppdGVyKSkgewogICAgICAgICAgICBmYWxsYmFjayA9IEZBTFNFOwogICAgICAgIH0gZWxzZSBpZiAoc3RyY21wKCItYiIsICppdGVyKSA9PSAwIHx8ICFzdHJjbXAoIi0tYmxvY2stc2l6ZSIsICppdGVyKSkgewogICAgICAgICAgICBpdGVyKys7CiAgICAgICAgICAgIGlmIChpdGVyICE9IGVuZCkgewogICAgICAgICAgICAgICAgYnVmc3ogPSBhdG9pKCppdGVyKTsKICAgICAgICAgICAgICAgIGlmICgoaW50KSBidWZzeiA8PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBzdHIoKml0ZXIpOwogICAgICAgICAgICAgICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgICAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJiYWRCbG9ja1NpemUiLCBzdHIuZ2V0VGVybWluYXRlZEJ1ZmZlcigpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHVzYWdlKHBuYW1lLCAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoc3RyY21wKCItbCIsICppdGVyKSA9PSAwIHx8ICFzdHJjbXAoIi0tbGlzdCIsICppdGVyKSkgewogICAgICAgICAgICBpZiAocHJpbnRUcmFuc2xpdHMpIHsKICAgICAgICAgICAgICAgIHVzYWdlKHBuYW1lLCAxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludENvbnZzID0gVFJVRTsKICAgICAgICB9IGVsc2UgaWYgKHN0cmNtcCgiLS1kZWZhdWx0LWNvZGUiLCAqaXRlcikgPT0gMCkgewogICAgICAgICAgICBpZiAocHJpbnRUcmFuc2xpdHMpIHsKICAgICAgICAgICAgICAgIHVzYWdlKHBuYW1lLCAxKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwcmludE5hbWUgPSB1Y252X2dldERlZmF1bHROYW1lKCk7CiAgICAgICAgfSBlbHNlIGlmIChzdHJjbXAoIi0tbGlzdC1jb2RlIiwgKml0ZXIpID09IDApIHsKICAgICAgICAgICAgaWYgKHByaW50VHJhbnNsaXRzKSB7CiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGl0ZXIrKzsKICAgICAgICAgICAgaWYgKGl0ZXIgIT0gZW5kKSB7CiAgICAgICAgICAgICAgICBVRXJyb3JDb2RlIGUgPSBVX1pFUk9fRVJST1I7CiAgICAgICAgICAgICAgICBwcmludE5hbWUgPSB1Y252X2dldEFsaWFzKCppdGVyLCAwLCAmZSk7CiAgICAgICAgICAgICAgICBpZiAoVV9GQUlMVVJFKGUpIHx8ICFwcmludE5hbWUpIHsKICAgICAgICAgICAgICAgICAgICBVbmljb2RlU3RyaW5nIHN0cigqaXRlcik7CiAgICAgICAgICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgICAgICAgICAgICAgdV93bXNnKHN0ZGVyciwgIm5vU3VjaENvZGVzZXQiLCBzdHIuZ2V0VGVybWluYXRlZEJ1ZmZlcigpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlCiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgfSBlbHNlIGlmIChzdHJjbXAoIi0tY2Fub24iLCAqaXRlcikgPT0gMCkgewogICAgICAgICAgICBwcmludENhbm9uID0gVFJVRTsKICAgICAgICB9IGVsc2UgaWYgKHN0cmNtcCgiLUwiLCAqaXRlcikgPT0gMAogICAgICAgICAgICB8fCAhc3RyY21wKCItLWxpc3QtdHJhbnNsaXRlcmF0b3JzIiwgKml0ZXIpKSB7CiAgICAgICAgICAgIGlmIChwcmludENvbnZzKSB7CiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHJpbnRUcmFuc2xpdHMgPSBUUlVFOwogICAgICAgIH0gZWxzZSBpZiAoc3RyY21wKCItaCIsICppdGVyKSA9PSAwIHx8ICFzdHJjbXAoIi0/IiwgKml0ZXIpCiAgICAgICAgICAgIHx8ICFzdHJjbXAoIi0taGVscCIsICppdGVyKSkgewogICAgICAgICAgICB1c2FnZShwbmFtZSwgMCk7CiAgICAgICAgfSBlbHNlIGlmICghc3RyY21wKCItYyIsICppdGVyKSkgewogICAgICAgICAgICBmcm9tdWNhbGxiYWNrID0gVUNOVl9GUk9NX1VfQ0FMTEJBQ0tfU0tJUDsKICAgICAgICB9IGVsc2UgaWYgKCFzdHJjbXAoIi0tdG8tY2FsbGJhY2siLCAqaXRlcikpIHsKICAgICAgICAgICAgaXRlcisrOwogICAgICAgICAgICBpZiAoaXRlciAhPSBlbmQpIHsKICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBjYWxsYmFja19lbnQgKmNiZSA9IGZpbmRDYWxsYmFjaygqaXRlcik7CiAgICAgICAgICAgICAgICBpZiAoY2JlKSB7CiAgICAgICAgICAgICAgICAgICAgZnJvbXVjYWxsYmFjayA9IGNiZS0+ZnJvbXU7CiAgICAgICAgICAgICAgICAgICAgZnJvbXVjdHh0ID0gY2JlLT5mcm9tdWN0eHQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKCppdGVyKTsKICAgICAgICAgICAgICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAidW5rbm93bkNhbGxiYWNrIiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKCFzdHJjbXAoIi0tZnJvbS1jYWxsYmFjayIsICppdGVyKSkgewogICAgICAgICAgICBpdGVyKys7CiAgICAgICAgICAgIGlmIChpdGVyICE9IGVuZCkgewogICAgICAgICAgICAgICAgY29uc3Qgc3RydWN0IGNhbGxiYWNrX2VudCAqY2JlID0gZmluZENhbGxiYWNrKCppdGVyKTsKICAgICAgICAgICAgICAgIGlmIChjYmUpIHsKICAgICAgICAgICAgICAgICAgICB0b3VjYWxsYmFjayA9IGNiZS0+dG91OwogICAgICAgICAgICAgICAgICAgIHRvdWN0eHQgPSBjYmUtPnRvdWN0eHQ7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyKCppdGVyKTsKICAgICAgICAgICAgICAgICAgICBpbml0TXNnKHBuYW1lKTsKICAgICAgICAgICAgICAgICAgICB1X3dtc2coc3RkZXJyLCAidW5rbm93bkNhbGxiYWNrIiwgc3RyLmdldFRlcm1pbmF0ZWRCdWZmZXIoKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKCFzdHJjbXAoIi1pIiwgKml0ZXIpKSB7CiAgICAgICAgICAgIHRvdWNhbGxiYWNrID0gVUNOVl9UT19VX0NBTExCQUNLX1NLSVA7CiAgICAgICAgfSBlbHNlIGlmICghc3RyY21wKCItLWNhbGxiYWNrIiwgKml0ZXIpKSB7CiAgICAgICAgICAgIGl0ZXIrKzsKICAgICAgICAgICAgaWYgKGl0ZXIgIT0gZW5kKSB7CiAgICAgICAgICAgICAgICBjb25zdCBzdHJ1Y3QgY2FsbGJhY2tfZW50ICpjYmUgPSBmaW5kQ2FsbGJhY2soKml0ZXIpOwogICAgICAgICAgICAgICAgaWYgKGNiZSkgewogICAgICAgICAgICAgICAgICAgIGZyb211Y2FsbGJhY2sgPSBjYmUtPmZyb211OwogICAgICAgICAgICAgICAgICAgIGZyb211Y3R4dCA9IGNiZS0+ZnJvbXVjdHh0OwogICAgICAgICAgICAgICAgICAgIHRvdWNhbGxiYWNrID0gY2JlLT50b3U7CiAgICAgICAgICAgICAgICAgICAgdG91Y3R4dCA9IGNiZS0+dG91Y3R4dDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgVW5pY29kZVN0cmluZyBzdHIoKml0ZXIpOwogICAgICAgICAgICAgICAgICAgIGluaXRNc2cocG5hbWUpOwogICAgICAgICAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJ1bmtub3duQ2FsbGJhY2siLCBzdHIuZ2V0VGVybWluYXRlZEJ1ZmZlcigpKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gNDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHVzYWdlKHBuYW1lLCAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoIXN0cmNtcCgiLXMiLCAqaXRlcikgfHwgIXN0cmNtcCgiLS1zaWxlbnQiLCAqaXRlcikpIHsKICAgICAgICAgICAgdmVyYm9zZSA9IEZBTFNFOwogICAgICAgIH0gZWxzZSBpZiAoIXN0cmNtcCgiLXYiLCAqaXRlcikgfHwgIXN0cmNtcCgiLS12ZXJib3NlIiwgKml0ZXIpKSB7CiAgICAgICAgICAgIHZlcmJvc2UgPSBUUlVFOwogICAgICAgIH0gZWxzZSBpZiAoIXN0cmNtcCgiLVYiLCAqaXRlcikgfHwgIXN0cmNtcCgiLS12ZXJzaW9uIiwgKml0ZXIpKSB7CiAgICAgICAgICAgIHByaW50ZigiJXMgdjIuMSAgSUNVICIgVV9JQ1VfVkVSU0lPTiAiXG4iLCBwbmFtZSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0gZWxzZSBpZiAoIXN0cmNtcCgiLW8iLCAqaXRlcikgfHwgIXN0cmNtcCgiLS1vdXRwdXQiLCAqaXRlcikpIHsKICAgICAgICAgICAgKytpdGVyOwogICAgICAgICAgICBpZiAoaXRlciAhPSBlbmQgJiYgIW91dGZpbGVzdHIpIHsKICAgICAgICAgICAgICAgIG91dGZpbGVzdHIgPSAqaXRlcjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHVzYWdlKHBuYW1lLCAxKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAoMCA9PSBzdHJjbXAoIi0tYWRkLXNpZ25hdHVyZSIsICppdGVyKSkgewogICAgICAgICAgICBjZi5zaWduYXR1cmUgPSAxOwogICAgICAgIH0gZWxzZSBpZiAoMCA9PSBzdHJjbXAoIi0tcmVtb3ZlLXNpZ25hdHVyZSIsICppdGVyKSkgewogICAgICAgICAgICBjZi5zaWduYXR1cmUgPSAtMTsKICAgICAgICB9IGVsc2UgaWYgKCoqaXRlciA9PSAnLScgJiYgKCppdGVyKVsxXSkgewogICAgICAgICAgICB1c2FnZShwbmFtZSwgMSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gbW92ZSBhIG5vbi1vcHRpb24gdXAgaW4gYXJndltdCiAgICAgICAgICAgICpyZW1haW5Bcmd2TGltaXQrKyA9ICppdGVyOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAocHJpbnRDb252cyB8fCBwcmludE5hbWUpIHsKICAgICAgICByZXR1cm4gcHJpbnRDb252ZXJ0ZXJzKHBuYW1lLCBwcmludE5hbWUsIHByaW50Q2Fub24pID8gMiA6IDA7CiAgICB9IGVsc2UgaWYgKHByaW50VHJhbnNsaXRzKSB7CiAgICAgICAgcmV0dXJuIHByaW50VHJhbnNsaXRlcmF0b3JzKHByaW50Q2Fub24pID8gMyA6IDA7CiAgICB9CgogICAgaWYgKCFmcm9tY3BhZ2UgfHwgIXVwcnZfc3RyY21wKGZyb21jcGFnZSwgIi0iKSkgewogICAgICAgIGZyb21jcGFnZSA9IHVjbnZfZ2V0RGVmYXVsdE5hbWUoKTsKICAgIH0KICAgIGlmICghdG9jcGFnZSB8fCAhdXBydl9zdHJjbXAodG9jcGFnZSwgIi0iKSkgewogICAgICAgIHRvY3BhZ2UgPSB1Y252X2dldERlZmF1bHROYW1lKCk7CiAgICB9CgogICAgLy8gT3BlbiB0aGUgY29ycmVjdCBvdXRwdXQgZmlsZSBvciBjb25uZWN0IHRvIHN0ZG91dCBmb3IgcmVhZGluZyBpbnB1dAogICAgaWYgKG91dGZpbGVzdHIgIT0gMCAmJiBzdHJjbXAob3V0ZmlsZXN0ciwgIi0iKSkgewogICAgICAgIG91dGZpbGUgPSBmb3BlbihvdXRmaWxlc3RyLCAid2IiKTsKICAgICAgICBpZiAob3V0ZmlsZSA9PSAwKSB7CiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyMShvdXRmaWxlc3RyLCAiIik7CiAgICAgICAgICAgIFVuaWNvZGVTdHJpbmcgc3RyMihzdHJlcnJvcihlcnJubyksICIiKTsKICAgICAgICAgICAgaW5pdE1zZyhwbmFtZSk7CiAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50Q3JlYXRlT3V0cHV0RiIsCiAgICAgICAgICAgICAgICBzdHIxLmdldEJ1ZmZlcigpLCBzdHIyLmdldEJ1ZmZlcigpKTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBvdXRmaWxlc3RyID0gIi0iOwogICAgICAgIG91dGZpbGUgPSBzdGRvdXQ7CiNpZmRlZiBXSU4zMgogICAgICAgIGlmIChzZXRtb2RlKGZpbGVubyhvdXRmaWxlKSwgT19CSU5BUlkpID09IC0xKSB7CiAgICAgICAgICAgIHVfd21zZyhzdGRlcnIsICJjYW50U2V0T3V0QmluTW9kZSIpOwogICAgICAgICAgICBleGl0KC0xKTsKICAgICAgICB9CiNlbmRpZgogICAgfQoKICAgIC8qIExvb3AgYWdhaW4gb24gdGhlIGFyZ3VtZW50cyB0byBmaW5kIGFsbCB0aGUgaW5wdXQgZmlsZXMsIGFuZAogICAgY29udmVydCB0aGVtLiAqLwoKICAgIGNmLnNldEJ1ZmZlclNpemUoYnVmc3opOwoKICAgIGlmKHJlbWFpbkFyZ3YgPCByZW1haW5Bcmd2TGltaXQpIHsKICAgICAgICBmb3IgKGl0ZXIgPSByZW1haW5Bcmd2OyBpdGVyICE9IHJlbWFpbkFyZ3ZMaW1pdDsgaXRlcisrKSB7CiAgICAgICAgICAgIGlmICghY2YuY29udmVydEZpbGUoCiAgICAgICAgICAgICAgICAgICAgcG5hbWUsIGZyb21jcGFnZSwgdG91Y2FsbGJhY2ssIHRvdWN0eHQsIHRvY3BhZ2UsCiAgICAgICAgICAgICAgICAgICAgZnJvbXVjYWxsYmFjaywgZnJvbXVjdHh0LCBmYWxsYmFjaywgdHJhbnNsaXQsICppdGVyLAogICAgICAgICAgICAgICAgICAgIG91dGZpbGUsIHZlcmJvc2UpCiAgICAgICAgICAgICkgewogICAgICAgICAgICAgICAgZ290byBlcnJvcl9leGl0OwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBpZiAoIWNmLmNvbnZlcnRGaWxlKAogICAgICAgICAgICAgICAgcG5hbWUsIGZyb21jcGFnZSwgdG91Y2FsbGJhY2ssIHRvdWN0eHQsIHRvY3BhZ2UsCiAgICAgICAgICAgICAgICBmcm9tdWNhbGxiYWNrLCBmcm9tdWN0eHQsIGZhbGxiYWNrLCB0cmFuc2xpdCwgMCwKICAgICAgICAgICAgICAgIG91dGZpbGUsIHZlcmJvc2UpCiAgICAgICAgKSB7CiAgICAgICAgICAgIGdvdG8gZXJyb3JfZXhpdDsKICAgICAgICB9CiAgICB9CgogICAgZ290byBub3JtYWxfZXhpdDsKZXJyb3JfZXhpdDoKICAgIHJldCA9IDE7Cm5vcm1hbF9leGl0OgoKICAgIGlmIChvdXRmaWxlICE9IHN0ZG91dCkgewogICAgICAgIGZjbG9zZShvdXRmaWxlKTsKICAgIH0KCiAgICByZXR1cm4gcmV0Owp9CgoKLyoKICogSGV5LCBFbWFjcywgcGxlYXNlIHNldCB0aGUgZm9sbG93aW5nOgogKgogKiBMb2NhbCBWYXJpYWJsZXM6CiAqIGluZGVudC10YWJzLW1vZGU6IG5pbAogKiBFbmQ6CiAqCiAqLwo=