IyAtKi0gY29kaW5nOiBpc28tODg1OS0xIC0qLQoiIiIgQSBTQVgyIGRyaXZlciBmb3IgbGlieG1sMiwgb24gdG9wIG9mIGl0J3MgWG1sUmVhZGVyIEFQSQoKVVNBR0UKICAgICMgcHV0IHRoaXMgZmlsZSAoZHJ2X2xpYnhtbDIucHkpIGluIFBZVEhPTlBBVEgKICAgIGltcG9ydCB4bWwuc2F4CiAgICByZWFkZXIgPSB4bWwuc2F4Lm1ha2VfcGFyc2VyKFsiZHJ2X2xpYnhtbDIiXSkKICAgICMgLi4uYW5kIHRoZSByZXN0IGlzIHN0YW5kYXJkIHB5dGhvbiBzYXguCgpDQVZFQVRTCiAgICAtIExleGljYWwgaGFuZGxlcnMgYXJlIHN1cHBvcnRlZCwgZXhjZXB0IGZvciBzdGFydC9lbmRFbnRpdHkKICAgICAgKHdhaXRpbmcgZm9yIFhtbFJlYWRlci5SZXNvbHZlRW50aXR5KSBhbmQgc3RhcnQvZW5kRFRECiAgICAtIEVycm9yIGNhbGxiYWNrcyBhcmUgbm90IGV4YWN0bHkgc3luY2hyb25vdXMsIHRoZXkgdGVuZAogICAgICB0byBiZSBpbnZva2VkIGJlZm9yZSB0aGUgY29ycmVzcG9uZGluZyBjb250ZW50IGNhbGxiYWNrLAogICAgICBiZWNhdXNlIHRoZSB1bmRlcmx5aW5nIHJlYWRlciBpbnRlcmZhY2UgcGFyc2VzCiAgICAgIGRhdGEgYnkgY2h1bmtzIG9mIDUxMiBieXRlcwogICAgClRPRE8KICAgIC0gc2VhcmNoIGZvciBUT0RPCiAgICAtIHNvbWUgRXJyb3JIYW5kbGVyIGV2ZW50cyAod2FybmluZykKICAgIC0gc29tZSBDb250ZW50SGFuZGxlciBldmVudHMgKHNldERvY3VtZW50TG9jYXRvciwgc2tpcHBlZEVudGl0eSkKICAgIC0gRW50aXR5UmVzb2x2ZXIgKHVzaW5nIGxpYnhtbDIuPykKICAgIC0gRFRESGFuZGxlciAoaWYvd2hlbiBsaWJ4bWwyIGV4cG9zZXMgc3VjaCBub2RlIHR5cGVzKQogICAgLSBEZWNsSGFuZGxlciAoaWYvd2hlbiBsaWJ4bWwyIGV4cG9zZXMgc3VjaCBub2RlIHR5cGVzKQogICAgLSBwcm9wZXJ0eV94bWxfc3RyaW5nPwogICAgLSBmZWF0dXJlX3N0cmluZ19pbnRlcm5pbmc/CiAgICAtIEluY3JlbWVudGFsIHBhcnNlcgogICAgLSBhZGRpdGlvbmFsIHBlcmZvcm1hbmNlIHR1bmluZzoKICAgICAgLSBvbmUgbWlnaHQgY2FjaGUgY2FsbGJhY2tzIHRvIGF2b2lkIHNvbWUgbmFtZSBsb29rdXBzCiAgICAgIC0gb25lIG1pZ2h0IGltcGxlbWVudCBhIHNtYXJ0ZXIgd2F5IHRvIHBhc3MgYXR0cmlidXRlcyB0byBzdGFydEVsZW1lbnQKICAgICAgICAoc29tZSBraW5kIG9mIGxhenkgZXZhbHVhdGlvbj8pCiAgICAgIC0gdGhlcmUgbWlnaHQgYmUgcm9vbSBmb3IgaW1wcm92ZW1lbnQgaW4gc3RhcnQvZW5kUHJlZml4TWFwcGluZwogICAgICAtIG90aGVyPwoKIiIiCgpfX2F1dGhvcl9fICA9IHUiU3TpcGhhbmUgQmlkb3VsIDxzYmlAc2t5bmV0LmJlPiIKX192ZXJzaW9uX18gPSAiMC4zIgoKaW1wb3J0IGNvZGVjcwpmcm9tIHR5cGVzIGltcG9ydCBTdHJpbmdUeXBlLCBVbmljb2RlVHlwZQpTdHJpbmdUeXBlcyA9IChTdHJpbmdUeXBlLFVuaWNvZGVUeXBlKQoKZnJvbSB4bWwuc2F4Ll9leGNlcHRpb25zIGltcG9ydCAqCmZyb20geG1sLnNheCBpbXBvcnQgeG1scmVhZGVyLCBzYXh1dGlscwpmcm9tIHhtbC5zYXguaGFuZGxlciBpbXBvcnQgXAogICAgIGZlYXR1cmVfbmFtZXNwYWNlcywgXAogICAgIGZlYXR1cmVfbmFtZXNwYWNlX3ByZWZpeGVzLCBcCiAgICAgZmVhdHVyZV9zdHJpbmdfaW50ZXJuaW5nLCBcCiAgICAgZmVhdHVyZV92YWxpZGF0aW9uLCBcCiAgICAgZmVhdHVyZV9leHRlcm5hbF9nZXMsIFwKICAgICBmZWF0dXJlX2V4dGVybmFsX3BlcywgXAogICAgIHByb3BlcnR5X2xleGljYWxfaGFuZGxlciwgXAogICAgIHByb3BlcnR5X2RlY2xhcmF0aW9uX2hhbmRsZXIsIFwKICAgICBwcm9wZXJ0eV9kb21fbm9kZSwgXAogICAgIHByb3BlcnR5X3htbF9zdHJpbmcKCiMgbGlieG1sMiByZXR1cm5zIHN0cmluZ3MgYXMgVVRGOApfZGVjb2RlciA9IGNvZGVjcy5sb29rdXAoInV0ZjgiKVsxXQpkZWYgX2Qocyk6CiAgICBpZiBzIGlzIE5vbmU6CiAgICAgICAgcmV0dXJuIHMKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuIF9kZWNvZGVyKHMpWzBdCgp0cnk6CiAgICBpbXBvcnQgbGlieG1sMgpleGNlcHQgSW1wb3J0RXJyb3IsIGU6CiAgICByYWlzZSBTQVhSZWFkZXJOb3RBdmFpbGFibGUoImxpYnhtbDIgbm90IGF2YWlsYWJsZTogIiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImltcG9ydCBlcnJvciB3YXM6ICVzIiAlIGUpCgpjbGFzcyBMb2NhdG9yKHhtbHJlYWRlci5Mb2NhdG9yKToKICAgICIiIlNBWCBMb2NhdG9yIGFkYXB0ZXIgZm9yIGxpYnhtbDIueG1sVGV4dFJlYWRlckxvY2F0b3IiIiIKCiAgICBkZWYgX19pbml0X18oc2VsZixsb2NhdG9yKToKICAgICAgICBzZWxmLl9fbG9jYXRvciA9IGxvY2F0b3IKCiAgICBkZWYgZ2V0Q29sdW1uTnVtYmVyKHNlbGYpOgogICAgICAgICJSZXR1cm4gdGhlIGNvbHVtbiBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZXZlbnQgZW5kcy4iCiAgICAgICAgcmV0dXJuIC0xCgogICAgZGVmIGdldExpbmVOdW1iZXIoc2VsZik6CiAgICAgICAgIlJldHVybiB0aGUgbGluZSBudW1iZXIgd2hlcmUgdGhlIGN1cnJlbnQgZXZlbnQgZW5kcy4iCiAgICAgICAgcmV0dXJuIHNlbGYuX19sb2NhdG9yLkxpbmVOdW1iZXIoKQoKICAgIGRlZiBnZXRQdWJsaWNJZChzZWxmKToKICAgICAgICAiUmV0dXJuIHRoZSBwdWJsaWMgaWRlbnRpZmllciBmb3IgdGhlIGN1cnJlbnQgZXZlbnQuIgogICAgICAgIHJldHVybiBOb25lCgogICAgZGVmIGdldFN5c3RlbUlkKHNlbGYpOgogICAgICAgICJSZXR1cm4gdGhlIHN5c3RlbSBpZGVudGlmaWVyIGZvciB0aGUgY3VycmVudCBldmVudC4iCiAgICAgICAgcmV0dXJuIHNlbGYuX19sb2NhdG9yLkJhc2VVUkkoKQoKY2xhc3MgTGliWG1sMlJlYWRlcih4bWxyZWFkZXIuWE1MUmVhZGVyKToKCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgeG1scmVhZGVyLlhNTFJlYWRlci5fX2luaXRfXyhzZWxmKQogICAgICAgICMgZmVhdHVyZXMKICAgICAgICBzZWxmLl9fbnMgPSAwCiAgICAgICAgc2VsZi5fX25zcGZ4ID0gMAogICAgICAgIHNlbGYuX192YWxpZGF0ZSA9IDAKICAgICAgICBzZWxmLl9fZXh0cGFyYW1zID0gMQogICAgICAgICMgcGFyc2luZyBmbGFnCiAgICAgICAgc2VsZi5fX3BhcnNpbmcgPSAwCiAgICAgICAgIyBhZGRpdGlvbmFsIGhhbmRsZXJzCiAgICAgICAgc2VsZi5fX2xleF9oYW5kbGVyID0gTm9uZQogICAgICAgIHNlbGYuX19kZWNsX2hhbmRsZXIgPSBOb25lCiAgICAgICAgIyBlcnJvciBtZXNzYWdlcyBhY2N1bXVsYXRvcgogICAgICAgIHNlbGYuX19lcnJvcnMgPSBOb25lCgogICAgZGVmIF9lcnJvckhhbmRsZXIoc2VsZixhcmcsbXNnLHNldmVyaXR5LGxvY2F0b3IpOgogICAgICAgIGlmIHNlbGYuX19lcnJvcnMgaXMgTm9uZToKICAgICAgICAgICAgc2VsZi5fX2Vycm9ycyA9IFtdCiAgICAgICAgc2VsZi5fX2Vycm9ycy5hcHBlbmQoKHNldmVyaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQVhQYXJzZUV4Y2VwdGlvbihtc2csTm9uZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTG9jYXRvcihsb2NhdG9yKSkpKQoKICAgIGRlZiBfcmVwb3J0RXJyb3JzKHNlbGYsZmF0YWwpOgogICAgICAgIGZvciBzZXZlcml0eSxleGNlcHRpb24gaW4gc2VsZi5fX2Vycm9yczoKICAgICAgICAgICAgaWYgc2V2ZXJpdHkgaW4gKGxpYnhtbDIuUEFSU0VSX1NFVkVSSVRZX1ZBTElESVRZX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaWJ4bWwyLlBBUlNFUl9TRVZFUklUWV9XQVJOSU5HKToKICAgICAgICAgICAgICAgIHNlbGYuX2Vycl9oYW5kbGVyLndhcm5pbmcoZXhjZXB0aW9uKQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgIyB3aGVuIGZhdGFsIGlzIHNldCwgdGhlIHBhcnNlIHdpbGwgc3RvcDsKICAgICAgICAgICAgICAgICMgd2UgY29uc2lkZXIgdGhhdCB0aGUgbGFzdCBlcnJvciByZXBvcnRlZAogICAgICAgICAgICAgICAgIyBpcyB0aGUgZmF0YWwgb25lLgogICAgICAgICAgICAgICAgaWYgZmF0YWwgYW5kIGV4Y2VwdGlvbiBpcyBzZWxmLl9fZXJyb3JzWy0xXVsxXToKICAgICAgICAgICAgICAgICAgICBzZWxmLl9lcnJfaGFuZGxlci5mYXRhbEVycm9yKGV4Y2VwdGlvbikKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fZXJyX2hhbmRsZXIuZXJyb3IoZXhjZXB0aW9uKQogICAgICAgIHNlbGYuX19lcnJvcnMgPSBOb25lCgogICAgZGVmIHBhcnNlKHNlbGYsIHNvdXJjZSk6CiAgICAgICAgc2VsZi5fX3BhcnNpbmcgPSAxCiAgICAgICAgdHJ5OgogICAgICAgICAgICAjIHByZXBhcmUgc291cmNlIGFuZCBjcmVhdGUgcmVhZGVyCiAgICAgICAgICAgIGlmIHR5cGUoc291cmNlKSBpbiBTdHJpbmdUeXBlczoKICAgICAgICAgICAgICAgIHJlYWRlciA9IGxpYnhtbDIubmV3VGV4dFJlYWRlckZpbGVuYW1lKHNvdXJjZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNheHV0aWxzLnByZXBhcmVfaW5wdXRfc291cmNlKHNvdXJjZSkKICAgICAgICAgICAgICAgIGlucHV0ID0gbGlieG1sMi5pbnB1dEJ1ZmZlcihzb3VyY2UuZ2V0Qnl0ZVN0cmVhbSgpKQogICAgICAgICAgICAgICAgcmVhZGVyID0gaW5wdXQubmV3VGV4dFJlYWRlcihzb3VyY2UuZ2V0U3lzdGVtSWQoKSkKICAgICAgICAgICAgcmVhZGVyLlNldEVycm9ySGFuZGxlcihzZWxmLl9lcnJvckhhbmRsZXIsTm9uZSkKICAgICAgICAgICAgIyBjb25maWd1cmUgcmVhZGVyCiAgICAgICAgICAgIGlmIHNlbGYuX19leHRwYXJhbXM6CiAgICAgICAgICAgICAgICByZWFkZXIuU2V0UGFyc2VyUHJvcChsaWJ4bWwyLlBBUlNFUl9MT0FERFRELDEpCiAgICAgICAgICAgICAgICByZWFkZXIuU2V0UGFyc2VyUHJvcChsaWJ4bWwyLlBBUlNFUl9ERUZBVUxUQVRUUlMsMSkKICAgICAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX1NVQlNUX0VOVElUSUVTLDEpCiAgICAgICAgICAgICAgICByZWFkZXIuU2V0UGFyc2VyUHJvcChsaWJ4bWwyLlBBUlNFUl9WQUxJREFURSxzZWxmLl9fdmFsaWRhdGUpCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICByZWFkZXIuU2V0UGFyc2VyUHJvcChsaWJ4bWwyLlBBUlNFUl9MT0FERFRELCAwKQogICAgICAgICAgICAjIHdlIHJldXNlIGF0dHJpYnV0ZSBtYXBzIChmb3IgYSBzbGlnaHQgcGVyZm9ybWFuY2UgZ2FpbikKICAgICAgICAgICAgaWYgc2VsZi5fX25zOgogICAgICAgICAgICAgICAgYXR0cmlidXRlc05TSW1wbCA9IHhtbHJlYWRlci5BdHRyaWJ1dGVzTlNJbXBsKHt9LHt9KQogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgYXR0cmlidXRlc0ltcGwgPSB4bWxyZWFkZXIuQXR0cmlidXRlc0ltcGwoe30pCiAgICAgICAgICAgICMgcHJlZml4ZXMgdG8gcG9wIChmb3IgZW5kUHJlZml4TWFwcGluZykKICAgICAgICAgICAgcHJlZml4ZXMgPSBbXQogICAgICAgICAgICAjIHN0YXJ0IGxvb3AKICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLnN0YXJ0RG9jdW1lbnQoKQogICAgICAgICAgICB3aGlsZSAxOgogICAgICAgICAgICAgICAgciA9IHJlYWRlci5SZWFkKCkKICAgICAgICAgICAgICAgICMgY2hlY2sgZm9yIGVycm9ycwogICAgICAgICAgICAgICAgaWYgciA9PSAxOgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fZXJyb3JzIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3JlcG9ydEVycm9ycygwKQogICAgICAgICAgICAgICAgZWxpZiByID09IDA6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19lcnJvcnMgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcmVwb3J0RXJyb3JzKDApCiAgICAgICAgICAgICAgICAgICAgYnJlYWsgIyBlbmQgb2YgcGFyc2UKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19lcnJvcnMgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fcmVwb3J0RXJyb3JzKDEpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fZXJyX2hhbmRsZXIuZmF0YWxFcnJvcihcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTQVhFeGNlcHRpb24oIlJlYWQgZmFpbGVkIChubyBkZXRhaWxzIGF2YWlsYWJsZSkiKSkKICAgICAgICAgICAgICAgICAgICBicmVhayAjIGZhdGFsIHBhcnNlIGVycm9yCiAgICAgICAgICAgICAgICAjIGdldCBub2RlIHR5cGUKICAgICAgICAgICAgICAgIG5vZGVUeXBlID0gcmVhZGVyLk5vZGVUeXBlKCkKICAgICAgICAgICAgICAgICMgRWxlbWVudAogICAgICAgICAgICAgICAgaWYgbm9kZVR5cGUgPT0gMTogCiAgICAgICAgICAgICAgICAgICAgaWYgc2VsZi5fX25zOgogICAgICAgICAgICAgICAgICAgICAgICBlbHROYW1lID0gKF9kKHJlYWRlci5OYW1lc3BhY2VVcmkoKSksXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kKHJlYWRlci5Mb2NhbE5hbWUoKSkpCiAgICAgICAgICAgICAgICAgICAgICAgIGVsdFFOYW1lID0gX2QocmVhZGVyLk5hbWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc05TSW1wbC5fYXR0cnMgPSBhdHRycyA9IHt9CiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNOU0ltcGwuX3FuYW1lcyA9IHFuYW1lcyA9IHt9CiAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ByZWZpeGVzID0gW10KICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgcmVhZGVyLk1vdmVUb05leHRBdHRyaWJ1dGUoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHFuYW1lID0gX2QocmVhZGVyLk5hbWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gX2QocmVhZGVyLlZhbHVlKCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiBxbmFtZS5zdGFydHN3aXRoKCJ4bWxucyIpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIGxlbihxbmFtZSkgPiA1OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQcmVmaXggPSBxbmFtZVs2Ol0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQcmVmaXggPSBOb25lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UHJlZml4ZXMuYXBwZW5kKG5ld1ByZWZpeCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuc3RhcnRQcmVmaXhNYXBwaW5nKFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3UHJlZml4LHZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fbnNwZng6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlICMgZG9uJ3QgcmVwb3J0IHhtbG5zIGF0dHJpYnV0ZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0TmFtZSA9IChfZChyZWFkZXIuTmFtZXNwYWNlVXJpKCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZChyZWFkZXIuTG9jYWxOYW1lKCkpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgcW5hbWVzW2F0dE5hbWVdID0gcW5hbWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJzW2F0dE5hbWVdID0gdmFsdWUKICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLk1vdmVUb0VsZW1lbnQoKQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuc3RhcnRFbGVtZW50TlMoIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsdE5hbWUsZWx0UU5hbWUsYXR0cmlidXRlc05TSW1wbCkgCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHJlYWRlci5Jc0VtcHR5RWxlbWVudCgpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZEVsZW1lbnROUyhlbHROYW1lLGVsdFFOYW1lKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIG5ld1ByZWZpeCBpbiBuZXdQcmVmaXhlczoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhuZXdQcmVmaXgpCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXhlcy5hcHBlbmQobmV3UHJlZml4ZXMpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgZWx0TmFtZSA9IF9kKHJlYWRlci5OYW1lKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNJbXBsLl9hdHRycyA9IGF0dHJzID0ge30KICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgcmVhZGVyLk1vdmVUb05leHRBdHRyaWJ1dGUoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dE5hbWUgPSBfZChyZWFkZXIuTmFtZSgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnNbYXR0TmFtZV0gPSBfZChyZWFkZXIuVmFsdWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgcmVhZGVyLk1vdmVUb0VsZW1lbnQoKQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuc3RhcnRFbGVtZW50KCBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHROYW1lLGF0dHJpYnV0ZXNJbXBsKQogICAgICAgICAgICAgICAgICAgICAgICBpZiByZWFkZXIuSXNFbXB0eUVsZW1lbnQoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmRFbGVtZW50KGVsdE5hbWUpCiAgICAgICAgICAgICAgICAjIEVuZEVsZW1lbnQKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTU6IAogICAgICAgICAgICAgICAgICAgIGlmIHNlbGYuX19uczoKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZEVsZW1lbnROUyggXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChfZChyZWFkZXIuTmFtZXNwYWNlVXJpKCkpLF9kKHJlYWRlci5Mb2NhbE5hbWUoKSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kKHJlYWRlci5OYW1lKCkpKQogICAgICAgICAgICAgICAgICAgICAgICBmb3IgcHJlZml4IGluIHByZWZpeGVzLnBvcCgpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZFByZWZpeE1hcHBpbmcocHJlZml4KQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmRFbGVtZW50KF9kKHJlYWRlci5OYW1lKCkpKQogICAgICAgICAgICAgICAgIyBUZXh0CiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDM6IAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5jaGFyYWN0ZXJzKF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICMgV2hpdGVzcGFjZQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxMzogCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoX2QocmVhZGVyLlZhbHVlKCkpKQogICAgICAgICAgICAgICAgIyBTaWduaWZpY2FudFdoaXRlc3BhY2UKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTQ6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmNoYXJhY3RlcnMoX2QocmVhZGVyLlZhbHVlKCkpKQogICAgICAgICAgICAgICAgIyBDREFUQQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSA0OgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fbGV4X2hhbmRsZXIgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2xleF9oYW5kbGVyLnN0YXJ0Q0RBVEEoKQogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5jaGFyYWN0ZXJzKF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX19sZXhfaGFuZGxlci5lbmRDREFUQSgpCiAgICAgICAgICAgICAgICAjIEVudGl0eVJlZmVyZW5jZQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSA1OgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fbGV4X2hhbmRsZXIgaXMgTm9uZToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5zdGFydEVudGl0eShfZChyZWFkZXIuTmFtZSgpKSkKICAgICAgICAgICAgICAgICAgICByZWFkZXIuUmVzb2x2ZUVudGl0eSgpCiAgICAgICAgICAgICAgICAjIEVuZEVudGl0eQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxNjoKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZW5kRW50aXR5KF9kKHJlYWRlci5OYW1lKCkpKQogICAgICAgICAgICAgICAgIyBQcm9jZXNzaW5nSW5zdHJ1Y3Rpb24KICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gNzogCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLnByb2Nlc3NpbmdJbnN0cnVjdGlvbiggXAogICAgICAgICAgICAgICAgICAgICAgICBfZChyZWFkZXIuTmFtZSgpKSxfZChyZWFkZXIuVmFsdWUoKSkpCiAgICAgICAgICAgICAgICAjIENvbW1lbnQKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gODoKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX19sZXhfaGFuZGxlci5jb21tZW50KF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICMgRG9jdW1lbnRUeXBlCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDEwOgogICAgICAgICAgICAgICAgICAgICNpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgIyAgICBzZWxmLl9fbGV4X2hhbmRsZXIuc3RhcnREVEQoKQogICAgICAgICAgICAgICAgICAgIHBhc3MgIyBUT0RPIChob3cgdG8gZGV0ZWN0IGVuZERURD8gb24gZmlyc3Qgbm9uLWR0ZCBldmVudD8pCiAgICAgICAgICAgICAgICAjIFhtbERlY2xhcmF0aW9uCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDE3OgogICAgICAgICAgICAgICAgICAgIHBhc3MgIyBUT0RPCiAgICAgICAgICAgICAgICAjIEVudGl0eQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSA2OgogICAgICAgICAgICAgICAgICAgIHBhc3MgIyBUT0RPIChlbnRpdHkgZGVjbCkKICAgICAgICAgICAgICAgICMgTm90YXRpb24gKGRlY2wpCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDEyOgogICAgICAgICAgICAgICAgICAgIHBhc3MgIyBUT0RPCiAgICAgICAgICAgICAgICAjIEF0dHJpYnV0ZSAobmV2ZXIgaW4gdGhpcyBsb29wKQogICAgICAgICAgICAgICAgI2VsaWYgbm9kZVR5cGUgPT0gMjogCiAgICAgICAgICAgICAgICAjICAgIHBhc3MKICAgICAgICAgICAgICAgICMgRG9jdW1lbnQgKG5vdCBleHBvc2VkKQogICAgICAgICAgICAgICAgI2VsaWYgbm9kZVR5cGUgPT0gOTogCiAgICAgICAgICAgICAgICAjICAgIHBhc3MKICAgICAgICAgICAgICAgICMgRG9jdW1lbnRGcmFnbWVudCAobmV2ZXIgcmV0dXJuZWQgYnkgWG1sUmVhZGVyKQogICAgICAgICAgICAgICAgI2VsaWYgbm9kZVR5cGUgPT0gMTE6CiAgICAgICAgICAgICAgICAjICAgIHBhc3MKICAgICAgICAgICAgICAgICMgTm9uZQogICAgICAgICAgICAgICAgI2VsaWYgbm9kZVR5cGUgPT0gMDoKICAgICAgICAgICAgICAgICMgICAgcGFzcwogICAgICAgICAgICAgICAgIyAtCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgIHJhaXNlIFNBWEV4Y2VwdGlvbigiVW5leHBlY3RlZCBub2RlIHR5cGUgJWQiICUgbm9kZVR5cGUpCiAgICAgICAgICAgIGlmIHIgPT0gMDoKICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmREb2N1bWVudCgpCiAgICAgICAgICAgIHJlYWRlci5DbG9zZSgpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgc2VsZi5fX3BhcnNpbmcgPSAwCgogICAgZGVmIHNldERUREhhbmRsZXIoc2VsZiwgaGFuZGxlcik6CiAgICAgICAgIyBUT0RPICh3aGVuIHN1cHBvcnRlZCwgdGhlIGluaGVyaXRlZCBtZXRob2Qgd29ya3MganVzdCBmaW5lKQogICAgICAgIHJhaXNlIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRFRESGFuZGxlciBub3Qgc3VwcG9ydGVkIikKCiAgICBkZWYgc2V0RW50aXR5UmVzb2x2ZXIoc2VsZiwgcmVzb2x2ZXIpOgogICAgICAgICMgVE9ETyAod2hlbiBzdXBwb3J0ZWQsIHRoZSBpbmhlcml0ZWQgbWV0aG9kIHdvcmtzIGp1c3QgZmluZSkKICAgICAgICByYWlzZSBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIkVudGl0eVJlc29sdmVyIG5vdCBzdXBwb3J0ZWQiKQoKICAgIGRlZiBnZXRGZWF0dXJlKHNlbGYsIG5hbWUpOgogICAgICAgIGlmIG5hbWUgPT0gZmVhdHVyZV9uYW1lc3BhY2VzOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX25zCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfbmFtZXNwYWNlX3ByZWZpeGVzOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX25zcGZ4CiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfdmFsaWRhdGlvbjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX192YWxpZGF0ZQogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX2V4dGVybmFsX2dlczoKICAgICAgICAgICAgcmV0dXJuIDEgIyBUT0RPIChkb2VzIHRoYXQgcmVsYXRlIHRvIFBBUlNFUl9MT0FERFREKT8KICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV9leHRlcm5hbF9wZXM6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fZXh0cGFyYW1zCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiRmVhdHVyZSAnJXMnIG5vdCByZWNvZ25pemVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQoKICAgIGRlZiBzZXRGZWF0dXJlKHNlbGYsIG5hbWUsIHN0YXRlKToKICAgICAgICBpZiBzZWxmLl9fcGFyc2luZzoKICAgICAgICAgICAgcmFpc2UgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJDYW5ub3Qgc2V0IGZlYXR1cmUgJXMgIiBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2hpbGUgcGFyc2luZyIgJSBuYW1lKQogICAgICAgIGlmIG5hbWUgPT0gZmVhdHVyZV9uYW1lc3BhY2VzOgogICAgICAgICAgICBzZWxmLl9fbnMgPSBzdGF0ZQogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX25hbWVzcGFjZV9wcmVmaXhlczoKICAgICAgICAgICAgc2VsZi5fX25zcGZ4ID0gc3RhdGUKICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV92YWxpZGF0aW9uOgogICAgICAgICAgICBzZWxmLl9fdmFsaWRhdGUgPSBzdGF0ZQogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX2V4dGVybmFsX2dlczoKICAgICAgICAgICAgaWYgc3RhdGUgPT0gMDoKICAgICAgICAgICAgICAgICMgVE9ETyAoZG9lcyB0aGF0IHJlbGF0ZSB0byBQQVJTRVJfTE9BRERURCk/CiAgICAgICAgICAgICAgICByYWlzZSBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIkZlYXR1cmUgJyVzJyBub3Qgc3VwcG9ydGVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX2V4dGVybmFsX3BlczoKICAgICAgICAgICAgc2VsZi5fX2V4dHBhcmFtcyA9IHN0YXRlCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiRmVhdHVyZSAnJXMnIG5vdCByZWNvZ25pemVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQoKICAgIGRlZiBnZXRQcm9wZXJ0eShzZWxmLCBuYW1lKToKICAgICAgICBpZiBuYW1lID09IHByb3BlcnR5X2xleGljYWxfaGFuZGxlcjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19sZXhfaGFuZGxlcgogICAgICAgIGVsaWYgbmFtZSA9PSBwcm9wZXJ0eV9kZWNsYXJhdGlvbl9oYW5kbGVyOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX2RlY2xfaGFuZGxlcgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIlByb3BlcnR5ICclcycgbm90IHJlY29nbml6ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCgogICAgZGVmIHNldFByb3BlcnR5KHNlbGYsIG5hbWUsIHZhbHVlKTogICAgIAogICAgICAgIGlmIG5hbWUgPT0gcHJvcGVydHlfbGV4aWNhbF9oYW5kbGVyOgogICAgICAgICAgICBzZWxmLl9fbGV4X2hhbmRsZXIgPSB2YWx1ZQogICAgICAgIGVsaWYgbmFtZSA9PSBwcm9wZXJ0eV9kZWNsYXJhdGlvbl9oYW5kbGVyOgogICAgICAgICAgICAjIFRPRE86IHJlbW92ZSBpZi93aGVuIGxpYnhtbDIgc3VwcG9ydHMgZHRkIGV2ZW50cwogICAgICAgICAgICByYWlzZSBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIlByb3BlcnR5ICclcycgbm90IHN1cHBvcnRlZCIgJSBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQogICAgICAgICAgICBzZWxmLl9fZGVjbF9oYW5kbGVyID0gdmFsdWUKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJQcm9wZXJ0eSAnJXMnIG5vdCByZWNvZ25pemVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQoKZGVmIGNyZWF0ZV9wYXJzZXIoKToKICAgIHJldHVybiBMaWJYbWwyUmVhZGVyKCkKCg==