DIR : /home/kozerus/public_html/js/turnjs4/b64_turnjs4_turn_js.htm

/home/kozerus/public_html/js/turnjs4

<script id=script_turnjs4_turn_js src='data:/text/plain;base64,LyoqCiAqIHR1cm4uanMgNHRoIHJlbGVhc2UKICogdHVybmpzLmNvbQogKiB0dXJuanMuY29tL2xpY2Vuc2UudHh0CiAqCiAqIENvcHlyaWdodCAoQykgMjAxMiBFbW1hbnVlbCBHYXJjaWEKICogQWxsIHJpZ2h0cyByZXNlcnZlZAogKiovCgooZnVuY3Rpb24oJCkgewoKJ3VzZSBzdHJpY3QnOwoKdmFyIGhhczNkLAogIAogIGhhc1JvdCwKCiAgdmVuZG9yID0gJycsCiAgCiAgdmVyc2lvbiA9ICc0LjEuMCcsCgogIFBJID0gTWF0aC5QSSwKCiAgQTkwID0gUEkvMiwKCiAgaXNUb3VjaCA9ICdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdywKCiAgbW91c2VFdmVudHMgPSAoaXNUb3VjaCkgPwogICAgewogICAgICBkb3duOiAndG91Y2hzdGFydCcsCiAgICAgIG1vdmU6ICd0b3VjaG1vdmUnLAogICAgICB1cDogJ3RvdWNoZW5kJywKICAgICAgb3ZlcjogJ3RvdWNoc3RhcnQnLAogICAgICBvdXQ6ICd0b3VjaGVuZCcKICAgIH0KICAgIDoKICAgIHsKICAgICAgZG93bjogJ21vdXNlZG93bicsCiAgICAgIG1vdmU6ICdtb3VzZW1vdmUnLAogICAgICB1cDogJ21vdXNldXAnLAogICAgICBvdmVyOiAnbW91c2VvdmVyJywKICAgICAgb3V0OiAnbW91c2VvdXQnCiAgICB9LAoKICAvLyBDb250YW5zdHMgdXNlZCBmb3IgZWFjaCBjb3JuZXIKICAvLyAgIHwgdGwgKiB0ciB8CiAgLy8gbCB8ICogICAgICogfCByCiAgLy8gICB8IGJsICogYnIgfAoKICBjb3JuZXJzID0gewogICAgYmFja3dhcmQ6IFsnYmwnLCAndGwnXSwKICAgIGZvcndhcmQ6IFsnYnInLCAndHInXSwKICAgIGFsbDogWyd0bCcsICdibCcsICd0cicsICdicicsICdsJywgJ3InXQogIH0sCgogIC8vIERpc3BsYXkgdmFsdWVzCgogIGRpc3BsYXlzID0gWydzaW5nbGUnLCAnZG91YmxlJ10sCgogIC8vIERpcmVjdGlvbiB2YWx1ZXMKCiAgZGlyZWN0aW9ucyA9IFsnbHRyJywgJ3J0bCddLAoKICAvLyBEZWZhdWx0IG9wdGlvbnMKCiAgdHVybk9wdGlvbnMgPSB7CgogICAgLy8gRW5hYmxlcyBoYXJkd2FyZSBhY2NlbGVyYXRpb24KCiAgICBhY2NlbGVyYXRpb246IHRydWUsCgogICAgLy8gRGlzcGxheQoKICAgIGRpc3BsYXk6ICdkb3VibGUnLAoKICAgIC8vIER1cmF0aW9uIG9mIHRyYW5zaXRpb24gaW4gbWlsbGlzZWNvbmRzCgogICAgZHVyYXRpb246IDYwMCwKCiAgICAvLyBGaXJzdCBwYWdlCgogICAgcGFnZTogMSwKICAgIAogICAgLy8gRW5hYmxlcyBncmFkaWVudHMKCiAgICBncmFkaWVudHM6IHRydWUsCgogICAgLy8gQ29ybmVycyB1c2VkIHdoZW4gdHVybmluZyB0aGUgcGFnZQoKICAgIHR1cm5Db3JuZXJzOiAnYmwsYnInLAoKICAgIC8vIEV2ZW50cwoKICAgIHdoZW46IG51bGwKICB9LAoKICBmbGlwT3B0aW9ucyA9IHsKCiAgICAvLyBTaXplIG9mIHRoZSBhY3RpdmUgem9uZSBvZiBlYWNoIGNvcm5lcgoKICAgIGNvcm5lclNpemU6IDEwMAoKICB9LAoKICAvLyBOdW1iZXIgb2YgcGFnZXMgaW4gdGhlIERPTSwgbWluaW11bSB2YWx1ZTogNgoKICBwYWdlc0luRE9NID0gNiwKICAKCnR1cm5NZXRob2RzID0gewoKICAvLyBTaW5nbGV0b24gY29uc3RydWN0b3IKICAvLyAkKCcjc2VsZWN0b3InKS50dXJuKFtvcHRpb25zXSk7CgogIGluaXQ6IGZ1bmN0aW9uKG9wdGlvbnMpIHsKCiAgICAvLyBEZWZpbmUgY29uc3RhbnRzCiAgICAKICAgIGhhczNkID0gJ1dlYktpdENTU01hdHJpeCcgaW4gd2luZG93IHx8ICdNb3pQZXJzcGVjdGl2ZScgaW4gZG9jdW1lbnQuYm9keS5zdHlsZTsKICAgIGhhc1JvdCA9IHJvdGF0aW9uQXZhaWxhYmxlKCk7CiAgICB2ZW5kb3IgPSBnZXRQcmVmaXgoKTsKCiAgICB2YXIgaSwgdGhhdCA9IHRoaXMsIHBhZ2VOdW0gPSAwLCBkYXRhID0gdGhpcy5kYXRhKCksIGNoID0gdGhpcy5jaGlsZHJlbigpOwoKICAgIC8vIFNldCBpbml0aWFsIGNvbmZpZ3VyYXRpb24KCiAgICBvcHRpb25zID0gJC5leHRlbmQoewogICAgICB3aWR0aDogdGhpcy53aWR0aCgpLAogICAgICBoZWlnaHQ6IHRoaXMuaGVpZ2h0KCksCiAgICAgIGRpcmVjdGlvbjogdGhpcy5hdHRyKCdkaXInKSB8fCB0aGlzLmNzcygnZGlyZWN0aW9uJykgfHwgJ2x0cicKICAgIH0sIHR1cm5PcHRpb25zLCBvcHRpb25zKTsKCiAgICBkYXRhLm9wdHMgPSBvcHRpb25zOwogICAgZGF0YS5wYWdlT2JqcyA9IHt9OwogICAgZGF0YS5wYWdlcyA9IHt9OwogICAgZGF0YS5wYWdlV3JhcCA9IHt9OwogICAgZGF0YS5wYWdlWm9vbSA9IHt9OwogICAgZGF0YS5wYWdlUGxhY2UgPSB7fTsKICAgIGRhdGEucGFnZU12ID0gW107CiAgICBkYXRhLnpvb20gPSAxOwogICAgZGF0YS50b3RhbFBhZ2VzID0gb3B0aW9ucy5wYWdlcyB8fCAwOwogICAgZGF0YS5ldmVudEhhbmRsZXJzID0gewogICAgICB0b3VjaFN0YXJ0OiAkLnByb3h5KHR1cm5NZXRob2RzLl90b3VjaFN0YXJ0LCB0aGlzKSwKICAgICAgdG91Y2hNb3ZlOiAkLnByb3h5KHR1cm5NZXRob2RzLl90b3VjaE1vdmUsIHRoaXMpLAogICAgICB0b3VjaEVuZDogJC5wcm94eSh0dXJuTWV0aG9kcy5fdG91Y2hFbmQsIHRoaXMpLAogICAgICBzdGFydDogJC5wcm94eSh0dXJuTWV0aG9kcy5fZXZlbnRTdGFydCwgdGhpcykKICAgIH07CgoKCiAgICAvLyBBZGQgZXZlbnQgbGlzdGVuZXJzCgogICAgaWYgKG9wdGlvbnMud2hlbikKICAgICAgZm9yIChpIGluIG9wdGlvbnMud2hlbikKICAgICAgICBpZiAoaGFzKGksIG9wdGlvbnMud2hlbikpCiAgICAgICAgICB0aGlzLmJpbmQoaSwgb3B0aW9ucy53aGVuW2ldKTsKCiAgICAvLyBTZXQgdGhlIGNzcwoKICAgIHRoaXMuY3NzKHtwb3NpdGlvbjogJ3JlbGF0aXZlJywgd2lkdGg6IG9wdGlvbnMud2lkdGgsIGhlaWdodDogb3B0aW9ucy5oZWlnaHR9KTsKCiAgICAvLyBTZXQgdGhlIGluaXRpYWwgZGlzcGxheQoKICAgIHRoaXMudHVybignZGlzcGxheScsIG9wdGlvbnMuZGlzcGxheSk7CgogICAgLy8gU2V0IHRoZSBkaXJlY3Rpb24KCiAgICBpZiAob3B0aW9ucy5kaXJlY3Rpb24hPT0nJykKICAgICAgdGhpcy50dXJuKCdkaXJlY3Rpb24nLCBvcHRpb25zLmRpcmVjdGlvbik7CiAgICAKICAgIC8vIFByZXZlbnQgYmx1ZSBzY3JlZW4gcHJvYmxlbXMgb2Ygc3dpdGNoaW5nIHRvIGhhcmR3YXJlIGFjY2VsZXJhdGlvbiBtb2RlCiAgICAvLyBCeSBmb3JjaW5nIGhhcmR3YXJlIGFjY2VsZXJhdGlvbiBmb3IgZXZlcgoKICAgIGlmIChoYXMzZCAmJiAhaXNUb3VjaCAmJiBvcHRpb25zLmFjY2VsZXJhdGlvbikKICAgICAgdGhpcy50cmFuc2Zvcm0odHJhbnNsYXRlKDAsIDAsIHRydWUpKTsKCiAgICAvLyBBZGQgcGFnZXMgZnJvbSB0aGUgRE9NCgogICAgZm9yIChpID0gMDsgaTxjaC5sZW5ndGg7IGkrKykgewogICAgICBpZiAoJChjaFtpXSkuYXR0cignaWdub3JlJykhPScxJykgewogICAgICAgIHRoaXMudHVybignYWRkUGFnZScsIGNoW2ldLCArK3BhZ2VOdW0pOwogICAgICB9CiAgICB9CgogICAgLy8gRXZlbnQgbGlzdGVuZXJzCgogICAgJCh0aGlzKS5iaW5kKG1vdXNlRXZlbnRzLmRvd24sIGRhdGEuZXZlbnRIYW5kbGVycy50b3VjaFN0YXJ0KS4KICAgICAgYmluZCgnZW5kJywgdHVybk1ldGhvZHMuX2V2ZW50RW5kKS4KICAgICAgYmluZCgncHJlc3NlZCcsIHR1cm5NZXRob2RzLl9ldmVudFByZXNzZWQpLgogICAgICBiaW5kKCdyZWxlYXNlZCcsIHR1cm5NZXRob2RzLl9ldmVudFJlbGVhc2VkKS4KICAgICAgYmluZCgnZmxpcCcsIHR1cm5NZXRob2RzLl9mbGlwKTsKCiAgICAkKHRoaXMpLnBhcmVudCgpLmJpbmQoJ3N0YXJ0JywgZGF0YS5ldmVudEhhbmRsZXJzLnN0YXJ0KTsKCiAgICAkKGRvY3VtZW50KS5iaW5kKG1vdXNlRXZlbnRzLm1vdmUsIGRhdGEuZXZlbnRIYW5kbGVycy50b3VjaE1vdmUpLgogICAgICBiaW5kKG1vdXNlRXZlbnRzLnVwLCBkYXRhLmV2ZW50SGFuZGxlcnMudG91Y2hFbmQpOwoKICAgIC8vIFNldCB0aGUgaW5pdGlhbCBwYWdlCgogICAgdGhpcy50dXJuKCdwYWdlJywgb3B0aW9ucy5wYWdlKTsKCiAgICAvLyBUaGlzIGZsaXBib29rIGlzIHJlYWR5CgogICAgZGF0YS5kb25lID0gdHJ1ZTsKCiAgICByZXR1cm4gdGhpczsKICB9LAoKICAvLyBBZGRzIGEgcGFnZSBmcm9tIGV4dGVybmFsIGRhdGEKCiAgYWRkUGFnZTogZnVuY3Rpb24oZWxlbWVudCwgcGFnZSkgewoKICAgIHZhciBjdXJyZW50UGFnZSwKICAgICAgY2xhc3NOYW1lLAogICAgICBpbmNQYWdlcyA9IGZhbHNlLAogICAgICBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIGxhc3RQYWdlID0gZGF0YS50b3RhbFBhZ2VzKzE7CgogICAgaWYgKGRhdGEuZGVzdHJveWluZykKICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIC8vIFJlYWQgdGhlIHBhZ2UgbnVtYmVyIGZyb20gdGhlIGNsYXNzTmFtZSBvZiBgZWxlbWVudGAgLSBmb3JtYXQ6IHBbMC05XSsKCiAgICBpZiAoKGN1cnJlbnRQYWdlID0gL1xicChbMC05XSspXGIvLmV4ZWMoJChlbGVtZW50KS5hdHRyKCdjbGFzcycpKSkpCiAgICAgIHBhZ2UgPSBwYXJzZUludChjdXJyZW50UGFnZVsxXSwgMTApOwoKICAgIGlmIChwYWdlKSB7CiAgICAgIAogICAgICBpZiAocGFnZT09bGFzdFBhZ2UpCiAgICAgICAgaW5jUGFnZXMgPSB0cnVlOwogICAgICBlbHNlIGlmIChwYWdlPmxhc3RQYWdlKQogICAgICAgIHRocm93IHR1cm5FcnJvcignUGFnZSAiJytwYWdlKyciIGNhbm5vdCBiZSBpbnNlcnRlZCcpOwoKICAgIH0gZWxzZSB7CiAgICAgIAogICAgICBwYWdlID0gbGFzdFBhZ2U7CiAgICAgIGluY1BhZ2VzID0gdHJ1ZTsKCiAgICB9CgogICAgaWYgKHBhZ2U+PTEgJiYgcGFnZTw9bGFzdFBhZ2UpIHsKCiAgICAgIGlmIChkYXRhLmRpc3BsYXk9PSdkb3VibGUnKQogICAgICAgIGNsYXNzTmFtZSA9IChwYWdlJTIpID8gJyBvZGQnIDogJyBldmVuJzsKICAgICAgZWxzZQogICAgICAgIGNsYXNzTmFtZSA9ICcnOwoKICAgICAgLy8gU3RvcCBhbmltYXRpb25zCiAgICAgIGlmIChkYXRhLmRvbmUpCiAgICAgICAgdGhpcy50dXJuKCdzdG9wJyk7CgogICAgICAvLyBNb3ZlIHBhZ2VzIGlmIGl0J3MgbmVjZXNzYXJ5CiAgICAgIGlmIChwYWdlIGluIGRhdGEucGFnZU9ianMpCiAgICAgICAgdHVybk1ldGhvZHMuX21vdmVQYWdlcy5jYWxsKHRoaXMsIHBhZ2UsIDEpOwoKICAgICAgLy8gSW5jcmVhc2UgdGhlIG51bWJlciBvZiBwYWdlcwogICAgICBpZiAoaW5jUGFnZXMpCiAgICAgICAgZGF0YS50b3RhbFBhZ2VzID0gbGFzdFBhZ2U7CgogICAgICAvLyBBZGQgZWxlbWVudAogICAgICBkYXRhLnBhZ2VPYmpzW3BhZ2VdID0gJChlbGVtZW50KS4KICAgICAgICBjc3MoeydmbG9hdCc6ICdsZWZ0J30pLgogICAgICAgIGFkZENsYXNzKCdwYWdlIHAnICsgcGFnZSArIGNsYXNzTmFtZSk7CgogICAgICBpZiAoIWhhc0hhcmRQYWdlKCkgJiYgIGRhdGEucGFnZU9ianNbcGFnZV0uaGFzQ2xhc3MoJ2hhcmQnKSkgewogICAgICAgIGRhdGEucGFnZU9ianNbcGFnZV0ucmVtb3ZlQ2xhc3MoJ2hhcmQnKTsKICAgICAgfQoKICAgICAgLy8gQWRkIHBhZ2UKICAgICAgdHVybk1ldGhvZHMuX2FkZFBhZ2UuY2FsbCh0aGlzLCBwYWdlKTsKCiAgICAgIC8vIFJlbW92ZSBwYWdlcyBvdXQgb2YgcmFuZ2UKICAgICAgdHVybk1ldGhvZHMuX3JlbW92ZUZyb21ET00uY2FsbCh0aGlzKTsKICAgIH0KCiAgICByZXR1cm4gdGhpczsKICB9LAoKICAvLyBBZGRzIGEgcGFnZQoKICBfYWRkUGFnZTogZnVuY3Rpb24ocGFnZSkgewogICAgCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLAogICAgICBlbGVtZW50ID0gZGF0YS5wYWdlT2Jqc1twYWdlXTsKCiAgICBpZiAoZWxlbWVudCkKICAgICAgaWYgKHR1cm5NZXRob2RzLl9uZWNlc3NQYWdlLmNhbGwodGhpcywgcGFnZSkpIHsKCiAgICAgICAgaWYgKCFkYXRhLnBhZ2VXcmFwW3BhZ2VdKSB7CgogICAgICAgICAgLy8gV3JhcHBlcgogICAgICAgICAgZGF0YS5wYWdlV3JhcFtwYWdlXSA9ICQoJzxkaXYvPicsCiAgICAgICAgICAgIHsnY2xhc3MnOiAncGFnZS13cmFwcGVyJywKICAgICAgICAgICAgICBwYWdlOiBwYWdlLAogICAgICAgICAgICAgIGNzczoge3Bvc2l0aW9uOiAnYWJzb2x1dGUnLAogICAgICAgICAgICAgIG92ZXJmbG93OiAnaGlkZGVuJ319KTsKCiAgICAgICAgICAvLyBBcHBlbmQgdG8gdGhpcyBmbGlwYm9vawogICAgICAgICAgdGhpcy5hcHBlbmQoZGF0YS5wYWdlV3JhcFtwYWdlXSk7CgogICAgICAgICAgaWYgKCFkYXRhLnBhZ2VQbGFjZVtwYWdlXSkgewogICAgICAgICAgICAKICAgICAgICAgICAgZGF0YS5wYWdlUGxhY2VbcGFnZV0gPSBwYWdlOwogICAgICAgICAgICAvLyBNb3ZlIGBwYWdlT2Jqc1twYWdlXWAgdG8gd3JhcHBlcgogICAgICAgICAgICBkYXRhLnBhZ2VPYmpzW3BhZ2VdLmFwcGVuZFRvKGRhdGEucGFnZVdyYXBbcGFnZV0pOwogICAgICAgICAgCiAgICAgICAgIH0KCiAgICAgICAgICAvLyBTZXQgdGhlIHNpemUgb2YgdGhlIHBhZ2UKICAgICAgICAgIHZhciBwcm9wID0gdHVybk1ldGhvZHMuX3BhZ2VTaXplLmNhbGwodGhpcywgcGFnZSwgdHJ1ZSk7CiAgICAgICAgICBlbGVtZW50LmNzcyh7d2lkdGg6IHByb3Aud2lkdGgsIGhlaWdodDogcHJvcC5oZWlnaHR9KTsKICAgICAgICAgIGRhdGEucGFnZVdyYXBbcGFnZV0uY3NzKHByb3ApOwoKICAgICAgICB9CgogICAgICAgIGlmIChkYXRhLnBhZ2VQbGFjZVtwYWdlXSA9PSBwYWdlKSB7CgogICAgICAgICAvLyBJZiB0aGUgcGFnZSBpc24ndCBpbiBhbm90aGVyIHBsYWNlLCBjcmVhdGUgdGhlIGZsaXAgZWZmZWN0CiAgICAgICAgICB0dXJuTWV0aG9kcy5fbWFrZUZsaXAuY2FsbCh0aGlzLCBwYWdlKTsKCiAgICAgIH0KICAgICAgICAKICAgICAgfSBlbHNlIHsKCiAgICAgICAgLy8gUGxhY2UKICAgICAgICBkYXRhLnBhZ2VQbGFjZVtwYWdlXSA9IDA7CgogICAgICAgIC8vIFJlbW92ZSBlbGVtZW50IGZyb20gdGhlIERPTQogICAgICAgIGlmIChkYXRhLnBhZ2VPYmpzW3BhZ2VdKQogICAgICAgICAgZGF0YS5wYWdlT2Jqc1twYWdlXS5yZW1vdmUoKTsKCiAgICAgIH0KCiAgfSwKCiAgLy8gQ2hlY2tzIGlmIGEgcGFnZSBpcyBpbiBtZW1vcnkKICAKICBoYXNQYWdlOiBmdW5jdGlvbihwYWdlKSB7CgogICAgcmV0dXJuIGhhcyhwYWdlLCB0aGlzLmRhdGEoKS5wYWdlT2Jqcyk7CiAgCiAgfSwKCiAgLy8gQ2VudGVycyB0aGUgZmxpcGJvb2sKCiAgY2VudGVyOiBmdW5jdGlvbihwYWdlKSB7CiAgICAKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIHNpemUgPSAkKHRoaXMpLnR1cm4oJ3NpemUnKSwKICAgICAgbGVmdCA9IDA7CgogICAgaWYgKCFkYXRhLm5vQ2VudGVyKSB7CiAgICAgIGlmIChkYXRhLmRpc3BsYXk9PSdkb3VibGUnKSB7CiAgICAgICAgdmFyIHZpZXcgPSB0aGlzLnR1cm4oJ3ZpZXcnLCBwYWdlIHx8IGRhdGEudHBhZ2UgfHwgZGF0YS5wYWdlKTsKCiAgICAgICAgaWYgKGRhdGEuZGlyZWN0aW9uPT0nbHRyJykgewogICAgICAgICAgaWYgKCF2aWV3WzBdKQogICAgICAgICAgICBsZWZ0IC09IHNpemUud2lkdGgvNDsKICAgICAgICAgIGVsc2UgaWYgKCF2aWV3WzFdKQogICAgICAgICAgICBsZWZ0ICs9IHNpemUud2lkdGgvNDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKCF2aWV3WzBdKQogICAgICAgICAgICBsZWZ0ICs9IHNpemUud2lkdGgvNDsKICAgICAgICAgIGVsc2UgaWYgKCF2aWV3WzFdKQogICAgICAgICAgICBsZWZ0IC09IHNpemUud2lkdGgvNDsKICAgICAgICB9CiAgICAgIAogICAgICB9CgogICAgICAkKHRoaXMpLmNzcyh7bWFyZ2luTGVmdDogbGVmdH0pOwogICAgfQoKICAgIHJldHVybiB0aGlzOwoKICB9LAoKICAvLyBEZXN0cm95cyB0aGUgZmxpcGJvb2sKCiAgZGVzdHJveTogZnVuY3Rpb24gKCkgewoKICAgIHZhciBwYWdlLAogICAgICBmbGlwYm9vayA9IHRoaXMsCiAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgZXZlbnRzID0gWwogICAgICAgICdlbmQnLCAnZmlyc3QnLCAnZmxpcCcsICdsYXN0JywgJ3ByZXNzZWQnLAogICAgICAgICdyZWxlYXNlZCcsICdzdGFydCcsICd0dXJuaW5nJywgJ3R1cm5lZCcsCiAgICAgICAgJ3pvb21pbmcnLCAnbWlzc2luZyddOwoKICAgIGlmICh0cmlnZ2VyKCdkZXN0cm95aW5nJywgdGhpcyk9PSdwcmV2ZW50ZWQnKQogICAgICByZXR1cm47CgogICAgZGF0YS5kZXN0cm95aW5nID0gdHJ1ZTsKCiAgICAkLmVhY2goZXZlbnRzLCBmdW5jdGlvbihpbmRleCwgZXZlbnROYW1lKSB7CiAgICAgIGZsaXBib29rLnVuYmluZChldmVudE5hbWUpOwogICAgfSk7CgogICAgdGhpcy5wYXJlbnQoKS51bmJpbmQoJ3N0YXJ0JywgZGF0YS5ldmVudEhhbmRsZXJzLnN0YXJ0KTsKCiAgICAkKGRvY3VtZW50KS51bmJpbmQobW91c2VFdmVudHMubW92ZSwgZGF0YS5ldmVudEhhbmRsZXJzLnRvdWNoTW92ZSkuCiAgICAgIHVuYmluZChtb3VzZUV2ZW50cy51cCwgZGF0YS5ldmVudEhhbmRsZXJzLnRvdWNoRW5kKTsKICAgIAogICAgd2hpbGUgKGRhdGEudG90YWxQYWdlcyE9PTApIHsKICAgICAgdGhpcy50dXJuKCdyZW1vdmVQYWdlJywgZGF0YS50b3RhbFBhZ2VzKTsKICAgIH0KCiAgICBpZiAoZGF0YS5mcGFyZW50KQogICAgICBkYXRhLmZwYXJlbnQucmVtb3ZlKCk7CgogICAgaWYgKGRhdGEuc2hhZG93KQogICAgICBkYXRhLnNoYWRvdy5yZW1vdmUoKTsKCiAgICB0aGlzLnJlbW92ZURhdGEoKTsKICAgIGRhdGEgPSBudWxsOwoKICAgIHJldHVybiB0aGlzOwoKICB9LAoKICAvLyBDaGVja3MgaWYgdGhpcyBlbGVtZW50IGlzIGEgZmxpcGJvb2sKCiAgaXM6IGZ1bmN0aW9uKCkgewoKICAgIHJldHVybiB0eXBlb2YodGhpcy5kYXRhKCkucGFnZXMpPT0nb2JqZWN0JzsKCiAgfSwKCiAgLy8gU2V0cyBhbmQgZ2V0cyB0aGUgem9vbSB2YWx1ZQoKICB6b29tOiBmdW5jdGlvbihuZXdab29tKSB7CiAgICAKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CgogICAgaWYgKHR5cGVvZihuZXdab29tKT09J251bWJlcicpIHsKCiAgICAgIGlmIChuZXdab29tPDAuMDAxIHx8IG5ld1pvb20+MTAwKQogICAgICAgIHRocm93IHR1cm5FcnJvcihuZXdab29tKyAnIGlzIG5vdCBhIHZhbHVlIGZvciB6b29tJyk7CiAgICAgIAogICAgICBpZiAodHJpZ2dlcignem9vbWluZycsIHRoaXMsIFtuZXdab29tLCBkYXRhLnpvb21dKT09J3ByZXZlbnRlZCcpCiAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgIAogICAgICB2YXIgc2l6ZSA9IHRoaXMudHVybignc2l6ZScpLAogICAgICAgIGN1cnJlbnRWaWV3ID0gdGhpcy50dXJuKCd2aWV3JyksCiAgICAgICAgaXogPSAxL2RhdGEuem9vbSwKICAgICAgICBuZXdXaWR0aCA9IE1hdGgucm91bmQoc2l6ZS53aWR0aCAqIGl6ICogbmV3Wm9vbSksCiAgICAgICAgbmV3SGVpZ2h0ID0gTWF0aC5yb3VuZChzaXplLmhlaWdodCAqIGl6ICogbmV3Wm9vbSk7CiAgICAKICAgICAgZGF0YS56b29tID0gbmV3Wm9vbTsKCiAgICAgICQodGhpcykudHVybignc3RvcCcpLgogICAgICAgIHR1cm4oJ3NpemUnLCBuZXdXaWR0aCwgbmV3SGVpZ2h0KTsKICAgICAgICAvKi4KICAgICAgICBjc3Moe21hcmdpblRvcDogc2l6ZS5oZWlnaHQgKiBpeiAvIDIgLSBuZXdIZWlnaHQgLyAyfSk7Ki8KCiAgICAgIGlmIChkYXRhLm9wdHMuYXV0b0NlbnRlcikKICAgICAgICB0aGlzLnR1cm4oJ2NlbnRlcicpOwogICAgICAvKmVsc2UKICAgICAgICAkKHRoaXMpLmNzcyh7bWFyZ2luTGVmdDogc2l6ZS53aWR0aCAqIGl6IC8gMiAtIG5ld1dpZHRoIC8gMn0pOyovCgogICAgICB0dXJuTWV0aG9kcy5fdXBkYXRlU2hhZG93LmNhbGwodGhpcyk7CgogICAgICBmb3IgKHZhciBpID0gMDsgaTxjdXJyZW50Vmlldy5sZW5ndGg7IGkrKykgewogICAgICAgIGlmIChjdXJyZW50Vmlld1tpXSAmJiBkYXRhLnBhZ2Vab29tW2N1cnJlbnRWaWV3W2ldXSE9ZGF0YS56b29tKSB7CiAgCiAgICAgICAgICB0aGlzLnRyaWdnZXIoJ3pvb21lZCcsWwogICAgICAgICAgICBjdXJyZW50Vmlld1tpXSwKICAgICAgICAgICAgY3VycmVudFZpZXcsCiAgICAgICAgICAgIGRhdGEucGFnZVpvb21bY3VycmVudFZpZXdbaV1dLAogICAgICAgICAgICBkYXRhLnpvb21dKTsKCiAgICAgICAgICBkYXRhLnBhZ2Vab29tW2N1cnJlbnRWaWV3W2ldXSA9IGRhdGEuem9vbTsKICAgICAgfQogICAgfQoKICAgICAgcmV0dXJuIHRoaXM7CgogICAgfSBlbHNlCiAgICAgIHJldHVybiBkYXRhLnpvb207CgogIH0sCgogIC8vIEdldHMgdGhlIHNpemUgb2YgYSBwYWdlCgogIF9wYWdlU2l6ZTogZnVuY3Rpb24ocGFnZSwgcG9zaXRpb24pIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLAogICAgICBwcm9wID0ge307CgogICAgaWYgKGRhdGEuZGlzcGxheT09J3NpbmdsZScpIHsKCiAgICAgIHByb3Aud2lkdGggPSB0aGlzLndpZHRoKCk7CiAgICAgIHByb3AuaGVpZ2h0ID0gdGhpcy5oZWlnaHQoKTsKCiAgICAgIGlmIChwb3NpdGlvbikgewogICAgICAgIHByb3AudG9wID0gMDsKICAgICAgICBwcm9wLmxlZnQgPSAwOwogICAgICAgIHByb3AucmlnaHQgPSAnYXV0byc7CiAgICAgIH0KCiAgICB9IGVsc2UgewoKICAgICAgdmFyIHBhZ2VXaWR0aCA9IHRoaXMud2lkdGgoKS8yLAogICAgICAgIHBhZ2VIZWlnaHQgPSB0aGlzLmhlaWdodCgpOwoKICAgICAgaWYgKGRhdGEucGFnZU9ianNbcGFnZV0uaGFzQ2xhc3MoJ293bi1zaXplJykpIHsKICAgICAgICBwcm9wLndpZHRoID0gZGF0YS5wYWdlT2Jqc1twYWdlXS53aWR0aCgpOwogICAgICAgIHByb3AuaGVpZ2h0ID0gZGF0YS5wYWdlT2Jqc1twYWdlXS5oZWlnaHQoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBwcm9wLndpZHRoID0gcGFnZVdpZHRoOwogICAgICAgIHByb3AuaGVpZ2h0ID0gcGFnZUhlaWdodDsKICAgICAgfQogICAgICAKICAgICAgaWYgKHBvc2l0aW9uKSB7CiAgICAgICAgdmFyIG9kZCA9IHBhZ2UlMjsKICAgICAgICBwcm9wLnRvcCA9IChwYWdlSGVpZ2h0LXByb3AuaGVpZ2h0KS8yOwoKICAgICAgICBpZiAoZGF0YS5kaXJlY3Rpb249PSdsdHInKSB7CiAgICAgICAgICAKICAgICAgICAgIHByb3BbKG9kZCkgPyAncmlnaHQnIDogJ2xlZnQnXSA9IHBhZ2VXaWR0aC1wcm9wLndpZHRoOwogICAgICAgICAgcHJvcFsob2RkKSA/ICdsZWZ0JyA6ICdyaWdodCddID0gJ2F1dG8nOwoKICAgICAgICB9IGVsc2UgewogICAgICAgICAgCiAgICAgICAgICBwcm9wWyhvZGQpID8gJ2xlZnQnIDogJ3JpZ2h0J10gPSBwYWdlV2lkdGgtcHJvcC53aWR0aDsKICAgICAgICAgIHByb3BbKG9kZCkgPyAncmlnaHQnIDogJ2xlZnQnXSA9ICdhdXRvJzsKCiAgICAgICAgfQogICAgICAKICAgICAgfQogICAgfQoKICAgIHJldHVybiBwcm9wOwoKICB9LAoKICAvLyBQcmVwYXJlcyB0aGUgZmxpcCBlZmZlY3QgZm9yIGEgcGFnZQoKICBfbWFrZUZsaXA6IGZ1bmN0aW9uKHBhZ2UpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmICghZGF0YS5wYWdlc1twYWdlXSAmJiBkYXRhLnBhZ2VQbGFjZVtwYWdlXT09cGFnZSkgewogICAgICAKICAgICAgdmFyIHNpbmdsZSA9IGRhdGEuZGlzcGxheT09J3NpbmdsZScsCiAgICAgICAgb2RkID0gcGFnZSUyOwoKICAgICAgZGF0YS5wYWdlc1twYWdlXSA9IGRhdGEucGFnZU9ianNbcGFnZV0uCiAgICAgICAgY3NzKHR1cm5NZXRob2RzLl9wYWdlU2l6ZS5jYWxsKHRoaXMsIHBhZ2UpKS4KICAgICAgICBmbGlwKHsKICAgICAgICAgIHBhZ2U6IHBhZ2UsCiAgICAgICAgICBuZXh0OiAob2RkIHx8IHNpbmdsZSkgPyBwYWdlKzEgOiBwYWdlLTEsCiAgICAgICAgICB0dXJuOiB0aGlzCiAgICAgICAgfSkuCiAgICAgICAgZmxpcCgnZGlzYWJsZScsIGRhdGEuZGlzYWJsZWQpOwoKICAgICAgICAvLyBJc3N1ZSBhYm91dCB6LWluZGV4CiAgICAgICAgdHVybk1ldGhvZHMuX3NldFBhZ2VMb2MuY2FsbCh0aGlzLCBwYWdlKTsKCiAgICAgICAgZGF0YS5wYWdlWm9vbVtwYWdlXSA9IGRhdGEuem9vbTsKICAgICAgICAKICAgIH0KCiAgICByZXR1cm4gZGF0YS5wYWdlc1twYWdlXTsKICB9LAoKICAvLyBNYWtlcyBwYWdlcyB3aXRoaW4gYSByYW5nZQoKICBfbWFrZVJhbmdlOiBmdW5jdGlvbigpIHsKCiAgICB2YXIgcGFnZSwgcmFuZ2UsCiAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKTsKCiAgICBpZiAoZGF0YS50b3RhbFBhZ2VzPDEpCiAgICAgIHJldHVybjsKCiAgICByYW5nZSA9IHRoaXMudHVybigncmFuZ2UnKTsKCiAgICBmb3IgKHBhZ2UgPSByYW5nZVswXTsgcGFnZTw9cmFuZ2VbMV07IHBhZ2UrKykKICAgICAgdHVybk1ldGhvZHMuX2FkZFBhZ2UuY2FsbCh0aGlzLCBwYWdlKTsKCiAgfSwKCiAgLy8gUmV0dXJucyBhIHJhbmdlIG9mIHBhZ2VzIHRoYXQgc2hvdWxkIGJlIGluIHRoZSBET00KICAvLyBFeGFtcGxlOgogIC8vIC0gcGFnZSBpbiB0aGUgY3VycmVudCB2aWV3LCByZXR1cm4gdHJ1ZQogIC8vICogcGFnZSBpcyBpbiB0aGUgcmFuZ2UsIHJldHVybiB0cnVlCiAgLy8gT3RoZXJ3aXNlLCByZXR1cm4gZmFsc2UKICAvLwogIC8vIDEgMi0zIDQtNSA2LTcgOC05IDEwLTExIDEyLTEzCiAgLy8gICAqKiAgKiogIC0tICAgKiogICoqCgogIHJhbmdlOiBmdW5jdGlvbihwYWdlKSB7CgogICAgdmFyIHJlbWFpbmluZ1BhZ2VzLCBsZWZ0LCByaWdodCwgdmlldywKICAgICAgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgICAgcGFnZSA9IHBhZ2UgfHwgZGF0YS50cGFnZSB8fCBkYXRhLnBhZ2UgfHwgMTsKICAgICAgdmlldyA9IHR1cm5NZXRob2RzLl92aWV3LmNhbGwodGhpcywgcGFnZSk7CgogICAgICBpZiAocGFnZTwxIHx8IHBhZ2U+ZGF0YS50b3RhbFBhZ2VzKQogICAgICAgIHRocm93IHR1cm5FcnJvcignIicrcGFnZSsnIiBpcyBub3QgYSB2YWxpZCBwYWdlJyk7CgogICAgCiAgICAgIHZpZXdbMV0gPSB2aWV3WzFdIHx8IHZpZXdbMF07CiAgICAgIAogICAgICBpZiAodmlld1swXT49MSAmJiB2aWV3WzFdPD1kYXRhLnRvdGFsUGFnZXMpIHsKCiAgICAgICAgcmVtYWluaW5nUGFnZXMgPSBNYXRoLmZsb29yKChwYWdlc0luRE9NLTIpLzIpOwoKICAgICAgICBpZiAoZGF0YS50b3RhbFBhZ2VzLXZpZXdbMV0gPiB2aWV3WzBdKSB7CiAgICAgICAgICBsZWZ0ID0gTWF0aC5taW4odmlld1swXS0xLCByZW1haW5pbmdQYWdlcyk7CiAgICAgICAgICByaWdodCA9IDIqcmVtYWluaW5nUGFnZXMtbGVmdDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmlnaHQgPSBNYXRoLm1pbihkYXRhLnRvdGFsUGFnZXMtdmlld1sxXSwgcmVtYWluaW5nUGFnZXMpOwogICAgICAgICAgbGVmdCA9IDIqcmVtYWluaW5nUGFnZXMtcmlnaHQ7CiAgICAgICAgfQoKICAgICAgfSBlbHNlIHsKICAgICAgICBsZWZ0ID0gcGFnZXNJbkRPTS0xOwogICAgICAgIHJpZ2h0ID0gcGFnZXNJbkRPTS0xOwogICAgICB9CgogICAgICByZXR1cm4gW01hdGgubWF4KDEsIHZpZXdbMF0tbGVmdCksCiAgICAgICAgICBNYXRoLm1pbihkYXRhLnRvdGFsUGFnZXMsIHZpZXdbMV0rcmlnaHQpXTsKCiAgfSwKCiAgLy8gRGV0ZWN0cyBpZiBhIHBhZ2UgaXMgd2l0aGluIHRoZSByYW5nZSBvZiBgcGFnZXNJbkRPTWAgZnJvbSB0aGUgY3VycmVudCB2aWV3CgogIF9uZWNlc3NQYWdlOiBmdW5jdGlvbihwYWdlKSB7CiAgICAKICAgIGlmIChwYWdlPT09MCkKICAgICAgcmV0dXJuIHRydWU7CgogICAgdmFyIHJhbmdlID0gdGhpcy50dXJuKCdyYW5nZScpOwoKICAgIHJldHVybiB0aGlzLmRhdGEoKS5wYWdlT2Jqc1twYWdlXS5oYXNDbGFzcygnZml4ZWQnKSB8fAogICAgICAocGFnZT49cmFuZ2VbMF0gJiYgcGFnZTw9cmFuZ2VbMV0pOwogICAgCiAgfSwKCiAgLy8gUmVsZWFzZXMgbWVtb3J5IGJ5IHJlbW92aW5nIHBhZ2VzIGZyb20gdGhlIERPTQoKICBfcmVtb3ZlRnJvbURPTTogZnVuY3Rpb24oKSB7CgogICAgdmFyIHBhZ2UsIGRhdGEgPSB0aGlzLmRhdGEoKTsKCiAgICBmb3IgKHBhZ2UgaW4gZGF0YS5wYWdlV3JhcCkKICAgICAgaWYgKGhhcyhwYWdlLCBkYXRhLnBhZ2VXcmFwKSAmJgogICAgICAgICF0dXJuTWV0aG9kcy5fbmVjZXNzUGFnZS5jYWxsKHRoaXMsIHBhZ2UpKQogICAgICB0dXJuTWV0aG9kcy5fcmVtb3ZlUGFnZUZyb21ET00uY2FsbCh0aGlzLCBwYWdlKTsKICAgIAogIH0sCgogIC8vIFJlbW92ZXMgYSBwYWdlIGZyb20gRE9NIGFuZCBpdHMgaW50ZXJuYWwgcmVmZXJlbmNlcwoKICBfcmVtb3ZlUGFnZUZyb21ET006IGZ1bmN0aW9uKHBhZ2UpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmIChkYXRhLnBhZ2VzW3BhZ2VdKSB7CiAgICAgIHZhciBkZCA9IGRhdGEucGFnZXNbcGFnZV0uZGF0YSgpOwoKICAgICAgZmxpcE1ldGhvZHMuX21vdmVGb2xkaW5nUGFnZS5jYWxsKGRhdGEucGFnZXNbcGFnZV0sIGZhbHNlKTsKCiAgICAgIGlmIChkZC5mICYmIGRkLmYuZndyYXBwZXIpCiAgICAgICAgZGQuZi5md3JhcHBlci5yZW1vdmUoKTsKCiAgICAgIGRhdGEucGFnZXNbcGFnZV0ucmVtb3ZlRGF0YSgpOwogICAgICBkYXRhLnBhZ2VzW3BhZ2VdLnJlbW92ZSgpOwogICAgICBkZWxldGUgZGF0YS5wYWdlc1twYWdlXTsKICAgIH0KCiAgICBpZiAoZGF0YS5wYWdlT2Jqc1twYWdlXSkKICAgICAgZGF0YS5wYWdlT2Jqc1twYWdlXS5yZW1vdmUoKTsKCiAgICBpZiAoZGF0YS5wYWdlV3JhcFtwYWdlXSkgewogICAgICBkYXRhLnBhZ2VXcmFwW3BhZ2VdLnJlbW92ZSgpOwogICAgICBkZWxldGUgZGF0YS5wYWdlV3JhcFtwYWdlXTsKICAgIH0KCiAgICB0dXJuTWV0aG9kcy5fcmVtb3ZlTXYuY2FsbCh0aGlzLCBwYWdlKTsKCiAgICBkZWxldGUgZGF0YS5wYWdlUGxhY2VbcGFnZV07CiAgICBkZWxldGUgZGF0YS5wYWdlWm9vbVtwYWdlXTsKCiAgfSwKCiAgLy8gUmVtb3ZlcyBhIHBhZ2UKCiAgcmVtb3ZlUGFnZTogZnVuY3Rpb24ocGFnZSkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CgogICAgLy8gRGVsZXRlIGFsbCB0aGUgcGFnZXMKICAgIGlmIChwYWdlPT0nKicpIHsKICAgICAgCiAgICAgIHdoaWxlIChkYXRhLnRvdGFsUGFnZXMhPT0wKSB7CiAgICAgICAgdGhpcy50dXJuKCdyZW1vdmVQYWdlJywgZGF0YS50b3RhbFBhZ2VzKTsKICAgICAgfQoKICAgIH0gZWxzZSB7CgogICAgICBpZiAocGFnZTwxIHx8IHBhZ2U+ZGF0YS50b3RhbFBhZ2VzKQogICAgICAgIHRocm93IHR1cm5FcnJvcignVGhlIHBhZ2UgJysgcGFnZSArICcgZG9lc25cJ3QgZXhpc3QnKTsKICAgICAgICAKICAgICAgaWYgKGRhdGEucGFnZU9ianNbcGFnZV0pIHsKCiAgICAgICAgLy8gU3RvcCBhbmltYXRpb25zCiAgICAgICAgdGhpcy50dXJuKCdzdG9wJyk7CgogICAgICAgIC8vIFJlbW92ZSBgcGFnZWAKICAgICAgICB0dXJuTWV0aG9kcy5fcmVtb3ZlUGFnZUZyb21ET00uY2FsbCh0aGlzLCBwYWdlKTsKCiAgICAgICAgZGVsZXRlIGRhdGEucGFnZU9ianNbcGFnZV07CgogICAgICB9CgogICAgICAvLyBNb3ZlIHRoZSBwYWdlcwogICAgICB0dXJuTWV0aG9kcy5fbW92ZVBhZ2VzLmNhbGwodGhpcywgcGFnZSwgLTEpOwoKICAgICAgLy8gUmVzaXplIHRoZSBzaXplIG9mIHRoaXMgZmxpcGJvb2sKICAgICAgZGF0YS50b3RhbFBhZ2VzID0gZGF0YS50b3RhbFBhZ2VzLTE7CgogICAgICAvLyBDaGVjayB0aGUgY3VycmVudCB2aWV3CgogICAgICBpZiAoZGF0YS5wYWdlPmRhdGEudG90YWxQYWdlcykgewoKICAgICAgIGRhdGEucGFnZSA9IG51bGw7CiAgICAgICB0dXJuTWV0aG9kcy5fZml0UGFnZS5jYWxsKHRoaXMsIGRhdGEudG90YWxQYWdlcyk7CgogICAgICB9IGVsc2UgewoKICAgICAgICB0dXJuTWV0aG9kcy5fbWFrZVJhbmdlLmNhbGwodGhpcyk7CiAgICAgICAgdGhpcy50dXJuKCd1cGRhdGUnKTsKCiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gdGhpczsKICAKICB9LAoKICAvLyBNb3ZlcyBwYWdlcwoKICBfbW92ZVBhZ2VzOiBmdW5jdGlvbihmcm9tLCBjaGFuZ2UpIHsKCiAgICB2YXIgcGFnZSwKICAgICAgdGhhdCA9IHRoaXMsCiAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgc2luZ2xlID0gZGF0YS5kaXNwbGF5PT0nc2luZ2xlJywKICAgICAgbW92ZSA9IGZ1bmN0aW9uKHBhZ2UpIHsKCiAgICAgICAgdmFyIG5leHQgPSBwYWdlICsgY2hhbmdlLAogICAgICAgICAgb2RkID0gbmV4dCUyLAogICAgICAgICAgY2xhc3NOYW1lID0gKG9kZCkgPyAnIG9kZCAnIDogJyBldmVuICc7CgogICAgICAgIGlmIChkYXRhLnBhZ2VPYmpzW3BhZ2VdKQogICAgICAgICAgZGF0YS5wYWdlT2Jqc1tuZXh0XSA9IGRhdGEucGFnZU9ianNbcGFnZV0uCiAgICAgICAgICAgIHJlbW92ZUNsYXNzKCdwJyArIHBhZ2UgKyAnIG9kZCBldmVuJykuCiAgICAgICAgICAgIGFkZENsYXNzKCdwJyArIG5leHQgKyBjbGFzc05hbWUpOwoKICAgICAgICBpZiAoZGF0YS5wYWdlUGxhY2VbcGFnZV0gJiYgZGF0YS5wYWdlV3JhcFtwYWdlXSkgewoKICAgICAgICAgIGRhdGEucGFnZVBsYWNlW25leHRdID0gbmV4dDsKICAgICAgICAKICAgICAgICAgIGlmIChkYXRhLnBhZ2VPYmpzW25leHRdLmhhc0NsYXNzKCdmaXhlZCcpKQogICAgICAgICAgICBkYXRhLnBhZ2VXcmFwW25leHRdID0gZGF0YS5wYWdlV3JhcFtwYWdlXS4KICAgICAgICAgICAgICBhdHRyKCdwYWdlJywgbmV4dCk7CiAgICAgICAgICBlbHNlCiAgICAgICAgICAgIGRhdGEucGFnZVdyYXBbbmV4dF0gPSBkYXRhLnBhZ2VXcmFwW3BhZ2VdLgogICAgICAgICAgICAgIGNzcyh0dXJuTWV0aG9kcy5fcGFnZVNpemUuY2FsbCh0aGF0LCBuZXh0LCB0cnVlKSkuCiAgICAgICAgICAgICAgYXR0cigncGFnZScsIG5leHQpOwogICAgICAKICAgICAgICAgICAgaWYgKGRhdGEucGFnZXNbcGFnZV0pCiAgICAgICAgICAgICAgZGF0YS5wYWdlc1tuZXh0XSA9IGRhdGEucGFnZXNbcGFnZV0uCiAgICAgICAgICAgICAgICBmbGlwKCdvcHRpb25zJywgewogICAgICAgICAgICAgICAgICBwYWdlOiBuZXh0LAogICAgICAgICAgICAgICAgICBuZXh0OiAoc2luZ2xlIHx8IG9kZCkgPyBuZXh0KzEgOiBuZXh0LTEKICAgICAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgaWYgKGNoYW5nZSkgewogICAgICAgICAgICAgIGRlbGV0ZSBkYXRhLnBhZ2VzW3BhZ2VdOwogICAgICAgICAgICAgIGRlbGV0ZSBkYXRhLnBhZ2VQbGFjZVtwYWdlXTsKICAgICAgICAgICAgICBkZWxldGUgZGF0YS5wYWdlWm9vbVtwYWdlXTsKICAgICAgICAgICAgICBkZWxldGUgZGF0YS5wYWdlT2Jqc1twYWdlXTsKICAgICAgICAgICAgICBkZWxldGUgZGF0YS5wYWdlV3JhcFtwYWdlXTsKICAgICAgICAgICAgfQoKICAgICAgICB9CgogICAgfTsKCiAgICBpZiAoY2hhbmdlPjApCiAgICAgIGZvciAocGFnZT1kYXRhLnRvdGFsUGFnZXM7IHBhZ2U+PWZyb207IHBhZ2UtLSkKICAgICAgICBtb3ZlKHBhZ2UpOwogICAgZWxzZQogICAgICBmb3IgKHBhZ2U9ZnJvbTsgcGFnZTw9ZGF0YS50b3RhbFBhZ2VzOyBwYWdlKyspCiAgICAgICAgbW92ZShwYWdlKTsKCiAgfSwKCiAgLy8gU2V0cyBvciBHZXRzIHRoZSBkaXNwbGF5IG1vZGUKCiAgZGlzcGxheTogZnVuY3Rpb24oZGlzcGxheSkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIGN1cnJlbnREaXNwbGF5ID0gZGF0YS5kaXNwbGF5OwoKICAgIGlmIChkaXNwbGF5PT09dW5kZWZpbmVkKSB7CiAgICAgIAogICAgICByZXR1cm4gY3VycmVudERpc3BsYXk7CgogICAgfSBlbHNlIHsKCiAgICAgIGlmICgkLmluQXJyYXkoZGlzcGxheSwgZGlzcGxheXMpPT0tMSkKICAgICAgICB0aHJvdyB0dXJuRXJyb3IoJyInK2Rpc3BsYXkgKyAnIiBpcyBub3QgYSB2YWx1ZSBmb3IgZGlzcGxheScpOwogICAgICAKICAgICAgc3dpdGNoKGRpc3BsYXkpIHsKICAgICAgICBjYXNlICdzaW5nbGUnOgoKICAgICAgICAgIC8vIENyZWF0ZSBhIHRlbXBvcmFsIHBhZ2UgdG8gdXNlIGFzIGZvbGRlZCBwYWdlCgogICAgICAgICAgaWYgKCFkYXRhLnBhZ2VPYmpzWzBdKSB7CiAgICAgICAgICAgIHRoaXMudHVybignc3RvcCcpLgogICAgICAgICAgICAgIGNzcyh7J292ZXJmbG93JzogJ2hpZGRlbid9KTsKCiAgICAgICAgICAgIGRhdGEucGFnZU9ianNbMF0gPSAkKCc8ZGl2IC8+JywKICAgICAgICAgICAgICAgIHsnY2xhc3MnOiAncGFnZSBwLXRlbXBvcmFsJ30pLgogICAgICAgICAgICAgIGNzcyh7d2lkdGg6IHRoaXMud2lkdGgoKSwgaGVpZ2h0OiB0aGlzLmhlaWdodCgpfSkuCiAgICAgICAgICAgICAgYXBwZW5kVG8odGhpcyk7CiAgICAgICAgICB9CgogICAgICAgICAgdGhpcy5hZGRDbGFzcygnc2hhZG93Jyk7CgogICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJ2RvdWJsZSc6CgogICAgICAgICAgLy8gUmVtb3ZlIHRoZSB0ZW1wb3JhbCBwYWdlCgogICAgICAgICAgaWYgKGRhdGEucGFnZU9ianNbMF0pIHsKICAgICAgICAgICAgdGhpcy50dXJuKCdzdG9wJykuY3NzKHsnb3ZlcmZsb3cnOiAnJ30pOwogICAgICAgICAgICBkYXRhLnBhZ2VPYmpzWzBdLnJlbW92ZSgpOwogICAgICAgICAgICBkZWxldGUgZGF0YS5wYWdlT2Jqc1swXTsKICAgICAgICAgIH0KCiAgICAgICAgICB0aGlzLnJlbW92ZUNsYXNzKCdzaGFkb3cnKTsKCiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgCgogICAgICBkYXRhLmRpc3BsYXkgPSBkaXNwbGF5OwoKICAgICAgaWYgKGN1cnJlbnREaXNwbGF5KSB7CiAgICAgICAgdmFyIHNpemUgPSB0aGlzLnR1cm4oJ3NpemUnKTsKICAgICAgICB0dXJuTWV0aG9kcy5fbW92ZVBhZ2VzLmNhbGwodGhpcywgMSwgMCk7CiAgICAgICAgdGhpcy50dXJuKCdzaXplJywgc2l6ZS53aWR0aCwgc2l6ZS5oZWlnaHQpLgogICAgICAgICAgdHVybigndXBkYXRlJyk7CiAgICAgIH0KCiAgICAgIHJldHVybiB0aGlzOwoKICAgIH0KICAKICB9LAogIAogIC8vIEdldHMgYW5kIHNldHMgdGhlIGRpcmVjdGlvbiBvZiB0aGUgZmxpcGJvb2sKCiAgZGlyZWN0aW9uOiBmdW5jdGlvbihkaXIpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmIChkaXI9PT11bmRlZmluZWQpIHsKCiAgICAgIHJldHVybiBkYXRhLmRpcmVjdGlvbjsKCiAgICB9IGVsc2UgewoKICAgICAgZGlyID0gZGlyLnRvTG93ZXJDYXNlKCk7CgogICAgICBpZiAoJC5pbkFycmF5KGRpciwgZGlyZWN0aW9ucyk9PS0xKQogICAgICAgIHRocm93IHR1cm5FcnJvcignIicgKyBkaXIgKyAnIiBpcyBub3QgYSB2YWx1ZSBmb3IgZGlyZWN0aW9uJyk7CgogICAgICBpZiAoZGlyPT0ncnRsJykgewogICAgICAgICQodGhpcykuYXR0cignZGlyJywgJ2x0cicpLgogICAgICAgICAgY3NzKHtkaXJlY3Rpb246ICdsdHInfSk7CiAgICAgIH0KCiAgICAgIGRhdGEuZGlyZWN0aW9uID0gZGlyOwoKICAgICAgaWYgKGRhdGEuZG9uZSkKICAgICAgICB0aGlzLnR1cm4oJ3NpemUnLCAkKHRoaXMpLndpZHRoKCksICQodGhpcykuaGVpZ2h0KCkpOwoKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogIH0sCgogIC8vIERldGVjdHMgYW5pbWF0aW9uCgogIGFuaW1hdGluZzogZnVuY3Rpb24oKSB7CgogICAgcmV0dXJuIHRoaXMuZGF0YSgpLnBhZ2VNdi5sZW5ndGg+MDsKCiAgfSwKCiAgLy8gR2V0cyB0aGUgY3VycmVudCBhY3RpdmF0ZWQgY29ybmVyCgogIGNvcm5lcjogZnVuY3Rpb24oKSB7CiAgICAKICAgIHZhciBjb3JuZXIsCiAgICAgIHBhZ2UsCiAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKTsKCiAgICBmb3IgKHBhZ2UgaW4gZGF0YS5wYWdlcykgewogICAgICBpZiAoaGFzKHBhZ2UsIGRhdGEucGFnZXMpKQogICAgICAgIGlmICgoY29ybmVyID0gZGF0YS5wYWdlc1twYWdlXS5mbGlwKCdjb3JuZXInKSkpIHsKICAgICAgICAgIHJldHVybiBjb3JuZXI7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBmYWxzZTsKICB9LAoKICAvLyBHZXRzIHRoZSBkYXRhIHN0b3JlZCBpbiB0aGUgZmxpcGJvb2sKCiAgZGF0YTogZnVuY3Rpb24oKSB7CiAgICAKICAgIHJldHVybiB0aGlzLmRhdGEoKTsKCiAgfSwKCiAgLy8gRGlzYWJsZXMgYW5kIGVuYWJsZXMgdGhlIGVmZmVjdAoKICBkaXNhYmxlOiBmdW5jdGlvbihkaXNhYmxlKSB7CgogICAgdmFyIHBhZ2UsCiAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgdmlldyA9IHRoaXMudHVybigndmlldycpOwoKICAgIGRhdGEuZGlzYWJsZWQgPSBkaXNhYmxlPT09dW5kZWZpbmVkIHx8IGRpc2FibGU9PT10cnVlOwoKICAgIGZvciAocGFnZSBpbiBkYXRhLnBhZ2VzKSB7CiAgICAgIGlmIChoYXMocGFnZSwgZGF0YS5wYWdlcykpCiAgICAgICAgZGF0YS5wYWdlc1twYWdlXS5mbGlwKCdkaXNhYmxlJywKICAgICAgICAgIChkYXRhLmRpc2FibGVkKSA/IHRydWUgOiAkLmluQXJyYXkocGFyc2VJbnQocGFnZSwgMTApLCB2aWV3KT09LTEpOwogICAgfQoKICAgIHJldHVybiB0aGlzOwoKICB9LAoKICAvLyBEaXNhYmxlcyBhbmQgZW5hYmxlcyB0aGUgZWZmZWN0CgogIGRpc2FibGVkOiBmdW5jdGlvbihkaXNhYmxlKSB7CgogICAgaWYgKGRpc2FibGU9PT11bmRlZmluZWQpIHsKICAgICAgcmV0dXJuIHRoaXMuZGF0YSgpLmRpc2FibGVkPT09dHJ1ZTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiB0aGlzLnR1cm4oJ2Rpc2FibGUnLCBkaXNhYmxlKTsKICAgIH0KCiAgfSwKCiAgLy8gR2V0cyBhbmQgc2V0cyB0aGUgc2l6ZQoKICBzaXplOiBmdW5jdGlvbih3aWR0aCwgaGVpZ2h0KSB7CgogICAgaWYgKHdpZHRoPT09dW5kZWZpbmVkIHx8IGhlaWdodD09PXVuZGVmaW5lZCkgewogICAgICAKICAgICAgcmV0dXJuIHt3aWR0aDogdGhpcy53aWR0aCgpLCBoZWlnaHQ6IHRoaXMuaGVpZ2h0KCl9OwoKICAgIH0gZWxzZSB7CgogICAgICB0aGlzLnR1cm4oJ3N0b3AnKTsKCiAgICAgIHZhciBwYWdlLCBwcm9wLAogICAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgICBwYWdlV2lkdGggPSAoZGF0YS5kaXNwbGF5PT0nZG91YmxlJykgPyB3aWR0aC8yIDogd2lkdGg7CgogICAgICB0aGlzLmNzcyh7d2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodH0pOwoKICAgICAgaWYgKGRhdGEucGFnZU9ianNbMF0pCiAgICAgICAgZGF0YS5wYWdlT2Jqc1swXS5jc3Moe3dpZHRoOiBwYWdlV2lkdGgsIGhlaWdodDogaGVpZ2h0fSk7CiAgICAgIAogICAgICBmb3IgKHBhZ2UgaW4gZGF0YS5wYWdlV3JhcCkgewogICAgICAgIGlmICghaGFzKHBhZ2UsIGRhdGEucGFnZVdyYXApKSBjb250aW51ZTsKCiAgICAgICAgcHJvcCA9IHR1cm5NZXRob2RzLl9wYWdlU2l6ZS5jYWxsKHRoaXMsIHBhZ2UsIHRydWUpOwoKICAgICAgICBkYXRhLnBhZ2VPYmpzW3BhZ2VdLmNzcyh7d2lkdGg6IHByb3Aud2lkdGgsIGhlaWdodDogcHJvcC5oZWlnaHR9KTsKICAgICAgICBkYXRhLnBhZ2VXcmFwW3BhZ2VdLmNzcyhwcm9wKTsKICAgICAgICAKICAgICAgICBpZiAoZGF0YS5wYWdlc1twYWdlXSkKICAgICAgICAgIGRhdGEucGFnZXNbcGFnZV0uY3NzKHt3aWR0aDogcHJvcC53aWR0aCwgaGVpZ2h0OiBwcm9wLmhlaWdodH0pOwogICAgICB9CgogICAgICB0aGlzLnR1cm4oJ3Jlc2l6ZScpOwoKICAgICAgcmV0dXJuIHRoaXM7CgogICAgfQogIH0sCgogIC8vIFJlc2l6ZXMgZWFjaCBwYWdlCgogIHJlc2l6ZTogZnVuY3Rpb24oKSB7CgogICAgdmFyIHBhZ2UsIGRhdGEgPSB0aGlzLmRhdGEoKTsKCiAgICBpZiAoZGF0YS5wYWdlc1swXSkgewogICAgICBkYXRhLnBhZ2VXcmFwWzBdLmNzcyh7bGVmdDogLXRoaXMud2lkdGgoKX0pOwogICAgICBkYXRhLnBhZ2VzWzBdLmZsaXAoJ3Jlc2l6ZScsIHRydWUpOwogICAgfQoKICAgIGZvciAocGFnZSA9IDE7IHBhZ2UgPD0gZGF0YS50b3RhbFBhZ2VzOyBwYWdlKyspCiAgICAgIGlmIChkYXRhLnBhZ2VzW3BhZ2VdKQogICAgICAgIGRhdGEucGFnZXNbcGFnZV0uZmxpcCgncmVzaXplJywgdHJ1ZSk7CgogICAgdHVybk1ldGhvZHMuX3VwZGF0ZVNoYWRvdy5jYWxsKHRoaXMpOwoKICAgIGlmIChkYXRhLm9wdHMuYXV0b0NlbnRlcikKICAgICAgdGhpcy50dXJuKCdjZW50ZXInKTsKCiAgfSwKCiAgLy8gUmVtb3ZlcyBhbiBhbmltYXRpb24gZnJvbSB0aGUgY2FjaGUKCiAgX3JlbW92ZU12OiBmdW5jdGlvbihwYWdlKSB7CgogICAgdmFyIGksIGRhdGEgPSB0aGlzLmRhdGEoKTsKICAgICAgCiAgICBmb3IgKGk9MDsgaTxkYXRhLnBhZ2VNdi5sZW5ndGg7IGkrKykKICAgICAgaWYgKGRhdGEucGFnZU12W2ldPT1wYWdlKSB7CiAgICAgICAgZGF0YS5wYWdlTXYuc3BsaWNlKGksIDEpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CgogICAgcmV0dXJuIGZhbHNlOwoKICB9LAoKICAvLyBBZGRzIGFuIGFuaW1hdGlvbiB0byB0aGUgY2FjaGUKICAKICBfYWRkTXY6IGZ1bmN0aW9uKHBhZ2UpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIHR1cm5NZXRob2RzLl9yZW1vdmVNdi5jYWxsKHRoaXMsIHBhZ2UpOwogICAgZGF0YS5wYWdlTXYucHVzaChwYWdlKTsKCiAgfSwKCiAgLy8gR2V0cyBpbmRleGVzIGZvciBhIHZpZXcKCiAgX3ZpZXc6IGZ1bmN0aW9uKHBhZ2UpIHsKICAKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CiAgICAKICAgIHBhZ2UgPSBwYWdlIHx8IGRhdGEucGFnZTsKCiAgICBpZiAoZGF0YS5kaXNwbGF5PT0nZG91YmxlJykKICAgICAgcmV0dXJuIChwYWdlJTIpID8gW3BhZ2UtMSwgcGFnZV0gOiBbcGFnZSwgcGFnZSsxXTsKICAgIGVsc2UKICAgICAgcmV0dXJuIFtwYWdlXTsKCiAgfSwKCiAgLy8gR2V0cyBhIHZpZXcKCiAgdmlldzogZnVuY3Rpb24ocGFnZSkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIHZpZXcgPSB0dXJuTWV0aG9kcy5fdmlldy5jYWxsKHRoaXMsIHBhZ2UpOwoKICAgIGlmIChkYXRhLmRpc3BsYXk9PSdkb3VibGUnKQogICAgICByZXR1cm4gWyh2aWV3WzBdPjApID8gdmlld1swXSA6IDAsCiAgICAgICAgKHZpZXdbMV08PWRhdGEudG90YWxQYWdlcykgPyB2aWV3WzFdIDogMF07CiAgICBlbHNlCiAgICAgIHJldHVybiBbKHZpZXdbMF0+MCAmJiB2aWV3WzBdPD1kYXRhLnRvdGFsUGFnZXMpID8gdmlld1swXSA6IDBdOwoKICB9LAoKICAvLyBTdG9wcyBhbmltYXRpb25zCgogIHN0b3A6IGZ1bmN0aW9uKGlnbm9yZSwgYW5pbWF0ZSkgewoKICAgIGlmICh0aGlzLnR1cm4oJ2FuaW1hdGluZycpKSB7CiAgCiAgICAgIHZhciBpLCBvcHRzLCBwYWdlLAogICAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKTsKCiAgICAgIGlmIChkYXRhLnRwYWdlKSB7CiAgICAgICAgZGF0YS5wYWdlID0gZGF0YS50cGFnZTsKICAgICAgICBkZWxldGUgZGF0YVsndHBhZ2UnXTsKICAgICAgfQoKICAgICAgZm9yIChpID0gMDsgaTxkYXRhLnBhZ2VNdi5sZW5ndGg7IGkrKykgewoKICAgICAgICBpZiAoIWRhdGEucGFnZU12W2ldIHx8IGRhdGEucGFnZU12W2ldPT09aWdub3JlKQogICAgICAgICAgY29udGludWU7CgogICAgICAgIHBhZ2UgPSBkYXRhLnBhZ2VzW2RhdGEucGFnZU12W2ldXTsKICAgICAgICBvcHRzID0gcGFnZS5kYXRhKCkuZi5vcHRzOwoKICAgICAgICBwYWdlLmZsaXAoJ2hpZGVGb2xkZWRQYWdlJywgYW5pbWF0ZSk7CgogICAgICAgIGlmICghYW5pbWF0ZSkKICAgICAgICAgIGZsaXBNZXRob2RzLl9tb3ZlRm9sZGluZ1BhZ2UuY2FsbChwYWdlLCBmYWxzZSk7CgogICAgICAgIGlmIChvcHRzLmZvcmNlKSB7CiAgICAgICAgICBvcHRzLm5leHQgPSAob3B0cy5wYWdlJTI9PT0wKSA/IG9wdHMucGFnZS0xIDogb3B0cy5wYWdlKzE7CiAgICAgICAgICBkZWxldGUgb3B0c1snZm9yY2UnXTsKICAgICAgICB9CgogICAgICB9CiAgICB9CiAgICAKICAgIHRoaXMudHVybigndXBkYXRlJyk7CgogICAgcmV0dXJuIHRoaXM7CiAgfSwKCiAgLy8gR2V0cyBhbmQgc2V0cyB0aGUgbnVtYmVyIG9mIHBhZ2VzCgogIHBhZ2VzOiBmdW5jdGlvbihwYWdlcykgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CgogICAgaWYgKHBhZ2VzKSB7CgogICAgICBpZiAocGFnZXM8ZGF0YS50b3RhbFBhZ2VzKSB7CgogICAgICAgIGZvciAodmFyIHBhZ2UgPSBkYXRhLnRvdGFsUGFnZXM7IHBhZ2U+cGFnZXM7IHBhZ2UtLSkKICAgICAgICAgIHRoaXMudHVybigncmVtb3ZlUGFnZScsIHBhZ2UpOwoKICAgICAgfQoKICAgICAgICBkYXRhLnRvdGFsUGFnZXMgPSBwYWdlczsKICAgICAgICB0dXJuTWV0aG9kcy5fZml0UGFnZS5jYWxsKHRoaXMsIGRhdGEucGFnZSk7CgogICAgICByZXR1cm4gdGhpczsKCiAgICB9IGVsc2UKICAgICAgcmV0dXJuIGRhdGEudG90YWxQYWdlczsKCiAgfSwKCiAgLy8gQ2hlY2tzIG1pc3NpbmcgcGFnZXMKCiAgX21pc3NpbmcgOiBmdW5jdGlvbihwYWdlKSB7CiAgICAKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CgogICAgaWYgKGRhdGEudG90YWxQYWdlczwxKQogICAgICByZXR1cm47CgogICAgdmFyIHAsCiAgICAgICAgcmFuZ2UgPSB0aGlzLnR1cm4oJ3JhbmdlJywgcGFnZSksCiAgICAgICAgbWlzc2luZyA9IFtdOwoKICAgIGZvciAocCA9IHJhbmdlWzBdOyBwPD1yYW5nZVsxXTsgcCsrKSB7CiAgICAgIGlmICghZGF0YS5wYWdlT2Jqc1twXSkKICAgICAgICBtaXNzaW5nLnB1c2gocCk7CiAgICB9CgogICAgaWYgKG1pc3NpbmcubGVuZ3RoPjApCiAgICAgIHRoaXMudHJpZ2dlcignbWlzc2luZycsIFttaXNzaW5nXSk7CgogIH0sCgogIC8vIFNldHMgYSBwYWdlIHdpdGhvdXQgZWZmZWN0CgogIF9maXRQYWdlOiBmdW5jdGlvbihwYWdlKSB7CgogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgbmV3VmlldyA9IHRoaXMudHVybigndmlldycsIHBhZ2UpOwoKICAgIHR1cm5NZXRob2RzLl9taXNzaW5nLmNhbGwodGhpcywgcGFnZSk7CiAgICAKICAgIGlmICghZGF0YS5wYWdlT2Jqc1twYWdlXSkKICAgICAgcmV0dXJuOwoKICAgIGRhdGEucGFnZSA9IHBhZ2U7CiAgCiAgICB0aGlzLnR1cm4oJ3N0b3AnKTsKCiAgICBmb3IgKHZhciBpID0gMDsgaTxuZXdWaWV3Lmxlbmd0aDsgaSsrKSB7CgogICAgICBpZiAobmV3Vmlld1tpXSAmJiBkYXRhLnBhZ2Vab29tW25ld1ZpZXdbaV1dIT1kYXRhLnpvb20pIHsKICAKICAgICAgICB0aGlzLnRyaWdnZXIoJ3pvb21lZCcsWwogICAgICAgICAgbmV3Vmlld1tpXSwKICAgICAgICAgIG5ld1ZpZXcsCiAgICAgICAgICBkYXRhLnBhZ2Vab29tW25ld1ZpZXdbaV1dLAogICAgICAgICAgZGF0YS56b29tXSk7CgogICAgICAgIGRhdGEucGFnZVpvb21bbmV3Vmlld1tpXV0gPSBkYXRhLnpvb207CgogICAgICB9CiAgICB9CgogICAgdHVybk1ldGhvZHMuX3JlbW92ZUZyb21ET00uY2FsbCh0aGlzKTsKICAgIHR1cm5NZXRob2RzLl9tYWtlUmFuZ2UuY2FsbCh0aGlzKTsKICAgIHR1cm5NZXRob2RzLl91cGRhdGVTaGFkb3cuY2FsbCh0aGlzKTsKICAgIHRoaXMudHJpZ2dlcigndHVybmVkJywgW3BhZ2UsIG5ld1ZpZXddKTsKICAgIHRoaXMudHVybigndXBkYXRlJyk7CgogICAgaWYgKGRhdGEub3B0cy5hdXRvQ2VudGVyKQogICAgICB0aGlzLnR1cm4oJ2NlbnRlcicpOwoKICB9LAogIAogIC8vIFR1cm5zIHRoZSBwYWdlCgogIF90dXJuUGFnZTogZnVuY3Rpb24ocGFnZSkgewoKICAgIHZhciBjdXJyZW50LAogICAgICBuZXh0LAogICAgICBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIHBsYWNlID0gZGF0YS5wYWdlUGxhY2VbcGFnZV0sCiAgICAgIHZpZXcgPSB0aGlzLnR1cm4oJ3ZpZXcnKSwKICAgICAgbmV3VmlldyA9IHRoaXMudHVybigndmlldycsIHBhZ2UpOwoKCiAgICBpZiAoZGF0YS5wYWdlIT1wYWdlKSB7CgogICAgICB2YXIgY3VycmVudFBhZ2UgPSBkYXRhLnBhZ2U7CgogICAgICBpZiAodHJpZ2dlcigndHVybmluZycsIHRoaXMsIFtwYWdlLCBuZXdWaWV3XSk9PSdwcmV2ZW50ZWQnKSB7CgogICAgICAgIGlmIChjdXJyZW50UGFnZT09ZGF0YS5wYWdlICYmICQuaW5BcnJheShwbGFjZSwgZGF0YS5wYWdlTXYpIT0tMSkKICAgICAgICAgIGRhdGEucGFnZXNbcGxhY2VdLmZsaXAoJ2hpZGVGb2xkZWRQYWdlJywgdHJ1ZSk7CiAgICAgICAgCiAgICAgICAgcmV0dXJuOwoKICAgICAgfQoKICAgICAgaWYgKCQuaW5BcnJheSgxLCBuZXdWaWV3KSE9LTEpCiAgICAgICAgdGhpcy50cmlnZ2VyKCdmaXJzdCcpOwogICAgICBpZiAoJC5pbkFycmF5KGRhdGEudG90YWxQYWdlcywgbmV3VmlldykhPS0xKQogICAgICAgIHRoaXMudHJpZ2dlcignbGFzdCcpOwoKICAgIH0KCiAgICBpZiAoZGF0YS5kaXNwbGF5PT0nc2luZ2xlJykgewogICAgICBjdXJyZW50ID0gdmlld1swXTsKICAgICAgbmV4dCA9IG5ld1ZpZXdbMF07CiAgICB9IGVsc2UgaWYgKHZpZXdbMV0gJiYgcGFnZT52aWV3WzFdKSB7CiAgICAgIGN1cnJlbnQgPSB2aWV3WzFdOwogICAgICBuZXh0ID0gbmV3Vmlld1swXTsKICAgIH0gZWxzZSBpZiAodmlld1swXSAmJiBwYWdlPHZpZXdbMF0pIHsKICAgICAgY3VycmVudCA9IHZpZXdbMF07CiAgICAgIG5leHQgPSBuZXdWaWV3WzFdOwogICAgfQoKICAgIHZhciBvcHRzQ29ybmVycyA9IGRhdGEub3B0cy50dXJuQ29ybmVycy5zcGxpdCgnLCcpLAogICAgICBmbGlwRGF0YSA9IGRhdGEucGFnZXNbY3VycmVudF0uZGF0YSgpLmYsCiAgICAgIG9wdHMgPSBmbGlwRGF0YS5vcHRzLAogICAgICBhY3R1YWxQb2ludCA9IGZsaXBEYXRhLnBvaW50OwoKICAgIHR1cm5NZXRob2RzLl9taXNzaW5nLmNhbGwodGhpcywgcGFnZSk7CiAgICAKICAgIGlmICghZGF0YS5wYWdlT2Jqc1twYWdlXSkKICAgICAgcmV0dXJuOwoKICAgIHRoaXMudHVybignc3RvcCcpOwoKICAgIGRhdGEucGFnZSA9IHBhZ2U7CgogICAgdHVybk1ldGhvZHMuX21ha2VSYW5nZS5jYWxsKHRoaXMpOwoKICAgIGRhdGEudHBhZ2UgPSBuZXh0OwoKICAgIGlmIChvcHRzLm5leHQhPW5leHQpIHsKICAgICAgb3B0cy5uZXh0ID0gbmV4dDsKICAgICAgb3B0cy5mb3JjZSA9IHRydWU7CiAgICB9CgogICAgdGhpcy50dXJuKCd1cGRhdGUnKTsKCiAgICBmbGlwRGF0YS5wb2ludCA9IGFjdHVhbFBvaW50OwogICAgCiAgICBpZiAoZmxpcERhdGEuZWZmZWN0PT0naGFyZCcpCiAgICAgIGlmIChkYXRhLmRpcmVjdGlvbj09J2x0cicpCiAgICAgICAgZGF0YS5wYWdlc1tjdXJyZW50XS5mbGlwKCd0dXJuUGFnZScsCiAgICAgICAgICAocGFnZT5jdXJyZW50KSA/ICdyJyA6ICdsJyk7CiAgICAgIGVsc2UKICAgICAgICBkYXRhLnBhZ2VzW2N1cnJlbnRdLmZsaXAoJ3R1cm5QYWdlJywKICAgICAgICAgIChwYWdlPmN1cnJlbnQpID8gJ2wnIDogJ3InKTsKICAgIGVsc2UgewogICAgICBpZiAoZGF0YS5kaXJlY3Rpb249PSdsdHInKQogICAgICAgIGRhdGEucGFnZXNbY3VycmVudF0uZmxpcCgndHVyblBhZ2UnLAogICAgICAgICAgb3B0c0Nvcm5lcnNbKHBhZ2U+Y3VycmVudCkgPyAxIDogMF0pOwogICAgICBlbHNlCiAgICAgICAgZGF0YS5wYWdlc1tjdXJyZW50XS5mbGlwKCd0dXJuUGFnZScsCiAgICAgICAgICBvcHRzQ29ybmVyc1socGFnZT5jdXJyZW50KSA/IDAgOiAxXSk7CiAgICB9CgogIH0sCgogIC8vIEdldHMgYW5kIHNldHMgYSBwYWdlCgogIHBhZ2U6IGZ1bmN0aW9uKHBhZ2UpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmIChwYWdlPT09dW5kZWZpbmVkKSB7CiAgICAgIAogICAgICByZXR1cm4gZGF0YS5wYWdlOwoKICAgIH0gZWxzZSB7CgogICAgICBpZiAoIWRhdGEuZGlzYWJsZWQgJiYgIWRhdGEuZGVzdHJveWluZykgewoKICAgICAgICBwYWdlID0gcGFyc2VJbnQocGFnZSwgMTApOwoKICAgICAgICBpZiAocGFnZT4wICYmIHBhZ2U8PWRhdGEudG90YWxQYWdlcykgewoKICAgICAgICAgIGlmIChwYWdlIT1kYXRhLnBhZ2UpIHsKICAgICAgICAgICAgaWYgKCFkYXRhLmRvbmUgfHwgJC5pbkFycmF5KHBhZ2UsIHRoaXMudHVybigndmlldycpKSE9LTEpCiAgICAgICAgICAgICAgdHVybk1ldGhvZHMuX2ZpdFBhZ2UuY2FsbCh0aGlzLCBwYWdlKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgIHR1cm5NZXRob2RzLl90dXJuUGFnZS5jYWxsKHRoaXMsIHBhZ2UpOwogICAgICAgICAgfQogICAgICAKICAgICAgICAgIHJldHVybiB0aGlzOwoKICAgICAgICB9IGVsc2UgewogICAgICAgIAogICAgICAgICAgdGhyb3cgdHVybkVycm9yKCdUaGUgcGFnZSAnICsgcGFnZSArICcgZG9lcyBub3QgZXhpc3QnKTsKCiAgICAgICAgfQoKICAgICAgfQoKICAgIH0KCiAgfSwKCiAgLy8gVHVybnMgdG8gdGhlIG5leHQgdmlldwoKICBuZXh0OiBmdW5jdGlvbigpIHsKCiAgICByZXR1cm4gdGhpcy50dXJuKCdwYWdlJywgTWF0aC5taW4odGhpcy5kYXRhKCkudG90YWxQYWdlcywKICAgICAgdHVybk1ldGhvZHMuX3ZpZXcuY2FsbCh0aGlzLCB0aGlzLmRhdGEoKS5wYWdlKS5wb3AoKSArIDEpKTsKICAKICB9LAoKICAvLyBUdXJucyB0byB0aGUgcHJldmlvdXMgdmlldwoKICBwcmV2aW91czogZnVuY3Rpb24oKSB7CgogICAgcmV0dXJuIHRoaXMudHVybigncGFnZScsIE1hdGgubWF4KDEsCiAgICAgIHR1cm5NZXRob2RzLl92aWV3LmNhbGwodGhpcywgdGhpcy5kYXRhKCkucGFnZSkuc2hpZnQoKSAtIDEpKTsKCiAgfSwKCiAgLy8gU2hvd3MgYSBwZWVsaW5nIGNvcm5lcgoKICBwZWVsOiBmdW5jdGlvbihjb3JuZXIsIGFuaW1hdGUpIHsKICAgIAogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgdmlldyA9IHRoaXMudHVybigndmlldycpOwoKICAgIGFuaW1hdGUgPSAoYW5pbWF0ZT09PXVuZGVmaW5lZCkgPyB0cnVlIDogYW5pbWF0ZT09PXRydWU7CgogICAgaWYgKGNvcm5lcj09PWZhbHNlKSB7CiAgICAgIAogICAgICB0aGlzLnR1cm4oJ3N0b3AnLCBudWxsLCBhbmltYXRlKTsKCiAgICB9IGVsc2UgewogICAgCiAgICAgIGlmIChkYXRhLmRpc3BsYXk9PSdzaW5nbGUnKSB7CgogICAgICAgIGRhdGEucGFnZXNbZGF0YS5wYWdlXS5mbGlwKCdwZWVsJywgY29ybmVyLCBhbmltYXRlKTsKCiAgICAgIH0gZWxzZSB7CgogICAgICAgIHZhciBwYWdlOwoKICAgICAgICBpZiAoZGF0YS5kaXJlY3Rpb249PSdsdHInKSB7CiAgICAgICAgICAKICAgICAgICAgIHBhZ2UgPSAoY29ybmVyLmluZGV4T2YoJ2wnKSE9LTEpID8gdmlld1swXSA6IHZpZXdbMV07CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAKICAgICAgICAgIHBhZ2UgPSAoY29ybmVyLmluZGV4T2YoJ2wnKSE9LTEpID8gdmlld1sxXSA6IHZpZXdbMF07CgogICAgICAgIH0KICAgICAgICAKICAgICAgICBpZiAoZGF0YS5wYWdlc1twYWdlXSkKICAgICAgICAgIGRhdGEucGFnZXNbcGFnZV0uZmxpcCgncGVlbCcsIGNvcm5lciwgYW5pbWF0ZSk7CgogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHRoaXM7CgogIH0sCgogIC8vIEFkZHMgYSBtb3Rpb24gdG8gdGhlIGludGVybmFsIGxpc3QKICAvLyBUaGlzIGV2ZW50IGlzIGNhbGxlZCBpbiBjb250ZXh0IG9mIGZsaXAKCiAgX2FkZE1vdGlvblBhZ2U6IGZ1bmN0aW9uKCkgewoKICAgIHZhciBvcHRzID0gJCh0aGlzKS5kYXRhKCkuZi5vcHRzLAogICAgICB0dXJuID0gb3B0cy50dXJuLAogICAgICBkZCA9IHR1cm4uZGF0YSgpOwoKICAgIHR1cm5NZXRob2RzLl9hZGRNdi5jYWxsKHR1cm4sIG9wdHMucGFnZSk7CgogIH0sCgogIC8vIFRoaXMgZXZlbnQgaXMgY2FsbGVkIGluIGNvbnRleHQgb2YgZmxpcAoKICBfZXZlbnRTdGFydDogZnVuY3Rpb24oZSwgb3B0cywgY29ybmVyKSB7CgogICAgdmFyIGRhdGEgPSBvcHRzLnR1cm4uZGF0YSgpLAogICAgICBhY3R1YWxab29tID0gZGF0YS5wYWdlWm9vbVtvcHRzLnBhZ2VdOwoKICAgIGlmIChlLmlzRGVmYXVsdFByZXZlbnRlZCgpKSB7CiAgICAgIHR1cm5NZXRob2RzLl91cGRhdGVTaGFkb3cuY2FsbChvcHRzLnR1cm4pOwogICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKGFjdHVhbFpvb20gJiYgYWN0dWFsWm9vbSE9ZGF0YS56b29tKSB7CiAgICAgIAogICAgICBvcHRzLnR1cm4udHJpZ2dlcignem9vbWVkJyxbCiAgICAgICAgb3B0cy5wYWdlLAogICAgICAgIG9wdHMudHVybi50dXJuKCd2aWV3Jywgb3B0cy5wYWdlKSwKICAgICAgICBhY3R1YWxab29tLAogICAgICAgIGRhdGEuem9vbV0pOwoKICAgICAgZGF0YS5wYWdlWm9vbVtvcHRzLnBhZ2VdID0gZGF0YS56b29tOwoKICAgIH0KCiAgICBpZiAoZGF0YS5kaXNwbGF5PT0nc2luZ2xlJyAmJiBjb3JuZXIpIHsKCiAgICAgIGlmICgoY29ybmVyLmNoYXJBdCgxKT09J2wnICYmIGRhdGEuZGlyZWN0aW9uPT0nbHRyJykgfHwKICAgICAgICAoY29ybmVyLmNoYXJBdCgxKT09J3InICYmIGRhdGEuZGlyZWN0aW9uPT0ncnRsJykpCiAgICAgIHsKICAgICAgICAKICAgICAgICBvcHRzLm5leHQgPSAob3B0cy5uZXh0PG9wdHMucGFnZSkgPyBvcHRzLm5leHQgOiBvcHRzLnBhZ2UtMTsKICAgICAgICBvcHRzLmZvcmNlID0gdHJ1ZTsKCiAgICAgIH0gZWxzZSB7CiAgICAgICAgCiAgICAgICAgb3B0cy5uZXh0ID0gKG9wdHMubmV4dD5vcHRzLnBhZ2UpID8gb3B0cy5uZXh0IDogb3B0cy5wYWdlKzE7CgogICAgICB9CgogICAgfQoKICAgIHR1cm5NZXRob2RzLl9hZGRNb3Rpb25QYWdlLmNhbGwoZS50YXJnZXQpOwogICAgdHVybk1ldGhvZHMuX3VwZGF0ZVNoYWRvdy5jYWxsKG9wdHMudHVybik7CiAgfSwKCiAgLy8gVGhpcyBldmVudCBpcyBjYWxsZWQgaW4gY29udGV4dCBvZiBmbGlwCgogIF9ldmVudEVuZDogZnVuY3Rpb24oZSwgb3B0cywgdHVybmVkKSB7CiAgCiAgICB2YXIgdGhhdCA9ICQoZS50YXJnZXQpLAogICAgICBkYXRhID0gdGhhdC5kYXRhKCkuZiwKICAgICAgdHVybiA9IG9wdHMudHVybiwKICAgICAgZGQgPSB0dXJuLmRhdGEoKTsKCiAgICBpZiAodHVybmVkKSB7CgogICAgICB2YXIgdHBhZ2UgPSBkZC50cGFnZSB8fCBkZC5wYWdlOwogICAgCiAgICAgIGlmICh0cGFnZT09b3B0cy5uZXh0IHx8IHRwYWdlPT1vcHRzLnBhZ2UpIHsKICAgICAgICBkZWxldGUgZGQudHBhZ2U7CgogICAgICAgIHR1cm5NZXRob2RzLl9maXRQYWdlLmNhbGwodHVybiwgdHBhZ2UgfHwgb3B0cy5uZXh0LCB0cnVlKTsKICAgICAgfQoKICAgIH0gZWxzZSB7CiAgICAgIAogICAgICB0dXJuTWV0aG9kcy5fcmVtb3ZlTXYuY2FsbCh0dXJuLCBvcHRzLnBhZ2UpOwogICAgICB0dXJuTWV0aG9kcy5fdXBkYXRlU2hhZG93LmNhbGwodHVybik7CiAgICAgIHR1cm4udHVybigndXBkYXRlJyk7CgogICAgfQogICAgCiAgfSwKICAKICAvLyBUaGlzIGV2ZW50IGlzIGNhbGxlZCBpbiBjb250ZXh0IG9mIGZsaXAKCiAgX2V2ZW50UHJlc3NlZDogZnVuY3Rpb24oZSkgewoKICAgIHZhciBwYWdlLAogICAgICBkYXRhID0gJChlLnRhcmdldCkuZGF0YSgpLmYsCiAgICAgIHR1cm4gPSBkYXRhLm9wdHMudHVybiwKICAgICAgdHVybkRhdGEgPSB0dXJuLmRhdGEoKSwKICAgICAgcGFnZXMgPSB0dXJuRGF0YS5wYWdlczsKICAgIAogICAgdHVybkRhdGEubW91c2VBY3Rpb24gPSB0cnVlOwoKICAgIHR1cm4udHVybigndXBkYXRlJyk7CgogICAgcmV0dXJuIGRhdGEudGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpOwoKICB9LAoKICAvLyBUaGlzIGV2ZW50IGlzIGNhbGxlZCBpbiBjb250ZXh0IG9mIGZsaXAKCiAgX2V2ZW50UmVsZWFzZWQ6IGZ1bmN0aW9uKGUsIHBvaW50KSB7CgogICAgdmFyIG91dEFyZWEsCiAgICAgIHBhZ2UgPSAkKGUudGFyZ2V0KSwKICAgICAgZGF0YSA9IHBhZ2UuZGF0YSgpLmYsCiAgICAgIHR1cm4gPSBkYXRhLm9wdHMudHVybiwKICAgICAgdHVybkRhdGEgPSB0dXJuLmRhdGEoKTsKICAgIAogICAgaWYgKHR1cm5EYXRhLmRpc3BsYXk9PSdzaW5nbGUnKSB7CiAgICAgIG91dEFyZWEgPSAocG9pbnQuY29ybmVyPT0nYnInIHx8IHBvaW50LmNvcm5lcj09J3RyJykgPwogICAgICAgIHBvaW50Lng8cGFnZS53aWR0aCgpLzI6CiAgICAgICAgcG9pbnQueD5wYWdlLndpZHRoKCkvMjsKICAgIH0gZWxzZSB7CiAgICAgIG91dEFyZWEgPSBwb2ludC54PDAgfHwgcG9pbnQueD5wYWdlLndpZHRoKCk7CiAgICB9CgogICAgaWYgKChuZXcgRGF0ZSgpKS5nZXRUaW1lKCktZGF0YS50aW1lPDIwMCB8fCBvdXRBcmVhKSB7CgogICAgICBlLnByZXZlbnREZWZhdWx0KCk7CiAgICAgIHR1cm5NZXRob2RzLl90dXJuUGFnZS5jYWxsKHR1cm4sIGRhdGEub3B0cy5uZXh0KTsKCiAgICB9CgogICAgdHVybkRhdGEubW91c2VBY3Rpb24gPSBmYWxzZTsKCiAgfSwKCiAgLy8gVGhpcyBldmVudCBpcyBjYWxsZWQgaW4gY29udGV4dCBvZiBmbGlwCiAgCiAgX2ZsaXA6IGZ1bmN0aW9uKGUpIHsKCiAgICBlLnN0b3BQcm9wYWdhdGlvbigpOwoKICAgIHZhciBvcHRzID0gJChlLnRhcmdldCkuZGF0YSgpLmYub3B0czsKCiAgICBvcHRzLnR1cm4udHJpZ2dlcigndHVybicsIFtvcHRzLm5leHRdKTsKCiAgICBpZiAob3B0cy50dXJuLmRhdGEoKS5vcHRzLmF1dG9DZW50ZXIpIHsKICAgICAgb3B0cy50dXJuLnR1cm4oJ2NlbnRlcicsIG9wdHMubmV4dCk7CiAgICB9CgogIH0sCgogLy8KICBfdG91Y2hTdGFydDogZnVuY3Rpb24oKSB7CiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwogICAgZm9yICh2YXIgcGFnZSBpbiBkYXRhLnBhZ2VzKSB7CiAgICAgIGlmIChoYXMocGFnZSwgZGF0YS5wYWdlcykgJiYKICAgICAgICBmbGlwTWV0aG9kcy5fZXZlbnRTdGFydC5hcHBseShkYXRhLnBhZ2VzW3BhZ2VdLCBhcmd1bWVudHMpPT09ZmFsc2UpIHsKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgfQogICAgfQogIH0sCiAgCiAgLy8KICBfdG91Y2hNb3ZlOiBmdW5jdGlvbigpIHsKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CiAgICBmb3IgKHZhciBwYWdlIGluIGRhdGEucGFnZXMpIHsKICAgICAgaWYgKGhhcyhwYWdlLCBkYXRhLnBhZ2VzKSkgewogICAgICAgIGZsaXBNZXRob2RzLl9ldmVudE1vdmUuYXBwbHkoZGF0YS5wYWdlc1twYWdlXSwgYXJndW1lbnRzKTsKICAgICAgfQogICAgfQogIH0sCgogIC8vCiAgX3RvdWNoRW5kOiBmdW5jdGlvbigpIHsKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CiAgICBmb3IgKHZhciBwYWdlIGluIGRhdGEucGFnZXMpIHsKICAgICAgaWYgKGhhcyhwYWdlLCBkYXRhLnBhZ2VzKSkgewogICAgICAgIGZsaXBNZXRob2RzLl9ldmVudEVuZC5hcHBseShkYXRhLnBhZ2VzW3BhZ2VdLCBhcmd1bWVudHMpOwogICAgICB9CiAgICB9CiAgfSwKCiAgLy8gQ2FsY3VsYXRlIHRoZSB6LWluZGV4IHZhbHVlIGZvciBwYWdlcyBkdXJpbmcgdGhlIGFuaW1hdGlvbgoKICBjYWxjdWxhdGVaOiBmdW5jdGlvbihtdikgewoKICAgIHZhciBpLCBwYWdlLCBuZXh0UGFnZSwgcGxhY2VQYWdlLCBkcGFnZSwKICAgICAgdGhhdCA9IHRoaXMsCiAgICAgIGRhdGEgPSB0aGlzLmRhdGEoKSwKICAgICAgdmlldyA9IHRoaXMudHVybigndmlldycpLAogICAgICBjdXJyZW50UGFnZSA9IHZpZXdbMF0gfHwgdmlld1sxXSwKICAgICAgdG90YWwgPSBtdi5sZW5ndGgtMSwKICAgICAgciA9IHtwYWdlWjoge30sIHBhcnRaOiB7fSwgcGFnZVY6IHt9fSwKCiAgICAgIGFkZFZpZXcgPSBmdW5jdGlvbihwYWdlKSB7CiAgICAgICAgdmFyIHZpZXcgPSB0aGF0LnR1cm4oJ3ZpZXcnLCBwYWdlKTsKICAgICAgICBpZiAodmlld1swXSkgci5wYWdlVlt2aWV3WzBdXSA9IHRydWU7CiAgICAgICAgaWYgKHZpZXdbMV0pIHIucGFnZVZbdmlld1sxXV0gPSB0cnVlOwogICAgICB9OwogICAgCiAgICBmb3IgKGkgPSAwOyBpPD10b3RhbDsgaSsrKSB7CiAgICAgIHBhZ2UgPSBtdltpXTsKICAgICAgbmV4dFBhZ2UgPSBkYXRhLnBhZ2VzW3BhZ2VdLmRhdGEoKS5mLm9wdHMubmV4dDsKICAgICAgcGxhY2VQYWdlID0gZGF0YS5wYWdlUGxhY2VbcGFnZV07CiAgICAgIGFkZFZpZXcocGFnZSk7CiAgICAgIGFkZFZpZXcobmV4dFBhZ2UpOwogICAgICBkcGFnZSA9IChkYXRhLnBhZ2VQbGFjZVtuZXh0UGFnZV09PW5leHRQYWdlKSA/IG5leHRQYWdlIDogcGFnZTsKICAgICAgci5wYWdlWltkcGFnZV0gPSBkYXRhLnRvdGFsUGFnZXMgLSBNYXRoLmFicyhjdXJyZW50UGFnZS1kcGFnZSk7CiAgICAgIHIucGFydFpbcGxhY2VQYWdlXSA9IGRhdGEudG90YWxQYWdlcyoyIC0gIHRvdGFsICsgaTsKICAgIH0KCiAgICByZXR1cm4gcjsKICB9LAoKICAvLyBVcGRhdGVzIHRoZSB6LWluZGV4IGFuZCBkaXNwbGF5IHByb3BlcnR5IG9mIGV2ZXJ5IHBhZ2UKCiAgdXBkYXRlOiBmdW5jdGlvbigpIHsKCiAgICB2YXIgcGFnZSwKICAgICAgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGlmICh0aGlzLnR1cm4oJ2FuaW1hdGluZycpICYmIGRhdGEucGFnZU12WzBdIT09MCkgewoKICAgICAgLy8gVXBkYXRlIG1vdGlvbgoKICAgICAgdmFyIHAsIGFwYWdlLCBmaXhlZCwKICAgICAgICBwb3MgPSB0aGlzLnR1cm4oJ2NhbGN1bGF0ZVonLCBkYXRhLnBhZ2VNdiksCiAgICAgICAgY29ybmVyID0gdGhpcy50dXJuKCdjb3JuZXInKSwKICAgICAgICBhY3R1YWxWaWV3ID0gdGhpcy50dXJuKCd2aWV3JyksCiAgICAgICAgbmV3VmlldyA9IHRoaXMudHVybigndmlldycsIGRhdGEudHBhZ2UpOwogIAogICAgICBmb3IgKHBhZ2UgaW4gZGF0YS5wYWdlV3JhcCkgewoKICAgICAgICBpZiAoIWhhcyhwYWdlLCBkYXRhLnBhZ2VXcmFwKSkKICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICBmaXhlZCA9IGRhdGEucGFnZU9ianNbcGFnZV0uaGFzQ2xhc3MoJ2ZpeGVkJyk7CgogICAgICAgIGRhdGEucGFnZVdyYXBbcGFnZV0uY3NzKHsKICAgICAgICAgIGRpc3BsYXk6IChwb3MucGFnZVZbcGFnZV0gfHwgZml4ZWQpID8gJycgOiAnbm9uZScsCiAgICAgICAgICB6SW5kZXg6CiAgICAgICAgICAgIChkYXRhLnBhZ2VPYmpzW3BhZ2VdLmhhc0NsYXNzKCdoYXJkJykgPwogICAgICAgICAgICAgIHBvcy5wYXJ0WltwYWdlXQogICAgICAgICAgICAgIDoKICAgICAgICAgICAgICBwb3MucGFnZVpbcGFnZV0KICAgICAgICAgICAgKSB8fCAoZml4ZWQgPyAtMSA6IDApCiAgICAgICAgfSk7CgogICAgICAgIGlmICgocCA9IGRhdGEucGFnZXNbcGFnZV0pKSB7CgogICAgICAgICAgcC5mbGlwKCd6JywgcG9zLnBhcnRaW3BhZ2VdIHx8IG51bGwpOwoKICAgICAgICAgIGlmIChwb3MucGFnZVZbcGFnZV0pCiAgICAgICAgICAgIHAuZmxpcCgncmVzaXplJyk7CiAgICAgICAgICAKICAgICAgICAgIGlmIChkYXRhLnRwYWdlKSB7IC8vIElzIGl0IHR1cm5pbmcgdGhlIHBhZ2UgdG8gYHRwYWdlYD8KCiAgICAgICAgICAgIHAuZmxpcCgnaG92ZXInLCBmYWxzZSkuCiAgICAgICAgICAgICAgZmxpcCgnZGlzYWJsZScsCiAgICAgICAgICAgICAgICAkLmluQXJyYXkocGFyc2VJbnQocGFnZSwgMTApLCBkYXRhLnBhZ2VNdik9PS0xICYmCiAgICAgICAgICAgICAgICBwYWdlIT1uZXdWaWV3WzBdICYmCiAgICAgICAgICAgICAgICBwYWdlIT1uZXdWaWV3WzFdKTsKCiAgICAgICAgICB9IGVsc2UgewoKICAgICAgICAgICAgcC5mbGlwKCdob3ZlcicsIGNvcm5lcj09PWZhbHNlKS4KICAgICAgICAgICAgICBmbGlwKCdkaXNhYmxlJywgcGFnZSE9YWN0dWFsVmlld1swXSAmJiBwYWdlIT1hY3R1YWxWaWV3WzFdKTsKCiAgICAgICAgICB9CgogICAgICAgIH0KCiAgICAgIH0KCiAgICB9IGVsc2UgewoKICAgICAgLy8gVXBkYXRlIHN0YXRpYyBwYWdlcwoKICAgICAgZm9yIChwYWdlIGluIGRhdGEucGFnZVdyYXApIHsKCiAgICAgICAgaWYgKCFoYXMocGFnZSwgZGF0YS5wYWdlV3JhcCkpCiAgICAgICAgICBjb250aW51ZTsKCiAgICAgICAgdmFyIHBhZ2VMb2NhdGlvbiA9IHR1cm5NZXRob2RzLl9zZXRQYWdlTG9jLmNhbGwodGhpcywgcGFnZSk7CgogICAgICAgIGlmIChkYXRhLnBhZ2VzW3BhZ2VdKSB7CiAgICAgICAgICBkYXRhLnBhZ2VzW3BhZ2VdLgogICAgICAgICAgICBmbGlwKCdkaXNhYmxlJywgZGF0YS5kaXNhYmxlZCB8fCBwYWdlTG9jYXRpb24hPTEpLgogICAgICAgICAgICBmbGlwKCdob3ZlcicsIHRydWUpLgogICAgICAgICAgICBmbGlwKCd6JywgbnVsbCk7CiAgICAgICAgfQogICAgICB9CiAgICB9CgogICAgcmV0dXJuIHRoaXM7CiAgfSwKCiAgLy8gVXBkYXRlcyB0aGUgcG9zaXRpb24gYW5kIHNpemUgb2YgdGhlIGZsaXBib29rJ3Mgc2hhZG93CgogIF91cGRhdGVTaGFkb3c6IGZ1bmN0aW9uKCkgewogICAgCiAgICB2YXIgdmlldywgdmlldzIsIHNoYWRvdywKICAgICAgZGF0YSA9IHRoaXMuZGF0YSgpLAogICAgICB3aWR0aCA9IHRoaXMud2lkdGgoKSwKICAgICAgaGVpZ2h0ID0gdGhpcy5oZWlnaHQoKSwKICAgICAgcGFnZVdpZHRoID0gKGRhdGEuZGlzcGxheT09J3NpbmdsZScpID8gd2lkdGggOiB3aWR0aC8yOwoKICAgIHZpZXcgPSB0aGlzLnR1cm4oJ3ZpZXcnKTsKCiAgICBpZiAoIWRhdGEuc2hhZG93KSB7CiAgICAgIGRhdGEuc2hhZG93ID0gJCgnPGRpdiAvPicsIHsKICAgICAgICAgICdjbGFzcyc6ICdzaGFkb3cnLAogICAgICAgICAgJ2Nzcyc6IGRpdkF0dCgwLCAwLCAwKS5jc3MKICAgICAgICB9KS4KICAgICAgICBhcHBlbmRUbyh0aGlzKTsKICAgIH0KCiAgICBmb3IgKHZhciBpID0gMDsgaTxkYXRhLnBhZ2VNdi5sZW5ndGg7IGkrKykgewogICAgICBpZiAoIXZpZXdbMF0gfHwgIXZpZXdbMV0pCiAgICAgICAgYnJlYWs7CiAgICAKICAgICAgdmlldyA9IHRoaXMudHVybigndmlldycsIGRhdGEucGFnZXNbZGF0YS5wYWdlTXZbaV1dLmRhdGEoKS5mLm9wdHMubmV4dCk7CiAgICAgIHZpZXcyID0gdGhpcy50dXJuKCd2aWV3JywgZGF0YS5wYWdlTXZbaV0pOwoKICAgICAgdmlld1swXSA9IHZpZXdbMF0gJiYgdmlldzJbMF07CiAgICAgIHZpZXdbMV0gPSB2aWV3WzFdICYmIHZpZXcyWzFdOwogICAgfQoKICAgIGlmICghdmlld1swXSkgc2hhZG93ID0gKGRhdGEuZGlyZWN0aW9uPT0nbHRyJykgPyAxIDogMjsKICAgIGVsc2UgaWYgKCF2aWV3WzFdKSBzaGFkb3cgPSAoZGF0YS5kaXJlY3Rpb249PSdsdHInKSA/IDIgOiAxOwogICAgZWxzZSBzaGFkb3cgPSAzOwoKICAgIHN3aXRjaCAoc2hhZG93KSB7CiAgICAgIGNhc2UgMToKICAgICAgICBkYXRhLnNoYWRvdy5jc3MoewogICAgICAgICAgd2lkdGg6IHBhZ2VXaWR0aCwKICAgICAgICAgIGhlaWdodDogaGVpZ2h0LAogICAgICAgICAgdG9wOiAwLAogICAgICAgICAgbGVmdDogcGFnZVdpZHRoCiAgICAgICAgfSk7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMjoKICAgICAgICBkYXRhLnNoYWRvdy5jc3MoewogICAgICAgICAgd2lkdGg6IHBhZ2VXaWR0aCwKICAgICAgICAgIGhlaWdodDogaGVpZ2h0LAogICAgICAgICAgdG9wOiAwLAogICAgICAgICAgbGVmdDogMAogICAgICAgIH0pOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDM6CiAgICAgICAgZGF0YS5zaGFkb3cuY3NzKHsKICAgICAgICAgIHdpZHRoOiB3aWR0aCwKICAgICAgICAgIGhlaWdodDogaGVpZ2h0LAogICAgICAgICAgdG9wOiAwLAogICAgICAgICAgbGVmdDogMAogICAgICAgIH0pOwogICAgICAgIGJyZWFrOwogICAgfQoKICB9LAoKICAvLyBTZXRzIHRoZSB6LWluZGV4IGFuZCBkaXNwbGF5IHByb3BlcnR5IG9mIGEgcGFnZQogIC8vIEl0IGRlcGVuZHMgb24gdGhlIGN1cnJlbnQgdmlldwoKICBfc2V0UGFnZUxvYzogZnVuY3Rpb24ocGFnZSkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCksCiAgICAgIHZpZXcgPSB0aGlzLnR1cm4oJ3ZpZXcnKSwKICAgICAgbG9jID0gMDsKCiAgICAKICAgIGlmIChwYWdlPT12aWV3WzBdIHx8IHBhZ2U9PXZpZXdbMV0pCiAgICAgIGxvYyA9IDE7CiAgICBlbHNlIGlmICgKICAgICAgKGRhdGEuZGlzcGxheT09J3NpbmdsZScgJiYgcGFnZT09dmlld1swXSsxKSB8fAogICAgICAoZGF0YS5kaXNwbGF5PT0nZG91YmxlJyAmJiBwYWdlPT12aWV3WzBdLTIgfHwgcGFnZT09dmlld1sxXSsyKQogICAgKQogICAgICBsb2MgPSAyOwoKICAgIGlmICghdGhpcy50dXJuKCdhbmltYXRpbmcnKSkKICAgICAgc3dpdGNoIChsb2MpIHsKICAgICAgICBjYXNlIDE6CiAgICAgICAgICBkYXRhLnBhZ2VXcmFwW3BhZ2VdLmNzcygKICAgICAgICAgIHsKICAgICAgICAgICAgekluZGV4OiBkYXRhLnRvdGFsUGFnZXMsCiAgICAgICAgICAgIGRpc3BsYXk6ICcnCiAgICAgICAgICB9KTsKICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDI6CiAgICAgICAgICBkYXRhLnBhZ2VXcmFwW3BhZ2VdLmNzcygKICAgICAgICAgIHsKICAgICAgICAgICAgekluZGV4OiBkYXRhLnRvdGFsUGFnZXMtMSwKICAgICAgICAgICAgZGlzcGxheTogJycKICAgICAgICAgIH0pOwogICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMDoKICAgICAgICAgIGRhdGEucGFnZVdyYXBbcGFnZV0uY3NzKAogICAgICAgICAgewogICAgICAgICAgICB6SW5kZXg6IDAsCiAgICAgICAgICAgIGRpc3BsYXk6IChkYXRhLnBhZ2VPYmpzW3BhZ2VdLmhhc0NsYXNzKCdmaXhlZCcpKSA/ICcnIDogJ25vbmUnfQogICAgICAgICAgKTsKICAgICAgICBicmVhazsKICAgICAgfQogICAgCiAgICByZXR1cm4gbG9jOwogIH0sCgogIC8vIEdldHMgYW5kIHNldHMgdGhlIG9wdGlvbnMKCiAgb3B0aW9uczogZnVuY3Rpb24ob3B0aW9ucykgewogICAgCiAgICBpZiAob3B0aW9ucz09PXVuZGVmaW5lZCkgewogICAgICAKICAgICAgcmV0dXJuIHRoaXMuZGF0YSgpLm9wdHM7CgogICAgfSBlbHNlIHsKCiAgICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCk7CgogICAgICAvLyBTZXQgbmV3IHZhbHVlcwoKICAgICAgJC5leHRlbmQoZGF0YS5vcHRzLCBvcHRpb25zKTsKICAgICAgCiAgICAgIC8vIFNldCBwYWdlcwoKICAgICAgaWYgKG9wdGlvbnMucGFnZXMpCiAgICAgICAgdGhpcy50dXJuKCdwYWdlcycsIG9wdGlvbnMucGFnZXMpOwoKICAgICAgLy8gU2V0IHBhZ2UKCiAgICAgIGlmIChvcHRpb25zLnBhZ2UpCiAgICAgICAgdGhpcy50dXJuKCdwYWdlJywgb3B0aW9ucy5wYWdlKTsKCiAgICAgIC8vIFNldCBkaXNwbGF5CgogICAgICBpZiAob3B0aW9ucy5kaXNwbGF5KQogICAgICAgIHRoaXMudHVybignZGlzcGxheScsIG9wdGlvbnMuZGlzcGxheSk7CiAgICAgIAogICAgICAvLyBTZXQgZGlyZWN0aW9uCgogICAgICBpZiAob3B0aW9ucy5kaXJlY3Rpb24pCiAgICAgICAgdGhpcy50dXJuKCdkaXJlY3Rpb24nLCBvcHRpb25zLmRpcmVjdGlvbik7CgogICAgICAvLyBTZXQgc2l6ZQoKICAgICAgaWYgKG9wdGlvbnMud2lkdGggJiYgb3B0aW9ucy5oZWlnaHQpCiAgICAgICAgdGhpcy50dXJuKCdzaXplJywgb3B0aW9ucy53aWR0aCwgb3B0aW9ucy5oZWlnaHQpOwogICAgICAKICAgICAgLy8gQWRkIGV2ZW50IGxpc3RlbmVycwoKICAgICAgaWYgKG9wdGlvbnMud2hlbikKICAgICAgICBmb3IgKHZhciBldmVudE5hbWUgaW4gb3B0aW9ucy53aGVuKQogICAgICAgICAgaWYgKGhhcyhldmVudE5hbWUsIG9wdGlvbnMud2hlbikpIHsKICAgICAgICAgICAgdGhpcy51bmJpbmQoZXZlbnROYW1lKS4KICAgICAgICAgICAgICBiaW5kKGV2ZW50TmFtZSwgb3B0aW9ucy53aGVuW2V2ZW50TmFtZV0pOwogICAgICAgICAgfQoKICAgICAgcmV0dXJuIHRoaXM7CiAgICB9CgogIH0sCgogIC8vIEdldHMgdGhlIGN1cnJlbnQgdmVyc2lvbgoKICB2ZXJzaW9uOiBmdW5jdGlvbigpIHsKCiAgICByZXR1cm4gdmVyc2lvbjsKCiAgfQp9LAoKLy8gTWV0aG9kcyBhbmQgcHJvcGVydGllcyBmb3IgdGhlIGZsaXAgcGFnZSBlZmZlY3QKCmZsaXBNZXRob2RzID0gewoKICAvLyBDb25zdHJ1Y3RvcgoKICBpbml0OiBmdW5jdGlvbihvcHRzKSB7CgogICAgdGhpcy5kYXRhKHtmOiB7CiAgICAgIGRpc2FibGVkOiBmYWxzZSwKICAgICAgaG92ZXI6IGZhbHNlLAogICAgICBlZmZlY3Q6ICh0aGlzLmhhc0NsYXNzKCdoYXJkJykpID8gJ2hhcmQnIDogJ3NoZWV0JwogICAgfX0pOwogIAogICAgdGhpcy5mbGlwKCdvcHRpb25zJywgb3B0cyk7CgogICAgZmxpcE1ldGhvZHMuX2FkZFBhZ2VXcmFwcGVyLmNhbGwodGhpcyk7CgogICAgcmV0dXJuIHRoaXM7CiAgfSwKCiAgc2V0RGF0YTogZnVuY3Rpb24oZCkgewogICAgCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpOwoKICAgIGRhdGEuZiA9ICQuZXh0ZW5kKGRhdGEuZiwgZCk7CgogICAgcmV0dXJuIHRoaXM7CiAgfSwKCiAgb3B0aW9uczogZnVuY3Rpb24ob3B0cykgewogICAgCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmY7CgogICAgaWYgKG9wdHMpIHsKICAgICAgZmxpcE1ldGhvZHMuc2V0RGF0YS5jYWxsKHRoaXMsCiAgICAgICAge29wdHM6ICQuZXh0ZW5kKHt9LCBkYXRhLm9wdHMgfHwgZmxpcE9wdGlvbnMsIG9wdHMpfSk7CiAgICAgIHJldHVybiB0aGlzOwogICAgfSBlbHNlCiAgICAgIHJldHVybiBkYXRhLm9wdHM7CgogIH0sCgogIHo6IGZ1bmN0aW9uKHopIHsKICAgIAogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKS5mOwoKICAgIGRhdGEub3B0c1snei1pbmRleCddID0gejsKCiAgICBpZiAoZGF0YS5md3JhcHBlcikKICAgICAgZGF0YS5md3JhcHBlci5jc3MoewogICAgICAgIHpJbmRleDogeiB8fCBwYXJzZUludChkYXRhLnBhcmVudC5jc3MoJ3otaW5kZXgnKSwgMTApIHx8IDAKICAgICAgfSk7CgogICAgcmV0dXJuIHRoaXM7CiAgfSwKCiAgX2NBbGxvd2VkOiBmdW5jdGlvbigpIHsKICAgIAogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKS5mLAogICAgICBwYWdlID0gZGF0YS5vcHRzLnBhZ2UsCiAgICAgIHR1cm5EYXRhID0gZGF0YS5vcHRzLnR1cm4uZGF0YSgpLAogICAgICBvZGQgPSBwYWdlJTI7CiAgICAKICAgIGlmIChkYXRhLmVmZmVjdD09J2hhcmQnKSB7CiAgICAKICAgICAgcmV0dXJuICh0dXJuRGF0YS5kaXJlY3Rpb249PSdsdHInKSA/CiAgICAgICAgWyhvZGQpID8gJ3InIDogJ2wnXSA6CiAgICAgICAgWyhvZGQpID8gJ2wnIDogJ3InXTsKCiAgICB9IGVsc2UgewoKICAgICAgaWYgKHR1cm5EYXRhLmRpc3BsYXk9PSdzaW5nbGUnKSB7CgogICAgICAgIGlmIChwYWdlPT0xKQogICAgICAgICAgcmV0dXJuICh0dXJuRGF0YS5kaXJlY3Rpb249PSdsdHInKSA/CiAgICAgICAgICAgIGNvcm5lcnNbJ2ZvcndhcmQnXSA6IGNvcm5lcnNbJ2JhY2t3YXJkJ107CiAgICAgICAgZWxzZSBpZiAocGFnZT09dHVybkRhdGEudG90YWxQYWdlcykKICAgICAgICAgIHJldHVybiAodHVybkRhdGEuZGlyZWN0aW9uPT0nbHRyJykgPwogICAgICAgICAgICBjb3JuZXJzWydiYWNrd2FyZCddIDogY29ybmVyc1snZm9yd2FyZCddOwogICAgICAgIGVsc2UKICAgICAgICAgIHJldHVybiBjb3JuZXJzWydhbGwnXTsKCiAgICAgIH0gZWxzZSB7CgogICAgICAgIHJldHVybiAodHVybkRhdGEuZGlyZWN0aW9uPT0nbHRyJykgPwogICAgICAgICAgY29ybmVyc1sob2RkKSA/ICdmb3J3YXJkJyA6ICdiYWNrd2FyZCddCiAgICAgICAgICA6CiAgICAgICAgICBjb3JuZXJzWyhvZGQpID8gJ2JhY2t3YXJkJyA6ICdmb3J3YXJkJ107CgogICAgICB9CgogICAgfQoKICB9LAoKICBfY29ybmVyQWN0aXZhdGVkOiBmdW5jdGlvbihwKSB7CgogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKS5mLAogICAgICB3aWR0aCA9IHRoaXMud2lkdGgoKSwKICAgICAgaGVpZ2h0ID0gdGhpcy5oZWlnaHQoKSwKICAgICAgcG9pbnQgPSB7eDogcC54LCB5OiBwLnksIGNvcm5lcjogJyd9LAogICAgICBjc3ogPSBkYXRhLm9wdHMuY29ybmVyU2l6ZTsKCiAgICBpZiAocG9pbnQueDw9MCB8fCBwb2ludC55PD0wIHx8IHBvaW50Lng+PXdpZHRoIHx8IHBvaW50Lnk+PWhlaWdodCkKICAgICAgcmV0dXJuIGZhbHNlOwoKICAgIHZhciBhbGxvd2VkQ29ybmVycyA9IGZsaXBNZXRob2RzLl9jQWxsb3dlZC5jYWxsKHRoaXMpOwoKICAgIHN3aXRjaCAoZGF0YS5lZmZlY3QpIHsKICAgICAgY2FzZSAnaGFyZCc6CiAgICAgICAgCiAgICAgICAgaWYgKHBvaW50Lng+d2lkdGgtY3N6KQogICAgICAgICAgcG9pbnQuY29ybmVyID0gJ3InOwogICAgICAgIGVsc2UgaWYgKHBvaW50Lng8Y3N6KQogICAgICAgICAgcG9pbnQuY29ybmVyID0gJ2wnOwogICAgICAgIGVsc2UKICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgCiAgICAgICAgYnJlYWs7CgogICAgICBjYXNlICdzaGVldCc6CiAgICAgICAgCiAgICAgICAgaWYgKHBvaW50Lnk8Y3N6KQogICAgICAgICAgcG9pbnQuY29ybmVyKz0gJ3QnOwogICAgICAgIGVsc2UgaWYgKHBvaW50Lnk+PWhlaWdodC1jc3opCiAgICAgICAgICBwb2ludC5jb3JuZXIrPSAnYic7CiAgICAgICAgZWxzZQogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgCiAgICAgICAgaWYgKHBvaW50Lng8PWNzeikKICAgICAgICAgIHBvaW50LmNvcm5lcis9ICdsJzsKICAgICAgICBlbHNlIGlmIChwb2ludC54Pj13aWR0aC1jc3opCiAgICAgICAgICBwb2ludC5jb3JuZXIrPSAncic7CiAgICAgICAgZWxzZQogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgIAogICAgICAgIGJyZWFrOwogICAgICB9CgogICAgcmV0dXJuICghcG9pbnQuY29ybmVyIHx8ICQuaW5BcnJheShwb2ludC5jb3JuZXIsIGFsbG93ZWRDb3JuZXJzKT09LTEpID8KICAgICAgZmFsc2UgOiBwb2ludDsKCiAgfSwKCiAgX2lzSUFyZWE6IGZ1bmN0aW9uKGUpIHsKCiAgICB2YXIgcG9zID0gdGhpcy5kYXRhKCkuZi5wYXJlbnQub2Zmc2V0KCk7CgogICAgZSA9IChpc1RvdWNoICYmIGUub3JpZ2luYWxFdmVudCkgPyBlLm9yaWdpbmFsRXZlbnQudG91Y2hlc1swXSA6IGU7CgogICAgcmV0dXJuIGZsaXBNZXRob2RzLl9jb3JuZXJBY3RpdmF0ZWQuY2FsbCh0aGlzLAogICAgICB7CiAgICAgICAgeDogZS5wYWdlWC1wb3MubGVmdCwKICAgICAgICB5OiBlLnBhZ2VZLXBvcy50b3AKICAgICAgfSk7CgogIH0sCgogIF9jOiBmdW5jdGlvbihjb3JuZXIsIG9wdHMpIHsKCiAgICBvcHRzID0gb3B0cyB8fCAwOwoKICAgIHN3aXRjaCAoY29ybmVyKSB7CiAgICAgIGNhc2UgJ3RsJzoKICAgICAgICByZXR1cm4gcG9pbnQyRChvcHRzLCBvcHRzKTsKICAgICAgY2FzZSAndHInOgogICAgICAgIHJldHVybiBwb2ludDJEKHRoaXMud2lkdGgoKS1vcHRzLCBvcHRzKTsKICAgICAgY2FzZSAnYmwnOgogICAgICAgIHJldHVybiBwb2ludDJEKG9wdHMsIHRoaXMuaGVpZ2h0KCktb3B0cyk7CiAgICAgIGNhc2UgJ2JyJzoKICAgICAgICByZXR1cm4gcG9pbnQyRCh0aGlzLndpZHRoKCktb3B0cywgdGhpcy5oZWlnaHQoKS1vcHRzKTsKICAgICAgY2FzZSAnbCc6CiAgICAgICAgcmV0dXJuIHBvaW50MkQob3B0cywgMCk7CiAgICAgIGNhc2UgJ3InOgogICAgICAgIHJldHVybiBwb2ludDJEKHRoaXMud2lkdGgoKS1vcHRzLCAwKTsKICAgIH0KCiAgfSwKCiAgX2MyOiBmdW5jdGlvbihjb3JuZXIpIHsKCiAgICBzd2l0Y2ggKGNvcm5lcikgewogICAgICBjYXNlICd0bCc6CiAgICAgICAgcmV0dXJuIHBvaW50MkQodGhpcy53aWR0aCgpKjIsIDApOwogICAgICBjYXNlICd0cic6CiAgICAgICAgcmV0dXJuIHBvaW50MkQoLXRoaXMud2lkdGgoKSwgMCk7CiAgICAgIGNhc2UgJ2JsJzoKICAgICAgICByZXR1cm4gcG9pbnQyRCh0aGlzLndpZHRoKCkqMiwgdGhpcy5oZWlnaHQoKSk7CiAgICAgIGNhc2UgJ2JyJzoKICAgICAgICByZXR1cm4gcG9pbnQyRCgtdGhpcy53aWR0aCgpLCB0aGlzLmhlaWdodCgpKTsKICAgICAgY2FzZSAnbCc6CiAgICAgICAgcmV0dXJuIHBvaW50MkQodGhpcy53aWR0aCgpKjIsIDApOwogICAgICBjYXNlICdyJzoKICAgICAgICByZXR1cm4gcG9pbnQyRCgtdGhpcy53aWR0aCgpLCAwKTsKICAgIH0KCiAgfSwKCiAgX2ZvbGRpbmdQYWdlOiBmdW5jdGlvbigpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmY7CgogICAgaWYgKCFkYXRhKQogICAgICByZXR1cm47CgogICAgdmFyIG9wdHMgPSBkYXRhLm9wdHM7CgogICAgaWYgKG9wdHMudHVybikgewogICAgICBkYXRhID0gb3B0cy50dXJuLmRhdGEoKTsKICAgICAgaWYgKGRhdGEuZGlzcGxheSA9PSAnc2luZ2xlJykKICAgICAgICByZXR1cm4gKG9wdHMubmV4dD4xIHx8IG9wdHMucGFnZT4xKSA/IGRhdGEucGFnZU9ianNbMF0gOiBudWxsOwogICAgICBlbHNlCiAgICAgICAgcmV0dXJuIGRhdGEucGFnZU9ianNbb3B0cy5uZXh0XTsKICAgIH0KCiAgfSwKCiAgX2JhY2tHcmFkaWVudDogZnVuY3Rpb24oKSB7CgogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKS5mLAogICAgICB0dXJuRGF0YSA9IGRhdGEub3B0cy50dXJuLmRhdGEoKSwKICAgICAgZ3JhZGllbnQgPSAgdHVybkRhdGEub3B0cy5ncmFkaWVudHMgJiYgKHR1cm5EYXRhLmRpc3BsYXk9PSdzaW5nbGUnIHx8CiAgICAgICAgIChkYXRhLm9wdHMucGFnZSE9MiAmJiBkYXRhLm9wdHMucGFnZSE9dHVybkRhdGEudG90YWxQYWdlcy0xKSk7CgogICAgaWYgKGdyYWRpZW50ICYmICFkYXRhLmJzaGFkb3cpCiAgICAgIGRhdGEuYnNoYWRvdyA9ICQoJzxkaXYvPicsIGRpdkF0dCgwLCAwLCAxKSkuCiAgICAgICAgY3NzKHsncG9zaXRpb24nOiAnJywgd2lkdGg6IHRoaXMud2lkdGgoKSwgaGVpZ2h0OiB0aGlzLmhlaWdodCgpfSkuCiAgICAgICAgYXBwZW5kVG8oZGF0YS5wYXJlbnQpOwoKICAgIHJldHVybiBncmFkaWVudDsKCiAgfSwKCiAgdHlwZTogZnVuY3Rpb24gKCkgewogICAgCiAgICByZXR1cm4gdGhpcy5kYXRhKCkuZi5lZmZlY3Q7CgogIH0sCgogIHJlc2l6ZTogZnVuY3Rpb24oZnVsbCkgewogICAgCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmYsCiAgICAgIHR1cm5EYXRhID0gZGF0YS5vcHRzLnR1cm4uZGF0YSgpLAogICAgICB3aWR0aCA9IHRoaXMud2lkdGgoKSwKICAgICAgaGVpZ2h0ID0gdGhpcy5oZWlnaHQoKTsKCiAgICBzd2l0Y2ggKGRhdGEuZWZmZWN0KSB7CiAgICAgIGNhc2UgJ2hhcmQnOgogICAgICAgIAogICAgICBpZiAoZnVsbCkgewogICAgICAgIGRhdGEud3JhcHBlci5jc3Moe3dpZHRoOiB3aWR0aCwgaGVpZ2h0OiBoZWlnaHR9KTsKICAgICAgICBkYXRhLmZwYWdlLmNzcyh7d2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodH0pOwogICAgICAgIGlmICh0dXJuRGF0YS5vcHRzLmdyYWRpZW50cykgewogICAgICAgICAgZGF0YS5hc2hhZG93LmNzcyh7d2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodH0pOwogICAgICAgICAgZGF0YS5ic2hhZG93LmNzcyh7d2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodH0pOwogICAgICAgIH0KICAgICAgfQoKICAgICAgYnJlYWs7CiAgICAgIGNhc2UgJ3NoZWV0JzoKCiAgICAgIGlmIChmdWxsKSB7CiAgICAgICAgdmFyIHNpemUgPSBNYXRoLnJvdW5kKE1hdGguc3FydChNYXRoLnBvdyh3aWR0aCwgMikrTWF0aC5wb3coaGVpZ2h0LCAyKSkpOwoKICAgICAgICBkYXRhLndyYXBwZXIuY3NzKHt3aWR0aDogc2l6ZSwgaGVpZ2h0OiBzaXplfSk7CiAgICAgICAgZGF0YS5md3JhcHBlci5jc3Moe3dpZHRoOiBzaXplLCBoZWlnaHQ6IHNpemV9KS4KICAgICAgICAgIGNoaWxkcmVuKCc6Zmlyc3QtY2hpbGQnKS4KICAgICAgICAgIGNzcyh7d2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodH0pOwoKICAgICAgICBkYXRhLmZwYWdlLmNzcyh7d2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodH0pOwoKICAgICAgICBpZiAodHVybkRhdGEub3B0cy5ncmFkaWVudHMpCiAgICAgICAgICBkYXRhLmFzaGFkb3cuY3NzKHt3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0fSk7CgogICAgICAgIGlmIChmbGlwTWV0aG9kcy5fYmFja0dyYWRpZW50LmNhbGwodGhpcykpCiAgICAgICAgICBkYXRhLmJzaGFkb3cuY3NzKHt3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0fSk7CiAgICAgIH0KCiAgICAgIGlmIChkYXRhLnBhcmVudC5pcygnOnZpc2libGUnKSkgewogICAgICAgIHZhciBvZmZzZXQgPSBmaW5kUG9zKGRhdGEucGFyZW50WzBdKTsKCiAgICAgICAgZGF0YS5md3JhcHBlci5jc3Moe3RvcDogb2Zmc2V0LnRvcCwKICAgICAgICAgIGxlZnQ6IG9mZnNldC5sZWZ0fSk7CgogICAgICAgIC8vaWYgKGRhdGEub3B0cy50dXJuKSB7CiAgICAgICAgIG9mZnNldCA9IGZpbmRQb3MoZGF0YS5vcHRzLnR1cm5bMF0pOwogICAgICAgICBkYXRhLmZwYXJlbnQuY3NzKHt0b3A6IC1vZmZzZXQudG9wLCBsZWZ0OiAtb2Zmc2V0LmxlZnR9KTsKICAgICAgICAvL30KICAgICAgfQoKICAgICAgdGhpcy5mbGlwKCd6JywgZGF0YS5vcHRzWyd6LWluZGV4J10pOwoKICAgICAgYnJlYWs7CiAgICB9CgogIH0sCgogIC8vIFByZXBhcmVzIHRoZSBwYWdlIGJ5IGFkZGluZyBhIGdlbmVyYWwgd3JhcHBlciBhbmQgYW5vdGhlciBvYmplY3RzCgogIF9hZGRQYWdlV3JhcHBlcjogZnVuY3Rpb24oKSB7CgogICAgdmFyIGF0dCwKICAgICAgZGF0YSA9IHRoaXMuZGF0YSgpLmYsCiAgICAgIHR1cm5EYXRhID0gZGF0YS5vcHRzLnR1cm4uZGF0YSgpLAogICAgICBwYXJlbnQgPSB0aGlzLnBhcmVudCgpOwoKICAgIGRhdGEucGFyZW50ID0gcGFyZW50OwoKICBpZiAoIWRhdGEud3JhcHBlcikKICAgIHN3aXRjaCAoZGF0YS5lZmZlY3QpIHsKICAgICAgY2FzZSAnaGFyZCc6CiAgICAgICAgCiAgICAgICAgdmFyIGNzc1Byb3BlcnRpZXMgPSB7fTsKICAgICAgICBjc3NQcm9wZXJ0aWVzW3ZlbmRvciArICd0cmFuc2Zvcm0tc3R5bGUnXSA9ICdwcmVzZXJ2ZS0zZCc7CiAgICAgICAgY3NzUHJvcGVydGllc1t2ZW5kb3IgKyAnYmFja2ZhY2UtdmlzaWJpbGl0eSddID0gJ2hpZGRlbic7CgogICAgICAgIGRhdGEud3JhcHBlciA9ICQoJzxkaXYvPicsIGRpdkF0dCgwLCAwLCAyKSkuCiAgICAgICAgICBjc3MoY3NzUHJvcGVydGllcykuCiAgICAgICAgICBhcHBlbmRUbyhwYXJlbnQpLgogICAgICAgICAgcHJlcGVuZCh0aGlzKTsKCiAgICAgICAgZGF0YS5mcGFnZSA9ICQoJzxkaXYvPicsIGRpdkF0dCgwLCAwLCAxKSkuCiAgICAgICAgICBjc3MoY3NzUHJvcGVydGllcykuCiAgICAgICAgICBhcHBlbmRUbyhwYXJlbnQpOwogICAgICAgIAogICAgICAgIGlmICh0dXJuRGF0YS5vcHRzLmdyYWRpZW50cykgewogICAgICAgICAgZGF0YS5hc2hhZG93ID0gJCgnPGRpdi8+JywgZGl2QXR0KDAsIDAsICAwKSkuCiAgICAgICAgICAgIGhpZGUoKS4KICAgICAgICAgICAgYXBwZW5kVG8ocGFyZW50KTsKCiAgICAgICAgICBkYXRhLmJzaGFkb3cgPSAkKCc8ZGl2Lz4nLCBkaXZBdHQoMCwgMCwgIDApKTsKICAgICAgICB9CgogICAgICBicmVhazsKICAgICAgY2FzZSAnc2hlZXQnOgogICAgICAgIAogICAgICAgIHZhciB3aWR0aCA9IHRoaXMud2lkdGgoKSwKICAgICAgICAgIGhlaWdodCA9IHRoaXMuaGVpZ2h0KCksCiAgICAgICAgICBzaXplID0gTWF0aC5yb3VuZChNYXRoLnNxcnQoTWF0aC5wb3cod2lkdGgsIDIpK01hdGgucG93KGhlaWdodCwgMikpKTsKICAgICAgICAKICAgICAgICBkYXRhLmZwYXJlbnQgPSBkYXRhLm9wdHMudHVybi5kYXRhKCkuZnBhcmVudDsKCiAgICAgICAgaWYgKCFkYXRhLmZwYXJlbnQpIHsKICAgICAgICAgIHZhciBmcGFyZW50ID0gJCgnPGRpdi8+Jywge2Nzczogeydwb2ludGVyLWV2ZW50cyc6ICdub25lJ319KS5oaWRlKCk7CiAgICAgICAgICAgIGZwYXJlbnQuZGF0YSgpLmZsaXBzID0gMDsKICAgICAgICAgICAgZnBhcmVudC5jc3MoZGl2QXR0KDAsIDAsICdhdXRvJywgJ3Zpc2libGUnKS5jc3MpLgogICAgICAgICAgICBhcHBlbmRUbyhkYXRhLm9wdHMudHVybik7CiAgICAgICAgICAgIAogICAgICAgICAgICBkYXRhLm9wdHMudHVybi5kYXRhKCkuZnBhcmVudCA9IGZwYXJlbnQ7CiAgICAgICAgICAgIGRhdGEuZnBhcmVudCA9IGZwYXJlbnQ7CiAgICAgICAgfQoKICAgICAgICB0aGlzLmNzcyh7cG9zaXRpb246ICdhYnNvbHV0ZScsIHRvcDogMCwgbGVmdDogMCwgYm90dG9tOiAnYXV0bycsIHJpZ2h0OiAnYXV0byd9KTsKCiAgICAgICAgZGF0YS53cmFwcGVyID0gJCgnPGRpdi8+JywgZGl2QXR0KDAsIDAsIHRoaXMuY3NzKCd6LWluZGV4JykpKS4KICAgICAgICAgIGFwcGVuZFRvKHBhcmVudCkuCiAgICAgICAgICBwcmVwZW5kKHRoaXMpOwoKICAgICAgICBkYXRhLmZ3cmFwcGVyID0gJCgnPGRpdi8+JywgZGl2QXR0KHBhcmVudC5vZmZzZXQoKS50b3AsIHBhcmVudC5vZmZzZXQoKS5sZWZ0KSkuCiAgICAgICAgICBoaWRlKCkuCiAgICAgICAgICBhcHBlbmRUbyhkYXRhLmZwYXJlbnQpOwoKICAgICAgICBkYXRhLmZwYWdlID0gJCgnPGRpdi8+JywgZGl2QXR0KDAsIDAsIDAsICd2aXNpYmxlJykpLgogICAgICAgICAgY3NzKHtjdXJzb3I6ICdkZWZhdWx0J30pLgogICAgICAgICAgYXBwZW5kVG8oZGF0YS5md3JhcHBlcik7CgogICAgICAgIGlmICh0dXJuRGF0YS5vcHRzLmdyYWRpZW50cykKICAgICAgICAgIGRhdGEuYXNoYWRvdyA9ICQoJzxkaXYvPicsIGRpdkF0dCgwLCAwLCAgMSkpLgogICAgICAgICAgYXBwZW5kVG8oZGF0YS5mcGFnZSk7CgogICAgICAgIGZsaXBNZXRob2RzLnNldERhdGEuY2FsbCh0aGlzLCBkYXRhKTsKCiAgICAgIGJyZWFrOwogICAgfQoKICAgIC8vIFNldCBzaXplCiAgICBmbGlwTWV0aG9kcy5yZXNpemUuY2FsbCh0aGlzLCB0cnVlKTsKCiAgfSwKCiAgLy8gVGFrZXMgYSAyUCBwb2ludCBmcm9tIHRoZSBzY3JlZW4gYW5kIGFwcGxpZXMgdGhlIHRyYW5zZm9ybWF0aW9uCgogIF9mb2xkOiBmdW5jdGlvbihwb2ludCkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCkuZiwKICAgICAgdHVybkRhdGEgPSBkYXRhLm9wdHMudHVybi5kYXRhKCksCiAgICAgIG8gPSBmbGlwTWV0aG9kcy5fYy5jYWxsKHRoaXMsIHBvaW50LmNvcm5lciksCiAgICAgIHdpZHRoID0gdGhpcy53aWR0aCgpLAogICAgICBoZWlnaHQgPSB0aGlzLmhlaWdodCgpOwoKICAgIHN3aXRjaCAoZGF0YS5lZmZlY3QpIHsKCiAgICAgIGNhc2UgJ2hhcmQnOgoKICAgICAgICBpZiAocG9pbnQuY29ybmVyPT0nbCcpCiAgICAgICAgICBwb2ludC54ID0gTWF0aC5taW4oTWF0aC5tYXgocG9pbnQueCwgMCksIHdpZHRoKjIpOwogICAgICAgIGVsc2UKICAgICAgICAgIHBvaW50LnggPSBNYXRoLm1heChNYXRoLm1pbihwb2ludC54LCB3aWR0aCksIC13aWR0aCk7CgogICAgICAgIHZhciBsZWZ0UG9zLAogICAgICAgICAgc2hhZG93LAogICAgICAgICAgZ3JhZGllbnRYLAogICAgICAgICAgZnBhZ2VPcmlnaW4sCiAgICAgICAgICBwYXJlbnRPcmlnaW4sCiAgICAgICAgICB0b3RhbFBhZ2VzID0gdHVybkRhdGEudG90YWxQYWdlcywKICAgICAgICAgIHpJbmRleCA9IGRhdGEub3B0c1snei1pbmRleCddIHx8IHRvdGFsUGFnZXMsCiAgICAgICAgICBwYXJlbnRDc3MgPSB7J292ZXJmbG93JzogJ3Zpc2libGUnfSwKICAgICAgICAgIHJlbFggPSAoby54KSA/IChvLnggLSBwb2ludC54KS93aWR0aCA6IHBvaW50Lngvd2lkdGgsCiAgICAgICAgICBhbmdsZSA9IHJlbFggKiA5MCwKICAgICAgICAgIGhhbGYgPSBhbmdsZTw5MDsKCiAgICAgICAgc3dpdGNoIChwb2ludC5jb3JuZXIpIHsKICAgICAgICAgIGNhc2UgJ2wnOgoKICAgICAgICAgICAgZnBhZ2VPcmlnaW4gPSAgJzAlIDUwJSc7CiAgICAgICAgICAgIHBhcmVudE9yaWdpbiA9ICAnMTAwJSA1MCUnOwoKICAgICAgICAgICAgaWYgKGhhbGYpIHsKICAgICAgICAgICAgICBsZWZ0UG9zID0gMDsKICAgICAgICAgICAgICBzaGFkb3cgPSBkYXRhLm9wdHMubmV4dC0xPjA7CiAgICAgICAgICAgICAgZ3JhZGllbnRYID0gMTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBsZWZ0UG9zID0gJzEwMCUnOwogICAgICAgICAgICAgIHNoYWRvdyA9IGRhdGEub3B0cy5wYWdlKzE8dG90YWxQYWdlczsKICAgICAgICAgICAgICBncmFkaWVudFggPSAwOwogICAgICAgICAgICB9CgogICAgICAgICAgYnJlYWs7CiAgICAgICAgICBjYXNlICdyJzoKCiAgICAgICAgICAgIGZwYWdlT3JpZ2luID0gICcxMDAlIDUwJSc7CiAgICAgICAgICAgIHBhcmVudE9yaWdpbiA9ICAnMCUgNTAlJzsKICAgICAgICAgICAgYW5nbGUgPSAtYW5nbGU7CiAgICAgICAgICAgIHdpZHRoID0gLXdpZHRoOwoKICAgICAgICAgICAgaWYgKGhhbGYpIHsKICAgICAgICAgICAgICBsZWZ0UG9zID0gMDsKICAgICAgICAgICAgICBzaGFkb3cgPSBkYXRhLm9wdHMubmV4dCsxPHRvdGFsUGFnZXM7CiAgICAgICAgICAgICAgZ3JhZGllbnRYID0gMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBsZWZ0UG9zID0gJy0xMDAlJzsKICAgICAgICAgICAgICBzaGFkb3cgPSBkYXRhLm9wdHMucGFnZSE9MTsKICAgICAgICAgICAgICBncmFkaWVudFggPSAxOwogICAgICAgICAgICB9CgogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQoKICAgICAgICBwYXJlbnRDc3NbdmVuZG9yKydwZXJzcGVjdGl2ZS1vcmlnaW4nXSA9IHBhcmVudE9yaWdpbjsKCiAgICAgICAgZGF0YS53cmFwcGVyLnRyYW5zZm9ybSgncm90YXRlWSgnK2FuZ2xlKydkZWcpJyArCiAgICAgICAgICAndHJhbnNsYXRlM2QoMHB4LCAwcHgsICcrKHRoaXMuYXR0cignZGVwdGgnKXx8MCkrJ3B4KScsIHBhcmVudE9yaWdpbik7CgogICAgICAgIGRhdGEuZnBhZ2UudHJhbnNmb3JtKCd0cmFuc2xhdGVYKCcrd2lkdGgrJ3B4KSByb3RhdGVZKCcrKDE4MCthbmdsZSkrJ2RlZyknLCBmcGFnZU9yaWdpbik7CgogICAgICAgIGRhdGEucGFyZW50LmNzcyhwYXJlbnRDc3MpOwoKICAgICAgICBpZiAoaGFsZikgewogICAgICAgICAgcmVsWCA9IC1yZWxYKzE7CiAgICAgICAgICBkYXRhLndyYXBwZXIuY3NzKHt6SW5kZXg6IHpJbmRleCsxfSk7CiAgICAgICAgICBkYXRhLmZwYWdlLmNzcyh7ekluZGV4OiB6SW5kZXh9KTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmVsWCA9IHJlbFgtMTsKICAgICAgICAgIGRhdGEud3JhcHBlci5jc3Moe3pJbmRleDogekluZGV4fSk7CiAgICAgICAgICBkYXRhLmZwYWdlLmNzcyh7ekluZGV4OiB6SW5kZXgrMX0pOwogICAgICAgIH0KCiAgICAgICAgaWYgKHR1cm5EYXRhLm9wdHMuZ3JhZGllbnRzKSB7CiAgICAgICAgICBpZiAoc2hhZG93KQogICAgICAgICAgICBkYXRhLmFzaGFkb3cuY3NzKHsKICAgICAgICAgICAgICBkaXNwbGF5OiAnJywKICAgICAgICAgICAgICBsZWZ0OiBsZWZ0UG9zLAogICAgICAgICAgICAgIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwwLDAsJysoMC41KnJlbFgpKycpJwogICAgICAgICAgICB9KS4KICAgICAgICAgICAgdHJhbnNmb3JtKCdyb3RhdGVZKDBkZWcpJyk7CiAgICAgICAgICBlbHNlCiAgICAgICAgICAgIGRhdGEuYXNoYWRvdy5oaWRlKCk7CgogICAgICAgICAgZGF0YS5ic2hhZG93LmNzcyh7b3BhY2l0eTotcmVsWCArIDF9KTsKCiAgICAgICAgICBpZiAoaGFsZikgewogICAgICAgICAgICBpZiAoZGF0YS5ic2hhZG93LnBhcmVudCgpWzBdIT1kYXRhLndyYXBwZXJbMF0pIHsKICAgICAgICAgICAgICBkYXRhLmJzaGFkb3cuYXBwZW5kVG8oZGF0YS53cmFwcGVyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaWYgKGRhdGEuYnNoYWRvdy5wYXJlbnQoKVswXSE9ZGF0YS5mcGFnZVswXSkgewogICAgICAgICAgICAgIGRhdGEuYnNoYWRvdy5hcHBlbmRUbyhkYXRhLmZwYWdlKTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgLypkYXRhLmJzaGFkb3cuY3NzKHsKICAgICAgICAgICAgYmFja2dyb3VuZENvbG9yOiAncmdiYSgwLDAsMCwnKygwLjEpKycpJwogICAgICAgICAgfSkqLwogICAgICAgICAgZ3JhZGllbnQoZGF0YS5ic2hhZG93LCBwb2ludDJEKGdyYWRpZW50WCAqIDEwMCwgMCksIHBvaW50MkQoKC1ncmFkaWVudFggKyAxKSoxMDAsIDApLAogICAgICAgICAgICBbWzAsICdyZ2JhKDAsMCwwLDAuMyknXSxbMSwgJ3JnYmEoMCwwLDAsMCknXV0sMik7CiAgICAgICAgICAKICAgICAgICB9CgogICAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGVldCc6CgogICAgICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICAgIGEgPSAwLAogICAgICAgICAgYWxwaGEgPSAwLAogICAgICAgICAgYmV0YSwKICAgICAgICAgIHB4LAogICAgICAgICAgZ3JhZGllbnRFbmRQb2ludEEsCiAgICAgICAgICBncmFkaWVudEVuZFBvaW50QiwKICAgICAgICAgIGdyYWRpZW50U3RhcnRWYWwsCiAgICAgICAgICBncmFkaWVudFNpemUsCiAgICAgICAgICBncmFkaWVudE9wYWNpdHksCiAgICAgICAgICBzaGFkb3dWYWwsCiAgICAgICAgICBtdiA9IHBvaW50MkQoMCwgMCksCiAgICAgICAgICBkZiA9IHBvaW50MkQoMCwgMCksCiAgICAgICAgICB0ciA9IHBvaW50MkQoMCwgMCksCiAgICAgICAgICBmb2xkaW5nID0gZmxpcE1ldGhvZHMuX2ZvbGRpbmdQYWdlLmNhbGwodGhpcyksCiAgICAgICAgICB0YW4gPSBNYXRoLnRhbihhbHBoYSksCiAgICAgICAgICBhYyA9IHR1cm5EYXRhLm9wdHMuYWNjZWxlcmF0aW9uLAogICAgICAgICAgaCA9IGRhdGEud3JhcHBlci5oZWlnaHQoKSwKICAgICAgICAgIHRvcCA9IHBvaW50LmNvcm5lci5zdWJzdHIoMCwgMSkgPT0gJ3QnLAogICAgICAgICAgbGVmdCA9IHBvaW50LmNvcm5lci5zdWJzdHIoMSwgMSkgPT0gJ2wnLAoKICAgICAgY29tcHV0ZSA9IGZ1bmN0aW9uKCkgewoKICAgICAgICB2YXIgcmVsID0gcG9pbnQyRCgwLCAwKTsKICAgICAgICB2YXIgbWlkZGxlID0gcG9pbnQyRCgwLCAwKTsKCiAgICAgICAgcmVsLnggPSAoby54KSA/IG8ueCAtIHBvaW50LnggOiBwb2ludC54OwoKICAgICAgICBpZiAoIWhhc1JvdCkgewogICAgICAgICAgcmVsLnkgPSAwOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZWwueSA9IChvLnkpID8gby55IC0gcG9pbnQueSA6IHBvaW50Lnk7CiAgICAgICAgfQoKICAgICAgICBtaWRkbGUueCA9IChsZWZ0KT8gd2lkdGggLSByZWwueC8yIDogcG9pbnQueCArIHJlbC54LzI7CiAgICAgICAgbWlkZGxlLnkgPSByZWwueS8yOwogICAgICAgIAogICAgICAgIHZhciBhbHBoYSA9ICBBOTAtTWF0aC5hdGFuMihyZWwueSwgcmVsLngpLAogICAgICAgICAgZ2FtbWEgPSBhbHBoYSAtIE1hdGguYXRhbjIobWlkZGxlLnksIG1pZGRsZS54KSwKICAgICAgICAgIGRpc3RhbmNlID0gIE1hdGgubWF4KDAsIE1hdGguc2luKGdhbW1hKSAqIE1hdGguc3FydChNYXRoLnBvdyhtaWRkbGUueCwgMikgKyBNYXRoLnBvdyhtaWRkbGUueSwgMikpKTsKICAgICAgICAgIAogICAgICAgICAgYSA9IGRlZyhhbHBoYSk7CgogICAgICAgICAgdHIgPSBwb2ludDJEKGRpc3RhbmNlICogTWF0aC5zaW4oYWxwaGEpLCBkaXN0YW5jZSAqIE1hdGguY29zKGFscGhhKSk7CgogICAgICAgICAgaWYgKGFscGhhID4gQTkwKSB7CiAgICAgICAgICAgIHRyLnggPSB0ci54ICsgTWF0aC5hYnModHIueSAqIHJlbC55L3JlbC54KTsKICAgICAgICAgICAgdHIueSA9IDA7CiAgICAgICAgICAgIGlmIChNYXRoLnJvdW5kKHRyLngqTWF0aC50YW4oUEktYWxwaGEpKSA8IGhlaWdodCkgewogICAgICAgICAgICAgIHBvaW50LnkgPSBNYXRoLnNxcnQoTWF0aC5wb3coaGVpZ2h0LCAyKSsyICogbWlkZGxlLnggKiByZWwueCk7CiAgICAgICAgICAgICAgaWYgKHRvcCkgcG9pbnQueSA9ICBoZWlnaHQgLSBwb2ludC55OwogICAgICAgICAgICAgIHJldHVybiBjb21wdXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgCiAgICAgICAgICBpZiAoYWxwaGE+QTkwKSB7CiAgICAgICAgICAgIHZhciBiZXRhID0gUEktYWxwaGEsIGRkID0gaCAtIGhlaWdodC9NYXRoLnNpbihiZXRhKTsKICAgICAgICAgICAgbXYgPSBwb2ludDJEKE1hdGgucm91bmQoZGQqTWF0aC5jb3MoYmV0YSkpLCBNYXRoLnJvdW5kKGRkKk1hdGguc2luKGJldGEpKSk7CiAgICAgICAgICAgIGlmIChsZWZ0KSBtdi54ID0gLSBtdi54OwogICAgICAgICAgICBpZiAodG9wKSBtdi55ID0gLSBtdi55OwogICAgICAgICAgfQoKICAgICAgICAgIHB4ID0gTWF0aC5yb3VuZCh0ci55L01hdGgudGFuKGFscGhhKSArIHRyLngpOwogICAgICAKICAgICAgICAgIHZhciBzaWRlID0gd2lkdGggLSBweCwKICAgICAgICAgICAgc2lkZVggPSBzaWRlKk1hdGguY29zKGFscGhhKjIpLAogICAgICAgICAgICBzaWRlWSA9IHNpZGUqTWF0aC5zaW4oYWxwaGEqMik7CiAgICAgICAgICAgIGRmID0gcG9pbnQyRCgKICAgICAgICAgICAgICBNYXRoLnJvdW5kKChsZWZ0ID8gc2lkZSAtc2lkZVggOiBweCtzaWRlWCkpLAogICAgICAgICAgICAgIE1hdGgucm91bmQoKHRvcCkgPyBzaWRlWSA6IGhlaWdodCAtIHNpZGVZKSk7CiAgICAgICAgICAKICAgICAgICAvLyBHcmFkaWVudHMKICAgICAgICAgIGlmICh0dXJuRGF0YS5vcHRzLmdyYWRpZW50cykgewoKICAgICAgICAgICAgZ3JhZGllbnRTaXplID0gc2lkZSpNYXRoLnNpbihhbHBoYSk7CgogICAgICAgICAgICB2YXIgZW5kaW5nUG9pbnQgPSBmbGlwTWV0aG9kcy5fYzIuY2FsbCh0aGF0LCBwb2ludC5jb3JuZXIpLAogICAgICAgICAgICAgZmFyID0gTWF0aC5zcXJ0KE1hdGgucG93KGVuZGluZ1BvaW50LngtcG9pbnQueCwgMikrTWF0aC5wb3coZW5kaW5nUG9pbnQueS1wb2ludC55LCAyKSkvd2lkdGg7CgogICAgICAgICAgICBzaGFkb3dWYWwgPSBNYXRoLnNpbihBOTAqKChmYXI+MSkgPyAyIC0gZmFyIDogZmFyKSk7CgogICAgICAgICAgICBncmFkaWVudE9wYWNpdHkgPSBNYXRoLm1pbihmYXIsIDEpOwoKICAgICAgICAgICAKICAgICAgICAgICAgICBncmFkaWVudFN0YXJ0VmFsID0gZ3JhZGllbnRTaXplPjEwMCA/IChncmFkaWVudFNpemUtMTAwKS9ncmFkaWVudFNpemUgOiAwOwoKICAgICAgICAgICAgICBncmFkaWVudEVuZFBvaW50QSA9IHBvaW50MkQoCiAgICAgICAgICAgICAgICBncmFkaWVudFNpemUqTWF0aC5zaW4oYWxwaGEpL3dpZHRoKjEwMCwKICAgICAgICAgICAgICAgIGdyYWRpZW50U2l6ZSpNYXRoLmNvcyhhbHBoYSkvaGVpZ2h0KjEwMCk7CiAgICAgICAgICAgCgogICAgICAgICAgICAgIGlmIChmbGlwTWV0aG9kcy5fYmFja0dyYWRpZW50LmNhbGwodGhhdCkpIHsKCiAgICAgICAgICAgICAgICBncmFkaWVudEVuZFBvaW50QiA9IHBvaW50MkQoCiAgICAgICAgICAgICAgICAgIGdyYWRpZW50U2l6ZSoxLjIqTWF0aC5zaW4oYWxwaGEpL3dpZHRoKjEwMCwKICAgICAgICAgICAgICAgICAgZ3JhZGllbnRTaXplKjEuMipNYXRoLmNvcyhhbHBoYSkvaGVpZ2h0KjEwMCk7CgogICAgICAgICAgICAgICAgaWYgKCFsZWZ0KSBncmFkaWVudEVuZFBvaW50Qi54ID0gMTAwLWdyYWRpZW50RW5kUG9pbnRCLng7CiAgICAgICAgICAgICAgICBpZiAoIXRvcCkgZ3JhZGllbnRFbmRQb2ludEIueSA9IDEwMC1ncmFkaWVudEVuZFBvaW50Qi55OwoKICAgICAgICAgICAgICB9CgogICAgICAgICAgfQoKICAgICAgICAgIHRyLnggPSBNYXRoLnJvdW5kKHRyLngpOwogICAgICAgICAgdHIueSA9IE1hdGgucm91bmQodHIueSk7CgogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9LAoKICAgICAgdHJhbnNmb3JtID0gZnVuY3Rpb24odHIsIGMsIHgsIGEpIHsKICAgICAgCiAgICAgICAgdmFyIGYgPSBbJzAnLCAnYXV0byddLCBtdlcgPSAod2lkdGgtaCkqeFswXS8xMDAsIG12SCA9IChoZWlnaHQtaCkqeFsxXS8xMDAsCiAgICAgICAgICBjc3NBID0ge2xlZnQ6IGZbY1swXV0sIHRvcDogZltjWzFdXSwgcmlnaHQ6IGZbY1syXV0sIGJvdHRvbTogZltjWzNdXX0sCiAgICAgICAgICBjc3NCID0ge30sCiAgICAgICAgICBhbGlhc2luZ0ZrID0gKGEhPTkwICYmIGEhPS05MCkgPyAobGVmdCA/IC0xIDogMSkgOiAwLAogICAgICAgICAgb3JpZ2luID0geFswXSArICclICcgKyB4WzFdICsgJyUnOwoKICAgICAgICB0aGF0LmNzcyhjc3NBKS4KICAgICAgICAgIHRyYW5zZm9ybShyb3RhdGUoYSkgKyB0cmFuc2xhdGUodHIueCArIGFsaWFzaW5nRmssIHRyLnksIGFjKSwgb3JpZ2luKTsKCiAgICAgICAgZGF0YS5mcGFnZS5jc3MoY3NzQSkudHJhbnNmb3JtKAogICAgICAgICAgcm90YXRlKGEpICsKICAgICAgICAgIHRyYW5zbGF0ZSh0ci54ICsgZGYueCAtIG12LnggLSB3aWR0aCp4WzBdLzEwMCwgdHIueSArIGRmLnkgLSBtdi55IC0gaGVpZ2h0KnhbMV0vMTAwLCBhYykgKwogICAgICAgICAgcm90YXRlKCgxODAvYSAtIDIpKmEpLAogICAgICAgICAgb3JpZ2luKTsKCiAgICAgICAgZGF0YS53cmFwcGVyLnRyYW5zZm9ybSh0cmFuc2xhdGUoLXRyLnggKyBtdlctYWxpYXNpbmdGaywgLXRyLnkgKyBtdkgsIGFjKSArIHJvdGF0ZSgtYSksIG9yaWdpbik7CgogICAgICAgIGRhdGEuZndyYXBwZXIudHJhbnNmb3JtKHRyYW5zbGF0ZSgtdHIueCArIG12LnggKyBtdlcsIC10ci55ICsgbXYueSArIG12SCwgYWMpICsgcm90YXRlKC1hKSwgb3JpZ2luKTsKICAgICAgCiAgICAgICAgaWYgKHR1cm5EYXRhLm9wdHMuZ3JhZGllbnRzKSB7CgogICAgICAgICAgaWYgKHhbMF0pCiAgICAgICAgICAgIGdyYWRpZW50RW5kUG9pbnRBLnggPSAxMDAtZ3JhZGllbnRFbmRQb2ludEEueDsKCiAgICAgICAgICBpZiAoeFsxXSkKICAgICAgICAgICAgZ3JhZGllbnRFbmRQb2ludEEueSA9ICgxMDAtZ3JhZGllbnRFbmRQb2ludEEueSk7CgogICAgICAgICAgY3NzQlsnYm94LXNoYWRvdyddID0gJzAgMCAyMHB4IHJnYmEoMCwwLDAsJysoMC41KnNoYWRvd1ZhbCkrJyknOwogICAgICAgICAgZm9sZGluZy5jc3MoY3NzQik7CgogICAgICAgICAgZ3JhZGllbnQoZGF0YS5hc2hhZG93LAogICAgICAgICAgICAgIHBvaW50MkQobGVmdD8xMDA6MCwgdG9wPzA6MTAwKSwKICAgICAgICAgICAgICBwb2ludDJEKGdyYWRpZW50RW5kUG9pbnRBLngsIGdyYWRpZW50RW5kUG9pbnRBLnkpLAogICAgICAgICAgICAgIFtbZ3JhZGllbnRTdGFydFZhbCwgJ3JnYmEoMCwwLDAsMCknXSwKICAgICAgICAgICAgICBbKCgxLWdyYWRpZW50U3RhcnRWYWwpKjAuOCkrZ3JhZGllbnRTdGFydFZhbCwgJ3JnYmEoMCwwLDAsJysoMC4yKmdyYWRpZW50T3BhY2l0eSkrJyknXSwKICAgICAgICAgICAgICBbMSwgJ3JnYmEoMjU1LDI1NSwyNTUsJysoMC4yKmdyYWRpZW50T3BhY2l0eSkrJyknXV0sCiAgICAgICAgICAgICAgMywKICAgICAgICAgICAgICBhbHBoYSk7CgogICAgICAgICAgaWYgKGZsaXBNZXRob2RzLl9iYWNrR3JhZGllbnQuY2FsbCh0aGF0KSkKICAgICAgICAgICAgZ3JhZGllbnQoZGF0YS5ic2hhZG93LAogICAgICAgICAgICAgICAgcG9pbnQyRChsZWZ0PzA6MTAwLCB0b3A/MDoxMDApLAogICAgICAgICAgICAgICAgcG9pbnQyRChncmFkaWVudEVuZFBvaW50Qi54LCBncmFkaWVudEVuZFBvaW50Qi55KSwKICAgICAgICAgICAgICAgIFtbMC42LCAncmdiYSgwLDAsMCwwKSddLAogICAgICAgICAgICAgICAgWzAuOCwgJ3JnYmEoMCwwLDAsJysoMC4zKmdyYWRpZW50T3BhY2l0eSkrJyknXSwKICAgICAgICAgICAgICAgIFsxLCAncmdiYSgwLDAsMCwwKSddCiAgICAgICAgICAgICAgICBdLAogICAgICAgICAgICAgICAgMyk7CiAgICAgICAgfQoKICAgICAgfTsKCiAgICAgIHN3aXRjaCAocG9pbnQuY29ybmVyKSB7CiAgICAgICAgY2FzZSAnbCcgOgoKCiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAncicgOgoKCiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAndGwnIDoKICAgICAgICAgIHBvaW50LnggPSBNYXRoLm1heChwb2ludC54LCAxKTsKICAgICAgICAgIGNvbXB1dGUoKTsKICAgICAgICAgIHRyYW5zZm9ybSh0ciwgWzEsMCwwLDFdLCBbMTAwLCAwXSwgYSk7CiAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAndHInIDoKICAgICAgICAgIHBvaW50LnggPSBNYXRoLm1pbihwb2ludC54LCB3aWR0aC0xKTsKICAgICAgICAgIGNvbXB1dGUoKTsKICAgICAgICAgIHRyYW5zZm9ybShwb2ludDJEKC10ci54LCB0ci55KSwgWzAsMCwwLDFdLCBbMCwgMF0sIC1hKTsKICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdibCcgOgogICAgICAgICAgcG9pbnQueCA9IE1hdGgubWF4KHBvaW50LngsIDEpOwogICAgICAgICAgY29tcHV0ZSgpOwogICAgICAgICAgdHJhbnNmb3JtKHBvaW50MkQodHIueCwgLXRyLnkpLCBbMSwxLDAsMF0sIFsxMDAsIDEwMF0sIC1hKTsKICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdicicgOgogICAgICAgICAgcG9pbnQueCA9IE1hdGgubWluKHBvaW50LngsIHdpZHRoLTEpOwogICAgICAgICAgY29tcHV0ZSgpOwogICAgICAgICAgdHJhbnNmb3JtKHBvaW50MkQoLXRyLngsIC10ci55KSwgWzAsMSwxLDBdLCBbMCwgMTAwXSwgYSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KCiAgICBicmVhazsKICB9CgogICAgZGF0YS5wb2ludCA9IHBvaW50OwogIAogIH0sCgogIF9tb3ZlRm9sZGluZ1BhZ2U6IGZ1bmN0aW9uKG1vdmUpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmY7CgogICAgaWYgKCFkYXRhKQogICAgICByZXR1cm47CgogICAgdmFyIHR1cm4gPSBkYXRhLm9wdHMudHVybiwKICAgICAgdHVybkRhdGEgPSB0dXJuLmRhdGEoKSwKICAgICAgcGxhY2UgPSB0dXJuRGF0YS5wYWdlUGxhY2U7CiAgICAgIAogICAgaWYgKG1vdmUpIHsKCiAgICAgIHZhciBuZXh0UGFnZSA9IGRhdGEub3B0cy5uZXh0OwogIAogICAgICBpZiAocGxhY2VbbmV4dFBhZ2VdIT1kYXRhLm9wdHMucGFnZSkgewoKICAgICAgICBpZiAoZGF0YS5mb2xkaW5nKQogICAgICAgICAgZmxpcE1ldGhvZHMuX21vdmVGb2xkaW5nUGFnZS5jYWxsKHRoaXMsIGZhbHNlKTsKCiAgICAgICAgdmFyIGZvbGRpbmcgPSBmbGlwTWV0aG9kcy5fZm9sZGluZ1BhZ2UuY2FsbCh0aGlzKTsKICAgICAgICAKICAgICAgICBmb2xkaW5nLmFwcGVuZFRvKGRhdGEuZnBhZ2UpOwogICAgICAgIHBsYWNlW25leHRQYWdlXSA9IGRhdGEub3B0cy5wYWdlOwogICAgICAgIGRhdGEuZm9sZGluZyA9IG5leHRQYWdlOwogICAgICB9CgogICAgICB0dXJuLnR1cm4oJ3VwZGF0ZScpOwoKICAgIH0gZWxzZSB7CgogICAgICBpZiAoZGF0YS5mb2xkaW5nKSB7CgogICAgICAgIGlmICh0dXJuRGF0YS5wYWdlc1tkYXRhLmZvbGRpbmddKSB7CiAgICAgICAgIAogICAgICAgICAgLy8gSWYgd2UgaGF2ZSBmbGlwIGF2YWlsYWJsZQoKICAgICAgICAgIHZhciBmbGlwRGF0YSA9IHR1cm5EYXRhLnBhZ2VzW2RhdGEuZm9sZGluZ10uZGF0YSgpLmY7CiAgICAgICAgICAKICAgICAgICAgIHR1cm5EYXRhLnBhZ2VPYmpzW2RhdGEuZm9sZGluZ10uCiAgICAgICAgICAgIGFwcGVuZFRvKGZsaXBEYXRhLndyYXBwZXIpOwoKICAgICAgICB9IGVsc2UgaWYgKHR1cm5EYXRhLnBhZ2VXcmFwW2RhdGEuZm9sZGluZ10pIHsKICAgICAgICAgIAogICAgICAgICAgLy8gSWYgd2UgaGF2ZSB0aGUgcGFnZVdyYXBwZXIKCiAgICAgICAgICB0dXJuRGF0YS5wYWdlT2Jqc1tkYXRhLmZvbGRpbmddLgogICAgICAgICAgICBhcHBlbmRUbyh0dXJuRGF0YS5wYWdlV3JhcFtkYXRhLmZvbGRpbmddKTsKCiAgICAgICAgfQoKICAgICAgICBpZiAoZGF0YS5mb2xkaW5nIGluIHBsYWNlKSB7CiAgICAgICAgICBwbGFjZVtkYXRhLmZvbGRpbmddID0gZGF0YS5mb2xkaW5nOwogICAgICAgIH0KCiAgICAgICAgZGVsZXRlIGRhdGEuZm9sZGluZzsKCiAgICAgIH0KICAgIH0KICB9LAoKICBfc2hvd0ZvbGRlZFBhZ2U6IGZ1bmN0aW9uKGMsIGFuaW1hdGUpIHsKCiAgICB2YXIgZm9sZGluZyA9IGZsaXBNZXRob2RzLl9mb2xkaW5nUGFnZS5jYWxsKHRoaXMpLAogICAgICBkZCA9IHRoaXMuZGF0YSgpLAogICAgICBkYXRhID0gZGQuZiwKICAgICAgdmlzaWJsZSA9IGRhdGEudmlzaWJsZTsKCiAgICBpZiAoZm9sZGluZykgewoKICAgICAgaWYgKCF2aXNpYmxlIHx8ICFkYXRhLnBvaW50IHx8IGRhdGEucG9pbnQuY29ybmVyIT1jLmNvcm5lcikgewoKICAgICAgICB2YXIgY29ybmVyID0gKAogICAgICAgICAgZGF0YS5zdGF0dXM9PSdob3ZlcicgfHwKICAgICAgICAgIGRhdGEuc3RhdHVzPT0ncGVlbCcgfHwKICAgICAgICAgIGRhdGEub3B0cy50dXJuLmRhdGEoKS5tb3VzZUFjdGlvbikgPwogICAgICAgIGMuY29ybmVyIDogbnVsbDsKCiAgICAgICAgdmlzaWJsZSA9IGZhbHNlOwoKICAgICAgICBpZiAodHJpZ2dlcignc3RhcnQnLCB0aGlzLCBbZGF0YS5vcHRzLCBjb3JuZXJdKT09J3ByZXZlbnRlZCcpCiAgICAgICAgICByZXR1cm4gZmFsc2U7CgogICAgICB9CgogICAgICBpZiAoYW5pbWF0ZSkgewogICAgICAgIAogICAgICAgIHZhciB0aGF0ID0gdGhpcywKICAgICAgICAgIHBvaW50ID0gKGRhdGEucG9pbnQgJiYgZGF0YS5wb2ludC5jb3JuZXI9PWMuY29ybmVyKSA/CiAgICAgICAgICBkYXRhLnBvaW50IDogZmxpcE1ldGhvZHMuX2MuY2FsbCh0aGlzLCBjLmNvcm5lciwgMSk7CiAgICAgIAogICAgICAgIHRoaXMuYW5pbWF0ZWYoewogICAgICAgICAgZnJvbTogW3BvaW50LngsIHBvaW50LnldLAogICAgICAgICAgdG86IFtjLngsIGMueV0sCiAgICAgICAgICBkdXJhdGlvbjogNTAwLAogICAgICAgICAgZnJhbWU6IGZ1bmN0aW9uKHYpIHsKICAgICAgICAgICAgYy54ID0gTWF0aC5yb3VuZCh2WzBdKTsKICAgICAgICAgICAgYy55ID0gTWF0aC5yb3VuZCh2WzFdKTsKICAgICAgICAgICAgZmxpcE1ldGhvZHMuX2ZvbGQuY2FsbCh0aGF0LCBjKTsKICAgICAgICAgIH0KICAgICAgICB9KTsKCiAgICAgIH0gZWxzZSAgewoKICAgICAgICBmbGlwTWV0aG9kcy5fZm9sZC5jYWxsKHRoaXMsIGMpOwoKICAgICAgICBpZiAoZGQuZWZmZWN0ICYmICFkZC5lZmZlY3QudHVybmluZykKICAgICAgICAgIHRoaXMuYW5pbWF0ZWYoZmFsc2UpOwoKICAgICAgfQoKICAgICAgaWYgKCF2aXNpYmxlKSB7CgogICAgICAgIHN3aXRjaChkYXRhLmVmZmVjdCkgewogICAgICAgICAgY2FzZSAnaGFyZCc6CgogICAgICAgICAgICBkYXRhLnZpc2libGUgPSB0cnVlOwogICAgICAgICAgICBmbGlwTWV0aG9kcy5fbW92ZUZvbGRpbmdQYWdlLmNhbGwodGhpcywgdHJ1ZSk7CiAgICAgICAgICAgIGRhdGEuZnBhZ2Uuc2hvdygpOwogICAgICAgICAgICBpZiAoZGF0YS5vcHRzLnNoYWRvd3MpCiAgICAgICAgICAgICAgZGF0YS5ic2hhZG93LnNob3coKTsKCiAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgJ3NoZWV0JzoKCiAgICAgICAgICAgIGRhdGEudmlzaWJsZSA9IHRydWU7CiAgICAgICAgICAgIGRhdGEuZnBhcmVudC5zaG93KCkuZGF0YSgpLmZsaXBzKys7CiAgICAgICAgICAgIGZsaXBNZXRob2RzLl9tb3ZlRm9sZGluZ1BhZ2UuY2FsbCh0aGlzLCB0cnVlKTsKICAgICAgICAgICAgZGF0YS5md3JhcHBlci5zaG93KCk7CiAgICAgICAgICAgIGlmIChkYXRhLmJzaGFkb3cpCiAgICAgICAgICAgICAgZGF0YS5ic2hhZG93LnNob3coKTsKCiAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICB9CgogICAgICByZXR1cm4gdHJ1ZTsKCiAgICB9CgogICAgcmV0dXJuIGZhbHNlOwogIH0sCgogIGhpZGU6IGZ1bmN0aW9uKCkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCkuZiwKICAgICAgdHVybkRhdGEgPSBkYXRhLm9wdHMudHVybi5kYXRhKCksCiAgICAgIGZvbGRpbmcgPSBmbGlwTWV0aG9kcy5fZm9sZGluZ1BhZ2UuY2FsbCh0aGlzKTsKCiAgICBzd2l0Y2ggKGRhdGEuZWZmZWN0KSB7CiAgICAgIGNhc2UgJ2hhcmQnOgogICAgICAgIAogICAgICAgIGlmICh0dXJuRGF0YS5vcHRzLmdyYWRpZW50cykgewogICAgICAgICAgZGF0YS5ic2hhZG93TG9jID0gMDsKICAgICAgICAgIGRhdGEuYnNoYWRvdy5yZW1vdmUoKTsKICAgICAgICAgIGRhdGEuYXNoYWRvdy5oaWRlKCk7CiAgICAgICAgfQoKICAgICAgICBkYXRhLndyYXBwZXIudHJhbnNmb3JtKCcnKTsKICAgICAgICBkYXRhLmZwYWdlLmhpZGUoKTsKCiAgICAgIGJyZWFrOwogICAgICBjYXNlICdzaGVldCc6CgogICAgICAgIGlmICgoLS1kYXRhLmZwYXJlbnQuZGF0YSgpLmZsaXBzKT09PTApCiAgICAgICAgICBkYXRhLmZwYXJlbnQuaGlkZSgpOwoKICAgICAgICB0aGlzLmNzcyh7bGVmdDogMCwgdG9wOiAwLCByaWdodDogJ2F1dG8nLCBib3R0b206ICdhdXRvJ30pLgogICAgICAgICAgdHJhbnNmb3JtKCcnKTsKCiAgICAgICAgZGF0YS53cmFwcGVyLnRyYW5zZm9ybSgnJyk7CgogICAgICAgIGRhdGEuZndyYXBwZXIuaGlkZSgpOwoKICAgICAgICBpZiAoZGF0YS5ic2hhZG93KQogICAgICAgICAgZGF0YS5ic2hhZG93LmhpZGUoKTsKCiAgICAgICAgZm9sZGluZy50cmFuc2Zvcm0oJycpOwoKICAgICAgYnJlYWs7CiAgICB9CgogICAgICBkYXRhLnZpc2libGUgPSBmYWxzZTsKCiAgICByZXR1cm4gdGhpczsKICB9LAoKICBoaWRlRm9sZGVkUGFnZTogZnVuY3Rpb24oYW5pbWF0ZSkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCkuZjsKCiAgICBpZiAoIWRhdGEucG9pbnQpIHJldHVybjsKCiAgICB2YXIgdGhhdCA9IHRoaXMsCiAgICAgIHAxID0gZGF0YS5wb2ludCwKICAgICAgaGlkZSA9IGZ1bmN0aW9uKCkgewogICAgICAgIGRhdGEucG9pbnQgPSBudWxsOwogICAgICAgIGRhdGEuc3RhdHVzID0gJyc7CiAgICAgICAgdGhhdC5mbGlwKCdoaWRlJyk7CiAgICAgICAgdGhhdC50cmlnZ2VyKCdlbmQnLCBbZGF0YS5vcHRzLCBmYWxzZV0pOwogICAgICB9OwoKICAgIGlmIChhbmltYXRlKSB7CgogICAgICB2YXIgcDQgPSBmbGlwTWV0aG9kcy5fYy5jYWxsKHRoaXMsIHAxLmNvcm5lciksCiAgICAgICAgdG9wID0gKHAxLmNvcm5lci5zdWJzdHIoMCwxKT09J3QnKSwKICAgICAgICBkZWx0YSA9ICh0b3ApID8gTWF0aC5taW4oMCwgcDEueS1wNC55KS8yIDogTWF0aC5tYXgoMCwgcDEueS1wNC55KS8yLAogICAgICAgIHAyID0gcG9pbnQyRChwMS54LCBwMS55K2RlbHRhKSwKICAgICAgICBwMyA9IHBvaW50MkQocDQueCwgcDQueS1kZWx0YSk7CiAgICAKICAgICAgdGhpcy5hbmltYXRlZih7CiAgICAgICAgZnJvbTogMCwKICAgICAgICB0bzogMSwKICAgICAgICBmcmFtZTogZnVuY3Rpb24odikgewogICAgICAgICAgdmFyIG5wID0gYmV6aWVyKHAxLCBwMiwgcDMsIHA0LCB2KTsKICAgICAgICAgIHAxLnggPSBucC54OwogICAgICAgICAgcDEueSA9IG5wLnk7CiAgICAgICAgICBmbGlwTWV0aG9kcy5fZm9sZC5jYWxsKHRoYXQsIHAxKTsKICAgICAgICB9LAogICAgICAgIGNvbXBsZXRlOiBoaWRlLAogICAgICAgIGR1cmF0aW9uOiA4MDAsCiAgICAgICAgaGlkaW5nOiB0cnVlCiAgICAgIH0pOwoKICAgIH0gZWxzZSB7CgogICAgICB0aGlzLmFuaW1hdGVmKGZhbHNlKTsKICAgICAgaGlkZSgpOwoKICAgIH0KICB9LAoKICB0dXJuUGFnZTogZnVuY3Rpb24oY29ybmVyKSB7CgogICAgdmFyIHRoYXQgPSB0aGlzLAogICAgICBkYXRhID0gdGhpcy5kYXRhKCkuZiwKICAgICAgdHVybkRhdGEgPSBkYXRhLm9wdHMudHVybi5kYXRhKCk7CgogICAgY29ybmVyID0ge2Nvcm5lcjogKGRhdGEuY29ybmVyKSA/CiAgICAgIGRhdGEuY29ybmVyLmNvcm5lciA6CiAgICAgIGNvcm5lciB8fCBmbGlwTWV0aG9kcy5fY0FsbG93ZWQuY2FsbCh0aGlzKVswXX07CgogICAgdmFyIHAxID0gZGF0YS5wb2ludCB8fAogICAgICBmbGlwTWV0aG9kcy5fYy5jYWxsKHRoaXMsCiAgICAgICAgY29ybmVyLmNvcm5lciwKICAgICAgICAoZGF0YS5vcHRzLnR1cm4pID8gdHVybkRhdGEub3B0cy5lbGV2YXRpb24gOiAwKSwKICAgICAgcDQgPSBmbGlwTWV0aG9kcy5fYzIuY2FsbCh0aGlzLCBjb3JuZXIuY29ybmVyKTsKCiAgICAgIHRoaXMudHJpZ2dlcignZmxpcCcpLgogICAgICAgIGFuaW1hdGVmKHsKICAgICAgICAgIGZyb206IDAsCiAgICAgICAgICB0bzogMSwKICAgICAgICAgIGZyYW1lOiBmdW5jdGlvbih2KSB7CgogICAgICAgICAgICB2YXIgbnAgPSBiZXppZXIocDEsIHAxLCBwNCwgcDQsIHYpOwogICAgICAgICAgICBjb3JuZXIueCA9IG5wLng7CiAgICAgICAgICAgIGNvcm5lci55ID0gbnAueTsKICAgICAgICAgICAgZmxpcE1ldGhvZHMuX3Nob3dGb2xkZWRQYWdlLmNhbGwodGhhdCwgY29ybmVyKTsKCiAgICAgICAgICB9LAogICAgICAgICAgY29tcGxldGU6IGZ1bmN0aW9uKCkgewogICAgICAgICAgICAKICAgICAgICAgICAgdGhhdC50cmlnZ2VyKCdlbmQnLCBbZGF0YS5vcHRzLCB0cnVlXSk7CgogICAgICAgICAgfSwKICAgICAgICAgIGR1cmF0aW9uOiB0dXJuRGF0YS5vcHRzLmR1cmF0aW9uLAogICAgICAgICAgdHVybmluZzogdHJ1ZQogICAgICAgIH0pOwoKICAgICAgZGF0YS5jb3JuZXIgPSBudWxsOwogIH0sCgogIG1vdmluZzogZnVuY3Rpb24oKSB7CgogICAgcmV0dXJuICdlZmZlY3QnIGluIHRoaXMuZGF0YSgpOwogIAogIH0sCgogIGlzVHVybmluZzogZnVuY3Rpb24oKSB7CgogICAgcmV0dXJuIHRoaXMuZmxpcCgnbW92aW5nJykgJiYgdGhpcy5kYXRhKCkuZWZmZWN0LnR1cm5pbmc7CiAgCiAgfSwKCiAgY29ybmVyOiBmdW5jdGlvbigpIHsKICAgIAogICAgcmV0dXJuIHRoaXMuZGF0YSgpLmYuY29ybmVyOwogICAgICAKICB9LAoKICBfZXZlbnRTdGFydDogZnVuY3Rpb24oZSkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCkuZiwKICAgICAgdHVybiA9IGRhdGEub3B0cy50dXJuOwoKICAgIGlmICghZGF0YS5jb3JuZXIgJiYgIWRhdGEuZGlzYWJsZWQgJiYgIXRoaXMuZmxpcCgnaXNUdXJuaW5nJykgJiYKICAgICAgZGF0YS5vcHRzLnBhZ2U9PXR1cm4uZGF0YSgpLnBhZ2VQbGFjZVtkYXRhLm9wdHMucGFnZV0pCiAgICB7CgogICAgICBkYXRhLmNvcm5lciA9IGZsaXBNZXRob2RzLl9pc0lBcmVhLmNhbGwodGhpcywgZSk7CgogICAgICBpZiAoZGF0YS5jb3JuZXIgJiYgZmxpcE1ldGhvZHMuX2ZvbGRpbmdQYWdlLmNhbGwodGhpcykpIHsKCiAgICAgICAgdGhpcy50cmlnZ2VyKCdwcmVzc2VkJywgW2RhdGEucG9pbnRdKTsKICAgICAgICBmbGlwTWV0aG9kcy5fc2hvd0ZvbGRlZFBhZ2UuY2FsbCh0aGlzLCBkYXRhLmNvcm5lcik7CgogICAgICAgIHJldHVybiBmYWxzZTsKCiAgICAgIH0gZWxzZQogICAgICAgIGRhdGEuY29ybmVyID0gbnVsbDsKCiAgICB9CgogIH0sCgogIF9ldmVudE1vdmU6IGZ1bmN0aW9uKGUpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmY7CgogICAgaWYgKCFkYXRhLmRpc2FibGVkKSB7CgogICAgICBlID0gKGlzVG91Y2gpID8gZS5vcmlnaW5hbEV2ZW50LnRvdWNoZXMgOiBbZV07CgogICAgICBpZiAoZGF0YS5jb3JuZXIpIHsKCiAgICAgICAgdmFyIHBvcyA9IGRhdGEucGFyZW50Lm9mZnNldCgpOwogICAgICAgIGRhdGEuY29ybmVyLnggPSBlWzBdLnBhZ2VYLXBvcy5sZWZ0OwogICAgICAgIGRhdGEuY29ybmVyLnkgPSBlWzBdLnBhZ2VZLXBvcy50b3A7CiAgICAgICAgZmxpcE1ldGhvZHMuX3Nob3dGb2xkZWRQYWdlLmNhbGwodGhpcywgZGF0YS5jb3JuZXIpOwoKICAgICAgfSBlbHNlIGlmIChkYXRhLmhvdmVyICYmICF0aGlzLmRhdGEoKS5lZmZlY3QgJiYgdGhpcy5pcygnOnZpc2libGUnKSkgewoKICAgICAgICB2YXIgcG9pbnQgPSBmbGlwTWV0aG9kcy5faXNJQXJlYS5jYWxsKHRoaXMsIGVbMF0pOwoKICAgICAgICBpZiAocG9pbnQpIHsKCiAgICAgICAgICBpZiAoKGRhdGEuZWZmZWN0PT0nc2hlZXQnICYmIHBvaW50LmNvcm5lci5sZW5ndGg9PTIpICB8fCBkYXRhLmVmZmVjdD09J2hhcmQnKSB7CiAgICAgICAgICAgIGRhdGEuc3RhdHVzID0gJ2hvdmVyJzsKICAgICAgICAgICAgdmFyIG9yaWdpbiA9IGZsaXBNZXRob2RzLl9jLmNhbGwodGhpcywgcG9pbnQuY29ybmVyLCBkYXRhLm9wdHMuY29ybmVyU2l6ZS8yKTsKICAgICAgICAgICAgcG9pbnQueCA9IG9yaWdpbi54OwogICAgICAgICAgICBwb2ludC55ID0gb3JpZ2luLnk7CiAgICAgICAgICAgIGZsaXBNZXRob2RzLl9zaG93Rm9sZGVkUGFnZS5jYWxsKHRoaXMsIHBvaW50LCB0cnVlKTsKICAgICAgICAgIH0KICAgICAgICAKICAgICAgICB9IGVsc2UgewogICAgICAgICAgCiAgICAgICAgICBpZiAoZGF0YS5zdGF0dXM9PSdob3ZlcicpIHsKICAgICAgICAgICAgZGF0YS5zdGF0dXMgPSAnJzsKICAgICAgICAgICAgZmxpcE1ldGhvZHMuaGlkZUZvbGRlZFBhZ2UuY2FsbCh0aGlzLCB0cnVlKTsKICAgICAgICAgIH0KCiAgICAgICAgfQoKICAgICAgfQoKICAgIH0KCiAgfSwKCiAgX2V2ZW50RW5kOiBmdW5jdGlvbigpIHsKCiAgICB2YXIgZGF0YSA9IHRoaXMuZGF0YSgpLmYsCiAgICAgIGNvcm5lciA9IGRhdGEuY29ybmVyOwoKICAgIGlmICghZGF0YS5kaXNhYmxlZCAmJiBjb3JuZXIpIHsKICAgICAgaWYgKHRyaWdnZXIoJ3JlbGVhc2VkJywgdGhpcywgW2RhdGEucG9pbnQgfHwgY29ybmVyXSkhPSdwcmV2ZW50ZWQnKSB7CiAgICAgICAgZmxpcE1ldGhvZHMuaGlkZUZvbGRlZFBhZ2UuY2FsbCh0aGlzLCB0cnVlKTsKICAgICAgfQogICAgfQoKICAgIGRhdGEuY29ybmVyID0gbnVsbDsKCiAgfSwKCiAgZGlzYWJsZTogZnVuY3Rpb24oZGlzYWJsZSkgewoKICAgIGZsaXBNZXRob2RzLnNldERhdGEuY2FsbCh0aGlzLCB7J2Rpc2FibGVkJzogZGlzYWJsZX0pOwogICAgcmV0dXJuIHRoaXM7CgogIH0sCgogIGhvdmVyOiBmdW5jdGlvbihob3ZlcikgewogICAgCiAgICBmbGlwTWV0aG9kcy5zZXREYXRhLmNhbGwodGhpcywgeydob3Zlcic6IGhvdmVyfSk7CiAgICByZXR1cm4gdGhpczsKCiAgfSwKCiAgcGVlbDogZnVuY3Rpb24gKGNvcm5lciwgYW5pbWF0ZSkgewoKICAgIHZhciBkYXRhID0gdGhpcy5kYXRhKCkuZjsKCiAgICBpZiAoY29ybmVyKSB7CgogICAgICBpZiAoJC5pbkFycmF5KGNvcm5lciwgY29ybmVycy5hbGwpPT0tMSkKICAgICAgICB0aHJvdyB0dXJuRXJyb3IoJ0Nvcm5lciAnK2Nvcm5lcisnIGlzIG5vdCBwZXJtaXR0ZWQnKTsKCiAgICAgIGlmICgkLmluQXJyYXkoY29ybmVyLCBmbGlwTWV0aG9kcy5fY0FsbG93ZWQuY2FsbCh0aGlzKSkhPS0xKSB7CgogICAgICAgIHZhciBwb2ludCA9IGZsaXBNZXRob2RzLl9jLmNhbGwodGhpcywgY29ybmVyLCBkYXRhLm9wdHMuY29ybmVyU2l6ZS8yKTsKICAgICAgICAKICAgICAgICBkYXRhLnN0YXR1cyA9ICdwZWVsJzsKCiAgICAgICAgZmxpcE1ldGhvZHMuX3Nob3dGb2xkZWRQYWdlLmNhbGwodGhpcywKICAgICAgICB7CiAgICAgICAgICBjb3JuZXI6IGNvcm5lciwKICAgICAgICAgIHg6IHBvaW50LngsCiAgICAgICAgICB5OiBwb2ludC55CiAgICAgICAgfSwgYW5pbWF0ZSk7CgogICAgICB9CgoKICAgIH0gZWxzZSB7CgogICAgICBkYXRhLnN0YXR1cyA9ICcnOwoKICAgICAgZmxpcE1ldGhvZHMuaGlkZUZvbGRlZFBhZ2UuY2FsbCh0aGlzLCBhbmltYXRlKTsKICAgICAgCiAgICB9CgogICAgcmV0dXJuIHRoaXM7CiAgfQp9OwoKCi8vIFByb2Nlc3NlcyBjbGFzc2VzCgpmdW5jdGlvbiBkZWModGhhdCwgbWV0aG9kcywgYXJncykgewoKICBpZiAoIWFyZ3NbMF0gfHwgdHlwZW9mKGFyZ3NbMF0pPT0nb2JqZWN0JykKICAgIHJldHVybiBtZXRob2RzLmluaXQuYXBwbHkodGhhdCwgYXJncyk7CgogIGVsc2UgaWYgKG1ldGhvZHNbYXJnc1swXV0pCiAgICByZXR1cm4gbWV0aG9kc1thcmdzWzBdXS5hcHBseSh0aGF0LCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmdzLCAxKSk7CgogIGVsc2UKICAgIHRocm93IHR1cm5FcnJvcihhcmdzWzBdICsgJyBpcyBub3QgYSBtZXRob2Qgb3IgcHJvcGVydHknKTsKCn0KCgovLyBBdHRyaWJ1dGVzIGZvciBhIGxheWVyCgpmdW5jdGlvbiBkaXZBdHQodG9wLCBsZWZ0LCB6SW5kZXgsIG92ZXJmKSB7CiAgICAKICByZXR1cm4geydjc3MnOiB7CiAgICBwb3NpdGlvbjogJ2Fic29sdXRlJywKICAgIHRvcDogdG9wLAogICAgbGVmdDogbGVmdCwKICAgICdvdmVyZmxvdyc6IG92ZXJmIHx8ICdoaWRkZW4nLAogICAgekluZGV4OiB6SW5kZXggfHwgJ2F1dG8nCiAgfQp9OwogICAgICAKfQoKLy8gR2V0cyBhIDJEIHBvaW50IGZyb20gYSBiZXppZXIgY3VydmUgb2YgZm91ciBwb2ludHMKCmZ1bmN0aW9uIGJlemllcihwMSwgcDIsIHAzLCBwNCwgdCkgewoKICB2YXIgYSA9IDEgLSB0LAogICAgYiA9IGEgKiBhICogYSwKICAgIGMgPSB0ICogdCAqIHQ7CiAgICAKICByZXR1cm4gcG9pbnQyRChNYXRoLnJvdW5kKGIqcDEueCArIDMqdCphKmEqcDIueCArIDMqdCp0KmEqcDMueCArIGMqcDQueCksCiAgICBNYXRoLnJvdW5kKGIqcDEueSArIDMqdCphKmEqcDIueSArIDMqdCp0KmEqcDMueSArIGMqcDQueSkpOwoKfQogIAovLyBDb252ZXJ0cyBhbiBhbmdsZSBmcm9tIGRlZ3JlZXMgdG8gcmFkaWFucwoKZnVuY3Rpb24gcmFkKGRlZ3JlZXMpIHsKICAKICByZXR1cm4gZGVncmVlcy8xODAqUEk7Cgp9CgovLyBDb252ZXJ0cyBhbiBhbmdsZSBmcm9tIHJhZGlhbnMgdG8gZGVncmVlcwoKZnVuY3Rpb24gZGVnKHJhZGlhbnMpIHsKICAKICByZXR1cm4gcmFkaWFucy9QSSoxODA7Cgp9CgovLyBHZXRzIGEgMkQgcG9pbnQKCmZ1bmN0aW9uIHBvaW50MkQoeCwgeSkgewogIAogIHJldHVybiB7eDogeCwgeTogeX07Cgp9CgovLyBXZWJraXQgNTM0LjMgb24gQW5kcm9pZCB3cm9uZ2x5IHJlcGFpbnRzIGVsZW1lbnRzIHRoYXQgdXNlIG92ZXJmbG93OmhpZGRlbiArIHJvdGF0aW9uCgpmdW5jdGlvbiByb3RhdGlvbkF2YWlsYWJsZSgpIHsKICB2YXIgcGFydHM7CgogIGlmICgocGFydHMgPSAvQXBwbGVXZWJraXRcLyhbMC05XC5dKykvaS5leGVjKG5hdmlnYXRvci51c2VyQWdlbnQpKSkgewogICAgdmFyIHdlYmtpdFZlcnNpb24gPSBwYXJzZUZsb2F0KHBhcnRzWzFdKTsKICAgIHJldHVybiAod2Via2l0VmVyc2lvbj41MzQuMyk7CiAgfSBlbHNlIHsKICAgIHJldHVybiB0cnVlOwogIH0KfQoKLy8gUmV0dXJucyB0aGUgdHJhc2xhdGUgdmFsdWUKCmZ1bmN0aW9uIHRyYW5zbGF0ZSh4LCB5LCB1c2UzZCkgewogIAogIHJldHVybiAoaGFzM2QgJiYgdXNlM2QpID8gJyB0cmFuc2xhdGUzZCgnICsgeCArICdweCwnICsgeSArICdweCwgMHB4KSAnCiAgOiAnIHRyYW5zbGF0ZSgnICsgeCArICdweCwgJyArIHkgKyAncHgpICc7Cgp9CgovLyBSZXR1cm5zIHRoZSByb3RhdGlvbiB2YWx1ZQoKZnVuY3Rpb24gcm90YXRlKGRlZ3JlZXMpIHsKICAKICByZXR1cm4gJyByb3RhdGUoJyArIGRlZ3JlZXMgKyAnZGVnKSAnOwoKfQoKLy8gQ2hlY2tzIGlmIGEgcHJvcGVydHkgYmVsb25ncyB0byBhbiBvYmplY3QKCmZ1bmN0aW9uIGhhcyhwcm9wZXJ0eSwgb2JqZWN0KSB7CiAgCiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsKCn0KCi8vIEdldHMgdGhlIENTUzMgdmVuZG9yIHByZWZpeAoKZnVuY3Rpb24gZ2V0UHJlZml4KCkgewoKICB2YXIgdmVuZG9yUHJlZml4ZXMgPSBbJ01veicsJ1dlYmtpdCcsJ0todG1sJywnTycsJ21zJ10sCiAgbGVuID0gdmVuZG9yUHJlZml4ZXMubGVuZ3RoLAogIHZlbmRvciA9ICcnOwoKICB3aGlsZSAobGVuLS0pCiAgICBpZiAoKHZlbmRvclByZWZpeGVzW2xlbl0gKyAnVHJhbnNmb3JtJykgaW4gZG9jdW1lbnQuYm9keS5zdHlsZSkKICAgICAgdmVuZG9yPSctJyt2ZW5kb3JQcmVmaXhlc1tsZW5dLnRvTG93ZXJDYXNlKCkrJy0nOwoKICByZXR1cm4gdmVuZG9yOwoKfQoKLy8gRGV0ZWN0cyB0aGUgdHJhbnNpdGlvbkVuZCBFdmVudAoKZnVuY3Rpb24gZ2V0VHJhbnNpdGlvbkVuZCgpIHsKCiAgdmFyIHQsCiAgICBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2Zha2VlbGVtZW50JyksCiAgICB0cmFuc2l0aW9ucyA9IHsKICAgICAgJ3RyYW5zaXRpb24nOid0cmFuc2l0aW9uZW5kJywKICAgICAgJ09UcmFuc2l0aW9uJzonb1RyYW5zaXRpb25FbmQnLAogICAgICAnTVNUcmFuc2l0aW9uJzondHJhbnNpdGlvbmVuZCcsCiAgICAgICdNb3pUcmFuc2l0aW9uJzondHJhbnNpdGlvbmVuZCcsCiAgICAgICdXZWJraXRUcmFuc2l0aW9uJzond2Via2l0VHJhbnNpdGlvbkVuZCcKICAgIH07CgogIGZvciAodCBpbiB0cmFuc2l0aW9ucykgewogICAgaWYgKGVsLnN0eWxlW3RdICE9PSB1bmRlZmluZWQpIHsKICAgICAgcmV0dXJuIHRyYW5zaXRpb25zW3RdOwogICAgfQogIH0KfQoKLy8gR3JhZGllbnRzCgpmdW5jdGlvbiBncmFkaWVudChvYmosIHAwLCBwMSwgY29sb3JzLCBudW1Db2xvcnMpIHsKCiAgdmFyIGosIGNvbHMgPSBbXTsKCiAgaWYgKHZlbmRvcj09Jy13ZWJraXQtJykgewoKICAgIGZvciAoaiA9IDA7IGo8bnVtQ29sb3JzOyBqKyspCiAgICAgIGNvbHMucHVzaCgnY29sb3Itc3RvcCgnK2NvbG9yc1tqXVswXSsnLCAnK2NvbG9yc1tqXVsxXSsnKScpOwogICAgCiAgICBvYmouY3NzKHsnYmFja2dyb3VuZC1pbWFnZSc6CiAgICAgICAgJy13ZWJraXQtZ3JhZGllbnQobGluZWFyLCAnKwogICAgICAgIHAwLngrJyUgJysKICAgICAgICBwMC55KyclLCcrCiAgICAgICAgcDEueCsnJSAnKwogICAgICAgIHAxLnkrJyUsICcrCiAgICAgICAgY29scy5qb2luKCcsJykgKyAnICknfSk7CiAgfSBlbHNlIHsKICAgIAogICAgcDAgPSB7eDpwMC54LzEwMCAqIG9iai53aWR0aCgpLCB5OnAwLnkvMTAwICogb2JqLmhlaWdodCgpfTsKICAgIHAxID0ge3g6cDEueC8xMDAgKiBvYmoud2lkdGgoKSwgeTpwMS55LzEwMCAqIG9iai5oZWlnaHQoKX07CgogICAgdmFyIGR4ID0gcDEueC1wMC54LAogICAgICBkeSA9IHAxLnktcDAueSwKICAgICAgYW5nbGUgPSBNYXRoLmF0YW4yKGR5LCBkeCksCiAgICAgIGFuZ2xlMiA9IGFuZ2xlIC0gTWF0aC5QSS8yLAogICAgICBkaWFnb25hbCA9IE1hdGguYWJzKG9iai53aWR0aCgpKk1hdGguc2luKGFuZ2xlMikpK01hdGguYWJzKG9iai5oZWlnaHQoKSpNYXRoLmNvcyhhbmdsZTIpKSwKICAgICAgZ3JhZGllbnREaWFnb25hbCA9IE1hdGguc3FydChkeSpkeSArIGR4KmR4KSwKICAgICAgY29ybmVyID0gcG9pbnQyRCgocDEueDxwMC54KSA/IG9iai53aWR0aCgpIDogMCwgKHAxLnk8cDAueSkgPyBvYmouaGVpZ2h0KCkgOiAwKSwKICAgICAgc2xvcGUgPSBNYXRoLnRhbihhbmdsZSksCiAgICAgIGludmVyc2UgPSAtMS9zbG9wZSwKICAgICAgeCA9IChpbnZlcnNlKmNvcm5lci54IC0gY29ybmVyLnkgLSBzbG9wZSpwMC54ICsgcDAueSkvKGludmVyc2Utc2xvcGUpLAogICAgICBjID0ge3g6IHgsIHk6IGludmVyc2UqeCAtIGludmVyc2UqY29ybmVyLnggKyBjb3JuZXIueX0sCiAgICAgIHNlZ0EgPSAoTWF0aC5zcXJ0KCBNYXRoLnBvdyhjLngtcDAueCwyKSArIE1hdGgucG93KGMueS1wMC55LDIpKSk7CgogICAgICBmb3IgKGogPSAwOyBqPG51bUNvbG9yczsgaisrKQogICAgICAgIGNvbHMucHVzaCgnICcrY29sb3JzW2pdWzFdKycgJysoKHNlZ0EgKyBncmFkaWVudERpYWdvbmFsKmNvbG9yc1tqXVswXSkqMTAwL2RpYWdvbmFsKSsnJScpOwoKICAgICAgb2JqLmNzcyh7J2JhY2tncm91bmQtaW1hZ2UnOiB2ZW5kb3IrJ2xpbmVhci1ncmFkaWVudCgnICsgKC1hbmdsZSkgKyAncmFkLCcgKyBjb2xzLmpvaW4oJywnKSArICcpJ30pOwogIH0KfQoKCi8vIFRyaWdnZXJzIGFuIGV2ZW50CgpmdW5jdGlvbiB0cmlnZ2VyKGV2ZW50TmFtZSwgY29udGV4dCwgYXJncykgewoKICB2YXIgZXZlbnQgPSAkLkV2ZW50KGV2ZW50TmFtZSk7CiAgY29udGV4dC50cmlnZ2VyKGV2ZW50LCBhcmdzKTsKICBpZiAoZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkpCiAgICByZXR1cm4gJ3ByZXZlbnRlZCc7CiAgZWxzZSBpZiAoZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSkKICAgIHJldHVybiAnc3RvcHBlZCc7CiAgZWxzZQogICAgcmV0dXJuICcnOwp9CgovLyBKUyBFcnJvcnMKCmZ1bmN0aW9uIHR1cm5FcnJvcihtZXNzYWdlKSB7CgogIGZ1bmN0aW9uIFR1cm5Kc0Vycm9yKG1lc3NhZ2UpIHsKICAgIHRoaXMubmFtZSA9ICJUdXJuSnNFcnJvciI7CiAgICB0aGlzLm1lc3NhZ2UgPSBtZXNzYWdlOwogIH0KCiAgVHVybkpzRXJyb3IucHJvdG90eXBlID0gbmV3IEVycm9yKCk7CiAgVHVybkpzRXJyb3IucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gVHVybkpzRXJyb3I7CiAgcmV0dXJuIG5ldyBUdXJuSnNFcnJvcihtZXNzYWdlKTsKCn0KCi8vIEZpbmQgdGhlIG9mZnNldCBvZiBhbiBlbGVtZW50IGlnbm9yaW5nIGl0cyB0cmFuc2Zvcm1hdGlvbgoKZnVuY3Rpb24gZmluZFBvcyhvYmopIHsKCiAgdmFyIG9mZnNldCA9IHt0b3A6IDAsIGxlZnQ6IDB9OwoKICBkb3sKICAgIG9mZnNldC5sZWZ0ICs9IG9iai5vZmZzZXRMZWZ0OwogICAgb2Zmc2V0LnRvcCArPSBvYmoub2Zmc2V0VG9wOwogIH0gd2hpbGUgKChvYmogPSBvYmoub2Zmc2V0UGFyZW50KSk7CgogIHJldHVybiBvZmZzZXQ7Cgp9CgovLyBDaGVja3MgaWYgdGhlcmUncyBoYXJkIHBhZ2UgY29tcGF0aWJpbGl0eQovLyBJRTkgaXMgdGhlIG9ubHkgYnJvd3NlciB0aGF0IGRvZXMgbm90IHN1cHBvcnQgaGFyZCBwYWdlcwoKZnVuY3Rpb24gaGFzSGFyZFBhZ2UoKSB7CiAgcmV0dXJuIChuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ01TSUUgOS4wJyk9PS0xKTsKfQoKLy8gUmVxdWVzdCBhbiBhbmltYXRpb24KCndpbmRvdy5yZXF1ZXN0QW5pbSA9IChmdW5jdGlvbigpIHsKICByZXR1cm4gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fAogICAgd2luZG93LndlYmtpdFJlcXVlc3RBbmltYXRpb25GcmFtZSB8fAogICAgd2luZG93Lm1velJlcXVlc3RBbmltYXRpb25GcmFtZSB8fAogICAgd2luZG93Lm9SZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwKICAgIHdpbmRvdy5tc1JlcXVlc3RBbmltYXRpb25GcmFtZSB8fAogICAgZnVuY3Rpb24oY2FsbGJhY2spIHsKICAgICAgd2luZG93LnNldFRpbWVvdXQoY2FsbGJhY2ssIDEwMDAgLyA2MCk7CiAgICB9OwoKfSkoKTsKCi8vIEV4dGVuZCAkLmZuCgokLmV4dGVuZCgkLmZuLCB7CgogIGZsaXA6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIGRlYygkKHRoaXNbMF0pLCBmbGlwTWV0aG9kcywgYXJndW1lbnRzKTsKICB9LAoKICB0dXJuOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiBkZWMoJCh0aGlzWzBdKSwgdHVybk1ldGhvZHMsIGFyZ3VtZW50cyk7CiAgfSwKCiAgdHJhbnNmb3JtOiBmdW5jdGlvbih0cmFuc2Zvcm0sIG9yaWdpbikgewoKICAgIHZhciBwcm9wZXJ0aWVzID0ge307CiAgICAKICAgIGlmIChvcmlnaW4pCiAgICAgIHByb3BlcnRpZXNbdmVuZG9yKyd0cmFuc2Zvcm0tb3JpZ2luJ10gPSBvcmlnaW47CiAgICAKICAgIHByb3BlcnRpZXNbdmVuZG9yKyd0cmFuc2Zvcm0nXSA9IHRyYW5zZm9ybTsKICAKICAgIHJldHVybiB0aGlzLmNzcyhwcm9wZXJ0aWVzKTsKCiAgfSwKCiAgYW5pbWF0ZWY6IGZ1bmN0aW9uKHBvaW50KSB7CgogICAgdmFyIGRhdGEgPSB0aGlzLmRhdGEoKTsKCiAgICBpZiAoZGF0YS5lZmZlY3QpCiAgICAgIGRhdGEuZWZmZWN0LnN0b3AoKTsKCiAgICBpZiAocG9pbnQpIHsKCiAgICAgIGlmICghcG9pbnQudG8ubGVuZ3RoKSBwb2ludC50byA9IFtwb2ludC50b107CiAgICAgIGlmICghcG9pbnQuZnJvbS5sZW5ndGgpIHBvaW50LmZyb20gPSBbcG9pbnQuZnJvbV07CgogICAgICB2YXIgZGlmZiA9IFtdLAogICAgICAgIGxlbiA9IHBvaW50LnRvLmxlbmd0aCwKICAgICAgICBhbmltYXRpbmcgPSB0cnVlLAogICAgICAgIHRoYXQgPSB0aGlzLAogICAgICAgIHRpbWUgPSAobmV3IERhdGUoKSkuZ2V0VGltZSgpLAogICAgICAgIGZyYW1lID0gZnVuY3Rpb24oKSB7CgogICAgICAgICAgaWYgKCFkYXRhLmVmZmVjdCB8fCAhYW5pbWF0aW5nKQogICAgICAgICAgICByZXR1cm47CgogICAgICAgICAgdmFyIHYgPSBbXSwKICAgICAgICAgICAgdGltZURpZmYgPSBNYXRoLm1pbihwb2ludC5kdXJhdGlvbiwgKG5ldyBEYXRlKCkpLmdldFRpbWUoKSAtIHRpbWUpOwoKICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspCiAgICAgICAgICAgIHYucHVzaChkYXRhLmVmZmVjdC5lYXNpbmcoMSwgdGltZURpZmYsIHBvaW50LmZyb21baV0sIGRpZmZbaV0sIHBvaW50LmR1cmF0aW9uKSk7CgogICAgICAgICAgcG9pbnQuZnJhbWUoKGxlbj09MSkgPyB2WzBdIDogdik7CgogICAgICAgICAgaWYgKHRpbWVEaWZmPT1wb2ludC5kdXJhdGlvbikgewogICAgICAgICAgICBkZWxldGUgZGF0YVsnZWZmZWN0J107CiAgICAgICAgICAgIHRoYXQuZGF0YShkYXRhKTsKICAgICAgICAgICAgaWYgKHBvaW50LmNvbXBsZXRlKQogICAgICAgICAgICAgIHBvaW50LmNvbXBsZXRlKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB3aW5kb3cucmVxdWVzdEFuaW0oZnJhbWUpOwogICAgICAgICAgfQogICAgICAgIH07CgogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKQogICAgICAgIGRpZmYucHVzaChwb2ludC50b1tpXSAtIHBvaW50LmZyb21baV0pOwoKICAgICAgZGF0YS5lZmZlY3QgPSAkLmV4dGVuZCh7CiAgICAgICAgc3RvcDogZnVuY3Rpb24oKSB7CiAgICAgICAgICBhbmltYXRpbmcgPSBmYWxzZTsKICAgICAgICB9LAogICAgICAgIGVhc2luZzogZnVuY3Rpb24gKHgsIHQsIGIsIGMsIGRhdGEpIHsKICAgICAgICAgIHJldHVybiBjICogTWF0aC5zcXJ0KDEgLSAodD10L2RhdGEtMSkqdCkgKyBiOwogICAgICAgIH0KICAgICAgfSwgcG9pbnQpOwoKICAgICAgdGhpcy5kYXRhKGRhdGEpOwoKICAgICAgZnJhbWUoKTsKCiAgICB9IGVsc2UgewogICAgICAKICAgICAgZGVsZXRlIGRhdGFbJ2VmZmVjdCddOwoKICAgIH0KICB9Cn0pOwoKLy8gRXhwb3J0IHNvbWUgZ2xvYmFscwoKJC5pc1RvdWNoID0gaXNUb3VjaDsKJC5tb3VzZUV2ZW50cyA9IG1vdXNlRXZlbnRzOwokLmNzc1ByZWZpeCA9IGdldFByZWZpeDsKJC5jc3NUcmFuc2l0aW9uRW5kID0gZ2V0VHJhbnNpdGlvbkVuZDsKJC5maW5kUG9zID0gZmluZFBvczsKCn0pKGpRdWVyeSk7Cg==
'></script id=script_turnjs4_turn_js_end>
//


koh5_pano



Your browser does not support the HTML5 canvas element.


Drag mouse to navigate.

Navigation





17.Aug.2010, Martin Wengenmayer