IyAtKi0gY29kaW5nOiBpc28tODg1OS0xIC0qLQoiIiIgQ29kZWMgZm9yIHRoZSBQdW5pY29kZSBlbmNvZGluZywgYXMgc3BlY2lmaWVkIGluIFJGQyAzNDkyCgpXcml0dGVuIGJ5IE1hcnRpbiB2LiBM9ndpcy4KIiIiCgppbXBvcnQgY29kZWNzCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMgRW5jb2RpbmcgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwoKZGVmIHNlZ3JlZ2F0ZShzdHIpOgogICAgIiIiMy4xIEJhc2ljIGNvZGUgcG9pbnQgc2VncmVnYXRpb24iIiIKICAgIGJhc2UgPSBbXQogICAgZXh0ZW5kZWQgPSB7fQogICAgZm9yIGMgaW4gc3RyOgogICAgICAgIGlmIG9yZChjKSA8IDEyODoKICAgICAgICAgICAgYmFzZS5hcHBlbmQoYykKICAgICAgICBlbHNlOgogICAgICAgICAgICBleHRlbmRlZFtjXSA9IDEKICAgIGV4dGVuZGVkID0gZXh0ZW5kZWQua2V5cygpCiAgICBleHRlbmRlZC5zb3J0KCkKICAgIHJldHVybiAiIi5qb2luKGJhc2UpLmVuY29kZSgiYXNjaWkiKSxleHRlbmRlZAoKZGVmIHNlbGVjdGl2ZV9sZW4oc3RyLCBtYXgpOgogICAgIiIiUmV0dXJuIHRoZSBsZW5ndGggb2Ygc3RyLCBjb25zaWRlcmluZyBvbmx5IGNoYXJhY3RlcnMgYmVsb3cgbWF4LiIiIgogICAgcmVzID0gMAogICAgZm9yIGMgaW4gc3RyOgogICAgICAgIGlmIG9yZChjKSA8IG1heDoKICAgICAgICAgICAgcmVzICs9IDEKICAgIHJldHVybiByZXMKCmRlZiBzZWxlY3RpdmVfZmluZChzdHIsIGNoYXIsIGluZGV4LCBwb3MpOgogICAgIiIiUmV0dXJuIGEgcGFpciAoaW5kZXgsIHBvcyksIGluZGljYXRpbmcgdGhlIG5leHQgb2NjdXJyZW5jZSBvZgogICAgY2hhciBpbiBzdHIuIGluZGV4IGlzIHRoZSBwb3NpdGlvbiBvZiB0aGUgY2hhcmFjdGVyIGNvbnNpZGVyaW5nCiAgICBvbmx5IG9yZGluYWxzIHVwIHRvIGFuZCBpbmNsdWRpbmcgY2hhciwgYW5kIHBvcyBpcyB0aGUgcG9zaXRpb24gaW4KICAgIHRoZSBmdWxsIHN0cmluZy4gaW5kZXgvcG9zIGlzIHRoZSBzdGFydGluZyBwb3NpdGlvbiBpbiB0aGUgZnVsbAogICAgc3RyaW5nLiIiIgoKICAgIGwgPSBsZW4oc3RyKQogICAgd2hpbGUgMToKICAgICAgICBwb3MgKz0gMQogICAgICAgIGlmIHBvcyA9PSBsOgogICAgICAgICAgICByZXR1cm4gKC0xLCAtMSkKICAgICAgICBjID0gc3RyW3Bvc10KICAgICAgICBpZiBjID09IGNoYXI6CiAgICAgICAgICAgIHJldHVybiBpbmRleCsxLCBwb3MKICAgICAgICBlbGlmIGMgPCBjaGFyOgogICAgICAgICAgICBpbmRleCArPSAxCgpkZWYgaW5zZXJ0aW9uX3Vuc29ydChzdHIsIGV4dGVuZGVkKToKICAgICIiIjMuMiBJbnNlcnRpb24gdW5zb3J0IGNvZGluZyIiIgogICAgb2xkY2hhciA9IDB4ODAKICAgIHJlc3VsdCA9IFtdCiAgICBvbGRpbmRleCA9IC0xCiAgICBmb3IgYyBpbiBleHRlbmRlZDoKICAgICAgICBpbmRleCA9IHBvcyA9IC0xCiAgICAgICAgY2hhciA9IG9yZChjKQogICAgICAgIGN1cmxlbiA9IHNlbGVjdGl2ZV9sZW4oc3RyLCBjaGFyKQogICAgICAgIGRlbHRhID0gKGN1cmxlbisxKSAqIChjaGFyIC0gb2xkY2hhcikKICAgICAgICB3aGlsZSAxOgogICAgICAgICAgICBpbmRleCxwb3MgPSBzZWxlY3RpdmVfZmluZChzdHIsYyxpbmRleCxwb3MpCiAgICAgICAgICAgIGlmIGluZGV4ID09IC0xOgogICAgICAgICAgICAgICAgYnJlYWsKICAgICAgICAgICAgZGVsdGEgKz0gaW5kZXggLSBvbGRpbmRleAogICAgICAgICAgICByZXN1bHQuYXBwZW5kKGRlbHRhLTEpCiAgICAgICAgICAgIG9sZGluZGV4ID0gaW5kZXgKICAgICAgICAgICAgZGVsdGEgPSAwCiAgICAgICAgb2xkY2hhciA9IGNoYXIKCiAgICByZXR1cm4gcmVzdWx0CgpkZWYgVChqLCBiaWFzKToKICAgICMgUHVueWNvZGUgcGFyYW1ldGVyczogdG1pbiA9IDEsIHRtYXggPSAyNiwgYmFzZSA9IDM2CiAgICByZXMgPSAzNiAqIChqICsgMSkgLSBiaWFzCiAgICBpZiByZXMgPCAxOiByZXR1cm4gMQogICAgaWYgcmVzID4gMjY6IHJldHVybiAyNgogICAgcmV0dXJuIHJlcwoKZGlnaXRzID0gImFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSIKZGVmIGdlbmVyYXRlX2dlbmVyYWxpemVkX2ludGVnZXIoTiwgYmlhcyk6CiAgICAiIiIzLjMgR2VuZXJhbGl6ZWQgdmFyaWFibGUtbGVuZ3RoIGludGVnZXJzIiIiCiAgICByZXN1bHQgPSBbXQogICAgaiA9IDAKICAgIHdoaWxlIDE6CiAgICAgICAgdCA9IFQoaiwgYmlhcykKICAgICAgICBpZiBOIDwgdDoKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZChkaWdpdHNbTl0pCiAgICAgICAgICAgIHJldHVybiByZXN1bHQKICAgICAgICByZXN1bHQuYXBwZW5kKGRpZ2l0c1t0ICsgKChOIC0gdCkgJSAoMzYgLSB0KSldKQogICAgICAgIE4gPSAoTiAtIHQpIC8vICgzNiAtIHQpCiAgICAgICAgaiArPSAxCgpkZWYgYWRhcHQoZGVsdGEsIGZpcnN0LCBudW1jaGFycyk6CiAgICBpZiBmaXJzdDoKICAgICAgICBkZWx0YSAvLz0gNzAwCiAgICBlbHNlOgogICAgICAgIGRlbHRhIC8vPSAyCiAgICBkZWx0YSArPSBkZWx0YSAvLyBudW1jaGFycwogICAgIyAoKGJhc2UgLSB0bWluKSAqIHRtYXgpIC8vIDIgPT0gNDU1CiAgICBkaXZpc2lvbnMgPSAwCiAgICB3aGlsZSBkZWx0YSA+IDQ1NToKICAgICAgICBkZWx0YSA9IGRlbHRhIC8vIDM1ICMgYmFzZSAtIHRtaW4KICAgICAgICBkaXZpc2lvbnMgKz0gMzYKICAgIGJpYXMgPSBkaXZpc2lvbnMgKyAoMzYgKiBkZWx0YSAvLyAoZGVsdGEgKyAzOCkpCiAgICByZXR1cm4gYmlhcwoKCmRlZiBnZW5lcmF0ZV9pbnRlZ2VycyhiYXNlbGVuLCBkZWx0YXMpOgogICAgIiIiMy40IEJpYXMgYWRhcHRhdGlvbiIiIgogICAgIyBQdW55Y29kZSBwYXJhbWV0ZXJzOiBpbml0aWFsIGJpYXMgPSA3MiwgZGFtcCA9IDcwMCwgc2tldyA9IDM4CiAgICByZXN1bHQgPSBbXQogICAgYmlhcyA9IDcyCiAgICBmb3IgcG9pbnRzLCBkZWx0YSBpbiBlbnVtZXJhdGUoZGVsdGFzKToKICAgICAgICBzID0gZ2VuZXJhdGVfZ2VuZXJhbGl6ZWRfaW50ZWdlcihkZWx0YSwgYmlhcykKICAgICAgICByZXN1bHQuZXh0ZW5kKHMpCiAgICAgICAgYmlhcyA9IGFkYXB0KGRlbHRhLCBwb2ludHM9PTAsIGJhc2VsZW4rcG9pbnRzKzEpCiAgICByZXR1cm4gIiIuam9pbihyZXN1bHQpCgpkZWYgcHVueWNvZGVfZW5jb2RlKHRleHQpOgogICAgYmFzZSwgZXh0ZW5kZWQgPSBzZWdyZWdhdGUodGV4dCkKICAgIGJhc2UgPSBiYXNlLmVuY29kZSgiYXNjaWkiKQogICAgZGVsdGFzID0gaW5zZXJ0aW9uX3Vuc29ydCh0ZXh0LCBleHRlbmRlZCkKICAgIGV4dGVuZGVkID0gZ2VuZXJhdGVfaW50ZWdlcnMobGVuKGJhc2UpLCBkZWx0YXMpCiAgICBpZiBiYXNlOgogICAgICAgIHJldHVybiBiYXNlICsgIi0iICsgZXh0ZW5kZWQKICAgIHJldHVybiBleHRlbmRlZAoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIERlY29kaW5nICMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKCmRlZiBkZWNvZGVfZ2VuZXJhbGl6ZWRfbnVtYmVyKGV4dGVuZGVkLCBleHRwb3MsIGJpYXMsIGVycm9ycyk6CiAgICAiIiIzLjMgR2VuZXJhbGl6ZWQgdmFyaWFibGUtbGVuZ3RoIGludGVnZXJzIiIiCiAgICByZXN1bHQgPSAwCiAgICB3ID0gMQogICAgaiA9IDAKICAgIHdoaWxlIDE6CiAgICAgICAgdHJ5OgogICAgICAgICAgICBjaGFyID0gb3JkKGV4dGVuZGVkW2V4dHBvc10pCiAgICAgICAgZXhjZXB0IEluZGV4RXJyb3I6CiAgICAgICAgICAgIGlmIGVycm9ycyA9PSAic3RyaWN0IjoKICAgICAgICAgICAgICAgIHJhaXNlIFVuaWNvZGVFcnJvciwgImluY29tcGxldGUgcHVuaWNvZGUgc3RyaW5nIgogICAgICAgICAgICByZXR1cm4gZXh0cG9zICsgMSwgTm9uZQogICAgICAgIGV4dHBvcyArPSAxCiAgICAgICAgaWYgMHg0MSA8PSBjaGFyIDw9IDB4NUE6ICMgQS1aCiAgICAgICAgICAgIGRpZ2l0ID0gY2hhciAtIDB4NDEKICAgICAgICBlbGlmIDB4MzAgPD0gY2hhciA8PSAweDM5OgogICAgICAgICAgICBkaWdpdCA9IGNoYXIgLSAyMiAjIDB4MzAtMjYKICAgICAgICBlbGlmIGVycm9ycyA9PSAic3RyaWN0IjoKICAgICAgICAgICAgcmFpc2UgVW5pY29kZUVycm9yKCJJbnZhbGlkIGV4dGVuZGVkIGNvZGUgcG9pbnQgJyVzJyIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICUgZXh0ZW5kZWRbZXh0cG9zXSkKICAgICAgICBlbHNlOgogICAgICAgICAgICByZXR1cm4gZXh0cG9zLCBOb25lCiAgICAgICAgdCA9IFQoaiwgYmlhcykKICAgICAgICByZXN1bHQgKz0gZGlnaXQgKiB3CiAgICAgICAgaWYgZGlnaXQgPCB0OgogICAgICAgICAgICByZXR1cm4gZXh0cG9zLCByZXN1bHQKICAgICAgICB3ID0gdyAqICgzNiAtIHQpCiAgICAgICAgaiArPSAxCgoKZGVmIGluc2VydGlvbl9zb3J0KGJhc2UsIGV4dGVuZGVkLCBlcnJvcnMpOgogICAgIiIiMy4yIEluc2VydGlvbiB1bnNvcnQgY29kaW5nIiIiCiAgICBjaGFyID0gMHg4MAogICAgcG9zID0gLTEKICAgIGJpYXMgPSA3MgogICAgZXh0cG9zID0gMAogICAgd2hpbGUgZXh0cG9zIDwgbGVuKGV4dGVuZGVkKToKICAgICAgICBuZXdwb3MsIGRlbHRhID0gZGVjb2RlX2dlbmVyYWxpemVkX251bWJlcihleHRlbmRlZCwgZXh0cG9zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJpYXMsIGVycm9ycykKICAgICAgICBpZiBkZWx0YSBpcyBOb25lOgogICAgICAgICAgICAjIFRoZXJlIHdhcyBhbiBlcnJvciBpbiBkZWNvZGluZy4gV2UgY2FuJ3QgY29udGludWUgYmVjYXVzZQogICAgICAgICAgICAjIHN5bmNocm9uaXphdGlvbiBpcyBsb3N0LgogICAgICAgICAgICByZXR1cm4gYmFzZQogICAgICAgIHBvcyArPSBkZWx0YSsxCiAgICAgICAgY2hhciArPSBwb3MgLy8gKGxlbihiYXNlKSArIDEpCiAgICAgICAgaWYgY2hhciA+IDB4MTBGRkZGOgogICAgICAgICAgICBpZiBlcnJvcnMgPT0gInN0cmljdCI6CiAgICAgICAgICAgICAgICByYWlzZSBVbmljb2RlRXJyb3IsICgiSW52YWxpZCBjaGFyYWN0ZXIgVSsleCIgJSBjaGFyKQogICAgICAgICAgICBjaGFyID0gb3JkKCc/JykKICAgICAgICBwb3MgPSBwb3MgJSAobGVuKGJhc2UpICsgMSkKICAgICAgICBiYXNlID0gYmFzZVs6cG9zXSArIHVuaWNocihjaGFyKSArIGJhc2VbcG9zOl0KICAgICAgICBiaWFzID0gYWRhcHQoZGVsdGEsIChleHRwb3MgPT0gMCksIGxlbihiYXNlKSkKICAgICAgICBleHRwb3MgPSBuZXdwb3MKICAgIHJldHVybiBiYXNlCgpkZWYgcHVueWNvZGVfZGVjb2RlKHRleHQsIGVycm9ycyk6CiAgICBwb3MgPSB0ZXh0LnJmaW5kKCItIikKICAgIGlmIHBvcyA9PSAtMToKICAgICAgICBiYXNlID0gIiIKICAgICAgICBleHRlbmRlZCA9IHRleHQKICAgIGVsc2U6CiAgICAgICAgYmFzZSA9IHRleHRbOnBvc10KICAgICAgICBleHRlbmRlZCA9IHRleHRbcG9zKzE6XQogICAgYmFzZSA9IHVuaWNvZGUoYmFzZSwgImFzY2lpIiwgZXJyb3JzKQogICAgZXh0ZW5kZWQgPSBleHRlbmRlZC51cHBlcigpCiAgICByZXR1cm4gaW5zZXJ0aW9uX3NvcnQoYmFzZSwgZXh0ZW5kZWQsIGVycm9ycykKCiMjIyBDb2RlYyBBUElzCgpjbGFzcyBDb2RlYyhjb2RlY3MuQ29kZWMpOgoKICAgIGRlZiBlbmNvZGUoc2VsZixpbnB1dCxlcnJvcnM9J3N0cmljdCcpOgogICAgICAgIHJlcyA9IHB1bnljb2RlX2VuY29kZShpbnB1dCkKICAgICAgICByZXR1cm4gcmVzLCBsZW4oaW5wdXQpCgogICAgZGVmIGRlY29kZShzZWxmLGlucHV0LGVycm9ycz0nc3RyaWN0Jyk6CiAgICAgICAgaWYgZXJyb3JzIG5vdCBpbiAoJ3N0cmljdCcsICdyZXBsYWNlJywgJ2lnbm9yZScpOgogICAgICAgICAgICByYWlzZSBVbmljb2RlRXJyb3IsICJVbnN1cHBvcnRlZCBlcnJvciBoYW5kbGluZyAiK2Vycm9ycwogICAgICAgIHJlcyA9IHB1bnljb2RlX2RlY29kZShpbnB1dCwgZXJyb3JzKQogICAgICAgIHJldHVybiByZXMsIGxlbihpbnB1dCkKCmNsYXNzIEluY3JlbWVudGFsRW5jb2Rlcihjb2RlY3MuSW5jcmVtZW50YWxFbmNvZGVyKToKICAgIGRlZiBlbmNvZGUoc2VsZiwgaW5wdXQsIGZpbmFsPUZhbHNlKToKICAgICAgICByZXR1cm4gcHVueWNvZGVfZW5jb2RlKGlucHV0KQoKY2xhc3MgSW5jcmVtZW50YWxEZWNvZGVyKGNvZGVjcy5JbmNyZW1lbnRhbERlY29kZXIpOgogICAgZGVmIGRlY29kZShzZWxmLCBpbnB1dCwgZmluYWw9RmFsc2UpOgogICAgICAgIGlmIHNlbGYuZXJyb3JzIG5vdCBpbiAoJ3N0cmljdCcsICdyZXBsYWNlJywgJ2lnbm9yZScpOgogICAgICAgICAgICByYWlzZSBVbmljb2RlRXJyb3IsICJVbnN1cHBvcnRlZCBlcnJvciBoYW5kbGluZyAiK3NlbGYuZXJyb3JzCiAgICAgICAgcmV0dXJuIHB1bnljb2RlX2RlY29kZShpbnB1dCwgc2VsZi5lcnJvcnMpCgpjbGFzcyBTdHJlYW1Xcml0ZXIoQ29kZWMsY29kZWNzLlN0cmVhbVdyaXRlcik6CiAgICBwYXNzCgpjbGFzcyBTdHJlYW1SZWFkZXIoQ29kZWMsY29kZWNzLlN0cmVhbVJlYWRlcik6CiAgICBwYXNzCgojIyMgZW5jb2RpbmdzIG1vZHVsZSBBUEkKCmRlZiBnZXRyZWdlbnRyeSgpOgogICAgcmV0dXJuIGNvZGVjcy5Db2RlY0luZm8oCiAgICAgICAgbmFtZT0ncHVueWNvZGUnLAogICAgICAgIGVuY29kZT1Db2RlYygpLmVuY29kZSwKICAgICAgICBkZWNvZGU9Q29kZWMoKS5kZWNvZGUsCiAgICAgICAgaW5jcmVtZW50YWxlbmNvZGVyPUluY3JlbWVudGFsRW5jb2RlciwKICAgICAgICBpbmNyZW1lbnRhbGRlY29kZXI9SW5jcmVtZW50YWxEZWNvZGVyLAogICAgICAgIHN0cmVhbXdyaXRlcj1TdHJlYW1Xcml0ZXIsCiAgICAgICAgc3RyZWFtcmVhZGVyPVN0cmVhbVJlYWRlciwKICAgICkK