memoscan
← all memos

Memo 0x5e31efa4…7a245d on Ethereum

XJyb3IpOwogICAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ29tcGlsZSBzaGFkZXIKICAgICAqIEBwYXJhbSB7V2ViR0wyUmVuZGVyaW5nQ29udGV4dH0gZ2wgLSBXZWJHTCBjb250ZXh0CiAgICAgKiBAcGFyYW0ge251bWJlcn0gdHlwZSAtIFNoYWRlciB0eXBlIChWRVJURVhfU0hBREVSIG9yIEZSQUdNRU5UX1NIQURFUikKICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBTaGFkZXIgc291cmNlIGNvZGUKICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gU2hhZGVyIG5hbWUgZm9yIGRlYnVnZ2luZwogICAgICogQHJldHVybnMge1dlYkdMU2hhZGVyfSBDb21waWxlZCBzaGFkZXIKICAgICAqLwogICAgY29tcGlsZVNoYWRlcihnbCwgdHlwZSwgc291cmNlLCBuYW1lKSB7CiAgICAgICAgY29uc3Qgc2hhZGVyID0gZ2wuY3JlYXRlU2hhZGVyKHR5cGUpOwogICAgICAgIGdsLnNoYWRlclNvdXJjZShzaGFkZXIsIHNvdXJjZSk7CiAgICAgICAgZ2wuY29tcGlsZVNoYWRlcihzaGFkZXIpOwogICAgICAgIAogICAgICAgIGlmICghZ2wuZ2V0U2hhZGVyUGFyYW1ldGVyKHNoYWRlciwgZ2wuQ09NUElMRV9TVEFUVVMpKSB7CiAgICAgICAgICAgIGNvbnN0IGluZm8gPSBnbC5nZXRTaGFkZXJJbmZvTG9nKHNoYWRlcik7CiAgICAgICAgICAgIGdsLmRlbGV0ZVNoYWRlcihzaGFkZXIpOwogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bmFtZX0gc2hhZGVyIGNvbXBpbGF0aW9uIGZhaWxlZDogJHtpbmZvfWApOwogICAgICAgIH0KICAgICAgICAKICAgICAgICByZXR1cm4gc2hhZGVyOwogICAgfQogICAgCiAgICAvKioKICAgICAqIEdldCBhbGwgdW5pZm9ybSBsb2NhdGlvbnMgZm9yIGEgcHJvZ3JhbQogICAgICogQHBhcmFtIHtXZWJHTDJSZW5kZXJpbmdDb250ZXh0fSBnbCAtIFdlYkdMIGNvbnRleHQKICAgICAqIEBwYXJhbSB7V2ViR0xQcm9ncmFtfSBwcm9ncmFtIC0gUHJvZ3JhbSB0byBnZXQgdW5pZm9ybXMgZnJvbQogICAgICogQHBhcmFtIHtFZmZlY3R9IGVmZmVjdCAtIEVmZmVjdCBpbnN0YW5jZQogICAgICogQHBhcmFtIHtib29sZWFufSBuZWVkc1RleHR1cmVJbnB1dCAtIFdoZXRoZXIgZWZmZWN0IG5lZWRzIHRleHR1cmUgaW5wdXQKICAgICAqIEByZXR1cm5zIHtPYmplY3R9IFVuaWZvcm0gbG9jYXRpb25zCiAgICAgKi8KICAgIGdldFVuaWZvcm1Mb2NhdGlvbnMoZ2wsIHByb2dyYW0sIGVmZmVjdCwgbmVlZHNUZXh0dXJlSW5wdXQpIHsKICAgICAgICBjb25zdCBsb2NhdGlvbnMgPSB7fTsKICAgICAgICAKICAgICAgICAvLyBHZXQgdW5pZm9ybSBjb3VudAogICAgICAgIGNvbnN0IG51bVVuaWZvcm1zID0gZ2wuZ2V0UHJvZ3JhbVBhcmFtZXRlcihwcm9ncmFtLCBnbC5BQ1RJVkVfVU5JRk9STVMpOwogICAgICAgIAogICAgICAgIC8vIEdldCBhbGwgdW5pZm9ybSBsb2NhdGlvbnMKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG51bVVuaWZvcm1zOyBpKyspIHsKICAgICAgICAgICAgY29uc3QgaW5mbyA9IGdsLmdldEFjdGl2ZVVuaWZvcm0ocHJvZ3JhbSwgaSk7CiAgICAgICAgICAgIGlmIChpbmZvKSB7CiAgICAgICAgICAgICAgICBjb25zdCBsb2NhdGlvbiA9IGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCBpbmZvLm5hbWUpOwogICAgICAgICAgICAgICAgbG9jYXRpb25zW2luZm8ubmFtZV0gPSBsb2NhdGlvbjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICB0aGlzLmxvZygnZGVidWcnLCBgRm91bmQgJHtPYmplY3Qua2V5cyhsb2NhdGlvbnMpLmxlbmd0aH0gdW5pZm9ybXMgZm9yICR7ZWZmZWN0Lm5hbWV9YCk7CiAgICAgICAgCiAgICAgICAgcmV0dXJuIGxvY2F0aW9uczsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDcmVhdGUgaW50ZXJtZWRpYXRlIHRleHR1cmUgZm9yIG11bHRpLXBhc3MgcmVuZGVyaW5nCiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBUZXh0dXJlIHdpZHRoCiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gVGV4dHVyZSBoZWlnaHQKICAgICAqLwogICAgY3JlYXRlSW50ZXJtZWRpYXRlVGV4dHVyZSh3aWR0aCwgaGVpZ2h0KSB7CiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLmlzSW5pdGlhbGl6ZWQpIHsKICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdSZW5kZXJlciBub3QgaW5pdGlhbGl6ZWQnKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLnN0YXRlLmdsOwogICAgICAgIAogICAgICAgIC8vIERlbGV0ZSBleGlzdGluZyByZXNvdXJjZXMKICAgICAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aXBhc3MuZnJhbWVidWZmZXIpIHsKICAgICAgICAgICAgZ2wuZGVsZXRlRnJhbWVidWZmZXIodGhpcy5zdGF0ZS5tdWx0aXBhc3MuZnJhbWVidWZmZXIpOwogICAgICAgICAgICBnbC5kZWxldGVUZXh0dXJlKHRoaXMuc3RhdGUubXVsdGlwYXNzLnRleHR1cmUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBDcmVhdGUgdGV4dHVyZQogICAgICAgIGNvbnN0IHRleHR1cmUgPSBnbC5jcmVhdGVUZXh0dXJlKCk7CiAgICAgICAgZ2wuYmluZFRleHR1cmUoZ2wuVEVYVFVSRV8yRCwgdGV4dHVyZSk7CiAgICAgICAgZ2wudGV4SW1hZ2UyRChnbC5URVhUVVJFXzJELCAwLCBnbC5SR0JBLCB3aWR0aCwgaGVpZ2h0LCAwLCBnbC5SR0JBLCBnbC5VTlNJR05FRF9CWVRFLCBudWxsKTsKICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUlOX0ZJTFRFUiwgZ2wuTElORUFSKTsKICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfTUFHX0ZJTFRFUiwgZ2wuTElORUFSKTsKICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9TLCBnbC5DTEFNUF9UT19FREdFKTsKICAgICAgICBnbC50ZXhQYXJhbWV0ZXJpKGdsLlRFWFRVUkVfMkQsIGdsLlRFWFRVUkVfV1JBUF9ULCBnbC5DTEFNUF9UT19FREdFKTsKICAgICAgICAKICAgICAgICAvLyBDcmVhdGUgZnJhbWVidWZmZXIKICAgICAgICBjb25zdCBmcmFtZWJ1ZmZlciA9IGdsLmNyZWF0ZUZyYW1lYnVmZmVyKCk7CiAgICAgICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCBmcmFtZWJ1ZmZlcik7CiAgICAgICAgZ2wuZnJhbWVidWZmZXJUZXh0dXJlMkQoZ2wuRlJBTUVCVUZGRVIsIGdsLkNPTE9SX0FUVEFDSE1FTlQwLCBnbC5URVhUVVJFXzJELCB0ZXh0dXJlLCAwKTsKICAgICAgICAKICAgICAgICAvLyBDaGVjayBmcmFtZWJ1ZmZlciBzdGF0dXMKICAgICAgICBjb25zdCBzdGF0dXMgPSBnbC5jaGVja0ZyYW1lYnVmZmVyU3RhdHVzKGdsLkZSQU1FQlVGRkVSKTsKICAgICAgICBpZiAoc3RhdHVzICE9PSBnbC5GUkFNRUJVRkZFUl9DT01QTEVURSkgewogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZyYW1lYnVmZmVyIGluY29tcGxldGU6ICR7c3RhdHVzfWApOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBVbmJpbmQKICAgICAgICBnbC5iaW5kRnJhbWVidWZmZXIoZ2wuRlJBTUVCVUZGRVIsIG51bGwpOwogICAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIG51bGwpOwogICAgICAgIAogICAgICAgIC8vIFN0b3JlCiAgICAgICAgdGhpcy5zdGF0ZS5tdWx0aXBhc3MuZnJhbWVidWZmZXIgPSBmcmFtZWJ1ZmZlcjsKICAgICAgICB0aGlzLnN0YXRlLm11bHRpcGFzcy50ZXh0dXJlID0gdGV4dHVyZTsKICAgICAgICB0aGlzLnN0YXRlLm11bHRpcGFzcy53aWR0aCA9IHdpZHRoOwogICAgICAgIHRoaXMuc3RhdGUubXVsdGlwYXNzLmhlaWdodCA9IGhlaWdodDsKICAgICAgICAKICAgICAgICB0aGlzLmxvZygnaW5mbycsIGBJbnRlcm1lZGlhdGUgdGV4dHVyZSBjcmVhdGVkOiAke3dpZHRofXgke2hlaWdodH1gKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBTaW5nbGUtcGFzcyByZW5kZXJpbmc6IEVmZmVjdCBkaXJlY3RseSB0byBzY3JlZW4KICAgICAqIEBwYXJhbSB7RWZmZWN0fSBlZmZlY3QgLSBFZmZlY3QgdG8gcmVuZGVyCiAgICAgKiBAcGFyYW0ge251bWJlcn0gdGltZXN0YW1wIC0gQ3VycmVudCB0aW1lc3RhbXAKICAgICAqIEBwYXJhbSB7bnVtYmVyfSB3aWR0aCAtIENhbnZhcyB3aWR0aAogICAgICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCAtIENhbnZhcyBoZWlnaHQKICAgICAqLwogICAgcmVuZGVyU2luZ2xlUGFzcyhlZmZlY3QsIHRpbWVzdGFtcCwgd2lkdGgsIGhlaWdodCkgewogICAgICAgIGNvbnN0IGdsID0gdGhpcy5zdGF0ZS5nbDsKICAgICAgICBjb25zdCBwcm9ncmFtSW5mbyA9IHRoaXMuc3RhdGUucHJvZ3JhbUluZm8uZ2V0KGVmZmVjdC5pZCk7CiAgICAgICAgCiAgICAgICAgaWYgKCFwcm9ncmFtSW5mbykgewogICAgICAgICAgICB0aGlzLmxvZygnd2FybicsIGBObyBwcm9ncmFtIGZvciBlZmZlY3QgJHtlZmZlY3QuaWR9YCk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gVXNlIHByb2dyYW0KICAgICAgICBnbC51c2VQcm9ncmFtKHByb2dyYW1JbmZvLnByb2dyYW0pOwogICAgICAgIAogICAgICAgIC8vIFVwZGF0ZSB1bmlmb3JtcwogICAgICAgIGNvbnN0IG1hcHBlZFBhcmFtcyA9IGVmZmVjdC5nZXRNYXBwZWRQYXJhbWV0ZXJzKCk7CiAgICAgICAgbWFwcGVkUGFyYW1zLnJlc29sdXRpb25YID0gd2lkdGg7CiAgICAgICAgbWFwcGVkUGFyYW1zLnJlc29sdXRpb25ZID0gaGVpZ2h0OwogICAgICAgIAogICAgICAgIHRoaXMuc2V0VW5pZm9ybXMoZ2wsIHByb2dyYW1JbmZvLnVuaWZvcm1Mb2NhdGlvbnMsIG1hcHBlZFBhcmFtcywgZWZmZWN0KTsKICAgICAgICAKICAgICAgICAvLyBCaW5kIGZyYW1lYnVmZmVyIChudWxsID0gc2NyZWVuKQogICAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7CiAgICAgICAgZ2wudmlld3BvcnQoMCwgMCwgd2lkdGgsIGhlaWdodCk7CiAgICAgICAgCiAgICAgICAgLy8gQ2xlYXIKICAgICAgICBnbC5jbGVhcihnbC5DT0xPUl9CVUZGRVJfQklUKTsKICAgICAgICAKICAgICAgICAvLyBEcmF3IGZ1bGxzY3JlZW4gdHJpYW5nbGUKICAgICAgICBnbC5iaW5kVmVydGV4QXJyYXkodGhpcy5zdGF0ZS5xdWFkLnZhbyk7CiAgICAgICAgZ2wuZHJhd0FycmF5cyhnbC5UUklBTkdMRVMsIDAsIDMpOwogICAgICAgIGdsLmJpbmRWZXJ0ZXhBcnJheShudWxsKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBNdWx0aS1wYXNzIHJlbmRlcmluZzogRmlyc3QgZWZmZWN0IOKGkiBUZXh0dXJlIOKGkiBTZWNvbmQgZWZmZWN0IOKGkiBTY3JlZW4KICAgICAqIEBwYXJhbSB7RWZmZWN0fSBmaXJzdEVmZmVjdCAtIEZpcnN0IGVmZmVjdCAoZS5nLiwgVFYgc3RhdGljKQogICAgICogQHBhcmFtIHtFZmZlY3R9IHNlY29uZEVmZmVjdCAtIFNlY29uZCBlZmZlY3QgKGUuZy4sIHBpeGVsaXphdGlvbikKICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0aW1lc3RhbXAgLSBDdXJyZW50IHRpbWVzdGFtcAogICAgICogQHBhcmFtIHtudW1iZXJ9IHdpZHRoIC0gQ2FudmFzIHdpZHRoCiAgICAgKiBAcGFyYW0ge251bWJlcn0gaGVpZ2h0IC0gQ2FudmFzIGhlaWdodAogICAgICovCiAgICByZW5kZXJNdWx0aVBhc3MoZmlyc3RFZmZlY3QsIHNlY29uZEVmZmVjdCwgdGltZXN0YW1wLCB3aWR0aCwgaGVpZ2h0KSB7CiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLnN0YXRlLmdsOwogICAgICAgIAogICAgICAgIGNvbnN0IGZpcnN0UHJvZ3JhbUluZm8gPSB0aGlzLnN0YXRlLnByb2dyYW1JbmZvLmdldChmaXJzdEVmZmVjdC5pZCk7CiAgICAgICAgY29uc3Qgc2Vjb25kUHJvZ3JhbUluZm8gPSB0aGlzLnN0YXRlLnByb2dyYW1JbmZvLmdldChzZWNvbmRFZmZlY3QuaWQpOwogICAgICAgIAogICAgICAgIGlmICghZmlyc3RQcm9ncmFtSW5mbyB8fCAhc2Vjb25kUHJvZ3JhbUluZm8pIHsKICAgICAgICAgICAgdGhpcy5sb2coJ3dhcm4nLCAnTWlzc2luZyBwcm9ncmFtIGZvciBtdWx0aS1wYXNzIHJlbmRlcmluZycpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIFBBU1MgMTogUmVuZGVyIGZpcnN0IGVmZmVjdCB0byB0ZXh0dXJlCiAgICAgICAgewogICAgICAgICAgICBnbC51c2VQcm9ncmFtKGZpcnN0UHJvZ3JhbUluZm8ucHJvZ3JhbSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBVcGRhdGUgdW5pZm9ybXMKICAgICAgICAgICAgY29uc3QgZmlyc3RQYXJhbXMgPSBmaXJzdEVmZmVjdC5nZXRNYXBwZWRQYXJhbWV0ZXJzKCk7CiAgICAgICAgICAgIGZpcnN0UGFyYW1zLnJlc29sdXRpb25YID0gd2lkdGg7CiAgICAgICAgICAgIGZpcnN0UGFyYW1zLnJlc29sdXRpb25ZID0gaGVpZ2h0OwogICAgICAgICAgICB0aGlzLnNldFVuaWZvcm1zKGdsLCBmaXJzdFByb2dyYW1JbmZvLnVuaWZvcm1Mb2NhdGlvbnMsIGZpcnN0UGFyYW1zLCBmaXJzdEVmZmVjdCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBSZW5kZXIgdG8gZnJhbWVidWZmZXIKICAgICAgICAgICAgZ2wuYmluZEZyYW1lYnVmZmVyKGdsLkZSQU1FQlVGRkVSLCB0aGlzLnN0YXRlLm11bHRpcGFzcy5mcmFtZWJ1ZmZlcik7CiAgICAgICAgICAgIGdsLnZpZXdwb3J0KDAsIDAsIHdpZHRoLCBoZWlnaHQpOwogICAgICAgICAgICBnbC5jbGVhcihnbC5DT0xPUl9CVUZGRVJfQklUKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIERyYXcKICAgICAgICAgICAgZ2wuYmluZFZlcnRleEFycmF5KHRoaXMuc3RhdGUucXVhZC52YW8pOwogICAgICAgICAgICBnbC5kcmF3QXJyYXlzKGdsLlRSSUFOR0xFUywgMCwgMyk7CiAgICAgICAgICAgIGdsLmJpbmRWZXJ0ZXhBcnJheShudWxsKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gUEFTUyAyOiBSZW5kZXIgc2Vjb25kIGVmZmVjdCAod2l0aCB0ZXh0dXJlIGlucHV0KSB0byBzY3JlZW4KICAgICAgICB7CiAgICAgICAgICAgIGdsLnVzZVByb2dyYW0oc2Vjb25kUHJvZ3JhbUluZm8ucHJvZ3JhbSk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBCaW5kIGlucHV0IHRleHR1cmUKICAgICAgICAgICAgZ2wuYWN0aXZlVGV4dHVyZShnbC5URVhUVVJFMCk7CiAgICAgICAgICAgIGdsLmJpbmRUZXh0dXJlKGdsLlRFWFRVUkVfMkQsIHRoaXMuc3RhdGUubXVsdGlwYXNzLnRleHR1cmUpOwogICAgICAgICAgICAKICAgICAgICAgICAgLy8gVXBkYXRlIHVuaWZvcm1zCiAgICAgICAgICAgIGNvbnN0IHNlY29uZFBhcmFtcyA9IHNlY29uZEVmZmVjdC5nZXRNYXBwZWRQYXJhbWV0ZXJzKCk7CiAgICAgICAgICAgIGlmIChzZWNvbmRFZmZlY3QudXBkYXRlQ2FudmFzRGltZW5zaW9ucykgewogICAgICAgICAgICAgICAgc2Vjb25kRWZmZWN0LnVwZGF0ZUNhbnZhc0RpbWVuc2lvbnMod2lkdGgsIGhlaWdodCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIFNldCB0ZXh0dXJlIHVuaWZvcm0KICAgICAgICAgICAgY29uc3QgaW5wdXRUZXh0dXJlTG9jYXRpb24gPSBzZWNvbmRQcm9ncmFtSW5mby51bmlmb3JtTG9jYXRpb25zWydpbnB1dFRleHR1cmUnXTsKICAgICAgICAgICAgaWYgKGlucHV0VGV4dHVyZUxvY2F0aW9uKSB7CiAgICAgICAgICAgICAgICBnbC51bmlmb3JtMWkoaW5wdXRUZXh0dXJlTG9jYXRpb24sIDApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICB0aGlzLnNldFVuaWZvcm1zKGdsLCBzZWNvbmRQcm9ncmFtSW5mby51bmlmb3JtTG9jYXRpb25zLCBzZWNvbmRQYXJhbXMsIHNlY29uZEVmZmVjdCk7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBSZW5kZXIgdG8gc2NyZWVuCiAgICAgICAgICAgIGdsLmJpbmRGcmFtZWJ1ZmZlcihnbC5GUkFNRUJVRkZFUiwgbnVsbCk7CiAgICAgICAgICAgIGdsLnZpZXdwb3J0KDAsIDAsIHdpZHRoLCBoZWlnaHQpOwogICAgICAgICAgICBnbC5jbGVhcihnbC5DT0xPUl9CVUZGRVJfQklUKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIERyYXcKICAgICAgICAgICAgZ2wuYmluZFZlcnRleEFycmF5KHRoaXMuc3RhdGUucXVhZC52YW8pOwogICAgICAgICAgICBnbC5kcmF3QXJyYXlzKGdsLlRSSUFOR0xFUywgMCwgMyk7CiAgICAgICAgICAgIGdsLmJpbmRWZXJ0ZXhBcnJheShudWxsKTsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogU2V0IHVuaWZvcm1zIGZyb20gbWFwcGVkIHBhcmFtZXRlcnMKICAgICAqIEBwYXJhbSB7V2ViR0wyUmVuZGVyaW5nQ29udGV4dH0gZ2wgLSBXZWJHTCBjb250ZXh0CiAgICAgKiBAcGFyYW0ge09iamVjdH0gbG9jYXRpb25zIC0gVW5pZm9ybSBsb2NhdGlvbnMKICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYXJhbXMgLSBQYXJhbWV0ZXIgdmFsdWVzCiAgICAgKiBAcGFyYW0ge0VmZmVjdH0gZWZmZWN0IC0gRWZmZWN0IGluc3RhbmNlIChmb3IgYWNjZXNzaW5nIGluc3RhbmNlIHZhcmlhYmxlcykKICAgICAqLwogICAgc2V0VW5pZm9ybXMoZ2wsIGxvY2F0aW9ucywgcGFyYW1zLCBlZmZlY3QgPSBudWxsKSB7CiAgICAgICAgZm9yIChjb25zdCBbbmFtZSwgbG9jYXRpb25dIG9mIE9iamVjdC5lbnRyaWVzKGxvY2F0aW9ucykpIHsKICAgICAgICAgICAgaWYgKCFsb2NhdGlvbikgY29udGludWU7CiAgICAgICAgICAgIAogICAgICAgICAgICBsZXQgdmFsdWUgPSBwYXJhbXNbbmFtZV07CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBIYW5kbGUgcmVzb2x1dGlvbiAoZm9yIFRWIHN0YXRpYyBlZmZlY3QpCiAgICAgICAgICAgIGlmIChuYW1lID09PSAncmVzb2x1dGlvbicgJiYgcGFyYW1zLnJlc29sdXRpb25YICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgIGdsLnVuaWZvcm0yZihsb2NhdGlvbiwgcGFyYW1zLnJlc29sdXRpb25YLCBwYXJhbXMucmVzb2x1dGlvblkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgCiAgICAgICAgICAgIC8vIEhhbmRsZSBjYW52YXMgZGltZW5zaW9ucyBmcm9tIGVmZmVjdCBpbnN0YW5jZSAoZm9yIHBpeGVsaXphdGlvbikKICAgICAgICAgICAgaWYgKG5hbWUgPT09ICdjYW52YXNXaWR0aCcgJiYgZWZmZWN0ICYmIGVmZmVjdC5jYW52YXNXaWR0aCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICBnbC51bmlmb3JtMWYobG9jYXRpb24sIGVmZmVjdC5jYW52YXNXaWR0aCk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAobmFtZSA9PT0gJ2NhbnZhc0hlaWdodCcgJiYgZWZmZWN0ICYmIGVmZmVjdC5jYW52YXNIZWlnaHQgIT09IHVuZGVmaW5lZCkgewogICAgICAgICAgICAgICAgZ2wudW5pZm9ybTFmKGxvY2F0aW9uLCBlZmZlY3QuY2FudmFzSGVpZ2h0KTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBIYW5kbGUgcGl4ZWxDb2xzIGNhbGN1bGF0aW9uIChmb3IgcGl4ZWxpemF0aW9uKQogICAgICAgICAgICBpZiAobmFtZSA9PT0gJ3BpeGVsQ29scycgJiYgZWZmZWN0ICYmIGVmZmVjdC5jYW52YXNXaWR0aCAmJiBlZmZlY3QuY2FudmFzSGVpZ2h0ICYmIHBhcmFtcy5waXhlbFJvd3MpIHsKICAgICAgICAgICAgICAgIGNvbnN0IGFzcGVjdFJhdGlvID0gZWZmZWN0LmNhbnZhc1dpZHRoIC8gZWZmZWN0LmNhbnZhc0hlaWdodDsKICAgICAgICAgICAgICAgIGNvbnN0IHBpeGVsQ29scyA9IE1hdGgucm91bmQocGFyYW1zLnBpeGVsUm93cyAqIGFzcGVjdFJhdGlvKTsKICAgICAgICAgICAgICAgIGdsLnVuaWZvcm0xZihsb2NhdGlvbiwgcGl4ZWxDb2xzKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBIYW5kbGUgdGltZSBmcm9tIGVmZmVjdCBpbnN0YW5jZQogICAgICAgICAgICBpZiAobmFtZSA9PT0gJ3RpbWUnICYmIHZhbHVlID09PSB1bmRlZmluZWQgJiYgZWZmZWN0ICYmIGVmZmVjdC5zdGF0ZSAmJiBlZmZlY3Quc3RhdGUucGFyYW1ldGVycykgewogICAgICAgICAgICAgICAgdmFsdWUgPSBlZmZlY3Quc3RhdGUucGFyYW1ldGVycy50aW1lOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgY29udGludWU7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBTZXQgdW5pZm9ybSBiYXNlZCBvbiB0eXBlCiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7CiAgICAgICAgICAgICAgICBnbC51bmlmb3JtMWYobG9jYXRpb24sIHZhbHVlKTsKICAgICAgICAgICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgewogICAgICAgICAgICAgICAgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMikgewogICAgICAgICAgICAgICAgICAgIGdsLnVuaWZvcm0yZihsb2NhdGlvbiwgdmFsdWVbMF0sIHZhbHVlWzFdKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUubGVuZ3RoID09PSAzKSB7CiAgICAgICAgICAgICAgICAgICAgZ2wudW5pZm9ybTNmKGxvY2F0aW9uLCB2YWx1ZVswXSwgdmFsdWVbMV0sIHZhbHVlWzJdKTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUubGVuZ3RoID09PSA0KSB7CiAgICAgICAgICAgICAgICAgICAgZ2wudW5pZm9ybTRmKGxvY2F0aW9uLCB2YWx1ZVswXSwgdmFsdWVbMV0sIHZhbHVlWzJdLCB2YWx1ZVszXSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUubGVuZ3RoICE9PSB1bmRlZmluZWQpIHsKICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBhcnJheS1saWtlIG9iamVjdHMKICAgICAgICAgICAgICAgIGlmICh2YWx1ZS5sZW5ndGggPT09IDIpIHsKICAgICAgICAgICAgICAgICAgICBnbC51bmlmb3JtMmYobG9jYXRpb24sIHZhbHVlWzBdLCB2YWx1ZVsxXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlLmxlbmd0aCA9PT0gMykgewogICAgICAgICAgICAgICAgICAgIGdsLnVuaWZvcm0zZihsb2NhdGlvbiwgdmFsdWVbMF0sIHZhbHVlWzFdLCB2YWx1ZVsyXSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlLmxlbmd0aCA9PT0gNCkgewogICAgICAgICAgICAgICAgICAgIGdsLnVuaWZvcm00Zihsb2NhdGlvbiwgdmFsdWVbMF0sIHZhbHVlWzFdLCB2YWx1ZVsyXSwgdmFsdWVbM10pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKioKICAgICAqIEhhbmRsZSBjYW52YXMgcmVzaXplCiAgICAgKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBOZXcgd2lkdGgKICAgICAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHQgLSBOZXcgaGVpZ2h0CiAgICAgKi8KICAgIHJlc2l6ZSh3aWR0aCwgaGVpZ2h0KSB7CiAgICAgICAgaWYgKCF0aGlzLnN0YXRlLmlzSW5pdGlhbGl6ZWQpIHJldHVybjsKICAgICAgICAKICAgICAgICBjb25zdCBnbCA9IHRoaXMuc3RhdGUuZ2w7CiAgICAgICAgCiAgICAgICAgLy8gVXBkYXRlIHZpZXdwb3J0CiAgICAgICAgZ2wudmlld3BvcnQoMCwgMCwgd2lkdGgsIGhlaWdodCk7CiAgICAgICAgCiAgICAgICAgLy8gUmVjcmVhdGUgaW50ZXJtZWRpYXRlIHRleHR1cmUgd2l0aCBuZXcgc2l6ZQogICAgICAgIHRoaXMuY3JlYXRlSW50ZXJtZWRpYXRlVGV4dHVyZSh3aWR0aCwgaGVpZ2h0KTsKICAgICAgICAKICAgICAgICB0aGlzLmxvZygnZGVidWcnLCBgUmVzaXplZCB0byAke3dpZHRofXgke2hlaWdodH1gKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBHZXQgcmVuZGVyZXIgc3RhdGUgZm9yIGRlYnVnZ2luZwogICAgICogQHJldHVybnMge09iamVjdH0gQ3VycmVudCBzdGF0ZQogICAgICovCiAgICBnZXRTdGF0ZSgpIHsKICAgICAgICByZXR1cm4gewogICAgICAgICAgICAuLi5zdXBlci5nZXRTdGF0ZSgpLAogICAgICAgICAgICBwcm9ncmFtc0NyZWF0ZWQ6IHRoaXMuc3RhdGUucHJvZ3JhbXMuc2l6ZSwKICAgICAgICAgICAgZWZmZWN0c1JlZ2lzdGVyZWQ6IHRoaXMuc3RhdGUuZWZmZWN0cy5zaXplLAogICAgICAgICAgICBoYXNJbnRlcm1lZGlhdGVUZXh0dXJlOiB0aGlzLnN0YXRlLm11bHRpcGFzcy50ZXh0dXJlICE9PSBudWxsCiAgICAgICAgfTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDbGVhbiB1cCBXZWJHTCByZXNvdXJjZXMKICAgICAqLwogICAgZGVzdHJveSgpIHsKICAgICAgICB0aGlzLmxvZygnaW5mbycsICdEZXN0cm95aW5nIFdlYkdMIHJlbmRlcmVyLi4uJyk7CiAgICAgICAgCiAgICAgICAgY29uc3QgZ2wgPSB0aGlzLnN0YXRlLmdsOwogICAgICAgIAogICAgICAgIGlmICghZ2wpIHJldHVybjsKICAgICAgICAKICAgICAgICAvLyBEZWxldGUgcHJvZ3JhbXMKICAgICAgICBmb3IgKGNvbnN0IHByb2dyYW0gb2YgdGhpcy5zdGF0ZS5wcm9ncmFtcy52YWx1ZXMoKSkgewogICAgICAgICAgICBnbC5kZWxldGVQcm9ncmFtKHByb2dyYW0pOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBEZWxldGUgZnJhbWVidWZmZXIgYW5kIHRleHR1cmUKICAgICAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aXBhc3MuZnJhbWVidWZmZXIpIHsKICAgICAgICAgICAgZ2wuZGVsZXRlRnJhbWVidWZmZXIodGhpcy5zdGF0ZS5tdWx0aXBhc3MuZnJhbWVidWZmZXIpOwogICAgICAgIH0KICAgICAgICBpZiAodGhpcy5zdGF0ZS5tdWx0aXBhc3MudGV4dHVyZSkgewogICAgICAgICAgICBnbC5kZWxldGVUZXh0dXJlKHRoaXMuc3RhdGUubXVsdGlwYXNzLnRleHR1cmUpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICAvLyBEZWxldGUgVkFPCiAgICAgICAgaWYgKHRoaXMuc3RhdGUucXVhZC52YW8pIHsKICAgICAgICAgICAgZ2wuZGVsZXRlVmVydGV4QXJyYXkodGhpcy5zdGF0ZS5xdWFkLnZhbyk7CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIENsZWFyIHN0YXRlCiAgICAgICAgdGhpcy5zdGF0ZS5wcm9ncmFtcy5jbGVhcigpOwogICAgICAgIHRoaXMuc3RhdGUucHJvZ3JhbUluZm8uY2xlYXIoKTsKICAgICAgICB0aGlzLnN0YXRlLmVmZmVjdHMuY2xlYXIoKTsKICAgICAgICB0aGlzLnN0YXRlLmlzSW5pdGlhbGl6ZWQgPSBmYWxzZTsKICAgICAgICAKICAgICAgICB0aGlzLmxvZygnaW5mbycsICdXZWJHTCByZW5kZXJlciBkZXN0cm95ZWQnKTsKICAgIH0KfQoKV2ViR0xSZW5kZXJlcjsKCgovLyBSZW5kZXJlckZhY3RvcnkuanMgLSBBdXRvbWF0aWMgcmVuZGVyZXIgZGV0ZWN0aW9uIGFuZCBpbnN0YW50aWF0aW9uCi8vIERldGVjdHMgR1BVIGNhcGFiaWxpdGllcyBhbmQgY3JlYXRlcyB0aGUgYmVzdCBhdmFpbGFibGUgcmVuZGVyZXIKLy8gUHJpb3JpdHk6IFdlYkdQVSA+IFdlYkdMIDIuMCA+IEVycm9yCgpjbGFzcyBSZW5kZXJlckZhY3RvcnkgewogICAgLyoqCiAgICAgKiBEZXRlY3QgYmVzdCBhdmFpbGFibGUgcmVuZGVyZXIgYW5kIGNyZWF0ZSBpbnN0YW5jZQogICAgICogUHJpb3JpdHk6IFdlYkdQVSA+IFdlYkdMIDIuMAogICAgICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudH0gY2FudmFzIC0gVGFyZ2V0IGNhbnZhcwogICAgICogQHJldHVybnMge1Byb21pc2U8SVJlbmRlcmVyPn0gSW5pdGlhbGl6ZWQgcmVuZGVyZXIKICAgICAqLwogICAgc3RhdGljIGFzeW5jIGNyZWF0ZVJlbmRlcmVyKGNhbnZhcykgewogICAgICAgIExvZ2dlci5pbmZvKCdSRU5ERVJFUicsICdEZXRlY3RpbmcgR1BVIGNhcGFiaWxpdGllcy4uLicpOwogICAgICAgIAogICAgICAgIC8vIEdldCBhdmFpbGFibGUgcmVuZGVyZXJzCiAgICAgICAgY29uc3QgYXZhaWxhYmxlID0gYXdhaXQgUmVuZGVyZXJGYWN0b3J5LmdldEF2YWlsYWJsZVJlbmRlcmVycyhjYW52YXMpOwogICAgICAgIExvZ2dlci5pbmZvKCdSRU5ERVJFUicsICdBdmFpbGFibGUgcmVuZGVyZXJzOicsIGF2YWlsYWJsZSk7CiAgICAgICAgCiAgICAgICAgLy8gVHJ5IFdlYkdQVSBmaXJzdCAoYmVzdCBwZXJmb3JtYW5jZSkKICAgICAgICBpZiAoYXZhaWxhYmxlLndlYmdwdSkgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgTG9nZ2VyLmluZm8oJ1JFTkRFUkVSJywgJ1dlYkdQVSBkZXRlY3RlZCAtIGF0dGVtcHRpbmcgdG8gaW5pdGlhbGl6ZSBXZWJHUFUgcmVuZGVyZXIuLi4nKTsKICAgICAgICAgICAgICAgIGNvbnN0IHJlbmRlcmVyID0gbmV3IFdlYkdQVVJlbmRlcmVyKCk7CiAgICAgICAgICAgICAgICAvLyBQYXNzIHRoZSBhbHJlYWR5LW9idGFpbmVkIGFkYXB0ZXIgdG8gYXZvaWQgYSBzZWNvbmQgcmVxdWVzdEFkYXB0ZXIoKSBjYWxsCiAgICAgICAgICAgICAgICBhd2FpdCByZW5kZXJlci5pbml0aWFsaXplKGNhbnZhcywgYXZhaWxhYmxlLndlYmdwdUFkYXB0ZXIpOwogICAgICAgICAgICAgICAgTG9nZ2VyLmluZm8oJ1JFTkRFUkVSJywgJ+KckyBXZWJHUFUgcmVuZGVyZXIgaW5pdGlhbGl6ZWQgc3VjY2Vzc2Z1bGx5Jyk7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVuZGVyZXI7CiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgICAgICAgICBMb2dnZXIud2FybignUkVOREVSRVInLCAnV2ViR1BVIGluaXRpYWxpemF0aW9uIGZhaWxlZDonLCBlcnJvci5tZXNzYWdlKTsKICAgICAgICAgICAgICAgIExvZ2dlci5pbmZvKCdSRU5ERVJFUicsICdGYWxsaW5nIGJhY2sgdG8gV2ViR0wgMi4wLi4uJyk7CiAgICAgICAgICAgICAgICAvLyBDb250aW51ZSB0byBXZWJHTCBmYWxsYmFjayBiZWxvdwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIAogICAgICAgIC8vIEZhbGwgYmFjayB0byBXZWJHTCAyLjAKICAgICAgICBpZiAoYXZhaWxhYmxlLndlYmdsMikgewogICAgICAgICAgICBMb2dnZXIuaW5mbygnUkVOREVSRVInLCAnSW5pdGlhbGl6aW5nIFdlYkdMIDIuMCByZW5kZXJlci4uLicpOwogICAgICAgICAgICBjb25zdCByZW5kZXJlciA9IG5ldyBXZWJHTFJlbmRlcmVyKCk7CiAgICAgICAgICAgIGF3YWl0IHJlbmRlcmVyLmluaXRpYWxpemUoY2FudmFzKTsKICAgICAgICAgICAgTG9nZ2VyLmluZm8oJ1JFTkRFUkVSJywgJ+KckyBXZWJHTCAyLjAgcmVuZGVyZXIgaW5pdGlhbGl6ZWQgc3VjY2Vzc2Z1bGx5Jyk7CiAgICAgICAgICAgIHJldHVybiByZW5kZXJlcjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLy8gTm8gc3VwcG9ydGVkIHJlbmRlcmVyCiAgICAgICAgTG9nZ2VyLmVycm9yKCdSRU5ERVJFUicsICdOZWl0aGVyIFdlYkdQVSBub3IgV2ViR0wgMi4wIHN1cHBvcnRlZCcpOwogICAgICAgIHRocm93IG5ldyBFcnJvcignTmVpdGhlciBXZWJHUFUgbm9yIFdlYkdMIDIuMCBzdXBwb3J0ZWQgaW4gdGhpcyBicm93c2VyLiBQbGVhc2UgdXBkYXRlIHlvdXIgYnJvd3Nlci4nKTsKICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBDaGVjayBpZiBXZWJHUFUgaXMgYXZhaWxhYmxlIGFuZCB3b3JraW5nCiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gVHJ1ZSBpZiBXZWJHUFUgYXZhaWxhYmxlCiAgICAgKi8KICAgIC8qKgogICAgICogUmV0dXJucyB0aGUgbGl2ZSBHUFVBZGFwdGVyIGlmIFdlYkdQVSBpcyBhdmFpbGFibGUsIG9yIG51bGwgaWYgbm90LgogICAgICogS2VlcGluZyB0aGUgYWRhcHRlciBhbGl2ZSBhdm9pZHMgYSBzZWNvbmQgcmVxdWVzdEFkYXB0ZXIoKSBjYWxsIGluIHRoZSByZW5kZXJlci4KICAgICAqLwogICAgc3RhdGljIGFzeW5jIGdldFdlYkdQVUFkYXB0ZXIoKSB7CiAgICAgICAgaWYgKCFuYXZpZ2F0b3IuZ3B1KSB7CiAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUkVOREVSRVInLCAnbmF2aWdhdG9yLmdwdSBub3QgZm91bmQgLSBXZWJHUFUgbm90IGF2YWlsYWJsZScpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CgogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGNvbnN0IGFkYXB0ZXIgPSBhd2FpdCBuYXZpZ2F0b3IuZ3B1LnJlcXVlc3RBZGFwdGVyKHsKICAgICAgICAgICAgICAgIHBvd2VyUHJlZmVyZW5jZTogJ2hpZ2gtcGVyZm9ybWFuY2UnCiAgICAgICAgICAgIH0pOwoKICAgICAgICAgICAgaWYgKCFhZGFwdGVyKSB7CiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JFTkRFUkVSJywgJ05vIFdlYkdQVSBhZGFwdGVyIGZvdW5kJyk7CiAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgTG9nZ2VyLmRlYnVnKCdSRU5ERVJFUicsICdXZWJHUFUgYWRhcHRlciBhY3F1aXJlZCBkdXJpbmcgZGV0ZWN0aW9uJyk7CiAgICAgICAgICAgIHJldHVybiBhZGFwdGVyOwoKICAgICAgICB9IGNhdGNoIChlcnJvcikgewogICAgICAgICAgICBMb2dnZXIud2FybignUkVOREVSRVInLCAnV2ViR1BVIGRldGVjdGlvbiBmYWlsZWQ6JywgZXJyb3IpOwogICAgICAgICAgICByZXR1cm4gbnVsbDsKICAgICAgICB9CiAgICB9CiAgICAKICAgIC8qKgogICAgICogQ2hlY2sgaWYgV2ViR0wgMi4wIGlzIGF2YWlsYWJsZQogICAgICogQ1JJVElDQUw6IFVzZXMgYSB0ZW1wb3JhcnkgY2FudmFzIHRvIGF2b2lkIGNvbnRhbWluYXRpbmcgdGhlIG1haW4gY2FudmFzIQogICAgICogT25jZSBhIGNhbnZhcyBnZXRzIEFOWSBjb250ZXh0IHR5cGUsIGl0IGNhbm5vdCBnZXQgYSBkaWZmZXJlbnQgY29udGV4dCB0eXBlLgogICAgICogQHJldHVybnMge2Jvb2xlYW59IFRydWUgaWYgV2ViR0wgMi4wIGF2YWlsYWJsZQogICAgICovCiAgICBzdGF0aWMgaXNXZWJHTDJBdmFpbGFibGUoKSB7CiAgICAgICAgdHJ5IHsKICAgICAgICAgICAgLy8gQ3JlYXRlIHRlbXBvcmFyeSBjYW52YXMgZm9yIHRlc3RpbmcgKGRvbid0IHVzZSB0aGUgcmVhbCBjYW52YXMhKQogICAgICAgICAgICBjb25zdCB0ZXN0Q2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7CiAgICAgICAgICAgIGNvbnN0IGdsID0gdGVzdENhbnZhcy5nZXRDb250ZXh0KCd3ZWJnbDInKTsKICAgICAgICAgICAgY29uc3QgYXZhaWxhYmxlID0gZ2wgIT09IG51bGw7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAoYXZhaWxhYmxlKSB7CiAgICAgICAgICAgICAgICBMb2dnZXIuZGVidWcoJ1JFTkRFUkVSJywgJ1dlYkdMIDIuMCBhdmFpbGFibGUnKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIExvZ2dlci5kZWJ1ZygnUkVOREVSRVInLCAnV2ViR0wgMi4wIG5vdCBhdmFpbGFibGUnKTsKICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIGF2YWlsYWJsZTsKICAgICAgICAgICAgCiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHsKICAgICAgICAgICAgTG9nZ2VyLndhcm4oJ1JFTkRFUkVSJywgJ1dlYkdMIDIuMCBkZXRlY3Rpb24gZmFpbGVkOicsIGVycm9yKTsKICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgIH0KICAgIH0KICAgIAogICAgLyoqCiAgICAgKiBHZXQgYWxsIGF2YWlsYWJsZSByZW5kZXJlciB0eXBlcwogICAgICogQHBhcmFtIHtIVE1MQ2FudmFzRWxlbWVudH0gY2FudmFzIC0gQ2FudmFzIChub3QgdXNlZCBmb3IgZGV0ZWN0aW9uIC0gc2VlIG5vdGUgYmVsb3cpCiAgICAgKiBAcmV0dXJucyB7UHJvbWlzZTxPYmplY3Q+fSBBdmFpbGFibGUgcmVuZGVyZXJzIGFuZCBwcmVmZXJyZWQgY2hvaWNlCiAgICAgKiAKICAgICAqIE5PVEU6IFdlIGRvbid0IHVzZSB0aGUgYWN0dWFsIGNhbnZhcyBmb3IgZGV0ZWN0aW9uIGJlY2F1c2UgZ2V0dGluZyBhbnkgY29udGV4dAogICAgICogb24gYSBjYW52YXMgcHJldmVudHMgZ2V0dGluZyBhIGRpZmZlcmVudCBjb250ZXh0IHR5cGUgbGF0ZXIhCiAgICAgKi8KICAgIHN0YXRpYyBhc3luYyBnZXRBdmFpbGFibGVSZW5kZXJlcnMoY2FudmFzKSB7CiAgICAgICAgY29uc3QgYWRhcHRlciA9IGF3YWl0IFJlbmRlcmVyRmFjdG9yeS5nZXRXZWJHUFVBZGFwdGVyKCk7CiAgICAgICAgY29uc3Qgd2ViZ2wyID0gUmVuZGVyZXJGYWN0b3J5LmlzV2ViR0wyQXZhaWxhYmxlKCk7IC8vIFVzZXMgdGVtcCBjYW52YXMgaW50ZXJuYWxseQoKICAgICAgICBjb25zdCBwcmVmZXJyZWQgPSBhZGFwdGVyID8gJ3dlYmdwdScgOiAod2ViZ2wyID8gJ3dlYmdsJyA6ICdub25lJyk7CgogICAgICAgIHJldHVybiB7CiAgICAgICAgICAgIHdlYmdwdTogISFhZGFwdGVyLAogICAgICAgICAgICB3ZWJncHVBZGFwdGVyOiBhZGFwdGVyLCAgIC8vIExpdmUgYWRhcHRlciDigJQgcGFzc2VkIHRvIFdlYkdQVVJlbmRlcmVyIHRvIHNraXAgc2Vjb25kIGluaXQKICAgICAgICAgICAgd2ViZ2wyLAogICAgICAgICAgICBwcmVmZXJyZWQKICAgICAgICB9OwogICAgfQp9CgpSZW5kZXJlckZhY3Rvcnk7CgoKLy8gRWZmZWN0IC0gQmFzZSBjbGFzcyBmb3IgYWxsIFdlYkdQVSBzaGFkZXIgZWZmZWN0cwovLyBQcm92aWRlcyBzdHJ1Y3R1cmVkIHN0YXRlIG1hbmFnZW1lbnQgYW5kIHVuaWZvcm0gYnVmZmVyIGhhbmRsaW5nCgovKioKICogQmFzZSBjbGFzcyBmb3IgYWxs