LyoKICBTb3J0VGFibGUKICB2ZXJzaW9uIDIKICA3dGggQXByaWwgMjAwNwogIFN0dWFydCBMYW5ncmlkZ2UsIGh0dHA6Ly93d3cua3J5b2dlbml4Lm9yZy9jb2RlL2Jyb3dzZXIvc29ydHRhYmxlLwogIAogIEluc3RydWN0aW9uczoKICBEb3dubG9hZCB0aGlzIGZpbGUKICBBZGQgPHNjcmlwdCBzcmM9InNvcnR0YWJsZS5qcyI+PC9zY3JpcHQ+IHRvIHlvdXIgSFRNTAogIEFkZCBjbGFzcz0ic29ydGFibGUiIHRvIGFueSB0YWJsZSB5b3UnZCBsaWtlIHRvIG1ha2Ugc29ydGFibGUKICBDbGljayBvbiB0aGUgaGVhZGVycyB0byBzb3J0CiAgCiAgVGhhbmtzIHRvIG1hbnksIG1hbnkgcGVvcGxlIGZvciBjb250cmlidXRpb25zIGFuZCBzdWdnZXN0aW9ucy4KICBMaWNlbmNlZCBhcyBYMTE6IGh0dHA6Ly93d3cua3J5b2dlbml4Lm9yZy9jb2RlL2Jyb3dzZXIvbGljZW5jZS5odG1sCiAgVGhpcyBiYXNpY2FsbHkgbWVhbnM6IGRvIHdoYXQgeW91IHdhbnQgd2l0aCBpdC4KKi8KCiAKdmFyIHN0SXNJRSA9IC8qQGNjX29uIUAqL2ZhbHNlOwoKc29ydHRhYmxlID0gewogIGluaXQ6IGZ1bmN0aW9uKCkgewogICAgLy8gcXVpdCBpZiB0aGlzIGZ1bmN0aW9uIGhhcyBhbHJlYWR5IGJlZW4gY2FsbGVkCiAgICBpZiAoYXJndW1lbnRzLmNhbGxlZS5kb25lKSByZXR1cm47CiAgICAvLyBmbGFnIHRoaXMgZnVuY3Rpb24gc28gd2UgZG9uJ3QgZG8gdGhlIHNhbWUgdGhpbmcgdHdpY2UKICAgIGFyZ3VtZW50cy5jYWxsZWUuZG9uZSA9IHRydWU7CiAgICAvLyBraWxsIHRoZSB0aW1lcgogICAgaWYgKF90aW1lcikgY2xlYXJJbnRlcnZhbChfdGltZXIpOwogICAgCiAgICBpZiAoIWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgfHwgIWRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKSByZXR1cm47CiAgICAKICAgIHNvcnR0YWJsZS5EQVRFX1JFID0gL14oXGRcZD8pW1wvXC4tXShcZFxkPylbXC9cLi1dKChcZFxkKT9cZFxkKSQvOwogICAgCiAgICBmb3JFYWNoKGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCd0YWJsZScpLCBmdW5jdGlvbih0YWJsZSkgewogICAgICBpZiAodGFibGUuY2xhc3NOYW1lLnNlYXJjaCgvXGJzb3J0YWJsZVxiLykgIT0gLTEpIHsKICAgICAgICBzb3J0dGFibGUubWFrZVNvcnRhYmxlKHRhYmxlKTsKICAgICAgfQogICAgfSk7CiAgICAKICB9LAogIAogIG1ha2VTb3J0YWJsZTogZnVuY3Rpb24odGFibGUpIHsKICAgIGlmICh0YWJsZS5nZXRFbGVtZW50c0J5VGFnTmFtZSgndGhlYWQnKS5sZW5ndGggPT0gMCkgewogICAgICAvLyB0YWJsZSBkb2Vzbid0IGhhdmUgYSB0SGVhZC4gU2luY2UgaXQgc2hvdWxkIGhhdmUsIGNyZWF0ZSBvbmUgYW5kCiAgICAgIC8vIHB1dCB0aGUgZmlyc3QgdGFibGUgcm93IGluIGl0LgogICAgICB0aGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCd0aGVhZCcpOwogICAgICB0aGUuYXBwZW5kQ2hpbGQodGFibGUucm93c1swXSk7CiAgICAgIHRhYmxlLmluc2VydEJlZm9yZSh0aGUsdGFibGUuZmlyc3RDaGlsZCk7CiAgICB9CiAgICAvLyBTYWZhcmkgZG9lc24ndCBzdXBwb3J0IHRhYmxlLnRIZWFkLCBzaWdoCiAgICBpZiAodGFibGUudEhlYWQgPT0gbnVsbCkgdGFibGUudEhlYWQgPSB0YWJsZS5nZXRFbGVtZW50c0J5VGFnTmFtZSgndGhlYWQnKVswXTsKICAgIAogICAgaWYgKHRhYmxlLnRIZWFkLnJvd3MubGVuZ3RoICE9IDEpIHJldHVybjsgLy8gY2FuJ3QgY29wZSB3aXRoIHR3byBoZWFkZXIgcm93cwogICAgCiAgICAvLyBTb3J0dGFibGUgdjEgcHV0IHJvd3Mgd2l0aCBhIGNsYXNzIG9mICJzb3J0Ym90dG9tIiBhdCB0aGUgYm90dG9tIChhcwogICAgLy8gInRvdGFsIiByb3dzLCBmb3IgZXhhbXBsZSkuIFRoaXMgaXMgQiZSLCBzaW5jZSB3aGF0IHlvdSdyZSBzdXBwb3NlZAogICAgLy8gdG8gZG8gaXMgcHV0IHRoZW0gaW4gYSB0Zm9vdC4gU28sIGlmIHRoZXJlIGFyZSBzb3J0Ym90dG9tIHJvd3MsCiAgICAvLyBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksIG1vdmUgdGhlbSB0byB0Zm9vdCAoY3JlYXRpbmcgaXQgaWYgbmVlZGVkKS4KICAgIHNvcnRib3R0b21yb3dzID0gW107CiAgICBmb3IgKHZhciBpPTA7IGk8dGFibGUucm93cy5sZW5ndGg7IGkrKykgewogICAgICBpZiAodGFibGUucm93c1tpXS5jbGFzc05hbWUuc2VhcmNoKC9cYnNvcnRib3R0b21cYi8pICE9IC0xKSB7CiAgICAgICAgc29ydGJvdHRvbXJvd3Nbc29ydGJvdHRvbXJvd3MubGVuZ3RoXSA9IHRhYmxlLnJvd3NbaV07CiAgICAgIH0KICAgIH0KICAgIGlmIChzb3J0Ym90dG9tcm93cykgewogICAgICBpZiAodGFibGUudEZvb3QgPT0gbnVsbCkgewogICAgICAgIC8vIHRhYmxlIGRvZXNuJ3QgaGF2ZSBhIHRmb290LiBDcmVhdGUgb25lLgogICAgICAgIHRmbyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3Rmb290Jyk7CiAgICAgICAgdGFibGUuYXBwZW5kQ2hpbGQodGZvKTsKICAgICAgfQogICAgICBmb3IgKHZhciBpPTA7IGk8c29ydGJvdHRvbXJvd3MubGVuZ3RoOyBpKyspIHsKICAgICAgICB0Zm8uYXBwZW5kQ2hpbGQoc29ydGJvdHRvbXJvd3NbaV0pOwogICAgICB9CiAgICAgIGRlbGV0ZSBzb3J0Ym90dG9tcm93czsKICAgIH0KICAgIAogICAgLy8gd29yayB0aHJvdWdoIGVhY2ggY29sdW1uIGFuZCBjYWxjdWxhdGUgaXRzIHR5cGUKICAgIGhlYWRyb3cgPSB0YWJsZS50SGVhZC5yb3dzWzBdLmNlbGxzOwogICAgZm9yICh2YXIgaT0wOyBpPGhlYWRyb3cubGVuZ3RoOyBpKyspIHsKICAgICAgLy8gbWFudWFsbHkgb3ZlcnJpZGUgdGhlIHR5cGUgd2l0aCBhIHNvcnR0YWJsZV90eXBlIGF0dHJpYnV0ZQogICAgICBpZiAoIWhlYWRyb3dbaV0uY2xhc3NOYW1lLm1hdGNoKC9cYnNvcnR0YWJsZV9ub3NvcnRcYi8pKSB7IC8vIHNraXAgdGhpcyBjb2wKICAgICAgICBtdGNoID0gaGVhZHJvd1tpXS5jbGFzc05hbWUubWF0Y2goL1xic29ydHRhYmxlXyhbYS16MC05XSspXGIvKTsKICAgICAgICBpZiAobXRjaCkgeyBvdmVycmlkZSA9IG10Y2hbMV07IH0KCSAgICAgIGlmIChtdGNoICYmIHR5cGVvZiBzb3J0dGFibGVbInNvcnRfIitvdmVycmlkZV0gPT0gJ2Z1bmN0aW9uJykgewoJICAgICAgICBoZWFkcm93W2ldLnNvcnR0YWJsZV9zb3J0ZnVuY3Rpb24gPSBzb3J0dGFibGVbInNvcnRfIitvdmVycmlkZV07CgkgICAgICB9IGVsc2UgewoJICAgICAgICBoZWFkcm93W2ldLnNvcnR0YWJsZV9zb3J0ZnVuY3Rpb24gPSBzb3J0dGFibGUuZ3Vlc3NUeXBlKHRhYmxlLGkpOwoJICAgICAgfQoJICAgICAgLy8gbWFrZSBpdCBjbGlja2FibGUgdG8gc29ydAoJICAgICAgaGVhZHJvd1tpXS5zb3J0dGFibGVfY29sdW1uaW5kZXggPSBpOwoJICAgICAgaGVhZHJvd1tpXS5zb3J0dGFibGVfdGJvZHkgPSB0YWJsZS50Qm9kaWVzWzBdOwoJICAgICAgZGVhbl9hZGRFdmVudChoZWFkcm93W2ldLCJjbGljayIsIGZ1bmN0aW9uKGUpIHsKCiAgICAgICAgICBpZiAodGhpcy5jbGFzc05hbWUuc2VhcmNoKC9cYnNvcnR0YWJsZV9zb3J0ZWRcYi8pICE9IC0xKSB7CiAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGFscmVhZHkgc29ydGVkIGJ5IHRoaXMgY29sdW1uLCBqdXN0IAogICAgICAgICAgICAvLyByZXZlcnNlIHRoZSB0YWJsZSwgd2hpY2ggaXMgcXVpY2tlcgogICAgICAgICAgICBzb3J0dGFibGUucmV2ZXJzZSh0aGlzLnNvcnR0YWJsZV90Ym9keSk7CiAgICAgICAgICAgIHRoaXMuY2xhc3NOYW1lID0gdGhpcy5jbGFzc05hbWUucmVwbGFjZSgnc29ydHRhYmxlX3NvcnRlZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnc29ydHRhYmxlX3NvcnRlZF9yZXZlcnNlJyk7CiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ2hpbGQoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NvcnR0YWJsZV9zb3J0ZndkaW5kJykpOwogICAgICAgICAgICBzb3J0cmV2aW5kID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnc3BhbicpOwogICAgICAgICAgICBzb3J0cmV2aW5kLmlkID0gInNvcnR0YWJsZV9zb3J0cmV2aW5kIjsKICAgICAgICAgICAgc29ydHJldmluZC5pbm5lckhUTUwgPSBzdElzSUUgPyAnJm5ic3A8Zm9udCBmYWNlPSJ3ZWJkaW5ncyI+NTwvZm9udD4nIDogJyZuYnNwOyYjeDI1QjQ7JzsKICAgICAgICAgICAgdGhpcy5hcHBlbmRDaGlsZChzb3J0cmV2aW5kKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgaWYgKHRoaXMuY2xhc3NOYW1lLnNlYXJjaCgvXGJzb3J0dGFibGVfc29ydGVkX3JldmVyc2VcYi8pICE9IC0xKSB7CiAgICAgICAgICAgIC8vIGlmIHdlJ3JlIGFscmVhZHkgc29ydGVkIGJ5IHRoaXMgY29sdW1uIGluIHJldmVyc2UsIGp1c3QgCiAgICAgICAgICAgIC8vIHJlLXJldmVyc2UgdGhlIHRhYmxlLCB3aGljaCBpcyBxdWlja2VyCiAgICAgICAgICAgIHNvcnR0YWJsZS5yZXZlcnNlKHRoaXMuc29ydHRhYmxlX3Rib2R5KTsKICAgICAgICAgICAgdGhpcy5jbGFzc05hbWUgPSB0aGlzLmNsYXNzTmFtZS5yZXBsYWNlKCdzb3J0dGFibGVfc29ydGVkX3JldmVyc2UnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NvcnR0YWJsZV9zb3J0ZWQnKTsKICAgICAgICAgICAgdGhpcy5yZW1vdmVDaGlsZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc29ydHRhYmxlX3NvcnRyZXZpbmQnKSk7CiAgICAgICAgICAgIHNvcnRmd2RpbmQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7CiAgICAgICAgICAgIHNvcnRmd2RpbmQuaWQgPSAic29ydHRhYmxlX3NvcnRmd2RpbmQiOwogICAgICAgICAgICBzb3J0ZndkaW5kLmlubmVySFRNTCA9IHN0SXNJRSA/ICcmbmJzcDxmb250IGZhY2U9IndlYmRpbmdzIj42PC9mb250PicgOiAnJm5ic3A7JiN4MjVCRTsnOwogICAgICAgICAgICB0aGlzLmFwcGVuZENoaWxkKHNvcnRmd2RpbmQpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9CiAgICAgICAgICAKICAgICAgICAgIC8vIHJlbW92ZSBzb3J0dGFibGVfc29ydGVkIGNsYXNzZXMKICAgICAgICAgIHRoZWFkcm93ID0gdGhpcy5wYXJlbnROb2RlOwogICAgICAgICAgZm9yRWFjaCh0aGVhZHJvdy5jaGlsZE5vZGVzLCBmdW5jdGlvbihjZWxsKSB7CiAgICAgICAgICAgIGlmIChjZWxsLm5vZGVUeXBlID09IDEpIHsgLy8gYW4gZWxlbWVudAogICAgICAgICAgICAgIGNlbGwuY2xhc3NOYW1lID0gY2VsbC5jbGFzc05hbWUucmVwbGFjZSgnc29ydHRhYmxlX3NvcnRlZF9yZXZlcnNlJywnJyk7CiAgICAgICAgICAgICAgY2VsbC5jbGFzc05hbWUgPSBjZWxsLmNsYXNzTmFtZS5yZXBsYWNlKCdzb3J0dGFibGVfc29ydGVkJywnJyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgICAgc29ydGZ3ZGluZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzb3J0dGFibGVfc29ydGZ3ZGluZCcpOwogICAgICAgICAgaWYgKHNvcnRmd2RpbmQpIHsgc29ydGZ3ZGluZC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHNvcnRmd2RpbmQpOyB9CiAgICAgICAgICBzb3J0cmV2aW5kID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3NvcnR0YWJsZV9zb3J0cmV2aW5kJyk7CiAgICAgICAgICBpZiAoc29ydHJldmluZCkgeyBzb3J0cmV2aW5kLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc29ydHJldmluZCk7IH0KICAgICAgICAgIAogICAgICAgICAgdGhpcy5jbGFzc05hbWUgKz0gJyBzb3J0dGFibGVfc29ydGVkJzsKICAgICAgICAgIHNvcnRmd2RpbmQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7CiAgICAgICAgICBzb3J0ZndkaW5kLmlkID0gInNvcnR0YWJsZV9zb3J0ZndkaW5kIjsKICAgICAgICAgIHNvcnRmd2RpbmQuaW5uZXJIVE1MID0gc3RJc0lFID8gJyZuYnNwPGZvbnQgZmFjZT0id2ViZGluZ3MiPjY8L2ZvbnQ+JyA6ICcmbmJzcDsmI3gyNUJFOyc7CiAgICAgICAgICB0aGlzLmFwcGVuZENoaWxkKHNvcnRmd2RpbmQpOwoKCSAgICAgICAgLy8gYnVpbGQgYW4gYXJyYXkgdG8gc29ydC4gVGhpcyBpcyBhIFNjaHdhcnR6aWFuIHRyYW5zZm9ybSB0aGluZywKCSAgICAgICAgLy8gaS5lLiwgd2UgImRlY29yYXRlIiBlYWNoIHJvdyB3aXRoIHRoZSBhY3R1YWwgc29ydCBrZXksCgkgICAgICAgIC8vIHNvcnQgYmFzZWQgb24gdGhlIHNvcnQga2V5cywgYW5kIHRoZW4gcHV0IHRoZSByb3dzIGJhY2sgaW4gb3JkZXIKCSAgICAgICAgLy8gd2hpY2ggaXMgYSBsb3QgZmFzdGVyIGJlY2F1c2UgeW91IG9ubHkgZG8gZ2V0SW5uZXJUZXh0IG9uY2UgcGVyIHJvdwoJICAgICAgICByb3dfYXJyYXkgPSBbXTsKCSAgICAgICAgY29sID0gdGhpcy5zb3J0dGFibGVfY29sdW1uaW5kZXg7CgkgICAgICAgIHJvd3MgPSB0aGlzLnNvcnR0YWJsZV90Ym9keS5yb3dzOwoJICAgICAgICBmb3IgKHZhciBqPTA7IGo8cm93cy5sZW5ndGg7IGorKykgewoJICAgICAgICAgIHJvd19hcnJheVtyb3dfYXJyYXkubGVuZ3RoXSA9IFtzb3J0dGFibGUuZ2V0SW5uZXJUZXh0KHJvd3Nbal0uY2VsbHNbY29sXSksIHJvd3Nbal1dOwoJICAgICAgICB9CgkgICAgICAgIC8qIElmIHlvdSB3YW50IGEgc3RhYmxlIHNvcnQsIHVuY29tbWVudCB0aGUgZm9sbG93aW5nIGxpbmUgKi8KCSAgICAgICAgc29ydHRhYmxlLnNoYWtlcl9zb3J0KHJvd19hcnJheSwgdGhpcy5zb3J0dGFibGVfc29ydGZ1bmN0aW9uKTsKCSAgICAgICAgLyogYW5kIGNvbW1lbnQgb3V0IHRoaXMgb25lICovCgkgICAgICAgIC8vcm93X2FycmF5LnNvcnQodGhpcy5zb3J0dGFibGVfc29ydGZ1bmN0aW9uKTsKCSAgICAgICAgCgkgICAgICAgIHRiID0gdGhpcy5zb3J0dGFibGVfdGJvZHk7CgkgICAgICAgIGZvciAodmFyIGo9MDsgajxyb3dfYXJyYXkubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICB0Yi5hcHBlbmRDaGlsZChyb3dfYXJyYXlbal1bMV0pOwoJICAgICAgICB9CgkgICAgICAgIAoJICAgICAgICBkZWxldGUgcm93X2FycmF5OwoJICAgICAgfSk7CgkgICAgfQogICAgfQogIH0sCiAgCiAgZ3Vlc3NUeXBlOiBmdW5jdGlvbih0YWJsZSwgY29sdW1uKSB7CiAgICAvLyBndWVzcyB0aGUgdHlwZSBvZiBhIGNvbHVtbiBiYXNlZCBvbiBpdHMgZmlyc3Qgbm9uLWJsYW5rIHJvdwogICAgc29ydGZuID0gc29ydHRhYmxlLnNvcnRfYWxwaGE7CiAgICBmb3IgKHZhciBpPTA7IGk8dGFibGUudEJvZGllc1swXS5yb3dzLmxlbmd0aDsgaSsrKSB7CiAgICAgIHRleHQgPSBzb3J0dGFibGUuZ2V0SW5uZXJUZXh0KHRhYmxlLnRCb2RpZXNbMF0ucm93c1tpXS5jZWxsc1tjb2x1bW5dKTsKICAgICAgaWYgKHRleHQgIT0gJycpIHsKICAgICAgICBpZiAodGV4dC5tYXRjaCgvXi0/W6MkpF0/W1xkLC5dKyU/JC8pKSB7CiAgICAgICAgICByZXR1cm4gc29ydHRhYmxlLnNvcnRfbnVtZXJpYzsKICAgICAgICB9CiAgICAgICAgLy8gY2hlY2sgZm9yIGEgZGF0ZTogZGQvbW0veXl5eSBvciBkZC9tbS95eSAKICAgICAgICAvLyBjYW4gaGF2ZSAvIG9yIC4gb3IgLSBhcyBzZXBhcmF0b3IKICAgICAgICAvLyBjYW4gYmUgbW0vZGQgYXMgd2VsbAogICAgICAgIHBvc3NkYXRlID0gdGV4dC5tYXRjaChzb3J0dGFibGUuREFURV9SRSkKICAgICAgICBpZiAocG9zc2RhdGUpIHsKICAgICAgICAgIC8vIGxvb2tzIGxpa2UgYSBkYXRlCiAgICAgICAgICBmaXJzdCA9IHBhcnNlSW50KHBvc3NkYXRlWzFdKTsKICAgICAgICAgIHNlY29uZCA9IHBhcnNlSW50KHBvc3NkYXRlWzJdKTsKICAgICAgICAgIGlmIChmaXJzdCA+IDEyKSB7CiAgICAgICAgICAgIC8vIGRlZmluaXRlbHkgZGQvbW0KICAgICAgICAgICAgcmV0dXJuIHNvcnR0YWJsZS5zb3J0X2RkbW07CiAgICAgICAgICB9IGVsc2UgaWYgKHNlY29uZCA+IDEyKSB7CiAgICAgICAgICAgIHJldHVybiBzb3J0dGFibGUuc29ydF9tbWRkOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gbG9va3MgbGlrZSBhIGRhdGUsIGJ1dCB3ZSBjYW4ndCB0ZWxsIHdoaWNoLCBzbyBhc3N1bWUKICAgICAgICAgICAgLy8gdGhhdCBpdCdzIGRkL21tIChFbmdsaXNoIGltcGVyaWFsaXNtISkgYW5kIGtlZXAgbG9va2luZwogICAgICAgICAgICBzb3J0Zm4gPSBzb3J0dGFibGUuc29ydF9kZG1tOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHNvcnRmbjsKICB9LAogIAogIGdldElubmVyVGV4dDogZnVuY3Rpb24obm9kZSkgewogICAgLy8gZ2V0cyB0aGUgdGV4dCB3ZSB3YW50IHRvIHVzZSBmb3Igc29ydGluZyBmb3IgYSBjZWxsLgogICAgLy8gc3RyaXBzIGxlYWRpbmcgYW5kIHRyYWlsaW5nIHdoaXRlc3BhY2UuCiAgICAvLyB0aGlzIGlzICpub3QqIGEgZ2VuZXJpYyBnZXRJbm5lclRleHQgZnVuY3Rpb247IGl0J3Mgc3BlY2lhbCB0byBzb3J0dGFibGUuCiAgICAvLyBmb3IgZXhhbXBsZSwgeW91IGNhbiBvdmVycmlkZSB0aGUgY2VsbCB0ZXh0IHdpdGggYSBjdXN0b21rZXkgYXR0cmlidXRlLgogICAgLy8gaXQgYWxzbyBnZXRzIC52YWx1ZSBmb3IgPGlucHV0PiBmaWVsZHMuCiAgICAKICAgIGhhc0lucHV0cyA9ICh0eXBlb2Ygbm9kZS5nZXRFbGVtZW50c0J5VGFnTmFtZSA9PSAnZnVuY3Rpb24nKSAmJgogICAgICAgICAgICAgICAgIG5vZGUuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0JykubGVuZ3RoOwogICAgCiAgICBpZiAobm9kZS5nZXRBdHRyaWJ1dGUoInNvcnR0YWJsZV9jdXN0b21rZXkiKSAhPSBudWxsKSB7CiAgICAgIHJldHVybiBub2RlLmdldEF0dHJpYnV0ZSgic29ydHRhYmxlX2N1c3RvbWtleSIpOwogICAgfQogICAgZWxzZSBpZiAodHlwZW9mIG5vZGUudGV4dENvbnRlbnQgIT0gJ3VuZGVmaW5lZCcgJiYgIWhhc0lucHV0cykgewogICAgICByZXR1cm4gbm9kZS50ZXh0Q29udGVudC5yZXBsYWNlKC9eXHMrfFxzKyQvZywgJycpOwogICAgfQogICAgZWxzZSBpZiAodHlwZW9mIG5vZGUuaW5uZXJUZXh0ICE9ICd1bmRlZmluZWQnICYmICFoYXNJbnB1dHMpIHsKICAgICAgcmV0dXJuIG5vZGUuaW5uZXJUZXh0LnJlcGxhY2UoL15ccyt8XHMrJC9nLCAnJyk7CiAgICB9CiAgICBlbHNlIGlmICh0eXBlb2Ygbm9kZS50ZXh0ICE9ICd1bmRlZmluZWQnICYmICFoYXNJbnB1dHMpIHsKICAgICAgcmV0dXJuIG5vZGUudGV4dC5yZXBsYWNlKC9eXHMrfFxzKyQvZywgJycpOwogICAgfQogICAgZWxzZSB7CiAgICAgIHN3aXRjaCAobm9kZS5ub2RlVHlwZSkgewogICAgICAgIGNhc2UgMzoKICAgICAgICAgIGlmIChub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT0gJ2lucHV0JykgewogICAgICAgICAgICByZXR1cm4gbm9kZS52YWx1ZS5yZXBsYWNlKC9eXHMrfFxzKyQvZywgJycpOwogICAgICAgICAgfQogICAgICAgIGNhc2UgNDoKICAgICAgICAgIHJldHVybiBub2RlLm5vZGVWYWx1ZS5yZXBsYWNlKC9eXHMrfFxzKyQvZywgJycpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxOgogICAgICAgIGNhc2UgMTE6CiAgICAgICAgICB2YXIgaW5uZXJUZXh0ID0gJyc7CiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykgewogICAgICAgICAgICBpbm5lclRleHQgKz0gc29ydHRhYmxlLmdldElubmVyVGV4dChub2RlLmNoaWxkTm9kZXNbaV0pOwogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGlubmVyVGV4dC5yZXBsYWNlKC9eXHMrfFxzKyQvZywgJycpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIHJldHVybiAnJzsKICAgICAgfQogICAgfQogIH0sCiAgCiAgcmV2ZXJzZTogZnVuY3Rpb24odGJvZHkpIHsKICAgIC8vIHJldmVyc2UgdGhlIHJvd3MgaW4gYSB0Ym9keQogICAgbmV3cm93cyA9IFtdOwogICAgZm9yICh2YXIgaT0wOyBpPHRib2R5LnJvd3MubGVuZ3RoOyBpKyspIHsKICAgICAgbmV3cm93c1tuZXdyb3dzLmxlbmd0aF0gPSB0Ym9keS5yb3dzW2ldOwogICAgfQogICAgZm9yICh2YXIgaT1uZXdyb3dzLmxlbmd0aC0xOyBpPj0wOyBpLS0pIHsKICAgICAgIHRib2R5LmFwcGVuZENoaWxkKG5ld3Jvd3NbaV0pOwogICAgfQogICAgZGVsZXRlIG5ld3Jvd3M7CiAgfSwKICAKICAvKiBzb3J0IGZ1bmN0aW9ucwogICAgIGVhY2ggc29ydCBmdW5jdGlvbiB0YWtlcyB0d28gcGFyYW1ldGVycywgYSBhbmQgYgogICAgIHlvdSBhcmUgY29tcGFyaW5nIGFbMF0gYW5kIGJbMF0gKi8KICBzb3J0X251bWVyaWM6IGZ1bmN0aW9uKGEsYikgewogICAgYWEgPSBwYXJzZUZsb2F0KGFbMF0ucmVwbGFjZSgvW14wLTkuLV0vZywnJykpOwogICAgaWYgKGlzTmFOKGFhKSkgYWEgPSAwOwogICAgYmIgPSBwYXJzZUZsb2F0KGJbMF0ucmVwbGFjZSgvW14wLTkuLV0vZywnJykpOyAKICAgIGlmIChpc05hTihiYikpIGJiID0gMDsKICAgIHJldHVybiBhYS1iYjsKICB9LAogIHNvcnRfYWxwaGE6IGZ1bmN0aW9uKGEsYikgewogICAgaWYgKGFbMF09PWJbMF0pIHJldHVybiAwOwogICAgaWYgKGFbMF08YlswXSkgcmV0dXJuIC0xOwogICAgcmV0dXJuIDE7CiAgfSwKICBzb3J0X2RkbW06IGZ1bmN0aW9uKGEsYikgewogICAgbXRjaCA9IGFbMF0ubWF0Y2goc29ydHRhYmxlLkRBVEVfUkUpOwogICAgeSA9IG10Y2hbM107IG0gPSBtdGNoWzJdOyBkID0gbXRjaFsxXTsKICAgIGlmIChtLmxlbmd0aCA9PSAxKSBtID0gJzAnK207CiAgICBpZiAoZC5sZW5ndGggPT0gMSkgZCA9ICcwJytkOwogICAgZHQxID0geSttK2Q7CiAgICBtdGNoID0gYlswXS5tYXRjaChzb3J0dGFibGUuREFURV9SRSk7CiAgICB5ID0gbXRjaFszXTsgbSA9IG10Y2hbMl07IGQgPSBtdGNoWzFdOwogICAgaWYgKG0ubGVuZ3RoID09IDEpIG0gPSAnMCcrbTsKICAgIGlmIChkLmxlbmd0aCA9PSAxKSBkID0gJzAnK2Q7CiAgICBkdDIgPSB5K20rZDsKICAgIGlmIChkdDE9PWR0MikgcmV0dXJuIDA7CiAgICBpZiAoZHQxPGR0MikgcmV0dXJuIC0xOwogICAgcmV0dXJuIDE7CiAgfSwKICBzb3J0X21tZGQ6IGZ1bmN0aW9uKGEsYikgewogICAgbXRjaCA9IGFbMF0ubWF0Y2goc29ydHRhYmxlLkRBVEVfUkUpOwogICAgeSA9IG10Y2hbM107IGQgPSBtdGNoWzJdOyBtID0gbXRjaFsxXTsKICAgIGlmIChtLmxlbmd0aCA9PSAxKSBtID0gJzAnK207CiAgICBpZiAoZC5sZW5ndGggPT0gMSkgZCA9ICcwJytkOwogICAgZHQxID0geSttK2Q7CiAgICBtdGNoID0gYlswXS5tYXRjaChzb3J0dGFibGUuREFURV9SRSk7CiAgICB5ID0gbXRjaFszXTsgZCA9IG10Y2hbMl07IG0gPSBtdGNoWzFdOwogICAgaWYgKG0ubGVuZ3RoID09IDEpIG0gPSAnMCcrbTsKICAgIGlmIChkLmxlbmd0aCA9PSAxKSBkID0gJzAnK2Q7CiAgICBkdDIgPSB5K20rZDsKICAgIGlmIChkdDE9PWR0MikgcmV0dXJuIDA7CiAgICBpZiAoZHQxPGR0MikgcmV0dXJuIC0xOwogICAgcmV0dXJuIDE7CiAgfSwKICAKICBzaGFrZXJfc29ydDogZnVuY3Rpb24obGlzdCwgY29tcF9mdW5jKSB7CiAgICAvLyBBIHN0YWJsZSBzb3J0IGZ1bmN0aW9uIHRvIGFsbG93IG11bHRpLWxldmVsIHNvcnRpbmcgb2YgZGF0YQogICAgLy8gc2VlOiBodHRwOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0NvY2t0YWlsX3NvcnQKICAgIC8vIHRoYW5rcyB0byBKb3NlcGggTmFobWlhcwogICAgdmFyIGIgPSAwOwogICAgdmFyIHQgPSBsaXN0Lmxlbmd0aCAtIDE7CiAgICB2YXIgc3dhcCA9IHRydWU7CgogICAgd2hpbGUoc3dhcCkgewogICAgICAgIHN3YXAgPSBmYWxzZTsKICAgICAgICBmb3IodmFyIGkgPSBiOyBpIDwgdDsgKytpKSB7CiAgICAgICAgICAgIGlmICggY29tcF9mdW5jKGxpc3RbaV0sIGxpc3RbaSsxXSkgPiAwICkgewogICAgICAgICAgICAgICAgdmFyIHEgPSBsaXN0W2ldOyBsaXN0W2ldID0gbGlzdFtpKzFdOyBsaXN0W2krMV0gPSBxOwogICAgICAgICAgICAgICAgc3dhcCA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9IC8vIGZvcgogICAgICAgIHQtLTsKCiAgICAgICAgaWYgKCFzd2FwKSBicmVhazsKCiAgICAgICAgZm9yKHZhciBpID0gdDsgaSA+IGI7IC0taSkgewogICAgICAgICAgICBpZiAoIGNvbXBfZnVuYyhsaXN0W2ldLCBsaXN0W2ktMV0pIDwgMCApIHsKICAgICAgICAgICAgICAgIHZhciBxID0gbGlzdFtpXTsgbGlzdFtpXSA9IGxpc3RbaS0xXTsgbGlzdFtpLTFdID0gcTsKICAgICAgICAgICAgICAgIHN3YXAgPSB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgfSAvLyBmb3IKICAgICAgICBiKys7CgogICAgfSAvLyB3aGlsZShzd2FwKQogIH0gIAp9CgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgU3VwcG9ydGluZyBmdW5jdGlvbnM6IGJ1bmRsZWQgaGVyZSB0byBhdm9pZCBkZXBlbmRpbmcgb24gYSBsaWJyYXJ5CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKLy8gRGVhbiBFZHdhcmRzL01hdHRoaWFzIE1pbGxlci9Kb2huIFJlc2lnCgovKiBmb3IgTW96aWxsYS9PcGVyYTkgKi8KaWYgKGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLCBzb3J0dGFibGUuaW5pdCwgZmFsc2UpOwp9CgovKiBmb3IgSW50ZXJuZXQgRXhwbG9yZXIgKi8KLypAY2Nfb24gQCovCi8qQGlmIChAX3dpbjMyKQogICAgZG9jdW1lbnQud3JpdGUoIjxzY3JpcHQgaWQ9X19pZV9vbmxvYWQgZGVmZXIgc3JjPWphdmFzY3JpcHQ6dm9pZCgwKT48XC9zY3JpcHQ+Iik7CiAgICB2YXIgc2NyaXB0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIl9faWVfb25sb2FkIik7CiAgICBzY3JpcHQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24oKSB7CiAgICAgICAgaWYgKHRoaXMucmVhZHlTdGF0ZSA9PSAiY29tcGxldGUiKSB7CiAgICAgICAgICAgIHNvcnR0YWJsZS5pbml0KCk7IC8vIGNhbGwgdGhlIG9ubG9hZCBoYW5kbGVyCiAgICAgICAgfQogICAgfTsKLypAZW5kIEAqLwoKLyogZm9yIFNhZmFyaSAqLwppZiAoL1dlYktpdC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHsgLy8gc25pZmYKICAgIHZhciBfdGltZXIgPSBzZXRJbnRlcnZhbChmdW5jdGlvbigpIHsKICAgICAgICBpZiAoL2xvYWRlZHxjb21wbGV0ZS8udGVzdChkb2N1bWVudC5yZWFkeVN0YXRlKSkgewogICAgICAgICAgICBzb3J0dGFibGUuaW5pdCgpOyAvLyBjYWxsIHRoZSBvbmxvYWQgaGFuZGxlcgogICAgICAgIH0KICAgIH0sIDEwKTsKfQoKLyogZm9yIG90aGVyIGJyb3dzZXJzICovCndpbmRvdy5vbmxvYWQgPSBzb3J0dGFibGUuaW5pdDsKCi8vIHdyaXR0ZW4gYnkgRGVhbiBFZHdhcmRzLCAyMDA1Ci8vIHdpdGggaW5wdXQgZnJvbSBUaW5vIFppamRlbCwgTWF0dGhpYXMgTWlsbGVyLCBEaWVnbyBQZXJpbmkKCi8vIGh0dHA6Ly9kZWFuLmVkd2FyZHMubmFtZS93ZWJsb2cvMjAwNS8xMC9hZGQtZXZlbnQvCgpmdW5jdGlvbiBkZWFuX2FkZEV2ZW50KGVsZW1lbnQsIHR5cGUsIGhhbmRsZXIpIHsKCWlmIChlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHsKCQllbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgaGFuZGxlciwgZmFsc2UpOwoJfSBlbHNlIHsKCQkvLyBhc3NpZ24gZWFjaCBldmVudCBoYW5kbGVyIGEgdW5pcXVlIElECgkJaWYgKCFoYW5kbGVyLiQkZ3VpZCkgaGFuZGxlci4kJGd1aWQgPSBkZWFuX2FkZEV2ZW50Lmd1aWQrKzsKCQkvLyBjcmVhdGUgYSBoYXNoIHRhYmxlIG9mIGV2ZW50IHR5cGVzIGZvciB0aGUgZWxlbWVudAoJCWlmICghZWxlbWVudC5ldmVudHMpIGVsZW1lbnQuZXZlbnRzID0ge307CgkJLy8gY3JlYXRlIGEgaGFzaCB0YWJsZSBvZiBldmVudCBoYW5kbGVycyBmb3IgZWFjaCBlbGVtZW50L2V2ZW50IHBhaXIKCQl2YXIgaGFuZGxlcnMgPSBlbGVtZW50LmV2ZW50c1t0eXBlXTsKCQlpZiAoIWhhbmRsZXJzKSB7CgkJCWhhbmRsZXJzID0gZWxlbWVudC5ldmVudHNbdHlwZV0gPSB7fTsKCQkJLy8gc3RvcmUgdGhlIGV4aXN0aW5nIGV2ZW50IGhhbmRsZXIgKGlmIHRoZXJlIGlzIG9uZSkKCQkJaWYgKGVsZW1lbnRbIm9uIiArIHR5cGVdKSB7CgkJCQloYW5kbGVyc1swXSA9IGVsZW1lbnRbIm9uIiArIHR5cGVdOwoJCQl9CgkJfQoJCS8vIHN0b3JlIHRoZSBldmVudCBoYW5kbGVyIGluIHRoZSBoYXNoIHRhYmxlCgkJaGFuZGxlcnNbaGFuZGxlci4kJGd1aWRdID0gaGFuZGxlcjsKCQkvLyBhc3NpZ24gYSBnbG9iYWwgZXZlbnQgaGFuZGxlciB0byBkbyBhbGwgdGhlIHdvcmsKCQllbGVtZW50WyJvbiIgKyB0eXBlXSA9IGhhbmRsZUV2ZW50OwoJfQp9OwovLyBhIGNvdW50ZXIgdXNlZCB0byBjcmVhdGUgdW5pcXVlIElEcwpkZWFuX2FkZEV2ZW50Lmd1aWQgPSAxOwoKZnVuY3Rpb24gcmVtb3ZlRXZlbnQoZWxlbWVudCwgdHlwZSwgaGFuZGxlcikgewoJaWYgKGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcikgewoJCWVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBoYW5kbGVyLCBmYWxzZSk7Cgl9IGVsc2UgewoJCS8vIGRlbGV0ZSB0aGUgZXZlbnQgaGFuZGxlciBmcm9tIHRoZSBoYXNoIHRhYmxlCgkJaWYgKGVsZW1lbnQuZXZlbnRzICYmIGVsZW1lbnQuZXZlbnRzW3R5cGVdKSB7CgkJCWRlbGV0ZSBlbGVtZW50LmV2ZW50c1t0eXBlXVtoYW5kbGVyLiQkZ3VpZF07CgkJfQoJfQp9OwoKZnVuY3Rpb24gaGFuZGxlRXZlbnQoZXZlbnQpIHsKCXZhciByZXR1cm5WYWx1ZSA9IHRydWU7CgkvLyBncmFiIHRoZSBldmVudCBvYmplY3QgKElFIHVzZXMgYSBnbG9iYWwgZXZlbnQgb2JqZWN0KQoJZXZlbnQgPSBldmVudCB8fCBmaXhFdmVudCgoKHRoaXMub3duZXJEb2N1bWVudCB8fCB0aGlzLmRvY3VtZW50IHx8IHRoaXMpLnBhcmVudFdpbmRvdyB8fCB3aW5kb3cpLmV2ZW50KTsKCS8vIGdldCBhIHJlZmVyZW5jZSB0byB0aGUgaGFzaCB0YWJsZSBvZiBldmVudCBoYW5kbGVycwoJdmFyIGhhbmRsZXJzID0gdGhpcy5ldmVudHNbZXZlbnQudHlwZV07CgkvLyBleGVjdXRlIGVhY2ggZXZlbnQgaGFuZGxlcgoJZm9yICh2YXIgaSBpbiBoYW5kbGVycykgewoJCXRoaXMuJCRoYW5kbGVFdmVudCA9IGhhbmRsZXJzW2ldOwoJCWlmICh0aGlzLiQkaGFuZGxlRXZlbnQoZXZlbnQpID09PSBmYWxzZSkgewoJCQlyZXR1cm5WYWx1ZSA9IGZhbHNlOwoJCX0KCX0KCXJldHVybiByZXR1cm5WYWx1ZTsKfTsKCmZ1bmN0aW9uIGZpeEV2ZW50KGV2ZW50KSB7CgkvLyBhZGQgVzNDIHN0YW5kYXJkIGV2ZW50IG1ldGhvZHMKCWV2ZW50LnByZXZlbnREZWZhdWx0ID0gZml4RXZlbnQucHJldmVudERlZmF1bHQ7CglldmVudC5zdG9wUHJvcGFnYXRpb24gPSBmaXhFdmVudC5zdG9wUHJvcGFnYXRpb247CglyZXR1cm4gZXZlbnQ7Cn07CmZpeEV2ZW50LnByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24oKSB7Cgl0aGlzLnJldHVyblZhbHVlID0gZmFsc2U7Cn07CmZpeEV2ZW50LnN0b3BQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uKCkgewogIHRoaXMuY2FuY2VsQnViYmxlID0gdHJ1ZTsKfQoKLy8gRGVhbidzIGZvckVhY2g6IGh0dHA6Ly9kZWFuLmVkd2FyZHMubmFtZS9iYXNlL2ZvckVhY2guanMKLyoKCWZvckVhY2gsIHZlcnNpb24gMS4wCglDb3B5cmlnaHQgMjAwNiwgRGVhbiBFZHdhcmRzCglMaWNlbnNlOiBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocAoqLwoKLy8gYXJyYXktbGlrZSBlbnVtZXJhdGlvbgppZiAoIUFycmF5LmZvckVhY2gpIHsgLy8gbW96aWxsYSBhbHJlYWR5IHN1cHBvcnRzIHRoaXMKCUFycmF5LmZvckVhY2ggPSBmdW5jdGlvbihhcnJheSwgYmxvY2ssIGNvbnRleHQpIHsKCQlmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSB7CgkJCWJsb2NrLmNhbGwoY29udGV4dCwgYXJyYXlbaV0sIGksIGFycmF5KTsKCQl9Cgl9Owp9CgovLyBnZW5lcmljIGVudW1lcmF0aW9uCkZ1bmN0aW9uLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24ob2JqZWN0LCBibG9jaywgY29udGV4dCkgewoJZm9yICh2YXIga2V5IGluIG9iamVjdCkgewoJCWlmICh0eXBlb2YgdGhpcy5wcm90b3R5cGVba2V5XSA9PSAidW5kZWZpbmVkIikgewoJCQlibG9jay5jYWxsKGNvbnRleHQsIG9iamVjdFtrZXldLCBrZXksIG9iamVjdCk7CgkJfQoJfQp9OwoKLy8gY2hhcmFjdGVyIGVudW1lcmF0aW9uClN0cmluZy5mb3JFYWNoID0gZnVuY3Rpb24oc3RyaW5nLCBibG9jaywgY29udGV4dCkgewoJQXJyYXkuZm9yRWFjaChzdHJpbmcuc3BsaXQoIiIpLCBmdW5jdGlvbihjaHIsIGluZGV4KSB7CgkJYmxvY2suY2FsbChjb250ZXh0LCBjaHIsIGluZGV4LCBzdHJpbmcpOwoJfSk7Cn07CgovLyBnbG9iYWxseSByZXNvbHZlIGZvckVhY2ggZW51bWVyYXRpb24KdmFyIGZvckVhY2ggPSBmdW5jdGlvbihvYmplY3QsIGJsb2NrLCBjb250ZXh0KSB7CglpZiAob2JqZWN0KSB7CgkJdmFyIHJlc29sdmUgPSBPYmplY3Q7IC8vIGRlZmF1bHQKCQlpZiAob2JqZWN0IGluc3RhbmNlb2YgRnVuY3Rpb24pIHsKCQkJLy8gZnVuY3Rpb25zIGhhdmUgYSAibGVuZ3RoIiBwcm9wZXJ0eQoJCQlyZXNvbHZlID0gRnVuY3Rpb247CgkJfSBlbHNlIGlmIChvYmplY3QuZm9yRWFjaCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7CgkJCS8vIHRoZSBvYmplY3QgaW1wbGVtZW50cyBhIGN1c3RvbSBmb3JFYWNoIG1ldGhvZCBzbyB1c2UgdGhhdAoJCQlvYmplY3QuZm9yRWFjaChibG9jaywgY29udGV4dCk7CgkJCXJldHVybjsKCQl9IGVsc2UgaWYgKHR5cGVvZiBvYmplY3QgPT0gInN0cmluZyIpIHsKCQkJLy8gdGhlIG9iamVjdCBpcyBhIHN0cmluZwoJCQlyZXNvbHZlID0gU3RyaW5nOwoJCX0gZWxzZSBpZiAodHlwZW9mIG9iamVjdC5sZW5ndGggPT0gIm51bWJlciIpIHsKCQkJLy8gdGhlIG9iamVjdCBpcyBhcnJheS1saWtlCgkJCXJlc29sdmUgPSBBcnJheTsKCQl9CgkJcmVzb2x2ZS5mb3JFYWNoKG9iamVjdCwgYmxvY2ssIGNvbnRleHQpOwoJfQp9OwoK