IiIiIEEgU0FYMiBkcml2ZXIgZm9yIGxpYnhtbDIsIG9uIHRvcCBvZiBpdCdzIFhtbFJlYWRlciBBUEkKClVTQUdFCiAgICAjIHB1dCB0aGlzIGZpbGUgKGRydl9saWJ4bWwyLnB5KSBpbiBQWVRIT05QQVRICiAgICBpbXBvcnQgeG1sLnNheAogICAgcmVhZGVyID0geG1sLnNheC5tYWtlX3BhcnNlcihbImRydl9saWJ4bWwyIl0pCiAgICAjIC4uLmFuZCB0aGUgcmVzdCBpcyBzdGFuZGFyZCBweXRob24gc2F4LgoKQ0FWRUFUUwogICAgLSBMZXhpY2FsIGhhbmRsZXJzIGFyZSBzdXBwb3J0ZWQsIGV4Y2VwdCBmb3Igc3RhcnQvZW5kRW50aXR5CiAgICAgICh3YWl0aW5nIGZvciBYbWxSZWFkZXIuUmVzb2x2ZUVudGl0eSkgYW5kIHN0YXJ0L2VuZERURAogICAgLSBhcyB1bmRlcnN0YW5kIGl0LCBsaWJ4bWwyIGVycm9yIGhhbmRsZXJzIGFyZSBnbG9iYWxzIChwZXIgdGhyZWFkKTsKICAgICAgZWFjaCBjYWxsIHRvIHBhcnNlKCkgcmVnaXN0ZXJzIGEgbmV3IGVycm9yIGhhbmRsZXIsIAogICAgICBvdmVyd3JpdGluZyBhbnkgcHJldmlvdXNseSByZWdpc3RlcmVkIGhhbmRsZXIgCiAgICAgIC0tPiB5b3UgY2FuJ3QgaGF2ZSAyIExpYlhtbDJSZWFkZXIgYWN0aXZlIGF0IHRoZSBzYW1lIHRpbWUKICAgIApUT0RPCiAgICAtIHNlYXJjaCBmb3IgVE9ETwogICAgLSBzb21lIEVycm9ySGFuZGxlciBldmVudHMgKHdhcm5pbmcpCiAgICAtIHNvbWUgQ29udGVudEhhbmRsZXIgZXZlbnRzIChzZXREb2N1bWVudExvY2F0b3IsIHNraXBwZWRFbnRpdHkpCiAgICAtIEVudGl0eVJlc29sdmVyICh1c2luZyBsaWJ4bWwyLj8pCiAgICAtIERUREhhbmRsZXIgKGlmL3doZW4gbGlieG1sMiBleHBvc2VzIHN1Y2ggbm9kZSB0eXBlcykKICAgIC0gRGVjbEhhbmRsZXIgKGlmL3doZW4gbGlieG1sMiBleHBvc2VzIHN1Y2ggbm9kZSB0eXBlcykKICAgIC0gcHJvcGVydHlfeG1sX3N0cmluZz8KICAgIC0gZmVhdHVyZV9zdHJpbmdfaW50ZXJuaW5nPwogICAgLSBJbmNyZW1lbnRhbCBwYXJzZXIKICAgIC0gYWRkaXRpb25hbCBwZXJmb3JtYW5jZSB0dW5pbmc6CiAgICAgIC0gb25lIG1pZ2h0IGNhY2hlIGNhbGxiYWNrcyB0byBhdm9pZCBzb21lIG5hbWUgbG9va3VwcwogICAgICAtIG9uZSBtaWdodCBpbXBsZW1lbnQgYSBzbWFydGVyIHdheSB0byBwYXNzIGF0dHJpYnV0ZXMgdG8gc3RhcnRFbGVtZW50CiAgICAgICAgKHNvbWUga2luZCBvZiBsYXp5IGV2YWx1YXRpb24/KQogICAgICAtIHRoZXJlIG1pZ2h0IGJlIHJvb20gZm9yIGltcHJvdmVtZW50IGluIHN0YXJ0L2VuZFByZWZpeE1hcHBpbmcKICAgICAgLSBvdGhlcj8KCiIiIgoKX19hdXRob3JfXyAgPSB1IlN06XBoYW5lIEJpZG91bCA8c2JpQHNreW5ldC5iZT4iCl9fdmVyc2lvbl9fID0gIjAuMSIKCmltcG9ydCBjb2RlY3MKZnJvbSB0eXBlcyBpbXBvcnQgU3RyaW5nVHlwZXMKCmZyb20geG1sLnNheC5fZXhjZXB0aW9ucyBpbXBvcnQgKgpmcm9tIHhtbC5zYXggaW1wb3J0IHhtbHJlYWRlciwgc2F4dXRpbHMKZnJvbSB4bWwuc2F4LmhhbmRsZXIgaW1wb3J0IFwKICAgICBmZWF0dXJlX25hbWVzcGFjZXMsIFwKICAgICBmZWF0dXJlX25hbWVzcGFjZV9wcmVmaXhlcywgXAogICAgIGZlYXR1cmVfc3RyaW5nX2ludGVybmluZywgXAogICAgIGZlYXR1cmVfdmFsaWRhdGlvbiwgXAogICAgIGZlYXR1cmVfZXh0ZXJuYWxfZ2VzLCBcCiAgICAgZmVhdHVyZV9leHRlcm5hbF9wZXMsIFwKICAgICBwcm9wZXJ0eV9sZXhpY2FsX2hhbmRsZXIsIFwKICAgICBwcm9wZXJ0eV9kZWNsYXJhdGlvbl9oYW5kbGVyLCBcCiAgICAgcHJvcGVydHlfZG9tX25vZGUsIFwKICAgICBwcm9wZXJ0eV94bWxfc3RyaW5nCgojIGxpYnhtbDIgcmV0dXJucyBzdHJpbmdzIGFzIFVURjgKX2RlY29kZXIgPSBjb2RlY3MuZ2V0ZGVjb2RlcigidXRmOCIpCmRlZiBfZChzKToKICAgIGlmIHMgaXMgTm9uZToKICAgICAgICByZXR1cm4gcwogICAgZWxzZToKICAgICAgICByZXR1cm4gX2RlY29kZXIocylbMF0KCnRyeToKICAgIGltcG9ydCBsaWJ4bWwyCmV4Y2VwdCBJbXBvcnRFcnJvciwgZToKICAgIHJhaXNlIFNBWFJlYWRlck5vdEF2YWlsYWJsZSgibGlieG1sMiBub3QgYXZhaWxhYmxlOiAiICsgZSkKCnRyeToKICAgIGltcG9ydCBsaWJ4c2x0CmV4Y2VwdCBJbXBvcnRFcnJvcjoKICAgICMgbm9ybWFsIGJlaGF2aW91cgogICAgZGVmIF9yZWdpc3RlckVycm9ySGFuZGxlcihoYW5kbGVyKToKICAgICAgICBsaWJ4bWwyLnJlZ2lzdGVyRXJyb3JIYW5kbGVyKGhhbmRsZXIsImRydl9saWJ4bWwiKQplbHNlOgogICAgIyB3b3JrIGFyb3VuZCBsaWJ4c2x0IGJpbmRpbmdzIGJ1ZyAobGlieG1sMiBidWcgIzEwMjE4MSkKICAgIGRlZiBfcmVnaXN0ZXJFcnJvckhhbmRsZXIoaGFuZGxlcik6CiAgICAgICAgbGlieG1sMi5yZWdpc3RlckVycm9ySGFuZGxlcihoYW5kbGVyLCJkcnZfbGlieG1sIikKICAgICAgICBsaWJ4c2x0LnJlZ2lzdGVyRXJyb3JIYW5kbGVyKGhhbmRsZXIsImRydl9saWJ4bWwiKQoKY2xhc3MgTGliWG1sMlJlYWRlcih4bWxyZWFkZXIuWE1MUmVhZGVyKToKCiAgICBkZWYgX19pbml0X18oc2VsZik6CiAgICAgICAgeG1scmVhZGVyLlhNTFJlYWRlci5fX2luaXRfXyhzZWxmKQogICAgICAgICMgZmVhdHVyZXMKICAgICAgICBzZWxmLl9fbnMgPSAwCiAgICAgICAgc2VsZi5fX25zcGZ4ID0gMAogICAgICAgIHNlbGYuX192YWxpZGF0ZSA9IDAKICAgICAgICAjIHBhcnNpbmcgZmxhZwogICAgICAgIHNlbGYuX19wYXJzaW5nID0gMAogICAgICAgICMgYWRkaXRpb25hbCBoYW5kbGVycwogICAgICAgIHNlbGYuX19sZXhfaGFuZGxlciA9IE5vbmUKICAgICAgICBzZWxmLl9fZGVjbF9oYW5kbGVyID0gTm9uZQogICAgICAgICMgZXJyb3IgbWVzc2FnZXMgYWNjdW11bGF0b3IKICAgICAgICBzZWxmLl9fZXJyb3JzID0gTm9uZQoKICAgIGRlZiBfZXJyb3JIYW5kbGVyKHNlbGYsY3R4LHN0cik6CiAgICAgICAgaWYgc2VsZi5fX2Vycm9ycyBpcyBOb25lOgogICAgICAgICAgICBzZWxmLl9fZXJyb3JzID0gW10KICAgICAgICBzZWxmLl9fZXJyb3JzLmFwcGVuZChzdHIpCgogICAgZGVmIF9yZXBvcnRFcnJvcihzZWxmLGNhbGxiYWNrKToKICAgICAgICAjIFRPRE86IHVzZSBTQVhQYXJzZUV4Y2VwdGlvbiwgYnV0IHdlIG5lZWQgYSBMb2NhdG9yIGZvciB0aGF0CiAgICAgICAgIyBUT0RPOiBkaXN0aW5ndWlzaCB3YXJuaW5ncyBmcm9tIGVycm9ycwogICAgICAgIG1zZyA9ICIiLmpvaW4oc2VsZi5fX2Vycm9ycykKICAgICAgICBzZWxmLl9fZXJyb3JzID0gTm9uZQogICAgICAgIGNhbGxiYWNrKFNBWEV4Y2VwdGlvbihtc2cpKQoKICAgIGRlZiBwYXJzZShzZWxmLCBzb3VyY2UpOgogICAgICAgIHNlbGYuX19wYXJzaW5nID0gMQogICAgICAgIF9yZWdpc3RlckVycm9ySGFuZGxlcihzZWxmLl9lcnJvckhhbmRsZXIpCiAgICAgICAgdHJ5OgogICAgICAgICAgICAjIHByZXBhcmUgc291cmNlIGFuZCBjcmVhdGUgcmVhZGVyCiAgICAgICAgICAgIGlmIHR5cGUoc291cmNlKSBpbiBTdHJpbmdUeXBlczoKICAgICAgICAgICAgICAgIHJlYWRlciA9IGxpYnhtbDIubmV3VGV4dFJlYWRlckZpbGVuYW1lKHNvdXJjZSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIHNvdXJjZSA9IHNheHV0aWxzLnByZXBhcmVfaW5wdXRfc291cmNlKHNvdXJjZSkKICAgICAgICAgICAgICAgIGlucHV0ID0gbGlieG1sMi5pbnB1dEJ1ZmZlcihzb3VyY2UuZ2V0Qnl0ZVN0cmVhbSgpKQogICAgICAgICAgICAgICAgcmVhZGVyID0gaW5wdXQubmV3VGV4dFJlYWRlcihzb3VyY2UuZ2V0U3lzdGVtSWQoKSkKICAgICAgICAgICAgIyBjb25maWd1cmUgcmVhZGVyCiAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX0xPQUREVEQsMSkKICAgICAgICAgICAgcmVhZGVyLlNldFBhcnNlclByb3AobGlieG1sMi5QQVJTRVJfREVGQVVMVEFUVFJTLDEpCiAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX1NVQlNUX0VOVElUSUVTLDEpCiAgICAgICAgICAgIHJlYWRlci5TZXRQYXJzZXJQcm9wKGxpYnhtbDIuUEFSU0VSX1ZBTElEQVRFLHNlbGYuX192YWxpZGF0ZSkKICAgICAgICAgICAgIyB3ZSByZXVzZSBhdHRyaWJ1dGUgbWFwcyAoZm9yIGEgc2xpZ2h0IHBlcmZvcm1hbmNlIGdhaW4pCiAgICAgICAgICAgIGlmIHNlbGYuX19uczoKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNOU0ltcGwgPSB4bWxyZWFkZXIuQXR0cmlidXRlc05TSW1wbCh7fSx7fSkKICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNJbXBsID0geG1scmVhZGVyLkF0dHJpYnV0ZXNJbXBsKHt9KQogICAgICAgICAgICAjIHByZWZpeGVzIHRvIHBvcCAoZm9yIGVuZFByZWZpeE1hcHBpbmcpCiAgICAgICAgICAgIHByZWZpeGVzID0gW10KICAgICAgICAgICAgIyBzdGFydCBsb29wCiAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5zdGFydERvY3VtZW50KCkKICAgICAgICAgICAgd2hpbGUgMToKICAgICAgICAgICAgICAgIHIgPSByZWFkZXIuUmVhZCgpCiAgICAgICAgICAgICAgICAjIGNoZWNrIGZvciBlcnJvcnMKICAgICAgICAgICAgICAgIGlmIHIgPT0gMToKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2Vycm9ycyBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICAjIG5vbi1mYXRhbCBlcnJvcgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9yZXBvcnRFcnJvcihzZWxmLl9lcnJfaGFuZGxlci5lcnJvcikKICAgICAgICAgICAgICAgIGVsaWYgciA9PSAwOgogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBzZWxmLl9fZXJyb3JzIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgICMgbm9uLWZhdGFsIGVycm9yCiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX3JlcG9ydEVycm9yKHNlbGYuX2Vycl9oYW5kbGVyLmVycm9yKQogICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICMgZmF0YWwgZXJyb3IKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2Vycm9ycyBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9yZXBvcnRFcnJvcihzZWxmLl9lcnJfaGFuZGxlci5mYXRhbEVycm9yKQogICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2Vycl9oYW5kbGVyLmZhdGFsRXJyb3IoXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgU0FYRXhjZXB0aW9uKCJSZWFkIGZhaWxlZCAobm8gZGV0YWlscyBhdmFpbGFibGUpIikpCiAgICAgICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgICAgICMgZ2V0IG5vZGUgdHlwZQogICAgICAgICAgICAgICAgbm9kZVR5cGUgPSByZWFkZXIuTm9kZVR5cGUoKQogICAgICAgICAgICAgICAgIyBFbGVtZW50CiAgICAgICAgICAgICAgICBpZiBub2RlVHlwZSA9PSAxOiAKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLl9fbnM6CiAgICAgICAgICAgICAgICAgICAgICAgIGVsdE5hbWUgPSAoX2QocmVhZGVyLk5hbWVzcGFjZVVyaSgpKSxcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX2QocmVhZGVyLkxvY2FsTmFtZSgpKSkKICAgICAgICAgICAgICAgICAgICAgICAgZWx0UU5hbWUgPSBfZChyZWFkZXIuTmFtZSgpKQogICAgICAgICAgICAgICAgICAgICAgICBhdHRyaWJ1dGVzTlNJbXBsLl9hdHRycyA9IGF0dHJzID0ge30KICAgICAgICAgICAgICAgICAgICAgICAgYXR0cmlidXRlc05TSW1wbC5fcW5hbWVzID0gcW5hbWVzID0ge30KICAgICAgICAgICAgICAgICAgICAgICAgbmV3UHJlZml4ZXMgPSBbXQogICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSByZWFkZXIuTW92ZVRvTmV4dEF0dHJpYnV0ZSgpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcW5hbWUgPSBfZChyZWFkZXIuTmFtZSgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBfZChyZWFkZXIuVmFsdWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIHFuYW1lLnN0YXJ0c3dpdGgoInhtbG5zIik6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKHFuYW1lKSA+IDU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ByZWZpeCA9IHFuYW1lWzY6XQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld1ByZWZpeCA9IE5vbmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQcmVmaXhlcy5hcHBlbmQobmV3UHJlZml4KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5zdGFydFByZWZpeE1hcHBpbmcoXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdQcmVmaXgsdmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19uc3BmeDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUgIyBkb24ndCByZXBvcnQgeG1sbnMgYXR0cmlidXRlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdHROYW1lID0gKF9kKHJlYWRlci5OYW1lc3BhY2VVcmkoKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9kKHJlYWRlci5Mb2NhbE5hbWUoKSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBxbmFtZXNbYXR0TmFtZV0gPSBxbmFtZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnNbYXR0TmFtZV0gPSB2YWx1ZQogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuc3RhcnRFbGVtZW50TlMoIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsdE5hbWUsZWx0UU5hbWUsYXR0cmlidXRlc05TSW1wbCkgCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIHJlYWRlci5Jc0VtcHR5RWxlbWVudCgpOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLmVuZEVsZW1lbnROUyhlbHROYW1lLGVsdFFOYW1lKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIG5ld1ByZWZpeCBpbiBuZXdQcmVmaXhlczoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kUHJlZml4TWFwcGluZyhuZXdQcmVmaXgpCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVmaXhlcy5hcHBlbmQobmV3UHJlZml4ZXMpCiAgICAgICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICAgICAgZWx0TmFtZSA9IF9kKHJlYWRlci5OYW1lKCkpCiAgICAgICAgICAgICAgICAgICAgICAgIGF0dHJpYnV0ZXNJbXBsLl9hdHRycyA9IGF0dHJzID0ge30KICAgICAgICAgICAgICAgICAgICAgICAgd2hpbGUgcmVhZGVyLk1vdmVUb05leHRBdHRyaWJ1dGUoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF0dE5hbWUgPSBfZChyZWFkZXIuTmFtZSgpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYXR0cnNbYXR0TmFtZV0gPSBfZChyZWFkZXIuVmFsdWUoKSkKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fY29udF9oYW5kbGVyLnN0YXJ0RWxlbWVudCggXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWx0TmFtZSxhdHRyaWJ1dGVzSW1wbCkKICAgICAgICAgICAgICAgICAgICAgICAgaWYgcmVhZGVyLklzRW1wdHlFbGVtZW50KCk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kRWxlbWVudChlbHROYW1lKQogICAgICAgICAgICAgICAgIyBFbmRFbGVtZW50CiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDE1OiAKICAgICAgICAgICAgICAgICAgICBpZiBzZWxmLl9fbnM6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmRFbGVtZW50TlMoIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoX2QocmVhZGVyLk5hbWVzcGFjZVVyaSgpKSxfZChyZWFkZXIuTG9jYWxOYW1lKCkpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfZChyZWFkZXIuTmFtZSgpKSkKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIHByZWZpeCBpbiBwcmVmaXhlcy5wb3AoKToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5lbmRQcmVmaXhNYXBwaW5nKHByZWZpeCkKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kRWxlbWVudChfZChyZWFkZXIuTmFtZSgpKSkKICAgICAgICAgICAgICAgICMgVGV4dAogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAzOiAKICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuY2hhcmFjdGVycyhfZChyZWFkZXIuVmFsdWUoKSkpCiAgICAgICAgICAgICAgICAjIFdoaXRlc3BhY2UKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTM6IAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5pZ25vcmFibGVXaGl0ZXNwYWNlKF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICMgU2lnbmlmaWNhbnRXaGl0ZXNwYWNlCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDE0OgogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5jaGFyYWN0ZXJzKF9kKHJlYWRlci5WYWx1ZSgpKSkKICAgICAgICAgICAgICAgICMgQ0RBVEEKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gNDoKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuX19sZXhfaGFuZGxlci5zdGFydENEQVRBKCkKICAgICAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuY2hhcmFjdGVycyhfZChyZWFkZXIuVmFsdWUoKSkpCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19sZXhfaGFuZGxlciBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9fbGV4X2hhbmRsZXIuZW5kQ0RBVEEoKQogICAgICAgICAgICAgICAgIyBFbnRpdHlSZWZlcmVuY2UKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gNToKICAgICAgICAgICAgICAgICAgICBpZiBub3Qgc2VsZi5fX2xleF9oYW5kbGVyIGlzIE5vbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuc3RhcnRFbnRpdHkoX2QocmVhZGVyLk5hbWUoKSkpCiAgICAgICAgICAgICAgICAgICAgcmVhZGVyLlJlc29sdmVFbnRpdHkoKQogICAgICAgICAgICAgICAgIyBFbmRFbnRpdHkKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gMTY6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19sZXhfaGFuZGxlciBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLmVuZEVudGl0eShfZChyZWFkZXIuTmFtZSgpKSkKICAgICAgICAgICAgICAgICMgUHJvY2Vzc2luZ0luc3RydWN0aW9uCiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDc6IAogICAgICAgICAgICAgICAgICAgIHNlbGYuX2NvbnRfaGFuZGxlci5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oIFwKICAgICAgICAgICAgICAgICAgICAgICAgX2QocmVhZGVyLk5hbWUoKSksX2QocmVhZGVyLlZhbHVlKCkpKQogICAgICAgICAgICAgICAgIyBDb21tZW50CiAgICAgICAgICAgICAgICBlbGlmIG5vZGVUeXBlID09IDg6CiAgICAgICAgICAgICAgICAgICAgaWYgbm90IHNlbGYuX19sZXhfaGFuZGxlciBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICAgICBzZWxmLl9fbGV4X2hhbmRsZXIuY29tbWVudChfZChyZWFkZXIuVmFsdWUoKSkpCiAgICAgICAgICAgICAgICAjIERvY3VtZW50VHlwZQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxMDoKICAgICAgICAgICAgICAgICAgICAjaWYgbm90IHNlbGYuX19sZXhfaGFuZGxlciBpcyBOb25lOgogICAgICAgICAgICAgICAgICAgICMgICAgc2VsZi5fX2xleF9oYW5kbGVyLnN0YXJ0RFREKCkKICAgICAgICAgICAgICAgICAgICBwYXNzICMgVE9ETyAoaG93IHRvIGRldGVjdCBlbmREVEQ/IG9uIGZpcnN0IG5vbi1kdGQgZXZlbnQ/KQogICAgICAgICAgICAgICAgIyBYbWxEZWNsYXJhdGlvbgogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxNzoKICAgICAgICAgICAgICAgICAgICBwYXNzICMgVE9ETwogICAgICAgICAgICAgICAgIyBFbnRpdHkKICAgICAgICAgICAgICAgIGVsaWYgbm9kZVR5cGUgPT0gNjoKICAgICAgICAgICAgICAgICAgICBwYXNzICMgVE9ETyAoZW50aXR5IGRlY2wpCiAgICAgICAgICAgICAgICAjIE5vdGF0aW9uIChkZWNsKQogICAgICAgICAgICAgICAgZWxpZiBub2RlVHlwZSA9PSAxMjoKICAgICAgICAgICAgICAgICAgICBwYXNzICMgVE9ETwogICAgICAgICAgICAgICAgIyBBdHRyaWJ1dGUgKG5ldmVyIGluIHRoaXMgbG9vcCkKICAgICAgICAgICAgICAgICNlbGlmIG5vZGVUeXBlID09IDI6IAogICAgICAgICAgICAgICAgIyAgICBwYXNzCiAgICAgICAgICAgICAgICAjIERvY3VtZW50IChub3QgZXhwb3NlZCkKICAgICAgICAgICAgICAgICNlbGlmIG5vZGVUeXBlID09IDk6IAogICAgICAgICAgICAgICAgIyAgICBwYXNzCiAgICAgICAgICAgICAgICAjIERvY3VtZW50RnJhZ21lbnQgKG5ldmVyIHJldHVybmVkIGJ5IFhtbFJlYWRlcikKICAgICAgICAgICAgICAgICNlbGlmIG5vZGVUeXBlID09IDExOgogICAgICAgICAgICAgICAgIyAgICBwYXNzCiAgICAgICAgICAgICAgICAjIE5vbmUKICAgICAgICAgICAgICAgICNlbGlmIG5vZGVUeXBlID09IDA6CiAgICAgICAgICAgICAgICAjICAgIHBhc3MKICAgICAgICAgICAgICAgICMgLQogICAgICAgICAgICAgICAgZWxzZToKICAgICAgICAgICAgICAgICAgICByYWlzZSBTQVhFeGNlcHRpb24oIlVuZXhwZWN0ZWQgbm9kZSB0eXBlICVkIiAlIG5vZGVUeXBlKQogICAgICAgICAgICBpZiByID09IDA6CiAgICAgICAgICAgICAgICBzZWxmLl9jb250X2hhbmRsZXIuZW5kRG9jdW1lbnQoKQogICAgICAgICAgICByZWFkZXIuQ2xvc2UoKQogICAgICAgIGZpbmFsbHk6CiAgICAgICAgICAgIHNlbGYuX19wYXJzaW5nID0gMAogICAgICAgICAgICAjIFRPRE86IHVucmVnaXN0ZXIgZXJyb3IgaGFuZGxlcj8KCiAgICBkZWYgc2V0RFRESGFuZGxlcihzZWxmLCBoYW5kbGVyKToKICAgICAgICAjIFRPRE8gKHdoZW4gc3VwcG9ydGVkLCB0aGUgaW5oZXJpdGVkIG1ldGhvZCB3b3JrcyBqdXN0IGZpbmUpCiAgICAgICAgcmFpc2UgU0FYTm90U3VwcG9ydGVkRXhjZXB0aW9uKCJEVERIYW5kbGVyIG5vdCBzdXBwb3J0ZWQiKQoKICAgIGRlZiBzZXRFbnRpdHlSZXNvbHZlcihzZWxmLCByZXNvbHZlcik6CiAgICAgICAgIyBUT0RPICh3aGVuIHN1cHBvcnRlZCwgdGhlIGluaGVyaXRlZCBtZXRob2Qgd29ya3MganVzdCBmaW5lKQogICAgICAgIHJhaXNlIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRW50aXR5UmVzb2x2ZXIgbm90IHN1cHBvcnRlZCIpCgogICAgZGVmIGdldEZlYXR1cmUoc2VsZiwgbmFtZSk6CiAgICAgICAgaWYgbmFtZSA9PSBmZWF0dXJlX25hbWVzcGFjZXM6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fbnMKICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV9uYW1lc3BhY2VfcHJlZml4ZXM6CiAgICAgICAgICAgIHJldHVybiBzZWxmLl9fbnNwZngKICAgICAgICBlbGlmIG5hbWUgPT0gZmVhdHVyZV92YWxpZGF0aW9uOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX3ZhbGlkYXRlCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfZXh0ZXJuYWxfZ2VzOgogICAgICAgICAgICByZXR1cm4gMSAjIFRPRE8gKGRvZXMgdGhhdCByZWxhdGUgdG8gUEFSU0VSX0xPQUREVEQpPwogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX2V4dGVybmFsX3BlczoKICAgICAgICAgICAgcmV0dXJuIDEgIyBUT0RPIChkb2VzIHRoYXQgcmVsYXRlIHRvIFBBUlNFUl9MT0FERFREKT8KICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJGZWF0dXJlICclcycgbm90IHJlY29nbml6ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCgogICAgZGVmIHNldEZlYXR1cmUoc2VsZiwgbmFtZSwgc3RhdGUpOgogICAgICAgIGlmIHNlbGYuX19wYXJzaW5nOgogICAgICAgICAgICByYWlzZSBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIkNhbm5vdCBzZXQgZmVhdHVyZSAlcyAiIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3aGlsZSBwYXJzaW5nIiAlIG5hbWUpCiAgICAgICAgaWYgbmFtZSA9PSBmZWF0dXJlX25hbWVzcGFjZXM6CiAgICAgICAgICAgIHNlbGYuX19ucyA9IHN0YXRlCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfbmFtZXNwYWNlX3ByZWZpeGVzOgogICAgICAgICAgICBzZWxmLl9fbnNwZnggPSBzdGF0ZQogICAgICAgIGVsaWYgbmFtZSA9PSBmZWF0dXJlX3ZhbGlkYXRpb246CiAgICAgICAgICAgIHNlbGYuX192YWxpZGF0ZSA9IHN0YXRlCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfZXh0ZXJuYWxfZ2VzOgogICAgICAgICAgICBpZiBzdGF0ZSA9PSAwOgogICAgICAgICAgICAgICAgIyBUT0RPIChkb2VzIHRoYXQgcmVsYXRlIHRvIFBBUlNFUl9MT0FERFREKT8KICAgICAgICAgICAgICAgIHJhaXNlIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRmVhdHVyZSAnJXMnIG5vdCBzdXBwb3J0ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCiAgICAgICAgZWxpZiBuYW1lID09IGZlYXR1cmVfZXh0ZXJuYWxfcGVzOgogICAgICAgICAgICBpZiBzdGF0ZSA9PSAwOgogICAgICAgICAgICAgICAgIyBUT0RPIChkb2VzIHRoYXQgcmVsYXRlIHRvIFBBUlNFUl9MT0FERFREKT8KICAgICAgICAgICAgICAgIHJhaXNlIFNBWE5vdFN1cHBvcnRlZEV4Y2VwdGlvbigiRmVhdHVyZSAnJXMnIG5vdCBzdXBwb3J0ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmFpc2UgU0FYTm90UmVjb2duaXplZEV4Y2VwdGlvbigiRmVhdHVyZSAnJXMnIG5vdCByZWNvZ25pemVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQoKICAgIGRlZiBnZXRQcm9wZXJ0eShzZWxmLCBuYW1lKToKICAgICAgICBpZiBuYW1lID09IHByb3BlcnR5X2xleGljYWxfaGFuZGxlcjoKICAgICAgICAgICAgcmV0dXJuIHNlbGYuX19sZXhfaGFuZGxlcgogICAgICAgIGVsaWYgbmFtZSA9PSBwcm9wZXJ0eV9kZWNsYXJhdGlvbl9oYW5kbGVyOgogICAgICAgICAgICByZXR1cm4gc2VsZi5fX2RlY2xfaGFuZGxlcgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHJhaXNlIFNBWE5vdFJlY29nbml6ZWRFeGNlcHRpb24oIlByb3BlcnR5ICclcycgbm90IHJlY29nbml6ZWQiICUgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUpCgogICAgZGVmIHNldFByb3BlcnR5KHNlbGYsIG5hbWUsIHZhbHVlKTogICAgIAogICAgICAgIGlmIG5hbWUgPT0gcHJvcGVydHlfbGV4aWNhbF9oYW5kbGVyOgogICAgICAgICAgICBzZWxmLl9fbGV4X2hhbmRsZXIgPSB2YWx1ZQogICAgICAgIGVsaWYgbmFtZSA9PSBwcm9wZXJ0eV9kZWNsYXJhdGlvbl9oYW5kbGVyOgogICAgICAgICAgICAjIFRPRE86IHJlbW92ZSBpZi93aGVuIGxpYnhtbDIgc3VwcG9ydHMgZHRkIGV2ZW50cwogICAgICAgICAgICByYWlzZSBTQVhOb3RTdXBwb3J0ZWRFeGNlcHRpb24oIlByb3BlcnR5ICclcycgbm90IHN1cHBvcnRlZCIgJSBcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQogICAgICAgICAgICBzZWxmLl9fZGVjbF9oYW5kbGVyID0gdmFsdWUKICAgICAgICBlbHNlOgogICAgICAgICAgICByYWlzZSBTQVhOb3RSZWNvZ25pemVkRXhjZXB0aW9uKCJQcm9wZXJ0eSAnJXMnIG5vdCByZWNvZ25pemVkIiAlIFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKQoKZGVmIGNyZWF0ZV9wYXJzZXIoKToKICAgIHJldHVybiBMaWJYbWwyUmVhZGVyKCkKCg==