Market Smart Contract
{"id":"ssc-mainnet1","json":{"contractName":"contract","contractAction":"update","contractPayload":{"name":"market","params":"","code":"LyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqLw0KLyogZ2xvYmFsIGFjdGlvbnMsIGFwaSAqLw0KY29uc3QgU1RFRU1fUEVHR0VEX1NZTUJPTCA9ICdTVEVFTVAnOw0KY29uc3QgU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04gPSA4Ow0KY29uc3QgQ09OVFJBQ1RfTkFNRSA9ICdtYXJrZXQnOw0KDQpjb25zdCBnZXRNZXRyaWMgPSBhc3luYyAoc3ltYm9sKSA9PiB7DQogIGxldCBtZXRyaWMgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnbWV0cmljcycsIHsgc3ltYm9sIH0pOw0KDQogIGlmIChtZXRyaWMgPT09IG51bGwpIHsNCiAgICBtZXRyaWMgPSB7fTsNCiAgICBtZXRyaWMuc3ltYm9sID0gc3ltYm9sOw0KICAgIG1ldHJpYy52b2x1bWUgPSAnMCc7DQogICAgbWV0cmljLnZvbHVtZUV4cGlyYXRpb24gPSAwOw0KICAgIG1ldHJpYy5sYXN0UHJpY2UgPSAnMCc7DQogICAgbWV0cmljLmxvd2VzdEFzayA9ICcwJzsNCiAgICBtZXRyaWMuaGlnaGVzdEJpZCA9ICcwJzsNCiAgICBtZXRyaWMubGFzdERheVByaWNlID0gJzAnOw0KICAgIG1ldHJpYy5sYXN0RGF5UHJpY2VFeHBpcmF0aW9uID0gMDsNCiAgICBtZXRyaWMucHJpY2VDaGFuZ2VTdGVlbSA9ICcwJzsNCiAgICBtZXRyaWMucHJpY2VDaGFuZ2VQZXJjZW50ID0gJzAnOw0KDQogICAgY29uc3QgbmV3TWV0cmljID0gYXdhaXQgYXBpLmRiLmluc2VydCgnbWV0cmljcycsIG1ldHJpYyk7DQogICAgcmV0dXJuIG5ld01ldHJpYzsNCiAgfQ0KDQogIHJldHVybiBtZXRyaWM7DQp9Ow0KDQpjb25zdCB1cGRhdGVWb2x1bWVNZXRyaWMgPSBhc3luYyAoc3ltYm9sLCBxdWFudGl0eSwgYWRkID0gdHJ1ZSkgPT4gew0KICBjb25zdCBibG9ja0RhdGUgPSBuZXcgRGF0ZShgJHthcGkuc3RlZW1CbG9ja1RpbWVzdGFtcH0uMDAwWmApOw0KICBjb25zdCB0aW1lc3RhbXBTZWMgPSBibG9ja0RhdGUuZ2V0VGltZSgpIC8gMTAwMDsNCiAgY29uc3QgbWV0cmljID0gYXdhaXQgZ2V0TWV0cmljKHN5bWJvbCk7DQoNCiAgaWYgKGFkZCA9PT0gdHJ1ZSkgew0KICAgIGlmIChtZXRyaWMudm9sdW1lRXhwaXJhdGlvbiA8IHRpbWVzdGFtcFNlYykgew0KICAgICAgbWV0cmljLnZvbHVtZSA9ICcwLjAwMCc7DQogICAgfQ0KICAgIG1ldHJpYy52b2x1bWUgPSBhcGkuQmlnTnVtYmVyKG1ldHJpYy52b2x1bWUpDQogICAgICAucGx1cyhxdWFudGl0eSkNCiAgICAgIC50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OKTsNCiAgICBtZXRyaWMudm9sdW1lRXhwaXJhdGlvbiA9IGJsb2NrRGF0ZS5zZXREYXRlKGJsb2NrRGF0ZS5nZXREYXRlKCkgKyAxKSAvIDEwMDA7DQogIH0gZWxzZSB7DQogICAgbWV0cmljLnZvbHVtZSA9IGFwaS5CaWdOdW1iZXIobWV0cmljLnZvbHVtZSkNCiAgICAgIC5taW51cyhxdWFudGl0eSkNCiAgICAgIC50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OKTsNCiAgfQ0KDQogIGlmIChhcGkuQmlnTnVtYmVyKG1ldHJpYy52b2x1bWUpLmx0KDApKSB7DQogICAgbWV0cmljLnZvbHVtZSA9ICcwLjAwMCc7DQogIH0NCg0KICBhd2FpdCBhcGkuZGIudXBkYXRlKCdtZXRyaWNzJywgbWV0cmljKTsNCn07DQoNCmNvbnN0IHVwZGF0ZVByaWNlTWV0cmljcyA9IGFzeW5jIChzeW1ib2wsIHByaWNlKSA9PiB7DQogIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7DQogIGNvbnN0IHRpbWVzdGFtcFNlYyA9IGJsb2NrRGF0ZS5nZXRUaW1lKCkgLyAxMDAwOw0KDQogIGNvbnN0IG1ldHJpYyA9IGF3YWl0IGdldE1ldHJpYyhzeW1ib2wpOw0KDQogIG1ldHJpYy5sYXN0UHJpY2UgPSBwcmljZTsNCg0KICBpZiAobWV0cmljLmxhc3REYXlQcmljZUV4cGlyYXRpb24gPCB0aW1lc3RhbXBTZWMpIHsNCiAgICBtZXRyaWMubGFzdERheVByaWNlID0gcHJpY2U7DQogICAgbWV0cmljLmxhc3REYXlQcmljZUV4cGlyYXRpb24gPSBibG9ja0RhdGUuc2V0RGF0ZShibG9ja0RhdGUuZ2V0RGF0ZSgpICsgMSkgLyAxMDAwOw0KICAgIG1ldHJpYy5wcmljZUNoYW5nZVN0ZWVtID0gJzAnOw0KICAgIG1ldHJpYy5wcmljZUNoYW5nZVBlcmNlbnQgPSAnMCUnOw0KICB9IGVsc2Ugew0KICAgIG1ldHJpYy5wcmljZUNoYW5nZVN0ZWVtID0gYXBpLkJpZ051bWJlcihwcmljZSkNCiAgICAgIC5taW51cyhtZXRyaWMubGFzdERheVByaWNlKQ0KICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KICAgIG1ldHJpYy5wcmljZUNoYW5nZVBlcmNlbnQgPSBgJHthcGkuQmlnTnVtYmVyKG1ldHJpYy5wcmljZUNoYW5nZVN0ZWVtKS5kaXZpZGVkQnkobWV0cmljLmxhc3REYXlQcmljZSkubXVsdGlwbGllZEJ5KDEwMCkudG9GaXhlZCgyKX0lYDsNCiAgfQ0KDQogIGF3YWl0IGFwaS5kYi51cGRhdGUoJ21ldHJpY3MnLCBtZXRyaWMpOw0KfTsNCg0KY29uc3QgdXBkYXRlQmlkTWV0cmljID0gYXN5bmMgKHN5bWJvbCkgPT4gew0KICBjb25zdCBtZXRyaWMgPSBhd2FpdCBnZXRNZXRyaWMoc3ltYm9sKTsNCg0KICBjb25zdCBidXlPcmRlckJvb2sgPSBhd2FpdCBhcGkuZGIuZmluZCgnYnV5Qm9vaycsDQogICAgew0KICAgICAgc3ltYm9sLA0KICAgIH0sIDEsIDAsDQogICAgWw0KICAgICAgeyBpbmRleDogJ3ByaWNlRGVjJywgZGVzY2VuZGluZzogdHJ1ZSB9LA0KICAgIF0pOw0KDQoNCiAgaWYgKGJ1eU9yZGVyQm9vay5sZW5ndGggPiAwKSB7DQogICAgbWV0cmljLmhpZ2hlc3RCaWQgPSBidXlPcmRlckJvb2tbMF0ucHJpY2U7DQogIH0gZWxzZSB7DQogICAgbWV0cmljLmhpZ2hlc3RCaWQgPSAnMCc7DQogIH0NCg0KICBhd2FpdCBhcGkuZGIudXBkYXRlKCdtZXRyaWNzJywgbWV0cmljKTsNCn07DQoNCmNvbnN0IHVwZGF0ZUFza01ldHJpYyA9IGFzeW5jIChzeW1ib2wpID0+IHsNCiAgY29uc3QgbWV0cmljID0gYXdhaXQgZ2V0TWV0cmljKHN5bWJvbCk7DQoNCiAgY29uc3Qgc2VsbE9yZGVyQm9vayA9IGF3YWl0IGFwaS5kYi5maW5kKCdzZWxsQm9vaycsDQogICAgew0KICAgICAgc3ltYm9sLA0KICAgIH0sIDEsIDAsDQogICAgWw0KICAgICAgeyBpbmRleDogJ3ByaWNlRGVjJywgZGVzY2VuZGluZzogZmFsc2UgfSwNCiAgICBdKTsNCg0KICBpZiAoc2VsbE9yZGVyQm9vay5sZW5ndGggPiAwKSB7DQogICAgbWV0cmljLmxvd2VzdEFzayA9IHNlbGxPcmRlckJvb2tbMF0ucHJpY2U7DQogIH0gZWxzZSB7DQogICAgbWV0cmljLmxvd2VzdEFzayA9ICcwJzsNCiAgfQ0KDQogIGF3YWl0IGFwaS5kYi51cGRhdGUoJ21ldHJpY3MnLCBtZXRyaWMpOw0KfTsNCg0KY29uc3QgdXBkYXRlVHJhZGVzSGlzdG9yeSA9IGFzeW5jICh0eXBlLCBidXllciwgc2VsbGVyLCBzeW1ib2wsIHF1YW50aXR5LCBwcmljZSwgdm9sdW1lKSA9PiB7DQogIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5zdGVlbUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7DQogIGNvbnN0IHRpbWVzdGFtcFNlYyA9IGJsb2NrRGF0ZS5nZXRUaW1lKCkgLyAxMDAwOw0KICBjb25zdCB0aW1lc3RhbXBNaW51czI0aHJzID0gYmxvY2tEYXRlLnNldERhdGUoYmxvY2tEYXRlLmdldERhdGUoKSAtIDEpIC8gMTAwMDsNCiAgLy8gY2xlYW4gaGlzdG9yeQ0KDQogIGxldCB0cmFkZXNUb0RlbGV0ZSA9IGF3YWl0IGFwaS5kYi5maW5kKA0KICAgICd0cmFkZXNIaXN0b3J5JywNCiAgICB7DQogICAgICBzeW1ib2wsDQogICAgICB0aW1lc3RhbXA6IHsNCiAgICAgICAgJGx0OiB0aW1lc3RhbXBNaW51czI0aHJzLA0KICAgICAgfSwNCiAgICB9LA0KICApOw0KICBsZXQgbmJUcmFkZXNUb0RlbGV0ZSA9IHRyYWRlc1RvRGVsZXRlLmxlbmd0aDsNCg0KICB3aGlsZSAobmJUcmFkZXNUb0RlbGV0ZSA+IDApIHsNCiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgbmJUcmFkZXNUb0RlbGV0ZTsgaW5kZXggKz0gMSkgew0KICAgICAgY29uc3QgdHJhZGUgPSB0cmFkZXNUb0RlbGV0ZVtpbmRleF07DQogICAgICBhd2FpdCB1cGRhdGVWb2x1bWVNZXRyaWModHJhZGUuc3ltYm9sLCB0cmFkZS52b2x1bWUsIGZhbHNlKTsNCiAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ3RyYWRlc0hpc3RvcnknLCB0cmFkZSk7DQogICAgfQ0KICAgIHRyYWRlc1RvRGVsZXRlID0gYXdhaXQgYXBpLmRiLmZpbmQoDQogICAgICAndHJhZGVzSGlzdG9yeScsDQogICAgICB7DQogICAgICAgIHN5bWJvbCwNCiAgICAgICAgdGltZXN0YW1wOiB7DQogICAgICAgICAgJGx0OiB0aW1lc3RhbXBNaW51czI0aHJzLA0KICAgICAgICB9LA0KICAgICAgfSwNCiAgICApOw0KICAgIG5iVHJhZGVzVG9EZWxldGUgPSB0cmFkZXNUb0RlbGV0ZS5sZW5ndGg7DQogIH0NCiAgLy8gYWRkIG9yZGVyIHRvIHRoZSBoaXN0b3J5DQogIGNvbnN0IG5ld1RyYWRlID0ge307DQogIG5ld1RyYWRlLnR5cGUgPSB0eXBlOw0KICBuZXdUcmFkZS5idXllciA9IGJ1eWVyOw0KICBuZXdUcmFkZS5zZWxsZXIgPSBzZWxsZXI7DQogIG5ld1RyYWRlLnN5bWJvbCA9IHN5bWJvbDsNCiAgbmV3VHJhZGUucXVhbnRpdHkgPSBxdWFudGl0eTsNCiAgbmV3VHJhZGUucHJpY2UgPSBwcmljZTsNCiAgbmV3VHJhZGUudGltZXN0YW1wID0gdGltZXN0YW1wU2VjOw0KICBuZXdUcmFkZS52b2x1bWUgPSB2b2x1bWU7DQogIGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3RyYWRlc0hpc3RvcnknLCBuZXdUcmFkZSk7DQogIGF3YWl0IHVwZGF0ZVByaWNlTWV0cmljcyhzeW1ib2wsIHByaWNlKTsNCn07DQoNCmNvbnN0IGNvdW50RGVjaW1hbHMgPSB2YWx1ZSA9PiBhcGkuQmlnTnVtYmVyKHZhbHVlKS5kcCgpOw0KDQpjb25zdCByZW1vdmVFeHBpcmVkT3JkZXJzID0gYXN5bmMgKHRhYmxlKSA9PiB7DQogIGNvbnN0IHRpbWVzdGFtcFNlYyA9IGFwaS5CaWdOdW1iZXIobmV3IERhdGUoYCR7YXBpLnN0ZWVtQmxvY2tUaW1lc3RhbXB9LjAwMFpgKS5nZXRUaW1lKCkpDQogICAgLmRpdmlkZWRCeSgxMDAwKQ0KICAgIC50b051bWJlcigpOw0KDQogIC8vIGNsZWFuIG9yZGVycw0KICBsZXQgbmJPcmRlcnNUb0RlbGV0ZSA9IDA7DQogIGxldCBvcmRlcnNUb0RlbGV0ZSA9IGF3YWl0IGFwaS5kYi5maW5kKA0KICAgIHRhYmxlLA0KICAgIHsNCiAgICAgIGV4cGlyYXRpb246IHsNCiAgICAgICAgJGx0ZTogdGltZXN0YW1wU2VjLA0KICAgICAgfSwNCiAgICB9LA0KICApOw0KDQogIG5iT3JkZXJzVG9EZWxldGUgPSBvcmRlcnNUb0RlbGV0ZS5sZW5ndGg7DQogIHdoaWxlIChuYk9yZGVyc1RvRGVsZXRlID4gMCkgew0KICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBuYk9yZGVyc1RvRGVsZXRlOyBpbmRleCArPSAxKSB7DQogICAgICBjb25zdCBvcmRlciA9IG9yZGVyc1RvRGVsZXRlW2luZGV4XTsNCiAgICAgIGxldCBxdWFudGl0eTsNCiAgICAgIGxldCBzeW1ib2w7DQoNCiAgICAgIGlmICh0YWJsZSA9PT0gJ2J1eUJvb2snKSB7DQogICAgICAgIHN5bWJvbCA9IFNURUVNX1BFR0dFRF9TWU1CT0w7DQogICAgICAgIHF1YW50aXR5ID0gb3JkZXIudG9rZW5zTG9ja2VkOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1kZXN0cnVjdHVyaW5nDQogICAgICAgIHN5bWJvbCA9IG9yZGVyLnN5bWJvbDsNCiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1kZXN0cnVjdHVyaW5nDQogICAgICAgIHF1YW50aXR5ID0gb3JkZXIucXVhbnRpdHk7DQogICAgICB9DQoNCiAgICAgIC8vIHVubG9jayB0b2tlbnMNCiAgICAgIGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhvcmRlci5hY2NvdW50LCBzeW1ib2wsIHF1YW50aXR5LCAndXNlcicpOw0KDQogICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKHRhYmxlLCBvcmRlcik7DQoNCiAgICAgIGlmICh0YWJsZSA9PT0gJ2J1eUJvb2snKSB7DQogICAgICAgIGF3YWl0IHVwZGF0ZUFza01ldHJpYyhvcmRlci5zeW1ib2wpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgYXdhaXQgdXBkYXRlQmlkTWV0cmljKG9yZGVyLnN5bWJvbCk7DQogICAgICB9DQogICAgfQ0KDQogICAgb3JkZXJzVG9EZWxldGUgPSBhd2FpdCBhcGkuZGIuZmluZCgNCiAgICAgIHRhYmxlLA0KICAgICAgew0KICAgICAgICBleHBpcmF0aW9uOiB7DQogICAgICAgICAgJGx0ZTogdGltZXN0YW1wU2VjLA0KICAgICAgICB9LA0KICAgICAgfSwNCiAgICApOw0KDQogICAgbmJPcmRlcnNUb0RlbGV0ZSA9IG9yZGVyc1RvRGVsZXRlLmxlbmd0aDsNCiAgfQ0KfTsNCg0KYWN0aW9ucy5jcmVhdGVTU0MgPSBhc3luYyAoKSA9PiB7DQogIGNvbnN0IHRhYmxlRXhpc3RzID0gYXdhaXQgYXBpLmRiLnRhYmxlRXhpc3RzKCdidXlCb29rJyk7DQoNCiAgaWYgKHRhYmxlRXhpc3RzID09PSBmYWxzZSkgew0KICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgnYnV5Qm9vaycsIFsnc3ltYm9sJywgJ2FjY291bnQnLCAncHJpY2VEZWMnLCAnZXhwaXJhdGlvbicsICd0eElkJ10pOw0KICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgnc2VsbEJvb2snLCBbJ3N5bWJvbCcsICdhY2NvdW50JywgJ3ByaWNlRGVjJywgJ2V4cGlyYXRpb24nLCAndHhJZCddKTsNCiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ3RyYWRlc0hpc3RvcnknLCBbJ3N5bWJvbCddKTsNCiAgICBhd2FpdCBhcGkuZGIuY3JlYXRlVGFibGUoJ21ldHJpY3MnLCBbJ3N5bWJvbCddKTsNCiAgfQ0KfTsNCg0KYWN0aW9ucy5jYW5jZWwgPSBhc3luYyAocGF5bG9hZCkgPT4gew0KICBjb25zdCB7IHR5cGUsIGlkLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXkgfSA9IHBheWxvYWQ7DQoNCiAgY29uc3QgdHlwZXMgPSBbJ2J1eScsICdzZWxsJ107DQoNCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykNCiAgICAmJiBhcGkuYXNzZXJ0KHR5cGUgJiYgdHlwZXMuaW5jbHVkZXModHlwZSkNCiAgICAgICYmIGlkLCAnaW52YWxpZCBwYXJhbXMnKSkgew0KICAgIGNvbnN0IHRhYmxlID0gdHlwZSA9PT0gJ2J1eScgPyAnYnV5Qm9vaycgOiAnc2VsbEJvb2snOw0KDQogICAgbGV0IG9yZGVyID0gbnVsbDsNCiAgICAvLyBnZXQgb3JkZXINCiAgICBpZiAodHlwZW9mIGlkID09PSAnc3RyaW5nJyAmJiBpZC5sZW5ndGggPCA1MCkgew0KICAgICAgb3JkZXIgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSh0YWJsZSwgeyB0eElkOiBpZCB9KTsNCiAgICB9DQoNCiAgICBpZiAoYXBpLmFzc2VydChvcmRlciAhPT0gbnVsbCwgJ29yZGVyIGRvZXMgbm90IGV4aXN0IG9yIGludmFsaWQgcGFyYW1zJykNCiAgICAgICYmIG9yZGVyLmFjY291bnQgPT09IGFwaS5zZW5kZXIpIHsNCiAgICAgIGxldCBxdWFudGl0eTsNCiAgICAgIGxldCBzeW1ib2w7DQoNCiAgICAgIGlmICh0eXBlID09PSAnYnV5Jykgew0KICAgICAgICBzeW1ib2wgPSBTVEVFTV9QRUdHRURfU1lNQk9MOw0KICAgICAgICBxdWFudGl0eSA9IG9yZGVyLnRva2Vuc0xvY2tlZDsNCiAgICAgIH0gZWxzZSB7DQogICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItZGVzdHJ1Y3R1cmluZw0KICAgICAgICBzeW1ib2wgPSBvcmRlci5zeW1ib2w7DQogICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBwcmVmZXItZGVzdHJ1Y3R1cmluZw0KICAgICAgICBxdWFudGl0eSA9IG9yZGVyLnF1YW50aXR5Ow0KICAgICAgfQ0KDQogICAgICAvLyB1bmxvY2sgdG9rZW5zDQogICAgICBhd2FpdCBhcGkudHJhbnNmZXJUb2tlbnMoYXBpLnNlbmRlciwgc3ltYm9sLCBxdWFudGl0eSwgJ3VzZXInKTsNCg0KICAgICAgYXdhaXQgYXBpLmRiLnJlbW92ZSh0YWJsZSwgb3JkZXIpOw0KDQogICAgICBpZiAodHlwZSA9PT0gJ3NlbGwnKSB7DQogICAgICAgIGF3YWl0IHVwZGF0ZUFza01ldHJpYyhvcmRlci5zeW1ib2wpOw0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgYXdhaXQgdXBkYXRlQmlkTWV0cmljKG9yZGVyLnN5bWJvbCk7DQogICAgICB9DQogICAgfQ0KICB9DQp9Ow0KDQpjb25zdCBmaW5kTWF0Y2hpbmdTZWxsT3JkZXJzID0gYXN5bmMgKG9yZGVyLCB0b2tlblByZWNpc2lvbikgPT4gew0KICBjb25zdCB7DQogICAgYWNjb3VudCwNCiAgICBzeW1ib2wsDQogICAgcHJpY2VEZWMsDQogIH0gPSBvcmRlcjsNCg0KICBjb25zdCBidXlPcmRlciA9IG9yZGVyOw0KICBsZXQgb2Zmc2V0ID0gMDsNCiAgbGV0IHZvbHVtZVRyYWRlZCA9IDA7DQoNCiAgYXdhaXQgcmVtb3ZlRXhwaXJlZE9yZGVycygnc2VsbEJvb2snKTsNCg0KICAvLyBnZXQgdGhlIG9yZGVycyB0aGF0IG1hdGNoIHRoZSBzeW1ib2wgYW5kIHRoZSBwcmljZQ0KICBsZXQgc2VsbE9yZGVyQm9vayA9IGF3YWl0IGFwaS5kYi5maW5kKCdzZWxsQm9vaycsIHsNCiAgICBzeW1ib2wsDQogICAgcHJpY2VEZWM6IHsNCiAgICAgICRsdGU6IHByaWNlRGVjLA0KICAgIH0sDQogIH0sIDEwMDAsIG9mZnNldCwNCiAgWw0KICAgIHsgaW5kZXg6ICdwcmljZURlYycsIGRlc2NlbmRpbmc6IGZhbHNlIH0sDQogICAgeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH0sDQogIF0pOw0KDQogIGRvIHsNCiAgICBjb25zdCBuYk9yZGVycyA9IHNlbGxPcmRlckJvb2subGVuZ3RoOw0KICAgIGxldCBpbmMgPSAwOw0KDQogICAgd2hpbGUgKGluYyA8IG5iT3JkZXJzICYmIGFwaS5CaWdOdW1iZXIoYnV5T3JkZXIucXVhbnRpdHkpLmd0KDApKSB7DQogICAgICBjb25zdCBzZWxsT3JkZXIgPSBzZWxsT3JkZXJCb29rW2luY107DQogICAgICBpZiAoYXBpLkJpZ051bWJlcihidXlPcmRlci5xdWFudGl0eSkubHRlKHNlbGxPcmRlci5xdWFudGl0eSkpIHsNCiAgICAgICAgbGV0IHF0eVRva2Vuc1RvU2VuZCA9IGFwaS5CaWdOdW1iZXIoc2VsbE9yZGVyLnByaWNlKQ0KICAgICAgICAgIC5tdWx0aXBsaWVkQnkoYnV5T3JkZXIucXVhbnRpdHkpDQogICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KDQogICAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHF0eVRva2Vuc1RvU2VuZCkuZ3QoYnV5T3JkZXIudG9rZW5zTG9ja2VkKSkgew0KICAgICAgICAgIHF0eVRva2Vuc1RvU2VuZCA9IGFwaS5CaWdOdW1iZXIoc2VsbE9yZGVyLnByaWNlKQ0KICAgICAgICAgICAgLm11bHRpcGxpZWRCeShidXlPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAgIC50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdHlUb2tlbnNUb1NlbmQpLmd0KDApDQogICAgICAgICAgJiYgYXBpLkJpZ051bWJlcihidXlPcmRlci5xdWFudGl0eSkuZ3QoMCksICd0aGUgb3JkZXIgY2Fubm90IGJlIGZpbGxlZCcpKSB7DQogICAgICAgICAgLy8gdHJhbnNmZXIgdGhlIHRva2VucyB0byB0aGUgYnV5ZXINCiAgICAgICAgICBsZXQgcmVzID0gYXdhaXQgYXBpLnRyYW5zZmVyVG9rZW5zKGFjY291bnQsIHN5bWJvbCwgYnV5T3JkZXIucXVhbnRpdHksICd1c2VyJyk7DQoNCiAgICAgICAgICBpZiAocmVzLmVycm9ycykgew0KICAgICAgICAgICAgYXBpLmRlYnVnKHJlcy5lcnJvcnMpOw0KICAgICAgICAgICAgYXBpLmRlYnVnKGBUWElEOiAke2FwaS50cmFuc2FjdGlvbklkfWApOw0KICAgICAgICAgICAgYXBpLmRlYnVnKGFjY291bnQpOw0KICAgICAgICAgICAgYXBpLmRlYnVnKHN5bWJvbCk7DQogICAgICAgICAgICBhcGkuZGVidWcoYnV5T3JkZXIucXVhbnRpdHkpOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIC8vIHRyYW5zZmVyIHRoZSB0b2tlbnMgdG8gdGhlIHNlbGxlcg0KICAgICAgICAgIHJlcyA9IGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhzZWxsT3JkZXIuYWNjb3VudCwgU1RFRU1fUEVHR0VEX1NZTUJPTCwgcXR5VG9rZW5zVG9TZW5kLCAndXNlcicpOw0KDQogICAgICAgICAgaWYgKHJlcy5lcnJvcnMpIHsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhyZXMuZXJyb3JzKTsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhgVFhJRDogJHthcGkudHJhbnNhY3Rpb25JZH1gKTsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhzZWxsT3JkZXIuYWNjb3VudCk7DQogICAgICAgICAgICBhcGkuZGVidWcoU1RFRU1fUEVHR0VEX1NZTUJPTCk7DQogICAgICAgICAgICBhcGkuZGVidWcocXR5VG9rZW5zVG9TZW5kKTsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAvLyB1cGRhdGUgdGhlIHNlbGwgb3JkZXINCiAgICAgICAgICBjb25zdCBxdHlMZWZ0U2VsbE9yZGVyID0gYXBpLkJpZ051bWJlcihzZWxsT3JkZXIucXVhbnRpdHkpDQogICAgICAgICAgICAubWludXMoYnV5T3JkZXIucXVhbnRpdHkpDQogICAgICAgICAgICAudG9GaXhlZCh0b2tlblByZWNpc2lvbik7DQogICAgICAgICAgY29uc3QgbmJUb2tlbnNUb0ZpbGxPcmRlciA9IGFwaS5CaWdOdW1iZXIoc2VsbE9yZGVyLnByaWNlKQ0KICAgICAgICAgICAgLm11bHRpcGxpZWRCeShxdHlMZWZ0U2VsbE9yZGVyKQ0KICAgICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KDQogICAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIocXR5TGVmdFNlbGxPcmRlcikuZ3QoMCkNCiAgICAgICAgICAgICYmIChhcGkuQmlnTnVtYmVyKG5iVG9rZW5zVG9GaWxsT3JkZXIpLmd0ZSgnMC4wMDAwMDAwMScpKSkgew0KICAgICAgICAgICAgc2VsbE9yZGVyLnF1YW50aXR5ID0gcXR5TGVmdFNlbGxPcmRlcjsNCg0KICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnc2VsbEJvb2snLCBzZWxsT3JkZXIpOw0KICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcihxdHlMZWZ0U2VsbE9yZGVyKS5ndCgwKSkgew0KICAgICAgICAgICAgICBhd2FpdCBhcGkudHJhbnNmZXJUb2tlbnMoc2VsbE9yZGVyLmFjY291bnQsIHN5bWJvbCwgcXR5TGVmdFNlbGxPcmRlciwgJ3VzZXInKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ3NlbGxCb29rJywgc2VsbE9yZGVyKTsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAvLyB1bmxvY2sgcmVtYWluaW5nIHRva2VucywgdXBkYXRlIHRoZSBxdWFudGl0eSB0byBnZXQgYW5kIHJlbW92ZSB0aGUgYnV5IG9yZGVyDQogICAgICAgICAgY29uc3QgdG9rZW5zVG9VbmxvY2sgPSBhcGkuQmlnTnVtYmVyKGJ1eU9yZGVyLnRva2Vuc0xvY2tlZCkNCiAgICAgICAgICAgIC5taW51cyhxdHlUb2tlbnNUb1NlbmQpDQogICAgICAgICAgICAudG9GaXhlZChTVEVFTV9QRUdHRURfU1lNQk9MX1BSRVNJQ0lPTik7DQoNCiAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcih0b2tlbnNUb1VubG9jaykuZ3QoMCkpIHsNCiAgICAgICAgICAgIGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhhY2NvdW50LCBTVEVFTV9QRUdHRURfU1lNQk9MLCB0b2tlbnNUb1VubG9jaywgJ3VzZXInKTsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAvLyBhZGQgdGhlIHRyYWRlIHRvIHRoZSBoaXN0b3J5DQogICAgICAgICAgYXdhaXQgdXBkYXRlVHJhZGVzSGlzdG9yeSgnYnV5JywgYWNjb3VudCwgc2VsbE9yZGVyLmFjY291bnQsIHN5bWJvbCwgYnV5T3JkZXIucXVhbnRpdHksIHNlbGxPcmRlci5wcmljZSwgcXR5VG9rZW5zVG9TZW5kKTsNCg0KICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgdm9sdW1lDQogICAgICAgICAgdm9sdW1lVHJhZGVkID0gYXBpLkJpZ051bWJlcih2b2x1bWVUcmFkZWQpLnBsdXMocXR5VG9rZW5zVG9TZW5kKTsNCg0KICAgICAgICAgIGJ1eU9yZGVyLnF1YW50aXR5ID0gJzAnOw0KICAgICAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ2J1eUJvb2snLCBidXlPcmRlcik7DQogICAgICAgIH0NCiAgICAgIH0gZWxzZSB7DQogICAgICAgIGxldCBxdHlUb2tlbnNUb1NlbmQgPSBhcGkuQmlnTnVtYmVyKHNlbGxPcmRlci5wcmljZSkNCiAgICAgICAgICAubXVsdGlwbGllZEJ5KHNlbGxPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAudG9GaXhlZChTVEVFTV9QRUdHRURfU1lNQk9MX1BSRVNJQ0lPTik7DQoNCiAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIocXR5VG9rZW5zVG9TZW5kKS5ndChidXlPcmRlci50b2tlbnNMb2NrZWQpKSB7DQogICAgICAgICAgcXR5VG9rZW5zVG9TZW5kID0gYXBpLkJpZ051bWJlcihzZWxsT3JkZXIucHJpY2UpDQogICAgICAgICAgICAubXVsdGlwbGllZEJ5KHNlbGxPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAgIC50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOw0KICAgICAgICB9DQoNCiAgICAgICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdHlUb2tlbnNUb1NlbmQpLmd0KDApDQogICAgICAgICAgJiYgYXBpLkJpZ051bWJlcihidXlPcmRlci5xdWFudGl0eSkuZ3QoMCksICd0aGUgb3JkZXIgY2Fubm90IGJlIGZpbGxlZCcpKSB7DQogICAgICAgICAgLy8gdHJhbnNmZXIgdGhlIHRva2VucyB0byB0aGUgYnV5ZXINCiAgICAgICAgICBsZXQgcmVzID0gYXdhaXQgYXBpLnRyYW5zZmVyVG9rZW5zKGFjY291bnQsIHN5bWJvbCwgc2VsbE9yZGVyLnF1YW50aXR5LCAndXNlcicpOw0KDQogICAgICAgICAgaWYgKHJlcy5lcnJvcnMpIHsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhyZXMuZXJyb3JzKTsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhgVFhJRDogJHthcGkudHJhbnNhY3Rpb25JZH1gKTsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhhY2NvdW50KTsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhzeW1ib2wpOw0KICAgICAgICAgICAgYXBpLmRlYnVnKHNlbGxPcmRlci5xdWFudGl0eSk7DQogICAgICAgICAgfQ0KDQogICAgICAgICAgLy8gdHJhbnNmZXIgdGhlIHRva2VucyB0byB0aGUgc2VsbGVyDQogICAgICAgICAgcmVzID0gYXdhaXQgYXBpLnRyYW5zZmVyVG9rZW5zKHNlbGxPcmRlci5hY2NvdW50LCBTVEVFTV9QRUdHRURfU1lNQk9MLCBxdHlUb2tlbnNUb1NlbmQsICd1c2VyJyk7DQoNCiAgICAgICAgICBpZiAocmVzLmVycm9ycykgew0KICAgICAgICAgICAgYXBpLmRlYnVnKHJlcy5lcnJvcnMpOw0KICAgICAgICAgICAgYXBpLmRlYnVnKGBUWElEOiAke2FwaS50cmFuc2FjdGlvbklkfWApOw0KICAgICAgICAgICAgYXBpLmRlYnVnKHNlbGxPcmRlci5hY2NvdW50KTsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhTVEVFTV9QRUdHRURfU1lNQk9MKTsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhxdHlUb2tlbnNUb1NlbmQpOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIC8vIHJlbW92ZSB0aGUgc2VsbCBvcmRlcg0KICAgICAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ3NlbGxCb29rJywgc2VsbE9yZGVyKTsNCg0KICAgICAgICAgIC8vIHVwZGF0ZSB0b2tlbnNMb2NrZWQgYW5kIHRoZSBxdWFudGl0eSB0byBnZXQNCiAgICAgICAgICBidXlPcmRlci50b2tlbnNMb2NrZWQgPSBhcGkuQmlnTnVtYmVyKGJ1eU9yZGVyLnRva2Vuc0xvY2tlZCkNCiAgICAgICAgICAgIC5taW51cyhxdHlUb2tlbnNUb1NlbmQpDQogICAgICAgICAgICAudG9GaXhlZChTVEVFTV9QRUdHRURfU1lNQk9MX1BSRVNJQ0lPTik7DQogICAgICAgICAgYnV5T3JkZXIucXVhbnRpdHkgPSBhcGkuQmlnTnVtYmVyKGJ1eU9yZGVyLnF1YW50aXR5KQ0KICAgICAgICAgICAgLm1pbnVzKHNlbGxPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAgIC50b0ZpeGVkKHRva2VuUHJlY2lzaW9uKTsNCg0KICAgICAgICAgIC8vIGNoZWNrIGlmIHRoZSBvcmRlciBjYW4gc3RpbGwgYmUgZmlsbGVkDQogICAgICAgICAgY29uc3QgbmJUb2tlbnNUb0ZpbGxPcmRlciA9IGFwaS5CaWdOdW1iZXIoYnV5T3JkZXIucHJpY2UpDQogICAgICAgICAgICAubXVsdGlwbGllZEJ5KGJ1eU9yZGVyLnF1YW50aXR5KQ0KICAgICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KDQogICAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIobmJUb2tlbnNUb0ZpbGxPcmRlcikubHQoJzAuMDAwMDAwMDEnKSkgew0KICAgICAgICAgICAgYXdhaXQgYXBpLnRyYW5zZmVyVG9rZW5zKGFjY291bnQsIFNURUVNX1BFR0dFRF9TWU1CT0wsIGJ1eU9yZGVyLnRva2Vuc0xvY2tlZCwgJ3VzZXInKTsNCg0KICAgICAgICAgICAgYnV5T3JkZXIucXVhbnRpdHkgPSAnMCc7DQogICAgICAgICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdidXlCb29rJywgYnV5T3JkZXIpOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIC8vIGFkZCB0aGUgdHJhZGUgdG8gdGhlIGhpc3RvcnkNCiAgICAgICAgICBhd2FpdCB1cGRhdGVUcmFkZXNIaXN0b3J5KCdidXknLCBhY2NvdW50LCBzZWxsT3JkZXIuYWNjb3VudCwgc3ltYm9sLCBzZWxsT3JkZXIucXVhbnRpdHksIHNlbGxPcmRlci5wcmljZSwgcXR5VG9rZW5zVG9TZW5kKTsNCg0KICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgdm9sdW1lDQogICAgICAgICAgdm9sdW1lVHJhZGVkID0gYXBpLkJpZ051bWJlcih2b2x1bWVUcmFkZWQpLnBsdXMocXR5VG9rZW5zVG9TZW5kKTsNCiAgICAgICAgfQ0KICAgICAgfQ0KDQogICAgICBpbmMgKz0gMTsNCiAgICB9DQoNCiAgICBvZmZzZXQgKz0gMTAwMDsNCg0KICAgIGlmIChhcGkuQmlnTnVtYmVyKGJ1eU9yZGVyLnF1YW50aXR5KS5ndCgwKSkgew0KICAgICAgLy8gZ2V0IHRoZSBvcmRlcnMgdGhhdCBtYXRjaCB0aGUgc3ltYm9sIGFuZCB0aGUgcHJpY2UNCiAgICAgIHNlbGxPcmRlckJvb2sgPSBhd2FpdCBhcGkuZGIuZmluZCgnc2VsbEJvb2snLCB7DQogICAgICAgIHN5bWJvbCwNCiAgICAgICAgcHJpY2VEZWM6IHsNCiAgICAgICAgICAkbHRlOiBwcmljZURlYywNCiAgICAgICAgfSwNCiAgICAgIH0sIDEwMDAsIG9mZnNldCwNCiAgICAgIFsNCiAgICAgICAgeyBpbmRleDogJ3ByaWNlRGVjJywgZGVzY2VuZGluZzogZmFsc2UgfSwNCiAgICAgICAgeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH0sDQogICAgICBdKTsNCiAgICB9DQogIH0gd2hpbGUgKHNlbGxPcmRlckJvb2subGVuZ3RoID4gMCAmJiBhcGkuQmlnTnVtYmVyKGJ1eU9yZGVyLnF1YW50aXR5KS5ndCgwKSk7DQoNCiAgLy8gdXBkYXRlIHRoZSBidXkgb3JkZXIgaWYgcGFydGlhbGx5IGZpbGxlZA0KICBpZiAoYXBpLkJpZ051bWJlcihidXlPcmRlci5xdWFudGl0eSkuZ3QoMCkpIHsNCiAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdidXlCb29rJywgYnV5T3JkZXIpOw0KICB9DQogIGlmIChhcGkuQmlnTnVtYmVyKHZvbHVtZVRyYWRlZCkuZ3QoMCkpIHsNCiAgICBhd2FpdCB1cGRhdGVWb2x1bWVNZXRyaWMoc3ltYm9sLCB2b2x1bWVUcmFkZWQpOw0KICB9DQogIGF3YWl0IHVwZGF0ZUFza01ldHJpYyhzeW1ib2wpOw0KICBhd2FpdCB1cGRhdGVCaWRNZXRyaWMoc3ltYm9sKTsNCn07DQoNCmNvbnN0IGZpbmRNYXRjaGluZ0J1eU9yZGVycyA9IGFzeW5jIChvcmRlciwgdG9rZW5QcmVjaXNpb24pID0+IHsNCiAgY29uc3Qgew0KICAgIGFjY291bnQsDQogICAgc3ltYm9sLA0KICAgIHByaWNlRGVjLA0KICB9ID0gb3JkZXI7DQoNCiAgY29uc3Qgc2VsbE9yZGVyID0gb3JkZXI7DQogIGxldCBvZmZzZXQgPSAwOw0KICBsZXQgdm9sdW1lVHJhZGVkID0gMDsNCg0KICBhd2FpdCByZW1vdmVFeHBpcmVkT3JkZXJzKCdidXlCb29rJyk7DQoNCiAgLy8gZ2V0IHRoZSBvcmRlcnMgdGhhdCBtYXRjaCB0aGUgc3ltYm9sIGFuZCB0aGUgcHJpY2UNCiAgbGV0IGJ1eU9yZGVyQm9vayA9IGF3YWl0IGFwaS5kYi5maW5kKCdidXlCb29rJywgew0KICAgIHN5bWJvbCwNCiAgICBwcmljZURlYzogew0KICAgICAgJGd0ZTogcHJpY2VEZWMsDQogICAgfSwNCiAgfSwgMTAwMCwgb2Zmc2V0LA0KICBbDQogICAgeyBpbmRleDogJ3ByaWNlRGVjJywgZGVzY2VuZGluZzogdHJ1ZSB9LA0KICAgIHsgaW5kZXg6ICdfaWQnLCBkZXNjZW5kaW5nOiBmYWxzZSB9LA0KICBdKTsNCg0KICBkbyB7DQogICAgY29uc3QgbmJPcmRlcnMgPSBidXlPcmRlckJvb2subGVuZ3RoOw0KICAgIGxldCBpbmMgPSAwOw0KDQogICAgd2hpbGUgKGluYyA8IG5iT3JkZXJzICYmIGFwaS5CaWdOdW1iZXIoc2VsbE9yZGVyLnF1YW50aXR5KS5ndCgwKSkgew0KICAgICAgY29uc3QgYnV5T3JkZXIgPSBidXlPcmRlckJvb2tbaW5jXTsNCiAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHNlbGxPcmRlci5xdWFudGl0eSkubHRlKGJ1eU9yZGVyLnF1YW50aXR5KSkgew0KICAgICAgICBsZXQgcXR5VG9rZW5zVG9TZW5kID0gYXBpLkJpZ051bWJlcihidXlPcmRlci5wcmljZSkNCiAgICAgICAgICAubXVsdGlwbGllZEJ5KHNlbGxPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAudG9GaXhlZChTVEVFTV9QRUdHRURfU1lNQk9MX1BSRVNJQ0lPTik7DQoNCiAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIocXR5VG9rZW5zVG9TZW5kKS5ndChidXlPcmRlci50b2tlbnNMb2NrZWQpKSB7DQogICAgICAgICAgcXR5VG9rZW5zVG9TZW5kID0gYXBpLkJpZ051bWJlcihidXlPcmRlci5wcmljZSkNCiAgICAgICAgICAgIC5tdWx0aXBsaWVkQnkoc2VsbE9yZGVyLnF1YW50aXR5KQ0KICAgICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04sIGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7DQogICAgICAgIH0NCg0KICAgICAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF0eVRva2Vuc1RvU2VuZCkuZ3QoMCkNCiAgICAgICAgICAmJiBhcGkuQmlnTnVtYmVyKHNlbGxPcmRlci5xdWFudGl0eSkuZ3QoMCksICd0aGUgb3JkZXIgY2Fubm90IGJlIGZpbGxlZCcpKSB7DQogICAgICAgICAgLy8gdHJhbnNmZXIgdGhlIHRva2VucyB0byB0aGUgYnV5ZXINCiAgICAgICAgICBsZXQgcmVzID0gYXdhaXQgYXBpLnRyYW5zZmVyVG9rZW5zKGJ1eU9yZGVyLmFjY291bnQsIHN5bWJvbCwgc2VsbE9yZGVyLnF1YW50aXR5LCAndXNlcicpOw0KDQogICAgICAgICAgaWYgKHJlcy5lcnJvcnMpIHsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhyZXMuZXJyb3JzKTsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhgVFhJRDogJHthcGkudHJhbnNhY3Rpb25JZH1gKTsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhidXlPcmRlci5hY2NvdW50KTsNCiAgICAgICAgICAgIGFwaS5kZWJ1ZyhzeW1ib2wpOw0KICAgICAgICAgICAgYXBpLmRlYnVnKHNlbGxPcmRlci5xdWFudGl0eSk7DQogICAgICAgICAgfQ0KDQogICAgICAgICAgLy8gdHJhbnNmZXIgdGhlIHRva2VucyB0byB0aGUgc2VsbGVyDQogICAgICAgICAgcmVzID0gYXdhaXQgYXBpLnRyYW5zZmVyVG9rZW5zKGFjY291bnQsIFNURUVNX1BFR0dFRF9TWU1CT0wsIHF0eVRva2Vuc1RvU2VuZCwgJ3VzZXInKTsNCg0KICAgICAgICAgIGlmIChyZXMuZXJyb3JzKSB7DQogICAgICAgICAgICBhcGkuZGVidWcocmVzLmVycm9ycyk7DQogICAgICAgICAgICBhcGkuZGVidWcoYFRYSUQ6ICR7YXBpLnRyYW5zYWN0aW9uSWR9YCk7DQogICAgICAgICAgICBhcGkuZGVidWcoYWNjb3VudCk7DQogICAgICAgICAgICBhcGkuZGVidWcoU1RFRU1fUEVHR0VEX1NZTUJPTCk7DQogICAgICAgICAgICBhcGkuZGVidWcocXR5VG9rZW5zVG9TZW5kKTsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAvLyB1cGRhdGUgdGhlIGJ1eSBvcmRlcg0KICAgICAgICAgIGNvbnN0IHF0eUxlZnRCdXlPcmRlciA9IGFwaS5CaWdOdW1iZXIoYnV5T3JkZXIucXVhbnRpdHkpDQogICAgICAgICAgICAubWludXMoc2VsbE9yZGVyLnF1YW50aXR5KQ0KICAgICAgICAgICAgLnRvRml4ZWQodG9rZW5QcmVjaXNpb24pOw0KDQogICAgICAgICAgY29uc3QgYnV5T3JkZXJ0b2tlbnNMb2NrZWQgPSBhcGkuQmlnTnVtYmVyKGJ1eU9yZGVyLnRva2Vuc0xvY2tlZCkNCiAgICAgICAgICAgIC5taW51cyhxdHlUb2tlbnNUb1NlbmQpDQogICAgICAgICAgICAudG9GaXhlZChTVEVFTV9QRUdHRURfU1lNQk9MX1BSRVNJQ0lPTik7DQogICAgICAgICAgY29uc3QgbmJUb2tlbnNUb0ZpbGxPcmRlciA9IGFwaS5CaWdOdW1iZXIoYnV5T3JkZXIucHJpY2UpDQogICAgICAgICAgICAubXVsdGlwbGllZEJ5KHF0eUxlZnRCdXlPcmRlcikNCiAgICAgICAgICAgIC50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OKTsNCg0KICAgICAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHF0eUxlZnRCdXlPcmRlcikuZ3QoMCkNCiAgICAgICAgICAgICYmIChhcGkuQmlnTnVtYmVyKG5iVG9rZW5zVG9GaWxsT3JkZXIpLmd0ZSgnMC4wMDAwMDAwMScpKSkgew0KICAgICAgICAgICAgYnV5T3JkZXIucXVhbnRpdHkgPSBxdHlMZWZ0QnV5T3JkZXI7DQogICAgICAgICAgICBidXlPcmRlci50b2tlbnNMb2NrZWQgPSBidXlPcmRlcnRva2Vuc0xvY2tlZDsNCg0KICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnYnV5Qm9vaycsIGJ1eU9yZGVyKTsNCiAgICAgICAgICB9IGVsc2Ugew0KICAgICAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIoYnV5T3JkZXJ0b2tlbnNMb2NrZWQpLmd0KDApKSB7DQogICAgICAgICAgICAgIGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhidXlPcmRlci5hY2NvdW50LCBTVEVFTV9QRUdHRURfU1lNQk9MLCBidXlPcmRlcnRva2Vuc0xvY2tlZCwgJ3VzZXInKTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ2J1eUJvb2snLCBidXlPcmRlcik7DQogICAgICAgICAgfQ0KDQogICAgICAgICAgLy8gYWRkIHRoZSB0cmFkZSB0byB0aGUgaGlzdG9yeQ0KICAgICAgICAgIGF3YWl0IHVwZGF0ZVRyYWRlc0hpc3RvcnkoJ3NlbGwnLCBidXlPcmRlci5hY2NvdW50LCBhY2NvdW50LCBzeW1ib2wsIHNlbGxPcmRlci5xdWFudGl0eSwgYnV5T3JkZXIucHJpY2UsIHF0eVRva2Vuc1RvU2VuZCk7DQoNCiAgICAgICAgICAvLyB1cGRhdGUgdGhlIHZvbHVtZQ0KICAgICAgICAgIHZvbHVtZVRyYWRlZCA9IGFwaS5CaWdOdW1iZXIodm9sdW1lVHJhZGVkKS5wbHVzKHF0eVRva2Vuc1RvU2VuZCk7DQoNCiAgICAgICAgICBzZWxsT3JkZXIucXVhbnRpdHkgPSAwOw0KICAgICAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ3NlbGxCb29rJywgc2VsbE9yZGVyKTsNCiAgICAgICAgfQ0KICAgICAgfSBlbHNlIHsNCiAgICAgICAgbGV0IHF0eVRva2Vuc1RvU2VuZCA9IGFwaS5CaWdOdW1iZXIoYnV5T3JkZXIucHJpY2UpDQogICAgICAgICAgLm11bHRpcGxpZWRCeShidXlPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAudG9GaXhlZChTVEVFTV9QRUdHRURfU1lNQk9MX1BSRVNJQ0lPTik7DQoNCiAgICAgICAgaWYgKHF0eVRva2Vuc1RvU2VuZCA+IGJ1eU9yZGVyLnRva2Vuc0xvY2tlZCkgew0KICAgICAgICAgIHF0eVRva2Vuc1RvU2VuZCA9IGFwaS5CaWdOdW1iZXIoYnV5T3JkZXIucHJpY2UpDQogICAgICAgICAgICAubXVsdGlwbGllZEJ5KGJ1eU9yZGVyLnF1YW50aXR5KQ0KICAgICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04sIGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7DQogICAgICAgIH0NCg0KICAgICAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKHF0eVRva2Vuc1RvU2VuZCkuZ3QoMCkNCiAgICAgICAgICAmJiBhcGkuQmlnTnVtYmVyKHNlbGxPcmRlci5xdWFudGl0eSkuZ3QoMCksICd0aGUgb3JkZXIgY2Fubm90IGJlIGZpbGxlZCcpKSB7DQogICAgICAgICAgLy8gdHJhbnNmZXIgdGhlIHRva2VucyB0byB0aGUgYnV5ZXINCiAgICAgICAgICBsZXQgcmVzID0gYXdhaXQgYXBpLnRyYW5zZmVyVG9rZW5zKGJ1eU9yZGVyLmFjY291bnQsIHN5bWJvbCwgYnV5T3JkZXIucXVhbnRpdHksICd1c2VyJyk7DQoNCiAgICAgICAgICBpZiAocmVzLmVycm9ycykgew0KICAgICAgICAgICAgYXBpLmRlYnVnKHJlcy5lcnJvcnMpOw0KICAgICAgICAgICAgYXBpLmRlYnVnKGBUWElEOiAke2FwaS50cmFuc2FjdGlvbklkfWApOw0KICAgICAgICAgICAgYXBpLmRlYnVnKGJ1eU9yZGVyLmFjY291bnQpOw0KICAgICAgICAgICAgYXBpLmRlYnVnKHN5bWJvbCk7DQogICAgICAgICAgICBhcGkuZGVidWcoYnV5T3JkZXIucXVhbnRpdHkpOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIC8vIHRyYW5zZmVyIHRoZSB0b2tlbnMgdG8gdGhlIHNlbGxlcg0KICAgICAgICAgIHJlcyA9IGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhhY2NvdW50LCBTVEVFTV9QRUdHRURfU1lNQk9MLCBxdHlUb2tlbnNUb1NlbmQsICd1c2VyJyk7DQoNCiAgICAgICAgICBpZiAocmVzLmVycm9ycykgew0KICAgICAgICAgICAgYXBpLmRlYnVnKHJlcy5lcnJvcnMpOw0KICAgICAgICAgICAgYXBpLmRlYnVnKGBUWElEOiAke2FwaS50cmFuc2FjdGlvbklkfWApOw0KICAgICAgICAgICAgYXBpLmRlYnVnKGFjY291bnQpOw0KICAgICAgICAgICAgYXBpLmRlYnVnKFNURUVNX1BFR0dFRF9TWU1CT0wpOw0KICAgICAgICAgICAgYXBpLmRlYnVnKHF0eVRva2Vuc1RvU2VuZCk7DQogICAgICAgICAgfQ0KDQogICAgICAgICAgY29uc3QgYnV5T3JkZXJ0b2tlbnNMb2NrZWQgPSBhcGkuQmlnTnVtYmVyKGJ1eU9yZGVyLnRva2Vuc0xvY2tlZCkNCiAgICAgICAgICAgIC5taW51cyhxdHlUb2tlbnNUb1NlbmQpDQogICAgICAgICAgICAudG9GaXhlZChTVEVFTV9QRUdHRURfU1lNQk9MX1BSRVNJQ0lPTik7DQoNCiAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcihidXlPcmRlcnRva2Vuc0xvY2tlZCkuZ3QoMCkpIHsNCiAgICAgICAgICAgIGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhidXlPcmRlci5hY2NvdW50LCBTVEVFTV9QRUdHRURfU1lNQk9MLCBidXlPcmRlcnRva2Vuc0xvY2tlZCwgJ3VzZXInKTsNCiAgICAgICAgICB9DQoNCiAgICAgICAgICAvLyByZW1vdmUgdGhlIGJ1eSBvcmRlcg0KICAgICAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ2J1eUJvb2snLCBidXlPcmRlcik7DQoNCiAgICAgICAgICAvLyB1cGRhdGUgdGhlIHF1YW50aXR5IHRvIGdldA0KICAgICAgICAgIHNlbGxPcmRlci5xdWFudGl0eSA9IGFwaS5CaWdOdW1iZXIoc2VsbE9yZGVyLnF1YW50aXR5KQ0KICAgICAgICAgICAgLm1pbnVzKGJ1eU9yZGVyLnF1YW50aXR5KQ0KICAgICAgICAgICAgLnRvRml4ZWQodG9rZW5QcmVjaXNpb24pOw0KDQogICAgICAgICAgLy8gY2hlY2sgaWYgdGhlIG9yZGVyIGNhbiBzdGlsbCBiZSBmaWxsZWQNCiAgICAgICAgICBjb25zdCBuYlRva2Vuc1RvRmlsbE9yZGVyID0gYXBpLkJpZ051bWJlcihzZWxsT3JkZXIucHJpY2UpDQogICAgICAgICAgICAubXVsdGlwbGllZEJ5KHNlbGxPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAgIC50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OKTsNCg0KICAgICAgICAgIGlmIChhcGkuQmlnTnVtYmVyKG5iVG9rZW5zVG9GaWxsT3JkZXIpLmx0KCcwLjAwMDAwMDAxJykpIHsNCiAgICAgICAgICAgIGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhhY2NvdW50LCBzeW1ib2wsIHNlbGxPcmRlci5xdWFudGl0eSwgJ3VzZXInKTsNCg0KICAgICAgICAgICAgc2VsbE9yZGVyLnF1YW50aXR5ID0gJzAnOw0KICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnJlbW92ZSgnc2VsbEJvb2snLCBzZWxsT3JkZXIpOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIC8vIGFkZCB0aGUgdHJhZGUgdG8gdGhlIGhpc3RvcnkNCiAgICAgICAgICBhd2FpdCB1cGRhdGVUcmFkZXNIaXN0b3J5KCdzZWxsJywgYnV5T3JkZXIuYWNjb3VudCwgYWNjb3VudCwgc3ltYm9sLCBidXlPcmRlci5xdWFudGl0eSwgYnV5T3JkZXIucHJpY2UsIHF0eVRva2Vuc1RvU2VuZCk7DQoNCiAgICAgICAgICAvLyB1cGRhdGUgdGhlIHZvbHVtZQ0KICAgICAgICAgIHZvbHVtZVRyYWRlZCA9IGFwaS5CaWdOdW1iZXIodm9sdW1lVHJhZGVkKS5wbHVzKHF0eVRva2Vuc1RvU2VuZCk7DQogICAgICAgIH0NCiAgICAgIH0NCg0KICAgICAgaW5jICs9IDE7DQogICAgfQ0KDQogICAgb2Zmc2V0ICs9IDEwMDA7DQoNCiAgICBpZiAoYXBpLkJpZ051bWJlcihzZWxsT3JkZXIucXVhbnRpdHkpLmd0KDApKSB7DQogICAgICAvLyBnZXQgdGhlIG9yZGVycyB0aGF0IG1hdGNoIHRoZSBzeW1ib2wgYW5kIHRoZSBwcmljZQ0KICAgICAgYnV5T3JkZXJCb29rID0gYXdhaXQgYXBpLmRiLmZpbmQoJ2J1eUJvb2snLCB7DQogICAgICAgIHN5bWJvbCwNCiAgICAgICAgcHJpY2VEZWM6IHsNCiAgICAgICAgICAkZ3RlOiBwcmljZURlYywNCiAgICAgICAgfSwNCiAgICAgIH0sIDEwMDAsIG9mZnNldCwNCiAgICAgIFsNCiAgICAgICAgeyBpbmRleDogJ3ByaWNlRGVjJywgZGVzY2VuZGluZzogdHJ1ZSB9LA0KICAgICAgICB7IGluZGV4OiAnX2lkJywgZGVzY2VuZGluZzogZmFsc2UgfSwNCiAgICAgIF0pOw0KICAgIH0NCiAgfSB3aGlsZSAoYnV5T3JkZXJCb29rLmxlbmd0aCA+IDAgJiYgYXBpLkJpZ051bWJlcihzZWxsT3JkZXIucXVhbnRpdHkpLmd0KDApKTsNCg0KICAvLyB1cGRhdGUgdGhlIHNlbGwgb3JkZXIgaWYgcGFydGlhbGx5IGZpbGxlZA0KICBpZiAoYXBpLkJpZ051bWJlcihzZWxsT3JkZXIucXVhbnRpdHkpLmd0KDApKSB7DQogICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnc2VsbEJvb2snLCBzZWxsT3JkZXIpOw0KICB9DQoNCiAgaWYgKGFwaS5CaWdOdW1iZXIodm9sdW1lVHJhZGVkKS5ndCgwKSkgew0KICAgIGF3YWl0IHVwZGF0ZVZvbHVtZU1ldHJpYyhzeW1ib2wsIHZvbHVtZVRyYWRlZCk7DQogIH0NCiAgYXdhaXQgdXBkYXRlQXNrTWV0cmljKHN5bWJvbCk7DQogIGF3YWl0IHVwZGF0ZUJpZE1ldHJpYyhzeW1ib2wpOw0KfTsNCg0KYWN0aW9ucy5idXkgPSBhc3luYyAocGF5bG9hZCkgPT4gew0KICBjb25zdCB7DQogICAgc3ltYm9sLA0KICAgIHF1YW50aXR5LA0KICAgIHByaWNlLA0KICAgIGV4cGlyYXRpb24sDQogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LA0KICB9ID0gcGF5bG9hZDsNCg0KICAvLyBidXkgKHF1YW50aXR5KSBvZiAoc3ltYm9sKSBhdCAocHJpY2UpKFNURUVNX1BFR0dFRF9TWU1CT0wpIHBlciAoc3ltYm9sKQ0KICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQ0KICAgICYmIGFwaS5hc3NlcnQocHJpY2UgJiYgdHlwZW9mIHByaWNlID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihwcmljZSkuaXNOYU4oKQ0KICAgICAgJiYgc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnICYmIHN5bWJvbCAhPT0gU1RFRU1fUEVHR0VEX1NZTUJPTA0KICAgICAgJiYgcXVhbnRpdHkgJiYgdHlwZW9mIHF1YW50aXR5ID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihxdWFudGl0eSkuaXNOYU4oKQ0KICAgICAgJiYgKGV4cGlyYXRpb24gPT09IHVuZGVmaW5lZCB8fCAoZXhwaXJhdGlvbiAmJiBOdW1iZXIuaXNJbnRlZ2VyKGV4cGlyYXRpb24pICYmIGV4cGlyYXRpb24gPiAwKSksICdpbnZhbGlkIHBhcmFtcycpDQogICkgew0KICAgIC8vIGdldCB0aGUgdG9rZW4gcGFyYW1zDQogICAgY29uc3QgdG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICd0b2tlbnMnLCB7IHN5bWJvbCB9KTsNCg0KICAgIC8vIHBlcmZvcm0gYSBmZXcgdmVyaWZpY2F0aW9ucw0KICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuDQogICAgICAmJiBhcGkuQmlnTnVtYmVyKHByaWNlKS5ndCgwKQ0KICAgICAgJiYgY291bnREZWNpbWFscyhwcmljZSkgPD0gU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04NCiAgICAgICYmIGNvdW50RGVjaW1hbHMocXVhbnRpdHkpIDw9IHRva2VuLnByZWNpc2lvbiwgJ2ludmFsaWQgcGFyYW1zJykpIHsNCiAgICAgIC8vIGluaXRpYXRlIGEgdHJhbnNmZXIgZnJvbSBhcGkuc2VuZGVyIHRvIGNvbnRyYWN0IGJhbGFuY2UNCg0KICAgICAgY29uc3QgbmJUb2tlbnNUb0xvY2sgPSBhcGkuQmlnTnVtYmVyKHByaWNlKQ0KICAgICAgICAubXVsdGlwbGllZEJ5KHF1YW50aXR5KQ0KICAgICAgICAudG9GaXhlZChTVEVFTV9QRUdHRURfU1lNQk9MX1BSRVNJQ0lPTik7DQoNCiAgICAgIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIobmJUb2tlbnNUb0xvY2spLmd0ZSgnMC4wMDAwMDAwMScpLCAnb3JkZXIgY2Fubm90IGJlIHBsYWNlZCBhcyBpdCBjYW5ub3QgYmUgZmlsbGVkJykpIHsNCiAgICAgICAgLy8gbG9jayBTVEVFTV9QRUdHRURfU1lNQk9MIHRva2Vucw0KICAgICAgICBjb25zdCByZXMgPSBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ3Rva2VucycsICd0cmFuc2ZlclRvQ29udHJhY3QnLCB7IHN5bWJvbDogU1RFRU1fUEVHR0VEX1NZTUJPTCwgcXVhbnRpdHk6IG5iVG9rZW5zVG9Mb2NrLCB0bzogQ09OVFJBQ1RfTkFNRSB9KTsNCg0KICAgICAgICBpZiAocmVzLmVycm9ycyA9PT0gdW5kZWZpbmVkDQogICAgICAgICAgJiYgcmVzLmV2ZW50cyAmJiByZXMuZXZlbnRzLmZpbmQoZWwgPT4gZWwuY29udHJhY3QgPT09ICd0b2tlbnMnICYmIGVsLmV2ZW50ID09PSAndHJhbnNmZXJUb0NvbnRyYWN0JyAmJiBlbC5kYXRhLmZyb20gPT09IGFwaS5zZW5kZXIgJiYgZWwuZGF0YS50byA9PT0gQ09OVFJBQ1RfTkFNRSAmJiBlbC5kYXRhLnF1YW50aXR5ID09PSBuYlRva2Vuc1RvTG9jayAmJiBlbC5kYXRhLnN5bWJvbCA9PT0gU1RFRU1fUEVHR0VEX1NZTUJPTCkgIT09IHVuZGVmaW5lZCkgew0KICAgICAgICAgIGNvbnN0IHRpbWVzdGFtcFNlYyA9IGFwaS5CaWdOdW1iZXIobmV3IERhdGUoYCR7YXBpLnN0ZWVtQmxvY2tUaW1lc3RhbXB9LjAwMFpgKS5nZXRUaW1lKCkpDQogICAgICAgICAgICAuZGl2aWRlZEJ5KDEwMDApDQogICAgICAgICAgICAudG9OdW1iZXIoKTsNCg0KICAgICAgICAgIC8vIG9yZGVyDQogICAgICAgICAgY29uc3Qgb3JkZXIgPSB7fTsNCg0KICAgICAgICAgIG9yZGVyLnR4SWQgPSBhcGkudHJhbnNhY3Rpb25JZDsNCiAgICAgICAgICBvcmRlci50aW1lc3RhbXAgPSB0aW1lc3RhbXBTZWM7DQogICAgICAgICAgb3JkZXIuYWNjb3VudCA9IGFwaS5zZW5kZXI7DQogICAgICAgICAgb3JkZXIuc3ltYm9sID0gc3ltYm9sOw0KICAgICAgICAgIG9yZGVyLnF1YW50aXR5ID0gYXBpLkJpZ051bWJlcihxdWFudGl0eSkudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24pOw0KICAgICAgICAgIG9yZGVyLnByaWNlID0gYXBpLkJpZ051bWJlcihwcmljZSkudG9GaXhlZChTVEVFTV9QRUdHRURfU1lNQk9MX1BSRVNJQ0lPTik7DQogICAgICAgICAgb3JkZXIucHJpY2VEZWMgPSB7ICRudW1iZXJEZWNpbWFsOiBvcmRlci5wcmljZSB9Ow0KICAgICAgICAgIG9yZGVyLnRva2Vuc0xvY2tlZCA9IG5iVG9rZW5zVG9Mb2NrOw0KICAgICAgICAgIG9yZGVyLmV4cGlyYXRpb24gPSBleHBpcmF0aW9uID09PSB1bmRlZmluZWQgfHwgZXhwaXJhdGlvbiA+IDI1OTIwMDANCiAgICAgICAgICAgID8gdGltZXN0YW1wU2VjICsgMjU5MjAwMA0KICAgICAgICAgICAgOiB0aW1lc3RhbXBTZWMgKyBleHBpcmF0aW9uOw0KDQogICAgICAgICAgY29uc3Qgb3JkZXJJbkRiID0gYXdhaXQgYXBpLmRiLmluc2VydCgnYnV5Qm9vaycsIG9yZGVyKTsNCg0KICAgICAgICAgIGF3YWl0IGZpbmRNYXRjaGluZ1NlbGxPcmRlcnMob3JkZXJJbkRiLCB0b2tlbi5wcmVjaXNpb24pOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KICB9DQp9Ow0KDQphY3Rpb25zLnNlbGwgPSBhc3luYyAocGF5bG9hZCkgPT4gew0KICBjb25zdCB7DQogICAgc3ltYm9sLA0KICAgIHF1YW50aXR5LA0KICAgIHByaWNlLA0KICAgIGV4cGlyYXRpb24sDQogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LA0KICB9ID0gcGF5bG9hZDsNCiAgLy8gc2VsbCAocXVhbnRpdHkpIG9mIChzeW1ib2wpIGF0IChwcmljZSkoU1RFRU1fUEVHR0VEX1NZTUJPTCkgcGVyIChzeW1ib2wpDQogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpDQogICAgJiYgYXBpLmFzc2VydChwcmljZSAmJiB0eXBlb2YgcHJpY2UgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHByaWNlKS5pc05hTigpDQogICAgICAmJiBzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycgJiYgc3ltYm9sICE9PSBTVEVFTV9QRUdHRURfU1lNQk9MDQogICAgICAmJiBxdWFudGl0eSAmJiB0eXBlb2YgcXVhbnRpdHkgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS5pc05hTigpDQogICAgICAmJiAoZXhwaXJhdGlvbiA9PT0gdW5kZWZpbmVkIHx8IChleHBpcmF0aW9uICYmIE51bWJlci5pc0ludGVnZXIoZXhwaXJhdGlvbikgJiYgZXhwaXJhdGlvbiA+IDApKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsNCiAgICAvLyBnZXQgdGhlIHRva2VuIHBhcmFtcw0KICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywgeyBzeW1ib2wgfSk7DQoNCiAgICAvLyBwZXJmb3JtIGEgZmV3IHZlcmlmaWNhdGlvbnMNCiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbg0KICAgICAgJiYgYXBpLkJpZ051bWJlcihwcmljZSkuZ3QoMCkNCiAgICAgICYmIGNvdW50RGVjaW1hbHMocHJpY2UpIDw9IFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9ODQogICAgICAmJiBjb3VudERlY2ltYWxzKHF1YW50aXR5KSA8PSB0b2tlbi5wcmVjaXNpb24sICdpbnZhbGlkIHBhcmFtcycpKSB7DQogICAgICBjb25zdCBuYlRva2Vuc1RvRmlsbE9yZGVyID0gYXBpLkJpZ051bWJlcihwcmljZSkNCiAgICAgICAgLm11bHRpcGxpZWRCeShxdWFudGl0eSkNCiAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KDQogICAgICBpZiAoYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKG5iVG9rZW5zVG9GaWxsT3JkZXIpLmd0ZSgnMC4wMDAwMDAwMScpLCAnb3JkZXIgY2Fubm90IGJlIHBsYWNlZCBhcyBpdCBjYW5ub3QgYmUgZmlsbGVkJykpIHsNCiAgICAgICAgLy8gaW5pdGlhdGUgYSB0cmFuc2ZlciBmcm9tIGFwaS5zZW5kZXIgdG8gY29udHJhY3QgYmFsYW5jZQ0KICAgICAgICAvLyBsb2NrIHN5bWJvbCB0b2tlbnMNCiAgICAgICAgY29uc3QgcmVzID0gYXdhaXQgYXBpLmV4ZWN1dGVTbWFydENvbnRyYWN0KCd0b2tlbnMnLCAndHJhbnNmZXJUb0NvbnRyYWN0JywgeyBzeW1ib2wsIHF1YW50aXR5LCB0bzogQ09OVFJBQ1RfTkFNRSB9KTsNCg0KICAgICAgICBpZiAocmVzLmVycm9ycyA9PT0gdW5kZWZpbmVkDQogICAgICAgICAgJiYgcmVzLmV2ZW50cyAmJiByZXMuZXZlbnRzLmZpbmQoZWwgPT4gZWwuY29udHJhY3QgPT09ICd0b2tlbnMnICYmIGVsLmV2ZW50ID09PSAndHJhbnNmZXJUb0NvbnRyYWN0JyAmJiBlbC5kYXRhLmZyb20gPT09IGFwaS5zZW5kZXIgJiYgZWwuZGF0YS50byA9PT0gQ09OVFJBQ1RfTkFNRSAmJiBlbC5kYXRhLnF1YW50aXR5ID09PSBxdWFudGl0eSAmJiBlbC5kYXRhLnN5bWJvbCA9PT0gc3ltYm9sKSAhPT0gdW5kZWZpbmVkKSB7DQogICAgICAgICAgY29uc3QgdGltZXN0YW1wU2VjID0gYXBpLkJpZ051bWJlcihuZXcgRGF0ZShgJHthcGkuc3RlZW1CbG9ja1RpbWVzdGFtcH0uMDAwWmApLmdldFRpbWUoKSkNCiAgICAgICAgICAgIC5kaXZpZGVkQnkoMTAwMCkNCiAgICAgICAgICAgIC50b051bWJlcigpOw0KDQogICAgICAgICAgLy8gb3JkZXINCiAgICAgICAgICBjb25zdCBvcmRlciA9IHt9Ow0KDQogICAgICAgICAgb3JkZXIudHhJZCA9IGFwaS50cmFuc2FjdGlvbklkOw0KICAgICAgICAgIG9yZGVyLnRpbWVzdGFtcCA9IHRpbWVzdGFtcFNlYzsNCiAgICAgICAgICBvcmRlci5hY2NvdW50ID0gYXBpLnNlbmRlcjsNCiAgICAgICAgICBvcmRlci5zeW1ib2wgPSBzeW1ib2w7DQogICAgICAgICAgb3JkZXIucXVhbnRpdHkgPSBhcGkuQmlnTnVtYmVyKHF1YW50aXR5KS50b0ZpeGVkKHRva2VuLnByZWNpc2lvbik7DQogICAgICAgICAgb3JkZXIucHJpY2UgPSBhcGkuQmlnTnVtYmVyKHByaWNlKS50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OKTsNCiAgICAgICAgICBvcmRlci5wcmljZURlYyA9IHsgJG51bWJlckRlY2ltYWw6IG9yZGVyLnByaWNlIH07DQogICAgICAgICAgb3JkZXIuZXhwaXJhdGlvbiA9IGV4cGlyYXRpb24gPT09IHVuZGVmaW5lZCB8fCBleHBpcmF0aW9uID4gMjU5MjAwMA0KICAgICAgICAgICAgPyB0aW1lc3RhbXBTZWMgKyAyNTkyMDAwDQogICAgICAgICAgICA6IHRpbWVzdGFtcFNlYyArIGV4cGlyYXRpb247DQoNCiAgICAgICAgICBjb25zdCBvcmRlckluRGIgPSBhd2FpdCBhcGkuZGIuaW5zZXJ0KCdzZWxsQm9vaycsIG9yZGVyKTsNCg0KICAgICAgICAgIGF3YWl0IGZpbmRNYXRjaGluZ0J1eU9yZGVycyhvcmRlckluRGIsIHRva2VuLnByZWNpc2lvbik7DQogICAgICAgIH0NCiAgICAgIH0NCiAgICB9DQogIH0NCn07DQoNCmFjdGlvbnMubWFya2V0QnV5ID0gYXN5bmMgKHBheWxvYWQpID0+IHsNCiAgY29uc3Qgew0KICAgIHN5bWJvbCwNCiAgICBxdWFudGl0eSwNCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksDQogIH0gPSBwYXlsb2FkOw0KDQogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpDQogICAgJiYgc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnICYmIHN5bWJvbCAhPT0gU1RFRU1fUEVHR0VEX1NZTUJPTA0KICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCkgJiYgYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCkpIHsNCiAgICAvLyBnZXQgdGhlIHRva2VuIHBhcmFtcw0KICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywgeyBzeW1ib2wgfSk7DQoNCiAgICAvLyBwZXJmb3JtIGEgZmV3IHZlcmlmaWNhdGlvbnMNCiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbg0KICAgICAgJiYgY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04sICdpbnZhbGlkIHBhcmFtcycpKSB7DQogICAgICAvLyBpbml0aWF0ZSBhIHRyYW5zZmVyIGZyb20gYXBpLnNlbmRlciB0byBjb250cmFjdCBiYWxhbmNlDQogICAgICAvLyBsb2NrIFNURUVNX1BFR0dFRF9TWU1CT0wgdG9rZW5zDQogICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ3Rva2VucycsICd0cmFuc2ZlclRvQ29udHJhY3QnLCB7IHN5bWJvbDogU1RFRU1fUEVHR0VEX1NZTUJPTCwgcXVhbnRpdHksIHRvOiBDT05UUkFDVF9OQU1FIH0pOw0KDQogICAgICBpZiAocmVzdWx0LmVycm9ycyA9PT0gdW5kZWZpbmVkDQogICAgICAgICYmIHJlc3VsdC5ldmVudHMgJiYgcmVzdWx0LmV2ZW50cy5maW5kKGVsID0+IGVsLmNvbnRyYWN0ID09PSAndG9rZW5zJyAmJiBlbC5ldmVudCA9PT0gJ3RyYW5zZmVyVG9Db250cmFjdCcgJiYgZWwuZGF0YS5mcm9tID09PSBhcGkuc2VuZGVyICYmIGVsLmRhdGEudG8gPT09IENPTlRSQUNUX05BTUUgJiYgZWwuZGF0YS5xdWFudGl0eSA9PT0gcXVhbnRpdHkgJiYgZWwuZGF0YS5zeW1ib2wgPT09IFNURUVNX1BFR0dFRF9TWU1CT0wpICE9PSB1bmRlZmluZWQpIHsNCiAgICAgICAgbGV0IHN0ZWVtcFJlbWFpbmluZyA9IHF1YW50aXR5Ow0KICAgICAgICBsZXQgb2Zmc2V0ID0gMDsNCiAgICAgICAgbGV0IHZvbHVtZVRyYWRlZCA9IDA7DQoNCiAgICAgICAgYXdhaXQgcmVtb3ZlRXhwaXJlZE9yZGVycygnc2VsbEJvb2snKTsNCg0KICAgICAgICAvLyBnZXQgdGhlIG9yZGVycyB0aGF0IG1hdGNoIHRoZSBzeW1ib2wgYW5kIHRoZSBwcmljZQ0KICAgICAgICBsZXQgc2VsbE9yZGVyQm9vayA9IGF3YWl0IGFwaS5kYi5maW5kKCdzZWxsQm9vaycsIHsNCiAgICAgICAgICBzeW1ib2wsDQogICAgICAgIH0sIDEwMDAsIG9mZnNldCwNCiAgICAgICAgWw0KICAgICAgICAgIHsgaW5kZXg6ICdwcmljZURlYycsIGRlc2NlbmRpbmc6IGZhbHNlIH0sDQogICAgICAgICAgeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH0sDQogICAgICAgIF0pOw0KDQogICAgICAgIGRvIHsNCiAgICAgICAgICBjb25zdCBuYk9yZGVycyA9IHNlbGxPcmRlckJvb2subGVuZ3RoOw0KICAgICAgICAgIGxldCBpbmMgPSAwOw0KDQogICAgICAgICAgd2hpbGUgKGluYyA8IG5iT3JkZXJzICYmIGFwaS5CaWdOdW1iZXIoc3RlZW1wUmVtYWluaW5nKS5ndCgwKSkgew0KICAgICAgICAgICAgY29uc3Qgc2VsbE9yZGVyID0gc2VsbE9yZGVyQm9va1tpbmNdOw0KICAgICAgICAgICAgY29uc3QgcXR5VG9rZW5zVG9TZW5kID0gYXBpLkJpZ051bWJlcihzdGVlbXBSZW1haW5pbmcpDQogICAgICAgICAgICAgIC5kaXZpZGVkQnkoc2VsbE9yZGVyLnByaWNlKQ0KICAgICAgICAgICAgICAudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24sIGFwaS5CaWdOdW1iZXIuUk9VTkRfRE9XTik7DQoNCiAgICAgICAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHF0eVRva2Vuc1RvU2VuZCkubHRlKHNlbGxPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAgICAgJiYgYXBpLkJpZ051bWJlcihxdHlUb2tlbnNUb1NlbmQpLmd0KDApKSB7DQogICAgICAgICAgICAgIGlmIChhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIocXR5VG9rZW5zVG9TZW5kKS5ndCgwKQ0KICAgICAgICAgICAgICAgICYmIGFwaS5CaWdOdW1iZXIoc3RlZW1wUmVtYWluaW5nKS5ndCgwKSwgJ3RoZSBvcmRlciBjYW5ub3QgYmUgZmlsbGVkJykpIHsNCiAgICAgICAgICAgICAgICAvLyB0cmFuc2ZlciB0aGUgdG9rZW5zIHRvIHRoZSBidXllcg0KICAgICAgICAgICAgICAgIGxldCByZXMgPSBhd2FpdCBhcGkudHJhbnNmZXJUb2tlbnMoYXBpLnNlbmRlciwgc3ltYm9sLCBxdHlUb2tlbnNUb1NlbmQsICd1c2VyJyk7DQoNCiAgICAgICAgICAgICAgICBpZiAocmVzLmVycm9ycykgew0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKHJlcy5lcnJvcnMpOw0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKGBUWElEOiAke2FwaS50cmFuc2FjdGlvbklkfWApOw0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKGFwaS5zZW5kZXIpOw0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKHN5bWJvbCk7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcocXR5VG9rZW5zVG9TZW5kKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyB0cmFuc2ZlciB0aGUgdG9rZW5zIHRvIHRoZSBzZWxsZXINCiAgICAgICAgICAgICAgICByZXMgPSBhd2FpdCBhcGkudHJhbnNmZXJUb2tlbnMoc2VsbE9yZGVyLmFjY291bnQsIFNURUVNX1BFR0dFRF9TWU1CT0wsIHN0ZWVtcFJlbWFpbmluZywgJ3VzZXInKTsNCg0KICAgICAgICAgICAgICAgIGlmIChyZXMuZXJyb3JzKSB7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcocmVzLmVycm9ycyk7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcoYFRYSUQ6ICR7YXBpLnRyYW5zYWN0aW9uSWR9YCk7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcoc2VsbE9yZGVyLmFjY291bnQpOw0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKFNURUVNX1BFR0dFRF9TWU1CT0wpOw0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKHN0ZWVtcFJlbWFpbmluZyk7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSBzZWxsIG9yZGVyDQogICAgICAgICAgICAgICAgY29uc3QgcXR5TGVmdFNlbGxPcmRlciA9IGFwaS5CaWdOdW1iZXIoc2VsbE9yZGVyLnF1YW50aXR5KQ0KICAgICAgICAgICAgICAgICAgLm1pbnVzKHF0eVRva2Vuc1RvU2VuZCkNCiAgICAgICAgICAgICAgICAgIC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbik7DQogICAgICAgICAgICAgICAgY29uc3QgbmJUb2tlbnNUb0ZpbGxPcmRlciA9IGFwaS5CaWdOdW1iZXIoc2VsbE9yZGVyLnByaWNlKQ0KICAgICAgICAgICAgICAgICAgLm11bHRpcGxpZWRCeShxdHlMZWZ0U2VsbE9yZGVyKQ0KICAgICAgICAgICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KDQogICAgICAgICAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIocXR5TGVmdFNlbGxPcmRlcikuZ3QoMCkNCiAgICAgICAgICAgICAgICAgICYmIChhcGkuQmlnTnVtYmVyKG5iVG9rZW5zVG9GaWxsT3JkZXIpLmd0ZSgnMC4wMDAwMDAwMScpKSkgew0KICAgICAgICAgICAgICAgICAgc2VsbE9yZGVyLnF1YW50aXR5ID0gcXR5TGVmdFNlbGxPcmRlcjsNCg0KICAgICAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnVwZGF0ZSgnc2VsbEJvb2snLCBzZWxsT3JkZXIpOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcihxdHlMZWZ0U2VsbE9yZGVyKS5ndCgwKSkgew0KICAgICAgICAgICAgICAgICAgICBhd2FpdCBhcGkudHJhbnNmZXJUb2tlbnMoc2VsbE9yZGVyLmFjY291bnQsIHN5bWJvbCwgcXR5TGVmdFNlbGxPcmRlciwgJ3VzZXInKTsNCiAgICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICAgIGF3YWl0IGFwaS5kYi5yZW1vdmUoJ3NlbGxCb29rJywgc2VsbE9yZGVyKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyBhZGQgdGhlIHRyYWRlIHRvIHRoZSBoaXN0b3J5DQogICAgICAgICAgICAgICAgYXdhaXQgdXBkYXRlVHJhZGVzSGlzdG9yeSgnYnV5JywgYXBpLnNlbmRlciwgc2VsbE9yZGVyLmFjY291bnQsIHN5bWJvbCwgcXR5VG9rZW5zVG9TZW5kLCBzZWxsT3JkZXIucHJpY2UsIHN0ZWVtcFJlbWFpbmluZyk7DQoNCiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgdGhlIHZvbHVtZQ0KICAgICAgICAgICAgICAgIHZvbHVtZVRyYWRlZCA9IGFwaS5CaWdOdW1iZXIodm9sdW1lVHJhZGVkKS5wbHVzKHN0ZWVtcFJlbWFpbmluZyk7DQoNCiAgICAgICAgICAgICAgICBzdGVlbXBSZW1haW5pbmcgPSAnMCc7DQogICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSBpZiAoYXBpLkJpZ051bWJlcihxdHlUb2tlbnNUb1NlbmQpLmd0KDApKSB7DQogICAgICAgICAgICAgIGxldCBxdHlTdGVlbXBUb1NlbmQgPSBhcGkuQmlnTnVtYmVyKHNlbGxPcmRlci5wcmljZSkNCiAgICAgICAgICAgICAgICAubXVsdGlwbGllZEJ5KHNlbGxPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAgICAgICAudG9GaXhlZChTVEVFTV9QRUdHRURfU1lNQk9MX1BSRVNJQ0lPTik7DQoNCiAgICAgICAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIocXR5U3RlZW1wVG9TZW5kKS5ndChzdGVlbXBSZW1haW5pbmcpKSB7DQogICAgICAgICAgICAgICAgcXR5U3RlZW1wVG9TZW5kID0gYXBpLkJpZ051bWJlcihzZWxsT3JkZXIucHJpY2UpDQogICAgICAgICAgICAgICAgICAubXVsdGlwbGllZEJ5KHNlbGxPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAgICAgICAgIC50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOw0KICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdHlTdGVlbXBUb1NlbmQpLmd0KDApDQogICAgICAgICAgICAgICAgJiYgYXBpLkJpZ051bWJlcihzdGVlbXBSZW1haW5pbmcpLmd0KDApLCAndGhlIG9yZGVyIGNhbm5vdCBiZSBmaWxsZWQnKSkgew0KICAgICAgICAgICAgICAgIC8vIHRyYW5zZmVyIHRoZSB0b2tlbnMgdG8gdGhlIGJ1eWVyDQogICAgICAgICAgICAgICAgbGV0IHJlcyA9IGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhhcGkuc2VuZGVyLCBzeW1ib2wsIHNlbGxPcmRlci5xdWFudGl0eSwgJ3VzZXInKTsNCg0KICAgICAgICAgICAgICAgIGlmIChyZXMuZXJyb3JzKSB7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcocmVzLmVycm9ycyk7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcoYFRYSUQ6ICR7YXBpLnRyYW5zYWN0aW9uSWR9YCk7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcoYXBpLnNlbmRlcik7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcoc3ltYm9sKTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhzZWxsT3JkZXIucXVhbnRpdHkpOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIC8vIHRyYW5zZmVyIHRoZSB0b2tlbnMgdG8gdGhlIHNlbGxlcg0KICAgICAgICAgICAgICAgIHJlcyA9IGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhzZWxsT3JkZXIuYWNjb3VudCwgU1RFRU1fUEVHR0VEX1NZTUJPTCwgcXR5U3RlZW1wVG9TZW5kLCAndXNlcicpOw0KDQogICAgICAgICAgICAgICAgaWYgKHJlcy5lcnJvcnMpIHsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhyZXMuZXJyb3JzKTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhgVFhJRDogJHthcGkudHJhbnNhY3Rpb25JZH1gKTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhzZWxsT3JkZXIuYWNjb3VudCk7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcoU1RFRU1fUEVHR0VEX1NZTUJPTCk7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcocXR5U3RlZW1wVG9TZW5kKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyByZW1vdmUgdGhlIHNlbGwgb3JkZXINCiAgICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdzZWxsQm9vaycsIHNlbGxPcmRlcik7DQoNCiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgdG9rZW5zTG9ja2VkIGFuZCB0aGUgcXVhbnRpdHkgdG8gZ2V0DQogICAgICAgICAgICAgICAgc3RlZW1wUmVtYWluaW5nID0gYXBpLkJpZ051bWJlcihzdGVlbXBSZW1haW5pbmcpDQogICAgICAgICAgICAgICAgICAubWludXMocXR5U3RlZW1wVG9TZW5kKQ0KICAgICAgICAgICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KDQogICAgICAgICAgICAgICAgLy8gYWRkIHRoZSB0cmFkZSB0byB0aGUgaGlzdG9yeQ0KICAgICAgICAgICAgICAgIGF3YWl0IHVwZGF0ZVRyYWRlc0hpc3RvcnkoJ2J1eScsIGFwaS5zZW5kZXIsIHNlbGxPcmRlci5hY2NvdW50LCBzeW1ib2wsIHNlbGxPcmRlci5xdWFudGl0eSwgc2VsbE9yZGVyLnByaWNlLCBxdHlTdGVlbXBUb1NlbmQpOw0KDQogICAgICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSB2b2x1bWUNCiAgICAgICAgICAgICAgICB2b2x1bWVUcmFkZWQgPSBhcGkuQmlnTnVtYmVyKHZvbHVtZVRyYWRlZCkucGx1cyhxdHlTdGVlbXBUb1NlbmQpOw0KICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGluYyArPSAxOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIG9mZnNldCArPSAxMDAwOw0KDQogICAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIoc3RlZW1wUmVtYWluaW5nKS5ndCgwKSkgew0KICAgICAgICAgICAgLy8gZ2V0IHRoZSBvcmRlcnMgdGhhdCBtYXRjaCB0aGUgc3ltYm9sIGFuZCB0aGUgcHJpY2UNCiAgICAgICAgICAgIHNlbGxPcmRlckJvb2sgPSBhd2FpdCBhcGkuZGIuZmluZCgnc2VsbEJvb2snLCB7DQogICAgICAgICAgICAgIHN5bWJvbCwNCiAgICAgICAgICAgIH0sIDEwMDAsIG9mZnNldCwNCiAgICAgICAgICAgIFsNCiAgICAgICAgICAgICAgeyBpbmRleDogJ3ByaWNlRGVjJywgZGVzY2VuZGluZzogZmFsc2UgfSwNCiAgICAgICAgICAgICAgeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH0sDQogICAgICAgICAgICBdKTsNCiAgICAgICAgICB9DQogICAgICAgIH0gd2hpbGUgKHNlbGxPcmRlckJvb2subGVuZ3RoID4gMCAmJiBhcGkuQmlnTnVtYmVyKHN0ZWVtcFJlbWFpbmluZykuZ3QoMCkpOw0KDQogICAgICAgIC8vIHVwZGF0ZSB0aGUgYnV5IG9yZGVyIGlmIHBhcnRpYWxseSBmaWxsZWQNCiAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIoc3RlZW1wUmVtYWluaW5nKS5ndCgwKSkgew0KICAgICAgICAgIGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhhcGkuc2VuZGVyLCBTVEVFTV9QRUdHRURfU1lNQk9MLCBzdGVlbXBSZW1haW5pbmcsICd1c2VyJyk7DQogICAgICAgIH0NCiAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIodm9sdW1lVHJhZGVkKS5ndCgwKSkgew0KICAgICAgICAgIGF3YWl0IHVwZGF0ZVZvbHVtZU1ldHJpYyhzeW1ib2wsIHZvbHVtZVRyYWRlZCk7DQogICAgICAgIH0NCiAgICAgICAgYXdhaXQgdXBkYXRlQXNrTWV0cmljKHN5bWJvbCk7DQogICAgICAgIGF3YWl0IHVwZGF0ZUJpZE1ldHJpYyhzeW1ib2wpOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KfTsNCg0KYWN0aW9ucy5tYXJrZXRTZWxsID0gYXN5bmMgKHBheWxvYWQpID0+IHsNCiAgY29uc3Qgew0KICAgIHN5bWJvbCwNCiAgICBxdWFudGl0eSwNCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksDQogIH0gPSBwYXlsb2FkOw0KDQogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpDQogICAgJiYgc3ltYm9sICYmIHR5cGVvZiBzeW1ib2wgPT09ICdzdHJpbmcnICYmIHN5bWJvbCAhPT0gU1RFRU1fUEVHR0VEX1NZTUJPTA0KICAgICYmIHF1YW50aXR5ICYmIHR5cGVvZiBxdWFudGl0eSA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIocXVhbnRpdHkpLmlzTmFOKCkgJiYgYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QoMCkpIHsNCiAgICAvLyBnZXQgdGhlIHRva2VuIHBhcmFtcw0KICAgIGNvbnN0IHRva2VuID0gYXdhaXQgYXBpLmRiLmZpbmRPbmVJblRhYmxlKCd0b2tlbnMnLCAndG9rZW5zJywgeyBzeW1ib2wgfSk7DQoNCiAgICAvLyBwZXJmb3JtIGEgZmV3IHZlcmlmaWNhdGlvbnMNCiAgICBpZiAoYXBpLmFzc2VydCh0b2tlbg0KICAgICAgJiYgY291bnREZWNpbWFscyhxdWFudGl0eSkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnaW52YWxpZCBwYXJhbXMnKSkgew0KICAgICAgLy8gaW5pdGlhdGUgYSB0cmFuc2ZlciBmcm9tIGFwaS5zZW5kZXIgdG8gY29udHJhY3QgYmFsYW5jZQ0KICAgICAgLy8gbG9jayBzeW1ib2wgdG9rZW5zDQogICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ3Rva2VucycsICd0cmFuc2ZlclRvQ29udHJhY3QnLCB7IHN5bWJvbCwgcXVhbnRpdHksIHRvOiBDT05UUkFDVF9OQU1FIH0pOw0KDQogICAgICBpZiAocmVzdWx0LmVycm9ycyA9PT0gdW5kZWZpbmVkDQogICAgICAgICYmIHJlc3VsdC5ldmVudHMgJiYgcmVzdWx0LmV2ZW50cy5maW5kKGVsID0+IGVsLmNvbnRyYWN0ID09PSAndG9rZW5zJyAmJiBlbC5ldmVudCA9PT0gJ3RyYW5zZmVyVG9Db250cmFjdCcgJiYgZWwuZGF0YS5mcm9tID09PSBhcGkuc2VuZGVyICYmIGVsLmRhdGEudG8gPT09IENPTlRSQUNUX05BTUUgJiYgZWwuZGF0YS5xdWFudGl0eSA9PT0gcXVhbnRpdHkgJiYgZWwuZGF0YS5zeW1ib2wgPT09IHN5bWJvbCkgIT09IHVuZGVmaW5lZCkgew0KICAgICAgICBsZXQgdG9rZW5zUmVtYWluaW5nID0gcXVhbnRpdHk7DQogICAgICAgIGxldCBvZmZzZXQgPSAwOw0KICAgICAgICBsZXQgdm9sdW1lVHJhZGVkID0gMDsNCg0KICAgICAgICBhd2FpdCByZW1vdmVFeHBpcmVkT3JkZXJzKCdidXlCb29rJyk7DQoNCiAgICAgICAgLy8gZ2V0IHRoZSBvcmRlcnMgdGhhdCBtYXRjaCB0aGUgc3ltYm9sDQogICAgICAgIGxldCBidXlPcmRlckJvb2sgPSBhd2FpdCBhcGkuZGIuZmluZCgnYnV5Qm9vaycsIHsNCiAgICAgICAgICBzeW1ib2wsDQogICAgICAgIH0sIDEwMDAsIG9mZnNldCwNCiAgICAgICAgWw0KICAgICAgICAgIHsgaW5kZXg6ICdwcmljZURlYycsIGRlc2NlbmRpbmc6IHRydWUgfSwNCiAgICAgICAgICB7IGluZGV4OiAnX2lkJywgZGVzY2VuZGluZzogZmFsc2UgfSwNCiAgICAgICAgXSk7DQoNCiAgICAgICAgZG8gew0KICAgICAgICAgIGNvbnN0IG5iT3JkZXJzID0gYnV5T3JkZXJCb29rLmxlbmd0aDsNCiAgICAgICAgICBsZXQgaW5jID0gMDsNCg0KICAgICAgICAgIHdoaWxlIChpbmMgPCBuYk9yZGVycyAmJiBhcGkuQmlnTnVtYmVyKHRva2Vuc1JlbWFpbmluZykuZ3QoMCkpIHsNCiAgICAgICAgICAgIGNvbnN0IGJ1eU9yZGVyID0gYnV5T3JkZXJCb29rW2luY107DQogICAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcih0b2tlbnNSZW1haW5pbmcpLmx0ZShidXlPcmRlci5xdWFudGl0eSkpIHsNCiAgICAgICAgICAgICAgbGV0IHF0eVRva2Vuc1RvU2VuZCA9IGFwaS5CaWdOdW1iZXIoYnV5T3JkZXIucHJpY2UpDQogICAgICAgICAgICAgICAgLm11bHRpcGxpZWRCeSh0b2tlbnNSZW1haW5pbmcpDQogICAgICAgICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KDQogICAgICAgICAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHF0eVRva2Vuc1RvU2VuZCkuZ3QoYnV5T3JkZXIudG9rZW5zTG9ja2VkKSkgew0KICAgICAgICAgICAgICAgIHF0eVRva2Vuc1RvU2VuZCA9IGFwaS5CaWdOdW1iZXIoYnV5T3JkZXIucHJpY2UpDQogICAgICAgICAgICAgICAgICAubXVsdGlwbGllZEJ5KHRva2Vuc1JlbWFpbmluZykNCiAgICAgICAgICAgICAgICAgIC50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOw0KICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdHlUb2tlbnNUb1NlbmQpLmd0KDApDQogICAgICAgICAgICAgICAgJiYgYXBpLkJpZ051bWJlcih0b2tlbnNSZW1haW5pbmcpLmd0KDApLCAndGhlIG9yZGVyIGNhbm5vdCBiZSBmaWxsZWQnKSkgew0KICAgICAgICAgICAgICAgIC8vIHRyYW5zZmVyIHRoZSB0b2tlbnMgdG8gdGhlIGJ1eWVyDQogICAgICAgICAgICAgICAgbGV0IHJlcyA9IGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhidXlPcmRlci5hY2NvdW50LCBzeW1ib2wsIHRva2Vuc1JlbWFpbmluZywgJ3VzZXInKTsNCg0KICAgICAgICAgICAgICAgIGlmIChyZXMuZXJyb3JzKSB7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcocmVzLmVycm9ycyk7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcoYFRYSUQ6ICR7YXBpLnRyYW5zYWN0aW9uSWR9YCk7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcoYnV5T3JkZXIuYWNjb3VudCk7DQogICAgICAgICAgICAgICAgICBhcGkuZGVidWcoc3ltYm9sKTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1Zyh0b2tlbnNSZW1haW5pbmcpOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIC8vIHRyYW5zZmVyIHRoZSB0b2tlbnMgdG8gdGhlIHNlbGxlcg0KICAgICAgICAgICAgICAgIHJlcyA9IGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhhcGkuc2VuZGVyLCBTVEVFTV9QRUdHRURfU1lNQk9MLCBxdHlUb2tlbnNUb1NlbmQsICd1c2VyJyk7DQoNCiAgICAgICAgICAgICAgICBpZiAocmVzLmVycm9ycykgew0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKHJlcy5lcnJvcnMpOw0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKGBUWElEOiAke2FwaS50cmFuc2FjdGlvbklkfWApOw0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKGFwaS5zZW5kZXIpOw0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKFNURUVNX1BFR0dFRF9TWU1CT0wpOw0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKHF0eVRva2Vuc1RvU2VuZCk7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSBidXkgb3JkZXINCiAgICAgICAgICAgICAgICBjb25zdCBxdHlMZWZ0QnV5T3JkZXIgPSBhcGkuQmlnTnVtYmVyKGJ1eU9yZGVyLnF1YW50aXR5KQ0KICAgICAgICAgICAgICAgICAgLm1pbnVzKHRva2Vuc1JlbWFpbmluZykNCiAgICAgICAgICAgICAgICAgIC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbik7DQoNCiAgICAgICAgICAgICAgICBjb25zdCBidXlPcmRlcnRva2Vuc0xvY2tlZCA9IGFwaS5CaWdOdW1iZXIoYnV5T3JkZXIudG9rZW5zTG9ja2VkKQ0KICAgICAgICAgICAgICAgICAgLm1pbnVzKHF0eVRva2Vuc1RvU2VuZCkNCiAgICAgICAgICAgICAgICAgIC50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OKTsNCiAgICAgICAgICAgICAgICBjb25zdCBuYlRva2Vuc1RvRmlsbE9yZGVyID0gYXBpLkJpZ051bWJlcihidXlPcmRlci5wcmljZSkNCiAgICAgICAgICAgICAgICAgIC5tdWx0aXBsaWVkQnkocXR5TGVmdEJ1eU9yZGVyKQ0KICAgICAgICAgICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KDQogICAgICAgICAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIocXR5TGVmdEJ1eU9yZGVyKS5ndCgwKQ0KICAgICAgICAgICAgICAgICAgJiYgKGFwaS5CaWdOdW1iZXIobmJUb2tlbnNUb0ZpbGxPcmRlcikuZ3RlKCcwLjAwMDAwMDAxJykpKSB7DQogICAgICAgICAgICAgICAgICBidXlPcmRlci5xdWFudGl0eSA9IHF0eUxlZnRCdXlPcmRlcjsNCiAgICAgICAgICAgICAgICAgIGJ1eU9yZGVyLnRva2Vuc0xvY2tlZCA9IGJ1eU9yZGVydG9rZW5zTG9ja2VkOw0KDQogICAgICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdidXlCb29rJywgYnV5T3JkZXIpOw0KICAgICAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcihidXlPcmRlcnRva2Vuc0xvY2tlZCkuZ3QoMCkpIHsNCiAgICAgICAgICAgICAgICAgICAgYXdhaXQgYXBpLnRyYW5zZmVyVG9rZW5zKGJ1eU9yZGVyLmFjY291bnQsIFNURUVNX1BFR0dFRF9TWU1CT0wsIGJ1eU9yZGVydG9rZW5zTG9ja2VkLCAndXNlcicpOw0KICAgICAgICAgICAgICAgICAgfQ0KICAgICAgICAgICAgICAgICAgYXdhaXQgYXBpLmRiLnJlbW92ZSgnYnV5Qm9vaycsIGJ1eU9yZGVyKTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyBhZGQgdGhlIHRyYWRlIHRvIHRoZSBoaXN0b3J5DQogICAgICAgICAgICAgICAgYXdhaXQgdXBkYXRlVHJhZGVzSGlzdG9yeSgnc2VsbCcsIGJ1eU9yZGVyLmFjY291bnQsIGFwaS5zZW5kZXIsIHN5bWJvbCwgdG9rZW5zUmVtYWluaW5nLCBidXlPcmRlci5wcmljZSwgcXR5VG9rZW5zVG9TZW5kKTsNCg0KICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgdm9sdW1lDQogICAgICAgICAgICAgICAgdm9sdW1lVHJhZGVkID0gYXBpLkJpZ051bWJlcih2b2x1bWVUcmFkZWQpLnBsdXMocXR5VG9rZW5zVG9TZW5kKTsNCg0KICAgICAgICAgICAgICAgIHRva2Vuc1JlbWFpbmluZyA9IDA7DQogICAgICAgICAgICAgIH0NCiAgICAgICAgICAgIH0gZWxzZSB7DQogICAgICAgICAgICAgIGxldCBxdHlUb2tlbnNUb1NlbmQgPSBhcGkuQmlnTnVtYmVyKGJ1eU9yZGVyLnByaWNlKQ0KICAgICAgICAgICAgICAgIC5tdWx0aXBsaWVkQnkoYnV5T3JkZXIucXVhbnRpdHkpDQogICAgICAgICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KDQogICAgICAgICAgICAgIGlmIChxdHlUb2tlbnNUb1NlbmQgPiBidXlPcmRlci50b2tlbnNMb2NrZWQpIHsNCiAgICAgICAgICAgICAgICBxdHlUb2tlbnNUb1NlbmQgPSBhcGkuQmlnTnVtYmVyKGJ1eU9yZGVyLnByaWNlKQ0KICAgICAgICAgICAgICAgICAgLm11bHRpcGxpZWRCeShidXlPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAgICAgICAgIC50b0ZpeGVkKFNURUVNX1BFR0dFRF9TWU1CT0xfUFJFU0lDSU9OLCBhcGkuQmlnTnVtYmVyLlJPVU5EX0RPV04pOw0KICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihxdHlUb2tlbnNUb1NlbmQpLmd0KDApDQogICAgICAgICAgICAgICAgJiYgYXBpLkJpZ051bWJlcih0b2tlbnNSZW1haW5pbmcpLmd0KDApLCAndGhlIG9yZGVyIGNhbm5vdCBiZSBmaWxsZWQnKSkgew0KICAgICAgICAgICAgICAgIC8vIHRyYW5zZmVyIHRoZSB0b2tlbnMgdG8gdGhlIGJ1eWVyDQogICAgICAgICAgICAgICAgbGV0IHJlcyA9IGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhidXlPcmRlci5hY2NvdW50LCBzeW1ib2wsIGJ1eU9yZGVyLnF1YW50aXR5LCAndXNlcicpOw0KDQogICAgICAgICAgICAgICAgaWYgKHJlcy5lcnJvcnMpIHsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhyZXMuZXJyb3JzKTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhgVFhJRDogJHthcGkudHJhbnNhY3Rpb25JZH1gKTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhidXlPcmRlci5hY2NvdW50KTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhzeW1ib2wpOw0KICAgICAgICAgICAgICAgICAgYXBpLmRlYnVnKGJ1eU9yZGVyLnF1YW50aXR5KTsNCiAgICAgICAgICAgICAgICB9DQoNCiAgICAgICAgICAgICAgICAvLyB0cmFuc2ZlciB0aGUgdG9rZW5zIHRvIHRoZSBzZWxsZXINCiAgICAgICAgICAgICAgICByZXMgPSBhd2FpdCBhcGkudHJhbnNmZXJUb2tlbnMoYXBpLnNlbmRlciwgU1RFRU1fUEVHR0VEX1NZTUJPTCwgcXR5VG9rZW5zVG9TZW5kLCAndXNlcicpOw0KDQogICAgICAgICAgICAgICAgaWYgKHJlcy5lcnJvcnMpIHsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhyZXMuZXJyb3JzKTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhgVFhJRDogJHthcGkudHJhbnNhY3Rpb25JZH1gKTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhhcGkuc2VuZGVyKTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhTVEVFTV9QRUdHRURfU1lNQk9MKTsNCiAgICAgICAgICAgICAgICAgIGFwaS5kZWJ1ZyhxdHlUb2tlbnNUb1NlbmQpOw0KICAgICAgICAgICAgICAgIH0NCg0KICAgICAgICAgICAgICAgIGNvbnN0IGJ1eU9yZGVydG9rZW5zTG9ja2VkID0gYXBpLkJpZ051bWJlcihidXlPcmRlci50b2tlbnNMb2NrZWQpDQogICAgICAgICAgICAgICAgICAubWludXMocXR5VG9rZW5zVG9TZW5kKQ0KICAgICAgICAgICAgICAgICAgLnRvRml4ZWQoU1RFRU1fUEVHR0VEX1NZTUJPTF9QUkVTSUNJT04pOw0KDQogICAgICAgICAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIoYnV5T3JkZXJ0b2tlbnNMb2NrZWQpLmd0KDApKSB7DQogICAgICAgICAgICAgICAgICBhd2FpdCBhcGkudHJhbnNmZXJUb2tlbnMoYnV5T3JkZXIuYWNjb3VudCwgU1RFRU1fUEVHR0VEX1NZTUJPTCwgYnV5T3JkZXJ0b2tlbnNMb2NrZWQsICd1c2VyJyk7DQogICAgICAgICAgICAgICAgfQ0KDQogICAgICAgICAgICAgICAgLy8gcmVtb3ZlIHRoZSBidXkgb3JkZXINCiAgICAgICAgICAgICAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdidXlCb29rJywgYnV5T3JkZXIpOw0KDQogICAgICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSBxdWFudGl0eSB0byBnZXQNCiAgICAgICAgICAgICAgICB0b2tlbnNSZW1haW5pbmcgPSBhcGkuQmlnTnVtYmVyKHRva2Vuc1JlbWFpbmluZykNCiAgICAgICAgICAgICAgICAgIC5taW51cyhidXlPcmRlci5xdWFudGl0eSkNCiAgICAgICAgICAgICAgICAgIC50b0ZpeGVkKHRva2VuLnByZWNpc2lvbik7DQoNCiAgICAgICAgICAgICAgICAvLyBhZGQgdGhlIHRyYWRlIHRvIHRoZSBoaXN0b3J5DQogICAgICAgICAgICAgICAgYXdhaXQgdXBkYXRlVHJhZGVzSGlzdG9yeSgnc2VsbCcsIGJ1eU9yZGVyLmFjY291bnQsIGFwaS5zZW5kZXIsIHN5bWJvbCwgYnV5T3JkZXIucXVhbnRpdHksIGJ1eU9yZGVyLnByaWNlLCBxdHlUb2tlbnNUb1NlbmQpOw0KDQogICAgICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSB2b2x1bWUNCiAgICAgICAgICAgICAgICB2b2x1bWVUcmFkZWQgPSBhcGkuQmlnTnVtYmVyKHZvbHVtZVRyYWRlZCkucGx1cyhxdHlUb2tlbnNUb1NlbmQpOw0KICAgICAgICAgICAgICB9DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIGluYyArPSAxOw0KICAgICAgICAgIH0NCg0KICAgICAgICAgIG9mZnNldCArPSAxMDAwOw0KDQogICAgICAgICAgaWYgKGFwaS5CaWdOdW1iZXIodG9rZW5zUmVtYWluaW5nKS5ndCgwKSkgew0KICAgICAgICAgICAgLy8gZ2V0IHRoZSBvcmRlcnMgdGhhdCBtYXRjaCB0aGUgc3ltYm9sIGFuZCB0aGUgcHJpY2UNCiAgICAgICAgICAgIGJ1eU9yZGVyQm9vayA9IGF3YWl0IGFwaS5kYi5maW5kKCdidXlCb29rJywgew0KICAgICAgICAgICAgICBzeW1ib2wsDQogICAgICAgICAgICB9LCAxMDAwLCBvZmZzZXQsDQogICAgICAgICAgICBbDQogICAgICAgICAgICAgIHsgaW5kZXg6ICdwcmljZURlYycsIGRlc2NlbmRpbmc6IHRydWUgfSwNCiAgICAgICAgICAgICAgeyBpbmRleDogJ19pZCcsIGRlc2NlbmRpbmc6IGZhbHNlIH0sDQogICAgICAgICAgICBdKTsNCiAgICAgICAgICB9DQogICAgICAgIH0gd2hpbGUgKGJ1eU9yZGVyQm9vay5sZW5ndGggPiAwICYmIGFwaS5CaWdOdW1iZXIodG9rZW5zUmVtYWluaW5nKS5ndCgwKSk7DQoNCiAgICAgICAgLy8gc2VuZCBiYWNrIHRoZSByZW1haW5pbmcgdG9rZW5zDQogICAgICAgIGlmIChhcGkuQmlnTnVtYmVyKHRva2Vuc1JlbWFpbmluZykuZ3QoMCkpIHsNCiAgICAgICAgICBhd2FpdCBhcGkudHJhbnNmZXJUb2tlbnMoYXBpLnNlbmRlciwgc3ltYm9sLCB0b2tlbnNSZW1haW5pbmcsICd1c2VyJyk7DQogICAgICAgIH0NCg0KICAgICAgICBpZiAoYXBpLkJpZ051bWJlcih2b2x1bWVUcmFkZWQpLmd0KDApKSB7DQogICAgICAgICAgYXdhaXQgdXBkYXRlVm9sdW1lTWV0cmljKHN5bWJvbCwgdm9sdW1lVHJhZGVkKTsNCiAgICAgICAgfQ0KICAgICAgICBhd2FpdCB1cGRhdGVBc2tNZXRyaWMoc3ltYm9sKTsNCiAgICAgICAgYXdhaXQgdXBkYXRlQmlkTWV0cmljKHN5bWJvbCk7DQogICAgICB9DQogICAgfQ0KICB9DQp9Ow0K"}}}