Created
July 12, 2024 14:13
-
-
Save chenxiaoyao6228/a94b6459e11c4b799322bacf3d926d1c to your computer and use it in GitHub Desktop.
title: angular-starter
description: editId: null
description: meta data description for code-studio
title: angular-starter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{"title":"untitled","description":"meta data description for code-studio","created_at":"2024-07-12 14:12:53","updated_at":"2024-07-12 14:12:53"} |
This file has been truncated, but you can view the full file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
data:application/zip;base64,UEsDBAoAAAAAAJpx7FgAAAAAAAAAAAAAAAAJAAAALmFuZ3VsYXIvUEsDBAoAAAAAAJpx7FgAAAAAAAAAAAAAAAAPAAAALmFuZ3VsYXIvY2FjaGUvUEsDBAoAAAAAAJpx7FgAAAAAAAAAAAAAAAAWAAAALmFuZ3VsYXIvY2FjaGUvMTguMC42L1BLAwQKAAAAAACacexYAAAAAAAAAAAAAAAAGwAAAC5hbmd1bGFyL2NhY2hlLzE4LjAuNi92aXRlL1BLAwQKAAAAAACacexYAAAAAAAAAAAAAAAAIAAAAC5hbmd1bGFyL2NhY2hlLzE4LjAuNi92aXRlL2RlcHMvUEsDBAoAAAAAAJpx7FiGWBIa9lsAAPZbAAAwAAAALmFuZ3VsYXIvY2FjaGUvMTguMC42L3ZpdGUvZGVwcy9AYW5ndWxhcl9jb3JlLmpzaW1wb3J0IHsKICBBTExPV19NVUxUSVBMRV9QTEFURk9STVMsCiAgQU5JTUFUSU9OX01PRFVMRV9UWVBFLAogIEFQUF9CT09UU1RSQVBfTElTVEVORVIsCiAgQVBQX0lELAogIEFQUF9JTklUSUFMSVpFUiwKICBBZnRlclJlbmRlckV2ZW50TWFuYWdlciwKICBBZnRlclJlbmRlclBoYXNlLAogIEFwcGxpY2F0aW9uSW5pdFN0YXR1cywKICBBcHBsaWNhdGlvbk1vZHVsZSwKICBBcHBsaWNhdGlvblJlZiwKICBBdHRyaWJ1dGUsCiAgQ09NUElMRVJfT1BUSU9OUywKICBDT05UQUlORVJfSEVBREVSX09GRlNFVCwKICBDU1BfTk9OQ0UsCiAgQ1VTVE9NX0VMRU1FTlRTX1NDSEVNQSwKICBDaGFuZ2VEZXRlY3Rpb25TY2hlZHVsZXIsCiAgQ2hhbmdlRGV0ZWN0aW9uU2NoZWR1bGVySW1wbCwKICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwKICBDaGFuZ2VEZXRlY3RvclJlZiwKICBDb21waWxlciwKICBDb21waWxlckZhY3RvcnksCiAgQ29tcG9uZW50LAogIENvbXBvbmVudEZhY3RvcnksCiAgQ29tcG9uZW50RmFjdG9yeSQxLAogIENvbXBvbmVudEZhY3RvcnlSZXNvbHZlciQxLAogIENvbXBvbmVudFJlZiwKICBDb21wb25lbnRSZWYkMSwKICBDb25zb2xlLAogIENvbnRlbnRDaGlsZCwKICBDb250ZW50Q2hpbGRyZW4sCiAgREVGQVVMVF9DVVJSRU5DWV9DT0RFLAogIERFRkFVTFRfTE9DQUxFX0lELAogIERFRkVSX0JMT0NLX0NPTkZJRywKICBERUZFUl9CTE9DS19ERVBFTkRFTkNZX0lOVEVSQ0VQVE9SLAogIERlYnVnRWxlbWVudCwKICBEZWJ1Z0V2ZW50TGlzdGVuZXIsCiAgRGVidWdOb2RlLAogIERlZmF1bHRJdGVyYWJsZURpZmZlciwKICBEZWZlckJsb2NrQmVoYXZpb3IsCiAgRGVmZXJCbG9ja1N0YXRlLAogIERlc3Ryb3lSZWYsCiAgRGlyZWN0aXZlLAogIEVOVklST05NRU5UX0lOSVRJQUxJWkVSLAogIEVmZmVjdFNjaGVkdWxlciwKICBFbGVtZW50UmVmLAogIEVtYmVkZGVkVmlld1JlZiwKICBFbnZpcm9ubWVudEluamVjdG9yLAogIEVycm9ySGFuZGxlciwKICBFdmVudEVtaXR0ZXIsCiAgRXhwZXJpbWVudGFsUGVuZGluZ1Rhc2tzLAogIEZhY3RvcnlUYXJnZXQsCiAgSE9TVF9UQUdfTkFNRSwKICBIb3N0LAogIEhvc3RBdHRyaWJ1dGVUb2tlbiwKICBIb3N0QmluZGluZywKICBIb3N0TGlzdGVuZXIsCiAgSU1BR0VfQ09ORklHLAogIElNQUdFX0NPTkZJR19ERUZBVUxUUywKICBJTkpFQ1RPUiQxLAogIElOSkVDVE9SX1NDT1BFLAogIElTX0hZRFJBVElPTl9ET01fUkVVU0VfRU5BQkxFRCwKICBJbmplY3QsCiAgSW5qZWN0RmxhZ3MsCiAgSW5qZWN0YWJsZSwKICBJbmplY3Rpb25Ub2tlbiwKICBJbmplY3RvciwKICBJbnB1dCwKICBJdGVyYWJsZURpZmZlcnMsCiAgS2V5VmFsdWVEaWZmZXJzLAogIExDb250ZXh0LAogIExPQ0FMRV9JRCwKICBMaWZlY3ljbGVIb29rc0ZlYXR1cmUsCiAgTG9jYWxlRGF0YUluZGV4LAogIE1pc3NpbmdUcmFuc2xhdGlvblN0cmF0ZWd5LAogIE1vZHVsZVdpdGhDb21wb25lbnRGYWN0b3JpZXMsCiAgTkdfQ09NUF9ERUYsCiAgTkdfRElSX0RFRiwKICBOR19FTEVNRU5UX0lELAogIE5HX0lOSl9ERUYsCiAgTkdfTU9EX0RFRiwKICBOR19QSVBFX0RFRiwKICBOR19QUk9WX0RFRiwKICBOT1RfRk9VTkRfQ0hFQ0tfT05MWV9FTEVNRU5UX0lOSkVDVE9SLAogIE5PX0NIQU5HRSwKICBOT19FUlJPUlNfU0NIRU1BLAogIE5nTW9kdWxlLAogIE5nTW9kdWxlRmFjdG9yeSwKICBOZ01vZHVsZUZhY3RvcnkkMSwKICBOZ01vZHVsZVJlZiwKICBOZ01vZHVsZVJlZiQxLAogIE5nUHJvYmVUb2tlbiwKICBOZ1pvbmUsCiAgTm9vcE5nWm9uZSwKICBPcHRpb25hbCwKICBPdXRwdXQsCiAgT3V0cHV0RW1pdHRlclJlZiwKICBQQUNLQUdFX1JPT1RfVVJMLAogIFBMQVRGT1JNX0lELAogIFBMQVRGT1JNX0lOSVRJQUxJWkVSLAogIFBST1ZJREVEX05HX1pPTkUsCiAgUGVuZGluZ1Rhc2tzLAogIFBpcGUsCiAgUGxhdGZvcm1SZWYsCiAgUXVlcnksCiAgUXVlcnlMaXN0LAogIFJlZmxlY3Rpb25DYXBhYmlsaXRpZXMsCiAgUmVuZGVyZXIyLAogIFJlbmRlcmVyRmFjdG9yeTIsCiAgUmVuZGVyZXJTdHlsZUZsYWdzMiwKICBSdW50aW1lRXJyb3IsCiAgU1NSX0NPTlRFTlRfSU5URUdSSVRZX01BUktFUiwKICBTYW5pdGl6ZXIsCiAgU2VjdXJpdHlDb250ZXh0LAogIFNlbGYsCiAgU2ltcGxlQ2hhbmdlLAogIFNraXBTZWxmLAogIFRFU1RBQklMSVRZLAogIFRFU1RBQklMSVRZX0dFVFRFUiwKICBUUkFOU0xBVElPTlMsCiAgVFJBTlNMQVRJT05TX0ZPUk1BVCwKICBUZW1wbGF0ZVJlZiwKICBUZXN0YWJpbGl0eSwKICBUZXN0YWJpbGl0eVJlZ2lzdHJ5LAogIFRyYW5zZmVyU3RhdGUsCiAgVHlwZSwKICBVU0VfUlVOVElNRV9ERVBTX1RSQUNLRVJfRk9SX0pJVCwKICBWRVJTSU9OLAogIFZlcnNpb24sCiAgVmlld0NoaWxkLAogIFZpZXdDaGlsZHJlbiwKICBWaWV3Q29udGFpbmVyUmVmLAogIFZpZXdFbmNhcHN1bGF0aW9uJDEsCiAgVmlld1JlZiwKICBWaWV3UmVmJDEsCiAgWFNTX1NFQ1VSSVRZX1VSTCwKICBaT05FTEVTU19FTkFCTEVELAogIF9nbG9iYWwsCiAgX3Nhbml0aXplSHRtbCwKICBfc2FuaXRpemVVcmwsCiAgYWZ0ZXJOZXh0UmVuZGVyLAogIGFmdGVyUmVuZGVyLAogIGFsbG93U2FuaXRpemF0aW9uQnlwYXNzQW5kVGhyb3csCiAgYW5ub3RhdGVGb3JIeWRyYXRpb24sCiAgYXNOYXRpdmVFbGVtZW50cywKICBhc3NlcnRJbkluamVjdGlvbkNvbnRleHQsCiAgYXNzZXJ0Tm90SW5SZWFjdGl2ZUNvbnRleHQsCiAgYXNzZXJ0UGxhdGZvcm0sCiAgYm9vbGVhbkF0dHJpYnV0ZSwKICBieXBhc3NTYW5pdGl6YXRpb25UcnVzdEh0bWwsCiAgYnlwYXNzU2FuaXRpemF0aW9uVHJ1c3RSZXNvdXJjZVVybCwKICBieXBhc3NTYW5pdGl6YXRpb25UcnVzdFNjcmlwdCwKICBieXBhc3NTYW5pdGl6YXRpb25UcnVzdFN0eWxlLAogIGJ5cGFzc1Nhbml0aXphdGlvblRydXN0VXJsLAogIGNsZWFyUmVzb2x1dGlvbk9mQ29tcG9uZW50UmVzb3VyY2VzUXVldWUsCiAgY29tcGlsZUNvbXBvbmVudCwKICBjb21waWxlRGlyZWN0aXZlLAogIGNvbXBpbGVOZ01vZHVsZSwKICBjb21waWxlTmdNb2R1bGVEZWZzLAogIGNvbXBpbGVOZ01vZHVsZUZhY3RvcnksCiAgY29tcGlsZVBpcGUsCiAgY29tcHV0ZWQsCiAgY29udGVudENoaWxkLAogIGNvbnRlbnRDaGlsZHJlbiwKICBjb252ZXJ0VG9CaXRGbGFncywKICBjcmVhdGVDb21wb25lbnQsCiAgY3JlYXRlRW52aXJvbm1lbnRJbmplY3RvciwKICBjcmVhdGVJbmplY3RvciwKICBjcmVhdGVOZ01vZHVsZSwKICBjcmVhdGVOZ01vZHVsZVJlZiwKICBjcmVhdGVQbGF0Zm9ybSwKICBjcmVhdGVQbGF0Zm9ybUZhY3RvcnksCiAgZGVmYXVsdEl0ZXJhYmxlRGlmZmVycywKICBkZWZhdWx0S2V5VmFsdWVEaWZmZXJzLAogIGRlZmluZUluamVjdGFibGUsCiAgZGVwc1RyYWNrZXIsCiAgZGVzdHJveVBsYXRmb3JtLAogIGRldGVjdENoYW5nZXNJblZpZXdJZlJlcXVpcmVkLAogIGRldk1vZGVFcXVhbCwKICBlZmZlY3QsCiAgZW5hYmxlUHJvZE1vZGUsCiAgZmluZExvY2FsZURhdGEsCiAgZmx1c2hNb2R1bGVTY29waW5nUXVldWVBc011Y2hBc1Bvc3NpYmxlLAogIGZvcm1hdFJ1bnRpbWVFcnJvciwKICBmb3J3YXJkUmVmLAogIGdlbmVyYXRlU3RhbmRhbG9uZUluRGVjbGFyYXRpb25zRXJyb3IsCiAgZ2V0QXN5bmNDbGFzc01ldGFkYXRhRm4sCiAgZ2V0RGVidWdOb2RlLAogIGdldERlZmVyQmxvY2tzLAogIGdldERpcmVjdGl2ZXMsCiAgZ2V0SG9zdEVsZW1lbnQsCiAgZ2V0SW5qZWN0YWJsZURlZiwKICBnZXRMQ29udGV4dCwKICBnZXRMb2NhbGVDdXJyZW5jeUNvZGUsCiAgZ2V0TG9jYWxlUGx1cmFsQ2FzZSwKICBnZXRNb2R1bGVGYWN0b3J5LAogIGdldE5nTW9kdWxlQnlJZCwKICBnZXRPdXRwdXREZXN0cm95UmVmLAogIGdldFBsYXRmb3JtLAogIGdldFNhbml0aXphdGlvbkJ5cGFzc1R5cGUsCiAgaW1wb3J0UHJvdmlkZXJzRnJvbSwKICBpbmplY3QsCiAgaW5qZWN0Q2hhbmdlRGV0ZWN0b3JSZWYsCiAgaW5wdXQsCiAgaW50ZXJuYWxBZnRlck5leHRSZW5kZXIsCiAgaW50ZXJuYWxDcmVhdGVBcHBsaWNhdGlvbiwKICBpbnRlcm5hbFByb3ZpZGVab25lQ2hhbmdlRGV0ZWN0aW9uLAogIGlzQm91bmRUb01vZHVsZSwKICBpc0NvbXBvbmVudERlZlBlbmRpbmdSZXNvbHV0aW9uLAogIGlzRGV2TW9kZSwKICBpc0Vudmlyb25tZW50UHJvdmlkZXJzLAogIGlzSW5qZWN0YWJsZSwKICBpc05nTW9kdWxlLAogIGlzUHJvbWlzZSwKICBpc1NpZ25hbCwKICBpc1N0YW5kYWxvbmUsCiAgaXNTdWJzY3JpYmFibGUsCiAgbWFrZUVudmlyb25tZW50UHJvdmlkZXJzLAogIG1ha2VTdGF0ZUtleSwKICBtZXJnZUFwcGxpY2F0aW9uQ29uZmlnLAogIG1vZGVsLAogIG5vU2lkZUVmZmVjdHMsCiAgbnVtYmVyQXR0cmlidXRlLAogIG91dHB1dCwKICBwYXRjaENvbXBvbmVudERlZldpdGhTY29wZSwKICBwZXJmb3JtYW5jZU1hcmtGZWF0dXJlLAogIHBsYXRmb3JtQ29yZSwKICBwcm92aWRlRXhwZXJpbWVudGFsQ2hlY2tOb0NoYW5nZXNGb3JEZWJ1ZywKICBwcm92aWRlRXhwZXJpbWVudGFsWm9uZWxlc3NDaGFuZ2VEZXRlY3Rpb24sCiAgcHJvdmlkZVpvbmVDaGFuZ2VEZXRlY3Rpb24sCiAgcXVldWVTdGF0ZVVwZGF0ZSwKICByZWFkSHlkcmF0aW9uSW5mbywKICByZWZsZWN0Q29tcG9uZW50VHlwZSwKICByZWdpc3RlckxvY2FsZURhdGEsCiAgcmVnaXN0ZXJOZ01vZHVsZVR5cGUsCiAgcmVuZGVyRGVmZXJCbG9ja1N0YXRlLAogIHJlc2V0Q29tcGlsZWRDb21wb25lbnRzLAogIHJlc2V0Sml0T3B0aW9ucywKICByZXNvbHZlQ29tcG9uZW50UmVzb3VyY2VzLAogIHJlc29sdmVGb3J3YXJkUmVmLAogIHJlc3RvcmVDb21wb25lbnRSZXNvbHV0aW9uUXVldWUsCiAgcnVuSW5JbmplY3Rpb25Db250ZXh0LAogIHNldEFsbG93RHVwbGljYXRlTmdNb2R1bGVJZHNGb3JUZXN0LAogIHNldEFsdGVybmF0ZVdlYWtSZWZJbXBsLAogIHNldENsYXNzTWV0YWRhdGEsCiAgc2V0Q2xhc3NNZXRhZGF0YUFzeW5jLAogIHNldEN1cnJlbnRJbmplY3RvciwKICBzZXREb2N1bWVudCwKICBzZXRJbmplY3RvclByb2ZpbGVyQ29udGV4dCwKICBzZXRMb2NhbGVJZCwKICBzZXRUZXN0YWJpbGl0eUdldHRlciwKICBzaWduYWwsCiAgc3RvcmUsCiAgc3RyaW5naWZ5LAogIHRyYW5zaXRpdmVTY29wZXNGb3IsCiAgdHJpZ2dlclJlc291cmNlTG9hZGluZywKICB0cnVuY2F0ZU1pZGRsZSwKICB1bnJlZ2lzdGVyQWxsTG9jYWxlRGF0YSwKICB1bnRyYWNrZWQsCiAgdW53cmFwU2FmZVZhbHVlLAogIHZpZXdDaGlsZCwKICB2aWV3Q2hpbGRyZW4sCiAgd2hlblN0YWJsZSwKICB3aXRoRG9tSHlkcmF0aW9uLAogIHdpdGhFdmVudFJlcGxheSwKICB3aXRoSTE4blN1cHBvcnQsCiAgybVJTlBVVF9TSUdOQUxfQlJBTkRfV1JJVEVfVFlQRSwKICDJtWdldFVua25vd25FbGVtZW50U3RyaWN0TW9kZSwKICDJtWdldFVua25vd25Qcm9wZXJ0eVN0cmljdE1vZGUsCiAgybVzZXRDbGFzc0RlYnVnSW5mbywKICDJtXNldFVua25vd25FbGVtZW50U3RyaWN0TW9kZSwKICDJtXNldFVua25vd25Qcm9wZXJ0eVN0cmljdE1vZGUsCiAgybV1bndyYXBXcml0YWJsZVNpZ25hbCwKICDJtcm1Q29weURlZmluaXRpb25GZWF0dXJlLAogIMm1ybVIb3N0RGlyZWN0aXZlc0ZlYXR1cmUsCiAgybXJtUluaGVyaXREZWZpbml0aW9uRmVhdHVyZSwKICDJtcm1SW5wdXRUcmFuc2Zvcm1zRmVhdHVyZSwKICDJtcm1TmdPbkNoYW5nZXNGZWF0dXJlLAogIMm1ybVQcm92aWRlcnNGZWF0dXJlLAogIMm1ybVTdGFuZGFsb25lRmVhdHVyZSwKICDJtcm1YWR2YW5jZSwKICDJtcm1YXR0cmlidXRlLAogIMm1ybVhdHRyaWJ1dGVJbnRlcnBvbGF0ZTEsCiAgybXJtWF0dHJpYnV0ZUludGVycG9sYXRlMiwKICDJtcm1YXR0cmlidXRlSW50ZXJwb2xhdGUzLAogIMm1ybVhdHRyaWJ1dGVJbnRlcnBvbGF0ZTQsCiAgybXJtWF0dHJpYnV0ZUludGVycG9sYXRlNSwKICDJtcm1YXR0cmlidXRlSW50ZXJwb2xhdGU2LAogIMm1ybVhdHRyaWJ1dGVJbnRlcnBvbGF0ZTcsCiAgybXJtWF0dHJpYnV0ZUludGVycG9sYXRlOCwKICDJtcm1YXR0cmlidXRlSW50ZXJwb2xhdGVWLAogIMm1ybVjbGFzc01hcCwKICDJtcm1Y2xhc3NNYXBJbnRlcnBvbGF0ZTEsCiAgybXJtWNsYXNzTWFwSW50ZXJwb2xhdGUyLAogIMm1ybVjbGFzc01hcEludGVycG9sYXRlMywKICDJtcm1Y2xhc3NNYXBJbnRlcnBvbGF0ZTQsCiAgybXJtWNsYXNzTWFwSW50ZXJwb2xhdGU1LAogIMm1ybVjbGFzc01hcEludGVycG9sYXRlNiwKICDJtcm1Y2xhc3NNYXBJbnRlcnBvbGF0ZTcsCiAgybXJtWNsYXNzTWFwSW50ZXJwb2xhdGU4LAogIMm1ybVjbGFzc01hcEludGVycG9sYXRlViwKICDJtcm1Y2xhc3NQcm9wLAogIMm1ybVjb21wb25lbnRJbnN0YW5jZSwKICDJtcm1Y29uZGl0aW9uYWwsCiAgybXJtWNvbnRlbnRRdWVyeSwKICDJtcm1Y29udGVudFF1ZXJ5U2lnbmFsLAogIMm1ybVkZWNsYXJlTGV0LAogIMm1ybVkZWZlciwKICDJtcm1ZGVmZXJFbmFibGVUaW1lclNjaGVkdWxpbmcsCiAgybXJtWRlZmVyT25Ib3ZlciwKICDJtcm1ZGVmZXJPbklkbGUsCiAgybXJtWRlZmVyT25JbW1lZGlhdGUsCiAgybXJtWRlZmVyT25JbnRlcmFjdGlvbiwKICDJtcm1ZGVmZXJPblRpbWVyLAogIMm1ybVkZWZlck9uVmlld3BvcnQsCiAgybXJtWRlZmVyUHJlZmV0Y2hPbkhvdmVyLAogIMm1ybVkZWZlclByZWZldGNoT25JZGxlLAogIMm1ybVkZWZlclByZWZldGNoT25JbW1lZGlhdGUsCiAgybXJtWRlZmVyUHJlZmV0Y2hPbkludGVyYWN0aW9uLAogIMm1ybVkZWZlclByZWZldGNoT25UaW1lciwKICDJtcm1ZGVmZXJQcmVmZXRjaE9uVmlld3BvcnQsCiAgybXJtWRlZmVyUHJlZmV0Y2hXaGVuLAogIMm1ybVkZWZlcldoZW4sCiAgybXJtWRlZmluZUNvbXBvbmVudCwKICDJtcm1ZGVmaW5lRGlyZWN0aXZlLAogIMm1ybVkZWZpbmVJbmplY3RhYmxlLAogIMm1ybVkZWZpbmVJbmplY3RvciwKICDJtcm1ZGVmaW5lTmdNb2R1bGUsCiAgybXJtWRlZmluZVBpcGUsCiAgybXJtWRpcmVjdGl2ZUluamVjdCwKICDJtcm1ZGlzYWJsZUJpbmRpbmdzLAogIMm1ybVlbGVtZW50LAogIMm1ybVlbGVtZW50Q29udGFpbmVyLAogIMm1ybVlbGVtZW50Q29udGFpbmVyRW5kLAogIMm1ybVlbGVtZW50Q29udGFpbmVyU3RhcnQsCiAgybXJtWVsZW1lbnRFbmQsCiAgybXJtWVsZW1lbnRTdGFydCwKICDJtcm1ZW5hYmxlQmluZGluZ3MsCiAgybXJtWdldENvbXBvbmVudERlcHNGYWN0b3J5LAogIMm1ybVnZXRDdXJyZW50VmlldywKICDJtcm1Z2V0SW5oZXJpdGVkRmFjdG9yeSwKICDJtcm1aG9zdFByb3BlcnR5LAogIMm1ybVpMThuLAogIMm1ybVpMThuQXBwbHksCiAgybXJtWkxOG5BdHRyaWJ1dGVzLAogIMm1ybVpMThuRW5kLAogIMm1ybVpMThuRXhwLAogIMm1ybVpMThuUG9zdHByb2Nlc3MsCiAgybXJtWkxOG5TdGFydCwKICDJtcm1aW5qZWN0LAogIMm1ybVpbmplY3RBdHRyaWJ1dGUsCiAgybXJtWludmFsaWRGYWN0b3J5LAogIMm1ybVpbnZhbGlkRmFjdG9yeURlcCwKICDJtcm1bGlzdGVuZXIsCiAgybXJtWxvYWRRdWVyeSwKICDJtcm1bmFtZXNwYWNlSFRNTCwKICDJtcm1bmFtZXNwYWNlTWF0aE1MLAogIMm1ybVuYW1lc3BhY2VTVkcsCiAgybXJtW5leHRDb250ZXh0LAogIMm1ybVuZ0RlY2xhcmVDbGFzc01ldGFkYXRhLAogIMm1ybVuZ0RlY2xhcmVDbGFzc01ldGFkYXRhQXN5bmMsCiAgybXJtW5nRGVjbGFyZUNvbXBvbmVudCwKICDJtcm1bmdEZWNsYXJlRGlyZWN0aXZlLAogIMm1ybVuZ0RlY2xhcmVGYWN0b3J5LAogIMm1ybVuZ0RlY2xhcmVJbmplY3RhYmxlLAogIMm1ybVuZ0RlY2xhcmVJbmplY3RvciwKICDJtcm1bmdEZWNsYXJlTmdNb2R1bGUsCiAgybXJtW5nRGVjbGFyZVBpcGUsCiAgybXJtXBpcGUsCiAgybXJtXBpcGVCaW5kMSwKICDJtcm1cGlwZUJpbmQyLAogIMm1ybVwaXBlQmluZDMsCiAgybXJtXBpcGVCaW5kNCwKICDJtcm1cGlwZUJpbmRWLAogIMm1ybVwcm9qZWN0aW9uLAogIMm1ybVwcm9qZWN0aW9uRGVmLAogIMm1ybVwcm9wZXJ0eSwKICDJtcm1cHJvcGVydHlJbnRlcnBvbGF0ZSwKICDJtcm1cHJvcGVydHlJbnRlcnBvbGF0ZTEsCiAgybXJtXByb3BlcnR5SW50ZXJwb2xhdGUyLAogIMm1ybVwcm9wZXJ0eUludGVycG9sYXRlMywKICDJtcm1cHJvcGVydHlJbnRlcnBvbGF0ZTQsCiAgybXJtXByb3BlcnR5SW50ZXJwb2xhdGU1LAogIMm1ybVwcm9wZXJ0eUludGVycG9sYXRlNiwKICDJtcm1cHJvcGVydHlJbnRlcnBvbGF0ZTcsCiAgybXJtXByb3BlcnR5SW50ZXJwb2xhdGU4LAogIMm1ybVwcm9wZXJ0eUludGVycG9sYXRlViwKICDJtcm1cHVyZUZ1bmN0aW9uMCwKICDJtcm1cHVyZUZ1bmN0aW9uMSwKICDJtcm1cHVyZUZ1bmN0aW9uMiwKICDJtcm1cHVyZUZ1bmN0aW9uMywKICDJtcm1cHVyZUZ1bmN0aW9uNCwKICDJtcm1cHVyZUZ1bmN0aW9uNSwKICDJtcm1cHVyZUZ1bmN0aW9uNiwKICDJtcm1cHVyZUZ1bmN0aW9uNywKICDJtcm1cHVyZUZ1bmN0aW9uOCwKICDJtcm1cHVyZUZ1bmN0aW9uViwKICDJtcm1cXVlcnlBZHZhbmNlLAogIMm1ybVxdWVyeVJlZnJlc2gsCiAgybXJtXJlYWRDb250ZXh0TGV0LAogIMm1ybVyZWZlcmVuY2UsCiAgybXJtXJlcGVhdGVyLAogIMm1ybVyZXBlYXRlckNyZWF0ZSwKICDJtcm1cmVwZWF0ZXJUcmFja0J5SWRlbnRpdHksCiAgybXJtXJlcGVhdGVyVHJhY2tCeUluZGV4LAogIMm1ybVyZXNldFZpZXcsCiAgybXJtXJlc29sdmVCb2R5LAogIMm1ybVyZXNvbHZlRG9jdW1lbnQsCiAgybXJtXJlc29sdmVXaW5kb3csCiAgybXJtXJlc3RvcmVWaWV3LAogIMm1ybVzYW5pdGl6ZUh0bWwsCiAgybXJtXNhbml0aXplUmVzb3VyY2VVcmwsCiAgybXJtXNhbml0aXplU2NyaXB0LAogIMm1ybVzYW5pdGl6ZVN0eWxlLAogIMm1ybVzYW5pdGl6ZVVybCwKICDJtcm1c2FuaXRpemVVcmxPclJlc291cmNlVXJsLAogIMm1ybVzZXRDb21wb25lbnRTY29wZSwKICDJtcm1c2V0TmdNb2R1bGVTY29wZSwKICDJtcm1c3RvcmVMZXQsCiAgybXJtXN0eWxlTWFwLAogIMm1ybVzdHlsZU1hcEludGVycG9sYXRlMSwKICDJtcm1c3R5bGVNYXBJbnRlcnBvbGF0ZTIsCiAgybXJtXN0eWxlTWFwSW50ZXJwb2xhdGUzLAogIMm1ybVzdHlsZU1hcEludGVycG9sYXRlNCwKICDJtcm1c3R5bGVNYXBJbnRlcnBvbGF0ZTUsCiAgybXJtXN0eWxlTWFwSW50ZXJwb2xhdGU2LAogIMm1ybVzdHlsZU1hcEludGVycG9sYXRlNywKICDJtcm1c3R5bGVNYXBJbnRlcnBvbGF0ZTgsCiAgybXJtXN0eWxlTWFwSW50ZXJwb2xhdGVWLAogIMm1ybVzdHlsZVByb3AsCiAgybXJtXN0eWxlUHJvcEludGVycG9sYXRlMSwKICDJtcm1c3R5bGVQcm9wSW50ZXJwb2xhdGUyLAogIMm1ybVzdHlsZVByb3BJbnRlcnBvbGF0ZTMsCiAgybXJtXN0eWxlUHJvcEludGVycG9sYXRlNCwKICDJtcm1c3R5bGVQcm9wSW50ZXJwb2xhdGU1LAogIMm1ybVzdHlsZVByb3BJbnRlcnBvbGF0ZTYsCiAgybXJtXN0eWxlUHJvcEludGVycG9sYXRlNywKICDJtcm1c3R5bGVQcm9wSW50ZXJwb2xhdGU4LAogIMm1ybVzdHlsZVByb3BJbnRlcnBvbGF0ZVYsCiAgybXJtXN5bnRoZXRpY0hvc3RMaXN0ZW5lciwKICDJtcm1c3ludGhldGljSG9zdFByb3BlcnR5LAogIMm1ybV0ZW1wbGF0ZSwKICDJtcm1dGVtcGxhdGVSZWZFeHRyYWN0b3IsCiAgybXJtXRleHQsCiAgybXJtXRleHRJbnRlcnBvbGF0ZSwKICDJtcm1dGV4dEludGVycG9sYXRlMSwKICDJtcm1dGV4dEludGVycG9sYXRlMiwKICDJtcm1dGV4dEludGVycG9sYXRlMywKICDJtcm1dGV4dEludGVycG9sYXRlNCwKICDJtcm1dGV4dEludGVycG9sYXRlNSwKICDJtcm1dGV4dEludGVycG9sYXRlNiwKICDJtcm1dGV4dEludGVycG9sYXRlNywKICDJtcm1dGV4dEludGVycG9sYXRlOCwKICDJtcm1dGV4dEludGVycG9sYXRlViwKICDJtcm1dHJ1c3RDb25zdGFudEh0bWwsCiAgybXJtXRydXN0Q29uc3RhbnRSZXNvdXJjZVVybCwKICDJtcm1dHdvV2F5QmluZGluZ1NldCwKICDJtcm1dHdvV2F5TGlzdGVuZXIsCiAgybXJtXR3b1dheVByb3BlcnR5LAogIMm1ybV2YWxpZGF0ZUlmcmFtZUF0dHJpYnV0ZSwKICDJtcm1dmlld1F1ZXJ5LAogIMm1ybV2aWV3UXVlcnlTaWduYWwKfSBmcm9tICIuL2NodW5rLUJOTlNDWkpXLmpzIjsKaW1wb3J0ICIuL2NodW5rLVRTWk9TV0VTLmpzIjsKZXhwb3J0IHsKICBBTklNQVRJT05fTU9EVUxFX1RZUEUsCiAgQVBQX0JPT1RTVFJBUF9MSVNURU5FUiwKICBBUFBfSUQsCiAgQVBQX0lOSVRJQUxJWkVSLAogIEFmdGVyUmVuZGVyUGhhc2UsCiAgQXBwbGljYXRpb25Jbml0U3RhdHVzLAogIEFwcGxpY2F0aW9uTW9kdWxlLAogIEFwcGxpY2F0aW9uUmVmLAogIEF0dHJpYnV0ZSwKICBDT01QSUxFUl9PUFRJT05TLAogIENTUF9OT05DRSwKICBDVVNUT01fRUxFTUVOVFNfU0NIRU1BLAogIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LAogIENoYW5nZURldGVjdG9yUmVmLAogIENvbXBpbGVyLAogIENvbXBpbGVyRmFjdG9yeSwKICBDb21wb25lbnQsCiAgQ29tcG9uZW50RmFjdG9yeSQxIGFzIENvbXBvbmVudEZhY3RvcnksCiAgQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyJDEgYXMgQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLAogIENvbXBvbmVudFJlZiQxIGFzIENvbXBvbmVudFJlZiwKICBDb250ZW50Q2hpbGQsCiAgQ29udGVudENoaWxkcmVuLAogIERFRkFVTFRfQ1VSUkVOQ1lfQ09ERSwKICBEZWJ1Z0VsZW1lbnQsCiAgRGVidWdFdmVudExpc3RlbmVyLAogIERlYnVnTm9kZSwKICBEZWZhdWx0SXRlcmFibGVEaWZmZXIsCiAgRGVzdHJveVJlZiwKICBEaXJlY3RpdmUsCiAgRU5WSVJPTk1FTlRfSU5JVElBTElaRVIsCiAgRWxlbWVudFJlZiwKICBFbWJlZGRlZFZpZXdSZWYsCiAgRW52aXJvbm1lbnRJbmplY3RvciwKICBFcnJvckhhbmRsZXIsCiAgRXZlbnRFbWl0dGVyLAogIEV4cGVyaW1lbnRhbFBlbmRpbmdUYXNrcywKICBIT1NUX1RBR19OQU1FLAogIEhvc3QsCiAgSG9zdEF0dHJpYnV0ZVRva2VuLAogIEhvc3RCaW5kaW5nLAogIEhvc3RMaXN0ZW5lciwKICBJTkpFQ1RPUiQxIGFzIElOSkVDVE9SLAogIEluamVjdCwKICBJbmplY3RGbGFncywKICBJbmplY3RhYmxlLAogIEluamVjdGlvblRva2VuLAogIEluamVjdG9yLAogIElucHV0LAogIEl0ZXJhYmxlRGlmZmVycywKICBLZXlWYWx1ZURpZmZlcnMsCiAgTE9DQUxFX0lELAogIE1pc3NpbmdUcmFuc2xhdGlvblN0cmF0ZWd5LAogIE1vZHVsZVdpdGhDb21wb25lbnRGYWN0b3JpZXMsCiAgTk9fRVJST1JTX1NDSEVNQSwKICBOZ01vZHVsZSwKICBOZ01vZHVsZUZhY3RvcnkkMSBhcyBOZ01vZHVsZUZhY3RvcnksCiAgTmdNb2R1bGVSZWYkMSBhcyBOZ01vZHVsZVJlZiwKICBOZ1Byb2JlVG9rZW4sCiAgTmdab25lLAogIE9wdGlvbmFsLAogIE91dHB1dCwKICBPdXRwdXRFbWl0dGVyUmVmLAogIFBBQ0tBR0VfUk9PVF9VUkwsCiAgUExBVEZPUk1fSUQsCiAgUExBVEZPUk1fSU5JVElBTElaRVIsCiAgUGlwZSwKICBQbGF0Zm9ybVJlZiwKICBRdWVyeSwKICBRdWVyeUxpc3QsCiAgUmVuZGVyZXIyLAogIFJlbmRlcmVyRmFjdG9yeTIsCiAgUmVuZGVyZXJTdHlsZUZsYWdzMiwKICBTYW5pdGl6ZXIsCiAgU2VjdXJpdHlDb250ZXh0LAogIFNlbGYsCiAgU2ltcGxlQ2hhbmdlLAogIFNraXBTZWxmLAogIFRSQU5TTEFUSU9OUywKICBUUkFOU0xBVElPTlNfRk9STUFULAogIFRlbXBsYXRlUmVmLAogIFRlc3RhYmlsaXR5LAogIFRlc3RhYmlsaXR5UmVnaXN0cnksCiAgVHJhbnNmZXJTdGF0ZSwKICBUeXBlLAogIFZFUlNJT04sCiAgVmVyc2lvbiwKICBWaWV3Q2hpbGQsCiAgVmlld0NoaWxkcmVuLAogIFZpZXdDb250YWluZXJSZWYsCiAgVmlld0VuY2Fwc3VsYXRpb24kMSBhcyBWaWV3RW5jYXBzdWxhdGlvbiwKICBWaWV3UmVmLAogIGFmdGVyTmV4dFJlbmRlciwKICBhZnRlclJlbmRlciwKICBhc05hdGl2ZUVsZW1lbnRzLAogIGFzc2VydEluSW5qZWN0aW9uQ29udGV4dCwKICBhc3NlcnROb3RJblJlYWN0aXZlQ29udGV4dCwKICBhc3NlcnRQbGF0Zm9ybSwKICBib29sZWFuQXR0cmlidXRlLAogIGNvbXB1dGVkLAogIGNvbnRlbnRDaGlsZCwKICBjb250ZW50Q2hpbGRyZW4sCiAgY3JlYXRlQ29tcG9uZW50LAogIGNyZWF0ZUVudmlyb25tZW50SW5qZWN0b3IsCiAgY3JlYXRlTmdNb2R1bGUsCiAgY3JlYXRlTmdNb2R1bGVSZWYsCiAgY3JlYXRlUGxhdGZvcm0sCiAgY3JlYXRlUGxhdGZvcm1GYWN0b3J5LAogIGRlZmluZUluamVjdGFibGUsCiAgZGVzdHJveVBsYXRmb3JtLAogIGVmZmVjdCwKICBlbmFibGVQcm9kTW9kZSwKICBmb3J3YXJkUmVmLAogIGdldERlYnVnTm9kZSwKICBnZXRNb2R1bGVGYWN0b3J5LAogIGdldE5nTW9kdWxlQnlJZCwKICBnZXRQbGF0Zm9ybSwKICBpbXBvcnRQcm92aWRlcnNGcm9tLAogIGluamVjdCwKICBpbnB1dCwKICBpc0Rldk1vZGUsCiAgaXNTaWduYWwsCiAgaXNTdGFuZGFsb25lLAogIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycywKICBtYWtlU3RhdGVLZXksCiAgbWVyZ2VBcHBsaWNhdGlvbkNvbmZpZywKICBtb2RlbCwKICBudW1iZXJBdHRyaWJ1dGUsCiAgb3V0cHV0LAogIHBsYXRmb3JtQ29yZSwKICBwcm92aWRlRXhwZXJpbWVudGFsQ2hlY2tOb0NoYW5nZXNGb3JEZWJ1ZywKICBwcm92aWRlRXhwZXJpbWVudGFsWm9uZWxlc3NDaGFuZ2VEZXRlY3Rpb24sCiAgcHJvdmlkZVpvbmVDaGFuZ2VEZXRlY3Rpb24sCiAgcmVmbGVjdENvbXBvbmVudFR5cGUsCiAgcmVzb2x2ZUZvcndhcmRSZWYsCiAgcnVuSW5JbmplY3Rpb25Db250ZXh0LAogIHNldFRlc3RhYmlsaXR5R2V0dGVyLAogIHNpZ25hbCwKICB1bnRyYWNrZWQsCiAgdmlld0NoaWxkLAogIHZpZXdDaGlsZHJlbiwKICBBTExPV19NVUxUSVBMRV9QTEFURk9STVMgYXMgybVBTExPV19NVUxUSVBMRV9QTEFURk9STVMsCiAgQWZ0ZXJSZW5kZXJFdmVudE1hbmFnZXIgYXMgybVBZnRlclJlbmRlckV2ZW50TWFuYWdlciwKICBDT05UQUlORVJfSEVBREVSX09GRlNFVCBhcyDJtUNPTlRBSU5FUl9IRUFERVJfT0ZGU0VULAogIENoYW5nZURldGVjdGlvblNjaGVkdWxlciBhcyDJtUNoYW5nZURldGVjdGlvblNjaGVkdWxlciwKICBDaGFuZ2VEZXRlY3Rpb25TY2hlZHVsZXJJbXBsIGFzIMm1Q2hhbmdlRGV0ZWN0aW9uU2NoZWR1bGVySW1wbCwKICBDb21wb25lbnRGYWN0b3J5JDEgYXMgybVDb21wb25lbnRGYWN0b3J5LAogIENvbnNvbGUgYXMgybVDb25zb2xlLAogIERFRkFVTFRfTE9DQUxFX0lEIGFzIMm1REVGQVVMVF9MT0NBTEVfSUQsCiAgREVGRVJfQkxPQ0tfQ09ORklHIGFzIMm1REVGRVJfQkxPQ0tfQ09ORklHLAogIERFRkVSX0JMT0NLX0RFUEVOREVOQ1lfSU5URVJDRVBUT1IgYXMgybVERUZFUl9CTE9DS19ERVBFTkRFTkNZX0lOVEVSQ0VQVE9SLAogIERlZmVyQmxvY2tCZWhhdmlvciBhcyDJtURlZmVyQmxvY2tCZWhhdmlvciwKICBEZWZlckJsb2NrU3RhdGUgYXMgybVEZWZlckJsb2NrU3RhdGUsCiAgRWZmZWN0U2NoZWR1bGVyIGFzIMm1RWZmZWN0U2NoZWR1bGVyLAogIElNQUdFX0NPTkZJRyBhcyDJtUlNQUdFX0NPTkZJRywKICBJTUFHRV9DT05GSUdfREVGQVVMVFMgYXMgybVJTUFHRV9DT05GSUdfREVGQVVMVFMsCiAgSU5KRUNUT1JfU0NPUEUgYXMgybVJTkpFQ1RPUl9TQ09QRSwKICDJtUlOUFVUX1NJR05BTF9CUkFORF9XUklURV9UWVBFLAogIElTX0hZRFJBVElPTl9ET01fUkVVU0VfRU5BQkxFRCBhcyDJtUlTX0hZRFJBVElPTl9ET01fUkVVU0VfRU5BQkxFRCwKICBMQ29udGV4dCBhcyDJtUxDb250ZXh0LAogIExpZmVjeWNsZUhvb2tzRmVhdHVyZSBhcyDJtUxpZmVjeWNsZUhvb2tzRmVhdHVyZSwKICBMb2NhbGVEYXRhSW5kZXggYXMgybVMb2NhbGVEYXRhSW5kZXgsCiAgTkdfQ09NUF9ERUYgYXMgybVOR19DT01QX0RFRiwKICBOR19ESVJfREVGIGFzIMm1TkdfRElSX0RFRiwKICBOR19FTEVNRU5UX0lEIGFzIMm1TkdfRUxFTUVOVF9JRCwKICBOR19JTkpfREVGIGFzIMm1TkdfSU5KX0RFRiwKICBOR19NT0RfREVGIGFzIMm1TkdfTU9EX0RFRiwKICBOR19QSVBFX0RFRiBhcyDJtU5HX1BJUEVfREVGLAogIE5HX1BST1ZfREVGIGFzIMm1TkdfUFJPVl9ERUYsCiAgTk9UX0ZPVU5EX0NIRUNLX09OTFlfRUxFTUVOVF9JTkpFQ1RPUiBhcyDJtU5PVF9GT1VORF9DSEVDS19PTkxZX0VMRU1FTlRfSU5KRUNUT1IsCiAgTk9fQ0hBTkdFIGFzIMm1Tk9fQ0hBTkdFLAogIE5nTW9kdWxlRmFjdG9yeSBhcyDJtU5nTW9kdWxlRmFjdG9yeSwKICBOb29wTmdab25lIGFzIMm1Tm9vcE5nWm9uZSwKICBQUk9WSURFRF9OR19aT05FIGFzIMm1UFJPVklERURfTkdfWk9ORSwKICBQZW5kaW5nVGFza3MgYXMgybVQZW5kaW5nVGFza3MsCiAgUmVmbGVjdGlvbkNhcGFiaWxpdGllcyBhcyDJtVJlZmxlY3Rpb25DYXBhYmlsaXRpZXMsCiAgQ29tcG9uZW50RmFjdG9yeSBhcyDJtVJlbmRlcjNDb21wb25lbnRGYWN0b3J5LAogIENvbXBvbmVudFJlZiBhcyDJtVJlbmRlcjNDb21wb25lbnRSZWYsCiAgTmdNb2R1bGVSZWYgYXMgybVSZW5kZXIzTmdNb2R1bGVSZWYsCiAgUnVudGltZUVycm9yIGFzIMm1UnVudGltZUVycm9yLAogIFNTUl9DT05URU5UX0lOVEVHUklUWV9NQVJLRVIgYXMgybVTU1JfQ09OVEVOVF9JTlRFR1JJVFlfTUFSS0VSLAogIFRFU1RBQklMSVRZIGFzIMm1VEVTVEFCSUxJVFksCiAgVEVTVEFCSUxJVFlfR0VUVEVSIGFzIMm1VEVTVEFCSUxJVFlfR0VUVEVSLAogIFVTRV9SVU5USU1FX0RFUFNfVFJBQ0tFUl9GT1JfSklUIGFzIMm1VVNFX1JVTlRJTUVfREVQU19UUkFDS0VSX0ZPUl9KSVQsCiAgVmlld1JlZiQxIGFzIMm1Vmlld1JlZiwKICBYU1NfU0VDVVJJVFlfVVJMIGFzIMm1WFNTX1NFQ1VSSVRZX1VSTCwKICBaT05FTEVTU19FTkFCTEVEIGFzIMm1Wk9ORUxFU1NfRU5BQkxFRCwKICBfc2FuaXRpemVIdG1sIGFzIMm1X3Nhbml0aXplSHRtbCwKICBfc2FuaXRpemVVcmwgYXMgybVfc2FuaXRpemVVcmwsCiAgYWxsb3dTYW5pdGl6YXRpb25CeXBhc3NBbmRUaHJvdyBhcyDJtWFsbG93U2FuaXRpemF0aW9uQnlwYXNzQW5kVGhyb3csCiAgYW5ub3RhdGVGb3JIeWRyYXRpb24gYXMgybVhbm5vdGF0ZUZvckh5ZHJhdGlvbiwKICBieXBhc3NTYW5pdGl6YXRpb25UcnVzdEh0bWwgYXMgybVieXBhc3NTYW5pdGl6YXRpb25UcnVzdEh0bWwsCiAgYnlwYXNzU2FuaXRpemF0aW9uVHJ1c3RSZXNvdXJjZVVybCBhcyDJtWJ5cGFzc1Nhbml0aXphdGlvblRydXN0UmVzb3VyY2VVcmwsCiAgYnlwYXNzU2FuaXRpemF0aW9uVHJ1c3RTY3JpcHQgYXMgybVieXBhc3NTYW5pdGl6YXRpb25UcnVzdFNjcmlwdCwKICBieXBhc3NTYW5pdGl6YXRpb25UcnVzdFN0eWxlIGFzIMm1YnlwYXNzU2FuaXRpemF0aW9uVHJ1c3RTdHlsZSwKICBieXBhc3NTYW5pdGl6YXRpb25UcnVzdFVybCBhcyDJtWJ5cGFzc1Nhbml0aXphdGlvblRydXN0VXJsLAogIGNsZWFyUmVzb2x1dGlvbk9mQ29tcG9uZW50UmVzb3VyY2VzUXVldWUgYXMgybVjbGVhclJlc29sdXRpb25PZkNvbXBvbmVudFJlc291cmNlc1F1ZXVlLAogIGNvbXBpbGVDb21wb25lbnQgYXMgybVjb21waWxlQ29tcG9uZW50LAogIGNvbXBpbGVEaXJlY3RpdmUgYXMgybVjb21waWxlRGlyZWN0aXZlLAogIGNvbXBpbGVOZ01vZHVsZSBhcyDJtWNvbXBpbGVOZ01vZHVsZSwKICBjb21waWxlTmdNb2R1bGVEZWZzIGFzIMm1Y29tcGlsZU5nTW9kdWxlRGVmcywKICBjb21waWxlTmdNb2R1bGVGYWN0b3J5IGFzIMm1Y29tcGlsZU5nTW9kdWxlRmFjdG9yeSwKICBjb21waWxlUGlwZSBhcyDJtWNvbXBpbGVQaXBlLAogIGNvbnZlcnRUb0JpdEZsYWdzIGFzIMm1Y29udmVydFRvQml0RmxhZ3MsCiAgY3JlYXRlSW5qZWN0b3IgYXMgybVjcmVhdGVJbmplY3RvciwKICBkZWZhdWx0SXRlcmFibGVEaWZmZXJzIGFzIMm1ZGVmYXVsdEl0ZXJhYmxlRGlmZmVycywKICBkZWZhdWx0S2V5VmFsdWVEaWZmZXJzIGFzIMm1ZGVmYXVsdEtleVZhbHVlRGlmZmVycywKICBkZXBzVHJhY2tlciBhcyDJtWRlcHNUcmFja2VyLAogIGRldGVjdENoYW5nZXNJblZpZXdJZlJlcXVpcmVkIGFzIMm1ZGV0ZWN0Q2hhbmdlc0luVmlld0lmUmVxdWlyZWQsCiAgZGV2TW9kZUVxdWFsIGFzIMm1ZGV2TW9kZUVxdWFsLAogIGZpbmRMb2NhbGVEYXRhIGFzIMm1ZmluZExvY2FsZURhdGEsCiAgZmx1c2hNb2R1bGVTY29waW5nUXVldWVBc011Y2hBc1Bvc3NpYmxlIGFzIMm1Zmx1c2hNb2R1bGVTY29waW5nUXVldWVBc011Y2hBc1Bvc3NpYmxlLAogIGZvcm1hdFJ1bnRpbWVFcnJvciBhcyDJtWZvcm1hdFJ1bnRpbWVFcnJvciwKICBnZW5lcmF0ZVN0YW5kYWxvbmVJbkRlY2xhcmF0aW9uc0Vycm9yIGFzIMm1Z2VuZXJhdGVTdGFuZGFsb25lSW5EZWNsYXJhdGlvbnNFcnJvciwKICBnZXRBc3luY0NsYXNzTWV0YWRhdGFGbiBhcyDJtWdldEFzeW5jQ2xhc3NNZXRhZGF0YUZuLAogIGdldERlYnVnTm9kZSBhcyDJtWdldERlYnVnTm9kZSwKICBnZXREZWZlckJsb2NrcyBhcyDJtWdldERlZmVyQmxvY2tzLAogIGdldERpcmVjdGl2ZXMgYXMgybVnZXREaXJlY3RpdmVzLAogIGdldEhvc3RFbGVtZW50IGFzIMm1Z2V0SG9zdEVsZW1lbnQsCiAgZ2V0SW5qZWN0YWJsZURlZiBhcyDJtWdldEluamVjdGFibGVEZWYsCiAgZ2V0TENvbnRleHQgYXMgybVnZXRMQ29udGV4dCwKICBnZXRMb2NhbGVDdXJyZW5jeUNvZGUgYXMgybVnZXRMb2NhbGVDdXJyZW5jeUNvZGUsCiAgZ2V0TG9jYWxlUGx1cmFsQ2FzZSBhcyDJtWdldExvY2FsZVBsdXJhbENhc2UsCiAgZ2V0T3V0cHV0RGVzdHJveVJlZiBhcyDJtWdldE91dHB1dERlc3Ryb3lSZWYsCiAgZ2V0U2FuaXRpemF0aW9uQnlwYXNzVHlwZSBhcyDJtWdldFNhbml0aXphdGlvbkJ5cGFzc1R5cGUsCiAgybVnZXRVbmtub3duRWxlbWVudFN0cmljdE1vZGUsCiAgybVnZXRVbmtub3duUHJvcGVydHlTdHJpY3RNb2RlLAogIF9nbG9iYWwgYXMgybVnbG9iYWwsCiAgaW5qZWN0Q2hhbmdlRGV0ZWN0b3JSZWYgYXMgybVpbmplY3RDaGFuZ2VEZXRlY3RvclJlZiwKICBpbnRlcm5hbEFmdGVyTmV4dFJlbmRlciBhcyDJtWludGVybmFsQWZ0ZXJOZXh0UmVuZGVyLAogIGludGVybmFsQ3JlYXRlQXBwbGljYXRpb24gYXMgybVpbnRlcm5hbENyZWF0ZUFwcGxpY2F0aW9uLAogIGludGVybmFsUHJvdmlkZVpvbmVDaGFuZ2VEZXRlY3Rpb24gYXMgybVpbnRlcm5hbFByb3ZpZGVab25lQ2hhbmdlRGV0ZWN0aW9uLAogIGlzQm91bmRUb01vZHVsZSBhcyDJtWlzQm91bmRUb01vZHVsZSwKICBpc0NvbXBvbmVudERlZlBlbmRpbmdSZXNvbHV0aW9uIGFzIMm1aXNDb21wb25lbnREZWZQZW5kaW5nUmVzb2x1dGlvbiwKICBpc0Vudmlyb25tZW50UHJvdmlkZXJzIGFzIMm1aXNFbnZpcm9ubWVudFByb3ZpZGVycywKICBpc0luamVjdGFibGUgYXMgybVpc0luamVjdGFibGUsCiAgaXNOZ01vZHVsZSBhcyDJtWlzTmdNb2R1bGUsCiAgaXNQcm9taXNlIGFzIMm1aXNQcm9taXNlLAogIGlzU3Vic2NyaWJhYmxlIGFzIMm1aXNTdWJzY3JpYmFibGUsCiAgbm9TaWRlRWZmZWN0cyBhcyDJtW5vU2lkZUVmZmVjdHMsCiAgcGF0Y2hDb21wb25lbnREZWZXaXRoU2NvcGUgYXMgybVwYXRjaENvbXBvbmVudERlZldpdGhTY29wZSwKICBwZXJmb3JtYW5jZU1hcmtGZWF0dXJlIGFzIMm1cGVyZm9ybWFuY2VNYXJrRmVhdHVyZSwKICBxdWV1ZVN0YXRlVXBkYXRlIGFzIMm1cXVldWVTdGF0ZVVwZGF0ZSwKICByZWFkSHlkcmF0aW9uSW5mbyBhcyDJtXJlYWRIeWRyYXRpb25JbmZvLAogIHJlZ2lzdGVyTG9jYWxlRGF0YSBhcyDJtXJlZ2lzdGVyTG9jYWxlRGF0YSwKICByZW5kZXJEZWZlckJsb2NrU3RhdGUgYXMgybVyZW5kZXJEZWZlckJsb2NrU3RhdGUsCiAgcmVzZXRDb21waWxlZENvbXBvbmVudHMgYXMgybVyZXNldENvbXBpbGVkQ29tcG9uZW50cywKICByZXNldEppdE9wdGlvbnMgYXMgybVyZXNldEppdE9wdGlvbnMsCiAgcmVzb2x2ZUNvbXBvbmVudFJlc291cmNlcyBhcyDJtXJlc29sdmVDb21wb25lbnRSZXNvdXJjZXMsCiAgcmVzdG9yZUNvbXBvbmVudFJlc29sdXRpb25RdWV1ZSBhcyDJtXJlc3RvcmVDb21wb25lbnRSZXNvbHV0aW9uUXVldWUsCiAgc2V0QWxsb3dEdXBsaWNhdGVOZ01vZHVsZUlkc0ZvclRlc3QgYXMgybVzZXRBbGxvd0R1cGxpY2F0ZU5nTW9kdWxlSWRzRm9yVGVzdCwKICBzZXRBbHRlcm5hdGVXZWFrUmVmSW1wbCBhcyDJtXNldEFsdGVybmF0ZVdlYWtSZWZJbXBsLAogIMm1c2V0Q2xhc3NEZWJ1Z0luZm8sCiAgc2V0Q2xhc3NNZXRhZGF0YSBhcyDJtXNldENsYXNzTWV0YWRhdGEsCiAgc2V0Q2xhc3NNZXRhZGF0YUFzeW5jIGFzIMm1c2V0Q2xhc3NNZXRhZGF0YUFzeW5jLAogIHNldEN1cnJlbnRJbmplY3RvciBhcyDJtXNldEN1cnJlbnRJbmplY3RvciwKICBzZXREb2N1bWVudCBhcyDJtXNldERvY3VtZW50LAogIHNldEluamVjdG9yUHJvZmlsZXJDb250ZXh0IGFzIMm1c2V0SW5qZWN0b3JQcm9maWxlckNvbnRleHQsCiAgc2V0TG9jYWxlSWQgYXMgybVzZXRMb2NhbGVJZCwKICDJtXNldFVua25vd25FbGVtZW50U3RyaWN0TW9kZSwKICDJtXNldFVua25vd25Qcm9wZXJ0eVN0cmljdE1vZGUsCiAgc3RvcmUgYXMgybVzdG9yZSwKICBzdHJpbmdpZnkgYXMgybVzdHJpbmdpZnksCiAgdHJhbnNpdGl2ZVNjb3Blc0ZvciBhcyDJtXRyYW5zaXRpdmVTY29wZXNGb3IsCiAgdHJpZ2dlclJlc291cmNlTG9hZGluZyBhcyDJtXRyaWdnZXJSZXNvdXJjZUxvYWRpbmcsCiAgdHJ1bmNhdGVNaWRkbGUgYXMgybV0cnVuY2F0ZU1pZGRsZSwKICB1bnJlZ2lzdGVyQWxsTG9jYWxlRGF0YSBhcyDJtXVucmVnaXN0ZXJMb2NhbGVEYXRhLAogIHVud3JhcFNhZmVWYWx1ZSBhcyDJtXVud3JhcFNhZmVWYWx1ZSwKICDJtXVud3JhcFdyaXRhYmxlU2lnbmFsLAogIHdoZW5TdGFibGUgYXMgybV3aGVuU3RhYmxlLAogIHdpdGhEb21IeWRyYXRpb24gYXMgybV3aXRoRG9tSHlkcmF0aW9uLAogIHdpdGhFdmVudFJlcGxheSBhcyDJtXdpdGhFdmVudFJlcGxheSwKICB3aXRoSTE4blN1cHBvcnQgYXMgybV3aXRoSTE4blN1cHBvcnQsCiAgybXJtUNvcHlEZWZpbml0aW9uRmVhdHVyZSwKICBGYWN0b3J5VGFyZ2V0IGFzIMm1ybVGYWN0b3J5VGFyZ2V0LAogIMm1ybVIb3N0RGlyZWN0aXZlc0ZlYXR1cmUsCiAgybXJtUluaGVyaXREZWZpbml0aW9uRmVhdHVyZSwKICDJtcm1SW5wdXRUcmFuc2Zvcm1zRmVhdHVyZSwKICDJtcm1TmdPbkNoYW5nZXNGZWF0dXJlLAogIMm1ybVQcm92aWRlcnNGZWF0dXJlLAogIMm1ybVTdGFuZGFsb25lRmVhdHVyZSwKICDJtcm1YWR2YW5jZSwKICDJtcm1YXR0cmlidXRlLAogIMm1ybVhdHRyaWJ1dGVJbnRlcnBvbGF0ZTEsCiAgybXJtWF0dHJpYnV0ZUludGVycG9sYXRlMiwKICDJtcm1YXR0cmlidXRlSW50ZXJwb2xhdGUzLAogIMm1ybVhdHRyaWJ1dGVJbnRlcnBvbGF0ZTQsCiAgybXJtWF0dHJpYnV0ZUludGVycG9sYXRlNSwKICDJtcm1YXR0cmlidXRlSW50ZXJwb2xhdGU2LAogIMm1ybVhdHRyaWJ1dGVJbnRlcnBvbGF0ZTcsCiAgybXJtWF0dHJpYnV0ZUludGVycG9sYXRlOCwKICDJtcm1YXR0cmlidXRlSW50ZXJwb2xhdGVWLAogIMm1ybVjbGFzc01hcCwKICDJtcm1Y2xhc3NNYXBJbnRlcnBvbGF0ZTEsCiAgybXJtWNsYXNzTWFwSW50ZXJwb2xhdGUyLAogIMm1ybVjbGFzc01hcEludGVycG9sYXRlMywKICDJtcm1Y2xhc3NNYXBJbnRlcnBvbGF0ZTQsCiAgybXJtWNsYXNzTWFwSW50ZXJwb2xhdGU1LAogIMm1ybVjbGFzc01hcEludGVycG9sYXRlNiwKICDJtcm1Y2xhc3NNYXBJbnRlcnBvbGF0ZTcsCiAgybXJtWNsYXNzTWFwSW50ZXJwb2xhdGU4LAogIMm1ybVjbGFzc01hcEludGVycG9sYXRlViwKICDJtcm1Y2xhc3NQcm9wLAogIMm1ybVjb21wb25lbnRJbnN0YW5jZSwKICDJtcm1Y29uZGl0aW9uYWwsCiAgybXJtWNvbnRlbnRRdWVyeSwKICDJtcm1Y29udGVudFF1ZXJ5U2lnbmFsLAogIMm1ybVkZWNsYXJlTGV0LAogIMm1ybVkZWZlciwKICDJtcm1ZGVmZXJFbmFibGVUaW1lclNjaGVkdWxpbmcsCiAgybXJtWRlZmVyT25Ib3ZlciwKICDJtcm1ZGVmZXJPbklkbGUsCiAgybXJtWRlZmVyT25JbW1lZGlhdGUsCiAgybXJtWRlZmVyT25JbnRlcmFjdGlvbiwKICDJtcm1ZGVmZXJPblRpbWVyLAogIMm1ybVkZWZlck9uVmlld3BvcnQsCiAgybXJtWRlZmVyUHJlZmV0Y2hPbkhvdmVyLAogIMm1ybVkZWZlclByZWZldGNoT25JZGxlLAogIMm1ybVkZWZlclByZWZldGNoT25JbW1lZGlhdGUsCiAgybXJtWRlZmVyUHJlZmV0Y2hPbkludGVyYWN0aW9uLAogIMm1ybVkZWZlclByZWZldGNoT25UaW1lciwKICDJtcm1ZGVmZXJQcmVmZXRjaE9uVmlld3BvcnQsCiAgybXJtWRlZmVyUHJlZmV0Y2hXaGVuLAogIMm1ybVkZWZlcldoZW4sCiAgybXJtWRlZmluZUNvbXBvbmVudCwKICDJtcm1ZGVmaW5lRGlyZWN0aXZlLAogIMm1ybVkZWZpbmVJbmplY3RhYmxlLAogIMm1ybVkZWZpbmVJbmplY3RvciwKICDJtcm1ZGVmaW5lTmdNb2R1bGUsCiAgybXJtWRlZmluZVBpcGUsCiAgybXJtWRpcmVjdGl2ZUluamVjdCwKICDJtcm1ZGlzYWJsZUJpbmRpbmdzLAogIMm1ybVlbGVtZW50LAogIMm1ybVlbGVtZW50Q29udGFpbmVyLAogIMm1ybVlbGVtZW50Q29udGFpbmVyRW5kLAogIMm1ybVlbGVtZW50Q29udGFpbmVyU3RhcnQsCiAgybXJtWVsZW1lbnRFbmQsCiAgybXJtWVsZW1lbnRTdGFydCwKICDJtcm1ZW5hYmxlQmluZGluZ3MsCiAgybXJtWdldENvbXBvbmVudERlcHNGYWN0b3J5LAogIMm1ybVnZXRDdXJyZW50VmlldywKICDJtcm1Z2V0SW5oZXJpdGVkRmFjdG9yeSwKICDJtcm1aG9zdFByb3BlcnR5LAogIMm1ybVpMThuLAogIMm1ybVpMThuQXBwbHksCiAgybXJtWkxOG5BdHRyaWJ1dGVzLAogIMm1ybVpMThuRW5kLAogIMm1ybVpMThuRXhwLAogIMm1ybVpMThuUG9zdHByb2Nlc3MsCiAgybXJtWkxOG5TdGFydCwKICDJtcm1aW5qZWN0LAogIMm1ybVpbmplY3RBdHRyaWJ1dGUsCiAgybXJtWludmFsaWRGYWN0b3J5LAogIMm1ybVpbnZhbGlkRmFjdG9yeURlcCwKICDJtcm1bGlzdGVuZXIsCiAgybXJtWxvYWRRdWVyeSwKICDJtcm1bmFtZXNwYWNlSFRNTCwKICDJtcm1bmFtZXNwYWNlTWF0aE1MLAogIMm1ybVuYW1lc3BhY2VTVkcsCiAgybXJtW5leHRDb250ZXh0LAogIMm1ybVuZ0RlY2xhcmVDbGFzc01ldGFkYXRhLAogIMm1ybVuZ0RlY2xhcmVDbGFzc01ldGFkYXRhQXN5bmMsCiAgybXJtW5nRGVjbGFyZUNvbXBvbmVudCwKICDJtcm1bmdEZWNsYXJlRGlyZWN0aXZlLAogIMm1ybVuZ0RlY2xhcmVGYWN0b3J5LAogIMm1ybVuZ0RlY2xhcmVJbmplY3RhYmxlLAogIMm1ybVuZ0RlY2xhcmVJbmplY3RvciwKICDJtcm1bmdEZWNsYXJlTmdNb2R1bGUsCiAgybXJtW5nRGVjbGFyZVBpcGUsCiAgybXJtXBpcGUsCiAgybXJtXBpcGVCaW5kMSwKICDJtcm1cGlwZUJpbmQyLAogIMm1ybVwaXBlQmluZDMsCiAgybXJtXBpcGVCaW5kNCwKICDJtcm1cGlwZUJpbmRWLAogIMm1ybVwcm9qZWN0aW9uLAogIMm1ybVwcm9qZWN0aW9uRGVmLAogIMm1ybVwcm9wZXJ0eSwKICDJtcm1cHJvcGVydHlJbnRlcnBvbGF0ZSwKICDJtcm1cHJvcGVydHlJbnRlcnBvbGF0ZTEsCiAgybXJtXByb3BlcnR5SW50ZXJwb2xhdGUyLAogIMm1ybVwcm9wZXJ0eUludGVycG9sYXRlMywKICDJtcm1cHJvcGVydHlJbnRlcnBvbGF0ZTQsCiAgybXJtXByb3BlcnR5SW50ZXJwb2xhdGU1LAogIMm1ybVwcm9wZXJ0eUludGVycG9sYXRlNiwKICDJtcm1cHJvcGVydHlJbnRlcnBvbGF0ZTcsCiAgybXJtXByb3BlcnR5SW50ZXJwb2xhdGU4LAogIMm1ybVwcm9wZXJ0eUludGVycG9sYXRlViwKICDJtcm1cHVyZUZ1bmN0aW9uMCwKICDJtcm1cHVyZUZ1bmN0aW9uMSwKICDJtcm1cHVyZUZ1bmN0aW9uMiwKICDJtcm1cHVyZUZ1bmN0aW9uMywKICDJtcm1cHVyZUZ1bmN0aW9uNCwKICDJtcm1cHVyZUZ1bmN0aW9uNSwKICDJtcm1cHVyZUZ1bmN0aW9uNiwKICDJtcm1cHVyZUZ1bmN0aW9uNywKICDJtcm1cHVyZUZ1bmN0aW9uOCwKICDJtcm1cHVyZUZ1bmN0aW9uViwKICDJtcm1cXVlcnlBZHZhbmNlLAogIMm1ybVxdWVyeVJlZnJlc2gsCiAgybXJtXJlYWRDb250ZXh0TGV0LAogIMm1ybVyZWZlcmVuY2UsCiAgcmVnaXN0ZXJOZ01vZHVsZVR5cGUgYXMgybXJtXJlZ2lzdGVyTmdNb2R1bGVUeXBlLAogIMm1ybVyZXBlYXRlciwKICDJtcm1cmVwZWF0ZXJDcmVhdGUsCiAgybXJtXJlcGVhdGVyVHJhY2tCeUlkZW50aXR5LAogIMm1ybVyZXBlYXRlclRyYWNrQnlJbmRleCwKICDJtcm1cmVzZXRWaWV3LAogIMm1ybVyZXNvbHZlQm9keSwKICDJtcm1cmVzb2x2ZURvY3VtZW50LAogIMm1ybVyZXNvbHZlV2luZG93LAogIMm1ybVyZXN0b3JlVmlldywKICDJtcm1c2FuaXRpemVIdG1sLAogIMm1ybVzYW5pdGl6ZVJlc291cmNlVXJsLAogIMm1ybVzYW5pdGl6ZVNjcmlwdCwKICDJtcm1c2FuaXRpemVTdHlsZSwKICDJtcm1c2FuaXRpemVVcmwsCiAgybXJtXNhbml0aXplVXJsT3JSZXNvdXJjZVVybCwKICDJtcm1c2V0Q29tcG9uZW50U2NvcGUsCiAgybXJtXNldE5nTW9kdWxlU2NvcGUsCiAgybXJtXN0b3JlTGV0LAogIMm1ybVzdHlsZU1hcCwKICDJtcm1c3R5bGVNYXBJbnRlcnBvbGF0ZTEsCiAgybXJtXN0eWxlTWFwSW50ZXJwb2xhdGUyLAogIMm1ybVzdHlsZU1hcEludGVycG9sYXRlMywKICDJtcm1c3R5bGVNYXBJbnRlcnBvbGF0ZTQsCiAgybXJtXN0eWxlTWFwSW50ZXJwb2xhdGU1LAogIMm1ybVzdHlsZU1hcEludGVycG9sYXRlNiwKICDJtcm1c3R5bGVNYXBJbnRlcnBvbGF0ZTcsCiAgybXJtXN0eWxlTWFwSW50ZXJwb2xhdGU4LAogIMm1ybVzdHlsZU1hcEludGVycG9sYXRlViwKICDJtcm1c3R5bGVQcm9wLAogIMm1ybVzdHlsZVByb3BJbnRlcnBvbGF0ZTEsCiAgybXJtXN0eWxlUHJvcEludGVycG9sYXRlMiwKICDJtcm1c3R5bGVQcm9wSW50ZXJwb2xhdGUzLAogIMm1ybVzdHlsZVByb3BJbnRlcnBvbGF0ZTQsCiAgybXJtXN0eWxlUHJvcEludGVycG9sYXRlNSwKICDJtcm1c3R5bGVQcm9wSW50ZXJwb2xhdGU2LAogIMm1ybVzdHlsZVByb3BJbnRlcnBvbGF0ZTcsCiAgybXJtXN0eWxlUHJvcEludGVycG9sYXRlOCwKICDJtcm1c3R5bGVQcm9wSW50ZXJwb2xhdGVWLAogIMm1ybVzeW50aGV0aWNIb3N0TGlzdGVuZXIsCiAgybXJtXN5bnRoZXRpY0hvc3RQcm9wZXJ0eSwKICDJtcm1dGVtcGxhdGUsCiAgybXJtXRlbXBsYXRlUmVmRXh0cmFjdG9yLAogIMm1ybV0ZXh0LAogIMm1ybV0ZXh0SW50ZXJwb2xhdGUsCiAgybXJtXRleHRJbnRlcnBvbGF0ZTEsCiAgybXJtXRleHRJbnRlcnBvbGF0ZTIsCiAgybXJtXRleHRJbnRlcnBvbGF0ZTMsCiAgybXJtXRleHRJbnRlcnBvbGF0ZTQsCiAgybXJtXRleHRJbnRlcnBvbGF0ZTUsCiAgybXJtXRleHRJbnRlcnBvbGF0ZTYsCiAgybXJtXRleHRJbnRlcnBvbGF0ZTcsCiAgybXJtXRleHRJbnRlcnBvbGF0ZTgsCiAgybXJtXRleHRJbnRlcnBvbGF0ZVYsCiAgybXJtXRydXN0Q29uc3RhbnRIdG1sLAogIMm1ybV0cnVzdENvbnN0YW50UmVzb3VyY2VVcmwsCiAgybXJtXR3b1dheUJpbmRpbmdTZXQsCiAgybXJtXR3b1dheUxpc3RlbmVyLAogIMm1ybV0d29XYXlQcm9wZXJ0eSwKICDJtcm1dmFsaWRhdGVJZnJhbWVBdHRyaWJ1dGUsCiAgybXJtXZpZXdRdWVyeSwKICDJtcm1dmlld1F1ZXJ5U2lnbmFsCn07Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPUBhbmd1bGFyX2NvcmUuanMubWFwClBLAwQKAAAAAACacexYJ1XoeF0AAABdAAAANAAAAC5hbmd1bGFyL2NhY2hlLzE4LjAuNi92aXRlL2RlcHMvQGFuZ3VsYXJfY29yZS5qcy5tYXB7CiAgInZlcnNpb24iOiAzLAogICJzb3VyY2VzIjogW10sCiAgInNvdXJjZXNDb250ZW50IjogW10sCiAgIm1hcHBpbmdzIjogIiIsCiAgIm5hbWVzIjogW10KfQpQSwMECgAAAAAAmnHsWDtmItomqwQAJqsEADwAAAAuYW5ndWxhci9jYWNoZS8xOC4wLjYvdml0ZS9kZXBzL0Bhbmd1bGFyX3BsYXRmb3JtLWJyb3dzZXIuanNpbXBvcnQgewogIEFQUF9CT09UU1RSQVBfTElTVEVORVIsCiAgQVBQX0lELAogIEFwcGxpY2F0aW9uTW9kdWxlLAogIEFwcGxpY2F0aW9uUmVmLAogIEF0dHJpYnV0ZSwKICBDU1BfTk9OQ0UsCiAgQ2hhbmdlRGV0ZWN0b3JSZWYsCiAgQ29uc29sZSwKICBERUZBVUxUX0NVUlJFTkNZX0NPREUsCiAgRGlyZWN0aXZlLAogIEVOVklST05NRU5UX0lOSVRJQUxJWkVSLAogIEVsZW1lbnRSZWYsCiAgRW52aXJvbm1lbnRJbmplY3RvciwKICBFcnJvckhhbmRsZXIsCiAgRXZlbnRFbWl0dGVyLAogIEhvc3QsCiAgSU1BR0VfQ09ORklHLAogIElNQUdFX0NPTkZJR19ERUZBVUxUUywKICBJTkpFQ1RPUl9TQ09QRSwKICBJbmplY3QsCiAgSW5qZWN0YWJsZSwKICBJbmplY3Rpb25Ub2tlbiwKICBJbmplY3RvciwKICBJbnB1dCwKICBJdGVyYWJsZURpZmZlcnMsCiAgS2V5VmFsdWVEaWZmZXJzLAogIExPQ0FMRV9JRCwKICBMb2NhbGVEYXRhSW5kZXgsCiAgTmdNb2R1bGUsCiAgTmdNb2R1bGVSZWYkMSwKICBOZ1pvbmUsCiAgT2JzZXJ2YWJsZSwKICBPcHRpb25hbCwKICBQTEFURk9STV9JRCwKICBQTEFURk9STV9JTklUSUFMSVpFUiwKICBQZW5kaW5nVGFza3MsCiAgUGlwZSwKICBSZW5kZXJlcjIsCiAgUmVuZGVyZXJGYWN0b3J5MiwKICBSZW5kZXJlclN0eWxlRmxhZ3MyLAogIFJ1bnRpbWVFcnJvciwKICBTZWN1cml0eUNvbnRleHQsCiAgU2tpcFNlbGYsCiAgVEVTVEFCSUxJVFksCiAgVEVTVEFCSUxJVFlfR0VUVEVSLAogIFRlbXBsYXRlUmVmLAogIFRlc3RhYmlsaXR5LAogIFRlc3RhYmlsaXR5UmVnaXN0cnksCiAgVHJhbnNmZXJTdGF0ZSwKICBWZXJzaW9uLAogIFZpZXdDb250YWluZXJSZWYsCiAgVmlld0VuY2Fwc3VsYXRpb24kMSwKICBYU1NfU0VDVVJJVFlfVVJMLAogIF9nbG9iYWwsCiAgX3Nhbml0aXplSHRtbCwKICBfc2FuaXRpemVVcmwsCiAgYWxsb3dTYW5pdGl6YXRpb25CeXBhc3NBbmRUaHJvdywKICBib29sZWFuQXR0cmlidXRlLAogIGJ5cGFzc1Nhbml0aXphdGlvblRydXN0SHRtbCwKICBieXBhc3NTYW5pdGl6YXRpb25UcnVzdFJlc291cmNlVXJsLAogIGJ5cGFzc1Nhbml0aXphdGlvblRydXN0U2NyaXB0LAogIGJ5cGFzc1Nhbml0aXphdGlvblRydXN0U3R5bGUsCiAgYnlwYXNzU2FuaXRpemF0aW9uVHJ1c3RVcmwsCiAgY29uY2F0TWFwLAogIGNyZWF0ZU5nTW9kdWxlLAogIGNyZWF0ZVBsYXRmb3JtRmFjdG9yeSwKICBmaWx0ZXIsCiAgZmluYWxpemUsCiAgZmluZExvY2FsZURhdGEsCiAgZm9ybWF0UnVudGltZUVycm9yLAogIGZvcndhcmRSZWYsCiAgZnJvbSwKICBnZXRMb2NhbGVQbHVyYWxDYXNlLAogIGluamVjdCwKICBpbnRlcm5hbENyZWF0ZUFwcGxpY2F0aW9uLAogIGlzUHJvbWlzZSwKICBpc1N1YnNjcmliYWJsZSwKICBtYWtlRW52aXJvbm1lbnRQcm92aWRlcnMsCiAgbWFrZVN0YXRlS2V5LAogIG1hcCwKICBudW1iZXJBdHRyaWJ1dGUsCiAgb2YsCiAgcGVyZm9ybWFuY2VNYXJrRmVhdHVyZSwKICBwbGF0Zm9ybUNvcmUsCiAgcnVuSW5JbmplY3Rpb25Db250ZXh0LAogIHNldENsYXNzTWV0YWRhdGEsCiAgc2V0RG9jdW1lbnQsCiAgc3RyaW5naWZ5LAogIHN3aXRjaE1hcCwKICB0YXAsCiAgdHJ1bmNhdGVNaWRkbGUsCiAgdW50cmFja2VkLAogIHVud3JhcFNhZmVWYWx1ZSwKICB3aGVuU3RhYmxlLAogIHdpdGhEb21IeWRyYXRpb24sCiAgd2l0aEV2ZW50UmVwbGF5LAogIHdpdGhJMThuU3VwcG9ydCwKICDJtcm1SW5wdXRUcmFuc2Zvcm1zRmVhdHVyZSwKICDJtcm1TmdPbkNoYW5nZXNGZWF0dXJlLAogIMm1ybVkZWZpbmVEaXJlY3RpdmUsCiAgybXJtWRlZmluZUluamVjdGFibGUsCiAgybXJtWRlZmluZUluamVjdG9yLAogIMm1ybVkZWZpbmVOZ01vZHVsZSwKICDJtcm1ZGVmaW5lUGlwZSwKICDJtcm1ZGlyZWN0aXZlSW5qZWN0LAogIMm1ybVpbmplY3QsCiAgybXJtWluamVjdEF0dHJpYnV0ZSwKICDJtcm1c3R5bGVQcm9wCn0gZnJvbSAiLi9jaHVuay1CTk5TQ1pKVy5qcyI7CmltcG9ydCB7CiAgX19vYmpSZXN0LAogIF9fc3ByZWFkUHJvcHMsCiAgX19zcHJlYWRWYWx1ZXMKfSBmcm9tICIuL2NodW5rLVRTWk9TV0VTLmpzIjsKCi8vIG5vZGVfbW9kdWxlcy9AYW5ndWxhci9jb21tb24vZmVzbTIwMjIvY29tbW9uLm1qcwp2YXIgX0RPTSA9IG51bGw7CmZ1bmN0aW9uIGdldERPTSgpIHsKICByZXR1cm4gX0RPTTsKfQpmdW5jdGlvbiBzZXRSb290RG9tQWRhcHRlcihhZGFwdGVyKSB7CiAgX0RPTSA/Pz0gYWRhcHRlcjsKfQp2YXIgRG9tQWRhcHRlciA9IGNsYXNzIHsKfTsKdmFyIF9QbGF0Zm9ybU5hdmlnYXRpb24gPSBjbGFzcyBfUGxhdGZvcm1OYXZpZ2F0aW9uIHsKfTsKX1BsYXRmb3JtTmF2aWdhdGlvbi7JtWZhYyA9IGZ1bmN0aW9uIFBsYXRmb3JtTmF2aWdhdGlvbl9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9QbGF0Zm9ybU5hdmlnYXRpb24pKCk7Cn07Cl9QbGF0Zm9ybU5hdmlnYXRpb24uybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfUGxhdGZvcm1OYXZpZ2F0aW9uLAogIGZhY3Rvcnk6ICgpID0+ICgoKSA9PiB3aW5kb3cubmF2aWdhdGlvbikoKSwKICBwcm92aWRlZEluOiAicGxhdGZvcm0iCn0pOwp2YXIgUGxhdGZvcm1OYXZpZ2F0aW9uID0gX1BsYXRmb3JtTmF2aWdhdGlvbjsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKFBsYXRmb3JtTmF2aWdhdGlvbiwgW3sKICAgIHR5cGU6IEluamVjdGFibGUsCiAgICBhcmdzOiBbewogICAgICBwcm92aWRlZEluOiAicGxhdGZvcm0iLAogICAgICB1c2VGYWN0b3J5OiAoKSA9PiB3aW5kb3cubmF2aWdhdGlvbgogICAgfV0KICB9XSwgbnVsbCwgbnVsbCk7Cn0pKCk7CnZhciBET0NVTUVOVCA9IG5ldyBJbmplY3Rpb25Ub2tlbihuZ0Rldk1vZGUgPyAiRG9jdW1lbnRUb2tlbiIgOiAiIik7CnZhciBfUGxhdGZvcm1Mb2NhdGlvbiA9IGNsYXNzIF9QbGF0Zm9ybUxvY2F0aW9uIHsKICBoaXN0b3J5R28ocmVsYXRpdmVQb3NpdGlvbikgewogICAgdGhyb3cgbmV3IEVycm9yKG5nRGV2TW9kZSA/ICJOb3QgaW1wbGVtZW50ZWQiIDogIiIpOwogIH0KfTsKX1BsYXRmb3JtTG9jYXRpb24uybVmYWMgPSBmdW5jdGlvbiBQbGF0Zm9ybUxvY2F0aW9uX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX1BsYXRmb3JtTG9jYXRpb24pKCk7Cn07Cl9QbGF0Zm9ybUxvY2F0aW9uLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX1BsYXRmb3JtTG9jYXRpb24sCiAgZmFjdG9yeTogKCkgPT4gKCgpID0+IGluamVjdChCcm93c2VyUGxhdGZvcm1Mb2NhdGlvbikpKCksCiAgcHJvdmlkZWRJbjogInBsYXRmb3JtIgp9KTsKdmFyIFBsYXRmb3JtTG9jYXRpb24gPSBfUGxhdGZvcm1Mb2NhdGlvbjsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKFBsYXRmb3JtTG9jYXRpb24sIFt7CiAgICB0eXBlOiBJbmplY3RhYmxlLAogICAgYXJnczogW3sKICAgICAgcHJvdmlkZWRJbjogInBsYXRmb3JtIiwKICAgICAgdXNlRmFjdG9yeTogKCkgPT4gaW5qZWN0KEJyb3dzZXJQbGF0Zm9ybUxvY2F0aW9uKQogICAgfV0KICB9XSwgbnVsbCwgbnVsbCk7Cn0pKCk7CnZhciBMT0NBVElPTl9JTklUSUFMSVpFRCA9IG5ldyBJbmplY3Rpb25Ub2tlbihuZ0Rldk1vZGUgPyAiTG9jYXRpb24gSW5pdGlhbGl6ZWQiIDogIiIpOwp2YXIgX0Jyb3dzZXJQbGF0Zm9ybUxvY2F0aW9uID0gY2xhc3MgX0Jyb3dzZXJQbGF0Zm9ybUxvY2F0aW9uIGV4dGVuZHMgUGxhdGZvcm1Mb2NhdGlvbiB7CiAgY29uc3RydWN0b3IoKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5fZG9jID0gaW5qZWN0KERPQ1VNRU5UKTsKICAgIHRoaXMuX2xvY2F0aW9uID0gd2luZG93LmxvY2F0aW9uOwogICAgdGhpcy5faGlzdG9yeSA9IHdpbmRvdy5oaXN0b3J5OwogIH0KICBnZXRCYXNlSHJlZkZyb21ET00oKSB7CiAgICByZXR1cm4gZ2V0RE9NKCkuZ2V0QmFzZUhyZWYodGhpcy5fZG9jKTsKICB9CiAgb25Qb3BTdGF0ZShmbikgewogICAgY29uc3Qgd2luZG93MiA9IGdldERPTSgpLmdldEdsb2JhbEV2ZW50VGFyZ2V0KHRoaXMuX2RvYywgIndpbmRvdyIpOwogICAgd2luZG93Mi5hZGRFdmVudExpc3RlbmVyKCJwb3BzdGF0ZSIsIGZuLCBmYWxzZSk7CiAgICByZXR1cm4gKCkgPT4gd2luZG93Mi5yZW1vdmVFdmVudExpc3RlbmVyKCJwb3BzdGF0ZSIsIGZuKTsKICB9CiAgb25IYXNoQ2hhbmdlKGZuKSB7CiAgICBjb25zdCB3aW5kb3cyID0gZ2V0RE9NKCkuZ2V0R2xvYmFsRXZlbnRUYXJnZXQodGhpcy5fZG9jLCAid2luZG93Iik7CiAgICB3aW5kb3cyLmFkZEV2ZW50TGlzdGVuZXIoImhhc2hjaGFuZ2UiLCBmbiwgZmFsc2UpOwogICAgcmV0dXJuICgpID0+IHdpbmRvdzIucmVtb3ZlRXZlbnRMaXN0ZW5lcigiaGFzaGNoYW5nZSIsIGZuKTsKICB9CiAgZ2V0IGhyZWYoKSB7CiAgICByZXR1cm4gdGhpcy5fbG9jYXRpb24uaHJlZjsKICB9CiAgZ2V0IHByb3RvY29sKCkgewogICAgcmV0dXJuIHRoaXMuX2xvY2F0aW9uLnByb3RvY29sOwogIH0KICBnZXQgaG9zdG5hbWUoKSB7CiAgICByZXR1cm4gdGhpcy5fbG9jYXRpb24uaG9zdG5hbWU7CiAgfQogIGdldCBwb3J0KCkgewogICAgcmV0dXJuIHRoaXMuX2xvY2F0aW9uLnBvcnQ7CiAgfQogIGdldCBwYXRobmFtZSgpIHsKICAgIHJldHVybiB0aGlzLl9sb2NhdGlvbi5wYXRobmFtZTsKICB9CiAgZ2V0IHNlYXJjaCgpIHsKICAgIHJldHVybiB0aGlzLl9sb2NhdGlvbi5zZWFyY2g7CiAgfQogIGdldCBoYXNoKCkgewogICAgcmV0dXJuIHRoaXMuX2xvY2F0aW9uLmhhc2g7CiAgfQogIHNldCBwYXRobmFtZShuZXdQYXRoKSB7CiAgICB0aGlzLl9sb2NhdGlvbi5wYXRobmFtZSA9IG5ld1BhdGg7CiAgfQogIHB1c2hTdGF0ZShzdGF0ZSwgdGl0bGUsIHVybCkgewogICAgdGhpcy5faGlzdG9yeS5wdXNoU3RhdGUoc3RhdGUsIHRpdGxlLCB1cmwpOwogIH0KICByZXBsYWNlU3RhdGUoc3RhdGUsIHRpdGxlLCB1cmwpIHsKICAgIHRoaXMuX2hpc3RvcnkucmVwbGFjZVN0YXRlKHN0YXRlLCB0aXRsZSwgdXJsKTsKICB9CiAgZm9yd2FyZCgpIHsKICAgIHRoaXMuX2hpc3RvcnkuZm9yd2FyZCgpOwogIH0KICBiYWNrKCkgewogICAgdGhpcy5faGlzdG9yeS5iYWNrKCk7CiAgfQogIGhpc3RvcnlHbyhyZWxhdGl2ZVBvc2l0aW9uID0gMCkgewogICAgdGhpcy5faGlzdG9yeS5nbyhyZWxhdGl2ZVBvc2l0aW9uKTsKICB9CiAgZ2V0U3RhdGUoKSB7CiAgICByZXR1cm4gdGhpcy5faGlzdG9yeS5zdGF0ZTsKICB9Cn07Cl9Ccm93c2VyUGxhdGZvcm1Mb2NhdGlvbi7JtWZhYyA9IGZ1bmN0aW9uIEJyb3dzZXJQbGF0Zm9ybUxvY2F0aW9uX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0Jyb3dzZXJQbGF0Zm9ybUxvY2F0aW9uKSgpOwp9OwpfQnJvd3NlclBsYXRmb3JtTG9jYXRpb24uybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfQnJvd3NlclBsYXRmb3JtTG9jYXRpb24sCiAgZmFjdG9yeTogKCkgPT4gKCgpID0+IG5ldyBfQnJvd3NlclBsYXRmb3JtTG9jYXRpb24oKSkoKSwKICBwcm92aWRlZEluOiAicGxhdGZvcm0iCn0pOwp2YXIgQnJvd3NlclBsYXRmb3JtTG9jYXRpb24gPSBfQnJvd3NlclBsYXRmb3JtTG9jYXRpb247CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShCcm93c2VyUGxhdGZvcm1Mb2NhdGlvbiwgW3sKICAgIHR5cGU6IEluamVjdGFibGUsCiAgICBhcmdzOiBbewogICAgICBwcm92aWRlZEluOiAicGxhdGZvcm0iLAogICAgICB1c2VGYWN0b3J5OiAoKSA9PiBuZXcgQnJvd3NlclBsYXRmb3JtTG9jYXRpb24oKQogICAgfV0KICB9XSwgKCkgPT4gW10sIG51bGwpOwp9KSgpOwpmdW5jdGlvbiBqb2luV2l0aFNsYXNoKHN0YXJ0LCBlbmQpIHsKICBpZiAoc3RhcnQubGVuZ3RoID09IDApIHsKICAgIHJldHVybiBlbmQ7CiAgfQogIGlmIChlbmQubGVuZ3RoID09IDApIHsKICAgIHJldHVybiBzdGFydDsKICB9CiAgbGV0IHNsYXNoZXMgPSAwOwogIGlmIChzdGFydC5lbmRzV2l0aCgiLyIpKSB7CiAgICBzbGFzaGVzKys7CiAgfQogIGlmIChlbmQuc3RhcnRzV2l0aCgiLyIpKSB7CiAgICBzbGFzaGVzKys7CiAgfQogIGlmIChzbGFzaGVzID09IDIpIHsKICAgIHJldHVybiBzdGFydCArIGVuZC5zdWJzdHJpbmcoMSk7CiAgfQogIGlmIChzbGFzaGVzID09IDEpIHsKICAgIHJldHVybiBzdGFydCArIGVuZDsKICB9CiAgcmV0dXJuIHN0YXJ0ICsgIi8iICsgZW5kOwp9CmZ1bmN0aW9uIHN0cmlwVHJhaWxpbmdTbGFzaCh1cmwpIHsKICBjb25zdCBtYXRjaCA9IHVybC5tYXRjaCgvI3xcP3wkLyk7CiAgY29uc3QgcGF0aEVuZElkeCA9IG1hdGNoICYmIG1hdGNoLmluZGV4IHx8IHVybC5sZW5ndGg7CiAgY29uc3QgZHJvcHBlZFNsYXNoSWR4ID0gcGF0aEVuZElkeCAtICh1cmxbcGF0aEVuZElkeCAtIDFdID09PSAiLyIgPyAxIDogMCk7CiAgcmV0dXJuIHVybC5zbGljZSgwLCBkcm9wcGVkU2xhc2hJZHgpICsgdXJsLnNsaWNlKHBhdGhFbmRJZHgpOwp9CmZ1bmN0aW9uIG5vcm1hbGl6ZVF1ZXJ5UGFyYW1zKHBhcmFtcykgewogIHJldHVybiBwYXJhbXMgJiYgcGFyYW1zWzBdICE9PSAiPyIgPyAiPyIgKyBwYXJhbXMgOiBwYXJhbXM7Cn0KdmFyIF9Mb2NhdGlvblN0cmF0ZWd5ID0gY2xhc3MgX0xvY2F0aW9uU3RyYXRlZ3kgewogIGhpc3RvcnlHbyhyZWxhdGl2ZVBvc2l0aW9uKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IobmdEZXZNb2RlID8gIk5vdCBpbXBsZW1lbnRlZCIgOiAiIik7CiAgfQp9OwpfTG9jYXRpb25TdHJhdGVneS7JtWZhYyA9IGZ1bmN0aW9uIExvY2F0aW9uU3RyYXRlZ3lfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTG9jYXRpb25TdHJhdGVneSkoKTsKfTsKX0xvY2F0aW9uU3RyYXRlZ3kuybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfTG9jYXRpb25TdHJhdGVneSwKICBmYWN0b3J5OiAoKSA9PiAoKCkgPT4gaW5qZWN0KFBhdGhMb2NhdGlvblN0cmF0ZWd5KSkoKSwKICBwcm92aWRlZEluOiAicm9vdCIKfSk7CnZhciBMb2NhdGlvblN0cmF0ZWd5ID0gX0xvY2F0aW9uU3RyYXRlZ3k7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShMb2NhdGlvblN0cmF0ZWd5LCBbewogICAgdHlwZTogSW5qZWN0YWJsZSwKICAgIGFyZ3M6IFt7CiAgICAgIHByb3ZpZGVkSW46ICJyb290IiwKICAgICAgdXNlRmFjdG9yeTogKCkgPT4gaW5qZWN0KFBhdGhMb2NhdGlvblN0cmF0ZWd5KQogICAgfV0KICB9XSwgbnVsbCwgbnVsbCk7Cn0pKCk7CnZhciBBUFBfQkFTRV9IUkVGID0gbmV3IEluamVjdGlvblRva2VuKG5nRGV2TW9kZSA/ICJhcHBCYXNlSHJlZiIgOiAiIik7CnZhciBfUGF0aExvY2F0aW9uU3RyYXRlZ3kgPSBjbGFzcyBfUGF0aExvY2F0aW9uU3RyYXRlZ3kgZXh0ZW5kcyBMb2NhdGlvblN0cmF0ZWd5IHsKICBjb25zdHJ1Y3RvcihfcGxhdGZvcm1Mb2NhdGlvbiwgaHJlZikgewogICAgc3VwZXIoKTsKICAgIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24gPSBfcGxhdGZvcm1Mb2NhdGlvbjsKICAgIHRoaXMuX3JlbW92ZUxpc3RlbmVyRm5zID0gW107CiAgICB0aGlzLl9iYXNlSHJlZiA9IGhyZWYgPz8gdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5nZXRCYXNlSHJlZkZyb21ET00oKSA/PyBpbmplY3QoRE9DVU1FTlQpLmxvY2F0aW9uPy5vcmlnaW4gPz8gIiI7CiAgfQogIC8qKiBAbm9kb2MgKi8KICBuZ09uRGVzdHJveSgpIHsKICAgIHdoaWxlICh0aGlzLl9yZW1vdmVMaXN0ZW5lckZucy5sZW5ndGgpIHsKICAgICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJGbnMucG9wKCkoKTsKICAgIH0KICB9CiAgb25Qb3BTdGF0ZShmbikgewogICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJGbnMucHVzaCh0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLm9uUG9wU3RhdGUoZm4pLCB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLm9uSGFzaENoYW5nZShmbikpOwogIH0KICBnZXRCYXNlSHJlZigpIHsKICAgIHJldHVybiB0aGlzLl9iYXNlSHJlZjsKICB9CiAgcHJlcGFyZUV4dGVybmFsVXJsKGludGVybmFsKSB7CiAgICByZXR1cm4gam9pbldpdGhTbGFzaCh0aGlzLl9iYXNlSHJlZiwgaW50ZXJuYWwpOwogIH0KICBwYXRoKGluY2x1ZGVIYXNoID0gZmFsc2UpIHsKICAgIGNvbnN0IHBhdGhuYW1lID0gdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5wYXRobmFtZSArIG5vcm1hbGl6ZVF1ZXJ5UGFyYW1zKHRoaXMuX3BsYXRmb3JtTG9jYXRpb24uc2VhcmNoKTsKICAgIGNvbnN0IGhhc2ggPSB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLmhhc2g7CiAgICByZXR1cm4gaGFzaCAmJiBpbmNsdWRlSGFzaCA/IGAke3BhdGhuYW1lfSR7aGFzaH1gIDogcGF0aG5hbWU7CiAgfQogIHB1c2hTdGF0ZShzdGF0ZSwgdGl0bGUsIHVybCwgcXVlcnlQYXJhbXMpIHsKICAgIGNvbnN0IGV4dGVybmFsVXJsID0gdGhpcy5wcmVwYXJlRXh0ZXJuYWxVcmwodXJsICsgbm9ybWFsaXplUXVlcnlQYXJhbXMocXVlcnlQYXJhbXMpKTsKICAgIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24ucHVzaFN0YXRlKHN0YXRlLCB0aXRsZSwgZXh0ZXJuYWxVcmwpOwogIH0KICByZXBsYWNlU3RhdGUoc3RhdGUsIHRpdGxlLCB1cmwsIHF1ZXJ5UGFyYW1zKSB7CiAgICBjb25zdCBleHRlcm5hbFVybCA9IHRoaXMucHJlcGFyZUV4dGVybmFsVXJsKHVybCArIG5vcm1hbGl6ZVF1ZXJ5UGFyYW1zKHF1ZXJ5UGFyYW1zKSk7CiAgICB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLnJlcGxhY2VTdGF0ZShzdGF0ZSwgdGl0bGUsIGV4dGVybmFsVXJsKTsKICB9CiAgZm9yd2FyZCgpIHsKICAgIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24uZm9yd2FyZCgpOwogIH0KICBiYWNrKCkgewogICAgdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5iYWNrKCk7CiAgfQogIGdldFN0YXRlKCkgewogICAgcmV0dXJuIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24uZ2V0U3RhdGUoKTsKICB9CiAgaGlzdG9yeUdvKHJlbGF0aXZlUG9zaXRpb24gPSAwKSB7CiAgICB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLmhpc3RvcnlHbz8uKHJlbGF0aXZlUG9zaXRpb24pOwogIH0KfTsKX1BhdGhMb2NhdGlvblN0cmF0ZWd5Lsm1ZmFjID0gZnVuY3Rpb24gUGF0aExvY2F0aW9uU3RyYXRlZ3lfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfUGF0aExvY2F0aW9uU3RyYXRlZ3kpKMm1ybVpbmplY3QoUGxhdGZvcm1Mb2NhdGlvbiksIMm1ybVpbmplY3QoQVBQX0JBU0VfSFJFRiwgOCkpOwp9OwpfUGF0aExvY2F0aW9uU3RyYXRlZ3kuybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfUGF0aExvY2F0aW9uU3RyYXRlZ3ksCiAgZmFjdG9yeTogX1BhdGhMb2NhdGlvblN0cmF0ZWd5Lsm1ZmFjLAogIHByb3ZpZGVkSW46ICJyb290Igp9KTsKdmFyIFBhdGhMb2NhdGlvblN0cmF0ZWd5ID0gX1BhdGhMb2NhdGlvblN0cmF0ZWd5OwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoUGF0aExvY2F0aW9uU3RyYXRlZ3ksIFt7CiAgICB0eXBlOiBJbmplY3RhYmxlLAogICAgYXJnczogW3sKICAgICAgcHJvdmlkZWRJbjogInJvb3QiCiAgICB9XQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogUGxhdGZvcm1Mb2NhdGlvbgogIH0sIHsKICAgIHR5cGU6IHZvaWQgMCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IE9wdGlvbmFsCiAgICB9LCB7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0FQUF9CQVNFX0hSRUZdCiAgICB9XQogIH1dLCBudWxsKTsKfSkoKTsKdmFyIF9IYXNoTG9jYXRpb25TdHJhdGVneSA9IGNsYXNzIF9IYXNoTG9jYXRpb25TdHJhdGVneSBleHRlbmRzIExvY2F0aW9uU3RyYXRlZ3kgewogIGNvbnN0cnVjdG9yKF9wbGF0Zm9ybUxvY2F0aW9uLCBfYmFzZUhyZWYpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uID0gX3BsYXRmb3JtTG9jYXRpb247CiAgICB0aGlzLl9iYXNlSHJlZiA9ICIiOwogICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJGbnMgPSBbXTsKICAgIGlmIChfYmFzZUhyZWYgIT0gbnVsbCkgewogICAgICB0aGlzLl9iYXNlSHJlZiA9IF9iYXNlSHJlZjsKICAgIH0KICB9CiAgLyoqIEBub2RvYyAqLwogIG5nT25EZXN0cm95KCkgewogICAgd2hpbGUgKHRoaXMuX3JlbW92ZUxpc3RlbmVyRm5zLmxlbmd0aCkgewogICAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lckZucy5wb3AoKSgpOwogICAgfQogIH0KICBvblBvcFN0YXRlKGZuKSB7CiAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lckZucy5wdXNoKHRoaXMuX3BsYXRmb3JtTG9jYXRpb24ub25Qb3BTdGF0ZShmbiksIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24ub25IYXNoQ2hhbmdlKGZuKSk7CiAgfQogIGdldEJhc2VIcmVmKCkgewogICAgcmV0dXJuIHRoaXMuX2Jhc2VIcmVmOwogIH0KICBwYXRoKGluY2x1ZGVIYXNoID0gZmFsc2UpIHsKICAgIGNvbnN0IHBhdGggPSB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLmhhc2ggPz8gIiMiOwogICAgcmV0dXJuIHBhdGgubGVuZ3RoID4gMCA/IHBhdGguc3Vic3RyaW5nKDEpIDogcGF0aDsKICB9CiAgcHJlcGFyZUV4dGVybmFsVXJsKGludGVybmFsKSB7CiAgICBjb25zdCB1cmwgPSBqb2luV2l0aFNsYXNoKHRoaXMuX2Jhc2VIcmVmLCBpbnRlcm5hbCk7CiAgICByZXR1cm4gdXJsLmxlbmd0aCA+IDAgPyAiIyIgKyB1cmwgOiB1cmw7CiAgfQogIHB1c2hTdGF0ZShzdGF0ZSwgdGl0bGUsIHBhdGgsIHF1ZXJ5UGFyYW1zKSB7CiAgICBsZXQgdXJsID0gdGhpcy5wcmVwYXJlRXh0ZXJuYWxVcmwocGF0aCArIG5vcm1hbGl6ZVF1ZXJ5UGFyYW1zKHF1ZXJ5UGFyYW1zKSk7CiAgICBpZiAodXJsLmxlbmd0aCA9PSAwKSB7CiAgICAgIHVybCA9IHRoaXMuX3BsYXRmb3JtTG9jYXRpb24ucGF0aG5hbWU7CiAgICB9CiAgICB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLnB1c2hTdGF0ZShzdGF0ZSwgdGl0bGUsIHVybCk7CiAgfQogIHJlcGxhY2VTdGF0ZShzdGF0ZSwgdGl0bGUsIHBhdGgsIHF1ZXJ5UGFyYW1zKSB7CiAgICBsZXQgdXJsID0gdGhpcy5wcmVwYXJlRXh0ZXJuYWxVcmwocGF0aCArIG5vcm1hbGl6ZVF1ZXJ5UGFyYW1zKHF1ZXJ5UGFyYW1zKSk7CiAgICBpZiAodXJsLmxlbmd0aCA9PSAwKSB7CiAgICAgIHVybCA9IHRoaXMuX3BsYXRmb3JtTG9jYXRpb24ucGF0aG5hbWU7CiAgICB9CiAgICB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLnJlcGxhY2VTdGF0ZShzdGF0ZSwgdGl0bGUsIHVybCk7CiAgfQogIGZvcndhcmQoKSB7CiAgICB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLmZvcndhcmQoKTsKICB9CiAgYmFjaygpIHsKICAgIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24uYmFjaygpOwogIH0KICBnZXRTdGF0ZSgpIHsKICAgIHJldHVybiB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLmdldFN0YXRlKCk7CiAgfQogIGhpc3RvcnlHbyhyZWxhdGl2ZVBvc2l0aW9uID0gMCkgewogICAgdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5oaXN0b3J5R28/LihyZWxhdGl2ZVBvc2l0aW9uKTsKICB9Cn07Cl9IYXNoTG9jYXRpb25TdHJhdGVneS7JtWZhYyA9IGZ1bmN0aW9uIEhhc2hMb2NhdGlvblN0cmF0ZWd5X0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0hhc2hMb2NhdGlvblN0cmF0ZWd5KSjJtcm1aW5qZWN0KFBsYXRmb3JtTG9jYXRpb24pLCDJtcm1aW5qZWN0KEFQUF9CQVNFX0hSRUYsIDgpKTsKfTsKX0hhc2hMb2NhdGlvblN0cmF0ZWd5Lsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX0hhc2hMb2NhdGlvblN0cmF0ZWd5LAogIGZhY3Rvcnk6IF9IYXNoTG9jYXRpb25TdHJhdGVneS7JtWZhYwp9KTsKdmFyIEhhc2hMb2NhdGlvblN0cmF0ZWd5ID0gX0hhc2hMb2NhdGlvblN0cmF0ZWd5OwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoSGFzaExvY2F0aW9uU3RyYXRlZ3ksIFt7CiAgICB0eXBlOiBJbmplY3RhYmxlCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiBQbGF0Zm9ybUxvY2F0aW9uCiAgfSwgewogICAgdHlwZTogdm9pZCAwLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogT3B0aW9uYWwKICAgIH0sIHsKICAgICAgdHlwZTogSW5qZWN0LAogICAgICBhcmdzOiBbQVBQX0JBU0VfSFJFRl0KICAgIH1dCiAgfV0sIG51bGwpOwp9KSgpOwp2YXIgX0xvY2F0aW9uID0gY2xhc3MgX0xvY2F0aW9uIHsKICBjb25zdHJ1Y3Rvcihsb2NhdGlvblN0cmF0ZWd5KSB7CiAgICB0aGlzLl9zdWJqZWN0ID0gbmV3IEV2ZW50RW1pdHRlcigpOwogICAgdGhpcy5fdXJsQ2hhbmdlTGlzdGVuZXJzID0gW107CiAgICB0aGlzLl91cmxDaGFuZ2VTdWJzY3JpcHRpb24gPSBudWxsOwogICAgdGhpcy5fbG9jYXRpb25TdHJhdGVneSA9IGxvY2F0aW9uU3RyYXRlZ3k7CiAgICBjb25zdCBiYXNlSHJlZiA9IHRoaXMuX2xvY2F0aW9uU3RyYXRlZ3kuZ2V0QmFzZUhyZWYoKTsKICAgIHRoaXMuX2Jhc2VQYXRoID0gX3N0cmlwT3JpZ2luKHN0cmlwVHJhaWxpbmdTbGFzaChfc3RyaXBJbmRleEh0bWwoYmFzZUhyZWYpKSk7CiAgICB0aGlzLl9sb2NhdGlvblN0cmF0ZWd5Lm9uUG9wU3RhdGUoKGV2KSA9PiB7CiAgICAgIHRoaXMuX3N1YmplY3QuZW1pdCh7CiAgICAgICAgInVybCI6IHRoaXMucGF0aCh0cnVlKSwKICAgICAgICAicG9wIjogdHJ1ZSwKICAgICAgICAic3RhdGUiOiBldi5zdGF0ZSwKICAgICAgICAidHlwZSI6IGV2LnR5cGUKICAgICAgfSk7CiAgICB9KTsKICB9CiAgLyoqIEBub2RvYyAqLwogIG5nT25EZXN0cm95KCkgewogICAgdGhpcy5fdXJsQ2hhbmdlU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpOwogICAgdGhpcy5fdXJsQ2hhbmdlTGlzdGVuZXJzID0gW107CiAgfQogIC8qKgogICAqIE5vcm1hbGl6ZXMgdGhlIFVSTCBwYXRoIGZvciB0aGlzIGxvY2F0aW9uLgogICAqCiAgICogQHBhcmFtIGluY2x1ZGVIYXNoIFRydWUgdG8gaW5jbHVkZSBhbiBhbmNob3IgZnJhZ21lbnQgaW4gdGhlIHBhdGguCiAgICoKICAgKiBAcmV0dXJucyBUaGUgbm9ybWFsaXplZCBVUkwgcGF0aC4KICAgKi8KICAvLyBUT0RPOiB2c2F2a2luLiBSZW1vdmUgdGhlIGJvb2xlYW4gZmxhZyBhbmQgYWx3YXlzIGluY2x1ZGUgaGFzaCBvbmNlIHRoZSBkZXByZWNhdGVkIHJvdXRlciBpcwogIC8vIHJlbW92ZWQuCiAgcGF0aChpbmNsdWRlSGFzaCA9IGZhbHNlKSB7CiAgICByZXR1cm4gdGhpcy5ub3JtYWxpemUodGhpcy5fbG9jYXRpb25TdHJhdGVneS5wYXRoKGluY2x1ZGVIYXNoKSk7CiAgfQogIC8qKgogICAqIFJlcG9ydHMgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIGxvY2F0aW9uIGhpc3RvcnkuCiAgICogQHJldHVybnMgVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGBoaXN0b3J5LnN0YXRlYCBvYmplY3QuCiAgICovCiAgZ2V0U3RhdGUoKSB7CiAgICByZXR1cm4gdGhpcy5fbG9jYXRpb25TdHJhdGVneS5nZXRTdGF0ZSgpOwogIH0KICAvKioKICAgKiBOb3JtYWxpemVzIHRoZSBnaXZlbiBwYXRoIGFuZCBjb21wYXJlcyB0byB0aGUgY3VycmVudCBub3JtYWxpemVkIHBhdGguCiAgICoKICAgKiBAcGFyYW0gcGF0aCBUaGUgZ2l2ZW4gVVJMIHBhdGguCiAgICogQHBhcmFtIHF1ZXJ5IFF1ZXJ5IHBhcmFtZXRlcnMuCiAgICoKICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSBnaXZlbiBVUkwgcGF0aCBpcyBlcXVhbCB0byB0aGUgY3VycmVudCBub3JtYWxpemVkIHBhdGgsIGZhbHNlCiAgICogb3RoZXJ3aXNlLgogICAqLwogIGlzQ3VycmVudFBhdGhFcXVhbFRvKHBhdGgsIHF1ZXJ5ID0gIiIpIHsKICAgIHJldHVybiB0aGlzLnBhdGgoKSA9PSB0aGlzLm5vcm1hbGl6ZShwYXRoICsgbm9ybWFsaXplUXVlcnlQYXJhbXMocXVlcnkpKTsKICB9CiAgLyoqCiAgICogTm9ybWFsaXplcyBhIFVSTCBwYXRoIGJ5IHN0cmlwcGluZyBhbnkgdHJhaWxpbmcgc2xhc2hlcy4KICAgKgogICAqIEBwYXJhbSB1cmwgU3RyaW5nIHJlcHJlc2VudGluZyBhIFVSTC4KICAgKgogICAqIEByZXR1cm5zIFRoZSBub3JtYWxpemVkIFVSTCBzdHJpbmcuCiAgICovCiAgbm9ybWFsaXplKHVybCkgewogICAgcmV0dXJuIF9Mb2NhdGlvbi5zdHJpcFRyYWlsaW5nU2xhc2goX3N0cmlwQmFzZVBhdGgodGhpcy5fYmFzZVBhdGgsIF9zdHJpcEluZGV4SHRtbCh1cmwpKSk7CiAgfQogIC8qKgogICAqIE5vcm1hbGl6ZXMgYW4gZXh0ZXJuYWwgVVJMIHBhdGguCiAgICogSWYgdGhlIGdpdmVuIFVSTCBkb2Vzbid0IGJlZ2luIHdpdGggYSBsZWFkaW5nIHNsYXNoIChgJy8nYCksIGFkZHMgb25lCiAgICogYmVmb3JlIG5vcm1hbGl6aW5nLiBBZGRzIGEgaGFzaCBpZiBgSGFzaExvY2F0aW9uU3RyYXRlZ3lgIGlzCiAgICogaW4gdXNlLCBvciB0aGUgYEFQUF9CQVNFX0hSRUZgIGlmIHRoZSBgUGF0aExvY2F0aW9uU3RyYXRlZ3lgIGlzIGluIHVzZS4KICAgKgogICAqIEBwYXJhbSB1cmwgU3RyaW5nIHJlcHJlc2VudGluZyBhIFVSTC4KICAgKgogICAqIEByZXR1cm5zICBBIG5vcm1hbGl6ZWQgcGxhdGZvcm0tc3BlY2lmaWMgVVJMLgogICAqLwogIHByZXBhcmVFeHRlcm5hbFVybCh1cmwpIHsKICAgIGlmICh1cmwgJiYgdXJsWzBdICE9PSAiLyIpIHsKICAgICAgdXJsID0gIi8iICsgdXJsOwogICAgfQogICAgcmV0dXJuIHRoaXMuX2xvY2F0aW9uU3RyYXRlZ3kucHJlcGFyZUV4dGVybmFsVXJsKHVybCk7CiAgfQogIC8vIFRPRE86IHJlbmFtZSB0aGlzIG1ldGhvZCB0byBwdXNoU3RhdGUKICAvKioKICAgKiBDaGFuZ2VzIHRoZSBicm93c2VyJ3MgVVJMIHRvIGEgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIGEgZ2l2ZW4gVVJMLCBhbmQgcHVzaGVzIGEKICAgKiBuZXcgaXRlbSBvbnRvIHRoZSBwbGF0Zm9ybSdzIGhpc3RvcnkuCiAgICoKICAgKiBAcGFyYW0gcGF0aCAgVVJMIHBhdGggdG8gbm9ybWFsaXplLgogICAqIEBwYXJhbSBxdWVyeSBRdWVyeSBwYXJhbWV0ZXJzLgogICAqIEBwYXJhbSBzdGF0ZSBMb2NhdGlvbiBoaXN0b3J5IHN0YXRlLgogICAqCiAgICovCiAgZ28ocGF0aCwgcXVlcnkgPSAiIiwgc3RhdGUgPSBudWxsKSB7CiAgICB0aGlzLl9sb2NhdGlvblN0cmF0ZWd5LnB1c2hTdGF0ZShzdGF0ZSwgIiIsIHBhdGgsIHF1ZXJ5KTsKICAgIHRoaXMuX25vdGlmeVVybENoYW5nZUxpc3RlbmVycyh0aGlzLnByZXBhcmVFeHRlcm5hbFVybChwYXRoICsgbm9ybWFsaXplUXVlcnlQYXJhbXMocXVlcnkpKSwgc3RhdGUpOwogIH0KICAvKioKICAgKiBDaGFuZ2VzIHRoZSBicm93c2VyJ3MgVVJMIHRvIGEgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBnaXZlbiBVUkwsIGFuZCByZXBsYWNlcwogICAqIHRoZSB0b3AgaXRlbSBvbiB0aGUgcGxhdGZvcm0ncyBoaXN0b3J5IHN0YWNrLgogICAqCiAgICogQHBhcmFtIHBhdGggIFVSTCBwYXRoIHRvIG5vcm1hbGl6ZS4KICAgKiBAcGFyYW0gcXVlcnkgUXVlcnkgcGFyYW1ldGVycy4KICAgKiBAcGFyYW0gc3RhdGUgTG9jYXRpb24gaGlzdG9yeSBzdGF0ZS4KICAgKi8KICByZXBsYWNlU3RhdGUocGF0aCwgcXVlcnkgPSAiIiwgc3RhdGUgPSBudWxsKSB7CiAgICB0aGlzLl9sb2NhdGlvblN0cmF0ZWd5LnJlcGxhY2VTdGF0ZShzdGF0ZSwgIiIsIHBhdGgsIHF1ZXJ5KTsKICAgIHRoaXMuX25vdGlmeVVybENoYW5nZUxpc3RlbmVycyh0aGlzLnByZXBhcmVFeHRlcm5hbFVybChwYXRoICsgbm9ybWFsaXplUXVlcnlQYXJhbXMocXVlcnkpKSwgc3RhdGUpOwogIH0KICAvKioKICAgKiBOYXZpZ2F0ZXMgZm9yd2FyZCBpbiB0aGUgcGxhdGZvcm0ncyBoaXN0b3J5LgogICAqLwogIGZvcndhcmQoKSB7CiAgICB0aGlzLl9sb2NhdGlvblN0cmF0ZWd5LmZvcndhcmQoKTsKICB9CiAgLyoqCiAgICogTmF2aWdhdGVzIGJhY2sgaW4gdGhlIHBsYXRmb3JtJ3MgaGlzdG9yeS4KICAgKi8KICBiYWNrKCkgewogICAgdGhpcy5fbG9jYXRpb25TdHJhdGVneS5iYWNrKCk7CiAgfQogIC8qKgogICAqIE5hdmlnYXRlIHRvIGEgc3BlY2lmaWMgcGFnZSBmcm9tIHNlc3Npb24gaGlzdG9yeSwgaWRlbnRpZmllZCBieSBpdHMgcmVsYXRpdmUgcG9zaXRpb24gdG8gdGhlCiAgICogY3VycmVudCBwYWdlLgogICAqCiAgICogQHBhcmFtIHJlbGF0aXZlUG9zaXRpb24gIFBvc2l0aW9uIG9mIHRoZSB0YXJnZXQgcGFnZSBpbiB0aGUgaGlzdG9yeSByZWxhdGl2ZSB0byB0aGUgY3VycmVudAogICAqICAgICBwYWdlLgogICAqIEEgbmVnYXRpdmUgdmFsdWUgbW92ZXMgYmFja3dhcmRzLCBhIHBvc2l0aXZlIHZhbHVlIG1vdmVzIGZvcndhcmRzLCBlLmcuIGBsb2NhdGlvbi5oaXN0b3J5R28oMilgCiAgICogbW92ZXMgZm9yd2FyZCB0d28gcGFnZXMgYW5kIGBsb2NhdGlvbi5oaXN0b3J5R28oLTIpYCBtb3ZlcyBiYWNrIHR3byBwYWdlcy4gV2hlbiB3ZSB0cnkgdG8gZ28KICAgKiBiZXlvbmQgd2hhdCdzIHN0b3JlZCBpbiB0aGUgaGlzdG9yeSBzZXNzaW9uLCB3ZSBzdGF5IGluIHRoZSBjdXJyZW50IHBhZ2UuIFNhbWUgYmVoYXZpb3VyIG9jY3VycwogICAqIHdoZW4gYHJlbGF0aXZlUG9zaXRpb25gIGVxdWFscyAwLgogICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hpc3RvcnlfQVBJI01vdmluZ190b19hX3NwZWNpZmljX3BvaW50X2luX2hpc3RvcnkKICAgKi8KICBoaXN0b3J5R28ocmVsYXRpdmVQb3NpdGlvbiA9IDApIHsKICAgIHRoaXMuX2xvY2F0aW9uU3RyYXRlZ3kuaGlzdG9yeUdvPy4ocmVsYXRpdmVQb3NpdGlvbik7CiAgfQogIC8qKgogICAqIFJlZ2lzdGVycyBhIFVSTCBjaGFuZ2UgbGlzdGVuZXIuIFVzZSB0byBjYXRjaCB1cGRhdGVzIHBlcmZvcm1lZCBieSB0aGUgQW5ndWxhcgogICAqIGZyYW1ld29yayB0aGF0IGFyZSBub3QgZGV0ZWN0aWJsZSB0aHJvdWdoICJwb3BzdGF0ZSIgb3IgImhhc2hjaGFuZ2UiIGV2ZW50cy4KICAgKgogICAqIEBwYXJhbSBmbiBUaGUgY2hhbmdlIGhhbmRsZXIgZnVuY3Rpb24sIHdoaWNoIHRha2UgYSBVUkwgYW5kIGEgbG9jYXRpb24gaGlzdG9yeSBzdGF0ZS4KICAgKiBAcmV0dXJucyBBIGZ1bmN0aW9uIHRoYXQsIHdoZW4gZXhlY3V0ZWQsIHVucmVnaXN0ZXJzIGEgVVJMIGNoYW5nZSBsaXN0ZW5lci4KICAgKi8KICBvblVybENoYW5nZShmbikgewogICAgdGhpcy5fdXJsQ2hhbmdlTGlzdGVuZXJzLnB1c2goZm4pOwogICAgdGhpcy5fdXJsQ2hhbmdlU3Vic2NyaXB0aW9uID8/PSB0aGlzLnN1YnNjcmliZSgodikgPT4gewogICAgICB0aGlzLl9ub3RpZnlVcmxDaGFuZ2VMaXN0ZW5lcnModi51cmwsIHYuc3RhdGUpOwogICAgfSk7CiAgICByZXR1cm4gKCkgPT4gewogICAgICBjb25zdCBmbkluZGV4ID0gdGhpcy5fdXJsQ2hhbmdlTGlzdGVuZXJzLmluZGV4T2YoZm4pOwogICAgICB0aGlzLl91cmxDaGFuZ2VMaXN0ZW5lcnMuc3BsaWNlKGZuSW5kZXgsIDEpOwogICAgICBpZiAodGhpcy5fdXJsQ2hhbmdlTGlzdGVuZXJzLmxlbmd0aCA9PT0gMCkgewogICAgICAgIHRoaXMuX3VybENoYW5nZVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTsKICAgICAgICB0aGlzLl91cmxDaGFuZ2VTdWJzY3JpcHRpb24gPSBudWxsOwogICAgICB9CiAgICB9OwogIH0KICAvKiogQGludGVybmFsICovCiAgX25vdGlmeVVybENoYW5nZUxpc3RlbmVycyh1cmwgPSAiIiwgc3RhdGUpIHsKICAgIHRoaXMuX3VybENoYW5nZUxpc3RlbmVycy5mb3JFYWNoKChmbikgPT4gZm4odXJsLCBzdGF0ZSkpOwogIH0KICAvKioKICAgKiBTdWJzY3JpYmVzIHRvIHRoZSBwbGF0Zm9ybSdzIGBwb3BTdGF0ZWAgZXZlbnRzLgogICAqCiAgICogTm90ZTogYExvY2F0aW9uLmdvKClgIGRvZXMgbm90IHRyaWdnZXIgdGhlIGBwb3BTdGF0ZWAgZXZlbnQgaW4gdGhlIGJyb3dzZXIuIFVzZQogICAqIGBMb2NhdGlvbi5vblVybENoYW5nZSgpYCB0byBzdWJzY3JpYmUgdG8gVVJMIGNoYW5nZXMgaW5zdGVhZC4KICAgKgogICAqIEBwYXJhbSB2YWx1ZSBFdmVudCB0aGF0IGlzIHRyaWdnZXJlZCB3aGVuIHRoZSBzdGF0ZSBoaXN0b3J5IGNoYW5nZXMuCiAgICogQHBhcmFtIGV4Y2VwdGlvbiBUaGUgZXhjZXB0aW9uIHRvIHRocm93LgogICAqCiAgICogQHNlZSBbb25wb3BzdGF0ZV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1dpbmRvd0V2ZW50SGFuZGxlcnMvb25wb3BzdGF0ZSkKICAgKgogICAqIEByZXR1cm5zIFN1YnNjcmliZWQgZXZlbnRzLgogICAqLwogIHN1YnNjcmliZShvbk5leHQsIG9uVGhyb3csIG9uUmV0dXJuKSB7CiAgICByZXR1cm4gdGhpcy5fc3ViamVjdC5zdWJzY3JpYmUoewogICAgICBuZXh0OiBvbk5leHQsCiAgICAgIGVycm9yOiBvblRocm93LAogICAgICBjb21wbGV0ZTogb25SZXR1cm4KICAgIH0pOwogIH0KfTsKX0xvY2F0aW9uLm5vcm1hbGl6ZVF1ZXJ5UGFyYW1zID0gbm9ybWFsaXplUXVlcnlQYXJhbXM7Cl9Mb2NhdGlvbi5qb2luV2l0aFNsYXNoID0gam9pbldpdGhTbGFzaDsKX0xvY2F0aW9uLnN0cmlwVHJhaWxpbmdTbGFzaCA9IHN0cmlwVHJhaWxpbmdTbGFzaDsKX0xvY2F0aW9uLsm1ZmFjID0gZnVuY3Rpb24gTG9jYXRpb25fRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTG9jYXRpb24pKMm1ybVpbmplY3QoTG9jYXRpb25TdHJhdGVneSkpOwp9OwpfTG9jYXRpb24uybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfTG9jYXRpb24sCiAgZmFjdG9yeTogKCkgPT4gY3JlYXRlTG9jYXRpb24oKSwKICBwcm92aWRlZEluOiAicm9vdCIKfSk7CnZhciBMb2NhdGlvbiA9IF9Mb2NhdGlvbjsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKExvY2F0aW9uLCBbewogICAgdHlwZTogSW5qZWN0YWJsZSwKICAgIGFyZ3M6IFt7CiAgICAgIHByb3ZpZGVkSW46ICJyb290IiwKICAgICAgLy8gU2VlICMyMzkxNwogICAgICB1c2VGYWN0b3J5OiBjcmVhdGVMb2NhdGlvbgogICAgfV0KICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IExvY2F0aW9uU3RyYXRlZ3kKICB9XSwgbnVsbCk7Cn0pKCk7CmZ1bmN0aW9uIGNyZWF0ZUxvY2F0aW9uKCkgewogIHJldHVybiBuZXcgTG9jYXRpb24oybXJtWluamVjdChMb2NhdGlvblN0cmF0ZWd5KSk7Cn0KZnVuY3Rpb24gX3N0cmlwQmFzZVBhdGgoYmFzZVBhdGgsIHVybCkgewogIGlmICghYmFzZVBhdGggfHwgIXVybC5zdGFydHNXaXRoKGJhc2VQYXRoKSkgewogICAgcmV0dXJuIHVybDsKICB9CiAgY29uc3Qgc3RyaXBwZWRVcmwgPSB1cmwuc3Vic3RyaW5nKGJhc2VQYXRoLmxlbmd0aCk7CiAgaWYgKHN0cmlwcGVkVXJsID09PSAiIiB8fCBbIi8iLCAiOyIsICI/IiwgIiMiXS5pbmNsdWRlcyhzdHJpcHBlZFVybFswXSkpIHsKICAgIHJldHVybiBzdHJpcHBlZFVybDsKICB9CiAgcmV0dXJuIHVybDsKfQpmdW5jdGlvbiBfc3RyaXBJbmRleEh0bWwodXJsKSB7CiAgcmV0dXJuIHVybC5yZXBsYWNlKC9cL2luZGV4Lmh0bWwkLywgIiIpOwp9CmZ1bmN0aW9uIF9zdHJpcE9yaWdpbihiYXNlSHJlZikgewogIGNvbnN0IGlzQWJzb2x1dGVVcmwyID0gbmV3IFJlZ0V4cCgiXihodHRwcz86KT8vLyIpLnRlc3QoYmFzZUhyZWYpOwogIGlmIChpc0Fic29sdXRlVXJsMikgewogICAgY29uc3QgWywgcGF0aG5hbWVdID0gYmFzZUhyZWYuc3BsaXQoL1wvXC9bXlwvXSsvKTsKICAgIHJldHVybiBwYXRobmFtZTsKICB9CiAgcmV0dXJuIGJhc2VIcmVmOwp9CnZhciBDVVJSRU5DSUVTX0VOID0gewogICJBRFAiOiBbdm9pZCAwLCB2b2lkIDAsIDBdLAogICJBRk4iOiBbdm9pZCAwLCAi2IsiLCAwXSwKICAiQUxMIjogW3ZvaWQgMCwgdm9pZCAwLCAwXSwKICAiQU1EIjogW3ZvaWQgMCwgItaPIiwgMl0sCiAgIkFPQSI6IFt2b2lkIDAsICJLeiJdLAogICJBUlMiOiBbdm9pZCAwLCAiJCJdLAogICJBVUQiOiBbIkEkIiwgIiQiXSwKICAiQVpOIjogW3ZvaWQgMCwgIuKCvCJdLAogICJCQU0iOiBbdm9pZCAwLCAiS00iXSwKICAiQkJEIjogW3ZvaWQgMCwgIiQiXSwKICAiQkRUIjogW3ZvaWQgMCwgIuCnsyJdLAogICJCSEQiOiBbdm9pZCAwLCB2b2lkIDAsIDNdLAogICJCSUYiOiBbdm9pZCAwLCB2b2lkIDAsIDBdLAogICJCTUQiOiBbdm9pZCAwLCAiJCJdLAogICJCTkQiOiBbdm9pZCAwLCAiJCJdLAogICJCT0IiOiBbdm9pZCAwLCAiQnMiXSwKICAiQlJMIjogWyJSJCJdLAogICJCU0QiOiBbdm9pZCAwLCAiJCJdLAogICJCV1AiOiBbdm9pZCAwLCAiUCJdLAogICJCWU4iOiBbdm9pZCAwLCB2b2lkIDAsIDJdLAogICJCWVIiOiBbdm9pZCAwLCB2b2lkIDAsIDBdLAogICJCWkQiOiBbdm9pZCAwLCAiJCJdLAogICJDQUQiOiBbIkNBJCIsICIkIiwgMl0sCiAgIkNIRiI6IFt2b2lkIDAsIHZvaWQgMCwgMl0sCiAgIkNMRiI6IFt2b2lkIDAsIHZvaWQgMCwgNF0sCiAgIkNMUCI6IFt2b2lkIDAsICIkIiwgMF0sCiAgIkNOWSI6IFsiQ07CpSIsICLCpSJdLAogICJDT1AiOiBbdm9pZCAwLCAiJCIsIDJdLAogICJDUkMiOiBbdm9pZCAwLCAi4oKhIiwgMl0sCiAgIkNVQyI6IFt2b2lkIDAsICIkIl0sCiAgIkNVUCI6IFt2b2lkIDAsICIkIl0sCiAgIkNaSyI6IFt2b2lkIDAsICJLxI0iLCAyXSwKICAiREpGIjogW3ZvaWQgMCwgdm9pZCAwLCAwXSwKICAiREtLIjogW3ZvaWQgMCwgImtyIiwgMl0sCiAgIkRPUCI6IFt2b2lkIDAsICIkIl0sCiAgIkVHUCI6IFt2b2lkIDAsICJFwqMiXSwKICAiRVNQIjogW3ZvaWQgMCwgIuKCpyIsIDBdLAogICJFVVIiOiBbIuKCrCJdLAogICJGSkQiOiBbdm9pZCAwLCAiJCJdLAogICJGS1AiOiBbdm9pZCAwLCAiwqMiXSwKICAiR0JQIjogWyLCoyJdLAogICJHRUwiOiBbdm9pZCAwLCAi4oK+Il0sCiAgIkdIUyI6IFt2b2lkIDAsICJHSOKCtSJdLAogICJHSVAiOiBbdm9pZCAwLCAiwqMiXSwKICAiR05GIjogW3ZvaWQgMCwgIkZHIiwgMF0sCiAgIkdUUSI6IFt2b2lkIDAsICJRIl0sCiAgIkdZRCI6IFt2b2lkIDAsICIkIiwgMl0sCiAgIkhLRCI6IFsiSEskIiwgIiQiXSwKICAiSE5MIjogW3ZvaWQgMCwgIkwiXSwKICAiSFJLIjogW3ZvaWQgMCwgImtuIl0sCiAgIkhVRiI6IFt2b2lkIDAsICJGdCIsIDJdLAogICJJRFIiOiBbdm9pZCAwLCAiUnAiLCAyXSwKICAiSUxTIjogWyLigqoiXSwKICAiSU5SIjogWyLigrkiXSwKICAiSVFEIjogW3ZvaWQgMCwgdm9pZCAwLCAwXSwKICAiSVJSIjogW3ZvaWQgMCwgdm9pZCAwLCAwXSwKICAiSVNLIjogW3ZvaWQgMCwgImtyIiwgMF0sCiAgIklUTCI6IFt2b2lkIDAsIHZvaWQgMCwgMF0sCiAgIkpNRCI6IFt2b2lkIDAsICIkIl0sCiAgIkpPRCI6IFt2b2lkIDAsIHZvaWQgMCwgM10sCiAgIkpQWSI6IFsiwqUiLCB2b2lkIDAsIDBdLAogICJLSFIiOiBbdm9pZCAwLCAi4Z+bIl0sCiAgIktNRiI6IFt2b2lkIDAsICJDRiIsIDBdLAogICJLUFciOiBbdm9pZCAwLCAi4oKpIiwgMF0sCiAgIktSVyI6IFsi4oKpIiwgdm9pZCAwLCAwXSwKICAiS1dEIjogW3ZvaWQgMCwgdm9pZCAwLCAzXSwKICAiS1lEIjogW3ZvaWQgMCwgIiQiXSwKICAiS1pUIjogW3ZvaWQgMCwgIuKCuCJdLAogICJMQUsiOiBbdm9pZCAwLCAi4oKtIiwgMF0sCiAgIkxCUCI6IFt2b2lkIDAsICJMwqMiLCAwXSwKICAiTEtSIjogW3ZvaWQgMCwgIlJzIl0sCiAgIkxSRCI6IFt2b2lkIDAsICIkIl0sCiAgIkxUTCI6IFt2b2lkIDAsICJMdCJdLAogICJMVUYiOiBbdm9pZCAwLCB2b2lkIDAsIDBdLAogICJMVkwiOiBbdm9pZCAwLCAiTHMiXSwKICAiTFlEIjogW3ZvaWQgMCwgdm9pZCAwLCAzXSwKICAiTUdBIjogW3ZvaWQgMCwgIkFyIiwgMF0sCiAgIk1HRiI6IFt2b2lkIDAsIHZvaWQgMCwgMF0sCiAgIk1NSyI6IFt2b2lkIDAsICJLIiwgMF0sCiAgIk1OVCI6IFt2b2lkIDAsICLigq4iLCAyXSwKICAiTVJPIjogW3ZvaWQgMCwgdm9pZCAwLCAwXSwKICAiTVVSIjogW3ZvaWQgMCwgIlJzIiwgMl0sCiAgIk1YTiI6IFsiTVgkIiwgIiQiXSwKICAiTVlSIjogW3ZvaWQgMCwgIlJNIl0sCiAgIk5BRCI6IFt2b2lkIDAsICIkIl0sCiAgIk5HTiI6IFt2b2lkIDAsICLigqYiXSwKICAiTklPIjogW3ZvaWQgMCwgIkMkIl0sCiAgIk5PSyI6IFt2b2lkIDAsICJrciIsIDJdLAogICJOUFIiOiBbdm9pZCAwLCAiUnMiXSwKICAiTlpEIjogWyJOWiQiLCAiJCJdLAogICJPTVIiOiBbdm9pZCAwLCB2b2lkIDAsIDNdLAogICJQSFAiOiBbIuKCsSJdLAogICJQS1IiOiBbdm9pZCAwLCAiUnMiLCAyXSwKICAiUExOIjogW3ZvaWQgMCwgInrFgiJdLAogICJQWUciOiBbdm9pZCAwLCAi4oKyIiwgMF0sCiAgIlJPTiI6IFt2b2lkIDAsICJsZWkiXSwKICAiUlNEIjogW3ZvaWQgMCwgdm9pZCAwLCAwXSwKICAiUlVCIjogW3ZvaWQgMCwgIuKCvSJdLAogICJSV0YiOiBbdm9pZCAwLCAiUkYiLCAwXSwKICAiU0JEIjogW3ZvaWQgMCwgIiQiXSwKICAiU0VLIjogW3ZvaWQgMCwgImtyIiwgMl0sCiAgIlNHRCI6IFt2b2lkIDAsICIkIl0sCiAgIlNIUCI6IFt2b2lkIDAsICLCoyJdLAogICJTTEUiOiBbdm9pZCAwLCB2b2lkIDAsIDJdLAogICJTTEwiOiBbdm9pZCAwLCB2b2lkIDAsIDBdLAogICJTT1MiOiBbdm9pZCAwLCB2b2lkIDAsIDBdLAogICJTUkQiOiBbdm9pZCAwLCAiJCJdLAogICJTU1AiOiBbdm9pZCAwLCAiwqMiXSwKICAiU1REIjogW3ZvaWQgMCwgdm9pZCAwLCAwXSwKICAiU1ROIjogW3ZvaWQgMCwgIkRiIl0sCiAgIlNZUCI6IFt2b2lkIDAsICLCoyIsIDBdLAogICJUSEIiOiBbdm9pZCAwLCAi4Li/Il0sCiAgIlRNTSI6IFt2b2lkIDAsIHZvaWQgMCwgMF0sCiAgIlRORCI6IFt2b2lkIDAsIHZvaWQgMCwgM10sCiAgIlRPUCI6IFt2b2lkIDAsICJUJCJdLAogICJUUkwiOiBbdm9pZCAwLCB2b2lkIDAsIDBdLAogICJUUlkiOiBbdm9pZCAwLCAi4oK6Il0sCiAgIlRURCI6IFt2b2lkIDAsICIkIl0sCiAgIlRXRCI6IFsiTlQkIiwgIiQiLCAyXSwKICAiVFpTIjogW3ZvaWQgMCwgdm9pZCAwLCAyXSwKICAiVUFIIjogW3ZvaWQgMCwgIuKCtCJdLAogICJVR1giOiBbdm9pZCAwLCB2b2lkIDAsIDBdLAogICJVU0QiOiBbIiQiXSwKICAiVVlJIjogW3ZvaWQgMCwgdm9pZCAwLCAwXSwKICAiVVlVIjogW3ZvaWQgMCwgIiQiXSwKICAiVVlXIjogW3ZvaWQgMCwgdm9pZCAwLCA0XSwKICAiVVpTIjogW3ZvaWQgMCwgdm9pZCAwLCAyXSwKICAiVkVGIjogW3ZvaWQgMCwgIkJzIiwgMl0sCiAgIlZORCI6IFsi4oKrIiwgdm9pZCAwLCAwXSwKICAiVlVWIjogW3ZvaWQgMCwgdm9pZCAwLCAwXSwKICAiWEFGIjogWyJGQ0ZBIiwgdm9pZCAwLCAwXSwKICAiWENEIjogWyJFQyQiLCAiJCJdLAogICJYT0YiOiBbIkbigK9DRkEiLCB2b2lkIDAsIDBdLAogICJYUEYiOiBbIkNGUEYiLCB2b2lkIDAsIDBdLAogICJYWFgiOiBbIsKkIl0sCiAgIllFUiI6IFt2b2lkIDAsIHZvaWQgMCwgMF0sCiAgIlpBUiI6IFt2b2lkIDAsICJSIl0sCiAgIlpNSyI6IFt2b2lkIDAsIHZvaWQgMCwgMF0sCiAgIlpNVyI6IFt2b2lkIDAsICJaSyJdLAogICJaV0QiOiBbdm9pZCAwLCB2b2lkIDAsIDBdCn07CnZhciBOdW1iZXJGb3JtYXRTdHlsZTsKKGZ1bmN0aW9uKE51bWJlckZvcm1hdFN0eWxlMikgewogIE51bWJlckZvcm1hdFN0eWxlMltOdW1iZXJGb3JtYXRTdHlsZTJbIkRlY2ltYWwiXSA9IDBdID0gIkRlY2ltYWwiOwogIE51bWJlckZvcm1hdFN0eWxlMltOdW1iZXJGb3JtYXRTdHlsZTJbIlBlcmNlbnQiXSA9IDFdID0gIlBlcmNlbnQiOwogIE51bWJlckZvcm1hdFN0eWxlMltOdW1iZXJGb3JtYXRTdHlsZTJbIkN1cnJlbmN5Il0gPSAyXSA9ICJDdXJyZW5jeSI7CiAgTnVtYmVyRm9ybWF0U3R5bGUyW051bWJlckZvcm1hdFN0eWxlMlsiU2NpZW50aWZpYyJdID0gM10gPSAiU2NpZW50aWZpYyI7Cn0pKE51bWJlckZvcm1hdFN0eWxlIHx8IChOdW1iZXJGb3JtYXRTdHlsZSA9IHt9KSk7CnZhciBQbHVyYWw7CihmdW5jdGlvbihQbHVyYWwyKSB7CiAgUGx1cmFsMltQbHVyYWwyWyJaZXJvIl0gPSAwXSA9ICJaZXJvIjsKICBQbHVyYWwyW1BsdXJhbDJbIk9uZSJdID0gMV0gPSAiT25lIjsKICBQbHVyYWwyW1BsdXJhbDJbIlR3byJdID0gMl0gPSAiVHdvIjsKICBQbHVyYWwyW1BsdXJhbDJbIkZldyJdID0gM10gPSAiRmV3IjsKICBQbHVyYWwyW1BsdXJhbDJbIk1hbnkiXSA9IDRdID0gIk1hbnkiOwogIFBsdXJhbDJbUGx1cmFsMlsiT3RoZXIiXSA9IDVdID0gIk90aGVyIjsKfSkoUGx1cmFsIHx8IChQbHVyYWwgPSB7fSkpOwp2YXIgRm9ybVN0eWxlOwooZnVuY3Rpb24oRm9ybVN0eWxlMikgewogIEZvcm1TdHlsZTJbRm9ybVN0eWxlMlsiRm9ybWF0Il0gPSAwXSA9ICJGb3JtYXQiOwogIEZvcm1TdHlsZTJbRm9ybVN0eWxlMlsiU3RhbmRhbG9uZSJdID0gMV0gPSAiU3RhbmRhbG9uZSI7Cn0pKEZvcm1TdHlsZSB8fCAoRm9ybVN0eWxlID0ge30pKTsKdmFyIFRyYW5zbGF0aW9uV2lkdGg7CihmdW5jdGlvbihUcmFuc2xhdGlvbldpZHRoMikgewogIFRyYW5zbGF0aW9uV2lkdGgyW1RyYW5zbGF0aW9uV2lkdGgyWyJOYXJyb3ciXSA9IDBdID0gIk5hcnJvdyI7CiAgVHJhbnNsYXRpb25XaWR0aDJbVHJhbnNsYXRpb25XaWR0aDJbIkFiYnJldmlhdGVkIl0gPSAxXSA9ICJBYmJyZXZpYXRlZCI7CiAgVHJhbnNsYXRpb25XaWR0aDJbVHJhbnNsYXRpb25XaWR0aDJbIldpZGUiXSA9IDJdID0gIldpZGUiOwogIFRyYW5zbGF0aW9uV2lkdGgyW1RyYW5zbGF0aW9uV2lkdGgyWyJTaG9ydCJdID0gM10gPSAiU2hvcnQiOwp9KShUcmFuc2xhdGlvbldpZHRoIHx8IChUcmFuc2xhdGlvbldpZHRoID0ge30pKTsKdmFyIEZvcm1hdFdpZHRoOwooZnVuY3Rpb24oRm9ybWF0V2lkdGgyKSB7CiAgRm9ybWF0V2lkdGgyW0Zvcm1hdFdpZHRoMlsiU2hvcnQiXSA9IDBdID0gIlNob3J0IjsKICBGb3JtYXRXaWR0aDJbRm9ybWF0V2lkdGgyWyJNZWRpdW0iXSA9IDFdID0gIk1lZGl1bSI7CiAgRm9ybWF0V2lkdGgyW0Zvcm1hdFdpZHRoMlsiTG9uZyJdID0gMl0gPSAiTG9uZyI7CiAgRm9ybWF0V2lkdGgyW0Zvcm1hdFdpZHRoMlsiRnVsbCJdID0gM10gPSAiRnVsbCI7Cn0pKEZvcm1hdFdpZHRoIHx8IChGb3JtYXRXaWR0aCA9IHt9KSk7CnZhciBOdW1iZXJTeW1ib2wgPSB7CiAgLyoqCiAgICogRGVjaW1hbCBzZXBhcmF0b3IuCiAgICogRm9yIGBlbi1VU2AsIHRoZSBkb3QgY2hhcmFjdGVyLgogICAqIEV4YW1wbGU6IDIsMzQ1YC5gNjcKICAgKi8KICBEZWNpbWFsOiAwLAogIC8qKgogICAqIEdyb3VwaW5nIHNlcGFyYXRvciwgdHlwaWNhbGx5IGZvciB0aG91c2FuZHMuCiAgICogRm9yIGBlbi1VU2AsIHRoZSBjb21tYSBjaGFyYWN0ZXIuCiAgICogRXhhbXBsZTogMmAsYDM0NS42NwogICAqLwogIEdyb3VwOiAxLAogIC8qKgogICAqIExpc3QtaXRlbSBzZXBhcmF0b3IuCiAgICogRXhhbXBsZTogIm9uZSwgdHdvLCBhbmQgdGhyZWUiCiAgICovCiAgTGlzdDogMiwKICAvKioKICAgKiBTaWduIGZvciBwZXJjZW50YWdlIChvdXQgb2YgMTAwKS4KICAgKiBFeGFtcGxlOiAyMy40JQogICAqLwogIFBlcmNlbnRTaWduOiAzLAogIC8qKgogICAqIFNpZ24gZm9yIHBvc2l0aXZlIG51bWJlcnMuCiAgICogRXhhbXBsZTogKzIzCiAgICovCiAgUGx1c1NpZ246IDQsCiAgLyoqCiAgICogU2lnbiBmb3IgbmVnYXRpdmUgbnVtYmVycy4KICAgKiBFeGFtcGxlOiAtMjMKICAgKi8KICBNaW51c1NpZ246IDUsCiAgLyoqCiAgICogQ29tcHV0ZXIgbm90YXRpb24gZm9yIGV4cG9uZW50aWFsIHZhbHVlIChuIHRpbWVzIGEgcG93ZXIgb2YgMTApLgogICAqIEV4YW1wbGU6IDEuMkUzCiAgICovCiAgRXhwb25lbnRpYWw6IDYsCiAgLyoqCiAgICogSHVtYW4tcmVhZGFibGUgZm9ybWF0IG9mIGV4cG9uZW50aWFsLgogICAqIEV4YW1wbGU6IDEuMngxMDMKICAgKi8KICBTdXBlcnNjcmlwdGluZ0V4cG9uZW50OiA3LAogIC8qKgogICAqIFNpZ24gZm9yIHBlcm1pbGxlIChvdXQgb2YgMTAwMCkuCiAgICogRXhhbXBsZTogMjMuNOKAsAogICAqLwogIFBlck1pbGxlOiA4LAogIC8qKgogICAqIEluZmluaXR5LCBjYW4gYmUgdXNlZCB3aXRoIHBsdXMgYW5kIG1pbnVzLgogICAqIEV4YW1wbGU6IOKIniwgK+KIniwgLeKIngogICAqLwogIEluZmluaXR5OiA5LAogIC8qKgogICAqIE5vdCBhIG51bWJlci4KICAgKiBFeGFtcGxlOiBOYU4KICAgKi8KICBOYU46IDEwLAogIC8qKgogICAqIFN5bWJvbCB1c2VkIGJldHdlZW4gdGltZSB1bml0cy4KICAgKiBFeGFtcGxlOiAxMDo1MgogICAqLwogIFRpbWVTZXBhcmF0b3I6IDExLAogIC8qKgogICAqIERlY2ltYWwgc2VwYXJhdG9yIGZvciBjdXJyZW5jeSB2YWx1ZXMgKGZhbGxiYWNrIHRvIGBEZWNpbWFsYCkuCiAgICogRXhhbXBsZTogJDIsMzQ1LjY3CiAgICovCiAgQ3VycmVuY3lEZWNpbWFsOiAxMiwKICAvKioKICAgKiBHcm91cCBzZXBhcmF0b3IgZm9yIGN1cnJlbmN5IHZhbHVlcyAoZmFsbGJhY2sgdG8gYEdyb3VwYCkuCiAgICogRXhhbXBsZTogJDIsMzQ1LjY3CiAgICovCiAgQ3VycmVuY3lHcm91cDogMTMKfTsKdmFyIFdlZWtEYXk7CihmdW5jdGlvbihXZWVrRGF5MikgewogIFdlZWtEYXkyW1dlZWtEYXkyWyJTdW5kYXkiXSA9IDBdID0gIlN1bmRheSI7CiAgV2Vla0RheTJbV2Vla0RheTJbIk1vbmRheSJdID0gMV0gPSAiTW9uZGF5IjsKICBXZWVrRGF5MltXZWVrRGF5MlsiVHVlc2RheSJdID0gMl0gPSAiVHVlc2RheSI7CiAgV2Vla0RheTJbV2Vla0RheTJbIldlZG5lc2RheSJdID0gM10gPSAiV2VkbmVzZGF5IjsKICBXZWVrRGF5MltXZWVrRGF5MlsiVGh1cnNkYXkiXSA9IDRdID0gIlRodXJzZGF5IjsKICBXZWVrRGF5MltXZWVrRGF5MlsiRnJpZGF5Il0gPSA1XSA9ICJGcmlkYXkiOwogIFdlZWtEYXkyW1dlZWtEYXkyWyJTYXR1cmRheSJdID0gNl0gPSAiU2F0dXJkYXkiOwp9KShXZWVrRGF5IHx8IChXZWVrRGF5ID0ge30pKTsKZnVuY3Rpb24gZ2V0TG9jYWxlSWQobG9jYWxlKSB7CiAgcmV0dXJuIGZpbmRMb2NhbGVEYXRhKGxvY2FsZSlbTG9jYWxlRGF0YUluZGV4LkxvY2FsZUlkXTsKfQpmdW5jdGlvbiBnZXRMb2NhbGVEYXlQZXJpb2RzKGxvY2FsZSwgZm9ybVN0eWxlLCB3aWR0aCkgewogIGNvbnN0IGRhdGEgPSBmaW5kTG9jYWxlRGF0YShsb2NhbGUpOwogIGNvbnN0IGFtUG1EYXRhID0gW2RhdGFbTG9jYWxlRGF0YUluZGV4LkRheVBlcmlvZHNGb3JtYXRdLCBkYXRhW0xvY2FsZURhdGFJbmRleC5EYXlQZXJpb2RzU3RhbmRhbG9uZV1dOwogIGNvbnN0IGFtUG0gPSBnZXRMYXN0RGVmaW5lZFZhbHVlKGFtUG1EYXRhLCBmb3JtU3R5bGUpOwogIHJldHVybiBnZXRMYXN0RGVmaW5lZFZhbHVlKGFtUG0sIHdpZHRoKTsKfQpmdW5jdGlvbiBnZXRMb2NhbGVEYXlOYW1lcyhsb2NhbGUsIGZvcm1TdHlsZSwgd2lkdGgpIHsKICBjb25zdCBkYXRhID0gZmluZExvY2FsZURhdGEobG9jYWxlKTsKICBjb25zdCBkYXlzRGF0YSA9IFtkYXRhW0xvY2FsZURhdGFJbmRleC5EYXlzRm9ybWF0XSwgZGF0YVtMb2NhbGVEYXRhSW5kZXguRGF5c1N0YW5kYWxvbmVdXTsKICBjb25zdCBkYXlzID0gZ2V0TGFzdERlZmluZWRWYWx1ZShkYXlzRGF0YSwgZm9ybVN0eWxlKTsKICByZXR1cm4gZ2V0TGFzdERlZmluZWRWYWx1ZShkYXlzLCB3aWR0aCk7Cn0KZnVuY3Rpb24gZ2V0TG9jYWxlTW9udGhOYW1lcyhsb2NhbGUsIGZvcm1TdHlsZSwgd2lkdGgpIHsKICBjb25zdCBkYXRhID0gZmluZExvY2FsZURhdGEobG9jYWxlKTsKICBjb25zdCBtb250aHNEYXRhID0gW2RhdGFbTG9jYWxlRGF0YUluZGV4Lk1vbnRoc0Zvcm1hdF0sIGRhdGFbTG9jYWxlRGF0YUluZGV4Lk1vbnRoc1N0YW5kYWxvbmVdXTsKICBjb25zdCBtb250aHMgPSBnZXRMYXN0RGVmaW5lZFZhbHVlKG1vbnRoc0RhdGEsIGZvcm1TdHlsZSk7CiAgcmV0dXJuIGdldExhc3REZWZpbmVkVmFsdWUobW9udGhzLCB3aWR0aCk7Cn0KZnVuY3Rpb24gZ2V0TG9jYWxlRXJhTmFtZXMobG9jYWxlLCB3aWR0aCkgewogIGNvbnN0IGRhdGEgPSBmaW5kTG9jYWxlRGF0YShsb2NhbGUpOwogIGNvbnN0IGVyYXNEYXRhID0gZGF0YVtMb2NhbGVEYXRhSW5kZXguRXJhc107CiAgcmV0dXJuIGdldExhc3REZWZpbmVkVmFsdWUoZXJhc0RhdGEsIHdpZHRoKTsKfQpmdW5jdGlvbiBnZXRMb2NhbGVEYXRlRm9ybWF0KGxvY2FsZSwgd2lkdGgpIHsKICBjb25zdCBkYXRhID0gZmluZExvY2FsZURhdGEobG9jYWxlKTsKICByZXR1cm4gZ2V0TGFzdERlZmluZWRWYWx1ZShkYXRhW0xvY2FsZURhdGFJbmRleC5EYXRlRm9ybWF0XSwgd2lkdGgpOwp9CmZ1bmN0aW9uIGdldExvY2FsZVRpbWVGb3JtYXQobG9jYWxlLCB3aWR0aCkgewogIGNvbnN0IGRhdGEgPSBmaW5kTG9jYWxlRGF0YShsb2NhbGUpOwogIHJldHVybiBnZXRMYXN0RGVmaW5lZFZhbHVlKGRhdGFbTG9jYWxlRGF0YUluZGV4LlRpbWVGb3JtYXRdLCB3aWR0aCk7Cn0KZnVuY3Rpb24gZ2V0TG9jYWxlRGF0ZVRpbWVGb3JtYXQobG9jYWxlLCB3aWR0aCkgewogIGNvbnN0IGRhdGEgPSBmaW5kTG9jYWxlRGF0YShsb2NhbGUpOwogIGNvbnN0IGRhdGVUaW1lRm9ybWF0RGF0YSA9IGRhdGFbTG9jYWxlRGF0YUluZGV4LkRhdGVUaW1lRm9ybWF0XTsKICByZXR1cm4gZ2V0TGFzdERlZmluZWRWYWx1ZShkYXRlVGltZUZvcm1hdERhdGEsIHdpZHRoKTsKfQpmdW5jdGlvbiBnZXRMb2NhbGVOdW1iZXJTeW1ib2wobG9jYWxlLCBzeW1ib2wpIHsKICBjb25zdCBkYXRhID0gZmluZExvY2FsZURhdGEobG9jYWxlKTsKICBjb25zdCByZXMgPSBkYXRhW0xvY2FsZURhdGFJbmRleC5OdW1iZXJTeW1ib2xzXVtzeW1ib2xdOwogIGlmICh0eXBlb2YgcmVzID09PSAidW5kZWZpbmVkIikgewogICAgaWYgKHN5bWJvbCA9PT0gTnVtYmVyU3ltYm9sLkN1cnJlbmN5RGVjaW1hbCkgewogICAgICByZXR1cm4gZGF0YVtMb2NhbGVEYXRhSW5kZXguTnVtYmVyU3ltYm9sc11bTnVtYmVyU3ltYm9sLkRlY2ltYWxdOwogICAgfSBlbHNlIGlmIChzeW1ib2wgPT09IE51bWJlclN5bWJvbC5DdXJyZW5jeUdyb3VwKSB7CiAgICAgIHJldHVybiBkYXRhW0xvY2FsZURhdGFJbmRleC5OdW1iZXJTeW1ib2xzXVtOdW1iZXJTeW1ib2wuR3JvdXBdOwogICAgfQogIH0KICByZXR1cm4gcmVzOwp9CmZ1bmN0aW9uIGdldExvY2FsZU51bWJlckZvcm1hdChsb2NhbGUsIHR5cGUpIHsKICBjb25zdCBkYXRhID0gZmluZExvY2FsZURhdGEobG9jYWxlKTsKICByZXR1cm4gZGF0YVtMb2NhbGVEYXRhSW5kZXguTnVtYmVyRm9ybWF0c11bdHlwZV07Cn0KZnVuY3Rpb24gZ2V0TG9jYWxlQ3VycmVuY2llcyhsb2NhbGUpIHsKICBjb25zdCBkYXRhID0gZmluZExvY2FsZURhdGEobG9jYWxlKTsKICByZXR1cm4gZGF0YVtMb2NhbGVEYXRhSW5kZXguQ3VycmVuY2llc107Cn0KdmFyIGdldExvY2FsZVBsdXJhbENhc2UyID0gZ2V0TG9jYWxlUGx1cmFsQ2FzZTsKZnVuY3Rpb24gY2hlY2tGdWxsRGF0YShkYXRhKSB7CiAgaWYgKCFkYXRhW0xvY2FsZURhdGFJbmRleC5FeHRyYURhdGFdKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgZXh0cmEgbG9jYWxlIGRhdGEgZm9yIHRoZSBsb2NhbGUgIiR7ZGF0YVtMb2NhbGVEYXRhSW5kZXguTG9jYWxlSWRdfSIuIFVzZSAicmVnaXN0ZXJMb2NhbGVEYXRhIiB0byBsb2FkIG5ldyBkYXRhLiBTZWUgdGhlICJJMThuIGd1aWRlIiBvbiBhbmd1bGFyLmlvIHRvIGtub3cgbW9yZS5gKTsKICB9Cn0KZnVuY3Rpb24gZ2V0TG9jYWxlRXh0cmFEYXlQZXJpb2RSdWxlcyhsb2NhbGUpIHsKICBjb25zdCBkYXRhID0gZmluZExvY2FsZURhdGEobG9jYWxlKTsKICBjaGVja0Z1bGxEYXRhKGRhdGEpOwogIGNvbnN0IHJ1bGVzID0gZGF0YVtMb2NhbGVEYXRhSW5kZXguRXh0cmFEYXRhXVsKICAgIDIKICAgIC8qIMm1RXh0cmFMb2NhbGVEYXRhSW5kZXguRXh0cmFEYXlQZXJpb2RzUnVsZXMgKi8KICBdIHx8IFtdOwogIHJldHVybiBydWxlcy5tYXAoKHJ1bGUpID0+IHsKICAgIGlmICh0eXBlb2YgcnVsZSA9PT0gInN0cmluZyIpIHsKICAgICAgcmV0dXJuIGV4dHJhY3RUaW1lKHJ1bGUpOwogICAgfQogICAgcmV0dXJuIFtleHRyYWN0VGltZShydWxlWzBdKSwgZXh0cmFjdFRpbWUocnVsZVsxXSldOwogIH0pOwp9CmZ1bmN0aW9uIGdldExvY2FsZUV4dHJhRGF5UGVyaW9kcyhsb2NhbGUsIGZvcm1TdHlsZSwgd2lkdGgpIHsKICBjb25zdCBkYXRhID0gZmluZExvY2FsZURhdGEobG9jYWxlKTsKICBjaGVja0Z1bGxEYXRhKGRhdGEpOwogIGNvbnN0IGRheVBlcmlvZHNEYXRhID0gW2RhdGFbTG9jYWxlRGF0YUluZGV4LkV4dHJhRGF0YV1bCiAgICAwCiAgICAvKiDJtUV4dHJhTG9jYWxlRGF0YUluZGV4LkV4dHJhRGF5UGVyaW9kRm9ybWF0cyAqLwogIF0sIGRhdGFbTG9jYWxlRGF0YUluZGV4LkV4dHJhRGF0YV1bCiAgICAxCiAgICAvKiDJtUV4dHJhTG9jYWxlRGF0YUluZGV4LkV4dHJhRGF5UGVyaW9kU3RhbmRhbG9uZSAqLwogIF1dOwogIGNvbnN0IGRheVBlcmlvZHMgPSBnZXRMYXN0RGVmaW5lZFZhbHVlKGRheVBlcmlvZHNEYXRhLCBmb3JtU3R5bGUpIHx8IFtdOwogIHJldHVybiBnZXRMYXN0RGVmaW5lZFZhbHVlKGRheVBlcmlvZHMsIHdpZHRoKSB8fCBbXTsKfQpmdW5jdGlvbiBnZXRMYXN0RGVmaW5lZFZhbHVlKGRhdGEsIGluZGV4KSB7CiAgZm9yIChsZXQgaSA9IGluZGV4OyBpID4gLTE7IGktLSkgewogICAgaWYgKHR5cGVvZiBkYXRhW2ldICE9PSAidW5kZWZpbmVkIikgewogICAgICByZXR1cm4gZGF0YVtpXTsKICAgIH0KICB9CiAgdGhyb3cgbmV3IEVycm9yKCJMb2NhbGUgZGF0YSBBUEk6IGxvY2FsZSBkYXRhIHVuZGVmaW5lZCIpOwp9CmZ1bmN0aW9uIGV4dHJhY3RUaW1lKHRpbWUpIHsKICBjb25zdCBbaCwgbV0gPSB0aW1lLnNwbGl0KCI6Iik7CiAgcmV0dXJuIHsKICAgIGhvdXJzOiAraCwKICAgIG1pbnV0ZXM6ICttCiAgfTsKfQpmdW5jdGlvbiBnZXRDdXJyZW5jeVN5bWJvbChjb2RlLCBmb3JtYXQsIGxvY2FsZSA9ICJlbiIpIHsKICBjb25zdCBjdXJyZW5jeSA9IGdldExvY2FsZUN1cnJlbmNpZXMobG9jYWxlKVtjb2RlXSB8fCBDVVJSRU5DSUVTX0VOW2NvZGVdIHx8IFtdOwogIGNvbnN0IHN5bWJvbE5hcnJvdyA9IGN1cnJlbmN5WwogICAgMQogICAgLyogybVDdXJyZW5jeUluZGV4LlN5bWJvbE5hcnJvdyAqLwogIF07CiAgaWYgKGZvcm1hdCA9PT0gIm5hcnJvdyIgJiYgdHlwZW9mIHN5bWJvbE5hcnJvdyA9PT0gInN0cmluZyIpIHsKICAgIHJldHVybiBzeW1ib2xOYXJyb3c7CiAgfQogIHJldHVybiBjdXJyZW5jeVsKICAgIDAKICAgIC8qIMm1Q3VycmVuY3lJbmRleC5TeW1ib2wgKi8KICBdIHx8IGNvZGU7Cn0KdmFyIERFRkFVTFRfTkJfT0ZfQ1VSUkVOQ1lfRElHSVRTID0gMjsKZnVuY3Rpb24gZ2V0TnVtYmVyT2ZDdXJyZW5jeURpZ2l0cyhjb2RlKSB7CiAgbGV0IGRpZ2l0czsKICBjb25zdCBjdXJyZW5jeSA9IENVUlJFTkNJRVNfRU5bY29kZV07CiAgaWYgKGN1cnJlbmN5KSB7CiAgICBkaWdpdHMgPSBjdXJyZW5jeVsKICAgICAgMgogICAgICAvKiDJtUN1cnJlbmN5SW5kZXguTmJPZkRpZ2l0cyAqLwogICAgXTsKICB9CiAgcmV0dXJuIHR5cGVvZiBkaWdpdHMgPT09ICJudW1iZXIiID8gZGlnaXRzIDogREVGQVVMVF9OQl9PRl9DVVJSRU5DWV9ESUdJVFM7Cn0KdmFyIElTTzg2MDFfREFURV9SRUdFWCA9IC9eKFxkezQsfSktPyhcZFxkKS0/KFxkXGQpKD86VChcZFxkKSg/Ojo/KFxkXGQpKD86Oj8oXGRcZCkoPzpcLihcZCspKT8pPyk/KFp8KFsrLV0pKFxkXGQpOj8oXGRcZCkpPyk/JC87CnZhciBOQU1FRF9GT1JNQVRTID0ge307CnZhciBEQVRFX0ZPUk1BVFNfU1BMSVQgPSAvKCg/OlteQkVHSExNT1NXWVphYmNkaG1zd3l6J10rKXwoPzonKD86W14nXXwnJykqJyl8KD86R3sxLDV9fHl7MSw0fXxZezEsNH18TXsxLDV9fEx7MSw1fXx3ezEsMn18V3sxfXxkezEsMn18RXsxLDZ9fGN7MSw2fXxhezEsNX18YnsxLDV9fEJ7MSw1fXxoezEsMn18SHsxLDJ9fG17MSwyfXxzezEsMn18U3sxLDN9fHp7MSw0fXxaezEsNX18T3sxLDR9KSkoW1xzXFNdKikvOwp2YXIgWm9uZVdpZHRoOwooZnVuY3Rpb24oWm9uZVdpZHRoMikgewogIFpvbmVXaWR0aDJbWm9uZVdpZHRoMlsiU2hvcnQiXSA9IDBdID0gIlNob3J0IjsKICBab25lV2lkdGgyW1pvbmVXaWR0aDJbIlNob3J0R01UIl0gPSAxXSA9ICJTaG9ydEdNVCI7CiAgWm9uZVdpZHRoMltab25lV2lkdGgyWyJMb25nIl0gPSAyXSA9ICJMb25nIjsKICBab25lV2lkdGgyW1pvbmVXaWR0aDJbIkV4dGVuZGVkIl0gPSAzXSA9ICJFeHRlbmRlZCI7Cn0pKFpvbmVXaWR0aCB8fCAoWm9uZVdpZHRoID0ge30pKTsKdmFyIERhdGVUeXBlOwooZnVuY3Rpb24oRGF0ZVR5cGUyKSB7CiAgRGF0ZVR5cGUyW0RhdGVUeXBlMlsiRnVsbFllYXIiXSA9IDBdID0gIkZ1bGxZZWFyIjsKICBEYXRlVHlwZTJbRGF0ZVR5cGUyWyJNb250aCJdID0gMV0gPSAiTW9udGgiOwogIERhdGVUeXBlMltEYXRlVHlwZTJbIkRhdGUiXSA9IDJdID0gIkRhdGUiOwogIERhdGVUeXBlMltEYXRlVHlwZTJbIkhvdXJzIl0gPSAzXSA9ICJIb3VycyI7CiAgRGF0ZVR5cGUyW0RhdGVUeXBlMlsiTWludXRlcyJdID0gNF0gPSAiTWludXRlcyI7CiAgRGF0ZVR5cGUyW0RhdGVUeXBlMlsiU2Vjb25kcyJdID0gNV0gPSAiU2Vjb25kcyI7CiAgRGF0ZVR5cGUyW0RhdGVUeXBlMlsiRnJhY3Rpb25hbFNlY29uZHMiXSA9IDZdID0gIkZyYWN0aW9uYWxTZWNvbmRzIjsKICBEYXRlVHlwZTJbRGF0ZVR5cGUyWyJEYXkiXSA9IDddID0gIkRheSI7Cn0pKERhdGVUeXBlIHx8IChEYXRlVHlwZSA9IHt9KSk7CnZhciBUcmFuc2xhdGlvblR5cGU7CihmdW5jdGlvbihUcmFuc2xhdGlvblR5cGUyKSB7CiAgVHJhbnNsYXRpb25UeXBlMltUcmFuc2xhdGlvblR5cGUyWyJEYXlQZXJpb2RzIl0gPSAwXSA9ICJEYXlQZXJpb2RzIjsKICBUcmFuc2xhdGlvblR5cGUyW1RyYW5zbGF0aW9uVHlwZTJbIkRheXMiXSA9IDFdID0gIkRheXMiOwogIFRyYW5zbGF0aW9uVHlwZTJbVHJhbnNsYXRpb25UeXBlMlsiTW9udGhzIl0gPSAyXSA9ICJNb250aHMiOwogIFRyYW5zbGF0aW9uVHlwZTJbVHJhbnNsYXRpb25UeXBlMlsiRXJhcyJdID0gM10gPSAiRXJhcyI7Cn0pKFRyYW5zbGF0aW9uVHlwZSB8fCAoVHJhbnNsYXRpb25UeXBlID0ge30pKTsKZnVuY3Rpb24gZm9ybWF0RGF0ZSh2YWx1ZSwgZm9ybWF0LCBsb2NhbGUsIHRpbWV6b25lKSB7CiAgbGV0IGRhdGUgPSB0b0RhdGUodmFsdWUpOwogIGNvbnN0IG5hbWVkRm9ybWF0ID0gZ2V0TmFtZWRGb3JtYXQobG9jYWxlLCBmb3JtYXQpOwogIGZvcm1hdCA9IG5hbWVkRm9ybWF0IHx8IGZvcm1hdDsKICBsZXQgcGFydHMgPSBbXTsKICBsZXQgbWF0Y2g7CiAgd2hpbGUgKGZvcm1hdCkgewogICAgbWF0Y2ggPSBEQVRFX0ZPUk1BVFNfU1BMSVQuZXhlYyhmb3JtYXQpOwogICAgaWYgKG1hdGNoKSB7CiAgICAgIHBhcnRzID0gcGFydHMuY29uY2F0KG1hdGNoLnNsaWNlKDEpKTsKICAgICAgY29uc3QgcGFydCA9IHBhcnRzLnBvcCgpOwogICAgICBpZiAoIXBhcnQpIHsKICAgICAgICBicmVhazsKICAgICAgfQogICAgICBmb3JtYXQgPSBwYXJ0OwogICAgfSBlbHNlIHsKICAgICAgcGFydHMucHVzaChmb3JtYXQpOwogICAgICBicmVhazsKICAgIH0KICB9CiAgbGV0IGRhdGVUaW1lem9uZU9mZnNldCA9IGRhdGUuZ2V0VGltZXpvbmVPZmZzZXQoKTsKICBpZiAodGltZXpvbmUpIHsKICAgIGRhdGVUaW1lem9uZU9mZnNldCA9IHRpbWV6b25lVG9PZmZzZXQodGltZXpvbmUsIGRhdGVUaW1lem9uZU9mZnNldCk7CiAgICBkYXRlID0gY29udmVydFRpbWV6b25lVG9Mb2NhbChkYXRlLCB0aW1lem9uZSwgdHJ1ZSk7CiAgfQogIGxldCB0ZXh0ID0gIiI7CiAgcGFydHMuZm9yRWFjaCgodmFsdWUyKSA9PiB7CiAgICBjb25zdCBkYXRlRm9ybWF0dGVyID0gZ2V0RGF0ZUZvcm1hdHRlcih2YWx1ZTIpOwogICAgdGV4dCArPSBkYXRlRm9ybWF0dGVyID8gZGF0ZUZvcm1hdHRlcihkYXRlLCBsb2NhbGUsIGRhdGVUaW1lem9uZU9mZnNldCkgOiB2YWx1ZTIgPT09ICInJyIgPyAiJyIgOiB2YWx1ZTIucmVwbGFjZSgvKF4nfCckKS9nLCAiIikucmVwbGFjZSgvJycvZywgIiciKTsKICB9KTsKICByZXR1cm4gdGV4dDsKfQpmdW5jdGlvbiBjcmVhdGVEYXRlKHllYXIsIG1vbnRoLCBkYXRlKSB7CiAgY29uc3QgbmV3RGF0ZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgRGF0ZSgwKTsKICBuZXdEYXRlLnNldEZ1bGxZZWFyKHllYXIsIG1vbnRoLCBkYXRlKTsKICBuZXdEYXRlLnNldEhvdXJzKDAsIDAsIDApOwogIHJldHVybiBuZXdEYXRlOwp9CmZ1bmN0aW9uIGdldE5hbWVkRm9ybWF0KGxvY2FsZSwgZm9ybWF0KSB7CiAgY29uc3QgbG9jYWxlSWQgPSBnZXRMb2NhbGVJZChsb2NhbGUpOwogIE5BTUVEX0ZPUk1BVFNbbG9jYWxlSWRdID8/PSB7fTsKICBpZiAoTkFNRURfRk9STUFUU1tsb2NhbGVJZF1bZm9ybWF0XSkgewogICAgcmV0dXJuIE5BTUVEX0ZPUk1BVFNbbG9jYWxlSWRdW2Zvcm1hdF07CiAgfQogIGxldCBmb3JtYXRWYWx1ZSA9ICIiOwogIHN3aXRjaCAoZm9ybWF0KSB7CiAgICBjYXNlICJzaG9ydERhdGUiOgogICAgICBmb3JtYXRWYWx1ZSA9IGdldExvY2FsZURhdGVGb3JtYXQobG9jYWxlLCBGb3JtYXRXaWR0aC5TaG9ydCk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAibWVkaXVtRGF0ZSI6CiAgICAgIGZvcm1hdFZhbHVlID0gZ2V0TG9jYWxlRGF0ZUZvcm1hdChsb2NhbGUsIEZvcm1hdFdpZHRoLk1lZGl1bSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAibG9uZ0RhdGUiOgogICAgICBmb3JtYXRWYWx1ZSA9IGdldExvY2FsZURhdGVGb3JtYXQobG9jYWxlLCBGb3JtYXRXaWR0aC5Mb25nKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJmdWxsRGF0ZSI6CiAgICAgIGZvcm1hdFZhbHVlID0gZ2V0TG9jYWxlRGF0ZUZvcm1hdChsb2NhbGUsIEZvcm1hdFdpZHRoLkZ1bGwpOwogICAgICBicmVhazsKICAgIGNhc2UgInNob3J0VGltZSI6CiAgICAgIGZvcm1hdFZhbHVlID0gZ2V0TG9jYWxlVGltZUZvcm1hdChsb2NhbGUsIEZvcm1hdFdpZHRoLlNob3J0KTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJtZWRpdW1UaW1lIjoKICAgICAgZm9ybWF0VmFsdWUgPSBnZXRMb2NhbGVUaW1lRm9ybWF0KGxvY2FsZSwgRm9ybWF0V2lkdGguTWVkaXVtKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJsb25nVGltZSI6CiAgICAgIGZvcm1hdFZhbHVlID0gZ2V0TG9jYWxlVGltZUZvcm1hdChsb2NhbGUsIEZvcm1hdFdpZHRoLkxvbmcpOwogICAgICBicmVhazsKICAgIGNhc2UgImZ1bGxUaW1lIjoKICAgICAgZm9ybWF0VmFsdWUgPSBnZXRMb2NhbGVUaW1lRm9ybWF0KGxvY2FsZSwgRm9ybWF0V2lkdGguRnVsbCk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAic2hvcnQiOgogICAgICBjb25zdCBzaG9ydFRpbWUgPSBnZXROYW1lZEZvcm1hdChsb2NhbGUsICJzaG9ydFRpbWUiKTsKICAgICAgY29uc3Qgc2hvcnREYXRlID0gZ2V0TmFtZWRGb3JtYXQobG9jYWxlLCAic2hvcnREYXRlIik7CiAgICAgIGZvcm1hdFZhbHVlID0gZm9ybWF0RGF0ZVRpbWUoZ2V0TG9jYWxlRGF0ZVRpbWVGb3JtYXQobG9jYWxlLCBGb3JtYXRXaWR0aC5TaG9ydCksIFtzaG9ydFRpbWUsIHNob3J0RGF0ZV0pOwogICAgICBicmVhazsKICAgIGNhc2UgIm1lZGl1bSI6CiAgICAgIGNvbnN0IG1lZGl1bVRpbWUgPSBnZXROYW1lZEZvcm1hdChsb2NhbGUsICJtZWRpdW1UaW1lIik7CiAgICAgIGNvbnN0IG1lZGl1bURhdGUgPSBnZXROYW1lZEZvcm1hdChsb2NhbGUsICJtZWRpdW1EYXRlIik7CiAgICAgIGZvcm1hdFZhbHVlID0gZm9ybWF0RGF0ZVRpbWUoZ2V0TG9jYWxlRGF0ZVRpbWVGb3JtYXQobG9jYWxlLCBGb3JtYXRXaWR0aC5NZWRpdW0pLCBbbWVkaXVtVGltZSwgbWVkaXVtRGF0ZV0pOwogICAgICBicmVhazsKICAgIGNhc2UgImxvbmciOgogICAgICBjb25zdCBsb25nVGltZSA9IGdldE5hbWVkRm9ybWF0KGxvY2FsZSwgImxvbmdUaW1lIik7CiAgICAgIGNvbnN0IGxvbmdEYXRlID0gZ2V0TmFtZWRGb3JtYXQobG9jYWxlLCAibG9uZ0RhdGUiKTsKICAgICAgZm9ybWF0VmFsdWUgPSBmb3JtYXREYXRlVGltZShnZXRMb2NhbGVEYXRlVGltZUZvcm1hdChsb2NhbGUsIEZvcm1hdFdpZHRoLkxvbmcpLCBbbG9uZ1RpbWUsIGxvbmdEYXRlXSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiZnVsbCI6CiAgICAgIGNvbnN0IGZ1bGxUaW1lID0gZ2V0TmFtZWRGb3JtYXQobG9jYWxlLCAiZnVsbFRpbWUiKTsKICAgICAgY29uc3QgZnVsbERhdGUgPSBnZXROYW1lZEZvcm1hdChsb2NhbGUsICJmdWxsRGF0ZSIpOwogICAgICBmb3JtYXRWYWx1ZSA9IGZvcm1hdERhdGVUaW1lKGdldExvY2FsZURhdGVUaW1lRm9ybWF0KGxvY2FsZSwgRm9ybWF0V2lkdGguRnVsbCksIFtmdWxsVGltZSwgZnVsbERhdGVdKTsKICAgICAgYnJlYWs7CiAgfQogIGlmIChmb3JtYXRWYWx1ZSkgewogICAgTkFNRURfRk9STUFUU1tsb2NhbGVJZF1bZm9ybWF0XSA9IGZvcm1hdFZhbHVlOwogIH0KICByZXR1cm4gZm9ybWF0VmFsdWU7Cn0KZnVuY3Rpb24gZm9ybWF0RGF0ZVRpbWUoc3RyLCBvcHRfdmFsdWVzKSB7CiAgaWYgKG9wdF92YWx1ZXMpIHsKICAgIHN0ciA9IHN0ci5yZXBsYWNlKC9ceyhbXn1dKyl9L2csIGZ1bmN0aW9uKG1hdGNoLCBrZXkpIHsKICAgICAgcmV0dXJuIG9wdF92YWx1ZXMgIT0gbnVsbCAmJiBrZXkgaW4gb3B0X3ZhbHVlcyA/IG9wdF92YWx1ZXNba2V5XSA6IG1hdGNoOwogICAgfSk7CiAgfQogIHJldHVybiBzdHI7Cn0KZnVuY3Rpb24gcGFkTnVtYmVyKG51bSwgZGlnaXRzLCBtaW51c1NpZ24gPSAiLSIsIHRyaW0sIG5lZ1dyYXApIHsKICBsZXQgbmVnID0gIiI7CiAgaWYgKG51bSA8IDAgfHwgbmVnV3JhcCAmJiBudW0gPD0gMCkgewogICAgaWYgKG5lZ1dyYXApIHsKICAgICAgbnVtID0gLW51bSArIDE7CiAgICB9IGVsc2UgewogICAgICBudW0gPSAtbnVtOwogICAgICBuZWcgPSBtaW51c1NpZ247CiAgICB9CiAgfQogIGxldCBzdHJOdW0gPSBTdHJpbmcobnVtKTsKICB3aGlsZSAoc3RyTnVtLmxlbmd0aCA8IGRpZ2l0cykgewogICAgc3RyTnVtID0gIjAiICsgc3RyTnVtOwogIH0KICBpZiAodHJpbSkgewogICAgc3RyTnVtID0gc3RyTnVtLnNsaWNlKHN0ck51bS5sZW5ndGggLSBkaWdpdHMpOwogIH0KICByZXR1cm4gbmVnICsgc3RyTnVtOwp9CmZ1bmN0aW9uIGZvcm1hdEZyYWN0aW9uYWxTZWNvbmRzKG1pbGxpc2Vjb25kcywgZGlnaXRzKSB7CiAgY29uc3Qgc3RyTXMgPSBwYWROdW1iZXIobWlsbGlzZWNvbmRzLCAzKTsKICByZXR1cm4gc3RyTXMuc3Vic3RyaW5nKDAsIGRpZ2l0cyk7Cn0KZnVuY3Rpb24gZGF0ZUdldHRlcihuYW1lLCBzaXplLCBvZmZzZXQgPSAwLCB0cmltID0gZmFsc2UsIG5lZ1dyYXAgPSBmYWxzZSkgewogIHJldHVybiBmdW5jdGlvbihkYXRlLCBsb2NhbGUpIHsKICAgIGxldCBwYXJ0ID0gZ2V0RGF0ZVBhcnQobmFtZSwgZGF0ZSk7CiAgICBpZiAob2Zmc2V0ID4gMCB8fCBwYXJ0ID4gLW9mZnNldCkgewogICAgICBwYXJ0ICs9IG9mZnNldDsKICAgIH0KICAgIGlmIChuYW1lID09PSBEYXRlVHlwZS5Ib3VycykgewogICAgICBpZiAocGFydCA9PT0gMCAmJiBvZmZzZXQgPT09IC0xMikgewogICAgICAgIHBhcnQgPSAxMjsKICAgICAgfQogICAgfSBlbHNlIGlmIChuYW1lID09PSBEYXRlVHlwZS5GcmFjdGlvbmFsU2Vjb25kcykgewogICAgICByZXR1cm4gZm9ybWF0RnJhY3Rpb25hbFNlY29uZHMocGFydCwgc2l6ZSk7CiAgICB9CiAgICBjb25zdCBsb2NhbGVNaW51cyA9IGdldExvY2FsZU51bWJlclN5bWJvbChsb2NhbGUsIE51bWJlclN5bWJvbC5NaW51c1NpZ24pOwogICAgcmV0dXJuIHBhZE51bWJlcihwYXJ0LCBzaXplLCBsb2NhbGVNaW51cywgdHJpbSwgbmVnV3JhcCk7CiAgfTsKfQpmdW5jdGlvbiBnZXREYXRlUGFydChwYXJ0LCBkYXRlKSB7CiAgc3dpdGNoIChwYXJ0KSB7CiAgICBjYXNlIERhdGVUeXBlLkZ1bGxZZWFyOgogICAgICByZXR1cm4gZGF0ZS5nZXRGdWxsWWVhcigpOwogICAgY2FzZSBEYXRlVHlwZS5Nb250aDoKICAgICAgcmV0dXJuIGRhdGUuZ2V0TW9udGgoKTsKICAgIGNhc2UgRGF0ZVR5cGUuRGF0ZToKICAgICAgcmV0dXJuIGRhdGUuZ2V0RGF0ZSgpOwogICAgY2FzZSBEYXRlVHlwZS5Ib3VyczoKICAgICAgcmV0dXJuIGRhdGUuZ2V0SG91cnMoKTsKICAgIGNhc2UgRGF0ZVR5cGUuTWludXRlczoKICAgICAgcmV0dXJuIGRhdGUuZ2V0TWludXRlcygpOwogICAgY2FzZSBEYXRlVHlwZS5TZWNvbmRzOgogICAgICByZXR1cm4gZGF0ZS5nZXRTZWNvbmRzKCk7CiAgICBjYXNlIERhdGVUeXBlLkZyYWN0aW9uYWxTZWNvbmRzOgogICAgICByZXR1cm4gZGF0ZS5nZXRNaWxsaXNlY29uZHMoKTsKICAgIGNhc2UgRGF0ZVR5cGUuRGF5OgogICAgICByZXR1cm4gZGF0ZS5nZXREYXkoKTsKICAgIGRlZmF1bHQ6CiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBEYXRlVHlwZSB2YWx1ZSAiJHtwYXJ0fSIuYCk7CiAgfQp9CmZ1bmN0aW9uIGRhdGVTdHJHZXR0ZXIobmFtZSwgd2lkdGgsIGZvcm0gPSBGb3JtU3R5bGUuRm9ybWF0LCBleHRlbmRlZCA9IGZhbHNlKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGRhdGUsIGxvY2FsZSkgewogICAgcmV0dXJuIGdldERhdGVUcmFuc2xhdGlvbihkYXRlLCBsb2NhbGUsIG5hbWUsIHdpZHRoLCBmb3JtLCBleHRlbmRlZCk7CiAgfTsKfQpmdW5jdGlvbiBnZXREYXRlVHJhbnNsYXRpb24oZGF0ZSwgbG9jYWxlLCBuYW1lLCB3aWR0aCwgZm9ybSwgZXh0ZW5kZWQpIHsKICBzd2l0Y2ggKG5hbWUpIHsKICAgIGNhc2UgVHJhbnNsYXRpb25UeXBlLk1vbnRoczoKICAgICAgcmV0dXJuIGdldExvY2FsZU1vbnRoTmFtZXMobG9jYWxlLCBmb3JtLCB3aWR0aClbZGF0ZS5nZXRNb250aCgpXTsKICAgIGNhc2UgVHJhbnNsYXRpb25UeXBlLkRheXM6CiAgICAgIHJldHVybiBnZXRMb2NhbGVEYXlOYW1lcyhsb2NhbGUsIGZvcm0sIHdpZHRoKVtkYXRlLmdldERheSgpXTsKICAgIGNhc2UgVHJhbnNsYXRpb25UeXBlLkRheVBlcmlvZHM6CiAgICAgIGNvbnN0IGN1cnJlbnRIb3VycyA9IGRhdGUuZ2V0SG91cnMoKTsKICAgICAgY29uc3QgY3VycmVudE1pbnV0ZXMgPSBkYXRlLmdldE1pbnV0ZXMoKTsKICAgICAgaWYgKGV4dGVuZGVkKSB7CiAgICAgICAgY29uc3QgcnVsZXMgPSBnZXRMb2NhbGVFeHRyYURheVBlcmlvZFJ1bGVzKGxvY2FsZSk7CiAgICAgICAgY29uc3QgZGF5UGVyaW9kcyA9IGdldExvY2FsZUV4dHJhRGF5UGVyaW9kcyhsb2NhbGUsIGZvcm0sIHdpZHRoKTsKICAgICAgICBjb25zdCBpbmRleCA9IHJ1bGVzLmZpbmRJbmRleCgocnVsZSkgPT4gewogICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocnVsZSkpIHsKICAgICAgICAgICAgY29uc3QgW2Zyb20yLCB0b10gPSBydWxlOwogICAgICAgICAgICBjb25zdCBhZnRlckZyb20gPSBjdXJyZW50SG91cnMgPj0gZnJvbTIuaG91cnMgJiYgY3VycmVudE1pbnV0ZXMgPj0gZnJvbTIubWludXRlczsKICAgICAgICAgICAgY29uc3QgYmVmb3JlVG8gPSBjdXJyZW50SG91cnMgPCB0by5ob3VycyB8fCBjdXJyZW50SG91cnMgPT09IHRvLmhvdXJzICYmIGN1cnJlbnRNaW51dGVzIDwgdG8ubWludXRlczsKICAgICAgICAgICAgaWYgKGZyb20yLmhvdXJzIDwgdG8uaG91cnMpIHsKICAgICAgICAgICAgICBpZiAoYWZ0ZXJGcm9tICYmIGJlZm9yZVRvKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAoYWZ0ZXJGcm9tIHx8IGJlZm9yZVRvKSB7CiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChydWxlLmhvdXJzID09PSBjdXJyZW50SG91cnMgJiYgcnVsZS5taW51dGVzID09PSBjdXJyZW50TWludXRlcykgewogICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgfSk7CiAgICAgICAgaWYgKGluZGV4ICE9PSAtMSkgewogICAgICAgICAgcmV0dXJuIGRheVBlcmlvZHNbaW5kZXhdOwogICAgICAgIH0KICAgICAgfQogICAgICByZXR1cm4gZ2V0TG9jYWxlRGF5UGVyaW9kcyhsb2NhbGUsIGZvcm0sIHdpZHRoKVtjdXJyZW50SG91cnMgPCAxMiA/IDAgOiAxXTsKICAgIGNhc2UgVHJhbnNsYXRpb25UeXBlLkVyYXM6CiAgICAgIHJldHVybiBnZXRMb2NhbGVFcmFOYW1lcyhsb2NhbGUsIHdpZHRoKVtkYXRlLmdldEZ1bGxZZWFyKCkgPD0gMCA/IDAgOiAxXTsKICAgIGRlZmF1bHQ6CiAgICAgIGNvbnN0IHVuZXhwZWN0ZWQgPSBuYW1lOwogICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuZXhwZWN0ZWQgdHJhbnNsYXRpb24gdHlwZSAke3VuZXhwZWN0ZWR9YCk7CiAgfQp9CmZ1bmN0aW9uIHRpbWVab25lR2V0dGVyKHdpZHRoKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGRhdGUsIGxvY2FsZSwgb2Zmc2V0KSB7CiAgICBjb25zdCB6b25lID0gLTEgKiBvZmZzZXQ7CiAgICBjb25zdCBtaW51c1NpZ24gPSBnZXRMb2NhbGVOdW1iZXJTeW1ib2wobG9jYWxlLCBOdW1iZXJTeW1ib2wuTWludXNTaWduKTsKICAgIGNvbnN0IGhvdXJzID0gem9uZSA+IDAgPyBNYXRoLmZsb29yKHpvbmUgLyA2MCkgOiBNYXRoLmNlaWwoem9uZSAvIDYwKTsKICAgIHN3aXRjaCAod2lkdGgpIHsKICAgICAgY2FzZSBab25lV2lkdGguU2hvcnQ6CiAgICAgICAgcmV0dXJuICh6b25lID49IDAgPyAiKyIgOiAiIikgKyBwYWROdW1iZXIoaG91cnMsIDIsIG1pbnVzU2lnbikgKyBwYWROdW1iZXIoTWF0aC5hYnMoem9uZSAlIDYwKSwgMiwgbWludXNTaWduKTsKICAgICAgY2FzZSBab25lV2lkdGguU2hvcnRHTVQ6CiAgICAgICAgcmV0dXJuICJHTVQiICsgKHpvbmUgPj0gMCA/ICIrIiA6ICIiKSArIHBhZE51bWJlcihob3VycywgMSwgbWludXNTaWduKTsKICAgICAgY2FzZSBab25lV2lkdGguTG9uZzoKICAgICAgICByZXR1cm4gIkdNVCIgKyAoem9uZSA+PSAwID8gIisiIDogIiIpICsgcGFkTnVtYmVyKGhvdXJzLCAyLCBtaW51c1NpZ24pICsgIjoiICsgcGFkTnVtYmVyKE1hdGguYWJzKHpvbmUgJSA2MCksIDIsIG1pbnVzU2lnbik7CiAgICAgIGNhc2UgWm9uZVdpZHRoLkV4dGVuZGVkOgogICAgICAgIGlmIChvZmZzZXQgPT09IDApIHsKICAgICAgICAgIHJldHVybiAiWiI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiAoem9uZSA+PSAwID8gIisiIDogIiIpICsgcGFkTnVtYmVyKGhvdXJzLCAyLCBtaW51c1NpZ24pICsgIjoiICsgcGFkTnVtYmVyKE1hdGguYWJzKHpvbmUgJSA2MCksIDIsIG1pbnVzU2lnbik7CiAgICAgICAgfQogICAgICBkZWZhdWx0OgogICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB6b25lIHdpZHRoICIke3dpZHRofSJgKTsKICAgIH0KICB9Owp9CnZhciBKQU5VQVJZID0gMDsKdmFyIFRIVVJTREFZID0gNDsKZnVuY3Rpb24gZ2V0Rmlyc3RUaHVyc2RheU9mWWVhcih5ZWFyKSB7CiAgY29uc3QgZmlyc3REYXlPZlllYXIgPSBjcmVhdGVEYXRlKHllYXIsIEpBTlVBUlksIDEpLmdldERheSgpOwogIHJldHVybiBjcmVhdGVEYXRlKHllYXIsIDAsIDEgKyAoZmlyc3REYXlPZlllYXIgPD0gVEhVUlNEQVkgPyBUSFVSU0RBWSA6IFRIVVJTREFZICsgNykgLSBmaXJzdERheU9mWWVhcik7Cn0KZnVuY3Rpb24gZ2V0VGh1cnNkYXlUaGlzSXNvV2VlayhkYXRldGltZSkgewogIGNvbnN0IGN1cnJlbnREYXkgPSBkYXRldGltZS5nZXREYXkoKTsKICBjb25zdCBkZWx0YVRvVGh1cnNkYXkgPSBjdXJyZW50RGF5ID09PSAwID8gLTMgOiBUSFVSU0RBWSAtIGN1cnJlbnREYXk7CiAgcmV0dXJuIGNyZWF0ZURhdGUoZGF0ZXRpbWUuZ2V0RnVsbFllYXIoKSwgZGF0ZXRpbWUuZ2V0TW9udGgoKSwgZGF0ZXRpbWUuZ2V0RGF0ZSgpICsgZGVsdGFUb1RodXJzZGF5KTsKfQpmdW5jdGlvbiB3ZWVrR2V0dGVyKHNpemUsIG1vbnRoQmFzZWQgPSBmYWxzZSkgewogIHJldHVybiBmdW5jdGlvbihkYXRlLCBsb2NhbGUpIHsKICAgIGxldCByZXN1bHQ7CiAgICBpZiAobW9udGhCYXNlZCkgewogICAgICBjb25zdCBuYkRheXNCZWZvcmUxc3REYXlPZk1vbnRoID0gbmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCksIDEpLmdldERheSgpIC0gMTsKICAgICAgY29uc3QgdG9kYXkgPSBkYXRlLmdldERhdGUoKTsKICAgICAgcmVzdWx0ID0gMSArIE1hdGguZmxvb3IoKHRvZGF5ICsgbmJEYXlzQmVmb3JlMXN0RGF5T2ZNb250aCkgLyA3KTsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IHRoaXNUaHVycyA9IGdldFRodXJzZGF5VGhpc0lzb1dlZWsoZGF0ZSk7CiAgICAgIGNvbnN0IGZpcnN0VGh1cnMgPSBnZXRGaXJzdFRodXJzZGF5T2ZZZWFyKHRoaXNUaHVycy5nZXRGdWxsWWVhcigpKTsKICAgICAgY29uc3QgZGlmZiA9IHRoaXNUaHVycy5nZXRUaW1lKCkgLSBmaXJzdFRodXJzLmdldFRpbWUoKTsKICAgICAgcmVzdWx0ID0gMSArIE1hdGgucm91bmQoZGlmZiAvIDYwNDhlNSk7CiAgICB9CiAgICByZXR1cm4gcGFkTnVtYmVyKHJlc3VsdCwgc2l6ZSwgZ2V0TG9jYWxlTnVtYmVyU3ltYm9sKGxvY2FsZSwgTnVtYmVyU3ltYm9sLk1pbnVzU2lnbikpOwogIH07Cn0KZnVuY3Rpb24gd2Vla051bWJlcmluZ1llYXJHZXR0ZXIoc2l6ZSwgdHJpbSA9IGZhbHNlKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGRhdGUsIGxvY2FsZSkgewogICAgY29uc3QgdGhpc1RodXJzID0gZ2V0VGh1cnNkYXlUaGlzSXNvV2VlayhkYXRlKTsKICAgIGNvbnN0IHdlZWtOdW1iZXJpbmdZZWFyID0gdGhpc1RodXJzLmdldEZ1bGxZZWFyKCk7CiAgICByZXR1cm4gcGFkTnVtYmVyKHdlZWtOdW1iZXJpbmdZZWFyLCBzaXplLCBnZXRMb2NhbGVOdW1iZXJTeW1ib2wobG9jYWxlLCBOdW1iZXJTeW1ib2wuTWludXNTaWduKSwgdHJpbSk7CiAgfTsKfQp2YXIgREFURV9GT1JNQVRTID0ge307CmZ1bmN0aW9uIGdldERhdGVGb3JtYXR0ZXIoZm9ybWF0KSB7CiAgaWYgKERBVEVfRk9STUFUU1tmb3JtYXRdKSB7CiAgICByZXR1cm4gREFURV9GT1JNQVRTW2Zvcm1hdF07CiAgfQogIGxldCBmb3JtYXR0ZXI7CiAgc3dpdGNoIChmb3JtYXQpIHsKICAgIGNhc2UgIkciOgogICAgY2FzZSAiR0ciOgogICAgY2FzZSAiR0dHIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRXJhcywgVHJhbnNsYXRpb25XaWR0aC5BYmJyZXZpYXRlZCk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiR0dHRyI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkVyYXMsIFRyYW5zbGF0aW9uV2lkdGguV2lkZSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiR0dHR0ciOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5FcmFzLCBUcmFuc2xhdGlvbldpZHRoLk5hcnJvdyk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAieSI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRnVsbFllYXIsIDEsIDAsIGZhbHNlLCB0cnVlKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJ5eSI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRnVsbFllYXIsIDIsIDAsIHRydWUsIHRydWUpOwogICAgICBicmVhazsKICAgIGNhc2UgInl5eSI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRnVsbFllYXIsIDMsIDAsIGZhbHNlLCB0cnVlKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJ5eXl5IjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZUdldHRlcihEYXRlVHlwZS5GdWxsWWVhciwgNCwgMCwgZmFsc2UsIHRydWUpOwogICAgICBicmVhazsKICAgIGNhc2UgIlkiOgogICAgICBmb3JtYXR0ZXIgPSB3ZWVrTnVtYmVyaW5nWWVhckdldHRlcigxKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJZWSI6CiAgICAgIGZvcm1hdHRlciA9IHdlZWtOdW1iZXJpbmdZZWFyR2V0dGVyKDIsIHRydWUpOwogICAgICBicmVhazsKICAgIGNhc2UgIllZWSI6CiAgICAgIGZvcm1hdHRlciA9IHdlZWtOdW1iZXJpbmdZZWFyR2V0dGVyKDMpOwogICAgICBicmVhazsKICAgIGNhc2UgIllZWVkiOgogICAgICBmb3JtYXR0ZXIgPSB3ZWVrTnVtYmVyaW5nWWVhckdldHRlcig0KTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJNIjoKICAgIGNhc2UgIkwiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlR2V0dGVyKERhdGVUeXBlLk1vbnRoLCAxLCAxKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJNTSI6CiAgICBjYXNlICJMTCI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuTW9udGgsIDIsIDEpOwogICAgICBicmVhazsKICAgIGNhc2UgIk1NTSI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLk1vbnRocywgVHJhbnNsYXRpb25XaWR0aC5BYmJyZXZpYXRlZCk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiTU1NTSI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLk1vbnRocywgVHJhbnNsYXRpb25XaWR0aC5XaWRlKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJNTU1NTSI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLk1vbnRocywgVHJhbnNsYXRpb25XaWR0aC5OYXJyb3cpOwogICAgICBicmVhazsKICAgIGNhc2UgIkxMTCI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLk1vbnRocywgVHJhbnNsYXRpb25XaWR0aC5BYmJyZXZpYXRlZCwgRm9ybVN0eWxlLlN0YW5kYWxvbmUpOwogICAgICBicmVhazsKICAgIGNhc2UgIkxMTEwiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5Nb250aHMsIFRyYW5zbGF0aW9uV2lkdGguV2lkZSwgRm9ybVN0eWxlLlN0YW5kYWxvbmUpOwogICAgICBicmVhazsKICAgIGNhc2UgIkxMTExMIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuTW9udGhzLCBUcmFuc2xhdGlvbldpZHRoLk5hcnJvdywgRm9ybVN0eWxlLlN0YW5kYWxvbmUpOwogICAgICBicmVhazsKICAgIGNhc2UgInciOgogICAgICBmb3JtYXR0ZXIgPSB3ZWVrR2V0dGVyKDEpOwogICAgICBicmVhazsKICAgIGNhc2UgInd3IjoKICAgICAgZm9ybWF0dGVyID0gd2Vla0dldHRlcigyKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJXIjoKICAgICAgZm9ybWF0dGVyID0gd2Vla0dldHRlcigxLCB0cnVlKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJkIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZUdldHRlcihEYXRlVHlwZS5EYXRlLCAxKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJkZCI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRGF0ZSwgMik7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiYyI6CiAgICBjYXNlICJjYyI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRGF5LCAxKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJjY2MiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlzLCBUcmFuc2xhdGlvbldpZHRoLkFiYnJldmlhdGVkLCBGb3JtU3R5bGUuU3RhbmRhbG9uZSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiY2NjYyI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheXMsIFRyYW5zbGF0aW9uV2lkdGguV2lkZSwgRm9ybVN0eWxlLlN0YW5kYWxvbmUpOwogICAgICBicmVhazsKICAgIGNhc2UgImNjY2NjIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRGF5cywgVHJhbnNsYXRpb25XaWR0aC5OYXJyb3csIEZvcm1TdHlsZS5TdGFuZGFsb25lKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJjY2NjY2MiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlzLCBUcmFuc2xhdGlvbldpZHRoLlNob3J0LCBGb3JtU3R5bGUuU3RhbmRhbG9uZSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiRSI6CiAgICBjYXNlICJFRSI6CiAgICBjYXNlICJFRUUiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlzLCBUcmFuc2xhdGlvbldpZHRoLkFiYnJldmlhdGVkKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJFRUVFIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRGF5cywgVHJhbnNsYXRpb25XaWR0aC5XaWRlKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJFRUVFRSI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheXMsIFRyYW5zbGF0aW9uV2lkdGguTmFycm93KTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJFRUVFRUUiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlzLCBUcmFuc2xhdGlvbldpZHRoLlNob3J0KTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJhIjoKICAgIGNhc2UgImFhIjoKICAgIGNhc2UgImFhYSI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheVBlcmlvZHMsIFRyYW5zbGF0aW9uV2lkdGguQWJicmV2aWF0ZWQpOwogICAgICBicmVhazsKICAgIGNhc2UgImFhYWEiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlQZXJpb2RzLCBUcmFuc2xhdGlvbldpZHRoLldpZGUpOwogICAgICBicmVhazsKICAgIGNhc2UgImFhYWFhIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRGF5UGVyaW9kcywgVHJhbnNsYXRpb25XaWR0aC5OYXJyb3cpOwogICAgICBicmVhazsKICAgIGNhc2UgImIiOgogICAgY2FzZSAiYmIiOgogICAgY2FzZSAiYmJiIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRGF5UGVyaW9kcywgVHJhbnNsYXRpb25XaWR0aC5BYmJyZXZpYXRlZCwgRm9ybVN0eWxlLlN0YW5kYWxvbmUsIHRydWUpOwogICAgICBicmVhazsKICAgIGNhc2UgImJiYmIiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlQZXJpb2RzLCBUcmFuc2xhdGlvbldpZHRoLldpZGUsIEZvcm1TdHlsZS5TdGFuZGFsb25lLCB0cnVlKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJiYmJiYiI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheVBlcmlvZHMsIFRyYW5zbGF0aW9uV2lkdGguTmFycm93LCBGb3JtU3R5bGUuU3RhbmRhbG9uZSwgdHJ1ZSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiQiI6CiAgICBjYXNlICJCQiI6CiAgICBjYXNlICJCQkIiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlQZXJpb2RzLCBUcmFuc2xhdGlvbldpZHRoLkFiYnJldmlhdGVkLCBGb3JtU3R5bGUuRm9ybWF0LCB0cnVlKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJCQkJCIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRGF5UGVyaW9kcywgVHJhbnNsYXRpb25XaWR0aC5XaWRlLCBGb3JtU3R5bGUuRm9ybWF0LCB0cnVlKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJCQkJCQiI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheVBlcmlvZHMsIFRyYW5zbGF0aW9uV2lkdGguTmFycm93LCBGb3JtU3R5bGUuRm9ybWF0LCB0cnVlKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJoIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZUdldHRlcihEYXRlVHlwZS5Ib3VycywgMSwgLTEyKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJoaCI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuSG91cnMsIDIsIC0xMik7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiSCI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuSG91cnMsIDEpOwogICAgICBicmVhazsKICAgIGNhc2UgIkhIIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZUdldHRlcihEYXRlVHlwZS5Ib3VycywgMik7CiAgICAgIGJyZWFrOwogICAgY2FzZSAibSI6CiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuTWludXRlcywgMSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAibW0iOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlR2V0dGVyKERhdGVUeXBlLk1pbnV0ZXMsIDIpOwogICAgICBicmVhazsKICAgIGNhc2UgInMiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlR2V0dGVyKERhdGVUeXBlLlNlY29uZHMsIDEpOwogICAgICBicmVhazsKICAgIGNhc2UgInNzIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZUdldHRlcihEYXRlVHlwZS5TZWNvbmRzLCAyKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJTIjoKICAgICAgZm9ybWF0dGVyID0gZGF0ZUdldHRlcihEYXRlVHlwZS5GcmFjdGlvbmFsU2Vjb25kcywgMSk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiU1MiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlR2V0dGVyKERhdGVUeXBlLkZyYWN0aW9uYWxTZWNvbmRzLCAyKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJTU1MiOgogICAgICBmb3JtYXR0ZXIgPSBkYXRlR2V0dGVyKERhdGVUeXBlLkZyYWN0aW9uYWxTZWNvbmRzLCAzKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJaIjoKICAgIGNhc2UgIlpaIjoKICAgIGNhc2UgIlpaWiI6CiAgICAgIGZvcm1hdHRlciA9IHRpbWVab25lR2V0dGVyKFpvbmVXaWR0aC5TaG9ydCk7CiAgICAgIGJyZWFrOwogICAgY2FzZSAiWlpaWloiOgogICAgICBmb3JtYXR0ZXIgPSB0aW1lWm9uZUdldHRlcihab25lV2lkdGguRXh0ZW5kZWQpOwogICAgICBicmVhazsKICAgIGNhc2UgIk8iOgogICAgY2FzZSAiT08iOgogICAgY2FzZSAiT09PIjoKICAgIGNhc2UgInoiOgogICAgY2FzZSAienoiOgogICAgY2FzZSAienp6IjoKICAgICAgZm9ybWF0dGVyID0gdGltZVpvbmVHZXR0ZXIoWm9uZVdpZHRoLlNob3J0R01UKTsKICAgICAgYnJlYWs7CiAgICBjYXNlICJPT09PIjoKICAgIGNhc2UgIlpaWloiOgogICAgY2FzZSAienp6eiI6CiAgICAgIGZvcm1hdHRlciA9IHRpbWVab25lR2V0dGVyKFpvbmVXaWR0aC5Mb25nKTsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICByZXR1cm4gbnVsbDsKICB9CiAgREFURV9GT1JNQVRTW2Zvcm1hdF0gPSBmb3JtYXR0ZXI7CiAgcmV0dXJuIGZvcm1hdHRlcjsKfQpmdW5jdGlvbiB0aW1lem9uZVRvT2Zmc2V0KHRpbWV6b25lLCBmYWxsYmFjaykgewogIHRpbWV6b25lID0gdGltZXpvbmUucmVwbGFjZSgvOi9nLCAiIik7CiAgY29uc3QgcmVxdWVzdGVkVGltZXpvbmVPZmZzZXQgPSBEYXRlLnBhcnNlKCJKYW4gMDEsIDE5NzAgMDA6MDA6MDAgIiArIHRpbWV6b25lKSAvIDZlNDsKICByZXR1cm4gaXNOYU4ocmVxdWVzdGVkVGltZXpvbmVPZmZzZXQpID8gZmFsbGJhY2sgOiByZXF1ZXN0ZWRUaW1lem9uZU9mZnNldDsKfQpmdW5jdGlvbiBhZGREYXRlTWludXRlcyhkYXRlLCBtaW51dGVzKSB7CiAgZGF0ZSA9IG5ldyBEYXRlKGRhdGUuZ2V0VGltZSgpKTsKICBkYXRlLnNldE1pbnV0ZXMoZGF0ZS5nZXRNaW51dGVzKCkgKyBtaW51dGVzKTsKICByZXR1cm4gZGF0ZTsKfQpmdW5jdGlvbiBjb252ZXJ0VGltZXpvbmVUb0xvY2FsKGRhdGUsIHRpbWV6b25lLCByZXZlcnNlKSB7CiAgY29uc3QgcmV2ZXJzZVZhbHVlID0gcmV2ZXJzZSA/IC0xIDogMTsKICBjb25zdCBkYXRlVGltZXpvbmVPZmZzZXQgPSBkYXRlLmdldFRpbWV6b25lT2Zmc2V0KCk7CiAgY29uc3QgdGltZXpvbmVPZmZzZXQgPSB0aW1lem9uZVRvT2Zmc2V0KHRpbWV6b25lLCBkYXRlVGltZXpvbmVPZmZzZXQpOwogIHJldHVybiBhZGREYXRlTWludXRlcyhkYXRlLCByZXZlcnNlVmFsdWUgKiAodGltZXpvbmVPZmZzZXQgLSBkYXRlVGltZXpvbmVPZmZzZXQpKTsKfQpmdW5jdGlvbiB0b0RhdGUodmFsdWUpIHsKICBpZiAoaXNEYXRlKHZhbHVlKSkgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICBpZiAodHlwZW9mIHZhbHVlID09PSAibnVtYmVyIiAmJiAhaXNOYU4odmFsdWUpKSB7CiAgICByZXR1cm4gbmV3IERhdGUodmFsdWUpOwogIH0KICBpZiAodHlwZW9mIHZhbHVlID09PSAic3RyaW5nIikgewogICAgdmFsdWUgPSB2YWx1ZS50cmltKCk7CiAgICBpZiAoL14oXGR7NH0oLVxkezEsMn0oLVxkezEsMn0pPyk/KSQvLnRlc3QodmFsdWUpKSB7CiAgICAgIGNvbnN0IFt5LCBtID0gMSwgZCA9IDFdID0gdmFsdWUuc3BsaXQoIi0iKS5tYXAoKHZhbCkgPT4gK3ZhbCk7CiAgICAgIHJldHVybiBjcmVhdGVEYXRlKHksIG0gLSAxLCBkKTsKICAgIH0KICAgIGNvbnN0IHBhcnNlZE5iID0gcGFyc2VGbG9hdCh2YWx1ZSk7CiAgICBpZiAoIWlzTmFOKHZhbHVlIC0gcGFyc2VkTmIpKSB7CiAgICAgIHJldHVybiBuZXcgRGF0ZShwYXJzZWROYik7CiAgICB9CiAgICBsZXQgbWF0Y2g7CiAgICBpZiAobWF0Y2ggPSB2YWx1ZS5tYXRjaChJU084NjAxX0RBVEVfUkVHRVgpKSB7CiAgICAgIHJldHVybiBpc29TdHJpbmdUb0RhdGUobWF0Y2gpOwogICAgfQogIH0KICBjb25zdCBkYXRlID0gbmV3IERhdGUodmFsdWUpOwogIGlmICghaXNEYXRlKGRhdGUpKSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBjb252ZXJ0ICIke3ZhbHVlfSIgaW50byBhIGRhdGVgKTsKICB9CiAgcmV0dXJuIGRhdGU7Cn0KZnVuY3Rpb24gaXNvU3RyaW5nVG9EYXRlKG1hdGNoKSB7CiAgY29uc3QgZGF0ZSA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgRGF0ZSgwKTsKICBsZXQgdHpIb3VyID0gMDsKICBsZXQgdHpNaW4gPSAwOwogIGNvbnN0IGRhdGVTZXR0ZXIgPSBtYXRjaFs4XSA/IGRhdGUuc2V0VVRDRnVsbFllYXIgOiBkYXRlLnNldEZ1bGxZZWFyOwogIGNvbnN0IHRpbWVTZXR0ZXIgPSBtYXRjaFs4XSA/IGRhdGUuc2V0VVRDSG91cnMgOiBkYXRlLnNldEhvdXJzOwogIGlmIChtYXRjaFs5XSkgewogICAgdHpIb3VyID0gTnVtYmVyKG1hdGNoWzldICsgbWF0Y2hbMTBdKTsKICAgIHR6TWluID0gTnVtYmVyKG1hdGNoWzldICsgbWF0Y2hbMTFdKTsKICB9CiAgZGF0ZVNldHRlci5jYWxsKGRhdGUsIE51bWJlcihtYXRjaFsxXSksIE51bWJlcihtYXRjaFsyXSkgLSAxLCBOdW1iZXIobWF0Y2hbM10pKTsKICBjb25zdCBoID0gTnVtYmVyKG1hdGNoWzRdIHx8IDApIC0gdHpIb3VyOwogIGNvbnN0IG0gPSBOdW1iZXIobWF0Y2hbNV0gfHwgMCkgLSB0ek1pbjsKICBjb25zdCBzID0gTnVtYmVyKG1hdGNoWzZdIHx8IDApOwogIGNvbnN0IG1zID0gTWF0aC5mbG9vcihwYXJzZUZsb2F0KCIwLiIgKyAobWF0Y2hbN10gfHwgMCkpICogMWUzKTsKICB0aW1lU2V0dGVyLmNhbGwoZGF0ZSwgaCwgbSwgcywgbXMpOwogIHJldHVybiBkYXRlOwp9CmZ1bmN0aW9uIGlzRGF0ZSh2YWx1ZSkgewogIHJldHVybiB2YWx1ZSBpbnN0YW5jZW9mIERhdGUgJiYgIWlzTmFOKHZhbHVlLnZhbHVlT2YoKSk7Cn0KdmFyIE5VTUJFUl9GT1JNQVRfUkVHRVhQID0gL14oXGQrKT9cLigoXGQrKSgtKFxkKykpPyk/JC87CnZhciBNQVhfRElHSVRTID0gMjI7CnZhciBERUNJTUFMX1NFUCA9ICIuIjsKdmFyIFpFUk9fQ0hBUiA9ICIwIjsKdmFyIFBBVFRFUk5fU0VQID0gIjsiOwp2YXIgR1JPVVBfU0VQID0gIiwiOwp2YXIgRElHSVRfQ0hBUiA9ICIjIjsKdmFyIENVUlJFTkNZX0NIQVIgPSAiwqQiOwp2YXIgUEVSQ0VOVF9DSEFSID0gIiUiOwpmdW5jdGlvbiBmb3JtYXROdW1iZXJUb0xvY2FsZVN0cmluZyh2YWx1ZSwgcGF0dGVybiwgbG9jYWxlLCBncm91cFN5bWJvbCwgZGVjaW1hbFN5bWJvbCwgZGlnaXRzSW5mbywgaXNQZXJjZW50ID0gZmFsc2UpIHsKICBsZXQgZm9ybWF0dGVkVGV4dCA9ICIiOwogIGxldCBpc1plcm8gPSBmYWxzZTsKICBpZiAoIWlzRmluaXRlKHZhbHVlKSkgewogICAgZm9ybWF0dGVkVGV4dCA9IGdldExvY2FsZU51bWJlclN5bWJvbChsb2NhbGUsIE51bWJlclN5bWJvbC5JbmZpbml0eSk7CiAgfSBlbHNlIHsKICAgIGxldCBwYXJzZWROdW1iZXIgPSBwYXJzZU51bWJlcih2YWx1ZSk7CiAgICBpZiAoaXNQZXJjZW50KSB7CiAgICAgIHBhcnNlZE51bWJlciA9IHRvUGVyY2VudChwYXJzZWROdW1iZXIpOwogICAgfQogICAgbGV0IG1pbkludCA9IHBhdHRlcm4ubWluSW50OwogICAgbGV0IG1pbkZyYWN0aW9uID0gcGF0dGVybi5taW5GcmFjOwogICAgbGV0IG1heEZyYWN0aW9uID0gcGF0dGVybi5tYXhGcmFjOwogICAgaWYgKGRpZ2l0c0luZm8pIHsKICAgICAgY29uc3QgcGFydHMgPSBkaWdpdHNJbmZvLm1hdGNoKE5VTUJFUl9GT1JNQVRfUkVHRVhQKTsKICAgICAgaWYgKHBhcnRzID09PSBudWxsKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke2RpZ2l0c0luZm99IGlzIG5vdCBhIHZhbGlkIGRpZ2l0IGluZm9gKTsKICAgICAgfQogICAgICBjb25zdCBtaW5JbnRQYXJ0ID0gcGFydHNbMV07CiAgICAgIGNvbnN0IG1pbkZyYWN0aW9uUGFydCA9IHBhcnRzWzNdOwogICAgICBjb25zdCBtYXhGcmFjdGlvblBhcnQgPSBwYXJ0c1s1XTsKICAgICAgaWYgKG1pbkludFBhcnQgIT0gbnVsbCkgewogICAgICAgIG1pbkludCA9IHBhcnNlSW50QXV0b1JhZGl4KG1pbkludFBhcnQpOwogICAgICB9CiAgICAgIGlmIChtaW5GcmFjdGlvblBhcnQgIT0gbnVsbCkgewogICAgICAgIG1pbkZyYWN0aW9uID0gcGFyc2VJbnRBdXRvUmFkaXgobWluRnJhY3Rpb25QYXJ0KTsKICAgICAgfQogICAgICBpZiAobWF4RnJhY3Rpb25QYXJ0ICE9IG51bGwpIHsKICAgICAgICBtYXhGcmFjdGlvbiA9IHBhcnNlSW50QXV0b1JhZGl4KG1heEZyYWN0aW9uUGFydCk7CiAgICAgIH0gZWxzZSBpZiAobWluRnJhY3Rpb25QYXJ0ICE9IG51bGwgJiYgbWluRnJhY3Rpb24gPiBtYXhGcmFjdGlvbikgewogICAgICAgIG1heEZyYWN0aW9uID0gbWluRnJhY3Rpb247CiAgICAgIH0KICAgIH0KICAgIHJvdW5kTnVtYmVyKHBhcnNlZE51bWJlciwgbWluRnJhY3Rpb24sIG1heEZyYWN0aW9uKTsKICAgIGxldCBkaWdpdHMgPSBwYXJzZWROdW1iZXIuZGlnaXRzOwogICAgbGV0IGludGVnZXJMZW4gPSBwYXJzZWROdW1iZXIuaW50ZWdlckxlbjsKICAgIGNvbnN0IGV4cG9uZW50ID0gcGFyc2VkTnVtYmVyLmV4cG9uZW50OwogICAgbGV0IGRlY2ltYWxzID0gW107CiAgICBpc1plcm8gPSBkaWdpdHMuZXZlcnkoKGQpID0+ICFkKTsKICAgIGZvciAoOyBpbnRlZ2VyTGVuIDwgbWluSW50OyBpbnRlZ2VyTGVuKyspIHsKICAgICAgZGlnaXRzLnVuc2hpZnQoMCk7CiAgICB9CiAgICBmb3IgKDsgaW50ZWdlckxlbiA8IDA7IGludGVnZXJMZW4rKykgewogICAgICBkaWdpdHMudW5zaGlmdCgwKTsKICAgIH0KICAgIGlmIChpbnRlZ2VyTGVuID4gMCkgewogICAgICBkZWNpbWFscyA9IGRpZ2l0cy5zcGxpY2UoaW50ZWdlckxlbiwgZGlnaXRzLmxlbmd0aCk7CiAgICB9IGVsc2UgewogICAgICBkZWNpbWFscyA9IGRpZ2l0czsKICAgICAgZGlnaXRzID0gWzBdOwogICAgfQogICAgY29uc3QgZ3JvdXBzID0gW107CiAgICBpZiAoZGlnaXRzLmxlbmd0aCA+PSBwYXR0ZXJuLmxnU2l6ZSkgewogICAgICBncm91cHMudW5zaGlmdChkaWdpdHMuc3BsaWNlKC1wYXR0ZXJuLmxnU2l6ZSwgZGlnaXRzLmxlbmd0aCkuam9pbigiIikpOwogICAgfQogICAgd2hpbGUgKGRpZ2l0cy5sZW5ndGggPiBwYXR0ZXJuLmdTaXplKSB7CiAgICAgIGdyb3Vwcy51bnNoaWZ0KGRpZ2l0cy5zcGxpY2UoLXBhdHRlcm4uZ1NpemUsIGRpZ2l0cy5sZW5ndGgpLmpvaW4oIiIpKTsKICAgIH0KICAgIGlmIChkaWdpdHMubGVuZ3RoKSB7CiAgICAgIGdyb3Vwcy51bnNoaWZ0KGRpZ2l0cy5qb2luKCIiKSk7CiAgICB9CiAgICBmb3JtYXR0ZWRUZXh0ID0gZ3JvdXBzLmpvaW4oZ2V0TG9jYWxlTnVtYmVyU3ltYm9sKGxvY2FsZSwgZ3JvdXBTeW1ib2wpKTsKICAgIGlmIChkZWNpbWFscy5sZW5ndGgpIHsKICAgICAgZm9ybWF0dGVkVGV4dCArPSBnZXRMb2NhbGVOdW1iZXJTeW1ib2wobG9jYWxlLCBkZWNpbWFsU3ltYm9sKSArIGRlY2ltYWxzLmpvaW4oIiIpOwogICAgfQogICAgaWYgKGV4cG9uZW50KSB7CiAgICAgIGZvcm1hdHRlZFRleHQgKz0gZ2V0TG9jYWxlTnVtYmVyU3ltYm9sKGxvY2FsZSwgTnVtYmVyU3ltYm9sLkV4cG9uZW50aWFsKSArICIrIiArIGV4cG9uZW50OwogICAgfQogIH0KICBpZiAodmFsdWUgPCAwICYmICFpc1plcm8pIHsKICAgIGZvcm1hdHRlZFRleHQgPSBwYXR0ZXJuLm5lZ1ByZSArIGZvcm1hdHRlZFRleHQgKyBwYXR0ZXJuLm5lZ1N1ZjsKICB9IGVsc2UgewogICAgZm9ybWF0dGVkVGV4dCA9IHBhdHRlcm4ucG9zUHJlICsgZm9ybWF0dGVkVGV4dCArIHBhdHRlcm4ucG9zU3VmOwogIH0KICByZXR1cm4gZm9ybWF0dGVkVGV4dDsKfQpmdW5jdGlvbiBmb3JtYXRDdXJyZW5jeSh2YWx1ZSwgbG9jYWxlLCBjdXJyZW5jeSwgY3VycmVuY3lDb2RlLCBkaWdpdHNJbmZvKSB7CiAgY29uc3QgZm9ybWF0ID0gZ2V0TG9jYWxlTnVtYmVyRm9ybWF0KGxvY2FsZSwgTnVtYmVyRm9ybWF0U3R5bGUuQ3VycmVuY3kpOwogIGNvbnN0IHBhdHRlcm4gPSBwYXJzZU51bWJlckZvcm1hdChmb3JtYXQsIGdldExvY2FsZU51bWJlclN5bWJvbChsb2NhbGUsIE51bWJlclN5bWJvbC5NaW51c1NpZ24pKTsKICBwYXR0ZXJuLm1pbkZyYWMgPSBnZXROdW1iZXJPZkN1cnJlbmN5RGlnaXRzKGN1cnJlbmN5Q29kZSk7CiAgcGF0dGVybi5tYXhGcmFjID0gcGF0dGVybi5taW5GcmFjOwogIGNvbnN0IHJlcyA9IGZvcm1hdE51bWJlclRvTG9jYWxlU3RyaW5nKHZhbHVlLCBwYXR0ZXJuLCBsb2NhbGUsIE51bWJlclN5bWJvbC5DdXJyZW5jeUdyb3VwLCBOdW1iZXJTeW1ib2wuQ3VycmVuY3lEZWNpbWFsLCBkaWdpdHNJbmZvKTsKICByZXR1cm4gcmVzLnJlcGxhY2UoQ1VSUkVOQ1lfQ0hBUiwgY3VycmVuY3kpLnJlcGxhY2UoQ1VSUkVOQ1lfQ0hBUiwgIiIpLnRyaW0oKTsKfQpmdW5jdGlvbiBmb3JtYXRQZXJjZW50KHZhbHVlLCBsb2NhbGUsIGRpZ2l0c0luZm8pIHsKICBjb25zdCBmb3JtYXQgPSBnZXRMb2NhbGVOdW1iZXJGb3JtYXQobG9jYWxlLCBOdW1iZXJGb3JtYXRTdHlsZS5QZXJjZW50KTsKICBjb25zdCBwYXR0ZXJuID0gcGFyc2VOdW1iZXJGb3JtYXQoZm9ybWF0LCBnZXRMb2NhbGVOdW1iZXJTeW1ib2wobG9jYWxlLCBOdW1iZXJTeW1ib2wuTWludXNTaWduKSk7CiAgY29uc3QgcmVzID0gZm9ybWF0TnVtYmVyVG9Mb2NhbGVTdHJpbmcodmFsdWUsIHBhdHRlcm4sIGxvY2FsZSwgTnVtYmVyU3ltYm9sLkdyb3VwLCBOdW1iZXJTeW1ib2wuRGVjaW1hbCwgZGlnaXRzSW5mbywgdHJ1ZSk7CiAgcmV0dXJuIHJlcy5yZXBsYWNlKG5ldyBSZWdFeHAoUEVSQ0VOVF9DSEFSLCAiZyIpLCBnZXRMb2NhbGVOdW1iZXJTeW1ib2wobG9jYWxlLCBOdW1iZXJTeW1ib2wuUGVyY2VudFNpZ24pKTsKfQpmdW5jdGlvbiBmb3JtYXROdW1iZXIodmFsdWUsIGxvY2FsZSwgZGlnaXRzSW5mbykgewogIGNvbnN0IGZvcm1hdCA9IGdldExvY2FsZU51bWJlckZvcm1hdChsb2NhbGUsIE51bWJlckZvcm1hdFN0eWxlLkRlY2ltYWwpOwogIGNvbnN0IHBhdHRlcm4gPSBwYXJzZU51bWJlckZvcm1hdChmb3JtYXQsIGdldExvY2FsZU51bWJlclN5bWJvbChsb2NhbGUsIE51bWJlclN5bWJvbC5NaW51c1NpZ24pKTsKICByZXR1cm4gZm9ybWF0TnVtYmVyVG9Mb2NhbGVTdHJpbmcodmFsdWUsIHBhdHRlcm4sIGxvY2FsZSwgTnVtYmVyU3ltYm9sLkdyb3VwLCBOdW1iZXJTeW1ib2wuRGVjaW1hbCwgZGlnaXRzSW5mbyk7Cn0KZnVuY3Rpb24gcGFyc2VOdW1iZXJGb3JtYXQoZm9ybWF0LCBtaW51c1NpZ24gPSAiLSIpIHsKICBjb25zdCBwID0gewogICAgbWluSW50OiAxLAogICAgbWluRnJhYzogMCwKICAgIG1heEZyYWM6IDAsCiAgICBwb3NQcmU6ICIiLAogICAgcG9zU3VmOiAiIiwKICAgIG5lZ1ByZTogIiIsCiAgICBuZWdTdWY6ICIiLAogICAgZ1NpemU6IDAsCiAgICBsZ1NpemU6IDAKICB9OwogIGNvbnN0IHBhdHRlcm5QYXJ0cyA9IGZvcm1hdC5zcGxpdChQQVRURVJOX1NFUCk7CiAgY29uc3QgcG9zaXRpdmUgPSBwYXR0ZXJuUGFydHNbMF07CiAgY29uc3QgbmVnYXRpdmUgPSBwYXR0ZXJuUGFydHNbMV07CiAgY29uc3QgcG9zaXRpdmVQYXJ0cyA9IHBvc2l0aXZlLmluZGV4T2YoREVDSU1BTF9TRVApICE9PSAtMSA/IHBvc2l0aXZlLnNwbGl0KERFQ0lNQUxfU0VQKSA6IFtwb3NpdGl2ZS5zdWJzdHJpbmcoMCwgcG9zaXRpdmUubGFzdEluZGV4T2YoWkVST19DSEFSKSArIDEpLCBwb3NpdGl2ZS5zdWJzdHJpbmcocG9zaXRpdmUubGFzdEluZGV4T2YoWkVST19DSEFSKSArIDEpXSwgaW50ZWdlciA9IHBvc2l0aXZlUGFydHNbMF0sIGZyYWN0aW9uID0gcG9zaXRpdmVQYXJ0c1sxXSB8fCAiIjsKICBwLnBvc1ByZSA9IGludGVnZXIuc3Vic3RyaW5nKDAsIGludGVnZXIuaW5kZXhPZihESUdJVF9DSEFSKSk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCBmcmFjdGlvbi5sZW5ndGg7IGkrKykgewogICAgY29uc3QgY2ggPSBmcmFjdGlvbi5jaGFyQXQoaSk7CiAgICBpZiAoY2ggPT09IFpFUk9fQ0hBUikgewogICAgICBwLm1pbkZyYWMgPSBwLm1heEZyYWMgPSBpICsgMTsKICAgIH0gZWxzZSBpZiAoY2ggPT09IERJR0lUX0NIQVIpIHsKICAgICAgcC5tYXhGcmFjID0gaSArIDE7CiAgICB9IGVsc2UgewogICAgICBwLnBvc1N1ZiArPSBjaDsKICAgIH0KICB9CiAgY29uc3QgZ3JvdXBzID0gaW50ZWdlci5zcGxpdChHUk9VUF9TRVApOwogIHAuZ1NpemUgPSBncm91cHNbMV0gPyBncm91cHNbMV0ubGVuZ3RoIDogMDsKICBwLmxnU2l6ZSA9IGdyb3Vwc1syXSB8fCBncm91cHNbMV0gPyAoZ3JvdXBzWzJdIHx8IGdyb3Vwc1sxXSkubGVuZ3RoIDogMDsKICBpZiAobmVnYXRpdmUpIHsKICAgIGNvbnN0IHRydW5rTGVuID0gcG9zaXRpdmUubGVuZ3RoIC0gcC5wb3NQcmUubGVuZ3RoIC0gcC5wb3NTdWYubGVuZ3RoLCBwb3MgPSBuZWdhdGl2ZS5pbmRleE9mKERJR0lUX0NIQVIpOwogICAgcC5uZWdQcmUgPSBuZWdhdGl2ZS5zdWJzdHJpbmcoMCwgcG9zKS5yZXBsYWNlKC8nL2csICIiKTsKICAgIHAubmVnU3VmID0gbmVnYXRpdmUuc2xpY2UocG9zICsgdHJ1bmtMZW4pLnJlcGxhY2UoLycvZywgIiIpOwogIH0gZWxzZSB7CiAgICBwLm5lZ1ByZSA9IG1pbnVzU2lnbiArIHAucG9zUHJlOwogICAgcC5uZWdTdWYgPSBwLnBvc1N1ZjsKICB9CiAgcmV0dXJuIHA7Cn0KZnVuY3Rpb24gdG9QZXJjZW50KHBhcnNlZE51bWJlcikgewogIGlmIChwYXJzZWROdW1iZXIuZGlnaXRzWzBdID09PSAwKSB7CiAgICByZXR1cm4gcGFyc2VkTnVtYmVyOwogIH0KICBjb25zdCBmcmFjdGlvbkxlbiA9IHBhcnNlZE51bWJlci5kaWdpdHMubGVuZ3RoIC0gcGFyc2VkTnVtYmVyLmludGVnZXJMZW47CiAgaWYgKHBhcnNlZE51bWJlci5leHBvbmVudCkgewogICAgcGFyc2VkTnVtYmVyLmV4cG9uZW50ICs9IDI7CiAgfSBlbHNlIHsKICAgIGlmIChmcmFjdGlvbkxlbiA9PT0gMCkgewogICAgICBwYXJzZWROdW1iZXIuZGlnaXRzLnB1c2goMCwgMCk7CiAgICB9IGVsc2UgaWYgKGZyYWN0aW9uTGVuID09PSAxKSB7CiAgICAgIHBhcnNlZE51bWJlci5kaWdpdHMucHVzaCgwKTsKICAgIH0KICAgIHBhcnNlZE51bWJlci5pbnRlZ2VyTGVuICs9IDI7CiAgfQogIHJldHVybiBwYXJzZWROdW1iZXI7Cn0KZnVuY3Rpb24gcGFyc2VOdW1iZXIobnVtKSB7CiAgbGV0IG51bVN0ciA9IE1hdGguYWJzKG51bSkgKyAiIjsKICBsZXQgZXhwb25lbnQgPSAwLCBkaWdpdHMsIGludGVnZXJMZW47CiAgbGV0IGksIGosIHplcm9zOwogIGlmICgoaW50ZWdlckxlbiA9IG51bVN0ci5pbmRleE9mKERFQ0lNQUxfU0VQKSkgPiAtMSkgewogICAgbnVtU3RyID0gbnVtU3RyLnJlcGxhY2UoREVDSU1BTF9TRVAsICIiKTsKICB9CiAgaWYgKChpID0gbnVtU3RyLnNlYXJjaCgvZS9pKSkgPiAwKSB7CiAgICBpZiAoaW50ZWdlckxlbiA8IDApCiAgICAgIGludGVnZXJMZW4gPSBpOwogICAgaW50ZWdlckxlbiArPSArbnVtU3RyLnNsaWNlKGkgKyAxKTsKICAgIG51bVN0ciA9IG51bVN0ci5zdWJzdHJpbmcoMCwgaSk7CiAgfSBlbHNlIGlmIChpbnRlZ2VyTGVuIDwgMCkgewogICAgaW50ZWdlckxlbiA9IG51bVN0ci5sZW5ndGg7CiAgfQogIGZvciAoaSA9IDA7IG51bVN0ci5jaGFyQXQoaSkgPT09IFpFUk9fQ0hBUjsgaSsrKSB7CiAgfQogIGlmIChpID09PSAoemVyb3MgPSBudW1TdHIubGVuZ3RoKSkgewogICAgZGlnaXRzID0gWzBdOwogICAgaW50ZWdlckxlbiA9IDE7CiAgfSBlbHNlIHsKICAgIHplcm9zLS07CiAgICB3aGlsZSAobnVtU3RyLmNoYXJBdCh6ZXJvcykgPT09IFpFUk9fQ0hBUikKICAgICAgemVyb3MtLTsKICAgIGludGVnZXJMZW4gLT0gaTsKICAgIGRpZ2l0cyA9IFtdOwogICAgZm9yIChqID0gMDsgaSA8PSB6ZXJvczsgaSsrLCBqKyspIHsKICAgICAgZGlnaXRzW2pdID0gTnVtYmVyKG51bVN0ci5jaGFyQXQoaSkpOwogICAgfQogIH0KICBpZiAoaW50ZWdlckxlbiA+IE1BWF9ESUdJVFMpIHsKICAgIGRpZ2l0cyA9IGRpZ2l0cy5zcGxpY2UoMCwgTUFYX0RJR0lUUyAtIDEpOwogICAgZXhwb25lbnQgPSBpbnRlZ2VyTGVuIC0gMTsKICAgIGludGVnZXJMZW4gPSAxOwogIH0KICByZXR1cm4gewogICAgZGlnaXRzLAogICAgZXhwb25lbnQsCiAgICBpbnRlZ2VyTGVuCiAgfTsKfQpmdW5jdGlvbiByb3VuZE51bWJlcihwYXJzZWROdW1iZXIsIG1pbkZyYWMsIG1heEZyYWMpIHsKICBpZiAobWluRnJhYyA+IG1heEZyYWMpIHsKICAgIHRocm93IG5ldyBFcnJvcihgVGhlIG1pbmltdW0gbnVtYmVyIG9mIGRpZ2l0cyBhZnRlciBmcmFjdGlvbiAoJHttaW5GcmFjfSkgaXMgaGlnaGVyIHRoYW4gdGhlIG1heGltdW0gKCR7bWF4RnJhY30pLmApOwogIH0KICBsZXQgZGlnaXRzID0gcGFyc2VkTnVtYmVyLmRpZ2l0czsKICBsZXQgZnJhY3Rpb25MZW4gPSBkaWdpdHMubGVuZ3RoIC0gcGFyc2VkTnVtYmVyLmludGVnZXJMZW47CiAgY29uc3QgZnJhY3Rpb25TaXplID0gTWF0aC5taW4oTWF0aC5tYXgobWluRnJhYywgZnJhY3Rpb25MZW4pLCBtYXhGcmFjKTsKICBsZXQgcm91bmRBdCA9IGZyYWN0aW9uU2l6ZSArIHBhcnNlZE51bWJlci5pbnRlZ2VyTGVuOwogIGxldCBkaWdpdCA9IGRpZ2l0c1tyb3VuZEF0XTsKICBpZiAocm91bmRBdCA+IDApIHsKICAgIGRpZ2l0cy5zcGxpY2UoTWF0aC5tYXgocGFyc2VkTnVtYmVyLmludGVnZXJMZW4sIHJvdW5kQXQpKTsKICAgIGZvciAobGV0IGogPSByb3VuZEF0OyBqIDwgZGlnaXRzLmxlbmd0aDsgaisrKSB7CiAgICAgIGRpZ2l0c1tqXSA9IDA7CiAgICB9CiAgfSBlbHNlIHsKICAgIGZyYWN0aW9uTGVuID0gTWF0aC5tYXgoMCwgZnJhY3Rpb25MZW4pOwogICAgcGFyc2VkTnVtYmVyLmludGVnZXJMZW4gPSAxOwogICAgZGlnaXRzLmxlbmd0aCA9IE1hdGgubWF4KDEsIHJvdW5kQXQgPSBmcmFjdGlvblNpemUgKyAxKTsKICAgIGRpZ2l0c1swXSA9IDA7CiAgICBmb3IgKGxldCBpID0gMTsgaSA8IHJvdW5kQXQ7IGkrKykKICAgICAgZGlnaXRzW2ldID0gMDsKICB9CiAgaWYgKGRpZ2l0ID49IDUpIHsKICAgIGlmIChyb3VuZEF0IC0gMSA8IDApIHsKICAgICAgZm9yIChsZXQgayA9IDA7IGsgPiByb3VuZEF0OyBrLS0pIHsKICAgICAgICBkaWdpdHMudW5zaGlmdCgwKTsKICAgICAgICBwYXJzZWROdW1iZXIuaW50ZWdlckxlbisrOwogICAgICB9CiAgICAgIGRpZ2l0cy51bnNoaWZ0KDEpOwogICAgICBwYXJzZWROdW1iZXIuaW50ZWdlckxlbisrOwogICAgfSBlbHNlIHsKICAgICAgZGlnaXRzW3JvdW5kQXQgLSAxXSsrOwogICAgfQogIH0KICBmb3IgKDsgZnJhY3Rpb25MZW4gPCBNYXRoLm1heCgwLCBmcmFjdGlvblNpemUpOyBmcmFjdGlvbkxlbisrKQogICAgZGlnaXRzLnB1c2goMCk7CiAgbGV0IGRyb3BUcmFpbGluZ1plcm9zID0gZnJhY3Rpb25TaXplICE9PSAwOwogIGNvbnN0IG1pbkxlbiA9IG1pbkZyYWMgKyBwYXJzZWROdW1iZXIuaW50ZWdlckxlbjsKICBjb25zdCBjYXJyeSA9IGRpZ2l0cy5yZWR1Y2VSaWdodChmdW5jdGlvbihjYXJyeTIsIGQsIGksIGRpZ2l0czIpIHsKICAgIGQgPSBkICsgY2FycnkyOwogICAgZGlnaXRzMltpXSA9IGQgPCAxMCA/IGQgOiBkIC0gMTA7CiAgICBpZiAoZHJvcFRyYWlsaW5nWmVyb3MpIHsKICAgICAgaWYgKGRpZ2l0czJbaV0gPT09IDAgJiYgaSA+PSBtaW5MZW4pIHsKICAgICAgICBkaWdpdHMyLnBvcCgpOwogICAgICB9IGVsc2UgewogICAgICAgIGRyb3BUcmFpbGluZ1plcm9zID0gZmFsc2U7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBkID49IDEwID8gMSA6IDA7CiAgfSwgMCk7CiAgaWYgKGNhcnJ5KSB7CiAgICBkaWdpdHMudW5zaGlmdChjYXJyeSk7CiAgICBwYXJzZWROdW1iZXIuaW50ZWdlckxlbisrOwogIH0KfQpmdW5jdGlvbiBwYXJzZUludEF1dG9SYWRpeCh0ZXh0KSB7CiAgY29uc3QgcmVzdWx0ID0gcGFyc2VJbnQodGV4dCk7CiAgaWYgKGlzTmFOKHJlc3VsdCkpIHsKICAgIHRocm93IG5ldyBFcnJvcigiSW52YWxpZCBpbnRlZ2VyIGxpdGVyYWwgd2hlbiBwYXJzaW5nICIgKyB0ZXh0KTsKICB9CiAgcmV0dXJuIHJlc3VsdDsKfQp2YXIgX05nTG9jYWxpemF0aW9uID0gY2xhc3MgX05nTG9jYWxpemF0aW9uIHsKfTsKX05nTG9jYWxpemF0aW9uLsm1ZmFjID0gZnVuY3Rpb24gTmdMb2NhbGl6YXRpb25fRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTmdMb2NhbGl6YXRpb24pKCk7Cn07Cl9OZ0xvY2FsaXphdGlvbi7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7CiAgdG9rZW46IF9OZ0xvY2FsaXphdGlvbiwKICBmYWN0b3J5OiBmdW5jdGlvbiBOZ0xvY2FsaXphdGlvbl9GYWN0b3J5KHQpIHsKICAgIGxldCByID0gbnVsbDsKICAgIGlmICh0KSB7CiAgICAgIHIgPSBuZXcgdCgpOwogICAgfSBlbHNlIHsKICAgICAgciA9ICgobG9jYWxlKSA9PiBuZXcgTmdMb2NhbGVMb2NhbGl6YXRpb24obG9jYWxlKSkoybXJtWluamVjdChMT0NBTEVfSUQpKTsKICAgIH0KICAgIHJldHVybiByOwogIH0sCiAgcHJvdmlkZWRJbjogInJvb3QiCn0pOwp2YXIgTmdMb2NhbGl6YXRpb24gPSBfTmdMb2NhbGl6YXRpb247CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShOZ0xvY2FsaXphdGlvbiwgW3sKICAgIHR5cGU6IEluamVjdGFibGUsCiAgICBhcmdzOiBbewogICAgICBwcm92aWRlZEluOiAicm9vdCIsCiAgICAgIHVzZUZhY3Rvcnk6IChsb2NhbGUpID0+IG5ldyBOZ0xvY2FsZUxvY2FsaXphdGlvbihsb2NhbGUpLAogICAgICBkZXBzOiBbTE9DQUxFX0lEXQogICAgfV0KICB9XSwgbnVsbCwgbnVsbCk7Cn0pKCk7CmZ1bmN0aW9uIGdldFBsdXJhbENhdGVnb3J5KHZhbHVlLCBjYXNlcywgbmdMb2NhbGl6YXRpb24sIGxvY2FsZSkgewogIGxldCBrZXkgPSBgPSR7dmFsdWV9YDsKICBpZiAoY2FzZXMuaW5kZXhPZihrZXkpID4gLTEpIHsKICAgIHJldHVybiBrZXk7CiAgfQogIGtleSA9IG5nTG9jYWxpemF0aW9uLmdldFBsdXJhbENhdGVnb3J5KHZhbHVlLCBsb2NhbGUpOwogIGlmIChjYXNlcy5pbmRleE9mKGtleSkgPiAtMSkgewogICAgcmV0dXJuIGtleTsKICB9CiAgaWYgKGNhc2VzLmluZGV4T2YoIm90aGVyIikgPiAtMSkgewogICAgcmV0dXJuICJvdGhlciI7CiAgfQogIHRocm93IG5ldyBFcnJvcihgTm8gcGx1cmFsIG1lc3NhZ2UgZm91bmQgZm9yIHZhbHVlICIke3ZhbHVlfSJgKTsKfQp2YXIgX05nTG9jYWxlTG9jYWxpemF0aW9uID0gY2xhc3MgX05nTG9jYWxlTG9jYWxpemF0aW9uIGV4dGVuZHMgTmdMb2NhbGl6YXRpb24gewogIGNvbnN0cnVjdG9yKGxvY2FsZSkgewogICAgc3VwZXIoKTsKICAgIHRoaXMubG9jYWxlID0gbG9jYWxlOwogIH0KICBnZXRQbHVyYWxDYXRlZ29yeSh2YWx1ZSwgbG9jYWxlKSB7CiAgICBjb25zdCBwbHVyYWwgPSBnZXRMb2NhbGVQbHVyYWxDYXNlMihsb2NhbGUgfHwgdGhpcy5sb2NhbGUpKHZhbHVlKTsKICAgIHN3aXRjaCAocGx1cmFsKSB7CiAgICAgIGNhc2UgUGx1cmFsLlplcm86CiAgICAgICAgcmV0dXJuICJ6ZXJvIjsKICAgICAgY2FzZSBQbHVyYWwuT25lOgogICAgICAgIHJldHVybiAib25lIjsKICAgICAgY2FzZSBQbHVyYWwuVHdvOgogICAgICAgIHJldHVybiAidHdvIjsKICAgICAgY2FzZSBQbHVyYWwuRmV3OgogICAgICAgIHJldHVybiAiZmV3IjsKICAgICAgY2FzZSBQbHVyYWwuTWFueToKICAgICAgICByZXR1cm4gIm1hbnkiOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiAib3RoZXIiOwogICAgfQogIH0KfTsKX05nTG9jYWxlTG9jYWxpemF0aW9uLsm1ZmFjID0gZnVuY3Rpb24gTmdMb2NhbGVMb2NhbGl6YXRpb25fRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTmdMb2NhbGVMb2NhbGl6YXRpb24pKMm1ybVpbmplY3QoTE9DQUxFX0lEKSk7Cn07Cl9OZ0xvY2FsZUxvY2FsaXphdGlvbi7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7CiAgdG9rZW46IF9OZ0xvY2FsZUxvY2FsaXphdGlvbiwKICBmYWN0b3J5OiBfTmdMb2NhbGVMb2NhbGl6YXRpb24uybVmYWMKfSk7CnZhciBOZ0xvY2FsZUxvY2FsaXphdGlvbiA9IF9OZ0xvY2FsZUxvY2FsaXphdGlvbjsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKE5nTG9jYWxlTG9jYWxpemF0aW9uLCBbewogICAgdHlwZTogSW5qZWN0YWJsZQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogdm9pZCAwLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogSW5qZWN0LAogICAgICBhcmdzOiBbTE9DQUxFX0lEXQogICAgfV0KICB9XSwgbnVsbCk7Cn0pKCk7CmZ1bmN0aW9uIHBhcnNlQ29va2llVmFsdWUoY29va2llU3RyLCBuYW1lKSB7CiAgbmFtZSA9IGVuY29kZVVSSUNvbXBvbmVudChuYW1lKTsKICBmb3IgKGNvbnN0IGNvb2tpZSBvZiBjb29raWVTdHIuc3BsaXQoIjsiKSkgewogICAgY29uc3QgZXFJbmRleCA9IGNvb2tpZS5pbmRleE9mKCI9Iik7CiAgICBjb25zdCBbY29va2llTmFtZSwgY29va2llVmFsdWVdID0gZXFJbmRleCA9PSAtMSA/IFtjb29raWUsICIiXSA6IFtjb29raWUuc2xpY2UoMCwgZXFJbmRleCksIGNvb2tpZS5zbGljZShlcUluZGV4ICsgMSldOwogICAgaWYgKGNvb2tpZU5hbWUudHJpbSgpID09PSBuYW1lKSB7CiAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoY29va2llVmFsdWUpOwogICAgfQogIH0KICByZXR1cm4gbnVsbDsKfQp2YXIgV1NfUkVHRVhQID0gL1xzKy87CnZhciBFTVBUWV9BUlJBWSA9IFtdOwp2YXIgX05nQ2xhc3MgPSBjbGFzcyBfTmdDbGFzcyB7CiAgY29uc3RydWN0b3IoX25nRWwsIF9yZW5kZXJlcikgewogICAgdGhpcy5fbmdFbCA9IF9uZ0VsOwogICAgdGhpcy5fcmVuZGVyZXIgPSBfcmVuZGVyZXI7CiAgICB0aGlzLmluaXRpYWxDbGFzc2VzID0gRU1QVFlfQVJSQVk7CiAgICB0aGlzLnN0YXRlTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICB9CiAgc2V0IGtsYXNzKHZhbHVlKSB7CiAgICB0aGlzLmluaXRpYWxDbGFzc2VzID0gdmFsdWUgIT0gbnVsbCA/IHZhbHVlLnRyaW0oKS5zcGxpdChXU19SRUdFWFApIDogRU1QVFlfQVJSQVk7CiAgfQogIHNldCBuZ0NsYXNzKHZhbHVlKSB7CiAgICB0aGlzLnJhd0NsYXNzID0gdHlwZW9mIHZhbHVlID09PSAic3RyaW5nIiA/IHZhbHVlLnRyaW0oKS5zcGxpdChXU19SRUdFWFApIDogdmFsdWU7CiAgfQogIC8qCiAgVGhlIE5nQ2xhc3MgZGlyZWN0aXZlIHVzZXMgdGhlIGN1c3RvbSBjaGFuZ2UgZGV0ZWN0aW9uIGFsZ29yaXRobSBmb3IgaXRzIGlucHV0cy4gVGhlIGN1c3RvbQogIGFsZ29yaXRobSBpcyBuZWNlc3Nhcnkgc2luY2UgaW5wdXRzIGFyZSByZXByZXNlbnRlZCBhcyBjb21wbGV4IG9iamVjdCBvciBhcnJheXMgdGhhdCBuZWVkIHRvIGJlCiAgZGVlcGx5LWNvbXBhcmVkLgogICAgIFRoaXMgYWxnb3JpdGhtIGlzIHBlcmYtc2Vuc2l0aXZlIHNpbmNlIE5nQ2xhc3MgaXMgdXNlZCB2ZXJ5IGZyZXF1ZW50bHkgYW5kIGl0cyBwb29yIHBlcmZvcm1hbmNlCiAgbWlnaHQgbmVnYXRpdmVseSBpbXBhY3QgcnVudGltZSBwZXJmb3JtYW5jZSBvZiB0aGUgZW50aXJlIGNoYW5nZSBkZXRlY3Rpb24gY3ljbGUuIFRoZSBkZXNpZ24gb2YKICB0aGlzIGFsZ29yaXRobSBpcyBtYWtpbmcgc3VyZSB0aGF0OgogIC0gdGhlcmUgaXMgbm8gdW5uZWNlc3NhcnkgRE9NIG1hbmlwdWxhdGlvbiAoQ1NTIGNsYXNzZXMgYXJlIGFkZGVkIC8gcmVtb3ZlZCBmcm9tIHRoZSBET00gb25seSB3aGVuCiAgbmVlZGVkKSwgZXZlbiBpZiByZWZlcmVuY2VzIHRvIGJvdW5kIG9iamVjdHMgY2hhbmdlOwogIC0gdGhlcmUgaXMgbm8gbWVtb3J5IGFsbG9jYXRpb24gaWYgbm90aGluZyBjaGFuZ2VzIChldmVuIHJlbGF0aXZlbHkgbW9kZXN0IG1lbW9yeSBhbGxvY2F0aW9uCiAgZHVyaW5nIHRoZSBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlIGNhbiByZXN1bHQgaW4gR0MgcGF1c2VzIGZvciBzb21lIG9mIHRoZSBDRCBjeWNsZXMpLgogICAgIFRoZSBhbGdvcml0aG0gd29ya3MgYnkgaXRlcmF0aW5nIG92ZXIgdGhlIHNldCBvZiBib3VuZCBjbGFzc2VzLCBzdGFyaW5nIHdpdGggW2NsYXNzXSBiaW5kaW5nIGFuZAogIHRoZW4gZ29pbmcgb3ZlciBbbmdDbGFzc10gYmluZGluZy4gRm9yIGVhY2ggQ1NTIGNsYXNzIG5hbWU6CiAgLSBjaGVjayBpZiBpdCB3YXMgc2VlbiBiZWZvcmUgKHRoaXMgaW5mb3JtYXRpb24gaXMgdHJhY2tlZCBpbiB0aGUgc3RhdGUgbWFwKSBhbmQgaWYgaXRzIHZhbHVlCiAgY2hhbmdlZDsKICAtIG1hcmsgaXQgYXMgInRvdWNoZWQiIC0gbmFtZXMgdGhhdCBhcmUgbm90IG1hcmtlZCBhcmUgbm90IHByZXNlbnQgaW4gdGhlIGxhdGVzdCBzZXQgb2YgYmluZGluZwogIGFuZCB3ZSBjYW4gcmVtb3ZlIHN1Y2ggY2xhc3MgbmFtZSBmcm9tIHRoZSBpbnRlcm5hbCBkYXRhIHN0cnVjdHVyZXM7CiAgICAgQWZ0ZXIgaXRlcmF0aW9uIG92ZXIgYWxsIHRoZSBDU1MgY2xhc3MgbmFtZXMgd2UndmUgZ290IGRhdGEgc3RydWN0dXJlIHdpdGggYWxsIHRoZSBpbmZvcm1hdGlvbgogIG5lY2Vzc2FyeSB0byBzeW5jaHJvbml6ZSBjaGFuZ2VzIHRvIHRoZSBET00gLSBpdCBpcyBlbm91Z2ggdG8gaXRlcmF0ZSBvdmVyIHRoZSBzdGF0ZSBtYXAsIGZsdXNoCiAgY2hhbmdlcyB0byB0aGUgRE9NIGFuZCByZXNldCBpbnRlcm5hbCBkYXRhIHN0cnVjdHVyZXMgc28gdGhvc2UgYXJlIHJlYWR5IGZvciB0aGUgbmV4dCBjaGFuZ2UKICBkZXRlY3Rpb24gY3ljbGUuCiAgICovCiAgbmdEb0NoZWNrKCkgewogICAgZm9yIChjb25zdCBrbGFzcyBvZiB0aGlzLmluaXRpYWxDbGFzc2VzKSB7CiAgICAgIHRoaXMuX3VwZGF0ZVN0YXRlKGtsYXNzLCB0cnVlKTsKICAgIH0KICAgIGNvbnN0IHJhd0NsYXNzID0gdGhpcy5yYXdDbGFzczsKICAgIGlmIChBcnJheS5pc0FycmF5KHJhd0NsYXNzKSB8fCByYXdDbGFzcyBpbnN0YW5jZW9mIFNldCkgewogICAgICBmb3IgKGNvbnN0IGtsYXNzIG9mIHJhd0NsYXNzKSB7CiAgICAgICAgdGhpcy5fdXBkYXRlU3RhdGUoa2xhc3MsIHRydWUpOwogICAgICB9CiAgICB9IGVsc2UgaWYgKHJhd0NsYXNzICE9IG51bGwpIHsKICAgICAgZm9yIChjb25zdCBrbGFzcyBvZiBPYmplY3Qua2V5cyhyYXdDbGFzcykpIHsKICAgICAgICB0aGlzLl91cGRhdGVTdGF0ZShrbGFzcywgQm9vbGVhbihyYXdDbGFzc1trbGFzc10pKTsKICAgICAgfQogICAgfQogICAgdGhpcy5fYXBwbHlTdGF0ZURpZmYoKTsKICB9CiAgX3VwZGF0ZVN0YXRlKGtsYXNzLCBuZXh0RW5hYmxlZCkgewogICAgY29uc3Qgc3RhdGUgPSB0aGlzLnN0YXRlTWFwLmdldChrbGFzcyk7CiAgICBpZiAoc3RhdGUgIT09IHZvaWQgMCkgewogICAgICBpZiAoc3RhdGUuZW5hYmxlZCAhPT0gbmV4dEVuYWJsZWQpIHsKICAgICAgICBzdGF0ZS5jaGFuZ2VkID0gdHJ1ZTsKICAgICAgICBzdGF0ZS5lbmFibGVkID0gbmV4dEVuYWJsZWQ7CiAgICAgIH0KICAgICAgc3RhdGUudG91Y2hlZCA9IHRydWU7CiAgICB9IGVsc2UgewogICAgICB0aGlzLnN0YXRlTWFwLnNldChrbGFzcywgewogICAgICAgIGVuYWJsZWQ6IG5leHRFbmFibGVkLAogICAgICAgIGNoYW5nZWQ6IHRydWUsCiAgICAgICAgdG91Y2hlZDogdHJ1ZQogICAgICB9KTsKICAgIH0KICB9CiAgX2FwcGx5U3RhdGVEaWZmKCkgewogICAgZm9yIChjb25zdCBzdGF0ZUVudHJ5IG9mIHRoaXMuc3RhdGVNYXApIHsKICAgICAgY29uc3Qga2xhc3MgPSBzdGF0ZUVudHJ5WzBdOwogICAgICBjb25zdCBzdGF0ZSA9IHN0YXRlRW50cnlbMV07CiAgICAgIGlmIChzdGF0ZS5jaGFuZ2VkKSB7CiAgICAgICAgdGhpcy5fdG9nZ2xlQ2xhc3Moa2xhc3MsIHN0YXRlLmVuYWJsZWQpOwogICAgICAgIHN0YXRlLmNoYW5nZWQgPSBmYWxzZTsKICAgICAgfSBlbHNlIGlmICghc3RhdGUudG91Y2hlZCkgewogICAgICAgIGlmIChzdGF0ZS5lbmFibGVkKSB7CiAgICAgICAgICB0aGlzLl90b2dnbGVDbGFzcyhrbGFzcywgZmFsc2UpOwogICAgICAgIH0KICAgICAgICB0aGlzLnN0YXRlTWFwLmRlbGV0ZShrbGFzcyk7CiAgICAgIH0KICAgICAgc3RhdGUudG91Y2hlZCA9IGZhbHNlOwogICAgfQogIH0KICBfdG9nZ2xlQ2xhc3Moa2xhc3MsIGVuYWJsZWQpIHsKICAgIGlmIChuZ0Rldk1vZGUpIHsKICAgICAgaWYgKHR5cGVvZiBrbGFzcyAhPT0gInN0cmluZyIpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5nQ2xhc3MgY2FuIG9ubHkgdG9nZ2xlIENTUyBjbGFzc2VzIGV4cHJlc3NlZCBhcyBzdHJpbmdzLCBnb3QgJHtzdHJpbmdpZnkoa2xhc3MpfWApOwogICAgICB9CiAgICB9CiAgICBrbGFzcyA9IGtsYXNzLnRyaW0oKTsKICAgIGlmIChrbGFzcy5sZW5ndGggPiAwKSB7CiAgICAgIGtsYXNzLnNwbGl0KFdTX1JFR0VYUCkuZm9yRWFjaCgoa2xhc3MyKSA9PiB7CiAgICAgICAgaWYgKGVuYWJsZWQpIHsKICAgICAgICAgIHRoaXMuX3JlbmRlcmVyLmFkZENsYXNzKHRoaXMuX25nRWwubmF0aXZlRWxlbWVudCwga2xhc3MyKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgdGhpcy5fcmVuZGVyZXIucmVtb3ZlQ2xhc3ModGhpcy5fbmdFbC5uYXRpdmVFbGVtZW50LCBrbGFzczIpOwogICAgICAgIH0KICAgICAgfSk7CiAgICB9CiAgfQp9OwpfTmdDbGFzcy7JtWZhYyA9IGZ1bmN0aW9uIE5nQ2xhc3NfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTmdDbGFzcykoybXJtWRpcmVjdGl2ZUluamVjdChFbGVtZW50UmVmKSwgybXJtWRpcmVjdGl2ZUluamVjdChSZW5kZXJlcjIpKTsKfTsKX05nQ2xhc3MuybVkaXIgPSDJtcm1ZGVmaW5lRGlyZWN0aXZlKHsKICB0eXBlOiBfTmdDbGFzcywKICBzZWxlY3RvcnM6IFtbIiIsICJuZ0NsYXNzIiwgIiJdXSwKICBpbnB1dHM6IHsKICAgIGtsYXNzOiBbMCwgImNsYXNzIiwgImtsYXNzIl0sCiAgICBuZ0NsYXNzOiAibmdDbGFzcyIKICB9LAogIHN0YW5kYWxvbmU6IHRydWUKfSk7CnZhciBOZ0NsYXNzID0gX05nQ2xhc3M7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShOZ0NsYXNzLCBbewogICAgdHlwZTogRGlyZWN0aXZlLAogICAgYXJnczogW3sKICAgICAgc2VsZWN0b3I6ICJbbmdDbGFzc10iLAogICAgICBzdGFuZGFsb25lOiB0cnVlCiAgICB9XQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogRWxlbWVudFJlZgogIH0sIHsKICAgIHR5cGU6IFJlbmRlcmVyMgogIH1dLCB7CiAgICBrbGFzczogW3sKICAgICAgdHlwZTogSW5wdXQsCiAgICAgIGFyZ3M6IFsiY2xhc3MiXQogICAgfV0sCiAgICBuZ0NsYXNzOiBbewogICAgICB0eXBlOiBJbnB1dCwKICAgICAgYXJnczogWyJuZ0NsYXNzIl0KICAgIH1dCiAgfSk7Cn0pKCk7CnZhciBfTmdDb21wb25lbnRPdXRsZXQgPSBjbGFzcyBfTmdDb21wb25lbnRPdXRsZXQgewogIGNvbnN0cnVjdG9yKF92aWV3Q29udGFpbmVyUmVmKSB7CiAgICB0aGlzLl92aWV3Q29udGFpbmVyUmVmID0gX3ZpZXdDb250YWluZXJSZWY7CiAgICB0aGlzLm5nQ29tcG9uZW50T3V0bGV0ID0gbnVsbDsKICAgIHRoaXMuX2lucHV0c1VzZWQgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogIH0KICBfbmVlZFRvUmVDcmVhdGVOZ01vZHVsZUluc3RhbmNlKGNoYW5nZXMpIHsKICAgIHJldHVybiBjaGFuZ2VzWyJuZ0NvbXBvbmVudE91dGxldE5nTW9kdWxlIl0gIT09IHZvaWQgMCB8fCBjaGFuZ2VzWyJuZ0NvbXBvbmVudE91dGxldE5nTW9kdWxlRmFjdG9yeSJdICE9PSB2b2lkIDA7CiAgfQogIF9uZWVkVG9SZUNyZWF0ZUNvbXBvbmVudEluc3RhbmNlKGNoYW5nZXMpIHsKICAgIHJldHVybiBjaGFuZ2VzWyJuZ0NvbXBvbmVudE91dGxldCJdICE9PSB2b2lkIDAgfHwgY2hhbmdlc1sibmdDb21wb25lbnRPdXRsZXRDb250ZW50Il0gIT09IHZvaWQgMCB8fCBjaGFuZ2VzWyJuZ0NvbXBvbmVudE91dGxldEluamVjdG9yIl0gIT09IHZvaWQgMCB8fCB0aGlzLl9uZWVkVG9SZUNyZWF0ZU5nTW9kdWxlSW5zdGFuY2UoY2hhbmdlcyk7CiAgfQogIC8qKiBAbm9kb2MgKi8KICBuZ09uQ2hhbmdlcyhjaGFuZ2VzKSB7CiAgICBpZiAodGhpcy5fbmVlZFRvUmVDcmVhdGVDb21wb25lbnRJbnN0YW5jZShjaGFuZ2VzKSkgewogICAgICB0aGlzLl92aWV3Q29udGFpbmVyUmVmLmNsZWFyKCk7CiAgICAgIHRoaXMuX2lucHV0c1VzZWQuY2xlYXIoKTsKICAgICAgdGhpcy5fY29tcG9uZW50UmVmID0gdm9pZCAwOwogICAgICBpZiAodGhpcy5uZ0NvbXBvbmVudE91dGxldCkgewogICAgICAgIGNvbnN0IGluamVjdG9yID0gdGhpcy5uZ0NvbXBvbmVudE91dGxldEluamVjdG9yIHx8IHRoaXMuX3ZpZXdDb250YWluZXJSZWYucGFyZW50SW5qZWN0b3I7CiAgICAgICAgaWYgKHRoaXMuX25lZWRUb1JlQ3JlYXRlTmdNb2R1bGVJbnN0YW5jZShjaGFuZ2VzKSkgewogICAgICAgICAgdGhpcy5fbW9kdWxlUmVmPy5kZXN0cm95KCk7CiAgICAgICAgICBpZiAodGhpcy5uZ0NvbXBvbmVudE91dGxldE5nTW9kdWxlKSB7CiAgICAgICAgICAgIHRoaXMuX21vZHVsZVJlZiA9IGNyZWF0ZU5nTW9kdWxlKHRoaXMubmdDb21wb25lbnRPdXRsZXROZ01vZHVsZSwgZ2V0UGFyZW50SW5qZWN0b3IoaW5qZWN0b3IpKTsKICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5uZ0NvbXBvbmVudE91dGxldE5nTW9kdWxlRmFjdG9yeSkgewogICAgICAgICAgICB0aGlzLl9tb2R1bGVSZWYgPSB0aGlzLm5nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGVGYWN0b3J5LmNyZWF0ZShnZXRQYXJlbnRJbmplY3RvcihpbmplY3RvcikpOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhpcy5fbW9kdWxlUmVmID0gdm9pZCAwOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB0aGlzLl9jb21wb25lbnRSZWYgPSB0aGlzLl92aWV3Q29udGFpbmVyUmVmLmNyZWF0ZUNvbXBvbmVudCh0aGlzLm5nQ29tcG9uZW50T3V0bGV0LCB7CiAgICAgICAgICBpbmplY3RvciwKICAgICAgICAgIG5nTW9kdWxlUmVmOiB0aGlzLl9tb2R1bGVSZWYsCiAgICAgICAgICBwcm9qZWN0YWJsZU5vZGVzOiB0aGlzLm5nQ29tcG9uZW50T3V0bGV0Q29udGVudAogICAgICAgIH0pOwogICAgICB9CiAgICB9CiAgfQogIC8qKiBAbm9kb2MgKi8KICBuZ0RvQ2hlY2soKSB7CiAgICBpZiAodGhpcy5fY29tcG9uZW50UmVmKSB7CiAgICAgIGlmICh0aGlzLm5nQ29tcG9uZW50T3V0bGV0SW5wdXRzKSB7CiAgICAgICAgZm9yIChjb25zdCBpbnB1dE5hbWUgb2YgT2JqZWN0LmtleXModGhpcy5uZ0NvbXBvbmVudE91dGxldElucHV0cykpIHsKICAgICAgICAgIHRoaXMuX2lucHV0c1VzZWQuc2V0KGlucHV0TmFtZSwgdHJ1ZSk7CiAgICAgICAgfQogICAgICB9CiAgICAgIHRoaXMuX2FwcGx5SW5wdXRTdGF0ZURpZmYodGhpcy5fY29tcG9uZW50UmVmKTsKICAgIH0KICB9CiAgLyoqIEBub2RvYyAqLwogIG5nT25EZXN0cm95KCkgewogICAgdGhpcy5fbW9kdWxlUmVmPy5kZXN0cm95KCk7CiAgfQogIF9hcHBseUlucHV0U3RhdGVEaWZmKGNvbXBvbmVudFJlZikgewogICAgZm9yIChjb25zdCBbaW5wdXROYW1lLCB0b3VjaGVkXSBvZiB0aGlzLl9pbnB1dHNVc2VkKSB7CiAgICAgIGlmICghdG91Y2hlZCkgewogICAgICAgIGNvbXBvbmVudFJlZi5zZXRJbnB1dChpbnB1dE5hbWUsIHZvaWQgMCk7CiAgICAgICAgdGhpcy5faW5wdXRzVXNlZC5kZWxldGUoaW5wdXROYW1lKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjb21wb25lbnRSZWYuc2V0SW5wdXQoaW5wdXROYW1lLCB0aGlzLm5nQ29tcG9uZW50T3V0bGV0SW5wdXRzW2lucHV0TmFtZV0pOwogICAgICAgIHRoaXMuX2lucHV0c1VzZWQuc2V0KGlucHV0TmFtZSwgZmFsc2UpOwogICAgICB9CiAgICB9CiAgfQp9OwpfTmdDb21wb25lbnRPdXRsZXQuybVmYWMgPSBmdW5jdGlvbiBOZ0NvbXBvbmVudE91dGxldF9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9OZ0NvbXBvbmVudE91dGxldCkoybXJtWRpcmVjdGl2ZUluamVjdChWaWV3Q29udGFpbmVyUmVmKSk7Cn07Cl9OZ0NvbXBvbmVudE91dGxldC7JtWRpciA9IMm1ybVkZWZpbmVEaXJlY3RpdmUoewogIHR5cGU6IF9OZ0NvbXBvbmVudE91dGxldCwKICBzZWxlY3RvcnM6IFtbIiIsICJuZ0NvbXBvbmVudE91dGxldCIsICIiXV0sCiAgaW5wdXRzOiB7CiAgICBuZ0NvbXBvbmVudE91dGxldDogIm5nQ29tcG9uZW50T3V0bGV0IiwKICAgIG5nQ29tcG9uZW50T3V0bGV0SW5wdXRzOiAibmdDb21wb25lbnRPdXRsZXRJbnB1dHMiLAogICAgbmdDb21wb25lbnRPdXRsZXRJbmplY3RvcjogIm5nQ29tcG9uZW50T3V0bGV0SW5qZWN0b3IiLAogICAgbmdDb21wb25lbnRPdXRsZXRDb250ZW50OiAibmdDb21wb25lbnRPdXRsZXRDb250ZW50IiwKICAgIG5nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGU6ICJuZ0NvbXBvbmVudE91dGxldE5nTW9kdWxlIiwKICAgIG5nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGVGYWN0b3J5OiAibmdDb21wb25lbnRPdXRsZXROZ01vZHVsZUZhY3RvcnkiCiAgfSwKICBzdGFuZGFsb25lOiB0cnVlLAogIGZlYXR1cmVzOiBbybXJtU5nT25DaGFuZ2VzRmVhdHVyZV0KfSk7CnZhciBOZ0NvbXBvbmVudE91dGxldCA9IF9OZ0NvbXBvbmVudE91dGxldDsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKE5nQ29tcG9uZW50T3V0bGV0LCBbewogICAgdHlwZTogRGlyZWN0aXZlLAogICAgYXJnczogW3sKICAgICAgc2VsZWN0b3I6ICJbbmdDb21wb25lbnRPdXRsZXRdIiwKICAgICAgc3RhbmRhbG9uZTogdHJ1ZQogICAgfV0KICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IFZpZXdDb250YWluZXJSZWYKICB9XSwgewogICAgbmdDb21wb25lbnRPdXRsZXQ6IFt7CiAgICAgIHR5cGU6IElucHV0CiAgICB9XSwKICAgIG5nQ29tcG9uZW50T3V0bGV0SW5wdXRzOiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0sCiAgICBuZ0NvbXBvbmVudE91dGxldEluamVjdG9yOiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0sCiAgICBuZ0NvbXBvbmVudE91dGxldENvbnRlbnQ6IFt7CiAgICAgIHR5cGU6IElucHV0CiAgICB9XSwKICAgIG5nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGU6IFt7CiAgICAgIHR5cGU6IElucHV0CiAgICB9XSwKICAgIG5nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGVGYWN0b3J5OiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0KICB9KTsKfSkoKTsKZnVuY3Rpb24gZ2V0UGFyZW50SW5qZWN0b3IoaW5qZWN0b3IpIHsKICBjb25zdCBwYXJlbnROZ01vZHVsZSA9IGluamVjdG9yLmdldChOZ01vZHVsZVJlZiQxKTsKICByZXR1cm4gcGFyZW50TmdNb2R1bGUuaW5qZWN0b3I7Cn0KdmFyIE5nRm9yT2ZDb250ZXh0ID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKCRpbXBsaWNpdCwgbmdGb3JPZiwgaW5kZXgsIGNvdW50KSB7CiAgICB0aGlzLiRpbXBsaWNpdCA9ICRpbXBsaWNpdDsKICAgIHRoaXMubmdGb3JPZiA9IG5nRm9yT2Y7CiAgICB0aGlzLmluZGV4ID0gaW5kZXg7CiAgICB0aGlzLmNvdW50ID0gY291bnQ7CiAgfQogIGdldCBmaXJzdCgpIHsKICAgIHJldHVybiB0aGlzLmluZGV4ID09PSAwOwogIH0KICBnZXQgbGFzdCgpIHsKICAgIHJldHVybiB0aGlzLmluZGV4ID09PSB0aGlzLmNvdW50IC0gMTsKICB9CiAgZ2V0IGV2ZW4oKSB7CiAgICByZXR1cm4gdGhpcy5pbmRleCAlIDIgPT09IDA7CiAgfQogIGdldCBvZGQoKSB7CiAgICByZXR1cm4gIXRoaXMuZXZlbjsKICB9Cn07CnZhciBfTmdGb3JPZiA9IGNsYXNzIF9OZ0Zvck9mIHsKICAvKioKICAgKiBUaGUgdmFsdWUgb2YgdGhlIGl0ZXJhYmxlIGV4cHJlc3Npb24sIHdoaWNoIGNhbiBiZSB1c2VkIGFzIGEKICAgKiBbdGVtcGxhdGUgaW5wdXQgdmFyaWFibGVdKGd1aWRlL2RpcmVjdGl2ZXMvc3RydWN0dXJhbC1kaXJlY3RpdmVzI3Nob3J0aGFuZCkuCiAgICovCiAgc2V0IG5nRm9yT2YobmdGb3JPZikgewogICAgdGhpcy5fbmdGb3JPZiA9IG5nRm9yT2Y7CiAgICB0aGlzLl9uZ0Zvck9mRGlydHkgPSB0cnVlOwogIH0KICAvKioKICAgKiBTcGVjaWZpZXMgYSBjdXN0b20gYFRyYWNrQnlGdW5jdGlvbmAgdG8gY29tcHV0ZSB0aGUgaWRlbnRpdHkgb2YgaXRlbXMgaW4gYW4gaXRlcmFibGUuCiAgICoKICAgKiBJZiBhIGN1c3RvbSBgVHJhY2tCeUZ1bmN0aW9uYCBpcyBub3QgcHJvdmlkZWQsIGBOZ0Zvck9mYCB3aWxsIHVzZSB0aGUgaXRlbSdzIFtvYmplY3QKICAgKiBpZGVudGl0eV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzKQogICAqIGFzIHRoZSBrZXkuCiAgICoKICAgKiBgTmdGb3JPZmAgdXNlcyB0aGUgY29tcHV0ZWQga2V5IHRvIGFzc29jaWF0ZSBpdGVtcyBpbiBhbiBpdGVyYWJsZSB3aXRoIERPTSBlbGVtZW50cwogICAqIGl0IHByb2R1Y2VzIGZvciB0aGVzZSBpdGVtcy4KICAgKgogICAqIEEgY3VzdG9tIGBUcmFja0J5RnVuY3Rpb25gIGlzIHVzZWZ1bCB0byBwcm92aWRlIGdvb2QgdXNlciBleHBlcmllbmNlIGluIGNhc2VzIHdoZW4gaXRlbXMgaW4gYW4KICAgKiBpdGVyYWJsZSByZW5kZXJlZCB1c2luZyBgTmdGb3JPZmAgaGF2ZSBhIG5hdHVyYWwgaWRlbnRpZmllciAoZm9yIGV4YW1wbGUsIGN1c3RvbSBJRCBvciBhCiAgICogcHJpbWFyeSBrZXkpLCBhbmQgdGhpcyBpdGVyYWJsZSBjb3VsZCBiZSB1cGRhdGVkIHdpdGggbmV3IG9iamVjdCBpbnN0YW5jZXMgdGhhdCBzdGlsbAogICAqIHJlcHJlc2VudCB0aGUgc2FtZSB1bmRlcmx5aW5nIGVudGl0eSAoZm9yIGV4YW1wbGUsIHdoZW4gZGF0YSBpcyByZS1mZXRjaGVkIGZyb20gdGhlIHNlcnZlciwKICAgKiBhbmQgdGhlIGl0ZXJhYmxlIGlzIHJlY3JlYXRlZCBhbmQgcmUtcmVuZGVyZWQsIGJ1dCBtb3N0IG9mIHRoZSBkYXRhIGlzIHN0aWxsIHRoZSBzYW1lKS4KICAgKgogICAqIEBzZWUge0BsaW5rIFRyYWNrQnlGdW5jdGlvbn0KICAgKi8KICBzZXQgbmdGb3JUcmFja0J5KGZuKSB7CiAgICBpZiAoKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgZm4gIT0gbnVsbCAmJiB0eXBlb2YgZm4gIT09ICJmdW5jdGlvbiIpIHsKICAgICAgY29uc29sZS53YXJuKGB0cmFja0J5IG11c3QgYmUgYSBmdW5jdGlvbiwgYnV0IHJlY2VpdmVkICR7SlNPTi5zdHJpbmdpZnkoZm4pfS4gU2VlIGh0dHBzOi8vYW5ndWxhci5pby9hcGkvY29tbW9uL05nRm9yT2YjY2hhbmdlLXByb3BhZ2F0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLmApOwogICAgfQogICAgdGhpcy5fdHJhY2tCeUZuID0gZm47CiAgfQogIGdldCBuZ0ZvclRyYWNrQnkoKSB7CiAgICByZXR1cm4gdGhpcy5fdHJhY2tCeUZuOwogIH0KICBjb25zdHJ1Y3Rvcihfdmlld0NvbnRhaW5lciwgX3RlbXBsYXRlLCBfZGlmZmVycykgewogICAgdGhpcy5fdmlld0NvbnRhaW5lciA9IF92aWV3Q29udGFpbmVyOwogICAgdGhpcy5fdGVtcGxhdGUgPSBfdGVtcGxhdGU7CiAgICB0aGlzLl9kaWZmZXJzID0gX2RpZmZlcnM7CiAgICB0aGlzLl9uZ0Zvck9mID0gbnVsbDsKICAgIHRoaXMuX25nRm9yT2ZEaXJ0eSA9IHRydWU7CiAgICB0aGlzLl9kaWZmZXIgPSBudWxsOwogIH0KICAvKioKICAgKiBBIHJlZmVyZW5jZSB0byB0aGUgdGVtcGxhdGUgdGhhdCBpcyBzdGFtcGVkIG91dCBmb3IgZWFjaCBpdGVtIGluIHRoZSBpdGVyYWJsZS4KICAgKiBAc2VlIFt0ZW1wbGF0ZSByZWZlcmVuY2UgdmFyaWFibGVdKGd1aWRlL3RlbXBsYXRlcy9yZWZlcmVuY2UtdmFyaWFibGVzKQogICAqLwogIHNldCBuZ0ZvclRlbXBsYXRlKHZhbHVlKSB7CiAgICBpZiAodmFsdWUpIHsKICAgICAgdGhpcy5fdGVtcGxhdGUgPSB2YWx1ZTsKICAgIH0KICB9CiAgLyoqCiAgICogQXBwbGllcyB0aGUgY2hhbmdlcyB3aGVuIG5lZWRlZC4KICAgKiBAbm9kb2MKICAgKi8KICBuZ0RvQ2hlY2soKSB7CiAgICBpZiAodGhpcy5fbmdGb3JPZkRpcnR5KSB7CiAgICAgIHRoaXMuX25nRm9yT2ZEaXJ0eSA9IGZhbHNlOwogICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX25nRm9yT2Y7CiAgICAgIGlmICghdGhpcy5fZGlmZmVyICYmIHZhbHVlKSB7CiAgICAgICAgaWYgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgewogICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgdGhpcy5fZGlmZmVyID0gdGhpcy5fZGlmZmVycy5maW5kKHZhbHVlKS5jcmVhdGUodGhpcy5uZ0ZvclRyYWNrQnkpOwogICAgICAgICAgfSBjYXRjaCB7CiAgICAgICAgICAgIGxldCBlcnJvck1lc3NhZ2UgPSBgQ2Fubm90IGZpbmQgYSBkaWZmZXIgc3VwcG9ydGluZyBvYmplY3QgJyR7dmFsdWV9JyBvZiB0eXBlICcke2dldFR5cGVOYW1lKHZhbHVlKX0nLiBOZ0ZvciBvbmx5IHN1cHBvcnRzIGJpbmRpbmcgdG8gSXRlcmFibGVzLCBzdWNoIGFzIEFycmF5cy5gOwogICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAib2JqZWN0IikgewogICAgICAgICAgICAgIGVycm9yTWVzc2FnZSArPSAiIERpZCB5b3UgbWVhbiB0byB1c2UgdGhlIGtleXZhbHVlIHBpcGU/IjsKICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKC0yMjAwLCBlcnJvck1lc3NhZ2UpOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aGlzLl9kaWZmZXIgPSB0aGlzLl9kaWZmZXJzLmZpbmQodmFsdWUpLmNyZWF0ZSh0aGlzLm5nRm9yVHJhY2tCeSk7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBpZiAodGhpcy5fZGlmZmVyKSB7CiAgICAgIGNvbnN0IGNoYW5nZXMgPSB0aGlzLl9kaWZmZXIuZGlmZih0aGlzLl9uZ0Zvck9mKTsKICAgICAgaWYgKGNoYW5nZXMpCiAgICAgICAgdGhpcy5fYXBwbHlDaGFuZ2VzKGNoYW5nZXMpOwogICAgfQogIH0KICBfYXBwbHlDaGFuZ2VzKGNoYW5nZXMpIHsKICAgIGNvbnN0IHZpZXdDb250YWluZXIgPSB0aGlzLl92aWV3Q29udGFpbmVyOwogICAgY2hhbmdlcy5mb3JFYWNoT3BlcmF0aW9uKChpdGVtLCBhZGp1c3RlZFByZXZpb3VzSW5kZXgsIGN1cnJlbnRJbmRleCkgPT4gewogICAgICBpZiAoaXRlbS5wcmV2aW91c0luZGV4ID09IG51bGwpIHsKICAgICAgICB2aWV3Q29udGFpbmVyLmNyZWF0ZUVtYmVkZGVkVmlldyh0aGlzLl90ZW1wbGF0ZSwgbmV3IE5nRm9yT2ZDb250ZXh0KGl0ZW0uaXRlbSwgdGhpcy5fbmdGb3JPZiwgLTEsIC0xKSwgY3VycmVudEluZGV4ID09PSBudWxsID8gdm9pZCAwIDogY3VycmVudEluZGV4KTsKICAgICAgfSBlbHNlIGlmIChjdXJyZW50SW5kZXggPT0gbnVsbCkgewogICAgICAgIHZpZXdDb250YWluZXIucmVtb3ZlKGFkanVzdGVkUHJldmlvdXNJbmRleCA9PT0gbnVsbCA/IHZvaWQgMCA6IGFkanVzdGVkUHJldmlvdXNJbmRleCk7CiAgICAgIH0gZWxzZSBpZiAoYWRqdXN0ZWRQcmV2aW91c0luZGV4ICE9PSBudWxsKSB7CiAgICAgICAgY29uc3QgdmlldyA9IHZpZXdDb250YWluZXIuZ2V0KGFkanVzdGVkUHJldmlvdXNJbmRleCk7CiAgICAgICAgdmlld0NvbnRhaW5lci5tb3ZlKHZpZXcsIGN1cnJlbnRJbmRleCk7CiAgICAgICAgYXBwbHlWaWV3Q2hhbmdlKHZpZXcsIGl0ZW0pOwogICAgICB9CiAgICB9KTsKICAgIGZvciAobGV0IGkgPSAwLCBpbGVuID0gdmlld0NvbnRhaW5lci5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHsKICAgICAgY29uc3Qgdmlld1JlZiA9IHZpZXdDb250YWluZXIuZ2V0KGkpOwogICAgICBjb25zdCBjb250ZXh0ID0gdmlld1JlZi5jb250ZXh0OwogICAgICBjb250ZXh0LmluZGV4ID0gaTsKICAgICAgY29udGV4dC5jb3VudCA9IGlsZW47CiAgICAgIGNvbnRleHQubmdGb3JPZiA9IHRoaXMuX25nRm9yT2Y7CiAgICB9CiAgICBjaGFuZ2VzLmZvckVhY2hJZGVudGl0eUNoYW5nZSgocmVjb3JkKSA9PiB7CiAgICAgIGNvbnN0IHZpZXdSZWYgPSB2aWV3Q29udGFpbmVyLmdldChyZWNvcmQuY3VycmVudEluZGV4KTsKICAgICAgYXBwbHlWaWV3Q2hhbmdlKHZpZXdSZWYsIHJlY29yZCk7CiAgICB9KTsKICB9CiAgLyoqCiAgICogQXNzZXJ0cyB0aGUgY29ycmVjdCB0eXBlIG9mIHRoZSBjb250ZXh0IGZvciB0aGUgdGVtcGxhdGUgdGhhdCBgTmdGb3JPZmAgd2lsbCByZW5kZXIuCiAgICoKICAgKiBUaGUgcHJlc2VuY2Ugb2YgdGhpcyBtZXRob2QgaXMgYSBzaWduYWwgdG8gdGhlIEl2eSB0ZW1wbGF0ZSB0eXBlLWNoZWNrIGNvbXBpbGVyIHRoYXQgdGhlCiAgICogYE5nRm9yT2ZgIHN0cnVjdHVyYWwgZGlyZWN0aXZlIHJlbmRlcnMgaXRzIHRlbXBsYXRlIHdpdGggYSBzcGVjaWZpYyBjb250ZXh0IHR5cGUuCiAgICovCiAgc3RhdGljIG5nVGVtcGxhdGVDb250ZXh0R3VhcmQoZGlyLCBjdHgpIHsKICAgIHJldHVybiB0cnVlOwogIH0KfTsKX05nRm9yT2YuybVmYWMgPSBmdW5jdGlvbiBOZ0Zvck9mX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX05nRm9yT2YpKMm1ybVkaXJlY3RpdmVJbmplY3QoVmlld0NvbnRhaW5lclJlZiksIMm1ybVkaXJlY3RpdmVJbmplY3QoVGVtcGxhdGVSZWYpLCDJtcm1ZGlyZWN0aXZlSW5qZWN0KEl0ZXJhYmxlRGlmZmVycykpOwp9OwpfTmdGb3JPZi7JtWRpciA9IMm1ybVkZWZpbmVEaXJlY3RpdmUoewogIHR5cGU6IF9OZ0Zvck9mLAogIHNlbGVjdG9yczogW1siIiwgIm5nRm9yIiwgIiIsICJuZ0Zvck9mIiwgIiJdXSwKICBpbnB1dHM6IHsKICAgIG5nRm9yT2Y6ICJuZ0Zvck9mIiwKICAgIG5nRm9yVHJhY2tCeTogIm5nRm9yVHJhY2tCeSIsCiAgICBuZ0ZvclRlbXBsYXRlOiAibmdGb3JUZW1wbGF0ZSIKICB9LAogIHN0YW5kYWxvbmU6IHRydWUKfSk7CnZhciBOZ0Zvck9mID0gX05nRm9yT2Y7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShOZ0Zvck9mLCBbewogICAgdHlwZTogRGlyZWN0aXZlLAogICAgYXJnczogW3sKICAgICAgc2VsZWN0b3I6ICJbbmdGb3JdW25nRm9yT2ZdIiwKICAgICAgc3RhbmRhbG9uZTogdHJ1ZQogICAgfV0KICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IFZpZXdDb250YWluZXJSZWYKICB9LCB7CiAgICB0eXBlOiBUZW1wbGF0ZVJlZgogIH0sIHsKICAgIHR5cGU6IEl0ZXJhYmxlRGlmZmVycwogIH1dLCB7CiAgICBuZ0Zvck9mOiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0sCiAgICBuZ0ZvclRyYWNrQnk6IFt7CiAgICAgIHR5cGU6IElucHV0CiAgICB9XSwKICAgIG5nRm9yVGVtcGxhdGU6IFt7CiAgICAgIHR5cGU6IElucHV0CiAgICB9XQogIH0pOwp9KSgpOwpmdW5jdGlvbiBhcHBseVZpZXdDaGFuZ2UodmlldywgcmVjb3JkKSB7CiAgdmlldy5jb250ZXh0LiRpbXBsaWNpdCA9IHJlY29yZC5pdGVtOwp9CmZ1bmN0aW9uIGdldFR5cGVOYW1lKHR5cGUpIHsKICByZXR1cm4gdHlwZVsibmFtZSJdIHx8IHR5cGVvZiB0eXBlOwp9CnZhciBfTmdJZiA9IGNsYXNzIF9OZ0lmIHsKICBjb25zdHJ1Y3Rvcihfdmlld0NvbnRhaW5lciwgdGVtcGxhdGVSZWYpIHsKICAgIHRoaXMuX3ZpZXdDb250YWluZXIgPSBfdmlld0NvbnRhaW5lcjsKICAgIHRoaXMuX2NvbnRleHQgPSBuZXcgTmdJZkNvbnRleHQoKTsKICAgIHRoaXMuX3RoZW5UZW1wbGF0ZVJlZiA9IG51bGw7CiAgICB0aGlzLl9lbHNlVGVtcGxhdGVSZWYgPSBudWxsOwogICAgdGhpcy5fdGhlblZpZXdSZWYgPSBudWxsOwogICAgdGhpcy5fZWxzZVZpZXdSZWYgPSBudWxsOwogICAgdGhpcy5fdGhlblRlbXBsYXRlUmVmID0gdGVtcGxhdGVSZWY7CiAgfQogIC8qKgogICAqIFRoZSBCb29sZWFuIGV4cHJlc3Npb24gdG8gZXZhbHVhdGUgYXMgdGhlIGNvbmRpdGlvbiBmb3Igc2hvd2luZyBhIHRlbXBsYXRlLgogICAqLwogIHNldCBuZ0lmKGNvbmRpdGlvbikgewogICAgdGhpcy5fY29udGV4dC4kaW1wbGljaXQgPSB0aGlzLl9jb250ZXh0Lm5nSWYgPSBjb25kaXRpb247CiAgICB0aGlzLl91cGRhdGVWaWV3KCk7CiAgfQogIC8qKgogICAqIEEgdGVtcGxhdGUgdG8gc2hvdyBpZiB0aGUgY29uZGl0aW9uIGV4cHJlc3Npb24gZXZhbHVhdGVzIHRvIHRydWUuCiAgICovCiAgc2V0IG5nSWZUaGVuKHRlbXBsYXRlUmVmKSB7CiAgICBhc3NlcnRUZW1wbGF0ZSgibmdJZlRoZW4iLCB0ZW1wbGF0ZVJlZik7CiAgICB0aGlzLl90aGVuVGVtcGxhdGVSZWYgPSB0ZW1wbGF0ZVJlZjsKICAgIHRoaXMuX3RoZW5WaWV3UmVmID0gbnVsbDsKICAgIHRoaXMuX3VwZGF0ZVZpZXcoKTsKICB9CiAgLyoqCiAgICogQSB0ZW1wbGF0ZSB0byBzaG93IGlmIHRoZSBjb25kaXRpb24gZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gZmFsc2UuCiAgICovCiAgc2V0IG5nSWZFbHNlKHRlbXBsYXRlUmVmKSB7CiAgICBhc3NlcnRUZW1wbGF0ZSgibmdJZkVsc2UiLCB0ZW1wbGF0ZVJlZik7CiAgICB0aGlzLl9lbHNlVGVtcGxhdGVSZWYgPSB0ZW1wbGF0ZVJlZjsKICAgIHRoaXMuX2Vsc2VWaWV3UmVmID0gbnVsbDsKICAgIHRoaXMuX3VwZGF0ZVZpZXcoKTsKICB9CiAgX3VwZGF0ZVZpZXcoKSB7CiAgICBpZiAodGhpcy5fY29udGV4dC4kaW1wbGljaXQpIHsKICAgICAgaWYgKCF0aGlzLl90aGVuVmlld1JlZikgewogICAgICAgIHRoaXMuX3ZpZXdDb250YWluZXIuY2xlYXIoKTsKICAgICAgICB0aGlzLl9lbHNlVmlld1JlZiA9IG51bGw7CiAgICAgICAgaWYgKHRoaXMuX3RoZW5UZW1wbGF0ZVJlZikgewogICAgICAgICAgdGhpcy5fdGhlblZpZXdSZWYgPSB0aGlzLl92aWV3Q29udGFpbmVyLmNyZWF0ZUVtYmVkZGVkVmlldyh0aGlzLl90aGVuVGVtcGxhdGVSZWYsIHRoaXMuX2NvbnRleHQpOwogICAgICAgIH0KICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgaWYgKCF0aGlzLl9lbHNlVmlld1JlZikgewogICAgICAgIHRoaXMuX3ZpZXdDb250YWluZXIuY2xlYXIoKTsKICAgICAgICB0aGlzLl90aGVuVmlld1JlZiA9IG51bGw7CiAgICAgICAgaWYgKHRoaXMuX2Vsc2VUZW1wbGF0ZVJlZikgewogICAgICAgICAgdGhpcy5fZWxzZVZpZXdSZWYgPSB0aGlzLl92aWV3Q29udGFpbmVyLmNyZWF0ZUVtYmVkZGVkVmlldyh0aGlzLl9lbHNlVGVtcGxhdGVSZWYsIHRoaXMuX2NvbnRleHQpOwogICAgICAgIH0KICAgICAgfQogICAgfQogIH0KICAvKioKICAgKiBBc3NlcnRzIHRoZSBjb3JyZWN0IHR5cGUgb2YgdGhlIGNvbnRleHQgZm9yIHRoZSB0ZW1wbGF0ZSB0aGF0IGBOZ0lmYCB3aWxsIHJlbmRlci4KICAgKgogICAqIFRoZSBwcmVzZW5jZSBvZiB0aGlzIG1ldGhvZCBpcyBhIHNpZ25hbCB0byB0aGUgSXZ5IHRlbXBsYXRlIHR5cGUtY2hlY2sgY29tcGlsZXIgdGhhdCB0aGUKICAgKiBgTmdJZmAgc3RydWN0dXJhbCBkaXJlY3RpdmUgcmVuZGVycyBpdHMgdGVtcGxhdGUgd2l0aCBhIHNwZWNpZmljIGNvbnRleHQgdHlwZS4KICAgKi8KICBzdGF0aWMgbmdUZW1wbGF0ZUNvbnRleHRHdWFyZChkaXIsIGN0eCkgewogICAgcmV0dXJuIHRydWU7CiAgfQp9OwpfTmdJZi7JtWZhYyA9IGZ1bmN0aW9uIE5nSWZfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTmdJZikoybXJtWRpcmVjdGl2ZUluamVjdChWaWV3Q29udGFpbmVyUmVmKSwgybXJtWRpcmVjdGl2ZUluamVjdChUZW1wbGF0ZVJlZikpOwp9OwpfTmdJZi7JtWRpciA9IMm1ybVkZWZpbmVEaXJlY3RpdmUoewogIHR5cGU6IF9OZ0lmLAogIHNlbGVjdG9yczogW1siIiwgIm5nSWYiLCAiIl1dLAogIGlucHV0czogewogICAgbmdJZjogIm5nSWYiLAogICAgbmdJZlRoZW46ICJuZ0lmVGhlbiIsCiAgICBuZ0lmRWxzZTogIm5nSWZFbHNlIgogIH0sCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIE5nSWYgPSBfTmdJZjsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKE5nSWYsIFt7CiAgICB0eXBlOiBEaXJlY3RpdmUsCiAgICBhcmdzOiBbewogICAgICBzZWxlY3RvcjogIltuZ0lmXSIsCiAgICAgIHN0YW5kYWxvbmU6IHRydWUKICAgIH1dCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiBWaWV3Q29udGFpbmVyUmVmCiAgfSwgewogICAgdHlwZTogVGVtcGxhdGVSZWYKICB9XSwgewogICAgbmdJZjogW3sKICAgICAgdHlwZTogSW5wdXQKICAgIH1dLAogICAgbmdJZlRoZW46IFt7CiAgICAgIHR5cGU6IElucHV0CiAgICB9XSwKICAgIG5nSWZFbHNlOiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0KICB9KTsKfSkoKTsKdmFyIE5nSWZDb250ZXh0ID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKCkgewogICAgdGhpcy4kaW1wbGljaXQgPSBudWxsOwogICAgdGhpcy5uZ0lmID0gbnVsbDsKICB9Cn07CmZ1bmN0aW9uIGFzc2VydFRlbXBsYXRlKHByb3BlcnR5LCB0ZW1wbGF0ZVJlZikgewogIGNvbnN0IGlzVGVtcGxhdGVSZWZPck51bGwgPSAhISghdGVtcGxhdGVSZWYgfHwgdGVtcGxhdGVSZWYuY3JlYXRlRW1iZWRkZWRWaWV3KTsKICBpZiAoIWlzVGVtcGxhdGVSZWZPck51bGwpIHsKICAgIHRocm93IG5ldyBFcnJvcihgJHtwcm9wZXJ0eX0gbXVzdCBiZSBhIFRlbXBsYXRlUmVmLCBidXQgcmVjZWl2ZWQgJyR7c3RyaW5naWZ5KHRlbXBsYXRlUmVmKX0nLmApOwogIH0KfQp2YXIgTkdfU1dJVENIX1VTRV9TVFJJQ1RfRVFVQUxTID0gdHJ1ZTsKdmFyIFN3aXRjaFZpZXcgPSBjbGFzcyB7CiAgY29uc3RydWN0b3IoX3ZpZXdDb250YWluZXJSZWYsIF90ZW1wbGF0ZVJlZikgewogICAgdGhpcy5fdmlld0NvbnRhaW5lclJlZiA9IF92aWV3Q29udGFpbmVyUmVmOwogICAgdGhpcy5fdGVtcGxhdGVSZWYgPSBfdGVtcGxhdGVSZWY7CiAgICB0aGlzLl9jcmVhdGVkID0gZmFsc2U7CiAgfQogIGNyZWF0ZSgpIHsKICAgIHRoaXMuX2NyZWF0ZWQgPSB0cnVlOwogICAgdGhpcy5fdmlld0NvbnRhaW5lclJlZi5jcmVhdGVFbWJlZGRlZFZpZXcodGhpcy5fdGVtcGxhdGVSZWYpOwogIH0KICBkZXN0cm95KCkgewogICAgdGhpcy5fY3JlYXRlZCA9IGZhbHNlOwogICAgdGhpcy5fdmlld0NvbnRhaW5lclJlZi5jbGVhcigpOwogIH0KICBlbmZvcmNlU3RhdGUoY3JlYXRlZCkgewogICAgaWYgKGNyZWF0ZWQgJiYgIXRoaXMuX2NyZWF0ZWQpIHsKICAgICAgdGhpcy5jcmVhdGUoKTsKICAgIH0gZWxzZSBpZiAoIWNyZWF0ZWQgJiYgdGhpcy5fY3JlYXRlZCkgewogICAgICB0aGlzLmRlc3Ryb3koKTsKICAgIH0KICB9Cn07CnZhciBfTmdTd2l0Y2ggPSBjbGFzcyBfTmdTd2l0Y2ggewogIGNvbnN0cnVjdG9yKCkgewogICAgdGhpcy5fZGVmYXVsdFZpZXdzID0gW107CiAgICB0aGlzLl9kZWZhdWx0VXNlZCA9IGZhbHNlOwogICAgdGhpcy5fY2FzZUNvdW50ID0gMDsKICAgIHRoaXMuX2xhc3RDYXNlQ2hlY2tJbmRleCA9IDA7CiAgICB0aGlzLl9sYXN0Q2FzZXNNYXRjaGVkID0gZmFsc2U7CiAgfQogIHNldCBuZ1N3aXRjaChuZXdWYWx1ZSkgewogICAgdGhpcy5fbmdTd2l0Y2ggPSBuZXdWYWx1ZTsKICAgIGlmICh0aGlzLl9jYXNlQ291bnQgPT09IDApIHsKICAgICAgdGhpcy5fdXBkYXRlRGVmYXVsdENhc2VzKHRydWUpOwogICAgfQogIH0KICAvKiogQGludGVybmFsICovCiAgX2FkZENhc2UoKSB7CiAgICByZXR1cm4gdGhpcy5fY2FzZUNvdW50Kys7CiAgfQogIC8qKiBAaW50ZXJuYWwgKi8KICBfYWRkRGVmYXVsdCh2aWV3KSB7CiAgICB0aGlzLl9kZWZhdWx0Vmlld3MucHVzaCh2aWV3KTsKICB9CiAgLyoqIEBpbnRlcm5hbCAqLwogIF9tYXRjaENhc2UodmFsdWUpIHsKICAgIGNvbnN0IG1hdGNoZWQgPSBOR19TV0lUQ0hfVVNFX1NUUklDVF9FUVVBTFMgPyB2YWx1ZSA9PT0gdGhpcy5fbmdTd2l0Y2ggOiB2YWx1ZSA9PSB0aGlzLl9uZ1N3aXRjaDsKICAgIGlmICgodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBtYXRjaGVkICE9PSAodmFsdWUgPT0gdGhpcy5fbmdTd2l0Y2gpKSB7CiAgICAgIGNvbnNvbGUud2Fybihmb3JtYXRSdW50aW1lRXJyb3IoMjAwMSwgYEFzIG9mIEFuZ3VsYXIgdjE3IHRoZSBOZ1N3aXRjaCBkaXJlY3RpdmUgdXNlcyBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbiA9PT0gaW5zdGVhZCBvZiA9PSB0byBtYXRjaCBkaWZmZXJlbnQgY2FzZXMuIFByZXZpb3VzbHkgdGhlIGNhc2UgdmFsdWUgIiR7c3RyaW5naWZ5VmFsdWUodmFsdWUpfSIgbWF0Y2hlZCBzd2l0Y2ggZXhwcmVzc2lvbiB2YWx1ZSAiJHtzdHJpbmdpZnlWYWx1ZSh0aGlzLl9uZ1N3aXRjaCl9IiwgYnV0IHRoaXMgaXMgbm8gbG9uZ2VyIHRoZSBjYXNlIHdpdGggdGhlIHN0cmljdGVyIGVxdWFsaXR5IGNoZWNrLiBZb3VyIGNvbXBhcmlzb24gcmVzdWx0cyByZXR1cm4gZGlmZmVyZW50IHJlc3VsdHMgdXNpbmcgPT09IHZzLiA9PSBhbmQgeW91IHNob3VsZCBhZGp1c3QgeW91ciBuZ1N3aXRjaCBleHByZXNzaW9uIGFuZCAvIG9yIHZhbHVlcyB0byBjb25mb3JtIHdpdGggdGhlIHN0cmljdCBlcXVhbGl0eSByZXF1aXJlbWVudHMuYCkpOwogICAgfQogICAgdGhpcy5fbGFzdENhc2VzTWF0Y2hlZCB8fD0gbWF0Y2hlZDsKICAgIHRoaXMuX2xhc3RDYXNlQ2hlY2tJbmRleCsrOwogICAgaWYgKHRoaXMuX2xhc3RDYXNlQ2hlY2tJbmRleCA9PT0gdGhpcy5fY2FzZUNvdW50KSB7CiAgICAgIHRoaXMuX3VwZGF0ZURlZmF1bHRDYXNlcyghdGhpcy5fbGFzdENhc2VzTWF0Y2hlZCk7CiAgICAgIHRoaXMuX2xhc3RDYXNlQ2hlY2tJbmRleCA9IDA7CiAgICAgIHRoaXMuX2xhc3RDYXNlc01hdGNoZWQgPSBmYWxzZTsKICAgIH0KICAgIHJldHVybiBtYXRjaGVkOwogIH0KICBfdXBkYXRlRGVmYXVsdENhc2VzKHVzZURlZmF1bHQpIHsKICAgIGlmICh0aGlzLl9kZWZhdWx0Vmlld3MubGVuZ3RoID4gMCAmJiB1c2VEZWZhdWx0ICE9PSB0aGlzLl9kZWZhdWx0VXNlZCkgewogICAgICB0aGlzLl9kZWZhdWx0VXNlZCA9IHVzZURlZmF1bHQ7CiAgICAgIGZvciAoY29uc3QgZGVmYXVsdFZpZXcgb2YgdGhpcy5fZGVmYXVsdFZpZXdzKSB7CiAgICAgICAgZGVmYXVsdFZpZXcuZW5mb3JjZVN0YXRlKHVzZURlZmF1bHQpOwogICAgICB9CiAgICB9CiAgfQp9OwpfTmdTd2l0Y2guybVmYWMgPSBmdW5jdGlvbiBOZ1N3aXRjaF9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9OZ1N3aXRjaCkoKTsKfTsKX05nU3dpdGNoLsm1ZGlyID0gybXJtWRlZmluZURpcmVjdGl2ZSh7CiAgdHlwZTogX05nU3dpdGNoLAogIHNlbGVjdG9yczogW1siIiwgIm5nU3dpdGNoIiwgIiJdXSwKICBpbnB1dHM6IHsKICAgIG5nU3dpdGNoOiAibmdTd2l0Y2giCiAgfSwKICBzdGFuZGFsb25lOiB0cnVlCn0pOwp2YXIgTmdTd2l0Y2ggPSBfTmdTd2l0Y2g7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShOZ1N3aXRjaCwgW3sKICAgIHR5cGU6IERpcmVjdGl2ZSwKICAgIGFyZ3M6IFt7CiAgICAgIHNlbGVjdG9yOiAiW25nU3dpdGNoXSIsCiAgICAgIHN0YW5kYWxvbmU6IHRydWUKICAgIH1dCiAgfV0sIG51bGwsIHsKICAgIG5nU3dpdGNoOiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0KICB9KTsKfSkoKTsKdmFyIF9OZ1N3aXRjaENhc2UgPSBjbGFzcyBfTmdTd2l0Y2hDYXNlIHsKICBjb25zdHJ1Y3Rvcih2aWV3Q29udGFpbmVyLCB0ZW1wbGF0ZVJlZiwgbmdTd2l0Y2gpIHsKICAgIHRoaXMubmdTd2l0Y2ggPSBuZ1N3aXRjaDsKICAgIGlmICgodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiAhbmdTd2l0Y2gpIHsKICAgICAgdGhyb3dOZ1N3aXRjaFByb3ZpZGVyTm90Rm91bmRFcnJvcigibmdTd2l0Y2hDYXNlIiwgIk5nU3dpdGNoQ2FzZSIpOwogICAgfQogICAgbmdTd2l0Y2guX2FkZENhc2UoKTsKICAgIHRoaXMuX3ZpZXcgPSBuZXcgU3dpdGNoVmlldyh2aWV3Q29udGFpbmVyLCB0ZW1wbGF0ZVJlZik7CiAgfQogIC8qKgogICAqIFBlcmZvcm1zIGNhc2UgbWF0Y2hpbmcuIEZvciBpbnRlcm5hbCB1c2Ugb25seS4KICAgKiBAbm9kb2MKICAgKi8KICBuZ0RvQ2hlY2soKSB7CiAgICB0aGlzLl92aWV3LmVuZm9yY2VTdGF0ZSh0aGlzLm5nU3dpdGNoLl9tYXRjaENhc2UodGhpcy5uZ1N3aXRjaENhc2UpKTsKICB9Cn07Cl9OZ1N3aXRjaENhc2UuybVmYWMgPSBmdW5jdGlvbiBOZ1N3aXRjaENhc2VfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTmdTd2l0Y2hDYXNlKSjJtcm1ZGlyZWN0aXZlSW5qZWN0KFZpZXdDb250YWluZXJSZWYpLCDJtcm1ZGlyZWN0aXZlSW5qZWN0KFRlbXBsYXRlUmVmKSwgybXJtWRpcmVjdGl2ZUluamVjdChOZ1N3aXRjaCwgOSkpOwp9OwpfTmdTd2l0Y2hDYXNlLsm1ZGlyID0gybXJtWRlZmluZURpcmVjdGl2ZSh7CiAgdHlwZTogX05nU3dpdGNoQ2FzZSwKICBzZWxlY3RvcnM6IFtbIiIsICJuZ1N3aXRjaENhc2UiLCAiIl1dLAogIGlucHV0czogewogICAgbmdTd2l0Y2hDYXNlOiAibmdTd2l0Y2hDYXNlIgogIH0sCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIE5nU3dpdGNoQ2FzZSA9IF9OZ1N3aXRjaENhc2U7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShOZ1N3aXRjaENhc2UsIFt7CiAgICB0eXBlOiBEaXJlY3RpdmUsCiAgICBhcmdzOiBbewogICAgICBzZWxlY3RvcjogIltuZ1N3aXRjaENhc2VdIiwKICAgICAgc3RhbmRhbG9uZTogdHJ1ZQogICAgfV0KICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IFZpZXdDb250YWluZXJSZWYKICB9LCB7CiAgICB0eXBlOiBUZW1wbGF0ZVJlZgogIH0sIHsKICAgIHR5cGU6IE5nU3dpdGNoLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogT3B0aW9uYWwKICAgIH0sIHsKICAgICAgdHlwZTogSG9zdAogICAgfV0KICB9XSwgewogICAgbmdTd2l0Y2hDYXNlOiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0KICB9KTsKfSkoKTsKdmFyIF9OZ1N3aXRjaERlZmF1bHQgPSBjbGFzcyBfTmdTd2l0Y2hEZWZhdWx0IHsKICBjb25zdHJ1Y3Rvcih2aWV3Q29udGFpbmVyLCB0ZW1wbGF0ZVJlZiwgbmdTd2l0Y2gpIHsKICAgIGlmICgodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiAhbmdTd2l0Y2gpIHsKICAgICAgdGhyb3dOZ1N3aXRjaFByb3ZpZGVyTm90Rm91bmRFcnJvcigibmdTd2l0Y2hEZWZhdWx0IiwgIk5nU3dpdGNoRGVmYXVsdCIpOwogICAgfQogICAgbmdTd2l0Y2guX2FkZERlZmF1bHQobmV3IFN3aXRjaFZpZXcodmlld0NvbnRhaW5lciwgdGVtcGxhdGVSZWYpKTsKICB9Cn07Cl9OZ1N3aXRjaERlZmF1bHQuybVmYWMgPSBmdW5jdGlvbiBOZ1N3aXRjaERlZmF1bHRfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTmdTd2l0Y2hEZWZhdWx0KSjJtcm1ZGlyZWN0aXZlSW5qZWN0KFZpZXdDb250YWluZXJSZWYpLCDJtcm1ZGlyZWN0aXZlSW5qZWN0KFRlbXBsYXRlUmVmKSwgybXJtWRpcmVjdGl2ZUluamVjdChOZ1N3aXRjaCwgOSkpOwp9OwpfTmdTd2l0Y2hEZWZhdWx0Lsm1ZGlyID0gybXJtWRlZmluZURpcmVjdGl2ZSh7CiAgdHlwZTogX05nU3dpdGNoRGVmYXVsdCwKICBzZWxlY3RvcnM6IFtbIiIsICJuZ1N3aXRjaERlZmF1bHQiLCAiIl1dLAogIHN0YW5kYWxvbmU6IHRydWUKfSk7CnZhciBOZ1N3aXRjaERlZmF1bHQgPSBfTmdTd2l0Y2hEZWZhdWx0OwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoTmdTd2l0Y2hEZWZhdWx0LCBbewogICAgdHlwZTogRGlyZWN0aXZlLAogICAgYXJnczogW3sKICAgICAgc2VsZWN0b3I6ICJbbmdTd2l0Y2hEZWZhdWx0XSIsCiAgICAgIHN0YW5kYWxvbmU6IHRydWUKICAgIH1dCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiBWaWV3Q29udGFpbmVyUmVmCiAgfSwgewogICAgdHlwZTogVGVtcGxhdGVSZWYKICB9LCB7CiAgICB0eXBlOiBOZ1N3aXRjaCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IE9wdGlvbmFsCiAgICB9LCB7CiAgICAgIHR5cGU6IEhvc3QKICAgIH1dCiAgfV0sIG51bGwpOwp9KSgpOwpmdW5jdGlvbiB0aHJvd05nU3dpdGNoUHJvdmlkZXJOb3RGb3VuZEVycm9yKGF0dHJOYW1lLCBkaXJlY3RpdmVOYW1lKSB7CiAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigyZTMsIGBBbiBlbGVtZW50IHdpdGggdGhlICIke2F0dHJOYW1lfSIgYXR0cmlidXRlIChtYXRjaGluZyB0aGUgIiR7ZGlyZWN0aXZlTmFtZX0iIGRpcmVjdGl2ZSkgbXVzdCBiZSBsb2NhdGVkIGluc2lkZSBhbiBlbGVtZW50IHdpdGggdGhlICJuZ1N3aXRjaCIgYXR0cmlidXRlIChtYXRjaGluZyAiTmdTd2l0Y2giIGRpcmVjdGl2ZSlgKTsKfQpmdW5jdGlvbiBzdHJpbmdpZnlWYWx1ZSh2YWx1ZSkgewogIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICJzdHJpbmciID8gYCcke3ZhbHVlfSdgIDogU3RyaW5nKHZhbHVlKTsKfQp2YXIgX05nUGx1cmFsID0gY2xhc3MgX05nUGx1cmFsIHsKICBjb25zdHJ1Y3RvcihfbG9jYWxpemF0aW9uKSB7CiAgICB0aGlzLl9sb2NhbGl6YXRpb24gPSBfbG9jYWxpemF0aW9uOwogICAgdGhpcy5fY2FzZVZpZXdzID0ge307CiAgfQogIHNldCBuZ1BsdXJhbCh2YWx1ZSkgewogICAgdGhpcy5fdXBkYXRlVmlldyh2YWx1ZSk7CiAgfQogIGFkZENhc2UodmFsdWUsIHN3aXRjaFZpZXcpIHsKICAgIHRoaXMuX2Nhc2VWaWV3c1t2YWx1ZV0gPSBzd2l0Y2hWaWV3OwogIH0KICBfdXBkYXRlVmlldyhzd2l0Y2hWYWx1ZSkgewogICAgdGhpcy5fY2xlYXJWaWV3cygpOwogICAgY29uc3QgY2FzZXMgPSBPYmplY3Qua2V5cyh0aGlzLl9jYXNlVmlld3MpOwogICAgY29uc3Qga2V5ID0gZ2V0UGx1cmFsQ2F0ZWdvcnkoc3dpdGNoVmFsdWUsIGNhc2VzLCB0aGlzLl9sb2NhbGl6YXRpb24pOwogICAgdGhpcy5fYWN0aXZhdGVWaWV3KHRoaXMuX2Nhc2VWaWV3c1trZXldKTsKICB9CiAgX2NsZWFyVmlld3MoKSB7CiAgICBpZiAodGhpcy5fYWN0aXZlVmlldykKICAgICAgdGhpcy5fYWN0aXZlVmlldy5kZXN0cm95KCk7CiAgfQogIF9hY3RpdmF0ZVZpZXcodmlldykgewogICAgaWYgKHZpZXcpIHsKICAgICAgdGhpcy5fYWN0aXZlVmlldyA9IHZpZXc7CiAgICAgIHRoaXMuX2FjdGl2ZVZpZXcuY3JlYXRlKCk7CiAgICB9CiAgfQp9OwpfTmdQbHVyYWwuybVmYWMgPSBmdW5jdGlvbiBOZ1BsdXJhbF9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9OZ1BsdXJhbCkoybXJtWRpcmVjdGl2ZUluamVjdChOZ0xvY2FsaXphdGlvbikpOwp9OwpfTmdQbHVyYWwuybVkaXIgPSDJtcm1ZGVmaW5lRGlyZWN0aXZlKHsKICB0eXBlOiBfTmdQbHVyYWwsCiAgc2VsZWN0b3JzOiBbWyIiLCAibmdQbHVyYWwiLCAiIl1dLAogIGlucHV0czogewogICAgbmdQbHVyYWw6ICJuZ1BsdXJhbCIKICB9LAogIHN0YW5kYWxvbmU6IHRydWUKfSk7CnZhciBOZ1BsdXJhbCA9IF9OZ1BsdXJhbDsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKE5nUGx1cmFsLCBbewogICAgdHlwZTogRGlyZWN0aXZlLAogICAgYXJnczogW3sKICAgICAgc2VsZWN0b3I6ICJbbmdQbHVyYWxdIiwKICAgICAgc3RhbmRhbG9uZTogdHJ1ZQogICAgfV0KICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IE5nTG9jYWxpemF0aW9uCiAgfV0sIHsKICAgIG5nUGx1cmFsOiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0KICB9KTsKfSkoKTsKdmFyIF9OZ1BsdXJhbENhc2UgPSBjbGFzcyBfTmdQbHVyYWxDYXNlIHsKICBjb25zdHJ1Y3Rvcih2YWx1ZSwgdGVtcGxhdGUsIHZpZXdDb250YWluZXIsIG5nUGx1cmFsKSB7CiAgICB0aGlzLnZhbHVlID0gdmFsdWU7CiAgICBjb25zdCBpc0FOdW1iZXIgPSAhaXNOYU4oTnVtYmVyKHZhbHVlKSk7CiAgICBuZ1BsdXJhbC5hZGRDYXNlKGlzQU51bWJlciA/IGA9JHt2YWx1ZX1gIDogdmFsdWUsIG5ldyBTd2l0Y2hWaWV3KHZpZXdDb250YWluZXIsIHRlbXBsYXRlKSk7CiAgfQp9OwpfTmdQbHVyYWxDYXNlLsm1ZmFjID0gZnVuY3Rpb24gTmdQbHVyYWxDYXNlX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX05nUGx1cmFsQ2FzZSkoybXJtWluamVjdEF0dHJpYnV0ZSgibmdQbHVyYWxDYXNlIiksIMm1ybVkaXJlY3RpdmVJbmplY3QoVGVtcGxhdGVSZWYpLCDJtcm1ZGlyZWN0aXZlSW5qZWN0KFZpZXdDb250YWluZXJSZWYpLCDJtcm1ZGlyZWN0aXZlSW5qZWN0KE5nUGx1cmFsLCAxKSk7Cn07Cl9OZ1BsdXJhbENhc2UuybVkaXIgPSDJtcm1ZGVmaW5lRGlyZWN0aXZlKHsKICB0eXBlOiBfTmdQbHVyYWxDYXNlLAogIHNlbGVjdG9yczogW1siIiwgIm5nUGx1cmFsQ2FzZSIsICIiXV0sCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIE5nUGx1cmFsQ2FzZSA9IF9OZ1BsdXJhbENhc2U7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShOZ1BsdXJhbENhc2UsIFt7CiAgICB0eXBlOiBEaXJlY3RpdmUsCiAgICBhcmdzOiBbewogICAgICBzZWxlY3RvcjogIltuZ1BsdXJhbENhc2VdIiwKICAgICAgc3RhbmRhbG9uZTogdHJ1ZQogICAgfV0KICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IHZvaWQgMCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEF0dHJpYnV0ZSwKICAgICAgYXJnczogWyJuZ1BsdXJhbENhc2UiXQogICAgfV0KICB9LCB7CiAgICB0eXBlOiBUZW1wbGF0ZVJlZgogIH0sIHsKICAgIHR5cGU6IFZpZXdDb250YWluZXJSZWYKICB9LCB7CiAgICB0eXBlOiBOZ1BsdXJhbCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEhvc3QKICAgIH1dCiAgfV0sIG51bGwpOwp9KSgpOwp2YXIgX05nU3R5bGUgPSBjbGFzcyBfTmdTdHlsZSB7CiAgY29uc3RydWN0b3IoX25nRWwsIF9kaWZmZXJzLCBfcmVuZGVyZXIpIHsKICAgIHRoaXMuX25nRWwgPSBfbmdFbDsKICAgIHRoaXMuX2RpZmZlcnMgPSBfZGlmZmVyczsKICAgIHRoaXMuX3JlbmRlcmVyID0gX3JlbmRlcmVyOwogICAgdGhpcy5fbmdTdHlsZSA9IG51bGw7CiAgICB0aGlzLl9kaWZmZXIgPSBudWxsOwogIH0KICBzZXQgbmdTdHlsZSh2YWx1ZXMpIHsKICAgIHRoaXMuX25nU3R5bGUgPSB2YWx1ZXM7CiAgICBpZiAoIXRoaXMuX2RpZmZlciAmJiB2YWx1ZXMpIHsKICAgICAgdGhpcy5fZGlmZmVyID0gdGhpcy5fZGlmZmVycy5maW5kKHZhbHVlcykuY3JlYXRlKCk7CiAgICB9CiAgfQogIG5nRG9DaGVjaygpIHsKICAgIGlmICh0aGlzLl9kaWZmZXIpIHsKICAgICAgY29uc3QgY2hhbmdlcyA9IHRoaXMuX2RpZmZlci5kaWZmKHRoaXMuX25nU3R5bGUpOwogICAgICBpZiAoY2hhbmdlcykgewogICAgICAgIHRoaXMuX2FwcGx5Q2hhbmdlcyhjaGFuZ2VzKTsKICAgICAgfQogICAgfQogIH0KICBfc2V0U3R5bGUobmFtZUFuZFVuaXQsIHZhbHVlKSB7CiAgICBjb25zdCBbbmFtZSwgdW5pdF0gPSBuYW1lQW5kVW5pdC5zcGxpdCgiLiIpOwogICAgY29uc3QgZmxhZ3MgPSBuYW1lLmluZGV4T2YoIi0iKSA9PT0gLTEgPyB2b2lkIDAgOiBSZW5kZXJlclN0eWxlRmxhZ3MyLkRhc2hDYXNlOwogICAgaWYgKHZhbHVlICE9IG51bGwpIHsKICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0U3R5bGUodGhpcy5fbmdFbC5uYXRpdmVFbGVtZW50LCBuYW1lLCB1bml0ID8gYCR7dmFsdWV9JHt1bml0fWAgOiB2YWx1ZSwgZmxhZ3MpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5fcmVuZGVyZXIucmVtb3ZlU3R5bGUodGhpcy5fbmdFbC5uYXRpdmVFbGVtZW50LCBuYW1lLCBmbGFncyk7CiAgICB9CiAgfQogIF9hcHBseUNoYW5nZXMoY2hhbmdlcykgewogICAgY2hhbmdlcy5mb3JFYWNoUmVtb3ZlZEl0ZW0oKHJlY29yZCkgPT4gdGhpcy5fc2V0U3R5bGUocmVjb3JkLmtleSwgbnVsbCkpOwogICAgY2hhbmdlcy5mb3JFYWNoQWRkZWRJdGVtKChyZWNvcmQpID0+IHRoaXMuX3NldFN0eWxlKHJlY29yZC5rZXksIHJlY29yZC5jdXJyZW50VmFsdWUpKTsKICAgIGNoYW5nZXMuZm9yRWFjaENoYW5nZWRJdGVtKChyZWNvcmQpID0+IHRoaXMuX3NldFN0eWxlKHJlY29yZC5rZXksIHJlY29yZC5jdXJyZW50VmFsdWUpKTsKICB9Cn07Cl9OZ1N0eWxlLsm1ZmFjID0gZnVuY3Rpb24gTmdTdHlsZV9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9OZ1N0eWxlKSjJtcm1ZGlyZWN0aXZlSW5qZWN0KEVsZW1lbnRSZWYpLCDJtcm1ZGlyZWN0aXZlSW5qZWN0KEtleVZhbHVlRGlmZmVycyksIMm1ybVkaXJlY3RpdmVJbmplY3QoUmVuZGVyZXIyKSk7Cn07Cl9OZ1N0eWxlLsm1ZGlyID0gybXJtWRlZmluZURpcmVjdGl2ZSh7CiAgdHlwZTogX05nU3R5bGUsCiAgc2VsZWN0b3JzOiBbWyIiLCAibmdTdHlsZSIsICIiXV0sCiAgaW5wdXRzOiB7CiAgICBuZ1N0eWxlOiAibmdTdHlsZSIKICB9LAogIHN0YW5kYWxvbmU6IHRydWUKfSk7CnZhciBOZ1N0eWxlID0gX05nU3R5bGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShOZ1N0eWxlLCBbewogICAgdHlwZTogRGlyZWN0aXZlLAogICAgYXJnczogW3sKICAgICAgc2VsZWN0b3I6ICJbbmdTdHlsZV0iLAogICAgICBzdGFuZGFsb25lOiB0cnVlCiAgICB9XQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogRWxlbWVudFJlZgogIH0sIHsKICAgIHR5cGU6IEtleVZhbHVlRGlmZmVycwogIH0sIHsKICAgIHR5cGU6IFJlbmRlcmVyMgogIH1dLCB7CiAgICBuZ1N0eWxlOiBbewogICAgICB0eXBlOiBJbnB1dCwKICAgICAgYXJnczogWyJuZ1N0eWxlIl0KICAgIH1dCiAgfSk7Cn0pKCk7CnZhciBfTmdUZW1wbGF0ZU91dGxldCA9IGNsYXNzIF9OZ1RlbXBsYXRlT3V0bGV0IHsKICBjb25zdHJ1Y3Rvcihfdmlld0NvbnRhaW5lclJlZikgewogICAgdGhpcy5fdmlld0NvbnRhaW5lclJlZiA9IF92aWV3Q29udGFpbmVyUmVmOwogICAgdGhpcy5fdmlld1JlZiA9IG51bGw7CiAgICB0aGlzLm5nVGVtcGxhdGVPdXRsZXRDb250ZXh0ID0gbnVsbDsKICAgIHRoaXMubmdUZW1wbGF0ZU91dGxldCA9IG51bGw7CiAgICB0aGlzLm5nVGVtcGxhdGVPdXRsZXRJbmplY3RvciA9IG51bGw7CiAgfQogIG5nT25DaGFuZ2VzKGNoYW5nZXMpIHsKICAgIGlmICh0aGlzLl9zaG91bGRSZWNyZWF0ZVZpZXcoY2hhbmdlcykpIHsKICAgICAgY29uc3Qgdmlld0NvbnRhaW5lclJlZiA9IHRoaXMuX3ZpZXdDb250YWluZXJSZWY7CiAgICAgIGlmICh0aGlzLl92aWV3UmVmKSB7CiAgICAgICAgdmlld0NvbnRhaW5lclJlZi5yZW1vdmUodmlld0NvbnRhaW5lclJlZi5pbmRleE9mKHRoaXMuX3ZpZXdSZWYpKTsKICAgICAgfQogICAgICBpZiAoIXRoaXMubmdUZW1wbGF0ZU91dGxldCkgewogICAgICAgIHRoaXMuX3ZpZXdSZWYgPSBudWxsOwogICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBjb25zdCB2aWV3Q29udGV4dCA9IHRoaXMuX2NyZWF0ZUNvbnRleHRGb3J3YXJkUHJveHkoKTsKICAgICAgdGhpcy5fdmlld1JlZiA9IHZpZXdDb250YWluZXJSZWYuY3JlYXRlRW1iZWRkZWRWaWV3KHRoaXMubmdUZW1wbGF0ZU91dGxldCwgdmlld0NvbnRleHQsIHsKICAgICAgICBpbmplY3RvcjogdGhpcy5uZ1RlbXBsYXRlT3V0bGV0SW5qZWN0b3IgPz8gdm9pZCAwCiAgICAgIH0pOwogICAgfQogIH0KICAvKioKICAgKiBXZSBuZWVkIHRvIHJlLWNyZWF0ZSBleGlzdGluZyBlbWJlZGRlZCB2aWV3IGlmIGVpdGhlciBpcyB0cnVlOgogICAqIC0gdGhlIG91dGxldCBjaGFuZ2VkLgogICAqIC0gdGhlIGluamVjdG9yIGNoYW5nZWQuCiAgICovCiAgX3Nob3VsZFJlY3JlYXRlVmlldyhjaGFuZ2VzKSB7CiAgICByZXR1cm4gISFjaGFuZ2VzWyJuZ1RlbXBsYXRlT3V0bGV0Il0gfHwgISFjaGFuZ2VzWyJuZ1RlbXBsYXRlT3V0bGV0SW5qZWN0b3IiXTsKICB9CiAgLyoqCiAgICogRm9yIGEgZ2l2ZW4gb3V0bGV0IGluc3RhbmNlLCB3ZSBjcmVhdGUgYSBwcm94eSBvYmplY3QgdGhhdCBkZWxlZ2F0ZXMKICAgKiB0byB0aGUgdXNlci1zcGVjaWZpZWQgY29udGV4dC4gVGhpcyBhbGxvd3MgY2hhbmdpbmcsIG9yIHN3YXBwaW5nIG91dAogICAqIHRoZSBjb250ZXh0IG9iamVjdCBjb21wbGV0ZWx5IHdpdGhvdXQgaGF2aW5nIHRvIGRlc3Ryb3kvcmUtY3JlYXRlIHRoZSB2aWV3LgogICAqLwogIF9jcmVhdGVDb250ZXh0Rm9yd2FyZFByb3h5KCkgewogICAgcmV0dXJuIG5ldyBQcm94eSh7fSwgewogICAgICBzZXQ6IChfdGFyZ2V0LCBwcm9wLCBuZXdWYWx1ZSkgPT4gewogICAgICAgIGlmICghdGhpcy5uZ1RlbXBsYXRlT3V0bGV0Q29udGV4dCkgewogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgICAgICByZXR1cm4gUmVmbGVjdC5zZXQodGhpcy5uZ1RlbXBsYXRlT3V0bGV0Q29udGV4dCwgcHJvcCwgbmV3VmFsdWUpOwogICAgICB9LAogICAgICBnZXQ6IChfdGFyZ2V0LCBwcm9wLCByZWNlaXZlcikgPT4gewogICAgICAgIGlmICghdGhpcy5uZ1RlbXBsYXRlT3V0bGV0Q29udGV4dCkgewogICAgICAgICAgcmV0dXJuIHZvaWQgMDsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIFJlZmxlY3QuZ2V0KHRoaXMubmdUZW1wbGF0ZU91dGxldENvbnRleHQsIHByb3AsIHJlY2VpdmVyKTsKICAgICAgfQogICAgfSk7CiAgfQp9OwpfTmdUZW1wbGF0ZU91dGxldC7JtWZhYyA9IGZ1bmN0aW9uIE5nVGVtcGxhdGVPdXRsZXRfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTmdUZW1wbGF0ZU91dGxldCkoybXJtWRpcmVjdGl2ZUluamVjdChWaWV3Q29udGFpbmVyUmVmKSk7Cn07Cl9OZ1RlbXBsYXRlT3V0bGV0Lsm1ZGlyID0gybXJtWRlZmluZURpcmVjdGl2ZSh7CiAgdHlwZTogX05nVGVtcGxhdGVPdXRsZXQsCiAgc2VsZWN0b3JzOiBbWyIiLCAibmdUZW1wbGF0ZU91dGxldCIsICIiXV0sCiAgaW5wdXRzOiB7CiAgICBuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dDogIm5nVGVtcGxhdGVPdXRsZXRDb250ZXh0IiwKICAgIG5nVGVtcGxhdGVPdXRsZXQ6ICJuZ1RlbXBsYXRlT3V0bGV0IiwKICAgIG5nVGVtcGxhdGVPdXRsZXRJbmplY3RvcjogIm5nVGVtcGxhdGVPdXRsZXRJbmplY3RvciIKICB9LAogIHN0YW5kYWxvbmU6IHRydWUsCiAgZmVhdHVyZXM6IFvJtcm1TmdPbkNoYW5nZXNGZWF0dXJlXQp9KTsKdmFyIE5nVGVtcGxhdGVPdXRsZXQgPSBfTmdUZW1wbGF0ZU91dGxldDsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKE5nVGVtcGxhdGVPdXRsZXQsIFt7CiAgICB0eXBlOiBEaXJlY3RpdmUsCiAgICBhcmdzOiBbewogICAgICBzZWxlY3RvcjogIltuZ1RlbXBsYXRlT3V0bGV0XSIsCiAgICAgIHN0YW5kYWxvbmU6IHRydWUKICAgIH1dCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiBWaWV3Q29udGFpbmVyUmVmCiAgfV0sIHsKICAgIG5nVGVtcGxhdGVPdXRsZXRDb250ZXh0OiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0sCiAgICBuZ1RlbXBsYXRlT3V0bGV0OiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0sCiAgICBuZ1RlbXBsYXRlT3V0bGV0SW5qZWN0b3I6IFt7CiAgICAgIHR5cGU6IElucHV0CiAgICB9XQogIH0pOwp9KSgpOwp2YXIgQ09NTU9OX0RJUkVDVElWRVMgPSBbTmdDbGFzcywgTmdDb21wb25lbnRPdXRsZXQsIE5nRm9yT2YsIE5nSWYsIE5nVGVtcGxhdGVPdXRsZXQsIE5nU3R5bGUsIE5nU3dpdGNoLCBOZ1N3aXRjaENhc2UsIE5nU3dpdGNoRGVmYXVsdCwgTmdQbHVyYWwsIE5nUGx1cmFsQ2FzZV07CmZ1bmN0aW9uIGludmFsaWRQaXBlQXJndW1lbnRFcnJvcih0eXBlLCB2YWx1ZSkgewogIHJldHVybiBuZXcgUnVudGltZUVycm9yKDIxMDAsIG5nRGV2TW9kZSAmJiBgSW52YWxpZFBpcGVBcmd1bWVudDogJyR7dmFsdWV9JyBmb3IgcGlwZSAnJHtzdHJpbmdpZnkodHlwZSl9J2ApOwp9CnZhciBTdWJzY3JpYmFibGVTdHJhdGVneSA9IGNsYXNzIHsKICBjcmVhdGVTdWJzY3JpcHRpb24oYXN5bmMsIHVwZGF0ZUxhdGVzdFZhbHVlKSB7CiAgICByZXR1cm4gdW50cmFja2VkKCgpID0+IGFzeW5jLnN1YnNjcmliZSh7CiAgICAgIG5leHQ6IHVwZGF0ZUxhdGVzdFZhbHVlLAogICAgICBlcnJvcjogKGUpID0+IHsKICAgICAgICB0aHJvdyBlOwogICAgICB9CiAgICB9KSk7CiAgfQogIGRpc3Bvc2Uoc3Vic2NyaXB0aW9uKSB7CiAgICB1bnRyYWNrZWQoKCkgPT4gc3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCkpOwogIH0KfTsKdmFyIFByb21pc2VTdHJhdGVneSA9IGNsYXNzIHsKICBjcmVhdGVTdWJzY3JpcHRpb24oYXN5bmMsIHVwZGF0ZUxhdGVzdFZhbHVlKSB7CiAgICByZXR1cm4gYXN5bmMudGhlbih1cGRhdGVMYXRlc3RWYWx1ZSwgKGUpID0+IHsKICAgICAgdGhyb3cgZTsKICAgIH0pOwogIH0KICBkaXNwb3NlKHN1YnNjcmlwdGlvbikgewogIH0KfTsKdmFyIF9wcm9taXNlU3RyYXRlZ3kgPSBuZXcgUHJvbWlzZVN0cmF0ZWd5KCk7CnZhciBfc3Vic2NyaWJhYmxlU3RyYXRlZ3kgPSBuZXcgU3Vic2NyaWJhYmxlU3RyYXRlZ3koKTsKdmFyIF9Bc3luY1BpcGUgPSBjbGFzcyBfQXN5bmNQaXBlIHsKICBjb25zdHJ1Y3RvcihyZWYpIHsKICAgIHRoaXMuX2xhdGVzdFZhbHVlID0gbnVsbDsKICAgIHRoaXMubWFya0ZvckNoZWNrT25WYWx1ZVVwZGF0ZSA9IHRydWU7CiAgICB0aGlzLl9zdWJzY3JpcHRpb24gPSBudWxsOwogICAgdGhpcy5fb2JqID0gbnVsbDsKICAgIHRoaXMuX3N0cmF0ZWd5ID0gbnVsbDsKICAgIHRoaXMuX3JlZiA9IHJlZjsKICB9CiAgbmdPbkRlc3Ryb3koKSB7CiAgICBpZiAodGhpcy5fc3Vic2NyaXB0aW9uKSB7CiAgICAgIHRoaXMuX2Rpc3Bvc2UoKTsKICAgIH0KICAgIHRoaXMuX3JlZiA9IG51bGw7CiAgfQogIHRyYW5zZm9ybShvYmopIHsKICAgIGlmICghdGhpcy5fb2JqKSB7CiAgICAgIGlmIChvYmopIHsKICAgICAgICB0cnkgewogICAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2tPblZhbHVlVXBkYXRlID0gZmFsc2U7CiAgICAgICAgICB0aGlzLl9zdWJzY3JpYmUob2JqKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2tPblZhbHVlVXBkYXRlID0gdHJ1ZTsKICAgICAgICB9CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX2xhdGVzdFZhbHVlOwogICAgfQogICAgaWYgKG9iaiAhPT0gdGhpcy5fb2JqKSB7CiAgICAgIHRoaXMuX2Rpc3Bvc2UoKTsKICAgICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKG9iaik7CiAgICB9CiAgICByZXR1cm4gdGhpcy5fbGF0ZXN0VmFsdWU7CiAgfQogIF9zdWJzY3JpYmUob2JqKSB7CiAgICB0aGlzLl9vYmogPSBvYmo7CiAgICB0aGlzLl9zdHJhdGVneSA9IHRoaXMuX3NlbGVjdFN0cmF0ZWd5KG9iaik7CiAgICB0aGlzLl9zdWJzY3JpcHRpb24gPSB0aGlzLl9zdHJhdGVneS5jcmVhdGVTdWJzY3JpcHRpb24ob2JqLCAodmFsdWUpID0+IHRoaXMuX3VwZGF0ZUxhdGVzdFZhbHVlKG9iaiwgdmFsdWUpKTsKICB9CiAgX3NlbGVjdFN0cmF0ZWd5KG9iaikgewogICAgaWYgKGlzUHJvbWlzZShvYmopKSB7CiAgICAgIHJldHVybiBfcHJvbWlzZVN0cmF0ZWd5OwogICAgfQogICAgaWYgKGlzU3Vic2NyaWJhYmxlKG9iaikpIHsKICAgICAgcmV0dXJuIF9zdWJzY3JpYmFibGVTdHJhdGVneTsKICAgIH0KICAgIHRocm93IGludmFsaWRQaXBlQXJndW1lbnRFcnJvcihfQXN5bmNQaXBlLCBvYmopOwogIH0KICBfZGlzcG9zZSgpIHsKICAgIHRoaXMuX3N0cmF0ZWd5LmRpc3Bvc2UodGhpcy5fc3Vic2NyaXB0aW9uKTsKICAgIHRoaXMuX2xhdGVzdFZhbHVlID0gbnVsbDsKICAgIHRoaXMuX3N1YnNjcmlwdGlvbiA9IG51bGw7CiAgICB0aGlzLl9vYmogPSBudWxsOwogIH0KICBfdXBkYXRlTGF0ZXN0VmFsdWUoYXN5bmMsIHZhbHVlKSB7CiAgICBpZiAoYXN5bmMgPT09IHRoaXMuX29iaikgewogICAgICB0aGlzLl9sYXRlc3RWYWx1ZSA9IHZhbHVlOwogICAgICBpZiAodGhpcy5tYXJrRm9yQ2hlY2tPblZhbHVlVXBkYXRlKSB7CiAgICAgICAgdGhpcy5fcmVmPy5tYXJrRm9yQ2hlY2soKTsKICAgICAgfQogICAgfQogIH0KfTsKX0FzeW5jUGlwZS7JtWZhYyA9IGZ1bmN0aW9uIEFzeW5jUGlwZV9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9Bc3luY1BpcGUpKMm1ybVkaXJlY3RpdmVJbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYsIDE2KSk7Cn07Cl9Bc3luY1BpcGUuybVwaXBlID0gybXJtWRlZmluZVBpcGUoewogIG5hbWU6ICJhc3luYyIsCiAgdHlwZTogX0FzeW5jUGlwZSwKICBwdXJlOiBmYWxzZSwKICBzdGFuZGFsb25lOiB0cnVlCn0pOwp2YXIgQXN5bmNQaXBlID0gX0FzeW5jUGlwZTsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKEFzeW5jUGlwZSwgW3sKICAgIHR5cGU6IFBpcGUsCiAgICBhcmdzOiBbewogICAgICBuYW1lOiAiYXN5bmMiLAogICAgICBwdXJlOiBmYWxzZSwKICAgICAgc3RhbmRhbG9uZTogdHJ1ZQogICAgfV0KICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IENoYW5nZURldGVjdG9yUmVmCiAgfV0sIG51bGwpOwp9KSgpOwp2YXIgX0xvd2VyQ2FzZVBpcGUgPSBjbGFzcyBfTG93ZXJDYXNlUGlwZSB7CiAgdHJhbnNmb3JtKHZhbHVlKSB7CiAgICBpZiAodmFsdWUgPT0gbnVsbCkKICAgICAgcmV0dXJuIG51bGw7CiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAic3RyaW5nIikgewogICAgICB0aHJvdyBpbnZhbGlkUGlwZUFyZ3VtZW50RXJyb3IoX0xvd2VyQ2FzZVBpcGUsIHZhbHVlKTsKICAgIH0KICAgIHJldHVybiB2YWx1ZS50b0xvd2VyQ2FzZSgpOwogIH0KfTsKX0xvd2VyQ2FzZVBpcGUuybVmYWMgPSBmdW5jdGlvbiBMb3dlckNhc2VQaXBlX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0xvd2VyQ2FzZVBpcGUpKCk7Cn07Cl9Mb3dlckNhc2VQaXBlLsm1cGlwZSA9IMm1ybVkZWZpbmVQaXBlKHsKICBuYW1lOiAibG93ZXJjYXNlIiwKICB0eXBlOiBfTG93ZXJDYXNlUGlwZSwKICBwdXJlOiB0cnVlLAogIHN0YW5kYWxvbmU6IHRydWUKfSk7CnZhciBMb3dlckNhc2VQaXBlID0gX0xvd2VyQ2FzZVBpcGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShMb3dlckNhc2VQaXBlLCBbewogICAgdHlwZTogUGlwZSwKICAgIGFyZ3M6IFt7CiAgICAgIG5hbWU6ICJsb3dlcmNhc2UiLAogICAgICBzdGFuZGFsb25lOiB0cnVlCiAgICB9XQogIH1dLCBudWxsLCBudWxsKTsKfSkoKTsKdmFyIHVuaWNvZGVXb3JkTWF0Y2ggPSAvKD86WzAtOUEtWmEtelx4QUFceEI1XHhCQVx4QzAtXHhENlx4RDgtXHhGNlx4RjgtXHUwMkMxXHUwMkM2LVx1MDJEMVx1MDJFMC1cdTAyRTRcdTAyRUNcdTAyRUVcdTAzNzAtXHUwMzc0XHUwMzc2XHUwMzc3XHUwMzdBLVx1MDM3RFx1MDM3Rlx1MDM4Nlx1MDM4OC1cdTAzOEFcdTAzOENcdTAzOEUtXHUwM0ExXHUwM0EzLVx1MDNGNVx1MDNGNy1cdTA0ODFcdTA0OEEtXHUwNTJGXHUwNTMxLVx1MDU1Nlx1MDU1OVx1MDU2MC1cdTA1ODhcdTA1RDAtXHUwNUVBXHUwNUVGLVx1MDVGMlx1MDYyMC1cdTA2NEFcdTA2NkVcdTA2NkZcdTA2NzEtXHUwNkQzXHUwNkQ1XHUwNkU1XHUwNkU2XHUwNkVFXHUwNkVGXHUwNkZBLVx1MDZGQ1x1MDZGRlx1MDcxMFx1MDcxMi1cdTA3MkZcdTA3NEQtXHUwN0E1XHUwN0IxXHUwN0NBLVx1MDdFQVx1MDdGNFx1MDdGNVx1MDdGQVx1MDgwMC1cdTA4MTVcdTA4MUFcdTA4MjRcdTA4MjhcdTA4NDAtXHUwODU4XHUwODYwLVx1MDg2QVx1MDg3MC1cdTA4ODdcdTA4ODktXHUwODhFXHUwOEEwLVx1MDhDOVx1MDkwNC1cdTA5MzlcdTA5M0RcdTA5NTBcdTA5NTgtXHUwOTYxXHUwOTcxLVx1MDk4MFx1MDk4NS1cdTA5OENcdTA5OEZcdTA5OTBcdTA5OTMtXHUwOUE4XHUwOUFBLVx1MDlCMFx1MDlCMlx1MDlCNi1cdTA5QjlcdTA5QkRcdTA5Q0VcdTA5RENcdTA5RERcdTA5REYtXHUwOUUxXHUwOUYwXHUwOUYxXHUwOUZDXHUwQTA1LVx1MEEwQVx1MEEwRlx1MEExMFx1MEExMy1cdTBBMjhcdTBBMkEtXHUwQTMwXHUwQTMyXHUwQTMzXHUwQTM1XHUwQTM2XHUwQTM4XHUwQTM5XHUwQTU5LVx1MEE1Q1x1MEE1RVx1MEE3Mi1cdTBBNzRcdTBBODUtXHUwQThEXHUwQThGLVx1MEE5MVx1MEE5My1cdTBBQThcdTBBQUEtXHUwQUIwXHUwQUIyXHUwQUIzXHUwQUI1LVx1MEFCOVx1MEFCRFx1MEFEMFx1MEFFMFx1MEFFMVx1MEFGOVx1MEIwNS1cdTBCMENcdTBCMEZcdTBCMTBcdTBCMTMtXHUwQjI4XHUwQjJBLVx1MEIzMFx1MEIzMlx1MEIzM1x1MEIzNS1cdTBCMzlcdTBCM0RcdTBCNUNcdTBCNURcdTBCNUYtXHUwQjYxXHUwQjcxXHUwQjgzXHUwQjg1LVx1MEI4QVx1MEI4RS1cdTBCOTBcdTBCOTItXHUwQjk1XHUwQjk5XHUwQjlBXHUwQjlDXHUwQjlFXHUwQjlGXHUwQkEzXHUwQkE0XHUwQkE4LVx1MEJBQVx1MEJBRS1cdTBCQjlcdTBCRDBcdTBDMDUtXHUwQzBDXHUwQzBFLVx1MEMxMFx1MEMxMi1cdTBDMjhcdTBDMkEtXHUwQzM5XHUwQzNEXHUwQzU4LVx1MEM1QVx1MEM1RFx1MEM2MFx1MEM2MVx1MEM4MFx1MEM4NS1cdTBDOENcdTBDOEUtXHUwQzkwXHUwQzkyLVx1MENBOFx1MENBQS1cdTBDQjNcdTBDQjUtXHUwQ0I5XHUwQ0JEXHUwQ0REXHUwQ0RFXHUwQ0UwXHUwQ0UxXHUwQ0YxXHUwQ0YyXHUwRDA0LVx1MEQwQ1x1MEQwRS1cdTBEMTBcdTBEMTItXHUwRDNBXHUwRDNEXHUwRDRFXHUwRDU0LVx1MEQ1Nlx1MEQ1Ri1cdTBENjFcdTBEN0EtXHUwRDdGXHUwRDg1LVx1MEQ5Nlx1MEQ5QS1cdTBEQjFcdTBEQjMtXHUwREJCXHUwREJEXHUwREMwLVx1MERDNlx1MEUwMS1cdTBFMzBcdTBFMzJcdTBFMzNcdTBFNDAtXHUwRTQ2XHUwRTgxXHUwRTgyXHUwRTg0XHUwRTg2LVx1MEU4QVx1MEU4Qy1cdTBFQTNcdTBFQTVcdTBFQTctXHUwRUIwXHUwRUIyXHUwRUIzXHUwRUJEXHUwRUMwLVx1MEVDNFx1MEVDNlx1MEVEQy1cdTBFREZcdTBGMDBcdTBGNDAtXHUwRjQ3XHUwRjQ5LVx1MEY2Q1x1MEY4OC1cdTBGOENcdTEwMDAtXHUxMDJBXHUxMDNGXHUxMDUwLVx1MTA1NVx1MTA1QS1cdTEwNURcdTEwNjFcdTEwNjVcdTEwNjZcdTEwNkUtXHUxMDcwXHUxMDc1LVx1MTA4MVx1MTA4RVx1MTBBMC1cdTEwQzVcdTEwQzdcdTEwQ0RcdTEwRDAtXHUxMEZBXHUxMEZDLVx1MTI0OFx1MTI0QS1cdTEyNERcdTEyNTAtXHUxMjU2XHUxMjU4XHUxMjVBLVx1MTI1RFx1MTI2MC1cdTEyODhcdTEyOEEtXHUxMjhEXHUxMjkwLVx1MTJCMFx1MTJCMi1cdTEyQjVcdTEyQjgtXHUxMkJFXHUxMkMwXHUxMkMyLVx1MTJDNVx1MTJDOC1cdTEyRDZcdTEyRDgtXHUxMzEwXHUxMzEyLVx1MTMxNVx1MTMxOC1cdTEzNUFcdTEzODAtXHUxMzhGXHUxM0EwLVx1MTNGNVx1MTNGOC1cdTEzRkRcdTE0MDEtXHUxNjZDXHUxNjZGLVx1MTY3Rlx1MTY4MS1cdTE2OUFcdTE2QTAtXHUxNkVBXHUxNkYxLVx1MTZGOFx1MTcwMC1cdTE3MTFcdTE3MUYtXHUxNzMxXHUxNzQwLVx1MTc1MVx1MTc2MC1cdTE3NkNcdTE3NkUtXHUxNzcwXHUxNzgwLVx1MTdCM1x1MTdEN1x1MTdEQ1x1MTgyMC1cdTE4NzhcdTE4ODAtXHUxODg0XHUxODg3LVx1MThBOFx1MThBQVx1MThCMC1cdTE4RjVcdTE5MDAtXHUxOTFFXHUxOTUwLVx1MTk2RFx1MTk3MC1cdTE5NzRcdTE5ODAtXHUxOUFCXHUxOUIwLVx1MTlDOVx1MUEwMC1cdTFBMTZcdTFBMjAtXHUxQTU0XHUxQUE3XHUxQjA1LVx1MUIzM1x1MUI0NS1cdTFCNENcdTFCODMtXHUxQkEwXHUxQkFFXHUxQkFGXHUxQkJBLVx1MUJFNVx1MUMwMC1cdTFDMjNcdTFDNEQtXHUxQzRGXHUxQzVBLVx1MUM3RFx1MUM4MC1cdTFDODhcdTFDOTAtXHUxQ0JBXHUxQ0JELVx1MUNCRlx1MUNFOS1cdTFDRUNcdTFDRUUtXHUxQ0YzXHUxQ0Y1XHUxQ0Y2XHUxQ0ZBXHUxRDAwLVx1MURCRlx1MUUwMC1cdTFGMTVcdTFGMTgtXHUxRjFEXHUxRjIwLVx1MUY0NVx1MUY0OC1cdTFGNERcdTFGNTAtXHUxRjU3XHUxRjU5XHUxRjVCXHUxRjVEXHUxRjVGLVx1MUY3RFx1MUY4MC1cdTFGQjRcdTFGQjYtXHUxRkJDXHUxRkJFXHUxRkMyLVx1MUZDNFx1MUZDNi1cdTFGQ0NcdTFGRDAtXHUxRkQzXHUxRkQ2LVx1MUZEQlx1MUZFMC1cdTFGRUNcdTFGRjItXHUxRkY0XHUxRkY2LVx1MUZGQ1x1MjA3MVx1MjA3Rlx1MjA5MC1cdTIwOUNcdTIxMDJcdTIxMDdcdTIxMEEtXHUyMTEzXHUyMTE1XHUyMTE5LVx1MjExRFx1MjEyNFx1MjEyNlx1MjEyOFx1MjEyQS1cdTIxMkRcdTIxMkYtXHUyMTM5XHUyMTNDLVx1MjEzRlx1MjE0NS1cdTIxNDlcdTIxNEVcdTIxODNcdTIxODRcdTJDMDAtXHUyQ0U0XHUyQ0VCLVx1MkNFRVx1MkNGMlx1MkNGM1x1MkQwMC1cdTJEMjVcdTJEMjdcdTJEMkRcdTJEMzAtXHUyRDY3XHUyRDZGXHUyRDgwLVx1MkQ5Nlx1MkRBMC1cdTJEQTZcdTJEQTgtXHUyREFFXHUyREIwLVx1MkRCNlx1MkRCOC1cdTJEQkVcdTJEQzAtXHUyREM2XHUyREM4LVx1MkRDRVx1MkREMC1cdTJERDZcdTJERDgtXHUyRERFXHUyRTJGXHUzMDA1XHUzMDA2XHUzMDMxLVx1MzAzNVx1MzAzQlx1MzAzQ1x1MzA0MS1cdTMwOTZcdTMwOUQtXHUzMDlGXHUzMEExLVx1MzBGQVx1MzBGQy1cdTMwRkZcdTMxMDUtXHUzMTJGXHUzMTMxLVx1MzE4RVx1MzFBMC1cdTMxQkZcdTMxRjAtXHUzMUZGXHUzNDAwLVx1NERCRlx1NEUwMC1cdUE0OENcdUE0RDAtXHVBNEZEXHVBNTAwLVx1QTYwQ1x1QTYxMC1cdUE2MUZcdUE2MkFcdUE2MkJcdUE2NDAtXHVBNjZFXHVBNjdGLVx1QTY5RFx1QTZBMC1cdUE2RTVcdUE3MTctXHVBNzFGXHVBNzIyLVx1QTc4OFx1QTc4Qi1cdUE3Q0FcdUE3RDBcdUE3RDFcdUE3RDNcdUE3RDUtXHVBN0Q5XHVBN0YyLVx1QTgwMVx1QTgwMy1cdUE4MDVcdUE4MDctXHVBODBBXHVBODBDLVx1QTgyMlx1QTg0MC1cdUE4NzNcdUE4ODItXHVBOEIzXHVBOEYyLVx1QThGN1x1QThGQlx1QThGRFx1QThGRVx1QTkwQS1cdUE5MjVcdUE5MzAtXHVBOTQ2XHVBOTYwLVx1QTk3Q1x1QTk4NC1cdUE5QjJcdUE5Q0ZcdUE5RTAtXHVBOUU0XHVBOUU2LVx1QTlFRlx1QTlGQS1cdUE5RkVcdUFBMDAtXHVBQTI4XHVBQTQwLVx1QUE0Mlx1QUE0NC1cdUFBNEJcdUFBNjAtXHVBQTc2XHVBQTdBXHVBQTdFLVx1QUFBRlx1QUFCMVx1QUFCNVx1QUFCNlx1QUFCOS1cdUFBQkRcdUFBQzBcdUFBQzJcdUFBREItXHVBQUREXHVBQUUwLVx1QUFFQVx1QUFGMi1cdUFBRjRcdUFCMDEtXHVBQjA2XHVBQjA5LVx1QUIwRVx1QUIxMS1cdUFCMTZcdUFCMjAtXHVBQjI2XHVBQjI4LVx1QUIyRVx1QUIzMC1cdUFCNUFcdUFCNUMtXHVBQjY5XHVBQjcwLVx1QUJFMlx1QUMwMC1cdUQ3QTNcdUQ3QjAtXHVEN0M2XHVEN0NCLVx1RDdGQlx1RjkwMC1cdUZBNkRcdUZBNzAtXHVGQUQ5XHVGQjAwLVx1RkIwNlx1RkIxMy1cdUZCMTdcdUZCMURcdUZCMUYtXHVGQjI4XHVGQjJBLVx1RkIzNlx1RkIzOC1cdUZCM0NcdUZCM0VcdUZCNDBcdUZCNDFcdUZCNDNcdUZCNDRcdUZCNDYtXHVGQkIxXHVGQkQzLVx1RkQzRFx1RkQ1MC1cdUZEOEZcdUZEOTItXHVGREM3XHVGREYwLVx1RkRGQlx1RkU3MC1cdUZFNzRcdUZFNzYtXHVGRUZDXHVGRjIxLVx1RkYzQVx1RkY0MS1cdUZGNUFcdUZGNjYtXHVGRkJFXHVGRkMyLVx1RkZDN1x1RkZDQS1cdUZGQ0ZcdUZGRDItXHVGRkQ3XHVGRkRBLVx1RkZEQ118XHVEODAwW1x1REMwMC1cdURDMEJcdURDMEQtXHVEQzI2XHVEQzI4LVx1REMzQVx1REMzQ1x1REMzRFx1REMzRi1cdURDNERcdURDNTAtXHVEQzVEXHVEQzgwLVx1RENGQVx1REU4MC1cdURFOUNcdURFQTAtXHVERUQwXHVERjAwLVx1REYxRlx1REYyRC1cdURGNDBcdURGNDItXHVERjQ5XHVERjUwLVx1REY3NVx1REY4MC1cdURGOURcdURGQTAtXHVERkMzXHVERkM4LVx1REZDRl18XHVEODAxW1x1REMwMC1cdURDOURcdURDQjAtXHVEQ0QzXHVEQ0Q4LVx1RENGQlx1REQwMC1cdUREMjdcdUREMzAtXHVERDYzXHVERDcwLVx1REQ3QVx1REQ3Qy1cdUREOEFcdUREOEMtXHVERDkyXHVERDk0XHVERDk1XHVERDk3LVx1RERBMVx1RERBMy1cdUREQjFcdUREQjMtXHVEREI5XHVEREJCXHVEREJDXHVERTAwLVx1REYzNlx1REY0MC1cdURGNTVcdURGNjAtXHVERjY3XHVERjgwLVx1REY4NVx1REY4Ny1cdURGQjBcdURGQjItXHVERkJBXXxcdUQ4MDJbXHVEQzAwLVx1REMwNVx1REMwOFx1REMwQS1cdURDMzVcdURDMzdcdURDMzhcdURDM0NcdURDM0YtXHVEQzU1XHVEQzYwLVx1REM3Nlx1REM4MC1cdURDOUVcdURDRTAtXHVEQ0YyXHVEQ0Y0XHVEQ0Y1XHVERDAwLVx1REQxNVx1REQyMC1cdUREMzlcdUREODAtXHVEREI3XHVEREJFXHVEREJGXHVERTAwXHVERTEwLVx1REUxM1x1REUxNS1cdURFMTdcdURFMTktXHVERTM1XHVERTYwLVx1REU3Q1x1REU4MC1cdURFOUNcdURFQzAtXHVERUM3XHVERUM5LVx1REVFNFx1REYwMC1cdURGMzVcdURGNDAtXHVERjU1XHVERjYwLVx1REY3Mlx1REY4MC1cdURGOTFdfFx1RDgwM1tcdURDMDAtXHVEQzQ4XHVEQzgwLVx1RENCMlx1RENDMC1cdURDRjJcdUREMDAtXHVERDIzXHVERTgwLVx1REVBOVx1REVCMFx1REVCMVx1REYwMC1cdURGMUNcdURGMjdcdURGMzAtXHVERjQ1XHVERjcwLVx1REY4MVx1REZCMC1cdURGQzRcdURGRTAtXHVERkY2XXxcdUQ4MDRbXHVEQzAzLVx1REMzN1x1REM3MVx1REM3Mlx1REM3NVx1REM4My1cdURDQUZcdURDRDAtXHVEQ0U4XHVERDAzLVx1REQyNlx1REQ0NFx1REQ0N1x1REQ1MC1cdURENzJcdURENzZcdUREODMtXHVEREIyXHVEREMxLVx1RERDNFx1REREQVx1REREQ1x1REUwMC1cdURFMTFcdURFMTMtXHVERTJCXHVERTgwLVx1REU4Nlx1REU4OFx1REU4QS1cdURFOERcdURFOEYtXHVERTlEXHVERTlGLVx1REVBOFx1REVCMC1cdURFREVcdURGMDUtXHVERjBDXHVERjBGXHVERjEwXHVERjEzLVx1REYyOFx1REYyQS1cdURGMzBcdURGMzJcdURGMzNcdURGMzUtXHVERjM5XHVERjNEXHVERjUwXHVERjVELVx1REY2MV18XHVEODA1W1x1REMwMC1cdURDMzRcdURDNDctXHVEQzRBXHVEQzVGLVx1REM2MVx1REM4MC1cdURDQUZcdURDQzRcdURDQzVcdURDQzdcdUREODAtXHVEREFFXHVEREQ4LVx1REREQlx1REUwMC1cdURFMkZcdURFNDRcdURFODAtXHVERUFBXHVERUI4XHVERjAwLVx1REYxQVx1REY0MC1cdURGNDZdfFx1RDgwNltcdURDMDAtXHVEQzJCXHVEQ0EwLVx1RENERlx1RENGRi1cdUREMDZcdUREMDlcdUREMEMtXHVERDEzXHVERDE1XHVERDE2XHVERDE4LVx1REQyRlx1REQzRlx1REQ0MVx1RERBMC1cdUREQTdcdUREQUEtXHVEREQwXHVEREUxXHVEREUzXHVERTAwXHVERTBCLVx1REUzMlx1REUzQVx1REU1MFx1REU1Qy1cdURFODlcdURFOURcdURFQjAtXHVERUY4XXxcdUQ4MDdbXHVEQzAwLVx1REMwOFx1REMwQS1cdURDMkVcdURDNDBcdURDNzItXHVEQzhGXHVERDAwLVx1REQwNlx1REQwOFx1REQwOVx1REQwQi1cdUREMzBcdURENDZcdURENjAtXHVERDY1XHVERDY3XHVERDY4XHVERDZBLVx1REQ4OVx1REQ5OFx1REVFMC1cdURFRjJcdURGQjBdfFx1RDgwOFtcdURDMDAtXHVERjk5XXxcdUQ4MDlbXHVEQzgwLVx1REQ0M118XHVEODBCW1x1REY5MC1cdURGRjBdfFtcdUQ4MENcdUQ4MUMtXHVEODIwXHVEODIyXHVEODQwLVx1RDg2OFx1RDg2QS1cdUQ4NkNcdUQ4NkYtXHVEODcyXHVEODc0LVx1RDg3OVx1RDg4MC1cdUQ4ODNdW1x1REMwMC1cdURGRkZdfFx1RDgwRFtcdURDMDAtXHVEQzJFXXxcdUQ4MTFbXHVEQzAwLVx1REU0Nl18XHVEODFBW1x1REMwMC1cdURFMzhcdURFNDAtXHVERTVFXHVERTcwLVx1REVCRVx1REVEMC1cdURFRURcdURGMDAtXHVERjJGXHVERjQwLVx1REY0M1x1REY2My1cdURGNzdcdURGN0QtXHVERjhGXXxcdUQ4MUJbXHVERTQwLVx1REU3Rlx1REYwMC1cdURGNEFcdURGNTBcdURGOTMtXHVERjlGXHVERkUwXHVERkUxXHVERkUzXXxcdUQ4MjFbXHVEQzAwLVx1REZGN118XHVEODIzW1x1REMwMC1cdURDRDVcdUREMDAtXHVERDA4XXxcdUQ4MkJbXHVERkYwLVx1REZGM1x1REZGNS1cdURGRkJcdURGRkRcdURGRkVdfFx1RDgyQ1tcdURDMDAtXHVERDIyXHVERDUwLVx1REQ1Mlx1REQ2NC1cdURENjdcdURENzAtXHVERUZCXXxcdUQ4MkZbXHVEQzAwLVx1REM2QVx1REM3MC1cdURDN0NcdURDODAtXHVEQzg4XHVEQzkwLVx1REM5OV18XHVEODM1W1x1REMwMC1cdURDNTRcdURDNTYtXHVEQzlDXHVEQzlFXHVEQzlGXHVEQ0EyXHVEQ0E1XHVEQ0E2XHVEQ0E5LVx1RENBQ1x1RENBRS1cdURDQjlcdURDQkJcdURDQkQtXHVEQ0MzXHVEQ0M1LVx1REQwNVx1REQwNy1cdUREMEFcdUREMEQtXHVERDE0XHVERDE2LVx1REQxQ1x1REQxRS1cdUREMzlcdUREM0ItXHVERDNFXHVERDQwLVx1REQ0NFx1REQ0Nlx1REQ0QS1cdURENTBcdURENTItXHVERUE1XHVERUE4LVx1REVDMFx1REVDMi1cdURFREFcdURFREMtXHVERUZBXHVERUZDLVx1REYxNFx1REYxNi1cdURGMzRcdURGMzYtXHVERjRFXHVERjUwLVx1REY2RVx1REY3MC1cdURGODhcdURGOEEtXHVERkE4XHVERkFBLVx1REZDMlx1REZDNC1cdURGQ0JdfFx1RDgzN1tcdURGMDAtXHVERjFFXXxcdUQ4MzhbXHVERDAwLVx1REQyQ1x1REQzNy1cdUREM0RcdURENEVcdURFOTAtXHVERUFEXHVERUMwLVx1REVFQl18XHVEODM5W1x1REZFMC1cdURGRTZcdURGRTgtXHVERkVCXHVERkVEXHVERkVFXHVERkYwLVx1REZGRV18XHVEODNBW1x1REMwMC1cdURDQzRcdUREMDAtXHVERDQzXHVERDRCXXxcdUQ4M0JbXHVERTAwLVx1REUwM1x1REUwNS1cdURFMUZcdURFMjFcdURFMjJcdURFMjRcdURFMjdcdURFMjktXHVERTMyXHVERTM0LVx1REUzN1x1REUzOVx1REUzQlx1REU0Mlx1REU0N1x1REU0OVx1REU0Qlx1REU0RC1cdURFNEZcdURFNTFcdURFNTJcdURFNTRcdURFNTdcdURFNTlcdURFNUJcdURFNURcdURFNUZcdURFNjFcdURFNjJcdURFNjRcdURFNjctXHVERTZBXHVERTZDLVx1REU3Mlx1REU3NC1cdURFNzdcdURFNzktXHVERTdDXHVERTdFXHVERTgwLVx1REU4OVx1REU4Qi1cdURFOUJcdURFQTEtXHVERUEzXHVERUE1LVx1REVBOVx1REVBQi1cdURFQkJdfFx1RDg2OVtcdURDMDAtXHVERURGXHVERjAwLVx1REZGRl18XHVEODZEW1x1REMwMC1cdURGMzhcdURGNDAtXHVERkZGXXxcdUQ4NkVbXHVEQzAwLVx1REMxRFx1REMyMC1cdURGRkZdfFx1RDg3M1tcdURDMDAtXHVERUExXHVERUIwLVx1REZGRl18XHVEODdBW1x1REMwMC1cdURGRTBdfFx1RDg3RVtcdURDMDAtXHVERTFEXXxcdUQ4ODRbXHVEQzAwLVx1REY0QV0pXFMqL2c7CnZhciBfVGl0bGVDYXNlUGlwZSA9IGNsYXNzIF9UaXRsZUNhc2VQaXBlIHsKICB0cmFuc2Zvcm0odmFsdWUpIHsKICAgIGlmICh2YWx1ZSA9PSBudWxsKQogICAgICByZXR1cm4gbnVsbDsKICAgIGlmICh0eXBlb2YgdmFsdWUgIT09ICJzdHJpbmciKSB7CiAgICAgIHRocm93IGludmFsaWRQaXBlQXJndW1lbnRFcnJvcihfVGl0bGVDYXNlUGlwZSwgdmFsdWUpOwogICAgfQogICAgcmV0dXJuIHZhbHVlLnJlcGxhY2UodW5pY29kZVdvcmRNYXRjaCwgKHR4dCkgPT4gdHh0WzBdLnRvVXBwZXJDYXNlKCkgKyB0eHQuc2xpY2UoMSkudG9Mb3dlckNhc2UoKSk7CiAgfQp9OwpfVGl0bGVDYXNlUGlwZS7JtWZhYyA9IGZ1bmN0aW9uIFRpdGxlQ2FzZVBpcGVfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfVGl0bGVDYXNlUGlwZSkoKTsKfTsKX1RpdGxlQ2FzZVBpcGUuybVwaXBlID0gybXJtWRlZmluZVBpcGUoewogIG5hbWU6ICJ0aXRsZWNhc2UiLAogIHR5cGU6IF9UaXRsZUNhc2VQaXBlLAogIHB1cmU6IHRydWUsCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIFRpdGxlQ2FzZVBpcGUgPSBfVGl0bGVDYXNlUGlwZTsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKFRpdGxlQ2FzZVBpcGUsIFt7CiAgICB0eXBlOiBQaXBlLAogICAgYXJnczogW3sKICAgICAgbmFtZTogInRpdGxlY2FzZSIsCiAgICAgIHN0YW5kYWxvbmU6IHRydWUKICAgIH1dCiAgfV0sIG51bGwsIG51bGwpOwp9KSgpOwp2YXIgX1VwcGVyQ2FzZVBpcGUgPSBjbGFzcyBfVXBwZXJDYXNlUGlwZSB7CiAgdHJhbnNmb3JtKHZhbHVlKSB7CiAgICBpZiAodmFsdWUgPT0gbnVsbCkKICAgICAgcmV0dXJuIG51bGw7CiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAic3RyaW5nIikgewogICAgICB0aHJvdyBpbnZhbGlkUGlwZUFyZ3VtZW50RXJyb3IoX1VwcGVyQ2FzZVBpcGUsIHZhbHVlKTsKICAgIH0KICAgIHJldHVybiB2YWx1ZS50b1VwcGVyQ2FzZSgpOwogIH0KfTsKX1VwcGVyQ2FzZVBpcGUuybVmYWMgPSBmdW5jdGlvbiBVcHBlckNhc2VQaXBlX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX1VwcGVyQ2FzZVBpcGUpKCk7Cn07Cl9VcHBlckNhc2VQaXBlLsm1cGlwZSA9IMm1ybVkZWZpbmVQaXBlKHsKICBuYW1lOiAidXBwZXJjYXNlIiwKICB0eXBlOiBfVXBwZXJDYXNlUGlwZSwKICBwdXJlOiB0cnVlLAogIHN0YW5kYWxvbmU6IHRydWUKfSk7CnZhciBVcHBlckNhc2VQaXBlID0gX1VwcGVyQ2FzZVBpcGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShVcHBlckNhc2VQaXBlLCBbewogICAgdHlwZTogUGlwZSwKICAgIGFyZ3M6IFt7CiAgICAgIG5hbWU6ICJ1cHBlcmNhc2UiLAogICAgICBzdGFuZGFsb25lOiB0cnVlCiAgICB9XQogIH1dLCBudWxsLCBudWxsKTsKfSkoKTsKdmFyIERFRkFVTFRfREFURV9GT1JNQVQgPSAibWVkaXVtRGF0ZSI7CnZhciBEQVRFX1BJUEVfREVGQVVMVF9USU1FWk9ORSA9IG5ldyBJbmplY3Rpb25Ub2tlbihuZ0Rldk1vZGUgPyAiREFURV9QSVBFX0RFRkFVTFRfVElNRVpPTkUiIDogIiIpOwp2YXIgREFURV9QSVBFX0RFRkFVTFRfT1BUSU9OUyA9IG5ldyBJbmplY3Rpb25Ub2tlbihuZ0Rldk1vZGUgPyAiREFURV9QSVBFX0RFRkFVTFRfT1BUSU9OUyIgOiAiIik7CnZhciBfRGF0ZVBpcGUgPSBjbGFzcyBfRGF0ZVBpcGUgewogIGNvbnN0cnVjdG9yKGxvY2FsZSwgZGVmYXVsdFRpbWV6b25lLCBkZWZhdWx0T3B0aW9ucykgewogICAgdGhpcy5sb2NhbGUgPSBsb2NhbGU7CiAgICB0aGlzLmRlZmF1bHRUaW1lem9uZSA9IGRlZmF1bHRUaW1lem9uZTsKICAgIHRoaXMuZGVmYXVsdE9wdGlvbnMgPSBkZWZhdWx0T3B0aW9uczsKICB9CiAgdHJhbnNmb3JtKHZhbHVlLCBmb3JtYXQsIHRpbWV6b25lLCBsb2NhbGUpIHsKICAgIGlmICh2YWx1ZSA9PSBudWxsIHx8IHZhbHVlID09PSAiIiB8fCB2YWx1ZSAhPT0gdmFsdWUpCiAgICAgIHJldHVybiBudWxsOwogICAgdHJ5IHsKICAgICAgY29uc3QgX2Zvcm1hdCA9IGZvcm1hdCA/PyB0aGlzLmRlZmF1bHRPcHRpb25zPy5kYXRlRm9ybWF0ID8/IERFRkFVTFRfREFURV9GT1JNQVQ7CiAgICAgIGNvbnN0IF90aW1lem9uZSA9IHRpbWV6b25lID8/IHRoaXMuZGVmYXVsdE9wdGlvbnM/LnRpbWV6b25lID8/IHRoaXMuZGVmYXVsdFRpbWV6b25lID8/IHZvaWQgMDsKICAgICAgcmV0dXJuIGZvcm1hdERhdGUodmFsdWUsIF9mb3JtYXQsIGxvY2FsZSB8fCB0aGlzLmxvY2FsZSwgX3RpbWV6b25lKTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIHRocm93IGludmFsaWRQaXBlQXJndW1lbnRFcnJvcihfRGF0ZVBpcGUsIGVycm9yLm1lc3NhZ2UpOwogICAgfQogIH0KfTsKX0RhdGVQaXBlLsm1ZmFjID0gZnVuY3Rpb24gRGF0ZVBpcGVfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfRGF0ZVBpcGUpKMm1ybVkaXJlY3RpdmVJbmplY3QoTE9DQUxFX0lELCAxNiksIMm1ybVkaXJlY3RpdmVJbmplY3QoREFURV9QSVBFX0RFRkFVTFRfVElNRVpPTkUsIDI0KSwgybXJtWRpcmVjdGl2ZUluamVjdChEQVRFX1BJUEVfREVGQVVMVF9PUFRJT05TLCAyNCkpOwp9OwpfRGF0ZVBpcGUuybVwaXBlID0gybXJtWRlZmluZVBpcGUoewogIG5hbWU6ICJkYXRlIiwKICB0eXBlOiBfRGF0ZVBpcGUsCiAgcHVyZTogdHJ1ZSwKICBzdGFuZGFsb25lOiB0cnVlCn0pOwp2YXIgRGF0ZVBpcGUgPSBfRGF0ZVBpcGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShEYXRlUGlwZSwgW3sKICAgIHR5cGU6IFBpcGUsCiAgICBhcmdzOiBbewogICAgICBuYW1lOiAiZGF0ZSIsCiAgICAgIHN0YW5kYWxvbmU6IHRydWUKICAgIH1dCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtMT0NBTEVfSURdCiAgICB9XQogIH0sIHsKICAgIHR5cGU6IHZvaWQgMCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0RBVEVfUElQRV9ERUZBVUxUX1RJTUVaT05FXQogICAgfSwgewogICAgICB0eXBlOiBPcHRpb25hbAogICAgfV0KICB9LCB7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtEQVRFX1BJUEVfREVGQVVMVF9PUFRJT05TXQogICAgfSwgewogICAgICB0eXBlOiBPcHRpb25hbAogICAgfV0KICB9XSwgbnVsbCk7Cn0pKCk7CnZhciBfSU5URVJQT0xBVElPTl9SRUdFWFAgPSAvIy9nOwp2YXIgX0kxOG5QbHVyYWxQaXBlID0gY2xhc3MgX0kxOG5QbHVyYWxQaXBlIHsKICBjb25zdHJ1Y3RvcihfbG9jYWxpemF0aW9uKSB7CiAgICB0aGlzLl9sb2NhbGl6YXRpb24gPSBfbG9jYWxpemF0aW9uOwogIH0KICAvKioKICAgKiBAcGFyYW0gdmFsdWUgdGhlIG51bWJlciB0byBiZSBmb3JtYXR0ZWQKICAgKiBAcGFyYW0gcGx1cmFsTWFwIGFuIG9iamVjdCB0aGF0IG1pbWljcyB0aGUgSUNVIGZvcm1hdCwgc2VlCiAgICogaHR0cHM6Ly91bmljb2RlLW9yZy5naXRodWIuaW8vaWN1L3VzZXJndWlkZS9mb3JtYXRfcGFyc2UvbWVzc2FnZXMvLgogICAqIEBwYXJhbSBsb2NhbGUgYSBgc3RyaW5nYCBkZWZpbmluZyB0aGUgbG9jYWxlIHRvIHVzZSAodXNlcyB0aGUgY3VycmVudCB7QGxpbmsgTE9DQUxFX0lEfSBieQogICAqIGRlZmF1bHQpLgogICAqLwogIHRyYW5zZm9ybSh2YWx1ZSwgcGx1cmFsTWFwLCBsb2NhbGUpIHsKICAgIGlmICh2YWx1ZSA9PSBudWxsKQogICAgICByZXR1cm4gIiI7CiAgICBpZiAodHlwZW9mIHBsdXJhbE1hcCAhPT0gIm9iamVjdCIgfHwgcGx1cmFsTWFwID09PSBudWxsKSB7CiAgICAgIHRocm93IGludmFsaWRQaXBlQXJndW1lbnRFcnJvcihfSTE4blBsdXJhbFBpcGUsIHBsdXJhbE1hcCk7CiAgICB9CiAgICBjb25zdCBrZXkgPSBnZXRQbHVyYWxDYXRlZ29yeSh2YWx1ZSwgT2JqZWN0LmtleXMocGx1cmFsTWFwKSwgdGhpcy5fbG9jYWxpemF0aW9uLCBsb2NhbGUpOwogICAgcmV0dXJuIHBsdXJhbE1hcFtrZXldLnJlcGxhY2UoX0lOVEVSUE9MQVRJT05fUkVHRVhQLCB2YWx1ZS50b1N0cmluZygpKTsKICB9Cn07Cl9JMThuUGx1cmFsUGlwZS7JtWZhYyA9IGZ1bmN0aW9uIEkxOG5QbHVyYWxQaXBlX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0kxOG5QbHVyYWxQaXBlKSjJtcm1ZGlyZWN0aXZlSW5qZWN0KE5nTG9jYWxpemF0aW9uLCAxNikpOwp9OwpfSTE4blBsdXJhbFBpcGUuybVwaXBlID0gybXJtWRlZmluZVBpcGUoewogIG5hbWU6ICJpMThuUGx1cmFsIiwKICB0eXBlOiBfSTE4blBsdXJhbFBpcGUsCiAgcHVyZTogdHJ1ZSwKICBzdGFuZGFsb25lOiB0cnVlCn0pOwp2YXIgSTE4blBsdXJhbFBpcGUgPSBfSTE4blBsdXJhbFBpcGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShJMThuUGx1cmFsUGlwZSwgW3sKICAgIHR5cGU6IFBpcGUsCiAgICBhcmdzOiBbewogICAgICBuYW1lOiAiaTE4blBsdXJhbCIsCiAgICAgIHN0YW5kYWxvbmU6IHRydWUKICAgIH1dCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiBOZ0xvY2FsaXphdGlvbgogIH1dLCBudWxsKTsKfSkoKTsKdmFyIF9JMThuU2VsZWN0UGlwZSA9IGNsYXNzIF9JMThuU2VsZWN0UGlwZSB7CiAgLyoqCiAgICogQHBhcmFtIHZhbHVlIGEgc3RyaW5nIHRvIGJlIGludGVybmF0aW9uYWxpemVkLgogICAqIEBwYXJhbSBtYXBwaW5nIGFuIG9iamVjdCB0aGF0IGluZGljYXRlcyB0aGUgdGV4dCB0aGF0IHNob3VsZCBiZSBkaXNwbGF5ZWQKICAgKiBmb3IgZGlmZmVyZW50IHZhbHVlcyBvZiB0aGUgcHJvdmlkZWQgYHZhbHVlYC4KICAgKi8KICB0cmFuc2Zvcm0odmFsdWUsIG1hcHBpbmcpIHsKICAgIGlmICh2YWx1ZSA9PSBudWxsKQogICAgICByZXR1cm4gIiI7CiAgICBpZiAodHlwZW9mIG1hcHBpbmcgIT09ICJvYmplY3QiIHx8IHR5cGVvZiB2YWx1ZSAhPT0gInN0cmluZyIpIHsKICAgICAgdGhyb3cgaW52YWxpZFBpcGVBcmd1bWVudEVycm9yKF9JMThuU2VsZWN0UGlwZSwgbWFwcGluZyk7CiAgICB9CiAgICBpZiAobWFwcGluZy5oYXNPd25Qcm9wZXJ0eSh2YWx1ZSkpIHsKICAgICAgcmV0dXJuIG1hcHBpbmdbdmFsdWVdOwogICAgfQogICAgaWYgKG1hcHBpbmcuaGFzT3duUHJvcGVydHkoIm90aGVyIikpIHsKICAgICAgcmV0dXJuIG1hcHBpbmdbIm90aGVyIl07CiAgICB9CiAgICByZXR1cm4gIiI7CiAgfQp9OwpfSTE4blNlbGVjdFBpcGUuybVmYWMgPSBmdW5jdGlvbiBJMThuU2VsZWN0UGlwZV9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9JMThuU2VsZWN0UGlwZSkoKTsKfTsKX0kxOG5TZWxlY3RQaXBlLsm1cGlwZSA9IMm1ybVkZWZpbmVQaXBlKHsKICBuYW1lOiAiaTE4blNlbGVjdCIsCiAgdHlwZTogX0kxOG5TZWxlY3RQaXBlLAogIHB1cmU6IHRydWUsCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIEkxOG5TZWxlY3RQaXBlID0gX0kxOG5TZWxlY3RQaXBlOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoSTE4blNlbGVjdFBpcGUsIFt7CiAgICB0eXBlOiBQaXBlLAogICAgYXJnczogW3sKICAgICAgbmFtZTogImkxOG5TZWxlY3QiLAogICAgICBzdGFuZGFsb25lOiB0cnVlCiAgICB9XQogIH1dLCBudWxsLCBudWxsKTsKfSkoKTsKdmFyIF9Kc29uUGlwZSA9IGNsYXNzIF9Kc29uUGlwZSB7CiAgLyoqCiAgICogQHBhcmFtIHZhbHVlIEEgdmFsdWUgb2YgYW55IHR5cGUgdG8gY29udmVydCBpbnRvIGEgSlNPTi1mb3JtYXQgc3RyaW5nLgogICAqLwogIHRyYW5zZm9ybSh2YWx1ZSkgewogICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlLCBudWxsLCAyKTsKICB9Cn07Cl9Kc29uUGlwZS7JtWZhYyA9IGZ1bmN0aW9uIEpzb25QaXBlX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0pzb25QaXBlKSgpOwp9OwpfSnNvblBpcGUuybVwaXBlID0gybXJtWRlZmluZVBpcGUoewogIG5hbWU6ICJqc29uIiwKICB0eXBlOiBfSnNvblBpcGUsCiAgcHVyZTogZmFsc2UsCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIEpzb25QaXBlID0gX0pzb25QaXBlOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoSnNvblBpcGUsIFt7CiAgICB0eXBlOiBQaXBlLAogICAgYXJnczogW3sKICAgICAgbmFtZTogImpzb24iLAogICAgICBwdXJlOiBmYWxzZSwKICAgICAgc3RhbmRhbG9uZTogdHJ1ZQogICAgfV0KICB9XSwgbnVsbCwgbnVsbCk7Cn0pKCk7CmZ1bmN0aW9uIG1ha2VLZXlWYWx1ZVBhaXIoa2V5LCB2YWx1ZSkgewogIHJldHVybiB7CiAgICBrZXksCiAgICB2YWx1ZQogIH07Cn0KdmFyIF9LZXlWYWx1ZVBpcGUgPSBjbGFzcyBfS2V5VmFsdWVQaXBlIHsKICBjb25zdHJ1Y3RvcihkaWZmZXJzKSB7CiAgICB0aGlzLmRpZmZlcnMgPSBkaWZmZXJzOwogICAgdGhpcy5rZXlWYWx1ZXMgPSBbXTsKICAgIHRoaXMuY29tcGFyZUZuID0gZGVmYXVsdENvbXBhcmF0b3I7CiAgfQogIHRyYW5zZm9ybShpbnB1dCwgY29tcGFyZUZuID0gZGVmYXVsdENvbXBhcmF0b3IpIHsKICAgIGlmICghaW5wdXQgfHwgIShpbnB1dCBpbnN0YW5jZW9mIE1hcCkgJiYgdHlwZW9mIGlucHV0ICE9PSAib2JqZWN0IikgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIHRoaXMuZGlmZmVyID8/PSB0aGlzLmRpZmZlcnMuZmluZChpbnB1dCkuY3JlYXRlKCk7CiAgICBjb25zdCBkaWZmZXJDaGFuZ2VzID0gdGhpcy5kaWZmZXIuZGlmZihpbnB1dCk7CiAgICBjb25zdCBjb21wYXJlRm5DaGFuZ2VkID0gY29tcGFyZUZuICE9PSB0aGlzLmNvbXBhcmVGbjsKICAgIGlmIChkaWZmZXJDaGFuZ2VzKSB7CiAgICAgIHRoaXMua2V5VmFsdWVzID0gW107CiAgICAgIGRpZmZlckNoYW5nZXMuZm9yRWFjaEl0ZW0oKHIpID0+IHsKICAgICAgICB0aGlzLmtleVZhbHVlcy5wdXNoKG1ha2VLZXlWYWx1ZVBhaXIoci5rZXksIHIuY3VycmVudFZhbHVlKSk7CiAgICAgIH0pOwogICAgfQogICAgaWYgKGRpZmZlckNoYW5nZXMgfHwgY29tcGFyZUZuQ2hhbmdlZCkgewogICAgICB0aGlzLmtleVZhbHVlcy5zb3J0KGNvbXBhcmVGbik7CiAgICAgIHRoaXMuY29tcGFyZUZuID0gY29tcGFyZUZuOwogICAgfQogICAgcmV0dXJuIHRoaXMua2V5VmFsdWVzOwogIH0KfTsKX0tleVZhbHVlUGlwZS7JtWZhYyA9IGZ1bmN0aW9uIEtleVZhbHVlUGlwZV9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9LZXlWYWx1ZVBpcGUpKMm1ybVkaXJlY3RpdmVJbmplY3QoS2V5VmFsdWVEaWZmZXJzLCAxNikpOwp9OwpfS2V5VmFsdWVQaXBlLsm1cGlwZSA9IMm1ybVkZWZpbmVQaXBlKHsKICBuYW1lOiAia2V5dmFsdWUiLAogIHR5cGU6IF9LZXlWYWx1ZVBpcGUsCiAgcHVyZTogZmFsc2UsCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIEtleVZhbHVlUGlwZSA9IF9LZXlWYWx1ZVBpcGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShLZXlWYWx1ZVBpcGUsIFt7CiAgICB0eXBlOiBQaXBlLAogICAgYXJnczogW3sKICAgICAgbmFtZTogImtleXZhbHVlIiwKICAgICAgcHVyZTogZmFsc2UsCiAgICAgIHN0YW5kYWxvbmU6IHRydWUKICAgIH1dCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiBLZXlWYWx1ZURpZmZlcnMKICB9XSwgbnVsbCk7Cn0pKCk7CmZ1bmN0aW9uIGRlZmF1bHRDb21wYXJhdG9yKGtleVZhbHVlQSwga2V5VmFsdWVCKSB7CiAgY29uc3QgYSA9IGtleVZhbHVlQS5rZXk7CiAgY29uc3QgYiA9IGtleVZhbHVlQi5rZXk7CiAgaWYgKGEgPT09IGIpCiAgICByZXR1cm4gMDsKICBpZiAoYSA9PT0gdm9pZCAwKQogICAgcmV0dXJuIDE7CiAgaWYgKGIgPT09IHZvaWQgMCkKICAgIHJldHVybiAtMTsKICBpZiAoYSA9PT0gbnVsbCkKICAgIHJldHVybiAxOwogIGlmIChiID09PSBudWxsKQogICAgcmV0dXJuIC0xOwogIGlmICh0eXBlb2YgYSA9PSAic3RyaW5nIiAmJiB0eXBlb2YgYiA9PSAic3RyaW5nIikgewogICAgcmV0dXJuIGEgPCBiID8gLTEgOiAxOwogIH0KICBpZiAodHlwZW9mIGEgPT0gIm51bWJlciIgJiYgdHlwZW9mIGIgPT0gIm51bWJlciIpIHsKICAgIHJldHVybiBhIC0gYjsKICB9CiAgaWYgKHR5cGVvZiBhID09ICJib29sZWFuIiAmJiB0eXBlb2YgYiA9PSAiYm9vbGVhbiIpIHsKICAgIHJldHVybiBhIDwgYiA/IC0xIDogMTsKICB9CiAgY29uc3QgYVN0cmluZyA9IFN0cmluZyhhKTsKICBjb25zdCBiU3RyaW5nID0gU3RyaW5nKGIpOwogIHJldHVybiBhU3RyaW5nID09IGJTdHJpbmcgPyAwIDogYVN0cmluZyA8IGJTdHJpbmcgPyAtMSA6IDE7Cn0KdmFyIF9EZWNpbWFsUGlwZSA9IGNsYXNzIF9EZWNpbWFsUGlwZSB7CiAgY29uc3RydWN0b3IoX2xvY2FsZSkgewogICAgdGhpcy5fbG9jYWxlID0gX2xvY2FsZTsKICB9CiAgLyoqCiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBiZSBmb3JtYXR0ZWQuCiAgICogQHBhcmFtIGRpZ2l0c0luZm8gU2V0cyBkaWdpdCBhbmQgZGVjaW1hbCByZXByZXNlbnRhdGlvbi4KICAgKiBbU2VlIG1vcmVdKCNkaWdpdHNpbmZvKS4KICAgKiBAcGFyYW0gbG9jYWxlIFNwZWNpZmllcyB3aGF0IGxvY2FsZSBmb3JtYXQgcnVsZXMgdG8gdXNlLgogICAqIFtTZWUgbW9yZV0oI2xvY2FsZSkuCiAgICovCiAgdHJhbnNmb3JtKHZhbHVlLCBkaWdpdHNJbmZvLCBsb2NhbGUpIHsKICAgIGlmICghaXNWYWx1ZSh2YWx1ZSkpCiAgICAgIHJldHVybiBudWxsOwogICAgbG9jYWxlIHx8PSB0aGlzLl9sb2NhbGU7CiAgICB0cnkgewogICAgICBjb25zdCBudW0gPSBzdHJUb051bWJlcih2YWx1ZSk7CiAgICAgIHJldHVybiBmb3JtYXROdW1iZXIobnVtLCBsb2NhbGUsIGRpZ2l0c0luZm8pOwogICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgdGhyb3cgaW52YWxpZFBpcGVBcmd1bWVudEVycm9yKF9EZWNpbWFsUGlwZSwgZXJyb3IubWVzc2FnZSk7CiAgICB9CiAgfQp9OwpfRGVjaW1hbFBpcGUuybVmYWMgPSBmdW5jdGlvbiBEZWNpbWFsUGlwZV9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9EZWNpbWFsUGlwZSkoybXJtWRpcmVjdGl2ZUluamVjdChMT0NBTEVfSUQsIDE2KSk7Cn07Cl9EZWNpbWFsUGlwZS7JtXBpcGUgPSDJtcm1ZGVmaW5lUGlwZSh7CiAgbmFtZTogIm51bWJlciIsCiAgdHlwZTogX0RlY2ltYWxQaXBlLAogIHB1cmU6IHRydWUsCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIERlY2ltYWxQaXBlID0gX0RlY2ltYWxQaXBlOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoRGVjaW1hbFBpcGUsIFt7CiAgICB0eXBlOiBQaXBlLAogICAgYXJnczogW3sKICAgICAgbmFtZTogIm51bWJlciIsCiAgICAgIHN0YW5kYWxvbmU6IHRydWUKICAgIH1dCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtMT0NBTEVfSURdCiAgICB9XQogIH1dLCBudWxsKTsKfSkoKTsKdmFyIF9QZXJjZW50UGlwZSA9IGNsYXNzIF9QZXJjZW50UGlwZSB7CiAgY29uc3RydWN0b3IoX2xvY2FsZSkgewogICAgdGhpcy5fbG9jYWxlID0gX2xvY2FsZTsKICB9CiAgLyoqCiAgICoKICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciB0byBiZSBmb3JtYXR0ZWQgYXMgYSBwZXJjZW50YWdlLgogICAqIEBwYXJhbSBkaWdpdHNJbmZvIERlY2ltYWwgcmVwcmVzZW50YXRpb24gb3B0aW9ucywgc3BlY2lmaWVkIGJ5IGEgc3RyaW5nCiAgICogaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6PGJyPgogICAqIDxjb2RlPnttaW5JbnRlZ2VyRGlnaXRzfS57bWluRnJhY3Rpb25EaWdpdHN9LXttYXhGcmFjdGlvbkRpZ2l0c308L2NvZGU+LgogICAqICAgLSBgbWluSW50ZWdlckRpZ2l0c2A6IFRoZSBtaW5pbXVtIG51bWJlciBvZiBpbnRlZ2VyIGRpZ2l0cyBiZWZvcmUgdGhlIGRlY2ltYWwgcG9pbnQuCiAgICogRGVmYXVsdCBpcyBgMWAuCiAgICogICAtIGBtaW5GcmFjdGlvbkRpZ2l0c2A6IFRoZSBtaW5pbXVtIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuCiAgICogRGVmYXVsdCBpcyBgMGAuCiAgICogICAtIGBtYXhGcmFjdGlvbkRpZ2l0c2A6IFRoZSBtYXhpbXVtIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuCiAgICogRGVmYXVsdCBpcyBgMGAuCiAgICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlIGZvciB0aGUgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuCiAgICogV2hlbiBub3Qgc3VwcGxpZWQsIHVzZXMgdGhlIHZhbHVlIG9mIGBMT0NBTEVfSURgLCB3aGljaCBpcyBgZW4tVVNgIGJ5IGRlZmF1bHQuCiAgICogU2VlIFtTZXR0aW5nIHlvdXIgYXBwIGxvY2FsZV0oZ3VpZGUvaTE4bi9sb2NhbGUtaWQpLgogICAqLwogIHRyYW5zZm9ybSh2YWx1ZSwgZGlnaXRzSW5mbywgbG9jYWxlKSB7CiAgICBpZiAoIWlzVmFsdWUodmFsdWUpKQogICAgICByZXR1cm4gbnVsbDsKICAgIGxvY2FsZSB8fD0gdGhpcy5fbG9jYWxlOwogICAgdHJ5IHsKICAgICAgY29uc3QgbnVtID0gc3RyVG9OdW1iZXIodmFsdWUpOwogICAgICByZXR1cm4gZm9ybWF0UGVyY2VudChudW0sIGxvY2FsZSwgZGlnaXRzSW5mbyk7CiAgICB9IGNhdGNoIChlcnJvcikgewogICAgICB0aHJvdyBpbnZhbGlkUGlwZUFyZ3VtZW50RXJyb3IoX1BlcmNlbnRQaXBlLCBlcnJvci5tZXNzYWdlKTsKICAgIH0KICB9Cn07Cl9QZXJjZW50UGlwZS7JtWZhYyA9IGZ1bmN0aW9uIFBlcmNlbnRQaXBlX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX1BlcmNlbnRQaXBlKSjJtcm1ZGlyZWN0aXZlSW5qZWN0KExPQ0FMRV9JRCwgMTYpKTsKfTsKX1BlcmNlbnRQaXBlLsm1cGlwZSA9IMm1ybVkZWZpbmVQaXBlKHsKICBuYW1lOiAicGVyY2VudCIsCiAgdHlwZTogX1BlcmNlbnRQaXBlLAogIHB1cmU6IHRydWUsCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIFBlcmNlbnRQaXBlID0gX1BlcmNlbnRQaXBlOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoUGVyY2VudFBpcGUsIFt7CiAgICB0eXBlOiBQaXBlLAogICAgYXJnczogW3sKICAgICAgbmFtZTogInBlcmNlbnQiLAogICAgICBzdGFuZGFsb25lOiB0cnVlCiAgICB9XQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogdm9pZCAwLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogSW5qZWN0LAogICAgICBhcmdzOiBbTE9DQUxFX0lEXQogICAgfV0KICB9XSwgbnVsbCk7Cn0pKCk7CnZhciBfQ3VycmVuY3lQaXBlID0gY2xhc3MgX0N1cnJlbmN5UGlwZSB7CiAgY29uc3RydWN0b3IoX2xvY2FsZSwgX2RlZmF1bHRDdXJyZW5jeUNvZGUgPSAiVVNEIikgewogICAgdGhpcy5fbG9jYWxlID0gX2xvY2FsZTsKICAgIHRoaXMuX2RlZmF1bHRDdXJyZW5jeUNvZGUgPSBfZGVmYXVsdEN1cnJlbmN5Q29kZTsKICB9CiAgLyoqCiAgICoKICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciB0byBiZSBmb3JtYXR0ZWQgYXMgY3VycmVuY3kuCiAgICogQHBhcmFtIGN1cnJlbmN5Q29kZSBUaGUgW0lTTyA0MjE3XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fNDIxNykgY3VycmVuY3kgY29kZSwKICAgKiBzdWNoIGFzIGBVU0RgIGZvciB0aGUgVVMgZG9sbGFyIGFuZCBgRVVSYCBmb3IgdGhlIGV1cm8uIFRoZSBkZWZhdWx0IGN1cnJlbmN5IGNvZGUgY2FuIGJlCiAgICogY29uZmlndXJlZCB1c2luZyB0aGUgYERFRkFVTFRfQ1VSUkVOQ1lfQ09ERWAgaW5qZWN0aW9uIHRva2VuLgogICAqIEBwYXJhbSBkaXNwbGF5IFRoZSBmb3JtYXQgZm9yIHRoZSBjdXJyZW5jeSBpbmRpY2F0b3IuIE9uZSBvZiB0aGUgZm9sbG93aW5nOgogICAqICAgLSBgY29kZWA6IFNob3cgdGhlIGNvZGUgKHN1Y2ggYXMgYFVTRGApLgogICAqICAgLSBgc3ltYm9sYChkZWZhdWx0KTogU2hvdyB0aGUgc3ltYm9sIChzdWNoIGFzIGAkYCkuCiAgICogICAtIGBzeW1ib2wtbmFycm93YDogVXNlIHRoZSBuYXJyb3cgc3ltYm9sIGZvciBsb2NhbGVzIHRoYXQgaGF2ZSB0d28gc3ltYm9scyBmb3IgdGhlaXIKICAgKiBjdXJyZW5jeS4KICAgKiBGb3IgZXhhbXBsZSwgdGhlIENhbmFkaWFuIGRvbGxhciBDQUQgaGFzIHRoZSBzeW1ib2wgYENBJGAgYW5kIHRoZSBzeW1ib2wtbmFycm93IGAkYC4gSWYgdGhlCiAgICogbG9jYWxlIGhhcyBubyBuYXJyb3cgc3ltYm9sLCB1c2VzIHRoZSBzdGFuZGFyZCBzeW1ib2wgZm9yIHRoZSBsb2NhbGUuCiAgICogICAtIFN0cmluZzogVXNlIHRoZSBnaXZlbiBzdHJpbmcgdmFsdWUgaW5zdGVhZCBvZiBhIGNvZGUgb3IgYSBzeW1ib2wuCiAgICogRm9yIGV4YW1wbGUsIGFuIGVtcHR5IHN0cmluZyB3aWxsIHN1cHByZXNzIHRoZSBjdXJyZW5jeSAmIHN5bWJvbC4KICAgKiAgIC0gQm9vbGVhbiAobWFya2VkIGRlcHJlY2F0ZWQgaW4gdjUpOiBgdHJ1ZWAgZm9yIHN5bWJvbCBhbmQgZmFsc2UgZm9yIGBjb2RlYC4KICAgKgogICAqIEBwYXJhbSBkaWdpdHNJbmZvIERlY2ltYWwgcmVwcmVzZW50YXRpb24gb3B0aW9ucywgc3BlY2lmaWVkIGJ5IGEgc3RyaW5nCiAgICogaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6PGJyPgogICAqIDxjb2RlPnttaW5JbnRlZ2VyRGlnaXRzfS57bWluRnJhY3Rpb25EaWdpdHN9LXttYXhGcmFjdGlvbkRpZ2l0c308L2NvZGU+LgogICAqICAgLSBgbWluSW50ZWdlckRpZ2l0c2A6IFRoZSBtaW5pbXVtIG51bWJlciBvZiBpbnRlZ2VyIGRpZ2l0cyBiZWZvcmUgdGhlIGRlY2ltYWwgcG9pbnQuCiAgICogRGVmYXVsdCBpcyBgMWAuCiAgICogICAtIGBtaW5GcmFjdGlvbkRpZ2l0c2A6IFRoZSBtaW5pbXVtIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuCiAgICogRGVmYXVsdCBpcyBgMmAuCiAgICogICAtIGBtYXhGcmFjdGlvbkRpZ2l0c2A6IFRoZSBtYXhpbXVtIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuCiAgICogRGVmYXVsdCBpcyBgMmAuCiAgICogSWYgbm90IHByb3ZpZGVkLCB0aGUgbnVtYmVyIHdpbGwgYmUgZm9ybWF0dGVkIHdpdGggdGhlIHByb3BlciBhbW91bnQgb2YgZGlnaXRzLAogICAqIGRlcGVuZGluZyBvbiB3aGF0IHRoZSBbSVNPIDQyMTddKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0lTT180MjE3KSBzcGVjaWZpZXMuCiAgICogRm9yIGV4YW1wbGUsIHRoZSBDYW5hZGlhbiBkb2xsYXIgaGFzIDIgZGlnaXRzLCB3aGVyZWFzIHRoZSBDaGlsZWFuIHBlc28gaGFzIG5vbmUuCiAgICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlIGZvciB0aGUgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuCiAgICogV2hlbiBub3Qgc3VwcGxpZWQsIHVzZXMgdGhlIHZhbHVlIG9mIGBMT0NBTEVfSURgLCB3aGljaCBpcyBgZW4tVVNgIGJ5IGRlZmF1bHQuCiAgICogU2VlIFtTZXR0aW5nIHlvdXIgYXBwIGxvY2FsZV0oZ3VpZGUvaTE4bi9sb2NhbGUtaWQpLgogICAqLwogIHRyYW5zZm9ybSh2YWx1ZSwgY3VycmVuY3lDb2RlID0gdGhpcy5fZGVmYXVsdEN1cnJlbmN5Q29kZSwgZGlzcGxheSA9ICJzeW1ib2wiLCBkaWdpdHNJbmZvLCBsb2NhbGUpIHsKICAgIGlmICghaXNWYWx1ZSh2YWx1ZSkpCiAgICAgIHJldHVybiBudWxsOwogICAgbG9jYWxlIHx8PSB0aGlzLl9sb2NhbGU7CiAgICBpZiAodHlwZW9mIGRpc3BsYXkgPT09ICJib29sZWFuIikgewogICAgICBpZiAoKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgY29uc29sZSAmJiBjb25zb2xlLndhcm4pIHsKICAgICAgICBjb25zb2xlLndhcm4oYFdhcm5pbmc6IHRoZSBjdXJyZW5jeSBwaXBlIGhhcyBiZWVuIGNoYW5nZWQgaW4gQW5ndWxhciB2NS4gVGhlIHN5bWJvbERpc3BsYXkgb3B0aW9uICh0aGlyZCBwYXJhbWV0ZXIpIGlzIG5vdyBhIHN0cmluZyBpbnN0ZWFkIG9mIGEgYm9vbGVhbi4gVGhlIGFjY2VwdGVkIHZhbHVlcyBhcmUgImNvZGUiLCAic3ltYm9sIiBvciAic3ltYm9sLW5hcnJvdyIuYCk7CiAgICAgIH0KICAgICAgZGlzcGxheSA9IGRpc3BsYXkgPyAic3ltYm9sIiA6ICJjb2RlIjsKICAgIH0KICAgIGxldCBjdXJyZW5jeSA9IGN1cnJlbmN5Q29kZSB8fCB0aGlzLl9kZWZhdWx0Q3VycmVuY3lDb2RlOwogICAgaWYgKGRpc3BsYXkgIT09ICJjb2RlIikgewogICAgICBpZiAoZGlzcGxheSA9PT0gInN5bWJvbCIgfHwgZGlzcGxheSA9PT0gInN5bWJvbC1uYXJyb3ciKSB7CiAgICAgICAgY3VycmVuY3kgPSBnZXRDdXJyZW5jeVN5bWJvbChjdXJyZW5jeSwgZGlzcGxheSA9PT0gInN5bWJvbCIgPyAid2lkZSIgOiAibmFycm93IiwgbG9jYWxlKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBjdXJyZW5jeSA9IGRpc3BsYXk7CiAgICAgIH0KICAgIH0KICAgIHRyeSB7CiAgICAgIGNvbnN0IG51bSA9IHN0clRvTnVtYmVyKHZhbHVlKTsKICAgICAgcmV0dXJuIGZvcm1hdEN1cnJlbmN5KG51bSwgbG9jYWxlLCBjdXJyZW5jeSwgY3VycmVuY3lDb2RlLCBkaWdpdHNJbmZvKTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIHRocm93IGludmFsaWRQaXBlQXJndW1lbnRFcnJvcihfQ3VycmVuY3lQaXBlLCBlcnJvci5tZXNzYWdlKTsKICAgIH0KICB9Cn07Cl9DdXJyZW5jeVBpcGUuybVmYWMgPSBmdW5jdGlvbiBDdXJyZW5jeVBpcGVfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfQ3VycmVuY3lQaXBlKSjJtcm1ZGlyZWN0aXZlSW5qZWN0KExPQ0FMRV9JRCwgMTYpLCDJtcm1ZGlyZWN0aXZlSW5qZWN0KERFRkFVTFRfQ1VSUkVOQ1lfQ09ERSwgMTYpKTsKfTsKX0N1cnJlbmN5UGlwZS7JtXBpcGUgPSDJtcm1ZGVmaW5lUGlwZSh7CiAgbmFtZTogImN1cnJlbmN5IiwKICB0eXBlOiBfQ3VycmVuY3lQaXBlLAogIHB1cmU6IHRydWUsCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIEN1cnJlbmN5UGlwZSA9IF9DdXJyZW5jeVBpcGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShDdXJyZW5jeVBpcGUsIFt7CiAgICB0eXBlOiBQaXBlLAogICAgYXJnczogW3sKICAgICAgbmFtZTogImN1cnJlbmN5IiwKICAgICAgc3RhbmRhbG9uZTogdHJ1ZQogICAgfV0KICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IHZvaWQgMCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0xPQ0FMRV9JRF0KICAgIH1dCiAgfSwgewogICAgdHlwZTogdm9pZCAwLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogSW5qZWN0LAogICAgICBhcmdzOiBbREVGQVVMVF9DVVJSRU5DWV9DT0RFXQogICAgfV0KICB9XSwgbnVsbCk7Cn0pKCk7CmZ1bmN0aW9uIGlzVmFsdWUodmFsdWUpIHsKICByZXR1cm4gISh2YWx1ZSA9PSBudWxsIHx8IHZhbHVlID09PSAiIiB8fCB2YWx1ZSAhPT0gdmFsdWUpOwp9CmZ1bmN0aW9uIHN0clRvTnVtYmVyKHZhbHVlKSB7CiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gInN0cmluZyIgJiYgIWlzTmFOKE51bWJlcih2YWx1ZSkgLSBwYXJzZUZsb2F0KHZhbHVlKSkpIHsKICAgIHJldHVybiBOdW1iZXIodmFsdWUpOwogIH0KICBpZiAodHlwZW9mIHZhbHVlICE9PSAibnVtYmVyIikgewogICAgdGhyb3cgbmV3IEVycm9yKGAke3ZhbHVlfSBpcyBub3QgYSBudW1iZXJgKTsKICB9CiAgcmV0dXJuIHZhbHVlOwp9CnZhciBfU2xpY2VQaXBlID0gY2xhc3MgX1NsaWNlUGlwZSB7CiAgdHJhbnNmb3JtKHZhbHVlLCBzdGFydCwgZW5kKSB7CiAgICBpZiAodmFsdWUgPT0gbnVsbCkKICAgICAgcmV0dXJuIG51bGw7CiAgICBpZiAoIXRoaXMuc3VwcG9ydHModmFsdWUpKSB7CiAgICAgIHRocm93IGludmFsaWRQaXBlQXJndW1lbnRFcnJvcihfU2xpY2VQaXBlLCB2YWx1ZSk7CiAgICB9CiAgICByZXR1cm4gdmFsdWUuc2xpY2Uoc3RhcnQsIGVuZCk7CiAgfQogIHN1cHBvcnRzKG9iaikgewogICAgcmV0dXJuIHR5cGVvZiBvYmogPT09ICJzdHJpbmciIHx8IEFycmF5LmlzQXJyYXkob2JqKTsKICB9Cn07Cl9TbGljZVBpcGUuybVmYWMgPSBmdW5jdGlvbiBTbGljZVBpcGVfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfU2xpY2VQaXBlKSgpOwp9OwpfU2xpY2VQaXBlLsm1cGlwZSA9IMm1ybVkZWZpbmVQaXBlKHsKICBuYW1lOiAic2xpY2UiLAogIHR5cGU6IF9TbGljZVBpcGUsCiAgcHVyZTogZmFsc2UsCiAgc3RhbmRhbG9uZTogdHJ1ZQp9KTsKdmFyIFNsaWNlUGlwZSA9IF9TbGljZVBpcGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShTbGljZVBpcGUsIFt7CiAgICB0eXBlOiBQaXBlLAogICAgYXJnczogW3sKICAgICAgbmFtZTogInNsaWNlIiwKICAgICAgcHVyZTogZmFsc2UsCiAgICAgIHN0YW5kYWxvbmU6IHRydWUKICAgIH1dCiAgfV0sIG51bGwsIG51bGwpOwp9KSgpOwp2YXIgQ09NTU9OX1BJUEVTID0gW0FzeW5jUGlwZSwgVXBwZXJDYXNlUGlwZSwgTG93ZXJDYXNlUGlwZSwgSnNvblBpcGUsIFNsaWNlUGlwZSwgRGVjaW1hbFBpcGUsIFBlcmNlbnRQaXBlLCBUaXRsZUNhc2VQaXBlLCBDdXJyZW5jeVBpcGUsIERhdGVQaXBlLCBJMThuUGx1cmFsUGlwZSwgSTE4blNlbGVjdFBpcGUsIEtleVZhbHVlUGlwZV07CnZhciBfQ29tbW9uTW9kdWxlID0gY2xhc3MgX0NvbW1vbk1vZHVsZSB7Cn07Cl9Db21tb25Nb2R1bGUuybVmYWMgPSBmdW5jdGlvbiBDb21tb25Nb2R1bGVfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfQ29tbW9uTW9kdWxlKSgpOwp9OwpfQ29tbW9uTW9kdWxlLsm1bW9kID0gybXJtWRlZmluZU5nTW9kdWxlKHsKICB0eXBlOiBfQ29tbW9uTW9kdWxlLAogIGltcG9ydHM6IFtOZ0NsYXNzLCBOZ0NvbXBvbmVudE91dGxldCwgTmdGb3JPZiwgTmdJZiwgTmdUZW1wbGF0ZU91dGxldCwgTmdTdHlsZSwgTmdTd2l0Y2gsIE5nU3dpdGNoQ2FzZSwgTmdTd2l0Y2hEZWZhdWx0LCBOZ1BsdXJhbCwgTmdQbHVyYWxDYXNlLCBBc3luY1BpcGUsIFVwcGVyQ2FzZVBpcGUsIExvd2VyQ2FzZVBpcGUsIEpzb25QaXBlLCBTbGljZVBpcGUsIERlY2ltYWxQaXBlLCBQZXJjZW50UGlwZSwgVGl0bGVDYXNlUGlwZSwgQ3VycmVuY3lQaXBlLCBEYXRlUGlwZSwgSTE4blBsdXJhbFBpcGUsIEkxOG5TZWxlY3RQaXBlLCBLZXlWYWx1ZVBpcGVdLAogIGV4cG9ydHM6IFtOZ0NsYXNzLCBOZ0NvbXBvbmVudE91dGxldCwgTmdGb3JPZiwgTmdJZiwgTmdUZW1wbGF0ZU91dGxldCwgTmdTdHlsZSwgTmdTd2l0Y2gsIE5nU3dpdGNoQ2FzZSwgTmdTd2l0Y2hEZWZhdWx0LCBOZ1BsdXJhbCwgTmdQbHVyYWxDYXNlLCBBc3luY1BpcGUsIFVwcGVyQ2FzZVBpcGUsIExvd2VyQ2FzZVBpcGUsIEpzb25QaXBlLCBTbGljZVBpcGUsIERlY2ltYWxQaXBlLCBQZXJjZW50UGlwZSwgVGl0bGVDYXNlUGlwZSwgQ3VycmVuY3lQaXBlLCBEYXRlUGlwZSwgSTE4blBsdXJhbFBpcGUsIEkxOG5TZWxlY3RQaXBlLCBLZXlWYWx1ZVBpcGVdCn0pOwpfQ29tbW9uTW9kdWxlLsm1aW5qID0gybXJtWRlZmluZUluamVjdG9yKHt9KTsKdmFyIENvbW1vbk1vZHVsZSA9IF9Db21tb25Nb2R1bGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShDb21tb25Nb2R1bGUsIFt7CiAgICB0eXBlOiBOZ01vZHVsZSwKICAgIGFyZ3M6IFt7CiAgICAgIGltcG9ydHM6IFtDT01NT05fRElSRUNUSVZFUywgQ09NTU9OX1BJUEVTXSwKICAgICAgZXhwb3J0czogW0NPTU1PTl9ESVJFQ1RJVkVTLCBDT01NT05fUElQRVNdCiAgICB9XQogIH1dLCBudWxsLCBudWxsKTsKfSkoKTsKdmFyIFBMQVRGT1JNX0JST1dTRVJfSUQgPSAiYnJvd3NlciI7CnZhciBQTEFURk9STV9TRVJWRVJfSUQgPSAic2VydmVyIjsKZnVuY3Rpb24gaXNQbGF0Zm9ybUJyb3dzZXIocGxhdGZvcm1JZCkgewogIHJldHVybiBwbGF0Zm9ybUlkID09PSBQTEFURk9STV9CUk9XU0VSX0lEOwp9CmZ1bmN0aW9uIGlzUGxhdGZvcm1TZXJ2ZXIocGxhdGZvcm1JZCkgewogIHJldHVybiBwbGF0Zm9ybUlkID09PSBQTEFURk9STV9TRVJWRVJfSUQ7Cn0KdmFyIFZFUlNJT04gPSBuZXcgVmVyc2lvbigiMTguMC41Iik7CnZhciBfVmlld3BvcnRTY3JvbGxlciA9IGNsYXNzIF9WaWV3cG9ydFNjcm9sbGVyIHsKfTsKX1ZpZXdwb3J0U2Nyb2xsZXIuybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfVmlld3BvcnRTY3JvbGxlciwKICBwcm92aWRlZEluOiAicm9vdCIsCiAgZmFjdG9yeTogKCkgPT4gaXNQbGF0Zm9ybUJyb3dzZXIoaW5qZWN0KFBMQVRGT1JNX0lEKSkgPyBuZXcgQnJvd3NlclZpZXdwb3J0U2Nyb2xsZXIoaW5qZWN0KERPQ1VNRU5UKSwgd2luZG93KSA6IG5ldyBOdWxsVmlld3BvcnRTY3JvbGxlcigpCn0pOwp2YXIgVmlld3BvcnRTY3JvbGxlciA9IF9WaWV3cG9ydFNjcm9sbGVyOwp2YXIgQnJvd3NlclZpZXdwb3J0U2Nyb2xsZXIgPSBjbGFzcyB7CiAgY29uc3RydWN0b3IoZG9jdW1lbnQyLCB3aW5kb3cyKSB7CiAgICB0aGlzLmRvY3VtZW50ID0gZG9jdW1lbnQyOwogICAgdGhpcy53aW5kb3cgPSB3aW5kb3cyOwogICAgdGhpcy5vZmZzZXQgPSAoKSA9PiBbMCwgMF07CiAgfQogIC8qKgogICAqIENvbmZpZ3VyZXMgdGhlIHRvcCBvZmZzZXQgdXNlZCB3aGVuIHNjcm9sbGluZyB0byBhbiBhbmNob3IuCiAgICogQHBhcmFtIG9mZnNldCBBIHBvc2l0aW9uIGluIHNjcmVlbiBjb29yZGluYXRlcyAoYSB0dXBsZSB3aXRoIHggYW5kIHkgdmFsdWVzKQogICAqIG9yIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB0b3Agb2Zmc2V0IHBvc2l0aW9uLgogICAqCiAgICovCiAgc2V0T2Zmc2V0KG9mZnNldCkgewogICAgaWYgKEFycmF5LmlzQXJyYXkob2Zmc2V0KSkgewogICAgICB0aGlzLm9mZnNldCA9ICgpID0+IG9mZnNldDsKICAgIH0gZWxzZSB7CiAgICAgIHRoaXMub2Zmc2V0ID0gb2Zmc2V0OwogICAgfQogIH0KICAvKioKICAgKiBSZXRyaWV2ZXMgdGhlIGN1cnJlbnQgc2Nyb2xsIHBvc2l0aW9uLgogICAqIEByZXR1cm5zIFRoZSBwb3NpdGlvbiBpbiBzY3JlZW4gY29vcmRpbmF0ZXMuCiAgICovCiAgZ2V0U2Nyb2xsUG9zaXRpb24oKSB7CiAgICByZXR1cm4gW3RoaXMud2luZG93LnNjcm9sbFgsIHRoaXMud2luZG93LnNjcm9sbFldOwogIH0KICAvKioKICAgKiBTZXRzIHRoZSBzY3JvbGwgcG9zaXRpb24uCiAgICogQHBhcmFtIHBvc2l0aW9uIFRoZSBuZXcgcG9zaXRpb24gaW4gc2NyZWVuIGNvb3JkaW5hdGVzLgogICAqLwogIHNjcm9sbFRvUG9zaXRpb24ocG9zaXRpb24pIHsKICAgIHRoaXMud2luZG93LnNjcm9sbFRvKHBvc2l0aW9uWzBdLCBwb3NpdGlvblsxXSk7CiAgfQogIC8qKgogICAqIFNjcm9sbHMgdG8gYW4gZWxlbWVudCBhbmQgYXR0ZW1wdHMgdG8gZm9jdXMgdGhlIGVsZW1lbnQuCiAgICoKICAgKiBOb3RlIHRoYXQgdGhlIGZ1bmN0aW9uIG5hbWUgaGVyZSBpcyBtaXNsZWFkaW5nIGluIHRoYXQgdGhlIHRhcmdldCBzdHJpbmcgbWF5IGJlIGFuIElEIGZvciBhCiAgICogbm9uLWFuY2hvciBlbGVtZW50LgogICAqCiAgICogQHBhcmFtIHRhcmdldCBUaGUgSUQgb2YgYW4gZWxlbWVudCBvciBuYW1lIG9mIHRoZSBhbmNob3IuCiAgICoKICAgKiBAc2VlIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI3RoZS1pbmRpY2F0ZWQtcGFydC1vZi10aGUtZG9jdW1lbnQKICAgKiBAc2VlIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI3Njcm9sbC10by1mcmFnaWQKICAgKi8KICBzY3JvbGxUb0FuY2hvcih0YXJnZXQpIHsKICAgIGNvbnN0IGVsU2VsZWN0ZWQgPSBmaW5kQW5jaG9yRnJvbURvY3VtZW50KHRoaXMuZG9jdW1lbnQsIHRhcmdldCk7CiAgICBpZiAoZWxTZWxlY3RlZCkgewogICAgICB0aGlzLnNjcm9sbFRvRWxlbWVudChlbFNlbGVjdGVkKTsKICAgICAgZWxTZWxlY3RlZC5mb2N1cygpOwogICAgfQogIH0KICAvKioKICAgKiBEaXNhYmxlcyBhdXRvbWF0aWMgc2Nyb2xsIHJlc3RvcmF0aW9uIHByb3ZpZGVkIGJ5IHRoZSBicm93c2VyLgogICAqLwogIHNldEhpc3RvcnlTY3JvbGxSZXN0b3JhdGlvbihzY3JvbGxSZXN0b3JhdGlvbikgewogICAgdGhpcy53aW5kb3cuaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9IHNjcm9sbFJlc3RvcmF0aW9uOwogIH0KICAvKioKICAgKiBTY3JvbGxzIHRvIGFuIGVsZW1lbnQgdXNpbmcgdGhlIG5hdGl2ZSBvZmZzZXQgYW5kIHRoZSBzcGVjaWZpZWQgb2Zmc2V0IHNldCBvbiB0aGlzIHNjcm9sbGVyLgogICAqCiAgICogVGhlIG9mZnNldCBjYW4gYmUgdXNlZCB3aGVuIHdlIGtub3cgdGhhdCB0aGVyZSBpcyBhIGZsb2F0aW5nIGhlYWRlciBhbmQgc2Nyb2xsaW5nIG5haXZlbHkgdG8gYW4KICAgKiBlbGVtZW50IChleDogYHNjcm9sbEludG9WaWV3YCkgbGVhdmVzIHRoZSBlbGVtZW50IGhpZGRlbiBiZWhpbmQgdGhlIGZsb2F0aW5nIGhlYWRlci4KICAgKi8KICBzY3JvbGxUb0VsZW1lbnQoZWwpIHsKICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTsKICAgIGNvbnN0IGxlZnQgPSByZWN0LmxlZnQgKyB0aGlzLndpbmRvdy5wYWdlWE9mZnNldDsKICAgIGNvbnN0IHRvcCA9IHJlY3QudG9wICsgdGhpcy53aW5kb3cucGFnZVlPZmZzZXQ7CiAgICBjb25zdCBvZmZzZXQgPSB0aGlzLm9mZnNldCgpOwogICAgdGhpcy53aW5kb3cuc2Nyb2xsVG8obGVmdCAtIG9mZnNldFswXSwgdG9wIC0gb2Zmc2V0WzFdKTsKICB9Cn07CmZ1bmN0aW9uIGZpbmRBbmNob3JGcm9tRG9jdW1lbnQoZG9jdW1lbnQyLCB0YXJnZXQpIHsKICBjb25zdCBkb2N1bWVudFJlc3VsdCA9IGRvY3VtZW50Mi5nZXRFbGVtZW50QnlJZCh0YXJnZXQpIHx8IGRvY3VtZW50Mi5nZXRFbGVtZW50c0J5TmFtZSh0YXJnZXQpWzBdOwogIGlmIChkb2N1bWVudFJlc3VsdCkgewogICAgcmV0dXJuIGRvY3VtZW50UmVzdWx0OwogIH0KICBpZiAodHlwZW9mIGRvY3VtZW50Mi5jcmVhdGVUcmVlV2Fsa2VyID09PSAiZnVuY3Rpb24iICYmIGRvY3VtZW50Mi5ib2R5ICYmIHR5cGVvZiBkb2N1bWVudDIuYm9keS5hdHRhY2hTaGFkb3cgPT09ICJmdW5jdGlvbiIpIHsKICAgIGNvbnN0IHRyZWVXYWxrZXIgPSBkb2N1bWVudDIuY3JlYXRlVHJlZVdhbGtlcihkb2N1bWVudDIuYm9keSwgTm9kZUZpbHRlci5TSE9XX0VMRU1FTlQpOwogICAgbGV0IGN1cnJlbnROb2RlID0gdHJlZVdhbGtlci5jdXJyZW50Tm9kZTsKICAgIHdoaWxlIChjdXJyZW50Tm9kZSkgewogICAgICBjb25zdCBzaGFkb3dSb290ID0gY3VycmVudE5vZGUuc2hhZG93Um9vdDsKICAgICAgaWYgKHNoYWRvd1Jvb3QpIHsKICAgICAgICBjb25zdCByZXN1bHQgPSBzaGFkb3dSb290LmdldEVsZW1lbnRCeUlkKHRhcmdldCkgfHwgc2hhZG93Um9vdC5xdWVyeVNlbGVjdG9yKGBbbmFtZT0iJHt0YXJnZXR9Il1gKTsKICAgICAgICBpZiAocmVzdWx0KSB7CiAgICAgICAgICByZXR1cm4gcmVzdWx0OwogICAgICAgIH0KICAgICAgfQogICAgICBjdXJyZW50Tm9kZSA9IHRyZWVXYWxrZXIubmV4dE5vZGUoKTsKICAgIH0KICB9CiAgcmV0dXJuIG51bGw7Cn0KdmFyIE51bGxWaWV3cG9ydFNjcm9sbGVyID0gY2xhc3MgewogIC8qKgogICAqIEVtcHR5IGltcGxlbWVudGF0aW9uCiAgICovCiAgc2V0T2Zmc2V0KG9mZnNldCkgewogIH0KICAvKioKICAgKiBFbXB0eSBpbXBsZW1lbnRhdGlvbgogICAqLwogIGdldFNjcm9sbFBvc2l0aW9uKCkgewogICAgcmV0dXJuIFswLCAwXTsKICB9CiAgLyoqCiAgICogRW1wdHkgaW1wbGVtZW50YXRpb24KICAgKi8KICBzY3JvbGxUb1Bvc2l0aW9uKHBvc2l0aW9uKSB7CiAgfQogIC8qKgogICAqIEVtcHR5IGltcGxlbWVudGF0aW9uCiAgICovCiAgc2Nyb2xsVG9BbmNob3IoYW5jaG9yKSB7CiAgfQogIC8qKgogICAqIEVtcHR5IGltcGxlbWVudGF0aW9uCiAgICovCiAgc2V0SGlzdG9yeVNjcm9sbFJlc3RvcmF0aW9uKHNjcm9sbFJlc3RvcmF0aW9uKSB7CiAgfQp9Owp2YXIgWGhyRmFjdG9yeSA9IGNsYXNzIHsKfTsKdmFyIFBMQUNFSE9MREVSX1FVQUxJVFkgPSAiMjAiOwpmdW5jdGlvbiBnZXRVcmwoc3JjLCB3aW4pIHsKICByZXR1cm4gaXNBYnNvbHV0ZVVybChzcmMpID8gbmV3IFVSTChzcmMpIDogbmV3IFVSTChzcmMsIHdpbi5sb2NhdGlvbi5ocmVmKTsKfQpmdW5jdGlvbiBpc0Fic29sdXRlVXJsKHNyYykgewogIHJldHVybiAvXmh0dHBzPzpcL1wvLy50ZXN0KHNyYyk7Cn0KZnVuY3Rpb24gZXh0cmFjdEhvc3RuYW1lKHVybCkgewogIHJldHVybiBpc0Fic29sdXRlVXJsKHVybCkgPyBuZXcgVVJMKHVybCkuaG9zdG5hbWUgOiB1cmw7Cn0KZnVuY3Rpb24gaXNWYWxpZFBhdGgocGF0aCkgewogIGNvbnN0IGlzU3RyaW5nID0gdHlwZW9mIHBhdGggPT09ICJzdHJpbmciOwogIGlmICghaXNTdHJpbmcgfHwgcGF0aC50cmltKCkgPT09ICIiKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQogIHRyeSB7CiAgICBjb25zdCB1cmwgPSBuZXcgVVJMKHBhdGgpOwogICAgcmV0dXJuIHRydWU7CiAgfSBjYXRjaCB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQp9CmZ1bmN0aW9uIG5vcm1hbGl6ZVBhdGgocGF0aCkgewogIHJldHVybiBwYXRoLmVuZHNXaXRoKCIvIikgPyBwYXRoLnNsaWNlKDAsIC0xKSA6IHBhdGg7Cn0KZnVuY3Rpb24gbm9ybWFsaXplU3JjKHNyYykgewogIHJldHVybiBzcmMuc3RhcnRzV2l0aCgiLyIpID8gc3JjLnNsaWNlKDEpIDogc3JjOwp9CnZhciBub29wSW1hZ2VMb2FkZXIgPSAoY29uZmlnKSA9PiBjb25maWcuc3JjOwp2YXIgSU1BR0VfTE9BREVSID0gbmV3IEluamVjdGlvblRva2VuKG5nRGV2TW9kZSA/ICJJbWFnZUxvYWRlciIgOiAiIiwgewogIHByb3ZpZGVkSW46ICJyb290IiwKICBmYWN0b3J5OiAoKSA9PiBub29wSW1hZ2VMb2FkZXIKfSk7CmZ1bmN0aW9uIGNyZWF0ZUltYWdlTG9hZGVyKGJ1aWxkVXJsRm4sIGV4YW1wbGVVcmxzKSB7CiAgcmV0dXJuIGZ1bmN0aW9uIHByb3ZpZGVJbWFnZUxvYWRlcihwYXRoKSB7CiAgICBpZiAoIWlzVmFsaWRQYXRoKHBhdGgpKSB7CiAgICAgIHRocm93SW52YWxpZFBhdGhFcnJvcihwYXRoLCBleGFtcGxlVXJscyB8fCBbXSk7CiAgICB9CiAgICBwYXRoID0gbm9ybWFsaXplUGF0aChwYXRoKTsKICAgIGNvbnN0IGxvYWRlckZuID0gKGNvbmZpZykgPT4gewogICAgICBpZiAoaXNBYnNvbHV0ZVVybChjb25maWcuc3JjKSkgewogICAgICAgIHRocm93VW5leHBlY3RlZEFic29sdXRlVXJsRXJyb3IocGF0aCwgY29uZmlnLnNyYyk7CiAgICAgIH0KICAgICAgcmV0dXJuIGJ1aWxkVXJsRm4ocGF0aCwgX19zcHJlYWRQcm9wcyhfX3NwcmVhZFZhbHVlcyh7fSwgY29uZmlnKSwgewogICAgICAgIHNyYzogbm9ybWFsaXplU3JjKGNvbmZpZy5zcmMpCiAgICAgIH0pKTsKICAgIH07CiAgICBjb25zdCBwcm92aWRlcnMgPSBbewogICAgICBwcm92aWRlOiBJTUFHRV9MT0FERVIsCiAgICAgIHVzZVZhbHVlOiBsb2FkZXJGbgogICAgfV07CiAgICByZXR1cm4gcHJvdmlkZXJzOwogIH07Cn0KZnVuY3Rpb24gdGhyb3dJbnZhbGlkUGF0aEVycm9yKHBhdGgsIGV4YW1wbGVVcmxzKSB7CiAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigyOTU5LCBuZ0Rldk1vZGUgJiYgYEltYWdlIGxvYWRlciBoYXMgZGV0ZWN0ZWQgYW4gaW52YWxpZCBwYXRoIChcYCR7cGF0aH1cYCkuIFRvIGZpeCB0aGlzLCBzdXBwbHkgYSBwYXRoIHVzaW5nIG9uZSBvZiB0aGUgZm9sbG93aW5nIGZvcm1hdHM6ICR7ZXhhbXBsZVVybHMuam9pbigiIG9yICIpfWApOwp9CmZ1bmN0aW9uIHRocm93VW5leHBlY3RlZEFic29sdXRlVXJsRXJyb3IocGF0aCwgdXJsKSB7CiAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigyOTU5LCBuZ0Rldk1vZGUgJiYgYEltYWdlIGxvYWRlciBoYXMgZGV0ZWN0ZWQgYSBcYDxpbWc+XGAgdGFnIHdpdGggYW4gaW52YWxpZCBcYG5nU3JjXGAgYXR0cmlidXRlOiAke3VybH0uIFRoaXMgaW1hZ2UgbG9hZGVyIGV4cGVjdHMgXGBuZ1NyY1xgIHRvIGJlIGEgcmVsYXRpdmUgVVJMIC0gaG93ZXZlciB0aGUgcHJvdmlkZWQgdmFsdWUgaXMgYW4gYWJzb2x1dGUgVVJMLiBUbyBmaXggdGhpcywgcHJvdmlkZSBcYG5nU3JjXGAgYXMgYSBwYXRoIHJlbGF0aXZlIHRvIHRoZSBiYXNlIFVSTCBjb25maWd1cmVkIGZvciB0aGlzIGxvYWRlciAoXGAke3BhdGh9XGApLmApOwp9CnZhciBwcm92aWRlQ2xvdWRmbGFyZUxvYWRlciA9IGNyZWF0ZUltYWdlTG9hZGVyKGNyZWF0ZUNsb3VkZmxhcmVVcmwsIG5nRGV2TW9kZSA/IFsiaHR0cHM6Ly88Wk9ORT4vY2RuLWNnaS9pbWFnZS88T1BUSU9OUz4vPFNPVVJDRS1JTUFHRT4iXSA6IHZvaWQgMCk7CmZ1bmN0aW9uIGNyZWF0ZUNsb3VkZmxhcmVVcmwocGF0aCwgY29uZmlnKSB7CiAgbGV0IHBhcmFtcyA9IGBmb3JtYXQ9YXV0b2A7CiAgaWYgKGNvbmZpZy53aWR0aCkgewogICAgcGFyYW1zICs9IGAsd2lkdGg9JHtjb25maWcud2lkdGh9YDsKICB9CiAgaWYgKGNvbmZpZy5pc1BsYWNlaG9sZGVyKSB7CiAgICBwYXJhbXMgKz0gYCxxdWFsaXR5PSR7UExBQ0VIT0xERVJfUVVBTElUWX1gOwogIH0KICByZXR1cm4gYCR7cGF0aH0vY2RuLWNnaS9pbWFnZS8ke3BhcmFtc30vJHtjb25maWcuc3JjfWA7Cn0KdmFyIGNsb3VkaW5hcnlMb2FkZXJJbmZvID0gewogIG5hbWU6ICJDbG91ZGluYXJ5IiwKICB0ZXN0VXJsOiBpc0Nsb3VkaW5hcnlVcmwKfTsKdmFyIENMT1VESU5BUllfTE9BREVSX1JFR0VYID0gL2h0dHBzP1w6XC9cL1teXC9dK1wuY2xvdWRpbmFyeVwuY29tXC8uKy87CmZ1bmN0aW9uIGlzQ2xvdWRpbmFyeVVybCh1cmwpIHsKICByZXR1cm4gQ0xPVURJTkFSWV9MT0FERVJfUkVHRVgudGVzdCh1cmwpOwp9CnZhciBwcm92aWRlQ2xvdWRpbmFyeUxvYWRlciA9IGNyZWF0ZUltYWdlTG9hZGVyKGNyZWF0ZUNsb3VkaW5hcnlVcmwsIG5nRGV2TW9kZSA/IFsiaHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vbXlzaXRlIiwgImh0dHBzOi8vbXlzaXRlLmNsb3VkaW5hcnkuY29tIiwgImh0dHBzOi8vc3ViZG9tYWluLm15c2l0ZS5jb20iXSA6IHZvaWQgMCk7CmZ1bmN0aW9uIGNyZWF0ZUNsb3VkaW5hcnlVcmwocGF0aCwgY29uZmlnKSB7CiAgY29uc3QgcXVhbGl0eSA9IGNvbmZpZy5pc1BsYWNlaG9sZGVyID8gInFfYXV0bzpsb3ciIDogInFfYXV0byI7CiAgbGV0IHBhcmFtcyA9IGBmX2F1dG8sJHtxdWFsaXR5fWA7CiAgaWYgKGNvbmZpZy53aWR0aCkgewogICAgcGFyYW1zICs9IGAsd18ke2NvbmZpZy53aWR0aH1gOwogIH0KICByZXR1cm4gYCR7cGF0aH0vaW1hZ2UvdXBsb2FkLyR7cGFyYW1zfS8ke2NvbmZpZy5zcmN9YDsKfQp2YXIgaW1hZ2VLaXRMb2FkZXJJbmZvID0gewogIG5hbWU6ICJJbWFnZUtpdCIsCiAgdGVzdFVybDogaXNJbWFnZUtpdFVybAp9Owp2YXIgSU1BR0VfS0lUX0xPQURFUl9SRUdFWCA9IC9odHRwcz9cOlwvXC9bXlwvXStcLmltYWdla2l0XC5pb1wvLisvOwpmdW5jdGlvbiBpc0ltYWdlS2l0VXJsKHVybCkgewogIHJldHVybiBJTUFHRV9LSVRfTE9BREVSX1JFR0VYLnRlc3QodXJsKTsKfQp2YXIgcHJvdmlkZUltYWdlS2l0TG9hZGVyID0gY3JlYXRlSW1hZ2VMb2FkZXIoY3JlYXRlSW1hZ2VraXRVcmwsIG5nRGV2TW9kZSA/IFsiaHR0cHM6Ly9pay5pbWFnZWtpdC5pby9teXNpdGUiLCAiaHR0cHM6Ly9zdWJkb21haW4ubXlzaXRlLmNvbSJdIDogdm9pZCAwKTsKZnVuY3Rpb24gY3JlYXRlSW1hZ2VraXRVcmwocGF0aCwgY29uZmlnKSB7CiAgY29uc3QgewogICAgc3JjLAogICAgd2lkdGgKICB9ID0gY29uZmlnOwogIGNvbnN0IHBhcmFtcyA9IFtdOwogIGlmICh3aWR0aCkgewogICAgcGFyYW1zLnB1c2goYHctJHt3aWR0aH1gKTsKICB9CiAgaWYgKGNvbmZpZy5pc1BsYWNlaG9sZGVyKSB7CiAgICBwYXJhbXMucHVzaChgcS0ke1BMQUNFSE9MREVSX1FVQUxJVFl9YCk7CiAgfQogIGNvbnN0IHVybFNlZ21lbnRzID0gcGFyYW1zLmxlbmd0aCA/IFtwYXRoLCBgdHI6JHtwYXJhbXMuam9pbigiLCIpfWAsIHNyY10gOiBbcGF0aCwgc3JjXTsKICBjb25zdCB1cmwgPSBuZXcgVVJMKHVybFNlZ21lbnRzLmpvaW4oIi8iKSk7CiAgcmV0dXJuIHVybC5ocmVmOwp9CnZhciBpbWdpeExvYWRlckluZm8gPSB7CiAgbmFtZTogIkltZ2l4IiwKICB0ZXN0VXJsOiBpc0ltZ2l4VXJsCn07CnZhciBJTUdJWF9MT0FERVJfUkVHRVggPSAvaHR0cHM/XDpcL1wvW15cL10rXC5pbWdpeFwubmV0XC8uKy87CmZ1bmN0aW9uIGlzSW1naXhVcmwodXJsKSB7CiAgcmV0dXJuIElNR0lYX0xPQURFUl9SRUdFWC50ZXN0KHVybCk7Cn0KdmFyIHByb3ZpZGVJbWdpeExvYWRlciA9IGNyZWF0ZUltYWdlTG9hZGVyKGNyZWF0ZUltZ2l4VXJsLCBuZ0Rldk1vZGUgPyBbImh0dHBzOi8vc29tZXBhdGguaW1naXgubmV0LyJdIDogdm9pZCAwKTsKZnVuY3Rpb24gY3JlYXRlSW1naXhVcmwocGF0aCwgY29uZmlnKSB7CiAgY29uc3QgdXJsID0gbmV3IFVSTChgJHtwYXRofS8ke2NvbmZpZy5zcmN9YCk7CiAgdXJsLnNlYXJjaFBhcmFtcy5zZXQoImF1dG8iLCAiZm9ybWF0Iik7CiAgaWYgKGNvbmZpZy53aWR0aCkgewogICAgdXJsLnNlYXJjaFBhcmFtcy5zZXQoInciLCBjb25maWcud2lkdGgudG9TdHJpbmcoKSk7CiAgfQogIGlmIChjb25maWcuaXNQbGFjZWhvbGRlcikgewogICAgdXJsLnNlYXJjaFBhcmFtcy5zZXQoInEiLCBQTEFDRUhPTERFUl9RVUFMSVRZKTsKICB9CiAgcmV0dXJuIHVybC5ocmVmOwp9CnZhciBuZXRsaWZ5TG9hZGVySW5mbyA9IHsKICBuYW1lOiAiTmV0bGlmeSIsCiAgdGVzdFVybDogaXNOZXRsaWZ5VXJsCn07CnZhciBORVRMSUZZX0xPQURFUl9SRUdFWCA9IC9odHRwcz9cOlwvXC9bXlwvXStcLm5ldGxpZnlcLmFwcFwvLisvOwpmdW5jdGlvbiBpc05ldGxpZnlVcmwodXJsKSB7CiAgcmV0dXJuIE5FVExJRllfTE9BREVSX1JFR0VYLnRlc3QodXJsKTsKfQpmdW5jdGlvbiBpbWdEaXJlY3RpdmVEZXRhaWxzKG5nU3JjLCBpbmNsdWRlTmdTcmMgPSB0cnVlKSB7CiAgY29uc3QgbmdTcmNJbmZvID0gaW5jbHVkZU5nU3JjID8gYChhY3RpdmF0ZWQgb24gYW4gPGltZz4gZWxlbWVudCB3aXRoIHRoZSBcYG5nU3JjPSIke25nU3JjfSJcYCkgYCA6ICIiOwogIHJldHVybiBgVGhlIE5nT3B0aW1pemVkSW1hZ2UgZGlyZWN0aXZlICR7bmdTcmNJbmZvfWhhcyBkZXRlY3RlZCB0aGF0YDsKfQpmdW5jdGlvbiBhc3NlcnREZXZNb2RlKGNoZWNrTmFtZSkgewogIGlmICghbmdEZXZNb2RlKSB7CiAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDI5NTgsIGBVbmV4cGVjdGVkIGludm9jYXRpb24gb2YgdGhlICR7Y2hlY2tOYW1lfSBpbiB0aGUgcHJvZCBtb2RlLiBQbGVhc2UgbWFrZSBzdXJlIHRoYXQgdGhlIHByb2QgbW9kZSBpcyBlbmFibGVkIGZvciBwcm9kdWN0aW9uIGJ1aWxkcy5gKTsKICB9Cn0KdmFyIF9MQ1BJbWFnZU9ic2VydmVyID0gY2xhc3MgX0xDUEltYWdlT2JzZXJ2ZXIgewogIGNvbnN0cnVjdG9yKCkgewogICAgdGhpcy5pbWFnZXMgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgdGhpcy53aW5kb3cgPSBudWxsOwogICAgdGhpcy5vYnNlcnZlciA9IG51bGw7CiAgICBhc3NlcnREZXZNb2RlKCJMQ1AgY2hlY2tlciIpOwogICAgY29uc3Qgd2luID0gaW5qZWN0KERPQ1VNRU5UKS5kZWZhdWx0VmlldzsKICAgIGlmICh0eXBlb2Ygd2luICE9PSAidW5kZWZpbmVkIiAmJiB0eXBlb2YgUGVyZm9ybWFuY2VPYnNlcnZlciAhPT0gInVuZGVmaW5lZCIpIHsKICAgICAgdGhpcy53aW5kb3cgPSB3aW47CiAgICAgIHRoaXMub2JzZXJ2ZXIgPSB0aGlzLmluaXRQZXJmb3JtYW5jZU9ic2VydmVyKCk7CiAgICB9CiAgfQogIC8qKgogICAqIEluaXRzIFBlcmZvcm1hbmNlT2JzZXJ2ZXIgYW5kIHN1YnNjcmliZXMgdG8gTENQIGV2ZW50cy4KICAgKiBCYXNlZCBvbiBodHRwczovL3dlYi5kZXYvbGNwLyNtZWFzdXJlLWxjcC1pbi1qYXZhc2NyaXB0CiAgICovCiAgaW5pdFBlcmZvcm1hbmNlT2JzZXJ2ZXIoKSB7CiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBQZXJmb3JtYW5jZU9ic2VydmVyKChlbnRyeUxpc3QpID0+IHsKICAgICAgY29uc3QgZW50cmllcyA9IGVudHJ5TGlzdC5nZXRFbnRyaWVzKCk7CiAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCA9PT0gMCkKICAgICAgICByZXR1cm47CiAgICAgIGNvbnN0IGxjcEVsZW1lbnQgPSBlbnRyaWVzW2VudHJpZXMubGVuZ3RoIC0gMV07CiAgICAgIGNvbnN0IGltZ1NyYyA9IGxjcEVsZW1lbnQuZWxlbWVudD8uc3JjID8/ICIiOwogICAgICBpZiAoaW1nU3JjLnN0YXJ0c1dpdGgoImRhdGE6IikgfHwgaW1nU3JjLnN0YXJ0c1dpdGgoImJsb2I6IikpCiAgICAgICAgcmV0dXJuOwogICAgICBjb25zdCBpbWcgPSB0aGlzLmltYWdlcy5nZXQoaW1nU3JjKTsKICAgICAgaWYgKCFpbWcpCiAgICAgICAgcmV0dXJuOwogICAgICBpZiAoIWltZy5wcmlvcml0eSAmJiAhaW1nLmFscmVhZHlXYXJuZWRQcmlvcml0eSkgewogICAgICAgIGltZy5hbHJlYWR5V2FybmVkUHJpb3JpdHkgPSB0cnVlOwogICAgICAgIGxvZ01pc3NpbmdQcmlvcml0eUVycm9yKGltZ1NyYyk7CiAgICAgIH0KICAgICAgaWYgKGltZy5tb2RpZmllZCAmJiAhaW1nLmFscmVhZHlXYXJuZWRNb2RpZmllZCkgewogICAgICAgIGltZy5hbHJlYWR5V2FybmVkTW9kaWZpZWQgPSB0cnVlOwogICAgICAgIGxvZ01vZGlmaWVkV2FybmluZyhpbWdTcmMpOwogICAgICB9CiAgICB9KTsKICAgIG9ic2VydmVyLm9ic2VydmUoewogICAgICB0eXBlOiAibGFyZ2VzdC1jb250ZW50ZnVsLXBhaW50IiwKICAgICAgYnVmZmVyZWQ6IHRydWUKICAgIH0pOwogICAgcmV0dXJuIG9ic2VydmVyOwogIH0KICByZWdpc3RlckltYWdlKHJld3JpdHRlblNyYywgb3JpZ2luYWxOZ1NyYywgaXNQcmlvcml0eSkgewogICAgaWYgKCF0aGlzLm9ic2VydmVyKQogICAgICByZXR1cm47CiAgICBjb25zdCBuZXdPYnNlcnZlZEltYWdlU3RhdGUgPSB7CiAgICAgIHByaW9yaXR5OiBpc1ByaW9yaXR5LAogICAgICBtb2RpZmllZDogZmFsc2UsCiAgICAgIGFscmVhZHlXYXJuZWRNb2RpZmllZDogZmFsc2UsCiAgICAgIGFscmVhZHlXYXJuZWRQcmlvcml0eTogZmFsc2UKICAgIH07CiAgICB0aGlzLmltYWdlcy5zZXQoZ2V0VXJsKHJld3JpdHRlblNyYywgdGhpcy53aW5kb3cpLmhyZWYsIG5ld09ic2VydmVkSW1hZ2VTdGF0ZSk7CiAgfQogIHVucmVnaXN0ZXJJbWFnZShyZXdyaXR0ZW5TcmMpIHsKICAgIGlmICghdGhpcy5vYnNlcnZlcikKICAgICAgcmV0dXJuOwogICAgdGhpcy5pbWFnZXMuZGVsZXRlKGdldFVybChyZXdyaXR0ZW5TcmMsIHRoaXMud2luZG93KS5ocmVmKTsKICB9CiAgdXBkYXRlSW1hZ2Uob3JpZ2luYWxTcmMsIG5ld1NyYykgewogICAgY29uc3Qgb3JpZ2luYWxVcmwgPSBnZXRVcmwob3JpZ2luYWxTcmMsIHRoaXMud2luZG93KS5ocmVmOwogICAgY29uc3QgaW1nID0gdGhpcy5pbWFnZXMuZ2V0KG9yaWdpbmFsVXJsKTsKICAgIGlmIChpbWcpIHsKICAgICAgaW1nLm1vZGlmaWVkID0gdHJ1ZTsKICAgICAgdGhpcy5pbWFnZXMuc2V0KGdldFVybChuZXdTcmMsIHRoaXMud2luZG93KS5ocmVmLCBpbWcpOwogICAgICB0aGlzLmltYWdlcy5kZWxldGUob3JpZ2luYWxVcmwpOwogICAgfQogIH0KICBuZ09uRGVzdHJveSgpIHsKICAgIGlmICghdGhpcy5vYnNlcnZlcikKICAgICAgcmV0dXJuOwogICAgdGhpcy5vYnNlcnZlci5kaXNjb25uZWN0KCk7CiAgICB0aGlzLmltYWdlcy5jbGVhcigpOwogIH0KfTsKX0xDUEltYWdlT2JzZXJ2ZXIuybVmYWMgPSBmdW5jdGlvbiBMQ1BJbWFnZU9ic2VydmVyX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0xDUEltYWdlT2JzZXJ2ZXIpKCk7Cn07Cl9MQ1BJbWFnZU9ic2VydmVyLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX0xDUEltYWdlT2JzZXJ2ZXIsCiAgZmFjdG9yeTogX0xDUEltYWdlT2JzZXJ2ZXIuybVmYWMsCiAgcHJvdmlkZWRJbjogInJvb3QiCn0pOwp2YXIgTENQSW1hZ2VPYnNlcnZlciA9IF9MQ1BJbWFnZU9ic2VydmVyOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoTENQSW1hZ2VPYnNlcnZlciwgW3sKICAgIHR5cGU6IEluamVjdGFibGUsCiAgICBhcmdzOiBbewogICAgICBwcm92aWRlZEluOiAicm9vdCIKICAgIH1dCiAgfV0sICgpID0+IFtdLCBudWxsKTsKfSkoKTsKZnVuY3Rpb24gbG9nTWlzc2luZ1ByaW9yaXR5RXJyb3IobmdTcmMpIHsKICBjb25zdCBkaXJlY3RpdmVEZXRhaWxzID0gaW1nRGlyZWN0aXZlRGV0YWlscyhuZ1NyYyk7CiAgY29uc29sZS5lcnJvcihmb3JtYXRSdW50aW1lRXJyb3IoMjk1NSwgYCR7ZGlyZWN0aXZlRGV0YWlsc30gdGhpcyBpbWFnZSBpcyB0aGUgTGFyZ2VzdCBDb250ZW50ZnVsIFBhaW50IChMQ1ApIGVsZW1lbnQgYnV0IHdhcyBub3QgbWFya2VkICJwcmlvcml0eSIuIFRoaXMgaW1hZ2Ugc2hvdWxkIGJlIG1hcmtlZCAicHJpb3JpdHkiIGluIG9yZGVyIHRvIHByaW9yaXRpemUgaXRzIGxvYWRpbmcuIFRvIGZpeCB0aGlzLCBhZGQgdGhlICJwcmlvcml0eSIgYXR0cmlidXRlLmApKTsKfQpmdW5jdGlvbiBsb2dNb2RpZmllZFdhcm5pbmcobmdTcmMpIHsKICBjb25zdCBkaXJlY3RpdmVEZXRhaWxzID0gaW1nRGlyZWN0aXZlRGV0YWlscyhuZ1NyYyk7CiAgY29uc29sZS53YXJuKGZvcm1hdFJ1bnRpbWVFcnJvcigyOTY0LCBgJHtkaXJlY3RpdmVEZXRhaWxzfSB0aGlzIGltYWdlIGlzIHRoZSBMYXJnZXN0IENvbnRlbnRmdWwgUGFpbnQgKExDUCkgZWxlbWVudCBhbmQgaGFzIGhhZCBpdHMgIm5nU3JjIiBhdHRyaWJ1dGUgbW9kaWZpZWQuIFRoaXMgY2FuIGNhdXNlIHNsb3dlciBsb2FkaW5nIHBlcmZvcm1hbmNlLiBJdCBpcyByZWNvbW1lbmRlZCBub3QgdG8gbW9kaWZ5IHRoZSAibmdTcmMiIHByb3BlcnR5IG9uIGFueSBpbWFnZSB3aGljaCBjb3VsZCBiZSB0aGUgTENQIGVsZW1lbnQuYCkpOwp9CnZhciBJTlRFUk5BTF9QUkVDT05ORUNUX0NIRUNLX0JMT0NLTElTVCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KFsibG9jYWxob3N0IiwgIjEyNy4wLjAuMSIsICIwLjAuMC4wIl0pOwp2YXIgUFJFQ09OTkVDVF9DSEVDS19CTE9DS0xJU1QgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gIlBSRUNPTk5FQ1RfQ0hFQ0tfQkxPQ0tMSVNUIiA6ICIiKTsKdmFyIF9QcmVjb25uZWN0TGlua0NoZWNrZXIgPSBjbGFzcyBfUHJlY29ubmVjdExpbmtDaGVja2VyIHsKICBjb25zdHJ1Y3RvcigpIHsKICAgIHRoaXMuZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpOwogICAgdGhpcy5wcmVjb25uZWN0TGlua3MgPSBudWxsOwogICAgdGhpcy5hbHJlYWR5U2VlbiA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7CiAgICB0aGlzLndpbmRvdyA9IG51bGw7CiAgICB0aGlzLmJsb2NrbGlzdCA9IG5ldyBTZXQoSU5URVJOQUxfUFJFQ09OTkVDVF9DSEVDS19CTE9DS0xJU1QpOwogICAgYXNzZXJ0RGV2TW9kZSgicHJlY29ubmVjdCBsaW5rIGNoZWNrZXIiKTsKICAgIGNvbnN0IHdpbiA9IHRoaXMuZG9jdW1lbnQuZGVmYXVsdFZpZXc7CiAgICBpZiAodHlwZW9mIHdpbiAhPT0gInVuZGVmaW5lZCIpIHsKICAgICAgdGhpcy53aW5kb3cgPSB3aW47CiAgICB9CiAgICBjb25zdCBibG9ja2xpc3QgPSBpbmplY3QoUFJFQ09OTkVDVF9DSEVDS19CTE9DS0xJU1QsIHsKICAgICAgb3B0aW9uYWw6IHRydWUKICAgIH0pOwogICAgaWYgKGJsb2NrbGlzdCkgewogICAgICB0aGlzLnBvcHVsYXRlQmxvY2tsaXN0KGJsb2NrbGlzdCk7CiAgICB9CiAgfQogIHBvcHVsYXRlQmxvY2tsaXN0KG9yaWdpbnMpIHsKICAgIGlmIChBcnJheS5pc0FycmF5KG9yaWdpbnMpKSB7CiAgICAgIGRlZXBGb3JFYWNoKG9yaWdpbnMsIChvcmlnaW4pID0+IHsKICAgICAgICB0aGlzLmJsb2NrbGlzdC5hZGQoZXh0cmFjdEhvc3RuYW1lKG9yaWdpbikpOwogICAgICB9KTsKICAgIH0gZWxzZSB7CiAgICAgIHRoaXMuYmxvY2tsaXN0LmFkZChleHRyYWN0SG9zdG5hbWUob3JpZ2lucykpOwogICAgfQogIH0KICAvKioKICAgKiBDaGVja3MgdGhhdCBhIHByZWNvbm5lY3QgcmVzb3VyY2UgaGludCBleGlzdHMgaW4gdGhlIGhlYWQgZm9yIHRoZQogICAqIGdpdmVuIHNyYy4KICAgKgogICAqIEBwYXJhbSByZXdyaXR0ZW5TcmMgc3JjIGZvcm1hdHRlZCB3aXRoIGxvYWRlcgogICAqIEBwYXJhbSBvcmlnaW5hbE5nU3JjIG5nU3JjIHZhbHVlCiAgICovCiAgYXNzZXJ0UHJlY29ubmVjdChyZXdyaXR0ZW5TcmMsIG9yaWdpbmFsTmdTcmMpIHsKICAgIGlmICghdGhpcy53aW5kb3cpCiAgICAgIHJldHVybjsKICAgIGNvbnN0IGltZ1VybCA9IGdldFVybChyZXdyaXR0ZW5TcmMsIHRoaXMud2luZG93KTsKICAgIGlmICh0aGlzLmJsb2NrbGlzdC5oYXMoaW1nVXJsLmhvc3RuYW1lKSB8fCB0aGlzLmFscmVhZHlTZWVuLmhhcyhpbWdVcmwub3JpZ2luKSkKICAgICAgcmV0dXJuOwogICAgdGhpcy5hbHJlYWR5U2Vlbi5hZGQoaW1nVXJsLm9yaWdpbik7CiAgICB0aGlzLnByZWNvbm5lY3RMaW5rcyA/Pz0gdGhpcy5xdWVyeVByZWNvbm5lY3RMaW5rcygpOwogICAgaWYgKCF0aGlzLnByZWNvbm5lY3RMaW5rcy5oYXMoaW1nVXJsLm9yaWdpbikpIHsKICAgICAgY29uc29sZS53YXJuKGZvcm1hdFJ1bnRpbWVFcnJvcigyOTU2LCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKG9yaWdpbmFsTmdTcmMpfSB0aGVyZSBpcyBubyBwcmVjb25uZWN0IHRhZyBwcmVzZW50IGZvciB0aGlzIGltYWdlLiBQcmVjb25uZWN0aW5nIHRvIHRoZSBvcmlnaW4ocykgdGhhdCBzZXJ2ZSBwcmlvcml0eSBpbWFnZXMgZW5zdXJlcyB0aGF0IHRoZXNlIGltYWdlcyBhcmUgZGVsaXZlcmVkIGFzIHNvb24gYXMgcG9zc2libGUuIFRvIGZpeCB0aGlzLCBwbGVhc2UgYWRkIHRoZSBmb2xsb3dpbmcgZWxlbWVudCBpbnRvIHRoZSA8aGVhZD4gb2YgdGhlIGRvY3VtZW50OgogIDxsaW5rIHJlbD0icHJlY29ubmVjdCIgaHJlZj0iJHtpbWdVcmwub3JpZ2lufSI+YCkpOwogICAgfQogIH0KICBxdWVyeVByZWNvbm5lY3RMaW5rcygpIHsKICAgIGNvbnN0IHByZWNvbm5lY3RVcmxzID0gLyogQF9fUFVSRV9fICovIG5ldyBTZXQoKTsKICAgIGNvbnN0IHNlbGVjdG9yID0gImxpbmtbcmVsPXByZWNvbm5lY3RdIjsKICAgIGNvbnN0IGxpbmtzID0gQXJyYXkuZnJvbSh0aGlzLmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKTsKICAgIGZvciAobGV0IGxpbmsgb2YgbGlua3MpIHsKICAgICAgY29uc3QgdXJsID0gZ2V0VXJsKGxpbmsuaHJlZiwgdGhpcy53aW5kb3cpOwogICAgICBwcmVjb25uZWN0VXJscy5hZGQodXJsLm9yaWdpbik7CiAgICB9CiAgICByZXR1cm4gcHJlY29ubmVjdFVybHM7CiAgfQogIG5nT25EZXN0cm95KCkgewogICAgdGhpcy5wcmVjb25uZWN0TGlua3M/LmNsZWFyKCk7CiAgICB0aGlzLmFscmVhZHlTZWVuLmNsZWFyKCk7CiAgfQp9OwpfUHJlY29ubmVjdExpbmtDaGVja2VyLsm1ZmFjID0gZnVuY3Rpb24gUHJlY29ubmVjdExpbmtDaGVja2VyX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX1ByZWNvbm5lY3RMaW5rQ2hlY2tlcikoKTsKfTsKX1ByZWNvbm5lY3RMaW5rQ2hlY2tlci7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7CiAgdG9rZW46IF9QcmVjb25uZWN0TGlua0NoZWNrZXIsCiAgZmFjdG9yeTogX1ByZWNvbm5lY3RMaW5rQ2hlY2tlci7JtWZhYywKICBwcm92aWRlZEluOiAicm9vdCIKfSk7CnZhciBQcmVjb25uZWN0TGlua0NoZWNrZXIgPSBfUHJlY29ubmVjdExpbmtDaGVja2VyOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoUHJlY29ubmVjdExpbmtDaGVja2VyLCBbewogICAgdHlwZTogSW5qZWN0YWJsZSwKICAgIGFyZ3M6IFt7CiAgICAgIHByb3ZpZGVkSW46ICJyb290IgogICAgfV0KICB9XSwgKCkgPT4gW10sIG51bGwpOwp9KSgpOwpmdW5jdGlvbiBkZWVwRm9yRWFjaChpbnB1dCwgZm4pIHsKICBmb3IgKGxldCB2YWx1ZSBvZiBpbnB1dCkgewogICAgQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyBkZWVwRm9yRWFjaCh2YWx1ZSwgZm4pIDogZm4odmFsdWUpOwogIH0KfQp2YXIgREVGQVVMVF9QUkVMT0FERURfSU1BR0VTX0xJTUlUID0gNTsKdmFyIFBSRUxPQURFRF9JTUFHRVMgPSBuZXcgSW5qZWN0aW9uVG9rZW4oIk5HX09QVElNSVpFRF9QUkVMT0FERURfSU1BR0VTIiwgewogIHByb3ZpZGVkSW46ICJyb290IiwKICBmYWN0b3J5OiAoKSA9PiAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpCn0pOwp2YXIgX1ByZWxvYWRMaW5rQ3JlYXRvciA9IGNsYXNzIF9QcmVsb2FkTGlua0NyZWF0b3IgewogIGNvbnN0cnVjdG9yKCkgewogICAgdGhpcy5wcmVsb2FkZWRJbWFnZXMgPSBpbmplY3QoUFJFTE9BREVEX0lNQUdFUyk7CiAgICB0aGlzLmRvY3VtZW50ID0gaW5qZWN0KERPQ1VNRU5UKTsKICB9CiAgLyoqCiAgICogQGRlc2NyaXB0aW9uIEFkZCBhIHByZWxvYWQgYDxsaW5rPmAgdG8gdGhlIGA8aGVhZD5gIG9mIHRoZSBgaW5kZXguaHRtbGAgdGhhdCBpcyBzZXJ2ZWQgZnJvbSB0aGUKICAgKiBzZXJ2ZXIgd2hpbGUgdXNpbmcgQW5ndWxhciBVbml2ZXJzYWwgYW5kIFNTUiB0byBraWNrIG9mZiBpbWFnZSBsb2FkcyBmb3IgaGlnaCBwcmlvcml0eSBpbWFnZXMuCiAgICoKICAgKiBUaGUgYHNpemVzYCAocGFzc2VkIGluIGZyb20gdGhlIHVzZXIpIGFuZCBgc3Jjc2V0YCAocGFyc2VkIGFuZCBmb3JtYXR0ZWQgZnJvbSBgbmdTcmNzZXRgKQogICAqIHByb3BlcnRpZXMgdXNlZCB0byBzZXQgdGhlIGNvcnJlc3BvbmRpbmcgYXR0cmlidXRlcywgYGltYWdlc2l6ZXNgIGFuZCBgaW1hZ2VzcmNzZXRgCiAgICogcmVzcGVjdGl2ZWx5LCBvbiB0aGUgcHJlbG9hZCBgPGxpbms+YCB0YWcgc28gdGhhdCB0aGUgY29ycmVjdGx5IHNpemVkIGltYWdlIGlzIHByZWxvYWRlZCBmcm9tCiAgICogdGhlIENETi4KICAgKgogICAqIHtAbGluayBodHRwczovL3dlYi5kZXYvcHJlbG9hZC1yZXNwb25zaXZlLWltYWdlcy8jaW1hZ2VzcmNzZXQtYW5kLWltYWdlc2l6ZXN9CiAgICoKICAgKiBAcGFyYW0gcmVuZGVyZXIgVGhlIGBSZW5kZXJlcjJgIHBhc3NlZCBpbiBmcm9tIHRoZSBkaXJlY3RpdmUKICAgKiBAcGFyYW0gc3JjIFRoZSBvcmlnaW5hbCBzcmMgb2YgdGhlIGltYWdlIHRoYXQgaXMgc2V0IG9uIHRoZSBgbmdTcmNgIGlucHV0LgogICAqIEBwYXJhbSBzcmNzZXQgVGhlIHBhcnNlZCBhbmQgZm9ybWF0dGVkIHNyY3NldCBjcmVhdGVkIGZyb20gdGhlIGBuZ1NyY3NldGAgaW5wdXQKICAgKiBAcGFyYW0gc2l6ZXMgVGhlIHZhbHVlIG9mIHRoZSBgc2l6ZXNgIGF0dHJpYnV0ZSBwYXNzZWQgaW4gdG8gdGhlIGA8aW1nPmAgdGFnCiAgICovCiAgY3JlYXRlUHJlbG9hZExpbmtUYWcocmVuZGVyZXIsIHNyYywgc3Jjc2V0LCBzaXplcykgewogICAgaWYgKG5nRGV2TW9kZSkgewogICAgICBpZiAodGhpcy5wcmVsb2FkZWRJbWFnZXMuc2l6ZSA+PSBERUZBVUxUX1BSRUxPQURFRF9JTUFHRVNfTElNSVQpIHsKICAgICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDI5NjEsIG5nRGV2TW9kZSAmJiBgVGhlIFxgTmdPcHRpbWl6ZWRJbWFnZVxgIGRpcmVjdGl2ZSBoYXMgZGV0ZWN0ZWQgdGhhdCBtb3JlIHRoYW4gJHtERUZBVUxUX1BSRUxPQURFRF9JTUFHRVNfTElNSVR9IGltYWdlcyB3ZXJlIG1hcmtlZCBhcyBwcmlvcml0eS4gVGhpcyBtaWdodCBuZWdhdGl2ZWx5IGFmZmVjdCBhbiBvdmVyYWxsIHBlcmZvcm1hbmNlIG9mIHRoZSBwYWdlLiBUbyBmaXggdGhpcywgcmVtb3ZlIHRoZSAicHJpb3JpdHkiIGF0dHJpYnV0ZSBmcm9tIGltYWdlcyB3aXRoIGxlc3MgcHJpb3JpdHkuYCk7CiAgICAgIH0KICAgIH0KICAgIGlmICh0aGlzLnByZWxvYWRlZEltYWdlcy5oYXMoc3JjKSkgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLnByZWxvYWRlZEltYWdlcy5hZGQoc3JjKTsKICAgIGNvbnN0IHByZWxvYWQgPSByZW5kZXJlci5jcmVhdGVFbGVtZW50KCJsaW5rIik7CiAgICByZW5kZXJlci5zZXRBdHRyaWJ1dGUocHJlbG9hZCwgImFzIiwgImltYWdlIik7CiAgICByZW5kZXJlci5zZXRBdHRyaWJ1dGUocHJlbG9hZCwgImhyZWYiLCBzcmMpOwogICAgcmVuZGVyZXIuc2V0QXR0cmlidXRlKHByZWxvYWQsICJyZWwiLCAicHJlbG9hZCIpOwogICAgcmVuZGVyZXIuc2V0QXR0cmlidXRlKHByZWxvYWQsICJmZXRjaHByaW9yaXR5IiwgImhpZ2giKTsKICAgIGlmIChzaXplcykgewogICAgICByZW5kZXJlci5zZXRBdHRyaWJ1dGUocHJlbG9hZCwgImltYWdlU2l6ZXMiLCBzaXplcyk7CiAgICB9CiAgICBpZiAoc3Jjc2V0KSB7CiAgICAgIHJlbmRlcmVyLnNldEF0dHJpYnV0ZShwcmVsb2FkLCAiaW1hZ2VTcmNzZXQiLCBzcmNzZXQpOwogICAgfQogICAgcmVuZGVyZXIuYXBwZW5kQ2hpbGQodGhpcy5kb2N1bWVudC5oZWFkLCBwcmVsb2FkKTsKICB9Cn07Cl9QcmVsb2FkTGlua0NyZWF0b3IuybVmYWMgPSBmdW5jdGlvbiBQcmVsb2FkTGlua0NyZWF0b3JfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfUHJlbG9hZExpbmtDcmVhdG9yKSgpOwp9OwpfUHJlbG9hZExpbmtDcmVhdG9yLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX1ByZWxvYWRMaW5rQ3JlYXRvciwKICBmYWN0b3J5OiBfUHJlbG9hZExpbmtDcmVhdG9yLsm1ZmFjLAogIHByb3ZpZGVkSW46ICJyb290Igp9KTsKdmFyIFByZWxvYWRMaW5rQ3JlYXRvciA9IF9QcmVsb2FkTGlua0NyZWF0b3I7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShQcmVsb2FkTGlua0NyZWF0b3IsIFt7CiAgICB0eXBlOiBJbmplY3RhYmxlLAogICAgYXJnczogW3sKICAgICAgcHJvdmlkZWRJbjogInJvb3QiCiAgICB9XQogIH1dLCBudWxsLCBudWxsKTsKfSkoKTsKdmFyIEJBU0U2NF9JTUdfTUFYX0xFTkdUSF9JTl9FUlJPUiA9IDUwOwp2YXIgVkFMSURfV0lEVEhfREVTQ1JJUFRPUl9TUkNTRVQgPSAvXigoXHMqXGQrd1xzKigsfCQpKXsxLH0pJC87CnZhciBWQUxJRF9ERU5TSVRZX0RFU0NSSVBUT1JfU1JDU0VUID0gL14oKFxzKlxkKyhcLlxkKyk/eFxzKigsfCQpKXsxLH0pJC87CnZhciBBQlNPTFVURV9TUkNTRVRfREVOU0lUWV9DQVAgPSAzOwp2YXIgUkVDT01NRU5ERURfU1JDU0VUX0RFTlNJVFlfQ0FQID0gMjsKdmFyIERFTlNJVFlfU1JDU0VUX01VTFRJUExJRVJTID0gWzEsIDJdOwp2YXIgVklFV1BPUlRfQlJFQUtQT0lOVF9DVVRPRkYgPSA2NDA7CnZhciBBU1BFQ1RfUkFUSU9fVE9MRVJBTkNFID0gMC4xOwp2YXIgT1ZFUlNJWkVEX0lNQUdFX1RPTEVSQU5DRSA9IDFlMzsKdmFyIEZJWEVEX1NSQ1NFVF9XSURUSF9MSU1JVCA9IDE5MjA7CnZhciBGSVhFRF9TUkNTRVRfSEVJR0hUX0xJTUlUID0gMTA4MDsKdmFyIFBMQUNFSE9MREVSX0JMVVJfQU1PVU5UID0gMTU7CnZhciBEQVRBX1VSTF9XQVJOX0xJTUlUID0gNGUzOwp2YXIgREFUQV9VUkxfRVJST1JfTElNSVQgPSAxZTQ7CnZhciBCVUlMVF9JTl9MT0FERVJTID0gW2ltZ2l4TG9hZGVySW5mbywgaW1hZ2VLaXRMb2FkZXJJbmZvLCBjbG91ZGluYXJ5TG9hZGVySW5mbywgbmV0bGlmeUxvYWRlckluZm9dOwp2YXIgX05nT3B0aW1pemVkSW1hZ2UgPSBjbGFzcyBfTmdPcHRpbWl6ZWRJbWFnZSB7CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLmltYWdlTG9hZGVyID0gaW5qZWN0KElNQUdFX0xPQURFUik7CiAgICB0aGlzLmNvbmZpZyA9IHByb2Nlc3NDb25maWcoaW5qZWN0KElNQUdFX0NPTkZJRykpOwogICAgdGhpcy5yZW5kZXJlciA9IGluamVjdChSZW5kZXJlcjIpOwogICAgdGhpcy5pbWdFbGVtZW50ID0gaW5qZWN0KEVsZW1lbnRSZWYpLm5hdGl2ZUVsZW1lbnQ7CiAgICB0aGlzLmluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTsKICAgIHRoaXMuaXNTZXJ2ZXIgPSBpc1BsYXRmb3JtU2VydmVyKGluamVjdChQTEFURk9STV9JRCkpOwogICAgdGhpcy5wcmVsb2FkTGlua0NyZWF0b3IgPSBpbmplY3QoUHJlbG9hZExpbmtDcmVhdG9yKTsKICAgIHRoaXMubGNwT2JzZXJ2ZXIgPSBuZ0Rldk1vZGUgPyB0aGlzLmluamVjdG9yLmdldChMQ1BJbWFnZU9ic2VydmVyKSA6IG51bGw7CiAgICB0aGlzLl9yZW5kZXJlZFNyYyA9IG51bGw7CiAgICB0aGlzLnByaW9yaXR5ID0gZmFsc2U7CiAgICB0aGlzLmRpc2FibGVPcHRpbWl6ZWRTcmNzZXQgPSBmYWxzZTsKICAgIHRoaXMuZmlsbCA9IGZhbHNlOwogIH0KICAvKiogQG5vZG9jICovCiAgbmdPbkluaXQoKSB7CiAgICBwZXJmb3JtYW5jZU1hcmtGZWF0dXJlKCJOZ09wdGltaXplZEltYWdlIik7CiAgICBpZiAobmdEZXZNb2RlKSB7CiAgICAgIGNvbnN0IG5nWm9uZSA9IHRoaXMuaW5qZWN0b3IuZ2V0KE5nWm9uZSk7CiAgICAgIGFzc2VydE5vbkVtcHR5SW5wdXQodGhpcywgIm5nU3JjIiwgdGhpcy5uZ1NyYyk7CiAgICAgIGFzc2VydFZhbGlkTmdTcmNzZXQodGhpcywgdGhpcy5uZ1NyY3NldCk7CiAgICAgIGFzc2VydE5vQ29uZmxpY3RpbmdTcmModGhpcyk7CiAgICAgIGlmICh0aGlzLm5nU3Jjc2V0KSB7CiAgICAgICAgYXNzZXJ0Tm9Db25mbGljdGluZ1NyY3NldCh0aGlzKTsKICAgICAgfQogICAgICBhc3NlcnROb3RCYXNlNjRJbWFnZSh0aGlzKTsKICAgICAgYXNzZXJ0Tm90QmxvYlVybCh0aGlzKTsKICAgICAgaWYgKHRoaXMuZmlsbCkgewogICAgICAgIGFzc2VydEVtcHR5V2lkdGhBbmRIZWlnaHQodGhpcyk7CiAgICAgICAgbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IGFzc2VydE5vblplcm9SZW5kZXJlZEhlaWdodCh0aGlzLCB0aGlzLmltZ0VsZW1lbnQsIHRoaXMucmVuZGVyZXIpKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBhc3NlcnROb25FbXB0eVdpZHRoQW5kSGVpZ2h0KHRoaXMpOwogICAgICAgIGlmICh0aGlzLmhlaWdodCAhPT0gdm9pZCAwKSB7CiAgICAgICAgICBhc3NlcnRHcmVhdGVyVGhhblplcm8odGhpcywgdGhpcy5oZWlnaHQsICJoZWlnaHQiKTsKICAgICAgICB9CiAgICAgICAgaWYgKHRoaXMud2lkdGggIT09IHZvaWQgMCkgewogICAgICAgICAgYXNzZXJ0R3JlYXRlclRoYW5aZXJvKHRoaXMsIHRoaXMud2lkdGgsICJ3aWR0aCIpOwogICAgICAgIH0KICAgICAgICBuZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gYXNzZXJ0Tm9JbWFnZURpc3RvcnRpb24odGhpcywgdGhpcy5pbWdFbGVtZW50LCB0aGlzLnJlbmRlcmVyKSk7CiAgICAgIH0KICAgICAgYXNzZXJ0VmFsaWRMb2FkaW5nSW5wdXQodGhpcyk7CiAgICAgIGlmICghdGhpcy5uZ1NyY3NldCkgewogICAgICAgIGFzc2VydE5vQ29tcGxleFNpemVzKHRoaXMpOwogICAgICB9CiAgICAgIGFzc2VydFZhbGlkUGxhY2Vob2xkZXIodGhpcywgdGhpcy5pbWFnZUxvYWRlcik7CiAgICAgIGFzc2VydE5vdE1pc3NpbmdCdWlsdEluTG9hZGVyKHRoaXMubmdTcmMsIHRoaXMuaW1hZ2VMb2FkZXIpOwogICAgICBhc3NlcnROb05nU3Jjc2V0V2l0aG91dExvYWRlcih0aGlzLCB0aGlzLmltYWdlTG9hZGVyKTsKICAgICAgYXNzZXJ0Tm9Mb2FkZXJQYXJhbXNXaXRob3V0TG9hZGVyKHRoaXMsIHRoaXMuaW1hZ2VMb2FkZXIpOwogICAgICBpZiAodGhpcy5sY3BPYnNlcnZlciAhPT0gbnVsbCkgewogICAgICAgIGNvbnN0IG5nWm9uZTIgPSB0aGlzLmluamVjdG9yLmdldChOZ1pvbmUpOwogICAgICAgIG5nWm9uZTIucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gewogICAgICAgICAgdGhpcy5sY3BPYnNlcnZlci5yZWdpc3RlckltYWdlKHRoaXMuZ2V0UmV3cml0dGVuU3JjKCksIHRoaXMubmdTcmMsIHRoaXMucHJpb3JpdHkpOwogICAgICAgIH0pOwogICAgICB9CiAgICAgIGlmICh0aGlzLnByaW9yaXR5KSB7CiAgICAgICAgY29uc3QgY2hlY2tlciA9IHRoaXMuaW5qZWN0b3IuZ2V0KFByZWNvbm5lY3RMaW5rQ2hlY2tlcik7CiAgICAgICAgY2hlY2tlci5hc3NlcnRQcmVjb25uZWN0KHRoaXMuZ2V0UmV3cml0dGVuU3JjKCksIHRoaXMubmdTcmMpOwogICAgICB9CiAgICB9CiAgICBpZiAodGhpcy5wbGFjZWhvbGRlcikgewogICAgICB0aGlzLnJlbW92ZVBsYWNlaG9sZGVyT25Mb2FkKHRoaXMuaW1nRWxlbWVudCk7CiAgICB9CiAgICB0aGlzLnNldEhvc3RBdHRyaWJ1dGVzKCk7CiAgfQogIHNldEhvc3RBdHRyaWJ1dGVzKCkgewogICAgaWYgKHRoaXMuZmlsbCkgewogICAgICB0aGlzLnNpemVzIHx8PSAiMTAwdnciOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5zZXRIb3N0QXR0cmlidXRlKCJ3aWR0aCIsIHRoaXMud2lkdGgudG9TdHJpbmcoKSk7CiAgICAgIHRoaXMuc2V0SG9zdEF0dHJpYnV0ZSgiaGVpZ2h0IiwgdGhpcy5oZWlnaHQudG9TdHJpbmcoKSk7CiAgICB9CiAgICB0aGlzLnNldEhvc3RBdHRyaWJ1dGUoImxvYWRpbmciLCB0aGlzLmdldExvYWRpbmdCZWhhdmlvcigpKTsKICAgIHRoaXMuc2V0SG9zdEF0dHJpYnV0ZSgiZmV0Y2hwcmlvcml0eSIsIHRoaXMuZ2V0RmV0Y2hQcmlvcml0eSgpKTsKICAgIHRoaXMuc2V0SG9zdEF0dHJpYnV0ZSgibmctaW1nIiwgInRydWUiKTsKICAgIGNvbnN0IHJld3JpdHRlblNyY3NldCA9IHRoaXMudXBkYXRlU3JjQW5kU3Jjc2V0KCk7CiAgICBpZiAodGhpcy5zaXplcykgewogICAgICB0aGlzLnNldEhvc3RBdHRyaWJ1dGUoInNpemVzIiwgdGhpcy5zaXplcyk7CiAgICB9CiAgICBpZiAodGhpcy5pc1NlcnZlciAmJiB0aGlzLnByaW9yaXR5KSB7CiAgICAgIHRoaXMucHJlbG9hZExpbmtDcmVhdG9yLmNyZWF0ZVByZWxvYWRMaW5rVGFnKHRoaXMucmVuZGVyZXIsIHRoaXMuZ2V0UmV3cml0dGVuU3JjKCksIHJld3JpdHRlblNyY3NldCwgdGhpcy5zaXplcyk7CiAgICB9CiAgfQogIC8qKiBAbm9kb2MgKi8KICBuZ09uQ2hhbmdlcyhjaGFuZ2VzKSB7CiAgICBpZiAobmdEZXZNb2RlKSB7CiAgICAgIGFzc2VydE5vUG9zdEluaXRJbnB1dENoYW5nZSh0aGlzLCBjaGFuZ2VzLCBbIm5nU3Jjc2V0IiwgIndpZHRoIiwgImhlaWdodCIsICJwcmlvcml0eSIsICJmaWxsIiwgImxvYWRpbmciLCAic2l6ZXMiLCAibG9hZGVyUGFyYW1zIiwgImRpc2FibGVPcHRpbWl6ZWRTcmNzZXQiXSk7CiAgICB9CiAgICBpZiAoY2hhbmdlc1sibmdTcmMiXSAmJiAhY2hhbmdlc1sibmdTcmMiXS5pc0ZpcnN0Q2hhbmdlKCkpIHsKICAgICAgY29uc3Qgb2xkU3JjID0gdGhpcy5fcmVuZGVyZWRTcmM7CiAgICAgIHRoaXMudXBkYXRlU3JjQW5kU3Jjc2V0KHRydWUpOwogICAgICBjb25zdCBuZXdTcmMgPSB0aGlzLl9yZW5kZXJlZFNyYzsKICAgICAgaWYgKHRoaXMubGNwT2JzZXJ2ZXIgIT09IG51bGwgJiYgb2xkU3JjICYmIG5ld1NyYyAmJiBvbGRTcmMgIT09IG5ld1NyYykgewogICAgICAgIGNvbnN0IG5nWm9uZSA9IHRoaXMuaW5qZWN0b3IuZ2V0KE5nWm9uZSk7CiAgICAgICAgbmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHsKICAgICAgICAgIHRoaXMubGNwT2JzZXJ2ZXI/LnVwZGF0ZUltYWdlKG9sZFNyYywgbmV3U3JjKTsKICAgICAgICB9KTsKICAgICAgfQogICAgfQogIH0KICBjYWxsSW1hZ2VMb2FkZXIoY29uZmlnV2l0aG91dEN1c3RvbVBhcmFtcykgewogICAgbGV0IGF1Z21lbnRlZENvbmZpZyA9IGNvbmZpZ1dpdGhvdXRDdXN0b21QYXJhbXM7CiAgICBpZiAodGhpcy5sb2FkZXJQYXJhbXMpIHsKICAgICAgYXVnbWVudGVkQ29uZmlnLmxvYWRlclBhcmFtcyA9IHRoaXMubG9hZGVyUGFyYW1zOwogICAgfQogICAgcmV0dXJuIHRoaXMuaW1hZ2VMb2FkZXIoYXVnbWVudGVkQ29uZmlnKTsKICB9CiAgZ2V0TG9hZGluZ0JlaGF2aW9yKCkgewogICAgaWYgKCF0aGlzLnByaW9yaXR5ICYmIHRoaXMubG9hZGluZyAhPT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB0aGlzLmxvYWRpbmc7CiAgICB9CiAgICByZXR1cm4gdGhpcy5wcmlvcml0eSA/ICJlYWdlciIgOiAibGF6eSI7CiAgfQogIGdldEZldGNoUHJpb3JpdHkoKSB7CiAgICByZXR1cm4gdGhpcy5wcmlvcml0eSA/ICJoaWdoIiA6ICJhdXRvIjsKICB9CiAgZ2V0UmV3cml0dGVuU3JjKCkgewogICAgaWYgKCF0aGlzLl9yZW5kZXJlZFNyYykgewogICAgICBjb25zdCBpbWdDb25maWcgPSB7CiAgICAgICAgc3JjOiB0aGlzLm5nU3JjCiAgICAgIH07CiAgICAgIHRoaXMuX3JlbmRlcmVkU3JjID0gdGhpcy5jYWxsSW1hZ2VMb2FkZXIoaW1nQ29uZmlnKTsKICAgIH0KICAgIHJldHVybiB0aGlzLl9yZW5kZXJlZFNyYzsKICB9CiAgZ2V0UmV3cml0dGVuU3Jjc2V0KCkgewogICAgY29uc3Qgd2lkdGhTcmNTZXQgPSBWQUxJRF9XSURUSF9ERVNDUklQVE9SX1NSQ1NFVC50ZXN0KHRoaXMubmdTcmNzZXQpOwogICAgY29uc3QgZmluYWxTcmNzID0gdGhpcy5uZ1NyY3NldC5zcGxpdCgiLCIpLmZpbHRlcigoc3JjKSA9PiBzcmMgIT09ICIiKS5tYXAoKHNyY1N0cikgPT4gewogICAgICBzcmNTdHIgPSBzcmNTdHIudHJpbSgpOwogICAgICBjb25zdCB3aWR0aCA9IHdpZHRoU3JjU2V0ID8gcGFyc2VGbG9hdChzcmNTdHIpIDogcGFyc2VGbG9hdChzcmNTdHIpICogdGhpcy53aWR0aDsKICAgICAgcmV0dXJuIGAke3RoaXMuY2FsbEltYWdlTG9hZGVyKHsKICAgICAgICBzcmM6IHRoaXMubmdTcmMsCiAgICAgICAgd2lkdGgKICAgICAgfSl9ICR7c3JjU3RyfWA7CiAgICB9KTsKICAgIHJldHVybiBmaW5hbFNyY3Muam9pbigiLCAiKTsKICB9CiAgZ2V0QXV0b21hdGljU3Jjc2V0KCkgewogICAgaWYgKHRoaXMuc2l6ZXMpIHsKICAgICAgcmV0dXJuIHRoaXMuZ2V0UmVzcG9uc2l2ZVNyY3NldCgpOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIHRoaXMuZ2V0Rml4ZWRTcmNzZXQoKTsKICAgIH0KICB9CiAgZ2V0UmVzcG9uc2l2ZVNyY3NldCgpIHsKICAgIGNvbnN0IHsKICAgICAgYnJlYWtwb2ludHMKICAgIH0gPSB0aGlzLmNvbmZpZzsKICAgIGxldCBmaWx0ZXJlZEJyZWFrcG9pbnRzID0gYnJlYWtwb2ludHM7CiAgICBpZiAodGhpcy5zaXplcz8udHJpbSgpID09PSAiMTAwdnciKSB7CiAgICAgIGZpbHRlcmVkQnJlYWtwb2ludHMgPSBicmVha3BvaW50cy5maWx0ZXIoKGJwKSA9PiBicCA+PSBWSUVXUE9SVF9CUkVBS1BPSU5UX0NVVE9GRik7CiAgICB9CiAgICBjb25zdCBmaW5hbFNyY3MgPSBmaWx0ZXJlZEJyZWFrcG9pbnRzLm1hcCgoYnApID0+IGAke3RoaXMuY2FsbEltYWdlTG9hZGVyKHsKICAgICAgc3JjOiB0aGlzLm5nU3JjLAogICAgICB3aWR0aDogYnAKICAgIH0pfSAke2JwfXdgKTsKICAgIHJldHVybiBmaW5hbFNyY3Muam9pbigiLCAiKTsKICB9CiAgdXBkYXRlU3JjQW5kU3Jjc2V0KGZvcmNlU3JjUmVjYWxjID0gZmFsc2UpIHsKICAgIGlmIChmb3JjZVNyY1JlY2FsYykgewogICAgICB0aGlzLl9yZW5kZXJlZFNyYyA9IG51bGw7CiAgICB9CiAgICBjb25zdCByZXdyaXR0ZW5TcmMgPSB0aGlzLmdldFJld3JpdHRlblNyYygpOwogICAgdGhpcy5zZXRIb3N0QXR0cmlidXRlKCJzcmMiLCByZXdyaXR0ZW5TcmMpOwogICAgbGV0IHJld3JpdHRlblNyY3NldCA9IHZvaWQgMDsKICAgIGlmICh0aGlzLm5nU3Jjc2V0KSB7CiAgICAgIHJld3JpdHRlblNyY3NldCA9IHRoaXMuZ2V0UmV3cml0dGVuU3Jjc2V0KCk7CiAgICB9IGVsc2UgaWYgKHRoaXMuc2hvdWxkR2VuZXJhdGVBdXRvbWF0aWNTcmNzZXQoKSkgewogICAgICByZXdyaXR0ZW5TcmNzZXQgPSB0aGlzLmdldEF1dG9tYXRpY1NyY3NldCgpOwogICAgfQogICAgaWYgKHJld3JpdHRlblNyY3NldCkgewogICAgICB0aGlzLnNldEhvc3RBdHRyaWJ1dGUoInNyY3NldCIsIHJld3JpdHRlblNyY3NldCk7CiAgICB9CiAgICByZXR1cm4gcmV3cml0dGVuU3Jjc2V0OwogIH0KICBnZXRGaXhlZFNyY3NldCgpIHsKICAgIGNvbnN0IGZpbmFsU3JjcyA9IERFTlNJVFlfU1JDU0VUX01VTFRJUExJRVJTLm1hcCgobXVsdGlwbGllcikgPT4gYCR7dGhpcy5jYWxsSW1hZ2VMb2FkZXIoewogICAgICBzcmM6IHRoaXMubmdTcmMsCiAgICAgIHdpZHRoOiB0aGlzLndpZHRoICogbXVsdGlwbGllcgogICAgfSl9ICR7bXVsdGlwbGllcn14YCk7CiAgICByZXR1cm4gZmluYWxTcmNzLmpvaW4oIiwgIik7CiAgfQogIHNob3VsZEdlbmVyYXRlQXV0b21hdGljU3Jjc2V0KCkgewogICAgbGV0IG92ZXJzaXplZEltYWdlID0gZmFsc2U7CiAgICBpZiAoIXRoaXMuc2l6ZXMpIHsKICAgICAgb3ZlcnNpemVkSW1hZ2UgPSB0aGlzLndpZHRoID4gRklYRURfU1JDU0VUX1dJRFRIX0xJTUlUIHx8IHRoaXMuaGVpZ2h0ID4gRklYRURfU1JDU0VUX0hFSUdIVF9MSU1JVDsKICAgIH0KICAgIHJldHVybiAhdGhpcy5kaXNhYmxlT3B0aW1pemVkU3Jjc2V0ICYmICF0aGlzLnNyY3NldCAmJiB0aGlzLmltYWdlTG9hZGVyICE9PSBub29wSW1hZ2VMb2FkZXIgJiYgIW92ZXJzaXplZEltYWdlOwogIH0KICAvKioKICAgKiBSZXR1cm5zIGFuIGltYWdlIHVybCBmb3JtYXR0ZWQgZm9yIHVzZSB3aXRoIHRoZSBDU1MgYmFja2dyb3VuZC1pbWFnZSBwcm9wZXJ0eS4gRXhwZWN0cyBvbmUgb2Y6CiAgICogKiBBIGJhc2U2NCBlbmNvZGVkIGltYWdlLCB3aGljaCBpcyB3cmFwcGVkIGFuZCBwYXNzZWQgdGhyb3VnaC4KICAgKiAqIEEgYm9vbGVhbi4gSWYgdHJ1ZSwgY2FsbHMgdGhlIGltYWdlIGxvYWRlciB0byBnZW5lcmF0ZSBhIHNtYWxsIHBsYWNlaG9sZGVyIHVybC4KICAgKi8KICBnZW5lcmF0ZVBsYWNlaG9sZGVyKHBsYWNlaG9sZGVySW5wdXQpIHsKICAgIGNvbnN0IHsKICAgICAgcGxhY2Vob2xkZXJSZXNvbHV0aW9uCiAgICB9ID0gdGhpcy5jb25maWc7CiAgICBpZiAocGxhY2Vob2xkZXJJbnB1dCA9PT0gdHJ1ZSkgewogICAgICByZXR1cm4gYHVybCgke3RoaXMuY2FsbEltYWdlTG9hZGVyKHsKICAgICAgICBzcmM6IHRoaXMubmdTcmMsCiAgICAgICAgd2lkdGg6IHBsYWNlaG9sZGVyUmVzb2x1dGlvbiwKICAgICAgICBpc1BsYWNlaG9sZGVyOiB0cnVlCiAgICAgIH0pfSlgOwogICAgfSBlbHNlIGlmICh0eXBlb2YgcGxhY2Vob2xkZXJJbnB1dCA9PT0gInN0cmluZyIgJiYgcGxhY2Vob2xkZXJJbnB1dC5zdGFydHNXaXRoKCJkYXRhOiIpKSB7CiAgICAgIHJldHVybiBgdXJsKCR7cGxhY2Vob2xkZXJJbnB1dH0pYDsKICAgIH0KICAgIHJldHVybiBudWxsOwogIH0KICAvKioKICAgKiBEZXRlcm1pbmVzIGlmIGJsdXIgc2hvdWxkIGJlIGFwcGxpZWQsIGJhc2VkIG9uIGFuIG9wdGlvbmFsIGJvb2xlYW4KICAgKiBwcm9wZXJ0eSBgYmx1cmAgd2l0aGluIHRoZSBvcHRpb25hbCBjb25maWd1cmF0aW9uIG9iamVjdCBgcGxhY2Vob2xkZXJDb25maWdgLgogICAqLwogIHNob3VsZEJsdXJQbGFjZWhvbGRlcihwbGFjZWhvbGRlckNvbmZpZykgewogICAgaWYgKCFwbGFjZWhvbGRlckNvbmZpZyB8fCAhcGxhY2Vob2xkZXJDb25maWcuaGFzT3duUHJvcGVydHkoImJsdXIiKSkgewogICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBCb29sZWFuKHBsYWNlaG9sZGVyQ29uZmlnLmJsdXIpOwogIH0KICByZW1vdmVQbGFjZWhvbGRlck9uTG9hZChpbWcpIHsKICAgIGNvbnN0IGNhbGxiYWNrID0gKCkgPT4gewogICAgICBjb25zdCBjaGFuZ2VEZXRlY3RvclJlZiA9IHRoaXMuaW5qZWN0b3IuZ2V0KENoYW5nZURldGVjdG9yUmVmKTsKICAgICAgcmVtb3ZlTG9hZExpc3RlbmVyRm4oKTsKICAgICAgcmVtb3ZlRXJyb3JMaXN0ZW5lckZuKCk7CiAgICAgIHRoaXMucGxhY2Vob2xkZXIgPSBmYWxzZTsKICAgICAgY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7CiAgICB9OwogICAgY29uc3QgcmVtb3ZlTG9hZExpc3RlbmVyRm4gPSB0aGlzLnJlbmRlcmVyLmxpc3RlbihpbWcsICJsb2FkIiwgY2FsbGJhY2spOwogICAgY29uc3QgcmVtb3ZlRXJyb3JMaXN0ZW5lckZuID0gdGhpcy5yZW5kZXJlci5saXN0ZW4oaW1nLCAiZXJyb3IiLCBjYWxsYmFjayk7CiAgfQogIC8qKiBAbm9kb2MgKi8KICBuZ09uRGVzdHJveSgpIHsKICAgIGlmIChuZ0Rldk1vZGUpIHsKICAgICAgaWYgKCF0aGlzLnByaW9yaXR5ICYmIHRoaXMuX3JlbmRlcmVkU3JjICE9PSBudWxsICYmIHRoaXMubGNwT2JzZXJ2ZXIgIT09IG51bGwpIHsKICAgICAgICB0aGlzLmxjcE9ic2VydmVyLnVucmVnaXN0ZXJJbWFnZSh0aGlzLl9yZW5kZXJlZFNyYyk7CiAgICAgIH0KICAgIH0KICB9CiAgc2V0SG9zdEF0dHJpYnV0ZShuYW1lLCB2YWx1ZSkgewogICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUodGhpcy5pbWdFbGVtZW50LCBuYW1lLCB2YWx1ZSk7CiAgfQp9OwpfTmdPcHRpbWl6ZWRJbWFnZS7JtWZhYyA9IGZ1bmN0aW9uIE5nT3B0aW1pemVkSW1hZ2VfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTmdPcHRpbWl6ZWRJbWFnZSkoKTsKfTsKX05nT3B0aW1pemVkSW1hZ2UuybVkaXIgPSDJtcm1ZGVmaW5lRGlyZWN0aXZlKHsKICB0eXBlOiBfTmdPcHRpbWl6ZWRJbWFnZSwKICBzZWxlY3RvcnM6IFtbImltZyIsICJuZ1NyYyIsICIiXV0sCiAgaG9zdFZhcnM6IDE4LAogIGhvc3RCaW5kaW5nczogZnVuY3Rpb24gTmdPcHRpbWl6ZWRJbWFnZV9Ib3N0QmluZGluZ3MocmYsIGN0eCkgewogICAgaWYgKHJmICYgMikgewogICAgICDJtcm1c3R5bGVQcm9wKCJwb3NpdGlvbiIsIGN0eC5maWxsID8gImFic29sdXRlIiA6IG51bGwpKCJ3aWR0aCIsIGN0eC5maWxsID8gIjEwMCUiIDogbnVsbCkoImhlaWdodCIsIGN0eC5maWxsID8gIjEwMCUiIDogbnVsbCkoImluc2V0IiwgY3R4LmZpbGwgPyAiMCIgOiBudWxsKSgiYmFja2dyb3VuZC1zaXplIiwgY3R4LnBsYWNlaG9sZGVyID8gImNvdmVyIiA6IG51bGwpKCJiYWNrZ3JvdW5kLXBvc2l0aW9uIiwgY3R4LnBsYWNlaG9sZGVyID8gIjUwJSA1MCUiIDogbnVsbCkoImJhY2tncm91bmQtcmVwZWF0IiwgY3R4LnBsYWNlaG9sZGVyID8gIm5vLXJlcGVhdCIgOiBudWxsKSgiYmFja2dyb3VuZC1pbWFnZSIsIGN0eC5wbGFjZWhvbGRlciA/IGN0eC5nZW5lcmF0ZVBsYWNlaG9sZGVyKGN0eC5wbGFjZWhvbGRlcikgOiBudWxsKSgiZmlsdGVyIiwgY3R4LnBsYWNlaG9sZGVyICYmIGN0eC5zaG91bGRCbHVyUGxhY2Vob2xkZXIoY3R4LnBsYWNlaG9sZGVyQ29uZmlnKSA/ICJibHVyKDE1cHgpIiA6IG51bGwpOwogICAgfQogIH0sCiAgaW5wdXRzOiB7CiAgICBuZ1NyYzogWzIsICJuZ1NyYyIsICJuZ1NyYyIsIHVud3JhcFNhZmVVcmxdLAogICAgbmdTcmNzZXQ6ICJuZ1NyY3NldCIsCiAgICBzaXplczogInNpemVzIiwKICAgIHdpZHRoOiBbMiwgIndpZHRoIiwgIndpZHRoIiwgbnVtYmVyQXR0cmlidXRlXSwKICAgIGhlaWdodDogWzIsICJoZWlnaHQiLCAiaGVpZ2h0IiwgbnVtYmVyQXR0cmlidXRlXSwKICAgIGxvYWRpbmc6ICJsb2FkaW5nIiwKICAgIHByaW9yaXR5OiBbMiwgInByaW9yaXR5IiwgInByaW9yaXR5IiwgYm9vbGVhbkF0dHJpYnV0ZV0sCiAgICBsb2FkZXJQYXJhbXM6ICJsb2FkZXJQYXJhbXMiLAogICAgZGlzYWJsZU9wdGltaXplZFNyY3NldDogWzIsICJkaXNhYmxlT3B0aW1pemVkU3Jjc2V0IiwgImRpc2FibGVPcHRpbWl6ZWRTcmNzZXQiLCBib29sZWFuQXR0cmlidXRlXSwKICAgIGZpbGw6IFsyLCAiZmlsbCIsICJmaWxsIiwgYm9vbGVhbkF0dHJpYnV0ZV0sCiAgICBwbGFjZWhvbGRlcjogWzIsICJwbGFjZWhvbGRlciIsICJwbGFjZWhvbGRlciIsIGJvb2xlYW5PckRhdGFVcmxBdHRyaWJ1dGVdLAogICAgcGxhY2Vob2xkZXJDb25maWc6ICJwbGFjZWhvbGRlckNvbmZpZyIsCiAgICBzcmM6ICJzcmMiLAogICAgc3Jjc2V0OiAic3Jjc2V0IgogIH0sCiAgc3RhbmRhbG9uZTogdHJ1ZSwKICBmZWF0dXJlczogW8m1ybVJbnB1dFRyYW5zZm9ybXNGZWF0dXJlLCDJtcm1TmdPbkNoYW5nZXNGZWF0dXJlXQp9KTsKdmFyIE5nT3B0aW1pemVkSW1hZ2UgPSBfTmdPcHRpbWl6ZWRJbWFnZTsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKE5nT3B0aW1pemVkSW1hZ2UsIFt7CiAgICB0eXBlOiBEaXJlY3RpdmUsCiAgICBhcmdzOiBbewogICAgICBzdGFuZGFsb25lOiB0cnVlLAogICAgICBzZWxlY3RvcjogImltZ1tuZ1NyY10iLAogICAgICBob3N0OiB7CiAgICAgICAgIltzdHlsZS5wb3NpdGlvbl0iOiAnZmlsbCA/ICJhYnNvbHV0ZSIgOiBudWxsJywKICAgICAgICAiW3N0eWxlLndpZHRoXSI6ICdmaWxsID8gIjEwMCUiIDogbnVsbCcsCiAgICAgICAgIltzdHlsZS5oZWlnaHRdIjogJ2ZpbGwgPyAiMTAwJSIgOiBudWxsJywKICAgICAgICAiW3N0eWxlLmluc2V0XSI6ICdmaWxsID8gIjAiIDogbnVsbCcsCiAgICAgICAgIltzdHlsZS5iYWNrZ3JvdW5kLXNpemVdIjogJ3BsYWNlaG9sZGVyID8gImNvdmVyIiA6IG51bGwnLAogICAgICAgICJbc3R5bGUuYmFja2dyb3VuZC1wb3NpdGlvbl0iOiAncGxhY2Vob2xkZXIgPyAiNTAlIDUwJSIgOiBudWxsJywKICAgICAgICAiW3N0eWxlLmJhY2tncm91bmQtcmVwZWF0XSI6ICdwbGFjZWhvbGRlciA/ICJuby1yZXBlYXQiIDogbnVsbCcsCiAgICAgICAgIltzdHlsZS5iYWNrZ3JvdW5kLWltYWdlXSI6ICJwbGFjZWhvbGRlciA/IGdlbmVyYXRlUGxhY2Vob2xkZXIocGxhY2Vob2xkZXIpIDogbnVsbCIsCiAgICAgICAgIltzdHlsZS5maWx0ZXJdIjogYHBsYWNlaG9sZGVyICYmIHNob3VsZEJsdXJQbGFjZWhvbGRlcihwbGFjZWhvbGRlckNvbmZpZykgPyAiYmx1cigke1BMQUNFSE9MREVSX0JMVVJfQU1PVU5UfXB4KSIgOiBudWxsYAogICAgICB9CiAgICB9XQogIH1dLCBudWxsLCB7CiAgICBuZ1NyYzogW3sKICAgICAgdHlwZTogSW5wdXQsCiAgICAgIGFyZ3M6IFt7CiAgICAgICAgcmVxdWlyZWQ6IHRydWUsCiAgICAgICAgdHJhbnNmb3JtOiB1bndyYXBTYWZlVXJsCiAgICAgIH1dCiAgICB9XSwKICAgIG5nU3Jjc2V0OiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0sCiAgICBzaXplczogW3sKICAgICAgdHlwZTogSW5wdXQKICAgIH1dLAogICAgd2lkdGg6IFt7CiAgICAgIHR5cGU6IElucHV0LAogICAgICBhcmdzOiBbewogICAgICAgIHRyYW5zZm9ybTogbnVtYmVyQXR0cmlidXRlCiAgICAgIH1dCiAgICB9XSwKICAgIGhlaWdodDogW3sKICAgICAgdHlwZTogSW5wdXQsCiAgICAgIGFyZ3M6IFt7CiAgICAgICAgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGUKICAgICAgfV0KICAgIH1dLAogICAgbG9hZGluZzogW3sKICAgICAgdHlwZTogSW5wdXQKICAgIH1dLAogICAgcHJpb3JpdHk6IFt7CiAgICAgIHR5cGU6IElucHV0LAogICAgICBhcmdzOiBbewogICAgICAgIHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZQogICAgICB9XQogICAgfV0sCiAgICBsb2FkZXJQYXJhbXM6IFt7CiAgICAgIHR5cGU6IElucHV0CiAgICB9XSwKICAgIGRpc2FibGVPcHRpbWl6ZWRTcmNzZXQ6IFt7CiAgICAgIHR5cGU6IElucHV0LAogICAgICBhcmdzOiBbewogICAgICAgIHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZQogICAgICB9XQogICAgfV0sCiAgICBmaWxsOiBbewogICAgICB0eXBlOiBJbnB1dCwKICAgICAgYXJnczogW3sKICAgICAgICB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGUKICAgICAgfV0KICAgIH1dLAogICAgcGxhY2Vob2xkZXI6IFt7CiAgICAgIHR5cGU6IElucHV0LAogICAgICBhcmdzOiBbewogICAgICAgIHRyYW5zZm9ybTogYm9vbGVhbk9yRGF0YVVybEF0dHJpYnV0ZQogICAgICB9XQogICAgfV0sCiAgICBwbGFjZWhvbGRlckNvbmZpZzogW3sKICAgICAgdHlwZTogSW5wdXQKICAgIH1dLAogICAgc3JjOiBbewogICAgICB0eXBlOiBJbnB1dAogICAgfV0sCiAgICBzcmNzZXQ6IFt7CiAgICAgIHR5cGU6IElucHV0CiAgICB9XQogIH0pOwp9KSgpOwpmdW5jdGlvbiBwcm9jZXNzQ29uZmlnKGNvbmZpZykgewogIGxldCBzb3J0ZWRCcmVha3BvaW50cyA9IHt9OwogIGlmIChjb25maWcuYnJlYWtwb2ludHMpIHsKICAgIHNvcnRlZEJyZWFrcG9pbnRzLmJyZWFrcG9pbnRzID0gY29uZmlnLmJyZWFrcG9pbnRzLnNvcnQoKGEsIGIpID0+IGEgLSBiKTsKICB9CiAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIElNQUdFX0NPTkZJR19ERUZBVUxUUywgY29uZmlnLCBzb3J0ZWRCcmVha3BvaW50cyk7Cn0KZnVuY3Rpb24gYXNzZXJ0Tm9Db25mbGljdGluZ1NyYyhkaXIpIHsKICBpZiAoZGlyLnNyYykgewogICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigyOTUwLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IGJvdGggXGBzcmNcYCBhbmQgXGBuZ1NyY1xgIGhhdmUgYmVlbiBzZXQuIFN1cHBseWluZyBib3RoIG9mIHRoZXNlIGF0dHJpYnV0ZXMgYnJlYWtzIGxhenkgbG9hZGluZy4gVGhlIE5nT3B0aW1pemVkSW1hZ2UgZGlyZWN0aXZlIHNldHMgXGBzcmNcYCBpdHNlbGYgYmFzZWQgb24gdGhlIHZhbHVlIG9mIFxgbmdTcmNcYC4gVG8gZml4IHRoaXMsIHBsZWFzZSByZW1vdmUgdGhlIFxgc3JjXGAgYXR0cmlidXRlLmApOwogIH0KfQpmdW5jdGlvbiBhc3NlcnROb0NvbmZsaWN0aW5nU3Jjc2V0KGRpcikgewogIGlmIChkaXIuc3Jjc2V0KSB7CiAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDI5NTEsIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gYm90aCBcYHNyY3NldFxgIGFuZCBcYG5nU3Jjc2V0XGAgaGF2ZSBiZWVuIHNldC4gU3VwcGx5aW5nIGJvdGggb2YgdGhlc2UgYXR0cmlidXRlcyBicmVha3MgbGF6eSBsb2FkaW5nLiBUaGUgTmdPcHRpbWl6ZWRJbWFnZSBkaXJlY3RpdmUgc2V0cyBcYHNyY3NldFxgIGl0c2VsZiBiYXNlZCBvbiB0aGUgdmFsdWUgb2YgXGBuZ1NyY3NldFxgLiBUbyBmaXggdGhpcywgcGxlYXNlIHJlbW92ZSB0aGUgXGBzcmNzZXRcYCBhdHRyaWJ1dGUuYCk7CiAgfQp9CmZ1bmN0aW9uIGFzc2VydE5vdEJhc2U2NEltYWdlKGRpcikgewogIGxldCBuZ1NyYyA9IGRpci5uZ1NyYy50cmltKCk7CiAgaWYgKG5nU3JjLnN0YXJ0c1dpdGgoImRhdGE6IikpIHsKICAgIGlmIChuZ1NyYy5sZW5ndGggPiBCQVNFNjRfSU1HX01BWF9MRU5HVEhfSU5fRVJST1IpIHsKICAgICAgbmdTcmMgPSBuZ1NyYy5zdWJzdHJpbmcoMCwgQkFTRTY0X0lNR19NQVhfTEVOR1RIX0lOX0VSUk9SKSArICIuLi4iOwogICAgfQogICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigyOTUyLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYywgZmFsc2UpfSBcYG5nU3JjXGAgaXMgYSBCYXNlNjQtZW5jb2RlZCBzdHJpbmcgKCR7bmdTcmN9KS4gTmdPcHRpbWl6ZWRJbWFnZSBkb2VzIG5vdCBzdXBwb3J0IEJhc2U2NC1lbmNvZGVkIHN0cmluZ3MuIFRvIGZpeCB0aGlzLCBkaXNhYmxlIHRoZSBOZ09wdGltaXplZEltYWdlIGRpcmVjdGl2ZSBmb3IgdGhpcyBlbGVtZW50IGJ5IHJlbW92aW5nIFxgbmdTcmNcYCBhbmQgdXNpbmcgYSBzdGFuZGFyZCBcYHNyY1xgIGF0dHJpYnV0ZSBpbnN0ZWFkLmApOwogIH0KfQpmdW5jdGlvbiBhc3NlcnROb0NvbXBsZXhTaXplcyhkaXIpIHsKICBsZXQgc2l6ZXMgPSBkaXIuc2l6ZXM7CiAgaWYgKHNpemVzPy5tYXRjaCgvKChcKXwsKVxzfF4pXGQrcHgvKSkgewogICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigyOTUyLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYywgZmFsc2UpfSBcYHNpemVzXGAgd2FzIHNldCB0byBhIHN0cmluZyBpbmNsdWRpbmcgcGl4ZWwgdmFsdWVzLiBGb3IgYXV0b21hdGljIFxgc3Jjc2V0XGAgZ2VuZXJhdGlvbiwgXGBzaXplc1xgIG11c3Qgb25seSBpbmNsdWRlIHJlc3BvbnNpdmUgdmFsdWVzLCBzdWNoIGFzIFxgc2l6ZXM9IjUwdnciXGAgb3IgXGBzaXplcz0iKG1pbi13aWR0aDogNzY4cHgpIDUwdncsIDEwMHZ3IlxgLiBUbyBmaXggdGhpcywgbW9kaWZ5IHRoZSBcYHNpemVzXGAgYXR0cmlidXRlLCBvciBwcm92aWRlIHlvdXIgb3duIFxgbmdTcmNzZXRcYCB2YWx1ZSBkaXJlY3RseS5gKTsKICB9Cn0KZnVuY3Rpb24gYXNzZXJ0VmFsaWRQbGFjZWhvbGRlcihkaXIsIGltYWdlTG9hZGVyKSB7CiAgYXNzZXJ0Tm9QbGFjZWhvbGRlckNvbmZpZ1dpdGhvdXRQbGFjZWhvbGRlcihkaXIpOwogIGFzc2VydE5vUmVsYXRpdmVQbGFjZWhvbGRlcldpdGhvdXRMb2FkZXIoZGlyLCBpbWFnZUxvYWRlcik7CiAgYXNzZXJ0Tm9PdmVyc2l6ZWREYXRhVXJsKGRpcik7Cn0KZnVuY3Rpb24gYXNzZXJ0Tm9QbGFjZWhvbGRlckNvbmZpZ1dpdGhvdXRQbGFjZWhvbGRlcihkaXIpIHsKICBpZiAoZGlyLnBsYWNlaG9sZGVyQ29uZmlnICYmICFkaXIucGxhY2Vob2xkZXIpIHsKICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoMjk1MiwgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMsIGZhbHNlKX0gXGBwbGFjZWhvbGRlckNvbmZpZ1xgIG9wdGlvbnMgd2VyZSBwcm92aWRlZCBmb3IgYW4gaW1hZ2UgdGhhdCBkb2VzIG5vdCB1c2UgdGhlIFxgcGxhY2Vob2xkZXJcYCBhdHRyaWJ1dGUsIGFuZCB3aWxsIGhhdmUgbm8gZWZmZWN0LmApOwogIH0KfQpmdW5jdGlvbiBhc3NlcnROb1JlbGF0aXZlUGxhY2Vob2xkZXJXaXRob3V0TG9hZGVyKGRpciwgaW1hZ2VMb2FkZXIpIHsKICBpZiAoZGlyLnBsYWNlaG9sZGVyID09PSB0cnVlICYmIGltYWdlTG9hZGVyID09PSBub29wSW1hZ2VMb2FkZXIpIHsKICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoMjk2MywgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSB0aGUgXGBwbGFjZWhvbGRlclxgIGF0dHJpYnV0ZSBpcyBzZXQgdG8gdHJ1ZSBidXQgbm8gaW1hZ2UgbG9hZGVyIGlzIGNvbmZpZ3VyZWQgKGkuZS4gdGhlIGRlZmF1bHQgb25lIGlzIGJlaW5nIHVzZWQpLCB3aGljaCB3b3VsZCByZXN1bHQgaW4gdGhlIHNhbWUgaW1hZ2UgYmVpbmcgdXNlZCBmb3IgdGhlIHByaW1hcnkgaW1hZ2UgYW5kIGl0cyBwbGFjZWhvbGRlci4gVG8gZml4IHRoaXMsIHByb3ZpZGUgYSBsb2FkZXIgb3IgcmVtb3ZlIHRoZSBcYHBsYWNlaG9sZGVyXGAgYXR0cmlidXRlIGZyb20gdGhlIGltYWdlLmApOwogIH0KfQpmdW5jdGlvbiBhc3NlcnROb092ZXJzaXplZERhdGFVcmwoZGlyKSB7CiAgaWYgKGRpci5wbGFjZWhvbGRlciAmJiB0eXBlb2YgZGlyLnBsYWNlaG9sZGVyID09PSAic3RyaW5nIiAmJiBkaXIucGxhY2Vob2xkZXIuc3RhcnRzV2l0aCgiZGF0YToiKSkgewogICAgaWYgKGRpci5wbGFjZWhvbGRlci5sZW5ndGggPiBEQVRBX1VSTF9FUlJPUl9MSU1JVCkgewogICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDI5NjUsIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gdGhlIFxgcGxhY2Vob2xkZXJcYCBhdHRyaWJ1dGUgaXMgc2V0IHRvIGEgZGF0YSBVUkwgd2hpY2ggaXMgbG9uZ2VyIHRoYW4gJHtEQVRBX1VSTF9FUlJPUl9MSU1JVH0gY2hhcmFjdGVycy4gVGhpcyBpcyBzdHJvbmdseSBkaXNjb3VyYWdlZCwgYXMgbGFyZ2UgaW5saW5lIHBsYWNlaG9sZGVycyBkaXJlY3RseSBpbmNyZWFzZSB0aGUgYnVuZGxlIHNpemUgb2YgQW5ndWxhciBhbmQgaHVydCBwYWdlIGxvYWQgcGVyZm9ybWFuY2UuIFRvIGZpeCB0aGlzLCBnZW5lcmF0ZSBhIHNtYWxsZXIgZGF0YSBVUkwgcGxhY2Vob2xkZXIuYCk7CiAgICB9CiAgICBpZiAoZGlyLnBsYWNlaG9sZGVyLmxlbmd0aCA+IERBVEFfVVJMX1dBUk5fTElNSVQpIHsKICAgICAgY29uc29sZS53YXJuKGZvcm1hdFJ1bnRpbWVFcnJvcigyOTY1LCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IHRoZSBcYHBsYWNlaG9sZGVyXGAgYXR0cmlidXRlIGlzIHNldCB0byBhIGRhdGEgVVJMIHdoaWNoIGlzIGxvbmdlciB0aGFuICR7REFUQV9VUkxfV0FSTl9MSU1JVH0gY2hhcmFjdGVycy4gVGhpcyBpcyBkaXNjb3VyYWdlZCwgYXMgbGFyZ2UgaW5saW5lIHBsYWNlaG9sZGVycyBkaXJlY3RseSBpbmNyZWFzZSB0aGUgYnVuZGxlIHNpemUgb2YgQW5ndWxhciBhbmQgaHVydCBwYWdlIGxvYWQgcGVyZm9ybWFuY2UuIEZvciBiZXR0ZXIgbG9hZGluZyBwZXJmb3JtYW5jZSwgZ2VuZXJhdGUgYSBzbWFsbGVyIGRhdGEgVVJMIHBsYWNlaG9sZGVyLmApKTsKICAgIH0KICB9Cn0KZnVuY3Rpb24gYXNzZXJ0Tm90QmxvYlVybChkaXIpIHsKICBjb25zdCBuZ1NyYyA9IGRpci5uZ1NyYy50cmltKCk7CiAgaWYgKG5nU3JjLnN0YXJ0c1dpdGgoImJsb2I6IikpIHsKICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoMjk1MiwgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSBcYG5nU3JjXGAgd2FzIHNldCB0byBhIGJsb2IgVVJMICgke25nU3JjfSkuIEJsb2IgVVJMcyBhcmUgbm90IHN1cHBvcnRlZCBieSB0aGUgTmdPcHRpbWl6ZWRJbWFnZSBkaXJlY3RpdmUuIFRvIGZpeCB0aGlzLCBkaXNhYmxlIHRoZSBOZ09wdGltaXplZEltYWdlIGRpcmVjdGl2ZSBmb3IgdGhpcyBlbGVtZW50IGJ5IHJlbW92aW5nIFxgbmdTcmNcYCBhbmQgdXNpbmcgYSByZWd1bGFyIFxgc3JjXGAgYXR0cmlidXRlIGluc3RlYWQuYCk7CiAgfQp9CmZ1bmN0aW9uIGFzc2VydE5vbkVtcHR5SW5wdXQoZGlyLCBuYW1lLCB2YWx1ZSkgewogIGNvbnN0IGlzU3RyaW5nID0gdHlwZW9mIHZhbHVlID09PSAic3RyaW5nIjsKICBjb25zdCBpc0VtcHR5U3RyaW5nID0gaXNTdHJpbmcgJiYgdmFsdWUudHJpbSgpID09PSAiIjsKICBpZiAoIWlzU3RyaW5nIHx8IGlzRW1wdHlTdHJpbmcpIHsKICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoMjk1MiwgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSBcYCR7bmFtZX1cYCBoYXMgYW4gaW52YWxpZCB2YWx1ZSAoXGAke3ZhbHVlfVxgKS4gVG8gZml4IHRoaXMsIGNoYW5nZSB0aGUgdmFsdWUgdG8gYSBub24tZW1wdHkgc3RyaW5nLmApOwogIH0KfQpmdW5jdGlvbiBhc3NlcnRWYWxpZE5nU3Jjc2V0KGRpciwgdmFsdWUpIHsKICBpZiAodmFsdWUgPT0gbnVsbCkKICAgIHJldHVybjsKICBhc3NlcnROb25FbXB0eUlucHV0KGRpciwgIm5nU3Jjc2V0IiwgdmFsdWUpOwogIGNvbnN0IHN0cmluZ1ZhbCA9IHZhbHVlOwogIGNvbnN0IGlzVmFsaWRXaWR0aERlc2NyaXB0b3IgPSBWQUxJRF9XSURUSF9ERVNDUklQVE9SX1NSQ1NFVC50ZXN0KHN0cmluZ1ZhbCk7CiAgY29uc3QgaXNWYWxpZERlbnNpdHlEZXNjcmlwdG9yID0gVkFMSURfREVOU0lUWV9ERVNDUklQVE9SX1NSQ1NFVC50ZXN0KHN0cmluZ1ZhbCk7CiAgaWYgKGlzVmFsaWREZW5zaXR5RGVzY3JpcHRvcikgewogICAgYXNzZXJ0VW5kZXJEZW5zaXR5Q2FwKGRpciwgc3RyaW5nVmFsKTsKICB9CiAgY29uc3QgaXNWYWxpZFNyY3NldCA9IGlzVmFsaWRXaWR0aERlc2NyaXB0b3IgfHwgaXNWYWxpZERlbnNpdHlEZXNjcmlwdG9yOwogIGlmICghaXNWYWxpZFNyY3NldCkgewogICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigyOTUyLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IFxgbmdTcmNzZXRcYCBoYXMgYW4gaW52YWxpZCB2YWx1ZSAoXGAke3ZhbHVlfVxgKS4gVG8gZml4IHRoaXMsIHN1cHBseSBcYG5nU3Jjc2V0XGAgdXNpbmcgYSBjb21tYS1zZXBhcmF0ZWQgbGlzdCBvZiBvbmUgb3IgbW9yZSB3aWR0aCBkZXNjcmlwdG9ycyAoZS5nLiAiMTAwdywgMjAwdyIpIG9yIGRlbnNpdHkgZGVzY3JpcHRvcnMgKGUuZy4gIjF4LCAyeCIpLmApOwogIH0KfQpmdW5jdGlvbiBhc3NlcnRVbmRlckRlbnNpdHlDYXAoZGlyLCB2YWx1ZSkgewogIGNvbnN0IHVuZGVyRGVuc2l0eUNhcCA9IHZhbHVlLnNwbGl0KCIsIikuZXZlcnkoKG51bSkgPT4gbnVtID09PSAiIiB8fCBwYXJzZUZsb2F0KG51bSkgPD0gQUJTT0xVVEVfU1JDU0VUX0RFTlNJVFlfQ0FQKTsKICBpZiAoIXVuZGVyRGVuc2l0eUNhcCkgewogICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigyOTUyLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IHRoZSBcYG5nU3Jjc2V0XGAgY29udGFpbnMgYW4gdW5zdXBwb3J0ZWQgaW1hZ2UgZGVuc2l0eTpcYCR7dmFsdWV9XGAuIE5nT3B0aW1pemVkSW1hZ2UgZ2VuZXJhbGx5IHJlY29tbWVuZHMgYSBtYXggaW1hZ2UgZGVuc2l0eSBvZiAke1JFQ09NTUVOREVEX1NSQ1NFVF9ERU5TSVRZX0NBUH14IGJ1dCBzdXBwb3J0cyBpbWFnZSBkZW5zaXRpZXMgdXAgdG8gJHtBQlNPTFVURV9TUkNTRVRfREVOU0lUWV9DQVB9eC4gVGhlIGh1bWFuIGV5ZSBjYW5ub3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBpbWFnZSBkZW5zaXRpZXMgZ3JlYXRlciB0aGFuICR7UkVDT01NRU5ERURfU1JDU0VUX0RFTlNJVFlfQ0FQfXggLSB3aGljaCBtYWtlcyB0aGVtIHVubmVjZXNzYXJ5IGZvciBtb3N0IHVzZSBjYXNlcy4gSW1hZ2VzIHRoYXQgd2lsbCBiZSBwaW5jaC16b29tZWQgYXJlIHR5cGljYWxseSB0aGUgcHJpbWFyeSB1c2UgY2FzZSBmb3IgJHtBQlNPTFVURV9TUkNTRVRfREVOU0lUWV9DQVB9eCBpbWFnZXMuIFBsZWFzZSByZW1vdmUgdGhlIGhpZ2ggZGVuc2l0eSBkZXNjcmlwdG9yIGFuZCB0cnkgYWdhaW4uYCk7CiAgfQp9CmZ1bmN0aW9uIHBvc3RJbml0SW5wdXRDaGFuZ2VFcnJvcihkaXIsIGlucHV0TmFtZSkgewogIGxldCByZWFzb247CiAgaWYgKGlucHV0TmFtZSA9PT0gIndpZHRoIiB8fCBpbnB1dE5hbWUgPT09ICJoZWlnaHQiKSB7CiAgICByZWFzb24gPSBgQ2hhbmdpbmcgXGAke2lucHV0TmFtZX1cYCBtYXkgcmVzdWx0IGluIGRpZmZlcmVudCBhdHRyaWJ1dGUgdmFsdWUgYXBwbGllZCB0byB0aGUgdW5kZXJseWluZyBpbWFnZSBlbGVtZW50IGFuZCBjYXVzZSBsYXlvdXQgc2hpZnRzIG9uIGEgcGFnZS5gOwogIH0gZWxzZSB7CiAgICByZWFzb24gPSBgQ2hhbmdpbmcgdGhlIFxgJHtpbnB1dE5hbWV9XGAgd291bGQgaGF2ZSBubyBlZmZlY3Qgb24gdGhlIHVuZGVybHlpbmcgaW1hZ2UgZWxlbWVudCwgYmVjYXVzZSB0aGUgcmVzb3VyY2UgbG9hZGluZyBoYXMgYWxyZWFkeSBvY2N1cnJlZC5gOwogIH0KICByZXR1cm4gbmV3IFJ1bnRpbWVFcnJvcigyOTUzLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IFxgJHtpbnB1dE5hbWV9XGAgd2FzIHVwZGF0ZWQgYWZ0ZXIgaW5pdGlhbGl6YXRpb24uIFRoZSBOZ09wdGltaXplZEltYWdlIGRpcmVjdGl2ZSB3aWxsIG5vdCByZWFjdCB0byB0aGlzIGlucHV0IGNoYW5nZS4gJHtyZWFzb259IFRvIGZpeCB0aGlzLCBlaXRoZXIgc3dpdGNoIFxgJHtpbnB1dE5hbWV9XGAgdG8gYSBzdGF0aWMgdmFsdWUgb3Igd3JhcCB0aGUgaW1hZ2UgZWxlbWVudCBpbiBhbiAqbmdJZiB0aGF0IGlzIGdhdGVkIG9uIHRoZSBuZWNlc3NhcnkgdmFsdWUuYCk7Cn0KZnVuY3Rpb24gYXNzZXJ0Tm9Qb3N0SW5pdElucHV0Q2hhbmdlKGRpciwgY2hhbmdlcywgaW5wdXRzKSB7CiAgaW5wdXRzLmZvckVhY2goKGlucHV0KSA9PiB7CiAgICBjb25zdCBpc1VwZGF0ZWQgPSBjaGFuZ2VzLmhhc093blByb3BlcnR5KGlucHV0KTsKICAgIGlmIChpc1VwZGF0ZWQgJiYgIWNoYW5nZXNbaW5wdXRdLmlzRmlyc3RDaGFuZ2UoKSkgewogICAgICBpZiAoaW5wdXQgPT09ICJuZ1NyYyIpIHsKICAgICAgICBkaXIgPSB7CiAgICAgICAgICBuZ1NyYzogY2hhbmdlc1tpbnB1dF0ucHJldmlvdXNWYWx1ZQogICAgICAgIH07CiAgICAgIH0KICAgICAgdGhyb3cgcG9zdEluaXRJbnB1dENoYW5nZUVycm9yKGRpciwgaW5wdXQpOwogICAgfQogIH0pOwp9CmZ1bmN0aW9uIGFzc2VydEdyZWF0ZXJUaGFuWmVybyhkaXIsIGlucHV0VmFsdWUsIGlucHV0TmFtZSkgewogIGNvbnN0IHZhbGlkTnVtYmVyID0gdHlwZW9mIGlucHV0VmFsdWUgPT09ICJudW1iZXIiICYmIGlucHV0VmFsdWUgPiAwOwogIGNvbnN0IHZhbGlkU3RyaW5nID0gdHlwZW9mIGlucHV0VmFsdWUgPT09ICJzdHJpbmciICYmIC9eXGQrJC8udGVzdChpbnB1dFZhbHVlLnRyaW0oKSkgJiYgcGFyc2VJbnQoaW5wdXRWYWx1ZSkgPiAwOwogIGlmICghdmFsaWROdW1iZXIgJiYgIXZhbGlkU3RyaW5nKSB7CiAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDI5NTIsIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gXGAke2lucHV0TmFtZX1cYCBoYXMgYW4gaW52YWxpZCB2YWx1ZS4gVG8gZml4IHRoaXMsIHByb3ZpZGUgXGAke2lucHV0TmFtZX1cYCBhcyBhIG51bWJlciBncmVhdGVyIHRoYW4gMC5gKTsKICB9Cn0KZnVuY3Rpb24gYXNzZXJ0Tm9JbWFnZURpc3RvcnRpb24oZGlyLCBpbWcsIHJlbmRlcmVyKSB7CiAgY29uc3QgcmVtb3ZlTG9hZExpc3RlbmVyRm4gPSByZW5kZXJlci5saXN0ZW4oaW1nLCAibG9hZCIsICgpID0+IHsKICAgIHJlbW92ZUxvYWRMaXN0ZW5lckZuKCk7CiAgICByZW1vdmVFcnJvckxpc3RlbmVyRm4oKTsKICAgIGNvbnN0IGNvbXB1dGVkU3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShpbWcpOwogICAgbGV0IHJlbmRlcmVkV2lkdGggPSBwYXJzZUZsb2F0KGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgid2lkdGgiKSk7CiAgICBsZXQgcmVuZGVyZWRIZWlnaHQgPSBwYXJzZUZsb2F0KGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgiaGVpZ2h0IikpOwogICAgY29uc3QgYm94U2l6aW5nID0gY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCJib3gtc2l6aW5nIik7CiAgICBpZiAoYm94U2l6aW5nID09PSAiYm9yZGVyLWJveCIpIHsKICAgICAgY29uc3QgcGFkZGluZ1RvcCA9IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgicGFkZGluZy10b3AiKTsKICAgICAgY29uc3QgcGFkZGluZ1JpZ2h0ID0gY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCJwYWRkaW5nLXJpZ2h0Iik7CiAgICAgIGNvbnN0IHBhZGRpbmdCb3R0b20gPSBjb21wdXRlZFN0eWxlLmdldFByb3BlcnR5VmFsdWUoInBhZGRpbmctYm90dG9tIik7CiAgICAgIGNvbnN0IHBhZGRpbmdMZWZ0ID0gY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCJwYWRkaW5nLWxlZnQiKTsKICAgICAgcmVuZGVyZWRXaWR0aCAtPSBwYXJzZUZsb2F0KHBhZGRpbmdSaWdodCkgKyBwYXJzZUZsb2F0KHBhZGRpbmdMZWZ0KTsKICAgICAgcmVuZGVyZWRIZWlnaHQgLT0gcGFyc2VGbG9hdChwYWRkaW5nVG9wKSArIHBhcnNlRmxvYXQocGFkZGluZ0JvdHRvbSk7CiAgICB9CiAgICBjb25zdCByZW5kZXJlZEFzcGVjdFJhdGlvID0gcmVuZGVyZWRXaWR0aCAvIHJlbmRlcmVkSGVpZ2h0OwogICAgY29uc3Qgbm9uWmVyb1JlbmRlcmVkRGltZW5zaW9ucyA9IHJlbmRlcmVkV2lkdGggIT09IDAgJiYgcmVuZGVyZWRIZWlnaHQgIT09IDA7CiAgICBjb25zdCBpbnRyaW5zaWNXaWR0aCA9IGltZy5uYXR1cmFsV2lkdGg7CiAgICBjb25zdCBpbnRyaW5zaWNIZWlnaHQgPSBpbWcubmF0dXJhbEhlaWdodDsKICAgIGNvbnN0IGludHJpbnNpY0FzcGVjdFJhdGlvID0gaW50cmluc2ljV2lkdGggLyBpbnRyaW5zaWNIZWlnaHQ7CiAgICBjb25zdCBzdXBwbGllZFdpZHRoID0gZGlyLndpZHRoOwogICAgY29uc3Qgc3VwcGxpZWRIZWlnaHQgPSBkaXIuaGVpZ2h0OwogICAgY29uc3Qgc3VwcGxpZWRBc3BlY3RSYXRpbyA9IHN1cHBsaWVkV2lkdGggLyBzdXBwbGllZEhlaWdodDsKICAgIGNvbnN0IGluYWNjdXJhdGVEaW1lbnNpb25zID0gTWF0aC5hYnMoc3VwcGxpZWRBc3BlY3RSYXRpbyAtIGludHJpbnNpY0FzcGVjdFJhdGlvKSA+IEFTUEVDVF9SQVRJT19UT0xFUkFOQ0U7CiAgICBjb25zdCBzdHlsaW5nRGlzdG9ydGlvbiA9IG5vblplcm9SZW5kZXJlZERpbWVuc2lvbnMgJiYgTWF0aC5hYnMoaW50cmluc2ljQXNwZWN0UmF0aW8gLSByZW5kZXJlZEFzcGVjdFJhdGlvKSA+IEFTUEVDVF9SQVRJT19UT0xFUkFOQ0U7CiAgICBpZiAoaW5hY2N1cmF0ZURpbWVuc2lvbnMpIHsKICAgICAgY29uc29sZS53YXJuKGZvcm1hdFJ1bnRpbWVFcnJvcigyOTUyLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IHRoZSBhc3BlY3QgcmF0aW8gb2YgdGhlIGltYWdlIGRvZXMgbm90IG1hdGNoIHRoZSBhc3BlY3QgcmF0aW8gaW5kaWNhdGVkIGJ5IHRoZSB3aWR0aCBhbmQgaGVpZ2h0IGF0dHJpYnV0ZXMuIApJbnRyaW5zaWMgaW1hZ2Ugc2l6ZTogJHtpbnRyaW5zaWNXaWR0aH13IHggJHtpbnRyaW5zaWNIZWlnaHR9aCAoYXNwZWN0LXJhdGlvOiAke3JvdW5kKGludHJpbnNpY0FzcGVjdFJhdGlvKX0pLiAKU3VwcGxpZWQgd2lkdGggYW5kIGhlaWdodCBhdHRyaWJ1dGVzOiAke3N1cHBsaWVkV2lkdGh9dyB4ICR7c3VwcGxpZWRIZWlnaHR9aCAoYXNwZWN0LXJhdGlvOiAke3JvdW5kKHN1cHBsaWVkQXNwZWN0UmF0aW8pfSkuIApUbyBmaXggdGhpcywgdXBkYXRlIHRoZSB3aWR0aCBhbmQgaGVpZ2h0IGF0dHJpYnV0ZXMuYCkpOwogICAgfSBlbHNlIGlmIChzdHlsaW5nRGlzdG9ydGlvbikgewogICAgICBjb25zb2xlLndhcm4oZm9ybWF0UnVudGltZUVycm9yKDI5NTIsIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gdGhlIGFzcGVjdCByYXRpbyBvZiB0aGUgcmVuZGVyZWQgaW1hZ2UgZG9lcyBub3QgbWF0Y2ggdGhlIGltYWdlJ3MgaW50cmluc2ljIGFzcGVjdCByYXRpby4gCkludHJpbnNpYyBpbWFnZSBzaXplOiAke2ludHJpbnNpY1dpZHRofXcgeCAke2ludHJpbnNpY0hlaWdodH1oIChhc3BlY3QtcmF0aW86ICR7cm91bmQoaW50cmluc2ljQXNwZWN0UmF0aW8pfSkuIApSZW5kZXJlZCBpbWFnZSBzaXplOiAke3JlbmRlcmVkV2lkdGh9dyB4ICR7cmVuZGVyZWRIZWlnaHR9aCAoYXNwZWN0LXJhdGlvOiAke3JvdW5kKHJlbmRlcmVkQXNwZWN0UmF0aW8pfSkuIApUaGlzIGlzc3VlIGNhbiBvY2N1ciBpZiAid2lkdGgiIGFuZCAiaGVpZ2h0IiBhdHRyaWJ1dGVzIGFyZSBhZGRlZCB0byBhbiBpbWFnZSB3aXRob3V0IHVwZGF0aW5nIHRoZSBjb3JyZXNwb25kaW5nIGltYWdlIHN0eWxpbmcuIFRvIGZpeCB0aGlzLCBhZGp1c3QgaW1hZ2Ugc3R5bGluZy4gSW4gbW9zdCBjYXNlcywgYWRkaW5nICJoZWlnaHQ6IGF1dG8iIG9yICJ3aWR0aDogYXV0byIgdG8gdGhlIGltYWdlIHN0eWxpbmcgd2lsbCBmaXggdGhpcyBpc3N1ZS5gKSk7CiAgICB9IGVsc2UgaWYgKCFkaXIubmdTcmNzZXQgJiYgbm9uWmVyb1JlbmRlcmVkRGltZW5zaW9ucykgewogICAgICBjb25zdCByZWNvbW1lbmRlZFdpZHRoID0gUkVDT01NRU5ERURfU1JDU0VUX0RFTlNJVFlfQ0FQICogcmVuZGVyZWRXaWR0aDsKICAgICAgY29uc3QgcmVjb21tZW5kZWRIZWlnaHQgPSBSRUNPTU1FTkRFRF9TUkNTRVRfREVOU0lUWV9DQVAgKiByZW5kZXJlZEhlaWdodDsKICAgICAgY29uc3Qgb3ZlcnNpemVkV2lkdGggPSBpbnRyaW5zaWNXaWR0aCAtIHJlY29tbWVuZGVkV2lkdGggPj0gT1ZFUlNJWkVEX0lNQUdFX1RPTEVSQU5DRTsKICAgICAgY29uc3Qgb3ZlcnNpemVkSGVpZ2h0ID0gaW50cmluc2ljSGVpZ2h0IC0gcmVjb21tZW5kZWRIZWlnaHQgPj0gT1ZFUlNJWkVEX0lNQUdFX1RPTEVSQU5DRTsKICAgICAgaWYgKG92ZXJzaXplZFdpZHRoIHx8IG92ZXJzaXplZEhlaWdodCkgewogICAgICAgIGNvbnNvbGUud2Fybihmb3JtYXRSdW50aW1lRXJyb3IoMjk2MCwgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSB0aGUgaW50cmluc2ljIGltYWdlIGlzIHNpZ25pZmljYW50bHkgbGFyZ2VyIHRoYW4gbmVjZXNzYXJ5LiAKUmVuZGVyZWQgaW1hZ2Ugc2l6ZTogJHtyZW5kZXJlZFdpZHRofXcgeCAke3JlbmRlcmVkSGVpZ2h0fWguIApJbnRyaW5zaWMgaW1hZ2Ugc2l6ZTogJHtpbnRyaW5zaWNXaWR0aH13IHggJHtpbnRyaW5zaWNIZWlnaHR9aC4gClJlY29tbWVuZGVkIGludHJpbnNpYyBpbWFnZSBzaXplOiAke3JlY29tbWVuZGVkV2lkdGh9dyB4ICR7cmVjb21tZW5kZWRIZWlnaHR9aC4gCk5vdGU6IFJlY29tbWVuZGVkIGludHJpbnNpYyBpbWFnZSBzaXplIGlzIGNhbGN1bGF0ZWQgYXNzdW1pbmcgYSBtYXhpbXVtIERQUiBvZiAke1JFQ09NTUVOREVEX1NSQ1NFVF9ERU5TSVRZX0NBUH0uIFRvIGltcHJvdmUgbG9hZGluZyB0aW1lLCByZXNpemUgdGhlIGltYWdlIG9yIGNvbnNpZGVyIHVzaW5nIHRoZSAibmdTcmNzZXQiIGFuZCAic2l6ZXMiIGF0dHJpYnV0ZXMuYCkpOwogICAgICB9CiAgICB9CiAgfSk7CiAgY29uc3QgcmVtb3ZlRXJyb3JMaXN0ZW5lckZuID0gcmVuZGVyZXIubGlzdGVuKGltZywgImVycm9yIiwgKCkgPT4gewogICAgcmVtb3ZlTG9hZExpc3RlbmVyRm4oKTsKICAgIHJlbW92ZUVycm9yTGlzdGVuZXJGbigpOwogIH0pOwp9CmZ1bmN0aW9uIGFzc2VydE5vbkVtcHR5V2lkdGhBbmRIZWlnaHQoZGlyKSB7CiAgbGV0IG1pc3NpbmdBdHRyaWJ1dGVzID0gW107CiAgaWYgKGRpci53aWR0aCA9PT0gdm9pZCAwKQogICAgbWlzc2luZ0F0dHJpYnV0ZXMucHVzaCgid2lkdGgiKTsKICBpZiAoZGlyLmhlaWdodCA9PT0gdm9pZCAwKQogICAgbWlzc2luZ0F0dHJpYnV0ZXMucHVzaCgiaGVpZ2h0Iik7CiAgaWYgKG1pc3NpbmdBdHRyaWJ1dGVzLmxlbmd0aCA+IDApIHsKICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoMjk1NCwgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSB0aGVzZSByZXF1aXJlZCBhdHRyaWJ1dGVzIGFyZSBtaXNzaW5nOiAke21pc3NpbmdBdHRyaWJ1dGVzLm1hcCgoYXR0cikgPT4gYCIke2F0dHJ9ImApLmpvaW4oIiwgIil9LiBJbmNsdWRpbmcgIndpZHRoIiBhbmQgImhlaWdodCIgYXR0cmlidXRlcyB3aWxsIHByZXZlbnQgaW1hZ2UtcmVsYXRlZCBsYXlvdXQgc2hpZnRzLiBUbyBmaXggdGhpcywgaW5jbHVkZSAid2lkdGgiIGFuZCAiaGVpZ2h0IiBhdHRyaWJ1dGVzIG9uIHRoZSBpbWFnZSB0YWcgb3IgdHVybiBvbiAiZmlsbCIgbW9kZSB3aXRoIHRoZSBcYGZpbGxcYCBhdHRyaWJ1dGUuYCk7CiAgfQp9CmZ1bmN0aW9uIGFzc2VydEVtcHR5V2lkdGhBbmRIZWlnaHQoZGlyKSB7CiAgaWYgKGRpci53aWR0aCB8fCBkaXIuaGVpZ2h0KSB7CiAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDI5NTIsIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gdGhlIGF0dHJpYnV0ZXMgXGBoZWlnaHRcYCBhbmQvb3IgXGB3aWR0aFxgIGFyZSBwcmVzZW50IGFsb25nIHdpdGggdGhlIFxgZmlsbFxgIGF0dHJpYnV0ZS4gQmVjYXVzZSBcYGZpbGxcYCBtb2RlIGNhdXNlcyBhbiBpbWFnZSB0byBmaWxsIGl0cyBjb250YWluaW5nIGVsZW1lbnQsIHRoZSBzaXplIGF0dHJpYnV0ZXMgaGF2ZSBubyBlZmZlY3QgYW5kIHNob3VsZCBiZSByZW1vdmVkLmApOwogIH0KfQpmdW5jdGlvbiBhc3NlcnROb25aZXJvUmVuZGVyZWRIZWlnaHQoZGlyLCBpbWcsIHJlbmRlcmVyKSB7CiAgY29uc3QgcmVtb3ZlTG9hZExpc3RlbmVyRm4gPSByZW5kZXJlci5saXN0ZW4oaW1nLCAibG9hZCIsICgpID0+IHsKICAgIHJlbW92ZUxvYWRMaXN0ZW5lckZuKCk7CiAgICByZW1vdmVFcnJvckxpc3RlbmVyRm4oKTsKICAgIGNvbnN0IHJlbmRlcmVkSGVpZ2h0ID0gaW1nLmNsaWVudEhlaWdodDsKICAgIGlmIChkaXIuZmlsbCAmJiByZW5kZXJlZEhlaWdodCA9PT0gMCkgewogICAgICBjb25zb2xlLndhcm4oZm9ybWF0UnVudGltZUVycm9yKDI5NTIsIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gdGhlIGhlaWdodCBvZiB0aGUgZmlsbC1tb2RlIGltYWdlIGlzIHplcm8uIFRoaXMgaXMgbGlrZWx5IGJlY2F1c2UgdGhlIGNvbnRhaW5pbmcgZWxlbWVudCBkb2VzIG5vdCBoYXZlIHRoZSBDU1MgJ3Bvc2l0aW9uJyBwcm9wZXJ0eSBzZXQgdG8gb25lIG9mIHRoZSBmb2xsb3dpbmc6ICJyZWxhdGl2ZSIsICJmaXhlZCIsIG9yICJhYnNvbHV0ZSIuIFRvIGZpeCB0aGlzIHByb2JsZW0sIG1ha2Ugc3VyZSB0aGUgY29udGFpbmVyIGVsZW1lbnQgaGFzIHRoZSBDU1MgJ3Bvc2l0aW9uJyBwcm9wZXJ0eSBkZWZpbmVkIGFuZCB0aGUgaGVpZ2h0IG9mIHRoZSBlbGVtZW50IGlzIG5vdCB6ZXJvLmApKTsKICAgIH0KICB9KTsKICBjb25zdCByZW1vdmVFcnJvckxpc3RlbmVyRm4gPSByZW5kZXJlci5saXN0ZW4oaW1nLCAiZXJyb3IiLCAoKSA9PiB7CiAgICByZW1vdmVMb2FkTGlzdGVuZXJGbigpOwogICAgcmVtb3ZlRXJyb3JMaXN0ZW5lckZuKCk7CiAgfSk7Cn0KZnVuY3Rpb24gYXNzZXJ0VmFsaWRMb2FkaW5nSW5wdXQoZGlyKSB7CiAgaWYgKGRpci5sb2FkaW5nICYmIGRpci5wcmlvcml0eSkgewogICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigyOTUyLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IHRoZSBcYGxvYWRpbmdcYCBhdHRyaWJ1dGUgd2FzIHVzZWQgb24gYW4gaW1hZ2UgdGhhdCB3YXMgbWFya2VkICJwcmlvcml0eSIuIFNldHRpbmcgXGBsb2FkaW5nXGAgb24gcHJpb3JpdHkgaW1hZ2VzIGlzIG5vdCBhbGxvd2VkIGJlY2F1c2UgdGhlc2UgaW1hZ2VzIHdpbGwgYWx3YXlzIGJlIGVhZ2VybHkgbG9hZGVkLiBUbyBmaXggdGhpcywgcmVtb3ZlIHRoZSDigJxsb2FkaW5n4oCdIGF0dHJpYnV0ZSBmcm9tIHRoZSBwcmlvcml0eSBpbWFnZS5gKTsKICB9CiAgY29uc3QgdmFsaWRJbnB1dHMgPSBbImF1dG8iLCAiZWFnZXIiLCAibGF6eSJdOwogIGlmICh0eXBlb2YgZGlyLmxvYWRpbmcgPT09ICJzdHJpbmciICYmICF2YWxpZElucHV0cy5pbmNsdWRlcyhkaXIubG9hZGluZykpIHsKICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoMjk1MiwgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSB0aGUgXGBsb2FkaW5nXGAgYXR0cmlidXRlIGhhcyBhbiBpbnZhbGlkIHZhbHVlIChcYCR7ZGlyLmxvYWRpbmd9XGApLiBUbyBmaXggdGhpcywgcHJvdmlkZSBhIHZhbGlkIHZhbHVlICgibGF6eSIsICJlYWdlciIsIG9yICJhdXRvIikuYCk7CiAgfQp9CmZ1bmN0aW9uIGFzc2VydE5vdE1pc3NpbmdCdWlsdEluTG9hZGVyKG5nU3JjLCBpbWFnZUxvYWRlcikgewogIGlmIChpbWFnZUxvYWRlciA9PT0gbm9vcEltYWdlTG9hZGVyKSB7CiAgICBsZXQgYnVpbHRJbkxvYWRlck5hbWUgPSAiIjsKICAgIGZvciAoY29uc3QgbG9hZGVyIG9mIEJVSUxUX0lOX0xPQURFUlMpIHsKICAgICAgaWYgKGxvYWRlci50ZXN0VXJsKG5nU3JjKSkgewogICAgICAgIGJ1aWx0SW5Mb2FkZXJOYW1lID0gbG9hZGVyLm5hbWU7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGlmIChidWlsdEluTG9hZGVyTmFtZSkgewogICAgICBjb25zb2xlLndhcm4oZm9ybWF0UnVudGltZUVycm9yKDI5NjIsIGBOZ09wdGltaXplZEltYWdlOiBJdCBsb29rcyBsaWtlIHlvdXIgaW1hZ2VzIG1heSBiZSBob3N0ZWQgb24gdGhlICR7YnVpbHRJbkxvYWRlck5hbWV9IENETiwgYnV0IHlvdXIgYXBwIGlzIG5vdCB1c2luZyBBbmd1bGFyJ3MgYnVpbHQtaW4gbG9hZGVyIGZvciB0aGF0IENETi4gV2UgcmVjb21tZW5kIHN3aXRjaGluZyB0byB1c2UgdGhlIGJ1aWx0LWluIGJ5IGNhbGxpbmcgXGBwcm92aWRlJHtidWlsdEluTG9hZGVyTmFtZX1Mb2FkZXIoKVxgIGluIHlvdXIgXGBwcm92aWRlcnNcYCBhbmQgcGFzc2luZyBpdCB5b3VyIGluc3RhbmNlJ3MgYmFzZSBVUkwuIElmIHlvdSBkb24ndCB3YW50IHRvIHVzZSB0aGUgYnVpbHQtaW4gbG9hZGVyLCBkZWZpbmUgYSBjdXN0b20gbG9hZGVyIGZ1bmN0aW9uIHVzaW5nIElNQUdFX0xPQURFUiB0byBzaWxlbmNlIHRoaXMgd2FybmluZy5gKSk7CiAgICB9CiAgfQp9CmZ1bmN0aW9uIGFzc2VydE5vTmdTcmNzZXRXaXRob3V0TG9hZGVyKGRpciwgaW1hZ2VMb2FkZXIpIHsKICBpZiAoZGlyLm5nU3Jjc2V0ICYmIGltYWdlTG9hZGVyID09PSBub29wSW1hZ2VMb2FkZXIpIHsKICAgIGNvbnNvbGUud2Fybihmb3JtYXRSdW50aW1lRXJyb3IoMjk2MywgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSB0aGUgXGBuZ1NyY3NldFxgIGF0dHJpYnV0ZSBpcyBwcmVzZW50IGJ1dCBubyBpbWFnZSBsb2FkZXIgaXMgY29uZmlndXJlZCAoaS5lLiB0aGUgZGVmYXVsdCBvbmUgaXMgYmVpbmcgdXNlZCksIHdoaWNoIHdvdWxkIHJlc3VsdCBpbiB0aGUgc2FtZSBpbWFnZSBiZWluZyB1c2VkIGZvciBhbGwgY29uZmlndXJlZCBzaXplcy4gVG8gZml4IHRoaXMsIHByb3ZpZGUgYSBsb2FkZXIgb3IgcmVtb3ZlIHRoZSBcYG5nU3Jjc2V0XGAgYXR0cmlidXRlIGZyb20gdGhlIGltYWdlLmApKTsKICB9Cn0KZnVuY3Rpb24gYXNzZXJ0Tm9Mb2FkZXJQYXJhbXNXaXRob3V0TG9hZGVyKGRpciwgaW1hZ2VMb2FkZXIpIHsKICBpZiAoZGlyLmxvYWRlclBhcmFtcyAmJiBpbWFnZUxvYWRlciA9PT0gbm9vcEltYWdlTG9hZGVyKSB7CiAgICBjb25zb2xlLndhcm4oZm9ybWF0UnVudGltZUVycm9yKDI5NjMsIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gdGhlIFxgbG9hZGVyUGFyYW1zXGAgYXR0cmlidXRlIGlzIHByZXNlbnQgYnV0IG5vIGltYWdlIGxvYWRlciBpcyBjb25maWd1cmVkIChpLmUuIHRoZSBkZWZhdWx0IG9uZSBpcyBiZWluZyB1c2VkKSwgd2hpY2ggbWVhbnMgdGhhdCB0aGUgbG9hZGVyUGFyYW1zIGRhdGEgd2lsbCBub3QgYmUgY29uc3VtZWQgYW5kIHdpbGwgbm90IGFmZmVjdCB0aGUgVVJMLiBUbyBmaXggdGhpcywgcHJvdmlkZSBhIGN1c3RvbSBsb2FkZXIgb3IgcmVtb3ZlIHRoZSBcYGxvYWRlclBhcmFtc1xgIGF0dHJpYnV0ZSBmcm9tIHRoZSBpbWFnZS5gKSk7CiAgfQp9CmZ1bmN0aW9uIHJvdW5kKGlucHV0KSB7CiAgcmV0dXJuIE51bWJlci5pc0ludGVnZXIoaW5wdXQpID8gaW5wdXQgOiBpbnB1dC50b0ZpeGVkKDIpOwp9CmZ1bmN0aW9uIHVud3JhcFNhZmVVcmwodmFsdWUpIHsKICBpZiAodHlwZW9mIHZhbHVlID09PSAic3RyaW5nIikgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICByZXR1cm4gdW53cmFwU2FmZVZhbHVlKHZhbHVlKTsKfQpmdW5jdGlvbiBib29sZWFuT3JEYXRhVXJsQXR0cmlidXRlKHZhbHVlKSB7CiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gInN0cmluZyIgJiYgdmFsdWUuc3RhcnRzV2l0aChgZGF0YTpgKSkgewogICAgcmV0dXJuIHZhbHVlOwogIH0KICByZXR1cm4gYm9vbGVhbkF0dHJpYnV0ZSh2YWx1ZSk7Cn0KCi8vIG5vZGVfbW9kdWxlcy9AYW5ndWxhci9jb21tb24vZmVzbTIwMjIvaHR0cC5tanMKdmFyIEh0dHBIYW5kbGVyID0gY2xhc3Mgewp9Owp2YXIgSHR0cEJhY2tlbmQgPSBjbGFzcyB7Cn07CnZhciBIdHRwSGVhZGVycyA9IGNsYXNzIF9IdHRwSGVhZGVycyB7CiAgLyoqICBDb25zdHJ1Y3RzIGEgbmV3IEhUVFAgaGVhZGVyIG9iamVjdCB3aXRoIHRoZSBnaXZlbiB2YWx1ZXMuKi8KICBjb25zdHJ1Y3RvcihoZWFkZXJzKSB7CiAgICB0aGlzLm5vcm1hbGl6ZWROYW1lcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICB0aGlzLmxhenlVcGRhdGUgPSBudWxsOwogICAgaWYgKCFoZWFkZXJzKSB7CiAgICAgIHRoaXMuaGVhZGVycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICB9IGVsc2UgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAic3RyaW5nIikgewogICAgICB0aGlzLmxhenlJbml0ID0gKCkgPT4gewogICAgICAgIHRoaXMuaGVhZGVycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgICAgaGVhZGVycy5zcGxpdCgiXG4iKS5mb3JFYWNoKChsaW5lKSA9PiB7CiAgICAgICAgICBjb25zdCBpbmRleCA9IGxpbmUuaW5kZXhPZigiOiIpOwogICAgICAgICAgaWYgKGluZGV4ID4gMCkgewogICAgICAgICAgICBjb25zdCBuYW1lID0gbGluZS5zbGljZSgwLCBpbmRleCk7CiAgICAgICAgICAgIGNvbnN0IGtleSA9IG5hbWUudG9Mb3dlckNhc2UoKTsKICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBsaW5lLnNsaWNlKGluZGV4ICsgMSkudHJpbSgpOwogICAgICAgICAgICB0aGlzLm1heWJlU2V0Tm9ybWFsaXplZE5hbWUobmFtZSwga2V5KTsKICAgICAgICAgICAgaWYgKHRoaXMuaGVhZGVycy5oYXMoa2V5KSkgewogICAgICAgICAgICAgIHRoaXMuaGVhZGVycy5nZXQoa2V5KS5wdXNoKHZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICB0aGlzLmhlYWRlcnMuc2V0KGtleSwgW3ZhbHVlXSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgfTsKICAgIH0gZWxzZSBpZiAodHlwZW9mIEhlYWRlcnMgIT09ICJ1bmRlZmluZWQiICYmIGhlYWRlcnMgaW5zdGFuY2VvZiBIZWFkZXJzKSB7CiAgICAgIHRoaXMuaGVhZGVycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIGhlYWRlcnMuZm9yRWFjaCgodmFsdWVzLCBuYW1lKSA9PiB7CiAgICAgICAgdGhpcy5zZXRIZWFkZXJFbnRyaWVzKG5hbWUsIHZhbHVlcyk7CiAgICAgIH0pOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5sYXp5SW5pdCA9ICgpID0+IHsKICAgICAgICBpZiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSB7CiAgICAgICAgICBhc3NlcnRWYWxpZEhlYWRlcnMoaGVhZGVycyk7CiAgICAgICAgfQogICAgICAgIHRoaXMuaGVhZGVycyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgICAgT2JqZWN0LmVudHJpZXMoaGVhZGVycykuZm9yRWFjaCgoW25hbWUsIHZhbHVlc10pID0+IHsKICAgICAgICAgIHRoaXMuc2V0SGVhZGVyRW50cmllcyhuYW1lLCB2YWx1ZXMpOwogICAgICAgIH0pOwogICAgICB9OwogICAgfQogIH0KICAvKioKICAgKiBDaGVja3MgZm9yIGV4aXN0ZW5jZSBvZiBhIGdpdmVuIGhlYWRlci4KICAgKgogICAqIEBwYXJhbSBuYW1lIFRoZSBoZWFkZXIgbmFtZSB0byBjaGVjayBmb3IgZXhpc3RlbmNlLgogICAqCiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgaGVhZGVyIGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlLgogICAqLwogIGhhcyhuYW1lKSB7CiAgICB0aGlzLmluaXQoKTsKICAgIHJldHVybiB0aGlzLmhlYWRlcnMuaGFzKG5hbWUudG9Mb3dlckNhc2UoKSk7CiAgfQogIC8qKgogICAqIFJldHJpZXZlcyB0aGUgZmlyc3QgdmFsdWUgb2YgYSBnaXZlbiBoZWFkZXIuCiAgICoKICAgKiBAcGFyYW0gbmFtZSBUaGUgaGVhZGVyIG5hbWUuCiAgICoKICAgKiBAcmV0dXJucyBUaGUgdmFsdWUgc3RyaW5nIGlmIHRoZSBoZWFkZXIgZXhpc3RzLCBudWxsIG90aGVyd2lzZQogICAqLwogIGdldChuYW1lKSB7CiAgICB0aGlzLmluaXQoKTsKICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuaGVhZGVycy5nZXQobmFtZS50b0xvd2VyQ2FzZSgpKTsKICAgIHJldHVybiB2YWx1ZXMgJiYgdmFsdWVzLmxlbmd0aCA+IDAgPyB2YWx1ZXNbMF0gOiBudWxsOwogIH0KICAvKioKICAgKiBSZXRyaWV2ZXMgdGhlIG5hbWVzIG9mIHRoZSBoZWFkZXJzLgogICAqCiAgICogQHJldHVybnMgQSBsaXN0IG9mIGhlYWRlciBuYW1lcy4KICAgKi8KICBrZXlzKCkgewogICAgdGhpcy5pbml0KCk7CiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLm5vcm1hbGl6ZWROYW1lcy52YWx1ZXMoKSk7CiAgfQogIC8qKgogICAqIFJldHJpZXZlcyBhIGxpc3Qgb2YgdmFsdWVzIGZvciBhIGdpdmVuIGhlYWRlci4KICAgKgogICAqIEBwYXJhbSBuYW1lIFRoZSBoZWFkZXIgbmFtZSBmcm9tIHdoaWNoIHRvIHJldHJpZXZlIHZhbHVlcy4KICAgKgogICAqIEByZXR1cm5zIEEgc3RyaW5nIG9mIHZhbHVlcyBpZiB0aGUgaGVhZGVyIGV4aXN0cywgbnVsbCBvdGhlcndpc2UuCiAgICovCiAgZ2V0QWxsKG5hbWUpIHsKICAgIHRoaXMuaW5pdCgpOwogICAgcmV0dXJuIHRoaXMuaGVhZGVycy5nZXQobmFtZS50b0xvd2VyQ2FzZSgpKSB8fCBudWxsOwogIH0KICAvKioKICAgKiBBcHBlbmRzIGEgbmV3IHZhbHVlIHRvIHRoZSBleGlzdGluZyBzZXQgb2YgdmFsdWVzIGZvciBhIGhlYWRlcgogICAqIGFuZCByZXR1cm5zIHRoZW0gaW4gYSBjbG9uZSBvZiB0aGUgb3JpZ2luYWwgaW5zdGFuY2UuCiAgICoKICAgKiBAcGFyYW0gbmFtZSBUaGUgaGVhZGVyIG5hbWUgZm9yIHdoaWNoIHRvIGFwcGVuZCB0aGUgdmFsdWVzLgogICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXBwZW5kLgogICAqCiAgICogQHJldHVybnMgQSBjbG9uZSBvZiB0aGUgSFRUUCBoZWFkZXJzIG9iamVjdCB3aXRoIHRoZSB2YWx1ZSBhcHBlbmRlZCB0byB0aGUgZ2l2ZW4gaGVhZGVyLgogICAqLwogIGFwcGVuZChuYW1lLCB2YWx1ZSkgewogICAgcmV0dXJuIHRoaXMuY2xvbmUoewogICAgICBuYW1lLAogICAgICB2YWx1ZSwKICAgICAgb3A6ICJhIgogICAgfSk7CiAgfQogIC8qKgogICAqIFNldHMgb3IgbW9kaWZpZXMgYSB2YWx1ZSBmb3IgYSBnaXZlbiBoZWFkZXIgaW4gYSBjbG9uZSBvZiB0aGUgb3JpZ2luYWwgaW5zdGFuY2UuCiAgICogSWYgdGhlIGhlYWRlciBhbHJlYWR5IGV4aXN0cywgaXRzIHZhbHVlIGlzIHJlcGxhY2VkIHdpdGggdGhlIGdpdmVuIHZhbHVlCiAgICogaW4gdGhlIHJldHVybmVkIG9iamVjdC4KICAgKgogICAqIEBwYXJhbSBuYW1lIFRoZSBoZWFkZXIgbmFtZS4KICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIG9yIHZhbHVlcyB0byBzZXQgb3Igb3ZlcnJpZGUgZm9yIHRoZSBnaXZlbiBoZWFkZXIuCiAgICoKICAgKiBAcmV0dXJucyBBIGNsb25lIG9mIHRoZSBIVFRQIGhlYWRlcnMgb2JqZWN0IHdpdGggdGhlIG5ld2x5IHNldCBoZWFkZXIgdmFsdWUuCiAgICovCiAgc2V0KG5hbWUsIHZhbHVlKSB7CiAgICByZXR1cm4gdGhpcy5jbG9uZSh7CiAgICAgIG5hbWUsCiAgICAgIHZhbHVlLAogICAgICBvcDogInMiCiAgICB9KTsKICB9CiAgLyoqCiAgICogRGVsZXRlcyB2YWx1ZXMgZm9yIGEgZ2l2ZW4gaGVhZGVyIGluIGEgY2xvbmUgb2YgdGhlIG9yaWdpbmFsIGluc3RhbmNlLgogICAqCiAgICogQHBhcmFtIG5hbWUgVGhlIGhlYWRlciBuYW1lLgogICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgb3IgdmFsdWVzIHRvIGRlbGV0ZSBmb3IgdGhlIGdpdmVuIGhlYWRlci4KICAgKgogICAqIEByZXR1cm5zIEEgY2xvbmUgb2YgdGhlIEhUVFAgaGVhZGVycyBvYmplY3Qgd2l0aCB0aGUgZ2l2ZW4gdmFsdWUgZGVsZXRlZC4KICAgKi8KICBkZWxldGUobmFtZSwgdmFsdWUpIHsKICAgIHJldHVybiB0aGlzLmNsb25lKHsKICAgICAgbmFtZSwKICAgICAgdmFsdWUsCiAgICAgIG9wOiAiZCIKICAgIH0pOwogIH0KICBtYXliZVNldE5vcm1hbGl6ZWROYW1lKG5hbWUsIGxjTmFtZSkgewogICAgaWYgKCF0aGlzLm5vcm1hbGl6ZWROYW1lcy5oYXMobGNOYW1lKSkgewogICAgICB0aGlzLm5vcm1hbGl6ZWROYW1lcy5zZXQobGNOYW1lLCBuYW1lKTsKICAgIH0KICB9CiAgaW5pdCgpIHsKICAgIGlmICghIXRoaXMubGF6eUluaXQpIHsKICAgICAgaWYgKHRoaXMubGF6eUluaXQgaW5zdGFuY2VvZiBfSHR0cEhlYWRlcnMpIHsKICAgICAgICB0aGlzLmNvcHlGcm9tKHRoaXMubGF6eUluaXQpOwogICAgICB9IGVsc2UgewogICAgICAgIHRoaXMubGF6eUluaXQoKTsKICAgICAgfQogICAgICB0aGlzLmxhenlJbml0ID0gbnVsbDsKICAgICAgaWYgKCEhdGhpcy5sYXp5VXBkYXRlKSB7CiAgICAgICAgdGhpcy5sYXp5VXBkYXRlLmZvckVhY2goKHVwZGF0ZSkgPT4gdGhpcy5hcHBseVVwZGF0ZSh1cGRhdGUpKTsKICAgICAgICB0aGlzLmxhenlVcGRhdGUgPSBudWxsOwogICAgICB9CiAgICB9CiAgfQogIGNvcHlGcm9tKG90aGVyKSB7CiAgICBvdGhlci5pbml0KCk7CiAgICBBcnJheS5mcm9tKG90aGVyLmhlYWRlcnMua2V5cygpKS5mb3JFYWNoKChrZXkpID0+IHsKICAgICAgdGhpcy5oZWFkZXJzLnNldChrZXksIG90aGVyLmhlYWRlcnMuZ2V0KGtleSkpOwogICAgICB0aGlzLm5vcm1hbGl6ZWROYW1lcy5zZXQoa2V5LCBvdGhlci5ub3JtYWxpemVkTmFtZXMuZ2V0KGtleSkpOwogICAgfSk7CiAgfQogIGNsb25lKHVwZGF0ZSkgewogICAgY29uc3QgY2xvbmUgPSBuZXcgX0h0dHBIZWFkZXJzKCk7CiAgICBjbG9uZS5sYXp5SW5pdCA9ICEhdGhpcy5sYXp5SW5pdCAmJiB0aGlzLmxhenlJbml0IGluc3RhbmNlb2YgX0h0dHBIZWFkZXJzID8gdGhpcy5sYXp5SW5pdCA6IHRoaXM7CiAgICBjbG9uZS5sYXp5VXBkYXRlID0gKHRoaXMubGF6eVVwZGF0ZSB8fCBbXSkuY29uY2F0KFt1cGRhdGVdKTsKICAgIHJldHVybiBjbG9uZTsKICB9CiAgYXBwbHlVcGRhdGUodXBkYXRlKSB7CiAgICBjb25zdCBrZXkgPSB1cGRhdGUubmFtZS50b0xvd2VyQ2FzZSgpOwogICAgc3dpdGNoICh1cGRhdGUub3ApIHsKICAgICAgY2FzZSAiYSI6CiAgICAgIGNhc2UgInMiOgogICAgICAgIGxldCB2YWx1ZSA9IHVwZGF0ZS52YWx1ZTsKICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAic3RyaW5nIikgewogICAgICAgICAgdmFsdWUgPSBbdmFsdWVdOwogICAgICAgIH0KICAgICAgICBpZiAodmFsdWUubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIHRoaXMubWF5YmVTZXROb3JtYWxpemVkTmFtZSh1cGRhdGUubmFtZSwga2V5KTsKICAgICAgICBjb25zdCBiYXNlID0gKHVwZGF0ZS5vcCA9PT0gImEiID8gdGhpcy5oZWFkZXJzLmdldChrZXkpIDogdm9pZCAwKSB8fCBbXTsKICAgICAgICBiYXNlLnB1c2goLi4udmFsdWUpOwogICAgICAgIHRoaXMuaGVhZGVycy5zZXQoa2V5LCBiYXNlKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAiZCI6CiAgICAgICAgY29uc3QgdG9EZWxldGUgPSB1cGRhdGUudmFsdWU7CiAgICAgICAgaWYgKCF0b0RlbGV0ZSkgewogICAgICAgICAgdGhpcy5oZWFkZXJzLmRlbGV0ZShrZXkpOwogICAgICAgICAgdGhpcy5ub3JtYWxpemVkTmFtZXMuZGVsZXRlKGtleSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGxldCBleGlzdGluZyA9IHRoaXMuaGVhZGVycy5nZXQoa2V5KTsKICAgICAgICAgIGlmICghZXhpc3RpbmcpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQogICAgICAgICAgZXhpc3RpbmcgPSBleGlzdGluZy5maWx0ZXIoKHZhbHVlMikgPT4gdG9EZWxldGUuaW5kZXhPZih2YWx1ZTIpID09PSAtMSk7CiAgICAgICAgICBpZiAoZXhpc3RpbmcubGVuZ3RoID09PSAwKSB7CiAgICAgICAgICAgIHRoaXMuaGVhZGVycy5kZWxldGUoa2V5KTsKICAgICAgICAgICAgdGhpcy5ub3JtYWxpemVkTmFtZXMuZGVsZXRlKGtleSk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGlzLmhlYWRlcnMuc2V0KGtleSwgZXhpc3RpbmcpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIH0KICB9CiAgc2V0SGVhZGVyRW50cmllcyhuYW1lLCB2YWx1ZXMpIHsKICAgIGNvbnN0IGhlYWRlclZhbHVlcyA9IChBcnJheS5pc0FycmF5KHZhbHVlcykgPyB2YWx1ZXMgOiBbdmFsdWVzXSkubWFwKCh2YWx1ZSkgPT4gdmFsdWUudG9TdHJpbmcoKSk7CiAgICBjb25zdCBrZXkgPSBuYW1lLnRvTG93ZXJDYXNlKCk7CiAgICB0aGlzLmhlYWRlcnMuc2V0KGtleSwgaGVhZGVyVmFsdWVzKTsKICAgIHRoaXMubWF5YmVTZXROb3JtYWxpemVkTmFtZShuYW1lLCBrZXkpOwogIH0KICAvKioKICAgKiBAaW50ZXJuYWwKICAgKi8KICBmb3JFYWNoKGZuKSB7CiAgICB0aGlzLmluaXQoKTsKICAgIEFycmF5LmZyb20odGhpcy5ub3JtYWxpemVkTmFtZXMua2V5cygpKS5mb3JFYWNoKChrZXkpID0+IGZuKHRoaXMubm9ybWFsaXplZE5hbWVzLmdldChrZXkpLCB0aGlzLmhlYWRlcnMuZ2V0KGtleSkpKTsKICB9Cn07CmZ1bmN0aW9uIGFzc2VydFZhbGlkSGVhZGVycyhoZWFkZXJzKSB7CiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoaGVhZGVycykpIHsKICAgIGlmICghKHR5cGVvZiB2YWx1ZSA9PT0gInN0cmluZyIgfHwgdHlwZW9mIHZhbHVlID09PSAibnVtYmVyIikgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCB2YWx1ZSBvZiB0aGUgXGAke2tleX1cYCBoZWFkZXIgcHJvdmlkZWQuIEV4cGVjdGluZyBlaXRoZXIgYSBzdHJpbmcsIGEgbnVtYmVyIG9yIGFuIGFycmF5LCBidXQgZ290OiBcYCR7dmFsdWV9XGAuYCk7CiAgICB9CiAgfQp9CnZhciBIdHRwVXJsRW5jb2RpbmdDb2RlYyA9IGNsYXNzIHsKICAvKioKICAgKiBFbmNvZGVzIGEga2V5IG5hbWUgZm9yIGEgVVJMIHBhcmFtZXRlciBvciBxdWVyeS1zdHJpbmcuCiAgICogQHBhcmFtIGtleSBUaGUga2V5IG5hbWUuCiAgICogQHJldHVybnMgVGhlIGVuY29kZWQga2V5IG5hbWUuCiAgICovCiAgZW5jb2RlS2V5KGtleSkgewogICAgcmV0dXJuIHN0YW5kYXJkRW5jb2Rpbmcoa2V5KTsKICB9CiAgLyoqCiAgICogRW5jb2RlcyB0aGUgdmFsdWUgb2YgYSBVUkwgcGFyYW1ldGVyIG9yIHF1ZXJ5LXN0cmluZy4KICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlLgogICAqIEByZXR1cm5zIFRoZSBlbmNvZGVkIHZhbHVlLgogICAqLwogIGVuY29kZVZhbHVlKHZhbHVlKSB7CiAgICByZXR1cm4gc3RhbmRhcmRFbmNvZGluZyh2YWx1ZSk7CiAgfQogIC8qKgogICAqIERlY29kZXMgYW4gZW5jb2RlZCBVUkwgcGFyYW1ldGVyIG9yIHF1ZXJ5LXN0cmluZyBrZXkuCiAgICogQHBhcmFtIGtleSBUaGUgZW5jb2RlZCBrZXkgbmFtZS4KICAgKiBAcmV0dXJucyBUaGUgZGVjb2RlZCBrZXkgbmFtZS4KICAgKi8KICBkZWNvZGVLZXkoa2V5KSB7CiAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGtleSk7CiAgfQogIC8qKgogICAqIERlY29kZXMgYW4gZW5jb2RlZCBVUkwgcGFyYW1ldGVyIG9yIHF1ZXJ5LXN0cmluZyB2YWx1ZS4KICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVuY29kZWQgdmFsdWUuCiAgICogQHJldHVybnMgVGhlIGRlY29kZWQgdmFsdWUuCiAgICovCiAgZGVjb2RlVmFsdWUodmFsdWUpIHsKICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQodmFsdWUpOwogIH0KfTsKZnVuY3Rpb24gcGFyYW1QYXJzZXIocmF3UGFyYW1zLCBjb2RlYykgewogIGNvbnN0IG1hcDIgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogIGlmIChyYXdQYXJhbXMubGVuZ3RoID4gMCkgewogICAgY29uc3QgcGFyYW1zID0gcmF3UGFyYW1zLnJlcGxhY2UoL15cPy8sICIiKS5zcGxpdCgiJiIpOwogICAgcGFyYW1zLmZvckVhY2goKHBhcmFtKSA9PiB7CiAgICAgIGNvbnN0IGVxSWR4ID0gcGFyYW0uaW5kZXhPZigiPSIpOwogICAgICBjb25zdCBba2V5LCB2YWxdID0gZXFJZHggPT0gLTEgPyBbY29kZWMuZGVjb2RlS2V5KHBhcmFtKSwgIiJdIDogW2NvZGVjLmRlY29kZUtleShwYXJhbS5zbGljZSgwLCBlcUlkeCkpLCBjb2RlYy5kZWNvZGVWYWx1ZShwYXJhbS5zbGljZShlcUlkeCArIDEpKV07CiAgICAgIGNvbnN0IGxpc3QgPSBtYXAyLmdldChrZXkpIHx8IFtdOwogICAgICBsaXN0LnB1c2godmFsKTsKICAgICAgbWFwMi5zZXQoa2V5LCBsaXN0KTsKICAgIH0pOwogIH0KICByZXR1cm4gbWFwMjsKfQp2YXIgU1RBTkRBUkRfRU5DT0RJTkdfUkVHRVggPSAvJShcZFthLWYwLTldKS9naTsKdmFyIFNUQU5EQVJEX0VOQ09ESU5HX1JFUExBQ0VNRU5UUyA9IHsKICAiNDAiOiAiQCIsCiAgIjNBIjogIjoiLAogICIyNCI6ICIkIiwKICAiMkMiOiAiLCIsCiAgIjNCIjogIjsiLAogICIzRCI6ICI9IiwKICAiM0YiOiAiPyIsCiAgIjJGIjogIi8iCn07CmZ1bmN0aW9uIHN0YW5kYXJkRW5jb2RpbmcodikgewogIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQodikucmVwbGFjZShTVEFOREFSRF9FTkNPRElOR19SRUdFWCwgKHMsIHQpID0+IFNUQU5EQVJEX0VOQ09ESU5HX1JFUExBQ0VNRU5UU1t0XSA/PyBzKTsKfQpmdW5jdGlvbiB2YWx1ZVRvU3RyaW5nKHZhbHVlKSB7CiAgcmV0dXJuIGAke3ZhbHVlfWA7Cn0KdmFyIEh0dHBQYXJhbXMgPSBjbGFzcyBfSHR0cFBhcmFtcyB7CiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7CiAgICB0aGlzLnVwZGF0ZXMgPSBudWxsOwogICAgdGhpcy5jbG9uZUZyb20gPSBudWxsOwogICAgdGhpcy5lbmNvZGVyID0gb3B0aW9ucy5lbmNvZGVyIHx8IG5ldyBIdHRwVXJsRW5jb2RpbmdDb2RlYygpOwogICAgaWYgKCEhb3B0aW9ucy5mcm9tU3RyaW5nKSB7CiAgICAgIGlmICghIW9wdGlvbnMuZnJvbU9iamVjdCkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHNwZWNpZnkgYm90aCBmcm9tU3RyaW5nIGFuZCBmcm9tT2JqZWN0LmApOwogICAgICB9CiAgICAgIHRoaXMubWFwID0gcGFyYW1QYXJzZXIob3B0aW9ucy5mcm9tU3RyaW5nLCB0aGlzLmVuY29kZXIpOwogICAgfSBlbHNlIGlmICghIW9wdGlvbnMuZnJvbU9iamVjdCkgewogICAgICB0aGlzLm1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICAgIE9iamVjdC5rZXlzKG9wdGlvbnMuZnJvbU9iamVjdCkuZm9yRWFjaCgoa2V5KSA9PiB7CiAgICAgICAgY29uc3QgdmFsdWUgPSBvcHRpb25zLmZyb21PYmplY3Rba2V5XTsKICAgICAgICBjb25zdCB2YWx1ZXMgPSBBcnJheS5pc0FycmF5KHZhbHVlKSA/IHZhbHVlLm1hcCh2YWx1ZVRvU3RyaW5nKSA6IFt2YWx1ZVRvU3RyaW5nKHZhbHVlKV07CiAgICAgICAgdGhpcy5tYXAuc2V0KGtleSwgdmFsdWVzKTsKICAgICAgfSk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLm1hcCA9IG51bGw7CiAgICB9CiAgfQogIC8qKgogICAqIFJlcG9ydHMgd2hldGhlciB0aGUgYm9keSBpbmNsdWRlcyBvbmUgb3IgbW9yZSB2YWx1ZXMgZm9yIGEgZ2l2ZW4gcGFyYW1ldGVyLgogICAqIEBwYXJhbSBwYXJhbSBUaGUgcGFyYW1ldGVyIG5hbWUuCiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgcGFyYW1ldGVyIGhhcyBvbmUgb3IgbW9yZSB2YWx1ZXMsCiAgICogZmFsc2UgaWYgaXQgaGFzIG5vIHZhbHVlIG9yIGlzIG5vdCBwcmVzZW50LgogICAqLwogIGhhcyhwYXJhbSkgewogICAgdGhpcy5pbml0KCk7CiAgICByZXR1cm4gdGhpcy5tYXAuaGFzKHBhcmFtKTsKICB9CiAgLyoqCiAgICogUmV0cmlldmVzIHRoZSBmaXJzdCB2YWx1ZSBmb3IgYSBwYXJhbWV0ZXIuCiAgICogQHBhcmFtIHBhcmFtIFRoZSBwYXJhbWV0ZXIgbmFtZS4KICAgKiBAcmV0dXJucyBUaGUgZmlyc3QgdmFsdWUgb2YgdGhlIGdpdmVuIHBhcmFtZXRlciwKICAgKiBvciBgbnVsbGAgaWYgdGhlIHBhcmFtZXRlciBpcyBub3QgcHJlc2VudC4KICAgKi8KICBnZXQocGFyYW0pIHsKICAgIHRoaXMuaW5pdCgpOwogICAgY29uc3QgcmVzID0gdGhpcy5tYXAuZ2V0KHBhcmFtKTsKICAgIHJldHVybiAhIXJlcyA/IHJlc1swXSA6IG51bGw7CiAgfQogIC8qKgogICAqIFJldHJpZXZlcyBhbGwgdmFsdWVzIGZvciBhICBwYXJhbWV0ZXIuCiAgICogQHBhcmFtIHBhcmFtIFRoZSBwYXJhbWV0ZXIgbmFtZS4KICAgKiBAcmV0dXJucyBBbGwgdmFsdWVzIGluIGEgc3RyaW5nIGFycmF5LAogICAqIG9yIGBudWxsYCBpZiB0aGUgcGFyYW1ldGVyIG5vdCBwcmVzZW50LgogICAqLwogIGdldEFsbChwYXJhbSkgewogICAgdGhpcy5pbml0KCk7CiAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KHBhcmFtKSB8fCBudWxsOwogIH0KICAvKioKICAgKiBSZXRyaWV2ZXMgYWxsIHRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIGJvZHkuCiAgICogQHJldHVybnMgVGhlIHBhcmFtZXRlciBuYW1lcyBpbiBhIHN0cmluZyBhcnJheS4KICAgKi8KICBrZXlzKCkgewogICAgdGhpcy5pbml0KCk7CiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLm1hcC5rZXlzKCkpOwogIH0KICAvKioKICAgKiBBcHBlbmRzIGEgbmV3IHZhbHVlIHRvIGV4aXN0aW5nIHZhbHVlcyBmb3IgYSBwYXJhbWV0ZXIuCiAgICogQHBhcmFtIHBhcmFtIFRoZSBwYXJhbWV0ZXIgbmFtZS4KICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5ldyB2YWx1ZSB0byBhZGQuCiAgICogQHJldHVybiBBIG5ldyBib2R5IHdpdGggdGhlIGFwcGVuZGVkIHZhbHVlLgogICAqLwogIGFwcGVuZChwYXJhbSwgdmFsdWUpIHsKICAgIHJldHVybiB0aGlzLmNsb25lKHsKICAgICAgcGFyYW0sCiAgICAgIHZhbHVlLAogICAgICBvcDogImEiCiAgICB9KTsKICB9CiAgLyoqCiAgICogQ29uc3RydWN0cyBhIG5ldyBib2R5IHdpdGggYXBwZW5kZWQgdmFsdWVzIGZvciB0aGUgZ2l2ZW4gcGFyYW1ldGVyIG5hbWUuCiAgICogQHBhcmFtIHBhcmFtcyBwYXJhbWV0ZXJzIGFuZCB2YWx1ZXMKICAgKiBAcmV0dXJuIEEgbmV3IGJvZHkgd2l0aCB0aGUgbmV3IHZhbHVlLgogICAqLwogIGFwcGVuZEFsbChwYXJhbXMpIHsKICAgIGNvbnN0IHVwZGF0ZXMgPSBbXTsKICAgIE9iamVjdC5rZXlzKHBhcmFtcykuZm9yRWFjaCgocGFyYW0pID0+IHsKICAgICAgY29uc3QgdmFsdWUgPSBwYXJhbXNbcGFyYW1dOwogICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHsKICAgICAgICB2YWx1ZS5mb3JFYWNoKChfdmFsdWUpID0+IHsKICAgICAgICAgIHVwZGF0ZXMucHVzaCh7CiAgICAgICAgICAgIHBhcmFtLAogICAgICAgICAgICB2YWx1ZTogX3ZhbHVlLAogICAgICAgICAgICBvcDogImEiCiAgICAgICAgICB9KTsKICAgICAgICB9KTsKICAgICAgfSBlbHNlIHsKICAgICAgICB1cGRhdGVzLnB1c2goewogICAgICAgICAgcGFyYW0sCiAgICAgICAgICB2YWx1ZSwKICAgICAgICAgIG9wOiAiYSIKICAgICAgICB9KTsKICAgICAgfQogICAgfSk7CiAgICByZXR1cm4gdGhpcy5jbG9uZSh1cGRhdGVzKTsKICB9CiAgLyoqCiAgICogUmVwbGFjZXMgdGhlIHZhbHVlIGZvciBhIHBhcmFtZXRlci4KICAgKiBAcGFyYW0gcGFyYW0gVGhlIHBhcmFtZXRlciBuYW1lLgogICAqIEBwYXJhbSB2YWx1ZSBUaGUgbmV3IHZhbHVlLgogICAqIEByZXR1cm4gQSBuZXcgYm9keSB3aXRoIHRoZSBuZXcgdmFsdWUuCiAgICovCiAgc2V0KHBhcmFtLCB2YWx1ZSkgewogICAgcmV0dXJuIHRoaXMuY2xvbmUoewogICAgICBwYXJhbSwKICAgICAgdmFsdWUsCiAgICAgIG9wOiAicyIKICAgIH0pOwogIH0KICAvKioKICAgKiBSZW1vdmVzIGEgZ2l2ZW4gdmFsdWUgb3IgYWxsIHZhbHVlcyBmcm9tIGEgcGFyYW1ldGVyLgogICAqIEBwYXJhbSBwYXJhbSBUaGUgcGFyYW1ldGVyIG5hbWUuCiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byByZW1vdmUsIGlmIHByb3ZpZGVkLgogICAqIEByZXR1cm4gQSBuZXcgYm9keSB3aXRoIHRoZSBnaXZlbiB2YWx1ZSByZW1vdmVkLCBvciB3aXRoIGFsbCB2YWx1ZXMKICAgKiByZW1vdmVkIGlmIG5vIHZhbHVlIGlzIHNwZWNpZmllZC4KICAgKi8KICBkZWxldGUocGFyYW0sIHZhbHVlKSB7CiAgICByZXR1cm4gdGhpcy5jbG9uZSh7CiAgICAgIHBhcmFtLAogICAgICB2YWx1ZSwKICAgICAgb3A6ICJkIgogICAgfSk7CiAgfQogIC8qKgogICAqIFNlcmlhbGl6ZXMgdGhlIGJvZHkgdG8gYW4gZW5jb2RlZCBzdHJpbmcsIHdoZXJlIGtleS12YWx1ZSBwYWlycyAoc2VwYXJhdGVkIGJ5IGA9YCkgYXJlCiAgICogc2VwYXJhdGVkIGJ5IGAmYHMuCiAgICovCiAgdG9TdHJpbmcoKSB7CiAgICB0aGlzLmluaXQoKTsKICAgIHJldHVybiB0aGlzLmtleXMoKS5tYXAoKGtleSkgPT4gewogICAgICBjb25zdCBlS2V5ID0gdGhpcy5lbmNvZGVyLmVuY29kZUtleShrZXkpOwogICAgICByZXR1cm4gdGhpcy5tYXAuZ2V0KGtleSkubWFwKCh2YWx1ZSkgPT4gZUtleSArICI9IiArIHRoaXMuZW5jb2Rlci5lbmNvZGVWYWx1ZSh2YWx1ZSkpLmpvaW4oIiYiKTsKICAgIH0pLmZpbHRlcigocGFyYW0pID0+IHBhcmFtICE9PSAiIikuam9pbigiJiIpOwogIH0KICBjbG9uZSh1cGRhdGUpIHsKICAgIGNvbnN0IGNsb25lID0gbmV3IF9IdHRwUGFyYW1zKHsKICAgICAgZW5jb2RlcjogdGhpcy5lbmNvZGVyCiAgICB9KTsKICAgIGNsb25lLmNsb25lRnJvbSA9IHRoaXMuY2xvbmVGcm9tIHx8IHRoaXM7CiAgICBjbG9uZS51cGRhdGVzID0gKHRoaXMudXBkYXRlcyB8fCBbXSkuY29uY2F0KHVwZGF0ZSk7CiAgICByZXR1cm4gY2xvbmU7CiAgfQogIGluaXQoKSB7CiAgICBpZiAodGhpcy5tYXAgPT09IG51bGwpIHsKICAgICAgdGhpcy5tYXAgPSAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpOwogICAgfQogICAgaWYgKHRoaXMuY2xvbmVGcm9tICE9PSBudWxsKSB7CiAgICAgIHRoaXMuY2xvbmVGcm9tLmluaXQoKTsKICAgICAgdGhpcy5jbG9uZUZyb20ua2V5cygpLmZvckVhY2goKGtleSkgPT4gdGhpcy5tYXAuc2V0KGtleSwgdGhpcy5jbG9uZUZyb20ubWFwLmdldChrZXkpKSk7CiAgICAgIHRoaXMudXBkYXRlcy5mb3JFYWNoKCh1cGRhdGUpID0+IHsKICAgICAgICBzd2l0Y2ggKHVwZGF0ZS5vcCkgewogICAgICAgICAgY2FzZSAiYSI6CiAgICAgICAgICBjYXNlICJzIjoKICAgICAgICAgICAgY29uc3QgYmFzZSA9ICh1cGRhdGUub3AgPT09ICJhIiA/IHRoaXMubWFwLmdldCh1cGRhdGUucGFyYW0pIDogdm9pZCAwKSB8fCBbXTsKICAgICAgICAgICAgYmFzZS5wdXNoKHZhbHVlVG9TdHJpbmcodXBkYXRlLnZhbHVlKSk7CiAgICAgICAgICAgIHRoaXMubWFwLnNldCh1cGRhdGUucGFyYW0sIGJhc2UpOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2UgImQiOgogICAgICAgICAgICBpZiAodXBkYXRlLnZhbHVlICE9PSB2b2lkIDApIHsKICAgICAgICAgICAgICBsZXQgYmFzZTIgPSB0aGlzLm1hcC5nZXQodXBkYXRlLnBhcmFtKSB8fCBbXTsKICAgICAgICAgICAgICBjb25zdCBpZHggPSBiYXNlMi5pbmRleE9mKHZhbHVlVG9TdHJpbmcodXBkYXRlLnZhbHVlKSk7CiAgICAgICAgICAgICAgaWYgKGlkeCAhPT0gLTEpIHsKICAgICAgICAgICAgICAgIGJhc2UyLnNwbGljZShpZHgsIDEpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAoYmFzZTIubGVuZ3RoID4gMCkgewogICAgICAgICAgICAgICAgdGhpcy5tYXAuc2V0KHVwZGF0ZS5wYXJhbSwgYmFzZTIpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLm1hcC5kZWxldGUodXBkYXRlLnBhcmFtKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgdGhpcy5tYXAuZGVsZXRlKHVwZGF0ZS5wYXJhbSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0pOwogICAgICB0aGlzLmNsb25lRnJvbSA9IHRoaXMudXBkYXRlcyA9IG51bGw7CiAgICB9CiAgfQp9Owp2YXIgSHR0cENvbnRleHQgPSBjbGFzcyB7CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLm1hcCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgfQogIC8qKgogICAqIFN0b3JlIGEgdmFsdWUgaW4gdGhlIGNvbnRleHQuIElmIGEgdmFsdWUgaXMgYWxyZWFkeSBwcmVzZW50IGl0IHdpbGwgYmUgb3ZlcndyaXR0ZW4uCiAgICoKICAgKiBAcGFyYW0gdG9rZW4gVGhlIHJlZmVyZW5jZSB0byBhbiBpbnN0YW5jZSBvZiBgSHR0cENvbnRleHRUb2tlbmAuCiAgICogQHBhcmFtIHZhbHVlIFRoZSB2YWx1ZSB0byBzdG9yZS4KICAgKgogICAqIEByZXR1cm5zIEEgcmVmZXJlbmNlIHRvIGl0c2VsZiBmb3IgZWFzeSBjaGFpbmluZy4KICAgKi8KICBzZXQodG9rZW4sIHZhbHVlKSB7CiAgICB0aGlzLm1hcC5zZXQodG9rZW4sIHZhbHVlKTsKICAgIHJldHVybiB0aGlzOwogIH0KICAvKioKICAgKiBSZXRyaWV2ZSB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiB0b2tlbi4KICAgKgogICAqIEBwYXJhbSB0b2tlbiBUaGUgcmVmZXJlbmNlIHRvIGFuIGluc3RhbmNlIG9mIGBIdHRwQ29udGV4dFRva2VuYC4KICAgKgogICAqIEByZXR1cm5zIFRoZSBzdG9yZWQgdmFsdWUgb3IgZGVmYXVsdCBpZiBvbmUgaXMgZGVmaW5lZC4KICAgKi8KICBnZXQodG9rZW4pIHsKICAgIGlmICghdGhpcy5tYXAuaGFzKHRva2VuKSkgewogICAgICB0aGlzLm1hcC5zZXQodG9rZW4sIHRva2VuLmRlZmF1bHRWYWx1ZSgpKTsKICAgIH0KICAgIHJldHVybiB0aGlzLm1hcC5nZXQodG9rZW4pOwogIH0KICAvKioKICAgKiBEZWxldGUgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gdG9rZW4uCiAgICoKICAgKiBAcGFyYW0gdG9rZW4gVGhlIHJlZmVyZW5jZSB0byBhbiBpbnN0YW5jZSBvZiBgSHR0cENvbnRleHRUb2tlbmAuCiAgICoKICAgKiBAcmV0dXJucyBBIHJlZmVyZW5jZSB0byBpdHNlbGYgZm9yIGVhc3kgY2hhaW5pbmcuCiAgICovCiAgZGVsZXRlKHRva2VuKSB7CiAgICB0aGlzLm1hcC5kZWxldGUodG9rZW4pOwogICAgcmV0dXJuIHRoaXM7CiAgfQogIC8qKgogICAqIENoZWNrcyBmb3IgZXhpc3RlbmNlIG9mIGEgZ2l2ZW4gdG9rZW4uCiAgICoKICAgKiBAcGFyYW0gdG9rZW4gVGhlIHJlZmVyZW5jZSB0byBhbiBpbnN0YW5jZSBvZiBgSHR0cENvbnRleHRUb2tlbmAuCiAgICoKICAgKiBAcmV0dXJucyBUcnVlIGlmIHRoZSB0b2tlbiBleGlzdHMsIGZhbHNlIG90aGVyd2lzZS4KICAgKi8KICBoYXModG9rZW4pIHsKICAgIHJldHVybiB0aGlzLm1hcC5oYXModG9rZW4pOwogIH0KICAvKioKICAgKiBAcmV0dXJucyBhIGxpc3Qgb2YgdG9rZW5zIGN1cnJlbnRseSBzdG9yZWQgaW4gdGhlIGNvbnRleHQuCiAgICovCiAga2V5cygpIHsKICAgIHJldHVybiB0aGlzLm1hcC5rZXlzKCk7CiAgfQp9OwpmdW5jdGlvbiBtaWdodEhhdmVCb2R5KG1ldGhvZCkgewogIHN3aXRjaCAobWV0aG9kKSB7CiAgICBjYXNlICJERUxFVEUiOgogICAgY2FzZSAiR0VUIjoKICAgIGNhc2UgIkhFQUQiOgogICAgY2FzZSAiT1BUSU9OUyI6CiAgICBjYXNlICJKU09OUCI6CiAgICAgIHJldHVybiBmYWxzZTsKICAgIGRlZmF1bHQ6CiAgICAgIHJldHVybiB0cnVlOwogIH0KfQpmdW5jdGlvbiBpc0FycmF5QnVmZmVyKHZhbHVlKSB7CiAgcmV0dXJuIHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gInVuZGVmaW5lZCIgJiYgdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcjsKfQpmdW5jdGlvbiBpc0Jsb2IodmFsdWUpIHsKICByZXR1cm4gdHlwZW9mIEJsb2IgIT09ICJ1bmRlZmluZWQiICYmIHZhbHVlIGluc3RhbmNlb2YgQmxvYjsKfQpmdW5jdGlvbiBpc0Zvcm1EYXRhKHZhbHVlKSB7CiAgcmV0dXJuIHR5cGVvZiBGb3JtRGF0YSAhPT0gInVuZGVmaW5lZCIgJiYgdmFsdWUgaW5zdGFuY2VvZiBGb3JtRGF0YTsKfQpmdW5jdGlvbiBpc1VybFNlYXJjaFBhcmFtcyh2YWx1ZSkgewogIHJldHVybiB0eXBlb2YgVVJMU2VhcmNoUGFyYW1zICE9PSAidW5kZWZpbmVkIiAmJiB2YWx1ZSBpbnN0YW5jZW9mIFVSTFNlYXJjaFBhcmFtczsKfQp2YXIgSHR0cFJlcXVlc3QgPSBjbGFzcyBfSHR0cFJlcXVlc3QgewogIGNvbnN0cnVjdG9yKG1ldGhvZCwgdXJsLCB0aGlyZCwgZm91cnRoKSB7CiAgICB0aGlzLnVybCA9IHVybDsKICAgIHRoaXMuYm9keSA9IG51bGw7CiAgICB0aGlzLnJlcG9ydFByb2dyZXNzID0gZmFsc2U7CiAgICB0aGlzLndpdGhDcmVkZW50aWFscyA9IGZhbHNlOwogICAgdGhpcy5yZXNwb25zZVR5cGUgPSAianNvbiI7CiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpOwogICAgbGV0IG9wdGlvbnM7CiAgICBpZiAobWlnaHRIYXZlQm9keSh0aGlzLm1ldGhvZCkgfHwgISFmb3VydGgpIHsKICAgICAgdGhpcy5ib2R5ID0gdGhpcmQgIT09IHZvaWQgMCA/IHRoaXJkIDogbnVsbDsKICAgICAgb3B0aW9ucyA9IGZvdXJ0aDsKICAgIH0gZWxzZSB7CiAgICAgIG9wdGlvbnMgPSB0aGlyZDsKICAgIH0KICAgIGlmIChvcHRpb25zKSB7CiAgICAgIHRoaXMucmVwb3J0UHJvZ3Jlc3MgPSAhIW9wdGlvbnMucmVwb3J0UHJvZ3Jlc3M7CiAgICAgIHRoaXMud2l0aENyZWRlbnRpYWxzID0gISFvcHRpb25zLndpdGhDcmVkZW50aWFsczsKICAgICAgaWYgKCEhb3B0aW9ucy5yZXNwb25zZVR5cGUpIHsKICAgICAgICB0aGlzLnJlc3BvbnNlVHlwZSA9IG9wdGlvbnMucmVzcG9uc2VUeXBlOwogICAgICB9CiAgICAgIGlmICghIW9wdGlvbnMuaGVhZGVycykgewogICAgICAgIHRoaXMuaGVhZGVycyA9IG9wdGlvbnMuaGVhZGVyczsKICAgICAgfQogICAgICBpZiAoISFvcHRpb25zLmNvbnRleHQpIHsKICAgICAgICB0aGlzLmNvbnRleHQgPSBvcHRpb25zLmNvbnRleHQ7CiAgICAgIH0KICAgICAgaWYgKCEhb3B0aW9ucy5wYXJhbXMpIHsKICAgICAgICB0aGlzLnBhcmFtcyA9IG9wdGlvbnMucGFyYW1zOwogICAgICB9CiAgICAgIHRoaXMudHJhbnNmZXJDYWNoZSA9IG9wdGlvbnMudHJhbnNmZXJDYWNoZTsKICAgIH0KICAgIHRoaXMuaGVhZGVycyA/Pz0gbmV3IEh0dHBIZWFkZXJzKCk7CiAgICB0aGlzLmNvbnRleHQgPz89IG5ldyBIdHRwQ29udGV4dCgpOwogICAgaWYgKCF0aGlzLnBhcmFtcykgewogICAgICB0aGlzLnBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKCk7CiAgICAgIHRoaXMudXJsV2l0aFBhcmFtcyA9IHVybDsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMucGFyYW1zLnRvU3RyaW5nKCk7CiAgICAgIGlmIChwYXJhbXMubGVuZ3RoID09PSAwKSB7CiAgICAgICAgdGhpcy51cmxXaXRoUGFyYW1zID0gdXJsOwogICAgICB9IGVsc2UgewogICAgICAgIGNvbnN0IHFJZHggPSB1cmwuaW5kZXhPZigiPyIpOwogICAgICAgIGNvbnN0IHNlcCA9IHFJZHggPT09IC0xID8gIj8iIDogcUlkeCA8IHVybC5sZW5ndGggLSAxID8gIiYiIDogIiI7CiAgICAgICAgdGhpcy51cmxXaXRoUGFyYW1zID0gdXJsICsgc2VwICsgcGFyYW1zOwogICAgICB9CiAgICB9CiAgfQogIC8qKgogICAqIFRyYW5zZm9ybSB0aGUgZnJlZS1mb3JtIGJvZHkgaW50byBhIHNlcmlhbGl6ZWQgZm9ybWF0IHN1aXRhYmxlIGZvcgogICAqIHRyYW5zbWlzc2lvbiB0byB0aGUgc2VydmVyLgogICAqLwogIHNlcmlhbGl6ZUJvZHkoKSB7CiAgICBpZiAodGhpcy5ib2R5ID09PSBudWxsKSB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgaWYgKHR5cGVvZiB0aGlzLmJvZHkgPT09ICJzdHJpbmciIHx8IGlzQXJyYXlCdWZmZXIodGhpcy5ib2R5KSB8fCBpc0Jsb2IodGhpcy5ib2R5KSB8fCBpc0Zvcm1EYXRhKHRoaXMuYm9keSkgfHwgaXNVcmxTZWFyY2hQYXJhbXModGhpcy5ib2R5KSkgewogICAgICByZXR1cm4gdGhpcy5ib2R5OwogICAgfQogICAgaWYgKHRoaXMuYm9keSBpbnN0YW5jZW9mIEh0dHBQYXJhbXMpIHsKICAgICAgcmV0dXJuIHRoaXMuYm9keS50b1N0cmluZygpOwogICAgfQogICAgaWYgKHR5cGVvZiB0aGlzLmJvZHkgPT09ICJvYmplY3QiIHx8IHR5cGVvZiB0aGlzLmJvZHkgPT09ICJib29sZWFuIiB8fCBBcnJheS5pc0FycmF5KHRoaXMuYm9keSkpIHsKICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMuYm9keSk7CiAgICB9CiAgICByZXR1cm4gdGhpcy5ib2R5LnRvU3RyaW5nKCk7CiAgfQogIC8qKgogICAqIEV4YW1pbmUgdGhlIGJvZHkgYW5kIGF0dGVtcHQgdG8gaW5mZXIgYW4gYXBwcm9wcmlhdGUgTUlNRSB0eXBlCiAgICogZm9yIGl0LgogICAqCiAgICogSWYgbm8gc3VjaCB0eXBlIGNhbiBiZSBpbmZlcnJlZCwgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gYG51bGxgLgogICAqLwogIGRldGVjdENvbnRlbnRUeXBlSGVhZGVyKCkgewogICAgaWYgKHRoaXMuYm9keSA9PT0gbnVsbCkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIGlmIChpc0Zvcm1EYXRhKHRoaXMuYm9keSkpIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBpZiAoaXNCbG9iKHRoaXMuYm9keSkpIHsKICAgICAgcmV0dXJuIHRoaXMuYm9keS50eXBlIHx8IG51bGw7CiAgICB9CiAgICBpZiAoaXNBcnJheUJ1ZmZlcih0aGlzLmJvZHkpKSB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgaWYgKHR5cGVvZiB0aGlzLmJvZHkgPT09ICJzdHJpbmciKSB7CiAgICAgIHJldHVybiAidGV4dC9wbGFpbiI7CiAgICB9CiAgICBpZiAodGhpcy5ib2R5IGluc3RhbmNlb2YgSHR0cFBhcmFtcykgewogICAgICByZXR1cm4gImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDtjaGFyc2V0PVVURi04IjsKICAgIH0KICAgIGlmICh0eXBlb2YgdGhpcy5ib2R5ID09PSAib2JqZWN0IiB8fCB0eXBlb2YgdGhpcy5ib2R5ID09PSAibnVtYmVyIiB8fCB0eXBlb2YgdGhpcy5ib2R5ID09PSAiYm9vbGVhbiIpIHsKICAgICAgcmV0dXJuICJhcHBsaWNhdGlvbi9qc29uIjsKICAgIH0KICAgIHJldHVybiBudWxsOwogIH0KICBjbG9uZSh1cGRhdGUgPSB7fSkgewogICAgY29uc3QgbWV0aG9kID0gdXBkYXRlLm1ldGhvZCB8fCB0aGlzLm1ldGhvZDsKICAgIGNvbnN0IHVybCA9IHVwZGF0ZS51cmwgfHwgdGhpcy51cmw7CiAgICBjb25zdCByZXNwb25zZVR5cGUgPSB1cGRhdGUucmVzcG9uc2VUeXBlIHx8IHRoaXMucmVzcG9uc2VUeXBlOwogICAgY29uc3QgdHJhbnNmZXJDYWNoZSA9IHVwZGF0ZS50cmFuc2ZlckNhY2hlID8/IHRoaXMudHJhbnNmZXJDYWNoZTsKICAgIGNvbnN0IGJvZHkgPSB1cGRhdGUuYm9keSAhPT0gdm9pZCAwID8gdXBkYXRlLmJvZHkgOiB0aGlzLmJvZHk7CiAgICBjb25zdCB3aXRoQ3JlZGVudGlhbHMgPSB1cGRhdGUud2l0aENyZWRlbnRpYWxzID8/IHRoaXMud2l0aENyZWRlbnRpYWxzOwogICAgY29uc3QgcmVwb3J0UHJvZ3Jlc3MgPSB1cGRhdGUucmVwb3J0UHJvZ3Jlc3MgPz8gdGhpcy5yZXBvcnRQcm9ncmVzczsKICAgIGxldCBoZWFkZXJzID0gdXBkYXRlLmhlYWRlcnMgfHwgdGhpcy5oZWFkZXJzOwogICAgbGV0IHBhcmFtcyA9IHVwZGF0ZS5wYXJhbXMgfHwgdGhpcy5wYXJhbXM7CiAgICBjb25zdCBjb250ZXh0ID0gdXBkYXRlLmNvbnRleHQgPz8gdGhpcy5jb250ZXh0OwogICAgaWYgKHVwZGF0ZS5zZXRIZWFkZXJzICE9PSB2b2lkIDApIHsKICAgICAgaGVhZGVycyA9IE9iamVjdC5rZXlzKHVwZGF0ZS5zZXRIZWFkZXJzKS5yZWR1Y2UoKGhlYWRlcnMyLCBuYW1lKSA9PiBoZWFkZXJzMi5zZXQobmFtZSwgdXBkYXRlLnNldEhlYWRlcnNbbmFtZV0pLCBoZWFkZXJzKTsKICAgIH0KICAgIGlmICh1cGRhdGUuc2V0UGFyYW1zKSB7CiAgICAgIHBhcmFtcyA9IE9iamVjdC5rZXlzKHVwZGF0ZS5zZXRQYXJhbXMpLnJlZHVjZSgocGFyYW1zMiwgcGFyYW0pID0+IHBhcmFtczIuc2V0KHBhcmFtLCB1cGRhdGUuc2V0UGFyYW1zW3BhcmFtXSksIHBhcmFtcyk7CiAgICB9CiAgICByZXR1cm4gbmV3IF9IdHRwUmVxdWVzdChtZXRob2QsIHVybCwgYm9keSwgewogICAgICBwYXJhbXMsCiAgICAgIGhlYWRlcnMsCiAgICAgIGNvbnRleHQsCiAgICAgIHJlcG9ydFByb2dyZXNzLAogICAgICByZXNwb25zZVR5cGUsCiAgICAgIHdpdGhDcmVkZW50aWFscywKICAgICAgdHJhbnNmZXJDYWNoZQogICAgfSk7CiAgfQp9Owp2YXIgSHR0cEV2ZW50VHlwZTsKKGZ1bmN0aW9uKEh0dHBFdmVudFR5cGUyKSB7CiAgSHR0cEV2ZW50VHlwZTJbSHR0cEV2ZW50VHlwZTJbIlNlbnQiXSA9IDBdID0gIlNlbnQiOwogIEh0dHBFdmVudFR5cGUyW0h0dHBFdmVudFR5cGUyWyJVcGxvYWRQcm9ncmVzcyJdID0gMV0gPSAiVXBsb2FkUHJvZ3Jlc3MiOwogIEh0dHBFdmVudFR5cGUyW0h0dHBFdmVudFR5cGUyWyJSZXNwb25zZUhlYWRlciJdID0gMl0gPSAiUmVzcG9uc2VIZWFkZXIiOwogIEh0dHBFdmVudFR5cGUyW0h0dHBFdmVudFR5cGUyWyJEb3dubG9hZFByb2dyZXNzIl0gPSAzXSA9ICJEb3dubG9hZFByb2dyZXNzIjsKICBIdHRwRXZlbnRUeXBlMltIdHRwRXZlbnRUeXBlMlsiUmVzcG9uc2UiXSA9IDRdID0gIlJlc3BvbnNlIjsKICBIdHRwRXZlbnRUeXBlMltIdHRwRXZlbnRUeXBlMlsiVXNlciJdID0gNV0gPSAiVXNlciI7Cn0pKEh0dHBFdmVudFR5cGUgfHwgKEh0dHBFdmVudFR5cGUgPSB7fSkpOwp2YXIgSHR0cFJlc3BvbnNlQmFzZSA9IGNsYXNzIHsKICAvKioKICAgKiBTdXBlci1jb25zdHJ1Y3RvciBmb3IgYWxsIHJlc3BvbnNlcy4KICAgKgogICAqIFRoZSBzaW5nbGUgcGFyYW1ldGVyIGFjY2VwdGVkIGlzIGFuIGluaXRpYWxpemF0aW9uIGhhc2guIEFueSBwcm9wZXJ0aWVzCiAgICogb2YgdGhlIHJlc3BvbnNlIHBhc3NlZCB0aGVyZSB3aWxsIG92ZXJyaWRlIHRoZSBkZWZhdWx0IHZhbHVlcy4KICAgKi8KICBjb25zdHJ1Y3Rvcihpbml0LCBkZWZhdWx0U3RhdHVzID0gMjAwLCBkZWZhdWx0U3RhdHVzVGV4dCA9ICJPSyIpIHsKICAgIHRoaXMuaGVhZGVycyA9IGluaXQuaGVhZGVycyB8fCBuZXcgSHR0cEhlYWRlcnMoKTsKICAgIHRoaXMuc3RhdHVzID0gaW5pdC5zdGF0dXMgIT09IHZvaWQgMCA/IGluaXQuc3RhdHVzIDogZGVmYXVsdFN0YXR1czsKICAgIHRoaXMuc3RhdHVzVGV4dCA9IGluaXQuc3RhdHVzVGV4dCB8fCBkZWZhdWx0U3RhdHVzVGV4dDsKICAgIHRoaXMudXJsID0gaW5pdC51cmwgfHwgbnVsbDsKICAgIHRoaXMub2sgPSB0aGlzLnN0YXR1cyA+PSAyMDAgJiYgdGhpcy5zdGF0dXMgPCAzMDA7CiAgfQp9Owp2YXIgSHR0cEhlYWRlclJlc3BvbnNlID0gY2xhc3MgX0h0dHBIZWFkZXJSZXNwb25zZSBleHRlbmRzIEh0dHBSZXNwb25zZUJhc2UgewogIC8qKgogICAqIENyZWF0ZSBhIG5ldyBgSHR0cEhlYWRlclJlc3BvbnNlYCB3aXRoIHRoZSBnaXZlbiBwYXJhbWV0ZXJzLgogICAqLwogIGNvbnN0cnVjdG9yKGluaXQgPSB7fSkgewogICAgc3VwZXIoaW5pdCk7CiAgICB0aGlzLnR5cGUgPSBIdHRwRXZlbnRUeXBlLlJlc3BvbnNlSGVhZGVyOwogIH0KICAvKioKICAgKiBDb3B5IHRoaXMgYEh0dHBIZWFkZXJSZXNwb25zZWAsIG92ZXJyaWRpbmcgaXRzIGNvbnRlbnRzIHdpdGggdGhlCiAgICogZ2l2ZW4gcGFyYW1ldGVyIGhhc2guCiAgICovCiAgY2xvbmUodXBkYXRlID0ge30pIHsKICAgIHJldHVybiBuZXcgX0h0dHBIZWFkZXJSZXNwb25zZSh7CiAgICAgIGhlYWRlcnM6IHVwZGF0ZS5oZWFkZXJzIHx8IHRoaXMuaGVhZGVycywKICAgICAgc3RhdHVzOiB1cGRhdGUuc3RhdHVzICE9PSB2b2lkIDAgPyB1cGRhdGUuc3RhdHVzIDogdGhpcy5zdGF0dXMsCiAgICAgIHN0YXR1c1RleHQ6IHVwZGF0ZS5zdGF0dXNUZXh0IHx8IHRoaXMuc3RhdHVzVGV4dCwKICAgICAgdXJsOiB1cGRhdGUudXJsIHx8IHRoaXMudXJsIHx8IHZvaWQgMAogICAgfSk7CiAgfQp9Owp2YXIgSHR0cFJlc3BvbnNlID0gY2xhc3MgX0h0dHBSZXNwb25zZSBleHRlbmRzIEh0dHBSZXNwb25zZUJhc2UgewogIC8qKgogICAqIENvbnN0cnVjdCBhIG5ldyBgSHR0cFJlc3BvbnNlYC4KICAgKi8KICBjb25zdHJ1Y3Rvcihpbml0ID0ge30pIHsKICAgIHN1cGVyKGluaXQpOwogICAgdGhpcy50eXBlID0gSHR0cEV2ZW50VHlwZS5SZXNwb25zZTsKICAgIHRoaXMuYm9keSA9IGluaXQuYm9keSAhPT0gdm9pZCAwID8gaW5pdC5ib2R5IDogbnVsbDsKICB9CiAgY2xvbmUodXBkYXRlID0ge30pIHsKICAgIHJldHVybiBuZXcgX0h0dHBSZXNwb25zZSh7CiAgICAgIGJvZHk6IHVwZGF0ZS5ib2R5ICE9PSB2b2lkIDAgPyB1cGRhdGUuYm9keSA6IHRoaXMuYm9keSwKICAgICAgaGVhZGVyczogdXBkYXRlLmhlYWRlcnMgfHwgdGhpcy5oZWFkZXJzLAogICAgICBzdGF0dXM6IHVwZGF0ZS5zdGF0dXMgIT09IHZvaWQgMCA/IHVwZGF0ZS5zdGF0dXMgOiB0aGlzLnN0YXR1cywKICAgICAgc3RhdHVzVGV4dDogdXBkYXRlLnN0YXR1c1RleHQgfHwgdGhpcy5zdGF0dXNUZXh0LAogICAgICB1cmw6IHVwZGF0ZS51cmwgfHwgdGhpcy51cmwgfHwgdm9pZCAwCiAgICB9KTsKICB9Cn07CnZhciBIdHRwRXJyb3JSZXNwb25zZSA9IGNsYXNzIGV4dGVuZHMgSHR0cFJlc3BvbnNlQmFzZSB7CiAgY29uc3RydWN0b3IoaW5pdCkgewogICAgc3VwZXIoaW5pdCwgMCwgIlVua25vd24gRXJyb3IiKTsKICAgIHRoaXMubmFtZSA9ICJIdHRwRXJyb3JSZXNwb25zZSI7CiAgICB0aGlzLm9rID0gZmFsc2U7CiAgICBpZiAodGhpcy5zdGF0dXMgPj0gMjAwICYmIHRoaXMuc3RhdHVzIDwgMzAwKSB7CiAgICAgIHRoaXMubWVzc2FnZSA9IGBIdHRwIGZhaWx1cmUgZHVyaW5nIHBhcnNpbmcgZm9yICR7aW5pdC51cmwgfHwgIih1bmtub3duIHVybCkifWA7CiAgICB9IGVsc2UgewogICAgICB0aGlzLm1lc3NhZ2UgPSBgSHR0cCBmYWlsdXJlIHJlc3BvbnNlIGZvciAke2luaXQudXJsIHx8ICIodW5rbm93biB1cmwpIn06ICR7aW5pdC5zdGF0dXN9ICR7aW5pdC5zdGF0dXNUZXh0fWA7CiAgICB9CiAgICB0aGlzLmVycm9yID0gaW5pdC5lcnJvciB8fCBudWxsOwogIH0KfTsKdmFyIEhUVFBfU1RBVFVTX0NPREVfT0sgPSAyMDA7CnZhciBIVFRQX1NUQVRVU19DT0RFX05PX0NPTlRFTlQgPSAyMDQ7CnZhciBIdHRwU3RhdHVzQ29kZTsKKGZ1bmN0aW9uKEh0dHBTdGF0dXNDb2RlMikgewogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIkNvbnRpbnVlIl0gPSAxMDBdID0gIkNvbnRpbnVlIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJTd2l0Y2hpbmdQcm90b2NvbHMiXSA9IDEwMV0gPSAiU3dpdGNoaW5nUHJvdG9jb2xzIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJQcm9jZXNzaW5nIl0gPSAxMDJdID0gIlByb2Nlc3NpbmciOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIkVhcmx5SGludHMiXSA9IDEwM10gPSAiRWFybHlIaW50cyI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiT2siXSA9IDIwMF0gPSAiT2siOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIkNyZWF0ZWQiXSA9IDIwMV0gPSAiQ3JlYXRlZCI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiQWNjZXB0ZWQiXSA9IDIwMl0gPSAiQWNjZXB0ZWQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIk5vbkF1dGhvcml0YXRpdmVJbmZvcm1hdGlvbiJdID0gMjAzXSA9ICJOb25BdXRob3JpdGF0aXZlSW5mb3JtYXRpb24iOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIk5vQ29udGVudCJdID0gMjA0XSA9ICJOb0NvbnRlbnQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIlJlc2V0Q29udGVudCJdID0gMjA1XSA9ICJSZXNldENvbnRlbnQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIlBhcnRpYWxDb250ZW50Il0gPSAyMDZdID0gIlBhcnRpYWxDb250ZW50IjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJNdWx0aVN0YXR1cyJdID0gMjA3XSA9ICJNdWx0aVN0YXR1cyI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiQWxyZWFkeVJlcG9ydGVkIl0gPSAyMDhdID0gIkFscmVhZHlSZXBvcnRlZCI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiSW1Vc2VkIl0gPSAyMjZdID0gIkltVXNlZCI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiTXVsdGlwbGVDaG9pY2VzIl0gPSAzMDBdID0gIk11bHRpcGxlQ2hvaWNlcyI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiTW92ZWRQZXJtYW5lbnRseSJdID0gMzAxXSA9ICJNb3ZlZFBlcm1hbmVudGx5IjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJGb3VuZCJdID0gMzAyXSA9ICJGb3VuZCI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiU2VlT3RoZXIiXSA9IDMwM10gPSAiU2VlT3RoZXIiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIk5vdE1vZGlmaWVkIl0gPSAzMDRdID0gIk5vdE1vZGlmaWVkIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJVc2VQcm94eSJdID0gMzA1XSA9ICJVc2VQcm94eSI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiVW51c2VkIl0gPSAzMDZdID0gIlVudXNlZCI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiVGVtcG9yYXJ5UmVkaXJlY3QiXSA9IDMwN10gPSAiVGVtcG9yYXJ5UmVkaXJlY3QiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIlBlcm1hbmVudFJlZGlyZWN0Il0gPSAzMDhdID0gIlBlcm1hbmVudFJlZGlyZWN0IjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJCYWRSZXF1ZXN0Il0gPSA0MDBdID0gIkJhZFJlcXVlc3QiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIlVuYXV0aG9yaXplZCJdID0gNDAxXSA9ICJVbmF1dGhvcml6ZWQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIlBheW1lbnRSZXF1aXJlZCJdID0gNDAyXSA9ICJQYXltZW50UmVxdWlyZWQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIkZvcmJpZGRlbiJdID0gNDAzXSA9ICJGb3JiaWRkZW4iOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIk5vdEZvdW5kIl0gPSA0MDRdID0gIk5vdEZvdW5kIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJNZXRob2ROb3RBbGxvd2VkIl0gPSA0MDVdID0gIk1ldGhvZE5vdEFsbG93ZWQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIk5vdEFjY2VwdGFibGUiXSA9IDQwNl0gPSAiTm90QWNjZXB0YWJsZSI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkIl0gPSA0MDddID0gIlByb3h5QXV0aGVudGljYXRpb25SZXF1aXJlZCI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiUmVxdWVzdFRpbWVvdXQiXSA9IDQwOF0gPSAiUmVxdWVzdFRpbWVvdXQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIkNvbmZsaWN0Il0gPSA0MDldID0gIkNvbmZsaWN0IjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJHb25lIl0gPSA0MTBdID0gIkdvbmUiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIkxlbmd0aFJlcXVpcmVkIl0gPSA0MTFdID0gIkxlbmd0aFJlcXVpcmVkIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJQcmVjb25kaXRpb25GYWlsZWQiXSA9IDQxMl0gPSAiUHJlY29uZGl0aW9uRmFpbGVkIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJQYXlsb2FkVG9vTGFyZ2UiXSA9IDQxM10gPSAiUGF5bG9hZFRvb0xhcmdlIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJVcmlUb29Mb25nIl0gPSA0MTRdID0gIlVyaVRvb0xvbmciOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIlVuc3VwcG9ydGVkTWVkaWFUeXBlIl0gPSA0MTVdID0gIlVuc3VwcG9ydGVkTWVkaWFUeXBlIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJSYW5nZU5vdFNhdGlzZmlhYmxlIl0gPSA0MTZdID0gIlJhbmdlTm90U2F0aXNmaWFibGUiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIkV4cGVjdGF0aW9uRmFpbGVkIl0gPSA0MTddID0gIkV4cGVjdGF0aW9uRmFpbGVkIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJJbUFUZWFwb3QiXSA9IDQxOF0gPSAiSW1BVGVhcG90IjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJNaXNkaXJlY3RlZFJlcXVlc3QiXSA9IDQyMV0gPSAiTWlzZGlyZWN0ZWRSZXF1ZXN0IjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJVbnByb2Nlc3NhYmxlRW50aXR5Il0gPSA0MjJdID0gIlVucHJvY2Vzc2FibGVFbnRpdHkiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIkxvY2tlZCJdID0gNDIzXSA9ICJMb2NrZWQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIkZhaWxlZERlcGVuZGVuY3kiXSA9IDQyNF0gPSAiRmFpbGVkRGVwZW5kZW5jeSI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiVG9vRWFybHkiXSA9IDQyNV0gPSAiVG9vRWFybHkiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIlVwZ3JhZGVSZXF1aXJlZCJdID0gNDI2XSA9ICJVcGdyYWRlUmVxdWlyZWQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIlByZWNvbmRpdGlvblJlcXVpcmVkIl0gPSA0MjhdID0gIlByZWNvbmRpdGlvblJlcXVpcmVkIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJUb29NYW55UmVxdWVzdHMiXSA9IDQyOV0gPSAiVG9vTWFueVJlcXVlc3RzIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJSZXF1ZXN0SGVhZGVyRmllbGRzVG9vTGFyZ2UiXSA9IDQzMV0gPSAiUmVxdWVzdEhlYWRlckZpZWxkc1Rvb0xhcmdlIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJVbmF2YWlsYWJsZUZvckxlZ2FsUmVhc29ucyJdID0gNDUxXSA9ICJVbmF2YWlsYWJsZUZvckxlZ2FsUmVhc29ucyI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiSW50ZXJuYWxTZXJ2ZXJFcnJvciJdID0gNTAwXSA9ICJJbnRlcm5hbFNlcnZlckVycm9yIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJOb3RJbXBsZW1lbnRlZCJdID0gNTAxXSA9ICJOb3RJbXBsZW1lbnRlZCI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiQmFkR2F0ZXdheSJdID0gNTAyXSA9ICJCYWRHYXRld2F5IjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJTZXJ2aWNlVW5hdmFpbGFibGUiXSA9IDUwM10gPSAiU2VydmljZVVuYXZhaWxhYmxlIjsKICBIdHRwU3RhdHVzQ29kZTJbSHR0cFN0YXR1c0NvZGUyWyJHYXRld2F5VGltZW91dCJdID0gNTA0XSA9ICJHYXRld2F5VGltZW91dCI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiSHR0cFZlcnNpb25Ob3RTdXBwb3J0ZWQiXSA9IDUwNV0gPSAiSHR0cFZlcnNpb25Ob3RTdXBwb3J0ZWQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIlZhcmlhbnRBbHNvTmVnb3RpYXRlcyJdID0gNTA2XSA9ICJWYXJpYW50QWxzb05lZ290aWF0ZXMiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIkluc3VmZmljaWVudFN0b3JhZ2UiXSA9IDUwN10gPSAiSW5zdWZmaWNpZW50U3RvcmFnZSI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiTG9vcERldGVjdGVkIl0gPSA1MDhdID0gIkxvb3BEZXRlY3RlZCI7CiAgSHR0cFN0YXR1c0NvZGUyW0h0dHBTdGF0dXNDb2RlMlsiTm90RXh0ZW5kZWQiXSA9IDUxMF0gPSAiTm90RXh0ZW5kZWQiOwogIEh0dHBTdGF0dXNDb2RlMltIdHRwU3RhdHVzQ29kZTJbIk5ldHdvcmtBdXRoZW50aWNhdGlvblJlcXVpcmVkIl0gPSA1MTFdID0gIk5ldHdvcmtBdXRoZW50aWNhdGlvblJlcXVpcmVkIjsKfSkoSHR0cFN0YXR1c0NvZGUgfHwgKEh0dHBTdGF0dXNDb2RlID0ge30pKTsKZnVuY3Rpb24gYWRkQm9keShvcHRpb25zLCBib2R5KSB7CiAgcmV0dXJuIHsKICAgIGJvZHksCiAgICBoZWFkZXJzOiBvcHRpb25zLmhlYWRlcnMsCiAgICBjb250ZXh0OiBvcHRpb25zLmNvbnRleHQsCiAgICBvYnNlcnZlOiBvcHRpb25zLm9ic2VydmUsCiAgICBwYXJhbXM6IG9wdGlvbnMucGFyYW1zLAogICAgcmVwb3J0UHJvZ3Jlc3M6IG9wdGlvbnMucmVwb3J0UHJvZ3Jlc3MsCiAgICByZXNwb25zZVR5cGU6IG9wdGlvbnMucmVzcG9uc2VUeXBlLAogICAgd2l0aENyZWRlbnRpYWxzOiBvcHRpb25zLndpdGhDcmVkZW50aWFscywKICAgIHRyYW5zZmVyQ2FjaGU6IG9wdGlvbnMudHJhbnNmZXJDYWNoZQogIH07Cn0KdmFyIF9IdHRwQ2xpZW50ID0gY2xhc3MgX0h0dHBDbGllbnQgewogIGNvbnN0cnVjdG9yKGhhbmRsZXIpIHsKICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7CiAgfQogIC8qKgogICAqIENvbnN0cnVjdHMgYW4gb2JzZXJ2YWJsZSBmb3IgYSBnZW5lcmljIEhUVFAgcmVxdWVzdCB0aGF0LCB3aGVuIHN1YnNjcmliZWQsCiAgICogZmlyZXMgdGhlIHJlcXVlc3QgdGhyb3VnaCB0aGUgY2hhaW4gb2YgcmVnaXN0ZXJlZCBpbnRlcmNlcHRvcnMgYW5kIG9uIHRvIHRoZQogICAqIHNlcnZlci4KICAgKgogICAqIFlvdSBjYW4gcGFzcyBhbiBgSHR0cFJlcXVlc3RgIGRpcmVjdGx5IGFzIHRoZSBvbmx5IHBhcmFtZXRlci4gSW4gdGhpcyBjYXNlLAogICAqIHRoZSBjYWxsIHJldHVybnMgYW4gb2JzZXJ2YWJsZSBvZiB0aGUgcmF3IGBIdHRwRXZlbnRgIHN0cmVhbS4KICAgKgogICAqIEFsdGVybmF0aXZlbHkgeW91IGNhbiBwYXNzIGFuIEhUVFAgbWV0aG9kIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIsCiAgICogYSBVUkwgc3RyaW5nIGFzIHRoZSBzZWNvbmQsIGFuZCBhbiBvcHRpb25zIGhhc2ggY29udGFpbmluZyB0aGUgcmVxdWVzdCBib2R5IGFzIHRoZSB0aGlyZC4KICAgKiBTZWUgYGFkZEJvZHkoKWAuIEluIHRoaXMgY2FzZSwgdGhlIHNwZWNpZmllZCBgcmVzcG9uc2VUeXBlYCBhbmQgYG9ic2VydmVgIG9wdGlvbnMgZGV0ZXJtaW5lIHRoZQogICAqIHR5cGUgb2YgcmV0dXJuZWQgb2JzZXJ2YWJsZS4KICAgKiAgICogVGhlIGByZXNwb25zZVR5cGVgIHZhbHVlIGRldGVybWluZXMgaG93IGEgc3VjY2Vzc2Z1bCByZXNwb25zZSBib2R5IGlzIHBhcnNlZC4KICAgKiAgICogSWYgYHJlc3BvbnNlVHlwZWAgaXMgdGhlIGRlZmF1bHQgYGpzb25gLCB5b3UgY2FuIHBhc3MgYSB0eXBlIGludGVyZmFjZSBmb3IgdGhlIHJlc3VsdGluZwogICAqIG9iamVjdCBhcyBhIHR5cGUgcGFyYW1ldGVyIHRvIHRoZSBjYWxsLgogICAqCiAgICogVGhlIGBvYnNlcnZlYCB2YWx1ZSBkZXRlcm1pbmVzIHRoZSByZXR1cm4gdHlwZSwgYWNjb3JkaW5nIHRvIHdoYXQgeW91IGFyZSBpbnRlcmVzdGVkIGluCiAgICogb2JzZXJ2aW5nLgogICAqICAgKiBBbiBgb2JzZXJ2ZWAgdmFsdWUgb2YgZXZlbnRzIHJldHVybnMgYW4gb2JzZXJ2YWJsZSBvZiB0aGUgcmF3IGBIdHRwRXZlbnRgIHN0cmVhbSwgaW5jbHVkaW5nCiAgICogcHJvZ3Jlc3MgZXZlbnRzIGJ5IGRlZmF1bHQuCiAgICogICAqIEFuIGBvYnNlcnZlYCB2YWx1ZSBvZiByZXNwb25zZSByZXR1cm5zIGFuIG9ic2VydmFibGUgb2YgYEh0dHBSZXNwb25zZTxUPmAsCiAgICogd2hlcmUgdGhlIGBUYCBwYXJhbWV0ZXIgZGVwZW5kcyBvbiB0aGUgYHJlc3BvbnNlVHlwZWAgYW5kIGFueSBvcHRpb25hbGx5IHByb3ZpZGVkIHR5cGUKICAgKiBwYXJhbWV0ZXIuCiAgICogICAqIEFuIGBvYnNlcnZlYCB2YWx1ZSBvZiBib2R5IHJldHVybnMgYW4gb2JzZXJ2YWJsZSBvZiBgPFQ+YCB3aXRoIHRoZSBzYW1lIGBUYCBib2R5IHR5cGUuCiAgICoKICAgKi8KICByZXF1ZXN0KGZpcnN0LCB1cmwsIG9wdGlvbnMgPSB7fSkgewogICAgbGV0IHJlcTsKICAgIGlmIChmaXJzdCBpbnN0YW5jZW9mIEh0dHBSZXF1ZXN0KSB7CiAgICAgIHJlcSA9IGZpcnN0OwogICAgfSBlbHNlIHsKICAgICAgbGV0IGhlYWRlcnMgPSB2b2lkIDA7CiAgICAgIGlmIChvcHRpb25zLmhlYWRlcnMgaW5zdGFuY2VvZiBIdHRwSGVhZGVycykgewogICAgICAgIGhlYWRlcnMgPSBvcHRpb25zLmhlYWRlcnM7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycyhvcHRpb25zLmhlYWRlcnMpOwogICAgICB9CiAgICAgIGxldCBwYXJhbXMgPSB2b2lkIDA7CiAgICAgIGlmICghIW9wdGlvbnMucGFyYW1zKSB7CiAgICAgICAgaWYgKG9wdGlvbnMucGFyYW1zIGluc3RhbmNlb2YgSHR0cFBhcmFtcykgewogICAgICAgICAgcGFyYW1zID0gb3B0aW9ucy5wYXJhbXM7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKHsKICAgICAgICAgICAgZnJvbU9iamVjdDogb3B0aW9ucy5wYXJhbXMKICAgICAgICAgIH0pOwogICAgICAgIH0KICAgICAgfQogICAgICByZXEgPSBuZXcgSHR0cFJlcXVlc3QoZmlyc3QsIHVybCwgb3B0aW9ucy5ib2R5ICE9PSB2b2lkIDAgPyBvcHRpb25zLmJvZHkgOiBudWxsLCB7CiAgICAgICAgaGVhZGVycywKICAgICAgICBjb250ZXh0OiBvcHRpb25zLmNvbnRleHQsCiAgICAgICAgcGFyYW1zLAogICAgICAgIHJlcG9ydFByb2dyZXNzOiBvcHRpb25zLnJlcG9ydFByb2dyZXNzLAogICAgICAgIC8vIEJ5IGRlZmF1bHQsIEpTT04gaXMgYXNzdW1lZCB0byBiZSByZXR1cm5lZCBmb3IgYWxsIGNhbGxzLgogICAgICAgIHJlc3BvbnNlVHlwZTogb3B0aW9ucy5yZXNwb25zZVR5cGUgfHwgImpzb24iLAogICAgICAgIHdpdGhDcmVkZW50aWFsczogb3B0aW9ucy53aXRoQ3JlZGVudGlhbHMsCiAgICAgICAgdHJhbnNmZXJDYWNoZTogb3B0aW9ucy50cmFuc2ZlckNhY2hlCiAgICAgIH0pOwogICAgfQogICAgY29uc3QgZXZlbnRzJCA9IG9mKHJlcSkucGlwZShjb25jYXRNYXAoKHJlcTIpID0+IHRoaXMuaGFuZGxlci5oYW5kbGUocmVxMikpKTsKICAgIGlmIChmaXJzdCBpbnN0YW5jZW9mIEh0dHBSZXF1ZXN0IHx8IG9wdGlvbnMub2JzZXJ2ZSA9PT0gImV2ZW50cyIpIHsKICAgICAgcmV0dXJuIGV2ZW50cyQ7CiAgICB9CiAgICBjb25zdCByZXMkID0gZXZlbnRzJC5waXBlKGZpbHRlcigoZXZlbnQpID0+IGV2ZW50IGluc3RhbmNlb2YgSHR0cFJlc3BvbnNlKSk7CiAgICBzd2l0Y2ggKG9wdGlvbnMub2JzZXJ2ZSB8fCAiYm9keSIpIHsKICAgICAgY2FzZSAiYm9keSI6CiAgICAgICAgc3dpdGNoIChyZXEucmVzcG9uc2VUeXBlKSB7CiAgICAgICAgICBjYXNlICJhcnJheWJ1ZmZlciI6CiAgICAgICAgICAgIHJldHVybiByZXMkLnBpcGUobWFwKChyZXMpID0+IHsKICAgICAgICAgICAgICBpZiAocmVzLmJvZHkgIT09IG51bGwgJiYgIShyZXMuYm9keSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSkgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJSZXNwb25zZSBpcyBub3QgYW4gQXJyYXlCdWZmZXIuIik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiByZXMuYm9keTsKICAgICAgICAgICAgfSkpOwogICAgICAgICAgY2FzZSAiYmxvYiI6CiAgICAgICAgICAgIHJldHVybiByZXMkLnBpcGUobWFwKChyZXMpID0+IHsKICAgICAgICAgICAgICBpZiAocmVzLmJvZHkgIT09IG51bGwgJiYgIShyZXMuYm9keSBpbnN0YW5jZW9mIEJsb2IpKSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIlJlc3BvbnNlIGlzIG5vdCBhIEJsb2IuIik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiByZXMuYm9keTsKICAgICAgICAgICAgfSkpOwogICAgICAgICAgY2FzZSAidGV4dCI6CiAgICAgICAgICAgIHJldHVybiByZXMkLnBpcGUobWFwKChyZXMpID0+IHsKICAgICAgICAgICAgICBpZiAocmVzLmJvZHkgIT09IG51bGwgJiYgdHlwZW9mIHJlcy5ib2R5ICE9PSAic3RyaW5nIikgewogICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJSZXNwb25zZSBpcyBub3QgYSBzdHJpbmcuIik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiByZXMuYm9keTsKICAgICAgICAgICAgfSkpOwogICAgICAgICAgY2FzZSAianNvbiI6CiAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXR1cm4gcmVzJC5waXBlKG1hcCgocmVzKSA9PiByZXMuYm9keSkpOwogICAgICAgIH0KICAgICAgY2FzZSAicmVzcG9uc2UiOgogICAgICAgIHJldHVybiByZXMkOwogICAgICBkZWZhdWx0OgogICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5yZWFjaGFibGU6IHVuaGFuZGxlZCBvYnNlcnZlIHR5cGUgJHtvcHRpb25zLm9ic2VydmV9fWApOwogICAgfQogIH0KICAvKioKICAgKiBDb25zdHJ1Y3RzIGFuIG9ic2VydmFibGUgdGhhdCwgd2hlbiBzdWJzY3JpYmVkLCBjYXVzZXMgdGhlIGNvbmZpZ3VyZWQKICAgKiBgREVMRVRFYCByZXF1ZXN0IHRvIGV4ZWN1dGUgb24gdGhlIHNlcnZlci4gU2VlIHRoZSBpbmRpdmlkdWFsIG92ZXJsb2FkcyBmb3IKICAgKiBkZXRhaWxzIG9uIHRoZSByZXR1cm4gdHlwZS4KICAgKgogICAqIEBwYXJhbSB1cmwgICAgIFRoZSBlbmRwb2ludCBVUkwuCiAgICogQHBhcmFtIG9wdGlvbnMgVGhlIEhUVFAgb3B0aW9ucyB0byBzZW5kIHdpdGggdGhlIHJlcXVlc3QuCiAgICoKICAgKi8KICBkZWxldGUodXJsLCBvcHRpb25zID0ge30pIHsKICAgIHJldHVybiB0aGlzLnJlcXVlc3QoIkRFTEVURSIsIHVybCwgb3B0aW9ucyk7CiAgfQogIC8qKgogICAqIENvbnN0cnVjdHMgYW4gb2JzZXJ2YWJsZSB0aGF0LCB3aGVuIHN1YnNjcmliZWQsIGNhdXNlcyB0aGUgY29uZmlndXJlZAogICAqIGBHRVRgIHJlcXVlc3QgdG8gZXhlY3V0ZSBvbiB0aGUgc2VydmVyLiBTZWUgdGhlIGluZGl2aWR1YWwgb3ZlcmxvYWRzIGZvcgogICAqIGRldGFpbHMgb24gdGhlIHJldHVybiB0eXBlLgogICAqLwogIGdldCh1cmwsIG9wdGlvbnMgPSB7fSkgewogICAgcmV0dXJuIHRoaXMucmVxdWVzdCgiR0VUIiwgdXJsLCBvcHRpb25zKTsKICB9CiAgLyoqCiAgICogQ29uc3RydWN0cyBhbiBvYnNlcnZhYmxlIHRoYXQsIHdoZW4gc3Vic2NyaWJlZCwgY2F1c2VzIHRoZSBjb25maWd1cmVkCiAgICogYEhFQURgIHJlcXVlc3QgdG8gZXhlY3V0ZSBvbiB0aGUgc2VydmVyLiBUaGUgYEhFQURgIG1ldGhvZCByZXR1cm5zCiAgICogbWV0YSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcmVzb3VyY2Ugd2l0aG91dCB0cmFuc2ZlcnJpbmcgdGhlCiAgICogcmVzb3VyY2UgaXRzZWxmLiBTZWUgdGhlIGluZGl2aWR1YWwgb3ZlcmxvYWRzIGZvcgogICAqIGRldGFpbHMgb24gdGhlIHJldHVybiB0eXBlLgogICAqLwogIGhlYWQodXJsLCBvcHRpb25zID0ge30pIHsKICAgIHJldHVybiB0aGlzLnJlcXVlc3QoIkhFQUQiLCB1cmwsIG9wdGlvbnMpOwogIH0KICAvKioKICAgKiBDb25zdHJ1Y3RzIGFuIGBPYnNlcnZhYmxlYCB0aGF0LCB3aGVuIHN1YnNjcmliZWQsIGNhdXNlcyBhIHJlcXVlc3Qgd2l0aCB0aGUgc3BlY2lhbCBtZXRob2QKICAgKiBgSlNPTlBgIHRvIGJlIGRpc3BhdGNoZWQgdmlhIHRoZSBpbnRlcmNlcHRvciBwaXBlbGluZS4KICAgKiBUaGUgW0pTT05QIHBhdHRlcm5dKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0pTT05QKSB3b3JrcyBhcm91bmQgbGltaXRhdGlvbnMgb2YgY2VydGFpbgogICAqIEFQSSBlbmRwb2ludHMgdGhhdCBkb24ndCBzdXBwb3J0IG5ld2VyLAogICAqIGFuZCBwcmVmZXJhYmxlIFtDT1JTXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVFRQL0NPUlMpIHByb3RvY29sLgogICAqIEpTT05QIHRyZWF0cyB0aGUgZW5kcG9pbnQgQVBJIGFzIGEgSmF2YVNjcmlwdCBmaWxlIGFuZCB0cmlja3MgdGhlIGJyb3dzZXIgdG8gcHJvY2VzcyB0aGUKICAgKiByZXF1ZXN0cyBldmVuIGlmIHRoZSBBUEkgZW5kcG9pbnQgaXMgbm90IGxvY2F0ZWQgb24gdGhlIHNhbWUgZG9tYWluIChvcmlnaW4pIGFzIHRoZSBjbGllbnQtc2lkZQogICAqIGFwcGxpY2F0aW9uIG1ha2luZyB0aGUgcmVxdWVzdC4KICAgKiBUaGUgZW5kcG9pbnQgQVBJIG11c3Qgc3VwcG9ydCBKU09OUCBjYWxsYmFjayBmb3IgSlNPTlAgcmVxdWVzdHMgdG8gd29yay4KICAgKiBUaGUgcmVzb3VyY2UgQVBJIHJldHVybnMgdGhlIEpTT04gcmVzcG9uc2Ugd3JhcHBlZCBpbiBhIGNhbGxiYWNrIGZ1bmN0aW9uLgogICAqIFlvdSBjYW4gcGFzcyB0aGUgY2FsbGJhY2sgZnVuY3Rpb24gbmFtZSBhcyBvbmUgb2YgdGhlIHF1ZXJ5IHBhcmFtZXRlcnMuCiAgICogTm90ZSB0aGF0IEpTT05QIHJlcXVlc3RzIGNhbiBvbmx5IGJlIHVzZWQgd2l0aCBgR0VUYCByZXF1ZXN0cy4KICAgKgogICAqIEBwYXJhbSB1cmwgVGhlIHJlc291cmNlIFVSTC4KICAgKiBAcGFyYW0gY2FsbGJhY2tQYXJhbSBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gbmFtZS4KICAgKgogICAqLwogIGpzb25wKHVybCwgY2FsbGJhY2tQYXJhbSkgewogICAgcmV0dXJuIHRoaXMucmVxdWVzdCgiSlNPTlAiLCB1cmwsIHsKICAgICAgcGFyYW1zOiBuZXcgSHR0cFBhcmFtcygpLmFwcGVuZChjYWxsYmFja1BhcmFtLCAiSlNPTlBfQ0FMTEJBQ0siKSwKICAgICAgb2JzZXJ2ZTogImJvZHkiLAogICAgICByZXNwb25zZVR5cGU6ICJqc29uIgogICAgfSk7CiAgfQogIC8qKgogICAqIENvbnN0cnVjdHMgYW4gYE9ic2VydmFibGVgIHRoYXQsIHdoZW4gc3Vic2NyaWJlZCwgY2F1c2VzIHRoZSBjb25maWd1cmVkCiAgICogYE9QVElPTlNgIHJlcXVlc3QgdG8gZXhlY3V0ZSBvbiB0aGUgc2VydmVyLiBUaGlzIG1ldGhvZCBhbGxvd3MgdGhlIGNsaWVudAogICAqIHRvIGRldGVybWluZSB0aGUgc3VwcG9ydGVkIEhUVFAgbWV0aG9kcyBhbmQgb3RoZXIgY2FwYWJpbGl0aWVzIG9mIGFuIGVuZHBvaW50LAogICAqIHdpdGhvdXQgaW1wbHlpbmcgYSByZXNvdXJjZSBhY3Rpb24uIFNlZSB0aGUgaW5kaXZpZHVhbCBvdmVybG9hZHMgZm9yCiAgICogZGV0YWlscyBvbiB0aGUgcmV0dXJuIHR5cGUuCiAgICovCiAgb3B0aW9ucyh1cmwsIG9wdGlvbnMgPSB7fSkgewogICAgcmV0dXJuIHRoaXMucmVxdWVzdCgiT1BUSU9OUyIsIHVybCwgb3B0aW9ucyk7CiAgfQogIC8qKgogICAqIENvbnN0cnVjdHMgYW4gb2JzZXJ2YWJsZSB0aGF0LCB3aGVuIHN1YnNjcmliZWQsIGNhdXNlcyB0aGUgY29uZmlndXJlZAogICAqIGBQQVRDSGAgcmVxdWVzdCB0byBleGVjdXRlIG9uIHRoZSBzZXJ2ZXIuIFNlZSB0aGUgaW5kaXZpZHVhbCBvdmVybG9hZHMgZm9yCiAgICogZGV0YWlscyBvbiB0aGUgcmV0dXJuIHR5cGUuCiAgICovCiAgcGF0Y2godXJsLCBib2R5LCBvcHRpb25zID0ge30pIHsKICAgIHJldHVybiB0aGlzLnJlcXVlc3QoIlBBVENIIiwgdXJsLCBhZGRCb2R5KG9wdGlvbnMsIGJvZHkpKTsKICB9CiAgLyoqCiAgICogQ29uc3RydWN0cyBhbiBvYnNlcnZhYmxlIHRoYXQsIHdoZW4gc3Vic2NyaWJlZCwgY2F1c2VzIHRoZSBjb25maWd1cmVkCiAgICogYFBPU1RgIHJlcXVlc3QgdG8gZXhlY3V0ZSBvbiB0aGUgc2VydmVyLiBUaGUgc2VydmVyIHJlc3BvbmRzIHdpdGggdGhlIGxvY2F0aW9uIG9mCiAgICogdGhlIHJlcGxhY2VkIHJlc291cmNlLiBTZWUgdGhlIGluZGl2aWR1YWwgb3ZlcmxvYWRzIGZvcgogICAqIGRldGFpbHMgb24gdGhlIHJldHVybiB0eXBlLgogICAqLwogIHBvc3QodXJsLCBib2R5LCBvcHRpb25zID0ge30pIHsKICAgIHJldHVybiB0aGlzLnJlcXVlc3QoIlBPU1QiLCB1cmwsIGFkZEJvZHkob3B0aW9ucywgYm9keSkpOwogIH0KICAvKioKICAgKiBDb25zdHJ1Y3RzIGFuIG9ic2VydmFibGUgdGhhdCwgd2hlbiBzdWJzY3JpYmVkLCBjYXVzZXMgdGhlIGNvbmZpZ3VyZWQKICAgKiBgUFVUYCByZXF1ZXN0IHRvIGV4ZWN1dGUgb24gdGhlIHNlcnZlci4gVGhlIGBQVVRgIG1ldGhvZCByZXBsYWNlcyBhbiBleGlzdGluZyByZXNvdXJjZQogICAqIHdpdGggYSBuZXcgc2V0IG9mIHZhbHVlcy4KICAgKiBTZWUgdGhlIGluZGl2aWR1YWwgb3ZlcmxvYWRzIGZvciBkZXRhaWxzIG9uIHRoZSByZXR1cm4gdHlwZS4KICAgKi8KICBwdXQodXJsLCBib2R5LCBvcHRpb25zID0ge30pIHsKICAgIHJldHVybiB0aGlzLnJlcXVlc3QoIlBVVCIsIHVybCwgYWRkQm9keShvcHRpb25zLCBib2R5KSk7CiAgfQp9OwpfSHR0cENsaWVudC7JtWZhYyA9IGZ1bmN0aW9uIEh0dHBDbGllbnRfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfSHR0cENsaWVudCkoybXJtWluamVjdChIdHRwSGFuZGxlcikpOwp9OwpfSHR0cENsaWVudC7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7CiAgdG9rZW46IF9IdHRwQ2xpZW50LAogIGZhY3Rvcnk6IF9IdHRwQ2xpZW50Lsm1ZmFjCn0pOwp2YXIgSHR0cENsaWVudCA9IF9IdHRwQ2xpZW50OwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoSHR0cENsaWVudCwgW3sKICAgIHR5cGU6IEluamVjdGFibGUKICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IEh0dHBIYW5kbGVyCiAgfV0sIG51bGwpOwp9KSgpOwp2YXIgWFNTSV9QUkVGSVgkMSA9IC9eXClcXVx9Jyw/XG4vOwp2YXIgUkVRVUVTVF9VUkxfSEVBREVSID0gYFgtUmVxdWVzdC1VUkxgOwpmdW5jdGlvbiBnZXRSZXNwb25zZVVybCQxKHJlc3BvbnNlKSB7CiAgaWYgKHJlc3BvbnNlLnVybCkgewogICAgcmV0dXJuIHJlc3BvbnNlLnVybDsKICB9CiAgY29uc3QgeFJlcXVlc3RVcmwgPSBSRVFVRVNUX1VSTF9IRUFERVIudG9Mb2NhbGVMb3dlckNhc2UoKTsKICByZXR1cm4gcmVzcG9uc2UuaGVhZGVycy5nZXQoeFJlcXVlc3RVcmwpOwp9CnZhciBfRmV0Y2hCYWNrZW5kID0gY2xhc3MgX0ZldGNoQmFja2VuZCB7CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLmZldGNoSW1wbCA9IGluamVjdChGZXRjaEZhY3RvcnksIHsKICAgICAgb3B0aW9uYWw6IHRydWUKICAgIH0pPy5mZXRjaCA/PyBmZXRjaC5iaW5kKGdsb2JhbFRoaXMpOwogICAgdGhpcy5uZ1pvbmUgPSBpbmplY3QoTmdab25lKTsKICB9CiAgaGFuZGxlKHJlcXVlc3QpIHsKICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgob2JzZXJ2ZXIpID0+IHsKICAgICAgY29uc3QgYWJvcnRlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTsKICAgICAgdGhpcy5kb1JlcXVlc3QocmVxdWVzdCwgYWJvcnRlci5zaWduYWwsIG9ic2VydmVyKS50aGVuKG5vb3AsIChlcnJvcikgPT4gb2JzZXJ2ZXIuZXJyb3IobmV3IEh0dHBFcnJvclJlc3BvbnNlKHsKICAgICAgICBlcnJvcgogICAgICB9KSkpOwogICAgICByZXR1cm4gKCkgPT4gYWJvcnRlci5hYm9ydCgpOwogICAgfSk7CiAgfQogIGFzeW5jIGRvUmVxdWVzdChyZXF1ZXN0LCBzaWduYWwsIG9ic2VydmVyKSB7CiAgICBjb25zdCBpbml0ID0gdGhpcy5jcmVhdGVSZXF1ZXN0SW5pdChyZXF1ZXN0KTsKICAgIGxldCByZXNwb25zZTsKICAgIHRyeSB7CiAgICAgIGNvbnN0IGZldGNoUHJvbWlzZSA9IHRoaXMuZmV0Y2hJbXBsKHJlcXVlc3QudXJsV2l0aFBhcmFtcywgX19zcHJlYWRWYWx1ZXMoewogICAgICAgIHNpZ25hbAogICAgICB9LCBpbml0KSk7CiAgICAgIHNpbGVuY2VTdXBlcmZsdW91c1VuaGFuZGxlZFByb21pc2VSZWplY3Rpb24oZmV0Y2hQcm9taXNlKTsKICAgICAgb2JzZXJ2ZXIubmV4dCh7CiAgICAgICAgdHlwZTogSHR0cEV2ZW50VHlwZS5TZW50CiAgICAgIH0pOwogICAgICByZXNwb25zZSA9IGF3YWl0IGZldGNoUHJvbWlzZTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgIG9ic2VydmVyLmVycm9yKG5ldyBIdHRwRXJyb3JSZXNwb25zZSh7CiAgICAgICAgZXJyb3IsCiAgICAgICAgc3RhdHVzOiBlcnJvci5zdGF0dXMgPz8gMCwKICAgICAgICBzdGF0dXNUZXh0OiBlcnJvci5zdGF0dXNUZXh0LAogICAgICAgIHVybDogcmVxdWVzdC51cmxXaXRoUGFyYW1zLAogICAgICAgIGhlYWRlcnM6IGVycm9yLmhlYWRlcnMKICAgICAgfSkpOwogICAgICByZXR1cm47CiAgICB9CiAgICBjb25zdCBoZWFkZXJzID0gbmV3IEh0dHBIZWFkZXJzKHJlc3BvbnNlLmhlYWRlcnMpOwogICAgY29uc3Qgc3RhdHVzVGV4dCA9IHJlc3BvbnNlLnN0YXR1c1RleHQ7CiAgICBjb25zdCB1cmwgPSBnZXRSZXNwb25zZVVybCQxKHJlc3BvbnNlKSA/PyByZXF1ZXN0LnVybFdpdGhQYXJhbXM7CiAgICBsZXQgc3RhdHVzID0gcmVzcG9uc2Uuc3RhdHVzOwogICAgbGV0IGJvZHkgPSBudWxsOwogICAgaWYgKHJlcXVlc3QucmVwb3J0UHJvZ3Jlc3MpIHsKICAgICAgb2JzZXJ2ZXIubmV4dChuZXcgSHR0cEhlYWRlclJlc3BvbnNlKHsKICAgICAgICBoZWFkZXJzLAogICAgICAgIHN0YXR1cywKICAgICAgICBzdGF0dXNUZXh0LAogICAgICAgIHVybAogICAgICB9KSk7CiAgICB9CiAgICBpZiAocmVzcG9uc2UuYm9keSkgewogICAgICBjb25zdCBjb250ZW50TGVuZ3RoID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoImNvbnRlbnQtbGVuZ3RoIik7CiAgICAgIGNvbnN0IGNodW5rcyA9IFtdOwogICAgICBjb25zdCByZWFkZXIgPSByZXNwb25zZS5ib2R5LmdldFJlYWRlcigpOwogICAgICBsZXQgcmVjZWl2ZWRMZW5ndGggPSAwOwogICAgICBsZXQgZGVjb2RlcjsKICAgICAgbGV0IHBhcnRpYWxUZXh0OwogICAgICBjb25zdCByZXFab25lID0gdHlwZW9mIFpvbmUgIT09ICJ1bmRlZmluZWQiICYmIFpvbmUuY3VycmVudDsKICAgICAgYXdhaXQgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoYXN5bmMgKCkgPT4gewogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICBjb25zdCB7CiAgICAgICAgICAgIGRvbmUsCiAgICAgICAgICAgIHZhbHVlCiAgICAgICAgICB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTsKICAgICAgICAgIGlmIChkb25lKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY2h1bmtzLnB1c2godmFsdWUpOwogICAgICAgICAgcmVjZWl2ZWRMZW5ndGggKz0gdmFsdWUubGVuZ3RoOwogICAgICAgICAgaWYgKHJlcXVlc3QucmVwb3J0UHJvZ3Jlc3MpIHsKICAgICAgICAgICAgcGFydGlhbFRleHQgPSByZXF1ZXN0LnJlc3BvbnNlVHlwZSA9PT0gInRleHQiID8gKHBhcnRpYWxUZXh0ID8/ICIiKSArIChkZWNvZGVyID8/PSBuZXcgVGV4dERlY29kZXIoKSkuZGVjb2RlKHZhbHVlLCB7CiAgICAgICAgICAgICAgc3RyZWFtOiB0cnVlCiAgICAgICAgICAgIH0pIDogdm9pZCAwOwogICAgICAgICAgICBjb25zdCByZXBvcnRQcm9ncmVzcyA9ICgpID0+IG9ic2VydmVyLm5leHQoewogICAgICAgICAgICAgIHR5cGU6IEh0dHBFdmVudFR5cGUuRG93bmxvYWRQcm9ncmVzcywKICAgICAgICAgICAgICB0b3RhbDogY29udGVudExlbmd0aCA/ICtjb250ZW50TGVuZ3RoIDogdm9pZCAwLAogICAgICAgICAgICAgIGxvYWRlZDogcmVjZWl2ZWRMZW5ndGgsCiAgICAgICAgICAgICAgcGFydGlhbFRleHQKICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIHJlcVpvbmUgPyByZXFab25lLnJ1bihyZXBvcnRQcm9ncmVzcykgOiByZXBvcnRQcm9ncmVzcygpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfSk7CiAgICAgIGNvbnN0IGNodW5rc0FsbCA9IHRoaXMuY29uY2F0Q2h1bmtzKGNodW5rcywgcmVjZWl2ZWRMZW5ndGgpOwogICAgICB0cnkgewogICAgICAgIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoIkNvbnRlbnQtVHlwZSIpID8/ICIiOwogICAgICAgIGJvZHkgPSB0aGlzLnBhcnNlQm9keShyZXF1ZXN0LCBjaHVua3NBbGwsIGNvbnRlbnRUeXBlKTsKICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICBvYnNlcnZlci5lcnJvcihuZXcgSHR0cEVycm9yUmVzcG9uc2UoewogICAgICAgICAgZXJyb3IsCiAgICAgICAgICBoZWFkZXJzOiBuZXcgSHR0cEhlYWRlcnMocmVzcG9uc2UuaGVhZGVycyksCiAgICAgICAgICBzdGF0dXM6IHJlc3BvbnNlLnN0YXR1cywKICAgICAgICAgIHN0YXR1c1RleHQ6IHJlc3BvbnNlLnN0YXR1c1RleHQsCiAgICAgICAgICB1cmw6IGdldFJlc3BvbnNlVXJsJDEocmVzcG9uc2UpID8/IHJlcXVlc3QudXJsV2l0aFBhcmFtcwogICAgICAgIH0pKTsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgIH0KICAgIGlmIChzdGF0dXMgPT09IDApIHsKICAgICAgc3RhdHVzID0gYm9keSA/IEhUVFBfU1RBVFVTX0NPREVfT0sgOiAwOwogICAgfQogICAgY29uc3Qgb2sgPSBzdGF0dXMgPj0gMjAwICYmIHN0YXR1cyA8IDMwMDsKICAgIGlmIChvaykgewogICAgICBvYnNlcnZlci5uZXh0KG5ldyBIdHRwUmVzcG9uc2UoewogICAgICAgIGJvZHksCiAgICAgICAgaGVhZGVycywKICAgICAgICBzdGF0dXMsCiAgICAgICAgc3RhdHVzVGV4dCwKICAgICAgICB1cmwKICAgICAgfSkpOwogICAgICBvYnNlcnZlci5jb21wbGV0ZSgpOwogICAgfSBlbHNlIHsKICAgICAgb2JzZXJ2ZXIuZXJyb3IobmV3IEh0dHBFcnJvclJlc3BvbnNlKHsKICAgICAgICBlcnJvcjogYm9keSwKICAgICAgICBoZWFkZXJzLAogICAgICAgIHN0YXR1cywKICAgICAgICBzdGF0dXNUZXh0LAogICAgICAgIHVybAogICAgICB9KSk7CiAgICB9CiAgfQogIHBhcnNlQm9keShyZXF1ZXN0LCBiaW5Db250ZW50LCBjb250ZW50VHlwZSkgewogICAgc3dpdGNoIChyZXF1ZXN0LnJlc3BvbnNlVHlwZSkgewogICAgICBjYXNlICJqc29uIjoKICAgICAgICBjb25zdCB0ZXh0ID0gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGJpbkNvbnRlbnQpLnJlcGxhY2UoWFNTSV9QUkVGSVgkMSwgIiIpOwogICAgICAgIHJldHVybiB0ZXh0ID09PSAiIiA/IG51bGwgOiBKU09OLnBhcnNlKHRleHQpOwogICAgICBjYXNlICJ0ZXh0IjoKICAgICAgICByZXR1cm4gbmV3IFRleHREZWNvZGVyKCkuZGVjb2RlKGJpbkNvbnRlbnQpOwogICAgICBjYXNlICJibG9iIjoKICAgICAgICByZXR1cm4gbmV3IEJsb2IoW2JpbkNvbnRlbnRdLCB7CiAgICAgICAgICB0eXBlOiBjb250ZW50VHlwZQogICAgICAgIH0pOwogICAgICBjYXNlICJhcnJheWJ1ZmZlciI6CiAgICAgICAgcmV0dXJuIGJpbkNvbnRlbnQuYnVmZmVyOwogICAgfQogIH0KICBjcmVhdGVSZXF1ZXN0SW5pdChyZXEpIHsKICAgIGNvbnN0IGhlYWRlcnMgPSB7fTsKICAgIGNvbnN0IGNyZWRlbnRpYWxzID0gcmVxLndpdGhDcmVkZW50aWFscyA/ICJpbmNsdWRlIiA6IHZvaWQgMDsKICAgIHJlcS5oZWFkZXJzLmZvckVhY2goKG5hbWUsIHZhbHVlcykgPT4gaGVhZGVyc1tuYW1lXSA9IHZhbHVlcy5qb2luKCIsIikpOwogICAgaGVhZGVyc1siQWNjZXB0Il0gPz89ICJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L3BsYWluLCAqLyoiOwogICAgaWYgKCFoZWFkZXJzWyJDb250ZW50LVR5cGUiXSkgewogICAgICBjb25zdCBkZXRlY3RlZFR5cGUgPSByZXEuZGV0ZWN0Q29udGVudFR5cGVIZWFkZXIoKTsKICAgICAgaWYgKGRldGVjdGVkVHlwZSAhPT0gbnVsbCkgewogICAgICAgIGhlYWRlcnNbIkNvbnRlbnQtVHlwZSJdID0gZGV0ZWN0ZWRUeXBlOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gewogICAgICBib2R5OiByZXEuc2VyaWFsaXplQm9keSgpLAogICAgICBtZXRob2Q6IHJlcS5tZXRob2QsCiAgICAgIGhlYWRlcnMsCiAgICAgIGNyZWRlbnRpYWxzCiAgICB9OwogIH0KICBjb25jYXRDaHVua3MoY2h1bmtzLCB0b3RhbExlbmd0aCkgewogICAgY29uc3QgY2h1bmtzQWxsID0gbmV3IFVpbnQ4QXJyYXkodG90YWxMZW5ndGgpOwogICAgbGV0IHBvc2l0aW9uID0gMDsKICAgIGZvciAoY29uc3QgY2h1bmsgb2YgY2h1bmtzKSB7CiAgICAgIGNodW5rc0FsbC5zZXQoY2h1bmssIHBvc2l0aW9uKTsKICAgICAgcG9zaXRpb24gKz0gY2h1bmsubGVuZ3RoOwogICAgfQogICAgcmV0dXJuIGNodW5rc0FsbDsKICB9Cn07Cl9GZXRjaEJhY2tlbmQuybVmYWMgPSBmdW5jdGlvbiBGZXRjaEJhY2tlbmRfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfRmV0Y2hCYWNrZW5kKSgpOwp9OwpfRmV0Y2hCYWNrZW5kLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX0ZldGNoQmFja2VuZCwKICBmYWN0b3J5OiBfRmV0Y2hCYWNrZW5kLsm1ZmFjCn0pOwp2YXIgRmV0Y2hCYWNrZW5kID0gX0ZldGNoQmFja2VuZDsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKEZldGNoQmFja2VuZCwgW3sKICAgIHR5cGU6IEluamVjdGFibGUKICB9XSwgbnVsbCwgbnVsbCk7Cn0pKCk7CnZhciBGZXRjaEZhY3RvcnkgPSBjbGFzcyB7Cn07CmZ1bmN0aW9uIG5vb3AoKSB7Cn0KZnVuY3Rpb24gc2lsZW5jZVN1cGVyZmx1b3VzVW5oYW5kbGVkUHJvbWlzZVJlamVjdGlvbihwcm9taXNlKSB7CiAgcHJvbWlzZS50aGVuKG5vb3AsIG5vb3ApOwp9CmZ1bmN0aW9uIGludGVyY2VwdG9yQ2hhaW5FbmRGbihyZXEsIGZpbmFsSGFuZGxlckZuKSB7CiAgcmV0dXJuIGZpbmFsSGFuZGxlckZuKHJlcSk7Cn0KZnVuY3Rpb24gYWRhcHRMZWdhY3lJbnRlcmNlcHRvclRvQ2hhaW4oY2hhaW5UYWlsRm4sIGludGVyY2VwdG9yKSB7CiAgcmV0dXJuIChpbml0aWFsUmVxdWVzdCwgZmluYWxIYW5kbGVyRm4pID0+IGludGVyY2VwdG9yLmludGVyY2VwdChpbml0aWFsUmVxdWVzdCwgewogICAgaGFuZGxlOiAoZG93bnN0cmVhbVJlcXVlc3QpID0+IGNoYWluVGFpbEZuKGRvd25zdHJlYW1SZXF1ZXN0LCBmaW5hbEhhbmRsZXJGbikKICB9KTsKfQpmdW5jdGlvbiBjaGFpbmVkSW50ZXJjZXB0b3JGbihjaGFpblRhaWxGbiwgaW50ZXJjZXB0b3JGbiwgaW5qZWN0b3IpIHsKICByZXR1cm4gKGluaXRpYWxSZXF1ZXN0LCBmaW5hbEhhbmRsZXJGbikgPT4gcnVuSW5JbmplY3Rpb25Db250ZXh0KGluamVjdG9yLCAoKSA9PiBpbnRlcmNlcHRvckZuKGluaXRpYWxSZXF1ZXN0LCAoZG93bnN0cmVhbVJlcXVlc3QpID0+IGNoYWluVGFpbEZuKGRvd25zdHJlYW1SZXF1ZXN0LCBmaW5hbEhhbmRsZXJGbikpKTsKfQp2YXIgSFRUUF9JTlRFUkNFUFRPUlMgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gIkhUVFBfSU5URVJDRVBUT1JTIiA6ICIiKTsKdmFyIEhUVFBfSU5URVJDRVBUT1JfRk5TID0gbmV3IEluamVjdGlvblRva2VuKG5nRGV2TW9kZSA/ICJIVFRQX0lOVEVSQ0VQVE9SX0ZOUyIgOiAiIik7CnZhciBIVFRQX1JPT1RfSU5URVJDRVBUT1JfRk5TID0gbmV3IEluamVjdGlvblRva2VuKG5nRGV2TW9kZSA/ICJIVFRQX1JPT1RfSU5URVJDRVBUT1JfRk5TIiA6ICIiKTsKdmFyIFJFUVVFU1RTX0NPTlRSSUJVVEVfVE9fU1RBQklMSVRZID0gbmV3IEluamVjdGlvblRva2VuKG5nRGV2TW9kZSA/ICJSRVFVRVNUU19DT05UUklCVVRFX1RPX1NUQUJJTElUWSIgOiAiIiwgewogIHByb3ZpZGVkSW46ICJyb290IiwKICBmYWN0b3J5OiAoKSA9PiB0cnVlCn0pOwpmdW5jdGlvbiBsZWdhY3lJbnRlcmNlcHRvckZuRmFjdG9yeSgpIHsKICBsZXQgY2hhaW4gPSBudWxsOwogIHJldHVybiAocmVxLCBoYW5kbGVyKSA9PiB7CiAgICBpZiAoY2hhaW4gPT09IG51bGwpIHsKICAgICAgY29uc3QgaW50ZXJjZXB0b3JzID0gaW5qZWN0KEhUVFBfSU5URVJDRVBUT1JTLCB7CiAgICAgICAgb3B0aW9uYWw6IHRydWUKICAgICAgfSkgPz8gW107CiAgICAgIGNoYWluID0gaW50ZXJjZXB0b3JzLnJlZHVjZVJpZ2h0KGFkYXB0TGVnYWN5SW50ZXJjZXB0b3JUb0NoYWluLCBpbnRlcmNlcHRvckNoYWluRW5kRm4pOwogICAgfQogICAgY29uc3QgcGVuZGluZ1Rhc2tzID0gaW5qZWN0KFBlbmRpbmdUYXNrcyk7CiAgICBjb25zdCBjb250cmlidXRlVG9TdGFiaWxpdHkgPSBpbmplY3QoUkVRVUVTVFNfQ09OVFJJQlVURV9UT19TVEFCSUxJVFkpOwogICAgaWYgKGNvbnRyaWJ1dGVUb1N0YWJpbGl0eSkgewogICAgICBjb25zdCB0YXNrSWQgPSBwZW5kaW5nVGFza3MuYWRkKCk7CiAgICAgIHJldHVybiBjaGFpbihyZXEsIGhhbmRsZXIpLnBpcGUoZmluYWxpemUoKCkgPT4gcGVuZGluZ1Rhc2tzLnJlbW92ZSh0YXNrSWQpKSk7CiAgICB9IGVsc2UgewogICAgICByZXR1cm4gY2hhaW4ocmVxLCBoYW5kbGVyKTsKICAgIH0KICB9Owp9CnZhciBmZXRjaEJhY2tlbmRXYXJuaW5nRGlzcGxheWVkID0gZmFsc2U7CnZhciBfSHR0cEludGVyY2VwdG9ySGFuZGxlciA9IGNsYXNzIF9IdHRwSW50ZXJjZXB0b3JIYW5kbGVyIGV4dGVuZHMgSHR0cEhhbmRsZXIgewogIGNvbnN0cnVjdG9yKGJhY2tlbmQsIGluamVjdG9yKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5iYWNrZW5kID0gYmFja2VuZDsKICAgIHRoaXMuaW5qZWN0b3IgPSBpbmplY3RvcjsKICAgIHRoaXMuY2hhaW4gPSBudWxsOwogICAgdGhpcy5wZW5kaW5nVGFza3MgPSBpbmplY3QoUGVuZGluZ1Rhc2tzKTsKICAgIHRoaXMuY29udHJpYnV0ZVRvU3RhYmlsaXR5ID0gaW5qZWN0KFJFUVVFU1RTX0NPTlRSSUJVVEVfVE9fU1RBQklMSVRZKTsKICAgIGlmICgodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiAhZmV0Y2hCYWNrZW5kV2FybmluZ0Rpc3BsYXllZCkgewogICAgICBjb25zdCBpc1NlcnZlciA9IGlzUGxhdGZvcm1TZXJ2ZXIoaW5qZWN0b3IuZ2V0KFBMQVRGT1JNX0lEKSk7CiAgICAgIGlmIChpc1NlcnZlciAmJiAhKHRoaXMuYmFja2VuZCBpbnN0YW5jZW9mIEZldGNoQmFja2VuZCkpIHsKICAgICAgICBmZXRjaEJhY2tlbmRXYXJuaW5nRGlzcGxheWVkID0gdHJ1ZTsKICAgICAgICBpbmplY3Rvci5nZXQoQ29uc29sZSkud2Fybihmb3JtYXRSdW50aW1lRXJyb3IoMjgwMSwgIkFuZ3VsYXIgZGV0ZWN0ZWQgdGhhdCBgSHR0cENsaWVudGAgaXMgbm90IGNvbmZpZ3VyZWQgdG8gdXNlIGBmZXRjaGAgQVBJcy4gSXQncyBzdHJvbmdseSByZWNvbW1lbmRlZCB0byBlbmFibGUgYGZldGNoYCBmb3IgYXBwbGljYXRpb25zIHRoYXQgdXNlIFNlcnZlci1TaWRlIFJlbmRlcmluZyBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlIGFuZCBjb21wYXRpYmlsaXR5LiBUbyBlbmFibGUgYGZldGNoYCwgYWRkIHRoZSBgd2l0aEZldGNoKClgIHRvIHRoZSBgcHJvdmlkZUh0dHBDbGllbnQoKWAgY2FsbCBhdCB0aGUgcm9vdCBvZiB0aGUgYXBwbGljYXRpb24uIikpOwogICAgICB9CiAgICB9CiAgfQogIGhhbmRsZShpbml0aWFsUmVxdWVzdCkgewogICAgaWYgKHRoaXMuY2hhaW4gPT09IG51bGwpIHsKICAgICAgY29uc3QgZGVkdXBlZEludGVyY2VwdG9yRm5zID0gQXJyYXkuZnJvbSgvKiBAX19QVVJFX18gKi8gbmV3IFNldChbLi4udGhpcy5pbmplY3Rvci5nZXQoSFRUUF9JTlRFUkNFUFRPUl9GTlMpLCAuLi50aGlzLmluamVjdG9yLmdldChIVFRQX1JPT1RfSU5URVJDRVBUT1JfRk5TLCBbXSldKSk7CiAgICAgIHRoaXMuY2hhaW4gPSBkZWR1cGVkSW50ZXJjZXB0b3JGbnMucmVkdWNlUmlnaHQoKG5leHRTZXF1ZW5jZWRGbiwgaW50ZXJjZXB0b3JGbikgPT4gY2hhaW5lZEludGVyY2VwdG9yRm4obmV4dFNlcXVlbmNlZEZuLCBpbnRlcmNlcHRvckZuLCB0aGlzLmluamVjdG9yKSwgaW50ZXJjZXB0b3JDaGFpbkVuZEZuKTsKICAgIH0KICAgIGlmICh0aGlzLmNvbnRyaWJ1dGVUb1N0YWJpbGl0eSkgewogICAgICBjb25zdCB0YXNrSWQgPSB0aGlzLnBlbmRpbmdUYXNrcy5hZGQoKTsKICAgICAgcmV0dXJuIHRoaXMuY2hhaW4oaW5pdGlhbFJlcXVlc3QsIChkb3duc3RyZWFtUmVxdWVzdCkgPT4gdGhpcy5iYWNrZW5kLmhhbmRsZShkb3duc3RyZWFtUmVxdWVzdCkpLnBpcGUoZmluYWxpemUoKCkgPT4gdGhpcy5wZW5kaW5nVGFza3MucmVtb3ZlKHRhc2tJZCkpKTsKICAgIH0gZWxzZSB7CiAgICAgIHJldHVybiB0aGlzLmNoYWluKGluaXRpYWxSZXF1ZXN0LCAoZG93bnN0cmVhbVJlcXVlc3QpID0+IHRoaXMuYmFja2VuZC5oYW5kbGUoZG93bnN0cmVhbVJlcXVlc3QpKTsKICAgIH0KICB9Cn07Cl9IdHRwSW50ZXJjZXB0b3JIYW5kbGVyLsm1ZmFjID0gZnVuY3Rpb24gSHR0cEludGVyY2VwdG9ySGFuZGxlcl9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9IdHRwSW50ZXJjZXB0b3JIYW5kbGVyKSjJtcm1aW5qZWN0KEh0dHBCYWNrZW5kKSwgybXJtWluamVjdChFbnZpcm9ubWVudEluamVjdG9yKSk7Cn07Cl9IdHRwSW50ZXJjZXB0b3JIYW5kbGVyLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX0h0dHBJbnRlcmNlcHRvckhhbmRsZXIsCiAgZmFjdG9yeTogX0h0dHBJbnRlcmNlcHRvckhhbmRsZXIuybVmYWMKfSk7CnZhciBIdHRwSW50ZXJjZXB0b3JIYW5kbGVyID0gX0h0dHBJbnRlcmNlcHRvckhhbmRsZXI7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShIdHRwSW50ZXJjZXB0b3JIYW5kbGVyLCBbewogICAgdHlwZTogSW5qZWN0YWJsZQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogSHR0cEJhY2tlbmQKICB9LCB7CiAgICB0eXBlOiBFbnZpcm9ubWVudEluamVjdG9yCiAgfV0sIG51bGwpOwp9KSgpOwp2YXIgbmV4dFJlcXVlc3RJZCA9IDA7CnZhciBmb3JlaWduRG9jdW1lbnQ7CnZhciBKU09OUF9FUlJfTk9fQ0FMTEJBQ0sgPSAiSlNPTlAgaW5qZWN0ZWQgc2NyaXB0IGRpZCBub3QgaW52b2tlIGNhbGxiYWNrLiI7CnZhciBKU09OUF9FUlJfV1JPTkdfTUVUSE9EID0gIkpTT05QIHJlcXVlc3RzIG11c3QgdXNlIEpTT05QIHJlcXVlc3QgbWV0aG9kLiI7CnZhciBKU09OUF9FUlJfV1JPTkdfUkVTUE9OU0VfVFlQRSA9ICJKU09OUCByZXF1ZXN0cyBtdXN0IHVzZSBKc29uIHJlc3BvbnNlIHR5cGUuIjsKdmFyIEpTT05QX0VSUl9IRUFERVJTX05PVF9TVVBQT1JURUQgPSAiSlNPTlAgcmVxdWVzdHMgZG8gbm90IHN1cHBvcnQgaGVhZGVycy4iOwp2YXIgSnNvbnBDYWxsYmFja0NvbnRleHQgPSBjbGFzcyB7Cn07CmZ1bmN0aW9uIGpzb25wQ2FsbGJhY2tDb250ZXh0KCkgewogIGlmICh0eXBlb2Ygd2luZG93ID09PSAib2JqZWN0IikgewogICAgcmV0dXJuIHdpbmRvdzsKICB9CiAgcmV0dXJuIHt9Owp9CnZhciBfSnNvbnBDbGllbnRCYWNrZW5kID0gY2xhc3MgX0pzb25wQ2xpZW50QmFja2VuZCB7CiAgY29uc3RydWN0b3IoY2FsbGJhY2tNYXAsIGRvY3VtZW50MikgewogICAgdGhpcy5jYWxsYmFja01hcCA9IGNhbGxiYWNrTWFwOwogICAgdGhpcy5kb2N1bWVudCA9IGRvY3VtZW50MjsKICAgIHRoaXMucmVzb2x2ZWRQcm9taXNlID0gUHJvbWlzZS5yZXNvbHZlKCk7CiAgfQogIC8qKgogICAqIEdldCB0aGUgbmFtZSBvZiB0aGUgbmV4dCBjYWxsYmFjayBtZXRob2QsIGJ5IGluY3JlbWVudGluZyB0aGUgZ2xvYmFsIGBuZXh0UmVxdWVzdElkYC4KICAgKi8KICBuZXh0Q2FsbGJhY2soKSB7CiAgICByZXR1cm4gYG5nX2pzb25wX2NhbGxiYWNrXyR7bmV4dFJlcXVlc3RJZCsrfWA7CiAgfQogIC8qKgogICAqIFByb2Nlc3NlcyBhIEpTT05QIHJlcXVlc3QgYW5kIHJldHVybnMgYW4gZXZlbnQgc3RyZWFtIG9mIHRoZSByZXN1bHRzLgogICAqIEBwYXJhbSByZXEgVGhlIHJlcXVlc3Qgb2JqZWN0LgogICAqIEByZXR1cm5zIEFuIG9ic2VydmFibGUgb2YgdGhlIHJlc3BvbnNlIGV2ZW50cy4KICAgKgogICAqLwogIGhhbmRsZShyZXEpIHsKICAgIGlmIChyZXEubWV0aG9kICE9PSAiSlNPTlAiKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihKU09OUF9FUlJfV1JPTkdfTUVUSE9EKTsKICAgIH0gZWxzZSBpZiAocmVxLnJlc3BvbnNlVHlwZSAhPT0gImpzb24iKSB7CiAgICAgIHRocm93IG5ldyBFcnJvcihKU09OUF9FUlJfV1JPTkdfUkVTUE9OU0VfVFlQRSk7CiAgICB9CiAgICBpZiAocmVxLmhlYWRlcnMua2V5cygpLmxlbmd0aCA+IDApIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKEpTT05QX0VSUl9IRUFERVJTX05PVF9TVVBQT1JURUQpOwogICAgfQogICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcikgPT4gewogICAgICBjb25zdCBjYWxsYmFjayA9IHRoaXMubmV4dENhbGxiYWNrKCk7CiAgICAgIGNvbnN0IHVybCA9IHJlcS51cmxXaXRoUGFyYW1zLnJlcGxhY2UoLz1KU09OUF9DQUxMQkFDSygmfCQpLywgYD0ke2NhbGxiYWNrfSQxYCk7CiAgICAgIGNvbnN0IG5vZGUgPSB0aGlzLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNjcmlwdCIpOwogICAgICBub2RlLnNyYyA9IHVybDsKICAgICAgbGV0IGJvZHkgPSBudWxsOwogICAgICBsZXQgZmluaXNoZWQgPSBmYWxzZTsKICAgICAgdGhpcy5jYWxsYmFja01hcFtjYWxsYmFja10gPSAoZGF0YSkgPT4gewogICAgICAgIGRlbGV0ZSB0aGlzLmNhbGxiYWNrTWFwW2NhbGxiYWNrXTsKICAgICAgICBib2R5ID0gZGF0YTsKICAgICAgICBmaW5pc2hlZCA9IHRydWU7CiAgICAgIH07CiAgICAgIGNvbnN0IGNsZWFudXAgPSAoKSA9PiB7CiAgICAgICAgaWYgKG5vZGUucGFyZW50Tm9kZSkgewogICAgICAgICAgbm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG5vZGUpOwogICAgICAgIH0KICAgICAgICBkZWxldGUgdGhpcy5jYWxsYmFja01hcFtjYWxsYmFja107CiAgICAgIH07CiAgICAgIGNvbnN0IG9uTG9hZCA9IChldmVudCkgPT4gewogICAgICAgIHRoaXMucmVzb2x2ZWRQcm9taXNlLnRoZW4oKCkgPT4gewogICAgICAgICAgY2xlYW51cCgpOwogICAgICAgICAgaWYgKCFmaW5pc2hlZCkgewogICAgICAgICAgICBvYnNlcnZlci5lcnJvcihuZXcgSHR0cEVycm9yUmVzcG9uc2UoewogICAgICAgICAgICAgIHVybCwKICAgICAgICAgICAgICBzdGF0dXM6IDAsCiAgICAgICAgICAgICAgc3RhdHVzVGV4dDogIkpTT05QIEVycm9yIiwKICAgICAgICAgICAgICBlcnJvcjogbmV3IEVycm9yKEpTT05QX0VSUl9OT19DQUxMQkFDSykKICAgICAgICAgICAgfSkpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgICB9CiAgICAgICAgICBvYnNlcnZlci5uZXh0KG5ldyBIdHRwUmVzcG9uc2UoewogICAgICAgICAgICBib2R5LAogICAgICAgICAgICBzdGF0dXM6IEhUVFBfU1RBVFVTX0NPREVfT0ssCiAgICAgICAgICAgIHN0YXR1c1RleHQ6ICJPSyIsCiAgICAgICAgICAgIHVybAogICAgICAgICAgfSkpOwogICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGUoKTsKICAgICAgICB9KTsKICAgICAgfTsKICAgICAgY29uc3Qgb25FcnJvciA9IChlcnJvcikgPT4gewogICAgICAgIGNsZWFudXAoKTsKICAgICAgICBvYnNlcnZlci5lcnJvcihuZXcgSHR0cEVycm9yUmVzcG9uc2UoewogICAgICAgICAgZXJyb3IsCiAgICAgICAgICBzdGF0dXM6IDAsCiAgICAgICAgICBzdGF0dXNUZXh0OiAiSlNPTlAgRXJyb3IiLAogICAgICAgICAgdXJsCiAgICAgICAgfSkpOwogICAgICB9OwogICAgICBub2RlLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLCBvbkxvYWQpOwogICAgICBub2RlLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgb25FcnJvcik7CiAgICAgIHRoaXMuZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChub2RlKTsKICAgICAgb2JzZXJ2ZXIubmV4dCh7CiAgICAgICAgdHlwZTogSHR0cEV2ZW50VHlwZS5TZW50CiAgICAgIH0pOwogICAgICByZXR1cm4gKCkgPT4gewogICAgICAgIGlmICghZmluaXNoZWQpIHsKICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXJzKG5vZGUpOwogICAgICAgIH0KICAgICAgICBjbGVhbnVwKCk7CiAgICAgIH07CiAgICB9KTsKICB9CiAgcmVtb3ZlTGlzdGVuZXJzKHNjcmlwdCkgewogICAgZm9yZWlnbkRvY3VtZW50ID8/PSB0aGlzLmRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCgpOwogICAgZm9yZWlnbkRvY3VtZW50LmFkb3B0Tm9kZShzY3JpcHQpOwogIH0KfTsKX0pzb25wQ2xpZW50QmFja2VuZC7JtWZhYyA9IGZ1bmN0aW9uIEpzb25wQ2xpZW50QmFja2VuZF9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9Kc29ucENsaWVudEJhY2tlbmQpKMm1ybVpbmplY3QoSnNvbnBDYWxsYmFja0NvbnRleHQpLCDJtcm1aW5qZWN0KERPQ1VNRU5UKSk7Cn07Cl9Kc29ucENsaWVudEJhY2tlbmQuybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfSnNvbnBDbGllbnRCYWNrZW5kLAogIGZhY3Rvcnk6IF9Kc29ucENsaWVudEJhY2tlbmQuybVmYWMKfSk7CnZhciBKc29ucENsaWVudEJhY2tlbmQgPSBfSnNvbnBDbGllbnRCYWNrZW5kOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoSnNvbnBDbGllbnRCYWNrZW5kLCBbewogICAgdHlwZTogSW5qZWN0YWJsZQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogSnNvbnBDYWxsYmFja0NvbnRleHQKICB9LCB7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtET0NVTUVOVF0KICAgIH1dCiAgfV0sIG51bGwpOwp9KSgpOwpmdW5jdGlvbiBqc29ucEludGVyY2VwdG9yRm4ocmVxLCBuZXh0KSB7CiAgaWYgKHJlcS5tZXRob2QgPT09ICJKU09OUCIpIHsKICAgIHJldHVybiBpbmplY3QoSnNvbnBDbGllbnRCYWNrZW5kKS5oYW5kbGUocmVxKTsKICB9CiAgcmV0dXJuIG5leHQocmVxKTsKfQp2YXIgX0pzb25wSW50ZXJjZXB0b3IgPSBjbGFzcyBfSnNvbnBJbnRlcmNlcHRvciB7CiAgY29uc3RydWN0b3IoaW5qZWN0b3IpIHsKICAgIHRoaXMuaW5qZWN0b3IgPSBpbmplY3RvcjsKICB9CiAgLyoqCiAgICogSWRlbnRpZmllcyBhbmQgaGFuZGxlcyBhIGdpdmVuIEpTT05QIHJlcXVlc3QuCiAgICogQHBhcmFtIGluaXRpYWxSZXF1ZXN0IFRoZSBvdXRnb2luZyByZXF1ZXN0IG9iamVjdCB0byBoYW5kbGUuCiAgICogQHBhcmFtIG5leHQgVGhlIG5leHQgaW50ZXJjZXB0b3IgaW4gdGhlIGNoYWluLCBvciB0aGUgYmFja2VuZAogICAqIGlmIG5vIGludGVyY2VwdG9ycyByZW1haW4gaW4gdGhlIGNoYWluLgogICAqIEByZXR1cm5zIEFuIG9ic2VydmFibGUgb2YgdGhlIGV2ZW50IHN0cmVhbS4KICAgKi8KICBpbnRlcmNlcHQoaW5pdGlhbFJlcXVlc3QsIG5leHQpIHsKICAgIHJldHVybiBydW5JbkluamVjdGlvbkNvbnRleHQodGhpcy5pbmplY3RvciwgKCkgPT4ganNvbnBJbnRlcmNlcHRvckZuKGluaXRpYWxSZXF1ZXN0LCAoZG93bnN0cmVhbVJlcXVlc3QpID0+IG5leHQuaGFuZGxlKGRvd25zdHJlYW1SZXF1ZXN0KSkpOwogIH0KfTsKX0pzb25wSW50ZXJjZXB0b3IuybVmYWMgPSBmdW5jdGlvbiBKc29ucEludGVyY2VwdG9yX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0pzb25wSW50ZXJjZXB0b3IpKMm1ybVpbmplY3QoRW52aXJvbm1lbnRJbmplY3RvcikpOwp9OwpfSnNvbnBJbnRlcmNlcHRvci7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7CiAgdG9rZW46IF9Kc29ucEludGVyY2VwdG9yLAogIGZhY3Rvcnk6IF9Kc29ucEludGVyY2VwdG9yLsm1ZmFjCn0pOwp2YXIgSnNvbnBJbnRlcmNlcHRvciA9IF9Kc29ucEludGVyY2VwdG9yOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoSnNvbnBJbnRlcmNlcHRvciwgW3sKICAgIHR5cGU6IEluamVjdGFibGUKICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IEVudmlyb25tZW50SW5qZWN0b3IKICB9XSwgbnVsbCk7Cn0pKCk7CnZhciBYU1NJX1BSRUZJWCA9IC9eXClcXVx9Jyw/XG4vOwpmdW5jdGlvbiBnZXRSZXNwb25zZVVybCh4aHIpIHsKICBpZiAoInJlc3BvbnNlVVJMIiBpbiB4aHIgJiYgeGhyLnJlc3BvbnNlVVJMKSB7CiAgICByZXR1cm4geGhyLnJlc3BvbnNlVVJMOwogIH0KICBpZiAoL15YLVJlcXVlc3QtVVJMOi9tLnRlc3QoeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKSkgewogICAgcmV0dXJuIHhoci5nZXRSZXNwb25zZUhlYWRlcigiWC1SZXF1ZXN0LVVSTCIpOwogIH0KICByZXR1cm4gbnVsbDsKfQp2YXIgX0h0dHBYaHJCYWNrZW5kID0gY2xhc3MgX0h0dHBYaHJCYWNrZW5kIHsKICBjb25zdHJ1Y3Rvcih4aHJGYWN0b3J5KSB7CiAgICB0aGlzLnhockZhY3RvcnkgPSB4aHJGYWN0b3J5OwogIH0KICAvKioKICAgKiBQcm9jZXNzZXMgYSByZXF1ZXN0IGFuZCByZXR1cm5zIGEgc3RyZWFtIG9mIHJlc3BvbnNlIGV2ZW50cy4KICAgKiBAcGFyYW0gcmVxIFRoZSByZXF1ZXN0IG9iamVjdC4KICAgKiBAcmV0dXJucyBBbiBvYnNlcnZhYmxlIG9mIHRoZSByZXNwb25zZSBldmVudHMuCiAgICovCiAgaGFuZGxlKHJlcSkgewogICAgaWYgKHJlcS5tZXRob2QgPT09ICJKU09OUCIpIHsKICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigtMjgwMCwgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgYENhbm5vdCBtYWtlIGEgSlNPTlAgcmVxdWVzdCB3aXRob3V0IEpTT05QIHN1cHBvcnQuIFRvIGZpeCB0aGUgcHJvYmxlbSwgZWl0aGVyIGFkZCB0aGUgXGB3aXRoSnNvbnBTdXBwb3J0KClcYCBjYWxsIChpZiBcYHByb3ZpZGVIdHRwQ2xpZW50KClcYCBpcyB1c2VkKSBvciBpbXBvcnQgdGhlIFxgSHR0cENsaWVudEpzb25wTW9kdWxlXGAgaW4gdGhlIHJvb3QgTmdNb2R1bGUuYCk7CiAgICB9CiAgICBjb25zdCB4aHJGYWN0b3J5ID0gdGhpcy54aHJGYWN0b3J5OwogICAgY29uc3Qgc291cmNlID0geGhyRmFjdG9yeS7JtWxvYWRJbXBsID8gZnJvbSh4aHJGYWN0b3J5Lsm1bG9hZEltcGwoKSkgOiBvZihudWxsKTsKICAgIHJldHVybiBzb3VyY2UucGlwZShzd2l0Y2hNYXAoKCkgPT4gewogICAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoKG9ic2VydmVyKSA9PiB7CiAgICAgICAgY29uc3QgeGhyID0geGhyRmFjdG9yeS5idWlsZCgpOwogICAgICAgIHhoci5vcGVuKHJlcS5tZXRob2QsIHJlcS51cmxXaXRoUGFyYW1zKTsKICAgICAgICBpZiAocmVxLndpdGhDcmVkZW50aWFscykgewogICAgICAgICAgeGhyLndpdGhDcmVkZW50aWFscyA9IHRydWU7CiAgICAgICAgfQogICAgICAgIHJlcS5oZWFkZXJzLmZvckVhY2goKG5hbWUsIHZhbHVlcykgPT4geGhyLnNldFJlcXVlc3RIZWFkZXIobmFtZSwgdmFsdWVzLmpvaW4oIiwiKSkpOwogICAgICAgIGlmICghcmVxLmhlYWRlcnMuaGFzKCJBY2NlcHQiKSkgewogICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoIkFjY2VwdCIsICJhcHBsaWNhdGlvbi9qc29uLCB0ZXh0L3BsYWluLCAqLyoiKTsKICAgICAgICB9CiAgICAgICAgaWYgKCFyZXEuaGVhZGVycy5oYXMoIkNvbnRlbnQtVHlwZSIpKSB7CiAgICAgICAgICBjb25zdCBkZXRlY3RlZFR5cGUgPSByZXEuZGV0ZWN0Q29udGVudFR5cGVIZWFkZXIoKTsKICAgICAgICAgIGlmIChkZXRlY3RlZFR5cGUgIT09IG51bGwpIHsKICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsIGRldGVjdGVkVHlwZSk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGlmIChyZXEucmVzcG9uc2VUeXBlKSB7CiAgICAgICAgICBjb25zdCByZXNwb25zZVR5cGUgPSByZXEucmVzcG9uc2VUeXBlLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgICB4aHIucmVzcG9uc2VUeXBlID0gcmVzcG9uc2VUeXBlICE9PSAianNvbiIgPyByZXNwb25zZVR5cGUgOiAidGV4dCI7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHJlcUJvZHkgPSByZXEuc2VyaWFsaXplQm9keSgpOwogICAgICAgIGxldCBoZWFkZXJSZXNwb25zZSA9IG51bGw7CiAgICAgICAgY29uc3QgcGFydGlhbEZyb21YaHIgPSAoKSA9PiB7CiAgICAgICAgICBpZiAoaGVhZGVyUmVzcG9uc2UgIT09IG51bGwpIHsKICAgICAgICAgICAgcmV0dXJuIGhlYWRlclJlc3BvbnNlOwogICAgICAgICAgfQogICAgICAgICAgY29uc3Qgc3RhdHVzVGV4dCA9IHhoci5zdGF0dXNUZXh0IHx8ICJPSyI7CiAgICAgICAgICBjb25zdCBoZWFkZXJzID0gbmV3IEh0dHBIZWFkZXJzKHhoci5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSk7CiAgICAgICAgICBjb25zdCB1cmwgPSBnZXRSZXNwb25zZVVybCh4aHIpIHx8IHJlcS51cmw7CiAgICAgICAgICBoZWFkZXJSZXNwb25zZSA9IG5ldyBIdHRwSGVhZGVyUmVzcG9uc2UoewogICAgICAgICAgICBoZWFkZXJzLAogICAgICAgICAgICBzdGF0dXM6IHhoci5zdGF0dXMsCiAgICAgICAgICAgIHN0YXR1c1RleHQsCiAgICAgICAgICAgIHVybAogICAgICAgICAgfSk7CiAgICAgICAgICByZXR1cm4gaGVhZGVyUmVzcG9uc2U7CiAgICAgICAgfTsKICAgICAgICBjb25zdCBvbkxvYWQgPSAoKSA9PiB7CiAgICAgICAgICBsZXQgewogICAgICAgICAgICBoZWFkZXJzLAogICAgICAgICAgICBzdGF0dXMsCiAgICAgICAgICAgIHN0YXR1c1RleHQsCiAgICAgICAgICAgIHVybAogICAgICAgICAgfSA9IHBhcnRpYWxGcm9tWGhyKCk7CiAgICAgICAgICBsZXQgYm9keSA9IG51bGw7CiAgICAgICAgICBpZiAoc3RhdHVzICE9PSBIVFRQX1NUQVRVU19DT0RFX05PX0NPTlRFTlQpIHsKICAgICAgICAgICAgYm9keSA9IHR5cGVvZiB4aHIucmVzcG9uc2UgPT09ICJ1bmRlZmluZWQiID8geGhyLnJlc3BvbnNlVGV4dCA6IHhoci5yZXNwb25zZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChzdGF0dXMgPT09IDApIHsKICAgICAgICAgICAgc3RhdHVzID0gISFib2R5ID8gSFRUUF9TVEFUVVNfQ09ERV9PSyA6IDA7CiAgICAgICAgICB9CiAgICAgICAgICBsZXQgb2sgPSBzdGF0dXMgPj0gMjAwICYmIHN0YXR1cyA8IDMwMDsKICAgICAgICAgIGlmIChyZXEucmVzcG9uc2VUeXBlID09PSAianNvbiIgJiYgdHlwZW9mIGJvZHkgPT09ICJzdHJpbmciKSB7CiAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsQm9keSA9IGJvZHk7CiAgICAgICAgICAgIGJvZHkgPSBib2R5LnJlcGxhY2UoWFNTSV9QUkVGSVgsICIiKTsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICBib2R5ID0gYm9keSAhPT0gIiIgPyBKU09OLnBhcnNlKGJvZHkpIDogbnVsbDsKICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgICAgICBib2R5ID0gb3JpZ2luYWxCb2R5OwogICAgICAgICAgICAgIGlmIChvaykgewogICAgICAgICAgICAgICAgb2sgPSBmYWxzZTsKICAgICAgICAgICAgICAgIGJvZHkgPSB7CiAgICAgICAgICAgICAgICAgIGVycm9yLAogICAgICAgICAgICAgICAgICB0ZXh0OiBib2R5CiAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgaWYgKG9rKSB7CiAgICAgICAgICAgIG9ic2VydmVyLm5leHQobmV3IEh0dHBSZXNwb25zZSh7CiAgICAgICAgICAgICAgYm9keSwKICAgICAgICAgICAgICBoZWFkZXJzLAogICAgICAgICAgICAgIHN0YXR1cywKICAgICAgICAgICAgICBzdGF0dXNUZXh0LAogICAgICAgICAgICAgIHVybDogdXJsIHx8IHZvaWQgMAogICAgICAgICAgICB9KSk7CiAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBvYnNlcnZlci5lcnJvcihuZXcgSHR0cEVycm9yUmVzcG9uc2UoewogICAgICAgICAgICAgIC8vIFRoZSBlcnJvciBpbiB0aGlzIGNhc2UgaXMgdGhlIHJlc3BvbnNlIGJvZHkgKGVycm9yIGZyb20gdGhlIHNlcnZlcikuCiAgICAgICAgICAgICAgZXJyb3I6IGJvZHksCiAgICAgICAgICAgICAgaGVhZGVycywKICAgICAgICAgICAgICBzdGF0dXMsCiAgICAgICAgICAgICAgc3RhdHVzVGV4dCwKICAgICAgICAgICAgICB1cmw6IHVybCB8fCB2b2lkIDAKICAgICAgICAgICAgfSkpOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgY29uc3Qgb25FcnJvciA9IChlcnJvcikgPT4gewogICAgICAgICAgY29uc3QgewogICAgICAgICAgICB1cmwKICAgICAgICAgIH0gPSBwYXJ0aWFsRnJvbVhocigpOwogICAgICAgICAgY29uc3QgcmVzID0gbmV3IEh0dHBFcnJvclJlc3BvbnNlKHsKICAgICAgICAgICAgZXJyb3IsCiAgICAgICAgICAgIHN0YXR1czogeGhyLnN0YXR1cyB8fCAwLAogICAgICAgICAgICBzdGF0dXNUZXh0OiB4aHIuc3RhdHVzVGV4dCB8fCAiVW5rbm93biBFcnJvciIsCiAgICAgICAgICAgIHVybDogdXJsIHx8IHZvaWQgMAogICAgICAgICAgfSk7CiAgICAgICAgICBvYnNlcnZlci5lcnJvcihyZXMpOwogICAgICAgIH07CiAgICAgICAgbGV0IHNlbnRIZWFkZXJzID0gZmFsc2U7CiAgICAgICAgY29uc3Qgb25Eb3duUHJvZ3Jlc3MgPSAoZXZlbnQpID0+IHsKICAgICAgICAgIGlmICghc2VudEhlYWRlcnMpIHsKICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChwYXJ0aWFsRnJvbVhocigpKTsKICAgICAgICAgICAgc2VudEhlYWRlcnMgPSB0cnVlOwogICAgICAgICAgfQogICAgICAgICAgbGV0IHByb2dyZXNzRXZlbnQgPSB7CiAgICAgICAgICAgIHR5cGU6IEh0dHBFdmVudFR5cGUuRG93bmxvYWRQcm9ncmVzcywKICAgICAgICAgICAgbG9hZGVkOiBldmVudC5sb2FkZWQKICAgICAgICAgIH07CiAgICAgICAgICBpZiAoZXZlbnQubGVuZ3RoQ29tcHV0YWJsZSkgewogICAgICAgICAgICBwcm9ncmVzc0V2ZW50LnRvdGFsID0gZXZlbnQudG90YWw7CiAgICAgICAgICB9CiAgICAgICAgICBpZiAocmVxLnJlc3BvbnNlVHlwZSA9PT0gInRleHQiICYmICEheGhyLnJlc3BvbnNlVGV4dCkgewogICAgICAgICAgICBwcm9ncmVzc0V2ZW50LnBhcnRpYWxUZXh0ID0geGhyLnJlc3BvbnNlVGV4dDsKICAgICAgICAgIH0KICAgICAgICAgIG9ic2VydmVyLm5leHQocHJvZ3Jlc3NFdmVudCk7CiAgICAgICAgfTsKICAgICAgICBjb25zdCBvblVwUHJvZ3Jlc3MgPSAoZXZlbnQpID0+IHsKICAgICAgICAgIGxldCBwcm9ncmVzcyA9IHsKICAgICAgICAgICAgdHlwZTogSHR0cEV2ZW50VHlwZS5VcGxvYWRQcm9ncmVzcywKICAgICAgICAgICAgbG9hZGVkOiBldmVudC5sb2FkZWQKICAgICAgICAgIH07CiAgICAgICAgICBpZiAoZXZlbnQubGVuZ3RoQ29tcHV0YWJsZSkgewogICAgICAgICAgICBwcm9ncmVzcy50b3RhbCA9IGV2ZW50LnRvdGFsOwogICAgICAgICAgfQogICAgICAgICAgb2JzZXJ2ZXIubmV4dChwcm9ncmVzcyk7CiAgICAgICAgfTsKICAgICAgICB4aHIuYWRkRXZlbnRMaXN0ZW5lcigibG9hZCIsIG9uTG9hZCk7CiAgICAgICAgeGhyLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgb25FcnJvcik7CiAgICAgICAgeGhyLmFkZEV2ZW50TGlzdGVuZXIoInRpbWVvdXQiLCBvbkVycm9yKTsKICAgICAgICB4aHIuYWRkRXZlbnRMaXN0ZW5lcigiYWJvcnQiLCBvbkVycm9yKTsKICAgICAgICBpZiAocmVxLnJlcG9ydFByb2dyZXNzKSB7CiAgICAgICAgICB4aHIuYWRkRXZlbnRMaXN0ZW5lcigicHJvZ3Jlc3MiLCBvbkRvd25Qcm9ncmVzcyk7CiAgICAgICAgICBpZiAocmVxQm9keSAhPT0gbnVsbCAmJiB4aHIudXBsb2FkKSB7CiAgICAgICAgICAgIHhoci51cGxvYWQuYWRkRXZlbnRMaXN0ZW5lcigicHJvZ3Jlc3MiLCBvblVwUHJvZ3Jlc3MpOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICB4aHIuc2VuZChyZXFCb2R5KTsKICAgICAgICBvYnNlcnZlci5uZXh0KHsKICAgICAgICAgIHR5cGU6IEh0dHBFdmVudFR5cGUuU2VudAogICAgICAgIH0pOwogICAgICAgIHJldHVybiAoKSA9PiB7CiAgICAgICAgICB4aHIucmVtb3ZlRXZlbnRMaXN0ZW5lcigiZXJyb3IiLCBvbkVycm9yKTsKICAgICAgICAgIHhoci5yZW1vdmVFdmVudExpc3RlbmVyKCJhYm9ydCIsIG9uRXJyb3IpOwogICAgICAgICAgeGhyLnJlbW92ZUV2ZW50TGlzdGVuZXIoImxvYWQiLCBvbkxvYWQpOwogICAgICAgICAgeGhyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInRpbWVvdXQiLCBvbkVycm9yKTsKICAgICAgICAgIGlmIChyZXEucmVwb3J0UHJvZ3Jlc3MpIHsKICAgICAgICAgICAgeGhyLnJlbW92ZUV2ZW50TGlzdGVuZXIoInByb2dyZXNzIiwgb25Eb3duUHJvZ3Jlc3MpOwogICAgICAgICAgICBpZiAocmVxQm9keSAhPT0gbnVsbCAmJiB4aHIudXBsb2FkKSB7CiAgICAgICAgICAgICAgeGhyLnVwbG9hZC5yZW1vdmVFdmVudExpc3RlbmVyKCJwcm9ncmVzcyIsIG9uVXBQcm9ncmVzcyk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGlmICh4aHIucmVhZHlTdGF0ZSAhPT0geGhyLkRPTkUpIHsKICAgICAgICAgICAgeGhyLmFib3J0KCk7CiAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgfSk7CiAgICB9KSk7CiAgfQp9OwpfSHR0cFhockJhY2tlbmQuybVmYWMgPSBmdW5jdGlvbiBIdHRwWGhyQmFja2VuZF9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9IdHRwWGhyQmFja2VuZCkoybXJtWluamVjdChYaHJGYWN0b3J5KSk7Cn07Cl9IdHRwWGhyQmFja2VuZC7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7CiAgdG9rZW46IF9IdHRwWGhyQmFja2VuZCwKICBmYWN0b3J5OiBfSHR0cFhockJhY2tlbmQuybVmYWMKfSk7CnZhciBIdHRwWGhyQmFja2VuZCA9IF9IdHRwWGhyQmFja2VuZDsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKEh0dHBYaHJCYWNrZW5kLCBbewogICAgdHlwZTogSW5qZWN0YWJsZQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogWGhyRmFjdG9yeQogIH1dLCBudWxsKTsKfSkoKTsKdmFyIFhTUkZfRU5BQkxFRCA9IG5ldyBJbmplY3Rpb25Ub2tlbihuZ0Rldk1vZGUgPyAiWFNSRl9FTkFCTEVEIiA6ICIiKTsKdmFyIFhTUkZfREVGQVVMVF9DT09LSUVfTkFNRSA9ICJYU1JGLVRPS0VOIjsKdmFyIFhTUkZfQ09PS0lFX05BTUUgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gIlhTUkZfQ09PS0lFX05BTUUiIDogIiIsIHsKICBwcm92aWRlZEluOiAicm9vdCIsCiAgZmFjdG9yeTogKCkgPT4gWFNSRl9ERUZBVUxUX0NPT0tJRV9OQU1FCn0pOwp2YXIgWFNSRl9ERUZBVUxUX0hFQURFUl9OQU1FID0gIlgtWFNSRi1UT0tFTiI7CnZhciBYU1JGX0hFQURFUl9OQU1FID0gbmV3IEluamVjdGlvblRva2VuKG5nRGV2TW9kZSA/ICJYU1JGX0hFQURFUl9OQU1FIiA6ICIiLCB7CiAgcHJvdmlkZWRJbjogInJvb3QiLAogIGZhY3Rvcnk6ICgpID0+IFhTUkZfREVGQVVMVF9IRUFERVJfTkFNRQp9KTsKdmFyIEh0dHBYc3JmVG9rZW5FeHRyYWN0b3IgPSBjbGFzcyB7Cn07CnZhciBfSHR0cFhzcmZDb29raWVFeHRyYWN0b3IgPSBjbGFzcyBfSHR0cFhzcmZDb29raWVFeHRyYWN0b3IgewogIGNvbnN0cnVjdG9yKGRvYywgcGxhdGZvcm0sIGNvb2tpZU5hbWUpIHsKICAgIHRoaXMuZG9jID0gZG9jOwogICAgdGhpcy5wbGF0Zm9ybSA9IHBsYXRmb3JtOwogICAgdGhpcy5jb29raWVOYW1lID0gY29va2llTmFtZTsKICAgIHRoaXMubGFzdENvb2tpZVN0cmluZyA9ICIiOwogICAgdGhpcy5sYXN0VG9rZW4gPSBudWxsOwogICAgdGhpcy5wYXJzZUNvdW50ID0gMDsKICB9CiAgZ2V0VG9rZW4oKSB7CiAgICBpZiAodGhpcy5wbGF0Zm9ybSA9PT0gInNlcnZlciIpIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBjb25zdCBjb29raWVTdHJpbmcgPSB0aGlzLmRvYy5jb29raWUgfHwgIiI7CiAgICBpZiAoY29va2llU3RyaW5nICE9PSB0aGlzLmxhc3RDb29raWVTdHJpbmcpIHsKICAgICAgdGhpcy5wYXJzZUNvdW50Kys7CiAgICAgIHRoaXMubGFzdFRva2VuID0gcGFyc2VDb29raWVWYWx1ZShjb29raWVTdHJpbmcsIHRoaXMuY29va2llTmFtZSk7CiAgICAgIHRoaXMubGFzdENvb2tpZVN0cmluZyA9IGNvb2tpZVN0cmluZzsKICAgIH0KICAgIHJldHVybiB0aGlzLmxhc3RUb2tlbjsKICB9Cn07Cl9IdHRwWHNyZkNvb2tpZUV4dHJhY3Rvci7JtWZhYyA9IGZ1bmN0aW9uIEh0dHBYc3JmQ29va2llRXh0cmFjdG9yX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0h0dHBYc3JmQ29va2llRXh0cmFjdG9yKSjJtcm1aW5qZWN0KERPQ1VNRU5UKSwgybXJtWluamVjdChQTEFURk9STV9JRCksIMm1ybVpbmplY3QoWFNSRl9DT09LSUVfTkFNRSkpOwp9OwpfSHR0cFhzcmZDb29raWVFeHRyYWN0b3IuybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfSHR0cFhzcmZDb29raWVFeHRyYWN0b3IsCiAgZmFjdG9yeTogX0h0dHBYc3JmQ29va2llRXh0cmFjdG9yLsm1ZmFjCn0pOwp2YXIgSHR0cFhzcmZDb29raWVFeHRyYWN0b3IgPSBfSHR0cFhzcmZDb29raWVFeHRyYWN0b3I7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShIdHRwWHNyZkNvb2tpZUV4dHJhY3RvciwgW3sKICAgIHR5cGU6IEluamVjdGFibGUKICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IHZvaWQgMCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0RPQ1VNRU5UXQogICAgfV0KICB9LCB7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtQTEFURk9STV9JRF0KICAgIH1dCiAgfSwgewogICAgdHlwZTogdm9pZCAwLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogSW5qZWN0LAogICAgICBhcmdzOiBbWFNSRl9DT09LSUVfTkFNRV0KICAgIH1dCiAgfV0sIG51bGwpOwp9KSgpOwpmdW5jdGlvbiB4c3JmSW50ZXJjZXB0b3JGbihyZXEsIG5leHQpIHsKICBjb25zdCBsY1VybCA9IHJlcS51cmwudG9Mb3dlckNhc2UoKTsKICBpZiAoIWluamVjdChYU1JGX0VOQUJMRUQpIHx8IHJlcS5tZXRob2QgPT09ICJHRVQiIHx8IHJlcS5tZXRob2QgPT09ICJIRUFEIiB8fCBsY1VybC5zdGFydHNXaXRoKCJodHRwOi8vIikgfHwgbGNVcmwuc3RhcnRzV2l0aCgiaHR0cHM6Ly8iKSkgewogICAgcmV0dXJuIG5leHQocmVxKTsKICB9CiAgY29uc3QgdG9rZW4gPSBpbmplY3QoSHR0cFhzcmZUb2tlbkV4dHJhY3RvcikuZ2V0VG9rZW4oKTsKICBjb25zdCBoZWFkZXJOYW1lID0gaW5qZWN0KFhTUkZfSEVBREVSX05BTUUpOwogIGlmICh0b2tlbiAhPSBudWxsICYmICFyZXEuaGVhZGVycy5oYXMoaGVhZGVyTmFtZSkpIHsKICAgIHJlcSA9IHJlcS5jbG9uZSh7CiAgICAgIGhlYWRlcnM6IHJlcS5oZWFkZXJzLnNldChoZWFkZXJOYW1lLCB0b2tlbikKICAgIH0pOwogIH0KICByZXR1cm4gbmV4dChyZXEpOwp9CnZhciBfSHR0cFhzcmZJbnRlcmNlcHRvciA9IGNsYXNzIF9IdHRwWHNyZkludGVyY2VwdG9yIHsKICBjb25zdHJ1Y3RvcihpbmplY3RvcikgewogICAgdGhpcy5pbmplY3RvciA9IGluamVjdG9yOwogIH0KICBpbnRlcmNlcHQoaW5pdGlhbFJlcXVlc3QsIG5leHQpIHsKICAgIHJldHVybiBydW5JbkluamVjdGlvbkNvbnRleHQodGhpcy5pbmplY3RvciwgKCkgPT4geHNyZkludGVyY2VwdG9yRm4oaW5pdGlhbFJlcXVlc3QsIChkb3duc3RyZWFtUmVxdWVzdCkgPT4gbmV4dC5oYW5kbGUoZG93bnN0cmVhbVJlcXVlc3QpKSk7CiAgfQp9OwpfSHR0cFhzcmZJbnRlcmNlcHRvci7JtWZhYyA9IGZ1bmN0aW9uIEh0dHBYc3JmSW50ZXJjZXB0b3JfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfSHR0cFhzcmZJbnRlcmNlcHRvcikoybXJtWluamVjdChFbnZpcm9ubWVudEluamVjdG9yKSk7Cn07Cl9IdHRwWHNyZkludGVyY2VwdG9yLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX0h0dHBYc3JmSW50ZXJjZXB0b3IsCiAgZmFjdG9yeTogX0h0dHBYc3JmSW50ZXJjZXB0b3IuybVmYWMKfSk7CnZhciBIdHRwWHNyZkludGVyY2VwdG9yID0gX0h0dHBYc3JmSW50ZXJjZXB0b3I7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShIdHRwWHNyZkludGVyY2VwdG9yLCBbewogICAgdHlwZTogSW5qZWN0YWJsZQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogRW52aXJvbm1lbnRJbmplY3RvcgogIH1dLCBudWxsKTsKfSkoKTsKdmFyIEh0dHBGZWF0dXJlS2luZDsKKGZ1bmN0aW9uKEh0dHBGZWF0dXJlS2luZDIpIHsKICBIdHRwRmVhdHVyZUtpbmQyW0h0dHBGZWF0dXJlS2luZDJbIkludGVyY2VwdG9ycyJdID0gMF0gPSAiSW50ZXJjZXB0b3JzIjsKICBIdHRwRmVhdHVyZUtpbmQyW0h0dHBGZWF0dXJlS2luZDJbIkxlZ2FjeUludGVyY2VwdG9ycyJdID0gMV0gPSAiTGVnYWN5SW50ZXJjZXB0b3JzIjsKICBIdHRwRmVhdHVyZUtpbmQyW0h0dHBGZWF0dXJlS2luZDJbIkN1c3RvbVhzcmZDb25maWd1cmF0aW9uIl0gPSAyXSA9ICJDdXN0b21Yc3JmQ29uZmlndXJhdGlvbiI7CiAgSHR0cEZlYXR1cmVLaW5kMltIdHRwRmVhdHVyZUtpbmQyWyJOb1hzcmZQcm90ZWN0aW9uIl0gPSAzXSA9ICJOb1hzcmZQcm90ZWN0aW9uIjsKICBIdHRwRmVhdHVyZUtpbmQyW0h0dHBGZWF0dXJlS2luZDJbIkpzb25wU3VwcG9ydCJdID0gNF0gPSAiSnNvbnBTdXBwb3J0IjsKICBIdHRwRmVhdHVyZUtpbmQyW0h0dHBGZWF0dXJlS2luZDJbIlJlcXVlc3RzTWFkZVZpYVBhcmVudCJdID0gNV0gPSAiUmVxdWVzdHNNYWRlVmlhUGFyZW50IjsKICBIdHRwRmVhdHVyZUtpbmQyW0h0dHBGZWF0dXJlS2luZDJbIkZldGNoIl0gPSA2XSA9ICJGZXRjaCI7Cn0pKEh0dHBGZWF0dXJlS2luZCB8fCAoSHR0cEZlYXR1cmVLaW5kID0ge30pKTsKZnVuY3Rpb24gbWFrZUh0dHBGZWF0dXJlKGtpbmQsIHByb3ZpZGVycykgewogIHJldHVybiB7CiAgICDJtWtpbmQ6IGtpbmQsCiAgICDJtXByb3ZpZGVyczogcHJvdmlkZXJzCiAgfTsKfQpmdW5jdGlvbiBwcm92aWRlSHR0cENsaWVudCguLi5mZWF0dXJlcykgewogIGlmIChuZ0Rldk1vZGUpIHsKICAgIGNvbnN0IGZlYXR1cmVLaW5kcyA9IG5ldyBTZXQoZmVhdHVyZXMubWFwKChmKSA9PiBmLsm1a2luZCkpOwogICAgaWYgKGZlYXR1cmVLaW5kcy5oYXMoSHR0cEZlYXR1cmVLaW5kLk5vWHNyZlByb3RlY3Rpb24pICYmIGZlYXR1cmVLaW5kcy5oYXMoSHR0cEZlYXR1cmVLaW5kLkN1c3RvbVhzcmZDb25maWd1cmF0aW9uKSkgewogICAgICB0aHJvdyBuZXcgRXJyb3IobmdEZXZNb2RlID8gYENvbmZpZ3VyYXRpb24gZXJyb3I6IGZvdW5kIGJvdGggd2l0aFhzcmZDb25maWd1cmF0aW9uKCkgYW5kIHdpdGhOb1hzcmZQcm90ZWN0aW9uKCkgaW4gdGhlIHNhbWUgY2FsbCB0byBwcm92aWRlSHR0cENsaWVudCgpLCB3aGljaCBpcyBhIGNvbnRyYWRpY3Rpb24uYCA6ICIiKTsKICAgIH0KICB9CiAgY29uc3QgcHJvdmlkZXJzID0gW0h0dHBDbGllbnQsIEh0dHBYaHJCYWNrZW5kLCBIdHRwSW50ZXJjZXB0b3JIYW5kbGVyLCB7CiAgICBwcm92aWRlOiBIdHRwSGFuZGxlciwKICAgIHVzZUV4aXN0aW5nOiBIdHRwSW50ZXJjZXB0b3JIYW5kbGVyCiAgfSwgewogICAgcHJvdmlkZTogSHR0cEJhY2tlbmQsCiAgICB1c2VGYWN0b3J5OiAoKSA9PiB7CiAgICAgIHJldHVybiBpbmplY3QoRmV0Y2hCYWNrZW5kLCB7CiAgICAgICAgb3B0aW9uYWw6IHRydWUKICAgICAgfSkgPz8gaW5qZWN0KEh0dHBYaHJCYWNrZW5kKTsKICAgIH0KICB9LCB7CiAgICBwcm92aWRlOiBIVFRQX0lOVEVSQ0VQVE9SX0ZOUywKICAgIHVzZVZhbHVlOiB4c3JmSW50ZXJjZXB0b3JGbiwKICAgIG11bHRpOiB0cnVlCiAgfSwgewogICAgcHJvdmlkZTogWFNSRl9FTkFCTEVELAogICAgdXNlVmFsdWU6IHRydWUKICB9LCB7CiAgICBwcm92aWRlOiBIdHRwWHNyZlRva2VuRXh0cmFjdG9yLAogICAgdXNlQ2xhc3M6IEh0dHBYc3JmQ29va2llRXh0cmFjdG9yCiAgfV07CiAgZm9yIChjb25zdCBmZWF0dXJlIG9mIGZlYXR1cmVzKSB7CiAgICBwcm92aWRlcnMucHVzaCguLi5mZWF0dXJlLsm1cHJvdmlkZXJzKTsKICB9CiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhwcm92aWRlcnMpOwp9CnZhciBMRUdBQ1lfSU5URVJDRVBUT1JfRk4gPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gIkxFR0FDWV9JTlRFUkNFUFRPUl9GTiIgOiAiIik7CmZ1bmN0aW9uIHdpdGhJbnRlcmNlcHRvcnNGcm9tRGkoKSB7CiAgcmV0dXJuIG1ha2VIdHRwRmVhdHVyZShIdHRwRmVhdHVyZUtpbmQuTGVnYWN5SW50ZXJjZXB0b3JzLCBbewogICAgcHJvdmlkZTogTEVHQUNZX0lOVEVSQ0VQVE9SX0ZOLAogICAgdXNlRmFjdG9yeTogbGVnYWN5SW50ZXJjZXB0b3JGbkZhY3RvcnkKICB9LCB7CiAgICBwcm92aWRlOiBIVFRQX0lOVEVSQ0VQVE9SX0ZOUywKICAgIHVzZUV4aXN0aW5nOiBMRUdBQ1lfSU5URVJDRVBUT1JfRk4sCiAgICBtdWx0aTogdHJ1ZQogIH1dKTsKfQpmdW5jdGlvbiB3aXRoWHNyZkNvbmZpZ3VyYXRpb24oewogIGNvb2tpZU5hbWUsCiAgaGVhZGVyTmFtZQp9KSB7CiAgY29uc3QgcHJvdmlkZXJzID0gW107CiAgaWYgKGNvb2tpZU5hbWUgIT09IHZvaWQgMCkgewogICAgcHJvdmlkZXJzLnB1c2goewogICAgICBwcm92aWRlOiBYU1JGX0NPT0tJRV9OQU1FLAogICAgICB1c2VWYWx1ZTogY29va2llTmFtZQogICAgfSk7CiAgfQogIGlmIChoZWFkZXJOYW1lICE9PSB2b2lkIDApIHsKICAgIHByb3ZpZGVycy5wdXNoKHsKICAgICAgcHJvdmlkZTogWFNSRl9IRUFERVJfTkFNRSwKICAgICAgdXNlVmFsdWU6IGhlYWRlck5hbWUKICAgIH0pOwogIH0KICByZXR1cm4gbWFrZUh0dHBGZWF0dXJlKEh0dHBGZWF0dXJlS2luZC5DdXN0b21Yc3JmQ29uZmlndXJhdGlvbiwgcHJvdmlkZXJzKTsKfQpmdW5jdGlvbiB3aXRoTm9Yc3JmUHJvdGVjdGlvbigpIHsKICByZXR1cm4gbWFrZUh0dHBGZWF0dXJlKEh0dHBGZWF0dXJlS2luZC5Ob1hzcmZQcm90ZWN0aW9uLCBbewogICAgcHJvdmlkZTogWFNSRl9FTkFCTEVELAogICAgdXNlVmFsdWU6IGZhbHNlCiAgfV0pOwp9CmZ1bmN0aW9uIHdpdGhKc29ucFN1cHBvcnQoKSB7CiAgcmV0dXJuIG1ha2VIdHRwRmVhdHVyZShIdHRwRmVhdHVyZUtpbmQuSnNvbnBTdXBwb3J0LCBbSnNvbnBDbGllbnRCYWNrZW5kLCB7CiAgICBwcm92aWRlOiBKc29ucENhbGxiYWNrQ29udGV4dCwKICAgIHVzZUZhY3Rvcnk6IGpzb25wQ2FsbGJhY2tDb250ZXh0CiAgfSwgewogICAgcHJvdmlkZTogSFRUUF9JTlRFUkNFUFRPUl9GTlMsCiAgICB1c2VWYWx1ZToganNvbnBJbnRlcmNlcHRvckZuLAogICAgbXVsdGk6IHRydWUKICB9XSk7Cn0KdmFyIF9IdHRwQ2xpZW50WHNyZk1vZHVsZSA9IGNsYXNzIF9IdHRwQ2xpZW50WHNyZk1vZHVsZSB7CiAgLyoqCiAgICogRGlzYWJsZSB0aGUgZGVmYXVsdCBYU1JGIHByb3RlY3Rpb24uCiAgICovCiAgc3RhdGljIGRpc2FibGUoKSB7CiAgICByZXR1cm4gewogICAgICBuZ01vZHVsZTogX0h0dHBDbGllbnRYc3JmTW9kdWxlLAogICAgICBwcm92aWRlcnM6IFt3aXRoTm9Yc3JmUHJvdGVjdGlvbigpLsm1cHJvdmlkZXJzXQogICAgfTsKICB9CiAgLyoqCiAgICogQ29uZmlndXJlIFhTUkYgcHJvdGVjdGlvbi4KICAgKiBAcGFyYW0gb3B0aW9ucyBBbiBvYmplY3QgdGhhdCBjYW4gc3BlY2lmeSBlaXRoZXIgb3IgYm90aAogICAqIGNvb2tpZSBuYW1lIG9yIGhlYWRlciBuYW1lLgogICAqIC0gQ29va2llIG5hbWUgZGVmYXVsdCBpcyBgWFNSRi1UT0tFTmAuCiAgICogLSBIZWFkZXIgbmFtZSBkZWZhdWx0IGlzIGBYLVhTUkYtVE9LRU5gLgogICAqCiAgICovCiAgc3RhdGljIHdpdGhPcHRpb25zKG9wdGlvbnMgPSB7fSkgewogICAgcmV0dXJuIHsKICAgICAgbmdNb2R1bGU6IF9IdHRwQ2xpZW50WHNyZk1vZHVsZSwKICAgICAgcHJvdmlkZXJzOiB3aXRoWHNyZkNvbmZpZ3VyYXRpb24ob3B0aW9ucykuybVwcm92aWRlcnMKICAgIH07CiAgfQp9OwpfSHR0cENsaWVudFhzcmZNb2R1bGUuybVmYWMgPSBmdW5jdGlvbiBIdHRwQ2xpZW50WHNyZk1vZHVsZV9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9IdHRwQ2xpZW50WHNyZk1vZHVsZSkoKTsKfTsKX0h0dHBDbGllbnRYc3JmTW9kdWxlLsm1bW9kID0gybXJtWRlZmluZU5nTW9kdWxlKHsKICB0eXBlOiBfSHR0cENsaWVudFhzcmZNb2R1bGUKfSk7Cl9IdHRwQ2xpZW50WHNyZk1vZHVsZS7JtWluaiA9IMm1ybVkZWZpbmVJbmplY3Rvcih7CiAgcHJvdmlkZXJzOiBbSHR0cFhzcmZJbnRlcmNlcHRvciwgewogICAgcHJvdmlkZTogSFRUUF9JTlRFUkNFUFRPUlMsCiAgICB1c2VFeGlzdGluZzogSHR0cFhzcmZJbnRlcmNlcHRvciwKICAgIG11bHRpOiB0cnVlCiAgfSwgewogICAgcHJvdmlkZTogSHR0cFhzcmZUb2tlbkV4dHJhY3RvciwKICAgIHVzZUNsYXNzOiBIdHRwWHNyZkNvb2tpZUV4dHJhY3RvcgogIH0sIHdpdGhYc3JmQ29uZmlndXJhdGlvbih7CiAgICBjb29raWVOYW1lOiBYU1JGX0RFRkFVTFRfQ09PS0lFX05BTUUsCiAgICBoZWFkZXJOYW1lOiBYU1JGX0RFRkFVTFRfSEVBREVSX05BTUUKICB9KS7JtXByb3ZpZGVycywgewogICAgcHJvdmlkZTogWFNSRl9FTkFCTEVELAogICAgdXNlVmFsdWU6IHRydWUKICB9XQp9KTsKdmFyIEh0dHBDbGllbnRYc3JmTW9kdWxlID0gX0h0dHBDbGllbnRYc3JmTW9kdWxlOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoSHR0cENsaWVudFhzcmZNb2R1bGUsIFt7CiAgICB0eXBlOiBOZ01vZHVsZSwKICAgIGFyZ3M6IFt7CiAgICAgIHByb3ZpZGVyczogW0h0dHBYc3JmSW50ZXJjZXB0b3IsIHsKICAgICAgICBwcm92aWRlOiBIVFRQX0lOVEVSQ0VQVE9SUywKICAgICAgICB1c2VFeGlzdGluZzogSHR0cFhzcmZJbnRlcmNlcHRvciwKICAgICAgICBtdWx0aTogdHJ1ZQogICAgICB9LCB7CiAgICAgICAgcHJvdmlkZTogSHR0cFhzcmZUb2tlbkV4dHJhY3RvciwKICAgICAgICB1c2VDbGFzczogSHR0cFhzcmZDb29raWVFeHRyYWN0b3IKICAgICAgfSwgd2l0aFhzcmZDb25maWd1cmF0aW9uKHsKICAgICAgICBjb29raWVOYW1lOiBYU1JGX0RFRkFVTFRfQ09PS0lFX05BTUUsCiAgICAgICAgaGVhZGVyTmFtZTogWFNSRl9ERUZBVUxUX0hFQURFUl9OQU1FCiAgICAgIH0pLsm1cHJvdmlkZXJzLCB7CiAgICAgICAgcHJvdmlkZTogWFNSRl9FTkFCTEVELAogICAgICAgIHVzZVZhbHVlOiB0cnVlCiAgICAgIH1dCiAgICB9XQogIH1dLCBudWxsLCBudWxsKTsKfSkoKTsKdmFyIF9IdHRwQ2xpZW50TW9kdWxlID0gY2xhc3MgX0h0dHBDbGllbnRNb2R1bGUgewp9OwpfSHR0cENsaWVudE1vZHVsZS7JtWZhYyA9IGZ1bmN0aW9uIEh0dHBDbGllbnRNb2R1bGVfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfSHR0cENsaWVudE1vZHVsZSkoKTsKfTsKX0h0dHBDbGllbnRNb2R1bGUuybVtb2QgPSDJtcm1ZGVmaW5lTmdNb2R1bGUoewogIHR5cGU6IF9IdHRwQ2xpZW50TW9kdWxlCn0pOwpfSHR0cENsaWVudE1vZHVsZS7JtWluaiA9IMm1ybVkZWZpbmVJbmplY3Rvcih7CiAgcHJvdmlkZXJzOiBbcHJvdmlkZUh0dHBDbGllbnQod2l0aEludGVyY2VwdG9yc0Zyb21EaSgpKV0KfSk7CnZhciBIdHRwQ2xpZW50TW9kdWxlID0gX0h0dHBDbGllbnRNb2R1bGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShIdHRwQ2xpZW50TW9kdWxlLCBbewogICAgdHlwZTogTmdNb2R1bGUsCiAgICBhcmdzOiBbewogICAgICAvKioKICAgICAgICogQ29uZmlndXJlcyB0aGUgZGVwZW5kZW5jeSBpbmplY3RvciB3aGVyZSBpdCBpcyBpbXBvcnRlZAogICAgICAgKiB3aXRoIHN1cHBvcnRpbmcgc2VydmljZXMgZm9yIEhUVFAgY29tbXVuaWNhdGlvbnMuCiAgICAgICAqLwogICAgICBwcm92aWRlcnM6IFtwcm92aWRlSHR0cENsaWVudCh3aXRoSW50ZXJjZXB0b3JzRnJvbURpKCkpXQogICAgfV0KICB9XSwgbnVsbCwgbnVsbCk7Cn0pKCk7CnZhciBfSHR0cENsaWVudEpzb25wTW9kdWxlID0gY2xhc3MgX0h0dHBDbGllbnRKc29ucE1vZHVsZSB7Cn07Cl9IdHRwQ2xpZW50SnNvbnBNb2R1bGUuybVmYWMgPSBmdW5jdGlvbiBIdHRwQ2xpZW50SnNvbnBNb2R1bGVfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfSHR0cENsaWVudEpzb25wTW9kdWxlKSgpOwp9OwpfSHR0cENsaWVudEpzb25wTW9kdWxlLsm1bW9kID0gybXJtWRlZmluZU5nTW9kdWxlKHsKICB0eXBlOiBfSHR0cENsaWVudEpzb25wTW9kdWxlCn0pOwpfSHR0cENsaWVudEpzb25wTW9kdWxlLsm1aW5qID0gybXJtWRlZmluZUluamVjdG9yKHsKICBwcm92aWRlcnM6IFt3aXRoSnNvbnBTdXBwb3J0KCkuybVwcm92aWRlcnNdCn0pOwp2YXIgSHR0cENsaWVudEpzb25wTW9kdWxlID0gX0h0dHBDbGllbnRKc29ucE1vZHVsZTsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKEh0dHBDbGllbnRKc29ucE1vZHVsZSwgW3sKICAgIHR5cGU6IE5nTW9kdWxlLAogICAgYXJnczogW3sKICAgICAgcHJvdmlkZXJzOiBbd2l0aEpzb25wU3VwcG9ydCgpLsm1cHJvdmlkZXJzXQogICAgfV0KICB9XSwgbnVsbCwgbnVsbCk7Cn0pKCk7CnZhciBIVFRQX1RSQU5TRkVSX0NBQ0hFX09SSUdJTl9NQVAgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gIkhUVFBfVFJBTlNGRVJfQ0FDSEVfT1JJR0lOX01BUCIgOiAiIik7CnZhciBCT0RZID0gImIiOwp2YXIgSEVBREVSUyA9ICJoIjsKdmFyIFNUQVRVUyA9ICJzIjsKdmFyIFNUQVRVU19URVhUID0gInN0IjsKdmFyIFJFUV9VUkwgPSAidSI7CnZhciBSRVNQT05TRV9UWVBFID0gInJ0IjsKdmFyIENBQ0hFX09QVElPTlMgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gIkhUVFBfVFJBTlNGRVJfU1RBVEVfQ0FDSEVfT1BUSU9OUyIgOiAiIik7CnZhciBBTExPV0VEX01FVEhPRFMgPSBbIkdFVCIsICJIRUFEIl07CmZ1bmN0aW9uIHRyYW5zZmVyQ2FjaGVJbnRlcmNlcHRvckZuKHJlcSwgbmV4dCkgewogIGNvbnN0IF9hID0gaW5qZWN0KENBQ0hFX09QVElPTlMpLCB7CiAgICBpc0NhY2hlQWN0aXZlCiAgfSA9IF9hLCBnbG9iYWxPcHRpb25zID0gX19vYmpSZXN0KF9hLCBbCiAgICAiaXNDYWNoZUFjdGl2ZSIKICBdKTsKICBjb25zdCB7CiAgICB0cmFuc2ZlckNhY2hlOiByZXF1ZXN0T3B0aW9ucywKICAgIG1ldGhvZDogcmVxdWVzdE1ldGhvZAogIH0gPSByZXE7CiAgaWYgKCFpc0NhY2hlQWN0aXZlIHx8IHJlcXVlc3RPcHRpb25zID09PSBmYWxzZSB8fCAvLyBQT1NUIHJlcXVlc3RzIGFyZSBhbGxvd2VkIGVpdGhlciBnbG9iYWxseSBvciBhdCByZXF1ZXN0IGxldmVsCiAgcmVxdWVzdE1ldGhvZCA9PT0gIlBPU1QiICYmICFnbG9iYWxPcHRpb25zLmluY2x1ZGVQb3N0UmVxdWVzdHMgJiYgIXJlcXVlc3RPcHRpb25zIHx8IHJlcXVlc3RNZXRob2QgIT09ICJQT1NUIiAmJiAhQUxMT1dFRF9NRVRIT0RTLmluY2x1ZGVzKHJlcXVlc3RNZXRob2QpIHx8IC8vIERvIG5vdCBjYWNoZSByZXF1ZXN0IHRoYXQgcmVxdWlyZSBhdXRob3JpemF0aW9uIHdoZW4gaW5jbHVkZVJlcXVlc3RzV2l0aEF1dGhIZWFkZXJzIGlzIGZhbHNleQogICFnbG9iYWxPcHRpb25zLmluY2x1ZGVSZXF1ZXN0c1dpdGhBdXRoSGVhZGVycyAmJiBoYXNBdXRoSGVhZGVycyhyZXEpIHx8IGdsb2JhbE9wdGlvbnMuZmlsdGVyPy4ocmVxKSA9PT0gZmFsc2UpIHsKICAgIHJldHVybiBuZXh0KHJlcSk7CiAgfQogIGNvbnN0IHRyYW5zZmVyU3RhdGUgPSBpbmplY3QoVHJhbnNmZXJTdGF0ZSk7CiAgY29uc3Qgb3JpZ2luTWFwID0gaW5qZWN0KEhUVFBfVFJBTlNGRVJfQ0FDSEVfT1JJR0lOX01BUCwgewogICAgb3B0aW9uYWw6IHRydWUKICB9KTsKICBjb25zdCBpc1NlcnZlciA9IGlzUGxhdGZvcm1TZXJ2ZXIoaW5qZWN0KFBMQVRGT1JNX0lEKSk7CiAgaWYgKG9yaWdpbk1hcCAmJiAhaXNTZXJ2ZXIpIHsKICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoMjgwMywgbmdEZXZNb2RlICYmICJBbmd1bGFyIGRldGVjdGVkIHRoYXQgdGhlIGBIVFRQX1RSQU5TRkVSX0NBQ0hFX09SSUdJTl9NQVBgIHRva2VuIGlzIGNvbmZpZ3VyZWQgYW5kIHByZXNlbnQgaW4gdGhlIGNsaWVudCBzaWRlIGNvZGUuIFBsZWFzZSBlbnN1cmUgdGhhdCB0aGlzIHRva2VuIGlzIG9ubHkgcHJvdmlkZWQgaW4gdGhlIHNlcnZlciBjb2RlIG9mIHRoZSBhcHBsaWNhdGlvbi4iKTsKICB9CiAgY29uc3QgcmVxdWVzdFVybCA9IGlzU2VydmVyICYmIG9yaWdpbk1hcCA/IG1hcFJlcXVlc3RPcmlnaW5VcmwocmVxLnVybCwgb3JpZ2luTWFwKSA6IHJlcS51cmw7CiAgY29uc3Qgc3RvcmVLZXkgPSBtYWtlQ2FjaGVLZXkocmVxLCByZXF1ZXN0VXJsKTsKICBjb25zdCByZXNwb25zZSA9IHRyYW5zZmVyU3RhdGUuZ2V0KHN0b3JlS2V5LCBudWxsKTsKICBsZXQgaGVhZGVyc1RvSW5jbHVkZSA9IGdsb2JhbE9wdGlvbnMuaW5jbHVkZUhlYWRlcnM7CiAgaWYgKHR5cGVvZiByZXF1ZXN0T3B0aW9ucyA9PT0gIm9iamVjdCIgJiYgcmVxdWVzdE9wdGlvbnMuaW5jbHVkZUhlYWRlcnMpIHsKICAgIGhlYWRlcnNUb0luY2x1ZGUgPSByZXF1ZXN0T3B0aW9ucy5pbmNsdWRlSGVhZGVyczsKICB9CiAgaWYgKHJlc3BvbnNlKSB7CiAgICBjb25zdCB7CiAgICAgIFtCT0RZXTogdW5kZWNvZGVkQm9keSwKICAgICAgW1JFU1BPTlNFX1RZUEVdOiByZXNwb25zZVR5cGUsCiAgICAgIFtIRUFERVJTXTogaHR0cEhlYWRlcnMsCiAgICAgIFtTVEFUVVNdOiBzdGF0dXMsCiAgICAgIFtTVEFUVVNfVEVYVF06IHN0YXR1c1RleHQsCiAgICAgIFtSRVFfVVJMXTogdXJsCiAgICB9ID0gcmVzcG9uc2U7CiAgICBsZXQgYm9keSA9IHVuZGVjb2RlZEJvZHk7CiAgICBzd2l0Y2ggKHJlc3BvbnNlVHlwZSkgewogICAgICBjYXNlICJhcnJheWJ1ZmZlciI6CiAgICAgICAgYm9keSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSh1bmRlY29kZWRCb2R5KS5idWZmZXI7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgImJsb2IiOgogICAgICAgIGJvZHkgPSBuZXcgQmxvYihbdW5kZWNvZGVkQm9keV0pOwogICAgICAgIGJyZWFrOwogICAgfQogICAgbGV0IGhlYWRlcnMgPSBuZXcgSHR0cEhlYWRlcnMoaHR0cEhlYWRlcnMpOwogICAgaWYgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgewogICAgICBoZWFkZXJzID0gYXBwZW5kTWlzc2luZ0hlYWRlcnNEZXRlY3Rpb24ocmVxLnVybCwgaGVhZGVycywgaGVhZGVyc1RvSW5jbHVkZSA/PyBbXSk7CiAgICB9CiAgICByZXR1cm4gb2YobmV3IEh0dHBSZXNwb25zZSh7CiAgICAgIGJvZHksCiAgICAgIGhlYWRlcnMsCiAgICAgIHN0YXR1cywKICAgICAgc3RhdHVzVGV4dCwKICAgICAgdXJsCiAgICB9KSk7CiAgfQogIHJldHVybiBuZXh0KHJlcSkucGlwZSh0YXAoKGV2ZW50KSA9PiB7CiAgICBpZiAoZXZlbnQgaW5zdGFuY2VvZiBIdHRwUmVzcG9uc2UgJiYgaXNTZXJ2ZXIpIHsKICAgICAgdHJhbnNmZXJTdGF0ZS5zZXQoc3RvcmVLZXksIHsKICAgICAgICBbQk9EWV06IGV2ZW50LmJvZHksCiAgICAgICAgW0hFQURFUlNdOiBnZXRGaWx0ZXJlZEhlYWRlcnMoZXZlbnQuaGVhZGVycywgaGVhZGVyc1RvSW5jbHVkZSksCiAgICAgICAgW1NUQVRVU106IGV2ZW50LnN0YXR1cywKICAgICAgICBbU1RBVFVTX1RFWFRdOiBldmVudC5zdGF0dXNUZXh0LAogICAgICAgIFtSRVFfVVJMXTogcmVxdWVzdFVybCwKICAgICAgICBbUkVTUE9OU0VfVFlQRV06IHJlcS5yZXNwb25zZVR5cGUKICAgICAgfSk7CiAgICB9CiAgfSkpOwp9CmZ1bmN0aW9uIGhhc0F1dGhIZWFkZXJzKHJlcSkgewogIHJldHVybiByZXEuaGVhZGVycy5oYXMoImF1dGhvcml6YXRpb24iKSB8fCByZXEuaGVhZGVycy5oYXMoInByb3h5LWF1dGhvcml6YXRpb24iKTsKfQpmdW5jdGlvbiBnZXRGaWx0ZXJlZEhlYWRlcnMoaGVhZGVycywgaW5jbHVkZUhlYWRlcnMpIHsKICBpZiAoIWluY2x1ZGVIZWFkZXJzKSB7CiAgICByZXR1cm4ge307CiAgfQogIGNvbnN0IGhlYWRlcnNNYXAgPSB7fTsKICBmb3IgKGNvbnN0IGtleSBvZiBpbmNsdWRlSGVhZGVycykgewogICAgY29uc3QgdmFsdWVzID0gaGVhZGVycy5nZXRBbGwoa2V5KTsKICAgIGlmICh2YWx1ZXMgIT09IG51bGwpIHsKICAgICAgaGVhZGVyc01hcFtrZXldID0gdmFsdWVzOwogICAgfQogIH0KICByZXR1cm4gaGVhZGVyc01hcDsKfQpmdW5jdGlvbiBzb3J0QW5kQ29uY2F0UGFyYW1zKHBhcmFtcykgewogIHJldHVybiBbLi4ucGFyYW1zLmtleXMoKV0uc29ydCgpLm1hcCgoaykgPT4gYCR7a309JHtwYXJhbXMuZ2V0QWxsKGspfWApLmpvaW4oIiYiKTsKfQpmdW5jdGlvbiBtYWtlQ2FjaGVLZXkocmVxdWVzdCwgbWFwcGVkUmVxdWVzdFVybCkgewogIGNvbnN0IHsKICAgIHBhcmFtcywKICAgIG1ldGhvZCwKICAgIHJlc3BvbnNlVHlwZQogIH0gPSByZXF1ZXN0OwogIGNvbnN0IGVuY29kZWRQYXJhbXMgPSBzb3J0QW5kQ29uY2F0UGFyYW1zKHBhcmFtcyk7CiAgbGV0IHNlcmlhbGl6ZWRCb2R5ID0gcmVxdWVzdC5zZXJpYWxpemVCb2R5KCk7CiAgaWYgKHNlcmlhbGl6ZWRCb2R5IGluc3RhbmNlb2YgVVJMU2VhcmNoUGFyYW1zKSB7CiAgICBzZXJpYWxpemVkQm9keSA9IHNvcnRBbmRDb25jYXRQYXJhbXMoc2VyaWFsaXplZEJvZHkpOwogIH0gZWxzZSBpZiAodHlwZW9mIHNlcmlhbGl6ZWRCb2R5ICE9PSAic3RyaW5nIikgewogICAgc2VyaWFsaXplZEJvZHkgPSAiIjsKICB9CiAgY29uc3Qga2V5ID0gW21ldGhvZCwgcmVzcG9uc2VUeXBlLCBtYXBwZWRSZXF1ZXN0VXJsLCBzZXJpYWxpemVkQm9keSwgZW5jb2RlZFBhcmFtc10uam9pbigifCIpOwogIGNvbnN0IGhhc2ggPSBnZW5lcmF0ZUhhc2goa2V5KTsKICByZXR1cm4gbWFrZVN0YXRlS2V5KGhhc2gpOwp9CmZ1bmN0aW9uIGdlbmVyYXRlSGFzaCh2YWx1ZSkgewogIGxldCBoYXNoID0gMDsKICBmb3IgKGNvbnN0IGNoYXIgb2YgdmFsdWUpIHsKICAgIGhhc2ggPSBNYXRoLmltdWwoMzEsIGhhc2gpICsgY2hhci5jaGFyQ29kZUF0KDApIDw8IDA7CiAgfQogIGhhc2ggKz0gMjE0NzQ4MzY0NyArIDE7CiAgcmV0dXJuIGhhc2gudG9TdHJpbmcoKTsKfQpmdW5jdGlvbiB3aXRoSHR0cFRyYW5zZmVyQ2FjaGUoY2FjaGVPcHRpb25zKSB7CiAgcmV0dXJuIFt7CiAgICBwcm92aWRlOiBDQUNIRV9PUFRJT05TLAogICAgdXNlRmFjdG9yeTogKCkgPT4gewogICAgICBwZXJmb3JtYW5jZU1hcmtGZWF0dXJlKCJOZ0h0dHBUcmFuc2ZlckNhY2hlIik7CiAgICAgIHJldHVybiBfX3NwcmVhZFZhbHVlcyh7CiAgICAgICAgaXNDYWNoZUFjdGl2ZTogdHJ1ZQogICAgICB9LCBjYWNoZU9wdGlvbnMpOwogICAgfQogIH0sIHsKICAgIHByb3ZpZGU6IEhUVFBfUk9PVF9JTlRFUkNFUFRPUl9GTlMsCiAgICB1c2VWYWx1ZTogdHJhbnNmZXJDYWNoZUludGVyY2VwdG9yRm4sCiAgICBtdWx0aTogdHJ1ZSwKICAgIGRlcHM6IFtUcmFuc2ZlclN0YXRlLCBDQUNIRV9PUFRJT05TXQogIH0sIHsKICAgIHByb3ZpZGU6IEFQUF9CT09UU1RSQVBfTElTVEVORVIsCiAgICBtdWx0aTogdHJ1ZSwKICAgIHVzZUZhY3Rvcnk6ICgpID0+IHsKICAgICAgY29uc3QgYXBwUmVmID0gaW5qZWN0KEFwcGxpY2F0aW9uUmVmKTsKICAgICAgY29uc3QgY2FjaGVTdGF0ZSA9IGluamVjdChDQUNIRV9PUFRJT05TKTsKICAgICAgcmV0dXJuICgpID0+IHsKICAgICAgICB3aGVuU3RhYmxlKGFwcFJlZikudGhlbigoKSA9PiB7CiAgICAgICAgICBjYWNoZVN0YXRlLmlzQ2FjaGVBY3RpdmUgPSBmYWxzZTsKICAgICAgICB9KTsKICAgICAgfTsKICAgIH0KICB9XTsKfQpmdW5jdGlvbiBhcHBlbmRNaXNzaW5nSGVhZGVyc0RldGVjdGlvbih1cmwsIGhlYWRlcnMsIGhlYWRlcnNUb0luY2x1ZGUpIHsKICBjb25zdCB3YXJuaW5nUHJvZHVjZWQgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpOwogIHJldHVybiBuZXcgUHJveHkoaGVhZGVycywgewogICAgZ2V0KHRhcmdldCwgcHJvcCkgewogICAgICBjb25zdCB2YWx1ZSA9IFJlZmxlY3QuZ2V0KHRhcmdldCwgcHJvcCk7CiAgICAgIGNvbnN0IG1ldGhvZHMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldChbImdldCIsICJoYXMiLCAiZ2V0QWxsIl0pOwogICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAiZnVuY3Rpb24iIHx8ICFtZXRob2RzLmhhcyhwcm9wKSkgewogICAgICAgIHJldHVybiB2YWx1ZTsKICAgICAgfQogICAgICByZXR1cm4gKGhlYWRlck5hbWUpID0+IHsKICAgICAgICBjb25zdCBrZXkgPSAocHJvcCArICI6IiArIGhlYWRlck5hbWUpLnRvTG93ZXJDYXNlKCk7CiAgICAgICAgaWYgKCFoZWFkZXJzVG9JbmNsdWRlLmluY2x1ZGVzKGhlYWRlck5hbWUpICYmICF3YXJuaW5nUHJvZHVjZWQuaGFzKGtleSkpIHsKICAgICAgICAgIHdhcm5pbmdQcm9kdWNlZC5hZGQoa2V5KTsKICAgICAgICAgIGNvbnN0IHRydW5jYXRlZFVybCA9IHRydW5jYXRlTWlkZGxlKHVybCk7CiAgICAgICAgICBjb25zb2xlLndhcm4oZm9ybWF0UnVudGltZUVycm9yKDI4MDIsIGBBbmd1bGFyIGRldGVjdGVkIHRoYXQgdGhlIFxgJHtoZWFkZXJOYW1lfVxgIGhlYWRlciBpcyBhY2Nlc3NlZCwgYnV0IHRoZSB2YWx1ZSBvZiB0aGUgaGVhZGVyIHdhcyBub3QgdHJhbnNmZXJyZWQgZnJvbSB0aGUgc2VydmVyIHRvIHRoZSBjbGllbnQgYnkgdGhlIEh0dHBUcmFuc2ZlckNhY2hlLiBUbyBpbmNsdWRlIHRoZSB2YWx1ZSBvZiB0aGUgXGAke2hlYWRlck5hbWV9XGAgaGVhZGVyIGZvciB0aGUgXGAke3RydW5jYXRlZFVybH1cYCByZXF1ZXN0LCB1c2UgdGhlIFxgaW5jbHVkZUhlYWRlcnNcYCBsaXN0LiBUaGUgXGBpbmNsdWRlSGVhZGVyc1xgIGNhbiBiZSBkZWZpbmVkIGVpdGhlciBvbiBhIHJlcXVlc3QgbGV2ZWwgYnkgYWRkaW5nIHRoZSBcYHRyYW5zZmVyQ2FjaGVcYCBwYXJhbWV0ZXIsIG9yIG9uIGFuIGFwcGxpY2F0aW9uIGxldmVsIGJ5IGFkZGluZyB0aGUgXGBodHRwQ2FjaGVUcmFuc2Zlci5pbmNsdWRlSGVhZGVyc1xgIGFyZ3VtZW50IHRvIHRoZSBcYHByb3ZpZGVDbGllbnRIeWRyYXRpb24oKVxgIGNhbGwuIGApKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlLmFwcGx5KHRhcmdldCwgW2hlYWRlck5hbWVdKTsKICAgICAgfTsKICAgIH0KICB9KTsKfQpmdW5jdGlvbiBtYXBSZXF1ZXN0T3JpZ2luVXJsKHVybCwgb3JpZ2luTWFwKSB7CiAgY29uc3Qgb3JpZ2luID0gbmV3IFVSTCh1cmwsICJyZXNvbHZlOi8vIikub3JpZ2luOwogIGNvbnN0IG1hcHBlZE9yaWdpbiA9IG9yaWdpbk1hcFtvcmlnaW5dOwogIGlmICghbWFwcGVkT3JpZ2luKSB7CiAgICByZXR1cm4gdXJsOwogIH0KICBpZiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSB7CiAgICB2ZXJpZnlNYXBwZWRPcmlnaW4obWFwcGVkT3JpZ2luKTsKICB9CiAgcmV0dXJuIHVybC5yZXBsYWNlKG9yaWdpbiwgbWFwcGVkT3JpZ2luKTsKfQpmdW5jdGlvbiB2ZXJpZnlNYXBwZWRPcmlnaW4odXJsKSB7CiAgaWYgKG5ldyBVUkwodXJsLCAicmVzb2x2ZTovLyIpLnBhdGhuYW1lICE9PSAiLyIpIHsKICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoMjgwNCwgYEFuZ3VsYXIgZGV0ZWN0ZWQgYSBVUkwgd2l0aCBhIHBhdGggc2VnbWVudCBpbiB0aGUgdmFsdWUgcHJvdmlkZWQgZm9yIHRoZSBcYEhUVFBfVFJBTlNGRVJfQ0FDSEVfT1JJR0lOX01BUFxgIHRva2VuOiAke3VybH0uIFRoZSBtYXAgc2hvdWxkIG9ubHkgY29udGFpbiBvcmlnaW5zIHdpdGhvdXQgYW55IG90aGVyIHNlZ21lbnRzLmApOwogIH0KfQoKLy8gbm9kZV9tb2R1bGVzL0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXIvZmVzbTIwMjIvcGxhdGZvcm0tYnJvd3Nlci5tanMKdmFyIEdlbmVyaWNCcm93c2VyRG9tQWRhcHRlciA9IGNsYXNzIGV4dGVuZHMgRG9tQWRhcHRlciB7CiAgY29uc3RydWN0b3IoKSB7CiAgICBzdXBlciguLi5hcmd1bWVudHMpOwogICAgdGhpcy5zdXBwb3J0c0RPTUV2ZW50cyA9IHRydWU7CiAgfQp9Owp2YXIgQnJvd3NlckRvbUFkYXB0ZXIgPSBjbGFzcyBfQnJvd3NlckRvbUFkYXB0ZXIgZXh0ZW5kcyBHZW5lcmljQnJvd3NlckRvbUFkYXB0ZXIgewogIHN0YXRpYyBtYWtlQ3VycmVudCgpIHsKICAgIHNldFJvb3REb21BZGFwdGVyKG5ldyBfQnJvd3NlckRvbUFkYXB0ZXIoKSk7CiAgfQogIG9uQW5kQ2FuY2VsKGVsLCBldnQsIGxpc3RlbmVyKSB7CiAgICBlbC5hZGRFdmVudExpc3RlbmVyKGV2dCwgbGlzdGVuZXIpOwogICAgcmV0dXJuICgpID0+IHsKICAgICAgZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihldnQsIGxpc3RlbmVyKTsKICAgIH07CiAgfQogIGRpc3BhdGNoRXZlbnQoZWwsIGV2dCkgewogICAgZWwuZGlzcGF0Y2hFdmVudChldnQpOwogIH0KICByZW1vdmUobm9kZSkgewogICAgaWYgKG5vZGUucGFyZW50Tm9kZSkgewogICAgICBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7CiAgICB9CiAgfQogIGNyZWF0ZUVsZW1lbnQodGFnTmFtZSwgZG9jKSB7CiAgICBkb2MgPSBkb2MgfHwgdGhpcy5nZXREZWZhdWx0RG9jdW1lbnQoKTsKICAgIHJldHVybiBkb2MuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTsKICB9CiAgY3JlYXRlSHRtbERvY3VtZW50KCkgewogICAgcmV0dXJuIGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudCgiZmFrZVRpdGxlIik7CiAgfQogIGdldERlZmF1bHREb2N1bWVudCgpIHsKICAgIHJldHVybiBkb2N1bWVudDsKICB9CiAgaXNFbGVtZW50Tm9kZShub2RlKSB7CiAgICByZXR1cm4gbm9kZS5ub2RlVHlwZSA9PT0gTm9kZS5FTEVNRU5UX05PREU7CiAgfQogIGlzU2hhZG93Um9vdChub2RlKSB7CiAgICByZXR1cm4gbm9kZSBpbnN0YW5jZW9mIERvY3VtZW50RnJhZ21lbnQ7CiAgfQogIC8qKiBAZGVwcmVjYXRlZCBObyBsb25nZXIgYmVpbmcgdXNlZCBpbiBJdnkgY29kZS4gVG8gYmUgcmVtb3ZlZCBpbiB2ZXJzaW9uIDE0LiAqLwogIGdldEdsb2JhbEV2ZW50VGFyZ2V0KGRvYywgdGFyZ2V0KSB7CiAgICBpZiAodGFyZ2V0ID09PSAid2luZG93IikgewogICAgICByZXR1cm4gd2luZG93OwogICAgfQogICAgaWYgKHRhcmdldCA9PT0gImRvY3VtZW50IikgewogICAgICByZXR1cm4gZG9jOwogICAgfQogICAgaWYgKHRhcmdldCA9PT0gImJvZHkiKSB7CiAgICAgIHJldHVybiBkb2MuYm9keTsKICAgIH0KICAgIHJldHVybiBudWxsOwogIH0KICBnZXRCYXNlSHJlZihkb2MpIHsKICAgIGNvbnN0IGhyZWYgPSBnZXRCYXNlRWxlbWVudEhyZWYoKTsKICAgIHJldHVybiBocmVmID09IG51bGwgPyBudWxsIDogcmVsYXRpdmVQYXRoKGhyZWYpOwogIH0KICByZXNldEJhc2VFbGVtZW50KCkgewogICAgYmFzZUVsZW1lbnQgPSBudWxsOwogIH0KICBnZXRVc2VyQWdlbnQoKSB7CiAgICByZXR1cm4gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7CiAgfQogIGdldENvb2tpZShuYW1lKSB7CiAgICByZXR1cm4gcGFyc2VDb29raWVWYWx1ZShkb2N1bWVudC5jb29raWUsIG5hbWUpOwogIH0KfTsKdmFyIGJhc2VFbGVtZW50ID0gbnVsbDsKZnVuY3Rpb24gZ2V0QmFzZUVsZW1lbnRIcmVmKCkgewogIGJhc2VFbGVtZW50ID0gYmFzZUVsZW1lbnQgfHwgZG9jdW1lbnQucXVlcnlTZWxlY3RvcigiYmFzZSIpOwogIHJldHVybiBiYXNlRWxlbWVudCA/IGJhc2VFbGVtZW50LmdldEF0dHJpYnV0ZSgiaHJlZiIpIDogbnVsbDsKfQpmdW5jdGlvbiByZWxhdGl2ZVBhdGgodXJsKSB7CiAgcmV0dXJuIG5ldyBVUkwodXJsLCBkb2N1bWVudC5iYXNlVVJJKS5wYXRobmFtZTsKfQp2YXIgQnJvd3NlckdldFRlc3RhYmlsaXR5ID0gY2xhc3MgewogIGFkZFRvV2luZG93KHJlZ2lzdHJ5KSB7CiAgICBfZ2xvYmFsWyJnZXRBbmd1bGFyVGVzdGFiaWxpdHkiXSA9IChlbGVtLCBmaW5kSW5BbmNlc3RvcnMgPSB0cnVlKSA9PiB7CiAgICAgIGNvbnN0IHRlc3RhYmlsaXR5ID0gcmVnaXN0cnkuZmluZFRlc3RhYmlsaXR5SW5UcmVlKGVsZW0sIGZpbmRJbkFuY2VzdG9ycyk7CiAgICAgIGlmICh0ZXN0YWJpbGl0eSA9PSBudWxsKSB7CiAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcig1MTAzLCAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiAiQ291bGQgbm90IGZpbmQgdGVzdGFiaWxpdHkgZm9yIGVsZW1lbnQuIik7CiAgICAgIH0KICAgICAgcmV0dXJuIHRlc3RhYmlsaXR5OwogICAgfTsKICAgIF9nbG9iYWxbImdldEFsbEFuZ3VsYXJUZXN0YWJpbGl0aWVzIl0gPSAoKSA9PiByZWdpc3RyeS5nZXRBbGxUZXN0YWJpbGl0aWVzKCk7CiAgICBfZ2xvYmFsWyJnZXRBbGxBbmd1bGFyUm9vdEVsZW1lbnRzIl0gPSAoKSA9PiByZWdpc3RyeS5nZXRBbGxSb290RWxlbWVudHMoKTsKICAgIGNvbnN0IHdoZW5BbGxTdGFibGUgPSAoY2FsbGJhY2spID0+IHsKICAgICAgY29uc3QgdGVzdGFiaWxpdGllcyA9IF9nbG9iYWxbImdldEFsbEFuZ3VsYXJUZXN0YWJpbGl0aWVzIl0oKTsKICAgICAgbGV0IGNvdW50ID0gdGVzdGFiaWxpdGllcy5sZW5ndGg7CiAgICAgIGNvbnN0IGRlY3JlbWVudCA9IGZ1bmN0aW9uKCkgewogICAgICAgIGNvdW50LS07CiAgICAgICAgaWYgKGNvdW50ID09IDApIHsKICAgICAgICAgIGNhbGxiYWNrKCk7CiAgICAgICAgfQogICAgICB9OwogICAgICB0ZXN0YWJpbGl0aWVzLmZvckVhY2goKHRlc3RhYmlsaXR5KSA9PiB7CiAgICAgICAgdGVzdGFiaWxpdHkud2hlblN0YWJsZShkZWNyZW1lbnQpOwogICAgICB9KTsKICAgIH07CiAgICBpZiAoIV9nbG9iYWxbImZyYW1ld29ya1N0YWJpbGl6ZXJzIl0pIHsKICAgICAgX2dsb2JhbFsiZnJhbWV3b3JrU3RhYmlsaXplcnMiXSA9IFtdOwogICAgfQogICAgX2dsb2JhbFsiZnJhbWV3b3JrU3RhYmlsaXplcnMiXS5wdXNoKHdoZW5BbGxTdGFibGUpOwogIH0KICBmaW5kVGVzdGFiaWxpdHlJblRyZWUocmVnaXN0cnksIGVsZW0sIGZpbmRJbkFuY2VzdG9ycykgewogICAgaWYgKGVsZW0gPT0gbnVsbCkgewogICAgICByZXR1cm4gbnVsbDsKICAgIH0KICAgIGNvbnN0IHQgPSByZWdpc3RyeS5nZXRUZXN0YWJpbGl0eShlbGVtKTsKICAgIGlmICh0ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHQ7CiAgICB9IGVsc2UgaWYgKCFmaW5kSW5BbmNlc3RvcnMpIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBpZiAoZ2V0RE9NKCkuaXNTaGFkb3dSb290KGVsZW0pKSB7CiAgICAgIHJldHVybiB0aGlzLmZpbmRUZXN0YWJpbGl0eUluVHJlZShyZWdpc3RyeSwgZWxlbS5ob3N0LCB0cnVlKTsKICAgIH0KICAgIHJldHVybiB0aGlzLmZpbmRUZXN0YWJpbGl0eUluVHJlZShyZWdpc3RyeSwgZWxlbS5wYXJlbnRFbGVtZW50LCB0cnVlKTsKICB9Cn07CnZhciBfQnJvd3NlclhociA9IGNsYXNzIF9Ccm93c2VyWGhyIHsKICBidWlsZCgpIHsKICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKTsKICB9Cn07Cl9Ccm93c2VyWGhyLsm1ZmFjID0gZnVuY3Rpb24gQnJvd3Nlclhocl9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9Ccm93c2VyWGhyKSgpOwp9OwpfQnJvd3Nlclhoci7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7CiAgdG9rZW46IF9Ccm93c2VyWGhyLAogIGZhY3Rvcnk6IF9Ccm93c2VyWGhyLsm1ZmFjCn0pOwp2YXIgQnJvd3NlclhociA9IF9Ccm93c2VyWGhyOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoQnJvd3NlclhociwgW3sKICAgIHR5cGU6IEluamVjdGFibGUKICB9XSwgbnVsbCwgbnVsbCk7Cn0pKCk7CnZhciBFVkVOVF9NQU5BR0VSX1BMVUdJTlMgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gIkV2ZW50TWFuYWdlclBsdWdpbnMiIDogIiIpOwp2YXIgX0V2ZW50TWFuYWdlciA9IGNsYXNzIF9FdmVudE1hbmFnZXIgewogIC8qKgogICAqIEluaXRpYWxpemVzIGFuIGluc3RhbmNlIG9mIHRoZSBldmVudC1tYW5hZ2VyIHNlcnZpY2UuCiAgICovCiAgY29uc3RydWN0b3IocGx1Z2lucywgX3pvbmUpIHsKICAgIHRoaXMuX3pvbmUgPSBfem9uZTsKICAgIHRoaXMuX2V2ZW50TmFtZVRvUGx1Z2luID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgIHBsdWdpbnMuZm9yRWFjaCgocGx1Z2luKSA9PiB7CiAgICAgIHBsdWdpbi5tYW5hZ2VyID0gdGhpczsKICAgIH0pOwogICAgdGhpcy5fcGx1Z2lucyA9IHBsdWdpbnMuc2xpY2UoKS5yZXZlcnNlKCk7CiAgfQogIC8qKgogICAqIFJlZ2lzdGVycyBhIGhhbmRsZXIgZm9yIGEgc3BlY2lmaWMgZWxlbWVudCBhbmQgZXZlbnQuCiAgICoKICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgSFRNTCBlbGVtZW50IHRvIHJlY2VpdmUgZXZlbnQgbm90aWZpY2F0aW9ucy4KICAgKiBAcGFyYW0gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBldmVudCB0byBsaXN0ZW4gZm9yLgogICAqIEBwYXJhbSBoYW5kbGVyIEEgZnVuY3Rpb24gdG8gY2FsbCB3aGVuIHRoZSBub3RpZmljYXRpb24gb2NjdXJzLiBSZWNlaXZlcyB0aGUKICAgKiBldmVudCBvYmplY3QgYXMgYW4gYXJndW1lbnQuCiAgICogQHJldHVybnMgIEEgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB0byByZW1vdmUgdGhlIGhhbmRsZXIuCiAgICovCiAgYWRkRXZlbnRMaXN0ZW5lcihlbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpIHsKICAgIGNvbnN0IHBsdWdpbiA9IHRoaXMuX2ZpbmRQbHVnaW5Gb3IoZXZlbnROYW1lKTsKICAgIHJldHVybiBwbHVnaW4uYWRkRXZlbnRMaXN0ZW5lcihlbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpOwogIH0KICAvKioKICAgKiBSZXRyaWV2ZXMgdGhlIGNvbXBpbGF0aW9uIHpvbmUgaW4gd2hpY2ggZXZlbnQgbGlzdGVuZXJzIGFyZSByZWdpc3RlcmVkLgogICAqLwogIGdldFpvbmUoKSB7CiAgICByZXR1cm4gdGhpcy5fem9uZTsKICB9CiAgLyoqIEBpbnRlcm5hbCAqLwogIF9maW5kUGx1Z2luRm9yKGV2ZW50TmFtZSkgewogICAgbGV0IHBsdWdpbiA9IHRoaXMuX2V2ZW50TmFtZVRvUGx1Z2luLmdldChldmVudE5hbWUpOwogICAgaWYgKHBsdWdpbikgewogICAgICByZXR1cm4gcGx1Z2luOwogICAgfQogICAgY29uc3QgcGx1Z2lucyA9IHRoaXMuX3BsdWdpbnM7CiAgICBwbHVnaW4gPSBwbHVnaW5zLmZpbmQoKHBsdWdpbjIpID0+IHBsdWdpbjIuc3VwcG9ydHMoZXZlbnROYW1lKSk7CiAgICBpZiAoIXBsdWdpbikgewogICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDUxMDEsICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIGBObyBldmVudCBtYW5hZ2VyIHBsdWdpbiBmb3VuZCBmb3IgZXZlbnQgJHtldmVudE5hbWV9YCk7CiAgICB9CiAgICB0aGlzLl9ldmVudE5hbWVUb1BsdWdpbi5zZXQoZXZlbnROYW1lLCBwbHVnaW4pOwogICAgcmV0dXJuIHBsdWdpbjsKICB9Cn07Cl9FdmVudE1hbmFnZXIuybVmYWMgPSBmdW5jdGlvbiBFdmVudE1hbmFnZXJfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfRXZlbnRNYW5hZ2VyKSjJtcm1aW5qZWN0KEVWRU5UX01BTkFHRVJfUExVR0lOUyksIMm1ybVpbmplY3QoTmdab25lKSk7Cn07Cl9FdmVudE1hbmFnZXIuybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfRXZlbnRNYW5hZ2VyLAogIGZhY3Rvcnk6IF9FdmVudE1hbmFnZXIuybVmYWMKfSk7CnZhciBFdmVudE1hbmFnZXIgPSBfRXZlbnRNYW5hZ2VyOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoRXZlbnRNYW5hZ2VyLCBbewogICAgdHlwZTogSW5qZWN0YWJsZQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogdm9pZCAwLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogSW5qZWN0LAogICAgICBhcmdzOiBbRVZFTlRfTUFOQUdFUl9QTFVHSU5TXQogICAgfV0KICB9LCB7CiAgICB0eXBlOiBOZ1pvbmUKICB9XSwgbnVsbCk7Cn0pKCk7CnZhciBFdmVudE1hbmFnZXJQbHVnaW4gPSBjbGFzcyB7CiAgLy8gVE9ETzogcmVtb3ZlIChoYXMgc29tZSB1c2FnZSBpbiBHMykKICBjb25zdHJ1Y3RvcihfZG9jKSB7CiAgICB0aGlzLl9kb2MgPSBfZG9jOwogIH0KfTsKdmFyIEFQUF9JRF9BVFRSSUJVVEVfTkFNRSA9ICJuZy1hcHAtaWQiOwp2YXIgX1NoYXJlZFN0eWxlc0hvc3QgPSBjbGFzcyBfU2hhcmVkU3R5bGVzSG9zdCB7CiAgY29uc3RydWN0b3IoZG9jLCBhcHBJZCwgbm9uY2UsIHBsYXRmb3JtSWQgPSB7fSkgewogICAgdGhpcy5kb2MgPSBkb2M7CiAgICB0aGlzLmFwcElkID0gYXBwSWQ7CiAgICB0aGlzLm5vbmNlID0gbm9uY2U7CiAgICB0aGlzLnBsYXRmb3JtSWQgPSBwbGF0Zm9ybUlkOwogICAgdGhpcy5zdHlsZVJlZiA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICB0aGlzLmhvc3ROb2RlcyA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgU2V0KCk7CiAgICB0aGlzLnN0eWxlTm9kZXNJbkRPTSA9IHRoaXMuY29sbGVjdFNlcnZlclJlbmRlcmVkU3R5bGVzKCk7CiAgICB0aGlzLnBsYXRmb3JtSXNTZXJ2ZXIgPSBpc1BsYXRmb3JtU2VydmVyKHBsYXRmb3JtSWQpOwogICAgdGhpcy5yZXNldEhvc3ROb2RlcygpOwogIH0KICBhZGRTdHlsZXMoc3R5bGVzKSB7CiAgICBmb3IgKGNvbnN0IHN0eWxlIG9mIHN0eWxlcykgewogICAgICBjb25zdCB1c2FnZUNvdW50ID0gdGhpcy5jaGFuZ2VVc2FnZUNvdW50KHN0eWxlLCAxKTsKICAgICAgaWYgKHVzYWdlQ291bnQgPT09IDEpIHsKICAgICAgICB0aGlzLm9uU3R5bGVBZGRlZChzdHlsZSk7CiAgICAgIH0KICAgIH0KICB9CiAgcmVtb3ZlU3R5bGVzKHN0eWxlcykgewogICAgZm9yIChjb25zdCBzdHlsZSBvZiBzdHlsZXMpIHsKICAgICAgY29uc3QgdXNhZ2VDb3VudCA9IHRoaXMuY2hhbmdlVXNhZ2VDb3VudChzdHlsZSwgLTEpOwogICAgICBpZiAodXNhZ2VDb3VudCA8PSAwKSB7CiAgICAgICAgdGhpcy5vblN0eWxlUmVtb3ZlZChzdHlsZSk7CiAgICAgIH0KICAgIH0KICB9CiAgbmdPbkRlc3Ryb3koKSB7CiAgICBjb25zdCBzdHlsZU5vZGVzSW5ET00gPSB0aGlzLnN0eWxlTm9kZXNJbkRPTTsKICAgIGlmIChzdHlsZU5vZGVzSW5ET00pIHsKICAgICAgc3R5bGVOb2Rlc0luRE9NLmZvckVhY2goKG5vZGUpID0+IG5vZGUucmVtb3ZlKCkpOwogICAgICBzdHlsZU5vZGVzSW5ET00uY2xlYXIoKTsKICAgIH0KICAgIGZvciAoY29uc3Qgc3R5bGUgb2YgdGhpcy5nZXRBbGxTdHlsZXMoKSkgewogICAgICB0aGlzLm9uU3R5bGVSZW1vdmVkKHN0eWxlKTsKICAgIH0KICAgIHRoaXMucmVzZXRIb3N0Tm9kZXMoKTsKICB9CiAgYWRkSG9zdChob3N0Tm9kZSkgewogICAgdGhpcy5ob3N0Tm9kZXMuYWRkKGhvc3ROb2RlKTsKICAgIGZvciAoY29uc3Qgc3R5bGUgb2YgdGhpcy5nZXRBbGxTdHlsZXMoKSkgewogICAgICB0aGlzLmFkZFN0eWxlVG9Ib3N0KGhvc3ROb2RlLCBzdHlsZSk7CiAgICB9CiAgfQogIHJlbW92ZUhvc3QoaG9zdE5vZGUpIHsKICAgIHRoaXMuaG9zdE5vZGVzLmRlbGV0ZShob3N0Tm9kZSk7CiAgfQogIGdldEFsbFN0eWxlcygpIHsKICAgIHJldHVybiB0aGlzLnN0eWxlUmVmLmtleXMoKTsKICB9CiAgb25TdHlsZUFkZGVkKHN0eWxlKSB7CiAgICBmb3IgKGNvbnN0IGhvc3Qgb2YgdGhpcy5ob3N0Tm9kZXMpIHsKICAgICAgdGhpcy5hZGRTdHlsZVRvSG9zdChob3N0LCBzdHlsZSk7CiAgICB9CiAgfQogIG9uU3R5bGVSZW1vdmVkKHN0eWxlKSB7CiAgICBjb25zdCBzdHlsZVJlZiA9IHRoaXMuc3R5bGVSZWY7CiAgICBzdHlsZVJlZi5nZXQoc3R5bGUpPy5lbGVtZW50cz8uZm9yRWFjaCgobm9kZSkgPT4gbm9kZS5yZW1vdmUoKSk7CiAgICBzdHlsZVJlZi5kZWxldGUoc3R5bGUpOwogIH0KICBjb2xsZWN0U2VydmVyUmVuZGVyZWRTdHlsZXMoKSB7CiAgICBjb25zdCBzdHlsZXMgPSB0aGlzLmRvYy5oZWFkPy5xdWVyeVNlbGVjdG9yQWxsKGBzdHlsZVske0FQUF9JRF9BVFRSSUJVVEVfTkFNRX09IiR7dGhpcy5hcHBJZH0iXWApOwogICAgaWYgKHN0eWxlcz8ubGVuZ3RoKSB7CiAgICAgIGNvbnN0IHN0eWxlTWFwID0gLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKTsKICAgICAgc3R5bGVzLmZvckVhY2goKHN0eWxlKSA9PiB7CiAgICAgICAgaWYgKHN0eWxlLnRleHRDb250ZW50ICE9IG51bGwpIHsKICAgICAgICAgIHN0eWxlTWFwLnNldChzdHlsZS50ZXh0Q29udGVudCwgc3R5bGUpOwogICAgICAgIH0KICAgICAgfSk7CiAgICAgIHJldHVybiBzdHlsZU1hcDsKICAgIH0KICAgIHJldHVybiBudWxsOwogIH0KICBjaGFuZ2VVc2FnZUNvdW50KHN0eWxlLCBkZWx0YSkgewogICAgY29uc3QgbWFwMiA9IHRoaXMuc3R5bGVSZWY7CiAgICBpZiAobWFwMi5oYXMoc3R5bGUpKSB7CiAgICAgIGNvbnN0IHN0eWxlUmVmVmFsdWUgPSBtYXAyLmdldChzdHlsZSk7CiAgICAgIHN0eWxlUmVmVmFsdWUudXNhZ2UgKz0gZGVsdGE7CiAgICAgIHJldHVybiBzdHlsZVJlZlZhbHVlLnVzYWdlOwogICAgfQogICAgbWFwMi5zZXQoc3R5bGUsIHsKICAgICAgdXNhZ2U6IGRlbHRhLAogICAgICBlbGVtZW50czogW10KICAgIH0pOwogICAgcmV0dXJuIGRlbHRhOwogIH0KICBnZXRTdHlsZUVsZW1lbnQoaG9zdCwgc3R5bGUpIHsKICAgIGNvbnN0IHN0eWxlTm9kZXNJbkRPTSA9IHRoaXMuc3R5bGVOb2Rlc0luRE9NOwogICAgY29uc3Qgc3R5bGVFbCA9IHN0eWxlTm9kZXNJbkRPTT8uZ2V0KHN0eWxlKTsKICAgIGlmIChzdHlsZUVsPy5wYXJlbnROb2RlID09PSBob3N0KSB7CiAgICAgIHN0eWxlTm9kZXNJbkRPTS5kZWxldGUoc3R5bGUpOwogICAgICBzdHlsZUVsLnJlbW92ZUF0dHJpYnV0ZShBUFBfSURfQVRUUklCVVRFX05BTUUpOwogICAgICBpZiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSB7CiAgICAgICAgc3R5bGVFbC5zZXRBdHRyaWJ1dGUoIm5nLXN0eWxlLXJldXNlZCIsICIiKTsKICAgICAgfQogICAgICByZXR1cm4gc3R5bGVFbDsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IHN0eWxlRWwyID0gdGhpcy5kb2MuY3JlYXRlRWxlbWVudCgic3R5bGUiKTsKICAgICAgaWYgKHRoaXMubm9uY2UpIHsKICAgICAgICBzdHlsZUVsMi5zZXRBdHRyaWJ1dGUoIm5vbmNlIiwgdGhpcy5ub25jZSk7CiAgICAgIH0KICAgICAgc3R5bGVFbDIudGV4dENvbnRlbnQgPSBzdHlsZTsKICAgICAgaWYgKHRoaXMucGxhdGZvcm1Jc1NlcnZlcikgewogICAgICAgIHN0eWxlRWwyLnNldEF0dHJpYnV0ZShBUFBfSURfQVRUUklCVVRFX05BTUUsIHRoaXMuYXBwSWQpOwogICAgICB9CiAgICAgIGhvc3QuYXBwZW5kQ2hpbGQoc3R5bGVFbDIpOwogICAgICByZXR1cm4gc3R5bGVFbDI7CiAgICB9CiAgfQogIGFkZFN0eWxlVG9Ib3N0KGhvc3QsIHN0eWxlKSB7CiAgICBjb25zdCBzdHlsZUVsID0gdGhpcy5nZXRTdHlsZUVsZW1lbnQoaG9zdCwgc3R5bGUpOwogICAgY29uc3Qgc3R5bGVSZWYgPSB0aGlzLnN0eWxlUmVmOwogICAgY29uc3Qgc3R5bGVFbFJlZiA9IHN0eWxlUmVmLmdldChzdHlsZSk/LmVsZW1lbnRzOwogICAgaWYgKHN0eWxlRWxSZWYpIHsKICAgICAgc3R5bGVFbFJlZi5wdXNoKHN0eWxlRWwpOwogICAgfSBlbHNlIHsKICAgICAgc3R5bGVSZWYuc2V0KHN0eWxlLCB7CiAgICAgICAgZWxlbWVudHM6IFtzdHlsZUVsXSwKICAgICAgICB1c2FnZTogMQogICAgICB9KTsKICAgIH0KICB9CiAgcmVzZXRIb3N0Tm9kZXMoKSB7CiAgICBjb25zdCBob3N0Tm9kZXMgPSB0aGlzLmhvc3ROb2RlczsKICAgIGhvc3ROb2Rlcy5jbGVhcigpOwogICAgaG9zdE5vZGVzLmFkZCh0aGlzLmRvYy5oZWFkKTsKICB9Cn07Cl9TaGFyZWRTdHlsZXNIb3N0Lsm1ZmFjID0gZnVuY3Rpb24gU2hhcmVkU3R5bGVzSG9zdF9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9TaGFyZWRTdHlsZXNIb3N0KSjJtcm1aW5qZWN0KERPQ1VNRU5UKSwgybXJtWluamVjdChBUFBfSUQpLCDJtcm1aW5qZWN0KENTUF9OT05DRSwgOCksIMm1ybVpbmplY3QoUExBVEZPUk1fSUQpKTsKfTsKX1NoYXJlZFN0eWxlc0hvc3QuybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfU2hhcmVkU3R5bGVzSG9zdCwKICBmYWN0b3J5OiBfU2hhcmVkU3R5bGVzSG9zdC7JtWZhYwp9KTsKdmFyIFNoYXJlZFN0eWxlc0hvc3QgPSBfU2hhcmVkU3R5bGVzSG9zdDsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKFNoYXJlZFN0eWxlc0hvc3QsIFt7CiAgICB0eXBlOiBJbmplY3RhYmxlCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiBEb2N1bWVudCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0RPQ1VNRU5UXQogICAgfV0KICB9LCB7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtBUFBfSURdCiAgICB9XQogIH0sIHsKICAgIHR5cGU6IHZvaWQgMCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0NTUF9OT05DRV0KICAgIH0sIHsKICAgICAgdHlwZTogT3B0aW9uYWwKICAgIH1dCiAgfSwgewogICAgdHlwZTogdm9pZCAwLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogSW5qZWN0LAogICAgICBhcmdzOiBbUExBVEZPUk1fSURdCiAgICB9XQogIH1dLCBudWxsKTsKfSkoKTsKdmFyIE5BTUVTUEFDRV9VUklTID0gewogICJzdmciOiAiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciLAogICJ4aHRtbCI6ICJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwKICAieGxpbmsiOiAiaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIsCiAgInhtbCI6ICJodHRwOi8vd3d3LnczLm9yZy9YTUwvMTk5OC9uYW1lc3BhY2UiLAogICJ4bWxucyI6ICJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zLyIsCiAgIm1hdGgiOiAiaHR0cDovL3d3dy53My5vcmcvMTk5OC9NYXRoL01hdGhNTCIKfTsKdmFyIENPTVBPTkVOVF9SRUdFWCA9IC8lQ09NUCUvZzsKdmFyIENPTVBPTkVOVF9WQVJJQUJMRSA9ICIlQ09NUCUiOwp2YXIgSE9TVF9BVFRSID0gYF9uZ2hvc3QtJHtDT01QT05FTlRfVkFSSUFCTEV9YDsKdmFyIENPTlRFTlRfQVRUUiA9IGBfbmdjb250ZW50LSR7Q09NUE9ORU5UX1ZBUklBQkxFfWA7CnZhciBSRU1PVkVfU1RZTEVTX09OX0NPTVBPTkVOVF9ERVNUUk9ZX0RFRkFVTFQgPSB0cnVlOwp2YXIgUkVNT1ZFX1NUWUxFU19PTl9DT01QT05FTlRfREVTVFJPWSA9IG5ldyBJbmplY3Rpb25Ub2tlbihuZ0Rldk1vZGUgPyAiUmVtb3ZlU3R5bGVzT25Db21wRGVzdHJveSIgOiAiIiwgewogIHByb3ZpZGVkSW46ICJyb290IiwKICBmYWN0b3J5OiAoKSA9PiBSRU1PVkVfU1RZTEVTX09OX0NPTVBPTkVOVF9ERVNUUk9ZX0RFRkFVTFQKfSk7CmZ1bmN0aW9uIHNoaW1Db250ZW50QXR0cmlidXRlKGNvbXBvbmVudFNob3J0SWQpIHsKICByZXR1cm4gQ09OVEVOVF9BVFRSLnJlcGxhY2UoQ09NUE9ORU5UX1JFR0VYLCBjb21wb25lbnRTaG9ydElkKTsKfQpmdW5jdGlvbiBzaGltSG9zdEF0dHJpYnV0ZShjb21wb25lbnRTaG9ydElkKSB7CiAgcmV0dXJuIEhPU1RfQVRUUi5yZXBsYWNlKENPTVBPTkVOVF9SRUdFWCwgY29tcG9uZW50U2hvcnRJZCk7Cn0KZnVuY3Rpb24gc2hpbVN0eWxlc0NvbnRlbnQoY29tcElkLCBzdHlsZXMpIHsKICByZXR1cm4gc3R5bGVzLm1hcCgocykgPT4gcy5yZXBsYWNlKENPTVBPTkVOVF9SRUdFWCwgY29tcElkKSk7Cn0KdmFyIF9Eb21SZW5kZXJlckZhY3RvcnkyID0gY2xhc3MgX0RvbVJlbmRlcmVyRmFjdG9yeTIgewogIGNvbnN0cnVjdG9yKGV2ZW50TWFuYWdlciwgc2hhcmVkU3R5bGVzSG9zdCwgYXBwSWQsIHJlbW92ZVN0eWxlc09uQ29tcERlc3Ryb3ksIGRvYywgcGxhdGZvcm1JZCwgbmdab25lLCBub25jZSA9IG51bGwpIHsKICAgIHRoaXMuZXZlbnRNYW5hZ2VyID0gZXZlbnRNYW5hZ2VyOwogICAgdGhpcy5zaGFyZWRTdHlsZXNIb3N0ID0gc2hhcmVkU3R5bGVzSG9zdDsKICAgIHRoaXMuYXBwSWQgPSBhcHBJZDsKICAgIHRoaXMucmVtb3ZlU3R5bGVzT25Db21wRGVzdHJveSA9IHJlbW92ZVN0eWxlc09uQ29tcERlc3Ryb3k7CiAgICB0aGlzLmRvYyA9IGRvYzsKICAgIHRoaXMucGxhdGZvcm1JZCA9IHBsYXRmb3JtSWQ7CiAgICB0aGlzLm5nWm9uZSA9IG5nWm9uZTsKICAgIHRoaXMubm9uY2UgPSBub25jZTsKICAgIHRoaXMucmVuZGVyZXJCeUNvbXBJZCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7CiAgICB0aGlzLnBsYXRmb3JtSXNTZXJ2ZXIgPSBpc1BsYXRmb3JtU2VydmVyKHBsYXRmb3JtSWQpOwogICAgdGhpcy5kZWZhdWx0UmVuZGVyZXIgPSBuZXcgRGVmYXVsdERvbVJlbmRlcmVyMihldmVudE1hbmFnZXIsIGRvYywgbmdab25lLCB0aGlzLnBsYXRmb3JtSXNTZXJ2ZXIpOwogIH0KICBjcmVhdGVSZW5kZXJlcihlbGVtZW50LCB0eXBlKSB7CiAgICBpZiAoIWVsZW1lbnQgfHwgIXR5cGUpIHsKICAgICAgcmV0dXJuIHRoaXMuZGVmYXVsdFJlbmRlcmVyOwogICAgfQogICAgaWYgKHRoaXMucGxhdGZvcm1Jc1NlcnZlciAmJiB0eXBlLmVuY2Fwc3VsYXRpb24gPT09IFZpZXdFbmNhcHN1bGF0aW9uJDEuU2hhZG93RG9tKSB7CiAgICAgIHR5cGUgPSBfX3NwcmVhZFByb3BzKF9fc3ByZWFkVmFsdWVzKHt9LCB0eXBlKSwgewogICAgICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uJDEuRW11bGF0ZWQKICAgICAgfSk7CiAgICB9CiAgICBjb25zdCByZW5kZXJlciA9IHRoaXMuZ2V0T3JDcmVhdGVSZW5kZXJlcihlbGVtZW50LCB0eXBlKTsKICAgIGlmIChyZW5kZXJlciBpbnN0YW5jZW9mIEVtdWxhdGVkRW5jYXBzdWxhdGlvbkRvbVJlbmRlcmVyMikgewogICAgICByZW5kZXJlci5hcHBseVRvSG9zdChlbGVtZW50KTsKICAgIH0gZWxzZSBpZiAocmVuZGVyZXIgaW5zdGFuY2VvZiBOb25lRW5jYXBzdWxhdGlvbkRvbVJlbmRlcmVyKSB7CiAgICAgIHJlbmRlcmVyLmFwcGx5U3R5bGVzKCk7CiAgICB9CiAgICByZXR1cm4gcmVuZGVyZXI7CiAgfQogIGdldE9yQ3JlYXRlUmVuZGVyZXIoZWxlbWVudCwgdHlwZSkgewogICAgY29uc3QgcmVuZGVyZXJCeUNvbXBJZCA9IHRoaXMucmVuZGVyZXJCeUNvbXBJZDsKICAgIGxldCByZW5kZXJlciA9IHJlbmRlcmVyQnlDb21wSWQuZ2V0KHR5cGUuaWQpOwogICAgaWYgKCFyZW5kZXJlcikgewogICAgICBjb25zdCBkb2MgPSB0aGlzLmRvYzsKICAgICAgY29uc3Qgbmdab25lID0gdGhpcy5uZ1pvbmU7CiAgICAgIGNvbnN0IGV2ZW50TWFuYWdlciA9IHRoaXMuZXZlbnRNYW5hZ2VyOwogICAgICBjb25zdCBzaGFyZWRTdHlsZXNIb3N0ID0gdGhpcy5zaGFyZWRTdHlsZXNIb3N0OwogICAgICBjb25zdCByZW1vdmVTdHlsZXNPbkNvbXBEZXN0cm95ID0gdGhpcy5yZW1vdmVTdHlsZXNPbkNvbXBEZXN0cm95OwogICAgICBjb25zdCBwbGF0Zm9ybUlzU2VydmVyID0gdGhpcy5wbGF0Zm9ybUlzU2VydmVyOwogICAgICBzd2l0Y2ggKHR5cGUuZW5jYXBzdWxhdGlvbikgewogICAgICAgIGNhc2UgVmlld0VuY2Fwc3VsYXRpb24kMS5FbXVsYXRlZDoKICAgICAgICAgIHJlbmRlcmVyID0gbmV3IEVtdWxhdGVkRW5jYXBzdWxhdGlvbkRvbVJlbmRlcmVyMihldmVudE1hbmFnZXIsIHNoYXJlZFN0eWxlc0hvc3QsIHR5cGUsIHRoaXMuYXBwSWQsIHJlbW92ZVN0eWxlc09uQ29tcERlc3Ryb3ksIGRvYywgbmdab25lLCBwbGF0Zm9ybUlzU2VydmVyKTsKICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVmlld0VuY2Fwc3VsYXRpb24kMS5TaGFkb3dEb206CiAgICAgICAgICByZXR1cm4gbmV3IFNoYWRvd0RvbVJlbmRlcmVyKGV2ZW50TWFuYWdlciwgc2hhcmVkU3R5bGVzSG9zdCwgZWxlbWVudCwgdHlwZSwgZG9jLCBuZ1pvbmUsIHRoaXMubm9uY2UsIHBsYXRmb3JtSXNTZXJ2ZXIpOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZW5kZXJlciA9IG5ldyBOb25lRW5jYXBzdWxhdGlvbkRvbVJlbmRlcmVyKGV2ZW50TWFuYWdlciwgc2hhcmVkU3R5bGVzSG9zdCwgdHlwZSwgcmVtb3ZlU3R5bGVzT25Db21wRGVzdHJveSwgZG9jLCBuZ1pvbmUsIHBsYXRmb3JtSXNTZXJ2ZXIpOwogICAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgcmVuZGVyZXJCeUNvbXBJZC5zZXQodHlwZS5pZCwgcmVuZGVyZXIpOwogICAgfQogICAgcmV0dXJuIHJlbmRlcmVyOwogIH0KICBuZ09uRGVzdHJveSgpIHsKICAgIHRoaXMucmVuZGVyZXJCeUNvbXBJZC5jbGVhcigpOwogIH0KfTsKX0RvbVJlbmRlcmVyRmFjdG9yeTIuybVmYWMgPSBmdW5jdGlvbiBEb21SZW5kZXJlckZhY3RvcnkyX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0RvbVJlbmRlcmVyRmFjdG9yeTIpKMm1ybVpbmplY3QoRXZlbnRNYW5hZ2VyKSwgybXJtWluamVjdChTaGFyZWRTdHlsZXNIb3N0KSwgybXJtWluamVjdChBUFBfSUQpLCDJtcm1aW5qZWN0KFJFTU9WRV9TVFlMRVNfT05fQ09NUE9ORU5UX0RFU1RST1kpLCDJtcm1aW5qZWN0KERPQ1VNRU5UKSwgybXJtWluamVjdChQTEFURk9STV9JRCksIMm1ybVpbmplY3QoTmdab25lKSwgybXJtWluamVjdChDU1BfTk9OQ0UpKTsKfTsKX0RvbVJlbmRlcmVyRmFjdG9yeTIuybVwcm92ID0gybXJtWRlZmluZUluamVjdGFibGUoewogIHRva2VuOiBfRG9tUmVuZGVyZXJGYWN0b3J5MiwKICBmYWN0b3J5OiBfRG9tUmVuZGVyZXJGYWN0b3J5Mi7JtWZhYwp9KTsKdmFyIERvbVJlbmRlcmVyRmFjdG9yeTIgPSBfRG9tUmVuZGVyZXJGYWN0b3J5MjsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKERvbVJlbmRlcmVyRmFjdG9yeTIsIFt7CiAgICB0eXBlOiBJbmplY3RhYmxlCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiBFdmVudE1hbmFnZXIKICB9LCB7CiAgICB0eXBlOiBTaGFyZWRTdHlsZXNIb3N0CiAgfSwgewogICAgdHlwZTogdm9pZCAwLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogSW5qZWN0LAogICAgICBhcmdzOiBbQVBQX0lEXQogICAgfV0KICB9LCB7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtSRU1PVkVfU1RZTEVTX09OX0NPTVBPTkVOVF9ERVNUUk9ZXQogICAgfV0KICB9LCB7CiAgICB0eXBlOiBEb2N1bWVudCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0RPQ1VNRU5UXQogICAgfV0KICB9LCB7CiAgICB0eXBlOiBPYmplY3QsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtQTEFURk9STV9JRF0KICAgIH1dCiAgfSwgewogICAgdHlwZTogTmdab25lCiAgfSwgewogICAgdHlwZTogdm9pZCAwLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogSW5qZWN0LAogICAgICBhcmdzOiBbQ1NQX05PTkNFXQogICAgfV0KICB9XSwgbnVsbCk7Cn0pKCk7CnZhciBEZWZhdWx0RG9tUmVuZGVyZXIyID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKGV2ZW50TWFuYWdlciwgZG9jLCBuZ1pvbmUsIHBsYXRmb3JtSXNTZXJ2ZXIpIHsKICAgIHRoaXMuZXZlbnRNYW5hZ2VyID0gZXZlbnRNYW5hZ2VyOwogICAgdGhpcy5kb2MgPSBkb2M7CiAgICB0aGlzLm5nWm9uZSA9IG5nWm9uZTsKICAgIHRoaXMucGxhdGZvcm1Jc1NlcnZlciA9IHBsYXRmb3JtSXNTZXJ2ZXI7CiAgICB0aGlzLmRhdGEgPSAvKiBAX19QVVJFX18gKi8gT2JqZWN0LmNyZWF0ZShudWxsKTsKICAgIHRoaXMudGhyb3dPblN5bnRoZXRpY1Byb3BzID0gdHJ1ZTsKICAgIHRoaXMuZGVzdHJveU5vZGUgPSBudWxsOwogIH0KICBkZXN0cm95KCkgewogIH0KICBjcmVhdGVFbGVtZW50KG5hbWUsIG5hbWVzcGFjZSkgewogICAgaWYgKG5hbWVzcGFjZSkgewogICAgICByZXR1cm4gdGhpcy5kb2MuY3JlYXRlRWxlbWVudE5TKE5BTUVTUEFDRV9VUklTW25hbWVzcGFjZV0gfHwgbmFtZXNwYWNlLCBuYW1lKTsKICAgIH0KICAgIHJldHVybiB0aGlzLmRvYy5jcmVhdGVFbGVtZW50KG5hbWUpOwogIH0KICBjcmVhdGVDb21tZW50KHZhbHVlKSB7CiAgICByZXR1cm4gdGhpcy5kb2MuY3JlYXRlQ29tbWVudCh2YWx1ZSk7CiAgfQogIGNyZWF0ZVRleHQodmFsdWUpIHsKICAgIHJldHVybiB0aGlzLmRvYy5jcmVhdGVUZXh0Tm9kZSh2YWx1ZSk7CiAgfQogIGFwcGVuZENoaWxkKHBhcmVudCwgbmV3Q2hpbGQpIHsKICAgIGNvbnN0IHRhcmdldFBhcmVudCA9IGlzVGVtcGxhdGVOb2RlKHBhcmVudCkgPyBwYXJlbnQuY29udGVudCA6IHBhcmVudDsKICAgIHRhcmdldFBhcmVudC5hcHBlbmRDaGlsZChuZXdDaGlsZCk7CiAgfQogIGluc2VydEJlZm9yZShwYXJlbnQsIG5ld0NoaWxkLCByZWZDaGlsZCkgewogICAgaWYgKHBhcmVudCkgewogICAgICBjb25zdCB0YXJnZXRQYXJlbnQgPSBpc1RlbXBsYXRlTm9kZShwYXJlbnQpID8gcGFyZW50LmNvbnRlbnQgOiBwYXJlbnQ7CiAgICAgIHRhcmdldFBhcmVudC5pbnNlcnRCZWZvcmUobmV3Q2hpbGQsIHJlZkNoaWxkKTsKICAgIH0KICB9CiAgcmVtb3ZlQ2hpbGQocGFyZW50LCBvbGRDaGlsZCkgewogICAgaWYgKHBhcmVudCkgewogICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQob2xkQ2hpbGQpOwogICAgfQogIH0KICBzZWxlY3RSb290RWxlbWVudChzZWxlY3Rvck9yTm9kZSwgcHJlc2VydmVDb250ZW50KSB7CiAgICBsZXQgZWwgPSB0eXBlb2Ygc2VsZWN0b3JPck5vZGUgPT09ICJzdHJpbmciID8gdGhpcy5kb2MucXVlcnlTZWxlY3RvcihzZWxlY3Rvck9yTm9kZSkgOiBzZWxlY3Rvck9yTm9kZTsKICAgIGlmICghZWwpIHsKICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcigtNTEwNCwgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgYFRoZSBzZWxlY3RvciAiJHtzZWxlY3Rvck9yTm9kZX0iIGRpZCBub3QgbWF0Y2ggYW55IGVsZW1lbnRzYCk7CiAgICB9CiAgICBpZiAoIXByZXNlcnZlQ29udGVudCkgewogICAgICBlbC50ZXh0Q29udGVudCA9ICIiOwogICAgfQogICAgcmV0dXJuIGVsOwogIH0KICBwYXJlbnROb2RlKG5vZGUpIHsKICAgIHJldHVybiBub2RlLnBhcmVudE5vZGU7CiAgfQogIG5leHRTaWJsaW5nKG5vZGUpIHsKICAgIHJldHVybiBub2RlLm5leHRTaWJsaW5nOwogIH0KICBzZXRBdHRyaWJ1dGUoZWwsIG5hbWUsIHZhbHVlLCBuYW1lc3BhY2UpIHsKICAgIGlmIChuYW1lc3BhY2UpIHsKICAgICAgbmFtZSA9IG5hbWVzcGFjZSArICI6IiArIG5hbWU7CiAgICAgIGNvbnN0IG5hbWVzcGFjZVVyaSA9IE5BTUVTUEFDRV9VUklTW25hbWVzcGFjZV07CiAgICAgIGlmIChuYW1lc3BhY2VVcmkpIHsKICAgICAgICBlbC5zZXRBdHRyaWJ1dGVOUyhuYW1lc3BhY2VVcmksIG5hbWUsIHZhbHVlKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBlbC5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBlbC5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpOwogICAgfQogIH0KICByZW1vdmVBdHRyaWJ1dGUoZWwsIG5hbWUsIG5hbWVzcGFjZSkgewogICAgaWYgKG5hbWVzcGFjZSkgewogICAgICBjb25zdCBuYW1lc3BhY2VVcmkgPSBOQU1FU1BBQ0VfVVJJU1tuYW1lc3BhY2VdOwogICAgICBpZiAobmFtZXNwYWNlVXJpKSB7CiAgICAgICAgZWwucmVtb3ZlQXR0cmlidXRlTlMobmFtZXNwYWNlVXJpLCBuYW1lKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBlbC5yZW1vdmVBdHRyaWJ1dGUoYCR7bmFtZXNwYWNlfToke25hbWV9YCk7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGVsLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTsKICAgIH0KICB9CiAgYWRkQ2xhc3MoZWwsIG5hbWUpIHsKICAgIGVsLmNsYXNzTGlzdC5hZGQobmFtZSk7CiAgfQogIHJlbW92ZUNsYXNzKGVsLCBuYW1lKSB7CiAgICBlbC5jbGFzc0xpc3QucmVtb3ZlKG5hbWUpOwogIH0KICBzZXRTdHlsZShlbCwgc3R5bGUsIHZhbHVlLCBmbGFncykgewogICAgaWYgKGZsYWdzICYgKFJlbmRlcmVyU3R5bGVGbGFnczIuRGFzaENhc2UgfCBSZW5kZXJlclN0eWxlRmxhZ3MyLkltcG9ydGFudCkpIHsKICAgICAgZWwuc3R5bGUuc2V0UHJvcGVydHkoc3R5bGUsIHZhbHVlLCBmbGFncyAmIFJlbmRlcmVyU3R5bGVGbGFnczIuSW1wb3J0YW50ID8gImltcG9ydGFudCIgOiAiIik7CiAgICB9IGVsc2UgewogICAgICBlbC5zdHlsZVtzdHlsZV0gPSB2YWx1ZTsKICAgIH0KICB9CiAgcmVtb3ZlU3R5bGUoZWwsIHN0eWxlLCBmbGFncykgewogICAgaWYgKGZsYWdzICYgUmVuZGVyZXJTdHlsZUZsYWdzMi5EYXNoQ2FzZSkgewogICAgICBlbC5zdHlsZS5yZW1vdmVQcm9wZXJ0eShzdHlsZSk7CiAgICB9IGVsc2UgewogICAgICBlbC5zdHlsZVtzdHlsZV0gPSAiIjsKICAgIH0KICB9CiAgc2V0UHJvcGVydHkoZWwsIG5hbWUsIHZhbHVlKSB7CiAgICBpZiAoZWwgPT0gbnVsbCkgewogICAgICByZXR1cm47CiAgICB9CiAgICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiB0aGlzLnRocm93T25TeW50aGV0aWNQcm9wcyAmJiBjaGVja05vU3ludGhldGljUHJvcChuYW1lLCAicHJvcGVydHkiKTsKICAgIGVsW25hbWVdID0gdmFsdWU7CiAgfQogIHNldFZhbHVlKG5vZGUsIHZhbHVlKSB7CiAgICBub2RlLm5vZGVWYWx1ZSA9IHZhbHVlOwogIH0KICBsaXN0ZW4odGFyZ2V0LCBldmVudCwgY2FsbGJhY2spIHsKICAgICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHRoaXMudGhyb3dPblN5bnRoZXRpY1Byb3BzICYmIGNoZWNrTm9TeW50aGV0aWNQcm9wKGV2ZW50LCAibGlzdGVuZXIiKTsKICAgIGlmICh0eXBlb2YgdGFyZ2V0ID09PSAic3RyaW5nIikgewogICAgICB0YXJnZXQgPSBnZXRET00oKS5nZXRHbG9iYWxFdmVudFRhcmdldCh0aGlzLmRvYywgdGFyZ2V0KTsKICAgICAgaWYgKCF0YXJnZXQpIHsKICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGV2ZW50IHRhcmdldCAke3RhcmdldH0gZm9yIGV2ZW50ICR7ZXZlbnR9YCk7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB0aGlzLmV2ZW50TWFuYWdlci5hZGRFdmVudExpc3RlbmVyKHRhcmdldCwgZXZlbnQsIHRoaXMuZGVjb3JhdGVQcmV2ZW50RGVmYXVsdChjYWxsYmFjaykpOwogIH0KICBkZWNvcmF0ZVByZXZlbnREZWZhdWx0KGV2ZW50SGFuZGxlcikgewogICAgcmV0dXJuIChldmVudCkgPT4gewogICAgICBpZiAoZXZlbnQgPT09ICJfX25nVW53cmFwX18iKSB7CiAgICAgICAgcmV0dXJuIGV2ZW50SGFuZGxlcjsKICAgICAgfQogICAgICBjb25zdCBhbGxvd0RlZmF1bHRCZWhhdmlvciA9IHRoaXMucGxhdGZvcm1Jc1NlcnZlciA/IHRoaXMubmdab25lLnJ1bkd1YXJkZWQoKCkgPT4gZXZlbnRIYW5kbGVyKGV2ZW50KSkgOiBldmVudEhhbmRsZXIoZXZlbnQpOwogICAgICBpZiAoYWxsb3dEZWZhdWx0QmVoYXZpb3IgPT09IGZhbHNlKSB7CiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgICAgfQogICAgICByZXR1cm4gdm9pZCAwOwogICAgfTsKICB9Cn07CnZhciBBVF9DSEFSQ09ERSA9ICgoKSA9PiAiQCIuY2hhckNvZGVBdCgwKSkoKTsKZnVuY3Rpb24gY2hlY2tOb1N5bnRoZXRpY1Byb3AobmFtZSwgbmFtZUtpbmQpIHsKICBpZiAobmFtZS5jaGFyQ29kZUF0KDApID09PSBBVF9DSEFSQ09ERSkgewogICAgdGhyb3cgbmV3IFJ1bnRpbWVFcnJvcig1MTA1LCBgVW5leHBlY3RlZCBzeW50aGV0aWMgJHtuYW1lS2luZH0gJHtuYW1lfSBmb3VuZC4gUGxlYXNlIG1ha2Ugc3VyZSB0aGF0OgogIC0gRWl0aGVyIFxgQnJvd3NlckFuaW1hdGlvbnNNb2R1bGVcYCBvciBcYE5vb3BBbmltYXRpb25zTW9kdWxlXGAgYXJlIGltcG9ydGVkIGluIHlvdXIgYXBwbGljYXRpb24uCiAgLSBUaGVyZSBpcyBjb3JyZXNwb25kaW5nIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBhbmltYXRpb24gbmFtZWQgXGAke25hbWV9XGAgZGVmaW5lZCBpbiB0aGUgXGBhbmltYXRpb25zXGAgZmllbGQgb2YgdGhlIFxgQENvbXBvbmVudFxgIGRlY29yYXRvciAoc2VlIGh0dHBzOi8vYW5ndWxhci5pby9hcGkvY29yZS9Db21wb25lbnQjYW5pbWF0aW9ucykuYCk7CiAgfQp9CmZ1bmN0aW9uIGlzVGVtcGxhdGVOb2RlKG5vZGUpIHsKICByZXR1cm4gbm9kZS50YWdOYW1lID09PSAiVEVNUExBVEUiICYmIG5vZGUuY29udGVudCAhPT0gdm9pZCAwOwp9CnZhciBTaGFkb3dEb21SZW5kZXJlciA9IGNsYXNzIGV4dGVuZHMgRGVmYXVsdERvbVJlbmRlcmVyMiB7CiAgY29uc3RydWN0b3IoZXZlbnRNYW5hZ2VyLCBzaGFyZWRTdHlsZXNIb3N0LCBob3N0RWwsIGNvbXBvbmVudCwgZG9jLCBuZ1pvbmUsIG5vbmNlLCBwbGF0Zm9ybUlzU2VydmVyKSB7CiAgICBzdXBlcihldmVudE1hbmFnZXIsIGRvYywgbmdab25lLCBwbGF0Zm9ybUlzU2VydmVyKTsKICAgIHRoaXMuc2hhcmVkU3R5bGVzSG9zdCA9IHNoYXJlZFN0eWxlc0hvc3Q7CiAgICB0aGlzLmhvc3RFbCA9IGhvc3RFbDsKICAgIHRoaXMuc2hhZG93Um9vdCA9IGhvc3RFbC5hdHRhY2hTaGFkb3coewogICAgICBtb2RlOiAib3BlbiIKICAgIH0pOwogICAgdGhpcy5zaGFyZWRTdHlsZXNIb3N0LmFkZEhvc3QodGhpcy5zaGFkb3dSb290KTsKICAgIGNvbnN0IHN0eWxlcyA9IHNoaW1TdHlsZXNDb250ZW50KGNvbXBvbmVudC5pZCwgY29tcG9uZW50LnN0eWxlcyk7CiAgICBmb3IgKGNvbnN0IHN0eWxlIG9mIHN0eWxlcykgewogICAgICBjb25zdCBzdHlsZUVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3R5bGUiKTsKICAgICAgaWYgKG5vbmNlKSB7CiAgICAgICAgc3R5bGVFbC5zZXRBdHRyaWJ1dGUoIm5vbmNlIiwgbm9uY2UpOwogICAgICB9CiAgICAgIHN0eWxlRWwudGV4dENvbnRlbnQgPSBzdHlsZTsKICAgICAgdGhpcy5zaGFkb3dSb290LmFwcGVuZENoaWxkKHN0eWxlRWwpOwogICAgfQogIH0KICBub2RlT3JTaGFkb3dSb290KG5vZGUpIHsKICAgIHJldHVybiBub2RlID09PSB0aGlzLmhvc3RFbCA/IHRoaXMuc2hhZG93Um9vdCA6IG5vZGU7CiAgfQogIGFwcGVuZENoaWxkKHBhcmVudCwgbmV3Q2hpbGQpIHsKICAgIHJldHVybiBzdXBlci5hcHBlbmRDaGlsZCh0aGlzLm5vZGVPclNoYWRvd1Jvb3QocGFyZW50KSwgbmV3Q2hpbGQpOwogIH0KICBpbnNlcnRCZWZvcmUocGFyZW50LCBuZXdDaGlsZCwgcmVmQ2hpbGQpIHsKICAgIHJldHVybiBzdXBlci5pbnNlcnRCZWZvcmUodGhpcy5ub2RlT3JTaGFkb3dSb290KHBhcmVudCksIG5ld0NoaWxkLCByZWZDaGlsZCk7CiAgfQogIHJlbW92ZUNoaWxkKHBhcmVudCwgb2xkQ2hpbGQpIHsKICAgIHJldHVybiBzdXBlci5yZW1vdmVDaGlsZCh0aGlzLm5vZGVPclNoYWRvd1Jvb3QocGFyZW50KSwgb2xkQ2hpbGQpOwogIH0KICBwYXJlbnROb2RlKG5vZGUpIHsKICAgIHJldHVybiB0aGlzLm5vZGVPclNoYWRvd1Jvb3Qoc3VwZXIucGFyZW50Tm9kZSh0aGlzLm5vZGVPclNoYWRvd1Jvb3Qobm9kZSkpKTsKICB9CiAgZGVzdHJveSgpIHsKICAgIHRoaXMuc2hhcmVkU3R5bGVzSG9zdC5yZW1vdmVIb3N0KHRoaXMuc2hhZG93Um9vdCk7CiAgfQp9Owp2YXIgTm9uZUVuY2Fwc3VsYXRpb25Eb21SZW5kZXJlciA9IGNsYXNzIGV4dGVuZHMgRGVmYXVsdERvbVJlbmRlcmVyMiB7CiAgY29uc3RydWN0b3IoZXZlbnRNYW5hZ2VyLCBzaGFyZWRTdHlsZXNIb3N0LCBjb21wb25lbnQsIHJlbW92ZVN0eWxlc09uQ29tcERlc3Ryb3ksIGRvYywgbmdab25lLCBwbGF0Zm9ybUlzU2VydmVyLCBjb21wSWQpIHsKICAgIHN1cGVyKGV2ZW50TWFuYWdlciwgZG9jLCBuZ1pvbmUsIHBsYXRmb3JtSXNTZXJ2ZXIpOwogICAgdGhpcy5zaGFyZWRTdHlsZXNIb3N0ID0gc2hhcmVkU3R5bGVzSG9zdDsKICAgIHRoaXMucmVtb3ZlU3R5bGVzT25Db21wRGVzdHJveSA9IHJlbW92ZVN0eWxlc09uQ29tcERlc3Ryb3k7CiAgICB0aGlzLnN0eWxlcyA9IGNvbXBJZCA/IHNoaW1TdHlsZXNDb250ZW50KGNvbXBJZCwgY29tcG9uZW50LnN0eWxlcykgOiBjb21wb25lbnQuc3R5bGVzOwogIH0KICBhcHBseVN0eWxlcygpIHsKICAgIHRoaXMuc2hhcmVkU3R5bGVzSG9zdC5hZGRTdHlsZXModGhpcy5zdHlsZXMpOwogIH0KICBkZXN0cm95KCkgewogICAgaWYgKCF0aGlzLnJlbW92ZVN0eWxlc09uQ29tcERlc3Ryb3kpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5zaGFyZWRTdHlsZXNIb3N0LnJlbW92ZVN0eWxlcyh0aGlzLnN0eWxlcyk7CiAgfQp9Owp2YXIgRW11bGF0ZWRFbmNhcHN1bGF0aW9uRG9tUmVuZGVyZXIyID0gY2xhc3MgZXh0ZW5kcyBOb25lRW5jYXBzdWxhdGlvbkRvbVJlbmRlcmVyIHsKICBjb25zdHJ1Y3RvcihldmVudE1hbmFnZXIsIHNoYXJlZFN0eWxlc0hvc3QsIGNvbXBvbmVudCwgYXBwSWQsIHJlbW92ZVN0eWxlc09uQ29tcERlc3Ryb3ksIGRvYywgbmdab25lLCBwbGF0Zm9ybUlzU2VydmVyKSB7CiAgICBjb25zdCBjb21wSWQgPSBhcHBJZCArICItIiArIGNvbXBvbmVudC5pZDsKICAgIHN1cGVyKGV2ZW50TWFuYWdlciwgc2hhcmVkU3R5bGVzSG9zdCwgY29tcG9uZW50LCByZW1vdmVTdHlsZXNPbkNvbXBEZXN0cm95LCBkb2MsIG5nWm9uZSwgcGxhdGZvcm1Jc1NlcnZlciwgY29tcElkKTsKICAgIHRoaXMuY29udGVudEF0dHIgPSBzaGltQ29udGVudEF0dHJpYnV0ZShjb21wSWQpOwogICAgdGhpcy5ob3N0QXR0ciA9IHNoaW1Ib3N0QXR0cmlidXRlKGNvbXBJZCk7CiAgfQogIGFwcGx5VG9Ib3N0KGVsZW1lbnQpIHsKICAgIHRoaXMuYXBwbHlTdHlsZXMoKTsKICAgIHRoaXMuc2V0QXR0cmlidXRlKGVsZW1lbnQsIHRoaXMuaG9zdEF0dHIsICIiKTsKICB9CiAgY3JlYXRlRWxlbWVudChwYXJlbnQsIG5hbWUpIHsKICAgIGNvbnN0IGVsID0gc3VwZXIuY3JlYXRlRWxlbWVudChwYXJlbnQsIG5hbWUpOwogICAgc3VwZXIuc2V0QXR0cmlidXRlKGVsLCB0aGlzLmNvbnRlbnRBdHRyLCAiIik7CiAgICByZXR1cm4gZWw7CiAgfQp9Owp2YXIgX0RvbUV2ZW50c1BsdWdpbiA9IGNsYXNzIF9Eb21FdmVudHNQbHVnaW4gZXh0ZW5kcyBFdmVudE1hbmFnZXJQbHVnaW4gewogIGNvbnN0cnVjdG9yKGRvYykgewogICAgc3VwZXIoZG9jKTsKICB9CiAgLy8gVGhpcyBwbHVnaW4gc2hvdWxkIGNvbWUgbGFzdCBpbiB0aGUgbGlzdCBvZiBwbHVnaW5zLCBiZWNhdXNlIGl0IGFjY2VwdHMgYWxsCiAgLy8gZXZlbnRzLgogIHN1cHBvcnRzKGV2ZW50TmFtZSkgewogICAgcmV0dXJuIHRydWU7CiAgfQogIGFkZEV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7CiAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBoYW5kbGVyLCBmYWxzZSk7CiAgICByZXR1cm4gKCkgPT4gdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50TmFtZSwgaGFuZGxlcik7CiAgfQogIHJlbW92ZUV2ZW50TGlzdGVuZXIodGFyZ2V0LCBldmVudE5hbWUsIGNhbGxiYWNrKSB7CiAgICByZXR1cm4gdGFyZ2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnROYW1lLCBjYWxsYmFjayk7CiAgfQp9OwpfRG9tRXZlbnRzUGx1Z2luLsm1ZmFjID0gZnVuY3Rpb24gRG9tRXZlbnRzUGx1Z2luX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0RvbUV2ZW50c1BsdWdpbikoybXJtWluamVjdChET0NVTUVOVCkpOwp9OwpfRG9tRXZlbnRzUGx1Z2luLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX0RvbUV2ZW50c1BsdWdpbiwKICBmYWN0b3J5OiBfRG9tRXZlbnRzUGx1Z2luLsm1ZmFjCn0pOwp2YXIgRG9tRXZlbnRzUGx1Z2luID0gX0RvbUV2ZW50c1BsdWdpbjsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKERvbUV2ZW50c1BsdWdpbiwgW3sKICAgIHR5cGU6IEluamVjdGFibGUKICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IHZvaWQgMCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0RPQ1VNRU5UXQogICAgfV0KICB9XSwgbnVsbCk7Cn0pKCk7CnZhciBNT0RJRklFUl9LRVlTID0gWyJhbHQiLCAiY29udHJvbCIsICJtZXRhIiwgInNoaWZ0Il07CnZhciBfa2V5TWFwID0gewogICJcYiI6ICJCYWNrc3BhY2UiLAogICIJIjogIlRhYiIsCiAgIn8iOiAiRGVsZXRlIiwKICAiXHgxQiI6ICJFc2NhcGUiLAogICJEZWwiOiAiRGVsZXRlIiwKICAiRXNjIjogIkVzY2FwZSIsCiAgIkxlZnQiOiAiQXJyb3dMZWZ0IiwKICAiUmlnaHQiOiAiQXJyb3dSaWdodCIsCiAgIlVwIjogIkFycm93VXAiLAogICJEb3duIjogIkFycm93RG93biIsCiAgIk1lbnUiOiAiQ29udGV4dE1lbnUiLAogICJTY3JvbGwiOiAiU2Nyb2xsTG9jayIsCiAgIldpbiI6ICJPUyIKfTsKdmFyIE1PRElGSUVSX0tFWV9HRVRURVJTID0gewogICJhbHQiOiAoZXZlbnQpID0+IGV2ZW50LmFsdEtleSwKICAiY29udHJvbCI6IChldmVudCkgPT4gZXZlbnQuY3RybEtleSwKICAibWV0YSI6IChldmVudCkgPT4gZXZlbnQubWV0YUtleSwKICAic2hpZnQiOiAoZXZlbnQpID0+IGV2ZW50LnNoaWZ0S2V5Cn07CnZhciBfS2V5RXZlbnRzUGx1Z2luID0gY2xhc3MgX0tleUV2ZW50c1BsdWdpbiBleHRlbmRzIEV2ZW50TWFuYWdlclBsdWdpbiB7CiAgLyoqCiAgICogSW5pdGlhbGl6ZXMgYW4gaW5zdGFuY2Ugb2YgdGhlIGJyb3dzZXIgcGx1Zy1pbi4KICAgKiBAcGFyYW0gZG9jIFRoZSBkb2N1bWVudCBpbiB3aGljaCBrZXkgZXZlbnRzIHdpbGwgYmUgZGV0ZWN0ZWQuCiAgICovCiAgY29uc3RydWN0b3IoZG9jKSB7CiAgICBzdXBlcihkb2MpOwogIH0KICAvKioKICAgKiBSZXBvcnRzIHdoZXRoZXIgYSBuYW1lZCBrZXkgZXZlbnQgaXMgc3VwcG9ydGVkLgogICAqIEBwYXJhbSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUgdG8gcXVlcnkuCiAgICogQHJldHVybiBUcnVlIGlmIHRoZSBuYW1lZCBrZXkgZXZlbnQgaXMgc3VwcG9ydGVkLgogICAqLwogIHN1cHBvcnRzKGV2ZW50TmFtZSkgewogICAgcmV0dXJuIF9LZXlFdmVudHNQbHVnaW4ucGFyc2VFdmVudE5hbWUoZXZlbnROYW1lKSAhPSBudWxsOwogIH0KICAvKioKICAgKiBSZWdpc3RlcnMgYSBoYW5kbGVyIGZvciBhIHNwZWNpZmljIGVsZW1lbnQgYW5kIGtleSBldmVudC4KICAgKiBAcGFyYW0gZWxlbWVudCBUaGUgSFRNTCBlbGVtZW50IHRvIHJlY2VpdmUgZXZlbnQgbm90aWZpY2F0aW9ucy4KICAgKiBAcGFyYW0gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBrZXkgZXZlbnQgdG8gbGlzdGVuIGZvci4KICAgKiBAcGFyYW0gaGFuZGxlciBBIGZ1bmN0aW9uIHRvIGNhbGwgd2hlbiB0aGUgbm90aWZpY2F0aW9uIG9jY3Vycy4gUmVjZWl2ZXMgdGhlCiAgICogZXZlbnQgb2JqZWN0IGFzIGFuIGFyZ3VtZW50LgogICAqIEByZXR1cm5zIFRoZSBrZXkgZXZlbnQgdGhhdCB3YXMgcmVnaXN0ZXJlZC4KICAgKi8KICBhZGRFdmVudExpc3RlbmVyKGVsZW1lbnQsIGV2ZW50TmFtZSwgaGFuZGxlcikgewogICAgY29uc3QgcGFyc2VkRXZlbnQgPSBfS2V5RXZlbnRzUGx1Z2luLnBhcnNlRXZlbnROYW1lKGV2ZW50TmFtZSk7CiAgICBjb25zdCBvdXRzaWRlSGFuZGxlciA9IF9LZXlFdmVudHNQbHVnaW4uZXZlbnRDYWxsYmFjayhwYXJzZWRFdmVudFsiZnVsbEtleSJdLCBoYW5kbGVyLCB0aGlzLm1hbmFnZXIuZ2V0Wm9uZSgpKTsKICAgIHJldHVybiB0aGlzLm1hbmFnZXIuZ2V0Wm9uZSgpLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHsKICAgICAgcmV0dXJuIGdldERPTSgpLm9uQW5kQ2FuY2VsKGVsZW1lbnQsIHBhcnNlZEV2ZW50WyJkb21FdmVudE5hbWUiXSwgb3V0c2lkZUhhbmRsZXIpOwogICAgfSk7CiAgfQogIC8qKgogICAqIFBhcnNlcyB0aGUgdXNlciBwcm92aWRlZCBmdWxsIGtleWJvYXJkIGV2ZW50IGRlZmluaXRpb24gYW5kIG5vcm1hbGl6ZXMgaXQgZm9yCiAgICogbGF0ZXIgaW50ZXJuYWwgdXNlLiBJdCBlbnN1cmVzIHRoZSBzdHJpbmcgaXMgYWxsIGxvd2VyY2FzZSwgY29udmVydHMgc3BlY2lhbAogICAqIGNoYXJhY3RlcnMgdG8gYSBzdGFuZGFyZCBzcGVsbGluZywgYW5kIG9yZGVycyBhbGwgdGhlIHZhbHVlcyBjb25zaXN0ZW50bHkuCiAgICoKICAgKiBAcGFyYW0gZXZlbnROYW1lIFRoZSBuYW1lIG9mIHRoZSBrZXkgZXZlbnQgdG8gbGlzdGVuIGZvci4KICAgKiBAcmV0dXJucyBhbiBvYmplY3Qgd2l0aCB0aGUgZnVsbCwgbm9ybWFsaXplZCBzdHJpbmcsIGFuZCB0aGUgZG9tIGV2ZW50IG5hbWUKICAgKiBvciBudWxsIGluIHRoZSBjYXNlIHdoZW4gdGhlIGV2ZW50IGRvZXNuJ3QgbWF0Y2ggYSBrZXlib2FyZCBldmVudC4KICAgKi8KICBzdGF0aWMgcGFyc2VFdmVudE5hbWUoZXZlbnROYW1lKSB7CiAgICBjb25zdCBwYXJ0cyA9IGV2ZW50TmFtZS50b0xvd2VyQ2FzZSgpLnNwbGl0KCIuIik7CiAgICBjb25zdCBkb21FdmVudE5hbWUgPSBwYXJ0cy5zaGlmdCgpOwogICAgaWYgKHBhcnRzLmxlbmd0aCA9PT0gMCB8fCAhKGRvbUV2ZW50TmFtZSA9PT0gImtleWRvd24iIHx8IGRvbUV2ZW50TmFtZSA9PT0gImtleXVwIikpIHsKICAgICAgcmV0dXJuIG51bGw7CiAgICB9CiAgICBjb25zdCBrZXkgPSBfS2V5RXZlbnRzUGx1Z2luLl9ub3JtYWxpemVLZXkocGFydHMucG9wKCkpOwogICAgbGV0IGZ1bGxLZXkgPSAiIjsKICAgIGxldCBjb2RlSVggPSBwYXJ0cy5pbmRleE9mKCJjb2RlIik7CiAgICBpZiAoY29kZUlYID4gLTEpIHsKICAgICAgcGFydHMuc3BsaWNlKGNvZGVJWCwgMSk7CiAgICAgIGZ1bGxLZXkgPSAiY29kZS4iOwogICAgfQogICAgTU9ESUZJRVJfS0VZUy5mb3JFYWNoKChtb2RpZmllck5hbWUpID0+IHsKICAgICAgY29uc3QgaW5kZXggPSBwYXJ0cy5pbmRleE9mKG1vZGlmaWVyTmFtZSk7CiAgICAgIGlmIChpbmRleCA+IC0xKSB7CiAgICAgICAgcGFydHMuc3BsaWNlKGluZGV4LCAxKTsKICAgICAgICBmdWxsS2V5ICs9IG1vZGlmaWVyTmFtZSArICIuIjsKICAgICAgfQogICAgfSk7CiAgICBmdWxsS2V5ICs9IGtleTsKICAgIGlmIChwYXJ0cy5sZW5ndGggIT0gMCB8fCBrZXkubGVuZ3RoID09PSAwKSB7CiAgICAgIHJldHVybiBudWxsOwogICAgfQogICAgY29uc3QgcmVzdWx0ID0ge307CiAgICByZXN1bHRbImRvbUV2ZW50TmFtZSJdID0gZG9tRXZlbnROYW1lOwogICAgcmVzdWx0WyJmdWxsS2V5Il0gPSBmdWxsS2V5OwogICAgcmV0dXJuIHJlc3VsdDsKICB9CiAgLyoqCiAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBhY3R1YWwga2V5cyBwcmVzc2VkIG1hdGNoIHRoZSBjb25maWd1cmVkIGtleSBjb2RlIHN0cmluZy4KICAgKiBUaGUgYGZ1bGxLZXlDb2RlYCBldmVudCBpcyBub3JtYWxpemVkIGluIHRoZSBgcGFyc2VFdmVudE5hbWVgIG1ldGhvZCB3aGVuIHRoZQogICAqIGV2ZW50IGlzIGF0dGFjaGVkIHRvIHRoZSBET00gZHVyaW5nIHRoZSBgYWRkRXZlbnRMaXN0ZW5lcmAgY2FsbC4gVGhpcyBpcyB1bnNlZW4KICAgKiBieSB0aGUgZW5kIHVzZXIgYW5kIGlzIG5vcm1hbGl6ZWQgZm9yIGludGVybmFsIGNvbnNpc3RlbmN5IGFuZCBwYXJzaW5nLgogICAqCiAgICogQHBhcmFtIGV2ZW50IFRoZSBrZXlib2FyZCBldmVudC4KICAgKiBAcGFyYW0gZnVsbEtleUNvZGUgVGhlIG5vcm1hbGl6ZWQgdXNlciBkZWZpbmVkIGV4cGVjdGVkIGtleSBldmVudCBzdHJpbmcKICAgKiBAcmV0dXJucyBib29sZWFuLgogICAqLwogIHN0YXRpYyBtYXRjaEV2ZW50RnVsbEtleUNvZGUoZXZlbnQsIGZ1bGxLZXlDb2RlKSB7CiAgICBsZXQga2V5Y29kZSA9IF9rZXlNYXBbZXZlbnQua2V5XSB8fCBldmVudC5rZXk7CiAgICBsZXQga2V5ID0gIiI7CiAgICBpZiAoZnVsbEtleUNvZGUuaW5kZXhPZigiY29kZS4iKSA+IC0xKSB7CiAgICAgIGtleWNvZGUgPSBldmVudC5jb2RlOwogICAgICBrZXkgPSAiY29kZS4iOwogICAgfQogICAgaWYgKGtleWNvZGUgPT0gbnVsbCB8fCAha2V5Y29kZSkKICAgICAgcmV0dXJuIGZhbHNlOwogICAga2V5Y29kZSA9IGtleWNvZGUudG9Mb3dlckNhc2UoKTsKICAgIGlmIChrZXljb2RlID09PSAiICIpIHsKICAgICAga2V5Y29kZSA9ICJzcGFjZSI7CiAgICB9IGVsc2UgaWYgKGtleWNvZGUgPT09ICIuIikgewogICAgICBrZXljb2RlID0gImRvdCI7CiAgICB9CiAgICBNT0RJRklFUl9LRVlTLmZvckVhY2goKG1vZGlmaWVyTmFtZSkgPT4gewogICAgICBpZiAobW9kaWZpZXJOYW1lICE9PSBrZXljb2RlKSB7CiAgICAgICAgY29uc3QgbW9kaWZpZXJHZXR0ZXIgPSBNT0RJRklFUl9LRVlfR0VUVEVSU1ttb2RpZmllck5hbWVdOwogICAgICAgIGlmIChtb2RpZmllckdldHRlcihldmVudCkpIHsKICAgICAgICAgIGtleSArPSBtb2RpZmllck5hbWUgKyAiLiI7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICAgIGtleSArPSBrZXljb2RlOwogICAgcmV0dXJuIGtleSA9PT0gZnVsbEtleUNvZGU7CiAgfQogIC8qKgogICAqIENvbmZpZ3VyZXMgYSBoYW5kbGVyIGNhbGxiYWNrIGZvciBhIGtleSBldmVudC4KICAgKiBAcGFyYW0gZnVsbEtleSBUaGUgZXZlbnQgbmFtZSB0aGF0IGNvbWJpbmVzIGFsbCBzaW11bHRhbmVvdXMga2V5c3Ryb2tlcy4KICAgKiBAcGFyYW0gaGFuZGxlciBUaGUgZnVuY3Rpb24gdGhhdCByZXNwb25kcyB0byB0aGUga2V5IGV2ZW50LgogICAqIEBwYXJhbSB6b25lIFRoZSB6b25lIGluIHdoaWNoIHRoZSBldmVudCBvY2N1cnJlZC4KICAgKiBAcmV0dXJucyBBIGNhbGxiYWNrIGZ1bmN0aW9uLgogICAqLwogIHN0YXRpYyBldmVudENhbGxiYWNrKGZ1bGxLZXksIGhhbmRsZXIsIHpvbmUpIHsKICAgIHJldHVybiAoZXZlbnQpID0+IHsKICAgICAgaWYgKF9LZXlFdmVudHNQbHVnaW4ubWF0Y2hFdmVudEZ1bGxLZXlDb2RlKGV2ZW50LCBmdWxsS2V5KSkgewogICAgICAgIHpvbmUucnVuR3VhcmRlZCgoKSA9PiBoYW5kbGVyKGV2ZW50KSk7CiAgICAgIH0KICAgIH07CiAgfQogIC8qKiBAaW50ZXJuYWwgKi8KICBzdGF0aWMgX25vcm1hbGl6ZUtleShrZXlOYW1lKSB7CiAgICByZXR1cm4ga2V5TmFtZSA9PT0gImVzYyIgPyAiZXNjYXBlIiA6IGtleU5hbWU7CiAgfQp9OwpfS2V5RXZlbnRzUGx1Z2luLsm1ZmFjID0gZnVuY3Rpb24gS2V5RXZlbnRzUGx1Z2luX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0tleUV2ZW50c1BsdWdpbikoybXJtWluamVjdChET0NVTUVOVCkpOwp9OwpfS2V5RXZlbnRzUGx1Z2luLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX0tleUV2ZW50c1BsdWdpbiwKICBmYWN0b3J5OiBfS2V5RXZlbnRzUGx1Z2luLsm1ZmFjCn0pOwp2YXIgS2V5RXZlbnRzUGx1Z2luID0gX0tleUV2ZW50c1BsdWdpbjsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKEtleUV2ZW50c1BsdWdpbiwgW3sKICAgIHR5cGU6IEluamVjdGFibGUKICB9XSwgKCkgPT4gW3sKICAgIHR5cGU6IHZvaWQgMCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0RPQ1VNRU5UXQogICAgfV0KICB9XSwgbnVsbCk7Cn0pKCk7CmZ1bmN0aW9uIGJvb3RzdHJhcEFwcGxpY2F0aW9uKHJvb3RDb21wb25lbnQsIG9wdGlvbnMpIHsKICByZXR1cm4gaW50ZXJuYWxDcmVhdGVBcHBsaWNhdGlvbihfX3NwcmVhZFZhbHVlcyh7CiAgICByb290Q29tcG9uZW50CiAgfSwgY3JlYXRlUHJvdmlkZXJzQ29uZmlnKG9wdGlvbnMpKSk7Cn0KZnVuY3Rpb24gY3JlYXRlQXBwbGljYXRpb24ob3B0aW9ucykgewogIHJldHVybiBpbnRlcm5hbENyZWF0ZUFwcGxpY2F0aW9uKGNyZWF0ZVByb3ZpZGVyc0NvbmZpZyhvcHRpb25zKSk7Cn0KZnVuY3Rpb24gY3JlYXRlUHJvdmlkZXJzQ29uZmlnKG9wdGlvbnMpIHsKICByZXR1cm4gewogICAgYXBwUHJvdmlkZXJzOiBbLi4uQlJPV1NFUl9NT0RVTEVfUFJPVklERVJTLCAuLi5vcHRpb25zPy5wcm92aWRlcnMgPz8gW11dLAogICAgcGxhdGZvcm1Qcm92aWRlcnM6IElOVEVSTkFMX0JST1dTRVJfUExBVEZPUk1fUFJPVklERVJTCiAgfTsKfQpmdW5jdGlvbiBwcm92aWRlUHJvdHJhY3RvclRlc3RpbmdTdXBwb3J0KCkgewogIHJldHVybiBbLi4uVEVTVEFCSUxJVFlfUFJPVklERVJTXTsKfQpmdW5jdGlvbiBpbml0RG9tQWRhcHRlcigpIHsKICBCcm93c2VyRG9tQWRhcHRlci5tYWtlQ3VycmVudCgpOwp9CmZ1bmN0aW9uIGVycm9ySGFuZGxlcigpIHsKICByZXR1cm4gbmV3IEVycm9ySGFuZGxlcigpOwp9CmZ1bmN0aW9uIF9kb2N1bWVudCgpIHsKICBzZXREb2N1bWVudChkb2N1bWVudCk7CiAgcmV0dXJuIGRvY3VtZW50Owp9CnZhciBJTlRFUk5BTF9CUk9XU0VSX1BMQVRGT1JNX1BST1ZJREVSUyA9IFt7CiAgcHJvdmlkZTogUExBVEZPUk1fSUQsCiAgdXNlVmFsdWU6IFBMQVRGT1JNX0JST1dTRVJfSUQKfSwgewogIHByb3ZpZGU6IFBMQVRGT1JNX0lOSVRJQUxJWkVSLAogIHVzZVZhbHVlOiBpbml0RG9tQWRhcHRlciwKICBtdWx0aTogdHJ1ZQp9LCB7CiAgcHJvdmlkZTogRE9DVU1FTlQsCiAgdXNlRmFjdG9yeTogX2RvY3VtZW50LAogIGRlcHM6IFtdCn1dOwp2YXIgcGxhdGZvcm1Ccm93c2VyID0gY3JlYXRlUGxhdGZvcm1GYWN0b3J5KHBsYXRmb3JtQ29yZSwgImJyb3dzZXIiLCBJTlRFUk5BTF9CUk9XU0VSX1BMQVRGT1JNX1BST1ZJREVSUyk7CnZhciBCUk9XU0VSX01PRFVMRV9QUk9WSURFUlNfTUFSS0VSID0gbmV3IEluamVjdGlvblRva2VuKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSA/ICJCcm93c2VyTW9kdWxlIFByb3ZpZGVycyBNYXJrZXIiIDogIiIpOwp2YXIgVEVTVEFCSUxJVFlfUFJPVklERVJTID0gW3sKICBwcm92aWRlOiBURVNUQUJJTElUWV9HRVRURVIsCiAgdXNlQ2xhc3M6IEJyb3dzZXJHZXRUZXN0YWJpbGl0eSwKICBkZXBzOiBbXQp9LCB7CiAgcHJvdmlkZTogVEVTVEFCSUxJVFksCiAgdXNlQ2xhc3M6IFRlc3RhYmlsaXR5LAogIGRlcHM6IFtOZ1pvbmUsIFRlc3RhYmlsaXR5UmVnaXN0cnksIFRFU1RBQklMSVRZX0dFVFRFUl0KfSwgewogIHByb3ZpZGU6IFRlc3RhYmlsaXR5LAogIC8vIEFsc28gcHJvdmlkZSBhcyBgVGVzdGFiaWxpdHlgIGZvciBiYWNrd2FyZHMtY29tcGF0aWJpbGl0eS4KICB1c2VDbGFzczogVGVzdGFiaWxpdHksCiAgZGVwczogW05nWm9uZSwgVGVzdGFiaWxpdHlSZWdpc3RyeSwgVEVTVEFCSUxJVFlfR0VUVEVSXQp9XTsKdmFyIEJST1dTRVJfTU9EVUxFX1BST1ZJREVSUyA9IFt7CiAgcHJvdmlkZTogSU5KRUNUT1JfU0NPUEUsCiAgdXNlVmFsdWU6ICJyb290Igp9LCB7CiAgcHJvdmlkZTogRXJyb3JIYW5kbGVyLAogIHVzZUZhY3Rvcnk6IGVycm9ySGFuZGxlciwKICBkZXBzOiBbXQp9LCB7CiAgcHJvdmlkZTogRVZFTlRfTUFOQUdFUl9QTFVHSU5TLAogIHVzZUNsYXNzOiBEb21FdmVudHNQbHVnaW4sCiAgbXVsdGk6IHRydWUsCiAgZGVwczogW0RPQ1VNRU5ULCBOZ1pvbmUsIFBMQVRGT1JNX0lEXQp9LCB7CiAgcHJvdmlkZTogRVZFTlRfTUFOQUdFUl9QTFVHSU5TLAogIHVzZUNsYXNzOiBLZXlFdmVudHNQbHVnaW4sCiAgbXVsdGk6IHRydWUsCiAgZGVwczogW0RPQ1VNRU5UXQp9LCBEb21SZW5kZXJlckZhY3RvcnkyLCBTaGFyZWRTdHlsZXNIb3N0LCBFdmVudE1hbmFnZXIsIHsKICBwcm92aWRlOiBSZW5kZXJlckZhY3RvcnkyLAogIHVzZUV4aXN0aW5nOiBEb21SZW5kZXJlckZhY3RvcnkyCn0sIHsKICBwcm92aWRlOiBYaHJGYWN0b3J5LAogIHVzZUNsYXNzOiBCcm93c2VyWGhyLAogIGRlcHM6IFtdCn0sIHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSA/IHsKICBwcm92aWRlOiBCUk9XU0VSX01PRFVMRV9QUk9WSURFUlNfTUFSS0VSLAogIHVzZVZhbHVlOiB0cnVlCn0gOiBbXV07CnZhciBfQnJvd3Nlck1vZHVsZSA9IGNsYXNzIF9Ccm93c2VyTW9kdWxlIHsKICBjb25zdHJ1Y3Rvcihwcm92aWRlcnNBbHJlYWR5UHJlc2VudCkgewogICAgaWYgKCh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHByb3ZpZGVyc0FscmVhZHlQcmVzZW50KSB7CiAgICAgIHRocm93IG5ldyBSdW50aW1lRXJyb3IoNTEwMCwgYFByb3ZpZGVycyBmcm9tIHRoZSBcYEJyb3dzZXJNb2R1bGVcYCBoYXZlIGFscmVhZHkgYmVlbiBsb2FkZWQuIElmIHlvdSBuZWVkIGFjY2VzcyB0byBjb21tb24gZGlyZWN0aXZlcyBzdWNoIGFzIE5nSWYgYW5kIE5nRm9yLCBpbXBvcnQgdGhlIFxgQ29tbW9uTW9kdWxlXGAgaW5zdGVhZC5gKTsKICAgIH0KICB9CiAgLyoqCiAgICogQ29uZmlndXJlcyBhIGJyb3dzZXItYmFzZWQgYXBwIHRvIHRyYW5zaXRpb24gZnJvbSBhIHNlcnZlci1yZW5kZXJlZCBhcHAsIGlmCiAgICogb25lIGlzIHByZXNlbnQgb24gdGhlIHBhZ2UuCiAgICoKICAgKiBAcGFyYW0gcGFyYW1zIEFuIG9iamVjdCBjb250YWluaW5nIGFuIGlkZW50aWZpZXIgZm9yIHRoZSBhcHAgdG8gdHJhbnNpdGlvbi4KICAgKiBUaGUgSUQgbXVzdCBtYXRjaCBiZXR3ZWVuIHRoZSBjbGllbnQgYW5kIHNlcnZlciB2ZXJzaW9ucyBvZiB0aGUgYXBwLgogICAqIEByZXR1cm5zIFRoZSByZWNvbmZpZ3VyZWQgYEJyb3dzZXJNb2R1bGVgIHRvIGltcG9ydCBpbnRvIHRoZSBhcHAncyByb290IGBBcHBNb2R1bGVgLgogICAqCiAgICogQGRlcHJlY2F0ZWQgVXNlIHtAbGluayBBUFBfSUR9IGluc3RlYWQgdG8gc2V0IHRoZSBhcHBsaWNhdGlvbiBJRC4KICAgKi8KICBzdGF0aWMgd2l0aFNlcnZlclRyYW5zaXRpb24ocGFyYW1zKSB7CiAgICByZXR1cm4gewogICAgICBuZ01vZHVsZTogX0Jyb3dzZXJNb2R1bGUsCiAgICAgIHByb3ZpZGVyczogW3sKICAgICAgICBwcm92aWRlOiBBUFBfSUQsCiAgICAgICAgdXNlVmFsdWU6IHBhcmFtcy5hcHBJZAogICAgICB9XQogICAgfTsKICB9Cn07Cl9Ccm93c2VyTW9kdWxlLsm1ZmFjID0gZnVuY3Rpb24gQnJvd3Nlck1vZHVsZV9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9Ccm93c2VyTW9kdWxlKSjJtcm1aW5qZWN0KEJST1dTRVJfTU9EVUxFX1BST1ZJREVSU19NQVJLRVIsIDEyKSk7Cn07Cl9Ccm93c2VyTW9kdWxlLsm1bW9kID0gybXJtWRlZmluZU5nTW9kdWxlKHsKICB0eXBlOiBfQnJvd3Nlck1vZHVsZSwKICBleHBvcnRzOiBbQ29tbW9uTW9kdWxlLCBBcHBsaWNhdGlvbk1vZHVsZV0KfSk7Cl9Ccm93c2VyTW9kdWxlLsm1aW5qID0gybXJtWRlZmluZUluamVjdG9yKHsKICBwcm92aWRlcnM6IFsuLi5CUk9XU0VSX01PRFVMRV9QUk9WSURFUlMsIC4uLlRFU1RBQklMSVRZX1BST1ZJREVSU10sCiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgQXBwbGljYXRpb25Nb2R1bGVdCn0pOwp2YXIgQnJvd3Nlck1vZHVsZSA9IF9Ccm93c2VyTW9kdWxlOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoQnJvd3Nlck1vZHVsZSwgW3sKICAgIHR5cGU6IE5nTW9kdWxlLAogICAgYXJnczogW3sKICAgICAgcHJvdmlkZXJzOiBbLi4uQlJPV1NFUl9NT0RVTEVfUFJPVklERVJTLCAuLi5URVNUQUJJTElUWV9QUk9WSURFUlNdLAogICAgICBleHBvcnRzOiBbQ29tbW9uTW9kdWxlLCBBcHBsaWNhdGlvbk1vZHVsZV0KICAgIH1dCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBPcHRpb25hbAogICAgfSwgewogICAgICB0eXBlOiBTa2lwU2VsZgogICAgfSwgewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtCUk9XU0VSX01PRFVMRV9QUk9WSURFUlNfTUFSS0VSXQogICAgfV0KICB9XSwgbnVsbCk7Cn0pKCk7CnZhciBfTWV0YSA9IGNsYXNzIF9NZXRhIHsKICBjb25zdHJ1Y3RvcihfZG9jKSB7CiAgICB0aGlzLl9kb2MgPSBfZG9jOwogICAgdGhpcy5fZG9tID0gZ2V0RE9NKCk7CiAgfQogIC8qKgogICAqIFJldHJpZXZlcyBvciBjcmVhdGVzIGEgc3BlY2lmaWMgYDxtZXRhPmAgdGFnIGVsZW1lbnQgaW4gdGhlIGN1cnJlbnQgSFRNTCBkb2N1bWVudC4KICAgKiBJbiBzZWFyY2hpbmcgZm9yIGFuIGV4aXN0aW5nIHRhZywgQW5ndWxhciBhdHRlbXB0cyB0byBtYXRjaCB0aGUgYG5hbWVgIG9yIGBwcm9wZXJ0eWAgYXR0cmlidXRlCiAgICogdmFsdWVzIGluIHRoZSBwcm92aWRlZCB0YWcgZGVmaW5pdGlvbiwgYW5kIHZlcmlmaWVzIHRoYXQgYWxsIG90aGVyIGF0dHJpYnV0ZSB2YWx1ZXMgYXJlIGVxdWFsLgogICAqIElmIGFuIGV4aXN0aW5nIGVsZW1lbnQgaXMgZm91bmQsIGl0IGlzIHJldHVybmVkIGFuZCBpcyBub3QgbW9kaWZpZWQgaW4gYW55IHdheS4KICAgKiBAcGFyYW0gdGFnIFRoZSBkZWZpbml0aW9uIG9mIGEgYDxtZXRhPmAgZWxlbWVudCB0byBtYXRjaCBvciBjcmVhdGUuCiAgICogQHBhcmFtIGZvcmNlQ3JlYXRpb24gVHJ1ZSB0byBjcmVhdGUgYSBuZXcgZWxlbWVudCB3aXRob3V0IGNoZWNraW5nIHdoZXRoZXIgb25lIGFscmVhZHkgZXhpc3RzLgogICAqIEByZXR1cm5zIFRoZSBleGlzdGluZyBlbGVtZW50IHdpdGggdGhlIHNhbWUgYXR0cmlidXRlcyBhbmQgdmFsdWVzIGlmIGZvdW5kLAogICAqIHRoZSBuZXcgZWxlbWVudCBpZiBubyBtYXRjaCBpcyBmb3VuZCwgb3IgYG51bGxgIGlmIHRoZSB0YWcgcGFyYW1ldGVyIGlzIG5vdCBkZWZpbmVkLgogICAqLwogIGFkZFRhZyh0YWcsIGZvcmNlQ3JlYXRpb24gPSBmYWxzZSkgewogICAgaWYgKCF0YWcpCiAgICAgIHJldHVybiBudWxsOwogICAgcmV0dXJuIHRoaXMuX2dldE9yQ3JlYXRlRWxlbWVudCh0YWcsIGZvcmNlQ3JlYXRpb24pOwogIH0KICAvKioKICAgKiBSZXRyaWV2ZXMgb3IgY3JlYXRlcyBhIHNldCBvZiBgPG1ldGE+YCB0YWcgZWxlbWVudHMgaW4gdGhlIGN1cnJlbnQgSFRNTCBkb2N1bWVudC4KICAgKiBJbiBzZWFyY2hpbmcgZm9yIGFuIGV4aXN0aW5nIHRhZywgQW5ndWxhciBhdHRlbXB0cyB0byBtYXRjaCB0aGUgYG5hbWVgIG9yIGBwcm9wZXJ0eWAgYXR0cmlidXRlCiAgICogdmFsdWVzIGluIHRoZSBwcm92aWRlZCB0YWcgZGVmaW5pdGlvbiwgYW5kIHZlcmlmaWVzIHRoYXQgYWxsIG90aGVyIGF0dHJpYnV0ZSB2YWx1ZXMgYXJlIGVxdWFsLgogICAqIEBwYXJhbSB0YWdzIEFuIGFycmF5IG9mIHRhZyBkZWZpbml0aW9ucyB0byBtYXRjaCBvciBjcmVhdGUuCiAgICogQHBhcmFtIGZvcmNlQ3JlYXRpb24gVHJ1ZSB0byBjcmVhdGUgbmV3IGVsZW1lbnRzIHdpdGhvdXQgY2hlY2tpbmcgd2hldGhlciB0aGV5IGFscmVhZHkgZXhpc3QuCiAgICogQHJldHVybnMgVGhlIG1hdGNoaW5nIGVsZW1lbnRzIGlmIGZvdW5kLCBvciB0aGUgbmV3IGVsZW1lbnRzLgogICAqLwogIGFkZFRhZ3ModGFncywgZm9yY2VDcmVhdGlvbiA9IGZhbHNlKSB7CiAgICBpZiAoIXRhZ3MpCiAgICAgIHJldHVybiBbXTsKICAgIHJldHVybiB0YWdzLnJlZHVjZSgocmVzdWx0LCB0YWcpID0+IHsKICAgICAgaWYgKHRhZykgewogICAgICAgIHJlc3VsdC5wdXNoKHRoaXMuX2dldE9yQ3JlYXRlRWxlbWVudCh0YWcsIGZvcmNlQ3JlYXRpb24pKTsKICAgICAgfQogICAgICByZXR1cm4gcmVzdWx0OwogICAgfSwgW10pOwogIH0KICAvKioKICAgKiBSZXRyaWV2ZXMgYSBgPG1ldGE+YCB0YWcgZWxlbWVudCBpbiB0aGUgY3VycmVudCBIVE1MIGRvY3VtZW50LgogICAqIEBwYXJhbSBhdHRyU2VsZWN0b3IgVGhlIHRhZyBhdHRyaWJ1dGUgYW5kIHZhbHVlIHRvIG1hdGNoIGFnYWluc3QsIGluIHRoZSBmb3JtYXQKICAgKiBgInRhZ19hdHRyaWJ1dGU9J3ZhbHVlIHN0cmluZyciYC4KICAgKiBAcmV0dXJucyBUaGUgbWF0Y2hpbmcgZWxlbWVudCwgaWYgYW55LgogICAqLwogIGdldFRhZyhhdHRyU2VsZWN0b3IpIHsKICAgIGlmICghYXR0clNlbGVjdG9yKQogICAgICByZXR1cm4gbnVsbDsKICAgIHJldHVybiB0aGlzLl9kb2MucXVlcnlTZWxlY3RvcihgbWV0YVske2F0dHJTZWxlY3Rvcn1dYCkgfHwgbnVsbDsKICB9CiAgLyoqCiAgICogUmV0cmlldmVzIGEgc2V0IG9mIGA8bWV0YT5gIHRhZyBlbGVtZW50cyBpbiB0aGUgY3VycmVudCBIVE1MIGRvY3VtZW50LgogICAqIEBwYXJhbSBhdHRyU2VsZWN0b3IgVGhlIHRhZyBhdHRyaWJ1dGUgYW5kIHZhbHVlIHRvIG1hdGNoIGFnYWluc3QsIGluIHRoZSBmb3JtYXQKICAgKiBgInRhZ19hdHRyaWJ1dGU9J3ZhbHVlIHN0cmluZyciYC4KICAgKiBAcmV0dXJucyBUaGUgbWF0Y2hpbmcgZWxlbWVudHMsIGlmIGFueS4KICAgKi8KICBnZXRUYWdzKGF0dHJTZWxlY3RvcikgewogICAgaWYgKCFhdHRyU2VsZWN0b3IpCiAgICAgIHJldHVybiBbXTsKICAgIGNvbnN0IGxpc3QgPSB0aGlzLl9kb2MucXVlcnlTZWxlY3RvckFsbChgbWV0YVske2F0dHJTZWxlY3Rvcn1dYCk7CiAgICByZXR1cm4gbGlzdCA/IFtdLnNsaWNlLmNhbGwobGlzdCkgOiBbXTsKICB9CiAgLyoqCiAgICogTW9kaWZpZXMgYW4gZXhpc3RpbmcgYDxtZXRhPmAgdGFnIGVsZW1lbnQgaW4gdGhlIGN1cnJlbnQgSFRNTCBkb2N1bWVudC4KICAgKiBAcGFyYW0gdGFnIFRoZSB0YWcgZGVzY3JpcHRpb24gd2l0aCB3aGljaCB0byByZXBsYWNlIHRoZSBleGlzdGluZyB0YWcgY29udGVudC4KICAgKiBAcGFyYW0gc2VsZWN0b3IgQSB0YWcgYXR0cmlidXRlIGFuZCB2YWx1ZSB0byBtYXRjaCBhZ2FpbnN0LCB0byBpZGVudGlmeQogICAqIGFuIGV4aXN0aW5nIHRhZy4gQSBzdHJpbmcgaW4gdGhlIGZvcm1hdCBgInRhZ19hdHRyaWJ1dGU9YHZhbHVlIHN0cmluZ2AiYC4KICAgKiBJZiBub3Qgc3VwcGxpZWQsIG1hdGNoZXMgYSB0YWcgd2l0aCB0aGUgc2FtZSBgbmFtZWAgb3IgYHByb3BlcnR5YCBhdHRyaWJ1dGUgdmFsdWUgYXMgdGhlCiAgICogcmVwbGFjZW1lbnQgdGFnLgogICAqIEByZXR1cm4gVGhlIG1vZGlmaWVkIGVsZW1lbnQuCiAgICovCiAgdXBkYXRlVGFnKHRhZywgc2VsZWN0b3IpIHsKICAgIGlmICghdGFnKQogICAgICByZXR1cm4gbnVsbDsKICAgIHNlbGVjdG9yID0gc2VsZWN0b3IgfHwgdGhpcy5fcGFyc2VTZWxlY3Rvcih0YWcpOwogICAgY29uc3QgbWV0YSA9IHRoaXMuZ2V0VGFnKHNlbGVjdG9yKTsKICAgIGlmIChtZXRhKSB7CiAgICAgIHJldHVybiB0aGlzLl9zZXRNZXRhRWxlbWVudEF0dHJpYnV0ZXModGFnLCBtZXRhKTsKICAgIH0KICAgIHJldHVybiB0aGlzLl9nZXRPckNyZWF0ZUVsZW1lbnQodGFnLCB0cnVlKTsKICB9CiAgLyoqCiAgICogUmVtb3ZlcyBhbiBleGlzdGluZyBgPG1ldGE+YCB0YWcgZWxlbWVudCBmcm9tIHRoZSBjdXJyZW50IEhUTUwgZG9jdW1lbnQuCiAgICogQHBhcmFtIGF0dHJTZWxlY3RvciBBIHRhZyBhdHRyaWJ1dGUgYW5kIHZhbHVlIHRvIG1hdGNoIGFnYWluc3QsIHRvIGlkZW50aWZ5CiAgICogYW4gZXhpc3RpbmcgdGFnLiBBIHN0cmluZyBpbiB0aGUgZm9ybWF0IGAidGFnX2F0dHJpYnV0ZT1gdmFsdWUgc3RyaW5nYCJgLgogICAqLwogIHJlbW92ZVRhZyhhdHRyU2VsZWN0b3IpIHsKICAgIHRoaXMucmVtb3ZlVGFnRWxlbWVudCh0aGlzLmdldFRhZyhhdHRyU2VsZWN0b3IpKTsKICB9CiAgLyoqCiAgICogUmVtb3ZlcyBhbiBleGlzdGluZyBgPG1ldGE+YCB0YWcgZWxlbWVudCBmcm9tIHRoZSBjdXJyZW50IEhUTUwgZG9jdW1lbnQuCiAgICogQHBhcmFtIG1ldGEgVGhlIHRhZyBkZWZpbml0aW9uIHRvIG1hdGNoIGFnYWluc3QgdG8gaWRlbnRpZnkgYW4gZXhpc3RpbmcgdGFnLgogICAqLwogIHJlbW92ZVRhZ0VsZW1lbnQobWV0YSkgewogICAgaWYgKG1ldGEpIHsKICAgICAgdGhpcy5fZG9tLnJlbW92ZShtZXRhKTsKICAgIH0KICB9CiAgX2dldE9yQ3JlYXRlRWxlbWVudChtZXRhLCBmb3JjZUNyZWF0aW9uID0gZmFsc2UpIHsKICAgIGlmICghZm9yY2VDcmVhdGlvbikgewogICAgICBjb25zdCBzZWxlY3RvciA9IHRoaXMuX3BhcnNlU2VsZWN0b3IobWV0YSk7CiAgICAgIGNvbnN0IGVsZW0gPSB0aGlzLmdldFRhZ3Moc2VsZWN0b3IpLmZpbHRlcigoZWxlbTIpID0+IHRoaXMuX2NvbnRhaW5zQXR0cmlidXRlcyhtZXRhLCBlbGVtMikpWzBdOwogICAgICBpZiAoZWxlbSAhPT0gdm9pZCAwKQogICAgICAgIHJldHVybiBlbGVtOwogICAgfQogICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2RvbS5jcmVhdGVFbGVtZW50KCJtZXRhIik7CiAgICB0aGlzLl9zZXRNZXRhRWxlbWVudEF0dHJpYnV0ZXMobWV0YSwgZWxlbWVudCk7CiAgICBjb25zdCBoZWFkID0gdGhpcy5fZG9jLmdldEVsZW1lbnRzQnlUYWdOYW1lKCJoZWFkIilbMF07CiAgICBoZWFkLmFwcGVuZENoaWxkKGVsZW1lbnQpOwogICAgcmV0dXJuIGVsZW1lbnQ7CiAgfQogIF9zZXRNZXRhRWxlbWVudEF0dHJpYnV0ZXModGFnLCBlbCkgewogICAgT2JqZWN0LmtleXModGFnKS5mb3JFYWNoKChwcm9wKSA9PiBlbC5zZXRBdHRyaWJ1dGUodGhpcy5fZ2V0TWV0YUtleU1hcChwcm9wKSwgdGFnW3Byb3BdKSk7CiAgICByZXR1cm4gZWw7CiAgfQogIF9wYXJzZVNlbGVjdG9yKHRhZykgewogICAgY29uc3QgYXR0ciA9IHRhZy5uYW1lID8gIm5hbWUiIDogInByb3BlcnR5IjsKICAgIHJldHVybiBgJHthdHRyfT0iJHt0YWdbYXR0cl19ImA7CiAgfQogIF9jb250YWluc0F0dHJpYnV0ZXModGFnLCBlbGVtKSB7CiAgICByZXR1cm4gT2JqZWN0LmtleXModGFnKS5ldmVyeSgoa2V5KSA9PiBlbGVtLmdldEF0dHJpYnV0ZSh0aGlzLl9nZXRNZXRhS2V5TWFwKGtleSkpID09PSB0YWdba2V5XSk7CiAgfQogIF9nZXRNZXRhS2V5TWFwKHByb3ApIHsKICAgIHJldHVybiBNRVRBX0tFWVNfTUFQW3Byb3BdIHx8IHByb3A7CiAgfQp9OwpfTWV0YS7JtWZhYyA9IGZ1bmN0aW9uIE1ldGFfRmFjdG9yeSh0KSB7CiAgcmV0dXJuIG5ldyAodCB8fCBfTWV0YSkoybXJtWluamVjdChET0NVTUVOVCkpOwp9OwpfTWV0YS7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7CiAgdG9rZW46IF9NZXRhLAogIGZhY3Rvcnk6IF9NZXRhLsm1ZmFjLAogIHByb3ZpZGVkSW46ICJyb290Igp9KTsKdmFyIE1ldGEgPSBfTWV0YTsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKE1ldGEsIFt7CiAgICB0eXBlOiBJbmplY3RhYmxlLAogICAgYXJnczogW3sKICAgICAgcHJvdmlkZWRJbjogInJvb3QiCiAgICB9XQogIH1dLCAoKSA9PiBbewogICAgdHlwZTogdm9pZCAwLAogICAgZGVjb3JhdG9yczogW3sKICAgICAgdHlwZTogSW5qZWN0LAogICAgICBhcmdzOiBbRE9DVU1FTlRdCiAgICB9XQogIH1dLCBudWxsKTsKfSkoKTsKdmFyIE1FVEFfS0VZU19NQVAgPSB7CiAgaHR0cEVxdWl2OiAiaHR0cC1lcXVpdiIKfTsKdmFyIF9UaXRsZSA9IGNsYXNzIF9UaXRsZSB7CiAgY29uc3RydWN0b3IoX2RvYykgewogICAgdGhpcy5fZG9jID0gX2RvYzsKICB9CiAgLyoqCiAgICogR2V0IHRoZSB0aXRsZSBvZiB0aGUgY3VycmVudCBIVE1MIGRvY3VtZW50LgogICAqLwogIGdldFRpdGxlKCkgewogICAgcmV0dXJuIHRoaXMuX2RvYy50aXRsZTsKICB9CiAgLyoqCiAgICogU2V0IHRoZSB0aXRsZSBvZiB0aGUgY3VycmVudCBIVE1MIGRvY3VtZW50LgogICAqIEBwYXJhbSBuZXdUaXRsZQogICAqLwogIHNldFRpdGxlKG5ld1RpdGxlKSB7CiAgICB0aGlzLl9kb2MudGl0bGUgPSBuZXdUaXRsZSB8fCAiIjsKICB9Cn07Cl9UaXRsZS7JtWZhYyA9IGZ1bmN0aW9uIFRpdGxlX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX1RpdGxlKSjJtcm1aW5qZWN0KERPQ1VNRU5UKSk7Cn07Cl9UaXRsZS7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7CiAgdG9rZW46IF9UaXRsZSwKICBmYWN0b3J5OiBfVGl0bGUuybVmYWMsCiAgcHJvdmlkZWRJbjogInJvb3QiCn0pOwp2YXIgVGl0bGUgPSBfVGl0bGU7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShUaXRsZSwgW3sKICAgIHR5cGU6IEluamVjdGFibGUsCiAgICBhcmdzOiBbewogICAgICBwcm92aWRlZEluOiAicm9vdCIKICAgIH1dCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtET0NVTUVOVF0KICAgIH1dCiAgfV0sIG51bGwpOwp9KSgpOwpmdW5jdGlvbiBleHBvcnROZ1ZhcihuYW1lLCB2YWx1ZSkgewogIGlmICh0eXBlb2YgQ09NUElMRUQgPT09ICJ1bmRlZmluZWQiIHx8ICFDT01QSUxFRCkgewogICAgY29uc3QgbmcgPSBfZ2xvYmFsWyJuZyJdID0gX2dsb2JhbFsibmciXSB8fCB7fTsKICAgIG5nW25hbWVdID0gdmFsdWU7CiAgfQp9CnZhciBDaGFuZ2VEZXRlY3Rpb25QZXJmUmVjb3JkID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG1zUGVyVGljaywgbnVtVGlja3MpIHsKICAgIHRoaXMubXNQZXJUaWNrID0gbXNQZXJUaWNrOwogICAgdGhpcy5udW1UaWNrcyA9IG51bVRpY2tzOwogIH0KfTsKdmFyIEFuZ3VsYXJQcm9maWxlciA9IGNsYXNzIHsKICBjb25zdHJ1Y3RvcihyZWYpIHsKICAgIHRoaXMuYXBwUmVmID0gcmVmLmluamVjdG9yLmdldChBcHBsaWNhdGlvblJlZik7CiAgfQogIC8vIHRzbGludDpkaXNhYmxlOm5vLWNvbnNvbGUKICAvKioKICAgKiBFeGVyY2lzZXMgY2hhbmdlIGRldGVjdGlvbiBpbiBhIGxvb3AgYW5kIHRoZW4gcHJpbnRzIHRoZSBhdmVyYWdlIGFtb3VudCBvZgogICAqIHRpbWUgaW4gbWlsbGlzZWNvbmRzIGhvdyBsb25nIGEgc2luZ2xlIHJvdW5kIG9mIGNoYW5nZSBkZXRlY3Rpb24gdGFrZXMgZm9yCiAgICogdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhlIFVJLiBJdCBydW5zIGEgbWluaW11bSBvZiA1IHJvdW5kcyBmb3IgYSBtaW5pbXVtCiAgICogb2YgNTAwIG1pbGxpc2Vjb25kcy4KICAgKgogICAqIE9wdGlvbmFsbHksIGEgdXNlciBtYXkgcGFzcyBhIGBjb25maWdgIHBhcmFtZXRlciBjb250YWluaW5nIGEgbWFwIG9mCiAgICogb3B0aW9ucy4gU3VwcG9ydGVkIG9wdGlvbnMgYXJlOgogICAqCiAgICogYHJlY29yZGAgKGJvb2xlYW4pIC0gY2F1c2VzIHRoZSBwcm9maWxlciB0byByZWNvcmQgYSBDUFUgcHJvZmlsZSB3aGlsZQogICAqIGl0IGV4ZXJjaXNlcyB0aGUgY2hhbmdlIGRldGVjdG9yLiBFeGFtcGxlOgogICAqCiAgICogYGBgCiAgICogbmcucHJvZmlsZXIudGltZUNoYW5nZURldGVjdGlvbih7cmVjb3JkOiB0cnVlfSkKICAgKiBgYGAKICAgKi8KICB0aW1lQ2hhbmdlRGV0ZWN0aW9uKGNvbmZpZykgewogICAgY29uc3QgcmVjb3JkID0gY29uZmlnICYmIGNvbmZpZ1sicmVjb3JkIl07CiAgICBjb25zdCBwcm9maWxlTmFtZSA9ICJDaGFuZ2UgRGV0ZWN0aW9uIjsKICAgIGlmIChyZWNvcmQgJiYgInByb2ZpbGUiIGluIGNvbnNvbGUgJiYgdHlwZW9mIGNvbnNvbGUucHJvZmlsZSA9PT0gImZ1bmN0aW9uIikgewogICAgICBjb25zb2xlLnByb2ZpbGUocHJvZmlsZU5hbWUpOwogICAgfQogICAgY29uc3Qgc3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTsKICAgIGxldCBudW1UaWNrcyA9IDA7CiAgICB3aGlsZSAobnVtVGlja3MgPCA1IHx8IHBlcmZvcm1hbmNlLm5vdygpIC0gc3RhcnQgPCA1MDApIHsKICAgICAgdGhpcy5hcHBSZWYudGljaygpOwogICAgICBudW1UaWNrcysrOwogICAgfQogICAgY29uc3QgZW5kID0gcGVyZm9ybWFuY2Uubm93KCk7CiAgICBpZiAocmVjb3JkICYmICJwcm9maWxlRW5kIiBpbiBjb25zb2xlICYmIHR5cGVvZiBjb25zb2xlLnByb2ZpbGVFbmQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgY29uc29sZS5wcm9maWxlRW5kKHByb2ZpbGVOYW1lKTsKICAgIH0KICAgIGNvbnN0IG1zUGVyVGljayA9IChlbmQgLSBzdGFydCkgLyBudW1UaWNrczsKICAgIGNvbnNvbGUubG9nKGByYW4gJHtudW1UaWNrc30gY2hhbmdlIGRldGVjdGlvbiBjeWNsZXNgKTsKICAgIGNvbnNvbGUubG9nKGAke21zUGVyVGljay50b0ZpeGVkKDIpfSBtcyBwZXIgY2hlY2tgKTsKICAgIHJldHVybiBuZXcgQ2hhbmdlRGV0ZWN0aW9uUGVyZlJlY29yZChtc1BlclRpY2ssIG51bVRpY2tzKTsKICB9Cn07CnZhciBQUk9GSUxFUl9HTE9CQUxfTkFNRSA9ICJwcm9maWxlciI7CmZ1bmN0aW9uIGVuYWJsZURlYnVnVG9vbHMocmVmKSB7CiAgZXhwb3J0TmdWYXIoUFJPRklMRVJfR0xPQkFMX05BTUUsIG5ldyBBbmd1bGFyUHJvZmlsZXIocmVmKSk7CiAgcmV0dXJuIHJlZjsKfQpmdW5jdGlvbiBkaXNhYmxlRGVidWdUb29scygpIHsKICBleHBvcnROZ1ZhcihQUk9GSUxFUl9HTE9CQUxfTkFNRSwgbnVsbCk7Cn0KdmFyIEJ5ID0gY2xhc3MgewogIC8qKgogICAqIE1hdGNoIGFsbCBub2Rlcy4KICAgKgogICAqIEB1c2FnZU5vdGVzCiAgICogIyMjIEV4YW1wbGUKICAgKgogICAqIHtAZXhhbXBsZSBwbGF0Zm9ybS1icm93c2VyL2RvbS9kZWJ1Zy90cy9ieS9ieS50cyByZWdpb249J2J5X2FsbCd9CiAgICovCiAgc3RhdGljIGFsbCgpIHsKICAgIHJldHVybiAoKSA9PiB0cnVlOwogIH0KICAvKioKICAgKiBNYXRjaCBlbGVtZW50cyBieSB0aGUgZ2l2ZW4gQ1NTIHNlbGVjdG9yLgogICAqCiAgICogQHVzYWdlTm90ZXMKICAgKiAjIyMgRXhhbXBsZQogICAqCiAgICoge0BleGFtcGxlIHBsYXRmb3JtLWJyb3dzZXIvZG9tL2RlYnVnL3RzL2J5L2J5LnRzIHJlZ2lvbj0nYnlfY3NzJ30KICAgKi8KICBzdGF0aWMgY3NzKHNlbGVjdG9yKSB7CiAgICByZXR1cm4gKGRlYnVnRWxlbWVudCkgPT4gewogICAgICByZXR1cm4gZGVidWdFbGVtZW50Lm5hdGl2ZUVsZW1lbnQgIT0gbnVsbCA/IGVsZW1lbnRNYXRjaGVzKGRlYnVnRWxlbWVudC5uYXRpdmVFbGVtZW50LCBzZWxlY3RvcikgOiBmYWxzZTsKICAgIH07CiAgfQogIC8qKgogICAqIE1hdGNoIG5vZGVzIHRoYXQgaGF2ZSB0aGUgZ2l2ZW4gZGlyZWN0aXZlIHByZXNlbnQuCiAgICoKICAgKiBAdXNhZ2VOb3RlcwogICAqICMjIyBFeGFtcGxlCiAgICoKICAgKiB7QGV4YW1wbGUgcGxhdGZvcm0tYnJvd3Nlci9kb20vZGVidWcvdHMvYnkvYnkudHMgcmVnaW9uPSdieV9kaXJlY3RpdmUnfQogICAqLwogIHN0YXRpYyBkaXJlY3RpdmUodHlwZSkgewogICAgcmV0dXJuIChkZWJ1Z05vZGUpID0+IGRlYnVnTm9kZS5wcm92aWRlclRva2Vucy5pbmRleE9mKHR5cGUpICE9PSAtMTsKICB9Cn07CmZ1bmN0aW9uIGVsZW1lbnRNYXRjaGVzKG4sIHNlbGVjdG9yKSB7CiAgaWYgKGdldERPTSgpLmlzRWxlbWVudE5vZGUobikpIHsKICAgIHJldHVybiBuLm1hdGNoZXMgJiYgbi5tYXRjaGVzKHNlbGVjdG9yKSB8fCBuLm1zTWF0Y2hlc1NlbGVjdG9yICYmIG4ubXNNYXRjaGVzU2VsZWN0b3Ioc2VsZWN0b3IpIHx8IG4ud2Via2l0TWF0Y2hlc1NlbGVjdG9yICYmIG4ud2Via2l0TWF0Y2hlc1NlbGVjdG9yKHNlbGVjdG9yKTsKICB9CiAgcmV0dXJuIGZhbHNlOwp9CnZhciBFVkVOVF9OQU1FUyA9IHsKICAvLyBwYW4KICAicGFuIjogdHJ1ZSwKICAicGFuc3RhcnQiOiB0cnVlLAogICJwYW5tb3ZlIjogdHJ1ZSwKICAicGFuZW5kIjogdHJ1ZSwKICAicGFuY2FuY2VsIjogdHJ1ZSwKICAicGFubGVmdCI6IHRydWUsCiAgInBhbnJpZ2h0IjogdHJ1ZSwKICAicGFudXAiOiB0cnVlLAogICJwYW5kb3duIjogdHJ1ZSwKICAvLyBwaW5jaAogICJwaW5jaCI6IHRydWUsCiAgInBpbmNoc3RhcnQiOiB0cnVlLAogICJwaW5jaG1vdmUiOiB0cnVlLAogICJwaW5jaGVuZCI6IHRydWUsCiAgInBpbmNoY2FuY2VsIjogdHJ1ZSwKICAicGluY2hpbiI6IHRydWUsCiAgInBpbmNob3V0IjogdHJ1ZSwKICAvLyBwcmVzcwogICJwcmVzcyI6IHRydWUsCiAgInByZXNzdXAiOiB0cnVlLAogIC8vIHJvdGF0ZQogICJyb3RhdGUiOiB0cnVlLAogICJyb3RhdGVzdGFydCI6IHRydWUsCiAgInJvdGF0ZW1vdmUiOiB0cnVlLAogICJyb3RhdGVlbmQiOiB0cnVlLAogICJyb3RhdGVjYW5jZWwiOiB0cnVlLAogIC8vIHN3aXBlCiAgInN3aXBlIjogdHJ1ZSwKICAic3dpcGVsZWZ0IjogdHJ1ZSwKICAic3dpcGVyaWdodCI6IHRydWUsCiAgInN3aXBldXAiOiB0cnVlLAogICJzd2lwZWRvd24iOiB0cnVlLAogIC8vIHRhcAogICJ0YXAiOiB0cnVlLAogICJkb3VibGV0YXAiOiB0cnVlCn07CnZhciBIQU1NRVJfR0VTVFVSRV9DT05GSUcgPSBuZXcgSW5qZWN0aW9uVG9rZW4oIkhhbW1lckdlc3R1cmVDb25maWciKTsKdmFyIEhBTU1FUl9MT0FERVIgPSBuZXcgSW5qZWN0aW9uVG9rZW4oIkhhbW1lckxvYWRlciIpOwp2YXIgX0hhbW1lckdlc3R1cmVDb25maWcgPSBjbGFzcyBfSGFtbWVyR2VzdHVyZUNvbmZpZyB7CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLmV2ZW50cyA9IFtdOwogICAgdGhpcy5vdmVycmlkZXMgPSB7fTsKICB9CiAgLyoqCiAgICogQ3JlYXRlcyBhIFtIYW1tZXJKUyBNYW5hZ2VyXShodHRwczovL2hhbW1lcmpzLmdpdGh1Yi5pby9hcGkvI2hhbW1lcm1hbmFnZXIpCiAgICogYW5kIGF0dGFjaGVzIGl0IHRvIGEgZ2l2ZW4gSFRNTCBlbGVtZW50LgogICAqIEBwYXJhbSBlbGVtZW50IFRoZSBlbGVtZW50IHRoYXQgd2lsbCByZWNvZ25pemUgZ2VzdHVyZXMuCiAgICogQHJldHVybnMgQSBIYW1tZXJKUyBldmVudC1tYW5hZ2VyIG9iamVjdC4KICAgKi8KICBidWlsZEhhbW1lcihlbGVtZW50KSB7CiAgICBjb25zdCBtYyA9IG5ldyBIYW1tZXIoZWxlbWVudCwgdGhpcy5vcHRpb25zKTsKICAgIG1jLmdldCgicGluY2giKS5zZXQoewogICAgICBlbmFibGU6IHRydWUKICAgIH0pOwogICAgbWMuZ2V0KCJyb3RhdGUiKS5zZXQoewogICAgICBlbmFibGU6IHRydWUKICAgIH0pOwogICAgZm9yIChjb25zdCBldmVudE5hbWUgaW4gdGhpcy5vdmVycmlkZXMpIHsKICAgICAgbWMuZ2V0KGV2ZW50TmFtZSkuc2V0KHRoaXMub3ZlcnJpZGVzW2V2ZW50TmFtZV0pOwogICAgfQogICAgcmV0dXJuIG1jOwogIH0KfTsKX0hhbW1lckdlc3R1cmVDb25maWcuybVmYWMgPSBmdW5jdGlvbiBIYW1tZXJHZXN0dXJlQ29uZmlnX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0hhbW1lckdlc3R1cmVDb25maWcpKCk7Cn07Cl9IYW1tZXJHZXN0dXJlQ29uZmlnLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX0hhbW1lckdlc3R1cmVDb25maWcsCiAgZmFjdG9yeTogX0hhbW1lckdlc3R1cmVDb25maWcuybVmYWMKfSk7CnZhciBIYW1tZXJHZXN0dXJlQ29uZmlnID0gX0hhbW1lckdlc3R1cmVDb25maWc7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShIYW1tZXJHZXN0dXJlQ29uZmlnLCBbewogICAgdHlwZTogSW5qZWN0YWJsZQogIH1dLCBudWxsLCBudWxsKTsKfSkoKTsKdmFyIF9IYW1tZXJHZXN0dXJlc1BsdWdpbiA9IGNsYXNzIF9IYW1tZXJHZXN0dXJlc1BsdWdpbiBleHRlbmRzIEV2ZW50TWFuYWdlclBsdWdpbiB7CiAgY29uc3RydWN0b3IoZG9jLCBfY29uZmlnLCBjb25zb2xlMiwgbG9hZGVyKSB7CiAgICBzdXBlcihkb2MpOwogICAgdGhpcy5fY29uZmlnID0gX2NvbmZpZzsKICAgIHRoaXMuY29uc29sZSA9IGNvbnNvbGUyOwogICAgdGhpcy5sb2FkZXIgPSBsb2FkZXI7CiAgICB0aGlzLl9sb2FkZXJQcm9taXNlID0gbnVsbDsKICB9CiAgc3VwcG9ydHMoZXZlbnROYW1lKSB7CiAgICBpZiAoIUVWRU5UX05BTUVTLmhhc093blByb3BlcnR5KGV2ZW50TmFtZS50b0xvd2VyQ2FzZSgpKSAmJiAhdGhpcy5pc0N1c3RvbUV2ZW50KGV2ZW50TmFtZSkpIHsKICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgaWYgKCF3aW5kb3cuSGFtbWVyICYmICF0aGlzLmxvYWRlcikgewogICAgICBpZiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSB7CiAgICAgICAgdGhpcy5jb25zb2xlLndhcm4oYFRoZSAiJHtldmVudE5hbWV9IiBldmVudCBjYW5ub3QgYmUgYm91bmQgYmVjYXVzZSBIYW1tZXIuSlMgaXMgbm90IGxvYWRlZCBhbmQgbm8gY3VzdG9tIGxvYWRlciBoYXMgYmVlbiBzcGVjaWZpZWQuYCk7CiAgICAgIH0KICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfQogIGFkZEV2ZW50TGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lLCBoYW5kbGVyKSB7CiAgICBjb25zdCB6b25lID0gdGhpcy5tYW5hZ2VyLmdldFpvbmUoKTsKICAgIGV2ZW50TmFtZSA9IGV2ZW50TmFtZS50b0xvd2VyQ2FzZSgpOwogICAgaWYgKCF3aW5kb3cuSGFtbWVyICYmIHRoaXMubG9hZGVyKSB7CiAgICAgIHRoaXMuX2xvYWRlclByb21pc2UgPSB0aGlzLl9sb2FkZXJQcm9taXNlIHx8IHpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gdGhpcy5sb2FkZXIoKSk7CiAgICAgIGxldCBjYW5jZWxSZWdpc3RyYXRpb24gPSBmYWxzZTsKICAgICAgbGV0IGRlcmVnaXN0ZXIgPSAoKSA9PiB7CiAgICAgICAgY2FuY2VsUmVnaXN0cmF0aW9uID0gdHJ1ZTsKICAgICAgfTsKICAgICAgem9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB0aGlzLl9sb2FkZXJQcm9taXNlLnRoZW4oKCkgPT4gewogICAgICAgIGlmICghd2luZG93LkhhbW1lcikgewogICAgICAgICAgaWYgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgewogICAgICAgICAgICB0aGlzLmNvbnNvbGUud2FybihgVGhlIGN1c3RvbSBIQU1NRVJfTE9BREVSIGNvbXBsZXRlZCwgYnV0IEhhbW1lci5KUyBpcyBub3QgcHJlc2VudC5gKTsKICAgICAgICAgIH0KICAgICAgICAgIGRlcmVnaXN0ZXIgPSAoKSA9PiB7CiAgICAgICAgICB9OwogICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgICAgICBpZiAoIWNhbmNlbFJlZ2lzdHJhdGlvbikgewogICAgICAgICAgZGVyZWdpc3RlciA9IHRoaXMuYWRkRXZlbnRMaXN0ZW5lcihlbGVtZW50LCBldmVudE5hbWUsIGhhbmRsZXIpOwogICAgICAgIH0KICAgICAgfSkuY2F0Y2goKCkgPT4gewogICAgICAgIGlmICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpIHsKICAgICAgICAgIHRoaXMuY29uc29sZS53YXJuKGBUaGUgIiR7ZXZlbnROYW1lfSIgZXZlbnQgY2Fubm90IGJlIGJvdW5kIGJlY2F1c2UgdGhlIGN1c3RvbSBIYW1tZXIuSlMgbG9hZGVyIGZhaWxlZC5gKTsKICAgICAgICB9CiAgICAgICAgZGVyZWdpc3RlciA9ICgpID0+IHsKICAgICAgICB9OwogICAgICB9KSk7CiAgICAgIHJldHVybiAoKSA9PiB7CiAgICAgICAgZGVyZWdpc3RlcigpOwogICAgICB9OwogICAgfQogICAgcmV0dXJuIHpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4gewogICAgICBjb25zdCBtYyA9IHRoaXMuX2NvbmZpZy5idWlsZEhhbW1lcihlbGVtZW50KTsKICAgICAgY29uc3QgY2FsbGJhY2sgPSBmdW5jdGlvbihldmVudE9iaikgewogICAgICAgIHpvbmUucnVuR3VhcmRlZChmdW5jdGlvbigpIHsKICAgICAgICAgIGhhbmRsZXIoZXZlbnRPYmopOwogICAgICAgIH0pOwogICAgICB9OwogICAgICBtYy5vbihldmVudE5hbWUsIGNhbGxiYWNrKTsKICAgICAgcmV0dXJuICgpID0+IHsKICAgICAgICBtYy5vZmYoZXZlbnROYW1lLCBjYWxsYmFjayk7CiAgICAgICAgaWYgKHR5cGVvZiBtYy5kZXN0cm95ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICBtYy5kZXN0cm95KCk7CiAgICAgICAgfQogICAgICB9OwogICAgfSk7CiAgfQogIGlzQ3VzdG9tRXZlbnQoZXZlbnROYW1lKSB7CiAgICByZXR1cm4gdGhpcy5fY29uZmlnLmV2ZW50cy5pbmRleE9mKGV2ZW50TmFtZSkgPiAtMTsKICB9Cn07Cl9IYW1tZXJHZXN0dXJlc1BsdWdpbi7JtWZhYyA9IGZ1bmN0aW9uIEhhbW1lckdlc3R1cmVzUGx1Z2luX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0hhbW1lckdlc3R1cmVzUGx1Z2luKSjJtcm1aW5qZWN0KERPQ1VNRU5UKSwgybXJtWluamVjdChIQU1NRVJfR0VTVFVSRV9DT05GSUcpLCDJtcm1aW5qZWN0KENvbnNvbGUpLCDJtcm1aW5qZWN0KEhBTU1FUl9MT0FERVIsIDgpKTsKfTsKX0hhbW1lckdlc3R1cmVzUGx1Z2luLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX0hhbW1lckdlc3R1cmVzUGx1Z2luLAogIGZhY3Rvcnk6IF9IYW1tZXJHZXN0dXJlc1BsdWdpbi7JtWZhYwp9KTsKdmFyIEhhbW1lckdlc3R1cmVzUGx1Z2luID0gX0hhbW1lckdlc3R1cmVzUGx1Z2luOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoSGFtbWVyR2VzdHVyZXNQbHVnaW4sIFt7CiAgICB0eXBlOiBJbmplY3RhYmxlCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtET0NVTUVOVF0KICAgIH1dCiAgfSwgewogICAgdHlwZTogSGFtbWVyR2VzdHVyZUNvbmZpZywKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0hBTU1FUl9HRVNUVVJFX0NPTkZJR10KICAgIH1dCiAgfSwgewogICAgdHlwZTogQ29uc29sZQogIH0sIHsKICAgIHR5cGU6IHZvaWQgMCwKICAgIGRlY29yYXRvcnM6IFt7CiAgICAgIHR5cGU6IE9wdGlvbmFsCiAgICB9LCB7CiAgICAgIHR5cGU6IEluamVjdCwKICAgICAgYXJnczogW0hBTU1FUl9MT0FERVJdCiAgICB9XQogIH1dLCBudWxsKTsKfSkoKTsKdmFyIF9IYW1tZXJNb2R1bGUgPSBjbGFzcyBfSGFtbWVyTW9kdWxlIHsKfTsKX0hhbW1lck1vZHVsZS7JtWZhYyA9IGZ1bmN0aW9uIEhhbW1lck1vZHVsZV9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9IYW1tZXJNb2R1bGUpKCk7Cn07Cl9IYW1tZXJNb2R1bGUuybVtb2QgPSDJtcm1ZGVmaW5lTmdNb2R1bGUoewogIHR5cGU6IF9IYW1tZXJNb2R1bGUKfSk7Cl9IYW1tZXJNb2R1bGUuybVpbmogPSDJtcm1ZGVmaW5lSW5qZWN0b3IoewogIHByb3ZpZGVyczogW3sKICAgIHByb3ZpZGU6IEVWRU5UX01BTkFHRVJfUExVR0lOUywKICAgIHVzZUNsYXNzOiBIYW1tZXJHZXN0dXJlc1BsdWdpbiwKICAgIG11bHRpOiB0cnVlLAogICAgZGVwczogW0RPQ1VNRU5ULCBIQU1NRVJfR0VTVFVSRV9DT05GSUcsIENvbnNvbGUsIFtuZXcgT3B0aW9uYWwoKSwgSEFNTUVSX0xPQURFUl1dCiAgfSwgewogICAgcHJvdmlkZTogSEFNTUVSX0dFU1RVUkVfQ09ORklHLAogICAgdXNlQ2xhc3M6IEhhbW1lckdlc3R1cmVDb25maWcsCiAgICBkZXBzOiBbXQogIH1dCn0pOwp2YXIgSGFtbWVyTW9kdWxlID0gX0hhbW1lck1vZHVsZTsKKCgpID0+IHsKICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gInVuZGVmaW5lZCIgfHwgbmdEZXZNb2RlKSAmJiBzZXRDbGFzc01ldGFkYXRhKEhhbW1lck1vZHVsZSwgW3sKICAgIHR5cGU6IE5nTW9kdWxlLAogICAgYXJnczogW3sKICAgICAgcHJvdmlkZXJzOiBbewogICAgICAgIHByb3ZpZGU6IEVWRU5UX01BTkFHRVJfUExVR0lOUywKICAgICAgICB1c2VDbGFzczogSGFtbWVyR2VzdHVyZXNQbHVnaW4sCiAgICAgICAgbXVsdGk6IHRydWUsCiAgICAgICAgZGVwczogW0RPQ1VNRU5ULCBIQU1NRVJfR0VTVFVSRV9DT05GSUcsIENvbnNvbGUsIFtuZXcgT3B0aW9uYWwoKSwgSEFNTUVSX0xPQURFUl1dCiAgICAgIH0sIHsKICAgICAgICBwcm92aWRlOiBIQU1NRVJfR0VTVFVSRV9DT05GSUcsCiAgICAgICAgdXNlQ2xhc3M6IEhhbW1lckdlc3R1cmVDb25maWcsCiAgICAgICAgZGVwczogW10KICAgICAgfV0KICAgIH1dCiAgfV0sIG51bGwsIG51bGwpOwp9KSgpOwp2YXIgX0RvbVNhbml0aXplciA9IGNsYXNzIF9Eb21TYW5pdGl6ZXIgewp9OwpfRG9tU2FuaXRpemVyLsm1ZmFjID0gZnVuY3Rpb24gRG9tU2FuaXRpemVyX0ZhY3RvcnkodCkgewogIHJldHVybiBuZXcgKHQgfHwgX0RvbVNhbml0aXplcikoKTsKfTsKX0RvbVNhbml0aXplci7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7CiAgdG9rZW46IF9Eb21TYW5pdGl6ZXIsCiAgZmFjdG9yeTogZnVuY3Rpb24gRG9tU2FuaXRpemVyX0ZhY3RvcnkodCkgewogICAgbGV0IHIgPSBudWxsOwogICAgaWYgKHQpIHsKICAgICAgciA9IG5ldyAodCB8fCBfRG9tU2FuaXRpemVyKSgpOwogICAgfSBlbHNlIHsKICAgICAgciA9IMm1ybVpbmplY3QoRG9tU2FuaXRpemVySW1wbCk7CiAgICB9CiAgICByZXR1cm4gcjsKICB9LAogIHByb3ZpZGVkSW46ICJyb290Igp9KTsKdmFyIERvbVNhbml0aXplciA9IF9Eb21TYW5pdGl6ZXI7CigoKSA9PiB7CiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICJ1bmRlZmluZWQiIHx8IG5nRGV2TW9kZSkgJiYgc2V0Q2xhc3NNZXRhZGF0YShEb21TYW5pdGl6ZXIsIFt7CiAgICB0eXBlOiBJbmplY3RhYmxlLAogICAgYXJnczogW3sKICAgICAgcHJvdmlkZWRJbjogInJvb3QiLAogICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBEb21TYW5pdGl6ZXJJbXBsKQogICAgfV0KICB9XSwgbnVsbCwgbnVsbCk7Cn0pKCk7CnZhciBfRG9tU2FuaXRpemVySW1wbCA9IGNsYXNzIF9Eb21TYW5pdGl6ZXJJbXBsIGV4dGVuZHMgRG9tU2FuaXRpemVyIHsKICBjb25zdHJ1Y3RvcihfZG9jKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5fZG9jID0gX2RvYzsKICB9CiAgc2FuaXRpemUoY3R4LCB2YWx1ZSkgewogICAgaWYgKHZhbHVlID09IG51bGwpCiAgICAgIHJldHVybiBudWxsOwogICAgc3dpdGNoIChjdHgpIHsKICAgICAgY2FzZSBTZWN1cml0eUNvbnRleHQuTk9ORToKICAgICAgICByZXR1cm4gdmFsdWU7CiAgICAgIGNhc2UgU2VjdXJpdHlDb250ZXh0LkhUTUw6CiAgICAgICAgaWYgKGFsbG93U2FuaXRpemF0aW9uQnlwYXNzQW5kVGhyb3coCiAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICJIVE1MIgogICAgICAgICAgLyogQnlwYXNzVHlwZS5IdG1sICovCiAgICAgICAgKSkgewogICAgICAgICAgcmV0dXJuIHVud3JhcFNhZmVWYWx1ZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBfc2FuaXRpemVIdG1sKHRoaXMuX2RvYywgU3RyaW5nKHZhbHVlKSkudG9TdHJpbmcoKTsKICAgICAgY2FzZSBTZWN1cml0eUNvbnRleHQuU1RZTEU6CiAgICAgICAgaWYgKGFsbG93U2FuaXRpemF0aW9uQnlwYXNzQW5kVGhyb3coCiAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICJTdHlsZSIKICAgICAgICAgIC8qIEJ5cGFzc1R5cGUuU3R5bGUgKi8KICAgICAgICApKSB7CiAgICAgICAgICByZXR1cm4gdW53cmFwU2FmZVZhbHVlKHZhbHVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHZhbHVlOwogICAgICBjYXNlIFNlY3VyaXR5Q29udGV4dC5TQ1JJUFQ6CiAgICAgICAgaWYgKGFsbG93U2FuaXRpemF0aW9uQnlwYXNzQW5kVGhyb3coCiAgICAgICAgICB2YWx1ZSwKICAgICAgICAgICJTY3JpcHQiCiAgICAgICAgICAvKiBCeXBhc3NUeXBlLlNjcmlwdCAqLwogICAgICAgICkpIHsKICAgICAgICAgIHJldHVybiB1bndyYXBTYWZlVmFsdWUodmFsdWUpOwogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDUyMDAsICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmICJ1bnNhZmUgdmFsdWUgdXNlZCBpbiBhIHNjcmlwdCBjb250ZXh0Iik7CiAgICAgIGNhc2UgU2VjdXJpdHlDb250ZXh0LlVSTDoKICAgICAgICBpZiAoYWxsb3dTYW5pdGl6YXRpb25CeXBhc3NBbmRUaHJvdygKICAgICAgICAgIHZhbHVlLAogICAgICAgICAgIlVSTCIKICAgICAgICAgIC8qIEJ5cGFzc1R5cGUuVXJsICovCiAgICAgICAgKSkgewogICAgICAgICAgcmV0dXJuIHVud3JhcFNhZmVWYWx1ZSh2YWx1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBfc2FuaXRpemVVcmwoU3RyaW5nKHZhbHVlKSk7CiAgICAgIGNhc2UgU2VjdXJpdHlDb250ZXh0LlJFU09VUkNFX1VSTDoKICAgICAgICBpZiAoYWxsb3dTYW5pdGl6YXRpb25CeXBhc3NBbmRUaHJvdygKICAgICAgICAgIHZhbHVlLAogICAgICAgICAgIlJlc291cmNlVVJMIgogICAgICAgICAgLyogQnlwYXNzVHlwZS5SZXNvdXJjZVVybCAqLwogICAgICAgICkpIHsKICAgICAgICAgIHJldHVybiB1bndyYXBTYWZlVmFsdWUodmFsdWUpOwogICAgICAgIH0KICAgICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDUyMDEsICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIGB1bnNhZmUgdmFsdWUgdXNlZCBpbiBhIHJlc291cmNlIFVSTCBjb250ZXh0IChzZWUgJHtYU1NfU0VDVVJJVFlfVVJMfSlgKTsKICAgICAgZGVmYXVsdDoKICAgICAgICB0aHJvdyBuZXcgUnVudGltZUVycm9yKDUyMDIsICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIGBVbmV4cGVjdGVkIFNlY3VyaXR5Q29udGV4dCAke2N0eH0gKHNlZSAke1hTU19TRUNVUklUWV9VUkx9KWApOwogICAgfQogIH0KICBieXBhc3NTZWN1cml0eVRydXN0SHRtbCh2YWx1ZSkgewogICAgcmV0dXJuIGJ5cGFzc1Nhbml0aXphdGlvblRydXN0SHRtbCh2YWx1ZSk7CiAgfQogIGJ5cGFzc1NlY3VyaXR5VHJ1c3RTdHlsZSh2YWx1ZSkgewogICAgcmV0dXJuIGJ5cGFzc1Nhbml0aXphdGlvblRydXN0U3R5bGUodmFsdWUpOwogIH0KICBieXBhc3NTZWN1cml0eVRydXN0U2NyaXB0KHZhbHVlKSB7CiAgICByZXR1cm4gYnlwYXNzU2FuaXRpemF0aW9uVHJ1c3RTY3JpcHQodmFsdWUpOwogIH0KICBieXBhc3NTZWN1cml0eVRydXN0VXJsKHZhbHVlKSB7CiAgICByZXR1cm4gYnlwYXNzU2FuaXRpemF0aW9uVHJ1c3RVcmwodmFsdWUpOwogIH0KICBieXBhc3NTZWN1cml0eVRydXN0UmVzb3VyY2VVcmwodmFsdWUpIHsKICAgIHJldHVybiBieXBhc3NTYW5pdGl6YXRpb25UcnVzdFJlc291cmNlVXJsKHZhbHVlKTsKICB9Cn07Cl9Eb21TYW5pdGl6ZXJJbXBsLsm1ZmFjID0gZnVuY3Rpb24gRG9tU2FuaXRpemVySW1wbF9GYWN0b3J5KHQpIHsKICByZXR1cm4gbmV3ICh0IHx8IF9Eb21TYW5pdGl6ZXJJbXBsKSjJtcm1aW5qZWN0KERPQ1VNRU5UKSk7Cn07Cl9Eb21TYW5pdGl6ZXJJbXBsLsm1cHJvdiA9IMm1ybVkZWZpbmVJbmplY3RhYmxlKHsKICB0b2tlbjogX0RvbVNhbml0aXplckltcGwsCiAgZmFjdG9yeTogX0RvbVNhbml0aXplckltcGwuybVmYWMsCiAgcHJvdmlkZWRJbjogInJvb3QiCn0pOwp2YXIgRG9tU2FuaXRpemVySW1wbCA9IF9Eb21TYW5pdGl6ZXJJbXBsOwooKCkgPT4gewogICh0eXBlb2YgbmdEZXZNb2RlID09PSAidW5kZWZpbmVkIiB8fCBuZ0Rldk1vZGUpICYmIHNldENsYXNzTWV0YWRhdGEoRG9tU2FuaXRpemVySW1wbCwgW3sKICAgIHR5cGU6IEluamVjdGFibGUsCiAgICBhcmdzOiBbewogICAgICBwcm92aWRlZEluOiAicm9vdCIKICAgIH1dCiAgfV0sICgpID0+IFt7CiAgICB0eXBlOiB2b2lkIDAsCiAgICBkZWNvcmF0b3JzOiBbewogICAgICB0eXBlOiBJbmplY3QsCiAgICAgIGFyZ3M6IFtET0NVTUVOVF0KICAgIH1dCiAgfV0sIG51bGwpOwp9KSgpOwp2YXIgSHlkcmF0aW9uRmVhdHVyZUtpbmQ7CihmdW5jdGlvbihIeWRyYXRpb25GZWF0dXJlS2luZDIpIHsKICBIeWRyYXRpb25GZWF0dXJlS2luZDJbSHlkcmF0aW9uRmVhdHVyZUtpbmQyWyJOb0h0dHBUcmFuc2ZlckNhY2hlIl0gPSAwXSA9ICJOb0h0dHBUcmFuc2ZlckNhY2hlIjsKICBIeWRyYXRpb25GZWF0dXJlS2luZDJbSHlkcmF0aW9uRmVhdHVyZUtpbmQyWyJIdHRwVHJhbnNmZXJDYWNoZU9wdGlvbnMiXSA9IDFdID0gIkh0dHBUcmFuc2ZlckNhY2hlT3B0aW9ucyI7CiAgSHlkcmF0aW9uRmVhdHVyZUtpbmQyW0h5ZHJhdGlvbkZlYXR1cmVLaW5kMlsiSTE4blN1cHBvcnQiXSA9IDJdID0gIkkxOG5TdXBwb3J0IjsKICBIeWRyYXRpb25GZWF0dXJlS2luZDJbSHlkcmF0aW9uRmVhdHVyZUtpbmQyWyJFdmVudFJlcGxheSJdID0gM10gPSAiRXZlbnRSZXBsYXkiOwp9KShIeWRyYXRpb25GZWF0dXJlS2luZCB8fCAoSHlkcmF0aW9uRmVhdHVyZUtpbmQgPSB7fSkpOwpmdW5jdGlvbiBoeWRyYXRpb25GZWF0dXJlKMm1a2luZCwgybVwcm92aWRlcnMgPSBbXSwgybVvcHRpb25zID0ge30pIHsKICByZXR1cm4gewogICAgybVraW5kLAogICAgybVwcm92aWRlcnMKICB9Owp9CmZ1bmN0aW9uIHdpdGhOb0h0dHBUcmFuc2ZlckNhY2hlKCkgewogIHJldHVybiBoeWRyYXRpb25GZWF0dXJlKEh5ZHJhdGlvbkZlYXR1cmVLaW5kLk5vSHR0cFRyYW5zZmVyQ2FjaGUpOwp9CmZ1bmN0aW9uIHdpdGhIdHRwVHJhbnNmZXJDYWNoZU9wdGlvbnMob3B0aW9ucykgewogIHJldHVybiBoeWRyYXRpb25GZWF0dXJlKEh5ZHJhdGlvbkZlYXR1cmVLaW5kLkh0dHBUcmFuc2ZlckNhY2hlT3B0aW9ucywgd2l0aEh0dHBUcmFuc2ZlckNhY2hlKG9wdGlvbnMpKTsKfQpmdW5jdGlvbiB3aXRoSTE4blN1cHBvcnQyKCkgewogIHJldHVybiBoeWRyYXRpb25GZWF0dXJlKEh5ZHJhdGlvbkZlYXR1cmVLaW5kLkkxOG5TdXBwb3J0LCB3aXRoSTE4blN1cHBvcnQoKSk7Cn0KZnVuY3Rpb24gd2l0aEV2ZW50UmVwbGF5MigpIHsKICByZXR1cm4gaHlkcmF0aW9uRmVhdHVyZShIeWRyYXRpb25GZWF0dXJlS2luZC5FdmVudFJlcGxheSwgd2l0aEV2ZW50UmVwbGF5KCkpOwp9CmZ1bmN0aW9uIHByb3ZpZGVab25lSnNDb21wYXRpYmlsaXR5RGV0ZWN0b3IoKSB7CiAgcmV0dXJuIFt7CiAgICBwcm92aWRlOiBFTlZJUk9OTUVOVF9JTklUSUFMSVpFUiwKICAgIHVzZVZhbHVlOiAoKSA9PiB7CiAgICAgIGNvbnN0IG5nWm9uZSA9IGluamVjdChOZ1pvbmUpOwogICAgICBpZiAobmdab25lLmNvbnN0cnVjdG9yICE9PSBOZ1pvbmUpIHsKICAgICAgICBjb25zdCBjb25zb2xlMiA9IGluamVjdChDb25zb2xlKTsKICAgICAgICBjb25zdCBtZXNzYWdlID0gZm9ybWF0UnVudGltZUVycm9yKC01ZTMsICJBbmd1bGFyIGRldGVjdGVkIHRoYXQgaHlkcmF0aW9uIHdhcyBlbmFibGVkIGZvciBhbiBhcHBsaWNhdGlvbiB0aGF0IHVzZXMgYSBjdXN0b20gb3IgYSBub29wIFpvbmUuanMgaW1wbGVtZW50YXRpb24uIFRoaXMgaXMgbm90IHlldCBhIGZ1bGx5IHN1cHBvcnRlZCBjb25maWd1cmF0aW9uLiIpOwogICAgICAgIGNvbnNvbGUyLndhcm4obWVzc2FnZSk7CiAgICAgIH0KICAgIH0sCiAgICBtdWx0aTogdHJ1ZQogIH1dOwp9CmZ1bmN0aW9uIHByb3ZpZGVDbGllbnRIeWRyYXRpb24oLi4uZmVhdHVyZXMpIHsKICBjb25zdCBwcm92aWRlcnMgPSBbXTsKICBjb25zdCBmZWF0dXJlc0tpbmQgPSAvKiBAX19QVVJFX18gKi8gbmV3IFNldCgpOwogIGNvbnN0IGhhc0h0dHBUcmFuc2ZlckNhY2hlT3B0aW9ucyA9IGZlYXR1cmVzS2luZC5oYXMoSHlkcmF0aW9uRmVhdHVyZUtpbmQuSHR0cFRyYW5zZmVyQ2FjaGVPcHRpb25zKTsKICBmb3IgKGNvbnN0IHsKICAgIMm1cHJvdmlkZXJzLAogICAgybVraW5kCiAgfSBvZiBmZWF0dXJlcykgewogICAgZmVhdHVyZXNLaW5kLmFkZCjJtWtpbmQpOwogICAgaWYgKMm1cHJvdmlkZXJzLmxlbmd0aCkgewogICAgICBwcm92aWRlcnMucHVzaCjJtXByb3ZpZGVycyk7CiAgICB9CiAgfQogIGlmICh0eXBlb2YgbmdEZXZNb2RlICE9PSAidW5kZWZpbmVkIiAmJiBuZ0Rldk1vZGUgJiYgZmVhdHVyZXNLaW5kLmhhcyhIeWRyYXRpb25GZWF0dXJlS2luZC5Ob0h0dHBUcmFuc2ZlckNhY2hlKSAmJiBoYXNIdHRwVHJhbnNmZXJDYWNoZU9wdGlvbnMpIHsKICAgIHRocm93IG5ldyBFcnJvcigiQ29uZmlndXJhdGlvbiBlcnJvcjogZm91bmQgYm90aCB3aXRoSHR0cFRyYW5zZmVyQ2FjaGVPcHRpb25zKCkgYW5kIHdpdGhOb0h0dHBUcmFuc2ZlckNhY2hlKCkgaW4gdGhlIHNhbWUgY2FsbCB0byBwcm92aWRlQ2xpZW50SHlkcmF0aW9uKCksIHdoaWNoIGlzIGEgY29udHJhZGljdGlvbi4iKTsKICB9CiAgcmV0dXJuIG1ha2VFbnZpcm9ubWVudFByb3ZpZGVycyhbdHlwZW9mIG5nRGV2TW9kZSAhPT0gInVuZGVmaW5lZCIgJiYgbmdEZXZNb2RlID8gcHJvdmlkZVpvbmVKc0NvbXBhdGliaWxpdHlEZXRlY3RvcigpIDogW10sIHdpdGhEb21IeWRyYXRpb24oKSwgZmVhdHVyZXNLaW5kLmhhcyhIeWRyYXRpb25GZWF0dXJlS2luZC5Ob0h0dHBUcmFuc2ZlckNhY2hlKSB8fCBoYXNIdHRwVHJhbnNmZXJDYWNoZU9wdGlvbnMgPyBbXSA6IHdpdGhIdHRwVHJhbnNmZXJDYWNoZSh7fSksIHByb3ZpZGVyc10pOwp9CnZhciBWRVJTSU9OMiA9IG5ldyBWZXJzaW9uKCIxOC4wLjUiKTsKZXhwb3J0IHsKICBCcm93c2VyTW9kdWxlLAogIEJ5LAogIERvbVNhbml0aXplciwKICBFVkVOVF9NQU5BR0VSX1BMVUdJTlMsCiAgRXZlbnRNYW5hZ2VyLAogIEV2ZW50TWFuYWdlclBsdWdpbiwKICBIQU1NRVJfR0VTVFVSRV9DT05GSUcsCiAgSEFNTUVSX0xPQURFUiwKICBIYW1tZXJHZXN0dXJlQ29uZmlnLAogIEhhbW1lck1vZHVsZSwKICBIeWRyYXRpb25GZWF0dXJlS2luZCwKICBNZXRhLAogIFJFTU9WRV9TVFlMRVNfT05fQ09NUE9ORU5UX0RFU1RST1ksCiAgVGl0bGUsCiAgVkVSU0lPTjIgYXMgVkVSU0lPTiwKICBib290c3RyYXBBcHBsaWNhdGlvbiwKICBjcmVhdGVBcHBsaWNhdGlvbiwKICBkaXNhYmxlRGVidWdUb29scywKICBlbmFibGVEZWJ1Z1Rvb2xzLAogIHBsYXRmb3JtQnJvd3NlciwKICBwcm92aWRlQ2xpZW50SHlkcmF0aW9uLAogIHByb3ZpZGVQcm90cmFjdG9yVGVzdGluZ1N1cHBvcnQsCiAgd2l0aEV2ZW50UmVwbGF5MiBhcyB3aXRoRXZlbnRSZXBsYXksCiAgd2l0aEh0dHBUcmFuc2ZlckNhY2hlT3B0aW9ucywKICB3aXRoSTE4blN1cHBvcnQyIGFzIHdpdGhJMThuU3VwcG9ydCwKICB3aXRoTm9IdHRwVHJhbnNmZXJDYWNoZSwKICBCcm93c2VyRG9tQWRhcHRlciBhcyDJtUJyb3dzZXJEb21BZGFwdGVyLAogIEJyb3dzZXJHZXRUZXN0YWJpbGl0eSBhcyDJtUJyb3dzZXJHZXRUZXN0YWJpbGl0eSwKICBEb21FdmVudHNQbHVnaW4gYXMgybVEb21FdmVudHNQbHVnaW4sCiAgRG9tUmVuZGVyZXJGYWN0b3J5MiBhcyDJtURvbVJlbmRlcmVyRmFjdG9yeTIsCiAgRG9tU2FuaXRpemVySW1wbCBhcyDJtURvbVNhbml0aXplckltcGwsCiAgSGFtbWVyR2VzdHVyZXNQbHVnaW4gYXMgybVIYW1tZXJHZXN0dXJlc1BsdWdpbiwKICBJTlRFUk5BTF9CUk9XU0VSX1BMQVRGT1JNX1BST1ZJREVSUyBhcyDJtUlOVEVSTkFMX0JST1dTRVJfUExBVEZPUk1fUFJPVklERVJTLAogIEtleUV2ZW50c1BsdWdpbiBhcyDJtUtleUV2ZW50c1BsdWdpbiwKICBTaGFyZWRTdHlsZXNIb3N0IGFzIMm1U2hhcmVkU3R5bGVzSG9zdCwKICBnZXRET00gYXMgybVnZXRET00sCiAgaW5pdERvbUFkYXB0ZXIgYXMgybVpbml0RG9tQWRhcHRlcgp9OwovKiEgQnVuZGxlZCBsaWNlbnNlIGluZm9ybWF0aW9uOgoKQGFuZ3VsYXIvY29tbW9uL2Zlc20yMDIyL2NvbW1vbi5tanM6CiAgKCoqCiAgICogQGxpY2Vuc2UgQW5ndWxhciB2MTguMC41CiAgICogKGMpIDIwMTAtMjAyNCBHb29nbGUgTExDLiBodHRwczovL2FuZ3VsYXIuaW8vCiAgICogTGljZW5zZTogTUlUCiAgICopCgpAYW5ndWxhci9jb21tb24vZmVzbTIwMjIvaHR0cC5tanM6CiAgKCoqCiAgICogQGxpY2Vuc2UgQW5ndWxhciB2MTguMC41CiAgICogKGMpIDIwMTAtMjAyNCBHb29nbGUgTExDLiBodHRwczovL2FuZ3VsYXIuaW8vCiAgICogTGljZW5zZTogTUlUCiAgICopCgpAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyL2Zlc20yMDIyL3BsYXRmb3JtLWJyb3dzZXIubWpzOgogICgqKgogICAqIEBsaWNlbnNlIEFuZ3VsYXIgdjE4LjAuNQogICAqIChjKSAyMDEwLTIwMjQgR29vZ2xlIExMQy4gaHR0cHM6Ly9hbmd1bGFyLmlvLwogICAqIExpY2Vuc2U6IE1JVAogICAqKQoqLwovLyMgc291cmNlTWFwcGluZ1VSTD1AYW5ndWxhcl9wbGF0Zm9ybS1icm93c2VyLmpzLm1hcApQSwMECgAAAAAAmnHsWKSblUorfAoAK3wKAEAAAAAuYW5ndWxhci9jYWNoZS8xOC4wLjYvdml0ZS9kZXBzL0Bhbmd1bGFyX3BsYXRmb3JtLWJyb3dzZXIuanMubWFwewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL0Bhbmd1bGFyL2NvbW1vbi9mZXNtMjAyMi9jb21tb24ubWpzIiwgIi4uLy4uLy4uLy4uLy4uL25vZGVfbW9kdWxlcy9AYW5ndWxhci9jb21tb24vZmVzbTIwMjIvaHR0cC5tanMiLCAiLi4vLi4vLi4vLi4vLi4vbm9kZV9tb2R1bGVzL0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXIvZmVzbTIwMjIvcGxhdGZvcm0tYnJvd3Nlci5tanMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8qKlxuICogQGxpY2Vuc2UgQW5ndWxhciB2MTguMC41XG4gKiAoYykgMjAxMC0yMDI0IEdvb2dsZSBMTEMuIGh0dHBzOi8vYW5ndWxhci5pby9cbiAqIExpY2Vuc2U6IE1JVFxuICovXG5cbmltcG9ydCAqIGFzIGkwIGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSwgSW5qZWN0aW9uVG9rZW4sIGluamVjdCwgT3B0aW9uYWwsIEluamVjdCwgRXZlbnRFbWl0dGVyLCDJtcm1aW5qZWN0LCDJtWZpbmRMb2NhbGVEYXRhLCDJtUxvY2FsZURhdGFJbmRleCwgybVnZXRMb2NhbGVDdXJyZW5jeUNvZGUsIMm1Z2V0TG9jYWxlUGx1cmFsQ2FzZSwgTE9DQUxFX0lELCDJtXJlZ2lzdGVyTG9jYWxlRGF0YSwgybVzdHJpbmdpZnksIERpcmVjdGl2ZSwgSW5wdXQsIGNyZWF0ZU5nTW9kdWxlLCBOZ01vZHVsZVJlZiwgybVSdW50aW1lRXJyb3IsIMm1Zm9ybWF0UnVudGltZUVycm9yLCBIb3N0LCBBdHRyaWJ1dGUsIFJlbmRlcmVyU3R5bGVGbGFnczIsIHVudHJhY2tlZCwgybVpc1Byb21pc2UsIMm1aXNTdWJzY3JpYmFibGUsIFBpcGUsIERFRkFVTFRfQ1VSUkVOQ1lfQ09ERSwgTmdNb2R1bGUsIFZlcnNpb24sIMm1ybVkZWZpbmVJbmplY3RhYmxlLCBQTEFURk9STV9JRCwgybVJTUFHRV9DT05GSUcsIFJlbmRlcmVyMiwgRWxlbWVudFJlZiwgSW5qZWN0b3IsIMm1cGVyZm9ybWFuY2VNYXJrRmVhdHVyZSwgTmdab25lLCBDaGFuZ2VEZXRlY3RvclJlZiwgbnVtYmVyQXR0cmlidXRlLCBib29sZWFuQXR0cmlidXRlLCDJtUlNQUdFX0NPTkZJR19ERUZBVUxUUywgybV1bndyYXBTYWZlVmFsdWUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmV4cG9ydCB7IMm1SU1BR0VfQ09ORklHIGFzIElNQUdFX0NPTkZJRyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xubGV0IF9ET00gPSBudWxsO1xuZnVuY3Rpb24gZ2V0RE9NKCkge1xuICByZXR1cm4gX0RPTTtcbn1cbmZ1bmN0aW9uIHNldFJvb3REb21BZGFwdGVyKGFkYXB0ZXIpIHtcbiAgX0RPTSA/Pz0gYWRhcHRlcjtcbn1cbi8qIHRzbGludDpkaXNhYmxlOnJlcXVpcmVQYXJhbWV0ZXJUeXBlICovXG4vKipcbiAqIFByb3ZpZGVzIERPTSBvcGVyYXRpb25zIGluIGFuIGVudmlyb25tZW50LWFnbm9zdGljIHdheS5cbiAqXG4gKiBAc2VjdXJpdHkgVHJlYWQgY2FyZWZ1bGx5ISBJbnRlcmFjdGluZyB3aXRoIHRoZSBET00gZGlyZWN0bHkgaXMgZGFuZ2Vyb3VzIGFuZFxuICogY2FuIGludHJvZHVjZSBYU1Mgcmlza3MuXG4gKi9cbmNsYXNzIERvbUFkYXB0ZXIge31cblxuLyoqXG4gKiBUaGlzIGNsYXNzIHdyYXBzIHRoZSBwbGF0Zm9ybSBOYXZpZ2F0aW9uIEFQSSB3aGljaCBhbGxvd3Mgc2VydmVyLXNwZWNpZmljIGFuZCB0ZXN0XG4gKiBpbXBsZW1lbnRhdGlvbnMuXG4gKi9cbmNsYXNzIFBsYXRmb3JtTmF2aWdhdGlvbiB7XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIFBsYXRmb3JtTmF2aWdhdGlvbl9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgUGxhdGZvcm1OYXZpZ2F0aW9uKSgpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1cHJvdiA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVJbmplY3RhYmxlKHtcbiAgICAgIHRva2VuOiBQbGF0Zm9ybU5hdmlnYXRpb24sXG4gICAgICBmYWN0b3J5OiAoKSA9PiAoKCkgPT4gd2luZG93Lm5hdmlnYXRpb24pKCksXG4gICAgICBwcm92aWRlZEluOiAncGxhdGZvcm0nXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKFBsYXRmb3JtTmF2aWdhdGlvbiwgW3tcbiAgICB0eXBlOiBJbmplY3RhYmxlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBwcm92aWRlZEluOiAncGxhdGZvcm0nLFxuICAgICAgdXNlRmFjdG9yeTogKCkgPT4gd2luZG93Lm5hdmlnYXRpb25cbiAgICB9XVxuICB9XSwgbnVsbCwgbnVsbCk7XG59KSgpO1xuXG4vKipcbiAqIEEgREkgVG9rZW4gcmVwcmVzZW50aW5nIHRoZSBtYWluIHJlbmRlcmluZyBjb250ZXh0LlxuICogSW4gYSBicm93c2VyIGFuZCBTU1IgdGhpcyBpcyB0aGUgRE9NIERvY3VtZW50LlxuICogV2hlbiB1c2luZyBTU1IsIHRoYXQgZG9jdW1lbnQgaXMgY3JlYXRlZCBieSBbRG9taW5vXShodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9kb21pbm8pLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY29uc3QgRE9DVU1FTlQgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gJ0RvY3VtZW50VG9rZW4nIDogJycpO1xuXG4vKipcbiAqIFRoaXMgY2xhc3Mgc2hvdWxkIG5vdCBiZSB1c2VkIGRpcmVjdGx5IGJ5IGFuIGFwcGxpY2F0aW9uIGRldmVsb3Blci4gSW5zdGVhZCwgdXNlXG4gKiB7QGxpbmsgTG9jYXRpb259LlxuICpcbiAqIGBQbGF0Zm9ybUxvY2F0aW9uYCBlbmNhcHN1bGF0ZXMgYWxsIGNhbGxzIHRvIERPTSBBUElzLCB3aGljaCBhbGxvd3MgdGhlIFJvdXRlciB0byBiZVxuICogcGxhdGZvcm0tYWdub3N0aWMuXG4gKiBUaGlzIG1lYW5zIHRoYXQgd2UgY2FuIGhhdmUgZGlmZmVyZW50IGltcGxlbWVudGF0aW9uIG9mIGBQbGF0Zm9ybUxvY2F0aW9uYCBmb3IgdGhlIGRpZmZlcmVudFxuICogcGxhdGZvcm1zIHRoYXQgQW5ndWxhciBzdXBwb3J0cy4gRm9yIGV4YW1wbGUsIGBAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyYCBwcm92aWRlcyBhblxuICogaW1wbGVtZW50YXRpb24gc3BlY2lmaWMgdG8gdGhlIGJyb3dzZXIgZW52aXJvbm1lbnQsIHdoaWxlIGBAYW5ndWxhci9wbGF0Zm9ybS1zZXJ2ZXJgIHByb3ZpZGVzXG4gKiBvbmUgc3VpdGFibGUgZm9yIHVzZSB3aXRoIHNlcnZlci1zaWRlIHJlbmRlcmluZy5cbiAqXG4gKiBUaGUgYFBsYXRmb3JtTG9jYXRpb25gIGNsYXNzIGlzIHVzZWQgZGlyZWN0bHkgYnkgYWxsIGltcGxlbWVudGF0aW9ucyBvZiB7QGxpbmsgTG9jYXRpb25TdHJhdGVneX1cbiAqIHdoZW4gdGhleSBuZWVkIHRvIGludGVyYWN0IHdpdGggdGhlIERPTSBBUElzIGxpa2UgcHVzaFN0YXRlLCBwb3BTdGF0ZSwgZXRjLlxuICpcbiAqIHtAbGluayBMb2NhdGlvblN0cmF0ZWd5fSBpbiB0dXJuIGlzIHVzZWQgYnkgdGhlIHtAbGluayBMb2NhdGlvbn0gc2VydmljZSB3aGljaCBpcyB1c2VkIGRpcmVjdGx5XG4gKiBieSB0aGUge0BsaW5rIFJvdXRlcn0gaW4gb3JkZXIgdG8gbmF2aWdhdGUgYmV0d2VlbiByb3V0ZXMuIFNpbmNlIGFsbCBpbnRlcmFjdGlvbnMgYmV0d2VlbiB7QGxpbmtcbiAqIFJvdXRlcn0gL1xuICoge0BsaW5rIExvY2F0aW9ufSAvIHtAbGluayBMb2NhdGlvblN0cmF0ZWd5fSBhbmQgRE9NIEFQSXMgZmxvdyB0aHJvdWdoIHRoZSBgUGxhdGZvcm1Mb2NhdGlvbmBcbiAqIGNsYXNzLCB0aGV5IGFyZSBhbGwgcGxhdGZvcm0tYWdub3N0aWMuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBQbGF0Zm9ybUxvY2F0aW9uIHtcbiAgaGlzdG9yeUdvKHJlbGF0aXZlUG9zaXRpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IobmdEZXZNb2RlID8gJ05vdCBpbXBsZW1lbnRlZCcgOiAnJyk7XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gUGxhdGZvcm1Mb2NhdGlvbl9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgUGxhdGZvcm1Mb2NhdGlvbikoKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXByb3YgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lSW5qZWN0YWJsZSh7XG4gICAgICB0b2tlbjogUGxhdGZvcm1Mb2NhdGlvbixcbiAgICAgIGZhY3Rvcnk6ICgpID0+ICgoKSA9PiBpbmplY3QoQnJvd3NlclBsYXRmb3JtTG9jYXRpb24pKSgpLFxuICAgICAgcHJvdmlkZWRJbjogJ3BsYXRmb3JtJ1xuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShQbGF0Zm9ybUxvY2F0aW9uLCBbe1xuICAgIHR5cGU6IEluamVjdGFibGUsXG4gICAgYXJnczogW3tcbiAgICAgIHByb3ZpZGVkSW46ICdwbGF0Zm9ybScsXG4gICAgICB1c2VGYWN0b3J5OiAoKSA9PiBpbmplY3QoQnJvd3NlclBsYXRmb3JtTG9jYXRpb24pXG4gICAgfV1cbiAgfV0sIG51bGwsIG51bGwpO1xufSkoKTtcbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKiBJbmRpY2F0ZXMgd2hlbiBhIGxvY2F0aW9uIGlzIGluaXRpYWxpemVkLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY29uc3QgTE9DQVRJT05fSU5JVElBTElaRUQgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gJ0xvY2F0aW9uIEluaXRpYWxpemVkJyA6ICcnKTtcbi8qKlxuICogYFBsYXRmb3JtTG9jYXRpb25gIGVuY2Fwc3VsYXRlcyBhbGwgb2YgdGhlIGRpcmVjdCBjYWxscyB0byBwbGF0Zm9ybSBBUElzLlxuICogVGhpcyBjbGFzcyBzaG91bGQgbm90IGJlIHVzZWQgZGlyZWN0bHkgYnkgYW4gYXBwbGljYXRpb24gZGV2ZWxvcGVyLiBJbnN0ZWFkLCB1c2VcbiAqIHtAbGluayBMb2NhdGlvbn0uXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBCcm93c2VyUGxhdGZvcm1Mb2NhdGlvbiBleHRlbmRzIFBsYXRmb3JtTG9jYXRpb24ge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX2RvYyA9IGluamVjdChET0NVTUVOVCk7XG4gICAgdGhpcy5fbG9jYXRpb24gPSB3aW5kb3cubG9jYXRpb247XG4gICAgdGhpcy5faGlzdG9yeSA9IHdpbmRvdy5oaXN0b3J5O1xuICB9XG4gIGdldEJhc2VIcmVmRnJvbURPTSgpIHtcbiAgICByZXR1cm4gZ2V0RE9NKCkuZ2V0QmFzZUhyZWYodGhpcy5fZG9jKTtcbiAgfVxuICBvblBvcFN0YXRlKGZuKSB7XG4gICAgY29uc3Qgd2luZG93ID0gZ2V0RE9NKCkuZ2V0R2xvYmFsRXZlbnRUYXJnZXQodGhpcy5fZG9jLCAnd2luZG93Jyk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3BvcHN0YXRlJywgZm4sIGZhbHNlKTtcbiAgICByZXR1cm4gKCkgPT4gd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvcHN0YXRlJywgZm4pO1xuICB9XG4gIG9uSGFzaENoYW5nZShmbikge1xuICAgIGNvbnN0IHdpbmRvdyA9IGdldERPTSgpLmdldEdsb2JhbEV2ZW50VGFyZ2V0KHRoaXMuX2RvYywgJ3dpbmRvdycpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdoYXNoY2hhbmdlJywgZm4sIGZhbHNlKTtcbiAgICByZXR1cm4gKCkgPT4gd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2hhc2hjaGFuZ2UnLCBmbik7XG4gIH1cbiAgZ2V0IGhyZWYoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2xvY2F0aW9uLmhyZWY7XG4gIH1cbiAgZ2V0IHByb3RvY29sKCkge1xuICAgIHJldHVybiB0aGlzLl9sb2NhdGlvbi5wcm90b2NvbDtcbiAgfVxuICBnZXQgaG9zdG5hbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2xvY2F0aW9uLmhvc3RuYW1lO1xuICB9XG4gIGdldCBwb3J0KCkge1xuICAgIHJldHVybiB0aGlzLl9sb2NhdGlvbi5wb3J0O1xuICB9XG4gIGdldCBwYXRobmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbG9jYXRpb24ucGF0aG5hbWU7XG4gIH1cbiAgZ2V0IHNlYXJjaCgpIHtcbiAgICByZXR1cm4gdGhpcy5fbG9jYXRpb24uc2VhcmNoO1xuICB9XG4gIGdldCBoYXNoKCkge1xuICAgIHJldHVybiB0aGlzLl9sb2NhdGlvbi5oYXNoO1xuICB9XG4gIHNldCBwYXRobmFtZShuZXdQYXRoKSB7XG4gICAgdGhpcy5fbG9jYXRpb24ucGF0aG5hbWUgPSBuZXdQYXRoO1xuICB9XG4gIHB1c2hTdGF0ZShzdGF0ZSwgdGl0bGUsIHVybCkge1xuICAgIHRoaXMuX2hpc3RvcnkucHVzaFN0YXRlKHN0YXRlLCB0aXRsZSwgdXJsKTtcbiAgfVxuICByZXBsYWNlU3RhdGUoc3RhdGUsIHRpdGxlLCB1cmwpIHtcbiAgICB0aGlzLl9oaXN0b3J5LnJlcGxhY2VTdGF0ZShzdGF0ZSwgdGl0bGUsIHVybCk7XG4gIH1cbiAgZm9yd2FyZCgpIHtcbiAgICB0aGlzLl9oaXN0b3J5LmZvcndhcmQoKTtcbiAgfVxuICBiYWNrKCkge1xuICAgIHRoaXMuX2hpc3RvcnkuYmFjaygpO1xuICB9XG4gIGhpc3RvcnlHbyhyZWxhdGl2ZVBvc2l0aW9uID0gMCkge1xuICAgIHRoaXMuX2hpc3RvcnkuZ28ocmVsYXRpdmVQb3NpdGlvbik7XG4gIH1cbiAgZ2V0U3RhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2hpc3Rvcnkuc3RhdGU7XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gQnJvd3NlclBsYXRmb3JtTG9jYXRpb25fRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IEJyb3dzZXJQbGF0Zm9ybUxvY2F0aW9uKSgpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1cHJvdiA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVJbmplY3RhYmxlKHtcbiAgICAgIHRva2VuOiBCcm93c2VyUGxhdGZvcm1Mb2NhdGlvbixcbiAgICAgIGZhY3Rvcnk6ICgpID0+ICgoKSA9PiBuZXcgQnJvd3NlclBsYXRmb3JtTG9jYXRpb24oKSkoKSxcbiAgICAgIHByb3ZpZGVkSW46ICdwbGF0Zm9ybSdcbiAgICB9KTtcbiAgfVxufVxuKCgpID0+IHtcbiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09IFwidW5kZWZpbmVkXCIgfHwgbmdEZXZNb2RlKSAmJiBpMC7JtXNldENsYXNzTWV0YWRhdGEoQnJvd3NlclBsYXRmb3JtTG9jYXRpb24sIFt7XG4gICAgdHlwZTogSW5qZWN0YWJsZSxcbiAgICBhcmdzOiBbe1xuICAgICAgcHJvdmlkZWRJbjogJ3BsYXRmb3JtJyxcbiAgICAgIHVzZUZhY3Rvcnk6ICgpID0+IG5ldyBCcm93c2VyUGxhdGZvcm1Mb2NhdGlvbigpXG4gICAgfV1cbiAgfV0sICgpID0+IFtdLCBudWxsKTtcbn0pKCk7XG5cbi8qKlxuICogSm9pbnMgdHdvIHBhcnRzIG9mIGEgVVJMIHdpdGggYSBzbGFzaCBpZiBuZWVkZWQuXG4gKlxuICogQHBhcmFtIHN0YXJ0ICBVUkwgc3RyaW5nXG4gKiBAcGFyYW0gZW5kICAgIFVSTCBzdHJpbmdcbiAqXG4gKlxuICogQHJldHVybnMgVGhlIGpvaW5lZCBVUkwgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBqb2luV2l0aFNsYXNoKHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0Lmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuIGVuZDtcbiAgfVxuICBpZiAoZW5kLmxlbmd0aCA9PSAwKSB7XG4gICAgcmV0dXJuIHN0YXJ0O1xuICB9XG4gIGxldCBzbGFzaGVzID0gMDtcbiAgaWYgKHN0YXJ0LmVuZHNXaXRoKCcvJykpIHtcbiAgICBzbGFzaGVzKys7XG4gIH1cbiAgaWYgKGVuZC5zdGFydHNXaXRoKCcvJykpIHtcbiAgICBzbGFzaGVzKys7XG4gIH1cbiAgaWYgKHNsYXNoZXMgPT0gMikge1xuICAgIHJldHVybiBzdGFydCArIGVuZC5zdWJzdHJpbmcoMSk7XG4gIH1cbiAgaWYgKHNsYXNoZXMgPT0gMSkge1xuICAgIHJldHVybiBzdGFydCArIGVuZDtcbiAgfVxuICByZXR1cm4gc3RhcnQgKyAnLycgKyBlbmQ7XG59XG4vKipcbiAqIFJlbW92ZXMgYSB0cmFpbGluZyBzbGFzaCBmcm9tIGEgVVJMIHN0cmluZyBpZiBuZWVkZWQuXG4gKiBMb29rcyBmb3IgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgZWl0aGVyIGAjYCwgYD9gLCBvciB0aGUgZW5kIG9mIHRoZVxuICogbGluZSBhcyBgL2AgY2hhcmFjdGVycyBhbmQgcmVtb3ZlcyB0aGUgdHJhaWxpbmcgc2xhc2ggaWYgb25lIGV4aXN0cy5cbiAqXG4gKiBAcGFyYW0gdXJsIFVSTCBzdHJpbmcuXG4gKlxuICogQHJldHVybnMgVGhlIFVSTCBzdHJpbmcsIG1vZGlmaWVkIGlmIG5lZWRlZC5cbiAqL1xuZnVuY3Rpb24gc3RyaXBUcmFpbGluZ1NsYXNoKHVybCkge1xuICBjb25zdCBtYXRjaCA9IHVybC5tYXRjaCgvI3xcXD98JC8pO1xuICBjb25zdCBwYXRoRW5kSWR4ID0gbWF0Y2ggJiYgbWF0Y2guaW5kZXggfHwgdXJsLmxlbmd0aDtcbiAgY29uc3QgZHJvcHBlZFNsYXNoSWR4ID0gcGF0aEVuZElkeCAtICh1cmxbcGF0aEVuZElkeCAtIDFdID09PSAnLycgPyAxIDogMCk7XG4gIHJldHVybiB1cmwuc2xpY2UoMCwgZHJvcHBlZFNsYXNoSWR4KSArIHVybC5zbGljZShwYXRoRW5kSWR4KTtcbn1cbi8qKlxuICogTm9ybWFsaXplcyBVUkwgcGFyYW1ldGVycyBieSBwcmVwZW5kaW5nIHdpdGggYD9gIGlmIG5lZWRlZC5cbiAqXG4gKiBAcGFyYW0gIHBhcmFtcyBTdHJpbmcgb2YgVVJMIHBhcmFtZXRlcnMuXG4gKlxuICogQHJldHVybnMgVGhlIG5vcm1hbGl6ZWQgVVJMIHBhcmFtZXRlcnMgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVRdWVyeVBhcmFtcyhwYXJhbXMpIHtcbiAgcmV0dXJuIHBhcmFtcyAmJiBwYXJhbXNbMF0gIT09ICc/JyA/ICc/JyArIHBhcmFtcyA6IHBhcmFtcztcbn1cblxuLyoqXG4gKiBFbmFibGVzIHRoZSBgTG9jYXRpb25gIHNlcnZpY2UgdG8gcmVhZCByb3V0ZSBzdGF0ZSBmcm9tIHRoZSBicm93c2VyJ3MgVVJMLlxuICogQW5ndWxhciBwcm92aWRlcyB0d28gc3RyYXRlZ2llczpcbiAqIGBIYXNoTG9jYXRpb25TdHJhdGVneWAgYW5kIGBQYXRoTG9jYXRpb25TdHJhdGVneWAuXG4gKlxuICogQXBwbGljYXRpb25zIHNob3VsZCB1c2UgdGhlIGBSb3V0ZXJgIG9yIGBMb2NhdGlvbmAgc2VydmljZXMgdG9cbiAqIGludGVyYWN0IHdpdGggYXBwbGljYXRpb24gcm91dGUgc3RhdGUuXG4gKlxuICogRm9yIGluc3RhbmNlLCBgSGFzaExvY2F0aW9uU3RyYXRlZ3lgIHByb2R1Y2VzIFVSTHMgbGlrZVxuICogPGNvZGUgY2xhc3M9XCJuby1hdXRvLWxpbmtcIj5odHRwOi8vZXhhbXBsZS5jb20jL2ZvbzwvY29kZT4sXG4gKiBhbmQgYFBhdGhMb2NhdGlvblN0cmF0ZWd5YCBwcm9kdWNlc1xuICogPGNvZGUgY2xhc3M9XCJuby1hdXRvLWxpbmtcIj5odHRwOi8vZXhhbXBsZS5jb20vZm9vPC9jb2RlPiBhcyBhbiBlcXVpdmFsZW50IFVSTC5cbiAqXG4gKiBTZWUgdGhlc2UgdHdvIGNsYXNzZXMgZm9yIG1vcmUuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBMb2NhdGlvblN0cmF0ZWd5IHtcbiAgaGlzdG9yeUdvKHJlbGF0aXZlUG9zaXRpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IobmdEZXZNb2RlID8gJ05vdCBpbXBsZW1lbnRlZCcgOiAnJyk7XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gTG9jYXRpb25TdHJhdGVneV9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgTG9jYXRpb25TdHJhdGVneSkoKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXByb3YgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lSW5qZWN0YWJsZSh7XG4gICAgICB0b2tlbjogTG9jYXRpb25TdHJhdGVneSxcbiAgICAgIGZhY3Rvcnk6ICgpID0+ICgoKSA9PiBpbmplY3QoUGF0aExvY2F0aW9uU3RyYXRlZ3kpKSgpLFxuICAgICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKExvY2F0aW9uU3RyYXRlZ3ksIFt7XG4gICAgdHlwZTogSW5qZWN0YWJsZSxcbiAgICBhcmdzOiBbe1xuICAgICAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxuICAgICAgdXNlRmFjdG9yeTogKCkgPT4gaW5qZWN0KFBhdGhMb2NhdGlvblN0cmF0ZWd5KVxuICAgIH1dXG4gIH1dLCBudWxsLCBudWxsKTtcbn0pKCk7XG4vKipcbiAqIEEgcHJlZGVmaW5lZCBESSB0b2tlbiBmb3IgdGhlIGJhc2UgaHJlZlxuICogdG8gYmUgdXNlZCB3aXRoIHRoZSBgUGF0aExvY2F0aW9uU3RyYXRlZ3lgLlxuICogVGhlIGJhc2UgaHJlZiBpcyB0aGUgVVJMIHByZWZpeCB0aGF0IHNob3VsZCBiZSBwcmVzZXJ2ZWQgd2hlbiBnZW5lcmF0aW5nXG4gKiBhbmQgcmVjb2duaXppbmcgVVJMcy5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBzaG93cyBob3cgdG8gdXNlIHRoaXMgdG9rZW4gdG8gY29uZmlndXJlIHRoZSByb290IGFwcCBpbmplY3RvclxuICogd2l0aCBhIGJhc2UgaHJlZiB2YWx1ZSwgc28gdGhhdCB0aGUgREkgZnJhbWV3b3JrIGNhbiBzdXBwbHkgdGhlIGRlcGVuZGVuY3kgYW55d2hlcmUgaW4gdGhlIGFwcC5cbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQge05nTW9kdWxlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbiAqIGltcG9ydCB7QVBQX0JBU0VfSFJFRn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbiAqXG4gKiBATmdNb2R1bGUoe1xuICogICBwcm92aWRlcnM6IFt7cHJvdmlkZTogQVBQX0JBU0VfSFJFRiwgdXNlVmFsdWU6ICcvbXkvYXBwJ31dXG4gKiB9KVxuICogY2xhc3MgQXBwTW9kdWxlIHt9XG4gKiBgYGBcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNvbnN0IEFQUF9CQVNFX0hSRUYgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gJ2FwcEJhc2VIcmVmJyA6ICcnKTtcbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKiBBIHtAbGluayBMb2NhdGlvblN0cmF0ZWd5fSB1c2VkIHRvIGNvbmZpZ3VyZSB0aGUge0BsaW5rIExvY2F0aW9ufSBzZXJ2aWNlIHRvXG4gKiByZXByZXNlbnQgaXRzIHN0YXRlIGluIHRoZVxuICogW3BhdGhdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1VuaWZvcm1fUmVzb3VyY2VfTG9jYXRvciNTeW50YXgpIG9mIHRoZVxuICogYnJvd3NlcidzIFVSTC5cbiAqXG4gKiBJZiB5b3UncmUgdXNpbmcgYFBhdGhMb2NhdGlvblN0cmF0ZWd5YCwgeW91IG1heSBwcm92aWRlIGEge0BsaW5rIEFQUF9CQVNFX0hSRUZ9XG4gKiBvciBhZGQgYSBgPGJhc2UgaHJlZj5gIGVsZW1lbnQgdG8gdGhlIGRvY3VtZW50IHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0LlxuICpcbiAqIEZvciBpbnN0YW5jZSwgaWYgeW91IHByb3ZpZGUgYW4gYEFQUF9CQVNFX0hSRUZgIG9mIGAnL215L2FwcC8nYCBhbmQgY2FsbFxuICogYGxvY2F0aW9uLmdvKCcvZm9vJylgLCB0aGUgYnJvd3NlcidzIFVSTCB3aWxsIGJlY29tZVxuICogYGV4YW1wbGUuY29tL215L2FwcC9mb29gLiBUbyBlbnN1cmUgYWxsIHJlbGF0aXZlIFVSSXMgcmVzb2x2ZSBjb3JyZWN0bHksXG4gKiB0aGUgYDxiYXNlIGhyZWY+YCBhbmQvb3IgYEFQUF9CQVNFX0hSRUZgIHNob3VsZCBlbmQgd2l0aCBhIGAvYC5cbiAqXG4gKiBTaW1pbGFybHksIGlmIHlvdSBhZGQgYDxiYXNlIGhyZWY9Jy9teS9hcHAvJy8+YCB0byB0aGUgZG9jdW1lbnQgYW5kIGNhbGxcbiAqIGBsb2NhdGlvbi5nbygnL2ZvbycpYCwgdGhlIGJyb3dzZXIncyBVUkwgd2lsbCBiZWNvbWVcbiAqIGBleGFtcGxlLmNvbS9teS9hcHAvZm9vYC5cbiAqXG4gKiBOb3RlIHRoYXQgd2hlbiB1c2luZyBgUGF0aExvY2F0aW9uU3RyYXRlZ3lgLCBuZWl0aGVyIHRoZSBxdWVyeSBub3JcbiAqIHRoZSBmcmFnbWVudCBpbiB0aGUgYDxiYXNlIGhyZWY+YCB3aWxsIGJlIHByZXNlcnZlZCwgYXMgb3V0bGluZWRcbiAqIGJ5IHRoZSBbUkZDXShodHRwczovL3Rvb2xzLmlldGYub3JnL2h0bWwvcmZjMzk4NiNzZWN0aW9uLTUuMi4yKS5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICpcbiAqICMjIyBFeGFtcGxlXG4gKlxuICoge0BleGFtcGxlIGNvbW1vbi9sb2NhdGlvbi90cy9wYXRoX2xvY2F0aW9uX2NvbXBvbmVudC50cyByZWdpb249J0xvY2F0aW9uQ29tcG9uZW50J31cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIFBhdGhMb2NhdGlvblN0cmF0ZWd5IGV4dGVuZHMgTG9jYXRpb25TdHJhdGVneSB7XG4gIGNvbnN0cnVjdG9yKF9wbGF0Zm9ybUxvY2F0aW9uLCBocmVmKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uID0gX3BsYXRmb3JtTG9jYXRpb247XG4gICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJGbnMgPSBbXTtcbiAgICB0aGlzLl9iYXNlSHJlZiA9IGhyZWYgPz8gdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5nZXRCYXNlSHJlZkZyb21ET00oKSA/PyBpbmplY3QoRE9DVU1FTlQpLmxvY2F0aW9uPy5vcmlnaW4gPz8gJyc7XG4gIH1cbiAgLyoqIEBub2RvYyAqL1xuICBuZ09uRGVzdHJveSgpIHtcbiAgICB3aGlsZSAodGhpcy5fcmVtb3ZlTGlzdGVuZXJGbnMubGVuZ3RoKSB7XG4gICAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lckZucy5wb3AoKSgpO1xuICAgIH1cbiAgfVxuICBvblBvcFN0YXRlKGZuKSB7XG4gICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJGbnMucHVzaCh0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLm9uUG9wU3RhdGUoZm4pLCB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLm9uSGFzaENoYW5nZShmbikpO1xuICB9XG4gIGdldEJhc2VIcmVmKCkge1xuICAgIHJldHVybiB0aGlzLl9iYXNlSHJlZjtcbiAgfVxuICBwcmVwYXJlRXh0ZXJuYWxVcmwoaW50ZXJuYWwpIHtcbiAgICByZXR1cm4gam9pbldpdGhTbGFzaCh0aGlzLl9iYXNlSHJlZiwgaW50ZXJuYWwpO1xuICB9XG4gIHBhdGgoaW5jbHVkZUhhc2ggPSBmYWxzZSkge1xuICAgIGNvbnN0IHBhdGhuYW1lID0gdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5wYXRobmFtZSArIG5vcm1hbGl6ZVF1ZXJ5UGFyYW1zKHRoaXMuX3BsYXRmb3JtTG9jYXRpb24uc2VhcmNoKTtcbiAgICBjb25zdCBoYXNoID0gdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5oYXNoO1xuICAgIHJldHVybiBoYXNoICYmIGluY2x1ZGVIYXNoID8gYCR7cGF0aG5hbWV9JHtoYXNofWAgOiBwYXRobmFtZTtcbiAgfVxuICBwdXNoU3RhdGUoc3RhdGUsIHRpdGxlLCB1cmwsIHF1ZXJ5UGFyYW1zKSB7XG4gICAgY29uc3QgZXh0ZXJuYWxVcmwgPSB0aGlzLnByZXBhcmVFeHRlcm5hbFVybCh1cmwgKyBub3JtYWxpemVRdWVyeVBhcmFtcyhxdWVyeVBhcmFtcykpO1xuICAgIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24ucHVzaFN0YXRlKHN0YXRlLCB0aXRsZSwgZXh0ZXJuYWxVcmwpO1xuICB9XG4gIHJlcGxhY2VTdGF0ZShzdGF0ZSwgdGl0bGUsIHVybCwgcXVlcnlQYXJhbXMpIHtcbiAgICBjb25zdCBleHRlcm5hbFVybCA9IHRoaXMucHJlcGFyZUV4dGVybmFsVXJsKHVybCArIG5vcm1hbGl6ZVF1ZXJ5UGFyYW1zKHF1ZXJ5UGFyYW1zKSk7XG4gICAgdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5yZXBsYWNlU3RhdGUoc3RhdGUsIHRpdGxlLCBleHRlcm5hbFVybCk7XG4gIH1cbiAgZm9yd2FyZCgpIHtcbiAgICB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLmZvcndhcmQoKTtcbiAgfVxuICBiYWNrKCkge1xuICAgIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24uYmFjaygpO1xuICB9XG4gIGdldFN0YXRlKCkge1xuICAgIHJldHVybiB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLmdldFN0YXRlKCk7XG4gIH1cbiAgaGlzdG9yeUdvKHJlbGF0aXZlUG9zaXRpb24gPSAwKSB7XG4gICAgdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5oaXN0b3J5R28/LihyZWxhdGl2ZVBvc2l0aW9uKTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBQYXRoTG9jYXRpb25TdHJhdGVneV9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgUGF0aExvY2F0aW9uU3RyYXRlZ3kpKGkwLsm1ybVpbmplY3QoUGxhdGZvcm1Mb2NhdGlvbiksIGkwLsm1ybVpbmplY3QoQVBQX0JBU0VfSFJFRiwgOCkpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1cHJvdiA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVJbmplY3RhYmxlKHtcbiAgICAgIHRva2VuOiBQYXRoTG9jYXRpb25TdHJhdGVneSxcbiAgICAgIGZhY3Rvcnk6IFBhdGhMb2NhdGlvblN0cmF0ZWd5Lsm1ZmFjLFxuICAgICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKFBhdGhMb2NhdGlvblN0cmF0ZWd5LCBbe1xuICAgIHR5cGU6IEluamVjdGFibGUsXG4gICAgYXJnczogW3tcbiAgICAgIHByb3ZpZGVkSW46ICdyb290J1xuICAgIH1dXG4gIH1dLCAoKSA9PiBbe1xuICAgIHR5cGU6IFBsYXRmb3JtTG9jYXRpb25cbiAgfSwge1xuICAgIHR5cGU6IHVuZGVmaW5lZCxcbiAgICBkZWNvcmF0b3JzOiBbe1xuICAgICAgdHlwZTogT3B0aW9uYWxcbiAgICB9LCB7XG4gICAgICB0eXBlOiBJbmplY3QsXG4gICAgICBhcmdzOiBbQVBQX0JBU0VfSFJFRl1cbiAgICB9XVxuICB9XSwgbnVsbCk7XG59KSgpO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvblxuICogQSB7QGxpbmsgTG9jYXRpb25TdHJhdGVneX0gdXNlZCB0byBjb25maWd1cmUgdGhlIHtAbGluayBMb2NhdGlvbn0gc2VydmljZSB0b1xuICogcmVwcmVzZW50IGl0cyBzdGF0ZSBpbiB0aGVcbiAqIFtoYXNoIGZyYWdtZW50XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Vbmlmb3JtX1Jlc291cmNlX0xvY2F0b3IjU3ludGF4KVxuICogb2YgdGhlIGJyb3dzZXIncyBVUkwuXG4gKlxuICogRm9yIGluc3RhbmNlLCBpZiB5b3UgY2FsbCBgbG9jYXRpb24uZ28oJy9mb28nKWAsIHRoZSBicm93c2VyJ3MgVVJMIHdpbGwgYmVjb21lXG4gKiBgZXhhbXBsZS5jb20jL2Zvb2AuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiAjIyMgRXhhbXBsZVxuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vbG9jYXRpb24vdHMvaGFzaF9sb2NhdGlvbl9jb21wb25lbnQudHMgcmVnaW9uPSdMb2NhdGlvbkNvbXBvbmVudCd9XG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBIYXNoTG9jYXRpb25TdHJhdGVneSBleHRlbmRzIExvY2F0aW9uU3RyYXRlZ3kge1xuICBjb25zdHJ1Y3RvcihfcGxhdGZvcm1Mb2NhdGlvbiwgX2Jhc2VIcmVmKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uID0gX3BsYXRmb3JtTG9jYXRpb247XG4gICAgdGhpcy5fYmFzZUhyZWYgPSAnJztcbiAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lckZucyA9IFtdO1xuICAgIGlmIChfYmFzZUhyZWYgIT0gbnVsbCkge1xuICAgICAgdGhpcy5fYmFzZUhyZWYgPSBfYmFzZUhyZWY7XG4gICAgfVxuICB9XG4gIC8qKiBAbm9kb2MgKi9cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgd2hpbGUgKHRoaXMuX3JlbW92ZUxpc3RlbmVyRm5zLmxlbmd0aCkge1xuICAgICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJGbnMucG9wKCkoKTtcbiAgICB9XG4gIH1cbiAgb25Qb3BTdGF0ZShmbikge1xuICAgIHRoaXMuX3JlbW92ZUxpc3RlbmVyRm5zLnB1c2godGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5vblBvcFN0YXRlKGZuKSwgdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5vbkhhc2hDaGFuZ2UoZm4pKTtcbiAgfVxuICBnZXRCYXNlSHJlZigpIHtcbiAgICByZXR1cm4gdGhpcy5fYmFzZUhyZWY7XG4gIH1cbiAgcGF0aChpbmNsdWRlSGFzaCA9IGZhbHNlKSB7XG4gICAgLy8gdGhlIGhhc2ggdmFsdWUgaXMgYWx3YXlzIHByZWZpeGVkIHdpdGggYSBgI2BcbiAgICAvLyBhbmQgaWYgaXQgaXMgZW1wdHkgdGhlbiBpdCB3aWxsIHN0YXkgZW1wdHlcbiAgICBjb25zdCBwYXRoID0gdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5oYXNoID8/ICcjJztcbiAgICByZXR1cm4gcGF0aC5sZW5ndGggPiAwID8gcGF0aC5zdWJzdHJpbmcoMSkgOiBwYXRoO1xuICB9XG4gIHByZXBhcmVFeHRlcm5hbFVybChpbnRlcm5hbCkge1xuICAgIGNvbnN0IHVybCA9IGpvaW5XaXRoU2xhc2godGhpcy5fYmFzZUhyZWYsIGludGVybmFsKTtcbiAgICByZXR1cm4gdXJsLmxlbmd0aCA+IDAgPyAnIycgKyB1cmwgOiB1cmw7XG4gIH1cbiAgcHVzaFN0YXRlKHN0YXRlLCB0aXRsZSwgcGF0aCwgcXVlcnlQYXJhbXMpIHtcbiAgICBsZXQgdXJsID0gdGhpcy5wcmVwYXJlRXh0ZXJuYWxVcmwocGF0aCArIG5vcm1hbGl6ZVF1ZXJ5UGFyYW1zKHF1ZXJ5UGFyYW1zKSk7XG4gICAgaWYgKHVybC5sZW5ndGggPT0gMCkge1xuICAgICAgdXJsID0gdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5wYXRobmFtZTtcbiAgICB9XG4gICAgdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5wdXNoU3RhdGUoc3RhdGUsIHRpdGxlLCB1cmwpO1xuICB9XG4gIHJlcGxhY2VTdGF0ZShzdGF0ZSwgdGl0bGUsIHBhdGgsIHF1ZXJ5UGFyYW1zKSB7XG4gICAgbGV0IHVybCA9IHRoaXMucHJlcGFyZUV4dGVybmFsVXJsKHBhdGggKyBub3JtYWxpemVRdWVyeVBhcmFtcyhxdWVyeVBhcmFtcykpO1xuICAgIGlmICh1cmwubGVuZ3RoID09IDApIHtcbiAgICAgIHVybCA9IHRoaXMuX3BsYXRmb3JtTG9jYXRpb24ucGF0aG5hbWU7XG4gICAgfVxuICAgIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24ucmVwbGFjZVN0YXRlKHN0YXRlLCB0aXRsZSwgdXJsKTtcbiAgfVxuICBmb3J3YXJkKCkge1xuICAgIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24uZm9yd2FyZCgpO1xuICB9XG4gIGJhY2soKSB7XG4gICAgdGhpcy5fcGxhdGZvcm1Mb2NhdGlvbi5iYWNrKCk7XG4gIH1cbiAgZ2V0U3RhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3BsYXRmb3JtTG9jYXRpb24uZ2V0U3RhdGUoKTtcbiAgfVxuICBoaXN0b3J5R28ocmVsYXRpdmVQb3NpdGlvbiA9IDApIHtcbiAgICB0aGlzLl9wbGF0Zm9ybUxvY2F0aW9uLmhpc3RvcnlHbz8uKHJlbGF0aXZlUG9zaXRpb24pO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIEhhc2hMb2NhdGlvblN0cmF0ZWd5X0ZhY3RvcnkodCkge1xuICAgICAgcmV0dXJuIG5ldyAodCB8fCBIYXNoTG9jYXRpb25TdHJhdGVneSkoaTAuybXJtWluamVjdChQbGF0Zm9ybUxvY2F0aW9uKSwgaTAuybXJtWluamVjdChBUFBfQkFTRV9IUkVGLCA4KSk7XG4gICAgfTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVwcm92ID0gLyogQF9fUFVSRV9fICovaTAuybXJtWRlZmluZUluamVjdGFibGUoe1xuICAgICAgdG9rZW46IEhhc2hMb2NhdGlvblN0cmF0ZWd5LFxuICAgICAgZmFjdG9yeTogSGFzaExvY2F0aW9uU3RyYXRlZ3kuybVmYWNcbiAgICB9KTtcbiAgfVxufVxuKCgpID0+IHtcbiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09IFwidW5kZWZpbmVkXCIgfHwgbmdEZXZNb2RlKSAmJiBpMC7JtXNldENsYXNzTWV0YWRhdGEoSGFzaExvY2F0aW9uU3RyYXRlZ3ksIFt7XG4gICAgdHlwZTogSW5qZWN0YWJsZVxuICB9XSwgKCkgPT4gW3tcbiAgICB0eXBlOiBQbGF0Zm9ybUxvY2F0aW9uXG4gIH0sIHtcbiAgICB0eXBlOiB1bmRlZmluZWQsXG4gICAgZGVjb3JhdG9yczogW3tcbiAgICAgIHR5cGU6IE9wdGlvbmFsXG4gICAgfSwge1xuICAgICAgdHlwZTogSW5qZWN0LFxuICAgICAgYXJnczogW0FQUF9CQVNFX0hSRUZdXG4gICAgfV1cbiAgfV0sIG51bGwpO1xufSkoKTtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiBBIHNlcnZpY2UgdGhhdCBhcHBsaWNhdGlvbnMgY2FuIHVzZSB0byBpbnRlcmFjdCB3aXRoIGEgYnJvd3NlcidzIFVSTC5cbiAqXG4gKiBEZXBlbmRpbmcgb24gdGhlIGBMb2NhdGlvblN0cmF0ZWd5YCB1c2VkLCBgTG9jYXRpb25gIHBlcnNpc3RzXG4gKiB0byB0aGUgVVJMJ3MgcGF0aCBvciB0aGUgVVJMJ3MgaGFzaCBzZWdtZW50LlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogSXQncyBiZXR0ZXIgdG8gdXNlIHRoZSBgUm91dGVyLm5hdmlnYXRlKClgIHNlcnZpY2UgdG8gdHJpZ2dlciByb3V0ZSBjaGFuZ2VzLiBVc2VcbiAqIGBMb2NhdGlvbmAgb25seSBpZiB5b3UgbmVlZCB0byBpbnRlcmFjdCB3aXRoIG9yIGNyZWF0ZSBub3JtYWxpemVkIFVSTHMgb3V0c2lkZSBvZlxuICogcm91dGluZy5cbiAqXG4gKiBgTG9jYXRpb25gIGlzIHJlc3BvbnNpYmxlIGZvciBub3JtYWxpemluZyB0aGUgVVJMIGFnYWluc3QgdGhlIGFwcGxpY2F0aW9uJ3MgYmFzZSBocmVmLlxuICogQSBub3JtYWxpemVkIFVSTCBpcyBhYnNvbHV0ZSBmcm9tIHRoZSBVUkwgaG9zdCwgaW5jbHVkZXMgdGhlIGFwcGxpY2F0aW9uJ3MgYmFzZSBocmVmLCBhbmQgaGFzIG5vXG4gKiB0cmFpbGluZyBzbGFzaDpcbiAqIC0gYC9teS9hcHAvdXNlci8xMjNgIGlzIG5vcm1hbGl6ZWRcbiAqIC0gYG15L2FwcC91c2VyLzEyM2AgKippcyBub3QqKiBub3JtYWxpemVkXG4gKiAtIGAvbXkvYXBwL3VzZXIvMTIzL2AgKippcyBub3QqKiBub3JtYWxpemVkXG4gKlxuICogIyMjIEV4YW1wbGVcbiAqXG4gKiA8Y29kZS1leGFtcGxlIHBhdGg9J2NvbW1vbi9sb2NhdGlvbi90cy9wYXRoX2xvY2F0aW9uX2NvbXBvbmVudC50cydcbiAqIHJlZ2lvbj0nTG9jYXRpb25Db21wb25lbnQnPjwvY29kZS1leGFtcGxlPlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgTG9jYXRpb24ge1xuICBjb25zdHJ1Y3Rvcihsb2NhdGlvblN0cmF0ZWd5KSB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIHRoaXMuX3N1YmplY3QgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIHRoaXMuX3VybENoYW5nZUxpc3RlbmVycyA9IFtdO1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICB0aGlzLl91cmxDaGFuZ2VTdWJzY3JpcHRpb24gPSBudWxsO1xuICAgIHRoaXMuX2xvY2F0aW9uU3RyYXRlZ3kgPSBsb2NhdGlvblN0cmF0ZWd5O1xuICAgIGNvbnN0IGJhc2VIcmVmID0gdGhpcy5fbG9jYXRpb25TdHJhdGVneS5nZXRCYXNlSHJlZigpO1xuICAgIC8vIE5vdGU6IFRoaXMgY2xhc3MncyBpbnRlcmFjdGlvbiB3aXRoIGJhc2UgSFJFRiBkb2VzIG5vdCBmdWxseSBmb2xsb3cgdGhlIHJ1bGVzXG4gICAgLy8gb3V0bGluZWQgaW4gdGhlIHNwZWMgaHR0cHM6Ly93d3cuZnJlZXNvZnQub3JnL0NJRS9SRkMvMTgwOC8xOC5odG0uXG4gICAgLy8gSW5zdGVhZCBvZiB0cnlpbmcgdG8gZml4IGluZGl2aWR1YWwgYnVncyB3aXRoIG1vcmUgYW5kIG1vcmUgY29kZSwgd2Ugc2hvdWxkXG4gICAgLy8gaW52ZXN0aWdhdGUgdXNpbmcgdGhlIFVSTCBjb25zdHJ1Y3RvciBhbmQgcHJvdmlkaW5nIHRoZSBiYXNlIGFzIGEgc2Vjb25kXG4gICAgLy8gYXJndW1lbnQuXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1VSTC9VUkwjcGFyYW1ldGVyc1xuICAgIHRoaXMuX2Jhc2VQYXRoID0gX3N0cmlwT3JpZ2luKHN0cmlwVHJhaWxpbmdTbGFzaChfc3RyaXBJbmRleEh0bWwoYmFzZUhyZWYpKSk7XG4gICAgdGhpcy5fbG9jYXRpb25TdHJhdGVneS5vblBvcFN0YXRlKGV2ID0+IHtcbiAgICAgIHRoaXMuX3N1YmplY3QuZW1pdCh7XG4gICAgICAgICd1cmwnOiB0aGlzLnBhdGgodHJ1ZSksXG4gICAgICAgICdwb3AnOiB0cnVlLFxuICAgICAgICAnc3RhdGUnOiBldi5zdGF0ZSxcbiAgICAgICAgJ3R5cGUnOiBldi50eXBlXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuICAvKiogQG5vZG9jICovXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX3VybENoYW5nZVN1YnNjcmlwdGlvbj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLl91cmxDaGFuZ2VMaXN0ZW5lcnMgPSBbXTtcbiAgfVxuICAvKipcbiAgICogTm9ybWFsaXplcyB0aGUgVVJMIHBhdGggZm9yIHRoaXMgbG9jYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSBpbmNsdWRlSGFzaCBUcnVlIHRvIGluY2x1ZGUgYW4gYW5jaG9yIGZyYWdtZW50IGluIHRoZSBwYXRoLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgbm9ybWFsaXplZCBVUkwgcGF0aC5cbiAgICovXG4gIC8vIFRPRE86IHZzYXZraW4uIFJlbW92ZSB0aGUgYm9vbGVhbiBmbGFnIGFuZCBhbHdheXMgaW5jbHVkZSBoYXNoIG9uY2UgdGhlIGRlcHJlY2F0ZWQgcm91dGVyIGlzXG4gIC8vIHJlbW92ZWQuXG4gIHBhdGgoaW5jbHVkZUhhc2ggPSBmYWxzZSkge1xuICAgIHJldHVybiB0aGlzLm5vcm1hbGl6ZSh0aGlzLl9sb2NhdGlvblN0cmF0ZWd5LnBhdGgoaW5jbHVkZUhhc2gpKTtcbiAgfVxuICAvKipcbiAgICogUmVwb3J0cyB0aGUgY3VycmVudCBzdGF0ZSBvZiB0aGUgbG9jYXRpb24gaGlzdG9yeS5cbiAgICogQHJldHVybnMgVGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGBoaXN0b3J5LnN0YXRlYCBvYmplY3QuXG4gICAqL1xuICBnZXRTdGF0ZSgpIHtcbiAgICByZXR1cm4gdGhpcy5fbG9jYXRpb25TdHJhdGVneS5nZXRTdGF0ZSgpO1xuICB9XG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIHRoZSBnaXZlbiBwYXRoIGFuZCBjb21wYXJlcyB0byB0aGUgY3VycmVudCBub3JtYWxpemVkIHBhdGguXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoIFRoZSBnaXZlbiBVUkwgcGF0aC5cbiAgICogQHBhcmFtIHF1ZXJ5IFF1ZXJ5IHBhcmFtZXRlcnMuXG4gICAqXG4gICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIGdpdmVuIFVSTCBwYXRoIGlzIGVxdWFsIHRvIHRoZSBjdXJyZW50IG5vcm1hbGl6ZWQgcGF0aCwgZmFsc2VcbiAgICogb3RoZXJ3aXNlLlxuICAgKi9cbiAgaXNDdXJyZW50UGF0aEVxdWFsVG8ocGF0aCwgcXVlcnkgPSAnJykge1xuICAgIHJldHVybiB0aGlzLnBhdGgoKSA9PSB0aGlzLm5vcm1hbGl6ZShwYXRoICsgbm9ybWFsaXplUXVlcnlQYXJhbXMocXVlcnkpKTtcbiAgfVxuICAvKipcbiAgICogTm9ybWFsaXplcyBhIFVSTCBwYXRoIGJ5IHN0cmlwcGluZyBhbnkgdHJhaWxpbmcgc2xhc2hlcy5cbiAgICpcbiAgICogQHBhcmFtIHVybCBTdHJpbmcgcmVwcmVzZW50aW5nIGEgVVJMLlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgbm9ybWFsaXplZCBVUkwgc3RyaW5nLlxuICAgKi9cbiAgbm9ybWFsaXplKHVybCkge1xuICAgIHJldHVybiBMb2NhdGlvbi5zdHJpcFRyYWlsaW5nU2xhc2goX3N0cmlwQmFzZVBhdGgodGhpcy5fYmFzZVBhdGgsIF9zdHJpcEluZGV4SHRtbCh1cmwpKSk7XG4gIH1cbiAgLyoqXG4gICAqIE5vcm1hbGl6ZXMgYW4gZXh0ZXJuYWwgVVJMIHBhdGguXG4gICAqIElmIHRoZSBnaXZlbiBVUkwgZG9lc24ndCBiZWdpbiB3aXRoIGEgbGVhZGluZyBzbGFzaCAoYCcvJ2ApLCBhZGRzIG9uZVxuICAgKiBiZWZvcmUgbm9ybWFsaXppbmcuIEFkZHMgYSBoYXNoIGlmIGBIYXNoTG9jYXRpb25TdHJhdGVneWAgaXNcbiAgICogaW4gdXNlLCBvciB0aGUgYEFQUF9CQVNFX0hSRUZgIGlmIHRoZSBgUGF0aExvY2F0aW9uU3RyYXRlZ3lgIGlzIGluIHVzZS5cbiAgICpcbiAgICogQHBhcmFtIHVybCBTdHJpbmcgcmVwcmVzZW50aW5nIGEgVVJMLlxuICAgKlxuICAgKiBAcmV0dXJucyAgQSBub3JtYWxpemVkIHBsYXRmb3JtLXNwZWNpZmljIFVSTC5cbiAgICovXG4gIHByZXBhcmVFeHRlcm5hbFVybCh1cmwpIHtcbiAgICBpZiAodXJsICYmIHVybFswXSAhPT0gJy8nKSB7XG4gICAgICB1cmwgPSAnLycgKyB1cmw7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9sb2NhdGlvblN0cmF0ZWd5LnByZXBhcmVFeHRlcm5hbFVybCh1cmwpO1xuICB9XG4gIC8vIFRPRE86IHJlbmFtZSB0aGlzIG1ldGhvZCB0byBwdXNoU3RhdGVcbiAgLyoqXG4gICAqIENoYW5nZXMgdGhlIGJyb3dzZXIncyBVUkwgdG8gYSBub3JtYWxpemVkIHZlcnNpb24gb2YgYSBnaXZlbiBVUkwsIGFuZCBwdXNoZXMgYVxuICAgKiBuZXcgaXRlbSBvbnRvIHRoZSBwbGF0Zm9ybSdzIGhpc3RvcnkuXG4gICAqXG4gICAqIEBwYXJhbSBwYXRoICBVUkwgcGF0aCB0byBub3JtYWxpemUuXG4gICAqIEBwYXJhbSBxdWVyeSBRdWVyeSBwYXJhbWV0ZXJzLlxuICAgKiBAcGFyYW0gc3RhdGUgTG9jYXRpb24gaGlzdG9yeSBzdGF0ZS5cbiAgICpcbiAgICovXG4gIGdvKHBhdGgsIHF1ZXJ5ID0gJycsIHN0YXRlID0gbnVsbCkge1xuICAgIHRoaXMuX2xvY2F0aW9uU3RyYXRlZ3kucHVzaFN0YXRlKHN0YXRlLCAnJywgcGF0aCwgcXVlcnkpO1xuICAgIHRoaXMuX25vdGlmeVVybENoYW5nZUxpc3RlbmVycyh0aGlzLnByZXBhcmVFeHRlcm5hbFVybChwYXRoICsgbm9ybWFsaXplUXVlcnlQYXJhbXMocXVlcnkpKSwgc3RhdGUpO1xuICB9XG4gIC8qKlxuICAgKiBDaGFuZ2VzIHRoZSBicm93c2VyJ3MgVVJMIHRvIGEgbm9ybWFsaXplZCB2ZXJzaW9uIG9mIHRoZSBnaXZlbiBVUkwsIGFuZCByZXBsYWNlc1xuICAgKiB0aGUgdG9wIGl0ZW0gb24gdGhlIHBsYXRmb3JtJ3MgaGlzdG9yeSBzdGFjay5cbiAgICpcbiAgICogQHBhcmFtIHBhdGggIFVSTCBwYXRoIHRvIG5vcm1hbGl6ZS5cbiAgICogQHBhcmFtIHF1ZXJ5IFF1ZXJ5IHBhcmFtZXRlcnMuXG4gICAqIEBwYXJhbSBzdGF0ZSBMb2NhdGlvbiBoaXN0b3J5IHN0YXRlLlxuICAgKi9cbiAgcmVwbGFjZVN0YXRlKHBhdGgsIHF1ZXJ5ID0gJycsIHN0YXRlID0gbnVsbCkge1xuICAgIHRoaXMuX2xvY2F0aW9uU3RyYXRlZ3kucmVwbGFjZVN0YXRlKHN0YXRlLCAnJywgcGF0aCwgcXVlcnkpO1xuICAgIHRoaXMuX25vdGlmeVVybENoYW5nZUxpc3RlbmVycyh0aGlzLnByZXBhcmVFeHRlcm5hbFVybChwYXRoICsgbm9ybWFsaXplUXVlcnlQYXJhbXMocXVlcnkpKSwgc3RhdGUpO1xuICB9XG4gIC8qKlxuICAgKiBOYXZpZ2F0ZXMgZm9yd2FyZCBpbiB0aGUgcGxhdGZvcm0ncyBoaXN0b3J5LlxuICAgKi9cbiAgZm9yd2FyZCgpIHtcbiAgICB0aGlzLl9sb2NhdGlvblN0cmF0ZWd5LmZvcndhcmQoKTtcbiAgfVxuICAvKipcbiAgICogTmF2aWdhdGVzIGJhY2sgaW4gdGhlIHBsYXRmb3JtJ3MgaGlzdG9yeS5cbiAgICovXG4gIGJhY2soKSB7XG4gICAgdGhpcy5fbG9jYXRpb25TdHJhdGVneS5iYWNrKCk7XG4gIH1cbiAgLyoqXG4gICAqIE5hdmlnYXRlIHRvIGEgc3BlY2lmaWMgcGFnZSBmcm9tIHNlc3Npb24gaGlzdG9yeSwgaWRlbnRpZmllZCBieSBpdHMgcmVsYXRpdmUgcG9zaXRpb24gdG8gdGhlXG4gICAqIGN1cnJlbnQgcGFnZS5cbiAgICpcbiAgICogQHBhcmFtIHJlbGF0aXZlUG9zaXRpb24gIFBvc2l0aW9uIG9mIHRoZSB0YXJnZXQgcGFnZSBpbiB0aGUgaGlzdG9yeSByZWxhdGl2ZSB0byB0aGUgY3VycmVudFxuICAgKiAgICAgcGFnZS5cbiAgICogQSBuZWdhdGl2ZSB2YWx1ZSBtb3ZlcyBiYWNrd2FyZHMsIGEgcG9zaXRpdmUgdmFsdWUgbW92ZXMgZm9yd2FyZHMsIGUuZy4gYGxvY2F0aW9uLmhpc3RvcnlHbygyKWBcbiAgICogbW92ZXMgZm9yd2FyZCB0d28gcGFnZXMgYW5kIGBsb2NhdGlvbi5oaXN0b3J5R28oLTIpYCBtb3ZlcyBiYWNrIHR3byBwYWdlcy4gV2hlbiB3ZSB0cnkgdG8gZ29cbiAgICogYmV5b25kIHdoYXQncyBzdG9yZWQgaW4gdGhlIGhpc3Rvcnkgc2Vzc2lvbiwgd2Ugc3RheSBpbiB0aGUgY3VycmVudCBwYWdlLiBTYW1lIGJlaGF2aW91ciBvY2N1cnNcbiAgICogd2hlbiBgcmVsYXRpdmVQb3NpdGlvbmAgZXF1YWxzIDAuXG4gICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hpc3RvcnlfQVBJI01vdmluZ190b19hX3NwZWNpZmljX3BvaW50X2luX2hpc3RvcnlcbiAgICovXG4gIGhpc3RvcnlHbyhyZWxhdGl2ZVBvc2l0aW9uID0gMCkge1xuICAgIHRoaXMuX2xvY2F0aW9uU3RyYXRlZ3kuaGlzdG9yeUdvPy4ocmVsYXRpdmVQb3NpdGlvbik7XG4gIH1cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyBhIFVSTCBjaGFuZ2UgbGlzdGVuZXIuIFVzZSB0byBjYXRjaCB1cGRhdGVzIHBlcmZvcm1lZCBieSB0aGUgQW5ndWxhclxuICAgKiBmcmFtZXdvcmsgdGhhdCBhcmUgbm90IGRldGVjdGlibGUgdGhyb3VnaCBcInBvcHN0YXRlXCIgb3IgXCJoYXNoY2hhbmdlXCIgZXZlbnRzLlxuICAgKlxuICAgKiBAcGFyYW0gZm4gVGhlIGNoYW5nZSBoYW5kbGVyIGZ1bmN0aW9uLCB3aGljaCB0YWtlIGEgVVJMIGFuZCBhIGxvY2F0aW9uIGhpc3Rvcnkgc3RhdGUuXG4gICAqIEByZXR1cm5zIEEgZnVuY3Rpb24gdGhhdCwgd2hlbiBleGVjdXRlZCwgdW5yZWdpc3RlcnMgYSBVUkwgY2hhbmdlIGxpc3RlbmVyLlxuICAgKi9cbiAgb25VcmxDaGFuZ2UoZm4pIHtcbiAgICB0aGlzLl91cmxDaGFuZ2VMaXN0ZW5lcnMucHVzaChmbik7XG4gICAgdGhpcy5fdXJsQ2hhbmdlU3Vic2NyaXB0aW9uID8/PSB0aGlzLnN1YnNjcmliZSh2ID0+IHtcbiAgICAgIHRoaXMuX25vdGlmeVVybENoYW5nZUxpc3RlbmVycyh2LnVybCwgdi5zdGF0ZSk7XG4gICAgfSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNvbnN0IGZuSW5kZXggPSB0aGlzLl91cmxDaGFuZ2VMaXN0ZW5lcnMuaW5kZXhPZihmbik7XG4gICAgICB0aGlzLl91cmxDaGFuZ2VMaXN0ZW5lcnMuc3BsaWNlKGZuSW5kZXgsIDEpO1xuICAgICAgaWYgKHRoaXMuX3VybENoYW5nZUxpc3RlbmVycy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5fdXJsQ2hhbmdlU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLl91cmxDaGFuZ2VTdWJzY3JpcHRpb24gPSBudWxsO1xuICAgICAgfVxuICAgIH07XG4gIH1cbiAgLyoqIEBpbnRlcm5hbCAqL1xuICBfbm90aWZ5VXJsQ2hhbmdlTGlzdGVuZXJzKHVybCA9ICcnLCBzdGF0ZSkge1xuICAgIHRoaXMuX3VybENoYW5nZUxpc3RlbmVycy5mb3JFYWNoKGZuID0+IGZuKHVybCwgc3RhdGUpKTtcbiAgfVxuICAvKipcbiAgICogU3Vic2NyaWJlcyB0byB0aGUgcGxhdGZvcm0ncyBgcG9wU3RhdGVgIGV2ZW50cy5cbiAgICpcbiAgICogTm90ZTogYExvY2F0aW9uLmdvKClgIGRvZXMgbm90IHRyaWdnZXIgdGhlIGBwb3BTdGF0ZWAgZXZlbnQgaW4gdGhlIGJyb3dzZXIuIFVzZVxuICAgKiBgTG9jYXRpb24ub25VcmxDaGFuZ2UoKWAgdG8gc3Vic2NyaWJlIHRvIFVSTCBjaGFuZ2VzIGluc3RlYWQuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBFdmVudCB0aGF0IGlzIHRyaWdnZXJlZCB3aGVuIHRoZSBzdGF0ZSBoaXN0b3J5IGNoYW5nZXMuXG4gICAqIEBwYXJhbSBleGNlcHRpb24gVGhlIGV4Y2VwdGlvbiB0byB0aHJvdy5cbiAgICpcbiAgICogQHNlZSBbb25wb3BzdGF0ZV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1dpbmRvd0V2ZW50SGFuZGxlcnMvb25wb3BzdGF0ZSlcbiAgICpcbiAgICogQHJldHVybnMgU3Vic2NyaWJlZCBldmVudHMuXG4gICAqL1xuICBzdWJzY3JpYmUob25OZXh0LCBvblRocm93LCBvblJldHVybikge1xuICAgIHJldHVybiB0aGlzLl9zdWJqZWN0LnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiBvbk5leHQsXG4gICAgICBlcnJvcjogb25UaHJvdyxcbiAgICAgIGNvbXBsZXRlOiBvblJldHVyblxuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIFVSTCBwYXJhbWV0ZXJzIGJ5IHByZXBlbmRpbmcgd2l0aCBgP2AgaWYgbmVlZGVkLlxuICAgKlxuICAgKiBAcGFyYW0gIHBhcmFtcyBTdHJpbmcgb2YgVVJMIHBhcmFtZXRlcnMuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSBub3JtYWxpemVkIFVSTCBwYXJhbWV0ZXJzIHN0cmluZy5cbiAgICovXG4gIHN0YXRpYyB7XG4gICAgdGhpcy5ub3JtYWxpemVRdWVyeVBhcmFtcyA9IG5vcm1hbGl6ZVF1ZXJ5UGFyYW1zO1xuICB9XG4gIC8qKlxuICAgKiBKb2lucyB0d28gcGFydHMgb2YgYSBVUkwgd2l0aCBhIHNsYXNoIGlmIG5lZWRlZC5cbiAgICpcbiAgICogQHBhcmFtIHN0YXJ0ICBVUkwgc3RyaW5nXG4gICAqIEBwYXJhbSBlbmQgICAgVVJMIHN0cmluZ1xuICAgKlxuICAgKlxuICAgKiBAcmV0dXJucyBUaGUgam9pbmVkIFVSTCBzdHJpbmcuXG4gICAqL1xuICBzdGF0aWMge1xuICAgIHRoaXMuam9pbldpdGhTbGFzaCA9IGpvaW5XaXRoU2xhc2g7XG4gIH1cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSB0cmFpbGluZyBzbGFzaCBmcm9tIGEgVVJMIHN0cmluZyBpZiBuZWVkZWQuXG4gICAqIExvb2tzIGZvciB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBlaXRoZXIgYCNgLCBgP2AsIG9yIHRoZSBlbmQgb2YgdGhlXG4gICAqIGxpbmUgYXMgYC9gIGNoYXJhY3RlcnMgYW5kIHJlbW92ZXMgdGhlIHRyYWlsaW5nIHNsYXNoIGlmIG9uZSBleGlzdHMuXG4gICAqXG4gICAqIEBwYXJhbSB1cmwgVVJMIHN0cmluZy5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIFVSTCBzdHJpbmcsIG1vZGlmaWVkIGlmIG5lZWRlZC5cbiAgICovXG4gIHN0YXRpYyB7XG4gICAgdGhpcy5zdHJpcFRyYWlsaW5nU2xhc2ggPSBzdHJpcFRyYWlsaW5nU2xhc2g7XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gTG9jYXRpb25fRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IExvY2F0aW9uKShpMC7Jtcm1aW5qZWN0KExvY2F0aW9uU3RyYXRlZ3kpKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXByb3YgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lSW5qZWN0YWJsZSh7XG4gICAgICB0b2tlbjogTG9jYXRpb24sXG4gICAgICBmYWN0b3J5OiAoKSA9PiBjcmVhdGVMb2NhdGlvbigpLFxuICAgICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKExvY2F0aW9uLCBbe1xuICAgIHR5cGU6IEluamVjdGFibGUsXG4gICAgYXJnczogW3tcbiAgICAgIHByb3ZpZGVkSW46ICdyb290JyxcbiAgICAgIC8vIFNlZSAjMjM5MTdcbiAgICAgIHVzZUZhY3Rvcnk6IGNyZWF0ZUxvY2F0aW9uXG4gICAgfV1cbiAgfV0sICgpID0+IFt7XG4gICAgdHlwZTogTG9jYXRpb25TdHJhdGVneVxuICB9XSwgbnVsbCk7XG59KSgpO1xuZnVuY3Rpb24gY3JlYXRlTG9jYXRpb24oKSB7XG4gIHJldHVybiBuZXcgTG9jYXRpb24oybXJtWluamVjdChMb2NhdGlvblN0cmF0ZWd5KSk7XG59XG5mdW5jdGlvbiBfc3RyaXBCYXNlUGF0aChiYXNlUGF0aCwgdXJsKSB7XG4gIGlmICghYmFzZVBhdGggfHwgIXVybC5zdGFydHNXaXRoKGJhc2VQYXRoKSkge1xuICAgIHJldHVybiB1cmw7XG4gIH1cbiAgY29uc3Qgc3RyaXBwZWRVcmwgPSB1cmwuc3Vic3RyaW5nKGJhc2VQYXRoLmxlbmd0aCk7XG4gIGlmIChzdHJpcHBlZFVybCA9PT0gJycgfHwgWycvJywgJzsnLCAnPycsICcjJ10uaW5jbHVkZXMoc3RyaXBwZWRVcmxbMF0pKSB7XG4gICAgcmV0dXJuIHN0cmlwcGVkVXJsO1xuICB9XG4gIHJldHVybiB1cmw7XG59XG5mdW5jdGlvbiBfc3RyaXBJbmRleEh0bWwodXJsKSB7XG4gIHJldHVybiB1cmwucmVwbGFjZSgvXFwvaW5kZXguaHRtbCQvLCAnJyk7XG59XG5mdW5jdGlvbiBfc3RyaXBPcmlnaW4oYmFzZUhyZWYpIHtcbiAgLy8gRE8gTk9UIFJFRkFDVE9SISBQcmV2aW91c2x5LCB0aGlzIGNoZWNrIGxvb2tlZCBsaWtlIHRoaXM6XG4gIC8vIGAvXihodHRwcz86KT9cXC9cXC8vLnRlc3QoYmFzZUhyZWYpYCwgYnV0IHRoYXQgcmVzdWx0ZWQgaW5cbiAgLy8gc3ludGFjdGljYWxseSBpbmNvcnJlY3QgY29kZSBhZnRlciBDbG9zdXJlIENvbXBpbGVyIG1pbmlmaWNhdGlvbi5cbiAgLy8gVGhpcyB3YXMgbGlrZWx5IGNhdXNlZCBieSBhIGJ1ZyBpbiBDbG9zdXJlIENvbXBpbGVyLCBidXRcbiAgLy8gZm9yIG5vdywgdGhlIGNoZWNrIGlzIHJld3JpdHRlbiB0byB1c2UgYG5ldyBSZWdFeHBgIGluc3RlYWQuXG4gIGNvbnN0IGlzQWJzb2x1dGVVcmwgPSBuZXcgUmVnRXhwKCdeKGh0dHBzPzopPy8vJykudGVzdChiYXNlSHJlZik7XG4gIGlmIChpc0Fic29sdXRlVXJsKSB7XG4gICAgY29uc3QgWywgcGF0aG5hbWVdID0gYmFzZUhyZWYuc3BsaXQoL1xcL1xcL1teXFwvXSsvKTtcbiAgICByZXR1cm4gcGF0aG5hbWU7XG4gIH1cbiAgcmV0dXJuIGJhc2VIcmVmO1xufVxuXG4vKiogQGludGVybmFsICovXG5jb25zdCBDVVJSRU5DSUVTX0VOID0ge1xuICBcIkFEUFwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDBdLFxuICBcIkFGTlwiOiBbdW5kZWZpbmVkLCBcItiLXCIsIDBdLFxuICBcIkFMTFwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDBdLFxuICBcIkFNRFwiOiBbdW5kZWZpbmVkLCBcItaPXCIsIDJdLFxuICBcIkFPQVwiOiBbdW5kZWZpbmVkLCBcIkt6XCJdLFxuICBcIkFSU1wiOiBbdW5kZWZpbmVkLCBcIiRcIl0sXG4gIFwiQVVEXCI6IFtcIkEkXCIsIFwiJFwiXSxcbiAgXCJBWk5cIjogW3VuZGVmaW5lZCwgXCLigrxcIl0sXG4gIFwiQkFNXCI6IFt1bmRlZmluZWQsIFwiS01cIl0sXG4gIFwiQkJEXCI6IFt1bmRlZmluZWQsIFwiJFwiXSxcbiAgXCJCRFRcIjogW3VuZGVmaW5lZCwgXCLgp7NcIl0sXG4gIFwiQkhEXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgM10sXG4gIFwiQklGXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMF0sXG4gIFwiQk1EXCI6IFt1bmRlZmluZWQsIFwiJFwiXSxcbiAgXCJCTkRcIjogW3VuZGVmaW5lZCwgXCIkXCJdLFxuICBcIkJPQlwiOiBbdW5kZWZpbmVkLCBcIkJzXCJdLFxuICBcIkJSTFwiOiBbXCJSJFwiXSxcbiAgXCJCU0RcIjogW3VuZGVmaW5lZCwgXCIkXCJdLFxuICBcIkJXUFwiOiBbdW5kZWZpbmVkLCBcIlBcIl0sXG4gIFwiQllOXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMl0sXG4gIFwiQllSXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMF0sXG4gIFwiQlpEXCI6IFt1bmRlZmluZWQsIFwiJFwiXSxcbiAgXCJDQURcIjogW1wiQ0EkXCIsIFwiJFwiLCAyXSxcbiAgXCJDSEZcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAyXSxcbiAgXCJDTEZcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCA0XSxcbiAgXCJDTFBcIjogW3VuZGVmaW5lZCwgXCIkXCIsIDBdLFxuICBcIkNOWVwiOiBbXCJDTsKlXCIsIFwiwqVcIl0sXG4gIFwiQ09QXCI6IFt1bmRlZmluZWQsIFwiJFwiLCAyXSxcbiAgXCJDUkNcIjogW3VuZGVmaW5lZCwgXCLigqFcIiwgMl0sXG4gIFwiQ1VDXCI6IFt1bmRlZmluZWQsIFwiJFwiXSxcbiAgXCJDVVBcIjogW3VuZGVmaW5lZCwgXCIkXCJdLFxuICBcIkNaS1wiOiBbdW5kZWZpbmVkLCBcIkvEjVwiLCAyXSxcbiAgXCJESkZcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAwXSxcbiAgXCJES0tcIjogW3VuZGVmaW5lZCwgXCJrclwiLCAyXSxcbiAgXCJET1BcIjogW3VuZGVmaW5lZCwgXCIkXCJdLFxuICBcIkVHUFwiOiBbdW5kZWZpbmVkLCBcIkXCo1wiXSxcbiAgXCJFU1BcIjogW3VuZGVmaW5lZCwgXCLigqdcIiwgMF0sXG4gIFwiRVVSXCI6IFtcIuKCrFwiXSxcbiAgXCJGSkRcIjogW3VuZGVmaW5lZCwgXCIkXCJdLFxuICBcIkZLUFwiOiBbdW5kZWZpbmVkLCBcIsKjXCJdLFxuICBcIkdCUFwiOiBbXCLCo1wiXSxcbiAgXCJHRUxcIjogW3VuZGVmaW5lZCwgXCLigr5cIl0sXG4gIFwiR0hTXCI6IFt1bmRlZmluZWQsIFwiR0jigrVcIl0sXG4gIFwiR0lQXCI6IFt1bmRlZmluZWQsIFwiwqNcIl0sXG4gIFwiR05GXCI6IFt1bmRlZmluZWQsIFwiRkdcIiwgMF0sXG4gIFwiR1RRXCI6IFt1bmRlZmluZWQsIFwiUVwiXSxcbiAgXCJHWURcIjogW3VuZGVmaW5lZCwgXCIkXCIsIDJdLFxuICBcIkhLRFwiOiBbXCJISyRcIiwgXCIkXCJdLFxuICBcIkhOTFwiOiBbdW5kZWZpbmVkLCBcIkxcIl0sXG4gIFwiSFJLXCI6IFt1bmRlZmluZWQsIFwia25cIl0sXG4gIFwiSFVGXCI6IFt1bmRlZmluZWQsIFwiRnRcIiwgMl0sXG4gIFwiSURSXCI6IFt1bmRlZmluZWQsIFwiUnBcIiwgMl0sXG4gIFwiSUxTXCI6IFtcIuKCqlwiXSxcbiAgXCJJTlJcIjogW1wi4oK5XCJdLFxuICBcIklRRFwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDBdLFxuICBcIklSUlwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDBdLFxuICBcIklTS1wiOiBbdW5kZWZpbmVkLCBcImtyXCIsIDBdLFxuICBcIklUTFwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDBdLFxuICBcIkpNRFwiOiBbdW5kZWZpbmVkLCBcIiRcIl0sXG4gIFwiSk9EXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgM10sXG4gIFwiSlBZXCI6IFtcIsKlXCIsIHVuZGVmaW5lZCwgMF0sXG4gIFwiS0hSXCI6IFt1bmRlZmluZWQsIFwi4Z+bXCJdLFxuICBcIktNRlwiOiBbdW5kZWZpbmVkLCBcIkNGXCIsIDBdLFxuICBcIktQV1wiOiBbdW5kZWZpbmVkLCBcIuKCqVwiLCAwXSxcbiAgXCJLUldcIjogW1wi4oKpXCIsIHVuZGVmaW5lZCwgMF0sXG4gIFwiS1dEXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgM10sXG4gIFwiS1lEXCI6IFt1bmRlZmluZWQsIFwiJFwiXSxcbiAgXCJLWlRcIjogW3VuZGVmaW5lZCwgXCLigrhcIl0sXG4gIFwiTEFLXCI6IFt1bmRlZmluZWQsIFwi4oKtXCIsIDBdLFxuICBcIkxCUFwiOiBbdW5kZWZpbmVkLCBcIkzCo1wiLCAwXSxcbiAgXCJMS1JcIjogW3VuZGVmaW5lZCwgXCJSc1wiXSxcbiAgXCJMUkRcIjogW3VuZGVmaW5lZCwgXCIkXCJdLFxuICBcIkxUTFwiOiBbdW5kZWZpbmVkLCBcIkx0XCJdLFxuICBcIkxVRlwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDBdLFxuICBcIkxWTFwiOiBbdW5kZWZpbmVkLCBcIkxzXCJdLFxuICBcIkxZRFwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDNdLFxuICBcIk1HQVwiOiBbdW5kZWZpbmVkLCBcIkFyXCIsIDBdLFxuICBcIk1HRlwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDBdLFxuICBcIk1NS1wiOiBbdW5kZWZpbmVkLCBcIktcIiwgMF0sXG4gIFwiTU5UXCI6IFt1bmRlZmluZWQsIFwi4oKuXCIsIDJdLFxuICBcIk1ST1wiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDBdLFxuICBcIk1VUlwiOiBbdW5kZWZpbmVkLCBcIlJzXCIsIDJdLFxuICBcIk1YTlwiOiBbXCJNWCRcIiwgXCIkXCJdLFxuICBcIk1ZUlwiOiBbdW5kZWZpbmVkLCBcIlJNXCJdLFxuICBcIk5BRFwiOiBbdW5kZWZpbmVkLCBcIiRcIl0sXG4gIFwiTkdOXCI6IFt1bmRlZmluZWQsIFwi4oKmXCJdLFxuICBcIk5JT1wiOiBbdW5kZWZpbmVkLCBcIkMkXCJdLFxuICBcIk5PS1wiOiBbdW5kZWZpbmVkLCBcImtyXCIsIDJdLFxuICBcIk5QUlwiOiBbdW5kZWZpbmVkLCBcIlJzXCJdLFxuICBcIk5aRFwiOiBbXCJOWiRcIiwgXCIkXCJdLFxuICBcIk9NUlwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDNdLFxuICBcIlBIUFwiOiBbXCLigrFcIl0sXG4gIFwiUEtSXCI6IFt1bmRlZmluZWQsIFwiUnNcIiwgMl0sXG4gIFwiUExOXCI6IFt1bmRlZmluZWQsIFwiesWCXCJdLFxuICBcIlBZR1wiOiBbdW5kZWZpbmVkLCBcIuKCslwiLCAwXSxcbiAgXCJST05cIjogW3VuZGVmaW5lZCwgXCJsZWlcIl0sXG4gIFwiUlNEXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMF0sXG4gIFwiUlVCXCI6IFt1bmRlZmluZWQsIFwi4oK9XCJdLFxuICBcIlJXRlwiOiBbdW5kZWZpbmVkLCBcIlJGXCIsIDBdLFxuICBcIlNCRFwiOiBbdW5kZWZpbmVkLCBcIiRcIl0sXG4gIFwiU0VLXCI6IFt1bmRlZmluZWQsIFwia3JcIiwgMl0sXG4gIFwiU0dEXCI6IFt1bmRlZmluZWQsIFwiJFwiXSxcbiAgXCJTSFBcIjogW3VuZGVmaW5lZCwgXCLCo1wiXSxcbiAgXCJTTEVcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAyXSxcbiAgXCJTTExcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAwXSxcbiAgXCJTT1NcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAwXSxcbiAgXCJTUkRcIjogW3VuZGVmaW5lZCwgXCIkXCJdLFxuICBcIlNTUFwiOiBbdW5kZWZpbmVkLCBcIsKjXCJdLFxuICBcIlNURFwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDBdLFxuICBcIlNUTlwiOiBbdW5kZWZpbmVkLCBcIkRiXCJdLFxuICBcIlNZUFwiOiBbdW5kZWZpbmVkLCBcIsKjXCIsIDBdLFxuICBcIlRIQlwiOiBbdW5kZWZpbmVkLCBcIuC4v1wiXSxcbiAgXCJUTU1cIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAwXSxcbiAgXCJUTkRcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAzXSxcbiAgXCJUT1BcIjogW3VuZGVmaW5lZCwgXCJUJFwiXSxcbiAgXCJUUkxcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAwXSxcbiAgXCJUUllcIjogW3VuZGVmaW5lZCwgXCLigrpcIl0sXG4gIFwiVFREXCI6IFt1bmRlZmluZWQsIFwiJFwiXSxcbiAgXCJUV0RcIjogW1wiTlQkXCIsIFwiJFwiLCAyXSxcbiAgXCJUWlNcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAyXSxcbiAgXCJVQUhcIjogW3VuZGVmaW5lZCwgXCLigrRcIl0sXG4gIFwiVUdYXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMF0sXG4gIFwiVVNEXCI6IFtcIiRcIl0sXG4gIFwiVVlJXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMF0sXG4gIFwiVVlVXCI6IFt1bmRlZmluZWQsIFwiJFwiXSxcbiAgXCJVWVdcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCA0XSxcbiAgXCJVWlNcIjogW3VuZGVmaW5lZCwgdW5kZWZpbmVkLCAyXSxcbiAgXCJWRUZcIjogW3VuZGVmaW5lZCwgXCJCc1wiLCAyXSxcbiAgXCJWTkRcIjogW1wi4oKrXCIsIHVuZGVmaW5lZCwgMF0sXG4gIFwiVlVWXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMF0sXG4gIFwiWEFGXCI6IFtcIkZDRkFcIiwgdW5kZWZpbmVkLCAwXSxcbiAgXCJYQ0RcIjogW1wiRUMkXCIsIFwiJFwiXSxcbiAgXCJYT0ZcIjogW1wiRuKAr0NGQVwiLCB1bmRlZmluZWQsIDBdLFxuICBcIlhQRlwiOiBbXCJDRlBGXCIsIHVuZGVmaW5lZCwgMF0sXG4gIFwiWFhYXCI6IFtcIsKkXCJdLFxuICBcIllFUlwiOiBbdW5kZWZpbmVkLCB1bmRlZmluZWQsIDBdLFxuICBcIlpBUlwiOiBbdW5kZWZpbmVkLCBcIlJcIl0sXG4gIFwiWk1LXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMF0sXG4gIFwiWk1XXCI6IFt1bmRlZmluZWQsIFwiWktcIl0sXG4gIFwiWldEXCI6IFt1bmRlZmluZWQsIHVuZGVmaW5lZCwgMF1cbn07XG5cbi8qKlxuICogRm9ybWF0IHN0eWxlcyB0aGF0IGNhbiBiZSB1c2VkIHRvIHJlcHJlc2VudCBudW1iZXJzLlxuICogQHNlZSB7QGxpbmsgZ2V0TG9jYWxlTnVtYmVyRm9ybWF0fVxuICogQHNlZSBbSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIEd1aWRlXShndWlkZS9pMThuKVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqXG4gKiBAZGVwcmVjYXRlZCBgZ2V0TG9jYWxlTnVtYmVyRm9ybWF0YCBpcyBkZXByZWNhdGVkXG4gKi9cbnZhciBOdW1iZXJGb3JtYXRTdHlsZTtcbihmdW5jdGlvbiAoTnVtYmVyRm9ybWF0U3R5bGUpIHtcbiAgTnVtYmVyRm9ybWF0U3R5bGVbTnVtYmVyRm9ybWF0U3R5bGVbXCJEZWNpbWFsXCJdID0gMF0gPSBcIkRlY2ltYWxcIjtcbiAgTnVtYmVyRm9ybWF0U3R5bGVbTnVtYmVyRm9ybWF0U3R5bGVbXCJQZXJjZW50XCJdID0gMV0gPSBcIlBlcmNlbnRcIjtcbiAgTnVtYmVyRm9ybWF0U3R5bGVbTnVtYmVyRm9ybWF0U3R5bGVbXCJDdXJyZW5jeVwiXSA9IDJdID0gXCJDdXJyZW5jeVwiO1xuICBOdW1iZXJGb3JtYXRTdHlsZVtOdW1iZXJGb3JtYXRTdHlsZVtcIlNjaWVudGlmaWNcIl0gPSAzXSA9IFwiU2NpZW50aWZpY1wiO1xufSkoTnVtYmVyRm9ybWF0U3R5bGUgfHwgKE51bWJlckZvcm1hdFN0eWxlID0ge30pKTtcbi8qKlxuICogUGx1cmFsaXR5IGNhc2VzIHVzZWQgZm9yIHRyYW5zbGF0aW5nIHBsdXJhbHMgdG8gZGlmZmVyZW50IGxhbmd1YWdlcy5cbiAqXG4gKiBAc2VlIHtAbGluayBOZ1BsdXJhbH1cbiAqIEBzZWUge0BsaW5rIE5nUGx1cmFsQ2FzZX1cbiAqIEBzZWUgW0ludGVybmF0aW9uYWxpemF0aW9uIChpMThuKSBHdWlkZV0oZ3VpZGUvaTE4bilcbiAqXG4gKiBAcHVibGljQXBpXG4gKlxuICogQGRlcHJlY2F0ZWQgYGdldExvY2FsZVBsdXJhbENhc2VgIGlzIGRlcHJlY2F0ZWRcbiAqL1xudmFyIFBsdXJhbDtcbihmdW5jdGlvbiAoUGx1cmFsKSB7XG4gIFBsdXJhbFtQbHVyYWxbXCJaZXJvXCJdID0gMF0gPSBcIlplcm9cIjtcbiAgUGx1cmFsW1BsdXJhbFtcIk9uZVwiXSA9IDFdID0gXCJPbmVcIjtcbiAgUGx1cmFsW1BsdXJhbFtcIlR3b1wiXSA9IDJdID0gXCJUd29cIjtcbiAgUGx1cmFsW1BsdXJhbFtcIkZld1wiXSA9IDNdID0gXCJGZXdcIjtcbiAgUGx1cmFsW1BsdXJhbFtcIk1hbnlcIl0gPSA0XSA9IFwiTWFueVwiO1xuICBQbHVyYWxbUGx1cmFsW1wiT3RoZXJcIl0gPSA1XSA9IFwiT3RoZXJcIjtcbn0pKFBsdXJhbCB8fCAoUGx1cmFsID0ge30pKTtcbi8qKlxuICogQ29udGV4dC1kZXBlbmRhbnQgdHJhbnNsYXRpb24gZm9ybXMgZm9yIHN0cmluZ3MuXG4gKiBUeXBpY2FsbHkgdGhlIHN0YW5kYWxvbmUgdmVyc2lvbiBpcyBmb3IgdGhlIG5vbWluYXRpdmUgZm9ybSBvZiB0aGUgd29yZCxcbiAqIGFuZCB0aGUgZm9ybWF0IHZlcnNpb24gaXMgdXNlZCBmb3IgdGhlIGdlbml0aXZlIGNhc2UuXG4gKiBAc2VlIFtDTERSIHdlYnNpdGVdKGh0dHA6Ly9jbGRyLnVuaWNvZGUub3JnL3RyYW5zbGF0aW9uL2RhdGUtdGltZS0xL2RhdGUtdGltZSNUT0MtU3RhbmRhbG9uZS12cy4tRm9ybWF0LVN0eWxlcylcbiAqIEBzZWUgW0ludGVybmF0aW9uYWxpemF0aW9uIChpMThuKSBHdWlkZV0oZ3VpZGUvaTE4bilcbiAqXG4gKiBAcHVibGljQXBpXG4gKlxuICogQGRlcHJlY2F0ZWQgbG9jYWxlIGRhdGEgZ2V0dGVycyBhcmUgZGVwcmVjYXRlZFxuICovXG52YXIgRm9ybVN0eWxlO1xuKGZ1bmN0aW9uIChGb3JtU3R5bGUpIHtcbiAgRm9ybVN0eWxlW0Zvcm1TdHlsZVtcIkZvcm1hdFwiXSA9IDBdID0gXCJGb3JtYXRcIjtcbiAgRm9ybVN0eWxlW0Zvcm1TdHlsZVtcIlN0YW5kYWxvbmVcIl0gPSAxXSA9IFwiU3RhbmRhbG9uZVwiO1xufSkoRm9ybVN0eWxlIHx8IChGb3JtU3R5bGUgPSB7fSkpO1xuLyoqXG4gKiBTdHJpbmcgd2lkdGhzIGF2YWlsYWJsZSBmb3IgdHJhbnNsYXRpb25zLlxuICogVGhlIHNwZWNpZmljIGNoYXJhY3RlciB3aWR0aHMgYXJlIGxvY2FsZS1zcGVjaWZpYy5cbiAqIEV4YW1wbGVzIGFyZSBnaXZlbiBmb3IgdGhlIHdvcmQgXCJTdW5kYXlcIiBpbiBFbmdsaXNoLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqXG4gKiBAZGVwcmVjYXRlZCBsb2NhbGUgZGF0YSBnZXR0ZXJzIGFyZSBkZXByZWNhdGVkXG4gKi9cbnZhciBUcmFuc2xhdGlvbldpZHRoO1xuKGZ1bmN0aW9uIChUcmFuc2xhdGlvbldpZHRoKSB7XG4gIC8qKiAxIGNoYXJhY3RlciBmb3IgYGVuLVVTYC4gRm9yIGV4YW1wbGU6ICdTJyAqL1xuICBUcmFuc2xhdGlvbldpZHRoW1RyYW5zbGF0aW9uV2lkdGhbXCJOYXJyb3dcIl0gPSAwXSA9IFwiTmFycm93XCI7XG4gIC8qKiAzIGNoYXJhY3RlcnMgZm9yIGBlbi1VU2AuIEZvciBleGFtcGxlOiAnU3VuJyAqL1xuICBUcmFuc2xhdGlvbldpZHRoW1RyYW5zbGF0aW9uV2lkdGhbXCJBYmJyZXZpYXRlZFwiXSA9IDFdID0gXCJBYmJyZXZpYXRlZFwiO1xuICAvKiogRnVsbCBsZW5ndGggZm9yIGBlbi1VU2AuIEZvciBleGFtcGxlOiBcIlN1bmRheVwiICovXG4gIFRyYW5zbGF0aW9uV2lkdGhbVHJhbnNsYXRpb25XaWR0aFtcIldpZGVcIl0gPSAyXSA9IFwiV2lkZVwiO1xuICAvKiogMiBjaGFyYWN0ZXJzIGZvciBgZW4tVVNgLCBGb3IgZXhhbXBsZTogXCJTdVwiICovXG4gIFRyYW5zbGF0aW9uV2lkdGhbVHJhbnNsYXRpb25XaWR0aFtcIlNob3J0XCJdID0gM10gPSBcIlNob3J0XCI7XG59KShUcmFuc2xhdGlvbldpZHRoIHx8IChUcmFuc2xhdGlvbldpZHRoID0ge30pKTtcbi8qKlxuICogU3RyaW5nIHdpZHRocyBhdmFpbGFibGUgZm9yIGRhdGUtdGltZSBmb3JtYXRzLlxuICogVGhlIHNwZWNpZmljIGNoYXJhY3RlciB3aWR0aHMgYXJlIGxvY2FsZS1zcGVjaWZpYy5cbiAqIEV4YW1wbGVzIGFyZSBnaXZlbiBmb3IgYGVuLVVTYC5cbiAqXG4gKiBAc2VlIHtAbGluayBnZXRMb2NhbGVEYXRlRm9ybWF0fVxuICogQHNlZSB7QGxpbmsgZ2V0TG9jYWxlVGltZUZvcm1hdH1cbiAqIEBzZWUge0BsaW5rIGdldExvY2FsZURhdGVUaW1lRm9ybWF0fVxuICogQHNlZSBbSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIEd1aWRlXShndWlkZS9pMThuKVxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIERhdGUgbG9jYWxlIGRhdGEgZ2V0dGVycyBhcmUgZGVwcmVjYXRlZFxuICovXG52YXIgRm9ybWF0V2lkdGg7XG4oZnVuY3Rpb24gKEZvcm1hdFdpZHRoKSB7XG4gIC8qKlxuICAgKiBGb3IgYGVuLVVTYCwgYCdNL2QveXksIGg6bW0gYSdgXG4gICAqIChFeGFtcGxlOiBgNi8xNS8xNSwgOTowMyBBTWApXG4gICAqL1xuICBGb3JtYXRXaWR0aFtGb3JtYXRXaWR0aFtcIlNob3J0XCJdID0gMF0gPSBcIlNob3J0XCI7XG4gIC8qKlxuICAgKiBGb3IgYGVuLVVTYCwgYCdNTU0gZCwgeSwgaDptbTpzcyBhJ2BcbiAgICogKEV4YW1wbGU6IGBKdW4gMTUsIDIwMTUsIDk6MDM6MDEgQU1gKVxuICAgKi9cbiAgRm9ybWF0V2lkdGhbRm9ybWF0V2lkdGhbXCJNZWRpdW1cIl0gPSAxXSA9IFwiTWVkaXVtXCI7XG4gIC8qKlxuICAgKiBGb3IgYGVuLVVTYCwgYCdNTU1NIGQsIHksIGg6bW06c3MgYSB6J2BcbiAgICogKEV4YW1wbGU6IGBKdW5lIDE1LCAyMDE1IGF0IDk6MDM6MDEgQU0gR01UKzFgKVxuICAgKi9cbiAgRm9ybWF0V2lkdGhbRm9ybWF0V2lkdGhbXCJMb25nXCJdID0gMl0gPSBcIkxvbmdcIjtcbiAgLyoqXG4gICAqIEZvciBgZW4tVVNgLCBgJ0VFRUUsIE1NTU0gZCwgeSwgaDptbTpzcyBhIHp6enonYFxuICAgKiAoRXhhbXBsZTogYE1vbmRheSwgSnVuZSAxNSwgMjAxNSBhdCA5OjAzOjAxIEFNIEdNVCswMTowMGApXG4gICAqL1xuICBGb3JtYXRXaWR0aFtGb3JtYXRXaWR0aFtcIkZ1bGxcIl0gPSAzXSA9IFwiRnVsbFwiO1xufSkoRm9ybWF0V2lkdGggfHwgKEZvcm1hdFdpZHRoID0ge30pKTtcbi8vIFRoaXMgbmVlZHMgdG8gYmUgYW4gb2JqZWN0IGxpdGVyYWwsIHJhdGhlciB0aGFuIGFuIGVudW0sIGJlY2F1c2UgVHlwZVNjcmlwdCA1LjQrXG4vLyBkb2Vzbid0IGFsbG93IG51bWVyaWMga2V5cyBhbmQgd2UgaGF2ZSBgSW5maW5pdHlgIGFuZCBgTmFOYC5cbi8qKlxuICogU3ltYm9scyB0aGF0IGNhbiBiZSB1c2VkIHRvIHJlcGxhY2UgcGxhY2Vob2xkZXJzIGluIG51bWJlciBwYXR0ZXJucy5cbiAqIEV4YW1wbGVzIGFyZSBiYXNlZCBvbiBgZW4tVVNgIHZhbHVlcy5cbiAqXG4gKiBAc2VlIHtAbGluayBnZXRMb2NhbGVOdW1iZXJTeW1ib2x9XG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIGBnZXRMb2NhbGVOdW1iZXJTeW1ib2xgIGlzIGRlcHJlY2F0ZWRcbiAqXG4gKiBAb2JqZWN0LWxpdGVyYWwtYXMtZW51bVxuICovXG5jb25zdCBOdW1iZXJTeW1ib2wgPSB7XG4gIC8qKlxuICAgKiBEZWNpbWFsIHNlcGFyYXRvci5cbiAgICogRm9yIGBlbi1VU2AsIHRoZSBkb3QgY2hhcmFjdGVyLlxuICAgKiBFeGFtcGxlOiAyLDM0NWAuYDY3XG4gICAqL1xuICBEZWNpbWFsOiAwLFxuICAvKipcbiAgICogR3JvdXBpbmcgc2VwYXJhdG9yLCB0eXBpY2FsbHkgZm9yIHRob3VzYW5kcy5cbiAgICogRm9yIGBlbi1VU2AsIHRoZSBjb21tYSBjaGFyYWN0ZXIuXG4gICAqIEV4YW1wbGU6IDJgLGAzNDUuNjdcbiAgICovXG4gIEdyb3VwOiAxLFxuICAvKipcbiAgICogTGlzdC1pdGVtIHNlcGFyYXRvci5cbiAgICogRXhhbXBsZTogXCJvbmUsIHR3bywgYW5kIHRocmVlXCJcbiAgICovXG4gIExpc3Q6IDIsXG4gIC8qKlxuICAgKiBTaWduIGZvciBwZXJjZW50YWdlIChvdXQgb2YgMTAwKS5cbiAgICogRXhhbXBsZTogMjMuNCVcbiAgICovXG4gIFBlcmNlbnRTaWduOiAzLFxuICAvKipcbiAgICogU2lnbiBmb3IgcG9zaXRpdmUgbnVtYmVycy5cbiAgICogRXhhbXBsZTogKzIzXG4gICAqL1xuICBQbHVzU2lnbjogNCxcbiAgLyoqXG4gICAqIFNpZ24gZm9yIG5lZ2F0aXZlIG51bWJlcnMuXG4gICAqIEV4YW1wbGU6IC0yM1xuICAgKi9cbiAgTWludXNTaWduOiA1LFxuICAvKipcbiAgICogQ29tcHV0ZXIgbm90YXRpb24gZm9yIGV4cG9uZW50aWFsIHZhbHVlIChuIHRpbWVzIGEgcG93ZXIgb2YgMTApLlxuICAgKiBFeGFtcGxlOiAxLjJFM1xuICAgKi9cbiAgRXhwb25lbnRpYWw6IDYsXG4gIC8qKlxuICAgKiBIdW1hbi1yZWFkYWJsZSBmb3JtYXQgb2YgZXhwb25lbnRpYWwuXG4gICAqIEV4YW1wbGU6IDEuMngxMDNcbiAgICovXG4gIFN1cGVyc2NyaXB0aW5nRXhwb25lbnQ6IDcsXG4gIC8qKlxuICAgKiBTaWduIGZvciBwZXJtaWxsZSAob3V0IG9mIDEwMDApLlxuICAgKiBFeGFtcGxlOiAyMy404oCwXG4gICAqL1xuICBQZXJNaWxsZTogOCxcbiAgLyoqXG4gICAqIEluZmluaXR5LCBjYW4gYmUgdXNlZCB3aXRoIHBsdXMgYW5kIG1pbnVzLlxuICAgKiBFeGFtcGxlOiDiiJ4sICviiJ4sIC3iiJ5cbiAgICovXG4gIEluZmluaXR5OiA5LFxuICAvKipcbiAgICogTm90IGEgbnVtYmVyLlxuICAgKiBFeGFtcGxlOiBOYU5cbiAgICovXG4gIE5hTjogMTAsXG4gIC8qKlxuICAgKiBTeW1ib2wgdXNlZCBiZXR3ZWVuIHRpbWUgdW5pdHMuXG4gICAqIEV4YW1wbGU6IDEwOjUyXG4gICAqL1xuICBUaW1lU2VwYXJhdG9yOiAxMSxcbiAgLyoqXG4gICAqIERlY2ltYWwgc2VwYXJhdG9yIGZvciBjdXJyZW5jeSB2YWx1ZXMgKGZhbGxiYWNrIHRvIGBEZWNpbWFsYCkuXG4gICAqIEV4YW1wbGU6ICQyLDM0NS42N1xuICAgKi9cbiAgQ3VycmVuY3lEZWNpbWFsOiAxMixcbiAgLyoqXG4gICAqIEdyb3VwIHNlcGFyYXRvciBmb3IgY3VycmVuY3kgdmFsdWVzIChmYWxsYmFjayB0byBgR3JvdXBgKS5cbiAgICogRXhhbXBsZTogJDIsMzQ1LjY3XG4gICAqL1xuICBDdXJyZW5jeUdyb3VwOiAxM1xufTtcbi8qKlxuICogVGhlIHZhbHVlIGZvciBlYWNoIGRheSBvZiB0aGUgd2VlaywgYmFzZWQgb24gdGhlIGBlbi1VU2AgbG9jYWxlXG4gKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIFdlZWsgbG9jYWxlIGdldHRlcnMgYXJlIGRlcHJlY2F0ZWRcbiAqL1xudmFyIFdlZWtEYXk7XG4oZnVuY3Rpb24gKFdlZWtEYXkpIHtcbiAgV2Vla0RheVtXZWVrRGF5W1wiU3VuZGF5XCJdID0gMF0gPSBcIlN1bmRheVwiO1xuICBXZWVrRGF5W1dlZWtEYXlbXCJNb25kYXlcIl0gPSAxXSA9IFwiTW9uZGF5XCI7XG4gIFdlZWtEYXlbV2Vla0RheVtcIlR1ZXNkYXlcIl0gPSAyXSA9IFwiVHVlc2RheVwiO1xuICBXZWVrRGF5W1dlZWtEYXlbXCJXZWRuZXNkYXlcIl0gPSAzXSA9IFwiV2VkbmVzZGF5XCI7XG4gIFdlZWtEYXlbV2Vla0RheVtcIlRodXJzZGF5XCJdID0gNF0gPSBcIlRodXJzZGF5XCI7XG4gIFdlZWtEYXlbV2Vla0RheVtcIkZyaWRheVwiXSA9IDVdID0gXCJGcmlkYXlcIjtcbiAgV2Vla0RheVtXZWVrRGF5W1wiU2F0dXJkYXlcIl0gPSA2XSA9IFwiU2F0dXJkYXlcIjtcbn0pKFdlZWtEYXkgfHwgKFdlZWtEYXkgPSB7fSkpO1xuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGxvY2FsZSBJRCBmcm9tIHRoZSBjdXJyZW50bHkgbG9hZGVkIGxvY2FsZS5cbiAqIFRoZSBsb2FkZWQgbG9jYWxlIGNvdWxkIGJlLCBmb3IgZXhhbXBsZSwgYSBnbG9iYWwgb25lIHJhdGhlciB0aGFuIGEgcmVnaW9uYWwgb25lLlxuICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlLCBzdWNoIGFzIGBmci1GUmAuXG4gKiBAcmV0dXJucyBUaGUgbG9jYWxlIGNvZGUuIEZvciBleGFtcGxlLCBgZnJgLlxuICogQHNlZSBbSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIEd1aWRlXShndWlkZS9pMThuKVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqXG4gKiBAZGVwcmVjYXRlZCBBbmd1bGFyIHJlY29tbWVuZHMgcmVseWluZyBvbiB0aGUgYEludGxgIEFQSSBmb3IgaTE4bi5cbiAqIFRoaXMgZnVuY3Rpb24gc2VydmVzIG5vIHB1cnBvc2Ugd2hlbiByZWx5aW5nIG9uIHRoZSBgSW50bGAgQVBJLlxuICovXG5mdW5jdGlvbiBnZXRMb2NhbGVJZChsb2NhbGUpIHtcbiAgcmV0dXJuIMm1ZmluZExvY2FsZURhdGEobG9jYWxlKVvJtUxvY2FsZURhdGFJbmRleC5Mb2NhbGVJZF07XG59XG4vKipcbiAqIFJldHJpZXZlcyBkYXkgcGVyaW9kIHN0cmluZ3MgZm9yIHRoZSBnaXZlbiBsb2NhbGUuXG4gKlxuICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlIGZvciB0aGUgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuXG4gKiBAcGFyYW0gZm9ybVN0eWxlIFRoZSByZXF1aXJlZCBncmFtbWF0aWNhbCBmb3JtLlxuICogQHBhcmFtIHdpZHRoIFRoZSByZXF1aXJlZCBjaGFyYWN0ZXIgd2lkdGguXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBsb2NhbGl6ZWQgcGVyaW9kIHN0cmluZ3MuIEZvciBleGFtcGxlLCBgW0FNLCBQTV1gIGZvciBgZW4tVVNgLlxuICogQHNlZSBbSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIEd1aWRlXShndWlkZS9pMThuKVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqXG4gKiBAZGVwcmVjYXRlZCBBbmd1bGFyIHJlY29tbWVuZHMgcmVseWluZyBvbiB0aGUgYEludGxgIEFQSSBmb3IgaTE4bi5cbiAqIFVzZSBgSW50bC5EYXRlVGltZUZvcm1hdGAgZm9yIGRhdGUgZm9ybWF0aW5nIGluc3RlYWQuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2FsZURheVBlcmlvZHMobG9jYWxlLCBmb3JtU3R5bGUsIHdpZHRoKSB7XG4gIGNvbnN0IGRhdGEgPSDJtWZpbmRMb2NhbGVEYXRhKGxvY2FsZSk7XG4gIGNvbnN0IGFtUG1EYXRhID0gW2RhdGFbybVMb2NhbGVEYXRhSW5kZXguRGF5UGVyaW9kc0Zvcm1hdF0sIGRhdGFbybVMb2NhbGVEYXRhSW5kZXguRGF5UGVyaW9kc1N0YW5kYWxvbmVdXTtcbiAgY29uc3QgYW1QbSA9IGdldExhc3REZWZpbmVkVmFsdWUoYW1QbURhdGEsIGZvcm1TdHlsZSk7XG4gIHJldHVybiBnZXRMYXN0RGVmaW5lZFZhbHVlKGFtUG0sIHdpZHRoKTtcbn1cbi8qKlxuICogUmV0cmlldmVzIGRheXMgb2YgdGhlIHdlZWsgZm9yIHRoZSBnaXZlbiBsb2NhbGUsIHVzaW5nIHRoZSBHcmVnb3JpYW4gY2FsZW5kYXIuXG4gKlxuICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlIGZvciB0aGUgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuXG4gKiBAcGFyYW0gZm9ybVN0eWxlIFRoZSByZXF1aXJlZCBncmFtbWF0aWNhbCBmb3JtLlxuICogQHBhcmFtIHdpZHRoIFRoZSByZXF1aXJlZCBjaGFyYWN0ZXIgd2lkdGguXG4gKiBAcmV0dXJucyBBbiBhcnJheSBvZiBsb2NhbGl6ZWQgbmFtZSBzdHJpbmdzLlxuICogRm9yIGV4YW1wbGUsYFtTdW5kYXksIE1vbmRheSwgLi4uIFNhdHVyZGF5XWAgZm9yIGBlbi1VU2AuXG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIEFuZ3VsYXIgcmVjb21tZW5kcyByZWx5aW5nIG9uIHRoZSBgSW50bGAgQVBJIGZvciBpMThuLlxuICogVXNlIGBJbnRsLkRhdGVUaW1lRm9ybWF0YCBmb3IgZGF0ZSBmb3JtYXRpbmcgaW5zdGVhZC5cbiAqL1xuZnVuY3Rpb24gZ2V0TG9jYWxlRGF5TmFtZXMobG9jYWxlLCBmb3JtU3R5bGUsIHdpZHRoKSB7XG4gIGNvbnN0IGRhdGEgPSDJtWZpbmRMb2NhbGVEYXRhKGxvY2FsZSk7XG4gIGNvbnN0IGRheXNEYXRhID0gW2RhdGFbybVMb2NhbGVEYXRhSW5kZXguRGF5c0Zvcm1hdF0sIGRhdGFbybVMb2NhbGVEYXRhSW5kZXguRGF5c1N0YW5kYWxvbmVdXTtcbiAgY29uc3QgZGF5cyA9IGdldExhc3REZWZpbmVkVmFsdWUoZGF5c0RhdGEsIGZvcm1TdHlsZSk7XG4gIHJldHVybiBnZXRMYXN0RGVmaW5lZFZhbHVlKGRheXMsIHdpZHRoKTtcbn1cbi8qKlxuICogUmV0cmlldmVzIG1vbnRocyBvZiB0aGUgeWVhciBmb3IgdGhlIGdpdmVuIGxvY2FsZSwgdXNpbmcgdGhlIEdyZWdvcmlhbiBjYWxlbmRhci5cbiAqXG4gKiBAcGFyYW0gbG9jYWxlIEEgbG9jYWxlIGNvZGUgZm9yIHRoZSBsb2NhbGUgZm9ybWF0IHJ1bGVzIHRvIHVzZS5cbiAqIEBwYXJhbSBmb3JtU3R5bGUgVGhlIHJlcXVpcmVkIGdyYW1tYXRpY2FsIGZvcm0uXG4gKiBAcGFyYW0gd2lkdGggVGhlIHJlcXVpcmVkIGNoYXJhY3RlciB3aWR0aC5cbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGxvY2FsaXplZCBuYW1lIHN0cmluZ3MuXG4gKiBGb3IgZXhhbXBsZSwgIGBbSmFudWFyeSwgRmVicnVhcnksIC4uLl1gIGZvciBgZW4tVVNgLlxuICogQHNlZSBbSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIEd1aWRlXShndWlkZS9pMThuKVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqXG4gKiBAZGVwcmVjYXRlZCBBbmd1bGFyIHJlY29tbWVuZHMgcmVseWluZyBvbiB0aGUgYEludGxgIEFQSSBmb3IgaTE4bi5cbiAqIFVzZSBgSW50bC5EYXRlVGltZUZvcm1hdGAgZm9yIGRhdGUgZm9ybWF0aW5nIGluc3RlYWQuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2FsZU1vbnRoTmFtZXMobG9jYWxlLCBmb3JtU3R5bGUsIHdpZHRoKSB7XG4gIGNvbnN0IGRhdGEgPSDJtWZpbmRMb2NhbGVEYXRhKGxvY2FsZSk7XG4gIGNvbnN0IG1vbnRoc0RhdGEgPSBbZGF0YVvJtUxvY2FsZURhdGFJbmRleC5Nb250aHNGb3JtYXRdLCBkYXRhW8m1TG9jYWxlRGF0YUluZGV4Lk1vbnRoc1N0YW5kYWxvbmVdXTtcbiAgY29uc3QgbW9udGhzID0gZ2V0TGFzdERlZmluZWRWYWx1ZShtb250aHNEYXRhLCBmb3JtU3R5bGUpO1xuICByZXR1cm4gZ2V0TGFzdERlZmluZWRWYWx1ZShtb250aHMsIHdpZHRoKTtcbn1cbi8qKlxuICogUmV0cmlldmVzIEdyZWdvcmlhbi1jYWxlbmRhciBlcmFzIGZvciB0aGUgZ2l2ZW4gbG9jYWxlLlxuICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlIGZvciB0aGUgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuXG4gKiBAcGFyYW0gd2lkdGggVGhlIHJlcXVpcmVkIGNoYXJhY3RlciB3aWR0aC5cblxuICogQHJldHVybnMgQW4gYXJyYXkgb2YgbG9jYWxpemVkIGVyYSBzdHJpbmdzLlxuICogRm9yIGV4YW1wbGUsIGBbQUQsIEJDXWAgZm9yIGBlbi1VU2AuXG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIEFuZ3VsYXIgcmVjb21tZW5kcyByZWx5aW5nIG9uIHRoZSBgSW50bGAgQVBJIGZvciBpMThuLlxuICogVXNlIGBJbnRsLkRhdGVUaW1lRm9ybWF0YCBmb3IgZGF0ZSBmb3JtYXRpbmcgaW5zdGVhZC5cbiAqL1xuZnVuY3Rpb24gZ2V0TG9jYWxlRXJhTmFtZXMobG9jYWxlLCB3aWR0aCkge1xuICBjb25zdCBkYXRhID0gybVmaW5kTG9jYWxlRGF0YShsb2NhbGUpO1xuICBjb25zdCBlcmFzRGF0YSA9IGRhdGFbybVMb2NhbGVEYXRhSW5kZXguRXJhc107XG4gIHJldHVybiBnZXRMYXN0RGVmaW5lZFZhbHVlKGVyYXNEYXRhLCB3aWR0aCk7XG59XG4vKipcbiAqIFJldHJpZXZlcyB0aGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrIGZvciB0aGUgZ2l2ZW4gbG9jYWxlLlxuICpcbiAqIEBwYXJhbSBsb2NhbGUgQSBsb2NhbGUgY29kZSBmb3IgdGhlIGxvY2FsZSBmb3JtYXQgcnVsZXMgdG8gdXNlLlxuICogQHJldHVybnMgQSBkYXkgaW5kZXggbnVtYmVyLCB1c2luZyB0aGUgMC1iYXNlZCB3ZWVrLWRheSBpbmRleCBmb3IgYGVuLVVTYFxuICogKFN1bmRheSA9IDAsIE1vbmRheSA9IDEsIC4uLikuXG4gKiBGb3IgZXhhbXBsZSwgZm9yIGBmci1GUmAsIHJldHVybnMgMSB0byBpbmRpY2F0ZSB0aGF0IHRoZSBmaXJzdCBkYXkgaXMgTW9uZGF5LlxuICogQHNlZSBbSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIEd1aWRlXShndWlkZS9pMThuKVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqXG4gKiBAZGVwcmVjYXRlZCBBbmd1bGFyIHJlY29tbWVuZHMgcmVseWluZyBvbiB0aGUgYEludGxgIEFQSSBmb3IgaTE4bi5cbiAqIEludGwncyBbYGdldFdlZWtJbmZvYF0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvSW50bC9Mb2NhbGUvZ2V0V2Vla0luZm8pIGhhcyBwYXJ0aWFsIHN1cHBvcnQgKENocm9taXVtIE05OSAmIFNhZmFyaSAxNykuXG4gKiBZb3UgbWF5IHdhbnQgdG8gcmVseSBvbiB0aGUgZm9sbG93aW5nIGFsdGVybmF0aXZlczpcbiAqIC0gTGlicmFyaWVzIGxpa2UgW2BMdXhvbmBdKGh0dHBzOi8vbW9tZW50LmdpdGh1Yi5pby9sdXhvbi8jLykgcmVseSBvbiBgSW50bGAgYnV0IGZhbGxiYWNrIG9uIHRoZSBJU08gODYwMSBkZWZpbml0aW9uIChtb25kYXkpIGlmIGBnZXRXZWVrSW5mb2AgaXMgbm90IHN1cHBvcnRlZC5cbiAqIC0gT3RoZXIgbGlicmFpcmllcyBsaWtlIFtgZGF0ZS1mbnNgXShodHRwczovL2RhdGUtZm5zLm9yZy8pLCBbYGRheS5qc2BdKGh0dHBzOi8vZGF5LmpzLm9yZy9lbi8pIG9yIFtgd2Vla3N0YXJ0YF0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2Uvd2Vla3N0YXJ0KSBsaWJyYXJ5IHByb3ZpZGUgdGhlaXIgb3duIGxvY2FsZSBiYXNlZCBkYXRhIGZvciB0aGUgZmlyc3QgZGF5IG9mIHRoZSB3ZWVrLlxuICovXG5mdW5jdGlvbiBnZXRMb2NhbGVGaXJzdERheU9mV2Vlayhsb2NhbGUpIHtcbiAgY29uc3QgZGF0YSA9IMm1ZmluZExvY2FsZURhdGEobG9jYWxlKTtcbiAgcmV0dXJuIGRhdGFbybVMb2NhbGVEYXRhSW5kZXguRmlyc3REYXlPZldlZWtdO1xufVxuLyoqXG4gKiBSYW5nZSBvZiB3ZWVrIGRheXMgdGhhdCBhcmUgY29uc2lkZXJlZCB0aGUgd2Vlay1lbmQgZm9yIHRoZSBnaXZlbiBsb2NhbGUuXG4gKlxuICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlIGZvciB0aGUgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuXG4gKiBAcmV0dXJucyBUaGUgcmFuZ2Ugb2YgZGF5IHZhbHVlcywgYFtzdGFydERheSwgZW5kRGF5XWAuXG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIEFuZ3VsYXIgcmVjb21tZW5kcyByZWx5aW5nIG9uIHRoZSBgSW50bGAgQVBJIGZvciBpMThuLlxuICogSW50bCdzIFtgZ2V0V2Vla0luZm9gXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9JbnRsL0xvY2FsZS9nZXRXZWVrSW5mbykgaGFzIHBhcnRpYWwgc3VwcG9ydCAoQ2hyb21pdW0gTTk5ICYgU2FmYXJpIDE3KS5cbiAqIExpYnJhcmllcyBsaWtlIFtgTHV4b25gXShodHRwczovL21vbWVudC5naXRodWIuaW8vbHV4b24vIy8pIHJlbHkgb24gYEludGxgIGJ1dCBmYWxsYmFjayBvbiB0aGUgSVNPIDg2MDEgZGVmaW5pdGlvbiAoU2F0dXJkYXkrU3VuZGF5KSBpZiBgZ2V0V2Vla0luZm9gIGlzIG5vdCBzdXBwb3J0ZWQgLlxuICovXG5mdW5jdGlvbiBnZXRMb2NhbGVXZWVrRW5kUmFuZ2UobG9jYWxlKSB7XG4gIGNvbnN0IGRhdGEgPSDJtWZpbmRMb2NhbGVEYXRhKGxvY2FsZSk7XG4gIHJldHVybiBkYXRhW8m1TG9jYWxlRGF0YUluZGV4LldlZWtlbmRSYW5nZV07XG59XG4vKipcbiAqIFJldHJpZXZlcyBhIGxvY2FsaXplZCBkYXRlLXZhbHVlIGZvcm1hdHRpbmcgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSBsb2NhbGUgQSBsb2NhbGUgY29kZSBmb3IgdGhlIGxvY2FsZSBmb3JtYXQgcnVsZXMgdG8gdXNlLlxuICogQHBhcmFtIHdpZHRoIFRoZSBmb3JtYXQgdHlwZS5cbiAqIEByZXR1cm5zIFRoZSBsb2NhbGl6ZWQgZm9ybWF0dGluZyBzdHJpbmcuXG4gKiBAc2VlIHtAbGluayBGb3JtYXRXaWR0aH1cbiAqIEBzZWUgW0ludGVybmF0aW9uYWxpemF0aW9uIChpMThuKSBHdWlkZV0oZ3VpZGUvaTE4bilcbiAqXG4gKiBAcHVibGljQXBpXG4gKlxuICogQGRlcHJlY2F0ZWQgQW5ndWxhciByZWNvbW1lbmRzIHJlbHlpbmcgb24gdGhlIGBJbnRsYCBBUEkgZm9yIGkxOG4uXG4gKiBVc2UgYEludGwuRGF0ZVRpbWVGb3JtYXRgIGZvciBkYXRlIGZvcm1hdGluZyBpbnN0ZWFkLlxuICovXG5mdW5jdGlvbiBnZXRMb2NhbGVEYXRlRm9ybWF0KGxvY2FsZSwgd2lkdGgpIHtcbiAgY29uc3QgZGF0YSA9IMm1ZmluZExvY2FsZURhdGEobG9jYWxlKTtcbiAgcmV0dXJuIGdldExhc3REZWZpbmVkVmFsdWUoZGF0YVvJtUxvY2FsZURhdGFJbmRleC5EYXRlRm9ybWF0XSwgd2lkdGgpO1xufVxuLyoqXG4gKiBSZXRyaWV2ZXMgYSBsb2NhbGl6ZWQgdGltZS12YWx1ZSBmb3JtYXR0aW5nIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gbG9jYWxlIEEgbG9jYWxlIGNvZGUgZm9yIHRoZSBsb2NhbGUgZm9ybWF0IHJ1bGVzIHRvIHVzZS5cbiAqIEBwYXJhbSB3aWR0aCBUaGUgZm9ybWF0IHR5cGUuXG4gKiBAcmV0dXJucyBUaGUgbG9jYWxpemVkIGZvcm1hdHRpbmcgc3RyaW5nLlxuICogQHNlZSB7QGxpbmsgRm9ybWF0V2lkdGh9XG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG5cbiAqIEBwdWJsaWNBcGlcbiAqIEBkZXByZWNhdGVkIEFuZ3VsYXIgcmVjb21tZW5kcyByZWx5aW5nIG9uIHRoZSBgSW50bGAgQVBJIGZvciBpMThuLlxuICogVXNlIGBJbnRsLkRhdGVUaW1lRm9ybWF0YCBmb3IgZGF0ZSBmb3JtYXRpbmcgaW5zdGVhZC5cbiAqL1xuZnVuY3Rpb24gZ2V0TG9jYWxlVGltZUZvcm1hdChsb2NhbGUsIHdpZHRoKSB7XG4gIGNvbnN0IGRhdGEgPSDJtWZpbmRMb2NhbGVEYXRhKGxvY2FsZSk7XG4gIHJldHVybiBnZXRMYXN0RGVmaW5lZFZhbHVlKGRhdGFbybVMb2NhbGVEYXRhSW5kZXguVGltZUZvcm1hdF0sIHdpZHRoKTtcbn1cbi8qKlxuICogUmV0cmlldmVzIGEgbG9jYWxpemVkIGRhdGUtdGltZSBmb3JtYXR0aW5nIHN0cmluZy5cbiAqXG4gKiBAcGFyYW0gbG9jYWxlIEEgbG9jYWxlIGNvZGUgZm9yIHRoZSBsb2NhbGUgZm9ybWF0IHJ1bGVzIHRvIHVzZS5cbiAqIEBwYXJhbSB3aWR0aCBUaGUgZm9ybWF0IHR5cGUuXG4gKiBAcmV0dXJucyBUaGUgbG9jYWxpemVkIGZvcm1hdHRpbmcgc3RyaW5nLlxuICogQHNlZSB7QGxpbmsgRm9ybWF0V2lkdGh9XG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIEFuZ3VsYXIgcmVjb21tZW5kcyByZWx5aW5nIG9uIHRoZSBgSW50bGAgQVBJIGZvciBpMThuLlxuICogVXNlIGBJbnRsLkRhdGVUaW1lRm9ybWF0YCBmb3IgZGF0ZSBmb3JtYXRpbmcgaW5zdGVhZC5cbiAqL1xuZnVuY3Rpb24gZ2V0TG9jYWxlRGF0ZVRpbWVGb3JtYXQobG9jYWxlLCB3aWR0aCkge1xuICBjb25zdCBkYXRhID0gybVmaW5kTG9jYWxlRGF0YShsb2NhbGUpO1xuICBjb25zdCBkYXRlVGltZUZvcm1hdERhdGEgPSBkYXRhW8m1TG9jYWxlRGF0YUluZGV4LkRhdGVUaW1lRm9ybWF0XTtcbiAgcmV0dXJuIGdldExhc3REZWZpbmVkVmFsdWUoZGF0ZVRpbWVGb3JtYXREYXRhLCB3aWR0aCk7XG59XG4vKipcbiAqIFJldHJpZXZlcyBhIGxvY2FsaXplZCBudW1iZXIgc3ltYm9sIHRoYXQgY2FuIGJlIHVzZWQgdG8gcmVwbGFjZSBwbGFjZWhvbGRlcnMgaW4gbnVtYmVyIGZvcm1hdHMuXG4gKiBAcGFyYW0gbG9jYWxlIFRoZSBsb2NhbGUgY29kZS5cbiAqIEBwYXJhbSBzeW1ib2wgVGhlIHN5bWJvbCB0byBsb2NhbGl6ZS4gTXVzdCBiZSBvbmUgb2YgYE51bWJlclN5bWJvbGAuXG4gKiBAcmV0dXJucyBUaGUgY2hhcmFjdGVyIGZvciB0aGUgbG9jYWxpemVkIHN5bWJvbC5cbiAqIEBzZWUge0BsaW5rIE51bWJlclN5bWJvbH1cbiAqIEBzZWUgW0ludGVybmF0aW9uYWxpemF0aW9uIChpMThuKSBHdWlkZV0oZ3VpZGUvaTE4bilcbiAqXG4gKiBAcHVibGljQXBpXG4gKlxuICogQGRlcHJlY2F0ZWQgQW5ndWxhciByZWNvbW1lbmRzIHJlbHlpbmcgb24gdGhlIGBJbnRsYCBBUEkgZm9yIGkxOG4uXG4gKiBVc2UgYEludGwuTnVtYmVyRm9ybWF0YCB0byBmb3JtYXQgbnVtYmVycyBpbnN0ZWFkLlxuICovXG5mdW5jdGlvbiBnZXRMb2NhbGVOdW1iZXJTeW1ib2wobG9jYWxlLCBzeW1ib2wpIHtcbiAgY29uc3QgZGF0YSA9IMm1ZmluZExvY2FsZURhdGEobG9jYWxlKTtcbiAgY29uc3QgcmVzID0gZGF0YVvJtUxvY2FsZURhdGFJbmRleC5OdW1iZXJTeW1ib2xzXVtzeW1ib2xdO1xuICBpZiAodHlwZW9mIHJlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBpZiAoc3ltYm9sID09PSBOdW1iZXJTeW1ib2wuQ3VycmVuY3lEZWNpbWFsKSB7XG4gICAgICByZXR1cm4gZGF0YVvJtUxvY2FsZURhdGFJbmRleC5OdW1iZXJTeW1ib2xzXVtOdW1iZXJTeW1ib2wuRGVjaW1hbF07XG4gICAgfSBlbHNlIGlmIChzeW1ib2wgPT09IE51bWJlclN5bWJvbC5DdXJyZW5jeUdyb3VwKSB7XG4gICAgICByZXR1cm4gZGF0YVvJtUxvY2FsZURhdGFJbmRleC5OdW1iZXJTeW1ib2xzXVtOdW1iZXJTeW1ib2wuR3JvdXBdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzO1xufVxuLyoqXG4gKiBSZXRyaWV2ZXMgYSBudW1iZXIgZm9ybWF0IGZvciBhIGdpdmVuIGxvY2FsZS5cbiAqXG4gKiBOdW1iZXJzIGFyZSBmb3JtYXR0ZWQgdXNpbmcgcGF0dGVybnMsIGxpa2UgYCMsIyMjLjAwYC4gRm9yIGV4YW1wbGUsIHRoZSBwYXR0ZXJuIGAjLCMjIy4wMGBcbiAqIHdoZW4gdXNlZCB0byBmb3JtYXQgdGhlIG51bWJlciAxMjM0NS42NzggY291bGQgcmVzdWx0IGluIFwiMTInMzQ1LDY3OFwiLiBUaGF0IHdvdWxkIGhhcHBlbiBpZiB0aGVcbiAqIGdyb3VwaW5nIHNlcGFyYXRvciBmb3IgeW91ciBsYW5ndWFnZSBpcyBhbiBhcG9zdHJvcGhlLCBhbmQgdGhlIGRlY2ltYWwgc2VwYXJhdG9yIGlzIGEgY29tbWEuXG4gKlxuICogPGI+SW1wb3J0YW50OjwvYj4gVGhlIGNoYXJhY3RlcnMgYC5gIGAsYCBgMGAgYCNgIChhbmQgb3RoZXJzIGJlbG93KSBhcmUgc3BlY2lhbCBwbGFjZWhvbGRlcnNcbiAqIHRoYXQgc3RhbmQgZm9yIHRoZSBkZWNpbWFsIHNlcGFyYXRvciwgYW5kIHNvIG9uLCBhbmQgYXJlIE5PVCByZWFsIGNoYXJhY3RlcnMuXG4gKiBZb3UgbXVzdCBOT1QgXCJ0cmFuc2xhdGVcIiB0aGUgcGxhY2Vob2xkZXJzLiBGb3IgZXhhbXBsZSwgZG9uJ3QgY2hhbmdlIGAuYCB0byBgLGAgZXZlbiB0aG91Z2ggaW5cbiAqIHlvdXIgbGFuZ3VhZ2UgdGhlIGRlY2ltYWwgcG9pbnQgaXMgd3JpdHRlbiB3aXRoIGEgY29tbWEuIFRoZSBzeW1ib2xzIHNob3VsZCBiZSByZXBsYWNlZCBieSB0aGVcbiAqIGxvY2FsIGVxdWl2YWxlbnRzLCB1c2luZyB0aGUgYXBwcm9wcmlhdGUgYE51bWJlclN5bWJvbGAgZm9yIHlvdXIgbGFuZ3VhZ2UuXG4gKlxuICogSGVyZSBhcmUgdGhlIHNwZWNpYWwgY2hhcmFjdGVycyB1c2VkIGluIG51bWJlciBwYXR0ZXJuczpcbiAqXG4gKiB8IFN5bWJvbCB8IE1lYW5pbmcgfFxuICogfC0tLS0tLS0tfC0tLS0tLS0tLXxcbiAqIHwgLiB8IFJlcGxhY2VkIGF1dG9tYXRpY2FsbHkgYnkgdGhlIGNoYXJhY3RlciB1c2VkIGZvciB0aGUgZGVjaW1hbCBwb2ludC4gfFxuICogfCAsIHwgUmVwbGFjZWQgYnkgdGhlIFwiZ3JvdXBpbmdcIiAodGhvdXNhbmRzKSBzZXBhcmF0b3IuIHxcbiAqIHwgMCB8IFJlcGxhY2VkIGJ5IGEgZGlnaXQgKG9yIHplcm8gaWYgdGhlcmUgYXJlbid0IGVub3VnaCBkaWdpdHMpLiB8XG4gKiB8ICMgfCBSZXBsYWNlZCBieSBhIGRpZ2l0IChvciBub3RoaW5nIGlmIHRoZXJlIGFyZW4ndCBlbm91Z2gpLiB8XG4gKiB8IMKkIHwgUmVwbGFjZWQgYnkgYSBjdXJyZW5jeSBzeW1ib2wsIHN1Y2ggYXMgJCBvciBVU0QuIHxcbiAqIHwgJSB8IE1hcmtzIGEgcGVyY2VudCBmb3JtYXQuIFRoZSAlIHN5bWJvbCBtYXkgY2hhbmdlIHBvc2l0aW9uLCBidXQgbXVzdCBiZSByZXRhaW5lZC4gfFxuICogfCBFIHwgTWFya3MgYSBzY2llbnRpZmljIGZvcm1hdC4gVGhlIEUgc3ltYm9sIG1heSBjaGFuZ2UgcG9zaXRpb24sIGJ1dCBtdXN0IGJlIHJldGFpbmVkLiB8XG4gKiB8ICcgfCBTcGVjaWFsIGNoYXJhY3RlcnMgdXNlZCBhcyBsaXRlcmFsIGNoYXJhY3RlcnMgYXJlIHF1b3RlZCB3aXRoIEFTQ0lJIHNpbmdsZSBxdW90ZXMuIHxcbiAqXG4gKiBAcGFyYW0gbG9jYWxlIEEgbG9jYWxlIGNvZGUgZm9yIHRoZSBsb2NhbGUgZm9ybWF0IHJ1bGVzIHRvIHVzZS5cbiAqIEBwYXJhbSB0eXBlIFRoZSB0eXBlIG9mIG51bWVyaWMgdmFsdWUgdG8gYmUgZm9ybWF0dGVkIChzdWNoIGFzIGBEZWNpbWFsYCBvciBgQ3VycmVuY3lgLilcbiAqIEByZXR1cm5zIFRoZSBsb2NhbGl6ZWQgZm9ybWF0IHN0cmluZy5cbiAqIEBzZWUge0BsaW5rIE51bWJlckZvcm1hdFN0eWxlfVxuICogQHNlZSBbQ0xEUiB3ZWJzaXRlXShodHRwOi8vY2xkci51bmljb2RlLm9yZy90cmFuc2xhdGlvbi9udW1iZXItcGF0dGVybnMpXG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIEFuZ3VsYXIgcmVjb21tZW5kcyByZWx5aW5nIG9uIHRoZSBgSW50bGAgQVBJIGZvciBpMThuLlxuICogTGV0IGBJbnRsLk51bWJlckZvcm1hdGAgZGV0ZXJtaW5lIHRoZSBudW1iZXIgZm9ybWF0IGluc3RlYWRcbiAqL1xuZnVuY3Rpb24gZ2V0TG9jYWxlTnVtYmVyRm9ybWF0KGxvY2FsZSwgdHlwZSkge1xuICBjb25zdCBkYXRhID0gybVmaW5kTG9jYWxlRGF0YShsb2NhbGUpO1xuICByZXR1cm4gZGF0YVvJtUxvY2FsZURhdGFJbmRleC5OdW1iZXJGb3JtYXRzXVt0eXBlXTtcbn1cbi8qKlxuICogUmV0cmlldmVzIHRoZSBzeW1ib2wgdXNlZCB0byByZXByZXNlbnQgdGhlIGN1cnJlbmN5IGZvciB0aGUgbWFpbiBjb3VudHJ5XG4gKiBjb3JyZXNwb25kaW5nIHRvIGEgZ2l2ZW4gbG9jYWxlLiBGb3IgZXhhbXBsZSwgJyQnIGZvciBgZW4tVVNgLlxuICpcbiAqIEBwYXJhbSBsb2NhbGUgQSBsb2NhbGUgY29kZSBmb3IgdGhlIGxvY2FsZSBmb3JtYXQgcnVsZXMgdG8gdXNlLlxuICogQHJldHVybnMgVGhlIGxvY2FsaXplZCBzeW1ib2wgY2hhcmFjdGVyLFxuICogb3IgYG51bGxgIGlmIHRoZSBtYWluIGNvdW50cnkgY2Fubm90IGJlIGRldGVybWluZWQuXG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIFVzZSB0aGUgYEludGxgIEFQSSB0byBmb3JtYXQgYSBjdXJyZW5jeSB3aXRoIGZyb20gY3VycmVuY3kgY29kZVxuICovXG5mdW5jdGlvbiBnZXRMb2NhbGVDdXJyZW5jeVN5bWJvbChsb2NhbGUpIHtcbiAgY29uc3QgZGF0YSA9IMm1ZmluZExvY2FsZURhdGEobG9jYWxlKTtcbiAgcmV0dXJuIGRhdGFbybVMb2NhbGVEYXRhSW5kZXguQ3VycmVuY3lTeW1ib2xdIHx8IG51bGw7XG59XG4vKipcbiAqIFJldHJpZXZlcyB0aGUgbmFtZSBvZiB0aGUgY3VycmVuY3kgZm9yIHRoZSBtYWluIGNvdW50cnkgY29ycmVzcG9uZGluZ1xuICogdG8gYSBnaXZlbiBsb2NhbGUuIEZvciBleGFtcGxlLCAnVVMgRG9sbGFyJyBmb3IgYGVuLVVTYC5cbiAqIEBwYXJhbSBsb2NhbGUgQSBsb2NhbGUgY29kZSBmb3IgdGhlIGxvY2FsZSBmb3JtYXQgcnVsZXMgdG8gdXNlLlxuICogQHJldHVybnMgVGhlIGN1cnJlbmN5IG5hbWUsXG4gKiBvciBgbnVsbGAgaWYgdGhlIG1haW4gY291bnRyeSBjYW5ub3QgYmUgZGV0ZXJtaW5lZC5cbiAqIEBzZWUgW0ludGVybmF0aW9uYWxpemF0aW9uIChpMThuKSBHdWlkZV0oZ3VpZGUvaTE4bilcbiAqXG4gKiBAcHVibGljQXBpXG4gKlxuICogQGRlcHJlY2F0ZWQgVXNlIHRoZSBgSW50bGAgQVBJIHRvIGZvcm1hdCBhIGN1cnJlbmN5IHdpdGggZnJvbSBjdXJyZW5jeSBjb2RlXG4gKi9cbmZ1bmN0aW9uIGdldExvY2FsZUN1cnJlbmN5TmFtZShsb2NhbGUpIHtcbiAgY29uc3QgZGF0YSA9IMm1ZmluZExvY2FsZURhdGEobG9jYWxlKTtcbiAgcmV0dXJuIGRhdGFbybVMb2NhbGVEYXRhSW5kZXguQ3VycmVuY3lOYW1lXSB8fCBudWxsO1xufVxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGRlZmF1bHQgY3VycmVuY3kgY29kZSBmb3IgdGhlIGdpdmVuIGxvY2FsZS5cbiAqXG4gKiBUaGUgZGVmYXVsdCBpcyBkZWZpbmVkIGFzIHRoZSBmaXJzdCBjdXJyZW5jeSB3aGljaCBpcyBzdGlsbCBpbiB1c2UuXG4gKlxuICogQHBhcmFtIGxvY2FsZSBUaGUgY29kZSBvZiB0aGUgbG9jYWxlIHdob3NlIGN1cnJlbmN5IGNvZGUgd2Ugd2FudC5cbiAqIEByZXR1cm5zIFRoZSBjb2RlIG9mIHRoZSBkZWZhdWx0IGN1cnJlbmN5IGZvciB0aGUgZ2l2ZW4gbG9jYWxlLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqXG4gKiBAZGVwcmVjYXRlZCBXZSByZWNvbW1lbmQgeW91IGNyZWF0ZSBhIG1hcCBvZiBsb2NhbGUgdG8gSVNPIDQyMTcgY3VycmVuY3kgY29kZXMuXG4gKiBUaW1lIHJlbGF0aXZlIGN1cnJlbmN5IGRhdGEgaXMgcHJvdmlkZWQgYnkgdGhlIENMRFIgcHJvamVjdC4gU2VlIGh0dHBzOi8vd3d3LnVuaWNvZGUub3JnL2NsZHIvY2hhcnRzLzQ0L3N1cHBsZW1lbnRhbC9kZXRhaWxlZF90ZXJyaXRvcnlfY3VycmVuY3lfaW5mb3JtYXRpb24uaHRtbFxuICovXG5mdW5jdGlvbiBnZXRMb2NhbGVDdXJyZW5jeUNvZGUobG9jYWxlKSB7XG4gIHJldHVybiDJtWdldExvY2FsZUN1cnJlbmN5Q29kZShsb2NhbGUpO1xufVxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGN1cnJlbmN5IHZhbHVlcyBmb3IgYSBnaXZlbiBsb2NhbGUuXG4gKiBAcGFyYW0gbG9jYWxlIEEgbG9jYWxlIGNvZGUgZm9yIHRoZSBsb2NhbGUgZm9ybWF0IHJ1bGVzIHRvIHVzZS5cbiAqIEByZXR1cm5zIFRoZSBjdXJyZW5jeSB2YWx1ZXMuXG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKi9cbmZ1bmN0aW9uIGdldExvY2FsZUN1cnJlbmNpZXMobG9jYWxlKSB7XG4gIGNvbnN0IGRhdGEgPSDJtWZpbmRMb2NhbGVEYXRhKGxvY2FsZSk7XG4gIHJldHVybiBkYXRhW8m1TG9jYWxlRGF0YUluZGV4LkN1cnJlbmNpZXNdO1xufVxuLyoqXG4gKiBAcHVibGljQXBpXG4gKlxuICogQGRlcHJlY2F0ZWQgQW5ndWxhciByZWNvbW1lbmRzIHJlbHlpbmcgb24gdGhlIGBJbnRsYCBBUEkgZm9yIGkxOG4uXG4gKiBVc2UgYEludGwuUGx1cmFsUnVsZXNgIGluc3RlYWRcbiAqL1xuY29uc3QgZ2V0TG9jYWxlUGx1cmFsQ2FzZSA9IMm1Z2V0TG9jYWxlUGx1cmFsQ2FzZTtcbmZ1bmN0aW9uIGNoZWNrRnVsbERhdGEoZGF0YSkge1xuICBpZiAoIWRhdGFbybVMb2NhbGVEYXRhSW5kZXguRXh0cmFEYXRhXSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyBleHRyYSBsb2NhbGUgZGF0YSBmb3IgdGhlIGxvY2FsZSBcIiR7ZGF0YVvJtUxvY2FsZURhdGFJbmRleC5Mb2NhbGVJZF19XCIuIFVzZSBcInJlZ2lzdGVyTG9jYWxlRGF0YVwiIHRvIGxvYWQgbmV3IGRhdGEuIFNlZSB0aGUgXCJJMThuIGd1aWRlXCIgb24gYW5ndWxhci5pbyB0byBrbm93IG1vcmUuYCk7XG4gIH1cbn1cbi8qKlxuICogUmV0cmlldmVzIGxvY2FsZS1zcGVjaWZpYyBydWxlcyB1c2VkIHRvIGRldGVybWluZSB3aGljaCBkYXkgcGVyaW9kIHRvIHVzZVxuICogd2hlbiBtb3JlIHRoYW4gb25lIHBlcmlvZCBpcyBkZWZpbmVkIGZvciBhIGxvY2FsZS5cbiAqXG4gKiBUaGVyZSBpcyBhIHJ1bGUgZm9yIGVhY2ggZGVmaW5lZCBkYXkgcGVyaW9kLiBUaGVcbiAqIGZpcnN0IHJ1bGUgaXMgYXBwbGllZCB0byB0aGUgZmlyc3QgZGF5IHBlcmlvZCBhbmQgc28gb24uXG4gKiBGYWxsIGJhY2sgdG8gQU0vUE0gd2hlbiBubyBydWxlcyBhcmUgYXZhaWxhYmxlLlxuICpcbiAqIEEgcnVsZSBjYW4gc3BlY2lmeSBhIHBlcmlvZCBhcyB0aW1lIHJhbmdlLCBvciBhcyBhIHNpbmdsZSB0aW1lIHZhbHVlLlxuICpcbiAqIFRoaXMgZnVuY3Rpb25hbGl0eSBpcyBvbmx5IGF2YWlsYWJsZSB3aGVuIHlvdSBoYXZlIGxvYWRlZCB0aGUgZnVsbCBsb2NhbGUgZGF0YS5cbiAqIFNlZSB0aGUgW1wiSTE4biBndWlkZVwiXShndWlkZS9pMThuL2Zvcm1hdC1kYXRhLWxvY2FsZSkuXG4gKlxuICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlIGZvciB0aGUgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuXG4gKiBAcmV0dXJucyBUaGUgcnVsZXMgZm9yIHRoZSBsb2NhbGUsIGEgc2luZ2xlIHRpbWUgdmFsdWUgb3IgYXJyYXkgb2YgKmZyb20tdGltZSwgdG8tdGltZSosXG4gKiBvciBudWxsIGlmIG5vIHBlcmlvZHMgYXJlIGF2YWlsYWJsZS5cbiAqXG4gKiBAc2VlIHtAbGluayBnZXRMb2NhbGVFeHRyYURheVBlcmlvZHN9XG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIEFuZ3VsYXIgcmVjb21tZW5kcyByZWx5aW5nIG9uIHRoZSBgSW50bGAgQVBJIGZvciBpMThuLlxuICogTGV0IGBJbnRsLkRhdGVUaW1lRm9ybWF0YCBkZXRlcm1pbmUgdGhlIGRheSBwZXJpb2QgaW5zdGVhZC5cbiAqL1xuZnVuY3Rpb24gZ2V0TG9jYWxlRXh0cmFEYXlQZXJpb2RSdWxlcyhsb2NhbGUpIHtcbiAgY29uc3QgZGF0YSA9IMm1ZmluZExvY2FsZURhdGEobG9jYWxlKTtcbiAgY2hlY2tGdWxsRGF0YShkYXRhKTtcbiAgY29uc3QgcnVsZXMgPSBkYXRhW8m1TG9jYWxlRGF0YUluZGV4LkV4dHJhRGF0YV1bMiAvKiDJtUV4dHJhTG9jYWxlRGF0YUluZGV4LkV4dHJhRGF5UGVyaW9kc1J1bGVzICovXSB8fCBbXTtcbiAgcmV0dXJuIHJ1bGVzLm1hcChydWxlID0+IHtcbiAgICBpZiAodHlwZW9mIHJ1bGUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gZXh0cmFjdFRpbWUocnVsZSk7XG4gICAgfVxuICAgIHJldHVybiBbZXh0cmFjdFRpbWUocnVsZVswXSksIGV4dHJhY3RUaW1lKHJ1bGVbMV0pXTtcbiAgfSk7XG59XG4vKipcbiAqIFJldHJpZXZlcyBsb2NhbGUtc3BlY2lmaWMgZGF5IHBlcmlvZHMsIHdoaWNoIGluZGljYXRlIHJvdWdobHkgaG93IGEgZGF5IGlzIGJyb2tlbiB1cFxuICogaW4gZGlmZmVyZW50IGxhbmd1YWdlcy5cbiAqIEZvciBleGFtcGxlLCBmb3IgYGVuLVVTYCwgcGVyaW9kcyBhcmUgbW9ybmluZywgbm9vbiwgYWZ0ZXJub29uLCBldmVuaW5nLCBhbmQgbWlkbmlnaHQuXG4gKlxuICogVGhpcyBmdW5jdGlvbmFsaXR5IGlzIG9ubHkgYXZhaWxhYmxlIHdoZW4geW91IGhhdmUgbG9hZGVkIHRoZSBmdWxsIGxvY2FsZSBkYXRhLlxuICogU2VlIHRoZSBbXCJJMThuIGd1aWRlXCJdKGd1aWRlL2kxOG4vZm9ybWF0LWRhdGEtbG9jYWxlKS5cbiAqXG4gKiBAcGFyYW0gbG9jYWxlIEEgbG9jYWxlIGNvZGUgZm9yIHRoZSBsb2NhbGUgZm9ybWF0IHJ1bGVzIHRvIHVzZS5cbiAqIEBwYXJhbSBmb3JtU3R5bGUgVGhlIHJlcXVpcmVkIGdyYW1tYXRpY2FsIGZvcm0uXG4gKiBAcGFyYW0gd2lkdGggVGhlIHJlcXVpcmVkIGNoYXJhY3RlciB3aWR0aC5cbiAqIEByZXR1cm5zIFRoZSB0cmFuc2xhdGVkIGRheS1wZXJpb2Qgc3RyaW5ncy5cbiAqIEBzZWUge0BsaW5rIGdldExvY2FsZUV4dHJhRGF5UGVyaW9kUnVsZXN9XG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKlxuICogQHB1YmxpY0FwaVxuICpcbiAqIEBkZXByZWNhdGVkIEFuZ3VsYXIgcmVjb21tZW5kcyByZWx5aW5nIG9uIHRoZSBgSW50bGAgQVBJIGZvciBpMThuLlxuICogVG8gZXh0cmFjdCBhIGRheSBwZXJpb2QgdXNlIGBJbnRsLkRhdGVUaW1lRm9ybWF0YCB3aXRoIHRoZSBgZGF5UGVyaW9kYCBvcHRpb24gaW5zdGVhZC5cbiAqL1xuZnVuY3Rpb24gZ2V0TG9jYWxlRXh0cmFEYXlQZXJpb2RzKGxvY2FsZSwgZm9ybVN0eWxlLCB3aWR0aCkge1xuICBjb25zdCBkYXRhID0gybVmaW5kTG9jYWxlRGF0YShsb2NhbGUpO1xuICBjaGVja0Z1bGxEYXRhKGRhdGEpO1xuICBjb25zdCBkYXlQZXJpb2RzRGF0YSA9IFtkYXRhW8m1TG9jYWxlRGF0YUluZGV4LkV4dHJhRGF0YV1bMCAvKiDJtUV4dHJhTG9jYWxlRGF0YUluZGV4LkV4dHJhRGF5UGVyaW9kRm9ybWF0cyAqL10sIGRhdGFbybVMb2NhbGVEYXRhSW5kZXguRXh0cmFEYXRhXVsxIC8qIMm1RXh0cmFMb2NhbGVEYXRhSW5kZXguRXh0cmFEYXlQZXJpb2RTdGFuZGFsb25lICovXV07XG4gIGNvbnN0IGRheVBlcmlvZHMgPSBnZXRMYXN0RGVmaW5lZFZhbHVlKGRheVBlcmlvZHNEYXRhLCBmb3JtU3R5bGUpIHx8IFtdO1xuICByZXR1cm4gZ2V0TGFzdERlZmluZWRWYWx1ZShkYXlQZXJpb2RzLCB3aWR0aCkgfHwgW107XG59XG4vKipcbiAqIFJldHJpZXZlcyB0aGUgd3JpdGluZyBkaXJlY3Rpb24gb2YgYSBzcGVjaWZpZWQgbG9jYWxlXG4gKiBAcGFyYW0gbG9jYWxlIEEgbG9jYWxlIGNvZGUgZm9yIHRoZSBsb2NhbGUgZm9ybWF0IHJ1bGVzIHRvIHVzZS5cbiAqIEBwdWJsaWNBcGlcbiAqIEByZXR1cm5zICdydGwnIG9yICdsdHInXG4gKiBAc2VlIFtJbnRlcm5hdGlvbmFsaXphdGlvbiAoaTE4bikgR3VpZGVdKGd1aWRlL2kxOG4pXG4gKlxuICogQGRlcHJlY2F0ZWQgQW5ndWxhciByZWNvbW1lbmRzIHJlbHlpbmcgb24gdGhlIGBJbnRsYCBBUEkgZm9yIGkxOG4uXG4gKiBGb3IgZGF0ZXMgYW5kIG51bWJlcnMsIGxldCBgSW50bC5EYXRlVGltZUZvcm1hdCgpYCBhbmQgYEludGwuTnVtYmVyRm9ybWF0KClgIGRldGVybWluZSB0aGUgd3JpdGluZyBkaXJlY3Rpb24uXG4gKiBUaGUgYEludGxgIGFsdGVybmF0aXZlIFtgZ2V0VGV4dEluZm9gXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9JbnRsL0xvY2FsZS9nZXRUZXh0SW5mbykuXG4gKiBoYXMgb25seSBwYXJ0aWFsIHN1cHBvcnQgKENocm9taXVtIE05OSAmIFNhZmFyaSAxNykuXG4gKiAzcmQgcGFydHkgYWx0ZXJuYXRpdmVzIGxpa2UgW2BydGwtZGV0ZWN0YF0oaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvcnRsLWRldGVjdCkgY2FuIHdvcmsgYXJvdW5kIHRoaXMgaXNzdWUuXG4gKi9cbmZ1bmN0aW9uIGdldExvY2FsZURpcmVjdGlvbihsb2NhbGUpIHtcbiAgY29uc3QgZGF0YSA9IMm1ZmluZExvY2FsZURhdGEobG9jYWxlKTtcbiAgcmV0dXJuIGRhdGFbybVMb2NhbGVEYXRhSW5kZXguRGlyZWN0aW9uYWxpdHldO1xufVxuLyoqXG4gKiBSZXRyaWV2ZXMgdGhlIGZpcnN0IHZhbHVlIHRoYXQgaXMgZGVmaW5lZCBpbiBhbiBhcnJheSwgZ29pbmcgYmFja3dhcmRzIGZyb20gYW4gaW5kZXggcG9zaXRpb24uXG4gKlxuICogVG8gYXZvaWQgcmVwZWF0aW5nIHRoZSBzYW1lIGRhdGEgKGFzIHdoZW4gdGhlIFwiZm9ybWF0XCIgYW5kIFwic3RhbmRhbG9uZVwiIGZvcm1zIGFyZSB0aGUgc2FtZSlcbiAqIGFkZCB0aGUgZmlyc3QgdmFsdWUgdG8gdGhlIGxvY2FsZSBkYXRhIGFycmF5cywgYW5kIGFkZCBvdGhlciB2YWx1ZXMgb25seSBpZiB0aGV5IGFyZSBkaWZmZXJlbnQuXG4gKlxuICogQHBhcmFtIGRhdGEgVGhlIGRhdGEgYXJyYXkgdG8gcmV0cmlldmUgZnJvbS5cbiAqIEBwYXJhbSBpbmRleCBBIDAtYmFzZWQgaW5kZXggaW50byB0aGUgYXJyYXkgdG8gc3RhcnQgZnJvbS5cbiAqIEByZXR1cm5zIFRoZSB2YWx1ZSBpbW1lZGlhdGVseSBiZWZvcmUgdGhlIGdpdmVuIGluZGV4IHBvc2l0aW9uLlxuICogQHNlZSBbSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIEd1aWRlXShndWlkZS9pMThuKVxuICpcbiAqL1xuZnVuY3Rpb24gZ2V0TGFzdERlZmluZWRWYWx1ZShkYXRhLCBpbmRleCkge1xuICBmb3IgKGxldCBpID0gaW5kZXg7IGkgPiAtMTsgaS0tKSB7XG4gICAgaWYgKHR5cGVvZiBkYXRhW2ldICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgcmV0dXJuIGRhdGFbaV07XG4gICAgfVxuICB9XG4gIHRocm93IG5ldyBFcnJvcignTG9jYWxlIGRhdGEgQVBJOiBsb2NhbGUgZGF0YSB1bmRlZmluZWQnKTtcbn1cbi8qKlxuICogRXh0cmFjdHMgdGhlIGhvdXJzIGFuZCBtaW51dGVzIGZyb20gYSBzdHJpbmcgbGlrZSBcIjE1OjQ1XCJcbiAqL1xuZnVuY3Rpb24gZXh0cmFjdFRpbWUodGltZSkge1xuICBjb25zdCBbaCwgbV0gPSB0aW1lLnNwbGl0KCc6Jyk7XG4gIHJldHVybiB7XG4gICAgaG91cnM6ICtoLFxuICAgIG1pbnV0ZXM6ICttXG4gIH07XG59XG4vKipcbiAqIFJldHJpZXZlcyB0aGUgY3VycmVuY3kgc3ltYm9sIGZvciBhIGdpdmVuIGN1cnJlbmN5IGNvZGUuXG4gKlxuICogRm9yIGV4YW1wbGUsIGZvciB0aGUgZGVmYXVsdCBgZW4tVVNgIGxvY2FsZSwgdGhlIGNvZGUgYFVTRGAgY2FuXG4gKiBiZSByZXByZXNlbnRlZCBieSB0aGUgbmFycm93IHN5bWJvbCBgJGAgb3IgdGhlIHdpZGUgc3ltYm9sIGBVUyRgLlxuICpcbiAqIEBwYXJhbSBjb2RlIFRoZSBjdXJyZW5jeSBjb2RlLlxuICogQHBhcmFtIGZvcm1hdCBUaGUgZm9ybWF0LCBgd2lkZWAgb3IgYG5hcnJvd2AuXG4gKiBAcGFyYW0gbG9jYWxlIEEgbG9jYWxlIGNvZGUgZm9yIHRoZSBsb2NhbGUgZm9ybWF0IHJ1bGVzIHRvIHVzZS5cbiAqXG4gKiBAcmV0dXJucyBUaGUgc3ltYm9sLCBvciB0aGUgY3VycmVuY3kgY29kZSBpZiBubyBzeW1ib2wgaXMgYXZhaWxhYmxlLlxuICogQHNlZSBbSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIEd1aWRlXShndWlkZS9pMThuKVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqXG4gKiBAZGVwcmVjYXRlZCBBbmd1bGFyIHJlY29tbWVuZHMgcmVseWluZyBvbiB0aGUgYEludGxgIEFQSSBmb3IgaTE4bi5cbiAqIFlvdSBjYW4gdXNlIGBJbnRsLk51bWJlckZvcm1hdCgpLmZvcm1hdFRvUGFydHMoKWAgdG8gZXh0cmFjdCB0aGUgY3VycmVuY3kgc3ltYm9sLlxuICogRm9yIGV4YW1wbGU6IGBJbnRsLk51bWJlckZvcm1hdCgnZW4nLCB7c3R5bGU6J2N1cnJlbmN5JywgY3VycmVuY3k6ICdVU0QnfSkuZm9ybWF0VG9QYXJ0cygpLmZpbmQocGFydCA9PiBwYXJ0LnR5cGUgPT09ICdjdXJyZW5jeScpLnZhbHVlYFxuICogcmV0dXJucyBgJGAgZm9yIFVTRCBjdXJyZW5jeSBjb2RlIGluIHRoZSBgZW5gIGxvY2FsZS5cbiAqIE5vdGU6IGBVUyRgIGlzIGEgY3VycmVuY3kgc3ltYm9sIGZvciB0aGUgYGVuLWNhYCBsb2NhbGUgYnV0IG5vdCB0aGUgYGVuLXVzYCBsb2NhbGUuXG4gKi9cbmZ1bmN0aW9uIGdldEN1cnJlbmN5U3ltYm9sKGNvZGUsIGZvcm1hdCwgbG9jYWxlID0gJ2VuJykge1xuICBjb25zdCBjdXJyZW5jeSA9IGdldExvY2FsZUN1cnJlbmNpZXMobG9jYWxlKVtjb2RlXSB8fCBDVVJSRU5DSUVTX0VOW2NvZGVdIHx8IFtdO1xuICBjb25zdCBzeW1ib2xOYXJyb3cgPSBjdXJyZW5jeVsxIC8qIMm1Q3VycmVuY3lJbmRleC5TeW1ib2xOYXJyb3cgKi9dO1xuICBpZiAoZm9ybWF0ID09PSAnbmFycm93JyAmJiB0eXBlb2Ygc3ltYm9sTmFycm93ID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBzeW1ib2xOYXJyb3c7XG4gIH1cbiAgcmV0dXJuIGN1cnJlbmN5WzAgLyogybVDdXJyZW5jeUluZGV4LlN5bWJvbCAqL10gfHwgY29kZTtcbn1cbi8vIE1vc3QgY3VycmVuY2llcyBoYXZlIGNlbnRzLCB0aGF0J3Mgd2h5IHRoZSBkZWZhdWx0IGlzIDJcbmNvbnN0IERFRkFVTFRfTkJfT0ZfQ1VSUkVOQ1lfRElHSVRTID0gMjtcbi8qKlxuICogUmVwb3J0cyB0aGUgbnVtYmVyIG9mIGRlY2ltYWwgZGlnaXRzIGZvciBhIGdpdmVuIGN1cnJlbmN5LlxuICogVGhlIHZhbHVlIGRlcGVuZHMgdXBvbiB0aGUgcHJlc2VuY2Ugb2YgY2VudHMgaW4gdGhhdCBwYXJ0aWN1bGFyIGN1cnJlbmN5LlxuICpcbiAqIEBwYXJhbSBjb2RlIFRoZSBjdXJyZW5jeSBjb2RlLlxuICogQHJldHVybnMgVGhlIG51bWJlciBvZiBkZWNpbWFsIGRpZ2l0cywgdHlwaWNhbGx5IDAgb3IgMi5cbiAqIEBzZWUgW0ludGVybmF0aW9uYWxpemF0aW9uIChpMThuKSBHdWlkZV0oZ3VpZGUvaTE4bilcbiAqXG4gKiBAcHVibGljQXBpXG4gKlxuICogQGRlcHJlY2F0ZWQgQW5ndWxhciByZWNvbW1lbmRzIHJlbHlpbmcgb24gdGhlIGBJbnRsYCBBUEkgZm9yIGkxOG4uXG4gKiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBub3QgYmUgdXNlZCBhbnltb3JlLiBMZXQgYEludGwuTnVtYmVyRm9ybWF0YCBkZXRlcm1pbmUgdGhlIG51bWJlciBvZiBkaWdpdHMgdG8gZGlzcGxheSBmb3IgdGhlIGN1cnJlbmN5XG4gKi9cbmZ1bmN0aW9uIGdldE51bWJlck9mQ3VycmVuY3lEaWdpdHMoY29kZSkge1xuICBsZXQgZGlnaXRzO1xuICBjb25zdCBjdXJyZW5jeSA9IENVUlJFTkNJRVNfRU5bY29kZV07XG4gIGlmIChjdXJyZW5jeSkge1xuICAgIGRpZ2l0cyA9IGN1cnJlbmN5WzIgLyogybVDdXJyZW5jeUluZGV4Lk5iT2ZEaWdpdHMgKi9dO1xuICB9XG4gIHJldHVybiB0eXBlb2YgZGlnaXRzID09PSAnbnVtYmVyJyA/IGRpZ2l0cyA6IERFRkFVTFRfTkJfT0ZfQ1VSUkVOQ1lfRElHSVRTO1xufVxuY29uc3QgSVNPODYwMV9EQVRFX1JFR0VYID0gL14oXFxkezQsfSktPyhcXGRcXGQpLT8oXFxkXFxkKSg/OlQoXFxkXFxkKSg/Ojo/KFxcZFxcZCkoPzo6PyhcXGRcXGQpKD86XFwuKFxcZCspKT8pPyk/KFp8KFsrLV0pKFxcZFxcZCk6PyhcXGRcXGQpKT8pPyQvO1xuLy8gICAgMSAgICAgICAgMiAgICAgICAzICAgICAgICAgNCAgICAgICAgICA1ICAgICAgICAgIDYgICAgICAgICAgNyAgICAgICAgICA4ICA5ICAgICAxMCAgICAgIDExXG5jb25zdCBOQU1FRF9GT1JNQVRTID0ge307XG5jb25zdCBEQVRFX0ZPUk1BVFNfU1BMSVQgPSAvKCg/OlteQkVHSExNT1NXWVphYmNkaG1zd3l6J10rKXwoPzonKD86W14nXXwnJykqJyl8KD86R3sxLDV9fHl7MSw0fXxZezEsNH18TXsxLDV9fEx7MSw1fXx3ezEsMn18V3sxfXxkezEsMn18RXsxLDZ9fGN7MSw2fXxhezEsNX18YnsxLDV9fEJ7MSw1fXxoezEsMn18SHsxLDJ9fG17MSwyfXxzezEsMn18U3sxLDN9fHp7MSw0fXxaezEsNX18T3sxLDR9KSkoW1xcc1xcU10qKS87XG52YXIgWm9uZVdpZHRoO1xuKGZ1bmN0aW9uIChab25lV2lkdGgpIHtcbiAgWm9uZVdpZHRoW1pvbmVXaWR0aFtcIlNob3J0XCJdID0gMF0gPSBcIlNob3J0XCI7XG4gIFpvbmVXaWR0aFtab25lV2lkdGhbXCJTaG9ydEdNVFwiXSA9IDFdID0gXCJTaG9ydEdNVFwiO1xuICBab25lV2lkdGhbWm9uZVdpZHRoW1wiTG9uZ1wiXSA9IDJdID0gXCJMb25nXCI7XG4gIFpvbmVXaWR0aFtab25lV2lkdGhbXCJFeHRlbmRlZFwiXSA9IDNdID0gXCJFeHRlbmRlZFwiO1xufSkoWm9uZVdpZHRoIHx8IChab25lV2lkdGggPSB7fSkpO1xudmFyIERhdGVUeXBlO1xuKGZ1bmN0aW9uIChEYXRlVHlwZSkge1xuICBEYXRlVHlwZVtEYXRlVHlwZVtcIkZ1bGxZZWFyXCJdID0gMF0gPSBcIkZ1bGxZZWFyXCI7XG4gIERhdGVUeXBlW0RhdGVUeXBlW1wiTW9udGhcIl0gPSAxXSA9IFwiTW9udGhcIjtcbiAgRGF0ZVR5cGVbRGF0ZVR5cGVbXCJEYXRlXCJdID0gMl0gPSBcIkRhdGVcIjtcbiAgRGF0ZVR5cGVbRGF0ZVR5cGVbXCJIb3Vyc1wiXSA9IDNdID0gXCJIb3Vyc1wiO1xuICBEYXRlVHlwZVtEYXRlVHlwZVtcIk1pbnV0ZXNcIl0gPSA0XSA9IFwiTWludXRlc1wiO1xuICBEYXRlVHlwZVtEYXRlVHlwZVtcIlNlY29uZHNcIl0gPSA1XSA9IFwiU2Vjb25kc1wiO1xuICBEYXRlVHlwZVtEYXRlVHlwZVtcIkZyYWN0aW9uYWxTZWNvbmRzXCJdID0gNl0gPSBcIkZyYWN0aW9uYWxTZWNvbmRzXCI7XG4gIERhdGVUeXBlW0RhdGVUeXBlW1wiRGF5XCJdID0gN10gPSBcIkRheVwiO1xufSkoRGF0ZVR5cGUgfHwgKERhdGVUeXBlID0ge30pKTtcbnZhciBUcmFuc2xhdGlvblR5cGU7XG4oZnVuY3Rpb24gKFRyYW5zbGF0aW9uVHlwZSkge1xuICBUcmFuc2xhdGlvblR5cGVbVHJhbnNsYXRpb25UeXBlW1wiRGF5UGVyaW9kc1wiXSA9IDBdID0gXCJEYXlQZXJpb2RzXCI7XG4gIFRyYW5zbGF0aW9uVHlwZVtUcmFuc2xhdGlvblR5cGVbXCJEYXlzXCJdID0gMV0gPSBcIkRheXNcIjtcbiAgVHJhbnNsYXRpb25UeXBlW1RyYW5zbGF0aW9uVHlwZVtcIk1vbnRoc1wiXSA9IDJdID0gXCJNb250aHNcIjtcbiAgVHJhbnNsYXRpb25UeXBlW1RyYW5zbGF0aW9uVHlwZVtcIkVyYXNcIl0gPSAzXSA9IFwiRXJhc1wiO1xufSkoVHJhbnNsYXRpb25UeXBlIHx8IChUcmFuc2xhdGlvblR5cGUgPSB7fSkpO1xuLyoqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiBGb3JtYXRzIGEgZGF0ZSBhY2NvcmRpbmcgdG8gbG9jYWxlIHJ1bGVzLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSBUaGUgZGF0ZSB0byBmb3JtYXQsIGFzIGEgRGF0ZSwgb3IgYSBudW1iZXIgKG1pbGxpc2Vjb25kcyBzaW5jZSBVVEMgZXBvY2gpXG4gKiBvciBhbiBbSVNPIGRhdGUtdGltZSBzdHJpbmddKGh0dHBzOi8vd3d3LnczLm9yZy9UUi9OT1RFLWRhdGV0aW1lKS5cbiAqIEBwYXJhbSBmb3JtYXQgVGhlIGRhdGUtdGltZSBjb21wb25lbnRzIHRvIGluY2x1ZGUuIFNlZSBgRGF0ZVBpcGVgIGZvciBkZXRhaWxzLlxuICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlIGZvciB0aGUgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuXG4gKiBAcGFyYW0gdGltZXpvbmUgVGhlIHRpbWUgem9uZS4gQSB0aW1lIHpvbmUgb2Zmc2V0IGZyb20gR01UIChzdWNoIGFzIGAnKzA0MzAnYCksXG4gKiBvciBhIHN0YW5kYXJkIFVUQy9HTVQgb3IgY29udGluZW50YWwgVVMgdGltZSB6b25lIGFiYnJldmlhdGlvbi5cbiAqIElmIG5vdCBzcGVjaWZpZWQsIHVzZXMgaG9zdCBzeXN0ZW0gc2V0dGluZ3MuXG4gKlxuICogQHJldHVybnMgVGhlIGZvcm1hdHRlZCBkYXRlIHN0cmluZy5cbiAqXG4gKiBAc2VlIHtAbGluayBEYXRlUGlwZX1cbiAqIEBzZWUgW0ludGVybmF0aW9uYWxpemF0aW9uIChpMThuKSBHdWlkZV0oZ3VpZGUvaTE4bilcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmZ1bmN0aW9uIGZvcm1hdERhdGUodmFsdWUsIGZvcm1hdCwgbG9jYWxlLCB0aW1lem9uZSkge1xuICBsZXQgZGF0ZSA9IHRvRGF0ZSh2YWx1ZSk7XG4gIGNvbnN0IG5hbWVkRm9ybWF0ID0gZ2V0TmFtZWRGb3JtYXQobG9jYWxlLCBmb3JtYXQpO1xuICBmb3JtYXQgPSBuYW1lZEZvcm1hdCB8fCBmb3JtYXQ7XG4gIGxldCBwYXJ0cyA9IFtdO1xuICBsZXQgbWF0Y2g7XG4gIHdoaWxlIChmb3JtYXQpIHtcbiAgICBtYXRjaCA9IERBVEVfRk9STUFUU19TUExJVC5leGVjKGZvcm1hdCk7XG4gICAgaWYgKG1hdGNoKSB7XG4gICAgICBwYXJ0cyA9IHBhcnRzLmNvbmNhdChtYXRjaC5zbGljZSgxKSk7XG4gICAgICBjb25zdCBwYXJ0ID0gcGFydHMucG9wKCk7XG4gICAgICBpZiAoIXBhcnQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBmb3JtYXQgPSBwYXJ0O1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJ0cy5wdXNoKGZvcm1hdCk7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgbGV0IGRhdGVUaW1lem9uZU9mZnNldCA9IGRhdGUuZ2V0VGltZXpvbmVPZmZzZXQoKTtcbiAgaWYgKHRpbWV6b25lKSB7XG4gICAgZGF0ZVRpbWV6b25lT2Zmc2V0ID0gdGltZXpvbmVUb09mZnNldCh0aW1lem9uZSwgZGF0ZVRpbWV6b25lT2Zmc2V0KTtcbiAgICBkYXRlID0gY29udmVydFRpbWV6b25lVG9Mb2NhbChkYXRlLCB0aW1lem9uZSwgdHJ1ZSk7XG4gIH1cbiAgbGV0IHRleHQgPSAnJztcbiAgcGFydHMuZm9yRWFjaCh2YWx1ZSA9PiB7XG4gICAgY29uc3QgZGF0ZUZvcm1hdHRlciA9IGdldERhdGVGb3JtYXR0ZXIodmFsdWUpO1xuICAgIHRleHQgKz0gZGF0ZUZvcm1hdHRlciA/IGRhdGVGb3JtYXR0ZXIoZGF0ZSwgbG9jYWxlLCBkYXRlVGltZXpvbmVPZmZzZXQpIDogdmFsdWUgPT09IFwiJydcIiA/IFwiJ1wiIDogdmFsdWUucmVwbGFjZSgvKF4nfCckKS9nLCAnJykucmVwbGFjZSgvJycvZywgXCInXCIpO1xuICB9KTtcbiAgcmV0dXJuIHRleHQ7XG59XG4vKipcbiAqIENyZWF0ZSBhIG5ldyBEYXRlIG9iamVjdCB3aXRoIHRoZSBnaXZlbiBkYXRlIHZhbHVlLCBhbmQgdGhlIHRpbWUgc2V0IHRvIG1pZG5pZ2h0LlxuICpcbiAqIFdlIGNhbm5vdCB1c2UgYG5ldyBEYXRlKHllYXIsIG1vbnRoLCBkYXRlKWAgYmVjYXVzZSBpdCBtYXBzIHllYXJzIGJldHdlZW4gMCBhbmQgOTkgdG8gMTkwMC0xOTk5LlxuICogU2VlOiBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9hbmd1bGFyL2lzc3Vlcy80MDM3N1xuICpcbiAqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIHJldHVybnMgYSBEYXRlIG9iamVjdCB3aG9zZSB0aW1lIGlzIG1pZG5pZ2h0IGluIHRoZSBjdXJyZW50IGxvY2FsZSdzXG4gKiB0aW1lem9uZS4gSW4gdGhlIGZ1dHVyZSB3ZSBtaWdodCB3YW50IHRvIGNoYW5nZSB0aGlzIHRvIGJlIG1pZG5pZ2h0IGluIFVUQywgYnV0IHRoaXMgd291bGQgYmUgYVxuICogY29uc2lkZXJhYmxlIGJyZWFraW5nIGNoYW5nZS5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRGF0ZSh5ZWFyLCBtb250aCwgZGF0ZSkge1xuICAvLyBUaGUgYG5ld0RhdGVgIGlzIHNldCB0byBtaWRuaWdodCAoVVRDKSBvbiBKYW51YXJ5IDFzdCAxOTcwLlxuICAvLyAtIEluIFBTVCB0aGlzIHdpbGwgYmUgRGVjZW1iZXIgMzFzdCAxOTY5IGF0IDRwbS5cbiAgLy8gLSBJbiBHTVQgdGhpcyB3aWxsIGJlIEphbnVhcnkgMXN0IDE5NzAgYXQgMWFtLlxuICAvLyBOb3RlIHRoYXQgdGhleSBldmVuIGhhdmUgZGlmZmVyZW50IHllYXJzLCBkYXRlcyBhbmQgbW9udGhzIVxuICBjb25zdCBuZXdEYXRlID0gbmV3IERhdGUoMCk7XG4gIC8vIGBzZXRGdWxsWWVhcigpYCBhbGxvd3MgeWVhcnMgbGlrZSAwMDAxIHRvIGJlIHNldCBjb3JyZWN0bHkuIFRoaXMgZnVuY3Rpb24gZG9lcyBub3RcbiAgLy8gY2hhbmdlIHRoZSBpbnRlcm5hbCB0aW1lIG9mIHRoZSBkYXRlLlxuICAvLyBDb25zaWRlciBjYWxsaW5nIGBzZXRGdWxsWWVhcigyMDE5LCA4LCAyMClgIChTZXB0ZW1iZXIgMjAsIDIwMTkpLlxuICAvLyAtIEluIFBTVCB0aGlzIHdpbGwgbm93IGJlIFNlcHRlbWJlciAyMCwgMjAxOSBhdCA0cG1cbiAgLy8gLSBJbiBHTVQgdGhpcyB3aWxsIG5vdyBiZSBTZXB0ZW1iZXIgMjAsIDIwMTkgYXQgMWFtXG4gIG5ld0RhdGUuc2V0RnVsbFllYXIoeWVhciwgbW9udGgsIGRhdGUpO1xuICAvLyBXZSB3YW50IHRoZSBmaW5hbCBkYXRlIHRvIGJlIGF0IGxvY2FsIG1pZG5pZ2h0LCBzbyB3ZSByZXNldCB0aGUgdGltZS5cbiAgLy8gLSBJbiBQU1QgdGhpcyB3aWxsIG5vdyBiZSBTZXB0ZW1iZXIgMjAsIDIwMTkgYXQgMTJhbVxuICAvLyAtIEluIEdNVCB0aGlzIHdpbGwgbm93IGJlIFNlcHRlbWJlciAyMCwgMjAxOSBhdCAxMmFtXG4gIG5ld0RhdGUuc2V0SG91cnMoMCwgMCwgMCk7XG4gIHJldHVybiBuZXdEYXRlO1xufVxuZnVuY3Rpb24gZ2V0TmFtZWRGb3JtYXQobG9jYWxlLCBmb3JtYXQpIHtcbiAgY29uc3QgbG9jYWxlSWQgPSBnZXRMb2NhbGVJZChsb2NhbGUpO1xuICBOQU1FRF9GT1JNQVRTW2xvY2FsZUlkXSA/Pz0ge307XG4gIGlmIChOQU1FRF9GT1JNQVRTW2xvY2FsZUlkXVtmb3JtYXRdKSB7XG4gICAgcmV0dXJuIE5BTUVEX0ZPUk1BVFNbbG9jYWxlSWRdW2Zvcm1hdF07XG4gIH1cbiAgbGV0IGZvcm1hdFZhbHVlID0gJyc7XG4gIHN3aXRjaCAoZm9ybWF0KSB7XG4gICAgY2FzZSAnc2hvcnREYXRlJzpcbiAgICAgIGZvcm1hdFZhbHVlID0gZ2V0TG9jYWxlRGF0ZUZvcm1hdChsb2NhbGUsIEZvcm1hdFdpZHRoLlNob3J0KTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ21lZGl1bURhdGUnOlxuICAgICAgZm9ybWF0VmFsdWUgPSBnZXRMb2NhbGVEYXRlRm9ybWF0KGxvY2FsZSwgRm9ybWF0V2lkdGguTWVkaXVtKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2xvbmdEYXRlJzpcbiAgICAgIGZvcm1hdFZhbHVlID0gZ2V0TG9jYWxlRGF0ZUZvcm1hdChsb2NhbGUsIEZvcm1hdFdpZHRoLkxvbmcpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZnVsbERhdGUnOlxuICAgICAgZm9ybWF0VmFsdWUgPSBnZXRMb2NhbGVEYXRlRm9ybWF0KGxvY2FsZSwgRm9ybWF0V2lkdGguRnVsbCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdzaG9ydFRpbWUnOlxuICAgICAgZm9ybWF0VmFsdWUgPSBnZXRMb2NhbGVUaW1lRm9ybWF0KGxvY2FsZSwgRm9ybWF0V2lkdGguU2hvcnQpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnbWVkaXVtVGltZSc6XG4gICAgICBmb3JtYXRWYWx1ZSA9IGdldExvY2FsZVRpbWVGb3JtYXQobG9jYWxlLCBGb3JtYXRXaWR0aC5NZWRpdW0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnbG9uZ1RpbWUnOlxuICAgICAgZm9ybWF0VmFsdWUgPSBnZXRMb2NhbGVUaW1lRm9ybWF0KGxvY2FsZSwgRm9ybWF0V2lkdGguTG9uZyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdmdWxsVGltZSc6XG4gICAgICBmb3JtYXRWYWx1ZSA9IGdldExvY2FsZVRpbWVGb3JtYXQobG9jYWxlLCBGb3JtYXRXaWR0aC5GdWxsKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3Nob3J0JzpcbiAgICAgIGNvbnN0IHNob3J0VGltZSA9IGdldE5hbWVkRm9ybWF0KGxvY2FsZSwgJ3Nob3J0VGltZScpO1xuICAgICAgY29uc3Qgc2hvcnREYXRlID0gZ2V0TmFtZWRGb3JtYXQobG9jYWxlLCAnc2hvcnREYXRlJyk7XG4gICAgICBmb3JtYXRWYWx1ZSA9IGZvcm1hdERhdGVUaW1lKGdldExvY2FsZURhdGVUaW1lRm9ybWF0KGxvY2FsZSwgRm9ybWF0V2lkdGguU2hvcnQpLCBbc2hvcnRUaW1lLCBzaG9ydERhdGVdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ21lZGl1bSc6XG4gICAgICBjb25zdCBtZWRpdW1UaW1lID0gZ2V0TmFtZWRGb3JtYXQobG9jYWxlLCAnbWVkaXVtVGltZScpO1xuICAgICAgY29uc3QgbWVkaXVtRGF0ZSA9IGdldE5hbWVkRm9ybWF0KGxvY2FsZSwgJ21lZGl1bURhdGUnKTtcbiAgICAgIGZvcm1hdFZhbHVlID0gZm9ybWF0RGF0ZVRpbWUoZ2V0TG9jYWxlRGF0ZVRpbWVGb3JtYXQobG9jYWxlLCBGb3JtYXRXaWR0aC5NZWRpdW0pLCBbbWVkaXVtVGltZSwgbWVkaXVtRGF0ZV0pO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnbG9uZyc6XG4gICAgICBjb25zdCBsb25nVGltZSA9IGdldE5hbWVkRm9ybWF0KGxvY2FsZSwgJ2xvbmdUaW1lJyk7XG4gICAgICBjb25zdCBsb25nRGF0ZSA9IGdldE5hbWVkRm9ybWF0KGxvY2FsZSwgJ2xvbmdEYXRlJyk7XG4gICAgICBmb3JtYXRWYWx1ZSA9IGZvcm1hdERhdGVUaW1lKGdldExvY2FsZURhdGVUaW1lRm9ybWF0KGxvY2FsZSwgRm9ybWF0V2lkdGguTG9uZyksIFtsb25nVGltZSwgbG9uZ0RhdGVdKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Z1bGwnOlxuICAgICAgY29uc3QgZnVsbFRpbWUgPSBnZXROYW1lZEZvcm1hdChsb2NhbGUsICdmdWxsVGltZScpO1xuICAgICAgY29uc3QgZnVsbERhdGUgPSBnZXROYW1lZEZvcm1hdChsb2NhbGUsICdmdWxsRGF0ZScpO1xuICAgICAgZm9ybWF0VmFsdWUgPSBmb3JtYXREYXRlVGltZShnZXRMb2NhbGVEYXRlVGltZUZvcm1hdChsb2NhbGUsIEZvcm1hdFdpZHRoLkZ1bGwpLCBbZnVsbFRpbWUsIGZ1bGxEYXRlXSk7XG4gICAgICBicmVhaztcbiAgfVxuICBpZiAoZm9ybWF0VmFsdWUpIHtcbiAgICBOQU1FRF9GT1JNQVRTW2xvY2FsZUlkXVtmb3JtYXRdID0gZm9ybWF0VmFsdWU7XG4gIH1cbiAgcmV0dXJuIGZvcm1hdFZhbHVlO1xufVxuZnVuY3Rpb24gZm9ybWF0RGF0ZVRpbWUoc3RyLCBvcHRfdmFsdWVzKSB7XG4gIGlmIChvcHRfdmFsdWVzKSB7XG4gICAgc3RyID0gc3RyLnJlcGxhY2UoL1xceyhbXn1dKyl9L2csIGZ1bmN0aW9uIChtYXRjaCwga2V5KSB7XG4gICAgICByZXR1cm4gb3B0X3ZhbHVlcyAhPSBudWxsICYmIGtleSBpbiBvcHRfdmFsdWVzID8gb3B0X3ZhbHVlc1trZXldIDogbWF0Y2g7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHN0cjtcbn1cbmZ1bmN0aW9uIHBhZE51bWJlcihudW0sIGRpZ2l0cywgbWludXNTaWduID0gJy0nLCB0cmltLCBuZWdXcmFwKSB7XG4gIGxldCBuZWcgPSAnJztcbiAgaWYgKG51bSA8IDAgfHwgbmVnV3JhcCAmJiBudW0gPD0gMCkge1xuICAgIGlmIChuZWdXcmFwKSB7XG4gICAgICBudW0gPSAtbnVtICsgMTtcbiAgICB9IGVsc2Uge1xuICAgICAgbnVtID0gLW51bTtcbiAgICAgIG5lZyA9IG1pbnVzU2lnbjtcbiAgICB9XG4gIH1cbiAgbGV0IHN0ck51bSA9IFN0cmluZyhudW0pO1xuICB3aGlsZSAoc3RyTnVtLmxlbmd0aCA8IGRpZ2l0cykge1xuICAgIHN0ck51bSA9ICcwJyArIHN0ck51bTtcbiAgfVxuICBpZiAodHJpbSkge1xuICAgIHN0ck51bSA9IHN0ck51bS5zbGljZShzdHJOdW0ubGVuZ3RoIC0gZGlnaXRzKTtcbiAgfVxuICByZXR1cm4gbmVnICsgc3RyTnVtO1xufVxuZnVuY3Rpb24gZm9ybWF0RnJhY3Rpb25hbFNlY29uZHMobWlsbGlzZWNvbmRzLCBkaWdpdHMpIHtcbiAgY29uc3Qgc3RyTXMgPSBwYWROdW1iZXIobWlsbGlzZWNvbmRzLCAzKTtcbiAgcmV0dXJuIHN0ck1zLnN1YnN0cmluZygwLCBkaWdpdHMpO1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgZGF0ZSBmb3JtYXR0ZXIgdGhhdCB0cmFuc2Zvcm1zIGEgZGF0ZSBpbnRvIGl0cyBsb2NhbGUgZGlnaXQgcmVwcmVzZW50YXRpb25cbiAqL1xuZnVuY3Rpb24gZGF0ZUdldHRlcihuYW1lLCBzaXplLCBvZmZzZXQgPSAwLCB0cmltID0gZmFsc2UsIG5lZ1dyYXAgPSBmYWxzZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKGRhdGUsIGxvY2FsZSkge1xuICAgIGxldCBwYXJ0ID0gZ2V0RGF0ZVBhcnQobmFtZSwgZGF0ZSk7XG4gICAgaWYgKG9mZnNldCA+IDAgfHwgcGFydCA+IC1vZmZzZXQpIHtcbiAgICAgIHBhcnQgKz0gb2Zmc2V0O1xuICAgIH1cbiAgICBpZiAobmFtZSA9PT0gRGF0ZVR5cGUuSG91cnMpIHtcbiAgICAgIGlmIChwYXJ0ID09PSAwICYmIG9mZnNldCA9PT0gLTEyKSB7XG4gICAgICAgIHBhcnQgPSAxMjtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKG5hbWUgPT09IERhdGVUeXBlLkZyYWN0aW9uYWxTZWNvbmRzKSB7XG4gICAgICByZXR1cm4gZm9ybWF0RnJhY3Rpb25hbFNlY29uZHMocGFydCwgc2l6ZSk7XG4gICAgfVxuICAgIGNvbnN0IGxvY2FsZU1pbnVzID0gZ2V0TG9jYWxlTnVtYmVyU3ltYm9sKGxvY2FsZSwgTnVtYmVyU3ltYm9sLk1pbnVzU2lnbik7XG4gICAgcmV0dXJuIHBhZE51bWJlcihwYXJ0LCBzaXplLCBsb2NhbGVNaW51cywgdHJpbSwgbmVnV3JhcCk7XG4gIH07XG59XG5mdW5jdGlvbiBnZXREYXRlUGFydChwYXJ0LCBkYXRlKSB7XG4gIHN3aXRjaCAocGFydCkge1xuICAgIGNhc2UgRGF0ZVR5cGUuRnVsbFllYXI6XG4gICAgICByZXR1cm4gZGF0ZS5nZXRGdWxsWWVhcigpO1xuICAgIGNhc2UgRGF0ZVR5cGUuTW9udGg6XG4gICAgICByZXR1cm4gZGF0ZS5nZXRNb250aCgpO1xuICAgIGNhc2UgRGF0ZVR5cGUuRGF0ZTpcbiAgICAgIHJldHVybiBkYXRlLmdldERhdGUoKTtcbiAgICBjYXNlIERhdGVUeXBlLkhvdXJzOlxuICAgICAgcmV0dXJuIGRhdGUuZ2V0SG91cnMoKTtcbiAgICBjYXNlIERhdGVUeXBlLk1pbnV0ZXM6XG4gICAgICByZXR1cm4gZGF0ZS5nZXRNaW51dGVzKCk7XG4gICAgY2FzZSBEYXRlVHlwZS5TZWNvbmRzOlxuICAgICAgcmV0dXJuIGRhdGUuZ2V0U2Vjb25kcygpO1xuICAgIGNhc2UgRGF0ZVR5cGUuRnJhY3Rpb25hbFNlY29uZHM6XG4gICAgICByZXR1cm4gZGF0ZS5nZXRNaWxsaXNlY29uZHMoKTtcbiAgICBjYXNlIERhdGVUeXBlLkRheTpcbiAgICAgIHJldHVybiBkYXRlLmdldERheSgpO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gRGF0ZVR5cGUgdmFsdWUgXCIke3BhcnR9XCIuYCk7XG4gIH1cbn1cbi8qKlxuICogUmV0dXJucyBhIGRhdGUgZm9ybWF0dGVyIHRoYXQgdHJhbnNmb3JtcyBhIGRhdGUgaW50byBpdHMgbG9jYWxlIHN0cmluZyByZXByZXNlbnRhdGlvblxuICovXG5mdW5jdGlvbiBkYXRlU3RyR2V0dGVyKG5hbWUsIHdpZHRoLCBmb3JtID0gRm9ybVN0eWxlLkZvcm1hdCwgZXh0ZW5kZWQgPSBmYWxzZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKGRhdGUsIGxvY2FsZSkge1xuICAgIHJldHVybiBnZXREYXRlVHJhbnNsYXRpb24oZGF0ZSwgbG9jYWxlLCBuYW1lLCB3aWR0aCwgZm9ybSwgZXh0ZW5kZWQpO1xuICB9O1xufVxuLyoqXG4gKiBSZXR1cm5zIHRoZSBsb2NhbGUgdHJhbnNsYXRpb24gb2YgYSBkYXRlIGZvciBhIGdpdmVuIGZvcm0sIHR5cGUgYW5kIHdpZHRoXG4gKi9cbmZ1bmN0aW9uIGdldERhdGVUcmFuc2xhdGlvbihkYXRlLCBsb2NhbGUsIG5hbWUsIHdpZHRoLCBmb3JtLCBleHRlbmRlZCkge1xuICBzd2l0Y2ggKG5hbWUpIHtcbiAgICBjYXNlIFRyYW5zbGF0aW9uVHlwZS5Nb250aHM6XG4gICAgICByZXR1cm4gZ2V0TG9jYWxlTW9udGhOYW1lcyhsb2NhbGUsIGZvcm0sIHdpZHRoKVtkYXRlLmdldE1vbnRoKCldO1xuICAgIGNhc2UgVHJhbnNsYXRpb25UeXBlLkRheXM6XG4gICAgICByZXR1cm4gZ2V0TG9jYWxlRGF5TmFtZXMobG9jYWxlLCBmb3JtLCB3aWR0aClbZGF0ZS5nZXREYXkoKV07XG4gICAgY2FzZSBUcmFuc2xhdGlvblR5cGUuRGF5UGVyaW9kczpcbiAgICAgIGNvbnN0IGN1cnJlbnRIb3VycyA9IGRhdGUuZ2V0SG91cnMoKTtcbiAgICAgIGNvbnN0IGN1cnJlbnRNaW51dGVzID0gZGF0ZS5nZXRNaW51dGVzKCk7XG4gICAgICBpZiAoZXh0ZW5kZWQpIHtcbiAgICAgICAgY29uc3QgcnVsZXMgPSBnZXRMb2NhbGVFeHRyYURheVBlcmlvZFJ1bGVzKGxvY2FsZSk7XG4gICAgICAgIGNvbnN0IGRheVBlcmlvZHMgPSBnZXRMb2NhbGVFeHRyYURheVBlcmlvZHMobG9jYWxlLCBmb3JtLCB3aWR0aCk7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gcnVsZXMuZmluZEluZGV4KHJ1bGUgPT4ge1xuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJ1bGUpKSB7XG4gICAgICAgICAgICAvLyBtb3JuaW5nLCBhZnRlcm5vb24sIGV2ZW5pbmcsIG5pZ2h0XG4gICAgICAgICAgICBjb25zdCBbZnJvbSwgdG9dID0gcnVsZTtcbiAgICAgICAgICAgIGNvbnN0IGFmdGVyRnJvbSA9IGN1cnJlbnRIb3VycyA+PSBmcm9tLmhvdXJzICYmIGN1cnJlbnRNaW51dGVzID49IGZyb20ubWludXRlcztcbiAgICAgICAgICAgIGNvbnN0IGJlZm9yZVRvID0gY3VycmVudEhvdXJzIDwgdG8uaG91cnMgfHwgY3VycmVudEhvdXJzID09PSB0by5ob3VycyAmJiBjdXJyZW50TWludXRlcyA8IHRvLm1pbnV0ZXM7XG4gICAgICAgICAgICAvLyBXZSBtdXN0IGFjY291bnQgZm9yIG5vcm1hbCBydWxlcyB0aGF0IHNwYW4gYSBwZXJpb2QgZHVyaW5nIHRoZSBkYXkgKGUuZy4gNmFtLTlhbSlcbiAgICAgICAgICAgIC8vIHdoZXJlIGBmcm9tYCBpcyBsZXNzIChlYXJsaWVyKSB0aGFuIGB0b2AuIEJ1dCBhbHNvIHJ1bGVzIHRoYXQgc3BhbiBtaWRuaWdodCAoZS5nLlxuICAgICAgICAgICAgLy8gMTBwbSAtIDVhbSkgd2hlcmUgYGZyb21gIGlzIGdyZWF0ZXIgKGxhdGVyISkgdGhhbiBgdG9gLlxuICAgICAgICAgICAgLy9cbiAgICAgICAgICAgIC8vIEluIHRoZSBmaXJzdCBjYXNlIHRoZSBjdXJyZW50IHRpbWUgbXVzdCBiZSBCT1RIIGFmdGVyIGBmcm9tYCBBTkQgYmVmb3JlIGB0b2BcbiAgICAgICAgICAgIC8vIChlLmcuIDhhbSBpcyBhZnRlciA2YW0gQU5EIGJlZm9yZSAxMGFtKS5cbiAgICAgICAgICAgIC8vXG4gICAgICAgICAgICAvLyBJbiB0aGUgc2Vjb25kIGNhc2UgdGhlIGN1cnJlbnQgdGltZSBtdXN0IGJlIEVJVEhFUiBhZnRlciBgZnJvbWAgT1IgYmVmb3JlIGB0b2BcbiAgICAgICAgICAgIC8vIChlLmcuIDRhbSBpcyBiZWZvcmUgNWFtIGJ1dCBub3QgYWZ0ZXIgMTBwbTsgYW5kIDExcG0gaXMgbm90IGJlZm9yZSA1YW0gYnV0IGl0IGlzXG4gICAgICAgICAgICAvLyBhZnRlciAxMHBtKS5cbiAgICAgICAgICAgIGlmIChmcm9tLmhvdXJzIDwgdG8uaG91cnMpIHtcbiAgICAgICAgICAgICAgaWYgKGFmdGVyRnJvbSAmJiBiZWZvcmVUbykge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFmdGVyRnJvbSB8fCBiZWZvcmVUbykge1xuICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gbm9vbiBvciBtaWRuaWdodFxuICAgICAgICAgICAgaWYgKHJ1bGUuaG91cnMgPT09IGN1cnJlbnRIb3VycyAmJiBydWxlLm1pbnV0ZXMgPT09IGN1cnJlbnRNaW51dGVzKSB7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgcmV0dXJuIGRheVBlcmlvZHNbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBpZiBubyBydWxlcyBmb3IgdGhlIGRheSBwZXJpb2RzLCB3ZSB1c2UgYW0vcG0gYnkgZGVmYXVsdFxuICAgICAgcmV0dXJuIGdldExvY2FsZURheVBlcmlvZHMobG9jYWxlLCBmb3JtLCB3aWR0aClbY3VycmVudEhvdXJzIDwgMTIgPyAwIDogMV07XG4gICAgY2FzZSBUcmFuc2xhdGlvblR5cGUuRXJhczpcbiAgICAgIHJldHVybiBnZXRMb2NhbGVFcmFOYW1lcyhsb2NhbGUsIHdpZHRoKVtkYXRlLmdldEZ1bGxZZWFyKCkgPD0gMCA/IDAgOiAxXTtcbiAgICBkZWZhdWx0OlxuICAgICAgLy8gVGhpcyBkZWZhdWx0IGNhc2UgaXMgbm90IG5lZWRlZCBieSBUeXBlU2NyaXB0IGNvbXBpbGVyLCBhcyB0aGUgc3dpdGNoIGlzIGV4aGF1c3RpdmUuXG4gICAgICAvLyBIb3dldmVyIENsb3N1cmUgQ29tcGlsZXIgZG9lcyBub3QgdW5kZXJzdGFuZCB0aGF0IGFuZCByZXBvcnRzIGFuIGVycm9yIGluIHR5cGVkIG1vZGUuXG4gICAgICAvLyBUaGUgYHRocm93IG5ldyBFcnJvcmAgYmVsb3cgd29ya3MgYXJvdW5kIHRoZSBwcm9ibGVtLCBhbmQgdGhlIHVuZXhwZWN0ZWQ6IG5ldmVyIHZhcmlhYmxlXG4gICAgICAvLyBtYWtlcyBzdXJlIHRzYyBzdGlsbCBjaGVja3MgdGhpcyBjb2RlIGlzIHVucmVhY2hhYmxlLlxuICAgICAgY29uc3QgdW5leHBlY3RlZCA9IG5hbWU7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYHVuZXhwZWN0ZWQgdHJhbnNsYXRpb24gdHlwZSAke3VuZXhwZWN0ZWR9YCk7XG4gIH1cbn1cbi8qKlxuICogUmV0dXJucyBhIGRhdGUgZm9ybWF0dGVyIHRoYXQgdHJhbnNmb3JtcyBhIGRhdGUgYW5kIGFuIG9mZnNldCBpbnRvIGEgdGltZXpvbmUgd2l0aCBJU084NjAxIG9yXG4gKiBHTVQgZm9ybWF0IGRlcGVuZGluZyBvbiB0aGUgd2lkdGggKGVnOiBzaG9ydCA9ICswNDMwLCBzaG9ydDpHTVQgPSBHTVQrNCwgbG9uZyA9IEdNVCswNDozMCxcbiAqIGV4dGVuZGVkID0gKzA0OjMwKVxuICovXG5mdW5jdGlvbiB0aW1lWm9uZUdldHRlcih3aWR0aCkge1xuICByZXR1cm4gZnVuY3Rpb24gKGRhdGUsIGxvY2FsZSwgb2Zmc2V0KSB7XG4gICAgY29uc3Qgem9uZSA9IC0xICogb2Zmc2V0O1xuICAgIGNvbnN0IG1pbnVzU2lnbiA9IGdldExvY2FsZU51bWJlclN5bWJvbChsb2NhbGUsIE51bWJlclN5bWJvbC5NaW51c1NpZ24pO1xuICAgIGNvbnN0IGhvdXJzID0gem9uZSA+IDAgPyBNYXRoLmZsb29yKHpvbmUgLyA2MCkgOiBNYXRoLmNlaWwoem9uZSAvIDYwKTtcbiAgICBzd2l0Y2ggKHdpZHRoKSB7XG4gICAgICBjYXNlIFpvbmVXaWR0aC5TaG9ydDpcbiAgICAgICAgcmV0dXJuICh6b25lID49IDAgPyAnKycgOiAnJykgKyBwYWROdW1iZXIoaG91cnMsIDIsIG1pbnVzU2lnbikgKyBwYWROdW1iZXIoTWF0aC5hYnMoem9uZSAlIDYwKSwgMiwgbWludXNTaWduKTtcbiAgICAgIGNhc2UgWm9uZVdpZHRoLlNob3J0R01UOlxuICAgICAgICByZXR1cm4gJ0dNVCcgKyAoem9uZSA+PSAwID8gJysnIDogJycpICsgcGFkTnVtYmVyKGhvdXJzLCAxLCBtaW51c1NpZ24pO1xuICAgICAgY2FzZSBab25lV2lkdGguTG9uZzpcbiAgICAgICAgcmV0dXJuICdHTVQnICsgKHpvbmUgPj0gMCA/ICcrJyA6ICcnKSArIHBhZE51bWJlcihob3VycywgMiwgbWludXNTaWduKSArICc6JyArIHBhZE51bWJlcihNYXRoLmFicyh6b25lICUgNjApLCAyLCBtaW51c1NpZ24pO1xuICAgICAgY2FzZSBab25lV2lkdGguRXh0ZW5kZWQ6XG4gICAgICAgIGlmIChvZmZzZXQgPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gJ1onO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiAoem9uZSA+PSAwID8gJysnIDogJycpICsgcGFkTnVtYmVyKGhvdXJzLCAyLCBtaW51c1NpZ24pICsgJzonICsgcGFkTnVtYmVyKE1hdGguYWJzKHpvbmUgJSA2MCksIDIsIG1pbnVzU2lnbik7XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB6b25lIHdpZHRoIFwiJHt3aWR0aH1cImApO1xuICAgIH1cbiAgfTtcbn1cbmNvbnN0IEpBTlVBUlkgPSAwO1xuY29uc3QgVEhVUlNEQVkgPSA0O1xuZnVuY3Rpb24gZ2V0Rmlyc3RUaHVyc2RheU9mWWVhcih5ZWFyKSB7XG4gIGNvbnN0IGZpcnN0RGF5T2ZZZWFyID0gY3JlYXRlRGF0ZSh5ZWFyLCBKQU5VQVJZLCAxKS5nZXREYXkoKTtcbiAgcmV0dXJuIGNyZWF0ZURhdGUoeWVhciwgMCwgMSArIChmaXJzdERheU9mWWVhciA8PSBUSFVSU0RBWSA/IFRIVVJTREFZIDogVEhVUlNEQVkgKyA3KSAtIGZpcnN0RGF5T2ZZZWFyKTtcbn1cbi8qKlxuICogIElTTyBXZWVrIHN0YXJ0cyBvbiBkYXkgMSAoTW9uZGF5KSBhbmQgZW5kcyB3aXRoIGRheSAwIChTdW5kYXkpXG4gKi9cbmZ1bmN0aW9uIGdldFRodXJzZGF5VGhpc0lzb1dlZWsoZGF0ZXRpbWUpIHtcbiAgLy8gZ2V0RGF5IHJldHVybnMgMC02IHJhbmdlIHdpdGggc3VuZGF5IGFzIDAuXG4gIGNvbnN0IGN1cnJlbnREYXkgPSBkYXRldGltZS5nZXREYXkoKTtcbiAgLy8gT24gYSBTdW5kYXksIHJlYWQgdGhlIHByZXZpb3VzIFRodXJzZGF5IHNpbmNlIElTTyB3ZWVrcyBzdGFydCBvbiBNb25kYXkuXG4gIGNvbnN0IGRlbHRhVG9UaHVyc2RheSA9IGN1cnJlbnREYXkgPT09IDAgPyAtMyA6IFRIVVJTREFZIC0gY3VycmVudERheTtcbiAgcmV0dXJuIGNyZWF0ZURhdGUoZGF0ZXRpbWUuZ2V0RnVsbFllYXIoKSwgZGF0ZXRpbWUuZ2V0TW9udGgoKSwgZGF0ZXRpbWUuZ2V0RGF0ZSgpICsgZGVsdGFUb1RodXJzZGF5KTtcbn1cbmZ1bmN0aW9uIHdlZWtHZXR0ZXIoc2l6ZSwgbW9udGhCYXNlZCA9IGZhbHNlKSB7XG4gIHJldHVybiBmdW5jdGlvbiAoZGF0ZSwgbG9jYWxlKSB7XG4gICAgbGV0IHJlc3VsdDtcbiAgICBpZiAobW9udGhCYXNlZCkge1xuICAgICAgY29uc3QgbmJEYXlzQmVmb3JlMXN0RGF5T2ZNb250aCA9IG5ldyBEYXRlKGRhdGUuZ2V0RnVsbFllYXIoKSwgZGF0ZS5nZXRNb250aCgpLCAxKS5nZXREYXkoKSAtIDE7XG4gICAgICBjb25zdCB0b2RheSA9IGRhdGUuZ2V0RGF0ZSgpO1xuICAgICAgcmVzdWx0ID0gMSArIE1hdGguZmxvb3IoKHRvZGF5ICsgbmJEYXlzQmVmb3JlMXN0RGF5T2ZNb250aCkgLyA3KTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgdGhpc1RodXJzID0gZ2V0VGh1cnNkYXlUaGlzSXNvV2VlayhkYXRlKTtcbiAgICAgIC8vIFNvbWUgZGF5cyBvZiBhIHllYXIgYXJlIHBhcnQgb2YgbmV4dCB5ZWFyIGFjY29yZGluZyB0byBJU08gODYwMS5cbiAgICAgIC8vIENvbXB1dGUgdGhlIGZpcnN0VGh1cnMgZnJvbSB0aGUgeWVhciBvZiB0aGlzIHdlZWsncyBUaHVyc2RheVxuICAgICAgY29uc3QgZmlyc3RUaHVycyA9IGdldEZpcnN0VGh1cnNkYXlPZlllYXIodGhpc1RodXJzLmdldEZ1bGxZZWFyKCkpO1xuICAgICAgY29uc3QgZGlmZiA9IHRoaXNUaHVycy5nZXRUaW1lKCkgLSBmaXJzdFRodXJzLmdldFRpbWUoKTtcbiAgICAgIHJlc3VsdCA9IDEgKyBNYXRoLnJvdW5kKGRpZmYgLyA2LjA0OGU4KTsgLy8gNi4wNDhlOCBtcyBwZXIgd2Vla1xuICAgIH1cbiAgICByZXR1cm4gcGFkTnVtYmVyKHJlc3VsdCwgc2l6ZSwgZ2V0TG9jYWxlTnVtYmVyU3ltYm9sKGxvY2FsZSwgTnVtYmVyU3ltYm9sLk1pbnVzU2lnbikpO1xuICB9O1xufVxuLyoqXG4gKiBSZXR1cm5zIGEgZGF0ZSBmb3JtYXR0ZXIgdGhhdCBwcm92aWRlcyB0aGUgd2Vlay1udW1iZXJpbmcgeWVhciBmb3IgdGhlIGlucHV0IGRhdGUuXG4gKi9cbmZ1bmN0aW9uIHdlZWtOdW1iZXJpbmdZZWFyR2V0dGVyKHNpemUsIHRyaW0gPSBmYWxzZSkge1xuICByZXR1cm4gZnVuY3Rpb24gKGRhdGUsIGxvY2FsZSkge1xuICAgIGNvbnN0IHRoaXNUaHVycyA9IGdldFRodXJzZGF5VGhpc0lzb1dlZWsoZGF0ZSk7XG4gICAgY29uc3Qgd2Vla051bWJlcmluZ1llYXIgPSB0aGlzVGh1cnMuZ2V0RnVsbFllYXIoKTtcbiAgICByZXR1cm4gcGFkTnVtYmVyKHdlZWtOdW1iZXJpbmdZZWFyLCBzaXplLCBnZXRMb2NhbGVOdW1iZXJTeW1ib2wobG9jYWxlLCBOdW1iZXJTeW1ib2wuTWludXNTaWduKSwgdHJpbSk7XG4gIH07XG59XG5jb25zdCBEQVRFX0ZPUk1BVFMgPSB7fTtcbi8vIEJhc2VkIG9uIENMRFIgZm9ybWF0czpcbi8vIFNlZSBjb21wbGV0ZSBsaXN0OiBodHRwOi8vd3d3LnVuaWNvZGUub3JnL3JlcG9ydHMvdHIzNS90cjM1LWRhdGVzLmh0bWwjRGF0ZV9GaWVsZF9TeW1ib2xfVGFibGVcbi8vIFNlZSBhbHNvIGV4cGxhbmF0aW9uczogaHR0cDovL2NsZHIudW5pY29kZS5vcmcvdHJhbnNsYXRpb24vZGF0ZS10aW1lXG4vLyBUT0RPKG9jb21iZSk6IHN1cHBvcnQgYWxsIG1pc3NpbmcgY2xkciBmb3JtYXRzOiBVLCBRLCBELCBGLCBlLCBqLCBKLCBDLCBBLCB2LCBWLCBYLCB4XG5mdW5jdGlvbiBnZXREYXRlRm9ybWF0dGVyKGZvcm1hdCkge1xuICBpZiAoREFURV9GT1JNQVRTW2Zvcm1hdF0pIHtcbiAgICByZXR1cm4gREFURV9GT1JNQVRTW2Zvcm1hdF07XG4gIH1cbiAgbGV0IGZvcm1hdHRlcjtcbiAgc3dpdGNoIChmb3JtYXQpIHtcbiAgICAvLyBFcmEgbmFtZSAoQUQvQkMpXG4gICAgY2FzZSAnRyc6XG4gICAgY2FzZSAnR0cnOlxuICAgIGNhc2UgJ0dHRyc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5FcmFzLCBUcmFuc2xhdGlvbldpZHRoLkFiYnJldmlhdGVkKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0dHR0cnOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRXJhcywgVHJhbnNsYXRpb25XaWR0aC5XaWRlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0dHR0dHJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkVyYXMsIFRyYW5zbGF0aW9uV2lkdGguTmFycm93KTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIDEgZGlnaXQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHllYXIsIGUuZy4gKEFEIDEgPT4gMSwgQUQgMTk5ID0+IDE5OSlcbiAgICBjYXNlICd5JzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRnVsbFllYXIsIDEsIDAsIGZhbHNlLCB0cnVlKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIDIgZGlnaXQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHllYXIsIHBhZGRlZCAoMDAtOTkpLiAoZS5nLiBBRCAyMDAxID0+IDAxLCBBRCAyMDEwID0+IDEwKVxuICAgIGNhc2UgJ3l5JzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRnVsbFllYXIsIDIsIDAsIHRydWUsIHRydWUpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gMyBkaWdpdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgeWVhciwgcGFkZGVkICgwMDAtOTk5KS4gKGUuZy4gQUQgMjAwMSA9PiAwMSwgQUQgMjAxMCA9PiAxMClcbiAgICBjYXNlICd5eXknOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZUdldHRlcihEYXRlVHlwZS5GdWxsWWVhciwgMywgMCwgZmFsc2UsIHRydWUpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gNCBkaWdpdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgeWVhciAoZS5nLiBBRCAxID0+IDAwMDEsIEFEIDIwMTAgPT4gMjAxMClcbiAgICBjYXNlICd5eXl5JzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRnVsbFllYXIsIDQsIDAsIGZhbHNlLCB0cnVlKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIDEgZGlnaXQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHdlZWstbnVtYmVyaW5nIHllYXIsIGUuZy4gKEFEIDEgPT4gMSwgQUQgMTk5ID0+IDE5OSlcbiAgICBjYXNlICdZJzpcbiAgICAgIGZvcm1hdHRlciA9IHdlZWtOdW1iZXJpbmdZZWFyR2V0dGVyKDEpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gMiBkaWdpdCByZXByZXNlbnRhdGlvbiBvZiB0aGUgd2Vlay1udW1iZXJpbmcgeWVhciwgcGFkZGVkICgwMC05OSkuIChlLmcuIEFEIDIwMDEgPT4gMDEsIEFEXG4gICAgLy8gMjAxMCA9PiAxMClcbiAgICBjYXNlICdZWSc6XG4gICAgICBmb3JtYXR0ZXIgPSB3ZWVrTnVtYmVyaW5nWWVhckdldHRlcigyLCB0cnVlKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIDMgZGlnaXQgcmVwcmVzZW50YXRpb24gb2YgdGhlIHdlZWstbnVtYmVyaW5nIHllYXIsIHBhZGRlZCAoMDAwLTk5OSkuIChlLmcuIEFEIDEgPT4gMDAxLCBBRFxuICAgIC8vIDIwMTAgPT4gMjAxMClcbiAgICBjYXNlICdZWVknOlxuICAgICAgZm9ybWF0dGVyID0gd2Vla051bWJlcmluZ1llYXJHZXR0ZXIoMyk7XG4gICAgICBicmVhaztcbiAgICAvLyA0IGRpZ2l0IHJlcHJlc2VudGF0aW9uIG9mIHRoZSB3ZWVrLW51bWJlcmluZyB5ZWFyIChlLmcuIEFEIDEgPT4gMDAwMSwgQUQgMjAxMCA9PiAyMDEwKVxuICAgIGNhc2UgJ1lZWVknOlxuICAgICAgZm9ybWF0dGVyID0gd2Vla051bWJlcmluZ1llYXJHZXR0ZXIoNCk7XG4gICAgICBicmVhaztcbiAgICAvLyBNb250aCBvZiB0aGUgeWVhciAoMS0xMiksIG51bWVyaWNcbiAgICBjYXNlICdNJzpcbiAgICBjYXNlICdMJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuTW9udGgsIDEsIDEpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnTU0nOlxuICAgIGNhc2UgJ0xMJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuTW9udGgsIDIsIDEpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gTW9udGggb2YgdGhlIHllYXIgKEphbnVhcnksIC4uLiksIHN0cmluZywgZm9ybWF0XG4gICAgY2FzZSAnTU1NJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLk1vbnRocywgVHJhbnNsYXRpb25XaWR0aC5BYmJyZXZpYXRlZCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdNTU1NJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLk1vbnRocywgVHJhbnNsYXRpb25XaWR0aC5XaWRlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ01NTU1NJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLk1vbnRocywgVHJhbnNsYXRpb25XaWR0aC5OYXJyb3cpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gTW9udGggb2YgdGhlIHllYXIgKEphbnVhcnksIC4uLiksIHN0cmluZywgc3RhbmRhbG9uZVxuICAgIGNhc2UgJ0xMTCc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5Nb250aHMsIFRyYW5zbGF0aW9uV2lkdGguQWJicmV2aWF0ZWQsIEZvcm1TdHlsZS5TdGFuZGFsb25lKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0xMTEwnOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuTW9udGhzLCBUcmFuc2xhdGlvbldpZHRoLldpZGUsIEZvcm1TdHlsZS5TdGFuZGFsb25lKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0xMTExMJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLk1vbnRocywgVHJhbnNsYXRpb25XaWR0aC5OYXJyb3csIEZvcm1TdHlsZS5TdGFuZGFsb25lKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIFdlZWsgb2YgdGhlIHllYXIgKDEsIC4uLiA1MilcbiAgICBjYXNlICd3JzpcbiAgICAgIGZvcm1hdHRlciA9IHdlZWtHZXR0ZXIoMSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd3dyc6XG4gICAgICBmb3JtYXR0ZXIgPSB3ZWVrR2V0dGVyKDIpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gV2VlayBvZiB0aGUgbW9udGggKDEsIC4uLilcbiAgICBjYXNlICdXJzpcbiAgICAgIGZvcm1hdHRlciA9IHdlZWtHZXR0ZXIoMSwgdHJ1ZSk7XG4gICAgICBicmVhaztcbiAgICAvLyBEYXkgb2YgdGhlIG1vbnRoICgxLTMxKVxuICAgIGNhc2UgJ2QnOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZUdldHRlcihEYXRlVHlwZS5EYXRlLCAxKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2RkJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRGF0ZSwgMik7XG4gICAgICBicmVhaztcbiAgICAvLyBEYXkgb2YgdGhlIFdlZWsgU3RhbmRBbG9uZSAoMSwgMSwgTW9uLCBNb25kYXksIE0sIE1vKVxuICAgIGNhc2UgJ2MnOlxuICAgIGNhc2UgJ2NjJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRGF5LCAxKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2NjYyc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlzLCBUcmFuc2xhdGlvbldpZHRoLkFiYnJldmlhdGVkLCBGb3JtU3R5bGUuU3RhbmRhbG9uZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdjY2NjJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheXMsIFRyYW5zbGF0aW9uV2lkdGguV2lkZSwgRm9ybVN0eWxlLlN0YW5kYWxvbmUpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnY2NjY2MnOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRGF5cywgVHJhbnNsYXRpb25XaWR0aC5OYXJyb3csIEZvcm1TdHlsZS5TdGFuZGFsb25lKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2NjY2NjYyc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlzLCBUcmFuc2xhdGlvbldpZHRoLlNob3J0LCBGb3JtU3R5bGUuU3RhbmRhbG9uZSk7XG4gICAgICBicmVhaztcbiAgICAvLyBEYXkgb2YgdGhlIFdlZWtcbiAgICBjYXNlICdFJzpcbiAgICBjYXNlICdFRSc6XG4gICAgY2FzZSAnRUVFJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheXMsIFRyYW5zbGF0aW9uV2lkdGguQWJicmV2aWF0ZWQpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnRUVFRSc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlzLCBUcmFuc2xhdGlvbldpZHRoLldpZGUpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnRUVFRUUnOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRGF5cywgVHJhbnNsYXRpb25XaWR0aC5OYXJyb3cpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnRUVFRUVFJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheXMsIFRyYW5zbGF0aW9uV2lkdGguU2hvcnQpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gR2VuZXJpYyBwZXJpb2Qgb2YgdGhlIGRheSAoYW0tcG0pXG4gICAgY2FzZSAnYSc6XG4gICAgY2FzZSAnYWEnOlxuICAgIGNhc2UgJ2FhYSc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlQZXJpb2RzLCBUcmFuc2xhdGlvbldpZHRoLkFiYnJldmlhdGVkKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2FhYWEnOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRGF5UGVyaW9kcywgVHJhbnNsYXRpb25XaWR0aC5XaWRlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2FhYWFhJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheVBlcmlvZHMsIFRyYW5zbGF0aW9uV2lkdGguTmFycm93KTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIEV4dGVuZGVkIHBlcmlvZCBvZiB0aGUgZGF5IChtaWRuaWdodCwgYXQgbmlnaHQsIC4uLiksIHN0YW5kYWxvbmVcbiAgICBjYXNlICdiJzpcbiAgICBjYXNlICdiYic6XG4gICAgY2FzZSAnYmJiJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheVBlcmlvZHMsIFRyYW5zbGF0aW9uV2lkdGguQWJicmV2aWF0ZWQsIEZvcm1TdHlsZS5TdGFuZGFsb25lLCB0cnVlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2JiYmInOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRGF5UGVyaW9kcywgVHJhbnNsYXRpb25XaWR0aC5XaWRlLCBGb3JtU3R5bGUuU3RhbmRhbG9uZSwgdHJ1ZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdiYmJiYic6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlQZXJpb2RzLCBUcmFuc2xhdGlvbldpZHRoLk5hcnJvdywgRm9ybVN0eWxlLlN0YW5kYWxvbmUsIHRydWUpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gRXh0ZW5kZWQgcGVyaW9kIG9mIHRoZSBkYXkgKG1pZG5pZ2h0LCBuaWdodCwgLi4uKSwgc3RhbmRhbG9uZVxuICAgIGNhc2UgJ0InOlxuICAgIGNhc2UgJ0JCJzpcbiAgICBjYXNlICdCQkInOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZVN0ckdldHRlcihUcmFuc2xhdGlvblR5cGUuRGF5UGVyaW9kcywgVHJhbnNsYXRpb25XaWR0aC5BYmJyZXZpYXRlZCwgRm9ybVN0eWxlLkZvcm1hdCwgdHJ1ZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdCQkJCJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVTdHJHZXR0ZXIoVHJhbnNsYXRpb25UeXBlLkRheVBlcmlvZHMsIFRyYW5zbGF0aW9uV2lkdGguV2lkZSwgRm9ybVN0eWxlLkZvcm1hdCwgdHJ1ZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdCQkJCQic6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlU3RyR2V0dGVyKFRyYW5zbGF0aW9uVHlwZS5EYXlQZXJpb2RzLCBUcmFuc2xhdGlvbldpZHRoLk5hcnJvdywgRm9ybVN0eWxlLkZvcm1hdCwgdHJ1ZSk7XG4gICAgICBicmVhaztcbiAgICAvLyBIb3VyIGluIEFNL1BNLCAoMS0xMilcbiAgICBjYXNlICdoJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuSG91cnMsIDEsIC0xMik7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdoaCc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlR2V0dGVyKERhdGVUeXBlLkhvdXJzLCAyLCAtMTIpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gSG91ciBvZiB0aGUgZGF5ICgwLTIzKVxuICAgIGNhc2UgJ0gnOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZUdldHRlcihEYXRlVHlwZS5Ib3VycywgMSk7XG4gICAgICBicmVhaztcbiAgICAvLyBIb3VyIGluIGRheSwgcGFkZGVkICgwMC0yMylcbiAgICBjYXNlICdISCc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlR2V0dGVyKERhdGVUeXBlLkhvdXJzLCAyKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIE1pbnV0ZSBvZiB0aGUgaG91ciAoMC01OSlcbiAgICBjYXNlICdtJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuTWludXRlcywgMSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdtbSc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlR2V0dGVyKERhdGVUeXBlLk1pbnV0ZXMsIDIpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gU2Vjb25kIG9mIHRoZSBtaW51dGUgKDAtNTkpXG4gICAgY2FzZSAncyc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlR2V0dGVyKERhdGVUeXBlLlNlY29uZHMsIDEpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnc3MnOlxuICAgICAgZm9ybWF0dGVyID0gZGF0ZUdldHRlcihEYXRlVHlwZS5TZWNvbmRzLCAyKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIEZyYWN0aW9uYWwgc2Vjb25kXG4gICAgY2FzZSAnUyc6XG4gICAgICBmb3JtYXR0ZXIgPSBkYXRlR2V0dGVyKERhdGVUeXBlLkZyYWN0aW9uYWxTZWNvbmRzLCAxKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ1NTJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRnJhY3Rpb25hbFNlY29uZHMsIDIpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnU1NTJzpcbiAgICAgIGZvcm1hdHRlciA9IGRhdGVHZXR0ZXIoRGF0ZVR5cGUuRnJhY3Rpb25hbFNlY29uZHMsIDMpO1xuICAgICAgYnJlYWs7XG4gICAgLy8gVGltZXpvbmUgSVNPODYwMSBzaG9ydCBmb3JtYXQgKC0wNDMwKVxuICAgIGNhc2UgJ1onOlxuICAgIGNhc2UgJ1paJzpcbiAgICBjYXNlICdaWlonOlxuICAgICAgZm9ybWF0dGVyID0gdGltZVpvbmVHZXR0ZXIoWm9uZVdpZHRoLlNob3J0KTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIFRpbWV6b25lIElTTzg2MDEgZXh0ZW5kZWQgZm9ybWF0ICgtMDQ6MzApXG4gICAgY2FzZSAnWlpaWlonOlxuICAgICAgZm9ybWF0dGVyID0gdGltZVpvbmVHZXR0ZXIoWm9uZVdpZHRoLkV4dGVuZGVkKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIFRpbWV6b25lIEdNVCBzaG9ydCBmb3JtYXQgKEdNVCs0KVxuICAgIGNhc2UgJ08nOlxuICAgIGNhc2UgJ09PJzpcbiAgICBjYXNlICdPT08nOlxuICAgIC8vIFNob3VsZCBiZSBsb2NhdGlvbiwgYnV0IGZhbGxiYWNrIHRvIGZvcm1hdCBPIGluc3RlYWQgYmVjYXVzZSB3ZSBkb24ndCBoYXZlIHRoZSBkYXRhIHlldFxuICAgIGNhc2UgJ3onOlxuICAgIGNhc2UgJ3p6JzpcbiAgICBjYXNlICd6enonOlxuICAgICAgZm9ybWF0dGVyID0gdGltZVpvbmVHZXR0ZXIoWm9uZVdpZHRoLlNob3J0R01UKTtcbiAgICAgIGJyZWFrO1xuICAgIC8vIFRpbWV6b25lIEdNVCBsb25nIGZvcm1hdCAoR01UKzA0MzApXG4gICAgY2FzZSAnT09PTyc6XG4gICAgY2FzZSAnWlpaWic6XG4gICAgLy8gU2hvdWxkIGJlIGxvY2F0aW9uLCBidXQgZmFsbGJhY2sgdG8gZm9ybWF0IE8gaW5zdGVhZCBiZWNhdXNlIHdlIGRvbid0IGhhdmUgdGhlIGRhdGEgeWV0XG4gICAgY2FzZSAnenp6eic6XG4gICAgICBmb3JtYXR0ZXIgPSB0aW1lWm9uZUdldHRlcihab25lV2lkdGguTG9uZyk7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgREFURV9GT1JNQVRTW2Zvcm1hdF0gPSBmb3JtYXR0ZXI7XG4gIHJldHVybiBmb3JtYXR0ZXI7XG59XG5mdW5jdGlvbiB0aW1lem9uZVRvT2Zmc2V0KHRpbWV6b25lLCBmYWxsYmFjaykge1xuICAvLyBTdXBwb3J0OiBJRSAxMSBvbmx5LCBFZGdlIDEzLTE1K1xuICAvLyBJRS9FZGdlIGRvIG5vdCBcInVuZGVyc3RhbmRcIiBjb2xvbiAoYDpgKSBpbiB0aW1lem9uZVxuICB0aW1lem9uZSA9IHRpbWV6b25lLnJlcGxhY2UoLzovZywgJycpO1xuICBjb25zdCByZXF1ZXN0ZWRUaW1lem9uZU9mZnNldCA9IERhdGUucGFyc2UoJ0phbiAwMSwgMTk3MCAwMDowMDowMCAnICsgdGltZXpvbmUpIC8gNjAwMDA7XG4gIHJldHVybiBpc05hTihyZXF1ZXN0ZWRUaW1lem9uZU9mZnNldCkgPyBmYWxsYmFjayA6IHJlcXVlc3RlZFRpbWV6b25lT2Zmc2V0O1xufVxuZnVuY3Rpb24gYWRkRGF0ZU1pbnV0ZXMoZGF0ZSwgbWludXRlcykge1xuICBkYXRlID0gbmV3IERhdGUoZGF0ZS5nZXRUaW1lKCkpO1xuICBkYXRlLnNldE1pbnV0ZXMoZGF0ZS5nZXRNaW51dGVzKCkgKyBtaW51dGVzKTtcbiAgcmV0dXJuIGRhdGU7XG59XG5mdW5jdGlvbiBjb252ZXJ0VGltZXpvbmVUb0xvY2FsKGRhdGUsIHRpbWV6b25lLCByZXZlcnNlKSB7XG4gIGNvbnN0IHJldmVyc2VWYWx1ZSA9IHJldmVyc2UgPyAtMSA6IDE7XG4gIGNvbnN0IGRhdGVUaW1lem9uZU9mZnNldCA9IGRhdGUuZ2V0VGltZXpvbmVPZmZzZXQoKTtcbiAgY29uc3QgdGltZXpvbmVPZmZzZXQgPSB0aW1lem9uZVRvT2Zmc2V0KHRpbWV6b25lLCBkYXRlVGltZXpvbmVPZmZzZXQpO1xuICByZXR1cm4gYWRkRGF0ZU1pbnV0ZXMoZGF0ZSwgcmV2ZXJzZVZhbHVlICogKHRpbWV6b25lT2Zmc2V0IC0gZGF0ZVRpbWV6b25lT2Zmc2V0KSk7XG59XG4vKipcbiAqIENvbnZlcnRzIGEgdmFsdWUgdG8gZGF0ZS5cbiAqXG4gKiBTdXBwb3J0ZWQgaW5wdXQgZm9ybWF0czpcbiAqIC0gYERhdGVgXG4gKiAtIG51bWJlcjogdGltZXN0YW1wXG4gKiAtIHN0cmluZzogbnVtZXJpYyAoZS5nLiBcIjEyMzRcIiksIElTTyBhbmQgZGF0ZSBzdHJpbmdzIGluIGEgZm9ybWF0IHN1cHBvcnRlZCBieVxuICogICBbRGF0ZS5wYXJzZSgpXShodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9EYXRlL3BhcnNlKS5cbiAqICAgTm90ZTogSVNPIHN0cmluZ3Mgd2l0aG91dCB0aW1lIHJldHVybiBhIGRhdGUgd2l0aG91dCB0aW1lb2Zmc2V0LlxuICpcbiAqIFRocm93cyBpZiB1bmFibGUgdG8gY29udmVydCB0byBhIGRhdGUuXG4gKi9cbmZ1bmN0aW9uIHRvRGF0ZSh2YWx1ZSkge1xuICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiAhaXNOYU4odmFsdWUpKSB7XG4gICAgcmV0dXJuIG5ldyBEYXRlKHZhbHVlKTtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHZhbHVlID0gdmFsdWUudHJpbSgpO1xuICAgIGlmICgvXihcXGR7NH0oLVxcZHsxLDJ9KC1cXGR7MSwyfSk/KT8pJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgIC8qIEZvciBJU08gU3RyaW5ncyB3aXRob3V0IHRpbWUgdGhlIGRheSwgbW9udGggYW5kIHllYXIgbXVzdCBiZSBleHRyYWN0ZWQgZnJvbSB0aGUgSVNPIFN0cmluZ1xuICAgICAgYmVmb3JlIERhdGUgY3JlYXRpb24gdG8gYXZvaWQgdGltZSBvZmZzZXQgYW5kIGVycm9ycyBpbiB0aGUgbmV3IERhdGUuXG4gICAgICBJZiB3ZSBvbmx5IHJlcGxhY2UgJy0nIHdpdGggJywnIGluIHRoZSBJU08gU3RyaW5nIChcIjIwMTUsMDEsMDFcIiksIGFuZCB0cnkgdG8gY3JlYXRlIGEgbmV3XG4gICAgICBkYXRlLCBzb21lIGJyb3dzZXJzIChlLmcuIElFIDkpIHdpbGwgdGhyb3cgYW4gaW52YWxpZCBEYXRlIGVycm9yLlxuICAgICAgSWYgd2UgbGVhdmUgdGhlICctJyAoXCIyMDE1LTAxLTAxXCIpIGFuZCB0cnkgdG8gY3JlYXRlIGEgbmV3IERhdGUoXCIyMDE1LTAxLTAxXCIpIHRoZSB0aW1lb2Zmc2V0XG4gICAgICBpcyBhcHBsaWVkLlxuICAgICAgTm90ZTogSVNPIG1vbnRocyBhcmUgMCBmb3IgSmFudWFyeSwgMSBmb3IgRmVicnVhcnksIC4uLiAqL1xuICAgICAgY29uc3QgW3ksIG0gPSAxLCBkID0gMV0gPSB2YWx1ZS5zcGxpdCgnLScpLm1hcCh2YWwgPT4gK3ZhbCk7XG4gICAgICByZXR1cm4gY3JlYXRlRGF0ZSh5LCBtIC0gMSwgZCk7XG4gICAgfVxuICAgIGNvbnN0IHBhcnNlZE5iID0gcGFyc2VGbG9hdCh2YWx1ZSk7XG4gICAgLy8gYW55IHN0cmluZyB0aGF0IG9ubHkgY29udGFpbnMgbnVtYmVycywgbGlrZSBcIjEyMzRcIiBidXQgbm90IGxpa2UgXCIxMjM0aGVsbG9cIlxuICAgIGlmICghaXNOYU4odmFsdWUgLSBwYXJzZWROYikpIHtcbiAgICAgIHJldHVybiBuZXcgRGF0ZShwYXJzZWROYik7XG4gICAgfVxuICAgIGxldCBtYXRjaDtcbiAgICBpZiAobWF0Y2ggPSB2YWx1ZS5tYXRjaChJU084NjAxX0RBVEVfUkVHRVgpKSB7XG4gICAgICByZXR1cm4gaXNvU3RyaW5nVG9EYXRlKG1hdGNoKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHZhbHVlKTtcbiAgaWYgKCFpc0RhdGUoZGF0ZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuYWJsZSB0byBjb252ZXJ0IFwiJHt2YWx1ZX1cIiBpbnRvIGEgZGF0ZWApO1xuICB9XG4gIHJldHVybiBkYXRlO1xufVxuLyoqXG4gKiBDb252ZXJ0cyBhIGRhdGUgaW4gSVNPODYwMSB0byBhIERhdGUuXG4gKiBVc2VkIGluc3RlYWQgb2YgYERhdGUucGFyc2VgIGJlY2F1c2Ugb2YgYnJvd3NlciBkaXNjcmVwYW5jaWVzLlxuICovXG5mdW5jdGlvbiBpc29TdHJpbmdUb0RhdGUobWF0Y2gpIHtcbiAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKDApO1xuICBsZXQgdHpIb3VyID0gMDtcbiAgbGV0IHR6TWluID0gMDtcbiAgLy8gbWF0Y2hbOF0gbWVhbnMgdGhhdCB0aGUgc3RyaW5nIGNvbnRhaW5zIFwiWlwiIChVVEMpIG9yIGEgdGltZXpvbmUgbGlrZSBcIiswMTowMFwiIG9yIFwiKzAxMDBcIlxuICBjb25zdCBkYXRlU2V0dGVyID0gbWF0Y2hbOF0gPyBkYXRlLnNldFVUQ0Z1bGxZZWFyIDogZGF0ZS5zZXRGdWxsWWVhcjtcbiAgY29uc3QgdGltZVNldHRlciA9IG1hdGNoWzhdID8gZGF0ZS5zZXRVVENIb3VycyA6IGRhdGUuc2V0SG91cnM7XG4gIC8vIGlmIHRoZXJlIGlzIGEgdGltZXpvbmUgZGVmaW5lZCBsaWtlIFwiKzAxOjAwXCIgb3IgXCIrMDEwMFwiXG4gIGlmIChtYXRjaFs5XSkge1xuICAgIHR6SG91ciA9IE51bWJlcihtYXRjaFs5XSArIG1hdGNoWzEwXSk7XG4gICAgdHpNaW4gPSBOdW1iZXIobWF0Y2hbOV0gKyBtYXRjaFsxMV0pO1xuICB9XG4gIGRhdGVTZXR0ZXIuY2FsbChkYXRlLCBOdW1iZXIobWF0Y2hbMV0pLCBOdW1iZXIobWF0Y2hbMl0pIC0gMSwgTnVtYmVyKG1hdGNoWzNdKSk7XG4gIGNvbnN0IGggPSBOdW1iZXIobWF0Y2hbNF0gfHwgMCkgLSB0ekhvdXI7XG4gIGNvbnN0IG0gPSBOdW1iZXIobWF0Y2hbNV0gfHwgMCkgLSB0ek1pbjtcbiAgY29uc3QgcyA9IE51bWJlcihtYXRjaFs2XSB8fCAwKTtcbiAgLy8gVGhlIEVDTUFTY3JpcHQgc3BlY2lmaWNhdGlvbiAoaHR0cHM6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi81LjEvI3NlYy0xNS45LjEuMTEpXG4gIC8vIGRlZmluZXMgdGhhdCBgRGF0ZVRpbWVgIG1pbGxpc2Vjb25kcyBzaG91bGQgYWx3YXlzIGJlIHJvdW5kZWQgZG93biwgc28gdGhhdCBgOTk5Ljltc2BcbiAgLy8gYmVjb21lcyBgOTk5bXNgLlxuICBjb25zdCBtcyA9IE1hdGguZmxvb3IocGFyc2VGbG9hdCgnMC4nICsgKG1hdGNoWzddIHx8IDApKSAqIDEwMDApO1xuICB0aW1lU2V0dGVyLmNhbGwoZGF0ZSwgaCwgbSwgcywgbXMpO1xuICByZXR1cm4gZGF0ZTtcbn1cbmZ1bmN0aW9uIGlzRGF0ZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBEYXRlICYmICFpc05hTih2YWx1ZS52YWx1ZU9mKCkpO1xufVxuY29uc3QgTlVNQkVSX0ZPUk1BVF9SRUdFWFAgPSAvXihcXGQrKT9cXC4oKFxcZCspKC0oXFxkKykpPyk/JC87XG5jb25zdCBNQVhfRElHSVRTID0gMjI7XG5jb25zdCBERUNJTUFMX1NFUCA9ICcuJztcbmNvbnN0IFpFUk9fQ0hBUiA9ICcwJztcbmNvbnN0IFBBVFRFUk5fU0VQID0gJzsnO1xuY29uc3QgR1JPVVBfU0VQID0gJywnO1xuY29uc3QgRElHSVRfQ0hBUiA9ICcjJztcbmNvbnN0IENVUlJFTkNZX0NIQVIgPSAnwqQnO1xuY29uc3QgUEVSQ0VOVF9DSEFSID0gJyUnO1xuLyoqXG4gKiBUcmFuc2Zvcm1zIGEgbnVtYmVyIHRvIGEgbG9jYWxlIHN0cmluZyBiYXNlZCBvbiBhIHN0eWxlIGFuZCBhIGZvcm1hdC5cbiAqL1xuZnVuY3Rpb24gZm9ybWF0TnVtYmVyVG9Mb2NhbGVTdHJpbmcodmFsdWUsIHBhdHRlcm4sIGxvY2FsZSwgZ3JvdXBTeW1ib2wsIGRlY2ltYWxTeW1ib2wsIGRpZ2l0c0luZm8sIGlzUGVyY2VudCA9IGZhbHNlKSB7XG4gIGxldCBmb3JtYXR0ZWRUZXh0ID0gJyc7XG4gIGxldCBpc1plcm8gPSBmYWxzZTtcbiAgaWYgKCFpc0Zpbml0ZSh2YWx1ZSkpIHtcbiAgICBmb3JtYXR0ZWRUZXh0ID0gZ2V0TG9jYWxlTnVtYmVyU3ltYm9sKGxvY2FsZSwgTnVtYmVyU3ltYm9sLkluZmluaXR5KTtcbiAgfSBlbHNlIHtcbiAgICBsZXQgcGFyc2VkTnVtYmVyID0gcGFyc2VOdW1iZXIodmFsdWUpO1xuICAgIGlmIChpc1BlcmNlbnQpIHtcbiAgICAgIHBhcnNlZE51bWJlciA9IHRvUGVyY2VudChwYXJzZWROdW1iZXIpO1xuICAgIH1cbiAgICBsZXQgbWluSW50ID0gcGF0dGVybi5taW5JbnQ7XG4gICAgbGV0IG1pbkZyYWN0aW9uID0gcGF0dGVybi5taW5GcmFjO1xuICAgIGxldCBtYXhGcmFjdGlvbiA9IHBhdHRlcm4ubWF4RnJhYztcbiAgICBpZiAoZGlnaXRzSW5mbykge1xuICAgICAgY29uc3QgcGFydHMgPSBkaWdpdHNJbmZvLm1hdGNoKE5VTUJFUl9GT1JNQVRfUkVHRVhQKTtcbiAgICAgIGlmIChwYXJ0cyA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZGlnaXRzSW5mb30gaXMgbm90IGEgdmFsaWQgZGlnaXQgaW5mb2ApO1xuICAgICAgfVxuICAgICAgY29uc3QgbWluSW50UGFydCA9IHBhcnRzWzFdO1xuICAgICAgY29uc3QgbWluRnJhY3Rpb25QYXJ0ID0gcGFydHNbM107XG4gICAgICBjb25zdCBtYXhGcmFjdGlvblBhcnQgPSBwYXJ0c1s1XTtcbiAgICAgIGlmIChtaW5JbnRQYXJ0ICE9IG51bGwpIHtcbiAgICAgICAgbWluSW50ID0gcGFyc2VJbnRBdXRvUmFkaXgobWluSW50UGFydCk7XG4gICAgICB9XG4gICAgICBpZiAobWluRnJhY3Rpb25QYXJ0ICE9IG51bGwpIHtcbiAgICAgICAgbWluRnJhY3Rpb24gPSBwYXJzZUludEF1dG9SYWRpeChtaW5GcmFjdGlvblBhcnQpO1xuICAgICAgfVxuICAgICAgaWYgKG1heEZyYWN0aW9uUGFydCAhPSBudWxsKSB7XG4gICAgICAgIG1heEZyYWN0aW9uID0gcGFyc2VJbnRBdXRvUmFkaXgobWF4RnJhY3Rpb25QYXJ0KTtcbiAgICAgIH0gZWxzZSBpZiAobWluRnJhY3Rpb25QYXJ0ICE9IG51bGwgJiYgbWluRnJhY3Rpb24gPiBtYXhGcmFjdGlvbikge1xuICAgICAgICBtYXhGcmFjdGlvbiA9IG1pbkZyYWN0aW9uO1xuICAgICAgfVxuICAgIH1cbiAgICByb3VuZE51bWJlcihwYXJzZWROdW1iZXIsIG1pbkZyYWN0aW9uLCBtYXhGcmFjdGlvbik7XG4gICAgbGV0IGRpZ2l0cyA9IHBhcnNlZE51bWJlci5kaWdpdHM7XG4gICAgbGV0IGludGVnZXJMZW4gPSBwYXJzZWROdW1iZXIuaW50ZWdlckxlbjtcbiAgICBjb25zdCBleHBvbmVudCA9IHBhcnNlZE51bWJlci5leHBvbmVudDtcbiAgICBsZXQgZGVjaW1hbHMgPSBbXTtcbiAgICBpc1plcm8gPSBkaWdpdHMuZXZlcnkoZCA9PiAhZCk7XG4gICAgLy8gcGFkIHplcm9zIGZvciBzbWFsbCBudW1iZXJzXG4gICAgZm9yICg7IGludGVnZXJMZW4gPCBtaW5JbnQ7IGludGVnZXJMZW4rKykge1xuICAgICAgZGlnaXRzLnVuc2hpZnQoMCk7XG4gICAgfVxuICAgIC8vIHBhZCB6ZXJvcyBmb3Igc21hbGwgbnVtYmVyc1xuICAgIGZvciAoOyBpbnRlZ2VyTGVuIDwgMDsgaW50ZWdlckxlbisrKSB7XG4gICAgICBkaWdpdHMudW5zaGlmdCgwKTtcbiAgICB9XG4gICAgLy8gZXh0cmFjdCBkZWNpbWFscyBkaWdpdHNcbiAgICBpZiAoaW50ZWdlckxlbiA+IDApIHtcbiAgICAgIGRlY2ltYWxzID0gZGlnaXRzLnNwbGljZShpbnRlZ2VyTGVuLCBkaWdpdHMubGVuZ3RoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVjaW1hbHMgPSBkaWdpdHM7XG4gICAgICBkaWdpdHMgPSBbMF07XG4gICAgfVxuICAgIC8vIGZvcm1hdCB0aGUgaW50ZWdlciBkaWdpdHMgd2l0aCBncm91cGluZyBzZXBhcmF0b3JzXG4gICAgY29uc3QgZ3JvdXBzID0gW107XG4gICAgaWYgKGRpZ2l0cy5sZW5ndGggPj0gcGF0dGVybi5sZ1NpemUpIHtcbiAgICAgIGdyb3Vwcy51bnNoaWZ0KGRpZ2l0cy5zcGxpY2UoLXBhdHRlcm4ubGdTaXplLCBkaWdpdHMubGVuZ3RoKS5qb2luKCcnKSk7XG4gICAgfVxuICAgIHdoaWxlIChkaWdpdHMubGVuZ3RoID4gcGF0dGVybi5nU2l6ZSkge1xuICAgICAgZ3JvdXBzLnVuc2hpZnQoZGlnaXRzLnNwbGljZSgtcGF0dGVybi5nU2l6ZSwgZGlnaXRzLmxlbmd0aCkuam9pbignJykpO1xuICAgIH1cbiAgICBpZiAoZGlnaXRzLmxlbmd0aCkge1xuICAgICAgZ3JvdXBzLnVuc2hpZnQoZGlnaXRzLmpvaW4oJycpKTtcbiAgICB9XG4gICAgZm9ybWF0dGVkVGV4dCA9IGdyb3Vwcy5qb2luKGdldExvY2FsZU51bWJlclN5bWJvbChsb2NhbGUsIGdyb3VwU3ltYm9sKSk7XG4gICAgLy8gYXBwZW5kIHRoZSBkZWNpbWFsIGRpZ2l0c1xuICAgIGlmIChkZWNpbWFscy5sZW5ndGgpIHtcbiAgICAgIGZvcm1hdHRlZFRleHQgKz0gZ2V0TG9jYWxlTnVtYmVyU3ltYm9sKGxvY2FsZSwgZGVjaW1hbFN5bWJvbCkgKyBkZWNpbWFscy5qb2luKCcnKTtcbiAgICB9XG4gICAgaWYgKGV4cG9uZW50KSB7XG4gICAgICBmb3JtYXR0ZWRUZXh0ICs9IGdldExvY2FsZU51bWJlclN5bWJvbChsb2NhbGUsIE51bWJlclN5bWJvbC5FeHBvbmVudGlhbCkgKyAnKycgKyBleHBvbmVudDtcbiAgICB9XG4gIH1cbiAgaWYgKHZhbHVlIDwgMCAmJiAhaXNaZXJvKSB7XG4gICAgZm9ybWF0dGVkVGV4dCA9IHBhdHRlcm4ubmVnUHJlICsgZm9ybWF0dGVkVGV4dCArIHBhdHRlcm4ubmVnU3VmO1xuICB9IGVsc2Uge1xuICAgIGZvcm1hdHRlZFRleHQgPSBwYXR0ZXJuLnBvc1ByZSArIGZvcm1hdHRlZFRleHQgKyBwYXR0ZXJuLnBvc1N1ZjtcbiAgfVxuICByZXR1cm4gZm9ybWF0dGVkVGV4dDtcbn1cbi8qKlxuICogQG5nTW9kdWxlIENvbW1vbk1vZHVsZVxuICogQGRlc2NyaXB0aW9uXG4gKlxuICogRm9ybWF0cyBhIG51bWJlciBhcyBjdXJyZW5jeSB1c2luZyBsb2NhbGUgcnVsZXMuXG4gKlxuICogQHBhcmFtIHZhbHVlIFRoZSBudW1iZXIgdG8gZm9ybWF0LlxuICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlIGZvciB0aGUgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuXG4gKiBAcGFyYW0gY3VycmVuY3kgQSBzdHJpbmcgY29udGFpbmluZyB0aGUgY3VycmVuY3kgc3ltYm9sIG9yIGl0cyBuYW1lLFxuICogc3VjaCBhcyBcIiRcIiBvciBcIkNhbmFkaWFuIERvbGxhclwiLiBVc2VkIGluIG91dHB1dCBzdHJpbmcsIGJ1dCBkb2VzIG5vdCBhZmZlY3QgdGhlIG9wZXJhdGlvblxuICogb2YgdGhlIGZ1bmN0aW9uLlxuICogQHBhcmFtIGN1cnJlbmN5Q29kZSBUaGUgW0lTTyA0MjE3XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fNDIxNylcbiAqIGN1cnJlbmN5IGNvZGUsIHN1Y2ggYXMgYFVTRGAgZm9yIHRoZSBVUyBkb2xsYXIgYW5kIGBFVVJgIGZvciB0aGUgZXVyby5cbiAqIFVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgZGlnaXRzIGluIHRoZSBkZWNpbWFsIHBhcnQuXG4gKiBAcGFyYW0gZGlnaXRzSW5mbyBEZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9wdGlvbnMsIHNwZWNpZmllZCBieSBhIHN0cmluZyBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDpcbiAqIGB7bWluSW50ZWdlckRpZ2l0c30ue21pbkZyYWN0aW9uRGlnaXRzfS17bWF4RnJhY3Rpb25EaWdpdHN9YC4gU2VlIGBEZWNpbWFsUGlwZWAgZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAcmV0dXJucyBUaGUgZm9ybWF0dGVkIGN1cnJlbmN5IHZhbHVlLlxuICpcbiAqIEBzZWUge0BsaW5rIGZvcm1hdE51bWJlcn1cbiAqIEBzZWUge0BsaW5rIERlY2ltYWxQaXBlfVxuICogQHNlZSBbSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIEd1aWRlXShndWlkZS9pMThuKVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZnVuY3Rpb24gZm9ybWF0Q3VycmVuY3kodmFsdWUsIGxvY2FsZSwgY3VycmVuY3ksIGN1cnJlbmN5Q29kZSwgZGlnaXRzSW5mbykge1xuICBjb25zdCBmb3JtYXQgPSBnZXRMb2NhbGVOdW1iZXJGb3JtYXQobG9jYWxlLCBOdW1iZXJGb3JtYXRTdHlsZS5DdXJyZW5jeSk7XG4gIGNvbnN0IHBhdHRlcm4gPSBwYXJzZU51bWJlckZvcm1hdChmb3JtYXQsIGdldExvY2FsZU51bWJlclN5bWJvbChsb2NhbGUsIE51bWJlclN5bWJvbC5NaW51c1NpZ24pKTtcbiAgcGF0dGVybi5taW5GcmFjID0gZ2V0TnVtYmVyT2ZDdXJyZW5jeURpZ2l0cyhjdXJyZW5jeUNvZGUpO1xuICBwYXR0ZXJuLm1heEZyYWMgPSBwYXR0ZXJuLm1pbkZyYWM7XG4gIGNvbnN0IHJlcyA9IGZvcm1hdE51bWJlclRvTG9jYWxlU3RyaW5nKHZhbHVlLCBwYXR0ZXJuLCBsb2NhbGUsIE51bWJlclN5bWJvbC5DdXJyZW5jeUdyb3VwLCBOdW1iZXJTeW1ib2wuQ3VycmVuY3lEZWNpbWFsLCBkaWdpdHNJbmZvKTtcbiAgcmV0dXJuIHJlcy5yZXBsYWNlKENVUlJFTkNZX0NIQVIsIGN1cnJlbmN5KVxuICAvLyBpZiB3ZSBoYXZlIDIgdGltZSB0aGUgY3VycmVuY3kgY2hhcmFjdGVyLCB0aGUgc2Vjb25kIG9uZSBpcyBpZ25vcmVkXG4gIC5yZXBsYWNlKENVUlJFTkNZX0NIQVIsICcnKVxuICAvLyBJZiB0aGVyZSBpcyBhIHNwYWNpbmcgYmV0d2VlbiBjdXJyZW5jeSBjaGFyYWN0ZXIgYW5kIHRoZSB2YWx1ZSBhbmRcbiAgLy8gdGhlIGN1cnJlbmN5IGNoYXJhY3RlciBpcyBzdXBwcmVzc2VkIGJ5IHBhc3NpbmcgYW4gZW1wdHkgc3RyaW5nLCB0aGVcbiAgLy8gc3BhY2luZyBjaGFyYWN0ZXIgd291bGQgcmVtYWluIGFzIHBhcnQgb2YgdGhlIHN0cmluZy4gVGhlbiB3ZVxuICAvLyBzaG91bGQgcmVtb3ZlIGl0LlxuICAudHJpbSgpO1xufVxuLyoqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiBGb3JtYXRzIGEgbnVtYmVyIGFzIGEgcGVyY2VudGFnZSBhY2NvcmRpbmcgdG8gbG9jYWxlIHJ1bGVzLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtYmVyIHRvIGZvcm1hdC5cbiAqIEBwYXJhbSBsb2NhbGUgQSBsb2NhbGUgY29kZSBmb3IgdGhlIGxvY2FsZSBmb3JtYXQgcnVsZXMgdG8gdXNlLlxuICogQHBhcmFtIGRpZ2l0c0luZm8gRGVjaW1hbCByZXByZXNlbnRhdGlvbiBvcHRpb25zLCBzcGVjaWZpZWQgYnkgYSBzdHJpbmcgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6XG4gKiBge21pbkludGVnZXJEaWdpdHN9LnttaW5GcmFjdGlvbkRpZ2l0c30te21heEZyYWN0aW9uRGlnaXRzfWAuIFNlZSBgRGVjaW1hbFBpcGVgIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHJldHVybnMgVGhlIGZvcm1hdHRlZCBwZXJjZW50YWdlIHZhbHVlLlxuICpcbiAqIEBzZWUge0BsaW5rIGZvcm1hdE51bWJlcn1cbiAqIEBzZWUge0BsaW5rIERlY2ltYWxQaXBlfVxuICogQHNlZSBbSW50ZXJuYXRpb25hbGl6YXRpb24gKGkxOG4pIEd1aWRlXShndWlkZS9pMThuKVxuICogQHB1YmxpY0FwaVxuICpcbiAqL1xuZnVuY3Rpb24gZm9ybWF0UGVyY2VudCh2YWx1ZSwgbG9jYWxlLCBkaWdpdHNJbmZvKSB7XG4gIGNvbnN0IGZvcm1hdCA9IGdldExvY2FsZU51bWJlckZvcm1hdChsb2NhbGUsIE51bWJlckZvcm1hdFN0eWxlLlBlcmNlbnQpO1xuICBjb25zdCBwYXR0ZXJuID0gcGFyc2VOdW1iZXJGb3JtYXQoZm9ybWF0LCBnZXRMb2NhbGVOdW1iZXJTeW1ib2wobG9jYWxlLCBOdW1iZXJTeW1ib2wuTWludXNTaWduKSk7XG4gIGNvbnN0IHJlcyA9IGZvcm1hdE51bWJlclRvTG9jYWxlU3RyaW5nKHZhbHVlLCBwYXR0ZXJuLCBsb2NhbGUsIE51bWJlclN5bWJvbC5Hcm91cCwgTnVtYmVyU3ltYm9sLkRlY2ltYWwsIGRpZ2l0c0luZm8sIHRydWUpO1xuICByZXR1cm4gcmVzLnJlcGxhY2UobmV3IFJlZ0V4cChQRVJDRU5UX0NIQVIsICdnJyksIGdldExvY2FsZU51bWJlclN5bWJvbChsb2NhbGUsIE51bWJlclN5bWJvbC5QZXJjZW50U2lnbikpO1xufVxuLyoqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiBGb3JtYXRzIGEgbnVtYmVyIGFzIHRleHQsIHdpdGggZ3JvdXAgc2l6aW5nLCBzZXBhcmF0b3IsIGFuZCBvdGhlclxuICogcGFyYW1ldGVycyBiYXNlZCBvbiB0aGUgbG9jYWxlLlxuICpcbiAqIEBwYXJhbSB2YWx1ZSBUaGUgbnVtYmVyIHRvIGZvcm1hdC5cbiAqIEBwYXJhbSBsb2NhbGUgQSBsb2NhbGUgY29kZSBmb3IgdGhlIGxvY2FsZSBmb3JtYXQgcnVsZXMgdG8gdXNlLlxuICogQHBhcmFtIGRpZ2l0c0luZm8gRGVjaW1hbCByZXByZXNlbnRhdGlvbiBvcHRpb25zLCBzcGVjaWZpZWQgYnkgYSBzdHJpbmcgaW4gdGhlIGZvbGxvd2luZyBmb3JtYXQ6XG4gKiBge21pbkludGVnZXJEaWdpdHN9LnttaW5GcmFjdGlvbkRpZ2l0c30te21heEZyYWN0aW9uRGlnaXRzfWAuIFNlZSBgRGVjaW1hbFBpcGVgIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHJldHVybnMgVGhlIGZvcm1hdHRlZCB0ZXh0IHN0cmluZy5cbiAqIEBzZWUgW0ludGVybmF0aW9uYWxpemF0aW9uIChpMThuKSBHdWlkZV0oZ3VpZGUvaTE4bilcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmZ1bmN0aW9uIGZvcm1hdE51bWJlcih2YWx1ZSwgbG9jYWxlLCBkaWdpdHNJbmZvKSB7XG4gIGNvbnN0IGZvcm1hdCA9IGdldExvY2FsZU51bWJlckZvcm1hdChsb2NhbGUsIE51bWJlckZvcm1hdFN0eWxlLkRlY2ltYWwpO1xuICBjb25zdCBwYXR0ZXJuID0gcGFyc2VOdW1iZXJGb3JtYXQoZm9ybWF0LCBnZXRMb2NhbGVOdW1iZXJTeW1ib2wobG9jYWxlLCBOdW1iZXJTeW1ib2wuTWludXNTaWduKSk7XG4gIHJldHVybiBmb3JtYXROdW1iZXJUb0xvY2FsZVN0cmluZyh2YWx1ZSwgcGF0dGVybiwgbG9jYWxlLCBOdW1iZXJTeW1ib2wuR3JvdXAsIE51bWJlclN5bWJvbC5EZWNpbWFsLCBkaWdpdHNJbmZvKTtcbn1cbmZ1bmN0aW9uIHBhcnNlTnVtYmVyRm9ybWF0KGZvcm1hdCwgbWludXNTaWduID0gJy0nKSB7XG4gIGNvbnN0IHAgPSB7XG4gICAgbWluSW50OiAxLFxuICAgIG1pbkZyYWM6IDAsXG4gICAgbWF4RnJhYzogMCxcbiAgICBwb3NQcmU6ICcnLFxuICAgIHBvc1N1ZjogJycsXG4gICAgbmVnUHJlOiAnJyxcbiAgICBuZWdTdWY6ICcnLFxuICAgIGdTaXplOiAwLFxuICAgIGxnU2l6ZTogMFxuICB9O1xuICBjb25zdCBwYXR0ZXJuUGFydHMgPSBmb3JtYXQuc3BsaXQoUEFUVEVSTl9TRVApO1xuICBjb25zdCBwb3NpdGl2ZSA9IHBhdHRlcm5QYXJ0c1swXTtcbiAgY29uc3QgbmVnYXRpdmUgPSBwYXR0ZXJuUGFydHNbMV07XG4gIGNvbnN0IHBvc2l0aXZlUGFydHMgPSBwb3NpdGl2ZS5pbmRleE9mKERFQ0lNQUxfU0VQKSAhPT0gLTEgPyBwb3NpdGl2ZS5zcGxpdChERUNJTUFMX1NFUCkgOiBbcG9zaXRpdmUuc3Vic3RyaW5nKDAsIHBvc2l0aXZlLmxhc3RJbmRleE9mKFpFUk9fQ0hBUikgKyAxKSwgcG9zaXRpdmUuc3Vic3RyaW5nKHBvc2l0aXZlLmxhc3RJbmRleE9mKFpFUk9fQ0hBUikgKyAxKV0sXG4gICAgaW50ZWdlciA9IHBvc2l0aXZlUGFydHNbMF0sXG4gICAgZnJhY3Rpb24gPSBwb3NpdGl2ZVBhcnRzWzFdIHx8ICcnO1xuICBwLnBvc1ByZSA9IGludGVnZXIuc3Vic3RyaW5nKDAsIGludGVnZXIuaW5kZXhPZihESUdJVF9DSEFSKSk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgZnJhY3Rpb24ubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBjaCA9IGZyYWN0aW9uLmNoYXJBdChpKTtcbiAgICBpZiAoY2ggPT09IFpFUk9fQ0hBUikge1xuICAgICAgcC5taW5GcmFjID0gcC5tYXhGcmFjID0gaSArIDE7XG4gICAgfSBlbHNlIGlmIChjaCA9PT0gRElHSVRfQ0hBUikge1xuICAgICAgcC5tYXhGcmFjID0gaSArIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHAucG9zU3VmICs9IGNoO1xuICAgIH1cbiAgfVxuICBjb25zdCBncm91cHMgPSBpbnRlZ2VyLnNwbGl0KEdST1VQX1NFUCk7XG4gIHAuZ1NpemUgPSBncm91cHNbMV0gPyBncm91cHNbMV0ubGVuZ3RoIDogMDtcbiAgcC5sZ1NpemUgPSBncm91cHNbMl0gfHwgZ3JvdXBzWzFdID8gKGdyb3Vwc1syXSB8fCBncm91cHNbMV0pLmxlbmd0aCA6IDA7XG4gIGlmIChuZWdhdGl2ZSkge1xuICAgIGNvbnN0IHRydW5rTGVuID0gcG9zaXRpdmUubGVuZ3RoIC0gcC5wb3NQcmUubGVuZ3RoIC0gcC5wb3NTdWYubGVuZ3RoLFxuICAgICAgcG9zID0gbmVnYXRpdmUuaW5kZXhPZihESUdJVF9DSEFSKTtcbiAgICBwLm5lZ1ByZSA9IG5lZ2F0aXZlLnN1YnN0cmluZygwLCBwb3MpLnJlcGxhY2UoLycvZywgJycpO1xuICAgIHAubmVnU3VmID0gbmVnYXRpdmUuc2xpY2UocG9zICsgdHJ1bmtMZW4pLnJlcGxhY2UoLycvZywgJycpO1xuICB9IGVsc2Uge1xuICAgIHAubmVnUHJlID0gbWludXNTaWduICsgcC5wb3NQcmU7XG4gICAgcC5uZWdTdWYgPSBwLnBvc1N1ZjtcbiAgfVxuICByZXR1cm4gcDtcbn1cbi8vIFRyYW5zZm9ybXMgYSBwYXJzZWQgbnVtYmVyIGludG8gYSBwZXJjZW50YWdlIGJ5IG11bHRpcGx5aW5nIGl0IGJ5IDEwMFxuZnVuY3Rpb24gdG9QZXJjZW50KHBhcnNlZE51bWJlcikge1xuICAvLyBpZiB0aGUgbnVtYmVyIGlzIDAsIGRvbid0IGRvIGFueXRoaW5nXG4gIGlmIChwYXJzZWROdW1iZXIuZGlnaXRzWzBdID09PSAwKSB7XG4gICAgcmV0dXJuIHBhcnNlZE51bWJlcjtcbiAgfVxuICAvLyBHZXR0aW5nIHRoZSBjdXJyZW50IG51bWJlciBvZiBkZWNpbWFsc1xuICBjb25zdCBmcmFjdGlvbkxlbiA9IHBhcnNlZE51bWJlci5kaWdpdHMubGVuZ3RoIC0gcGFyc2VkTnVtYmVyLmludGVnZXJMZW47XG4gIGlmIChwYXJzZWROdW1iZXIuZXhwb25lbnQpIHtcbiAgICBwYXJzZWROdW1iZXIuZXhwb25lbnQgKz0gMjtcbiAgfSBlbHNlIHtcbiAgICBpZiAoZnJhY3Rpb25MZW4gPT09IDApIHtcbiAgICAgIHBhcnNlZE51bWJlci5kaWdpdHMucHVzaCgwLCAwKTtcbiAgICB9IGVsc2UgaWYgKGZyYWN0aW9uTGVuID09PSAxKSB7XG4gICAgICBwYXJzZWROdW1iZXIuZGlnaXRzLnB1c2goMCk7XG4gICAgfVxuICAgIHBhcnNlZE51bWJlci5pbnRlZ2VyTGVuICs9IDI7XG4gIH1cbiAgcmV0dXJuIHBhcnNlZE51bWJlcjtcbn1cbi8qKlxuICogUGFyc2VzIGEgbnVtYmVyLlxuICogU2lnbmlmaWNhbnQgYml0cyBvZiB0aGlzIHBhcnNlIGFsZ29yaXRobSBjYW1lIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL01pa2VNY2wvYmlnLmpzL1xuICovXG5mdW5jdGlvbiBwYXJzZU51bWJlcihudW0pIHtcbiAgbGV0IG51bVN0ciA9IE1hdGguYWJzKG51bSkgKyAnJztcbiAgbGV0IGV4cG9uZW50ID0gMCxcbiAgICBkaWdpdHMsXG4gICAgaW50ZWdlckxlbjtcbiAgbGV0IGksIGosIHplcm9zO1xuICAvLyBEZWNpbWFsIHBvaW50P1xuICBpZiAoKGludGVnZXJMZW4gPSBudW1TdHIuaW5kZXhPZihERUNJTUFMX1NFUCkpID4gLTEpIHtcbiAgICBudW1TdHIgPSBudW1TdHIucmVwbGFjZShERUNJTUFMX1NFUCwgJycpO1xuICB9XG4gIC8vIEV4cG9uZW50aWFsIGZvcm0/XG4gIGlmICgoaSA9IG51bVN0ci5zZWFyY2goL2UvaSkpID4gMCkge1xuICAgIC8vIFdvcmsgb3V0IHRoZSBleHBvbmVudC5cbiAgICBpZiAoaW50ZWdlckxlbiA8IDApIGludGVnZXJMZW4gPSBpO1xuICAgIGludGVnZXJMZW4gKz0gK251bVN0ci5zbGljZShpICsgMSk7XG4gICAgbnVtU3RyID0gbnVtU3RyLnN1YnN0cmluZygwLCBpKTtcbiAgfSBlbHNlIGlmIChpbnRlZ2VyTGVuIDwgMCkge1xuICAgIC8vIFRoZXJlIHdhcyBubyBkZWNpbWFsIHBvaW50IG9yIGV4cG9uZW50IHNvIGl0IGlzIGFuIGludGVnZXIuXG4gICAgaW50ZWdlckxlbiA9IG51bVN0ci5sZW5ndGg7XG4gIH1cbiAgLy8gQ291bnQgdGhlIG51bWJlciBvZiBsZWFkaW5nIHplcm9zLlxuICBmb3IgKGkgPSAwOyBudW1TdHIuY2hhckF0KGkpID09PSBaRVJPX0NIQVI7IGkrKykge1xuICAgIC8qIGVtcHR5ICovXG4gIH1cbiAgaWYgKGkgPT09ICh6ZXJvcyA9IG51bVN0ci5sZW5ndGgpKSB7XG4gICAgLy8gVGhlIGRpZ2l0cyBhcmUgYWxsIHplcm8uXG4gICAgZGlnaXRzID0gWzBdO1xuICAgIGludGVnZXJMZW4gPSAxO1xuICB9IGVsc2Uge1xuICAgIC8vIENvdW50IHRoZSBudW1iZXIgb2YgdHJhaWxpbmcgemVyb3NcbiAgICB6ZXJvcy0tO1xuICAgIHdoaWxlIChudW1TdHIuY2hhckF0KHplcm9zKSA9PT0gWkVST19DSEFSKSB6ZXJvcy0tO1xuICAgIC8vIFRyYWlsaW5nIHplcm9zIGFyZSBpbnNpZ25pZmljYW50IHNvIGlnbm9yZSB0aGVtXG4gICAgaW50ZWdlckxlbiAtPSBpO1xuICAgIGRpZ2l0cyA9IFtdO1xuICAgIC8vIENvbnZlcnQgc3RyaW5nIHRvIGFycmF5IG9mIGRpZ2l0cyB3aXRob3V0IGxlYWRpbmcvdHJhaWxpbmcgemVyb3MuXG4gICAgZm9yIChqID0gMDsgaSA8PSB6ZXJvczsgaSsrLCBqKyspIHtcbiAgICAgIGRpZ2l0c1tqXSA9IE51bWJlcihudW1TdHIuY2hhckF0KGkpKTtcbiAgICB9XG4gIH1cbiAgLy8gSWYgdGhlIG51bWJlciBvdmVyZmxvd3MgdGhlIG1heGltdW0gYWxsb3dlZCBkaWdpdHMgdGhlbiB1c2UgYW4gZXhwb25lbnQuXG4gIGlmIChpbnRlZ2VyTGVuID4gTUFYX0RJR0lUUykge1xuICAgIGRpZ2l0cyA9IGRpZ2l0cy5zcGxpY2UoMCwgTUFYX0RJR0lUUyAtIDEpO1xuICAgIGV4cG9uZW50ID0gaW50ZWdlckxlbiAtIDE7XG4gICAgaW50ZWdlckxlbiA9IDE7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBkaWdpdHMsXG4gICAgZXhwb25lbnQsXG4gICAgaW50ZWdlckxlblxuICB9O1xufVxuLyoqXG4gKiBSb3VuZCB0aGUgcGFyc2VkIG51bWJlciB0byB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlc1xuICogVGhpcyBmdW5jdGlvbiBjaGFuZ2VzIHRoZSBwYXJzZWROdW1iZXIgaW4tcGxhY2VcbiAqL1xuZnVuY3Rpb24gcm91bmROdW1iZXIocGFyc2VkTnVtYmVyLCBtaW5GcmFjLCBtYXhGcmFjKSB7XG4gIGlmIChtaW5GcmFjID4gbWF4RnJhYykge1xuICAgIHRocm93IG5ldyBFcnJvcihgVGhlIG1pbmltdW0gbnVtYmVyIG9mIGRpZ2l0cyBhZnRlciBmcmFjdGlvbiAoJHttaW5GcmFjfSkgaXMgaGlnaGVyIHRoYW4gdGhlIG1heGltdW0gKCR7bWF4RnJhY30pLmApO1xuICB9XG4gIGxldCBkaWdpdHMgPSBwYXJzZWROdW1iZXIuZGlnaXRzO1xuICBsZXQgZnJhY3Rpb25MZW4gPSBkaWdpdHMubGVuZ3RoIC0gcGFyc2VkTnVtYmVyLmludGVnZXJMZW47XG4gIGNvbnN0IGZyYWN0aW9uU2l6ZSA9IE1hdGgubWluKE1hdGgubWF4KG1pbkZyYWMsIGZyYWN0aW9uTGVuKSwgbWF4RnJhYyk7XG4gIC8vIFRoZSBpbmRleCBvZiB0aGUgZGlnaXQgdG8gd2hlcmUgcm91bmRpbmcgaXMgdG8gb2NjdXJcbiAgbGV0IHJvdW5kQXQgPSBmcmFjdGlvblNpemUgKyBwYXJzZWROdW1iZXIuaW50ZWdlckxlbjtcbiAgbGV0IGRpZ2l0ID0gZGlnaXRzW3JvdW5kQXRdO1xuICBpZiAocm91bmRBdCA+IDApIHtcbiAgICAvLyBEcm9wIGZyYWN0aW9uYWwgZGlnaXRzIGJleW9uZCBgcm91bmRBdGBcbiAgICBkaWdpdHMuc3BsaWNlKE1hdGgubWF4KHBhcnNlZE51bWJlci5pbnRlZ2VyTGVuLCByb3VuZEF0KSk7XG4gICAgLy8gU2V0IG5vbi1mcmFjdGlvbmFsIGRpZ2l0cyBiZXlvbmQgYHJvdW5kQXRgIHRvIDBcbiAgICBmb3IgKGxldCBqID0gcm91bmRBdDsgaiA8IGRpZ2l0cy5sZW5ndGg7IGorKykge1xuICAgICAgZGlnaXRzW2pdID0gMDtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gV2Ugcm91bmRlZCB0byB6ZXJvIHNvIHJlc2V0IHRoZSBwYXJzZWROdW1iZXJcbiAgICBmcmFjdGlvbkxlbiA9IE1hdGgubWF4KDAsIGZyYWN0aW9uTGVuKTtcbiAgICBwYXJzZWROdW1iZXIuaW50ZWdlckxlbiA9IDE7XG4gICAgZGlnaXRzLmxlbmd0aCA9IE1hdGgubWF4KDEsIHJvdW5kQXQgPSBmcmFjdGlvblNpemUgKyAxKTtcbiAgICBkaWdpdHNbMF0gPSAwO1xuICAgIGZvciAobGV0IGkgPSAxOyBpIDwgcm91bmRBdDsgaSsrKSBkaWdpdHNbaV0gPSAwO1xuICB9XG4gIGlmIChkaWdpdCA+PSA1KSB7XG4gICAgaWYgKHJvdW5kQXQgLSAxIDwgMCkge1xuICAgICAgZm9yIChsZXQgayA9IDA7IGsgPiByb3VuZEF0OyBrLS0pIHtcbiAgICAgICAgZGlnaXRzLnVuc2hpZnQoMCk7XG4gICAgICAgIHBhcnNlZE51bWJlci5pbnRlZ2VyTGVuKys7XG4gICAgICB9XG4gICAgICBkaWdpdHMudW5zaGlmdCgxKTtcbiAgICAgIHBhcnNlZE51bWJlci5pbnRlZ2VyTGVuKys7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRpZ2l0c1tyb3VuZEF0IC0gMV0rKztcbiAgICB9XG4gIH1cbiAgLy8gUGFkIG91dCB3aXRoIHplcm9zIHRvIGdldCB0aGUgcmVxdWlyZWQgZnJhY3Rpb24gbGVuZ3RoXG4gIGZvciAoOyBmcmFjdGlvbkxlbiA8IE1hdGgubWF4KDAsIGZyYWN0aW9uU2l6ZSk7IGZyYWN0aW9uTGVuKyspIGRpZ2l0cy5wdXNoKDApO1xuICBsZXQgZHJvcFRyYWlsaW5nWmVyb3MgPSBmcmFjdGlvblNpemUgIT09IDA7XG4gIC8vIE1pbmltYWwgbGVuZ3RoID0gbmIgb2YgZGVjaW1hbHMgcmVxdWlyZWQgKyBjdXJyZW50IG5iIG9mIGludGVnZXJzXG4gIC8vIEFueSBudW1iZXIgYmVzaWRlcyB0aGF0IGlzIG9wdGlvbmFsIGFuZCBjYW4gYmUgcmVtb3ZlZCBpZiBpdCdzIGEgdHJhaWxpbmcgMFxuICBjb25zdCBtaW5MZW4gPSBtaW5GcmFjICsgcGFyc2VkTnVtYmVyLmludGVnZXJMZW47XG4gIC8vIERvIGFueSBjYXJyeWluZywgZS5nLiBhIGRpZ2l0IHdhcyByb3VuZGVkIHVwIHRvIDEwXG4gIGNvbnN0IGNhcnJ5ID0gZGlnaXRzLnJlZHVjZVJpZ2h0KGZ1bmN0aW9uIChjYXJyeSwgZCwgaSwgZGlnaXRzKSB7XG4gICAgZCA9IGQgKyBjYXJyeTtcbiAgICBkaWdpdHNbaV0gPSBkIDwgMTAgPyBkIDogZCAtIDEwOyAvLyBkICUgMTBcbiAgICBpZiAoZHJvcFRyYWlsaW5nWmVyb3MpIHtcbiAgICAgIC8vIERvIG5vdCBrZWVwIG1lYW5pbmdsZXNzIGZyYWN0aW9uYWwgdHJhaWxpbmcgemVyb3MgKGUuZy4gMTUuNTIwMDAgLS0+IDE1LjUyKVxuICAgICAgaWYgKGRpZ2l0c1tpXSA9PT0gMCAmJiBpID49IG1pbkxlbikge1xuICAgICAgICBkaWdpdHMucG9wKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkcm9wVHJhaWxpbmdaZXJvcyA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZCA+PSAxMCA/IDEgOiAwOyAvLyBNYXRoLmZsb29yKGQgLyAxMCk7XG4gIH0sIDApO1xuICBpZiAoY2FycnkpIHtcbiAgICBkaWdpdHMudW5zaGlmdChjYXJyeSk7XG4gICAgcGFyc2VkTnVtYmVyLmludGVnZXJMZW4rKztcbiAgfVxufVxuZnVuY3Rpb24gcGFyc2VJbnRBdXRvUmFkaXgodGV4dCkge1xuICBjb25zdCByZXN1bHQgPSBwYXJzZUludCh0ZXh0KTtcbiAgaWYgKGlzTmFOKHJlc3VsdCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgaW50ZWdlciBsaXRlcmFsIHdoZW4gcGFyc2luZyAnICsgdGV4dCk7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIE5nTG9jYWxpemF0aW9uIHtcbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gTmdMb2NhbGl6YXRpb25fRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IE5nTG9jYWxpemF0aW9uKSgpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1cHJvdiA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVJbmplY3RhYmxlKHtcbiAgICAgIHRva2VuOiBOZ0xvY2FsaXphdGlvbixcbiAgICAgIGZhY3Rvcnk6IGZ1bmN0aW9uIE5nTG9jYWxpemF0aW9uX0ZhY3RvcnkodCkge1xuICAgICAgICBsZXQgciA9IG51bGw7XG4gICAgICAgIGlmICh0KSB7XG4gICAgICAgICAgciA9IG5ldyB0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgciA9IChsb2NhbGUgPT4gbmV3IE5nTG9jYWxlTG9jYWxpemF0aW9uKGxvY2FsZSkpKGkwLsm1ybVpbmplY3QoTE9DQUxFX0lEKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHI7XG4gICAgICB9LFxuICAgICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKE5nTG9jYWxpemF0aW9uLCBbe1xuICAgIHR5cGU6IEluamVjdGFibGUsXG4gICAgYXJnczogW3tcbiAgICAgIHByb3ZpZGVkSW46ICdyb290JyxcbiAgICAgIHVzZUZhY3Rvcnk6IGxvY2FsZSA9PiBuZXcgTmdMb2NhbGVMb2NhbGl6YXRpb24obG9jYWxlKSxcbiAgICAgIGRlcHM6IFtMT0NBTEVfSURdXG4gICAgfV1cbiAgfV0sIG51bGwsIG51bGwpO1xufSkoKTtcbi8qKlxuICogUmV0dXJucyB0aGUgcGx1cmFsIGNhdGVnb3J5IGZvciBhIGdpdmVuIHZhbHVlLlxuICogLSBcIj12YWx1ZVwiIHdoZW4gdGhlIGNhc2UgZXhpc3RzLFxuICogLSB0aGUgcGx1cmFsIGNhdGVnb3J5IG90aGVyd2lzZVxuICovXG5mdW5jdGlvbiBnZXRQbHVyYWxDYXRlZ29yeSh2YWx1ZSwgY2FzZXMsIG5nTG9jYWxpemF0aW9uLCBsb2NhbGUpIHtcbiAgbGV0IGtleSA9IGA9JHt2YWx1ZX1gO1xuICBpZiAoY2FzZXMuaW5kZXhPZihrZXkpID4gLTEpIHtcbiAgICByZXR1cm4ga2V5O1xuICB9XG4gIGtleSA9IG5nTG9jYWxpemF0aW9uLmdldFBsdXJhbENhdGVnb3J5KHZhbHVlLCBsb2NhbGUpO1xuICBpZiAoY2FzZXMuaW5kZXhPZihrZXkpID4gLTEpIHtcbiAgICByZXR1cm4ga2V5O1xuICB9XG4gIGlmIChjYXNlcy5pbmRleE9mKCdvdGhlcicpID4gLTEpIHtcbiAgICByZXR1cm4gJ290aGVyJztcbiAgfVxuICB0aHJvdyBuZXcgRXJyb3IoYE5vIHBsdXJhbCBtZXNzYWdlIGZvdW5kIGZvciB2YWx1ZSBcIiR7dmFsdWV9XCJgKTtcbn1cbi8qKlxuICogUmV0dXJucyB0aGUgcGx1cmFsIGNhc2UgYmFzZWQgb24gdGhlIGxvY2FsZVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgTmdMb2NhbGVMb2NhbGl6YXRpb24gZXh0ZW5kcyBOZ0xvY2FsaXphdGlvbiB7XG4gIGNvbnN0cnVjdG9yKGxvY2FsZSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5sb2NhbGUgPSBsb2NhbGU7XG4gIH1cbiAgZ2V0UGx1cmFsQ2F0ZWdvcnkodmFsdWUsIGxvY2FsZSkge1xuICAgIGNvbnN0IHBsdXJhbCA9IGdldExvY2FsZVBsdXJhbENhc2UobG9jYWxlIHx8IHRoaXMubG9jYWxlKSh2YWx1ZSk7XG4gICAgc3dpdGNoIChwbHVyYWwpIHtcbiAgICAgIGNhc2UgUGx1cmFsLlplcm86XG4gICAgICAgIHJldHVybiAnemVybyc7XG4gICAgICBjYXNlIFBsdXJhbC5PbmU6XG4gICAgICAgIHJldHVybiAnb25lJztcbiAgICAgIGNhc2UgUGx1cmFsLlR3bzpcbiAgICAgICAgcmV0dXJuICd0d28nO1xuICAgICAgY2FzZSBQbHVyYWwuRmV3OlxuICAgICAgICByZXR1cm4gJ2Zldyc7XG4gICAgICBjYXNlIFBsdXJhbC5NYW55OlxuICAgICAgICByZXR1cm4gJ21hbnknO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICdvdGhlcic7XG4gICAgfVxuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIE5nTG9jYWxlTG9jYWxpemF0aW9uX0ZhY3RvcnkodCkge1xuICAgICAgcmV0dXJuIG5ldyAodCB8fCBOZ0xvY2FsZUxvY2FsaXphdGlvbikoaTAuybXJtWluamVjdChMT0NBTEVfSUQpKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXByb3YgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lSW5qZWN0YWJsZSh7XG4gICAgICB0b2tlbjogTmdMb2NhbGVMb2NhbGl6YXRpb24sXG4gICAgICBmYWN0b3J5OiBOZ0xvY2FsZUxvY2FsaXphdGlvbi7JtWZhY1xuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShOZ0xvY2FsZUxvY2FsaXphdGlvbiwgW3tcbiAgICB0eXBlOiBJbmplY3RhYmxlXG4gIH1dLCAoKSA9PiBbe1xuICAgIHR5cGU6IHVuZGVmaW5lZCxcbiAgICBkZWNvcmF0b3JzOiBbe1xuICAgICAgdHlwZTogSW5qZWN0LFxuICAgICAgYXJnczogW0xPQ0FMRV9JRF1cbiAgICB9XVxuICB9XSwgbnVsbCk7XG59KSgpO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGdsb2JhbCBkYXRhIHRvIGJlIHVzZWQgaW50ZXJuYWxseSBieSBBbmd1bGFyLiBTZWUgdGhlXG4gKiBbXCJJMThuIGd1aWRlXCJdKGd1aWRlL2kxOG4vZm9ybWF0LWRhdGEtbG9jYWxlKSB0byBrbm93IGhvdyB0byBpbXBvcnQgYWRkaXRpb25hbCBsb2NhbGVcbiAqIGRhdGEuXG4gKlxuICogVGhlIHNpZ25hdHVyZSByZWdpc3RlckxvY2FsZURhdGEoZGF0YTogYW55LCBleHRyYURhdGE/OiBhbnkpIGlzIGRlcHJlY2F0ZWQgc2luY2UgdjUuMVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJMb2NhbGVEYXRhKGRhdGEsIGxvY2FsZUlkLCBleHRyYURhdGEpIHtcbiAgcmV0dXJuIMm1cmVnaXN0ZXJMb2NhbGVEYXRhKGRhdGEsIGxvY2FsZUlkLCBleHRyYURhdGEpO1xufVxuZnVuY3Rpb24gcGFyc2VDb29raWVWYWx1ZShjb29raWVTdHIsIG5hbWUpIHtcbiAgbmFtZSA9IGVuY29kZVVSSUNvbXBvbmVudChuYW1lKTtcbiAgZm9yIChjb25zdCBjb29raWUgb2YgY29va2llU3RyLnNwbGl0KCc7JykpIHtcbiAgICBjb25zdCBlcUluZGV4ID0gY29va2llLmluZGV4T2YoJz0nKTtcbiAgICBjb25zdCBbY29va2llTmFtZSwgY29va2llVmFsdWVdID0gZXFJbmRleCA9PSAtMSA/IFtjb29raWUsICcnXSA6IFtjb29raWUuc2xpY2UoMCwgZXFJbmRleCksIGNvb2tpZS5zbGljZShlcUluZGV4ICsgMSldO1xuICAgIGlmIChjb29raWVOYW1lLnRyaW0oKSA9PT0gbmFtZSkge1xuICAgICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudChjb29raWVWYWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufVxuY29uc3QgV1NfUkVHRVhQID0gL1xccysvO1xuY29uc3QgRU1QVFlfQVJSQVkgPSBbXTtcbi8qKlxuICogQG5nTW9kdWxlIENvbW1vbk1vZHVsZVxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBgYGBcbiAqICAgICA8c29tZS1lbGVtZW50IFtuZ0NsYXNzXT1cIidmaXJzdCBzZWNvbmQnXCI+Li4uPC9zb21lLWVsZW1lbnQ+XG4gKlxuICogICAgIDxzb21lLWVsZW1lbnQgW25nQ2xhc3NdPVwiWydmaXJzdCcsICdzZWNvbmQnXVwiPi4uLjwvc29tZS1lbGVtZW50PlxuICpcbiAqICAgICA8c29tZS1lbGVtZW50IFtuZ0NsYXNzXT1cInsnZmlyc3QnOiB0cnVlLCAnc2Vjb25kJzogdHJ1ZSwgJ3RoaXJkJzogZmFsc2V9XCI+Li4uPC9zb21lLWVsZW1lbnQ+XG4gKlxuICogICAgIDxzb21lLWVsZW1lbnQgW25nQ2xhc3NdPVwic3RyaW5nRXhwfGFycmF5RXhwfG9iakV4cFwiPi4uLjwvc29tZS1lbGVtZW50PlxuICpcbiAqICAgICA8c29tZS1lbGVtZW50IFtuZ0NsYXNzXT1cInsnY2xhc3MxIGNsYXNzMiBjbGFzczMnIDogdHJ1ZX1cIj4uLi48L3NvbWUtZWxlbWVudD5cbiAqIGBgYFxuICpcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIEFkZHMgYW5kIHJlbW92ZXMgQ1NTIGNsYXNzZXMgb24gYW4gSFRNTCBlbGVtZW50LlxuICpcbiAqIFRoZSBDU1MgY2xhc3NlcyBhcmUgdXBkYXRlZCBhcyBmb2xsb3dzLCBkZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgdGhlIGV4cHJlc3Npb24gZXZhbHVhdGlvbjpcbiAqIC0gYHN0cmluZ2AgLSB0aGUgQ1NTIGNsYXNzZXMgbGlzdGVkIGluIHRoZSBzdHJpbmcgKHNwYWNlIGRlbGltaXRlZCkgYXJlIGFkZGVkLFxuICogLSBgQXJyYXlgIC0gdGhlIENTUyBjbGFzc2VzIGRlY2xhcmVkIGFzIEFycmF5IGVsZW1lbnRzIGFyZSBhZGRlZCxcbiAqIC0gYE9iamVjdGAgLSBrZXlzIGFyZSBDU1MgY2xhc3NlcyB0aGF0IGdldCBhZGRlZCB3aGVuIHRoZSBleHByZXNzaW9uIGdpdmVuIGluIHRoZSB2YWx1ZVxuICogICAgICAgICAgICAgIGV2YWx1YXRlcyB0byBhIHRydXRoeSB2YWx1ZSwgb3RoZXJ3aXNlIHRoZXkgYXJlIHJlbW92ZWQuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBOZ0NsYXNzIHtcbiAgY29uc3RydWN0b3IoX25nRWwsIF9yZW5kZXJlcikge1xuICAgIHRoaXMuX25nRWwgPSBfbmdFbDtcbiAgICB0aGlzLl9yZW5kZXJlciA9IF9yZW5kZXJlcjtcbiAgICB0aGlzLmluaXRpYWxDbGFzc2VzID0gRU1QVFlfQVJSQVk7XG4gICAgdGhpcy5zdGF0ZU1hcCA9IG5ldyBNYXAoKTtcbiAgfVxuICBzZXQga2xhc3ModmFsdWUpIHtcbiAgICB0aGlzLmluaXRpYWxDbGFzc2VzID0gdmFsdWUgIT0gbnVsbCA/IHZhbHVlLnRyaW0oKS5zcGxpdChXU19SRUdFWFApIDogRU1QVFlfQVJSQVk7XG4gIH1cbiAgc2V0IG5nQ2xhc3ModmFsdWUpIHtcbiAgICB0aGlzLnJhd0NsYXNzID0gdHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyA/IHZhbHVlLnRyaW0oKS5zcGxpdChXU19SRUdFWFApIDogdmFsdWU7XG4gIH1cbiAgLypcbiAgVGhlIE5nQ2xhc3MgZGlyZWN0aXZlIHVzZXMgdGhlIGN1c3RvbSBjaGFuZ2UgZGV0ZWN0aW9uIGFsZ29yaXRobSBmb3IgaXRzIGlucHV0cy4gVGhlIGN1c3RvbVxuICBhbGdvcml0aG0gaXMgbmVjZXNzYXJ5IHNpbmNlIGlucHV0cyBhcmUgcmVwcmVzZW50ZWQgYXMgY29tcGxleCBvYmplY3Qgb3IgYXJyYXlzIHRoYXQgbmVlZCB0byBiZVxuICBkZWVwbHktY29tcGFyZWQuXG4gICAgIFRoaXMgYWxnb3JpdGhtIGlzIHBlcmYtc2Vuc2l0aXZlIHNpbmNlIE5nQ2xhc3MgaXMgdXNlZCB2ZXJ5IGZyZXF1ZW50bHkgYW5kIGl0cyBwb29yIHBlcmZvcm1hbmNlXG4gIG1pZ2h0IG5lZ2F0aXZlbHkgaW1wYWN0IHJ1bnRpbWUgcGVyZm9ybWFuY2Ugb2YgdGhlIGVudGlyZSBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlLiBUaGUgZGVzaWduIG9mXG4gIHRoaXMgYWxnb3JpdGhtIGlzIG1ha2luZyBzdXJlIHRoYXQ6XG4gIC0gdGhlcmUgaXMgbm8gdW5uZWNlc3NhcnkgRE9NIG1hbmlwdWxhdGlvbiAoQ1NTIGNsYXNzZXMgYXJlIGFkZGVkIC8gcmVtb3ZlZCBmcm9tIHRoZSBET00gb25seSB3aGVuXG4gIG5lZWRlZCksIGV2ZW4gaWYgcmVmZXJlbmNlcyB0byBib3VuZCBvYmplY3RzIGNoYW5nZTtcbiAgLSB0aGVyZSBpcyBubyBtZW1vcnkgYWxsb2NhdGlvbiBpZiBub3RoaW5nIGNoYW5nZXMgKGV2ZW4gcmVsYXRpdmVseSBtb2Rlc3QgbWVtb3J5IGFsbG9jYXRpb25cbiAgZHVyaW5nIHRoZSBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlIGNhbiByZXN1bHQgaW4gR0MgcGF1c2VzIGZvciBzb21lIG9mIHRoZSBDRCBjeWNsZXMpLlxuICAgICBUaGUgYWxnb3JpdGhtIHdvcmtzIGJ5IGl0ZXJhdGluZyBvdmVyIHRoZSBzZXQgb2YgYm91bmQgY2xhc3Nlcywgc3RhcmluZyB3aXRoIFtjbGFzc10gYmluZGluZyBhbmRcbiAgdGhlbiBnb2luZyBvdmVyIFtuZ0NsYXNzXSBiaW5kaW5nLiBGb3IgZWFjaCBDU1MgY2xhc3MgbmFtZTpcbiAgLSBjaGVjayBpZiBpdCB3YXMgc2VlbiBiZWZvcmUgKHRoaXMgaW5mb3JtYXRpb24gaXMgdHJhY2tlZCBpbiB0aGUgc3RhdGUgbWFwKSBhbmQgaWYgaXRzIHZhbHVlXG4gIGNoYW5nZWQ7XG4gIC0gbWFyayBpdCBhcyBcInRvdWNoZWRcIiAtIG5hbWVzIHRoYXQgYXJlIG5vdCBtYXJrZWQgYXJlIG5vdCBwcmVzZW50IGluIHRoZSBsYXRlc3Qgc2V0IG9mIGJpbmRpbmdcbiAgYW5kIHdlIGNhbiByZW1vdmUgc3VjaCBjbGFzcyBuYW1lIGZyb20gdGhlIGludGVybmFsIGRhdGEgc3RydWN0dXJlcztcbiAgICAgQWZ0ZXIgaXRlcmF0aW9uIG92ZXIgYWxsIHRoZSBDU1MgY2xhc3MgbmFtZXMgd2UndmUgZ290IGRhdGEgc3RydWN0dXJlIHdpdGggYWxsIHRoZSBpbmZvcm1hdGlvblxuICBuZWNlc3NhcnkgdG8gc3luY2hyb25pemUgY2hhbmdlcyB0byB0aGUgRE9NIC0gaXQgaXMgZW5vdWdoIHRvIGl0ZXJhdGUgb3ZlciB0aGUgc3RhdGUgbWFwLCBmbHVzaFxuICBjaGFuZ2VzIHRvIHRoZSBET00gYW5kIHJlc2V0IGludGVybmFsIGRhdGEgc3RydWN0dXJlcyBzbyB0aG9zZSBhcmUgcmVhZHkgZm9yIHRoZSBuZXh0IGNoYW5nZVxuICBkZXRlY3Rpb24gY3ljbGUuXG4gICAqL1xuICBuZ0RvQ2hlY2soKSB7XG4gICAgLy8gY2xhc3NlcyBmcm9tIHRoZSBbY2xhc3NdIGJpbmRpbmdcbiAgICBmb3IgKGNvbnN0IGtsYXNzIG9mIHRoaXMuaW5pdGlhbENsYXNzZXMpIHtcbiAgICAgIHRoaXMuX3VwZGF0ZVN0YXRlKGtsYXNzLCB0cnVlKTtcbiAgICB9XG4gICAgLy8gY2xhc3NlcyBmcm9tIHRoZSBbbmdDbGFzc10gYmluZGluZ1xuICAgIGNvbnN0IHJhd0NsYXNzID0gdGhpcy5yYXdDbGFzcztcbiAgICBpZiAoQXJyYXkuaXNBcnJheShyYXdDbGFzcykgfHwgcmF3Q2xhc3MgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICAgIGZvciAoY29uc3Qga2xhc3Mgb2YgcmF3Q2xhc3MpIHtcbiAgICAgICAgdGhpcy5fdXBkYXRlU3RhdGUoa2xhc3MsIHRydWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAocmF3Q2xhc3MgIT0gbnVsbCkge1xuICAgICAgZm9yIChjb25zdCBrbGFzcyBvZiBPYmplY3Qua2V5cyhyYXdDbGFzcykpIHtcbiAgICAgICAgdGhpcy5fdXBkYXRlU3RhdGUoa2xhc3MsIEJvb2xlYW4ocmF3Q2xhc3Nba2xhc3NdKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuX2FwcGx5U3RhdGVEaWZmKCk7XG4gIH1cbiAgX3VwZGF0ZVN0YXRlKGtsYXNzLCBuZXh0RW5hYmxlZCkge1xuICAgIGNvbnN0IHN0YXRlID0gdGhpcy5zdGF0ZU1hcC5nZXQoa2xhc3MpO1xuICAgIGlmIChzdGF0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoc3RhdGUuZW5hYmxlZCAhPT0gbmV4dEVuYWJsZWQpIHtcbiAgICAgICAgc3RhdGUuY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIHN0YXRlLmVuYWJsZWQgPSBuZXh0RW5hYmxlZDtcbiAgICAgIH1cbiAgICAgIHN0YXRlLnRvdWNoZWQgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0YXRlTWFwLnNldChrbGFzcywge1xuICAgICAgICBlbmFibGVkOiBuZXh0RW5hYmxlZCxcbiAgICAgICAgY2hhbmdlZDogdHJ1ZSxcbiAgICAgICAgdG91Y2hlZDogdHJ1ZVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIF9hcHBseVN0YXRlRGlmZigpIHtcbiAgICBmb3IgKGNvbnN0IHN0YXRlRW50cnkgb2YgdGhpcy5zdGF0ZU1hcCkge1xuICAgICAgY29uc3Qga2xhc3MgPSBzdGF0ZUVudHJ5WzBdO1xuICAgICAgY29uc3Qgc3RhdGUgPSBzdGF0ZUVudHJ5WzFdO1xuICAgICAgaWYgKHN0YXRlLmNoYW5nZWQpIHtcbiAgICAgICAgdGhpcy5fdG9nZ2xlQ2xhc3Moa2xhc3MsIHN0YXRlLmVuYWJsZWQpO1xuICAgICAgICBzdGF0ZS5jaGFuZ2VkID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKCFzdGF0ZS50b3VjaGVkKSB7XG4gICAgICAgIC8vIEEgY2xhc3MgdGhhdCB3YXMgcHJldmlvdXNseSBhY3RpdmUgZ290IHJlbW92ZWQgZnJvbSB0aGUgbmV3IGNvbGxlY3Rpb24gb2YgY2xhc3NlcyAtXG4gICAgICAgIC8vIHJlbW92ZSBmcm9tIHRoZSBET00gYXMgd2VsbC5cbiAgICAgICAgaWYgKHN0YXRlLmVuYWJsZWQpIHtcbiAgICAgICAgICB0aGlzLl90b2dnbGVDbGFzcyhrbGFzcywgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3RhdGVNYXAuZGVsZXRlKGtsYXNzKTtcbiAgICAgIH1cbiAgICAgIHN0YXRlLnRvdWNoZWQgPSBmYWxzZTtcbiAgICB9XG4gIH1cbiAgX3RvZ2dsZUNsYXNzKGtsYXNzLCBlbmFibGVkKSB7XG4gICAgaWYgKG5nRGV2TW9kZSkge1xuICAgICAgaWYgKHR5cGVvZiBrbGFzcyAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBOZ0NsYXNzIGNhbiBvbmx5IHRvZ2dsZSBDU1MgY2xhc3NlcyBleHByZXNzZWQgYXMgc3RyaW5ncywgZ290ICR7ybVzdHJpbmdpZnkoa2xhc3MpfWApO1xuICAgICAgfVxuICAgIH1cbiAgICBrbGFzcyA9IGtsYXNzLnRyaW0oKTtcbiAgICBpZiAoa2xhc3MubGVuZ3RoID4gMCkge1xuICAgICAga2xhc3Muc3BsaXQoV1NfUkVHRVhQKS5mb3JFYWNoKGtsYXNzID0+IHtcbiAgICAgICAgaWYgKGVuYWJsZWQpIHtcbiAgICAgICAgICB0aGlzLl9yZW5kZXJlci5hZGRDbGFzcyh0aGlzLl9uZ0VsLm5hdGl2ZUVsZW1lbnQsIGtsYXNzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9yZW5kZXJlci5yZW1vdmVDbGFzcyh0aGlzLl9uZ0VsLm5hdGl2ZUVsZW1lbnQsIGtsYXNzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIE5nQ2xhc3NfRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IE5nQ2xhc3MpKGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoaTAuRWxlbWVudFJlZiksIGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoaTAuUmVuZGVyZXIyKSk7XG4gICAgfTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVkaXIgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lRGlyZWN0aXZlKHtcbiAgICAgIHR5cGU6IE5nQ2xhc3MsXG4gICAgICBzZWxlY3RvcnM6IFtbXCJcIiwgXCJuZ0NsYXNzXCIsIFwiXCJdXSxcbiAgICAgIGlucHV0czoge1xuICAgICAgICBrbGFzczogWzAsIFwiY2xhc3NcIiwgXCJrbGFzc1wiXSxcbiAgICAgICAgbmdDbGFzczogXCJuZ0NsYXNzXCJcbiAgICAgIH0sXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKE5nQ2xhc3MsIFt7XG4gICAgdHlwZTogRGlyZWN0aXZlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBzZWxlY3RvcjogJ1tuZ0NsYXNzXScsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfV1cbiAgfV0sICgpID0+IFt7XG4gICAgdHlwZTogaTAuRWxlbWVudFJlZlxuICB9LCB7XG4gICAgdHlwZTogaTAuUmVuZGVyZXIyXG4gIH1dLCB7XG4gICAga2xhc3M6IFt7XG4gICAgICB0eXBlOiBJbnB1dCxcbiAgICAgIGFyZ3M6IFsnY2xhc3MnXVxuICAgIH1dLFxuICAgIG5nQ2xhc3M6IFt7XG4gICAgICB0eXBlOiBJbnB1dCxcbiAgICAgIGFyZ3M6IFsnbmdDbGFzcyddXG4gICAgfV1cbiAgfSk7XG59KSgpO1xuXG4vKipcbiAqIEluc3RhbnRpYXRlcyBhIHtAbGluayBDb21wb25lbnR9IHR5cGUgYW5kIGluc2VydHMgaXRzIEhvc3QgVmlldyBpbnRvIHRoZSBjdXJyZW50IFZpZXcuXG4gKiBgTmdDb21wb25lbnRPdXRsZXRgIHByb3ZpZGVzIGEgZGVjbGFyYXRpdmUgYXBwcm9hY2ggZm9yIGR5bmFtaWMgY29tcG9uZW50IGNyZWF0aW9uLlxuICpcbiAqIGBOZ0NvbXBvbmVudE91dGxldGAgcmVxdWlyZXMgYSBjb21wb25lbnQgdHlwZSwgaWYgYSBmYWxzeSB2YWx1ZSBpcyBzZXQgdGhlIHZpZXcgd2lsbCBjbGVhciBhbmRcbiAqIGFueSBleGlzdGluZyBjb21wb25lbnQgd2lsbCBiZSBkZXN0cm95ZWQuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiAjIyMgRmluZSB0dW5lIGNvbnRyb2xcbiAqXG4gKiBZb3UgY2FuIGNvbnRyb2wgdGhlIGNvbXBvbmVudCBjcmVhdGlvbiBwcm9jZXNzIGJ5IHVzaW5nIHRoZSBmb2xsb3dpbmcgb3B0aW9uYWwgYXR0cmlidXRlczpcbiAqXG4gKiAqIGBuZ0NvbXBvbmVudE91dGxldElucHV0c2A6IE9wdGlvbmFsIGNvbXBvbmVudCBpbnB1dHMgb2JqZWN0LCB3aGljaCB3aWxsIGJlIGJpbmQgdG8gdGhlXG4gKiBjb21wb25lbnQuXG4gKlxuICogKiBgbmdDb21wb25lbnRPdXRsZXRJbmplY3RvcmA6IE9wdGlvbmFsIGN1c3RvbSB7QGxpbmsgSW5qZWN0b3J9IHRoYXQgd2lsbCBiZSB1c2VkIGFzIHBhcmVudCBmb3JcbiAqIHRoZSBDb21wb25lbnQuIERlZmF1bHRzIHRvIHRoZSBpbmplY3RvciBvZiB0aGUgY3VycmVudCB2aWV3IGNvbnRhaW5lci5cbiAqXG4gKiAqIGBuZ0NvbXBvbmVudE91dGxldENvbnRlbnRgOiBPcHRpb25hbCBsaXN0IG9mIHByb2plY3RhYmxlIG5vZGVzIHRvIGluc2VydCBpbnRvIHRoZSBjb250ZW50XG4gKiBzZWN0aW9uIG9mIHRoZSBjb21wb25lbnQsIGlmIGl0IGV4aXN0cy5cbiAqXG4gKiAqIGBuZ0NvbXBvbmVudE91dGxldE5nTW9kdWxlYDogT3B0aW9uYWwgTmdNb2R1bGUgY2xhc3MgcmVmZXJlbmNlIHRvIGFsbG93IGxvYWRpbmcgYW5vdGhlclxuICogbW9kdWxlIGR5bmFtaWNhbGx5LCB0aGVuIGxvYWRpbmcgYSBjb21wb25lbnQgZnJvbSB0aGF0IG1vZHVsZS5cbiAqXG4gKiAqIGBuZ0NvbXBvbmVudE91dGxldE5nTW9kdWxlRmFjdG9yeWA6IERlcHJlY2F0ZWQgY29uZmlnIG9wdGlvbiB0aGF0IGFsbG93cyBwcm92aWRpbmcgb3B0aW9uYWxcbiAqIE5nTW9kdWxlIGZhY3RvcnkgdG8gYWxsb3cgbG9hZGluZyBhbm90aGVyIG1vZHVsZSBkeW5hbWljYWxseSwgdGhlbiBsb2FkaW5nIGEgY29tcG9uZW50IGZyb20gdGhhdFxuICogbW9kdWxlLiBVc2UgYG5nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGVgIGluc3RlYWQuXG4gKlxuICogIyMjIFN5bnRheFxuICpcbiAqIFNpbXBsZVxuICogYGBgXG4gKiA8bmctY29udGFpbmVyICpuZ0NvbXBvbmVudE91dGxldD1cImNvbXBvbmVudFR5cGVFeHByZXNzaW9uXCI+PC9uZy1jb250YWluZXI+XG4gKiBgYGBcbiAqXG4gKiBXaXRoIGlucHV0c1xuICogYGBgXG4gKiA8bmctY29udGFpbmVyICpuZ0NvbXBvbmVudE91dGxldD1cImNvbXBvbmVudFR5cGVFeHByZXNzaW9uO1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0czogaW5wdXRzRXhwcmVzc2lvbjtcIj5cbiAqIDwvbmctY29udGFpbmVyPlxuICogYGBgXG4gKlxuICogQ3VzdG9taXplZCBpbmplY3Rvci9jb250ZW50XG4gKiBgYGBcbiAqIDxuZy1jb250YWluZXIgKm5nQ29tcG9uZW50T3V0bGV0PVwiY29tcG9uZW50VHlwZUV4cHJlc3Npb247XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5qZWN0b3I6IGluamVjdG9yRXhwcmVzc2lvbjtcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb250ZW50OiBjb250ZW50Tm9kZXNFeHByZXNzaW9uO1wiPlxuICogPC9uZy1jb250YWluZXI+XG4gKiBgYGBcbiAqXG4gKiBDdXN0b21pemVkIE5nTW9kdWxlIHJlZmVyZW5jZVxuICogYGBgXG4gKiA8bmctY29udGFpbmVyICpuZ0NvbXBvbmVudE91dGxldD1cImNvbXBvbmVudFR5cGVFeHByZXNzaW9uO1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5nTW9kdWxlOiBuZ01vZHVsZUNsYXNzO1wiPlxuICogPC9uZy1jb250YWluZXI+XG4gKiBgYGBcbiAqXG4gKiAjIyMgQSBzaW1wbGUgZXhhbXBsZVxuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vbmdDb21wb25lbnRPdXRsZXQvdHMvbW9kdWxlLnRzIHJlZ2lvbj0nU2ltcGxlRXhhbXBsZSd9XG4gKlxuICogQSBtb3JlIGNvbXBsZXRlIGV4YW1wbGUgd2l0aCBhZGRpdGlvbmFsIG9wdGlvbnM6XG4gKlxuICoge0BleGFtcGxlIGNvbW1vbi9uZ0NvbXBvbmVudE91dGxldC90cy9tb2R1bGUudHMgcmVnaW9uPSdDb21wbGV0ZUV4YW1wbGUnfVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqL1xuY2xhc3MgTmdDb21wb25lbnRPdXRsZXQge1xuICBjb25zdHJ1Y3Rvcihfdmlld0NvbnRhaW5lclJlZikge1xuICAgIHRoaXMuX3ZpZXdDb250YWluZXJSZWYgPSBfdmlld0NvbnRhaW5lclJlZjtcbiAgICB0aGlzLm5nQ29tcG9uZW50T3V0bGV0ID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBBIGhlbHBlciBkYXRhIHN0cnVjdHVyZSB0aGF0IGFsbG93cyB1cyB0byB0cmFjayBpbnB1dHMgdGhhdCB3ZXJlIHBhcnQgb2YgdGhlXG4gICAgICogbmdDb21wb25lbnRPdXRsZXRJbnB1dHMgZXhwcmVzc2lvbi4gVHJhY2tpbmcgaW5wdXRzIGlzIG5lY2Vzc2FyeSBmb3IgcHJvcGVyIHJlbW92YWwgb2Ygb25lc1xuICAgICAqIHRoYXQgYXJlIG5vIGxvbmdlciByZWZlcmVuY2VkLlxuICAgICAqL1xuICAgIHRoaXMuX2lucHV0c1VzZWQgPSBuZXcgTWFwKCk7XG4gIH1cbiAgX25lZWRUb1JlQ3JlYXRlTmdNb2R1bGVJbnN0YW5jZShjaGFuZ2VzKSB7XG4gICAgLy8gTm90ZTogc3F1YXJlIGJyYWNrZXRzIHByb3BlcnR5IGFjY2Vzc29yIGlzIHNhZmUgZm9yIENsb3N1cmUgY29tcGlsZXIgb3B0aW1pemF0aW9ucyAodGhlXG4gICAgLy8gYGNoYW5nZXNgIGFyZ3VtZW50IG9mIHRoZSBgbmdPbkNoYW5nZXNgIGxpZmVjeWNsZSBob29rIHJldGFpbnMgdGhlIG5hbWVzIG9mIHRoZSBmaWVsZHMgdGhhdFxuICAgIC8vIHdlcmUgY2hhbmdlZCkuXG4gICAgcmV0dXJuIGNoYW5nZXNbJ25nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGUnXSAhPT0gdW5kZWZpbmVkIHx8IGNoYW5nZXNbJ25nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGVGYWN0b3J5J10gIT09IHVuZGVmaW5lZDtcbiAgfVxuICBfbmVlZFRvUmVDcmVhdGVDb21wb25lbnRJbnN0YW5jZShjaGFuZ2VzKSB7XG4gICAgLy8gTm90ZTogc3F1YXJlIGJyYWNrZXRzIHByb3BlcnR5IGFjY2Vzc29yIGlzIHNhZmUgZm9yIENsb3N1cmUgY29tcGlsZXIgb3B0aW1pemF0aW9ucyAodGhlXG4gICAgLy8gYGNoYW5nZXNgIGFyZ3VtZW50IG9mIHRoZSBgbmdPbkNoYW5nZXNgIGxpZmVjeWNsZSBob29rIHJldGFpbnMgdGhlIG5hbWVzIG9mIHRoZSBmaWVsZHMgdGhhdFxuICAgIC8vIHdlcmUgY2hhbmdlZCkuXG4gICAgcmV0dXJuIGNoYW5nZXNbJ25nQ29tcG9uZW50T3V0bGV0J10gIT09IHVuZGVmaW5lZCB8fCBjaGFuZ2VzWyduZ0NvbXBvbmVudE91dGxldENvbnRlbnQnXSAhPT0gdW5kZWZpbmVkIHx8IGNoYW5nZXNbJ25nQ29tcG9uZW50T3V0bGV0SW5qZWN0b3InXSAhPT0gdW5kZWZpbmVkIHx8IHRoaXMuX25lZWRUb1JlQ3JlYXRlTmdNb2R1bGVJbnN0YW5jZShjaGFuZ2VzKTtcbiAgfVxuICAvKiogQG5vZG9jICovXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXMpIHtcbiAgICBpZiAodGhpcy5fbmVlZFRvUmVDcmVhdGVDb21wb25lbnRJbnN0YW5jZShjaGFuZ2VzKSkge1xuICAgICAgdGhpcy5fdmlld0NvbnRhaW5lclJlZi5jbGVhcigpO1xuICAgICAgdGhpcy5faW5wdXRzVXNlZC5jbGVhcigpO1xuICAgICAgdGhpcy5fY29tcG9uZW50UmVmID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKHRoaXMubmdDb21wb25lbnRPdXRsZXQpIHtcbiAgICAgICAgY29uc3QgaW5qZWN0b3IgPSB0aGlzLm5nQ29tcG9uZW50T3V0bGV0SW5qZWN0b3IgfHwgdGhpcy5fdmlld0NvbnRhaW5lclJlZi5wYXJlbnRJbmplY3RvcjtcbiAgICAgICAgaWYgKHRoaXMuX25lZWRUb1JlQ3JlYXRlTmdNb2R1bGVJbnN0YW5jZShjaGFuZ2VzKSkge1xuICAgICAgICAgIHRoaXMuX21vZHVsZVJlZj8uZGVzdHJveSgpO1xuICAgICAgICAgIGlmICh0aGlzLm5nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGUpIHtcbiAgICAgICAgICAgIHRoaXMuX21vZHVsZVJlZiA9IGNyZWF0ZU5nTW9kdWxlKHRoaXMubmdDb21wb25lbnRPdXRsZXROZ01vZHVsZSwgZ2V0UGFyZW50SW5qZWN0b3IoaW5qZWN0b3IpKTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMubmdDb21wb25lbnRPdXRsZXROZ01vZHVsZUZhY3RvcnkpIHtcbiAgICAgICAgICAgIHRoaXMuX21vZHVsZVJlZiA9IHRoaXMubmdDb21wb25lbnRPdXRsZXROZ01vZHVsZUZhY3RvcnkuY3JlYXRlKGdldFBhcmVudEluamVjdG9yKGluamVjdG9yKSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX21vZHVsZVJlZiA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fY29tcG9uZW50UmVmID0gdGhpcy5fdmlld0NvbnRhaW5lclJlZi5jcmVhdGVDb21wb25lbnQodGhpcy5uZ0NvbXBvbmVudE91dGxldCwge1xuICAgICAgICAgIGluamVjdG9yLFxuICAgICAgICAgIG5nTW9kdWxlUmVmOiB0aGlzLl9tb2R1bGVSZWYsXG4gICAgICAgICAgcHJvamVjdGFibGVOb2RlczogdGhpcy5uZ0NvbXBvbmVudE91dGxldENvbnRlbnRcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8qKiBAbm9kb2MgKi9cbiAgbmdEb0NoZWNrKCkge1xuICAgIGlmICh0aGlzLl9jb21wb25lbnRSZWYpIHtcbiAgICAgIGlmICh0aGlzLm5nQ29tcG9uZW50T3V0bGV0SW5wdXRzKSB7XG4gICAgICAgIGZvciAoY29uc3QgaW5wdXROYW1lIG9mIE9iamVjdC5rZXlzKHRoaXMubmdDb21wb25lbnRPdXRsZXRJbnB1dHMpKSB7XG4gICAgICAgICAgdGhpcy5faW5wdXRzVXNlZC5zZXQoaW5wdXROYW1lLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5fYXBwbHlJbnB1dFN0YXRlRGlmZih0aGlzLl9jb21wb25lbnRSZWYpO1xuICAgIH1cbiAgfVxuICAvKiogQG5vZG9jICovXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX21vZHVsZVJlZj8uZGVzdHJveSgpO1xuICB9XG4gIF9hcHBseUlucHV0U3RhdGVEaWZmKGNvbXBvbmVudFJlZikge1xuICAgIGZvciAoY29uc3QgW2lucHV0TmFtZSwgdG91Y2hlZF0gb2YgdGhpcy5faW5wdXRzVXNlZCkge1xuICAgICAgaWYgKCF0b3VjaGVkKSB7XG4gICAgICAgIC8vIFRoZSBpbnB1dCB0aGF0IHdhcyBwcmV2aW91c2x5IGFjdGl2ZSBubyBsb25nZXIgZXhpc3RzIGFuZCBuZWVkcyB0byBiZSBzZXQgdG8gdW5kZWZpbmVkLlxuICAgICAgICBjb21wb25lbnRSZWYuc2V0SW5wdXQoaW5wdXROYW1lLCB1bmRlZmluZWQpO1xuICAgICAgICB0aGlzLl9pbnB1dHNVc2VkLmRlbGV0ZShpbnB1dE5hbWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gU2luY2UgdG91Y2hlZCBpcyB0cnVlLCBpdCBjYW4gYmUgYXNzZXJ0ZWQgdGhhdCB0aGUgaW5wdXRzIG9iamVjdCBpcyBub3QgZW1wdHkuXG4gICAgICAgIGNvbXBvbmVudFJlZi5zZXRJbnB1dChpbnB1dE5hbWUsIHRoaXMubmdDb21wb25lbnRPdXRsZXRJbnB1dHNbaW5wdXROYW1lXSk7XG4gICAgICAgIHRoaXMuX2lucHV0c1VzZWQuc2V0KGlucHV0TmFtZSwgZmFsc2UpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBOZ0NvbXBvbmVudE91dGxldF9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgTmdDb21wb25lbnRPdXRsZXQpKGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoaTAuVmlld0NvbnRhaW5lclJlZikpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZGlyID0gLyogQF9fUFVSRV9fICovaTAuybXJtWRlZmluZURpcmVjdGl2ZSh7XG4gICAgICB0eXBlOiBOZ0NvbXBvbmVudE91dGxldCxcbiAgICAgIHNlbGVjdG9yczogW1tcIlwiLCBcIm5nQ29tcG9uZW50T3V0bGV0XCIsIFwiXCJdXSxcbiAgICAgIGlucHV0czoge1xuICAgICAgICBuZ0NvbXBvbmVudE91dGxldDogXCJuZ0NvbXBvbmVudE91dGxldFwiLFxuICAgICAgICBuZ0NvbXBvbmVudE91dGxldElucHV0czogXCJuZ0NvbXBvbmVudE91dGxldElucHV0c1wiLFxuICAgICAgICBuZ0NvbXBvbmVudE91dGxldEluamVjdG9yOiBcIm5nQ29tcG9uZW50T3V0bGV0SW5qZWN0b3JcIixcbiAgICAgICAgbmdDb21wb25lbnRPdXRsZXRDb250ZW50OiBcIm5nQ29tcG9uZW50T3V0bGV0Q29udGVudFwiLFxuICAgICAgICBuZ0NvbXBvbmVudE91dGxldE5nTW9kdWxlOiBcIm5nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGVcIixcbiAgICAgICAgbmdDb21wb25lbnRPdXRsZXROZ01vZHVsZUZhY3Rvcnk6IFwibmdDb21wb25lbnRPdXRsZXROZ01vZHVsZUZhY3RvcnlcIlxuICAgICAgfSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgICBmZWF0dXJlczogW2kwLsm1ybVOZ09uQ2hhbmdlc0ZlYXR1cmVdXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKE5nQ29tcG9uZW50T3V0bGV0LCBbe1xuICAgIHR5cGU6IERpcmVjdGl2ZSxcbiAgICBhcmdzOiBbe1xuICAgICAgc2VsZWN0b3I6ICdbbmdDb21wb25lbnRPdXRsZXRdJyxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgKCkgPT4gW3tcbiAgICB0eXBlOiBpMC5WaWV3Q29udGFpbmVyUmVmXG4gIH1dLCB7XG4gICAgbmdDb21wb25lbnRPdXRsZXQ6IFt7XG4gICAgICB0eXBlOiBJbnB1dFxuICAgIH1dLFxuICAgIG5nQ29tcG9uZW50T3V0bGV0SW5wdXRzOiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XSxcbiAgICBuZ0NvbXBvbmVudE91dGxldEluamVjdG9yOiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XSxcbiAgICBuZ0NvbXBvbmVudE91dGxldENvbnRlbnQ6IFt7XG4gICAgICB0eXBlOiBJbnB1dFxuICAgIH1dLFxuICAgIG5nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGU6IFt7XG4gICAgICB0eXBlOiBJbnB1dFxuICAgIH1dLFxuICAgIG5nQ29tcG9uZW50T3V0bGV0TmdNb2R1bGVGYWN0b3J5OiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XVxuICB9KTtcbn0pKCk7XG4vLyBIZWxwZXIgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGFuIEluamVjdG9yIGluc3RhbmNlIG9mIGEgcGFyZW50IE5nTW9kdWxlLlxuZnVuY3Rpb24gZ2V0UGFyZW50SW5qZWN0b3IoaW5qZWN0b3IpIHtcbiAgY29uc3QgcGFyZW50TmdNb2R1bGUgPSBpbmplY3Rvci5nZXQoTmdNb2R1bGVSZWYpO1xuICByZXR1cm4gcGFyZW50TmdNb2R1bGUuaW5qZWN0b3I7XG59XG5cbi8qKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBOZ0Zvck9mQ29udGV4dCB7XG4gIGNvbnN0cnVjdG9yKCRpbXBsaWNpdCwgbmdGb3JPZiwgaW5kZXgsIGNvdW50KSB7XG4gICAgdGhpcy4kaW1wbGljaXQgPSAkaW1wbGljaXQ7XG4gICAgdGhpcy5uZ0Zvck9mID0gbmdGb3JPZjtcbiAgICB0aGlzLmluZGV4ID0gaW5kZXg7XG4gICAgdGhpcy5jb3VudCA9IGNvdW50O1xuICB9XG4gIGdldCBmaXJzdCgpIHtcbiAgICByZXR1cm4gdGhpcy5pbmRleCA9PT0gMDtcbiAgfVxuICBnZXQgbGFzdCgpIHtcbiAgICByZXR1cm4gdGhpcy5pbmRleCA9PT0gdGhpcy5jb3VudCAtIDE7XG4gIH1cbiAgZ2V0IGV2ZW4oKSB7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXggJSAyID09PSAwO1xuICB9XG4gIGdldCBvZGQoKSB7XG4gICAgcmV0dXJuICF0aGlzLmV2ZW47XG4gIH1cbn1cbi8qKlxuICogQSBbc3RydWN0dXJhbCBkaXJlY3RpdmVdKGd1aWRlL2RpcmVjdGl2ZXMvc3RydWN0dXJhbC1kaXJlY3RpdmVzKSB0aGF0IHJlbmRlcnNcbiAqIGEgdGVtcGxhdGUgZm9yIGVhY2ggaXRlbSBpbiBhIGNvbGxlY3Rpb24uXG4gKiBUaGUgZGlyZWN0aXZlIGlzIHBsYWNlZCBvbiBhbiBlbGVtZW50LCB3aGljaCBiZWNvbWVzIHRoZSBwYXJlbnRcbiAqIG9mIHRoZSBjbG9uZWQgdGVtcGxhdGVzLlxuICpcbiAqIFRoZSBgbmdGb3JPZmAgZGlyZWN0aXZlIGlzIGdlbmVyYWxseSB1c2VkIGluIHRoZVxuICogW3Nob3J0aGFuZCBmb3JtXShndWlkZS9kaXJlY3RpdmVzL3N0cnVjdHVyYWwtZGlyZWN0aXZlcyNhc3RlcmlzaykgYCpuZ0ZvcmAuXG4gKiBJbiB0aGlzIGZvcm0sIHRoZSB0ZW1wbGF0ZSB0byBiZSByZW5kZXJlZCBmb3IgZWFjaCBpdGVyYXRpb24gaXMgdGhlIGNvbnRlbnRcbiAqIG9mIGFuIGFuY2hvciBlbGVtZW50IGNvbnRhaW5pbmcgdGhlIGRpcmVjdGl2ZS5cbiAqXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2hvd3MgdGhlIHNob3J0aGFuZCBzeW50YXggd2l0aCBzb21lIG9wdGlvbnMsXG4gKiBjb250YWluZWQgaW4gYW4gYDxsaT5gIGVsZW1lbnQuXG4gKlxuICogYGBgXG4gKiA8bGkgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXM7IGluZGV4IGFzIGk7IHRyYWNrQnk6IHRyYWNrQnlGblwiPi4uLjwvbGk+XG4gKiBgYGBcbiAqXG4gKiBUaGUgc2hvcnRoYW5kIGZvcm0gZXhwYW5kcyBpbnRvIGEgbG9uZyBmb3JtIHRoYXQgdXNlcyB0aGUgYG5nRm9yT2ZgIHNlbGVjdG9yXG4gKiBvbiBhbiBgPG5nLXRlbXBsYXRlPmAgZWxlbWVudC5cbiAqIFRoZSBjb250ZW50IG9mIHRoZSBgPG5nLXRlbXBsYXRlPmAgZWxlbWVudCBpcyB0aGUgYDxsaT5gIGVsZW1lbnQgdGhhdCBoZWxkIHRoZVxuICogc2hvcnQtZm9ybSBkaXJlY3RpdmUuXG4gKlxuICogSGVyZSBpcyB0aGUgZXhwYW5kZWQgdmVyc2lvbiBvZiB0aGUgc2hvcnQtZm9ybSBleGFtcGxlLlxuICpcbiAqIGBgYFxuICogPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1pdGVtIFtuZ0Zvck9mXT1cIml0ZW1zXCIgbGV0LWk9XCJpbmRleFwiIFtuZ0ZvclRyYWNrQnldPVwidHJhY2tCeUZuXCI+XG4gKiAgIDxsaT4uLi48L2xpPlxuICogPC9uZy10ZW1wbGF0ZT5cbiAqIGBgYFxuICpcbiAqIEFuZ3VsYXIgYXV0b21hdGljYWxseSBleHBhbmRzIHRoZSBzaG9ydGhhbmQgc3ludGF4IGFzIGl0IGNvbXBpbGVzIHRoZSB0ZW1wbGF0ZS5cbiAqIFRoZSBjb250ZXh0IGZvciBlYWNoIGVtYmVkZGVkIHZpZXcgaXMgbG9naWNhbGx5IG1lcmdlZCB0byB0aGUgY3VycmVudCBjb21wb25lbnRcbiAqIGNvbnRleHQgYWNjb3JkaW5nIHRvIGl0cyBsZXhpY2FsIHBvc2l0aW9uLlxuICpcbiAqIFdoZW4gdXNpbmcgdGhlIHNob3J0aGFuZCBzeW50YXgsIEFuZ3VsYXIgYWxsb3dzIG9ubHkgW29uZSBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZVxuICogb24gYW4gZWxlbWVudF0oZ3VpZGUvZGlyZWN0aXZlcy9zdHJ1Y3R1cmFsLWRpcmVjdGl2ZXMjb25lLXBlci1lbGVtZW50KS5cbiAqIElmIHlvdSB3YW50IHRvIGl0ZXJhdGUgY29uZGl0aW9uYWxseSwgZm9yIGV4YW1wbGUsXG4gKiBwdXQgdGhlIGAqbmdJZmAgb24gYSBjb250YWluZXIgZWxlbWVudCB0aGF0IHdyYXBzIHRoZSBgKm5nRm9yYCBlbGVtZW50LlxuICogRm9yIGZ1cnRoZXIgZGlzY3Vzc2lvbiwgc2VlXG4gKiBbU3RydWN0dXJhbCBEaXJlY3RpdmVzXShndWlkZS9kaXJlY3RpdmVzL3N0cnVjdHVyYWwtZGlyZWN0aXZlcyNvbmUtcGVyLWVsZW1lbnQpLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogIyMjIExvY2FsIHZhcmlhYmxlc1xuICpcbiAqIGBOZ0Zvck9mYCBwcm92aWRlcyBleHBvcnRlZCB2YWx1ZXMgdGhhdCBjYW4gYmUgYWxpYXNlZCB0byBsb2NhbCB2YXJpYWJsZXMuXG4gKiBGb3IgZXhhbXBsZTpcbiAqXG4gKiAgYGBgXG4gKiA8bGkgKm5nRm9yPVwibGV0IHVzZXIgb2YgdXNlcnM7IGluZGV4IGFzIGk7IGZpcnN0IGFzIGlzRmlyc3RcIj5cbiAqICAgIHt7aX19L3t7dXNlcnMubGVuZ3RofX0uIHt7dXNlcn19IDxzcGFuICpuZ0lmPVwiaXNGaXJzdFwiPmRlZmF1bHQ8L3NwYW4+XG4gKiA8L2xpPlxuICogYGBgXG4gKlxuICogVGhlIGZvbGxvd2luZyBleHBvcnRlZCB2YWx1ZXMgY2FuIGJlIGFsaWFzZWQgdG8gbG9jYWwgdmFyaWFibGVzOlxuICpcbiAqIC0gYCRpbXBsaWNpdDogVGA6IFRoZSB2YWx1ZSBvZiB0aGUgaW5kaXZpZHVhbCBpdGVtcyBpbiB0aGUgaXRlcmFibGUgKGBuZ0Zvck9mYCkuXG4gKiAtIGBuZ0Zvck9mOiBOZ0l0ZXJhYmxlPFQ+YDogVGhlIHZhbHVlIG9mIHRoZSBpdGVyYWJsZSBleHByZXNzaW9uLiBVc2VmdWwgd2hlbiB0aGUgZXhwcmVzc2lvbiBpc1xuICogbW9yZSBjb21wbGV4IHRoZW4gYSBwcm9wZXJ0eSBhY2Nlc3MsIGZvciBleGFtcGxlIHdoZW4gdXNpbmcgdGhlIGFzeW5jIHBpcGUgKGB1c2VyU3RyZWFtcyB8XG4gKiBhc3luY2ApLlxuICogLSBgaW5kZXg6IG51bWJlcmA6IFRoZSBpbmRleCBvZiB0aGUgY3VycmVudCBpdGVtIGluIHRoZSBpdGVyYWJsZS5cbiAqIC0gYGNvdW50OiBudW1iZXJgOiBUaGUgbGVuZ3RoIG9mIHRoZSBpdGVyYWJsZS5cbiAqIC0gYGZpcnN0OiBib29sZWFuYDogVHJ1ZSB3aGVuIHRoZSBpdGVtIGlzIHRoZSBmaXJzdCBpdGVtIGluIHRoZSBpdGVyYWJsZS5cbiAqIC0gYGxhc3Q6IGJvb2xlYW5gOiBUcnVlIHdoZW4gdGhlIGl0ZW0gaXMgdGhlIGxhc3QgaXRlbSBpbiB0aGUgaXRlcmFibGUuXG4gKiAtIGBldmVuOiBib29sZWFuYDogVHJ1ZSB3aGVuIHRoZSBpdGVtIGhhcyBhbiBldmVuIGluZGV4IGluIHRoZSBpdGVyYWJsZS5cbiAqIC0gYG9kZDogYm9vbGVhbmA6IFRydWUgd2hlbiB0aGUgaXRlbSBoYXMgYW4gb2RkIGluZGV4IGluIHRoZSBpdGVyYWJsZS5cbiAqXG4gKiAjIyMgQ2hhbmdlIHByb3BhZ2F0aW9uXG4gKlxuICogV2hlbiB0aGUgY29udGVudHMgb2YgdGhlIGl0ZXJhdG9yIGNoYW5nZXMsIGBOZ0Zvck9mYCBtYWtlcyB0aGUgY29ycmVzcG9uZGluZyBjaGFuZ2VzIHRvIHRoZSBET006XG4gKlxuICogKiBXaGVuIGFuIGl0ZW0gaXMgYWRkZWQsIGEgbmV3IGluc3RhbmNlIG9mIHRoZSB0ZW1wbGF0ZSBpcyBhZGRlZCB0byB0aGUgRE9NLlxuICogKiBXaGVuIGFuIGl0ZW0gaXMgcmVtb3ZlZCwgaXRzIHRlbXBsYXRlIGluc3RhbmNlIGlzIHJlbW92ZWQgZnJvbSB0aGUgRE9NLlxuICogKiBXaGVuIGl0ZW1zIGFyZSByZW9yZGVyZWQsIHRoZWlyIHJlc3BlY3RpdmUgdGVtcGxhdGVzIGFyZSByZW9yZGVyZWQgaW4gdGhlIERPTS5cbiAqXG4gKiBBbmd1bGFyIHVzZXMgb2JqZWN0IGlkZW50aXR5IHRvIHRyYWNrIGluc2VydGlvbnMgYW5kIGRlbGV0aW9ucyB3aXRoaW4gdGhlIGl0ZXJhdG9yIGFuZCByZXByb2R1Y2VcbiAqIHRob3NlIGNoYW5nZXMgaW4gdGhlIERPTS4gVGhpcyBoYXMgaW1wb3J0YW50IGltcGxpY2F0aW9ucyBmb3IgYW5pbWF0aW9ucyBhbmQgYW55IHN0YXRlZnVsXG4gKiBjb250cm9scyB0aGF0IGFyZSBwcmVzZW50LCBzdWNoIGFzIGA8aW5wdXQ+YCBlbGVtZW50cyB0aGF0IGFjY2VwdCB1c2VyIGlucHV0LiBJbnNlcnRlZCByb3dzIGNhblxuICogYmUgYW5pbWF0ZWQgaW4sIGRlbGV0ZWQgcm93cyBjYW4gYmUgYW5pbWF0ZWQgb3V0LCBhbmQgdW5jaGFuZ2VkIHJvd3MgcmV0YWluIGFueSB1bnNhdmVkIHN0YXRlXG4gKiBzdWNoIGFzIHVzZXIgaW5wdXQuXG4gKiBGb3IgbW9yZSBvbiBhbmltYXRpb25zLCBzZWUgW1RyYW5zaXRpb25zIGFuZCBUcmlnZ2Vyc10oZ3VpZGUvYW5pbWF0aW9ucy90cmFuc2l0aW9uLWFuZC10cmlnZ2VycykuXG4gKlxuICogVGhlIGlkZW50aXRpZXMgb2YgZWxlbWVudHMgaW4gdGhlIGl0ZXJhdG9yIGNhbiBjaGFuZ2Ugd2hpbGUgdGhlIGRhdGEgZG9lcyBub3QuXG4gKiBUaGlzIGNhbiBoYXBwZW4sIGZvciBleGFtcGxlLCBpZiB0aGUgaXRlcmF0b3IgaXMgcHJvZHVjZWQgZnJvbSBhbiBSUEMgdG8gdGhlIHNlcnZlciwgYW5kIHRoYXRcbiAqIFJQQyBpcyByZS1ydW4uIEV2ZW4gaWYgdGhlIGRhdGEgaGFzbid0IGNoYW5nZWQsIHRoZSBzZWNvbmQgcmVzcG9uc2UgcHJvZHVjZXMgb2JqZWN0cyB3aXRoXG4gKiBkaWZmZXJlbnQgaWRlbnRpdGllcywgYW5kIEFuZ3VsYXIgbXVzdCB0ZWFyIGRvd24gdGhlIGVudGlyZSBET00gYW5kIHJlYnVpbGQgaXQgKGFzIGlmIGFsbCBvbGRcbiAqIGVsZW1lbnRzIHdlcmUgZGVsZXRlZCBhbmQgYWxsIG5ldyBlbGVtZW50cyBpbnNlcnRlZCkuXG4gKlxuICogVG8gYXZvaWQgdGhpcyBleHBlbnNpdmUgb3BlcmF0aW9uLCB5b3UgY2FuIGN1c3RvbWl6ZSB0aGUgZGVmYXVsdCB0cmFja2luZyBhbGdvcml0aG0uXG4gKiBieSBzdXBwbHlpbmcgdGhlIGB0cmFja0J5YCBvcHRpb24gdG8gYE5nRm9yT2ZgLlxuICogYHRyYWNrQnlgIHRha2VzIGEgZnVuY3Rpb24gdGhhdCBoYXMgdHdvIGFyZ3VtZW50czogYGluZGV4YCBhbmQgYGl0ZW1gLlxuICogSWYgYHRyYWNrQnlgIGlzIGdpdmVuLCBBbmd1bGFyIHRyYWNrcyBjaGFuZ2VzIGJ5IHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZ1bmN0aW9uLlxuICpcbiAqIEBzZWUgW1N0cnVjdHVyYWwgRGlyZWN0aXZlc10oZ3VpZGUvZGlyZWN0aXZlcy9zdHJ1Y3R1cmFsLWRpcmVjdGl2ZXMpXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIE5nRm9yT2Yge1xuICAvKipcbiAgICogVGhlIHZhbHVlIG9mIHRoZSBpdGVyYWJsZSBleHByZXNzaW9uLCB3aGljaCBjYW4gYmUgdXNlZCBhcyBhXG4gICAqIFt0ZW1wbGF0ZSBpbnB1dCB2YXJpYWJsZV0oZ3VpZGUvZGlyZWN0aXZlcy9zdHJ1Y3R1cmFsLWRpcmVjdGl2ZXMjc2hvcnRoYW5kKS5cbiAgICovXG4gIHNldCBuZ0Zvck9mKG5nRm9yT2YpIHtcbiAgICB0aGlzLl9uZ0Zvck9mID0gbmdGb3JPZjtcbiAgICB0aGlzLl9uZ0Zvck9mRGlydHkgPSB0cnVlO1xuICB9XG4gIC8qKlxuICAgKiBTcGVjaWZpZXMgYSBjdXN0b20gYFRyYWNrQnlGdW5jdGlvbmAgdG8gY29tcHV0ZSB0aGUgaWRlbnRpdHkgb2YgaXRlbXMgaW4gYW4gaXRlcmFibGUuXG4gICAqXG4gICAqIElmIGEgY3VzdG9tIGBUcmFja0J5RnVuY3Rpb25gIGlzIG5vdCBwcm92aWRlZCwgYE5nRm9yT2ZgIHdpbGwgdXNlIHRoZSBpdGVtJ3MgW29iamVjdFxuICAgKiBpZGVudGl0eV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSmF2YVNjcmlwdC9SZWZlcmVuY2UvR2xvYmFsX09iamVjdHMvT2JqZWN0L2lzKVxuICAgKiBhcyB0aGUga2V5LlxuICAgKlxuICAgKiBgTmdGb3JPZmAgdXNlcyB0aGUgY29tcHV0ZWQga2V5IHRvIGFzc29jaWF0ZSBpdGVtcyBpbiBhbiBpdGVyYWJsZSB3aXRoIERPTSBlbGVtZW50c1xuICAgKiBpdCBwcm9kdWNlcyBmb3IgdGhlc2UgaXRlbXMuXG4gICAqXG4gICAqIEEgY3VzdG9tIGBUcmFja0J5RnVuY3Rpb25gIGlzIHVzZWZ1bCB0byBwcm92aWRlIGdvb2QgdXNlciBleHBlcmllbmNlIGluIGNhc2VzIHdoZW4gaXRlbXMgaW4gYW5cbiAgICogaXRlcmFibGUgcmVuZGVyZWQgdXNpbmcgYE5nRm9yT2ZgIGhhdmUgYSBuYXR1cmFsIGlkZW50aWZpZXIgKGZvciBleGFtcGxlLCBjdXN0b20gSUQgb3IgYVxuICAgKiBwcmltYXJ5IGtleSksIGFuZCB0aGlzIGl0ZXJhYmxlIGNvdWxkIGJlIHVwZGF0ZWQgd2l0aCBuZXcgb2JqZWN0IGluc3RhbmNlcyB0aGF0IHN0aWxsXG4gICAqIHJlcHJlc2VudCB0aGUgc2FtZSB1bmRlcmx5aW5nIGVudGl0eSAoZm9yIGV4YW1wbGUsIHdoZW4gZGF0YSBpcyByZS1mZXRjaGVkIGZyb20gdGhlIHNlcnZlcixcbiAgICogYW5kIHRoZSBpdGVyYWJsZSBpcyByZWNyZWF0ZWQgYW5kIHJlLXJlbmRlcmVkLCBidXQgbW9zdCBvZiB0aGUgZGF0YSBpcyBzdGlsbCB0aGUgc2FtZSkuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIFRyYWNrQnlGdW5jdGlvbn1cbiAgICovXG4gIHNldCBuZ0ZvclRyYWNrQnkoZm4pIHtcbiAgICBpZiAoKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSkgJiYgZm4gIT0gbnVsbCAmJiB0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICAgIGNvbnNvbGUud2FybihgdHJhY2tCeSBtdXN0IGJlIGEgZnVuY3Rpb24sIGJ1dCByZWNlaXZlZCAke0pTT04uc3RyaW5naWZ5KGZuKX0uIGAgKyBgU2VlIGh0dHBzOi8vYW5ndWxhci5pby9hcGkvY29tbW9uL05nRm9yT2YjY2hhbmdlLXByb3BhZ2F0aW9uIGZvciBtb3JlIGluZm9ybWF0aW9uLmApO1xuICAgIH1cbiAgICB0aGlzLl90cmFja0J5Rm4gPSBmbjtcbiAgfVxuICBnZXQgbmdGb3JUcmFja0J5KCkge1xuICAgIHJldHVybiB0aGlzLl90cmFja0J5Rm47XG4gIH1cbiAgY29uc3RydWN0b3IoX3ZpZXdDb250YWluZXIsIF90ZW1wbGF0ZSwgX2RpZmZlcnMpIHtcbiAgICB0aGlzLl92aWV3Q29udGFpbmVyID0gX3ZpZXdDb250YWluZXI7XG4gICAgdGhpcy5fdGVtcGxhdGUgPSBfdGVtcGxhdGU7XG4gICAgdGhpcy5fZGlmZmVycyA9IF9kaWZmZXJzO1xuICAgIHRoaXMuX25nRm9yT2YgPSBudWxsO1xuICAgIHRoaXMuX25nRm9yT2ZEaXJ0eSA9IHRydWU7XG4gICAgdGhpcy5fZGlmZmVyID0gbnVsbDtcbiAgfVxuICAvKipcbiAgICogQSByZWZlcmVuY2UgdG8gdGhlIHRlbXBsYXRlIHRoYXQgaXMgc3RhbXBlZCBvdXQgZm9yIGVhY2ggaXRlbSBpbiB0aGUgaXRlcmFibGUuXG4gICAqIEBzZWUgW3RlbXBsYXRlIHJlZmVyZW5jZSB2YXJpYWJsZV0oZ3VpZGUvdGVtcGxhdGVzL3JlZmVyZW5jZS12YXJpYWJsZXMpXG4gICAqL1xuICBzZXQgbmdGb3JUZW1wbGF0ZSh2YWx1ZSkge1xuICAgIC8vIFRPRE8oVFMyLjEpOiBtYWtlIFRlbXBsYXRlUmVmPFBhcnRpYWw8TmdGb3JSb3dPZjxUPj4+IG9uY2Ugd2UgbW92ZSB0byBUUyB2Mi4xXG4gICAgLy8gVGhlIGN1cnJlbnQgdHlwZSBpcyB0b28gcmVzdHJpY3RpdmU7IGEgdGVtcGxhdGUgdGhhdCBqdXN0IHVzZXMgaW5kZXgsIGZvciBleGFtcGxlLFxuICAgIC8vIHNob3VsZCBiZSBhY2NlcHRhYmxlLlxuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5fdGVtcGxhdGUgPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEFwcGxpZXMgdGhlIGNoYW5nZXMgd2hlbiBuZWVkZWQuXG4gICAqIEBub2RvY1xuICAgKi9cbiAgbmdEb0NoZWNrKCkge1xuICAgIGlmICh0aGlzLl9uZ0Zvck9mRGlydHkpIHtcbiAgICAgIHRoaXMuX25nRm9yT2ZEaXJ0eSA9IGZhbHNlO1xuICAgICAgLy8gUmVhY3Qgb24gbmdGb3JPZiBjaGFuZ2VzIG9ubHkgb25jZSBhbGwgaW5wdXRzIGhhdmUgYmVlbiBpbml0aWFsaXplZFxuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLl9uZ0Zvck9mO1xuICAgICAgaWYgKCF0aGlzLl9kaWZmZXIgJiYgdmFsdWUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBDQVVUSU9OOiB0aGlzIGxvZ2ljIGlzIGR1cGxpY2F0ZWQgZm9yIHByb2R1Y3Rpb24gbW9kZSBiZWxvdywgYXMgdGhlIHRyeS1jYXRjaFxuICAgICAgICAgICAgLy8gaXMgb25seSBwcmVzZW50IGluIGRldmVsb3BtZW50IGJ1aWxkcy5cbiAgICAgICAgICAgIHRoaXMuX2RpZmZlciA9IHRoaXMuX2RpZmZlcnMuZmluZCh2YWx1ZSkuY3JlYXRlKHRoaXMubmdGb3JUcmFja0J5KTtcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIGxldCBlcnJvck1lc3NhZ2UgPSBgQ2Fubm90IGZpbmQgYSBkaWZmZXIgc3VwcG9ydGluZyBvYmplY3QgJyR7dmFsdWV9JyBvZiB0eXBlICdgICsgYCR7Z2V0VHlwZU5hbWUodmFsdWUpfScuIE5nRm9yIG9ubHkgc3VwcG9ydHMgYmluZGluZyB0byBJdGVyYWJsZXMsIHN1Y2ggYXMgQXJyYXlzLmA7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgICBlcnJvck1lc3NhZ2UgKz0gJyBEaWQgeW91IG1lYW4gdG8gdXNlIHRoZSBrZXl2YWx1ZSBwaXBlPyc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgybVSdW50aW1lRXJyb3IoLTIyMDAgLyogUnVudGltZUVycm9yQ29kZS5OR19GT1JfTUlTU0lOR19ESUZGRVIgKi8sIGVycm9yTWVzc2FnZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIENBVVRJT046IHRoaXMgbG9naWMgaXMgZHVwbGljYXRlZCBmb3IgZGV2ZWxvcG1lbnQgbW9kZSBhYm92ZSwgYXMgdGhlIHRyeS1jYXRjaFxuICAgICAgICAgIC8vIGlzIG9ubHkgcHJlc2VudCBpbiBkZXZlbG9wbWVudCBidWlsZHMuXG4gICAgICAgICAgdGhpcy5fZGlmZmVyID0gdGhpcy5fZGlmZmVycy5maW5kKHZhbHVlKS5jcmVhdGUodGhpcy5uZ0ZvclRyYWNrQnkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0aGlzLl9kaWZmZXIpIHtcbiAgICAgIGNvbnN0IGNoYW5nZXMgPSB0aGlzLl9kaWZmZXIuZGlmZih0aGlzLl9uZ0Zvck9mKTtcbiAgICAgIGlmIChjaGFuZ2VzKSB0aGlzLl9hcHBseUNoYW5nZXMoY2hhbmdlcyk7XG4gICAgfVxuICB9XG4gIF9hcHBseUNoYW5nZXMoY2hhbmdlcykge1xuICAgIGNvbnN0IHZpZXdDb250YWluZXIgPSB0aGlzLl92aWV3Q29udGFpbmVyO1xuICAgIGNoYW5nZXMuZm9yRWFjaE9wZXJhdGlvbigoaXRlbSwgYWRqdXN0ZWRQcmV2aW91c0luZGV4LCBjdXJyZW50SW5kZXgpID0+IHtcbiAgICAgIGlmIChpdGVtLnByZXZpb3VzSW5kZXggPT0gbnVsbCkge1xuICAgICAgICAvLyBOZ0Zvck9mIGlzIG5ldmVyIFwibnVsbFwiIG9yIFwidW5kZWZpbmVkXCIgaGVyZSBiZWNhdXNlIHRoZSBkaWZmZXIgZGV0ZWN0ZWRcbiAgICAgICAgLy8gdGhhdCBhIG5ldyBpdGVtIG5lZWRzIHRvIGJlIGluc2VydGVkIGZyb20gdGhlIGl0ZXJhYmxlLiBUaGlzIGltcGxpZXMgdGhhdFxuICAgICAgICAvLyB0aGVyZSBpcyBhbiBpdGVyYWJsZSB2YWx1ZSBmb3IgXCJfbmdGb3JPZlwiLlxuICAgICAgICB2aWV3Q29udGFpbmVyLmNyZWF0ZUVtYmVkZGVkVmlldyh0aGlzLl90ZW1wbGF0ZSwgbmV3IE5nRm9yT2ZDb250ZXh0KGl0ZW0uaXRlbSwgdGhpcy5fbmdGb3JPZiwgLTEsIC0xKSwgY3VycmVudEluZGV4ID09PSBudWxsID8gdW5kZWZpbmVkIDogY3VycmVudEluZGV4KTtcbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudEluZGV4ID09IG51bGwpIHtcbiAgICAgICAgdmlld0NvbnRhaW5lci5yZW1vdmUoYWRqdXN0ZWRQcmV2aW91c0luZGV4ID09PSBudWxsID8gdW5kZWZpbmVkIDogYWRqdXN0ZWRQcmV2aW91c0luZGV4KTtcbiAgICAgIH0gZWxzZSBpZiAoYWRqdXN0ZWRQcmV2aW91c0luZGV4ICE9PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IHZpZXcgPSB2aWV3Q29udGFpbmVyLmdldChhZGp1c3RlZFByZXZpb3VzSW5kZXgpO1xuICAgICAgICB2aWV3Q29udGFpbmVyLm1vdmUodmlldywgY3VycmVudEluZGV4KTtcbiAgICAgICAgYXBwbHlWaWV3Q2hhbmdlKHZpZXcsIGl0ZW0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGZvciAobGV0IGkgPSAwLCBpbGVuID0gdmlld0NvbnRhaW5lci5sZW5ndGg7IGkgPCBpbGVuOyBpKyspIHtcbiAgICAgIGNvbnN0IHZpZXdSZWYgPSB2aWV3Q29udGFpbmVyLmdldChpKTtcbiAgICAgIGNvbnN0IGNvbnRleHQgPSB2aWV3UmVmLmNvbnRleHQ7XG4gICAgICBjb250ZXh0LmluZGV4ID0gaTtcbiAgICAgIGNvbnRleHQuY291bnQgPSBpbGVuO1xuICAgICAgY29udGV4dC5uZ0Zvck9mID0gdGhpcy5fbmdGb3JPZjtcbiAgICB9XG4gICAgY2hhbmdlcy5mb3JFYWNoSWRlbnRpdHlDaGFuZ2UocmVjb3JkID0+IHtcbiAgICAgIGNvbnN0IHZpZXdSZWYgPSB2aWV3Q29udGFpbmVyLmdldChyZWNvcmQuY3VycmVudEluZGV4KTtcbiAgICAgIGFwcGx5Vmlld0NoYW5nZSh2aWV3UmVmLCByZWNvcmQpO1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBBc3NlcnRzIHRoZSBjb3JyZWN0IHR5cGUgb2YgdGhlIGNvbnRleHQgZm9yIHRoZSB0ZW1wbGF0ZSB0aGF0IGBOZ0Zvck9mYCB3aWxsIHJlbmRlci5cbiAgICpcbiAgICogVGhlIHByZXNlbmNlIG9mIHRoaXMgbWV0aG9kIGlzIGEgc2lnbmFsIHRvIHRoZSBJdnkgdGVtcGxhdGUgdHlwZS1jaGVjayBjb21waWxlciB0aGF0IHRoZVxuICAgKiBgTmdGb3JPZmAgc3RydWN0dXJhbCBkaXJlY3RpdmUgcmVuZGVycyBpdHMgdGVtcGxhdGUgd2l0aCBhIHNwZWNpZmljIGNvbnRleHQgdHlwZS5cbiAgICovXG4gIHN0YXRpYyBuZ1RlbXBsYXRlQ29udGV4dEd1YXJkKGRpciwgY3R4KSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gTmdGb3JPZl9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgTmdGb3JPZikoaTAuybXJtWRpcmVjdGl2ZUluamVjdChpMC5WaWV3Q29udGFpbmVyUmVmKSwgaTAuybXJtWRpcmVjdGl2ZUluamVjdChpMC5UZW1wbGF0ZVJlZiksIGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoaTAuSXRlcmFibGVEaWZmZXJzKSk7XG4gICAgfTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVkaXIgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lRGlyZWN0aXZlKHtcbiAgICAgIHR5cGU6IE5nRm9yT2YsXG4gICAgICBzZWxlY3RvcnM6IFtbXCJcIiwgXCJuZ0ZvclwiLCBcIlwiLCBcIm5nRm9yT2ZcIiwgXCJcIl1dLFxuICAgICAgaW5wdXRzOiB7XG4gICAgICAgIG5nRm9yT2Y6IFwibmdGb3JPZlwiLFxuICAgICAgICBuZ0ZvclRyYWNrQnk6IFwibmdGb3JUcmFja0J5XCIsXG4gICAgICAgIG5nRm9yVGVtcGxhdGU6IFwibmdGb3JUZW1wbGF0ZVwiXG4gICAgICB9LFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShOZ0Zvck9mLCBbe1xuICAgIHR5cGU6IERpcmVjdGl2ZSxcbiAgICBhcmdzOiBbe1xuICAgICAgc2VsZWN0b3I6ICdbbmdGb3JdW25nRm9yT2ZdJyxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgKCkgPT4gW3tcbiAgICB0eXBlOiBpMC5WaWV3Q29udGFpbmVyUmVmXG4gIH0sIHtcbiAgICB0eXBlOiBpMC5UZW1wbGF0ZVJlZlxuICB9LCB7XG4gICAgdHlwZTogaTAuSXRlcmFibGVEaWZmZXJzXG4gIH1dLCB7XG4gICAgbmdGb3JPZjogW3tcbiAgICAgIHR5cGU6IElucHV0XG4gICAgfV0sXG4gICAgbmdGb3JUcmFja0J5OiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XSxcbiAgICBuZ0ZvclRlbXBsYXRlOiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XVxuICB9KTtcbn0pKCk7XG5mdW5jdGlvbiBhcHBseVZpZXdDaGFuZ2UodmlldywgcmVjb3JkKSB7XG4gIHZpZXcuY29udGV4dC4kaW1wbGljaXQgPSByZWNvcmQuaXRlbTtcbn1cbmZ1bmN0aW9uIGdldFR5cGVOYW1lKHR5cGUpIHtcbiAgcmV0dXJuIHR5cGVbJ25hbWUnXSB8fCB0eXBlb2YgdHlwZTtcbn1cblxuLyoqXG4gKiBBIHN0cnVjdHVyYWwgZGlyZWN0aXZlIHRoYXQgY29uZGl0aW9uYWxseSBpbmNsdWRlcyBhIHRlbXBsYXRlIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZlxuICogYW4gZXhwcmVzc2lvbiBjb2VyY2VkIHRvIEJvb2xlYW4uXG4gKiBXaGVuIHRoZSBleHByZXNzaW9uIGV2YWx1YXRlcyB0byB0cnVlLCBBbmd1bGFyIHJlbmRlcnMgdGhlIHRlbXBsYXRlXG4gKiBwcm92aWRlZCBpbiBhIGB0aGVuYCBjbGF1c2UsIGFuZCB3aGVuICBmYWxzZSBvciBudWxsLFxuICogQW5ndWxhciByZW5kZXJzIHRoZSB0ZW1wbGF0ZSBwcm92aWRlZCBpbiBhbiBvcHRpb25hbCBgZWxzZWAgY2xhdXNlLiBUaGUgZGVmYXVsdFxuICogdGVtcGxhdGUgZm9yIHRoZSBgZWxzZWAgY2xhdXNlIGlzIGJsYW5rLlxuICpcbiAqIEEgW3Nob3J0aGFuZCBmb3JtXShndWlkZS9kaXJlY3RpdmVzL3N0cnVjdHVyYWwtZGlyZWN0aXZlcyNhc3Rlcmlzaykgb2YgdGhlIGRpcmVjdGl2ZSxcbiAqIGAqbmdJZj1cImNvbmRpdGlvblwiYCwgaXMgZ2VuZXJhbGx5IHVzZWQsIHByb3ZpZGVkXG4gKiBhcyBhbiBhdHRyaWJ1dGUgb2YgdGhlIGFuY2hvciBlbGVtZW50IGZvciB0aGUgaW5zZXJ0ZWQgdGVtcGxhdGUuXG4gKiBBbmd1bGFyIGV4cGFuZHMgdGhpcyBpbnRvIGEgbW9yZSBleHBsaWNpdCB2ZXJzaW9uLCBpbiB3aGljaCB0aGUgYW5jaG9yIGVsZW1lbnRcbiAqIGlzIGNvbnRhaW5lZCBpbiBhbiBgPG5nLXRlbXBsYXRlPmAgZWxlbWVudC5cbiAqXG4gKiBTaW1wbGUgZm9ybSB3aXRoIHNob3J0aGFuZCBzeW50YXg6XG4gKlxuICogYGBgXG4gKiA8ZGl2ICpuZ0lmPVwiY29uZGl0aW9uXCI+Q29udGVudCB0byByZW5kZXIgd2hlbiBjb25kaXRpb24gaXMgdHJ1ZS48L2Rpdj5cbiAqIGBgYFxuICpcbiAqIFNpbXBsZSBmb3JtIHdpdGggZXhwYW5kZWQgc3ludGF4OlxuICpcbiAqIGBgYFxuICogPG5nLXRlbXBsYXRlIFtuZ0lmXT1cImNvbmRpdGlvblwiPjxkaXY+Q29udGVudCB0byByZW5kZXIgd2hlbiBjb25kaXRpb24gaXNcbiAqIHRydWUuPC9kaXY+PC9uZy10ZW1wbGF0ZT5cbiAqIGBgYFxuICpcbiAqIEZvcm0gd2l0aCBhbiBcImVsc2VcIiBibG9jazpcbiAqXG4gKiBgYGBcbiAqIDxkaXYgKm5nSWY9XCJjb25kaXRpb247IGVsc2UgZWxzZUJsb2NrXCI+Q29udGVudCB0byByZW5kZXIgd2hlbiBjb25kaXRpb24gaXMgdHJ1ZS48L2Rpdj5cbiAqIDxuZy10ZW1wbGF0ZSAjZWxzZUJsb2NrPkNvbnRlbnQgdG8gcmVuZGVyIHdoZW4gY29uZGl0aW9uIGlzIGZhbHNlLjwvbmctdGVtcGxhdGU+XG4gKiBgYGBcbiAqXG4gKiBTaG9ydGhhbmQgZm9ybSB3aXRoIFwidGhlblwiIGFuZCBcImVsc2VcIiBibG9ja3M6XG4gKlxuICogYGBgXG4gKiA8ZGl2ICpuZ0lmPVwiY29uZGl0aW9uOyB0aGVuIHRoZW5CbG9jayBlbHNlIGVsc2VCbG9ja1wiPjwvZGl2PlxuICogPG5nLXRlbXBsYXRlICN0aGVuQmxvY2s+Q29udGVudCB0byByZW5kZXIgd2hlbiBjb25kaXRpb24gaXMgdHJ1ZS48L25nLXRlbXBsYXRlPlxuICogPG5nLXRlbXBsYXRlICNlbHNlQmxvY2s+Q29udGVudCB0byByZW5kZXIgd2hlbiBjb25kaXRpb24gaXMgZmFsc2UuPC9uZy10ZW1wbGF0ZT5cbiAqIGBgYFxuICpcbiAqIEZvcm0gd2l0aCBzdG9yaW5nIHRoZSB2YWx1ZSBsb2NhbGx5OlxuICpcbiAqIGBgYFxuICogPGRpdiAqbmdJZj1cImNvbmRpdGlvbiBhcyB2YWx1ZTsgZWxzZSBlbHNlQmxvY2tcIj57e3ZhbHVlfX08L2Rpdj5cbiAqIDxuZy10ZW1wbGF0ZSAjZWxzZUJsb2NrPkNvbnRlbnQgdG8gcmVuZGVyIHdoZW4gdmFsdWUgaXMgbnVsbC48L25nLXRlbXBsYXRlPlxuICogYGBgXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiBUaGUgYCpuZ0lmYCBkaXJlY3RpdmUgaXMgbW9zdCBjb21tb25seSB1c2VkIHRvIGNvbmRpdGlvbmFsbHkgc2hvdyBhbiBpbmxpbmUgdGVtcGxhdGUsXG4gKiBhcyBzZWVuIGluIHRoZSBmb2xsb3dpbmcgIGV4YW1wbGUuXG4gKiBUaGUgZGVmYXVsdCBgZWxzZWAgdGVtcGxhdGUgaXMgYmxhbmsuXG4gKlxuICoge0BleGFtcGxlIGNvbW1vbi9uZ0lmL3RzL21vZHVsZS50cyByZWdpb249J05nSWZTaW1wbGUnfVxuICpcbiAqICMjIyBTaG93aW5nIGFuIGFsdGVybmF0aXZlIHRlbXBsYXRlIHVzaW5nIGBlbHNlYFxuICpcbiAqIFRvIGRpc3BsYXkgYSB0ZW1wbGF0ZSB3aGVuIGBleHByZXNzaW9uYCBldmFsdWF0ZXMgdG8gZmFsc2UsIHVzZSBhbiBgZWxzZWAgdGVtcGxhdGVcbiAqIGJpbmRpbmcgYXMgc2hvd24gaW4gdGhlIGZvbGxvd2luZyBleGFtcGxlLlxuICogVGhlIGBlbHNlYCBiaW5kaW5nIHBvaW50cyB0byBhbiBgPG5nLXRlbXBsYXRlPmAgIGVsZW1lbnQgbGFiZWxlZCBgI2Vsc2VCbG9ja2AuXG4gKiBUaGUgdGVtcGxhdGUgY2FuIGJlIGRlZmluZWQgYW55d2hlcmUgaW4gdGhlIGNvbXBvbmVudCB2aWV3LCBidXQgaXMgdHlwaWNhbGx5IHBsYWNlZCByaWdodCBhZnRlclxuICogYG5nSWZgIGZvciByZWFkYWJpbGl0eS5cbiAqXG4gKiB7QGV4YW1wbGUgY29tbW9uL25nSWYvdHMvbW9kdWxlLnRzIHJlZ2lvbj0nTmdJZkVsc2UnfVxuICpcbiAqICMjIyBVc2luZyBhbiBleHRlcm5hbCBgdGhlbmAgdGVtcGxhdGVcbiAqXG4gKiBJbiB0aGUgcHJldmlvdXMgZXhhbXBsZSwgdGhlIHRoZW4tY2xhdXNlIHRlbXBsYXRlIGlzIHNwZWNpZmllZCBpbmxpbmUsIGFzIHRoZSBjb250ZW50IG9mIHRoZVxuICogdGFnIHRoYXQgY29udGFpbnMgdGhlIGBuZ0lmYCBkaXJlY3RpdmUuIFlvdSBjYW4gYWxzbyBzcGVjaWZ5IGEgdGVtcGxhdGUgdGhhdCBpcyBkZWZpbmVkXG4gKiBleHRlcm5hbGx5LCBieSByZWZlcmVuY2luZyBhIGxhYmVsZWQgYDxuZy10ZW1wbGF0ZT5gIGVsZW1lbnQuIFdoZW4geW91IGRvIHRoaXMsIHlvdSBjYW5cbiAqIGNoYW5nZSB3aGljaCB0ZW1wbGF0ZSB0byB1c2UgYXQgcnVudGltZSwgYXMgc2hvd24gaW4gdGhlIGZvbGxvd2luZyBleGFtcGxlLlxuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vbmdJZi90cy9tb2R1bGUudHMgcmVnaW9uPSdOZ0lmVGhlbkVsc2UnfVxuICpcbiAqICMjIyBTdG9yaW5nIGEgY29uZGl0aW9uYWwgcmVzdWx0IGluIGEgdmFyaWFibGVcbiAqXG4gKiBZb3UgbWlnaHQgd2FudCB0byBzaG93IGEgc2V0IG9mIHByb3BlcnRpZXMgZnJvbSB0aGUgc2FtZSBvYmplY3QuIElmIHlvdSBhcmUgd2FpdGluZ1xuICogZm9yIGFzeW5jaHJvbm91cyBkYXRhLCB0aGUgb2JqZWN0IGNhbiBiZSB1bmRlZmluZWQuXG4gKiBJbiB0aGlzIGNhc2UsIHlvdSBjYW4gdXNlIGBuZ0lmYCBhbmQgc3RvcmUgdGhlIHJlc3VsdCBvZiB0aGUgY29uZGl0aW9uIGluIGEgbG9jYWxcbiAqIHZhcmlhYmxlIGFzIHNob3duIGluIHRoZSBmb2xsb3dpbmcgZXhhbXBsZS5cbiAqXG4gKiB7QGV4YW1wbGUgY29tbW9uL25nSWYvdHMvbW9kdWxlLnRzIHJlZ2lvbj0nTmdJZkFzJ31cbiAqXG4gKiBUaGlzIGNvZGUgdXNlcyBvbmx5IG9uZSBgQXN5bmNQaXBlYCwgc28gb25seSBvbmUgc3Vic2NyaXB0aW9uIGlzIGNyZWF0ZWQuXG4gKiBUaGUgY29uZGl0aW9uYWwgc3RhdGVtZW50IHN0b3JlcyB0aGUgcmVzdWx0IG9mIGB1c2VyU3RyZWFtfGFzeW5jYCBpbiB0aGUgbG9jYWwgdmFyaWFibGUgYHVzZXJgLlxuICogWW91IGNhbiB0aGVuIGJpbmQgdGhlIGxvY2FsIGB1c2VyYCByZXBlYXRlZGx5LlxuICpcbiAqIFRoZSBjb25kaXRpb25hbCBkaXNwbGF5cyB0aGUgZGF0YSBvbmx5IGlmIGB1c2VyU3RyZWFtYCByZXR1cm5zIGEgdmFsdWUsXG4gKiBzbyB5b3UgZG9uJ3QgbmVlZCB0byB1c2UgdGhlXG4gKiBzYWZlLW5hdmlnYXRpb24tb3BlcmF0b3IgKGA/LmApXG4gKiB0byBndWFyZCBhZ2FpbnN0IG51bGwgdmFsdWVzIHdoZW4gYWNjZXNzaW5nIHByb3BlcnRpZXMuXG4gKiBZb3UgY2FuIGRpc3BsYXkgYW4gYWx0ZXJuYXRpdmUgdGVtcGxhdGUgd2hpbGUgd2FpdGluZyBmb3IgdGhlIGRhdGEuXG4gKlxuICogIyMjIFNob3J0aGFuZCBzeW50YXhcbiAqXG4gKiBUaGUgc2hvcnRoYW5kIHN5bnRheCBgKm5nSWZgIGV4cGFuZHMgaW50byB0d28gc2VwYXJhdGUgdGVtcGxhdGUgc3BlY2lmaWNhdGlvbnNcbiAqIGZvciB0aGUgXCJ0aGVuXCIgYW5kIFwiZWxzZVwiIGNsYXVzZXMuIEZvciBleGFtcGxlLCBjb25zaWRlciB0aGUgZm9sbG93aW5nIHNob3J0aGFuZCBzdGF0ZW1lbnQsXG4gKiB0aGF0IGlzIG1lYW50IHRvIHNob3cgYSBsb2FkaW5nIHBhZ2Ugd2hpbGUgd2FpdGluZyBmb3IgZGF0YSB0byBiZSBsb2FkZWQuXG4gKlxuICogYGBgXG4gKiA8ZGl2IGNsYXNzPVwiaGVyby1saXN0XCIgKm5nSWY9XCJoZXJvZXMgZWxzZSBsb2FkaW5nXCI+XG4gKiAgLi4uXG4gKiA8L2Rpdj5cbiAqXG4gKiA8bmctdGVtcGxhdGUgI2xvYWRpbmc+XG4gKiAgPGRpdj5Mb2FkaW5nLi4uPC9kaXY+XG4gKiA8L25nLXRlbXBsYXRlPlxuICogYGBgXG4gKlxuICogWW91IGNhbiBzZWUgdGhhdCB0aGUgXCJlbHNlXCIgY2xhdXNlIHJlZmVyZW5jZXMgdGhlIGA8bmctdGVtcGxhdGU+YFxuICogd2l0aCB0aGUgYCNsb2FkaW5nYCBsYWJlbCwgYW5kIHRoZSB0ZW1wbGF0ZSBmb3IgdGhlIFwidGhlblwiIGNsYXVzZVxuICogaXMgcHJvdmlkZWQgYXMgdGhlIGNvbnRlbnQgb2YgdGhlIGFuY2hvciBlbGVtZW50LlxuICpcbiAqIEhvd2V2ZXIsIHdoZW4gQW5ndWxhciBleHBhbmRzIHRoZSBzaG9ydGhhbmQgc3ludGF4LCBpdCBjcmVhdGVzXG4gKiBhbm90aGVyIGA8bmctdGVtcGxhdGU+YCB0YWcsIHdpdGggYG5nSWZgIGFuZCBgbmdJZkVsc2VgIGRpcmVjdGl2ZXMuXG4gKiBUaGUgYW5jaG9yIGVsZW1lbnQgY29udGFpbmluZyB0aGUgdGVtcGxhdGUgZm9yIHRoZSBcInRoZW5cIiBjbGF1c2UgYmVjb21lc1xuICogdGhlIGNvbnRlbnQgb2YgdGhpcyB1bmxhYmVsZWQgYDxuZy10ZW1wbGF0ZT5gIHRhZy5cbiAqXG4gKiBgYGBcbiAqIDxuZy10ZW1wbGF0ZSBbbmdJZl09XCJoZXJvZXNcIiBbbmdJZkVsc2VdPVwibG9hZGluZ1wiPlxuICogIDxkaXYgY2xhc3M9XCJoZXJvLWxpc3RcIj5cbiAqICAgLi4uXG4gKiAgPC9kaXY+XG4gKiA8L25nLXRlbXBsYXRlPlxuICpcbiAqIDxuZy10ZW1wbGF0ZSAjbG9hZGluZz5cbiAqICA8ZGl2PkxvYWRpbmcuLi48L2Rpdj5cbiAqIDwvbmctdGVtcGxhdGU+XG4gKiBgYGBcbiAqXG4gKiBUaGUgcHJlc2VuY2Ugb2YgdGhlIGltcGxpY2l0IHRlbXBsYXRlIG9iamVjdCBoYXMgaW1wbGljYXRpb25zIGZvciB0aGUgbmVzdGluZyBvZlxuICogc3RydWN0dXJhbCBkaXJlY3RpdmVzLiBGb3IgbW9yZSBvbiB0aGlzIHN1YmplY3QsIHNlZVxuICogW1N0cnVjdHVyYWwgRGlyZWN0aXZlc10oZ3VpZGUvZGlyZWN0aXZlcy9zdHJ1Y3R1cmFsLWRpcmVjdGl2ZXMjb25lLXBlci1lbGVtZW50KS5cbiAqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIE5nSWYge1xuICBjb25zdHJ1Y3Rvcihfdmlld0NvbnRhaW5lciwgdGVtcGxhdGVSZWYpIHtcbiAgICB0aGlzLl92aWV3Q29udGFpbmVyID0gX3ZpZXdDb250YWluZXI7XG4gICAgdGhpcy5fY29udGV4dCA9IG5ldyBOZ0lmQ29udGV4dCgpO1xuICAgIHRoaXMuX3RoZW5UZW1wbGF0ZVJlZiA9IG51bGw7XG4gICAgdGhpcy5fZWxzZVRlbXBsYXRlUmVmID0gbnVsbDtcbiAgICB0aGlzLl90aGVuVmlld1JlZiA9IG51bGw7XG4gICAgdGhpcy5fZWxzZVZpZXdSZWYgPSBudWxsO1xuICAgIHRoaXMuX3RoZW5UZW1wbGF0ZVJlZiA9IHRlbXBsYXRlUmVmO1xuICB9XG4gIC8qKlxuICAgKiBUaGUgQm9vbGVhbiBleHByZXNzaW9uIHRvIGV2YWx1YXRlIGFzIHRoZSBjb25kaXRpb24gZm9yIHNob3dpbmcgYSB0ZW1wbGF0ZS5cbiAgICovXG4gIHNldCBuZ0lmKGNvbmRpdGlvbikge1xuICAgIHRoaXMuX2NvbnRleHQuJGltcGxpY2l0ID0gdGhpcy5fY29udGV4dC5uZ0lmID0gY29uZGl0aW9uO1xuICAgIHRoaXMuX3VwZGF0ZVZpZXcoKTtcbiAgfVxuICAvKipcbiAgICogQSB0ZW1wbGF0ZSB0byBzaG93IGlmIHRoZSBjb25kaXRpb24gZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gdHJ1ZS5cbiAgICovXG4gIHNldCBuZ0lmVGhlbih0ZW1wbGF0ZVJlZikge1xuICAgIGFzc2VydFRlbXBsYXRlKCduZ0lmVGhlbicsIHRlbXBsYXRlUmVmKTtcbiAgICB0aGlzLl90aGVuVGVtcGxhdGVSZWYgPSB0ZW1wbGF0ZVJlZjtcbiAgICB0aGlzLl90aGVuVmlld1JlZiA9IG51bGw7IC8vIGNsZWFyIHByZXZpb3VzIHZpZXcgaWYgYW55LlxuICAgIHRoaXMuX3VwZGF0ZVZpZXcoKTtcbiAgfVxuICAvKipcbiAgICogQSB0ZW1wbGF0ZSB0byBzaG93IGlmIHRoZSBjb25kaXRpb24gZXhwcmVzc2lvbiBldmFsdWF0ZXMgdG8gZmFsc2UuXG4gICAqL1xuICBzZXQgbmdJZkVsc2UodGVtcGxhdGVSZWYpIHtcbiAgICBhc3NlcnRUZW1wbGF0ZSgnbmdJZkVsc2UnLCB0ZW1wbGF0ZVJlZik7XG4gICAgdGhpcy5fZWxzZVRlbXBsYXRlUmVmID0gdGVtcGxhdGVSZWY7XG4gICAgdGhpcy5fZWxzZVZpZXdSZWYgPSBudWxsOyAvLyBjbGVhciBwcmV2aW91cyB2aWV3IGlmIGFueS5cbiAgICB0aGlzLl91cGRhdGVWaWV3KCk7XG4gIH1cbiAgX3VwZGF0ZVZpZXcoKSB7XG4gICAgaWYgKHRoaXMuX2NvbnRleHQuJGltcGxpY2l0KSB7XG4gICAgICBpZiAoIXRoaXMuX3RoZW5WaWV3UmVmKSB7XG4gICAgICAgIHRoaXMuX3ZpZXdDb250YWluZXIuY2xlYXIoKTtcbiAgICAgICAgdGhpcy5fZWxzZVZpZXdSZWYgPSBudWxsO1xuICAgICAgICBpZiAodGhpcy5fdGhlblRlbXBsYXRlUmVmKSB7XG4gICAgICAgICAgdGhpcy5fdGhlblZpZXdSZWYgPSB0aGlzLl92aWV3Q29udGFpbmVyLmNyZWF0ZUVtYmVkZGVkVmlldyh0aGlzLl90aGVuVGVtcGxhdGVSZWYsIHRoaXMuX2NvbnRleHQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghdGhpcy5fZWxzZVZpZXdSZWYpIHtcbiAgICAgICAgdGhpcy5fdmlld0NvbnRhaW5lci5jbGVhcigpO1xuICAgICAgICB0aGlzLl90aGVuVmlld1JlZiA9IG51bGw7XG4gICAgICAgIGlmICh0aGlzLl9lbHNlVGVtcGxhdGVSZWYpIHtcbiAgICAgICAgICB0aGlzLl9lbHNlVmlld1JlZiA9IHRoaXMuX3ZpZXdDb250YWluZXIuY3JlYXRlRW1iZWRkZWRWaWV3KHRoaXMuX2Vsc2VUZW1wbGF0ZVJlZiwgdGhpcy5fY29udGV4dCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIEFzc2VydHMgdGhlIGNvcnJlY3QgdHlwZSBvZiB0aGUgY29udGV4dCBmb3IgdGhlIHRlbXBsYXRlIHRoYXQgYE5nSWZgIHdpbGwgcmVuZGVyLlxuICAgKlxuICAgKiBUaGUgcHJlc2VuY2Ugb2YgdGhpcyBtZXRob2QgaXMgYSBzaWduYWwgdG8gdGhlIEl2eSB0ZW1wbGF0ZSB0eXBlLWNoZWNrIGNvbXBpbGVyIHRoYXQgdGhlXG4gICAqIGBOZ0lmYCBzdHJ1Y3R1cmFsIGRpcmVjdGl2ZSByZW5kZXJzIGl0cyB0ZW1wbGF0ZSB3aXRoIGEgc3BlY2lmaWMgY29udGV4dCB0eXBlLlxuICAgKi9cbiAgc3RhdGljIG5nVGVtcGxhdGVDb250ZXh0R3VhcmQoZGlyLCBjdHgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBOZ0lmX0ZhY3RvcnkodCkge1xuICAgICAgcmV0dXJuIG5ldyAodCB8fCBOZ0lmKShpMC7Jtcm1ZGlyZWN0aXZlSW5qZWN0KGkwLlZpZXdDb250YWluZXJSZWYpLCBpMC7Jtcm1ZGlyZWN0aXZlSW5qZWN0KGkwLlRlbXBsYXRlUmVmKSk7XG4gICAgfTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVkaXIgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lRGlyZWN0aXZlKHtcbiAgICAgIHR5cGU6IE5nSWYsXG4gICAgICBzZWxlY3RvcnM6IFtbXCJcIiwgXCJuZ0lmXCIsIFwiXCJdXSxcbiAgICAgIGlucHV0czoge1xuICAgICAgICBuZ0lmOiBcIm5nSWZcIixcbiAgICAgICAgbmdJZlRoZW46IFwibmdJZlRoZW5cIixcbiAgICAgICAgbmdJZkVsc2U6IFwibmdJZkVsc2VcIlxuICAgICAgfSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9KTtcbiAgfVxufVxuKCgpID0+IHtcbiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09IFwidW5kZWZpbmVkXCIgfHwgbmdEZXZNb2RlKSAmJiBpMC7JtXNldENsYXNzTWV0YWRhdGEoTmdJZiwgW3tcbiAgICB0eXBlOiBEaXJlY3RpdmUsXG4gICAgYXJnczogW3tcbiAgICAgIHNlbGVjdG9yOiAnW25nSWZdJyxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgKCkgPT4gW3tcbiAgICB0eXBlOiBpMC5WaWV3Q29udGFpbmVyUmVmXG4gIH0sIHtcbiAgICB0eXBlOiBpMC5UZW1wbGF0ZVJlZlxuICB9XSwge1xuICAgIG5nSWY6IFt7XG4gICAgICB0eXBlOiBJbnB1dFxuICAgIH1dLFxuICAgIG5nSWZUaGVuOiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XSxcbiAgICBuZ0lmRWxzZTogW3tcbiAgICAgIHR5cGU6IElucHV0XG4gICAgfV1cbiAgfSk7XG59KSgpO1xuLyoqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIE5nSWZDb250ZXh0IHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy4kaW1wbGljaXQgPSBudWxsO1xuICAgIHRoaXMubmdJZiA9IG51bGw7XG4gIH1cbn1cbmZ1bmN0aW9uIGFzc2VydFRlbXBsYXRlKHByb3BlcnR5LCB0ZW1wbGF0ZVJlZikge1xuICBjb25zdCBpc1RlbXBsYXRlUmVmT3JOdWxsID0gISEoIXRlbXBsYXRlUmVmIHx8IHRlbXBsYXRlUmVmLmNyZWF0ZUVtYmVkZGVkVmlldyk7XG4gIGlmICghaXNUZW1wbGF0ZVJlZk9yTnVsbCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtwcm9wZXJ0eX0gbXVzdCBiZSBhIFRlbXBsYXRlUmVmLCBidXQgcmVjZWl2ZWQgJyR7ybVzdHJpbmdpZnkodGVtcGxhdGVSZWYpfScuYCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIGNvbnN0YW50IGluZGljYXRpbmcgYSB0eXBlIG9mIGNvbXBhcmlzb24gdGhhdCBOZ1N3aXRjaCB1c2VzIHRvIG1hdGNoIGNhc2VzLiBFeHRyYWN0ZWQgdG8gYVxuICogc2VwYXJhdGUgZmlsZSB0byBmYWNpbGl0YXRlIEczIHBhdGNoZXMuXG4gKi9cbmNvbnN0IE5HX1NXSVRDSF9VU0VfU1RSSUNUX0VRVUFMUyA9IHRydWU7XG5jbGFzcyBTd2l0Y2hWaWV3IHtcbiAgY29uc3RydWN0b3IoX3ZpZXdDb250YWluZXJSZWYsIF90ZW1wbGF0ZVJlZikge1xuICAgIHRoaXMuX3ZpZXdDb250YWluZXJSZWYgPSBfdmlld0NvbnRhaW5lclJlZjtcbiAgICB0aGlzLl90ZW1wbGF0ZVJlZiA9IF90ZW1wbGF0ZVJlZjtcbiAgICB0aGlzLl9jcmVhdGVkID0gZmFsc2U7XG4gIH1cbiAgY3JlYXRlKCkge1xuICAgIHRoaXMuX2NyZWF0ZWQgPSB0cnVlO1xuICAgIHRoaXMuX3ZpZXdDb250YWluZXJSZWYuY3JlYXRlRW1iZWRkZWRWaWV3KHRoaXMuX3RlbXBsYXRlUmVmKTtcbiAgfVxuICBkZXN0cm95KCkge1xuICAgIHRoaXMuX2NyZWF0ZWQgPSBmYWxzZTtcbiAgICB0aGlzLl92aWV3Q29udGFpbmVyUmVmLmNsZWFyKCk7XG4gIH1cbiAgZW5mb3JjZVN0YXRlKGNyZWF0ZWQpIHtcbiAgICBpZiAoY3JlYXRlZCAmJiAhdGhpcy5fY3JlYXRlZCkge1xuICAgICAgdGhpcy5jcmVhdGUoKTtcbiAgICB9IGVsc2UgaWYgKCFjcmVhdGVkICYmIHRoaXMuX2NyZWF0ZWQpIHtcbiAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxufVxuLyoqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKiBUaGUgYFtuZ1N3aXRjaF1gIGRpcmVjdGl2ZSBvbiBhIGNvbnRhaW5lciBzcGVjaWZpZXMgYW4gZXhwcmVzc2lvbiB0byBtYXRjaCBhZ2FpbnN0LlxuICogVGhlIGV4cHJlc3Npb25zIHRvIG1hdGNoIGFyZSBwcm92aWRlZCBieSBgbmdTd2l0Y2hDYXNlYCBkaXJlY3RpdmVzIG9uIHZpZXdzIHdpdGhpbiB0aGUgY29udGFpbmVyLlxuICogLSBFdmVyeSB2aWV3IHRoYXQgbWF0Y2hlcyBpcyByZW5kZXJlZC5cbiAqIC0gSWYgdGhlcmUgYXJlIG5vIG1hdGNoZXMsIGEgdmlldyB3aXRoIHRoZSBgbmdTd2l0Y2hEZWZhdWx0YCBkaXJlY3RpdmUgaXMgcmVuZGVyZWQuXG4gKiAtIEVsZW1lbnRzIHdpdGhpbiB0aGUgYFtOZ1N3aXRjaF1gIHN0YXRlbWVudCBidXQgb3V0c2lkZSBvZiBhbnkgYE5nU3dpdGNoQ2FzZWBcbiAqIG9yIGBuZ1N3aXRjaERlZmF1bHRgIGRpcmVjdGl2ZSBhcmUgcHJlc2VydmVkIGF0IHRoZSBsb2NhdGlvbi5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogRGVmaW5lIGEgY29udGFpbmVyIGVsZW1lbnQgZm9yIHRoZSBkaXJlY3RpdmUsIGFuZCBzcGVjaWZ5IHRoZSBzd2l0Y2ggZXhwcmVzc2lvblxuICogdG8gbWF0Y2ggYWdhaW5zdCBhcyBhbiBhdHRyaWJ1dGU6XG4gKlxuICogYGBgXG4gKiA8Y29udGFpbmVyLWVsZW1lbnQgW25nU3dpdGNoXT1cInN3aXRjaF9leHByZXNzaW9uXCI+XG4gKiBgYGBcbiAqXG4gKiBXaXRoaW4gdGhlIGNvbnRhaW5lciwgYCpuZ1N3aXRjaENhc2VgIHN0YXRlbWVudHMgc3BlY2lmeSB0aGUgbWF0Y2ggZXhwcmVzc2lvbnNcbiAqIGFzIGF0dHJpYnV0ZXMuIEluY2x1ZGUgYCpuZ1N3aXRjaERlZmF1bHRgIGFzIHRoZSBmaW5hbCBjYXNlLlxuICpcbiAqIGBgYFxuICogPGNvbnRhaW5lci1lbGVtZW50IFtuZ1N3aXRjaF09XCJzd2l0Y2hfZXhwcmVzc2lvblwiPlxuICogICAgPHNvbWUtZWxlbWVudCAqbmdTd2l0Y2hDYXNlPVwibWF0Y2hfZXhwcmVzc2lvbl8xXCI+Li4uPC9zb21lLWVsZW1lbnQ+XG4gKiAuLi5cbiAqICAgIDxzb21lLWVsZW1lbnQgKm5nU3dpdGNoRGVmYXVsdD4uLi48L3NvbWUtZWxlbWVudD5cbiAqIDwvY29udGFpbmVyLWVsZW1lbnQ+XG4gKiBgYGBcbiAqXG4gKiAjIyMgVXNhZ2UgRXhhbXBsZXNcbiAqXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgc2hvd3MgaG93IHRvIHVzZSBtb3JlIHRoYW4gb25lIGNhc2UgdG8gZGlzcGxheSB0aGUgc2FtZSB2aWV3OlxuICpcbiAqIGBgYFxuICogPGNvbnRhaW5lci1lbGVtZW50IFtuZ1N3aXRjaF09XCJzd2l0Y2hfZXhwcmVzc2lvblwiPlxuICogICA8IS0tIHRoZSBzYW1lIHZpZXcgY2FuIGJlIHNob3duIGluIG1vcmUgdGhhbiBvbmUgY2FzZSAtLT5cbiAqICAgPHNvbWUtZWxlbWVudCAqbmdTd2l0Y2hDYXNlPVwibWF0Y2hfZXhwcmVzc2lvbl8xXCI+Li4uPC9zb21lLWVsZW1lbnQ+XG4gKiAgIDxzb21lLWVsZW1lbnQgKm5nU3dpdGNoQ2FzZT1cIm1hdGNoX2V4cHJlc3Npb25fMlwiPi4uLjwvc29tZS1lbGVtZW50PlxuICogICA8c29tZS1vdGhlci1lbGVtZW50ICpuZ1N3aXRjaENhc2U9XCJtYXRjaF9leHByZXNzaW9uXzNcIj4uLi48L3NvbWUtb3RoZXItZWxlbWVudD5cbiAqICAgPCEtLWRlZmF1bHQgY2FzZSB3aGVuIHRoZXJlIGFyZSBubyBtYXRjaGVzIC0tPlxuICogICA8c29tZS1lbGVtZW50ICpuZ1N3aXRjaERlZmF1bHQ+Li4uPC9zb21lLWVsZW1lbnQ+XG4gKiA8L2NvbnRhaW5lci1lbGVtZW50PlxuICogYGBgXG4gKlxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzIGhvdyBjYXNlcyBjYW4gYmUgbmVzdGVkOlxuICogYGBgXG4gKiA8Y29udGFpbmVyLWVsZW1lbnQgW25nU3dpdGNoXT1cInN3aXRjaF9leHByZXNzaW9uXCI+XG4gKiAgICAgICA8c29tZS1lbGVtZW50ICpuZ1N3aXRjaENhc2U9XCJtYXRjaF9leHByZXNzaW9uXzFcIj4uLi48L3NvbWUtZWxlbWVudD5cbiAqICAgICAgIDxzb21lLWVsZW1lbnQgKm5nU3dpdGNoQ2FzZT1cIm1hdGNoX2V4cHJlc3Npb25fMlwiPi4uLjwvc29tZS1lbGVtZW50PlxuICogICAgICAgPHNvbWUtb3RoZXItZWxlbWVudCAqbmdTd2l0Y2hDYXNlPVwibWF0Y2hfZXhwcmVzc2lvbl8zXCI+Li4uPC9zb21lLW90aGVyLWVsZW1lbnQ+XG4gKiAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCJtYXRjaF9leHByZXNzaW9uXzNcIj5cbiAqICAgICAgICAgPCEtLSB1c2UgYSBuZy1jb250YWluZXIgdG8gZ3JvdXAgbXVsdGlwbGUgcm9vdCBub2RlcyAtLT5cbiAqICAgICAgICAgPGlubmVyLWVsZW1lbnQ+PC9pbm5lci1lbGVtZW50PlxuICogICAgICAgICA8aW5uZXItb3RoZXItZWxlbWVudD48L2lubmVyLW90aGVyLWVsZW1lbnQ+XG4gKiAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAqICAgICAgIDxzb21lLWVsZW1lbnQgKm5nU3dpdGNoRGVmYXVsdD4uLi48L3NvbWUtZWxlbWVudD5cbiAqICAgICA8L2NvbnRhaW5lci1lbGVtZW50PlxuICogYGBgXG4gKlxuICogQHB1YmxpY0FwaVxuICogQHNlZSB7QGxpbmsgTmdTd2l0Y2hDYXNlfVxuICogQHNlZSB7QGxpbmsgTmdTd2l0Y2hEZWZhdWx0fVxuICogQHNlZSBbU3RydWN0dXJhbCBEaXJlY3RpdmVzXShndWlkZS9kaXJlY3RpdmVzL3N0cnVjdHVyYWwtZGlyZWN0aXZlcylcbiAqXG4gKi9cbmNsYXNzIE5nU3dpdGNoIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5fZGVmYXVsdFZpZXdzID0gW107XG4gICAgdGhpcy5fZGVmYXVsdFVzZWQgPSBmYWxzZTtcbiAgICB0aGlzLl9jYXNlQ291bnQgPSAwO1xuICAgIHRoaXMuX2xhc3RDYXNlQ2hlY2tJbmRleCA9IDA7XG4gICAgdGhpcy5fbGFzdENhc2VzTWF0Y2hlZCA9IGZhbHNlO1xuICB9XG4gIHNldCBuZ1N3aXRjaChuZXdWYWx1ZSkge1xuICAgIHRoaXMuX25nU3dpdGNoID0gbmV3VmFsdWU7XG4gICAgaWYgKHRoaXMuX2Nhc2VDb3VudCA9PT0gMCkge1xuICAgICAgdGhpcy5fdXBkYXRlRGVmYXVsdENhc2VzKHRydWUpO1xuICAgIH1cbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIF9hZGRDYXNlKCkge1xuICAgIHJldHVybiB0aGlzLl9jYXNlQ291bnQrKztcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIF9hZGREZWZhdWx0KHZpZXcpIHtcbiAgICB0aGlzLl9kZWZhdWx0Vmlld3MucHVzaCh2aWV3KTtcbiAgfVxuICAvKiogQGludGVybmFsICovXG4gIF9tYXRjaENhc2UodmFsdWUpIHtcbiAgICBjb25zdCBtYXRjaGVkID0gTkdfU1dJVENIX1VTRV9TVFJJQ1RfRVFVQUxTID8gdmFsdWUgPT09IHRoaXMuX25nU3dpdGNoIDogdmFsdWUgPT0gdGhpcy5fbmdTd2l0Y2g7XG4gICAgaWYgKCh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpICYmIG1hdGNoZWQgIT09ICh2YWx1ZSA9PSB0aGlzLl9uZ1N3aXRjaCkpIHtcbiAgICAgIGNvbnNvbGUud2FybijJtWZvcm1hdFJ1bnRpbWVFcnJvcigyMDAxIC8qIFJ1bnRpbWVFcnJvckNvZGUuRVFVQUxJVFlfTkdfU1dJVENIX0RJRkZFUkVOQ0UgKi8sICdBcyBvZiBBbmd1bGFyIHYxNyB0aGUgTmdTd2l0Y2ggZGlyZWN0aXZlIHVzZXMgc3RyaWN0IGVxdWFsaXR5IGNvbXBhcmlzb24gPT09IGluc3RlYWQgb2YgPT0gdG8gbWF0Y2ggZGlmZmVyZW50IGNhc2VzLiAnICsgYFByZXZpb3VzbHkgdGhlIGNhc2UgdmFsdWUgXCIke3N0cmluZ2lmeVZhbHVlKHZhbHVlKX1cIiBtYXRjaGVkIHN3aXRjaCBleHByZXNzaW9uIHZhbHVlIFwiJHtzdHJpbmdpZnlWYWx1ZSh0aGlzLl9uZ1N3aXRjaCl9XCIsIGJ1dCB0aGlzIGlzIG5vIGxvbmdlciB0aGUgY2FzZSB3aXRoIHRoZSBzdHJpY3RlciBlcXVhbGl0eSBjaGVjay4gYCArICdZb3VyIGNvbXBhcmlzb24gcmVzdWx0cyByZXR1cm4gZGlmZmVyZW50IHJlc3VsdHMgdXNpbmcgPT09IHZzLiA9PSBhbmQgeW91IHNob3VsZCBhZGp1c3QgeW91ciBuZ1N3aXRjaCBleHByZXNzaW9uIGFuZCAvIG9yIHZhbHVlcyB0byBjb25mb3JtIHdpdGggdGhlIHN0cmljdCBlcXVhbGl0eSByZXF1aXJlbWVudHMuJykpO1xuICAgIH1cbiAgICB0aGlzLl9sYXN0Q2FzZXNNYXRjaGVkIHx8PSBtYXRjaGVkO1xuICAgIHRoaXMuX2xhc3RDYXNlQ2hlY2tJbmRleCsrO1xuICAgIGlmICh0aGlzLl9sYXN0Q2FzZUNoZWNrSW5kZXggPT09IHRoaXMuX2Nhc2VDb3VudCkge1xuICAgICAgdGhpcy5fdXBkYXRlRGVmYXVsdENhc2VzKCF0aGlzLl9sYXN0Q2FzZXNNYXRjaGVkKTtcbiAgICAgIHRoaXMuX2xhc3RDYXNlQ2hlY2tJbmRleCA9IDA7XG4gICAgICB0aGlzLl9sYXN0Q2FzZXNNYXRjaGVkID0gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBtYXRjaGVkO1xuICB9XG4gIF91cGRhdGVEZWZhdWx0Q2FzZXModXNlRGVmYXVsdCkge1xuICAgIGlmICh0aGlzLl9kZWZhdWx0Vmlld3MubGVuZ3RoID4gMCAmJiB1c2VEZWZhdWx0ICE9PSB0aGlzLl9kZWZhdWx0VXNlZCkge1xuICAgICAgdGhpcy5fZGVmYXVsdFVzZWQgPSB1c2VEZWZhdWx0O1xuICAgICAgZm9yIChjb25zdCBkZWZhdWx0VmlldyBvZiB0aGlzLl9kZWZhdWx0Vmlld3MpIHtcbiAgICAgICAgZGVmYXVsdFZpZXcuZW5mb3JjZVN0YXRlKHVzZURlZmF1bHQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBOZ1N3aXRjaF9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgTmdTd2l0Y2gpKCk7XG4gICAgfTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVkaXIgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lRGlyZWN0aXZlKHtcbiAgICAgIHR5cGU6IE5nU3dpdGNoLFxuICAgICAgc2VsZWN0b3JzOiBbW1wiXCIsIFwibmdTd2l0Y2hcIiwgXCJcIl1dLFxuICAgICAgaW5wdXRzOiB7XG4gICAgICAgIG5nU3dpdGNoOiBcIm5nU3dpdGNoXCJcbiAgICAgIH0sXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKE5nU3dpdGNoLCBbe1xuICAgIHR5cGU6IERpcmVjdGl2ZSxcbiAgICBhcmdzOiBbe1xuICAgICAgc2VsZWN0b3I6ICdbbmdTd2l0Y2hdJyxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgbnVsbCwge1xuICAgIG5nU3dpdGNoOiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XVxuICB9KTtcbn0pKCk7XG4vKipcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqIFByb3ZpZGVzIGEgc3dpdGNoIGNhc2UgZXhwcmVzc2lvbiB0byBtYXRjaCBhZ2FpbnN0IGFuIGVuY2xvc2luZyBgbmdTd2l0Y2hgIGV4cHJlc3Npb24uXG4gKiBXaGVuIHRoZSBleHByZXNzaW9ucyBtYXRjaCwgdGhlIGdpdmVuIGBOZ1N3aXRjaENhc2VgIHRlbXBsYXRlIGlzIHJlbmRlcmVkLlxuICogSWYgbXVsdGlwbGUgbWF0Y2ggZXhwcmVzc2lvbnMgbWF0Y2ggdGhlIHN3aXRjaCBleHByZXNzaW9uIHZhbHVlLCBhbGwgb2YgdGhlbSBhcmUgZGlzcGxheWVkLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogV2l0aGluIGEgc3dpdGNoIGNvbnRhaW5lciwgYCpuZ1N3aXRjaENhc2VgIHN0YXRlbWVudHMgc3BlY2lmeSB0aGUgbWF0Y2ggZXhwcmVzc2lvbnNcbiAqIGFzIGF0dHJpYnV0ZXMuIEluY2x1ZGUgYCpuZ1N3aXRjaERlZmF1bHRgIGFzIHRoZSBmaW5hbCBjYXNlLlxuICpcbiAqIGBgYFxuICogPGNvbnRhaW5lci1lbGVtZW50IFtuZ1N3aXRjaF09XCJzd2l0Y2hfZXhwcmVzc2lvblwiPlxuICogICA8c29tZS1lbGVtZW50ICpuZ1N3aXRjaENhc2U9XCJtYXRjaF9leHByZXNzaW9uXzFcIj4uLi48L3NvbWUtZWxlbWVudD5cbiAqICAgLi4uXG4gKiAgIDxzb21lLWVsZW1lbnQgKm5nU3dpdGNoRGVmYXVsdD4uLi48L3NvbWUtZWxlbWVudD5cbiAqIDwvY29udGFpbmVyLWVsZW1lbnQ+XG4gKiBgYGBcbiAqXG4gKiBFYWNoIHN3aXRjaC1jYXNlIHN0YXRlbWVudCBjb250YWlucyBhbiBpbi1saW5lIEhUTUwgdGVtcGxhdGUgb3IgdGVtcGxhdGUgcmVmZXJlbmNlXG4gKiB0aGF0IGRlZmluZXMgdGhlIHN1YnRyZWUgdG8gYmUgc2VsZWN0ZWQgaWYgdGhlIHZhbHVlIG9mIHRoZSBtYXRjaCBleHByZXNzaW9uXG4gKiBtYXRjaGVzIHRoZSB2YWx1ZSBvZiB0aGUgc3dpdGNoIGV4cHJlc3Npb24uXG4gKlxuICogQXMgb2YgQW5ndWxhciB2MTcgdGhlIE5nU3dpdGNoIGRpcmVjdGl2ZSB1c2VzIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29uIChgPT09YCkgaW5zdGVhZCBvZlxuICogbG9vc2UgZXF1YWxpdHkgKGA9PWApIHRvIG1hdGNoIGRpZmZlcmVudCBjYXNlcy5cbiAqXG4gKiBAcHVibGljQXBpXG4gKiBAc2VlIHtAbGluayBOZ1N3aXRjaH1cbiAqIEBzZWUge0BsaW5rIE5nU3dpdGNoRGVmYXVsdH1cbiAqXG4gKi9cbmNsYXNzIE5nU3dpdGNoQ2FzZSB7XG4gIGNvbnN0cnVjdG9yKHZpZXdDb250YWluZXIsIHRlbXBsYXRlUmVmLCBuZ1N3aXRjaCkge1xuICAgIHRoaXMubmdTd2l0Y2ggPSBuZ1N3aXRjaDtcbiAgICBpZiAoKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSkgJiYgIW5nU3dpdGNoKSB7XG4gICAgICB0aHJvd05nU3dpdGNoUHJvdmlkZXJOb3RGb3VuZEVycm9yKCduZ1N3aXRjaENhc2UnLCAnTmdTd2l0Y2hDYXNlJyk7XG4gICAgfVxuICAgIG5nU3dpdGNoLl9hZGRDYXNlKCk7XG4gICAgdGhpcy5fdmlldyA9IG5ldyBTd2l0Y2hWaWV3KHZpZXdDb250YWluZXIsIHRlbXBsYXRlUmVmKTtcbiAgfVxuICAvKipcbiAgICogUGVyZm9ybXMgY2FzZSBtYXRjaGluZy4gRm9yIGludGVybmFsIHVzZSBvbmx5LlxuICAgKiBAbm9kb2NcbiAgICovXG4gIG5nRG9DaGVjaygpIHtcbiAgICB0aGlzLl92aWV3LmVuZm9yY2VTdGF0ZSh0aGlzLm5nU3dpdGNoLl9tYXRjaENhc2UodGhpcy5uZ1N3aXRjaENhc2UpKTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBOZ1N3aXRjaENhc2VfRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IE5nU3dpdGNoQ2FzZSkoaTAuybXJtWRpcmVjdGl2ZUluamVjdChpMC5WaWV3Q29udGFpbmVyUmVmKSwgaTAuybXJtWRpcmVjdGl2ZUluamVjdChpMC5UZW1wbGF0ZVJlZiksIGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoTmdTd2l0Y2gsIDkpKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWRpciA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVEaXJlY3RpdmUoe1xuICAgICAgdHlwZTogTmdTd2l0Y2hDYXNlLFxuICAgICAgc2VsZWN0b3JzOiBbW1wiXCIsIFwibmdTd2l0Y2hDYXNlXCIsIFwiXCJdXSxcbiAgICAgIGlucHV0czoge1xuICAgICAgICBuZ1N3aXRjaENhc2U6IFwibmdTd2l0Y2hDYXNlXCJcbiAgICAgIH0sXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKE5nU3dpdGNoQ2FzZSwgW3tcbiAgICB0eXBlOiBEaXJlY3RpdmUsXG4gICAgYXJnczogW3tcbiAgICAgIHNlbGVjdG9yOiAnW25nU3dpdGNoQ2FzZV0nLFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH1dXG4gIH1dLCAoKSA9PiBbe1xuICAgIHR5cGU6IGkwLlZpZXdDb250YWluZXJSZWZcbiAgfSwge1xuICAgIHR5cGU6IGkwLlRlbXBsYXRlUmVmXG4gIH0sIHtcbiAgICB0eXBlOiBOZ1N3aXRjaCxcbiAgICBkZWNvcmF0b3JzOiBbe1xuICAgICAgdHlwZTogT3B0aW9uYWxcbiAgICB9LCB7XG4gICAgICB0eXBlOiBIb3N0XG4gICAgfV1cbiAgfV0sIHtcbiAgICBuZ1N3aXRjaENhc2U6IFt7XG4gICAgICB0eXBlOiBJbnB1dFxuICAgIH1dXG4gIH0pO1xufSkoKTtcbi8qKlxuICogQG5nTW9kdWxlIENvbW1vbk1vZHVsZVxuICpcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIENyZWF0ZXMgYSB2aWV3IHRoYXQgaXMgcmVuZGVyZWQgd2hlbiBubyBgTmdTd2l0Y2hDYXNlYCBleHByZXNzaW9uc1xuICogbWF0Y2ggdGhlIGBOZ1N3aXRjaGAgZXhwcmVzc2lvbi5cbiAqIFRoaXMgc3RhdGVtZW50IHNob3VsZCBiZSB0aGUgZmluYWwgY2FzZSBpbiBhbiBgTmdTd2l0Y2hgLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqIEBzZWUge0BsaW5rIE5nU3dpdGNofVxuICogQHNlZSB7QGxpbmsgTmdTd2l0Y2hDYXNlfVxuICpcbiAqL1xuY2xhc3MgTmdTd2l0Y2hEZWZhdWx0IHtcbiAgY29uc3RydWN0b3Iodmlld0NvbnRhaW5lciwgdGVtcGxhdGVSZWYsIG5nU3dpdGNoKSB7XG4gICAgaWYgKCh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpICYmICFuZ1N3aXRjaCkge1xuICAgICAgdGhyb3dOZ1N3aXRjaFByb3ZpZGVyTm90Rm91bmRFcnJvcignbmdTd2l0Y2hEZWZhdWx0JywgJ05nU3dpdGNoRGVmYXVsdCcpO1xuICAgIH1cbiAgICBuZ1N3aXRjaC5fYWRkRGVmYXVsdChuZXcgU3dpdGNoVmlldyh2aWV3Q29udGFpbmVyLCB0ZW1wbGF0ZVJlZikpO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIE5nU3dpdGNoRGVmYXVsdF9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgTmdTd2l0Y2hEZWZhdWx0KShpMC7Jtcm1ZGlyZWN0aXZlSW5qZWN0KGkwLlZpZXdDb250YWluZXJSZWYpLCBpMC7Jtcm1ZGlyZWN0aXZlSW5qZWN0KGkwLlRlbXBsYXRlUmVmKSwgaTAuybXJtWRpcmVjdGl2ZUluamVjdChOZ1N3aXRjaCwgOSkpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZGlyID0gLyogQF9fUFVSRV9fICovaTAuybXJtWRlZmluZURpcmVjdGl2ZSh7XG4gICAgICB0eXBlOiBOZ1N3aXRjaERlZmF1bHQsXG4gICAgICBzZWxlY3RvcnM6IFtbXCJcIiwgXCJuZ1N3aXRjaERlZmF1bHRcIiwgXCJcIl1dLFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShOZ1N3aXRjaERlZmF1bHQsIFt7XG4gICAgdHlwZTogRGlyZWN0aXZlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBzZWxlY3RvcjogJ1tuZ1N3aXRjaERlZmF1bHRdJyxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgKCkgPT4gW3tcbiAgICB0eXBlOiBpMC5WaWV3Q29udGFpbmVyUmVmXG4gIH0sIHtcbiAgICB0eXBlOiBpMC5UZW1wbGF0ZVJlZlxuICB9LCB7XG4gICAgdHlwZTogTmdTd2l0Y2gsXG4gICAgZGVjb3JhdG9yczogW3tcbiAgICAgIHR5cGU6IE9wdGlvbmFsXG4gICAgfSwge1xuICAgICAgdHlwZTogSG9zdFxuICAgIH1dXG4gIH1dLCBudWxsKTtcbn0pKCk7XG5mdW5jdGlvbiB0aHJvd05nU3dpdGNoUHJvdmlkZXJOb3RGb3VuZEVycm9yKGF0dHJOYW1lLCBkaXJlY3RpdmVOYW1lKSB7XG4gIHRocm93IG5ldyDJtVJ1bnRpbWVFcnJvcigyMDAwIC8qIFJ1bnRpbWVFcnJvckNvZGUuUEFSRU5UX05HX1NXSVRDSF9OT1RfRk9VTkQgKi8sIGBBbiBlbGVtZW50IHdpdGggdGhlIFwiJHthdHRyTmFtZX1cIiBhdHRyaWJ1dGUgYCArIGAobWF0Y2hpbmcgdGhlIFwiJHtkaXJlY3RpdmVOYW1lfVwiIGRpcmVjdGl2ZSkgbXVzdCBiZSBsb2NhdGVkIGluc2lkZSBhbiBlbGVtZW50IHdpdGggdGhlIFwibmdTd2l0Y2hcIiBhdHRyaWJ1dGUgYCArIGAobWF0Y2hpbmcgXCJOZ1N3aXRjaFwiIGRpcmVjdGl2ZSlgKTtcbn1cbmZ1bmN0aW9uIHN0cmluZ2lmeVZhbHVlKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnID8gYCcke3ZhbHVlfSdgIDogU3RyaW5nKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIGBgYFxuICogPHNvbWUtZWxlbWVudCBbbmdQbHVyYWxdPVwidmFsdWVcIj5cbiAqICAgPG5nLXRlbXBsYXRlIG5nUGx1cmFsQ2FzZT1cIj0wXCI+dGhlcmUgaXMgbm90aGluZzwvbmctdGVtcGxhdGU+XG4gKiAgIDxuZy10ZW1wbGF0ZSBuZ1BsdXJhbENhc2U9XCI9MVwiPnRoZXJlIGlzIG9uZTwvbmctdGVtcGxhdGU+XG4gKiAgIDxuZy10ZW1wbGF0ZSBuZ1BsdXJhbENhc2U9XCJmZXdcIj50aGVyZSBhcmUgYSBmZXc8L25nLXRlbXBsYXRlPlxuICogPC9zb21lLWVsZW1lbnQ+XG4gKiBgYGBcbiAqXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiBBZGRzIC8gcmVtb3ZlcyBET00gc3ViLXRyZWVzIGJhc2VkIG9uIGEgbnVtZXJpYyB2YWx1ZS4gVGFpbG9yZWQgZm9yIHBsdXJhbGl6YXRpb24uXG4gKlxuICogRGlzcGxheXMgRE9NIHN1Yi10cmVlcyB0aGF0IG1hdGNoIHRoZSBzd2l0Y2ggZXhwcmVzc2lvbiB2YWx1ZSwgb3IgZmFpbGluZyB0aGF0LCBET00gc3ViLXRyZWVzXG4gKiB0aGF0IG1hdGNoIHRoZSBzd2l0Y2ggZXhwcmVzc2lvbidzIHBsdXJhbGl6YXRpb24gY2F0ZWdvcnkuXG4gKlxuICogVG8gdXNlIHRoaXMgZGlyZWN0aXZlIHlvdSBtdXN0IHByb3ZpZGUgYSBjb250YWluZXIgZWxlbWVudCB0aGF0IHNldHMgdGhlIGBbbmdQbHVyYWxdYCBhdHRyaWJ1dGVcbiAqIHRvIGEgc3dpdGNoIGV4cHJlc3Npb24uIElubmVyIGVsZW1lbnRzIHdpdGggYSBgW25nUGx1cmFsQ2FzZV1gIHdpbGwgZGlzcGxheSBiYXNlZCBvbiB0aGVpclxuICogZXhwcmVzc2lvbjpcbiAqIC0gaWYgYFtuZ1BsdXJhbENhc2VdYCBpcyBzZXQgdG8gYSB2YWx1ZSBzdGFydGluZyB3aXRoIGA9YCwgaXQgd2lsbCBvbmx5IGRpc3BsYXkgaWYgdGhlIHZhbHVlXG4gKiAgIG1hdGNoZXMgdGhlIHN3aXRjaCBleHByZXNzaW9uIGV4YWN0bHksXG4gKiAtIG90aGVyd2lzZSwgdGhlIHZpZXcgd2lsbCBiZSB0cmVhdGVkIGFzIGEgXCJjYXRlZ29yeSBtYXRjaFwiLCBhbmQgd2lsbCBvbmx5IGRpc3BsYXkgaWYgZXhhY3RcbiAqICAgdmFsdWUgbWF0Y2hlcyBhcmVuJ3QgZm91bmQgYW5kIHRoZSB2YWx1ZSBtYXBzIHRvIGl0cyBjYXRlZ29yeSBmb3IgdGhlIGRlZmluZWQgbG9jYWxlLlxuICpcbiAqIFNlZSBodHRwOi8vY2xkci51bmljb2RlLm9yZy9pbmRleC9jbGRyLXNwZWMvcGx1cmFsLXJ1bGVzXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBOZ1BsdXJhbCB7XG4gIGNvbnN0cnVjdG9yKF9sb2NhbGl6YXRpb24pIHtcbiAgICB0aGlzLl9sb2NhbGl6YXRpb24gPSBfbG9jYWxpemF0aW9uO1xuICAgIHRoaXMuX2Nhc2VWaWV3cyA9IHt9O1xuICB9XG4gIHNldCBuZ1BsdXJhbCh2YWx1ZSkge1xuICAgIHRoaXMuX3VwZGF0ZVZpZXcodmFsdWUpO1xuICB9XG4gIGFkZENhc2UodmFsdWUsIHN3aXRjaFZpZXcpIHtcbiAgICB0aGlzLl9jYXNlVmlld3NbdmFsdWVdID0gc3dpdGNoVmlldztcbiAgfVxuICBfdXBkYXRlVmlldyhzd2l0Y2hWYWx1ZSkge1xuICAgIHRoaXMuX2NsZWFyVmlld3MoKTtcbiAgICBjb25zdCBjYXNlcyA9IE9iamVjdC5rZXlzKHRoaXMuX2Nhc2VWaWV3cyk7XG4gICAgY29uc3Qga2V5ID0gZ2V0UGx1cmFsQ2F0ZWdvcnkoc3dpdGNoVmFsdWUsIGNhc2VzLCB0aGlzLl9sb2NhbGl6YXRpb24pO1xuICAgIHRoaXMuX2FjdGl2YXRlVmlldyh0aGlzLl9jYXNlVmlld3Nba2V5XSk7XG4gIH1cbiAgX2NsZWFyVmlld3MoKSB7XG4gICAgaWYgKHRoaXMuX2FjdGl2ZVZpZXcpIHRoaXMuX2FjdGl2ZVZpZXcuZGVzdHJveSgpO1xuICB9XG4gIF9hY3RpdmF0ZVZpZXcodmlldykge1xuICAgIGlmICh2aWV3KSB7XG4gICAgICB0aGlzLl9hY3RpdmVWaWV3ID0gdmlldztcbiAgICAgIHRoaXMuX2FjdGl2ZVZpZXcuY3JlYXRlKCk7XG4gICAgfVxuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIE5nUGx1cmFsX0ZhY3RvcnkodCkge1xuICAgICAgcmV0dXJuIG5ldyAodCB8fCBOZ1BsdXJhbCkoaTAuybXJtWRpcmVjdGl2ZUluamVjdChOZ0xvY2FsaXphdGlvbikpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZGlyID0gLyogQF9fUFVSRV9fICovaTAuybXJtWRlZmluZURpcmVjdGl2ZSh7XG4gICAgICB0eXBlOiBOZ1BsdXJhbCxcbiAgICAgIHNlbGVjdG9yczogW1tcIlwiLCBcIm5nUGx1cmFsXCIsIFwiXCJdXSxcbiAgICAgIGlucHV0czoge1xuICAgICAgICBuZ1BsdXJhbDogXCJuZ1BsdXJhbFwiXG4gICAgICB9LFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShOZ1BsdXJhbCwgW3tcbiAgICB0eXBlOiBEaXJlY3RpdmUsXG4gICAgYXJnczogW3tcbiAgICAgIHNlbGVjdG9yOiAnW25nUGx1cmFsXScsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfV1cbiAgfV0sICgpID0+IFt7XG4gICAgdHlwZTogTmdMb2NhbGl6YXRpb25cbiAgfV0sIHtcbiAgICBuZ1BsdXJhbDogW3tcbiAgICAgIHR5cGU6IElucHV0XG4gICAgfV1cbiAgfSk7XG59KSgpO1xuLyoqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKlxuICogQ3JlYXRlcyBhIHZpZXcgdGhhdCB3aWxsIGJlIGFkZGVkL3JlbW92ZWQgZnJvbSB0aGUgcGFyZW50IHtAbGluayBOZ1BsdXJhbH0gd2hlbiB0aGVcbiAqIGdpdmVuIGV4cHJlc3Npb24gbWF0Y2hlcyB0aGUgcGx1cmFsIGV4cHJlc3Npb24gYWNjb3JkaW5nIHRvIENMRFIgcnVsZXMuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIGBgYFxuICogPHNvbWUtZWxlbWVudCBbbmdQbHVyYWxdPVwidmFsdWVcIj5cbiAqICAgPG5nLXRlbXBsYXRlIG5nUGx1cmFsQ2FzZT1cIj0wXCI+Li4uPC9uZy10ZW1wbGF0ZT5cbiAqICAgPG5nLXRlbXBsYXRlIG5nUGx1cmFsQ2FzZT1cIm90aGVyXCI+Li4uPC9uZy10ZW1wbGF0ZT5cbiAqIDwvc29tZS1lbGVtZW50PlxuICpgYGBcbiAqXG4gKiBTZWUge0BsaW5rIE5nUGx1cmFsfSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBleGFtcGxlLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgTmdQbHVyYWxDYXNlIHtcbiAgY29uc3RydWN0b3IodmFsdWUsIHRlbXBsYXRlLCB2aWV3Q29udGFpbmVyLCBuZ1BsdXJhbCkge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICBjb25zdCBpc0FOdW1iZXIgPSAhaXNOYU4oTnVtYmVyKHZhbHVlKSk7XG4gICAgbmdQbHVyYWwuYWRkQ2FzZShpc0FOdW1iZXIgPyBgPSR7dmFsdWV9YCA6IHZhbHVlLCBuZXcgU3dpdGNoVmlldyh2aWV3Q29udGFpbmVyLCB0ZW1wbGF0ZSkpO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIE5nUGx1cmFsQ2FzZV9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgTmdQbHVyYWxDYXNlKShpMC7Jtcm1aW5qZWN0QXR0cmlidXRlKCduZ1BsdXJhbENhc2UnKSwgaTAuybXJtWRpcmVjdGl2ZUluamVjdChpMC5UZW1wbGF0ZVJlZiksIGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoaTAuVmlld0NvbnRhaW5lclJlZiksIGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoTmdQbHVyYWwsIDEpKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWRpciA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVEaXJlY3RpdmUoe1xuICAgICAgdHlwZTogTmdQbHVyYWxDYXNlLFxuICAgICAgc2VsZWN0b3JzOiBbW1wiXCIsIFwibmdQbHVyYWxDYXNlXCIsIFwiXCJdXSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9KTtcbiAgfVxufVxuKCgpID0+IHtcbiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09IFwidW5kZWZpbmVkXCIgfHwgbmdEZXZNb2RlKSAmJiBpMC7JtXNldENsYXNzTWV0YWRhdGEoTmdQbHVyYWxDYXNlLCBbe1xuICAgIHR5cGU6IERpcmVjdGl2ZSxcbiAgICBhcmdzOiBbe1xuICAgICAgc2VsZWN0b3I6ICdbbmdQbHVyYWxDYXNlXScsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfV1cbiAgfV0sICgpID0+IFt7XG4gICAgdHlwZTogdW5kZWZpbmVkLFxuICAgIGRlY29yYXRvcnM6IFt7XG4gICAgICB0eXBlOiBBdHRyaWJ1dGUsXG4gICAgICBhcmdzOiBbJ25nUGx1cmFsQ2FzZSddXG4gICAgfV1cbiAgfSwge1xuICAgIHR5cGU6IGkwLlRlbXBsYXRlUmVmXG4gIH0sIHtcbiAgICB0eXBlOiBpMC5WaWV3Q29udGFpbmVyUmVmXG4gIH0sIHtcbiAgICB0eXBlOiBOZ1BsdXJhbCxcbiAgICBkZWNvcmF0b3JzOiBbe1xuICAgICAgdHlwZTogSG9zdFxuICAgIH1dXG4gIH1dLCBudWxsKTtcbn0pKCk7XG5cbi8qKlxuICogQG5nTW9kdWxlIENvbW1vbk1vZHVsZVxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogU2V0IHRoZSBmb250IG9mIHRoZSBjb250YWluaW5nIGVsZW1lbnQgdG8gdGhlIHJlc3VsdCBvZiBhbiBleHByZXNzaW9uLlxuICpcbiAqIGBgYFxuICogPHNvbWUtZWxlbWVudCBbbmdTdHlsZV09XCJ7J2ZvbnQtc3R5bGUnOiBzdHlsZUV4cH1cIj4uLi48L3NvbWUtZWxlbWVudD5cbiAqIGBgYFxuICpcbiAqIFNldCB0aGUgd2lkdGggb2YgdGhlIGNvbnRhaW5pbmcgZWxlbWVudCB0byBhIHBpeGVsIHZhbHVlIHJldHVybmVkIGJ5IGFuIGV4cHJlc3Npb24uXG4gKlxuICogYGBgXG4gKiA8c29tZS1lbGVtZW50IFtuZ1N0eWxlXT1cInsnbWF4LXdpZHRoLnB4Jzogd2lkdGhFeHB9XCI+Li4uPC9zb21lLWVsZW1lbnQ+XG4gKiBgYGBcbiAqXG4gKiBTZXQgYSBjb2xsZWN0aW9uIG9mIHN0eWxlIHZhbHVlcyB1c2luZyBhbiBleHByZXNzaW9uIHRoYXQgcmV0dXJucyBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogYGBgXG4gKiA8c29tZS1lbGVtZW50IFtuZ1N0eWxlXT1cIm9iakV4cFwiPi4uLjwvc29tZS1lbGVtZW50PlxuICogYGBgXG4gKlxuICogQGRlc2NyaXB0aW9uXG4gKlxuICogQW4gYXR0cmlidXRlIGRpcmVjdGl2ZSB0aGF0IHVwZGF0ZXMgc3R5bGVzIGZvciB0aGUgY29udGFpbmluZyBIVE1MIGVsZW1lbnQuXG4gKiBTZXRzIG9uZSBvciBtb3JlIHN0eWxlIHByb3BlcnRpZXMsIHNwZWNpZmllZCBhcyBjb2xvbi1zZXBhcmF0ZWQga2V5LXZhbHVlIHBhaXJzLlxuICogVGhlIGtleSBpcyBhIHN0eWxlIG5hbWUsIHdpdGggYW4gb3B0aW9uYWwgYC48dW5pdD5gIHN1ZmZpeFxuICogKHN1Y2ggYXMgJ3RvcC5weCcsICdmb250LXN0eWxlLmVtJykuXG4gKiBUaGUgdmFsdWUgaXMgYW4gZXhwcmVzc2lvbiB0byBiZSBldmFsdWF0ZWQuXG4gKiBUaGUgcmVzdWx0aW5nIG5vbi1udWxsIHZhbHVlLCBleHByZXNzZWQgaW4gdGhlIGdpdmVuIHVuaXQsXG4gKiBpcyBhc3NpZ25lZCB0byB0aGUgZ2l2ZW4gc3R5bGUgcHJvcGVydHkuXG4gKiBJZiB0aGUgcmVzdWx0IG9mIGV2YWx1YXRpb24gaXMgbnVsbCwgdGhlIGNvcnJlc3BvbmRpbmcgc3R5bGUgaXMgcmVtb3ZlZC5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIE5nU3R5bGUge1xuICBjb25zdHJ1Y3RvcihfbmdFbCwgX2RpZmZlcnMsIF9yZW5kZXJlcikge1xuICAgIHRoaXMuX25nRWwgPSBfbmdFbDtcbiAgICB0aGlzLl9kaWZmZXJzID0gX2RpZmZlcnM7XG4gICAgdGhpcy5fcmVuZGVyZXIgPSBfcmVuZGVyZXI7XG4gICAgdGhpcy5fbmdTdHlsZSA9IG51bGw7XG4gICAgdGhpcy5fZGlmZmVyID0gbnVsbDtcbiAgfVxuICBzZXQgbmdTdHlsZSh2YWx1ZXMpIHtcbiAgICB0aGlzLl9uZ1N0eWxlID0gdmFsdWVzO1xuICAgIGlmICghdGhpcy5fZGlmZmVyICYmIHZhbHVlcykge1xuICAgICAgdGhpcy5fZGlmZmVyID0gdGhpcy5fZGlmZmVycy5maW5kKHZhbHVlcykuY3JlYXRlKCk7XG4gICAgfVxuICB9XG4gIG5nRG9DaGVjaygpIHtcbiAgICBpZiAodGhpcy5fZGlmZmVyKSB7XG4gICAgICBjb25zdCBjaGFuZ2VzID0gdGhpcy5fZGlmZmVyLmRpZmYodGhpcy5fbmdTdHlsZSk7XG4gICAgICBpZiAoY2hhbmdlcykge1xuICAgICAgICB0aGlzLl9hcHBseUNoYW5nZXMoY2hhbmdlcyk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIF9zZXRTdHlsZShuYW1lQW5kVW5pdCwgdmFsdWUpIHtcbiAgICBjb25zdCBbbmFtZSwgdW5pdF0gPSBuYW1lQW5kVW5pdC5zcGxpdCgnLicpO1xuICAgIGNvbnN0IGZsYWdzID0gbmFtZS5pbmRleE9mKCctJykgPT09IC0xID8gdW5kZWZpbmVkIDogUmVuZGVyZXJTdHlsZUZsYWdzMi5EYXNoQ2FzZTtcbiAgICBpZiAodmFsdWUgIT0gbnVsbCkge1xuICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0U3R5bGUodGhpcy5fbmdFbC5uYXRpdmVFbGVtZW50LCBuYW1lLCB1bml0ID8gYCR7dmFsdWV9JHt1bml0fWAgOiB2YWx1ZSwgZmxhZ3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZW5kZXJlci5yZW1vdmVTdHlsZSh0aGlzLl9uZ0VsLm5hdGl2ZUVsZW1lbnQsIG5hbWUsIGZsYWdzKTtcbiAgICB9XG4gIH1cbiAgX2FwcGx5Q2hhbmdlcyhjaGFuZ2VzKSB7XG4gICAgY2hhbmdlcy5mb3JFYWNoUmVtb3ZlZEl0ZW0ocmVjb3JkID0+IHRoaXMuX3NldFN0eWxlKHJlY29yZC5rZXksIG51bGwpKTtcbiAgICBjaGFuZ2VzLmZvckVhY2hBZGRlZEl0ZW0ocmVjb3JkID0+IHRoaXMuX3NldFN0eWxlKHJlY29yZC5rZXksIHJlY29yZC5jdXJyZW50VmFsdWUpKTtcbiAgICBjaGFuZ2VzLmZvckVhY2hDaGFuZ2VkSXRlbShyZWNvcmQgPT4gdGhpcy5fc2V0U3R5bGUocmVjb3JkLmtleSwgcmVjb3JkLmN1cnJlbnRWYWx1ZSkpO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIE5nU3R5bGVfRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IE5nU3R5bGUpKGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoaTAuRWxlbWVudFJlZiksIGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoaTAuS2V5VmFsdWVEaWZmZXJzKSwgaTAuybXJtWRpcmVjdGl2ZUluamVjdChpMC5SZW5kZXJlcjIpKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWRpciA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVEaXJlY3RpdmUoe1xuICAgICAgdHlwZTogTmdTdHlsZSxcbiAgICAgIHNlbGVjdG9yczogW1tcIlwiLCBcIm5nU3R5bGVcIiwgXCJcIl1dLFxuICAgICAgaW5wdXRzOiB7XG4gICAgICAgIG5nU3R5bGU6IFwibmdTdHlsZVwiXG4gICAgICB9LFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShOZ1N0eWxlLCBbe1xuICAgIHR5cGU6IERpcmVjdGl2ZSxcbiAgICBhcmdzOiBbe1xuICAgICAgc2VsZWN0b3I6ICdbbmdTdHlsZV0nLFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH1dXG4gIH1dLCAoKSA9PiBbe1xuICAgIHR5cGU6IGkwLkVsZW1lbnRSZWZcbiAgfSwge1xuICAgIHR5cGU6IGkwLktleVZhbHVlRGlmZmVyc1xuICB9LCB7XG4gICAgdHlwZTogaTAuUmVuZGVyZXIyXG4gIH1dLCB7XG4gICAgbmdTdHlsZTogW3tcbiAgICAgIHR5cGU6IElucHV0LFxuICAgICAgYXJnczogWyduZ1N0eWxlJ11cbiAgICB9XVxuICB9KTtcbn0pKCk7XG5cbi8qKlxuICogQG5nTW9kdWxlIENvbW1vbk1vZHVsZVxuICpcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIEluc2VydHMgYW4gZW1iZWRkZWQgdmlldyBmcm9tIGEgcHJlcGFyZWQgYFRlbXBsYXRlUmVmYC5cbiAqXG4gKiBZb3UgY2FuIGF0dGFjaCBhIGNvbnRleHQgb2JqZWN0IHRvIHRoZSBgRW1iZWRkZWRWaWV3UmVmYCBieSBzZXR0aW5nIGBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdYC5cbiAqIGBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdYCBzaG91bGQgYmUgYW4gb2JqZWN0LCB0aGUgb2JqZWN0J3Mga2V5cyB3aWxsIGJlIGF2YWlsYWJsZSBmb3IgYmluZGluZ1xuICogYnkgdGhlIGxvY2FsIHRlbXBsYXRlIGBsZXRgIGRlY2xhcmF0aW9ucy5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogYGBgXG4gKiA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidGVtcGxhdGVSZWZFeHA7IGNvbnRleHQ6IGNvbnRleHRFeHBcIj48L25nLWNvbnRhaW5lcj5cbiAqIGBgYFxuICpcbiAqIFVzaW5nIHRoZSBrZXkgYCRpbXBsaWNpdGAgaW4gdGhlIGNvbnRleHQgb2JqZWN0IHdpbGwgc2V0IGl0cyB2YWx1ZSBhcyBkZWZhdWx0LlxuICpcbiAqICMjIyBFeGFtcGxlXG4gKlxuICoge0BleGFtcGxlIGNvbW1vbi9uZ1RlbXBsYXRlT3V0bGV0L3RzL21vZHVsZS50cyByZWdpb249J05nVGVtcGxhdGVPdXRsZXQnfVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgTmdUZW1wbGF0ZU91dGxldCB7XG4gIGNvbnN0cnVjdG9yKF92aWV3Q29udGFpbmVyUmVmKSB7XG4gICAgdGhpcy5fdmlld0NvbnRhaW5lclJlZiA9IF92aWV3Q29udGFpbmVyUmVmO1xuICAgIHRoaXMuX3ZpZXdSZWYgPSBudWxsO1xuICAgIC8qKlxuICAgICAqIEEgY29udGV4dCBvYmplY3QgdG8gYXR0YWNoIHRvIHRoZSB7QGxpbmsgRW1iZWRkZWRWaWV3UmVmfS4gVGhpcyBzaG91bGQgYmUgYW5cbiAgICAgKiBvYmplY3QsIHRoZSBvYmplY3QncyBrZXlzIHdpbGwgYmUgYXZhaWxhYmxlIGZvciBiaW5kaW5nIGJ5IHRoZSBsb2NhbCB0ZW1wbGF0ZSBgbGV0YFxuICAgICAqIGRlY2xhcmF0aW9ucy5cbiAgICAgKiBVc2luZyB0aGUga2V5IGAkaW1wbGljaXRgIGluIHRoZSBjb250ZXh0IG9iamVjdCB3aWxsIHNldCBpdHMgdmFsdWUgYXMgZGVmYXVsdC5cbiAgICAgKi9cbiAgICB0aGlzLm5nVGVtcGxhdGVPdXRsZXRDb250ZXh0ID0gbnVsbDtcbiAgICAvKipcbiAgICAgKiBBIHN0cmluZyBkZWZpbmluZyB0aGUgdGVtcGxhdGUgcmVmZXJlbmNlIGFuZCBvcHRpb25hbGx5IHRoZSBjb250ZXh0IG9iamVjdCBmb3IgdGhlIHRlbXBsYXRlLlxuICAgICAqL1xuICAgIHRoaXMubmdUZW1wbGF0ZU91dGxldCA9IG51bGw7XG4gICAgLyoqIEluamVjdG9yIHRvIGJlIHVzZWQgd2l0aGluIHRoZSBlbWJlZGRlZCB2aWV3LiAqL1xuICAgIHRoaXMubmdUZW1wbGF0ZU91dGxldEluamVjdG9yID0gbnVsbDtcbiAgfVxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzKSB7XG4gICAgaWYgKHRoaXMuX3Nob3VsZFJlY3JlYXRlVmlldyhjaGFuZ2VzKSkge1xuICAgICAgY29uc3Qgdmlld0NvbnRhaW5lclJlZiA9IHRoaXMuX3ZpZXdDb250YWluZXJSZWY7XG4gICAgICBpZiAodGhpcy5fdmlld1JlZikge1xuICAgICAgICB2aWV3Q29udGFpbmVyUmVmLnJlbW92ZSh2aWV3Q29udGFpbmVyUmVmLmluZGV4T2YodGhpcy5fdmlld1JlZikpO1xuICAgICAgfVxuICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gb3V0bGV0LCBjbGVhciB0aGUgZGVzdHJveWVkIHZpZXcgcmVmLlxuICAgICAgaWYgKCF0aGlzLm5nVGVtcGxhdGVPdXRsZXQpIHtcbiAgICAgICAgdGhpcy5fdmlld1JlZiA9IG51bGw7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIC8vIENyZWF0ZSBhIGNvbnRleHQgZm9yd2FyZCBgUHJveHlgIHRoYXQgd2lsbCBhbHdheXMgYmluZCB0byB0aGUgdXNlci1zcGVjaWZpZWQgY29udGV4dCxcbiAgICAgIC8vIHdpdGhvdXQgaGF2aW5nIHRvIGRlc3Ryb3kgYW5kIHJlLWNyZWF0ZSB2aWV3cyB3aGVuZXZlciB0aGUgY29udGV4dCBjaGFuZ2VzLlxuICAgICAgY29uc3Qgdmlld0NvbnRleHQgPSB0aGlzLl9jcmVhdGVDb250ZXh0Rm9yd2FyZFByb3h5KCk7XG4gICAgICB0aGlzLl92aWV3UmVmID0gdmlld0NvbnRhaW5lclJlZi5jcmVhdGVFbWJlZGRlZFZpZXcodGhpcy5uZ1RlbXBsYXRlT3V0bGV0LCB2aWV3Q29udGV4dCwge1xuICAgICAgICBpbmplY3RvcjogdGhpcy5uZ1RlbXBsYXRlT3V0bGV0SW5qZWN0b3IgPz8gdW5kZWZpbmVkXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIFdlIG5lZWQgdG8gcmUtY3JlYXRlIGV4aXN0aW5nIGVtYmVkZGVkIHZpZXcgaWYgZWl0aGVyIGlzIHRydWU6XG4gICAqIC0gdGhlIG91dGxldCBjaGFuZ2VkLlxuICAgKiAtIHRoZSBpbmplY3RvciBjaGFuZ2VkLlxuICAgKi9cbiAgX3Nob3VsZFJlY3JlYXRlVmlldyhjaGFuZ2VzKSB7XG4gICAgcmV0dXJuICEhY2hhbmdlc1snbmdUZW1wbGF0ZU91dGxldCddIHx8ICEhY2hhbmdlc1snbmdUZW1wbGF0ZU91dGxldEluamVjdG9yJ107XG4gIH1cbiAgLyoqXG4gICAqIEZvciBhIGdpdmVuIG91dGxldCBpbnN0YW5jZSwgd2UgY3JlYXRlIGEgcHJveHkgb2JqZWN0IHRoYXQgZGVsZWdhdGVzXG4gICAqIHRvIHRoZSB1c2VyLXNwZWNpZmllZCBjb250ZXh0LiBUaGlzIGFsbG93cyBjaGFuZ2luZywgb3Igc3dhcHBpbmcgb3V0XG4gICAqIHRoZSBjb250ZXh0IG9iamVjdCBjb21wbGV0ZWx5IHdpdGhvdXQgaGF2aW5nIHRvIGRlc3Ryb3kvcmUtY3JlYXRlIHRoZSB2aWV3LlxuICAgKi9cbiAgX2NyZWF0ZUNvbnRleHRGb3J3YXJkUHJveHkoKSB7XG4gICAgcmV0dXJuIG5ldyBQcm94eSh7fSwge1xuICAgICAgc2V0OiAoX3RhcmdldCwgcHJvcCwgbmV3VmFsdWUpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLm5nVGVtcGxhdGVPdXRsZXRDb250ZXh0KSB7XG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBSZWZsZWN0LnNldCh0aGlzLm5nVGVtcGxhdGVPdXRsZXRDb250ZXh0LCBwcm9wLCBuZXdWYWx1ZSk7XG4gICAgICB9LFxuICAgICAgZ2V0OiAoX3RhcmdldCwgcHJvcCwgcmVjZWl2ZXIpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLm5nVGVtcGxhdGVPdXRsZXRDb250ZXh0KSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gUmVmbGVjdC5nZXQodGhpcy5uZ1RlbXBsYXRlT3V0bGV0Q29udGV4dCwgcHJvcCwgcmVjZWl2ZXIpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIE5nVGVtcGxhdGVPdXRsZXRfRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IE5nVGVtcGxhdGVPdXRsZXQpKGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoaTAuVmlld0NvbnRhaW5lclJlZikpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZGlyID0gLyogQF9fUFVSRV9fICovaTAuybXJtWRlZmluZURpcmVjdGl2ZSh7XG4gICAgICB0eXBlOiBOZ1RlbXBsYXRlT3V0bGV0LFxuICAgICAgc2VsZWN0b3JzOiBbW1wiXCIsIFwibmdUZW1wbGF0ZU91dGxldFwiLCBcIlwiXV0sXG4gICAgICBpbnB1dHM6IHtcbiAgICAgICAgbmdUZW1wbGF0ZU91dGxldENvbnRleHQ6IFwibmdUZW1wbGF0ZU91dGxldENvbnRleHRcIixcbiAgICAgICAgbmdUZW1wbGF0ZU91dGxldDogXCJuZ1RlbXBsYXRlT3V0bGV0XCIsXG4gICAgICAgIG5nVGVtcGxhdGVPdXRsZXRJbmplY3RvcjogXCJuZ1RlbXBsYXRlT3V0bGV0SW5qZWN0b3JcIlxuICAgICAgfSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgICBmZWF0dXJlczogW2kwLsm1ybVOZ09uQ2hhbmdlc0ZlYXR1cmVdXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKE5nVGVtcGxhdGVPdXRsZXQsIFt7XG4gICAgdHlwZTogRGlyZWN0aXZlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBzZWxlY3RvcjogJ1tuZ1RlbXBsYXRlT3V0bGV0XScsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfV1cbiAgfV0sICgpID0+IFt7XG4gICAgdHlwZTogaTAuVmlld0NvbnRhaW5lclJlZlxuICB9XSwge1xuICAgIG5nVGVtcGxhdGVPdXRsZXRDb250ZXh0OiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XSxcbiAgICBuZ1RlbXBsYXRlT3V0bGV0OiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XSxcbiAgICBuZ1RlbXBsYXRlT3V0bGV0SW5qZWN0b3I6IFt7XG4gICAgICB0eXBlOiBJbnB1dFxuICAgIH1dXG4gIH0pO1xufSkoKTtcblxuLyoqXG4gKiBBIGNvbGxlY3Rpb24gb2YgQW5ndWxhciBkaXJlY3RpdmVzIHRoYXQgYXJlIGxpa2VseSB0byBiZSB1c2VkIGluIGVhY2ggYW5kIGV2ZXJ5IEFuZ3VsYXJcbiAqIGFwcGxpY2F0aW9uLlxuICovXG5jb25zdCBDT01NT05fRElSRUNUSVZFUyA9IFtOZ0NsYXNzLCBOZ0NvbXBvbmVudE91dGxldCwgTmdGb3JPZiwgTmdJZiwgTmdUZW1wbGF0ZU91dGxldCwgTmdTdHlsZSwgTmdTd2l0Y2gsIE5nU3dpdGNoQ2FzZSwgTmdTd2l0Y2hEZWZhdWx0LCBOZ1BsdXJhbCwgTmdQbHVyYWxDYXNlXTtcbmZ1bmN0aW9uIGludmFsaWRQaXBlQXJndW1lbnRFcnJvcih0eXBlLCB2YWx1ZSkge1xuICByZXR1cm4gbmV3IMm1UnVudGltZUVycm9yKDIxMDAgLyogUnVudGltZUVycm9yQ29kZS5JTlZBTElEX1BJUEVfQVJHVU1FTlQgKi8sIG5nRGV2TW9kZSAmJiBgSW52YWxpZFBpcGVBcmd1bWVudDogJyR7dmFsdWV9JyBmb3IgcGlwZSAnJHvJtXN0cmluZ2lmeSh0eXBlKX0nYCk7XG59XG5jbGFzcyBTdWJzY3JpYmFibGVTdHJhdGVneSB7XG4gIGNyZWF0ZVN1YnNjcmlwdGlvbihhc3luYywgdXBkYXRlTGF0ZXN0VmFsdWUpIHtcbiAgICAvLyBTdWJzY3JpcHRpb24gY2FuIGJlIHNpZGUtZWZmZWN0ZnVsLCBhbmQgd2UgZG9uJ3Qgd2FudCBhbnkgc2lnbmFsIHJlYWRzIHdoaWNoIGhhcHBlbiBpbiB0aGVcbiAgICAvLyBzaWRlIGVmZmVjdCBvZiB0aGUgc3Vic2NyaXB0aW9uIHRvIGJlIHRyYWNrZWQgYnkgYSBjb21wb25lbnQncyB0ZW1wbGF0ZSB3aGVuIHRoYXRcbiAgICAvLyBzdWJzY3JpcHRpb24gaXMgdHJpZ2dlcmVkIHZpYSB0aGUgYXN5bmMgcGlwZS4gU28gd2Ugd3JhcCB0aGUgc3Vic2NyaXB0aW9uIGluIGB1bnRyYWNrZWRgIHRvXG4gICAgLy8gZGVjb3VwbGUgZnJvbSB0aGUgY3VycmVudCByZWFjdGl2ZSBjb250ZXh0LlxuICAgIC8vXG4gICAgLy8gYHVudHJhY2tlZGAgYWxzbyBwcmV2ZW50cyBzaWduYWwgX3dyaXRlc18gd2hpY2ggaGFwcGVuIGluIHRoZSBzdWJzY3JpcHRpb24gc2lkZSBlZmZlY3QgZnJvbVxuICAgIC8vIGJlaW5nIHRyZWF0ZWQgYXMgc2lnbmFsIHdyaXRlcyBkdXJpbmcgdGhlIHRlbXBsYXRlIGV2YWx1YXRpb24gKHdoaWNoIHRocm93cyBlcnJvcnMpLlxuICAgIHJldHVybiB1bnRyYWNrZWQoKCkgPT4gYXN5bmMuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IHVwZGF0ZUxhdGVzdFZhbHVlLFxuICAgICAgZXJyb3I6IGUgPT4ge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgIH0pKTtcbiAgfVxuICBkaXNwb3NlKHN1YnNjcmlwdGlvbikge1xuICAgIC8vIFNlZSB0aGUgY29tbWVudCBpbiBgY3JlYXRlU3Vic2NyaXB0aW9uYCBhYm92ZSBvbiB0aGUgdXNlIG9mIGB1bnRyYWNrZWRgLlxuICAgIHVudHJhY2tlZCgoKSA9PiBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKSk7XG4gIH1cbn1cbmNsYXNzIFByb21pc2VTdHJhdGVneSB7XG4gIGNyZWF0ZVN1YnNjcmlwdGlvbihhc3luYywgdXBkYXRlTGF0ZXN0VmFsdWUpIHtcbiAgICByZXR1cm4gYXN5bmMudGhlbih1cGRhdGVMYXRlc3RWYWx1ZSwgZSA9PiB7XG4gICAgICB0aHJvdyBlO1xuICAgIH0pO1xuICB9XG4gIGRpc3Bvc2Uoc3Vic2NyaXB0aW9uKSB7fVxufVxuY29uc3QgX3Byb21pc2VTdHJhdGVneSA9IG5ldyBQcm9taXNlU3RyYXRlZ3koKTtcbmNvbnN0IF9zdWJzY3JpYmFibGVTdHJhdGVneSA9IG5ldyBTdWJzY3JpYmFibGVTdHJhdGVneSgpO1xuLyoqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiBVbndyYXBzIGEgdmFsdWUgZnJvbSBhbiBhc3luY2hyb25vdXMgcHJpbWl0aXZlLlxuICpcbiAqIFRoZSBgYXN5bmNgIHBpcGUgc3Vic2NyaWJlcyB0byBhbiBgT2JzZXJ2YWJsZWAgb3IgYFByb21pc2VgIGFuZCByZXR1cm5zIHRoZSBsYXRlc3QgdmFsdWUgaXQgaGFzXG4gKiBlbWl0dGVkLiBXaGVuIGEgbmV3IHZhbHVlIGlzIGVtaXR0ZWQsIHRoZSBgYXN5bmNgIHBpcGUgbWFya3MgdGhlIGNvbXBvbmVudCB0byBiZSBjaGVja2VkIGZvclxuICogY2hhbmdlcy4gV2hlbiB0aGUgY29tcG9uZW50IGdldHMgZGVzdHJveWVkLCB0aGUgYGFzeW5jYCBwaXBlIHVuc3Vic2NyaWJlcyBhdXRvbWF0aWNhbGx5IHRvIGF2b2lkXG4gKiBwb3RlbnRpYWwgbWVtb3J5IGxlYWtzLiBXaGVuIHRoZSByZWZlcmVuY2Ugb2YgdGhlIGV4cHJlc3Npb24gY2hhbmdlcywgdGhlIGBhc3luY2AgcGlwZVxuICogYXV0b21hdGljYWxseSB1bnN1YnNjcmliZXMgZnJvbSB0aGUgb2xkIGBPYnNlcnZhYmxlYCBvciBgUHJvbWlzZWAgYW5kIHN1YnNjcmliZXMgdG8gdGhlIG5ldyBvbmUuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiAjIyMgRXhhbXBsZXNcbiAqXG4gKiBUaGlzIGV4YW1wbGUgYmluZHMgYSBgUHJvbWlzZWAgdG8gdGhlIHZpZXcuIENsaWNraW5nIHRoZSBgUmVzb2x2ZWAgYnV0dG9uIHJlc29sdmVzIHRoZVxuICogcHJvbWlzZS5cbiAqXG4gKiB7QGV4YW1wbGUgY29tbW9uL3BpcGVzL3RzL2FzeW5jX3BpcGUudHMgcmVnaW9uPSdBc3luY1BpcGVQcm9taXNlJ31cbiAqXG4gKiBJdCdzIGFsc28gcG9zc2libGUgdG8gdXNlIGBhc3luY2Agd2l0aCBPYnNlcnZhYmxlcy4gVGhlIGV4YW1wbGUgYmVsb3cgYmluZHMgdGhlIGB0aW1lYCBPYnNlcnZhYmxlXG4gKiB0byB0aGUgdmlldy4gVGhlIE9ic2VydmFibGUgY29udGludW91c2x5IHVwZGF0ZXMgdGhlIHZpZXcgd2l0aCB0aGUgY3VycmVudCB0aW1lLlxuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vcGlwZXMvdHMvYXN5bmNfcGlwZS50cyByZWdpb249J0FzeW5jUGlwZU9ic2VydmFibGUnfVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgQXN5bmNQaXBlIHtcbiAgY29uc3RydWN0b3IocmVmKSB7XG4gICAgdGhpcy5fbGF0ZXN0VmFsdWUgPSBudWxsO1xuICAgIHRoaXMubWFya0ZvckNoZWNrT25WYWx1ZVVwZGF0ZSA9IHRydWU7XG4gICAgdGhpcy5fc3Vic2NyaXB0aW9uID0gbnVsbDtcbiAgICB0aGlzLl9vYmogPSBudWxsO1xuICAgIHRoaXMuX3N0cmF0ZWd5ID0gbnVsbDtcbiAgICAvLyBBc3NpZ24gYHJlZmAgaW50byBgdGhpcy5fcmVmYCBtYW51YWxseSBpbnN0ZWFkIG9mIGRlY2xhcmluZyBgX3JlZmAgaW4gdGhlIGNvbnN0cnVjdG9yXG4gICAgLy8gcGFyYW1ldGVyIGxpc3QsIGFzIHRoZSB0eXBlIG9mIGB0aGlzLl9yZWZgIGluY2x1ZGVzIGBudWxsYCB1bmxpa2UgdGhlIHR5cGUgb2YgYHJlZmAuXG4gICAgdGhpcy5fcmVmID0gcmVmO1xuICB9XG4gIG5nT25EZXN0cm95KCkge1xuICAgIGlmICh0aGlzLl9zdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMuX2Rpc3Bvc2UoKTtcbiAgICB9XG4gICAgLy8gQ2xlYXIgdGhlIGBDaGFuZ2VEZXRlY3RvclJlZmAgYW5kIGl0cyBhc3NvY2lhdGlvbiB3aXRoIHRoZSB2aWV3IGRhdGEsIHRvIG1pdGlnYXRlXG4gICAgLy8gcG90ZW50aWFsIG1lbW9yeSBsZWFrcyBpbiBPYnNlcnZhYmxlcyB0aGF0IGNvdWxkIG90aGVyd2lzZSBjYXVzZSB0aGUgdmlldyBkYXRhIHRvXG4gICAgLy8gYmUgcmV0YWluZWQuXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9pc3N1ZXMvMTc2MjRcbiAgICB0aGlzLl9yZWYgPSBudWxsO1xuICB9XG4gIHRyYW5zZm9ybShvYmopIHtcbiAgICBpZiAoIXRoaXMuX29iaikge1xuICAgICAgaWYgKG9iaikge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIC8vIE9ubHkgY2FsbCBgbWFya0ZvckNoZWNrYCBpZiB0aGUgdmFsdWUgaXMgdXBkYXRlZCBhc3luY2hyb25vdXNseS5cbiAgICAgICAgICAvLyBTeW5jaHJvbm91cyB1cGRhdGVzIF9kdXJpbmdfIHN1YnNjcmlwdGlvbiBzaG91bGQgbm90IHdhc3RlZnVsbHkgbWFyayBmb3IgY2hlY2sgLVxuICAgICAgICAgIC8vIHRoaXMgdmFsdWUgaXMgYWxyZWFkeSBnb2luZyB0byBiZSByZXR1cm5lZCBmcm9tIHRoZSB0cmFuc2Zvcm0gZnVuY3Rpb24uXG4gICAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2tPblZhbHVlVXBkYXRlID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5fc3Vic2NyaWJlKG9iaik7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgdGhpcy5tYXJrRm9yQ2hlY2tPblZhbHVlVXBkYXRlID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMuX2xhdGVzdFZhbHVlO1xuICAgIH1cbiAgICBpZiAob2JqICE9PSB0aGlzLl9vYmopIHtcbiAgICAgIHRoaXMuX2Rpc3Bvc2UoKTtcbiAgICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybShvYmopO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fbGF0ZXN0VmFsdWU7XG4gIH1cbiAgX3N1YnNjcmliZShvYmopIHtcbiAgICB0aGlzLl9vYmogPSBvYmo7XG4gICAgdGhpcy5fc3RyYXRlZ3kgPSB0aGlzLl9zZWxlY3RTdHJhdGVneShvYmopO1xuICAgIHRoaXMuX3N1YnNjcmlwdGlvbiA9IHRoaXMuX3N0cmF0ZWd5LmNyZWF0ZVN1YnNjcmlwdGlvbihvYmosIHZhbHVlID0+IHRoaXMuX3VwZGF0ZUxhdGVzdFZhbHVlKG9iaiwgdmFsdWUpKTtcbiAgfVxuICBfc2VsZWN0U3RyYXRlZ3kob2JqKSB7XG4gICAgaWYgKMm1aXNQcm9taXNlKG9iaikpIHtcbiAgICAgIHJldHVybiBfcHJvbWlzZVN0cmF0ZWd5O1xuICAgIH1cbiAgICBpZiAoybVpc1N1YnNjcmliYWJsZShvYmopKSB7XG4gICAgICByZXR1cm4gX3N1YnNjcmliYWJsZVN0cmF0ZWd5O1xuICAgIH1cbiAgICB0aHJvdyBpbnZhbGlkUGlwZUFyZ3VtZW50RXJyb3IoQXN5bmNQaXBlLCBvYmopO1xuICB9XG4gIF9kaXNwb3NlKCkge1xuICAgIC8vIE5vdGU6IGBkaXNwb3NlYCBpcyBvbmx5IGNhbGxlZCBpZiBhIHN1YnNjcmlwdGlvbiBoYXMgYmVlbiBpbml0aWFsaXplZCBiZWZvcmUsIGluZGljYXRpbmdcbiAgICAvLyB0aGF0IGB0aGlzLl9zdHJhdGVneWAgaXMgYWxzbyBhdmFpbGFibGUuXG4gICAgdGhpcy5fc3RyYXRlZ3kuZGlzcG9zZSh0aGlzLl9zdWJzY3JpcHRpb24pO1xuICAgIHRoaXMuX2xhdGVzdFZhbHVlID0gbnVsbDtcbiAgICB0aGlzLl9zdWJzY3JpcHRpb24gPSBudWxsO1xuICAgIHRoaXMuX29iaiA9IG51bGw7XG4gIH1cbiAgX3VwZGF0ZUxhdGVzdFZhbHVlKGFzeW5jLCB2YWx1ZSkge1xuICAgIGlmIChhc3luYyA9PT0gdGhpcy5fb2JqKSB7XG4gICAgICB0aGlzLl9sYXRlc3RWYWx1ZSA9IHZhbHVlO1xuICAgICAgaWYgKHRoaXMubWFya0ZvckNoZWNrT25WYWx1ZVVwZGF0ZSkge1xuICAgICAgICB0aGlzLl9yZWY/Lm1hcmtGb3JDaGVjaygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBBc3luY1BpcGVfRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IEFzeW5jUGlwZSkoaTAuybXJtWRpcmVjdGl2ZUluamVjdChpMC5DaGFuZ2VEZXRlY3RvclJlZiwgMTYpKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXBpcGUgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lUGlwZSh7XG4gICAgICBuYW1lOiBcImFzeW5jXCIsXG4gICAgICB0eXBlOiBBc3luY1BpcGUsXG4gICAgICBwdXJlOiBmYWxzZSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9KTtcbiAgfVxufVxuKCgpID0+IHtcbiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09IFwidW5kZWZpbmVkXCIgfHwgbmdEZXZNb2RlKSAmJiBpMC7JtXNldENsYXNzTWV0YWRhdGEoQXN5bmNQaXBlLCBbe1xuICAgIHR5cGU6IFBpcGUsXG4gICAgYXJnczogW3tcbiAgICAgIG5hbWU6ICdhc3luYycsXG4gICAgICBwdXJlOiBmYWxzZSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgKCkgPT4gW3tcbiAgICB0eXBlOiBpMC5DaGFuZ2VEZXRlY3RvclJlZlxuICB9XSwgbnVsbCk7XG59KSgpO1xuXG4vKipcbiAqIFRyYW5zZm9ybXMgdGV4dCB0byBhbGwgbG93ZXIgY2FzZS5cbiAqXG4gKiBAc2VlIHtAbGluayBVcHBlckNhc2VQaXBlfVxuICogQHNlZSB7QGxpbmsgVGl0bGVDYXNlUGlwZX1cbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIGRlZmluZXMgYSB2aWV3IHRoYXQgYWxsb3dzIHRoZSB1c2VyIHRvIGVudGVyXG4gKiB0ZXh0LCBhbmQgdGhlbiB1c2VzIHRoZSBwaXBlIHRvIGNvbnZlcnQgdGhlIGlucHV0IHRleHQgdG8gYWxsIGxvd2VyIGNhc2UuXG4gKlxuICogPGNvZGUtZXhhbXBsZSBwYXRoPVwiY29tbW9uL3BpcGVzL3RzL2xvd2VydXBwZXJfcGlwZS50c1wiIHJlZ2lvbj0nTG93ZXJVcHBlclBpcGUnPjwvY29kZS1leGFtcGxlPlxuICpcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgTG93ZXJDYXNlUGlwZSB7XG4gIHRyYW5zZm9ybSh2YWx1ZSkge1xuICAgIGlmICh2YWx1ZSA9PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgdGhyb3cgaW52YWxpZFBpcGVBcmd1bWVudEVycm9yKExvd2VyQ2FzZVBpcGUsIHZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlLnRvTG93ZXJDYXNlKCk7XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gTG93ZXJDYXNlUGlwZV9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgTG93ZXJDYXNlUGlwZSkoKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXBpcGUgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lUGlwZSh7XG4gICAgICBuYW1lOiBcImxvd2VyY2FzZVwiLFxuICAgICAgdHlwZTogTG93ZXJDYXNlUGlwZSxcbiAgICAgIHB1cmU6IHRydWUsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKExvd2VyQ2FzZVBpcGUsIFt7XG4gICAgdHlwZTogUGlwZSxcbiAgICBhcmdzOiBbe1xuICAgICAgbmFtZTogJ2xvd2VyY2FzZScsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfV1cbiAgfV0sIG51bGwsIG51bGwpO1xufSkoKTtcbi8vXG4vLyBSZWdleCBiZWxvdyBtYXRjaGVzIGFueSBVbmljb2RlIHdvcmQgYW5kIG51bWJlciBjb21wYXRpYmxlIHdpdGggRVM1LiBJbiBFUzIwMTggdGhlIHNhbWUgcmVzdWx0XG4vLyBjYW4gYmUgYWNoaWV2ZWQgYnkgdXNpbmcgL1swLTlcXHB7TH1dXFxTKi9ndSBhbmQgYWxzbyBrbm93biBhcyBVbmljb2RlIFByb3BlcnR5IEVzY2FwZXNcbi8vIChodHRwczovLzJhbGl0eS5jb20vMjAxNy8wNy9yZWdleHAtdW5pY29kZS1wcm9wZXJ0eS1lc2NhcGVzLmh0bWwpLiBTaW5jZSB0aGVyZSBpcyBub1xuLy8gdHJhbnNwaWxhdGlvbiBvZiB0aGlzIGZ1bmN0aW9uYWxpdHkgZG93biB0byBFUzUgd2l0aG91dCBleHRlcm5hbCB0b29sLCB0aGUgb25seSBzb2x1dGlvbiBpc1xuLy8gdG8gdXNlIGFscmVhZHkgdHJhbnNwaWxlZCBmb3JtLiBFeGFtcGxlIGNhbiBiZSBmb3VuZCBoZXJlIC1cbi8vIGh0dHBzOi8vbW90aGVyZWZmLmluL3JlZ2V4cHUjaW5wdXQ9dmFyK3JlZ2V4KyUzRCslMkYlNUIwLTklNUNwJTdCTCU3RCU1RCU1Q1MqJTJGZ3UlM0IlMEElMEEmdW5pY29kZVByb3BlcnR5RXNjYXBlPTFcbi8vXG5jb25zdCB1bmljb2RlV29yZE1hdGNoID0gLyg/OlswLTlBLVphLXpcXHhBQVxceEI1XFx4QkFcXHhDMC1cXHhENlxceEQ4LVxceEY2XFx4RjgtXFx1MDJDMVxcdTAyQzYtXFx1MDJEMVxcdTAyRTAtXFx1MDJFNFxcdTAyRUNcXHUwMkVFXFx1MDM3MC1cXHUwMzc0XFx1MDM3NlxcdTAzNzdcXHUwMzdBLVxcdTAzN0RcXHUwMzdGXFx1MDM4NlxcdTAzODgtXFx1MDM4QVxcdTAzOENcXHUwMzhFLVxcdTAzQTFcXHUwM0EzLVxcdTAzRjVcXHUwM0Y3LVxcdTA0ODFcXHUwNDhBLVxcdTA1MkZcXHUwNTMxLVxcdTA1NTZcXHUwNTU5XFx1MDU2MC1cXHUwNTg4XFx1MDVEMC1cXHUwNUVBXFx1MDVFRi1cXHUwNUYyXFx1MDYyMC1cXHUwNjRBXFx1MDY2RVxcdTA2NkZcXHUwNjcxLVxcdTA2RDNcXHUwNkQ1XFx1MDZFNVxcdTA2RTZcXHUwNkVFXFx1MDZFRlxcdTA2RkEtXFx1MDZGQ1xcdTA2RkZcXHUwNzEwXFx1MDcxMi1cXHUwNzJGXFx1MDc0RC1cXHUwN0E1XFx1MDdCMVxcdTA3Q0EtXFx1MDdFQVxcdTA3RjRcXHUwN0Y1XFx1MDdGQVxcdTA4MDAtXFx1MDgxNVxcdTA4MUFcXHUwODI0XFx1MDgyOFxcdTA4NDAtXFx1MDg1OFxcdTA4NjAtXFx1MDg2QVxcdTA4NzAtXFx1MDg4N1xcdTA4ODktXFx1MDg4RVxcdTA4QTAtXFx1MDhDOVxcdTA5MDQtXFx1MDkzOVxcdTA5M0RcXHUwOTUwXFx1MDk1OC1cXHUwOTYxXFx1MDk3MS1cXHUwOTgwXFx1MDk4NS1cXHUwOThDXFx1MDk4RlxcdTA5OTBcXHUwOTkzLVxcdTA5QThcXHUwOUFBLVxcdTA5QjBcXHUwOUIyXFx1MDlCNi1cXHUwOUI5XFx1MDlCRFxcdTA5Q0VcXHUwOURDXFx1MDlERFxcdTA5REYtXFx1MDlFMVxcdTA5RjBcXHUwOUYxXFx1MDlGQ1xcdTBBMDUtXFx1MEEwQVxcdTBBMEZcXHUwQTEwXFx1MEExMy1cXHUwQTI4XFx1MEEyQS1cXHUwQTMwXFx1MEEzMlxcdTBBMzNcXHUwQTM1XFx1MEEzNlxcdTBBMzhcXHUwQTM5XFx1MEE1OS1cXHUwQTVDXFx1MEE1RVxcdTBBNzItXFx1MEE3NFxcdTBBODUtXFx1MEE4RFxcdTBBOEYtXFx1MEE5MVxcdTBBOTMtXFx1MEFBOFxcdTBBQUEtXFx1MEFCMFxcdTBBQjJcXHUwQUIzXFx1MEFCNS1cXHUwQUI5XFx1MEFCRFxcdTBBRDBcXHUwQUUwXFx1MEFFMVxcdTBBRjlcXHUwQjA1LVxcdTBCMENcXHUwQjBGXFx1MEIxMFxcdTBCMTMtXFx1MEIyOFxcdTBCMkEtXFx1MEIzMFxcdTBCMzJcXHUwQjMzXFx1MEIzNS1cXHUwQjM5XFx1MEIzRFxcdTBCNUNcXHUwQjVEXFx1MEI1Ri1cXHUwQjYxXFx1MEI3MVxcdTBCODNcXHUwQjg1LVxcdTBCOEFcXHUwQjhFLVxcdTBCOTBcXHUwQjkyLVxcdTBCOTVcXHUwQjk5XFx1MEI5QVxcdTBCOUNcXHUwQjlFXFx1MEI5RlxcdTBCQTNcXHUwQkE0XFx1MEJBOC1cXHUwQkFBXFx1MEJBRS1cXHUwQkI5XFx1MEJEMFxcdTBDMDUtXFx1MEMwQ1xcdTBDMEUtXFx1MEMxMFxcdTBDMTItXFx1MEMyOFxcdTBDMkEtXFx1MEMzOVxcdTBDM0RcXHUwQzU4LVxcdTBDNUFcXHUwQzVEXFx1MEM2MFxcdTBDNjFcXHUwQzgwXFx1MEM4NS1cXHUwQzhDXFx1MEM4RS1cXHUwQzkwXFx1MEM5Mi1cXHUwQ0E4XFx1MENBQS1cXHUwQ0IzXFx1MENCNS1cXHUwQ0I5XFx1MENCRFxcdTBDRERcXHUwQ0RFXFx1MENFMFxcdTBDRTFcXHUwQ0YxXFx1MENGMlxcdTBEMDQtXFx1MEQwQ1xcdTBEMEUtXFx1MEQxMFxcdTBEMTItXFx1MEQzQVxcdTBEM0RcXHUwRDRFXFx1MEQ1NC1cXHUwRDU2XFx1MEQ1Ri1cXHUwRDYxXFx1MEQ3QS1cXHUwRDdGXFx1MEQ4NS1cXHUwRDk2XFx1MEQ5QS1cXHUwREIxXFx1MERCMy1cXHUwREJCXFx1MERCRFxcdTBEQzAtXFx1MERDNlxcdTBFMDEtXFx1MEUzMFxcdTBFMzJcXHUwRTMzXFx1MEU0MC1cXHUwRTQ2XFx1MEU4MVxcdTBFODJcXHUwRTg0XFx1MEU4Ni1cXHUwRThBXFx1MEU4Qy1cXHUwRUEzXFx1MEVBNVxcdTBFQTctXFx1MEVCMFxcdTBFQjJcXHUwRUIzXFx1MEVCRFxcdTBFQzAtXFx1MEVDNFxcdTBFQzZcXHUwRURDLVxcdTBFREZcXHUwRjAwXFx1MEY0MC1cXHUwRjQ3XFx1MEY0OS1cXHUwRjZDXFx1MEY4OC1cXHUwRjhDXFx1MTAwMC1cXHUxMDJBXFx1MTAzRlxcdTEwNTAtXFx1MTA1NVxcdTEwNUEtXFx1MTA1RFxcdTEwNjFcXHUxMDY1XFx1MTA2NlxcdTEwNkUtXFx1MTA3MFxcdTEwNzUtXFx1MTA4MVxcdTEwOEVcXHUxMEEwLVxcdTEwQzVcXHUxMEM3XFx1MTBDRFxcdTEwRDAtXFx1MTBGQVxcdTEwRkMtXFx1MTI0OFxcdTEyNEEtXFx1MTI0RFxcdTEyNTAtXFx1MTI1NlxcdTEyNThcXHUxMjVBLVxcdTEyNURcXHUxMjYwLVxcdTEyODhcXHUxMjhBLVxcdTEyOERcXHUxMjkwLVxcdTEyQjBcXHUxMkIyLVxcdTEyQjVcXHUxMkI4LVxcdTEyQkVcXHUxMkMwXFx1MTJDMi1cXHUxMkM1XFx1MTJDOC1cXHUxMkQ2XFx1MTJEOC1cXHUxMzEwXFx1MTMxMi1cXHUxMzE1XFx1MTMxOC1cXHUxMzVBXFx1MTM4MC1cXHUxMzhGXFx1MTNBMC1cXHUxM0Y1XFx1MTNGOC1cXHUxM0ZEXFx1MTQwMS1cXHUxNjZDXFx1MTY2Ri1cXHUxNjdGXFx1MTY4MS1cXHUxNjlBXFx1MTZBMC1cXHUxNkVBXFx1MTZGMS1cXHUxNkY4XFx1MTcwMC1cXHUxNzExXFx1MTcxRi1cXHUxNzMxXFx1MTc0MC1cXHUxNzUxXFx1MTc2MC1cXHUxNzZDXFx1MTc2RS1cXHUxNzcwXFx1MTc4MC1cXHUxN0IzXFx1MTdEN1xcdTE3RENcXHUxODIwLVxcdTE4NzhcXHUxODgwLVxcdTE4ODRcXHUxODg3LVxcdTE4QThcXHUxOEFBXFx1MThCMC1cXHUxOEY1XFx1MTkwMC1cXHUxOTFFXFx1MTk1MC1cXHUxOTZEXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOUFCXFx1MTlCMC1cXHUxOUM5XFx1MUEwMC1cXHUxQTE2XFx1MUEyMC1cXHUxQTU0XFx1MUFBN1xcdTFCMDUtXFx1MUIzM1xcdTFCNDUtXFx1MUI0Q1xcdTFCODMtXFx1MUJBMFxcdTFCQUVcXHUxQkFGXFx1MUJCQS1cXHUxQkU1XFx1MUMwMC1cXHUxQzIzXFx1MUM0RC1cXHUxQzRGXFx1MUM1QS1cXHUxQzdEXFx1MUM4MC1cXHUxQzg4XFx1MUM5MC1cXHUxQ0JBXFx1MUNCRC1cXHUxQ0JGXFx1MUNFOS1cXHUxQ0VDXFx1MUNFRS1cXHUxQ0YzXFx1MUNGNVxcdTFDRjZcXHUxQ0ZBXFx1MUQwMC1cXHUxREJGXFx1MUUwMC1cXHUxRjE1XFx1MUYxOC1cXHUxRjFEXFx1MUYyMC1cXHUxRjQ1XFx1MUY0OC1cXHUxRjREXFx1MUY1MC1cXHUxRjU3XFx1MUY1OVxcdTFGNUJcXHUxRjVEXFx1MUY1Ri1cXHUxRjdEXFx1MUY4MC1cXHUxRkI0XFx1MUZCNi1cXHUxRkJDXFx1MUZCRVxcdTFGQzItXFx1MUZDNFxcdTFGQzYtXFx1MUZDQ1xcdTFGRDAtXFx1MUZEM1xcdTFGRDYtXFx1MUZEQlxcdTFGRTAtXFx1MUZFQ1xcdTFGRjItXFx1MUZGNFxcdTFGRjYtXFx1MUZGQ1xcdTIwNzFcXHUyMDdGXFx1MjA5MC1cXHUyMDlDXFx1MjEwMlxcdTIxMDdcXHUyMTBBLVxcdTIxMTNcXHUyMTE1XFx1MjExOS1cXHUyMTFEXFx1MjEyNFxcdTIxMjZcXHUyMTI4XFx1MjEyQS1cXHUyMTJEXFx1MjEyRi1cXHUyMTM5XFx1MjEzQy1cXHUyMTNGXFx1MjE0NS1cXHUyMTQ5XFx1MjE0RVxcdTIxODNcXHUyMTg0XFx1MkMwMC1cXHUyQ0U0XFx1MkNFQi1cXHUyQ0VFXFx1MkNGMlxcdTJDRjNcXHUyRDAwLVxcdTJEMjVcXHUyRDI3XFx1MkQyRFxcdTJEMzAtXFx1MkQ2N1xcdTJENkZcXHUyRDgwLVxcdTJEOTZcXHUyREEwLVxcdTJEQTZcXHUyREE4LVxcdTJEQUVcXHUyREIwLVxcdTJEQjZcXHUyREI4LVxcdTJEQkVcXHUyREMwLVxcdTJEQzZcXHUyREM4LVxcdTJEQ0VcXHUyREQwLVxcdTJERDZcXHUyREQ4LVxcdTJEREVcXHUyRTJGXFx1MzAwNVxcdTMwMDZcXHUzMDMxLVxcdTMwMzVcXHUzMDNCXFx1MzAzQ1xcdTMwNDEtXFx1MzA5NlxcdTMwOUQtXFx1MzA5RlxcdTMwQTEtXFx1MzBGQVxcdTMwRkMtXFx1MzBGRlxcdTMxMDUtXFx1MzEyRlxcdTMxMzEtXFx1MzE4RVxcdTMxQTAtXFx1MzFCRlxcdTMxRjAtXFx1MzFGRlxcdTM0MDAtXFx1NERCRlxcdTRFMDAtXFx1QTQ4Q1xcdUE0RDAtXFx1QTRGRFxcdUE1MDAtXFx1QTYwQ1xcdUE2MTAtXFx1QTYxRlxcdUE2MkFcXHVBNjJCXFx1QTY0MC1cXHVBNjZFXFx1QTY3Ri1cXHVBNjlEXFx1QTZBMC1cXHVBNkU1XFx1QTcxNy1cXHVBNzFGXFx1QTcyMi1cXHVBNzg4XFx1QTc4Qi1cXHVBN0NBXFx1QTdEMFxcdUE3RDFcXHVBN0QzXFx1QTdENS1cXHVBN0Q5XFx1QTdGMi1cXHVBODAxXFx1QTgwMy1cXHVBODA1XFx1QTgwNy1cXHVBODBBXFx1QTgwQy1cXHVBODIyXFx1QTg0MC1cXHVBODczXFx1QTg4Mi1cXHVBOEIzXFx1QThGMi1cXHVBOEY3XFx1QThGQlxcdUE4RkRcXHVBOEZFXFx1QTkwQS1cXHVBOTI1XFx1QTkzMC1cXHVBOTQ2XFx1QTk2MC1cXHVBOTdDXFx1QTk4NC1cXHVBOUIyXFx1QTlDRlxcdUE5RTAtXFx1QTlFNFxcdUE5RTYtXFx1QTlFRlxcdUE5RkEtXFx1QTlGRVxcdUFBMDAtXFx1QUEyOFxcdUFBNDAtXFx1QUE0MlxcdUFBNDQtXFx1QUE0QlxcdUFBNjAtXFx1QUE3NlxcdUFBN0FcXHVBQTdFLVxcdUFBQUZcXHVBQUIxXFx1QUFCNVxcdUFBQjZcXHVBQUI5LVxcdUFBQkRcXHVBQUMwXFx1QUFDMlxcdUFBREItXFx1QUFERFxcdUFBRTAtXFx1QUFFQVxcdUFBRjItXFx1QUFGNFxcdUFCMDEtXFx1QUIwNlxcdUFCMDktXFx1QUIwRVxcdUFCMTEtXFx1QUIxNlxcdUFCMjAtXFx1QUIyNlxcdUFCMjgtXFx1QUIyRVxcdUFCMzAtXFx1QUI1QVxcdUFCNUMtXFx1QUI2OVxcdUFCNzAtXFx1QUJFMlxcdUFDMDAtXFx1RDdBM1xcdUQ3QjAtXFx1RDdDNlxcdUQ3Q0ItXFx1RDdGQlxcdUY5MDAtXFx1RkE2RFxcdUZBNzAtXFx1RkFEOVxcdUZCMDAtXFx1RkIwNlxcdUZCMTMtXFx1RkIxN1xcdUZCMURcXHVGQjFGLVxcdUZCMjhcXHVGQjJBLVxcdUZCMzZcXHVGQjM4LVxcdUZCM0NcXHVGQjNFXFx1RkI0MFxcdUZCNDFcXHVGQjQzXFx1RkI0NFxcdUZCNDYtXFx1RkJCMVxcdUZCRDMtXFx1RkQzRFxcdUZENTAtXFx1RkQ4RlxcdUZEOTItXFx1RkRDN1xcdUZERjAtXFx1RkRGQlxcdUZFNzAtXFx1RkU3NFxcdUZFNzYtXFx1RkVGQ1xcdUZGMjEtXFx1RkYzQVxcdUZGNDEtXFx1RkY1QVxcdUZGNjYtXFx1RkZCRVxcdUZGQzItXFx1RkZDN1xcdUZGQ0EtXFx1RkZDRlxcdUZGRDItXFx1RkZEN1xcdUZGREEtXFx1RkZEQ118XFx1RDgwMFtcXHVEQzAwLVxcdURDMEJcXHVEQzBELVxcdURDMjZcXHVEQzI4LVxcdURDM0FcXHVEQzNDXFx1REMzRFxcdURDM0YtXFx1REM0RFxcdURDNTAtXFx1REM1RFxcdURDODAtXFx1RENGQVxcdURFODAtXFx1REU5Q1xcdURFQTAtXFx1REVEMFxcdURGMDAtXFx1REYxRlxcdURGMkQtXFx1REY0MFxcdURGNDItXFx1REY0OVxcdURGNTAtXFx1REY3NVxcdURGODAtXFx1REY5RFxcdURGQTAtXFx1REZDM1xcdURGQzgtXFx1REZDRl18XFx1RDgwMVtcXHVEQzAwLVxcdURDOURcXHVEQ0IwLVxcdURDRDNcXHVEQ0Q4LVxcdURDRkJcXHVERDAwLVxcdUREMjdcXHVERDMwLVxcdURENjNcXHVERDcwLVxcdUREN0FcXHVERDdDLVxcdUREOEFcXHVERDhDLVxcdUREOTJcXHVERDk0XFx1REQ5NVxcdUREOTctXFx1RERBMVxcdUREQTMtXFx1RERCMVxcdUREQjMtXFx1RERCOVxcdUREQkJcXHVEREJDXFx1REUwMC1cXHVERjM2XFx1REY0MC1cXHVERjU1XFx1REY2MC1cXHVERjY3XFx1REY4MC1cXHVERjg1XFx1REY4Ny1cXHVERkIwXFx1REZCMi1cXHVERkJBXXxcXHVEODAyW1xcdURDMDAtXFx1REMwNVxcdURDMDhcXHVEQzBBLVxcdURDMzVcXHVEQzM3XFx1REMzOFxcdURDM0NcXHVEQzNGLVxcdURDNTVcXHVEQzYwLVxcdURDNzZcXHVEQzgwLVxcdURDOUVcXHVEQ0UwLVxcdURDRjJcXHVEQ0Y0XFx1RENGNVxcdUREMDAtXFx1REQxNVxcdUREMjAtXFx1REQzOVxcdUREODAtXFx1RERCN1xcdUREQkVcXHVEREJGXFx1REUwMFxcdURFMTAtXFx1REUxM1xcdURFMTUtXFx1REUxN1xcdURFMTktXFx1REUzNVxcdURFNjAtXFx1REU3Q1xcdURFODAtXFx1REU5Q1xcdURFQzAtXFx1REVDN1xcdURFQzktXFx1REVFNFxcdURGMDAtXFx1REYzNVxcdURGNDAtXFx1REY1NVxcdURGNjAtXFx1REY3MlxcdURGODAtXFx1REY5MV18XFx1RDgwM1tcXHVEQzAwLVxcdURDNDhcXHVEQzgwLVxcdURDQjJcXHVEQ0MwLVxcdURDRjJcXHVERDAwLVxcdUREMjNcXHVERTgwLVxcdURFQTlcXHVERUIwXFx1REVCMVxcdURGMDAtXFx1REYxQ1xcdURGMjdcXHVERjMwLVxcdURGNDVcXHVERjcwLVxcdURGODFcXHVERkIwLVxcdURGQzRcXHVERkUwLVxcdURGRjZdfFxcdUQ4MDRbXFx1REMwMy1cXHVEQzM3XFx1REM3MVxcdURDNzJcXHVEQzc1XFx1REM4My1cXHVEQ0FGXFx1RENEMC1cXHVEQ0U4XFx1REQwMy1cXHVERDI2XFx1REQ0NFxcdURENDdcXHVERDUwLVxcdURENzJcXHVERDc2XFx1REQ4My1cXHVEREIyXFx1RERDMS1cXHVEREM0XFx1REREQVxcdURERENcXHVERTAwLVxcdURFMTFcXHVERTEzLVxcdURFMkJcXHVERTgwLVxcdURFODZcXHVERTg4XFx1REU4QS1cXHVERThEXFx1REU4Ri1cXHVERTlEXFx1REU5Ri1cXHVERUE4XFx1REVCMC1cXHVERURFXFx1REYwNS1cXHVERjBDXFx1REYwRlxcdURGMTBcXHVERjEzLVxcdURGMjhcXHVERjJBLVxcdURGMzBcXHVERjMyXFx1REYzM1xcdURGMzUtXFx1REYzOVxcdURGM0RcXHVERjUwXFx1REY1RC1cXHVERjYxXXxcXHVEODA1W1xcdURDMDAtXFx1REMzNFxcdURDNDctXFx1REM0QVxcdURDNUYtXFx1REM2MVxcdURDODAtXFx1RENBRlxcdURDQzRcXHVEQ0M1XFx1RENDN1xcdUREODAtXFx1RERBRVxcdURERDgtXFx1REREQlxcdURFMDAtXFx1REUyRlxcdURFNDRcXHVERTgwLVxcdURFQUFcXHVERUI4XFx1REYwMC1cXHVERjFBXFx1REY0MC1cXHVERjQ2XXxcXHVEODA2W1xcdURDMDAtXFx1REMyQlxcdURDQTAtXFx1RENERlxcdURDRkYtXFx1REQwNlxcdUREMDlcXHVERDBDLVxcdUREMTNcXHVERDE1XFx1REQxNlxcdUREMTgtXFx1REQyRlxcdUREM0ZcXHVERDQxXFx1RERBMC1cXHVEREE3XFx1RERBQS1cXHVEREQwXFx1RERFMVxcdURERTNcXHVERTAwXFx1REUwQi1cXHVERTMyXFx1REUzQVxcdURFNTBcXHVERTVDLVxcdURFODlcXHVERTlEXFx1REVCMC1cXHVERUY4XXxcXHVEODA3W1xcdURDMDAtXFx1REMwOFxcdURDMEEtXFx1REMyRVxcdURDNDBcXHVEQzcyLVxcdURDOEZcXHVERDAwLVxcdUREMDZcXHVERDA4XFx1REQwOVxcdUREMEItXFx1REQzMFxcdURENDZcXHVERDYwLVxcdURENjVcXHVERDY3XFx1REQ2OFxcdURENkEtXFx1REQ4OVxcdUREOThcXHVERUUwLVxcdURFRjJcXHVERkIwXXxcXHVEODA4W1xcdURDMDAtXFx1REY5OV18XFx1RDgwOVtcXHVEQzgwLVxcdURENDNdfFxcdUQ4MEJbXFx1REY5MC1cXHVERkYwXXxbXFx1RDgwQ1xcdUQ4MUMtXFx1RDgyMFxcdUQ4MjJcXHVEODQwLVxcdUQ4NjhcXHVEODZBLVxcdUQ4NkNcXHVEODZGLVxcdUQ4NzJcXHVEODc0LVxcdUQ4NzlcXHVEODgwLVxcdUQ4ODNdW1xcdURDMDAtXFx1REZGRl18XFx1RDgwRFtcXHVEQzAwLVxcdURDMkVdfFxcdUQ4MTFbXFx1REMwMC1cXHVERTQ2XXxcXHVEODFBW1xcdURDMDAtXFx1REUzOFxcdURFNDAtXFx1REU1RVxcdURFNzAtXFx1REVCRVxcdURFRDAtXFx1REVFRFxcdURGMDAtXFx1REYyRlxcdURGNDAtXFx1REY0M1xcdURGNjMtXFx1REY3N1xcdURGN0QtXFx1REY4Rl18XFx1RDgxQltcXHVERTQwLVxcdURFN0ZcXHVERjAwLVxcdURGNEFcXHVERjUwXFx1REY5My1cXHVERjlGXFx1REZFMFxcdURGRTFcXHVERkUzXXxcXHVEODIxW1xcdURDMDAtXFx1REZGN118XFx1RDgyM1tcXHVEQzAwLVxcdURDRDVcXHVERDAwLVxcdUREMDhdfFxcdUQ4MkJbXFx1REZGMC1cXHVERkYzXFx1REZGNS1cXHVERkZCXFx1REZGRFxcdURGRkVdfFxcdUQ4MkNbXFx1REMwMC1cXHVERDIyXFx1REQ1MC1cXHVERDUyXFx1REQ2NC1cXHVERDY3XFx1REQ3MC1cXHVERUZCXXxcXHVEODJGW1xcdURDMDAtXFx1REM2QVxcdURDNzAtXFx1REM3Q1xcdURDODAtXFx1REM4OFxcdURDOTAtXFx1REM5OV18XFx1RDgzNVtcXHVEQzAwLVxcdURDNTRcXHVEQzU2LVxcdURDOUNcXHVEQzlFXFx1REM5RlxcdURDQTJcXHVEQ0E1XFx1RENBNlxcdURDQTktXFx1RENBQ1xcdURDQUUtXFx1RENCOVxcdURDQkJcXHVEQ0JELVxcdURDQzNcXHVEQ0M1LVxcdUREMDVcXHVERDA3LVxcdUREMEFcXHVERDBELVxcdUREMTRcXHVERDE2LVxcdUREMUNcXHVERDFFLVxcdUREMzlcXHVERDNCLVxcdUREM0VcXHVERDQwLVxcdURENDRcXHVERDQ2XFx1REQ0QS1cXHVERDUwXFx1REQ1Mi1cXHVERUE1XFx1REVBOC1cXHVERUMwXFx1REVDMi1cXHVERURBXFx1REVEQy1cXHVERUZBXFx1REVGQy1cXHVERjE0XFx1REYxNi1cXHVERjM0XFx1REYzNi1cXHVERjRFXFx1REY1MC1cXHVERjZFXFx1REY3MC1cXHVERjg4XFx1REY4QS1cXHVERkE4XFx1REZBQS1cXHVERkMyXFx1REZDNC1cXHVERkNCXXxcXHVEODM3W1xcdURGMDAtXFx1REYxRV18XFx1RDgzOFtcXHVERDAwLVxcdUREMkNcXHVERDM3LVxcdUREM0RcXHVERDRFXFx1REU5MC1cXHVERUFEXFx1REVDMC1cXHVERUVCXXxcXHVEODM5W1xcdURGRTAtXFx1REZFNlxcdURGRTgtXFx1REZFQlxcdURGRURcXHVERkVFXFx1REZGMC1cXHVERkZFXXxcXHVEODNBW1xcdURDMDAtXFx1RENDNFxcdUREMDAtXFx1REQ0M1xcdURENEJdfFxcdUQ4M0JbXFx1REUwMC1cXHVERTAzXFx1REUwNS1cXHVERTFGXFx1REUyMVxcdURFMjJcXHVERTI0XFx1REUyN1xcdURFMjktXFx1REUzMlxcdURFMzQtXFx1REUzN1xcdURFMzlcXHVERTNCXFx1REU0MlxcdURFNDdcXHVERTQ5XFx1REU0QlxcdURFNEQtXFx1REU0RlxcdURFNTFcXHVERTUyXFx1REU1NFxcdURFNTdcXHVERTU5XFx1REU1QlxcdURFNURcXHVERTVGXFx1REU2MVxcdURFNjJcXHVERTY0XFx1REU2Ny1cXHVERTZBXFx1REU2Qy1cXHVERTcyXFx1REU3NC1cXHVERTc3XFx1REU3OS1cXHVERTdDXFx1REU3RVxcdURFODAtXFx1REU4OVxcdURFOEItXFx1REU5QlxcdURFQTEtXFx1REVBM1xcdURFQTUtXFx1REVBOVxcdURFQUItXFx1REVCQl18XFx1RDg2OVtcXHVEQzAwLVxcdURFREZcXHVERjAwLVxcdURGRkZdfFxcdUQ4NkRbXFx1REMwMC1cXHVERjM4XFx1REY0MC1cXHVERkZGXXxcXHVEODZFW1xcdURDMDAtXFx1REMxRFxcdURDMjAtXFx1REZGRl18XFx1RDg3M1tcXHVEQzAwLVxcdURFQTFcXHVERUIwLVxcdURGRkZdfFxcdUQ4N0FbXFx1REMwMC1cXHVERkUwXXxcXHVEODdFW1xcdURDMDAtXFx1REUxRF18XFx1RDg4NFtcXHVEQzAwLVxcdURGNEFdKVxcUyovZztcbi8qKlxuICogVHJhbnNmb3JtcyB0ZXh0IHRvIHRpdGxlIGNhc2UuXG4gKiBDYXBpdGFsaXplcyB0aGUgZmlyc3QgbGV0dGVyIG9mIGVhY2ggd29yZCBhbmQgdHJhbnNmb3JtcyB0aGVcbiAqIHJlc3Qgb2YgdGhlIHdvcmQgdG8gbG93ZXIgY2FzZS5cbiAqIFdvcmRzIGFyZSBkZWxpbWl0ZWQgYnkgYW55IHdoaXRlc3BhY2UgY2hhcmFjdGVyLCBzdWNoIGFzIGEgc3BhY2UsIHRhYiwgb3IgbGluZS1mZWVkIGNoYXJhY3Rlci5cbiAqXG4gKiBAc2VlIHtAbGluayBMb3dlckNhc2VQaXBlfVxuICogQHNlZSB7QGxpbmsgVXBwZXJDYXNlUGlwZX1cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogVGhlIGZvbGxvd2luZyBleGFtcGxlIHNob3dzIHRoZSByZXN1bHQgb2YgdHJhbnNmb3JtaW5nIHZhcmlvdXMgc3RyaW5ncyBpbnRvIHRpdGxlIGNhc2UuXG4gKlxuICogPGNvZGUtZXhhbXBsZSBwYXRoPVwiY29tbW9uL3BpcGVzL3RzL3RpdGxlY2FzZV9waXBlLnRzXCIgcmVnaW9uPSdUaXRsZUNhc2VQaXBlJz48L2NvZGUtZXhhbXBsZT5cbiAqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIFRpdGxlQ2FzZVBpcGUge1xuICB0cmFuc2Zvcm0odmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IGludmFsaWRQaXBlQXJndW1lbnRFcnJvcihUaXRsZUNhc2VQaXBlLCB2YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZS5yZXBsYWNlKHVuaWNvZGVXb3JkTWF0Y2gsIHR4dCA9PiB0eHRbMF0udG9VcHBlckNhc2UoKSArIHR4dC5zbGljZSgxKS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBUaXRsZUNhc2VQaXBlX0ZhY3RvcnkodCkge1xuICAgICAgcmV0dXJuIG5ldyAodCB8fCBUaXRsZUNhc2VQaXBlKSgpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1cGlwZSA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVQaXBlKHtcbiAgICAgIG5hbWU6IFwidGl0bGVjYXNlXCIsXG4gICAgICB0eXBlOiBUaXRsZUNhc2VQaXBlLFxuICAgICAgcHVyZTogdHJ1ZSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9KTtcbiAgfVxufVxuKCgpID0+IHtcbiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09IFwidW5kZWZpbmVkXCIgfHwgbmdEZXZNb2RlKSAmJiBpMC7JtXNldENsYXNzTWV0YWRhdGEoVGl0bGVDYXNlUGlwZSwgW3tcbiAgICB0eXBlOiBQaXBlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBuYW1lOiAndGl0bGVjYXNlJyxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgbnVsbCwgbnVsbCk7XG59KSgpO1xuLyoqXG4gKiBUcmFuc2Zvcm1zIHRleHQgdG8gYWxsIHVwcGVyIGNhc2UuXG4gKiBAc2VlIHtAbGluayBMb3dlckNhc2VQaXBlfVxuICogQHNlZSB7QGxpbmsgVGl0bGVDYXNlUGlwZX1cbiAqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIFVwcGVyQ2FzZVBpcGUge1xuICB0cmFuc2Zvcm0odmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IGludmFsaWRQaXBlQXJndW1lbnRFcnJvcihVcHBlckNhc2VQaXBlLCB2YWx1ZSk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZS50b1VwcGVyQ2FzZSgpO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIFVwcGVyQ2FzZVBpcGVfRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IFVwcGVyQ2FzZVBpcGUpKCk7XG4gICAgfTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVwaXBlID0gLyogQF9fUFVSRV9fICovaTAuybXJtWRlZmluZVBpcGUoe1xuICAgICAgbmFtZTogXCJ1cHBlcmNhc2VcIixcbiAgICAgIHR5cGU6IFVwcGVyQ2FzZVBpcGUsXG4gICAgICBwdXJlOiB0cnVlLFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShVcHBlckNhc2VQaXBlLCBbe1xuICAgIHR5cGU6IFBpcGUsXG4gICAgYXJnczogW3tcbiAgICAgIG5hbWU6ICd1cHBlcmNhc2UnLFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH1dXG4gIH1dLCBudWxsLCBudWxsKTtcbn0pKCk7XG5cbi8qKlxuICogVGhlIGRlZmF1bHQgZGF0ZSBmb3JtYXQgb2YgQW5ndWxhciBkYXRlIHBpcGUsIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBmb2xsb3dpbmcgZm9ybWF0OlxuICogYCdNTU0gZCx5J2AgKGUuZy4gYEp1biAxNSwgMjAxNWApXG4gKi9cbmNvbnN0IERFRkFVTFRfREFURV9GT1JNQVQgPSAnbWVkaXVtRGF0ZSc7XG5cbi8qKlxuICogT3B0aW9uYWxseS1wcm92aWRlZCBkZWZhdWx0IHRpbWV6b25lIHRvIHVzZSBmb3IgYWxsIGluc3RhbmNlcyBvZiBgRGF0ZVBpcGVgIChzdWNoIGFzIGAnKzA0MzAnYCkuXG4gKiBJZiB0aGUgdmFsdWUgaXNuJ3QgcHJvdmlkZWQsIHRoZSBgRGF0ZVBpcGVgIHdpbGwgdXNlIHRoZSBlbmQtdXNlcidzIGxvY2FsIHN5c3RlbSB0aW1lem9uZS5cbiAqXG4gKiBAZGVwcmVjYXRlZCB1c2UgREFURV9QSVBFX0RFRkFVTFRfT1BUSU9OUyB0b2tlbiB0byBjb25maWd1cmUgRGF0ZVBpcGVcbiAqL1xuY29uc3QgREFURV9QSVBFX0RFRkFVTFRfVElNRVpPTkUgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gJ0RBVEVfUElQRV9ERUZBVUxUX1RJTUVaT05FJyA6ICcnKTtcbi8qKlxuICogREkgdG9rZW4gdGhhdCBhbGxvd3MgdG8gcHJvdmlkZSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBgRGF0ZVBpcGVgIGluc3RhbmNlcyBpbiBhblxuICogYXBwbGljYXRpb24uIFRoZSB2YWx1ZSBpcyBhbiBvYmplY3Qgd2hpY2ggY2FuIGluY2x1ZGUgdGhlIGZvbGxvd2luZyBmaWVsZHM6XG4gKiAtIGBkYXRlRm9ybWF0YDogY29uZmlndXJlcyB0aGUgZGVmYXVsdCBkYXRlIGZvcm1hdC4gSWYgbm90IHByb3ZpZGVkLCB0aGUgYERhdGVQaXBlYFxuICogd2lsbCB1c2UgdGhlICdtZWRpdW1EYXRlJyBhcyBhIHZhbHVlLlxuICogLSBgdGltZXpvbmVgOiBjb25maWd1cmVzIHRoZSBkZWZhdWx0IHRpbWV6b25lLiBJZiBub3QgcHJvdmlkZWQsIHRoZSBgRGF0ZVBpcGVgIHdpbGxcbiAqIHVzZSB0aGUgZW5kLXVzZXIncyBsb2NhbCBzeXN0ZW0gdGltZXpvbmUuXG4gKlxuICogQHNlZSB7QGxpbmsgRGF0ZVBpcGVDb25maWd9XG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiBWYXJpb3VzIGRhdGUgcGlwZSBkZWZhdWx0IHZhbHVlcyBjYW4gYmUgb3ZlcndyaXR0ZW4gYnkgcHJvdmlkaW5nIHRoaXMgdG9rZW4gd2l0aFxuICogdGhlIHZhbHVlIHRoYXQgaGFzIHRoaXMgaW50ZXJmYWNlLlxuICpcbiAqIEZvciBleGFtcGxlOlxuICpcbiAqIE92ZXJyaWRlIHRoZSBkZWZhdWx0IGRhdGUgZm9ybWF0IGJ5IHByb3ZpZGluZyBhIHZhbHVlIHVzaW5nIHRoZSB0b2tlbjpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIHByb3ZpZGVyczogW1xuICogICB7cHJvdmlkZTogREFURV9QSVBFX0RFRkFVTFRfT1BUSU9OUywgdXNlVmFsdWU6IHtkYXRlRm9ybWF0OiAnc2hvcnREYXRlJ319XG4gKiBdXG4gKiBgYGBcbiAqXG4gKiBPdmVycmlkZSB0aGUgZGVmYXVsdCB0aW1lem9uZSBieSBwcm92aWRpbmcgYSB2YWx1ZSB1c2luZyB0aGUgdG9rZW46XG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBwcm92aWRlcnM6IFtcbiAqICAge3Byb3ZpZGU6IERBVEVfUElQRV9ERUZBVUxUX09QVElPTlMsIHVzZVZhbHVlOiB7dGltZXpvbmU6ICctMTIwMCd9fVxuICogXVxuICogYGBgXG4gKi9cbmNvbnN0IERBVEVfUElQRV9ERUZBVUxUX09QVElPTlMgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gJ0RBVEVfUElQRV9ERUZBVUxUX09QVElPTlMnIDogJycpO1xuLyoqXG4gKiBAbmdNb2R1bGUgQ29tbW9uTW9kdWxlXG4gKiBAZGVzY3JpcHRpb25cbiAqXG4gKiBGb3JtYXRzIGEgZGF0ZSB2YWx1ZSBhY2NvcmRpbmcgdG8gbG9jYWxlIHJ1bGVzLlxuICpcbiAqIGBEYXRlUGlwZWAgaXMgZXhlY3V0ZWQgb25seSB3aGVuIGl0IGRldGVjdHMgYSBwdXJlIGNoYW5nZSB0byB0aGUgaW5wdXQgdmFsdWUuXG4gKiBBIHB1cmUgY2hhbmdlIGlzIGVpdGhlciBhIGNoYW5nZSB0byBhIHByaW1pdGl2ZSBpbnB1dCB2YWx1ZVxuICogKHN1Y2ggYXMgYFN0cmluZ2AsIGBOdW1iZXJgLCBgQm9vbGVhbmAsIG9yIGBTeW1ib2xgKSxcbiAqIG9yIGEgY2hhbmdlZCBvYmplY3QgcmVmZXJlbmNlIChzdWNoIGFzIGBEYXRlYCwgYEFycmF5YCwgYEZ1bmN0aW9uYCwgb3IgYE9iamVjdGApLlxuICpcbiAqIE5vdGUgdGhhdCBtdXRhdGluZyBhIGBEYXRlYCBvYmplY3QgZG9lcyBub3QgY2F1c2UgdGhlIHBpcGUgdG8gYmUgcmVuZGVyZWQgYWdhaW4uXG4gKiBUbyBlbnN1cmUgdGhhdCB0aGUgcGlwZSBpcyBleGVjdXRlZCwgeW91IG11c3QgY3JlYXRlIGEgbmV3IGBEYXRlYCBvYmplY3QuXG4gKlxuICogT25seSB0aGUgYGVuLVVTYCBsb2NhbGUgZGF0YSBjb21lcyB3aXRoIEFuZ3VsYXIuIFRvIGxvY2FsaXplIGRhdGVzXG4gKiBpbiBhbm90aGVyIGxhbmd1YWdlLCB5b3UgbXVzdCBpbXBvcnQgdGhlIGNvcnJlc3BvbmRpbmcgbG9jYWxlIGRhdGEuXG4gKiBTZWUgdGhlIFtJMThuIGd1aWRlXShndWlkZS9pMThuL2Zvcm1hdC1kYXRhLWxvY2FsZSkgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gKlxuICogVGhlIHRpbWUgem9uZSBvZiB0aGUgZm9ybWF0dGVkIHZhbHVlIGNhbiBiZSBzcGVjaWZpZWQgZWl0aGVyIGJ5IHBhc3NpbmcgaXQgaW4gYXMgdGhlIHNlY29uZFxuICogcGFyYW1ldGVyIG9mIHRoZSBwaXBlLCBvciBieSBzZXR0aW5nIHRoZSBkZWZhdWx0IHRocm91Z2ggdGhlIGBEQVRFX1BJUEVfREVGQVVMVF9PUFRJT05TYFxuICogaW5qZWN0aW9uIHRva2VuLiBUaGUgdmFsdWUgdGhhdCBpcyBwYXNzZWQgaW4gYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXIgdGFrZXMgcHJlY2VkZW5jZSBvdmVyXG4gKiB0aGUgb25lIGRlZmluZWQgdXNpbmcgdGhlIGluamVjdGlvbiB0b2tlbi5cbiAqXG4gKiBAc2VlIHtAbGluayBmb3JtYXREYXRlfVxuICpcbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICpcbiAqIFRoZSByZXN1bHQgb2YgdGhpcyBwaXBlIGlzIG5vdCByZWV2YWx1YXRlZCB3aGVuIHRoZSBpbnB1dCBpcyBtdXRhdGVkLiBUbyBhdm9pZCB0aGUgbmVlZCB0b1xuICogcmVmb3JtYXQgdGhlIGRhdGUgb24gZXZlcnkgY2hhbmdlLWRldGVjdGlvbiBjeWNsZSwgdHJlYXQgdGhlIGRhdGUgYXMgYW4gaW1tdXRhYmxlIG9iamVjdFxuICogYW5kIGNoYW5nZSB0aGUgcmVmZXJlbmNlIHdoZW4gdGhlIHBpcGUgbmVlZHMgdG8gcnVuIGFnYWluLlxuICpcbiAqICMjIyBQcmUtZGVmaW5lZCBmb3JtYXQgb3B0aW9uc1xuICpcbiAqIHwgT3B0aW9uICAgICAgICB8IEVxdWl2YWxlbnQgdG8gICAgICAgICAgICAgICAgICAgICAgIHwgRXhhbXBsZXMgKGdpdmVuIGluIGBlbi1VU2AgbG9jYWxlKSAgICAgICAgICAgICAgfFxuICogfC0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18XG4gKiB8IGAnc2hvcnQnYCAgICAgfCBgJ00vZC95eSwgaDptbSBhJ2AgICAgICAgICAgICAgICAgICB8IGA2LzE1LzE1LCA5OjAzIEFNYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqIHwgYCdtZWRpdW0nYCAgICB8IGAnTU1NIGQsIHksIGg6bW06c3MgYSdgICAgICAgICAgICAgIHwgYEp1biAxNSwgMjAxNSwgOTowMzowMSBBTWAgICAgICAgICAgICAgICAgICAgICAgfFxuICogfCBgJ2xvbmcnYCAgICAgIHwgYCdNTU1NIGQsIHksIGg6bW06c3MgYSB6J2AgICAgICAgICAgfCBgSnVuZSAxNSwgMjAxNSBhdCA5OjAzOjAxIEFNIEdNVCsxYCAgICAgICAgICAgICB8XG4gKiB8IGAnZnVsbCdgICAgICAgfCBgJ0VFRUUsIE1NTU0gZCwgeSwgaDptbTpzcyBhIHp6enonYCB8IGBNb25kYXksIEp1bmUgMTUsIDIwMTUgYXQgOTowMzowMSBBTSBHTVQrMDE6MDBgIHxcbiAqIHwgYCdzaG9ydERhdGUnYCB8IGAnTS9kL3l5J2AgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYDYvMTUvMTVgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogfCBgJ21lZGl1bURhdGUnYHwgYCdNTU0gZCwgeSdgICAgICAgICAgICAgICAgICAgICAgICAgfCBgSnVuIDE1LCAyMDE1YCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IGAnbG9uZ0RhdGUnYCAgfCBgJ01NTU0gZCwgeSdgICAgICAgICAgICAgICAgICAgICAgICB8IGBKdW5lIDE1LCAyMDE1YCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqIHwgYCdmdWxsRGF0ZSdgICB8IGAnRUVFRSwgTU1NTSBkLCB5J2AgICAgICAgICAgICAgICAgIHwgYE1vbmRheSwgSnVuZSAxNSwgMjAxNWAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogfCBgJ3Nob3J0VGltZSdgIHwgYCdoOm1tIGEnYCAgICAgICAgICAgICAgICAgICAgICAgICAgfCBgOTowMyBBTWAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiB8IGAnbWVkaXVtVGltZSdgfCBgJ2g6bW06c3MgYSdgICAgICAgICAgICAgICAgICAgICAgICB8IGA5OjAzOjAxIEFNYCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqIHwgYCdsb25nVGltZSdgICB8IGAnaDptbTpzcyBhIHonYCAgICAgICAgICAgICAgICAgICAgIHwgYDk6MDM6MDEgQU0gR01UKzFgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogfCBgJ2Z1bGxUaW1lJ2AgIHwgYCdoOm1tOnNzIGEgenp6eidgICAgICAgICAgICAgICAgICAgfCBgOTowMzowMSBBTSBHTVQrMDE6MDBgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKlxuICogIyMjIEN1c3RvbSBmb3JtYXQgb3B0aW9uc1xuICpcbiAqIFlvdSBjYW4gY29uc3RydWN0IGEgZm9ybWF0IHN0cmluZyB1c2luZyBzeW1ib2xzIHRvIHNwZWNpZnkgdGhlIGNvbXBvbmVudHNcbiAqIG9mIGEgZGF0ZS10aW1lIHZhbHVlLCBhcyBkZXNjcmliZWQgaW4gdGhlIGZvbGxvd2luZyB0YWJsZS5cbiAqIEZvcm1hdCBkZXRhaWxzIGRlcGVuZCBvbiB0aGUgbG9jYWxlLlxuICogRmllbGRzIG1hcmtlZCB3aXRoICgqKSBhcmUgb25seSBhdmFpbGFibGUgaW4gdGhlIGV4dHJhIGRhdGEgc2V0IGZvciB0aGUgZ2l2ZW4gbG9jYWxlLlxuICpcbiAqICB8IEZpZWxkIHR5cGUgICAgICAgICAgICAgIHwgRm9ybWF0ICAgICAgfCBEZXNjcmlwdGlvbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgRXhhbXBsZSBWYWx1ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tfFxuICogIHwgRXJhICAgICAgICAgICAgICAgICAgICAgfCBHLCBHRyAmIEdHRyB8IEFiYnJldmlhdGVkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBRCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgR0dHRyAgICAgICAgfCBXaWRlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQW5ubyBEb21pbmkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IEdHR0dHICAgICAgIHwgTmFycm93ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgWWVhciAgICAgICAgICAgICAgICAgICAgfCB5ICAgICAgICAgICB8IE51bWVyaWM6IG1pbmltdW0gZGlnaXRzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAyLCAyMCwgMjAxLCAyMDE3LCAyMDE3MyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgeXkgICAgICAgICAgfCBOdW1lcmljOiAyIGRpZ2l0cyArIHplcm8gcGFkZGVkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMDIsIDIwLCAwMSwgMTcsIDczICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IHl5eSAgICAgICAgIHwgTnVtZXJpYzogMyBkaWdpdHMgKyB6ZXJvIHBhZGRlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDAwMiwgMDIwLCAyMDEsIDIwMTcsIDIwMTczICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCB5eXl5ICAgICAgICB8IE51bWVyaWM6IDQgZGlnaXRzIG9yIG1vcmUgKyB6ZXJvIHBhZGRlZCAgICAgICAgICAgICAgICAgICAgICAgfCAwMDAyLCAwMDIwLCAwMjAxLCAyMDE3LCAyMDE3MyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8IElTTyBXZWVrLW51bWJlcmluZyB5ZWFyIHwgWSAgICAgICAgICAgfCBOdW1lcmljOiBtaW5pbXVtIGRpZ2l0cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMiwgMjAsIDIwMSwgMjAxNywgMjAxNzMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IFlZICAgICAgICAgIHwgTnVtZXJpYzogMiBkaWdpdHMgKyB6ZXJvIHBhZGRlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDAyLCAyMCwgMDEsIDE3LCA3MyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBZWVkgICAgICAgICB8IE51bWVyaWM6IDMgZGlnaXRzICsgemVybyBwYWRkZWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAwMDIsIDAyMCwgMjAxLCAyMDE3LCAyMDE3MyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgWVlZWSAgICAgICAgfCBOdW1lcmljOiA0IGRpZ2l0cyBvciBtb3JlICsgemVybyBwYWRkZWQgICAgICAgICAgICAgICAgICAgICAgIHwgMDAwMiwgMDAyMCwgMDIwMSwgMjAxNywgMjAxNzMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCBNb250aCAgICAgICAgICAgICAgICAgICB8IE0gICAgICAgICAgIHwgTnVtZXJpYzogMSBkaWdpdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDksIDEyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBNTSAgICAgICAgICB8IE51bWVyaWM6IDIgZGlnaXRzICsgemVybyBwYWRkZWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAwOSwgMTIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgTU1NICAgICAgICAgfCBBYmJyZXZpYXRlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2VwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IE1NTU0gICAgICAgIHwgV2lkZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFNlcHRlbWJlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBNTU1NTSAgICAgICB8IE5hcnJvdyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8IE1vbnRoIHN0YW5kYWxvbmUgICAgICAgIHwgTCAgICAgICAgICAgfCBOdW1lcmljOiAxIGRpZ2l0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgOSwgMTIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IExMICAgICAgICAgIHwgTnVtZXJpYzogMiBkaWdpdHMgKyB6ZXJvIHBhZGRlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDA5LCAxMiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBMTEwgICAgICAgICB8IEFiYnJldmlhdGVkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTZXAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgTExMTCAgICAgICAgfCBXaWRlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgU2VwdGVtYmVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IExMTExMICAgICAgIHwgTmFycm93ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgSVNPIFdlZWsgb2YgeWVhciAgICAgICAgfCB3ICAgICAgICAgICB8IE51bWVyaWM6IG1pbmltdW0gZGlnaXRzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAxLi4uIDUzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgd3cgICAgICAgICAgfCBOdW1lcmljOiAyIGRpZ2l0cyArIHplcm8gcGFkZGVkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMDEuLi4gNTMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCBXZWVrIG9mIG1vbnRoICAgICAgICAgICB8IFcgICAgICAgICAgIHwgTnVtZXJpYzogMSBkaWdpdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDEuLi4gNSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgRGF5IG9mIG1vbnRoICAgICAgICAgICAgfCBkICAgICAgICAgICB8IE51bWVyaWM6IG1pbmltdW0gZGlnaXRzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAxICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgZGQgICAgICAgICAgfCBOdW1lcmljOiAyIGRpZ2l0cyArIHplcm8gcGFkZGVkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMDEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCBXZWVrIGRheSAgICAgICAgICAgICAgICB8IEUsIEVFICYgRUVFIHwgQWJicmV2aWF0ZWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFR1ZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBFRUVFICAgICAgICB8IFdpZGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBUdWVzZGF5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgRUVFRUUgICAgICAgfCBOYXJyb3cgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgVCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IEVFRUVFRSAgICAgIHwgU2hvcnQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFR1ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgV2VlayBkYXkgc3RhbmRhbG9uZSAgICAgfCBjLCBjYyAgICAgICB8IE51bWVyaWM6IDEgZGlnaXQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgY2NjICAgICAgICAgfCBBYmJyZXZpYXRlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgVHVlICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IGNjY2MgICAgICAgIHwgV2lkZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IFR1ZXNkYXkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBjY2NjYyAgICAgICB8IE5hcnJvdyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBUICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgY2NjY2NjICAgICAgfCBTaG9ydCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgVHUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCBQZXJpb2QgICAgICAgICAgICAgICAgICB8IGEsIGFhICYgYWFhIHwgQWJicmV2aWF0ZWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IGFtL3BtIG9yIEFNL1BNICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBhYWFhICAgICAgICB8IFdpZGUgKGZhbGxiYWNrIHRvIGBhYCB3aGVuIG1pc3NpbmcpICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBhbnRlIG1lcmlkaWVtL3Bvc3QgbWVyaWRpZW0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgYWFhYWEgICAgICAgfCBOYXJyb3cgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgYS9wICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCBQZXJpb2QqICAgICAgICAgICAgICAgICB8IEIsIEJCICYgQkJCIHwgQWJicmV2aWF0ZWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IG1pZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBCQkJCICAgICAgICB8IFdpZGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBhbSwgcG0sIG1pZG5pZ2h0LCBub29uLCBtb3JuaW5nLCBhZnRlcm5vb24sIGV2ZW5pbmcsIG5pZ2h0IHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgQkJCQkIgICAgICAgfCBOYXJyb3cgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgbWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCBQZXJpb2Qgc3RhbmRhbG9uZSogICAgICB8IGIsIGJiICYgYmJiIHwgQWJicmV2aWF0ZWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IG1pZC4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBiYmJiICAgICAgICB8IFdpZGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBhbSwgcG0sIG1pZG5pZ2h0LCBub29uLCBtb3JuaW5nLCBhZnRlcm5vb24sIGV2ZW5pbmcsIG5pZ2h0IHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgYmJiYmIgICAgICAgfCBOYXJyb3cgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgbWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCBIb3VyIDEtMTIgICAgICAgICAgICAgICB8IGggICAgICAgICAgIHwgTnVtZXJpYzogbWluaW11bSBkaWdpdHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDEsIDEyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBoaCAgICAgICAgICB8IE51bWVyaWM6IDIgZGlnaXRzICsgemVybyBwYWRkZWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAwMSwgMTIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8IEhvdXIgMC0yMyAgICAgICAgICAgICAgIHwgSCAgICAgICAgICAgfCBOdW1lcmljOiBtaW5pbXVtIGRpZ2l0cyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMCwgMjMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IEhIICAgICAgICAgIHwgTnVtZXJpYzogMiBkaWdpdHMgKyB6ZXJvIHBhZGRlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDAwLCAyMyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgTWludXRlICAgICAgICAgICAgICAgICAgfCBtICAgICAgICAgICB8IE51bWVyaWM6IG1pbmltdW0gZGlnaXRzICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCA4LCA1OSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgbW0gICAgICAgICAgfCBOdW1lcmljOiAyIGRpZ2l0cyArIHplcm8gcGFkZGVkICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMDgsIDU5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCBTZWNvbmQgICAgICAgICAgICAgICAgICB8IHMgICAgICAgICAgIHwgTnVtZXJpYzogbWluaW11bSBkaWdpdHMgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDAuLi4gNTkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBzcyAgICAgICAgICB8IE51bWVyaWM6IDIgZGlnaXRzICsgemVybyBwYWRkZWQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAwMC4uLiA1OSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8IEZyYWN0aW9uYWwgc2Vjb25kcyAgICAgIHwgUyAgICAgICAgICAgfCBOdW1lcmljOiAxIGRpZ2l0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgMC4uLiA5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IFNTICAgICAgICAgIHwgTnVtZXJpYzogMiBkaWdpdHMgKyB6ZXJvIHBhZGRlZCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IDAwLi4uIDk5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBTU1MgICAgICAgICB8IE51bWVyaWM6IDMgZGlnaXRzICsgemVybyBwYWRkZWQgKD0gbWlsbGlzZWNvbmRzKSAgICAgICAgICAgICAgfCAwMDAuLi4gOTk5ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8IFpvbmUgICAgICAgICAgICAgICAgICAgIHwgeiwgenogJiB6enogfCBTaG9ydCBzcGVjaWZpYyBub24gbG9jYXRpb24gZm9ybWF0IChmYWxsYmFjayB0byBPKSAgICAgICAgICAgIHwgR01ULTggICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IHp6enogICAgICAgIHwgTG9uZyBzcGVjaWZpYyBub24gbG9jYXRpb24gZm9ybWF0IChmYWxsYmFjayB0byBPT09PKSAgICAgICAgICB8IEdNVC0wODowMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBaLCBaWiAmIFpaWiB8IElTTzg2MDEgYmFzaWMgZm9ybWF0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAtMDgwMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgWlpaWiAgICAgICAgfCBMb25nIGxvY2FsaXplZCBHTVQgZm9ybWF0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgR01ULTg6MDAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgfCAgICAgICAgICAgICAgICAgICAgICAgICB8IFpaWlpaICAgICAgIHwgSVNPODYwMSBleHRlbmRlZCBmb3JtYXQgKyBaIGluZGljYXRvciBmb3Igb2Zmc2V0IDAgKD0gWFhYWFgpICB8IC0wODowMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogIHwgICAgICAgICAgICAgICAgICAgICAgICAgfCBPLCBPTyAmIE9PTyB8IFNob3J0IGxvY2FsaXplZCBHTVQgZm9ybWF0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBHTVQtOCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHxcbiAqICB8ICAgICAgICAgICAgICAgICAgICAgICAgIHwgT09PTyAgICAgICAgfCBMb25nIGxvY2FsaXplZCBHTVQgZm9ybWF0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgR01ULTA4OjAwICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKlxuICpcbiAqICMjIyBGb3JtYXQgZXhhbXBsZXNcbiAqXG4gKiBUaGVzZSBleGFtcGxlcyB0cmFuc2Zvcm0gYSBkYXRlIGludG8gdmFyaW91cyBmb3JtYXRzLFxuICogYXNzdW1pbmcgdGhhdCBgZGF0ZU9iamAgaXMgYSBKYXZhU2NyaXB0IGBEYXRlYCBvYmplY3QgZm9yXG4gKiB5ZWFyOiAyMDE1LCBtb250aDogNiwgZGF5OiAxNSwgaG91cjogMjEsIG1pbnV0ZTogNDMsIHNlY29uZDogMTEsXG4gKiBnaXZlbiBpbiB0aGUgbG9jYWwgdGltZSBmb3IgdGhlIGBlbi1VU2AgbG9jYWxlLlxuICpcbiAqIGBgYFxuICoge3sgZGF0ZU9iaiB8IGRhdGUgfX0gICAgICAgICAgICAgICAvLyBvdXRwdXQgaXMgJ0p1biAxNSwgMjAxNSdcbiAqIHt7IGRhdGVPYmogfCBkYXRlOidtZWRpdW0nIH19ICAgICAgLy8gb3V0cHV0IGlzICdKdW4gMTUsIDIwMTUsIDk6NDM6MTEgUE0nXG4gKiB7eyBkYXRlT2JqIHwgZGF0ZTonc2hvcnRUaW1lJyB9fSAgIC8vIG91dHB1dCBpcyAnOTo0MyBQTSdcbiAqIHt7IGRhdGVPYmogfCBkYXRlOidtbTpzcycgfX0gICAgICAgLy8gb3V0cHV0IGlzICc0MzoxMSdcbiAqIHt7IGRhdGVPYmogfCBkYXRlOlwiTU1NIGRkLCB5eXl5ICdhdCcgaGg6bW0gYVwiIH19ICAvLyBvdXRwdXQgaXMgJ0p1biAxNSwgMjAxNSBhdCAwOTo0MyBQTSdcbiAqIGBgYFxuICpcbiAqICMjIyBVc2FnZSBleGFtcGxlXG4gKlxuICogVGhlIGZvbGxvd2luZyBjb21wb25lbnQgdXNlcyBhIGRhdGUgcGlwZSB0byBkaXNwbGF5IHRoZSBjdXJyZW50IGRhdGUgaW4gZGlmZmVyZW50IGZvcm1hdHMuXG4gKlxuICogYGBgXG4gKiBAQ29tcG9uZW50KHtcbiAqICBzZWxlY3RvcjogJ2RhdGUtcGlwZScsXG4gKiAgdGVtcGxhdGU6IGA8ZGl2PlxuICogICAgPHA+VG9kYXkgaXMge3t0b2RheSB8IGRhdGV9fTwvcD5cbiAqICAgIDxwPk9yIGlmIHlvdSBwcmVmZXIsIHt7dG9kYXkgfCBkYXRlOidmdWxsRGF0ZSd9fTwvcD5cbiAqICAgIDxwPlRoZSB0aW1lIGlzIHt7dG9kYXkgfCBkYXRlOidoOm1tIGEgeid9fTwvcD5cbiAqICA8L2Rpdj5gXG4gKiB9KVxuICogLy8gR2V0IHRoZSBjdXJyZW50IGRhdGUgYW5kIHRpbWUgYXMgYSBkYXRlLXRpbWUgdmFsdWUuXG4gKiBleHBvcnQgY2xhc3MgRGF0ZVBpcGVDb21wb25lbnQge1xuICogICB0b2RheTogbnVtYmVyID0gRGF0ZS5ub3coKTtcbiAqIH1cbiAqIGBgYFxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgRGF0ZVBpcGUge1xuICBjb25zdHJ1Y3Rvcihsb2NhbGUsIGRlZmF1bHRUaW1lem9uZSwgZGVmYXVsdE9wdGlvbnMpIHtcbiAgICB0aGlzLmxvY2FsZSA9IGxvY2FsZTtcbiAgICB0aGlzLmRlZmF1bHRUaW1lem9uZSA9IGRlZmF1bHRUaW1lem9uZTtcbiAgICB0aGlzLmRlZmF1bHRPcHRpb25zID0gZGVmYXVsdE9wdGlvbnM7XG4gIH1cbiAgdHJhbnNmb3JtKHZhbHVlLCBmb3JtYXQsIHRpbWV6b25lLCBsb2NhbGUpIHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSA9PT0gJycgfHwgdmFsdWUgIT09IHZhbHVlKSByZXR1cm4gbnVsbDtcbiAgICB0cnkge1xuICAgICAgY29uc3QgX2Zvcm1hdCA9IGZvcm1hdCA/PyB0aGlzLmRlZmF1bHRPcHRpb25zPy5kYXRlRm9ybWF0ID8/IERFRkFVTFRfREFURV9GT1JNQVQ7XG4gICAgICBjb25zdCBfdGltZXpvbmUgPSB0aW1lem9uZSA/PyB0aGlzLmRlZmF1bHRPcHRpb25zPy50aW1lem9uZSA/PyB0aGlzLmRlZmF1bHRUaW1lem9uZSA/PyB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gZm9ybWF0RGF0ZSh2YWx1ZSwgX2Zvcm1hdCwgbG9jYWxlIHx8IHRoaXMubG9jYWxlLCBfdGltZXpvbmUpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBpbnZhbGlkUGlwZUFyZ3VtZW50RXJyb3IoRGF0ZVBpcGUsIGVycm9yLm1lc3NhZ2UpO1xuICAgIH1cbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBEYXRlUGlwZV9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgRGF0ZVBpcGUpKGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoTE9DQUxFX0lELCAxNiksIGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoREFURV9QSVBFX0RFRkFVTFRfVElNRVpPTkUsIDI0KSwgaTAuybXJtWRpcmVjdGl2ZUluamVjdChEQVRFX1BJUEVfREVGQVVMVF9PUFRJT05TLCAyNCkpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1cGlwZSA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVQaXBlKHtcbiAgICAgIG5hbWU6IFwiZGF0ZVwiLFxuICAgICAgdHlwZTogRGF0ZVBpcGUsXG4gICAgICBwdXJlOiB0cnVlLFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShEYXRlUGlwZSwgW3tcbiAgICB0eXBlOiBQaXBlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBuYW1lOiAnZGF0ZScsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfV1cbiAgfV0sICgpID0+IFt7XG4gICAgdHlwZTogdW5kZWZpbmVkLFxuICAgIGRlY29yYXRvcnM6IFt7XG4gICAgICB0eXBlOiBJbmplY3QsXG4gICAgICBhcmdzOiBbTE9DQUxFX0lEXVxuICAgIH1dXG4gIH0sIHtcbiAgICB0eXBlOiB1bmRlZmluZWQsXG4gICAgZGVjb3JhdG9yczogW3tcbiAgICAgIHR5cGU6IEluamVjdCxcbiAgICAgIGFyZ3M6IFtEQVRFX1BJUEVfREVGQVVMVF9USU1FWk9ORV1cbiAgICB9LCB7XG4gICAgICB0eXBlOiBPcHRpb25hbFxuICAgIH1dXG4gIH0sIHtcbiAgICB0eXBlOiB1bmRlZmluZWQsXG4gICAgZGVjb3JhdG9yczogW3tcbiAgICAgIHR5cGU6IEluamVjdCxcbiAgICAgIGFyZ3M6IFtEQVRFX1BJUEVfREVGQVVMVF9PUFRJT05TXVxuICAgIH0sIHtcbiAgICAgIHR5cGU6IE9wdGlvbmFsXG4gICAgfV1cbiAgfV0sIG51bGwpO1xufSkoKTtcbmNvbnN0IF9JTlRFUlBPTEFUSU9OX1JFR0VYUCA9IC8jL2c7XG4vKipcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIE1hcHMgYSB2YWx1ZSB0byBhIHN0cmluZyB0aGF0IHBsdXJhbGl6ZXMgdGhlIHZhbHVlIGFjY29yZGluZyB0byBsb2NhbGUgcnVsZXMuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiAjIyMgRXhhbXBsZVxuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vcGlwZXMvdHMvaTE4bl9waXBlLnRzIHJlZ2lvbj0nSTE4blBsdXJhbFBpcGVDb21wb25lbnQnfVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgSTE4blBsdXJhbFBpcGUge1xuICBjb25zdHJ1Y3RvcihfbG9jYWxpemF0aW9uKSB7XG4gICAgdGhpcy5fbG9jYWxpemF0aW9uID0gX2xvY2FsaXphdGlvbjtcbiAgfVxuICAvKipcbiAgICogQHBhcmFtIHZhbHVlIHRoZSBudW1iZXIgdG8gYmUgZm9ybWF0dGVkXG4gICAqIEBwYXJhbSBwbHVyYWxNYXAgYW4gb2JqZWN0IHRoYXQgbWltaWNzIHRoZSBJQ1UgZm9ybWF0LCBzZWVcbiAgICogaHR0cHM6Ly91bmljb2RlLW9yZy5naXRodWIuaW8vaWN1L3VzZXJndWlkZS9mb3JtYXRfcGFyc2UvbWVzc2FnZXMvLlxuICAgKiBAcGFyYW0gbG9jYWxlIGEgYHN0cmluZ2AgZGVmaW5pbmcgdGhlIGxvY2FsZSB0byB1c2UgKHVzZXMgdGhlIGN1cnJlbnQge0BsaW5rIExPQ0FMRV9JRH0gYnlcbiAgICogZGVmYXVsdCkuXG4gICAqL1xuICB0cmFuc2Zvcm0odmFsdWUsIHBsdXJhbE1hcCwgbG9jYWxlKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiAnJztcbiAgICBpZiAodHlwZW9mIHBsdXJhbE1hcCAhPT0gJ29iamVjdCcgfHwgcGx1cmFsTWFwID09PSBudWxsKSB7XG4gICAgICB0aHJvdyBpbnZhbGlkUGlwZUFyZ3VtZW50RXJyb3IoSTE4blBsdXJhbFBpcGUsIHBsdXJhbE1hcCk7XG4gICAgfVxuICAgIGNvbnN0IGtleSA9IGdldFBsdXJhbENhdGVnb3J5KHZhbHVlLCBPYmplY3Qua2V5cyhwbHVyYWxNYXApLCB0aGlzLl9sb2NhbGl6YXRpb24sIGxvY2FsZSk7XG4gICAgcmV0dXJuIHBsdXJhbE1hcFtrZXldLnJlcGxhY2UoX0lOVEVSUE9MQVRJT05fUkVHRVhQLCB2YWx1ZS50b1N0cmluZygpKTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBJMThuUGx1cmFsUGlwZV9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgSTE4blBsdXJhbFBpcGUpKGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoTmdMb2NhbGl6YXRpb24sIDE2KSk7XG4gICAgfTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVwaXBlID0gLyogQF9fUFVSRV9fICovaTAuybXJtWRlZmluZVBpcGUoe1xuICAgICAgbmFtZTogXCJpMThuUGx1cmFsXCIsXG4gICAgICB0eXBlOiBJMThuUGx1cmFsUGlwZSxcbiAgICAgIHB1cmU6IHRydWUsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKEkxOG5QbHVyYWxQaXBlLCBbe1xuICAgIHR5cGU6IFBpcGUsXG4gICAgYXJnczogW3tcbiAgICAgIG5hbWU6ICdpMThuUGx1cmFsJyxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgKCkgPT4gW3tcbiAgICB0eXBlOiBOZ0xvY2FsaXphdGlvblxuICB9XSwgbnVsbCk7XG59KSgpO1xuXG4vKipcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIEdlbmVyaWMgc2VsZWN0b3IgdGhhdCBkaXNwbGF5cyB0aGUgc3RyaW5nIHRoYXQgbWF0Y2hlcyB0aGUgY3VycmVudCB2YWx1ZS5cbiAqXG4gKiBJZiBub25lIG9mIHRoZSBrZXlzIG9mIHRoZSBgbWFwcGluZ2AgbWF0Y2ggdGhlIGB2YWx1ZWAsIHRoZW4gdGhlIGNvbnRlbnRcbiAqIG9mIHRoZSBgb3RoZXJgIGtleSBpcyByZXR1cm5lZCB3aGVuIHByZXNlbnQsIG90aGVyd2lzZSBhbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiAjIyMgRXhhbXBsZVxuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vcGlwZXMvdHMvaTE4bl9waXBlLnRzIHJlZ2lvbj0nSTE4blNlbGVjdFBpcGVDb21wb25lbnQnfVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgSTE4blNlbGVjdFBpcGUge1xuICAvKipcbiAgICogQHBhcmFtIHZhbHVlIGEgc3RyaW5nIHRvIGJlIGludGVybmF0aW9uYWxpemVkLlxuICAgKiBAcGFyYW0gbWFwcGluZyBhbiBvYmplY3QgdGhhdCBpbmRpY2F0ZXMgdGhlIHRleHQgdGhhdCBzaG91bGQgYmUgZGlzcGxheWVkXG4gICAqIGZvciBkaWZmZXJlbnQgdmFsdWVzIG9mIHRoZSBwcm92aWRlZCBgdmFsdWVgLlxuICAgKi9cbiAgdHJhbnNmb3JtKHZhbHVlLCBtYXBwaW5nKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiAnJztcbiAgICBpZiAodHlwZW9mIG1hcHBpbmcgIT09ICdvYmplY3QnIHx8IHR5cGVvZiB2YWx1ZSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHRocm93IGludmFsaWRQaXBlQXJndW1lbnRFcnJvcihJMThuU2VsZWN0UGlwZSwgbWFwcGluZyk7XG4gICAgfVxuICAgIGlmIChtYXBwaW5nLmhhc093blByb3BlcnR5KHZhbHVlKSkge1xuICAgICAgcmV0dXJuIG1hcHBpbmdbdmFsdWVdO1xuICAgIH1cbiAgICBpZiAobWFwcGluZy5oYXNPd25Qcm9wZXJ0eSgnb3RoZXInKSkge1xuICAgICAgcmV0dXJuIG1hcHBpbmdbJ290aGVyJ107XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBJMThuU2VsZWN0UGlwZV9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgSTE4blNlbGVjdFBpcGUpKCk7XG4gICAgfTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVwaXBlID0gLyogQF9fUFVSRV9fICovaTAuybXJtWRlZmluZVBpcGUoe1xuICAgICAgbmFtZTogXCJpMThuU2VsZWN0XCIsXG4gICAgICB0eXBlOiBJMThuU2VsZWN0UGlwZSxcbiAgICAgIHB1cmU6IHRydWUsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKEkxOG5TZWxlY3RQaXBlLCBbe1xuICAgIHR5cGU6IFBpcGUsXG4gICAgYXJnczogW3tcbiAgICAgIG5hbWU6ICdpMThuU2VsZWN0JyxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgbnVsbCwgbnVsbCk7XG59KSgpO1xuXG4vKipcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIENvbnZlcnRzIGEgdmFsdWUgaW50byBpdHMgSlNPTi1mb3JtYXQgcmVwcmVzZW50YXRpb24uICBVc2VmdWwgZm9yIGRlYnVnZ2luZy5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICpcbiAqIFRoZSBmb2xsb3dpbmcgY29tcG9uZW50IHVzZXMgYSBKU09OIHBpcGUgdG8gY29udmVydCBhbiBvYmplY3RcbiAqIHRvIEpTT04gZm9ybWF0LCBhbmQgZGlzcGxheXMgdGhlIHN0cmluZyBpbiBib3RoIGZvcm1hdHMgZm9yIGNvbXBhcmlzb24uXG4gKlxuICoge0BleGFtcGxlIGNvbW1vbi9waXBlcy90cy9qc29uX3BpcGUudHMgcmVnaW9uPSdKc29uUGlwZSd9XG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBKc29uUGlwZSB7XG4gIC8qKlxuICAgKiBAcGFyYW0gdmFsdWUgQSB2YWx1ZSBvZiBhbnkgdHlwZSB0byBjb252ZXJ0IGludG8gYSBKU09OLWZvcm1hdCBzdHJpbmcuXG4gICAqL1xuICB0cmFuc2Zvcm0odmFsdWUpIHtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodmFsdWUsIG51bGwsIDIpO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIEpzb25QaXBlX0ZhY3RvcnkodCkge1xuICAgICAgcmV0dXJuIG5ldyAodCB8fCBKc29uUGlwZSkoKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXBpcGUgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lUGlwZSh7XG4gICAgICBuYW1lOiBcImpzb25cIixcbiAgICAgIHR5cGU6IEpzb25QaXBlLFxuICAgICAgcHVyZTogZmFsc2UsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKEpzb25QaXBlLCBbe1xuICAgIHR5cGU6IFBpcGUsXG4gICAgYXJnczogW3tcbiAgICAgIG5hbWU6ICdqc29uJyxcbiAgICAgIHB1cmU6IGZhbHNlLFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH1dXG4gIH1dLCBudWxsLCBudWxsKTtcbn0pKCk7XG5mdW5jdGlvbiBtYWtlS2V5VmFsdWVQYWlyKGtleSwgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICBrZXk6IGtleSxcbiAgICB2YWx1ZTogdmFsdWVcbiAgfTtcbn1cbi8qKlxuICogQG5nTW9kdWxlIENvbW1vbk1vZHVsZVxuICogQGRlc2NyaXB0aW9uXG4gKlxuICogVHJhbnNmb3JtcyBPYmplY3Qgb3IgTWFwIGludG8gYW4gYXJyYXkgb2Yga2V5IHZhbHVlIHBhaXJzLlxuICpcbiAqIFRoZSBvdXRwdXQgYXJyYXkgd2lsbCBiZSBvcmRlcmVkIGJ5IGtleXMuXG4gKiBCeSBkZWZhdWx0IHRoZSBjb21wYXJhdG9yIHdpbGwgYmUgYnkgVW5pY29kZSBwb2ludCB2YWx1ZS5cbiAqIFlvdSBjYW4gb3B0aW9uYWxseSBwYXNzIGEgY29tcGFyZUZuIGlmIHlvdXIga2V5cyBhcmUgY29tcGxleCB0eXBlcy5cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogIyMjIEV4YW1wbGVzXG4gKlxuICogVGhpcyBleGFtcGxlcyBzaG93IGhvdyBhbiBPYmplY3Qgb3IgYSBNYXAgY2FuIGJlIGl0ZXJhdGVkIGJ5IG5nRm9yIHdpdGggdGhlIHVzZSBvZiB0aGlzXG4gKiBrZXl2YWx1ZSBwaXBlLlxuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vcGlwZXMvdHMva2V5dmFsdWVfcGlwZS50cyByZWdpb249J0tleVZhbHVlUGlwZSd9XG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBLZXlWYWx1ZVBpcGUge1xuICBjb25zdHJ1Y3RvcihkaWZmZXJzKSB7XG4gICAgdGhpcy5kaWZmZXJzID0gZGlmZmVycztcbiAgICB0aGlzLmtleVZhbHVlcyA9IFtdO1xuICAgIHRoaXMuY29tcGFyZUZuID0gZGVmYXVsdENvbXBhcmF0b3I7XG4gIH1cbiAgdHJhbnNmb3JtKGlucHV0LCBjb21wYXJlRm4gPSBkZWZhdWx0Q29tcGFyYXRvcikge1xuICAgIGlmICghaW5wdXQgfHwgIShpbnB1dCBpbnN0YW5jZW9mIE1hcCkgJiYgdHlwZW9mIGlucHV0ICE9PSAnb2JqZWN0Jykge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8vIG1ha2UgYSBkaWZmZXIgZm9yIHdoYXRldmVyIHR5cGUgd2UndmUgYmVlbiBwYXNzZWQgaW5cbiAgICB0aGlzLmRpZmZlciA/Pz0gdGhpcy5kaWZmZXJzLmZpbmQoaW5wdXQpLmNyZWF0ZSgpO1xuICAgIGNvbnN0IGRpZmZlckNoYW5nZXMgPSB0aGlzLmRpZmZlci5kaWZmKGlucHV0KTtcbiAgICBjb25zdCBjb21wYXJlRm5DaGFuZ2VkID0gY29tcGFyZUZuICE9PSB0aGlzLmNvbXBhcmVGbjtcbiAgICBpZiAoZGlmZmVyQ2hhbmdlcykge1xuICAgICAgdGhpcy5rZXlWYWx1ZXMgPSBbXTtcbiAgICAgIGRpZmZlckNoYW5nZXMuZm9yRWFjaEl0ZW0ociA9PiB7XG4gICAgICAgIHRoaXMua2V5VmFsdWVzLnB1c2gobWFrZUtleVZhbHVlUGFpcihyLmtleSwgci5jdXJyZW50VmFsdWUpKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoZGlmZmVyQ2hhbmdlcyB8fCBjb21wYXJlRm5DaGFuZ2VkKSB7XG4gICAgICB0aGlzLmtleVZhbHVlcy5zb3J0KGNvbXBhcmVGbik7XG4gICAgICB0aGlzLmNvbXBhcmVGbiA9IGNvbXBhcmVGbjtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMua2V5VmFsdWVzO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIEtleVZhbHVlUGlwZV9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgS2V5VmFsdWVQaXBlKShpMC7Jtcm1ZGlyZWN0aXZlSW5qZWN0KGkwLktleVZhbHVlRGlmZmVycywgMTYpKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXBpcGUgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lUGlwZSh7XG4gICAgICBuYW1lOiBcImtleXZhbHVlXCIsXG4gICAgICB0eXBlOiBLZXlWYWx1ZVBpcGUsXG4gICAgICBwdXJlOiBmYWxzZSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9KTtcbiAgfVxufVxuKCgpID0+IHtcbiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09IFwidW5kZWZpbmVkXCIgfHwgbmdEZXZNb2RlKSAmJiBpMC7JtXNldENsYXNzTWV0YWRhdGEoS2V5VmFsdWVQaXBlLCBbe1xuICAgIHR5cGU6IFBpcGUsXG4gICAgYXJnczogW3tcbiAgICAgIG5hbWU6ICdrZXl2YWx1ZScsXG4gICAgICBwdXJlOiBmYWxzZSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgKCkgPT4gW3tcbiAgICB0eXBlOiBpMC5LZXlWYWx1ZURpZmZlcnNcbiAgfV0sIG51bGwpO1xufSkoKTtcbmZ1bmN0aW9uIGRlZmF1bHRDb21wYXJhdG9yKGtleVZhbHVlQSwga2V5VmFsdWVCKSB7XG4gIGNvbnN0IGEgPSBrZXlWYWx1ZUEua2V5O1xuICBjb25zdCBiID0ga2V5VmFsdWVCLmtleTtcbiAgLy8gaWYgc2FtZSBleGl0IHdpdGggMDtcbiAgaWYgKGEgPT09IGIpIHJldHVybiAwO1xuICAvLyBtYWtlIHN1cmUgdGhhdCB1bmRlZmluZWQgYXJlIGF0IHRoZSBlbmQgb2YgdGhlIHNvcnQuXG4gIGlmIChhID09PSB1bmRlZmluZWQpIHJldHVybiAxO1xuICBpZiAoYiA9PT0gdW5kZWZpbmVkKSByZXR1cm4gLTE7XG4gIC8vIG1ha2Ugc3VyZSB0aGF0IG51bGxzIGFyZSBhdCB0aGUgZW5kIG9mIHRoZSBzb3J0LlxuICBpZiAoYSA9PT0gbnVsbCkgcmV0dXJuIDE7XG4gIGlmIChiID09PSBudWxsKSByZXR1cm4gLTE7XG4gIGlmICh0eXBlb2YgYSA9PSAnc3RyaW5nJyAmJiB0eXBlb2YgYiA9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiBhIDwgYiA/IC0xIDogMTtcbiAgfVxuICBpZiAodHlwZW9mIGEgPT0gJ251bWJlcicgJiYgdHlwZW9mIGIgPT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gYSAtIGI7XG4gIH1cbiAgaWYgKHR5cGVvZiBhID09ICdib29sZWFuJyAmJiB0eXBlb2YgYiA9PSAnYm9vbGVhbicpIHtcbiAgICByZXR1cm4gYSA8IGIgPyAtMSA6IDE7XG4gIH1cbiAgLy8gYGFgIGFuZCBgYmAgYXJlIG9mIGRpZmZlcmVudCB0eXBlcy4gQ29tcGFyZSB0aGVpciBzdHJpbmcgdmFsdWVzLlxuICBjb25zdCBhU3RyaW5nID0gU3RyaW5nKGEpO1xuICBjb25zdCBiU3RyaW5nID0gU3RyaW5nKGIpO1xuICByZXR1cm4gYVN0cmluZyA9PSBiU3RyaW5nID8gMCA6IGFTdHJpbmcgPCBiU3RyaW5nID8gLTEgOiAxO1xufVxuXG4vKipcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIEZvcm1hdHMgYSB2YWx1ZSBhY2NvcmRpbmcgdG8gZGlnaXQgb3B0aW9ucyBhbmQgbG9jYWxlIHJ1bGVzLlxuICogTG9jYWxlIGRldGVybWluZXMgZ3JvdXAgc2l6aW5nIGFuZCBzZXBhcmF0b3IsXG4gKiBkZWNpbWFsIHBvaW50IGNoYXJhY3RlciwgYW5kIG90aGVyIGxvY2FsZS1zcGVjaWZpYyBjb25maWd1cmF0aW9ucy5cbiAqXG4gKiBAc2VlIHtAbGluayBmb3JtYXROdW1iZXJ9XG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiAjIyMgZGlnaXRzSW5mb1xuICpcbiAqIFRoZSB2YWx1ZSdzIGRlY2ltYWwgcmVwcmVzZW50YXRpb24gaXMgc3BlY2lmaWVkIGJ5IHRoZSBgZGlnaXRzSW5mb2BcbiAqIHBhcmFtZXRlciwgd3JpdHRlbiBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDo8YnI+XG4gKlxuICogYGBgXG4gKiB7bWluSW50ZWdlckRpZ2l0c30ue21pbkZyYWN0aW9uRGlnaXRzfS17bWF4RnJhY3Rpb25EaWdpdHN9XG4gKiBgYGBcbiAqXG4gKiAgLSBgbWluSW50ZWdlckRpZ2l0c2A6XG4gKiBUaGUgbWluaW11bSBudW1iZXIgb2YgaW50ZWdlciBkaWdpdHMgYmVmb3JlIHRoZSBkZWNpbWFsIHBvaW50LlxuICogRGVmYXVsdCBpcyAxLlxuICpcbiAqIC0gYG1pbkZyYWN0aW9uRGlnaXRzYDpcbiAqIFRoZSBtaW5pbXVtIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuXG4gKiBEZWZhdWx0IGlzIDAuXG4gKlxuICogIC0gYG1heEZyYWN0aW9uRGlnaXRzYDpcbiAqIFRoZSBtYXhpbXVtIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuXG4gKiBEZWZhdWx0IGlzIDMuXG4gKlxuICogSWYgdGhlIGZvcm1hdHRlZCB2YWx1ZSBpcyB0cnVuY2F0ZWQgaXQgd2lsbCBiZSByb3VuZGVkIHVzaW5nIHRoZSBcInRvLW5lYXJlc3RcIiBtZXRob2Q6XG4gKlxuICogYGBgXG4gKiB7ezMuNiB8IG51bWJlcjogJzEuMC0wJ319XG4gKiA8IS0td2lsbCBvdXRwdXQgJzQnLS0+XG4gKlxuICoge3stMy42IHwgbnVtYmVyOicxLjAtMCd9fVxuICogPCEtLXdpbGwgb3V0cHV0ICctNCctLT5cbiAqIGBgYFxuICpcbiAqICMjIyBsb2NhbGVcbiAqXG4gKiBgbG9jYWxlYCB3aWxsIGZvcm1hdCBhIHZhbHVlIGFjY29yZGluZyB0byBsb2NhbGUgcnVsZXMuXG4gKiBMb2NhbGUgZGV0ZXJtaW5lcyBncm91cCBzaXppbmcgYW5kIHNlcGFyYXRvcixcbiAqIGRlY2ltYWwgcG9pbnQgY2hhcmFjdGVyLCBhbmQgb3RoZXIgbG9jYWxlLXNwZWNpZmljIGNvbmZpZ3VyYXRpb25zLlxuICpcbiAqIFdoZW4gbm90IHN1cHBsaWVkLCB1c2VzIHRoZSB2YWx1ZSBvZiBgTE9DQUxFX0lEYCwgd2hpY2ggaXMgYGVuLVVTYCBieSBkZWZhdWx0LlxuICpcbiAqIFNlZSBbU2V0dGluZyB5b3VyIGFwcCBsb2NhbGVdKGd1aWRlL2kxOG4vbG9jYWxlLWlkKS5cbiAqXG4gKiAjIyMgRXhhbXBsZVxuICpcbiAqIFRoZSBmb2xsb3dpbmcgY29kZSBzaG93cyBob3cgdGhlIHBpcGUgdHJhbnNmb3JtcyB2YWx1ZXNcbiAqIGFjY29yZGluZyB0byB2YXJpb3VzIGZvcm1hdCBzcGVjaWZpY2F0aW9ucyxcbiAqIHdoZXJlIHRoZSBjYWxsZXIncyBkZWZhdWx0IGxvY2FsZSBpcyBgZW4tVVNgLlxuICpcbiAqIDxjb2RlLWV4YW1wbGUgcGF0aD1cImNvbW1vbi9waXBlcy90cy9udW1iZXJfcGlwZS50c1wiIHJlZ2lvbj0nTnVtYmVyUGlwZSc+PC9jb2RlLWV4YW1wbGU+XG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBEZWNpbWFsUGlwZSB7XG4gIGNvbnN0cnVjdG9yKF9sb2NhbGUpIHtcbiAgICB0aGlzLl9sb2NhbGUgPSBfbG9jYWxlO1xuICB9XG4gIC8qKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGJlIGZvcm1hdHRlZC5cbiAgICogQHBhcmFtIGRpZ2l0c0luZm8gU2V0cyBkaWdpdCBhbmQgZGVjaW1hbCByZXByZXNlbnRhdGlvbi5cbiAgICogW1NlZSBtb3JlXSgjZGlnaXRzaW5mbykuXG4gICAqIEBwYXJhbSBsb2NhbGUgU3BlY2lmaWVzIHdoYXQgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuXG4gICAqIFtTZWUgbW9yZV0oI2xvY2FsZSkuXG4gICAqL1xuICB0cmFuc2Zvcm0odmFsdWUsIGRpZ2l0c0luZm8sIGxvY2FsZSkge1xuICAgIGlmICghaXNWYWx1ZSh2YWx1ZSkpIHJldHVybiBudWxsO1xuICAgIGxvY2FsZSB8fD0gdGhpcy5fbG9jYWxlO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBudW0gPSBzdHJUb051bWJlcih2YWx1ZSk7XG4gICAgICByZXR1cm4gZm9ybWF0TnVtYmVyKG51bSwgbG9jYWxlLCBkaWdpdHNJbmZvKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgaW52YWxpZFBpcGVBcmd1bWVudEVycm9yKERlY2ltYWxQaXBlLCBlcnJvci5tZXNzYWdlKTtcbiAgICB9XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gRGVjaW1hbFBpcGVfRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IERlY2ltYWxQaXBlKShpMC7Jtcm1ZGlyZWN0aXZlSW5qZWN0KExPQ0FMRV9JRCwgMTYpKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXBpcGUgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lUGlwZSh7XG4gICAgICBuYW1lOiBcIm51bWJlclwiLFxuICAgICAgdHlwZTogRGVjaW1hbFBpcGUsXG4gICAgICBwdXJlOiB0cnVlLFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShEZWNpbWFsUGlwZSwgW3tcbiAgICB0eXBlOiBQaXBlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBuYW1lOiAnbnVtYmVyJyxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWVcbiAgICB9XVxuICB9XSwgKCkgPT4gW3tcbiAgICB0eXBlOiB1bmRlZmluZWQsXG4gICAgZGVjb3JhdG9yczogW3tcbiAgICAgIHR5cGU6IEluamVjdCxcbiAgICAgIGFyZ3M6IFtMT0NBTEVfSURdXG4gICAgfV1cbiAgfV0sIG51bGwpO1xufSkoKTtcbi8qKlxuICogQG5nTW9kdWxlIENvbW1vbk1vZHVsZVxuICogQGRlc2NyaXB0aW9uXG4gKlxuICogVHJhbnNmb3JtcyBhIG51bWJlciB0byBhIHBlcmNlbnRhZ2VcbiAqIHN0cmluZywgZm9ybWF0dGVkIGFjY29yZGluZyB0byBsb2NhbGUgcnVsZXMgdGhhdCBkZXRlcm1pbmUgZ3JvdXAgc2l6aW5nIGFuZFxuICogc2VwYXJhdG9yLCBkZWNpbWFsLXBvaW50IGNoYXJhY3RlciwgYW5kIG90aGVyIGxvY2FsZS1zcGVjaWZpY1xuICogY29uZmlndXJhdGlvbnMuXG4gKlxuICogQHNlZSB7QGxpbmsgZm9ybWF0UGVyY2VudH1cbiAqXG4gKiBAdXNhZ2VOb3Rlc1xuICogVGhlIGZvbGxvd2luZyBjb2RlIHNob3dzIGhvdyB0aGUgcGlwZSB0cmFuc2Zvcm1zIG51bWJlcnNcbiAqIGludG8gdGV4dCBzdHJpbmdzLCBhY2NvcmRpbmcgdG8gdmFyaW91cyBmb3JtYXQgc3BlY2lmaWNhdGlvbnMsXG4gKiB3aGVyZSB0aGUgY2FsbGVyJ3MgZGVmYXVsdCBsb2NhbGUgaXMgYGVuLVVTYC5cbiAqXG4gKiA8Y29kZS1leGFtcGxlIHBhdGg9XCJjb21tb24vcGlwZXMvdHMvcGVyY2VudF9waXBlLnRzXCIgcmVnaW9uPSdQZXJjZW50UGlwZSc+PC9jb2RlLWV4YW1wbGU+XG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBQZXJjZW50UGlwZSB7XG4gIGNvbnN0cnVjdG9yKF9sb2NhbGUpIHtcbiAgICB0aGlzLl9sb2NhbGUgPSBfbG9jYWxlO1xuICB9XG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciB0byBiZSBmb3JtYXR0ZWQgYXMgYSBwZXJjZW50YWdlLlxuICAgKiBAcGFyYW0gZGlnaXRzSW5mbyBEZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9wdGlvbnMsIHNwZWNpZmllZCBieSBhIHN0cmluZ1xuICAgKiBpbiB0aGUgZm9sbG93aW5nIGZvcm1hdDo8YnI+XG4gICAqIDxjb2RlPnttaW5JbnRlZ2VyRGlnaXRzfS57bWluRnJhY3Rpb25EaWdpdHN9LXttYXhGcmFjdGlvbkRpZ2l0c308L2NvZGU+LlxuICAgKiAgIC0gYG1pbkludGVnZXJEaWdpdHNgOiBUaGUgbWluaW11bSBudW1iZXIgb2YgaW50ZWdlciBkaWdpdHMgYmVmb3JlIHRoZSBkZWNpbWFsIHBvaW50LlxuICAgKiBEZWZhdWx0IGlzIGAxYC5cbiAgICogICAtIGBtaW5GcmFjdGlvbkRpZ2l0c2A6IFRoZSBtaW5pbXVtIG51bWJlciBvZiBkaWdpdHMgYWZ0ZXIgdGhlIGRlY2ltYWwgcG9pbnQuXG4gICAqIERlZmF1bHQgaXMgYDBgLlxuICAgKiAgIC0gYG1heEZyYWN0aW9uRGlnaXRzYDogVGhlIG1heGltdW0gbnVtYmVyIG9mIGRpZ2l0cyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC5cbiAgICogRGVmYXVsdCBpcyBgMGAuXG4gICAqIEBwYXJhbSBsb2NhbGUgQSBsb2NhbGUgY29kZSBmb3IgdGhlIGxvY2FsZSBmb3JtYXQgcnVsZXMgdG8gdXNlLlxuICAgKiBXaGVuIG5vdCBzdXBwbGllZCwgdXNlcyB0aGUgdmFsdWUgb2YgYExPQ0FMRV9JRGAsIHdoaWNoIGlzIGBlbi1VU2AgYnkgZGVmYXVsdC5cbiAgICogU2VlIFtTZXR0aW5nIHlvdXIgYXBwIGxvY2FsZV0oZ3VpZGUvaTE4bi9sb2NhbGUtaWQpLlxuICAgKi9cbiAgdHJhbnNmb3JtKHZhbHVlLCBkaWdpdHNJbmZvLCBsb2NhbGUpIHtcbiAgICBpZiAoIWlzVmFsdWUodmFsdWUpKSByZXR1cm4gbnVsbDtcbiAgICBsb2NhbGUgfHw9IHRoaXMuX2xvY2FsZTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbnVtID0gc3RyVG9OdW1iZXIodmFsdWUpO1xuICAgICAgcmV0dXJuIGZvcm1hdFBlcmNlbnQobnVtLCBsb2NhbGUsIGRpZ2l0c0luZm8pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBpbnZhbGlkUGlwZUFyZ3VtZW50RXJyb3IoUGVyY2VudFBpcGUsIGVycm9yLm1lc3NhZ2UpO1xuICAgIH1cbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBQZXJjZW50UGlwZV9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgUGVyY2VudFBpcGUpKGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoTE9DQUxFX0lELCAxNikpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1cGlwZSA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVQaXBlKHtcbiAgICAgIG5hbWU6IFwicGVyY2VudFwiLFxuICAgICAgdHlwZTogUGVyY2VudFBpcGUsXG4gICAgICBwdXJlOiB0cnVlLFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShQZXJjZW50UGlwZSwgW3tcbiAgICB0eXBlOiBQaXBlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBuYW1lOiAncGVyY2VudCcsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfV1cbiAgfV0sICgpID0+IFt7XG4gICAgdHlwZTogdW5kZWZpbmVkLFxuICAgIGRlY29yYXRvcnM6IFt7XG4gICAgICB0eXBlOiBJbmplY3QsXG4gICAgICBhcmdzOiBbTE9DQUxFX0lEXVxuICAgIH1dXG4gIH1dLCBudWxsKTtcbn0pKCk7XG4vKipcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIFRyYW5zZm9ybXMgYSBudW1iZXIgdG8gYSBjdXJyZW5jeSBzdHJpbmcsIGZvcm1hdHRlZCBhY2NvcmRpbmcgdG8gbG9jYWxlIHJ1bGVzXG4gKiB0aGF0IGRldGVybWluZSBncm91cCBzaXppbmcgYW5kIHNlcGFyYXRvciwgZGVjaW1hbC1wb2ludCBjaGFyYWN0ZXIsXG4gKiBhbmQgb3RoZXIgbG9jYWxlLXNwZWNpZmljIGNvbmZpZ3VyYXRpb25zLlxuICpcbiAqXG4gKiBAc2VlIHtAbGluayBnZXRDdXJyZW5jeVN5bWJvbH1cbiAqIEBzZWUge0BsaW5rIGZvcm1hdEN1cnJlbmN5fVxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKiBUaGUgZm9sbG93aW5nIGNvZGUgc2hvd3MgaG93IHRoZSBwaXBlIHRyYW5zZm9ybXMgbnVtYmVyc1xuICogaW50byB0ZXh0IHN0cmluZ3MsIGFjY29yZGluZyB0byB2YXJpb3VzIGZvcm1hdCBzcGVjaWZpY2F0aW9ucyxcbiAqIHdoZXJlIHRoZSBjYWxsZXIncyBkZWZhdWx0IGxvY2FsZSBpcyBgZW4tVVNgLlxuICpcbiAqIDxjb2RlLWV4YW1wbGUgcGF0aD1cImNvbW1vbi9waXBlcy90cy9jdXJyZW5jeV9waXBlLnRzXCIgcmVnaW9uPSdDdXJyZW5jeVBpcGUnPjwvY29kZS1leGFtcGxlPlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgQ3VycmVuY3lQaXBlIHtcbiAgY29uc3RydWN0b3IoX2xvY2FsZSwgX2RlZmF1bHRDdXJyZW5jeUNvZGUgPSAnVVNEJykge1xuICAgIHRoaXMuX2xvY2FsZSA9IF9sb2NhbGU7XG4gICAgdGhpcy5fZGVmYXVsdEN1cnJlbmN5Q29kZSA9IF9kZWZhdWx0Q3VycmVuY3lDb2RlO1xuICB9XG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIG51bWJlciB0byBiZSBmb3JtYXR0ZWQgYXMgY3VycmVuY3kuXG4gICAqIEBwYXJhbSBjdXJyZW5jeUNvZGUgVGhlIFtJU08gNDIxN10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSVNPXzQyMTcpIGN1cnJlbmN5IGNvZGUsXG4gICAqIHN1Y2ggYXMgYFVTRGAgZm9yIHRoZSBVUyBkb2xsYXIgYW5kIGBFVVJgIGZvciB0aGUgZXVyby4gVGhlIGRlZmF1bHQgY3VycmVuY3kgY29kZSBjYW4gYmVcbiAgICogY29uZmlndXJlZCB1c2luZyB0aGUgYERFRkFVTFRfQ1VSUkVOQ1lfQ09ERWAgaW5qZWN0aW9uIHRva2VuLlxuICAgKiBAcGFyYW0gZGlzcGxheSBUaGUgZm9ybWF0IGZvciB0aGUgY3VycmVuY3kgaW5kaWNhdG9yLiBPbmUgb2YgdGhlIGZvbGxvd2luZzpcbiAgICogICAtIGBjb2RlYDogU2hvdyB0aGUgY29kZSAoc3VjaCBhcyBgVVNEYCkuXG4gICAqICAgLSBgc3ltYm9sYChkZWZhdWx0KTogU2hvdyB0aGUgc3ltYm9sIChzdWNoIGFzIGAkYCkuXG4gICAqICAgLSBgc3ltYm9sLW5hcnJvd2A6IFVzZSB0aGUgbmFycm93IHN5bWJvbCBmb3IgbG9jYWxlcyB0aGF0IGhhdmUgdHdvIHN5bWJvbHMgZm9yIHRoZWlyXG4gICAqIGN1cnJlbmN5LlxuICAgKiBGb3IgZXhhbXBsZSwgdGhlIENhbmFkaWFuIGRvbGxhciBDQUQgaGFzIHRoZSBzeW1ib2wgYENBJGAgYW5kIHRoZSBzeW1ib2wtbmFycm93IGAkYC4gSWYgdGhlXG4gICAqIGxvY2FsZSBoYXMgbm8gbmFycm93IHN5bWJvbCwgdXNlcyB0aGUgc3RhbmRhcmQgc3ltYm9sIGZvciB0aGUgbG9jYWxlLlxuICAgKiAgIC0gU3RyaW5nOiBVc2UgdGhlIGdpdmVuIHN0cmluZyB2YWx1ZSBpbnN0ZWFkIG9mIGEgY29kZSBvciBhIHN5bWJvbC5cbiAgICogRm9yIGV4YW1wbGUsIGFuIGVtcHR5IHN0cmluZyB3aWxsIHN1cHByZXNzIHRoZSBjdXJyZW5jeSAmIHN5bWJvbC5cbiAgICogICAtIEJvb2xlYW4gKG1hcmtlZCBkZXByZWNhdGVkIGluIHY1KTogYHRydWVgIGZvciBzeW1ib2wgYW5kIGZhbHNlIGZvciBgY29kZWAuXG4gICAqXG4gICAqIEBwYXJhbSBkaWdpdHNJbmZvIERlY2ltYWwgcmVwcmVzZW50YXRpb24gb3B0aW9ucywgc3BlY2lmaWVkIGJ5IGEgc3RyaW5nXG4gICAqIGluIHRoZSBmb2xsb3dpbmcgZm9ybWF0Ojxicj5cbiAgICogPGNvZGU+e21pbkludGVnZXJEaWdpdHN9LnttaW5GcmFjdGlvbkRpZ2l0c30te21heEZyYWN0aW9uRGlnaXRzfTwvY29kZT4uXG4gICAqICAgLSBgbWluSW50ZWdlckRpZ2l0c2A6IFRoZSBtaW5pbXVtIG51bWJlciBvZiBpbnRlZ2VyIGRpZ2l0cyBiZWZvcmUgdGhlIGRlY2ltYWwgcG9pbnQuXG4gICAqIERlZmF1bHQgaXMgYDFgLlxuICAgKiAgIC0gYG1pbkZyYWN0aW9uRGlnaXRzYDogVGhlIG1pbmltdW0gbnVtYmVyIG9mIGRpZ2l0cyBhZnRlciB0aGUgZGVjaW1hbCBwb2ludC5cbiAgICogRGVmYXVsdCBpcyBgMmAuXG4gICAqICAgLSBgbWF4RnJhY3Rpb25EaWdpdHNgOiBUaGUgbWF4aW11bSBudW1iZXIgb2YgZGlnaXRzIGFmdGVyIHRoZSBkZWNpbWFsIHBvaW50LlxuICAgKiBEZWZhdWx0IGlzIGAyYC5cbiAgICogSWYgbm90IHByb3ZpZGVkLCB0aGUgbnVtYmVyIHdpbGwgYmUgZm9ybWF0dGVkIHdpdGggdGhlIHByb3BlciBhbW91bnQgb2YgZGlnaXRzLFxuICAgKiBkZXBlbmRpbmcgb24gd2hhdCB0aGUgW0lTTyA0MjE3XShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9JU09fNDIxNykgc3BlY2lmaWVzLlxuICAgKiBGb3IgZXhhbXBsZSwgdGhlIENhbmFkaWFuIGRvbGxhciBoYXMgMiBkaWdpdHMsIHdoZXJlYXMgdGhlIENoaWxlYW4gcGVzbyBoYXMgbm9uZS5cbiAgICogQHBhcmFtIGxvY2FsZSBBIGxvY2FsZSBjb2RlIGZvciB0aGUgbG9jYWxlIGZvcm1hdCBydWxlcyB0byB1c2UuXG4gICAqIFdoZW4gbm90IHN1cHBsaWVkLCB1c2VzIHRoZSB2YWx1ZSBvZiBgTE9DQUxFX0lEYCwgd2hpY2ggaXMgYGVuLVVTYCBieSBkZWZhdWx0LlxuICAgKiBTZWUgW1NldHRpbmcgeW91ciBhcHAgbG9jYWxlXShndWlkZS9pMThuL2xvY2FsZS1pZCkuXG4gICAqL1xuICB0cmFuc2Zvcm0odmFsdWUsIGN1cnJlbmN5Q29kZSA9IHRoaXMuX2RlZmF1bHRDdXJyZW5jeUNvZGUsIGRpc3BsYXkgPSAnc3ltYm9sJywgZGlnaXRzSW5mbywgbG9jYWxlKSB7XG4gICAgaWYgKCFpc1ZhbHVlKHZhbHVlKSkgcmV0dXJuIG51bGw7XG4gICAgbG9jYWxlIHx8PSB0aGlzLl9sb2NhbGU7XG4gICAgaWYgKHR5cGVvZiBkaXNwbGF5ID09PSAnYm9vbGVhbicpIHtcbiAgICAgIGlmICgodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSAmJiBjb25zb2xlICYmIGNvbnNvbGUud2Fybikge1xuICAgICAgICBjb25zb2xlLndhcm4oYFdhcm5pbmc6IHRoZSBjdXJyZW5jeSBwaXBlIGhhcyBiZWVuIGNoYW5nZWQgaW4gQW5ndWxhciB2NS4gVGhlIHN5bWJvbERpc3BsYXkgb3B0aW9uICh0aGlyZCBwYXJhbWV0ZXIpIGlzIG5vdyBhIHN0cmluZyBpbnN0ZWFkIG9mIGEgYm9vbGVhbi4gVGhlIGFjY2VwdGVkIHZhbHVlcyBhcmUgXCJjb2RlXCIsIFwic3ltYm9sXCIgb3IgXCJzeW1ib2wtbmFycm93XCIuYCk7XG4gICAgICB9XG4gICAgICBkaXNwbGF5ID0gZGlzcGxheSA/ICdzeW1ib2wnIDogJ2NvZGUnO1xuICAgIH1cbiAgICBsZXQgY3VycmVuY3kgPSBjdXJyZW5jeUNvZGUgfHwgdGhpcy5fZGVmYXVsdEN1cnJlbmN5Q29kZTtcbiAgICBpZiAoZGlzcGxheSAhPT0gJ2NvZGUnKSB7XG4gICAgICBpZiAoZGlzcGxheSA9PT0gJ3N5bWJvbCcgfHwgZGlzcGxheSA9PT0gJ3N5bWJvbC1uYXJyb3cnKSB7XG4gICAgICAgIGN1cnJlbmN5ID0gZ2V0Q3VycmVuY3lTeW1ib2woY3VycmVuY3ksIGRpc3BsYXkgPT09ICdzeW1ib2wnID8gJ3dpZGUnIDogJ25hcnJvdycsIGxvY2FsZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdXJyZW5jeSA9IGRpc3BsYXk7XG4gICAgICB9XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBjb25zdCBudW0gPSBzdHJUb051bWJlcih2YWx1ZSk7XG4gICAgICByZXR1cm4gZm9ybWF0Q3VycmVuY3kobnVtLCBsb2NhbGUsIGN1cnJlbmN5LCBjdXJyZW5jeUNvZGUsIGRpZ2l0c0luZm8pO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aHJvdyBpbnZhbGlkUGlwZUFyZ3VtZW50RXJyb3IoQ3VycmVuY3lQaXBlLCBlcnJvci5tZXNzYWdlKTtcbiAgICB9XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gQ3VycmVuY3lQaXBlX0ZhY3RvcnkodCkge1xuICAgICAgcmV0dXJuIG5ldyAodCB8fCBDdXJyZW5jeVBpcGUpKGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoTE9DQUxFX0lELCAxNiksIGkwLsm1ybVkaXJlY3RpdmVJbmplY3QoREVGQVVMVF9DVVJSRU5DWV9DT0RFLCAxNikpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1cGlwZSA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVQaXBlKHtcbiAgICAgIG5hbWU6IFwiY3VycmVuY3lcIixcbiAgICAgIHR5cGU6IEN1cnJlbmN5UGlwZSxcbiAgICAgIHB1cmU6IHRydWUsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKEN1cnJlbmN5UGlwZSwgW3tcbiAgICB0eXBlOiBQaXBlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBuYW1lOiAnY3VycmVuY3knLFxuICAgICAgc3RhbmRhbG9uZTogdHJ1ZVxuICAgIH1dXG4gIH1dLCAoKSA9PiBbe1xuICAgIHR5cGU6IHVuZGVmaW5lZCxcbiAgICBkZWNvcmF0b3JzOiBbe1xuICAgICAgdHlwZTogSW5qZWN0LFxuICAgICAgYXJnczogW0xPQ0FMRV9JRF1cbiAgICB9XVxuICB9LCB7XG4gICAgdHlwZTogdW5kZWZpbmVkLFxuICAgIGRlY29yYXRvcnM6IFt7XG4gICAgICB0eXBlOiBJbmplY3QsXG4gICAgICBhcmdzOiBbREVGQVVMVF9DVVJSRU5DWV9DT0RFXVxuICAgIH1dXG4gIH1dLCBudWxsKTtcbn0pKCk7XG5mdW5jdGlvbiBpc1ZhbHVlKHZhbHVlKSB7XG4gIHJldHVybiAhKHZhbHVlID09IG51bGwgfHwgdmFsdWUgPT09ICcnIHx8IHZhbHVlICE9PSB2YWx1ZSk7XG59XG4vKipcbiAqIFRyYW5zZm9ybXMgYSBzdHJpbmcgaW50byBhIG51bWJlciAoaWYgbmVlZGVkKS5cbiAqL1xuZnVuY3Rpb24gc3RyVG9OdW1iZXIodmFsdWUpIHtcbiAgLy8gQ29udmVydCBzdHJpbmdzIHRvIG51bWJlcnNcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgIWlzTmFOKE51bWJlcih2YWx1ZSkgLSBwYXJzZUZsb2F0KHZhbHVlKSkpIHtcbiAgICByZXR1cm4gTnVtYmVyKHZhbHVlKTtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHt2YWx1ZX0gaXMgbm90IGEgbnVtYmVyYCk7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG4vKipcbiAqIEBuZ01vZHVsZSBDb21tb25Nb2R1bGVcbiAqIEBkZXNjcmlwdGlvblxuICpcbiAqIENyZWF0ZXMgYSBuZXcgYEFycmF5YCBvciBgU3RyaW5nYCBjb250YWluaW5nIGEgc3Vic2V0IChzbGljZSkgb2YgdGhlIGVsZW1lbnRzLlxuICpcbiAqIEB1c2FnZU5vdGVzXG4gKlxuICogQWxsIGJlaGF2aW9yIGlzIGJhc2VkIG9uIHRoZSBleHBlY3RlZCBiZWhhdmlvciBvZiB0aGUgSmF2YVNjcmlwdCBBUEkgYEFycmF5LnByb3RvdHlwZS5zbGljZSgpYFxuICogYW5kIGBTdHJpbmcucHJvdG90eXBlLnNsaWNlKClgLlxuICpcbiAqIFdoZW4gb3BlcmF0aW5nIG9uIGFuIGBBcnJheWAsIHRoZSByZXR1cm5lZCBgQXJyYXlgIGlzIGFsd2F5cyBhIGNvcHkgZXZlbiB3aGVuIGFsbFxuICogdGhlIGVsZW1lbnRzIGFyZSBiZWluZyByZXR1cm5lZC5cbiAqXG4gKiBXaGVuIG9wZXJhdGluZyBvbiBhIGJsYW5rIHZhbHVlLCB0aGUgcGlwZSByZXR1cm5zIHRoZSBibGFuayB2YWx1ZS5cbiAqXG4gKiAjIyMgTGlzdCBFeGFtcGxlXG4gKlxuICogVGhpcyBgbmdGb3JgIGV4YW1wbGU6XG4gKlxuICoge0BleGFtcGxlIGNvbW1vbi9waXBlcy90cy9zbGljZV9waXBlLnRzIHJlZ2lvbj0nU2xpY2VQaXBlX2xpc3QnfVxuICpcbiAqIHByb2R1Y2VzIHRoZSBmb2xsb3dpbmc6XG4gKlxuICogYGBgaHRtbFxuICogPGxpPmI8L2xpPlxuICogPGxpPmM8L2xpPlxuICogYGBgXG4gKlxuICogIyMjIFN0cmluZyBFeGFtcGxlc1xuICpcbiAqIHtAZXhhbXBsZSBjb21tb24vcGlwZXMvdHMvc2xpY2VfcGlwZS50cyByZWdpb249J1NsaWNlUGlwZV9zdHJpbmcnfVxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgU2xpY2VQaXBlIHtcbiAgdHJhbnNmb3JtKHZhbHVlLCBzdGFydCwgZW5kKSB7XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHJldHVybiBudWxsO1xuICAgIGlmICghdGhpcy5zdXBwb3J0cyh2YWx1ZSkpIHtcbiAgICAgIHRocm93IGludmFsaWRQaXBlQXJndW1lbnRFcnJvcihTbGljZVBpcGUsIHZhbHVlKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICB9XG4gIHN1cHBvcnRzKG9iaikge1xuICAgIHJldHVybiB0eXBlb2Ygb2JqID09PSAnc3RyaW5nJyB8fCBBcnJheS5pc0FycmF5KG9iaik7XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gU2xpY2VQaXBlX0ZhY3RvcnkodCkge1xuICAgICAgcmV0dXJuIG5ldyAodCB8fCBTbGljZVBpcGUpKCk7XG4gICAgfTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVwaXBlID0gLyogQF9fUFVSRV9fICovaTAuybXJtWRlZmluZVBpcGUoe1xuICAgICAgbmFtZTogXCJzbGljZVwiLFxuICAgICAgdHlwZTogU2xpY2VQaXBlLFxuICAgICAgcHVyZTogZmFsc2UsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKFNsaWNlUGlwZSwgW3tcbiAgICB0eXBlOiBQaXBlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBuYW1lOiAnc2xpY2UnLFxuICAgICAgcHVyZTogZmFsc2UsXG4gICAgICBzdGFuZGFsb25lOiB0cnVlXG4gICAgfV1cbiAgfV0sIG51bGwsIG51bGwpO1xufSkoKTtcblxuLyoqXG4gKiBAbW9kdWxlXG4gKiBAZGVzY3JpcHRpb25cbiAqIFRoaXMgbW9kdWxlIHByb3ZpZGVzIGEgc2V0IG9mIGNvbW1vbiBQaXBlcy5cbiAqL1xuLyoqXG4gKiBBIGNvbGxlY3Rpb24gb2YgQW5ndWxhciBwaXBlcyB0aGF0IGFyZSBsaWtlbHkgdG8gYmUgdXNlZCBpbiBlYWNoIGFuZCBldmVyeSBhcHBsaWNhdGlvbi5cbiAqL1xuY29uc3QgQ09NTU9OX1BJUEVTID0gW0FzeW5jUGlwZSwgVXBwZXJDYXNlUGlwZSwgTG93ZXJDYXNlUGlwZSwgSnNvblBpcGUsIFNsaWNlUGlwZSwgRGVjaW1hbFBpcGUsIFBlcmNlbnRQaXBlLCBUaXRsZUNhc2VQaXBlLCBDdXJyZW5jeVBpcGUsIERhdGVQaXBlLCBJMThuUGx1cmFsUGlwZSwgSTE4blNlbGVjdFBpcGUsIEtleVZhbHVlUGlwZV07XG5cbi8vIE5vdGU6IFRoaXMgZG9lcyBub3QgY29udGFpbiB0aGUgbG9jYXRpb24gcHJvdmlkZXJzLFxuLy8gYXMgdGhleSBuZWVkIHNvbWUgcGxhdGZvcm0gc3BlY2lmaWMgaW1wbGVtZW50YXRpb25zIHRvIHdvcmsuXG4vKipcbiAqIEV4cG9ydHMgYWxsIHRoZSBiYXNpYyBBbmd1bGFyIGRpcmVjdGl2ZXMgYW5kIHBpcGVzLFxuICogc3VjaCBhcyBgTmdJZmAsIGBOZ0Zvck9mYCwgYERlY2ltYWxQaXBlYCwgYW5kIHNvIG9uLlxuICogUmUtZXhwb3J0ZWQgYnkgYEJyb3dzZXJNb2R1bGVgLCB3aGljaCBpcyBpbmNsdWRlZCBhdXRvbWF0aWNhbGx5IGluIHRoZSByb290XG4gKiBgQXBwTW9kdWxlYCB3aGVuIHlvdSBjcmVhdGUgYSBuZXcgYXBwIHdpdGggdGhlIENMSSBgbmV3YCBjb21tYW5kLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgQ29tbW9uTW9kdWxlIHtcbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gQ29tbW9uTW9kdWxlX0ZhY3RvcnkodCkge1xuICAgICAgcmV0dXJuIG5ldyAodCB8fCBDb21tb25Nb2R1bGUpKCk7XG4gICAgfTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVtb2QgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lTmdNb2R1bGUoe1xuICAgICAgdHlwZTogQ29tbW9uTW9kdWxlLFxuICAgICAgaW1wb3J0czogW05nQ2xhc3MsIE5nQ29tcG9uZW50T3V0bGV0LCBOZ0Zvck9mLCBOZ0lmLCBOZ1RlbXBsYXRlT3V0bGV0LCBOZ1N0eWxlLCBOZ1N3aXRjaCwgTmdTd2l0Y2hDYXNlLCBOZ1N3aXRjaERlZmF1bHQsIE5nUGx1cmFsLCBOZ1BsdXJhbENhc2UsIEFzeW5jUGlwZSwgVXBwZXJDYXNlUGlwZSwgTG93ZXJDYXNlUGlwZSwgSnNvblBpcGUsIFNsaWNlUGlwZSwgRGVjaW1hbFBpcGUsIFBlcmNlbnRQaXBlLCBUaXRsZUNhc2VQaXBlLCBDdXJyZW5jeVBpcGUsIERhdGVQaXBlLCBJMThuUGx1cmFsUGlwZSwgSTE4blNlbGVjdFBpcGUsIEtleVZhbHVlUGlwZV0sXG4gICAgICBleHBvcnRzOiBbTmdDbGFzcywgTmdDb21wb25lbnRPdXRsZXQsIE5nRm9yT2YsIE5nSWYsIE5nVGVtcGxhdGVPdXRsZXQsIE5nU3R5bGUsIE5nU3dpdGNoLCBOZ1N3aXRjaENhc2UsIE5nU3dpdGNoRGVmYXVsdCwgTmdQbHVyYWwsIE5nUGx1cmFsQ2FzZSwgQXN5bmNQaXBlLCBVcHBlckNhc2VQaXBlLCBMb3dlckNhc2VQaXBlLCBKc29uUGlwZSwgU2xpY2VQaXBlLCBEZWNpbWFsUGlwZSwgUGVyY2VudFBpcGUsIFRpdGxlQ2FzZVBpcGUsIEN1cnJlbmN5UGlwZSwgRGF0ZVBpcGUsIEkxOG5QbHVyYWxQaXBlLCBJMThuU2VsZWN0UGlwZSwgS2V5VmFsdWVQaXBlXVxuICAgIH0pO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWluaiA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVJbmplY3Rvcih7fSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKENvbW1vbk1vZHVsZSwgW3tcbiAgICB0eXBlOiBOZ01vZHVsZSxcbiAgICBhcmdzOiBbe1xuICAgICAgaW1wb3J0czogW0NPTU1PTl9ESVJFQ1RJVkVTLCBDT01NT05fUElQRVNdLFxuICAgICAgZXhwb3J0czogW0NPTU1PTl9ESVJFQ1RJVkVTLCBDT01NT05fUElQRVNdXG4gICAgfV1cbiAgfV0sIG51bGwsIG51bGwpO1xufSkoKTtcbmNvbnN0IFBMQVRGT1JNX0JST1dTRVJfSUQgPSAnYnJvd3Nlcic7XG5jb25zdCBQTEFURk9STV9TRVJWRVJfSUQgPSAnc2VydmVyJztcbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIGEgcGxhdGZvcm0gaWQgcmVwcmVzZW50cyBhIGJyb3dzZXIgcGxhdGZvcm0uXG4gKiBAcHVibGljQXBpXG4gKi9cbmZ1bmN0aW9uIGlzUGxhdGZvcm1Ccm93c2VyKHBsYXRmb3JtSWQpIHtcbiAgcmV0dXJuIHBsYXRmb3JtSWQgPT09IFBMQVRGT1JNX0JST1dTRVJfSUQ7XG59XG4vKipcbiAqIFJldHVybnMgd2hldGhlciBhIHBsYXRmb3JtIGlkIHJlcHJlc2VudHMgYSBzZXJ2ZXIgcGxhdGZvcm0uXG4gKiBAcHVibGljQXBpXG4gKi9cbmZ1bmN0aW9uIGlzUGxhdGZvcm1TZXJ2ZXIocGxhdGZvcm1JZCkge1xuICByZXR1cm4gcGxhdGZvcm1JZCA9PT0gUExBVEZPUk1fU0VSVkVSX0lEO1xufVxuXG4vKipcbiAqIEBtb2R1bGVcbiAqIEBkZXNjcmlwdGlvblxuICogRW50cnkgcG9pbnQgZm9yIGFsbCBwdWJsaWMgQVBJcyBvZiB0aGUgY29tbW9uIHBhY2thZ2UuXG4gKi9cbi8qKlxuICogQHB1YmxpY0FwaVxuICovXG5jb25zdCBWRVJTSU9OID0gbmV3IFZlcnNpb24oJzE4LjAuNScpO1xuXG4vKipcbiAqIERlZmluZXMgYSBzY3JvbGwgcG9zaXRpb24gbWFuYWdlci4gSW1wbGVtZW50ZWQgYnkgYEJyb3dzZXJWaWV3cG9ydFNjcm9sbGVyYC5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIFZpZXdwb3J0U2Nyb2xsZXIge1xuICAvLyBEZS1zdWdhcmVkIHRyZWUtc2hha2FibGUgaW5qZWN0aW9uXG4gIC8vIFNlZSAjMjM5MTdcbiAgLyoqIEBub2NvbGxhcHNlICovXG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXByb3YgPSDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7XG4gICAgICB0b2tlbjogVmlld3BvcnRTY3JvbGxlcixcbiAgICAgIHByb3ZpZGVkSW46ICdyb290JyxcbiAgICAgIGZhY3Rvcnk6ICgpID0+IGlzUGxhdGZvcm1Ccm93c2VyKGluamVjdChQTEFURk9STV9JRCkpID8gbmV3IEJyb3dzZXJWaWV3cG9ydFNjcm9sbGVyKGluamVjdChET0NVTUVOVCksIHdpbmRvdykgOiBuZXcgTnVsbFZpZXdwb3J0U2Nyb2xsZXIoKVxuICAgIH0pO1xuICB9XG59XG4vKipcbiAqIE1hbmFnZXMgdGhlIHNjcm9sbCBwb3NpdGlvbiBmb3IgYSBicm93c2VyIHdpbmRvdy5cbiAqL1xuY2xhc3MgQnJvd3NlclZpZXdwb3J0U2Nyb2xsZXIge1xuICBjb25zdHJ1Y3Rvcihkb2N1bWVudCwgd2luZG93KSB7XG4gICAgdGhpcy5kb2N1bWVudCA9IGRvY3VtZW50O1xuICAgIHRoaXMud2luZG93ID0gd2luZG93O1xuICAgIHRoaXMub2Zmc2V0ID0gKCkgPT4gWzAsIDBdO1xuICB9XG4gIC8qKlxuICAgKiBDb25maWd1cmVzIHRoZSB0b3Agb2Zmc2V0IHVzZWQgd2hlbiBzY3JvbGxpbmcgdG8gYW4gYW5jaG9yLlxuICAgKiBAcGFyYW0gb2Zmc2V0IEEgcG9zaXRpb24gaW4gc2NyZWVuIGNvb3JkaW5hdGVzIChhIHR1cGxlIHdpdGggeCBhbmQgeSB2YWx1ZXMpXG4gICAqIG9yIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB0b3Agb2Zmc2V0IHBvc2l0aW9uLlxuICAgKlxuICAgKi9cbiAgc2V0T2Zmc2V0KG9mZnNldCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KG9mZnNldCkpIHtcbiAgICAgIHRoaXMub2Zmc2V0ID0gKCkgPT4gb2Zmc2V0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9mZnNldCA9IG9mZnNldDtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIFJldHJpZXZlcyB0aGUgY3VycmVudCBzY3JvbGwgcG9zaXRpb24uXG4gICAqIEByZXR1cm5zIFRoZSBwb3NpdGlvbiBpbiBzY3JlZW4gY29vcmRpbmF0ZXMuXG4gICAqL1xuICBnZXRTY3JvbGxQb3NpdGlvbigpIHtcbiAgICByZXR1cm4gW3RoaXMud2luZG93LnNjcm9sbFgsIHRoaXMud2luZG93LnNjcm9sbFldO1xuICB9XG4gIC8qKlxuICAgKiBTZXRzIHRoZSBzY3JvbGwgcG9zaXRpb24uXG4gICAqIEBwYXJhbSBwb3NpdGlvbiBUaGUgbmV3IHBvc2l0aW9uIGluIHNjcmVlbiBjb29yZGluYXRlcy5cbiAgICovXG4gIHNjcm9sbFRvUG9zaXRpb24ocG9zaXRpb24pIHtcbiAgICB0aGlzLndpbmRvdy5zY3JvbGxUbyhwb3NpdGlvblswXSwgcG9zaXRpb25bMV0pO1xuICB9XG4gIC8qKlxuICAgKiBTY3JvbGxzIHRvIGFuIGVsZW1lbnQgYW5kIGF0dGVtcHRzIHRvIGZvY3VzIHRoZSBlbGVtZW50LlxuICAgKlxuICAgKiBOb3RlIHRoYXQgdGhlIGZ1bmN0aW9uIG5hbWUgaGVyZSBpcyBtaXNsZWFkaW5nIGluIHRoYXQgdGhlIHRhcmdldCBzdHJpbmcgbWF5IGJlIGFuIElEIGZvciBhXG4gICAqIG5vbi1hbmNob3IgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHRhcmdldCBUaGUgSUQgb2YgYW4gZWxlbWVudCBvciBuYW1lIG9mIHRoZSBhbmNob3IuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jdGhlLWluZGljYXRlZC1wYXJ0LW9mLXRoZS1kb2N1bWVudFxuICAgKiBAc2VlIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI3Njcm9sbC10by1mcmFnaWRcbiAgICovXG4gIHNjcm9sbFRvQW5jaG9yKHRhcmdldCkge1xuICAgIGNvbnN0IGVsU2VsZWN0ZWQgPSBmaW5kQW5jaG9yRnJvbURvY3VtZW50KHRoaXMuZG9jdW1lbnQsIHRhcmdldCk7XG4gICAgaWYgKGVsU2VsZWN0ZWQpIHtcbiAgICAgIHRoaXMuc2Nyb2xsVG9FbGVtZW50KGVsU2VsZWN0ZWQpO1xuICAgICAgLy8gQWZ0ZXIgc2Nyb2xsaW5nIHRvIHRoZSBlbGVtZW50LCB0aGUgc3BlYyBkaWN0YXRlcyB0aGF0IHdlIGZvbGxvdyB0aGUgZm9jdXMgc3RlcHMgZm9yIHRoZVxuICAgICAgLy8gdGFyZ2V0LiBSYXRoZXIgdGhhbiBmb2xsb3dpbmcgdGhlIHJvYnVzdCBzdGVwcywgc2ltcGx5IGF0dGVtcHQgZm9jdXMuXG4gICAgICAvL1xuICAgICAgLy8gQHNlZSBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNnZXQtdGhlLWZvY3VzYWJsZS1hcmVhXG4gICAgICAvLyBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9IVE1MT3JGb3JlaWduRWxlbWVudC9mb2N1c1xuICAgICAgLy8gQHNlZSBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNmb2N1c2FibGUtYXJlYVxuICAgICAgZWxTZWxlY3RlZC5mb2N1cygpO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogRGlzYWJsZXMgYXV0b21hdGljIHNjcm9sbCByZXN0b3JhdGlvbiBwcm92aWRlZCBieSB0aGUgYnJvd3Nlci5cbiAgICovXG4gIHNldEhpc3RvcnlTY3JvbGxSZXN0b3JhdGlvbihzY3JvbGxSZXN0b3JhdGlvbikge1xuICAgIHRoaXMud2luZG93Lmhpc3Rvcnkuc2Nyb2xsUmVzdG9yYXRpb24gPSBzY3JvbGxSZXN0b3JhdGlvbjtcbiAgfVxuICAvKipcbiAgICogU2Nyb2xscyB0byBhbiBlbGVtZW50IHVzaW5nIHRoZSBuYXRpdmUgb2Zmc2V0IGFuZCB0aGUgc3BlY2lmaWVkIG9mZnNldCBzZXQgb24gdGhpcyBzY3JvbGxlci5cbiAgICpcbiAgICogVGhlIG9mZnNldCBjYW4gYmUgdXNlZCB3aGVuIHdlIGtub3cgdGhhdCB0aGVyZSBpcyBhIGZsb2F0aW5nIGhlYWRlciBhbmQgc2Nyb2xsaW5nIG5haXZlbHkgdG8gYW5cbiAgICogZWxlbWVudCAoZXg6IGBzY3JvbGxJbnRvVmlld2ApIGxlYXZlcyB0aGUgZWxlbWVudCBoaWRkZW4gYmVoaW5kIHRoZSBmbG9hdGluZyBoZWFkZXIuXG4gICAqL1xuICBzY3JvbGxUb0VsZW1lbnQoZWwpIHtcbiAgICBjb25zdCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgbGVmdCA9IHJlY3QubGVmdCArIHRoaXMud2luZG93LnBhZ2VYT2Zmc2V0O1xuICAgIGNvbnN0IHRvcCA9IHJlY3QudG9wICsgdGhpcy53aW5kb3cucGFnZVlPZmZzZXQ7XG4gICAgY29uc3Qgb2Zmc2V0ID0gdGhpcy5vZmZzZXQoKTtcbiAgICB0aGlzLndpbmRvdy5zY3JvbGxUbyhsZWZ0IC0gb2Zmc2V0WzBdLCB0b3AgLSBvZmZzZXRbMV0pO1xuICB9XG59XG5mdW5jdGlvbiBmaW5kQW5jaG9yRnJvbURvY3VtZW50KGRvY3VtZW50LCB0YXJnZXQpIHtcbiAgY29uc3QgZG9jdW1lbnRSZXN1bHQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0YXJnZXQpIHx8IGRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lKHRhcmdldClbMF07XG4gIGlmIChkb2N1bWVudFJlc3VsdCkge1xuICAgIHJldHVybiBkb2N1bWVudFJlc3VsdDtcbiAgfVxuICAvLyBgZ2V0RWxlbWVudEJ5SWRgIGFuZCBgZ2V0RWxlbWVudHNCeU5hbWVgIHdvbid0IHBpZXJjZSB0aHJvdWdoIHRoZSBzaGFkb3cgRE9NIHNvIHdlXG4gIC8vIGhhdmUgdG8gdHJhdmVyc2UgdGhlIERPTSBtYW51YWxseSBhbmQgZG8gdGhlIGxvb2t1cCB0aHJvdWdoIHRoZSBzaGFkb3cgcm9vdHMuXG4gIGlmICh0eXBlb2YgZG9jdW1lbnQuY3JlYXRlVHJlZVdhbGtlciA9PT0gJ2Z1bmN0aW9uJyAmJiBkb2N1bWVudC5ib2R5ICYmIHR5cGVvZiBkb2N1bWVudC5ib2R5LmF0dGFjaFNoYWRvdyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGNvbnN0IHRyZWVXYWxrZXIgPSBkb2N1bWVudC5jcmVhdGVUcmVlV2Fsa2VyKGRvY3VtZW50LmJvZHksIE5vZGVGaWx0ZXIuU0hPV19FTEVNRU5UKTtcbiAgICBsZXQgY3VycmVudE5vZGUgPSB0cmVlV2Fsa2VyLmN1cnJlbnROb2RlO1xuICAgIHdoaWxlIChjdXJyZW50Tm9kZSkge1xuICAgICAgY29uc3Qgc2hhZG93Um9vdCA9IGN1cnJlbnROb2RlLnNoYWRvd1Jvb3Q7XG4gICAgICBpZiAoc2hhZG93Um9vdCkge1xuICAgICAgICAvLyBOb3RlIHRoYXQgYFNoYWRvd1Jvb3RgIGRvZXNuJ3Qgc3VwcG9ydCBgZ2V0RWxlbWVudHNCeU5hbWVgXG4gICAgICAgIC8vIHNvIHdlIGhhdmUgdG8gZmFsbCBiYWNrIHRvIGBxdWVyeVNlbGVjdG9yYC5cbiAgICAgICAgY29uc3QgcmVzdWx0ID0gc2hhZG93Um9vdC5nZXRFbGVtZW50QnlJZCh0YXJnZXQpIHx8IHNoYWRvd1Jvb3QucXVlcnlTZWxlY3RvcihgW25hbWU9XCIke3RhcmdldH1cIl1gKTtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGN1cnJlbnROb2RlID0gdHJlZVdhbGtlci5uZXh0Tm9kZSgpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cbi8qKlxuICogUHJvdmlkZXMgYW4gZW1wdHkgaW1wbGVtZW50YXRpb24gb2YgdGhlIHZpZXdwb3J0IHNjcm9sbGVyLlxuICovXG5jbGFzcyBOdWxsVmlld3BvcnRTY3JvbGxlciB7XG4gIC8qKlxuICAgKiBFbXB0eSBpbXBsZW1lbnRhdGlvblxuICAgKi9cbiAgc2V0T2Zmc2V0KG9mZnNldCkge31cbiAgLyoqXG4gICAqIEVtcHR5IGltcGxlbWVudGF0aW9uXG4gICAqL1xuICBnZXRTY3JvbGxQb3NpdGlvbigpIHtcbiAgICByZXR1cm4gWzAsIDBdO1xuICB9XG4gIC8qKlxuICAgKiBFbXB0eSBpbXBsZW1lbnRhdGlvblxuICAgKi9cbiAgc2Nyb2xsVG9Qb3NpdGlvbihwb3NpdGlvbikge31cbiAgLyoqXG4gICAqIEVtcHR5IGltcGxlbWVudGF0aW9uXG4gICAqL1xuICBzY3JvbGxUb0FuY2hvcihhbmNob3IpIHt9XG4gIC8qKlxuICAgKiBFbXB0eSBpbXBsZW1lbnRhdGlvblxuICAgKi9cbiAgc2V0SGlzdG9yeVNjcm9sbFJlc3RvcmF0aW9uKHNjcm9sbFJlc3RvcmF0aW9uKSB7fVxufVxuXG4vKipcbiAqIEEgd3JhcHBlciBhcm91bmQgdGhlIGBYTUxIdHRwUmVxdWVzdGAgY29uc3RydWN0b3IuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBYaHJGYWN0b3J5IHt9XG5cbi8qKlxuICogVmFsdWUgKG91dCBvZiAxMDApIG9mIHRoZSByZXF1ZXN0ZWQgcXVhbGl0eSBmb3IgcGxhY2Vob2xkZXIgaW1hZ2VzLlxuICovXG5jb25zdCBQTEFDRUhPTERFUl9RVUFMSVRZID0gJzIwJztcblxuLy8gQ29udmVydHMgYSBzdHJpbmcgdGhhdCByZXByZXNlbnRzIGEgVVJMIGludG8gYSBVUkwgY2xhc3MgaW5zdGFuY2UuXG5mdW5jdGlvbiBnZXRVcmwoc3JjLCB3aW4pIHtcbiAgLy8gRG9uJ3QgdXNlIGEgYmFzZSBVUkwgaXMgdGhlIFVSTCBpcyBhYnNvbHV0ZS5cbiAgcmV0dXJuIGlzQWJzb2x1dGVVcmwoc3JjKSA/IG5ldyBVUkwoc3JjKSA6IG5ldyBVUkwoc3JjLCB3aW4ubG9jYXRpb24uaHJlZik7XG59XG4vLyBDaGVja3Mgd2hldGhlciBhIFVSTCBpcyBhYnNvbHV0ZSAoaS5lLiBzdGFydHMgd2l0aCBgaHR0cDovL2Agb3IgYGh0dHBzOi8vYCkuXG5mdW5jdGlvbiBpc0Fic29sdXRlVXJsKHNyYykge1xuICByZXR1cm4gL15odHRwcz86XFwvXFwvLy50ZXN0KHNyYyk7XG59XG4vLyBHaXZlbiBhIFVSTCwgZXh0cmFjdCB0aGUgaG9zdG5hbWUgcGFydC5cbi8vIElmIGEgVVJMIGlzIGEgcmVsYXRpdmUgb25lIC0gdGhlIFVSTCBpcyByZXR1cm5lZCBhcyBpcy5cbmZ1bmN0aW9uIGV4dHJhY3RIb3N0bmFtZSh1cmwpIHtcbiAgcmV0dXJuIGlzQWJzb2x1dGVVcmwodXJsKSA/IG5ldyBVUkwodXJsKS5ob3N0bmFtZSA6IHVybDtcbn1cbmZ1bmN0aW9uIGlzVmFsaWRQYXRoKHBhdGgpIHtcbiAgY29uc3QgaXNTdHJpbmcgPSB0eXBlb2YgcGF0aCA9PT0gJ3N0cmluZyc7XG4gIGlmICghaXNTdHJpbmcgfHwgcGF0aC50cmltKCkgPT09ICcnKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vIENhbGxpbmcgbmV3IFVSTCgpIHdpbGwgdGhyb3cgaWYgdGhlIHBhdGggc3RyaW5nIGlzIG1hbGZvcm1lZFxuICB0cnkge1xuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocGF0aCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuZnVuY3Rpb24gbm9ybWFsaXplUGF0aChwYXRoKSB7XG4gIHJldHVybiBwYXRoLmVuZHNXaXRoKCcvJykgPyBwYXRoLnNsaWNlKDAsIC0xKSA6IHBhdGg7XG59XG5mdW5jdGlvbiBub3JtYWxpemVTcmMoc3JjKSB7XG4gIHJldHVybiBzcmMuc3RhcnRzV2l0aCgnLycpID8gc3JjLnNsaWNlKDEpIDogc3JjO1xufVxuXG4vKipcbiAqIE5vb3AgaW1hZ2UgbG9hZGVyIHRoYXQgZG9lcyBubyB0cmFuc2Zvcm1hdGlvbiB0byB0aGUgb3JpZ2luYWwgc3JjIGFuZCBqdXN0IHJldHVybnMgaXQgYXMgaXMuXG4gKiBUaGlzIGxvYWRlciBpcyB1c2VkIGFzIGEgZGVmYXVsdCBvbmUgaWYgbW9yZSBzcGVjaWZpYyBsb2dpYyBpcyBub3QgcHJvdmlkZWQgaW4gYW4gYXBwIGNvbmZpZy5cbiAqXG4gKiBAc2VlIHtAbGluayBJbWFnZUxvYWRlcn1cbiAqIEBzZWUge0BsaW5rIE5nT3B0aW1pemVkSW1hZ2V9XG4gKi9cbmNvbnN0IG5vb3BJbWFnZUxvYWRlciA9IGNvbmZpZyA9PiBjb25maWcuc3JjO1xuLyoqXG4gKiBJbmplY3Rpb24gdG9rZW4gdGhhdCBjb25maWd1cmVzIHRoZSBpbWFnZSBsb2FkZXIgZnVuY3Rpb24uXG4gKlxuICogQHNlZSB7QGxpbmsgSW1hZ2VMb2FkZXJ9XG4gKiBAc2VlIHtAbGluayBOZ09wdGltaXplZEltYWdlfVxuICogQHB1YmxpY0FwaVxuICovXG5jb25zdCBJTUFHRV9MT0FERVIgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gJ0ltYWdlTG9hZGVyJyA6ICcnLCB7XG4gIHByb3ZpZGVkSW46ICdyb290JyxcbiAgZmFjdG9yeTogKCkgPT4gbm9vcEltYWdlTG9hZGVyXG59KTtcbi8qKlxuICogSW50ZXJuYWwgaGVscGVyIGZ1bmN0aW9uIHRoYXQgbWFrZXMgaXQgZWFzaWVyIHRvIGludHJvZHVjZSBjdXN0b20gaW1hZ2UgbG9hZGVycyBmb3IgdGhlXG4gKiBgTmdPcHRpbWl6ZWRJbWFnZWAgZGlyZWN0aXZlLiBJdCBpcyBlbm91Z2ggdG8gc3BlY2lmeSBhIFVSTCBidWlsZGVyIGZ1bmN0aW9uIHRvIG9idGFpbiBmdWxsIERJXG4gKiBjb25maWd1cmF0aW9uIGZvciBhIGdpdmVuIGxvYWRlcjogYSBESSB0b2tlbiBjb3JyZXNwb25kaW5nIHRvIHRoZSBhY3R1YWwgbG9hZGVyIGZ1bmN0aW9uLCBwbHVzIERJXG4gKiB0b2tlbnMgbWFuYWdpbmcgcHJlY29ubmVjdCBjaGVjayBmdW5jdGlvbmFsaXR5LlxuICogQHBhcmFtIGJ1aWxkVXJsRm4gYSBmdW5jdGlvbiByZXR1cm5pbmcgYSBmdWxsIFVSTCBiYXNlZCBvbiBsb2FkZXIncyBjb25maWd1cmF0aW9uXG4gKiBAcGFyYW0gZXhhbXBsZVVybHMgZXhhbXBsZSBvZiBmdWxsIFVSTHMgZm9yIGEgZ2l2ZW4gbG9hZGVyICh1c2VkIGluIGVycm9yIG1lc3NhZ2VzKVxuICogQHJldHVybnMgYSBzZXQgb2YgREkgcHJvdmlkZXJzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIGNvbmZpZ3VyZWQgaW1hZ2UgbG9hZGVyXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUltYWdlTG9hZGVyKGJ1aWxkVXJsRm4sIGV4YW1wbGVVcmxzKSB7XG4gIHJldHVybiBmdW5jdGlvbiBwcm92aWRlSW1hZ2VMb2FkZXIocGF0aCkge1xuICAgIGlmICghaXNWYWxpZFBhdGgocGF0aCkpIHtcbiAgICAgIHRocm93SW52YWxpZFBhdGhFcnJvcihwYXRoLCBleGFtcGxlVXJscyB8fCBbXSk7XG4gICAgfVxuICAgIC8vIFRoZSB0cmFpbGluZyAvIGlzIHN0cmlwcGVkIChpZiBwcm92aWRlZCkgdG8gbWFrZSBVUkwgY29uc3RydWN0aW9uIChjb25jYXRlbmF0aW9uKSBlYXNpZXIgaW5cbiAgICAvLyB0aGUgaW5kaXZpZHVhbCBsb2FkZXIgZnVuY3Rpb25zLlxuICAgIHBhdGggPSBub3JtYWxpemVQYXRoKHBhdGgpO1xuICAgIGNvbnN0IGxvYWRlckZuID0gY29uZmlnID0+IHtcbiAgICAgIGlmIChpc0Fic29sdXRlVXJsKGNvbmZpZy5zcmMpKSB7XG4gICAgICAgIC8vIEltYWdlIGxvYWRlciBmdW5jdGlvbnMgZXhwZWN0IGFuIGltYWdlIGZpbGUgbmFtZSAoZS5nLiBgbXktaW1hZ2UucG5nYClcbiAgICAgICAgLy8gb3IgYSByZWxhdGl2ZSBwYXRoICsgYSBmaWxlIG5hbWUgKGUuZy4gYC9hL2IvYy9teS1pbWFnZS5wbmdgKSBhcyBhbiBpbnB1dCxcbiAgICAgICAgLy8gc28gdGhlIGZpbmFsIGFic29sdXRlIFVSTCBjYW4gYmUgY29uc3RydWN0ZWQuXG4gICAgICAgIC8vIFdoZW4gYW4gYWJzb2x1dGUgVVJMIGlzIHByb3ZpZGVkIGluc3RlYWQgLSB0aGUgbG9hZGVyIGNhbiBub3RcbiAgICAgICAgLy8gYnVpbGQgYSBmaW5hbCBVUkwsIHRodXMgdGhlIGVycm9yIGlzIHRocm93biB0byBpbmRpY2F0ZSB0aGF0LlxuICAgICAgICB0aHJvd1VuZXhwZWN0ZWRBYnNvbHV0ZVVybEVycm9yKHBhdGgsIGNvbmZpZy5zcmMpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGJ1aWxkVXJsRm4ocGF0aCwge1xuICAgICAgICAuLi5jb25maWcsXG4gICAgICAgIHNyYzogbm9ybWFsaXplU3JjKGNvbmZpZy5zcmMpXG4gICAgICB9KTtcbiAgICB9O1xuICAgIGNvbnN0IHByb3ZpZGVycyA9IFt7XG4gICAgICBwcm92aWRlOiBJTUFHRV9MT0FERVIsXG4gICAgICB1c2VWYWx1ZTogbG9hZGVyRm5cbiAgICB9XTtcbiAgICByZXR1cm4gcHJvdmlkZXJzO1xuICB9O1xufVxuZnVuY3Rpb24gdGhyb3dJbnZhbGlkUGF0aEVycm9yKHBhdGgsIGV4YW1wbGVVcmxzKSB7XG4gIHRocm93IG5ldyDJtVJ1bnRpbWVFcnJvcigyOTU5IC8qIFJ1bnRpbWVFcnJvckNvZGUuSU5WQUxJRF9MT0FERVJfQVJHVU1FTlRTICovLCBuZ0Rldk1vZGUgJiYgYEltYWdlIGxvYWRlciBoYXMgZGV0ZWN0ZWQgYW4gaW52YWxpZCBwYXRoIChcXGAke3BhdGh9XFxgKS4gYCArIGBUbyBmaXggdGhpcywgc3VwcGx5IGEgcGF0aCB1c2luZyBvbmUgb2YgdGhlIGZvbGxvd2luZyBmb3JtYXRzOiAke2V4YW1wbGVVcmxzLmpvaW4oJyBvciAnKX1gKTtcbn1cbmZ1bmN0aW9uIHRocm93VW5leHBlY3RlZEFic29sdXRlVXJsRXJyb3IocGF0aCwgdXJsKSB7XG4gIHRocm93IG5ldyDJtVJ1bnRpbWVFcnJvcigyOTU5IC8qIFJ1bnRpbWVFcnJvckNvZGUuSU5WQUxJRF9MT0FERVJfQVJHVU1FTlRTICovLCBuZ0Rldk1vZGUgJiYgYEltYWdlIGxvYWRlciBoYXMgZGV0ZWN0ZWQgYSBcXGA8aW1nPlxcYCB0YWcgd2l0aCBhbiBpbnZhbGlkIFxcYG5nU3JjXFxgIGF0dHJpYnV0ZTogJHt1cmx9LiBgICsgYFRoaXMgaW1hZ2UgbG9hZGVyIGV4cGVjdHMgXFxgbmdTcmNcXGAgdG8gYmUgYSByZWxhdGl2ZSBVUkwgLSBgICsgYGhvd2V2ZXIgdGhlIHByb3ZpZGVkIHZhbHVlIGlzIGFuIGFic29sdXRlIFVSTC4gYCArIGBUbyBmaXggdGhpcywgcHJvdmlkZSBcXGBuZ1NyY1xcYCBhcyBhIHBhdGggcmVsYXRpdmUgdG8gdGhlIGJhc2UgVVJMIGAgKyBgY29uZmlndXJlZCBmb3IgdGhpcyBsb2FkZXIgKFxcYCR7cGF0aH1cXGApLmApO1xufVxuXG4vKipcbiAqIEZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIGFuIEltYWdlTG9hZGVyIGZvciBbQ2xvdWRmbGFyZSBJbWFnZVxuICogUmVzaXppbmddKGh0dHBzOi8vZGV2ZWxvcGVycy5jbG91ZGZsYXJlLmNvbS9pbWFnZXMvaW1hZ2UtcmVzaXppbmcvKSBhbmQgdHVybnMgaXQgaW50byBhbiBBbmd1bGFyXG4gKiBwcm92aWRlci4gTm90ZTogQ2xvdWRmbGFyZSBoYXMgbXVsdGlwbGUgaW1hZ2UgcHJvZHVjdHMgLSB0aGlzIHByb3ZpZGVyIGlzIHNwZWNpZmljYWxseSBmb3JcbiAqIENsb3VkZmxhcmUgSW1hZ2UgUmVzaXppbmc7IGl0IHdpbGwgbm90IHdvcmsgd2l0aCBDbG91ZGZsYXJlIEltYWdlcyBvciBDbG91ZGZsYXJlIFBvbGlzaC5cbiAqXG4gKiBAcGFyYW0gcGF0aCBZb3VyIGRvbWFpbiBuYW1lLCBlLmcuIGh0dHBzOi8vbXlzaXRlLmNvbVxuICogQHJldHVybnMgUHJvdmlkZXIgdGhhdCBwcm92aWRlcyBhbiBJbWFnZUxvYWRlciBmdW5jdGlvblxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY29uc3QgcHJvdmlkZUNsb3VkZmxhcmVMb2FkZXIgPSBjcmVhdGVJbWFnZUxvYWRlcihjcmVhdGVDbG91ZGZsYXJlVXJsLCBuZ0Rldk1vZGUgPyBbJ2h0dHBzOi8vPFpPTkU+L2Nkbi1jZ2kvaW1hZ2UvPE9QVElPTlM+LzxTT1VSQ0UtSU1BR0U+J10gOiB1bmRlZmluZWQpO1xuZnVuY3Rpb24gY3JlYXRlQ2xvdWRmbGFyZVVybChwYXRoLCBjb25maWcpIHtcbiAgbGV0IHBhcmFtcyA9IGBmb3JtYXQ9YXV0b2A7XG4gIGlmIChjb25maWcud2lkdGgpIHtcbiAgICBwYXJhbXMgKz0gYCx3aWR0aD0ke2NvbmZpZy53aWR0aH1gO1xuICB9XG4gIC8vIFdoZW4gcmVxdWVzdGluZyBhIHBsYWNlaG9sZGVyIGltYWdlIHdlIGFzayBmb3IgYSBsb3cgcXVhbGl0eSBpbWFnZSB0byByZWR1Y2UgdGhlIGxvYWQgdGltZS5cbiAgaWYgKGNvbmZpZy5pc1BsYWNlaG9sZGVyKSB7XG4gICAgcGFyYW1zICs9IGAscXVhbGl0eT0ke1BMQUNFSE9MREVSX1FVQUxJVFl9YDtcbiAgfVxuICAvLyBDbG91ZGZsYXJlIGltYWdlIFVSTHMgZm9ybWF0OlxuICAvLyBodHRwczovL2RldmVsb3BlcnMuY2xvdWRmbGFyZS5jb20vaW1hZ2VzL2ltYWdlLXJlc2l6aW5nL3VybC1mb3JtYXQvXG4gIHJldHVybiBgJHtwYXRofS9jZG4tY2dpL2ltYWdlLyR7cGFyYW1zfS8ke2NvbmZpZy5zcmN9YDtcbn1cblxuLyoqXG4gKiBOYW1lIGFuZCBVUkwgdGVzdGVyIGZvciBDbG91ZGluYXJ5LlxuICovXG5jb25zdCBjbG91ZGluYXJ5TG9hZGVySW5mbyA9IHtcbiAgbmFtZTogJ0Nsb3VkaW5hcnknLFxuICB0ZXN0VXJsOiBpc0Nsb3VkaW5hcnlVcmxcbn07XG5jb25zdCBDTE9VRElOQVJZX0xPQURFUl9SRUdFWCA9IC9odHRwcz9cXDpcXC9cXC9bXlxcL10rXFwuY2xvdWRpbmFyeVxcLmNvbVxcLy4rLztcbi8qKlxuICogVGVzdHMgd2hldGhlciBhIFVSTCBpcyBmcm9tIENsb3VkaW5hcnkgQ0ROLlxuICovXG5mdW5jdGlvbiBpc0Nsb3VkaW5hcnlVcmwodXJsKSB7XG4gIHJldHVybiBDTE9VRElOQVJZX0xPQURFUl9SRUdFWC50ZXN0KHVybCk7XG59XG4vKipcbiAqIEZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIGFuIEltYWdlTG9hZGVyIGZvciBDbG91ZGluYXJ5IGFuZCB0dXJucyBpdCBpbnRvIGFuIEFuZ3VsYXIgcHJvdmlkZXIuXG4gKlxuICogQHBhcmFtIHBhdGggQmFzZSBVUkwgb2YgeW91ciBDbG91ZGluYXJ5IGltYWdlc1xuICogVGhpcyBVUkwgc2hvdWxkIG1hdGNoIG9uZSBvZiB0aGUgZm9sbG93aW5nIGZvcm1hdHM6XG4gKiBodHRwczovL3Jlcy5jbG91ZGluYXJ5LmNvbS9teXNpdGVcbiAqIGh0dHBzOi8vbXlzaXRlLmNsb3VkaW5hcnkuY29tXG4gKiBodHRwczovL3N1YmRvbWFpbi5teXNpdGUuY29tXG4gKiBAcmV0dXJucyBTZXQgb2YgcHJvdmlkZXJzIHRvIGNvbmZpZ3VyZSB0aGUgQ2xvdWRpbmFyeSBsb2FkZXIuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jb25zdCBwcm92aWRlQ2xvdWRpbmFyeUxvYWRlciA9IGNyZWF0ZUltYWdlTG9hZGVyKGNyZWF0ZUNsb3VkaW5hcnlVcmwsIG5nRGV2TW9kZSA/IFsnaHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vbXlzaXRlJywgJ2h0dHBzOi8vbXlzaXRlLmNsb3VkaW5hcnkuY29tJywgJ2h0dHBzOi8vc3ViZG9tYWluLm15c2l0ZS5jb20nXSA6IHVuZGVmaW5lZCk7XG5mdW5jdGlvbiBjcmVhdGVDbG91ZGluYXJ5VXJsKHBhdGgsIGNvbmZpZykge1xuICAvLyBDbG91ZGluYXJ5IGltYWdlIFVSTGZvcm1hdDpcbiAgLy8gaHR0cHM6Ly9jbG91ZGluYXJ5LmNvbS9kb2N1bWVudGF0aW9uL2ltYWdlX3RyYW5zZm9ybWF0aW9ucyN0cmFuc2Zvcm1hdGlvbl91cmxfc3RydWN0dXJlXG4gIC8vIEV4YW1wbGUgb2YgYSBDbG91ZGluYXJ5IGltYWdlIFVSTDpcbiAgLy8gaHR0cHM6Ly9yZXMuY2xvdWRpbmFyeS5jb20vbXlzaXRlL2ltYWdlL3VwbG9hZC9jX3NjYWxlLGZfYXV0byxxX2F1dG8sd182MDAvbWFya2V0aW5nL3RpbGUtdG9waWNzLW0ucG5nXG4gIC8vIEZvciBhIHBsYWNlaG9sZGVyIGltYWdlLCB3ZSB1c2UgdGhlIGxvd2VzdCBpbWFnZSBzZXR0aW5nIGF2YWlsYWJsZSB0byByZWR1Y2UgdGhlIGxvYWQgdGltZVxuICAvLyBlbHNlIHdlIHVzZSB0aGUgYXV0byBzaXplXG4gIGNvbnN0IHF1YWxpdHkgPSBjb25maWcuaXNQbGFjZWhvbGRlciA/ICdxX2F1dG86bG93JyA6ICdxX2F1dG8nO1xuICBsZXQgcGFyYW1zID0gYGZfYXV0bywke3F1YWxpdHl9YDtcbiAgaWYgKGNvbmZpZy53aWR0aCkge1xuICAgIHBhcmFtcyArPSBgLHdfJHtjb25maWcud2lkdGh9YDtcbiAgfVxuICByZXR1cm4gYCR7cGF0aH0vaW1hZ2UvdXBsb2FkLyR7cGFyYW1zfS8ke2NvbmZpZy5zcmN9YDtcbn1cblxuLyoqXG4gKiBOYW1lIGFuZCBVUkwgdGVzdGVyIGZvciBJbWFnZUtpdC5cbiAqL1xuY29uc3QgaW1hZ2VLaXRMb2FkZXJJbmZvID0ge1xuICBuYW1lOiAnSW1hZ2VLaXQnLFxuICB0ZXN0VXJsOiBpc0ltYWdlS2l0VXJsXG59O1xuY29uc3QgSU1BR0VfS0lUX0xPQURFUl9SRUdFWCA9IC9odHRwcz9cXDpcXC9cXC9bXlxcL10rXFwuaW1hZ2VraXRcXC5pb1xcLy4rLztcbi8qKlxuICogVGVzdHMgd2hldGhlciBhIFVSTCBpcyBmcm9tIEltYWdlS2l0IENETi5cbiAqL1xuZnVuY3Rpb24gaXNJbWFnZUtpdFVybCh1cmwpIHtcbiAgcmV0dXJuIElNQUdFX0tJVF9MT0FERVJfUkVHRVgudGVzdCh1cmwpO1xufVxuLyoqXG4gKiBGdW5jdGlvbiB0aGF0IGdlbmVyYXRlcyBhbiBJbWFnZUxvYWRlciBmb3IgSW1hZ2VLaXQgYW5kIHR1cm5zIGl0IGludG8gYW4gQW5ndWxhciBwcm92aWRlci5cbiAqXG4gKiBAcGFyYW0gcGF0aCBCYXNlIFVSTCBvZiB5b3VyIEltYWdlS2l0IGltYWdlc1xuICogVGhpcyBVUkwgc2hvdWxkIG1hdGNoIG9uZSBvZiB0aGUgZm9sbG93aW5nIGZvcm1hdHM6XG4gKiBodHRwczovL2lrLmltYWdla2l0LmlvL215YWNjb3VudFxuICogaHR0cHM6Ly9zdWJkb21haW4ubXlzaXRlLmNvbVxuICogQHJldHVybnMgU2V0IG9mIHByb3ZpZGVycyB0byBjb25maWd1cmUgdGhlIEltYWdlS2l0IGxvYWRlci5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNvbnN0IHByb3ZpZGVJbWFnZUtpdExvYWRlciA9IGNyZWF0ZUltYWdlTG9hZGVyKGNyZWF0ZUltYWdla2l0VXJsLCBuZ0Rldk1vZGUgPyBbJ2h0dHBzOi8vaWsuaW1hZ2VraXQuaW8vbXlzaXRlJywgJ2h0dHBzOi8vc3ViZG9tYWluLm15c2l0ZS5jb20nXSA6IHVuZGVmaW5lZCk7XG5mdW5jdGlvbiBjcmVhdGVJbWFnZWtpdFVybChwYXRoLCBjb25maWcpIHtcbiAgLy8gRXhhbXBsZSBvZiBhbiBJbWFnZUtpdCBpbWFnZSBVUkw6XG4gIC8vIGh0dHBzOi8vaWsuaW1hZ2VraXQuaW8vZGVtby90cjp3LTMwMCxoLTMwMC9tZWRpdW1fY2FmZV9CMWlUZEQwQy5qcGdcbiAgY29uc3Qge1xuICAgIHNyYyxcbiAgICB3aWR0aFxuICB9ID0gY29uZmlnO1xuICBjb25zdCBwYXJhbXMgPSBbXTtcbiAgaWYgKHdpZHRoKSB7XG4gICAgcGFyYW1zLnB1c2goYHctJHt3aWR0aH1gKTtcbiAgfVxuICAvLyBXaGVuIHJlcXVlc3RpbmcgYSBwbGFjZWhvbGRlciBpbWFnZSB3ZSBhc2sgZm9yIGEgbG93IHF1YWxpdHkgaW1hZ2UgdG8gcmVkdWNlIHRoZSBsb2FkIHRpbWUuXG4gIGlmIChjb25maWcuaXNQbGFjZWhvbGRlcikge1xuICAgIHBhcmFtcy5wdXNoKGBxLSR7UExBQ0VIT0xERVJfUVVBTElUWX1gKTtcbiAgfVxuICBjb25zdCB1cmxTZWdtZW50cyA9IHBhcmFtcy5sZW5ndGggPyBbcGF0aCwgYHRyOiR7cGFyYW1zLmpvaW4oJywnKX1gLCBzcmNdIDogW3BhdGgsIHNyY107XG4gIGNvbnN0IHVybCA9IG5ldyBVUkwodXJsU2VnbWVudHMuam9pbignLycpKTtcbiAgcmV0dXJuIHVybC5ocmVmO1xufVxuXG4vKipcbiAqIE5hbWUgYW5kIFVSTCB0ZXN0ZXIgZm9yIEltZ2l4LlxuICovXG5jb25zdCBpbWdpeExvYWRlckluZm8gPSB7XG4gIG5hbWU6ICdJbWdpeCcsXG4gIHRlc3RVcmw6IGlzSW1naXhVcmxcbn07XG5jb25zdCBJTUdJWF9MT0FERVJfUkVHRVggPSAvaHR0cHM/XFw6XFwvXFwvW15cXC9dK1xcLmltZ2l4XFwubmV0XFwvLisvO1xuLyoqXG4gKiBUZXN0cyB3aGV0aGVyIGEgVVJMIGlzIGZyb20gSW1naXggQ0ROLlxuICovXG5mdW5jdGlvbiBpc0ltZ2l4VXJsKHVybCkge1xuICByZXR1cm4gSU1HSVhfTE9BREVSX1JFR0VYLnRlc3QodXJsKTtcbn1cbi8qKlxuICogRnVuY3Rpb24gdGhhdCBnZW5lcmF0ZXMgYW4gSW1hZ2VMb2FkZXIgZm9yIEltZ2l4IGFuZCB0dXJucyBpdCBpbnRvIGFuIEFuZ3VsYXIgcHJvdmlkZXIuXG4gKlxuICogQHBhcmFtIHBhdGggcGF0aCB0byB0aGUgZGVzaXJlZCBJbWdpeCBvcmlnaW4sXG4gKiBlLmcuIGh0dHBzOi8vc29tZXBhdGguaW1naXgubmV0IG9yIGh0dHBzOi8vaW1hZ2VzLm15c2l0ZS5jb21cbiAqIEByZXR1cm5zIFNldCBvZiBwcm92aWRlcnMgdG8gY29uZmlndXJlIHRoZSBJbWdpeCBsb2FkZXIuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jb25zdCBwcm92aWRlSW1naXhMb2FkZXIgPSBjcmVhdGVJbWFnZUxvYWRlcihjcmVhdGVJbWdpeFVybCwgbmdEZXZNb2RlID8gWydodHRwczovL3NvbWVwYXRoLmltZ2l4Lm5ldC8nXSA6IHVuZGVmaW5lZCk7XG5mdW5jdGlvbiBjcmVhdGVJbWdpeFVybChwYXRoLCBjb25maWcpIHtcbiAgY29uc3QgdXJsID0gbmV3IFVSTChgJHtwYXRofS8ke2NvbmZpZy5zcmN9YCk7XG4gIC8vIFRoaXMgc2V0dGluZyBlbnN1cmVzIHRoZSBzbWFsbGVzdCBhbGxvd2FibGUgZm9ybWF0IGlzIHNldC5cbiAgdXJsLnNlYXJjaFBhcmFtcy5zZXQoJ2F1dG8nLCAnZm9ybWF0Jyk7XG4gIGlmIChjb25maWcud2lkdGgpIHtcbiAgICB1cmwuc2VhcmNoUGFyYW1zLnNldCgndycsIGNvbmZpZy53aWR0aC50b1N0cmluZygpKTtcbiAgfVxuICAvLyBXaGVuIHJlcXVlc3RpbmcgYSBwbGFjZWhvbGRlciBpbWFnZSB3ZSBhc2sgYSBsb3cgcXVhbGl0eSBpbWFnZSB0byByZWR1Y2UgdGhlIGxvYWQgdGltZS5cbiAgaWYgKGNvbmZpZy5pc1BsYWNlaG9sZGVyKSB7XG4gICAgdXJsLnNlYXJjaFBhcmFtcy5zZXQoJ3EnLCBQTEFDRUhPTERFUl9RVUFMSVRZKTtcbiAgfVxuICByZXR1cm4gdXJsLmhyZWY7XG59XG5cbi8qKlxuICogTmFtZSBhbmQgVVJMIHRlc3RlciBmb3IgTmV0bGlmeS5cbiAqL1xuY29uc3QgbmV0bGlmeUxvYWRlckluZm8gPSB7XG4gIG5hbWU6ICdOZXRsaWZ5JyxcbiAgdGVzdFVybDogaXNOZXRsaWZ5VXJsXG59O1xuY29uc3QgTkVUTElGWV9MT0FERVJfUkVHRVggPSAvaHR0cHM/XFw6XFwvXFwvW15cXC9dK1xcLm5ldGxpZnlcXC5hcHBcXC8uKy87XG4vKipcbiAqIFRlc3RzIHdoZXRoZXIgYSBVUkwgaXMgZnJvbSBhIE5ldGxpZnkgc2l0ZS4gVGhpcyB3b24ndCBjYXRjaCBzaXRlcyB3aXRoIGEgY3VzdG9tIGRvbWFpbixcbiAqIGJ1dCBpdCdzIGEgZ29vZCBzdGFydCBmb3Igc2l0ZXMgaW4gZGV2ZWxvcG1lbnQuIFRoaXMgaXMgb25seSB1c2VkIHRvIHdhcm4gdXNlcnMgd2hvIGhhdmVuJ3RcbiAqIGNvbmZpZ3VyZWQgYW4gaW1hZ2UgbG9hZGVyLlxuICovXG5mdW5jdGlvbiBpc05ldGxpZnlVcmwodXJsKSB7XG4gIHJldHVybiBORVRMSUZZX0xPQURFUl9SRUdFWC50ZXN0KHVybCk7XG59XG4vKipcbiAqIEZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIGFuIEltYWdlTG9hZGVyIGZvciBOZXRsaWZ5IGFuZCB0dXJucyBpdCBpbnRvIGFuIEFuZ3VsYXIgcHJvdmlkZXIuXG4gKlxuICogQHBhcmFtIHBhdGggb3B0aW9uYWwgVVJMIG9mIHRoZSBkZXNpcmVkIE5ldGxpZnkgc2l0ZS4gRGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgc2l0ZS5cbiAqIEByZXR1cm5zIFNldCBvZiBwcm92aWRlcnMgdG8gY29uZmlndXJlIHRoZSBOZXRsaWZ5IGxvYWRlci5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmZ1bmN0aW9uIHByb3ZpZGVOZXRsaWZ5TG9hZGVyKHBhdGgpIHtcbiAgaWYgKHBhdGggJiYgIWlzVmFsaWRQYXRoKHBhdGgpKSB7XG4gICAgdGhyb3cgbmV3IMm1UnVudGltZUVycm9yKDI5NTkgLyogUnVudGltZUVycm9yQ29kZS5JTlZBTElEX0xPQURFUl9BUkdVTUVOVFMgKi8sIG5nRGV2TW9kZSAmJiBgSW1hZ2UgbG9hZGVyIGhhcyBkZXRlY3RlZCBhbiBpbnZhbGlkIHBhdGggKFxcYCR7cGF0aH1cXGApLiBgICsgYFRvIGZpeCB0aGlzLCBzdXBwbHkgZWl0aGVyIHRoZSBmdWxsIFVSTCB0byB0aGUgTmV0bGlmeSBzaXRlLCBvciBsZWF2ZSBpdCBlbXB0eSB0byB1c2UgdGhlIGN1cnJlbnQgc2l0ZS5gKTtcbiAgfVxuICBpZiAocGF0aCkge1xuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwocGF0aCk7XG4gICAgcGF0aCA9IHVybC5vcmlnaW47XG4gIH1cbiAgY29uc3QgbG9hZGVyRm4gPSBjb25maWcgPT4ge1xuICAgIHJldHVybiBjcmVhdGVOZXRsaWZ5VXJsKGNvbmZpZywgcGF0aCk7XG4gIH07XG4gIGNvbnN0IHByb3ZpZGVycyA9IFt7XG4gICAgcHJvdmlkZTogSU1BR0VfTE9BREVSLFxuICAgIHVzZVZhbHVlOiBsb2FkZXJGblxuICB9XTtcbiAgcmV0dXJuIHByb3ZpZGVycztcbn1cbmNvbnN0IHZhbGlkUGFyYW1zID0gbmV3IE1hcChbWydoZWlnaHQnLCAnaCddLCBbJ2ZpdCcsICdmaXQnXSwgWydxdWFsaXR5JywgJ3EnXSwgWydxJywgJ3EnXSwgWydwb3NpdGlvbicsICdwb3NpdGlvbiddXSk7XG5mdW5jdGlvbiBjcmVhdGVOZXRsaWZ5VXJsKGNvbmZpZywgcGF0aCkge1xuICAvLyBOb3RlOiBgcGF0aGAgY2FuIGJlIHVuZGVmaW5lZCwgaW4gd2hpY2ggY2FzZSB3ZSB1c2UgYSBmYWtlIG9uZSB0byBjb25zdHJ1Y3QgYSBgVVJMYCBpbnN0YW5jZS5cbiAgY29uc3QgdXJsID0gbmV3IFVSTChwYXRoID8/ICdodHRwczovL2EvJyk7XG4gIHVybC5wYXRobmFtZSA9ICcvLm5ldGxpZnkvaW1hZ2VzJztcbiAgaWYgKCFpc0Fic29sdXRlVXJsKGNvbmZpZy5zcmMpICYmICFjb25maWcuc3JjLnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgIGNvbmZpZy5zcmMgPSAnLycgKyBjb25maWcuc3JjO1xuICB9XG4gIHVybC5zZWFyY2hQYXJhbXMuc2V0KCd1cmwnLCBjb25maWcuc3JjKTtcbiAgaWYgKGNvbmZpZy53aWR0aCkge1xuICAgIHVybC5zZWFyY2hQYXJhbXMuc2V0KCd3JywgY29uZmlnLndpZHRoLnRvU3RyaW5nKCkpO1xuICB9XG4gIC8vIFdoZW4gcmVxdWVzdGluZyBhIHBsYWNlaG9sZGVyIGltYWdlIHdlIGFzayBmb3IgYSBsb3cgcXVhbGl0eSBpbWFnZSB0byByZWR1Y2UgdGhlIGxvYWQgdGltZS5cbiAgLy8gSWYgdGhlIHF1YWxpdHkgaXMgc3BlY2lmaWVkIGluIHRoZSBsb2FkZXIgY29uZmlnIC0gYWx3YXlzIHVzZSBwcm92aWRlZCB2YWx1ZS5cbiAgY29uc3QgY29uZmlnUXVhbGl0eSA9IGNvbmZpZy5sb2FkZXJQYXJhbXM/LlsncXVhbGl0eSddID8/IGNvbmZpZy5sb2FkZXJQYXJhbXM/LlsncSddO1xuICBpZiAoY29uZmlnLmlzUGxhY2Vob2xkZXIgJiYgIWNvbmZpZ1F1YWxpdHkpIHtcbiAgICB1cmwuc2VhcmNoUGFyYW1zLnNldCgncScsIFBMQUNFSE9MREVSX1FVQUxJVFkpO1xuICB9XG4gIGZvciAoY29uc3QgW3BhcmFtLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoY29uZmlnLmxvYWRlclBhcmFtcyA/PyB7fSkpIHtcbiAgICBpZiAodmFsaWRQYXJhbXMuaGFzKHBhcmFtKSkge1xuICAgICAgdXJsLnNlYXJjaFBhcmFtcy5zZXQodmFsaWRQYXJhbXMuZ2V0KHBhcmFtKSwgdmFsdWUudG9TdHJpbmcoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChuZ0Rldk1vZGUpIHtcbiAgICAgICAgY29uc29sZS53YXJuKMm1Zm9ybWF0UnVudGltZUVycm9yKDI5NTkgLyogUnVudGltZUVycm9yQ29kZS5JTlZBTElEX0xPQURFUl9BUkdVTUVOVFMgKi8sIGBUaGUgTmV0bGlmeSBpbWFnZSBsb2FkZXIgaGFzIGRldGVjdGVkIGFuIFxcYDxpbWc+XFxgIHRhZyB3aXRoIHRoZSB1bnN1cHBvcnRlZCBhdHRyaWJ1dGUgXCJcXGAke3BhcmFtfVxcYFwiLmApKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLy8gVGhlIFwiYVwiIGhvc3RuYW1lIGlzIHVzZWQgZm9yIHJlbGF0aXZlIFVSTHMsIHNvIHdlIGNhbiByZW1vdmUgaXQgZnJvbSB0aGUgZmluYWwgVVJMLlxuICByZXR1cm4gdXJsLmhvc3RuYW1lID09PSAnYScgPyB1cmwuaHJlZi5yZXBsYWNlKHVybC5vcmlnaW4sICcnKSA6IHVybC5ocmVmO1xufVxuXG4vLyBBc3NlbWJsZXMgZGlyZWN0aXZlIGRldGFpbHMgc3RyaW5nLCB1c2VmdWwgZm9yIGVycm9yIG1lc3NhZ2VzLlxuZnVuY3Rpb24gaW1nRGlyZWN0aXZlRGV0YWlscyhuZ1NyYywgaW5jbHVkZU5nU3JjID0gdHJ1ZSkge1xuICBjb25zdCBuZ1NyY0luZm8gPSBpbmNsdWRlTmdTcmMgPyBgKGFjdGl2YXRlZCBvbiBhbiA8aW1nPiBlbGVtZW50IHdpdGggdGhlIFxcYG5nU3JjPVwiJHtuZ1NyY31cIlxcYCkgYCA6ICcnO1xuICByZXR1cm4gYFRoZSBOZ09wdGltaXplZEltYWdlIGRpcmVjdGl2ZSAke25nU3JjSW5mb31oYXMgZGV0ZWN0ZWQgdGhhdGA7XG59XG5cbi8qKlxuICogQXNzZXJ0cyB0aGF0IHRoZSBhcHBsaWNhdGlvbiBpcyBpbiBkZXZlbG9wbWVudCBtb2RlLiBUaHJvd3MgYW4gZXJyb3IgaWYgdGhlIGFwcGxpY2F0aW9uIGlzIGluXG4gKiBwcm9kdWN0aW9uIG1vZGUuIFRoaXMgYXNzZXJ0IGNhbiBiZSB1c2VkIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZXJlIGlzIG5vIGRldi1tb2RlIGNvZGUgaW52b2tlZCBpblxuICogdGhlIHByb2QgbW9kZSBhY2NpZGVudGFsbHkuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydERldk1vZGUoY2hlY2tOYW1lKSB7XG4gIGlmICghbmdEZXZNb2RlKSB7XG4gICAgdGhyb3cgbmV3IMm1UnVudGltZUVycm9yKDI5NTggLyogUnVudGltZUVycm9yQ29kZS5VTkVYUEVDVEVEX0RFVl9NT0RFX0NIRUNLX0lOX1BST0RfTU9ERSAqLywgYFVuZXhwZWN0ZWQgaW52b2NhdGlvbiBvZiB0aGUgJHtjaGVja05hbWV9IGluIHRoZSBwcm9kIG1vZGUuIGAgKyBgUGxlYXNlIG1ha2Ugc3VyZSB0aGF0IHRoZSBwcm9kIG1vZGUgaXMgZW5hYmxlZCBmb3IgcHJvZHVjdGlvbiBidWlsZHMuYCk7XG4gIH1cbn1cblxuLyoqXG4gKiBPYnNlcnZlciB0aGF0IGRldGVjdHMgd2hldGhlciBhbiBpbWFnZSB3aXRoIGBOZ09wdGltaXplZEltYWdlYFxuICogaXMgdHJlYXRlZCBhcyBhIExhcmdlc3QgQ29udGVudGZ1bCBQYWludCAoTENQKSBlbGVtZW50LiBJZiBzbyxcbiAqIGFzc2VydHMgdGhhdCB0aGUgaW1hZ2UgaGFzIHRoZSBgcHJpb3JpdHlgIGF0dHJpYnV0ZS5cbiAqXG4gKiBOb3RlOiB0aGlzIGlzIGEgZGV2LW1vZGUgb25seSBjbGFzcyBhbmQgaXQgZG9lcyBub3QgYXBwZWFyIGluIHByb2QgYnVuZGxlcyxcbiAqIHRodXMgdGhlcmUgaXMgbm8gYG5nRGV2TW9kZWAgdXNlIGluIHRoZSBjb2RlLlxuICpcbiAqIEJhc2VkIG9uIGh0dHBzOi8vd2ViLmRldi9sY3AvI21lYXN1cmUtbGNwLWluLWphdmFzY3JpcHQuXG4gKi9cbmNsYXNzIExDUEltYWdlT2JzZXJ2ZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBNYXAgb2YgZnVsbCBpbWFnZSBVUkxzIC0+IG9yaWdpbmFsIGBuZ1NyY2AgdmFsdWVzLlxuICAgIHRoaXMuaW1hZ2VzID0gbmV3IE1hcCgpO1xuICAgIHRoaXMud2luZG93ID0gbnVsbDtcbiAgICB0aGlzLm9ic2VydmVyID0gbnVsbDtcbiAgICBhc3NlcnREZXZNb2RlKCdMQ1AgY2hlY2tlcicpO1xuICAgIGNvbnN0IHdpbiA9IGluamVjdChET0NVTUVOVCkuZGVmYXVsdFZpZXc7XG4gICAgaWYgKHR5cGVvZiB3aW4gIT09ICd1bmRlZmluZWQnICYmIHR5cGVvZiBQZXJmb3JtYW5jZU9ic2VydmVyICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy53aW5kb3cgPSB3aW47XG4gICAgICB0aGlzLm9ic2VydmVyID0gdGhpcy5pbml0UGVyZm9ybWFuY2VPYnNlcnZlcigpO1xuICAgIH1cbiAgfVxuICAvKipcbiAgICogSW5pdHMgUGVyZm9ybWFuY2VPYnNlcnZlciBhbmQgc3Vic2NyaWJlcyB0byBMQ1AgZXZlbnRzLlxuICAgKiBCYXNlZCBvbiBodHRwczovL3dlYi5kZXYvbGNwLyNtZWFzdXJlLWxjcC1pbi1qYXZhc2NyaXB0XG4gICAqL1xuICBpbml0UGVyZm9ybWFuY2VPYnNlcnZlcigpIHtcbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBQZXJmb3JtYW5jZU9ic2VydmVyKGVudHJ5TGlzdCA9PiB7XG4gICAgICBjb25zdCBlbnRyaWVzID0gZW50cnlMaXN0LmdldEVudHJpZXMoKTtcbiAgICAgIGlmIChlbnRyaWVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuICAgICAgLy8gV2UgdXNlIHRoZSBsYXRlc3QgZW50cnkgcHJvZHVjZWQgYnkgdGhlIGBQZXJmb3JtYW5jZU9ic2VydmVyYCBhcyB0aGUgYmVzdFxuICAgICAgLy8gc2lnbmFsIG9uIHdoaWNoIGVsZW1lbnQgaXMgYWN0dWFsbHkgYW4gTENQIG9uZS4gQXMgYW4gZXhhbXBsZSwgdGhlIGZpcnN0IGltYWdlIHRvIGxvYWQgb25cbiAgICAgIC8vIGEgcGFnZSwgYnkgdmlydHVlIG9mIGJlaW5nIHRoZSBvbmx5IHRoaW5nIG9uIHRoZSBwYWdlIHNvIGZhciwgaXMgb2Z0ZW4gYSBMQ1AgY2FuZGlkYXRlXG4gICAgICAvLyBhbmQgZ2V0cyByZXBvcnRlZCBieSBQZXJmb3JtYW5jZU9ic2VydmVyLCBidXQgaXNuJ3QgbmVjZXNzYXJpbHkgdGhlIExDUCBlbGVtZW50LlxuICAgICAgY29uc3QgbGNwRWxlbWVudCA9IGVudHJpZXNbZW50cmllcy5sZW5ndGggLSAxXTtcbiAgICAgIC8vIENhc3QgdG8gYGFueWAgZHVlIHRvIG1pc3NpbmcgYGVsZW1lbnRgIG9uIHRoZSBgTGFyZ2VzdENvbnRlbnRmdWxQYWludGAgdHlwZSBvZiBlbnRyeS5cbiAgICAgIC8vIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvTGFyZ2VzdENvbnRlbnRmdWxQYWludFxuICAgICAgY29uc3QgaW1nU3JjID0gbGNwRWxlbWVudC5lbGVtZW50Py5zcmMgPz8gJyc7XG4gICAgICAvLyBFeGNsdWRlIGBkYXRhOmAgYW5kIGBibG9iOmAgVVJMcywgc2luY2UgdGhleSBhcmUgbm90IHN1cHBvcnRlZCBieSB0aGUgZGlyZWN0aXZlLlxuICAgICAgaWYgKGltZ1NyYy5zdGFydHNXaXRoKCdkYXRhOicpIHx8IGltZ1NyYy5zdGFydHNXaXRoKCdibG9iOicpKSByZXR1cm47XG4gICAgICBjb25zdCBpbWcgPSB0aGlzLmltYWdlcy5nZXQoaW1nU3JjKTtcbiAgICAgIGlmICghaW1nKSByZXR1cm47XG4gICAgICBpZiAoIWltZy5wcmlvcml0eSAmJiAhaW1nLmFscmVhZHlXYXJuZWRQcmlvcml0eSkge1xuICAgICAgICBpbWcuYWxyZWFkeVdhcm5lZFByaW9yaXR5ID0gdHJ1ZTtcbiAgICAgICAgbG9nTWlzc2luZ1ByaW9yaXR5RXJyb3IoaW1nU3JjKTtcbiAgICAgIH1cbiAgICAgIGlmIChpbWcubW9kaWZpZWQgJiYgIWltZy5hbHJlYWR5V2FybmVkTW9kaWZpZWQpIHtcbiAgICAgICAgaW1nLmFscmVhZHlXYXJuZWRNb2RpZmllZCA9IHRydWU7XG4gICAgICAgIGxvZ01vZGlmaWVkV2FybmluZyhpbWdTcmMpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIG9ic2VydmVyLm9ic2VydmUoe1xuICAgICAgdHlwZTogJ2xhcmdlc3QtY29udGVudGZ1bC1wYWludCcsXG4gICAgICBidWZmZXJlZDogdHJ1ZVxuICAgIH0pO1xuICAgIHJldHVybiBvYnNlcnZlcjtcbiAgfVxuICByZWdpc3RlckltYWdlKHJld3JpdHRlblNyYywgb3JpZ2luYWxOZ1NyYywgaXNQcmlvcml0eSkge1xuICAgIGlmICghdGhpcy5vYnNlcnZlcikgcmV0dXJuO1xuICAgIGNvbnN0IG5ld09ic2VydmVkSW1hZ2VTdGF0ZSA9IHtcbiAgICAgIHByaW9yaXR5OiBpc1ByaW9yaXR5LFxuICAgICAgbW9kaWZpZWQ6IGZhbHNlLFxuICAgICAgYWxyZWFkeVdhcm5lZE1vZGlmaWVkOiBmYWxzZSxcbiAgICAgIGFscmVhZHlXYXJuZWRQcmlvcml0eTogZmFsc2VcbiAgICB9O1xuICAgIHRoaXMuaW1hZ2VzLnNldChnZXRVcmwocmV3cml0dGVuU3JjLCB0aGlzLndpbmRvdykuaHJlZiwgbmV3T2JzZXJ2ZWRJbWFnZVN0YXRlKTtcbiAgfVxuICB1bnJlZ2lzdGVySW1hZ2UocmV3cml0dGVuU3JjKSB7XG4gICAgaWYgKCF0aGlzLm9ic2VydmVyKSByZXR1cm47XG4gICAgdGhpcy5pbWFnZXMuZGVsZXRlKGdldFVybChyZXdyaXR0ZW5TcmMsIHRoaXMud2luZG93KS5ocmVmKTtcbiAgfVxuICB1cGRhdGVJbWFnZShvcmlnaW5hbFNyYywgbmV3U3JjKSB7XG4gICAgY29uc3Qgb3JpZ2luYWxVcmwgPSBnZXRVcmwob3JpZ2luYWxTcmMsIHRoaXMud2luZG93KS5ocmVmO1xuICAgIGNvbnN0IGltZyA9IHRoaXMuaW1hZ2VzLmdldChvcmlnaW5hbFVybCk7XG4gICAgaWYgKGltZykge1xuICAgICAgaW1nLm1vZGlmaWVkID0gdHJ1ZTtcbiAgICAgIHRoaXMuaW1hZ2VzLnNldChnZXRVcmwobmV3U3JjLCB0aGlzLndpbmRvdykuaHJlZiwgaW1nKTtcbiAgICAgIHRoaXMuaW1hZ2VzLmRlbGV0ZShvcmlnaW5hbFVybCk7XG4gICAgfVxuICB9XG4gIG5nT25EZXN0cm95KCkge1xuICAgIGlmICghdGhpcy5vYnNlcnZlcikgcmV0dXJuO1xuICAgIHRoaXMub2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuICAgIHRoaXMuaW1hZ2VzLmNsZWFyKCk7XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gTENQSW1hZ2VPYnNlcnZlcl9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgTENQSW1hZ2VPYnNlcnZlcikoKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXByb3YgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lSW5qZWN0YWJsZSh7XG4gICAgICB0b2tlbjogTENQSW1hZ2VPYnNlcnZlcixcbiAgICAgIGZhY3Rvcnk6IExDUEltYWdlT2JzZXJ2ZXIuybVmYWMsXG4gICAgICBwcm92aWRlZEluOiAncm9vdCdcbiAgICB9KTtcbiAgfVxufVxuKCgpID0+IHtcbiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09IFwidW5kZWZpbmVkXCIgfHwgbmdEZXZNb2RlKSAmJiBpMC7JtXNldENsYXNzTWV0YWRhdGEoTENQSW1hZ2VPYnNlcnZlciwgW3tcbiAgICB0eXBlOiBJbmplY3RhYmxlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBwcm92aWRlZEluOiAncm9vdCdcbiAgICB9XVxuICB9XSwgKCkgPT4gW10sIG51bGwpO1xufSkoKTtcbmZ1bmN0aW9uIGxvZ01pc3NpbmdQcmlvcml0eUVycm9yKG5nU3JjKSB7XG4gIGNvbnN0IGRpcmVjdGl2ZURldGFpbHMgPSBpbWdEaXJlY3RpdmVEZXRhaWxzKG5nU3JjKTtcbiAgY29uc29sZS5lcnJvcijJtWZvcm1hdFJ1bnRpbWVFcnJvcigyOTU1IC8qIFJ1bnRpbWVFcnJvckNvZGUuTENQX0lNR19NSVNTSU5HX1BSSU9SSVRZICovLCBgJHtkaXJlY3RpdmVEZXRhaWxzfSB0aGlzIGltYWdlIGlzIHRoZSBMYXJnZXN0IENvbnRlbnRmdWwgUGFpbnQgKExDUCkgYCArIGBlbGVtZW50IGJ1dCB3YXMgbm90IG1hcmtlZCBcInByaW9yaXR5XCIuIFRoaXMgaW1hZ2Ugc2hvdWxkIGJlIG1hcmtlZCBgICsgYFwicHJpb3JpdHlcIiBpbiBvcmRlciB0byBwcmlvcml0aXplIGl0cyBsb2FkaW5nLiBgICsgYFRvIGZpeCB0aGlzLCBhZGQgdGhlIFwicHJpb3JpdHlcIiBhdHRyaWJ1dGUuYCkpO1xufVxuZnVuY3Rpb24gbG9nTW9kaWZpZWRXYXJuaW5nKG5nU3JjKSB7XG4gIGNvbnN0IGRpcmVjdGl2ZURldGFpbHMgPSBpbWdEaXJlY3RpdmVEZXRhaWxzKG5nU3JjKTtcbiAgY29uc29sZS53YXJuKMm1Zm9ybWF0UnVudGltZUVycm9yKDI5NjQgLyogUnVudGltZUVycm9yQ29kZS5MQ1BfSU1HX05HU1JDX01PRElGSUVEICovLCBgJHtkaXJlY3RpdmVEZXRhaWxzfSB0aGlzIGltYWdlIGlzIHRoZSBMYXJnZXN0IENvbnRlbnRmdWwgUGFpbnQgKExDUCkgYCArIGBlbGVtZW50IGFuZCBoYXMgaGFkIGl0cyBcIm5nU3JjXCIgYXR0cmlidXRlIG1vZGlmaWVkLiBUaGlzIGNhbiBjYXVzZSBgICsgYHNsb3dlciBsb2FkaW5nIHBlcmZvcm1hbmNlLiBJdCBpcyByZWNvbW1lbmRlZCBub3QgdG8gbW9kaWZ5IHRoZSBcIm5nU3JjXCIgYCArIGBwcm9wZXJ0eSBvbiBhbnkgaW1hZ2Ugd2hpY2ggY291bGQgYmUgdGhlIExDUCBlbGVtZW50LmApKTtcbn1cblxuLy8gU2V0IG9mIG9yaWdpbnMgdGhhdCBhcmUgYWx3YXlzIGV4Y2x1ZGVkIGZyb20gdGhlIHByZWNvbm5lY3QgY2hlY2tzLlxuY29uc3QgSU5URVJOQUxfUFJFQ09OTkVDVF9DSEVDS19CTE9DS0xJU1QgPSBuZXcgU2V0KFsnbG9jYWxob3N0JywgJzEyNy4wLjAuMScsICcwLjAuMC4wJ10pO1xuLyoqXG4gKiBJbmplY3Rpb24gdG9rZW4gdG8gY29uZmlndXJlIHdoaWNoIG9yaWdpbnMgc2hvdWxkIGJlIGV4Y2x1ZGVkXG4gKiBmcm9tIHRoZSBwcmVjb25uZWN0IGNoZWNrcy4gSXQgY2FuIGVpdGhlciBiZSBhIHNpbmdsZSBzdHJpbmcgb3IgYW4gYXJyYXkgb2Ygc3RyaW5nc1xuICogdG8gcmVwcmVzZW50IGEgZ3JvdXAgb2Ygb3JpZ2lucywgZm9yIGV4YW1wbGU6XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogIHtwcm92aWRlOiBQUkVDT05ORUNUX0NIRUNLX0JMT0NLTElTVCwgdXNlVmFsdWU6ICdodHRwczovL3lvdXItZG9tYWluLmNvbSd9XG4gKiBgYGBcbiAqXG4gKiBvcjpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAge3Byb3ZpZGU6IFBSRUNPTk5FQ1RfQ0hFQ0tfQkxPQ0tMSVNULFxuICogICB1c2VWYWx1ZTogWydodHRwczovL3lvdXItZG9tYWluLTEuY29tJywgJ2h0dHBzOi8veW91ci1kb21haW4tMi5jb20nXX1cbiAqIGBgYFxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY29uc3QgUFJFQ09OTkVDVF9DSEVDS19CTE9DS0xJU1QgPSBuZXcgSW5qZWN0aW9uVG9rZW4obmdEZXZNb2RlID8gJ1BSRUNPTk5FQ1RfQ0hFQ0tfQkxPQ0tMSVNUJyA6ICcnKTtcbi8qKlxuICogQ29udGFpbnMgdGhlIGxvZ2ljIHRvIGRldGVjdCB3aGV0aGVyIGFuIGltYWdlLCBtYXJrZWQgd2l0aCB0aGUgXCJwcmlvcml0eVwiIGF0dHJpYnV0ZVxuICogaGFzIGEgY29ycmVzcG9uZGluZyBgPGxpbmsgcmVsPVwicHJlY29ubmVjdFwiPmAgdGFnIGluIHRoZSBgZG9jdW1lbnQuaGVhZGAuXG4gKlxuICogTm90ZTogdGhpcyBpcyBhIGRldi1tb2RlIG9ubHkgY2xhc3MsIHdoaWNoIHNob3VsZCBub3QgYXBwZWFyIGluIHByb2QgYnVuZGxlcyxcbiAqIHRodXMgdGhlcmUgaXMgbm8gYG5nRGV2TW9kZWAgdXNlIGluIHRoZSBjb2RlLlxuICovXG5jbGFzcyBQcmVjb25uZWN0TGlua0NoZWNrZXIge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmRvY3VtZW50ID0gaW5qZWN0KERPQ1VNRU5UKTtcbiAgICAvKipcbiAgICAgKiBTZXQgb2YgPGxpbmsgcmVsPVwicHJlY29ubmVjdFwiPiB0YWdzIGZvdW5kIG9uIHRoaXMgcGFnZS5cbiAgICAgKiBUaGUgYG51bGxgIHZhbHVlIGluZGljYXRlcyB0aGF0IHRoZXJlIHdhcyBubyBET00gcXVlcnkgb3BlcmF0aW9uIHBlcmZvcm1lZC5cbiAgICAgKi9cbiAgICB0aGlzLnByZWNvbm5lY3RMaW5rcyA9IG51bGw7XG4gICAgLypcbiAgICAgKiBLZWVwIHRyYWNrIG9mIGFsbCBhbHJlYWR5IHNlZW4gb3JpZ2luIFVSTHMgdG8gYXZvaWQgcmVwZWF0aW5nIHRoZSBzYW1lIGNoZWNrLlxuICAgICAqL1xuICAgIHRoaXMuYWxyZWFkeVNlZW4gPSBuZXcgU2V0KCk7XG4gICAgdGhpcy53aW5kb3cgPSBudWxsO1xuICAgIHRoaXMuYmxvY2tsaXN0ID0gbmV3IFNldChJTlRFUk5BTF9QUkVDT05ORUNUX0NIRUNLX0JMT0NLTElTVCk7XG4gICAgYXNzZXJ0RGV2TW9kZSgncHJlY29ubmVjdCBsaW5rIGNoZWNrZXInKTtcbiAgICBjb25zdCB3aW4gPSB0aGlzLmRvY3VtZW50LmRlZmF1bHRWaWV3O1xuICAgIGlmICh0eXBlb2Ygd2luICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy53aW5kb3cgPSB3aW47XG4gICAgfVxuICAgIGNvbnN0IGJsb2NrbGlzdCA9IGluamVjdChQUkVDT05ORUNUX0NIRUNLX0JMT0NLTElTVCwge1xuICAgICAgb3B0aW9uYWw6IHRydWVcbiAgICB9KTtcbiAgICBpZiAoYmxvY2tsaXN0KSB7XG4gICAgICB0aGlzLnBvcHVsYXRlQmxvY2tsaXN0KGJsb2NrbGlzdCk7XG4gICAgfVxuICB9XG4gIHBvcHVsYXRlQmxvY2tsaXN0KG9yaWdpbnMpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcmlnaW5zKSkge1xuICAgICAgZGVlcEZvckVhY2gob3JpZ2lucywgb3JpZ2luID0+IHtcbiAgICAgICAgdGhpcy5ibG9ja2xpc3QuYWRkKGV4dHJhY3RIb3N0bmFtZShvcmlnaW4pKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmJsb2NrbGlzdC5hZGQoZXh0cmFjdEhvc3RuYW1lKG9yaWdpbnMpKTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrcyB0aGF0IGEgcHJlY29ubmVjdCByZXNvdXJjZSBoaW50IGV4aXN0cyBpbiB0aGUgaGVhZCBmb3IgdGhlXG4gICAqIGdpdmVuIHNyYy5cbiAgICpcbiAgICogQHBhcmFtIHJld3JpdHRlblNyYyBzcmMgZm9ybWF0dGVkIHdpdGggbG9hZGVyXG4gICAqIEBwYXJhbSBvcmlnaW5hbE5nU3JjIG5nU3JjIHZhbHVlXG4gICAqL1xuICBhc3NlcnRQcmVjb25uZWN0KHJld3JpdHRlblNyYywgb3JpZ2luYWxOZ1NyYykge1xuICAgIGlmICghdGhpcy53aW5kb3cpIHJldHVybjtcbiAgICBjb25zdCBpbWdVcmwgPSBnZXRVcmwocmV3cml0dGVuU3JjLCB0aGlzLndpbmRvdyk7XG4gICAgaWYgKHRoaXMuYmxvY2tsaXN0LmhhcyhpbWdVcmwuaG9zdG5hbWUpIHx8IHRoaXMuYWxyZWFkeVNlZW4uaGFzKGltZ1VybC5vcmlnaW4pKSByZXR1cm47XG4gICAgLy8gUmVnaXN0ZXIgdGhpcyBvcmlnaW4gYXMgc2Vlbiwgc28gd2UgZG9uJ3QgY2hlY2sgaXQgYWdhaW4gbGF0ZXIuXG4gICAgdGhpcy5hbHJlYWR5U2Vlbi5hZGQoaW1nVXJsLm9yaWdpbik7XG4gICAgLy8gTm90ZTogd2UgcXVlcnkgZm9yIHByZWNvbm5lY3QgbGlua3Mgb25seSAqb25jZSogYW5kIGNhY2hlIHRoZSByZXN1bHRzXG4gICAgLy8gZm9yIHRoZSBlbnRpcmUgbGlmZXNwYW4gb2YgYW4gYXBwbGljYXRpb24sIHNpbmNlIGl0J3MgdW5saWtlbHkgdGhhdCB0aGVcbiAgICAvLyBsaXN0IHdvdWxkIGNoYW5nZSBmcmVxdWVudGx5LiBUaGlzIGFsbG93cyB0byBtYWtlIHN1cmUgdGhlcmUgYXJlIG5vXG4gICAgLy8gcGVyZm9ybWFuY2UgaW1wbGljYXRpb25zIG9mIG1ha2luZyBleHRyYSBET00gbG9va3VwcyBmb3IgZWFjaCBpbWFnZS5cbiAgICB0aGlzLnByZWNvbm5lY3RMaW5rcyA/Pz0gdGhpcy5xdWVyeVByZWNvbm5lY3RMaW5rcygpO1xuICAgIGlmICghdGhpcy5wcmVjb25uZWN0TGlua3MuaGFzKGltZ1VybC5vcmlnaW4pKSB7XG4gICAgICBjb25zb2xlLndhcm4oybVmb3JtYXRSdW50aW1lRXJyb3IoMjk1NiAvKiBSdW50aW1lRXJyb3JDb2RlLlBSSU9SSVRZX0lNR19NSVNTSU5HX1BSRUNPTk5FQ1RfVEFHICovLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKG9yaWdpbmFsTmdTcmMpfSB0aGVyZSBpcyBubyBwcmVjb25uZWN0IHRhZyBwcmVzZW50IGZvciB0aGlzIGAgKyBgaW1hZ2UuIFByZWNvbm5lY3RpbmcgdG8gdGhlIG9yaWdpbihzKSB0aGF0IHNlcnZlIHByaW9yaXR5IGltYWdlcyBlbnN1cmVzIHRoYXQgdGhlc2UgYCArIGBpbWFnZXMgYXJlIGRlbGl2ZXJlZCBhcyBzb29uIGFzIHBvc3NpYmxlLiBUbyBmaXggdGhpcywgcGxlYXNlIGFkZCB0aGUgZm9sbG93aW5nIGAgKyBgZWxlbWVudCBpbnRvIHRoZSA8aGVhZD4gb2YgdGhlIGRvY3VtZW50OlxcbmAgKyBgICA8bGluayByZWw9XCJwcmVjb25uZWN0XCIgaHJlZj1cIiR7aW1nVXJsLm9yaWdpbn1cIj5gKSk7XG4gICAgfVxuICB9XG4gIHF1ZXJ5UHJlY29ubmVjdExpbmtzKCkge1xuICAgIGNvbnN0IHByZWNvbm5lY3RVcmxzID0gbmV3IFNldCgpO1xuICAgIGNvbnN0IHNlbGVjdG9yID0gJ2xpbmtbcmVsPXByZWNvbm5lY3RdJztcbiAgICBjb25zdCBsaW5rcyA9IEFycmF5LmZyb20odGhpcy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKSk7XG4gICAgZm9yIChsZXQgbGluayBvZiBsaW5rcykge1xuICAgICAgY29uc3QgdXJsID0gZ2V0VXJsKGxpbmsuaHJlZiwgdGhpcy53aW5kb3cpO1xuICAgICAgcHJlY29ubmVjdFVybHMuYWRkKHVybC5vcmlnaW4pO1xuICAgIH1cbiAgICByZXR1cm4gcHJlY29ubmVjdFVybHM7XG4gIH1cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5wcmVjb25uZWN0TGlua3M/LmNsZWFyKCk7XG4gICAgdGhpcy5hbHJlYWR5U2Vlbi5jbGVhcigpO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIFByZWNvbm5lY3RMaW5rQ2hlY2tlcl9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgUHJlY29ubmVjdExpbmtDaGVja2VyKSgpO1xuICAgIH07XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1cHJvdiA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVJbmplY3RhYmxlKHtcbiAgICAgIHRva2VuOiBQcmVjb25uZWN0TGlua0NoZWNrZXIsXG4gICAgICBmYWN0b3J5OiBQcmVjb25uZWN0TGlua0NoZWNrZXIuybVmYWMsXG4gICAgICBwcm92aWRlZEluOiAncm9vdCdcbiAgICB9KTtcbiAgfVxufVxuKCgpID0+IHtcbiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09IFwidW5kZWZpbmVkXCIgfHwgbmdEZXZNb2RlKSAmJiBpMC7JtXNldENsYXNzTWV0YWRhdGEoUHJlY29ubmVjdExpbmtDaGVja2VyLCBbe1xuICAgIHR5cGU6IEluamVjdGFibGUsXG4gICAgYXJnczogW3tcbiAgICAgIHByb3ZpZGVkSW46ICdyb290J1xuICAgIH1dXG4gIH1dLCAoKSA9PiBbXSwgbnVsbCk7XG59KSgpO1xuLyoqXG4gKiBJbnZva2VzIGEgY2FsbGJhY2sgZm9yIGVhY2ggZWxlbWVudCBpbiB0aGUgYXJyYXkuIEFsc28gaW52b2tlcyBhIGNhbGxiYWNrXG4gKiByZWN1cnNpdmVseSBmb3IgZWFjaCBuZXN0ZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGRlZXBGb3JFYWNoKGlucHV0LCBmbikge1xuICBmb3IgKGxldCB2YWx1ZSBvZiBpbnB1dCkge1xuICAgIEFycmF5LmlzQXJyYXkodmFsdWUpID8gZGVlcEZvckVhY2godmFsdWUsIGZuKSA6IGZuKHZhbHVlKTtcbiAgfVxufVxuXG4vKipcbiAqIEluIFNTUiBzY2VuYXJpb3MsIGEgcHJlbG9hZCBgPGxpbms+YCBlbGVtZW50IGlzIGdlbmVyYXRlZCBmb3IgcHJpb3JpdHkgaW1hZ2VzLlxuICogSGF2aW5nIGEgbGFyZ2UgbnVtYmVyIG9mIHByZWxvYWQgdGFncyBtYXkgbmVnYXRpdmVseSBhZmZlY3QgdGhlIHBlcmZvcm1hbmNlLFxuICogc28gd2Ugd2FybiBkZXZlbG9wZXJzIChieSB0aHJvd2luZyBhbiBlcnJvcikgaWYgdGhlIG51bWJlciBvZiBwcmVsb2FkZWQgaW1hZ2VzXG4gKiBpcyBhYm92ZSBhIGNlcnRhaW4gdGhyZXNob2xkLiBUaGlzIGNvbnN0IHNwZWNpZmllcyB0aGlzIHRocmVzaG9sZC5cbiAqL1xuY29uc3QgREVGQVVMVF9QUkVMT0FERURfSU1BR0VTX0xJTUlUID0gNTtcbi8qKlxuICogSGVscHMgdG8ga2VlcCB0cmFjayBvZiBwcmlvcml0eSBpbWFnZXMgdGhhdCBhbHJlYWR5IGhhdmUgYSBjb3JyZXNwb25kaW5nXG4gKiBwcmVsb2FkIHRhZyAodG8gYXZvaWQgZ2VuZXJhdGluZyBtdWx0aXBsZSBwcmVsb2FkIHRhZ3Mgd2l0aCB0aGUgc2FtZSBVUkwpLlxuICpcbiAqIFRoaXMgU2V0IHRyYWNrcyB0aGUgb3JpZ2luYWwgc3JjIHBhc3NlZCBpbnRvIHRoZSBgbmdTcmNgIGlucHV0IG5vdCB0aGUgc3JjIGFmdGVyIGl0IGhhcyBiZWVuXG4gKiBydW4gdGhyb3VnaCB0aGUgc3BlY2lmaWVkIGBJTUFHRV9MT0FERVJgLlxuICovXG5jb25zdCBQUkVMT0FERURfSU1BR0VTID0gbmV3IEluamVjdGlvblRva2VuKCdOR19PUFRJTUlaRURfUFJFTE9BREVEX0lNQUdFUycsIHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxuICBmYWN0b3J5OiAoKSA9PiBuZXcgU2V0KClcbn0pO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb250YWlucyB0aGUgbG9naWMgbmVlZGVkIHRvIHRyYWNrIGFuZCBhZGQgcHJlbG9hZCBsaW5rIHRhZ3MgdG8gdGhlIGA8aGVhZD5gIHRhZy4gSXRcbiAqIHdpbGwgYWxzbyB0cmFjayB3aGF0IGltYWdlcyBoYXZlIGFscmVhZHkgaGFkIHByZWxvYWQgbGluayB0YWdzIGFkZGVkIHNvIGFzIHRvIG5vdCBkdXBsaWNhdGUgbGlua1xuICogdGFncy5cbiAqXG4gKiBJbiBkZXYgbW9kZSB0aGlzIHNlcnZpY2Ugd2lsbCB2YWxpZGF0ZSB0aGF0IHRoZSBudW1iZXIgb2YgcHJlbG9hZGVkIGltYWdlcyBkb2VzIG5vdCBleGNlZWQgdGhlXG4gKiBjb25maWd1cmVkIGRlZmF1bHQgcHJlbG9hZGVkIGltYWdlcyBsaW1pdDoge0BsaW5rIERFRkFVTFRfUFJFTE9BREVEX0lNQUdFU19MSU1JVH0uXG4gKi9cbmNsYXNzIFByZWxvYWRMaW5rQ3JlYXRvciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMucHJlbG9hZGVkSW1hZ2VzID0gaW5qZWN0KFBSRUxPQURFRF9JTUFHRVMpO1xuICAgIHRoaXMuZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpO1xuICB9XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQWRkIGEgcHJlbG9hZCBgPGxpbms+YCB0byB0aGUgYDxoZWFkPmAgb2YgdGhlIGBpbmRleC5odG1sYCB0aGF0IGlzIHNlcnZlZCBmcm9tIHRoZVxuICAgKiBzZXJ2ZXIgd2hpbGUgdXNpbmcgQW5ndWxhciBVbml2ZXJzYWwgYW5kIFNTUiB0byBraWNrIG9mZiBpbWFnZSBsb2FkcyBmb3IgaGlnaCBwcmlvcml0eSBpbWFnZXMuXG4gICAqXG4gICAqIFRoZSBgc2l6ZXNgIChwYXNzZWQgaW4gZnJvbSB0aGUgdXNlcikgYW5kIGBzcmNzZXRgIChwYXJzZWQgYW5kIGZvcm1hdHRlZCBmcm9tIGBuZ1NyY3NldGApXG4gICAqIHByb3BlcnRpZXMgdXNlZCB0byBzZXQgdGhlIGNvcnJlc3BvbmRpbmcgYXR0cmlidXRlcywgYGltYWdlc2l6ZXNgIGFuZCBgaW1hZ2VzcmNzZXRgXG4gICAqIHJlc3BlY3RpdmVseSwgb24gdGhlIHByZWxvYWQgYDxsaW5rPmAgdGFnIHNvIHRoYXQgdGhlIGNvcnJlY3RseSBzaXplZCBpbWFnZSBpcyBwcmVsb2FkZWQgZnJvbVxuICAgKiB0aGUgQ0ROLlxuICAgKlxuICAgKiB7QGxpbmsgaHR0cHM6Ly93ZWIuZGV2L3ByZWxvYWQtcmVzcG9uc2l2ZS1pbWFnZXMvI2ltYWdlc3Jjc2V0LWFuZC1pbWFnZXNpemVzfVxuICAgKlxuICAgKiBAcGFyYW0gcmVuZGVyZXIgVGhlIGBSZW5kZXJlcjJgIHBhc3NlZCBpbiBmcm9tIHRoZSBkaXJlY3RpdmVcbiAgICogQHBhcmFtIHNyYyBUaGUgb3JpZ2luYWwgc3JjIG9mIHRoZSBpbWFnZSB0aGF0IGlzIHNldCBvbiB0aGUgYG5nU3JjYCBpbnB1dC5cbiAgICogQHBhcmFtIHNyY3NldCBUaGUgcGFyc2VkIGFuZCBmb3JtYXR0ZWQgc3Jjc2V0IGNyZWF0ZWQgZnJvbSB0aGUgYG5nU3Jjc2V0YCBpbnB1dFxuICAgKiBAcGFyYW0gc2l6ZXMgVGhlIHZhbHVlIG9mIHRoZSBgc2l6ZXNgIGF0dHJpYnV0ZSBwYXNzZWQgaW4gdG8gdGhlIGA8aW1nPmAgdGFnXG4gICAqL1xuICBjcmVhdGVQcmVsb2FkTGlua1RhZyhyZW5kZXJlciwgc3JjLCBzcmNzZXQsIHNpemVzKSB7XG4gICAgaWYgKG5nRGV2TW9kZSkge1xuICAgICAgaWYgKHRoaXMucHJlbG9hZGVkSW1hZ2VzLnNpemUgPj0gREVGQVVMVF9QUkVMT0FERURfSU1BR0VTX0xJTUlUKSB7XG4gICAgICAgIHRocm93IG5ldyDJtVJ1bnRpbWVFcnJvcigyOTYxIC8qIFJ1bnRpbWVFcnJvckNvZGUuVE9PX01BTllfUFJFTE9BREVEX0lNQUdFUyAqLywgbmdEZXZNb2RlICYmIGBUaGUgXFxgTmdPcHRpbWl6ZWRJbWFnZVxcYCBkaXJlY3RpdmUgaGFzIGRldGVjdGVkIHRoYXQgbW9yZSB0aGFuIGAgKyBgJHtERUZBVUxUX1BSRUxPQURFRF9JTUFHRVNfTElNSVR9IGltYWdlcyB3ZXJlIG1hcmtlZCBhcyBwcmlvcml0eS4gYCArIGBUaGlzIG1pZ2h0IG5lZ2F0aXZlbHkgYWZmZWN0IGFuIG92ZXJhbGwgcGVyZm9ybWFuY2Ugb2YgdGhlIHBhZ2UuIGAgKyBgVG8gZml4IHRoaXMsIHJlbW92ZSB0aGUgXCJwcmlvcml0eVwiIGF0dHJpYnV0ZSBmcm9tIGltYWdlcyB3aXRoIGxlc3MgcHJpb3JpdHkuYCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0aGlzLnByZWxvYWRlZEltYWdlcy5oYXMoc3JjKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnByZWxvYWRlZEltYWdlcy5hZGQoc3JjKTtcbiAgICBjb25zdCBwcmVsb2FkID0gcmVuZGVyZXIuY3JlYXRlRWxlbWVudCgnbGluaycpO1xuICAgIHJlbmRlcmVyLnNldEF0dHJpYnV0ZShwcmVsb2FkLCAnYXMnLCAnaW1hZ2UnKTtcbiAgICByZW5kZXJlci5zZXRBdHRyaWJ1dGUocHJlbG9hZCwgJ2hyZWYnLCBzcmMpO1xuICAgIHJlbmRlcmVyLnNldEF0dHJpYnV0ZShwcmVsb2FkLCAncmVsJywgJ3ByZWxvYWQnKTtcbiAgICByZW5kZXJlci5zZXRBdHRyaWJ1dGUocHJlbG9hZCwgJ2ZldGNocHJpb3JpdHknLCAnaGlnaCcpO1xuICAgIGlmIChzaXplcykge1xuICAgICAgcmVuZGVyZXIuc2V0QXR0cmlidXRlKHByZWxvYWQsICdpbWFnZVNpemVzJywgc2l6ZXMpO1xuICAgIH1cbiAgICBpZiAoc3Jjc2V0KSB7XG4gICAgICByZW5kZXJlci5zZXRBdHRyaWJ1dGUocHJlbG9hZCwgJ2ltYWdlU3Jjc2V0Jywgc3Jjc2V0KTtcbiAgICB9XG4gICAgcmVuZGVyZXIuYXBwZW5kQ2hpbGQodGhpcy5kb2N1bWVudC5oZWFkLCBwcmVsb2FkKTtcbiAgfVxuICBzdGF0aWMge1xuICAgIHRoaXMuybVmYWMgPSBmdW5jdGlvbiBQcmVsb2FkTGlua0NyZWF0b3JfRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IFByZWxvYWRMaW5rQ3JlYXRvcikoKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXByb3YgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lSW5qZWN0YWJsZSh7XG4gICAgICB0b2tlbjogUHJlbG9hZExpbmtDcmVhdG9yLFxuICAgICAgZmFjdG9yeTogUHJlbG9hZExpbmtDcmVhdG9yLsm1ZmFjLFxuICAgICAgcHJvdmlkZWRJbjogJ3Jvb3QnXG4gICAgfSk7XG4gIH1cbn1cbigoKSA9PiB7XG4gICh0eXBlb2YgbmdEZXZNb2RlID09PSBcInVuZGVmaW5lZFwiIHx8IG5nRGV2TW9kZSkgJiYgaTAuybVzZXRDbGFzc01ldGFkYXRhKFByZWxvYWRMaW5rQ3JlYXRvciwgW3tcbiAgICB0eXBlOiBJbmplY3RhYmxlLFxuICAgIGFyZ3M6IFt7XG4gICAgICBwcm92aWRlZEluOiAncm9vdCdcbiAgICB9XVxuICB9XSwgbnVsbCwgbnVsbCk7XG59KSgpO1xuXG4vKipcbiAqIFdoZW4gYSBCYXNlNjQtZW5jb2RlZCBpbWFnZSBpcyBwYXNzZWQgYXMgYW4gaW5wdXQgdG8gdGhlIGBOZ09wdGltaXplZEltYWdlYCBkaXJlY3RpdmUsXG4gKiBhbiBlcnJvciBpcyB0aHJvd24uIFRoZSBpbWFnZSBjb250ZW50IChhcyBhIHN0cmluZykgbWlnaHQgYmUgdmVyeSBsb25nLCB0aHVzIG1ha2luZ1xuICogaXQgaGFyZCB0byByZWFkIGFuIGVycm9yIG1lc3NhZ2UgaWYgdGhlIGVudGlyZSBzdHJpbmcgaXMgaW5jbHVkZWQuIFRoaXMgY29uc3QgZGVmaW5lc1xuICogdGhlIG51bWJlciBvZiBjaGFyYWN0ZXJzIHRoYXQgc2hvdWxkIGJlIGluY2x1ZGVkIGludG8gdGhlIGVycm9yIG1lc3NhZ2UuIFRoZSByZXN0XG4gKiBvZiB0aGUgY29udGVudCBpcyB0cnVuY2F0ZWQuXG4gKi9cbmNvbnN0IEJBU0U2NF9JTUdfTUFYX0xFTkdUSF9JTl9FUlJPUiA9IDUwO1xuLyoqXG4gKiBSZWdFeHByIHRvIGRldGVybWluZSB3aGV0aGVyIGEgc3JjIGluIGEgc3Jjc2V0IGlzIHVzaW5nIHdpZHRoIGRlc2NyaXB0b3JzLlxuICogU2hvdWxkIG1hdGNoIHNvbWV0aGluZyBsaWtlOiBcIjEwMHcsIDIwMHdcIi5cbiAqL1xuY29uc3QgVkFMSURfV0lEVEhfREVTQ1JJUFRPUl9TUkNTRVQgPSAvXigoXFxzKlxcZCt3XFxzKigsfCQpKXsxLH0pJC87XG4vKipcbiAqIFJlZ0V4cHIgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgYSBzcmMgaW4gYSBzcmNzZXQgaXMgdXNpbmcgZGVuc2l0eSBkZXNjcmlwdG9ycy5cbiAqIFNob3VsZCBtYXRjaCBzb21ldGhpbmcgbGlrZTogXCIxeCwgMngsIDUweFwiLiBBbHNvIHN1cHBvcnRzIGRlY2ltYWxzIGxpa2UgXCIxLjV4LCAxLjUweFwiLlxuICovXG5jb25zdCBWQUxJRF9ERU5TSVRZX0RFU0NSSVBUT1JfU1JDU0VUID0gL14oKFxccypcXGQrKFxcLlxcZCspP3hcXHMqKCx8JCkpezEsfSkkLztcbi8qKlxuICogU3Jjc2V0IHZhbHVlcyB3aXRoIGEgZGVuc2l0eSBkZXNjcmlwdG9yIGhpZ2hlciB0aGFuIHRoaXMgdmFsdWUgd2lsbCBhY3RpdmVseVxuICogdGhyb3cgYW4gZXJyb3IuIFN1Y2ggZGVuc2l0aWVzIGFyZSBub3QgcGVybWl0dGVkIGFzIHRoZXkgY2F1c2UgaW1hZ2Ugc2l6ZXNcbiAqIHRvIGJlIHVucmVhc29uYWJseSBsYXJnZSBhbmQgc2xvdyBkb3duIExDUC5cbiAqL1xuY29uc3QgQUJTT0xVVEVfU1JDU0VUX0RFTlNJVFlfQ0FQID0gMztcbi8qKlxuICogVXNlZCBvbmx5IGluIGVycm9yIG1lc3NhZ2UgdGV4dCB0byBjb21tdW5pY2F0ZSBiZXN0IHByYWN0aWNlcywgYXMgd2Ugd2lsbFxuICogb25seSB0aHJvdyBiYXNlZCBvbiB0aGUgc2xpZ2h0bHkgbW9yZSBjb25zZXJ2YXRpdmUgQUJTT0xVVEVfU1JDU0VUX0RFTlNJVFlfQ0FQLlxuICovXG5jb25zdCBSRUNPTU1FTkRFRF9TUkNTRVRfREVOU0lUWV9DQVAgPSAyO1xuLyoqXG4gKiBVc2VkIGluIGdlbmVyYXRpbmcgYXV0b21hdGljIGRlbnNpdHktYmFzZWQgc3Jjc2V0c1xuICovXG5jb25zdCBERU5TSVRZX1NSQ1NFVF9NVUxUSVBMSUVSUyA9IFsxLCAyXTtcbi8qKlxuICogVXNlZCB0byBkZXRlcm1pbmUgd2hpY2ggYnJlYWtwb2ludHMgdG8gdXNlIG9uIGZ1bGwtd2lkdGggaW1hZ2VzXG4gKi9cbmNvbnN0IFZJRVdQT1JUX0JSRUFLUE9JTlRfQ1VUT0ZGID0gNjQwO1xuLyoqXG4gKiBVc2VkIHRvIGRldGVybWluZSB3aGV0aGVyIHR3byBhc3BlY3QgcmF0aW9zIGFyZSBzaW1pbGFyIGluIHZhbHVlLlxuICovXG5jb25zdCBBU1BFQ1RfUkFUSU9fVE9MRVJBTkNFID0gMC4xO1xuLyoqXG4gKiBVc2VkIHRvIGRldGVybWluZSB3aGV0aGVyIHRoZSBpbWFnZSBoYXMgYmVlbiByZXF1ZXN0ZWQgYXQgYW4gb3Zlcmx5XG4gKiBsYXJnZSBzaXplIGNvbXBhcmVkIHRvIHRoZSBhY3R1YWwgcmVuZGVyZWQgaW1hZ2Ugc2l6ZSAoYWZ0ZXIgdGFraW5nXG4gKiBpbnRvIGFjY291bnQgYSB0eXBpY2FsIGRldmljZSBwaXhlbCByYXRpbykuIEluIHBpeGVscy5cbiAqL1xuY29uc3QgT1ZFUlNJWkVEX0lNQUdFX1RPTEVSQU5DRSA9IDEwMDA7XG4vKipcbiAqIFVzZWQgdG8gbGltaXQgYXV0b21hdGljIHNyY3NldCBnZW5lcmF0aW9uIG9mIHZlcnkgbGFyZ2Ugc291cmNlcyBmb3JcbiAqIGZpeGVkLXNpemUgaW1hZ2VzLiBJbiBwaXhlbHMuXG4gKi9cbmNvbnN0IEZJWEVEX1NSQ1NFVF9XSURUSF9MSU1JVCA9IDE5MjA7XG5jb25zdCBGSVhFRF9TUkNTRVRfSEVJR0hUX0xJTUlUID0gMTA4MDtcbi8qKlxuICogRGVmYXVsdCBibHVyIHJhZGl1cyBvZiB0aGUgQ1NTIGZpbHRlciB1c2VkIG9uIHBsYWNlaG9sZGVyIGltYWdlcywgaW4gcGl4ZWxzXG4gKi9cbmNvbnN0IFBMQUNFSE9MREVSX0JMVVJfQU1PVU5UID0gMTU7XG4vKipcbiAqIFVzZWQgdG8gd2FybiBvciBlcnJvciB3aGVuIHRoZSB1c2VyIHByb3ZpZGVzIGFuIG92ZXJseSBsYXJnZSBkYXRhVVJMIGZvciB0aGUgcGxhY2Vob2xkZXJcbiAqIGF0dHJpYnV0ZS5cbiAqIENoYXJhY3RlciBjb3VudCBvZiBCYXNlNjQgaW1hZ2VzIGlzIDEgY2hhcmFjdGVyIHBlciBieXRlLCBhbmQgYmFzZTY0IGVuY29kaW5nIGlzIGFwcHJveGltYXRlbHlcbiAqIDMzJSBsYXJnZXIgdGhhbiBiYXNlIGltYWdlcywgc28gNDAwMCBjaGFyYWN0ZXJzIGlzIGFyb3VuZCAzS0Igb24gZGlzayBhbmQgMTAwMDAgY2hhcmFjdGVycyBpc1xuICogYXJvdW5kIDcuN0tCLiBFeHBlcmltZW50YWxseSwgNDAwMCBjaGFyYWN0ZXJzIGlzIGFib3V0IDIweDIwcHggaW4gUE5HIG9yIG1lZGl1bS1xdWFsaXR5IEpQRUdcbiAqIGZvcm1hdCwgYW5kIDEwLDAwMCBpcyBhcm91bmQgNTB4NTBweCwgYnV0IHRoZXJlJ3MgcXVpdGUgYSBiaXQgb2YgdmFyaWF0aW9uIGRlcGVuZGluZyBvbiBob3cgdGhlXG4gKiBpbWFnZSBpcyBzYXZlZC5cbiAqL1xuY29uc3QgREFUQV9VUkxfV0FSTl9MSU1JVCA9IDQwMDA7XG5jb25zdCBEQVRBX1VSTF9FUlJPUl9MSU1JVCA9IDEwMDAwO1xuLyoqIEluZm8gYWJvdXQgYnVpbHQtaW4gbG9hZGVycyB3ZSBjYW4gdGVzdCBmb3IuICovXG5jb25zdCBCVUlMVF9JTl9MT0FERVJTID0gW2ltZ2l4TG9hZGVySW5mbywgaW1hZ2VLaXRMb2FkZXJJbmZvLCBjbG91ZGluYXJ5TG9hZGVySW5mbywgbmV0bGlmeUxvYWRlckluZm9dO1xuLyoqXG4gKiBEaXJlY3RpdmUgdGhhdCBpbXByb3ZlcyBpbWFnZSBsb2FkaW5nIHBlcmZvcm1hbmNlIGJ5IGVuZm9yY2luZyBiZXN0IHByYWN0aWNlcy5cbiAqXG4gKiBgTmdPcHRpbWl6ZWRJbWFnZWAgZW5zdXJlcyB0aGF0IHRoZSBsb2FkaW5nIG9mIHRoZSBMYXJnZXN0IENvbnRlbnRmdWwgUGFpbnQgKExDUCkgaW1hZ2UgaXNcbiAqIHByaW9yaXRpemVkIGJ5OlxuICogLSBBdXRvbWF0aWNhbGx5IHNldHRpbmcgdGhlIGBmZXRjaHByaW9yaXR5YCBhdHRyaWJ1dGUgb24gdGhlIGA8aW1nPmAgdGFnXG4gKiAtIExhenkgbG9hZGluZyBub24tcHJpb3JpdHkgaW1hZ2VzIGJ5IGRlZmF1bHRcbiAqIC0gQXV0b21hdGljYWxseSBnZW5lcmF0aW5nIGEgcHJlY29ubmVjdCBsaW5rIHRhZyBpbiB0aGUgZG9jdW1lbnQgaGVhZFxuICpcbiAqIEluIGFkZGl0aW9uLCB0aGUgZGlyZWN0aXZlOlxuICogLSBHZW5lcmF0ZXMgYXBwcm9wcmlhdGUgYXNzZXQgVVJMcyBpZiBhIGNvcnJlc3BvbmRpbmcgYEltYWdlTG9hZGVyYCBmdW5jdGlvbiBpcyBwcm92aWRlZFxuICogLSBBdXRvbWF0aWNhbGx5IGdlbmVyYXRlcyBhIHNyY3NldFxuICogLSBSZXF1aXJlcyB0aGF0IGB3aWR0aGAgYW5kIGBoZWlnaHRgIGFyZSBzZXRcbiAqIC0gV2FybnMgaWYgYHdpZHRoYCBvciBgaGVpZ2h0YCBoYXZlIGJlZW4gc2V0IGluY29ycmVjdGx5XG4gKiAtIFdhcm5zIGlmIHRoZSBpbWFnZSB3aWxsIGJlIHZpc3VhbGx5IGRpc3RvcnRlZCB3aGVuIHJlbmRlcmVkXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqIFRoZSBgTmdPcHRpbWl6ZWRJbWFnZWAgZGlyZWN0aXZlIGlzIG1hcmtlZCBhcyBbc3RhbmRhbG9uZV0oZ3VpZGUvY29tcG9uZW50cy9pbXBvcnRpbmcpIGFuZCBjYW5cbiAqIGJlIGltcG9ydGVkIGRpcmVjdGx5LlxuICpcbiAqIEZvbGxvdyB0aGUgc3RlcHMgYmVsb3cgdG8gZW5hYmxlIGFuZCB1c2UgdGhlIGRpcmVjdGl2ZTpcbiAqIDEuIEltcG9ydCBpdCBpbnRvIHRoZSBuZWNlc3NhcnkgTmdNb2R1bGUgb3IgYSBzdGFuZGFsb25lIENvbXBvbmVudC5cbiAqIDIuIE9wdGlvbmFsbHkgcHJvdmlkZSBhbiBgSW1hZ2VMb2FkZXJgIGlmIHlvdSB1c2UgYW4gaW1hZ2UgaG9zdGluZyBzZXJ2aWNlLlxuICogMy4gVXBkYXRlIHRoZSBuZWNlc3NhcnkgYDxpbWc+YCB0YWdzIGluIHRlbXBsYXRlcyBhbmQgcmVwbGFjZSBgc3JjYCBhdHRyaWJ1dGVzIHdpdGggYG5nU3JjYC5cbiAqIFVzaW5nIGEgYG5nU3JjYCBhbGxvd3MgdGhlIGRpcmVjdGl2ZSB0byBjb250cm9sIHdoZW4gdGhlIGBzcmNgIGdldHMgc2V0LCB3aGljaCB0cmlnZ2VycyBhbiBpbWFnZVxuICogZG93bmxvYWQuXG4gKlxuICogU3RlcCAxOiBpbXBvcnQgdGhlIGBOZ09wdGltaXplZEltYWdlYCBkaXJlY3RpdmUuXG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogaW1wb3J0IHsgTmdPcHRpbWl6ZWRJbWFnZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG4gKlxuICogLy8gSW5jbHVkZSBpdCBpbnRvIHRoZSBuZWNlc3NhcnkgTmdNb2R1bGVcbiAqIEBOZ01vZHVsZSh7XG4gKiAgIGltcG9ydHM6IFtOZ09wdGltaXplZEltYWdlXSxcbiAqIH0pXG4gKiBjbGFzcyBBcHBNb2R1bGUge31cbiAqXG4gKiAvLyAuLi4gb3IgYSBzdGFuZGFsb25lIENvbXBvbmVudFxuICogQENvbXBvbmVudCh7XG4gKiAgIHN0YW5kYWxvbmU6IHRydWVcbiAqICAgaW1wb3J0czogW05nT3B0aW1pemVkSW1hZ2VdLFxuICogfSlcbiAqIGNsYXNzIE15U3RhbmRhbG9uZUNvbXBvbmVudCB7fVxuICogYGBgXG4gKlxuICogU3RlcCAyOiBjb25maWd1cmUgYSBsb2FkZXIuXG4gKlxuICogVG8gdXNlIHRoZSAqKmRlZmF1bHQgbG9hZGVyKio6IG5vIGFkZGl0aW9uYWwgY29kZSBjaGFuZ2VzIGFyZSBuZWNlc3NhcnkuIFRoZSBVUkwgcmV0dXJuZWQgYnkgdGhlXG4gKiBnZW5lcmljIGxvYWRlciB3aWxsIGFsd2F5cyBtYXRjaCB0aGUgdmFsdWUgb2YgXCJzcmNcIi4gSW4gb3RoZXIgd29yZHMsIHRoaXMgbG9hZGVyIGFwcGxpZXMgbm9cbiAqIHRyYW5zZm9ybWF0aW9ucyB0byB0aGUgcmVzb3VyY2UgVVJMIGFuZCB0aGUgdmFsdWUgb2YgdGhlIGBuZ1NyY2AgYXR0cmlidXRlIHdpbGwgYmUgdXNlZCBhcyBpcy5cbiAqXG4gKiBUbyB1c2UgYW4gZXhpc3RpbmcgbG9hZGVyIGZvciBhICoqdGhpcmQtcGFydHkgaW1hZ2Ugc2VydmljZSoqOiBhZGQgdGhlIHByb3ZpZGVyIGZhY3RvcnkgZm9yIHlvdXJcbiAqIGNob3NlbiBzZXJ2aWNlIHRvIHRoZSBgcHJvdmlkZXJzYCBhcnJheS4gSW4gdGhlIGV4YW1wbGUgYmVsb3csIHRoZSBJbWdpeCBsb2FkZXIgaXMgdXNlZDpcbiAqXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQge3Byb3ZpZGVJbWdpeExvYWRlcn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbiAqXG4gKiAvLyBDYWxsIHRoZSBmdW5jdGlvbiBhbmQgYWRkIHRoZSByZXN1bHQgdG8gdGhlIGBwcm92aWRlcnNgIGFycmF5OlxuICogcHJvdmlkZXJzOiBbXG4gKiAgIHByb3ZpZGVJbWdpeExvYWRlcihcImh0dHBzOi8vbXkuYmFzZS51cmwvXCIpLFxuICogXSxcbiAqIGBgYFxuICpcbiAqIFRoZSBgTmdPcHRpbWl6ZWRJbWFnZWAgZGlyZWN0aXZlIHByb3ZpZGVzIHRoZSBmb2xsb3dpbmcgZnVuY3Rpb25zOlxuICogLSBgcHJvdmlkZUNsb3VkZmxhcmVMb2FkZXJgXG4gKiAtIGBwcm92aWRlQ2xvdWRpbmFyeUxvYWRlcmBcbiAqIC0gYHByb3ZpZGVJbWFnZUtpdExvYWRlcmBcbiAqIC0gYHByb3ZpZGVJbWdpeExvYWRlcmBcbiAqXG4gKiBJZiB5b3UgdXNlIGEgZGlmZmVyZW50IGltYWdlIHByb3ZpZGVyLCB5b3UgY2FuIGNyZWF0ZSBhIGN1c3RvbSBsb2FkZXIgZnVuY3Rpb24gYXMgZGVzY3JpYmVkXG4gKiBiZWxvdy5cbiAqXG4gKiBUbyB1c2UgYSAqKmN1c3RvbSBsb2FkZXIqKjogcHJvdmlkZSB5b3VyIGxvYWRlciBmdW5jdGlvbiBhcyBhIHZhbHVlIGZvciB0aGUgYElNQUdFX0xPQURFUmAgRElcbiAqIHRva2VuLlxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIGltcG9ydCB7SU1BR0VfTE9BREVSLCBJbWFnZUxvYWRlckNvbmZpZ30gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbiAqXG4gKiAvLyBDb25maWd1cmUgdGhlIGxvYWRlciB1c2luZyB0aGUgYElNQUdFX0xPQURFUmAgdG9rZW4uXG4gKiBwcm92aWRlcnM6IFtcbiAqICAge1xuICogICAgICBwcm92aWRlOiBJTUFHRV9MT0FERVIsXG4gKiAgICAgIHVzZVZhbHVlOiAoY29uZmlnOiBJbWFnZUxvYWRlckNvbmZpZykgPT4ge1xuICogICAgICAgIHJldHVybiBgaHR0cHM6Ly9leGFtcGxlLmNvbS8ke2NvbmZpZy5zcmN9LSR7Y29uZmlnLndpZHRofS5qcGd9YDtcbiAqICAgICAgfVxuICogICB9LFxuICogXSxcbiAqIGBgYFxuICpcbiAqIFN0ZXAgMzogdXBkYXRlIGA8aW1nPmAgdGFncyBpbiB0ZW1wbGF0ZXMgdG8gdXNlIGBuZ1NyY2AgaW5zdGVhZCBvZiBgc3JjYC5cbiAqXG4gKiBgYGBcbiAqIDxpbWcgbmdTcmM9XCJsb2dvLnBuZ1wiIHdpZHRoPVwiMjAwXCIgaGVpZ2h0PVwiMTAwXCI+XG4gKiBgYGBcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIE5nT3B0aW1pemVkSW1hZ2Uge1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmltYWdlTG9hZGVyID0gaW5qZWN0KElNQUdFX0xPQURFUik7XG4gICAgdGhpcy5jb25maWcgPSBwcm9jZXNzQ29uZmlnKGluamVjdCjJtUlNQUdFX0NPTkZJRykpO1xuICAgIHRoaXMucmVuZGVyZXIgPSBpbmplY3QoUmVuZGVyZXIyKTtcbiAgICB0aGlzLmltZ0VsZW1lbnQgPSBpbmplY3QoRWxlbWVudFJlZikubmF0aXZlRWxlbWVudDtcbiAgICB0aGlzLmluamVjdG9yID0gaW5qZWN0KEluamVjdG9yKTtcbiAgICB0aGlzLmlzU2VydmVyID0gaXNQbGF0Zm9ybVNlcnZlcihpbmplY3QoUExBVEZPUk1fSUQpKTtcbiAgICB0aGlzLnByZWxvYWRMaW5rQ3JlYXRvciA9IGluamVjdChQcmVsb2FkTGlua0NyZWF0b3IpO1xuICAgIC8vIGEgTENQIGltYWdlIG9ic2VydmVyIC0gc2hvdWxkIGJlIGluamVjdGVkIG9ubHkgaW4gdGhlIGRldiBtb2RlXG4gICAgdGhpcy5sY3BPYnNlcnZlciA9IG5nRGV2TW9kZSA/IHRoaXMuaW5qZWN0b3IuZ2V0KExDUEltYWdlT2JzZXJ2ZXIpIDogbnVsbDtcbiAgICAvKipcbiAgICAgKiBDYWxjdWxhdGUgdGhlIHJld3JpdHRlbiBgc3JjYCBvbmNlIGFuZCBzdG9yZSBpdC5cbiAgICAgKiBUaGlzIGlzIG5lZWRlZCB0byBhdm9pZCByZXBldGl0aXZlIGNhbGN1bGF0aW9ucyBhbmQgbWFrZSBzdXJlIHRoZSBkaXJlY3RpdmUgY2xlYW51cCBpbiB0aGVcbiAgICAgKiBgbmdPbkRlc3Ryb3lgIGRvZXMgbm90IHJlbHkgb24gdGhlIGBJTUFHRV9MT0FERVJgIGxvZ2ljICh3aGljaCBpbiB0dXJuIGNhbiByZWx5IG9uIHNvbWUgb3RoZXJcbiAgICAgKiBpbnN0YW5jZSB0aGF0IG1pZ2h0IGJlIGFscmVhZHkgZGVzdHJveWVkKS5cbiAgICAgKi9cbiAgICB0aGlzLl9yZW5kZXJlZFNyYyA9IG51bGw7XG4gICAgLyoqXG4gICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhpcyBpbWFnZSBzaG91bGQgaGF2ZSBhIGhpZ2ggcHJpb3JpdHkuXG4gICAgICovXG4gICAgdGhpcy5wcmlvcml0eSA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIERpc2FibGVzIGF1dG9tYXRpYyBzcmNzZXQgZ2VuZXJhdGlvbiBmb3IgdGhpcyBpbWFnZS5cbiAgICAgKi9cbiAgICB0aGlzLmRpc2FibGVPcHRpbWl6ZWRTcmNzZXQgPSBmYWxzZTtcbiAgICAvKipcbiAgICAgKiBTZXRzIHRoZSBpbWFnZSB0byBcImZpbGwgbW9kZVwiLCB3aGljaCBlbGltaW5hdGVzIHRoZSBoZWlnaHQvd2lkdGggcmVxdWlyZW1lbnQgYW5kIGFkZHNcbiAgICAgKiBzdHlsZXMgc3VjaCB0aGF0IHRoZSBpbWFnZSBmaWxscyBpdHMgY29udGFpbmluZyBlbGVtZW50LlxuICAgICAqL1xuICAgIHRoaXMuZmlsbCA9IGZhbHNlO1xuICB9XG4gIC8qKiBAbm9kb2MgKi9cbiAgbmdPbkluaXQoKSB7XG4gICAgybVwZXJmb3JtYW5jZU1hcmtGZWF0dXJlKCdOZ09wdGltaXplZEltYWdlJyk7XG4gICAgaWYgKG5nRGV2TW9kZSkge1xuICAgICAgY29uc3Qgbmdab25lID0gdGhpcy5pbmplY3Rvci5nZXQoTmdab25lKTtcbiAgICAgIGFzc2VydE5vbkVtcHR5SW5wdXQodGhpcywgJ25nU3JjJywgdGhpcy5uZ1NyYyk7XG4gICAgICBhc3NlcnRWYWxpZE5nU3Jjc2V0KHRoaXMsIHRoaXMubmdTcmNzZXQpO1xuICAgICAgYXNzZXJ0Tm9Db25mbGljdGluZ1NyYyh0aGlzKTtcbiAgICAgIGlmICh0aGlzLm5nU3Jjc2V0KSB7XG4gICAgICAgIGFzc2VydE5vQ29uZmxpY3RpbmdTcmNzZXQodGhpcyk7XG4gICAgICB9XG4gICAgICBhc3NlcnROb3RCYXNlNjRJbWFnZSh0aGlzKTtcbiAgICAgIGFzc2VydE5vdEJsb2JVcmwodGhpcyk7XG4gICAgICBpZiAodGhpcy5maWxsKSB7XG4gICAgICAgIGFzc2VydEVtcHR5V2lkdGhBbmRIZWlnaHQodGhpcyk7XG4gICAgICAgIC8vIFRoaXMgbGVhdmVzIHRoZSBBbmd1bGFyIHpvbmUgdG8gYXZvaWQgdHJpZ2dlcmluZyB1bm5lY2Vzc2FyeSBjaGFuZ2UgZGV0ZWN0aW9uIGN5Y2xlcyB3aGVuXG4gICAgICAgIC8vIGBsb2FkYCB0YXNrcyBhcmUgaW52b2tlZCBvbiBpbWFnZXMuXG4gICAgICAgIG5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiBhc3NlcnROb25aZXJvUmVuZGVyZWRIZWlnaHQodGhpcywgdGhpcy5pbWdFbGVtZW50LCB0aGlzLnJlbmRlcmVyKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhc3NlcnROb25FbXB0eVdpZHRoQW5kSGVpZ2h0KHRoaXMpO1xuICAgICAgICBpZiAodGhpcy5oZWlnaHQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGFzc2VydEdyZWF0ZXJUaGFuWmVybyh0aGlzLCB0aGlzLmhlaWdodCwgJ2hlaWdodCcpO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLndpZHRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICBhc3NlcnRHcmVhdGVyVGhhblplcm8odGhpcywgdGhpcy53aWR0aCwgJ3dpZHRoJyk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gT25seSBjaGVjayBmb3IgZGlzdG9ydGVkIGltYWdlcyB3aGVuIG5vdCBpbiBmaWxsIG1vZGUsIHdoZXJlXG4gICAgICAgIC8vIGltYWdlcyBtYXkgYmUgaW50ZW50aW9uYWxseSBzdHJldGNoZWQsIGNyb3BwZWQgb3IgbGV0dGVyYm94ZWQuXG4gICAgICAgIG5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiBhc3NlcnROb0ltYWdlRGlzdG9ydGlvbih0aGlzLCB0aGlzLmltZ0VsZW1lbnQsIHRoaXMucmVuZGVyZXIpKTtcbiAgICAgIH1cbiAgICAgIGFzc2VydFZhbGlkTG9hZGluZ0lucHV0KHRoaXMpO1xuICAgICAgaWYgKCF0aGlzLm5nU3Jjc2V0KSB7XG4gICAgICAgIGFzc2VydE5vQ29tcGxleFNpemVzKHRoaXMpO1xuICAgICAgfVxuICAgICAgYXNzZXJ0VmFsaWRQbGFjZWhvbGRlcih0aGlzLCB0aGlzLmltYWdlTG9hZGVyKTtcbiAgICAgIGFzc2VydE5vdE1pc3NpbmdCdWlsdEluTG9hZGVyKHRoaXMubmdTcmMsIHRoaXMuaW1hZ2VMb2FkZXIpO1xuICAgICAgYXNzZXJ0Tm9OZ1NyY3NldFdpdGhvdXRMb2FkZXIodGhpcywgdGhpcy5pbWFnZUxvYWRlcik7XG4gICAgICBhc3NlcnROb0xvYWRlclBhcmFtc1dpdGhvdXRMb2FkZXIodGhpcywgdGhpcy5pbWFnZUxvYWRlcik7XG4gICAgICBpZiAodGhpcy5sY3BPYnNlcnZlciAhPT0gbnVsbCkge1xuICAgICAgICBjb25zdCBuZ1pvbmUgPSB0aGlzLmluamVjdG9yLmdldChOZ1pvbmUpO1xuICAgICAgICBuZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgICAgIHRoaXMubGNwT2JzZXJ2ZXIucmVnaXN0ZXJJbWFnZSh0aGlzLmdldFJld3JpdHRlblNyYygpLCB0aGlzLm5nU3JjLCB0aGlzLnByaW9yaXR5KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5wcmlvcml0eSkge1xuICAgICAgICBjb25zdCBjaGVja2VyID0gdGhpcy5pbmplY3Rvci5nZXQoUHJlY29ubmVjdExpbmtDaGVja2VyKTtcbiAgICAgICAgY2hlY2tlci5hc3NlcnRQcmVjb25uZWN0KHRoaXMuZ2V0UmV3cml0dGVuU3JjKCksIHRoaXMubmdTcmMpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGhpcy5wbGFjZWhvbGRlcikge1xuICAgICAgdGhpcy5yZW1vdmVQbGFjZWhvbGRlck9uTG9hZCh0aGlzLmltZ0VsZW1lbnQpO1xuICAgIH1cbiAgICB0aGlzLnNldEhvc3RBdHRyaWJ1dGVzKCk7XG4gIH1cbiAgc2V0SG9zdEF0dHJpYnV0ZXMoKSB7XG4gICAgLy8gTXVzdCBzZXQgd2lkdGgvaGVpZ2h0IGV4cGxpY2l0bHkgaW4gY2FzZSB0aGV5IGFyZSBib3VuZCAoaW4gd2hpY2ggY2FzZSB0aGV5IHdpbGxcbiAgICAvLyBvbmx5IGJlIHJlZmxlY3RlZCBhbmQgbm90IGZvdW5kIGJ5IHRoZSBicm93c2VyKVxuICAgIGlmICh0aGlzLmZpbGwpIHtcbiAgICAgIHRoaXMuc2l6ZXMgfHw9ICcxMDB2dyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0SG9zdEF0dHJpYnV0ZSgnd2lkdGgnLCB0aGlzLndpZHRoLnRvU3RyaW5nKCkpO1xuICAgICAgdGhpcy5zZXRIb3N0QXR0cmlidXRlKCdoZWlnaHQnLCB0aGlzLmhlaWdodC50b1N0cmluZygpKTtcbiAgICB9XG4gICAgdGhpcy5zZXRIb3N0QXR0cmlidXRlKCdsb2FkaW5nJywgdGhpcy5nZXRMb2FkaW5nQmVoYXZpb3IoKSk7XG4gICAgdGhpcy5zZXRIb3N0QXR0cmlidXRlKCdmZXRjaHByaW9yaXR5JywgdGhpcy5nZXRGZXRjaFByaW9yaXR5KCkpO1xuICAgIC8vIFRoZSBgZGF0YS1uZy1pbWdgIGF0dHJpYnV0ZSBmbGFncyBhbiBpbWFnZSBhcyB1c2luZyB0aGUgZGlyZWN0aXZlLCB0byBhbGxvd1xuICAgIC8vIGZvciBhbmFseXNpcyBvZiB0aGUgZGlyZWN0aXZlJ3MgcGVyZm9ybWFuY2UuXG4gICAgdGhpcy5zZXRIb3N0QXR0cmlidXRlKCduZy1pbWcnLCAndHJ1ZScpO1xuICAgIC8vIFRoZSBgc3JjYCBhbmQgYHNyY3NldGAgYXR0cmlidXRlcyBzaG91bGQgYmUgc2V0IGxhc3Qgc2luY2Ugb3RoZXIgYXR0cmlidXRlc1xuICAgIC8vIGNvdWxkIGFmZmVjdCB0aGUgaW1hZ2UncyBsb2FkaW5nIGJlaGF2aW9yLlxuICAgIGNvbnN0IHJld3JpdHRlblNyY3NldCA9IHRoaXMudXBkYXRlU3JjQW5kU3Jjc2V0KCk7XG4gICAgaWYgKHRoaXMuc2l6ZXMpIHtcbiAgICAgIHRoaXMuc2V0SG9zdEF0dHJpYnV0ZSgnc2l6ZXMnLCB0aGlzLnNpemVzKTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXNTZXJ2ZXIgJiYgdGhpcy5wcmlvcml0eSkge1xuICAgICAgdGhpcy5wcmVsb2FkTGlua0NyZWF0b3IuY3JlYXRlUHJlbG9hZExpbmtUYWcodGhpcy5yZW5kZXJlciwgdGhpcy5nZXRSZXdyaXR0ZW5TcmMoKSwgcmV3cml0dGVuU3Jjc2V0LCB0aGlzLnNpemVzKTtcbiAgICB9XG4gIH1cbiAgLyoqIEBub2RvYyAqL1xuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzKSB7XG4gICAgaWYgKG5nRGV2TW9kZSkge1xuICAgICAgYXNzZXJ0Tm9Qb3N0SW5pdElucHV0Q2hhbmdlKHRoaXMsIGNoYW5nZXMsIFsnbmdTcmNzZXQnLCAnd2lkdGgnLCAnaGVpZ2h0JywgJ3ByaW9yaXR5JywgJ2ZpbGwnLCAnbG9hZGluZycsICdzaXplcycsICdsb2FkZXJQYXJhbXMnLCAnZGlzYWJsZU9wdGltaXplZFNyY3NldCddKTtcbiAgICB9XG4gICAgaWYgKGNoYW5nZXNbJ25nU3JjJ10gJiYgIWNoYW5nZXNbJ25nU3JjJ10uaXNGaXJzdENoYW5nZSgpKSB7XG4gICAgICBjb25zdCBvbGRTcmMgPSB0aGlzLl9yZW5kZXJlZFNyYztcbiAgICAgIHRoaXMudXBkYXRlU3JjQW5kU3Jjc2V0KHRydWUpO1xuICAgICAgY29uc3QgbmV3U3JjID0gdGhpcy5fcmVuZGVyZWRTcmM7XG4gICAgICBpZiAodGhpcy5sY3BPYnNlcnZlciAhPT0gbnVsbCAmJiBvbGRTcmMgJiYgbmV3U3JjICYmIG9sZFNyYyAhPT0gbmV3U3JjKSB7XG4gICAgICAgIGNvbnN0IG5nWm9uZSA9IHRoaXMuaW5qZWN0b3IuZ2V0KE5nWm9uZSk7XG4gICAgICAgIG5nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgICAgdGhpcy5sY3BPYnNlcnZlcj8udXBkYXRlSW1hZ2Uob2xkU3JjLCBuZXdTcmMpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY2FsbEltYWdlTG9hZGVyKGNvbmZpZ1dpdGhvdXRDdXN0b21QYXJhbXMpIHtcbiAgICBsZXQgYXVnbWVudGVkQ29uZmlnID0gY29uZmlnV2l0aG91dEN1c3RvbVBhcmFtcztcbiAgICBpZiAodGhpcy5sb2FkZXJQYXJhbXMpIHtcbiAgICAgIGF1Z21lbnRlZENvbmZpZy5sb2FkZXJQYXJhbXMgPSB0aGlzLmxvYWRlclBhcmFtcztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VMb2FkZXIoYXVnbWVudGVkQ29uZmlnKTtcbiAgfVxuICBnZXRMb2FkaW5nQmVoYXZpb3IoKSB7XG4gICAgaWYgKCF0aGlzLnByaW9yaXR5ICYmIHRoaXMubG9hZGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdGhpcy5sb2FkaW5nO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wcmlvcml0eSA/ICdlYWdlcicgOiAnbGF6eSc7XG4gIH1cbiAgZ2V0RmV0Y2hQcmlvcml0eSgpIHtcbiAgICByZXR1cm4gdGhpcy5wcmlvcml0eSA/ICdoaWdoJyA6ICdhdXRvJztcbiAgfVxuICBnZXRSZXdyaXR0ZW5TcmMoKSB7XG4gICAgLy8gSW1hZ2VMb2FkZXJDb25maWcgc3VwcG9ydHMgc2V0dGluZyBhIHdpZHRoIHByb3BlcnR5LiBIb3dldmVyLCB3ZSdyZSBub3Qgc2V0dGluZyB3aWR0aCBoZXJlXG4gICAgLy8gYmVjYXVzZSBpZiB0aGUgZGV2ZWxvcGVyIHVzZXMgcmVuZGVyZWQgd2lkdGggaW5zdGVhZCBvZiBpbnRyaW5zaWMgd2lkdGggaW4gdGhlIEhUTUwgd2lkdGhcbiAgICAvLyBhdHRyaWJ1dGUsIHRoZSBpbWFnZSByZXF1ZXN0ZWQgbWF5IGJlIHRvbyBzbWFsbCBmb3IgMngrIHNjcmVlbnMuXG4gICAgaWYgKCF0aGlzLl9yZW5kZXJlZFNyYykge1xuICAgICAgY29uc3QgaW1nQ29uZmlnID0ge1xuICAgICAgICBzcmM6IHRoaXMubmdTcmNcbiAgICAgIH07XG4gICAgICAvLyBDYWNoZSBjYWxjdWxhdGVkIGltYWdlIHNyYyB0byByZXVzZSBpdCBsYXRlciBpbiB0aGUgY29kZS5cbiAgICAgIHRoaXMuX3JlbmRlcmVkU3JjID0gdGhpcy5jYWxsSW1hZ2VMb2FkZXIoaW1nQ29uZmlnKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3JlbmRlcmVkU3JjO1xuICB9XG4gIGdldFJld3JpdHRlblNyY3NldCgpIHtcbiAgICBjb25zdCB3aWR0aFNyY1NldCA9IFZBTElEX1dJRFRIX0RFU0NSSVBUT1JfU1JDU0VULnRlc3QodGhpcy5uZ1NyY3NldCk7XG4gICAgY29uc3QgZmluYWxTcmNzID0gdGhpcy5uZ1NyY3NldC5zcGxpdCgnLCcpLmZpbHRlcihzcmMgPT4gc3JjICE9PSAnJykubWFwKHNyY1N0ciA9PiB7XG4gICAgICBzcmNTdHIgPSBzcmNTdHIudHJpbSgpO1xuICAgICAgY29uc3Qgd2lkdGggPSB3aWR0aFNyY1NldCA/IHBhcnNlRmxvYXQoc3JjU3RyKSA6IHBhcnNlRmxvYXQoc3JjU3RyKSAqIHRoaXMud2lkdGg7XG4gICAgICByZXR1cm4gYCR7dGhpcy5jYWxsSW1hZ2VMb2FkZXIoe1xuICAgICAgICBzcmM6IHRoaXMubmdTcmMsXG4gICAgICAgIHdpZHRoXG4gICAgICB9KX0gJHtzcmNTdHJ9YDtcbiAgICB9KTtcbiAgICByZXR1cm4gZmluYWxTcmNzLmpvaW4oJywgJyk7XG4gIH1cbiAgZ2V0QXV0b21hdGljU3Jjc2V0KCkge1xuICAgIGlmICh0aGlzLnNpemVzKSB7XG4gICAgICByZXR1cm4gdGhpcy5nZXRSZXNwb25zaXZlU3Jjc2V0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEZpeGVkU3Jjc2V0KCk7XG4gICAgfVxuICB9XG4gIGdldFJlc3BvbnNpdmVTcmNzZXQoKSB7XG4gICAgY29uc3Qge1xuICAgICAgYnJlYWtwb2ludHNcbiAgICB9ID0gdGhpcy5jb25maWc7XG4gICAgbGV0IGZpbHRlcmVkQnJlYWtwb2ludHMgPSBicmVha3BvaW50cztcbiAgICBpZiAodGhpcy5zaXplcz8udHJpbSgpID09PSAnMTAwdncnKSB7XG4gICAgICAvLyBTaW5jZSB0aGlzIGlzIGEgZnVsbC1zY3JlZW4td2lkdGggaW1hZ2UsIG91ciBzcmNzZXQgb25seSBuZWVkcyB0byBpbmNsdWRlXG4gICAgICAvLyBicmVha3BvaW50cyB3aXRoIGZ1bGwgdmlld3BvcnQgd2lkdGhzLlxuICAgICAgZmlsdGVyZWRCcmVha3BvaW50cyA9IGJyZWFrcG9pbnRzLmZpbHRlcihicCA9PiBicCA+PSBWSUVXUE9SVF9CUkVBS1BPSU5UX0NVVE9GRik7XG4gICAgfVxuICAgIGNvbnN0IGZpbmFsU3JjcyA9IGZpbHRlcmVkQnJlYWtwb2ludHMubWFwKGJwID0+IGAke3RoaXMuY2FsbEltYWdlTG9hZGVyKHtcbiAgICAgIHNyYzogdGhpcy5uZ1NyYyxcbiAgICAgIHdpZHRoOiBicFxuICAgIH0pfSAke2JwfXdgKTtcbiAgICByZXR1cm4gZmluYWxTcmNzLmpvaW4oJywgJyk7XG4gIH1cbiAgdXBkYXRlU3JjQW5kU3Jjc2V0KGZvcmNlU3JjUmVjYWxjID0gZmFsc2UpIHtcbiAgICBpZiAoZm9yY2VTcmNSZWNhbGMpIHtcbiAgICAgIC8vIFJlc2V0IGNhY2hlZCB2YWx1ZSwgc28gdGhhdCB0aGUgZm9sbG93dXAgYGdldFJld3JpdHRlblNyYygpYCBjYWxsXG4gICAgICAvLyB3aWxsIHJlY2FsY3VsYXRlIGl0IGFuZCB1cGRhdGUgdGhlIGNhY2hlLlxuICAgICAgdGhpcy5fcmVuZGVyZWRTcmMgPSBudWxsO1xuICAgIH1cbiAgICBjb25zdCByZXdyaXR0ZW5TcmMgPSB0aGlzLmdldFJld3JpdHRlblNyYygpO1xuICAgIHRoaXMuc2V0SG9zdEF0dHJpYnV0ZSgnc3JjJywgcmV3cml0dGVuU3JjKTtcbiAgICBsZXQgcmV3cml0dGVuU3Jjc2V0ID0gdW5kZWZpbmVkO1xuICAgIGlmICh0aGlzLm5nU3Jjc2V0KSB7XG4gICAgICByZXdyaXR0ZW5TcmNzZXQgPSB0aGlzLmdldFJld3JpdHRlblNyY3NldCgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zaG91bGRHZW5lcmF0ZUF1dG9tYXRpY1NyY3NldCgpKSB7XG4gICAgICByZXdyaXR0ZW5TcmNzZXQgPSB0aGlzLmdldEF1dG9tYXRpY1NyY3NldCgpO1xuICAgIH1cbiAgICBpZiAocmV3cml0dGVuU3Jjc2V0KSB7XG4gICAgICB0aGlzLnNldEhvc3RBdHRyaWJ1dGUoJ3NyY3NldCcsIHJld3JpdHRlblNyY3NldCk7XG4gICAgfVxuICAgIHJldHVybiByZXdyaXR0ZW5TcmNzZXQ7XG4gIH1cbiAgZ2V0Rml4ZWRTcmNzZXQoKSB7XG4gICAgY29uc3QgZmluYWxTcmNzID0gREVOU0lUWV9TUkNTRVRfTVVMVElQTElFUlMubWFwKG11bHRpcGxpZXIgPT4gYCR7dGhpcy5jYWxsSW1hZ2VMb2FkZXIoe1xuICAgICAgc3JjOiB0aGlzLm5nU3JjLFxuICAgICAgd2lkdGg6IHRoaXMud2lkdGggKiBtdWx0aXBsaWVyXG4gICAgfSl9ICR7bXVsdGlwbGllcn14YCk7XG4gICAgcmV0dXJuIGZpbmFsU3Jjcy5qb2luKCcsICcpO1xuICB9XG4gIHNob3VsZEdlbmVyYXRlQXV0b21hdGljU3Jjc2V0KCkge1xuICAgIGxldCBvdmVyc2l6ZWRJbWFnZSA9IGZhbHNlO1xuICAgIGlmICghdGhpcy5zaXplcykge1xuICAgICAgb3ZlcnNpemVkSW1hZ2UgPSB0aGlzLndpZHRoID4gRklYRURfU1JDU0VUX1dJRFRIX0xJTUlUIHx8IHRoaXMuaGVpZ2h0ID4gRklYRURfU1JDU0VUX0hFSUdIVF9MSU1JVDtcbiAgICB9XG4gICAgcmV0dXJuICF0aGlzLmRpc2FibGVPcHRpbWl6ZWRTcmNzZXQgJiYgIXRoaXMuc3Jjc2V0ICYmIHRoaXMuaW1hZ2VMb2FkZXIgIT09IG5vb3BJbWFnZUxvYWRlciAmJiAhb3ZlcnNpemVkSW1hZ2U7XG4gIH1cbiAgLyoqXG4gICAqIFJldHVybnMgYW4gaW1hZ2UgdXJsIGZvcm1hdHRlZCBmb3IgdXNlIHdpdGggdGhlIENTUyBiYWNrZ3JvdW5kLWltYWdlIHByb3BlcnR5LiBFeHBlY3RzIG9uZSBvZjpcbiAgICogKiBBIGJhc2U2NCBlbmNvZGVkIGltYWdlLCB3aGljaCBpcyB3cmFwcGVkIGFuZCBwYXNzZWQgdGhyb3VnaC5cbiAgICogKiBBIGJvb2xlYW4uIElmIHRydWUsIGNhbGxzIHRoZSBpbWFnZSBsb2FkZXIgdG8gZ2VuZXJhdGUgYSBzbWFsbCBwbGFjZWhvbGRlciB1cmwuXG4gICAqL1xuICBnZW5lcmF0ZVBsYWNlaG9sZGVyKHBsYWNlaG9sZGVySW5wdXQpIHtcbiAgICBjb25zdCB7XG4gICAgICBwbGFjZWhvbGRlclJlc29sdXRpb25cbiAgICB9ID0gdGhpcy5jb25maWc7XG4gICAgaWYgKHBsYWNlaG9sZGVySW5wdXQgPT09IHRydWUpIHtcbiAgICAgIHJldHVybiBgdXJsKCR7dGhpcy5jYWxsSW1hZ2VMb2FkZXIoe1xuICAgICAgICBzcmM6IHRoaXMubmdTcmMsXG4gICAgICAgIHdpZHRoOiBwbGFjZWhvbGRlclJlc29sdXRpb24sXG4gICAgICAgIGlzUGxhY2Vob2xkZXI6IHRydWVcbiAgICAgIH0pfSlgO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHBsYWNlaG9sZGVySW5wdXQgPT09ICdzdHJpbmcnICYmIHBsYWNlaG9sZGVySW5wdXQuc3RhcnRzV2l0aCgnZGF0YTonKSkge1xuICAgICAgcmV0dXJuIGB1cmwoJHtwbGFjZWhvbGRlcklucHV0fSlgO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICAvKipcbiAgICogRGV0ZXJtaW5lcyBpZiBibHVyIHNob3VsZCBiZSBhcHBsaWVkLCBiYXNlZCBvbiBhbiBvcHRpb25hbCBib29sZWFuXG4gICAqIHByb3BlcnR5IGBibHVyYCB3aXRoaW4gdGhlIG9wdGlvbmFsIGNvbmZpZ3VyYXRpb24gb2JqZWN0IGBwbGFjZWhvbGRlckNvbmZpZ2AuXG4gICAqL1xuICBzaG91bGRCbHVyUGxhY2Vob2xkZXIocGxhY2Vob2xkZXJDb25maWcpIHtcbiAgICBpZiAoIXBsYWNlaG9sZGVyQ29uZmlnIHx8ICFwbGFjZWhvbGRlckNvbmZpZy5oYXNPd25Qcm9wZXJ0eSgnYmx1cicpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIEJvb2xlYW4ocGxhY2Vob2xkZXJDb25maWcuYmx1cik7XG4gIH1cbiAgcmVtb3ZlUGxhY2Vob2xkZXJPbkxvYWQoaW1nKSB7XG4gICAgY29uc3QgY2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICBjb25zdCBjaGFuZ2VEZXRlY3RvclJlZiA9IHRoaXMuaW5qZWN0b3IuZ2V0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgICAgIHJlbW92ZUxvYWRMaXN0ZW5lckZuKCk7XG4gICAgICByZW1vdmVFcnJvckxpc3RlbmVyRm4oKTtcbiAgICAgIHRoaXMucGxhY2Vob2xkZXIgPSBmYWxzZTtcbiAgICAgIGNoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgIH07XG4gICAgY29uc3QgcmVtb3ZlTG9hZExpc3RlbmVyRm4gPSB0aGlzLnJlbmRlcmVyLmxpc3RlbihpbWcsICdsb2FkJywgY2FsbGJhY2spO1xuICAgIGNvbnN0IHJlbW92ZUVycm9yTGlzdGVuZXJGbiA9IHRoaXMucmVuZGVyZXIubGlzdGVuKGltZywgJ2Vycm9yJywgY2FsbGJhY2spO1xuICB9XG4gIC8qKiBAbm9kb2MgKi9cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKG5nRGV2TW9kZSkge1xuICAgICAgaWYgKCF0aGlzLnByaW9yaXR5ICYmIHRoaXMuX3JlbmRlcmVkU3JjICE9PSBudWxsICYmIHRoaXMubGNwT2JzZXJ2ZXIgIT09IG51bGwpIHtcbiAgICAgICAgdGhpcy5sY3BPYnNlcnZlci51bnJlZ2lzdGVySW1hZ2UodGhpcy5fcmVuZGVyZWRTcmMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBzZXRIb3N0QXR0cmlidXRlKG5hbWUsIHZhbHVlKSB7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRBdHRyaWJ1dGUodGhpcy5pbWdFbGVtZW50LCBuYW1lLCB2YWx1ZSk7XG4gIH1cbiAgc3RhdGljIHtcbiAgICB0aGlzLsm1ZmFjID0gZnVuY3Rpb24gTmdPcHRpbWl6ZWRJbWFnZV9GYWN0b3J5KHQpIHtcbiAgICAgIHJldHVybiBuZXcgKHQgfHwgTmdPcHRpbWl6ZWRJbWFnZSkoKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWRpciA9IC8qIEBfX1BVUkVfXyAqL2kwLsm1ybVkZWZpbmVEaXJlY3RpdmUoe1xuICAgICAgdHlwZTogTmdPcHRpbWl6ZWRJbWFnZSxcbiAgICAgIHNlbGVjdG9yczogW1tcImltZ1wiLCBcIm5nU3JjXCIsIFwiXCJdXSxcbiAgICAgIGhvc3RWYXJzOiAxOCxcbiAgICAgIGhvc3RCaW5kaW5nczogZnVuY3Rpb24gTmdPcHRpbWl6ZWRJbWFnZV9Ib3N0QmluZGluZ3MocmYsIGN0eCkge1xuICAgICAgICBpZiAocmYgJiAyKSB7XG4gICAgICAgICAgaTAuybXJtXN0eWxlUHJvcChcInBvc2l0aW9uXCIsIGN0eC5maWxsID8gXCJhYnNvbHV0ZVwiIDogbnVsbCkoXCJ3aWR0aFwiLCBjdHguZmlsbCA/IFwiMTAwJVwiIDogbnVsbCkoXCJoZWlnaHRcIiwgY3R4LmZpbGwgPyBcIjEwMCVcIiA6IG51bGwpKFwiaW5zZXRcIiwgY3R4LmZpbGwgPyBcIjBcIiA6IG51bGwpKFwiYmFja2dyb3VuZC1zaXplXCIsIGN0eC5wbGFjZWhvbGRlciA/IFwiY292ZXJcIiA6IG51bGwpKFwiYmFja2dyb3VuZC1wb3NpdGlvblwiLCBjdHgucGxhY2Vob2xkZXIgPyBcIjUwJSA1MCVcIiA6IG51bGwpKFwiYmFja2dyb3VuZC1yZXBlYXRcIiwgY3R4LnBsYWNlaG9sZGVyID8gXCJuby1yZXBlYXRcIiA6IG51bGwpKFwiYmFja2dyb3VuZC1pbWFnZVwiLCBjdHgucGxhY2Vob2xkZXIgPyBjdHguZ2VuZXJhdGVQbGFjZWhvbGRlcihjdHgucGxhY2Vob2xkZXIpIDogbnVsbCkoXCJmaWx0ZXJcIiwgY3R4LnBsYWNlaG9sZGVyICYmIGN0eC5zaG91bGRCbHVyUGxhY2Vob2xkZXIoY3R4LnBsYWNlaG9sZGVyQ29uZmlnKSA/IFwiYmx1cigxNXB4KVwiIDogbnVsbCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBpbnB1dHM6IHtcbiAgICAgICAgbmdTcmM6IFsyLCBcIm5nU3JjXCIsIFwibmdTcmNcIiwgdW53cmFwU2FmZVVybF0sXG4gICAgICAgIG5nU3Jjc2V0OiBcIm5nU3Jjc2V0XCIsXG4gICAgICAgIHNpemVzOiBcInNpemVzXCIsXG4gICAgICAgIHdpZHRoOiBbMiwgXCJ3aWR0aFwiLCBcIndpZHRoXCIsIG51bWJlckF0dHJpYnV0ZV0sXG4gICAgICAgIGhlaWdodDogWzIsIFwiaGVpZ2h0XCIsIFwiaGVpZ2h0XCIsIG51bWJlckF0dHJpYnV0ZV0sXG4gICAgICAgIGxvYWRpbmc6IFwibG9hZGluZ1wiLFxuICAgICAgICBwcmlvcml0eTogWzIsIFwicHJpb3JpdHlcIiwgXCJwcmlvcml0eVwiLCBib29sZWFuQXR0cmlidXRlXSxcbiAgICAgICAgbG9hZGVyUGFyYW1zOiBcImxvYWRlclBhcmFtc1wiLFxuICAgICAgICBkaXNhYmxlT3B0aW1pemVkU3Jjc2V0OiBbMiwgXCJkaXNhYmxlT3B0aW1pemVkU3Jjc2V0XCIsIFwiZGlzYWJsZU9wdGltaXplZFNyY3NldFwiLCBib29sZWFuQXR0cmlidXRlXSxcbiAgICAgICAgZmlsbDogWzIsIFwiZmlsbFwiLCBcImZpbGxcIiwgYm9vbGVhbkF0dHJpYnV0ZV0sXG4gICAgICAgIHBsYWNlaG9sZGVyOiBbMiwgXCJwbGFjZWhvbGRlclwiLCBcInBsYWNlaG9sZGVyXCIsIGJvb2xlYW5PckRhdGFVcmxBdHRyaWJ1dGVdLFxuICAgICAgICBwbGFjZWhvbGRlckNvbmZpZzogXCJwbGFjZWhvbGRlckNvbmZpZ1wiLFxuICAgICAgICBzcmM6IFwic3JjXCIsXG4gICAgICAgIHNyY3NldDogXCJzcmNzZXRcIlxuICAgICAgfSxcbiAgICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgICBmZWF0dXJlczogW2kwLsm1ybVJbnB1dFRyYW5zZm9ybXNGZWF0dXJlLCBpMC7Jtcm1TmdPbkNoYW5nZXNGZWF0dXJlXVxuICAgIH0pO1xuICB9XG59XG4oKCkgPT4ge1xuICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCBuZ0Rldk1vZGUpICYmIGkwLsm1c2V0Q2xhc3NNZXRhZGF0YShOZ09wdGltaXplZEltYWdlLCBbe1xuICAgIHR5cGU6IERpcmVjdGl2ZSxcbiAgICBhcmdzOiBbe1xuICAgICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICAgIHNlbGVjdG9yOiAnaW1nW25nU3JjXScsXG4gICAgICBob3N0OiB7XG4gICAgICAgICdbc3R5bGUucG9zaXRpb25dJzogJ2ZpbGwgPyBcImFic29sdXRlXCIgOiBudWxsJyxcbiAgICAgICAgJ1tzdHlsZS53aWR0aF0nOiAnZmlsbCA/IFwiMTAwJVwiIDogbnVsbCcsXG4gICAgICAgICdbc3R5bGUuaGVpZ2h0XSc6ICdmaWxsID8gXCIxMDAlXCIgOiBudWxsJyxcbiAgICAgICAgJ1tzdHlsZS5pbnNldF0nOiAnZmlsbCA/IFwiMFwiIDogbnVsbCcsXG4gICAgICAgICdbc3R5bGUuYmFja2dyb3VuZC1zaXplXSc6ICdwbGFjZWhvbGRlciA/IFwiY292ZXJcIiA6IG51bGwnLFxuICAgICAgICAnW3N0eWxlLmJhY2tncm91bmQtcG9zaXRpb25dJzogJ3BsYWNlaG9sZGVyID8gXCI1MCUgNTAlXCIgOiBudWxsJyxcbiAgICAgICAgJ1tzdHlsZS5iYWNrZ3JvdW5kLXJlcGVhdF0nOiAncGxhY2Vob2xkZXIgPyBcIm5vLXJlcGVhdFwiIDogbnVsbCcsXG4gICAgICAgICdbc3R5bGUuYmFja2dyb3VuZC1pbWFnZV0nOiAncGxhY2Vob2xkZXIgPyBnZW5lcmF0ZVBsYWNlaG9sZGVyKHBsYWNlaG9sZGVyKSA6IG51bGwnLFxuICAgICAgICAnW3N0eWxlLmZpbHRlcl0nOiBgcGxhY2Vob2xkZXIgJiYgc2hvdWxkQmx1clBsYWNlaG9sZGVyKHBsYWNlaG9sZGVyQ29uZmlnKSA/IFwiYmx1cigke1BMQUNFSE9MREVSX0JMVVJfQU1PVU5UfXB4KVwiIDogbnVsbGBcbiAgICAgIH1cbiAgICB9XVxuICB9XSwgbnVsbCwge1xuICAgIG5nU3JjOiBbe1xuICAgICAgdHlwZTogSW5wdXQsXG4gICAgICBhcmdzOiBbe1xuICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgdHJhbnNmb3JtOiB1bndyYXBTYWZlVXJsXG4gICAgICB9XVxuICAgIH1dLFxuICAgIG5nU3Jjc2V0OiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XSxcbiAgICBzaXplczogW3tcbiAgICAgIHR5cGU6IElucHV0XG4gICAgfV0sXG4gICAgd2lkdGg6IFt7XG4gICAgICB0eXBlOiBJbnB1dCxcbiAgICAgIGFyZ3M6IFt7XG4gICAgICAgIHRyYW5zZm9ybTogbnVtYmVyQXR0cmlidXRlXG4gICAgICB9XVxuICAgIH1dLFxuICAgIGhlaWdodDogW3tcbiAgICAgIHR5cGU6IElucHV0LFxuICAgICAgYXJnczogW3tcbiAgICAgICAgdHJhbnNmb3JtOiBudW1iZXJBdHRyaWJ1dGVcbiAgICAgIH1dXG4gICAgfV0sXG4gICAgbG9hZGluZzogW3tcbiAgICAgIHR5cGU6IElucHV0XG4gICAgfV0sXG4gICAgcHJpb3JpdHk6IFt7XG4gICAgICB0eXBlOiBJbnB1dCxcbiAgICAgIGFyZ3M6IFt7XG4gICAgICAgIHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZVxuICAgICAgfV1cbiAgICB9XSxcbiAgICBsb2FkZXJQYXJhbXM6IFt7XG4gICAgICB0eXBlOiBJbnB1dFxuICAgIH1dLFxuICAgIGRpc2FibGVPcHRpbWl6ZWRTcmNzZXQ6IFt7XG4gICAgICB0eXBlOiBJbnB1dCxcbiAgICAgIGFyZ3M6IFt7XG4gICAgICAgIHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZVxuICAgICAgfV1cbiAgICB9XSxcbiAgICBmaWxsOiBbe1xuICAgICAgdHlwZTogSW5wdXQsXG4gICAgICBhcmdzOiBbe1xuICAgICAgICB0cmFuc2Zvcm06IGJvb2xlYW5BdHRyaWJ1dGVcbiAgICAgIH1dXG4gICAgfV0sXG4gICAgcGxhY2Vob2xkZXI6IFt7XG4gICAgICB0eXBlOiBJbnB1dCxcbiAgICAgIGFyZ3M6IFt7XG4gICAgICAgIHRyYW5zZm9ybTogYm9vbGVhbk9yRGF0YVVybEF0dHJpYnV0ZVxuICAgICAgfV1cbiAgICB9XSxcbiAgICBwbGFjZWhvbGRlckNvbmZpZzogW3tcbiAgICAgIHR5cGU6IElucHV0XG4gICAgfV0sXG4gICAgc3JjOiBbe1xuICAgICAgdHlwZTogSW5wdXRcbiAgICB9XSxcbiAgICBzcmNzZXQ6IFt7XG4gICAgICB0eXBlOiBJbnB1dFxuICAgIH1dXG4gIH0pO1xufSkoKTtcbi8qKioqKiBIZWxwZXJzICoqKioqL1xuLyoqXG4gKiBTb3J0cyBwcm92aWRlZCBjb25maWcgYnJlYWtwb2ludHMgYW5kIHVzZXMgZGVmYXVsdHMuXG4gKi9cbmZ1bmN0aW9uIHByb2Nlc3NDb25maWcoY29uZmlnKSB7XG4gIGxldCBzb3J0ZWRCcmVha3BvaW50cyA9IHt9O1xuICBpZiAoY29uZmlnLmJyZWFrcG9pbnRzKSB7XG4gICAgc29ydGVkQnJlYWtwb2ludHMuYnJlYWtwb2ludHMgPSBjb25maWcuYnJlYWtwb2ludHMuc29ydCgoYSwgYikgPT4gYSAtIGIpO1xuICB9XG4gIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCDJtUlNQUdFX0NPTkZJR19ERUZBVUxUUywgY29uZmlnLCBzb3J0ZWRCcmVha3BvaW50cyk7XG59XG4vKioqKiogQXNzZXJ0IGZ1bmN0aW9ucyAqKioqKi9cbi8qKlxuICogVmVyaWZpZXMgdGhhdCB0aGVyZSBpcyBubyBgc3JjYCBzZXQgb24gYSBob3N0IGVsZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydE5vQ29uZmxpY3RpbmdTcmMoZGlyKSB7XG4gIGlmIChkaXIuc3JjKSB7XG4gICAgdGhyb3cgbmV3IMm1UnVudGltZUVycm9yKDI5NTAgLyogUnVudGltZUVycm9yQ29kZS5VTkVYUEVDVEVEX1NSQ19BVFRSICovLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IGJvdGggXFxgc3JjXFxgIGFuZCBcXGBuZ1NyY1xcYCBoYXZlIGJlZW4gc2V0LiBgICsgYFN1cHBseWluZyBib3RoIG9mIHRoZXNlIGF0dHJpYnV0ZXMgYnJlYWtzIGxhenkgbG9hZGluZy4gYCArIGBUaGUgTmdPcHRpbWl6ZWRJbWFnZSBkaXJlY3RpdmUgc2V0cyBcXGBzcmNcXGAgaXRzZWxmIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiBcXGBuZ1NyY1xcYC4gYCArIGBUbyBmaXggdGhpcywgcGxlYXNlIHJlbW92ZSB0aGUgXFxgc3JjXFxgIGF0dHJpYnV0ZS5gKTtcbiAgfVxufVxuLyoqXG4gKiBWZXJpZmllcyB0aGF0IHRoZXJlIGlzIG5vIGBzcmNzZXRgIHNldCBvbiBhIGhvc3QgZWxlbWVudC5cbiAqL1xuZnVuY3Rpb24gYXNzZXJ0Tm9Db25mbGljdGluZ1NyY3NldChkaXIpIHtcbiAgaWYgKGRpci5zcmNzZXQpIHtcbiAgICB0aHJvdyBuZXcgybVSdW50aW1lRXJyb3IoMjk1MSAvKiBSdW50aW1lRXJyb3JDb2RlLlVORVhQRUNURURfU1JDU0VUX0FUVFIgKi8sIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gYm90aCBcXGBzcmNzZXRcXGAgYW5kIFxcYG5nU3Jjc2V0XFxgIGhhdmUgYmVlbiBzZXQuIGAgKyBgU3VwcGx5aW5nIGJvdGggb2YgdGhlc2UgYXR0cmlidXRlcyBicmVha3MgbGF6eSBsb2FkaW5nLiBgICsgYFRoZSBOZ09wdGltaXplZEltYWdlIGRpcmVjdGl2ZSBzZXRzIFxcYHNyY3NldFxcYCBpdHNlbGYgYmFzZWQgb24gdGhlIHZhbHVlIG9mIGAgKyBgXFxgbmdTcmNzZXRcXGAuIFRvIGZpeCB0aGlzLCBwbGVhc2UgcmVtb3ZlIHRoZSBcXGBzcmNzZXRcXGAgYXR0cmlidXRlLmApO1xuICB9XG59XG4vKipcbiAqIFZlcmlmaWVzIHRoYXQgdGhlIGBuZ1NyY2AgaXMgbm90IGEgQmFzZTY0LWVuY29kZWQgaW1hZ2UuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydE5vdEJhc2U2NEltYWdlKGRpcikge1xuICBsZXQgbmdTcmMgPSBkaXIubmdTcmMudHJpbSgpO1xuICBpZiAobmdTcmMuc3RhcnRzV2l0aCgnZGF0YTonKSkge1xuICAgIGlmIChuZ1NyYy5sZW5ndGggPiBCQVNFNjRfSU1HX01BWF9MRU5HVEhfSU5fRVJST1IpIHtcbiAgICAgIG5nU3JjID0gbmdTcmMuc3Vic3RyaW5nKDAsIEJBU0U2NF9JTUdfTUFYX0xFTkdUSF9JTl9FUlJPUikgKyAnLi4uJztcbiAgICB9XG4gICAgdGhyb3cgbmV3IMm1UnVudGltZUVycm9yKDI5NTIgLyogUnVudGltZUVycm9yQ29kZS5JTlZBTElEX0lOUFVUICovLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYywgZmFsc2UpfSBcXGBuZ1NyY1xcYCBpcyBhIEJhc2U2NC1lbmNvZGVkIHN0cmluZyBgICsgYCgke25nU3JjfSkuIE5nT3B0aW1pemVkSW1hZ2UgZG9lcyBub3Qgc3VwcG9ydCBCYXNlNjQtZW5jb2RlZCBzdHJpbmdzLiBgICsgYFRvIGZpeCB0aGlzLCBkaXNhYmxlIHRoZSBOZ09wdGltaXplZEltYWdlIGRpcmVjdGl2ZSBmb3IgdGhpcyBlbGVtZW50IGAgKyBgYnkgcmVtb3ZpbmcgXFxgbmdTcmNcXGAgYW5kIHVzaW5nIGEgc3RhbmRhcmQgXFxgc3JjXFxgIGF0dHJpYnV0ZSBpbnN0ZWFkLmApO1xuICB9XG59XG4vKipcbiAqIFZlcmlmaWVzIHRoYXQgdGhlICdzaXplcycgb25seSBpbmNsdWRlcyByZXNwb25zaXZlIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gYXNzZXJ0Tm9Db21wbGV4U2l6ZXMoZGlyKSB7XG4gIGxldCBzaXplcyA9IGRpci5zaXplcztcbiAgaWYgKHNpemVzPy5tYXRjaCgvKChcXCl8LClcXHN8XilcXGQrcHgvKSkge1xuICAgIHRocm93IG5ldyDJtVJ1bnRpbWVFcnJvcigyOTUyIC8qIFJ1bnRpbWVFcnJvckNvZGUuSU5WQUxJRF9JTlBVVCAqLywgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMsIGZhbHNlKX0gXFxgc2l6ZXNcXGAgd2FzIHNldCB0byBhIHN0cmluZyBpbmNsdWRpbmcgYCArIGBwaXhlbCB2YWx1ZXMuIEZvciBhdXRvbWF0aWMgXFxgc3Jjc2V0XFxgIGdlbmVyYXRpb24sIFxcYHNpemVzXFxgIG11c3Qgb25seSBpbmNsdWRlIHJlc3BvbnNpdmUgYCArIGB2YWx1ZXMsIHN1Y2ggYXMgXFxgc2l6ZXM9XCI1MHZ3XCJcXGAgb3IgXFxgc2l6ZXM9XCIobWluLXdpZHRoOiA3NjhweCkgNTB2dywgMTAwdndcIlxcYC4gYCArIGBUbyBmaXggdGhpcywgbW9kaWZ5IHRoZSBcXGBzaXplc1xcYCBhdHRyaWJ1dGUsIG9yIHByb3ZpZGUgeW91ciBvd24gXFxgbmdTcmNzZXRcXGAgdmFsdWUgZGlyZWN0bHkuYCk7XG4gIH1cbn1cbmZ1bmN0aW9uIGFzc2VydFZhbGlkUGxhY2Vob2xkZXIoZGlyLCBpbWFnZUxvYWRlcikge1xuICBhc3NlcnROb1BsYWNlaG9sZGVyQ29uZmlnV2l0aG91dFBsYWNlaG9sZGVyKGRpcik7XG4gIGFzc2VydE5vUmVsYXRpdmVQbGFjZWhvbGRlcldpdGhvdXRMb2FkZXIoZGlyLCBpbWFnZUxvYWRlcik7XG4gIGFzc2VydE5vT3ZlcnNpemVkRGF0YVVybChkaXIpO1xufVxuLyoqXG4gKiBWZXJpZmllcyB0aGF0IHBsYWNlaG9sZGVyQ29uZmlnIGlzbid0IGJlaW5nIHVzZWQgd2l0aG91dCBwbGFjZWhvbGRlclxuICovXG5mdW5jdGlvbiBhc3NlcnROb1BsYWNlaG9sZGVyQ29uZmlnV2l0aG91dFBsYWNlaG9sZGVyKGRpcikge1xuICBpZiAoZGlyLnBsYWNlaG9sZGVyQ29uZmlnICYmICFkaXIucGxhY2Vob2xkZXIpIHtcbiAgICB0aHJvdyBuZXcgybVSdW50aW1lRXJyb3IoMjk1MiAvKiBSdW50aW1lRXJyb3JDb2RlLklOVkFMSURfSU5QVVQgKi8sIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjLCBmYWxzZSl9IFxcYHBsYWNlaG9sZGVyQ29uZmlnXFxgIG9wdGlvbnMgd2VyZSBwcm92aWRlZCBmb3IgYW4gYCArIGBpbWFnZSB0aGF0IGRvZXMgbm90IHVzZSB0aGUgXFxgcGxhY2Vob2xkZXJcXGAgYXR0cmlidXRlLCBhbmQgd2lsbCBoYXZlIG5vIGVmZmVjdC5gKTtcbiAgfVxufVxuLyoqXG4gKiBXYXJucyBpZiBhIHJlbGF0aXZlIFVSTCBwbGFjZWhvbGRlciBpcyBzcGVjaWZpZWQsIGJ1dCBubyBsb2FkZXIgaXMgcHJlc2VudCB0byBwcm92aWRlIHRoZSBzbWFsbFxuICogaW1hZ2UuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydE5vUmVsYXRpdmVQbGFjZWhvbGRlcldpdGhvdXRMb2FkZXIoZGlyLCBpbWFnZUxvYWRlcikge1xuICBpZiAoZGlyLnBsYWNlaG9sZGVyID09PSB0cnVlICYmIGltYWdlTG9hZGVyID09PSBub29wSW1hZ2VMb2FkZXIpIHtcbiAgICB0aHJvdyBuZXcgybVSdW50aW1lRXJyb3IoMjk2MyAvKiBSdW50aW1lRXJyb3JDb2RlLk1JU1NJTkdfTkVDRVNTQVJZX0xPQURFUiAqLywgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSB0aGUgXFxgcGxhY2Vob2xkZXJcXGAgYXR0cmlidXRlIGlzIHNldCB0byB0cnVlIGJ1dCBgICsgYG5vIGltYWdlIGxvYWRlciBpcyBjb25maWd1cmVkIChpLmUuIHRoZSBkZWZhdWx0IG9uZSBpcyBiZWluZyB1c2VkKSwgYCArIGB3aGljaCB3b3VsZCByZXN1bHQgaW4gdGhlIHNhbWUgaW1hZ2UgYmVpbmcgdXNlZCBmb3IgdGhlIHByaW1hcnkgaW1hZ2UgYW5kIGl0cyBwbGFjZWhvbGRlci4gYCArIGBUbyBmaXggdGhpcywgcHJvdmlkZSBhIGxvYWRlciBvciByZW1vdmUgdGhlIFxcYHBsYWNlaG9sZGVyXFxgIGF0dHJpYnV0ZSBmcm9tIHRoZSBpbWFnZS5gKTtcbiAgfVxufVxuLyoqXG4gKiBXYXJucyBvciB0aHJvd3MgYW4gZXJyb3IgaWYgYW4gb3ZlcnNpemVkIGRhdGFVUkwgcGxhY2Vob2xkZXIgaXMgcHJvdmlkZWQuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydE5vT3ZlcnNpemVkRGF0YVVybChkaXIpIHtcbiAgaWYgKGRpci5wbGFjZWhvbGRlciAmJiB0eXBlb2YgZGlyLnBsYWNlaG9sZGVyID09PSAnc3RyaW5nJyAmJiBkaXIucGxhY2Vob2xkZXIuc3RhcnRzV2l0aCgnZGF0YTonKSkge1xuICAgIGlmIChkaXIucGxhY2Vob2xkZXIubGVuZ3RoID4gREFUQV9VUkxfRVJST1JfTElNSVQpIHtcbiAgICAgIHRocm93IG5ldyDJtVJ1bnRpbWVFcnJvcigyOTY1IC8qIFJ1bnRpbWVFcnJvckNvZGUuT1ZFUlNJWkVEX1BMQUNFSE9MREVSICovLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IHRoZSBcXGBwbGFjZWhvbGRlclxcYCBhdHRyaWJ1dGUgaXMgc2V0IHRvIGEgZGF0YSBVUkwgd2hpY2ggaXMgbG9uZ2VyIGAgKyBgdGhhbiAke0RBVEFfVVJMX0VSUk9SX0xJTUlUfSBjaGFyYWN0ZXJzLiBUaGlzIGlzIHN0cm9uZ2x5IGRpc2NvdXJhZ2VkLCBhcyBsYXJnZSBpbmxpbmUgcGxhY2Vob2xkZXJzIGAgKyBgZGlyZWN0bHkgaW5jcmVhc2UgdGhlIGJ1bmRsZSBzaXplIG9mIEFuZ3VsYXIgYW5kIGh1cnQgcGFnZSBsb2FkIHBlcmZvcm1hbmNlLiBUbyBmaXggdGhpcywgZ2VuZXJhdGUgYCArIGBhIHNtYWxsZXIgZGF0YSBVUkwgcGxhY2Vob2xkZXIuYCk7XG4gICAgfVxuICAgIGlmIChkaXIucGxhY2Vob2xkZXIubGVuZ3RoID4gREFUQV9VUkxfV0FSTl9MSU1JVCkge1xuICAgICAgY29uc29sZS53YXJuKMm1Zm9ybWF0UnVudGltZUVycm9yKDI5NjUgLyogUnVudGltZUVycm9yQ29kZS5PVkVSU0laRURfUExBQ0VIT0xERVIgKi8sIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gdGhlIFxcYHBsYWNlaG9sZGVyXFxgIGF0dHJpYnV0ZSBpcyBzZXQgdG8gYSBkYXRhIFVSTCB3aGljaCBpcyBsb25nZXIgYCArIGB0aGFuICR7REFUQV9VUkxfV0FSTl9MSU1JVH0gY2hhcmFjdGVycy4gVGhpcyBpcyBkaXNjb3VyYWdlZCwgYXMgbGFyZ2UgaW5saW5lIHBsYWNlaG9sZGVycyBgICsgYGRpcmVjdGx5IGluY3JlYXNlIHRoZSBidW5kbGUgc2l6ZSBvZiBBbmd1bGFyIGFuZCBodXJ0IHBhZ2UgbG9hZCBwZXJmb3JtYW5jZS4gRm9yIGJldHRlciBsb2FkaW5nIHBlcmZvcm1hbmNlLCBgICsgYGdlbmVyYXRlIGEgc21hbGxlciBkYXRhIFVSTCBwbGFjZWhvbGRlci5gKSk7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIFZlcmlmaWVzIHRoYXQgdGhlIGBuZ1NyY2AgaXMgbm90IGEgQmxvYiBVUkwuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydE5vdEJsb2JVcmwoZGlyKSB7XG4gIGNvbnN0IG5nU3JjID0gZGlyLm5nU3JjLnRyaW0oKTtcbiAgaWYgKG5nU3JjLnN0YXJ0c1dpdGgoJ2Jsb2I6JykpIHtcbiAgICB0aHJvdyBuZXcgybVSdW50aW1lRXJyb3IoMjk1MiAvKiBSdW50aW1lRXJyb3JDb2RlLklOVkFMSURfSU5QVVQgKi8sIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gXFxgbmdTcmNcXGAgd2FzIHNldCB0byBhIGJsb2IgVVJMICgke25nU3JjfSkuIGAgKyBgQmxvYiBVUkxzIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBOZ09wdGltaXplZEltYWdlIGRpcmVjdGl2ZS4gYCArIGBUbyBmaXggdGhpcywgZGlzYWJsZSB0aGUgTmdPcHRpbWl6ZWRJbWFnZSBkaXJlY3RpdmUgZm9yIHRoaXMgZWxlbWVudCBgICsgYGJ5IHJlbW92aW5nIFxcYG5nU3JjXFxgIGFuZCB1c2luZyBhIHJlZ3VsYXIgXFxgc3JjXFxgIGF0dHJpYnV0ZSBpbnN0ZWFkLmApO1xuICB9XG59XG4vKipcbiAqIFZlcmlmaWVzIHRoYXQgdGhlIGlucHV0IGlzIHNldCB0byBhIG5vbi1lbXB0eSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydE5vbkVtcHR5SW5wdXQoZGlyLCBuYW1lLCB2YWx1ZSkge1xuICBjb25zdCBpc1N0cmluZyA9IHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZyc7XG4gIGNvbnN0IGlzRW1wdHlTdHJpbmcgPSBpc1N0cmluZyAmJiB2YWx1ZS50cmltKCkgPT09ICcnO1xuICBpZiAoIWlzU3RyaW5nIHx8IGlzRW1wdHlTdHJpbmcpIHtcbiAgICB0aHJvdyBuZXcgybVSdW50aW1lRXJyb3IoMjk1MiAvKiBSdW50aW1lRXJyb3JDb2RlLklOVkFMSURfSU5QVVQgKi8sIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gXFxgJHtuYW1lfVxcYCBoYXMgYW4gaW52YWxpZCB2YWx1ZSBgICsgYChcXGAke3ZhbHVlfVxcYCkuIFRvIGZpeCB0aGlzLCBjaGFuZ2UgdGhlIHZhbHVlIHRvIGEgbm9uLWVtcHR5IHN0cmluZy5gKTtcbiAgfVxufVxuLyoqXG4gKiBWZXJpZmllcyB0aGF0IHRoZSBgbmdTcmNzZXRgIGlzIGluIGEgdmFsaWQgZm9ybWF0LCBlLmcuIFwiMTAwdywgMjAwd1wiIG9yIFwiMXgsIDJ4XCIuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydFZhbGlkTmdTcmNzZXQoZGlyLCB2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gbnVsbCkgcmV0dXJuO1xuICBhc3NlcnROb25FbXB0eUlucHV0KGRpciwgJ25nU3Jjc2V0JywgdmFsdWUpO1xuICBjb25zdCBzdHJpbmdWYWwgPSB2YWx1ZTtcbiAgY29uc3QgaXNWYWxpZFdpZHRoRGVzY3JpcHRvciA9IFZBTElEX1dJRFRIX0RFU0NSSVBUT1JfU1JDU0VULnRlc3Qoc3RyaW5nVmFsKTtcbiAgY29uc3QgaXNWYWxpZERlbnNpdHlEZXNjcmlwdG9yID0gVkFMSURfREVOU0lUWV9ERVNDUklQVE9SX1NSQ1NFVC50ZXN0KHN0cmluZ1ZhbCk7XG4gIGlmIChpc1ZhbGlkRGVuc2l0eURlc2NyaXB0b3IpIHtcbiAgICBhc3NlcnRVbmRlckRlbnNpdHlDYXAoZGlyLCBzdHJpbmdWYWwpO1xuICB9XG4gIGNvbnN0IGlzVmFsaWRTcmNzZXQgPSBpc1ZhbGlkV2lkdGhEZXNjcmlwdG9yIHx8IGlzVmFsaWREZW5zaXR5RGVzY3JpcHRvcjtcbiAgaWYgKCFpc1ZhbGlkU3Jjc2V0KSB7XG4gICAgdGhyb3cgbmV3IMm1UnVudGltZUVycm9yKDI5NTIgLyogUnVudGltZUVycm9yQ29kZS5JTlZBTElEX0lOUFVUICovLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IFxcYG5nU3Jjc2V0XFxgIGhhcyBhbiBpbnZhbGlkIHZhbHVlIChcXGAke3ZhbHVlfVxcYCkuIGAgKyBgVG8gZml4IHRoaXMsIHN1cHBseSBcXGBuZ1NyY3NldFxcYCB1c2luZyBhIGNvbW1hLXNlcGFyYXRlZCBsaXN0IG9mIG9uZSBvciBtb3JlIHdpZHRoIGAgKyBgZGVzY3JpcHRvcnMgKGUuZy4gXCIxMDB3LCAyMDB3XCIpIG9yIGRlbnNpdHkgZGVzY3JpcHRvcnMgKGUuZy4gXCIxeCwgMnhcIikuYCk7XG4gIH1cbn1cbmZ1bmN0aW9uIGFzc2VydFVuZGVyRGVuc2l0eUNhcChkaXIsIHZhbHVlKSB7XG4gIGNvbnN0IHVuZGVyRGVuc2l0eUNhcCA9IHZhbHVlLnNwbGl0KCcsJykuZXZlcnkobnVtID0+IG51bSA9PT0gJycgfHwgcGFyc2VGbG9hdChudW0pIDw9IEFCU09MVVRFX1NSQ1NFVF9ERU5TSVRZX0NBUCk7XG4gIGlmICghdW5kZXJEZW5zaXR5Q2FwKSB7XG4gICAgdGhyb3cgbmV3IMm1UnVudGltZUVycm9yKDI5NTIgLyogUnVudGltZUVycm9yQ29kZS5JTlZBTElEX0lOUFVUICovLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IHRoZSBcXGBuZ1NyY3NldFxcYCBjb250YWlucyBhbiB1bnN1cHBvcnRlZCBpbWFnZSBkZW5zaXR5OmAgKyBgXFxgJHt2YWx1ZX1cXGAuIE5nT3B0aW1pemVkSW1hZ2UgZ2VuZXJhbGx5IHJlY29tbWVuZHMgYSBtYXggaW1hZ2UgZGVuc2l0eSBvZiBgICsgYCR7UkVDT01NRU5ERURfU1JDU0VUX0RFTlNJVFlfQ0FQfXggYnV0IHN1cHBvcnRzIGltYWdlIGRlbnNpdGllcyB1cCB0byBgICsgYCR7QUJTT0xVVEVfU1JDU0VUX0RFTlNJVFlfQ0FQfXguIFRoZSBodW1hbiBleWUgY2Fubm90IGRpc3Rpbmd1aXNoIGJldHdlZW4gaW1hZ2UgZGVuc2l0aWVzIGAgKyBgZ3JlYXRlciB0aGFuICR7UkVDT01NRU5ERURfU1JDU0VUX0RFTlNJVFlfQ0FQfXggLSB3aGljaCBtYWtlcyB0aGVtIHVubmVjZXNzYXJ5IGZvciBgICsgYG1vc3QgdXNlIGNhc2VzLiBJbWFnZXMgdGhhdCB3aWxsIGJlIHBpbmNoLXpvb21lZCBhcmUgdHlwaWNhbGx5IHRoZSBwcmltYXJ5IHVzZSBjYXNlIGZvciBgICsgYCR7QUJTT0xVVEVfU1JDU0VUX0RFTlNJVFlfQ0FQfXggaW1hZ2VzLiBQbGVhc2UgcmVtb3ZlIHRoZSBoaWdoIGRlbnNpdHkgZGVzY3JpcHRvciBhbmQgdHJ5IGFnYWluLmApO1xuICB9XG59XG4vKipcbiAqIENyZWF0ZXMgYSBgUnVudGltZUVycm9yYCBpbnN0YW5jZSB0byByZXByZXNlbnQgYSBzaXR1YXRpb24gd2hlbiBhbiBpbnB1dCBpcyBzZXQgYWZ0ZXJcbiAqIHRoZSBkaXJlY3RpdmUgaGFzIGluaXRpYWxpemVkLlxuICovXG5mdW5jdGlvbiBwb3N0SW5pdElucHV0Q2hhbmdlRXJyb3IoZGlyLCBpbnB1dE5hbWUpIHtcbiAgbGV0IHJlYXNvbjtcbiAgaWYgKGlucHV0TmFtZSA9PT0gJ3dpZHRoJyB8fCBpbnB1dE5hbWUgPT09ICdoZWlnaHQnKSB7XG4gICAgcmVhc29uID0gYENoYW5naW5nIFxcYCR7aW5wdXROYW1lfVxcYCBtYXkgcmVzdWx0IGluIGRpZmZlcmVudCBhdHRyaWJ1dGUgdmFsdWUgYCArIGBhcHBsaWVkIHRvIHRoZSB1bmRlcmx5aW5nIGltYWdlIGVsZW1lbnQgYW5kIGNhdXNlIGxheW91dCBzaGlmdHMgb24gYSBwYWdlLmA7XG4gIH0gZWxzZSB7XG4gICAgcmVhc29uID0gYENoYW5naW5nIHRoZSBcXGAke2lucHV0TmFtZX1cXGAgd291bGQgaGF2ZSBubyBlZmZlY3Qgb24gdGhlIHVuZGVybHlpbmcgYCArIGBpbWFnZSBlbGVtZW50LCBiZWNhdXNlIHRoZSByZXNvdXJjZSBsb2FkaW5nIGhhcyBhbHJlYWR5IG9jY3VycmVkLmA7XG4gIH1cbiAgcmV0dXJuIG5ldyDJtVJ1bnRpbWVFcnJvcigyOTUzIC8qIFJ1bnRpbWVFcnJvckNvZGUuVU5FWFBFQ1RFRF9JTlBVVF9DSEFOR0UgKi8sIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gXFxgJHtpbnB1dE5hbWV9XFxgIHdhcyB1cGRhdGVkIGFmdGVyIGluaXRpYWxpemF0aW9uLiBgICsgYFRoZSBOZ09wdGltaXplZEltYWdlIGRpcmVjdGl2ZSB3aWxsIG5vdCByZWFjdCB0byB0aGlzIGlucHV0IGNoYW5nZS4gJHtyZWFzb259IGAgKyBgVG8gZml4IHRoaXMsIGVpdGhlciBzd2l0Y2ggXFxgJHtpbnB1dE5hbWV9XFxgIHRvIGEgc3RhdGljIHZhbHVlIGAgKyBgb3Igd3JhcCB0aGUgaW1hZ2UgZWxlbWVudCBpbiBhbiAqbmdJZiB0aGF0IGlzIGdhdGVkIG9uIHRoZSBuZWNlc3NhcnkgdmFsdWUuYCk7XG59XG4vKipcbiAqIFZlcmlmeSB0aGF0IG5vbmUgb2YgdGhlIGxpc3RlZCBpbnB1dHMgaGFzIGNoYW5nZWQuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydE5vUG9zdEluaXRJbnB1dENoYW5nZShkaXIsIGNoYW5nZXMsIGlucHV0cykge1xuICBpbnB1dHMuZm9yRWFjaChpbnB1dCA9PiB7XG4gICAgY29uc3QgaXNVcGRhdGVkID0gY2hhbmdlcy5oYXNPd25Qcm9wZXJ0eShpbnB1dCk7XG4gICAgaWYgKGlzVXBkYXRlZCAmJiAhY2hhbmdlc1tpbnB1dF0uaXNGaXJzdENoYW5nZSgpKSB7XG4gICAgICBpZiAoaW5wdXQgPT09ICduZ1NyYycpIHtcbiAgICAgICAgLy8gV2hlbiB0aGUgYG5nU3JjYCBpbnB1dCBjaGFuZ2VzLCB3ZSBkZXRlY3QgdGhhdCBvbmx5IGluIHRoZVxuICAgICAgICAvLyBgbmdPbkNoYW5nZXNgIGhvb2ssIHRodXMgdGhlIGBuZ1NyY2AgaXMgYWxyZWFkeSBzZXQuIFdlIHVzZVxuICAgICAgICAvLyBgbmdTcmNgIGluIHRoZSBlcnJvciBtZXNzYWdlLCBzbyB3ZSB1c2UgYSBwcmV2aW91cyB2YWx1ZSwgYnV0XG4gICAgICAgIC8vIG5vdCB0aGUgdXBkYXRlZCBvbmUgaW4gaXQuXG4gICAgICAgIGRpciA9IHtcbiAgICAgICAgICBuZ1NyYzogY2hhbmdlc1tpbnB1dF0ucHJldmlvdXNWYWx1ZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgdGhyb3cgcG9zdEluaXRJbnB1dENoYW5nZUVycm9yKGRpciwgaW5wdXQpO1xuICAgIH1cbiAgfSk7XG59XG4vKipcbiAqIFZlcmlmaWVzIHRoYXQgYSBzcGVjaWZpZWQgaW5wdXQgaXMgYSBudW1iZXIgZ3JlYXRlciB0aGFuIDAuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydEdyZWF0ZXJUaGFuWmVybyhkaXIsIGlucHV0VmFsdWUsIGlucHV0TmFtZSkge1xuICBjb25zdCB2YWxpZE51bWJlciA9IHR5cGVvZiBpbnB1dFZhbHVlID09PSAnbnVtYmVyJyAmJiBpbnB1dFZhbHVlID4gMDtcbiAgY29uc3QgdmFsaWRTdHJpbmcgPSB0eXBlb2YgaW5wdXRWYWx1ZSA9PT0gJ3N0cmluZycgJiYgL15cXGQrJC8udGVzdChpbnB1dFZhbHVlLnRyaW0oKSkgJiYgcGFyc2VJbnQoaW5wdXRWYWx1ZSkgPiAwO1xuICBpZiAoIXZhbGlkTnVtYmVyICYmICF2YWxpZFN0cmluZykge1xuICAgIHRocm93IG5ldyDJtVJ1bnRpbWVFcnJvcigyOTUyIC8qIFJ1bnRpbWVFcnJvckNvZGUuSU5WQUxJRF9JTlBVVCAqLywgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSBcXGAke2lucHV0TmFtZX1cXGAgaGFzIGFuIGludmFsaWQgdmFsdWUuIGAgKyBgVG8gZml4IHRoaXMsIHByb3ZpZGUgXFxgJHtpbnB1dE5hbWV9XFxgIGFzIGEgbnVtYmVyIGdyZWF0ZXIgdGhhbiAwLmApO1xuICB9XG59XG4vKipcbiAqIFZlcmlmaWVzIHRoYXQgdGhlIHJlbmRlcmVkIGltYWdlIGlzIG5vdCB2aXN1YWxseSBkaXN0b3J0ZWQuIEVmZmVjdGl2ZWx5IHRoaXMgaXMgY2hlY2tpbmc6XG4gKiAtIFdoZXRoZXIgdGhlIFwid2lkdGhcIiBhbmQgXCJoZWlnaHRcIiBhdHRyaWJ1dGVzIHJlZmxlY3QgdGhlIGFjdHVhbCBkaW1lbnNpb25zIG9mIHRoZSBpbWFnZS5cbiAqIC0gV2hldGhlciBpbWFnZSBzdHlsaW5nIGlzIFwiY29ycmVjdFwiIChzZWUgYmVsb3cgZm9yIGEgbG9uZ2VyIGV4cGxhbmF0aW9uKS5cbiAqL1xuZnVuY3Rpb24gYXNzZXJ0Tm9JbWFnZURpc3RvcnRpb24oZGlyLCBpbWcsIHJlbmRlcmVyKSB7XG4gIGNvbnN0IHJlbW92ZUxvYWRMaXN0ZW5lckZuID0gcmVuZGVyZXIubGlzdGVuKGltZywgJ2xvYWQnLCAoKSA9PiB7XG4gICAgcmVtb3ZlTG9hZExpc3RlbmVyRm4oKTtcbiAgICByZW1vdmVFcnJvckxpc3RlbmVyRm4oKTtcbiAgICBjb25zdCBjb21wdXRlZFN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoaW1nKTtcbiAgICBsZXQgcmVuZGVyZWRXaWR0aCA9IHBhcnNlRmxvYXQoY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCd3aWR0aCcpKTtcbiAgICBsZXQgcmVuZGVyZWRIZWlnaHQgPSBwYXJzZUZsb2F0KGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgnaGVpZ2h0JykpO1xuICAgIGNvbnN0IGJveFNpemluZyA9IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgnYm94LXNpemluZycpO1xuICAgIGlmIChib3hTaXppbmcgPT09ICdib3JkZXItYm94Jykge1xuICAgICAgY29uc3QgcGFkZGluZ1RvcCA9IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgncGFkZGluZy10b3AnKTtcbiAgICAgIGNvbnN0IHBhZGRpbmdSaWdodCA9IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgncGFkZGluZy1yaWdodCcpO1xuICAgICAgY29uc3QgcGFkZGluZ0JvdHRvbSA9IGNvbXB1dGVkU3R5bGUuZ2V0UHJvcGVydHlWYWx1ZSgncGFkZGluZy1ib3R0b20nKTtcbiAgICAgIGNvbnN0IHBhZGRpbmdMZWZ0ID0gY29tcHV0ZWRTdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCdwYWRkaW5nLWxlZnQnKTtcbiAgICAgIHJlbmRlcmVkV2lkdGggLT0gcGFyc2VGbG9hdChwYWRkaW5nUmlnaHQpICsgcGFyc2VGbG9hdChwYWRkaW5nTGVmdCk7XG4gICAgICByZW5kZXJlZEhlaWdodCAtPSBwYXJzZUZsb2F0KHBhZGRpbmdUb3ApICsgcGFyc2VGbG9hdChwYWRkaW5nQm90dG9tKTtcbiAgICB9XG4gICAgY29uc3QgcmVuZGVyZWRBc3BlY3RSYXRpbyA9IHJlbmRlcmVkV2lkdGggLyByZW5kZXJlZEhlaWdodDtcbiAgICBjb25zdCBub25aZXJvUmVuZGVyZWREaW1lbnNpb25zID0gcmVuZGVyZWRXaWR0aCAhPT0gMCAmJiByZW5kZXJlZEhlaWdodCAhPT0gMDtcbiAgICBjb25zdCBpbnRyaW5zaWNXaWR0aCA9IGltZy5uYXR1cmFsV2lkdGg7XG4gICAgY29uc3QgaW50cmluc2ljSGVpZ2h0ID0gaW1nLm5hdHVyYWxIZWlnaHQ7XG4gICAgY29uc3QgaW50cmluc2ljQXNwZWN0UmF0aW8gPSBpbnRyaW5zaWNXaWR0aCAvIGludHJpbnNpY0hlaWdodDtcbiAgICBjb25zdCBzdXBwbGllZFdpZHRoID0gZGlyLndpZHRoO1xuICAgIGNvbnN0IHN1cHBsaWVkSGVpZ2h0ID0gZGlyLmhlaWdodDtcbiAgICBjb25zdCBzdXBwbGllZEFzcGVjdFJhdGlvID0gc3VwcGxpZWRXaWR0aCAvIHN1cHBsaWVkSGVpZ2h0O1xuICAgIC8vIFRvbGVyYW5jZSBpcyB1c2VkIHRvIGFjY291bnQgZm9yIHRoZSBpbXBhY3Qgb2Ygc3VicGl4ZWwgcmVuZGVyaW5nLlxuICAgIC8vIER1ZSB0byBzdWJwaXhlbCByZW5kZXJpbmcsIHRoZSByZW5kZXJlZCwgaW50cmluc2ljLCBhbmQgc3VwcGxpZWRcbiAgICAvLyBhc3BlY3QgcmF0aW9zIG9mIGEgY29ycmVjdGx5IGNvbmZpZ3VyZWQgaW1hZ2UgbWF5IG5vdCBleGFjdGx5IG1hdGNoLlxuICAgIC8vIEZvciBleGFtcGxlLCBhIGB3aWR0aD00MDMwIGhlaWdodD0zMDIwYCBpbWFnZSBtaWdodCBoYXZlIGEgcmVuZGVyZWRcbiAgICAvLyBzaXplIG9mIFwiMTA2MncsIDc5Ni40OGhcIi4gKEFuIGFzcGVjdCByYXRpbyBvZiAxLjMzNC4uLiB2cy4gMS4zMzMuLi4pXG4gICAgY29uc3QgaW5hY2N1cmF0ZURpbWVuc2lvbnMgPSBNYXRoLmFicyhzdXBwbGllZEFzcGVjdFJhdGlvIC0gaW50cmluc2ljQXNwZWN0UmF0aW8pID4gQVNQRUNUX1JBVElPX1RPTEVSQU5DRTtcbiAgICBjb25zdCBzdHlsaW5nRGlzdG9ydGlvbiA9IG5vblplcm9SZW5kZXJlZERpbWVuc2lvbnMgJiYgTWF0aC5hYnMoaW50cmluc2ljQXNwZWN0UmF0aW8gLSByZW5kZXJlZEFzcGVjdFJhdGlvKSA+IEFTUEVDVF9SQVRJT19UT0xFUkFOQ0U7XG4gICAgaWYgKGluYWNjdXJhdGVEaW1lbnNpb25zKSB7XG4gICAgICBjb25zb2xlLndhcm4oybVmb3JtYXRSdW50aW1lRXJyb3IoMjk1MiAvKiBSdW50aW1lRXJyb3JDb2RlLklOVkFMSURfSU5QVVQgKi8sIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gdGhlIGFzcGVjdCByYXRpbyBvZiB0aGUgaW1hZ2UgZG9lcyBub3QgbWF0Y2ggYCArIGB0aGUgYXNwZWN0IHJhdGlvIGluZGljYXRlZCBieSB0aGUgd2lkdGggYW5kIGhlaWdodCBhdHRyaWJ1dGVzLiBgICsgYFxcbkludHJpbnNpYyBpbWFnZSBzaXplOiAke2ludHJpbnNpY1dpZHRofXcgeCAke2ludHJpbnNpY0hlaWdodH1oIGAgKyBgKGFzcGVjdC1yYXRpbzogJHtyb3VuZChpbnRyaW5zaWNBc3BlY3RSYXRpbyl9KS4gXFxuU3VwcGxpZWQgd2lkdGggYW5kIGhlaWdodCBhdHRyaWJ1dGVzOiBgICsgYCR7c3VwcGxpZWRXaWR0aH13IHggJHtzdXBwbGllZEhlaWdodH1oIChhc3BlY3QtcmF0aW86ICR7cm91bmQoc3VwcGxpZWRBc3BlY3RSYXRpbyl9KS4gYCArIGBcXG5UbyBmaXggdGhpcywgdXBkYXRlIHRoZSB3aWR0aCBhbmQgaGVpZ2h0IGF0dHJpYnV0ZXMuYCkpO1xuICAgIH0gZWxzZSBpZiAoc3R5bGluZ0Rpc3RvcnRpb24pIHtcbiAgICAgIGNvbnNvbGUud2FybijJtWZvcm1hdFJ1bnRpbWVFcnJvcigyOTUyIC8qIFJ1bnRpbWVFcnJvckNvZGUuSU5WQUxJRF9JTlBVVCAqLywgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSB0aGUgYXNwZWN0IHJhdGlvIG9mIHRoZSByZW5kZXJlZCBpbWFnZSBgICsgYGRvZXMgbm90IG1hdGNoIHRoZSBpbWFnZSdzIGludHJpbnNpYyBhc3BlY3QgcmF0aW8uIGAgKyBgXFxuSW50cmluc2ljIGltYWdlIHNpemU6ICR7aW50cmluc2ljV2lkdGh9dyB4ICR7aW50cmluc2ljSGVpZ2h0fWggYCArIGAoYXNwZWN0LXJhdGlvOiAke3JvdW5kKGludHJpbnNpY0FzcGVjdFJhdGlvKX0pLiBcXG5SZW5kZXJlZCBpbWFnZSBzaXplOiBgICsgYCR7cmVuZGVyZWRXaWR0aH13IHggJHtyZW5kZXJlZEhlaWdodH1oIChhc3BlY3QtcmF0aW86IGAgKyBgJHtyb3VuZChyZW5kZXJlZEFzcGVjdFJhdGlvKX0pLiBcXG5UaGlzIGlzc3VlIGNhbiBvY2N1ciBpZiBcIndpZHRoXCIgYW5kIFwiaGVpZ2h0XCIgYCArIGBhdHRyaWJ1dGVzIGFyZSBhZGRlZCB0byBhbiBpbWFnZSB3aXRob3V0IHVwZGF0aW5nIHRoZSBjb3JyZXNwb25kaW5nIGAgKyBgaW1hZ2Ugc3R5bGluZy4gVG8gZml4IHRoaXMsIGFkanVzdCBpbWFnZSBzdHlsaW5nLiBJbiBtb3N0IGNhc2VzLCBgICsgYGFkZGluZyBcImhlaWdodDogYXV0b1wiIG9yIFwid2lkdGg6IGF1dG9cIiB0byB0aGUgaW1hZ2Ugc3R5bGluZyB3aWxsIGZpeCBgICsgYHRoaXMgaXNzdWUuYCkpO1xuICAgIH0gZWxzZSBpZiAoIWRpci5uZ1NyY3NldCAmJiBub25aZXJvUmVuZGVyZWREaW1lbnNpb25zKSB7XG4gICAgICAvLyBJZiBgbmdTcmNzZXRgIGhhc24ndCBiZWVuIHNldCwgc2FuaXR5IGNoZWNrIHRoZSBpbnRyaW5zaWMgc2l6ZS5cbiAgICAgIGNvbnN0IHJlY29tbWVuZGVkV2lkdGggPSBSRUNPTU1FTkRFRF9TUkNTRVRfREVOU0lUWV9DQVAgKiByZW5kZXJlZFdpZHRoO1xuICAgICAgY29uc3QgcmVjb21tZW5kZWRIZWlnaHQgPSBSRUNPTU1FTkRFRF9TUkNTRVRfREVOU0lUWV9DQVAgKiByZW5kZXJlZEhlaWdodDtcbiAgICAgIGNvbnN0IG92ZXJzaXplZFdpZHRoID0gaW50cmluc2ljV2lkdGggLSByZWNvbW1lbmRlZFdpZHRoID49IE9WRVJTSVpFRF9JTUFHRV9UT0xFUkFOQ0U7XG4gICAgICBjb25zdCBvdmVyc2l6ZWRIZWlnaHQgPSBpbnRyaW5zaWNIZWlnaHQgLSByZWNvbW1lbmRlZEhlaWdodCA+PSBPVkVSU0laRURfSU1BR0VfVE9MRVJBTkNFO1xuICAgICAgaWYgKG92ZXJzaXplZFdpZHRoIHx8IG92ZXJzaXplZEhlaWdodCkge1xuICAgICAgICBjb25zb2xlLndhcm4oybVmb3JtYXRSdW50aW1lRXJyb3IoMjk2MCAvKiBSdW50aW1lRXJyb3JDb2RlLk9WRVJTSVpFRF9JTUFHRSAqLywgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSB0aGUgaW50cmluc2ljIGltYWdlIGlzIHNpZ25pZmljYW50bHkgYCArIGBsYXJnZXIgdGhhbiBuZWNlc3NhcnkuIGAgKyBgXFxuUmVuZGVyZWQgaW1hZ2Ugc2l6ZTogJHtyZW5kZXJlZFdpZHRofXcgeCAke3JlbmRlcmVkSGVpZ2h0fWguIGAgKyBgXFxuSW50cmluc2ljIGltYWdlIHNpemU6ICR7aW50cmluc2ljV2lkdGh9dyB4ICR7aW50cmluc2ljSGVpZ2h0fWguIGAgKyBgXFxuUmVjb21tZW5kZWQgaW50cmluc2ljIGltYWdlIHNpemU6ICR7cmVjb21tZW5kZWRXaWR0aH13IHggJHtyZWNvbW1lbmRlZEhlaWdodH1oLiBgICsgYFxcbk5vdGU6IFJlY29tbWVuZGVkIGludHJpbnNpYyBpbWFnZSBzaXplIGlzIGNhbGN1bGF0ZWQgYXNzdW1pbmcgYSBtYXhpbXVtIERQUiBvZiBgICsgYCR7UkVDT01NRU5ERURfU1JDU0VUX0RFTlNJVFlfQ0FQfS4gVG8gaW1wcm92ZSBsb2FkaW5nIHRpbWUsIHJlc2l6ZSB0aGUgaW1hZ2UgYCArIGBvciBjb25zaWRlciB1c2luZyB0aGUgXCJuZ1NyY3NldFwiIGFuZCBcInNpemVzXCIgYXR0cmlidXRlcy5gKSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbiAgLy8gV2Ugb25seSBsaXN0ZW4gdG8gdGhlIGBlcnJvcmAgZXZlbnQgdG8gcmVtb3ZlIHRoZSBgbG9hZGAgZXZlbnQgbGlzdGVuZXIgYmVjYXVzZSBpdCB3aWxsIG5vdCBiZVxuICAvLyBmaXJlZCBpZiB0aGUgaW1hZ2UgZmFpbHMgdG8gbG9hZC4gVGhpcyBpcyBkb25lIHRvIHByZXZlbnQgbWVtb3J5IGxlYWtzIGluIGRldmVsb3BtZW50IG1vZGVcbiAgLy8gYmVjYXVzZSBpbWFnZSBlbGVtZW50cyBhcmVuJ3QgZ2FyYmFnZS1jb2xsZWN0ZWQgcHJvcGVybHkuIEl0IGhhcHBlbnMgYmVjYXVzZSB6b25lLmpzIHN0b3JlcyB0aGVcbiAgLy8gZXZlbnQgbGlzdGVuZXIgZGlyZWN0bHkgb24gdGhlIGVsZW1lbnQgYW5kIGNsb3N1cmVzIGNhcHR1cmUgYGRpcmAuXG4gIGNvbnN0IHJlbW92ZUVycm9yTGlzdGVuZXJGbiA9IHJlbmRlcmVyLmxpc3RlbihpbWcsICdlcnJvcicsICgpID0+IHtcbiAgICByZW1vdmVMb2FkTGlzdGVuZXJGbigpO1xuICAgIHJlbW92ZUVycm9yTGlzdGVuZXJGbigpO1xuICB9KTtcbn1cbi8qKlxuICogVmVyaWZpZXMgdGhhdCBhIHNwZWNpZmllZCBpbnB1dCBpcyBzZXQuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydE5vbkVtcHR5V2lkdGhBbmRIZWlnaHQoZGlyKSB7XG4gIGxldCBtaXNzaW5nQXR0cmlidXRlcyA9IFtdO1xuICBpZiAoZGlyLndpZHRoID09PSB1bmRlZmluZWQpIG1pc3NpbmdBdHRyaWJ1dGVzLnB1c2goJ3dpZHRoJyk7XG4gIGlmIChkaXIuaGVpZ2h0ID09PSB1bmRlZmluZWQpIG1pc3NpbmdBdHRyaWJ1dGVzLnB1c2goJ2hlaWdodCcpO1xuICBpZiAobWlzc2luZ0F0dHJpYnV0ZXMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyDJtVJ1bnRpbWVFcnJvcigyOTU0IC8qIFJ1bnRpbWVFcnJvckNvZGUuUkVRVUlSRURfSU5QVVRfTUlTU0lORyAqLywgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSB0aGVzZSByZXF1aXJlZCBhdHRyaWJ1dGVzIGAgKyBgYXJlIG1pc3Npbmc6ICR7bWlzc2luZ0F0dHJpYnV0ZXMubWFwKGF0dHIgPT4gYFwiJHthdHRyfVwiYCkuam9pbignLCAnKX0uIGAgKyBgSW5jbHVkaW5nIFwid2lkdGhcIiBhbmQgXCJoZWlnaHRcIiBhdHRyaWJ1dGVzIHdpbGwgcHJldmVudCBpbWFnZS1yZWxhdGVkIGxheW91dCBzaGlmdHMuIGAgKyBgVG8gZml4IHRoaXMsIGluY2x1ZGUgXCJ3aWR0aFwiIGFuZCBcImhlaWdodFwiIGF0dHJpYnV0ZXMgb24gdGhlIGltYWdlIHRhZyBvciB0dXJuIG9uIGAgKyBgXCJmaWxsXCIgbW9kZSB3aXRoIHRoZSBcXGBmaWxsXFxgIGF0dHJpYnV0ZS5gKTtcbiAgfVxufVxuLyoqXG4gKiBWZXJpZmllcyB0aGF0IHdpZHRoIGFuZCBoZWlnaHQgYXJlIG5vdCBzZXQuIFVzZWQgaW4gZmlsbCBtb2RlLCB3aGVyZSB0aG9zZSBhdHRyaWJ1dGVzIGRvbid0IG1ha2VcbiAqIHNlbnNlLlxuICovXG5mdW5jdGlvbiBhc3NlcnRFbXB0eVdpZHRoQW5kSGVpZ2h0KGRpcikge1xuICBpZiAoZGlyLndpZHRoIHx8IGRpci5oZWlnaHQpIHtcbiAgICB0aHJvdyBuZXcgybVSdW50aW1lRXJyb3IoMjk1MiAvKiBSdW50aW1lRXJyb3JDb2RlLklOVkFMSURfSU5QVVQgKi8sIGAke2ltZ0RpcmVjdGl2ZURldGFpbHMoZGlyLm5nU3JjKX0gdGhlIGF0dHJpYnV0ZXMgXFxgaGVpZ2h0XFxgIGFuZC9vciBcXGB3aWR0aFxcYCBhcmUgcHJlc2VudCBgICsgYGFsb25nIHdpdGggdGhlIFxcYGZpbGxcXGAgYXR0cmlidXRlLiBCZWNhdXNlIFxcYGZpbGxcXGAgbW9kZSBjYXVzZXMgYW4gaW1hZ2UgdG8gZmlsbCBpdHMgY29udGFpbmluZyBgICsgYGVsZW1lbnQsIHRoZSBzaXplIGF0dHJpYnV0ZXMgaGF2ZSBubyBlZmZlY3QgYW5kIHNob3VsZCBiZSByZW1vdmVkLmApO1xuICB9XG59XG4vKipcbiAqIFZlcmlmaWVzIHRoYXQgdGhlIHJlbmRlcmVkIGltYWdlIGhhcyBhIG5vbnplcm8gaGVpZ2h0LiBJZiB0aGUgaW1hZ2UgaXMgaW4gZmlsbCBtb2RlLCBwcm92aWRlc1xuICogZ3VpZGFuY2UgdGhhdCB0aGlzIGNhbiBiZSBjYXVzZWQgYnkgdGhlIGNvbnRhaW5pbmcgZWxlbWVudCdzIENTUyBwb3NpdGlvbiBwcm9wZXJ0eS5cbiAqL1xuZnVuY3Rpb24gYXNzZXJ0Tm9uWmVyb1JlbmRlcmVkSGVpZ2h0KGRpciwgaW1nLCByZW5kZXJlcikge1xuICBjb25zdCByZW1vdmVMb2FkTGlzdGVuZXJGbiA9IHJlbmRlcmVyLmxpc3RlbihpbWcsICdsb2FkJywgKCkgPT4ge1xuICAgIHJlbW92ZUxvYWRMaXN0ZW5lckZuKCk7XG4gICAgcmVtb3ZlRXJyb3JMaXN0ZW5lckZuKCk7XG4gICAgY29uc3QgcmVuZGVyZWRIZWlnaHQgPSBpbWcuY2xpZW50SGVpZ2h0O1xuICAgIGlmIChkaXIuZmlsbCAmJiByZW5kZXJlZEhlaWdodCA9PT0gMCkge1xuICAgICAgY29uc29sZS53YXJuKMm1Zm9ybWF0UnVudGltZUVycm9yKDI5NTIgLyogUnVudGltZUVycm9yQ29kZS5JTlZBTElEX0lOUFVUICovLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IHRoZSBoZWlnaHQgb2YgdGhlIGZpbGwtbW9kZSBpbWFnZSBpcyB6ZXJvLiBgICsgYFRoaXMgaXMgbGlrZWx5IGJlY2F1c2UgdGhlIGNvbnRhaW5pbmcgZWxlbWVudCBkb2VzIG5vdCBoYXZlIHRoZSBDU1MgJ3Bvc2l0aW9uJyBgICsgYHByb3BlcnR5IHNldCB0byBvbmUgb2YgdGhlIGZvbGxvd2luZzogXCJyZWxhdGl2ZVwiLCBcImZpeGVkXCIsIG9yIFwiYWJzb2x1dGVcIi4gYCArIGBUbyBmaXggdGhpcyBwcm9ibGVtLCBtYWtlIHN1cmUgdGhlIGNvbnRhaW5lciBlbGVtZW50IGhhcyB0aGUgQ1NTICdwb3NpdGlvbicgYCArIGBwcm9wZXJ0eSBkZWZpbmVkIGFuZCB0aGUgaGVpZ2h0IG9mIHRoZSBlbGVtZW50IGlzIG5vdCB6ZXJvLmApKTtcbiAgICB9XG4gIH0pO1xuICAvLyBTZWUgY29tbWVudHMgaW4gdGhlIGBhc3NlcnROb0ltYWdlRGlzdG9ydGlvbmAuXG4gIGNvbnN0IHJlbW92ZUVycm9yTGlzdGVuZXJGbiA9IHJlbmRlcmVyLmxpc3RlbihpbWcsICdlcnJvcicsICgpID0+IHtcbiAgICByZW1vdmVMb2FkTGlzdGVuZXJGbigpO1xuICAgIHJlbW92ZUVycm9yTGlzdGVuZXJGbigpO1xuICB9KTtcbn1cbi8qKlxuICogVmVyaWZpZXMgdGhhdCB0aGUgYGxvYWRpbmdgIGF0dHJpYnV0ZSBpcyBzZXQgdG8gYSB2YWxpZCBpbnB1dCAmXG4gKiBpcyBub3QgdXNlZCBvbiBwcmlvcml0eSBpbWFnZXMuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydFZhbGlkTG9hZGluZ0lucHV0KGRpcikge1xuICBpZiAoZGlyLmxvYWRpbmcgJiYgZGlyLnByaW9yaXR5KSB7XG4gICAgdGhyb3cgbmV3IMm1UnVudGltZUVycm9yKDI5NTIgLyogUnVudGltZUVycm9yQ29kZS5JTlZBTElEX0lOUFVUICovLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IHRoZSBcXGBsb2FkaW5nXFxgIGF0dHJpYnV0ZSBgICsgYHdhcyB1c2VkIG9uIGFuIGltYWdlIHRoYXQgd2FzIG1hcmtlZCBcInByaW9yaXR5XCIuIGAgKyBgU2V0dGluZyBcXGBsb2FkaW5nXFxgIG9uIHByaW9yaXR5IGltYWdlcyBpcyBub3QgYWxsb3dlZCBgICsgYGJlY2F1c2UgdGhlc2UgaW1hZ2VzIHdpbGwgYWx3YXlzIGJlIGVhZ2VybHkgbG9hZGVkLiBgICsgYFRvIGZpeCB0aGlzLCByZW1vdmUgdGhlIOKAnGxvYWRpbmfigJ0gYXR0cmlidXRlIGZyb20gdGhlIHByaW9yaXR5IGltYWdlLmApO1xuICB9XG4gIGNvbnN0IHZhbGlkSW5wdXRzID0gWydhdXRvJywgJ2VhZ2VyJywgJ2xhenknXTtcbiAgaWYgKHR5cGVvZiBkaXIubG9hZGluZyA9PT0gJ3N0cmluZycgJiYgIXZhbGlkSW5wdXRzLmluY2x1ZGVzKGRpci5sb2FkaW5nKSkge1xuICAgIHRocm93IG5ldyDJtVJ1bnRpbWVFcnJvcigyOTUyIC8qIFJ1bnRpbWVFcnJvckNvZGUuSU5WQUxJRF9JTlBVVCAqLywgYCR7aW1nRGlyZWN0aXZlRGV0YWlscyhkaXIubmdTcmMpfSB0aGUgXFxgbG9hZGluZ1xcYCBhdHRyaWJ1dGUgYCArIGBoYXMgYW4gaW52YWxpZCB2YWx1ZSAoXFxgJHtkaXIubG9hZGluZ31cXGApLiBgICsgYFRvIGZpeCB0aGlzLCBwcm92aWRlIGEgdmFsaWQgdmFsdWUgKFwibGF6eVwiLCBcImVhZ2VyXCIsIG9yIFwiYXV0b1wiKS5gKTtcbiAgfVxufVxuLyoqXG4gKiBXYXJucyBpZiBOT1QgdXNpbmcgYSBsb2FkZXIgKGZhbGxpbmcgYmFjayB0byB0aGUgZ2VuZXJpYyBsb2FkZXIpIGFuZFxuICogdGhlIGltYWdlIGFwcGVhcnMgdG8gYmUgaG9zdGVkIG9uIG9uZSBvZiB0aGUgaW1hZ2UgQ0ROcyBmb3Igd2hpY2hcbiAqIHdlIGRvIGhhdmUgYSBidWlsdC1pbiBpbWFnZSBsb2FkZXIuIFN1Z2dlc3RzIHN3aXRjaGluZyB0byB0aGVcbiAqIGJ1aWx0LWluIGxvYWRlci5cbiAqXG4gKiBAcGFyYW0gbmdTcmMgVmFsdWUgb2YgdGhlIG5nU3JjIGF0dHJpYnV0ZVxuICogQHBhcmFtIGltYWdlTG9hZGVyIEltYWdlTG9hZGVyIHByb3ZpZGVkXG4gKi9cbmZ1bmN0aW9uIGFzc2VydE5vdE1pc3NpbmdCdWlsdEluTG9hZGVyKG5nU3JjLCBpbWFnZUxvYWRlcikge1xuICBpZiAoaW1hZ2VMb2FkZXIgPT09IG5vb3BJbWFnZUxvYWRlcikge1xuICAgIGxldCBidWlsdEluTG9hZGVyTmFtZSA9ICcnO1xuICAgIGZvciAoY29uc3QgbG9hZGVyIG9mIEJVSUxUX0lOX0xPQURFUlMpIHtcbiAgICAgIGlmIChsb2FkZXIudGVzdFVybChuZ1NyYykpIHtcbiAgICAgICAgYnVpbHRJbkxvYWRlck5hbWUgPSBsb2FkZXIubmFtZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChidWlsdEluTG9hZGVyTmFtZSkge1xuICAgICAgY29uc29sZS53YXJuKMm1Zm9ybWF0UnVudGltZUVycm9yKDI5NjIgLyogUnVudGltZUVycm9yQ29kZS5NSVNTSU5HX0JVSUxUSU5fTE9BREVSICovLCBgTmdPcHRpbWl6ZWRJbWFnZTogSXQgbG9va3MgbGlrZSB5b3VyIGltYWdlcyBtYXkgYmUgaG9zdGVkIG9uIHRoZSBgICsgYCR7YnVpbHRJbkxvYWRlck5hbWV9IENETiwgYnV0IHlvdXIgYXBwIGlzIG5vdCB1c2luZyBBbmd1bGFyJ3MgYCArIGBidWlsdC1pbiBsb2FkZXIgZm9yIHRoYXQgQ0ROLiBXZSByZWNvbW1lbmQgc3dpdGNoaW5nIHRvIHVzZSBgICsgYHRoZSBidWlsdC1pbiBieSBjYWxsaW5nIFxcYHByb3ZpZGUke2J1aWx0SW5Mb2FkZXJOYW1lfUxvYWRlcigpXFxgIGAgKyBgaW4geW91ciBcXGBwcm92aWRlcnNcXGAgYW5kIHBhc3NpbmcgaXQgeW91ciBpbnN0YW5jZSdzIGJhc2UgVVJMLiBgICsgYElmIHlvdSBkb24ndCB3YW50IHRvIHVzZSB0aGUgYnVpbHQtaW4gbG9hZGVyLCBkZWZpbmUgYSBjdXN0b20gYCArIGBsb2FkZXIgZnVuY3Rpb24gdXNpbmcgSU1BR0VfTE9BREVSIHRvIHNpbGVuY2UgdGhpcyB3YXJuaW5nLmApKTtcbiAgICB9XG4gIH1cbn1cbi8qKlxuICogV2FybnMgaWYgbmdTcmNzZXQgaXMgcHJlc2VudCBhbmQgbm8gbG9hZGVyIGlzIGNvbmZpZ3VyZWQgKGkuZS4gdGhlIGRlZmF1bHQgb25lIGlzIGJlaW5nIHVzZWQpLlxuICovXG5mdW5jdGlvbiBhc3NlcnROb05nU3Jjc2V0V2l0aG91dExvYWRlcihkaXIsIGltYWdlTG9hZGVyKSB7XG4gIGlmIChkaXIubmdTcmNzZXQgJiYgaW1hZ2VMb2FkZXIgPT09IG5vb3BJbWFnZUxvYWRlcikge1xuICAgIGNvbnNvbGUud2FybijJtWZvcm1hdFJ1bnRpbWVFcnJvcigyOTYzIC8qIFJ1bnRpbWVFcnJvckNvZGUuTUlTU0lOR19ORUNFU1NBUllfTE9BREVSICovLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IHRoZSBcXGBuZ1NyY3NldFxcYCBhdHRyaWJ1dGUgaXMgcHJlc2VudCBidXQgYCArIGBubyBpbWFnZSBsb2FkZXIgaXMgY29uZmlndXJlZCAoaS5lLiB0aGUgZGVmYXVsdCBvbmUgaXMgYmVpbmcgdXNlZCksIGAgKyBgd2hpY2ggd291bGQgcmVzdWx0IGluIHRoZSBzYW1lIGltYWdlIGJlaW5nIHVzZWQgZm9yIGFsbCBjb25maWd1cmVkIHNpemVzLiBgICsgYFRvIGZpeCB0aGlzLCBwcm92aWRlIGEgbG9hZGVyIG9yIHJlbW92ZSB0aGUgXFxgbmdTcmNzZXRcXGAgYXR0cmlidXRlIGZyb20gdGhlIGltYWdlLmApKTtcbiAgfVxufVxuLyoqXG4gKiBXYXJucyBpZiBsb2FkZXJQYXJhbXMgaXMgcHJlc2VudCBhbmQgbm8gbG9hZGVyIGlzIGNvbmZpZ3VyZWQgKGkuZS4gdGhlIGRlZmF1bHQgb25lIGlzIGJlaW5nXG4gKiB1c2VkKS5cbiAqL1xuZnVuY3Rpb24gYXNzZXJ0Tm9Mb2FkZXJQYXJhbXNXaXRob3V0TG9hZGVyKGRpciwgaW1hZ2VMb2FkZXIpIHtcbiAgaWYgKGRpci5sb2FkZXJQYXJhbXMgJiYgaW1hZ2VMb2FkZXIgPT09IG5vb3BJbWFnZUxvYWRlcikge1xuICAgIGNvbnNvbGUud2FybijJtWZvcm1hdFJ1bnRpbWVFcnJvcigyOTYzIC8qIFJ1bnRpbWVFcnJvckNvZGUuTUlTU0lOR19ORUNFU1NBUllfTE9BREVSICovLCBgJHtpbWdEaXJlY3RpdmVEZXRhaWxzKGRpci5uZ1NyYyl9IHRoZSBcXGBsb2FkZXJQYXJhbXNcXGAgYXR0cmlidXRlIGlzIHByZXNlbnQgYnV0IGAgKyBgbm8gaW1hZ2UgbG9hZGVyIGlzIGNvbmZpZ3VyZWQgKGkuZS4gdGhlIGRlZmF1bHQgb25lIGlzIGJlaW5nIHVzZWQpLCBgICsgYHdoaWNoIG1lYW5zIHRoYXQgdGhlIGxvYWRlclBhcmFtcyBkYXRhIHdpbGwgbm90IGJlIGNvbnN1bWVkIGFuZCB3aWxsIG5vdCBhZmZlY3QgdGhlIFVSTC4gYCArIGBUbyBmaXggdGhpcywgcHJvdmlkZSBhIGN1c3RvbSBsb2FkZXIgb3IgcmVtb3ZlIHRoZSBcXGBsb2FkZXJQYXJhbXNcXGAgYXR0cmlidXRlIGZyb20gdGhlIGltYWdlLmApKTtcbiAgfVxufVxuZnVuY3Rpb24gcm91bmQoaW5wdXQpIHtcbiAgcmV0dXJuIE51bWJlci5pc0ludGVnZXIoaW5wdXQpID8gaW5wdXQgOiBpbnB1dC50b0ZpeGVkKDIpO1xufVxuLy8gVHJhbnNmb3JtIGZ1bmN0aW9uIHRvIGhhbmRsZSBTYWZlVmFsdWUgaW5wdXQgZm9yIG5nU3JjLiBUaGlzIGRvZXNuJ3QgZG8gYW55IHNhbml0aXphdGlvbixcbi8vIGFzIHRoYXQgaXMgbm90IG5lZWRlZCBmb3IgaW1nLnNyYyBhbmQgaW1nLnNyY3NldC4gVGhpcyB0cmFuc2Zvcm0gaXMgcHVyZWx5IGZvciBjb21wYXRpYmlsaXR5LlxuZnVuY3Rpb24gdW53cmFwU2FmZVVybCh2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gybV1bndyYXBTYWZlVmFsdWUodmFsdWUpO1xufVxuLy8gVHJhbnNmb3JtIGZ1bmN0aW9uIHRvIGhhbmRsZSBpbnB1dHMgd2hpY2ggbWF5IGJlIGJvb2xlYW5zLCBzdHJpbmdzLCBvciBzdHJpbmcgcmVwcmVzZW50YXRpb25zXG4vLyBvZiBib29sZWFuIHZhbHVlcy4gVXNlZCBmb3IgdGhlIHBsYWNlaG9sZGVyIGF0dHJpYnV0ZS5cbmZ1bmN0aW9uIGJvb2xlYW5PckRhdGFVcmxBdHRyaWJ1dGUodmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUuc3RhcnRzV2l0aChgZGF0YTpgKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gYm9vbGVhbkF0dHJpYnV0ZSh2YWx1ZSk7XG59XG5cbi8qKlxuICogQG1vZHVsZVxuICogQGRlc2NyaXB0aW9uXG4gKiBFbnRyeSBwb2ludCBmb3IgYWxsIHB1YmxpYyBBUElzIG9mIHRoZSBjb21tb24gcGFja2FnZS5cbiAqL1xuXG4vKipcbiAqIEBtb2R1bGVcbiAqIEBkZXNjcmlwdGlvblxuICogRW50cnkgcG9pbnQgZm9yIGFsbCBwdWJsaWMgQVBJcyBvZiB0aGlzIHBhY2thZ2UuXG4gKi9cbi8vIFRoaXMgZmlsZSBvbmx5IHJlZXhwb3J0cyBjb250ZW50IG9mIHRoZSBgc3JjYCBmb2xkZXIuIEtlZXAgaXQgdGhhdCB3YXkuXG5cbi8vIFRoaXMgZmlsZSBpcyBub3QgdXNlZCB0byBidWlsZCB0aGlzIG1vZHVsZS4gSXQgaXMgb25seSB1c2VkIGR1cmluZyBlZGl0aW5nXG5cbi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0IHsgQVBQX0JBU0VfSFJFRiwgQXN5bmNQaXBlLCBCcm93c2VyUGxhdGZvcm1Mb2NhdGlvbiwgQ29tbW9uTW9kdWxlLCBDdXJyZW5jeVBpcGUsIERBVEVfUElQRV9ERUZBVUxUX09QVElPTlMsIERBVEVfUElQRV9ERUZBVUxUX1RJTUVaT05FLCBET0NVTUVOVCwgRGF0ZVBpcGUsIERlY2ltYWxQaXBlLCBGb3JtU3R5bGUsIEZvcm1hdFdpZHRoLCBIYXNoTG9jYXRpb25TdHJhdGVneSwgSTE4blBsdXJhbFBpcGUsIEkxOG5TZWxlY3RQaXBlLCBJTUFHRV9MT0FERVIsIEpzb25QaXBlLCBLZXlWYWx1ZVBpcGUsIExPQ0FUSU9OX0lOSVRJQUxJWkVELCBMb2NhdGlvbiwgTG9jYXRpb25TdHJhdGVneSwgTG93ZXJDYXNlUGlwZSwgTmdDbGFzcywgTmdDb21wb25lbnRPdXRsZXQsIE5nRm9yT2YgYXMgTmdGb3IsIE5nRm9yT2YsIE5nRm9yT2ZDb250ZXh0LCBOZ0lmLCBOZ0lmQ29udGV4dCwgTmdMb2NhbGVMb2NhbGl6YXRpb24sIE5nTG9jYWxpemF0aW9uLCBOZ09wdGltaXplZEltYWdlLCBOZ1BsdXJhbCwgTmdQbHVyYWxDYXNlLCBOZ1N0eWxlLCBOZ1N3aXRjaCwgTmdTd2l0Y2hDYXNlLCBOZ1N3aXRjaERlZmF1bHQsIE5nVGVtcGxhdGVPdXRsZXQsIE51bWJlckZvcm1hdFN0eWxlLCBOdW1iZXJTeW1ib2wsIFBSRUNPTk5FQ1RfQ0hFQ0tfQkxPQ0tMSVNULCBQYXRoTG9jYXRpb25TdHJhdGVneSwgUGVyY2VudFBpcGUsIFBsYXRmb3JtTG9jYXRpb24sIFBsdXJhbCwgU2xpY2VQaXBlLCBUaXRsZUNhc2VQaXBlLCBUcmFuc2xhdGlvbldpZHRoLCBVcHBlckNhc2VQaXBlLCBWRVJTSU9OLCBWaWV3cG9ydFNjcm9sbGVyLCBXZWVrRGF5LCBYaHJGYWN0b3J5LCBmb3JtYXRDdXJyZW5jeSwgZm9ybWF0RGF0ZSwgZm9ybWF0TnVtYmVyLCBmb3JtYXRQZXJjZW50LCBnZXRDdXJyZW5jeVN5bWJvbCwgZ2V0TG9jYWxlQ3VycmVuY3lDb2RlLCBnZXRMb2NhbGVDdXJyZW5jeU5hbWUsIGdldExvY2FsZUN1cnJlbmN5U3ltYm9sLCBnZXRMb2NhbGVEYXRlRm9ybWF0LCBnZXRMb2NhbGVEYXRlVGltZUZvcm1hdCwgZ2V0TG9jYWxlRGF5TmFtZXMsIGdldExvY2FsZURheVBlcmlvZHMsIGdldExvY2FsZURpcmVjdGlvbiwgZ2V0TG9jYWxlRXJhTmFtZXMsIGdldExvY2FsZUV4dHJhRGF5UGVyaW9kUnVsZXMsIGdldExvY2FsZUV4dHJhRGF5UGVyaW9kcywgZ2V0TG9jYWxlRmlyc3REYXlPZldlZWssIGdldExvY2FsZUlkLCBnZXRMb2NhbGVNb250aE5hbWVzLCBnZXRMb2NhbGVOdW1iZXJGb3JtYXQsIGdldExvY2FsZU51bWJlclN5bWJvbCwgZ2V0TG9jYWxlUGx1cmFsQ2FzZSwgZ2V0TG9jYWxlVGltZUZvcm1hdCwgZ2V0TG9jYWxlV2Vla0VuZFJhbmdlLCBnZXROdW1iZXJPZkN1cnJlbmN5RGlnaXRzLCBpc1BsYXRmb3JtQnJvd3NlciwgaXNQbGF0Zm9ybVNlcnZlciwgcHJvdmlkZUNsb3VkZmxhcmVMb2FkZXIsIHByb3ZpZGVDbG91ZGluYXJ5TG9hZGVyLCBwcm92aWRlSW1hZ2VLaXRMb2FkZXIsIHByb3ZpZGVJbWdpeExvYWRlciwgcHJvdmlkZU5ldGxpZnlMb2FkZXIsIHJlZ2lzdGVyTG9jYWxlRGF0YSwgRG9tQWRhcHRlciBhcyDJtURvbUFkYXB0ZXIsIE51bGxWaWV3cG9ydFNjcm9sbGVyIGFzIMm1TnVsbFZpZXdwb3J0U2Nyb2xsZXIsIFBMQVRGT1JNX0JST1dTRVJfSUQgYXMgybVQTEFURk9STV9CUk9XU0VSX0lELCBQTEFURk9STV9TRVJWRVJfSUQgYXMgybVQTEFURk9STV9TRVJWRVJfSUQsIFBsYXRmb3JtTmF2aWdhdGlvbiBhcyDJtVBsYXRmb3JtTmF2aWdhdGlvbiwgZ2V0RE9NIGFzIMm1Z2V0RE9NLCBub3JtYWxpemVRdWVyeVBhcmFtcyBhcyDJtW5vcm1hbGl6ZVF1ZXJ5UGFyYW1zLCBwYXJzZUNvb2tpZVZhbHVlIGFzIMm1cGFyc2VDb29raWVWYWx1ZSwgc2V0Um9vdERvbUFkYXB0ZXIgYXMgybVzZXRSb290RG9tQWRhcHRlciB9O1xuIiwgIi8qKlxuICogQGxpY2Vuc2UgQW5ndWxhciB2MTguMC41XG4gKiAoYykgMjAxMC0yMDI0IEdvb2dsZSBMTEMuIGh0dHBzOi8vYW5ndWxhci5pby9cbiAqIExpY2Vuc2U6IE1JVFxuICovXG5cbmltcG9ydCAqIGFzIGkwIGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0LCBOZ1pvbmUsIHJ1bkluSW5qZWN0aW9uQ29udGV4dCwgSW5qZWN0aW9uVG9rZW4sIMm1UGVuZGluZ1Rhc2tzLCBQTEFURk9STV9JRCwgybVDb25zb2xlLCDJtWZvcm1hdFJ1bnRpbWVFcnJvciwgSW5qZWN0LCDJtVJ1bnRpbWVFcnJvciwgbWFrZUVudmlyb25tZW50UHJvdmlkZXJzLCBOZ01vZHVsZSwgVHJhbnNmZXJTdGF0ZSwgbWFrZVN0YXRlS2V5LCDJtXBlcmZvcm1hbmNlTWFya0ZlYXR1cmUsIEFQUF9CT09UU1RSQVBfTElTVEVORVIsIEFwcGxpY2F0aW9uUmVmLCDJtXdoZW5TdGFibGUsIMm1dHJ1bmNhdGVNaWRkbGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IG9mLCBPYnNlcnZhYmxlLCBmcm9tIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjb25jYXRNYXAsIGZpbHRlciwgbWFwLCBmaW5hbGl6ZSwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgKiBhcyBpMSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgaXNQbGF0Zm9ybVNlcnZlciwgRE9DVU1FTlQsIMm1cGFyc2VDb29raWVWYWx1ZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbi8qKlxuICogVHJhbnNmb3JtcyBhbiBgSHR0cFJlcXVlc3RgIGludG8gYSBzdHJlYW0gb2YgYEh0dHBFdmVudGBzLCBvbmUgb2Ygd2hpY2ggd2lsbCBsaWtlbHkgYmUgYVxuICogYEh0dHBSZXNwb25zZWAuXG4gKlxuICogYEh0dHBIYW5kbGVyYCBpcyBpbmplY3RhYmxlLiBXaGVuIGluamVjdGVkLCB0aGUgaGFuZGxlciBpbnN0YW5jZSBkaXNwYXRjaGVzIHJlcXVlc3RzIHRvIHRoZVxuICogZmlyc3QgaW50ZXJjZXB0b3IgaW4gdGhlIGNoYWluLCB3aGljaCBkaXNwYXRjaGVzIHRvIHRoZSBzZWNvbmQsIGV0YywgZXZlbnR1YWxseSByZWFjaGluZyB0aGVcbiAqIGBIdHRwQmFja2VuZGAuXG4gKlxuICogSW4gYW4gYEh0dHBJbnRlcmNlcHRvcmAsIHRoZSBgSHR0cEhhbmRsZXJgIHBhcmFtZXRlciBpcyB0aGUgbmV4dCBpbnRlcmNlcHRvciBpbiB0aGUgY2hhaW4uXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBIdHRwSGFuZGxlciB7fVxuLyoqXG4gKiBBIGZpbmFsIGBIdHRwSGFuZGxlcmAgd2hpY2ggd2lsbCBkaXNwYXRjaCB0aGUgcmVxdWVzdCB2aWEgYnJvd3NlciBIVFRQIEFQSXMgdG8gYSBiYWNrZW5kLlxuICpcbiAqIEludGVyY2VwdG9ycyBzaXQgYmV0d2VlbiB0aGUgYEh0dHBDbGllbnRgIGludGVyZmFjZSBhbmQgdGhlIGBIdHRwQmFja2VuZGAuXG4gKlxuICogV2hlbiBpbmplY3RlZCwgYEh0dHBCYWNrZW5kYCBkaXNwYXRjaGVzIHJlcXVlc3RzIGRpcmVjdGx5IHRvIHRoZSBiYWNrZW5kLCB3aXRob3V0IGdvaW5nXG4gKiB0aHJvdWdoIHRoZSBpbnRlcmNlcHRvciBjaGFpbi5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIEh0dHBCYWNrZW5kIHt9XG5cbi8qKlxuICogUmVwcmVzZW50cyB0aGUgaGVhZGVyIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyBmb3IgYW4gSFRUUCByZXF1ZXN0LlxuICogSW5zdGFuY2VzIGFyZSBpbW11dGFibGUuIE1vZGlmeWluZyBtZXRob2RzIHJldHVybiBhIGNsb25lZFxuICogaW5zdGFuY2Ugd2l0aCB0aGUgY2hhbmdlLiBUaGUgb3JpZ2luYWwgb2JqZWN0IGlzIG5ldmVyIGNoYW5nZWQuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBIdHRwSGVhZGVycyB7XG4gIC8qKiAgQ29uc3RydWN0cyBhIG5ldyBIVFRQIGhlYWRlciBvYmplY3Qgd2l0aCB0aGUgZ2l2ZW4gdmFsdWVzLiovXG4gIGNvbnN0cnVjdG9yKGhlYWRlcnMpIHtcbiAgICAvKipcbiAgICAgKiBJbnRlcm5hbCBtYXAgb2YgbG93ZXJjYXNlZCBoZWFkZXIgbmFtZXMgdG8gdGhlIG5vcm1hbGl6ZWRcbiAgICAgKiBmb3JtIG9mIHRoZSBuYW1lICh0aGUgZm9ybSBzZWVuIGZpcnN0KS5cbiAgICAgKi9cbiAgICB0aGlzLm5vcm1hbGl6ZWROYW1lcyA9IG5ldyBNYXAoKTtcbiAgICAvKipcbiAgICAgKiBRdWV1ZWQgdXBkYXRlcyB0byBiZSBtYXRlcmlhbGl6ZWQgdGhlIG5leHQgaW5pdGlhbGl6YXRpb24uXG4gICAgICovXG4gICAgdGhpcy5sYXp5VXBkYXRlID0gbnVsbDtcbiAgICBpZiAoIWhlYWRlcnMpIHtcbiAgICAgIHRoaXMuaGVhZGVycyA9IG5ldyBNYXAoKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBoZWFkZXJzID09PSAnc3RyaW5nJykge1xuICAgICAgdGhpcy5sYXp5SW5pdCA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gbmV3IE1hcCgpO1xuICAgICAgICBoZWFkZXJzLnNwbGl0KCdcXG4nKS5mb3JFYWNoKGxpbmUgPT4ge1xuICAgICAgICAgIGNvbnN0IGluZGV4ID0gbGluZS5pbmRleE9mKCc6Jyk7XG4gICAgICAgICAgaWYgKGluZGV4ID4gMCkge1xuICAgICAgICAgICAgY29uc3QgbmFtZSA9IGxpbmUuc2xpY2UoMCwgaW5kZXgpO1xuICAgICAgICAgICAgY29uc3Qga2V5ID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBsaW5lLnNsaWNlKGluZGV4ICsgMSkudHJpbSgpO1xuICAgICAgICAgICAgdGhpcy5tYXliZVNldE5vcm1hbGl6ZWROYW1lKG5hbWUsIGtleSk7XG4gICAgICAgICAgICBpZiAodGhpcy5oZWFkZXJzLmhhcyhrZXkpKSB7XG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVycy5nZXQoa2V5KS5wdXNoKHZhbHVlKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMuaGVhZGVycy5zZXQoa2V5LCBbdmFsdWVdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBIZWFkZXJzICE9PSAndW5kZWZpbmVkJyAmJiBoZWFkZXJzIGluc3RhbmNlb2YgSGVhZGVycykge1xuICAgICAgdGhpcy5oZWFkZXJzID0gbmV3IE1hcCgpO1xuICAgICAgaGVhZGVycy5mb3JFYWNoKCh2YWx1ZXMsIG5hbWUpID0+IHtcbiAgICAgICAgdGhpcy5zZXRIZWFkZXJFbnRyaWVzKG5hbWUsIHZhbHVlcyk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5sYXp5SW5pdCA9ICgpID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiBuZ0Rldk1vZGUgPT09ICd1bmRlZmluZWQnIHx8IG5nRGV2TW9kZSkge1xuICAgICAgICAgIGFzc2VydFZhbGlkSGVhZGVycyhoZWFkZXJzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmhlYWRlcnMgPSBuZXcgTWFwKCk7XG4gICAgICAgIE9iamVjdC5lbnRyaWVzKGhlYWRlcnMpLmZvckVhY2goKFtuYW1lLCB2YWx1ZXNdKSA9PiB7XG4gICAgICAgICAgdGhpcy5zZXRIZWFkZXJFbnRyaWVzKG5hbWUsIHZhbHVlcyk7XG4gICAgICAgIH0pO1xuICAgICAgfTtcbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIENoZWNrcyBmb3IgZXhpc3RlbmNlIG9mIGEgZ2l2ZW4gaGVhZGVyLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgaGVhZGVyIG5hbWUgdG8gY2hlY2sgZm9yIGV4aXN0ZW5jZS5cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgaGVhZGVyIGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgaGFzKG5hbWUpIHtcbiAgICB0aGlzLmluaXQoKTtcbiAgICByZXR1cm4gdGhpcy5oZWFkZXJzLmhhcyhuYW1lLnRvTG93ZXJDYXNlKCkpO1xuICB9XG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIGZpcnN0IHZhbHVlIG9mIGEgZ2l2ZW4gaGVhZGVyLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgaGVhZGVyIG5hbWUuXG4gICAqXG4gICAqIEByZXR1cm5zIFRoZSB2YWx1ZSBzdHJpbmcgaWYgdGhlIGhlYWRlciBleGlzdHMsIG51bGwgb3RoZXJ3aXNlXG4gICAqL1xuICBnZXQobmFtZSkge1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuaGVhZGVycy5nZXQobmFtZS50b0xvd2VyQ2FzZSgpKTtcbiAgICByZXR1cm4gdmFsdWVzICYmIHZhbHVlcy5sZW5ndGggPiAwID8gdmFsdWVzWzBdIDogbnVsbDtcbiAgfVxuICAvKipcbiAgICogUmV0cmlldmVzIHRoZSBuYW1lcyBvZiB0aGUgaGVhZGVycy5cbiAgICpcbiAgICogQHJldHVybnMgQSBsaXN0IG9mIGhlYWRlciBuYW1lcy5cbiAgICovXG4gIGtleXMoKSB7XG4gICAgdGhpcy5pbml0KCk7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5ub3JtYWxpemVkTmFtZXMudmFsdWVzKCkpO1xuICB9XG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgYSBsaXN0IG9mIHZhbHVlcyBmb3IgYSBnaXZlbiBoZWFkZXIuXG4gICAqXG4gICAqIEBwYXJhbSBuYW1lIFRoZSBoZWFkZXIgbmFtZSBmcm9tIHdoaWNoIHRvIHJldHJpZXZlIHZhbHVlcy5cbiAgICpcbiAgICogQHJldHVybnMgQSBzdHJpbmcgb2YgdmFsdWVzIGlmIHRoZSBoZWFkZXIgZXhpc3RzLCBudWxsIG90aGVyd2lzZS5cbiAgICovXG4gIGdldEFsbChuYW1lKSB7XG4gICAgdGhpcy5pbml0KCk7XG4gICAgcmV0dXJuIHRoaXMuaGVhZGVycy5nZXQobmFtZS50b0xvd2VyQ2FzZSgpKSB8fCBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBBcHBlbmRzIGEgbmV3IHZhbHVlIHRvIHRoZSBleGlzdGluZyBzZXQgb2YgdmFsdWVzIGZvciBhIGhlYWRlclxuICAgKiBhbmQgcmV0dXJucyB0aGVtIGluIGEgY2xvbmUgb2YgdGhlIG9yaWdpbmFsIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgaGVhZGVyIG5hbWUgZm9yIHdoaWNoIHRvIGFwcGVuZCB0aGUgdmFsdWVzLlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGFwcGVuZC5cbiAgICpcbiAgICogQHJldHVybnMgQSBjbG9uZSBvZiB0aGUgSFRUUCBoZWFkZXJzIG9iamVjdCB3aXRoIHRoZSB2YWx1ZSBhcHBlbmRlZCB0byB0aGUgZ2l2ZW4gaGVhZGVyLlxuICAgKi9cbiAgYXBwZW5kKG5hbWUsIHZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoe1xuICAgICAgbmFtZSxcbiAgICAgIHZhbHVlLFxuICAgICAgb3A6ICdhJ1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBTZXRzIG9yIG1vZGlmaWVzIGEgdmFsdWUgZm9yIGEgZ2l2ZW4gaGVhZGVyIGluIGEgY2xvbmUgb2YgdGhlIG9yaWdpbmFsIGluc3RhbmNlLlxuICAgKiBJZiB0aGUgaGVhZGVyIGFscmVhZHkgZXhpc3RzLCBpdHMgdmFsdWUgaXMgcmVwbGFjZWQgd2l0aCB0aGUgZ2l2ZW4gdmFsdWVcbiAgICogaW4gdGhlIHJldHVybmVkIG9iamVjdC5cbiAgICpcbiAgICogQHBhcmFtIG5hbWUgVGhlIGhlYWRlciBuYW1lLlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIG9yIHZhbHVlcyB0byBzZXQgb3Igb3ZlcnJpZGUgZm9yIHRoZSBnaXZlbiBoZWFkZXIuXG4gICAqXG4gICAqIEByZXR1cm5zIEEgY2xvbmUgb2YgdGhlIEhUVFAgaGVhZGVycyBvYmplY3Qgd2l0aCB0aGUgbmV3bHkgc2V0IGhlYWRlciB2YWx1ZS5cbiAgICovXG4gIHNldChuYW1lLCB2YWx1ZSkge1xuICAgIHJldHVybiB0aGlzLmNsb25lKHtcbiAgICAgIG5hbWUsXG4gICAgICB2YWx1ZSxcbiAgICAgIG9wOiAncydcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogRGVsZXRlcyB2YWx1ZXMgZm9yIGEgZ2l2ZW4gaGVhZGVyIGluIGEgY2xvbmUgb2YgdGhlIG9yaWdpbmFsIGluc3RhbmNlLlxuICAgKlxuICAgKiBAcGFyYW0gbmFtZSBUaGUgaGVhZGVyIG5hbWUuXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgb3IgdmFsdWVzIHRvIGRlbGV0ZSBmb3IgdGhlIGdpdmVuIGhlYWRlci5cbiAgICpcbiAgICogQHJldHVybnMgQSBjbG9uZSBvZiB0aGUgSFRUUCBoZWFkZXJzIG9iamVjdCB3aXRoIHRoZSBnaXZlbiB2YWx1ZSBkZWxldGVkLlxuICAgKi9cbiAgZGVsZXRlKG5hbWUsIHZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoe1xuICAgICAgbmFtZSxcbiAgICAgIHZhbHVlLFxuICAgICAgb3A6ICdkJ1xuICAgIH0pO1xuICB9XG4gIG1heWJlU2V0Tm9ybWFsaXplZE5hbWUobmFtZSwgbGNOYW1lKSB7XG4gICAgaWYgKCF0aGlzLm5vcm1hbGl6ZWROYW1lcy5oYXMobGNOYW1lKSkge1xuICAgICAgdGhpcy5ub3JtYWxpemVkTmFtZXMuc2V0KGxjTmFtZSwgbmFtZSk7XG4gICAgfVxuICB9XG4gIGluaXQoKSB7XG4gICAgaWYgKCEhdGhpcy5sYXp5SW5pdCkge1xuICAgICAgaWYgKHRoaXMubGF6eUluaXQgaW5zdGFuY2VvZiBIdHRwSGVhZGVycykge1xuICAgICAgICB0aGlzLmNvcHlGcm9tKHRoaXMubGF6eUluaXQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5sYXp5SW5pdCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5sYXp5SW5pdCA9IG51bGw7XG4gICAgICBpZiAoISF0aGlzLmxhenlVcGRhdGUpIHtcbiAgICAgICAgdGhpcy5sYXp5VXBkYXRlLmZvckVhY2godXBkYXRlID0+IHRoaXMuYXBwbHlVcGRhdGUodXBkYXRlKSk7XG4gICAgICAgIHRoaXMubGF6eVVwZGF0ZSA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGNvcHlGcm9tKG90aGVyKSB7XG4gICAgb3RoZXIuaW5pdCgpO1xuICAgIEFycmF5LmZyb20ob3RoZXIuaGVhZGVycy5rZXlzKCkpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIHRoaXMuaGVhZGVycy5zZXQoa2V5LCBvdGhlci5oZWFkZXJzLmdldChrZXkpKTtcbiAgICAgIHRoaXMubm9ybWFsaXplZE5hbWVzLnNldChrZXksIG90aGVyLm5vcm1hbGl6ZWROYW1lcy5nZXQoa2V5KSk7XG4gICAgfSk7XG4gIH1cbiAgY2xvbmUodXBkYXRlKSB7XG4gICAgY29uc3QgY2xvbmUgPSBuZXcgSHR0cEhlYWRlcnMoKTtcbiAgICBjbG9uZS5sYXp5SW5pdCA9ICEhdGhpcy5sYXp5SW5pdCAmJiB0aGlzLmxhenlJbml0IGluc3RhbmNlb2YgSHR0cEhlYWRlcnMgPyB0aGlzLmxhenlJbml0IDogdGhpcztcbiAgICBjbG9uZS5sYXp5VXBkYXRlID0gKHRoaXMubGF6eVVwZGF0ZSB8fCBbXSkuY29uY2F0KFt1cGRhdGVdKTtcbiAgICByZXR1cm4gY2xvbmU7XG4gIH1cbiAgYXBwbHlVcGRhdGUodXBkYXRlKSB7XG4gICAgY29uc3Qga2V5ID0gdXBkYXRlLm5hbWUudG9Mb3dlckNhc2UoKTtcbiAgICBzd2l0Y2ggKHVwZGF0ZS5vcCkge1xuICAgICAgY2FzZSAnYSc6XG4gICAgICBjYXNlICdzJzpcbiAgICAgICAgbGV0IHZhbHVlID0gdXBkYXRlLnZhbHVlO1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHZhbHVlID0gW3ZhbHVlXTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubWF5YmVTZXROb3JtYWxpemVkTmFtZSh1cGRhdGUubmFtZSwga2V5KTtcbiAgICAgICAgY29uc3QgYmFzZSA9ICh1cGRhdGUub3AgPT09ICdhJyA/IHRoaXMuaGVhZGVycy5nZXQoa2V5KSA6IHVuZGVmaW5lZCkgfHwgW107XG4gICAgICAgIGJhc2UucHVzaCguLi52YWx1ZSk7XG4gICAgICAgIHRoaXMuaGVhZGVycy5zZXQoa2V5LCBiYXNlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdkJzpcbiAgICAgICAgY29uc3QgdG9EZWxldGUgPSB1cGRhdGUudmFsdWU7XG4gICAgICAgIGlmICghdG9EZWxldGUpIHtcbiAgICAgICAgICB0aGlzLmhlYWRlcnMuZGVsZXRlKGtleSk7XG4gICAgICAgICAgdGhpcy5ub3JtYWxpemVkTmFtZXMuZGVsZXRlKGtleSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbGV0IGV4aXN0aW5nID0gdGhpcy5oZWFkZXJzLmdldChrZXkpO1xuICAgICAgICAgIGlmICghZXhpc3RpbmcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgZXhpc3RpbmcgPSBleGlzdGluZy5maWx0ZXIodmFsdWUgPT4gdG9EZWxldGUuaW5kZXhPZih2YWx1ZSkgPT09IC0xKTtcbiAgICAgICAgICBpZiAoZXhpc3RpbmcubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLmhlYWRlcnMuZGVsZXRlKGtleSk7XG4gICAgICAgICAgICB0aGlzLm5vcm1hbGl6ZWROYW1lcy5kZWxldGUoa2V5KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5oZWFkZXJzLnNldChrZXksIGV4aXN0aW5nKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIHNldEhlYWRlckVudHJpZXMobmFtZSwgdmFsdWVzKSB7XG4gICAgY29uc3QgaGVhZGVyVmFsdWVzID0gKEFycmF5LmlzQXJyYXkodmFsdWVzKSA/IHZhbHVlcyA6IFt2YWx1ZXNdKS5tYXAodmFsdWUgPT4gdmFsdWUudG9TdHJpbmcoKSk7XG4gICAgY29uc3Qga2V5ID0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIHRoaXMuaGVhZGVycy5zZXQoa2V5LCBoZWFkZXJWYWx1ZXMpO1xuICAgIHRoaXMubWF5YmVTZXROb3JtYWxpemVkTmFtZShuYW1lLCBrZXkpO1xuICB9XG4gIC8qKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIGZvckVhY2goZm4pIHtcbiAgICB0aGlzLmluaXQoKTtcbiAgICBBcnJheS5mcm9tKHRoaXMubm9ybWFsaXplZE5hbWVzLmtleXMoKSkuZm9yRWFjaChrZXkgPT4gZm4odGhpcy5ub3JtYWxpemVkTmFtZXMuZ2V0KGtleSksIHRoaXMuaGVhZGVycy5nZXQoa2V5KSkpO1xuICB9XG59XG4vKipcbiAqIFZlcmlmaWVzIHRoYXQgdGhlIGhlYWRlcnMgb2JqZWN0IGhhcyB0aGUgcmlnaHQgc2hhcGU6IHRoZSB2YWx1ZXNcbiAqIG11c3QgYmUgZWl0aGVyIHN0cmluZ3MsIG51bWJlcnMgb3IgYXJyYXlzLiBUaHJvd3MgYW4gZXJyb3IgaWYgYW4gaW52YWxpZFxuICogaGVhZGVyIHZhbHVlIGlzIHByZXNlbnQuXG4gKi9cbmZ1bmN0aW9uIGFzc2VydFZhbGlkSGVhZGVycyhoZWFkZXJzKSB7XG4gIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKGhlYWRlcnMpKSB7XG4gICAgaWYgKCEodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJyB8fCB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSAmJiAhQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCB2YWx1ZSBvZiB0aGUgXFxgJHtrZXl9XFxgIGhlYWRlciBwcm92aWRlZC4gYCArIGBFeHBlY3RpbmcgZWl0aGVyIGEgc3RyaW5nLCBhIG51bWJlciBvciBhbiBhcnJheSwgYnV0IGdvdDogXFxgJHt2YWx1ZX1cXGAuYCk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUHJvdmlkZXMgZW5jb2RpbmcgYW5kIGRlY29kaW5nIG9mIFVSTCBwYXJhbWV0ZXIgYW5kIHF1ZXJ5LXN0cmluZyB2YWx1ZXMuXG4gKlxuICogU2VyaWFsaXplcyBhbmQgcGFyc2VzIFVSTCBwYXJhbWV0ZXIga2V5cyBhbmQgdmFsdWVzIHRvIGVuY29kZSBhbmQgZGVjb2RlIHRoZW0uXG4gKiBJZiB5b3UgcGFzcyBVUkwgcXVlcnkgcGFyYW1ldGVycyB3aXRob3V0IGVuY29kaW5nLFxuICogdGhlIHF1ZXJ5IHBhcmFtZXRlcnMgY2FuIGJlIG1pc2ludGVycHJldGVkIGF0IHRoZSByZWNlaXZpbmcgZW5kLlxuICpcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIEh0dHBVcmxFbmNvZGluZ0NvZGVjIHtcbiAgLyoqXG4gICAqIEVuY29kZXMgYSBrZXkgbmFtZSBmb3IgYSBVUkwgcGFyYW1ldGVyIG9yIHF1ZXJ5LXN0cmluZy5cbiAgICogQHBhcmFtIGtleSBUaGUga2V5IG5hbWUuXG4gICAqIEByZXR1cm5zIFRoZSBlbmNvZGVkIGtleSBuYW1lLlxuICAgKi9cbiAgZW5jb2RlS2V5KGtleSkge1xuICAgIHJldHVybiBzdGFuZGFyZEVuY29kaW5nKGtleSk7XG4gIH1cbiAgLyoqXG4gICAqIEVuY29kZXMgdGhlIHZhbHVlIG9mIGEgVVJMIHBhcmFtZXRlciBvciBxdWVyeS1zdHJpbmcuXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUuXG4gICAqIEByZXR1cm5zIFRoZSBlbmNvZGVkIHZhbHVlLlxuICAgKi9cbiAgZW5jb2RlVmFsdWUodmFsdWUpIHtcbiAgICByZXR1cm4gc3RhbmRhcmRFbmNvZGluZyh2YWx1ZSk7XG4gIH1cbiAgLyoqXG4gICAqIERlY29kZXMgYW4gZW5jb2RlZCBVUkwgcGFyYW1ldGVyIG9yIHF1ZXJ5LXN0cmluZyBrZXkuXG4gICAqIEBwYXJhbSBrZXkgVGhlIGVuY29kZWQga2V5IG5hbWUuXG4gICAqIEByZXR1cm5zIFRoZSBkZWNvZGVkIGtleSBuYW1lLlxuICAgKi9cbiAgZGVjb2RlS2V5KGtleSkge1xuICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoa2V5KTtcbiAgfVxuICAvKipcbiAgICogRGVjb2RlcyBhbiBlbmNvZGVkIFVSTCBwYXJhbWV0ZXIgb3IgcXVlcnktc3RyaW5nIHZhbHVlLlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIGVuY29kZWQgdmFsdWUuXG4gICAqIEByZXR1cm5zIFRoZSBkZWNvZGVkIHZhbHVlLlxuICAgKi9cbiAgZGVjb2RlVmFsdWUodmFsdWUpIHtcbiAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcbiAgfVxufVxuZnVuY3Rpb24gcGFyYW1QYXJzZXIocmF3UGFyYW1zLCBjb2RlYykge1xuICBjb25zdCBtYXAgPSBuZXcgTWFwKCk7XG4gIGlmIChyYXdQYXJhbXMubGVuZ3RoID4gMCkge1xuICAgIC8vIFRoZSBgd2luZG93LmxvY2F0aW9uLnNlYXJjaGAgY2FuIGJlIHVzZWQgd2hpbGUgY3JlYXRpbmcgYW4gaW5zdGFuY2Ugb2YgdGhlIGBIdHRwUGFyYW1zYCBjbGFzc1xuICAgIC8vIChlLmcuIGBuZXcgSHR0cFBhcmFtcyh7IGZyb21TdHJpbmc6IHdpbmRvdy5sb2NhdGlvbi5zZWFyY2ggfSlgKS4gVGhlIGB3aW5kb3cubG9jYXRpb24uc2VhcmNoYFxuICAgIC8vIG1heSBzdGFydCB3aXRoIHRoZSBgP2AgY2hhciwgc28gd2Ugc3RyaXAgaXQgaWYgaXQncyBwcmVzZW50LlxuICAgIGNvbnN0IHBhcmFtcyA9IHJhd1BhcmFtcy5yZXBsYWNlKC9eXFw/LywgJycpLnNwbGl0KCcmJyk7XG4gICAgcGFyYW1zLmZvckVhY2gocGFyYW0gPT4ge1xuICAgICAgY29uc3QgZXFJZHggPSBwYXJhbS5pbmRleE9mKCc9Jyk7XG4gICAgICBjb25zdCBba2V5LCB2YWxdID0gZXFJZHggPT0gLTEgPyBbY29kZWMuZGVjb2RlS2V5KHBhcmFtKSwgJyddIDogW2NvZGVjLmRlY29kZUtleShwYXJhbS5zbGljZSgwLCBlcUlkeCkpLCBjb2RlYy5kZWNvZGVWYWx1ZShwYXJhbS5zbGljZShlcUlkeCArIDEpKV07XG4gICAgICBjb25zdCBsaXN0ID0gbWFwLmdldChrZXkpIHx8IFtdO1xuICAgICAgbGlzdC5wdXNoKHZhbCk7XG4gICAgICBtYXAuc2V0KGtleSwgbGlzdCk7XG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG1hcDtcbn1cbi8qKlxuICogRW5jb2RlIGlucHV0IHN0cmluZyB3aXRoIHN0YW5kYXJkIGVuY29kZVVSSUNvbXBvbmVudCBhbmQgdGhlbiB1bi1lbmNvZGUgc3BlY2lmaWMgY2hhcmFjdGVycy5cbiAqL1xuY29uc3QgU1RBTkRBUkRfRU5DT0RJTkdfUkVHRVggPSAvJShcXGRbYS1mMC05XSkvZ2k7XG5jb25zdCBTVEFOREFSRF9FTkNPRElOR19SRVBMQUNFTUVOVFMgPSB7XG4gICc0MCc6ICdAJyxcbiAgJzNBJzogJzonLFxuICAnMjQnOiAnJCcsXG4gICcyQyc6ICcsJyxcbiAgJzNCJzogJzsnLFxuICAnM0QnOiAnPScsXG4gICczRic6ICc/JyxcbiAgJzJGJzogJy8nXG59O1xuZnVuY3Rpb24gc3RhbmRhcmRFbmNvZGluZyh2KSB7XG4gIHJldHVybiBlbmNvZGVVUklDb21wb25lbnQodikucmVwbGFjZShTVEFOREFSRF9FTkNPRElOR19SRUdFWCwgKHMsIHQpID0+IFNUQU5EQVJEX0VOQ09ESU5HX1JFUExBQ0VNRU5UU1t0XSA/PyBzKTtcbn1cbmZ1bmN0aW9uIHZhbHVlVG9TdHJpbmcodmFsdWUpIHtcbiAgcmV0dXJuIGAke3ZhbHVlfWA7XG59XG4vKipcbiAqIEFuIEhUVFAgcmVxdWVzdC9yZXNwb25zZSBib2R5IHRoYXQgcmVwcmVzZW50cyBzZXJpYWxpemVkIHBhcmFtZXRlcnMsXG4gKiBwZXIgdGhlIE1JTUUgdHlwZSBgYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkYC5cbiAqXG4gKiBUaGlzIGNsYXNzIGlzIGltbXV0YWJsZTsgYWxsIG11dGF0aW9uIG9wZXJhdGlvbnMgcmV0dXJuIGEgbmV3IGluc3RhbmNlLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgSHR0cFBhcmFtcyB7XG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMudXBkYXRlcyA9IG51bGw7XG4gICAgdGhpcy5jbG9uZUZyb20gPSBudWxsO1xuICAgIHRoaXMuZW5jb2RlciA9IG9wdGlvbnMuZW5jb2RlciB8fCBuZXcgSHR0cFVybEVuY29kaW5nQ29kZWMoKTtcbiAgICBpZiAoISFvcHRpb25zLmZyb21TdHJpbmcpIHtcbiAgICAgIGlmICghIW9wdGlvbnMuZnJvbU9iamVjdCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbm5vdCBzcGVjaWZ5IGJvdGggZnJvbVN0cmluZyBhbmQgZnJvbU9iamVjdC5gKTtcbiAgICAgIH1cbiAgICAgIHRoaXMubWFwID0gcGFyYW1QYXJzZXIob3B0aW9ucy5mcm9tU3RyaW5nLCB0aGlzLmVuY29kZXIpO1xuICAgIH0gZWxzZSBpZiAoISFvcHRpb25zLmZyb21PYmplY3QpIHtcbiAgICAgIHRoaXMubWFwID0gbmV3IE1hcCgpO1xuICAgICAgT2JqZWN0LmtleXMob3B0aW9ucy5mcm9tT2JqZWN0KS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gb3B0aW9ucy5mcm9tT2JqZWN0W2tleV07XG4gICAgICAgIC8vIGNvbnZlcnQgdGhlIHZhbHVlcyB0byBzdHJpbmdzXG4gICAgICAgIGNvbnN0IHZhbHVlcyA9IEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUubWFwKHZhbHVlVG9TdHJpbmcpIDogW3ZhbHVlVG9TdHJpbmcodmFsdWUpXTtcbiAgICAgICAgdGhpcy5tYXAuc2V0KGtleSwgdmFsdWVzKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm1hcCA9IG51bGw7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBSZXBvcnRzIHdoZXRoZXIgdGhlIGJvZHkgaW5jbHVkZXMgb25lIG9yIG1vcmUgdmFsdWVzIGZvciBhIGdpdmVuIHBhcmFtZXRlci5cbiAgICogQHBhcmFtIHBhcmFtIFRoZSBwYXJhbWV0ZXIgbmFtZS5cbiAgICogQHJldHVybnMgVHJ1ZSBpZiB0aGUgcGFyYW1ldGVyIGhhcyBvbmUgb3IgbW9yZSB2YWx1ZXMsXG4gICAqIGZhbHNlIGlmIGl0IGhhcyBubyB2YWx1ZSBvciBpcyBub3QgcHJlc2VudC5cbiAgICovXG4gIGhhcyhwYXJhbSkge1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIHJldHVybiB0aGlzLm1hcC5oYXMocGFyYW0pO1xuICB9XG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgdGhlIGZpcnN0IHZhbHVlIGZvciBhIHBhcmFtZXRlci5cbiAgICogQHBhcmFtIHBhcmFtIFRoZSBwYXJhbWV0ZXIgbmFtZS5cbiAgICogQHJldHVybnMgVGhlIGZpcnN0IHZhbHVlIG9mIHRoZSBnaXZlbiBwYXJhbWV0ZXIsXG4gICAqIG9yIGBudWxsYCBpZiB0aGUgcGFyYW1ldGVyIGlzIG5vdCBwcmVzZW50LlxuICAgKi9cbiAgZ2V0KHBhcmFtKSB7XG4gICAgdGhpcy5pbml0KCk7XG4gICAgY29uc3QgcmVzID0gdGhpcy5tYXAuZ2V0KHBhcmFtKTtcbiAgICByZXR1cm4gISFyZXMgPyByZXNbMF0gOiBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgYWxsIHZhbHVlcyBmb3IgYSAgcGFyYW1ldGVyLlxuICAgKiBAcGFyYW0gcGFyYW0gVGhlIHBhcmFtZXRlciBuYW1lLlxuICAgKiBAcmV0dXJucyBBbGwgdmFsdWVzIGluIGEgc3RyaW5nIGFycmF5LFxuICAgKiBvciBgbnVsbGAgaWYgdGhlIHBhcmFtZXRlciBub3QgcHJlc2VudC5cbiAgICovXG4gIGdldEFsbChwYXJhbSkge1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIHJldHVybiB0aGlzLm1hcC5nZXQocGFyYW0pIHx8IG51bGw7XG4gIH1cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBhbGwgdGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgYm9keS5cbiAgICogQHJldHVybnMgVGhlIHBhcmFtZXRlciBuYW1lcyBpbiBhIHN0cmluZyBhcnJheS5cbiAgICovXG4gIGtleXMoKSB7XG4gICAgdGhpcy5pbml0KCk7XG4gICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy5tYXAua2V5cygpKTtcbiAgfVxuICAvKipcbiAgICogQXBwZW5kcyBhIG5ldyB2YWx1ZSB0byBleGlzdGluZyB2YWx1ZXMgZm9yIGEgcGFyYW1ldGVyLlxuICAgKiBAcGFyYW0gcGFyYW0gVGhlIHBhcmFtZXRlciBuYW1lLlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5ldyB2YWx1ZSB0byBhZGQuXG4gICAqIEByZXR1cm4gQSBuZXcgYm9keSB3aXRoIHRoZSBhcHBlbmRlZCB2YWx1ZS5cbiAgICovXG4gIGFwcGVuZChwYXJhbSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSh7XG4gICAgICBwYXJhbSxcbiAgICAgIHZhbHVlLFxuICAgICAgb3A6ICdhJ1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGEgbmV3IGJvZHkgd2l0aCBhcHBlbmRlZCB2YWx1ZXMgZm9yIHRoZSBnaXZlbiBwYXJhbWV0ZXIgbmFtZS5cbiAgICogQHBhcmFtIHBhcmFtcyBwYXJhbWV0ZXJzIGFuZCB2YWx1ZXNcbiAgICogQHJldHVybiBBIG5ldyBib2R5IHdpdGggdGhlIG5ldyB2YWx1ZS5cbiAgICovXG4gIGFwcGVuZEFsbChwYXJhbXMpIHtcbiAgICBjb25zdCB1cGRhdGVzID0gW107XG4gICAgT2JqZWN0LmtleXMocGFyYW1zKS5mb3JFYWNoKHBhcmFtID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gcGFyYW1zW3BhcmFtXTtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZS5mb3JFYWNoKF92YWx1ZSA9PiB7XG4gICAgICAgICAgdXBkYXRlcy5wdXNoKHtcbiAgICAgICAgICAgIHBhcmFtLFxuICAgICAgICAgICAgdmFsdWU6IF92YWx1ZSxcbiAgICAgICAgICAgIG9wOiAnYSdcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1cGRhdGVzLnB1c2goe1xuICAgICAgICAgIHBhcmFtLFxuICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICBvcDogJ2EnXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLmNsb25lKHVwZGF0ZXMpO1xuICB9XG4gIC8qKlxuICAgKiBSZXBsYWNlcyB0aGUgdmFsdWUgZm9yIGEgcGFyYW1ldGVyLlxuICAgKiBAcGFyYW0gcGFyYW0gVGhlIHBhcmFtZXRlciBuYW1lLlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIG5ldyB2YWx1ZS5cbiAgICogQHJldHVybiBBIG5ldyBib2R5IHdpdGggdGhlIG5ldyB2YWx1ZS5cbiAgICovXG4gIHNldChwYXJhbSwgdmFsdWUpIHtcbiAgICByZXR1cm4gdGhpcy5jbG9uZSh7XG4gICAgICBwYXJhbSxcbiAgICAgIHZhbHVlLFxuICAgICAgb3A6ICdzJ1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgZ2l2ZW4gdmFsdWUgb3IgYWxsIHZhbHVlcyBmcm9tIGEgcGFyYW1ldGVyLlxuICAgKiBAcGFyYW0gcGFyYW0gVGhlIHBhcmFtZXRlciBuYW1lLlxuICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIHJlbW92ZSwgaWYgcHJvdmlkZWQuXG4gICAqIEByZXR1cm4gQSBuZXcgYm9keSB3aXRoIHRoZSBnaXZlbiB2YWx1ZSByZW1vdmVkLCBvciB3aXRoIGFsbCB2YWx1ZXNcbiAgICogcmVtb3ZlZCBpZiBubyB2YWx1ZSBpcyBzcGVjaWZpZWQuXG4gICAqL1xuICBkZWxldGUocGFyYW0sIHZhbHVlKSB7XG4gICAgcmV0dXJuIHRoaXMuY2xvbmUoe1xuICAgICAgcGFyYW0sXG4gICAgICB2YWx1ZSxcbiAgICAgIG9wOiAnZCdcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogU2VyaWFsaXplcyB0aGUgYm9keSB0byBhbiBlbmNvZGVkIHN0cmluZywgd2hlcmUga2V5LXZhbHVlIHBhaXJzIChzZXBhcmF0ZWQgYnkgYD1gKSBhcmVcbiAgICogc2VwYXJhdGVkIGJ5IGAmYHMuXG4gICAqL1xuICB0b1N0cmluZygpIHtcbiAgICB0aGlzLmluaXQoKTtcbiAgICByZXR1cm4gdGhpcy5rZXlzKCkubWFwKGtleSA9PiB7XG4gICAgICBjb25zdCBlS2V5ID0gdGhpcy5lbmNvZGVyLmVuY29kZUtleShrZXkpO1xuICAgICAgLy8gYGE6IFsnMSddYCBwcm9kdWNlcyBgJ2E9MSdgXG4gICAgICAvLyBgYjogW11gIHByb2R1Y2VzIGAnJ2BcbiAgICAgIC8vIGBjOiBbJzEnLCAnMiddYCBwcm9kdWNlcyBgJ2M9MSZjPTInYFxuICAgICAgcmV0dXJuIHRoaXMubWFwLmdldChrZXkpLm1hcCh2YWx1ZSA9PiBlS2V5ICsgJz0nICsgdGhpcy5lbmNvZGVyLmVuY29kZVZhbHVlKHZhbHVlKSkuam9pbignJicpO1xuICAgIH0pXG4gICAgLy8gZmlsdGVyIG91dCBlbXB0eSB2YWx1ZXMgYmVjYXVzZSBgYjogW11gIHByb2R1Y2VzIGAnJ2BcbiAgICAvLyB3aGljaCByZXN1bHRzIGluIGBhPTEmJmM9MSZjPTJgIGluc3RlYWQgb2YgYGE9MSZjPTEmYz0yYCBpZiB3ZSBkb24ndFxuICAgIC5maWx0ZXIocGFyYW0gPT4gcGFyYW0gIT09ICcnKS5qb2luKCcmJyk7XG4gIH1cbiAgY2xvbmUodXBkYXRlKSB7XG4gICAgY29uc3QgY2xvbmUgPSBuZXcgSHR0cFBhcmFtcyh7XG4gICAgICBlbmNvZGVyOiB0aGlzLmVuY29kZXJcbiAgICB9KTtcbiAgICBjbG9uZS5jbG9uZUZyb20gPSB0aGlzLmNsb25lRnJvbSB8fCB0aGlzO1xuICAgIGNsb25lLnVwZGF0ZXMgPSAodGhpcy51cGRhdGVzIHx8IFtdKS5jb25jYXQodXBkYXRlKTtcbiAgICByZXR1cm4gY2xvbmU7XG4gIH1cbiAgaW5pdCgpIHtcbiAgICBpZiAodGhpcy5tYXAgPT09IG51bGwpIHtcbiAgICAgIHRoaXMubWFwID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5jbG9uZUZyb20gIT09IG51bGwpIHtcbiAgICAgIHRoaXMuY2xvbmVGcm9tLmluaXQoKTtcbiAgICAgIHRoaXMuY2xvbmVGcm9tLmtleXMoKS5mb3JFYWNoKGtleSA9PiB0aGlzLm1hcC5zZXQoa2V5LCB0aGlzLmNsb25lRnJvbS5tYXAuZ2V0KGtleSkpKTtcbiAgICAgIHRoaXMudXBkYXRlcy5mb3JFYWNoKHVwZGF0ZSA9PiB7XG4gICAgICAgIHN3aXRjaCAodXBkYXRlLm9wKSB7XG4gICAgICAgICAgY2FzZSAnYSc6XG4gICAgICAgICAgY2FzZSAncyc6XG4gICAgICAgICAgICBjb25zdCBiYXNlID0gKHVwZGF0ZS5vcCA9PT0gJ2EnID8gdGhpcy5tYXAuZ2V0KHVwZGF0ZS5wYXJhbSkgOiB1bmRlZmluZWQpIHx8IFtdO1xuICAgICAgICAgICAgYmFzZS5wdXNoKHZhbHVlVG9TdHJpbmcodXBkYXRlLnZhbHVlKSk7XG4gICAgICAgICAgICB0aGlzLm1hcC5zZXQodXBkYXRlLnBhcmFtLCBiYXNlKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2QnOlxuICAgICAgICAgICAgaWYgKHVwZGF0ZS52YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGxldCBiYXNlID0gdGhpcy5tYXAuZ2V0KHVwZGF0ZS5wYXJhbSkgfHwgW107XG4gICAgICAgICAgICAgIGNvbnN0IGlkeCA9IGJhc2UuaW5kZXhPZih2YWx1ZVRvU3RyaW5nKHVwZGF0ZS52YWx1ZSkpO1xuICAgICAgICAgICAgICBpZiAoaWR4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIGJhc2Uuc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGJhc2UubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMubWFwLnNldCh1cGRhdGUucGFyYW0sIGJhc2UpO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMubWFwLmRlbGV0ZSh1cGRhdGUucGFyYW0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLm1hcC5kZWxldGUodXBkYXRlLnBhcmFtKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgdGhpcy5jbG9uZUZyb20gPSB0aGlzLnVwZGF0ZXMgPSBudWxsO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEEgdG9rZW4gdXNlZCB0byBtYW5pcHVsYXRlIGFuZCBhY2Nlc3MgdmFsdWVzIHN0b3JlZCBpbiBgSHR0cENvbnRleHRgLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xuY2xhc3MgSHR0cENvbnRleHRUb2tlbiB7XG4gIGNvbnN0cnVjdG9yKGRlZmF1bHRWYWx1ZSkge1xuICAgIHRoaXMuZGVmYXVsdFZhbHVlID0gZGVmYXVsdFZhbHVlO1xuICB9XG59XG4vKipcbiAqIEh0dHAgY29udGV4dCBzdG9yZXMgYXJiaXRyYXJ5IHVzZXIgZGVmaW5lZCB2YWx1ZXMgYW5kIGVuc3VyZXMgdHlwZSBzYWZldHkgd2l0aG91dFxuICogYWN0dWFsbHkga25vd2luZyB0aGUgdHlwZXMuIEl0IGlzIGJhY2tlZCBieSBhIGBNYXBgIGFuZCBndWFyYW50ZWVzIHRoYXQga2V5cyBkbyBub3QgY2xhc2guXG4gKlxuICogVGhpcyBjb250ZXh0IGlzIG11dGFibGUgYW5kIGlzIHNoYXJlZCBiZXR3ZWVuIGNsb25lZCByZXF1ZXN0cyB1bmxlc3MgZXhwbGljaXRseSBzcGVjaWZpZWQuXG4gKlxuICogQHVzYWdlTm90ZXNcbiAqXG4gKiAjIyMgVXNhZ2UgRXhhbXBsZVxuICpcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIGluc2lkZSBjYWNoZS5pbnRlcmNlcHRvcnMudHNcbiAqIGV4cG9ydCBjb25zdCBJU19DQUNIRV9FTkFCTEVEID0gbmV3IEh0dHBDb250ZXh0VG9rZW48Ym9vbGVhbj4oKCkgPT4gZmFsc2UpO1xuICpcbiAqIGV4cG9ydCBjbGFzcyBDYWNoZUludGVyY2VwdG9yIGltcGxlbWVudHMgSHR0cEludGVyY2VwdG9yIHtcbiAqXG4gKiAgIGludGVyY2VwdChyZXE6IEh0dHBSZXF1ZXN0PGFueT4sIGRlbGVnYXRlOiBIdHRwSGFuZGxlcik6IE9ic2VydmFibGU8SHR0cEV2ZW50PGFueT4+IHtcbiAqICAgICBpZiAocmVxLmNvbnRleHQuZ2V0KElTX0NBQ0hFX0VOQUJMRUQpID09PSB0cnVlKSB7XG4gKiAgICAgICByZXR1cm4gLi4uO1xuICogICAgIH1cbiAqICAgICByZXR1cm4gZGVsZWdhdGUuaGFuZGxlKHJlcSk7XG4gKiAgIH1cbiAqIH1cbiAqXG4gKiAvLyBpbnNpZGUgYSBzZXJ2aWNlXG4gKlxuICogdGhpcy5odHRwQ2xpZW50LmdldCgnL2FwaS93ZWF0aGVyJywge1xuICogICBjb250ZXh0OiBuZXcgSHR0cENvbnRleHQoKS5zZXQoSVNfQ0FDSEVfRU5BQkxFRCwgdHJ1ZSlcbiAqIH0pLnN1YnNjcmliZSguLi4pO1xuICogYGBgXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBIdHRwQ29udGV4dCB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMubWFwID0gbmV3IE1hcCgpO1xuICB9XG4gIC8qKlxuICAgKiBTdG9yZSBhIHZhbHVlIGluIHRoZSBjb250ZXh0LiBJZiBhIHZhbHVlIGlzIGFscmVhZHkgcHJlc2VudCBpdCB3aWxsIGJlIG92ZXJ3cml0dGVuLlxuICAgKlxuICAgKiBAcGFyYW0gdG9rZW4gVGhlIHJlZmVyZW5jZSB0byBhbiBpbnN0YW5jZSBvZiBgSHR0cENvbnRleHRUb2tlbmAuXG4gICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc3RvcmUuXG4gICAqXG4gICAqIEByZXR1cm5zIEEgcmVmZXJlbmNlIHRvIGl0c2VsZiBmb3IgZWFzeSBjaGFpbmluZy5cbiAgICovXG4gIHNldCh0b2tlbiwgdmFsdWUpIHtcbiAgICB0aGlzLm1hcC5zZXQodG9rZW4sIHZhbHVlKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuICAvKipcbiAgICogUmV0cmlldmUgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgZ2l2ZW4gdG9rZW4uXG4gICAqXG4gICAqIEBwYXJhbSB0b2tlbiBUaGUgcmVmZXJlbmNlIHRvIGFuIGluc3RhbmNlIG9mIGBIdHRwQ29udGV4dFRva2VuYC5cbiAgICpcbiAgICogQHJldHVybnMgVGhlIHN0b3JlZCB2YWx1ZSBvciBkZWZhdWx0IGlmIG9uZSBpcyBkZWZpbmVkLlxuICAgKi9cbiAgZ2V0KHRva2VuKSB7XG4gICAgaWYgKCF0aGlzLm1hcC5oYXModG9rZW4pKSB7XG4gICAgICB0aGlzLm1hcC5zZXQodG9rZW4sIHRva2VuLmRlZmF1bHRWYWx1ZSgpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubWFwLmdldCh0b2tlbik7XG4gIH1cbiAgLyoqXG4gICAqIERlbGV0ZSB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiB0b2tlbi5cbiAgICpcbiAgICogQHBhcmFtIHRva2VuIFRoZSByZWZlcmVuY2UgdG8gYW4gaW5zdGFuY2Ugb2YgYEh0dHBDb250ZXh0VG9rZW5gLlxuICAgKlxuICAgKiBAcmV0dXJucyBBIHJlZmVyZW5jZSB0byBpdHNlbGYgZm9yIGVhc3kgY2hhaW5pbmcuXG4gICAqL1xuICBkZWxldGUodG9rZW4pIHtcbiAgICB0aGlzLm1hcC5kZWxldGUodG9rZW4pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIC8qKlxuICAgKiBDaGVja3MgZm9yIGV4aXN0ZW5jZSBvZiBhIGdpdmVuIHRva2VuLlxuICAgKlxuICAgKiBAcGFyYW0gdG9rZW4gVGhlIHJlZmVyZW5jZSB0byBhbiBpbnN0YW5jZSBvZiBgSHR0cENvbnRleHRUb2tlbmAuXG4gICAqXG4gICAqIEByZXR1cm5zIFRydWUgaWYgdGhlIHRva2VuIGV4aXN0cywgZmFsc2Ugb3RoZXJ3aXNlLlxuICAgKi9cbiAgaGFzKHRva2VuKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwLmhhcyh0b2tlbik7XG4gIH1cbiAgLyoqXG4gICAqIEByZXR1cm5zIGEgbGlzdCBvZiB0b2tlbnMgY3VycmVudGx5IHN0b3JlZCBpbiB0aGUgY29udGV4dC5cbiAgICovXG4gIGtleXMoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwLmtleXMoKTtcbiAgfVxufVxuXG4vKipcbiAqIERldGVybWluZSB3aGV0aGVyIHRoZSBnaXZlbiBIVFRQIG1ldGhvZCBtYXkgaW5jbHVkZSBhIGJvZHkuXG4gKi9cbmZ1bmN0aW9uIG1pZ2h0SGF2ZUJvZHkobWV0aG9kKSB7XG4gIHN3aXRjaCAobWV0aG9kKSB7XG4gICAgY2FzZSAnREVMRVRFJzpcbiAgICBjYXNlICdHRVQnOlxuICAgIGNhc2UgJ0hFQUQnOlxuICAgIGNhc2UgJ09QVElPTlMnOlxuICAgIGNhc2UgJ0pTT05QJzpcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHRydWU7XG4gIH1cbn1cbi8qKlxuICogU2FmZWx5IGFzc2VydCB3aGV0aGVyIHRoZSBnaXZlbiB2YWx1ZSBpcyBhbiBBcnJheUJ1ZmZlci5cbiAqXG4gKiBJbiBzb21lIGV4ZWN1dGlvbiBlbnZpcm9ubWVudHMgQXJyYXlCdWZmZXIgaXMgbm90IGRlZmluZWQuXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXlCdWZmZXIodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiBBcnJheUJ1ZmZlciAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcjtcbn1cbi8qKlxuICogU2FmZWx5IGFzc2VydCB3aGV0aGVyIHRoZSBnaXZlbiB2YWx1ZSBpcyBhIEJsb2IuXG4gKlxuICogSW4gc29tZSBleGVjdXRpb24gZW52aXJvbm1lbnRzIEJsb2IgaXMgbm90IGRlZmluZWQuXG4gKi9cbmZ1bmN0aW9uIGlzQmxvYih2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIEJsb2IgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlIGluc3RhbmNlb2YgQmxvYjtcbn1cbi8qKlxuICogU2FmZWx5IGFzc2VydCB3aGV0aGVyIHRoZSBnaXZlbiB2YWx1ZSBpcyBhIEZvcm1EYXRhIGluc3RhbmNlLlxuICpcbiAqIEluIHNvbWUgZXhlY3V0aW9uIGVudmlyb25tZW50cyBGb3JtRGF0YSBpcyBub3QgZGVmaW5lZC5cbiAqL1xuZnVuY3Rpb24gaXNGb3JtRGF0YSh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIEZvcm1EYXRhICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIEZvcm1EYXRhO1xufVxuLyoqXG4gKiBTYWZlbHkgYXNzZXJ0IHdoZXRoZXIgdGhlIGdpdmVuIHZhbHVlIGlzIGEgVVJMU2VhcmNoUGFyYW1zIGluc3RhbmNlLlxuICpcbiAqIEluIHNvbWUgZXhlY3V0aW9uIGVudmlyb25tZW50cyBVUkxTZWFyY2hQYXJhbXMgaXMgbm90IGRlZmluZWQuXG4gKi9cbmZ1bmN0aW9uIGlzVXJsU2VhcmNoUGFyYW1zKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgVVJMU2VhcmNoUGFyYW1zICE9PSAndW5kZWZpbmVkJyAmJiB2YWx1ZSBpbnN0YW5jZW9mIFVSTFNlYXJjaFBhcmFtcztcbn1cbi8qKlxuICogQW4gb3V0Z29pbmcgSFRUUCByZXF1ZXN0IHdpdGggYW4gb3B0aW9uYWwgdHlwZWQgYm9keS5cbiAqXG4gKiBgSHR0cFJlcXVlc3RgIHJlcHJlc2VudHMgYW4gb3V0Z29pbmcgcmVxdWVzdCwgaW5jbHVkaW5nIFVSTCwgbWV0aG9kLFxuICogaGVhZGVycywgYm9keSwgYW5kIG90aGVyIHJlcXVlc3QgY29uZmlndXJhdGlvbiBvcHRpb25zLiBJbnN0YW5jZXMgc2hvdWxkIGJlXG4gKiBhc3N1bWVkIHRvIGJlIGltbXV0YWJsZS4gVG8gbW9kaWZ5IGEgYEh0dHBSZXF1ZXN0YCwgdGhlIGBjbG9uZWBcbiAqIG1ldGhvZCBzaG91bGQgYmUgdXNlZC5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIEh0dHBSZXF1ZXN0IHtcbiAgY29uc3RydWN0b3IobWV0aG9kLCB1cmwsIHRoaXJkLCBmb3VydGgpIHtcbiAgICB0aGlzLnVybCA9IHVybDtcbiAgICAvKipcbiAgICAgKiBUaGUgcmVxdWVzdCBib2R5LCBvciBgbnVsbGAgaWYgb25lIGlzbid0IHNldC5cbiAgICAgKlxuICAgICAqIEJvZGllcyBhcmUgbm90IGVuZm9yY2VkIHRvIGJlIGltbXV0YWJsZSwgYXMgdGhleSBjYW4gaW5jbHVkZSBhIHJlZmVyZW5jZSB0byBhbnlcbiAgICAgKiB1c2VyLWRlZmluZWQgZGF0YSB0eXBlLiBIb3dldmVyLCBpbnRlcmNlcHRvcnMgc2hvdWxkIHRha2UgY2FyZSB0byBwcmVzZXJ2ZVxuICAgICAqIGlkZW1wb3RlbmNlIGJ5IHRyZWF0aW5nIHRoZW0gYXMgc3VjaC5cbiAgICAgKi9cbiAgICB0aGlzLmJvZHkgPSBudWxsO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhpcyByZXF1ZXN0IHNob3VsZCBiZSBtYWRlIGluIGEgd2F5IHRoYXQgZXhwb3NlcyBwcm9ncmVzcyBldmVudHMuXG4gICAgICpcbiAgICAgKiBQcm9ncmVzcyBldmVudHMgYXJlIGV4cGVuc2l2ZSAoY2hhbmdlIGRldGVjdGlvbiBydW5zIG9uIGVhY2ggZXZlbnQpIGFuZCBzb1xuICAgICAqIHRoZXkgc2hvdWxkIG9ubHkgYmUgcmVxdWVzdGVkIGlmIHRoZSBjb25zdW1lciBpbnRlbmRzIHRvIG1vbml0b3IgdGhlbS5cbiAgICAgKlxuICAgICAqIE5vdGU6IFRoZSBgRmV0Y2hCYWNrZW5kYCBkb2Vzbid0IHN1cHBvcnQgcHJvZ3Jlc3MgcmVwb3J0IG9uIHVwbG9hZHMuXG4gICAgICovXG4gICAgdGhpcy5yZXBvcnRQcm9ncmVzcyA9IGZhbHNlO1xuICAgIC8qKlxuICAgICAqIFdoZXRoZXIgdGhpcyByZXF1ZXN0IHNob3VsZCBiZSBzZW50IHdpdGggb3V0Z29pbmcgY3JlZGVudGlhbHMgKGNvb2tpZXMpLlxuICAgICAqL1xuICAgIHRoaXMud2l0aENyZWRlbnRpYWxzID0gZmFsc2U7XG4gICAgLyoqXG4gICAgICogVGhlIGV4cGVjdGVkIHJlc3BvbnNlIHR5cGUgb2YgdGhlIHNlcnZlci5cbiAgICAgKlxuICAgICAqIFRoaXMgaXMgdXNlZCB0byBwYXJzZSB0aGUgcmVzcG9uc2UgYXBwcm9wcmlhdGVseSBiZWZvcmUgcmV0dXJuaW5nIGl0IHRvXG4gICAgICogdGhlIHJlcXVlc3RlZS5cbiAgICAgKi9cbiAgICB0aGlzLnJlc3BvbnNlVHlwZSA9ICdqc29uJztcbiAgICB0aGlzLm1ldGhvZCA9IG1ldGhvZC50b1VwcGVyQ2FzZSgpO1xuICAgIC8vIE5leHQsIG5lZWQgdG8gZmlndXJlIG91dCB3aGljaCBhcmd1bWVudCBob2xkcyB0aGUgSHR0cFJlcXVlc3RJbml0XG4gICAgLy8gb3B0aW9ucywgaWYgYW55LlxuICAgIGxldCBvcHRpb25zO1xuICAgIC8vIENoZWNrIHdoZXRoZXIgYSBib2R5IGFyZ3VtZW50IGlzIGV4cGVjdGVkLiBUaGUgb25seSB2YWxpZCB3YXkgdG8gb21pdFxuICAgIC8vIHRoZSBib2R5IGFyZ3VtZW50IGlzIHRvIHVzZSBhIGtub3duIG5vLWJvZHkgbWV0aG9kIGxpa2UgR0VULlxuICAgIGlmIChtaWdodEhhdmVCb2R5KHRoaXMubWV0aG9kKSB8fCAhIWZvdXJ0aCkge1xuICAgICAgLy8gQm9keSBpcyB0aGUgdGhpcmQgYXJndW1lbnQsIG9wdGlvbnMgYXJlIHRoZSBmb3VydGguXG4gICAgICB0aGlzLmJvZHkgPSB0aGlyZCAhPT0gdW5kZWZpbmVkID8gdGhpcmQgOiBudWxsO1xuICAgICAgb3B0aW9ucyA9IGZvdXJ0aDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gTm8gYm9keSByZXF1aXJlZCwgb3B0aW9ucyBhcmUgdGhlIHRoaXJkIGFyZ3VtZW50LiBUaGUgYm9keSBzdGF5cyBudWxsLlxuICAgICAgb3B0aW9ucyA9IHRoaXJkO1xuICAgIH1cbiAgICAvLyBJZiBvcHRpb25zIGhhdmUgYmVlbiBwYXNzZWQsIGludGVycHJldCB0aGVtLlxuICAgIGlmIChvcHRpb25zKSB7XG4gICAgICAvLyBOb3JtYWxpemUgcmVwb3J0UHJvZ3Jlc3MgYW5kIHdpdGhDcmVkZW50aWFscy5cbiAgICAgIHRoaXMucmVwb3J0UHJvZ3Jlc3MgPSAhIW9wdGlvbnMucmVwb3J0UHJvZ3Jlc3M7XG4gICAgICB0aGlzLndpdGhDcmVkZW50aWFscyA9ICEhb3B0aW9ucy53aXRoQ3JlZGVudGlhbHM7XG4gICAgICAvLyBPdmVycmlkZSBkZWZhdWx0IHJlc3BvbnNlIHR5cGUgb2YgJ2pzb24nIGlmIG9uZSBpcyBwcm92aWRlZC5cbiAgICAgIGlmICghIW9wdGlvbnMucmVzcG9uc2VUeXBlKSB7XG4gICAgICAgIHRoaXMucmVzcG9uc2VUeXBlID0gb3B0aW9ucy5yZXNwb25zZVR5cGU7XG4gICAgICB9XG4gICAgICAvLyBPdmVycmlkZSBoZWFkZXJzIGlmIHRoZXkncmUgcHJvdmlkZWQuXG4gICAgICBpZiAoISFvcHRpb25zLmhlYWRlcnMpIHtcbiAgICAgICAgdGhpcy5oZWFkZXJzID0gb3B0aW9ucy5oZWFkZXJzO1xuICAgICAgfVxuICAgICAgaWYgKCEhb3B0aW9ucy5jb250ZXh0KSB7XG4gICAgICAgIHRoaXMuY29udGV4dCA9IG9wdGlvbnMuY29udGV4dDtcbiAgICAgIH1cbiAgICAgIGlmICghIW9wdGlvbnMucGFyYW1zKSB7XG4gICAgICAgIHRoaXMucGFyYW1zID0gb3B0aW9ucy5wYXJhbXM7XG4gICAgICB9XG4gICAgICAvLyBXZSBkbyB3YW50IHRvIGFzc2lnbiB0cmFuc2ZlckNhY2hlIGV2ZW4gaWYgaXQncyBmYWxzeSAoZmFsc2UgaXMgdmFsaWQgdmFsdWUpXG4gICAgICB0aGlzLnRyYW5zZmVyQ2FjaGUgPSBvcHRpb25zLnRyYW5zZmVyQ2FjaGU7XG4gICAgfVxuICAgIC8vIElmIG5vIGhlYWRlcnMgaGF2ZSBiZWVuIHBhc3NlZCBpbiwgY29uc3RydWN0IGEgbmV3IEh0dHBIZWFkZXJzIGluc3RhbmNlLlxuICAgIHRoaXMuaGVhZGVycyA/Pz0gbmV3IEh0dHBIZWFkZXJzKCk7XG4gICAgLy8gSWYgbm8gY29udGV4dCBoYXZlIGJlZW4gcGFzc2VkIGluLCBjb25zdHJ1Y3QgYSBuZXcgSHR0cENvbnRleHQgaW5zdGFuY2UuXG4gICAgdGhpcy5jb250ZXh0ID8/PSBuZXcgSHR0cENvbnRleHQoKTtcbiAgICAvLyBJZiBubyBwYXJhbWV0ZXJzIGhhdmUgYmVlbiBwYXNzZWQgaW4sIGNvbnN0cnVjdCBhIG5ldyBIdHRwVXJsRW5jb2RlZFBhcmFtcyBpbnN0YW5jZS5cbiAgICBpZiAoIXRoaXMucGFyYW1zKSB7XG4gICAgICB0aGlzLnBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKCk7XG4gICAgICB0aGlzLnVybFdpdGhQYXJhbXMgPSB1cmw7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEVuY29kZSB0aGUgcGFyYW1ldGVycyB0byBhIHN0cmluZyBpbiBwcmVwYXJhdGlvbiBmb3IgaW5jbHVzaW9uIGluIHRoZSBVUkwuXG4gICAgICBjb25zdCBwYXJhbXMgPSB0aGlzLnBhcmFtcy50b1N0cmluZygpO1xuICAgICAgaWYgKHBhcmFtcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgLy8gTm8gcGFyYW1ldGVycywgdGhlIHZpc2libGUgVVJMIGlzIGp1c3QgdGhlIFVSTCBnaXZlbiBhdCBjcmVhdGlvbiB0aW1lLlxuICAgICAgICB0aGlzLnVybFdpdGhQYXJhbXMgPSB1cmw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBEb2VzIHRoZSBVUkwgYWxyZWFkeSBoYXZlIHF1ZXJ5IHBhcmFtZXRlcnM/IExvb2sgZm9yICc/Jy5cbiAgICAgICAgY29uc3QgcUlkeCA9IHVybC5pbmRleE9mKCc/Jyk7XG4gICAgICAgIC8vIFRoZXJlIGFyZSAzIGNhc2VzIHRvIGhhbmRsZTpcbiAgICAgICAgLy8gMSkgTm8gZXhpc3RpbmcgcGFyYW1ldGVycyAtPiBhcHBlbmQgJz8nIGZvbGxvd2VkIGJ5IHBhcmFtcy5cbiAgICAgICAgLy8gMikgJz8nIGV4aXN0cyBhbmQgaXMgZm9sbG93ZWQgYnkgZXhpc3RpbmcgcXVlcnkgc3RyaW5nIC0+XG4gICAgICAgIC8vICAgIGFwcGVuZCAnJicgZm9sbG93ZWQgYnkgcGFyYW1zLlxuICAgICAgICAvLyAzKSAnPycgZXhpc3RzIGF0IHRoZSBlbmQgb2YgdGhlIHVybCAtPiBhcHBlbmQgcGFyYW1zIGRpcmVjdGx5LlxuICAgICAgICAvLyBUaGlzIGJhc2ljYWxseSBhbW91bnRzIHRvIGRldGVybWluaW5nIHRoZSBjaGFyYWN0ZXIsIGlmIGFueSwgd2l0aFxuICAgICAgICAvLyB3aGljaCB0byBqb2luIHRoZSBVUkwgYW5kIHBhcmFtZXRlcnMuXG4gICAgICAgIGNvbnN0IHNlcCA9IHFJZHggPT09IC0xID8gJz8nIDogcUlkeCA8IHVybC5sZW5ndGggLSAxID8gJyYnIDogJyc7XG4gICAgICAgIHRoaXMudXJsV2l0aFBhcmFtcyA9IHVybCArIHNlcCArIHBhcmFtcztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgLyoqXG4gICAqIFRyYW5zZm9ybSB0aGUgZnJlZS1mb3JtIGJvZHkgaW50byBhIHNlcmlhbGl6ZWQgZm9ybWF0IHN1aXRhYmxlIGZvclxuICAgKiB0cmFuc21pc3Npb24gdG8gdGhlIHNlcnZlci5cbiAgICovXG4gIHNlcmlhbGl6ZUJvZHkoKSB7XG4gICAgLy8gSWYgbm8gYm9keSBpcyBwcmVzZW50LCBubyBuZWVkIHRvIHNlcmlhbGl6ZSBpdC5cbiAgICBpZiAodGhpcy5ib2R5ID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gQ2hlY2sgd2hldGhlciB0aGUgYm9keSBpcyBhbHJlYWR5IGluIGEgc2VyaWFsaXplZCBmb3JtLiBJZiBzbyxcbiAgICAvLyBpdCBjYW4ganVzdCBiZSByZXR1cm5lZCBkaXJlY3RseS5cbiAgICBpZiAodHlwZW9mIHRoaXMuYm9keSA9PT0gJ3N0cmluZycgfHwgaXNBcnJheUJ1ZmZlcih0aGlzLmJvZHkpIHx8IGlzQmxvYih0aGlzLmJvZHkpIHx8IGlzRm9ybURhdGEodGhpcy5ib2R5KSB8fCBpc1VybFNlYXJjaFBhcmFtcyh0aGlzLmJvZHkpKSB7XG4gICAgICByZXR1cm4gdGhpcy5ib2R5O1xuICAgIH1cbiAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBib2R5IGlzIGFuIGluc3RhbmNlIG9mIEh0dHBVcmxFbmNvZGVkUGFyYW1zLlxuICAgIGlmICh0aGlzLmJvZHkgaW5zdGFuY2VvZiBIdHRwUGFyYW1zKSB7XG4gICAgICByZXR1cm4gdGhpcy5ib2R5LnRvU3RyaW5nKCk7XG4gICAgfVxuICAgIC8vIENoZWNrIHdoZXRoZXIgdGhlIGJvZHkgaXMgYW4gb2JqZWN0IG9yIGFycmF5LCBhbmQgc2VyaWFsaXplIHdpdGggSlNPTiBpZiBzby5cbiAgICBpZiAodHlwZW9mIHRoaXMuYm9keSA9PT0gJ29iamVjdCcgfHwgdHlwZW9mIHRoaXMuYm9keSA9PT0gJ2Jvb2xlYW4nIHx8IEFycmF5LmlzQXJyYXkodGhpcy5ib2R5KSkge1xuICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMuYm9keSk7XG4gICAgfVxuICAgIC8vIEZhbGwgYmFjayBvbiB0b1N0cmluZygpIGZvciBldmVyeXRoaW5nIGVsc2UuXG4gICAgcmV0dXJuIHRoaXMuYm9keS50b1N0cmluZygpO1xuICB9XG4gIC8qKlxuICAgKiBFeGFtaW5lIHRoZSBib2R5IGFuZCBhdHRlbXB0IHRvIGluZmVyIGFuIGFwcHJvcHJpYXRlIE1JTUUgdHlwZVxuICAgKiBmb3IgaXQuXG4gICAqXG4gICAqIElmIG5vIHN1Y2ggdHlwZSBjYW4gYmUgaW5mZXJyZWQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGBudWxsYC5cbiAgICovXG4gIGRldGVjdENvbnRlbnRUeXBlSGVhZGVyKCkge1xuICAgIC8vIEFuIGVtcHR5IGJvZHkgaGFzIG5vIGNvbnRlbnQgdHlwZS5cbiAgICBpZiAodGhpcy5ib2R5ID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gRm9ybURhdGEgYm9kaWVzIHJlbHkgb24gdGhlIGJyb3dzZXIncyBjb250ZW50IHR5cGUgYXNzaWdubWVudC5cbiAgICBpZiAoaXNGb3JtRGF0YSh0aGlzLmJvZHkpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gQmxvYnMgdXN1YWxseSBoYXZlIHRoZWlyIG93biBjb250ZW50IHR5cGUuIElmIGl0IGRvZXNuJ3QsIHRoZW5cbiAgICAvLyBubyB0eXBlIGNhbiBiZSBpbmZlcnJlZC5cbiAgICBpZiAoaXNCbG9iKHRoaXMuYm9keSkpIHtcbiAgICAgIHJldHVybiB0aGlzLmJvZHkudHlwZSB8fCBudWxsO1xuICAgIH1cbiAgICAvLyBBcnJheSBidWZmZXJzIGhhdmUgdW5rbm93biBjb250ZW50cyBhbmQgdGh1cyBubyB0eXBlIGNhbiBiZSBpbmZlcnJlZC5cbiAgICBpZiAoaXNBcnJheUJ1ZmZlcih0aGlzLmJvZHkpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgLy8gVGVjaG5pY2FsbHksIHN0cmluZ3MgY291bGQgYmUgYSBmb3JtIG9mIEpTT04gZGF0YSwgYnV0IGl0J3Mgc2FmZSBlbm91Z2hcbiAgICAvLyB0byBhc3N1bWUgdGhleSdyZSBwbGFpbiBzdHJpbmdzLlxuICAgIGlmICh0eXBlb2YgdGhpcy5ib2R5ID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuICd0ZXh0L3BsYWluJztcbiAgICB9XG4gICAgLy8gYEh0dHBVcmxFbmNvZGVkUGFyYW1zYCBoYXMgaXRzIG93biBjb250ZW50LXR5cGUuXG4gICAgaWYgKHRoaXMuYm9keSBpbnN0YW5jZW9mIEh0dHBQYXJhbXMpIHtcbiAgICAgIHJldHVybiAnYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkO2NoYXJzZXQ9VVRGLTgnO1xuICAgIH1cbiAgICAvLyBBcnJheXMsIG9iamVjdHMsIGJvb2xlYW4gYW5kIG51bWJlcnMgd2lsbCBiZSBlbmNvZGVkIGFzIEpTT04uXG4gICAgaWYgKHR5cGVvZiB0aGlzLmJvZHkgPT09ICdvYmplY3QnIHx8IHR5cGVvZiB0aGlzLmJvZHkgPT09ICdudW1iZXInIHx8IHR5cGVvZiB0aGlzLmJvZHkgPT09ICdib29sZWFuJykge1xuICAgICAgcmV0dXJuICdhcHBsaWNhdGlvbi9qc29uJztcbiAgICB9XG4gICAgLy8gTm8gdHlwZSBjb3VsZCBiZSBpbmZlcnJlZC5cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjbG9uZSh1cGRhdGUgPSB7fSkge1xuICAgIC8vIEZvciBtZXRob2QsIHVybCwgYW5kIHJlc3BvbnNlVHlwZSwgdGFrZSB0aGUgY3VycmVudCB2YWx1ZSB1bmxlc3NcbiAgICAvLyBpdCBpcyBvdmVycmlkZGVuIGluIHRoZSB1cGRhdGUgaGFzaC5cbiAgICBjb25zdCBtZXRob2QgPSB1cGRhdGUubWV0aG9kIHx8IHRoaXMubWV0aG9kO1xuICAgIGNvbnN0IHVybCA9IHVwZGF0ZS51cmwgfHwgdGhpcy51cmw7XG4gICAgY29uc3QgcmVzcG9uc2VUeXBlID0gdXBkYXRlLnJlc3BvbnNlVHlwZSB8fCB0aGlzLnJlc3BvbnNlVHlwZTtcbiAgICAvLyBDYXJlZnVsbHkgaGFuZGxlIHRoZSB0cmFuc2ZlckNhY2hlIHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlblxuICAgIC8vIGBmYWxzZWAgYW5kIGB1bmRlZmluZWRgIGluIHRoZSB1cGRhdGUgYXJncy5cbiAgICBjb25zdCB0cmFuc2ZlckNhY2hlID0gdXBkYXRlLnRyYW5zZmVyQ2FjaGUgPz8gdGhpcy50cmFuc2ZlckNhY2hlO1xuICAgIC8vIFRoZSBib2R5IGlzIHNvbWV3aGF0IHNwZWNpYWwgLSBhIGBudWxsYCB2YWx1ZSBpbiB1cGRhdGUuYm9keSBtZWFuc1xuICAgIC8vIHdoYXRldmVyIGN1cnJlbnQgYm9keSBpcyBwcmVzZW50IGlzIGJlaW5nIG92ZXJyaWRkZW4gd2l0aCBhbiBlbXB0eVxuICAgIC8vIGJvZHksIHdoZXJlYXMgYW4gYHVuZGVmaW5lZGAgdmFsdWUgaW4gdXBkYXRlLmJvZHkgaW1wbGllcyBub1xuICAgIC8vIG92ZXJyaWRlLlxuICAgIGNvbnN0IGJvZHkgPSB1cGRhdGUuYm9keSAhPT0gdW5kZWZpbmVkID8gdXBkYXRlLmJvZHkgOiB0aGlzLmJvZHk7XG4gICAgLy8gQ2FyZWZ1bGx5IGhhbmRsZSB0aGUgYm9vbGVhbiBvcHRpb25zIHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlblxuICAgIC8vIGBmYWxzZWAgYW5kIGB1bmRlZmluZWRgIGluIHRoZSB1cGRhdGUgYXJncy5cbiAgICBjb25zdCB3aXRoQ3JlZGVudGlhbHMgPSB1cGRhdGUud2l0aENyZWRlbnRpYWxzID8/IHRoaXMud2l0aENyZWRlbnRpYWxzO1xuICAgIGNvbnN0IHJlcG9ydFByb2dyZXNzID0gdXBkYXRlLnJlcG9ydFByb2dyZXNzID8/IHRoaXMucmVwb3J0UHJvZ3Jlc3M7XG4gICAgLy8gSGVhZGVycyBhbmQgcGFyYW1zIG1heSBiZSBhcHBlbmRlZCB0byBpZiBgc2V0SGVhZGVyc2Agb3JcbiAgICAvLyBgc2V0UGFyYW1zYCBhcmUgdXNlZC5cbiAgICBsZXQgaGVhZGVycyA9IHVwZGF0ZS5oZWFkZXJzIHx8IHRoaXMuaGVhZGVycztcbiAgICBsZXQgcGFyYW1zID0gdXBkYXRlLnBhcmFtcyB8fCB0aGlzLnBhcmFtcztcbiAgICAvLyBQYXNzIG9uIGNvbnRleHQgaWYgbmVlZGVkXG4gICAgY29uc3QgY29udGV4dCA9IHVwZGF0ZS5jb250ZXh0ID8/IHRoaXMuY29udGV4dDtcbiAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBjYWxsZXIgaGFzIGFza2VkIHRvIGFkZCBoZWFkZXJzLlxuICAgIGlmICh1cGRhdGUuc2V0SGVhZGVycyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBTZXQgZXZlcnkgcmVxdWVzdGVkIGhlYWRlci5cbiAgICAgIGhlYWRlcnMgPSBPYmplY3Qua2V5cyh1cGRhdGUuc2V0SGVhZGVycykucmVkdWNlKChoZWFkZXJzLCBuYW1lKSA9PiBoZWFkZXJzLnNldChuYW1lLCB1cGRhdGUuc2V0SGVhZGVyc1tuYW1lXSksIGhlYWRlcnMpO1xuICAgIH1cbiAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBjYWxsZXIgaGFzIGFza2VkIHRvIHNldCBwYXJhbXMuXG4gICAgaWYgKHVwZGF0ZS5zZXRQYXJhbXMpIHtcbiAgICAgIC8vIFNldCBldmVyeSByZXF1ZXN0ZWQgcGFyYW0uXG4gICAgICBwYXJhbXMgPSBPYmplY3Qua2V5cyh1cGRhdGUuc2V0UGFyYW1zKS5yZWR1Y2UoKHBhcmFtcywgcGFyYW0pID0+IHBhcmFtcy5zZXQocGFyYW0sIHVwZGF0ZS5zZXRQYXJhbXNbcGFyYW1dKSwgcGFyYW1zKTtcbiAgICB9XG4gICAgLy8gRmluYWxseSwgY29uc3RydWN0IHRoZSBuZXcgSHR0cFJlcXVlc3QgdXNpbmcgdGhlIHBpZWNlcyBmcm9tIGFib3ZlLlxuICAgIHJldHVybiBuZXcgSHR0cFJlcXVlc3QobWV0aG9kLCB1cmwsIGJvZHksIHtcbiAgICAgIHBhcmFtcyxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBjb250ZXh0LFxuICAgICAgcmVwb3J0UHJvZ3Jlc3MsXG4gICAgICByZXNwb25zZVR5cGUsXG4gICAgICB3aXRoQ3JlZGVudGlhbHMsXG4gICAgICB0cmFuc2ZlckNhY2hlXG4gICAgfSk7XG4gIH1cbn1cblxuLyoqXG4gKiBUeXBlIGVudW1lcmF0aW9uIGZvciB0aGUgZGlmZmVyZW50IGtpbmRzIG9mIGBIdHRwRXZlbnRgLlxuICpcbiAqIEBwdWJsaWNBcGlcbiAqL1xudmFyIEh0dHBFdmVudFR5cGU7XG4oZnVuY3Rpb24gKEh0dHBFdmVudFR5cGUpIHtcbiAgLyoqXG4gICAqIFRoZSByZXF1ZXN0IHdhcyBzZW50IG91dCBvdmVyIHRoZSB3aXJlLlxuICAgKi9cbiAgSHR0cEV2ZW50VHlwZVtIdHRwRXZlbnRUeXBlW1wiU2VudFwiXSA9IDBdID0gXCJTZW50XCI7XG4gIC8qKlxuICAgKiBBbiB1cGxvYWQgcHJvZ3Jlc3MgZXZlbnQgd2FzIHJlY2VpdmVkLlxuICAgKlxuICAgKiBOb3RlOiBUaGUgYEZldGNoQmFja2VuZGAgZG9lc24ndCBzdXBwb3J0IHByb2dyZXNzIHJlcG9ydCBvbiB1cGxvYWRzLlxuICAgKi9cbiAgSHR0cEV2ZW50VHlwZVtIdHRwRXZlbnRUeXBlW1wiVXBsb2FkUHJvZ3Jlc3NcIl0gPSAxXSA9IFwiVXBsb2FkUHJvZ3Jlc3NcIjtcbiAgLyoqXG4gICAqIFRoZSByZXNwb25zZSBzdGF0dXMgY29kZSBhbmQgaGVhZGVycyB3ZXJlIHJlY2VpdmVkLlxuICAgKi9cbiAgSHR0cEV2ZW50VHlwZVtIdHRwRXZlbnRUeXBlW1wiUmVzcG9uc2VIZWFkZXJcIl0gPSAyXSA9IFwiUmVzcG9uc2VIZWFkZXJcIjtcbiAgLyoqXG4gICAqIEEgZG93bmxvYWQgcHJvZ3Jlc3MgZXZlbnQgd2FzIHJlY2VpdmVkLlxuICAgKi9cbiAgSHR0cEV2ZW50VHlwZVtIdHRwRXZlbnRUeXBlW1wiRG93bmxvYWRQcm9ncmVzc1wiXSA9IDNdID0gXCJEb3dubG9hZFByb2dyZXNzXCI7XG4gIC8qKlxuICAgKiBUaGUgZnVsbCByZXNwb25zZSBpbmNsdWRpbmcgdGhlIGJvZHkgd2FzIHJlY2VpdmVkLlxuICAgKi9cbiAgSHR0cEV2ZW50VHlwZVtIdHRwRXZlbnRUeXBlW1wiUmVzcG9uc2VcIl0gPSA0XSA9IFwiUmVzcG9uc2VcIjtcbiAgLyoqXG4gICAqIEEgY3VzdG9tIGV2ZW50IGZyb20gYW4gaW50ZXJjZXB0b3Igb3IgYSBiYWNrZW5kLlxuICAgKi9cbiAgSHR0cEV2ZW50VHlwZVtIdHRwRXZlbnRUeXBlW1wiVXNlclwiXSA9IDVdID0gXCJVc2VyXCI7XG59KShIdHRwRXZlbnRUeXBlIHx8IChIdHRwRXZlbnRUeXBlID0ge30pKTtcbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgYm90aCBgSHR0cFJlc3BvbnNlYCBhbmQgYEh0dHBIZWFkZXJSZXNwb25zZWAuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBIdHRwUmVzcG9uc2VCYXNlIHtcbiAgLyoqXG4gICAqIFN1cGVyLWNvbnN0cnVjdG9yIGZvciBhbGwgcmVzcG9uc2VzLlxuICAgKlxuICAgKiBUaGUgc2luZ2xlIHBhcmFtZXRlciBhY2NlcHRlZCBpcyBhbiBpbml0aWFsaXphdGlvbiBoYXNoLiBBbnkgcHJvcGVydGllc1xuICAgKiBvZiB0aGUgcmVzcG9uc2UgcGFzc2VkIHRoZXJlIHdpbGwgb3ZlcnJpZGUgdGhlIGRlZmF1bHQgdmFsdWVzLlxuICAgKi9cbiAgY29uc3RydWN0b3IoaW5pdCwgZGVmYXVsdFN0YXR1cyA9IDIwMCwgZGVmYXVsdFN0YXR1c1RleHQgPSAnT0snKSB7XG4gICAgLy8gSWYgdGhlIGhhc2ggaGFzIHZhbHVlcyBwYXNzZWQsIHVzZSB0aGVtIHRvIGluaXRpYWxpemUgdGhlIHJlc3BvbnNlLlxuICAgIC8vIE90aGVyd2lzZSB1c2UgdGhlIGRlZmF1bHQgdmFsdWVzLlxuICAgIHRoaXMuaGVhZGVycyA9IGluaXQuaGVhZGVycyB8fCBuZXcgSHR0cEhlYWRlcnMoKTtcbiAgICB0aGlzLnN0YXR1cyA9IGluaXQuc3RhdHVzICE9PSB1bmRlZmluZWQgPyBpbml0LnN0YXR1cyA6IGRlZmF1bHRTdGF0dXM7XG4gICAgdGhpcy5zdGF0dXNUZXh0ID0gaW5pdC5zdGF0dXNUZXh0IHx8IGRlZmF1bHRTdGF0dXNUZXh0O1xuICAgIHRoaXMudXJsID0gaW5pdC51cmwgfHwgbnVsbDtcbiAgICAvLyBDYWNoZSB0aGUgb2sgdmFsdWUgdG8gYXZvaWQgZGVmaW5pbmcgYSBnZXR0ZXIuXG4gICAgdGhpcy5vayA9IHRoaXMuc3RhdHVzID49IDIwMCAmJiB0aGlzLnN0YXR1cyA8IDMwMDtcbiAgfVxufVxuLyoqXG4gKiBBIHBhcnRpYWwgSFRUUCByZXNwb25zZSB3aGljaCBvbmx5IGluY2x1ZGVzIHRoZSBzdGF0dXMgYW5kIGhlYWRlciBkYXRhLFxuICogYnV0IG5vIHJlc3BvbnNlIGJvZHkuXG4gKlxuICogYEh0dHBIZWFkZXJSZXNwb25zZWAgaXMgYSBgSHR0cEV2ZW50YCBhdmFpbGFibGUgb24gdGhlIHJlc3BvbnNlXG4gKiBldmVudCBzdHJlYW0sIG9ubHkgd2hlbiBwcm9ncmVzcyBldmVudHMgYXJlIHJlcXVlc3RlZC5cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIEh0dHBIZWFkZXJSZXNwb25zZSBleHRlbmRzIEh0dHBSZXNwb25zZUJhc2Uge1xuICAvKipcbiAgICogQ3JlYXRlIGEgbmV3IGBIdHRwSGVhZGVyUmVzcG9uc2VgIHdpdGggdGhlIGdpdmVuIHBhcmFtZXRlcnMuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcihpbml0ID0ge30pIHtcbiAgICBzdXBlcihpbml0KTtcbiAgICB0aGlzLnR5cGUgPSBIdHRwRXZlbnRUeXBlLlJlc3BvbnNlSGVhZGVyO1xuICB9XG4gIC8qKlxuICAgKiBDb3B5IHRoaXMgYEh0dHBIZWFkZXJSZXNwb25zZWAsIG92ZXJyaWRpbmcgaXRzIGNvbnRlbnRzIHdpdGggdGhlXG4gICAqIGdpdmVuIHBhcmFtZXRlciBoYXNoLlxuICAgKi9cbiAgY2xvbmUodXBkYXRlID0ge30pIHtcbiAgICAvLyBQZXJmb3JtIGEgc3RyYWlnaHRmb3J3YXJkIGluaXRpYWxpemF0aW9uIG9mIHRoZSBuZXcgSHR0cEhlYWRlclJlc3BvbnNlLFxuICAgIC8vIG92ZXJyaWRpbmcgdGhlIGN1cnJlbnQgcGFyYW1ldGVycyB3aXRoIG5ldyBvbmVzIGlmIGdpdmVuLlxuICAgIHJldHVybiBuZXcgSHR0cEhlYWRlclJlc3BvbnNlKHtcbiAgICAgIGhlYWRlcnM6IHVwZGF0ZS5oZWFkZXJzIHx8IHRoaXMuaGVhZGVycyxcbiAgICAgIHN0YXR1czogdXBkYXRlLnN0YXR1cyAhPT0gdW5kZWZpbmVkID8gdXBkYXRlLnN0YXR1cyA6IHRoaXMuc3RhdHVzLFxuICAgICAgc3RhdHVzVGV4dDogdXBkYXRlLnN0YXR1c1RleHQgfHwgdGhpcy5zdGF0dXNUZXh0LFxuICAgICAgdXJsOiB1cGRhdGUudXJsIHx8IHRoaXMudXJsIHx8IHVuZGVmaW5lZFxuICAgIH0pO1xuICB9XG59XG4vKipcbiAqIEEgZnVsbCBIVFRQIHJlc3BvbnNlLCBpbmNsdWRpbmcgYSB0eXBlZCByZXNwb25zZSBib2R5ICh3aGljaCBtYXkgYmUgYG51bGxgXG4gKiBpZiBvbmUgd2FzIG5vdCByZXR1cm5lZCkuXG4gKlxuICogYEh0dHBSZXNwb25zZWAgaXMgYSBgSHR0cEV2ZW50YCBhdmFpbGFibGUgb24gdGhlIHJlc3BvbnNlIGV2ZW50XG4gKiBzdHJlYW0uXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBIdHRwUmVzcG9uc2UgZXh0ZW5kcyBIdHRwUmVzcG9uc2VCYXNlIHtcbiAgLyoqXG4gICAqIENvbnN0cnVjdCBhIG5ldyBgSHR0cFJlc3BvbnNlYC5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGluaXQgPSB7fSkge1xuICAgIHN1cGVyKGluaXQpO1xuICAgIHRoaXMudHlwZSA9IEh0dHBFdmVudFR5cGUuUmVzcG9uc2U7XG4gICAgdGhpcy5ib2R5ID0gaW5pdC5ib2R5ICE9PSB1bmRlZmluZWQgPyBpbml0LmJvZHkgOiBudWxsO1xuICB9XG4gIGNsb25lKHVwZGF0ZSA9IHt9KSB7XG4gICAgcmV0dXJuIG5ldyBIdHRwUmVzcG9uc2Uoe1xuICAgICAgYm9keTogdXBkYXRlLmJvZHkgIT09IHVuZGVmaW5lZCA/IHVwZGF0ZS5ib2R5IDogdGhpcy5ib2R5LFxuICAgICAgaGVhZGVyczogdXBkYXRlLmhlYWRlcnMgfHwgdGhpcy5oZWFkZXJzLFxuICAgICAgc3RhdHVzOiB1cGRhdGUuc3RhdHVzICE9PSB1bmRlZmluZWQgPyB1cGRhdGUuc3RhdHVzIDogdGhpcy5zdGF0dXMsXG4gICAgICBzdGF0dXNUZXh0OiB1cGRhdGUuc3RhdHVzVGV4dCB8fCB0aGlzLnN0YXR1c1RleHQsXG4gICAgICB1cmw6IHVwZGF0ZS51cmwgfHwgdGhpcy51cmwgfHwgdW5kZWZpbmVkXG4gICAgfSk7XG4gIH1cbn1cbi8qKlxuICogQSByZXNwb25zZSB0aGF0IHJlcHJlc2VudHMgYW4gZXJyb3Igb3IgZmFpbHVyZSwgZWl0aGVyIGZyb20gYVxuICogbm9uLXN1Y2Nlc3NmdWwgSFRUUCBzdGF0dXMsIGFuIGVycm9yIHdoaWxlIGV4ZWN1dGluZyB0aGUgcmVxdWVzdCxcbiAqIG9yIHNvbWUgb3RoZXIgZmFpbHVyZSB3aGljaCBvY2N1cnJlZCBkdXJpbmcgdGhlIHBhcnNpbmcgb2YgdGhlIHJlc3BvbnNlLlxuICpcbiAqIEFueSBlcnJvciByZXR1cm5lZCBvbiB0aGUgYE9ic2VydmFibGVgIHJlc3BvbnNlIHN0cmVhbSB3aWxsIGJlXG4gKiB3cmFwcGVkIGluIGFuIGBIdHRwRXJyb3JSZXNwb25zZWAgdG8gcHJvdmlkZSBhZGRpdGlvbmFsIGNvbnRleHQgYWJvdXRcbiAqIHRoZSBzdGF0ZSBvZiB0aGUgSFRUUCBsYXllciB3aGVuIHRoZSBlcnJvciBvY2N1cnJlZC4gVGhlIGVycm9yIHByb3BlcnR5XG4gKiB3aWxsIGNvbnRhaW4gZWl0aGVyIGEgd3JhcHBlZCBFcnJvciBvYmplY3Qgb3IgdGhlIGVycm9yIHJlc3BvbnNlIHJldHVybmVkXG4gKiBmcm9tIHRoZSBzZXJ2ZXIuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5jbGFzcyBIdHRwRXJyb3JSZXNwb25zZSBleHRlbmRzIEh0dHBSZXNwb25zZUJhc2Uge1xuICBjb25zdHJ1Y3Rvcihpbml0KSB7XG4gICAgLy8gSW5pdGlhbGl6ZSB3aXRoIGEgZGVmYXVsdCBzdGF0dXMgb2YgMCAvIFVua25vd24gRXJyb3IuXG4gICAgc3VwZXIoaW5pdCwgMCwgJ1Vua25vd24gRXJyb3InKTtcbiAgICB0aGlzLm5hbWUgPSAnSHR0cEVycm9yUmVzcG9uc2UnO1xuICAgIC8qKlxuICAgICAqIEVycm9ycyBhcmUgbmV2ZXIgb2theSwgZXZlbiB3aGVuIHRoZSBzdGF0dXMgY29kZSBpcyBpbiB0aGUgMnh4IHN1Y2Nlc3MgcmFuZ2UuXG4gICAgICovXG4gICAgdGhpcy5vayA9IGZhbHNlO1xuICAgIC8vIElmIHRoZSByZXNwb25zZSB3YXMgc3VjY2Vzc2Z1bCwgdGhlbiB0aGlzIHdhcyBhIHBhcnNlIGVycm9yLiBPdGhlcndpc2UsIGl0IHdhc1xuICAgIC8vIGEgcHJvdG9jb2wtbGV2ZWwgZmFpbHVyZSBvZiBzb21lIHNvcnQuIEVpdGhlciB0aGUgcmVxdWVzdCBmYWlsZWQgaW4gdHJhbnNpdFxuICAgIC8vIG9yIHRoZSBzZXJ2ZXIgcmV0dXJuZWQgYW4gdW5zdWNjZXNzZnVsIHN0YXR1cyBjb2RlLlxuICAgIGlmICh0aGlzLnN0YXR1cyA+PSAyMDAgJiYgdGhpcy5zdGF0dXMgPCAzMDApIHtcbiAgICAgIHRoaXMubWVzc2FnZSA9IGBIdHRwIGZhaWx1cmUgZHVyaW5nIHBhcnNpbmcgZm9yICR7aW5pdC51cmwgfHwgJyh1bmtub3duIHVybCknfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubWVzc2FnZSA9IGBIdHRwIGZhaWx1cmUgcmVzcG9uc2UgZm9yICR7aW5pdC51cmwgfHwgJyh1bmtub3duIHVybCknfTogJHtpbml0LnN0YXR1c30gJHtpbml0LnN0YXR1c1RleHR9YDtcbiAgICB9XG4gICAgdGhpcy5lcnJvciA9IGluaXQuZXJyb3IgfHwgbnVsbDtcbiAgfVxufVxuLyoqXG4gKiBXZSB1c2UgdGhlc2UgY29uc3RhbnQgdG8gcHJldmVudCBwdWxsaW5nIHRoZSB3aG9sZSBIdHRwU3RhdHVzQ29kZSBlbnVtXG4gKiBUaG9zZSBhcmUgdGhlIG9ubHkgb25lcyByZWZlcmVuY2VkIGRpcmVjdGx5IGJ5IHRoZSBmcmFtZXdvcmtcbiAqL1xuY29uc3QgSFRUUF9TVEFUVVNfQ09ERV9PSyA9IDIwMDtcbmNvbnN0IEhUVFBfU1RBVFVTX0NPREVfTk9fQ09OVEVOVCA9IDIwNDtcbi8qKlxuICogSHR0cCBzdGF0dXMgY29kZXMuXG4gKiBBcyBwZXIgaHR0cHM6Ly93d3cuaWFuYS5vcmcvYXNzaWdubWVudHMvaHR0cC1zdGF0dXMtY29kZXMvaHR0cC1zdGF0dXMtY29kZXMueGh0bWxcbiAqIEBwdWJsaWNBcGlcbiAqL1xudmFyIEh0dHBTdGF0dXNDb2RlO1xuKGZ1bmN0aW9uIChIdHRwU3RhdHVzQ29kZSkge1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIkNvbnRpbnVlXCJdID0gMTAwXSA9IFwiQ29udGludWVcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJTd2l0Y2hpbmdQcm90b2NvbHNcIl0gPSAxMDFdID0gXCJTd2l0Y2hpbmdQcm90b2NvbHNcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJQcm9jZXNzaW5nXCJdID0gMTAyXSA9IFwiUHJvY2Vzc2luZ1wiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIkVhcmx5SGludHNcIl0gPSAxMDNdID0gXCJFYXJseUhpbnRzXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiT2tcIl0gPSAyMDBdID0gXCJPa1wiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIkNyZWF0ZWRcIl0gPSAyMDFdID0gXCJDcmVhdGVkXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiQWNjZXB0ZWRcIl0gPSAyMDJdID0gXCJBY2NlcHRlZFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIk5vbkF1dGhvcml0YXRpdmVJbmZvcm1hdGlvblwiXSA9IDIwM10gPSBcIk5vbkF1dGhvcml0YXRpdmVJbmZvcm1hdGlvblwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIk5vQ29udGVudFwiXSA9IDIwNF0gPSBcIk5vQ29udGVudFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIlJlc2V0Q29udGVudFwiXSA9IDIwNV0gPSBcIlJlc2V0Q29udGVudFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIlBhcnRpYWxDb250ZW50XCJdID0gMjA2XSA9IFwiUGFydGlhbENvbnRlbnRcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJNdWx0aVN0YXR1c1wiXSA9IDIwN10gPSBcIk11bHRpU3RhdHVzXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiQWxyZWFkeVJlcG9ydGVkXCJdID0gMjA4XSA9IFwiQWxyZWFkeVJlcG9ydGVkXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiSW1Vc2VkXCJdID0gMjI2XSA9IFwiSW1Vc2VkXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiTXVsdGlwbGVDaG9pY2VzXCJdID0gMzAwXSA9IFwiTXVsdGlwbGVDaG9pY2VzXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiTW92ZWRQZXJtYW5lbnRseVwiXSA9IDMwMV0gPSBcIk1vdmVkUGVybWFuZW50bHlcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJGb3VuZFwiXSA9IDMwMl0gPSBcIkZvdW5kXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiU2VlT3RoZXJcIl0gPSAzMDNdID0gXCJTZWVPdGhlclwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIk5vdE1vZGlmaWVkXCJdID0gMzA0XSA9IFwiTm90TW9kaWZpZWRcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJVc2VQcm94eVwiXSA9IDMwNV0gPSBcIlVzZVByb3h5XCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiVW51c2VkXCJdID0gMzA2XSA9IFwiVW51c2VkXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiVGVtcG9yYXJ5UmVkaXJlY3RcIl0gPSAzMDddID0gXCJUZW1wb3JhcnlSZWRpcmVjdFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIlBlcm1hbmVudFJlZGlyZWN0XCJdID0gMzA4XSA9IFwiUGVybWFuZW50UmVkaXJlY3RcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJCYWRSZXF1ZXN0XCJdID0gNDAwXSA9IFwiQmFkUmVxdWVzdFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIlVuYXV0aG9yaXplZFwiXSA9IDQwMV0gPSBcIlVuYXV0aG9yaXplZFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIlBheW1lbnRSZXF1aXJlZFwiXSA9IDQwMl0gPSBcIlBheW1lbnRSZXF1aXJlZFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIkZvcmJpZGRlblwiXSA9IDQwM10gPSBcIkZvcmJpZGRlblwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIk5vdEZvdW5kXCJdID0gNDA0XSA9IFwiTm90Rm91bmRcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJNZXRob2ROb3RBbGxvd2VkXCJdID0gNDA1XSA9IFwiTWV0aG9kTm90QWxsb3dlZFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIk5vdEFjY2VwdGFibGVcIl0gPSA0MDZdID0gXCJOb3RBY2NlcHRhYmxlXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkXCJdID0gNDA3XSA9IFwiUHJveHlBdXRoZW50aWNhdGlvblJlcXVpcmVkXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiUmVxdWVzdFRpbWVvdXRcIl0gPSA0MDhdID0gXCJSZXF1ZXN0VGltZW91dFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIkNvbmZsaWN0XCJdID0gNDA5XSA9IFwiQ29uZmxpY3RcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJHb25lXCJdID0gNDEwXSA9IFwiR29uZVwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIkxlbmd0aFJlcXVpcmVkXCJdID0gNDExXSA9IFwiTGVuZ3RoUmVxdWlyZWRcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJQcmVjb25kaXRpb25GYWlsZWRcIl0gPSA0MTJdID0gXCJQcmVjb25kaXRpb25GYWlsZWRcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJQYXlsb2FkVG9vTGFyZ2VcIl0gPSA0MTNdID0gXCJQYXlsb2FkVG9vTGFyZ2VcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJVcmlUb29Mb25nXCJdID0gNDE0XSA9IFwiVXJpVG9vTG9uZ1wiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIlVuc3VwcG9ydGVkTWVkaWFUeXBlXCJdID0gNDE1XSA9IFwiVW5zdXBwb3J0ZWRNZWRpYVR5cGVcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJSYW5nZU5vdFNhdGlzZmlhYmxlXCJdID0gNDE2XSA9IFwiUmFuZ2VOb3RTYXRpc2ZpYWJsZVwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIkV4cGVjdGF0aW9uRmFpbGVkXCJdID0gNDE3XSA9IFwiRXhwZWN0YXRpb25GYWlsZWRcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJJbUFUZWFwb3RcIl0gPSA0MThdID0gXCJJbUFUZWFwb3RcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJNaXNkaXJlY3RlZFJlcXVlc3RcIl0gPSA0MjFdID0gXCJNaXNkaXJlY3RlZFJlcXVlc3RcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJVbnByb2Nlc3NhYmxlRW50aXR5XCJdID0gNDIyXSA9IFwiVW5wcm9jZXNzYWJsZUVudGl0eVwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIkxvY2tlZFwiXSA9IDQyM10gPSBcIkxvY2tlZFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIkZhaWxlZERlcGVuZGVuY3lcIl0gPSA0MjRdID0gXCJGYWlsZWREZXBlbmRlbmN5XCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiVG9vRWFybHlcIl0gPSA0MjVdID0gXCJUb29FYXJseVwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIlVwZ3JhZGVSZXF1aXJlZFwiXSA9IDQyNl0gPSBcIlVwZ3JhZGVSZXF1aXJlZFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIlByZWNvbmRpdGlvblJlcXVpcmVkXCJdID0gNDI4XSA9IFwiUHJlY29uZGl0aW9uUmVxdWlyZWRcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJUb29NYW55UmVxdWVzdHNcIl0gPSA0MjldID0gXCJUb29NYW55UmVxdWVzdHNcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJSZXF1ZXN0SGVhZGVyRmllbGRzVG9vTGFyZ2VcIl0gPSA0MzFdID0gXCJSZXF1ZXN0SGVhZGVyRmllbGRzVG9vTGFyZ2VcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJVbmF2YWlsYWJsZUZvckxlZ2FsUmVhc29uc1wiXSA9IDQ1MV0gPSBcIlVuYXZhaWxhYmxlRm9yTGVnYWxSZWFzb25zXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiSW50ZXJuYWxTZXJ2ZXJFcnJvclwiXSA9IDUwMF0gPSBcIkludGVybmFsU2VydmVyRXJyb3JcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJOb3RJbXBsZW1lbnRlZFwiXSA9IDUwMV0gPSBcIk5vdEltcGxlbWVudGVkXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiQmFkR2F0ZXdheVwiXSA9IDUwMl0gPSBcIkJhZEdhdGV3YXlcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJTZXJ2aWNlVW5hdmFpbGFibGVcIl0gPSA1MDNdID0gXCJTZXJ2aWNlVW5hdmFpbGFibGVcIjtcbiAgSHR0cFN0YXR1c0NvZGVbSHR0cFN0YXR1c0NvZGVbXCJHYXRld2F5VGltZW91dFwiXSA9IDUwNF0gPSBcIkdhdGV3YXlUaW1lb3V0XCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiSHR0cFZlcnNpb25Ob3RTdXBwb3J0ZWRcIl0gPSA1MDVdID0gXCJIdHRwVmVyc2lvbk5vdFN1cHBvcnRlZFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIlZhcmlhbnRBbHNvTmVnb3RpYXRlc1wiXSA9IDUwNl0gPSBcIlZhcmlhbnRBbHNvTmVnb3RpYXRlc1wiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIkluc3VmZmljaWVudFN0b3JhZ2VcIl0gPSA1MDddID0gXCJJbnN1ZmZpY2llbnRTdG9yYWdlXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiTG9vcERldGVjdGVkXCJdID0gNTA4XSA9IFwiTG9vcERldGVjdGVkXCI7XG4gIEh0dHBTdGF0dXNDb2RlW0h0dHBTdGF0dXNDb2RlW1wiTm90RXh0ZW5kZWRcIl0gPSA1MTBdID0gXCJOb3RFeHRlbmRlZFwiO1xuICBIdHRwU3RhdHVzQ29kZVtIdHRwU3RhdHVzQ29kZVtcIk5ldHdvcmtBdXRoZW50aWNhdGlvblJlcXVpcmVkXCJdID0gNTExXSA9IFwiTmV0d29ya0F1dGhlbnRpY2F0aW9uUmVxdWlyZWRcIjtcbn0pKEh0dHBTdGF0dXNDb2RlIHx8IChIdHRwU3RhdHVzQ29kZSA9IHt9KSk7XG5cbi8qKlxuICogQ29uc3RydWN0cyBhbiBpbnN0YW5jZSBvZiBgSHR0cFJlcXVlc3RPcHRpb25zPFQ+YCBmcm9tIGEgc291cmNlIGBIdHRwTWV0aG9kT3B0aW9uc2AgYW5kXG4gKiB0aGUgZ2l2ZW4gYGJvZHlgLiBUaGlzIGZ1bmN0aW9uIGNsb25lcyB0aGUgb2JqZWN0IGFuZCBhZGRzIHRoZSBib2R5LlxuICpcbiAqIE5vdGUgdGhhdCB0aGUgYHJlc3BvbnNlVHlwZWAgKm9wdGlvbnMqIHZhbHVlIGlzIGEgU3RyaW5nIHRoYXQgaWRlbnRpZmllcyB0aGVcbiAqIHNpbmdsZSBkYXRhIHR5cGUgb2YgdGhlIHJlc3BvbnNlLlxuICogQSBzaW5nbGUgb3ZlcmxvYWQgdmVyc2lvbiBvZiB0aGUgbWV0aG9kIGhhbmRsZXMgZWFjaCByZXNwb25zZSB0eXBlLlxuICogVGhlIHZhbHVlIG9mIGByZXNwb25zZVR5cGVgIGNhbm5vdCBiZSBhIHVuaW9uLCBhcyB0aGUgY29tYmluZWQgc2lnbmF0dXJlIGNvdWxkIGltcGx5LlxuICpcbiAqL1xuZnVuY3Rpb24gYWRkQm9keShvcHRpb25zLCBib2R5KSB7XG4gIHJldHVybiB7XG4gICAgYm9keSxcbiAgICBoZWFkZXJzOiBvcHRpb25zLmhlYWRlcnMsXG4gICAgY29udGV4dDogb3B0aW9ucy5jb250ZXh0LFxuICAgIG9ic2VydmU6IG9wdGlvbnMub2JzZXJ2ZSxcbiAgICBwYXJhbXM6IG9wdGlvbnMucGFyYW1zLFxuICAgIHJlcG9ydFByb2dyZXNzOiBvcHRpb25zLnJlcG9ydFByb2dyZXNzLFxuICAgIHJlc3BvbnNlVHlwZTogb3B0aW9ucy5yZXNwb25zZVR5cGUsXG4gICAgd2l0aENyZWRlbnRpYWxzOiBvcHRpb25zLndpdGhDcmVkZW50aWFscyxcbiAgICB0cmFuc2ZlckNhY2hlOiBvcHRpb25zLnRyYW5zZmVyQ2FjaGVcbiAgfTtcbn1cbi8qKlxuICogUGVyZm9ybXMgSFRUUCByZXF1ZXN0cy5cbiAqIFRoaXMgc2VydmljZSBpcyBhdmFpbGFibGUgYXMgYW4gaW5qZWN0YWJsZSBjbGFzcywgd2l0aCBtZXRob2RzIHRvIHBlcmZvcm0gSFRUUCByZXF1ZXN0cy5cbiAqIEVhY2ggcmVxdWVzdCBtZXRob2QgaGFzIG11bHRpcGxlIHNpZ25hdHVyZXMsIGFuZCB0aGUgcmV0dXJuIHR5cGUgdmFyaWVzIGJhc2VkIG9uXG4gKiB0aGUgc2lnbmF0dXJlIHRoYXQgaXMgY2FsbGVkIChtYWlubHkgdGhlIHZhbHVlcyBvZiBgb2JzZXJ2ZWAgYW5kIGByZXNwb25zZVR5cGVgKS5cbiAqXG4gKiBOb3RlIHRoYXQgdGhlIGByZXNwb25zZVR5cGVgICpvcHRpb25zKiB2YWx1ZSBpcyBhIFN0cmluZyB0aGF0IGlkZW50aWZpZXMgdGhlXG4gKiBzaW5nbGUgZGF0YSB0eXBlIG9mIHRoZSByZXNwb25zZS5cbiAqIEEgc2luZ2xlIG92ZXJsb2FkIHZlcnNpb24gb2YgdGhlIG1ldGhvZCBoYW5kbGVzIGVhY2ggcmVzcG9uc2UgdHlwZS5cbiAqIFRoZSB2YWx1ZSBvZiBgcmVzcG9uc2VUeXBlYCBjYW5ub3QgYmUgYSB1bmlvbiwgYXMgdGhlIGNvbWJpbmVkIHNpZ25hdHVyZSBjb3VsZCBpbXBseS5cblxuICogVE9ETyhhZGV2KTogcmV2aWV3XG4gKiBAdXNhZ2VOb3Rlc1xuICpcbiAqICMjIyBIVFRQIFJlcXVlc3QgRXhhbXBsZVxuICpcbiAqIGBgYFxuICogIC8vIEdFVCBoZXJvZXMgd2hvc2UgbmFtZSBjb250YWlucyBzZWFyY2ggdGVybVxuICogc2VhcmNoSGVyb2VzKHRlcm06IHN0cmluZyk6IG9ic2VydmFibGU8SGVyb1tdPntcbiAqXG4gKiAgY29uc3QgcGFyYW1zID0gbmV3IEh0dHBQYXJhbXMoe2Zyb21TdHJpbmc6ICduYW1lPXRlcm0nfSk7XG4gKiAgICByZXR1cm4gdGhpcy5odHRwQ2xpZW50LnJlcXVlc3QoJ0dFVCcsIHRoaXMuaGVyb2VzVXJsLCB7cmVzcG9uc2VUeXBlOidqc29uJywgcGFyYW1zfSk7XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBBbHRlcm5hdGl2ZWx5LCB0aGUgcGFyYW1ldGVyIHN0cmluZyBjYW4gYmUgdXNlZCB3aXRob3V0IGludm9raW5nIEh0dHBQYXJhbXNcbiAqIGJ5IGRpcmVjdGx5IGpvaW5pbmcgdG8gdGhlIFVSTC5cbiAqIGBgYFxuICogdGhpcy5odHRwQ2xpZW50LnJlcXVlc3QoJ0dFVCcsIHRoaXMuaGVyb2VzVXJsICsgJz8nICsgJ25hbWU9dGVybScsIHtyZXNwb25zZVR5cGU6J2pzb24nfSk7XG4gKiBgYGBcbiAqXG4gKlxuICogIyMjIEpTT05QIEV4YW1wbGVcbiAqIGBgYFxuICogcmVxdWVzdEpzb25wKHVybCwgY2FsbGJhY2sgPSAnY2FsbGJhY2snKSB7XG4gKiAgcmV0dXJuIHRoaXMuaHR0cENsaWVudC5qc29ucCh0aGlzLmhlcm9lc1VSTCwgY2FsbGJhY2spO1xuICogfVxuICogYGBgXG4gKlxuICogIyMjIFBBVENIIEV4YW1wbGVcbiAqIGBgYFxuICogLy8gUEFUQ0ggb25lIG9mIHRoZSBoZXJvZXMnIG5hbWVcbiAqIHBhdGNoSGVybyAoaWQ6IG51bWJlciwgaGVyb05hbWU6IHN0cmluZyk6IE9ic2VydmFibGU8e30+IHtcbiAqIGNvbnN0IHVybCA9IGAke3RoaXMuaGVyb2VzVXJsfS8ke2lkfWA7ICAgLy8gUEFUQ0ggYXBpL2hlcm9lcy80MlxuICogIHJldHVybiB0aGlzLmh0dHBDbGllbnQucGF0Y2godXJsLCB7bmFtZTogaGVyb05hbWV9LCBodHRwT3B0aW9ucylcbiAqICAgIC5waXBlKGNhdGNoRXJyb3IodGhpcy5oYW5kbGVFcnJvcigncGF0Y2hIZXJvJykpKTtcbiAqIH1cbiAqIGBgYFxuICpcbiAqIEBzZWUgW0hUVFAgR3VpZGVdKGd1aWRlL2h0dHApXG4gKiBAc2VlIFtIVFRQIFJlcXVlc3RdKGFwaS9jb21tb24vaHR0cC9IdHRwUmVxdWVzdClcbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIEh0dHBDbGllbnQge1xuICBjb25zdHJ1Y3RvcihoYW5kbGVyKSB7XG4gICAgdGhpcy5oYW5kbGVyID0gaGFuZGxlcjtcbiAgfVxuICAvKipcbiAgICogQ29uc3RydWN0cyBhbiBvYnNlcnZhYmxlIGZvciBhIGdlbmVyaWMgSFRUUCByZXF1ZXN0IHRoYXQsIHdoZW4gc3Vic2NyaWJlZCxcbiAgICogZmlyZXMgdGhlIHJlcXVlc3QgdGhyb3VnaCB0aGUgY2hhaW4gb2YgcmVnaXN0ZXJlZCBpbnRlcmNlcHRvcnMgYW5kIG9uIHRvIHRoZVxuICAgKiBzZXJ2ZXIuXG4gICAqXG4gICAqIFlvdSBjYW4gcGFzcyBhbiBgSHR0cFJlcXVlc3RgIGRpcmVjdGx5IGFzIHRoZSBvbmx5IHBhcmFtZXRlci4gSW4gdGhpcyBjYXNlLFxuICAgKiB0aGUgY2FsbCByZXR1cm5zIGFuIG9ic2VydmFibGUgb2YgdGhlIHJhdyBgSHR0cEV2ZW50YCBzdHJlYW0uXG4gICAqXG4gICAqIEFsdGVybmF0aXZlbHkgeW91IGNhbiBwYXNzIGFuIEhUVFAgbWV0aG9kIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXIsXG4gICAqIGEgVVJMIHN0cmluZyBhcyB0aGUgc2Vjb25kLCBhbmQgYW4gb3B0aW9ucyBoYXNoIGNvbnRhaW5pbmcgdGhlIHJlcXVlc3QgYm9keSBhcyB0aGUgdGhpcmQuXG4gICAqIFNlZSBgYWRkQm9keSgpYC4gSW4gdGhpcyBjYXNlLCB0aGUgc3BlY2lmaWVkIGByZXNwb25zZVR5cGVgIGFuZCBgb2JzZXJ2ZWAgb3B0aW9ucyBkZXRlcm1pbmUgdGhlXG4gICAqIHR5cGUgb2YgcmV0dXJuZWQgb2JzZXJ2YWJsZS5cbiAgICogICAqIFRoZSBgcmVzcG9uc2VUeXBlYCB2YWx1ZSBkZXRlcm1pbmVzIGhvdyBhIHN1Y2Nlc3NmdWwgcmVzcG9uc2UgYm9keSBpcyBwYXJzZWQuXG4gICAqICAgKiBJZiBgcmVzcG9uc2VUeXBlYCBpcyB0aGUgZGVmYXVsdCBganNvbmAsIHlvdSBjYW4gcGFzcyBhIHR5cGUgaW50ZXJmYWNlIGZvciB0aGUgcmVzdWx0aW5nXG4gICAqIG9iamVjdCBhcyBhIHR5cGUgcGFyYW1ldGVyIHRvIHRoZSBjYWxsLlxuICAgKlxuICAgKiBUaGUgYG9ic2VydmVgIHZhbHVlIGRldGVybWluZXMgdGhlIHJldHVybiB0eXBlLCBhY2NvcmRpbmcgdG8gd2hhdCB5b3UgYXJlIGludGVyZXN0ZWQgaW5cbiAgICogb2JzZXJ2aW5nLlxuICAgKiAgICogQW4gYG9ic2VydmVgIHZhbHVlIG9mIGV2ZW50cyByZXR1cm5zIGFuIG9ic2VydmFibGUgb2YgdGhlIHJhdyBgSHR0cEV2ZW50YCBzdHJlYW0sIGluY2x1ZGluZ1xuICAgKiBwcm9ncmVzcyBldmVudHMgYnkgZGVmYXVsdC5cbiAgICogICAqIEFuIGBvYnNlcnZlYCB2YWx1ZSBvZiByZXNwb25zZSByZXR1cm5zIGFuIG9ic2VydmFibGUgb2YgYEh0dHBSZXNwb25zZTxUPmAsXG4gICAqIHdoZXJlIHRoZSBgVGAgcGFyYW1ldGVyIGRlcGVuZHMgb24gdGhlIGByZXNwb25zZVR5cGVgIGFuZCBhbnkgb3B0aW9uYWxseSBwcm92aWRlZCB0eXBlXG4gICAqIHBhcmFtZXRlci5cbiAgICogICAqIEFuIGBvYnNlcnZlYCB2YWx1ZSBvZiBib2R5IHJldHVybnMgYW4gb2JzZXJ2YWJsZSBvZiBgPFQ+YCB3aXRoIHRoZSBzYW1lIGBUYCBib2R5IHR5cGUuXG4gICAqXG4gICAqL1xuICByZXF1ZXN0KGZpcnN0LCB1cmwsIG9wdGlvbnMgPSB7fSkge1xuICAgIGxldCByZXE7XG4gICAgLy8gRmlyc3QsIGNoZWNrIHdoZXRoZXIgdGhlIHByaW1hcnkgYXJndW1lbnQgaXMgYW4gaW5zdGFuY2Ugb2YgYEh0dHBSZXF1ZXN0YC5cbiAgICBpZiAoZmlyc3QgaW5zdGFuY2VvZiBIdHRwUmVxdWVzdCkge1xuICAgICAgLy8gSXQgaXMuIFRoZSBvdGhlciBhcmd1bWVudHMgbXVzdCBiZSB1bmRlZmluZWQgKHBlciB0aGUgc2lnbmF0dXJlcykgYW5kIGNhbiBiZVxuICAgICAgLy8gaWdub3JlZC5cbiAgICAgIHJlcSA9IGZpcnN0O1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJdCdzIGEgc3RyaW5nLCBzbyBpdCByZXByZXNlbnRzIGEgVVJMLiBDb25zdHJ1Y3QgYSByZXF1ZXN0IGJhc2VkIG9uIGl0LFxuICAgICAgLy8gYW5kIGluY29ycG9yYXRlIHRoZSByZW1haW5pbmcgYXJndW1lbnRzIChhc3N1bWluZyBgR0VUYCB1bmxlc3MgYSBtZXRob2QgaXNcbiAgICAgIC8vIHByb3ZpZGVkLlxuICAgICAgLy8gRmlndXJlIG91dCB0aGUgaGVhZGVycy5cbiAgICAgIGxldCBoZWFkZXJzID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKG9wdGlvbnMuaGVhZGVycyBpbnN0YW5jZW9mIEh0dHBIZWFkZXJzKSB7XG4gICAgICAgIGhlYWRlcnMgPSBvcHRpb25zLmhlYWRlcnM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoZWFkZXJzID0gbmV3IEh0dHBIZWFkZXJzKG9wdGlvbnMuaGVhZGVycyk7XG4gICAgICB9XG4gICAgICAvLyBTb3J0IG91dCBwYXJhbWV0ZXJzLlxuICAgICAgbGV0IHBhcmFtcyA9IHVuZGVmaW5lZDtcbiAgICAgIGlmICghIW9wdGlvbnMucGFyYW1zKSB7XG4gICAgICAgIGlmIChvcHRpb25zLnBhcmFtcyBpbnN0YW5jZW9mIEh0dHBQYXJhbXMpIHtcbiAgICAgICAgICBwYXJhbXMgPSBvcHRpb25zLnBhcmFtcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBwYXJhbXMgPSBuZXcgSHR0cFBhcmFtcyh7XG4gICAgICAgICAgICBmcm9tT2JqZWN0OiBvcHRpb25zLnBhcmFtc1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBDb25zdHJ1Y3QgdGhlIHJlcXVlc3QuXG4gICAgICByZXEgPSBuZXcgSHR0cFJlcXVlc3QoZmlyc3QsIHVybCwgb3B0aW9ucy5ib2R5ICE9PSB1bmRlZmluZWQgPyBvcHRpb25zLmJvZHkgOiBudWxsLCB7XG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIGNvbnRleHQ6IG9wdGlvbnMuY29udGV4dCxcbiAgICAgICAgcGFyYW1zLFxuICAgICAgICByZXBvcnRQcm9ncmVzczogb3B0aW9ucy5yZXBvcnRQcm9ncmVzcyxcbiAgICAgICAgLy8gQnkgZGVmYXVsdCwgSlNPTiBpcyBhc3N1bWVkIHRvIGJlIHJldHVybmVkIGZvciBhbGwgY2FsbHMuXG4gICAgICAgIHJlc3BvbnNlVHlwZTogb3B0aW9ucy5yZXNwb25zZVR5cGUgfHwgJ2pzb24nLFxuICAgICAgICB3aXRoQ3JlZGVudGlhbHM6IG9wdGlvbnMud2l0aENyZWRlbnRpYWxzLFxuICAgICAgICB0cmFuc2ZlckNhY2hlOiBvcHRpb25zLnRyYW5zZmVyQ2FjaGVcbiAgICAgIH0pO1xuICAgIH1cbiAgICAvLyBTdGFydCB3aXRoIGFuIE9ic2VydmFibGUub2YoKSB0aGUgaW5pdGlhbCByZXF1ZXN0LCBhbmQgcnVuIHRoZSBoYW5kbGVyICh3aGljaFxuICAgIC8vIGluY2x1ZGVzIGFsbCBpbnRlcmNlcHRvcnMpIGluc2lkZSBhIGNvbmNhdE1hcCgpLiBUaGlzIHdheSwgdGhlIGhhbmRsZXIgcnVuc1xuICAgIC8vIGluc2lkZSBhbiBPYnNlcnZhYmxlIGNoYWluLCB3aGljaCBjYXVzZXMgaW50ZXJjZXB0b3JzIHRvIGJlIHJlLXJ1biBvbiBldmVyeVxuICAgIC8vIHN1YnNjcmlwdGlvbiAodGhpcyBhbHNvIG1ha2VzIHJldHJpZXMgcmUtcnVuIHRoZSBoYW5kbGVyLCBpbmNsdWRpbmcgaW50ZXJjZXB0b3JzKS5cbiAgICBjb25zdCBldmVudHMkID0gb2YocmVxKS5waXBlKGNvbmNhdE1hcChyZXEgPT4gdGhpcy5oYW5kbGVyLmhhbmRsZShyZXEpKSk7XG4gICAgLy8gSWYgY29taW5nIHZpYSB0aGUgQVBJIHNpZ25hdHVyZSB3aGljaCBhY2NlcHRzIGEgcHJldmlvdXNseSBjb25zdHJ1Y3RlZCBIdHRwUmVxdWVzdCxcbiAgICAvLyB0aGUgb25seSBvcHRpb24gaXMgdG8gZ2V0IHRoZSBldmVudCBzdHJlYW0uIE90aGVyd2lzZSwgcmV0dXJuIHRoZSBldmVudCBzdHJlYW0gaWZcbiAgICAvLyB0aGF0IGlzIHdoYXQgd2FzIHJlcXVlc3RlZC5cbiAgICBpZiAoZmlyc3QgaW5zdGFuY2VvZiBIdHRwUmVxdWVzdCB8fCBvcHRpb25zLm9ic2VydmUgPT09ICdldmVudHMnKSB7XG4gICAgICByZXR1cm4gZXZlbnRzJDtcbiAgICB9XG4gICAgLy8gVGhlIHJlcXVlc3RlZCBzdHJlYW0gY29udGFpbnMgZWl0aGVyIHRoZSBmdWxsIHJlc3BvbnNlIG9yIHRoZSBib2R5LiBJbiBlaXRoZXJcbiAgICAvLyBjYXNlLCB0aGUgZmlyc3Qgc3RlcCBpcyB0byBmaWx0ZXIgdGhlIGV2ZW50IHN0cmVhbSB0byBleHRyYWN0IGEgc3RyZWFtIG9mXG4gICAgLy8gcmVzcG9uc2VzKHMpLlxuICAgIGNvbnN0IHJlcyQgPSBldmVudHMkLnBpcGUoZmlsdGVyKGV2ZW50ID0+IGV2ZW50IGluc3RhbmNlb2YgSHR0cFJlc3BvbnNlKSk7XG4gICAgLy8gRGVjaWRlIHdoaWNoIHN0cmVhbSB0byByZXR1cm4uXG4gICAgc3dpdGNoIChvcHRpb25zLm9ic2VydmUgfHwgJ2JvZHknKSB7XG4gICAgICBjYXNlICdib2R5JzpcbiAgICAgICAgLy8gVGhlIHJlcXVlc3RlZCBzdHJlYW0gaXMgdGhlIGJvZHkuIE1hcCB0aGUgcmVzcG9uc2Ugc3RyZWFtIHRvIHRoZSByZXNwb25zZVxuICAgICAgICAvLyBib2R5LiBUaGlzIGNvdWxkIGJlIGRvbmUgbW9yZSBzaW1wbHksIGJ1dCBhIG1pc2JlaGF2aW5nIGludGVyY2VwdG9yIG1pZ2h0XG4gICAgICAgIC8vIHRyYW5zZm9ybSB0aGUgcmVzcG9uc2UgYm9keSBpbnRvIGEgZGlmZmVyZW50IGZvcm1hdCBhbmQgaWdub3JlIHRoZSByZXF1ZXN0ZWRcbiAgICAgICAgLy8gcmVzcG9uc2VUeXBlLiBHdWFyZCBhZ2FpbnN0IHRoaXMgYnkgdmFsaWRhdGluZyB0aGF0IHRoZSByZXNwb25zZSBpcyBvZiB0aGVcbiAgICAgICAgLy8gcmVxdWVzdGVkIHR5cGUuXG4gICAgICAgIHN3aXRjaCAocmVxLnJlc3BvbnNlVHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2FycmF5YnVmZmVyJzpcbiAgICAgICAgICAgIHJldHVybiByZXMkLnBpcGUobWFwKHJlcyA9PiB7XG4gICAgICAgICAgICAgIC8vIFZhbGlkYXRlIHRoYXQgdGhlIGJvZHkgaXMgYW4gQXJyYXlCdWZmZXIuXG4gICAgICAgICAgICAgIGlmIChyZXMuYm9keSAhPT0gbnVsbCAmJiAhKHJlcy5ib2R5IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZXNwb25zZSBpcyBub3QgYW4gQXJyYXlCdWZmZXIuJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHJlcy5ib2R5O1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIGNhc2UgJ2Jsb2InOlxuICAgICAgICAgICAgcmV0dXJuIHJlcyQucGlwZShtYXAocmVzID0+IHtcbiAgICAgICAgICAgICAgLy8gVmFsaWRhdGUgdGhhdCB0aGUgYm9keSBpcyBhIEJsb2IuXG4gICAgICAgICAgICAgIGlmIChyZXMuYm9keSAhPT0gbnVsbCAmJiAhKHJlcy5ib2R5IGluc3RhbmNlb2YgQmxvYikpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc3BvbnNlIGlzIG5vdCBhIEJsb2IuJyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIHJlcy5ib2R5O1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICAgIGNhc2UgJ3RleHQnOlxuICAgICAgICAgICAgcmV0dXJuIHJlcyQucGlwZShtYXAocmVzID0+IHtcbiAgICAgICAgICAgICAgLy8gVmFsaWRhdGUgdGhhdCB0aGUgYm9keSBpcyBhIHN0cmluZy5cbiAgICAgICAgICAgICAgaWYgKHJlcy5ib2R5ICE9PSBudWxsICYmIHR5cGVvZiByZXMuYm9keSAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Jlc3BvbnNlIGlzIG5vdCBhIHN0cmluZy4nKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gcmVzLmJvZHk7XG4gICAgICAgICAgICB9KSk7XG4gICAgICAgICAgY2FzZSAnanNvbic6XG4gICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgIC8vIE5vIHZhbGlkYXRpb24gbmVlZGVkIGZvciBKU09OIHJlc3BvbnNlcywgYXMgdGhleSBjYW4gYmUgb2YgYW55IHR5cGUuXG4gICAgICAgICAgICByZXR1cm4gcmVzJC5waXBlKG1hcChyZXMgPT4gcmVzLmJvZHkpKTtcbiAgICAgICAgfVxuICAgICAgY2FzZSAncmVzcG9uc2UnOlxuICAgICAgICAvLyBUaGUgcmVzcG9uc2Ugc3RyZWFtIHdhcyByZXF1ZXN0ZWQgZGlyZWN0bHksIHNvIHJldHVybiBpdC5cbiAgICAgICAgcmV0dXJuIHJlcyQ7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICAvLyBHdWFyZCBhZ2FpbnN0IG5ldyBmdXR1cmUgb2JzZXJ2ZSB0eXBlcyBiZWluZyBhZGRlZC5cbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnJlYWNoYWJsZTogdW5oYW5kbGVkIG9ic2VydmUgdHlwZSAke29wdGlvbnMub2JzZXJ2ZX19YCk7XG4gICAgfVxuICB9XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGFuIG9ic2VydmFibGUgdGhhdCwgd2hlbiBzdWJzY3JpYmVkLCBjYXVzZXMgdGhlIGNvbmZpZ3VyZWRcbiAgICogYERFTEVURWAgcmVxdWVzdCB0byBleGVjdXRlIG9uIHRoZSBzZXJ2ZXIuIFNlZSB0aGUgaW5kaXZpZHVhbCBvdmVybG9hZHMgZm9yXG4gICAqIGRldGFpbHMgb24gdGhlIHJldHVybiB0eXBlLlxuICAgKlxuICAgKiBAcGFyYW0gdXJsICAgICBUaGUgZW5kcG9pbnQgVVJMLlxuICAgKiBAcGFyYW0gb3B0aW9ucyBUaGUgSFRUUCBvcHRpb25zIHRvIHNlbmQgd2l0aCB0aGUgcmVxdWVzdC5cbiAgICpcbiAgICovXG4gIGRlbGV0ZSh1cmwsIG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ0RFTEVURScsIHVybCwgb3B0aW9ucyk7XG4gIH1cbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgYW4gb2JzZXJ2YWJsZSB0aGF0LCB3aGVuIHN1YnNjcmliZWQsIGNhdXNlcyB0aGUgY29uZmlndXJlZFxuICAgKiBgR0VUYCByZXF1ZXN0IHRvIGV4ZWN1dGUgb24gdGhlIHNlcnZlci4gU2VlIHRoZSBpbmRpdmlkdWFsIG92ZXJsb2FkcyBmb3JcbiAgICogZGV0YWlscyBvbiB0aGUgcmV0dXJuIHR5cGUuXG4gICAqL1xuICBnZXQodXJsLCBvcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdHRVQnLCB1cmwsIG9wdGlvbnMpO1xuICB9XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGFuIG9ic2VydmFibGUgdGhhdCwgd2hlbiBzdWJzY3JpYmVkLCBjYXVzZXMgdGhlIGNvbmZpZ3VyZWRcbiAgICogYEhFQURgIHJlcXVlc3QgdG8gZXhlY3V0ZSBvbiB0aGUgc2VydmVyLiBUaGUgYEhFQURgIG1ldGhvZCByZXR1cm5zXG4gICAqIG1ldGEgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHJlc291cmNlIHdpdGhvdXQgdHJhbnNmZXJyaW5nIHRoZVxuICAgKiByZXNvdXJjZSBpdHNlbGYuIFNlZSB0aGUgaW5kaXZpZHVhbCBvdmVybG9hZHMgZm9yXG4gICAqIGRldGFpbHMgb24gdGhlIHJldHVybiB0eXBlLlxuICAgKi9cbiAgaGVhZCh1cmwsIG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QoJ0hFQUQnLCB1cmwsIG9wdGlvbnMpO1xuICB9XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGFuIGBPYnNlcnZhYmxlYCB0aGF0LCB3aGVuIHN1YnNjcmliZWQsIGNhdXNlcyBhIHJlcXVlc3Qgd2l0aCB0aGUgc3BlY2lhbCBtZXRob2RcbiAgICogYEpTT05QYCB0byBiZSBkaXNwYXRjaGVkIHZpYSB0aGUgaW50ZXJjZXB0b3IgcGlwZWxpbmUuXG4gICAqIFRoZSBbSlNPTlAgcGF0dGVybl0oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvSlNPTlApIHdvcmtzIGFyb3VuZCBsaW1pdGF0aW9ucyBvZiBjZXJ0YWluXG4gICAqIEFQSSBlbmRwb2ludHMgdGhhdCBkb24ndCBzdXBwb3J0IG5ld2VyLFxuICAgKiBhbmQgcHJlZmVyYWJsZSBbQ09SU10oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRUUC9DT1JTKSBwcm90b2NvbC5cbiAgICogSlNPTlAgdHJlYXRzIHRoZSBlbmRwb2ludCBBUEkgYXMgYSBKYXZhU2NyaXB0IGZpbGUgYW5kIHRyaWNrcyB0aGUgYnJvd3NlciB0byBwcm9jZXNzIHRoZVxuICAgKiByZXF1ZXN0cyBldmVuIGlmIHRoZSBBUEkgZW5kcG9pbnQgaXMgbm90IGxvY2F0ZWQgb24gdGhlIHNhbWUgZG9tYWluIChvcmlnaW4pIGFzIHRoZSBjbGllbnQtc2lkZVxuICAgKiBhcHBsaWNhdGlvbiBtYWtpbmcgdGhlIHJlcXVlc3QuXG4gICAqIFRoZSBlbmRwb2ludCBBUEkgbXVzdCBzdXBwb3J0IEpTT05QIGNhbGxiYWNrIGZvciBKU09OUCByZXF1ZXN0cyB0byB3b3JrLlxuICAgKiBUaGUgcmVzb3VyY2UgQVBJIHJldHVybnMgdGhlIEpTT04gcmVzcG9uc2Ugd3JhcHBlZCBpbiBhIGNhbGxiYWNrIGZ1bmN0aW9uLlxuICAgKiBZb3UgY2FuIHBhc3MgdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIG5hbWUgYXMgb25lIG9mIHRoZSBxdWVyeSBwYXJhbWV0ZXJzLlxuICAgKiBOb3RlIHRoYXQgSlNPTlAgcmVxdWVzdHMgY2FuIG9ubHkgYmUgdXNlZCB3aXRoIGBHRVRgIHJlcXVlc3RzLlxuICAgKlxuICAgKiBAcGFyYW0gdXJsIFRoZSByZXNvdXJjZSBVUkwuXG4gICAqIEBwYXJhbSBjYWxsYmFja1BhcmFtIFRoZSBjYWxsYmFjayBmdW5jdGlvbiBuYW1lLlxuICAgKlxuICAgKi9cbiAganNvbnAodXJsLCBjYWxsYmFja1BhcmFtKSB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdCgnSlNPTlAnLCB1cmwsIHtcbiAgICAgIHBhcmFtczogbmV3IEh0dHBQYXJhbXMoKS5hcHBlbmQoY2FsbGJhY2tQYXJhbSwgJ0pTT05QX0NBTExCQUNLJyksXG4gICAgICBvYnNlcnZlOiAnYm9keScsXG4gICAgICByZXNwb25zZVR5cGU6ICdqc29uJ1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIGFuIGBPYnNlcnZhYmxlYCB0aGF0LCB3aGVuIHN1YnNjcmliZWQsIGNhdXNlcyB0aGUgY29uZmlndXJlZFxuICAgKiBgT1BUSU9OU2AgcmVxdWVzdCB0byBleGVjdXRlIG9uIHRoZSBzZXJ2ZXIuIFRoaXMgbWV0aG9kIGFsbG93cyB0aGUgY2xpZW50XG4gICAqIHRvIGRldGVybWluZSB0aGUgc3VwcG9ydGVkIEhUVFAgbWV0aG9kcyBhbmQgb3RoZXIgY2FwYWJpbGl0aWVzIG9mIGFuIGVuZHBvaW50LFxuICAgKiB3aXRob3V0IGltcGx5aW5nIGEgcmVzb3VyY2UgYWN0aW9uLiBTZWUgdGhlIGluZGl2aWR1YWwgb3ZlcmxvYWRzIGZvclxuICAgKiBkZXRhaWxzIG9uIHRoZSByZXR1cm4gdHlwZS5cbiAgICovXG4gIG9wdGlvbnModXJsLCBvcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdPUFRJT05TJywgdXJsLCBvcHRpb25zKTtcbiAgfVxuICAvKipcbiAgICogQ29uc3RydWN0cyBhbiBvYnNlcnZhYmxlIHRoYXQsIHdoZW4gc3Vic2NyaWJlZCwgY2F1c2VzIHRoZSBjb25maWd1cmVkXG4gICAqIGBQQVRDSGAgcmVxdWVzdCB0byBleGVjdXRlIG9uIHRoZSBzZXJ2ZXIuIFNlZSB0aGUgaW5kaXZpZHVhbCBvdmVybG9hZHMgZm9yXG4gICAqIGRldGFpbHMgb24gdGhlIHJldHVybiB0eXBlLlxuICAgKi9cbiAgcGF0Y2godXJsLCBib2R5LCBvcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdQQVRDSCcsIHVybCwgYWRkQm9keShvcHRpb25zLCBib2R5KSk7XG4gIH1cbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgYW4gb2JzZXJ2YWJsZSB0aGF0LCB3aGVuIHN1YnNjcmliZWQsIGNhdXNlcyB0aGUgY29uZmlndXJlZFxuICAgKiBgUE9TVGAgcmVxdWVzdCB0byBleGVjdXRlIG9uIHRoZSBzZXJ2ZXIuIFRoZSBzZXJ2ZXIgcmVzcG9uZHMgd2l0aCB0aGUgbG9jYXRpb24gb2ZcbiAgICogdGhlIHJlcGxhY2VkIHJlc291cmNlLiBTZWUgdGhlIGluZGl2aWR1YWwgb3ZlcmxvYWRzIGZvclxuICAgKiBkZXRhaWxzIG9uIHRoZSByZXR1cm4gdHlwZS5cbiAgICovXG4gIHBvc3QodXJsLCBib2R5LCBvcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdQT1NUJywgdXJsLCBhZGRCb2R5KG9wdGlvbnMsIGJvZHkpKTtcbiAgfVxuICAvKipcbiAgICogQ29uc3RydWN0cyBhbiBvYnNlcnZhYmxlIHRoYXQsIHdoZW4gc3Vic2NyaWJlZCwgY2F1c2VzIHRoZSBjb25maWd1cmVkXG4gICAqIGBQVVRgIHJlcXVlc3QgdG8gZXhlY3V0ZSBvbiB0aGUgc2VydmVyLiBUaGUgYFBVVGAgbWV0aG9kIHJlcGxhY2VzIGFuIGV4aXN0aW5nIHJlc291cmNlXG4gICAqIHdpdGggYSBuZXcgc2V0IG9mIHZhbHVlcy5cbiAgICogU2VlIHRoZSBpbmRpdmlkdWFsIG92ZXJsb2FkcyBmb3IgZGV0YWlscyBvbiB0aGUgcmV0dXJuIHR5cGUuXG4gICAqL1xuICBwdXQodXJsLCBib2R5LCBvcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KCdQVVQnLCB1cmwsIGFkZEJvZHkob3B0aW9ucywgYm9keSkpO1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtWZhYyA9IGZ1bmN0aW9uIEh0dHBDbGllbnRfRmFjdG9yeSh0KSB7XG4gICAgICByZXR1cm4gbmV3ICh0IHx8IEh0dHBDbGllbnQpKGkwLsm1ybVpbmplY3QoSHR0cEhhbmRsZXIpKTtcbiAgICB9O1xuICB9XG4gIHN0YXRpYyB7XG4gICAgdGhpcy7JtXByb3YgPSAvKiBAX19QVVJFX18gKi9pMC7Jtcm1ZGVmaW5lSW5qZWN0YWJsZSh7XG4gICAgICB0b2tlbjogSHR0cENsaWVudCxcbiAgICAgIGZhY3Rvcnk6IEh0dHBDbGllbnQuybVmYWNcbiAgICB9KTtcbiAgfVxufVxuKCgpID0+IHtcbiAgKHR5cGVvZiBuZ0Rldk1vZGUgPT09IFwidW5kZWZpbmVkXCIgfHwgbmdEZXZNb2RlKSAmJiBpMC7JtXNldENsYXNzTWV0YWRhdGEoSHR0cENsaWVudCwgW3tcbiAgICB0eXBlOiBJbmplY3RhYmxlXG4gIH1dLCAoKSA9PiBbe1xuICAgIHR5cGU6IEh0dHBIYW5kbGVyXG4gIH1dLCBudWxsKTtcbn0pKCk7XG5jb25zdCBYU1NJX1BSRUZJWCQxID0gL15cXClcXF1cXH0nLD9cXG4vO1xuY29uc3QgUkVRVUVTVF9VUkxfSEVBREVSID0gYFgtUmVxdWVzdC1VUkxgO1xuLyoqXG4gKiBEZXRlcm1pbmUgYW4gYXBwcm9wcmlhdGUgVVJMIGZvciB0aGUgcmVzcG9uc2UsIGJ5IGNoZWNraW5nIGVpdGhlclxuICogcmVzcG9uc2UgdXJsIG9yIHRoZSBYLVJlcXVlc3QtVVJMIGhlYWRlci5cbiAqL1xuZnVuY3Rpb24gZ2V0UmVzcG9uc2VVcmwkMShyZXNwb25zZSkge1xuICBpZiAocmVzcG9uc2UudXJsKSB7XG4gICAgcmV0dXJuIHJlc3BvbnNlLnVybDtcbiAgfVxuICAvLyBzdG9yZWQgYXMgbG93ZXJjYXNlIGluIHRoZSBtYXBcbiAgY29uc3QgeFJlcXVlc3RVcmwgPSBSRVFVRVNUX1VSTF9IRUFERVIudG9Mb2NhbGVMb3dlckNhc2UoKTtcbiAgcmV0dXJuIHJlc3BvbnNlLmhlYWRlcnMuZ2V0KHhSZXF1ZXN0VXJsKTtcbn1cbi8qKlxuICogVXNlcyBgZmV0Y2hgIHRvIHNlbmQgcmVxdWVzdHMgdG8gYSBiYWNrZW5kIHNlcnZlci5cbiAqXG4gKiBUaGlzIGBGZXRjaEJhY2tlbmRgIHJlcXVpcmVzIHRoZSBzdXBwb3J0IG9mIHRoZVxuICogW0ZldGNoIEFQSV0oaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0ZldGNoX0FQSSkgd2hpY2ggaXMgYXZhaWxhYmxlIG9uIGFsbFxuICogc3VwcG9ydGVkIGJyb3dzZXJzIGFuZCBvbiBOb2RlLmpzIHYxOCBvciBsYXRlci5cbiAqXG4gKiBAc2VlIHtAbGluayBIdHRwSGFuZGxlcn1cbiAqXG4gKiBAcHVibGljQXBpXG4gKi9cbmNsYXNzIEZldGNoQmFja2VuZCB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIC8vIFdlIG5lZWQgdG8gYmluZCB0aGUgbmF0aXZlIGZldGNoIHRvIGl0cyBjb250ZXh0IG9yIGl0IHdpbGwgdGhyb3cgYW4gXCJpbGxlZ2FsIGludm9jYXRpb25cIlxuICAgIHRoaXMuZmV0Y2hJbXBsID0gaW5qZWN0KEZldGNoRmFjdG9yeSwge1xuICAgICAgb3B0aW9uYWw6IHRydWVcbiAgICB9KT8uZmV0Y2ggPz8gZmV0Y2guYmluZChnbG9iYWxUaGlzKTtcbiAgICB0aGlzLm5nWm9uZSA9IGluamVjdChOZ1pvbmUpO1xuICB9XG4gIGhhbmRsZShyZXF1ZXN0KSB7XG4gICAgcmV0dXJuIG5ldyBPYnNlcnZhYmxlKG9ic2VydmVyID0+IHtcbiAgICAgIGNvbnN0IGFib3J0ZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICB0aGlzLmRvUmVxdWVzdChyZXF1ZXN0LCBhYm9ydGVyLnNpZ25hbCwgb2JzZXJ2ZXIpLnRoZW4obm9vcCwgZXJyb3IgPT4gb2JzZXJ2ZXIuZXJyb3IobmV3IEh0dHBFcnJvclJlc3BvbnNlKHtcbiAgICAgICAgZXJyb3JcbiAgICAgIH0pKSk7XG4gICAgICByZXR1cm4gKCkgPT4gYWJvcnRlci5hYm9ydCgpO1xuICAgIH0pO1xuICB9XG4gIGFzeW5jIGRvUmVxdWVzdChyZXF1ZXN0LCBzaWduYWwsIG9ic2VydmVyKSB7XG4gICAgY29uc3QgaW5pdCA9IHRoaXMuY3JlYXRlUmVxdWVzdEluaXQocmVxdWVzdCk7XG4gICAgbGV0IHJlc3BvbnNlO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBmZXRjaFByb21pc2UgPSB0aGlzLmZldGNoSW1wbChyZXF1ZXN0LnVybFdpdGhQYXJhbXMsIHtcbiAgICAgICAgc2lnbmFsLFxuICAgICAgICAuLi5pbml0XG4gICAgICB9KTtcbiAgICAgIC8vIE1ha2Ugc3VyZSBab25lLmpzIGRvZXNuJ3QgdHJpZ2dlciBmYWxzZS1wb3NpdGl2ZSB1bmhhbmRsZWQgcHJvbWlzZVxuICAgICAgLy8gZXJyb3IgaW4gY2FzZSB0aGUgUHJvbWlzZSBpcyByZWplY3RlZCBzeW5jaHJvbm91c2x5LiBTZWUgZnVuY3Rpb25cbiAgICAgIC8vIGRlc2NyaXB0aW9uIGZvciBhZGRpdGlvbmFsIGluZm9ybWF0aW9uLlxuICAgICAgc2lsZW5jZVN1cGVyZmx1b3VzVW5oYW5kbGVkUHJvbWlzZVJlamVjdGlvbihmZXRjaFByb21pc2UpO1xuICAgICAgLy8gU2VuZCB0aGUgYFNlbnRgIGV2ZW50IGJlZm9yZSBhd2FpdGluZyB0aGUgcmVzcG9uc2UuXG4gICAgICBvYnNlcnZlci5uZXh0KHtcbiAgICAgICAgdHlwZTogSHR0cEV2ZW50VHlwZS5TZW50XG4gICAgICB9KTtcbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgZmV0Y2hQcm9taXNlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBvYnNlcnZlci5lcnJvcihuZXcgSHR0cEVycm9yUmVzcG9uc2Uoe1xuICAgICAgICBlcnJvcixcbiAgICAgICAgc3RhdHVzOiBlcnJvci5zdGF0dXMgPz8gMCxcbiAgICAgICAgc3RhdHVzVGV4dDogZXJyb3Iuc3RhdHVzVGV4dCxcbiAgICAgICAgdXJsOiByZXF1ZXN0LnVybFdpdGhQYXJhbXMsXG4gICAgICAgIGhlYWRlcnM6IGVycm9yLmhlYWRlcnNcbiAgICAgIH0pKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaGVhZGVycyA9IG5ldyBIdHRwSGVhZGVycyhyZXNwb25zZS5oZWFkZXJzKTtcbiAgICBjb25zdCBzdGF0dXNUZXh0ID0gcmVzcG9uc2Uuc3RhdHVzVGV4dDtcbiAgICBjb25zdCB1cmwgPSBnZXRSZXNwb25zZVVybCQxKHJlc3BvbnNlKSA/PyByZXF1ZXN0LnVybFdpdGhQYXJhbXM7XG4gICAgbGV0IHN0YXR1cyA9IHJlc3BvbnNlLnN0YXR1cztcbiAgICBsZXQgYm9keSA9IG51bGw7XG4gICAgaWYgKHJlcXVlc3QucmVwb3J0UHJvZ3Jlc3MpIHtcbiAgICAgIG9ic2VydmVyLm5leHQobmV3IEh0dHBIZWFkZXJSZXNwb25zZSh7XG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIHN0YXR1cyxcbiAgICAgICAgc3RhdHVzVGV4dCxcbiAgICAgICAgdXJsXG4gICAgICB9KSk7XG4gICAgfVxuICAgIGlmIChyZXNwb25zZS5ib2R5KSB7XG4gICAgICAvLyBSZWFkIFByb2dyZXNzXG4gICAgICBjb25zdCBjb250ZW50TGVuZ3RoID0gcmVzcG9uc2UuaGVhZGVycy5nZXQoJ2NvbnRlbnQtbGVuZ3RoJyk7XG4gICAgICBjb25zdCBjaHVua3MgPSBbXTtcbiAgICAgIGNvbnN0IHJlYWRlciA9IHJlc3BvbnNlLmJvZHkuZ2V0UmVhZGVyKCk7XG4gICAgICBsZXQgcmVjZWl2ZWRMZW5ndGggPSAwO1xuICAgICAgbGV0IGRlY29kZXI7XG4gICAgICBsZXQgcGFydGlhbFRleHQ7XG4gICAgICAvLyBXZSBoYXZlIHRvIGNoZWNrIHdoZXRoZXIgdGhlIFpvbmUgaXMgZGVmaW5lZCBpbiB0aGUgZ2xvYmFsIHNjb3BlIGJlY2F1c2UgdGhpcyBtYXkgYmUgY2FsbGVkXG4gICAgICAvLyB3aGVuIHRoZSB6b25lIGlzIG5vb3BlZC5cbiAgICAgIGNvbnN0IHJlcVpvbmUgPSB0eXBlb2YgWm9uZSAhPT0gJ3VuZGVmaW5lZCcgJiYgWm9uZS5jdXJyZW50O1xuICAgICAgLy8gUGVyZm9ybSByZXNwb25zZSBwcm9jZXNzaW5nIG91dHNpZGUgb2YgQW5ndWxhciB6b25lIHRvXG4gICAgICAvLyBlbnN1cmUgbm8gZXhjZXNzaXZlIGNoYW5nZSBkZXRlY3Rpb24gcnVucyBhcmUgZXhlY3V0ZWRcbiAgICAgIC8vIEhlcmUgY2FsbGluZyB0aGUgYXN5bmMgUmVhZGFibGVTdHJlYW1EZWZhdWx0UmVhZGVyLnJlYWQoKSBpcyByZXNwb25zaWJsZSBmb3IgdHJpZ2dlcmluZyBDRFxuICAgICAgYXdhaXQgdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoYXN5bmMgKCkgPT4ge1xuICAgICAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgICAgIGNvbnN0IHtcbiAgICAgICAgICAgIGRvbmUsXG4gICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuICAgICAgICAgIGlmIChkb25lKSB7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgY2h1bmtzLnB1c2godmFsdWUpO1xuICAgICAgICAgIHJlY2VpdmVkTGVuZ3RoICs9IHZhbHVlLmxlbmd0aDtcbiAgICAgICAgICBpZiAocmVxdWVzdC5yZXBvcnRQcm9ncmVzcykge1xuICAgICAgICAgICAgcGFydGlhbFRleHQgPSByZXF1ZXN0LnJlc3BvbnNlVHlwZSA9PT0gJ3RleHQnID8gKHBhcnRpYWxUZXh0ID8/ICcnKSArIChkZWNvZGVyID8/PSBuZXcgVGV4dERlY29kZXIoKSkuZGVjb2RlKHZhbHVlLCB7XG4gICAgICAgICAgICAgIHN0cmVhbTogdHJ1ZVxuICAgICAgICAgICAgfSkgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICBjb25zdCByZXBvcnRQcm9ncmVzcyA9ICgpID0+IG9ic2VydmVyLm5leHQoe1xuICAgICAgICAgICAgICB0eXBlOiBIdHRwRXZlbnRUeXBlLkRvd25sb2FkUHJvZ3Jlc3MsXG4gICAgICAgICAgICAgIHRvdGFsOiBjb250ZW50TGVuZ3RoID8gK2NvbnRlbnRMZW5ndGggOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIGxvYWRlZDogcmVjZWl2ZWRMZW5ndGgsXG4gICAgICAgICAgICAgIHBhcnRpYWxUZXh0XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHJlcVpvbmUgPyByZXFab25lLnJ1bihyZXBvcnRQcm9ncmVzcykgOiByZXBvcnRQcm9ncmVzcygpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxu |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment