diff --git a/Sources/CartonKit/Server/StaticArchive.swift b/Sources/CartonKit/Server/StaticArchive.swift index 72350f11..0486153f 100644 --- a/Sources/CartonKit/Server/StaticArchive.swift +++ b/Sources/CartonKit/Server/StaticArchive.swift @@ -4,6 +4,6 @@ public enum StaticResource { public static let dev: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL3JlY29ubmVjdGluZy13ZWJzb2NrZXQvZGlzdC9yZWNvbm5lY3Rpbmctd2Vic29ja2V0LW1qcy5qcwp2YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24oZDIsIGIyKSB7CiAgICBkMi5fX3Byb3RvX18gPSBiMjsKICB9IHx8IGZ1bmN0aW9uKGQyLCBiMikgewogICAgZm9yICh2YXIgcCBpbiBiMikKICAgICAgaWYgKGIyLmhhc093blByb3BlcnR5KHApKQogICAgICAgIGQyW3BdID0gYjJbcF07CiAgfTsKICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKfTsKZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzKGQsIGIpOwogIGZ1bmN0aW9uIF9fKCkgewogICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7CiAgfQogIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKfQpmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7CiAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSAiZnVuY3Rpb24iICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7CiAgaWYgKG0pCiAgICByZXR1cm4gbS5jYWxsKG8pOwogIHJldHVybiB7CiAgICBuZXh0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkKICAgICAgICBvID0gdm9pZCAwOwogICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07CiAgICB9CiAgfTsKfQpmdW5jdGlvbiBfX3JlYWQobywgbikgewogIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07CiAgaWYgKCFtKQogICAgcmV0dXJuIG87CiAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7CiAgdHJ5IHsKICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKQogICAgICBhci5wdXNoKHIudmFsdWUpOwogIH0gY2F0Y2ggKGVycm9yKSB7CiAgICBlID0geyBlcnJvciB9OwogIH0gZmluYWxseSB7CiAgICB0cnkgewogICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVsicmV0dXJuIl0pKQogICAgICAgIG0uY2FsbChpKTsKICAgIH0gZmluYWxseSB7CiAgICAgIGlmIChlKQogICAgICAgIHRocm93IGUuZXJyb3I7CiAgICB9CiAgfQogIHJldHVybiBhcjsKfQpmdW5jdGlvbiBfX3NwcmVhZCgpIHsKICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykKICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTsKICByZXR1cm4gYXI7Cn0KdmFyIEV2ZW50ID0gZnVuY3Rpb24oKSB7CiAgZnVuY3Rpb24gRXZlbnQyKHR5cGUsIHRhcmdldCkgewogICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CiAgICB0aGlzLnR5cGUgPSB0eXBlOwogIH0KICByZXR1cm4gRXZlbnQyOwp9KCk7CnZhciBFcnJvckV2ZW50ID0gZnVuY3Rpb24oX3N1cGVyKSB7CiAgX19leHRlbmRzKEVycm9yRXZlbnQyLCBfc3VwZXIpOwogIGZ1bmN0aW9uIEVycm9yRXZlbnQyKGVycm9yLCB0YXJnZXQpIHsKICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJlcnJvciIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLm1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlOwogICAgX3RoaXMuZXJyb3IgPSBlcnJvcjsKICAgIHJldHVybiBfdGhpczsKICB9CiAgcmV0dXJuIEVycm9yRXZlbnQyOwp9KEV2ZW50KTsKdmFyIENsb3NlRXZlbnQgPSBmdW5jdGlvbihfc3VwZXIpIHsKICBfX2V4dGVuZHMoQ2xvc2VFdmVudDIsIF9zdXBlcik7CiAgZnVuY3Rpb24gQ2xvc2VFdmVudDIoY29kZSwgcmVhc29uLCB0YXJnZXQpIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIGlmIChyZWFzb24gPT09IHZvaWQgMCkgewogICAgICByZWFzb24gPSAiIjsKICAgIH0KICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJjbG9zZSIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLndhc0NsZWFuID0gdHJ1ZTsKICAgIF90aGlzLmNvZGUgPSBjb2RlOwogICAgX3RoaXMucmVhc29uID0gcmVhc29uOwogICAgcmV0dXJuIF90aGlzOwogIH0KICByZXR1cm4gQ2xvc2VFdmVudDI7Cn0oRXZlbnQpOwp2YXIgZ2V0R2xvYmFsV2ViU29ja2V0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKHR5cGVvZiBXZWJTb2NrZXQgIT09ICJ1bmRlZmluZWQiKSB7CiAgICByZXR1cm4gV2ViU29ja2V0OwogIH0KfTsKdmFyIGlzV2ViU29ja2V0ID0gZnVuY3Rpb24odykgewogIHJldHVybiB0eXBlb2YgdyAhPT0gInVuZGVmaW5lZCIgJiYgISF3ICYmIHcuQ0xPU0lORyA9PT0gMjsKfTsKdmFyIERFRkFVTFQgPSB7CiAgbWF4UmVjb25uZWN0aW9uRGVsYXk6IDFlNCwKICBtaW5SZWNvbm5lY3Rpb25EZWxheTogMWUzICsgTWF0aC5yYW5kb20oKSAqIDRlMywKICBtaW5VcHRpbWU6IDVlMywKICByZWNvbm5lY3Rpb25EZWxheUdyb3dGYWN0b3I6IDEuMywKICBjb25uZWN0aW9uVGltZW91dDogNGUzLAogIG1heFJldHJpZXM6IEluZmluaXR5LAogIG1heEVucXVldWVkTWVzc2FnZXM6IEluZmluaXR5LAogIHN0YXJ0Q2xvc2VkOiBmYWxzZSwKICBkZWJ1ZzogZmFsc2UKfTsKdmFyIFJlY29ubmVjdGluZ1dlYlNvY2tldCA9IGZ1bmN0aW9uKCkgewogIGZ1bmN0aW9uIFJlY29ubmVjdGluZ1dlYlNvY2tldDIodXJsLCBwcm90b2NvbHMsIG9wdGlvbnMpIHsKICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7CiAgICAgIG9wdGlvbnMgPSB7fTsKICAgIH0KICAgIHRoaXMuX2xpc3RlbmVycyA9IHsKICAgICAgZXJyb3I6IFtdLAogICAgICBtZXNzYWdlOiBbXSwKICAgICAgb3BlbjogW10sCiAgICAgIGNsb3NlOiBbXQogICAgfTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIHRoaXMuX3Nob3VsZFJlY29ubmVjdCA9IHRydWU7CiAgICB0aGlzLl9jb25uZWN0TG9jayA9IGZhbHNlOwogICAgdGhpcy5fYmluYXJ5VHlwZSA9ICJibG9iIjsKICAgIHRoaXMuX2Nsb3NlQ2FsbGVkID0gZmFsc2U7CiAgICB0aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgIHRoaXMub25jbG9zZSA9IG51bGw7CiAgICB0aGlzLm9uZXJyb3IgPSBudWxsOwogICAgdGhpcy5vbm1lc3NhZ2UgPSBudWxsOwogICAgdGhpcy5vbm9wZW4gPSBudWxsOwogICAgdGhpcy5faGFuZGxlT3BlbiA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgIF90aGlzLl9kZWJ1Zygib3BlbiBldmVudCIpOwogICAgICB2YXIgX2EgPSBfdGhpcy5fb3B0aW9ucy5taW5VcHRpbWUsIG1pblVwdGltZSA9IF9hID09PSB2b2lkIDAgPyBERUZBVUxULm1pblVwdGltZSA6IF9hOwogICAgICBjbGVhclRpbWVvdXQoX3RoaXMuX2Nvbm5lY3RUaW1lb3V0KTsKICAgICAgX3RoaXMuX3VwdGltZVRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5fYWNjZXB0T3BlbigpOwogICAgICB9LCBtaW5VcHRpbWUpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fbWVzc2FnZVF1ZXVlLmZvckVhY2goZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHJldHVybiBfdGhpcy5fd3Muc2VuZChtZXNzYWdlKTsKICAgICAgfSk7CiAgICAgIF90aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgICAgaWYgKF90aGlzLm9ub3BlbikgewogICAgICAgIF90aGlzLm9ub3BlbihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5vcGVuLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZU1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkgewogICAgICBfdGhpcy5fZGVidWcoIm1lc3NhZ2UgZXZlbnQiKTsKICAgICAgaWYgKF90aGlzLm9ubWVzc2FnZSkgewogICAgICAgIF90aGlzLm9ubWVzc2FnZShldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5tZXNzYWdlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUVycm9yID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJlcnJvciBldmVudCIsIGV2ZW50Lm1lc3NhZ2UpOwogICAgICBfdGhpcy5fZGlzY29ubmVjdCh2b2lkIDAsIGV2ZW50Lm1lc3NhZ2UgPT09ICJUSU1FT1VUIiA/ICJ0aW1lb3V0IiA6IHZvaWQgMCk7CiAgICAgIGlmIChfdGhpcy5vbmVycm9yKSB7CiAgICAgICAgX3RoaXMub25lcnJvcihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJleGVjIGVycm9yIGxpc3RlbmVycyIpOwogICAgICBfdGhpcy5fbGlzdGVuZXJzLmVycm9yLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgICBfdGhpcy5fY29ubmVjdCgpOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUNsb3NlID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJjbG9zZSBldmVudCIpOwogICAgICBfdGhpcy5fY2xlYXJUaW1lb3V0cygpOwogICAgICBpZiAoX3RoaXMuX3Nob3VsZFJlY29ubmVjdCkgewogICAgICAgIF90aGlzLl9jb25uZWN0KCk7CiAgICAgIH0KICAgICAgaWYgKF90aGlzLm9uY2xvc2UpIHsKICAgICAgICBfdGhpcy5vbmNsb3NlKGV2ZW50KTsKICAgICAgfQogICAgICBfdGhpcy5fbGlzdGVuZXJzLmNsb3NlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX3VybCA9IHVybDsKICAgIHRoaXMuX3Byb3RvY29scyA9IHByb3RvY29sczsKICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zOwogICAgaWYgKHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQpIHsKICAgICAgdGhpcy5fc2hvdWxkUmVjb25uZWN0ID0gZmFsc2U7CiAgICB9CiAgICB0aGlzLl9jb25uZWN0KCk7CiAgfQogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ09OTkVDVElORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiAwOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0MiwgIk9QRU4iLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gMTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIsICJDTE9TSU5HIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ0xPU0VEIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDM7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNPTk5FQ1RJTkciLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5DT05ORUNUSU5HOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJPUEVOIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIFJlY29ubmVjdGluZ1dlYlNvY2tldDIuT1BFTjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiQ0xPU0lORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NJTkc7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNMT1NFRCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRDsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYmluYXJ5VHlwZSIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmJpbmFyeVR5cGUgOiB0aGlzLl9iaW5hcnlUeXBlOwogICAgfSwKICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgdGhpcy5fYmluYXJ5VHlwZSA9IHZhbHVlOwogICAgICBpZiAodGhpcy5fd3MpIHsKICAgICAgICB0aGlzLl93cy5iaW5hcnlUeXBlID0gdmFsdWU7CiAgICAgIH0KICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicmV0cnlDb3VudCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBNYXRoLm1heCh0aGlzLl9yZXRyeUNvdW50LCAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYnVmZmVyZWRBbW91bnQiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICB2YXIgYnl0ZXMgPSB0aGlzLl9tZXNzYWdlUXVldWUucmVkdWNlKGZ1bmN0aW9uKGFjYywgbWVzc2FnZSkgewogICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgIGFjYyArPSBtZXNzYWdlLmxlbmd0aDsKICAgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBCbG9iKSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5zaXplOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5ieXRlTGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYWNjOwogICAgICB9LCAwKTsKICAgICAgcmV0dXJuIGJ5dGVzICsgKHRoaXMuX3dzID8gdGhpcy5fd3MuYnVmZmVyZWRBbW91bnQgOiAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiZXh0ZW5zaW9ucyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmV4dGVuc2lvbnMgOiAiIjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicHJvdG9jb2wiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gdGhpcy5fd3MgPyB0aGlzLl93cy5wcm90b2NvbCA6ICIiOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJyZWFkeVN0YXRlIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKHRoaXMuX3dzKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX3dzLnJlYWR5U3RhdGU7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQgPyBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRCA6IFJlY29ubmVjdGluZ1dlYlNvY2tldDIuQ09OTkVDVElORzsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAidXJsIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIHRoaXMuX3dzID8gdGhpcy5fd3MudXJsIDogIiI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICBpZiAoY29kZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvZGUgPSAxZTM7CiAgICB9CiAgICB0aGlzLl9jbG9zZUNhbGxlZCA9IHRydWU7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSBmYWxzZTsKICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlIGVucXVldWVkOiBubyB3cyBpbnN0YW5jZSIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlOiBhbHJlYWR5IGNsb3NlZCIpOwogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSB0cnVlOwogICAgdGhpcy5fY2xvc2VDYWxsZWQgPSBmYWxzZTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIGlmICghdGhpcy5fd3MgfHwgdGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fY29ubmVjdCgpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5fZGlzY29ubmVjdChjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9jb25uZWN0KCk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSkgewogICAgaWYgKHRoaXMuX3dzICYmIHRoaXMuX3dzLnJlYWR5U3RhdGUgPT09IHRoaXMuT1BFTikgewogICAgICB0aGlzLl9kZWJ1Zygic2VuZCIsIGRhdGEpOwogICAgICB0aGlzLl93cy5zZW5kKGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucy5tYXhFbnF1ZXVlZE1lc3NhZ2VzLCBtYXhFbnF1ZXVlZE1lc3NhZ2VzID0gX2EgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4RW5xdWV1ZWRNZXNzYWdlcyA6IF9hOwogICAgICBpZiAodGhpcy5fbWVzc2FnZVF1ZXVlLmxlbmd0aCA8IG1heEVucXVldWVkTWVzc2FnZXMpIHsKICAgICAgICB0aGlzLl9kZWJ1ZygiZW5xdWV1ZSIsIGRhdGEpOwogICAgICAgIHRoaXMuX21lc3NhZ2VRdWV1ZS5wdXNoKGRhdGEpOwogICAgICB9CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdLnB1c2gobGlzdGVuZXIpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuZGlzcGF0Y2hFdmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICB2YXIgZV8xLCBfYTsKICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnNbZXZlbnQudHlwZV07CiAgICBpZiAobGlzdGVuZXJzKSB7CiAgICAgIHRyeSB7CiAgICAgICAgZm9yICh2YXIgbGlzdGVuZXJzXzEgPSBfX3ZhbHVlcyhsaXN0ZW5lcnMpLCBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpOyAhbGlzdGVuZXJzXzFfMS5kb25lOyBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpKSB7CiAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNfMV8xLnZhbHVlOwogICAgICAgICAgdGhpcy5fY2FsbEV2ZW50TGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyKTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2ggKGVfMV8xKSB7CiAgICAgICAgZV8xID0geyBlcnJvcjogZV8xXzEgfTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICB0cnkgewogICAgICAgICAgaWYgKGxpc3RlbmVyc18xXzEgJiYgIWxpc3RlbmVyc18xXzEuZG9uZSAmJiAoX2EgPSBsaXN0ZW5lcnNfMS5yZXR1cm4pKQogICAgICAgICAgICBfYS5jYWxsKGxpc3RlbmVyc18xKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgaWYgKGVfMSkKICAgICAgICAgICAgdGhyb3cgZV8xLmVycm9yOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdID0gdGhpcy5fbGlzdGVuZXJzW3R5cGVdLmZpbHRlcihmdW5jdGlvbihsKSB7CiAgICAgICAgcmV0dXJuIGwgIT09IGxpc3RlbmVyOwogICAgICB9KTsKICAgIH0KICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9kZWJ1ZyA9IGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3MgPSBbXTsKICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7CiAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTsKICAgIH0KICAgIGlmICh0aGlzLl9vcHRpb25zLmRlYnVnKSB7CiAgICAgIGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIF9fc3ByZWFkKFsiUldTPiJdLCBhcmdzKSk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fZ2V0TmV4dERlbGF5ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX2EgPSB0aGlzLl9vcHRpb25zLCBfYiA9IF9hLnJlY29ubmVjdGlvbkRlbGF5R3Jvd0ZhY3RvciwgcmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQucmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yIDogX2IsIF9jID0gX2EubWluUmVjb25uZWN0aW9uRGVsYXksIG1pblJlY29ubmVjdGlvbkRlbGF5ID0gX2MgPT09IHZvaWQgMCA/IERFRkFVTFQubWluUmVjb25uZWN0aW9uRGVsYXkgOiBfYywgX2QgPSBfYS5tYXhSZWNvbm5lY3Rpb25EZWxheSwgbWF4UmVjb25uZWN0aW9uRGVsYXkgPSBfZCA9PT0gdm9pZCAwID8gREVGQVVMVC5tYXhSZWNvbm5lY3Rpb25EZWxheSA6IF9kOwogICAgdmFyIGRlbGF5ID0gMDsKICAgIGlmICh0aGlzLl9yZXRyeUNvdW50ID4gMCkgewogICAgICBkZWxheSA9IG1pblJlY29ubmVjdGlvbkRlbGF5ICogTWF0aC5wb3cocmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yLCB0aGlzLl9yZXRyeUNvdW50IC0gMSk7CiAgICAgIGlmIChkZWxheSA+IG1heFJlY29ubmVjdGlvbkRlbGF5KSB7CiAgICAgICAgZGVsYXkgPSBtYXhSZWNvbm5lY3Rpb25EZWxheTsKICAgICAgfQogICAgfQogICAgdGhpcy5fZGVidWcoIm5leHQgZGVsYXkiLCBkZWxheSk7CiAgICByZXR1cm4gZGVsYXk7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fd2FpdCA9IGZ1bmN0aW9uKCkgewogICAgdmFyIF90aGlzID0gdGhpczsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7CiAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgX3RoaXMuX2dldE5leHREZWxheSgpKTsKICAgIH0pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2dldE5leHRVcmwgPSBmdW5jdGlvbih1cmxQcm92aWRlcikgewogICAgaWYgKHR5cGVvZiB1cmxQcm92aWRlciA9PT0gInN0cmluZyIpIHsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1cmxQcm92aWRlcik7CiAgICB9CiAgICBpZiAodHlwZW9mIHVybFByb3ZpZGVyID09PSAiZnVuY3Rpb24iKSB7CiAgICAgIHZhciB1cmwgPSB1cmxQcm92aWRlcigpOwogICAgICBpZiAodHlwZW9mIHVybCA9PT0gInN0cmluZyIpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVybCk7CiAgICAgIH0KICAgICAgaWYgKCEhdXJsLnRoZW4pIHsKICAgICAgICByZXR1cm4gdXJsOwogICAgICB9CiAgICB9CiAgICB0aHJvdyBFcnJvcigiSW52YWxpZCBVUkwiKTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jb25uZWN0ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX3RoaXMgPSB0aGlzOwogICAgaWYgKHRoaXMuX2Nvbm5lY3RMb2NrIHx8ICF0aGlzLl9zaG91bGRSZWNvbm5lY3QpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fY29ubmVjdExvY2sgPSB0cnVlOwogICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucywgX2IgPSBfYS5tYXhSZXRyaWVzLCBtYXhSZXRyaWVzID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4UmV0cmllcyA6IF9iLCBfYyA9IF9hLmNvbm5lY3Rpb25UaW1lb3V0LCBjb25uZWN0aW9uVGltZW91dCA9IF9jID09PSB2b2lkIDAgPyBERUZBVUxULmNvbm5lY3Rpb25UaW1lb3V0IDogX2MsIF9kID0gX2EuV2ViU29ja2V0LCBXZWJTb2NrZXQyID0gX2QgPT09IHZvaWQgMCA/IGdldEdsb2JhbFdlYlNvY2tldCgpIDogX2Q7CiAgICBpZiAodGhpcy5fcmV0cnlDb3VudCA+PSBtYXhSZXRyaWVzKSB7CiAgICAgIHRoaXMuX2RlYnVnKCJtYXggcmV0cmllcyByZWFjaGVkIiwgdGhpcy5fcmV0cnlDb3VudCwgIj49IiwgbWF4UmV0cmllcyk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIHRoaXMuX3JldHJ5Q291bnQrKzsKICAgIHRoaXMuX2RlYnVnKCJjb25uZWN0IiwgdGhpcy5fcmV0cnlDb3VudCk7CiAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lcnMoKTsKICAgIGlmICghaXNXZWJTb2NrZXQoV2ViU29ja2V0MikpIHsKICAgICAgdGhyb3cgRXJyb3IoIk5vIHZhbGlkIFdlYlNvY2tldCBjbGFzcyBwcm92aWRlZCIpOwogICAgfQogICAgdGhpcy5fd2FpdCgpLnRoZW4oZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBfdGhpcy5fZ2V0TmV4dFVybChfdGhpcy5fdXJsKTsKICAgIH0pLnRoZW4oZnVuY3Rpb24odXJsKSB7CiAgICAgIGlmIChfdGhpcy5fY2xvc2VDYWxsZWQpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJjb25uZWN0IiwgeyB1cmwsIHByb3RvY29sczogX3RoaXMuX3Byb3RvY29scyB9KTsKICAgICAgX3RoaXMuX3dzID0gX3RoaXMuX3Byb3RvY29scyA/IG5ldyBXZWJTb2NrZXQyKHVybCwgX3RoaXMuX3Byb3RvY29scykgOiBuZXcgV2ViU29ja2V0Mih1cmwpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fY29ubmVjdExvY2sgPSBmYWxzZTsKICAgICAgX3RoaXMuX2FkZExpc3RlbmVycygpOwogICAgICBfdGhpcy5fY29ubmVjdFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5faGFuZGxlVGltZW91dCgpOwogICAgICB9LCBjb25uZWN0aW9uVGltZW91dCk7CiAgICB9KTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9oYW5kbGVUaW1lb3V0ID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLl9kZWJ1ZygidGltZW91dCBldmVudCIpOwogICAgdGhpcy5faGFuZGxlRXJyb3IobmV3IEVycm9yRXZlbnQoRXJyb3IoIlRJTUVPVVQiKSwgdGhpcykpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2Rpc2Nvbm5lY3QgPSBmdW5jdGlvbihjb2RlLCByZWFzb24pIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJzKCk7CiAgICB0cnkgewogICAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9oYW5kbGVDbG9zZShuZXcgQ2xvc2VFdmVudChjb2RlLCByZWFzb24sIHRoaXMpKTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fYWNjZXB0T3BlbiA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5fZGVidWcoImFjY2VwdCBvcGVuIik7CiAgICB0aGlzLl9yZXRyeUNvdW50ID0gMDsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jYWxsRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBsaXN0ZW5lcikgewogICAgaWYgKCJoYW5kbGVFdmVudCIgaW4gbGlzdGVuZXIpIHsKICAgICAgbGlzdGVuZXIuaGFuZGxlRXZlbnQoZXZlbnQpOwogICAgfSBlbHNlIHsKICAgICAgbGlzdGVuZXIoZXZlbnQpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX3JlbW92ZUxpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygicmVtb3ZlTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2FkZExpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygiYWRkTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2NsZWFyVGltZW91dHMgPSBmdW5jdGlvbigpIHsKICAgIGNsZWFyVGltZW91dCh0aGlzLl9jb25uZWN0VGltZW91dCk7CiAgICBjbGVhclRpbWVvdXQodGhpcy5fdXB0aW1lVGltZW91dCk7CiAgfTsKICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0MjsKfSgpOwp2YXIgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdCA9IFJlY29ubmVjdGluZ1dlYlNvY2tldDsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJncywgZW52LCBmZHMsIG9wdGlvbnMgPSB7fSkgewogICAgdGhpcy5hcmdzID0gW107CiAgICB0aGlzLmVudiA9IFtdOwogICAgdGhpcy5mZHMgPSBbXTsKICAgIGRlYnVnLmVuYWJsZShvcHRpb25zLmRlYnVnKTsKICAgIHRoaXMuYXJncyA9IGFyZ3M7CiAgICB0aGlzLmVudiA9IGVudjsKICAgIHRoaXMuZmRzID0gZmRzOwogICAgY29uc3Qgc2VsZiA9IHRoaXM7CiAgICB0aGlzLndhc2lJbXBvcnQgPSB7IGFyZ3Nfc2l6ZXNfZ2V0KGFyZ2MsIGFyZ3ZfYnVmX3NpemUpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ2MsIHNlbGYuYXJncy5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGFyZyBvZiBzZWxmLmFyZ3MpIHsKICAgICAgICBidWZfc2l6ZSArPSBhcmcubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3ZfYnVmX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoYXJnYywgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGFyZ3NfZ2V0KGFyZ3YsIGFyZ3ZfYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2FyZ3ZfYnVmID0gYXJndl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5hcmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihhcmd2LCBhcmd2X2J1ZiwgdHJ1ZSk7CiAgICAgICAgYXJndiArPSA0OwogICAgICAgIGNvbnN0IGFyZyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmFyZ3NbaV0pOwogICAgICAgIGJ1ZmZlcjguc2V0KGFyZywgYXJndl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChhcmd2X2J1ZiArIGFyZy5sZW5ndGgsIDApOwogICAgICAgIGFyZ3ZfYnVmICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgICAgZGVidWcubG9nKG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvcmlnX2FyZ3ZfYnVmLCBhcmd2X2J1ZikpKTsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fc2l6ZXNfZ2V0KGVudmlyb25fY291bnQsIGVudmlyb25fc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9jb3VudCwgc2VsZi5lbnYubGVuZ3RoLCB0cnVlKTsKICAgICAgbGV0IGJ1Zl9zaXplID0gMDsKICAgICAgZm9yIChjb25zdCBlbnZpcm9uIG9mIHNlbGYuZW52KSB7CiAgICAgICAgYnVmX3NpemUgKz0gZW52aXJvbi5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9zaXplLCBidWZfc2l6ZSwgdHJ1ZSk7CiAgICAgIGRlYnVnLmxvZyhidWZmZXIuZ2V0VWludDMyKGVudmlyb25fY291bnQsIHRydWUpLCBidWZmZXIuZ2V0VWludDMyKGVudmlyb25fc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fZ2V0KGVudmlyb24sIGVudmlyb25fYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2Vudmlyb25fYnVmID0gZW52aXJvbl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5lbnYubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGVudmlyb24sIGVudmlyb25fYnVmLCB0cnVlKTsKICAgICAgICBlbnZpcm9uICs9IDQ7CiAgICAgICAgY29uc3QgZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmVudltpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoZSwgZW52aXJvbl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChlbnZpcm9uX2J1ZiArIGUubGVuZ3RoLCAwKTsKICAgICAgICBlbnZpcm9uX2J1ZiArPSBlLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfZW52aXJvbl9idWYsIGVudmlyb25fYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgY2xvY2tfcmVzX2dldChpZCwgcmVzX3B0cikgewogICAgICBsZXQgcmVzb2x1dGlvblZhbHVlOwogICAgICBzd2l0Y2ggKGlkKSB7CiAgICAgICAgY2FzZSBDTE9DS0lEX01PTk9UT05JQzogewogICAgICAgICAgcmVzb2x1dGlvblZhbHVlID0gNTAwMG47CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDTE9DS0lEX1JFQUxUSU1FOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSAxMDAwMDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuIEVSUk5PX05PU1lTOwogICAgICB9CiAgICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIHZpZXcuc2V0QmlnVWludDY0KHJlc19wdHIsIHJlc29sdXRpb25WYWx1ZSwgdHJ1ZSk7CiAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgfSwgY2xvY2tfdGltZV9nZXQoaWQsIHByZWNpc2lvbiwgdGltZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChpZCA9PT0gQ0xPQ0tJRF9SRUFMVElNRSkgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgQmlnSW50KG5ldyBEYXRlKCkuZ2V0VGltZSgpKSAqIDEwMDAwMDBuLCB0cnVlKTsKICAgICAgfSBlbHNlIGlmIChpZCA9PSBDTE9DS0lEX01PTk9UT05JQykgewogICAgICAgIGxldCBtb25vdG9uaWNfdGltZTsKICAgICAgICB0cnkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSBCaWdJbnQoTWF0aC5yb3VuZChwZXJmb3JtYW5jZS5ub3coKSAqIDFlNikpOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIG1vbm90b25pY190aW1lID0gMG47CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgbW9ub3RvbmljX3RpbWUsIHRydWUpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgMG4sIHRydWUpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZmRfYWR2aXNlKGZkLCBvZmZzZXQsIGxlbiwgYWR2aWNlKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2FsbG9jYXRlKGZkLCBvZmZzZXQsIGxlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9jbG9zZShmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW2ZkXS5mZF9jbG9zZSgpOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9kYXRhc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfZ2V0KGZkLCBmZHN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZkc3RhdCB9ID0gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmRzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZkc3RhdC53cml0ZV9ieXRlcyhuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlciksIGZkc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfc2V0X2ZsYWdzKGZkLCBmbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZkLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X2dldChmZCwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfZ2V0KCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfc2V0X3NpemUoZmQsIHNpemUpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlYWQoaW92ZWMuYnVmX2xlbiwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgb2Zmc2V0ICs9IEJpZ0ludChkYXRhLmxlbmd0aCk7CiAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggIT0gaW92ZWMuYnVmX2xlbikgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9nZXQoZmQsIGJ1Zl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBwcmVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgYnVmX3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZXN0YXRfZGlyX25hbWUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBjb25zdCBwcmVzdGF0X2Rpcl9uYW1lID0gcHJlc3RhdC5pbm5lci5wcl9uYW1lOwogICAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgICBidWZmZXI4LnNldChwcmVzdGF0X2Rpcl9uYW1lLnNsaWNlKDAsIHBhdGhfbGVuKSwgcGF0aF9wdHIpOwogICAgICAgIHJldHVybiBwcmVzdGF0X2Rpcl9uYW1lLmJ5dGVMZW5ndGggPiBwYXRoX2xlbiA/IEVSUk5PX05BTUVUT09MT05HIDogRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHdyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbndyaXR0ZW5fcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IENpb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbndyaXR0ZW4gPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCBkYXRhID0gYnVmZmVyOC5zbGljZShpb3ZlYy5idWYsIGlvdmVjLmJ1ZiArIGlvdmVjLmJ1Zl9sZW4pOwogICAgICAgICAgY29uc3QgeyByZXQsIG53cml0dGVuOiBud3JpdHRlbl9wYXJ0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHdyaXRlKGRhdGEsIG9mZnNldCk7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIG53cml0dGVuICs9IG53cml0dGVuX3BhcnQ7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KG53cml0dGVuX3BhcnQpOwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG5yZWFkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBJb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbnJlYWQgPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLmZkX3JlYWQoaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGEsIGlvdmVjLmJ1Zik7CiAgICAgICAgICBucmVhZCArPSBkYXRhLmxlbmd0aDsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkZGlyKGZkLCBidWYsIGJ1Zl9sZW4sIGNvb2tpZSwgYnVmdXNlZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgbGV0IGJ1ZnVzZWQgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGlyZW50IH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKTsKICAgICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChkaXJlbnQgPT0gbnVsbCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5oZWFkX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNvbnN0IGhlYWRfYnl0ZXMgPSBuZXcgQXJyYXlCdWZmZXIoZGlyZW50LmhlYWRfbGVuZ3RoKCkpOwogICAgICAgICAgZGlyZW50LndyaXRlX2hlYWRfYnl0ZXMobmV3IERhdGFWaWV3KGhlYWRfYnl0ZXMpLCAwKTsKICAgICAgICAgIGJ1ZmZlcjguc2V0KG5ldyBVaW50OEFycmF5KGhlYWRfYnl0ZXMpLnNsaWNlKDAsIE1hdGgubWluKGhlYWRfYnl0ZXMuYnl0ZUxlbmd0aCwgYnVmX2xlbiAtIGJ1ZnVzZWQpKSwgYnVmKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50LmhlYWRfbGVuZ3RoKCk7CiAgICAgICAgICBpZiAoYnVmX2xlbiAtIGJ1ZnVzZWQgPCBkaXJlbnQubmFtZV9sZW5ndGgoKSkgewogICAgICAgICAgICBidWZ1c2VkID0gYnVmX2xlbjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBkaXJlbnQud3JpdGVfbmFtZV9ieXRlcyhidWZmZXI4LCBidWYsIGJ1Zl9sZW4gLSBidWZ1c2VkKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50Lm5hbWVfbGVuZ3RoKCk7CiAgICAgICAgICBjb29raWUgPSBkaXJlbnQuZF9uZXh0OwogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcmVudW1iZXIoZmQsIHRvKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW3RvXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCByZXQgPSBzZWxmLmZkc1t0b10uZmRfY2xvc2UoKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzW3RvXSA9IHNlbGYuZmRzW2ZkXTsKICAgICAgICBzZWxmLmZkc1tmZF0gPSB2b2lkIDA7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3NlZWsoZmQsIG9mZnNldCwgd2hlbmNlLCBvZmZzZXRfb3V0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIG9mZnNldDogb2Zmc2V0X291dCB9ID0gc2VsZi5mZHNbZmRdLmZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdJbnQ2NChvZmZzZXRfb3V0X3B0ciwgb2Zmc2V0X291dCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF90ZWxsKGZkLCBvZmZzZXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfdGVsbCgpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQob2Zmc2V0X3B0ciwgb2Zmc2V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF93cml0ZShmZCwgaW92c19wdHIsIGlvdnNfbGVuLCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF93cml0ZShkYXRhKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIGlmIChud3JpdHRlbl9wYXJ0ICE9IGRhdGEuYnl0ZUxlbmd0aCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9nZXQoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGZpbGVzdGF0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2xpbmsob2xkX2ZkLCBvbGRfZmxhZ3MsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW29sZF9mZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW29sZF9mZF0ucGF0aF9sb29rdXAob2xkX3BhdGgsIG9sZF9mbGFncyk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgZmFsc2UpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX29wZW4oZmQsIGRpcmZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncywgb3BlbmVkX2ZkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgpOwogICAgICAgIGNvbnN0IHsgcmV0LCBmZF9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGgsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncyk7CiAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBzZWxmLmZkcy5wdXNoKGZkX29iaik7CiAgICAgICAgY29uc3Qgb3BlbmVkX2ZkID0gc2VsZi5mZHMubGVuZ3RoIC0gMTsKICAgICAgICBidWZmZXIuc2V0VWludDMyKG9wZW5lZF9mZF9wdHIsIG9wZW5lZF9mZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVhZGxpbmsoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbiwgYnVmX3B0ciwgYnVmX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3JlYWRsaW5rKHBhdGgpOwogICAgICAgIGlmIChkYXRhICE9IG51bGwpIHsKICAgICAgICAgIGNvbnN0IGRhdGFfYnVmID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGRhdGEpOwogICAgICAgICAgaWYgKGRhdGFfYnVmLmxlbmd0aCA+IGJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIDAsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGFfYnVmLCBidWZfcHRyKTsKICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBkYXRhX2J1Zi5sZW5ndGgsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbW92ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbmFtZShmZCwgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCAmJiBzZWxmLmZkc1tuZXdfZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICBsZXQgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfdW5saW5rKG9sZF9wYXRoKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldCA9IHNlbGYuZmRzW25ld19mZF0ucGF0aF9saW5rKG5ld19wYXRoLCBpbm9kZV9vYmosIHRydWUpOwogICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgaWYgKHNlbGYuZmRzW2ZkXS5wYXRoX2xpbmsob2xkX3BhdGgsIGlub2RlX29iaiwgdHJ1ZSkgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICB0aHJvdyAicGF0aF9saW5rIHNob3VsZCBhbHdheXMgcmV0dXJuIHN1Y2Nlc3Mgd2hlbiByZWxpbmtpbmcgYW4gaW5vZGUgYmFjayB0byB0aGUgb3JpZ2luYWwgcGxhY2UiOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3N5bWxpbmsob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIGZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfdW5saW5rX2ZpbGUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmtfZmlsZShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGgsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfcmVhZGxpbmsocGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG51bGwgfTsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQp9Owp2YXIgSW5vZGUgPSBjbGFzcyB7Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZzX21lbS5qcwp2YXIgT3BlbkZpbGUgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gb2Zmc2V0ICsgbGVuKSB7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBsZW4pKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCAwKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBzaXplKSB7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5maWxlLmRhdGEuYnVmZmVyLnNsaWNlKDAsIE51bWJlcihzaXplKSkpOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIoc2l6ZSkpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIodGhpcy5maWxlX3BvcyksIE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KHNpemUpKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChzbGljZS5sZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKG9mZnNldCksIE51bWJlcihvZmZzZXQgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgbGV0IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgc3dpdGNoICh3aGVuY2UpIHsKICAgICAgY2FzZSBXSEVOQ0VfU0VUOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9DVVI6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSB0aGlzLmZpbGVfcG9zICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9FTkQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBCaWdJbnQodGhpcy5maWxlLmRhdGEuYnl0ZUxlbmd0aCkgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgaWYgKGNhbGN1bGF0ZWRfb2Zmc2V0IDwgMCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICB0aGlzLmZpbGVfcG9zID0gY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcihvZmZzZXQpKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmZpbGUuc3RhdCgpIH07CiAgfQogIGNvbnN0cnVjdG9yKGZpbGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmZpbGVfcG9zID0gMG47CiAgICB0aGlzLmZpbGUgPSBmaWxlOwogIH0KfTsKdmFyIE9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9ESVJFQ1RPUlksIDApIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgZGVidWcubG9nKCJyZWFkZGlyX3NpbmdsZSIsIGNvb2tpZSk7CiAgICAgIGRlYnVnLmxvZyhjb29raWUsIHRoaXMuZGlyLmNvbnRlbnRzLmtleXMoKSk7CiAgICB9CiAgICBpZiAoY29va2llID09IDBuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDFuLCAiLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0gZWxzZSBpZiAoY29va2llID09IDFuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDJuLCAiLi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9CiAgICBpZiAoY29va2llID49IEJpZ0ludCh0aGlzLmRpci5jb250ZW50cy5zaXplKSArIDJuKSB7CiAgICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBbbmFtZSwgZW50cnldID0gQXJyYXkuZnJvbSh0aGlzLmRpci5jb250ZW50cy5lbnRyaWVzKCkpW051bWJlcihjb29raWUgLSAybildOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG5ldyBEaXJlbnQoY29va2llICsgMW4sIG5hbWUsIGVudHJ5LnN0YXQoKS5maWxldHlwZSkgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9lcnIsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IGVudHJ5LnN0YXQoKSB9OwogIH0KICBwYXRoX2xvb2t1cChwYXRoX3N0ciwgZGlyZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoX3N0ciwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgaWYgKHJldCAhPSBFUlJOT19OT0VOVCkgewogICAgICAgIHJldHVybiB7IHJldCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfQ1JFQVQpID09IE9GTEFHU19DUkVBVCkgewogICAgICAgIGNvbnN0IHsgcmV0OiByZXQyLCBlbnRyeTogbmV3X2VudHJ5IH0gPSB0aGlzLmRpci5jcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZKTsKICAgICAgICBpZiAobmV3X2VudHJ5ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiB7IHJldDogcmV0MiwgZmRfb2JqOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGVudHJ5ID0gbmV3X2VudHJ5OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICB9IGVsc2UgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRVhDTCkgPT0gT0ZMQUdTX0VYQ0wpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIGVudHJ5LnBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncyk7CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gdGhpcy5wYXRoX29wZW4oMCwgcGF0aCwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIGNvbnN0IHNvdXJjZV9pc19kaXIgPSBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBjb25zdCB0YXJnZXRfaXNfZGlyID0gZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgaWYgKHNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIGlmIChhbGxvd19kaXIgJiYgZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHsKICAgICAgICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplID09IDApIHsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChzb3VyY2VfaXNfZGlyICYmICF0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgICAgfSBlbHNlIGlmICghc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgICB9IGVsc2UgaWYgKGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSkgewogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgfQogICAgfQogICAgaWYgKCFhbGxvd19kaXIgJiYgaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fUEVSTTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIGlub2RlKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3VubGluayhwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF91bmxpbmtfZmlsZShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHx8IGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICB9CiAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSAhPT0gMCkgewogICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICB9CiAgICBpZiAoIXBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpKSB7CiAgICAgIHJldHVybiBFUlJOT19OT0VOVDsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmRpci5zdGF0KCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBjb25zdHJ1Y3RvcihkaXIpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRpciA9IGRpcjsKICB9Cn07CnZhciBQcmVvcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBPcGVuRGlyZWN0b3J5IHsKICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgcHJlc3RhdDogUHJlc3RhdC5kaXIodGhpcy5wcmVzdGF0X25hbWUpIH07CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnRzKSB7CiAgICBzdXBlcihuZXcgRGlyZWN0b3J5KGNvbnRlbnRzKSk7CiAgICB0aGlzLnByZXN0YXRfbmFtZSA9IG5hbWU7CiAgfQp9Owp2YXIgRmlsZSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgaWYgKHRoaXMucmVhZG9ubHkgJiYgKGZzX3JpZ2h0c19iYXNlICYgQmlnSW50KFJJR0hUU19GRF9XUklURSkpID09IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19UUlVOQykgPT0gT0ZMQUdTX1RSVU5DKSB7CiAgICAgIGlmICh0aGlzLnJlYWRvbmx5KQogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KFtdKTsKICAgIH0KICAgIGNvbnN0IGZpbGUgPSBuZXcgT3BlbkZpbGUodGhpcyk7CiAgICBpZiAoZmRfZmxhZ3MgJiBGREZMQUdTX0FQUEVORCkKICAgICAgZmlsZS5mZF9zZWVrKDBuLCBXSEVOQ0VfRU5EKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZmRfb2JqOiBmaWxlIH07CiAgfQogIGdldCBzaXplKCkgewogICAgcmV0dXJuIEJpZ0ludCh0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgdGhpcy5zaXplKTsKICB9CiAgY29uc3RydWN0b3IoZGF0YSwgb3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgdGhpcy5yZWFkb25seSA9ICEhb3B0aW9ucz8ucmVhZG9ubHk7CiAgfQp9Owp2YXIgUGF0aCA9IGNsYXNzIFBhdGgyIHsKICBzdGF0aWMgZnJvbShwYXRoKSB7CiAgICBjb25zdCBzZWxmID0gbmV3IFBhdGgyKCk7CiAgICBzZWxmLmlzX2RpciA9IHBhdGguZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVENBUEFCTEUsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGlmIChwYXRoLmluY2x1ZGVzKCJcMCIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGguc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aCkgewogICAgbGV0IGVudHJ5ID0gdGhpczsKICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgucGFydHMpIHsKICAgICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgICAgY29uc3QgY2hpbGQgPSBlbnRyeS5jb250ZW50cy5nZXQoY29tcG9uZW50KTsKICAgICAgaWYgKGNoaWxkICE9PSB2b2lkIDApIHsKICAgICAgICBlbnRyeSA9IGNoaWxkOwogICAgICB9IGVsc2UgewogICAgICAgIGRlYnVnLmxvZyhjb21wb25lbnQpOwogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBhbGxvd191bmRlZmluZWQpIHsKICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5wYXJ0cy5wb3AoKTsKICAgIGlmIChmaWxlbmFtZSA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldDogZW50cnlfcmV0LCBlbnRyeTogcGFyZW50X2VudHJ5IH0gPSB0aGlzLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfTsKICB9CiAgY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCBpc19kaXIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGRlYnVnLmxvZygiY3JlYXRlIiwgcGF0aCk7CiAgICBsZXQgbmV3X2NoaWxkOwogICAgaWYgKCFpc19kaXIpIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IEZpbGUobmV3IEFycmF5QnVmZmVyKDApKTsKICAgIH0gZWxzZSB7CiAgICAgIG5ld19jaGlsZCA9IG5ldyBEaXJlY3RvcnkoLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSk7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBuZXdfY2hpbGQpOwogICAgZW50cnkgPSBuZXdfY2hpbGQ7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGNvbnN0cnVjdG9yKGNvbnRlbnRzKSB7CiAgICBzdXBlcigpOwogICAgaWYgKGNvbnRlbnRzIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgdGhpcy5jb250ZW50cyA9IG5ldyBNYXAoY29udGVudHMpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5jb250ZW50cyA9IGNvbnRlbnRzOwogICAgfQogIH0KfTsKdmFyIENvbnNvbGVTdGRvdXQgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmaWxlc3RhdCA9IG5ldyBGaWxlc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCBCaWdJbnQoMCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdCB9OwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgY29uc3QgZmRzdGF0ID0gbmV3IEZkc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCAwKTsKICAgIGZkc3RhdC5mc19yaWdodHNfYmFzZSA9IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgdGhpcy53cml0ZShkYXRhKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBzdGF0aWMgbGluZUJ1ZmZlcmVkKHdyaXRlKSB7CiAgICBjb25zdCBkZWMgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICBsZXQgbGluZV9idWYgPSAiIjsKICAgIHJldHVybiBuZXcgQ29uc29sZVN0ZG91dCgoYnVmZmVyKSA9PiB7CiAgICAgIGxpbmVfYnVmICs9IGRlYy5kZWNvZGUoYnVmZmVyLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgICAgY29uc3QgbGluZXMgPSBsaW5lX2J1Zi5zcGxpdCgiXG4iKTsKICAgICAgZm9yIChjb25zdCBbaSwgbGluZV0gb2YgbGluZXMuZW50cmllcygpKSB7CiAgICAgICAgaWYgKGkgPCBsaW5lcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICB3cml0ZShsaW5lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGluZV9idWYgPSBsaW5lOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfQogIGNvbnN0cnVjdG9yKHdyaXRlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy53cml0ZSA9IHdyaXRlOwogIH0KfTsKCi8vIGVudHJ5cG9pbnQvY29tbW9uLnRzCnZhciBMaW5lRGVjb2RlciA9IGNsYXNzIHsKICBjb25zdHJ1Y3RvcihvbkxpbmUpIHsKICAgIHRoaXMuZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIHRoaXMuYnVmZmVyID0gIiI7CiAgICB0aGlzLm9uTGluZSA9IG9uTGluZTsKICB9CiAgZGVjb2RlcjsKICBidWZmZXI7CiAgb25MaW5lOwogIHNlbmQoY2h1bmspIHsKICAgIHRoaXMuYnVmZmVyICs9IHRoaXMuZGVjb2Rlci5kZWNvZGUoY2h1bmssIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgY29uc3QgbGluZXMgPSB0aGlzLmJ1ZmZlci5zcGxpdCgiXG4iKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoIC0gMTsgaSsrKSB7CiAgICAgIHRoaXMub25MaW5lKGxpbmVzW2ldKTsKICAgIH0KICAgIHRoaXMuYnVmZmVyID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV07CiAgfQp9Owp2YXIgV2FzbVJ1bm5lciA9IChyYXdPcHRpb25zLCBTd2lmdFJ1bnRpbWUpID0+IHsKICBjb25zdCBvcHRpb25zID0gZGVmYXVsdFJ1bm5lck9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0OwogIGlmIChTd2lmdFJ1bnRpbWUpIHsKICAgIHN3aWZ0ID0gbmV3IFN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJncyA9IG9wdGlvbnMuYXJncyB8fCBbXTsKICBjb25zdCBmZHMgPSBbCiAgICBuZXcgT3BlbkZpbGUobmV3IEZpbGUoW10pKSwKICAgIHN0ZG91dCwKICAgIHN0ZGVyciwKICAgIG5ldyBQcmVvcGVuRGlyZWN0b3J5KCIvIiwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSkKICBdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzLCBbXSwgZmRzLCB7CiAgICBkZWJ1ZzogZmFsc2UKICB9KTsKICBjb25zdCBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0ID0gKGV4dHJhV2FzbUltcG9ydHMsIG1vZHVsZSkgPT4gewogICAgY29uc3QgaW1wb3J0T2JqZWN0ID0gewogICAgICB3YXNpX3NuYXBzaG90X3ByZXZpZXcxOiB3YXNpLndhc2lJbXBvcnQKICAgIH07CiAgICBpZiAoc3dpZnQpIHsKICAgICAgaW1wb3J0T2JqZWN0LmphdmFzY3JpcHRfa2l0ID0gc3dpZnQud2FzbUltcG9ydHM7CiAgICB9CiAgICBpZiAoZXh0cmFXYXNtSW1wb3J0cykgewogICAgICBmb3IgKGNvbnN0IG1vZHVsZU5hbWUgaW4gZXh0cmFXYXNtSW1wb3J0cykgewogICAgICAgIGlmICghaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdKSB7CiAgICAgICAgICBpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0gPSB7fTsKICAgICAgICB9CiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBpbiBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdKSB7CiAgICAgICAgICBpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV1bZW50cnldID0gZXh0cmFXYXNtSW1wb3J0c1ttb2R1bGVOYW1lXVtlbnRyeV07CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBmb3IgKGNvbnN0IGltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKG1vZHVsZSkpIHsKICAgICAgaWYgKCFpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXSkgewogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdID0ge307CiAgICAgIH0KICAgICAgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gImZ1bmN0aW9uIiAmJiAhaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGltcG9ydE9iamVjdDsKICB9OwogIHJldHVybiB7CiAgICBhc3luYyBydW4od2FzbUJ5dGVzLCBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGlmICghZXh0cmFXYXNtSW1wb3J0cykgewogICAgICAgIGV4dHJhV2FzbUltcG9ydHMgPSB7fTsKICAgICAgfQogICAgICBleHRyYVdhc21JbXBvcnRzLl9fc3RhY2tfc2FuaXRpemVyID0gewogICAgICAgIHJlcG9ydF9zdGFja19vdmVyZmxvdzogKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJEZXRlY3RlZCBzdGFjayBidWZmZXIgb3ZlcmZsb3cuIik7CiAgICAgICAgfQogICAgICB9OwogICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseS5jb21waWxlKHdhc21CeXRlcyk7CiAgICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKTsKICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShtb2R1bGUsIGltcG9ydE9iamVjdCk7CiAgICAgIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICAgICAgc3dpZnQuc2V0SW5zdGFuY2UoaW5zdGFuY2UpOwogICAgICB9CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLnN0YXJ0KGluc3RhbmNlKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgICAgICBpZiAoc3dpZnQgJiYgc3dpZnQubWFpbikgewogICAgICAgICAgc3dpZnQubWFpbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMubWFpbiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YoMCwgMCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKfTsKdmFyIGRlZmF1bHRSdW5uZXJPcHRpb25zID0gKG9wdGlvbnMpID0+IHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIHJldHVybiBvcHRpb25zOwp9OwoKLy8gZW50cnlwb2ludC9kZXYudHMKdmFyIHNvY2tldCA9IG5ldyByZWNvbm5lY3Rpbmdfd2Vic29ja2V0X21qc19kZWZhdWx0KGB3czovLyR7bG9jYXRpb24uaG9zdH0vd2F0Y2hlcmApOwpzb2NrZXQuYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsIChtZXNzYWdlKSA9PiB7CiAgaWYgKG1lc3NhZ2UuZGF0YSA9PT0gInJlbG9hZCIpIHsKICAgIGxvY2F0aW9uLnJlbG9hZCgpOwogIH0KfSk7CnZhciBzdGFydFdhc2lUYXNrID0gYXN5bmMgKCkgPT4gewogIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goIi9tYWluLndhc20iKTsKICBjb25zdCByZXNwb25zZUFycmF5QnVmZmVyID0gYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTsKICBsZXQgcnVudGltZUNvbnN0cnVjdG9yID0gdm9pZCAwOwogIHRyeSB7CiAgICBjb25zdCB7IFN3aWZ0UnVudGltZSB9ID0gYXdhaXQgaW1wb3J0KAogICAgICAvLyBAdHMtaWdub3JlCiAgICAgICIuL0phdmFTY3JpcHRLaXRfSmF2YVNjcmlwdEtpdC5yZXNvdXJjZXMvUnVudGltZS9pbmRleC5tanMiCiAgICApOwogICAgcnVudGltZUNvbnN0cnVjdG9yID0gU3dpZnRSdW50aW1lOwogIH0gY2F0Y2ggewogICAgY29uc29sZS5sb2coIkphdmFTY3JpcHRLaXQgbW9kdWxlIG5vdCBhdmFpbGFibGUsIHJ1bm5pbmcgd2l0aG91dCBKYXZhU2NyaXB0S2l0IHJ1bnRpbWUuIik7CiAgfQogIGNvbnN0IHdhc21SdW5uZXIgPSBXYXNtUnVubmVyKHsKICAgIG9uU3Rkb3V0KGNodW5rKSB7CiAgICAgIGNvbnN0IGtpbmRCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoMik7CiAgICAgIG5ldyBEYXRhVmlldyhraW5kQnVmZmVyKS5zZXRVaW50MTYoMCwgMTAwMSwgdHJ1ZSk7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDIgKyBjaHVuay5sZW5ndGgpOwogICAgICBidWZmZXIuc2V0KG5ldyBVaW50OEFycmF5KGtpbmRCdWZmZXIpLCAwKTsKICAgICAgYnVmZmVyLnNldChjaHVuaywgMik7CiAgICAgIHNvY2tldC5zZW5kKGJ1ZmZlcik7CiAgICB9LAogICAgb25TdGRvdXRMaW5lKGxpbmUpIHsKICAgICAgY29uc29sZS5sb2cobGluZSk7CiAgICB9LAogICAgb25TdGRlcnIoY2h1bmspIHsKICAgICAgY29uc3Qga2luZEJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcigyKTsKICAgICAgbmV3IERhdGFWaWV3KGtpbmRCdWZmZXIpLnNldFVpbnQxNigwLCAxMDAyLCB0cnVlKTsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoMiArIGNodW5rLmxlbmd0aCk7CiAgICAgIGJ1ZmZlci5zZXQobmV3IFVpbnQ4QXJyYXkoa2luZEJ1ZmZlciksIDApOwogICAgICBidWZmZXIuc2V0KGNodW5rLCAyKTsKICAgICAgc29ja2V0LnNlbmQoYnVmZmVyKTsKICAgIH0sCiAgICBvblN0ZGVyckxpbmUobGluZSkgewogICAgICBjb25zb2xlLmVycm9yKGxpbmUpOwogICAgfQogIH0sIHJ1bnRpbWVDb25zdHJ1Y3Rvcik7CiAgY29uc3Qgd2FzbUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkocmVzcG9uc2VBcnJheUJ1ZmZlcikuYnVmZmVyOwogIGF3YWl0IHdhc21SdW5uZXIucnVuKHdhc21CeXRlcyk7Cn07CmZ1bmN0aW9uIGhhbmRsZUVycm9yKGUpIHsKICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yKSB7CiAgICBjb25zdCBzdGFjayA9IGUuc3RhY2s7CiAgICBpZiAoc3RhY2sgIT0gbnVsbCkgewogICAgICBzb2NrZXQuc2VuZChKU09OLnN0cmluZ2lmeSh7CiAgICAgICAga2luZDogInN0YWNrVHJhY2UiLAogICAgICAgIHN0YWNrVHJhY2U6IHN0YWNrCiAgICAgIH0pKTsKICAgIH0KICB9Cn0KYXN5bmMgZnVuY3Rpb24gbWFpbigpIHsKICB0cnkgewogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgKGV2ZW50KSA9PiB7CiAgICAgIGhhbmRsZUVycm9yKGV2ZW50LmVycm9yKTsKICAgIH0pOwogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoInVuaGFuZGxlZHJlamVjdGlvbiIsIChldmVudCkgPT4gewogICAgICBoYW5kbGVFcnJvcihldmVudC5yZWFzb24pOwogICAgfSk7CiAgICBhd2FpdCBzdGFydFdhc2lUYXNrKCk7CiAgfSBjYXRjaCAoZSkgewogICAgaGFuZGxlRXJyb3IoZSk7CiAgICB0aHJvdyBlOwogIH0KfQptYWluKCk7Ci8qIQogKiBSZWNvbm5lY3RpbmcgV2ViU29ja2V0CiAqIGJ5IFBlZHJvIExhZGFyaWEgPHBlZHJvLmxhZGFyaWFAZ21haWwuY29tPgogKiBodHRwczovL2dpdGh1Yi5jb20vcGxhZGFyaWEvcmVjb25uZWN0aW5nLXdlYnNvY2tldAogKiBMaWNlbnNlIE1JVAogKi8KLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgpMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlCnRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlCkxpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCgpUSElTIENPREUgSVMgUFJPVklERUQgT04gQU4gKkFTIElTKiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCktJTkQsIEVJVEhFUiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04gQU5ZIElNUExJRUQKV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIFRJVExFLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwKTUVSQ0hBTlRBQkxJVFkgT1IgTk9OLUlORlJJTkdFTUVOVC4KClNlZSB0aGUgQXBhY2hlIFZlcnNpb24gMi4wIExpY2Vuc2UgZm9yIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucwphbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCg==")! public static let bundle: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpX2RlZnMuanMKdmFyIENMT0NLSURfUkVBTFRJTUUgPSAwOwp2YXIgQ0xPQ0tJRF9NT05PVE9OSUMgPSAxOwp2YXIgRVJSTk9fU1VDQ0VTUyA9IDA7CnZhciBFUlJOT19CQURGID0gODsKdmFyIEVSUk5PX0VYSVNUID0gMjA7CnZhciBFUlJOT19JTlZBTCA9IDI4Owp2YXIgRVJSTk9fSVNESVIgPSAzMTsKdmFyIEVSUk5PX05BTUVUT09MT05HID0gMzc7CnZhciBFUlJOT19OT0VOVCA9IDQ0Owp2YXIgRVJSTk9fTk9TWVMgPSA1MjsKdmFyIEVSUk5PX05PVERJUiA9IDU0Owp2YXIgRVJSTk9fTk9URU1QVFkgPSA1NTsKdmFyIEVSUk5PX05PVFNVUCA9IDU4Owp2YXIgRVJSTk9fUEVSTSA9IDYzOwp2YXIgRVJSTk9fTk9UQ0FQQUJMRSA9IDc2Owp2YXIgUklHSFRTX0ZEX0RBVEFTWU5DID0gMSA8PCAwOwp2YXIgUklHSFRTX0ZEX1JFQUQgPSAxIDw8IDE7CnZhciBSSUdIVFNfRkRfU0VFSyA9IDEgPDwgMjsKdmFyIFJJR0hUU19GRF9GRFNUQVRfU0VUX0ZMQUdTID0gMSA8PCAzOwp2YXIgUklHSFRTX0ZEX1NZTkMgPSAxIDw8IDQ7CnZhciBSSUdIVFNfRkRfVEVMTCA9IDEgPDwgNTsKdmFyIFJJR0hUU19GRF9XUklURSA9IDEgPDwgNjsKdmFyIFJJR0hUU19GRF9BRFZJU0UgPSAxIDw8IDc7CnZhciBSSUdIVFNfRkRfQUxMT0NBVEUgPSAxIDw8IDg7CnZhciBSSUdIVFNfUEFUSF9DUkVBVEVfRElSRUNUT1JZID0gMSA8PCA5Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0ZJTEUgPSAxIDw8IDEwOwp2YXIgUklHSFRTX1BBVEhfTElOS19TT1VSQ0UgPSAxIDw8IDExOwp2YXIgUklHSFRTX1BBVEhfTElOS19UQVJHRVQgPSAxIDw8IDEyOwp2YXIgUklHSFRTX1BBVEhfT1BFTiA9IDEgPDwgMTM7CnZhciBSSUdIVFNfRkRfUkVBRERJUiA9IDEgPDwgMTQ7CnZhciBSSUdIVFNfUEFUSF9SRUFETElOSyA9IDEgPDwgMTU7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfU09VUkNFID0gMSA8PCAxNjsKdmFyIFJJR0hUU19QQVRIX1JFTkFNRV9UQVJHRVQgPSAxIDw8IDE3Owp2YXIgUklHSFRTX1BBVEhfRklMRVNUQVRfR0VUID0gMSA8PCAxODsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9TSVpFID0gMSA8PCAxOTsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjA7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfR0VUID0gMSA8PCAyMTsKdmFyIFJJR0hUU19GRF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMjI7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1RJTUVTID0gMSA8PCAyMzsKdmFyIFJJR0hUU19QQVRIX1NZTUxJTksgPSAxIDw8IDI0Owp2YXIgUklHSFRTX1BBVEhfUkVNT1ZFX0RJUkVDVE9SWSA9IDEgPDwgMjU7CnZhciBSSUdIVFNfUEFUSF9VTkxJTktfRklMRSA9IDEgPDwgMjY7CnZhciBSSUdIVFNfUE9MTF9GRF9SRUFEV1JJVEUgPSAxIDw8IDI3Owp2YXIgUklHSFRTX1NPQ0tfU0hVVERPV04gPSAxIDw8IDI4Owp2YXIgSW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBJb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChJb3ZlYy5yZWFkX2J5dGVzKHZpZXcsIHB0ciArIDggKiBpKSk7CiAgICB9CiAgICByZXR1cm4gaW92ZWNzOwogIH0KfTsKdmFyIENpb3ZlYyA9IGNsYXNzIHsKICBzdGF0aWMgcmVhZF9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIGNvbnN0IGlvdmVjID0gbmV3IENpb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChDaW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBXSEVOQ0VfU0VUID0gMDsKdmFyIFdIRU5DRV9DVVIgPSAxOwp2YXIgV0hFTkNFX0VORCA9IDI7CnZhciBGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFID0gMjsKdmFyIEZJTEVUWVBFX0RJUkVDVE9SWSA9IDM7CnZhciBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgPSA0Owp2YXIgRGlyZW50ID0gY2xhc3MgewogIGhlYWRfbGVuZ3RoKCkgewogICAgcmV0dXJuIDI0OwogIH0KICBuYW1lX2xlbmd0aCgpIHsKICAgIHJldHVybiB0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGg7CiAgfQogIHdyaXRlX2hlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIsIHRoaXMuZF9uZXh0LCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDgsIHRoaXMuZF9pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50MzIocHRyICsgMTYsIHRoaXMuZGlyX25hbWUubGVuZ3RoLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDgocHRyICsgMjAsIHRoaXMuZF90eXBlKTsKICB9CiAgd3JpdGVfbmFtZV9ieXRlcyh2aWV3OCwgcHRyLCBidWZfbGVuKSB7CiAgICB2aWV3OC5zZXQodGhpcy5kaXJfbmFtZS5zbGljZSgwLCBNYXRoLm1pbih0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGgsIGJ1Zl9sZW4pKSwgcHRyKTsKICB9CiAgY29uc3RydWN0b3IobmV4dF9jb29raWUsIG5hbWUsIHR5cGUpIHsKICAgIHRoaXMuZF9pbm8gPSAwbjsKICAgIGNvbnN0IGVuY29kZWRfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICAgIHRoaXMuZF9uZXh0ID0gbmV4dF9jb29raWU7CiAgICB0aGlzLmRfbmFtbGVuID0gZW5jb2RlZF9uYW1lLmJ5dGVMZW5ndGg7CiAgICB0aGlzLmRfdHlwZSA9IHR5cGU7CiAgICB0aGlzLmRpcl9uYW1lID0gZW5jb2RlZF9uYW1lOwogIH0KfTsKdmFyIEZERkxBR1NfQVBQRU5EID0gMSA8PCAwOwp2YXIgRkRGTEFHU19EU1lOQyA9IDEgPDwgMTsKdmFyIEZERkxBR1NfTk9OQkxPQ0sgPSAxIDw8IDI7CnZhciBGREZMQUdTX1JTWU5DID0gMSA8PCAzOwp2YXIgRkRGTEFHU19TWU5DID0gMSA8PCA0Owp2YXIgRmRzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50OChwdHIsIHRoaXMuZnNfZmlsZXR5cGUpOwogICAgdmlldy5zZXRVaW50MTYocHRyICsgMiwgdGhpcy5mc19mbGFncywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmZzX3JpZ2h0c19iYXNlLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDE2LCB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgZmxhZ3MpIHsKICAgIHRoaXMuZnNfcmlnaHRzX2Jhc2UgPSAwbjsKICAgIHRoaXMuZnNfcmlnaHRzX2luaGVyaXRlZCA9IDBuOwogICAgdGhpcy5mc19maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5mc19mbGFncyA9IGZsYWdzOwogIH0KfTsKdmFyIEZTVEZMQUdTX0FUSU0gPSAxIDw8IDA7CnZhciBGU1RGTEFHU19BVElNX05PVyA9IDEgPDwgMTsKdmFyIEZTVEZMQUdTX01USU0gPSAxIDw8IDI7CnZhciBGU1RGTEFHU19NVElNX05PVyA9IDEgPDwgMzsKdmFyIE9GTEFHU19DUkVBVCA9IDEgPDwgMDsKdmFyIE9GTEFHU19ESVJFQ1RPUlkgPSAxIDw8IDE7CnZhciBPRkxBR1NfRVhDTCA9IDEgPDwgMjsKdmFyIE9GTEFHU19UUlVOQyA9IDEgPDwgMzsKdmFyIEZpbGVzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRldiwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmlubywgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDE2LCB0aGlzLmZpbGV0eXBlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDI0LCB0aGlzLm5saW5rLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDMyLCB0aGlzLnNpemUsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgMzgsIHRoaXMuYXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA0NiwgdGhpcy5tdGltLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDUyLCB0aGlzLmN0aW0sIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgc2l6ZSkgewogICAgdGhpcy5kZXYgPSAwbjsKICAgIHRoaXMuaW5vID0gMG47CiAgICB0aGlzLm5saW5rID0gMG47CiAgICB0aGlzLmF0aW0gPSAwbjsKICAgIHRoaXMubXRpbSA9IDBuOwogICAgdGhpcy5jdGltID0gMG47CiAgICB0aGlzLmZpbGV0eXBlID0gZmlsZXR5cGU7CiAgICB0aGlzLnNpemUgPSBzaXplOwogIH0KfTsKdmFyIEVWRU5UUldGTEFHU19GRF9SRUFEV1JJVEVfSEFOR1VQID0gMSA8PCAwOwp2YXIgU1VCQ0xPQ0tGTEFHU19TVUJTQ1JJUFRJT05fQ0xPQ0tfQUJTVElNRSA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9QRUVLID0gMSA8PCAwOwp2YXIgUklGTEFHU19SRUNWX1dBSVRBTEwgPSAxIDw8IDE7CnZhciBST0ZMQUdTX1JFQ1ZfREFUQV9UUlVOQ0FURUQgPSAxIDw8IDA7CnZhciBTREZMQUdTX1JEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19XUiA9IDEgPDwgMTsKdmFyIFBSRU9QRU5UWVBFX0RJUiA9IDA7CnZhciBQcmVzdGF0RGlyID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50MzIocHRyLCB0aGlzLnByX25hbWUuYnl0ZUxlbmd0aCwgdHJ1ZSk7CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUpIHsKICAgIHRoaXMucHJfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICB9Cn07CnZhciBQcmVzdGF0ID0gY2xhc3MgewogIHN0YXRpYyBkaXIobmFtZSkgewogICAgY29uc3QgcHJlc3RhdCA9IG5ldyBQcmVzdGF0KCk7CiAgICBwcmVzdGF0LnRhZyA9IFBSRU9QRU5UWVBFX0RJUjsKICAgIHByZXN0YXQuaW5uZXIgPSBuZXcgUHJlc3RhdERpcihuYW1lKTsKICAgIHJldHVybiBwcmVzdGF0OwogIH0KICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy50YWcsIHRydWUpOwogICAgdGhpcy5pbm5lci53cml0ZV9ieXRlcyh2aWV3LCBwdHIgKyA0KTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2RlYnVnLmpzCnZhciBEZWJ1ZyA9IGNsYXNzIERlYnVnMiB7CiAgZW5hYmxlKGVuYWJsZWQpIHsKICAgIHRoaXMubG9nID0gY3JlYXRlTG9nZ2VyKGVuYWJsZWQgPT09IHZvaWQgMCA/IHRydWUgOiBlbmFibGVkLCB0aGlzLnByZWZpeCk7CiAgfQogIGdldCBlbmFibGVkKCkgewogICAgcmV0dXJuIHRoaXMuaXNFbmFibGVkOwogIH0KICBjb25zdHJ1Y3Rvcihpc0VuYWJsZWQpIHsKICAgIHRoaXMuaXNFbmFibGVkID0gaXNFbmFibGVkOwogICAgdGhpcy5wcmVmaXggPSAid2FzaToiOwogICAgdGhpcy5lbmFibGUoaXNFbmFibGVkKTsKICB9Cn07CmZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihlbmFibGVkLCBwcmVmaXgpIHsKICBpZiAoZW5hYmxlZCkgewogICAgY29uc3QgYSA9IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSwgIiVjJXMiLCAiY29sb3I6ICMyNjVCQTAiLCBwcmVmaXgpOwogICAgcmV0dXJuIGE7CiAgfSBlbHNlIHsKICAgIHJldHVybiAoKSA9PiB7CiAgICB9OwogIH0KfQp2YXIgZGVidWcgPSBuZXcgRGVidWcoZmFsc2UpOwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpLmpzCnZhciBXQVNJUHJvY0V4aXQgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKICBjb25zdHJ1Y3Rvcihjb2RlKSB7CiAgICBzdXBlcigiZXhpdCB3aXRoIGV4aXQgY29kZSAiICsgY29kZSk7CiAgICB0aGlzLmNvZGUgPSBjb2RlOwogIH0KfTsKdmFyIFdBU0kgPSBjbGFzcyBXQVNJMiB7CiAgc3RhcnQoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgdHJ5IHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQoKTsKICAgICAgcmV0dXJuIDA7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIGlmIChlIGluc3RhbmNlb2YgV0FTSVByb2NFeGl0KSB7CiAgICAgICAgcmV0dXJuIGUuY29kZTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aHJvdyBlOwogICAgICB9CiAgICB9CiAgfQogIGluaXRpYWxpemUoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgaWYgKGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUpIHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSgpOwogICAgfQogIH0KICBjb25zdHJ1Y3RvcihhcmdzLCBlbnYsIGZkcywgb3B0aW9ucyA9IHt9KSB7CiAgICB0aGlzLmFyZ3MgPSBbXTsKICAgIHRoaXMuZW52ID0gW107CiAgICB0aGlzLmZkcyA9IFtdOwogICAgZGVidWcuZW5hYmxlKG9wdGlvbnMuZGVidWcpOwogICAgdGhpcy5hcmdzID0gYXJnczsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2ZpbGVzdGF0X2dldChmZCwgZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGZkX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIGRlYnVnLmxvZyhwYXRoKTsKICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfcmVhZGxpbmsocGF0aCk7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVuYW1lKGZkLCBvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgbmV3X2ZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGxldCB7IHJldCwgaW5vZGVfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmsob2xkX3BhdGgpOwogICAgICAgIGlmIChpbm9kZV9vYmogPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgdHJ1ZSk7CiAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICBpZiAoc2VsZi5mZHNbZmRdLnBhdGhfbGluayhvbGRfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKSAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIHRocm93ICJwYXRoX2xpbmsgc2hvdWxkIGFsd2F5cyByZXR1cm4gc3VjY2VzcyB3aGVuIHJlbGlua2luZyBhbiBpbm9kZSBiYWNrIHRvIHRoZSBvcmlnaW5hbCBwbGFjZSI7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfc3ltbGluayhvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF91bmxpbmtfZmlsZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwb2xsX29uZW9mZihpbl8sIG91dCwgbnN1YnNjcmlwdGlvbnMpIHsKICAgICAgdGhyb3cgImFzeW5jIGlvIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgcHJvY19leGl0KGV4aXRfY29kZSkgewogICAgICB0aHJvdyBuZXcgV0FTSVByb2NFeGl0KGV4aXRfY29kZSk7CiAgICB9LCBwcm9jX3JhaXNlKHNpZykgewogICAgICB0aHJvdyAicmFpc2VkIHNpZ25hbCAiICsgc2lnOwogICAgfSwgc2NoZWRfeWllbGQoKSB7CiAgICB9LCByYW5kb21fZ2V0KGJ1ZiwgYnVmX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmX2xlbjsgaSsrKSB7CiAgICAgICAgYnVmZmVyOFtidWYgKyBpXSA9IE1hdGgucmFuZG9tKCkgKiAyNTYgfCAwOwogICAgICB9CiAgICB9LCBzb2NrX3JlY3YoZmQsIHJpX2RhdGEsIHJpX2ZsYWdzKSB7CiAgICAgIHRocm93ICJzb2NrZXRzIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgc29ja19zZW5kKGZkLCBzaV9kYXRhLCBzaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2h1dGRvd24oZmQsIGhvdykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfYWNjZXB0KGZkLCBmbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0gfTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZkLmpzCnZhciBGZCA9IGNsYXNzIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfY2xvc2UoKSB7CiAgICByZXR1cm4gMDsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBmZHN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBwcmVzdGF0OiBudWxsIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRpcmVudDogbnVsbCB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9zeW5jKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9saW5rKHBhdGgsIGlub2RlLCBhbGxvd19kaXIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rKHBhdGgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aCwgZGlyZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9yZWFkbGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9yZW5hbWUob2xkX3BhdGgsIG5ld19mZCwgbmV3X3BhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9Cn07CnZhciBJbm9kZSA9IGNsYXNzIHsKfTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3QvZnNfbWVtLmpzCnZhciBPcGVuRmlsZSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBvZmZzZXQgKyBsZW4pIHsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIGxlbikpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIDApIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IHNpemUpIHsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheSh0aGlzLmZpbGUuZGF0YS5idWZmZXIuc2xpY2UoMCwgTnVtYmVyKHNpemUpKSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihzaXplKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcih0aGlzLmZpbGVfcG9zKSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KHNsaWNlLmxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIob2Zmc2V0KSwgTnVtYmVyKG9mZnNldCArIEJpZ0ludChzaXplKSkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICBsZXQgY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICBzd2l0Y2ggKHdoZW5jZSkgewogICAgICBjYXNlIFdIRU5DRV9TRVQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0NVUjoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IHRoaXMuZmlsZV9wb3MgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0VORDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IEJpZ0ludCh0aGlzLmZpbGUuZGF0YS5ieXRlTGVuZ3RoKSArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICBpZiAoY2FsY3VsYXRlZF9vZmZzZXQgPCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIHRoaXMuZmlsZV9wb3MgPSBjYWxjdWxhdGVkX29mZnNldDsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIodGhpcy5maWxlX3BvcykpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKG9mZnNldCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZmlsZS5zdGF0KCkgfTsKICB9CiAgY29uc3RydWN0b3IoZmlsZSkgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZmlsZV9wb3MgPSAwbjsKICAgIHRoaXMuZmlsZSA9IGZpbGU7CiAgfQp9Owp2YXIgT3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMCkgfTsKICB9CiAgZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKSB7CiAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICBkZWJ1Zy5sb2coInJlYWRkaXJfc2luZ2xlIiwgY29va2llKTsKICAgICAgZGVidWcubG9nKGNvb2tpZSwgdGhpcy5kaXIuY29udGVudHMua2V5cygpKTsKICAgIH0KICAgIGlmIChjb29raWUgPT0gMG4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMW4sICIuIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfSBlbHNlIGlmIChjb29raWUgPT0gMW4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMm4sICIuLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0KICAgIGlmIChjb29raWUgPj0gQmlnSW50KHRoaXMuZGlyLmNvbnRlbnRzLnNpemUpICsgMm4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IFtuYW1lLCBlbnRyeV0gPSBBcnJheS5mcm9tKHRoaXMuZGlyLmNvbnRlbnRzLmVudHJpZXMoKSlbTnVtYmVyKGNvb2tpZSAtIDJuKV07CiAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbmV3IERpcmVudChjb29raWUgKyAxbiwgbmFtZSwgZW50cnkuc3RhdCgpLmZpbGV0eXBlKSB9OwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX2VyciwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX2VyciwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBmaWxlc3RhdDogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogZW50cnkuc3RhdCgpIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGhfc3RyLCBkaXJmbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGhfc3RyLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBsZXQgeyByZXQsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfZW50cnlfZm9yX3BhdGgocGF0aCk7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICBpZiAocmV0ICE9IEVSUk5PX05PRU5UKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0LCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19DUkVBVCkgPT0gT0ZMQUdTX0NSRUFUKSB7CiAgICAgICAgY29uc3QgeyByZXQ6IHJldDIsIGVudHJ5OiBuZXdfZW50cnkgfSA9IHRoaXMuZGlyLmNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkpOwogICAgICAgIGlmIChuZXdfZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiByZXQyLCBmZF9vYmo6IG51bGwgfTsKICAgICAgICB9CiAgICAgICAgZW50cnkgPSBuZXdfZW50cnk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoKG9mbGFncyAmIE9GTEFHU19FWENMKSA9PSBPRkxBR1NfRVhDTCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4gZW50cnkucGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoLCBPRkxBR1NfQ1JFQVQgfCBPRkxBR1NfRElSRUNUT1JZLCAwbiwgMG4sIDApLnJldDsKICB9CiAgcGF0aF9saW5rKHBhdGhfc3RyLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgY29uc3Qgc291cmNlX2lzX2RpciA9IGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGNvbnN0IHRhcmdldF9pc19kaXIgPSBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBpZiAoc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgaWYgKGFsbG93X2RpciAmJiBlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgewogICAgICAgICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgPT0gMCkgewogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYgKHNvdXJjZV9pc19kaXIgJiYgIXRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgICB9IGVsc2UgaWYgKCFzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICAgIH0gZWxzZSBpZiAoaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFKSB7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICB9CiAgICB9CiAgICBpZiAoIWFsbG93X2RpciAmJiBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19QRVJNOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLnNldChmaWxlbmFtZSwgaW5vZGUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfdW5saW5rKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlID09PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgfHwgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgIH0KICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplICE9PSAwKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgIH0KICAgIGlmICghcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZGlyLnN0YXQoKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGNvbnN0cnVjdG9yKGRpcikgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGlyID0gZGlyOwogIH0KfTsKdmFyIFByZW9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIE9wZW5EaXJlY3RvcnkgewogIGZkX3ByZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBwcmVzdGF0OiBQcmVzdGF0LmRpcih0aGlzLnByZXN0YXRfbmFtZSkgfTsKICB9CiAgY29uc3RydWN0b3IobmFtZSwgY29udGVudHMpIHsKICAgIHN1cGVyKG5ldyBEaXJlY3RvcnkoY29udGVudHMpKTsKICAgIHRoaXMucHJlc3RhdF9uYW1lID0gbmFtZTsKICB9Cn07CnZhciBGaWxlID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICBpZiAodGhpcy5yZWFkb25seSAmJiAoZnNfcmlnaHRzX2Jhc2UgJiBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgPT0gQmlnSW50KFJJR0hUU19GRF9XUklURSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX1RSVU5DKSA9PSBPRkxBR1NfVFJVTkMpIHsKICAgICAgaWYgKHRoaXMucmVhZG9ubHkpCiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoW10pOwogICAgfQogICAgY29uc3QgZmlsZSA9IG5ldyBPcGVuRmlsZSh0aGlzKTsKICAgIGlmIChmZF9mbGFncyAmIEZERkxBR1NfQVBQRU5EKQogICAgICBmaWxlLmZkX3NlZWsoMG4sIFdIRU5DRV9FTkQpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IGZpbGUgfTsKICB9CiAgZ2V0IHNpemUoKSB7CiAgICByZXR1cm4gQmlnSW50KHRoaXMuZGF0YS5ieXRlTGVuZ3RoKTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCB0aGlzLnNpemUpOwogIH0KICBjb25zdHJ1Y3RvcihkYXRhLCBvcHRpb25zKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7CiAgICB0aGlzLnJlYWRvbmx5ID0gISFvcHRpb25zPy5yZWFkb25seTsKICB9Cn07CnZhciBQYXRoID0gY2xhc3MgUGF0aDIgewogIHN0YXRpYyBmcm9tKHBhdGgpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aC5lbmRzV2l0aCgiLyIpOwogICAgaWYgKHBhdGguc3RhcnRzV2l0aCgiLyIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgfQogICAgaWYgKHBhdGguaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5zcGxpdCgiLyIpKSB7CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIiIHx8IGNvbXBvbmVudCA9PT0gIi4iKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKGNvbXBvbmVudCA9PT0gIi4uIikgewogICAgICAgIGlmIChzZWxmLnBhcnRzLnBvcCgpID09IHZvaWQgMCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIHNlbGYucGFydHMucHVzaChjb21wb25lbnQpOwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXRoOiBzZWxmIH07CiAgfQogIHRvX3BhdGhfc3RyaW5nKCkgewogICAgbGV0IHMgPSB0aGlzLnBhcnRzLmpvaW4oIi8iKTsKICAgIGlmICh0aGlzLmlzX2RpcikgewogICAgICBzICs9ICIvIjsKICAgIH0KICAgIHJldHVybiBzOwogIH0KICBjb25zdHJ1Y3RvcigpIHsKICAgIHRoaXMucGFydHMgPSBbXTsKICAgIHRoaXMuaXNfZGlyID0gZmFsc2U7CiAgfQp9Owp2YXIgRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogbmV3IE9wZW5EaXJlY3RvcnkodGhpcykgfTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwbik7CiAgfQogIGdldF9lbnRyeV9mb3JfcGF0aChwYXRoKSB7CiAgICBsZXQgZW50cnkgPSB0aGlzOwogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGFsbG93X3VuZGVmaW5lZCkgewogICAgY29uc3QgZmlsZW5hbWUgPSBwYXRoLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogZW50cnlfcmV0LCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKCEocGFyZW50X2VudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IGVudHJ5ID0gcGFyZW50X2VudHJ5LmNvbnRlbnRzLmdldChmaWxlbmFtZSk7CiAgICBpZiAoZW50cnkgPT09IHZvaWQgMCkgewogICAgICBpZiAoIWFsbG93X3VuZGVmaW5lZCkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9OwogIH0KICBjcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIGlzX2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgZGVidWcubG9nKCJjcmVhdGUiLCBwYXRoKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gZW50cnlwb2ludC9jb21tb24udHMKdmFyIExpbmVEZWNvZGVyID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG9uTGluZSkgewogICAgdGhpcy5kZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIsIHsgZmF0YWw6IGZhbHNlIH0pOwogICAgdGhpcy5idWZmZXIgPSAiIjsKICAgIHRoaXMub25MaW5lID0gb25MaW5lOwogIH0KICBkZWNvZGVyOwogIGJ1ZmZlcjsKICBvbkxpbmU7CiAgc2VuZChjaHVuaykgewogICAgdGhpcy5idWZmZXIgKz0gdGhpcy5kZWNvZGVyLmRlY29kZShjaHVuaywgeyBzdHJlYW06IHRydWUgfSk7CiAgICBjb25zdCBsaW5lcyA9IHRoaXMuYnVmZmVyLnNwbGl0KCJcbiIpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGggLSAxOyBpKyspIHsKICAgICAgdGhpcy5vbkxpbmUobGluZXNbaV0pOwogICAgfQogICAgdGhpcy5idWZmZXIgPSBsaW5lc1tsaW5lcy5sZW5ndGggLSAxXTsKICB9Cn07CnZhciBXYXNtUnVubmVyID0gKHJhd09wdGlvbnMsIFN3aWZ0UnVudGltZSkgPT4gewogIGNvbnN0IG9wdGlvbnMgPSBkZWZhdWx0UnVubmVyT3B0aW9ucyhyYXdPcHRpb25zKTsKICBsZXQgc3dpZnQ7CiAgaWYgKFN3aWZ0UnVudGltZSkgewogICAgc3dpZnQgPSBuZXcgU3dpZnRSdW50aW1lKCk7CiAgfQogIGxldCBzdGRvdXRMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3Rkb3V0TGluZSAhPSBudWxsKSB7CiAgICBzdGRvdXRMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRvdXRMaW5lKTsKICB9CiAgY29uc3Qgc3Rkb3V0ID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3Rkb3V0Py5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3Rkb3V0TGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgbGV0IHN0ZGVyckxpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRlcnJMaW5lICE9IG51bGwpIHsKICAgIHN0ZGVyckxpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZGVyckxpbmUpOwogIH0KICBjb25zdCBzdGRlcnIgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRlcnI/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRlcnJMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBjb25zdCBhcmdzID0gb3B0aW9ucy5hcmdzIHx8IFtdOwogIGNvbnN0IGZkcyA9IFsKICAgIG5ldyBPcGVuRmlsZShuZXcgRmlsZShbXSkpLAogICAgc3Rkb3V0LAogICAgc3RkZXJyLAogICAgbmV3IFByZW9wZW5EaXJlY3RvcnkoIi8iLCAvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKQogIF07CiAgY29uc3Qgd2FzaSA9IG5ldyBXQVNJKGFyZ3MsIFtdLCBmZHMsIHsKICAgIGRlYnVnOiBmYWxzZQogIH0pOwogIGNvbnN0IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QgPSAoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QgPSB7CiAgICAgIHdhc2lfc25hcHNob3RfcHJldmlldzE6IHdhc2kud2FzaUltcG9ydAogICAgfTsKICAgIGlmIChzd2lmdCkgewogICAgICBpbXBvcnRPYmplY3QuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgaWYgKCFpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgaW1wb3J0RW50cnkgb2YgV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMobW9kdWxlKSkgewogICAgICBpZiAoIWltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0gPSB7fTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAiZnVuY3Rpb24iICYmICFpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSkgewogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbXBvcnRlZCBmdW5jdGlvbiAke2ltcG9ydEVudHJ5Lm1vZHVsZX0uJHtpbXBvcnRFbnRyeS5uYW1lfSBub3QgaW1wbGVtZW50ZWRgKTsKICAgICAgICB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0OwogIH07CiAgcmV0dXJuIHsKICAgIGFzeW5jIHJ1bih3YXNtQnl0ZXMsIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgaWYgKCFleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgZXh0cmFXYXNtSW1wb3J0cyA9IHt9OwogICAgICB9CiAgICAgIGV4dHJhV2FzbUltcG9ydHMuX19zdGFja19zYW5pdGl6ZXIgPSB7CiAgICAgICAgcmVwb3J0X3N0YWNrX292ZXJmbG93OiAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkRldGVjdGVkIHN0YWNrIGJ1ZmZlciBvdmVyZmxvdy4iKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIGNvbnN0IG1vZHVsZSA9IGF3YWl0IFdlYkFzc2VtYmx5LmNvbXBpbGUod2FzbUJ5dGVzKTsKICAgICAgY29uc3QgaW1wb3J0T2JqZWN0ID0gY3JlYXRlV2FzbUltcG9ydE9iamVjdChleHRyYVdhc21JbXBvcnRzLCBtb2R1bGUpOwogICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKG1vZHVsZSwgaW1wb3J0T2JqZWN0KTsKICAgICAgaWYgKHN3aWZ0ICYmIGluc3RhbmNlLmV4cG9ydHMuc3dqc19saWJyYXJ5X3ZlcnNpb24pIHsKICAgICAgICBzd2lmdC5zZXRJbnN0YW5jZShpbnN0YW5jZSk7CiAgICAgIH0KICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9zdGFydCA9PT0gImZ1bmN0aW9uIikgewogICAgICAgIHdhc2kuc3RhcnQoaW5zdGFuY2UpOwogICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplID09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLmluaXRpYWxpemUoaW5zdGFuY2UpOwogICAgICAgIGlmIChzd2lmdCAmJiBzd2lmdC5tYWluKSB7CiAgICAgICAgICBzd2lmdC5tYWluKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5tYWluID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICAgIGluc3RhbmNlLmV4cG9ydHMubWFpbigpOwogICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICAgIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndigwLCAwKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Owp9Owp2YXIgZGVmYXVsdFJ1bm5lck9wdGlvbnMgPSAob3B0aW9ucykgPT4gewogIGlmIChvcHRpb25zLmFyZ3MgPT0gbnVsbCkgewogICAgb3B0aW9ucy5hcmdzID0gWyJtYWluLndhc20iXTsKICB9CiAgcmV0dXJuIG9wdGlvbnM7Cn07CgovLyBlbnRyeXBvaW50L2J1bmRsZS50cwp2YXIgc3RhcnRXYXNpVGFzayA9IGFzeW5jICgpID0+IHsKICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCJSRVBMQUNFX1RISVNfV0lUSF9USEVfTUFJTl9XRUJBU1NFTUJMWV9NT0RVTEUiKTsKICBjb25zdCByZXNwb25zZUFycmF5QnVmZmVyID0gYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTsKICBsZXQgcnVudGltZUNvbnN0cnVjdG9yID0gdm9pZCAwOwogIHRyeSB7CiAgICBjb25zdCB7IFN3aWZ0UnVudGltZSB9ID0gYXdhaXQgaW1wb3J0KAogICAgICAvLyBAdHMtaWdub3JlCiAgICAgICIuL0phdmFTY3JpcHRLaXRfSmF2YVNjcmlwdEtpdC5yZXNvdXJjZXMvUnVudGltZS9pbmRleC5tanMiCiAgICApOwogICAgcnVudGltZUNvbnN0cnVjdG9yID0gU3dpZnRSdW50aW1lOwogIH0gY2F0Y2ggewogIH0KICBjb25zdCB3YXNtUnVubmVyID0gV2FzbVJ1bm5lcih7CiAgICBvblN0ZG91dExpbmUobGluZSkgewogICAgICBjb25zb2xlLmxvZyhsaW5lKTsKICAgIH0sCiAgICBvblN0ZGVyckxpbmUobGluZSkgewogICAgICBjb25zb2xlLmVycm9yKGxpbmUpOwogICAgfQogIH0sIHJ1bnRpbWVDb25zdHJ1Y3Rvcik7CiAgY29uc3Qgd2FzbUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkocmVzcG9uc2VBcnJheUJ1ZmZlcikuYnVmZmVyOwogIGF3YWl0IHdhc21SdW5uZXIucnVuKHdhc21CeXRlcyk7Cn07CmFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7CiAgYXdhaXQgc3RhcnRXYXNpVGFzaygpOwp9Cm1haW4oKTsK")! public static let test: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL3JlY29ubmVjdGluZy13ZWJzb2NrZXQvZGlzdC9yZWNvbm5lY3Rpbmctd2Vic29ja2V0LW1qcy5qcwp2YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24oZDIsIGIyKSB7CiAgICBkMi5fX3Byb3RvX18gPSBiMjsKICB9IHx8IGZ1bmN0aW9uKGQyLCBiMikgewogICAgZm9yICh2YXIgcCBpbiBiMikKICAgICAgaWYgKGIyLmhhc093blByb3BlcnR5KHApKQogICAgICAgIGQyW3BdID0gYjJbcF07CiAgfTsKICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKfTsKZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzKGQsIGIpOwogIGZ1bmN0aW9uIF9fKCkgewogICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7CiAgfQogIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKfQpmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7CiAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSAiZnVuY3Rpb24iICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7CiAgaWYgKG0pCiAgICByZXR1cm4gbS5jYWxsKG8pOwogIHJldHVybiB7CiAgICBuZXh0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkKICAgICAgICBvID0gdm9pZCAwOwogICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07CiAgICB9CiAgfTsKfQpmdW5jdGlvbiBfX3JlYWQobywgbikgewogIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07CiAgaWYgKCFtKQogICAgcmV0dXJuIG87CiAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7CiAgdHJ5IHsKICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKQogICAgICBhci5wdXNoKHIudmFsdWUpOwogIH0gY2F0Y2ggKGVycm9yKSB7CiAgICBlID0geyBlcnJvciB9OwogIH0gZmluYWxseSB7CiAgICB0cnkgewogICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVsicmV0dXJuIl0pKQogICAgICAgIG0uY2FsbChpKTsKICAgIH0gZmluYWxseSB7CiAgICAgIGlmIChlKQogICAgICAgIHRocm93IGUuZXJyb3I7CiAgICB9CiAgfQogIHJldHVybiBhcjsKfQpmdW5jdGlvbiBfX3NwcmVhZCgpIHsKICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykKICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTsKICByZXR1cm4gYXI7Cn0KdmFyIEV2ZW50ID0gZnVuY3Rpb24oKSB7CiAgZnVuY3Rpb24gRXZlbnQyKHR5cGUsIHRhcmdldCkgewogICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CiAgICB0aGlzLnR5cGUgPSB0eXBlOwogIH0KICByZXR1cm4gRXZlbnQyOwp9KCk7CnZhciBFcnJvckV2ZW50ID0gZnVuY3Rpb24oX3N1cGVyKSB7CiAgX19leHRlbmRzKEVycm9yRXZlbnQyLCBfc3VwZXIpOwogIGZ1bmN0aW9uIEVycm9yRXZlbnQyKGVycm9yLCB0YXJnZXQpIHsKICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJlcnJvciIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLm1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlOwogICAgX3RoaXMuZXJyb3IgPSBlcnJvcjsKICAgIHJldHVybiBfdGhpczsKICB9CiAgcmV0dXJuIEVycm9yRXZlbnQyOwp9KEV2ZW50KTsKdmFyIENsb3NlRXZlbnQgPSBmdW5jdGlvbihfc3VwZXIpIHsKICBfX2V4dGVuZHMoQ2xvc2VFdmVudDIsIF9zdXBlcik7CiAgZnVuY3Rpb24gQ2xvc2VFdmVudDIoY29kZSwgcmVhc29uLCB0YXJnZXQpIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIGlmIChyZWFzb24gPT09IHZvaWQgMCkgewogICAgICByZWFzb24gPSAiIjsKICAgIH0KICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJjbG9zZSIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLndhc0NsZWFuID0gdHJ1ZTsKICAgIF90aGlzLmNvZGUgPSBjb2RlOwogICAgX3RoaXMucmVhc29uID0gcmVhc29uOwogICAgcmV0dXJuIF90aGlzOwogIH0KICByZXR1cm4gQ2xvc2VFdmVudDI7Cn0oRXZlbnQpOwp2YXIgZ2V0R2xvYmFsV2ViU29ja2V0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKHR5cGVvZiBXZWJTb2NrZXQgIT09ICJ1bmRlZmluZWQiKSB7CiAgICByZXR1cm4gV2ViU29ja2V0OwogIH0KfTsKdmFyIGlzV2ViU29ja2V0ID0gZnVuY3Rpb24odykgewogIHJldHVybiB0eXBlb2YgdyAhPT0gInVuZGVmaW5lZCIgJiYgISF3ICYmIHcuQ0xPU0lORyA9PT0gMjsKfTsKdmFyIERFRkFVTFQgPSB7CiAgbWF4UmVjb25uZWN0aW9uRGVsYXk6IDFlNCwKICBtaW5SZWNvbm5lY3Rpb25EZWxheTogMWUzICsgTWF0aC5yYW5kb20oKSAqIDRlMywKICBtaW5VcHRpbWU6IDVlMywKICByZWNvbm5lY3Rpb25EZWxheUdyb3dGYWN0b3I6IDEuMywKICBjb25uZWN0aW9uVGltZW91dDogNGUzLAogIG1heFJldHJpZXM6IEluZmluaXR5LAogIG1heEVucXVldWVkTWVzc2FnZXM6IEluZmluaXR5LAogIHN0YXJ0Q2xvc2VkOiBmYWxzZSwKICBkZWJ1ZzogZmFsc2UKfTsKdmFyIFJlY29ubmVjdGluZ1dlYlNvY2tldCA9IGZ1bmN0aW9uKCkgewogIGZ1bmN0aW9uIFJlY29ubmVjdGluZ1dlYlNvY2tldDIodXJsLCBwcm90b2NvbHMsIG9wdGlvbnMpIHsKICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7CiAgICAgIG9wdGlvbnMgPSB7fTsKICAgIH0KICAgIHRoaXMuX2xpc3RlbmVycyA9IHsKICAgICAgZXJyb3I6IFtdLAogICAgICBtZXNzYWdlOiBbXSwKICAgICAgb3BlbjogW10sCiAgICAgIGNsb3NlOiBbXQogICAgfTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIHRoaXMuX3Nob3VsZFJlY29ubmVjdCA9IHRydWU7CiAgICB0aGlzLl9jb25uZWN0TG9jayA9IGZhbHNlOwogICAgdGhpcy5fYmluYXJ5VHlwZSA9ICJibG9iIjsKICAgIHRoaXMuX2Nsb3NlQ2FsbGVkID0gZmFsc2U7CiAgICB0aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgIHRoaXMub25jbG9zZSA9IG51bGw7CiAgICB0aGlzLm9uZXJyb3IgPSBudWxsOwogICAgdGhpcy5vbm1lc3NhZ2UgPSBudWxsOwogICAgdGhpcy5vbm9wZW4gPSBudWxsOwogICAgdGhpcy5faGFuZGxlT3BlbiA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgIF90aGlzLl9kZWJ1Zygib3BlbiBldmVudCIpOwogICAgICB2YXIgX2EgPSBfdGhpcy5fb3B0aW9ucy5taW5VcHRpbWUsIG1pblVwdGltZSA9IF9hID09PSB2b2lkIDAgPyBERUZBVUxULm1pblVwdGltZSA6IF9hOwogICAgICBjbGVhclRpbWVvdXQoX3RoaXMuX2Nvbm5lY3RUaW1lb3V0KTsKICAgICAgX3RoaXMuX3VwdGltZVRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5fYWNjZXB0T3BlbigpOwogICAgICB9LCBtaW5VcHRpbWUpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fbWVzc2FnZVF1ZXVlLmZvckVhY2goZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHJldHVybiBfdGhpcy5fd3Muc2VuZChtZXNzYWdlKTsKICAgICAgfSk7CiAgICAgIF90aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgICAgaWYgKF90aGlzLm9ub3BlbikgewogICAgICAgIF90aGlzLm9ub3BlbihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5vcGVuLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZU1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkgewogICAgICBfdGhpcy5fZGVidWcoIm1lc3NhZ2UgZXZlbnQiKTsKICAgICAgaWYgKF90aGlzLm9ubWVzc2FnZSkgewogICAgICAgIF90aGlzLm9ubWVzc2FnZShldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5tZXNzYWdlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUVycm9yID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJlcnJvciBldmVudCIsIGV2ZW50Lm1lc3NhZ2UpOwogICAgICBfdGhpcy5fZGlzY29ubmVjdCh2b2lkIDAsIGV2ZW50Lm1lc3NhZ2UgPT09ICJUSU1FT1VUIiA/ICJ0aW1lb3V0IiA6IHZvaWQgMCk7CiAgICAgIGlmIChfdGhpcy5vbmVycm9yKSB7CiAgICAgICAgX3RoaXMub25lcnJvcihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJleGVjIGVycm9yIGxpc3RlbmVycyIpOwogICAgICBfdGhpcy5fbGlzdGVuZXJzLmVycm9yLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgICBfdGhpcy5fY29ubmVjdCgpOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUNsb3NlID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJjbG9zZSBldmVudCIpOwogICAgICBfdGhpcy5fY2xlYXJUaW1lb3V0cygpOwogICAgICBpZiAoX3RoaXMuX3Nob3VsZFJlY29ubmVjdCkgewogICAgICAgIF90aGlzLl9jb25uZWN0KCk7CiAgICAgIH0KICAgICAgaWYgKF90aGlzLm9uY2xvc2UpIHsKICAgICAgICBfdGhpcy5vbmNsb3NlKGV2ZW50KTsKICAgICAgfQogICAgICBfdGhpcy5fbGlzdGVuZXJzLmNsb3NlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX3VybCA9IHVybDsKICAgIHRoaXMuX3Byb3RvY29scyA9IHByb3RvY29sczsKICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zOwogICAgaWYgKHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQpIHsKICAgICAgdGhpcy5fc2hvdWxkUmVjb25uZWN0ID0gZmFsc2U7CiAgICB9CiAgICB0aGlzLl9jb25uZWN0KCk7CiAgfQogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ09OTkVDVElORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiAwOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0MiwgIk9QRU4iLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gMTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIsICJDTE9TSU5HIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ0xPU0VEIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDM7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNPTk5FQ1RJTkciLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5DT05ORUNUSU5HOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJPUEVOIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIFJlY29ubmVjdGluZ1dlYlNvY2tldDIuT1BFTjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiQ0xPU0lORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NJTkc7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNMT1NFRCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRDsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYmluYXJ5VHlwZSIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmJpbmFyeVR5cGUgOiB0aGlzLl9iaW5hcnlUeXBlOwogICAgfSwKICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgdGhpcy5fYmluYXJ5VHlwZSA9IHZhbHVlOwogICAgICBpZiAodGhpcy5fd3MpIHsKICAgICAgICB0aGlzLl93cy5iaW5hcnlUeXBlID0gdmFsdWU7CiAgICAgIH0KICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicmV0cnlDb3VudCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBNYXRoLm1heCh0aGlzLl9yZXRyeUNvdW50LCAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYnVmZmVyZWRBbW91bnQiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICB2YXIgYnl0ZXMgPSB0aGlzLl9tZXNzYWdlUXVldWUucmVkdWNlKGZ1bmN0aW9uKGFjYywgbWVzc2FnZSkgewogICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgIGFjYyArPSBtZXNzYWdlLmxlbmd0aDsKICAgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBCbG9iKSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5zaXplOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5ieXRlTGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYWNjOwogICAgICB9LCAwKTsKICAgICAgcmV0dXJuIGJ5dGVzICsgKHRoaXMuX3dzID8gdGhpcy5fd3MuYnVmZmVyZWRBbW91bnQgOiAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiZXh0ZW5zaW9ucyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmV4dGVuc2lvbnMgOiAiIjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicHJvdG9jb2wiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gdGhpcy5fd3MgPyB0aGlzLl93cy5wcm90b2NvbCA6ICIiOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJyZWFkeVN0YXRlIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKHRoaXMuX3dzKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX3dzLnJlYWR5U3RhdGU7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQgPyBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRCA6IFJlY29ubmVjdGluZ1dlYlNvY2tldDIuQ09OTkVDVElORzsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAidXJsIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIHRoaXMuX3dzID8gdGhpcy5fd3MudXJsIDogIiI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICBpZiAoY29kZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvZGUgPSAxZTM7CiAgICB9CiAgICB0aGlzLl9jbG9zZUNhbGxlZCA9IHRydWU7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSBmYWxzZTsKICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlIGVucXVldWVkOiBubyB3cyBpbnN0YW5jZSIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlOiBhbHJlYWR5IGNsb3NlZCIpOwogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSB0cnVlOwogICAgdGhpcy5fY2xvc2VDYWxsZWQgPSBmYWxzZTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIGlmICghdGhpcy5fd3MgfHwgdGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fY29ubmVjdCgpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5fZGlzY29ubmVjdChjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9jb25uZWN0KCk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSkgewogICAgaWYgKHRoaXMuX3dzICYmIHRoaXMuX3dzLnJlYWR5U3RhdGUgPT09IHRoaXMuT1BFTikgewogICAgICB0aGlzLl9kZWJ1Zygic2VuZCIsIGRhdGEpOwogICAgICB0aGlzLl93cy5zZW5kKGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucy5tYXhFbnF1ZXVlZE1lc3NhZ2VzLCBtYXhFbnF1ZXVlZE1lc3NhZ2VzID0gX2EgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4RW5xdWV1ZWRNZXNzYWdlcyA6IF9hOwogICAgICBpZiAodGhpcy5fbWVzc2FnZVF1ZXVlLmxlbmd0aCA8IG1heEVucXVldWVkTWVzc2FnZXMpIHsKICAgICAgICB0aGlzLl9kZWJ1ZygiZW5xdWV1ZSIsIGRhdGEpOwogICAgICAgIHRoaXMuX21lc3NhZ2VRdWV1ZS5wdXNoKGRhdGEpOwogICAgICB9CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdLnB1c2gobGlzdGVuZXIpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuZGlzcGF0Y2hFdmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICB2YXIgZV8xLCBfYTsKICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnNbZXZlbnQudHlwZV07CiAgICBpZiAobGlzdGVuZXJzKSB7CiAgICAgIHRyeSB7CiAgICAgICAgZm9yICh2YXIgbGlzdGVuZXJzXzEgPSBfX3ZhbHVlcyhsaXN0ZW5lcnMpLCBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpOyAhbGlzdGVuZXJzXzFfMS5kb25lOyBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpKSB7CiAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNfMV8xLnZhbHVlOwogICAgICAgICAgdGhpcy5fY2FsbEV2ZW50TGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyKTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2ggKGVfMV8xKSB7CiAgICAgICAgZV8xID0geyBlcnJvcjogZV8xXzEgfTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICB0cnkgewogICAgICAgICAgaWYgKGxpc3RlbmVyc18xXzEgJiYgIWxpc3RlbmVyc18xXzEuZG9uZSAmJiAoX2EgPSBsaXN0ZW5lcnNfMS5yZXR1cm4pKQogICAgICAgICAgICBfYS5jYWxsKGxpc3RlbmVyc18xKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgaWYgKGVfMSkKICAgICAgICAgICAgdGhyb3cgZV8xLmVycm9yOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdID0gdGhpcy5fbGlzdGVuZXJzW3R5cGVdLmZpbHRlcihmdW5jdGlvbihsKSB7CiAgICAgICAgcmV0dXJuIGwgIT09IGxpc3RlbmVyOwogICAgICB9KTsKICAgIH0KICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9kZWJ1ZyA9IGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3MgPSBbXTsKICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7CiAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTsKICAgIH0KICAgIGlmICh0aGlzLl9vcHRpb25zLmRlYnVnKSB7CiAgICAgIGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIF9fc3ByZWFkKFsiUldTPiJdLCBhcmdzKSk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fZ2V0TmV4dERlbGF5ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX2EgPSB0aGlzLl9vcHRpb25zLCBfYiA9IF9hLnJlY29ubmVjdGlvbkRlbGF5R3Jvd0ZhY3RvciwgcmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQucmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yIDogX2IsIF9jID0gX2EubWluUmVjb25uZWN0aW9uRGVsYXksIG1pblJlY29ubmVjdGlvbkRlbGF5ID0gX2MgPT09IHZvaWQgMCA/IERFRkFVTFQubWluUmVjb25uZWN0aW9uRGVsYXkgOiBfYywgX2QgPSBfYS5tYXhSZWNvbm5lY3Rpb25EZWxheSwgbWF4UmVjb25uZWN0aW9uRGVsYXkgPSBfZCA9PT0gdm9pZCAwID8gREVGQVVMVC5tYXhSZWNvbm5lY3Rpb25EZWxheSA6IF9kOwogICAgdmFyIGRlbGF5ID0gMDsKICAgIGlmICh0aGlzLl9yZXRyeUNvdW50ID4gMCkgewogICAgICBkZWxheSA9IG1pblJlY29ubmVjdGlvbkRlbGF5ICogTWF0aC5wb3cocmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yLCB0aGlzLl9yZXRyeUNvdW50IC0gMSk7CiAgICAgIGlmIChkZWxheSA+IG1heFJlY29ubmVjdGlvbkRlbGF5KSB7CiAgICAgICAgZGVsYXkgPSBtYXhSZWNvbm5lY3Rpb25EZWxheTsKICAgICAgfQogICAgfQogICAgdGhpcy5fZGVidWcoIm5leHQgZGVsYXkiLCBkZWxheSk7CiAgICByZXR1cm4gZGVsYXk7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fd2FpdCA9IGZ1bmN0aW9uKCkgewogICAgdmFyIF90aGlzID0gdGhpczsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7CiAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgX3RoaXMuX2dldE5leHREZWxheSgpKTsKICAgIH0pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2dldE5leHRVcmwgPSBmdW5jdGlvbih1cmxQcm92aWRlcikgewogICAgaWYgKHR5cGVvZiB1cmxQcm92aWRlciA9PT0gInN0cmluZyIpIHsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1cmxQcm92aWRlcik7CiAgICB9CiAgICBpZiAodHlwZW9mIHVybFByb3ZpZGVyID09PSAiZnVuY3Rpb24iKSB7CiAgICAgIHZhciB1cmwgPSB1cmxQcm92aWRlcigpOwogICAgICBpZiAodHlwZW9mIHVybCA9PT0gInN0cmluZyIpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVybCk7CiAgICAgIH0KICAgICAgaWYgKCEhdXJsLnRoZW4pIHsKICAgICAgICByZXR1cm4gdXJsOwogICAgICB9CiAgICB9CiAgICB0aHJvdyBFcnJvcigiSW52YWxpZCBVUkwiKTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jb25uZWN0ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX3RoaXMgPSB0aGlzOwogICAgaWYgKHRoaXMuX2Nvbm5lY3RMb2NrIHx8ICF0aGlzLl9zaG91bGRSZWNvbm5lY3QpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fY29ubmVjdExvY2sgPSB0cnVlOwogICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucywgX2IgPSBfYS5tYXhSZXRyaWVzLCBtYXhSZXRyaWVzID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4UmV0cmllcyA6IF9iLCBfYyA9IF9hLmNvbm5lY3Rpb25UaW1lb3V0LCBjb25uZWN0aW9uVGltZW91dCA9IF9jID09PSB2b2lkIDAgPyBERUZBVUxULmNvbm5lY3Rpb25UaW1lb3V0IDogX2MsIF9kID0gX2EuV2ViU29ja2V0LCBXZWJTb2NrZXQyID0gX2QgPT09IHZvaWQgMCA/IGdldEdsb2JhbFdlYlNvY2tldCgpIDogX2Q7CiAgICBpZiAodGhpcy5fcmV0cnlDb3VudCA+PSBtYXhSZXRyaWVzKSB7CiAgICAgIHRoaXMuX2RlYnVnKCJtYXggcmV0cmllcyByZWFjaGVkIiwgdGhpcy5fcmV0cnlDb3VudCwgIj49IiwgbWF4UmV0cmllcyk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIHRoaXMuX3JldHJ5Q291bnQrKzsKICAgIHRoaXMuX2RlYnVnKCJjb25uZWN0IiwgdGhpcy5fcmV0cnlDb3VudCk7CiAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lcnMoKTsKICAgIGlmICghaXNXZWJTb2NrZXQoV2ViU29ja2V0MikpIHsKICAgICAgdGhyb3cgRXJyb3IoIk5vIHZhbGlkIFdlYlNvY2tldCBjbGFzcyBwcm92aWRlZCIpOwogICAgfQogICAgdGhpcy5fd2FpdCgpLnRoZW4oZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBfdGhpcy5fZ2V0TmV4dFVybChfdGhpcy5fdXJsKTsKICAgIH0pLnRoZW4oZnVuY3Rpb24odXJsKSB7CiAgICAgIGlmIChfdGhpcy5fY2xvc2VDYWxsZWQpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJjb25uZWN0IiwgeyB1cmwsIHByb3RvY29sczogX3RoaXMuX3Byb3RvY29scyB9KTsKICAgICAgX3RoaXMuX3dzID0gX3RoaXMuX3Byb3RvY29scyA/IG5ldyBXZWJTb2NrZXQyKHVybCwgX3RoaXMuX3Byb3RvY29scykgOiBuZXcgV2ViU29ja2V0Mih1cmwpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fY29ubmVjdExvY2sgPSBmYWxzZTsKICAgICAgX3RoaXMuX2FkZExpc3RlbmVycygpOwogICAgICBfdGhpcy5fY29ubmVjdFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5faGFuZGxlVGltZW91dCgpOwogICAgICB9LCBjb25uZWN0aW9uVGltZW91dCk7CiAgICB9KTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9oYW5kbGVUaW1lb3V0ID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLl9kZWJ1ZygidGltZW91dCBldmVudCIpOwogICAgdGhpcy5faGFuZGxlRXJyb3IobmV3IEVycm9yRXZlbnQoRXJyb3IoIlRJTUVPVVQiKSwgdGhpcykpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2Rpc2Nvbm5lY3QgPSBmdW5jdGlvbihjb2RlLCByZWFzb24pIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJzKCk7CiAgICB0cnkgewogICAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9oYW5kbGVDbG9zZShuZXcgQ2xvc2VFdmVudChjb2RlLCByZWFzb24sIHRoaXMpKTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fYWNjZXB0T3BlbiA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5fZGVidWcoImFjY2VwdCBvcGVuIik7CiAgICB0aGlzLl9yZXRyeUNvdW50ID0gMDsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jYWxsRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBsaXN0ZW5lcikgewogICAgaWYgKCJoYW5kbGVFdmVudCIgaW4gbGlzdGVuZXIpIHsKICAgICAgbGlzdGVuZXIuaGFuZGxlRXZlbnQoZXZlbnQpOwogICAgfSBlbHNlIHsKICAgICAgbGlzdGVuZXIoZXZlbnQpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX3JlbW92ZUxpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygicmVtb3ZlTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2FkZExpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygiYWRkTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2NsZWFyVGltZW91dHMgPSBmdW5jdGlvbigpIHsKICAgIGNsZWFyVGltZW91dCh0aGlzLl9jb25uZWN0VGltZW91dCk7CiAgICBjbGVhclRpbWVvdXQodGhpcy5fdXB0aW1lVGltZW91dCk7CiAgfTsKICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0MjsKfSgpOwp2YXIgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdCA9IFJlY29ubmVjdGluZ1dlYlNvY2tldDsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJncywgZW52LCBmZHMsIG9wdGlvbnMgPSB7fSkgewogICAgdGhpcy5hcmdzID0gW107CiAgICB0aGlzLmVudiA9IFtdOwogICAgdGhpcy5mZHMgPSBbXTsKICAgIGRlYnVnLmVuYWJsZShvcHRpb25zLmRlYnVnKTsKICAgIHRoaXMuYXJncyA9IGFyZ3M7CiAgICB0aGlzLmVudiA9IGVudjsKICAgIHRoaXMuZmRzID0gZmRzOwogICAgY29uc3Qgc2VsZiA9IHRoaXM7CiAgICB0aGlzLndhc2lJbXBvcnQgPSB7IGFyZ3Nfc2l6ZXNfZ2V0KGFyZ2MsIGFyZ3ZfYnVmX3NpemUpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ2MsIHNlbGYuYXJncy5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGFyZyBvZiBzZWxmLmFyZ3MpIHsKICAgICAgICBidWZfc2l6ZSArPSBhcmcubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3ZfYnVmX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoYXJnYywgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGFyZ3NfZ2V0KGFyZ3YsIGFyZ3ZfYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2FyZ3ZfYnVmID0gYXJndl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5hcmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihhcmd2LCBhcmd2X2J1ZiwgdHJ1ZSk7CiAgICAgICAgYXJndiArPSA0OwogICAgICAgIGNvbnN0IGFyZyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmFyZ3NbaV0pOwogICAgICAgIGJ1ZmZlcjguc2V0KGFyZywgYXJndl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChhcmd2X2J1ZiArIGFyZy5sZW5ndGgsIDApOwogICAgICAgIGFyZ3ZfYnVmICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgICAgZGVidWcubG9nKG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvcmlnX2FyZ3ZfYnVmLCBhcmd2X2J1ZikpKTsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fc2l6ZXNfZ2V0KGVudmlyb25fY291bnQsIGVudmlyb25fc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9jb3VudCwgc2VsZi5lbnYubGVuZ3RoLCB0cnVlKTsKICAgICAgbGV0IGJ1Zl9zaXplID0gMDsKICAgICAgZm9yIChjb25zdCBlbnZpcm9uIG9mIHNlbGYuZW52KSB7CiAgICAgICAgYnVmX3NpemUgKz0gZW52aXJvbi5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9zaXplLCBidWZfc2l6ZSwgdHJ1ZSk7CiAgICAgIGRlYnVnLmxvZyhidWZmZXIuZ2V0VWludDMyKGVudmlyb25fY291bnQsIHRydWUpLCBidWZmZXIuZ2V0VWludDMyKGVudmlyb25fc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fZ2V0KGVudmlyb24sIGVudmlyb25fYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2Vudmlyb25fYnVmID0gZW52aXJvbl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5lbnYubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGVudmlyb24sIGVudmlyb25fYnVmLCB0cnVlKTsKICAgICAgICBlbnZpcm9uICs9IDQ7CiAgICAgICAgY29uc3QgZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmVudltpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoZSwgZW52aXJvbl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChlbnZpcm9uX2J1ZiArIGUubGVuZ3RoLCAwKTsKICAgICAgICBlbnZpcm9uX2J1ZiArPSBlLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfZW52aXJvbl9idWYsIGVudmlyb25fYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgY2xvY2tfcmVzX2dldChpZCwgcmVzX3B0cikgewogICAgICBsZXQgcmVzb2x1dGlvblZhbHVlOwogICAgICBzd2l0Y2ggKGlkKSB7CiAgICAgICAgY2FzZSBDTE9DS0lEX01PTk9UT05JQzogewogICAgICAgICAgcmVzb2x1dGlvblZhbHVlID0gNTAwMG47CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDTE9DS0lEX1JFQUxUSU1FOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSAxMDAwMDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuIEVSUk5PX05PU1lTOwogICAgICB9CiAgICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIHZpZXcuc2V0QmlnVWludDY0KHJlc19wdHIsIHJlc29sdXRpb25WYWx1ZSwgdHJ1ZSk7CiAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgfSwgY2xvY2tfdGltZV9nZXQoaWQsIHByZWNpc2lvbiwgdGltZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChpZCA9PT0gQ0xPQ0tJRF9SRUFMVElNRSkgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgQmlnSW50KG5ldyBEYXRlKCkuZ2V0VGltZSgpKSAqIDEwMDAwMDBuLCB0cnVlKTsKICAgICAgfSBlbHNlIGlmIChpZCA9PSBDTE9DS0lEX01PTk9UT05JQykgewogICAgICAgIGxldCBtb25vdG9uaWNfdGltZTsKICAgICAgICB0cnkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSBCaWdJbnQoTWF0aC5yb3VuZChwZXJmb3JtYW5jZS5ub3coKSAqIDFlNikpOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIG1vbm90b25pY190aW1lID0gMG47CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgbW9ub3RvbmljX3RpbWUsIHRydWUpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgMG4sIHRydWUpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZmRfYWR2aXNlKGZkLCBvZmZzZXQsIGxlbiwgYWR2aWNlKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2FsbG9jYXRlKGZkLCBvZmZzZXQsIGxlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9jbG9zZShmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW2ZkXS5mZF9jbG9zZSgpOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9kYXRhc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfZ2V0KGZkLCBmZHN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZkc3RhdCB9ID0gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmRzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZkc3RhdC53cml0ZV9ieXRlcyhuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlciksIGZkc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfc2V0X2ZsYWdzKGZkLCBmbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZkLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X2dldChmZCwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfZ2V0KCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfc2V0X3NpemUoZmQsIHNpemUpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlYWQoaW92ZWMuYnVmX2xlbiwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgb2Zmc2V0ICs9IEJpZ0ludChkYXRhLmxlbmd0aCk7CiAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggIT0gaW92ZWMuYnVmX2xlbikgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9nZXQoZmQsIGJ1Zl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBwcmVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgYnVmX3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZXN0YXRfZGlyX25hbWUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBjb25zdCBwcmVzdGF0X2Rpcl9uYW1lID0gcHJlc3RhdC5pbm5lci5wcl9uYW1lOwogICAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgICBidWZmZXI4LnNldChwcmVzdGF0X2Rpcl9uYW1lLnNsaWNlKDAsIHBhdGhfbGVuKSwgcGF0aF9wdHIpOwogICAgICAgIHJldHVybiBwcmVzdGF0X2Rpcl9uYW1lLmJ5dGVMZW5ndGggPiBwYXRoX2xlbiA/IEVSUk5PX05BTUVUT09MT05HIDogRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHdyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbndyaXR0ZW5fcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IENpb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbndyaXR0ZW4gPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCBkYXRhID0gYnVmZmVyOC5zbGljZShpb3ZlYy5idWYsIGlvdmVjLmJ1ZiArIGlvdmVjLmJ1Zl9sZW4pOwogICAgICAgICAgY29uc3QgeyByZXQsIG53cml0dGVuOiBud3JpdHRlbl9wYXJ0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHdyaXRlKGRhdGEsIG9mZnNldCk7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIG53cml0dGVuICs9IG53cml0dGVuX3BhcnQ7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KG53cml0dGVuX3BhcnQpOwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG5yZWFkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBJb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbnJlYWQgPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLmZkX3JlYWQoaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGEsIGlvdmVjLmJ1Zik7CiAgICAgICAgICBucmVhZCArPSBkYXRhLmxlbmd0aDsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkZGlyKGZkLCBidWYsIGJ1Zl9sZW4sIGNvb2tpZSwgYnVmdXNlZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgbGV0IGJ1ZnVzZWQgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGlyZW50IH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKTsKICAgICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChkaXJlbnQgPT0gbnVsbCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5oZWFkX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNvbnN0IGhlYWRfYnl0ZXMgPSBuZXcgQXJyYXlCdWZmZXIoZGlyZW50LmhlYWRfbGVuZ3RoKCkpOwogICAgICAgICAgZGlyZW50LndyaXRlX2hlYWRfYnl0ZXMobmV3IERhdGFWaWV3KGhlYWRfYnl0ZXMpLCAwKTsKICAgICAgICAgIGJ1ZmZlcjguc2V0KG5ldyBVaW50OEFycmF5KGhlYWRfYnl0ZXMpLnNsaWNlKDAsIE1hdGgubWluKGhlYWRfYnl0ZXMuYnl0ZUxlbmd0aCwgYnVmX2xlbiAtIGJ1ZnVzZWQpKSwgYnVmKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50LmhlYWRfbGVuZ3RoKCk7CiAgICAgICAgICBpZiAoYnVmX2xlbiAtIGJ1ZnVzZWQgPCBkaXJlbnQubmFtZV9sZW5ndGgoKSkgewogICAgICAgICAgICBidWZ1c2VkID0gYnVmX2xlbjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBkaXJlbnQud3JpdGVfbmFtZV9ieXRlcyhidWZmZXI4LCBidWYsIGJ1Zl9sZW4gLSBidWZ1c2VkKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50Lm5hbWVfbGVuZ3RoKCk7CiAgICAgICAgICBjb29raWUgPSBkaXJlbnQuZF9uZXh0OwogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcmVudW1iZXIoZmQsIHRvKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW3RvXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCByZXQgPSBzZWxmLmZkc1t0b10uZmRfY2xvc2UoKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzW3RvXSA9IHNlbGYuZmRzW2ZkXTsKICAgICAgICBzZWxmLmZkc1tmZF0gPSB2b2lkIDA7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3NlZWsoZmQsIG9mZnNldCwgd2hlbmNlLCBvZmZzZXRfb3V0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIG9mZnNldDogb2Zmc2V0X291dCB9ID0gc2VsZi5mZHNbZmRdLmZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdJbnQ2NChvZmZzZXRfb3V0X3B0ciwgb2Zmc2V0X291dCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF90ZWxsKGZkLCBvZmZzZXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfdGVsbCgpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQob2Zmc2V0X3B0ciwgb2Zmc2V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF93cml0ZShmZCwgaW92c19wdHIsIGlvdnNfbGVuLCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF93cml0ZShkYXRhKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIGlmIChud3JpdHRlbl9wYXJ0ICE9IGRhdGEuYnl0ZUxlbmd0aCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9nZXQoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGZpbGVzdGF0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2xpbmsob2xkX2ZkLCBvbGRfZmxhZ3MsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW29sZF9mZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW29sZF9mZF0ucGF0aF9sb29rdXAob2xkX3BhdGgsIG9sZF9mbGFncyk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgZmFsc2UpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX29wZW4oZmQsIGRpcmZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncywgb3BlbmVkX2ZkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgpOwogICAgICAgIGNvbnN0IHsgcmV0LCBmZF9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGgsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncyk7CiAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBzZWxmLmZkcy5wdXNoKGZkX29iaik7CiAgICAgICAgY29uc3Qgb3BlbmVkX2ZkID0gc2VsZi5mZHMubGVuZ3RoIC0gMTsKICAgICAgICBidWZmZXIuc2V0VWludDMyKG9wZW5lZF9mZF9wdHIsIG9wZW5lZF9mZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVhZGxpbmsoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbiwgYnVmX3B0ciwgYnVmX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3JlYWRsaW5rKHBhdGgpOwogICAgICAgIGlmIChkYXRhICE9IG51bGwpIHsKICAgICAgICAgIGNvbnN0IGRhdGFfYnVmID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGRhdGEpOwogICAgICAgICAgaWYgKGRhdGFfYnVmLmxlbmd0aCA+IGJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIDAsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGFfYnVmLCBidWZfcHRyKTsKICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBkYXRhX2J1Zi5sZW5ndGgsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbW92ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbmFtZShmZCwgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCAmJiBzZWxmLmZkc1tuZXdfZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICBsZXQgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfdW5saW5rKG9sZF9wYXRoKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldCA9IHNlbGYuZmRzW25ld19mZF0ucGF0aF9saW5rKG5ld19wYXRoLCBpbm9kZV9vYmosIHRydWUpOwogICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgaWYgKHNlbGYuZmRzW2ZkXS5wYXRoX2xpbmsob2xkX3BhdGgsIGlub2RlX29iaiwgdHJ1ZSkgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICB0aHJvdyAicGF0aF9saW5rIHNob3VsZCBhbHdheXMgcmV0dXJuIHN1Y2Nlc3Mgd2hlbiByZWxpbmtpbmcgYW4gaW5vZGUgYmFjayB0byB0aGUgb3JpZ2luYWwgcGxhY2UiOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3N5bWxpbmsob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIGZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfdW5saW5rX2ZpbGUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmtfZmlsZShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGgsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfcmVhZGxpbmsocGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG51bGwgfTsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQp9Owp2YXIgSW5vZGUgPSBjbGFzcyB7Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZzX21lbS5qcwp2YXIgT3BlbkZpbGUgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gb2Zmc2V0ICsgbGVuKSB7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBsZW4pKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCAwKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBzaXplKSB7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5maWxlLmRhdGEuYnVmZmVyLnNsaWNlKDAsIE51bWJlcihzaXplKSkpOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIoc2l6ZSkpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIodGhpcy5maWxlX3BvcyksIE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KHNpemUpKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChzbGljZS5sZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKG9mZnNldCksIE51bWJlcihvZmZzZXQgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgbGV0IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgc3dpdGNoICh3aGVuY2UpIHsKICAgICAgY2FzZSBXSEVOQ0VfU0VUOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9DVVI6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSB0aGlzLmZpbGVfcG9zICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9FTkQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBCaWdJbnQodGhpcy5maWxlLmRhdGEuYnl0ZUxlbmd0aCkgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgaWYgKGNhbGN1bGF0ZWRfb2Zmc2V0IDwgMCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICB0aGlzLmZpbGVfcG9zID0gY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcihvZmZzZXQpKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmZpbGUuc3RhdCgpIH07CiAgfQogIGNvbnN0cnVjdG9yKGZpbGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmZpbGVfcG9zID0gMG47CiAgICB0aGlzLmZpbGUgPSBmaWxlOwogIH0KfTsKdmFyIE9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9ESVJFQ1RPUlksIDApIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgZGVidWcubG9nKCJyZWFkZGlyX3NpbmdsZSIsIGNvb2tpZSk7CiAgICAgIGRlYnVnLmxvZyhjb29raWUsIHRoaXMuZGlyLmNvbnRlbnRzLmtleXMoKSk7CiAgICB9CiAgICBpZiAoY29va2llID09IDBuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDFuLCAiLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0gZWxzZSBpZiAoY29va2llID09IDFuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDJuLCAiLi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9CiAgICBpZiAoY29va2llID49IEJpZ0ludCh0aGlzLmRpci5jb250ZW50cy5zaXplKSArIDJuKSB7CiAgICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBbbmFtZSwgZW50cnldID0gQXJyYXkuZnJvbSh0aGlzLmRpci5jb250ZW50cy5lbnRyaWVzKCkpW051bWJlcihjb29raWUgLSAybildOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG5ldyBEaXJlbnQoY29va2llICsgMW4sIG5hbWUsIGVudHJ5LnN0YXQoKS5maWxldHlwZSkgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9lcnIsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IGVudHJ5LnN0YXQoKSB9OwogIH0KICBwYXRoX2xvb2t1cChwYXRoX3N0ciwgZGlyZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoX3N0ciwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgaWYgKHJldCAhPSBFUlJOT19OT0VOVCkgewogICAgICAgIHJldHVybiB7IHJldCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfQ1JFQVQpID09IE9GTEFHU19DUkVBVCkgewogICAgICAgIGNvbnN0IHsgcmV0OiByZXQyLCBlbnRyeTogbmV3X2VudHJ5IH0gPSB0aGlzLmRpci5jcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZKTsKICAgICAgICBpZiAobmV3X2VudHJ5ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiB7IHJldDogcmV0MiwgZmRfb2JqOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGVudHJ5ID0gbmV3X2VudHJ5OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICB9IGVsc2UgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRVhDTCkgPT0gT0ZMQUdTX0VYQ0wpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIGVudHJ5LnBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncyk7CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gdGhpcy5wYXRoX29wZW4oMCwgcGF0aCwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIGNvbnN0IHNvdXJjZV9pc19kaXIgPSBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBjb25zdCB0YXJnZXRfaXNfZGlyID0gZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgaWYgKHNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIGlmIChhbGxvd19kaXIgJiYgZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHsKICAgICAgICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplID09IDApIHsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChzb3VyY2VfaXNfZGlyICYmICF0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgICAgfSBlbHNlIGlmICghc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgICB9IGVsc2UgaWYgKGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSkgewogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgfQogICAgfQogICAgaWYgKCFhbGxvd19kaXIgJiYgaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fUEVSTTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIGlub2RlKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3VubGluayhwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF91bmxpbmtfZmlsZShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHx8IGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICB9CiAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSAhPT0gMCkgewogICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICB9CiAgICBpZiAoIXBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpKSB7CiAgICAgIHJldHVybiBFUlJOT19OT0VOVDsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmRpci5zdGF0KCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBjb25zdHJ1Y3RvcihkaXIpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRpciA9IGRpcjsKICB9Cn07CnZhciBQcmVvcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBPcGVuRGlyZWN0b3J5IHsKICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgcHJlc3RhdDogUHJlc3RhdC5kaXIodGhpcy5wcmVzdGF0X25hbWUpIH07CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnRzKSB7CiAgICBzdXBlcihuZXcgRGlyZWN0b3J5KGNvbnRlbnRzKSk7CiAgICB0aGlzLnByZXN0YXRfbmFtZSA9IG5hbWU7CiAgfQp9Owp2YXIgRmlsZSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgaWYgKHRoaXMucmVhZG9ubHkgJiYgKGZzX3JpZ2h0c19iYXNlICYgQmlnSW50KFJJR0hUU19GRF9XUklURSkpID09IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19UUlVOQykgPT0gT0ZMQUdTX1RSVU5DKSB7CiAgICAgIGlmICh0aGlzLnJlYWRvbmx5KQogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KFtdKTsKICAgIH0KICAgIGNvbnN0IGZpbGUgPSBuZXcgT3BlbkZpbGUodGhpcyk7CiAgICBpZiAoZmRfZmxhZ3MgJiBGREZMQUdTX0FQUEVORCkKICAgICAgZmlsZS5mZF9zZWVrKDBuLCBXSEVOQ0VfRU5EKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZmRfb2JqOiBmaWxlIH07CiAgfQogIGdldCBzaXplKCkgewogICAgcmV0dXJuIEJpZ0ludCh0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgdGhpcy5zaXplKTsKICB9CiAgY29uc3RydWN0b3IoZGF0YSwgb3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgdGhpcy5yZWFkb25seSA9ICEhb3B0aW9ucz8ucmVhZG9ubHk7CiAgfQp9Owp2YXIgUGF0aCA9IGNsYXNzIFBhdGgyIHsKICBzdGF0aWMgZnJvbShwYXRoKSB7CiAgICBjb25zdCBzZWxmID0gbmV3IFBhdGgyKCk7CiAgICBzZWxmLmlzX2RpciA9IHBhdGguZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVENBUEFCTEUsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGlmIChwYXRoLmluY2x1ZGVzKCJcMCIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGguc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aCkgewogICAgbGV0IGVudHJ5ID0gdGhpczsKICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgucGFydHMpIHsKICAgICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgICAgY29uc3QgY2hpbGQgPSBlbnRyeS5jb250ZW50cy5nZXQoY29tcG9uZW50KTsKICAgICAgaWYgKGNoaWxkICE9PSB2b2lkIDApIHsKICAgICAgICBlbnRyeSA9IGNoaWxkOwogICAgICB9IGVsc2UgewogICAgICAgIGRlYnVnLmxvZyhjb21wb25lbnQpOwogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBhbGxvd191bmRlZmluZWQpIHsKICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5wYXJ0cy5wb3AoKTsKICAgIGlmIChmaWxlbmFtZSA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldDogZW50cnlfcmV0LCBlbnRyeTogcGFyZW50X2VudHJ5IH0gPSB0aGlzLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfTsKICB9CiAgY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCBpc19kaXIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGRlYnVnLmxvZygiY3JlYXRlIiwgcGF0aCk7CiAgICBsZXQgbmV3X2NoaWxkOwogICAgaWYgKCFpc19kaXIpIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IEZpbGUobmV3IEFycmF5QnVmZmVyKDApKTsKICAgIH0gZWxzZSB7CiAgICAgIG5ld19jaGlsZCA9IG5ldyBEaXJlY3RvcnkoLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSk7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBuZXdfY2hpbGQpOwogICAgZW50cnkgPSBuZXdfY2hpbGQ7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGNvbnN0cnVjdG9yKGNvbnRlbnRzKSB7CiAgICBzdXBlcigpOwogICAgaWYgKGNvbnRlbnRzIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgdGhpcy5jb250ZW50cyA9IG5ldyBNYXAoY29udGVudHMpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5jb250ZW50cyA9IGNvbnRlbnRzOwogICAgfQogIH0KfTsKdmFyIENvbnNvbGVTdGRvdXQgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmaWxlc3RhdCA9IG5ldyBGaWxlc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCBCaWdJbnQoMCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdCB9OwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgY29uc3QgZmRzdGF0ID0gbmV3IEZkc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCAwKTsKICAgIGZkc3RhdC5mc19yaWdodHNfYmFzZSA9IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgdGhpcy53cml0ZShkYXRhKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBzdGF0aWMgbGluZUJ1ZmZlcmVkKHdyaXRlKSB7CiAgICBjb25zdCBkZWMgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICBsZXQgbGluZV9idWYgPSAiIjsKICAgIHJldHVybiBuZXcgQ29uc29sZVN0ZG91dCgoYnVmZmVyKSA9PiB7CiAgICAgIGxpbmVfYnVmICs9IGRlYy5kZWNvZGUoYnVmZmVyLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgICAgY29uc3QgbGluZXMgPSBsaW5lX2J1Zi5zcGxpdCgiXG4iKTsKICAgICAgZm9yIChjb25zdCBbaSwgbGluZV0gb2YgbGluZXMuZW50cmllcygpKSB7CiAgICAgICAgaWYgKGkgPCBsaW5lcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICB3cml0ZShsaW5lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGluZV9idWYgPSBsaW5lOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfQogIGNvbnN0cnVjdG9yKHdyaXRlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy53cml0ZSA9IHdyaXRlOwogIH0KfTsKCi8vIGVudHJ5cG9pbnQvY29tbW9uLnRzCnZhciBMaW5lRGVjb2RlciA9IGNsYXNzIHsKICBjb25zdHJ1Y3RvcihvbkxpbmUpIHsKICAgIHRoaXMuZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIHRoaXMuYnVmZmVyID0gIiI7CiAgICB0aGlzLm9uTGluZSA9IG9uTGluZTsKICB9CiAgZGVjb2RlcjsKICBidWZmZXI7CiAgb25MaW5lOwogIHNlbmQoY2h1bmspIHsKICAgIHRoaXMuYnVmZmVyICs9IHRoaXMuZGVjb2Rlci5kZWNvZGUoY2h1bmssIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgY29uc3QgbGluZXMgPSB0aGlzLmJ1ZmZlci5zcGxpdCgiXG4iKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoIC0gMTsgaSsrKSB7CiAgICAgIHRoaXMub25MaW5lKGxpbmVzW2ldKTsKICAgIH0KICAgIHRoaXMuYnVmZmVyID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV07CiAgfQp9Owp2YXIgV2FzbVJ1bm5lciA9IChyYXdPcHRpb25zLCBTd2lmdFJ1bnRpbWUpID0+IHsKICBjb25zdCBvcHRpb25zID0gZGVmYXVsdFJ1bm5lck9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0OwogIGlmIChTd2lmdFJ1bnRpbWUpIHsKICAgIHN3aWZ0ID0gbmV3IFN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJncyA9IG9wdGlvbnMuYXJncyB8fCBbXTsKICBjb25zdCBmZHMgPSBbCiAgICBuZXcgT3BlbkZpbGUobmV3IEZpbGUoW10pKSwKICAgIHN0ZG91dCwKICAgIHN0ZGVyciwKICAgIG5ldyBQcmVvcGVuRGlyZWN0b3J5KCIvIiwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSkKICBdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzLCBbXSwgZmRzLCB7CiAgICBkZWJ1ZzogZmFsc2UKICB9KTsKICBjb25zdCBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0ID0gKGV4dHJhV2FzbUltcG9ydHMsIG1vZHVsZSkgPT4gewogICAgY29uc3QgaW1wb3J0T2JqZWN0ID0gewogICAgICB3YXNpX3NuYXBzaG90X3ByZXZpZXcxOiB3YXNpLndhc2lJbXBvcnQKICAgIH07CiAgICBpZiAoc3dpZnQpIHsKICAgICAgaW1wb3J0T2JqZWN0LmphdmFzY3JpcHRfa2l0ID0gc3dpZnQud2FzbUltcG9ydHM7CiAgICB9CiAgICBpZiAoZXh0cmFXYXNtSW1wb3J0cykgewogICAgICBmb3IgKGNvbnN0IG1vZHVsZU5hbWUgaW4gZXh0cmFXYXNtSW1wb3J0cykgewogICAgICAgIGlmICghaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdKSB7CiAgICAgICAgICBpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0gPSB7fTsKICAgICAgICB9CiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBpbiBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdKSB7CiAgICAgICAgICBpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV1bZW50cnldID0gZXh0cmFXYXNtSW1wb3J0c1ttb2R1bGVOYW1lXVtlbnRyeV07CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBmb3IgKGNvbnN0IGltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKG1vZHVsZSkpIHsKICAgICAgaWYgKCFpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXSkgewogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdID0ge307CiAgICAgIH0KICAgICAgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gImZ1bmN0aW9uIiAmJiAhaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGltcG9ydE9iamVjdDsKICB9OwogIHJldHVybiB7CiAgICBhc3luYyBydW4od2FzbUJ5dGVzLCBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGlmICghZXh0cmFXYXNtSW1wb3J0cykgewogICAgICAgIGV4dHJhV2FzbUltcG9ydHMgPSB7fTsKICAgICAgfQogICAgICBleHRyYVdhc21JbXBvcnRzLl9fc3RhY2tfc2FuaXRpemVyID0gewogICAgICAgIHJlcG9ydF9zdGFja19vdmVyZmxvdzogKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJEZXRlY3RlZCBzdGFjayBidWZmZXIgb3ZlcmZsb3cuIik7CiAgICAgICAgfQogICAgICB9OwogICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseS5jb21waWxlKHdhc21CeXRlcyk7CiAgICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKTsKICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShtb2R1bGUsIGltcG9ydE9iamVjdCk7CiAgICAgIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICAgICAgc3dpZnQuc2V0SW5zdGFuY2UoaW5zdGFuY2UpOwogICAgICB9CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLnN0YXJ0KGluc3RhbmNlKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgICAgICBpZiAoc3dpZnQgJiYgc3dpZnQubWFpbikgewogICAgICAgICAgc3dpZnQubWFpbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMubWFpbiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YoMCwgMCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKfTsKdmFyIGRlZmF1bHRSdW5uZXJPcHRpb25zID0gKG9wdGlvbnMpID0+IHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIHJldHVybiBvcHRpb25zOwp9OwoKLy8gZW50cnlwb2ludC90ZXN0LnRzCnZhciBzb2NrZXQgPSBuZXcgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdChgd3M6Ly8ke2xvY2F0aW9uLmhvc3R9L3dhdGNoZXJgKTsKc29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCAobWVzc2FnZSkgPT4gewogIGlmIChtZXNzYWdlLmRhdGEgPT09ICJyZWxvYWQiKSB7CiAgICBsb2NhdGlvbi5yZWxvYWQoKTsKICB9Cn0pOwp2YXIgc3RhcnRXYXNpVGFzayA9IGFzeW5jICgpID0+IHsKICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCIvbWFpbi53YXNtIik7CiAgY29uc3QgcmVzcG9uc2VBcnJheUJ1ZmZlciA9IGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICB9IGNhdGNoIHsKICAgIGNvbnNvbGUubG9nKCJKYXZhU2NyaXB0S2l0IG1vZHVsZSBub3QgYXZhaWxhYmxlLCBydW5uaW5nIHdpdGhvdXQgSmF2YVNjcmlwdEtpdCBydW50aW1lLiIpOwogIH0KICBsZXQgdGVzdFJ1bk91dHB1dCA9ICIiOwogIGNvbnN0IHdhc21SdW5uZXIgPSBXYXNtUnVubmVyKHsKICAgIG9uU3Rkb3V0TGluZTogKGxpbmUpID0+IHsKICAgICAgY29uc29sZS5sb2cobGluZSk7CiAgICAgIHRlc3RSdW5PdXRwdXQgKz0gbGluZSArICJcbiI7CiAgICB9LAogICAgb25TdGRlcnJMaW5lOiAobGluZSkgPT4gewogICAgICBjb25zb2xlLmVycm9yKGxpbmUpOwogICAgfQogIH0sIHJ1bnRpbWVDb25zdHJ1Y3Rvcik7CiAgY29uc3Qgd2FzbUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkocmVzcG9uc2VBcnJheUJ1ZmZlcikuYnVmZmVyOwogIGNvbnN0IGhhbmRsZUV4aXRPckVycm9yID0gKGVycm9yKSA9PiB7CiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXQVNJUHJvY0V4aXQpIHsKICAgICAgc29ja2V0LnNlbmQoSlNPTi5zdHJpbmdpZnkoeyBraW5kOiAidGVzdFJ1bk91dHB1dCIsIHRlc3RSdW5PdXRwdXQgfSkpOwogICAgICBpZiAoZXJyb3IuY29kZSA9PT0gMCkgewogICAgICAgIHNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KHsga2luZDogInRlc3RQYXNzZWQiIH0pKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBoYW5kbGVFcnJvcihlcnJvcik7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGhhbmRsZUVycm9yKGVycm9yKTsKICAgIH0KICAgIGNvbnN0IGRpdkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJwIik7CiAgICBkaXZFbGVtZW50LmlubmVySFRNTCA9ICJUZXN0IHJ1biBmaW5pc2hlZC4gQ2hlY2sgdGhlIG91dHB1dCBvZiA8Y29kZT5jYXJ0b24gdGVzdDwvY29kZT4gZm9yIGRldGFpbHMuIjsKICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZGl2RWxlbWVudCk7CiAgfTsKICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigidW5oYW5kbGVkcmVqZWN0aW9uIiwgKGV2ZW50KSA9PiB7CiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgY29uc3QgZXJyb3IgPSBldmVudC5yZWFzb247CiAgICBoYW5kbGVFeGl0T3JFcnJvcihlcnJvcik7CiAgfSk7CiAgdHJ5IHsKICAgIGF3YWl0IHdhc21SdW5uZXIucnVuKHdhc21CeXRlcyk7CiAgfSBjYXRjaCAoZXJyb3IpIHsKICAgIGhhbmRsZUV4aXRPckVycm9yKGVycm9yKTsKICAgIHJldHVybjsKICB9Cn07CmZ1bmN0aW9uIGhhbmRsZUVycm9yKGUpIHsKICBjb25zb2xlLmVycm9yKGUpOwogIGlmIChlIGluc3RhbmNlb2YgRXJyb3IpIHsKICAgIGNvbnN0IHN0YWNrID0gZS5zdGFjazsKICAgIGlmIChzdGFjayAhPSBudWxsKSB7CiAgICAgIHNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KHsKICAgICAgICBraW5kOiAic3RhY2tUcmFjZSIsCiAgICAgICAgc3RhY2tUcmFjZTogc3RhY2sKICAgICAgfSkpOwogICAgfQogIH0KICBzb2NrZXQuc2VuZChKU09OLnN0cmluZ2lmeSh7CiAgICBraW5kOiAiZXJyb3JSZXBvcnQiLAogICAgZXJyb3JSZXBvcnQ6IGUudG9TdHJpbmcoKQogIH0pKTsKfQphc3luYyBmdW5jdGlvbiBtYWluKCkgewogIHRyeSB7CiAgICBhd2FpdCBzdGFydFdhc2lUYXNrKCk7CiAgfSBjYXRjaCAoZSkgewogICAgaGFuZGxlRXJyb3IoZSk7CiAgfQp9Cm1haW4oKTsKLyohCiAqIFJlY29ubmVjdGluZyBXZWJTb2NrZXQKICogYnkgUGVkcm8gTGFkYXJpYSA8cGVkcm8ubGFkYXJpYUBnbWFpbC5jb20+CiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9wbGFkYXJpYS9yZWNvbm5lY3Rpbmctd2Vic29ja2V0CiAqIExpY2Vuc2UgTUlUCiAqLwovKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UKdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUKTGljZW5zZSBhdCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKClRISVMgQ09ERSBJUyBQUk9WSURFRCBPTiBBTiAqQVMgSVMqIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBBTlkgSU1QTElFRApXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLApNRVJDSEFOVEFCTElUWSBPUiBOT04tSU5GUklOR0VNRU5ULgoKU2VlIHRoZSBBcGFjaGUgVmVyc2lvbiAyLjAgTGljZW5zZSBmb3Igc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zCmFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8K")! - public static let testNode: Data = Data(base64Encoded: "dmFyIF9fY3JlYXRlID0gT2JqZWN0LmNyZWF0ZTsKdmFyIF9fZGVmUHJvcCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTsKdmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOwp2YXIgX19nZXRPd25Qcm9wTmFtZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lczsKdmFyIF9fZ2V0UHJvdG9PZiA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjsKdmFyIF9faGFzT3duUHJvcCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7CnZhciBfX2NvcHlQcm9wcyA9ICh0bywgZnJvbSwgZXhjZXB0LCBkZXNjKSA9PiB7CiAgaWYgKGZyb20gJiYgdHlwZW9mIGZyb20gPT09ICJvYmplY3QiIHx8IHR5cGVvZiBmcm9tID09PSAiZnVuY3Rpb24iKSB7CiAgICBmb3IgKGxldCBrZXkgb2YgX19nZXRPd25Qcm9wTmFtZXMoZnJvbSkpCiAgICAgIGlmICghX19oYXNPd25Qcm9wLmNhbGwodG8sIGtleSkgJiYga2V5ICE9PSBleGNlcHQpCiAgICAgICAgX19kZWZQcm9wKHRvLCBrZXksIHsgZ2V0OiAoKSA9PiBmcm9tW2tleV0sIGVudW1lcmFibGU6ICEoZGVzYyA9IF9fZ2V0T3duUHJvcERlc2MoZnJvbSwga2V5KSkgfHwgZGVzYy5lbnVtZXJhYmxlIH0pOwogIH0KICByZXR1cm4gdG87Cn07CnZhciBfX3RvRVNNID0gKG1vZCwgaXNOb2RlTW9kZSwgdGFyZ2V0KSA9PiAodGFyZ2V0ID0gbW9kICE9IG51bGwgPyBfX2NyZWF0ZShfX2dldFByb3RvT2YobW9kKSkgOiB7fSwgX19jb3B5UHJvcHMoaXNOb2RlTW9kZSB8fCAhbW9kIHx8ICFtb2QuX19lc01vZHVsZSA/IF9fZGVmUHJvcCh0YXJnZXQsICJkZWZhdWx0IiwgeyB2YWx1ZTogbW9kLCBlbnVtZXJhYmxlOiB0cnVlIH0pIDogdGFyZ2V0LCBtb2QpKTsKCi8vIGVudHJ5cG9pbnQvdGVzdE5vZGUudHMKdmFyIGltcG9ydF9wcm9taXNlcyA9IF9fdG9FU00ocmVxdWlyZSgiZnMvcHJvbWlzZXMiKSk7CnZhciBpbXBvcnRfcGF0aCA9IF9fdG9FU00ocmVxdWlyZSgicGF0aCIpKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJnczIsIGVudiwgZmRzLCBvcHRpb25zID0ge30pIHsKICAgIHRoaXMuYXJncyA9IFtdOwogICAgdGhpcy5lbnYgPSBbXTsKICAgIHRoaXMuZmRzID0gW107CiAgICBkZWJ1Zy5lbmFibGUob3B0aW9ucy5kZWJ1Zyk7CiAgICB0aGlzLmFyZ3MgPSBhcmdzMjsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfZ2V0KGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aDIpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X3NldF90aW1lcyhmbGFncywgcGF0aDIsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgyKTsKICAgICAgICBjb25zdCB7IHJldCwgZmRfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoMiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aDIpOwogICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9yZWFkbGluayhwYXRoMik7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoMiA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZW5hbWUoZmQsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgbGV0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3VubGluayhvbGRfcGF0aCk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXQgPSBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKTsKICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgIGlmIChzZWxmLmZkc1tmZF0ucGF0aF9saW5rKG9sZF9wYXRoLCBpbm9kZV9vYmosIHRydWUpICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgdGhyb3cgInBhdGhfbGluayBzaG91bGQgYWx3YXlzIHJldHVybiBzdWNjZXNzIHdoZW4gcmVsaW5raW5nIGFuIGlub2RlIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHBsYWNlIjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9zeW1saW5rKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBmZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3VubGlua19maWxlKGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgyLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoMiwgaW5vZGUsIGFsbG93X2RpcikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF91bmxpbmsocGF0aDIpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aDIsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aDIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogIH0KICBwYXRoX3JlYWRsaW5rKHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KfTsKdmFyIElub2RlID0gY2xhc3Mgewp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mc19tZW0uanMKdmFyIE9wZW5GaWxlID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IG9mZnNldCArIGxlbikgewogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgbGVuKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgMCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gc2l6ZSkgewogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KHRoaXMuZmlsZS5kYXRhLmJ1ZmZlci5zbGljZSgwLCBOdW1iZXIoc2l6ZSkpKTsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHNpemUpKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKHRoaXMuZmlsZV9wb3MpLCBOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChzaXplKSkpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoc2xpY2UubGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcihvZmZzZXQpLCBOdW1iZXIob2Zmc2V0ICsgQmlnSW50KHNpemUpKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIGxldCBjYWxjdWxhdGVkX29mZnNldDsKICAgIHN3aXRjaCAod2hlbmNlKSB7CiAgICAgIGNhc2UgV0hFTkNFX1NFVDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfQ1VSOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gdGhpcy5maWxlX3BvcyArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfRU5EOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gQmlnSW50KHRoaXMuZmlsZS5kYXRhLmJ5dGVMZW5ndGgpICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIGlmIChjYWxjdWxhdGVkX29mZnNldCA8IDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgdGhpcy5maWxlX3BvcyA9IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmICh0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcih0aGlzLmZpbGVfcG9zKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmIChvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIob2Zmc2V0KSk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5maWxlLnN0YXQoKSB9OwogIH0KICBjb25zdHJ1Y3RvcihmaWxlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5maWxlX3BvcyA9IDBuOwogICAgdGhpcy5maWxlID0gZmlsZTsKICB9Cn07CnZhciBPcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgIGRlYnVnLmxvZygicmVhZGRpcl9zaW5nbGUiLCBjb29raWUpOwogICAgICBkZWJ1Zy5sb2coY29va2llLCB0aGlzLmRpci5jb250ZW50cy5rZXlzKCkpOwogICAgfQogICAgaWYgKGNvb2tpZSA9PSAwbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgxbiwgIi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9IGVsc2UgaWYgKGNvb2tpZSA9PSAxbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgybiwgIi4uIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfQogICAgaWYgKGNvb2tpZSA+PSBCaWdJbnQodGhpcy5kaXIuY29udGVudHMuc2l6ZSkgKyAybikgewogICAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbnVsbCB9OwogICAgfQogICAgY29uc3QgW25hbWUsIGVudHJ5XSA9IEFycmF5LmZyb20odGhpcy5kaXIuY29udGVudHMuZW50cmllcygpKVtOdW1iZXIoY29va2llIC0gMm4pXTsKICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBuZXcgRGlyZW50KGNvb2tpZSArIDFuLCBuYW1lLCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUpIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfZXJyLCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiBlbnRyeS5zdGF0KCkgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aF9zdHIsIGRpcmZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aF9zdHIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIGlmIChyZXQgIT0gRVJSTk9fTk9FTlQpIHsKICAgICAgICByZXR1cm4geyByZXQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0NSRUFUKSA9PSBPRkxBR1NfQ1JFQVQpIHsKICAgICAgICBjb25zdCB7IHJldDogcmV0MiwgZW50cnk6IG5ld19lbnRyeSB9ID0gdGhpcy5kaXIuY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCAob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSk7CiAgICAgICAgaWYgKG5ld19lbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4geyByZXQ6IHJldDIsIGZkX29iajogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBlbnRyeSA9IG5ld19lbnRyeTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgfSBlbHNlIGlmICgob2ZsYWdzICYgT0ZMQUdTX0VYQ0wpID09IE9GTEFHU19FWENMKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiBlbnRyeS5wYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpOwogIH0KICBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoMiwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoMi5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aDIsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICBjb25zdCBzb3VyY2VfaXNfZGlyID0gaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgY29uc3QgdGFyZ2V0X2lzX2RpciA9IGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGlmIChzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICBpZiAoYWxsb3dfZGlyICYmIGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB7CiAgICAgICAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSA9PSAwKSB7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoc291cmNlX2lzX2RpciAmJiAhdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICAgIH0gZWxzZSBpZiAoIXNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgICAgfSBlbHNlIGlmIChpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUpIHsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgIH0KICAgIH0KICAgIGlmICghYWxsb3dfZGlyICYmIGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX1BFUk07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBpbm9kZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF91bmxpbmsocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmICghKGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB8fCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgfQogICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgIT09IDApIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgfQogICAgaWYgKCFwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKSkgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5kaXIuc3RhdCgpIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgY29uc3RydWN0b3IoZGlyKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kaXIgPSBkaXI7CiAgfQp9Owp2YXIgUHJlb3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgT3BlbkRpcmVjdG9yeSB7CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIHByZXN0YXQ6IFByZXN0YXQuZGlyKHRoaXMucHJlc3RhdF9uYW1lKSB9OwogIH0KICBjb25zdHJ1Y3RvcihuYW1lLCBjb250ZW50cykgewogICAgc3VwZXIobmV3IERpcmVjdG9yeShjb250ZW50cykpOwogICAgdGhpcy5wcmVzdGF0X25hbWUgPSBuYW1lOwogIH0KfTsKdmFyIEZpbGUgPSBjbGFzcyBleHRlbmRzIElub2RlIHsKICBwYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpIHsKICAgIGlmICh0aGlzLnJlYWRvbmx5ICYmIChmc19yaWdodHNfYmFzZSAmIEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSA9PSBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfVFJVTkMpID09IE9GTEFHU19UUlVOQykgewogICAgICBpZiAodGhpcy5yZWFkb25seSkKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShbXSk7CiAgICB9CiAgICBjb25zdCBmaWxlID0gbmV3IE9wZW5GaWxlKHRoaXMpOwogICAgaWYgKGZkX2ZsYWdzICYgRkRGTEFHU19BUFBFTkQpCiAgICAgIGZpbGUuZmRfc2VlaygwbiwgV0hFTkNFX0VORCk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogZmlsZSB9OwogIH0KICBnZXQgc2l6ZSgpIHsKICAgIHJldHVybiBCaWdJbnQodGhpcy5kYXRhLmJ5dGVMZW5ndGgpOwogIH0KICBzdGF0KCkgewogICAgcmV0dXJuIG5ldyBGaWxlc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIHRoaXMuc2l6ZSk7CiAgfQogIGNvbnN0cnVjdG9yKGRhdGEsIG9wdGlvbnMpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShkYXRhKTsKICAgIHRoaXMucmVhZG9ubHkgPSAhIW9wdGlvbnM/LnJlYWRvbmx5OwogIH0KfTsKdmFyIFBhdGggPSBjbGFzcyBQYXRoMiB7CiAgc3RhdGljIGZyb20ocGF0aDIpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aDIuZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoMi5zdGFydHNXaXRoKCIvIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICB9CiAgICBpZiAocGF0aDIuaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aDIuc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aDIpIHsKICAgIGxldCBlbnRyeSA9IHRoaXM7CiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiBwYXRoMi5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgYWxsb3dfdW5kZWZpbmVkKSB7CiAgICBjb25zdCBmaWxlbmFtZSA9IHBhdGgyLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH07CiAgfQogIGNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgaXNfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBkZWJ1Zy5sb2coImNyZWF0ZSIsIHBhdGgyKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gZW50cnlwb2ludC9jb21tb24udHMKdmFyIExpbmVEZWNvZGVyID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG9uTGluZSkgewogICAgdGhpcy5kZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIsIHsgZmF0YWw6IGZhbHNlIH0pOwogICAgdGhpcy5idWZmZXIgPSAiIjsKICAgIHRoaXMub25MaW5lID0gb25MaW5lOwogIH0KICBkZWNvZGVyOwogIGJ1ZmZlcjsKICBvbkxpbmU7CiAgc2VuZChjaHVuaykgewogICAgdGhpcy5idWZmZXIgKz0gdGhpcy5kZWNvZGVyLmRlY29kZShjaHVuaywgeyBzdHJlYW06IHRydWUgfSk7CiAgICBjb25zdCBsaW5lcyA9IHRoaXMuYnVmZmVyLnNwbGl0KCJcbiIpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGggLSAxOyBpKyspIHsKICAgICAgdGhpcy5vbkxpbmUobGluZXNbaV0pOwogICAgfQogICAgdGhpcy5idWZmZXIgPSBsaW5lc1tsaW5lcy5sZW5ndGggLSAxXTsKICB9Cn07CnZhciBXYXNtUnVubmVyID0gKHJhd09wdGlvbnMsIFN3aWZ0UnVudGltZSkgPT4gewogIGNvbnN0IG9wdGlvbnMgPSBkZWZhdWx0UnVubmVyT3B0aW9ucyhyYXdPcHRpb25zKTsKICBsZXQgc3dpZnQ7CiAgaWYgKFN3aWZ0UnVudGltZSkgewogICAgc3dpZnQgPSBuZXcgU3dpZnRSdW50aW1lKCk7CiAgfQogIGxldCBzdGRvdXRMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3Rkb3V0TGluZSAhPSBudWxsKSB7CiAgICBzdGRvdXRMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRvdXRMaW5lKTsKICB9CiAgY29uc3Qgc3Rkb3V0ID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3Rkb3V0Py5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3Rkb3V0TGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgbGV0IHN0ZGVyckxpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRlcnJMaW5lICE9IG51bGwpIHsKICAgIHN0ZGVyckxpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZGVyckxpbmUpOwogIH0KICBjb25zdCBzdGRlcnIgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRlcnI/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRlcnJMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBjb25zdCBhcmdzMiA9IG9wdGlvbnMuYXJncyB8fCBbXTsKICBjb25zdCBmZHMgPSBbCiAgICBuZXcgT3BlbkZpbGUobmV3IEZpbGUoW10pKSwKICAgIHN0ZG91dCwKICAgIHN0ZGVyciwKICAgIG5ldyBQcmVvcGVuRGlyZWN0b3J5KCIvIiwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSkKICBdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzMiwgW10sIGZkcywgewogICAgZGVidWc6IGZhbHNlCiAgfSk7CiAgY29uc3QgY3JlYXRlV2FzbUltcG9ydE9iamVjdCA9IChleHRyYVdhc21JbXBvcnRzLCBtb2R1bGUyKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QgPSB7CiAgICAgIHdhc2lfc25hcHNob3RfcHJldmlldzE6IHdhc2kud2FzaUltcG9ydAogICAgfTsKICAgIGlmIChzd2lmdCkgewogICAgICBpbXBvcnRPYmplY3QuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgaWYgKCFpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgaW1wb3J0RW50cnkgb2YgV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMobW9kdWxlMikpIHsKICAgICAgaWYgKCFpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXSkgewogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdID0ge307CiAgICAgIH0KICAgICAgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gImZ1bmN0aW9uIiAmJiAhaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGltcG9ydE9iamVjdDsKICB9OwogIHJldHVybiB7CiAgICBhc3luYyBydW4od2FzbUJ5dGVzLCBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGlmICghZXh0cmFXYXNtSW1wb3J0cykgewogICAgICAgIGV4dHJhV2FzbUltcG9ydHMgPSB7fTsKICAgICAgfQogICAgICBleHRyYVdhc21JbXBvcnRzLl9fc3RhY2tfc2FuaXRpemVyID0gewogICAgICAgIHJlcG9ydF9zdGFja19vdmVyZmxvdzogKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJEZXRlY3RlZCBzdGFjayBidWZmZXIgb3ZlcmZsb3cuIik7CiAgICAgICAgfQogICAgICB9OwogICAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkuY29tcGlsZSh3YXNtQnl0ZXMpOwogICAgICBjb25zdCBpbXBvcnRPYmplY3QgPSBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0KGV4dHJhV2FzbUltcG9ydHMsIG1vZHVsZTIpOwogICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKG1vZHVsZTIsIGltcG9ydE9iamVjdCk7CiAgICAgIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICAgICAgc3dpZnQuc2V0SW5zdGFuY2UoaW5zdGFuY2UpOwogICAgICB9CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLnN0YXJ0KGluc3RhbmNlKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgICAgICBpZiAoc3dpZnQgJiYgc3dpZnQubWFpbikgewogICAgICAgICAgc3dpZnQubWFpbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMubWFpbiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YoMCwgMCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKfTsKdmFyIGRlZmF1bHRSdW5uZXJPcHRpb25zID0gKG9wdGlvbnMpID0+IHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIHJldHVybiBvcHRpb25zOwp9OwoKLy8gZW50cnlwb2ludC90ZXN0Tm9kZS50cwp2YXIgYXJncyA9IFsuLi5wcm9jZXNzLmFyZ3ZdOwphcmdzLnNoaWZ0KCk7CmFyZ3Muc2hpZnQoKTsKdmFyIFt3YXNtRmlsZSwgLi4udGVzdEFyZ3NdID0gYXJnczsKdGVzdEFyZ3MudW5zaGlmdChpbXBvcnRfcGF0aC5kZWZhdWx0LmJhc2VuYW1lKHdhc21GaWxlKSk7CmlmICghd2FzbUZpbGUpIHsKICB0aHJvdyBFcnJvcigiTm8gV0FTTSB0ZXN0IGZpbGUgc3BlY2lmaWVkLCBjYW4gbm90IHJ1biB0ZXN0cyIpOwp9CnZhciBzdGFydFdhc2lUYXNrID0gYXN5bmMgKCkgPT4gewogIGNvbnN0IHdhc21CeXRlcyA9IGF3YWl0IGltcG9ydF9wcm9taXNlcy5kZWZhdWx0LnJlYWRGaWxlKHdhc21GaWxlKTsKICBsZXQgcnVudGltZUNvbnN0cnVjdG9yID0gdm9pZCAwOwogIHRyeSB7CiAgICBjb25zdCB7IFN3aWZ0UnVudGltZSB9ID0gYXdhaXQgaW1wb3J0KAogICAgICAvLyBAdHMtaWdub3JlCiAgICAgICIuL0phdmFTY3JpcHRLaXRfSmF2YVNjcmlwdEtpdC5yZXNvdXJjZXMvUnVudGltZS9pbmRleC5tanMiCiAgICApOwogICAgcnVudGltZUNvbnN0cnVjdG9yID0gU3dpZnRSdW50aW1lOwogICAgZ2xvYmFsLnJlcXVpcmUgPSByZXF1aXJlOwogIH0gY2F0Y2ggewogIH0KICBjb25zdCB3YXNtUnVubmVyID0gV2FzbVJ1bm5lcih7IGFyZ3M6IHRlc3RBcmdzIH0sIHJ1bnRpbWVDb25zdHJ1Y3Rvcik7CiAgbGV0IHByb2NFeGl0Q2FsbGVkID0gZmFsc2U7CiAgcHJvY2Vzcy5vbigiYmVmb3JlRXhpdCIsICgpID0+IHsKICAgIGlmICghcHJvY0V4aXRDYWxsZWQpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZXN0IGhhcm5lc3MgcHJvY2VzcyBleGl0ZWQgYmVmb3JlIHRlc3QgcHJvY2Vzcy4KVGhpcyB1c3VhbGx5IG1lYW5zIHRoZXJlIGFyZSBzb21lIGRhbmdsaW5nIGNvbnRpbnVhdGlvbnMsIHdoaWNoIGFyZSBhd2FpdGVkIGJ1dCBuZXZlciByZXN1bWVkLmApOwogICAgfQogIH0pOwogIGF3YWl0IHdhc21SdW5uZXIucnVuKHdhc21CeXRlcywgewogICAgIndhc2lfc25hcHNob3RfcHJldmlldzEiOiB7CiAgICAgIHByb2NfZXhpdDogKGNvZGUpID0+IHsKICAgICAgICBwcm9jRXhpdENhbGxlZCA9IHRydWU7CiAgICAgICAgcHJvY2Vzcy5leGl0KGNvZGUpOwogICAgICB9CiAgICB9CiAgfSk7Cn07CnN0YXJ0V2FzaVRhc2soKS5jYXRjaCgoZSkgPT4gewogIHRocm93IGU7Cn0pOwo=")! + public static let testNode: Data = Data(base64Encoded: "dmFyIF9fY3JlYXRlID0gT2JqZWN0LmNyZWF0ZTsKdmFyIF9fZGVmUHJvcCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTsKdmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOwp2YXIgX19nZXRPd25Qcm9wTmFtZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lczsKdmFyIF9fZ2V0UHJvdG9PZiA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjsKdmFyIF9faGFzT3duUHJvcCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7CnZhciBfX2NvcHlQcm9wcyA9ICh0bywgZnJvbSwgZXhjZXB0LCBkZXNjKSA9PiB7CiAgaWYgKGZyb20gJiYgdHlwZW9mIGZyb20gPT09ICJvYmplY3QiIHx8IHR5cGVvZiBmcm9tID09PSAiZnVuY3Rpb24iKSB7CiAgICBmb3IgKGxldCBrZXkgb2YgX19nZXRPd25Qcm9wTmFtZXMoZnJvbSkpCiAgICAgIGlmICghX19oYXNPd25Qcm9wLmNhbGwodG8sIGtleSkgJiYga2V5ICE9PSBleGNlcHQpCiAgICAgICAgX19kZWZQcm9wKHRvLCBrZXksIHsgZ2V0OiAoKSA9PiBmcm9tW2tleV0sIGVudW1lcmFibGU6ICEoZGVzYyA9IF9fZ2V0T3duUHJvcERlc2MoZnJvbSwga2V5KSkgfHwgZGVzYy5lbnVtZXJhYmxlIH0pOwogIH0KICByZXR1cm4gdG87Cn07CnZhciBfX3RvRVNNID0gKG1vZCwgaXNOb2RlTW9kZSwgdGFyZ2V0KSA9PiAodGFyZ2V0ID0gbW9kICE9IG51bGwgPyBfX2NyZWF0ZShfX2dldFByb3RvT2YobW9kKSkgOiB7fSwgX19jb3B5UHJvcHMoaXNOb2RlTW9kZSB8fCAhbW9kIHx8ICFtb2QuX19lc01vZHVsZSA/IF9fZGVmUHJvcCh0YXJnZXQsICJkZWZhdWx0IiwgeyB2YWx1ZTogbW9kLCBlbnVtZXJhYmxlOiB0cnVlIH0pIDogdGFyZ2V0LCBtb2QpKTsKCi8vIGVudHJ5cG9pbnQvdGVzdE5vZGUudHMKdmFyIGltcG9ydF9wcm9taXNlcyA9IF9fdG9FU00ocmVxdWlyZSgiZnMvcHJvbWlzZXMiKSk7CnZhciBpbXBvcnRfcGF0aCA9IF9fdG9FU00ocmVxdWlyZSgicGF0aCIpKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJnczIsIGVudiwgZmRzLCBvcHRpb25zID0ge30pIHsKICAgIHRoaXMuYXJncyA9IFtdOwogICAgdGhpcy5lbnYgPSBbXTsKICAgIHRoaXMuZmRzID0gW107CiAgICBkZWJ1Zy5lbmFibGUob3B0aW9ucy5kZWJ1Zyk7CiAgICB0aGlzLmFyZ3MgPSBhcmdzMjsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfZ2V0KGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aDIpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X3NldF90aW1lcyhmbGFncywgcGF0aDIsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgyKTsKICAgICAgICBjb25zdCB7IHJldCwgZmRfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoMiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aDIpOwogICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9yZWFkbGluayhwYXRoMik7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoMiA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZW5hbWUoZmQsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgbGV0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3VubGluayhvbGRfcGF0aCk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXQgPSBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKTsKICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgIGlmIChzZWxmLmZkc1tmZF0ucGF0aF9saW5rKG9sZF9wYXRoLCBpbm9kZV9vYmosIHRydWUpICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgdGhyb3cgInBhdGhfbGluayBzaG91bGQgYWx3YXlzIHJldHVybiBzdWNjZXNzIHdoZW4gcmVsaW5raW5nIGFuIGlub2RlIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHBsYWNlIjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9zeW1saW5rKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBmZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3VubGlua19maWxlKGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgyLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoMiwgaW5vZGUsIGFsbG93X2RpcikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF91bmxpbmsocGF0aDIpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aDIsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aDIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogIH0KICBwYXRoX3JlYWRsaW5rKHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KfTsKdmFyIElub2RlID0gY2xhc3Mgewp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mc19tZW0uanMKdmFyIE9wZW5GaWxlID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IG9mZnNldCArIGxlbikgewogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgbGVuKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgMCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gc2l6ZSkgewogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KHRoaXMuZmlsZS5kYXRhLmJ1ZmZlci5zbGljZSgwLCBOdW1iZXIoc2l6ZSkpKTsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHNpemUpKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKHRoaXMuZmlsZV9wb3MpLCBOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChzaXplKSkpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoc2xpY2UubGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcihvZmZzZXQpLCBOdW1iZXIob2Zmc2V0ICsgQmlnSW50KHNpemUpKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIGxldCBjYWxjdWxhdGVkX29mZnNldDsKICAgIHN3aXRjaCAod2hlbmNlKSB7CiAgICAgIGNhc2UgV0hFTkNFX1NFVDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfQ1VSOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gdGhpcy5maWxlX3BvcyArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfRU5EOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gQmlnSW50KHRoaXMuZmlsZS5kYXRhLmJ5dGVMZW5ndGgpICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIGlmIChjYWxjdWxhdGVkX29mZnNldCA8IDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgdGhpcy5maWxlX3BvcyA9IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmICh0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcih0aGlzLmZpbGVfcG9zKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmIChvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIob2Zmc2V0KSk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5maWxlLnN0YXQoKSB9OwogIH0KICBjb25zdHJ1Y3RvcihmaWxlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5maWxlX3BvcyA9IDBuOwogICAgdGhpcy5maWxlID0gZmlsZTsKICB9Cn07CnZhciBPcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgIGRlYnVnLmxvZygicmVhZGRpcl9zaW5nbGUiLCBjb29raWUpOwogICAgICBkZWJ1Zy5sb2coY29va2llLCB0aGlzLmRpci5jb250ZW50cy5rZXlzKCkpOwogICAgfQogICAgaWYgKGNvb2tpZSA9PSAwbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgxbiwgIi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9IGVsc2UgaWYgKGNvb2tpZSA9PSAxbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgybiwgIi4uIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfQogICAgaWYgKGNvb2tpZSA+PSBCaWdJbnQodGhpcy5kaXIuY29udGVudHMuc2l6ZSkgKyAybikgewogICAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbnVsbCB9OwogICAgfQogICAgY29uc3QgW25hbWUsIGVudHJ5XSA9IEFycmF5LmZyb20odGhpcy5kaXIuY29udGVudHMuZW50cmllcygpKVtOdW1iZXIoY29va2llIC0gMm4pXTsKICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBuZXcgRGlyZW50KGNvb2tpZSArIDFuLCBuYW1lLCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUpIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfZXJyLCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiBlbnRyeS5zdGF0KCkgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aF9zdHIsIGRpcmZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aF9zdHIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIGlmIChyZXQgIT0gRVJSTk9fTk9FTlQpIHsKICAgICAgICByZXR1cm4geyByZXQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0NSRUFUKSA9PSBPRkxBR1NfQ1JFQVQpIHsKICAgICAgICBjb25zdCB7IHJldDogcmV0MiwgZW50cnk6IG5ld19lbnRyeSB9ID0gdGhpcy5kaXIuY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCAob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSk7CiAgICAgICAgaWYgKG5ld19lbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4geyByZXQ6IHJldDIsIGZkX29iajogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBlbnRyeSA9IG5ld19lbnRyeTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgfSBlbHNlIGlmICgob2ZsYWdzICYgT0ZMQUdTX0VYQ0wpID09IE9GTEFHU19FWENMKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiBlbnRyeS5wYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpOwogIH0KICBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoMiwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoMi5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aDIsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICBjb25zdCBzb3VyY2VfaXNfZGlyID0gaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgY29uc3QgdGFyZ2V0X2lzX2RpciA9IGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGlmIChzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICBpZiAoYWxsb3dfZGlyICYmIGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB7CiAgICAgICAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSA9PSAwKSB7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoc291cmNlX2lzX2RpciAmJiAhdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICAgIH0gZWxzZSBpZiAoIXNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgICAgfSBlbHNlIGlmIChpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUpIHsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgIH0KICAgIH0KICAgIGlmICghYWxsb3dfZGlyICYmIGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX1BFUk07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBpbm9kZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF91bmxpbmsocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmICghKGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB8fCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgfQogICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgIT09IDApIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgfQogICAgaWYgKCFwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKSkgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5kaXIuc3RhdCgpIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgY29uc3RydWN0b3IoZGlyKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kaXIgPSBkaXI7CiAgfQp9Owp2YXIgUHJlb3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgT3BlbkRpcmVjdG9yeSB7CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIHByZXN0YXQ6IFByZXN0YXQuZGlyKHRoaXMucHJlc3RhdF9uYW1lKSB9OwogIH0KICBjb25zdHJ1Y3RvcihuYW1lLCBjb250ZW50cykgewogICAgc3VwZXIobmV3IERpcmVjdG9yeShjb250ZW50cykpOwogICAgdGhpcy5wcmVzdGF0X25hbWUgPSBuYW1lOwogIH0KfTsKdmFyIEZpbGUgPSBjbGFzcyBleHRlbmRzIElub2RlIHsKICBwYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpIHsKICAgIGlmICh0aGlzLnJlYWRvbmx5ICYmIChmc19yaWdodHNfYmFzZSAmIEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSA9PSBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfVFJVTkMpID09IE9GTEFHU19UUlVOQykgewogICAgICBpZiAodGhpcy5yZWFkb25seSkKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShbXSk7CiAgICB9CiAgICBjb25zdCBmaWxlID0gbmV3IE9wZW5GaWxlKHRoaXMpOwogICAgaWYgKGZkX2ZsYWdzICYgRkRGTEFHU19BUFBFTkQpCiAgICAgIGZpbGUuZmRfc2VlaygwbiwgV0hFTkNFX0VORCk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogZmlsZSB9OwogIH0KICBnZXQgc2l6ZSgpIHsKICAgIHJldHVybiBCaWdJbnQodGhpcy5kYXRhLmJ5dGVMZW5ndGgpOwogIH0KICBzdGF0KCkgewogICAgcmV0dXJuIG5ldyBGaWxlc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIHRoaXMuc2l6ZSk7CiAgfQogIGNvbnN0cnVjdG9yKGRhdGEsIG9wdGlvbnMpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShkYXRhKTsKICAgIHRoaXMucmVhZG9ubHkgPSAhIW9wdGlvbnM/LnJlYWRvbmx5OwogIH0KfTsKdmFyIFBhdGggPSBjbGFzcyBQYXRoMiB7CiAgc3RhdGljIGZyb20ocGF0aDIpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aDIuZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoMi5zdGFydHNXaXRoKCIvIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICB9CiAgICBpZiAocGF0aDIuaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aDIuc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aDIpIHsKICAgIGxldCBlbnRyeSA9IHRoaXM7CiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiBwYXRoMi5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgYWxsb3dfdW5kZWZpbmVkKSB7CiAgICBjb25zdCBmaWxlbmFtZSA9IHBhdGgyLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH07CiAgfQogIGNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgaXNfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBkZWJ1Zy5sb2coImNyZWF0ZSIsIHBhdGgyKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gZW50cnlwb2ludC9jb21tb24udHMKdmFyIExpbmVEZWNvZGVyID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG9uTGluZSkgewogICAgdGhpcy5kZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIsIHsgZmF0YWw6IGZhbHNlIH0pOwogICAgdGhpcy5idWZmZXIgPSAiIjsKICAgIHRoaXMub25MaW5lID0gb25MaW5lOwogIH0KICBkZWNvZGVyOwogIGJ1ZmZlcjsKICBvbkxpbmU7CiAgc2VuZChjaHVuaykgewogICAgdGhpcy5idWZmZXIgKz0gdGhpcy5kZWNvZGVyLmRlY29kZShjaHVuaywgeyBzdHJlYW06IHRydWUgfSk7CiAgICBjb25zdCBsaW5lcyA9IHRoaXMuYnVmZmVyLnNwbGl0KCJcbiIpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGggLSAxOyBpKyspIHsKICAgICAgdGhpcy5vbkxpbmUobGluZXNbaV0pOwogICAgfQogICAgdGhpcy5idWZmZXIgPSBsaW5lc1tsaW5lcy5sZW5ndGggLSAxXTsKICB9Cn07CnZhciBXYXNtUnVubmVyID0gKHJhd09wdGlvbnMsIFN3aWZ0UnVudGltZSkgPT4gewogIGNvbnN0IG9wdGlvbnMgPSBkZWZhdWx0UnVubmVyT3B0aW9ucyhyYXdPcHRpb25zKTsKICBsZXQgc3dpZnQ7CiAgaWYgKFN3aWZ0UnVudGltZSkgewogICAgc3dpZnQgPSBuZXcgU3dpZnRSdW50aW1lKCk7CiAgfQogIGxldCBzdGRvdXRMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3Rkb3V0TGluZSAhPSBudWxsKSB7CiAgICBzdGRvdXRMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRvdXRMaW5lKTsKICB9CiAgY29uc3Qgc3Rkb3V0ID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3Rkb3V0Py5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3Rkb3V0TGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgbGV0IHN0ZGVyckxpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRlcnJMaW5lICE9IG51bGwpIHsKICAgIHN0ZGVyckxpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZGVyckxpbmUpOwogIH0KICBjb25zdCBzdGRlcnIgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRlcnI/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRlcnJMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBjb25zdCBhcmdzMiA9IG9wdGlvbnMuYXJncyB8fCBbXTsKICBjb25zdCBmZHMgPSBbCiAgICBuZXcgT3BlbkZpbGUobmV3IEZpbGUoW10pKSwKICAgIHN0ZG91dCwKICAgIHN0ZGVyciwKICAgIG5ldyBQcmVvcGVuRGlyZWN0b3J5KCIvIiwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSkKICBdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzMiwgW10sIGZkcywgewogICAgZGVidWc6IGZhbHNlCiAgfSk7CiAgY29uc3QgY3JlYXRlV2FzbUltcG9ydE9iamVjdCA9IChleHRyYVdhc21JbXBvcnRzLCBtb2R1bGUyKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QgPSB7CiAgICAgIHdhc2lfc25hcHNob3RfcHJldmlldzE6IHdhc2kud2FzaUltcG9ydAogICAgfTsKICAgIGlmIChzd2lmdCkgewogICAgICBpbXBvcnRPYmplY3QuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgaWYgKCFpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgaW1wb3J0RW50cnkgb2YgV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMobW9kdWxlMikpIHsKICAgICAgaWYgKCFpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXSkgewogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdID0ge307CiAgICAgIH0KICAgICAgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gImZ1bmN0aW9uIiAmJiAhaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGltcG9ydE9iamVjdDsKICB9OwogIHJldHVybiB7CiAgICBhc3luYyBydW4od2FzbUJ5dGVzLCBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGlmICghZXh0cmFXYXNtSW1wb3J0cykgewogICAgICAgIGV4dHJhV2FzbUltcG9ydHMgPSB7fTsKICAgICAgfQogICAgICBleHRyYVdhc21JbXBvcnRzLl9fc3RhY2tfc2FuaXRpemVyID0gewogICAgICAgIHJlcG9ydF9zdGFja19vdmVyZmxvdzogKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJEZXRlY3RlZCBzdGFjayBidWZmZXIgb3ZlcmZsb3cuIik7CiAgICAgICAgfQogICAgICB9OwogICAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkuY29tcGlsZSh3YXNtQnl0ZXMpOwogICAgICBjb25zdCBpbXBvcnRPYmplY3QgPSBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0KGV4dHJhV2FzbUltcG9ydHMsIG1vZHVsZTIpOwogICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKG1vZHVsZTIsIGltcG9ydE9iamVjdCk7CiAgICAgIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICAgICAgc3dpZnQuc2V0SW5zdGFuY2UoaW5zdGFuY2UpOwogICAgICB9CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLnN0YXJ0KGluc3RhbmNlKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgICAgICBpZiAoc3dpZnQgJiYgc3dpZnQubWFpbikgewogICAgICAgICAgc3dpZnQubWFpbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMubWFpbiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YoMCwgMCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKfTsKdmFyIGRlZmF1bHRSdW5uZXJPcHRpb25zID0gKG9wdGlvbnMpID0+IHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIHJldHVybiBvcHRpb25zOwp9OwoKLy8gZW50cnlwb2ludC90ZXN0Tm9kZS50cwp2YXIgYXJncyA9IFsuLi5wcm9jZXNzLmFyZ3ZdOwphcmdzLnNoaWZ0KCk7CmFyZ3Muc2hpZnQoKTsKdmFyIFt3YXNtRmlsZSwgLi4udGVzdEFyZ3NdID0gYXJnczsKdGVzdEFyZ3MudW5zaGlmdChpbXBvcnRfcGF0aC5kZWZhdWx0LmJhc2VuYW1lKHdhc21GaWxlKSk7CmlmICghd2FzbUZpbGUpIHsKICB0aHJvdyBFcnJvcigiTm8gV0FTTSB0ZXN0IGZpbGUgc3BlY2lmaWVkLCBjYW4gbm90IHJ1biB0ZXN0cyIpOwp9CnZhciBzdGFydFdhc2lUYXNrID0gYXN5bmMgKCkgPT4gewogIGNvbnN0IHdhc21CeXRlcyA9IGF3YWl0IGltcG9ydF9wcm9taXNlcy5kZWZhdWx0LnJlYWRGaWxlKHdhc21GaWxlKTsKICBsZXQgcnVudGltZUNvbnN0cnVjdG9yID0gdm9pZCAwOwogIHRyeSB7CiAgICBjb25zdCB7IFN3aWZ0UnVudGltZSB9ID0gYXdhaXQgaW1wb3J0KAogICAgICAvLyBAdHMtaWdub3JlCiAgICAgICIuL0phdmFTY3JpcHRLaXRfSmF2YVNjcmlwdEtpdC5yZXNvdXJjZXMvUnVudGltZS9pbmRleC5tanMiCiAgICApOwogICAgcnVudGltZUNvbnN0cnVjdG9yID0gU3dpZnRSdW50aW1lOwogICAgZ2xvYmFsLnJlcXVpcmUgPSByZXF1aXJlOwogIH0gY2F0Y2ggewogIH0KICBjb25zdCB3YXNtUnVubmVyID0gV2FzbVJ1bm5lcih7CiAgICBhcmdzOiB0ZXN0QXJncywKICAgIG9uU3Rkb3V0TGluZTogKGxpbmUpID0+IHsKICAgICAgY29uc29sZS5sb2cobGluZSk7CiAgICB9LAogICAgb25TdGRlcnJMaW5lOiAobGluZSkgPT4gewogICAgICBjb25zb2xlLmVycm9yKGxpbmUpOwogICAgfQogIH0sIHJ1bnRpbWVDb25zdHJ1Y3Rvcik7CiAgbGV0IHByb2NFeGl0Q2FsbGVkID0gZmFsc2U7CiAgcHJvY2Vzcy5vbigiYmVmb3JlRXhpdCIsICgpID0+IHsKICAgIGlmICghcHJvY0V4aXRDYWxsZWQpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZXN0IGhhcm5lc3MgcHJvY2VzcyBleGl0ZWQgYmVmb3JlIHRlc3QgcHJvY2Vzcy4KVGhpcyB1c3VhbGx5IG1lYW5zIHRoZXJlIGFyZSBzb21lIGRhbmdsaW5nIGNvbnRpbnVhdGlvbnMsIHdoaWNoIGFyZSBhd2FpdGVkIGJ1dCBuZXZlciByZXN1bWVkLmApOwogICAgfQogIH0pOwogIGF3YWl0IHdhc21SdW5uZXIucnVuKHdhc21CeXRlcywgewogICAgIndhc2lfc25hcHNob3RfcHJldmlldzEiOiB7CiAgICAgIHByb2NfZXhpdDogKGNvZGUpID0+IHsKICAgICAgICBwcm9jRXhpdENhbGxlZCA9IHRydWU7CiAgICAgICAgcHJvY2Vzcy5leGl0KGNvZGUpOwogICAgICB9CiAgICB9CiAgfSk7Cn07CnN0YXJ0V2FzaVRhc2soKS5jYXRjaCgoZSkgPT4gewogIHRocm93IGU7Cn0pOwo=")! } \ No newline at end of file diff --git a/Tests/CartonCommandTests/TestCommandTests.swift b/Tests/CartonCommandTests/TestCommandTests.swift index c1199c03..f254ac9d 100644 --- a/Tests/CartonCommandTests/TestCommandTests.swift +++ b/Tests/CartonCommandTests/TestCommandTests.swift @@ -43,6 +43,11 @@ final class TestCommandTests: XCTestCase { ["carton", "test", "--environment", "node"], packageDirectory: packageDirectory.asURL ) try result.checkNonZeroExit() + let stdout = try result.utf8Output() + let stderr = try result.utf8stderrOutput() + let expectedContent = "Test Suite 'All tests' passed" + // SwiftPM changed the output destination of SwiftPM Plugin in 6.0 + XCTAssertTrue(stdout.contains(expectedContent) || stderr.contains(expectedContent)) } } diff --git a/entrypoint/testNode.ts b/entrypoint/testNode.ts index 6451c1f1..dc727676 100644 --- a/entrypoint/testNode.ts +++ b/entrypoint/testNode.ts @@ -46,7 +46,15 @@ const startWasiTask = async () => { // No JavaScriptKit module found, run the Wasm module without JSKit } - const wasmRunner = WasmRunner({ args: testArgs }, runtimeConstructor); + const wasmRunner = WasmRunner({ + args: testArgs, + onStdoutLine: (line) => { + console.log(line); + }, + onStderrLine: (line) => { + console.error(line); + }, + }, runtimeConstructor); let procExitCalled = false; process.on("beforeExit", () => {