IyAtKi0gY29kaW5nOiBpc28tODg1OS0xIC0qLQoiIiJQYXJzZXIgZm9yIGNvbW1hbmQgbGluZSBvcHRpb25zLgoKVGhpcyBtb2R1bGUgaGVscHMgc2NyaXB0cyB0byBwYXJzZSB0aGUgY29tbWFuZCBsaW5lIGFyZ3VtZW50cyBpbgpzeXMuYXJndi4gIEl0IHN1cHBvcnRzIHRoZSBzYW1lIGNvbnZlbnRpb25zIGFzIHRoZSBVbml4IGdldG9wdCgpCmZ1bmN0aW9uIChpbmNsdWRpbmcgdGhlIHNwZWNpYWwgbWVhbmluZ3Mgb2YgYXJndW1lbnRzIG9mIHRoZSBmb3JtIGAtJwphbmQgYC0tJykuICBMb25nIG9wdGlvbnMgc2ltaWxhciB0byB0aG9zZSBzdXBwb3J0ZWQgYnkgR05VIHNvZnR3YXJlCm1heSBiZSB1c2VkIGFzIHdlbGwgdmlhIGFuIG9wdGlvbmFsIHRoaXJkIGFyZ3VtZW50LiAgVGhpcyBtb2R1bGUKcHJvdmlkZXMgdHdvIGZ1bmN0aW9ucyBhbmQgYW4gZXhjZXB0aW9uOgoKZ2V0b3B0KCkgLS0gUGFyc2UgY29tbWFuZCBsaW5lIG9wdGlvbnMKZ251X2dldG9wdCgpIC0tIExpa2UgZ2V0b3B0KCksIGJ1dCBhbGxvdyBvcHRpb24gYW5kIG5vbi1vcHRpb24gYXJndW1lbnRzCnRvIGJlIGludGVybWl4ZWQuCkdldG9wdEVycm9yIC0tIGV4Y2VwdGlvbiAoY2xhc3MpIHJhaXNlZCB3aXRoICdvcHQnIGF0dHJpYnV0ZSwgd2hpY2ggaXMgdGhlCm9wdGlvbiBpbnZvbHZlZCB3aXRoIHRoZSBleGNlcHRpb24uCiIiIgoKIyBMb25nIG9wdGlvbiBzdXBwb3J0IGFkZGVkIGJ5IExhcnMgV2lyemVuaXVzIDxsaXdAaWtpLmZpPi4KIwojIEdlcnJpdCBIb2xsIDxnZXJyaXRAbmwubGludXgub3JnPiBtb3ZlZCB0aGUgc3RyaW5nLWJhc2VkIGV4Y2VwdGlvbnMKIyB0byBjbGFzcy1iYXNlZCBleGNlcHRpb25zLgojCiMgUGV0ZXIgxXN0cmFuZCA8YXN0cmFuZEBseXNhdG9yLmxpdS5zZT4gYWRkZWQgZ251X2dldG9wdCgpLgojCiMgVE9ETyBmb3IgZ251X2dldG9wdCgpOgojCiMgLSBHTlUgZ2V0b3B0X2xvbmdfb25seSBtZWNoYW5pc20KIyAtIGFsbG93IHRoZSBjYWxsZXIgdG8gc3BlY2lmeSBvcmRlcmluZwojIC0gUkVUVVJOX0lOX09SREVSIG9wdGlvbgojIC0gR05VIGV4dGVuc2lvbiB3aXRoICctJyBhcyBmaXJzdCBjaGFyYWN0ZXIgb2Ygb3B0aW9uIHN0cmluZwojIC0gb3B0aW9uYWwgYXJndW1lbnRzLCBzcGVjaWZpZWQgYnkgZG91YmxlIGNvbG9ucwojIC0gYSBvcHRpb24gc3RyaW5nIHdpdGggYSBXIGZvbGxvd2VkIGJ5IHNlbWljb2xvbiBzaG91bGQKIyAgIHRyZWF0ICItVyBmb28iIGFzICItLWZvbyIKCl9fYWxsX18gPSBbIkdldG9wdEVycm9yIiwiZXJyb3IiLCJnZXRvcHQiLCJnbnVfZ2V0b3B0Il0KCmltcG9ydCBvcwoKY2xhc3MgR2V0b3B0RXJyb3IoRXhjZXB0aW9uKToKICAgIG9wdCA9ICcnCiAgICBtc2cgPSAnJwogICAgZGVmIF9faW5pdF9fKHNlbGYsIG1zZywgb3B0PScnKToKICAgICAgICBzZWxmLm1zZyA9IG1zZwogICAgICAgIHNlbGYub3B0ID0gb3B0CiAgICAgICAgRXhjZXB0aW9uLl9faW5pdF9fKHNlbGYsIG1zZywgb3B0KQoKICAgIGRlZiBfX3N0cl9fKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLm1zZwoKZXJyb3IgPSBHZXRvcHRFcnJvciAjIGJhY2t3YXJkIGNvbXBhdGliaWxpdHkKCmRlZiBnZXRvcHQoYXJncywgc2hvcnRvcHRzLCBsb25nb3B0cyA9IFtdKToKICAgICIiImdldG9wdChhcmdzLCBvcHRpb25zWywgbG9uZ19vcHRpb25zXSkgLT4gb3B0cywgYXJncwoKICAgIFBhcnNlcyBjb21tYW5kIGxpbmUgb3B0aW9ucyBhbmQgcGFyYW1ldGVyIGxpc3QuICBhcmdzIGlzIHRoZQogICAgYXJndW1lbnQgbGlzdCB0byBiZSBwYXJzZWQsIHdpdGhvdXQgdGhlIGxlYWRpbmcgcmVmZXJlbmNlIHRvIHRoZQogICAgcnVubmluZyBwcm9ncmFtLiAgVHlwaWNhbGx5LCB0aGlzIG1lYW5zICJzeXMuYXJndlsxOl0iLiAgc2hvcnRvcHRzCiAgICBpcyB0aGUgc3RyaW5nIG9mIG9wdGlvbiBsZXR0ZXJzIHRoYXQgdGhlIHNjcmlwdCB3YW50cyB0bwogICAgcmVjb2duaXplLCB3aXRoIG9wdGlvbnMgdGhhdCByZXF1aXJlIGFuIGFyZ3VtZW50IGZvbGxvd2VkIGJ5IGEKICAgIGNvbG9uIChpLmUuLCB0aGUgc2FtZSBmb3JtYXQgdGhhdCBVbml4IGdldG9wdCgpIHVzZXMpLiAgSWYKICAgIHNwZWNpZmllZCwgbG9uZ29wdHMgaXMgYSBsaXN0IG9mIHN0cmluZ3Mgd2l0aCB0aGUgbmFtZXMgb2YgdGhlCiAgICBsb25nIG9wdGlvbnMgd2hpY2ggc2hvdWxkIGJlIHN1cHBvcnRlZC4gIFRoZSBsZWFkaW5nICctLScKICAgIGNoYXJhY3RlcnMgc2hvdWxkIG5vdCBiZSBpbmNsdWRlZCBpbiB0aGUgb3B0aW9uIG5hbWUuICBPcHRpb25zCiAgICB3aGljaCByZXF1aXJlIGFuIGFyZ3VtZW50IHNob3VsZCBiZSBmb2xsb3dlZCBieSBhbiBlcXVhbCBzaWduCiAgICAoJz0nKS4KCiAgICBUaGUgcmV0dXJuIHZhbHVlIGNvbnNpc3RzIG9mIHR3byBlbGVtZW50czogdGhlIGZpcnN0IGlzIGEgbGlzdCBvZgogICAgKG9wdGlvbiwgdmFsdWUpIHBhaXJzOyB0aGUgc2Vjb25kIGlzIHRoZSBsaXN0IG9mIHByb2dyYW0gYXJndW1lbnRzCiAgICBsZWZ0IGFmdGVyIHRoZSBvcHRpb24gbGlzdCB3YXMgc3RyaXBwZWQgKHRoaXMgaXMgYSB0cmFpbGluZyBzbGljZQogICAgb2YgdGhlIGZpcnN0IGFyZ3VtZW50KS4gIEVhY2ggb3B0aW9uLWFuZC12YWx1ZSBwYWlyIHJldHVybmVkIGhhcwogICAgdGhlIG9wdGlvbiBhcyBpdHMgZmlyc3QgZWxlbWVudCwgcHJlZml4ZWQgd2l0aCBhIGh5cGhlbiAoZS5nLiwKICAgICcteCcpLCBhbmQgdGhlIG9wdGlvbiBhcmd1bWVudCBhcyBpdHMgc2Vjb25kIGVsZW1lbnQsIG9yIGFuIGVtcHR5CiAgICBzdHJpbmcgaWYgdGhlIG9wdGlvbiBoYXMgbm8gYXJndW1lbnQuICBUaGUgb3B0aW9ucyBvY2N1ciBpbiB0aGUKICAgIGxpc3QgaW4gdGhlIHNhbWUgb3JkZXIgaW4gd2hpY2ggdGhleSB3ZXJlIGZvdW5kLCB0aHVzIGFsbG93aW5nCiAgICBtdWx0aXBsZSBvY2N1cnJlbmNlcy4gIExvbmcgYW5kIHNob3J0IG9wdGlvbnMgbWF5IGJlIG1peGVkLgoKICAgICIiIgoKICAgIG9wdHMgPSBbXQogICAgaWYgdHlwZShsb25nb3B0cykgPT0gdHlwZSgiIik6CiAgICAgICAgbG9uZ29wdHMgPSBbbG9uZ29wdHNdCiAgICBlbHNlOgogICAgICAgIGxvbmdvcHRzID0gbGlzdChsb25nb3B0cykKICAgIHdoaWxlIGFyZ3MgYW5kIGFyZ3NbMF0uc3RhcnRzd2l0aCgnLScpIGFuZCBhcmdzWzBdICE9ICctJzoKICAgICAgICBpZiBhcmdzWzBdID09ICctLSc6CiAgICAgICAgICAgIGFyZ3MgPSBhcmdzWzE6XQogICAgICAgICAgICBicmVhawogICAgICAgIGlmIGFyZ3NbMF0uc3RhcnRzd2l0aCgnLS0nKToKICAgICAgICAgICAgb3B0cywgYXJncyA9IGRvX2xvbmdzKG9wdHMsIGFyZ3NbMF1bMjpdLCBsb25nb3B0cywgYXJnc1sxOl0pCiAgICAgICAgZWxzZToKICAgICAgICAgICAgb3B0cywgYXJncyA9IGRvX3Nob3J0cyhvcHRzLCBhcmdzWzBdWzE6XSwgc2hvcnRvcHRzLCBhcmdzWzE6XSkKCiAgICByZXR1cm4gb3B0cywgYXJncwoKZGVmIGdudV9nZXRvcHQoYXJncywgc2hvcnRvcHRzLCBsb25nb3B0cyA9IFtdKToKICAgICIiImdldG9wdChhcmdzLCBvcHRpb25zWywgbG9uZ19vcHRpb25zXSkgLT4gb3B0cywgYXJncwoKICAgIFRoaXMgZnVuY3Rpb24gd29ya3MgbGlrZSBnZXRvcHQoKSwgZXhjZXB0IHRoYXQgR05VIHN0eWxlIHNjYW5uaW5nCiAgICBtb2RlIGlzIHVzZWQgYnkgZGVmYXVsdC4gVGhpcyBtZWFucyB0aGF0IG9wdGlvbiBhbmQgbm9uLW9wdGlvbgogICAgYXJndW1lbnRzIG1heSBiZSBpbnRlcm1peGVkLiBUaGUgZ2V0b3B0KCkgZnVuY3Rpb24gc3RvcHMKICAgIHByb2Nlc3Npbmcgb3B0aW9ucyBhcyBzb29uIGFzIGEgbm9uLW9wdGlvbiBhcmd1bWVudCBpcwogICAgZW5jb3VudGVyZWQuCgogICAgSWYgdGhlIGZpcnN0IGNoYXJhY3RlciBvZiB0aGUgb3B0aW9uIHN0cmluZyBpcyBgKycsIG9yIGlmIHRoZQogICAgZW52aXJvbm1lbnQgdmFyaWFibGUgUE9TSVhMWV9DT1JSRUNUIGlzIHNldCwgdGhlbiBvcHRpb24KICAgIHByb2Nlc3Npbmcgc3RvcHMgYXMgc29vbiBhcyBhIG5vbi1vcHRpb24gYXJndW1lbnQgaXMgZW5jb3VudGVyZWQuCgogICAgIiIiCgogICAgb3B0cyA9IFtdCiAgICBwcm9nX2FyZ3MgPSBbXQogICAgaWYgaXNpbnN0YW5jZShsb25nb3B0cywgc3RyKToKICAgICAgICBsb25nb3B0cyA9IFtsb25nb3B0c10KICAgIGVsc2U6CiAgICAgICAgbG9uZ29wdHMgPSBsaXN0KGxvbmdvcHRzKQoKICAgICMgQWxsb3cgb3B0aW9ucyBhZnRlciBub24tb3B0aW9uIGFyZ3VtZW50cz8KICAgIGlmIHNob3J0b3B0cy5zdGFydHN3aXRoKCcrJyk6CiAgICAgICAgc2hvcnRvcHRzID0gc2hvcnRvcHRzWzE6XQogICAgICAgIGFsbF9vcHRpb25zX2ZpcnN0ID0gVHJ1ZQogICAgZWxpZiBvcy5lbnZpcm9uLmdldCgiUE9TSVhMWV9DT1JSRUNUIik6CiAgICAgICAgYWxsX29wdGlvbnNfZmlyc3QgPSBUcnVlCiAgICBlbHNlOgogICAgICAgIGFsbF9vcHRpb25zX2ZpcnN0ID0gRmFsc2UKCiAgICB3aGlsZSBhcmdzOgogICAgICAgIGlmIGFyZ3NbMF0gPT0gJy0tJzoKICAgICAgICAgICAgcHJvZ19hcmdzICs9IGFyZ3NbMTpdCiAgICAgICAgICAgIGJyZWFrCgogICAgICAgIGlmIGFyZ3NbMF1bOjJdID09ICctLSc6CiAgICAgICAgICAgIG9wdHMsIGFyZ3MgPSBkb19sb25ncyhvcHRzLCBhcmdzWzBdWzI6XSwgbG9uZ29wdHMsIGFyZ3NbMTpdKQogICAgICAgIGVsaWYgYXJnc1swXVs6MV0gPT0gJy0nIGFuZCBhcmdzWzBdICE9ICctJzoKICAgICAgICAgICAgb3B0cywgYXJncyA9IGRvX3Nob3J0cyhvcHRzLCBhcmdzWzBdWzE6XSwgc2hvcnRvcHRzLCBhcmdzWzE6XSkKICAgICAgICBlbHNlOgogICAgICAgICAgICBpZiBhbGxfb3B0aW9uc19maXJzdDoKICAgICAgICAgICAgICAgIHByb2dfYXJncyArPSBhcmdzCiAgICAgICAgICAgICAgICBicmVhawogICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgcHJvZ19hcmdzLmFwcGVuZChhcmdzWzBdKQogICAgICAgICAgICAgICAgYXJncyA9IGFyZ3NbMTpdCgogICAgcmV0dXJuIG9wdHMsIHByb2dfYXJncwoKZGVmIGRvX2xvbmdzKG9wdHMsIG9wdCwgbG9uZ29wdHMsIGFyZ3MpOgogICAgdHJ5OgogICAgICAgIGkgPSBvcHQuaW5kZXgoJz0nKQogICAgZXhjZXB0IFZhbHVlRXJyb3I6CiAgICAgICAgb3B0YXJnID0gTm9uZQogICAgZWxzZToKICAgICAgICBvcHQsIG9wdGFyZyA9IG9wdFs6aV0sIG9wdFtpKzE6XQoKICAgIGhhc19hcmcsIG9wdCA9IGxvbmdfaGFzX2FyZ3Mob3B0LCBsb25nb3B0cykKICAgIGlmIGhhc19hcmc6CiAgICAgICAgaWYgb3B0YXJnIGlzIE5vbmU6CiAgICAgICAgICAgIGlmIG5vdCBhcmdzOgogICAgICAgICAgICAgICAgcmFpc2UgR2V0b3B0RXJyb3IoJ29wdGlvbiAtLSVzIHJlcXVpcmVzIGFyZ3VtZW50JyAlIG9wdCwgb3B0KQogICAgICAgICAgICBvcHRhcmcsIGFyZ3MgPSBhcmdzWzBdLCBhcmdzWzE6XQogICAgZWxpZiBvcHRhcmc6CiAgICAgICAgcmFpc2UgR2V0b3B0RXJyb3IoJ29wdGlvbiAtLSVzIG11c3Qgbm90IGhhdmUgYW4gYXJndW1lbnQnICUgb3B0LCBvcHQpCiAgICBvcHRzLmFwcGVuZCgoJy0tJyArIG9wdCwgb3B0YXJnIG9yICcnKSkKICAgIHJldHVybiBvcHRzLCBhcmdzCgojIFJldHVybjoKIyAgIGhhc19hcmc/CiMgICBmdWxsIG9wdGlvbiBuYW1lCmRlZiBsb25nX2hhc19hcmdzKG9wdCwgbG9uZ29wdHMpOgogICAgcG9zc2liaWxpdGllcyA9IFtvIGZvciBvIGluIGxvbmdvcHRzIGlmIG8uc3RhcnRzd2l0aChvcHQpXQogICAgaWYgbm90IHBvc3NpYmlsaXRpZXM6CiAgICAgICAgcmFpc2UgR2V0b3B0RXJyb3IoJ29wdGlvbiAtLSVzIG5vdCByZWNvZ25pemVkJyAlIG9wdCwgb3B0KQogICAgIyBJcyB0aGVyZSBhbiBleGFjdCBtYXRjaD8KICAgIGlmIG9wdCBpbiBwb3NzaWJpbGl0aWVzOgogICAgICAgIHJldHVybiBGYWxzZSwgb3B0CiAgICBlbGlmIG9wdCArICc9JyBpbiBwb3NzaWJpbGl0aWVzOgogICAgICAgIHJldHVybiBUcnVlLCBvcHQKICAgICMgTm8gZXhhY3QgbWF0Y2gsIHNvIGJldHRlciBiZSB1bmlxdWUuCiAgICBpZiBsZW4ocG9zc2liaWxpdGllcykgPiAxOgogICAgICAgICMgWFhYIHNpbmNlIHBvc3NpYmlsaXRpZXMgY29udGFpbnMgYWxsIHZhbGlkIGNvbnRpbnVhdGlvbnMsIG1pZ2h0IGJlCiAgICAgICAgIyBuaWNlIHRvIHdvcmsgdGhlbSBpbnRvIHRoZSBlcnJvciBtc2cKICAgICAgICByYWlzZSBHZXRvcHRFcnJvcignb3B0aW9uIC0tJXMgbm90IGEgdW5pcXVlIHByZWZpeCcgJSBvcHQsIG9wdCkKICAgIGFzc2VydCBsZW4ocG9zc2liaWxpdGllcykgPT0gMQogICAgdW5pcXVlX21hdGNoID0gcG9zc2liaWxpdGllc1swXQogICAgaGFzX2FyZyA9IHVuaXF1ZV9tYXRjaC5lbmRzd2l0aCgnPScpCiAgICBpZiBoYXNfYXJnOgogICAgICAgIHVuaXF1ZV9tYXRjaCA9IHVuaXF1ZV9tYXRjaFs6LTFdCiAgICByZXR1cm4gaGFzX2FyZywgdW5pcXVlX21hdGNoCgpkZWYgZG9fc2hvcnRzKG9wdHMsIG9wdHN0cmluZywgc2hvcnRvcHRzLCBhcmdzKToKICAgIHdoaWxlIG9wdHN0cmluZyAhPSAnJzoKICAgICAgICBvcHQsIG9wdHN0cmluZyA9IG9wdHN0cmluZ1swXSwgb3B0c3RyaW5nWzE6XQogICAgICAgIGlmIHNob3J0X2hhc19hcmcob3B0LCBzaG9ydG9wdHMpOgogICAgICAgICAgICBpZiBvcHRzdHJpbmcgPT0gJyc6CiAgICAgICAgICAgICAgICBpZiBub3QgYXJnczoKICAgICAgICAgICAgICAgICAgICByYWlzZSBHZXRvcHRFcnJvcignb3B0aW9uIC0lcyByZXF1aXJlcyBhcmd1bWVudCcgJSBvcHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0KQogICAgICAgICAgICAgICAgb3B0c3RyaW5nLCBhcmdzID0gYXJnc1swXSwgYXJnc1sxOl0KICAgICAgICAgICAgb3B0YXJnLCBvcHRzdHJpbmcgPSBvcHRzdHJpbmcsICcnCiAgICAgICAgZWxzZToKICAgICAgICAgICAgb3B0YXJnID0gJycKICAgICAgICBvcHRzLmFwcGVuZCgoJy0nICsgb3B0LCBvcHRhcmcpKQogICAgcmV0dXJuIG9wdHMsIGFyZ3MKCmRlZiBzaG9ydF9oYXNfYXJnKG9wdCwgc2hvcnRvcHRzKToKICAgIGZvciBpIGluIHJhbmdlKGxlbihzaG9ydG9wdHMpKToKICAgICAgICBpZiBvcHQgPT0gc2hvcnRvcHRzW2ldICE9ICc6JzoKICAgICAgICAgICAgcmV0dXJuIHNob3J0b3B0cy5zdGFydHN3aXRoKCc6JywgaSsxKQogICAgcmFpc2UgR2V0b3B0RXJyb3IoJ29wdGlvbiAtJXMgbm90IHJlY29nbml6ZWQnICUgb3B0LCBvcHQpCgppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOgogICAgaW1wb3J0IHN5cwogICAgcHJpbnQgZ2V0b3B0KHN5cy5hcmd2WzE6XSwgImE6YiIsIFsiYWxwaGE9IiwgImJldGEiXSkK