LyogIFByb3RvdHlwZSBKYXZhU2NyaXB0IGZyYW1ld29yaywgdmVyc2lvbiAxLjUuMF9yYzEKICogIChjKSAyMDA1IFNhbSBTdGVwaGVuc29uIDxzYW1AY29uaW8ubmV0PgogKgogKiAgUHJvdG90eXBlIGlzIGZyZWVseSBkaXN0cmlidXRhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiBhbiBNSVQtc3R5bGUgbGljZW5zZS4KICogIEZvciBkZXRhaWxzLCBzZWUgdGhlIFByb3RvdHlwZSB3ZWIgc2l0ZTogaHR0cDovL3Byb3RvdHlwZS5jb25pby5uZXQvCiAqCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKdmFyIFByb3RvdHlwZSA9IHsKICBWZXJzaW9uOiAnMS41LjBfcmMxJywKICBCcm93c2VyRmVhdHVyZXM6IHsKICAgIFhQYXRoOiAhIWRvY3VtZW50LmV2YWx1YXRlCiAgfSwKCiAgU2NyaXB0RnJhZ21lbnQ6ICcoPzo8c2NyaXB0Lio/PikoKFxufFxyfC4pKj8pKD86PFwvc2NyaXB0PiknLAogIGVtcHR5RnVuY3Rpb246IGZ1bmN0aW9uKCkge30sCiAgSzogZnVuY3Rpb24oeCkgeyByZXR1cm4geCB9Cn0KCnZhciBDbGFzcyA9IHsKICBjcmVhdGU6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIGZ1bmN0aW9uKCkgewogICAgICB0aGlzLmluaXRpYWxpemUuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICAgIH0KICB9Cn0KCnZhciBBYnN0cmFjdCA9IG5ldyBPYmplY3QoKTsKCk9iamVjdC5leHRlbmQgPSBmdW5jdGlvbihkZXN0aW5hdGlvbiwgc291cmNlKSB7CiAgZm9yICh2YXIgcHJvcGVydHkgaW4gc291cmNlKSB7CiAgICBkZXN0aW5hdGlvbltwcm9wZXJ0eV0gPSBzb3VyY2VbcHJvcGVydHldOwogIH0KICByZXR1cm4gZGVzdGluYXRpb247Cn0KCk9iamVjdC5leHRlbmQoT2JqZWN0LCB7CiAgaW5zcGVjdDogZnVuY3Rpb24ob2JqZWN0KSB7CiAgICB0cnkgewogICAgICBpZiAob2JqZWN0ID09PSB1bmRlZmluZWQpIHJldHVybiAndW5kZWZpbmVkJzsKICAgICAgaWYgKG9iamVjdCA9PT0gbnVsbCkgcmV0dXJuICdudWxsJzsKICAgICAgcmV0dXJuIG9iamVjdC5pbnNwZWN0ID8gb2JqZWN0Lmluc3BlY3QoKSA6IG9iamVjdC50b1N0cmluZygpOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpIHJldHVybiAnLi4uJzsKICAgICAgdGhyb3cgZTsKICAgIH0KICB9LAoKICBrZXlzOiBmdW5jdGlvbihvYmplY3QpIHsKICAgIHZhciBrZXlzID0gW107CiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBvYmplY3QpCiAgICAgIGtleXMucHVzaChwcm9wZXJ0eSk7CiAgICByZXR1cm4ga2V5czsKICB9LAoKICB2YWx1ZXM6IGZ1bmN0aW9uKG9iamVjdCkgewogICAgdmFyIHZhbHVlcyA9IFtdOwogICAgZm9yICh2YXIgcHJvcGVydHkgaW4gb2JqZWN0KQogICAgICB2YWx1ZXMucHVzaChvYmplY3RbcHJvcGVydHldKTsKICAgIHJldHVybiB2YWx1ZXM7CiAgfSwKCiAgY2xvbmU6IGZ1bmN0aW9uKG9iamVjdCkgewogICAgcmV0dXJuIE9iamVjdC5leHRlbmQoe30sIG9iamVjdCk7CiAgfQp9KTsKCkZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24oKSB7CiAgdmFyIF9fbWV0aG9kID0gdGhpcywgYXJncyA9ICRBKGFyZ3VtZW50cyksIG9iamVjdCA9IGFyZ3Muc2hpZnQoKTsKICByZXR1cm4gZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gX19tZXRob2QuYXBwbHkob2JqZWN0LCBhcmdzLmNvbmNhdCgkQShhcmd1bWVudHMpKSk7CiAgfQp9CgpGdW5jdGlvbi5wcm90b3R5cGUuYmluZEFzRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKG9iamVjdCkgewogIHZhciBfX21ldGhvZCA9IHRoaXMsIGFyZ3MgPSAkQShhcmd1bWVudHMpLCBvYmplY3QgPSBhcmdzLnNoaWZ0KCk7CiAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7CiAgICByZXR1cm4gX19tZXRob2QuYXBwbHkob2JqZWN0LCBbKCBldmVudCB8fCB3aW5kb3cuZXZlbnQpXS5jb25jYXQoYXJncykuY29uY2F0KCRBKGFyZ3VtZW50cykpKTsKICB9Cn0KCk9iamVjdC5leHRlbmQoTnVtYmVyLnByb3RvdHlwZSwgewogIHRvQ29sb3JQYXJ0OiBmdW5jdGlvbigpIHsKICAgIHZhciBkaWdpdHMgPSB0aGlzLnRvU3RyaW5nKDE2KTsKICAgIGlmICh0aGlzIDwgMTYpIHJldHVybiAnMCcgKyBkaWdpdHM7CiAgICByZXR1cm4gZGlnaXRzOwogIH0sCgogIHN1Y2M6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMgKyAxOwogIH0sCgogIHRpbWVzOiBmdW5jdGlvbihpdGVyYXRvcikgewogICAgJFIoMCwgdGhpcywgdHJ1ZSkuZWFjaChpdGVyYXRvcik7CiAgICByZXR1cm4gdGhpczsKICB9Cn0pOwoKdmFyIFRyeSA9IHsKICB0aGVzZTogZnVuY3Rpb24oKSB7CiAgICB2YXIgcmV0dXJuVmFsdWU7CgogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIGxhbWJkYSA9IGFyZ3VtZW50c1tpXTsKICAgICAgdHJ5IHsKICAgICAgICByZXR1cm5WYWx1ZSA9IGxhbWJkYSgpOwogICAgICAgIGJyZWFrOwogICAgICB9IGNhdGNoIChlKSB7fQogICAgfQoKICAgIHJldHVybiByZXR1cm5WYWx1ZTsKICB9Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKdmFyIFBlcmlvZGljYWxFeGVjdXRlciA9IENsYXNzLmNyZWF0ZSgpOwpQZXJpb2RpY2FsRXhlY3V0ZXIucHJvdG90eXBlID0gewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKGNhbGxiYWNrLCBmcmVxdWVuY3kpIHsKICAgIHRoaXMuY2FsbGJhY2sgPSBjYWxsYmFjazsKICAgIHRoaXMuZnJlcXVlbmN5ID0gZnJlcXVlbmN5OwogICAgdGhpcy5jdXJyZW50bHlFeGVjdXRpbmcgPSBmYWxzZTsKCiAgICB0aGlzLnJlZ2lzdGVyQ2FsbGJhY2soKTsKICB9LAoKICByZWdpc3RlckNhbGxiYWNrOiBmdW5jdGlvbigpIHsKICAgIHRoaXMudGltZXIgPSBzZXRJbnRlcnZhbCh0aGlzLm9uVGltZXJFdmVudC5iaW5kKHRoaXMpLCB0aGlzLmZyZXF1ZW5jeSAqIDEwMDApOwogIH0sCgogIHN0b3A6IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLnRpbWVyKSByZXR1cm47CiAgICBjbGVhckludGVydmFsKHRoaXMudGltZXIpOwogICAgdGhpcy50aW1lciA9IG51bGw7CiAgfSwKCiAgb25UaW1lckV2ZW50OiBmdW5jdGlvbigpIHsKICAgIGlmICghdGhpcy5jdXJyZW50bHlFeGVjdXRpbmcpIHsKICAgICAgdHJ5IHsKICAgICAgICB0aGlzLmN1cnJlbnRseUV4ZWN1dGluZyA9IHRydWU7CiAgICAgICAgdGhpcy5jYWxsYmFjayh0aGlzKTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICB0aGlzLmN1cnJlbnRseUV4ZWN1dGluZyA9IGZhbHNlOwogICAgICB9CiAgICB9CiAgfQp9Ck9iamVjdC5leHRlbmQoU3RyaW5nLnByb3RvdHlwZSwgewogIGdzdWI6IGZ1bmN0aW9uKHBhdHRlcm4sIHJlcGxhY2VtZW50KSB7CiAgICB2YXIgcmVzdWx0ID0gJycsIHNvdXJjZSA9IHRoaXMsIG1hdGNoOwogICAgcmVwbGFjZW1lbnQgPSBhcmd1bWVudHMuY2FsbGVlLnByZXBhcmVSZXBsYWNlbWVudChyZXBsYWNlbWVudCk7CgogICAgd2hpbGUgKHNvdXJjZS5sZW5ndGggPiAwKSB7CiAgICAgIGlmIChtYXRjaCA9IHNvdXJjZS5tYXRjaChwYXR0ZXJuKSkgewogICAgICAgIHJlc3VsdCArPSBzb3VyY2Uuc2xpY2UoMCwgbWF0Y2guaW5kZXgpOwogICAgICAgIHJlc3VsdCArPSAocmVwbGFjZW1lbnQobWF0Y2gpIHx8ICcnKS50b1N0cmluZygpOwogICAgICAgIHNvdXJjZSAgPSBzb3VyY2Uuc2xpY2UobWF0Y2guaW5kZXggKyBtYXRjaFswXS5sZW5ndGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJlc3VsdCArPSBzb3VyY2UsIHNvdXJjZSA9ICcnOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gcmVzdWx0OwogIH0sCgogIHN1YjogZnVuY3Rpb24ocGF0dGVybiwgcmVwbGFjZW1lbnQsIGNvdW50KSB7CiAgICByZXBsYWNlbWVudCA9IHRoaXMuZ3N1Yi5wcmVwYXJlUmVwbGFjZW1lbnQocmVwbGFjZW1lbnQpOwogICAgY291bnQgPSBjb3VudCA9PT0gdW5kZWZpbmVkID8gMSA6IGNvdW50OwoKICAgIHJldHVybiB0aGlzLmdzdWIocGF0dGVybiwgZnVuY3Rpb24obWF0Y2gpIHsKICAgICAgaWYgKC0tY291bnQgPCAwKSByZXR1cm4gbWF0Y2hbMF07CiAgICAgIHJldHVybiByZXBsYWNlbWVudChtYXRjaCk7CiAgICB9KTsKICB9LAoKICBzY2FuOiBmdW5jdGlvbihwYXR0ZXJuLCBpdGVyYXRvcikgewogICAgdGhpcy5nc3ViKHBhdHRlcm4sIGl0ZXJhdG9yKTsKICAgIHJldHVybiB0aGlzOwogIH0sCgogIHRydW5jYXRlOiBmdW5jdGlvbihsZW5ndGgsIHRydW5jYXRpb24pIHsKICAgIGxlbmd0aCA9IGxlbmd0aCB8fCAzMDsKICAgIHRydW5jYXRpb24gPSB0cnVuY2F0aW9uID09PSB1bmRlZmluZWQgPyAnLi4uJyA6IHRydW5jYXRpb247CiAgICByZXR1cm4gdGhpcy5sZW5ndGggPiBsZW5ndGggPwogICAgICB0aGlzLnNsaWNlKDAsIGxlbmd0aCAtIHRydW5jYXRpb24ubGVuZ3RoKSArIHRydW5jYXRpb24gOiB0aGlzOwogIH0sCgogIHN0cmlwOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLnJlcGxhY2UoL15ccysvLCAnJykucmVwbGFjZSgvXHMrJC8sICcnKTsKICB9LAoKICBzdHJpcFRhZ3M6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMucmVwbGFjZSgvPFwvP1tePl0rPi9naSwgJycpOwogIH0sCgogIHN0cmlwU2NyaXB0czogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhpcy5yZXBsYWNlKG5ldyBSZWdFeHAoUHJvdG90eXBlLlNjcmlwdEZyYWdtZW50LCAnaW1nJyksICcnKTsKICB9LAoKICBleHRyYWN0U2NyaXB0czogZnVuY3Rpb24oKSB7CiAgICB2YXIgbWF0Y2hBbGwgPSBuZXcgUmVnRXhwKFByb3RvdHlwZS5TY3JpcHRGcmFnbWVudCwgJ2ltZycpOwogICAgdmFyIG1hdGNoT25lID0gbmV3IFJlZ0V4cChQcm90b3R5cGUuU2NyaXB0RnJhZ21lbnQsICdpbScpOwogICAgcmV0dXJuICh0aGlzLm1hdGNoKG1hdGNoQWxsKSB8fCBbXSkubWFwKGZ1bmN0aW9uKHNjcmlwdFRhZykgewogICAgICByZXR1cm4gKHNjcmlwdFRhZy5tYXRjaChtYXRjaE9uZSkgfHwgWycnLCAnJ10pWzFdOwogICAgfSk7CiAgfSwKCiAgZXZhbFNjcmlwdHM6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMuZXh0cmFjdFNjcmlwdHMoKS5tYXAoZnVuY3Rpb24oc2NyaXB0KSB7IHJldHVybiBldmFsKHNjcmlwdCkgfSk7CiAgfSwKCiAgZXNjYXBlSFRNTDogZnVuY3Rpb24oKSB7CiAgICB2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7CiAgICB2YXIgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRoaXMpOwogICAgZGl2LmFwcGVuZENoaWxkKHRleHQpOwogICAgcmV0dXJuIGRpdi5pbm5lckhUTUw7CiAgfSwKCiAgdW5lc2NhcGVIVE1MOiBmdW5jdGlvbigpIHsKICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgIGRpdi5pbm5lckhUTUwgPSB0aGlzLnN0cmlwVGFncygpOwogICAgcmV0dXJuIGRpdi5jaGlsZE5vZGVzWzBdID8gZGl2LmNoaWxkTm9kZXNbMF0ubm9kZVZhbHVlIDogJyc7CiAgfSwKCiAgdG9RdWVyeVBhcmFtczogZnVuY3Rpb24oKSB7CiAgICB2YXIgbWF0Y2ggPSB0aGlzLnN0cmlwKCkubWF0Y2goL1teP10qJC8pWzBdOwogICAgaWYgKCFtYXRjaCkgcmV0dXJuIHt9OwogICAgdmFyIHBhaXJzID0gbWF0Y2guc3BsaXQoJyYnKTsKICAgIHJldHVybiBwYWlycy5pbmplY3Qoe30sIGZ1bmN0aW9uKHBhcmFtcywgcGFpclN0cmluZykgewogICAgICB2YXIgcGFpciAgPSBwYWlyU3RyaW5nLnNwbGl0KCc9Jyk7CiAgICAgIHZhciB2YWx1ZSA9IHBhaXJbMV0gPyBkZWNvZGVVUklDb21wb25lbnQocGFpclsxXSkgOiB1bmRlZmluZWQ7CiAgICAgIHBhcmFtc1tkZWNvZGVVUklDb21wb25lbnQocGFpclswXSldID0gdmFsdWU7CiAgICAgIHJldHVybiBwYXJhbXM7CiAgICB9KTsKICB9LAoKICB0b0FycmF5OiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLnNwbGl0KCcnKTsKICB9LAoKICBjYW1lbGl6ZTogZnVuY3Rpb24oKSB7CiAgICB2YXIgb1N0cmluZ0xpc3QgPSB0aGlzLnNwbGl0KCctJyk7CiAgICBpZiAob1N0cmluZ0xpc3QubGVuZ3RoID09IDEpIHJldHVybiBvU3RyaW5nTGlzdFswXTsKCiAgICB2YXIgY2FtZWxpemVkU3RyaW5nID0gdGhpcy5pbmRleE9mKCctJykgPT0gMAogICAgICA/IG9TdHJpbmdMaXN0WzBdLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgb1N0cmluZ0xpc3RbMF0uc3Vic3RyaW5nKDEpCiAgICAgIDogb1N0cmluZ0xpc3RbMF07CgogICAgZm9yICh2YXIgaSA9IDEsIGxlbmd0aCA9IG9TdHJpbmdMaXN0Lmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKSB7CiAgICAgIHZhciBzID0gb1N0cmluZ0xpc3RbaV07CiAgICAgIGNhbWVsaXplZFN0cmluZyArPSBzLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgcy5zdWJzdHJpbmcoMSk7CiAgICB9CgogICAgcmV0dXJuIGNhbWVsaXplZFN0cmluZzsKICB9LAoKICBpbnNwZWN0OiBmdW5jdGlvbih1c2VEb3VibGVRdW90ZXMpIHsKICAgIHZhciBlc2NhcGVkU3RyaW5nID0gdGhpcy5yZXBsYWNlKC9cXC9nLCAnXFxcXCcpOwogICAgaWYgKHVzZURvdWJsZVF1b3RlcykKICAgICAgcmV0dXJuICciJyArIGVzY2FwZWRTdHJpbmcucmVwbGFjZSgvIi9nLCAnXFwiJykgKyAnIic7CiAgICBlbHNlCiAgICAgIHJldHVybiAiJyIgKyBlc2NhcGVkU3RyaW5nLnJlcGxhY2UoLycvZywgJ1xcXCcnKSArICInIjsKICB9Cn0pOwoKU3RyaW5nLnByb3RvdHlwZS5nc3ViLnByZXBhcmVSZXBsYWNlbWVudCA9IGZ1bmN0aW9uKHJlcGxhY2VtZW50KSB7CiAgaWYgKHR5cGVvZiByZXBsYWNlbWVudCA9PSAnZnVuY3Rpb24nKSByZXR1cm4gcmVwbGFjZW1lbnQ7CiAgdmFyIHRlbXBsYXRlID0gbmV3IFRlbXBsYXRlKHJlcGxhY2VtZW50KTsKICByZXR1cm4gZnVuY3Rpb24obWF0Y2gpIHsgcmV0dXJuIHRlbXBsYXRlLmV2YWx1YXRlKG1hdGNoKSB9Owp9CgpTdHJpbmcucHJvdG90eXBlLnBhcnNlUXVlcnkgPSBTdHJpbmcucHJvdG90eXBlLnRvUXVlcnlQYXJhbXM7Cgp2YXIgVGVtcGxhdGUgPSBDbGFzcy5jcmVhdGUoKTsKVGVtcGxhdGUuUGF0dGVybiA9IC8oXnwufFxyfFxuKSgjXHsoLio/KVx9KS87ClRlbXBsYXRlLnByb3RvdHlwZSA9IHsKICBpbml0aWFsaXplOiBmdW5jdGlvbih0ZW1wbGF0ZSwgcGF0dGVybikgewogICAgdGhpcy50ZW1wbGF0ZSA9IHRlbXBsYXRlLnRvU3RyaW5nKCk7CiAgICB0aGlzLnBhdHRlcm4gID0gcGF0dGVybiB8fCBUZW1wbGF0ZS5QYXR0ZXJuOwogIH0sCgogIGV2YWx1YXRlOiBmdW5jdGlvbihvYmplY3QpIHsKICAgIHJldHVybiB0aGlzLnRlbXBsYXRlLmdzdWIodGhpcy5wYXR0ZXJuLCBmdW5jdGlvbihtYXRjaCkgewogICAgICB2YXIgYmVmb3JlID0gbWF0Y2hbMV07CiAgICAgIGlmIChiZWZvcmUgPT0gJ1xcJykgcmV0dXJuIG1hdGNoWzJdOwogICAgICByZXR1cm4gYmVmb3JlICsgKG9iamVjdFttYXRjaFszXV0gfHwgJycpLnRvU3RyaW5nKCk7CiAgICB9KTsKICB9Cn0KCnZhciAkYnJlYWsgICAgPSBuZXcgT2JqZWN0KCk7CnZhciAkY29udGludWUgPSBuZXcgT2JqZWN0KCk7Cgp2YXIgRW51bWVyYWJsZSA9IHsKICBlYWNoOiBmdW5jdGlvbihpdGVyYXRvcikgewogICAgdmFyIGluZGV4ID0gMDsKICAgIHRyeSB7CiAgICAgIHRoaXMuX2VhY2goZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICB0cnkgewogICAgICAgICAgaXRlcmF0b3IodmFsdWUsIGluZGV4KyspOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIGlmIChlICE9ICRjb250aW51ZSkgdGhyb3cgZTsKICAgICAgICB9CiAgICAgIH0pOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSAhPSAkYnJlYWspIHRocm93IGU7CiAgICB9CiAgICByZXR1cm4gdGhpczsKICB9LAoKICBlYWNoU2xpY2U6IGZ1bmN0aW9uKG51bWJlciwgaXRlcmF0b3IpIHsKICAgIHZhciBpbmRleCA9IC1udW1iZXIsIHNsaWNlcyA9IFtdLCBhcnJheSA9IHRoaXMudG9BcnJheSgpOwogICAgd2hpbGUgKChpbmRleCArPSBudW1iZXIpIDwgYXJyYXkubGVuZ3RoKQogICAgICBzbGljZXMucHVzaChhcnJheS5zbGljZShpbmRleCwgaW5kZXgrbnVtYmVyKSk7CiAgICByZXR1cm4gc2xpY2VzLmNvbGxlY3QoaXRlcmF0b3IgfHwgUHJvdG90eXBlLkspOwogIH0sCgogIGFsbDogZnVuY3Rpb24oaXRlcmF0b3IpIHsKICAgIHZhciByZXN1bHQgPSB0cnVlOwogICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgewogICAgICByZXN1bHQgPSByZXN1bHQgJiYgISEoaXRlcmF0b3IgfHwgUHJvdG90eXBlLkspKHZhbHVlLCBpbmRleCk7CiAgICAgIGlmICghcmVzdWx0KSB0aHJvdyAkYnJlYWs7CiAgICB9KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfSwKCiAgYW55OiBmdW5jdGlvbihpdGVyYXRvcikgewogICAgdmFyIHJlc3VsdCA9IGZhbHNlOwogICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgewogICAgICBpZiAocmVzdWx0ID0gISEoaXRlcmF0b3IgfHwgUHJvdG90eXBlLkspKHZhbHVlLCBpbmRleCkpCiAgICAgICAgdGhyb3cgJGJyZWFrOwogICAgfSk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0sCgogIGNvbGxlY3Q6IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgewogICAgICByZXN1bHRzLnB1c2goaXRlcmF0b3IodmFsdWUsIGluZGV4KSk7CiAgICB9KTsKICAgIHJldHVybiByZXN1bHRzOwogIH0sCgogIGRldGVjdDogZnVuY3Rpb24oaXRlcmF0b3IpIHsKICAgIHZhciByZXN1bHQ7CiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CiAgICAgIGlmIChpdGVyYXRvcih2YWx1ZSwgaW5kZXgpKSB7CiAgICAgICAgcmVzdWx0ID0gdmFsdWU7CiAgICAgICAgdGhyb3cgJGJyZWFrOwogICAgICB9CiAgICB9KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfSwKCiAgZmluZEFsbDogZnVuY3Rpb24oaXRlcmF0b3IpIHsKICAgIHZhciByZXN1bHRzID0gW107CiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CiAgICAgIGlmIChpdGVyYXRvcih2YWx1ZSwgaW5kZXgpKQogICAgICAgIHJlc3VsdHMucHVzaCh2YWx1ZSk7CiAgICB9KTsKICAgIHJldHVybiByZXN1bHRzOwogIH0sCgogIGdyZXA6IGZ1bmN0aW9uKHBhdHRlcm4sIGl0ZXJhdG9yKSB7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgdGhpcy5lYWNoKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgewogICAgICB2YXIgc3RyaW5nVmFsdWUgPSB2YWx1ZS50b1N0cmluZygpOwogICAgICBpZiAoc3RyaW5nVmFsdWUubWF0Y2gocGF0dGVybikpCiAgICAgICAgcmVzdWx0cy5wdXNoKChpdGVyYXRvciB8fCBQcm90b3R5cGUuSykodmFsdWUsIGluZGV4KSk7CiAgICB9KQogICAgcmV0dXJuIHJlc3VsdHM7CiAgfSwKCiAgaW5jbHVkZTogZnVuY3Rpb24ob2JqZWN0KSB7CiAgICB2YXIgZm91bmQgPSBmYWxzZTsKICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSkgewogICAgICBpZiAodmFsdWUgPT0gb2JqZWN0KSB7CiAgICAgICAgZm91bmQgPSB0cnVlOwogICAgICAgIHRocm93ICRicmVhazsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gZm91bmQ7CiAgfSwKCiAgaW5Hcm91cHNPZjogZnVuY3Rpb24obnVtYmVyLCBmaWxsV2l0aCkgewogICAgZmlsbFdpdGggPSBmaWxsV2l0aCB8fCBudWxsOwogICAgdmFyIHJlc3VsdHMgPSB0aGlzLmVhY2hTbGljZShudW1iZXIpOwogICAgaWYgKHJlc3VsdHMubGVuZ3RoID4gMCkgKG51bWJlciAtIHJlc3VsdHMubGFzdCgpLmxlbmd0aCkudGltZXMoZnVuY3Rpb24oKSB7CiAgICAgIHJlc3VsdHMubGFzdCgpLnB1c2goZmlsbFdpdGgpCiAgICB9KTsKICAgIHJldHVybiByZXN1bHRzOwogIH0sCgogIGluamVjdDogZnVuY3Rpb24obWVtbywgaXRlcmF0b3IpIHsKICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKICAgICAgbWVtbyA9IGl0ZXJhdG9yKG1lbW8sIHZhbHVlLCBpbmRleCk7CiAgICB9KTsKICAgIHJldHVybiBtZW1vOwogIH0sCgogIGludm9rZTogZnVuY3Rpb24obWV0aG9kKSB7CiAgICB2YXIgYXJncyA9ICRBKGFyZ3VtZW50cykuc2xpY2UoMSk7CiAgICByZXR1cm4gdGhpcy5jb2xsZWN0KGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIHJldHVybiB2YWx1ZVttZXRob2RdLmFwcGx5KHZhbHVlLCBhcmdzKTsKICAgIH0pOwogIH0sCgogIG1heDogZnVuY3Rpb24oaXRlcmF0b3IpIHsKICAgIHZhciByZXN1bHQ7CiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CiAgICAgIHZhbHVlID0gKGl0ZXJhdG9yIHx8IFByb3RvdHlwZS5LKSh2YWx1ZSwgaW5kZXgpOwogICAgICBpZiAocmVzdWx0ID09IHVuZGVmaW5lZCB8fCB2YWx1ZSA+PSByZXN1bHQpCiAgICAgICAgcmVzdWx0ID0gdmFsdWU7CiAgICB9KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfSwKCiAgbWluOiBmdW5jdGlvbihpdGVyYXRvcikgewogICAgdmFyIHJlc3VsdDsKICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKICAgICAgdmFsdWUgPSAoaXRlcmF0b3IgfHwgUHJvdG90eXBlLkspKHZhbHVlLCBpbmRleCk7CiAgICAgIGlmIChyZXN1bHQgPT0gdW5kZWZpbmVkIHx8IHZhbHVlIDwgcmVzdWx0KQogICAgICAgIHJlc3VsdCA9IHZhbHVlOwogICAgfSk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0sCgogIHBhcnRpdGlvbjogZnVuY3Rpb24oaXRlcmF0b3IpIHsKICAgIHZhciB0cnVlcyA9IFtdLCBmYWxzZXMgPSBbXTsKICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKICAgICAgKChpdGVyYXRvciB8fCBQcm90b3R5cGUuSykodmFsdWUsIGluZGV4KSA/CiAgICAgICAgdHJ1ZXMgOiBmYWxzZXMpLnB1c2godmFsdWUpOwogICAgfSk7CiAgICByZXR1cm4gW3RydWVzLCBmYWxzZXNdOwogIH0sCgogIHBsdWNrOiBmdW5jdGlvbihwcm9wZXJ0eSkgewogICAgdmFyIHJlc3VsdHMgPSBbXTsKICAgIHRoaXMuZWFjaChmdW5jdGlvbih2YWx1ZSwgaW5kZXgpIHsKICAgICAgcmVzdWx0cy5wdXNoKHZhbHVlW3Byb3BlcnR5XSk7CiAgICB9KTsKICAgIHJldHVybiByZXN1bHRzOwogIH0sCgogIHJlamVjdDogZnVuY3Rpb24oaXRlcmF0b3IpIHsKICAgIHZhciByZXN1bHRzID0gW107CiAgICB0aGlzLmVhY2goZnVuY3Rpb24odmFsdWUsIGluZGV4KSB7CiAgICAgIGlmICghaXRlcmF0b3IodmFsdWUsIGluZGV4KSkKICAgICAgICByZXN1bHRzLnB1c2godmFsdWUpOwogICAgfSk7CiAgICByZXR1cm4gcmVzdWx0czsKICB9LAoKICBzb3J0Qnk6IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CiAgICByZXR1cm4gdGhpcy5jb2xsZWN0KGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgewogICAgICByZXR1cm4ge3ZhbHVlOiB2YWx1ZSwgY3JpdGVyaWE6IGl0ZXJhdG9yKHZhbHVlLCBpbmRleCl9OwogICAgfSkuc29ydChmdW5jdGlvbihsZWZ0LCByaWdodCkgewogICAgICB2YXIgYSA9IGxlZnQuY3JpdGVyaWEsIGIgPSByaWdodC5jcml0ZXJpYTsKICAgICAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiAwOwogICAgfSkucGx1Y2soJ3ZhbHVlJyk7CiAgfSwKCiAgdG9BcnJheTogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhpcy5jb2xsZWN0KFByb3RvdHlwZS5LKTsKICB9LAoKICB6aXA6IGZ1bmN0aW9uKCkgewogICAgdmFyIGl0ZXJhdG9yID0gUHJvdG90eXBlLkssIGFyZ3MgPSAkQShhcmd1bWVudHMpOwogICAgaWYgKHR5cGVvZiBhcmdzLmxhc3QoKSA9PSAnZnVuY3Rpb24nKQogICAgICBpdGVyYXRvciA9IGFyZ3MucG9wKCk7CgogICAgdmFyIGNvbGxlY3Rpb25zID0gW3RoaXNdLmNvbmNhdChhcmdzKS5tYXAoJEEpOwogICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkgewogICAgICByZXR1cm4gaXRlcmF0b3IoY29sbGVjdGlvbnMucGx1Y2soaW5kZXgpKTsKICAgIH0pOwogIH0sCgogIGluc3BlY3Q6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuICcjPEVudW1lcmFibGU6JyArIHRoaXMudG9BcnJheSgpLmluc3BlY3QoKSArICc+JzsKICB9Cn0KCk9iamVjdC5leHRlbmQoRW51bWVyYWJsZSwgewogIG1hcDogICAgIEVudW1lcmFibGUuY29sbGVjdCwKICBmaW5kOiAgICBFbnVtZXJhYmxlLmRldGVjdCwKICBzZWxlY3Q6ICBFbnVtZXJhYmxlLmZpbmRBbGwsCiAgbWVtYmVyOiAgRW51bWVyYWJsZS5pbmNsdWRlLAogIGVudHJpZXM6IEVudW1lcmFibGUudG9BcnJheQp9KTsKdmFyICRBID0gQXJyYXkuZnJvbSA9IGZ1bmN0aW9uKGl0ZXJhYmxlKSB7CiAgaWYgKCFpdGVyYWJsZSkgcmV0dXJuIFtdOwogIGlmIChpdGVyYWJsZS50b0FycmF5KSB7CiAgICByZXR1cm4gaXRlcmFibGUudG9BcnJheSgpOwogIH0gZWxzZSB7CiAgICB2YXIgcmVzdWx0cyA9IFtdOwogICAgZm9yICh2YXIgaSA9IDAsIGxlbmd0aCA9IGl0ZXJhYmxlLmxlbmd0aDsgaSA8IGxlbmd0aDsgaSsrKQogICAgICByZXN1bHRzLnB1c2goaXRlcmFibGVbaV0pOwogICAgcmV0dXJuIHJlc3VsdHM7CiAgfQp9CgpPYmplY3QuZXh0ZW5kKEFycmF5LnByb3RvdHlwZSwgRW51bWVyYWJsZSk7CgppZiAoIUFycmF5LnByb3RvdHlwZS5fcmV2ZXJzZSkKICBBcnJheS5wcm90b3R5cGUuX3JldmVyc2UgPSBBcnJheS5wcm90b3R5cGUucmV2ZXJzZTsKCk9iamVjdC5leHRlbmQoQXJyYXkucHJvdG90eXBlLCB7CiAgX2VhY2g6IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gdGhpcy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykKICAgICAgaXRlcmF0b3IodGhpc1tpXSk7CiAgfSwKCiAgY2xlYXI6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5sZW5ndGggPSAwOwogICAgcmV0dXJuIHRoaXM7CiAgfSwKCiAgZmlyc3Q6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXNbMF07CiAgfSwKCiAgbGFzdDogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhpc1t0aGlzLmxlbmd0aCAtIDFdOwogIH0sCgogIGNvbXBhY3Q6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIHJldHVybiB2YWx1ZSAhPSB1bmRlZmluZWQgfHwgdmFsdWUgIT0gbnVsbDsKICAgIH0pOwogIH0sCgogIGZsYXR0ZW46IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMuaW5qZWN0KFtdLCBmdW5jdGlvbihhcnJheSwgdmFsdWUpIHsKICAgICAgcmV0dXJuIGFycmF5LmNvbmNhdCh2YWx1ZSAmJiB2YWx1ZS5jb25zdHJ1Y3RvciA9PSBBcnJheSA/CiAgICAgICAgdmFsdWUuZmxhdHRlbigpIDogW3ZhbHVlXSk7CiAgICB9KTsKICB9LAoKICB3aXRob3V0OiBmdW5jdGlvbigpIHsKICAgIHZhciB2YWx1ZXMgPSAkQShhcmd1bWVudHMpOwogICAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uKHZhbHVlKSB7CiAgICAgIHJldHVybiAhdmFsdWVzLmluY2x1ZGUodmFsdWUpOwogICAgfSk7CiAgfSwKCiAgaW5kZXhPZjogZnVuY3Rpb24ob2JqZWN0KSB7CiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gdGhpcy5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykKICAgICAgaWYgKHRoaXNbaV0gPT0gb2JqZWN0KSByZXR1cm4gaTsKICAgIHJldHVybiAtMTsKICB9LAoKICByZXZlcnNlOiBmdW5jdGlvbihpbmxpbmUpIHsKICAgIHJldHVybiAoaW5saW5lICE9PSBmYWxzZSA/IHRoaXMgOiB0aGlzLnRvQXJyYXkoKSkuX3JldmVyc2UoKTsKICB9LAoKICByZWR1Y2U6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMubGVuZ3RoID4gMSA/IHRoaXMgOiB0aGlzWzBdOwogIH0sCgogIHVuaXE6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMuaW5qZWN0KFtdLCBmdW5jdGlvbihhcnJheSwgdmFsdWUpIHsKICAgICAgcmV0dXJuIGFycmF5LmluY2x1ZGUodmFsdWUpID8gYXJyYXkgOiBhcnJheS5jb25jYXQoW3ZhbHVlXSk7CiAgICB9KTsKICB9LAoKICBjbG9uZTogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gW10uY29uY2F0KHRoaXMpOwogIH0sCgogIGluc3BlY3Q6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuICdbJyArIHRoaXMubWFwKE9iamVjdC5pbnNwZWN0KS5qb2luKCcsICcpICsgJ10nOwogIH0KfSk7CgpBcnJheS5wcm90b3R5cGUudG9BcnJheSA9IEFycmF5LnByb3RvdHlwZS5jbG9uZTsKdmFyIEhhc2ggPSB7CiAgX2VhY2g6IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CiAgICBmb3IgKHZhciBrZXkgaW4gdGhpcykgewogICAgICB2YXIgdmFsdWUgPSB0aGlzW2tleV07CiAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gJ2Z1bmN0aW9uJykgY29udGludWU7CgogICAgICB2YXIgcGFpciA9IFtrZXksIHZhbHVlXTsKICAgICAgcGFpci5rZXkgPSBrZXk7CiAgICAgIHBhaXIudmFsdWUgPSB2YWx1ZTsKICAgICAgaXRlcmF0b3IocGFpcik7CiAgICB9CiAgfSwKCiAga2V5czogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gdGhpcy5wbHVjaygna2V5Jyk7CiAgfSwKCiAgdmFsdWVzOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLnBsdWNrKCd2YWx1ZScpOwogIH0sCgogIG1lcmdlOiBmdW5jdGlvbihoYXNoKSB7CiAgICByZXR1cm4gJEgoaGFzaCkuaW5qZWN0KHRoaXMsIGZ1bmN0aW9uKG1lcmdlZEhhc2gsIHBhaXIpIHsKICAgICAgbWVyZ2VkSGFzaFtwYWlyLmtleV0gPSBwYWlyLnZhbHVlOwogICAgICByZXR1cm4gbWVyZ2VkSGFzaDsKICAgIH0pOwogIH0sCgogIHRvUXVlcnlTdHJpbmc6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKHBhaXIpIHsKICAgICAgaWYgKCFwYWlyLnZhbHVlICYmIHBhaXIudmFsdWUgIT09IDApIHBhaXJbMV0gPSAnJzsKICAgICAgaWYgKCFwYWlyLmtleSkgcmV0dXJuOwogICAgICByZXR1cm4gcGFpci5tYXAoZW5jb2RlVVJJQ29tcG9uZW50KS5qb2luKCc9Jyk7CiAgICB9KS5qb2luKCcmJyk7CiAgfSwKCiAgaW5zcGVjdDogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gJyM8SGFzaDp7JyArIHRoaXMubWFwKGZ1bmN0aW9uKHBhaXIpIHsKICAgICAgcmV0dXJuIHBhaXIubWFwKE9iamVjdC5pbnNwZWN0KS5qb2luKCc6ICcpOwogICAgfSkuam9pbignLCAnKSArICd9Pic7CiAgfQp9CgpmdW5jdGlvbiAkSChvYmplY3QpIHsKICB2YXIgaGFzaCA9IE9iamVjdC5leHRlbmQoe30sIG9iamVjdCB8fCB7fSk7CiAgT2JqZWN0LmV4dGVuZChoYXNoLCBFbnVtZXJhYmxlKTsKICBPYmplY3QuZXh0ZW5kKGhhc2gsIEhhc2gpOwogIHJldHVybiBoYXNoOwp9Ck9iamVjdFJhbmdlID0gQ2xhc3MuY3JlYXRlKCk7Ck9iamVjdC5leHRlbmQoT2JqZWN0UmFuZ2UucHJvdG90eXBlLCBFbnVtZXJhYmxlKTsKT2JqZWN0LmV4dGVuZChPYmplY3RSYW5nZS5wcm90b3R5cGUsIHsKICBpbml0aWFsaXplOiBmdW5jdGlvbihzdGFydCwgZW5kLCBleGNsdXNpdmUpIHsKICAgIHRoaXMuc3RhcnQgPSBzdGFydDsKICAgIHRoaXMuZW5kID0gZW5kOwogICAgdGhpcy5leGNsdXNpdmUgPSBleGNsdXNpdmU7CiAgfSwKCiAgX2VhY2g6IGZ1bmN0aW9uKGl0ZXJhdG9yKSB7CiAgICB2YXIgdmFsdWUgPSB0aGlzLnN0YXJ0OwogICAgd2hpbGUgKHRoaXMuaW5jbHVkZSh2YWx1ZSkpIHsKICAgICAgaXRlcmF0b3IodmFsdWUpOwogICAgICB2YWx1ZSA9IHZhbHVlLnN1Y2MoKTsKICAgIH0KICB9LAoKICBpbmNsdWRlOiBmdW5jdGlvbih2YWx1ZSkgewogICAgaWYgKHZhbHVlIDwgdGhpcy5zdGFydCkKICAgICAgcmV0dXJuIGZhbHNlOwogICAgaWYgKHRoaXMuZXhjbHVzaXZlKQogICAgICByZXR1cm4gdmFsdWUgPCB0aGlzLmVuZDsKICAgIHJldHVybiB2YWx1ZSA8PSB0aGlzLmVuZDsKICB9Cn0pOwoKdmFyICRSID0gZnVuY3Rpb24oc3RhcnQsIGVuZCwgZXhjbHVzaXZlKSB7CiAgcmV0dXJuIG5ldyBPYmplY3RSYW5nZShzdGFydCwgZW5kLCBleGNsdXNpdmUpOwp9Cgp2YXIgQWpheCA9IHsKICBnZXRUcmFuc3BvcnQ6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIFRyeS50aGVzZSgKICAgICAgZnVuY3Rpb24oKSB7cmV0dXJuIG5ldyBYTUxIdHRwUmVxdWVzdCgpfSwKICAgICAgZnVuY3Rpb24oKSB7cmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNc3htbDIuWE1MSFRUUCcpfSwKICAgICAgZnVuY3Rpb24oKSB7cmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KCdNaWNyb3NvZnQuWE1MSFRUUCcpfQogICAgKSB8fCBmYWxzZTsKICB9LAoKICBhY3RpdmVSZXF1ZXN0Q291bnQ6IDAKfQoKQWpheC5SZXNwb25kZXJzID0gewogIHJlc3BvbmRlcnM6IFtdLAoKICBfZWFjaDogZnVuY3Rpb24oaXRlcmF0b3IpIHsKICAgIHRoaXMucmVzcG9uZGVycy5fZWFjaChpdGVyYXRvcik7CiAgfSwKCiAgcmVnaXN0ZXI6IGZ1bmN0aW9uKHJlc3BvbmRlcikgewogICAgaWYgKCF0aGlzLmluY2x1ZGUocmVzcG9uZGVyKSkKICAgICAgdGhpcy5yZXNwb25kZXJzLnB1c2gocmVzcG9uZGVyKTsKICB9LAoKICB1bnJlZ2lzdGVyOiBmdW5jdGlvbihyZXNwb25kZXIpIHsKICAgIHRoaXMucmVzcG9uZGVycyA9IHRoaXMucmVzcG9uZGVycy53aXRob3V0KHJlc3BvbmRlcik7CiAgfSwKCiAgZGlzcGF0Y2g6IGZ1bmN0aW9uKGNhbGxiYWNrLCByZXF1ZXN0LCB0cmFuc3BvcnQsIGpzb24pIHsKICAgIHRoaXMuZWFjaChmdW5jdGlvbihyZXNwb25kZXIpIHsKICAgICAgaWYgKHR5cGVvZiByZXNwb25kZXJbY2FsbGJhY2tdID09ICdmdW5jdGlvbicpIHsKICAgICAgICB0cnkgewogICAgICAgICAgcmVzcG9uZGVyW2NhbGxiYWNrXS5hcHBseShyZXNwb25kZXIsIFtyZXF1ZXN0LCB0cmFuc3BvcnQsIGpzb25dKTsKICAgICAgICB9IGNhdGNoIChlKSB7fQogICAgICB9CiAgICB9KTsKICB9Cn07CgpPYmplY3QuZXh0ZW5kKEFqYXguUmVzcG9uZGVycywgRW51bWVyYWJsZSk7CgpBamF4LlJlc3BvbmRlcnMucmVnaXN0ZXIoewogIG9uQ3JlYXRlOiBmdW5jdGlvbigpIHsKICAgIEFqYXguYWN0aXZlUmVxdWVzdENvdW50Kys7CiAgfSwKICBvbkNvbXBsZXRlOiBmdW5jdGlvbigpIHsKICAgIEFqYXguYWN0aXZlUmVxdWVzdENvdW50LS07CiAgfQp9KTsKCkFqYXguQmFzZSA9IGZ1bmN0aW9uKCkge307CkFqYXguQmFzZS5wcm90b3R5cGUgPSB7CiAgc2V0T3B0aW9uczogZnVuY3Rpb24ob3B0aW9ucykgewogICAgdGhpcy5vcHRpb25zID0gewogICAgICBtZXRob2Q6ICAgICAgICdwb3N0JywKICAgICAgYXN5bmNocm9ub3VzOiB0cnVlLAogICAgICBjb250ZW50VHlwZTogICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQnLAogICAgICBlbmNvZGluZzogICAgICdVVEYtOCcsCiAgICAgIHBhcmFtZXRlcnM6ICAgJycKICAgIH0KICAgIE9iamVjdC5leHRlbmQodGhpcy5vcHRpb25zLCBvcHRpb25zIHx8IHt9KTsKCiAgICB0aGlzLm9wdGlvbnMubWV0aG9kID0gdGhpcy5vcHRpb25zLm1ldGhvZC50b0xvd2VyQ2FzZSgpOwogICAgdGhpcy5vcHRpb25zLnBhcmFtZXRlcnMgPSAkSCh0eXBlb2YgdGhpcy5vcHRpb25zLnBhcmFtZXRlcnMgPT0gJ3N0cmluZycgPwogICAgICB0aGlzLm9wdGlvbnMucGFyYW1ldGVycy50b1F1ZXJ5UGFyYW1zKCkgOiB0aGlzLm9wdGlvbnMucGFyYW1ldGVycyk7CiAgfQp9CgpBamF4LlJlcXVlc3QgPSBDbGFzcy5jcmVhdGUoKTsKQWpheC5SZXF1ZXN0LkV2ZW50cyA9CiAgWydVbmluaXRpYWxpemVkJywgJ0xvYWRpbmcnLCAnTG9hZGVkJywgJ0ludGVyYWN0aXZlJywgJ0NvbXBsZXRlJ107CgpBamF4LlJlcXVlc3QucHJvdG90eXBlID0gT2JqZWN0LmV4dGVuZChuZXcgQWpheC5CYXNlKCksIHsKICBpbml0aWFsaXplOiBmdW5jdGlvbih1cmwsIG9wdGlvbnMpIHsKICAgIHRoaXMudHJhbnNwb3J0ID0gQWpheC5nZXRUcmFuc3BvcnQoKTsKICAgIHRoaXMuc2V0T3B0aW9ucyhvcHRpb25zKTsKICAgIHRoaXMucmVxdWVzdCh1cmwpOwogIH0sCgogIHJlcXVlc3Q6IGZ1bmN0aW9uKHVybCkgewogICAgdmFyIHBhcmFtcyA9IHRoaXMub3B0aW9ucy5wYXJhbWV0ZXJzOwogICAgaWYgKHBhcmFtcy5hbnkoKSkgcGFyYW1zWydfJ10gPSAnJzsKCiAgICBpZiAoIVsnZ2V0JywgJ3Bvc3QnXS5pbmNsdWRlKHRoaXMub3B0aW9ucy5tZXRob2QpKSB7CiAgICAgIC8vIHNpbXVsYXRlIG90aGVyIHZlcmJzIG92ZXIgcG9zdAogICAgICBwYXJhbXNbJ19tZXRob2QnXSA9IHRoaXMub3B0aW9ucy5tZXRob2Q7CiAgICAgIHRoaXMub3B0aW9ucy5tZXRob2QgPSAncG9zdCc7CiAgICB9CgogICAgdGhpcy51cmwgPSB1cmw7CgogICAgLy8gd2hlbiBHRVQsIGFwcGVuZCBwYXJhbWV0ZXJzIHRvIFVSTAogICAgaWYgKHRoaXMub3B0aW9ucy5tZXRob2QgPT0gJ2dldCcgJiYgcGFyYW1zLmFueSgpKQogICAgICB0aGlzLnVybCArPSAodGhpcy51cmwuaW5kZXhPZignPycpID49IDAgPyAnJicgOiAnPycpICsKICAgICAgICBwYXJhbXMudG9RdWVyeVN0cmluZygpOwoKICAgIHRyeSB7CiAgICAgIEFqYXguUmVzcG9uZGVycy5kaXNwYXRjaCgnb25DcmVhdGUnLCB0aGlzLCB0aGlzLnRyYW5zcG9ydCk7CgogICAgICB0aGlzLnRyYW5zcG9ydC5vcGVuKHRoaXMub3B0aW9ucy5tZXRob2QudG9VcHBlckNhc2UoKSwgdGhpcy51cmwsCiAgICAgICAgdGhpcy5vcHRpb25zLmFzeW5jaHJvbm91cywgdGhpcy5vcHRpb25zLnVzZXJuYW1lLAogICAgICAgIHRoaXMub3B0aW9ucy5wYXNzd29yZCk7CgogICAgICBpZiAodGhpcy5vcHRpb25zLmFzeW5jaHJvbm91cykKICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyB0aGlzLnJlc3BvbmRUb1JlYWR5U3RhdGUoMSkgfS5iaW5kKHRoaXMpLCAxMCk7CgogICAgICB0aGlzLnRyYW5zcG9ydC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSB0aGlzLm9uU3RhdGVDaGFuZ2UuYmluZCh0aGlzKTsKICAgICAgdGhpcy5zZXRSZXF1ZXN0SGVhZGVycygpOwoKICAgICAgdmFyIGJvZHkgPSB0aGlzLm9wdGlvbnMubWV0aG9kID09ICdwb3N0JyA/CiAgICAgICAgKHRoaXMub3B0aW9ucy5wb3N0Qm9keSB8fCBwYXJhbXMudG9RdWVyeVN0cmluZygpKSA6IG51bGw7CgogICAgICB0aGlzLnRyYW5zcG9ydC5zZW5kKGJvZHkpOwoKICAgICAgLyogRm9yY2UgRmlyZWZveCB0byBoYW5kbGUgcmVhZHkgc3RhdGUgNCBmb3Igc3luY2hyb25vdXMgcmVxdWVzdHMgKi8KICAgICAgaWYgKCF0aGlzLm9wdGlvbnMuYXN5bmNocm9ub3VzICYmIHRoaXMudHJhbnNwb3J0Lm92ZXJyaWRlTWltZVR5cGUpCiAgICAgICAgdGhpcy5vblN0YXRlQ2hhbmdlKCk7CiAgICB9CiAgICBjYXRjaCAoZSkgewogICAgICB0aGlzLmRpc3BhdGNoRXhjZXB0aW9uKGUpOwogICAgfQogIH0sCgogIG9uU3RhdGVDaGFuZ2U6IGZ1bmN0aW9uKCkgewogICAgdmFyIHJlYWR5U3RhdGUgPSB0aGlzLnRyYW5zcG9ydC5yZWFkeVN0YXRlOwogICAgaWYgKHJlYWR5U3RhdGUgPiAxKQogICAgICB0aGlzLnJlc3BvbmRUb1JlYWR5U3RhdGUodGhpcy50cmFuc3BvcnQucmVhZHlTdGF0ZSk7CiAgfSwKCiAgc2V0UmVxdWVzdEhlYWRlcnM6IGZ1bmN0aW9uKCkgewogICAgdmFyIGhlYWRlcnMgPSB7CiAgICAgICdYLVJlcXVlc3RlZC1XaXRoJzogJ1hNTEh0dHBSZXF1ZXN0JywKICAgICAgJ1gtUHJvdG90eXBlLVZlcnNpb24nOiBQcm90b3R5cGUuVmVyc2lvbiwKICAgICAgJ0FjY2VwdCc6ICd0ZXh0L2phdmFzY3JpcHQsIHRleHQvaHRtbCwgYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbCwgKi8qJwogICAgfTsKCiAgICBpZiAodGhpcy5vcHRpb25zLm1ldGhvZCA9PSAncG9zdCcpIHsKICAgICAgaGVhZGVyc1snQ29udGVudC10eXBlJ10gPSB0aGlzLm9wdGlvbnMuY29udGVudFR5cGUgKwogICAgICAgICh0aGlzLm9wdGlvbnMuZW5jb2RpbmcgPyAnOyBjaGFyc2V0PScgKyB0aGlzLm9wdGlvbnMuZW5jb2RpbmcgOiAnJyk7CgogICAgICAvKiBGb3JjZSAiQ29ubmVjdGlvbjogY2xvc2UiIGZvciBvbGRlciBNb3ppbGxhIGJyb3dzZXJzIHRvIHdvcmsKICAgICAgICogYXJvdW5kIGEgYnVnIHdoZXJlIFhNTEh0dHBSZXF1ZXN0IHNlbmRzIGFuIGluY29ycmVjdAogICAgICAgKiBDb250ZW50LWxlbmd0aCBoZWFkZXIuIFNlZSBNb3ppbGxhIEJ1Z3ppbGxhICMyNDY2NTEuCiAgICAgICAqLwogICAgICBpZiAodGhpcy50cmFuc3BvcnQub3ZlcnJpZGVNaW1lVHlwZSAmJgogICAgICAgICAgKG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0dlY2tvXC8oXGR7NH0pLykgfHwgWzAsMjAwNV0pWzFdIDwgMjAwNSkKICAgICAgICAgICAgaGVhZGVyc1snQ29ubmVjdGlvbiddID0gJ2Nsb3NlJzsKICAgIH0KCiAgICAvLyB1c2VyLWRlZmluZWQgaGVhZGVycwogICAgaWYgKHR5cGVvZiB0aGlzLm9wdGlvbnMucmVxdWVzdEhlYWRlcnMgPT0gJ29iamVjdCcpIHsKICAgICAgdmFyIGV4dHJhcyA9IHRoaXMub3B0aW9ucy5yZXF1ZXN0SGVhZGVyczsKCiAgICAgIGlmICh0eXBlb2YgZXh0cmFzLnB1c2ggPT0gJ2Z1bmN0aW9uJykKICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGV4dHJhcy5sZW5ndGg7IGkgKz0gMikKICAgICAgICAgIGhlYWRlcnNbZXh0cmFzW2ldXSA9IGV4dHJhc1tpKzFdOwogICAgICBlbHNlCiAgICAgICAgJEgoZXh0cmFzKS5lYWNoKGZ1bmN0aW9uKHBhaXIpIHsgaGVhZGVyc1twYWlyLmtleV0gPSBwYWlyLnZhbHVlIH0pOwogICAgfQoKICAgIGZvciAodmFyIG5hbWUgaW4gaGVhZGVycykKICAgICAgdGhpcy50cmFuc3BvcnQuc2V0UmVxdWVzdEhlYWRlcihuYW1lLCBoZWFkZXJzW25hbWVdKTsKICB9LAoKICBzdWNjZXNzOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiAhdGhpcy50cmFuc3BvcnQuc3RhdHVzCiAgICAgICAgfHwgKHRoaXMudHJhbnNwb3J0LnN0YXR1cyA+PSAyMDAgJiYgdGhpcy50cmFuc3BvcnQuc3RhdHVzIDwgMzAwKTsKICB9LAoKICByZXNwb25kVG9SZWFkeVN0YXRlOiBmdW5jdGlvbihyZWFkeVN0YXRlKSB7CiAgICB2YXIgc3RhdGUgPSBBamF4LlJlcXVlc3QuRXZlbnRzW3JlYWR5U3RhdGVdOwogICAgdmFyIHRyYW5zcG9ydCA9IHRoaXMudHJhbnNwb3J0LCBqc29uID0gdGhpcy5ldmFsSlNPTigpOwoKICAgIGlmIChzdGF0ZSA9PSAnQ29tcGxldGUnKSB7CiAgICAgIHRyeSB7CiAgICAgICAgKHRoaXMub3B0aW9uc1snb24nICsgdGhpcy50cmFuc3BvcnQuc3RhdHVzXQogICAgICAgICB8fCB0aGlzLm9wdGlvbnNbJ29uJyArICh0aGlzLnN1Y2Nlc3MoKSA/ICdTdWNjZXNzJyA6ICdGYWlsdXJlJyldCiAgICAgICAgIHx8IFByb3RvdHlwZS5lbXB0eUZ1bmN0aW9uKSh0cmFuc3BvcnQsIGpzb24pOwogICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgdGhpcy5kaXNwYXRjaEV4Y2VwdGlvbihlKTsKICAgICAgfQogICAgfQoKICAgIHRyeSB7CiAgICAgICh0aGlzLm9wdGlvbnNbJ29uJyArIHN0YXRlXSB8fCBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbikodHJhbnNwb3J0LCBqc29uKTsKICAgICAgQWpheC5SZXNwb25kZXJzLmRpc3BhdGNoKCdvbicgKyBzdGF0ZSwgdGhpcywgdHJhbnNwb3J0LCBqc29uKTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgdGhpcy5kaXNwYXRjaEV4Y2VwdGlvbihlKTsKICAgIH0KCiAgICBpZiAoc3RhdGUgPT0gJ0NvbXBsZXRlJykgewogICAgICBpZiAoKHRoaXMuZ2V0SGVhZGVyKCdDb250ZW50LXR5cGUnKSB8fCAnJykuc3RyaXAoKS4KICAgICAgICBtYXRjaCgvXih0ZXh0fGFwcGxpY2F0aW9uKVwvKHgtKT8oamF2YXxlY21hKXNjcmlwdCg7LiopPyQvaSkpCiAgICAgICAgICB0aGlzLmV2YWxSZXNwb25zZSgpOwoKICAgICAgLy8gYXZvaWQgbWVtb3J5IGxlYWsgaW4gTVNJRTogY2xlYW4gdXAKICAgICAgdGhpcy50cmFuc3BvcnQub25yZWFkeXN0YXRlY2hhbmdlID0gUHJvdG90eXBlLmVtcHR5RnVuY3Rpb247CiAgICB9CiAgfSwKCiAgZ2V0SGVhZGVyOiBmdW5jdGlvbihuYW1lKSB7CiAgICB0cnkgewogICAgICByZXR1cm4gdGhpcy50cmFuc3BvcnQuZ2V0UmVzcG9uc2VIZWFkZXIobmFtZSk7CiAgICB9IGNhdGNoIChlKSB7IHJldHVybiBudWxsIH0KICB9LAoKICBldmFsSlNPTjogZnVuY3Rpb24oKSB7CiAgICB0cnkgewogICAgICB2YXIganNvbiA9IHRoaXMuZ2V0SGVhZGVyKCdYLUpTT04nKTsKICAgICAgcmV0dXJuIGpzb24gPyBldmFsKCcoJyArIGpzb24gKyAnKScpIDogbnVsbDsKICAgIH0gY2F0Y2ggKGUpIHsgcmV0dXJuIG51bGwgfQogIH0sCgogIGV2YWxSZXNwb25zZTogZnVuY3Rpb24oKSB7CiAgICB0cnkgewogICAgICByZXR1cm4gZXZhbCh0aGlzLnRyYW5zcG9ydC5yZXNwb25zZVRleHQpOwogICAgfSBjYXRjaCAoZSkgewogICAgICB0aGlzLmRpc3BhdGNoRXhjZXB0aW9uKGUpOwogICAgfQogIH0sCgogIGRpc3BhdGNoRXhjZXB0aW9uOiBmdW5jdGlvbihleGNlcHRpb24pIHsKICAgICh0aGlzLm9wdGlvbnMub25FeGNlcHRpb24gfHwgUHJvdG90eXBlLmVtcHR5RnVuY3Rpb24pKHRoaXMsIGV4Y2VwdGlvbik7CiAgICBBamF4LlJlc3BvbmRlcnMuZGlzcGF0Y2goJ29uRXhjZXB0aW9uJywgdGhpcywgZXhjZXB0aW9uKTsKICB9Cn0pOwoKQWpheC5VcGRhdGVyID0gQ2xhc3MuY3JlYXRlKCk7CgpPYmplY3QuZXh0ZW5kKE9iamVjdC5leHRlbmQoQWpheC5VcGRhdGVyLnByb3RvdHlwZSwgQWpheC5SZXF1ZXN0LnByb3RvdHlwZSksIHsKICBpbml0aWFsaXplOiBmdW5jdGlvbihjb250YWluZXIsIHVybCwgb3B0aW9ucykgewogICAgdGhpcy5jb250YWluZXIgPSB7CiAgICAgIHN1Y2Nlc3M6IChjb250YWluZXIuc3VjY2VzcyB8fCBjb250YWluZXIpLAogICAgICBmYWlsdXJlOiAoY29udGFpbmVyLmZhaWx1cmUgfHwgKGNvbnRhaW5lci5zdWNjZXNzID8gbnVsbCA6IGNvbnRhaW5lcikpCiAgICB9CgogICAgdGhpcy50cmFuc3BvcnQgPSBBamF4LmdldFRyYW5zcG9ydCgpOwogICAgdGhpcy5zZXRPcHRpb25zKG9wdGlvbnMpOwoKICAgIHZhciBvbkNvbXBsZXRlID0gdGhpcy5vcHRpb25zLm9uQ29tcGxldGUgfHwgUHJvdG90eXBlLmVtcHR5RnVuY3Rpb247CiAgICB0aGlzLm9wdGlvbnMub25Db21wbGV0ZSA9IChmdW5jdGlvbih0cmFuc3BvcnQsIHBhcmFtKSB7CiAgICAgIHRoaXMudXBkYXRlQ29udGVudCgpOwogICAgICBvbkNvbXBsZXRlKHRyYW5zcG9ydCwgcGFyYW0pOwogICAgfSkuYmluZCh0aGlzKTsKCiAgICB0aGlzLnJlcXVlc3QodXJsKTsKICB9LAoKICB1cGRhdGVDb250ZW50OiBmdW5jdGlvbigpIHsKICAgIHZhciByZWNlaXZlciA9IHRoaXMuY29udGFpbmVyW3RoaXMuc3VjY2VzcygpID8gJ3N1Y2Nlc3MnIDogJ2ZhaWx1cmUnXTsKICAgIHZhciByZXNwb25zZSA9IHRoaXMudHJhbnNwb3J0LnJlc3BvbnNlVGV4dDsKCiAgICBpZiAoIXRoaXMub3B0aW9ucy5ldmFsU2NyaXB0cykgcmVzcG9uc2UgPSByZXNwb25zZS5zdHJpcFNjcmlwdHMoKTsKCiAgICBpZiAocmVjZWl2ZXIgPSAkKHJlY2VpdmVyKSkgewogICAgICBpZiAodGhpcy5vcHRpb25zLmluc2VydGlvbikKICAgICAgICBuZXcgdGhpcy5vcHRpb25zLmluc2VydGlvbihyZWNlaXZlciwgcmVzcG9uc2UpOwogICAgICBlbHNlCiAgICAgICAgcmVjZWl2ZXIudXBkYXRlKHJlc3BvbnNlKTsKICAgIH0KCiAgICBpZiAodGhpcy5zdWNjZXNzKCkpIHsKICAgICAgaWYgKHRoaXMub25Db21wbGV0ZSkKICAgICAgICBzZXRUaW1lb3V0KHRoaXMub25Db21wbGV0ZS5iaW5kKHRoaXMpLCAxMCk7CiAgICB9CiAgfQp9KTsKCkFqYXguUGVyaW9kaWNhbFVwZGF0ZXIgPSBDbGFzcy5jcmVhdGUoKTsKQWpheC5QZXJpb2RpY2FsVXBkYXRlci5wcm90b3R5cGUgPSBPYmplY3QuZXh0ZW5kKG5ldyBBamF4LkJhc2UoKSwgewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKGNvbnRhaW5lciwgdXJsLCBvcHRpb25zKSB7CiAgICB0aGlzLnNldE9wdGlvbnMob3B0aW9ucyk7CiAgICB0aGlzLm9uQ29tcGxldGUgPSB0aGlzLm9wdGlvbnMub25Db21wbGV0ZTsKCiAgICB0aGlzLmZyZXF1ZW5jeSA9ICh0aGlzLm9wdGlvbnMuZnJlcXVlbmN5IHx8IDIpOwogICAgdGhpcy5kZWNheSA9ICh0aGlzLm9wdGlvbnMuZGVjYXkgfHwgMSk7CgogICAgdGhpcy51cGRhdGVyID0ge307CiAgICB0aGlzLmNvbnRhaW5lciA9IGNvbnRhaW5lcjsKICAgIHRoaXMudXJsID0gdXJsOwoKICAgIHRoaXMuc3RhcnQoKTsKICB9LAoKICBzdGFydDogZnVuY3Rpb24oKSB7CiAgICB0aGlzLm9wdGlvbnMub25Db21wbGV0ZSA9IHRoaXMudXBkYXRlQ29tcGxldGUuYmluZCh0aGlzKTsKICAgIHRoaXMub25UaW1lckV2ZW50KCk7CiAgfSwKCiAgc3RvcDogZnVuY3Rpb24oKSB7CiAgICB0aGlzLnVwZGF0ZXIub3B0aW9ucy5vbkNvbXBsZXRlID0gdW5kZWZpbmVkOwogICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpOwogICAgKHRoaXMub25Db21wbGV0ZSB8fCBQcm90b3R5cGUuZW1wdHlGdW5jdGlvbikuYXBwbHkodGhpcywgYXJndW1lbnRzKTsKICB9LAoKICB1cGRhdGVDb21wbGV0ZTogZnVuY3Rpb24ocmVxdWVzdCkgewogICAgaWYgKHRoaXMub3B0aW9ucy5kZWNheSkgewogICAgICB0aGlzLmRlY2F5ID0gKHJlcXVlc3QucmVzcG9uc2VUZXh0ID09IHRoaXMubGFzdFRleHQgPwogICAgICAgIHRoaXMuZGVjYXkgKiB0aGlzLm9wdGlvbnMuZGVjYXkgOiAxKTsKCiAgICAgIHRoaXMubGFzdFRleHQgPSByZXF1ZXN0LnJlc3BvbnNlVGV4dDsKICAgIH0KICAgIHRoaXMudGltZXIgPSBzZXRUaW1lb3V0KHRoaXMub25UaW1lckV2ZW50LmJpbmQodGhpcyksCiAgICAgIHRoaXMuZGVjYXkgKiB0aGlzLmZyZXF1ZW5jeSAqIDEwMDApOwogIH0sCgogIG9uVGltZXJFdmVudDogZnVuY3Rpb24oKSB7CiAgICB0aGlzLnVwZGF0ZXIgPSBuZXcgQWpheC5VcGRhdGVyKHRoaXMuY29udGFpbmVyLCB0aGlzLnVybCwgdGhpcy5vcHRpb25zKTsKICB9Cn0pOwpmdW5jdGlvbiAkKGVsZW1lbnQpIHsKICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHsKICAgIGZvciAodmFyIGkgPSAwLCBlbGVtZW50cyA9IFtdLCBsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspCiAgICAgIGVsZW1lbnRzLnB1c2goJChhcmd1bWVudHNbaV0pKTsKICAgIHJldHVybiBlbGVtZW50czsKICB9CiAgaWYgKHR5cGVvZiBlbGVtZW50ID09ICdzdHJpbmcnKQogICAgZWxlbWVudCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGVsZW1lbnQpOwogIHJldHVybiBFbGVtZW50LmV4dGVuZChlbGVtZW50KTsKfQoKaWYgKFByb3RvdHlwZS5Ccm93c2VyRmVhdHVyZXMuWFBhdGgpIHsKICBkb2N1bWVudC5fZ2V0RWxlbWVudHNCeVhQYXRoID0gZnVuY3Rpb24oZXhwcmVzc2lvbiwgcGFyZW50RWxlbWVudCkgewogICAgdmFyIHJlc3VsdHMgPSBbXTsKICAgIHZhciBxdWVyeSA9IGRvY3VtZW50LmV2YWx1YXRlKGV4cHJlc3Npb24sICQocGFyZW50RWxlbWVudCkgfHwgZG9jdW1lbnQsCiAgICAgIG51bGwsIFhQYXRoUmVzdWx0Lk9SREVSRURfTk9ERV9TTkFQU0hPVF9UWVBFLCBudWxsKTsKICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBxdWVyeS5zbmFwc2hvdExlbmd0aDsgaSA8IGxlbjsgaSsrKQogICAgICByZXN1bHRzLnB1c2gocXVlcnkuc25hcHNob3RJdGVtKGkpKTsKICAgIHJldHVybiByZXN1bHRzOwogIH0KfQoKZG9jdW1lbnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSA9IGZ1bmN0aW9uKGNsYXNzTmFtZSwgcGFyZW50RWxlbWVudCkgewogIGlmIChQcm90b3R5cGUuQnJvd3NlckZlYXR1cmVzLlhQYXRoKSB7CiAgICB2YXIgcSA9ICIuLy8qW2NvbnRhaW5zKGNvbmNhdCgnICcsIEBjbGFzcywgJyAnKSwgJyAiICsgY2xhc3NOYW1lICsgIiAnKV0iOwogICAgcmV0dXJuIGRvY3VtZW50Ll9nZXRFbGVtZW50c0J5WFBhdGgocSwgcGFyZW50RWxlbWVudCk7CiAgfSBlbHNlIHsKICAgIHZhciBjaGlsZHJlbiA9ICgkKHBhcmVudEVsZW1lbnQpIHx8IGRvY3VtZW50LmJvZHkpLmdldEVsZW1lbnRzQnlUYWdOYW1lKCcqJyk7CiAgICB2YXIgZWxlbWVudHMgPSBbXSwgY2hpbGQ7CiAgICBmb3IgKHZhciBpID0gMCwgbGVuZ3RoID0gY2hpbGRyZW4ubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgY2hpbGQgPSBjaGlsZHJlbltpXTsKICAgICAgaWYgKEVsZW1lbnQuaGFzQ2xhc3NOYW1lKGNoaWxkLCBjbGFzc05hbWUpKQogICAgICAgIGVsZW1lbnRzLnB1c2goRWxlbWVudC5leHRlbmQoY2hpbGQpKTsKICAgIH0KICAgIHJldHVybiBlbGVtZW50czsKICB9Cn0KCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKaWYgKCF3aW5kb3cuRWxlbWVudCkKICB2YXIgRWxlbWVudCA9IG5ldyBPYmplY3QoKTsKCkVsZW1lbnQuZXh0ZW5kID0gZnVuY3Rpb24oZWxlbWVudCkgewogIGlmICghZWxlbWVudCkgcmV0dXJuOwogIGlmIChfbmF0aXZlRXh0ZW5zaW9ucyB8fCBlbGVtZW50Lm5vZGVUeXBlID09IDMpIHJldHVybiBlbGVtZW50OwoKICBpZiAoIWVsZW1lbnQuX2V4dGVuZGVkICYmIGVsZW1lbnQudGFnTmFtZSAmJiBlbGVtZW50ICE9IHdpbmRvdykgewogICAgdmFyIG1ldGhvZHMgPSBPYmplY3QuY2xvbmUoRWxlbWVudC5NZXRob2RzKSwgY2FjaGUgPSBFbGVtZW50LmV4dGVuZC5jYWNoZTsKCiAgICBpZiAoZWxlbWVudC50YWdOYW1lID09ICdGT1JNJykKICAgICAgT2JqZWN0LmV4dGVuZChtZXRob2RzLCBGb3JtLk1ldGhvZHMpOwogICAgaWYgKFsnSU5QVVQnLCAnVEVYVEFSRUEnLCAnU0VMRUNUJ10uaW5jbHVkZShlbGVtZW50LnRhZ05hbWUpKQogICAgICBPYmplY3QuZXh0ZW5kKG1ldGhvZHMsIEZvcm0uRWxlbWVudC5NZXRob2RzKTsKCiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBtZXRob2RzKSB7CiAgICAgIHZhciB2YWx1ZSA9IG1ldGhvZHNbcHJvcGVydHldOwogICAgICBpZiAodHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicpCiAgICAgICAgZWxlbWVudFtwcm9wZXJ0eV0gPSBjYWNoZS5maW5kT3JTdG9yZSh2YWx1ZSk7CiAgICB9CgogICAgdmFyIG1ldGhvZHMgPSBPYmplY3QuY2xvbmUoRWxlbWVudC5NZXRob2RzLlNpbXVsYXRlZCksIGNhY2hlID0gRWxlbWVudC5leHRlbmQuY2FjaGU7CiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiBtZXRob2RzKSB7CiAgICAgIHZhciB2YWx1ZSA9IG1ldGhvZHNbcHJvcGVydHldOwogICAgICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgdmFsdWUgJiYgIShwcm9wZXJ0eSBpbiBlbGVtZW50KSkKICAgICAgICBlbGVtZW50W3Byb3BlcnR5XSA9IGNhY2hlLmZpbmRPclN0b3JlKHZhbHVlKTsKICAgIH0KICB9CgogIGVsZW1lbnQuX2V4dGVuZGVkID0gdHJ1ZTsKICByZXR1cm4gZWxlbWVudDsKfQoKRWxlbWVudC5leHRlbmQuY2FjaGUgPSB7CiAgZmluZE9yU3RvcmU6IGZ1bmN0aW9uKHZhbHVlKSB7CiAgICByZXR1cm4gdGhpc1t2YWx1ZV0gPSB0aGlzW3ZhbHVlXSB8fCBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KG51bGwsIFt0aGlzXS5jb25jYXQoJEEoYXJndW1lbnRzKSkpOwogICAgfQogIH0KfQoKRWxlbWVudC5NZXRob2RzID0gewogIHZpc2libGU6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHJldHVybiAkKGVsZW1lbnQpLnN0eWxlLmRpc3BsYXkgIT0gJ25vbmUnOwogIH0sCgogIHRvZ2dsZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBFbGVtZW50W0VsZW1lbnQudmlzaWJsZShlbGVtZW50KSA/ICdoaWRlJyA6ICdzaG93J10oZWxlbWVudCk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBoaWRlOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAkKGVsZW1lbnQpLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBzaG93OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAkKGVsZW1lbnQpLnN0eWxlLmRpc3BsYXkgPSAnJzsKICAgIHJldHVybiBlbGVtZW50OwogIH0sCgogIHJlbW92ZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBlbGVtZW50LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWxlbWVudCk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICB1cGRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIGh0bWwpIHsKICAgIGh0bWwgPSB0eXBlb2YgaHRtbCA9PSAndW5kZWZpbmVkJyA/ICcnIDogaHRtbC50b1N0cmluZygpOwogICAgJChlbGVtZW50KS5pbm5lckhUTUwgPSBodG1sLnN0cmlwU2NyaXB0cygpOwogICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtodG1sLmV2YWxTY3JpcHRzKCl9LCAxMCk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICByZXBsYWNlOiBmdW5jdGlvbihlbGVtZW50LCBodG1sKSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGlmIChlbGVtZW50Lm91dGVySFRNTCkgewogICAgICBlbGVtZW50Lm91dGVySFRNTCA9IGh0bWwuc3RyaXBTY3JpcHRzKCk7CiAgICB9IGVsc2UgewogICAgICB2YXIgcmFuZ2UgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTsKICAgICAgcmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKGVsZW1lbnQpOwogICAgICBlbGVtZW50LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKAogICAgICAgIHJhbmdlLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChodG1sLnN0cmlwU2NyaXB0cygpKSwgZWxlbWVudCk7CiAgICB9CiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge2h0bWwuZXZhbFNjcmlwdHMoKX0sIDEwKTsKICAgIHJldHVybiBlbGVtZW50OwogIH0sCgogIGluc3BlY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIHJlc3VsdCA9ICc8JyArIGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgJEgoeydpZCc6ICdpZCcsICdjbGFzc05hbWUnOiAnY2xhc3MnfSkuZWFjaChmdW5jdGlvbihwYWlyKSB7CiAgICAgIHZhciBwcm9wZXJ0eSA9IHBhaXIuZmlyc3QoKSwgYXR0cmlidXRlID0gcGFpci5sYXN0KCk7CiAgICAgIHZhciB2YWx1ZSA9IChlbGVtZW50W3Byb3BlcnR5XSB8fCAnJykudG9TdHJpbmcoKTsKICAgICAgaWYgKHZhbHVlKSByZXN1bHQgKz0gJyAnICsgYXR0cmlidXRlICsgJz0nICsgdmFsdWUuaW5zcGVjdCh0cnVlKTsKICAgIH0pOwogICAgcmV0dXJuIHJlc3VsdCArICc+JzsKICB9LAoKICByZWN1cnNpdmVseUNvbGxlY3Q6IGZ1bmN0aW9uKGVsZW1lbnQsIHByb3BlcnR5KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIHZhciBlbGVtZW50cyA9IFtdOwogICAgd2hpbGUgKGVsZW1lbnQgPSBlbGVtZW50W3Byb3BlcnR5XSkKICAgICAgaWYgKGVsZW1lbnQubm9kZVR5cGUgPT0gMSkKICAgICAgICBlbGVtZW50cy5wdXNoKEVsZW1lbnQuZXh0ZW5kKGVsZW1lbnQpKTsKICAgIHJldHVybiBlbGVtZW50czsKICB9LAoKICBhbmNlc3RvcnM6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHJldHVybiAkKGVsZW1lbnQpLnJlY3Vyc2l2ZWx5Q29sbGVjdCgncGFyZW50Tm9kZScpOwogIH0sCgogIGRlc2NlbmRhbnRzOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIHJldHVybiAkQShlbGVtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCcqJykpOwogIH0sCgogIHByZXZpb3VzU2libGluZ3M6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHJldHVybiAkKGVsZW1lbnQpLnJlY3Vyc2l2ZWx5Q29sbGVjdCgncHJldmlvdXNTaWJsaW5nJyk7CiAgfSwKCiAgbmV4dFNpYmxpbmdzOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICByZXR1cm4gJChlbGVtZW50KS5yZWN1cnNpdmVseUNvbGxlY3QoJ25leHRTaWJsaW5nJyk7CiAgfSwKCiAgc2libGluZ3M6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgcmV0dXJuIGVsZW1lbnQucHJldmlvdXNTaWJsaW5ncygpLnJldmVyc2UoKS5jb25jYXQoZWxlbWVudC5uZXh0U2libGluZ3MoKSk7CiAgfSwKCiAgbWF0Y2g6IGZ1bmN0aW9uKGVsZW1lbnQsIHNlbGVjdG9yKSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGlmICh0eXBlb2Ygc2VsZWN0b3IgPT0gJ3N0cmluZycpCiAgICAgIHNlbGVjdG9yID0gbmV3IFNlbGVjdG9yKHNlbGVjdG9yKTsKICAgIHJldHVybiBzZWxlY3Rvci5tYXRjaChlbGVtZW50KTsKICB9LAoKICB1cDogZnVuY3Rpb24oZWxlbWVudCwgZXhwcmVzc2lvbiwgaW5kZXgpIHsKICAgIHJldHVybiBTZWxlY3Rvci5maW5kRWxlbWVudCgkKGVsZW1lbnQpLmFuY2VzdG9ycygpLCBleHByZXNzaW9uLCBpbmRleCk7CiAgfSwKCiAgZG93bjogZnVuY3Rpb24oZWxlbWVudCwgZXhwcmVzc2lvbiwgaW5kZXgpIHsKICAgIHJldHVybiBTZWxlY3Rvci5maW5kRWxlbWVudCgkKGVsZW1lbnQpLmRlc2NlbmRhbnRzKCksIGV4cHJlc3Npb24sIGluZGV4KTsKICB9LAoKICBwcmV2aW91czogZnVuY3Rpb24oZWxlbWVudCwgZXhwcmVzc2lvbiwgaW5kZXgpIHsKICAgIHJldHVybiBTZWxlY3Rvci5maW5kRWxlbWVudCgkKGVsZW1lbnQpLnByZXZpb3VzU2libGluZ3MoKSwgZXhwcmVzc2lvbiwgaW5kZXgpOwogIH0sCgogIG5leHQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGV4cHJlc3Npb24sIGluZGV4KSB7CiAgICByZXR1cm4gU2VsZWN0b3IuZmluZEVsZW1lbnQoJChlbGVtZW50KS5uZXh0U2libGluZ3MoKSwgZXhwcmVzc2lvbiwgaW5kZXgpOwogIH0sCgogIGdldEVsZW1lbnRzQnlTZWxlY3RvcjogZnVuY3Rpb24oKSB7CiAgICB2YXIgYXJncyA9ICRBKGFyZ3VtZW50cyksIGVsZW1lbnQgPSAkKGFyZ3Muc2hpZnQoKSk7CiAgICByZXR1cm4gU2VsZWN0b3IuZmluZENoaWxkRWxlbWVudHMoZWxlbWVudCwgYXJncyk7CiAgfSwKCiAgZ2V0RWxlbWVudHNCeUNsYXNzTmFtZTogZnVuY3Rpb24oZWxlbWVudCwgY2xhc3NOYW1lKSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGNsYXNzTmFtZSwgZWxlbWVudCk7CiAgfSwKCiAgZ2V0SGVpZ2h0OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIHJldHVybiBlbGVtZW50Lm9mZnNldEhlaWdodDsKICB9LAoKICBjbGFzc05hbWVzOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICByZXR1cm4gbmV3IEVsZW1lbnQuQ2xhc3NOYW1lcyhlbGVtZW50KTsKICB9LAoKICBoYXNDbGFzc05hbWU6IGZ1bmN0aW9uKGVsZW1lbnQsIGNsYXNzTmFtZSkgewogICAgaWYgKCEoZWxlbWVudCA9ICQoZWxlbWVudCkpKSByZXR1cm47CiAgICB2YXIgZWxlbWVudENsYXNzTmFtZSA9IGVsZW1lbnQuY2xhc3NOYW1lOwogICAgaWYgKGVsZW1lbnRDbGFzc05hbWUubGVuZ3RoID09IDApIHJldHVybiBmYWxzZTsKICAgIGlmIChlbGVtZW50Q2xhc3NOYW1lID09IGNsYXNzTmFtZSB8fAogICAgICAgIGVsZW1lbnRDbGFzc05hbWUubWF0Y2gobmV3IFJlZ0V4cCgiKF58XFxzKSIgKyBjbGFzc05hbWUgKyAiKFxcc3wkKSIpKSkKICAgICAgcmV0dXJuIHRydWU7CiAgICByZXR1cm4gZmFsc2U7CiAgfSwKCiAgYWRkQ2xhc3NOYW1lOiBmdW5jdGlvbihlbGVtZW50LCBjbGFzc05hbWUpIHsKICAgIGlmICghKGVsZW1lbnQgPSAkKGVsZW1lbnQpKSkgcmV0dXJuOwogICAgRWxlbWVudC5jbGFzc05hbWVzKGVsZW1lbnQpLmFkZChjbGFzc05hbWUpOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgcmVtb3ZlQ2xhc3NOYW1lOiBmdW5jdGlvbihlbGVtZW50LCBjbGFzc05hbWUpIHsKICAgIGlmICghKGVsZW1lbnQgPSAkKGVsZW1lbnQpKSkgcmV0dXJuOwogICAgRWxlbWVudC5jbGFzc05hbWVzKGVsZW1lbnQpLnJlbW92ZShjbGFzc05hbWUpOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgb2JzZXJ2ZTogZnVuY3Rpb24oKSB7CiAgICBFdmVudC5vYnNlcnZlLmFwcGx5KEV2ZW50LCBhcmd1bWVudHMpOwogICAgcmV0dXJuICRBKGFyZ3VtZW50cykuZmlyc3QoKTsKICB9LAoKICBzdG9wT2JzZXJ2aW5nOiBmdW5jdGlvbigpIHsKICAgIEV2ZW50LnN0b3BPYnNlcnZpbmcuYXBwbHkoRXZlbnQsIGFyZ3VtZW50cyk7CiAgICByZXR1cm4gJEEoYXJndW1lbnRzKS5maXJzdCgpOwogIH0sCgogIC8vIHJlbW92ZXMgd2hpdGVzcGFjZS1vbmx5IHRleHQgbm9kZSBjaGlsZHJlbgogIGNsZWFuV2hpdGVzcGFjZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICB2YXIgbm9kZSA9IGVsZW1lbnQuZmlyc3RDaGlsZDsKICAgIHdoaWxlIChub2RlKSB7CiAgICAgIHZhciBuZXh0Tm9kZSA9IG5vZGUubmV4dFNpYmxpbmc7CiAgICAgIGlmIChub2RlLm5vZGVUeXBlID09IDMgJiYgIS9cUy8udGVzdChub2RlLm5vZGVWYWx1ZSkpCiAgICAgICAgZWxlbWVudC5yZW1vdmVDaGlsZChub2RlKTsKICAgICAgbm9kZSA9IG5leHROb2RlOwogICAgfQogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgZW1wdHk6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHJldHVybiAkKGVsZW1lbnQpLmlubmVySFRNTC5tYXRjaCgvXlxzKiQvKTsKICB9LAoKICBjaGlsZE9mOiBmdW5jdGlvbihlbGVtZW50LCBhbmNlc3RvcikgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCksIGFuY2VzdG9yID0gJChhbmNlc3Rvcik7CiAgICB3aGlsZSAoZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZSkKICAgICAgaWYgKGVsZW1lbnQgPT0gYW5jZXN0b3IpIHJldHVybiB0cnVlOwogICAgcmV0dXJuIGZhbHNlOwogIH0sCgogIHNjcm9sbFRvOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIHZhciB4ID0gZWxlbWVudC54ID8gZWxlbWVudC54IDogZWxlbWVudC5vZmZzZXRMZWZ0LAogICAgICAgIHkgPSBlbGVtZW50LnkgPyBlbGVtZW50LnkgOiBlbGVtZW50Lm9mZnNldFRvcDsKICAgIHdpbmRvdy5zY3JvbGxUbyh4LCB5KTsKICAgIHJldHVybiBlbGVtZW50OwogIH0sCgogIGdldFN0eWxlOiBmdW5jdGlvbihlbGVtZW50LCBzdHlsZSkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICB2YXIgdmFsdWUgPSBlbGVtZW50LnN0eWxlW3N0eWxlLmNhbWVsaXplKCldOwogICAgaWYgKCF2YWx1ZSkgewogICAgICBpZiAoZG9jdW1lbnQuZGVmYXVsdFZpZXcgJiYgZG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZSkgewogICAgICAgIHZhciBjc3MgPSBkb2N1bWVudC5kZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQsIG51bGwpOwogICAgICAgIHZhbHVlID0gY3NzID8gY3NzLmdldFByb3BlcnR5VmFsdWUoc3R5bGUpIDogbnVsbDsKICAgICAgfSBlbHNlIGlmIChlbGVtZW50LmN1cnJlbnRTdHlsZSkgewogICAgICAgIHZhbHVlID0gZWxlbWVudC5jdXJyZW50U3R5bGVbc3R5bGUuY2FtZWxpemUoKV07CiAgICAgIH0KICAgIH0KCiAgICBpZiAod2luZG93Lm9wZXJhICYmIFsnbGVmdCcsICd0b3AnLCAncmlnaHQnLCAnYm90dG9tJ10uaW5jbHVkZShzdHlsZSkpCiAgICAgIGlmIChFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdwb3NpdGlvbicpID09ICdzdGF0aWMnKSB2YWx1ZSA9ICdhdXRvJzsKCiAgICByZXR1cm4gdmFsdWUgPT0gJ2F1dG8nID8gbnVsbCA6IHZhbHVlOwogIH0sCgogIHNldFN0eWxlOiBmdW5jdGlvbihlbGVtZW50LCBzdHlsZSkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBmb3IgKHZhciBuYW1lIGluIHN0eWxlKQogICAgICBlbGVtZW50LnN0eWxlW25hbWUuY2FtZWxpemUoKV0gPSBzdHlsZVtuYW1lXTsKICAgIHJldHVybiBlbGVtZW50OwogIH0sCgogIGdldERpbWVuc2lvbnM6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ2Rpc3BsYXknKSAhPSAnbm9uZScpCiAgICAgIHJldHVybiB7d2lkdGg6IGVsZW1lbnQub2Zmc2V0V2lkdGgsIGhlaWdodDogZWxlbWVudC5vZmZzZXRIZWlnaHR9OwoKICAgIC8vIEFsbCAqV2lkdGggYW5kICpIZWlnaHQgcHJvcGVydGllcyBnaXZlIDAgb24gZWxlbWVudHMgd2l0aCBkaXNwbGF5IG5vbmUsCiAgICAvLyBzbyBlbmFibGUgdGhlIGVsZW1lbnQgdGVtcG9yYXJpbHkKICAgIHZhciBlbHMgPSBlbGVtZW50LnN0eWxlOwogICAgdmFyIG9yaWdpbmFsVmlzaWJpbGl0eSA9IGVscy52aXNpYmlsaXR5OwogICAgdmFyIG9yaWdpbmFsUG9zaXRpb24gPSBlbHMucG9zaXRpb247CiAgICBlbHMudmlzaWJpbGl0eSA9ICdoaWRkZW4nOwogICAgZWxzLnBvc2l0aW9uID0gJ2Fic29sdXRlJzsKICAgIGVscy5kaXNwbGF5ID0gJyc7CiAgICB2YXIgb3JpZ2luYWxXaWR0aCA9IGVsZW1lbnQuY2xpZW50V2lkdGg7CiAgICB2YXIgb3JpZ2luYWxIZWlnaHQgPSBlbGVtZW50LmNsaWVudEhlaWdodDsKICAgIGVscy5kaXNwbGF5ID0gJ25vbmUnOwogICAgZWxzLnBvc2l0aW9uID0gb3JpZ2luYWxQb3NpdGlvbjsKICAgIGVscy52aXNpYmlsaXR5ID0gb3JpZ2luYWxWaXNpYmlsaXR5OwogICAgcmV0dXJuIHt3aWR0aDogb3JpZ2luYWxXaWR0aCwgaGVpZ2h0OiBvcmlnaW5hbEhlaWdodH07CiAgfSwKCiAgbWFrZVBvc2l0aW9uZWQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdmFyIHBvcyA9IEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ3Bvc2l0aW9uJyk7CiAgICBpZiAocG9zID09ICdzdGF0aWMnIHx8ICFwb3MpIHsKICAgICAgZWxlbWVudC5fbWFkZVBvc2l0aW9uZWQgPSB0cnVlOwogICAgICBlbGVtZW50LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJzsKICAgICAgLy8gT3BlcmEgcmV0dXJucyB0aGUgb2Zmc2V0IHJlbGF0aXZlIHRvIHRoZSBwb3NpdGlvbmluZyBjb250ZXh0LCB3aGVuIGFuCiAgICAgIC8vIGVsZW1lbnQgaXMgcG9zaXRpb24gcmVsYXRpdmUgYnV0IHRvcCBhbmQgbGVmdCBoYXZlIG5vdCBiZWVuIGRlZmluZWQKICAgICAgaWYgKHdpbmRvdy5vcGVyYSkgewogICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0gMDsKICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPSAwOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICB1bmRvUG9zaXRpb25lZDogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBpZiAoZWxlbWVudC5fbWFkZVBvc2l0aW9uZWQpIHsKICAgICAgZWxlbWVudC5fbWFkZVBvc2l0aW9uZWQgPSB1bmRlZmluZWQ7CiAgICAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPQogICAgICAgIGVsZW1lbnQuc3R5bGUudG9wID0KICAgICAgICBlbGVtZW50LnN0eWxlLmxlZnQgPQogICAgICAgIGVsZW1lbnQuc3R5bGUuYm90dG9tID0KICAgICAgICBlbGVtZW50LnN0eWxlLnJpZ2h0ID0gJyc7CiAgICB9CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBtYWtlQ2xpcHBpbmc6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKGVsZW1lbnQuX292ZXJmbG93KSByZXR1cm4gZWxlbWVudDsKICAgIGVsZW1lbnQuX292ZXJmbG93ID0gZWxlbWVudC5zdHlsZS5vdmVyZmxvdyB8fCAnYXV0byc7CiAgICBpZiAoKEVsZW1lbnQuZ2V0U3R5bGUoZWxlbWVudCwgJ292ZXJmbG93JykgfHwgJ3Zpc2libGUnKSAhPSAnaGlkZGVuJykKICAgICAgZWxlbWVudC5zdHlsZS5vdmVyZmxvdyA9ICdoaWRkZW4nOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgdW5kb0NsaXBwaW5nOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGlmICghZWxlbWVudC5fb3ZlcmZsb3cpIHJldHVybiBlbGVtZW50OwogICAgZWxlbWVudC5zdHlsZS5vdmVyZmxvdyA9IGVsZW1lbnQuX292ZXJmbG93ID09ICdhdXRvJyA/ICcnIDogZWxlbWVudC5fb3ZlcmZsb3c7CiAgICBlbGVtZW50Ll9vdmVyZmxvdyA9IG51bGw7CiAgICByZXR1cm4gZWxlbWVudDsKICB9Cn0KCkVsZW1lbnQuTWV0aG9kcy5TaW11bGF0ZWQgPSB7CiAgaGFzQXR0cmlidXRlOiBmdW5jdGlvbihlbGVtZW50LCBhdHRyaWJ1dGUpIHsKICAgIHJldHVybiAkKGVsZW1lbnQpLmdldEF0dHJpYnV0ZU5vZGUoYXR0cmlidXRlKS5zcGVjaWZpZWQ7CiAgfQp9CgovLyBJRSBpcyBtaXNzaW5nIC5pbm5lckhUTUwgc3VwcG9ydCBmb3IgVEFCTEUtcmVsYXRlZCBlbGVtZW50cwppZihkb2N1bWVudC5hbGwpewogIEVsZW1lbnQuTWV0aG9kcy51cGRhdGUgPSBmdW5jdGlvbihlbGVtZW50LCBodG1sKSB7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIGh0bWwgPSB0eXBlb2YgaHRtbCA9PSAndW5kZWZpbmVkJyA/ICcnIDogaHRtbC50b1N0cmluZygpOwogICAgdmFyIHRhZ05hbWUgPSBlbGVtZW50LnRhZ05hbWUudG9VcHBlckNhc2UoKTsKICAgIGlmIChbJ1RIRUFEJywnVEJPRFknLCdUUicsJ1REJ10uaW5kZXhPZih0YWdOYW1lKSA+IC0xKSB7CiAgICAgIHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTsKICAgICAgc3dpdGNoICh0YWdOYW1lKSB7CiAgICAgICAgY2FzZSAnVEhFQUQnOgogICAgICAgIGNhc2UgJ1RCT0RZJzoKICAgICAgICAgIGRpdi5pbm5lckhUTUwgPSAnPHRhYmxlPjx0Ym9keT4nICsgIGh0bWwuc3RyaXBTY3JpcHRzKCkgKyAnPC90Ym9keT48L3RhYmxlPic7CiAgICAgICAgICBkZXB0aCA9IDI7CiAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICdUUic6CiAgICAgICAgICBkaXYuaW5uZXJIVE1MID0gJzx0YWJsZT48dGJvZHk+PHRyPicgKyAgaHRtbC5zdHJpcFNjcmlwdHMoKSArICc8L3RyPjwvdGJvZHk+PC90YWJsZT4nOwogICAgICAgICAgZGVwdGggPSAzOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnVEQnOgogICAgICAgICAgZGl2LmlubmVySFRNTCA9ICc8dGFibGU+PHRib2R5Pjx0cj48dGQ+JyArICBodG1sLnN0cmlwU2NyaXB0cygpICsgJzwvdGQ+PC90cj48L3Rib2R5PjwvdGFibGU+JzsKICAgICAgICAgIGRlcHRoID0gNDsKICAgICAgfQogICAgICAkQShlbGVtZW50LmNoaWxkTm9kZXMpLmVhY2goZnVuY3Rpb24obm9kZSl7CiAgICAgICAgZWxlbWVudC5yZW1vdmVDaGlsZChub2RlKQogICAgICB9KTsKICAgICAgZGVwdGgudGltZXMoZnVuY3Rpb24oKXsgZGl2ID0gZGl2LmZpcnN0Q2hpbGQgfSk7CgogICAgICAkQShkaXYuY2hpbGROb2RlcykuZWFjaCgKICAgICAgICBmdW5jdGlvbihub2RlKXsgZWxlbWVudC5hcHBlbmRDaGlsZChub2RlKSB9KTsKICAgIH0gZWxzZSB7CiAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gaHRtbC5zdHJpcFNjcmlwdHMoKTsKICAgIH0KICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7aHRtbC5ldmFsU2NyaXB0cygpfSwgMTApOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfQp9CgpPYmplY3QuZXh0ZW5kKEVsZW1lbnQsIEVsZW1lbnQuTWV0aG9kcyk7Cgp2YXIgX25hdGl2ZUV4dGVuc2lvbnMgPSBmYWxzZTsKCmlmKC9Lb25xdWVyb3J8U2FmYXJpfEtIVE1MLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKQogIFsnJywgJ0Zvcm0nLCAnSW5wdXQnLCAnVGV4dEFyZWEnLCAnU2VsZWN0J10uZWFjaChmdW5jdGlvbih0YWcpIHsKICAgIHZhciBjbGFzc05hbWUgPSAnSFRNTCcgKyB0YWcgKyAnRWxlbWVudCc7CiAgICBpZih3aW5kb3dbY2xhc3NOYW1lXSkgcmV0dXJuOwogICAgdmFyIGtsYXNzID0gd2luZG93W2NsYXNzTmFtZV0gPSB7fTsKICAgIGtsYXNzLnByb3RvdHlwZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnID8gdGFnLnRvTG93ZXJDYXNlKCkgOiAnZGl2JykuX19wcm90b19fOwogIH0pOwoKRWxlbWVudC5hZGRNZXRob2RzID0gZnVuY3Rpb24obWV0aG9kcykgewogIE9iamVjdC5leHRlbmQoRWxlbWVudC5NZXRob2RzLCBtZXRob2RzIHx8IHt9KTsKCiAgZnVuY3Rpb24gY29weShtZXRob2RzLCBkZXN0aW5hdGlvbiwgb25seUlmQWJzZW50KSB7CiAgICBvbmx5SWZBYnNlbnQgPSBvbmx5SWZBYnNlbnQgfHwgZmFsc2U7CiAgICB2YXIgY2FjaGUgPSBFbGVtZW50LmV4dGVuZC5jYWNoZTsKICAgIGZvciAodmFyIHByb3BlcnR5IGluIG1ldGhvZHMpIHsKICAgICAgdmFyIHZhbHVlID0gbWV0aG9kc1twcm9wZXJ0eV07CiAgICAgIGlmICghb25seUlmQWJzZW50IHx8ICEocHJvcGVydHkgaW4gZGVzdGluYXRpb24pKQogICAgICAgIGRlc3RpbmF0aW9uW3Byb3BlcnR5XSA9IGNhY2hlLmZpbmRPclN0b3JlKHZhbHVlKTsKICAgIH0KICB9CgogIGlmICh0eXBlb2YgSFRNTEVsZW1lbnQgIT0gJ3VuZGVmaW5lZCcpIHsKICAgIGNvcHkoRWxlbWVudC5NZXRob2RzLCBIVE1MRWxlbWVudC5wcm90b3R5cGUpOwogICAgY29weShFbGVtZW50Lk1ldGhvZHMuU2ltdWxhdGVkLCBIVE1MRWxlbWVudC5wcm90b3R5cGUsIHRydWUpOwogICAgY29weShGb3JtLk1ldGhvZHMsIEhUTUxGb3JtRWxlbWVudC5wcm90b3R5cGUpOwogICAgW0hUTUxJbnB1dEVsZW1lbnQsIEhUTUxUZXh0QXJlYUVsZW1lbnQsIEhUTUxTZWxlY3RFbGVtZW50XS5lYWNoKGZ1bmN0aW9uKGtsYXNzKSB7CiAgICAgIGNvcHkoRm9ybS5FbGVtZW50Lk1ldGhvZHMsIGtsYXNzLnByb3RvdHlwZSk7CiAgICB9KTsKICAgIF9uYXRpdmVFeHRlbnNpb25zID0gdHJ1ZTsKICB9Cn0KCnZhciBUb2dnbGUgPSBuZXcgT2JqZWN0KCk7ClRvZ2dsZS5kaXNwbGF5ID0gRWxlbWVudC50b2dnbGU7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCkFic3RyYWN0Lkluc2VydGlvbiA9IGZ1bmN0aW9uKGFkamFjZW5jeSkgewogIHRoaXMuYWRqYWNlbmN5ID0gYWRqYWNlbmN5Owp9CgpBYnN0cmFjdC5JbnNlcnRpb24ucHJvdG90eXBlID0gewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKGVsZW1lbnQsIGNvbnRlbnQpIHsKICAgIHRoaXMuZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICB0aGlzLmNvbnRlbnQgPSBjb250ZW50LnN0cmlwU2NyaXB0cygpOwoKICAgIGlmICh0aGlzLmFkamFjZW5jeSAmJiB0aGlzLmVsZW1lbnQuaW5zZXJ0QWRqYWNlbnRIVE1MKSB7CiAgICAgIHRyeSB7CiAgICAgICAgdGhpcy5lbGVtZW50Lmluc2VydEFkamFjZW50SFRNTCh0aGlzLmFkamFjZW5jeSwgdGhpcy5jb250ZW50KTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIHZhciB0YWdOYW1lID0gdGhpcy5lbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKTsKICAgICAgICBpZiAodGFnTmFtZSA9PSAndGJvZHknIHx8IHRhZ05hbWUgPT0gJ3RyJykgewogICAgICAgICAgdGhpcy5pbnNlcnRDb250ZW50KHRoaXMuY29udGVudEZyb21Bbm9ueW1vdXNUYWJsZSgpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGhyb3cgZTsKICAgICAgICB9CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIHRoaXMucmFuZ2UgPSB0aGlzLmVsZW1lbnQub3duZXJEb2N1bWVudC5jcmVhdGVSYW5nZSgpOwogICAgICBpZiAodGhpcy5pbml0aWFsaXplUmFuZ2UpIHRoaXMuaW5pdGlhbGl6ZVJhbmdlKCk7CiAgICAgIHRoaXMuaW5zZXJ0Q29udGVudChbdGhpcy5yYW5nZS5jcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQodGhpcy5jb250ZW50KV0pOwogICAgfQoKICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7Y29udGVudC5ldmFsU2NyaXB0cygpfSwgMTApOwogIH0sCgogIGNvbnRlbnRGcm9tQW5vbnltb3VzVGFibGU6IGZ1bmN0aW9uKCkgewogICAgdmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpOwogICAgZGl2LmlubmVySFRNTCA9ICc8dGFibGU+PHRib2R5PicgKyB0aGlzLmNvbnRlbnQgKyAnPC90Ym9keT48L3RhYmxlPic7CiAgICByZXR1cm4gJEEoZGl2LmNoaWxkTm9kZXNbMF0uY2hpbGROb2Rlc1swXS5jaGlsZE5vZGVzKTsKICB9Cn0KCnZhciBJbnNlcnRpb24gPSBuZXcgT2JqZWN0KCk7CgpJbnNlcnRpb24uQmVmb3JlID0gQ2xhc3MuY3JlYXRlKCk7Ckluc2VydGlvbi5CZWZvcmUucHJvdG90eXBlID0gT2JqZWN0LmV4dGVuZChuZXcgQWJzdHJhY3QuSW5zZXJ0aW9uKCdiZWZvcmVCZWdpbicpLCB7CiAgaW5pdGlhbGl6ZVJhbmdlOiBmdW5jdGlvbigpIHsKICAgIHRoaXMucmFuZ2Uuc2V0U3RhcnRCZWZvcmUodGhpcy5lbGVtZW50KTsKICB9LAoKICBpbnNlcnRDb250ZW50OiBmdW5jdGlvbihmcmFnbWVudHMpIHsKICAgIGZyYWdtZW50cy5lYWNoKChmdW5jdGlvbihmcmFnbWVudCkgewogICAgICB0aGlzLmVsZW1lbnQucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZnJhZ21lbnQsIHRoaXMuZWxlbWVudCk7CiAgICB9KS5iaW5kKHRoaXMpKTsKICB9Cn0pOwoKSW5zZXJ0aW9uLlRvcCA9IENsYXNzLmNyZWF0ZSgpOwpJbnNlcnRpb24uVG9wLnByb3RvdHlwZSA9IE9iamVjdC5leHRlbmQobmV3IEFic3RyYWN0Lkluc2VydGlvbignYWZ0ZXJCZWdpbicpLCB7CiAgaW5pdGlhbGl6ZVJhbmdlOiBmdW5jdGlvbigpIHsKICAgIHRoaXMucmFuZ2Uuc2VsZWN0Tm9kZUNvbnRlbnRzKHRoaXMuZWxlbWVudCk7CiAgICB0aGlzLnJhbmdlLmNvbGxhcHNlKHRydWUpOwogIH0sCgogIGluc2VydENvbnRlbnQ6IGZ1bmN0aW9uKGZyYWdtZW50cykgewogICAgZnJhZ21lbnRzLnJldmVyc2UoZmFsc2UpLmVhY2goKGZ1bmN0aW9uKGZyYWdtZW50KSB7CiAgICAgIHRoaXMuZWxlbWVudC5pbnNlcnRCZWZvcmUoZnJhZ21lbnQsIHRoaXMuZWxlbWVudC5maXJzdENoaWxkKTsKICAgIH0pLmJpbmQodGhpcykpOwogIH0KfSk7CgpJbnNlcnRpb24uQm90dG9tID0gQ2xhc3MuY3JlYXRlKCk7Ckluc2VydGlvbi5Cb3R0b20ucHJvdG90eXBlID0gT2JqZWN0LmV4dGVuZChuZXcgQWJzdHJhY3QuSW5zZXJ0aW9uKCdiZWZvcmVFbmQnKSwgewogIGluaXRpYWxpemVSYW5nZTogZnVuY3Rpb24oKSB7CiAgICB0aGlzLnJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyh0aGlzLmVsZW1lbnQpOwogICAgdGhpcy5yYW5nZS5jb2xsYXBzZSh0aGlzLmVsZW1lbnQpOwogIH0sCgogIGluc2VydENvbnRlbnQ6IGZ1bmN0aW9uKGZyYWdtZW50cykgewogICAgZnJhZ21lbnRzLmVhY2goKGZ1bmN0aW9uKGZyYWdtZW50KSB7CiAgICAgIHRoaXMuZWxlbWVudC5hcHBlbmRDaGlsZChmcmFnbWVudCk7CiAgICB9KS5iaW5kKHRoaXMpKTsKICB9Cn0pOwoKSW5zZXJ0aW9uLkFmdGVyID0gQ2xhc3MuY3JlYXRlKCk7Ckluc2VydGlvbi5BZnRlci5wcm90b3R5cGUgPSBPYmplY3QuZXh0ZW5kKG5ldyBBYnN0cmFjdC5JbnNlcnRpb24oJ2FmdGVyRW5kJyksIHsKICBpbml0aWFsaXplUmFuZ2U6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5yYW5nZS5zZXRTdGFydEFmdGVyKHRoaXMuZWxlbWVudCk7CiAgfSwKCiAgaW5zZXJ0Q29udGVudDogZnVuY3Rpb24oZnJhZ21lbnRzKSB7CiAgICBmcmFnbWVudHMuZWFjaCgoZnVuY3Rpb24oZnJhZ21lbnQpIHsKICAgICAgdGhpcy5lbGVtZW50LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGZyYWdtZW50LAogICAgICAgIHRoaXMuZWxlbWVudC5uZXh0U2libGluZyk7CiAgICB9KS5iaW5kKHRoaXMpKTsKICB9Cn0pOwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpFbGVtZW50LkNsYXNzTmFtZXMgPSBDbGFzcy5jcmVhdGUoKTsKRWxlbWVudC5DbGFzc05hbWVzLnByb3RvdHlwZSA9IHsKICBpbml0aWFsaXplOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICB0aGlzLmVsZW1lbnQgPSAkKGVsZW1lbnQpOwogIH0sCgogIF9lYWNoOiBmdW5jdGlvbihpdGVyYXRvcikgewogICAgdGhpcy5lbGVtZW50LmNsYXNzTmFtZS5zcGxpdCgvXHMrLykuc2VsZWN0KGZ1bmN0aW9uKG5hbWUpIHsKICAgICAgcmV0dXJuIG5hbWUubGVuZ3RoID4gMDsKICAgIH0pLl9lYWNoKGl0ZXJhdG9yKTsKICB9LAoKICBzZXQ6IGZ1bmN0aW9uKGNsYXNzTmFtZSkgewogICAgdGhpcy5lbGVtZW50LmNsYXNzTmFtZSA9IGNsYXNzTmFtZTsKICB9LAoKICBhZGQ6IGZ1bmN0aW9uKGNsYXNzTmFtZVRvQWRkKSB7CiAgICBpZiAodGhpcy5pbmNsdWRlKGNsYXNzTmFtZVRvQWRkKSkgcmV0dXJuOwogICAgdGhpcy5zZXQoJEEodGhpcykuY29uY2F0KGNsYXNzTmFtZVRvQWRkKS5qb2luKCcgJykpOwogIH0sCgogIHJlbW92ZTogZnVuY3Rpb24oY2xhc3NOYW1lVG9SZW1vdmUpIHsKICAgIGlmICghdGhpcy5pbmNsdWRlKGNsYXNzTmFtZVRvUmVtb3ZlKSkgcmV0dXJuOwogICAgdGhpcy5zZXQoJEEodGhpcykud2l0aG91dChjbGFzc05hbWVUb1JlbW92ZSkuam9pbignICcpKTsKICB9LAoKICB0b1N0cmluZzogZnVuY3Rpb24oKSB7CiAgICByZXR1cm4gJEEodGhpcykuam9pbignICcpOwogIH0KfQoKT2JqZWN0LmV4dGVuZChFbGVtZW50LkNsYXNzTmFtZXMucHJvdG90eXBlLCBFbnVtZXJhYmxlKTsKdmFyIFNlbGVjdG9yID0gQ2xhc3MuY3JlYXRlKCk7ClNlbGVjdG9yLnByb3RvdHlwZSA9IHsKICBpbml0aWFsaXplOiBmdW5jdGlvbihleHByZXNzaW9uKSB7CiAgICB0aGlzLnBhcmFtcyA9IHtjbGFzc05hbWVzOiBbXX07CiAgICB0aGlzLmV4cHJlc3Npb24gPSBleHByZXNzaW9uLnRvU3RyaW5nKCkuc3RyaXAoKTsKICAgIHRoaXMucGFyc2VFeHByZXNzaW9uKCk7CiAgICB0aGlzLmNvbXBpbGVNYXRjaGVyKCk7CiAgfSwKCiAgcGFyc2VFeHByZXNzaW9uOiBmdW5jdGlvbigpIHsKICAgIGZ1bmN0aW9uIGFib3J0KG1lc3NhZ2UpIHsgdGhyb3cgJ1BhcnNlIGVycm9yIGluIHNlbGVjdG9yOiAnICsgbWVzc2FnZTsgfQoKICAgIGlmICh0aGlzLmV4cHJlc3Npb24gPT0gJycpICBhYm9ydCgnZW1wdHkgZXhwcmVzc2lvbicpOwoKICAgIHZhciBwYXJhbXMgPSB0aGlzLnBhcmFtcywgZXhwciA9IHRoaXMuZXhwcmVzc2lvbiwgbWF0Y2gsIG1vZGlmaWVyLCBjbGF1c2UsIHJlc3Q7CiAgICB3aGlsZSAobWF0Y2ggPSBleHByLm1hdGNoKC9eKC4qKVxbKFthLXowLTlfOi1dKz8pKD86KFt+XHwhXT89KSg/OiIoW14iXSopInwoW15cXVxzXSopKSk/XF0kL2kpKSB7CiAgICAgIHBhcmFtcy5hdHRyaWJ1dGVzID0gcGFyYW1zLmF0dHJpYnV0ZXMgfHwgW107CiAgICAgIHBhcmFtcy5hdHRyaWJ1dGVzLnB1c2goe25hbWU6IG1hdGNoWzJdLCBvcGVyYXRvcjogbWF0Y2hbM10sIHZhbHVlOiBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCAnJ30pOwogICAgICBleHByID0gbWF0Y2hbMV07CiAgICB9CgogICAgaWYgKGV4cHIgPT0gJyonKSByZXR1cm4gdGhpcy5wYXJhbXMud2lsZGNhcmQgPSB0cnVlOwoKICAgIHdoaWxlIChtYXRjaCA9IGV4cHIubWF0Y2goL14oW15hLXowLTlfLV0pPyhbYS16MC05Xy1dKykoLiopL2kpKSB7CiAgICAgIG1vZGlmaWVyID0gbWF0Y2hbMV0sIGNsYXVzZSA9IG1hdGNoWzJdLCByZXN0ID0gbWF0Y2hbM107CiAgICAgIHN3aXRjaCAobW9kaWZpZXIpIHsKICAgICAgICBjYXNlICcjJzogICAgICAgcGFyYW1zLmlkID0gY2xhdXNlOyBicmVhazsKICAgICAgICBjYXNlICcuJzogICAgICAgcGFyYW1zLmNsYXNzTmFtZXMucHVzaChjbGF1c2UpOyBicmVhazsKICAgICAgICBjYXNlICcnOgogICAgICAgIGNhc2UgdW5kZWZpbmVkOiBwYXJhbXMudGFnTmFtZSA9IGNsYXVzZS50b1VwcGVyQ2FzZSgpOyBicmVhazsKICAgICAgICBkZWZhdWx0OiAgICAgICAgYWJvcnQoZXhwci5pbnNwZWN0KCkpOwogICAgICB9CiAgICAgIGV4cHIgPSByZXN0OwogICAgfQoKICAgIGlmIChleHByLmxlbmd0aCA+IDApIGFib3J0KGV4cHIuaW5zcGVjdCgpKTsKICB9LAoKICBidWlsZE1hdGNoRXhwcmVzc2lvbjogZnVuY3Rpb24oKSB7CiAgICB2YXIgcGFyYW1zID0gdGhpcy5wYXJhbXMsIGNvbmRpdGlvbnMgPSBbXSwgY2xhdXNlOwoKICAgIGlmIChwYXJhbXMud2lsZGNhcmQpCiAgICAgIGNvbmRpdGlvbnMucHVzaCgndHJ1ZScpOwogICAgaWYgKGNsYXVzZSA9IHBhcmFtcy5pZCkKICAgICAgY29uZGl0aW9ucy5wdXNoKCdlbGVtZW50LmlkID09ICcgKyBjbGF1c2UuaW5zcGVjdCgpKTsKICAgIGlmIChjbGF1c2UgPSBwYXJhbXMudGFnTmFtZSkKICAgICAgY29uZGl0aW9ucy5wdXNoKCdlbGVtZW50LnRhZ05hbWUudG9VcHBlckNhc2UoKSA9PSAnICsgY2xhdXNlLmluc3BlY3QoKSk7CiAgICBpZiAoKGNsYXVzZSA9IHBhcmFtcy5jbGFzc05hbWVzKS5sZW5ndGggPiAwKQogICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNsYXVzZS5sZW5ndGg7IGkrKykKICAgICAgICBjb25kaXRpb25zLnB1c2goJ0VsZW1lbnQuaGFzQ2xhc3NOYW1lKGVsZW1lbnQsICcgKyBjbGF1c2VbaV0uaW5zcGVjdCgpICsgJyknKTsKICAgIGlmIChjbGF1c2UgPSBwYXJhbXMuYXR0cmlidXRlcykgewogICAgICBjbGF1c2UuZWFjaChmdW5jdGlvbihhdHRyaWJ1dGUpIHsKICAgICAgICB2YXIgdmFsdWUgPSAnZWxlbWVudC5nZXRBdHRyaWJ1dGUoJyArIGF0dHJpYnV0ZS5uYW1lLmluc3BlY3QoKSArICcpJzsKICAgICAgICB2YXIgc3BsaXRWYWx1ZUJ5ID0gZnVuY3Rpb24oZGVsaW1pdGVyKSB7CiAgICAgICAgICByZXR1cm4gdmFsdWUgKyAnICYmICcgKyB2YWx1ZSArICcuc3BsaXQoJyArIGRlbGltaXRlci5pbnNwZWN0KCkgKyAnKSc7CiAgICAgICAgfQoKICAgICAgICBzd2l0Y2ggKGF0dHJpYnV0ZS5vcGVyYXRvcikgewogICAgICAgICAgY2FzZSAnPSc6ICAgICAgIGNvbmRpdGlvbnMucHVzaCh2YWx1ZSArICcgPT0gJyArIGF0dHJpYnV0ZS52YWx1ZS5pbnNwZWN0KCkpOyBicmVhazsKICAgICAgICAgIGNhc2UgJ349JzogICAgICBjb25kaXRpb25zLnB1c2goc3BsaXRWYWx1ZUJ5KCcgJykgKyAnLmluY2x1ZGUoJyArIGF0dHJpYnV0ZS52YWx1ZS5pbnNwZWN0KCkgKyAnKScpOyBicmVhazsKICAgICAgICAgIGNhc2UgJ3w9JzogICAgICBjb25kaXRpb25zLnB1c2goCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGxpdFZhbHVlQnkoJy0nKSArICcuZmlyc3QoKS50b1VwcGVyQ2FzZSgpID09ICcgKyBhdHRyaWJ1dGUudmFsdWUudG9VcHBlckNhc2UoKS5pbnNwZWN0KCkKICAgICAgICAgICAgICAgICAgICAgICAgICApOyBicmVhazsKICAgICAgICAgIGNhc2UgJyE9JzogICAgICBjb25kaXRpb25zLnB1c2godmFsdWUgKyAnICE9ICcgKyBhdHRyaWJ1dGUudmFsdWUuaW5zcGVjdCgpKTsgYnJlYWs7CiAgICAgICAgICBjYXNlICcnOgogICAgICAgICAgY2FzZSB1bmRlZmluZWQ6IGNvbmRpdGlvbnMucHVzaCh2YWx1ZSArICcgIT0gbnVsbCcpOyBicmVhazsKICAgICAgICAgIGRlZmF1bHQ6ICAgICAgICB0aHJvdyAnVW5rbm93biBvcGVyYXRvciAnICsgYXR0cmlidXRlLm9wZXJhdG9yICsgJyBpbiBzZWxlY3Rvcic7CiAgICAgICAgfQogICAgICB9KTsKICAgIH0KCiAgICByZXR1cm4gY29uZGl0aW9ucy5qb2luKCcgJiYgJyk7CiAgfSwKCiAgY29tcGlsZU1hdGNoZXI6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5tYXRjaCA9IG5ldyBGdW5jdGlvbignZWxlbWVudCcsICdpZiAoIWVsZW1lbnQudGFnTmFtZSkgcmV0dXJuIGZhbHNlOyBcCiAgICAgIHJldHVybiAnICsgdGhpcy5idWlsZE1hdGNoRXhwcmVzc2lvbigpKTsKICB9LAoKICBmaW5kRWxlbWVudHM6IGZ1bmN0aW9uKHNjb3BlKSB7CiAgICB2YXIgZWxlbWVudDsKCiAgICBpZiAoZWxlbWVudCA9ICQodGhpcy5wYXJhbXMuaWQpKQogICAgICBpZiAodGhpcy5tYXRjaChlbGVtZW50KSkKICAgICAgICBpZiAoIXNjb3BlIHx8IEVsZW1lbnQuY2hpbGRPZihlbGVtZW50LCBzY29wZSkpCiAgICAgICAgICByZXR1cm4gW2VsZW1lbnRdOwoKICAgIHNjb3BlID0gKHNjb3BlIHx8IGRvY3VtZW50KS5nZXRFbGVtZW50c0J5VGFnTmFtZSh0aGlzLnBhcmFtcy50YWdOYW1lIHx8ICcqJyk7CgogICAgdmFyIHJlc3VsdHMgPSBbXTsKICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBzY29wZS5sZW5ndGg7IGkgPCBsZW5ndGg7IGkrKykKICAgICAgaWYgKHRoaXMubWF0Y2goZWxlbWVudCA9IHNjb3BlW2ldKSkKICAgICAgICByZXN1bHRzLnB1c2goRWxlbWVudC5leHRlbmQoZWxlbWVudCkpOwoKICAgIHJldHVybiByZXN1bHRzOwogIH0sCgogIHRvU3RyaW5nOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiB0aGlzLmV4cHJlc3Npb247CiAgfQp9CgpPYmplY3QuZXh0ZW5kKFNlbGVjdG9yLCB7CiAgbWF0Y2hFbGVtZW50czogZnVuY3Rpb24oZWxlbWVudHMsIGV4cHJlc3Npb24pIHsKICAgIHZhciBzZWxlY3RvciA9IG5ldyBTZWxlY3RvcihleHByZXNzaW9uKTsKICAgIHJldHVybiBlbGVtZW50cy5zZWxlY3Qoc2VsZWN0b3IubWF0Y2guYmluZChzZWxlY3RvcikpLmNvbGxlY3QoRWxlbWVudC5leHRlbmQpOwogIH0sCgogIGZpbmRFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50cywgZXhwcmVzc2lvbiwgaW5kZXgpIHsKICAgIGlmICh0eXBlb2YgZXhwcmVzc2lvbiA9PSAnbnVtYmVyJykgaW5kZXggPSBleHByZXNzaW9uLCBleHByZXNzaW9uID0gZmFsc2U7CiAgICByZXR1cm4gU2VsZWN0b3IubWF0Y2hFbGVtZW50cyhlbGVtZW50cywgZXhwcmVzc2lvbiB8fCAnKicpW2luZGV4IHx8IDBdOwogIH0sCgogIGZpbmRDaGlsZEVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50LCBleHByZXNzaW9ucykgewogICAgcmV0dXJuIGV4cHJlc3Npb25zLm1hcChmdW5jdGlvbihleHByZXNzaW9uKSB7CiAgICAgIHJldHVybiBleHByZXNzaW9uLnN0cmlwKCkuc3BsaXQoL1xzKy8pLmluamVjdChbbnVsbF0sIGZ1bmN0aW9uKHJlc3VsdHMsIGV4cHIpIHsKICAgICAgICB2YXIgc2VsZWN0b3IgPSBuZXcgU2VsZWN0b3IoZXhwcik7CiAgICAgICAgcmV0dXJuIHJlc3VsdHMuaW5qZWN0KFtdLCBmdW5jdGlvbihlbGVtZW50cywgcmVzdWx0KSB7CiAgICAgICAgICByZXR1cm4gZWxlbWVudHMuY29uY2F0KHNlbGVjdG9yLmZpbmRFbGVtZW50cyhyZXN1bHQgfHwgZWxlbWVudCkpOwogICAgICAgIH0pOwogICAgICB9KTsKICAgIH0pLmZsYXR0ZW4oKTsKICB9Cn0pOwoKZnVuY3Rpb24gJCQoKSB7CiAgcmV0dXJuIFNlbGVjdG9yLmZpbmRDaGlsZEVsZW1lbnRzKGRvY3VtZW50LCAkQShhcmd1bWVudHMpKTsKfQp2YXIgRm9ybSA9IHsKICByZXNldDogZnVuY3Rpb24oZm9ybSkgewogICAgJChmb3JtKS5yZXNldCgpOwogICAgcmV0dXJuIGZvcm07CiAgfSwKCiAgc2VyaWFsaXplRWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnRzKSB7CiAgICByZXR1cm4gZWxlbWVudHMuaW5qZWN0KFtdLCBmdW5jdGlvbihxdWVyeUNvbXBvbmVudHMsIGVsZW1lbnQpIHsKICAgICAgdmFyIHF1ZXJ5Q29tcG9uZW50ID0gRm9ybS5FbGVtZW50LnNlcmlhbGl6ZShlbGVtZW50KTsKICAgICAgaWYgKHF1ZXJ5Q29tcG9uZW50KSBxdWVyeUNvbXBvbmVudHMucHVzaChxdWVyeUNvbXBvbmVudCk7CiAgICAgIHJldHVybiBxdWVyeUNvbXBvbmVudHM7CiAgICB9KS5qb2luKCcmJyk7CiAgfQp9OwoKRm9ybS5NZXRob2RzID0gewogIHNlcmlhbGl6ZTogZnVuY3Rpb24oZm9ybSkgewogICAgcmV0dXJuIEZvcm0uc2VyaWFsaXplRWxlbWVudHMoJChmb3JtKS5nZXRFbGVtZW50cygpKTsKICB9LAoKICBnZXRFbGVtZW50czogZnVuY3Rpb24oZm9ybSkgewogICAgcmV0dXJuICRBKCQoZm9ybSkuZ2V0RWxlbWVudHNCeVRhZ05hbWUoJyonKSkuaW5qZWN0KFtdLAogICAgICBmdW5jdGlvbihlbGVtZW50cywgY2hpbGQpIHsKICAgICAgICBpZiAoRm9ybS5FbGVtZW50LlNlcmlhbGl6ZXJzW2NoaWxkLnRhZ05hbWUudG9Mb3dlckNhc2UoKV0pCiAgICAgICAgICBlbGVtZW50cy5wdXNoKEVsZW1lbnQuZXh0ZW5kKGNoaWxkKSk7CiAgICAgICAgcmV0dXJuIGVsZW1lbnRzOwogICAgICB9CiAgICApOwogIH0sCgogIGdldElucHV0czogZnVuY3Rpb24oZm9ybSwgdHlwZU5hbWUsIG5hbWUpIHsKICAgIGZvcm0gPSAkKGZvcm0pOwogICAgdmFyIGlucHV0cyA9IGZvcm0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoJ2lucHV0Jyk7CgogICAgaWYgKCF0eXBlTmFtZSAmJiAhbmFtZSkKICAgICAgcmV0dXJuIGlucHV0czsKCiAgICB2YXIgbWF0Y2hpbmdJbnB1dHMgPSBuZXcgQXJyYXkoKTsKICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBpbnB1dHMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIGlucHV0ID0gaW5wdXRzW2ldOwogICAgICBpZiAoKHR5cGVOYW1lICYmIGlucHV0LnR5cGUgIT0gdHlwZU5hbWUpIHx8CiAgICAgICAgICAobmFtZSAmJiBpbnB1dC5uYW1lICE9IG5hbWUpKQogICAgICAgIGNvbnRpbnVlOwogICAgICBtYXRjaGluZ0lucHV0cy5wdXNoKEVsZW1lbnQuZXh0ZW5kKGlucHV0KSk7CiAgICB9CgogICAgcmV0dXJuIG1hdGNoaW5nSW5wdXRzOwogIH0sCgogIGRpc2FibGU6IGZ1bmN0aW9uKGZvcm0pIHsKICAgIGZvcm0gPSAkKGZvcm0pOwogICAgZm9ybS5nZXRFbGVtZW50cygpLmVhY2goZnVuY3Rpb24oZWxlbWVudCkgewogICAgICBlbGVtZW50LmJsdXIoKTsKICAgICAgZWxlbWVudC5kaXNhYmxlZCA9ICd0cnVlJzsKICAgIH0pOwogICAgcmV0dXJuIGZvcm07CiAgfSwKCiAgZW5hYmxlOiBmdW5jdGlvbihmb3JtKSB7CiAgICBmb3JtID0gJChmb3JtKTsKICAgIGZvcm0uZ2V0RWxlbWVudHMoKS5lYWNoKGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICAgZWxlbWVudC5kaXNhYmxlZCA9ICcnOwogICAgfSk7CiAgICByZXR1cm4gZm9ybTsKICB9LAoKICBmaW5kRmlyc3RFbGVtZW50OiBmdW5jdGlvbihmb3JtKSB7CiAgICByZXR1cm4gJChmb3JtKS5nZXRFbGVtZW50cygpLmZpbmQoZnVuY3Rpb24oZWxlbWVudCkgewogICAgICByZXR1cm4gZWxlbWVudC50eXBlICE9ICdoaWRkZW4nICYmICFlbGVtZW50LmRpc2FibGVkICYmCiAgICAgICAgWydpbnB1dCcsICdzZWxlY3QnLCAndGV4dGFyZWEnXS5pbmNsdWRlKGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpKTsKICAgIH0pOwogIH0sCgogIGZvY3VzRmlyc3RFbGVtZW50OiBmdW5jdGlvbihmb3JtKSB7CiAgICBmb3JtID0gJChmb3JtKTsKICAgIGZvcm0uZmluZEZpcnN0RWxlbWVudCgpLmFjdGl2YXRlKCk7CiAgICByZXR1cm4gZm9ybTsKICB9Cn0KCk9iamVjdC5leHRlbmQoRm9ybSwgRm9ybS5NZXRob2RzKTsKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKRm9ybS5FbGVtZW50ID0gewogIGZvY3VzOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAkKGVsZW1lbnQpLmZvY3VzKCk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBzZWxlY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgICQoZWxlbWVudCkuc2VsZWN0KCk7CiAgICByZXR1cm4gZWxlbWVudDsKICB9Cn0KCkZvcm0uRWxlbWVudC5NZXRob2RzID0gewogIHNlcmlhbGl6ZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBpZiAoZWxlbWVudC5kaXNhYmxlZCkgcmV0dXJuICcnOwogICAgdmFyIG1ldGhvZCA9IGVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpOwogICAgdmFyIHBhcmFtZXRlciA9IEZvcm0uRWxlbWVudC5TZXJpYWxpemVyc1ttZXRob2RdKGVsZW1lbnQpOwoKICAgIGlmIChwYXJhbWV0ZXIpIHsKICAgICAgdmFyIGtleSA9IGVuY29kZVVSSUNvbXBvbmVudChwYXJhbWV0ZXJbMF0pOwogICAgICBpZiAoa2V5Lmxlbmd0aCA9PSAwKSByZXR1cm47CgogICAgICBpZiAocGFyYW1ldGVyWzFdLmNvbnN0cnVjdG9yICE9IEFycmF5KQogICAgICAgIHBhcmFtZXRlclsxXSA9IFtwYXJhbWV0ZXJbMV1dOwoKICAgICAgcmV0dXJuIHBhcmFtZXRlclsxXS5tYXAoZnVuY3Rpb24odmFsdWUpIHsKICAgICAgICByZXR1cm4ga2V5ICsgJz0nICsgZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTsKICAgICAgfSkuam9pbignJicpOwogICAgfQogIH0sCgoJLyogbel0aG9kZSBub3RhbW1lbnQgYXBwZWzpZSBsb3JzIGRlIGwndXRpbGlzYXRpb24gZGUgJEYoKSAqLwogIGdldFZhbHVlOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgCS8vYWxlcnQoZWxlbWVudCk7CiAgICBlbGVtZW50ID0gJChlbGVtZW50KTsKICAgIHZhciBtZXRob2QgPSBlbGVtZW50LnRhZ05hbWUudG9Mb3dlckNhc2UoKTsKICAgIHZhciBwYXJhbWV0ZXIgPSBGb3JtLkVsZW1lbnQuU2VyaWFsaXplcnNbbWV0aG9kXShlbGVtZW50KTsKCiAgICBpZiAocGFyYW1ldGVyKQogICAgICByZXR1cm4gcGFyYW1ldGVyWzFdOwogIH0sCgogIGNsZWFyOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICAkKGVsZW1lbnQpLnZhbHVlID0gJyc7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBwcmVzZW50OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICByZXR1cm4gJChlbGVtZW50KS52YWx1ZSAhPSAnJzsKICB9LAoKICBhY3RpdmF0ZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBlbGVtZW50LmZvY3VzKCk7CiAgICAvL2lmIChlbGVtZW50LnNlbGVjdCkKICAgIC8vICBlbGVtZW50LnNlbGVjdCgpOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfSwKCiAgZGlzYWJsZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBlbGVtZW50LmRpc2FibGVkID0gdHJ1ZTsKICAgIHJldHVybiBlbGVtZW50OwogIH0sCgogIGVuYWJsZTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgZWxlbWVudCA9ICQoZWxlbWVudCk7CiAgICBlbGVtZW50LmJsdXIoKTsKICAgIGVsZW1lbnQuZGlzYWJsZWQgPSBmYWxzZTsKICAgIHJldHVybiBlbGVtZW50OwogIH0KfQoKT2JqZWN0LmV4dGVuZChGb3JtLkVsZW1lbnQsIEZvcm0uRWxlbWVudC5NZXRob2RzKTsKdmFyIEZpZWxkID0gRm9ybS5FbGVtZW50OwoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgpGb3JtLkVsZW1lbnQuU2VyaWFsaXplcnMgPSB7CiAgaW5wdXQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHN3aXRjaCAoZWxlbWVudC50eXBlLnRvTG93ZXJDYXNlKCkpIHsKICAgICAgY2FzZSAnY2hlY2tib3gnOgogICAgICBjYXNlICdyYWRpbyc6CiAgICAgICAgcmV0dXJuIEZvcm0uRWxlbWVudC5TZXJpYWxpemVycy5pbnB1dFNlbGVjdG9yKGVsZW1lbnQpOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBGb3JtLkVsZW1lbnQuU2VyaWFsaXplcnMudGV4dGFyZWEoZWxlbWVudCk7CiAgICB9CiAgICByZXR1cm4gZmFsc2U7CiAgfSwKCiAgaW5wdXRTZWxlY3RvcjogZnVuY3Rpb24oZWxlbWVudCkgewogICAgaWYgKGVsZW1lbnQuY2hlY2tlZCkKICAgICAgcmV0dXJuIFtlbGVtZW50Lm5hbWUsIGVsZW1lbnQudmFsdWVdOwogIH0sCgogIHRleHRhcmVhOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICByZXR1cm4gW2VsZW1lbnQubmFtZSwgZWxlbWVudC52YWx1ZV07CiAgfSwKCiAgc2VsZWN0OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICByZXR1cm4gRm9ybS5FbGVtZW50LlNlcmlhbGl6ZXJzW2VsZW1lbnQudHlwZSA9PSAnc2VsZWN0LW9uZScgPwogICAgICAnc2VsZWN0T25lJyA6ICdzZWxlY3RNYW55J10oZWxlbWVudCk7CiAgfSwKCiAgc2VsZWN0T25lOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICB2YXIgdmFsdWUgPSAnJywgb3B0LCBpbmRleCA9IGVsZW1lbnQuc2VsZWN0ZWRJbmRleDsKICAgIGlmIChpbmRleCA+PSAwKSB7CiAgICAgIG9wdCA9IEVsZW1lbnQuZXh0ZW5kKGVsZW1lbnQub3B0aW9uc1tpbmRleF0pOwogICAgICAvLyBVc2VzIHRoZSBuZXcgcG90ZW50aWFsIGV4dGVuc2lvbiBpZiBoYXNBdHRyaWJ1dGUgaXNuJ3QgbmF0aXZlLgogICAgICB2YWx1ZSA9IG9wdC5oYXNBdHRyaWJ1dGUoJ3ZhbHVlJykgPyBvcHQudmFsdWUgOiBvcHQudGV4dDsKICAgIH0KICAgIHJldHVybiBbZWxlbWVudC5uYW1lLCB2YWx1ZV07CiAgfSwKCiAgc2VsZWN0TWFueTogZnVuY3Rpb24oZWxlbWVudCkgewogICAgdmFyIHZhbHVlID0gW107CiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGVsZW1lbnQubGVuZ3RoOyBpKyspIHsKICAgICAgdmFyIG9wdCA9IEVsZW1lbnQuZXh0ZW5kKGVsZW1lbnQub3B0aW9uc1tpXSk7CiAgICAgIGlmIChvcHQuc2VsZWN0ZWQpCiAgICAgICAgLy8gVXNlcyB0aGUgbmV3IHBvdGVudGlhbCBleHRlbnNpb24gaWYgaGFzQXR0cmlidXRlIGlzbid0IG5hdGl2ZS4KICAgICAgICB2YWx1ZS5wdXNoKG9wdC5oYXNBdHRyaWJ1dGUoJ3ZhbHVlJykgPyBvcHQudmFsdWUgOiBvcHQudGV4dCk7CiAgICB9CiAgICByZXR1cm4gW2VsZW1lbnQubmFtZSwgdmFsdWVdOwogIH0KfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCgp2YXIgJEYgPSBGb3JtLkVsZW1lbnQuZ2V0VmFsdWU7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCkFic3RyYWN0LlRpbWVkT2JzZXJ2ZXIgPSBmdW5jdGlvbigpIHt9CkFic3RyYWN0LlRpbWVkT2JzZXJ2ZXIucHJvdG90eXBlID0gewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKGVsZW1lbnQsIGZyZXF1ZW5jeSwgY2FsbGJhY2spIHsKICAgIHRoaXMuZnJlcXVlbmN5ID0gZnJlcXVlbmN5OwogICAgdGhpcy5lbGVtZW50ICAgPSAkKGVsZW1lbnQpOwogICAgdGhpcy5jYWxsYmFjayAgPSBjYWxsYmFjazsKCiAgICB0aGlzLmxhc3RWYWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTsKICAgIHRoaXMucmVnaXN0ZXJDYWxsYmFjaygpOwogIH0sCgogIHJlZ2lzdGVyQ2FsbGJhY2s6IGZ1bmN0aW9uKCkgewogICAgc2V0SW50ZXJ2YWwodGhpcy5vblRpbWVyRXZlbnQuYmluZCh0aGlzKSwgdGhpcy5mcmVxdWVuY3kgKiAxMDAwKTsKICB9LAoKICBvblRpbWVyRXZlbnQ6IGZ1bmN0aW9uKCkgewogICAgdmFyIHZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpOwogICAgaWYgKHRoaXMubGFzdFZhbHVlICE9IHZhbHVlKSB7CiAgICAgIHRoaXMuY2FsbGJhY2sodGhpcy5lbGVtZW50LCB2YWx1ZSk7CiAgICAgIHRoaXMubGFzdFZhbHVlID0gdmFsdWU7CiAgICB9CiAgfQp9CgpGb3JtLkVsZW1lbnQuT2JzZXJ2ZXIgPSBDbGFzcy5jcmVhdGUoKTsKRm9ybS5FbGVtZW50Lk9ic2VydmVyLnByb3RvdHlwZSA9IE9iamVjdC5leHRlbmQobmV3IEFic3RyYWN0LlRpbWVkT2JzZXJ2ZXIoKSwgewogIGdldFZhbHVlOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiBGb3JtLkVsZW1lbnQuZ2V0VmFsdWUodGhpcy5lbGVtZW50KTsKICB9Cn0pOwoKRm9ybS5PYnNlcnZlciA9IENsYXNzLmNyZWF0ZSgpOwpGb3JtLk9ic2VydmVyLnByb3RvdHlwZSA9IE9iamVjdC5leHRlbmQobmV3IEFic3RyYWN0LlRpbWVkT2JzZXJ2ZXIoKSwgewogIGdldFZhbHVlOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiBGb3JtLnNlcmlhbGl6ZSh0aGlzLmVsZW1lbnQpOwogIH0KfSk7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KCkFic3RyYWN0LkV2ZW50T2JzZXJ2ZXIgPSBmdW5jdGlvbigpIHt9CkFic3RyYWN0LkV2ZW50T2JzZXJ2ZXIucHJvdG90eXBlID0gewogIGluaXRpYWxpemU6IGZ1bmN0aW9uKGVsZW1lbnQsIGNhbGxiYWNrKSB7CiAgICB0aGlzLmVsZW1lbnQgID0gJChlbGVtZW50KTsKICAgIHRoaXMuY2FsbGJhY2sgPSBjYWxsYmFjazsKCiAgICB0aGlzLmxhc3RWYWx1ZSA9IHRoaXMuZ2V0VmFsdWUoKTsKICAgIGlmICh0aGlzLmVsZW1lbnQudGFnTmFtZS50b0xvd2VyQ2FzZSgpID09ICdmb3JtJykKICAgICAgdGhpcy5yZWdpc3RlckZvcm1DYWxsYmFja3MoKTsKICAgIGVsc2UKICAgICAgdGhpcy5yZWdpc3RlckNhbGxiYWNrKHRoaXMuZWxlbWVudCk7CiAgfSwKCiAgb25FbGVtZW50RXZlbnQ6IGZ1bmN0aW9uKCkgewogICAgdmFyIHZhbHVlID0gdGhpcy5nZXRWYWx1ZSgpOwogICAgaWYgKHRoaXMubGFzdFZhbHVlICE9IHZhbHVlKSB7CiAgICAgIHRoaXMuY2FsbGJhY2sodGhpcy5lbGVtZW50LCB2YWx1ZSk7CiAgICAgIHRoaXMubGFzdFZhbHVlID0gdmFsdWU7CiAgICB9CiAgfSwKCiAgcmVnaXN0ZXJGb3JtQ2FsbGJhY2tzOiBmdW5jdGlvbigpIHsKICAgIEZvcm0uZ2V0RWxlbWVudHModGhpcy5lbGVtZW50KS5lYWNoKHRoaXMucmVnaXN0ZXJDYWxsYmFjay5iaW5kKHRoaXMpKTsKICB9LAoKICByZWdpc3RlckNhbGxiYWNrOiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICBpZiAoZWxlbWVudC50eXBlKSB7CiAgICAgIHN3aXRjaCAoZWxlbWVudC50eXBlLnRvTG93ZXJDYXNlKCkpIHsKICAgICAgICBjYXNlICdjaGVja2JveCc6CiAgICAgICAgY2FzZSAncmFkaW8nOgogICAgICAgICAgRXZlbnQub2JzZXJ2ZShlbGVtZW50LCAnY2xpY2snLCB0aGlzLm9uRWxlbWVudEV2ZW50LmJpbmQodGhpcykpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgIEV2ZW50Lm9ic2VydmUoZWxlbWVudCwgJ2NoYW5nZScsIHRoaXMub25FbGVtZW50RXZlbnQuYmluZCh0aGlzKSk7CiAgICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogIH0KfQoKRm9ybS5FbGVtZW50LkV2ZW50T2JzZXJ2ZXIgPSBDbGFzcy5jcmVhdGUoKTsKRm9ybS5FbGVtZW50LkV2ZW50T2JzZXJ2ZXIucHJvdG90eXBlID0gT2JqZWN0LmV4dGVuZChuZXcgQWJzdHJhY3QuRXZlbnRPYnNlcnZlcigpLCB7CiAgZ2V0VmFsdWU6IGZ1bmN0aW9uKCkgewogICAgcmV0dXJuIEZvcm0uRWxlbWVudC5nZXRWYWx1ZSh0aGlzLmVsZW1lbnQpOwogIH0KfSk7CgpGb3JtLkV2ZW50T2JzZXJ2ZXIgPSBDbGFzcy5jcmVhdGUoKTsKRm9ybS5FdmVudE9ic2VydmVyLnByb3RvdHlwZSA9IE9iamVjdC5leHRlbmQobmV3IEFic3RyYWN0LkV2ZW50T2JzZXJ2ZXIoKSwgewogIGdldFZhbHVlOiBmdW5jdGlvbigpIHsKICAgIHJldHVybiBGb3JtLnNlcmlhbGl6ZSh0aGlzLmVsZW1lbnQpOwogIH0KfSk7CmlmICghd2luZG93LkV2ZW50KSB7CiAgdmFyIEV2ZW50ID0gbmV3IE9iamVjdCgpOwp9CgpPYmplY3QuZXh0ZW5kKEV2ZW50LCB7CiAgS0VZX0JBQ0tTUEFDRTogOCwKICBLRVlfVEFCOiAgICAgICA5LAogIEtFWV9SRVRVUk46ICAgMTMsCiAgS0VZX0VTQzogICAgICAyNywKICBLRVlfTEVGVDogICAgIDM3LAogIEtFWV9VUDogICAgICAgMzgsCiAgS0VZX1JJR0hUOiAgICAzOSwKICBLRVlfRE9XTjogICAgIDQwLAogIEtFWV9ERUxFVEU6ICAgNDYsCiAgS0VZX0hPTUU6ICAgICAzNiwKICBLRVlfRU5EOiAgICAgIDM1LAogIEtFWV9QQUdFVVA6ICAgMzMsCiAgS0VZX1BBR0VET1dOOiAzNCwKCiAgZWxlbWVudDogZnVuY3Rpb24oZXZlbnQpIHsKICAgIHJldHVybiBldmVudC50YXJnZXQgfHwgZXZlbnQuc3JjRWxlbWVudDsKICB9LAoKICBpc0xlZnRDbGljazogZnVuY3Rpb24oZXZlbnQpIHsKICAgIHJldHVybiAoKChldmVudC53aGljaCkgJiYgKGV2ZW50LndoaWNoID09IDEpKSB8fAogICAgICAgICAgICAoKGV2ZW50LmJ1dHRvbikgJiYgKGV2ZW50LmJ1dHRvbiA9PSAxKSkpOwogIH0sCgogIHBvaW50ZXJYOiBmdW5jdGlvbihldmVudCkgewogICAgcmV0dXJuIGV2ZW50LnBhZ2VYIHx8IChldmVudC5jbGllbnRYICsKICAgICAgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0IHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsTGVmdCkpOwogIH0sCgogIHBvaW50ZXJZOiBmdW5jdGlvbihldmVudCkgewogICAgcmV0dXJuIGV2ZW50LnBhZ2VZIHx8IChldmVudC5jbGllbnRZICsKICAgICAgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3ApKTsKICB9LAoKICBzdG9wOiBmdW5jdGlvbihldmVudCkgewogICAgaWYgKGV2ZW50LnByZXZlbnREZWZhdWx0KSB7CiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7CiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOwogICAgfSBlbHNlIHsKICAgICAgZXZlbnQucmV0dXJuVmFsdWUgPSBmYWxzZTsKICAgICAgZXZlbnQuY2FuY2VsQnViYmxlID0gdHJ1ZTsKICAgIH0KICB9LAoKICAvLyBmaW5kIHRoZSBmaXJzdCBub2RlIHdpdGggdGhlIGdpdmVuIHRhZ05hbWUsIHN0YXJ0aW5nIGZyb20gdGhlCiAgLy8gbm9kZSB0aGUgZXZlbnQgd2FzIHRyaWdnZXJlZCBvbjsgdHJhdmVyc2VzIHRoZSBET00gdXB3YXJkcwogIGZpbmRFbGVtZW50OiBmdW5jdGlvbihldmVudCwgdGFnTmFtZSkgewogICAgdmFyIGVsZW1lbnQgPSBFdmVudC5lbGVtZW50KGV2ZW50KTsKICAgIHdoaWxlIChlbGVtZW50LnBhcmVudE5vZGUgJiYgKCFlbGVtZW50LnRhZ05hbWUgfHwKICAgICAgICAoZWxlbWVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCkgIT0gdGFnTmFtZS50b1VwcGVyQ2FzZSgpKSkpCiAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7CiAgICByZXR1cm4gZWxlbWVudDsKICB9LAoKICBvYnNlcnZlcnM6IGZhbHNlLAoKICBfb2JzZXJ2ZUFuZENhY2hlOiBmdW5jdGlvbihlbGVtZW50LCBuYW1lLCBvYnNlcnZlciwgdXNlQ2FwdHVyZSkgewogICAgaWYgKCF0aGlzLm9ic2VydmVycykgdGhpcy5vYnNlcnZlcnMgPSBbXTsKICAgIGlmIChlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHsKICAgICAgdGhpcy5vYnNlcnZlcnMucHVzaChbZWxlbWVudCwgbmFtZSwgb2JzZXJ2ZXIsIHVzZUNhcHR1cmVdKTsKICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKG5hbWUsIG9ic2VydmVyLCB1c2VDYXB0dXJlKTsKICAgIH0gZWxzZSBpZiAoZWxlbWVudC5hdHRhY2hFdmVudCkgewogICAgICB0aGlzLm9ic2VydmVycy5wdXNoKFtlbGVtZW50LCBuYW1lLCBvYnNlcnZlciwgdXNlQ2FwdHVyZV0pOwogICAgICBlbGVtZW50LmF0dGFjaEV2ZW50KCdvbicgKyBuYW1lLCBvYnNlcnZlcik7CiAgICB9CiAgfSwKCiAgdW5sb2FkQ2FjaGU6IGZ1bmN0aW9uKCkgewogICAgaWYgKCFFdmVudC5vYnNlcnZlcnMpIHJldHVybjsKICAgIGZvciAodmFyIGkgPSAwLCBsZW5ndGggPSBFdmVudC5vYnNlcnZlcnMubGVuZ3RoOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgRXZlbnQuc3RvcE9ic2VydmluZy5hcHBseSh0aGlzLCBFdmVudC5vYnNlcnZlcnNbaV0pOwogICAgICBFdmVudC5vYnNlcnZlcnNbaV1bMF0gPSBudWxsOwogICAgfQogICAgRXZlbnQub2JzZXJ2ZXJzID0gZmFsc2U7CiAgfSwKCiAgb2JzZXJ2ZTogZnVuY3Rpb24oZWxlbWVudCwgbmFtZSwgb2JzZXJ2ZXIsIHVzZUNhcHR1cmUpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdXNlQ2FwdHVyZSA9IHVzZUNhcHR1cmUgfHwgZmFsc2U7CgogICAgaWYgKG5hbWUgPT0gJ2tleXByZXNzJyAmJgogICAgICAgIChuYXZpZ2F0b3IuYXBwVmVyc2lvbi5tYXRjaCgvS29ucXVlcm9yfFNhZmFyaXxLSFRNTC8pCiAgICAgICAgfHwgZWxlbWVudC5hdHRhY2hFdmVudCkpCiAgICAgIG5hbWUgPSAna2V5ZG93bic7CgogICAgRXZlbnQuX29ic2VydmVBbmRDYWNoZShlbGVtZW50LCBuYW1lLCBvYnNlcnZlciwgdXNlQ2FwdHVyZSk7CiAgfSwKCiAgc3RvcE9ic2VydmluZzogZnVuY3Rpb24oZWxlbWVudCwgbmFtZSwgb2JzZXJ2ZXIsIHVzZUNhcHR1cmUpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgdXNlQ2FwdHVyZSA9IHVzZUNhcHR1cmUgfHwgZmFsc2U7CgogICAgaWYgKG5hbWUgPT0gJ2tleXByZXNzJyAmJgogICAgICAgIChuYXZpZ2F0b3IuYXBwVmVyc2lvbi5tYXRjaCgvS29ucXVlcm9yfFNhZmFyaXxLSFRNTC8pCiAgICAgICAgfHwgZWxlbWVudC5kZXRhY2hFdmVudCkpCiAgICAgIG5hbWUgPSAna2V5ZG93bic7CgogICAgaWYgKGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcikgewogICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIobmFtZSwgb2JzZXJ2ZXIsIHVzZUNhcHR1cmUpOwogICAgfSBlbHNlIGlmIChlbGVtZW50LmRldGFjaEV2ZW50KSB7CiAgICAgIHRyeSB7CiAgICAgICAgZWxlbWVudC5kZXRhY2hFdmVudCgnb24nICsgbmFtZSwgb2JzZXJ2ZXIpOwogICAgICB9IGNhdGNoIChlKSB7fQogICAgfQogIH0KfSk7CgovKiBwcmV2ZW50IG1lbW9yeSBsZWFrcyBpbiBJRSAqLwppZiAobmF2aWdhdG9yLmFwcFZlcnNpb24ubWF0Y2goL1xiTVNJRVxiLykpCiAgRXZlbnQub2JzZXJ2ZSh3aW5kb3csICd1bmxvYWQnLCBFdmVudC51bmxvYWRDYWNoZSwgZmFsc2UpOwp2YXIgUG9zaXRpb24gPSB7CiAgLy8gc2V0IHRvIHRydWUgaWYgbmVlZGVkLCB3YXJuaW5nOiBmaXJlZm94IHBlcmZvcm1hbmNlIHByb2JsZW1zCiAgLy8gTk9UIG5lZWVkZWQgZm9yIHBhZ2Ugc2Nyb2xsaW5nLCBvbmx5IGlmIGRyYWdnYWJsZSBjb250YWluZWQgaW4KICAvLyBzY3JvbGxhYmxlIGVsZW1lbnRzCiAgaW5jbHVkZVNjcm9sbE9mZnNldHM6IGZhbHNlLAoKICAvLyBtdXN0IGJlIGNhbGxlZCBiZWZvcmUgY2FsbGluZyB3aXRoaW5JbmNsdWRpbmdTY3JvbGxvZmZzZXQsIGV2ZXJ5IHRpbWUgdGhlCiAgLy8gcGFnZSBpcyBzY3JvbGxlZAogIHByZXBhcmU6IGZ1bmN0aW9uKCkgewogICAgdGhpcy5kZWx0YVggPSAgd2luZG93LnBhZ2VYT2Zmc2V0CiAgICAgICAgICAgICAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdAogICAgICAgICAgICAgICAgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxMZWZ0CiAgICAgICAgICAgICAgICB8fCAwOwogICAgdGhpcy5kZWx0YVkgPSAgd2luZG93LnBhZ2VZT2Zmc2V0CiAgICAgICAgICAgICAgICB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsVG9wCiAgICAgICAgICAgICAgICB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcAogICAgICAgICAgICAgICAgfHwgMDsKICB9LAoKICByZWFsT2Zmc2V0OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICB2YXIgdmFsdWVUID0gMCwgdmFsdWVMID0gMDsKICAgIGRvIHsKICAgICAgdmFsdWVUICs9IGVsZW1lbnQuc2Nyb2xsVG9wICB8fCAwOwogICAgICB2YWx1ZUwgKz0gZWxlbWVudC5zY3JvbGxMZWZ0IHx8IDA7CiAgICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7CiAgICB9IHdoaWxlIChlbGVtZW50KTsKICAgIHJldHVybiBbdmFsdWVMLCB2YWx1ZVRdOwogIH0sCgogIGN1bXVsYXRpdmVPZmZzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIHZhciB2YWx1ZVQgPSAwLCB2YWx1ZUwgPSAwOwogICAgZG8gewogICAgICB2YWx1ZVQgKz0gZWxlbWVudC5vZmZzZXRUb3AgIHx8IDA7CiAgICAgIHZhbHVlTCArPSBlbGVtZW50Lm9mZnNldExlZnQgfHwgMDsKICAgICAgZWxlbWVudCA9IGVsZW1lbnQub2Zmc2V0UGFyZW50OwogICAgfSB3aGlsZSAoZWxlbWVudCk7CiAgICByZXR1cm4gW3ZhbHVlTCwgdmFsdWVUXTsKICB9LAoKICBwb3NpdGlvbmVkT2Zmc2V0OiBmdW5jdGlvbihlbGVtZW50KSB7CiAgICB2YXIgdmFsdWVUID0gMCwgdmFsdWVMID0gMDsKICAgIGRvIHsKICAgICAgdmFsdWVUICs9IGVsZW1lbnQub2Zmc2V0VG9wICB8fCAwOwogICAgICB2YWx1ZUwgKz0gZWxlbWVudC5vZmZzZXRMZWZ0IHx8IDA7CiAgICAgIGVsZW1lbnQgPSBlbGVtZW50Lm9mZnNldFBhcmVudDsKICAgICAgaWYgKGVsZW1lbnQpIHsKICAgICAgICBpZihlbGVtZW50LnRhZ05hbWU9PSdCT0RZJykgYnJlYWs7CiAgICAgICAgdmFyIHAgPSBFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdwb3NpdGlvbicpOwogICAgICAgIGlmIChwID09ICdyZWxhdGl2ZScgfHwgcCA9PSAnYWJzb2x1dGUnKSBicmVhazsKICAgICAgfQogICAgfSB3aGlsZSAoZWxlbWVudCk7CiAgICByZXR1cm4gW3ZhbHVlTCwgdmFsdWVUXTsKICB9LAoKICBvZmZzZXRQYXJlbnQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGlmIChlbGVtZW50Lm9mZnNldFBhcmVudCkgcmV0dXJuIGVsZW1lbnQub2Zmc2V0UGFyZW50OwogICAgaWYgKGVsZW1lbnQgPT0gZG9jdW1lbnQuYm9keSkgcmV0dXJuIGVsZW1lbnQ7CgogICAgd2hpbGUgKChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnROb2RlKSAmJiBlbGVtZW50ICE9IGRvY3VtZW50LmJvZHkpCiAgICAgIGlmIChFbGVtZW50LmdldFN0eWxlKGVsZW1lbnQsICdwb3NpdGlvbicpICE9ICdzdGF0aWMnKQogICAgICAgIHJldHVybiBlbGVtZW50OwoKICAgIHJldHVybiBkb2N1bWVudC5ib2R5OwogIH0sCgogIC8vIGNhY2hlcyB4L3kgY29vcmRpbmF0ZSBwYWlyIHRvIHVzZSB3aXRoIG92ZXJsYXAKICB3aXRoaW46IGZ1bmN0aW9uKGVsZW1lbnQsIHgsIHkpIHsKICAgIGlmICh0aGlzLmluY2x1ZGVTY3JvbGxPZmZzZXRzKQogICAgICByZXR1cm4gdGhpcy53aXRoaW5JbmNsdWRpbmdTY3JvbGxvZmZzZXRzKGVsZW1lbnQsIHgsIHkpOwogICAgdGhpcy54Y29tcCA9IHg7CiAgICB0aGlzLnljb21wID0geTsKICAgIHRoaXMub2Zmc2V0ID0gdGhpcy5jdW11bGF0aXZlT2Zmc2V0KGVsZW1lbnQpOwoKICAgIHJldHVybiAoeSA+PSB0aGlzLm9mZnNldFsxXSAmJgogICAgICAgICAgICB5IDwgIHRoaXMub2Zmc2V0WzFdICsgZWxlbWVudC5vZmZzZXRIZWlnaHQgJiYKICAgICAgICAgICAgeCA+PSB0aGlzLm9mZnNldFswXSAmJgogICAgICAgICAgICB4IDwgIHRoaXMub2Zmc2V0WzBdICsgZWxlbWVudC5vZmZzZXRXaWR0aCk7CiAgfSwKCiAgd2l0aGluSW5jbHVkaW5nU2Nyb2xsb2Zmc2V0czogZnVuY3Rpb24oZWxlbWVudCwgeCwgeSkgewogICAgdmFyIG9mZnNldGNhY2hlID0gdGhpcy5yZWFsT2Zmc2V0KGVsZW1lbnQpOwoKICAgIHRoaXMueGNvbXAgPSB4ICsgb2Zmc2V0Y2FjaGVbMF0gLSB0aGlzLmRlbHRhWDsKICAgIHRoaXMueWNvbXAgPSB5ICsgb2Zmc2V0Y2FjaGVbMV0gLSB0aGlzLmRlbHRhWTsKICAgIHRoaXMub2Zmc2V0ID0gdGhpcy5jdW11bGF0aXZlT2Zmc2V0KGVsZW1lbnQpOwoKICAgIHJldHVybiAodGhpcy55Y29tcCA+PSB0aGlzLm9mZnNldFsxXSAmJgogICAgICAgICAgICB0aGlzLnljb21wIDwgIHRoaXMub2Zmc2V0WzFdICsgZWxlbWVudC5vZmZzZXRIZWlnaHQgJiYKICAgICAgICAgICAgdGhpcy54Y29tcCA+PSB0aGlzLm9mZnNldFswXSAmJgogICAgICAgICAgICB0aGlzLnhjb21wIDwgIHRoaXMub2Zmc2V0WzBdICsgZWxlbWVudC5vZmZzZXRXaWR0aCk7CiAgfSwKCiAgLy8gd2l0aGluIG11c3QgYmUgY2FsbGVkIGRpcmVjdGx5IGJlZm9yZQogIG92ZXJsYXA6IGZ1bmN0aW9uKG1vZGUsIGVsZW1lbnQpIHsKICAgIGlmICghbW9kZSkgcmV0dXJuIDA7CiAgICBpZiAobW9kZSA9PSAndmVydGljYWwnKQogICAgICByZXR1cm4gKCh0aGlzLm9mZnNldFsxXSArIGVsZW1lbnQub2Zmc2V0SGVpZ2h0KSAtIHRoaXMueWNvbXApIC8KICAgICAgICBlbGVtZW50Lm9mZnNldEhlaWdodDsKICAgIGlmIChtb2RlID09ICdob3Jpem9udGFsJykKICAgICAgcmV0dXJuICgodGhpcy5vZmZzZXRbMF0gKyBlbGVtZW50Lm9mZnNldFdpZHRoKSAtIHRoaXMueGNvbXApIC8KICAgICAgICBlbGVtZW50Lm9mZnNldFdpZHRoOwogIH0sCgogIHBhZ2U6IGZ1bmN0aW9uKGZvckVsZW1lbnQpIHsKICAgIHZhciB2YWx1ZVQgPSAwLCB2YWx1ZUwgPSAwOwoKICAgIHZhciBlbGVtZW50ID0gZm9yRWxlbWVudDsKICAgIGRvIHsKICAgICAgdmFsdWVUICs9IGVsZW1lbnQub2Zmc2V0VG9wICB8fCAwOwogICAgICB2YWx1ZUwgKz0gZWxlbWVudC5vZmZzZXRMZWZ0IHx8IDA7CgogICAgICAvLyBTYWZhcmkgZml4CiAgICAgIGlmIChlbGVtZW50Lm9mZnNldFBhcmVudD09ZG9jdW1lbnQuYm9keSkKICAgICAgICBpZiAoRWxlbWVudC5nZXRTdHlsZShlbGVtZW50LCdwb3NpdGlvbicpPT0nYWJzb2x1dGUnKSBicmVhazsKCiAgICB9IHdoaWxlIChlbGVtZW50ID0gZWxlbWVudC5vZmZzZXRQYXJlbnQpOwoKICAgIGVsZW1lbnQgPSBmb3JFbGVtZW50OwogICAgZG8gewogICAgICBpZiAoIXdpbmRvdy5vcGVyYSB8fCBlbGVtZW50LnRhZ05hbWU9PSdCT0RZJykgewogICAgICAgIHZhbHVlVCAtPSBlbGVtZW50LnNjcm9sbFRvcCAgfHwgMDsKICAgICAgICB2YWx1ZUwgLT0gZWxlbWVudC5zY3JvbGxMZWZ0IHx8IDA7CiAgICAgIH0KICAgIH0gd2hpbGUgKGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudE5vZGUpOwoKICAgIHJldHVybiBbdmFsdWVMLCB2YWx1ZVRdOwogIH0sCgogIGNsb25lOiBmdW5jdGlvbihzb3VyY2UsIHRhcmdldCkgewogICAgdmFyIG9wdGlvbnMgPSBPYmplY3QuZXh0ZW5kKHsKICAgICAgc2V0TGVmdDogICAgdHJ1ZSwKICAgICAgc2V0VG9wOiAgICAgdHJ1ZSwKICAgICAgc2V0V2lkdGg6ICAgdHJ1ZSwKICAgICAgc2V0SGVpZ2h0OiAgdHJ1ZSwKICAgICAgb2Zmc2V0VG9wOiAgMCwKICAgICAgb2Zmc2V0TGVmdDogMAogICAgfSwgYXJndW1lbnRzWzJdIHx8IHt9KQoKICAgIC8vIGZpbmQgcGFnZSBwb3NpdGlvbiBvZiBzb3VyY2UKICAgIHNvdXJjZSA9ICQoc291cmNlKTsKICAgIHZhciBwID0gUG9zaXRpb24ucGFnZShzb3VyY2UpOwoKICAgIC8vIGZpbmQgY29vcmRpbmF0ZSBzeXN0ZW0gdG8gdXNlCiAgICB0YXJnZXQgPSAkKHRhcmdldCk7CiAgICB2YXIgZGVsdGEgPSBbMCwgMF07CiAgICB2YXIgcGFyZW50ID0gbnVsbDsKICAgIC8vIGRlbHRhIFswLDBdIHdpbGwgZG8gZmluZSB3aXRoIHBvc2l0aW9uOiBmaXhlZCBlbGVtZW50cywKICAgIC8vIHBvc2l0aW9uOmFic29sdXRlIG5lZWRzIG9mZnNldFBhcmVudCBkZWx0YXMKICAgIGlmIChFbGVtZW50LmdldFN0eWxlKHRhcmdldCwncG9zaXRpb24nKSA9PSAnYWJzb2x1dGUnKSB7CiAgICAgIHBhcmVudCA9IFBvc2l0aW9uLm9mZnNldFBhcmVudCh0YXJnZXQpOwogICAgICBkZWx0YSA9IFBvc2l0aW9uLnBhZ2UocGFyZW50KTsKICAgIH0KCiAgICAvLyBjb3JyZWN0IGJ5IGJvZHkgb2Zmc2V0cyAoZml4ZXMgU2FmYXJpKQogICAgaWYgKHBhcmVudCA9PSBkb2N1bWVudC5ib2R5KSB7CiAgICAgIGRlbHRhWzBdIC09IGRvY3VtZW50LmJvZHkub2Zmc2V0TGVmdDsKICAgICAgZGVsdGFbMV0gLT0gZG9jdW1lbnQuYm9keS5vZmZzZXRUb3A7CiAgICB9CgogICAgLy8gc2V0IHBvc2l0aW9uCiAgICBpZihvcHRpb25zLnNldExlZnQpICAgdGFyZ2V0LnN0eWxlLmxlZnQgID0gKHBbMF0gLSBkZWx0YVswXSArIG9wdGlvbnMub2Zmc2V0TGVmdCkgKyAncHgnOwogICAgaWYob3B0aW9ucy5zZXRUb3ApICAgIHRhcmdldC5zdHlsZS50b3AgICA9IChwWzFdIC0gZGVsdGFbMV0gKyBvcHRpb25zLm9mZnNldFRvcCkgKyAncHgnOwogICAgaWYob3B0aW9ucy5zZXRXaWR0aCkgIHRhcmdldC5zdHlsZS53aWR0aCA9IHNvdXJjZS5vZmZzZXRXaWR0aCArICdweCc7CiAgICBpZihvcHRpb25zLnNldEhlaWdodCkgdGFyZ2V0LnN0eWxlLmhlaWdodCA9IHNvdXJjZS5vZmZzZXRIZWlnaHQgKyAncHgnOwogIH0sCgogIGFic29sdXRpemU6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPT0gJ2Fic29sdXRlJykgcmV0dXJuOwogICAgUG9zaXRpb24ucHJlcGFyZSgpOwoKICAgIHZhciBvZmZzZXRzID0gUG9zaXRpb24ucG9zaXRpb25lZE9mZnNldChlbGVtZW50KTsKICAgIHZhciB0b3AgICAgID0gb2Zmc2V0c1sxXTsKICAgIHZhciBsZWZ0ICAgID0gb2Zmc2V0c1swXTsKICAgIHZhciB3aWR0aCAgID0gZWxlbWVudC5jbGllbnRXaWR0aDsKICAgIHZhciBoZWlnaHQgID0gZWxlbWVudC5jbGllbnRIZWlnaHQ7CgogICAgZWxlbWVudC5fb3JpZ2luYWxMZWZ0ICAgPSBsZWZ0IC0gcGFyc2VGbG9hdChlbGVtZW50LnN0eWxlLmxlZnQgIHx8IDApOwogICAgZWxlbWVudC5fb3JpZ2luYWxUb3AgICAgPSB0b3AgIC0gcGFyc2VGbG9hdChlbGVtZW50LnN0eWxlLnRvcCB8fCAwKTsKICAgIGVsZW1lbnQuX29yaWdpbmFsV2lkdGggID0gZWxlbWVudC5zdHlsZS53aWR0aDsKICAgIGVsZW1lbnQuX29yaWdpbmFsSGVpZ2h0ID0gZWxlbWVudC5zdHlsZS5oZWlnaHQ7CgogICAgZWxlbWVudC5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7CiAgICBlbGVtZW50LnN0eWxlLnRvcCAgICA9IHRvcCArICdweCc7OwogICAgZWxlbWVudC5zdHlsZS5sZWZ0ICAgPSBsZWZ0ICsgJ3B4Jzs7CiAgICBlbGVtZW50LnN0eWxlLndpZHRoICA9IHdpZHRoICsgJ3B4Jzs7CiAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGhlaWdodCArICdweCc7OwogIH0sCgogIHJlbGF0aXZpemU6IGZ1bmN0aW9uKGVsZW1lbnQpIHsKICAgIGVsZW1lbnQgPSAkKGVsZW1lbnQpOwogICAgaWYgKGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPT0gJ3JlbGF0aXZlJykgcmV0dXJuOwogICAgUG9zaXRpb24ucHJlcGFyZSgpOwoKICAgIGVsZW1lbnQuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnOwogICAgdmFyIHRvcCAgPSBwYXJzZUZsb2F0KGVsZW1lbnQuc3R5bGUudG9wICB8fCAwKSAtIChlbGVtZW50Ll9vcmlnaW5hbFRvcCB8fCAwKTsKICAgIHZhciBsZWZ0ID0gcGFyc2VGbG9hdChlbGVtZW50LnN0eWxlLmxlZnQgfHwgMCkgLSAoZWxlbWVudC5fb3JpZ2luYWxMZWZ0IHx8IDApOwoKICAgIGVsZW1lbnQuc3R5bGUudG9wICAgID0gdG9wICsgJ3B4JzsKICAgIGVsZW1lbnQuc3R5bGUubGVmdCAgID0gbGVmdCArICdweCc7CiAgICBlbGVtZW50LnN0eWxlLmhlaWdodCA9IGVsZW1lbnQuX29yaWdpbmFsSGVpZ2h0OwogICAgZWxlbWVudC5zdHlsZS53aWR0aCAgPSBlbGVtZW50Ll9vcmlnaW5hbFdpZHRoOwogIH0KfQoKLy8gU2FmYXJpIHJldHVybnMgbWFyZ2lucyBvbiBib2R5IHdoaWNoIGlzIGluY29ycmVjdCBpZiB0aGUgY2hpbGQgaXMgYWJzb2x1dGVseQovLyBwb3NpdGlvbmVkLiAgRm9yIHBlcmZvcm1hbmNlIHJlYXNvbnMsIHJlZGVmaW5lIFBvc2l0aW9uLmN1bXVsYXRpdmVPZmZzZXQgZm9yCi8vIEtIVE1ML1dlYktpdCBvbmx5LgppZiAoL0tvbnF1ZXJvcnxTYWZhcml8S0hUTUwvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkpIHsKICBQb3NpdGlvbi5jdW11bGF0aXZlT2Zmc2V0ID0gZnVuY3Rpb24oZWxlbWVudCkgewogICAgdmFyIHZhbHVlVCA9IDAsIHZhbHVlTCA9IDA7CiAgICBkbyB7CiAgICAgIHZhbHVlVCArPSBlbGVtZW50Lm9mZnNldFRvcCAgfHwgMDsKICAgICAgdmFsdWVMICs9IGVsZW1lbnQub2Zmc2V0TGVmdCB8fCAwOwogICAgICBpZiAoZWxlbWVudC5vZmZzZXRQYXJlbnQgPT0gZG9jdW1lbnQuYm9keSkKICAgICAgICBpZiAoRWxlbWVudC5nZXRTdHlsZShlbGVtZW50LCAncG9zaXRpb24nKSA9PSAnYWJzb2x1dGUnKSBicmVhazsKCiAgICAgIGVsZW1lbnQgPSBlbGVtZW50Lm9mZnNldFBhcmVudDsKICAgIH0gd2hpbGUgKGVsZW1lbnQpOwoKICAgIHJldHVybiBbdmFsdWVMLCB2YWx1ZVRdOwogIH0KfQoKRWxlbWVudC5hZGRNZXRob2RzKCk7