NFT Auction Smart Contract

in #hsc3 years ago

{"id":"ssc-testnet-hive","json":{"contractName":"contract","contractAction":"deploy","contractPayload":{"name":"nftauction","params":"","code":"LyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqLwovKiBnbG9iYWwgYWN0aW9ucywgYXBpICovCgpjb25zdCBVVElMSVRZX1RPS0VOX1NZTUJPTCA9ICdCRUUnOwpjb25zdCBNQVhfTlVNX1VOSVRTX09QRVJBQkxFID0gNTA7Cgpjb25zdCBDT05UUkFDVF9OQU1FID0gJ25mdGF1Y3Rpb24nOwoKYWN0aW9ucy5jcmVhdGVTU0MgPSBhc3luYyAoKSA9PiB7CiAgY29uc3QgdGFibGVFeGlzdHMgPSBhd2FpdCBhcGkuZGIudGFibGVFeGlzdHMoJ2F1Y3Rpb25zJyk7CiAgaWYgKHRhYmxlRXhpc3RzID09PSBmYWxzZSkgewogICAgYXdhaXQgYXBpLmRiLmNyZWF0ZVRhYmxlKCdhdWN0aW9ucycsIFsnYXVjdGlvbklkJywgJ3N5bWJvbCddKTsKICAgIGF3YWl0IGFwaS5kYi5jcmVhdGVUYWJsZSgncGFyYW1zJyk7CgogICAgY29uc3QgcGFyYW1zID0ge307CiAgICAvLyBmZWUgcmVxdWlyZWQgdG8gc2V0IHVwIGFuIGF1Y3Rpb24KICAgIHBhcmFtcy5jcmVhdGlvbkZlZSA9ICcxJzsKCiAgICAvLyBwZXJjZW50IGEgYmlkIG5lZWRzIHRvIGluY3JlYXNlIHRvIHRha2UgdGhlIGxlYWQKICAgIHBhcmFtcy5taW5CaWRJbmNyZW1lbnQgPSA1MDsgLy8gNSUKCiAgICAvLyB0aW1lIHJlbWFpbmluZyBpbiB0aGUgYXVjdGlvbiBzZXR0bGluZyB3aGVuIGNhbmNlbCBhY3Rpb24gaXMgbG9ja2VkCiAgICBwYXJhbXMuY2FuY2VsTG9ja1RpbWUgPSAzMDAwMDA7IC8vIDUgbWlucwoKICAgIC8vIHRpbWUgYWZ0ZXIgdGhlIGxhc3QgbGVhZCBiaWQgaXQgdGFrZXMgdG8gc2V0dGxlIHRoZSBhdWN0aW9uCiAgICBwYXJhbXMuZXhwaXJ5VGltZSA9IDg2NDAwMDAwOyAvLyAyNCBob3VycwoKICAgIC8vIG1heCB0aW1lIGFuIGF1Y3Rpb24gY2FuIHJ1bgogICAgcGFyYW1zLm1heEV4cGlyeVRpbWUgPSAyNTkyMDAwMDAwOyAvLyAzMCBkYXlzCgogICAgLy8gbWF4IGF1Y3Rpb25zIHRvIHNldHRsZSBwZXIgYmxvY2sKICAgIHBhcmFtcy5hdWN0aW9uc1BlckJsb2NrID0gMjsKICAgIGF3YWl0IGFwaS5kYi5pbnNlcnQoJ3BhcmFtcycsIHBhcmFtcyk7CiAgfQp9OwoKYWN0aW9ucy51cGRhdGVQYXJhbXMgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGlmIChhcGkuYXNzZXJ0KGFwaS5zZW5kZXIgPT09IGFwaS5vd25lciwgJ25vdCBhdXRob3JpemVkJykpIHsKICAgIGNvbnN0IHsKICAgICAgY3JlYXRpb25GZWUsCiAgICAgIG1pbkJpZEluY3JlbWVudCwKICAgICAgY2FuY2VsTG9ja1RpbWUsCiAgICAgIGV4cGlyeVRpbWUsCiAgICAgIG1heEV4cGlyeVRpbWUsCiAgICAgIGF1Y3Rpb25zUGVyQmxvY2ssCiAgICB9ID0gcGF5bG9hZDsKCiAgICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgncGFyYW1zJywge30pOwoKICAgIGlmIChjcmVhdGlvbkZlZSkgewogICAgICBpZiAoIWFwaS5hc3NlcnQodHlwZW9mIGNyZWF0aW9uRmVlID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihjcmVhdGlvbkZlZSkuaXNOYU4oKSAmJiBhcGkuQmlnTnVtYmVyKGNyZWF0aW9uRmVlKS5ndGUoMCksICdpbnZhbGlkIGNyZWF0aW9uRmVlJykpIHJldHVybjsKICAgICAgcGFyYW1zLmNyZWF0aW9uRmVlID0gY3JlYXRpb25GZWU7CiAgICB9CiAgICBpZiAobWluQmlkSW5jcmVtZW50KSB7CiAgICAgIGlmICghYXBpLmFzc2VydChOdW1iZXIuaXNJbnRlZ2VyKG1pbkJpZEluY3JlbWVudCkgJiYgbWluQmlkSW5jcmVtZW50ID4gMCwgJ2ludmFsaWQgbWluQmlkSW5jcmVtZW50JykpIHJldHVybjsKICAgICAgcGFyYW1zLm1pbkJpZEluY3JlbWVudCA9IG1pbkJpZEluY3JlbWVudDsKICAgIH0KICAgIGlmIChjYW5jZWxMb2NrVGltZSkgewogICAgICBpZiAoIWFwaS5hc3NlcnQoTnVtYmVyLmlzSW50ZWdlcihjYW5jZWxMb2NrVGltZSkgJiYgY2FuY2VsTG9ja1RpbWUgPiAwLCAnaW52YWxpZCBjYW5jZWxMb2NrVGltZScpKSByZXR1cm47CiAgICAgIHBhcmFtcy5jYW5jZWxMb2NrVGltZSA9IGNhbmNlbExvY2tUaW1lOwogICAgfQogICAgaWYgKGV4cGlyeVRpbWUpIHsKICAgICAgaWYgKCFhcGkuYXNzZXJ0KE51bWJlci5pc0ludGVnZXIoZXhwaXJ5VGltZSkgJiYgZXhwaXJ5VGltZSA+IDAsICdpbnZhbGlkIGV4cGlyeVRpbWUnKSkgcmV0dXJuOwogICAgICBwYXJhbXMuZXhwaXJ5VGltZSA9IGV4cGlyeVRpbWU7CiAgICB9CiAgICBpZiAobWF4RXhwaXJ5VGltZSkgewogICAgICBpZiAoIWFwaS5hc3NlcnQoTnVtYmVyLmlzSW50ZWdlcihtYXhFeHBpcnlUaW1lKSAmJiBtYXhFeHBpcnlUaW1lID4gMCwgJ2ludmFsaWQgbWF4RXhwaXJ5VGltZScpKSByZXR1cm47CiAgICAgIHBhcmFtcy5tYXhFeHBpcnlUaW1lID0gbWF4RXhwaXJ5VGltZTsKICAgIH0KICAgIGlmIChhdWN0aW9uc1BlckJsb2NrKSB7CiAgICAgIGlmICghYXBpLmFzc2VydChOdW1iZXIuaXNJbnRlZ2VyKGF1Y3Rpb25zUGVyQmxvY2spICYmIGF1Y3Rpb25zUGVyQmxvY2sgPiAwLCAnaW52YWxpZCBhdWN0aW9uc1BlckJsb2NrJykpIHJldHVybjsKICAgICAgcGFyYW1zLmF1Y3Rpb25zUGVyQmxvY2sgPSBhdWN0aW9uc1BlckJsb2NrOwogICAgfQoKICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ3BhcmFtcycsIHBhcmFtcyk7CiAgfQp9OwoKY29uc3QgY291bnREZWNpbWFscyA9IHZhbHVlID0+IGFwaS5CaWdOdW1iZXIodmFsdWUpLmRwKCk7Cgpjb25zdCBnZXRUaW1lc3RhbXAgPSAodmFsdWUpID0+IHsKICB0cnkgewogICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKGAke3ZhbHVlfS4wMFpgKTsKICAgIHJldHVybiBkYXRlLmdldFRpbWUoKTsKICB9IGNhdGNoIChlKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQp9OwoKY29uc3QgdHJhbnNmZXJJc1N1Y2Nlc3NmdWwgPSAocmVzdWx0LCBhY3Rpb24sIGZyb20sIHRvLCBzeW1ib2wsIHF1YW50aXR5KSA9PiB7CiAgaWYgKHJlc3VsdC5lcnJvcnMgPT09IHVuZGVmaW5lZAogICAgJiYgcmVzdWx0LmV2ZW50cyAmJiByZXN1bHQuZXZlbnRzLmZpbmQoZWwgPT4gZWwuY29udHJhY3QgPT09ICd0b2tlbnMnCiAgICAmJiBlbC5ldmVudCA9PT0gYWN0aW9uCiAgICAmJiBlbC5kYXRhLmZyb20gPT09IGZyb20KICAgICYmIGVsLmRhdGEudG8gPT09IHRvCiAgICAmJiBhcGkuQmlnTnVtYmVyKGVsLmRhdGEucXVhbnRpdHkpLmVxKHF1YW50aXR5KQogICAgJiYgZWwuZGF0YS5zeW1ib2wgPT09IHN5bWJvbCkgIT09IHVuZGVmaW5lZCkgewogICAgcmV0dXJuIHRydWU7CiAgfQoKICByZXR1cm4gZmFsc2U7Cn07Cgpjb25zdCBzZXR0bGVBdWN0aW9uID0gYXN5bmMgKGF1Y3Rpb24sIGlkID0gbnVsbCwgc2V0dGxlID0gdHJ1ZSkgPT4gewogIGNvbnN0IHsKICAgIGF1Y3Rpb25JZCwKICAgIHN5bWJvbCwKICAgIHNlbGxlciwKICAgIG5mdElkcywKICAgIHByaWNlU3ltYm9sLAogICAgYmlkcywKICAgIGN1cnJlbnRMZWFkLAogIH0gPSBhdWN0aW9uOwoKICBjb25zdCBibG9ja0RhdGUgPSBuZXcgRGF0ZShgJHthcGkuaGl2ZUJsb2NrVGltZXN0YW1wfS4wMDBaYCk7CiAgY29uc3QgdGltZXN0YW1wID0gYmxvY2tEYXRlLmdldFRpbWUoKTsKCiAgY29uc3Qgd3JhcHBlZE5mdHMgPSB7CiAgICBzeW1ib2wsCiAgICBpZHM6IG5mdElkcywKICB9OwoKICBpZiAoYmlkcy5sZW5ndGggPiAwKSB7CiAgICBjb25zdCBiaWRJZCA9IGlkID09PSBudWxsID8gY3VycmVudExlYWQgOiBpZDsKICAgIGNvbnN0IGxlYWRCaWQgPSBiaWRzW2JpZElkXTsKICAgIGNvbnN0IGZpbmFsVG8gPSBzZXR0bGUgPyBsZWFkQmlkLmFjY291bnQgOiBzZWxsZXI7CgogICAgLy8gb25seSBzZW5kIHBheW1lbnQgJiBORlRzIGlmIGF1Y3Rpb24gaXMgc2V0dGxpbmcgKG5vdCBjYW5jZWxsZWQpCiAgICBpZiAoc2V0dGxlKSB7CiAgICAgIGJpZHMuc3BsaWNlKGJpZElkLCAxKTsKCiAgICAgIC8vIHNlbmQgcGF5bWVudCB0byB0aGUgc2VsbGVyCiAgICAgIGF3YWl0IGFwaS50cmFuc2ZlclRva2VucyhzZWxsZXIsIHByaWNlU3ltYm9sLCBsZWFkQmlkLmJpZCwgJ3VzZXInKTsKICAgIH0KCiAgICAvLyB0cmFuc2ZlciB0aGUgTkZUcyB0byB0aGUgYnV5ZXIvc2VsbGVyCiAgICBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ25mdCcsICd0cmFuc2ZlcicsIHsKICAgICAgZnJvbVR5cGU6ICdjb250cmFjdCcsCiAgICAgIHRvOiBmaW5hbFRvLAogICAgICB0b1R5cGU6ICd1c2VyJywKICAgICAgbmZ0czogW3dyYXBwZWROZnRzXSwKICAgICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5OiB0cnVlLAogICAgfSk7CgogICAgbGV0IGNvdW50ID0gMDsKCiAgICB3aGlsZSAoY291bnQgPCBiaWRzLmxlbmd0aCkgewogICAgICBjb25zdCB7CiAgICAgICAgYWNjb3VudCwKICAgICAgICBiaWQsCiAgICAgIH0gPSBiaWRzW2NvdW50XTsKCiAgICAgIC8vIHNlbmQgdG9rZW5zIGJhY2sgdG8gYmlkZGVycwogICAgICBhd2FpdCBhcGkudHJhbnNmZXJUb2tlbnMoYWNjb3VudCwgcHJpY2VTeW1ib2wsIGJpZCwgJ3VzZXInKTsKICAgICAgY291bnQgKz0gMTsKICAgIH0KCiAgICBhd2FpdCBhcGkuZGIucmVtb3ZlKCdhdWN0aW9ucycsIGF1Y3Rpb24pOwoKICAgIGlmIChzZXR0bGUpIHsKICAgICAgYXBpLmVtaXQoJ3NldHRsZUF1Y3Rpb24nLCB7CiAgICAgICAgYXVjdGlvbklkLAogICAgICAgIHN5bWJvbCwKICAgICAgICBzZWxsZXIsCiAgICAgICAgbmZ0SWRzLAogICAgICAgIGJpZGRlcjogbGVhZEJpZC5hY2NvdW50LAogICAgICAgIHByaWNlOiBsZWFkQmlkLmJpZCwKICAgICAgICBwcmljZVN5bWJvbCwKICAgICAgICB0aW1lc3RhbXAsCiAgICAgIH0pOwogICAgfSBlbHNlIHsKICAgICAgYXBpLmVtaXQoJ2NhbmNlbEF1Y3Rpb24nLCB7CiAgICAgICAgYXVjdGlvbklkLAogICAgICB9KTsKICAgIH0KICB9IGVsc2UgewogICAgLy8gaWYgdGhlcmUgYXJlIG5vIGJpZHMsIGV4cGlyZSB0aGUgYXVjdGlvbgogICAgYXdhaXQgYXBpLmRiLnJlbW92ZSgnYXVjdGlvbnMnLCBhdWN0aW9uKTsKCiAgICAvLyByZXR1cm4gdGhlIE5GVHMgdG8gdGhlIHNlbGxlcgogICAgYXdhaXQgYXBpLmV4ZWN1dGVTbWFydENvbnRyYWN0KCduZnQnLCAndHJhbnNmZXInLCB7CiAgICAgIGZyb21UeXBlOiAnY29udHJhY3QnLAogICAgICB0bzogc2VsbGVyLAogICAgICB0b1R5cGU6ICd1c2VyJywKICAgICAgbmZ0czogW3dyYXBwZWROZnRzXSwKICAgICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5OiB0cnVlLAogICAgfSk7CgogICAgYXBpLmVtaXQoJ2V4cGlyZUF1Y3Rpb24nLCB7CiAgICAgIGF1Y3Rpb25JZCwKICAgICAgc3ltYm9sLAogICAgICBzZWxsZXIsCiAgICAgIG5mdElkcywKICAgICAgdGltZXN0YW1wLAogICAgfSk7CiAgfQp9OwoKYWN0aW9ucy5jcmVhdGUgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIHN5bWJvbCwKICAgIG5mdHMsCiAgICBtaW5CaWQsCiAgICBmaW5hbFByaWNlLAogICAgcHJpY2VTeW1ib2wsCiAgICBleHBpcnksCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmICghYXBpLmFzc2VydChzeW1ib2wgJiYgdHlwZW9mIHN5bWJvbCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHN5bWJvbCcpKSByZXR1cm47CgogIGNvbnN0IG5mdCA9IGF3YWl0IGFwaS5kYi5maW5kT25lSW5UYWJsZSgnbmZ0JywgJ25mdHMnLCB7IHN5bWJvbCB9KTsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQobmZ0cyAmJiB0eXBlb2YgbmZ0cyA9PT0gJ29iamVjdCcgJiYgQXJyYXkuaXNBcnJheShuZnRzKQogICAgICAmJiBtaW5CaWQgJiYgdHlwZW9mIG1pbkJpZCA9PT0gJ3N0cmluZycgJiYgIWFwaS5CaWdOdW1iZXIobWluQmlkKS5pc05hTigpCiAgICAgICYmIGZpbmFsUHJpY2UgJiYgdHlwZW9mIGZpbmFsUHJpY2UgPT09ICdzdHJpbmcnICYmICFhcGkuQmlnTnVtYmVyKGZpbmFsUHJpY2UpLmlzTmFOKCkKICAgICAgJiYgcHJpY2VTeW1ib2wgJiYgdHlwZW9mIHByaWNlU3ltYm9sID09PSAnc3RyaW5nJwogICAgICAmJiBleHBpcnkgJiYgdHlwZW9mIGV4cGlyeSA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHBhcmFtcycpCiAgICAmJiBhcGkuYXNzZXJ0KG5mdHMubGVuZ3RoIDw9IE1BWF9OVU1fVU5JVFNfT1BFUkFCTEUsIGBjYW5ub3QgcHJvY2VzcyBtb3JlIHRoYW4gJHtNQVhfTlVNX1VOSVRTX09QRVJBQkxFfSBORlQgaW5zdGFuY2VzIGF0IG9uY2VgKQogICAgJiYgYXBpLmFzc2VydChuZnQsICdORlQgc3ltYm9sIGRvZXMgbm90IGV4aXN0JykpIHsKICAgIC8vIGdldCB0aGUgcHJpY2UgdG9rZW4gcGFyYW1zCiAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lSW5UYWJsZSgndG9rZW5zJywgJ3Rva2VucycsIHsgc3ltYm9sOiBwcmljZVN5bWJvbCB9KTsKICAgIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CgogICAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLmhpdmVCbG9ja1RpbWVzdGFtcH0uMDAwWmApOwogICAgY29uc3QgdGltZXN0YW1wID0gYmxvY2tEYXRlLmdldFRpbWUoKTsKICAgIGNvbnN0IGV4cGlyeVRpbWVzdGFtcCA9IGdldFRpbWVzdGFtcChleHBpcnkpOwogICAgY29uc3QgbWF4RXhwaXJ5VGltZXN0YW1wID0gYXBpLkJpZ051bWJlcih0aW1lc3RhbXApCiAgICAgIC5wbHVzKHBhcmFtcy5tYXhFeHBpcnlUaW1lKS50b051bWJlcigpOwoKICAgIGlmIChhcGkuYXNzZXJ0KHRva2VuLCAncHJpY2VTeW1ib2wgZG9lcyBub3QgZXhpc3QnKQogICAgICAvLyBtaW5CaWQgY2hlY2tzCiAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihtaW5CaWQpLmd0KDApCiAgICAgICAgJiYgY291bnREZWNpbWFscyhtaW5CaWQpIDw9IHRva2VuLnByZWNpc2lvbiwgJ2ludmFsaWQgbWluQmlkJykKICAgICAgLy8gZmluYWxQcmljZSBjaGVja3MKICAgICAgJiYgYXBpLmFzc2VydChhcGkuQmlnTnVtYmVyKGZpbmFsUHJpY2UpLmd0KDApCiAgICAgICAgJiYgY291bnREZWNpbWFscyhmaW5hbFByaWNlKSA8PSB0b2tlbi5wcmVjaXNpb24sICdpbnZhbGlkIGZpbmFsUHJpY2UnKQogICAgICAvLyBleHBpcnkgY2hlY2tzCiAgICAgICYmIGFwaS5hc3NlcnQoZXhwaXJ5VGltZXN0YW1wICYmIGV4cGlyeVRpbWVzdGFtcCA+IHRpbWVzdGFtcCwgJ2ludmFsaWQgZXhwaXJ5JykKICAgICAgJiYgYXBpLmFzc2VydChleHBpcnlUaW1lc3RhbXAgPD0gbWF4RXhwaXJ5VGltZXN0YW1wLCAnZXhwaXJ5IGV4Y2VlZHMgbGltaXQnKSkgewogICAgICBjb25zdCB1dGlsaXR5VG9rZW4gPSBhd2FpdCBhcGkuZGIuZmluZE9uZUluVGFibGUoJ3Rva2VucycsICdiYWxhbmNlcycsIHsgYWNjb3VudDogYXBpLnNlbmRlciwgc3ltYm9sOiBVVElMSVRZX1RPS0VOX1NZTUJPTCB9KTsKCiAgICAgIGlmIChhcGkuYXNzZXJ0KHV0aWxpdHlUb2tlbiAmJiB1dGlsaXR5VG9rZW4uYmFsYW5jZQogICAgICAgICYmIGFwaS5CaWdOdW1iZXIodXRpbGl0eVRva2VuLmJhbGFuY2UpLmd0ZShwYXJhbXMuY3JlYXRpb25GZWUpLCAneW91IG11c3QgaGF2ZSBlbm91Z2ggdG9rZW5zIHRvIGNvdmVyIHRoZSBjcmVhdGlvbiBmZWUnKSkgewogICAgICAgIC8vIGxvY2sgdGhlIE5GVHMgdG8gc2VsbCBieSBtb3ZpbmcgdGhlbSB0byB0aGlzIGNvbnRyYWN0IGZvciBzYWZla2VlcGluZwogICAgICAgIGNvbnN0IHdyYXBwZWROZnRzID0gewogICAgICAgICAgc3ltYm9sLAogICAgICAgICAgaWRzOiBuZnRzLAogICAgICAgIH07CiAgICAgICAgY29uc3QgbmZ0VHJhbnNmZXIgPSBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ25mdCcsICd0cmFuc2ZlcicsIHsKICAgICAgICAgIGZyb21UeXBlOiAndXNlcicsCiAgICAgICAgICB0bzogQ09OVFJBQ1RfTkFNRSwKICAgICAgICAgIHRvVHlwZTogJ2NvbnRyYWN0JywKICAgICAgICAgIG5mdHM6IFt3cmFwcGVkTmZ0c10sCiAgICAgICAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgICAgICAgfSk7CgogICAgICAgIC8vIG9ubHkgYWRkIG5mdHMgaW4gdGhlIGF1Y3Rpb24gd2hpY2ggdHJhbnNmZXJlZCBzdWNjZXNzZnVsbHkKICAgICAgICBpZiAoYXBpLmFzc2VydChuZnRUcmFuc2Zlci5ldmVudHMsICdmYWlsZWQgdG8gdHJhc2ZlciBORlRzIHRvIHRoZSBjb250cmFjdCcpKSB7CiAgICAgICAgICBjb25zdCBuZnRJZHMgPSBbXTsKCiAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5mdFRyYW5zZmVyLmV2ZW50cy5sZW5ndGg7IGkgKz0gMSkgewogICAgICAgICAgICBjb25zdCBldiA9IG5mdFRyYW5zZmVyLmV2ZW50c1tpXTsKICAgICAgICAgICAgaWYgKGV2LmNvbnRyYWN0ICYmIGV2LmV2ZW50ICYmIGV2LmRhdGEKICAgICAgICAgICAgICAmJiBldi5jb250cmFjdCA9PT0gJ25mdCcKICAgICAgICAgICAgICAmJiBldi5ldmVudCA9PT0gJ3RyYW5zZmVyJwogICAgICAgICAgICAgICYmIGV2LmRhdGEuZnJvbSA9PT0gYXBpLnNlbmRlcgogICAgICAgICAgICAgICYmIGV2LmRhdGEuZnJvbVR5cGUgPT09ICd1JwogICAgICAgICAgICAgICYmIGV2LmRhdGEudG8gPT09IENPTlRSQUNUX05BTUUKICAgICAgICAgICAgICAmJiBldi5kYXRhLnRvVHlwZSA9PT0gJ2MnCiAgICAgICAgICAgICAgJiYgZXYuZGF0YS5zeW1ib2wgPT09IHN5bWJvbCkgewogICAgICAgICAgICAgIC8vIHRyYW5zZmVyIGlzIHZlcmlmaWVkCiAgICAgICAgICAgICAgY29uc3QgaW5zdGFuY2VJZCA9IGV2LmRhdGEuaWQ7CiAgICAgICAgICAgICAgbmZ0SWRzLnB1c2goaW5zdGFuY2VJZCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBpZiAobmZ0SWRzLmxlbmd0aCA+IDApIHsKICAgICAgICAgICAgY29uc3QgZmVlVHJhbnNmZXIgPSBhd2FpdCBhcGkuZXhlY3V0ZVNtYXJ0Q29udHJhY3QoJ3Rva2VucycsICd0cmFuc2ZlcicsIHsKICAgICAgICAgICAgICB0bzogJ251bGwnLCBzeW1ib2w6IFVUSUxJVFlfVE9LRU5fU1lNQk9MLCBxdWFudGl0eTogcGFyYW1zLmNyZWF0aW9uRmVlLCBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgaWYgKHRyYW5zZmVySXNTdWNjZXNzZnVsKGZlZVRyYW5zZmVyLCAndHJhbnNmZXInLCBhcGkuc2VuZGVyLCAnbnVsbCcsIFVUSUxJVFlfVE9LRU5fU1lNQk9MLCBwYXJhbXMuY3JlYXRpb25GZWUpKSB7CiAgICAgICAgICAgICAgLy8gY3JlYXRlIGFuIGF1Y3Rpb24KICAgICAgICAgICAgICBjb25zdCBhdWN0aW9uID0gewogICAgICAgICAgICAgICAgYXVjdGlvbklkOiBhcGkudHJhbnNhY3Rpb25JZCwKICAgICAgICAgICAgICAgIHN5bWJvbCwKICAgICAgICAgICAgICAgIHNlbGxlcjogYXBpLnNlbmRlciwKICAgICAgICAgICAgICAgIG5mdElkcywKICAgICAgICAgICAgICAgIHByaWNlU3ltYm9sLAogICAgICAgICAgICAgICAgbWluQmlkLAogICAgICAgICAgICAgICAgZmluYWxQcmljZSwKICAgICAgICAgICAgICAgIGV4cGlyeVRpbWVzdGFtcCwKICAgICAgICAgICAgICAgIGJpZHM6IFtdLAogICAgICAgICAgICAgICAgY3VycmVudExlYWQ6IG51bGwsCiAgICAgICAgICAgICAgICBsYXN0TGVhZFVwZGF0ZTogdGltZXN0YW1wLAogICAgICAgICAgICAgIH07CgogICAgICAgICAgICAgIGNvbnN0IHJlcyA9IGF3YWl0IGFwaS5kYi5pbnNlcnQoJ2F1Y3Rpb25zJywgYXVjdGlvbik7CgogICAgICAgICAgICAgIGFwaS5lbWl0KCdjcmVhdGUnLCB7IGF1Y3Rpb25JZDogcmVzLmF1Y3Rpb25JZCB9KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAvLyBpZiBmZWUgdHJhbnNmZXIgc29tZWhvdyBmYWlscywgcmV0dXJuIHRoZSB0cmFuc2ZlcmVkIE5GVHMKICAgICAgICAgICAgICB3cmFwcGVkTmZ0cy5pZHMgPSBuZnRJZHM7CiAgICAgICAgICAgICAgYXdhaXQgYXBpLmV4ZWN1dGVTbWFydENvbnRyYWN0KCduZnQnLCAndHJhbnNmZXInLCB7CiAgICAgICAgICAgICAgICBmcm9tVHlwZTogJ2NvbnRyYWN0JywKICAgICAgICAgICAgICAgIHRvOiBhcGkuc2VuZGVyLAogICAgICAgICAgICAgICAgdG9UeXBlOiAndXNlcicsCiAgICAgICAgICAgICAgICBuZnRzOiBbd3JhcHBlZE5mdHNdLAogICAgICAgICAgICAgICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5zZXR0bGUgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIGF1Y3Rpb25JZCwKICAgIGFjY291bnQsCiAgICBpc1NpZ25lZFdpdGhBY3RpdmVLZXksCiAgfSA9IHBheWxvYWQ7CgogIGlmIChhcGkuYXNzZXJ0KGlzU2lnbmVkV2l0aEFjdGl2ZUtleSA9PT0gdHJ1ZSwgJ3lvdSBtdXN0IHVzZSBhIGN1c3RvbV9qc29uIHNpZ25lZCB3aXRoIHlvdXIgYWN0aXZlIGtleScpCiAgICAmJiBhcGkuYXNzZXJ0KGF1Y3Rpb25JZCAmJiB0eXBlb2YgYXVjdGlvbklkID09PSAnc3RyaW5nJwogICAgICAmJiAoIWFjY291bnQgfHwgKGFjY291bnQgJiYgdHlwZW9mIGFjY291bnQgPT09ICdzdHJpbmcnICYmIGFwaS5pc1ZhbGlkQWNjb3VudE5hbWUoYWNjb3VudCkpKSwgJ2ludmFsaWQgcGFyYW1zJykpIHsKICAgIGNvbnN0IGF1Y3Rpb24gPSBhd2FpdCBhcGkuZGIuZmluZE9uZSgnYXVjdGlvbnMnLCB7IGF1Y3Rpb25JZCB9KTsKCiAgICBpZiAoYXBpLmFzc2VydChhdWN0aW9uLCAnYXVjdGlvbiBkb2VzIG5vdCBleGlzdCBvciBoYXMgYmVlbiBleHBpcmVkJykKICAgICAgJiYgYXBpLmFzc2VydChhdWN0aW9uLnNlbGxlciA9PT0gYXBpLnNlbmRlciwgJ3lvdSBtdXN0IGJlIHRoZSBvd25lciBvZiB0aGUgYXVjdGlvbicpKSB7CiAgICAgIGxldCBpZCA9IGF1Y3Rpb24uY3VycmVudExlYWQ7CgogICAgICBpZiAoYWNjb3VudCkgewogICAgICAgIC8vIHNlYXJjaCBpZiB0aGVyZSBpcyBhIGJpZCBmcm9tIHRoaXMgYWNjb3VudAogICAgICAgIGlkID0gYXVjdGlvbi5iaWRzLmZpbmRJbmRleChlbCA9PiBlbC5hY2NvdW50ID09PSBhY2NvdW50KTsKICAgICAgICBpZiAoIWFwaS5hc3NlcnQoYXVjdGlvbi5iaWRzW2lkXSwgJ25vIGJpZCBmcm9tIGFjY291bnQgZm91bmQgaW4gdGhlIGF1Y3Rpb24nKSkgcmV0dXJuOwogICAgICB9CgogICAgICBhd2FpdCBzZXR0bGVBdWN0aW9uKGF1Y3Rpb24sIGlkKTsKICAgIH0KICB9Cn07CgphY3Rpb25zLmNhbmNlbCA9IGFzeW5jIChwYXlsb2FkKSA9PiB7CiAgY29uc3QgewogICAgYXVjdGlvbklkLAogICAgaXNTaWduZWRXaXRoQWN0aXZlS2V5LAogIH0gPSBwYXlsb2FkOwoKICBpZiAoYXBpLmFzc2VydChpc1NpZ25lZFdpdGhBY3RpdmVLZXkgPT09IHRydWUsICd5b3UgbXVzdCB1c2UgYSBjdXN0b21fanNvbiBzaWduZWQgd2l0aCB5b3VyIGFjdGl2ZSBrZXknKQogICAgJiYgYXBpLmFzc2VydChhdWN0aW9uSWQgJiYgdHlwZW9mIGF1Y3Rpb25JZCA9PT0gJ3N0cmluZycsICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBhdWN0aW9uID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2F1Y3Rpb25zJywgeyBhdWN0aW9uSWQgfSk7CgogICAgaWYgKGFwaS5hc3NlcnQoYXVjdGlvbiwgJ2F1Y3Rpb24gZG9lcyBub3QgZXhpc3Qgb3IgaGFzIGJlZW4gZXhwaXJlZCcpCiAgICAmJiBhcGkuYXNzZXJ0KGF1Y3Rpb24uc2VsbGVyID09PSBhcGkuc2VuZGVyLCAneW91IG11c3QgYmUgdGhlIG93bmVyIG9mIHRoZSBhdWN0aW9uJykpIHsKICAgICAgYXdhaXQgc2V0dGxlQXVjdGlvbihhdWN0aW9uLCBudWxsLCBmYWxzZSk7CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5iaWQgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIGF1Y3Rpb25JZCwKICAgIGJpZCwKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoYXVjdGlvbklkICYmIHR5cGVvZiBhdWN0aW9uSWQgPT09ICdzdHJpbmcnCiAgICAgICYmIGJpZCAmJiB0eXBlb2YgYmlkID09PSAnc3RyaW5nJyAmJiAhYXBpLkJpZ051bWJlcihiaWQpLmlzTmFOKCksICdpbnZhbGlkIHBhcmFtcycpKSB7CiAgICBjb25zdCBhdWN0aW9uID0gYXdhaXQgYXBpLmRiLmZpbmRPbmUoJ2F1Y3Rpb25zJywgeyBhdWN0aW9uSWQgfSk7CgogICAgaWYgKGFwaS5hc3NlcnQoYXVjdGlvbiwgJ2F1Y3Rpb24gZG9lcyBub3QgZXhpc3Qgb3IgaGFzIGJlZW4gZXhwaXJlZCcpKSB7CiAgICAgIGNvbnN0IHsKICAgICAgICBwcmljZVN5bWJvbCwKICAgICAgICBtaW5CaWQsCiAgICAgICAgZmluYWxQcmljZSwKICAgICAgICBjdXJyZW50TGVhZCwKICAgICAgICBleHBpcnlUaW1lc3RhbXAsCiAgICAgIH0gPSBhdWN0aW9uOwogICAgICBjb25zdCB0b2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lSW5UYWJsZSgndG9rZW5zJywgJ3Rva2VucycsIHsgc3ltYm9sOiBwcmljZVN5bWJvbCB9KTsKICAgICAgY29uc3QgYmxvY2tEYXRlID0gbmV3IERhdGUoYCR7YXBpLmhpdmVCbG9ja1RpbWVzdGFtcH0uMDAwWmApOwogICAgICBjb25zdCB0aW1lc3RhbXAgPSBibG9ja0RhdGUuZ2V0VGltZSgpOwoKICAgICAgaWYgKGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiaWQpLmd0KDApCiAgICAgICAgICAmJiBjb3VudERlY2ltYWxzKGJpZCkgPD0gdG9rZW4ucHJlY2lzaW9uLCAnaW52YWxpZCBiaWQnKQogICAgICAgICYmIGFwaS5hc3NlcnQoYXBpLkJpZ051bWJlcihiaWQpLmd0ZShtaW5CaWQpLCBgYmlkIGNhbiBub3QgYmUgbGVzcyB0aGFuICR7bWluQmlkfWApCiAgICAgICAgJiYgYXBpLmFzc2VydChleHBpcnlUaW1lc3RhbXAgPj0gdGltZXN0YW1wLCAnYXVjdGlvbiBoYXMgYmVlbiBleHBpcmVkJykpIHsKICAgICAgICBsZXQgbmJUb2tlbnNUb0xvY2sgPSBhcGkuQmlnTnVtYmVyKGJpZCkuZ3QoZmluYWxQcmljZSkgPyBmaW5hbFByaWNlIDogYmlkOwogICAgICAgIC8vIGZpbmQgaWYgdGhlIGFjY291bnQgaGFzIGFueSBwcmV2aW91cyBiaWQgaW4gdGhpcyBhdWN0aW9uCiAgICAgICAgY29uc3QgcHJldmlvdXNCaWRJbmRleCA9IGF1Y3Rpb24uYmlkcy5maW5kSW5kZXgoZWwgPT4gZWwuYWNjb3VudCA9PT0gYXBpLnNlbmRlcik7CiAgICAgICAgY29uc3QgcHJldmlvdXNCaWQgPSBhdWN0aW9uLmJpZHNbcHJldmlvdXNCaWRJbmRleF07CgogICAgICAgIGNvbnN0IG5ld0JpZCA9IHsKICAgICAgICAgIGFjY291bnQ6IGFwaS5zZW5kZXIsCiAgICAgICAgICBiaWQ6IG5iVG9rZW5zVG9Mb2NrLAogICAgICAgICAgdGltZXN0YW1wLAogICAgICAgIH07CgogICAgICAgIGlmIChwcmV2aW91c0JpZCkgewogICAgICAgICAgaWYgKCFhcGkuYXNzZXJ0KGFwaS5CaWdOdW1iZXIobmJUb2tlbnNUb0xvY2spLmd0KHByZXZpb3VzQmlkLmJpZCksICdiaWQgbXVzdCBiZSBncmVhdGVyIHRoYW4geW91ciBwcmV2aW91cyBiaWQnKSkgcmV0dXJuOwogICAgICAgICAgLy8gdXBkYXRlIHRoZSBwcmV2aW91cyBiaWQKICAgICAgICAgIGF1Y3Rpb24uYmlkc1twcmV2aW91c0JpZEluZGV4XSA9IG5ld0JpZDsKICAgICAgICAgIC8vIGxvY2sgb25seSB0b2tlbnMgdGhhdCBleGNlZWQgdGhlIHByZXZpb3VzIGJpZCBxdWFudGl0eQogICAgICAgICAgbmJUb2tlbnNUb0xvY2sgPSBhcGkuQmlnTnVtYmVyKG5iVG9rZW5zVG9Mb2NrKQogICAgICAgICAgICAubWludXMocHJldmlvdXNCaWQuYmlkKQogICAgICAgICAgICAudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhdWN0aW9uLmJpZHMucHVzaChuZXdCaWQpOwogICAgICAgIH0KCiAgICAgICAgY29uc3QgcHJpY2VUb2tlbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lSW5UYWJsZSgndG9rZW5zJywgJ2JhbGFuY2VzJywgeyBhY2NvdW50OiBhcGkuc2VuZGVyLCBzeW1ib2w6IHByaWNlU3ltYm9sIH0pOwoKICAgICAgICBpZiAoYXBpLmFzc2VydChwcmljZVRva2VuICYmIHByaWNlVG9rZW4uYmFsYW5jZQogICAgICAgICAgJiYgYXBpLkJpZ051bWJlcihwcmljZVRva2VuLmJhbGFuY2UpLmd0ZShuYlRva2Vuc1RvTG9jayksICdpbnN1ZmZpY2llbnQgYmFsYW5jZSBmb3IgdGhpcyBiaWQnKSkgewogICAgICAgICAgLy8gbG9jayB0aGUgYmlkIGluIHRoZSBjb250cmFjdCBmb3Igc2FmZSBrZWVwaW5nCiAgICAgICAgICBjb25zdCB0b2tlblRyYW5zZmVyID0gYXdhaXQgYXBpLmV4ZWN1dGVTbWFydENvbnRyYWN0KCd0b2tlbnMnLCAndHJhbnNmZXJUb0NvbnRyYWN0JywgewogICAgICAgICAgICB0bzogQ09OVFJBQ1RfTkFNRSwgc3ltYm9sOiBwcmljZVN5bWJvbCwgcXVhbnRpdHk6IG5iVG9rZW5zVG9Mb2NrLAogICAgICAgICAgfSk7CgogICAgICAgICAgLy8gbWFrZSBzdXJlIHRoZSB0cmFuc2ZlciB3YXMgc3VjY2VzZnVsbCBhbmQgdXBkYXRlIGF1Y3Rpb24KICAgICAgICAgIGlmICh0cmFuc2ZlcklzU3VjY2Vzc2Z1bCh0b2tlblRyYW5zZmVyLCAndHJhbnNmZXJUb0NvbnRyYWN0JywgYXBpLnNlbmRlciwgQ09OVFJBQ1RfTkFNRSwgcHJpY2VTeW1ib2wsIG5iVG9rZW5zVG9Mb2NrKSkgewogICAgICAgICAgICBjb25zdCBuZXdCaWRJbmRleCA9IGF1Y3Rpb24uYmlkcy5maW5kSW5kZXgoZWwgPT4gZWwuYWNjb3VudCA9PT0gYXBpLnNlbmRlcik7CgogICAgICAgICAgICAvLyBpZiB0aGUgYmlkIGhpdHMgdGhlIGZpbmFsUHJpY2UsIHNldHRsZSB0aGUgYXVjdGlvbgogICAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcihuZXdCaWQuYmlkKS5ndGUoZmluYWxQcmljZSkpIHsKICAgICAgICAgICAgICBhdWN0aW9uLmN1cnJlbnRMZWFkID0gbmV3QmlkSW5kZXg7CiAgICAgICAgICAgICAgYXdhaXQgc2V0dGxlQXVjdGlvbihhdWN0aW9uKTsKICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CgogICAgICAgICAgICBpZiAoY3VycmVudExlYWQgIT09IG51bGwpIHsKICAgICAgICAgICAgICAvLyBjaGVjayBpZiBuZXcgYmlkIHRha2VzIHRoZSBsZWFkCiAgICAgICAgICAgICAgY29uc3QgbGVhZEJpZCA9IGF1Y3Rpb24uYmlkc1tjdXJyZW50TGVhZF07CiAgICAgICAgICAgICAgY29uc3QgbWluQmlkSW5jcmVtZW50UGN0ID0gcGFyYW1zLm1pbkJpZEluY3JlbWVudCAvIDEwMDA7CiAgICAgICAgICAgICAgLy8gcXVhbnRpdHkgaW5jcmVtZW50IHRoZSBuZXcgYmlkIHJlcXVpcmVzIHRvIHRha2UgdGhlIGxlYWQKICAgICAgICAgICAgICBjb25zdCBtaW5CaWRJbmNyZW1lbnQgPSBhcGkuQmlnTnVtYmVyKGxlYWRCaWQuYmlkKQogICAgICAgICAgICAgICAgLm11bHRpcGxpZWRCeShtaW5CaWRJbmNyZW1lbnRQY3QpCiAgICAgICAgICAgICAgICAudG9GaXhlZCh0b2tlbi5wcmVjaXNpb24pOwoKICAgICAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcihuZXdCaWQuYmlkKS5taW51cyhsZWFkQmlkLmJpZCkuZ3RlKG1pbkJpZEluY3JlbWVudCkpIHsKICAgICAgICAgICAgICAgIC8vIGNoYW5nZSB0aGUgbGVhZCB0byB0aGlzIG5ldyBiaWQKICAgICAgICAgICAgICAgIGF1Y3Rpb24uY3VycmVudExlYWQgPSBuZXdCaWRJbmRleDsKICAgICAgICAgICAgICAgIGF1Y3Rpb24ubGFzdExlYWRVcGRhdGUgPSB0aW1lc3RhbXA7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGF1Y3Rpb24uY3VycmVudExlYWQgPSBuZXdCaWRJbmRleDsKICAgICAgICAgICAgICBhdWN0aW9uLmxhc3RMZWFkVXBkYXRlID0gdGltZXN0YW1wOwogICAgICAgICAgICB9CgogICAgICAgICAgICBhd2FpdCBhcGkuZGIudXBkYXRlKCdhdWN0aW9ucycsIGF1Y3Rpb24pOwoKICAgICAgICAgICAgaWYgKHByZXZpb3VzQmlkKSB7CiAgICAgICAgICAgICAgYXBpLmVtaXQoJ3VwZGF0ZUJpZCcsIHsKICAgICAgICAgICAgICAgIGF1Y3Rpb25JZCwKICAgICAgICAgICAgICAgIGFjY291bnQ6IG5ld0JpZC5hY2NvdW50LAogICAgICAgICAgICAgICAgb2xkQmlkOiBwcmV2aW91c0JpZC5iaWQsCiAgICAgICAgICAgICAgICBuZXdCaWQ6IG5ld0JpZC5iaWQsCiAgICAgICAgICAgICAgICBvbGRUaW1lc3RhbXA6IHByZXZpb3VzQmlkLnRpbWVzdGFtcCwKICAgICAgICAgICAgICAgIG5ld1RpbWVzdGFtcDogbmV3QmlkLnRpbWVzdGFtcCwKICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICBhcGkuZW1pdCgnYmlkJywgewogICAgICAgICAgICAgICAgYXVjdGlvbklkLAogICAgICAgICAgICAgICAgLi4ubmV3QmlkLAogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQp9OwoKYWN0aW9ucy5jYW5jZWxCaWQgPSBhc3luYyAocGF5bG9hZCkgPT4gewogIGNvbnN0IHsKICAgIGF1Y3Rpb25JZCwKICAgIGlzU2lnbmVkV2l0aEFjdGl2ZUtleSwKICB9ID0gcGF5bG9hZDsKCiAgaWYgKGFwaS5hc3NlcnQoaXNTaWduZWRXaXRoQWN0aXZlS2V5ID09PSB0cnVlLCAneW91IG11c3QgdXNlIGEgY3VzdG9tX2pzb24gc2lnbmVkIHdpdGggeW91ciBhY3RpdmUga2V5JykKICAgICYmIGFwaS5hc3NlcnQoYXVjdGlvbklkICYmIHR5cGVvZiBhdWN0aW9uSWQgPT09ICdzdHJpbmcnLCAnaW52YWxpZCBwYXJhbXMnKSkgewogICAgY29uc3QgYXVjdGlvbiA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdhdWN0aW9ucycsIHsgYXVjdGlvbklkIH0pOwoKICAgIGlmIChhcGkuYXNzZXJ0KGF1Y3Rpb24sICdhdWN0aW9uIGRvZXMgbm90IGV4aXN0IG9yIGhhcyBiZWVuIGV4cGlyZWQnKSkgewogICAgICBjb25zdCB7CiAgICAgICAgcHJpY2VTeW1ib2wsCiAgICAgICAgY3VycmVudExlYWQsCiAgICAgICAgZXhwaXJ5VGltZXN0YW1wLAogICAgICAgIGxhc3RMZWFkVXBkYXRlLAogICAgICB9ID0gYXVjdGlvbjsKCiAgICAgIC8vIGZpbmQgaWYgdGhlIGFjY291bnQgaGFzIGFueSBiaWQgaW4gdGhpcyBhdWN0aW9uCiAgICAgIGNvbnN0IGJpZEluZGV4ID0gYXVjdGlvbi5iaWRzLmZpbmRJbmRleChlbCA9PiBlbC5hY2NvdW50ID09PSBhcGkuc2VuZGVyKTsKICAgICAgY29uc3QgYmlkID0gYXVjdGlvbi5iaWRzW2JpZEluZGV4XTsKCiAgICAgIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5oaXZlQmxvY2tUaW1lc3RhbXB9LjAwMFpgKTsKICAgICAgY29uc3QgdGltZXN0YW1wID0gYmxvY2tEYXRlLmdldFRpbWUoKTsKCiAgICAgIGlmIChhcGkuYXNzZXJ0KGJpZCwgJ3lvdSBkb24gbm90IGhhdmUgYSBiaWQgaW4gdGhpcyBhdWN0aW9uJykKICAgICAgICAmJiBhcGkuYXNzZXJ0KGV4cGlyeVRpbWVzdGFtcCA+PSB0aW1lc3RhbXAsICdhdWN0aW9uIGhhcyBiZWVuIGV4cGlyZWQnKSkgewogICAgICAgIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CiAgICAgICAgY29uc3QgdGltZVJlbWFpbmluZyA9IGFwaS5CaWdOdW1iZXIobGFzdExlYWRVcGRhdGUpCiAgICAgICAgICAucGx1cyhwYXJhbXMuZXhwaXJ5VGltZSkKICAgICAgICAgIC5taW51cyh0aW1lc3RhbXApOwogICAgICAgIGNvbnN0IHRpbWVSZW1haW5pbmdFeHBpcmUgPSBhcGkuQmlnTnVtYmVyKGV4cGlyeVRpbWVzdGFtcCkubWludXModGltZXN0YW1wKTsKCiAgICAgICAgLy8gZG8gbm90IGNhbmNlbCBiaWQgaWYgYXVjdGlvbiBpcyBhYm91dCB0byBzZXR0bGUKICAgICAgICBpZiAoYXBpLmFzc2VydCh0aW1lUmVtYWluaW5nLmd0KHBhcmFtcy5jYW5jZWxMb2NrVGltZSkKICAgICAgICAgICYmIHRpbWVSZW1haW5pbmdFeHBpcmUuZ3QocGFyYW1zLmNhbmNlbExvY2tUaW1lKSwgJ2NhbiBub3QgY2FuY2VsIGJpZCB3aGVuIGF1Y3Rpb24gaXMgYWJvdXQgdG8gc2V0dGxlJykpIHsKICAgICAgICAgIC8vIHJlbW92ZSB0aGlzIGJpZCBmcm9tIHRoZSBhdWN0aW9uCiAgICAgICAgICBhdWN0aW9uLmJpZHMuc3BsaWNlKGJpZEluZGV4LCAxKTsKCiAgICAgICAgICBpZiAoY3VycmVudExlYWQgPT09IGJpZEluZGV4KSB7CiAgICAgICAgICAgIGxldCBsYXJnZXN0QmlkID0gJzAnOwogICAgICAgICAgICBsZXQgbGFyZ2VzdEJpZEluZGV4ID0gbnVsbDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhdWN0aW9uLmJpZHMubGVuZ3RoOyBpICs9IDEpIHsKICAgICAgICAgICAgICBjb25zdCB7IGJpZDogcXVhbnRpdHkgfSA9IGF1Y3Rpb24uYmlkc1tpXTsKICAgICAgICAgICAgICBpZiAoYXBpLkJpZ051bWJlcihxdWFudGl0eSkuZ3QobGFyZ2VzdEJpZCkpIHsKICAgICAgICAgICAgICAgIGxhcmdlc3RCaWQgPSBxdWFudGl0eTsKICAgICAgICAgICAgICAgIGxhcmdlc3RCaWRJbmRleCA9IGk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBhdWN0aW9uLmN1cnJlbnRMZWFkID0gbGFyZ2VzdEJpZEluZGV4OwogICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50TGVhZCA+IGJpZEluZGV4KSB7CiAgICAgICAgICAgIC8vIHJlLWFzc2lnbiBsZWFkIGlmIGEgbG93ZXIgaW5kZXhlZCBiaWQgaXMgcmVtb3ZlZAogICAgICAgICAgICBhdWN0aW9uLmN1cnJlbnRMZWFkIC09IDE7CiAgICAgICAgICB9CgogICAgICAgICAgYXdhaXQgYXBpLnRyYW5zZmVyVG9rZW5zKGFwaS5zZW5kZXIsIHByaWNlU3ltYm9sLCBiaWQuYmlkLCAndXNlcicpOwoKICAgICAgICAgIGF3YWl0IGFwaS5kYi51cGRhdGUoJ2F1Y3Rpb25zJywgYXVjdGlvbik7CgogICAgICAgICAgYXBpLmVtaXQoJ2NhbmNlbEJpZCcsIHsKICAgICAgICAgICAgYXVjdGlvbklkLAogICAgICAgICAgICAuLi5iaWQsCiAgICAgICAgICB9KTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Cn07CgphY3Rpb25zLnVwZGF0ZUF1Y3Rpb25zID0gYXN5bmMgKCkgPT4gewogIGlmICghYXBpLmFzc2VydChhcGkuc2VuZGVyID09PSAnbnVsbCcsICdub3QgYXV0aG9yaXplZCcpKSByZXR1cm47CgogIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFwaS5kYi5maW5kT25lKCdwYXJhbXMnLCB7fSk7CgogIGNvbnN0IGJsb2NrRGF0ZSA9IG5ldyBEYXRlKGAke2FwaS5oaXZlQmxvY2tUaW1lc3RhbXB9LjAwMFpgKTsKICBjb25zdCB0aW1lc3RhbXAgPSBibG9ja0RhdGUuZ2V0VGltZSgpOwoKICBjb25zdCBsYXN0VmFsaWRMZWFkID0gdGltZXN0YW1wIC0gcGFyYW1zLmV4cGlyeVRpbWU7CgogIGNvbnN0IGF1Y3Rpb25zVG9TZXR0bGUgPSBhd2FpdCBhcGkuZGIuZmluZCgnYXVjdGlvbnMnLAogICAgewogICAgICAkb3I6IFsKICAgICAgICB7IGxhc3RMZWFkVXBkYXRlOiB7ICRsdGU6IGxhc3RWYWxpZExlYWQgfSB9LAogICAgICAgIHsgZXhwaXJ5VGltZXN0YW1wOiB7ICRsdGU6IHRpbWVzdGFtcCB9IH0sCiAgICAgIF0sCiAgICB9LAogICAgcGFyYW1zLmF1Y3Rpb25zUGVyQmxvY2ssCiAgICAwLAogICAgW3sgaW5kZXg6ICdfaWQnLCBkZXNjZW5kaW5nOiBmYWxzZSB9XSk7CgogIGZvciAobGV0IGkgPSAwOyBpIDwgYXVjdGlvbnNUb1NldHRsZS5sZW5ndGg7IGkgKz0gMSkgewogICAgY29uc3QgYXVjdGlvbiA9IGF1Y3Rpb25zVG9TZXR0bGVbaV07CiAgICBhd2FpdCBzZXR0bGVBdWN0aW9uKGF1Y3Rpb24pOwogIH0KfTsK"}}}