From 5f35b2ce4d36087b7de1d80b3742cebccaab4d91 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 17 Nov 2024 08:43:11 +0900 Subject: [PATCH 1/2] Don't overwrite global `WebAssembly` object --- Sources/CartonHelpers/StaticArchive.swift | 8 ++++---- entrypoint/common.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/CartonHelpers/StaticArchive.swift b/Sources/CartonHelpers/StaticArchive.swift index 816cda8c..4886c65c 100644 --- a/Sources/CartonHelpers/StaticArchive.swift +++ b/Sources/CartonHelpers/StaticArchive.swift @@ -1,9 +1,9 @@ import Foundation 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+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcihvZmZzZXQpKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmZpbGUuc3RhdCgpIH07CiAgfQogIGNvbnN0cnVjdG9yKGZpbGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmZpbGVfcG9zID0gMG47CiAgICB0aGlzLmZpbGUgPSBmaWxlOwogIH0KfTsKdmFyIE9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9ESVJFQ1RPUlksIDApIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgZGVidWcubG9nKCJyZWFkZGlyX3NpbmdsZSIsIGNvb2tpZSk7CiAgICAgIGRlYnVnLmxvZyhjb29raWUsIHRoaXMuZGlyLmNvbnRlbnRzLmtleXMoKSk7CiAgICB9CiAgICBpZiAoY29va2llID09IDBuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDFuLCAiLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0gZWxzZSBpZiAoY29va2llID09IDFuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDJuLCAiLi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9CiAgICBpZiAoY29va2llID49IEJpZ0ludCh0aGlzLmRpci5jb250ZW50cy5zaXplKSArIDJuKSB7CiAgICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBbbmFtZSwgZW50cnldID0gQXJyYXkuZnJvbSh0aGlzLmRpci5jb250ZW50cy5lbnRyaWVzKCkpW051bWJlcihjb29raWUgLSAybildOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG5ldyBEaXJlbnQoY29va2llICsgMW4sIG5hbWUsIGVudHJ5LnN0YXQoKS5maWxldHlwZSkgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9lcnIsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IGVudHJ5LnN0YXQoKSB9OwogIH0KICBwYXRoX2xvb2t1cChwYXRoX3N0ciwgZGlyZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoX3N0ciwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgaWYgKHJldCAhPSBFUlJOT19OT0VOVCkgewogICAgICAgIHJldHVybiB7IHJldCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfQ1JFQVQpID09IE9GTEFHU19DUkVBVCkgewogICAgICAgIGNvbnN0IHsgcmV0OiByZXQyLCBlbnRyeTogbmV3X2VudHJ5IH0gPSB0aGlzLmRpci5jcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZKTsKICAgICAgICBpZiAobmV3X2VudHJ5ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiB7IHJldDogcmV0MiwgZmRfb2JqOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGVudHJ5ID0gbmV3X2VudHJ5OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICB9IGVsc2UgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRVhDTCkgPT0gT0ZMQUdTX0VYQ0wpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIGVudHJ5LnBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncyk7CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gdGhpcy5wYXRoX29wZW4oMCwgcGF0aCwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIGNvbnN0IHNvdXJjZV9pc19kaXIgPSBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBjb25zdCB0YXJnZXRfaXNfZGlyID0gZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgaWYgKHNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIGlmIChhbGxvd19kaXIgJiYgZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHsKICAgICAgICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplID09IDApIHsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChzb3VyY2VfaXNfZGlyICYmICF0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgICAgfSBlbHNlIGlmICghc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgICB9IGVsc2UgaWYgKGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSkgewogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgfQogICAgfQogICAgaWYgKCFhbGxvd19kaXIgJiYgaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fUEVSTTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIGlub2RlKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3VubGluayhwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF91bmxpbmtfZmlsZShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHx8IGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICB9CiAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSAhPT0gMCkgewogICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICB9CiAgICBpZiAoIXBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpKSB7CiAgICAgIHJldHVybiBFUlJOT19OT0VOVDsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmRpci5zdGF0KCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBjb25zdHJ1Y3RvcihkaXIpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRpciA9IGRpcjsKICB9Cn07CnZhciBQcmVvcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBPcGVuRGlyZWN0b3J5IHsKICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgcHJlc3RhdDogUHJlc3RhdC5kaXIodGhpcy5wcmVzdGF0X25hbWUpIH07CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnRzKSB7CiAgICBzdXBlcihuZXcgRGlyZWN0b3J5KGNvbnRlbnRzKSk7CiAgICB0aGlzLnByZXN0YXRfbmFtZSA9IG5hbWU7CiAgfQp9Owp2YXIgRmlsZSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgaWYgKHRoaXMucmVhZG9ubHkgJiYgKGZzX3JpZ2h0c19iYXNlICYgQmlnSW50KFJJR0hUU19GRF9XUklURSkpID09IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19UUlVOQykgPT0gT0ZMQUdTX1RSVU5DKSB7CiAgICAgIGlmICh0aGlzLnJlYWRvbmx5KQogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KFtdKTsKICAgIH0KICAgIGNvbnN0IGZpbGUgPSBuZXcgT3BlbkZpbGUodGhpcyk7CiAgICBpZiAoZmRfZmxhZ3MgJiBGREZMQUdTX0FQUEVORCkKICAgICAgZmlsZS5mZF9zZWVrKDBuLCBXSEVOQ0VfRU5EKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZmRfb2JqOiBmaWxlIH07CiAgfQogIGdldCBzaXplKCkgewogICAgcmV0dXJuIEJpZ0ludCh0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgdGhpcy5zaXplKTsKICB9CiAgY29uc3RydWN0b3IoZGF0YSwgb3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgdGhpcy5yZWFkb25seSA9ICEhb3B0aW9ucz8ucmVhZG9ubHk7CiAgfQp9Owp2YXIgUGF0aCA9IGNsYXNzIFBhdGgyIHsKICBzdGF0aWMgZnJvbShwYXRoKSB7CiAgICBjb25zdCBzZWxmID0gbmV3IFBhdGgyKCk7CiAgICBzZWxmLmlzX2RpciA9IHBhdGguZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVENBUEFCTEUsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGlmIChwYXRoLmluY2x1ZGVzKCJcMCIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGguc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aCkgewogICAgbGV0IGVudHJ5ID0gdGhpczsKICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgucGFydHMpIHsKICAgICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgICAgY29uc3QgY2hpbGQgPSBlbnRyeS5jb250ZW50cy5nZXQoY29tcG9uZW50KTsKICAgICAgaWYgKGNoaWxkICE9PSB2b2lkIDApIHsKICAgICAgICBlbnRyeSA9IGNoaWxkOwogICAgICB9IGVsc2UgewogICAgICAgIGRlYnVnLmxvZyhjb21wb25lbnQpOwogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBhbGxvd191bmRlZmluZWQpIHsKICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5wYXJ0cy5wb3AoKTsKICAgIGlmIChmaWxlbmFtZSA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldDogZW50cnlfcmV0LCBlbnRyeTogcGFyZW50X2VudHJ5IH0gPSB0aGlzLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfTsKICB9CiAgY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCBpc19kaXIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGRlYnVnLmxvZygiY3JlYXRlIiwgcGF0aCk7CiAgICBsZXQgbmV3X2NoaWxkOwogICAgaWYgKCFpc19kaXIpIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IEZpbGUobmV3IEFycmF5QnVmZmVyKDApKTsKICAgIH0gZWxzZSB7CiAgICAgIG5ld19jaGlsZCA9IG5ldyBEaXJlY3RvcnkoLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSk7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBuZXdfY2hpbGQpOwogICAgZW50cnkgPSBuZXdfY2hpbGQ7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGNvbnN0cnVjdG9yKGNvbnRlbnRzKSB7CiAgICBzdXBlcigpOwogICAgaWYgKGNvbnRlbnRzIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgdGhpcy5jb250ZW50cyA9IG5ldyBNYXAoY29udGVudHMpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5jb250ZW50cyA9IGNvbnRlbnRzOwogICAgfQogIH0KfTsKdmFyIENvbnNvbGVTdGRvdXQgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmaWxlc3RhdCA9IG5ldyBGaWxlc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCBCaWdJbnQoMCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdCB9OwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgY29uc3QgZmRzdGF0ID0gbmV3IEZkc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCAwKTsKICAgIGZkc3RhdC5mc19yaWdodHNfYmFzZSA9IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgdGhpcy53cml0ZShkYXRhKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBzdGF0aWMgbGluZUJ1ZmZlcmVkKHdyaXRlKSB7CiAgICBjb25zdCBkZWMgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICBsZXQgbGluZV9idWYgPSAiIjsKICAgIHJldHVybiBuZXcgQ29uc29sZVN0ZG91dCgoYnVmZmVyKSA9PiB7CiAgICAgIGxpbmVfYnVmICs9IGRlYy5kZWNvZGUoYnVmZmVyLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgICAgY29uc3QgbGluZXMgPSBsaW5lX2J1Zi5zcGxpdCgiXG4iKTsKICAgICAgZm9yIChjb25zdCBbaSwgbGluZV0gb2YgbGluZXMuZW50cmllcygpKSB7CiAgICAgICAgaWYgKGkgPCBsaW5lcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICB3cml0ZShsaW5lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGluZV9idWYgPSBsaW5lOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfQogIGNvbnN0cnVjdG9yKHdyaXRlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy53cml0ZSA9IHdyaXRlOwogIH0KfTsKCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL2luZGV4LmpzCmZ1bmN0aW9uIHBhcnNlSW1wb3J0cyhtb2R1bGVCeXRlcykgewogIGlmIChtb2R1bGVCeXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsKICB9IGVsc2UgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMpOwogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMuYnVmZmVyKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCJBcmd1bWVudCBtdXN0IGJlIGEgYnVmZmVyIHNvdXJjZSwgbGlrZSBVaW50OEFycmF5IG9yIEFycmF5QnVmZmVyIik7CiAgfQogIGNvbnN0IHBhcnNlU3RhdGUgPSBuZXcgUGFyc2VTdGF0ZShtb2R1bGVCeXRlcyk7CiAgcGFyc2VNYWdpY051bWJlcihwYXJzZVN0YXRlKTsKICBwYXJzZVZlcnNpb24ocGFyc2VTdGF0ZSk7CiAgY29uc3QgdHlwZXMgPSBbXTsKICBjb25zdCBpbXBvcnRzID0gW107CiAgd2hpbGUgKHBhcnNlU3RhdGUuaGFzTW9yZUJ5dGVzKCkpIHsKICAgIGNvbnN0IHNlY3Rpb25JZCA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICAgIGNvbnN0IHNlY3Rpb25TaXplID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgIHN3aXRjaCAoc2VjdGlvbklkKSB7CiAgICAgIGNhc2UgMTogewogICAgICAgIGNvbnN0IHR5cGVDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eXBlQ291bnQ7IGkrKykgewogICAgICAgICAgdHlwZXMucHVzaChwYXJzZUZ1bmN0aW9uVHlwZShwYXJzZVN0YXRlKSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgMjogewogICAgICAgIGNvbnN0IGltcG9ydENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGltcG9ydENvdW50OyBpKyspIHsKICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobW9kdWxlQnl0ZXMpOwogIGNvbnN0IGltcG9ydHMgPSBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpOwogIGNvbnN0IG1lbW9yeUltcG9ydCA9IGltcG9ydHNbMF07CiAgcmV0dXJuIHR5cGVvZiBtZW1vcnlJbXBvcnQudHlwZSA9PT0gIm9iamVjdCI7Cn0pKCk7CmZ1bmN0aW9uIHBvbHlmaWxsKFdlYkFzc2VtYmx5MikgewogIGlmIChoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0KSB7CiAgICByZXR1cm4gV2ViQXNzZW1ibHkyOwogIH0KICBjb25zdCBuZXdXZWJBc3NlbWJseSA9IHt9OwogIGZvciAoY29uc3Qga2V5IGluIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKFdlYkFzc2VtYmx5MikpIHsKICAgIG5ld1dlYkFzc2VtYmx5W2tleV0gPSBXZWJBc3NlbWJseTJba2V5XTsKICB9CiAgY29uc3QgcG9seWZpbGxlZEltcG9ydHNTeW1ib2wgPSBTeW1ib2woInBvbHlmaWxsZWRJbXBvcnRzU3ltYm9sIik7CiAgY29uc3QgYXNzaWduSW1wb3J0cyA9IChtb2R1bGUsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdID0gcGFyc2VJbXBvcnRzKHNvdXJjZUJ5dGVzKTsKICB9OwogIGNvbnN0IG5ld01vZHVsZSA9IG5ld1dlYkFzc2VtYmx5Lk1vZHVsZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICBjb25zdCBtb2R1bGUgPSBuZXcgV2ViQXNzZW1ibHkyLk1vZHVsZShieXRlcyk7CiAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZSwgbmV3TW9kdWxlLnByb3RvdHlwZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG5ld01vZHVsZS5wcm90b3R5cGUsIFdlYkFzc2VtYmx5Mi5Nb2R1bGUucHJvdG90eXBlKTsKICBuZXdXZWJBc3NlbWJseS5jb21waWxlID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkyLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBzb3VyY2UpOwogICAgcmV0dXJuIG1vZHVsZTsKICB9OwogIGlmIChXZWJBc3NlbWJseTIuY29tcGlsZVN0cmVhbWluZykgewogICAgbmV3V2ViQXNzZW1ibHkuY29tcGlsZVN0cmVhbWluZyA9IGFzeW5jIChzb3VyY2UpID0+IHsKICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzb3VyY2U7CiAgICAgIGNvbnN0IGNsb25lID0gcmVzcG9uc2UuY2xvbmUoKTsKICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkyLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgbmV3IFVpbnQ4QXJyYXkoYXdhaXQgY2xvbmUuYXJyYXlCdWZmZXIoKSkpOwogICAgICByZXR1cm4gbW9kdWxlOwogICAgfTsKICB9CiAgbmV3TW9kdWxlLmltcG9ydHMgPSAobW9kdWxlKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXTsKICAgIGlmICghcGFyc2VkSW1wb3J0cykgewogICAgICByZXR1cm4gV2ViQXNzZW1ibHkyLk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgICB9CiAgICByZXR1cm4gcGFyc2VkSW1wb3J0czsKICB9OwogIHJldHVybiBuZXdXZWJBc3NlbWJseTsKfQoKLy8gZW50cnlwb2ludC9jb21tb24udHMKZ2xvYmFsVGhpcy5XZWJBc3NlbWJseSA9IHBvbHlmaWxsKGdsb2JhbFRoaXMuV2ViQXNzZW1ibHkpOwp2YXIgTGluZURlY29kZXIgPSBjbGFzcyB7CiAgY29uc3RydWN0b3Iob25MaW5lKSB7CiAgICB0aGlzLmRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICB0aGlzLmJ1ZmZlciA9ICIiOwogICAgdGhpcy5vbkxpbmUgPSBvbkxpbmU7CiAgfQogIGRlY29kZXI7CiAgYnVmZmVyOwogIG9uTGluZTsKICBzZW5kKGNodW5rKSB7CiAgICB0aGlzLmJ1ZmZlciArPSB0aGlzLmRlY29kZXIuZGVjb2RlKGNodW5rLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgIGNvbnN0IGxpbmVzID0gdGhpcy5idWZmZXIuc3BsaXQoIlxuIik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykgewogICAgICB0aGlzLm9uTGluZShsaW5lc1tpXSk7CiAgICB9CiAgICB0aGlzLmJ1ZmZlciA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdOwogIH0KfTsKdmFyIFdhc21SdW5uZXIgPSAocmF3T3B0aW9ucywgU3dpZnRSdW50aW1lKSA9PiB7CiAgY29uc3Qgb3B0aW9ucyA9IGRlZmF1bHRSdW5uZXJPcHRpb25zKHJhd09wdGlvbnMpOwogIGxldCBzd2lmdDsKICBpZiAoU3dpZnRSdW50aW1lKSB7CiAgICBzd2lmdCA9IG5ldyBTd2lmdFJ1bnRpbWUoKTsKICB9CiAgbGV0IHN0ZG91dExpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRvdXRMaW5lICE9IG51bGwpIHsKICAgIHN0ZG91dExpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZG91dExpbmUpOwogIH0KICBjb25zdCBzdGRvdXQgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRvdXQ/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRvdXRMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBsZXQgc3RkZXJyTGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZGVyckxpbmUgIT0gbnVsbCkgewogICAgc3RkZXJyTGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3RkZXJyTGluZSk7CiAgfQogIGNvbnN0IHN0ZGVyciA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZGVycj8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZGVyckxpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGNvbnN0IGFyZ3MgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzLCBlbnZzLCBmZHMsIHsKICAgIGRlYnVnOiBmYWxzZQogIH0pOwogIGNvbnN0IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QgPSAoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QgPSB7CiAgICAgIHdhc2lfc25hcHNob3RfcHJldmlldzE6IHdhc2kud2FzaUltcG9ydAogICAgfTsKICAgIGlmIChzd2lmdCkgewogICAgICBpbXBvcnRPYmplY3QuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgaWYgKCFpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgX2ltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKG1vZHVsZSkpIHsKICAgICAgY29uc3QgaW1wb3J0RW50cnkgPSBfaW1wb3J0RW50cnk7CiAgICAgIGlmICghaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXSA9IHt9OwogICAgICB9CiAgICAgIGlmIChpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSkgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJmdW5jdGlvbiIpIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfSBlbHNlIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJtZW1vcnkiICYmIGltcG9ydEVudHJ5Lm1vZHVsZSA9PSAiZW52IiAmJiBpbXBvcnRFbnRyeS5uYW1lID09ICJtZW1vcnkiKSB7CiAgICAgICAgY29uc3QgdHlwZSA9IGltcG9ydEVudHJ5LnR5cGU7CiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsKICAgICAgICAgIGluaXRpYWw6IHR5cGUubWluaW11bSwKICAgICAgICAgIG1heGltdW06IHR5cGUubWF4aW11bSwKICAgICAgICAgIHNoYXJlZDogdHlwZS5zaGFyZWQKICAgICAgICB9OwogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gbmV3IFdlYkFzc2VtYmx5Lk1lbW9yeShkZXNjcmlwdG9yKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGltcG9ydE9iamVjdDsKICB9OwogIHJldHVybiB7CiAgICBhc3luYyBydW4od2FzbUJ5dGVzLCBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGlmICghZXh0cmFXYXNtSW1wb3J0cykgewogICAgICAgIGV4dHJhV2FzbUltcG9ydHMgPSB7fTsKICAgICAgfQogICAgICBleHRyYVdhc21JbXBvcnRzLl9fc3RhY2tfc2FuaXRpemVyID0gewogICAgICAgIHJlcG9ydF9zdGFja19vdmVyZmxvdzogKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJEZXRlY3RlZCBzdGFjayBidWZmZXIgb3ZlcmZsb3cuIik7CiAgICAgICAgfQogICAgICB9OwogICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseS5jb21waWxlKHdhc21CeXRlcyk7CiAgICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKTsKICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShtb2R1bGUsIGltcG9ydE9iamVjdCk7CiAgICAgIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICAgICAgc3dpZnQuc2V0SW5zdGFuY2UoaW5zdGFuY2UpOwogICAgICB9CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLnN0YXJ0KGluc3RhbmNlKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgICAgICBpZiAoc3dpZnQgJiYgc3dpZnQubWFpbikgewogICAgICAgICAgc3dpZnQubWFpbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMubWFpbiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YoMCwgMCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKfTsKdmFyIGRlZmF1bHRSdW5uZXJPcHRpb25zID0gKG9wdGlvbnMpID0+IHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIHJldHVybiBvcHRpb25zOwp9OwoKLy8gZW50cnlwb2ludC9kZXYudHMKdmFyIHNvY2tldCA9IG5ldyByZWNvbm5lY3Rpbmdfd2Vic29ja2V0X21qc19kZWZhdWx0KGB3czovLyR7bG9jYXRpb24uaG9zdH0vd2F0Y2hlcmApOwpzb2NrZXQuYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsIChtZXNzYWdlKSA9PiB7CiAgaWYgKG1lc3NhZ2UuZGF0YSA9PT0gInJlbG9hZCIpIHsKICAgIGxvY2F0aW9uLnJlbG9hZCgpOwogIH0KfSk7CnZhciBzdGFydFdhc2lUYXNrID0gYXN5bmMgKCkgPT4gewogIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goIi9tYWluLndhc20iKTsKICBjb25zdCByZXNwb25zZUFycmF5QnVmZmVyID0gYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKTsKICBsZXQgcnVudGltZUNvbnN0cnVjdG9yID0gdm9pZCAwOwogIHRyeSB7CiAgICBjb25zdCB7IFN3aWZ0UnVudGltZSB9ID0gYXdhaXQgaW1wb3J0KAogICAgICAvLyBAdHMtaWdub3JlCiAgICAgICIuL0phdmFTY3JpcHRLaXRfSmF2YVNjcmlwdEtpdC5yZXNvdXJjZXMvUnVudGltZS9pbmRleC5tanMiCiAgICApOwogICAgcnVudGltZUNvbnN0cnVjdG9yID0gU3dpZnRSdW50aW1lOwogIH0gY2F0Y2ggewogICAgY29uc29sZS5sb2coIkphdmFTY3JpcHRLaXQgbW9kdWxlIG5vdCBhdmFpbGFibGUsIHJ1bm5pbmcgd2l0aG91dCBKYXZhU2NyaXB0S2l0IHJ1bnRpbWUuIik7CiAgfQogIGNvbnN0IHdhc21SdW5uZXIgPSBXYXNtUnVubmVyKHsKICAgIG9uU3Rkb3V0KGNodW5rKSB7CiAgICAgIGNvbnN0IGtpbmRCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoMik7CiAgICAgIG5ldyBEYXRhVmlldyhraW5kQnVmZmVyKS5zZXRVaW50MTYoMCwgMTAwMSwgdHJ1ZSk7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDIgKyBjaHVuay5sZW5ndGgpOwogICAgICBidWZmZXIuc2V0KG5ldyBVaW50OEFycmF5KGtpbmRCdWZmZXIpLCAwKTsKICAgICAgYnVmZmVyLnNldChjaHVuaywgMik7CiAgICAgIHNvY2tldC5zZW5kKGJ1ZmZlcik7CiAgICB9LAogICAgb25TdGRvdXRMaW5lKGxpbmUpIHsKICAgICAgY29uc29sZS5sb2cobGluZSk7CiAgICB9LAogICAgb25TdGRlcnIoY2h1bmspIHsKICAgICAgY29uc3Qga2luZEJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcigyKTsKICAgICAgbmV3IERhdGFWaWV3KGtpbmRCdWZmZXIpLnNldFVpbnQxNigwLCAxMDAyLCB0cnVlKTsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoMiArIGNodW5rLmxlbmd0aCk7CiAgICAgIGJ1ZmZlci5zZXQobmV3IFVpbnQ4QXJyYXkoa2luZEJ1ZmZlciksIDApOwogICAgICBidWZmZXIuc2V0KGNodW5rLCAyKTsKICAgICAgc29ja2V0LnNlbmQoYnVmZmVyKTsKICAgIH0sCiAgICBvblN0ZGVyckxpbmUobGluZSkgewogICAgICBjb25zb2xlLmVycm9yKGxpbmUpOwogICAgfQogIH0sIHJ1bnRpbWVDb25zdHJ1Y3Rvcik7CiAgY29uc3Qgd2FzbUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkocmVzcG9uc2VBcnJheUJ1ZmZlcikuYnVmZmVyOwogIGF3YWl0IHdhc21SdW5uZXIucnVuKHdhc21CeXRlcyk7Cn07CmZ1bmN0aW9uIGhhbmRsZUVycm9yKGUpIHsKICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yKSB7CiAgICBjb25zdCBzdGFjayA9IGUuc3RhY2s7CiAgICBpZiAoc3RhY2sgIT0gbnVsbCkgewogICAgICBzb2NrZXQuc2VuZChKU09OLnN0cmluZ2lmeSh7CiAgICAgICAga2luZDogInN0YWNrVHJhY2UiLAogICAgICAgIHN0YWNrVHJhY2U6IHN0YWNrCiAgICAgIH0pKTsKICAgIH0KICB9Cn0KYXN5bmMgZnVuY3Rpb24gbWFpbigpIHsKICB0cnkgewogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgKGV2ZW50KSA9PiB7CiAgICAgIGhhbmRsZUVycm9yKGV2ZW50LmVycm9yKTsKICAgIH0pOwogICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoInVuaGFuZGxlZHJlamVjdGlvbiIsIChldmVudCkgPT4gewogICAgICBoYW5kbGVFcnJvcihldmVudC5yZWFzb24pOwogICAgfSk7CiAgICBhd2FpdCBzdGFydFdhc2lUYXNrKCk7CiAgfSBjYXRjaCAoZSkgewogICAgaGFuZGxlRXJyb3IoZSk7CiAgICB0aHJvdyBlOwogIH0KfQptYWluKCk7Ci8qIQogKiBSZWNvbm5lY3RpbmcgV2ViU29ja2V0CiAqIGJ5IFBlZHJvIExhZGFyaWEgPHBlZHJvLmxhZGFyaWFAZ21haWwuY29tPgogKiBodHRwczovL2dpdGh1Yi5jb20vcGxhZGFyaWEvcmVjb25uZWN0aW5nLXdlYnNvY2tldAogKiBMaWNlbnNlIE1JVAogKi8KLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgpMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlCnRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlCkxpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCgpUSElTIENPREUgSVMgUFJPVklERUQgT04gQU4gKkFTIElTKiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCktJTkQsIEVJVEhFUiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04gQU5ZIElNUExJRUQKV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIFRJVExFLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwKTUVSQ0hBTlRBQkxJVFkgT1IgTk9OLUlORlJJTkdFTUVOVC4KClNlZSB0aGUgQXBhY2hlIFZlcnNpb24gMi4wIExpY2Vuc2UgZm9yIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucwphbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCg==")! - public static let bundle: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpX2RlZnMuanMKdmFyIENMT0NLSURfUkVBTFRJTUUgPSAwOwp2YXIgQ0xPQ0tJRF9NT05PVE9OSUMgPSAxOwp2YXIgRVJSTk9fU1VDQ0VTUyA9IDA7CnZhciBFUlJOT19CQURGID0gODsKdmFyIEVSUk5PX0VYSVNUID0gMjA7CnZhciBFUlJOT19JTlZBTCA9IDI4Owp2YXIgRVJSTk9fSVNESVIgPSAzMTsKdmFyIEVSUk5PX05BTUVUT09MT05HID0gMzc7CnZhciBFUlJOT19OT0VOVCA9IDQ0Owp2YXIgRVJSTk9fTk9TWVMgPSA1MjsKdmFyIEVSUk5PX05PVERJUiA9IDU0Owp2YXIgRVJSTk9fTk9URU1QVFkgPSA1NTsKdmFyIEVSUk5PX05PVFNVUCA9IDU4Owp2YXIgRVJSTk9fUEVSTSA9IDYzOwp2YXIgRVJSTk9fTk9UQ0FQQUJMRSA9IDc2Owp2YXIgUklHSFRTX0ZEX0RBVEFTWU5DID0gMSA8PCAwOwp2YXIgUklHSFRTX0ZEX1JFQUQgPSAxIDw8IDE7CnZhciBSSUdIVFNfRkRfU0VFSyA9IDEgPDwgMjsKdmFyIFJJR0hUU19GRF9GRFNUQVRfU0VUX0ZMQUdTID0gMSA8PCAzOwp2YXIgUklHSFRTX0ZEX1NZTkMgPSAxIDw8IDQ7CnZhciBSSUdIVFNfRkRfVEVMTCA9IDEgPDwgNTsKdmFyIFJJR0hUU19GRF9XUklURSA9IDEgPDwgNjsKdmFyIFJJR0hUU19GRF9BRFZJU0UgPSAxIDw8IDc7CnZhciBSSUdIVFNfRkRfQUxMT0NBVEUgPSAxIDw8IDg7CnZhciBSSUdIVFNfUEFUSF9DUkVBVEVfRElSRUNUT1JZID0gMSA8PCA5Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0ZJTEUgPSAxIDw8IDEwOwp2YXIgUklHSFRTX1BBVEhfTElOS19TT1VSQ0UgPSAxIDw8IDExOwp2YXIgUklHSFRTX1BBVEhfTElOS19UQVJHRVQgPSAxIDw8IDEyOwp2YXIgUklHSFRTX1BBVEhfT1BFTiA9IDEgPDwgMTM7CnZhciBSSUdIVFNfRkRfUkVBRERJUiA9IDEgPDwgMTQ7CnZhciBSSUdIVFNfUEFUSF9SRUFETElOSyA9IDEgPDwgMTU7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfU09VUkNFID0gMSA8PCAxNjsKdmFyIFJJR0hUU19QQVRIX1JFTkFNRV9UQVJHRVQgPSAxIDw8IDE3Owp2YXIgUklHSFRTX1BBVEhfRklMRVNUQVRfR0VUID0gMSA8PCAxODsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9TSVpFID0gMSA8PCAxOTsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjA7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfR0VUID0gMSA8PCAyMTsKdmFyIFJJR0hUU19GRF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMjI7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1RJTUVTID0gMSA8PCAyMzsKdmFyIFJJR0hUU19QQVRIX1NZTUxJTksgPSAxIDw8IDI0Owp2YXIgUklHSFRTX1BBVEhfUkVNT1ZFX0RJUkVDVE9SWSA9IDEgPDwgMjU7CnZhciBSSUdIVFNfUEFUSF9VTkxJTktfRklMRSA9IDEgPDwgMjY7CnZhciBSSUdIVFNfUE9MTF9GRF9SRUFEV1JJVEUgPSAxIDw8IDI3Owp2YXIgUklHSFRTX1NPQ0tfU0hVVERPV04gPSAxIDw8IDI4Owp2YXIgSW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBJb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChJb3ZlYy5yZWFkX2J5dGVzKHZpZXcsIHB0ciArIDggKiBpKSk7CiAgICB9CiAgICByZXR1cm4gaW92ZWNzOwogIH0KfTsKdmFyIENpb3ZlYyA9IGNsYXNzIHsKICBzdGF0aWMgcmVhZF9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIGNvbnN0IGlvdmVjID0gbmV3IENpb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChDaW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBXSEVOQ0VfU0VUID0gMDsKdmFyIFdIRU5DRV9DVVIgPSAxOwp2YXIgV0hFTkNFX0VORCA9IDI7CnZhciBGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFID0gMjsKdmFyIEZJTEVUWVBFX0RJUkVDVE9SWSA9IDM7CnZhciBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgPSA0Owp2YXIgRGlyZW50ID0gY2xhc3MgewogIGhlYWRfbGVuZ3RoKCkgewogICAgcmV0dXJuIDI0OwogIH0KICBuYW1lX2xlbmd0aCgpIHsKICAgIHJldHVybiB0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGg7CiAgfQogIHdyaXRlX2hlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIsIHRoaXMuZF9uZXh0LCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDgsIHRoaXMuZF9pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50MzIocHRyICsgMTYsIHRoaXMuZGlyX25hbWUubGVuZ3RoLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDgocHRyICsgMjAsIHRoaXMuZF90eXBlKTsKICB9CiAgd3JpdGVfbmFtZV9ieXRlcyh2aWV3OCwgcHRyLCBidWZfbGVuKSB7CiAgICB2aWV3OC5zZXQodGhpcy5kaXJfbmFtZS5zbGljZSgwLCBNYXRoLm1pbih0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGgsIGJ1Zl9sZW4pKSwgcHRyKTsKICB9CiAgY29uc3RydWN0b3IobmV4dF9jb29raWUsIG5hbWUsIHR5cGUpIHsKICAgIHRoaXMuZF9pbm8gPSAwbjsKICAgIGNvbnN0IGVuY29kZWRfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICAgIHRoaXMuZF9uZXh0ID0gbmV4dF9jb29raWU7CiAgICB0aGlzLmRfbmFtbGVuID0gZW5jb2RlZF9uYW1lLmJ5dGVMZW5ndGg7CiAgICB0aGlzLmRfdHlwZSA9IHR5cGU7CiAgICB0aGlzLmRpcl9uYW1lID0gZW5jb2RlZF9uYW1lOwogIH0KfTsKdmFyIEZERkxBR1NfQVBQRU5EID0gMSA8PCAwOwp2YXIgRkRGTEFHU19EU1lOQyA9IDEgPDwgMTsKdmFyIEZERkxBR1NfTk9OQkxPQ0sgPSAxIDw8IDI7CnZhciBGREZMQUdTX1JTWU5DID0gMSA8PCAzOwp2YXIgRkRGTEFHU19TWU5DID0gMSA8PCA0Owp2YXIgRmRzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50OChwdHIsIHRoaXMuZnNfZmlsZXR5cGUpOwogICAgdmlldy5zZXRVaW50MTYocHRyICsgMiwgdGhpcy5mc19mbGFncywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmZzX3JpZ2h0c19iYXNlLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDE2LCB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgZmxhZ3MpIHsKICAgIHRoaXMuZnNfcmlnaHRzX2Jhc2UgPSAwbjsKICAgIHRoaXMuZnNfcmlnaHRzX2luaGVyaXRlZCA9IDBuOwogICAgdGhpcy5mc19maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5mc19mbGFncyA9IGZsYWdzOwogIH0KfTsKdmFyIEZTVEZMQUdTX0FUSU0gPSAxIDw8IDA7CnZhciBGU1RGTEFHU19BVElNX05PVyA9IDEgPDwgMTsKdmFyIEZTVEZMQUdTX01USU0gPSAxIDw8IDI7CnZhciBGU1RGTEFHU19NVElNX05PVyA9IDEgPDwgMzsKdmFyIE9GTEFHU19DUkVBVCA9IDEgPDwgMDsKdmFyIE9GTEFHU19ESVJFQ1RPUlkgPSAxIDw8IDE7CnZhciBPRkxBR1NfRVhDTCA9IDEgPDwgMjsKdmFyIE9GTEFHU19UUlVOQyA9IDEgPDwgMzsKdmFyIEZpbGVzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRldiwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmlubywgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDE2LCB0aGlzLmZpbGV0eXBlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDI0LCB0aGlzLm5saW5rLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDMyLCB0aGlzLnNpemUsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgMzgsIHRoaXMuYXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA0NiwgdGhpcy5tdGltLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDUyLCB0aGlzLmN0aW0sIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgc2l6ZSkgewogICAgdGhpcy5kZXYgPSAwbjsKICAgIHRoaXMuaW5vID0gMG47CiAgICB0aGlzLm5saW5rID0gMG47CiAgICB0aGlzLmF0aW0gPSAwbjsKICAgIHRoaXMubXRpbSA9IDBuOwogICAgdGhpcy5jdGltID0gMG47CiAgICB0aGlzLmZpbGV0eXBlID0gZmlsZXR5cGU7CiAgICB0aGlzLnNpemUgPSBzaXplOwogIH0KfTsKdmFyIEVWRU5UUldGTEFHU19GRF9SRUFEV1JJVEVfSEFOR1VQID0gMSA8PCAwOwp2YXIgU1VCQ0xPQ0tGTEFHU19TVUJTQ1JJUFRJT05fQ0xPQ0tfQUJTVElNRSA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9QRUVLID0gMSA8PCAwOwp2YXIgUklGTEFHU19SRUNWX1dBSVRBTEwgPSAxIDw8IDE7CnZhciBST0ZMQUdTX1JFQ1ZfREFUQV9UUlVOQ0FURUQgPSAxIDw8IDA7CnZhciBTREZMQUdTX1JEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19XUiA9IDEgPDwgMTsKdmFyIFBSRU9QRU5UWVBFX0RJUiA9IDA7CnZhciBQcmVzdGF0RGlyID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50MzIocHRyLCB0aGlzLnByX25hbWUuYnl0ZUxlbmd0aCwgdHJ1ZSk7CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUpIHsKICAgIHRoaXMucHJfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICB9Cn07CnZhciBQcmVzdGF0ID0gY2xhc3MgewogIHN0YXRpYyBkaXIobmFtZSkgewogICAgY29uc3QgcHJlc3RhdCA9IG5ldyBQcmVzdGF0KCk7CiAgICBwcmVzdGF0LnRhZyA9IFBSRU9QRU5UWVBFX0RJUjsKICAgIHByZXN0YXQuaW5uZXIgPSBuZXcgUHJlc3RhdERpcihuYW1lKTsKICAgIHJldHVybiBwcmVzdGF0OwogIH0KICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy50YWcsIHRydWUpOwogICAgdGhpcy5pbm5lci53cml0ZV9ieXRlcyh2aWV3LCBwdHIgKyA0KTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2RlYnVnLmpzCnZhciBEZWJ1ZyA9IGNsYXNzIERlYnVnMiB7CiAgZW5hYmxlKGVuYWJsZWQpIHsKICAgIHRoaXMubG9nID0gY3JlYXRlTG9nZ2VyKGVuYWJsZWQgPT09IHZvaWQgMCA/IHRydWUgOiBlbmFibGVkLCB0aGlzLnByZWZpeCk7CiAgfQogIGdldCBlbmFibGVkKCkgewogICAgcmV0dXJuIHRoaXMuaXNFbmFibGVkOwogIH0KICBjb25zdHJ1Y3Rvcihpc0VuYWJsZWQpIHsKICAgIHRoaXMuaXNFbmFibGVkID0gaXNFbmFibGVkOwogICAgdGhpcy5wcmVmaXggPSAid2FzaToiOwogICAgdGhpcy5lbmFibGUoaXNFbmFibGVkKTsKICB9Cn07CmZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihlbmFibGVkLCBwcmVmaXgpIHsKICBpZiAoZW5hYmxlZCkgewogICAgY29uc3QgYSA9IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSwgIiVjJXMiLCAiY29sb3I6ICMyNjVCQTAiLCBwcmVmaXgpOwogICAgcmV0dXJuIGE7CiAgfSBlbHNlIHsKICAgIHJldHVybiAoKSA9PiB7CiAgICB9OwogIH0KfQp2YXIgZGVidWcgPSBuZXcgRGVidWcoZmFsc2UpOwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpLmpzCnZhciBXQVNJUHJvY0V4aXQgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKICBjb25zdHJ1Y3Rvcihjb2RlKSB7CiAgICBzdXBlcigiZXhpdCB3aXRoIGV4aXQgY29kZSAiICsgY29kZSk7CiAgICB0aGlzLmNvZGUgPSBjb2RlOwogIH0KfTsKdmFyIFdBU0kgPSBjbGFzcyBXQVNJMiB7CiAgc3RhcnQoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgdHJ5IHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQoKTsKICAgICAgcmV0dXJuIDA7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIGlmIChlIGluc3RhbmNlb2YgV0FTSVByb2NFeGl0KSB7CiAgICAgICAgcmV0dXJuIGUuY29kZTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aHJvdyBlOwogICAgICB9CiAgICB9CiAgfQogIGluaXRpYWxpemUoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgaWYgKGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUpIHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSgpOwogICAgfQogIH0KICBjb25zdHJ1Y3RvcihhcmdzLCBlbnYsIGZkcywgb3B0aW9ucyA9IHt9KSB7CiAgICB0aGlzLmFyZ3MgPSBbXTsKICAgIHRoaXMuZW52ID0gW107CiAgICB0aGlzLmZkcyA9IFtdOwogICAgZGVidWcuZW5hYmxlKG9wdGlvbnMuZGVidWcpOwogICAgdGhpcy5hcmdzID0gYXJnczsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2ZpbGVzdGF0X2dldChmZCwgZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGZkX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIGRlYnVnLmxvZyhwYXRoKTsKICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfcmVhZGxpbmsocGF0aCk7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVuYW1lKGZkLCBvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgbmV3X2ZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGxldCB7IHJldCwgaW5vZGVfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmsob2xkX3BhdGgpOwogICAgICAgIGlmIChpbm9kZV9vYmogPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgdHJ1ZSk7CiAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICBpZiAoc2VsZi5mZHNbZmRdLnBhdGhfbGluayhvbGRfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKSAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIHRocm93ICJwYXRoX2xpbmsgc2hvdWxkIGFsd2F5cyByZXR1cm4gc3VjY2VzcyB3aGVuIHJlbGlua2luZyBhbiBpbm9kZSBiYWNrIHRvIHRoZSBvcmlnaW5hbCBwbGFjZSI7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfc3ltbGluayhvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF91bmxpbmtfZmlsZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwb2xsX29uZW9mZihpbl8sIG91dCwgbnN1YnNjcmlwdGlvbnMpIHsKICAgICAgdGhyb3cgImFzeW5jIGlvIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgcHJvY19leGl0KGV4aXRfY29kZSkgewogICAgICB0aHJvdyBuZXcgV0FTSVByb2NFeGl0KGV4aXRfY29kZSk7CiAgICB9LCBwcm9jX3JhaXNlKHNpZykgewogICAgICB0aHJvdyAicmFpc2VkIHNpZ25hbCAiICsgc2lnOwogICAgfSwgc2NoZWRfeWllbGQoKSB7CiAgICB9LCByYW5kb21fZ2V0KGJ1ZiwgYnVmX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmX2xlbjsgaSsrKSB7CiAgICAgICAgYnVmZmVyOFtidWYgKyBpXSA9IE1hdGgucmFuZG9tKCkgKiAyNTYgfCAwOwogICAgICB9CiAgICB9LCBzb2NrX3JlY3YoZmQsIHJpX2RhdGEsIHJpX2ZsYWdzKSB7CiAgICAgIHRocm93ICJzb2NrZXRzIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgc29ja19zZW5kKGZkLCBzaV9kYXRhLCBzaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2h1dGRvd24oZmQsIGhvdykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfYWNjZXB0KGZkLCBmbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0gfTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZkLmpzCnZhciBGZCA9IGNsYXNzIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfY2xvc2UoKSB7CiAgICByZXR1cm4gMDsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBmZHN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBwcmVzdGF0OiBudWxsIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRpcmVudDogbnVsbCB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9zeW5jKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9saW5rKHBhdGgsIGlub2RlLCBhbGxvd19kaXIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rKHBhdGgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aCwgZGlyZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9yZWFkbGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9yZW5hbWUob2xkX3BhdGgsIG5ld19mZCwgbmV3X3BhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9Cn07CnZhciBJbm9kZSA9IGNsYXNzIHsKfTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3QvZnNfbWVtLmpzCnZhciBPcGVuRmlsZSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBvZmZzZXQgKyBsZW4pIHsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIGxlbikpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIDApIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IHNpemUpIHsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheSh0aGlzLmZpbGUuZGF0YS5idWZmZXIuc2xpY2UoMCwgTnVtYmVyKHNpemUpKSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihzaXplKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcih0aGlzLmZpbGVfcG9zKSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KHNsaWNlLmxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIob2Zmc2V0KSwgTnVtYmVyKG9mZnNldCArIEJpZ0ludChzaXplKSkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICBsZXQgY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICBzd2l0Y2ggKHdoZW5jZSkgewogICAgICBjYXNlIFdIRU5DRV9TRVQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0NVUjoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IHRoaXMuZmlsZV9wb3MgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0VORDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IEJpZ0ludCh0aGlzLmZpbGUuZGF0YS5ieXRlTGVuZ3RoKSArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICBpZiAoY2FsY3VsYXRlZF9vZmZzZXQgPCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIHRoaXMuZmlsZV9wb3MgPSBjYWxjdWxhdGVkX29mZnNldDsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIodGhpcy5maWxlX3BvcykpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKG9mZnNldCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZmlsZS5zdGF0KCkgfTsKICB9CiAgY29uc3RydWN0b3IoZmlsZSkgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZmlsZV9wb3MgPSAwbjsKICAgIHRoaXMuZmlsZSA9IGZpbGU7CiAgfQp9Owp2YXIgT3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMCkgfTsKICB9CiAgZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKSB7CiAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICBkZWJ1Zy5sb2coInJlYWRkaXJfc2luZ2xlIiwgY29va2llKTsKICAgICAgZGVidWcubG9nKGNvb2tpZSwgdGhpcy5kaXIuY29udGVudHMua2V5cygpKTsKICAgIH0KICAgIGlmIChjb29raWUgPT0gMG4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMW4sICIuIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfSBlbHNlIGlmIChjb29raWUgPT0gMW4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMm4sICIuLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0KICAgIGlmIChjb29raWUgPj0gQmlnSW50KHRoaXMuZGlyLmNvbnRlbnRzLnNpemUpICsgMm4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IFtuYW1lLCBlbnRyeV0gPSBBcnJheS5mcm9tKHRoaXMuZGlyLmNvbnRlbnRzLmVudHJpZXMoKSlbTnVtYmVyKGNvb2tpZSAtIDJuKV07CiAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbmV3IERpcmVudChjb29raWUgKyAxbiwgbmFtZSwgZW50cnkuc3RhdCgpLmZpbGV0eXBlKSB9OwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX2VyciwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX2VyciwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBmaWxlc3RhdDogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogZW50cnkuc3RhdCgpIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGhfc3RyLCBkaXJmbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGhfc3RyLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBsZXQgeyByZXQsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfZW50cnlfZm9yX3BhdGgocGF0aCk7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICBpZiAocmV0ICE9IEVSUk5PX05PRU5UKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0LCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19DUkVBVCkgPT0gT0ZMQUdTX0NSRUFUKSB7CiAgICAgICAgY29uc3QgeyByZXQ6IHJldDIsIGVudHJ5OiBuZXdfZW50cnkgfSA9IHRoaXMuZGlyLmNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkpOwogICAgICAgIGlmIChuZXdfZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiByZXQyLCBmZF9vYmo6IG51bGwgfTsKICAgICAgICB9CiAgICAgICAgZW50cnkgPSBuZXdfZW50cnk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoKG9mbGFncyAmIE9GTEFHU19FWENMKSA9PSBPRkxBR1NfRVhDTCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4gZW50cnkucGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoLCBPRkxBR1NfQ1JFQVQgfCBPRkxBR1NfRElSRUNUT1JZLCAwbiwgMG4sIDApLnJldDsKICB9CiAgcGF0aF9saW5rKHBhdGhfc3RyLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgY29uc3Qgc291cmNlX2lzX2RpciA9IGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGNvbnN0IHRhcmdldF9pc19kaXIgPSBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBpZiAoc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgaWYgKGFsbG93X2RpciAmJiBlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgewogICAgICAgICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgPT0gMCkgewogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYgKHNvdXJjZV9pc19kaXIgJiYgIXRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgICB9IGVsc2UgaWYgKCFzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICAgIH0gZWxzZSBpZiAoaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFKSB7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICB9CiAgICB9CiAgICBpZiAoIWFsbG93X2RpciAmJiBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19QRVJNOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLnNldChmaWxlbmFtZSwgaW5vZGUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfdW5saW5rKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlID09PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgfHwgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgIH0KICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplICE9PSAwKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgIH0KICAgIGlmICghcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZGlyLnN0YXQoKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGNvbnN0cnVjdG9yKGRpcikgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGlyID0gZGlyOwogIH0KfTsKdmFyIFByZW9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIE9wZW5EaXJlY3RvcnkgewogIGZkX3ByZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBwcmVzdGF0OiBQcmVzdGF0LmRpcih0aGlzLnByZXN0YXRfbmFtZSkgfTsKICB9CiAgY29uc3RydWN0b3IobmFtZSwgY29udGVudHMpIHsKICAgIHN1cGVyKG5ldyBEaXJlY3RvcnkoY29udGVudHMpKTsKICAgIHRoaXMucHJlc3RhdF9uYW1lID0gbmFtZTsKICB9Cn07CnZhciBGaWxlID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICBpZiAodGhpcy5yZWFkb25seSAmJiAoZnNfcmlnaHRzX2Jhc2UgJiBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgPT0gQmlnSW50KFJJR0hUU19GRF9XUklURSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX1RSVU5DKSA9PSBPRkxBR1NfVFJVTkMpIHsKICAgICAgaWYgKHRoaXMucmVhZG9ubHkpCiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoW10pOwogICAgfQogICAgY29uc3QgZmlsZSA9IG5ldyBPcGVuRmlsZSh0aGlzKTsKICAgIGlmIChmZF9mbGFncyAmIEZERkxBR1NfQVBQRU5EKQogICAgICBmaWxlLmZkX3NlZWsoMG4sIFdIRU5DRV9FTkQpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IGZpbGUgfTsKICB9CiAgZ2V0IHNpemUoKSB7CiAgICByZXR1cm4gQmlnSW50KHRoaXMuZGF0YS5ieXRlTGVuZ3RoKTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCB0aGlzLnNpemUpOwogIH0KICBjb25zdHJ1Y3RvcihkYXRhLCBvcHRpb25zKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7CiAgICB0aGlzLnJlYWRvbmx5ID0gISFvcHRpb25zPy5yZWFkb25seTsKICB9Cn07CnZhciBQYXRoID0gY2xhc3MgUGF0aDIgewogIHN0YXRpYyBmcm9tKHBhdGgpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aC5lbmRzV2l0aCgiLyIpOwogICAgaWYgKHBhdGguc3RhcnRzV2l0aCgiLyIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgfQogICAgaWYgKHBhdGguaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5zcGxpdCgiLyIpKSB7CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIiIHx8IGNvbXBvbmVudCA9PT0gIi4iKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKGNvbXBvbmVudCA9PT0gIi4uIikgewogICAgICAgIGlmIChzZWxmLnBhcnRzLnBvcCgpID09IHZvaWQgMCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIHNlbGYucGFydHMucHVzaChjb21wb25lbnQpOwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXRoOiBzZWxmIH07CiAgfQogIHRvX3BhdGhfc3RyaW5nKCkgewogICAgbGV0IHMgPSB0aGlzLnBhcnRzLmpvaW4oIi8iKTsKICAgIGlmICh0aGlzLmlzX2RpcikgewogICAgICBzICs9ICIvIjsKICAgIH0KICAgIHJldHVybiBzOwogIH0KICBjb25zdHJ1Y3RvcigpIHsKICAgIHRoaXMucGFydHMgPSBbXTsKICAgIHRoaXMuaXNfZGlyID0gZmFsc2U7CiAgfQp9Owp2YXIgRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogbmV3IE9wZW5EaXJlY3RvcnkodGhpcykgfTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwbik7CiAgfQogIGdldF9lbnRyeV9mb3JfcGF0aChwYXRoKSB7CiAgICBsZXQgZW50cnkgPSB0aGlzOwogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGFsbG93X3VuZGVmaW5lZCkgewogICAgY29uc3QgZmlsZW5hbWUgPSBwYXRoLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogZW50cnlfcmV0LCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKCEocGFyZW50X2VudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IGVudHJ5ID0gcGFyZW50X2VudHJ5LmNvbnRlbnRzLmdldChmaWxlbmFtZSk7CiAgICBpZiAoZW50cnkgPT09IHZvaWQgMCkgewogICAgICBpZiAoIWFsbG93X3VuZGVmaW5lZCkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9OwogIH0KICBjcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIGlzX2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgZGVidWcubG9nKCJjcmVhdGUiLCBwYXRoKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvaW5kZXguanMKZnVuY3Rpb24gcGFyc2VJbXBvcnRzKG1vZHVsZUJ5dGVzKSB7CiAgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcyk7CiAgfSBlbHNlIGlmIChtb2R1bGVCeXRlcy5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcy5idWZmZXIpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoIkFyZ3VtZW50IG11c3QgYmUgYSBidWZmZXIgc291cmNlLCBsaWtlIFVpbnQ4QXJyYXkgb3IgQXJyYXlCdWZmZXIiKTsKICB9CiAgY29uc3QgcGFyc2VTdGF0ZSA9IG5ldyBQYXJzZVN0YXRlKG1vZHVsZUJ5dGVzKTsKICBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpOwogIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKTsKICBjb25zdCB0eXBlcyA9IFtdOwogIGNvbnN0IGltcG9ydHMgPSBbXTsKICB3aGlsZSAocGFyc2VTdGF0ZS5oYXNNb3JlQnl0ZXMoKSkgewogICAgY29uc3Qgc2VjdGlvbklkID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgY29uc3Qgc2VjdGlvblNpemUgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgc3dpdGNoIChzZWN0aW9uSWQpIHsKICAgICAgY2FzZSAxOiB7CiAgICAgICAgY29uc3QgdHlwZUNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVDb3VudDsgaSsrKSB7CiAgICAgICAgICB0eXBlcy5wdXNoKHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAyOiB7CiAgICAgICAgY29uc3QgaW1wb3J0Q291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW1wb3J0Q291bnQ7IGkrKykgewogICAgICAgICAgY29uc3QgbW9kdWxlID0gcGFyc2VTdGF0ZS5yZWFkTmFtZSgpOwogICAgICAgICAgY29uc3QgbmFtZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJmdW5jdGlvbiIsIHR5cGU6IHR5cGVzW2luZGV4XSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgIGltcG9ydHMucHVzaCh7IG1vZHVsZSwgbmFtZSwga2luZDogInRhYmxlIiwgdHlwZTogcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJtZW1vcnkiLCB0eXBlOiBwYXJzZUxpbWl0cyhwYXJzZVN0YXRlKSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgIGltcG9ydHMucHVzaCh7IG1vZHVsZSwgbmFtZSwga2luZDogImdsb2JhbCIsIHR5cGU6IHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gaW1wb3J0IGRlc2NyaXB0b3IgdHlwZSAke3R5cGV9YCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbXBvcnRzOwogICAgICB9CiAgICAgIGRlZmF1bHQ6IHsKICAgICAgICBwYXJzZVN0YXRlLnNraXBCeXRlcyhzZWN0aW9uU2l6ZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFtdOwp9CnZhciBQYXJzZVN0YXRlID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG1vZHVsZUJ5dGVzKSB7CiAgICB0aGlzLm1vZHVsZUJ5dGVzID0gbW9kdWxlQnl0ZXM7CiAgICB0aGlzLm9mZnNldCA9IDA7CiAgICB0aGlzLnRleHREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpOwogIH0KICBoYXNNb3JlQnl0ZXMoKSB7CiAgICByZXR1cm4gdGhpcy5vZmZzZXQgPCB0aGlzLm1vZHVsZUJ5dGVzLmxlbmd0aDsKICB9CiAgcmVhZEJ5dGUoKSB7CiAgICByZXR1cm4gdGhpcy5tb2R1bGVCeXRlc1t0aGlzLm9mZnNldCsrXTsKICB9CiAgc2tpcEJ5dGVzKGNvdW50KSB7CiAgICB0aGlzLm9mZnNldCArPSBjb3VudDsKICB9CiAgcmVhZFVuc2lnbmVkTEVCMTI4KCkgewogICAgbGV0IHJlc3VsdCA9IDA7CiAgICBsZXQgc2hpZnQgPSAwOwogICAgbGV0IGJ5dGU7CiAgICBkbyB7CiAgICAgIGJ5dGUgPSB0aGlzLnJlYWRCeXRlKCk7CiAgICAgIHJlc3VsdCB8PSAoYnl0ZSAmIDEyNykgPDwgc2hpZnQ7CiAgICAgIHNoaWZ0ICs9IDc7CiAgICB9IHdoaWxlIChieXRlICYgMTI4KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfQogIHJlYWROYW1lKCkgewogICAgY29uc3QgbmFtZUxlbmd0aCA9IHRoaXMucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICBjb25zdCBuYW1lQnl0ZXMgPSB0aGlzLm1vZHVsZUJ5dGVzLnNsaWNlKHRoaXMub2Zmc2V0LCB0aGlzLm9mZnNldCArIG5hbWVMZW5ndGgpOwogICAgY29uc3QgbmFtZSA9IHRoaXMudGV4dERlY29kZXIuZGVjb2RlKG5hbWVCeXRlcyk7CiAgICB0aGlzLm9mZnNldCArPSBuYW1lTGVuZ3RoOwogICAgcmV0dXJuIG5hbWU7CiAgfQogIGFzc2VydEJ5dGVzKGV4cGVjdGVkKSB7CiAgICBjb25zdCBiYXNlT2Zmc2V0ID0gdGhpcy5vZmZzZXQ7CiAgICBjb25zdCBleHBlY3RlZExlbmd0aCA9IGV4cGVjdGVkLmxlbmd0aDsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwZWN0ZWRMZW5ndGg7IGkrKykgewogICAgICBpZiAodGhpcy5tb2R1bGVCeXRlc1tiYXNlT2Zmc2V0ICsgaV0gIT09IGV4cGVjdGVkW2ldKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSBhdCBvZmZzZXQgJHtiYXNlT2Zmc2V0fWApOwogICAgICB9CiAgICB9CiAgICB0aGlzLm9mZnNldCArPSBleHBlY3RlZExlbmd0aDsKICB9Cn07CmZ1bmN0aW9uIHBhcnNlTWFnaWNOdW1iZXIocGFyc2VTdGF0ZSkgewogIGNvbnN0IGV4cGVjdGVkID0gWzAsIDk3LCAxMTUsIDEwOV07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VWZXJzaW9uKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFsxLCAwLCAwLCAwXTsKICBwYXJzZVN0YXRlLmFzc2VydEJ5dGVzKGV4cGVjdGVkKTsKfQpmdW5jdGlvbiBwYXJzZVRhYmxlVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgZWxlbWVudFR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgbGV0IGVsZW1lbnQ7CiAgc3dpdGNoIChlbGVtZW50VHlwZSkgewogICAgY2FzZSAxMTI6CiAgICAgIGVsZW1lbnQgPSAiZnVuY3JlZiI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAxMTE6CiAgICAgIGVsZW1lbnQgPSAiZXh0ZXJucmVmIjsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdGFibGUgZWxlbWVudCB0eXBlICR7ZWxlbWVudFR5cGV9YCk7CiAgfQogIGNvbnN0IHsgbWluaW11bSwgbWF4aW11bSB9ID0gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSk7CiAgaWYgKG1heGltdW0pIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0sIG1heGltdW0gfTsKICB9IGVsc2UgewogICAgcmV0dXJuIHsgZWxlbWVudCwgbWluaW11bSB9OwogIH0KfQpmdW5jdGlvbiBwYXJzZUxpbWl0cyhwYXJzZVN0YXRlKSB7CiAgY29uc3QgZmxhZ3MgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgY29uc3QgbWluaW11bSA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgY29uc3QgaGFzTWF4aW11bSA9IGZsYWdzICYgMTsKICBjb25zdCBzaGFyZWQgPSAoZmxhZ3MgJiAyKSAhPT0gMDsKICBjb25zdCBpc01lbW9yeTY0ID0gKGZsYWdzICYgNCkgIT09IDA7CiAgY29uc3QgaW5kZXggPSBpc01lbW9yeTY0ID8gImk2NCIgOiAiaTMyIjsKICBpZiAoaGFzTWF4aW11bSkgewogICAgY29uc3QgbWF4aW11bSA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4LCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IG1pbmltdW0sIHNoYXJlZCwgaW5kZXggfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VHbG9iYWxUeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCB2YWx1ZSA9IHBhcnNlVmFsdWVUeXBlKHBhcnNlU3RhdGUpOwogIGNvbnN0IG11dGFibGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCkgPT09IDE7CiAgcmV0dXJuIHsgdmFsdWUsIG11dGFibGUgfTsKfQpmdW5jdGlvbiBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdHlwZSA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgMTI3OgogICAgICByZXR1cm4gImkzMiI7CiAgICBjYXNlIDEyNjoKICAgICAgcmV0dXJuICJpNjQiOwogICAgY2FzZSAxMjU6CiAgICAgIHJldHVybiAiZjMyIjsKICAgIGNhc2UgMTI0OgogICAgICByZXR1cm4gImY2NCI7CiAgICBjYXNlIDExMjoKICAgICAgcmV0dXJuICJmdW5jcmVmIjsKICAgIGNhc2UgMTExOgogICAgICByZXR1cm4gImV4dGVybnJlZiI7CiAgICBjYXNlIDEyMzoKICAgICAgcmV0dXJuICJ2MTI4IjsKICAgIGRlZmF1bHQ6CiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB2YWx1ZSB0eXBlICR7dHlwZX1gKTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VGdW5jdGlvblR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZvcm0gPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgaWYgKGZvcm0gIT09IDk2KSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGZ1bmN0aW9uIHR5cGUgZm9ybSAweDYwLCBnb3QgJHtmb3JtfWApOwogIH0KICBjb25zdCBwYXJhbWV0ZXJzID0gW107CiAgY29uc3QgcGFyYW1ldGVyQ291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1ldGVyQ291bnQ7IGkrKykgewogICAgcGFyYW1ldGVycy5wdXNoKHBhcnNlVmFsdWVUeXBlKHBhcnNlU3RhdGUpKTsKICB9CiAgY29uc3QgcmVzdWx0cyA9IFtdOwogIGNvbnN0IHJlc3VsdENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdENvdW50OyBpKyspIHsKICAgIHJlc3VsdHMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIHJldHVybiB7IHBhcmFtZXRlcnMsIHJlc3VsdHMgfTsKfQoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvcG9seWZpbGwuanMKdmFyIGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQgPSAoKCkgPT4gewogIGNvbnN0IG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoWwogICAgMCwKICAgIDk3LAogICAgMTE1LAogICAgMTA5LAogICAgMSwKICAgIDAsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICA2LAogICAgMSwKICAgIDAsCiAgICAwLAogICAgMiwKICAgIDAsCiAgICAxCiAgXSk7CiAgY29uc3QgbW9kdWxlID0gbmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShtb2R1bGVCeXRlcyk7CiAgY29uc3QgaW1wb3J0cyA9IFdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgY29uc3QgbWVtb3J5SW1wb3J0ID0gaW1wb3J0c1swXTsKICByZXR1cm4gdHlwZW9mIG1lbW9yeUltcG9ydC50eXBlID09PSAib2JqZWN0IjsKfSkoKTsKZnVuY3Rpb24gcG9seWZpbGwoV2ViQXNzZW1ibHkyKSB7CiAgaWYgKGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQpIHsKICAgIHJldHVybiBXZWJBc3NlbWJseTI7CiAgfQogIGNvbnN0IG5ld1dlYkFzc2VtYmx5ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoV2ViQXNzZW1ibHkyKSkgewogICAgbmV3V2ViQXNzZW1ibHlba2V5XSA9IFdlYkFzc2VtYmx5MltrZXldOwogIH0KICBjb25zdCBwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbCA9IFN5bWJvbCgicG9seWZpbGxlZEltcG9ydHNTeW1ib2wiKTsKICBjb25zdCBhc3NpZ25JbXBvcnRzID0gKG1vZHVsZSwgc291cmNlQnl0ZXMpID0+IHsKICAgIG1vZHVsZVtwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbF0gPSBwYXJzZUltcG9ydHMoc291cmNlQnl0ZXMpOwogIH07CiAgY29uc3QgbmV3TW9kdWxlID0gbmV3V2ViQXNzZW1ibHkuTW9kdWxlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICAgIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseTIuTW9kdWxlKGJ5dGVzKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBieXRlcyk7CiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YobW9kdWxlLCBuZXdNb2R1bGUucHJvdG90eXBlKTsKICAgIHJldHVybiBtb2R1bGU7CiAgfTsKICBPYmplY3Quc2V0UHJvdG90eXBlT2YobmV3TW9kdWxlLnByb3RvdHlwZSwgV2ViQXNzZW1ibHkyLk1vZHVsZS5wcm90b3R5cGUpOwogIG5ld1dlYkFzc2VtYmx5LmNvbXBpbGUgPSBhc3luYyAoc291cmNlKSA9PiB7CiAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseTIuY29tcGlsZShzb3VyY2UpOwogICAgYXNzaWduSW1wb3J0cyhtb2R1bGUsIHNvdXJjZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgaWYgKFdlYkFzc2VtYmx5Mi5jb21waWxlU3RyZWFtaW5nKSB7CiAgICBuZXdXZWJBc3NlbWJseS5jb21waWxlU3RyZWFtaW5nID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNvdXJjZTsKICAgICAgY29uc3QgY2xvbmUgPSByZXNwb25zZS5jbG9uZSgpOwogICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseTIuY29tcGlsZVN0cmVhbWluZyhyZXNwb25zZSk7CiAgICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBuZXcgVWludDhBcnJheShhd2FpdCBjbG9uZS5hcnJheUJ1ZmZlcigpKSk7CiAgICAgIHJldHVybiBtb2R1bGU7CiAgICB9OwogIH0KICBuZXdNb2R1bGUuaW1wb3J0cyA9IChtb2R1bGUpID0+IHsKICAgIGNvbnN0IHBhcnNlZEltcG9ydHMgPSBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdOwogICAgaWYgKCFwYXJzZWRJbXBvcnRzKSB7CiAgICAgIHJldHVybiBXZWJBc3NlbWJseTIuTW9kdWxlLmltcG9ydHMobW9kdWxlKTsKICAgIH0KICAgIHJldHVybiBwYXJzZWRJbXBvcnRzOwogIH07CiAgcmV0dXJuIG5ld1dlYkFzc2VtYmx5Owp9CgovLyBlbnRyeXBvaW50L2NvbW1vbi50cwpnbG9iYWxUaGlzLldlYkFzc2VtYmx5ID0gcG9seWZpbGwoZ2xvYmFsVGhpcy5XZWJBc3NlbWJseSk7CnZhciBMaW5lRGVjb2RlciA9IGNsYXNzIHsKICBjb25zdHJ1Y3RvcihvbkxpbmUpIHsKICAgIHRoaXMuZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIHRoaXMuYnVmZmVyID0gIiI7CiAgICB0aGlzLm9uTGluZSA9IG9uTGluZTsKICB9CiAgZGVjb2RlcjsKICBidWZmZXI7CiAgb25MaW5lOwogIHNlbmQoY2h1bmspIHsKICAgIHRoaXMuYnVmZmVyICs9IHRoaXMuZGVjb2Rlci5kZWNvZGUoY2h1bmssIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgY29uc3QgbGluZXMgPSB0aGlzLmJ1ZmZlci5zcGxpdCgiXG4iKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoIC0gMTsgaSsrKSB7CiAgICAgIHRoaXMub25MaW5lKGxpbmVzW2ldKTsKICAgIH0KICAgIHRoaXMuYnVmZmVyID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV07CiAgfQp9Owp2YXIgV2FzbVJ1bm5lciA9IChyYXdPcHRpb25zLCBTd2lmdFJ1bnRpbWUpID0+IHsKICBjb25zdCBvcHRpb25zID0gZGVmYXVsdFJ1bm5lck9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0OwogIGlmIChTd2lmdFJ1bnRpbWUpIHsKICAgIHN3aWZ0ID0gbmV3IFN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJncyA9IG9wdGlvbnMuYXJncyB8fCBbXTsKICBjb25zdCBmZHMgPSBbCiAgICBuZXcgT3BlbkZpbGUobmV3IEZpbGUoW10pKSwKICAgIHN0ZG91dCwKICAgIHN0ZGVyciwKICAgIG5ldyBQcmVvcGVuRGlyZWN0b3J5KCIvIiwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSkKICBdOwogIGNvbnN0IGVudnMgPSBvcHRpb25zLmVudiA/IE9iamVjdC5lbnRyaWVzKG9wdGlvbnMuZW52KS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYCR7a2V5fT0ke3ZhbHVlfWApIDogW107CiAgY29uc3Qgd2FzaSA9IG5ldyBXQVNJKGFyZ3MsIGVudnMsIGZkcywgewogICAgZGVidWc6IGZhbHNlCiAgfSk7CiAgY29uc3QgY3JlYXRlV2FzbUltcG9ydE9iamVjdCA9IChleHRyYVdhc21JbXBvcnRzLCBtb2R1bGUpID0+IHsKICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IHsKICAgICAgd2FzaV9zbmFwc2hvdF9wcmV2aWV3MTogd2FzaS53YXNpSW1wb3J0CiAgICB9OwogICAgaWYgKHN3aWZ0KSB7CiAgICAgIGltcG9ydE9iamVjdC5qYXZhc2NyaXB0X2tpdCA9IHN3aWZ0Lndhc21JbXBvcnRzOwogICAgfQogICAgaWYgKGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgZm9yIChjb25zdCBtb2R1bGVOYW1lIGluIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgICBpZiAoIWltcG9ydE9iamVjdFttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdID0ge307CiAgICAgICAgfQogICAgICAgIGZvciAoY29uc3QgZW50cnkgaW4gZXh0cmFXYXNtSW1wb3J0c1ttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdW2VudHJ5XSA9IGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV1bZW50cnldOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZm9yIChjb25zdCBfaW1wb3J0RW50cnkgb2YgV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMobW9kdWxlKSkgewogICAgICBjb25zdCBpbXBvcnRFbnRyeSA9IF9pbXBvcnRFbnRyeTsKICAgICAgaWYgKCFpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXSkgewogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdID0ge307CiAgICAgIH0KICAgICAgaWYgKGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gImZ1bmN0aW9uIikgewogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbXBvcnRlZCBmdW5jdGlvbiAke2ltcG9ydEVudHJ5Lm1vZHVsZX0uJHtpbXBvcnRFbnRyeS5uYW1lfSBub3QgaW1wbGVtZW50ZWRgKTsKICAgICAgICB9OwogICAgICB9IGVsc2UgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gIm1lbW9yeSIgJiYgaW1wb3J0RW50cnkubW9kdWxlID09ICJlbnYiICYmIGltcG9ydEVudHJ5Lm5hbWUgPT0gIm1lbW9yeSIpIHsKICAgICAgICBjb25zdCB0eXBlID0gaW1wb3J0RW50cnkudHlwZTsKICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0gewogICAgICAgICAgaW5pdGlhbDogdHlwZS5taW5pbXVtLAogICAgICAgICAgbWF4aW11bTogdHlwZS5tYXhpbXVtLAogICAgICAgICAgc2hhcmVkOiB0eXBlLnNoYXJlZAogICAgICAgIH07CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0gPSBuZXcgV2ViQXNzZW1ibHkuTWVtb3J5KGRlc2NyaXB0b3IpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0OwogIH07CiAgcmV0dXJuIHsKICAgIGFzeW5jIHJ1bih3YXNtQnl0ZXMsIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgaWYgKCFleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgZXh0cmFXYXNtSW1wb3J0cyA9IHt9OwogICAgICB9CiAgICAgIGV4dHJhV2FzbUltcG9ydHMuX19zdGFja19zYW5pdGl6ZXIgPSB7CiAgICAgICAgcmVwb3J0X3N0YWNrX292ZXJmbG93OiAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkRldGVjdGVkIHN0YWNrIGJ1ZmZlciBvdmVyZmxvdy4iKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIGNvbnN0IG1vZHVsZSA9IGF3YWl0IFdlYkFzc2VtYmx5LmNvbXBpbGUod2FzbUJ5dGVzKTsKICAgICAgY29uc3QgaW1wb3J0T2JqZWN0ID0gY3JlYXRlV2FzbUltcG9ydE9iamVjdChleHRyYVdhc21JbXBvcnRzLCBtb2R1bGUpOwogICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKG1vZHVsZSwgaW1wb3J0T2JqZWN0KTsKICAgICAgaWYgKHN3aWZ0ICYmIGluc3RhbmNlLmV4cG9ydHMuc3dqc19saWJyYXJ5X3ZlcnNpb24pIHsKICAgICAgICBzd2lmdC5zZXRJbnN0YW5jZShpbnN0YW5jZSk7CiAgICAgIH0KICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9zdGFydCA9PT0gImZ1bmN0aW9uIikgewogICAgICAgIHdhc2kuc3RhcnQoaW5zdGFuY2UpOwogICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplID09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLmluaXRpYWxpemUoaW5zdGFuY2UpOwogICAgICAgIGlmIChzd2lmdCAmJiBzd2lmdC5tYWluKSB7CiAgICAgICAgICBzd2lmdC5tYWluKCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5tYWluID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICAgIGluc3RhbmNlLmV4cG9ydHMubWFpbigpOwogICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgICAgIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndigwLCAwKTsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9Owp9Owp2YXIgZGVmYXVsdFJ1bm5lck9wdGlvbnMgPSAob3B0aW9ucykgPT4gewogIGlmIChvcHRpb25zLmFyZ3MgPT0gbnVsbCkgewogICAgb3B0aW9ucy5hcmdzID0gWyJtYWluLndhc20iXTsKICB9CiAgcmV0dXJuIG9wdGlvbnM7Cn07CgovLyBlbnRyeXBvaW50L2J1bmRsZS50cwp2YXIgc3RhcnRXYXNpVGFzayA9IGFzeW5jICgpID0+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+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcihvZmZzZXQpKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmZpbGUuc3RhdCgpIH07CiAgfQogIGNvbnN0cnVjdG9yKGZpbGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmZpbGVfcG9zID0gMG47CiAgICB0aGlzLmZpbGUgPSBmaWxlOwogIH0KfTsKdmFyIE9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9ESVJFQ1RPUlksIDApIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgZGVidWcubG9nKCJyZWFkZGlyX3NpbmdsZSIsIGNvb2tpZSk7CiAgICAgIGRlYnVnLmxvZyhjb29raWUsIHRoaXMuZGlyLmNvbnRlbnRzLmtleXMoKSk7CiAgICB9CiAgICBpZiAoY29va2llID09IDBuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDFuLCAiLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0gZWxzZSBpZiAoY29va2llID09IDFuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDJuLCAiLi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9CiAgICBpZiAoY29va2llID49IEJpZ0ludCh0aGlzLmRpci5jb250ZW50cy5zaXplKSArIDJuKSB7CiAgICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBbbmFtZSwgZW50cnldID0gQXJyYXkuZnJvbSh0aGlzLmRpci5jb250ZW50cy5lbnRyaWVzKCkpW051bWJlcihjb29raWUgLSAybildOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG5ldyBEaXJlbnQoY29va2llICsgMW4sIG5hbWUsIGVudHJ5LnN0YXQoKS5maWxldHlwZSkgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9lcnIsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IGVudHJ5LnN0YXQoKSB9OwogIH0KICBwYXRoX2xvb2t1cChwYXRoX3N0ciwgZGlyZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoX3N0ciwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgaWYgKHJldCAhPSBFUlJOT19OT0VOVCkgewogICAgICAgIHJldHVybiB7IHJldCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfQ1JFQVQpID09IE9GTEFHU19DUkVBVCkgewogICAgICAgIGNvbnN0IHsgcmV0OiByZXQyLCBlbnRyeTogbmV3X2VudHJ5IH0gPSB0aGlzLmRpci5jcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZKTsKICAgICAgICBpZiAobmV3X2VudHJ5ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiB7IHJldDogcmV0MiwgZmRfb2JqOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGVudHJ5ID0gbmV3X2VudHJ5OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICB9IGVsc2UgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRVhDTCkgPT0gT0ZMQUdTX0VYQ0wpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIGVudHJ5LnBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncyk7CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gdGhpcy5wYXRoX29wZW4oMCwgcGF0aCwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIGNvbnN0IHNvdXJjZV9pc19kaXIgPSBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBjb25zdCB0YXJnZXRfaXNfZGlyID0gZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgaWYgKHNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIGlmIChhbGxvd19kaXIgJiYgZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHsKICAgICAgICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplID09IDApIHsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChzb3VyY2VfaXNfZGlyICYmICF0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgICAgfSBlbHNlIGlmICghc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgICB9IGVsc2UgaWYgKGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSkgewogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgfQogICAgfQogICAgaWYgKCFhbGxvd19kaXIgJiYgaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fUEVSTTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIGlub2RlKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3VubGluayhwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF91bmxpbmtfZmlsZShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHx8IGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICB9CiAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSAhPT0gMCkgewogICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICB9CiAgICBpZiAoIXBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpKSB7CiAgICAgIHJldHVybiBFUlJOT19OT0VOVDsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmRpci5zdGF0KCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBjb25zdHJ1Y3RvcihkaXIpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRpciA9IGRpcjsKICB9Cn07CnZhciBQcmVvcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBPcGVuRGlyZWN0b3J5IHsKICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgcHJlc3RhdDogUHJlc3RhdC5kaXIodGhpcy5wcmVzdGF0X25hbWUpIH07CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnRzKSB7CiAgICBzdXBlcihuZXcgRGlyZWN0b3J5KGNvbnRlbnRzKSk7CiAgICB0aGlzLnByZXN0YXRfbmFtZSA9IG5hbWU7CiAgfQp9Owp2YXIgRmlsZSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgaWYgKHRoaXMucmVhZG9ubHkgJiYgKGZzX3JpZ2h0c19iYXNlICYgQmlnSW50KFJJR0hUU19GRF9XUklURSkpID09IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19UUlVOQykgPT0gT0ZMQUdTX1RSVU5DKSB7CiAgICAgIGlmICh0aGlzLnJlYWRvbmx5KQogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KFtdKTsKICAgIH0KICAgIGNvbnN0IGZpbGUgPSBuZXcgT3BlbkZpbGUodGhpcyk7CiAgICBpZiAoZmRfZmxhZ3MgJiBGREZMQUdTX0FQUEVORCkKICAgICAgZmlsZS5mZF9zZWVrKDBuLCBXSEVOQ0VfRU5EKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZmRfb2JqOiBmaWxlIH07CiAgfQogIGdldCBzaXplKCkgewogICAgcmV0dXJuIEJpZ0ludCh0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgdGhpcy5zaXplKTsKICB9CiAgY29uc3RydWN0b3IoZGF0YSwgb3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgdGhpcy5yZWFkb25seSA9ICEhb3B0aW9ucz8ucmVhZG9ubHk7CiAgfQp9Owp2YXIgUGF0aCA9IGNsYXNzIFBhdGgyIHsKICBzdGF0aWMgZnJvbShwYXRoKSB7CiAgICBjb25zdCBzZWxmID0gbmV3IFBhdGgyKCk7CiAgICBzZWxmLmlzX2RpciA9IHBhdGguZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVENBUEFCTEUsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGlmIChwYXRoLmluY2x1ZGVzKCJcMCIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGguc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aCkgewogICAgbGV0IGVudHJ5ID0gdGhpczsKICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgucGFydHMpIHsKICAgICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgICAgY29uc3QgY2hpbGQgPSBlbnRyeS5jb250ZW50cy5nZXQoY29tcG9uZW50KTsKICAgICAgaWYgKGNoaWxkICE9PSB2b2lkIDApIHsKICAgICAgICBlbnRyeSA9IGNoaWxkOwogICAgICB9IGVsc2UgewogICAgICAgIGRlYnVnLmxvZyhjb21wb25lbnQpOwogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBhbGxvd191bmRlZmluZWQpIHsKICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5wYXJ0cy5wb3AoKTsKICAgIGlmIChmaWxlbmFtZSA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldDogZW50cnlfcmV0LCBlbnRyeTogcGFyZW50X2VudHJ5IH0gPSB0aGlzLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfTsKICB9CiAgY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCBpc19kaXIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGRlYnVnLmxvZygiY3JlYXRlIiwgcGF0aCk7CiAgICBsZXQgbmV3X2NoaWxkOwogICAgaWYgKCFpc19kaXIpIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IEZpbGUobmV3IEFycmF5QnVmZmVyKDApKTsKICAgIH0gZWxzZSB7CiAgICAgIG5ld19jaGlsZCA9IG5ldyBEaXJlY3RvcnkoLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSk7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBuZXdfY2hpbGQpOwogICAgZW50cnkgPSBuZXdfY2hpbGQ7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGNvbnN0cnVjdG9yKGNvbnRlbnRzKSB7CiAgICBzdXBlcigpOwogICAgaWYgKGNvbnRlbnRzIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgdGhpcy5jb250ZW50cyA9IG5ldyBNYXAoY29udGVudHMpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5jb250ZW50cyA9IGNvbnRlbnRzOwogICAgfQogIH0KfTsKdmFyIENvbnNvbGVTdGRvdXQgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmaWxlc3RhdCA9IG5ldyBGaWxlc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCBCaWdJbnQoMCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdCB9OwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgY29uc3QgZmRzdGF0ID0gbmV3IEZkc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCAwKTsKICAgIGZkc3RhdC5mc19yaWdodHNfYmFzZSA9IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgdGhpcy53cml0ZShkYXRhKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBzdGF0aWMgbGluZUJ1ZmZlcmVkKHdyaXRlKSB7CiAgICBjb25zdCBkZWMgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICBsZXQgbGluZV9idWYgPSAiIjsKICAgIHJldHVybiBuZXcgQ29uc29sZVN0ZG91dCgoYnVmZmVyKSA9PiB7CiAgICAgIGxpbmVfYnVmICs9IGRlYy5kZWNvZGUoYnVmZmVyLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgICAgY29uc3QgbGluZXMgPSBsaW5lX2J1Zi5zcGxpdCgiXG4iKTsKICAgICAgZm9yIChjb25zdCBbaSwgbGluZV0gb2YgbGluZXMuZW50cmllcygpKSB7CiAgICAgICAgaWYgKGkgPCBsaW5lcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICB3cml0ZShsaW5lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGluZV9idWYgPSBsaW5lOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfQogIGNvbnN0cnVjdG9yKHdyaXRlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy53cml0ZSA9IHdyaXRlOwogIH0KfTsKCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL2luZGV4LmpzCmZ1bmN0aW9uIHBhcnNlSW1wb3J0cyhtb2R1bGVCeXRlcykgewogIGlmIChtb2R1bGVCeXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsKICB9IGVsc2UgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMpOwogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMuYnVmZmVyKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCJBcmd1bWVudCBtdXN0IGJlIGEgYnVmZmVyIHNvdXJjZSwgbGlrZSBVaW50OEFycmF5IG9yIEFycmF5QnVmZmVyIik7CiAgfQogIGNvbnN0IHBhcnNlU3RhdGUgPSBuZXcgUGFyc2VTdGF0ZShtb2R1bGVCeXRlcyk7CiAgcGFyc2VNYWdpY051bWJlcihwYXJzZVN0YXRlKTsKICBwYXJzZVZlcnNpb24ocGFyc2VTdGF0ZSk7CiAgY29uc3QgdHlwZXMgPSBbXTsKICBjb25zdCBpbXBvcnRzID0gW107CiAgd2hpbGUgKHBhcnNlU3RhdGUuaGFzTW9yZUJ5dGVzKCkpIHsKICAgIGNvbnN0IHNlY3Rpb25JZCA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICAgIGNvbnN0IHNlY3Rpb25TaXplID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgIHN3aXRjaCAoc2VjdGlvbklkKSB7CiAgICAgIGNhc2UgMTogewogICAgICAgIGNvbnN0IHR5cGVDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eXBlQ291bnQ7IGkrKykgewogICAgICAgICAgdHlwZXMucHVzaChwYXJzZUZ1bmN0aW9uVHlwZShwYXJzZVN0YXRlKSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgMjogewogICAgICAgIGNvbnN0IGltcG9ydENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGltcG9ydENvdW50OyBpKyspIHsKICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobW9kdWxlQnl0ZXMpOwogIGNvbnN0IGltcG9ydHMgPSBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpOwogIGNvbnN0IG1lbW9yeUltcG9ydCA9IGltcG9ydHNbMF07CiAgcmV0dXJuIHR5cGVvZiBtZW1vcnlJbXBvcnQudHlwZSA9PT0gIm9iamVjdCI7Cn0pKCk7CmZ1bmN0aW9uIHBvbHlmaWxsKFdlYkFzc2VtYmx5MikgewogIGlmIChoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0KSB7CiAgICByZXR1cm4gV2ViQXNzZW1ibHkyOwogIH0KICBjb25zdCBuZXdXZWJBc3NlbWJseSA9IHt9OwogIGZvciAoY29uc3Qga2V5IGluIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKFdlYkFzc2VtYmx5MikpIHsKICAgIG5ld1dlYkFzc2VtYmx5W2tleV0gPSBXZWJBc3NlbWJseTJba2V5XTsKICB9CiAgY29uc3QgcG9seWZpbGxlZEltcG9ydHNTeW1ib2wgPSBTeW1ib2woInBvbHlmaWxsZWRJbXBvcnRzU3ltYm9sIik7CiAgY29uc3QgYXNzaWduSW1wb3J0cyA9IChtb2R1bGUsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdID0gcGFyc2VJbXBvcnRzKHNvdXJjZUJ5dGVzKTsKICB9OwogIGNvbnN0IG5ld01vZHVsZSA9IG5ld1dlYkFzc2VtYmx5Lk1vZHVsZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICBjb25zdCBtb2R1bGUgPSBuZXcgV2ViQXNzZW1ibHkyLk1vZHVsZShieXRlcyk7CiAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZSwgbmV3TW9kdWxlLnByb3RvdHlwZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG5ld01vZHVsZS5wcm90b3R5cGUsIFdlYkFzc2VtYmx5Mi5Nb2R1bGUucHJvdG90eXBlKTsKICBuZXdXZWJBc3NlbWJseS5jb21waWxlID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkyLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBzb3VyY2UpOwogICAgcmV0dXJuIG1vZHVsZTsKICB9OwogIGlmIChXZWJBc3NlbWJseTIuY29tcGlsZVN0cmVhbWluZykgewogICAgbmV3V2ViQXNzZW1ibHkuY29tcGlsZVN0cmVhbWluZyA9IGFzeW5jIChzb3VyY2UpID0+IHsKICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzb3VyY2U7CiAgICAgIGNvbnN0IGNsb25lID0gcmVzcG9uc2UuY2xvbmUoKTsKICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkyLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgbmV3IFVpbnQ4QXJyYXkoYXdhaXQgY2xvbmUuYXJyYXlCdWZmZXIoKSkpOwogICAgICByZXR1cm4gbW9kdWxlOwogICAgfTsKICB9CiAgbmV3TW9kdWxlLmltcG9ydHMgPSAobW9kdWxlKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXTsKICAgIGlmICghcGFyc2VkSW1wb3J0cykgewogICAgICByZXR1cm4gV2ViQXNzZW1ibHkyLk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgICB9CiAgICByZXR1cm4gcGFyc2VkSW1wb3J0czsKICB9OwogIHJldHVybiBuZXdXZWJBc3NlbWJseTsKfQoKLy8gZW50cnlwb2ludC9jb21tb24udHMKZ2xvYmFsVGhpcy5XZWJBc3NlbWJseSA9IHBvbHlmaWxsKGdsb2JhbFRoaXMuV2ViQXNzZW1ibHkpOwp2YXIgTGluZURlY29kZXIgPSBjbGFzcyB7CiAgY29uc3RydWN0b3Iob25MaW5lKSB7CiAgICB0aGlzLmRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICB0aGlzLmJ1ZmZlciA9ICIiOwogICAgdGhpcy5vbkxpbmUgPSBvbkxpbmU7CiAgfQogIGRlY29kZXI7CiAgYnVmZmVyOwogIG9uTGluZTsKICBzZW5kKGNodW5rKSB7CiAgICB0aGlzLmJ1ZmZlciArPSB0aGlzLmRlY29kZXIuZGVjb2RlKGNodW5rLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgIGNvbnN0IGxpbmVzID0gdGhpcy5idWZmZXIuc3BsaXQoIlxuIik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykgewogICAgICB0aGlzLm9uTGluZShsaW5lc1tpXSk7CiAgICB9CiAgICB0aGlzLmJ1ZmZlciA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdOwogIH0KfTsKdmFyIFdhc21SdW5uZXIgPSAocmF3T3B0aW9ucywgU3dpZnRSdW50aW1lKSA9PiB7CiAgY29uc3Qgb3B0aW9ucyA9IGRlZmF1bHRSdW5uZXJPcHRpb25zKHJhd09wdGlvbnMpOwogIGxldCBzd2lmdDsKICBpZiAoU3dpZnRSdW50aW1lKSB7CiAgICBzd2lmdCA9IG5ldyBTd2lmdFJ1bnRpbWUoKTsKICB9CiAgbGV0IHN0ZG91dExpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRvdXRMaW5lICE9IG51bGwpIHsKICAgIHN0ZG91dExpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZG91dExpbmUpOwogIH0KICBjb25zdCBzdGRvdXQgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRvdXQ/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRvdXRMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBsZXQgc3RkZXJyTGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZGVyckxpbmUgIT0gbnVsbCkgewogICAgc3RkZXJyTGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3RkZXJyTGluZSk7CiAgfQogIGNvbnN0IHN0ZGVyciA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZGVycj8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZGVyckxpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGNvbnN0IGFyZ3MgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzLCBlbnZzLCBmZHMsIHsKICAgIGRlYnVnOiBmYWxzZQogIH0pOwogIGNvbnN0IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QgPSAoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QgPSB7CiAgICAgIHdhc2lfc25hcHNob3RfcHJldmlldzE6IHdhc2kud2FzaUltcG9ydAogICAgfTsKICAgIGlmIChzd2lmdCkgewogICAgICBpbXBvcnRPYmplY3QuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgaWYgKCFpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgX2ltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKG1vZHVsZSkpIHsKICAgICAgY29uc3QgaW1wb3J0RW50cnkgPSBfaW1wb3J0RW50cnk7CiAgICAgIGlmICghaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXSA9IHt9OwogICAgICB9CiAgICAgIGlmIChpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSkgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJmdW5jdGlvbiIpIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfSBlbHNlIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJtZW1vcnkiICYmIGltcG9ydEVudHJ5Lm1vZHVsZSA9PSAiZW52IiAmJiBpbXBvcnRFbnRyeS5uYW1lID09ICJtZW1vcnkiKSB7CiAgICAgICAgY29uc3QgdHlwZSA9IGltcG9ydEVudHJ5LnR5cGU7CiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsKICAgICAgICAgIGluaXRpYWw6IHR5cGUubWluaW11bSwKICAgICAgICAgIG1heGltdW06IHR5cGUubWF4aW11bSwKICAgICAgICAgIHNoYXJlZDogdHlwZS5zaGFyZWQKICAgICAgICB9OwogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gbmV3IFdlYkFzc2VtYmx5Lk1lbW9yeShkZXNjcmlwdG9yKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGltcG9ydE9iamVjdDsKICB9OwogIHJldHVybiB7CiAgICBhc3luYyBydW4od2FzbUJ5dGVzLCBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGlmICghZXh0cmFXYXNtSW1wb3J0cykgewogICAgICAgIGV4dHJhV2FzbUltcG9ydHMgPSB7fTsKICAgICAgfQogICAgICBleHRyYVdhc21JbXBvcnRzLl9fc3RhY2tfc2FuaXRpemVyID0gewogICAgICAgIHJlcG9ydF9zdGFja19vdmVyZmxvdzogKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJEZXRlY3RlZCBzdGFjayBidWZmZXIgb3ZlcmZsb3cuIik7CiAgICAgICAgfQogICAgICB9OwogICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseS5jb21waWxlKHdhc21CeXRlcyk7CiAgICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKTsKICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBXZWJBc3NlbWJseS5pbnN0YW50aWF0ZShtb2R1bGUsIGltcG9ydE9iamVjdCk7CiAgICAgIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICAgICAgc3dpZnQuc2V0SW5zdGFuY2UoaW5zdGFuY2UpOwogICAgICB9CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLnN0YXJ0KGluc3RhbmNlKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgICAgICBpZiAoc3dpZnQgJiYgc3dpZnQubWFpbikgewogICAgICAgICAgc3dpZnQubWFpbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMubWFpbiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YoMCwgMCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKfTsKdmFyIGRlZmF1bHRSdW5uZXJPcHRpb25zID0gKG9wdGlvbnMpID0+IHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIHJldHVybiBvcHRpb25zOwp9OwoKLy8gZW50cnlwb2ludC90ZXN0LnRzCnZhciBzb2NrZXQgPSBuZXcgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdChgd3M6Ly8ke2xvY2F0aW9uLmhvc3R9L3dhdGNoZXJgKTsKc29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCAobWVzc2FnZSkgPT4gewogIGlmIChtZXNzYWdlLmRhdGEgPT09ICJyZWxvYWQiKSB7CiAgICBsb2NhdGlvbi5yZWxvYWQoKTsKICB9Cn0pOwp2YXIgc3RhcnRXYXNpVGFzayA9IGFzeW5jICgpID0+IHsKICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCIvbWFpbi53YXNtIik7CiAgY29uc3QgcmVzcG9uc2VBcnJheUJ1ZmZlciA9IGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICB9IGNhdGNoIHsKICAgIGNvbnNvbGUubG9nKCJKYXZhU2NyaXB0S2l0IG1vZHVsZSBub3QgYXZhaWxhYmxlLCBydW5uaW5nIHdpdGhvdXQgSmF2YVNjcmlwdEtpdCBydW50aW1lLiIpOwogIH0KICBjb25zdCBjb25maWcgPSBhd2FpdCBmZXRjaCgiL3Byb2Nlc3MtaW5mby5qc29uIikudGhlbigocmVzcG9uc2UyKSA9PiByZXNwb25zZTIuanNvbigpKTsKICBsZXQgdGVzdFJ1bk91dHB1dCA9ICIiOwogIGNvbnN0IHdhc21SdW5uZXIgPSBXYXNtUnVubmVyKHsKICAgIGVudjogY29uZmlnLmVudiwKICAgIG9uU3Rkb3V0TGluZTogKGxpbmUpID0+IHsKICAgICAgY29uc29sZS5sb2cobGluZSk7CiAgICAgIHRlc3RSdW5PdXRwdXQgKz0gbGluZSArICJcbiI7CiAgICB9LAogICAgb25TdGRlcnJMaW5lOiAobGluZSkgPT4gewogICAgICBjb25zb2xlLmVycm9yKGxpbmUpOwogICAgfQogIH0sIHJ1bnRpbWVDb25zdHJ1Y3Rvcik7CiAgY29uc3Qgd2FzbUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkocmVzcG9uc2VBcnJheUJ1ZmZlcikuYnVmZmVyOwogIGNvbnN0IGhhbmRsZUV4aXRPckVycm9yID0gKGVycm9yKSA9PiB7CiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBXQVNJUHJvY0V4aXQpIHsKICAgICAgc29ja2V0LnNlbmQoSlNPTi5zdHJpbmdpZnkoeyBraW5kOiAidGVzdFJ1bk91dHB1dCIsIHRlc3RSdW5PdXRwdXQgfSkpOwogICAgICBpZiAoZXJyb3IuY29kZSA9PT0gMCkgewogICAgICAgIHNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KHsga2luZDogInRlc3RQYXNzZWQiIH0pKTsKICAgICAgfSBlbHNlIHsKICAgICAgICBoYW5kbGVFcnJvcihlcnJvcik7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIGhhbmRsZUVycm9yKGVycm9yKTsKICAgIH0KICAgIGNvbnN0IGRpdkVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCJwIik7CiAgICBkaXZFbGVtZW50LmlubmVySFRNTCA9ICJUZXN0IHJ1biBmaW5pc2hlZC4gQ2hlY2sgdGhlIG91dHB1dCBvZiA8Y29kZT5jYXJ0b24gdGVzdDwvY29kZT4gZm9yIGRldGFpbHMuIjsKICAgIGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoZGl2RWxlbWVudCk7CiAgfTsKICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigidW5oYW5kbGVkcmVqZWN0aW9uIiwgKGV2ZW50KSA9PiB7CiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOwogICAgY29uc3QgZXJyb3IgPSBldmVudC5yZWFzb247CiAgICBoYW5kbGVFeGl0T3JFcnJvcihlcnJvcik7CiAgfSk7CiAgdHJ5IHsKICAgIGF3YWl0IHdhc21SdW5uZXIucnVuKHdhc21CeXRlcyk7CiAgfSBjYXRjaCAoZXJyb3IpIHsKICAgIGhhbmRsZUV4aXRPckVycm9yKGVycm9yKTsKICAgIHJldHVybjsKICB9Cn07CmZ1bmN0aW9uIGhhbmRsZUVycm9yKGUpIHsKICBjb25zb2xlLmVycm9yKGUpOwogIGlmIChlIGluc3RhbmNlb2YgRXJyb3IpIHsKICAgIGNvbnN0IHN0YWNrID0gZS5zdGFjazsKICAgIGlmIChzdGFjayAhPSBudWxsKSB7CiAgICAgIHNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KHsKICAgICAgICBraW5kOiAic3RhY2tUcmFjZSIsCiAgICAgICAgc3RhY2tUcmFjZTogc3RhY2sKICAgICAgfSkpOwogICAgfQogIH0KICBzb2NrZXQuc2VuZChKU09OLnN0cmluZ2lmeSh7CiAgICBraW5kOiAiZXJyb3JSZXBvcnQiLAogICAgZXJyb3JSZXBvcnQ6IGUudG9TdHJpbmcoKQogIH0pKTsKfQphc3luYyBmdW5jdGlvbiBtYWluKCkgewogIHRyeSB7CiAgICBhd2FpdCBzdGFydFdhc2lUYXNrKCk7CiAgfSBjYXRjaCAoZSkgewogICAgaGFuZGxlRXJyb3IoZSk7CiAgfQp9Cm1haW4oKTsKLyohCiAqIFJlY29ubmVjdGluZyBXZWJTb2NrZXQKICogYnkgUGVkcm8gTGFkYXJpYSA8cGVkcm8ubGFkYXJpYUBnbWFpbC5jb20+CiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9wbGFkYXJpYS9yZWNvbm5lY3Rpbmctd2Vic29ja2V0CiAqIExpY2Vuc2UgTUlUCiAqLwovKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UKdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUKTGljZW5zZSBhdCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKClRISVMgQ09ERSBJUyBQUk9WSURFRCBPTiBBTiAqQVMgSVMqIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBBTlkgSU1QTElFRApXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLApNRVJDSEFOVEFCTElUWSBPUiBOT04tSU5GUklOR0VNRU5ULgoKU2VlIHRoZSBBcGFjaGUgVmVyc2lvbiAyLjAgTGljZW5zZSBmb3Igc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zCmFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8K")! - public static let testNode: Data = Data(base64Encoded: "dmFyIF9fY3JlYXRlID0gT2JqZWN0LmNyZWF0ZTsKdmFyIF9fZGVmUHJvcCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTsKdmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOwp2YXIgX19nZXRPd25Qcm9wTmFtZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lczsKdmFyIF9fZ2V0UHJvdG9PZiA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjsKdmFyIF9faGFzT3duUHJvcCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7CnZhciBfX2NvcHlQcm9wcyA9ICh0bywgZnJvbSwgZXhjZXB0LCBkZXNjKSA9PiB7CiAgaWYgKGZyb20gJiYgdHlwZW9mIGZyb20gPT09ICJvYmplY3QiIHx8IHR5cGVvZiBmcm9tID09PSAiZnVuY3Rpb24iKSB7CiAgICBmb3IgKGxldCBrZXkgb2YgX19nZXRPd25Qcm9wTmFtZXMoZnJvbSkpCiAgICAgIGlmICghX19oYXNPd25Qcm9wLmNhbGwodG8sIGtleSkgJiYga2V5ICE9PSBleGNlcHQpCiAgICAgICAgX19kZWZQcm9wKHRvLCBrZXksIHsgZ2V0OiAoKSA9PiBmcm9tW2tleV0sIGVudW1lcmFibGU6ICEoZGVzYyA9IF9fZ2V0T3duUHJvcERlc2MoZnJvbSwga2V5KSkgfHwgZGVzYy5lbnVtZXJhYmxlIH0pOwogIH0KICByZXR1cm4gdG87Cn07CnZhciBfX3RvRVNNID0gKG1vZCwgaXNOb2RlTW9kZSwgdGFyZ2V0KSA9PiAodGFyZ2V0ID0gbW9kICE9IG51bGwgPyBfX2NyZWF0ZShfX2dldFByb3RvT2YobW9kKSkgOiB7fSwgX19jb3B5UHJvcHMoaXNOb2RlTW9kZSB8fCAhbW9kIHx8ICFtb2QuX19lc01vZHVsZSA/IF9fZGVmUHJvcCh0YXJnZXQsICJkZWZhdWx0IiwgeyB2YWx1ZTogbW9kLCBlbnVtZXJhYmxlOiB0cnVlIH0pIDogdGFyZ2V0LCBtb2QpKTsKCi8vIGVudHJ5cG9pbnQvdGVzdE5vZGUudHMKdmFyIGltcG9ydF9wcm9taXNlcyA9IF9fdG9FU00ocmVxdWlyZSgiZnMvcHJvbWlzZXMiKSk7CnZhciBpbXBvcnRfcGF0aCA9IF9fdG9FU00ocmVxdWlyZSgicGF0aCIpKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJnczIsIGVudiwgZmRzLCBvcHRpb25zID0ge30pIHsKICAgIHRoaXMuYXJncyA9IFtdOwogICAgdGhpcy5lbnYgPSBbXTsKICAgIHRoaXMuZmRzID0gW107CiAgICBkZWJ1Zy5lbmFibGUob3B0aW9ucy5kZWJ1Zyk7CiAgICB0aGlzLmFyZ3MgPSBhcmdzMjsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfZ2V0KGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aDIpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X3NldF90aW1lcyhmbGFncywgcGF0aDIsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgyKTsKICAgICAgICBjb25zdCB7IHJldCwgZmRfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoMiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aDIpOwogICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9yZWFkbGluayhwYXRoMik7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoMiA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZW5hbWUoZmQsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgbGV0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3VubGluayhvbGRfcGF0aCk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXQgPSBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKTsKICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgIGlmIChzZWxmLmZkc1tmZF0ucGF0aF9saW5rKG9sZF9wYXRoLCBpbm9kZV9vYmosIHRydWUpICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgdGhyb3cgInBhdGhfbGluayBzaG91bGQgYWx3YXlzIHJldHVybiBzdWNjZXNzIHdoZW4gcmVsaW5raW5nIGFuIGlub2RlIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHBsYWNlIjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9zeW1saW5rKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBmZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3VubGlua19maWxlKGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgyLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoMiwgaW5vZGUsIGFsbG93X2RpcikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF91bmxpbmsocGF0aDIpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aDIsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aDIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogIH0KICBwYXRoX3JlYWRsaW5rKHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KfTsKdmFyIElub2RlID0gY2xhc3Mgewp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mc19tZW0uanMKdmFyIE9wZW5GaWxlID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IG9mZnNldCArIGxlbikgewogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgbGVuKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgMCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gc2l6ZSkgewogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KHRoaXMuZmlsZS5kYXRhLmJ1ZmZlci5zbGljZSgwLCBOdW1iZXIoc2l6ZSkpKTsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHNpemUpKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKHRoaXMuZmlsZV9wb3MpLCBOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChzaXplKSkpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoc2xpY2UubGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcihvZmZzZXQpLCBOdW1iZXIob2Zmc2V0ICsgQmlnSW50KHNpemUpKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIGxldCBjYWxjdWxhdGVkX29mZnNldDsKICAgIHN3aXRjaCAod2hlbmNlKSB7CiAgICAgIGNhc2UgV0hFTkNFX1NFVDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfQ1VSOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gdGhpcy5maWxlX3BvcyArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfRU5EOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gQmlnSW50KHRoaXMuZmlsZS5kYXRhLmJ5dGVMZW5ndGgpICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIGlmIChjYWxjdWxhdGVkX29mZnNldCA8IDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgdGhpcy5maWxlX3BvcyA9IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmICh0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcih0aGlzLmZpbGVfcG9zKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmIChvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIob2Zmc2V0KSk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5maWxlLnN0YXQoKSB9OwogIH0KICBjb25zdHJ1Y3RvcihmaWxlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5maWxlX3BvcyA9IDBuOwogICAgdGhpcy5maWxlID0gZmlsZTsKICB9Cn07CnZhciBPcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgIGRlYnVnLmxvZygicmVhZGRpcl9zaW5nbGUiLCBjb29raWUpOwogICAgICBkZWJ1Zy5sb2coY29va2llLCB0aGlzLmRpci5jb250ZW50cy5rZXlzKCkpOwogICAgfQogICAgaWYgKGNvb2tpZSA9PSAwbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgxbiwgIi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9IGVsc2UgaWYgKGNvb2tpZSA9PSAxbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgybiwgIi4uIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfQogICAgaWYgKGNvb2tpZSA+PSBCaWdJbnQodGhpcy5kaXIuY29udGVudHMuc2l6ZSkgKyAybikgewogICAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbnVsbCB9OwogICAgfQogICAgY29uc3QgW25hbWUsIGVudHJ5XSA9IEFycmF5LmZyb20odGhpcy5kaXIuY29udGVudHMuZW50cmllcygpKVtOdW1iZXIoY29va2llIC0gMm4pXTsKICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBuZXcgRGlyZW50KGNvb2tpZSArIDFuLCBuYW1lLCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUpIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfZXJyLCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiBlbnRyeS5zdGF0KCkgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aF9zdHIsIGRpcmZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aF9zdHIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIGlmIChyZXQgIT0gRVJSTk9fTk9FTlQpIHsKICAgICAgICByZXR1cm4geyByZXQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0NSRUFUKSA9PSBPRkxBR1NfQ1JFQVQpIHsKICAgICAgICBjb25zdCB7IHJldDogcmV0MiwgZW50cnk6IG5ld19lbnRyeSB9ID0gdGhpcy5kaXIuY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCAob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSk7CiAgICAgICAgaWYgKG5ld19lbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4geyByZXQ6IHJldDIsIGZkX29iajogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBlbnRyeSA9IG5ld19lbnRyeTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgfSBlbHNlIGlmICgob2ZsYWdzICYgT0ZMQUdTX0VYQ0wpID09IE9GTEFHU19FWENMKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiBlbnRyeS5wYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpOwogIH0KICBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoMiwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoMi5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aDIsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICBjb25zdCBzb3VyY2VfaXNfZGlyID0gaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgY29uc3QgdGFyZ2V0X2lzX2RpciA9IGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGlmIChzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICBpZiAoYWxsb3dfZGlyICYmIGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB7CiAgICAgICAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSA9PSAwKSB7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoc291cmNlX2lzX2RpciAmJiAhdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICAgIH0gZWxzZSBpZiAoIXNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgICAgfSBlbHNlIGlmIChpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUpIHsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgIH0KICAgIH0KICAgIGlmICghYWxsb3dfZGlyICYmIGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX1BFUk07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBpbm9kZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF91bmxpbmsocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmICghKGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB8fCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgfQogICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgIT09IDApIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgfQogICAgaWYgKCFwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKSkgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5kaXIuc3RhdCgpIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgY29uc3RydWN0b3IoZGlyKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kaXIgPSBkaXI7CiAgfQp9Owp2YXIgUHJlb3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgT3BlbkRpcmVjdG9yeSB7CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIHByZXN0YXQ6IFByZXN0YXQuZGlyKHRoaXMucHJlc3RhdF9uYW1lKSB9OwogIH0KICBjb25zdHJ1Y3RvcihuYW1lLCBjb250ZW50cykgewogICAgc3VwZXIobmV3IERpcmVjdG9yeShjb250ZW50cykpOwogICAgdGhpcy5wcmVzdGF0X25hbWUgPSBuYW1lOwogIH0KfTsKdmFyIEZpbGUgPSBjbGFzcyBleHRlbmRzIElub2RlIHsKICBwYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpIHsKICAgIGlmICh0aGlzLnJlYWRvbmx5ICYmIChmc19yaWdodHNfYmFzZSAmIEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSA9PSBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfVFJVTkMpID09IE9GTEFHU19UUlVOQykgewogICAgICBpZiAodGhpcy5yZWFkb25seSkKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShbXSk7CiAgICB9CiAgICBjb25zdCBmaWxlID0gbmV3IE9wZW5GaWxlKHRoaXMpOwogICAgaWYgKGZkX2ZsYWdzICYgRkRGTEFHU19BUFBFTkQpCiAgICAgIGZpbGUuZmRfc2VlaygwbiwgV0hFTkNFX0VORCk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogZmlsZSB9OwogIH0KICBnZXQgc2l6ZSgpIHsKICAgIHJldHVybiBCaWdJbnQodGhpcy5kYXRhLmJ5dGVMZW5ndGgpOwogIH0KICBzdGF0KCkgewogICAgcmV0dXJuIG5ldyBGaWxlc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIHRoaXMuc2l6ZSk7CiAgfQogIGNvbnN0cnVjdG9yKGRhdGEsIG9wdGlvbnMpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShkYXRhKTsKICAgIHRoaXMucmVhZG9ubHkgPSAhIW9wdGlvbnM/LnJlYWRvbmx5OwogIH0KfTsKdmFyIFBhdGggPSBjbGFzcyBQYXRoMiB7CiAgc3RhdGljIGZyb20ocGF0aDIpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aDIuZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoMi5zdGFydHNXaXRoKCIvIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICB9CiAgICBpZiAocGF0aDIuaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aDIuc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aDIpIHsKICAgIGxldCBlbnRyeSA9IHRoaXM7CiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiBwYXRoMi5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgYWxsb3dfdW5kZWZpbmVkKSB7CiAgICBjb25zdCBmaWxlbmFtZSA9IHBhdGgyLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH07CiAgfQogIGNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgaXNfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBkZWJ1Zy5sb2coImNyZWF0ZSIsIHBhdGgyKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvaW5kZXguanMKZnVuY3Rpb24gcGFyc2VJbXBvcnRzKG1vZHVsZUJ5dGVzKSB7CiAgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcyk7CiAgfSBlbHNlIGlmIChtb2R1bGVCeXRlcy5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcy5idWZmZXIpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoIkFyZ3VtZW50IG11c3QgYmUgYSBidWZmZXIgc291cmNlLCBsaWtlIFVpbnQ4QXJyYXkgb3IgQXJyYXlCdWZmZXIiKTsKICB9CiAgY29uc3QgcGFyc2VTdGF0ZSA9IG5ldyBQYXJzZVN0YXRlKG1vZHVsZUJ5dGVzKTsKICBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpOwogIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKTsKICBjb25zdCB0eXBlcyA9IFtdOwogIGNvbnN0IGltcG9ydHMgPSBbXTsKICB3aGlsZSAocGFyc2VTdGF0ZS5oYXNNb3JlQnl0ZXMoKSkgewogICAgY29uc3Qgc2VjdGlvbklkID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgY29uc3Qgc2VjdGlvblNpemUgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgc3dpdGNoIChzZWN0aW9uSWQpIHsKICAgICAgY2FzZSAxOiB7CiAgICAgICAgY29uc3QgdHlwZUNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVDb3VudDsgaSsrKSB7CiAgICAgICAgICB0eXBlcy5wdXNoKHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAyOiB7CiAgICAgICAgY29uc3QgaW1wb3J0Q291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW1wb3J0Q291bnQ7IGkrKykgewogICAgICAgICAgY29uc3QgbW9kdWxlMiA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlOiBtb2R1bGUyLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGU6IG1vZHVsZTIsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlOiBtb2R1bGUyLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGU6IG1vZHVsZTIsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZTIgPSBuZXcgV2ViQXNzZW1ibHkuTW9kdWxlKG1vZHVsZUJ5dGVzKTsKICBjb25zdCBpbXBvcnRzID0gV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMobW9kdWxlMik7CiAgY29uc3QgbWVtb3J5SW1wb3J0ID0gaW1wb3J0c1swXTsKICByZXR1cm4gdHlwZW9mIG1lbW9yeUltcG9ydC50eXBlID09PSAib2JqZWN0IjsKfSkoKTsKZnVuY3Rpb24gcG9seWZpbGwoV2ViQXNzZW1ibHkyKSB7CiAgaWYgKGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQpIHsKICAgIHJldHVybiBXZWJBc3NlbWJseTI7CiAgfQogIGNvbnN0IG5ld1dlYkFzc2VtYmx5ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoV2ViQXNzZW1ibHkyKSkgewogICAgbmV3V2ViQXNzZW1ibHlba2V5XSA9IFdlYkFzc2VtYmx5MltrZXldOwogIH0KICBjb25zdCBwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbCA9IFN5bWJvbCgicG9seWZpbGxlZEltcG9ydHNTeW1ib2wiKTsKICBjb25zdCBhc3NpZ25JbXBvcnRzID0gKG1vZHVsZTIsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGUyW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXSA9IHBhcnNlSW1wb3J0cyhzb3VyY2VCeXRlcyk7CiAgfTsKICBjb25zdCBuZXdNb2R1bGUgPSBuZXdXZWJBc3NlbWJseS5Nb2R1bGUgPSBmdW5jdGlvbihieXRlcykgewogICAgY29uc3QgbW9kdWxlMiA9IG5ldyBXZWJBc3NlbWJseTIuTW9kdWxlKGJ5dGVzKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlMiwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZTIsIG5ld01vZHVsZS5wcm90b3R5cGUpOwogICAgcmV0dXJuIG1vZHVsZTI7CiAgfTsKICBPYmplY3Quc2V0UHJvdG90eXBlT2YobmV3TW9kdWxlLnByb3RvdHlwZSwgV2ViQXNzZW1ibHkyLk1vZHVsZS5wcm90b3R5cGUpOwogIG5ld1dlYkFzc2VtYmx5LmNvbXBpbGUgPSBhc3luYyAoc291cmNlKSA9PiB7CiAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkyLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlMiwgc291cmNlKTsKICAgIHJldHVybiBtb2R1bGUyOwogIH07CiAgaWYgKFdlYkFzc2VtYmx5Mi5jb21waWxlU3RyZWFtaW5nKSB7CiAgICBuZXdXZWJBc3NlbWJseS5jb21waWxlU3RyZWFtaW5nID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNvdXJjZTsKICAgICAgY29uc3QgY2xvbmUgPSByZXNwb25zZS5jbG9uZSgpOwogICAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkyLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZTIsIG5ldyBVaW50OEFycmF5KGF3YWl0IGNsb25lLmFycmF5QnVmZmVyKCkpKTsKICAgICAgcmV0dXJuIG1vZHVsZTI7CiAgICB9OwogIH0KICBuZXdNb2R1bGUuaW1wb3J0cyA9IChtb2R1bGUyKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlMltwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbF07CiAgICBpZiAoIXBhcnNlZEltcG9ydHMpIHsKICAgICAgcmV0dXJuIFdlYkFzc2VtYmx5Mi5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUyKTsKICAgIH0KICAgIHJldHVybiBwYXJzZWRJbXBvcnRzOwogIH07CiAgcmV0dXJuIG5ld1dlYkFzc2VtYmx5Owp9CgovLyBlbnRyeXBvaW50L2NvbW1vbi50cwpnbG9iYWxUaGlzLldlYkFzc2VtYmx5ID0gcG9seWZpbGwoZ2xvYmFsVGhpcy5XZWJBc3NlbWJseSk7CnZhciBMaW5lRGVjb2RlciA9IGNsYXNzIHsKICBjb25zdHJ1Y3RvcihvbkxpbmUpIHsKICAgIHRoaXMuZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIHRoaXMuYnVmZmVyID0gIiI7CiAgICB0aGlzLm9uTGluZSA9IG9uTGluZTsKICB9CiAgZGVjb2RlcjsKICBidWZmZXI7CiAgb25MaW5lOwogIHNlbmQoY2h1bmspIHsKICAgIHRoaXMuYnVmZmVyICs9IHRoaXMuZGVjb2Rlci5kZWNvZGUoY2h1bmssIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgY29uc3QgbGluZXMgPSB0aGlzLmJ1ZmZlci5zcGxpdCgiXG4iKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoIC0gMTsgaSsrKSB7CiAgICAgIHRoaXMub25MaW5lKGxpbmVzW2ldKTsKICAgIH0KICAgIHRoaXMuYnVmZmVyID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV07CiAgfQp9Owp2YXIgV2FzbVJ1bm5lciA9IChyYXdPcHRpb25zLCBTd2lmdFJ1bnRpbWUpID0+IHsKICBjb25zdCBvcHRpb25zID0gZGVmYXVsdFJ1bm5lck9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0OwogIGlmIChTd2lmdFJ1bnRpbWUpIHsKICAgIHN3aWZ0ID0gbmV3IFN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJnczIgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzMiwgZW52cywgZmRzLCB7CiAgICBkZWJ1ZzogZmFsc2UKICB9KTsKICBjb25zdCBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0ID0gKGV4dHJhV2FzbUltcG9ydHMsIG1vZHVsZTIpID0+IHsKICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IHsKICAgICAgd2FzaV9zbmFwc2hvdF9wcmV2aWV3MTogd2FzaS53YXNpSW1wb3J0CiAgICB9OwogICAgaWYgKHN3aWZ0KSB7CiAgICAgIGltcG9ydE9iamVjdC5qYXZhc2NyaXB0X2tpdCA9IHN3aWZ0Lndhc21JbXBvcnRzOwogICAgfQogICAgaWYgKGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgZm9yIChjb25zdCBtb2R1bGVOYW1lIGluIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgICBpZiAoIWltcG9ydE9iamVjdFttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdID0ge307CiAgICAgICAgfQogICAgICAgIGZvciAoY29uc3QgZW50cnkgaW4gZXh0cmFXYXNtSW1wb3J0c1ttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdW2VudHJ5XSA9IGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV1bZW50cnldOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZm9yIChjb25zdCBfaW1wb3J0RW50cnkgb2YgV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMobW9kdWxlMikpIHsKICAgICAgY29uc3QgaW1wb3J0RW50cnkgPSBfaW1wb3J0RW50cnk7CiAgICAgIGlmICghaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXSA9IHt9OwogICAgICB9CiAgICAgIGlmIChpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSkgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJmdW5jdGlvbiIpIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfSBlbHNlIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJtZW1vcnkiICYmIGltcG9ydEVudHJ5Lm1vZHVsZSA9PSAiZW52IiAmJiBpbXBvcnRFbnRyeS5uYW1lID09ICJtZW1vcnkiKSB7CiAgICAgICAgY29uc3QgdHlwZSA9IGltcG9ydEVudHJ5LnR5cGU7CiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsKICAgICAgICAgIGluaXRpYWw6IHR5cGUubWluaW11bSwKICAgICAgICAgIG1heGltdW06IHR5cGUubWF4aW11bSwKICAgICAgICAgIHNoYXJlZDogdHlwZS5zaGFyZWQKICAgICAgICB9OwogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gbmV3IFdlYkFzc2VtYmx5Lk1lbW9yeShkZXNjcmlwdG9yKTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIGltcG9ydE9iamVjdDsKICB9OwogIHJldHVybiB7CiAgICBhc3luYyBydW4od2FzbUJ5dGVzLCBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGlmICghZXh0cmFXYXNtSW1wb3J0cykgewogICAgICAgIGV4dHJhV2FzbUltcG9ydHMgPSB7fTsKICAgICAgfQogICAgICBleHRyYVdhc21JbXBvcnRzLl9fc3RhY2tfc2FuaXRpemVyID0gewogICAgICAgIHJlcG9ydF9zdGFja19vdmVyZmxvdzogKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCJEZXRlY3RlZCBzdGFjayBidWZmZXIgb3ZlcmZsb3cuIik7CiAgICAgICAgfQogICAgICB9OwogICAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkuY29tcGlsZSh3YXNtQnl0ZXMpOwogICAgICBjb25zdCBpbXBvcnRPYmplY3QgPSBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0KGV4dHJhV2FzbUltcG9ydHMsIG1vZHVsZTIpOwogICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IFdlYkFzc2VtYmx5Lmluc3RhbnRpYXRlKG1vZHVsZTIsIGltcG9ydE9iamVjdCk7CiAgICAgIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICAgICAgc3dpZnQuc2V0SW5zdGFuY2UoaW5zdGFuY2UpOwogICAgICB9CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLnN0YXJ0KGluc3RhbmNlKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgICAgICBpZiAoc3dpZnQgJiYgc3dpZnQubWFpbikgewogICAgICAgICAgc3dpZnQubWFpbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMubWFpbiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YoMCwgMCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKfTsKdmFyIGRlZmF1bHRSdW5uZXJPcHRpb25zID0gKG9wdGlvbnMpID0+IHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIHJldHVybiBvcHRpb25zOwp9OwoKLy8gZW50cnlwb2ludC90ZXN0Tm9kZS50cwp2YXIgYXJncyA9IFsuLi5wcm9jZXNzLmFyZ3ZdOwphcmdzLnNoaWZ0KCk7CmFyZ3Muc2hpZnQoKTsKdmFyIFt3YXNtRmlsZSwgLi4udGVzdEFyZ3NdID0gYXJnczsKdGVzdEFyZ3MudW5zaGlmdChpbXBvcnRfcGF0aC5kZWZhdWx0LmJhc2VuYW1lKHdhc21GaWxlKSk7CmlmICghd2FzbUZpbGUpIHsKICB0aHJvdyBFcnJvcigiTm8gV0FTTSB0ZXN0IGZpbGUgc3BlY2lmaWVkLCBjYW4gbm90IHJ1biB0ZXN0cyIpOwp9CnZhciBzdGFydFdhc2lUYXNrID0gYXN5bmMgKCkgPT4gewogIGNvbnN0IHdhc21CeXRlcyA9IGF3YWl0IGltcG9ydF9wcm9taXNlcy5kZWZhdWx0LnJlYWRGaWxlKHdhc21GaWxlKTsKICBsZXQgcnVudGltZUNvbnN0cnVjdG9yID0gdm9pZCAwOwogIHRyeSB7CiAgICBjb25zdCB7IFN3aWZ0UnVudGltZSB9ID0gYXdhaXQgaW1wb3J0KAogICAgICAvLyBAdHMtaWdub3JlCiAgICAgICIuL0phdmFTY3JpcHRLaXRfSmF2YVNjcmlwdEtpdC5yZXNvdXJjZXMvUnVudGltZS9pbmRleC5tanMiCiAgICApOwogICAgcnVudGltZUNvbnN0cnVjdG9yID0gU3dpZnRSdW50aW1lOwogICAgZ2xvYmFsLnJlcXVpcmUgPSByZXF1aXJlOwogIH0gY2F0Y2ggewogIH0KICBjb25zdCBlbnYgPSB7fTsKICBmb3IgKGNvbnN0IGtleSBpbiBwcm9jZXNzLmVudikgewogICAgY29uc3QgdmFsdWUgPSBwcm9jZXNzLmVudltrZXldOwogICAgaWYgKHZhbHVlKSB7CiAgICAgIGVudltrZXldID0gdmFsdWU7CiAgICB9CiAgfQogIGNvbnN0IHdhc21SdW5uZXIgPSBXYXNtUnVubmVyKHsKICAgIGFyZ3M6IHRlc3RBcmdzLAogICAgZW52LAogICAgb25TdGRvdXRMaW5lOiAobGluZSkgPT4gewogICAgICBjb25zb2xlLmxvZyhsaW5lKTsKICAgIH0sCiAgICBvblN0ZGVyckxpbmU6IChsaW5lKSA9PiB7CiAgICAgIGNvbnNvbGUuZXJyb3IobGluZSk7CiAgICB9CiAgfSwgcnVudGltZUNvbnN0cnVjdG9yKTsKICBsZXQgcHJvY0V4aXRDYWxsZWQgPSBmYWxzZTsKICBwcm9jZXNzLm9uKCJiZWZvcmVFeGl0IiwgKCkgPT4gewogICAgaWYgKCFwcm9jRXhpdENhbGxlZCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlc3QgaGFybmVzcyBwcm9jZXNzIGV4aXRlZCBiZWZvcmUgdGVzdCBwcm9jZXNzLgpUaGlzIHVzdWFsbHkgbWVhbnMgdGhlcmUgYXJlIHNvbWUgZGFuZ2xpbmcgY29udGludWF0aW9ucywgd2hpY2ggYXJlIGF3YWl0ZWQgYnV0IG5ldmVyIHJlc3VtZWQuYCk7CiAgICB9CiAgfSk7CiAgYXdhaXQgd2FzbVJ1bm5lci5ydW4od2FzbUJ5dGVzLCB7CiAgICAid2FzaV9zbmFwc2hvdF9wcmV2aWV3MSI6IHsKICAgICAgcHJvY19leGl0OiAoY29kZSkgPT4gewogICAgICAgIHByb2NFeGl0Q2FsbGVkID0gdHJ1ZTsKICAgICAgICBwcm9jZXNzLmV4aXQoY29kZSk7CiAgICAgIH0KICAgIH0KICB9KTsKfTsKc3RhcnRXYXNpVGFzaygpLmNhdGNoKChlKSA9PiB7CiAgdGhyb3cgZTsKfSk7Cg==")! + public static let dev: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL3JlY29ubmVjdGluZy13ZWJzb2NrZXQvZGlzdC9yZWNvbm5lY3Rpbmctd2Vic29ja2V0LW1qcy5qcwp2YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24oZDIsIGIyKSB7CiAgICBkMi5fX3Byb3RvX18gPSBiMjsKICB9IHx8IGZ1bmN0aW9uKGQyLCBiMikgewogICAgZm9yICh2YXIgcCBpbiBiMikKICAgICAgaWYgKGIyLmhhc093blByb3BlcnR5KHApKQogICAgICAgIGQyW3BdID0gYjJbcF07CiAgfTsKICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKfTsKZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzKGQsIGIpOwogIGZ1bmN0aW9uIF9fKCkgewogICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7CiAgfQogIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKfQpmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7CiAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSAiZnVuY3Rpb24iICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7CiAgaWYgKG0pCiAgICByZXR1cm4gbS5jYWxsKG8pOwogIHJldHVybiB7CiAgICBuZXh0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkKICAgICAgICBvID0gdm9pZCAwOwogICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07CiAgICB9CiAgfTsKfQpmdW5jdGlvbiBfX3JlYWQobywgbikgewogIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07CiAgaWYgKCFtKQogICAgcmV0dXJuIG87CiAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7CiAgdHJ5IHsKICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKQogICAgICBhci5wdXNoKHIudmFsdWUpOwogIH0gY2F0Y2ggKGVycm9yKSB7CiAgICBlID0geyBlcnJvciB9OwogIH0gZmluYWxseSB7CiAgICB0cnkgewogICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVsicmV0dXJuIl0pKQogICAgICAgIG0uY2FsbChpKTsKICAgIH0gZmluYWxseSB7CiAgICAgIGlmIChlKQogICAgICAgIHRocm93IGUuZXJyb3I7CiAgICB9CiAgfQogIHJldHVybiBhcjsKfQpmdW5jdGlvbiBfX3NwcmVhZCgpIHsKICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykKICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTsKICByZXR1cm4gYXI7Cn0KdmFyIEV2ZW50ID0gZnVuY3Rpb24oKSB7CiAgZnVuY3Rpb24gRXZlbnQyKHR5cGUsIHRhcmdldCkgewogICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CiAgICB0aGlzLnR5cGUgPSB0eXBlOwogIH0KICByZXR1cm4gRXZlbnQyOwp9KCk7CnZhciBFcnJvckV2ZW50ID0gZnVuY3Rpb24oX3N1cGVyKSB7CiAgX19leHRlbmRzKEVycm9yRXZlbnQyLCBfc3VwZXIpOwogIGZ1bmN0aW9uIEVycm9yRXZlbnQyKGVycm9yLCB0YXJnZXQpIHsKICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJlcnJvciIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLm1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlOwogICAgX3RoaXMuZXJyb3IgPSBlcnJvcjsKICAgIHJldHVybiBfdGhpczsKICB9CiAgcmV0dXJuIEVycm9yRXZlbnQyOwp9KEV2ZW50KTsKdmFyIENsb3NlRXZlbnQgPSBmdW5jdGlvbihfc3VwZXIpIHsKICBfX2V4dGVuZHMoQ2xvc2VFdmVudDIsIF9zdXBlcik7CiAgZnVuY3Rpb24gQ2xvc2VFdmVudDIoY29kZSwgcmVhc29uLCB0YXJnZXQpIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIGlmIChyZWFzb24gPT09IHZvaWQgMCkgewogICAgICByZWFzb24gPSAiIjsKICAgIH0KICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJjbG9zZSIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLndhc0NsZWFuID0gdHJ1ZTsKICAgIF90aGlzLmNvZGUgPSBjb2RlOwogICAgX3RoaXMucmVhc29uID0gcmVhc29uOwogICAgcmV0dXJuIF90aGlzOwogIH0KICByZXR1cm4gQ2xvc2VFdmVudDI7Cn0oRXZlbnQpOwp2YXIgZ2V0R2xvYmFsV2ViU29ja2V0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKHR5cGVvZiBXZWJTb2NrZXQgIT09ICJ1bmRlZmluZWQiKSB7CiAgICByZXR1cm4gV2ViU29ja2V0OwogIH0KfTsKdmFyIGlzV2ViU29ja2V0ID0gZnVuY3Rpb24odykgewogIHJldHVybiB0eXBlb2YgdyAhPT0gInVuZGVmaW5lZCIgJiYgISF3ICYmIHcuQ0xPU0lORyA9PT0gMjsKfTsKdmFyIERFRkFVTFQgPSB7CiAgbWF4UmVjb25uZWN0aW9uRGVsYXk6IDFlNCwKICBtaW5SZWNvbm5lY3Rpb25EZWxheTogMWUzICsgTWF0aC5yYW5kb20oKSAqIDRlMywKICBtaW5VcHRpbWU6IDVlMywKICByZWNvbm5lY3Rpb25EZWxheUdyb3dGYWN0b3I6IDEuMywKICBjb25uZWN0aW9uVGltZW91dDogNGUzLAogIG1heFJldHJpZXM6IEluZmluaXR5LAogIG1heEVucXVldWVkTWVzc2FnZXM6IEluZmluaXR5LAogIHN0YXJ0Q2xvc2VkOiBmYWxzZSwKICBkZWJ1ZzogZmFsc2UKfTsKdmFyIFJlY29ubmVjdGluZ1dlYlNvY2tldCA9IGZ1bmN0aW9uKCkgewogIGZ1bmN0aW9uIFJlY29ubmVjdGluZ1dlYlNvY2tldDIodXJsLCBwcm90b2NvbHMsIG9wdGlvbnMpIHsKICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7CiAgICAgIG9wdGlvbnMgPSB7fTsKICAgIH0KICAgIHRoaXMuX2xpc3RlbmVycyA9IHsKICAgICAgZXJyb3I6IFtdLAogICAgICBtZXNzYWdlOiBbXSwKICAgICAgb3BlbjogW10sCiAgICAgIGNsb3NlOiBbXQogICAgfTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIHRoaXMuX3Nob3VsZFJlY29ubmVjdCA9IHRydWU7CiAgICB0aGlzLl9jb25uZWN0TG9jayA9IGZhbHNlOwogICAgdGhpcy5fYmluYXJ5VHlwZSA9ICJibG9iIjsKICAgIHRoaXMuX2Nsb3NlQ2FsbGVkID0gZmFsc2U7CiAgICB0aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgIHRoaXMub25jbG9zZSA9IG51bGw7CiAgICB0aGlzLm9uZXJyb3IgPSBudWxsOwogICAgdGhpcy5vbm1lc3NhZ2UgPSBudWxsOwogICAgdGhpcy5vbm9wZW4gPSBudWxsOwogICAgdGhpcy5faGFuZGxlT3BlbiA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgIF90aGlzLl9kZWJ1Zygib3BlbiBldmVudCIpOwogICAgICB2YXIgX2EgPSBfdGhpcy5fb3B0aW9ucy5taW5VcHRpbWUsIG1pblVwdGltZSA9IF9hID09PSB2b2lkIDAgPyBERUZBVUxULm1pblVwdGltZSA6IF9hOwogICAgICBjbGVhclRpbWVvdXQoX3RoaXMuX2Nvbm5lY3RUaW1lb3V0KTsKICAgICAgX3RoaXMuX3VwdGltZVRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5fYWNjZXB0T3BlbigpOwogICAgICB9LCBtaW5VcHRpbWUpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fbWVzc2FnZVF1ZXVlLmZvckVhY2goZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHJldHVybiBfdGhpcy5fd3Muc2VuZChtZXNzYWdlKTsKICAgICAgfSk7CiAgICAgIF90aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgICAgaWYgKF90aGlzLm9ub3BlbikgewogICAgICAgIF90aGlzLm9ub3BlbihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5vcGVuLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZU1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkgewogICAgICBfdGhpcy5fZGVidWcoIm1lc3NhZ2UgZXZlbnQiKTsKICAgICAgaWYgKF90aGlzLm9ubWVzc2FnZSkgewogICAgICAgIF90aGlzLm9ubWVzc2FnZShldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5tZXNzYWdlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUVycm9yID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJlcnJvciBldmVudCIsIGV2ZW50Lm1lc3NhZ2UpOwogICAgICBfdGhpcy5fZGlzY29ubmVjdCh2b2lkIDAsIGV2ZW50Lm1lc3NhZ2UgPT09ICJUSU1FT1VUIiA/ICJ0aW1lb3V0IiA6IHZvaWQgMCk7CiAgICAgIGlmIChfdGhpcy5vbmVycm9yKSB7CiAgICAgICAgX3RoaXMub25lcnJvcihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJleGVjIGVycm9yIGxpc3RlbmVycyIpOwogICAgICBfdGhpcy5fbGlzdGVuZXJzLmVycm9yLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgICBfdGhpcy5fY29ubmVjdCgpOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUNsb3NlID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJjbG9zZSBldmVudCIpOwogICAgICBfdGhpcy5fY2xlYXJUaW1lb3V0cygpOwogICAgICBpZiAoX3RoaXMuX3Nob3VsZFJlY29ubmVjdCkgewogICAgICAgIF90aGlzLl9jb25uZWN0KCk7CiAgICAgIH0KICAgICAgaWYgKF90aGlzLm9uY2xvc2UpIHsKICAgICAgICBfdGhpcy5vbmNsb3NlKGV2ZW50KTsKICAgICAgfQogICAgICBfdGhpcy5fbGlzdGVuZXJzLmNsb3NlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX3VybCA9IHVybDsKICAgIHRoaXMuX3Byb3RvY29scyA9IHByb3RvY29sczsKICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zOwogICAgaWYgKHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQpIHsKICAgICAgdGhpcy5fc2hvdWxkUmVjb25uZWN0ID0gZmFsc2U7CiAgICB9CiAgICB0aGlzLl9jb25uZWN0KCk7CiAgfQogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ09OTkVDVElORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiAwOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0MiwgIk9QRU4iLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gMTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIsICJDTE9TSU5HIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ0xPU0VEIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDM7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNPTk5FQ1RJTkciLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5DT05ORUNUSU5HOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJPUEVOIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIFJlY29ubmVjdGluZ1dlYlNvY2tldDIuT1BFTjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiQ0xPU0lORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NJTkc7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNMT1NFRCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRDsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYmluYXJ5VHlwZSIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmJpbmFyeVR5cGUgOiB0aGlzLl9iaW5hcnlUeXBlOwogICAgfSwKICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgdGhpcy5fYmluYXJ5VHlwZSA9IHZhbHVlOwogICAgICBpZiAodGhpcy5fd3MpIHsKICAgICAgICB0aGlzLl93cy5iaW5hcnlUeXBlID0gdmFsdWU7CiAgICAgIH0KICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicmV0cnlDb3VudCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBNYXRoLm1heCh0aGlzLl9yZXRyeUNvdW50LCAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYnVmZmVyZWRBbW91bnQiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICB2YXIgYnl0ZXMgPSB0aGlzLl9tZXNzYWdlUXVldWUucmVkdWNlKGZ1bmN0aW9uKGFjYywgbWVzc2FnZSkgewogICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgIGFjYyArPSBtZXNzYWdlLmxlbmd0aDsKICAgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBCbG9iKSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5zaXplOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5ieXRlTGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYWNjOwogICAgICB9LCAwKTsKICAgICAgcmV0dXJuIGJ5dGVzICsgKHRoaXMuX3dzID8gdGhpcy5fd3MuYnVmZmVyZWRBbW91bnQgOiAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiZXh0ZW5zaW9ucyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmV4dGVuc2lvbnMgOiAiIjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicHJvdG9jb2wiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gdGhpcy5fd3MgPyB0aGlzLl93cy5wcm90b2NvbCA6ICIiOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJyZWFkeVN0YXRlIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKHRoaXMuX3dzKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX3dzLnJlYWR5U3RhdGU7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQgPyBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRCA6IFJlY29ubmVjdGluZ1dlYlNvY2tldDIuQ09OTkVDVElORzsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAidXJsIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIHRoaXMuX3dzID8gdGhpcy5fd3MudXJsIDogIiI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICBpZiAoY29kZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvZGUgPSAxZTM7CiAgICB9CiAgICB0aGlzLl9jbG9zZUNhbGxlZCA9IHRydWU7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSBmYWxzZTsKICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlIGVucXVldWVkOiBubyB3cyBpbnN0YW5jZSIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlOiBhbHJlYWR5IGNsb3NlZCIpOwogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSB0cnVlOwogICAgdGhpcy5fY2xvc2VDYWxsZWQgPSBmYWxzZTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIGlmICghdGhpcy5fd3MgfHwgdGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fY29ubmVjdCgpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5fZGlzY29ubmVjdChjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9jb25uZWN0KCk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSkgewogICAgaWYgKHRoaXMuX3dzICYmIHRoaXMuX3dzLnJlYWR5U3RhdGUgPT09IHRoaXMuT1BFTikgewogICAgICB0aGlzLl9kZWJ1Zygic2VuZCIsIGRhdGEpOwogICAgICB0aGlzLl93cy5zZW5kKGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucy5tYXhFbnF1ZXVlZE1lc3NhZ2VzLCBtYXhFbnF1ZXVlZE1lc3NhZ2VzID0gX2EgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4RW5xdWV1ZWRNZXNzYWdlcyA6IF9hOwogICAgICBpZiAodGhpcy5fbWVzc2FnZVF1ZXVlLmxlbmd0aCA8IG1heEVucXVldWVkTWVzc2FnZXMpIHsKICAgICAgICB0aGlzLl9kZWJ1ZygiZW5xdWV1ZSIsIGRhdGEpOwogICAgICAgIHRoaXMuX21lc3NhZ2VRdWV1ZS5wdXNoKGRhdGEpOwogICAgICB9CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdLnB1c2gobGlzdGVuZXIpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuZGlzcGF0Y2hFdmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICB2YXIgZV8xLCBfYTsKICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnNbZXZlbnQudHlwZV07CiAgICBpZiAobGlzdGVuZXJzKSB7CiAgICAgIHRyeSB7CiAgICAgICAgZm9yICh2YXIgbGlzdGVuZXJzXzEgPSBfX3ZhbHVlcyhsaXN0ZW5lcnMpLCBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpOyAhbGlzdGVuZXJzXzFfMS5kb25lOyBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpKSB7CiAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNfMV8xLnZhbHVlOwogICAgICAgICAgdGhpcy5fY2FsbEV2ZW50TGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyKTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2ggKGVfMV8xKSB7CiAgICAgICAgZV8xID0geyBlcnJvcjogZV8xXzEgfTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICB0cnkgewogICAgICAgICAgaWYgKGxpc3RlbmVyc18xXzEgJiYgIWxpc3RlbmVyc18xXzEuZG9uZSAmJiAoX2EgPSBsaXN0ZW5lcnNfMS5yZXR1cm4pKQogICAgICAgICAgICBfYS5jYWxsKGxpc3RlbmVyc18xKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgaWYgKGVfMSkKICAgICAgICAgICAgdGhyb3cgZV8xLmVycm9yOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdID0gdGhpcy5fbGlzdGVuZXJzW3R5cGVdLmZpbHRlcihmdW5jdGlvbihsKSB7CiAgICAgICAgcmV0dXJuIGwgIT09IGxpc3RlbmVyOwogICAgICB9KTsKICAgIH0KICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9kZWJ1ZyA9IGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3MgPSBbXTsKICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7CiAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTsKICAgIH0KICAgIGlmICh0aGlzLl9vcHRpb25zLmRlYnVnKSB7CiAgICAgIGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIF9fc3ByZWFkKFsiUldTPiJdLCBhcmdzKSk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fZ2V0TmV4dERlbGF5ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX2EgPSB0aGlzLl9vcHRpb25zLCBfYiA9IF9hLnJlY29ubmVjdGlvbkRlbGF5R3Jvd0ZhY3RvciwgcmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQucmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yIDogX2IsIF9jID0gX2EubWluUmVjb25uZWN0aW9uRGVsYXksIG1pblJlY29ubmVjdGlvbkRlbGF5ID0gX2MgPT09IHZvaWQgMCA/IERFRkFVTFQubWluUmVjb25uZWN0aW9uRGVsYXkgOiBfYywgX2QgPSBfYS5tYXhSZWNvbm5lY3Rpb25EZWxheSwgbWF4UmVjb25uZWN0aW9uRGVsYXkgPSBfZCA9PT0gdm9pZCAwID8gREVGQVVMVC5tYXhSZWNvbm5lY3Rpb25EZWxheSA6IF9kOwogICAgdmFyIGRlbGF5ID0gMDsKICAgIGlmICh0aGlzLl9yZXRyeUNvdW50ID4gMCkgewogICAgICBkZWxheSA9IG1pblJlY29ubmVjdGlvbkRlbGF5ICogTWF0aC5wb3cocmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yLCB0aGlzLl9yZXRyeUNvdW50IC0gMSk7CiAgICAgIGlmIChkZWxheSA+IG1heFJlY29ubmVjdGlvbkRlbGF5KSB7CiAgICAgICAgZGVsYXkgPSBtYXhSZWNvbm5lY3Rpb25EZWxheTsKICAgICAgfQogICAgfQogICAgdGhpcy5fZGVidWcoIm5leHQgZGVsYXkiLCBkZWxheSk7CiAgICByZXR1cm4gZGVsYXk7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fd2FpdCA9IGZ1bmN0aW9uKCkgewogICAgdmFyIF90aGlzID0gdGhpczsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7CiAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgX3RoaXMuX2dldE5leHREZWxheSgpKTsKICAgIH0pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2dldE5leHRVcmwgPSBmdW5jdGlvbih1cmxQcm92aWRlcikgewogICAgaWYgKHR5cGVvZiB1cmxQcm92aWRlciA9PT0gInN0cmluZyIpIHsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1cmxQcm92aWRlcik7CiAgICB9CiAgICBpZiAodHlwZW9mIHVybFByb3ZpZGVyID09PSAiZnVuY3Rpb24iKSB7CiAgICAgIHZhciB1cmwgPSB1cmxQcm92aWRlcigpOwogICAgICBpZiAodHlwZW9mIHVybCA9PT0gInN0cmluZyIpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVybCk7CiAgICAgIH0KICAgICAgaWYgKCEhdXJsLnRoZW4pIHsKICAgICAgICByZXR1cm4gdXJsOwogICAgICB9CiAgICB9CiAgICB0aHJvdyBFcnJvcigiSW52YWxpZCBVUkwiKTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jb25uZWN0ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX3RoaXMgPSB0aGlzOwogICAgaWYgKHRoaXMuX2Nvbm5lY3RMb2NrIHx8ICF0aGlzLl9zaG91bGRSZWNvbm5lY3QpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fY29ubmVjdExvY2sgPSB0cnVlOwogICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucywgX2IgPSBfYS5tYXhSZXRyaWVzLCBtYXhSZXRyaWVzID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4UmV0cmllcyA6IF9iLCBfYyA9IF9hLmNvbm5lY3Rpb25UaW1lb3V0LCBjb25uZWN0aW9uVGltZW91dCA9IF9jID09PSB2b2lkIDAgPyBERUZBVUxULmNvbm5lY3Rpb25UaW1lb3V0IDogX2MsIF9kID0gX2EuV2ViU29ja2V0LCBXZWJTb2NrZXQyID0gX2QgPT09IHZvaWQgMCA/IGdldEdsb2JhbFdlYlNvY2tldCgpIDogX2Q7CiAgICBpZiAodGhpcy5fcmV0cnlDb3VudCA+PSBtYXhSZXRyaWVzKSB7CiAgICAgIHRoaXMuX2RlYnVnKCJtYXggcmV0cmllcyByZWFjaGVkIiwgdGhpcy5fcmV0cnlDb3VudCwgIj49IiwgbWF4UmV0cmllcyk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIHRoaXMuX3JldHJ5Q291bnQrKzsKICAgIHRoaXMuX2RlYnVnKCJjb25uZWN0IiwgdGhpcy5fcmV0cnlDb3VudCk7CiAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lcnMoKTsKICAgIGlmICghaXNXZWJTb2NrZXQoV2ViU29ja2V0MikpIHsKICAgICAgdGhyb3cgRXJyb3IoIk5vIHZhbGlkIFdlYlNvY2tldCBjbGFzcyBwcm92aWRlZCIpOwogICAgfQogICAgdGhpcy5fd2FpdCgpLnRoZW4oZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBfdGhpcy5fZ2V0TmV4dFVybChfdGhpcy5fdXJsKTsKICAgIH0pLnRoZW4oZnVuY3Rpb24odXJsKSB7CiAgICAgIGlmIChfdGhpcy5fY2xvc2VDYWxsZWQpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJjb25uZWN0IiwgeyB1cmwsIHByb3RvY29sczogX3RoaXMuX3Byb3RvY29scyB9KTsKICAgICAgX3RoaXMuX3dzID0gX3RoaXMuX3Byb3RvY29scyA/IG5ldyBXZWJTb2NrZXQyKHVybCwgX3RoaXMuX3Byb3RvY29scykgOiBuZXcgV2ViU29ja2V0Mih1cmwpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fY29ubmVjdExvY2sgPSBmYWxzZTsKICAgICAgX3RoaXMuX2FkZExpc3RlbmVycygpOwogICAgICBfdGhpcy5fY29ubmVjdFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5faGFuZGxlVGltZW91dCgpOwogICAgICB9LCBjb25uZWN0aW9uVGltZW91dCk7CiAgICB9KTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9oYW5kbGVUaW1lb3V0ID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLl9kZWJ1ZygidGltZW91dCBldmVudCIpOwogICAgdGhpcy5faGFuZGxlRXJyb3IobmV3IEVycm9yRXZlbnQoRXJyb3IoIlRJTUVPVVQiKSwgdGhpcykpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2Rpc2Nvbm5lY3QgPSBmdW5jdGlvbihjb2RlLCByZWFzb24pIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJzKCk7CiAgICB0cnkgewogICAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9oYW5kbGVDbG9zZShuZXcgQ2xvc2VFdmVudChjb2RlLCByZWFzb24sIHRoaXMpKTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fYWNjZXB0T3BlbiA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5fZGVidWcoImFjY2VwdCBvcGVuIik7CiAgICB0aGlzLl9yZXRyeUNvdW50ID0gMDsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jYWxsRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBsaXN0ZW5lcikgewogICAgaWYgKCJoYW5kbGVFdmVudCIgaW4gbGlzdGVuZXIpIHsKICAgICAgbGlzdGVuZXIuaGFuZGxlRXZlbnQoZXZlbnQpOwogICAgfSBlbHNlIHsKICAgICAgbGlzdGVuZXIoZXZlbnQpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX3JlbW92ZUxpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygicmVtb3ZlTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2FkZExpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygiYWRkTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2NsZWFyVGltZW91dHMgPSBmdW5jdGlvbigpIHsKICAgIGNsZWFyVGltZW91dCh0aGlzLl9jb25uZWN0VGltZW91dCk7CiAgICBjbGVhclRpbWVvdXQodGhpcy5fdXB0aW1lVGltZW91dCk7CiAgfTsKICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0MjsKfSgpOwp2YXIgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdCA9IFJlY29ubmVjdGluZ1dlYlNvY2tldDsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJncywgZW52LCBmZHMsIG9wdGlvbnMgPSB7fSkgewogICAgdGhpcy5hcmdzID0gW107CiAgICB0aGlzLmVudiA9IFtdOwogICAgdGhpcy5mZHMgPSBbXTsKICAgIGRlYnVnLmVuYWJsZShvcHRpb25zLmRlYnVnKTsKICAgIHRoaXMuYXJncyA9IGFyZ3M7CiAgICB0aGlzLmVudiA9IGVudjsKICAgIHRoaXMuZmRzID0gZmRzOwogICAgY29uc3Qgc2VsZiA9IHRoaXM7CiAgICB0aGlzLndhc2lJbXBvcnQgPSB7IGFyZ3Nfc2l6ZXNfZ2V0KGFyZ2MsIGFyZ3ZfYnVmX3NpemUpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ2MsIHNlbGYuYXJncy5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGFyZyBvZiBzZWxmLmFyZ3MpIHsKICAgICAgICBidWZfc2l6ZSArPSBhcmcubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3ZfYnVmX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoYXJnYywgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGFyZ3NfZ2V0KGFyZ3YsIGFyZ3ZfYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2FyZ3ZfYnVmID0gYXJndl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5hcmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihhcmd2LCBhcmd2X2J1ZiwgdHJ1ZSk7CiAgICAgICAgYXJndiArPSA0OwogICAgICAgIGNvbnN0IGFyZyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmFyZ3NbaV0pOwogICAgICAgIGJ1ZmZlcjguc2V0KGFyZywgYXJndl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChhcmd2X2J1ZiArIGFyZy5sZW5ndGgsIDApOwogICAgICAgIGFyZ3ZfYnVmICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgICAgZGVidWcubG9nKG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvcmlnX2FyZ3ZfYnVmLCBhcmd2X2J1ZikpKTsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fc2l6ZXNfZ2V0KGVudmlyb25fY291bnQsIGVudmlyb25fc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9jb3VudCwgc2VsZi5lbnYubGVuZ3RoLCB0cnVlKTsKICAgICAgbGV0IGJ1Zl9zaXplID0gMDsKICAgICAgZm9yIChjb25zdCBlbnZpcm9uIG9mIHNlbGYuZW52KSB7CiAgICAgICAgYnVmX3NpemUgKz0gZW52aXJvbi5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9zaXplLCBidWZfc2l6ZSwgdHJ1ZSk7CiAgICAgIGRlYnVnLmxvZyhidWZmZXIuZ2V0VWludDMyKGVudmlyb25fY291bnQsIHRydWUpLCBidWZmZXIuZ2V0VWludDMyKGVudmlyb25fc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fZ2V0KGVudmlyb24sIGVudmlyb25fYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2Vudmlyb25fYnVmID0gZW52aXJvbl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5lbnYubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGVudmlyb24sIGVudmlyb25fYnVmLCB0cnVlKTsKICAgICAgICBlbnZpcm9uICs9IDQ7CiAgICAgICAgY29uc3QgZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmVudltpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoZSwgZW52aXJvbl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChlbnZpcm9uX2J1ZiArIGUubGVuZ3RoLCAwKTsKICAgICAgICBlbnZpcm9uX2J1ZiArPSBlLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfZW52aXJvbl9idWYsIGVudmlyb25fYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgY2xvY2tfcmVzX2dldChpZCwgcmVzX3B0cikgewogICAgICBsZXQgcmVzb2x1dGlvblZhbHVlOwogICAgICBzd2l0Y2ggKGlkKSB7CiAgICAgICAgY2FzZSBDTE9DS0lEX01PTk9UT05JQzogewogICAgICAgICAgcmVzb2x1dGlvblZhbHVlID0gNTAwMG47CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDTE9DS0lEX1JFQUxUSU1FOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSAxMDAwMDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuIEVSUk5PX05PU1lTOwogICAgICB9CiAgICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIHZpZXcuc2V0QmlnVWludDY0KHJlc19wdHIsIHJlc29sdXRpb25WYWx1ZSwgdHJ1ZSk7CiAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgfSwgY2xvY2tfdGltZV9nZXQoaWQsIHByZWNpc2lvbiwgdGltZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChpZCA9PT0gQ0xPQ0tJRF9SRUFMVElNRSkgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgQmlnSW50KG5ldyBEYXRlKCkuZ2V0VGltZSgpKSAqIDEwMDAwMDBuLCB0cnVlKTsKICAgICAgfSBlbHNlIGlmIChpZCA9PSBDTE9DS0lEX01PTk9UT05JQykgewogICAgICAgIGxldCBtb25vdG9uaWNfdGltZTsKICAgICAgICB0cnkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSBCaWdJbnQoTWF0aC5yb3VuZChwZXJmb3JtYW5jZS5ub3coKSAqIDFlNikpOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIG1vbm90b25pY190aW1lID0gMG47CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgbW9ub3RvbmljX3RpbWUsIHRydWUpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgMG4sIHRydWUpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZmRfYWR2aXNlKGZkLCBvZmZzZXQsIGxlbiwgYWR2aWNlKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2FsbG9jYXRlKGZkLCBvZmZzZXQsIGxlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9jbG9zZShmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW2ZkXS5mZF9jbG9zZSgpOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9kYXRhc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfZ2V0KGZkLCBmZHN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZkc3RhdCB9ID0gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmRzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZkc3RhdC53cml0ZV9ieXRlcyhuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlciksIGZkc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfc2V0X2ZsYWdzKGZkLCBmbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZkLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X2dldChmZCwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfZ2V0KCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfc2V0X3NpemUoZmQsIHNpemUpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlYWQoaW92ZWMuYnVmX2xlbiwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgb2Zmc2V0ICs9IEJpZ0ludChkYXRhLmxlbmd0aCk7CiAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggIT0gaW92ZWMuYnVmX2xlbikgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9nZXQoZmQsIGJ1Zl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBwcmVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgYnVmX3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZXN0YXRfZGlyX25hbWUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBjb25zdCBwcmVzdGF0X2Rpcl9uYW1lID0gcHJlc3RhdC5pbm5lci5wcl9uYW1lOwogICAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgICBidWZmZXI4LnNldChwcmVzdGF0X2Rpcl9uYW1lLnNsaWNlKDAsIHBhdGhfbGVuKSwgcGF0aF9wdHIpOwogICAgICAgIHJldHVybiBwcmVzdGF0X2Rpcl9uYW1lLmJ5dGVMZW5ndGggPiBwYXRoX2xlbiA/IEVSUk5PX05BTUVUT09MT05HIDogRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHdyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbndyaXR0ZW5fcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IENpb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbndyaXR0ZW4gPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCBkYXRhID0gYnVmZmVyOC5zbGljZShpb3ZlYy5idWYsIGlvdmVjLmJ1ZiArIGlvdmVjLmJ1Zl9sZW4pOwogICAgICAgICAgY29uc3QgeyByZXQsIG53cml0dGVuOiBud3JpdHRlbl9wYXJ0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHdyaXRlKGRhdGEsIG9mZnNldCk7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIG53cml0dGVuICs9IG53cml0dGVuX3BhcnQ7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KG53cml0dGVuX3BhcnQpOwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG5yZWFkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBJb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbnJlYWQgPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLmZkX3JlYWQoaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGEsIGlvdmVjLmJ1Zik7CiAgICAgICAgICBucmVhZCArPSBkYXRhLmxlbmd0aDsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkZGlyKGZkLCBidWYsIGJ1Zl9sZW4sIGNvb2tpZSwgYnVmdXNlZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgbGV0IGJ1ZnVzZWQgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGlyZW50IH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKTsKICAgICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChkaXJlbnQgPT0gbnVsbCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5oZWFkX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNvbnN0IGhlYWRfYnl0ZXMgPSBuZXcgQXJyYXlCdWZmZXIoZGlyZW50LmhlYWRfbGVuZ3RoKCkpOwogICAgICAgICAgZGlyZW50LndyaXRlX2hlYWRfYnl0ZXMobmV3IERhdGFWaWV3KGhlYWRfYnl0ZXMpLCAwKTsKICAgICAgICAgIGJ1ZmZlcjguc2V0KG5ldyBVaW50OEFycmF5KGhlYWRfYnl0ZXMpLnNsaWNlKDAsIE1hdGgubWluKGhlYWRfYnl0ZXMuYnl0ZUxlbmd0aCwgYnVmX2xlbiAtIGJ1ZnVzZWQpKSwgYnVmKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50LmhlYWRfbGVuZ3RoKCk7CiAgICAgICAgICBpZiAoYnVmX2xlbiAtIGJ1ZnVzZWQgPCBkaXJlbnQubmFtZV9sZW5ndGgoKSkgewogICAgICAgICAgICBidWZ1c2VkID0gYnVmX2xlbjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBkaXJlbnQud3JpdGVfbmFtZV9ieXRlcyhidWZmZXI4LCBidWYsIGJ1Zl9sZW4gLSBidWZ1c2VkKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50Lm5hbWVfbGVuZ3RoKCk7CiAgICAgICAgICBjb29raWUgPSBkaXJlbnQuZF9uZXh0OwogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcmVudW1iZXIoZmQsIHRvKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW3RvXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCByZXQgPSBzZWxmLmZkc1t0b10uZmRfY2xvc2UoKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzW3RvXSA9IHNlbGYuZmRzW2ZkXTsKICAgICAgICBzZWxmLmZkc1tmZF0gPSB2b2lkIDA7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3NlZWsoZmQsIG9mZnNldCwgd2hlbmNlLCBvZmZzZXRfb3V0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIG9mZnNldDogb2Zmc2V0X291dCB9ID0gc2VsZi5mZHNbZmRdLmZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdJbnQ2NChvZmZzZXRfb3V0X3B0ciwgb2Zmc2V0X291dCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF90ZWxsKGZkLCBvZmZzZXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfdGVsbCgpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQob2Zmc2V0X3B0ciwgb2Zmc2V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF93cml0ZShmZCwgaW92c19wdHIsIGlvdnNfbGVuLCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF93cml0ZShkYXRhKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIGlmIChud3JpdHRlbl9wYXJ0ICE9IGRhdGEuYnl0ZUxlbmd0aCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9nZXQoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGZpbGVzdGF0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2xpbmsob2xkX2ZkLCBvbGRfZmxhZ3MsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW29sZF9mZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW29sZF9mZF0ucGF0aF9sb29rdXAob2xkX3BhdGgsIG9sZF9mbGFncyk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgZmFsc2UpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX29wZW4oZmQsIGRpcmZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncywgb3BlbmVkX2ZkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgpOwogICAgICAgIGNvbnN0IHsgcmV0LCBmZF9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGgsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncyk7CiAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBzZWxmLmZkcy5wdXNoKGZkX29iaik7CiAgICAgICAgY29uc3Qgb3BlbmVkX2ZkID0gc2VsZi5mZHMubGVuZ3RoIC0gMTsKICAgICAgICBidWZmZXIuc2V0VWludDMyKG9wZW5lZF9mZF9wdHIsIG9wZW5lZF9mZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVhZGxpbmsoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbiwgYnVmX3B0ciwgYnVmX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3JlYWRsaW5rKHBhdGgpOwogICAgICAgIGlmIChkYXRhICE9IG51bGwpIHsKICAgICAgICAgIGNvbnN0IGRhdGFfYnVmID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGRhdGEpOwogICAgICAgICAgaWYgKGRhdGFfYnVmLmxlbmd0aCA+IGJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIDAsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGFfYnVmLCBidWZfcHRyKTsKICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBkYXRhX2J1Zi5sZW5ndGgsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbW92ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbmFtZShmZCwgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCAmJiBzZWxmLmZkc1tuZXdfZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICBsZXQgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfdW5saW5rKG9sZF9wYXRoKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldCA9IHNlbGYuZmRzW25ld19mZF0ucGF0aF9saW5rKG5ld19wYXRoLCBpbm9kZV9vYmosIHRydWUpOwogICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgaWYgKHNlbGYuZmRzW2ZkXS5wYXRoX2xpbmsob2xkX3BhdGgsIGlub2RlX29iaiwgdHJ1ZSkgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICB0aHJvdyAicGF0aF9saW5rIHNob3VsZCBhbHdheXMgcmV0dXJuIHN1Y2Nlc3Mgd2hlbiByZWxpbmtpbmcgYW4gaW5vZGUgYmFjayB0byB0aGUgb3JpZ2luYWwgcGxhY2UiOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3N5bWxpbmsob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIGZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfdW5saW5rX2ZpbGUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmtfZmlsZShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGgsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfcmVhZGxpbmsocGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG51bGwgfTsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQp9Owp2YXIgSW5vZGUgPSBjbGFzcyB7Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZzX21lbS5qcwp2YXIgT3BlbkZpbGUgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gb2Zmc2V0ICsgbGVuKSB7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBsZW4pKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCAwKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBzaXplKSB7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5maWxlLmRhdGEuYnVmZmVyLnNsaWNlKDAsIE51bWJlcihzaXplKSkpOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIoc2l6ZSkpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIodGhpcy5maWxlX3BvcyksIE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KHNpemUpKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChzbGljZS5sZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKG9mZnNldCksIE51bWJlcihvZmZzZXQgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgbGV0IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgc3dpdGNoICh3aGVuY2UpIHsKICAgICAgY2FzZSBXSEVOQ0VfU0VUOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9DVVI6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSB0aGlzLmZpbGVfcG9zICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9FTkQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBCaWdJbnQodGhpcy5maWxlLmRhdGEuYnl0ZUxlbmd0aCkgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgaWYgKGNhbGN1bGF0ZWRfb2Zmc2V0IDwgMCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICB0aGlzLmZpbGVfcG9zID0gY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcihvZmZzZXQpKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmZpbGUuc3RhdCgpIH07CiAgfQogIGNvbnN0cnVjdG9yKGZpbGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmZpbGVfcG9zID0gMG47CiAgICB0aGlzLmZpbGUgPSBmaWxlOwogIH0KfTsKdmFyIE9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9ESVJFQ1RPUlksIDApIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgZGVidWcubG9nKCJyZWFkZGlyX3NpbmdsZSIsIGNvb2tpZSk7CiAgICAgIGRlYnVnLmxvZyhjb29raWUsIHRoaXMuZGlyLmNvbnRlbnRzLmtleXMoKSk7CiAgICB9CiAgICBpZiAoY29va2llID09IDBuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDFuLCAiLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0gZWxzZSBpZiAoY29va2llID09IDFuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDJuLCAiLi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9CiAgICBpZiAoY29va2llID49IEJpZ0ludCh0aGlzLmRpci5jb250ZW50cy5zaXplKSArIDJuKSB7CiAgICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBbbmFtZSwgZW50cnldID0gQXJyYXkuZnJvbSh0aGlzLmRpci5jb250ZW50cy5lbnRyaWVzKCkpW051bWJlcihjb29raWUgLSAybildOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG5ldyBEaXJlbnQoY29va2llICsgMW4sIG5hbWUsIGVudHJ5LnN0YXQoKS5maWxldHlwZSkgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9lcnIsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IGVudHJ5LnN0YXQoKSB9OwogIH0KICBwYXRoX2xvb2t1cChwYXRoX3N0ciwgZGlyZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoX3N0ciwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgaWYgKHJldCAhPSBFUlJOT19OT0VOVCkgewogICAgICAgIHJldHVybiB7IHJldCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfQ1JFQVQpID09IE9GTEFHU19DUkVBVCkgewogICAgICAgIGNvbnN0IHsgcmV0OiByZXQyLCBlbnRyeTogbmV3X2VudHJ5IH0gPSB0aGlzLmRpci5jcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZKTsKICAgICAgICBpZiAobmV3X2VudHJ5ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiB7IHJldDogcmV0MiwgZmRfb2JqOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGVudHJ5ID0gbmV3X2VudHJ5OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICB9IGVsc2UgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRVhDTCkgPT0gT0ZMQUdTX0VYQ0wpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIGVudHJ5LnBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncyk7CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gdGhpcy5wYXRoX29wZW4oMCwgcGF0aCwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIGNvbnN0IHNvdXJjZV9pc19kaXIgPSBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBjb25zdCB0YXJnZXRfaXNfZGlyID0gZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgaWYgKHNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIGlmIChhbGxvd19kaXIgJiYgZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHsKICAgICAgICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplID09IDApIHsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChzb3VyY2VfaXNfZGlyICYmICF0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgICAgfSBlbHNlIGlmICghc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgICB9IGVsc2UgaWYgKGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSkgewogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgfQogICAgfQogICAgaWYgKCFhbGxvd19kaXIgJiYgaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fUEVSTTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIGlub2RlKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3VubGluayhwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF91bmxpbmtfZmlsZShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHx8IGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICB9CiAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSAhPT0gMCkgewogICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICB9CiAgICBpZiAoIXBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpKSB7CiAgICAgIHJldHVybiBFUlJOT19OT0VOVDsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmRpci5zdGF0KCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBjb25zdHJ1Y3RvcihkaXIpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRpciA9IGRpcjsKICB9Cn07CnZhciBQcmVvcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBPcGVuRGlyZWN0b3J5IHsKICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgcHJlc3RhdDogUHJlc3RhdC5kaXIodGhpcy5wcmVzdGF0X25hbWUpIH07CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnRzKSB7CiAgICBzdXBlcihuZXcgRGlyZWN0b3J5KGNvbnRlbnRzKSk7CiAgICB0aGlzLnByZXN0YXRfbmFtZSA9IG5hbWU7CiAgfQp9Owp2YXIgRmlsZSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgaWYgKHRoaXMucmVhZG9ubHkgJiYgKGZzX3JpZ2h0c19iYXNlICYgQmlnSW50KFJJR0hUU19GRF9XUklURSkpID09IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19UUlVOQykgPT0gT0ZMQUdTX1RSVU5DKSB7CiAgICAgIGlmICh0aGlzLnJlYWRvbmx5KQogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KFtdKTsKICAgIH0KICAgIGNvbnN0IGZpbGUgPSBuZXcgT3BlbkZpbGUodGhpcyk7CiAgICBpZiAoZmRfZmxhZ3MgJiBGREZMQUdTX0FQUEVORCkKICAgICAgZmlsZS5mZF9zZWVrKDBuLCBXSEVOQ0VfRU5EKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZmRfb2JqOiBmaWxlIH07CiAgfQogIGdldCBzaXplKCkgewogICAgcmV0dXJuIEJpZ0ludCh0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgdGhpcy5zaXplKTsKICB9CiAgY29uc3RydWN0b3IoZGF0YSwgb3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgdGhpcy5yZWFkb25seSA9ICEhb3B0aW9ucz8ucmVhZG9ubHk7CiAgfQp9Owp2YXIgUGF0aCA9IGNsYXNzIFBhdGgyIHsKICBzdGF0aWMgZnJvbShwYXRoKSB7CiAgICBjb25zdCBzZWxmID0gbmV3IFBhdGgyKCk7CiAgICBzZWxmLmlzX2RpciA9IHBhdGguZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVENBUEFCTEUsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGlmIChwYXRoLmluY2x1ZGVzKCJcMCIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGguc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aCkgewogICAgbGV0IGVudHJ5ID0gdGhpczsKICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgucGFydHMpIHsKICAgICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgICAgY29uc3QgY2hpbGQgPSBlbnRyeS5jb250ZW50cy5nZXQoY29tcG9uZW50KTsKICAgICAgaWYgKGNoaWxkICE9PSB2b2lkIDApIHsKICAgICAgICBlbnRyeSA9IGNoaWxkOwogICAgICB9IGVsc2UgewogICAgICAgIGRlYnVnLmxvZyhjb21wb25lbnQpOwogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBhbGxvd191bmRlZmluZWQpIHsKICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5wYXJ0cy5wb3AoKTsKICAgIGlmIChmaWxlbmFtZSA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldDogZW50cnlfcmV0LCBlbnRyeTogcGFyZW50X2VudHJ5IH0gPSB0aGlzLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfTsKICB9CiAgY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCBpc19kaXIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGRlYnVnLmxvZygiY3JlYXRlIiwgcGF0aCk7CiAgICBsZXQgbmV3X2NoaWxkOwogICAgaWYgKCFpc19kaXIpIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IEZpbGUobmV3IEFycmF5QnVmZmVyKDApKTsKICAgIH0gZWxzZSB7CiAgICAgIG5ld19jaGlsZCA9IG5ldyBEaXJlY3RvcnkoLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSk7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBuZXdfY2hpbGQpOwogICAgZW50cnkgPSBuZXdfY2hpbGQ7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGNvbnN0cnVjdG9yKGNvbnRlbnRzKSB7CiAgICBzdXBlcigpOwogICAgaWYgKGNvbnRlbnRzIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgdGhpcy5jb250ZW50cyA9IG5ldyBNYXAoY29udGVudHMpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5jb250ZW50cyA9IGNvbnRlbnRzOwogICAgfQogIH0KfTsKdmFyIENvbnNvbGVTdGRvdXQgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmaWxlc3RhdCA9IG5ldyBGaWxlc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCBCaWdJbnQoMCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdCB9OwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgY29uc3QgZmRzdGF0ID0gbmV3IEZkc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCAwKTsKICAgIGZkc3RhdC5mc19yaWdodHNfYmFzZSA9IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgdGhpcy53cml0ZShkYXRhKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBzdGF0aWMgbGluZUJ1ZmZlcmVkKHdyaXRlKSB7CiAgICBjb25zdCBkZWMgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICBsZXQgbGluZV9idWYgPSAiIjsKICAgIHJldHVybiBuZXcgQ29uc29sZVN0ZG91dCgoYnVmZmVyKSA9PiB7CiAgICAgIGxpbmVfYnVmICs9IGRlYy5kZWNvZGUoYnVmZmVyLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgICAgY29uc3QgbGluZXMgPSBsaW5lX2J1Zi5zcGxpdCgiXG4iKTsKICAgICAgZm9yIChjb25zdCBbaSwgbGluZV0gb2YgbGluZXMuZW50cmllcygpKSB7CiAgICAgICAgaWYgKGkgPCBsaW5lcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICB3cml0ZShsaW5lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGluZV9idWYgPSBsaW5lOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfQogIGNvbnN0cnVjdG9yKHdyaXRlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy53cml0ZSA9IHdyaXRlOwogIH0KfTsKCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL2luZGV4LmpzCmZ1bmN0aW9uIHBhcnNlSW1wb3J0cyhtb2R1bGVCeXRlcykgewogIGlmIChtb2R1bGVCeXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsKICB9IGVsc2UgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMpOwogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMuYnVmZmVyKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCJBcmd1bWVudCBtdXN0IGJlIGEgYnVmZmVyIHNvdXJjZSwgbGlrZSBVaW50OEFycmF5IG9yIEFycmF5QnVmZmVyIik7CiAgfQogIGNvbnN0IHBhcnNlU3RhdGUgPSBuZXcgUGFyc2VTdGF0ZShtb2R1bGVCeXRlcyk7CiAgcGFyc2VNYWdpY051bWJlcihwYXJzZVN0YXRlKTsKICBwYXJzZVZlcnNpb24ocGFyc2VTdGF0ZSk7CiAgY29uc3QgdHlwZXMgPSBbXTsKICBjb25zdCBpbXBvcnRzID0gW107CiAgd2hpbGUgKHBhcnNlU3RhdGUuaGFzTW9yZUJ5dGVzKCkpIHsKICAgIGNvbnN0IHNlY3Rpb25JZCA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICAgIGNvbnN0IHNlY3Rpb25TaXplID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgIHN3aXRjaCAoc2VjdGlvbklkKSB7CiAgICAgIGNhc2UgMTogewogICAgICAgIGNvbnN0IHR5cGVDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eXBlQ291bnQ7IGkrKykgewogICAgICAgICAgdHlwZXMucHVzaChwYXJzZUZ1bmN0aW9uVHlwZShwYXJzZVN0YXRlKSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgMjogewogICAgICAgIGNvbnN0IGltcG9ydENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGltcG9ydENvdW50OyBpKyspIHsKICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobW9kdWxlQnl0ZXMpOwogIGNvbnN0IGltcG9ydHMgPSBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpOwogIGNvbnN0IG1lbW9yeUltcG9ydCA9IGltcG9ydHNbMF07CiAgcmV0dXJuIHR5cGVvZiBtZW1vcnlJbXBvcnQudHlwZSA9PT0gIm9iamVjdCI7Cn0pKCk7CmZ1bmN0aW9uIHBvbHlmaWxsKFdlYkFzc2VtYmx5MykgewogIGlmIChoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0KSB7CiAgICByZXR1cm4gV2ViQXNzZW1ibHkzOwogIH0KICBjb25zdCBuZXdXZWJBc3NlbWJseSA9IHt9OwogIGZvciAoY29uc3Qga2V5IGluIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKFdlYkFzc2VtYmx5MykpIHsKICAgIG5ld1dlYkFzc2VtYmx5W2tleV0gPSBXZWJBc3NlbWJseTNba2V5XTsKICB9CiAgY29uc3QgcG9seWZpbGxlZEltcG9ydHNTeW1ib2wgPSBTeW1ib2woInBvbHlmaWxsZWRJbXBvcnRzU3ltYm9sIik7CiAgY29uc3QgYXNzaWduSW1wb3J0cyA9IChtb2R1bGUsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdID0gcGFyc2VJbXBvcnRzKHNvdXJjZUJ5dGVzKTsKICB9OwogIGNvbnN0IG5ld01vZHVsZSA9IG5ld1dlYkFzc2VtYmx5Lk1vZHVsZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICBjb25zdCBtb2R1bGUgPSBuZXcgV2ViQXNzZW1ibHkzLk1vZHVsZShieXRlcyk7CiAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZSwgbmV3TW9kdWxlLnByb3RvdHlwZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG5ld01vZHVsZS5wcm90b3R5cGUsIFdlYkFzc2VtYmx5My5Nb2R1bGUucHJvdG90eXBlKTsKICBuZXdXZWJBc3NlbWJseS5jb21waWxlID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBzb3VyY2UpOwogICAgcmV0dXJuIG1vZHVsZTsKICB9OwogIGlmIChXZWJBc3NlbWJseTMuY29tcGlsZVN0cmVhbWluZykgewogICAgbmV3V2ViQXNzZW1ibHkuY29tcGlsZVN0cmVhbWluZyA9IGFzeW5jIChzb3VyY2UpID0+IHsKICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzb3VyY2U7CiAgICAgIGNvbnN0IGNsb25lID0gcmVzcG9uc2UuY2xvbmUoKTsKICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgbmV3IFVpbnQ4QXJyYXkoYXdhaXQgY2xvbmUuYXJyYXlCdWZmZXIoKSkpOwogICAgICByZXR1cm4gbW9kdWxlOwogICAgfTsKICB9CiAgbmV3TW9kdWxlLmltcG9ydHMgPSAobW9kdWxlKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXTsKICAgIGlmICghcGFyc2VkSW1wb3J0cykgewogICAgICByZXR1cm4gV2ViQXNzZW1ibHkzLk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgICB9CiAgICByZXR1cm4gcGFyc2VkSW1wb3J0czsKICB9OwogIHJldHVybiBuZXdXZWJBc3NlbWJseTsKfQoKLy8gZW50cnlwb2ludC9jb21tb24udHMKdmFyIFdlYkFzc2VtYmx5MiA9IHBvbHlmaWxsKGdsb2JhbFRoaXMuV2ViQXNzZW1ibHkpOwp2YXIgTGluZURlY29kZXIgPSBjbGFzcyB7CiAgY29uc3RydWN0b3Iob25MaW5lKSB7CiAgICB0aGlzLmRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICB0aGlzLmJ1ZmZlciA9ICIiOwogICAgdGhpcy5vbkxpbmUgPSBvbkxpbmU7CiAgfQogIGRlY29kZXI7CiAgYnVmZmVyOwogIG9uTGluZTsKICBzZW5kKGNodW5rKSB7CiAgICB0aGlzLmJ1ZmZlciArPSB0aGlzLmRlY29kZXIuZGVjb2RlKGNodW5rLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgIGNvbnN0IGxpbmVzID0gdGhpcy5idWZmZXIuc3BsaXQoIlxuIik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykgewogICAgICB0aGlzLm9uTGluZShsaW5lc1tpXSk7CiAgICB9CiAgICB0aGlzLmJ1ZmZlciA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdOwogIH0KfTsKdmFyIFdhc21SdW5uZXIgPSAocmF3T3B0aW9ucywgU3dpZnRSdW50aW1lKSA9PiB7CiAgY29uc3Qgb3B0aW9ucyA9IGRlZmF1bHRSdW5uZXJPcHRpb25zKHJhd09wdGlvbnMpOwogIGxldCBzd2lmdDsKICBpZiAoU3dpZnRSdW50aW1lKSB7CiAgICBzd2lmdCA9IG5ldyBTd2lmdFJ1bnRpbWUoKTsKICB9CiAgbGV0IHN0ZG91dExpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRvdXRMaW5lICE9IG51bGwpIHsKICAgIHN0ZG91dExpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZG91dExpbmUpOwogIH0KICBjb25zdCBzdGRvdXQgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRvdXQ/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRvdXRMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBsZXQgc3RkZXJyTGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZGVyckxpbmUgIT0gbnVsbCkgewogICAgc3RkZXJyTGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3RkZXJyTGluZSk7CiAgfQogIGNvbnN0IHN0ZGVyciA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZGVycj8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZGVyckxpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGNvbnN0IGFyZ3MgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzLCBlbnZzLCBmZHMsIHsKICAgIGRlYnVnOiBmYWxzZQogIH0pOwogIGNvbnN0IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QgPSAoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QgPSB7CiAgICAgIHdhc2lfc25hcHNob3RfcHJldmlldzE6IHdhc2kud2FzaUltcG9ydAogICAgfTsKICAgIGlmIChzd2lmdCkgewogICAgICBpbXBvcnRPYmplY3QuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgaWYgKCFpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgX2ltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Mi5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpKSB7CiAgICAgIGNvbnN0IGltcG9ydEVudHJ5ID0gX2ltcG9ydEVudHJ5OwogICAgICBpZiAoIWltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0gPSB7fTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0gPSAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEltcG9ydGVkIGZ1bmN0aW9uICR7aW1wb3J0RW50cnkubW9kdWxlfS4ke2ltcG9ydEVudHJ5Lm5hbWV9IG5vdCBpbXBsZW1lbnRlZGApOwogICAgICAgIH07CiAgICAgIH0gZWxzZSBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAibWVtb3J5IiAmJiBpbXBvcnRFbnRyeS5tb2R1bGUgPT0gImVudiIgJiYgaW1wb3J0RW50cnkubmFtZSA9PSAibWVtb3J5IikgewogICAgICAgIGNvbnN0IHR5cGUgPSBpbXBvcnRFbnRyeS50eXBlOwogICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB7CiAgICAgICAgICBpbml0aWFsOiB0eXBlLm1pbmltdW0sCiAgICAgICAgICBtYXhpbXVtOiB0eXBlLm1heGltdW0sCiAgICAgICAgICBzaGFyZWQ6IHR5cGUuc2hhcmVkCiAgICAgICAgfTsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9IG5ldyBXZWJBc3NlbWJseTIuTWVtb3J5KGRlc2NyaXB0b3IpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0OwogIH07CiAgcmV0dXJuIHsKICAgIGFzeW5jIHJ1bih3YXNtQnl0ZXMsIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgaWYgKCFleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgZXh0cmFXYXNtSW1wb3J0cyA9IHt9OwogICAgICB9CiAgICAgIGV4dHJhV2FzbUltcG9ydHMuX19zdGFja19zYW5pdGl6ZXIgPSB7CiAgICAgICAgcmVwb3J0X3N0YWNrX292ZXJmbG93OiAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkRldGVjdGVkIHN0YWNrIGJ1ZmZlciBvdmVyZmxvdy4iKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIGNvbnN0IG1vZHVsZSA9IGF3YWl0IFdlYkFzc2VtYmx5Mi5jb21waWxlKHdhc21CeXRlcyk7CiAgICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKTsKICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBXZWJBc3NlbWJseTIuaW5zdGFudGlhdGUobW9kdWxlLCBpbXBvcnRPYmplY3QpOwogICAgICBpZiAoc3dpZnQgJiYgaW5zdGFuY2UuZXhwb3J0cy5zd2pzX2xpYnJhcnlfdmVyc2lvbikgewogICAgICAgIHN3aWZ0LnNldEluc3RhbmNlKGluc3RhbmNlKTsKICAgICAgfQogICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5zdGFydChpbnN0YW5jZSk7CiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUgPT0gImZ1bmN0aW9uIikgewogICAgICAgIHdhc2kuaW5pdGlhbGl6ZShpbnN0YW5jZSk7CiAgICAgICAgaWYgKHN3aWZ0ICYmIHN3aWZ0Lm1haW4pIHsKICAgICAgICAgIHN3aWZ0Lm1haW4oKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLm1haW4gPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5tYWluKCk7CiAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2KDAsIDApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH07Cn07CnZhciBkZWZhdWx0UnVubmVyT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7CiAgaWYgKG9wdGlvbnMuYXJncyA9PSBudWxsKSB7CiAgICBvcHRpb25zLmFyZ3MgPSBbIm1haW4ud2FzbSJdOwogIH0KICByZXR1cm4gb3B0aW9uczsKfTsKCi8vIGVudHJ5cG9pbnQvZGV2LnRzCnZhciBzb2NrZXQgPSBuZXcgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdChgd3M6Ly8ke2xvY2F0aW9uLmhvc3R9L3dhdGNoZXJgKTsKc29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCAobWVzc2FnZSkgPT4gewogIGlmIChtZXNzYWdlLmRhdGEgPT09ICJyZWxvYWQiKSB7CiAgICBsb2NhdGlvbi5yZWxvYWQoKTsKICB9Cn0pOwp2YXIgc3RhcnRXYXNpVGFzayA9IGFzeW5jICgpID0+IHsKICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCIvbWFpbi53YXNtIik7CiAgY29uc3QgcmVzcG9uc2VBcnJheUJ1ZmZlciA9IGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICB9IGNhdGNoIHsKICAgIGNvbnNvbGUubG9nKCJKYXZhU2NyaXB0S2l0IG1vZHVsZSBub3QgYXZhaWxhYmxlLCBydW5uaW5nIHdpdGhvdXQgSmF2YVNjcmlwdEtpdCBydW50aW1lLiIpOwogIH0KICBjb25zdCB3YXNtUnVubmVyID0gV2FzbVJ1bm5lcih7CiAgICBvblN0ZG91dChjaHVuaykgewogICAgICBjb25zdCBraW5kQnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKDIpOwogICAgICBuZXcgRGF0YVZpZXcoa2luZEJ1ZmZlcikuc2V0VWludDE2KDAsIDEwMDEsIHRydWUpOwogICAgICBjb25zdCBidWZmZXIgPSBuZXcgVWludDhBcnJheSgyICsgY2h1bmsubGVuZ3RoKTsKICAgICAgYnVmZmVyLnNldChuZXcgVWludDhBcnJheShraW5kQnVmZmVyKSwgMCk7CiAgICAgIGJ1ZmZlci5zZXQoY2h1bmssIDIpOwogICAgICBzb2NrZXQuc2VuZChidWZmZXIpOwogICAgfSwKICAgIG9uU3Rkb3V0TGluZShsaW5lKSB7CiAgICAgIGNvbnNvbGUubG9nKGxpbmUpOwogICAgfSwKICAgIG9uU3RkZXJyKGNodW5rKSB7CiAgICAgIGNvbnN0IGtpbmRCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoMik7CiAgICAgIG5ldyBEYXRhVmlldyhraW5kQnVmZmVyKS5zZXRVaW50MTYoMCwgMTAwMiwgdHJ1ZSk7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDIgKyBjaHVuay5sZW5ndGgpOwogICAgICBidWZmZXIuc2V0KG5ldyBVaW50OEFycmF5KGtpbmRCdWZmZXIpLCAwKTsKICAgICAgYnVmZmVyLnNldChjaHVuaywgMik7CiAgICAgIHNvY2tldC5zZW5kKGJ1ZmZlcik7CiAgICB9LAogICAgb25TdGRlcnJMaW5lKGxpbmUpIHsKICAgICAgY29uc29sZS5lcnJvcihsaW5lKTsKICAgIH0KICB9LCBydW50aW1lQ29uc3RydWN0b3IpOwogIGNvbnN0IHdhc21CeXRlcyA9IG5ldyBVaW50OEFycmF5KHJlc3BvbnNlQXJyYXlCdWZmZXIpLmJ1ZmZlcjsKICBhd2FpdCB3YXNtUnVubmVyLnJ1bih3YXNtQnl0ZXMpOwp9OwpmdW5jdGlvbiBoYW5kbGVFcnJvcihlKSB7CiAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvcikgewogICAgY29uc3Qgc3RhY2sgPSBlLnN0YWNrOwogICAgaWYgKHN0YWNrICE9IG51bGwpIHsKICAgICAgc29ja2V0LnNlbmQoSlNPTi5zdHJpbmdpZnkoewogICAgICAgIGtpbmQ6ICJzdGFja1RyYWNlIiwKICAgICAgICBzdGFja1RyYWNlOiBzdGFjawogICAgICB9KSk7CiAgICB9CiAgfQp9CmFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7CiAgdHJ5IHsKICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJlcnJvciIsIChldmVudCkgPT4gewogICAgICBoYW5kbGVFcnJvcihldmVudC5lcnJvcik7CiAgICB9KTsKICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJ1bmhhbmRsZWRyZWplY3Rpb24iLCAoZXZlbnQpID0+IHsKICAgICAgaGFuZGxlRXJyb3IoZXZlbnQucmVhc29uKTsKICAgIH0pOwogICAgYXdhaXQgc3RhcnRXYXNpVGFzaygpOwogIH0gY2F0Y2ggKGUpIHsKICAgIGhhbmRsZUVycm9yKGUpOwogICAgdGhyb3cgZTsKICB9Cn0KbWFpbigpOwovKiEKICogUmVjb25uZWN0aW5nIFdlYlNvY2tldAogKiBieSBQZWRybyBMYWRhcmlhIDxwZWRyby5sYWRhcmlhQGdtYWlsLmNvbT4KICogaHR0cHM6Ly9naXRodWIuY29tL3BsYWRhcmlhL3JlY29ubmVjdGluZy13ZWJzb2NrZXQKICogTGljZW5zZSBNSVQKICovCi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgpDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZQp0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZQpMaWNlbnNlIGF0IGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKVEhJUyBDT0RFIElTIFBST1ZJREVEIE9OIEFOICpBUyBJUyogQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQpLSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIEFOWSBJTVBMSUVECldBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBUSVRMRSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsCk1FUkNIQU5UQUJMSVRZIE9SIE5PTi1JTkZSSU5HRU1FTlQuCgpTZWUgdGhlIEFwYWNoZSBWZXJzaW9uIDIuMCBMaWNlbnNlIGZvciBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMKYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwo=")! + public static let bundle: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpX2RlZnMuanMKdmFyIENMT0NLSURfUkVBTFRJTUUgPSAwOwp2YXIgQ0xPQ0tJRF9NT05PVE9OSUMgPSAxOwp2YXIgRVJSTk9fU1VDQ0VTUyA9IDA7CnZhciBFUlJOT19CQURGID0gODsKdmFyIEVSUk5PX0VYSVNUID0gMjA7CnZhciBFUlJOT19JTlZBTCA9IDI4Owp2YXIgRVJSTk9fSVNESVIgPSAzMTsKdmFyIEVSUk5PX05BTUVUT09MT05HID0gMzc7CnZhciBFUlJOT19OT0VOVCA9IDQ0Owp2YXIgRVJSTk9fTk9TWVMgPSA1MjsKdmFyIEVSUk5PX05PVERJUiA9IDU0Owp2YXIgRVJSTk9fTk9URU1QVFkgPSA1NTsKdmFyIEVSUk5PX05PVFNVUCA9IDU4Owp2YXIgRVJSTk9fUEVSTSA9IDYzOwp2YXIgRVJSTk9fTk9UQ0FQQUJMRSA9IDc2Owp2YXIgUklHSFRTX0ZEX0RBVEFTWU5DID0gMSA8PCAwOwp2YXIgUklHSFRTX0ZEX1JFQUQgPSAxIDw8IDE7CnZhciBSSUdIVFNfRkRfU0VFSyA9IDEgPDwgMjsKdmFyIFJJR0hUU19GRF9GRFNUQVRfU0VUX0ZMQUdTID0gMSA8PCAzOwp2YXIgUklHSFRTX0ZEX1NZTkMgPSAxIDw8IDQ7CnZhciBSSUdIVFNfRkRfVEVMTCA9IDEgPDwgNTsKdmFyIFJJR0hUU19GRF9XUklURSA9IDEgPDwgNjsKdmFyIFJJR0hUU19GRF9BRFZJU0UgPSAxIDw8IDc7CnZhciBSSUdIVFNfRkRfQUxMT0NBVEUgPSAxIDw8IDg7CnZhciBSSUdIVFNfUEFUSF9DUkVBVEVfRElSRUNUT1JZID0gMSA8PCA5Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0ZJTEUgPSAxIDw8IDEwOwp2YXIgUklHSFRTX1BBVEhfTElOS19TT1VSQ0UgPSAxIDw8IDExOwp2YXIgUklHSFRTX1BBVEhfTElOS19UQVJHRVQgPSAxIDw8IDEyOwp2YXIgUklHSFRTX1BBVEhfT1BFTiA9IDEgPDwgMTM7CnZhciBSSUdIVFNfRkRfUkVBRERJUiA9IDEgPDwgMTQ7CnZhciBSSUdIVFNfUEFUSF9SRUFETElOSyA9IDEgPDwgMTU7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfU09VUkNFID0gMSA8PCAxNjsKdmFyIFJJR0hUU19QQVRIX1JFTkFNRV9UQVJHRVQgPSAxIDw8IDE3Owp2YXIgUklHSFRTX1BBVEhfRklMRVNUQVRfR0VUID0gMSA8PCAxODsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9TSVpFID0gMSA8PCAxOTsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjA7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfR0VUID0gMSA8PCAyMTsKdmFyIFJJR0hUU19GRF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMjI7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1RJTUVTID0gMSA8PCAyMzsKdmFyIFJJR0hUU19QQVRIX1NZTUxJTksgPSAxIDw8IDI0Owp2YXIgUklHSFRTX1BBVEhfUkVNT1ZFX0RJUkVDVE9SWSA9IDEgPDwgMjU7CnZhciBSSUdIVFNfUEFUSF9VTkxJTktfRklMRSA9IDEgPDwgMjY7CnZhciBSSUdIVFNfUE9MTF9GRF9SRUFEV1JJVEUgPSAxIDw8IDI3Owp2YXIgUklHSFRTX1NPQ0tfU0hVVERPV04gPSAxIDw8IDI4Owp2YXIgSW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBJb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChJb3ZlYy5yZWFkX2J5dGVzKHZpZXcsIHB0ciArIDggKiBpKSk7CiAgICB9CiAgICByZXR1cm4gaW92ZWNzOwogIH0KfTsKdmFyIENpb3ZlYyA9IGNsYXNzIHsKICBzdGF0aWMgcmVhZF9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIGNvbnN0IGlvdmVjID0gbmV3IENpb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChDaW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBXSEVOQ0VfU0VUID0gMDsKdmFyIFdIRU5DRV9DVVIgPSAxOwp2YXIgV0hFTkNFX0VORCA9IDI7CnZhciBGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFID0gMjsKdmFyIEZJTEVUWVBFX0RJUkVDVE9SWSA9IDM7CnZhciBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgPSA0Owp2YXIgRGlyZW50ID0gY2xhc3MgewogIGhlYWRfbGVuZ3RoKCkgewogICAgcmV0dXJuIDI0OwogIH0KICBuYW1lX2xlbmd0aCgpIHsKICAgIHJldHVybiB0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGg7CiAgfQogIHdyaXRlX2hlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIsIHRoaXMuZF9uZXh0LCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDgsIHRoaXMuZF9pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50MzIocHRyICsgMTYsIHRoaXMuZGlyX25hbWUubGVuZ3RoLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDgocHRyICsgMjAsIHRoaXMuZF90eXBlKTsKICB9CiAgd3JpdGVfbmFtZV9ieXRlcyh2aWV3OCwgcHRyLCBidWZfbGVuKSB7CiAgICB2aWV3OC5zZXQodGhpcy5kaXJfbmFtZS5zbGljZSgwLCBNYXRoLm1pbih0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGgsIGJ1Zl9sZW4pKSwgcHRyKTsKICB9CiAgY29uc3RydWN0b3IobmV4dF9jb29raWUsIG5hbWUsIHR5cGUpIHsKICAgIHRoaXMuZF9pbm8gPSAwbjsKICAgIGNvbnN0IGVuY29kZWRfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICAgIHRoaXMuZF9uZXh0ID0gbmV4dF9jb29raWU7CiAgICB0aGlzLmRfbmFtbGVuID0gZW5jb2RlZF9uYW1lLmJ5dGVMZW5ndGg7CiAgICB0aGlzLmRfdHlwZSA9IHR5cGU7CiAgICB0aGlzLmRpcl9uYW1lID0gZW5jb2RlZF9uYW1lOwogIH0KfTsKdmFyIEZERkxBR1NfQVBQRU5EID0gMSA8PCAwOwp2YXIgRkRGTEFHU19EU1lOQyA9IDEgPDwgMTsKdmFyIEZERkxBR1NfTk9OQkxPQ0sgPSAxIDw8IDI7CnZhciBGREZMQUdTX1JTWU5DID0gMSA8PCAzOwp2YXIgRkRGTEFHU19TWU5DID0gMSA8PCA0Owp2YXIgRmRzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50OChwdHIsIHRoaXMuZnNfZmlsZXR5cGUpOwogICAgdmlldy5zZXRVaW50MTYocHRyICsgMiwgdGhpcy5mc19mbGFncywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmZzX3JpZ2h0c19iYXNlLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDE2LCB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgZmxhZ3MpIHsKICAgIHRoaXMuZnNfcmlnaHRzX2Jhc2UgPSAwbjsKICAgIHRoaXMuZnNfcmlnaHRzX2luaGVyaXRlZCA9IDBuOwogICAgdGhpcy5mc19maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5mc19mbGFncyA9IGZsYWdzOwogIH0KfTsKdmFyIEZTVEZMQUdTX0FUSU0gPSAxIDw8IDA7CnZhciBGU1RGTEFHU19BVElNX05PVyA9IDEgPDwgMTsKdmFyIEZTVEZMQUdTX01USU0gPSAxIDw8IDI7CnZhciBGU1RGTEFHU19NVElNX05PVyA9IDEgPDwgMzsKdmFyIE9GTEFHU19DUkVBVCA9IDEgPDwgMDsKdmFyIE9GTEFHU19ESVJFQ1RPUlkgPSAxIDw8IDE7CnZhciBPRkxBR1NfRVhDTCA9IDEgPDwgMjsKdmFyIE9GTEFHU19UUlVOQyA9IDEgPDwgMzsKdmFyIEZpbGVzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRldiwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmlubywgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDE2LCB0aGlzLmZpbGV0eXBlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDI0LCB0aGlzLm5saW5rLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDMyLCB0aGlzLnNpemUsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgMzgsIHRoaXMuYXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA0NiwgdGhpcy5tdGltLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDUyLCB0aGlzLmN0aW0sIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgc2l6ZSkgewogICAgdGhpcy5kZXYgPSAwbjsKICAgIHRoaXMuaW5vID0gMG47CiAgICB0aGlzLm5saW5rID0gMG47CiAgICB0aGlzLmF0aW0gPSAwbjsKICAgIHRoaXMubXRpbSA9IDBuOwogICAgdGhpcy5jdGltID0gMG47CiAgICB0aGlzLmZpbGV0eXBlID0gZmlsZXR5cGU7CiAgICB0aGlzLnNpemUgPSBzaXplOwogIH0KfTsKdmFyIEVWRU5UUldGTEFHU19GRF9SRUFEV1JJVEVfSEFOR1VQID0gMSA8PCAwOwp2YXIgU1VCQ0xPQ0tGTEFHU19TVUJTQ1JJUFRJT05fQ0xPQ0tfQUJTVElNRSA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9QRUVLID0gMSA8PCAwOwp2YXIgUklGTEFHU19SRUNWX1dBSVRBTEwgPSAxIDw8IDE7CnZhciBST0ZMQUdTX1JFQ1ZfREFUQV9UUlVOQ0FURUQgPSAxIDw8IDA7CnZhciBTREZMQUdTX1JEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19XUiA9IDEgPDwgMTsKdmFyIFBSRU9QRU5UWVBFX0RJUiA9IDA7CnZhciBQcmVzdGF0RGlyID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50MzIocHRyLCB0aGlzLnByX25hbWUuYnl0ZUxlbmd0aCwgdHJ1ZSk7CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUpIHsKICAgIHRoaXMucHJfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICB9Cn07CnZhciBQcmVzdGF0ID0gY2xhc3MgewogIHN0YXRpYyBkaXIobmFtZSkgewogICAgY29uc3QgcHJlc3RhdCA9IG5ldyBQcmVzdGF0KCk7CiAgICBwcmVzdGF0LnRhZyA9IFBSRU9QRU5UWVBFX0RJUjsKICAgIHByZXN0YXQuaW5uZXIgPSBuZXcgUHJlc3RhdERpcihuYW1lKTsKICAgIHJldHVybiBwcmVzdGF0OwogIH0KICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy50YWcsIHRydWUpOwogICAgdGhpcy5pbm5lci53cml0ZV9ieXRlcyh2aWV3LCBwdHIgKyA0KTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2RlYnVnLmpzCnZhciBEZWJ1ZyA9IGNsYXNzIERlYnVnMiB7CiAgZW5hYmxlKGVuYWJsZWQpIHsKICAgIHRoaXMubG9nID0gY3JlYXRlTG9nZ2VyKGVuYWJsZWQgPT09IHZvaWQgMCA/IHRydWUgOiBlbmFibGVkLCB0aGlzLnByZWZpeCk7CiAgfQogIGdldCBlbmFibGVkKCkgewogICAgcmV0dXJuIHRoaXMuaXNFbmFibGVkOwogIH0KICBjb25zdHJ1Y3Rvcihpc0VuYWJsZWQpIHsKICAgIHRoaXMuaXNFbmFibGVkID0gaXNFbmFibGVkOwogICAgdGhpcy5wcmVmaXggPSAid2FzaToiOwogICAgdGhpcy5lbmFibGUoaXNFbmFibGVkKTsKICB9Cn07CmZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihlbmFibGVkLCBwcmVmaXgpIHsKICBpZiAoZW5hYmxlZCkgewogICAgY29uc3QgYSA9IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSwgIiVjJXMiLCAiY29sb3I6ICMyNjVCQTAiLCBwcmVmaXgpOwogICAgcmV0dXJuIGE7CiAgfSBlbHNlIHsKICAgIHJldHVybiAoKSA9PiB7CiAgICB9OwogIH0KfQp2YXIgZGVidWcgPSBuZXcgRGVidWcoZmFsc2UpOwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpLmpzCnZhciBXQVNJUHJvY0V4aXQgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKICBjb25zdHJ1Y3Rvcihjb2RlKSB7CiAgICBzdXBlcigiZXhpdCB3aXRoIGV4aXQgY29kZSAiICsgY29kZSk7CiAgICB0aGlzLmNvZGUgPSBjb2RlOwogIH0KfTsKdmFyIFdBU0kgPSBjbGFzcyBXQVNJMiB7CiAgc3RhcnQoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgdHJ5IHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQoKTsKICAgICAgcmV0dXJuIDA7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIGlmIChlIGluc3RhbmNlb2YgV0FTSVByb2NFeGl0KSB7CiAgICAgICAgcmV0dXJuIGUuY29kZTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aHJvdyBlOwogICAgICB9CiAgICB9CiAgfQogIGluaXRpYWxpemUoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgaWYgKGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUpIHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSgpOwogICAgfQogIH0KICBjb25zdHJ1Y3RvcihhcmdzLCBlbnYsIGZkcywgb3B0aW9ucyA9IHt9KSB7CiAgICB0aGlzLmFyZ3MgPSBbXTsKICAgIHRoaXMuZW52ID0gW107CiAgICB0aGlzLmZkcyA9IFtdOwogICAgZGVidWcuZW5hYmxlKG9wdGlvbnMuZGVidWcpOwogICAgdGhpcy5hcmdzID0gYXJnczsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2ZpbGVzdGF0X2dldChmZCwgZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGZkX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIGRlYnVnLmxvZyhwYXRoKTsKICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfcmVhZGxpbmsocGF0aCk7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVuYW1lKGZkLCBvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgbmV3X2ZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGxldCB7IHJldCwgaW5vZGVfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmsob2xkX3BhdGgpOwogICAgICAgIGlmIChpbm9kZV9vYmogPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgdHJ1ZSk7CiAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICBpZiAoc2VsZi5mZHNbZmRdLnBhdGhfbGluayhvbGRfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKSAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIHRocm93ICJwYXRoX2xpbmsgc2hvdWxkIGFsd2F5cyByZXR1cm4gc3VjY2VzcyB3aGVuIHJlbGlua2luZyBhbiBpbm9kZSBiYWNrIHRvIHRoZSBvcmlnaW5hbCBwbGFjZSI7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfc3ltbGluayhvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF91bmxpbmtfZmlsZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwb2xsX29uZW9mZihpbl8sIG91dCwgbnN1YnNjcmlwdGlvbnMpIHsKICAgICAgdGhyb3cgImFzeW5jIGlvIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgcHJvY19leGl0KGV4aXRfY29kZSkgewogICAgICB0aHJvdyBuZXcgV0FTSVByb2NFeGl0KGV4aXRfY29kZSk7CiAgICB9LCBwcm9jX3JhaXNlKHNpZykgewogICAgICB0aHJvdyAicmFpc2VkIHNpZ25hbCAiICsgc2lnOwogICAgfSwgc2NoZWRfeWllbGQoKSB7CiAgICB9LCByYW5kb21fZ2V0KGJ1ZiwgYnVmX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmX2xlbjsgaSsrKSB7CiAgICAgICAgYnVmZmVyOFtidWYgKyBpXSA9IE1hdGgucmFuZG9tKCkgKiAyNTYgfCAwOwogICAgICB9CiAgICB9LCBzb2NrX3JlY3YoZmQsIHJpX2RhdGEsIHJpX2ZsYWdzKSB7CiAgICAgIHRocm93ICJzb2NrZXRzIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgc29ja19zZW5kKGZkLCBzaV9kYXRhLCBzaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2h1dGRvd24oZmQsIGhvdykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfYWNjZXB0KGZkLCBmbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0gfTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZkLmpzCnZhciBGZCA9IGNsYXNzIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfY2xvc2UoKSB7CiAgICByZXR1cm4gMDsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBmZHN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBwcmVzdGF0OiBudWxsIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRpcmVudDogbnVsbCB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9zeW5jKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9saW5rKHBhdGgsIGlub2RlLCBhbGxvd19kaXIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rKHBhdGgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aCwgZGlyZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9yZWFkbGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9yZW5hbWUob2xkX3BhdGgsIG5ld19mZCwgbmV3X3BhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9Cn07CnZhciBJbm9kZSA9IGNsYXNzIHsKfTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3QvZnNfbWVtLmpzCnZhciBPcGVuRmlsZSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBvZmZzZXQgKyBsZW4pIHsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIGxlbikpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIDApIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IHNpemUpIHsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheSh0aGlzLmZpbGUuZGF0YS5idWZmZXIuc2xpY2UoMCwgTnVtYmVyKHNpemUpKSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihzaXplKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcih0aGlzLmZpbGVfcG9zKSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KHNsaWNlLmxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIob2Zmc2V0KSwgTnVtYmVyKG9mZnNldCArIEJpZ0ludChzaXplKSkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICBsZXQgY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICBzd2l0Y2ggKHdoZW5jZSkgewogICAgICBjYXNlIFdIRU5DRV9TRVQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0NVUjoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IHRoaXMuZmlsZV9wb3MgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0VORDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IEJpZ0ludCh0aGlzLmZpbGUuZGF0YS5ieXRlTGVuZ3RoKSArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICBpZiAoY2FsY3VsYXRlZF9vZmZzZXQgPCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIHRoaXMuZmlsZV9wb3MgPSBjYWxjdWxhdGVkX29mZnNldDsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIodGhpcy5maWxlX3BvcykpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKG9mZnNldCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZmlsZS5zdGF0KCkgfTsKICB9CiAgY29uc3RydWN0b3IoZmlsZSkgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZmlsZV9wb3MgPSAwbjsKICAgIHRoaXMuZmlsZSA9IGZpbGU7CiAgfQp9Owp2YXIgT3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMCkgfTsKICB9CiAgZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKSB7CiAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICBkZWJ1Zy5sb2coInJlYWRkaXJfc2luZ2xlIiwgY29va2llKTsKICAgICAgZGVidWcubG9nKGNvb2tpZSwgdGhpcy5kaXIuY29udGVudHMua2V5cygpKTsKICAgIH0KICAgIGlmIChjb29raWUgPT0gMG4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMW4sICIuIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfSBlbHNlIGlmIChjb29raWUgPT0gMW4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMm4sICIuLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0KICAgIGlmIChjb29raWUgPj0gQmlnSW50KHRoaXMuZGlyLmNvbnRlbnRzLnNpemUpICsgMm4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IFtuYW1lLCBlbnRyeV0gPSBBcnJheS5mcm9tKHRoaXMuZGlyLmNvbnRlbnRzLmVudHJpZXMoKSlbTnVtYmVyKGNvb2tpZSAtIDJuKV07CiAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbmV3IERpcmVudChjb29raWUgKyAxbiwgbmFtZSwgZW50cnkuc3RhdCgpLmZpbGV0eXBlKSB9OwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX2VyciwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX2VyciwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBmaWxlc3RhdDogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogZW50cnkuc3RhdCgpIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGhfc3RyLCBkaXJmbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGhfc3RyLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBsZXQgeyByZXQsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfZW50cnlfZm9yX3BhdGgocGF0aCk7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICBpZiAocmV0ICE9IEVSUk5PX05PRU5UKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0LCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19DUkVBVCkgPT0gT0ZMQUdTX0NSRUFUKSB7CiAgICAgICAgY29uc3QgeyByZXQ6IHJldDIsIGVudHJ5OiBuZXdfZW50cnkgfSA9IHRoaXMuZGlyLmNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkpOwogICAgICAgIGlmIChuZXdfZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiByZXQyLCBmZF9vYmo6IG51bGwgfTsKICAgICAgICB9CiAgICAgICAgZW50cnkgPSBuZXdfZW50cnk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoKG9mbGFncyAmIE9GTEFHU19FWENMKSA9PSBPRkxBR1NfRVhDTCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4gZW50cnkucGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoLCBPRkxBR1NfQ1JFQVQgfCBPRkxBR1NfRElSRUNUT1JZLCAwbiwgMG4sIDApLnJldDsKICB9CiAgcGF0aF9saW5rKHBhdGhfc3RyLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgY29uc3Qgc291cmNlX2lzX2RpciA9IGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGNvbnN0IHRhcmdldF9pc19kaXIgPSBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBpZiAoc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgaWYgKGFsbG93X2RpciAmJiBlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgewogICAgICAgICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgPT0gMCkgewogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYgKHNvdXJjZV9pc19kaXIgJiYgIXRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgICB9IGVsc2UgaWYgKCFzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICAgIH0gZWxzZSBpZiAoaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFKSB7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICB9CiAgICB9CiAgICBpZiAoIWFsbG93X2RpciAmJiBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19QRVJNOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLnNldChmaWxlbmFtZSwgaW5vZGUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfdW5saW5rKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlID09PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgfHwgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgIH0KICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplICE9PSAwKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgIH0KICAgIGlmICghcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZGlyLnN0YXQoKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGNvbnN0cnVjdG9yKGRpcikgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGlyID0gZGlyOwogIH0KfTsKdmFyIFByZW9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIE9wZW5EaXJlY3RvcnkgewogIGZkX3ByZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBwcmVzdGF0OiBQcmVzdGF0LmRpcih0aGlzLnByZXN0YXRfbmFtZSkgfTsKICB9CiAgY29uc3RydWN0b3IobmFtZSwgY29udGVudHMpIHsKICAgIHN1cGVyKG5ldyBEaXJlY3RvcnkoY29udGVudHMpKTsKICAgIHRoaXMucHJlc3RhdF9uYW1lID0gbmFtZTsKICB9Cn07CnZhciBGaWxlID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICBpZiAodGhpcy5yZWFkb25seSAmJiAoZnNfcmlnaHRzX2Jhc2UgJiBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgPT0gQmlnSW50KFJJR0hUU19GRF9XUklURSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX1RSVU5DKSA9PSBPRkxBR1NfVFJVTkMpIHsKICAgICAgaWYgKHRoaXMucmVhZG9ubHkpCiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoW10pOwogICAgfQogICAgY29uc3QgZmlsZSA9IG5ldyBPcGVuRmlsZSh0aGlzKTsKICAgIGlmIChmZF9mbGFncyAmIEZERkxBR1NfQVBQRU5EKQogICAgICBmaWxlLmZkX3NlZWsoMG4sIFdIRU5DRV9FTkQpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IGZpbGUgfTsKICB9CiAgZ2V0IHNpemUoKSB7CiAgICByZXR1cm4gQmlnSW50KHRoaXMuZGF0YS5ieXRlTGVuZ3RoKTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCB0aGlzLnNpemUpOwogIH0KICBjb25zdHJ1Y3RvcihkYXRhLCBvcHRpb25zKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7CiAgICB0aGlzLnJlYWRvbmx5ID0gISFvcHRpb25zPy5yZWFkb25seTsKICB9Cn07CnZhciBQYXRoID0gY2xhc3MgUGF0aDIgewogIHN0YXRpYyBmcm9tKHBhdGgpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aC5lbmRzV2l0aCgiLyIpOwogICAgaWYgKHBhdGguc3RhcnRzV2l0aCgiLyIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgfQogICAgaWYgKHBhdGguaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5zcGxpdCgiLyIpKSB7CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIiIHx8IGNvbXBvbmVudCA9PT0gIi4iKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKGNvbXBvbmVudCA9PT0gIi4uIikgewogICAgICAgIGlmIChzZWxmLnBhcnRzLnBvcCgpID09IHZvaWQgMCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIHNlbGYucGFydHMucHVzaChjb21wb25lbnQpOwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXRoOiBzZWxmIH07CiAgfQogIHRvX3BhdGhfc3RyaW5nKCkgewogICAgbGV0IHMgPSB0aGlzLnBhcnRzLmpvaW4oIi8iKTsKICAgIGlmICh0aGlzLmlzX2RpcikgewogICAgICBzICs9ICIvIjsKICAgIH0KICAgIHJldHVybiBzOwogIH0KICBjb25zdHJ1Y3RvcigpIHsKICAgIHRoaXMucGFydHMgPSBbXTsKICAgIHRoaXMuaXNfZGlyID0gZmFsc2U7CiAgfQp9Owp2YXIgRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogbmV3IE9wZW5EaXJlY3RvcnkodGhpcykgfTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwbik7CiAgfQogIGdldF9lbnRyeV9mb3JfcGF0aChwYXRoKSB7CiAgICBsZXQgZW50cnkgPSB0aGlzOwogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGFsbG93X3VuZGVmaW5lZCkgewogICAgY29uc3QgZmlsZW5hbWUgPSBwYXRoLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogZW50cnlfcmV0LCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKCEocGFyZW50X2VudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IGVudHJ5ID0gcGFyZW50X2VudHJ5LmNvbnRlbnRzLmdldChmaWxlbmFtZSk7CiAgICBpZiAoZW50cnkgPT09IHZvaWQgMCkgewogICAgICBpZiAoIWFsbG93X3VuZGVmaW5lZCkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9OwogIH0KICBjcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIGlzX2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgZGVidWcubG9nKCJjcmVhdGUiLCBwYXRoKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvaW5kZXguanMKZnVuY3Rpb24gcGFyc2VJbXBvcnRzKG1vZHVsZUJ5dGVzKSB7CiAgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcyk7CiAgfSBlbHNlIGlmIChtb2R1bGVCeXRlcy5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcy5idWZmZXIpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoIkFyZ3VtZW50IG11c3QgYmUgYSBidWZmZXIgc291cmNlLCBsaWtlIFVpbnQ4QXJyYXkgb3IgQXJyYXlCdWZmZXIiKTsKICB9CiAgY29uc3QgcGFyc2VTdGF0ZSA9IG5ldyBQYXJzZVN0YXRlKG1vZHVsZUJ5dGVzKTsKICBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpOwogIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKTsKICBjb25zdCB0eXBlcyA9IFtdOwogIGNvbnN0IGltcG9ydHMgPSBbXTsKICB3aGlsZSAocGFyc2VTdGF0ZS5oYXNNb3JlQnl0ZXMoKSkgewogICAgY29uc3Qgc2VjdGlvbklkID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgY29uc3Qgc2VjdGlvblNpemUgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgc3dpdGNoIChzZWN0aW9uSWQpIHsKICAgICAgY2FzZSAxOiB7CiAgICAgICAgY29uc3QgdHlwZUNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVDb3VudDsgaSsrKSB7CiAgICAgICAgICB0eXBlcy5wdXNoKHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAyOiB7CiAgICAgICAgY29uc3QgaW1wb3J0Q291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW1wb3J0Q291bnQ7IGkrKykgewogICAgICAgICAgY29uc3QgbW9kdWxlID0gcGFyc2VTdGF0ZS5yZWFkTmFtZSgpOwogICAgICAgICAgY29uc3QgbmFtZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJmdW5jdGlvbiIsIHR5cGU6IHR5cGVzW2luZGV4XSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgIGltcG9ydHMucHVzaCh7IG1vZHVsZSwgbmFtZSwga2luZDogInRhYmxlIiwgdHlwZTogcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJtZW1vcnkiLCB0eXBlOiBwYXJzZUxpbWl0cyhwYXJzZVN0YXRlKSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgIGltcG9ydHMucHVzaCh7IG1vZHVsZSwgbmFtZSwga2luZDogImdsb2JhbCIsIHR5cGU6IHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gaW1wb3J0IGRlc2NyaXB0b3IgdHlwZSAke3R5cGV9YCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbXBvcnRzOwogICAgICB9CiAgICAgIGRlZmF1bHQ6IHsKICAgICAgICBwYXJzZVN0YXRlLnNraXBCeXRlcyhzZWN0aW9uU2l6ZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFtdOwp9CnZhciBQYXJzZVN0YXRlID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG1vZHVsZUJ5dGVzKSB7CiAgICB0aGlzLm1vZHVsZUJ5dGVzID0gbW9kdWxlQnl0ZXM7CiAgICB0aGlzLm9mZnNldCA9IDA7CiAgICB0aGlzLnRleHREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpOwogIH0KICBoYXNNb3JlQnl0ZXMoKSB7CiAgICByZXR1cm4gdGhpcy5vZmZzZXQgPCB0aGlzLm1vZHVsZUJ5dGVzLmxlbmd0aDsKICB9CiAgcmVhZEJ5dGUoKSB7CiAgICByZXR1cm4gdGhpcy5tb2R1bGVCeXRlc1t0aGlzLm9mZnNldCsrXTsKICB9CiAgc2tpcEJ5dGVzKGNvdW50KSB7CiAgICB0aGlzLm9mZnNldCArPSBjb3VudDsKICB9CiAgcmVhZFVuc2lnbmVkTEVCMTI4KCkgewogICAgbGV0IHJlc3VsdCA9IDA7CiAgICBsZXQgc2hpZnQgPSAwOwogICAgbGV0IGJ5dGU7CiAgICBkbyB7CiAgICAgIGJ5dGUgPSB0aGlzLnJlYWRCeXRlKCk7CiAgICAgIHJlc3VsdCB8PSAoYnl0ZSAmIDEyNykgPDwgc2hpZnQ7CiAgICAgIHNoaWZ0ICs9IDc7CiAgICB9IHdoaWxlIChieXRlICYgMTI4KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfQogIHJlYWROYW1lKCkgewogICAgY29uc3QgbmFtZUxlbmd0aCA9IHRoaXMucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICBjb25zdCBuYW1lQnl0ZXMgPSB0aGlzLm1vZHVsZUJ5dGVzLnNsaWNlKHRoaXMub2Zmc2V0LCB0aGlzLm9mZnNldCArIG5hbWVMZW5ndGgpOwogICAgY29uc3QgbmFtZSA9IHRoaXMudGV4dERlY29kZXIuZGVjb2RlKG5hbWVCeXRlcyk7CiAgICB0aGlzLm9mZnNldCArPSBuYW1lTGVuZ3RoOwogICAgcmV0dXJuIG5hbWU7CiAgfQogIGFzc2VydEJ5dGVzKGV4cGVjdGVkKSB7CiAgICBjb25zdCBiYXNlT2Zmc2V0ID0gdGhpcy5vZmZzZXQ7CiAgICBjb25zdCBleHBlY3RlZExlbmd0aCA9IGV4cGVjdGVkLmxlbmd0aDsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwZWN0ZWRMZW5ndGg7IGkrKykgewogICAgICBpZiAodGhpcy5tb2R1bGVCeXRlc1tiYXNlT2Zmc2V0ICsgaV0gIT09IGV4cGVjdGVkW2ldKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSBhdCBvZmZzZXQgJHtiYXNlT2Zmc2V0fWApOwogICAgICB9CiAgICB9CiAgICB0aGlzLm9mZnNldCArPSBleHBlY3RlZExlbmd0aDsKICB9Cn07CmZ1bmN0aW9uIHBhcnNlTWFnaWNOdW1iZXIocGFyc2VTdGF0ZSkgewogIGNvbnN0IGV4cGVjdGVkID0gWzAsIDk3LCAxMTUsIDEwOV07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VWZXJzaW9uKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFsxLCAwLCAwLCAwXTsKICBwYXJzZVN0YXRlLmFzc2VydEJ5dGVzKGV4cGVjdGVkKTsKfQpmdW5jdGlvbiBwYXJzZVRhYmxlVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgZWxlbWVudFR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgbGV0IGVsZW1lbnQ7CiAgc3dpdGNoIChlbGVtZW50VHlwZSkgewogICAgY2FzZSAxMTI6CiAgICAgIGVsZW1lbnQgPSAiZnVuY3JlZiI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAxMTE6CiAgICAgIGVsZW1lbnQgPSAiZXh0ZXJucmVmIjsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdGFibGUgZWxlbWVudCB0eXBlICR7ZWxlbWVudFR5cGV9YCk7CiAgfQogIGNvbnN0IHsgbWluaW11bSwgbWF4aW11bSB9ID0gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSk7CiAgaWYgKG1heGltdW0pIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0sIG1heGltdW0gfTsKICB9IGVsc2UgewogICAgcmV0dXJuIHsgZWxlbWVudCwgbWluaW11bSB9OwogIH0KfQpmdW5jdGlvbiBwYXJzZUxpbWl0cyhwYXJzZVN0YXRlKSB7CiAgY29uc3QgZmxhZ3MgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgY29uc3QgbWluaW11bSA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgY29uc3QgaGFzTWF4aW11bSA9IGZsYWdzICYgMTsKICBjb25zdCBzaGFyZWQgPSAoZmxhZ3MgJiAyKSAhPT0gMDsKICBjb25zdCBpc01lbW9yeTY0ID0gKGZsYWdzICYgNCkgIT09IDA7CiAgY29uc3QgaW5kZXggPSBpc01lbW9yeTY0ID8gImk2NCIgOiAiaTMyIjsKICBpZiAoaGFzTWF4aW11bSkgewogICAgY29uc3QgbWF4aW11bSA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4LCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IG1pbmltdW0sIHNoYXJlZCwgaW5kZXggfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VHbG9iYWxUeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCB2YWx1ZSA9IHBhcnNlVmFsdWVUeXBlKHBhcnNlU3RhdGUpOwogIGNvbnN0IG11dGFibGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCkgPT09IDE7CiAgcmV0dXJuIHsgdmFsdWUsIG11dGFibGUgfTsKfQpmdW5jdGlvbiBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdHlwZSA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgMTI3OgogICAgICByZXR1cm4gImkzMiI7CiAgICBjYXNlIDEyNjoKICAgICAgcmV0dXJuICJpNjQiOwogICAgY2FzZSAxMjU6CiAgICAgIHJldHVybiAiZjMyIjsKICAgIGNhc2UgMTI0OgogICAgICByZXR1cm4gImY2NCI7CiAgICBjYXNlIDExMjoKICAgICAgcmV0dXJuICJmdW5jcmVmIjsKICAgIGNhc2UgMTExOgogICAgICByZXR1cm4gImV4dGVybnJlZiI7CiAgICBjYXNlIDEyMzoKICAgICAgcmV0dXJuICJ2MTI4IjsKICAgIGRlZmF1bHQ6CiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB2YWx1ZSB0eXBlICR7dHlwZX1gKTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VGdW5jdGlvblR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZvcm0gPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgaWYgKGZvcm0gIT09IDk2KSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGZ1bmN0aW9uIHR5cGUgZm9ybSAweDYwLCBnb3QgJHtmb3JtfWApOwogIH0KICBjb25zdCBwYXJhbWV0ZXJzID0gW107CiAgY29uc3QgcGFyYW1ldGVyQ291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1ldGVyQ291bnQ7IGkrKykgewogICAgcGFyYW1ldGVycy5wdXNoKHBhcnNlVmFsdWVUeXBlKHBhcnNlU3RhdGUpKTsKICB9CiAgY29uc3QgcmVzdWx0cyA9IFtdOwogIGNvbnN0IHJlc3VsdENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdENvdW50OyBpKyspIHsKICAgIHJlc3VsdHMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIHJldHVybiB7IHBhcmFtZXRlcnMsIHJlc3VsdHMgfTsKfQoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvcG9seWZpbGwuanMKdmFyIGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQgPSAoKCkgPT4gewogIGNvbnN0IG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoWwogICAgMCwKICAgIDk3LAogICAgMTE1LAogICAgMTA5LAogICAgMSwKICAgIDAsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICA2LAogICAgMSwKICAgIDAsCiAgICAwLAogICAgMiwKICAgIDAsCiAgICAxCiAgXSk7CiAgY29uc3QgbW9kdWxlID0gbmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShtb2R1bGVCeXRlcyk7CiAgY29uc3QgaW1wb3J0cyA9IFdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgY29uc3QgbWVtb3J5SW1wb3J0ID0gaW1wb3J0c1swXTsKICByZXR1cm4gdHlwZW9mIG1lbW9yeUltcG9ydC50eXBlID09PSAib2JqZWN0IjsKfSkoKTsKZnVuY3Rpb24gcG9seWZpbGwoV2ViQXNzZW1ibHkzKSB7CiAgaWYgKGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQpIHsKICAgIHJldHVybiBXZWJBc3NlbWJseTM7CiAgfQogIGNvbnN0IG5ld1dlYkFzc2VtYmx5ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoV2ViQXNzZW1ibHkzKSkgewogICAgbmV3V2ViQXNzZW1ibHlba2V5XSA9IFdlYkFzc2VtYmx5M1trZXldOwogIH0KICBjb25zdCBwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbCA9IFN5bWJvbCgicG9seWZpbGxlZEltcG9ydHNTeW1ib2wiKTsKICBjb25zdCBhc3NpZ25JbXBvcnRzID0gKG1vZHVsZSwgc291cmNlQnl0ZXMpID0+IHsKICAgIG1vZHVsZVtwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbF0gPSBwYXJzZUltcG9ydHMoc291cmNlQnl0ZXMpOwogIH07CiAgY29uc3QgbmV3TW9kdWxlID0gbmV3V2ViQXNzZW1ibHkuTW9kdWxlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICAgIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseTMuTW9kdWxlKGJ5dGVzKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBieXRlcyk7CiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YobW9kdWxlLCBuZXdNb2R1bGUucHJvdG90eXBlKTsKICAgIHJldHVybiBtb2R1bGU7CiAgfTsKICBPYmplY3Quc2V0UHJvdG90eXBlT2YobmV3TW9kdWxlLnByb3RvdHlwZSwgV2ViQXNzZW1ibHkzLk1vZHVsZS5wcm90b3R5cGUpOwogIG5ld1dlYkFzc2VtYmx5LmNvbXBpbGUgPSBhc3luYyAoc291cmNlKSA9PiB7CiAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseTMuY29tcGlsZShzb3VyY2UpOwogICAgYXNzaWduSW1wb3J0cyhtb2R1bGUsIHNvdXJjZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgaWYgKFdlYkFzc2VtYmx5My5jb21waWxlU3RyZWFtaW5nKSB7CiAgICBuZXdXZWJBc3NlbWJseS5jb21waWxlU3RyZWFtaW5nID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNvdXJjZTsKICAgICAgY29uc3QgY2xvbmUgPSByZXNwb25zZS5jbG9uZSgpOwogICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseTMuY29tcGlsZVN0cmVhbWluZyhyZXNwb25zZSk7CiAgICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBuZXcgVWludDhBcnJheShhd2FpdCBjbG9uZS5hcnJheUJ1ZmZlcigpKSk7CiAgICAgIHJldHVybiBtb2R1bGU7CiAgICB9OwogIH0KICBuZXdNb2R1bGUuaW1wb3J0cyA9IChtb2R1bGUpID0+IHsKICAgIGNvbnN0IHBhcnNlZEltcG9ydHMgPSBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdOwogICAgaWYgKCFwYXJzZWRJbXBvcnRzKSB7CiAgICAgIHJldHVybiBXZWJBc3NlbWJseTMuTW9kdWxlLmltcG9ydHMobW9kdWxlKTsKICAgIH0KICAgIHJldHVybiBwYXJzZWRJbXBvcnRzOwogIH07CiAgcmV0dXJuIG5ld1dlYkFzc2VtYmx5Owp9CgovLyBlbnRyeXBvaW50L2NvbW1vbi50cwp2YXIgV2ViQXNzZW1ibHkyID0gcG9seWZpbGwoZ2xvYmFsVGhpcy5XZWJBc3NlbWJseSk7CnZhciBMaW5lRGVjb2RlciA9IGNsYXNzIHsKICBjb25zdHJ1Y3RvcihvbkxpbmUpIHsKICAgIHRoaXMuZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIHRoaXMuYnVmZmVyID0gIiI7CiAgICB0aGlzLm9uTGluZSA9IG9uTGluZTsKICB9CiAgZGVjb2RlcjsKICBidWZmZXI7CiAgb25MaW5lOwogIHNlbmQoY2h1bmspIHsKICAgIHRoaXMuYnVmZmVyICs9IHRoaXMuZGVjb2Rlci5kZWNvZGUoY2h1bmssIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgY29uc3QgbGluZXMgPSB0aGlzLmJ1ZmZlci5zcGxpdCgiXG4iKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoIC0gMTsgaSsrKSB7CiAgICAgIHRoaXMub25MaW5lKGxpbmVzW2ldKTsKICAgIH0KICAgIHRoaXMuYnVmZmVyID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV07CiAgfQp9Owp2YXIgV2FzbVJ1bm5lciA9IChyYXdPcHRpb25zLCBTd2lmdFJ1bnRpbWUpID0+IHsKICBjb25zdCBvcHRpb25zID0gZGVmYXVsdFJ1bm5lck9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0OwogIGlmIChTd2lmdFJ1bnRpbWUpIHsKICAgIHN3aWZ0ID0gbmV3IFN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJncyA9IG9wdGlvbnMuYXJncyB8fCBbXTsKICBjb25zdCBmZHMgPSBbCiAgICBuZXcgT3BlbkZpbGUobmV3IEZpbGUoW10pKSwKICAgIHN0ZG91dCwKICAgIHN0ZGVyciwKICAgIG5ldyBQcmVvcGVuRGlyZWN0b3J5KCIvIiwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSkKICBdOwogIGNvbnN0IGVudnMgPSBvcHRpb25zLmVudiA/IE9iamVjdC5lbnRyaWVzKG9wdGlvbnMuZW52KS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYCR7a2V5fT0ke3ZhbHVlfWApIDogW107CiAgY29uc3Qgd2FzaSA9IG5ldyBXQVNJKGFyZ3MsIGVudnMsIGZkcywgewogICAgZGVidWc6IGZhbHNlCiAgfSk7CiAgY29uc3QgY3JlYXRlV2FzbUltcG9ydE9iamVjdCA9IChleHRyYVdhc21JbXBvcnRzLCBtb2R1bGUpID0+IHsKICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IHsKICAgICAgd2FzaV9zbmFwc2hvdF9wcmV2aWV3MTogd2FzaS53YXNpSW1wb3J0CiAgICB9OwogICAgaWYgKHN3aWZ0KSB7CiAgICAgIGltcG9ydE9iamVjdC5qYXZhc2NyaXB0X2tpdCA9IHN3aWZ0Lndhc21JbXBvcnRzOwogICAgfQogICAgaWYgKGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgZm9yIChjb25zdCBtb2R1bGVOYW1lIGluIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgICBpZiAoIWltcG9ydE9iamVjdFttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdID0ge307CiAgICAgICAgfQogICAgICAgIGZvciAoY29uc3QgZW50cnkgaW4gZXh0cmFXYXNtSW1wb3J0c1ttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdW2VudHJ5XSA9IGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV1bZW50cnldOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZm9yIChjb25zdCBfaW1wb3J0RW50cnkgb2YgV2ViQXNzZW1ibHkyLk1vZHVsZS5pbXBvcnRzKG1vZHVsZSkpIHsKICAgICAgY29uc3QgaW1wb3J0RW50cnkgPSBfaW1wb3J0RW50cnk7CiAgICAgIGlmICghaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXSA9IHt9OwogICAgICB9CiAgICAgIGlmIChpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSkgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJmdW5jdGlvbiIpIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfSBlbHNlIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJtZW1vcnkiICYmIGltcG9ydEVudHJ5Lm1vZHVsZSA9PSAiZW52IiAmJiBpbXBvcnRFbnRyeS5uYW1lID09ICJtZW1vcnkiKSB7CiAgICAgICAgY29uc3QgdHlwZSA9IGltcG9ydEVudHJ5LnR5cGU7CiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsKICAgICAgICAgIGluaXRpYWw6IHR5cGUubWluaW11bSwKICAgICAgICAgIG1heGltdW06IHR5cGUubWF4aW11bSwKICAgICAgICAgIHNoYXJlZDogdHlwZS5zaGFyZWQKICAgICAgICB9OwogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gbmV3IFdlYkFzc2VtYmx5Mi5NZW1vcnkoZGVzY3JpcHRvcik7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBpbXBvcnRPYmplY3Q7CiAgfTsKICByZXR1cm4gewogICAgYXN5bmMgcnVuKHdhc21CeXRlcywgZXh0cmFXYXNtSW1wb3J0cykgewogICAgICBpZiAoIWV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgICBleHRyYVdhc21JbXBvcnRzID0ge307CiAgICAgIH0KICAgICAgZXh0cmFXYXNtSW1wb3J0cy5fX3N0YWNrX3Nhbml0aXplciA9IHsKICAgICAgICByZXBvcnRfc3RhY2tfb3ZlcmZsb3c6ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiRGV0ZWN0ZWQgc3RhY2sgYnVmZmVyIG92ZXJmbG93LiIpOwogICAgICAgIH0KICAgICAgfTsKICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkyLmNvbXBpbGUod2FzbUJ5dGVzKTsKICAgICAgY29uc3QgaW1wb3J0T2JqZWN0ID0gY3JlYXRlV2FzbUltcG9ydE9iamVjdChleHRyYVdhc21JbXBvcnRzLCBtb2R1bGUpOwogICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IFdlYkFzc2VtYmx5Mi5pbnN0YW50aWF0ZShtb2R1bGUsIGltcG9ydE9iamVjdCk7CiAgICAgIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICAgICAgc3dpZnQuc2V0SW5zdGFuY2UoaW5zdGFuY2UpOwogICAgICB9CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLnN0YXJ0KGluc3RhbmNlKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgICAgICBpZiAoc3dpZnQgJiYgc3dpZnQubWFpbikgewogICAgICAgICAgc3dpZnQubWFpbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMubWFpbiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YoMCwgMCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKfTsKdmFyIGRlZmF1bHRSdW5uZXJPcHRpb25zID0gKG9wdGlvbnMpID0+IHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIHJldHVybiBvcHRpb25zOwp9OwoKLy8gZW50cnlwb2ludC9idW5kbGUudHMKdmFyIHN0YXJ0V2FzaVRhc2sgPSBhc3luYyAoKSA9PiB7CiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgiUkVQTEFDRV9USElTX1dJVEhfVEhFX01BSU5fV0VCQVNTRU1CTFlfTU9EVUxFIik7CiAgY29uc3QgcmVzcG9uc2VBcnJheUJ1ZmZlciA9IGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICB9IGNhdGNoIHsKICB9CiAgY29uc3Qgd2FzbVJ1bm5lciA9IFdhc21SdW5uZXIoewogICAgb25TdGRvdXRMaW5lKGxpbmUpIHsKICAgICAgY29uc29sZS5sb2cobGluZSk7CiAgICB9LAogICAgb25TdGRlcnJMaW5lKGxpbmUpIHsKICAgICAgY29uc29sZS5lcnJvcihsaW5lKTsKICAgIH0KICB9LCBydW50aW1lQ29uc3RydWN0b3IpOwogIGNvbnN0IHdhc21CeXRlcyA9IG5ldyBVaW50OEFycmF5KHJlc3BvbnNlQXJyYXlCdWZmZXIpLmJ1ZmZlcjsKICBhd2FpdCB3YXNtUnVubmVyLnJ1bih3YXNtQnl0ZXMpOwp9Owphc3luYyBmdW5jdGlvbiBtYWluKCkgewogIGF3YWl0IHN0YXJ0V2FzaVRhc2soKTsKfQptYWluKCk7Cg==")! + public static let test: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL3JlY29ubmVjdGluZy13ZWJzb2NrZXQvZGlzdC9yZWNvbm5lY3Rpbmctd2Vic29ja2V0LW1qcy5qcwp2YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24oZDIsIGIyKSB7CiAgICBkMi5fX3Byb3RvX18gPSBiMjsKICB9IHx8IGZ1bmN0aW9uKGQyLCBiMikgewogICAgZm9yICh2YXIgcCBpbiBiMikKICAgICAgaWYgKGIyLmhhc093blByb3BlcnR5KHApKQogICAgICAgIGQyW3BdID0gYjJbcF07CiAgfTsKICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKfTsKZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzKGQsIGIpOwogIGZ1bmN0aW9uIF9fKCkgewogICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7CiAgfQogIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKfQpmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7CiAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSAiZnVuY3Rpb24iICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7CiAgaWYgKG0pCiAgICByZXR1cm4gbS5jYWxsKG8pOwogIHJldHVybiB7CiAgICBuZXh0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkKICAgICAgICBvID0gdm9pZCAwOwogICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07CiAgICB9CiAgfTsKfQpmdW5jdGlvbiBfX3JlYWQobywgbikgewogIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07CiAgaWYgKCFtKQogICAgcmV0dXJuIG87CiAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7CiAgdHJ5IHsKICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKQogICAgICBhci5wdXNoKHIudmFsdWUpOwogIH0gY2F0Y2ggKGVycm9yKSB7CiAgICBlID0geyBlcnJvciB9OwogIH0gZmluYWxseSB7CiAgICB0cnkgewogICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVsicmV0dXJuIl0pKQogICAgICAgIG0uY2FsbChpKTsKICAgIH0gZmluYWxseSB7CiAgICAgIGlmIChlKQogICAgICAgIHRocm93IGUuZXJyb3I7CiAgICB9CiAgfQogIHJldHVybiBhcjsKfQpmdW5jdGlvbiBfX3NwcmVhZCgpIHsKICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykKICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTsKICByZXR1cm4gYXI7Cn0KdmFyIEV2ZW50ID0gZnVuY3Rpb24oKSB7CiAgZnVuY3Rpb24gRXZlbnQyKHR5cGUsIHRhcmdldCkgewogICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CiAgICB0aGlzLnR5cGUgPSB0eXBlOwogIH0KICByZXR1cm4gRXZlbnQyOwp9KCk7CnZhciBFcnJvckV2ZW50ID0gZnVuY3Rpb24oX3N1cGVyKSB7CiAgX19leHRlbmRzKEVycm9yRXZlbnQyLCBfc3VwZXIpOwogIGZ1bmN0aW9uIEVycm9yRXZlbnQyKGVycm9yLCB0YXJnZXQpIHsKICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJlcnJvciIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLm1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlOwogICAgX3RoaXMuZXJyb3IgPSBlcnJvcjsKICAgIHJldHVybiBfdGhpczsKICB9CiAgcmV0dXJuIEVycm9yRXZlbnQyOwp9KEV2ZW50KTsKdmFyIENsb3NlRXZlbnQgPSBmdW5jdGlvbihfc3VwZXIpIHsKICBfX2V4dGVuZHMoQ2xvc2VFdmVudDIsIF9zdXBlcik7CiAgZnVuY3Rpb24gQ2xvc2VFdmVudDIoY29kZSwgcmVhc29uLCB0YXJnZXQpIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIGlmIChyZWFzb24gPT09IHZvaWQgMCkgewogICAgICByZWFzb24gPSAiIjsKICAgIH0KICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJjbG9zZSIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLndhc0NsZWFuID0gdHJ1ZTsKICAgIF90aGlzLmNvZGUgPSBjb2RlOwogICAgX3RoaXMucmVhc29uID0gcmVhc29uOwogICAgcmV0dXJuIF90aGlzOwogIH0KICByZXR1cm4gQ2xvc2VFdmVudDI7Cn0oRXZlbnQpOwp2YXIgZ2V0R2xvYmFsV2ViU29ja2V0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKHR5cGVvZiBXZWJTb2NrZXQgIT09ICJ1bmRlZmluZWQiKSB7CiAgICByZXR1cm4gV2ViU29ja2V0OwogIH0KfTsKdmFyIGlzV2ViU29ja2V0ID0gZnVuY3Rpb24odykgewogIHJldHVybiB0eXBlb2YgdyAhPT0gInVuZGVmaW5lZCIgJiYgISF3ICYmIHcuQ0xPU0lORyA9PT0gMjsKfTsKdmFyIERFRkFVTFQgPSB7CiAgbWF4UmVjb25uZWN0aW9uRGVsYXk6IDFlNCwKICBtaW5SZWNvbm5lY3Rpb25EZWxheTogMWUzICsgTWF0aC5yYW5kb20oKSAqIDRlMywKICBtaW5VcHRpbWU6IDVlMywKICByZWNvbm5lY3Rpb25EZWxheUdyb3dGYWN0b3I6IDEuMywKICBjb25uZWN0aW9uVGltZW91dDogNGUzLAogIG1heFJldHJpZXM6IEluZmluaXR5LAogIG1heEVucXVldWVkTWVzc2FnZXM6IEluZmluaXR5LAogIHN0YXJ0Q2xvc2VkOiBmYWxzZSwKICBkZWJ1ZzogZmFsc2UKfTsKdmFyIFJlY29ubmVjdGluZ1dlYlNvY2tldCA9IGZ1bmN0aW9uKCkgewogIGZ1bmN0aW9uIFJlY29ubmVjdGluZ1dlYlNvY2tldDIodXJsLCBwcm90b2NvbHMsIG9wdGlvbnMpIHsKICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7CiAgICAgIG9wdGlvbnMgPSB7fTsKICAgIH0KICAgIHRoaXMuX2xpc3RlbmVycyA9IHsKICAgICAgZXJyb3I6IFtdLAogICAgICBtZXNzYWdlOiBbXSwKICAgICAgb3BlbjogW10sCiAgICAgIGNsb3NlOiBbXQogICAgfTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIHRoaXMuX3Nob3VsZFJlY29ubmVjdCA9IHRydWU7CiAgICB0aGlzLl9jb25uZWN0TG9jayA9IGZhbHNlOwogICAgdGhpcy5fYmluYXJ5VHlwZSA9ICJibG9iIjsKICAgIHRoaXMuX2Nsb3NlQ2FsbGVkID0gZmFsc2U7CiAgICB0aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgIHRoaXMub25jbG9zZSA9IG51bGw7CiAgICB0aGlzLm9uZXJyb3IgPSBudWxsOwogICAgdGhpcy5vbm1lc3NhZ2UgPSBudWxsOwogICAgdGhpcy5vbm9wZW4gPSBudWxsOwogICAgdGhpcy5faGFuZGxlT3BlbiA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgIF90aGlzLl9kZWJ1Zygib3BlbiBldmVudCIpOwogICAgICB2YXIgX2EgPSBfdGhpcy5fb3B0aW9ucy5taW5VcHRpbWUsIG1pblVwdGltZSA9IF9hID09PSB2b2lkIDAgPyBERUZBVUxULm1pblVwdGltZSA6IF9hOwogICAgICBjbGVhclRpbWVvdXQoX3RoaXMuX2Nvbm5lY3RUaW1lb3V0KTsKICAgICAgX3RoaXMuX3VwdGltZVRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5fYWNjZXB0T3BlbigpOwogICAgICB9LCBtaW5VcHRpbWUpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fbWVzc2FnZVF1ZXVlLmZvckVhY2goZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHJldHVybiBfdGhpcy5fd3Muc2VuZChtZXNzYWdlKTsKICAgICAgfSk7CiAgICAgIF90aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgICAgaWYgKF90aGlzLm9ub3BlbikgewogICAgICAgIF90aGlzLm9ub3BlbihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5vcGVuLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZU1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkgewogICAgICBfdGhpcy5fZGVidWcoIm1lc3NhZ2UgZXZlbnQiKTsKICAgICAgaWYgKF90aGlzLm9ubWVzc2FnZSkgewogICAgICAgIF90aGlzLm9ubWVzc2FnZShldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5tZXNzYWdlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUVycm9yID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJlcnJvciBldmVudCIsIGV2ZW50Lm1lc3NhZ2UpOwogICAgICBfdGhpcy5fZGlzY29ubmVjdCh2b2lkIDAsIGV2ZW50Lm1lc3NhZ2UgPT09ICJUSU1FT1VUIiA/ICJ0aW1lb3V0IiA6IHZvaWQgMCk7CiAgICAgIGlmIChfdGhpcy5vbmVycm9yKSB7CiAgICAgICAgX3RoaXMub25lcnJvcihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJleGVjIGVycm9yIGxpc3RlbmVycyIpOwogICAgICBfdGhpcy5fbGlzdGVuZXJzLmVycm9yLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgICBfdGhpcy5fY29ubmVjdCgpOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUNsb3NlID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJjbG9zZSBldmVudCIpOwogICAgICBfdGhpcy5fY2xlYXJUaW1lb3V0cygpOwogICAgICBpZiAoX3RoaXMuX3Nob3VsZFJlY29ubmVjdCkgewogICAgICAgIF90aGlzLl9jb25uZWN0KCk7CiAgICAgIH0KICAgICAgaWYgKF90aGlzLm9uY2xvc2UpIHsKICAgICAgICBfdGhpcy5vbmNsb3NlKGV2ZW50KTsKICAgICAgfQogICAgICBfdGhpcy5fbGlzdGVuZXJzLmNsb3NlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX3VybCA9IHVybDsKICAgIHRoaXMuX3Byb3RvY29scyA9IHByb3RvY29sczsKICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zOwogICAgaWYgKHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQpIHsKICAgICAgdGhpcy5fc2hvdWxkUmVjb25uZWN0ID0gZmFsc2U7CiAgICB9CiAgICB0aGlzLl9jb25uZWN0KCk7CiAgfQogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ09OTkVDVElORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiAwOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0MiwgIk9QRU4iLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gMTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIsICJDTE9TSU5HIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ0xPU0VEIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDM7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNPTk5FQ1RJTkciLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5DT05ORUNUSU5HOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJPUEVOIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIFJlY29ubmVjdGluZ1dlYlNvY2tldDIuT1BFTjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiQ0xPU0lORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NJTkc7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNMT1NFRCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRDsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYmluYXJ5VHlwZSIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmJpbmFyeVR5cGUgOiB0aGlzLl9iaW5hcnlUeXBlOwogICAgfSwKICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgdGhpcy5fYmluYXJ5VHlwZSA9IHZhbHVlOwogICAgICBpZiAodGhpcy5fd3MpIHsKICAgICAgICB0aGlzLl93cy5iaW5hcnlUeXBlID0gdmFsdWU7CiAgICAgIH0KICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicmV0cnlDb3VudCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBNYXRoLm1heCh0aGlzLl9yZXRyeUNvdW50LCAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYnVmZmVyZWRBbW91bnQiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICB2YXIgYnl0ZXMgPSB0aGlzLl9tZXNzYWdlUXVldWUucmVkdWNlKGZ1bmN0aW9uKGFjYywgbWVzc2FnZSkgewogICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgIGFjYyArPSBtZXNzYWdlLmxlbmd0aDsKICAgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBCbG9iKSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5zaXplOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5ieXRlTGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYWNjOwogICAgICB9LCAwKTsKICAgICAgcmV0dXJuIGJ5dGVzICsgKHRoaXMuX3dzID8gdGhpcy5fd3MuYnVmZmVyZWRBbW91bnQgOiAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiZXh0ZW5zaW9ucyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmV4dGVuc2lvbnMgOiAiIjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicHJvdG9jb2wiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gdGhpcy5fd3MgPyB0aGlzLl93cy5wcm90b2NvbCA6ICIiOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJyZWFkeVN0YXRlIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKHRoaXMuX3dzKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX3dzLnJlYWR5U3RhdGU7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQgPyBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRCA6IFJlY29ubmVjdGluZ1dlYlNvY2tldDIuQ09OTkVDVElORzsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAidXJsIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIHRoaXMuX3dzID8gdGhpcy5fd3MudXJsIDogIiI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICBpZiAoY29kZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvZGUgPSAxZTM7CiAgICB9CiAgICB0aGlzLl9jbG9zZUNhbGxlZCA9IHRydWU7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSBmYWxzZTsKICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlIGVucXVldWVkOiBubyB3cyBpbnN0YW5jZSIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlOiBhbHJlYWR5IGNsb3NlZCIpOwogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSB0cnVlOwogICAgdGhpcy5fY2xvc2VDYWxsZWQgPSBmYWxzZTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIGlmICghdGhpcy5fd3MgfHwgdGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fY29ubmVjdCgpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5fZGlzY29ubmVjdChjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9jb25uZWN0KCk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSkgewogICAgaWYgKHRoaXMuX3dzICYmIHRoaXMuX3dzLnJlYWR5U3RhdGUgPT09IHRoaXMuT1BFTikgewogICAgICB0aGlzLl9kZWJ1Zygic2VuZCIsIGRhdGEpOwogICAgICB0aGlzLl93cy5zZW5kKGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucy5tYXhFbnF1ZXVlZE1lc3NhZ2VzLCBtYXhFbnF1ZXVlZE1lc3NhZ2VzID0gX2EgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4RW5xdWV1ZWRNZXNzYWdlcyA6IF9hOwogICAgICBpZiAodGhpcy5fbWVzc2FnZVF1ZXVlLmxlbmd0aCA8IG1heEVucXVldWVkTWVzc2FnZXMpIHsKICAgICAgICB0aGlzLl9kZWJ1ZygiZW5xdWV1ZSIsIGRhdGEpOwogICAgICAgIHRoaXMuX21lc3NhZ2VRdWV1ZS5wdXNoKGRhdGEpOwogICAgICB9CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdLnB1c2gobGlzdGVuZXIpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuZGlzcGF0Y2hFdmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICB2YXIgZV8xLCBfYTsKICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnNbZXZlbnQudHlwZV07CiAgICBpZiAobGlzdGVuZXJzKSB7CiAgICAgIHRyeSB7CiAgICAgICAgZm9yICh2YXIgbGlzdGVuZXJzXzEgPSBfX3ZhbHVlcyhsaXN0ZW5lcnMpLCBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpOyAhbGlzdGVuZXJzXzFfMS5kb25lOyBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpKSB7CiAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNfMV8xLnZhbHVlOwogICAgICAgICAgdGhpcy5fY2FsbEV2ZW50TGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyKTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2ggKGVfMV8xKSB7CiAgICAgICAgZV8xID0geyBlcnJvcjogZV8xXzEgfTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICB0cnkgewogICAgICAgICAgaWYgKGxpc3RlbmVyc18xXzEgJiYgIWxpc3RlbmVyc18xXzEuZG9uZSAmJiAoX2EgPSBsaXN0ZW5lcnNfMS5yZXR1cm4pKQogICAgICAgICAgICBfYS5jYWxsKGxpc3RlbmVyc18xKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgaWYgKGVfMSkKICAgICAgICAgICAgdGhyb3cgZV8xLmVycm9yOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdID0gdGhpcy5fbGlzdGVuZXJzW3R5cGVdLmZpbHRlcihmdW5jdGlvbihsKSB7CiAgICAgICAgcmV0dXJuIGwgIT09IGxpc3RlbmVyOwogICAgICB9KTsKICAgIH0KICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9kZWJ1ZyA9IGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3MgPSBbXTsKICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7CiAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTsKICAgIH0KICAgIGlmICh0aGlzLl9vcHRpb25zLmRlYnVnKSB7CiAgICAgIGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIF9fc3ByZWFkKFsiUldTPiJdLCBhcmdzKSk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fZ2V0TmV4dERlbGF5ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX2EgPSB0aGlzLl9vcHRpb25zLCBfYiA9IF9hLnJlY29ubmVjdGlvbkRlbGF5R3Jvd0ZhY3RvciwgcmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQucmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yIDogX2IsIF9jID0gX2EubWluUmVjb25uZWN0aW9uRGVsYXksIG1pblJlY29ubmVjdGlvbkRlbGF5ID0gX2MgPT09IHZvaWQgMCA/IERFRkFVTFQubWluUmVjb25uZWN0aW9uRGVsYXkgOiBfYywgX2QgPSBfYS5tYXhSZWNvbm5lY3Rpb25EZWxheSwgbWF4UmVjb25uZWN0aW9uRGVsYXkgPSBfZCA9PT0gdm9pZCAwID8gREVGQVVMVC5tYXhSZWNvbm5lY3Rpb25EZWxheSA6IF9kOwogICAgdmFyIGRlbGF5ID0gMDsKICAgIGlmICh0aGlzLl9yZXRyeUNvdW50ID4gMCkgewogICAgICBkZWxheSA9IG1pblJlY29ubmVjdGlvbkRlbGF5ICogTWF0aC5wb3cocmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yLCB0aGlzLl9yZXRyeUNvdW50IC0gMSk7CiAgICAgIGlmIChkZWxheSA+IG1heFJlY29ubmVjdGlvbkRlbGF5KSB7CiAgICAgICAgZGVsYXkgPSBtYXhSZWNvbm5lY3Rpb25EZWxheTsKICAgICAgfQogICAgfQogICAgdGhpcy5fZGVidWcoIm5leHQgZGVsYXkiLCBkZWxheSk7CiAgICByZXR1cm4gZGVsYXk7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fd2FpdCA9IGZ1bmN0aW9uKCkgewogICAgdmFyIF90aGlzID0gdGhpczsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7CiAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgX3RoaXMuX2dldE5leHREZWxheSgpKTsKICAgIH0pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2dldE5leHRVcmwgPSBmdW5jdGlvbih1cmxQcm92aWRlcikgewogICAgaWYgKHR5cGVvZiB1cmxQcm92aWRlciA9PT0gInN0cmluZyIpIHsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1cmxQcm92aWRlcik7CiAgICB9CiAgICBpZiAodHlwZW9mIHVybFByb3ZpZGVyID09PSAiZnVuY3Rpb24iKSB7CiAgICAgIHZhciB1cmwgPSB1cmxQcm92aWRlcigpOwogICAgICBpZiAodHlwZW9mIHVybCA9PT0gInN0cmluZyIpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVybCk7CiAgICAgIH0KICAgICAgaWYgKCEhdXJsLnRoZW4pIHsKICAgICAgICByZXR1cm4gdXJsOwogICAgICB9CiAgICB9CiAgICB0aHJvdyBFcnJvcigiSW52YWxpZCBVUkwiKTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jb25uZWN0ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX3RoaXMgPSB0aGlzOwogICAgaWYgKHRoaXMuX2Nvbm5lY3RMb2NrIHx8ICF0aGlzLl9zaG91bGRSZWNvbm5lY3QpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fY29ubmVjdExvY2sgPSB0cnVlOwogICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucywgX2IgPSBfYS5tYXhSZXRyaWVzLCBtYXhSZXRyaWVzID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4UmV0cmllcyA6IF9iLCBfYyA9IF9hLmNvbm5lY3Rpb25UaW1lb3V0LCBjb25uZWN0aW9uVGltZW91dCA9IF9jID09PSB2b2lkIDAgPyBERUZBVUxULmNvbm5lY3Rpb25UaW1lb3V0IDogX2MsIF9kID0gX2EuV2ViU29ja2V0LCBXZWJTb2NrZXQyID0gX2QgPT09IHZvaWQgMCA/IGdldEdsb2JhbFdlYlNvY2tldCgpIDogX2Q7CiAgICBpZiAodGhpcy5fcmV0cnlDb3VudCA+PSBtYXhSZXRyaWVzKSB7CiAgICAgIHRoaXMuX2RlYnVnKCJtYXggcmV0cmllcyByZWFjaGVkIiwgdGhpcy5fcmV0cnlDb3VudCwgIj49IiwgbWF4UmV0cmllcyk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIHRoaXMuX3JldHJ5Q291bnQrKzsKICAgIHRoaXMuX2RlYnVnKCJjb25uZWN0IiwgdGhpcy5fcmV0cnlDb3VudCk7CiAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lcnMoKTsKICAgIGlmICghaXNXZWJTb2NrZXQoV2ViU29ja2V0MikpIHsKICAgICAgdGhyb3cgRXJyb3IoIk5vIHZhbGlkIFdlYlNvY2tldCBjbGFzcyBwcm92aWRlZCIpOwogICAgfQogICAgdGhpcy5fd2FpdCgpLnRoZW4oZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBfdGhpcy5fZ2V0TmV4dFVybChfdGhpcy5fdXJsKTsKICAgIH0pLnRoZW4oZnVuY3Rpb24odXJsKSB7CiAgICAgIGlmIChfdGhpcy5fY2xvc2VDYWxsZWQpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJjb25uZWN0IiwgeyB1cmwsIHByb3RvY29sczogX3RoaXMuX3Byb3RvY29scyB9KTsKICAgICAgX3RoaXMuX3dzID0gX3RoaXMuX3Byb3RvY29scyA/IG5ldyBXZWJTb2NrZXQyKHVybCwgX3RoaXMuX3Byb3RvY29scykgOiBuZXcgV2ViU29ja2V0Mih1cmwpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fY29ubmVjdExvY2sgPSBmYWxzZTsKICAgICAgX3RoaXMuX2FkZExpc3RlbmVycygpOwogICAgICBfdGhpcy5fY29ubmVjdFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5faGFuZGxlVGltZW91dCgpOwogICAgICB9LCBjb25uZWN0aW9uVGltZW91dCk7CiAgICB9KTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9oYW5kbGVUaW1lb3V0ID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLl9kZWJ1ZygidGltZW91dCBldmVudCIpOwogICAgdGhpcy5faGFuZGxlRXJyb3IobmV3IEVycm9yRXZlbnQoRXJyb3IoIlRJTUVPVVQiKSwgdGhpcykpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2Rpc2Nvbm5lY3QgPSBmdW5jdGlvbihjb2RlLCByZWFzb24pIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJzKCk7CiAgICB0cnkgewogICAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9oYW5kbGVDbG9zZShuZXcgQ2xvc2VFdmVudChjb2RlLCByZWFzb24sIHRoaXMpKTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fYWNjZXB0T3BlbiA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5fZGVidWcoImFjY2VwdCBvcGVuIik7CiAgICB0aGlzLl9yZXRyeUNvdW50ID0gMDsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jYWxsRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBsaXN0ZW5lcikgewogICAgaWYgKCJoYW5kbGVFdmVudCIgaW4gbGlzdGVuZXIpIHsKICAgICAgbGlzdGVuZXIuaGFuZGxlRXZlbnQoZXZlbnQpOwogICAgfSBlbHNlIHsKICAgICAgbGlzdGVuZXIoZXZlbnQpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX3JlbW92ZUxpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygicmVtb3ZlTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2FkZExpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygiYWRkTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2NsZWFyVGltZW91dHMgPSBmdW5jdGlvbigpIHsKICAgIGNsZWFyVGltZW91dCh0aGlzLl9jb25uZWN0VGltZW91dCk7CiAgICBjbGVhclRpbWVvdXQodGhpcy5fdXB0aW1lVGltZW91dCk7CiAgfTsKICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0MjsKfSgpOwp2YXIgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdCA9IFJlY29ubmVjdGluZ1dlYlNvY2tldDsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJncywgZW52LCBmZHMsIG9wdGlvbnMgPSB7fSkgewogICAgdGhpcy5hcmdzID0gW107CiAgICB0aGlzLmVudiA9IFtdOwogICAgdGhpcy5mZHMgPSBbXTsKICAgIGRlYnVnLmVuYWJsZShvcHRpb25zLmRlYnVnKTsKICAgIHRoaXMuYXJncyA9IGFyZ3M7CiAgICB0aGlzLmVudiA9IGVudjsKICAgIHRoaXMuZmRzID0gZmRzOwogICAgY29uc3Qgc2VsZiA9IHRoaXM7CiAgICB0aGlzLndhc2lJbXBvcnQgPSB7IGFyZ3Nfc2l6ZXNfZ2V0KGFyZ2MsIGFyZ3ZfYnVmX3NpemUpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ2MsIHNlbGYuYXJncy5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGFyZyBvZiBzZWxmLmFyZ3MpIHsKICAgICAgICBidWZfc2l6ZSArPSBhcmcubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3ZfYnVmX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoYXJnYywgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGFyZ3NfZ2V0KGFyZ3YsIGFyZ3ZfYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2FyZ3ZfYnVmID0gYXJndl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5hcmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihhcmd2LCBhcmd2X2J1ZiwgdHJ1ZSk7CiAgICAgICAgYXJndiArPSA0OwogICAgICAgIGNvbnN0IGFyZyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmFyZ3NbaV0pOwogICAgICAgIGJ1ZmZlcjguc2V0KGFyZywgYXJndl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChhcmd2X2J1ZiArIGFyZy5sZW5ndGgsIDApOwogICAgICAgIGFyZ3ZfYnVmICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgICAgZGVidWcubG9nKG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvcmlnX2FyZ3ZfYnVmLCBhcmd2X2J1ZikpKTsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fc2l6ZXNfZ2V0KGVudmlyb25fY291bnQsIGVudmlyb25fc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9jb3VudCwgc2VsZi5lbnYubGVuZ3RoLCB0cnVlKTsKICAgICAgbGV0IGJ1Zl9zaXplID0gMDsKICAgICAgZm9yIChjb25zdCBlbnZpcm9uIG9mIHNlbGYuZW52KSB7CiAgICAgICAgYnVmX3NpemUgKz0gZW52aXJvbi5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9zaXplLCBidWZfc2l6ZSwgdHJ1ZSk7CiAgICAgIGRlYnVnLmxvZyhidWZmZXIuZ2V0VWludDMyKGVudmlyb25fY291bnQsIHRydWUpLCBidWZmZXIuZ2V0VWludDMyKGVudmlyb25fc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fZ2V0KGVudmlyb24sIGVudmlyb25fYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2Vudmlyb25fYnVmID0gZW52aXJvbl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5lbnYubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGVudmlyb24sIGVudmlyb25fYnVmLCB0cnVlKTsKICAgICAgICBlbnZpcm9uICs9IDQ7CiAgICAgICAgY29uc3QgZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmVudltpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoZSwgZW52aXJvbl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChlbnZpcm9uX2J1ZiArIGUubGVuZ3RoLCAwKTsKICAgICAgICBlbnZpcm9uX2J1ZiArPSBlLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfZW52aXJvbl9idWYsIGVudmlyb25fYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgY2xvY2tfcmVzX2dldChpZCwgcmVzX3B0cikgewogICAgICBsZXQgcmVzb2x1dGlvblZhbHVlOwogICAgICBzd2l0Y2ggKGlkKSB7CiAgICAgICAgY2FzZSBDTE9DS0lEX01PTk9UT05JQzogewogICAgICAgICAgcmVzb2x1dGlvblZhbHVlID0gNTAwMG47CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDTE9DS0lEX1JFQUxUSU1FOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSAxMDAwMDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuIEVSUk5PX05PU1lTOwogICAgICB9CiAgICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIHZpZXcuc2V0QmlnVWludDY0KHJlc19wdHIsIHJlc29sdXRpb25WYWx1ZSwgdHJ1ZSk7CiAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgfSwgY2xvY2tfdGltZV9nZXQoaWQsIHByZWNpc2lvbiwgdGltZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChpZCA9PT0gQ0xPQ0tJRF9SRUFMVElNRSkgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgQmlnSW50KG5ldyBEYXRlKCkuZ2V0VGltZSgpKSAqIDEwMDAwMDBuLCB0cnVlKTsKICAgICAgfSBlbHNlIGlmIChpZCA9PSBDTE9DS0lEX01PTk9UT05JQykgewogICAgICAgIGxldCBtb25vdG9uaWNfdGltZTsKICAgICAgICB0cnkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSBCaWdJbnQoTWF0aC5yb3VuZChwZXJmb3JtYW5jZS5ub3coKSAqIDFlNikpOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIG1vbm90b25pY190aW1lID0gMG47CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgbW9ub3RvbmljX3RpbWUsIHRydWUpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgMG4sIHRydWUpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZmRfYWR2aXNlKGZkLCBvZmZzZXQsIGxlbiwgYWR2aWNlKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2FsbG9jYXRlKGZkLCBvZmZzZXQsIGxlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9jbG9zZShmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW2ZkXS5mZF9jbG9zZSgpOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9kYXRhc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfZ2V0KGZkLCBmZHN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZkc3RhdCB9ID0gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmRzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZkc3RhdC53cml0ZV9ieXRlcyhuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlciksIGZkc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfc2V0X2ZsYWdzKGZkLCBmbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZkLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X2dldChmZCwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfZ2V0KCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfc2V0X3NpemUoZmQsIHNpemUpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlYWQoaW92ZWMuYnVmX2xlbiwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgb2Zmc2V0ICs9IEJpZ0ludChkYXRhLmxlbmd0aCk7CiAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggIT0gaW92ZWMuYnVmX2xlbikgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9nZXQoZmQsIGJ1Zl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBwcmVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgYnVmX3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZXN0YXRfZGlyX25hbWUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBjb25zdCBwcmVzdGF0X2Rpcl9uYW1lID0gcHJlc3RhdC5pbm5lci5wcl9uYW1lOwogICAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgICBidWZmZXI4LnNldChwcmVzdGF0X2Rpcl9uYW1lLnNsaWNlKDAsIHBhdGhfbGVuKSwgcGF0aF9wdHIpOwogICAgICAgIHJldHVybiBwcmVzdGF0X2Rpcl9uYW1lLmJ5dGVMZW5ndGggPiBwYXRoX2xlbiA/IEVSUk5PX05BTUVUT09MT05HIDogRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHdyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbndyaXR0ZW5fcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IENpb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbndyaXR0ZW4gPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCBkYXRhID0gYnVmZmVyOC5zbGljZShpb3ZlYy5idWYsIGlvdmVjLmJ1ZiArIGlvdmVjLmJ1Zl9sZW4pOwogICAgICAgICAgY29uc3QgeyByZXQsIG53cml0dGVuOiBud3JpdHRlbl9wYXJ0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHdyaXRlKGRhdGEsIG9mZnNldCk7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIG53cml0dGVuICs9IG53cml0dGVuX3BhcnQ7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KG53cml0dGVuX3BhcnQpOwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG5yZWFkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBJb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbnJlYWQgPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLmZkX3JlYWQoaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGEsIGlvdmVjLmJ1Zik7CiAgICAgICAgICBucmVhZCArPSBkYXRhLmxlbmd0aDsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkZGlyKGZkLCBidWYsIGJ1Zl9sZW4sIGNvb2tpZSwgYnVmdXNlZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgbGV0IGJ1ZnVzZWQgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGlyZW50IH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKTsKICAgICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChkaXJlbnQgPT0gbnVsbCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5oZWFkX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNvbnN0IGhlYWRfYnl0ZXMgPSBuZXcgQXJyYXlCdWZmZXIoZGlyZW50LmhlYWRfbGVuZ3RoKCkpOwogICAgICAgICAgZGlyZW50LndyaXRlX2hlYWRfYnl0ZXMobmV3IERhdGFWaWV3KGhlYWRfYnl0ZXMpLCAwKTsKICAgICAgICAgIGJ1ZmZlcjguc2V0KG5ldyBVaW50OEFycmF5KGhlYWRfYnl0ZXMpLnNsaWNlKDAsIE1hdGgubWluKGhlYWRfYnl0ZXMuYnl0ZUxlbmd0aCwgYnVmX2xlbiAtIGJ1ZnVzZWQpKSwgYnVmKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50LmhlYWRfbGVuZ3RoKCk7CiAgICAgICAgICBpZiAoYnVmX2xlbiAtIGJ1ZnVzZWQgPCBkaXJlbnQubmFtZV9sZW5ndGgoKSkgewogICAgICAgICAgICBidWZ1c2VkID0gYnVmX2xlbjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBkaXJlbnQud3JpdGVfbmFtZV9ieXRlcyhidWZmZXI4LCBidWYsIGJ1Zl9sZW4gLSBidWZ1c2VkKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50Lm5hbWVfbGVuZ3RoKCk7CiAgICAgICAgICBjb29raWUgPSBkaXJlbnQuZF9uZXh0OwogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcmVudW1iZXIoZmQsIHRvKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW3RvXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCByZXQgPSBzZWxmLmZkc1t0b10uZmRfY2xvc2UoKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzW3RvXSA9IHNlbGYuZmRzW2ZkXTsKICAgICAgICBzZWxmLmZkc1tmZF0gPSB2b2lkIDA7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3NlZWsoZmQsIG9mZnNldCwgd2hlbmNlLCBvZmZzZXRfb3V0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIG9mZnNldDogb2Zmc2V0X291dCB9ID0gc2VsZi5mZHNbZmRdLmZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdJbnQ2NChvZmZzZXRfb3V0X3B0ciwgb2Zmc2V0X291dCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF90ZWxsKGZkLCBvZmZzZXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfdGVsbCgpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQob2Zmc2V0X3B0ciwgb2Zmc2V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF93cml0ZShmZCwgaW92c19wdHIsIGlvdnNfbGVuLCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF93cml0ZShkYXRhKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIGlmIChud3JpdHRlbl9wYXJ0ICE9IGRhdGEuYnl0ZUxlbmd0aCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9nZXQoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGZpbGVzdGF0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2xpbmsob2xkX2ZkLCBvbGRfZmxhZ3MsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW29sZF9mZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW29sZF9mZF0ucGF0aF9sb29rdXAob2xkX3BhdGgsIG9sZF9mbGFncyk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgZmFsc2UpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX29wZW4oZmQsIGRpcmZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncywgb3BlbmVkX2ZkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgpOwogICAgICAgIGNvbnN0IHsgcmV0LCBmZF9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGgsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncyk7CiAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBzZWxmLmZkcy5wdXNoKGZkX29iaik7CiAgICAgICAgY29uc3Qgb3BlbmVkX2ZkID0gc2VsZi5mZHMubGVuZ3RoIC0gMTsKICAgICAgICBidWZmZXIuc2V0VWludDMyKG9wZW5lZF9mZF9wdHIsIG9wZW5lZF9mZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVhZGxpbmsoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbiwgYnVmX3B0ciwgYnVmX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3JlYWRsaW5rKHBhdGgpOwogICAgICAgIGlmIChkYXRhICE9IG51bGwpIHsKICAgICAgICAgIGNvbnN0IGRhdGFfYnVmID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGRhdGEpOwogICAgICAgICAgaWYgKGRhdGFfYnVmLmxlbmd0aCA+IGJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIDAsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGFfYnVmLCBidWZfcHRyKTsKICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBkYXRhX2J1Zi5sZW5ndGgsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbW92ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbmFtZShmZCwgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCAmJiBzZWxmLmZkc1tuZXdfZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICBsZXQgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfdW5saW5rKG9sZF9wYXRoKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldCA9IHNlbGYuZmRzW25ld19mZF0ucGF0aF9saW5rKG5ld19wYXRoLCBpbm9kZV9vYmosIHRydWUpOwogICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgaWYgKHNlbGYuZmRzW2ZkXS5wYXRoX2xpbmsob2xkX3BhdGgsIGlub2RlX29iaiwgdHJ1ZSkgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICB0aHJvdyAicGF0aF9saW5rIHNob3VsZCBhbHdheXMgcmV0dXJuIHN1Y2Nlc3Mgd2hlbiByZWxpbmtpbmcgYW4gaW5vZGUgYmFjayB0byB0aGUgb3JpZ2luYWwgcGxhY2UiOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3N5bWxpbmsob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIGZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfdW5saW5rX2ZpbGUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmtfZmlsZShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGgsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfcmVhZGxpbmsocGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG51bGwgfTsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQp9Owp2YXIgSW5vZGUgPSBjbGFzcyB7Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZzX21lbS5qcwp2YXIgT3BlbkZpbGUgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gb2Zmc2V0ICsgbGVuKSB7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBsZW4pKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCAwKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBzaXplKSB7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5maWxlLmRhdGEuYnVmZmVyLnNsaWNlKDAsIE51bWJlcihzaXplKSkpOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIoc2l6ZSkpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIodGhpcy5maWxlX3BvcyksIE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KHNpemUpKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChzbGljZS5sZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKG9mZnNldCksIE51bWJlcihvZmZzZXQgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgbGV0IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgc3dpdGNoICh3aGVuY2UpIHsKICAgICAgY2FzZSBXSEVOQ0VfU0VUOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9DVVI6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSB0aGlzLmZpbGVfcG9zICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9FTkQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBCaWdJbnQodGhpcy5maWxlLmRhdGEuYnl0ZUxlbmd0aCkgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgaWYgKGNhbGN1bGF0ZWRfb2Zmc2V0IDwgMCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICB0aGlzLmZpbGVfcG9zID0gY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcihvZmZzZXQpKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmZpbGUuc3RhdCgpIH07CiAgfQogIGNvbnN0cnVjdG9yKGZpbGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmZpbGVfcG9zID0gMG47CiAgICB0aGlzLmZpbGUgPSBmaWxlOwogIH0KfTsKdmFyIE9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9ESVJFQ1RPUlksIDApIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgZGVidWcubG9nKCJyZWFkZGlyX3NpbmdsZSIsIGNvb2tpZSk7CiAgICAgIGRlYnVnLmxvZyhjb29raWUsIHRoaXMuZGlyLmNvbnRlbnRzLmtleXMoKSk7CiAgICB9CiAgICBpZiAoY29va2llID09IDBuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDFuLCAiLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0gZWxzZSBpZiAoY29va2llID09IDFuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDJuLCAiLi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9CiAgICBpZiAoY29va2llID49IEJpZ0ludCh0aGlzLmRpci5jb250ZW50cy5zaXplKSArIDJuKSB7CiAgICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBbbmFtZSwgZW50cnldID0gQXJyYXkuZnJvbSh0aGlzLmRpci5jb250ZW50cy5lbnRyaWVzKCkpW051bWJlcihjb29raWUgLSAybildOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG5ldyBEaXJlbnQoY29va2llICsgMW4sIG5hbWUsIGVudHJ5LnN0YXQoKS5maWxldHlwZSkgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9lcnIsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IGVudHJ5LnN0YXQoKSB9OwogIH0KICBwYXRoX2xvb2t1cChwYXRoX3N0ciwgZGlyZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoX3N0ciwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgaWYgKHJldCAhPSBFUlJOT19OT0VOVCkgewogICAgICAgIHJldHVybiB7IHJldCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfQ1JFQVQpID09IE9GTEFHU19DUkVBVCkgewogICAgICAgIGNvbnN0IHsgcmV0OiByZXQyLCBlbnRyeTogbmV3X2VudHJ5IH0gPSB0aGlzLmRpci5jcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZKTsKICAgICAgICBpZiAobmV3X2VudHJ5ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiB7IHJldDogcmV0MiwgZmRfb2JqOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGVudHJ5ID0gbmV3X2VudHJ5OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICB9IGVsc2UgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRVhDTCkgPT0gT0ZMQUdTX0VYQ0wpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIGVudHJ5LnBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncyk7CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gdGhpcy5wYXRoX29wZW4oMCwgcGF0aCwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIGNvbnN0IHNvdXJjZV9pc19kaXIgPSBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBjb25zdCB0YXJnZXRfaXNfZGlyID0gZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgaWYgKHNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIGlmIChhbGxvd19kaXIgJiYgZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHsKICAgICAgICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplID09IDApIHsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChzb3VyY2VfaXNfZGlyICYmICF0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgICAgfSBlbHNlIGlmICghc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgICB9IGVsc2UgaWYgKGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSkgewogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgfQogICAgfQogICAgaWYgKCFhbGxvd19kaXIgJiYgaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fUEVSTTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIGlub2RlKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3VubGluayhwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF91bmxpbmtfZmlsZShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHx8IGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICB9CiAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSAhPT0gMCkgewogICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICB9CiAgICBpZiAoIXBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpKSB7CiAgICAgIHJldHVybiBFUlJOT19OT0VOVDsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmRpci5zdGF0KCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBjb25zdHJ1Y3RvcihkaXIpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRpciA9IGRpcjsKICB9Cn07CnZhciBQcmVvcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBPcGVuRGlyZWN0b3J5IHsKICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgcHJlc3RhdDogUHJlc3RhdC5kaXIodGhpcy5wcmVzdGF0X25hbWUpIH07CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnRzKSB7CiAgICBzdXBlcihuZXcgRGlyZWN0b3J5KGNvbnRlbnRzKSk7CiAgICB0aGlzLnByZXN0YXRfbmFtZSA9IG5hbWU7CiAgfQp9Owp2YXIgRmlsZSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgaWYgKHRoaXMucmVhZG9ubHkgJiYgKGZzX3JpZ2h0c19iYXNlICYgQmlnSW50KFJJR0hUU19GRF9XUklURSkpID09IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19UUlVOQykgPT0gT0ZMQUdTX1RSVU5DKSB7CiAgICAgIGlmICh0aGlzLnJlYWRvbmx5KQogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KFtdKTsKICAgIH0KICAgIGNvbnN0IGZpbGUgPSBuZXcgT3BlbkZpbGUodGhpcyk7CiAgICBpZiAoZmRfZmxhZ3MgJiBGREZMQUdTX0FQUEVORCkKICAgICAgZmlsZS5mZF9zZWVrKDBuLCBXSEVOQ0VfRU5EKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZmRfb2JqOiBmaWxlIH07CiAgfQogIGdldCBzaXplKCkgewogICAgcmV0dXJuIEJpZ0ludCh0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgdGhpcy5zaXplKTsKICB9CiAgY29uc3RydWN0b3IoZGF0YSwgb3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgdGhpcy5yZWFkb25seSA9ICEhb3B0aW9ucz8ucmVhZG9ubHk7CiAgfQp9Owp2YXIgUGF0aCA9IGNsYXNzIFBhdGgyIHsKICBzdGF0aWMgZnJvbShwYXRoKSB7CiAgICBjb25zdCBzZWxmID0gbmV3IFBhdGgyKCk7CiAgICBzZWxmLmlzX2RpciA9IHBhdGguZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVENBUEFCTEUsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGlmIChwYXRoLmluY2x1ZGVzKCJcMCIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGguc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aCkgewogICAgbGV0IGVudHJ5ID0gdGhpczsKICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgucGFydHMpIHsKICAgICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgICAgY29uc3QgY2hpbGQgPSBlbnRyeS5jb250ZW50cy5nZXQoY29tcG9uZW50KTsKICAgICAgaWYgKGNoaWxkICE9PSB2b2lkIDApIHsKICAgICAgICBlbnRyeSA9IGNoaWxkOwogICAgICB9IGVsc2UgewogICAgICAgIGRlYnVnLmxvZyhjb21wb25lbnQpOwogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBhbGxvd191bmRlZmluZWQpIHsKICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5wYXJ0cy5wb3AoKTsKICAgIGlmIChmaWxlbmFtZSA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldDogZW50cnlfcmV0LCBlbnRyeTogcGFyZW50X2VudHJ5IH0gPSB0aGlzLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfTsKICB9CiAgY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCBpc19kaXIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGRlYnVnLmxvZygiY3JlYXRlIiwgcGF0aCk7CiAgICBsZXQgbmV3X2NoaWxkOwogICAgaWYgKCFpc19kaXIpIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IEZpbGUobmV3IEFycmF5QnVmZmVyKDApKTsKICAgIH0gZWxzZSB7CiAgICAgIG5ld19jaGlsZCA9IG5ldyBEaXJlY3RvcnkoLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSk7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBuZXdfY2hpbGQpOwogICAgZW50cnkgPSBuZXdfY2hpbGQ7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGNvbnN0cnVjdG9yKGNvbnRlbnRzKSB7CiAgICBzdXBlcigpOwogICAgaWYgKGNvbnRlbnRzIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgdGhpcy5jb250ZW50cyA9IG5ldyBNYXAoY29udGVudHMpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5jb250ZW50cyA9IGNvbnRlbnRzOwogICAgfQogIH0KfTsKdmFyIENvbnNvbGVTdGRvdXQgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmaWxlc3RhdCA9IG5ldyBGaWxlc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCBCaWdJbnQoMCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdCB9OwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgY29uc3QgZmRzdGF0ID0gbmV3IEZkc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCAwKTsKICAgIGZkc3RhdC5mc19yaWdodHNfYmFzZSA9IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgdGhpcy53cml0ZShkYXRhKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBzdGF0aWMgbGluZUJ1ZmZlcmVkKHdyaXRlKSB7CiAgICBjb25zdCBkZWMgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICBsZXQgbGluZV9idWYgPSAiIjsKICAgIHJldHVybiBuZXcgQ29uc29sZVN0ZG91dCgoYnVmZmVyKSA9PiB7CiAgICAgIGxpbmVfYnVmICs9IGRlYy5kZWNvZGUoYnVmZmVyLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgICAgY29uc3QgbGluZXMgPSBsaW5lX2J1Zi5zcGxpdCgiXG4iKTsKICAgICAgZm9yIChjb25zdCBbaSwgbGluZV0gb2YgbGluZXMuZW50cmllcygpKSB7CiAgICAgICAgaWYgKGkgPCBsaW5lcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICB3cml0ZShsaW5lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGluZV9idWYgPSBsaW5lOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfQogIGNvbnN0cnVjdG9yKHdyaXRlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy53cml0ZSA9IHdyaXRlOwogIH0KfTsKCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL2luZGV4LmpzCmZ1bmN0aW9uIHBhcnNlSW1wb3J0cyhtb2R1bGVCeXRlcykgewogIGlmIChtb2R1bGVCeXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsKICB9IGVsc2UgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMpOwogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMuYnVmZmVyKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCJBcmd1bWVudCBtdXN0IGJlIGEgYnVmZmVyIHNvdXJjZSwgbGlrZSBVaW50OEFycmF5IG9yIEFycmF5QnVmZmVyIik7CiAgfQogIGNvbnN0IHBhcnNlU3RhdGUgPSBuZXcgUGFyc2VTdGF0ZShtb2R1bGVCeXRlcyk7CiAgcGFyc2VNYWdpY051bWJlcihwYXJzZVN0YXRlKTsKICBwYXJzZVZlcnNpb24ocGFyc2VTdGF0ZSk7CiAgY29uc3QgdHlwZXMgPSBbXTsKICBjb25zdCBpbXBvcnRzID0gW107CiAgd2hpbGUgKHBhcnNlU3RhdGUuaGFzTW9yZUJ5dGVzKCkpIHsKICAgIGNvbnN0IHNlY3Rpb25JZCA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICAgIGNvbnN0IHNlY3Rpb25TaXplID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgIHN3aXRjaCAoc2VjdGlvbklkKSB7CiAgICAgIGNhc2UgMTogewogICAgICAgIGNvbnN0IHR5cGVDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eXBlQ291bnQ7IGkrKykgewogICAgICAgICAgdHlwZXMucHVzaChwYXJzZUZ1bmN0aW9uVHlwZShwYXJzZVN0YXRlKSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgMjogewogICAgICAgIGNvbnN0IGltcG9ydENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGltcG9ydENvdW50OyBpKyspIHsKICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobW9kdWxlQnl0ZXMpOwogIGNvbnN0IGltcG9ydHMgPSBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpOwogIGNvbnN0IG1lbW9yeUltcG9ydCA9IGltcG9ydHNbMF07CiAgcmV0dXJuIHR5cGVvZiBtZW1vcnlJbXBvcnQudHlwZSA9PT0gIm9iamVjdCI7Cn0pKCk7CmZ1bmN0aW9uIHBvbHlmaWxsKFdlYkFzc2VtYmx5MykgewogIGlmIChoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0KSB7CiAgICByZXR1cm4gV2ViQXNzZW1ibHkzOwogIH0KICBjb25zdCBuZXdXZWJBc3NlbWJseSA9IHt9OwogIGZvciAoY29uc3Qga2V5IGluIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKFdlYkFzc2VtYmx5MykpIHsKICAgIG5ld1dlYkFzc2VtYmx5W2tleV0gPSBXZWJBc3NlbWJseTNba2V5XTsKICB9CiAgY29uc3QgcG9seWZpbGxlZEltcG9ydHNTeW1ib2wgPSBTeW1ib2woInBvbHlmaWxsZWRJbXBvcnRzU3ltYm9sIik7CiAgY29uc3QgYXNzaWduSW1wb3J0cyA9IChtb2R1bGUsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdID0gcGFyc2VJbXBvcnRzKHNvdXJjZUJ5dGVzKTsKICB9OwogIGNvbnN0IG5ld01vZHVsZSA9IG5ld1dlYkFzc2VtYmx5Lk1vZHVsZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICBjb25zdCBtb2R1bGUgPSBuZXcgV2ViQXNzZW1ibHkzLk1vZHVsZShieXRlcyk7CiAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZSwgbmV3TW9kdWxlLnByb3RvdHlwZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG5ld01vZHVsZS5wcm90b3R5cGUsIFdlYkFzc2VtYmx5My5Nb2R1bGUucHJvdG90eXBlKTsKICBuZXdXZWJBc3NlbWJseS5jb21waWxlID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBzb3VyY2UpOwogICAgcmV0dXJuIG1vZHVsZTsKICB9OwogIGlmIChXZWJBc3NlbWJseTMuY29tcGlsZVN0cmVhbWluZykgewogICAgbmV3V2ViQXNzZW1ibHkuY29tcGlsZVN0cmVhbWluZyA9IGFzeW5jIChzb3VyY2UpID0+IHsKICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzb3VyY2U7CiAgICAgIGNvbnN0IGNsb25lID0gcmVzcG9uc2UuY2xvbmUoKTsKICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgbmV3IFVpbnQ4QXJyYXkoYXdhaXQgY2xvbmUuYXJyYXlCdWZmZXIoKSkpOwogICAgICByZXR1cm4gbW9kdWxlOwogICAgfTsKICB9CiAgbmV3TW9kdWxlLmltcG9ydHMgPSAobW9kdWxlKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXTsKICAgIGlmICghcGFyc2VkSW1wb3J0cykgewogICAgICByZXR1cm4gV2ViQXNzZW1ibHkzLk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgICB9CiAgICByZXR1cm4gcGFyc2VkSW1wb3J0czsKICB9OwogIHJldHVybiBuZXdXZWJBc3NlbWJseTsKfQoKLy8gZW50cnlwb2ludC9jb21tb24udHMKdmFyIFdlYkFzc2VtYmx5MiA9IHBvbHlmaWxsKGdsb2JhbFRoaXMuV2ViQXNzZW1ibHkpOwp2YXIgTGluZURlY29kZXIgPSBjbGFzcyB7CiAgY29uc3RydWN0b3Iob25MaW5lKSB7CiAgICB0aGlzLmRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICB0aGlzLmJ1ZmZlciA9ICIiOwogICAgdGhpcy5vbkxpbmUgPSBvbkxpbmU7CiAgfQogIGRlY29kZXI7CiAgYnVmZmVyOwogIG9uTGluZTsKICBzZW5kKGNodW5rKSB7CiAgICB0aGlzLmJ1ZmZlciArPSB0aGlzLmRlY29kZXIuZGVjb2RlKGNodW5rLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgIGNvbnN0IGxpbmVzID0gdGhpcy5idWZmZXIuc3BsaXQoIlxuIik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykgewogICAgICB0aGlzLm9uTGluZShsaW5lc1tpXSk7CiAgICB9CiAgICB0aGlzLmJ1ZmZlciA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdOwogIH0KfTsKdmFyIFdhc21SdW5uZXIgPSAocmF3T3B0aW9ucywgU3dpZnRSdW50aW1lKSA9PiB7CiAgY29uc3Qgb3B0aW9ucyA9IGRlZmF1bHRSdW5uZXJPcHRpb25zKHJhd09wdGlvbnMpOwogIGxldCBzd2lmdDsKICBpZiAoU3dpZnRSdW50aW1lKSB7CiAgICBzd2lmdCA9IG5ldyBTd2lmdFJ1bnRpbWUoKTsKICB9CiAgbGV0IHN0ZG91dExpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRvdXRMaW5lICE9IG51bGwpIHsKICAgIHN0ZG91dExpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZG91dExpbmUpOwogIH0KICBjb25zdCBzdGRvdXQgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRvdXQ/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRvdXRMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBsZXQgc3RkZXJyTGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZGVyckxpbmUgIT0gbnVsbCkgewogICAgc3RkZXJyTGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3RkZXJyTGluZSk7CiAgfQogIGNvbnN0IHN0ZGVyciA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZGVycj8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZGVyckxpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGNvbnN0IGFyZ3MgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzLCBlbnZzLCBmZHMsIHsKICAgIGRlYnVnOiBmYWxzZQogIH0pOwogIGNvbnN0IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QgPSAoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QgPSB7CiAgICAgIHdhc2lfc25hcHNob3RfcHJldmlldzE6IHdhc2kud2FzaUltcG9ydAogICAgfTsKICAgIGlmIChzd2lmdCkgewogICAgICBpbXBvcnRPYmplY3QuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgaWYgKCFpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgX2ltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Mi5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpKSB7CiAgICAgIGNvbnN0IGltcG9ydEVudHJ5ID0gX2ltcG9ydEVudHJ5OwogICAgICBpZiAoIWltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0gPSB7fTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0gPSAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEltcG9ydGVkIGZ1bmN0aW9uICR7aW1wb3J0RW50cnkubW9kdWxlfS4ke2ltcG9ydEVudHJ5Lm5hbWV9IG5vdCBpbXBsZW1lbnRlZGApOwogICAgICAgIH07CiAgICAgIH0gZWxzZSBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAibWVtb3J5IiAmJiBpbXBvcnRFbnRyeS5tb2R1bGUgPT0gImVudiIgJiYgaW1wb3J0RW50cnkubmFtZSA9PSAibWVtb3J5IikgewogICAgICAgIGNvbnN0IHR5cGUgPSBpbXBvcnRFbnRyeS50eXBlOwogICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB7CiAgICAgICAgICBpbml0aWFsOiB0eXBlLm1pbmltdW0sCiAgICAgICAgICBtYXhpbXVtOiB0eXBlLm1heGltdW0sCiAgICAgICAgICBzaGFyZWQ6IHR5cGUuc2hhcmVkCiAgICAgICAgfTsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9IG5ldyBXZWJBc3NlbWJseTIuTWVtb3J5KGRlc2NyaXB0b3IpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0OwogIH07CiAgcmV0dXJuIHsKICAgIGFzeW5jIHJ1bih3YXNtQnl0ZXMsIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgaWYgKCFleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgZXh0cmFXYXNtSW1wb3J0cyA9IHt9OwogICAgICB9CiAgICAgIGV4dHJhV2FzbUltcG9ydHMuX19zdGFja19zYW5pdGl6ZXIgPSB7CiAgICAgICAgcmVwb3J0X3N0YWNrX292ZXJmbG93OiAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkRldGVjdGVkIHN0YWNrIGJ1ZmZlciBvdmVyZmxvdy4iKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIGNvbnN0IG1vZHVsZSA9IGF3YWl0IFdlYkFzc2VtYmx5Mi5jb21waWxlKHdhc21CeXRlcyk7CiAgICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKTsKICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBXZWJBc3NlbWJseTIuaW5zdGFudGlhdGUobW9kdWxlLCBpbXBvcnRPYmplY3QpOwogICAgICBpZiAoc3dpZnQgJiYgaW5zdGFuY2UuZXhwb3J0cy5zd2pzX2xpYnJhcnlfdmVyc2lvbikgewogICAgICAgIHN3aWZ0LnNldEluc3RhbmNlKGluc3RhbmNlKTsKICAgICAgfQogICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5zdGFydChpbnN0YW5jZSk7CiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUgPT0gImZ1bmN0aW9uIikgewogICAgICAgIHdhc2kuaW5pdGlhbGl6ZShpbnN0YW5jZSk7CiAgICAgICAgaWYgKHN3aWZ0ICYmIHN3aWZ0Lm1haW4pIHsKICAgICAgICAgIHN3aWZ0Lm1haW4oKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLm1haW4gPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5tYWluKCk7CiAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2KDAsIDApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH07Cn07CnZhciBkZWZhdWx0UnVubmVyT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7CiAgaWYgKG9wdGlvbnMuYXJncyA9PSBudWxsKSB7CiAgICBvcHRpb25zLmFyZ3MgPSBbIm1haW4ud2FzbSJdOwogIH0KICByZXR1cm4gb3B0aW9uczsKfTsKCi8vIGVudHJ5cG9pbnQvdGVzdC50cwp2YXIgc29ja2V0ID0gbmV3IHJlY29ubmVjdGluZ193ZWJzb2NrZXRfbWpzX2RlZmF1bHQoYHdzOi8vJHtsb2NhdGlvbi5ob3N0fS93YXRjaGVyYCk7CnNvY2tldC5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwgKG1lc3NhZ2UpID0+IHsKICBpZiAobWVzc2FnZS5kYXRhID09PSAicmVsb2FkIikgewogICAgbG9jYXRpb24ucmVsb2FkKCk7CiAgfQp9KTsKdmFyIHN0YXJ0V2FzaVRhc2sgPSBhc3luYyAoKSA9PiB7CiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgiL21haW4ud2FzbSIpOwogIGNvbnN0IHJlc3BvbnNlQXJyYXlCdWZmZXIgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpOwogIGxldCBydW50aW1lQ29uc3RydWN0b3IgPSB2b2lkIDA7CiAgdHJ5IHsKICAgIGNvbnN0IHsgU3dpZnRSdW50aW1lIH0gPSBhd2FpdCBpbXBvcnQoCiAgICAgIC8vIEB0cy1pZ25vcmUKICAgICAgIi4vSmF2YVNjcmlwdEtpdF9KYXZhU2NyaXB0S2l0LnJlc291cmNlcy9SdW50aW1lL2luZGV4Lm1qcyIKICAgICk7CiAgICBydW50aW1lQ29uc3RydWN0b3IgPSBTd2lmdFJ1bnRpbWU7CiAgfSBjYXRjaCB7CiAgICBjb25zb2xlLmxvZygiSmF2YVNjcmlwdEtpdCBtb2R1bGUgbm90IGF2YWlsYWJsZSwgcnVubmluZyB3aXRob3V0IEphdmFTY3JpcHRLaXQgcnVudGltZS4iKTsKICB9CiAgY29uc3QgY29uZmlnID0gYXdhaXQgZmV0Y2goIi9wcm9jZXNzLWluZm8uanNvbiIpLnRoZW4oKHJlc3BvbnNlMikgPT4gcmVzcG9uc2UyLmpzb24oKSk7CiAgbGV0IHRlc3RSdW5PdXRwdXQgPSAiIjsKICBjb25zdCB3YXNtUnVubmVyID0gV2FzbVJ1bm5lcih7CiAgICBlbnY6IGNvbmZpZy5lbnYsCiAgICBvblN0ZG91dExpbmU6IChsaW5lKSA9PiB7CiAgICAgIGNvbnNvbGUubG9nKGxpbmUpOwogICAgICB0ZXN0UnVuT3V0cHV0ICs9IGxpbmUgKyAiXG4iOwogICAgfSwKICAgIG9uU3RkZXJyTGluZTogKGxpbmUpID0+IHsKICAgICAgY29uc29sZS5lcnJvcihsaW5lKTsKICAgIH0KICB9LCBydW50aW1lQ29uc3RydWN0b3IpOwogIGNvbnN0IHdhc21CeXRlcyA9IG5ldyBVaW50OEFycmF5KHJlc3BvbnNlQXJyYXlCdWZmZXIpLmJ1ZmZlcjsKICBjb25zdCBoYW5kbGVFeGl0T3JFcnJvciA9IChlcnJvcikgPT4gewogICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV0FTSVByb2NFeGl0KSB7CiAgICAgIHNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KHsga2luZDogInRlc3RSdW5PdXRwdXQiLCB0ZXN0UnVuT3V0cHV0IH0pKTsKICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDApIHsKICAgICAgICBzb2NrZXQuc2VuZChKU09OLnN0cmluZ2lmeSh7IGtpbmQ6ICJ0ZXN0UGFzc2VkIiB9KSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaGFuZGxlRXJyb3IoZXJyb3IpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBoYW5kbGVFcnJvcihlcnJvcik7CiAgICB9CiAgICBjb25zdCBkaXZFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgicCIpOwogICAgZGl2RWxlbWVudC5pbm5lckhUTUwgPSAiVGVzdCBydW4gZmluaXNoZWQuIENoZWNrIHRoZSBvdXRwdXQgb2YgPGNvZGU+Y2FydG9uIHRlc3Q8L2NvZGU+IGZvciBkZXRhaWxzLiI7CiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRpdkVsZW1lbnQpOwogIH07CiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoInVuaGFuZGxlZHJlamVjdGlvbiIsIChldmVudCkgPT4gewogICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgIGNvbnN0IGVycm9yID0gZXZlbnQucmVhc29uOwogICAgaGFuZGxlRXhpdE9yRXJyb3IoZXJyb3IpOwogIH0pOwogIHRyeSB7CiAgICBhd2FpdCB3YXNtUnVubmVyLnJ1bih3YXNtQnl0ZXMpOwogIH0gY2F0Y2ggKGVycm9yKSB7CiAgICBoYW5kbGVFeGl0T3JFcnJvcihlcnJvcik7CiAgICByZXR1cm47CiAgfQp9OwpmdW5jdGlvbiBoYW5kbGVFcnJvcihlKSB7CiAgY29uc29sZS5lcnJvcihlKTsKICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yKSB7CiAgICBjb25zdCBzdGFjayA9IGUuc3RhY2s7CiAgICBpZiAoc3RhY2sgIT0gbnVsbCkgewogICAgICBzb2NrZXQuc2VuZChKU09OLnN0cmluZ2lmeSh7CiAgICAgICAga2luZDogInN0YWNrVHJhY2UiLAogICAgICAgIHN0YWNrVHJhY2U6IHN0YWNrCiAgICAgIH0pKTsKICAgIH0KICB9CiAgc29ja2V0LnNlbmQoSlNPTi5zdHJpbmdpZnkoewogICAga2luZDogImVycm9yUmVwb3J0IiwKICAgIGVycm9yUmVwb3J0OiBlLnRvU3RyaW5nKCkKICB9KSk7Cn0KYXN5bmMgZnVuY3Rpb24gbWFpbigpIHsKICB0cnkgewogICAgYXdhaXQgc3RhcnRXYXNpVGFzaygpOwogIH0gY2F0Y2ggKGUpIHsKICAgIGhhbmRsZUVycm9yKGUpOwogIH0KfQptYWluKCk7Ci8qIQogKiBSZWNvbm5lY3RpbmcgV2ViU29ja2V0CiAqIGJ5IFBlZHJvIExhZGFyaWEgPHBlZHJvLmxhZGFyaWFAZ21haWwuY29tPgogKiBodHRwczovL2dpdGh1Yi5jb20vcGxhZGFyaWEvcmVjb25uZWN0aW5nLXdlYnNvY2tldAogKiBMaWNlbnNlIE1JVAogKi8KLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgpMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlCnRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlCkxpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCgpUSElTIENPREUgSVMgUFJPVklERUQgT04gQU4gKkFTIElTKiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCktJTkQsIEVJVEhFUiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04gQU5ZIElNUExJRUQKV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIFRJVExFLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwKTUVSQ0hBTlRBQkxJVFkgT1IgTk9OLUlORlJJTkdFTUVOVC4KClNlZSB0aGUgQXBhY2hlIFZlcnNpb24gMi4wIExpY2Vuc2UgZm9yIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucwphbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCg==")! + public static let testNode: Data = Data(base64Encoded: "dmFyIF9fY3JlYXRlID0gT2JqZWN0LmNyZWF0ZTsKdmFyIF9fZGVmUHJvcCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTsKdmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOwp2YXIgX19nZXRPd25Qcm9wTmFtZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lczsKdmFyIF9fZ2V0UHJvdG9PZiA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjsKdmFyIF9faGFzT3duUHJvcCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7CnZhciBfX2NvcHlQcm9wcyA9ICh0bywgZnJvbSwgZXhjZXB0LCBkZXNjKSA9PiB7CiAgaWYgKGZyb20gJiYgdHlwZW9mIGZyb20gPT09ICJvYmplY3QiIHx8IHR5cGVvZiBmcm9tID09PSAiZnVuY3Rpb24iKSB7CiAgICBmb3IgKGxldCBrZXkgb2YgX19nZXRPd25Qcm9wTmFtZXMoZnJvbSkpCiAgICAgIGlmICghX19oYXNPd25Qcm9wLmNhbGwodG8sIGtleSkgJiYga2V5ICE9PSBleGNlcHQpCiAgICAgICAgX19kZWZQcm9wKHRvLCBrZXksIHsgZ2V0OiAoKSA9PiBmcm9tW2tleV0sIGVudW1lcmFibGU6ICEoZGVzYyA9IF9fZ2V0T3duUHJvcERlc2MoZnJvbSwga2V5KSkgfHwgZGVzYy5lbnVtZXJhYmxlIH0pOwogIH0KICByZXR1cm4gdG87Cn07CnZhciBfX3RvRVNNID0gKG1vZCwgaXNOb2RlTW9kZSwgdGFyZ2V0KSA9PiAodGFyZ2V0ID0gbW9kICE9IG51bGwgPyBfX2NyZWF0ZShfX2dldFByb3RvT2YobW9kKSkgOiB7fSwgX19jb3B5UHJvcHMoaXNOb2RlTW9kZSB8fCAhbW9kIHx8ICFtb2QuX19lc01vZHVsZSA/IF9fZGVmUHJvcCh0YXJnZXQsICJkZWZhdWx0IiwgeyB2YWx1ZTogbW9kLCBlbnVtZXJhYmxlOiB0cnVlIH0pIDogdGFyZ2V0LCBtb2QpKTsKCi8vIGVudHJ5cG9pbnQvdGVzdE5vZGUudHMKdmFyIGltcG9ydF9wcm9taXNlcyA9IF9fdG9FU00ocmVxdWlyZSgiZnMvcHJvbWlzZXMiKSk7CnZhciBpbXBvcnRfcGF0aCA9IF9fdG9FU00ocmVxdWlyZSgicGF0aCIpKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJnczIsIGVudiwgZmRzLCBvcHRpb25zID0ge30pIHsKICAgIHRoaXMuYXJncyA9IFtdOwogICAgdGhpcy5lbnYgPSBbXTsKICAgIHRoaXMuZmRzID0gW107CiAgICBkZWJ1Zy5lbmFibGUob3B0aW9ucy5kZWJ1Zyk7CiAgICB0aGlzLmFyZ3MgPSBhcmdzMjsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfZ2V0KGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aDIpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X3NldF90aW1lcyhmbGFncywgcGF0aDIsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgyKTsKICAgICAgICBjb25zdCB7IHJldCwgZmRfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoMiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aDIpOwogICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9yZWFkbGluayhwYXRoMik7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoMiA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZW5hbWUoZmQsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgbGV0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3VubGluayhvbGRfcGF0aCk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXQgPSBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKTsKICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgIGlmIChzZWxmLmZkc1tmZF0ucGF0aF9saW5rKG9sZF9wYXRoLCBpbm9kZV9vYmosIHRydWUpICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgdGhyb3cgInBhdGhfbGluayBzaG91bGQgYWx3YXlzIHJldHVybiBzdWNjZXNzIHdoZW4gcmVsaW5raW5nIGFuIGlub2RlIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHBsYWNlIjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9zeW1saW5rKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBmZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3VubGlua19maWxlKGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgyLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoMiwgaW5vZGUsIGFsbG93X2RpcikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF91bmxpbmsocGF0aDIpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aDIsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aDIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogIH0KICBwYXRoX3JlYWRsaW5rKHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KfTsKdmFyIElub2RlID0gY2xhc3Mgewp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mc19tZW0uanMKdmFyIE9wZW5GaWxlID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IG9mZnNldCArIGxlbikgewogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgbGVuKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgMCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gc2l6ZSkgewogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KHRoaXMuZmlsZS5kYXRhLmJ1ZmZlci5zbGljZSgwLCBOdW1iZXIoc2l6ZSkpKTsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHNpemUpKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKHRoaXMuZmlsZV9wb3MpLCBOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChzaXplKSkpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoc2xpY2UubGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcihvZmZzZXQpLCBOdW1iZXIob2Zmc2V0ICsgQmlnSW50KHNpemUpKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIGxldCBjYWxjdWxhdGVkX29mZnNldDsKICAgIHN3aXRjaCAod2hlbmNlKSB7CiAgICAgIGNhc2UgV0hFTkNFX1NFVDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfQ1VSOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gdGhpcy5maWxlX3BvcyArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfRU5EOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gQmlnSW50KHRoaXMuZmlsZS5kYXRhLmJ5dGVMZW5ndGgpICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIGlmIChjYWxjdWxhdGVkX29mZnNldCA8IDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgdGhpcy5maWxlX3BvcyA9IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmICh0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcih0aGlzLmZpbGVfcG9zKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmIChvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIob2Zmc2V0KSk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5maWxlLnN0YXQoKSB9OwogIH0KICBjb25zdHJ1Y3RvcihmaWxlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5maWxlX3BvcyA9IDBuOwogICAgdGhpcy5maWxlID0gZmlsZTsKICB9Cn07CnZhciBPcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgIGRlYnVnLmxvZygicmVhZGRpcl9zaW5nbGUiLCBjb29raWUpOwogICAgICBkZWJ1Zy5sb2coY29va2llLCB0aGlzLmRpci5jb250ZW50cy5rZXlzKCkpOwogICAgfQogICAgaWYgKGNvb2tpZSA9PSAwbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgxbiwgIi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9IGVsc2UgaWYgKGNvb2tpZSA9PSAxbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgybiwgIi4uIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfQogICAgaWYgKGNvb2tpZSA+PSBCaWdJbnQodGhpcy5kaXIuY29udGVudHMuc2l6ZSkgKyAybikgewogICAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbnVsbCB9OwogICAgfQogICAgY29uc3QgW25hbWUsIGVudHJ5XSA9IEFycmF5LmZyb20odGhpcy5kaXIuY29udGVudHMuZW50cmllcygpKVtOdW1iZXIoY29va2llIC0gMm4pXTsKICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBuZXcgRGlyZW50KGNvb2tpZSArIDFuLCBuYW1lLCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUpIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfZXJyLCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiBlbnRyeS5zdGF0KCkgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aF9zdHIsIGRpcmZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aF9zdHIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIGlmIChyZXQgIT0gRVJSTk9fTk9FTlQpIHsKICAgICAgICByZXR1cm4geyByZXQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0NSRUFUKSA9PSBPRkxBR1NfQ1JFQVQpIHsKICAgICAgICBjb25zdCB7IHJldDogcmV0MiwgZW50cnk6IG5ld19lbnRyeSB9ID0gdGhpcy5kaXIuY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCAob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSk7CiAgICAgICAgaWYgKG5ld19lbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4geyByZXQ6IHJldDIsIGZkX29iajogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBlbnRyeSA9IG5ld19lbnRyeTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgfSBlbHNlIGlmICgob2ZsYWdzICYgT0ZMQUdTX0VYQ0wpID09IE9GTEFHU19FWENMKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiBlbnRyeS5wYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpOwogIH0KICBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoMiwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoMi5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aDIsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICBjb25zdCBzb3VyY2VfaXNfZGlyID0gaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgY29uc3QgdGFyZ2V0X2lzX2RpciA9IGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGlmIChzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICBpZiAoYWxsb3dfZGlyICYmIGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB7CiAgICAgICAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSA9PSAwKSB7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoc291cmNlX2lzX2RpciAmJiAhdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICAgIH0gZWxzZSBpZiAoIXNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgICAgfSBlbHNlIGlmIChpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUpIHsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgIH0KICAgIH0KICAgIGlmICghYWxsb3dfZGlyICYmIGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX1BFUk07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBpbm9kZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF91bmxpbmsocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmICghKGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB8fCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgfQogICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgIT09IDApIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgfQogICAgaWYgKCFwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKSkgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5kaXIuc3RhdCgpIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgY29uc3RydWN0b3IoZGlyKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kaXIgPSBkaXI7CiAgfQp9Owp2YXIgUHJlb3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgT3BlbkRpcmVjdG9yeSB7CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIHByZXN0YXQ6IFByZXN0YXQuZGlyKHRoaXMucHJlc3RhdF9uYW1lKSB9OwogIH0KICBjb25zdHJ1Y3RvcihuYW1lLCBjb250ZW50cykgewogICAgc3VwZXIobmV3IERpcmVjdG9yeShjb250ZW50cykpOwogICAgdGhpcy5wcmVzdGF0X25hbWUgPSBuYW1lOwogIH0KfTsKdmFyIEZpbGUgPSBjbGFzcyBleHRlbmRzIElub2RlIHsKICBwYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpIHsKICAgIGlmICh0aGlzLnJlYWRvbmx5ICYmIChmc19yaWdodHNfYmFzZSAmIEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSA9PSBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfVFJVTkMpID09IE9GTEFHU19UUlVOQykgewogICAgICBpZiAodGhpcy5yZWFkb25seSkKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShbXSk7CiAgICB9CiAgICBjb25zdCBmaWxlID0gbmV3IE9wZW5GaWxlKHRoaXMpOwogICAgaWYgKGZkX2ZsYWdzICYgRkRGTEFHU19BUFBFTkQpCiAgICAgIGZpbGUuZmRfc2VlaygwbiwgV0hFTkNFX0VORCk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogZmlsZSB9OwogIH0KICBnZXQgc2l6ZSgpIHsKICAgIHJldHVybiBCaWdJbnQodGhpcy5kYXRhLmJ5dGVMZW5ndGgpOwogIH0KICBzdGF0KCkgewogICAgcmV0dXJuIG5ldyBGaWxlc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIHRoaXMuc2l6ZSk7CiAgfQogIGNvbnN0cnVjdG9yKGRhdGEsIG9wdGlvbnMpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShkYXRhKTsKICAgIHRoaXMucmVhZG9ubHkgPSAhIW9wdGlvbnM/LnJlYWRvbmx5OwogIH0KfTsKdmFyIFBhdGggPSBjbGFzcyBQYXRoMiB7CiAgc3RhdGljIGZyb20ocGF0aDIpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aDIuZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoMi5zdGFydHNXaXRoKCIvIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICB9CiAgICBpZiAocGF0aDIuaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aDIuc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aDIpIHsKICAgIGxldCBlbnRyeSA9IHRoaXM7CiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiBwYXRoMi5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgYWxsb3dfdW5kZWZpbmVkKSB7CiAgICBjb25zdCBmaWxlbmFtZSA9IHBhdGgyLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH07CiAgfQogIGNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgaXNfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBkZWJ1Zy5sb2coImNyZWF0ZSIsIHBhdGgyKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvaW5kZXguanMKZnVuY3Rpb24gcGFyc2VJbXBvcnRzKG1vZHVsZUJ5dGVzKSB7CiAgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcyk7CiAgfSBlbHNlIGlmIChtb2R1bGVCeXRlcy5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcy5idWZmZXIpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoIkFyZ3VtZW50IG11c3QgYmUgYSBidWZmZXIgc291cmNlLCBsaWtlIFVpbnQ4QXJyYXkgb3IgQXJyYXlCdWZmZXIiKTsKICB9CiAgY29uc3QgcGFyc2VTdGF0ZSA9IG5ldyBQYXJzZVN0YXRlKG1vZHVsZUJ5dGVzKTsKICBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpOwogIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKTsKICBjb25zdCB0eXBlcyA9IFtdOwogIGNvbnN0IGltcG9ydHMgPSBbXTsKICB3aGlsZSAocGFyc2VTdGF0ZS5oYXNNb3JlQnl0ZXMoKSkgewogICAgY29uc3Qgc2VjdGlvbklkID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgY29uc3Qgc2VjdGlvblNpemUgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgc3dpdGNoIChzZWN0aW9uSWQpIHsKICAgICAgY2FzZSAxOiB7CiAgICAgICAgY29uc3QgdHlwZUNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVDb3VudDsgaSsrKSB7CiAgICAgICAgICB0eXBlcy5wdXNoKHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAyOiB7CiAgICAgICAgY29uc3QgaW1wb3J0Q291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW1wb3J0Q291bnQ7IGkrKykgewogICAgICAgICAgY29uc3QgbW9kdWxlMiA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlOiBtb2R1bGUyLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGU6IG1vZHVsZTIsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlOiBtb2R1bGUyLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGU6IG1vZHVsZTIsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZTIgPSBuZXcgV2ViQXNzZW1ibHkuTW9kdWxlKG1vZHVsZUJ5dGVzKTsKICBjb25zdCBpbXBvcnRzID0gV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMobW9kdWxlMik7CiAgY29uc3QgbWVtb3J5SW1wb3J0ID0gaW1wb3J0c1swXTsKICByZXR1cm4gdHlwZW9mIG1lbW9yeUltcG9ydC50eXBlID09PSAib2JqZWN0IjsKfSkoKTsKZnVuY3Rpb24gcG9seWZpbGwoV2ViQXNzZW1ibHkzKSB7CiAgaWYgKGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQpIHsKICAgIHJldHVybiBXZWJBc3NlbWJseTM7CiAgfQogIGNvbnN0IG5ld1dlYkFzc2VtYmx5ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoV2ViQXNzZW1ibHkzKSkgewogICAgbmV3V2ViQXNzZW1ibHlba2V5XSA9IFdlYkFzc2VtYmx5M1trZXldOwogIH0KICBjb25zdCBwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbCA9IFN5bWJvbCgicG9seWZpbGxlZEltcG9ydHNTeW1ib2wiKTsKICBjb25zdCBhc3NpZ25JbXBvcnRzID0gKG1vZHVsZTIsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGUyW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXSA9IHBhcnNlSW1wb3J0cyhzb3VyY2VCeXRlcyk7CiAgfTsKICBjb25zdCBuZXdNb2R1bGUgPSBuZXdXZWJBc3NlbWJseS5Nb2R1bGUgPSBmdW5jdGlvbihieXRlcykgewogICAgY29uc3QgbW9kdWxlMiA9IG5ldyBXZWJBc3NlbWJseTMuTW9kdWxlKGJ5dGVzKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlMiwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZTIsIG5ld01vZHVsZS5wcm90b3R5cGUpOwogICAgcmV0dXJuIG1vZHVsZTI7CiAgfTsKICBPYmplY3Quc2V0UHJvdG90eXBlT2YobmV3TW9kdWxlLnByb3RvdHlwZSwgV2ViQXNzZW1ibHkzLk1vZHVsZS5wcm90b3R5cGUpOwogIG5ld1dlYkFzc2VtYmx5LmNvbXBpbGUgPSBhc3luYyAoc291cmNlKSA9PiB7CiAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlMiwgc291cmNlKTsKICAgIHJldHVybiBtb2R1bGUyOwogIH07CiAgaWYgKFdlYkFzc2VtYmx5My5jb21waWxlU3RyZWFtaW5nKSB7CiAgICBuZXdXZWJBc3NlbWJseS5jb21waWxlU3RyZWFtaW5nID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNvdXJjZTsKICAgICAgY29uc3QgY2xvbmUgPSByZXNwb25zZS5jbG9uZSgpOwogICAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZTIsIG5ldyBVaW50OEFycmF5KGF3YWl0IGNsb25lLmFycmF5QnVmZmVyKCkpKTsKICAgICAgcmV0dXJuIG1vZHVsZTI7CiAgICB9OwogIH0KICBuZXdNb2R1bGUuaW1wb3J0cyA9IChtb2R1bGUyKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlMltwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbF07CiAgICBpZiAoIXBhcnNlZEltcG9ydHMpIHsKICAgICAgcmV0dXJuIFdlYkFzc2VtYmx5My5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUyKTsKICAgIH0KICAgIHJldHVybiBwYXJzZWRJbXBvcnRzOwogIH07CiAgcmV0dXJuIG5ld1dlYkFzc2VtYmx5Owp9CgovLyBlbnRyeXBvaW50L2NvbW1vbi50cwp2YXIgV2ViQXNzZW1ibHkyID0gcG9seWZpbGwoZ2xvYmFsVGhpcy5XZWJBc3NlbWJseSk7CnZhciBMaW5lRGVjb2RlciA9IGNsYXNzIHsKICBjb25zdHJ1Y3RvcihvbkxpbmUpIHsKICAgIHRoaXMuZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIHRoaXMuYnVmZmVyID0gIiI7CiAgICB0aGlzLm9uTGluZSA9IG9uTGluZTsKICB9CiAgZGVjb2RlcjsKICBidWZmZXI7CiAgb25MaW5lOwogIHNlbmQoY2h1bmspIHsKICAgIHRoaXMuYnVmZmVyICs9IHRoaXMuZGVjb2Rlci5kZWNvZGUoY2h1bmssIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgY29uc3QgbGluZXMgPSB0aGlzLmJ1ZmZlci5zcGxpdCgiXG4iKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoIC0gMTsgaSsrKSB7CiAgICAgIHRoaXMub25MaW5lKGxpbmVzW2ldKTsKICAgIH0KICAgIHRoaXMuYnVmZmVyID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV07CiAgfQp9Owp2YXIgV2FzbVJ1bm5lciA9IChyYXdPcHRpb25zLCBTd2lmdFJ1bnRpbWUpID0+IHsKICBjb25zdCBvcHRpb25zID0gZGVmYXVsdFJ1bm5lck9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0OwogIGlmIChTd2lmdFJ1bnRpbWUpIHsKICAgIHN3aWZ0ID0gbmV3IFN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJnczIgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzMiwgZW52cywgZmRzLCB7CiAgICBkZWJ1ZzogZmFsc2UKICB9KTsKICBjb25zdCBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0ID0gKGV4dHJhV2FzbUltcG9ydHMsIG1vZHVsZTIpID0+IHsKICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IHsKICAgICAgd2FzaV9zbmFwc2hvdF9wcmV2aWV3MTogd2FzaS53YXNpSW1wb3J0CiAgICB9OwogICAgaWYgKHN3aWZ0KSB7CiAgICAgIGltcG9ydE9iamVjdC5qYXZhc2NyaXB0X2tpdCA9IHN3aWZ0Lndhc21JbXBvcnRzOwogICAgfQogICAgaWYgKGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgZm9yIChjb25zdCBtb2R1bGVOYW1lIGluIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgICBpZiAoIWltcG9ydE9iamVjdFttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdID0ge307CiAgICAgICAgfQogICAgICAgIGZvciAoY29uc3QgZW50cnkgaW4gZXh0cmFXYXNtSW1wb3J0c1ttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdW2VudHJ5XSA9IGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV1bZW50cnldOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZm9yIChjb25zdCBfaW1wb3J0RW50cnkgb2YgV2ViQXNzZW1ibHkyLk1vZHVsZS5pbXBvcnRzKG1vZHVsZTIpKSB7CiAgICAgIGNvbnN0IGltcG9ydEVudHJ5ID0gX2ltcG9ydEVudHJ5OwogICAgICBpZiAoIWltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0gPSB7fTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0gPSAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEltcG9ydGVkIGZ1bmN0aW9uICR7aW1wb3J0RW50cnkubW9kdWxlfS4ke2ltcG9ydEVudHJ5Lm5hbWV9IG5vdCBpbXBsZW1lbnRlZGApOwogICAgICAgIH07CiAgICAgIH0gZWxzZSBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAibWVtb3J5IiAmJiBpbXBvcnRFbnRyeS5tb2R1bGUgPT0gImVudiIgJiYgaW1wb3J0RW50cnkubmFtZSA9PSAibWVtb3J5IikgewogICAgICAgIGNvbnN0IHR5cGUgPSBpbXBvcnRFbnRyeS50eXBlOwogICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB7CiAgICAgICAgICBpbml0aWFsOiB0eXBlLm1pbmltdW0sCiAgICAgICAgICBtYXhpbXVtOiB0eXBlLm1heGltdW0sCiAgICAgICAgICBzaGFyZWQ6IHR5cGUuc2hhcmVkCiAgICAgICAgfTsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9IG5ldyBXZWJBc3NlbWJseTIuTWVtb3J5KGRlc2NyaXB0b3IpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0OwogIH07CiAgcmV0dXJuIHsKICAgIGFzeW5jIHJ1bih3YXNtQnl0ZXMsIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgaWYgKCFleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgZXh0cmFXYXNtSW1wb3J0cyA9IHt9OwogICAgICB9CiAgICAgIGV4dHJhV2FzbUltcG9ydHMuX19zdGFja19zYW5pdGl6ZXIgPSB7CiAgICAgICAgcmVwb3J0X3N0YWNrX292ZXJmbG93OiAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkRldGVjdGVkIHN0YWNrIGJ1ZmZlciBvdmVyZmxvdy4iKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIGNvbnN0IG1vZHVsZTIgPSBhd2FpdCBXZWJBc3NlbWJseTIuY29tcGlsZSh3YXNtQnl0ZXMpOwogICAgICBjb25zdCBpbXBvcnRPYmplY3QgPSBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0KGV4dHJhV2FzbUltcG9ydHMsIG1vZHVsZTIpOwogICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IFdlYkFzc2VtYmx5Mi5pbnN0YW50aWF0ZShtb2R1bGUyLCBpbXBvcnRPYmplY3QpOwogICAgICBpZiAoc3dpZnQgJiYgaW5zdGFuY2UuZXhwb3J0cy5zd2pzX2xpYnJhcnlfdmVyc2lvbikgewogICAgICAgIHN3aWZ0LnNldEluc3RhbmNlKGluc3RhbmNlKTsKICAgICAgfQogICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5zdGFydChpbnN0YW5jZSk7CiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUgPT0gImZ1bmN0aW9uIikgewogICAgICAgIHdhc2kuaW5pdGlhbGl6ZShpbnN0YW5jZSk7CiAgICAgICAgaWYgKHN3aWZ0ICYmIHN3aWZ0Lm1haW4pIHsKICAgICAgICAgIHN3aWZ0Lm1haW4oKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLm1haW4gPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5tYWluKCk7CiAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2KDAsIDApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH07Cn07CnZhciBkZWZhdWx0UnVubmVyT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7CiAgaWYgKG9wdGlvbnMuYXJncyA9PSBudWxsKSB7CiAgICBvcHRpb25zLmFyZ3MgPSBbIm1haW4ud2FzbSJdOwogIH0KICByZXR1cm4gb3B0aW9uczsKfTsKCi8vIGVudHJ5cG9pbnQvdGVzdE5vZGUudHMKdmFyIGFyZ3MgPSBbLi4ucHJvY2Vzcy5hcmd2XTsKYXJncy5zaGlmdCgpOwphcmdzLnNoaWZ0KCk7CnZhciBbd2FzbUZpbGUsIC4uLnRlc3RBcmdzXSA9IGFyZ3M7CnRlc3RBcmdzLnVuc2hpZnQoaW1wb3J0X3BhdGguZGVmYXVsdC5iYXNlbmFtZSh3YXNtRmlsZSkpOwppZiAoIXdhc21GaWxlKSB7CiAgdGhyb3cgRXJyb3IoIk5vIFdBU00gdGVzdCBmaWxlIHNwZWNpZmllZCwgY2FuIG5vdCBydW4gdGVzdHMiKTsKfQp2YXIgc3RhcnRXYXNpVGFzayA9IGFzeW5jICgpID0+IHsKICBjb25zdCB3YXNtQnl0ZXMgPSBhd2FpdCBpbXBvcnRfcHJvbWlzZXMuZGVmYXVsdC5yZWFkRmlsZSh3YXNtRmlsZSk7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICAgIGdsb2JhbC5yZXF1aXJlID0gcmVxdWlyZTsKICB9IGNhdGNoIHsKICB9CiAgY29uc3QgZW52ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gcHJvY2Vzcy5lbnYpIHsKICAgIGNvbnN0IHZhbHVlID0gcHJvY2Vzcy5lbnZba2V5XTsKICAgIGlmICh2YWx1ZSkgewogICAgICBlbnZba2V5XSA9IHZhbHVlOwogICAgfQogIH0KICBjb25zdCB3YXNtUnVubmVyID0gV2FzbVJ1bm5lcih7CiAgICBhcmdzOiB0ZXN0QXJncywKICAgIGVudiwKICAgIG9uU3Rkb3V0TGluZTogKGxpbmUpID0+IHsKICAgICAgY29uc29sZS5sb2cobGluZSk7CiAgICB9LAogICAgb25TdGRlcnJMaW5lOiAobGluZSkgPT4gewogICAgICBjb25zb2xlLmVycm9yKGxpbmUpOwogICAgfQogIH0sIHJ1bnRpbWVDb25zdHJ1Y3Rvcik7CiAgbGV0IHByb2NFeGl0Q2FsbGVkID0gZmFsc2U7CiAgcHJvY2Vzcy5vbigiYmVmb3JlRXhpdCIsICgpID0+IHsKICAgIGlmICghcHJvY0V4aXRDYWxsZWQpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZXN0IGhhcm5lc3MgcHJvY2VzcyBleGl0ZWQgYmVmb3JlIHRlc3QgcHJvY2Vzcy4KVGhpcyB1c3VhbGx5IG1lYW5zIHRoZXJlIGFyZSBzb21lIGRhbmdsaW5nIGNvbnRpbnVhdGlvbnMsIHdoaWNoIGFyZSBhd2FpdGVkIGJ1dCBuZXZlciByZXN1bWVkLmApOwogICAgfQogIH0pOwogIGF3YWl0IHdhc21SdW5uZXIucnVuKHdhc21CeXRlcywgewogICAgIndhc2lfc25hcHNob3RfcHJldmlldzEiOiB7CiAgICAgIHByb2NfZXhpdDogKGNvZGUpID0+IHsKICAgICAgICBwcm9jRXhpdENhbGxlZCA9IHRydWU7CiAgICAgICAgcHJvY2Vzcy5leGl0KGNvZGUpOwogICAgICB9CiAgICB9CiAgfSk7Cn07CnN0YXJ0V2FzaVRhc2soKS5jYXRjaCgoZSkgPT4gewogIHRocm93IGU7Cn0pOwo=")! } \ No newline at end of file diff --git a/entrypoint/common.ts b/entrypoint/common.ts index 348b446f..4e2afe9d 100644 --- a/entrypoint/common.ts +++ b/entrypoint/common.ts @@ -19,7 +19,7 @@ import type { ImportEntry } from "wasm-imports-parser"; // Apply polyfill for WebAssembly Type Reflection JS API to inspect imported memory info. // https://github.com/WebAssembly/js-types/blob/main/proposals/js-types/Overview.md -globalThis.WebAssembly = polyfillWebAssemblyTypeReflection(globalThis.WebAssembly); +const WebAssembly = polyfillWebAssemblyTypeReflection(globalThis.WebAssembly); export class LineDecoder { constructor(onLine: (line: string) => void) { From 1bd567e07d6b8f1152d69c965ea93a53ce0393cf Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 17 Nov 2024 09:25:33 +0900 Subject: [PATCH 2/2] Expose `instantiate` API from bundled package --- Sources/CartonHelpers/StaticArchive.swift | 9 +- .../CartonFrontendBundleCommand.swift | 97 ++++++++++++++- Sources/carton-release/HashArchive.swift | 16 +-- entrypoint/bundle.ts | 18 ++- entrypoint/dev.ts | 19 ++- entrypoint/{common.ts => intrinsics.ts} | 111 ++++++++++-------- entrypoint/test.ts | 35 +++--- entrypoint/testNode.ts | 42 ++++--- 8 files changed, 219 insertions(+), 128 deletions(-) rename entrypoint/{common.ts => intrinsics.ts} (67%) diff --git a/Sources/CartonHelpers/StaticArchive.swift b/Sources/CartonHelpers/StaticArchive.swift index 4886c65c..f5c2530f 100644 --- a/Sources/CartonHelpers/StaticArchive.swift +++ b/Sources/CartonHelpers/StaticArchive.swift @@ -1,9 +1,10 @@ import Foundation 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+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcihvZmZzZXQpKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmZpbGUuc3RhdCgpIH07CiAgfQogIGNvbnN0cnVjdG9yKGZpbGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmZpbGVfcG9zID0gMG47CiAgICB0aGlzLmZpbGUgPSBmaWxlOwogIH0KfTsKdmFyIE9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9ESVJFQ1RPUlksIDApIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgZGVidWcubG9nKCJyZWFkZGlyX3NpbmdsZSIsIGNvb2tpZSk7CiAgICAgIGRlYnVnLmxvZyhjb29raWUsIHRoaXMuZGlyLmNvbnRlbnRzLmtleXMoKSk7CiAgICB9CiAgICBpZiAoY29va2llID09IDBuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDFuLCAiLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0gZWxzZSBpZiAoY29va2llID09IDFuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDJuLCAiLi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9CiAgICBpZiAoY29va2llID49IEJpZ0ludCh0aGlzLmRpci5jb250ZW50cy5zaXplKSArIDJuKSB7CiAgICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBbbmFtZSwgZW50cnldID0gQXJyYXkuZnJvbSh0aGlzLmRpci5jb250ZW50cy5lbnRyaWVzKCkpW051bWJlcihjb29raWUgLSAybildOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG5ldyBEaXJlbnQoY29va2llICsgMW4sIG5hbWUsIGVudHJ5LnN0YXQoKS5maWxldHlwZSkgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9lcnIsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IGVudHJ5LnN0YXQoKSB9OwogIH0KICBwYXRoX2xvb2t1cChwYXRoX3N0ciwgZGlyZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoX3N0ciwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgaWYgKHJldCAhPSBFUlJOT19OT0VOVCkgewogICAgICAgIHJldHVybiB7IHJldCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfQ1JFQVQpID09IE9GTEFHU19DUkVBVCkgewogICAgICAgIGNvbnN0IHsgcmV0OiByZXQyLCBlbnRyeTogbmV3X2VudHJ5IH0gPSB0aGlzLmRpci5jcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZKTsKICAgICAgICBpZiAobmV3X2VudHJ5ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiB7IHJldDogcmV0MiwgZmRfb2JqOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGVudHJ5ID0gbmV3X2VudHJ5OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICB9IGVsc2UgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRVhDTCkgPT0gT0ZMQUdTX0VYQ0wpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIGVudHJ5LnBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncyk7CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gdGhpcy5wYXRoX29wZW4oMCwgcGF0aCwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIGNvbnN0IHNvdXJjZV9pc19kaXIgPSBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBjb25zdCB0YXJnZXRfaXNfZGlyID0gZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgaWYgKHNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIGlmIChhbGxvd19kaXIgJiYgZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHsKICAgICAgICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplID09IDApIHsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChzb3VyY2VfaXNfZGlyICYmICF0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgICAgfSBlbHNlIGlmICghc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgICB9IGVsc2UgaWYgKGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSkgewogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgfQogICAgfQogICAgaWYgKCFhbGxvd19kaXIgJiYgaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fUEVSTTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIGlub2RlKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3VubGluayhwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF91bmxpbmtfZmlsZShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHx8IGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICB9CiAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSAhPT0gMCkgewogICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICB9CiAgICBpZiAoIXBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpKSB7CiAgICAgIHJldHVybiBFUlJOT19OT0VOVDsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmRpci5zdGF0KCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBjb25zdHJ1Y3RvcihkaXIpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRpciA9IGRpcjsKICB9Cn07CnZhciBQcmVvcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBPcGVuRGlyZWN0b3J5IHsKICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgcHJlc3RhdDogUHJlc3RhdC5kaXIodGhpcy5wcmVzdGF0X25hbWUpIH07CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnRzKSB7CiAgICBzdXBlcihuZXcgRGlyZWN0b3J5KGNvbnRlbnRzKSk7CiAgICB0aGlzLnByZXN0YXRfbmFtZSA9IG5hbWU7CiAgfQp9Owp2YXIgRmlsZSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgaWYgKHRoaXMucmVhZG9ubHkgJiYgKGZzX3JpZ2h0c19iYXNlICYgQmlnSW50KFJJR0hUU19GRF9XUklURSkpID09IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19UUlVOQykgPT0gT0ZMQUdTX1RSVU5DKSB7CiAgICAgIGlmICh0aGlzLnJlYWRvbmx5KQogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KFtdKTsKICAgIH0KICAgIGNvbnN0IGZpbGUgPSBuZXcgT3BlbkZpbGUodGhpcyk7CiAgICBpZiAoZmRfZmxhZ3MgJiBGREZMQUdTX0FQUEVORCkKICAgICAgZmlsZS5mZF9zZWVrKDBuLCBXSEVOQ0VfRU5EKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZmRfb2JqOiBmaWxlIH07CiAgfQogIGdldCBzaXplKCkgewogICAgcmV0dXJuIEJpZ0ludCh0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgdGhpcy5zaXplKTsKICB9CiAgY29uc3RydWN0b3IoZGF0YSwgb3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgdGhpcy5yZWFkb25seSA9ICEhb3B0aW9ucz8ucmVhZG9ubHk7CiAgfQp9Owp2YXIgUGF0aCA9IGNsYXNzIFBhdGgyIHsKICBzdGF0aWMgZnJvbShwYXRoKSB7CiAgICBjb25zdCBzZWxmID0gbmV3IFBhdGgyKCk7CiAgICBzZWxmLmlzX2RpciA9IHBhdGguZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVENBUEFCTEUsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGlmIChwYXRoLmluY2x1ZGVzKCJcMCIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGguc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aCkgewogICAgbGV0IGVudHJ5ID0gdGhpczsKICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgucGFydHMpIHsKICAgICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgICAgY29uc3QgY2hpbGQgPSBlbnRyeS5jb250ZW50cy5nZXQoY29tcG9uZW50KTsKICAgICAgaWYgKGNoaWxkICE9PSB2b2lkIDApIHsKICAgICAgICBlbnRyeSA9IGNoaWxkOwogICAgICB9IGVsc2UgewogICAgICAgIGRlYnVnLmxvZyhjb21wb25lbnQpOwogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBhbGxvd191bmRlZmluZWQpIHsKICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5wYXJ0cy5wb3AoKTsKICAgIGlmIChmaWxlbmFtZSA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldDogZW50cnlfcmV0LCBlbnRyeTogcGFyZW50X2VudHJ5IH0gPSB0aGlzLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfTsKICB9CiAgY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCBpc19kaXIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGRlYnVnLmxvZygiY3JlYXRlIiwgcGF0aCk7CiAgICBsZXQgbmV3X2NoaWxkOwogICAgaWYgKCFpc19kaXIpIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IEZpbGUobmV3IEFycmF5QnVmZmVyKDApKTsKICAgIH0gZWxzZSB7CiAgICAgIG5ld19jaGlsZCA9IG5ldyBEaXJlY3RvcnkoLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSk7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBuZXdfY2hpbGQpOwogICAgZW50cnkgPSBuZXdfY2hpbGQ7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGNvbnN0cnVjdG9yKGNvbnRlbnRzKSB7CiAgICBzdXBlcigpOwogICAgaWYgKGNvbnRlbnRzIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgdGhpcy5jb250ZW50cyA9IG5ldyBNYXAoY29udGVudHMpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5jb250ZW50cyA9IGNvbnRlbnRzOwogICAgfQogIH0KfTsKdmFyIENvbnNvbGVTdGRvdXQgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmaWxlc3RhdCA9IG5ldyBGaWxlc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCBCaWdJbnQoMCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdCB9OwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgY29uc3QgZmRzdGF0ID0gbmV3IEZkc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCAwKTsKICAgIGZkc3RhdC5mc19yaWdodHNfYmFzZSA9IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgdGhpcy53cml0ZShkYXRhKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBzdGF0aWMgbGluZUJ1ZmZlcmVkKHdyaXRlKSB7CiAgICBjb25zdCBkZWMgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICBsZXQgbGluZV9idWYgPSAiIjsKICAgIHJldHVybiBuZXcgQ29uc29sZVN0ZG91dCgoYnVmZmVyKSA9PiB7CiAgICAgIGxpbmVfYnVmICs9IGRlYy5kZWNvZGUoYnVmZmVyLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgICAgY29uc3QgbGluZXMgPSBsaW5lX2J1Zi5zcGxpdCgiXG4iKTsKICAgICAgZm9yIChjb25zdCBbaSwgbGluZV0gb2YgbGluZXMuZW50cmllcygpKSB7CiAgICAgICAgaWYgKGkgPCBsaW5lcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICB3cml0ZShsaW5lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGluZV9idWYgPSBsaW5lOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfQogIGNvbnN0cnVjdG9yKHdyaXRlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy53cml0ZSA9IHdyaXRlOwogIH0KfTsKCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL2luZGV4LmpzCmZ1bmN0aW9uIHBhcnNlSW1wb3J0cyhtb2R1bGVCeXRlcykgewogIGlmIChtb2R1bGVCeXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsKICB9IGVsc2UgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMpOwogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMuYnVmZmVyKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCJBcmd1bWVudCBtdXN0IGJlIGEgYnVmZmVyIHNvdXJjZSwgbGlrZSBVaW50OEFycmF5IG9yIEFycmF5QnVmZmVyIik7CiAgfQogIGNvbnN0IHBhcnNlU3RhdGUgPSBuZXcgUGFyc2VTdGF0ZShtb2R1bGVCeXRlcyk7CiAgcGFyc2VNYWdpY051bWJlcihwYXJzZVN0YXRlKTsKICBwYXJzZVZlcnNpb24ocGFyc2VTdGF0ZSk7CiAgY29uc3QgdHlwZXMgPSBbXTsKICBjb25zdCBpbXBvcnRzID0gW107CiAgd2hpbGUgKHBhcnNlU3RhdGUuaGFzTW9yZUJ5dGVzKCkpIHsKICAgIGNvbnN0IHNlY3Rpb25JZCA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICAgIGNvbnN0IHNlY3Rpb25TaXplID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgIHN3aXRjaCAoc2VjdGlvbklkKSB7CiAgICAgIGNhc2UgMTogewogICAgICAgIGNvbnN0IHR5cGVDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eXBlQ291bnQ7IGkrKykgewogICAgICAgICAgdHlwZXMucHVzaChwYXJzZUZ1bmN0aW9uVHlwZShwYXJzZVN0YXRlKSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgMjogewogICAgICAgIGNvbnN0IGltcG9ydENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGltcG9ydENvdW50OyBpKyspIHsKICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobW9kdWxlQnl0ZXMpOwogIGNvbnN0IGltcG9ydHMgPSBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpOwogIGNvbnN0IG1lbW9yeUltcG9ydCA9IGltcG9ydHNbMF07CiAgcmV0dXJuIHR5cGVvZiBtZW1vcnlJbXBvcnQudHlwZSA9PT0gIm9iamVjdCI7Cn0pKCk7CmZ1bmN0aW9uIHBvbHlmaWxsKFdlYkFzc2VtYmx5MykgewogIGlmIChoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0KSB7CiAgICByZXR1cm4gV2ViQXNzZW1ibHkzOwogIH0KICBjb25zdCBuZXdXZWJBc3NlbWJseSA9IHt9OwogIGZvciAoY29uc3Qga2V5IGluIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKFdlYkFzc2VtYmx5MykpIHsKICAgIG5ld1dlYkFzc2VtYmx5W2tleV0gPSBXZWJBc3NlbWJseTNba2V5XTsKICB9CiAgY29uc3QgcG9seWZpbGxlZEltcG9ydHNTeW1ib2wgPSBTeW1ib2woInBvbHlmaWxsZWRJbXBvcnRzU3ltYm9sIik7CiAgY29uc3QgYXNzaWduSW1wb3J0cyA9IChtb2R1bGUsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdID0gcGFyc2VJbXBvcnRzKHNvdXJjZUJ5dGVzKTsKICB9OwogIGNvbnN0IG5ld01vZHVsZSA9IG5ld1dlYkFzc2VtYmx5Lk1vZHVsZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICBjb25zdCBtb2R1bGUgPSBuZXcgV2ViQXNzZW1ibHkzLk1vZHVsZShieXRlcyk7CiAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZSwgbmV3TW9kdWxlLnByb3RvdHlwZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG5ld01vZHVsZS5wcm90b3R5cGUsIFdlYkFzc2VtYmx5My5Nb2R1bGUucHJvdG90eXBlKTsKICBuZXdXZWJBc3NlbWJseS5jb21waWxlID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBzb3VyY2UpOwogICAgcmV0dXJuIG1vZHVsZTsKICB9OwogIGlmIChXZWJBc3NlbWJseTMuY29tcGlsZVN0cmVhbWluZykgewogICAgbmV3V2ViQXNzZW1ibHkuY29tcGlsZVN0cmVhbWluZyA9IGFzeW5jIChzb3VyY2UpID0+IHsKICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzb3VyY2U7CiAgICAgIGNvbnN0IGNsb25lID0gcmVzcG9uc2UuY2xvbmUoKTsKICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgbmV3IFVpbnQ4QXJyYXkoYXdhaXQgY2xvbmUuYXJyYXlCdWZmZXIoKSkpOwogICAgICByZXR1cm4gbW9kdWxlOwogICAgfTsKICB9CiAgbmV3TW9kdWxlLmltcG9ydHMgPSAobW9kdWxlKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXTsKICAgIGlmICghcGFyc2VkSW1wb3J0cykgewogICAgICByZXR1cm4gV2ViQXNzZW1ibHkzLk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgICB9CiAgICByZXR1cm4gcGFyc2VkSW1wb3J0czsKICB9OwogIHJldHVybiBuZXdXZWJBc3NlbWJseTsKfQoKLy8gZW50cnlwb2ludC9jb21tb24udHMKdmFyIFdlYkFzc2VtYmx5MiA9IHBvbHlmaWxsKGdsb2JhbFRoaXMuV2ViQXNzZW1ibHkpOwp2YXIgTGluZURlY29kZXIgPSBjbGFzcyB7CiAgY29uc3RydWN0b3Iob25MaW5lKSB7CiAgICB0aGlzLmRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICB0aGlzLmJ1ZmZlciA9ICIiOwogICAgdGhpcy5vbkxpbmUgPSBvbkxpbmU7CiAgfQogIGRlY29kZXI7CiAgYnVmZmVyOwogIG9uTGluZTsKICBzZW5kKGNodW5rKSB7CiAgICB0aGlzLmJ1ZmZlciArPSB0aGlzLmRlY29kZXIuZGVjb2RlKGNodW5rLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgIGNvbnN0IGxpbmVzID0gdGhpcy5idWZmZXIuc3BsaXQoIlxuIik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykgewogICAgICB0aGlzLm9uTGluZShsaW5lc1tpXSk7CiAgICB9CiAgICB0aGlzLmJ1ZmZlciA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdOwogIH0KfTsKdmFyIFdhc21SdW5uZXIgPSAocmF3T3B0aW9ucywgU3dpZnRSdW50aW1lKSA9PiB7CiAgY29uc3Qgb3B0aW9ucyA9IGRlZmF1bHRSdW5uZXJPcHRpb25zKHJhd09wdGlvbnMpOwogIGxldCBzd2lmdDsKICBpZiAoU3dpZnRSdW50aW1lKSB7CiAgICBzd2lmdCA9IG5ldyBTd2lmdFJ1bnRpbWUoKTsKICB9CiAgbGV0IHN0ZG91dExpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRvdXRMaW5lICE9IG51bGwpIHsKICAgIHN0ZG91dExpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZG91dExpbmUpOwogIH0KICBjb25zdCBzdGRvdXQgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRvdXQ/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRvdXRMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBsZXQgc3RkZXJyTGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZGVyckxpbmUgIT0gbnVsbCkgewogICAgc3RkZXJyTGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3RkZXJyTGluZSk7CiAgfQogIGNvbnN0IHN0ZGVyciA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZGVycj8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZGVyckxpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGNvbnN0IGFyZ3MgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzLCBlbnZzLCBmZHMsIHsKICAgIGRlYnVnOiBmYWxzZQogIH0pOwogIGNvbnN0IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QgPSAoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QgPSB7CiAgICAgIHdhc2lfc25hcHNob3RfcHJldmlldzE6IHdhc2kud2FzaUltcG9ydAogICAgfTsKICAgIGlmIChzd2lmdCkgewogICAgICBpbXBvcnRPYmplY3QuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgaWYgKCFpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgX2ltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Mi5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpKSB7CiAgICAgIGNvbnN0IGltcG9ydEVudHJ5ID0gX2ltcG9ydEVudHJ5OwogICAgICBpZiAoIWltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0gPSB7fTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0gPSAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEltcG9ydGVkIGZ1bmN0aW9uICR7aW1wb3J0RW50cnkubW9kdWxlfS4ke2ltcG9ydEVudHJ5Lm5hbWV9IG5vdCBpbXBsZW1lbnRlZGApOwogICAgICAgIH07CiAgICAgIH0gZWxzZSBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAibWVtb3J5IiAmJiBpbXBvcnRFbnRyeS5tb2R1bGUgPT0gImVudiIgJiYgaW1wb3J0RW50cnkubmFtZSA9PSAibWVtb3J5IikgewogICAgICAgIGNvbnN0IHR5cGUgPSBpbXBvcnRFbnRyeS50eXBlOwogICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB7CiAgICAgICAgICBpbml0aWFsOiB0eXBlLm1pbmltdW0sCiAgICAgICAgICBtYXhpbXVtOiB0eXBlLm1heGltdW0sCiAgICAgICAgICBzaGFyZWQ6IHR5cGUuc2hhcmVkCiAgICAgICAgfTsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9IG5ldyBXZWJBc3NlbWJseTIuTWVtb3J5KGRlc2NyaXB0b3IpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0OwogIH07CiAgcmV0dXJuIHsKICAgIGFzeW5jIHJ1bih3YXNtQnl0ZXMsIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgaWYgKCFleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgZXh0cmFXYXNtSW1wb3J0cyA9IHt9OwogICAgICB9CiAgICAgIGV4dHJhV2FzbUltcG9ydHMuX19zdGFja19zYW5pdGl6ZXIgPSB7CiAgICAgICAgcmVwb3J0X3N0YWNrX292ZXJmbG93OiAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkRldGVjdGVkIHN0YWNrIGJ1ZmZlciBvdmVyZmxvdy4iKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIGNvbnN0IG1vZHVsZSA9IGF3YWl0IFdlYkFzc2VtYmx5Mi5jb21waWxlKHdhc21CeXRlcyk7CiAgICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKTsKICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBXZWJBc3NlbWJseTIuaW5zdGFudGlhdGUobW9kdWxlLCBpbXBvcnRPYmplY3QpOwogICAgICBpZiAoc3dpZnQgJiYgaW5zdGFuY2UuZXhwb3J0cy5zd2pzX2xpYnJhcnlfdmVyc2lvbikgewogICAgICAgIHN3aWZ0LnNldEluc3RhbmNlKGluc3RhbmNlKTsKICAgICAgfQogICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5zdGFydChpbnN0YW5jZSk7CiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUgPT0gImZ1bmN0aW9uIikgewogICAgICAgIHdhc2kuaW5pdGlhbGl6ZShpbnN0YW5jZSk7CiAgICAgICAgaWYgKHN3aWZ0ICYmIHN3aWZ0Lm1haW4pIHsKICAgICAgICAgIHN3aWZ0Lm1haW4oKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLm1haW4gPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5tYWluKCk7CiAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2KDAsIDApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH07Cn07CnZhciBkZWZhdWx0UnVubmVyT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7CiAgaWYgKG9wdGlvbnMuYXJncyA9PSBudWxsKSB7CiAgICBvcHRpb25zLmFyZ3MgPSBbIm1haW4ud2FzbSJdOwogIH0KICByZXR1cm4gb3B0aW9uczsKfTsKCi8vIGVudHJ5cG9pbnQvZGV2LnRzCnZhciBzb2NrZXQgPSBuZXcgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdChgd3M6Ly8ke2xvY2F0aW9uLmhvc3R9L3dhdGNoZXJgKTsKc29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCAobWVzc2FnZSkgPT4gewogIGlmIChtZXNzYWdlLmRhdGEgPT09ICJyZWxvYWQiKSB7CiAgICBsb2NhdGlvbi5yZWxvYWQoKTsKICB9Cn0pOwp2YXIgc3RhcnRXYXNpVGFzayA9IGFzeW5jICgpID0+IHsKICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCIvbWFpbi53YXNtIik7CiAgY29uc3QgcmVzcG9uc2VBcnJheUJ1ZmZlciA9IGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICB9IGNhdGNoIHsKICAgIGNvbnNvbGUubG9nKCJKYXZhU2NyaXB0S2l0IG1vZHVsZSBub3QgYXZhaWxhYmxlLCBydW5uaW5nIHdpdGhvdXQgSmF2YVNjcmlwdEtpdCBydW50aW1lLiIpOwogIH0KICBjb25zdCB3YXNtUnVubmVyID0gV2FzbVJ1bm5lcih7CiAgICBvblN0ZG91dChjaHVuaykgewogICAgICBjb25zdCBraW5kQnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKDIpOwogICAgICBuZXcgRGF0YVZpZXcoa2luZEJ1ZmZlcikuc2V0VWludDE2KDAsIDEwMDEsIHRydWUpOwogICAgICBjb25zdCBidWZmZXIgPSBuZXcgVWludDhBcnJheSgyICsgY2h1bmsubGVuZ3RoKTsKICAgICAgYnVmZmVyLnNldChuZXcgVWludDhBcnJheShraW5kQnVmZmVyKSwgMCk7CiAgICAgIGJ1ZmZlci5zZXQoY2h1bmssIDIpOwogICAgICBzb2NrZXQuc2VuZChidWZmZXIpOwogICAgfSwKICAgIG9uU3Rkb3V0TGluZShsaW5lKSB7CiAgICAgIGNvbnNvbGUubG9nKGxpbmUpOwogICAgfSwKICAgIG9uU3RkZXJyKGNodW5rKSB7CiAgICAgIGNvbnN0IGtpbmRCdWZmZXIgPSBuZXcgQXJyYXlCdWZmZXIoMik7CiAgICAgIG5ldyBEYXRhVmlldyhraW5kQnVmZmVyKS5zZXRVaW50MTYoMCwgMTAwMiwgdHJ1ZSk7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBVaW50OEFycmF5KDIgKyBjaHVuay5sZW5ndGgpOwogICAgICBidWZmZXIuc2V0KG5ldyBVaW50OEFycmF5KGtpbmRCdWZmZXIpLCAwKTsKICAgICAgYnVmZmVyLnNldChjaHVuaywgMik7CiAgICAgIHNvY2tldC5zZW5kKGJ1ZmZlcik7CiAgICB9LAogICAgb25TdGRlcnJMaW5lKGxpbmUpIHsKICAgICAgY29uc29sZS5lcnJvcihsaW5lKTsKICAgIH0KICB9LCBydW50aW1lQ29uc3RydWN0b3IpOwogIGNvbnN0IHdhc21CeXRlcyA9IG5ldyBVaW50OEFycmF5KHJlc3BvbnNlQXJyYXlCdWZmZXIpLmJ1ZmZlcjsKICBhd2FpdCB3YXNtUnVubmVyLnJ1bih3YXNtQnl0ZXMpOwp9OwpmdW5jdGlvbiBoYW5kbGVFcnJvcihlKSB7CiAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvcikgewogICAgY29uc3Qgc3RhY2sgPSBlLnN0YWNrOwogICAgaWYgKHN0YWNrICE9IG51bGwpIHsKICAgICAgc29ja2V0LnNlbmQoSlNPTi5zdHJpbmdpZnkoewogICAgICAgIGtpbmQ6ICJzdGFja1RyYWNlIiwKICAgICAgICBzdGFja1RyYWNlOiBzdGFjawogICAgICB9KSk7CiAgICB9CiAgfQp9CmFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7CiAgdHJ5IHsKICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJlcnJvciIsIChldmVudCkgPT4gewogICAgICBoYW5kbGVFcnJvcihldmVudC5lcnJvcik7CiAgICB9KTsKICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCJ1bmhhbmRsZWRyZWplY3Rpb24iLCAoZXZlbnQpID0+IHsKICAgICAgaGFuZGxlRXJyb3IoZXZlbnQucmVhc29uKTsKICAgIH0pOwogICAgYXdhaXQgc3RhcnRXYXNpVGFzaygpOwogIH0gY2F0Y2ggKGUpIHsKICAgIGhhbmRsZUVycm9yKGUpOwogICAgdGhyb3cgZTsKICB9Cn0KbWFpbigpOwovKiEKICogUmVjb25uZWN0aW5nIFdlYlNvY2tldAogKiBieSBQZWRybyBMYWRhcmlhIDxwZWRyby5sYWRhcmlhQGdtYWlsLmNvbT4KICogaHR0cHM6Ly9naXRodWIuY29tL3BsYWRhcmlhL3JlY29ubmVjdGluZy13ZWJzb2NrZXQKICogTGljZW5zZSBNSVQKICovCi8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgpDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBDb3Jwb3JhdGlvbi4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7IHlvdSBtYXkgbm90IHVzZQp0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4gWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZQpMaWNlbnNlIGF0IGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMAoKVEhJUyBDT0RFIElTIFBST1ZJREVEIE9OIEFOICpBUyBJUyogQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWQpLSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELCBJTkNMVURJTkcgV0lUSE9VVCBMSU1JVEFUSU9OIEFOWSBJTVBMSUVECldBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBUSVRMRSwgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsCk1FUkNIQU5UQUJMSVRZIE9SIE5PTi1JTkZSSU5HRU1FTlQuCgpTZWUgdGhlIEFwYWNoZSBWZXJzaW9uIDIuMCBMaWNlbnNlIGZvciBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMKYW5kIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLgoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwo=")! - public static let bundle: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpX2RlZnMuanMKdmFyIENMT0NLSURfUkVBTFRJTUUgPSAwOwp2YXIgQ0xPQ0tJRF9NT05PVE9OSUMgPSAxOwp2YXIgRVJSTk9fU1VDQ0VTUyA9IDA7CnZhciBFUlJOT19CQURGID0gODsKdmFyIEVSUk5PX0VYSVNUID0gMjA7CnZhciBFUlJOT19JTlZBTCA9IDI4Owp2YXIgRVJSTk9fSVNESVIgPSAzMTsKdmFyIEVSUk5PX05BTUVUT09MT05HID0gMzc7CnZhciBFUlJOT19OT0VOVCA9IDQ0Owp2YXIgRVJSTk9fTk9TWVMgPSA1MjsKdmFyIEVSUk5PX05PVERJUiA9IDU0Owp2YXIgRVJSTk9fTk9URU1QVFkgPSA1NTsKdmFyIEVSUk5PX05PVFNVUCA9IDU4Owp2YXIgRVJSTk9fUEVSTSA9IDYzOwp2YXIgRVJSTk9fTk9UQ0FQQUJMRSA9IDc2Owp2YXIgUklHSFRTX0ZEX0RBVEFTWU5DID0gMSA8PCAwOwp2YXIgUklHSFRTX0ZEX1JFQUQgPSAxIDw8IDE7CnZhciBSSUdIVFNfRkRfU0VFSyA9IDEgPDwgMjsKdmFyIFJJR0hUU19GRF9GRFNUQVRfU0VUX0ZMQUdTID0gMSA8PCAzOwp2YXIgUklHSFRTX0ZEX1NZTkMgPSAxIDw8IDQ7CnZhciBSSUdIVFNfRkRfVEVMTCA9IDEgPDwgNTsKdmFyIFJJR0hUU19GRF9XUklURSA9IDEgPDwgNjsKdmFyIFJJR0hUU19GRF9BRFZJU0UgPSAxIDw8IDc7CnZhciBSSUdIVFNfRkRfQUxMT0NBVEUgPSAxIDw8IDg7CnZhciBSSUdIVFNfUEFUSF9DUkVBVEVfRElSRUNUT1JZID0gMSA8PCA5Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0ZJTEUgPSAxIDw8IDEwOwp2YXIgUklHSFRTX1BBVEhfTElOS19TT1VSQ0UgPSAxIDw8IDExOwp2YXIgUklHSFRTX1BBVEhfTElOS19UQVJHRVQgPSAxIDw8IDEyOwp2YXIgUklHSFRTX1BBVEhfT1BFTiA9IDEgPDwgMTM7CnZhciBSSUdIVFNfRkRfUkVBRERJUiA9IDEgPDwgMTQ7CnZhciBSSUdIVFNfUEFUSF9SRUFETElOSyA9IDEgPDwgMTU7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfU09VUkNFID0gMSA8PCAxNjsKdmFyIFJJR0hUU19QQVRIX1JFTkFNRV9UQVJHRVQgPSAxIDw8IDE3Owp2YXIgUklHSFRTX1BBVEhfRklMRVNUQVRfR0VUID0gMSA8PCAxODsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9TSVpFID0gMSA8PCAxOTsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjA7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfR0VUID0gMSA8PCAyMTsKdmFyIFJJR0hUU19GRF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMjI7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1RJTUVTID0gMSA8PCAyMzsKdmFyIFJJR0hUU19QQVRIX1NZTUxJTksgPSAxIDw8IDI0Owp2YXIgUklHSFRTX1BBVEhfUkVNT1ZFX0RJUkVDVE9SWSA9IDEgPDwgMjU7CnZhciBSSUdIVFNfUEFUSF9VTkxJTktfRklMRSA9IDEgPDwgMjY7CnZhciBSSUdIVFNfUE9MTF9GRF9SRUFEV1JJVEUgPSAxIDw8IDI3Owp2YXIgUklHSFRTX1NPQ0tfU0hVVERPV04gPSAxIDw8IDI4Owp2YXIgSW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBJb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChJb3ZlYy5yZWFkX2J5dGVzKHZpZXcsIHB0ciArIDggKiBpKSk7CiAgICB9CiAgICByZXR1cm4gaW92ZWNzOwogIH0KfTsKdmFyIENpb3ZlYyA9IGNsYXNzIHsKICBzdGF0aWMgcmVhZF9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIGNvbnN0IGlvdmVjID0gbmV3IENpb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChDaW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBXSEVOQ0VfU0VUID0gMDsKdmFyIFdIRU5DRV9DVVIgPSAxOwp2YXIgV0hFTkNFX0VORCA9IDI7CnZhciBGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFID0gMjsKdmFyIEZJTEVUWVBFX0RJUkVDVE9SWSA9IDM7CnZhciBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgPSA0Owp2YXIgRGlyZW50ID0gY2xhc3MgewogIGhlYWRfbGVuZ3RoKCkgewogICAgcmV0dXJuIDI0OwogIH0KICBuYW1lX2xlbmd0aCgpIHsKICAgIHJldHVybiB0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGg7CiAgfQogIHdyaXRlX2hlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIsIHRoaXMuZF9uZXh0LCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDgsIHRoaXMuZF9pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50MzIocHRyICsgMTYsIHRoaXMuZGlyX25hbWUubGVuZ3RoLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDgocHRyICsgMjAsIHRoaXMuZF90eXBlKTsKICB9CiAgd3JpdGVfbmFtZV9ieXRlcyh2aWV3OCwgcHRyLCBidWZfbGVuKSB7CiAgICB2aWV3OC5zZXQodGhpcy5kaXJfbmFtZS5zbGljZSgwLCBNYXRoLm1pbih0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGgsIGJ1Zl9sZW4pKSwgcHRyKTsKICB9CiAgY29uc3RydWN0b3IobmV4dF9jb29raWUsIG5hbWUsIHR5cGUpIHsKICAgIHRoaXMuZF9pbm8gPSAwbjsKICAgIGNvbnN0IGVuY29kZWRfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICAgIHRoaXMuZF9uZXh0ID0gbmV4dF9jb29raWU7CiAgICB0aGlzLmRfbmFtbGVuID0gZW5jb2RlZF9uYW1lLmJ5dGVMZW5ndGg7CiAgICB0aGlzLmRfdHlwZSA9IHR5cGU7CiAgICB0aGlzLmRpcl9uYW1lID0gZW5jb2RlZF9uYW1lOwogIH0KfTsKdmFyIEZERkxBR1NfQVBQRU5EID0gMSA8PCAwOwp2YXIgRkRGTEFHU19EU1lOQyA9IDEgPDwgMTsKdmFyIEZERkxBR1NfTk9OQkxPQ0sgPSAxIDw8IDI7CnZhciBGREZMQUdTX1JTWU5DID0gMSA8PCAzOwp2YXIgRkRGTEFHU19TWU5DID0gMSA8PCA0Owp2YXIgRmRzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50OChwdHIsIHRoaXMuZnNfZmlsZXR5cGUpOwogICAgdmlldy5zZXRVaW50MTYocHRyICsgMiwgdGhpcy5mc19mbGFncywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmZzX3JpZ2h0c19iYXNlLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDE2LCB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgZmxhZ3MpIHsKICAgIHRoaXMuZnNfcmlnaHRzX2Jhc2UgPSAwbjsKICAgIHRoaXMuZnNfcmlnaHRzX2luaGVyaXRlZCA9IDBuOwogICAgdGhpcy5mc19maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5mc19mbGFncyA9IGZsYWdzOwogIH0KfTsKdmFyIEZTVEZMQUdTX0FUSU0gPSAxIDw8IDA7CnZhciBGU1RGTEFHU19BVElNX05PVyA9IDEgPDwgMTsKdmFyIEZTVEZMQUdTX01USU0gPSAxIDw8IDI7CnZhciBGU1RGTEFHU19NVElNX05PVyA9IDEgPDwgMzsKdmFyIE9GTEFHU19DUkVBVCA9IDEgPDwgMDsKdmFyIE9GTEFHU19ESVJFQ1RPUlkgPSAxIDw8IDE7CnZhciBPRkxBR1NfRVhDTCA9IDEgPDwgMjsKdmFyIE9GTEFHU19UUlVOQyA9IDEgPDwgMzsKdmFyIEZpbGVzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRldiwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmlubywgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDE2LCB0aGlzLmZpbGV0eXBlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDI0LCB0aGlzLm5saW5rLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDMyLCB0aGlzLnNpemUsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgMzgsIHRoaXMuYXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA0NiwgdGhpcy5tdGltLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDUyLCB0aGlzLmN0aW0sIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgc2l6ZSkgewogICAgdGhpcy5kZXYgPSAwbjsKICAgIHRoaXMuaW5vID0gMG47CiAgICB0aGlzLm5saW5rID0gMG47CiAgICB0aGlzLmF0aW0gPSAwbjsKICAgIHRoaXMubXRpbSA9IDBuOwogICAgdGhpcy5jdGltID0gMG47CiAgICB0aGlzLmZpbGV0eXBlID0gZmlsZXR5cGU7CiAgICB0aGlzLnNpemUgPSBzaXplOwogIH0KfTsKdmFyIEVWRU5UUldGTEFHU19GRF9SRUFEV1JJVEVfSEFOR1VQID0gMSA8PCAwOwp2YXIgU1VCQ0xPQ0tGTEFHU19TVUJTQ1JJUFRJT05fQ0xPQ0tfQUJTVElNRSA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9QRUVLID0gMSA8PCAwOwp2YXIgUklGTEFHU19SRUNWX1dBSVRBTEwgPSAxIDw8IDE7CnZhciBST0ZMQUdTX1JFQ1ZfREFUQV9UUlVOQ0FURUQgPSAxIDw8IDA7CnZhciBTREZMQUdTX1JEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19XUiA9IDEgPDwgMTsKdmFyIFBSRU9QRU5UWVBFX0RJUiA9IDA7CnZhciBQcmVzdGF0RGlyID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50MzIocHRyLCB0aGlzLnByX25hbWUuYnl0ZUxlbmd0aCwgdHJ1ZSk7CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUpIHsKICAgIHRoaXMucHJfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICB9Cn07CnZhciBQcmVzdGF0ID0gY2xhc3MgewogIHN0YXRpYyBkaXIobmFtZSkgewogICAgY29uc3QgcHJlc3RhdCA9IG5ldyBQcmVzdGF0KCk7CiAgICBwcmVzdGF0LnRhZyA9IFBSRU9QRU5UWVBFX0RJUjsKICAgIHByZXN0YXQuaW5uZXIgPSBuZXcgUHJlc3RhdERpcihuYW1lKTsKICAgIHJldHVybiBwcmVzdGF0OwogIH0KICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy50YWcsIHRydWUpOwogICAgdGhpcy5pbm5lci53cml0ZV9ieXRlcyh2aWV3LCBwdHIgKyA0KTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2RlYnVnLmpzCnZhciBEZWJ1ZyA9IGNsYXNzIERlYnVnMiB7CiAgZW5hYmxlKGVuYWJsZWQpIHsKICAgIHRoaXMubG9nID0gY3JlYXRlTG9nZ2VyKGVuYWJsZWQgPT09IHZvaWQgMCA/IHRydWUgOiBlbmFibGVkLCB0aGlzLnByZWZpeCk7CiAgfQogIGdldCBlbmFibGVkKCkgewogICAgcmV0dXJuIHRoaXMuaXNFbmFibGVkOwogIH0KICBjb25zdHJ1Y3Rvcihpc0VuYWJsZWQpIHsKICAgIHRoaXMuaXNFbmFibGVkID0gaXNFbmFibGVkOwogICAgdGhpcy5wcmVmaXggPSAid2FzaToiOwogICAgdGhpcy5lbmFibGUoaXNFbmFibGVkKTsKICB9Cn07CmZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihlbmFibGVkLCBwcmVmaXgpIHsKICBpZiAoZW5hYmxlZCkgewogICAgY29uc3QgYSA9IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSwgIiVjJXMiLCAiY29sb3I6ICMyNjVCQTAiLCBwcmVmaXgpOwogICAgcmV0dXJuIGE7CiAgfSBlbHNlIHsKICAgIHJldHVybiAoKSA9PiB7CiAgICB9OwogIH0KfQp2YXIgZGVidWcgPSBuZXcgRGVidWcoZmFsc2UpOwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpLmpzCnZhciBXQVNJUHJvY0V4aXQgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKICBjb25zdHJ1Y3Rvcihjb2RlKSB7CiAgICBzdXBlcigiZXhpdCB3aXRoIGV4aXQgY29kZSAiICsgY29kZSk7CiAgICB0aGlzLmNvZGUgPSBjb2RlOwogIH0KfTsKdmFyIFdBU0kgPSBjbGFzcyBXQVNJMiB7CiAgc3RhcnQoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgdHJ5IHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQoKTsKICAgICAgcmV0dXJuIDA7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIGlmIChlIGluc3RhbmNlb2YgV0FTSVByb2NFeGl0KSB7CiAgICAgICAgcmV0dXJuIGUuY29kZTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aHJvdyBlOwogICAgICB9CiAgICB9CiAgfQogIGluaXRpYWxpemUoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgaWYgKGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUpIHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSgpOwogICAgfQogIH0KICBjb25zdHJ1Y3RvcihhcmdzLCBlbnYsIGZkcywgb3B0aW9ucyA9IHt9KSB7CiAgICB0aGlzLmFyZ3MgPSBbXTsKICAgIHRoaXMuZW52ID0gW107CiAgICB0aGlzLmZkcyA9IFtdOwogICAgZGVidWcuZW5hYmxlKG9wdGlvbnMuZGVidWcpOwogICAgdGhpcy5hcmdzID0gYXJnczsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2ZpbGVzdGF0X2dldChmZCwgZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGZkX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIGRlYnVnLmxvZyhwYXRoKTsKICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfcmVhZGxpbmsocGF0aCk7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVuYW1lKGZkLCBvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgbmV3X2ZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGxldCB7IHJldCwgaW5vZGVfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmsob2xkX3BhdGgpOwogICAgICAgIGlmIChpbm9kZV9vYmogPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgdHJ1ZSk7CiAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICBpZiAoc2VsZi5mZHNbZmRdLnBhdGhfbGluayhvbGRfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKSAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIHRocm93ICJwYXRoX2xpbmsgc2hvdWxkIGFsd2F5cyByZXR1cm4gc3VjY2VzcyB3aGVuIHJlbGlua2luZyBhbiBpbm9kZSBiYWNrIHRvIHRoZSBvcmlnaW5hbCBwbGFjZSI7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfc3ltbGluayhvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF91bmxpbmtfZmlsZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwb2xsX29uZW9mZihpbl8sIG91dCwgbnN1YnNjcmlwdGlvbnMpIHsKICAgICAgdGhyb3cgImFzeW5jIGlvIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgcHJvY19leGl0KGV4aXRfY29kZSkgewogICAgICB0aHJvdyBuZXcgV0FTSVByb2NFeGl0KGV4aXRfY29kZSk7CiAgICB9LCBwcm9jX3JhaXNlKHNpZykgewogICAgICB0aHJvdyAicmFpc2VkIHNpZ25hbCAiICsgc2lnOwogICAgfSwgc2NoZWRfeWllbGQoKSB7CiAgICB9LCByYW5kb21fZ2V0KGJ1ZiwgYnVmX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmX2xlbjsgaSsrKSB7CiAgICAgICAgYnVmZmVyOFtidWYgKyBpXSA9IE1hdGgucmFuZG9tKCkgKiAyNTYgfCAwOwogICAgICB9CiAgICB9LCBzb2NrX3JlY3YoZmQsIHJpX2RhdGEsIHJpX2ZsYWdzKSB7CiAgICAgIHRocm93ICJzb2NrZXRzIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgc29ja19zZW5kKGZkLCBzaV9kYXRhLCBzaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2h1dGRvd24oZmQsIGhvdykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfYWNjZXB0KGZkLCBmbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0gfTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZkLmpzCnZhciBGZCA9IGNsYXNzIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfY2xvc2UoKSB7CiAgICByZXR1cm4gMDsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBmZHN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBwcmVzdGF0OiBudWxsIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRpcmVudDogbnVsbCB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9zeW5jKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9saW5rKHBhdGgsIGlub2RlLCBhbGxvd19kaXIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rKHBhdGgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aCwgZGlyZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9yZWFkbGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9yZW5hbWUob2xkX3BhdGgsIG5ld19mZCwgbmV3X3BhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9Cn07CnZhciBJbm9kZSA9IGNsYXNzIHsKfTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3QvZnNfbWVtLmpzCnZhciBPcGVuRmlsZSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBvZmZzZXQgKyBsZW4pIHsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIGxlbikpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIDApIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IHNpemUpIHsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheSh0aGlzLmZpbGUuZGF0YS5idWZmZXIuc2xpY2UoMCwgTnVtYmVyKHNpemUpKSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihzaXplKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcih0aGlzLmZpbGVfcG9zKSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KHNsaWNlLmxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIob2Zmc2V0KSwgTnVtYmVyKG9mZnNldCArIEJpZ0ludChzaXplKSkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICBsZXQgY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICBzd2l0Y2ggKHdoZW5jZSkgewogICAgICBjYXNlIFdIRU5DRV9TRVQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0NVUjoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IHRoaXMuZmlsZV9wb3MgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0VORDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IEJpZ0ludCh0aGlzLmZpbGUuZGF0YS5ieXRlTGVuZ3RoKSArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICBpZiAoY2FsY3VsYXRlZF9vZmZzZXQgPCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIHRoaXMuZmlsZV9wb3MgPSBjYWxjdWxhdGVkX29mZnNldDsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIodGhpcy5maWxlX3BvcykpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKG9mZnNldCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZmlsZS5zdGF0KCkgfTsKICB9CiAgY29uc3RydWN0b3IoZmlsZSkgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZmlsZV9wb3MgPSAwbjsKICAgIHRoaXMuZmlsZSA9IGZpbGU7CiAgfQp9Owp2YXIgT3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMCkgfTsKICB9CiAgZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKSB7CiAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICBkZWJ1Zy5sb2coInJlYWRkaXJfc2luZ2xlIiwgY29va2llKTsKICAgICAgZGVidWcubG9nKGNvb2tpZSwgdGhpcy5kaXIuY29udGVudHMua2V5cygpKTsKICAgIH0KICAgIGlmIChjb29raWUgPT0gMG4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMW4sICIuIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfSBlbHNlIGlmIChjb29raWUgPT0gMW4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMm4sICIuLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0KICAgIGlmIChjb29raWUgPj0gQmlnSW50KHRoaXMuZGlyLmNvbnRlbnRzLnNpemUpICsgMm4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IFtuYW1lLCBlbnRyeV0gPSBBcnJheS5mcm9tKHRoaXMuZGlyLmNvbnRlbnRzLmVudHJpZXMoKSlbTnVtYmVyKGNvb2tpZSAtIDJuKV07CiAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbmV3IERpcmVudChjb29raWUgKyAxbiwgbmFtZSwgZW50cnkuc3RhdCgpLmZpbGV0eXBlKSB9OwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX2VyciwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX2VyciwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBmaWxlc3RhdDogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogZW50cnkuc3RhdCgpIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGhfc3RyLCBkaXJmbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGhfc3RyLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBsZXQgeyByZXQsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfZW50cnlfZm9yX3BhdGgocGF0aCk7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICBpZiAocmV0ICE9IEVSUk5PX05PRU5UKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0LCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19DUkVBVCkgPT0gT0ZMQUdTX0NSRUFUKSB7CiAgICAgICAgY29uc3QgeyByZXQ6IHJldDIsIGVudHJ5OiBuZXdfZW50cnkgfSA9IHRoaXMuZGlyLmNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkpOwogICAgICAgIGlmIChuZXdfZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiByZXQyLCBmZF9vYmo6IG51bGwgfTsKICAgICAgICB9CiAgICAgICAgZW50cnkgPSBuZXdfZW50cnk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoKG9mbGFncyAmIE9GTEFHU19FWENMKSA9PSBPRkxBR1NfRVhDTCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4gZW50cnkucGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoLCBPRkxBR1NfQ1JFQVQgfCBPRkxBR1NfRElSRUNUT1JZLCAwbiwgMG4sIDApLnJldDsKICB9CiAgcGF0aF9saW5rKHBhdGhfc3RyLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgY29uc3Qgc291cmNlX2lzX2RpciA9IGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGNvbnN0IHRhcmdldF9pc19kaXIgPSBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBpZiAoc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgaWYgKGFsbG93X2RpciAmJiBlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgewogICAgICAgICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgPT0gMCkgewogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYgKHNvdXJjZV9pc19kaXIgJiYgIXRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgICB9IGVsc2UgaWYgKCFzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICAgIH0gZWxzZSBpZiAoaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFKSB7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICB9CiAgICB9CiAgICBpZiAoIWFsbG93X2RpciAmJiBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19QRVJNOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLnNldChmaWxlbmFtZSwgaW5vZGUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfdW5saW5rKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlID09PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgfHwgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgIH0KICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplICE9PSAwKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgIH0KICAgIGlmICghcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZGlyLnN0YXQoKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGNvbnN0cnVjdG9yKGRpcikgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGlyID0gZGlyOwogIH0KfTsKdmFyIFByZW9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIE9wZW5EaXJlY3RvcnkgewogIGZkX3ByZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBwcmVzdGF0OiBQcmVzdGF0LmRpcih0aGlzLnByZXN0YXRfbmFtZSkgfTsKICB9CiAgY29uc3RydWN0b3IobmFtZSwgY29udGVudHMpIHsKICAgIHN1cGVyKG5ldyBEaXJlY3RvcnkoY29udGVudHMpKTsKICAgIHRoaXMucHJlc3RhdF9uYW1lID0gbmFtZTsKICB9Cn07CnZhciBGaWxlID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICBpZiAodGhpcy5yZWFkb25seSAmJiAoZnNfcmlnaHRzX2Jhc2UgJiBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgPT0gQmlnSW50KFJJR0hUU19GRF9XUklURSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX1RSVU5DKSA9PSBPRkxBR1NfVFJVTkMpIHsKICAgICAgaWYgKHRoaXMucmVhZG9ubHkpCiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoW10pOwogICAgfQogICAgY29uc3QgZmlsZSA9IG5ldyBPcGVuRmlsZSh0aGlzKTsKICAgIGlmIChmZF9mbGFncyAmIEZERkxBR1NfQVBQRU5EKQogICAgICBmaWxlLmZkX3NlZWsoMG4sIFdIRU5DRV9FTkQpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IGZpbGUgfTsKICB9CiAgZ2V0IHNpemUoKSB7CiAgICByZXR1cm4gQmlnSW50KHRoaXMuZGF0YS5ieXRlTGVuZ3RoKTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCB0aGlzLnNpemUpOwogIH0KICBjb25zdHJ1Y3RvcihkYXRhLCBvcHRpb25zKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7CiAgICB0aGlzLnJlYWRvbmx5ID0gISFvcHRpb25zPy5yZWFkb25seTsKICB9Cn07CnZhciBQYXRoID0gY2xhc3MgUGF0aDIgewogIHN0YXRpYyBmcm9tKHBhdGgpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aC5lbmRzV2l0aCgiLyIpOwogICAgaWYgKHBhdGguc3RhcnRzV2l0aCgiLyIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgfQogICAgaWYgKHBhdGguaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5zcGxpdCgiLyIpKSB7CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIiIHx8IGNvbXBvbmVudCA9PT0gIi4iKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKGNvbXBvbmVudCA9PT0gIi4uIikgewogICAgICAgIGlmIChzZWxmLnBhcnRzLnBvcCgpID09IHZvaWQgMCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIHNlbGYucGFydHMucHVzaChjb21wb25lbnQpOwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXRoOiBzZWxmIH07CiAgfQogIHRvX3BhdGhfc3RyaW5nKCkgewogICAgbGV0IHMgPSB0aGlzLnBhcnRzLmpvaW4oIi8iKTsKICAgIGlmICh0aGlzLmlzX2RpcikgewogICAgICBzICs9ICIvIjsKICAgIH0KICAgIHJldHVybiBzOwogIH0KICBjb25zdHJ1Y3RvcigpIHsKICAgIHRoaXMucGFydHMgPSBbXTsKICAgIHRoaXMuaXNfZGlyID0gZmFsc2U7CiAgfQp9Owp2YXIgRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogbmV3IE9wZW5EaXJlY3RvcnkodGhpcykgfTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwbik7CiAgfQogIGdldF9lbnRyeV9mb3JfcGF0aChwYXRoKSB7CiAgICBsZXQgZW50cnkgPSB0aGlzOwogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGFsbG93X3VuZGVmaW5lZCkgewogICAgY29uc3QgZmlsZW5hbWUgPSBwYXRoLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogZW50cnlfcmV0LCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKCEocGFyZW50X2VudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IGVudHJ5ID0gcGFyZW50X2VudHJ5LmNvbnRlbnRzLmdldChmaWxlbmFtZSk7CiAgICBpZiAoZW50cnkgPT09IHZvaWQgMCkgewogICAgICBpZiAoIWFsbG93X3VuZGVmaW5lZCkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9OwogIH0KICBjcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIGlzX2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgZGVidWcubG9nKCJjcmVhdGUiLCBwYXRoKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvaW5kZXguanMKZnVuY3Rpb24gcGFyc2VJbXBvcnRzKG1vZHVsZUJ5dGVzKSB7CiAgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcyk7CiAgfSBlbHNlIGlmIChtb2R1bGVCeXRlcy5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcy5idWZmZXIpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoIkFyZ3VtZW50IG11c3QgYmUgYSBidWZmZXIgc291cmNlLCBsaWtlIFVpbnQ4QXJyYXkgb3IgQXJyYXlCdWZmZXIiKTsKICB9CiAgY29uc3QgcGFyc2VTdGF0ZSA9IG5ldyBQYXJzZVN0YXRlKG1vZHVsZUJ5dGVzKTsKICBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpOwogIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKTsKICBjb25zdCB0eXBlcyA9IFtdOwogIGNvbnN0IGltcG9ydHMgPSBbXTsKICB3aGlsZSAocGFyc2VTdGF0ZS5oYXNNb3JlQnl0ZXMoKSkgewogICAgY29uc3Qgc2VjdGlvbklkID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgY29uc3Qgc2VjdGlvblNpemUgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgc3dpdGNoIChzZWN0aW9uSWQpIHsKICAgICAgY2FzZSAxOiB7CiAgICAgICAgY29uc3QgdHlwZUNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVDb3VudDsgaSsrKSB7CiAgICAgICAgICB0eXBlcy5wdXNoKHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAyOiB7CiAgICAgICAgY29uc3QgaW1wb3J0Q291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW1wb3J0Q291bnQ7IGkrKykgewogICAgICAgICAgY29uc3QgbW9kdWxlID0gcGFyc2VTdGF0ZS5yZWFkTmFtZSgpOwogICAgICAgICAgY29uc3QgbmFtZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJmdW5jdGlvbiIsIHR5cGU6IHR5cGVzW2luZGV4XSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgIGltcG9ydHMucHVzaCh7IG1vZHVsZSwgbmFtZSwga2luZDogInRhYmxlIiwgdHlwZTogcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJtZW1vcnkiLCB0eXBlOiBwYXJzZUxpbWl0cyhwYXJzZVN0YXRlKSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgIGltcG9ydHMucHVzaCh7IG1vZHVsZSwgbmFtZSwga2luZDogImdsb2JhbCIsIHR5cGU6IHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gaW1wb3J0IGRlc2NyaXB0b3IgdHlwZSAke3R5cGV9YCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbXBvcnRzOwogICAgICB9CiAgICAgIGRlZmF1bHQ6IHsKICAgICAgICBwYXJzZVN0YXRlLnNraXBCeXRlcyhzZWN0aW9uU2l6ZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFtdOwp9CnZhciBQYXJzZVN0YXRlID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG1vZHVsZUJ5dGVzKSB7CiAgICB0aGlzLm1vZHVsZUJ5dGVzID0gbW9kdWxlQnl0ZXM7CiAgICB0aGlzLm9mZnNldCA9IDA7CiAgICB0aGlzLnRleHREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpOwogIH0KICBoYXNNb3JlQnl0ZXMoKSB7CiAgICByZXR1cm4gdGhpcy5vZmZzZXQgPCB0aGlzLm1vZHVsZUJ5dGVzLmxlbmd0aDsKICB9CiAgcmVhZEJ5dGUoKSB7CiAgICByZXR1cm4gdGhpcy5tb2R1bGVCeXRlc1t0aGlzLm9mZnNldCsrXTsKICB9CiAgc2tpcEJ5dGVzKGNvdW50KSB7CiAgICB0aGlzLm9mZnNldCArPSBjb3VudDsKICB9CiAgcmVhZFVuc2lnbmVkTEVCMTI4KCkgewogICAgbGV0IHJlc3VsdCA9IDA7CiAgICBsZXQgc2hpZnQgPSAwOwogICAgbGV0IGJ5dGU7CiAgICBkbyB7CiAgICAgIGJ5dGUgPSB0aGlzLnJlYWRCeXRlKCk7CiAgICAgIHJlc3VsdCB8PSAoYnl0ZSAmIDEyNykgPDwgc2hpZnQ7CiAgICAgIHNoaWZ0ICs9IDc7CiAgICB9IHdoaWxlIChieXRlICYgMTI4KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfQogIHJlYWROYW1lKCkgewogICAgY29uc3QgbmFtZUxlbmd0aCA9IHRoaXMucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICBjb25zdCBuYW1lQnl0ZXMgPSB0aGlzLm1vZHVsZUJ5dGVzLnNsaWNlKHRoaXMub2Zmc2V0LCB0aGlzLm9mZnNldCArIG5hbWVMZW5ndGgpOwogICAgY29uc3QgbmFtZSA9IHRoaXMudGV4dERlY29kZXIuZGVjb2RlKG5hbWVCeXRlcyk7CiAgICB0aGlzLm9mZnNldCArPSBuYW1lTGVuZ3RoOwogICAgcmV0dXJuIG5hbWU7CiAgfQogIGFzc2VydEJ5dGVzKGV4cGVjdGVkKSB7CiAgICBjb25zdCBiYXNlT2Zmc2V0ID0gdGhpcy5vZmZzZXQ7CiAgICBjb25zdCBleHBlY3RlZExlbmd0aCA9IGV4cGVjdGVkLmxlbmd0aDsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwZWN0ZWRMZW5ndGg7IGkrKykgewogICAgICBpZiAodGhpcy5tb2R1bGVCeXRlc1tiYXNlT2Zmc2V0ICsgaV0gIT09IGV4cGVjdGVkW2ldKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSBhdCBvZmZzZXQgJHtiYXNlT2Zmc2V0fWApOwogICAgICB9CiAgICB9CiAgICB0aGlzLm9mZnNldCArPSBleHBlY3RlZExlbmd0aDsKICB9Cn07CmZ1bmN0aW9uIHBhcnNlTWFnaWNOdW1iZXIocGFyc2VTdGF0ZSkgewogIGNvbnN0IGV4cGVjdGVkID0gWzAsIDk3LCAxMTUsIDEwOV07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VWZXJzaW9uKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFsxLCAwLCAwLCAwXTsKICBwYXJzZVN0YXRlLmFzc2VydEJ5dGVzKGV4cGVjdGVkKTsKfQpmdW5jdGlvbiBwYXJzZVRhYmxlVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgZWxlbWVudFR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgbGV0IGVsZW1lbnQ7CiAgc3dpdGNoIChlbGVtZW50VHlwZSkgewogICAgY2FzZSAxMTI6CiAgICAgIGVsZW1lbnQgPSAiZnVuY3JlZiI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAxMTE6CiAgICAgIGVsZW1lbnQgPSAiZXh0ZXJucmVmIjsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdGFibGUgZWxlbWVudCB0eXBlICR7ZWxlbWVudFR5cGV9YCk7CiAgfQogIGNvbnN0IHsgbWluaW11bSwgbWF4aW11bSB9ID0gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSk7CiAgaWYgKG1heGltdW0pIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0sIG1heGltdW0gfTsKICB9IGVsc2UgewogICAgcmV0dXJuIHsgZWxlbWVudCwgbWluaW11bSB9OwogIH0KfQpmdW5jdGlvbiBwYXJzZUxpbWl0cyhwYXJzZVN0YXRlKSB7CiAgY29uc3QgZmxhZ3MgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgY29uc3QgbWluaW11bSA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgY29uc3QgaGFzTWF4aW11bSA9IGZsYWdzICYgMTsKICBjb25zdCBzaGFyZWQgPSAoZmxhZ3MgJiAyKSAhPT0gMDsKICBjb25zdCBpc01lbW9yeTY0ID0gKGZsYWdzICYgNCkgIT09IDA7CiAgY29uc3QgaW5kZXggPSBpc01lbW9yeTY0ID8gImk2NCIgOiAiaTMyIjsKICBpZiAoaGFzTWF4aW11bSkgewogICAgY29uc3QgbWF4aW11bSA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4LCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IG1pbmltdW0sIHNoYXJlZCwgaW5kZXggfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VHbG9iYWxUeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCB2YWx1ZSA9IHBhcnNlVmFsdWVUeXBlKHBhcnNlU3RhdGUpOwogIGNvbnN0IG11dGFibGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCkgPT09IDE7CiAgcmV0dXJuIHsgdmFsdWUsIG11dGFibGUgfTsKfQpmdW5jdGlvbiBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdHlwZSA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgMTI3OgogICAgICByZXR1cm4gImkzMiI7CiAgICBjYXNlIDEyNjoKICAgICAgcmV0dXJuICJpNjQiOwogICAgY2FzZSAxMjU6CiAgICAgIHJldHVybiAiZjMyIjsKICAgIGNhc2UgMTI0OgogICAgICByZXR1cm4gImY2NCI7CiAgICBjYXNlIDExMjoKICAgICAgcmV0dXJuICJmdW5jcmVmIjsKICAgIGNhc2UgMTExOgogICAgICByZXR1cm4gImV4dGVybnJlZiI7CiAgICBjYXNlIDEyMzoKICAgICAgcmV0dXJuICJ2MTI4IjsKICAgIGRlZmF1bHQ6CiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB2YWx1ZSB0eXBlICR7dHlwZX1gKTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VGdW5jdGlvblR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZvcm0gPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgaWYgKGZvcm0gIT09IDk2KSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGZ1bmN0aW9uIHR5cGUgZm9ybSAweDYwLCBnb3QgJHtmb3JtfWApOwogIH0KICBjb25zdCBwYXJhbWV0ZXJzID0gW107CiAgY29uc3QgcGFyYW1ldGVyQ291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1ldGVyQ291bnQ7IGkrKykgewogICAgcGFyYW1ldGVycy5wdXNoKHBhcnNlVmFsdWVUeXBlKHBhcnNlU3RhdGUpKTsKICB9CiAgY29uc3QgcmVzdWx0cyA9IFtdOwogIGNvbnN0IHJlc3VsdENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdENvdW50OyBpKyspIHsKICAgIHJlc3VsdHMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIHJldHVybiB7IHBhcmFtZXRlcnMsIHJlc3VsdHMgfTsKfQoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvcG9seWZpbGwuanMKdmFyIGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQgPSAoKCkgPT4gewogIGNvbnN0IG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoWwogICAgMCwKICAgIDk3LAogICAgMTE1LAogICAgMTA5LAogICAgMSwKICAgIDAsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICA2LAogICAgMSwKICAgIDAsCiAgICAwLAogICAgMiwKICAgIDAsCiAgICAxCiAgXSk7CiAgY29uc3QgbW9kdWxlID0gbmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShtb2R1bGVCeXRlcyk7CiAgY29uc3QgaW1wb3J0cyA9IFdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgY29uc3QgbWVtb3J5SW1wb3J0ID0gaW1wb3J0c1swXTsKICByZXR1cm4gdHlwZW9mIG1lbW9yeUltcG9ydC50eXBlID09PSAib2JqZWN0IjsKfSkoKTsKZnVuY3Rpb24gcG9seWZpbGwoV2ViQXNzZW1ibHkzKSB7CiAgaWYgKGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQpIHsKICAgIHJldHVybiBXZWJBc3NlbWJseTM7CiAgfQogIGNvbnN0IG5ld1dlYkFzc2VtYmx5ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoV2ViQXNzZW1ibHkzKSkgewogICAgbmV3V2ViQXNzZW1ibHlba2V5XSA9IFdlYkFzc2VtYmx5M1trZXldOwogIH0KICBjb25zdCBwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbCA9IFN5bWJvbCgicG9seWZpbGxlZEltcG9ydHNTeW1ib2wiKTsKICBjb25zdCBhc3NpZ25JbXBvcnRzID0gKG1vZHVsZSwgc291cmNlQnl0ZXMpID0+IHsKICAgIG1vZHVsZVtwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbF0gPSBwYXJzZUltcG9ydHMoc291cmNlQnl0ZXMpOwogIH07CiAgY29uc3QgbmV3TW9kdWxlID0gbmV3V2ViQXNzZW1ibHkuTW9kdWxlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICAgIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseTMuTW9kdWxlKGJ5dGVzKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBieXRlcyk7CiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YobW9kdWxlLCBuZXdNb2R1bGUucHJvdG90eXBlKTsKICAgIHJldHVybiBtb2R1bGU7CiAgfTsKICBPYmplY3Quc2V0UHJvdG90eXBlT2YobmV3TW9kdWxlLnByb3RvdHlwZSwgV2ViQXNzZW1ibHkzLk1vZHVsZS5wcm90b3R5cGUpOwogIG5ld1dlYkFzc2VtYmx5LmNvbXBpbGUgPSBhc3luYyAoc291cmNlKSA9PiB7CiAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseTMuY29tcGlsZShzb3VyY2UpOwogICAgYXNzaWduSW1wb3J0cyhtb2R1bGUsIHNvdXJjZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgaWYgKFdlYkFzc2VtYmx5My5jb21waWxlU3RyZWFtaW5nKSB7CiAgICBuZXdXZWJBc3NlbWJseS5jb21waWxlU3RyZWFtaW5nID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNvdXJjZTsKICAgICAgY29uc3QgY2xvbmUgPSByZXNwb25zZS5jbG9uZSgpOwogICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseTMuY29tcGlsZVN0cmVhbWluZyhyZXNwb25zZSk7CiAgICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBuZXcgVWludDhBcnJheShhd2FpdCBjbG9uZS5hcnJheUJ1ZmZlcigpKSk7CiAgICAgIHJldHVybiBtb2R1bGU7CiAgICB9OwogIH0KICBuZXdNb2R1bGUuaW1wb3J0cyA9IChtb2R1bGUpID0+IHsKICAgIGNvbnN0IHBhcnNlZEltcG9ydHMgPSBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdOwogICAgaWYgKCFwYXJzZWRJbXBvcnRzKSB7CiAgICAgIHJldHVybiBXZWJBc3NlbWJseTMuTW9kdWxlLmltcG9ydHMobW9kdWxlKTsKICAgIH0KICAgIHJldHVybiBwYXJzZWRJbXBvcnRzOwogIH07CiAgcmV0dXJuIG5ld1dlYkFzc2VtYmx5Owp9CgovLyBlbnRyeXBvaW50L2NvbW1vbi50cwp2YXIgV2ViQXNzZW1ibHkyID0gcG9seWZpbGwoZ2xvYmFsVGhpcy5XZWJBc3NlbWJseSk7CnZhciBMaW5lRGVjb2RlciA9IGNsYXNzIHsKICBjb25zdHJ1Y3RvcihvbkxpbmUpIHsKICAgIHRoaXMuZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIHRoaXMuYnVmZmVyID0gIiI7CiAgICB0aGlzLm9uTGluZSA9IG9uTGluZTsKICB9CiAgZGVjb2RlcjsKICBidWZmZXI7CiAgb25MaW5lOwogIHNlbmQoY2h1bmspIHsKICAgIHRoaXMuYnVmZmVyICs9IHRoaXMuZGVjb2Rlci5kZWNvZGUoY2h1bmssIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgY29uc3QgbGluZXMgPSB0aGlzLmJ1ZmZlci5zcGxpdCgiXG4iKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoIC0gMTsgaSsrKSB7CiAgICAgIHRoaXMub25MaW5lKGxpbmVzW2ldKTsKICAgIH0KICAgIHRoaXMuYnVmZmVyID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV07CiAgfQp9Owp2YXIgV2FzbVJ1bm5lciA9IChyYXdPcHRpb25zLCBTd2lmdFJ1bnRpbWUpID0+IHsKICBjb25zdCBvcHRpb25zID0gZGVmYXVsdFJ1bm5lck9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0OwogIGlmIChTd2lmdFJ1bnRpbWUpIHsKICAgIHN3aWZ0ID0gbmV3IFN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJncyA9IG9wdGlvbnMuYXJncyB8fCBbXTsKICBjb25zdCBmZHMgPSBbCiAgICBuZXcgT3BlbkZpbGUobmV3IEZpbGUoW10pKSwKICAgIHN0ZG91dCwKICAgIHN0ZGVyciwKICAgIG5ldyBQcmVvcGVuRGlyZWN0b3J5KCIvIiwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSkKICBdOwogIGNvbnN0IGVudnMgPSBvcHRpb25zLmVudiA/IE9iamVjdC5lbnRyaWVzKG9wdGlvbnMuZW52KS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYCR7a2V5fT0ke3ZhbHVlfWApIDogW107CiAgY29uc3Qgd2FzaSA9IG5ldyBXQVNJKGFyZ3MsIGVudnMsIGZkcywgewogICAgZGVidWc6IGZhbHNlCiAgfSk7CiAgY29uc3QgY3JlYXRlV2FzbUltcG9ydE9iamVjdCA9IChleHRyYVdhc21JbXBvcnRzLCBtb2R1bGUpID0+IHsKICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IHsKICAgICAgd2FzaV9zbmFwc2hvdF9wcmV2aWV3MTogd2FzaS53YXNpSW1wb3J0CiAgICB9OwogICAgaWYgKHN3aWZ0KSB7CiAgICAgIGltcG9ydE9iamVjdC5qYXZhc2NyaXB0X2tpdCA9IHN3aWZ0Lndhc21JbXBvcnRzOwogICAgfQogICAgaWYgKGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgZm9yIChjb25zdCBtb2R1bGVOYW1lIGluIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgICBpZiAoIWltcG9ydE9iamVjdFttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdID0ge307CiAgICAgICAgfQogICAgICAgIGZvciAoY29uc3QgZW50cnkgaW4gZXh0cmFXYXNtSW1wb3J0c1ttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdW2VudHJ5XSA9IGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV1bZW50cnldOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZm9yIChjb25zdCBfaW1wb3J0RW50cnkgb2YgV2ViQXNzZW1ibHkyLk1vZHVsZS5pbXBvcnRzKG1vZHVsZSkpIHsKICAgICAgY29uc3QgaW1wb3J0RW50cnkgPSBfaW1wb3J0RW50cnk7CiAgICAgIGlmICghaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXSA9IHt9OwogICAgICB9CiAgICAgIGlmIChpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSkgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJmdW5jdGlvbiIpIHsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfSBlbHNlIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJtZW1vcnkiICYmIGltcG9ydEVudHJ5Lm1vZHVsZSA9PSAiZW52IiAmJiBpbXBvcnRFbnRyeS5uYW1lID09ICJtZW1vcnkiKSB7CiAgICAgICAgY29uc3QgdHlwZSA9IGltcG9ydEVudHJ5LnR5cGU7CiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsKICAgICAgICAgIGluaXRpYWw6IHR5cGUubWluaW11bSwKICAgICAgICAgIG1heGltdW06IHR5cGUubWF4aW11bSwKICAgICAgICAgIHNoYXJlZDogdHlwZS5zaGFyZWQKICAgICAgICB9OwogICAgICAgIGltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gbmV3IFdlYkFzc2VtYmx5Mi5NZW1vcnkoZGVzY3JpcHRvcik7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBpbXBvcnRPYmplY3Q7CiAgfTsKICByZXR1cm4gewogICAgYXN5bmMgcnVuKHdhc21CeXRlcywgZXh0cmFXYXNtSW1wb3J0cykgewogICAgICBpZiAoIWV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgICBleHRyYVdhc21JbXBvcnRzID0ge307CiAgICAgIH0KICAgICAgZXh0cmFXYXNtSW1wb3J0cy5fX3N0YWNrX3Nhbml0aXplciA9IHsKICAgICAgICByZXBvcnRfc3RhY2tfb3ZlcmZsb3c6ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcigiRGV0ZWN0ZWQgc3RhY2sgYnVmZmVyIG92ZXJmbG93LiIpOwogICAgICAgIH0KICAgICAgfTsKICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkyLmNvbXBpbGUod2FzbUJ5dGVzKTsKICAgICAgY29uc3QgaW1wb3J0T2JqZWN0ID0gY3JlYXRlV2FzbUltcG9ydE9iamVjdChleHRyYVdhc21JbXBvcnRzLCBtb2R1bGUpOwogICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IFdlYkFzc2VtYmx5Mi5pbnN0YW50aWF0ZShtb2R1bGUsIGltcG9ydE9iamVjdCk7CiAgICAgIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICAgICAgc3dpZnQuc2V0SW5zdGFuY2UoaW5zdGFuY2UpOwogICAgICB9CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICB3YXNpLnN0YXJ0KGluc3RhbmNlKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgICAgICBpZiAoc3dpZnQgJiYgc3dpZnQubWFpbikgewogICAgICAgICAgc3dpZnQubWFpbigpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMubWFpbiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgICAgICBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YoMCwgMCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfTsKfTsKdmFyIGRlZmF1bHRSdW5uZXJPcHRpb25zID0gKG9wdGlvbnMpID0+IHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIHJldHVybiBvcHRpb25zOwp9OwoKLy8gZW50cnlwb2ludC9idW5kbGUudHMKdmFyIHN0YXJ0V2FzaVRhc2sgPSBhc3luYyAoKSA9PiB7CiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgiUkVQTEFDRV9USElTX1dJVEhfVEhFX01BSU5fV0VCQVNTRU1CTFlfTU9EVUxFIik7CiAgY29uc3QgcmVzcG9uc2VBcnJheUJ1ZmZlciA9IGF3YWl0IHJlc3BvbnNlLmFycmF5QnVmZmVyKCk7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICB9IGNhdGNoIHsKICB9CiAgY29uc3Qgd2FzbVJ1bm5lciA9IFdhc21SdW5uZXIoewogICAgb25TdGRvdXRMaW5lKGxpbmUpIHsKICAgICAgY29uc29sZS5sb2cobGluZSk7CiAgICB9LAogICAgb25TdGRlcnJMaW5lKGxpbmUpIHsKICAgICAgY29uc29sZS5lcnJvcihsaW5lKTsKICAgIH0KICB9LCBydW50aW1lQ29uc3RydWN0b3IpOwogIGNvbnN0IHdhc21CeXRlcyA9IG5ldyBVaW50OEFycmF5KHJlc3BvbnNlQXJyYXlCdWZmZXIpLmJ1ZmZlcjsKICBhd2FpdCB3YXNtUnVubmVyLnJ1bih3YXNtQnl0ZXMpOwp9Owphc3luYyBmdW5jdGlvbiBtYWluKCkgewogIGF3YWl0IHN0YXJ0V2FzaVRhc2soKTsKfQptYWluKCk7Cg==")! - public static let test: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL3JlY29ubmVjdGluZy13ZWJzb2NrZXQvZGlzdC9yZWNvbm5lY3Rpbmctd2Vic29ja2V0LW1qcy5qcwp2YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24oZDIsIGIyKSB7CiAgICBkMi5fX3Byb3RvX18gPSBiMjsKICB9IHx8IGZ1bmN0aW9uKGQyLCBiMikgewogICAgZm9yICh2YXIgcCBpbiBiMikKICAgICAgaWYgKGIyLmhhc093blByb3BlcnR5KHApKQogICAgICAgIGQyW3BdID0gYjJbcF07CiAgfTsKICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKfTsKZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzKGQsIGIpOwogIGZ1bmN0aW9uIF9fKCkgewogICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7CiAgfQogIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKfQpmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7CiAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSAiZnVuY3Rpb24iICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7CiAgaWYgKG0pCiAgICByZXR1cm4gbS5jYWxsKG8pOwogIHJldHVybiB7CiAgICBuZXh0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkKICAgICAgICBvID0gdm9pZCAwOwogICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07CiAgICB9CiAgfTsKfQpmdW5jdGlvbiBfX3JlYWQobywgbikgewogIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07CiAgaWYgKCFtKQogICAgcmV0dXJuIG87CiAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7CiAgdHJ5IHsKICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKQogICAgICBhci5wdXNoKHIudmFsdWUpOwogIH0gY2F0Y2ggKGVycm9yKSB7CiAgICBlID0geyBlcnJvciB9OwogIH0gZmluYWxseSB7CiAgICB0cnkgewogICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVsicmV0dXJuIl0pKQogICAgICAgIG0uY2FsbChpKTsKICAgIH0gZmluYWxseSB7CiAgICAgIGlmIChlKQogICAgICAgIHRocm93IGUuZXJyb3I7CiAgICB9CiAgfQogIHJldHVybiBhcjsKfQpmdW5jdGlvbiBfX3NwcmVhZCgpIHsKICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykKICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTsKICByZXR1cm4gYXI7Cn0KdmFyIEV2ZW50ID0gZnVuY3Rpb24oKSB7CiAgZnVuY3Rpb24gRXZlbnQyKHR5cGUsIHRhcmdldCkgewogICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CiAgICB0aGlzLnR5cGUgPSB0eXBlOwogIH0KICByZXR1cm4gRXZlbnQyOwp9KCk7CnZhciBFcnJvckV2ZW50ID0gZnVuY3Rpb24oX3N1cGVyKSB7CiAgX19leHRlbmRzKEVycm9yRXZlbnQyLCBfc3VwZXIpOwogIGZ1bmN0aW9uIEVycm9yRXZlbnQyKGVycm9yLCB0YXJnZXQpIHsKICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJlcnJvciIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLm1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlOwogICAgX3RoaXMuZXJyb3IgPSBlcnJvcjsKICAgIHJldHVybiBfdGhpczsKICB9CiAgcmV0dXJuIEVycm9yRXZlbnQyOwp9KEV2ZW50KTsKdmFyIENsb3NlRXZlbnQgPSBmdW5jdGlvbihfc3VwZXIpIHsKICBfX2V4dGVuZHMoQ2xvc2VFdmVudDIsIF9zdXBlcik7CiAgZnVuY3Rpb24gQ2xvc2VFdmVudDIoY29kZSwgcmVhc29uLCB0YXJnZXQpIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIGlmIChyZWFzb24gPT09IHZvaWQgMCkgewogICAgICByZWFzb24gPSAiIjsKICAgIH0KICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJjbG9zZSIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLndhc0NsZWFuID0gdHJ1ZTsKICAgIF90aGlzLmNvZGUgPSBjb2RlOwogICAgX3RoaXMucmVhc29uID0gcmVhc29uOwogICAgcmV0dXJuIF90aGlzOwogIH0KICByZXR1cm4gQ2xvc2VFdmVudDI7Cn0oRXZlbnQpOwp2YXIgZ2V0R2xvYmFsV2ViU29ja2V0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKHR5cGVvZiBXZWJTb2NrZXQgIT09ICJ1bmRlZmluZWQiKSB7CiAgICByZXR1cm4gV2ViU29ja2V0OwogIH0KfTsKdmFyIGlzV2ViU29ja2V0ID0gZnVuY3Rpb24odykgewogIHJldHVybiB0eXBlb2YgdyAhPT0gInVuZGVmaW5lZCIgJiYgISF3ICYmIHcuQ0xPU0lORyA9PT0gMjsKfTsKdmFyIERFRkFVTFQgPSB7CiAgbWF4UmVjb25uZWN0aW9uRGVsYXk6IDFlNCwKICBtaW5SZWNvbm5lY3Rpb25EZWxheTogMWUzICsgTWF0aC5yYW5kb20oKSAqIDRlMywKICBtaW5VcHRpbWU6IDVlMywKICByZWNvbm5lY3Rpb25EZWxheUdyb3dGYWN0b3I6IDEuMywKICBjb25uZWN0aW9uVGltZW91dDogNGUzLAogIG1heFJldHJpZXM6IEluZmluaXR5LAogIG1heEVucXVldWVkTWVzc2FnZXM6IEluZmluaXR5LAogIHN0YXJ0Q2xvc2VkOiBmYWxzZSwKICBkZWJ1ZzogZmFsc2UKfTsKdmFyIFJlY29ubmVjdGluZ1dlYlNvY2tldCA9IGZ1bmN0aW9uKCkgewogIGZ1bmN0aW9uIFJlY29ubmVjdGluZ1dlYlNvY2tldDIodXJsLCBwcm90b2NvbHMsIG9wdGlvbnMpIHsKICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7CiAgICAgIG9wdGlvbnMgPSB7fTsKICAgIH0KICAgIHRoaXMuX2xpc3RlbmVycyA9IHsKICAgICAgZXJyb3I6IFtdLAogICAgICBtZXNzYWdlOiBbXSwKICAgICAgb3BlbjogW10sCiAgICAgIGNsb3NlOiBbXQogICAgfTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIHRoaXMuX3Nob3VsZFJlY29ubmVjdCA9IHRydWU7CiAgICB0aGlzLl9jb25uZWN0TG9jayA9IGZhbHNlOwogICAgdGhpcy5fYmluYXJ5VHlwZSA9ICJibG9iIjsKICAgIHRoaXMuX2Nsb3NlQ2FsbGVkID0gZmFsc2U7CiAgICB0aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgIHRoaXMub25jbG9zZSA9IG51bGw7CiAgICB0aGlzLm9uZXJyb3IgPSBudWxsOwogICAgdGhpcy5vbm1lc3NhZ2UgPSBudWxsOwogICAgdGhpcy5vbm9wZW4gPSBudWxsOwogICAgdGhpcy5faGFuZGxlT3BlbiA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgIF90aGlzLl9kZWJ1Zygib3BlbiBldmVudCIpOwogICAgICB2YXIgX2EgPSBfdGhpcy5fb3B0aW9ucy5taW5VcHRpbWUsIG1pblVwdGltZSA9IF9hID09PSB2b2lkIDAgPyBERUZBVUxULm1pblVwdGltZSA6IF9hOwogICAgICBjbGVhclRpbWVvdXQoX3RoaXMuX2Nvbm5lY3RUaW1lb3V0KTsKICAgICAgX3RoaXMuX3VwdGltZVRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5fYWNjZXB0T3BlbigpOwogICAgICB9LCBtaW5VcHRpbWUpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fbWVzc2FnZVF1ZXVlLmZvckVhY2goZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHJldHVybiBfdGhpcy5fd3Muc2VuZChtZXNzYWdlKTsKICAgICAgfSk7CiAgICAgIF90aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgICAgaWYgKF90aGlzLm9ub3BlbikgewogICAgICAgIF90aGlzLm9ub3BlbihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5vcGVuLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZU1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkgewogICAgICBfdGhpcy5fZGVidWcoIm1lc3NhZ2UgZXZlbnQiKTsKICAgICAgaWYgKF90aGlzLm9ubWVzc2FnZSkgewogICAgICAgIF90aGlzLm9ubWVzc2FnZShldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5tZXNzYWdlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUVycm9yID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJlcnJvciBldmVudCIsIGV2ZW50Lm1lc3NhZ2UpOwogICAgICBfdGhpcy5fZGlzY29ubmVjdCh2b2lkIDAsIGV2ZW50Lm1lc3NhZ2UgPT09ICJUSU1FT1VUIiA/ICJ0aW1lb3V0IiA6IHZvaWQgMCk7CiAgICAgIGlmIChfdGhpcy5vbmVycm9yKSB7CiAgICAgICAgX3RoaXMub25lcnJvcihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJleGVjIGVycm9yIGxpc3RlbmVycyIpOwogICAgICBfdGhpcy5fbGlzdGVuZXJzLmVycm9yLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgICBfdGhpcy5fY29ubmVjdCgpOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUNsb3NlID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJjbG9zZSBldmVudCIpOwogICAgICBfdGhpcy5fY2xlYXJUaW1lb3V0cygpOwogICAgICBpZiAoX3RoaXMuX3Nob3VsZFJlY29ubmVjdCkgewogICAgICAgIF90aGlzLl9jb25uZWN0KCk7CiAgICAgIH0KICAgICAgaWYgKF90aGlzLm9uY2xvc2UpIHsKICAgICAgICBfdGhpcy5vbmNsb3NlKGV2ZW50KTsKICAgICAgfQogICAgICBfdGhpcy5fbGlzdGVuZXJzLmNsb3NlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX3VybCA9IHVybDsKICAgIHRoaXMuX3Byb3RvY29scyA9IHByb3RvY29sczsKICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zOwogICAgaWYgKHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQpIHsKICAgICAgdGhpcy5fc2hvdWxkUmVjb25uZWN0ID0gZmFsc2U7CiAgICB9CiAgICB0aGlzLl9jb25uZWN0KCk7CiAgfQogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ09OTkVDVElORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiAwOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0MiwgIk9QRU4iLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gMTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIsICJDTE9TSU5HIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ0xPU0VEIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDM7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNPTk5FQ1RJTkciLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5DT05ORUNUSU5HOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJPUEVOIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIFJlY29ubmVjdGluZ1dlYlNvY2tldDIuT1BFTjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiQ0xPU0lORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NJTkc7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNMT1NFRCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRDsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYmluYXJ5VHlwZSIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmJpbmFyeVR5cGUgOiB0aGlzLl9iaW5hcnlUeXBlOwogICAgfSwKICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgdGhpcy5fYmluYXJ5VHlwZSA9IHZhbHVlOwogICAgICBpZiAodGhpcy5fd3MpIHsKICAgICAgICB0aGlzLl93cy5iaW5hcnlUeXBlID0gdmFsdWU7CiAgICAgIH0KICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicmV0cnlDb3VudCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBNYXRoLm1heCh0aGlzLl9yZXRyeUNvdW50LCAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYnVmZmVyZWRBbW91bnQiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICB2YXIgYnl0ZXMgPSB0aGlzLl9tZXNzYWdlUXVldWUucmVkdWNlKGZ1bmN0aW9uKGFjYywgbWVzc2FnZSkgewogICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgIGFjYyArPSBtZXNzYWdlLmxlbmd0aDsKICAgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBCbG9iKSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5zaXplOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5ieXRlTGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYWNjOwogICAgICB9LCAwKTsKICAgICAgcmV0dXJuIGJ5dGVzICsgKHRoaXMuX3dzID8gdGhpcy5fd3MuYnVmZmVyZWRBbW91bnQgOiAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiZXh0ZW5zaW9ucyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmV4dGVuc2lvbnMgOiAiIjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicHJvdG9jb2wiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gdGhpcy5fd3MgPyB0aGlzLl93cy5wcm90b2NvbCA6ICIiOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJyZWFkeVN0YXRlIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKHRoaXMuX3dzKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX3dzLnJlYWR5U3RhdGU7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQgPyBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRCA6IFJlY29ubmVjdGluZ1dlYlNvY2tldDIuQ09OTkVDVElORzsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAidXJsIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIHRoaXMuX3dzID8gdGhpcy5fd3MudXJsIDogIiI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICBpZiAoY29kZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvZGUgPSAxZTM7CiAgICB9CiAgICB0aGlzLl9jbG9zZUNhbGxlZCA9IHRydWU7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSBmYWxzZTsKICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlIGVucXVldWVkOiBubyB3cyBpbnN0YW5jZSIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlOiBhbHJlYWR5IGNsb3NlZCIpOwogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSB0cnVlOwogICAgdGhpcy5fY2xvc2VDYWxsZWQgPSBmYWxzZTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIGlmICghdGhpcy5fd3MgfHwgdGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fY29ubmVjdCgpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5fZGlzY29ubmVjdChjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9jb25uZWN0KCk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSkgewogICAgaWYgKHRoaXMuX3dzICYmIHRoaXMuX3dzLnJlYWR5U3RhdGUgPT09IHRoaXMuT1BFTikgewogICAgICB0aGlzLl9kZWJ1Zygic2VuZCIsIGRhdGEpOwogICAgICB0aGlzLl93cy5zZW5kKGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucy5tYXhFbnF1ZXVlZE1lc3NhZ2VzLCBtYXhFbnF1ZXVlZE1lc3NhZ2VzID0gX2EgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4RW5xdWV1ZWRNZXNzYWdlcyA6IF9hOwogICAgICBpZiAodGhpcy5fbWVzc2FnZVF1ZXVlLmxlbmd0aCA8IG1heEVucXVldWVkTWVzc2FnZXMpIHsKICAgICAgICB0aGlzLl9kZWJ1ZygiZW5xdWV1ZSIsIGRhdGEpOwogICAgICAgIHRoaXMuX21lc3NhZ2VRdWV1ZS5wdXNoKGRhdGEpOwogICAgICB9CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdLnB1c2gobGlzdGVuZXIpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuZGlzcGF0Y2hFdmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICB2YXIgZV8xLCBfYTsKICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnNbZXZlbnQudHlwZV07CiAgICBpZiAobGlzdGVuZXJzKSB7CiAgICAgIHRyeSB7CiAgICAgICAgZm9yICh2YXIgbGlzdGVuZXJzXzEgPSBfX3ZhbHVlcyhsaXN0ZW5lcnMpLCBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpOyAhbGlzdGVuZXJzXzFfMS5kb25lOyBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpKSB7CiAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNfMV8xLnZhbHVlOwogICAgICAgICAgdGhpcy5fY2FsbEV2ZW50TGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyKTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2ggKGVfMV8xKSB7CiAgICAgICAgZV8xID0geyBlcnJvcjogZV8xXzEgfTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICB0cnkgewogICAgICAgICAgaWYgKGxpc3RlbmVyc18xXzEgJiYgIWxpc3RlbmVyc18xXzEuZG9uZSAmJiAoX2EgPSBsaXN0ZW5lcnNfMS5yZXR1cm4pKQogICAgICAgICAgICBfYS5jYWxsKGxpc3RlbmVyc18xKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgaWYgKGVfMSkKICAgICAgICAgICAgdGhyb3cgZV8xLmVycm9yOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdID0gdGhpcy5fbGlzdGVuZXJzW3R5cGVdLmZpbHRlcihmdW5jdGlvbihsKSB7CiAgICAgICAgcmV0dXJuIGwgIT09IGxpc3RlbmVyOwogICAgICB9KTsKICAgIH0KICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9kZWJ1ZyA9IGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3MgPSBbXTsKICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7CiAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTsKICAgIH0KICAgIGlmICh0aGlzLl9vcHRpb25zLmRlYnVnKSB7CiAgICAgIGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIF9fc3ByZWFkKFsiUldTPiJdLCBhcmdzKSk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fZ2V0TmV4dERlbGF5ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX2EgPSB0aGlzLl9vcHRpb25zLCBfYiA9IF9hLnJlY29ubmVjdGlvbkRlbGF5R3Jvd0ZhY3RvciwgcmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQucmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yIDogX2IsIF9jID0gX2EubWluUmVjb25uZWN0aW9uRGVsYXksIG1pblJlY29ubmVjdGlvbkRlbGF5ID0gX2MgPT09IHZvaWQgMCA/IERFRkFVTFQubWluUmVjb25uZWN0aW9uRGVsYXkgOiBfYywgX2QgPSBfYS5tYXhSZWNvbm5lY3Rpb25EZWxheSwgbWF4UmVjb25uZWN0aW9uRGVsYXkgPSBfZCA9PT0gdm9pZCAwID8gREVGQVVMVC5tYXhSZWNvbm5lY3Rpb25EZWxheSA6IF9kOwogICAgdmFyIGRlbGF5ID0gMDsKICAgIGlmICh0aGlzLl9yZXRyeUNvdW50ID4gMCkgewogICAgICBkZWxheSA9IG1pblJlY29ubmVjdGlvbkRlbGF5ICogTWF0aC5wb3cocmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yLCB0aGlzLl9yZXRyeUNvdW50IC0gMSk7CiAgICAgIGlmIChkZWxheSA+IG1heFJlY29ubmVjdGlvbkRlbGF5KSB7CiAgICAgICAgZGVsYXkgPSBtYXhSZWNvbm5lY3Rpb25EZWxheTsKICAgICAgfQogICAgfQogICAgdGhpcy5fZGVidWcoIm5leHQgZGVsYXkiLCBkZWxheSk7CiAgICByZXR1cm4gZGVsYXk7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fd2FpdCA9IGZ1bmN0aW9uKCkgewogICAgdmFyIF90aGlzID0gdGhpczsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7CiAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgX3RoaXMuX2dldE5leHREZWxheSgpKTsKICAgIH0pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2dldE5leHRVcmwgPSBmdW5jdGlvbih1cmxQcm92aWRlcikgewogICAgaWYgKHR5cGVvZiB1cmxQcm92aWRlciA9PT0gInN0cmluZyIpIHsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1cmxQcm92aWRlcik7CiAgICB9CiAgICBpZiAodHlwZW9mIHVybFByb3ZpZGVyID09PSAiZnVuY3Rpb24iKSB7CiAgICAgIHZhciB1cmwgPSB1cmxQcm92aWRlcigpOwogICAgICBpZiAodHlwZW9mIHVybCA9PT0gInN0cmluZyIpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVybCk7CiAgICAgIH0KICAgICAgaWYgKCEhdXJsLnRoZW4pIHsKICAgICAgICByZXR1cm4gdXJsOwogICAgICB9CiAgICB9CiAgICB0aHJvdyBFcnJvcigiSW52YWxpZCBVUkwiKTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jb25uZWN0ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX3RoaXMgPSB0aGlzOwogICAgaWYgKHRoaXMuX2Nvbm5lY3RMb2NrIHx8ICF0aGlzLl9zaG91bGRSZWNvbm5lY3QpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fY29ubmVjdExvY2sgPSB0cnVlOwogICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucywgX2IgPSBfYS5tYXhSZXRyaWVzLCBtYXhSZXRyaWVzID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4UmV0cmllcyA6IF9iLCBfYyA9IF9hLmNvbm5lY3Rpb25UaW1lb3V0LCBjb25uZWN0aW9uVGltZW91dCA9IF9jID09PSB2b2lkIDAgPyBERUZBVUxULmNvbm5lY3Rpb25UaW1lb3V0IDogX2MsIF9kID0gX2EuV2ViU29ja2V0LCBXZWJTb2NrZXQyID0gX2QgPT09IHZvaWQgMCA/IGdldEdsb2JhbFdlYlNvY2tldCgpIDogX2Q7CiAgICBpZiAodGhpcy5fcmV0cnlDb3VudCA+PSBtYXhSZXRyaWVzKSB7CiAgICAgIHRoaXMuX2RlYnVnKCJtYXggcmV0cmllcyByZWFjaGVkIiwgdGhpcy5fcmV0cnlDb3VudCwgIj49IiwgbWF4UmV0cmllcyk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIHRoaXMuX3JldHJ5Q291bnQrKzsKICAgIHRoaXMuX2RlYnVnKCJjb25uZWN0IiwgdGhpcy5fcmV0cnlDb3VudCk7CiAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lcnMoKTsKICAgIGlmICghaXNXZWJTb2NrZXQoV2ViU29ja2V0MikpIHsKICAgICAgdGhyb3cgRXJyb3IoIk5vIHZhbGlkIFdlYlNvY2tldCBjbGFzcyBwcm92aWRlZCIpOwogICAgfQogICAgdGhpcy5fd2FpdCgpLnRoZW4oZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBfdGhpcy5fZ2V0TmV4dFVybChfdGhpcy5fdXJsKTsKICAgIH0pLnRoZW4oZnVuY3Rpb24odXJsKSB7CiAgICAgIGlmIChfdGhpcy5fY2xvc2VDYWxsZWQpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJjb25uZWN0IiwgeyB1cmwsIHByb3RvY29sczogX3RoaXMuX3Byb3RvY29scyB9KTsKICAgICAgX3RoaXMuX3dzID0gX3RoaXMuX3Byb3RvY29scyA/IG5ldyBXZWJTb2NrZXQyKHVybCwgX3RoaXMuX3Byb3RvY29scykgOiBuZXcgV2ViU29ja2V0Mih1cmwpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fY29ubmVjdExvY2sgPSBmYWxzZTsKICAgICAgX3RoaXMuX2FkZExpc3RlbmVycygpOwogICAgICBfdGhpcy5fY29ubmVjdFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5faGFuZGxlVGltZW91dCgpOwogICAgICB9LCBjb25uZWN0aW9uVGltZW91dCk7CiAgICB9KTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9oYW5kbGVUaW1lb3V0ID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLl9kZWJ1ZygidGltZW91dCBldmVudCIpOwogICAgdGhpcy5faGFuZGxlRXJyb3IobmV3IEVycm9yRXZlbnQoRXJyb3IoIlRJTUVPVVQiKSwgdGhpcykpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2Rpc2Nvbm5lY3QgPSBmdW5jdGlvbihjb2RlLCByZWFzb24pIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJzKCk7CiAgICB0cnkgewogICAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9oYW5kbGVDbG9zZShuZXcgQ2xvc2VFdmVudChjb2RlLCByZWFzb24sIHRoaXMpKTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fYWNjZXB0T3BlbiA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5fZGVidWcoImFjY2VwdCBvcGVuIik7CiAgICB0aGlzLl9yZXRyeUNvdW50ID0gMDsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jYWxsRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBsaXN0ZW5lcikgewogICAgaWYgKCJoYW5kbGVFdmVudCIgaW4gbGlzdGVuZXIpIHsKICAgICAgbGlzdGVuZXIuaGFuZGxlRXZlbnQoZXZlbnQpOwogICAgfSBlbHNlIHsKICAgICAgbGlzdGVuZXIoZXZlbnQpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX3JlbW92ZUxpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygicmVtb3ZlTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2FkZExpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygiYWRkTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2NsZWFyVGltZW91dHMgPSBmdW5jdGlvbigpIHsKICAgIGNsZWFyVGltZW91dCh0aGlzLl9jb25uZWN0VGltZW91dCk7CiAgICBjbGVhclRpbWVvdXQodGhpcy5fdXB0aW1lVGltZW91dCk7CiAgfTsKICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0MjsKfSgpOwp2YXIgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdCA9IFJlY29ubmVjdGluZ1dlYlNvY2tldDsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJncywgZW52LCBmZHMsIG9wdGlvbnMgPSB7fSkgewogICAgdGhpcy5hcmdzID0gW107CiAgICB0aGlzLmVudiA9IFtdOwogICAgdGhpcy5mZHMgPSBbXTsKICAgIGRlYnVnLmVuYWJsZShvcHRpb25zLmRlYnVnKTsKICAgIHRoaXMuYXJncyA9IGFyZ3M7CiAgICB0aGlzLmVudiA9IGVudjsKICAgIHRoaXMuZmRzID0gZmRzOwogICAgY29uc3Qgc2VsZiA9IHRoaXM7CiAgICB0aGlzLndhc2lJbXBvcnQgPSB7IGFyZ3Nfc2l6ZXNfZ2V0KGFyZ2MsIGFyZ3ZfYnVmX3NpemUpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ2MsIHNlbGYuYXJncy5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGFyZyBvZiBzZWxmLmFyZ3MpIHsKICAgICAgICBidWZfc2l6ZSArPSBhcmcubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3ZfYnVmX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoYXJnYywgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGFyZ3NfZ2V0KGFyZ3YsIGFyZ3ZfYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2FyZ3ZfYnVmID0gYXJndl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5hcmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihhcmd2LCBhcmd2X2J1ZiwgdHJ1ZSk7CiAgICAgICAgYXJndiArPSA0OwogICAgICAgIGNvbnN0IGFyZyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmFyZ3NbaV0pOwogICAgICAgIGJ1ZmZlcjguc2V0KGFyZywgYXJndl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChhcmd2X2J1ZiArIGFyZy5sZW5ndGgsIDApOwogICAgICAgIGFyZ3ZfYnVmICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgICAgZGVidWcubG9nKG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvcmlnX2FyZ3ZfYnVmLCBhcmd2X2J1ZikpKTsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fc2l6ZXNfZ2V0KGVudmlyb25fY291bnQsIGVudmlyb25fc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9jb3VudCwgc2VsZi5lbnYubGVuZ3RoLCB0cnVlKTsKICAgICAgbGV0IGJ1Zl9zaXplID0gMDsKICAgICAgZm9yIChjb25zdCBlbnZpcm9uIG9mIHNlbGYuZW52KSB7CiAgICAgICAgYnVmX3NpemUgKz0gZW52aXJvbi5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9zaXplLCBidWZfc2l6ZSwgdHJ1ZSk7CiAgICAgIGRlYnVnLmxvZyhidWZmZXIuZ2V0VWludDMyKGVudmlyb25fY291bnQsIHRydWUpLCBidWZmZXIuZ2V0VWludDMyKGVudmlyb25fc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fZ2V0KGVudmlyb24sIGVudmlyb25fYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2Vudmlyb25fYnVmID0gZW52aXJvbl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5lbnYubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGVudmlyb24sIGVudmlyb25fYnVmLCB0cnVlKTsKICAgICAgICBlbnZpcm9uICs9IDQ7CiAgICAgICAgY29uc3QgZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmVudltpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoZSwgZW52aXJvbl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChlbnZpcm9uX2J1ZiArIGUubGVuZ3RoLCAwKTsKICAgICAgICBlbnZpcm9uX2J1ZiArPSBlLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfZW52aXJvbl9idWYsIGVudmlyb25fYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgY2xvY2tfcmVzX2dldChpZCwgcmVzX3B0cikgewogICAgICBsZXQgcmVzb2x1dGlvblZhbHVlOwogICAgICBzd2l0Y2ggKGlkKSB7CiAgICAgICAgY2FzZSBDTE9DS0lEX01PTk9UT05JQzogewogICAgICAgICAgcmVzb2x1dGlvblZhbHVlID0gNTAwMG47CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDTE9DS0lEX1JFQUxUSU1FOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSAxMDAwMDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuIEVSUk5PX05PU1lTOwogICAgICB9CiAgICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIHZpZXcuc2V0QmlnVWludDY0KHJlc19wdHIsIHJlc29sdXRpb25WYWx1ZSwgdHJ1ZSk7CiAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgfSwgY2xvY2tfdGltZV9nZXQoaWQsIHByZWNpc2lvbiwgdGltZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChpZCA9PT0gQ0xPQ0tJRF9SRUFMVElNRSkgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgQmlnSW50KG5ldyBEYXRlKCkuZ2V0VGltZSgpKSAqIDEwMDAwMDBuLCB0cnVlKTsKICAgICAgfSBlbHNlIGlmIChpZCA9PSBDTE9DS0lEX01PTk9UT05JQykgewogICAgICAgIGxldCBtb25vdG9uaWNfdGltZTsKICAgICAgICB0cnkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSBCaWdJbnQoTWF0aC5yb3VuZChwZXJmb3JtYW5jZS5ub3coKSAqIDFlNikpOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIG1vbm90b25pY190aW1lID0gMG47CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgbW9ub3RvbmljX3RpbWUsIHRydWUpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgMG4sIHRydWUpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZmRfYWR2aXNlKGZkLCBvZmZzZXQsIGxlbiwgYWR2aWNlKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2FsbG9jYXRlKGZkLCBvZmZzZXQsIGxlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9jbG9zZShmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW2ZkXS5mZF9jbG9zZSgpOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9kYXRhc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfZ2V0KGZkLCBmZHN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZkc3RhdCB9ID0gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmRzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZkc3RhdC53cml0ZV9ieXRlcyhuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlciksIGZkc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfc2V0X2ZsYWdzKGZkLCBmbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZkLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X2dldChmZCwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfZ2V0KCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfc2V0X3NpemUoZmQsIHNpemUpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlYWQoaW92ZWMuYnVmX2xlbiwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgb2Zmc2V0ICs9IEJpZ0ludChkYXRhLmxlbmd0aCk7CiAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggIT0gaW92ZWMuYnVmX2xlbikgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9nZXQoZmQsIGJ1Zl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBwcmVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgYnVmX3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZXN0YXRfZGlyX25hbWUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBjb25zdCBwcmVzdGF0X2Rpcl9uYW1lID0gcHJlc3RhdC5pbm5lci5wcl9uYW1lOwogICAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgICBidWZmZXI4LnNldChwcmVzdGF0X2Rpcl9uYW1lLnNsaWNlKDAsIHBhdGhfbGVuKSwgcGF0aF9wdHIpOwogICAgICAgIHJldHVybiBwcmVzdGF0X2Rpcl9uYW1lLmJ5dGVMZW5ndGggPiBwYXRoX2xlbiA/IEVSUk5PX05BTUVUT09MT05HIDogRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHdyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbndyaXR0ZW5fcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IENpb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbndyaXR0ZW4gPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCBkYXRhID0gYnVmZmVyOC5zbGljZShpb3ZlYy5idWYsIGlvdmVjLmJ1ZiArIGlvdmVjLmJ1Zl9sZW4pOwogICAgICAgICAgY29uc3QgeyByZXQsIG53cml0dGVuOiBud3JpdHRlbl9wYXJ0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHdyaXRlKGRhdGEsIG9mZnNldCk7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIG53cml0dGVuICs9IG53cml0dGVuX3BhcnQ7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KG53cml0dGVuX3BhcnQpOwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG5yZWFkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBJb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbnJlYWQgPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLmZkX3JlYWQoaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGEsIGlvdmVjLmJ1Zik7CiAgICAgICAgICBucmVhZCArPSBkYXRhLmxlbmd0aDsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkZGlyKGZkLCBidWYsIGJ1Zl9sZW4sIGNvb2tpZSwgYnVmdXNlZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgbGV0IGJ1ZnVzZWQgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGlyZW50IH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKTsKICAgICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChkaXJlbnQgPT0gbnVsbCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5oZWFkX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNvbnN0IGhlYWRfYnl0ZXMgPSBuZXcgQXJyYXlCdWZmZXIoZGlyZW50LmhlYWRfbGVuZ3RoKCkpOwogICAgICAgICAgZGlyZW50LndyaXRlX2hlYWRfYnl0ZXMobmV3IERhdGFWaWV3KGhlYWRfYnl0ZXMpLCAwKTsKICAgICAgICAgIGJ1ZmZlcjguc2V0KG5ldyBVaW50OEFycmF5KGhlYWRfYnl0ZXMpLnNsaWNlKDAsIE1hdGgubWluKGhlYWRfYnl0ZXMuYnl0ZUxlbmd0aCwgYnVmX2xlbiAtIGJ1ZnVzZWQpKSwgYnVmKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50LmhlYWRfbGVuZ3RoKCk7CiAgICAgICAgICBpZiAoYnVmX2xlbiAtIGJ1ZnVzZWQgPCBkaXJlbnQubmFtZV9sZW5ndGgoKSkgewogICAgICAgICAgICBidWZ1c2VkID0gYnVmX2xlbjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBkaXJlbnQud3JpdGVfbmFtZV9ieXRlcyhidWZmZXI4LCBidWYsIGJ1Zl9sZW4gLSBidWZ1c2VkKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50Lm5hbWVfbGVuZ3RoKCk7CiAgICAgICAgICBjb29raWUgPSBkaXJlbnQuZF9uZXh0OwogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcmVudW1iZXIoZmQsIHRvKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW3RvXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCByZXQgPSBzZWxmLmZkc1t0b10uZmRfY2xvc2UoKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzW3RvXSA9IHNlbGYuZmRzW2ZkXTsKICAgICAgICBzZWxmLmZkc1tmZF0gPSB2b2lkIDA7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3NlZWsoZmQsIG9mZnNldCwgd2hlbmNlLCBvZmZzZXRfb3V0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIG9mZnNldDogb2Zmc2V0X291dCB9ID0gc2VsZi5mZHNbZmRdLmZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdJbnQ2NChvZmZzZXRfb3V0X3B0ciwgb2Zmc2V0X291dCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF90ZWxsKGZkLCBvZmZzZXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfdGVsbCgpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQob2Zmc2V0X3B0ciwgb2Zmc2V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF93cml0ZShmZCwgaW92c19wdHIsIGlvdnNfbGVuLCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF93cml0ZShkYXRhKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIGlmIChud3JpdHRlbl9wYXJ0ICE9IGRhdGEuYnl0ZUxlbmd0aCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9nZXQoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGZpbGVzdGF0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2xpbmsob2xkX2ZkLCBvbGRfZmxhZ3MsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW29sZF9mZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW29sZF9mZF0ucGF0aF9sb29rdXAob2xkX3BhdGgsIG9sZF9mbGFncyk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgZmFsc2UpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX29wZW4oZmQsIGRpcmZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncywgb3BlbmVkX2ZkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgpOwogICAgICAgIGNvbnN0IHsgcmV0LCBmZF9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGgsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncyk7CiAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBzZWxmLmZkcy5wdXNoKGZkX29iaik7CiAgICAgICAgY29uc3Qgb3BlbmVkX2ZkID0gc2VsZi5mZHMubGVuZ3RoIC0gMTsKICAgICAgICBidWZmZXIuc2V0VWludDMyKG9wZW5lZF9mZF9wdHIsIG9wZW5lZF9mZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVhZGxpbmsoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbiwgYnVmX3B0ciwgYnVmX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3JlYWRsaW5rKHBhdGgpOwogICAgICAgIGlmIChkYXRhICE9IG51bGwpIHsKICAgICAgICAgIGNvbnN0IGRhdGFfYnVmID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGRhdGEpOwogICAgICAgICAgaWYgKGRhdGFfYnVmLmxlbmd0aCA+IGJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIDAsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGFfYnVmLCBidWZfcHRyKTsKICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBkYXRhX2J1Zi5sZW5ndGgsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbW92ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbmFtZShmZCwgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCAmJiBzZWxmLmZkc1tuZXdfZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICBsZXQgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfdW5saW5rKG9sZF9wYXRoKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldCA9IHNlbGYuZmRzW25ld19mZF0ucGF0aF9saW5rKG5ld19wYXRoLCBpbm9kZV9vYmosIHRydWUpOwogICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgaWYgKHNlbGYuZmRzW2ZkXS5wYXRoX2xpbmsob2xkX3BhdGgsIGlub2RlX29iaiwgdHJ1ZSkgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICB0aHJvdyAicGF0aF9saW5rIHNob3VsZCBhbHdheXMgcmV0dXJuIHN1Y2Nlc3Mgd2hlbiByZWxpbmtpbmcgYW4gaW5vZGUgYmFjayB0byB0aGUgb3JpZ2luYWwgcGxhY2UiOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3N5bWxpbmsob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIGZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfdW5saW5rX2ZpbGUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmtfZmlsZShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGgsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfcmVhZGxpbmsocGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG51bGwgfTsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQp9Owp2YXIgSW5vZGUgPSBjbGFzcyB7Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZzX21lbS5qcwp2YXIgT3BlbkZpbGUgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gb2Zmc2V0ICsgbGVuKSB7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBsZW4pKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCAwKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBzaXplKSB7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5maWxlLmRhdGEuYnVmZmVyLnNsaWNlKDAsIE51bWJlcihzaXplKSkpOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIoc2l6ZSkpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIodGhpcy5maWxlX3BvcyksIE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KHNpemUpKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChzbGljZS5sZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKG9mZnNldCksIE51bWJlcihvZmZzZXQgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgbGV0IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgc3dpdGNoICh3aGVuY2UpIHsKICAgICAgY2FzZSBXSEVOQ0VfU0VUOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9DVVI6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSB0aGlzLmZpbGVfcG9zICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9FTkQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBCaWdJbnQodGhpcy5maWxlLmRhdGEuYnl0ZUxlbmd0aCkgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgaWYgKGNhbGN1bGF0ZWRfb2Zmc2V0IDwgMCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICB0aGlzLmZpbGVfcG9zID0gY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcihvZmZzZXQpKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmZpbGUuc3RhdCgpIH07CiAgfQogIGNvbnN0cnVjdG9yKGZpbGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmZpbGVfcG9zID0gMG47CiAgICB0aGlzLmZpbGUgPSBmaWxlOwogIH0KfTsKdmFyIE9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9ESVJFQ1RPUlksIDApIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgZGVidWcubG9nKCJyZWFkZGlyX3NpbmdsZSIsIGNvb2tpZSk7CiAgICAgIGRlYnVnLmxvZyhjb29raWUsIHRoaXMuZGlyLmNvbnRlbnRzLmtleXMoKSk7CiAgICB9CiAgICBpZiAoY29va2llID09IDBuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDFuLCAiLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0gZWxzZSBpZiAoY29va2llID09IDFuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDJuLCAiLi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9CiAgICBpZiAoY29va2llID49IEJpZ0ludCh0aGlzLmRpci5jb250ZW50cy5zaXplKSArIDJuKSB7CiAgICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBbbmFtZSwgZW50cnldID0gQXJyYXkuZnJvbSh0aGlzLmRpci5jb250ZW50cy5lbnRyaWVzKCkpW051bWJlcihjb29raWUgLSAybildOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG5ldyBEaXJlbnQoY29va2llICsgMW4sIG5hbWUsIGVudHJ5LnN0YXQoKS5maWxldHlwZSkgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9lcnIsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IGVudHJ5LnN0YXQoKSB9OwogIH0KICBwYXRoX2xvb2t1cChwYXRoX3N0ciwgZGlyZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoX3N0ciwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgaWYgKHJldCAhPSBFUlJOT19OT0VOVCkgewogICAgICAgIHJldHVybiB7IHJldCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfQ1JFQVQpID09IE9GTEFHU19DUkVBVCkgewogICAgICAgIGNvbnN0IHsgcmV0OiByZXQyLCBlbnRyeTogbmV3X2VudHJ5IH0gPSB0aGlzLmRpci5jcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZKTsKICAgICAgICBpZiAobmV3X2VudHJ5ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiB7IHJldDogcmV0MiwgZmRfb2JqOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGVudHJ5ID0gbmV3X2VudHJ5OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICB9IGVsc2UgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRVhDTCkgPT0gT0ZMQUdTX0VYQ0wpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIGVudHJ5LnBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncyk7CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gdGhpcy5wYXRoX29wZW4oMCwgcGF0aCwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIGNvbnN0IHNvdXJjZV9pc19kaXIgPSBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBjb25zdCB0YXJnZXRfaXNfZGlyID0gZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgaWYgKHNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIGlmIChhbGxvd19kaXIgJiYgZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHsKICAgICAgICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplID09IDApIHsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChzb3VyY2VfaXNfZGlyICYmICF0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgICAgfSBlbHNlIGlmICghc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgICB9IGVsc2UgaWYgKGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSkgewogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgfQogICAgfQogICAgaWYgKCFhbGxvd19kaXIgJiYgaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fUEVSTTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIGlub2RlKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3VubGluayhwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF91bmxpbmtfZmlsZShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHx8IGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICB9CiAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSAhPT0gMCkgewogICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICB9CiAgICBpZiAoIXBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpKSB7CiAgICAgIHJldHVybiBFUlJOT19OT0VOVDsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmRpci5zdGF0KCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBjb25zdHJ1Y3RvcihkaXIpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRpciA9IGRpcjsKICB9Cn07CnZhciBQcmVvcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBPcGVuRGlyZWN0b3J5IHsKICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgcHJlc3RhdDogUHJlc3RhdC5kaXIodGhpcy5wcmVzdGF0X25hbWUpIH07CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnRzKSB7CiAgICBzdXBlcihuZXcgRGlyZWN0b3J5KGNvbnRlbnRzKSk7CiAgICB0aGlzLnByZXN0YXRfbmFtZSA9IG5hbWU7CiAgfQp9Owp2YXIgRmlsZSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgaWYgKHRoaXMucmVhZG9ubHkgJiYgKGZzX3JpZ2h0c19iYXNlICYgQmlnSW50KFJJR0hUU19GRF9XUklURSkpID09IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19UUlVOQykgPT0gT0ZMQUdTX1RSVU5DKSB7CiAgICAgIGlmICh0aGlzLnJlYWRvbmx5KQogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KFtdKTsKICAgIH0KICAgIGNvbnN0IGZpbGUgPSBuZXcgT3BlbkZpbGUodGhpcyk7CiAgICBpZiAoZmRfZmxhZ3MgJiBGREZMQUdTX0FQUEVORCkKICAgICAgZmlsZS5mZF9zZWVrKDBuLCBXSEVOQ0VfRU5EKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZmRfb2JqOiBmaWxlIH07CiAgfQogIGdldCBzaXplKCkgewogICAgcmV0dXJuIEJpZ0ludCh0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgdGhpcy5zaXplKTsKICB9CiAgY29uc3RydWN0b3IoZGF0YSwgb3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgdGhpcy5yZWFkb25seSA9ICEhb3B0aW9ucz8ucmVhZG9ubHk7CiAgfQp9Owp2YXIgUGF0aCA9IGNsYXNzIFBhdGgyIHsKICBzdGF0aWMgZnJvbShwYXRoKSB7CiAgICBjb25zdCBzZWxmID0gbmV3IFBhdGgyKCk7CiAgICBzZWxmLmlzX2RpciA9IHBhdGguZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVENBUEFCTEUsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGlmIChwYXRoLmluY2x1ZGVzKCJcMCIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGguc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aCkgewogICAgbGV0IGVudHJ5ID0gdGhpczsKICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgucGFydHMpIHsKICAgICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgICAgY29uc3QgY2hpbGQgPSBlbnRyeS5jb250ZW50cy5nZXQoY29tcG9uZW50KTsKICAgICAgaWYgKGNoaWxkICE9PSB2b2lkIDApIHsKICAgICAgICBlbnRyeSA9IGNoaWxkOwogICAgICB9IGVsc2UgewogICAgICAgIGRlYnVnLmxvZyhjb21wb25lbnQpOwogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBhbGxvd191bmRlZmluZWQpIHsKICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5wYXJ0cy5wb3AoKTsKICAgIGlmIChmaWxlbmFtZSA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldDogZW50cnlfcmV0LCBlbnRyeTogcGFyZW50X2VudHJ5IH0gPSB0aGlzLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfTsKICB9CiAgY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCBpc19kaXIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGRlYnVnLmxvZygiY3JlYXRlIiwgcGF0aCk7CiAgICBsZXQgbmV3X2NoaWxkOwogICAgaWYgKCFpc19kaXIpIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IEZpbGUobmV3IEFycmF5QnVmZmVyKDApKTsKICAgIH0gZWxzZSB7CiAgICAgIG5ld19jaGlsZCA9IG5ldyBEaXJlY3RvcnkoLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSk7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBuZXdfY2hpbGQpOwogICAgZW50cnkgPSBuZXdfY2hpbGQ7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGNvbnN0cnVjdG9yKGNvbnRlbnRzKSB7CiAgICBzdXBlcigpOwogICAgaWYgKGNvbnRlbnRzIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgdGhpcy5jb250ZW50cyA9IG5ldyBNYXAoY29udGVudHMpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5jb250ZW50cyA9IGNvbnRlbnRzOwogICAgfQogIH0KfTsKdmFyIENvbnNvbGVTdGRvdXQgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmaWxlc3RhdCA9IG5ldyBGaWxlc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCBCaWdJbnQoMCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdCB9OwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgY29uc3QgZmRzdGF0ID0gbmV3IEZkc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCAwKTsKICAgIGZkc3RhdC5mc19yaWdodHNfYmFzZSA9IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgdGhpcy53cml0ZShkYXRhKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBzdGF0aWMgbGluZUJ1ZmZlcmVkKHdyaXRlKSB7CiAgICBjb25zdCBkZWMgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICBsZXQgbGluZV9idWYgPSAiIjsKICAgIHJldHVybiBuZXcgQ29uc29sZVN0ZG91dCgoYnVmZmVyKSA9PiB7CiAgICAgIGxpbmVfYnVmICs9IGRlYy5kZWNvZGUoYnVmZmVyLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgICAgY29uc3QgbGluZXMgPSBsaW5lX2J1Zi5zcGxpdCgiXG4iKTsKICAgICAgZm9yIChjb25zdCBbaSwgbGluZV0gb2YgbGluZXMuZW50cmllcygpKSB7CiAgICAgICAgaWYgKGkgPCBsaW5lcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICB3cml0ZShsaW5lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGluZV9idWYgPSBsaW5lOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfQogIGNvbnN0cnVjdG9yKHdyaXRlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy53cml0ZSA9IHdyaXRlOwogIH0KfTsKCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL2luZGV4LmpzCmZ1bmN0aW9uIHBhcnNlSW1wb3J0cyhtb2R1bGVCeXRlcykgewogIGlmIChtb2R1bGVCeXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsKICB9IGVsc2UgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMpOwogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMuYnVmZmVyKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCJBcmd1bWVudCBtdXN0IGJlIGEgYnVmZmVyIHNvdXJjZSwgbGlrZSBVaW50OEFycmF5IG9yIEFycmF5QnVmZmVyIik7CiAgfQogIGNvbnN0IHBhcnNlU3RhdGUgPSBuZXcgUGFyc2VTdGF0ZShtb2R1bGVCeXRlcyk7CiAgcGFyc2VNYWdpY051bWJlcihwYXJzZVN0YXRlKTsKICBwYXJzZVZlcnNpb24ocGFyc2VTdGF0ZSk7CiAgY29uc3QgdHlwZXMgPSBbXTsKICBjb25zdCBpbXBvcnRzID0gW107CiAgd2hpbGUgKHBhcnNlU3RhdGUuaGFzTW9yZUJ5dGVzKCkpIHsKICAgIGNvbnN0IHNlY3Rpb25JZCA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICAgIGNvbnN0IHNlY3Rpb25TaXplID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgIHN3aXRjaCAoc2VjdGlvbklkKSB7CiAgICAgIGNhc2UgMTogewogICAgICAgIGNvbnN0IHR5cGVDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eXBlQ291bnQ7IGkrKykgewogICAgICAgICAgdHlwZXMucHVzaChwYXJzZUZ1bmN0aW9uVHlwZShwYXJzZVN0YXRlKSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgMjogewogICAgICAgIGNvbnN0IGltcG9ydENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGltcG9ydENvdW50OyBpKyspIHsKICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobW9kdWxlQnl0ZXMpOwogIGNvbnN0IGltcG9ydHMgPSBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpOwogIGNvbnN0IG1lbW9yeUltcG9ydCA9IGltcG9ydHNbMF07CiAgcmV0dXJuIHR5cGVvZiBtZW1vcnlJbXBvcnQudHlwZSA9PT0gIm9iamVjdCI7Cn0pKCk7CmZ1bmN0aW9uIHBvbHlmaWxsKFdlYkFzc2VtYmx5MykgewogIGlmIChoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0KSB7CiAgICByZXR1cm4gV2ViQXNzZW1ibHkzOwogIH0KICBjb25zdCBuZXdXZWJBc3NlbWJseSA9IHt9OwogIGZvciAoY29uc3Qga2V5IGluIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKFdlYkFzc2VtYmx5MykpIHsKICAgIG5ld1dlYkFzc2VtYmx5W2tleV0gPSBXZWJBc3NlbWJseTNba2V5XTsKICB9CiAgY29uc3QgcG9seWZpbGxlZEltcG9ydHNTeW1ib2wgPSBTeW1ib2woInBvbHlmaWxsZWRJbXBvcnRzU3ltYm9sIik7CiAgY29uc3QgYXNzaWduSW1wb3J0cyA9IChtb2R1bGUsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdID0gcGFyc2VJbXBvcnRzKHNvdXJjZUJ5dGVzKTsKICB9OwogIGNvbnN0IG5ld01vZHVsZSA9IG5ld1dlYkFzc2VtYmx5Lk1vZHVsZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICBjb25zdCBtb2R1bGUgPSBuZXcgV2ViQXNzZW1ibHkzLk1vZHVsZShieXRlcyk7CiAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZSwgbmV3TW9kdWxlLnByb3RvdHlwZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG5ld01vZHVsZS5wcm90b3R5cGUsIFdlYkFzc2VtYmx5My5Nb2R1bGUucHJvdG90eXBlKTsKICBuZXdXZWJBc3NlbWJseS5jb21waWxlID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBzb3VyY2UpOwogICAgcmV0dXJuIG1vZHVsZTsKICB9OwogIGlmIChXZWJBc3NlbWJseTMuY29tcGlsZVN0cmVhbWluZykgewogICAgbmV3V2ViQXNzZW1ibHkuY29tcGlsZVN0cmVhbWluZyA9IGFzeW5jIChzb3VyY2UpID0+IHsKICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzb3VyY2U7CiAgICAgIGNvbnN0IGNsb25lID0gcmVzcG9uc2UuY2xvbmUoKTsKICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgbmV3IFVpbnQ4QXJyYXkoYXdhaXQgY2xvbmUuYXJyYXlCdWZmZXIoKSkpOwogICAgICByZXR1cm4gbW9kdWxlOwogICAgfTsKICB9CiAgbmV3TW9kdWxlLmltcG9ydHMgPSAobW9kdWxlKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXTsKICAgIGlmICghcGFyc2VkSW1wb3J0cykgewogICAgICByZXR1cm4gV2ViQXNzZW1ibHkzLk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgICB9CiAgICByZXR1cm4gcGFyc2VkSW1wb3J0czsKICB9OwogIHJldHVybiBuZXdXZWJBc3NlbWJseTsKfQoKLy8gZW50cnlwb2ludC9jb21tb24udHMKdmFyIFdlYkFzc2VtYmx5MiA9IHBvbHlmaWxsKGdsb2JhbFRoaXMuV2ViQXNzZW1ibHkpOwp2YXIgTGluZURlY29kZXIgPSBjbGFzcyB7CiAgY29uc3RydWN0b3Iob25MaW5lKSB7CiAgICB0aGlzLmRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICB0aGlzLmJ1ZmZlciA9ICIiOwogICAgdGhpcy5vbkxpbmUgPSBvbkxpbmU7CiAgfQogIGRlY29kZXI7CiAgYnVmZmVyOwogIG9uTGluZTsKICBzZW5kKGNodW5rKSB7CiAgICB0aGlzLmJ1ZmZlciArPSB0aGlzLmRlY29kZXIuZGVjb2RlKGNodW5rLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgIGNvbnN0IGxpbmVzID0gdGhpcy5idWZmZXIuc3BsaXQoIlxuIik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykgewogICAgICB0aGlzLm9uTGluZShsaW5lc1tpXSk7CiAgICB9CiAgICB0aGlzLmJ1ZmZlciA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdOwogIH0KfTsKdmFyIFdhc21SdW5uZXIgPSAocmF3T3B0aW9ucywgU3dpZnRSdW50aW1lKSA9PiB7CiAgY29uc3Qgb3B0aW9ucyA9IGRlZmF1bHRSdW5uZXJPcHRpb25zKHJhd09wdGlvbnMpOwogIGxldCBzd2lmdDsKICBpZiAoU3dpZnRSdW50aW1lKSB7CiAgICBzd2lmdCA9IG5ldyBTd2lmdFJ1bnRpbWUoKTsKICB9CiAgbGV0IHN0ZG91dExpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRvdXRMaW5lICE9IG51bGwpIHsKICAgIHN0ZG91dExpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZG91dExpbmUpOwogIH0KICBjb25zdCBzdGRvdXQgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRvdXQ/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRvdXRMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBsZXQgc3RkZXJyTGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZGVyckxpbmUgIT0gbnVsbCkgewogICAgc3RkZXJyTGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3RkZXJyTGluZSk7CiAgfQogIGNvbnN0IHN0ZGVyciA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZGVycj8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZGVyckxpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGNvbnN0IGFyZ3MgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzLCBlbnZzLCBmZHMsIHsKICAgIGRlYnVnOiBmYWxzZQogIH0pOwogIGNvbnN0IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QgPSAoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QgPSB7CiAgICAgIHdhc2lfc25hcHNob3RfcHJldmlldzE6IHdhc2kud2FzaUltcG9ydAogICAgfTsKICAgIGlmIChzd2lmdCkgewogICAgICBpbXBvcnRPYmplY3QuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgaWYgKCFpbXBvcnRPYmplY3RbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdFttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgX2ltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Mi5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpKSB7CiAgICAgIGNvbnN0IGltcG9ydEVudHJ5ID0gX2ltcG9ydEVudHJ5OwogICAgICBpZiAoIWltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0gPSB7fTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0gPSAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEltcG9ydGVkIGZ1bmN0aW9uICR7aW1wb3J0RW50cnkubW9kdWxlfS4ke2ltcG9ydEVudHJ5Lm5hbWV9IG5vdCBpbXBsZW1lbnRlZGApOwogICAgICAgIH07CiAgICAgIH0gZWxzZSBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAibWVtb3J5IiAmJiBpbXBvcnRFbnRyeS5tb2R1bGUgPT0gImVudiIgJiYgaW1wb3J0RW50cnkubmFtZSA9PSAibWVtb3J5IikgewogICAgICAgIGNvbnN0IHR5cGUgPSBpbXBvcnRFbnRyeS50eXBlOwogICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB7CiAgICAgICAgICBpbml0aWFsOiB0eXBlLm1pbmltdW0sCiAgICAgICAgICBtYXhpbXVtOiB0eXBlLm1heGltdW0sCiAgICAgICAgICBzaGFyZWQ6IHR5cGUuc2hhcmVkCiAgICAgICAgfTsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9IG5ldyBXZWJBc3NlbWJseTIuTWVtb3J5KGRlc2NyaXB0b3IpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0OwogIH07CiAgcmV0dXJuIHsKICAgIGFzeW5jIHJ1bih3YXNtQnl0ZXMsIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgaWYgKCFleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgZXh0cmFXYXNtSW1wb3J0cyA9IHt9OwogICAgICB9CiAgICAgIGV4dHJhV2FzbUltcG9ydHMuX19zdGFja19zYW5pdGl6ZXIgPSB7CiAgICAgICAgcmVwb3J0X3N0YWNrX292ZXJmbG93OiAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkRldGVjdGVkIHN0YWNrIGJ1ZmZlciBvdmVyZmxvdy4iKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIGNvbnN0IG1vZHVsZSA9IGF3YWl0IFdlYkFzc2VtYmx5Mi5jb21waWxlKHdhc21CeXRlcyk7CiAgICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgbW9kdWxlKTsKICAgICAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBXZWJBc3NlbWJseTIuaW5zdGFudGlhdGUobW9kdWxlLCBpbXBvcnRPYmplY3QpOwogICAgICBpZiAoc3dpZnQgJiYgaW5zdGFuY2UuZXhwb3J0cy5zd2pzX2xpYnJhcnlfdmVyc2lvbikgewogICAgICAgIHN3aWZ0LnNldEluc3RhbmNlKGluc3RhbmNlKTsKICAgICAgfQogICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5zdGFydChpbnN0YW5jZSk7CiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUgPT0gImZ1bmN0aW9uIikgewogICAgICAgIHdhc2kuaW5pdGlhbGl6ZShpbnN0YW5jZSk7CiAgICAgICAgaWYgKHN3aWZ0ICYmIHN3aWZ0Lm1haW4pIHsKICAgICAgICAgIHN3aWZ0Lm1haW4oKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLm1haW4gPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5tYWluKCk7CiAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2KDAsIDApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH07Cn07CnZhciBkZWZhdWx0UnVubmVyT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7CiAgaWYgKG9wdGlvbnMuYXJncyA9PSBudWxsKSB7CiAgICBvcHRpb25zLmFyZ3MgPSBbIm1haW4ud2FzbSJdOwogIH0KICByZXR1cm4gb3B0aW9uczsKfTsKCi8vIGVudHJ5cG9pbnQvdGVzdC50cwp2YXIgc29ja2V0ID0gbmV3IHJlY29ubmVjdGluZ193ZWJzb2NrZXRfbWpzX2RlZmF1bHQoYHdzOi8vJHtsb2NhdGlvbi5ob3N0fS93YXRjaGVyYCk7CnNvY2tldC5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwgKG1lc3NhZ2UpID0+IHsKICBpZiAobWVzc2FnZS5kYXRhID09PSAicmVsb2FkIikgewogICAgbG9jYXRpb24ucmVsb2FkKCk7CiAgfQp9KTsKdmFyIHN0YXJ0V2FzaVRhc2sgPSBhc3luYyAoKSA9PiB7CiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgiL21haW4ud2FzbSIpOwogIGNvbnN0IHJlc3BvbnNlQXJyYXlCdWZmZXIgPSBhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpOwogIGxldCBydW50aW1lQ29uc3RydWN0b3IgPSB2b2lkIDA7CiAgdHJ5IHsKICAgIGNvbnN0IHsgU3dpZnRSdW50aW1lIH0gPSBhd2FpdCBpbXBvcnQoCiAgICAgIC8vIEB0cy1pZ25vcmUKICAgICAgIi4vSmF2YVNjcmlwdEtpdF9KYXZhU2NyaXB0S2l0LnJlc291cmNlcy9SdW50aW1lL2luZGV4Lm1qcyIKICAgICk7CiAgICBydW50aW1lQ29uc3RydWN0b3IgPSBTd2lmdFJ1bnRpbWU7CiAgfSBjYXRjaCB7CiAgICBjb25zb2xlLmxvZygiSmF2YVNjcmlwdEtpdCBtb2R1bGUgbm90IGF2YWlsYWJsZSwgcnVubmluZyB3aXRob3V0IEphdmFTY3JpcHRLaXQgcnVudGltZS4iKTsKICB9CiAgY29uc3QgY29uZmlnID0gYXdhaXQgZmV0Y2goIi9wcm9jZXNzLWluZm8uanNvbiIpLnRoZW4oKHJlc3BvbnNlMikgPT4gcmVzcG9uc2UyLmpzb24oKSk7CiAgbGV0IHRlc3RSdW5PdXRwdXQgPSAiIjsKICBjb25zdCB3YXNtUnVubmVyID0gV2FzbVJ1bm5lcih7CiAgICBlbnY6IGNvbmZpZy5lbnYsCiAgICBvblN0ZG91dExpbmU6IChsaW5lKSA9PiB7CiAgICAgIGNvbnNvbGUubG9nKGxpbmUpOwogICAgICB0ZXN0UnVuT3V0cHV0ICs9IGxpbmUgKyAiXG4iOwogICAgfSwKICAgIG9uU3RkZXJyTGluZTogKGxpbmUpID0+IHsKICAgICAgY29uc29sZS5lcnJvcihsaW5lKTsKICAgIH0KICB9LCBydW50aW1lQ29uc3RydWN0b3IpOwogIGNvbnN0IHdhc21CeXRlcyA9IG5ldyBVaW50OEFycmF5KHJlc3BvbnNlQXJyYXlCdWZmZXIpLmJ1ZmZlcjsKICBjb25zdCBoYW5kbGVFeGl0T3JFcnJvciA9IChlcnJvcikgPT4gewogICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV0FTSVByb2NFeGl0KSB7CiAgICAgIHNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KHsga2luZDogInRlc3RSdW5PdXRwdXQiLCB0ZXN0UnVuT3V0cHV0IH0pKTsKICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDApIHsKICAgICAgICBzb2NrZXQuc2VuZChKU09OLnN0cmluZ2lmeSh7IGtpbmQ6ICJ0ZXN0UGFzc2VkIiB9KSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaGFuZGxlRXJyb3IoZXJyb3IpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBoYW5kbGVFcnJvcihlcnJvcik7CiAgICB9CiAgICBjb25zdCBkaXZFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgicCIpOwogICAgZGl2RWxlbWVudC5pbm5lckhUTUwgPSAiVGVzdCBydW4gZmluaXNoZWQuIENoZWNrIHRoZSBvdXRwdXQgb2YgPGNvZGU+Y2FydG9uIHRlc3Q8L2NvZGU+IGZvciBkZXRhaWxzLiI7CiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRpdkVsZW1lbnQpOwogIH07CiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoInVuaGFuZGxlZHJlamVjdGlvbiIsIChldmVudCkgPT4gewogICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgIGNvbnN0IGVycm9yID0gZXZlbnQucmVhc29uOwogICAgaGFuZGxlRXhpdE9yRXJyb3IoZXJyb3IpOwogIH0pOwogIHRyeSB7CiAgICBhd2FpdCB3YXNtUnVubmVyLnJ1bih3YXNtQnl0ZXMpOwogIH0gY2F0Y2ggKGVycm9yKSB7CiAgICBoYW5kbGVFeGl0T3JFcnJvcihlcnJvcik7CiAgICByZXR1cm47CiAgfQp9OwpmdW5jdGlvbiBoYW5kbGVFcnJvcihlKSB7CiAgY29uc29sZS5lcnJvcihlKTsKICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yKSB7CiAgICBjb25zdCBzdGFjayA9IGUuc3RhY2s7CiAgICBpZiAoc3RhY2sgIT0gbnVsbCkgewogICAgICBzb2NrZXQuc2VuZChKU09OLnN0cmluZ2lmeSh7CiAgICAgICAga2luZDogInN0YWNrVHJhY2UiLAogICAgICAgIHN0YWNrVHJhY2U6IHN0YWNrCiAgICAgIH0pKTsKICAgIH0KICB9CiAgc29ja2V0LnNlbmQoSlNPTi5zdHJpbmdpZnkoewogICAga2luZDogImVycm9yUmVwb3J0IiwKICAgIGVycm9yUmVwb3J0OiBlLnRvU3RyaW5nKCkKICB9KSk7Cn0KYXN5bmMgZnVuY3Rpb24gbWFpbigpIHsKICB0cnkgewogICAgYXdhaXQgc3RhcnRXYXNpVGFzaygpOwogIH0gY2F0Y2ggKGUpIHsKICAgIGhhbmRsZUVycm9yKGUpOwogIH0KfQptYWluKCk7Ci8qIQogKiBSZWNvbm5lY3RpbmcgV2ViU29ja2V0CiAqIGJ5IFBlZHJvIExhZGFyaWEgPHBlZHJvLmxhZGFyaWFAZ21haWwuY29tPgogKiBodHRwczovL2dpdGh1Yi5jb20vcGxhZGFyaWEvcmVjb25uZWN0aW5nLXdlYnNvY2tldAogKiBMaWNlbnNlIE1JVAogKi8KLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLgpMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsgeW91IG1heSBub3QgdXNlCnRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlCkxpY2Vuc2UgYXQgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCgpUSElTIENPREUgSVMgUFJPVklERUQgT04gQU4gKkFTIElTKiBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZCktJTkQsIEVJVEhFUiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBXSVRIT1VUIExJTUlUQVRJT04gQU5ZIElNUExJRUQKV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIFRJVExFLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwKTUVSQ0hBTlRBQkxJVFkgT1IgTk9OLUlORlJJTkdFTUVOVC4KClNlZSB0aGUgQXBhY2hlIFZlcnNpb24gMi4wIExpY2Vuc2UgZm9yIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucwphbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCg==")! - public static let testNode: Data = Data(base64Encoded: "dmFyIF9fY3JlYXRlID0gT2JqZWN0LmNyZWF0ZTsKdmFyIF9fZGVmUHJvcCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTsKdmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOwp2YXIgX19nZXRPd25Qcm9wTmFtZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lczsKdmFyIF9fZ2V0UHJvdG9PZiA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjsKdmFyIF9faGFzT3duUHJvcCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7CnZhciBfX2NvcHlQcm9wcyA9ICh0bywgZnJvbSwgZXhjZXB0LCBkZXNjKSA9PiB7CiAgaWYgKGZyb20gJiYgdHlwZW9mIGZyb20gPT09ICJvYmplY3QiIHx8IHR5cGVvZiBmcm9tID09PSAiZnVuY3Rpb24iKSB7CiAgICBmb3IgKGxldCBrZXkgb2YgX19nZXRPd25Qcm9wTmFtZXMoZnJvbSkpCiAgICAgIGlmICghX19oYXNPd25Qcm9wLmNhbGwodG8sIGtleSkgJiYga2V5ICE9PSBleGNlcHQpCiAgICAgICAgX19kZWZQcm9wKHRvLCBrZXksIHsgZ2V0OiAoKSA9PiBmcm9tW2tleV0sIGVudW1lcmFibGU6ICEoZGVzYyA9IF9fZ2V0T3duUHJvcERlc2MoZnJvbSwga2V5KSkgfHwgZGVzYy5lbnVtZXJhYmxlIH0pOwogIH0KICByZXR1cm4gdG87Cn07CnZhciBfX3RvRVNNID0gKG1vZCwgaXNOb2RlTW9kZSwgdGFyZ2V0KSA9PiAodGFyZ2V0ID0gbW9kICE9IG51bGwgPyBfX2NyZWF0ZShfX2dldFByb3RvT2YobW9kKSkgOiB7fSwgX19jb3B5UHJvcHMoaXNOb2RlTW9kZSB8fCAhbW9kIHx8ICFtb2QuX19lc01vZHVsZSA/IF9fZGVmUHJvcCh0YXJnZXQsICJkZWZhdWx0IiwgeyB2YWx1ZTogbW9kLCBlbnVtZXJhYmxlOiB0cnVlIH0pIDogdGFyZ2V0LCBtb2QpKTsKCi8vIGVudHJ5cG9pbnQvdGVzdE5vZGUudHMKdmFyIGltcG9ydF9wcm9taXNlcyA9IF9fdG9FU00ocmVxdWlyZSgiZnMvcHJvbWlzZXMiKSk7CnZhciBpbXBvcnRfcGF0aCA9IF9fdG9FU00ocmVxdWlyZSgicGF0aCIpKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJnczIsIGVudiwgZmRzLCBvcHRpb25zID0ge30pIHsKICAgIHRoaXMuYXJncyA9IFtdOwogICAgdGhpcy5lbnYgPSBbXTsKICAgIHRoaXMuZmRzID0gW107CiAgICBkZWJ1Zy5lbmFibGUob3B0aW9ucy5kZWJ1Zyk7CiAgICB0aGlzLmFyZ3MgPSBhcmdzMjsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfZ2V0KGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aDIpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X3NldF90aW1lcyhmbGFncywgcGF0aDIsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgyKTsKICAgICAgICBjb25zdCB7IHJldCwgZmRfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoMiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aDIpOwogICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9yZWFkbGluayhwYXRoMik7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoMiA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZW5hbWUoZmQsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgbGV0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3VubGluayhvbGRfcGF0aCk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXQgPSBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKTsKICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgIGlmIChzZWxmLmZkc1tmZF0ucGF0aF9saW5rKG9sZF9wYXRoLCBpbm9kZV9vYmosIHRydWUpICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgdGhyb3cgInBhdGhfbGluayBzaG91bGQgYWx3YXlzIHJldHVybiBzdWNjZXNzIHdoZW4gcmVsaW5raW5nIGFuIGlub2RlIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHBsYWNlIjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9zeW1saW5rKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBmZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3VubGlua19maWxlKGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgyLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoMiwgaW5vZGUsIGFsbG93X2RpcikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF91bmxpbmsocGF0aDIpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aDIsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aDIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogIH0KICBwYXRoX3JlYWRsaW5rKHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KfTsKdmFyIElub2RlID0gY2xhc3Mgewp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mc19tZW0uanMKdmFyIE9wZW5GaWxlID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IG9mZnNldCArIGxlbikgewogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgbGVuKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgMCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gc2l6ZSkgewogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KHRoaXMuZmlsZS5kYXRhLmJ1ZmZlci5zbGljZSgwLCBOdW1iZXIoc2l6ZSkpKTsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHNpemUpKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKHRoaXMuZmlsZV9wb3MpLCBOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChzaXplKSkpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoc2xpY2UubGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcihvZmZzZXQpLCBOdW1iZXIob2Zmc2V0ICsgQmlnSW50KHNpemUpKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIGxldCBjYWxjdWxhdGVkX29mZnNldDsKICAgIHN3aXRjaCAod2hlbmNlKSB7CiAgICAgIGNhc2UgV0hFTkNFX1NFVDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfQ1VSOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gdGhpcy5maWxlX3BvcyArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfRU5EOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gQmlnSW50KHRoaXMuZmlsZS5kYXRhLmJ5dGVMZW5ndGgpICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIGlmIChjYWxjdWxhdGVkX29mZnNldCA8IDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgdGhpcy5maWxlX3BvcyA9IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmICh0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcih0aGlzLmZpbGVfcG9zKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmIChvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIob2Zmc2V0KSk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5maWxlLnN0YXQoKSB9OwogIH0KICBjb25zdHJ1Y3RvcihmaWxlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5maWxlX3BvcyA9IDBuOwogICAgdGhpcy5maWxlID0gZmlsZTsKICB9Cn07CnZhciBPcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgIGRlYnVnLmxvZygicmVhZGRpcl9zaW5nbGUiLCBjb29raWUpOwogICAgICBkZWJ1Zy5sb2coY29va2llLCB0aGlzLmRpci5jb250ZW50cy5rZXlzKCkpOwogICAgfQogICAgaWYgKGNvb2tpZSA9PSAwbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgxbiwgIi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9IGVsc2UgaWYgKGNvb2tpZSA9PSAxbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgybiwgIi4uIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfQogICAgaWYgKGNvb2tpZSA+PSBCaWdJbnQodGhpcy5kaXIuY29udGVudHMuc2l6ZSkgKyAybikgewogICAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbnVsbCB9OwogICAgfQogICAgY29uc3QgW25hbWUsIGVudHJ5XSA9IEFycmF5LmZyb20odGhpcy5kaXIuY29udGVudHMuZW50cmllcygpKVtOdW1iZXIoY29va2llIC0gMm4pXTsKICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBuZXcgRGlyZW50KGNvb2tpZSArIDFuLCBuYW1lLCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUpIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfZXJyLCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiBlbnRyeS5zdGF0KCkgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aF9zdHIsIGRpcmZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aF9zdHIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIGlmIChyZXQgIT0gRVJSTk9fTk9FTlQpIHsKICAgICAgICByZXR1cm4geyByZXQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0NSRUFUKSA9PSBPRkxBR1NfQ1JFQVQpIHsKICAgICAgICBjb25zdCB7IHJldDogcmV0MiwgZW50cnk6IG5ld19lbnRyeSB9ID0gdGhpcy5kaXIuY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCAob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSk7CiAgICAgICAgaWYgKG5ld19lbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4geyByZXQ6IHJldDIsIGZkX29iajogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBlbnRyeSA9IG5ld19lbnRyeTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgfSBlbHNlIGlmICgob2ZsYWdzICYgT0ZMQUdTX0VYQ0wpID09IE9GTEFHU19FWENMKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiBlbnRyeS5wYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpOwogIH0KICBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoMiwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoMi5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aDIsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICBjb25zdCBzb3VyY2VfaXNfZGlyID0gaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgY29uc3QgdGFyZ2V0X2lzX2RpciA9IGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGlmIChzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICBpZiAoYWxsb3dfZGlyICYmIGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB7CiAgICAgICAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSA9PSAwKSB7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoc291cmNlX2lzX2RpciAmJiAhdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICAgIH0gZWxzZSBpZiAoIXNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgICAgfSBlbHNlIGlmIChpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUpIHsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgIH0KICAgIH0KICAgIGlmICghYWxsb3dfZGlyICYmIGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX1BFUk07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBpbm9kZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF91bmxpbmsocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmICghKGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB8fCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgfQogICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgIT09IDApIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgfQogICAgaWYgKCFwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKSkgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5kaXIuc3RhdCgpIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgY29uc3RydWN0b3IoZGlyKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kaXIgPSBkaXI7CiAgfQp9Owp2YXIgUHJlb3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgT3BlbkRpcmVjdG9yeSB7CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIHByZXN0YXQ6IFByZXN0YXQuZGlyKHRoaXMucHJlc3RhdF9uYW1lKSB9OwogIH0KICBjb25zdHJ1Y3RvcihuYW1lLCBjb250ZW50cykgewogICAgc3VwZXIobmV3IERpcmVjdG9yeShjb250ZW50cykpOwogICAgdGhpcy5wcmVzdGF0X25hbWUgPSBuYW1lOwogIH0KfTsKdmFyIEZpbGUgPSBjbGFzcyBleHRlbmRzIElub2RlIHsKICBwYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpIHsKICAgIGlmICh0aGlzLnJlYWRvbmx5ICYmIChmc19yaWdodHNfYmFzZSAmIEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSA9PSBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfVFJVTkMpID09IE9GTEFHU19UUlVOQykgewogICAgICBpZiAodGhpcy5yZWFkb25seSkKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShbXSk7CiAgICB9CiAgICBjb25zdCBmaWxlID0gbmV3IE9wZW5GaWxlKHRoaXMpOwogICAgaWYgKGZkX2ZsYWdzICYgRkRGTEFHU19BUFBFTkQpCiAgICAgIGZpbGUuZmRfc2VlaygwbiwgV0hFTkNFX0VORCk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogZmlsZSB9OwogIH0KICBnZXQgc2l6ZSgpIHsKICAgIHJldHVybiBCaWdJbnQodGhpcy5kYXRhLmJ5dGVMZW5ndGgpOwogIH0KICBzdGF0KCkgewogICAgcmV0dXJuIG5ldyBGaWxlc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIHRoaXMuc2l6ZSk7CiAgfQogIGNvbnN0cnVjdG9yKGRhdGEsIG9wdGlvbnMpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShkYXRhKTsKICAgIHRoaXMucmVhZG9ubHkgPSAhIW9wdGlvbnM/LnJlYWRvbmx5OwogIH0KfTsKdmFyIFBhdGggPSBjbGFzcyBQYXRoMiB7CiAgc3RhdGljIGZyb20ocGF0aDIpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aDIuZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoMi5zdGFydHNXaXRoKCIvIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICB9CiAgICBpZiAocGF0aDIuaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aDIuc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aDIpIHsKICAgIGxldCBlbnRyeSA9IHRoaXM7CiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiBwYXRoMi5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgYWxsb3dfdW5kZWZpbmVkKSB7CiAgICBjb25zdCBmaWxlbmFtZSA9IHBhdGgyLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH07CiAgfQogIGNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgaXNfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBkZWJ1Zy5sb2coImNyZWF0ZSIsIHBhdGgyKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvaW5kZXguanMKZnVuY3Rpb24gcGFyc2VJbXBvcnRzKG1vZHVsZUJ5dGVzKSB7CiAgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcyk7CiAgfSBlbHNlIGlmIChtb2R1bGVCeXRlcy5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcy5idWZmZXIpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoIkFyZ3VtZW50IG11c3QgYmUgYSBidWZmZXIgc291cmNlLCBsaWtlIFVpbnQ4QXJyYXkgb3IgQXJyYXlCdWZmZXIiKTsKICB9CiAgY29uc3QgcGFyc2VTdGF0ZSA9IG5ldyBQYXJzZVN0YXRlKG1vZHVsZUJ5dGVzKTsKICBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpOwogIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKTsKICBjb25zdCB0eXBlcyA9IFtdOwogIGNvbnN0IGltcG9ydHMgPSBbXTsKICB3aGlsZSAocGFyc2VTdGF0ZS5oYXNNb3JlQnl0ZXMoKSkgewogICAgY29uc3Qgc2VjdGlvbklkID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgY29uc3Qgc2VjdGlvblNpemUgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgc3dpdGNoIChzZWN0aW9uSWQpIHsKICAgICAgY2FzZSAxOiB7CiAgICAgICAgY29uc3QgdHlwZUNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVDb3VudDsgaSsrKSB7CiAgICAgICAgICB0eXBlcy5wdXNoKHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAyOiB7CiAgICAgICAgY29uc3QgaW1wb3J0Q291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW1wb3J0Q291bnQ7IGkrKykgewogICAgICAgICAgY29uc3QgbW9kdWxlMiA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlOiBtb2R1bGUyLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGU6IG1vZHVsZTIsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlOiBtb2R1bGUyLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGU6IG1vZHVsZTIsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZTIgPSBuZXcgV2ViQXNzZW1ibHkuTW9kdWxlKG1vZHVsZUJ5dGVzKTsKICBjb25zdCBpbXBvcnRzID0gV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMobW9kdWxlMik7CiAgY29uc3QgbWVtb3J5SW1wb3J0ID0gaW1wb3J0c1swXTsKICByZXR1cm4gdHlwZW9mIG1lbW9yeUltcG9ydC50eXBlID09PSAib2JqZWN0IjsKfSkoKTsKZnVuY3Rpb24gcG9seWZpbGwoV2ViQXNzZW1ibHkzKSB7CiAgaWYgKGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQpIHsKICAgIHJldHVybiBXZWJBc3NlbWJseTM7CiAgfQogIGNvbnN0IG5ld1dlYkFzc2VtYmx5ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoV2ViQXNzZW1ibHkzKSkgewogICAgbmV3V2ViQXNzZW1ibHlba2V5XSA9IFdlYkFzc2VtYmx5M1trZXldOwogIH0KICBjb25zdCBwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbCA9IFN5bWJvbCgicG9seWZpbGxlZEltcG9ydHNTeW1ib2wiKTsKICBjb25zdCBhc3NpZ25JbXBvcnRzID0gKG1vZHVsZTIsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGUyW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXSA9IHBhcnNlSW1wb3J0cyhzb3VyY2VCeXRlcyk7CiAgfTsKICBjb25zdCBuZXdNb2R1bGUgPSBuZXdXZWJBc3NlbWJseS5Nb2R1bGUgPSBmdW5jdGlvbihieXRlcykgewogICAgY29uc3QgbW9kdWxlMiA9IG5ldyBXZWJBc3NlbWJseTMuTW9kdWxlKGJ5dGVzKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlMiwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZTIsIG5ld01vZHVsZS5wcm90b3R5cGUpOwogICAgcmV0dXJuIG1vZHVsZTI7CiAgfTsKICBPYmplY3Quc2V0UHJvdG90eXBlT2YobmV3TW9kdWxlLnByb3RvdHlwZSwgV2ViQXNzZW1ibHkzLk1vZHVsZS5wcm90b3R5cGUpOwogIG5ld1dlYkFzc2VtYmx5LmNvbXBpbGUgPSBhc3luYyAoc291cmNlKSA9PiB7CiAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlMiwgc291cmNlKTsKICAgIHJldHVybiBtb2R1bGUyOwogIH07CiAgaWYgKFdlYkFzc2VtYmx5My5jb21waWxlU3RyZWFtaW5nKSB7CiAgICBuZXdXZWJBc3NlbWJseS5jb21waWxlU3RyZWFtaW5nID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNvdXJjZTsKICAgICAgY29uc3QgY2xvbmUgPSByZXNwb25zZS5jbG9uZSgpOwogICAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZTIsIG5ldyBVaW50OEFycmF5KGF3YWl0IGNsb25lLmFycmF5QnVmZmVyKCkpKTsKICAgICAgcmV0dXJuIG1vZHVsZTI7CiAgICB9OwogIH0KICBuZXdNb2R1bGUuaW1wb3J0cyA9IChtb2R1bGUyKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlMltwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbF07CiAgICBpZiAoIXBhcnNlZEltcG9ydHMpIHsKICAgICAgcmV0dXJuIFdlYkFzc2VtYmx5My5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUyKTsKICAgIH0KICAgIHJldHVybiBwYXJzZWRJbXBvcnRzOwogIH07CiAgcmV0dXJuIG5ld1dlYkFzc2VtYmx5Owp9CgovLyBlbnRyeXBvaW50L2NvbW1vbi50cwp2YXIgV2ViQXNzZW1ibHkyID0gcG9seWZpbGwoZ2xvYmFsVGhpcy5XZWJBc3NlbWJseSk7CnZhciBMaW5lRGVjb2RlciA9IGNsYXNzIHsKICBjb25zdHJ1Y3RvcihvbkxpbmUpIHsKICAgIHRoaXMuZGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIHRoaXMuYnVmZmVyID0gIiI7CiAgICB0aGlzLm9uTGluZSA9IG9uTGluZTsKICB9CiAgZGVjb2RlcjsKICBidWZmZXI7CiAgb25MaW5lOwogIHNlbmQoY2h1bmspIHsKICAgIHRoaXMuYnVmZmVyICs9IHRoaXMuZGVjb2Rlci5kZWNvZGUoY2h1bmssIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgY29uc3QgbGluZXMgPSB0aGlzLmJ1ZmZlci5zcGxpdCgiXG4iKTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGluZXMubGVuZ3RoIC0gMTsgaSsrKSB7CiAgICAgIHRoaXMub25MaW5lKGxpbmVzW2ldKTsKICAgIH0KICAgIHRoaXMuYnVmZmVyID0gbGluZXNbbGluZXMubGVuZ3RoIC0gMV07CiAgfQp9Owp2YXIgV2FzbVJ1bm5lciA9IChyYXdPcHRpb25zLCBTd2lmdFJ1bnRpbWUpID0+IHsKICBjb25zdCBvcHRpb25zID0gZGVmYXVsdFJ1bm5lck9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0OwogIGlmIChTd2lmdFJ1bnRpbWUpIHsKICAgIHN3aWZ0ID0gbmV3IFN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJnczIgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzMiwgZW52cywgZmRzLCB7CiAgICBkZWJ1ZzogZmFsc2UKICB9KTsKICBjb25zdCBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0ID0gKGV4dHJhV2FzbUltcG9ydHMsIG1vZHVsZTIpID0+IHsKICAgIGNvbnN0IGltcG9ydE9iamVjdCA9IHsKICAgICAgd2FzaV9zbmFwc2hvdF9wcmV2aWV3MTogd2FzaS53YXNpSW1wb3J0CiAgICB9OwogICAgaWYgKHN3aWZ0KSB7CiAgICAgIGltcG9ydE9iamVjdC5qYXZhc2NyaXB0X2tpdCA9IHN3aWZ0Lndhc21JbXBvcnRzOwogICAgfQogICAgaWYgKGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgZm9yIChjb25zdCBtb2R1bGVOYW1lIGluIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgICBpZiAoIWltcG9ydE9iamVjdFttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdID0ge307CiAgICAgICAgfQogICAgICAgIGZvciAoY29uc3QgZW50cnkgaW4gZXh0cmFXYXNtSW1wb3J0c1ttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0W21vZHVsZU5hbWVdW2VudHJ5XSA9IGV4dHJhV2FzbUltcG9ydHNbbW9kdWxlTmFtZV1bZW50cnldOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgZm9yIChjb25zdCBfaW1wb3J0RW50cnkgb2YgV2ViQXNzZW1ibHkyLk1vZHVsZS5pbXBvcnRzKG1vZHVsZTIpKSB7CiAgICAgIGNvbnN0IGltcG9ydEVudHJ5ID0gX2ltcG9ydEVudHJ5OwogICAgICBpZiAoIWltcG9ydE9iamVjdFtpbXBvcnRFbnRyeS5tb2R1bGVdKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV0gPSB7fTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0W2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0gPSAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEltcG9ydGVkIGZ1bmN0aW9uICR7aW1wb3J0RW50cnkubW9kdWxlfS4ke2ltcG9ydEVudHJ5Lm5hbWV9IG5vdCBpbXBsZW1lbnRlZGApOwogICAgICAgIH07CiAgICAgIH0gZWxzZSBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAibWVtb3J5IiAmJiBpbXBvcnRFbnRyeS5tb2R1bGUgPT0gImVudiIgJiYgaW1wb3J0RW50cnkubmFtZSA9PSAibWVtb3J5IikgewogICAgICAgIGNvbnN0IHR5cGUgPSBpbXBvcnRFbnRyeS50eXBlOwogICAgICAgIGNvbnN0IGRlc2NyaXB0b3IgPSB7CiAgICAgICAgICBpbml0aWFsOiB0eXBlLm1pbmltdW0sCiAgICAgICAgICBtYXhpbXVtOiB0eXBlLm1heGltdW0sCiAgICAgICAgICBzaGFyZWQ6IHR5cGUuc2hhcmVkCiAgICAgICAgfTsKICAgICAgICBpbXBvcnRPYmplY3RbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9IG5ldyBXZWJBc3NlbWJseTIuTWVtb3J5KGRlc2NyaXB0b3IpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0OwogIH07CiAgcmV0dXJuIHsKICAgIGFzeW5jIHJ1bih3YXNtQnl0ZXMsIGV4dHJhV2FzbUltcG9ydHMpIHsKICAgICAgaWYgKCFleHRyYVdhc21JbXBvcnRzKSB7CiAgICAgICAgZXh0cmFXYXNtSW1wb3J0cyA9IHt9OwogICAgICB9CiAgICAgIGV4dHJhV2FzbUltcG9ydHMuX19zdGFja19zYW5pdGl6ZXIgPSB7CiAgICAgICAgcmVwb3J0X3N0YWNrX292ZXJmbG93OiAoKSA9PiB7CiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoIkRldGVjdGVkIHN0YWNrIGJ1ZmZlciBvdmVyZmxvdy4iKTsKICAgICAgICB9CiAgICAgIH07CiAgICAgIGNvbnN0IG1vZHVsZTIgPSBhd2FpdCBXZWJBc3NlbWJseTIuY29tcGlsZSh3YXNtQnl0ZXMpOwogICAgICBjb25zdCBpbXBvcnRPYmplY3QgPSBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0KGV4dHJhV2FzbUltcG9ydHMsIG1vZHVsZTIpOwogICAgICBjb25zdCBpbnN0YW5jZSA9IGF3YWl0IFdlYkFzc2VtYmx5Mi5pbnN0YW50aWF0ZShtb2R1bGUyLCBpbXBvcnRPYmplY3QpOwogICAgICBpZiAoc3dpZnQgJiYgaW5zdGFuY2UuZXhwb3J0cy5zd2pzX2xpYnJhcnlfdmVyc2lvbikgewogICAgICAgIHN3aWZ0LnNldEluc3RhbmNlKGluc3RhbmNlKTsKICAgICAgfQogICAgICBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgd2FzaS5zdGFydChpbnN0YW5jZSk7CiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUgPT0gImZ1bmN0aW9uIikgewogICAgICAgIHdhc2kuaW5pdGlhbGl6ZShpbnN0YW5jZSk7CiAgICAgICAgaWYgKHN3aWZ0ICYmIHN3aWZ0Lm1haW4pIHsKICAgICAgICAgIHN3aWZ0Lm1haW4oKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLm1haW4gPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5tYWluKCk7CiAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9fbWFpbl9hcmdjX2FyZ3YgPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2KDAsIDApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgfQogICAgfQogIH07Cn07CnZhciBkZWZhdWx0UnVubmVyT3B0aW9ucyA9IChvcHRpb25zKSA9PiB7CiAgaWYgKG9wdGlvbnMuYXJncyA9PSBudWxsKSB7CiAgICBvcHRpb25zLmFyZ3MgPSBbIm1haW4ud2FzbSJdOwogIH0KICByZXR1cm4gb3B0aW9uczsKfTsKCi8vIGVudHJ5cG9pbnQvdGVzdE5vZGUudHMKdmFyIGFyZ3MgPSBbLi4ucHJvY2Vzcy5hcmd2XTsKYXJncy5zaGlmdCgpOwphcmdzLnNoaWZ0KCk7CnZhciBbd2FzbUZpbGUsIC4uLnRlc3RBcmdzXSA9IGFyZ3M7CnRlc3RBcmdzLnVuc2hpZnQoaW1wb3J0X3BhdGguZGVmYXVsdC5iYXNlbmFtZSh3YXNtRmlsZSkpOwppZiAoIXdhc21GaWxlKSB7CiAgdGhyb3cgRXJyb3IoIk5vIFdBU00gdGVzdCBmaWxlIHNwZWNpZmllZCwgY2FuIG5vdCBydW4gdGVzdHMiKTsKfQp2YXIgc3RhcnRXYXNpVGFzayA9IGFzeW5jICgpID0+IHsKICBjb25zdCB3YXNtQnl0ZXMgPSBhd2FpdCBpbXBvcnRfcHJvbWlzZXMuZGVmYXVsdC5yZWFkRmlsZSh3YXNtRmlsZSk7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICAgIGdsb2JhbC5yZXF1aXJlID0gcmVxdWlyZTsKICB9IGNhdGNoIHsKICB9CiAgY29uc3QgZW52ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gcHJvY2Vzcy5lbnYpIHsKICAgIGNvbnN0IHZhbHVlID0gcHJvY2Vzcy5lbnZba2V5XTsKICAgIGlmICh2YWx1ZSkgewogICAgICBlbnZba2V5XSA9IHZhbHVlOwogICAgfQogIH0KICBjb25zdCB3YXNtUnVubmVyID0gV2FzbVJ1bm5lcih7CiAgICBhcmdzOiB0ZXN0QXJncywKICAgIGVudiwKICAgIG9uU3Rkb3V0TGluZTogKGxpbmUpID0+IHsKICAgICAgY29uc29sZS5sb2cobGluZSk7CiAgICB9LAogICAgb25TdGRlcnJMaW5lOiAobGluZSkgPT4gewogICAgICBjb25zb2xlLmVycm9yKGxpbmUpOwogICAgfQogIH0sIHJ1bnRpbWVDb25zdHJ1Y3Rvcik7CiAgbGV0IHByb2NFeGl0Q2FsbGVkID0gZmFsc2U7CiAgcHJvY2Vzcy5vbigiYmVmb3JlRXhpdCIsICgpID0+IHsKICAgIGlmICghcHJvY0V4aXRDYWxsZWQpIHsKICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZXN0IGhhcm5lc3MgcHJvY2VzcyBleGl0ZWQgYmVmb3JlIHRlc3QgcHJvY2Vzcy4KVGhpcyB1c3VhbGx5IG1lYW5zIHRoZXJlIGFyZSBzb21lIGRhbmdsaW5nIGNvbnRpbnVhdGlvbnMsIHdoaWNoIGFyZSBhd2FpdGVkIGJ1dCBuZXZlciByZXN1bWVkLmApOwogICAgfQogIH0pOwogIGF3YWl0IHdhc21SdW5uZXIucnVuKHdhc21CeXRlcywgewogICAgIndhc2lfc25hcHNob3RfcHJldmlldzEiOiB7CiAgICAgIHByb2NfZXhpdDogKGNvZGUpID0+IHsKICAgICAgICBwcm9jRXhpdENhbGxlZCA9IHRydWU7CiAgICAgICAgcHJvY2Vzcy5leGl0KGNvZGUpOwogICAgICB9CiAgICB9CiAgfSk7Cn07CnN0YXJ0V2FzaVRhc2soKS5jYXRjaCgoZSkgPT4gewogIHRocm93IGU7Cn0pOwo=")! + public static let dev: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL3JlY29ubmVjdGluZy13ZWJzb2NrZXQvZGlzdC9yZWNvbm5lY3Rpbmctd2Vic29ja2V0LW1qcy5qcwp2YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24oZDIsIGIyKSB7CiAgICBkMi5fX3Byb3RvX18gPSBiMjsKICB9IHx8IGZ1bmN0aW9uKGQyLCBiMikgewogICAgZm9yICh2YXIgcCBpbiBiMikKICAgICAgaWYgKGIyLmhhc093blByb3BlcnR5KHApKQogICAgICAgIGQyW3BdID0gYjJbcF07CiAgfTsKICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKfTsKZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzKGQsIGIpOwogIGZ1bmN0aW9uIF9fKCkgewogICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7CiAgfQogIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKfQpmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7CiAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSAiZnVuY3Rpb24iICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7CiAgaWYgKG0pCiAgICByZXR1cm4gbS5jYWxsKG8pOwogIHJldHVybiB7CiAgICBuZXh0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkKICAgICAgICBvID0gdm9pZCAwOwogICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07CiAgICB9CiAgfTsKfQpmdW5jdGlvbiBfX3JlYWQobywgbikgewogIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07CiAgaWYgKCFtKQogICAgcmV0dXJuIG87CiAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7CiAgdHJ5IHsKICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKQogICAgICBhci5wdXNoKHIudmFsdWUpOwogIH0gY2F0Y2ggKGVycm9yKSB7CiAgICBlID0geyBlcnJvciB9OwogIH0gZmluYWxseSB7CiAgICB0cnkgewogICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVsicmV0dXJuIl0pKQogICAgICAgIG0uY2FsbChpKTsKICAgIH0gZmluYWxseSB7CiAgICAgIGlmIChlKQogICAgICAgIHRocm93IGUuZXJyb3I7CiAgICB9CiAgfQogIHJldHVybiBhcjsKfQpmdW5jdGlvbiBfX3NwcmVhZCgpIHsKICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykKICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTsKICByZXR1cm4gYXI7Cn0KdmFyIEV2ZW50ID0gZnVuY3Rpb24oKSB7CiAgZnVuY3Rpb24gRXZlbnQyKHR5cGUsIHRhcmdldCkgewogICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CiAgICB0aGlzLnR5cGUgPSB0eXBlOwogIH0KICByZXR1cm4gRXZlbnQyOwp9KCk7CnZhciBFcnJvckV2ZW50ID0gZnVuY3Rpb24oX3N1cGVyKSB7CiAgX19leHRlbmRzKEVycm9yRXZlbnQyLCBfc3VwZXIpOwogIGZ1bmN0aW9uIEVycm9yRXZlbnQyKGVycm9yLCB0YXJnZXQpIHsKICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJlcnJvciIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLm1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlOwogICAgX3RoaXMuZXJyb3IgPSBlcnJvcjsKICAgIHJldHVybiBfdGhpczsKICB9CiAgcmV0dXJuIEVycm9yRXZlbnQyOwp9KEV2ZW50KTsKdmFyIENsb3NlRXZlbnQgPSBmdW5jdGlvbihfc3VwZXIpIHsKICBfX2V4dGVuZHMoQ2xvc2VFdmVudDIsIF9zdXBlcik7CiAgZnVuY3Rpb24gQ2xvc2VFdmVudDIoY29kZSwgcmVhc29uLCB0YXJnZXQpIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIGlmIChyZWFzb24gPT09IHZvaWQgMCkgewogICAgICByZWFzb24gPSAiIjsKICAgIH0KICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJjbG9zZSIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLndhc0NsZWFuID0gdHJ1ZTsKICAgIF90aGlzLmNvZGUgPSBjb2RlOwogICAgX3RoaXMucmVhc29uID0gcmVhc29uOwogICAgcmV0dXJuIF90aGlzOwogIH0KICByZXR1cm4gQ2xvc2VFdmVudDI7Cn0oRXZlbnQpOwp2YXIgZ2V0R2xvYmFsV2ViU29ja2V0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKHR5cGVvZiBXZWJTb2NrZXQgIT09ICJ1bmRlZmluZWQiKSB7CiAgICByZXR1cm4gV2ViU29ja2V0OwogIH0KfTsKdmFyIGlzV2ViU29ja2V0ID0gZnVuY3Rpb24odykgewogIHJldHVybiB0eXBlb2YgdyAhPT0gInVuZGVmaW5lZCIgJiYgISF3ICYmIHcuQ0xPU0lORyA9PT0gMjsKfTsKdmFyIERFRkFVTFQgPSB7CiAgbWF4UmVjb25uZWN0aW9uRGVsYXk6IDFlNCwKICBtaW5SZWNvbm5lY3Rpb25EZWxheTogMWUzICsgTWF0aC5yYW5kb20oKSAqIDRlMywKICBtaW5VcHRpbWU6IDVlMywKICByZWNvbm5lY3Rpb25EZWxheUdyb3dGYWN0b3I6IDEuMywKICBjb25uZWN0aW9uVGltZW91dDogNGUzLAogIG1heFJldHJpZXM6IEluZmluaXR5LAogIG1heEVucXVldWVkTWVzc2FnZXM6IEluZmluaXR5LAogIHN0YXJ0Q2xvc2VkOiBmYWxzZSwKICBkZWJ1ZzogZmFsc2UKfTsKdmFyIFJlY29ubmVjdGluZ1dlYlNvY2tldCA9IGZ1bmN0aW9uKCkgewogIGZ1bmN0aW9uIFJlY29ubmVjdGluZ1dlYlNvY2tldDIodXJsLCBwcm90b2NvbHMsIG9wdGlvbnMpIHsKICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7CiAgICAgIG9wdGlvbnMgPSB7fTsKICAgIH0KICAgIHRoaXMuX2xpc3RlbmVycyA9IHsKICAgICAgZXJyb3I6IFtdLAogICAgICBtZXNzYWdlOiBbXSwKICAgICAgb3BlbjogW10sCiAgICAgIGNsb3NlOiBbXQogICAgfTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIHRoaXMuX3Nob3VsZFJlY29ubmVjdCA9IHRydWU7CiAgICB0aGlzLl9jb25uZWN0TG9jayA9IGZhbHNlOwogICAgdGhpcy5fYmluYXJ5VHlwZSA9ICJibG9iIjsKICAgIHRoaXMuX2Nsb3NlQ2FsbGVkID0gZmFsc2U7CiAgICB0aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgIHRoaXMub25jbG9zZSA9IG51bGw7CiAgICB0aGlzLm9uZXJyb3IgPSBudWxsOwogICAgdGhpcy5vbm1lc3NhZ2UgPSBudWxsOwogICAgdGhpcy5vbm9wZW4gPSBudWxsOwogICAgdGhpcy5faGFuZGxlT3BlbiA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgIF90aGlzLl9kZWJ1Zygib3BlbiBldmVudCIpOwogICAgICB2YXIgX2EgPSBfdGhpcy5fb3B0aW9ucy5taW5VcHRpbWUsIG1pblVwdGltZSA9IF9hID09PSB2b2lkIDAgPyBERUZBVUxULm1pblVwdGltZSA6IF9hOwogICAgICBjbGVhclRpbWVvdXQoX3RoaXMuX2Nvbm5lY3RUaW1lb3V0KTsKICAgICAgX3RoaXMuX3VwdGltZVRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5fYWNjZXB0T3BlbigpOwogICAgICB9LCBtaW5VcHRpbWUpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fbWVzc2FnZVF1ZXVlLmZvckVhY2goZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHJldHVybiBfdGhpcy5fd3Muc2VuZChtZXNzYWdlKTsKICAgICAgfSk7CiAgICAgIF90aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgICAgaWYgKF90aGlzLm9ub3BlbikgewogICAgICAgIF90aGlzLm9ub3BlbihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5vcGVuLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZU1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkgewogICAgICBfdGhpcy5fZGVidWcoIm1lc3NhZ2UgZXZlbnQiKTsKICAgICAgaWYgKF90aGlzLm9ubWVzc2FnZSkgewogICAgICAgIF90aGlzLm9ubWVzc2FnZShldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5tZXNzYWdlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUVycm9yID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJlcnJvciBldmVudCIsIGV2ZW50Lm1lc3NhZ2UpOwogICAgICBfdGhpcy5fZGlzY29ubmVjdCh2b2lkIDAsIGV2ZW50Lm1lc3NhZ2UgPT09ICJUSU1FT1VUIiA/ICJ0aW1lb3V0IiA6IHZvaWQgMCk7CiAgICAgIGlmIChfdGhpcy5vbmVycm9yKSB7CiAgICAgICAgX3RoaXMub25lcnJvcihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJleGVjIGVycm9yIGxpc3RlbmVycyIpOwogICAgICBfdGhpcy5fbGlzdGVuZXJzLmVycm9yLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgICBfdGhpcy5fY29ubmVjdCgpOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUNsb3NlID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJjbG9zZSBldmVudCIpOwogICAgICBfdGhpcy5fY2xlYXJUaW1lb3V0cygpOwogICAgICBpZiAoX3RoaXMuX3Nob3VsZFJlY29ubmVjdCkgewogICAgICAgIF90aGlzLl9jb25uZWN0KCk7CiAgICAgIH0KICAgICAgaWYgKF90aGlzLm9uY2xvc2UpIHsKICAgICAgICBfdGhpcy5vbmNsb3NlKGV2ZW50KTsKICAgICAgfQogICAgICBfdGhpcy5fbGlzdGVuZXJzLmNsb3NlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX3VybCA9IHVybDsKICAgIHRoaXMuX3Byb3RvY29scyA9IHByb3RvY29sczsKICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zOwogICAgaWYgKHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQpIHsKICAgICAgdGhpcy5fc2hvdWxkUmVjb25uZWN0ID0gZmFsc2U7CiAgICB9CiAgICB0aGlzLl9jb25uZWN0KCk7CiAgfQogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ09OTkVDVElORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiAwOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0MiwgIk9QRU4iLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gMTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIsICJDTE9TSU5HIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ0xPU0VEIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDM7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNPTk5FQ1RJTkciLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5DT05ORUNUSU5HOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJPUEVOIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIFJlY29ubmVjdGluZ1dlYlNvY2tldDIuT1BFTjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiQ0xPU0lORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NJTkc7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNMT1NFRCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRDsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYmluYXJ5VHlwZSIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmJpbmFyeVR5cGUgOiB0aGlzLl9iaW5hcnlUeXBlOwogICAgfSwKICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgdGhpcy5fYmluYXJ5VHlwZSA9IHZhbHVlOwogICAgICBpZiAodGhpcy5fd3MpIHsKICAgICAgICB0aGlzLl93cy5iaW5hcnlUeXBlID0gdmFsdWU7CiAgICAgIH0KICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicmV0cnlDb3VudCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBNYXRoLm1heCh0aGlzLl9yZXRyeUNvdW50LCAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYnVmZmVyZWRBbW91bnQiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICB2YXIgYnl0ZXMgPSB0aGlzLl9tZXNzYWdlUXVldWUucmVkdWNlKGZ1bmN0aW9uKGFjYywgbWVzc2FnZSkgewogICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgIGFjYyArPSBtZXNzYWdlLmxlbmd0aDsKICAgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBCbG9iKSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5zaXplOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5ieXRlTGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYWNjOwogICAgICB9LCAwKTsKICAgICAgcmV0dXJuIGJ5dGVzICsgKHRoaXMuX3dzID8gdGhpcy5fd3MuYnVmZmVyZWRBbW91bnQgOiAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiZXh0ZW5zaW9ucyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmV4dGVuc2lvbnMgOiAiIjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicHJvdG9jb2wiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gdGhpcy5fd3MgPyB0aGlzLl93cy5wcm90b2NvbCA6ICIiOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJyZWFkeVN0YXRlIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKHRoaXMuX3dzKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX3dzLnJlYWR5U3RhdGU7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQgPyBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRCA6IFJlY29ubmVjdGluZ1dlYlNvY2tldDIuQ09OTkVDVElORzsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAidXJsIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIHRoaXMuX3dzID8gdGhpcy5fd3MudXJsIDogIiI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICBpZiAoY29kZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvZGUgPSAxZTM7CiAgICB9CiAgICB0aGlzLl9jbG9zZUNhbGxlZCA9IHRydWU7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSBmYWxzZTsKICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlIGVucXVldWVkOiBubyB3cyBpbnN0YW5jZSIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlOiBhbHJlYWR5IGNsb3NlZCIpOwogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSB0cnVlOwogICAgdGhpcy5fY2xvc2VDYWxsZWQgPSBmYWxzZTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIGlmICghdGhpcy5fd3MgfHwgdGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fY29ubmVjdCgpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5fZGlzY29ubmVjdChjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9jb25uZWN0KCk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSkgewogICAgaWYgKHRoaXMuX3dzICYmIHRoaXMuX3dzLnJlYWR5U3RhdGUgPT09IHRoaXMuT1BFTikgewogICAgICB0aGlzLl9kZWJ1Zygic2VuZCIsIGRhdGEpOwogICAgICB0aGlzLl93cy5zZW5kKGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucy5tYXhFbnF1ZXVlZE1lc3NhZ2VzLCBtYXhFbnF1ZXVlZE1lc3NhZ2VzID0gX2EgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4RW5xdWV1ZWRNZXNzYWdlcyA6IF9hOwogICAgICBpZiAodGhpcy5fbWVzc2FnZVF1ZXVlLmxlbmd0aCA8IG1heEVucXVldWVkTWVzc2FnZXMpIHsKICAgICAgICB0aGlzLl9kZWJ1ZygiZW5xdWV1ZSIsIGRhdGEpOwogICAgICAgIHRoaXMuX21lc3NhZ2VRdWV1ZS5wdXNoKGRhdGEpOwogICAgICB9CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdLnB1c2gobGlzdGVuZXIpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuZGlzcGF0Y2hFdmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICB2YXIgZV8xLCBfYTsKICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnNbZXZlbnQudHlwZV07CiAgICBpZiAobGlzdGVuZXJzKSB7CiAgICAgIHRyeSB7CiAgICAgICAgZm9yICh2YXIgbGlzdGVuZXJzXzEgPSBfX3ZhbHVlcyhsaXN0ZW5lcnMpLCBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpOyAhbGlzdGVuZXJzXzFfMS5kb25lOyBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpKSB7CiAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNfMV8xLnZhbHVlOwogICAgICAgICAgdGhpcy5fY2FsbEV2ZW50TGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyKTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2ggKGVfMV8xKSB7CiAgICAgICAgZV8xID0geyBlcnJvcjogZV8xXzEgfTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICB0cnkgewogICAgICAgICAgaWYgKGxpc3RlbmVyc18xXzEgJiYgIWxpc3RlbmVyc18xXzEuZG9uZSAmJiAoX2EgPSBsaXN0ZW5lcnNfMS5yZXR1cm4pKQogICAgICAgICAgICBfYS5jYWxsKGxpc3RlbmVyc18xKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgaWYgKGVfMSkKICAgICAgICAgICAgdGhyb3cgZV8xLmVycm9yOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdID0gdGhpcy5fbGlzdGVuZXJzW3R5cGVdLmZpbHRlcihmdW5jdGlvbihsKSB7CiAgICAgICAgcmV0dXJuIGwgIT09IGxpc3RlbmVyOwogICAgICB9KTsKICAgIH0KICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9kZWJ1ZyA9IGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3MgPSBbXTsKICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7CiAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTsKICAgIH0KICAgIGlmICh0aGlzLl9vcHRpb25zLmRlYnVnKSB7CiAgICAgIGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIF9fc3ByZWFkKFsiUldTPiJdLCBhcmdzKSk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fZ2V0TmV4dERlbGF5ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX2EgPSB0aGlzLl9vcHRpb25zLCBfYiA9IF9hLnJlY29ubmVjdGlvbkRlbGF5R3Jvd0ZhY3RvciwgcmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQucmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yIDogX2IsIF9jID0gX2EubWluUmVjb25uZWN0aW9uRGVsYXksIG1pblJlY29ubmVjdGlvbkRlbGF5ID0gX2MgPT09IHZvaWQgMCA/IERFRkFVTFQubWluUmVjb25uZWN0aW9uRGVsYXkgOiBfYywgX2QgPSBfYS5tYXhSZWNvbm5lY3Rpb25EZWxheSwgbWF4UmVjb25uZWN0aW9uRGVsYXkgPSBfZCA9PT0gdm9pZCAwID8gREVGQVVMVC5tYXhSZWNvbm5lY3Rpb25EZWxheSA6IF9kOwogICAgdmFyIGRlbGF5ID0gMDsKICAgIGlmICh0aGlzLl9yZXRyeUNvdW50ID4gMCkgewogICAgICBkZWxheSA9IG1pblJlY29ubmVjdGlvbkRlbGF5ICogTWF0aC5wb3cocmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yLCB0aGlzLl9yZXRyeUNvdW50IC0gMSk7CiAgICAgIGlmIChkZWxheSA+IG1heFJlY29ubmVjdGlvbkRlbGF5KSB7CiAgICAgICAgZGVsYXkgPSBtYXhSZWNvbm5lY3Rpb25EZWxheTsKICAgICAgfQogICAgfQogICAgdGhpcy5fZGVidWcoIm5leHQgZGVsYXkiLCBkZWxheSk7CiAgICByZXR1cm4gZGVsYXk7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fd2FpdCA9IGZ1bmN0aW9uKCkgewogICAgdmFyIF90aGlzID0gdGhpczsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7CiAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgX3RoaXMuX2dldE5leHREZWxheSgpKTsKICAgIH0pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2dldE5leHRVcmwgPSBmdW5jdGlvbih1cmxQcm92aWRlcikgewogICAgaWYgKHR5cGVvZiB1cmxQcm92aWRlciA9PT0gInN0cmluZyIpIHsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1cmxQcm92aWRlcik7CiAgICB9CiAgICBpZiAodHlwZW9mIHVybFByb3ZpZGVyID09PSAiZnVuY3Rpb24iKSB7CiAgICAgIHZhciB1cmwgPSB1cmxQcm92aWRlcigpOwogICAgICBpZiAodHlwZW9mIHVybCA9PT0gInN0cmluZyIpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVybCk7CiAgICAgIH0KICAgICAgaWYgKCEhdXJsLnRoZW4pIHsKICAgICAgICByZXR1cm4gdXJsOwogICAgICB9CiAgICB9CiAgICB0aHJvdyBFcnJvcigiSW52YWxpZCBVUkwiKTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jb25uZWN0ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX3RoaXMgPSB0aGlzOwogICAgaWYgKHRoaXMuX2Nvbm5lY3RMb2NrIHx8ICF0aGlzLl9zaG91bGRSZWNvbm5lY3QpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fY29ubmVjdExvY2sgPSB0cnVlOwogICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucywgX2IgPSBfYS5tYXhSZXRyaWVzLCBtYXhSZXRyaWVzID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4UmV0cmllcyA6IF9iLCBfYyA9IF9hLmNvbm5lY3Rpb25UaW1lb3V0LCBjb25uZWN0aW9uVGltZW91dCA9IF9jID09PSB2b2lkIDAgPyBERUZBVUxULmNvbm5lY3Rpb25UaW1lb3V0IDogX2MsIF9kID0gX2EuV2ViU29ja2V0LCBXZWJTb2NrZXQyID0gX2QgPT09IHZvaWQgMCA/IGdldEdsb2JhbFdlYlNvY2tldCgpIDogX2Q7CiAgICBpZiAodGhpcy5fcmV0cnlDb3VudCA+PSBtYXhSZXRyaWVzKSB7CiAgICAgIHRoaXMuX2RlYnVnKCJtYXggcmV0cmllcyByZWFjaGVkIiwgdGhpcy5fcmV0cnlDb3VudCwgIj49IiwgbWF4UmV0cmllcyk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIHRoaXMuX3JldHJ5Q291bnQrKzsKICAgIHRoaXMuX2RlYnVnKCJjb25uZWN0IiwgdGhpcy5fcmV0cnlDb3VudCk7CiAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lcnMoKTsKICAgIGlmICghaXNXZWJTb2NrZXQoV2ViU29ja2V0MikpIHsKICAgICAgdGhyb3cgRXJyb3IoIk5vIHZhbGlkIFdlYlNvY2tldCBjbGFzcyBwcm92aWRlZCIpOwogICAgfQogICAgdGhpcy5fd2FpdCgpLnRoZW4oZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBfdGhpcy5fZ2V0TmV4dFVybChfdGhpcy5fdXJsKTsKICAgIH0pLnRoZW4oZnVuY3Rpb24odXJsKSB7CiAgICAgIGlmIChfdGhpcy5fY2xvc2VDYWxsZWQpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJjb25uZWN0IiwgeyB1cmwsIHByb3RvY29sczogX3RoaXMuX3Byb3RvY29scyB9KTsKICAgICAgX3RoaXMuX3dzID0gX3RoaXMuX3Byb3RvY29scyA/IG5ldyBXZWJTb2NrZXQyKHVybCwgX3RoaXMuX3Byb3RvY29scykgOiBuZXcgV2ViU29ja2V0Mih1cmwpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fY29ubmVjdExvY2sgPSBmYWxzZTsKICAgICAgX3RoaXMuX2FkZExpc3RlbmVycygpOwogICAgICBfdGhpcy5fY29ubmVjdFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5faGFuZGxlVGltZW91dCgpOwogICAgICB9LCBjb25uZWN0aW9uVGltZW91dCk7CiAgICB9KTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9oYW5kbGVUaW1lb3V0ID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLl9kZWJ1ZygidGltZW91dCBldmVudCIpOwogICAgdGhpcy5faGFuZGxlRXJyb3IobmV3IEVycm9yRXZlbnQoRXJyb3IoIlRJTUVPVVQiKSwgdGhpcykpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2Rpc2Nvbm5lY3QgPSBmdW5jdGlvbihjb2RlLCByZWFzb24pIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJzKCk7CiAgICB0cnkgewogICAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9oYW5kbGVDbG9zZShuZXcgQ2xvc2VFdmVudChjb2RlLCByZWFzb24sIHRoaXMpKTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fYWNjZXB0T3BlbiA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5fZGVidWcoImFjY2VwdCBvcGVuIik7CiAgICB0aGlzLl9yZXRyeUNvdW50ID0gMDsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jYWxsRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBsaXN0ZW5lcikgewogICAgaWYgKCJoYW5kbGVFdmVudCIgaW4gbGlzdGVuZXIpIHsKICAgICAgbGlzdGVuZXIuaGFuZGxlRXZlbnQoZXZlbnQpOwogICAgfSBlbHNlIHsKICAgICAgbGlzdGVuZXIoZXZlbnQpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX3JlbW92ZUxpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygicmVtb3ZlTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2FkZExpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygiYWRkTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2NsZWFyVGltZW91dHMgPSBmdW5jdGlvbigpIHsKICAgIGNsZWFyVGltZW91dCh0aGlzLl9jb25uZWN0VGltZW91dCk7CiAgICBjbGVhclRpbWVvdXQodGhpcy5fdXB0aW1lVGltZW91dCk7CiAgfTsKICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0MjsKfSgpOwp2YXIgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdCA9IFJlY29ubmVjdGluZ1dlYlNvY2tldDsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJncywgZW52LCBmZHMsIG9wdGlvbnMgPSB7fSkgewogICAgdGhpcy5hcmdzID0gW107CiAgICB0aGlzLmVudiA9IFtdOwogICAgdGhpcy5mZHMgPSBbXTsKICAgIGRlYnVnLmVuYWJsZShvcHRpb25zLmRlYnVnKTsKICAgIHRoaXMuYXJncyA9IGFyZ3M7CiAgICB0aGlzLmVudiA9IGVudjsKICAgIHRoaXMuZmRzID0gZmRzOwogICAgY29uc3Qgc2VsZiA9IHRoaXM7CiAgICB0aGlzLndhc2lJbXBvcnQgPSB7IGFyZ3Nfc2l6ZXNfZ2V0KGFyZ2MsIGFyZ3ZfYnVmX3NpemUpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ2MsIHNlbGYuYXJncy5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGFyZyBvZiBzZWxmLmFyZ3MpIHsKICAgICAgICBidWZfc2l6ZSArPSBhcmcubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3ZfYnVmX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoYXJnYywgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGFyZ3NfZ2V0KGFyZ3YsIGFyZ3ZfYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2FyZ3ZfYnVmID0gYXJndl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5hcmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihhcmd2LCBhcmd2X2J1ZiwgdHJ1ZSk7CiAgICAgICAgYXJndiArPSA0OwogICAgICAgIGNvbnN0IGFyZyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmFyZ3NbaV0pOwogICAgICAgIGJ1ZmZlcjguc2V0KGFyZywgYXJndl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChhcmd2X2J1ZiArIGFyZy5sZW5ndGgsIDApOwogICAgICAgIGFyZ3ZfYnVmICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgICAgZGVidWcubG9nKG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvcmlnX2FyZ3ZfYnVmLCBhcmd2X2J1ZikpKTsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fc2l6ZXNfZ2V0KGVudmlyb25fY291bnQsIGVudmlyb25fc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9jb3VudCwgc2VsZi5lbnYubGVuZ3RoLCB0cnVlKTsKICAgICAgbGV0IGJ1Zl9zaXplID0gMDsKICAgICAgZm9yIChjb25zdCBlbnZpcm9uIG9mIHNlbGYuZW52KSB7CiAgICAgICAgYnVmX3NpemUgKz0gZW52aXJvbi5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9zaXplLCBidWZfc2l6ZSwgdHJ1ZSk7CiAgICAgIGRlYnVnLmxvZyhidWZmZXIuZ2V0VWludDMyKGVudmlyb25fY291bnQsIHRydWUpLCBidWZmZXIuZ2V0VWludDMyKGVudmlyb25fc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fZ2V0KGVudmlyb24sIGVudmlyb25fYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2Vudmlyb25fYnVmID0gZW52aXJvbl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5lbnYubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGVudmlyb24sIGVudmlyb25fYnVmLCB0cnVlKTsKICAgICAgICBlbnZpcm9uICs9IDQ7CiAgICAgICAgY29uc3QgZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmVudltpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoZSwgZW52aXJvbl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChlbnZpcm9uX2J1ZiArIGUubGVuZ3RoLCAwKTsKICAgICAgICBlbnZpcm9uX2J1ZiArPSBlLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfZW52aXJvbl9idWYsIGVudmlyb25fYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgY2xvY2tfcmVzX2dldChpZCwgcmVzX3B0cikgewogICAgICBsZXQgcmVzb2x1dGlvblZhbHVlOwogICAgICBzd2l0Y2ggKGlkKSB7CiAgICAgICAgY2FzZSBDTE9DS0lEX01PTk9UT05JQzogewogICAgICAgICAgcmVzb2x1dGlvblZhbHVlID0gNTAwMG47CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDTE9DS0lEX1JFQUxUSU1FOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSAxMDAwMDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuIEVSUk5PX05PU1lTOwogICAgICB9CiAgICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIHZpZXcuc2V0QmlnVWludDY0KHJlc19wdHIsIHJlc29sdXRpb25WYWx1ZSwgdHJ1ZSk7CiAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgfSwgY2xvY2tfdGltZV9nZXQoaWQsIHByZWNpc2lvbiwgdGltZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChpZCA9PT0gQ0xPQ0tJRF9SRUFMVElNRSkgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgQmlnSW50KG5ldyBEYXRlKCkuZ2V0VGltZSgpKSAqIDEwMDAwMDBuLCB0cnVlKTsKICAgICAgfSBlbHNlIGlmIChpZCA9PSBDTE9DS0lEX01PTk9UT05JQykgewogICAgICAgIGxldCBtb25vdG9uaWNfdGltZTsKICAgICAgICB0cnkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSBCaWdJbnQoTWF0aC5yb3VuZChwZXJmb3JtYW5jZS5ub3coKSAqIDFlNikpOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIG1vbm90b25pY190aW1lID0gMG47CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgbW9ub3RvbmljX3RpbWUsIHRydWUpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgMG4sIHRydWUpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZmRfYWR2aXNlKGZkLCBvZmZzZXQsIGxlbiwgYWR2aWNlKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2FsbG9jYXRlKGZkLCBvZmZzZXQsIGxlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9jbG9zZShmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW2ZkXS5mZF9jbG9zZSgpOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9kYXRhc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfZ2V0KGZkLCBmZHN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZkc3RhdCB9ID0gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmRzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZkc3RhdC53cml0ZV9ieXRlcyhuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlciksIGZkc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfc2V0X2ZsYWdzKGZkLCBmbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZkLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X2dldChmZCwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfZ2V0KCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfc2V0X3NpemUoZmQsIHNpemUpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlYWQoaW92ZWMuYnVmX2xlbiwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgb2Zmc2V0ICs9IEJpZ0ludChkYXRhLmxlbmd0aCk7CiAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggIT0gaW92ZWMuYnVmX2xlbikgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9nZXQoZmQsIGJ1Zl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBwcmVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgYnVmX3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZXN0YXRfZGlyX25hbWUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBjb25zdCBwcmVzdGF0X2Rpcl9uYW1lID0gcHJlc3RhdC5pbm5lci5wcl9uYW1lOwogICAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgICBidWZmZXI4LnNldChwcmVzdGF0X2Rpcl9uYW1lLnNsaWNlKDAsIHBhdGhfbGVuKSwgcGF0aF9wdHIpOwogICAgICAgIHJldHVybiBwcmVzdGF0X2Rpcl9uYW1lLmJ5dGVMZW5ndGggPiBwYXRoX2xlbiA/IEVSUk5PX05BTUVUT09MT05HIDogRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHdyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbndyaXR0ZW5fcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IENpb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbndyaXR0ZW4gPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCBkYXRhID0gYnVmZmVyOC5zbGljZShpb3ZlYy5idWYsIGlvdmVjLmJ1ZiArIGlvdmVjLmJ1Zl9sZW4pOwogICAgICAgICAgY29uc3QgeyByZXQsIG53cml0dGVuOiBud3JpdHRlbl9wYXJ0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHdyaXRlKGRhdGEsIG9mZnNldCk7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIG53cml0dGVuICs9IG53cml0dGVuX3BhcnQ7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KG53cml0dGVuX3BhcnQpOwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG5yZWFkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBJb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbnJlYWQgPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLmZkX3JlYWQoaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGEsIGlvdmVjLmJ1Zik7CiAgICAgICAgICBucmVhZCArPSBkYXRhLmxlbmd0aDsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkZGlyKGZkLCBidWYsIGJ1Zl9sZW4sIGNvb2tpZSwgYnVmdXNlZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgbGV0IGJ1ZnVzZWQgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGlyZW50IH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKTsKICAgICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChkaXJlbnQgPT0gbnVsbCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5oZWFkX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNvbnN0IGhlYWRfYnl0ZXMgPSBuZXcgQXJyYXlCdWZmZXIoZGlyZW50LmhlYWRfbGVuZ3RoKCkpOwogICAgICAgICAgZGlyZW50LndyaXRlX2hlYWRfYnl0ZXMobmV3IERhdGFWaWV3KGhlYWRfYnl0ZXMpLCAwKTsKICAgICAgICAgIGJ1ZmZlcjguc2V0KG5ldyBVaW50OEFycmF5KGhlYWRfYnl0ZXMpLnNsaWNlKDAsIE1hdGgubWluKGhlYWRfYnl0ZXMuYnl0ZUxlbmd0aCwgYnVmX2xlbiAtIGJ1ZnVzZWQpKSwgYnVmKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50LmhlYWRfbGVuZ3RoKCk7CiAgICAgICAgICBpZiAoYnVmX2xlbiAtIGJ1ZnVzZWQgPCBkaXJlbnQubmFtZV9sZW5ndGgoKSkgewogICAgICAgICAgICBidWZ1c2VkID0gYnVmX2xlbjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBkaXJlbnQud3JpdGVfbmFtZV9ieXRlcyhidWZmZXI4LCBidWYsIGJ1Zl9sZW4gLSBidWZ1c2VkKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50Lm5hbWVfbGVuZ3RoKCk7CiAgICAgICAgICBjb29raWUgPSBkaXJlbnQuZF9uZXh0OwogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcmVudW1iZXIoZmQsIHRvKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW3RvXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCByZXQgPSBzZWxmLmZkc1t0b10uZmRfY2xvc2UoKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzW3RvXSA9IHNlbGYuZmRzW2ZkXTsKICAgICAgICBzZWxmLmZkc1tmZF0gPSB2b2lkIDA7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3NlZWsoZmQsIG9mZnNldCwgd2hlbmNlLCBvZmZzZXRfb3V0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIG9mZnNldDogb2Zmc2V0X291dCB9ID0gc2VsZi5mZHNbZmRdLmZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdJbnQ2NChvZmZzZXRfb3V0X3B0ciwgb2Zmc2V0X291dCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF90ZWxsKGZkLCBvZmZzZXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfdGVsbCgpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQob2Zmc2V0X3B0ciwgb2Zmc2V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF93cml0ZShmZCwgaW92c19wdHIsIGlvdnNfbGVuLCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF93cml0ZShkYXRhKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIGlmIChud3JpdHRlbl9wYXJ0ICE9IGRhdGEuYnl0ZUxlbmd0aCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9nZXQoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGZpbGVzdGF0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2xpbmsob2xkX2ZkLCBvbGRfZmxhZ3MsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW29sZF9mZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW29sZF9mZF0ucGF0aF9sb29rdXAob2xkX3BhdGgsIG9sZF9mbGFncyk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgZmFsc2UpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX29wZW4oZmQsIGRpcmZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncywgb3BlbmVkX2ZkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgpOwogICAgICAgIGNvbnN0IHsgcmV0LCBmZF9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGgsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncyk7CiAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBzZWxmLmZkcy5wdXNoKGZkX29iaik7CiAgICAgICAgY29uc3Qgb3BlbmVkX2ZkID0gc2VsZi5mZHMubGVuZ3RoIC0gMTsKICAgICAgICBidWZmZXIuc2V0VWludDMyKG9wZW5lZF9mZF9wdHIsIG9wZW5lZF9mZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVhZGxpbmsoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbiwgYnVmX3B0ciwgYnVmX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3JlYWRsaW5rKHBhdGgpOwogICAgICAgIGlmIChkYXRhICE9IG51bGwpIHsKICAgICAgICAgIGNvbnN0IGRhdGFfYnVmID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGRhdGEpOwogICAgICAgICAgaWYgKGRhdGFfYnVmLmxlbmd0aCA+IGJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIDAsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGFfYnVmLCBidWZfcHRyKTsKICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBkYXRhX2J1Zi5sZW5ndGgsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbW92ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbmFtZShmZCwgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCAmJiBzZWxmLmZkc1tuZXdfZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICBsZXQgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfdW5saW5rKG9sZF9wYXRoKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldCA9IHNlbGYuZmRzW25ld19mZF0ucGF0aF9saW5rKG5ld19wYXRoLCBpbm9kZV9vYmosIHRydWUpOwogICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgaWYgKHNlbGYuZmRzW2ZkXS5wYXRoX2xpbmsob2xkX3BhdGgsIGlub2RlX29iaiwgdHJ1ZSkgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICB0aHJvdyAicGF0aF9saW5rIHNob3VsZCBhbHdheXMgcmV0dXJuIHN1Y2Nlc3Mgd2hlbiByZWxpbmtpbmcgYW4gaW5vZGUgYmFjayB0byB0aGUgb3JpZ2luYWwgcGxhY2UiOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3N5bWxpbmsob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIGZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfdW5saW5rX2ZpbGUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmtfZmlsZShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGgsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfcmVhZGxpbmsocGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG51bGwgfTsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQp9Owp2YXIgSW5vZGUgPSBjbGFzcyB7Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZzX21lbS5qcwp2YXIgT3BlbkZpbGUgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gb2Zmc2V0ICsgbGVuKSB7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBsZW4pKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCAwKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBzaXplKSB7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5maWxlLmRhdGEuYnVmZmVyLnNsaWNlKDAsIE51bWJlcihzaXplKSkpOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIoc2l6ZSkpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIodGhpcy5maWxlX3BvcyksIE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KHNpemUpKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChzbGljZS5sZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKG9mZnNldCksIE51bWJlcihvZmZzZXQgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgbGV0IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgc3dpdGNoICh3aGVuY2UpIHsKICAgICAgY2FzZSBXSEVOQ0VfU0VUOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9DVVI6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSB0aGlzLmZpbGVfcG9zICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9FTkQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBCaWdJbnQodGhpcy5maWxlLmRhdGEuYnl0ZUxlbmd0aCkgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgaWYgKGNhbGN1bGF0ZWRfb2Zmc2V0IDwgMCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICB0aGlzLmZpbGVfcG9zID0gY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcihvZmZzZXQpKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmZpbGUuc3RhdCgpIH07CiAgfQogIGNvbnN0cnVjdG9yKGZpbGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmZpbGVfcG9zID0gMG47CiAgICB0aGlzLmZpbGUgPSBmaWxlOwogIH0KfTsKdmFyIE9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9ESVJFQ1RPUlksIDApIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgZGVidWcubG9nKCJyZWFkZGlyX3NpbmdsZSIsIGNvb2tpZSk7CiAgICAgIGRlYnVnLmxvZyhjb29raWUsIHRoaXMuZGlyLmNvbnRlbnRzLmtleXMoKSk7CiAgICB9CiAgICBpZiAoY29va2llID09IDBuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDFuLCAiLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0gZWxzZSBpZiAoY29va2llID09IDFuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDJuLCAiLi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9CiAgICBpZiAoY29va2llID49IEJpZ0ludCh0aGlzLmRpci5jb250ZW50cy5zaXplKSArIDJuKSB7CiAgICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBbbmFtZSwgZW50cnldID0gQXJyYXkuZnJvbSh0aGlzLmRpci5jb250ZW50cy5lbnRyaWVzKCkpW051bWJlcihjb29raWUgLSAybildOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG5ldyBEaXJlbnQoY29va2llICsgMW4sIG5hbWUsIGVudHJ5LnN0YXQoKS5maWxldHlwZSkgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9lcnIsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IGVudHJ5LnN0YXQoKSB9OwogIH0KICBwYXRoX2xvb2t1cChwYXRoX3N0ciwgZGlyZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoX3N0ciwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgaWYgKHJldCAhPSBFUlJOT19OT0VOVCkgewogICAgICAgIHJldHVybiB7IHJldCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfQ1JFQVQpID09IE9GTEFHU19DUkVBVCkgewogICAgICAgIGNvbnN0IHsgcmV0OiByZXQyLCBlbnRyeTogbmV3X2VudHJ5IH0gPSB0aGlzLmRpci5jcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZKTsKICAgICAgICBpZiAobmV3X2VudHJ5ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiB7IHJldDogcmV0MiwgZmRfb2JqOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGVudHJ5ID0gbmV3X2VudHJ5OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICB9IGVsc2UgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRVhDTCkgPT0gT0ZMQUdTX0VYQ0wpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIGVudHJ5LnBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncyk7CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gdGhpcy5wYXRoX29wZW4oMCwgcGF0aCwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIGNvbnN0IHNvdXJjZV9pc19kaXIgPSBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBjb25zdCB0YXJnZXRfaXNfZGlyID0gZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgaWYgKHNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIGlmIChhbGxvd19kaXIgJiYgZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHsKICAgICAgICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplID09IDApIHsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChzb3VyY2VfaXNfZGlyICYmICF0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgICAgfSBlbHNlIGlmICghc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgICB9IGVsc2UgaWYgKGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSkgewogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgfQogICAgfQogICAgaWYgKCFhbGxvd19kaXIgJiYgaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fUEVSTTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIGlub2RlKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3VubGluayhwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF91bmxpbmtfZmlsZShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHx8IGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICB9CiAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSAhPT0gMCkgewogICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICB9CiAgICBpZiAoIXBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpKSB7CiAgICAgIHJldHVybiBFUlJOT19OT0VOVDsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmRpci5zdGF0KCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBjb25zdHJ1Y3RvcihkaXIpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRpciA9IGRpcjsKICB9Cn07CnZhciBQcmVvcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBPcGVuRGlyZWN0b3J5IHsKICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgcHJlc3RhdDogUHJlc3RhdC5kaXIodGhpcy5wcmVzdGF0X25hbWUpIH07CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnRzKSB7CiAgICBzdXBlcihuZXcgRGlyZWN0b3J5KGNvbnRlbnRzKSk7CiAgICB0aGlzLnByZXN0YXRfbmFtZSA9IG5hbWU7CiAgfQp9Owp2YXIgRmlsZSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgaWYgKHRoaXMucmVhZG9ubHkgJiYgKGZzX3JpZ2h0c19iYXNlICYgQmlnSW50KFJJR0hUU19GRF9XUklURSkpID09IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19UUlVOQykgPT0gT0ZMQUdTX1RSVU5DKSB7CiAgICAgIGlmICh0aGlzLnJlYWRvbmx5KQogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KFtdKTsKICAgIH0KICAgIGNvbnN0IGZpbGUgPSBuZXcgT3BlbkZpbGUodGhpcyk7CiAgICBpZiAoZmRfZmxhZ3MgJiBGREZMQUdTX0FQUEVORCkKICAgICAgZmlsZS5mZF9zZWVrKDBuLCBXSEVOQ0VfRU5EKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZmRfb2JqOiBmaWxlIH07CiAgfQogIGdldCBzaXplKCkgewogICAgcmV0dXJuIEJpZ0ludCh0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgdGhpcy5zaXplKTsKICB9CiAgY29uc3RydWN0b3IoZGF0YSwgb3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgdGhpcy5yZWFkb25seSA9ICEhb3B0aW9ucz8ucmVhZG9ubHk7CiAgfQp9Owp2YXIgUGF0aCA9IGNsYXNzIFBhdGgyIHsKICBzdGF0aWMgZnJvbShwYXRoKSB7CiAgICBjb25zdCBzZWxmID0gbmV3IFBhdGgyKCk7CiAgICBzZWxmLmlzX2RpciA9IHBhdGguZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVENBUEFCTEUsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGlmIChwYXRoLmluY2x1ZGVzKCJcMCIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGguc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aCkgewogICAgbGV0IGVudHJ5ID0gdGhpczsKICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgucGFydHMpIHsKICAgICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgICAgY29uc3QgY2hpbGQgPSBlbnRyeS5jb250ZW50cy5nZXQoY29tcG9uZW50KTsKICAgICAgaWYgKGNoaWxkICE9PSB2b2lkIDApIHsKICAgICAgICBlbnRyeSA9IGNoaWxkOwogICAgICB9IGVsc2UgewogICAgICAgIGRlYnVnLmxvZyhjb21wb25lbnQpOwogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBhbGxvd191bmRlZmluZWQpIHsKICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5wYXJ0cy5wb3AoKTsKICAgIGlmIChmaWxlbmFtZSA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldDogZW50cnlfcmV0LCBlbnRyeTogcGFyZW50X2VudHJ5IH0gPSB0aGlzLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfTsKICB9CiAgY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCBpc19kaXIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGRlYnVnLmxvZygiY3JlYXRlIiwgcGF0aCk7CiAgICBsZXQgbmV3X2NoaWxkOwogICAgaWYgKCFpc19kaXIpIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IEZpbGUobmV3IEFycmF5QnVmZmVyKDApKTsKICAgIH0gZWxzZSB7CiAgICAgIG5ld19jaGlsZCA9IG5ldyBEaXJlY3RvcnkoLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSk7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBuZXdfY2hpbGQpOwogICAgZW50cnkgPSBuZXdfY2hpbGQ7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGNvbnN0cnVjdG9yKGNvbnRlbnRzKSB7CiAgICBzdXBlcigpOwogICAgaWYgKGNvbnRlbnRzIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgdGhpcy5jb250ZW50cyA9IG5ldyBNYXAoY29udGVudHMpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5jb250ZW50cyA9IGNvbnRlbnRzOwogICAgfQogIH0KfTsKdmFyIENvbnNvbGVTdGRvdXQgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmaWxlc3RhdCA9IG5ldyBGaWxlc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCBCaWdJbnQoMCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdCB9OwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgY29uc3QgZmRzdGF0ID0gbmV3IEZkc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCAwKTsKICAgIGZkc3RhdC5mc19yaWdodHNfYmFzZSA9IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgdGhpcy53cml0ZShkYXRhKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBzdGF0aWMgbGluZUJ1ZmZlcmVkKHdyaXRlKSB7CiAgICBjb25zdCBkZWMgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICBsZXQgbGluZV9idWYgPSAiIjsKICAgIHJldHVybiBuZXcgQ29uc29sZVN0ZG91dCgoYnVmZmVyKSA9PiB7CiAgICAgIGxpbmVfYnVmICs9IGRlYy5kZWNvZGUoYnVmZmVyLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgICAgY29uc3QgbGluZXMgPSBsaW5lX2J1Zi5zcGxpdCgiXG4iKTsKICAgICAgZm9yIChjb25zdCBbaSwgbGluZV0gb2YgbGluZXMuZW50cmllcygpKSB7CiAgICAgICAgaWYgKGkgPCBsaW5lcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICB3cml0ZShsaW5lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGluZV9idWYgPSBsaW5lOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfQogIGNvbnN0cnVjdG9yKHdyaXRlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy53cml0ZSA9IHdyaXRlOwogIH0KfTsKCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL2luZGV4LmpzCmZ1bmN0aW9uIHBhcnNlSW1wb3J0cyhtb2R1bGVCeXRlcykgewogIGlmIChtb2R1bGVCeXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsKICB9IGVsc2UgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMpOwogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMuYnVmZmVyKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCJBcmd1bWVudCBtdXN0IGJlIGEgYnVmZmVyIHNvdXJjZSwgbGlrZSBVaW50OEFycmF5IG9yIEFycmF5QnVmZmVyIik7CiAgfQogIGNvbnN0IHBhcnNlU3RhdGUgPSBuZXcgUGFyc2VTdGF0ZShtb2R1bGVCeXRlcyk7CiAgcGFyc2VNYWdpY051bWJlcihwYXJzZVN0YXRlKTsKICBwYXJzZVZlcnNpb24ocGFyc2VTdGF0ZSk7CiAgY29uc3QgdHlwZXMgPSBbXTsKICBjb25zdCBpbXBvcnRzID0gW107CiAgd2hpbGUgKHBhcnNlU3RhdGUuaGFzTW9yZUJ5dGVzKCkpIHsKICAgIGNvbnN0IHNlY3Rpb25JZCA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICAgIGNvbnN0IHNlY3Rpb25TaXplID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgIHN3aXRjaCAoc2VjdGlvbklkKSB7CiAgICAgIGNhc2UgMTogewogICAgICAgIGNvbnN0IHR5cGVDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eXBlQ291bnQ7IGkrKykgewogICAgICAgICAgdHlwZXMucHVzaChwYXJzZUZ1bmN0aW9uVHlwZShwYXJzZVN0YXRlKSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgMjogewogICAgICAgIGNvbnN0IGltcG9ydENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGltcG9ydENvdW50OyBpKyspIHsKICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobW9kdWxlQnl0ZXMpOwogIGNvbnN0IGltcG9ydHMgPSBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpOwogIGNvbnN0IG1lbW9yeUltcG9ydCA9IGltcG9ydHNbMF07CiAgcmV0dXJuIHR5cGVvZiBtZW1vcnlJbXBvcnQudHlwZSA9PT0gIm9iamVjdCI7Cn0pKCk7CmZ1bmN0aW9uIHBvbHlmaWxsKFdlYkFzc2VtYmx5MykgewogIGlmIChoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0KSB7CiAgICByZXR1cm4gV2ViQXNzZW1ibHkzOwogIH0KICBjb25zdCBuZXdXZWJBc3NlbWJseSA9IHt9OwogIGZvciAoY29uc3Qga2V5IGluIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKFdlYkFzc2VtYmx5MykpIHsKICAgIG5ld1dlYkFzc2VtYmx5W2tleV0gPSBXZWJBc3NlbWJseTNba2V5XTsKICB9CiAgY29uc3QgcG9seWZpbGxlZEltcG9ydHNTeW1ib2wgPSBTeW1ib2woInBvbHlmaWxsZWRJbXBvcnRzU3ltYm9sIik7CiAgY29uc3QgYXNzaWduSW1wb3J0cyA9IChtb2R1bGUsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdID0gcGFyc2VJbXBvcnRzKHNvdXJjZUJ5dGVzKTsKICB9OwogIGNvbnN0IG5ld01vZHVsZSA9IG5ld1dlYkFzc2VtYmx5Lk1vZHVsZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICBjb25zdCBtb2R1bGUgPSBuZXcgV2ViQXNzZW1ibHkzLk1vZHVsZShieXRlcyk7CiAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZSwgbmV3TW9kdWxlLnByb3RvdHlwZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG5ld01vZHVsZS5wcm90b3R5cGUsIFdlYkFzc2VtYmx5My5Nb2R1bGUucHJvdG90eXBlKTsKICBuZXdXZWJBc3NlbWJseS5jb21waWxlID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBzb3VyY2UpOwogICAgcmV0dXJuIG1vZHVsZTsKICB9OwogIGlmIChXZWJBc3NlbWJseTMuY29tcGlsZVN0cmVhbWluZykgewogICAgbmV3V2ViQXNzZW1ibHkuY29tcGlsZVN0cmVhbWluZyA9IGFzeW5jIChzb3VyY2UpID0+IHsKICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzb3VyY2U7CiAgICAgIGNvbnN0IGNsb25lID0gcmVzcG9uc2UuY2xvbmUoKTsKICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgbmV3IFVpbnQ4QXJyYXkoYXdhaXQgY2xvbmUuYXJyYXlCdWZmZXIoKSkpOwogICAgICByZXR1cm4gbW9kdWxlOwogICAgfTsKICB9CiAgbmV3TW9kdWxlLmltcG9ydHMgPSAobW9kdWxlKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXTsKICAgIGlmICghcGFyc2VkSW1wb3J0cykgewogICAgICByZXR1cm4gV2ViQXNzZW1ibHkzLk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgICB9CiAgICByZXR1cm4gcGFyc2VkSW1wb3J0czsKICB9OwogIHJldHVybiBuZXdXZWJBc3NlbWJseTsKfQoKLy8gZW50cnlwb2ludC9pbnRyaW5zaWNzLnRzCnZhciBXZWJBc3NlbWJseTIgPSBwb2x5ZmlsbChnbG9iYWxUaGlzLldlYkFzc2VtYmx5KTsKdmFyIExpbmVEZWNvZGVyID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG9uTGluZSkgewogICAgdGhpcy5kZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIsIHsgZmF0YWw6IGZhbHNlIH0pOwogICAgdGhpcy5idWZmZXIgPSAiIjsKICAgIHRoaXMub25MaW5lID0gb25MaW5lOwogIH0KICBkZWNvZGVyOwogIGJ1ZmZlcjsKICBvbkxpbmU7CiAgc2VuZChjaHVuaykgewogICAgdGhpcy5idWZmZXIgKz0gdGhpcy5kZWNvZGVyLmRlY29kZShjaHVuaywgeyBzdHJlYW06IHRydWUgfSk7CiAgICBjb25zdCBsaW5lcyA9IHRoaXMuYnVmZmVyLnNwbGl0KCJcbiIpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGggLSAxOyBpKyspIHsKICAgICAgdGhpcy5vbkxpbmUobGluZXNbaV0pOwogICAgfQogICAgdGhpcy5idWZmZXIgPSBsaW5lc1tsaW5lcy5sZW5ndGggLSAxXTsKICB9Cn07CmFzeW5jIGZ1bmN0aW9uIGluc3RhbnRpYXRlKHJhd09wdGlvbnMsIGV4dHJhV2FzbUltcG9ydHMpIHsKICBjb25zdCBvcHRpb25zID0gZGVmYXVsdEluc3RhbnRpYXRpb25PcHRpb25zKHJhd09wdGlvbnMpOwogIGxldCBzd2lmdCA9IG9wdGlvbnMuc3dpZnQ7CiAgaWYgKCFzd2lmdCAmJiBvcHRpb25zLlN3aWZ0UnVudGltZSkgewogICAgc3dpZnQgPSBuZXcgb3B0aW9ucy5Td2lmdFJ1bnRpbWUoKTsKICB9CiAgbGV0IHN0ZG91dExpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRvdXRMaW5lICE9IG51bGwpIHsKICAgIHN0ZG91dExpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZG91dExpbmUpOwogIH0KICBjb25zdCBzdGRvdXQgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRvdXQ/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRvdXRMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBsZXQgc3RkZXJyTGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZGVyckxpbmUgIT0gbnVsbCkgewogICAgc3RkZXJyTGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3RkZXJyTGluZSk7CiAgfQogIGNvbnN0IHN0ZGVyciA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZGVycj8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZGVyckxpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGNvbnN0IGFyZ3MgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzLCBlbnZzLCBmZHMsIHsKICAgIGRlYnVnOiBmYWxzZQogIH0pOwogIGNvbnN0IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QgPSAoZXh0cmFXYXNtSW1wb3J0czIsIG1vZHVsZSkgPT4gewogICAgY29uc3QgaW1wb3J0T2JqZWN0MiA9IHsKICAgICAgd2FzaV9zbmFwc2hvdF9wcmV2aWV3MTogd2FzaS53YXNpSW1wb3J0CiAgICB9OwogICAgaWYgKHN3aWZ0KSB7CiAgICAgIGltcG9ydE9iamVjdDIuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzMikgewogICAgICBmb3IgKGNvbnN0IG1vZHVsZU5hbWUgaW4gZXh0cmFXYXNtSW1wb3J0czIpIHsKICAgICAgICBpZiAoIWltcG9ydE9iamVjdDJbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdDJbbW9kdWxlTmFtZV0gPSB7fTsKICAgICAgICB9CiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBpbiBleHRyYVdhc21JbXBvcnRzMlttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0Mlttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzMlttb2R1bGVOYW1lXVtlbnRyeV07CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBmb3IgKGNvbnN0IF9pbXBvcnRFbnRyeSBvZiBXZWJBc3NlbWJseTIuTW9kdWxlLmltcG9ydHMobW9kdWxlKSkgewogICAgICBjb25zdCBpbXBvcnRFbnRyeSA9IF9pbXBvcnRFbnRyeTsKICAgICAgaWYgKCFpbXBvcnRPYmplY3QyW2ltcG9ydEVudHJ5Lm1vZHVsZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3QyW2ltcG9ydEVudHJ5Lm1vZHVsZV0gPSB7fTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0T2JqZWN0MltpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gImZ1bmN0aW9uIikgewogICAgICAgIGltcG9ydE9iamVjdDJbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfSBlbHNlIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJtZW1vcnkiICYmIGltcG9ydEVudHJ5Lm1vZHVsZSA9PSAiZW52IiAmJiBpbXBvcnRFbnRyeS5uYW1lID09ICJtZW1vcnkiKSB7CiAgICAgICAgY29uc3QgdHlwZSA9IGltcG9ydEVudHJ5LnR5cGU7CiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsKICAgICAgICAgIGluaXRpYWw6IHR5cGUubWluaW11bSwKICAgICAgICAgIG1heGltdW06IHR5cGUubWF4aW11bSwKICAgICAgICAgIHNoYXJlZDogdHlwZS5zaGFyZWQKICAgICAgICB9OwogICAgICAgIGltcG9ydE9iamVjdDJbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9IG5ldyBXZWJBc3NlbWJseTIuTWVtb3J5KGRlc2NyaXB0b3IpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0MjsKICB9OwogIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgb3B0aW9ucy5tb2R1bGUpOwogIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgV2ViQXNzZW1ibHkyLmluc3RhbnRpYXRlKG9wdGlvbnMubW9kdWxlLCBpbXBvcnRPYmplY3QpOwogIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICBzd2lmdC5zZXRJbnN0YW5jZShpbnN0YW5jZSk7CiAgfQogIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgIHdhc2kuc3RhcnQoaW5zdGFuY2UpOwogIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUgPT0gImZ1bmN0aW9uIikgewogICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgIGlmIChzd2lmdCAmJiBzd2lmdC5tYWluKSB7CiAgICAgIHN3aWZ0Lm1haW4oKTsKICAgIH0gZWxzZSB7CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5tYWluID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5tYWluKCk7CiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndigwLCAwKTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4geyBpbnN0YW5jZSB9Owp9CmZ1bmN0aW9uIGRlZmF1bHRJbnN0YW50aWF0aW9uT3B0aW9ucyhvcHRpb25zKSB7CiAgaWYgKG9wdGlvbnMuYXJncyA9PSBudWxsKSB7CiAgICBvcHRpb25zLmFyZ3MgPSBbIm1haW4ud2FzbSJdOwogIH0KICBjb25zdCBpc05vZGVKcyA9IHR5cGVvZiBwcm9jZXNzICE9PSAidW5kZWZpbmVkIiAmJiBwcm9jZXNzLnJlbGVhc2UubmFtZSA9PT0gIm5vZGUiOwogIGNvbnN0IGlzV2ViQnJvd3NlciA9IHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiOwogIGlmIChpc05vZGVKcykgewogICAgaWYgKCFvcHRpb25zLm9uU3Rkb3V0KSB7CiAgICAgIG9wdGlvbnMub25TdGRvdXQgPSAoY2h1bmspID0+IHByb2Nlc3Muc3Rkb3V0LndyaXRlKGNodW5rKTsKICAgIH0KICAgIGlmICghb3B0aW9ucy5vblN0ZGVycikgewogICAgICBvcHRpb25zLm9uU3RkZXJyID0gKGNodW5rKSA9PiBwcm9jZXNzLnN0ZGVyci53cml0ZShjaHVuayk7CiAgICB9CiAgfSBlbHNlIGlmIChpc1dlYkJyb3dzZXIpIHsKICAgIGlmICghb3B0aW9ucy5vblN0ZG91dExpbmUpIHsKICAgICAgb3B0aW9ucy5vblN0ZG91dExpbmUgPSAobGluZSkgPT4gY29uc29sZS5sb2cobGluZSk7CiAgICB9CiAgICBpZiAoIW9wdGlvbnMub25TdGRlcnJMaW5lKSB7CiAgICAgIG9wdGlvbnMub25TdGRlcnJMaW5lID0gKGxpbmUpID0+IGNvbnNvbGUud2FybihsaW5lKTsKICAgIH0KICB9CiAgcmV0dXJuIG9wdGlvbnM7Cn0KCi8vIGVudHJ5cG9pbnQvZGV2LnRzCnZhciBzb2NrZXQgPSBuZXcgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdChgd3M6Ly8ke2xvY2F0aW9uLmhvc3R9L3dhdGNoZXJgKTsKc29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCAobWVzc2FnZSkgPT4gewogIGlmIChtZXNzYWdlLmRhdGEgPT09ICJyZWxvYWQiKSB7CiAgICBsb2NhdGlvbi5yZWxvYWQoKTsKICB9Cn0pOwp2YXIgc3RhcnRXYXNpVGFzayA9IGFzeW5jICgpID0+IHsKICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKCIvbWFpbi53YXNtIik7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICB9IGNhdGNoIHsKICAgIGNvbnNvbGUubG9nKCJKYXZhU2NyaXB0S2l0IG1vZHVsZSBub3QgYXZhaWxhYmxlLCBydW5uaW5nIHdpdGhvdXQgSmF2YVNjcmlwdEtpdCBydW50aW1lLiIpOwogIH0KICBhd2FpdCBpbnN0YW50aWF0ZSh7CiAgICBtb2R1bGU6IGF3YWl0IFdlYkFzc2VtYmx5LmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpLAogICAgb25TdGRvdXQoY2h1bmspIHsKICAgICAgY29uc3Qga2luZEJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcigyKTsKICAgICAgbmV3IERhdGFWaWV3KGtpbmRCdWZmZXIpLnNldFVpbnQxNigwLCAxMDAxLCB0cnVlKTsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IFVpbnQ4QXJyYXkoMiArIGNodW5rLmxlbmd0aCk7CiAgICAgIGJ1ZmZlci5zZXQobmV3IFVpbnQ4QXJyYXkoa2luZEJ1ZmZlciksIDApOwogICAgICBidWZmZXIuc2V0KGNodW5rLCAyKTsKICAgICAgc29ja2V0LnNlbmQoYnVmZmVyKTsKICAgIH0sCiAgICBvblN0ZG91dExpbmUobGluZSkgewogICAgICBjb25zb2xlLmxvZyhsaW5lKTsKICAgIH0sCiAgICBvblN0ZGVycihjaHVuaykgewogICAgICBjb25zdCBraW5kQnVmZmVyID0gbmV3IEFycmF5QnVmZmVyKDIpOwogICAgICBuZXcgRGF0YVZpZXcoa2luZEJ1ZmZlcikuc2V0VWludDE2KDAsIDEwMDIsIHRydWUpOwogICAgICBjb25zdCBidWZmZXIgPSBuZXcgVWludDhBcnJheSgyICsgY2h1bmsubGVuZ3RoKTsKICAgICAgYnVmZmVyLnNldChuZXcgVWludDhBcnJheShraW5kQnVmZmVyKSwgMCk7CiAgICAgIGJ1ZmZlci5zZXQoY2h1bmssIDIpOwogICAgICBzb2NrZXQuc2VuZChidWZmZXIpOwogICAgfSwKICAgIG9uU3RkZXJyTGluZShsaW5lKSB7CiAgICAgIGNvbnNvbGUuZXJyb3IobGluZSk7CiAgICB9LAogICAgU3dpZnRSdW50aW1lOiBydW50aW1lQ29uc3RydWN0b3IKICB9KTsKfTsKZnVuY3Rpb24gaGFuZGxlRXJyb3IoZSkgewogIGlmIChlIGluc3RhbmNlb2YgRXJyb3IpIHsKICAgIGNvbnN0IHN0YWNrID0gZS5zdGFjazsKICAgIGlmIChzdGFjayAhPSBudWxsKSB7CiAgICAgIHNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KHsKICAgICAgICBraW5kOiAic3RhY2tUcmFjZSIsCiAgICAgICAgc3RhY2tUcmFjZTogc3RhY2sKICAgICAgfSkpOwogICAgfQogIH0KfQphc3luYyBmdW5jdGlvbiBtYWluKCkgewogIHRyeSB7CiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigiZXJyb3IiLCAoZXZlbnQpID0+IHsKICAgICAgaGFuZGxlRXJyb3IoZXZlbnQuZXJyb3IpOwogICAgfSk7CiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigidW5oYW5kbGVkcmVqZWN0aW9uIiwgKGV2ZW50KSA9PiB7CiAgICAgIGhhbmRsZUVycm9yKGV2ZW50LnJlYXNvbik7CiAgICB9KTsKICAgIGF3YWl0IHN0YXJ0V2FzaVRhc2soKTsKICB9IGNhdGNoIChlKSB7CiAgICBoYW5kbGVFcnJvcihlKTsKICAgIHRocm93IGU7CiAgfQp9Cm1haW4oKTsKLyohCiAqIFJlY29ubmVjdGluZyBXZWJTb2NrZXQKICogYnkgUGVkcm8gTGFkYXJpYSA8cGVkcm8ubGFkYXJpYUBnbWFpbC5jb20+CiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9wbGFkYXJpYS9yZWNvbm5lY3Rpbmctd2Vic29ja2V0CiAqIExpY2Vuc2UgTUlUCiAqLwovKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UKdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUKTGljZW5zZSBhdCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKClRISVMgQ09ERSBJUyBQUk9WSURFRCBPTiBBTiAqQVMgSVMqIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBBTlkgSU1QTElFRApXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLApNRVJDSEFOVEFCTElUWSBPUiBOT04tSU5GUklOR0VNRU5ULgoKU2VlIHRoZSBBcGFjaGUgVmVyc2lvbiAyLjAgTGljZW5zZSBmb3Igc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zCmFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8K")! + public static let bundle: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpX2RlZnMuanMKdmFyIENMT0NLSURfUkVBTFRJTUUgPSAwOwp2YXIgQ0xPQ0tJRF9NT05PVE9OSUMgPSAxOwp2YXIgRVJSTk9fU1VDQ0VTUyA9IDA7CnZhciBFUlJOT19CQURGID0gODsKdmFyIEVSUk5PX0VYSVNUID0gMjA7CnZhciBFUlJOT19JTlZBTCA9IDI4Owp2YXIgRVJSTk9fSVNESVIgPSAzMTsKdmFyIEVSUk5PX05BTUVUT09MT05HID0gMzc7CnZhciBFUlJOT19OT0VOVCA9IDQ0Owp2YXIgRVJSTk9fTk9TWVMgPSA1MjsKdmFyIEVSUk5PX05PVERJUiA9IDU0Owp2YXIgRVJSTk9fTk9URU1QVFkgPSA1NTsKdmFyIEVSUk5PX05PVFNVUCA9IDU4Owp2YXIgRVJSTk9fUEVSTSA9IDYzOwp2YXIgRVJSTk9fTk9UQ0FQQUJMRSA9IDc2Owp2YXIgUklHSFRTX0ZEX0RBVEFTWU5DID0gMSA8PCAwOwp2YXIgUklHSFRTX0ZEX1JFQUQgPSAxIDw8IDE7CnZhciBSSUdIVFNfRkRfU0VFSyA9IDEgPDwgMjsKdmFyIFJJR0hUU19GRF9GRFNUQVRfU0VUX0ZMQUdTID0gMSA8PCAzOwp2YXIgUklHSFRTX0ZEX1NZTkMgPSAxIDw8IDQ7CnZhciBSSUdIVFNfRkRfVEVMTCA9IDEgPDwgNTsKdmFyIFJJR0hUU19GRF9XUklURSA9IDEgPDwgNjsKdmFyIFJJR0hUU19GRF9BRFZJU0UgPSAxIDw8IDc7CnZhciBSSUdIVFNfRkRfQUxMT0NBVEUgPSAxIDw8IDg7CnZhciBSSUdIVFNfUEFUSF9DUkVBVEVfRElSRUNUT1JZID0gMSA8PCA5Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0ZJTEUgPSAxIDw8IDEwOwp2YXIgUklHSFRTX1BBVEhfTElOS19TT1VSQ0UgPSAxIDw8IDExOwp2YXIgUklHSFRTX1BBVEhfTElOS19UQVJHRVQgPSAxIDw8IDEyOwp2YXIgUklHSFRTX1BBVEhfT1BFTiA9IDEgPDwgMTM7CnZhciBSSUdIVFNfRkRfUkVBRERJUiA9IDEgPDwgMTQ7CnZhciBSSUdIVFNfUEFUSF9SRUFETElOSyA9IDEgPDwgMTU7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfU09VUkNFID0gMSA8PCAxNjsKdmFyIFJJR0hUU19QQVRIX1JFTkFNRV9UQVJHRVQgPSAxIDw8IDE3Owp2YXIgUklHSFRTX1BBVEhfRklMRVNUQVRfR0VUID0gMSA8PCAxODsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9TSVpFID0gMSA8PCAxOTsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjA7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfR0VUID0gMSA8PCAyMTsKdmFyIFJJR0hUU19GRF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMjI7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1RJTUVTID0gMSA8PCAyMzsKdmFyIFJJR0hUU19QQVRIX1NZTUxJTksgPSAxIDw8IDI0Owp2YXIgUklHSFRTX1BBVEhfUkVNT1ZFX0RJUkVDVE9SWSA9IDEgPDwgMjU7CnZhciBSSUdIVFNfUEFUSF9VTkxJTktfRklMRSA9IDEgPDwgMjY7CnZhciBSSUdIVFNfUE9MTF9GRF9SRUFEV1JJVEUgPSAxIDw8IDI3Owp2YXIgUklHSFRTX1NPQ0tfU0hVVERPV04gPSAxIDw8IDI4Owp2YXIgSW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBJb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChJb3ZlYy5yZWFkX2J5dGVzKHZpZXcsIHB0ciArIDggKiBpKSk7CiAgICB9CiAgICByZXR1cm4gaW92ZWNzOwogIH0KfTsKdmFyIENpb3ZlYyA9IGNsYXNzIHsKICBzdGF0aWMgcmVhZF9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIGNvbnN0IGlvdmVjID0gbmV3IENpb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChDaW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBXSEVOQ0VfU0VUID0gMDsKdmFyIFdIRU5DRV9DVVIgPSAxOwp2YXIgV0hFTkNFX0VORCA9IDI7CnZhciBGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFID0gMjsKdmFyIEZJTEVUWVBFX0RJUkVDVE9SWSA9IDM7CnZhciBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgPSA0Owp2YXIgRGlyZW50ID0gY2xhc3MgewogIGhlYWRfbGVuZ3RoKCkgewogICAgcmV0dXJuIDI0OwogIH0KICBuYW1lX2xlbmd0aCgpIHsKICAgIHJldHVybiB0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGg7CiAgfQogIHdyaXRlX2hlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIsIHRoaXMuZF9uZXh0LCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDgsIHRoaXMuZF9pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50MzIocHRyICsgMTYsIHRoaXMuZGlyX25hbWUubGVuZ3RoLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDgocHRyICsgMjAsIHRoaXMuZF90eXBlKTsKICB9CiAgd3JpdGVfbmFtZV9ieXRlcyh2aWV3OCwgcHRyLCBidWZfbGVuKSB7CiAgICB2aWV3OC5zZXQodGhpcy5kaXJfbmFtZS5zbGljZSgwLCBNYXRoLm1pbih0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGgsIGJ1Zl9sZW4pKSwgcHRyKTsKICB9CiAgY29uc3RydWN0b3IobmV4dF9jb29raWUsIG5hbWUsIHR5cGUpIHsKICAgIHRoaXMuZF9pbm8gPSAwbjsKICAgIGNvbnN0IGVuY29kZWRfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICAgIHRoaXMuZF9uZXh0ID0gbmV4dF9jb29raWU7CiAgICB0aGlzLmRfbmFtbGVuID0gZW5jb2RlZF9uYW1lLmJ5dGVMZW5ndGg7CiAgICB0aGlzLmRfdHlwZSA9IHR5cGU7CiAgICB0aGlzLmRpcl9uYW1lID0gZW5jb2RlZF9uYW1lOwogIH0KfTsKdmFyIEZERkxBR1NfQVBQRU5EID0gMSA8PCAwOwp2YXIgRkRGTEFHU19EU1lOQyA9IDEgPDwgMTsKdmFyIEZERkxBR1NfTk9OQkxPQ0sgPSAxIDw8IDI7CnZhciBGREZMQUdTX1JTWU5DID0gMSA8PCAzOwp2YXIgRkRGTEFHU19TWU5DID0gMSA8PCA0Owp2YXIgRmRzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50OChwdHIsIHRoaXMuZnNfZmlsZXR5cGUpOwogICAgdmlldy5zZXRVaW50MTYocHRyICsgMiwgdGhpcy5mc19mbGFncywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmZzX3JpZ2h0c19iYXNlLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDE2LCB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgZmxhZ3MpIHsKICAgIHRoaXMuZnNfcmlnaHRzX2Jhc2UgPSAwbjsKICAgIHRoaXMuZnNfcmlnaHRzX2luaGVyaXRlZCA9IDBuOwogICAgdGhpcy5mc19maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5mc19mbGFncyA9IGZsYWdzOwogIH0KfTsKdmFyIEZTVEZMQUdTX0FUSU0gPSAxIDw8IDA7CnZhciBGU1RGTEFHU19BVElNX05PVyA9IDEgPDwgMTsKdmFyIEZTVEZMQUdTX01USU0gPSAxIDw8IDI7CnZhciBGU1RGTEFHU19NVElNX05PVyA9IDEgPDwgMzsKdmFyIE9GTEFHU19DUkVBVCA9IDEgPDwgMDsKdmFyIE9GTEFHU19ESVJFQ1RPUlkgPSAxIDw8IDE7CnZhciBPRkxBR1NfRVhDTCA9IDEgPDwgMjsKdmFyIE9GTEFHU19UUlVOQyA9IDEgPDwgMzsKdmFyIEZpbGVzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRldiwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmlubywgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDE2LCB0aGlzLmZpbGV0eXBlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDI0LCB0aGlzLm5saW5rLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDMyLCB0aGlzLnNpemUsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgMzgsIHRoaXMuYXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA0NiwgdGhpcy5tdGltLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDUyLCB0aGlzLmN0aW0sIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgc2l6ZSkgewogICAgdGhpcy5kZXYgPSAwbjsKICAgIHRoaXMuaW5vID0gMG47CiAgICB0aGlzLm5saW5rID0gMG47CiAgICB0aGlzLmF0aW0gPSAwbjsKICAgIHRoaXMubXRpbSA9IDBuOwogICAgdGhpcy5jdGltID0gMG47CiAgICB0aGlzLmZpbGV0eXBlID0gZmlsZXR5cGU7CiAgICB0aGlzLnNpemUgPSBzaXplOwogIH0KfTsKdmFyIEVWRU5UUldGTEFHU19GRF9SRUFEV1JJVEVfSEFOR1VQID0gMSA8PCAwOwp2YXIgU1VCQ0xPQ0tGTEFHU19TVUJTQ1JJUFRJT05fQ0xPQ0tfQUJTVElNRSA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9QRUVLID0gMSA8PCAwOwp2YXIgUklGTEFHU19SRUNWX1dBSVRBTEwgPSAxIDw8IDE7CnZhciBST0ZMQUdTX1JFQ1ZfREFUQV9UUlVOQ0FURUQgPSAxIDw8IDA7CnZhciBTREZMQUdTX1JEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19XUiA9IDEgPDwgMTsKdmFyIFBSRU9QRU5UWVBFX0RJUiA9IDA7CnZhciBQcmVzdGF0RGlyID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50MzIocHRyLCB0aGlzLnByX25hbWUuYnl0ZUxlbmd0aCwgdHJ1ZSk7CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUpIHsKICAgIHRoaXMucHJfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICB9Cn07CnZhciBQcmVzdGF0ID0gY2xhc3MgewogIHN0YXRpYyBkaXIobmFtZSkgewogICAgY29uc3QgcHJlc3RhdCA9IG5ldyBQcmVzdGF0KCk7CiAgICBwcmVzdGF0LnRhZyA9IFBSRU9QRU5UWVBFX0RJUjsKICAgIHByZXN0YXQuaW5uZXIgPSBuZXcgUHJlc3RhdERpcihuYW1lKTsKICAgIHJldHVybiBwcmVzdGF0OwogIH0KICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy50YWcsIHRydWUpOwogICAgdGhpcy5pbm5lci53cml0ZV9ieXRlcyh2aWV3LCBwdHIgKyA0KTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2RlYnVnLmpzCnZhciBEZWJ1ZyA9IGNsYXNzIERlYnVnMiB7CiAgZW5hYmxlKGVuYWJsZWQpIHsKICAgIHRoaXMubG9nID0gY3JlYXRlTG9nZ2VyKGVuYWJsZWQgPT09IHZvaWQgMCA/IHRydWUgOiBlbmFibGVkLCB0aGlzLnByZWZpeCk7CiAgfQogIGdldCBlbmFibGVkKCkgewogICAgcmV0dXJuIHRoaXMuaXNFbmFibGVkOwogIH0KICBjb25zdHJ1Y3Rvcihpc0VuYWJsZWQpIHsKICAgIHRoaXMuaXNFbmFibGVkID0gaXNFbmFibGVkOwogICAgdGhpcy5wcmVmaXggPSAid2FzaToiOwogICAgdGhpcy5lbmFibGUoaXNFbmFibGVkKTsKICB9Cn07CmZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihlbmFibGVkLCBwcmVmaXgpIHsKICBpZiAoZW5hYmxlZCkgewogICAgY29uc3QgYSA9IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSwgIiVjJXMiLCAiY29sb3I6ICMyNjVCQTAiLCBwcmVmaXgpOwogICAgcmV0dXJuIGE7CiAgfSBlbHNlIHsKICAgIHJldHVybiAoKSA9PiB7CiAgICB9OwogIH0KfQp2YXIgZGVidWcgPSBuZXcgRGVidWcoZmFsc2UpOwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpLmpzCnZhciBXQVNJUHJvY0V4aXQgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKICBjb25zdHJ1Y3Rvcihjb2RlKSB7CiAgICBzdXBlcigiZXhpdCB3aXRoIGV4aXQgY29kZSAiICsgY29kZSk7CiAgICB0aGlzLmNvZGUgPSBjb2RlOwogIH0KfTsKdmFyIFdBU0kgPSBjbGFzcyBXQVNJMiB7CiAgc3RhcnQoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgdHJ5IHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQoKTsKICAgICAgcmV0dXJuIDA7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIGlmIChlIGluc3RhbmNlb2YgV0FTSVByb2NFeGl0KSB7CiAgICAgICAgcmV0dXJuIGUuY29kZTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aHJvdyBlOwogICAgICB9CiAgICB9CiAgfQogIGluaXRpYWxpemUoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgaWYgKGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUpIHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSgpOwogICAgfQogIH0KICBjb25zdHJ1Y3RvcihhcmdzLCBlbnYsIGZkcywgb3B0aW9ucyA9IHt9KSB7CiAgICB0aGlzLmFyZ3MgPSBbXTsKICAgIHRoaXMuZW52ID0gW107CiAgICB0aGlzLmZkcyA9IFtdOwogICAgZGVidWcuZW5hYmxlKG9wdGlvbnMuZGVidWcpOwogICAgdGhpcy5hcmdzID0gYXJnczsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2ZpbGVzdGF0X2dldChmZCwgZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGZkX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIGRlYnVnLmxvZyhwYXRoKTsKICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfcmVhZGxpbmsocGF0aCk7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVuYW1lKGZkLCBvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgbmV3X2ZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGxldCB7IHJldCwgaW5vZGVfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmsob2xkX3BhdGgpOwogICAgICAgIGlmIChpbm9kZV9vYmogPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgdHJ1ZSk7CiAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICBpZiAoc2VsZi5mZHNbZmRdLnBhdGhfbGluayhvbGRfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKSAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIHRocm93ICJwYXRoX2xpbmsgc2hvdWxkIGFsd2F5cyByZXR1cm4gc3VjY2VzcyB3aGVuIHJlbGlua2luZyBhbiBpbm9kZSBiYWNrIHRvIHRoZSBvcmlnaW5hbCBwbGFjZSI7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfc3ltbGluayhvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF91bmxpbmtfZmlsZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwb2xsX29uZW9mZihpbl8sIG91dCwgbnN1YnNjcmlwdGlvbnMpIHsKICAgICAgdGhyb3cgImFzeW5jIGlvIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgcHJvY19leGl0KGV4aXRfY29kZSkgewogICAgICB0aHJvdyBuZXcgV0FTSVByb2NFeGl0KGV4aXRfY29kZSk7CiAgICB9LCBwcm9jX3JhaXNlKHNpZykgewogICAgICB0aHJvdyAicmFpc2VkIHNpZ25hbCAiICsgc2lnOwogICAgfSwgc2NoZWRfeWllbGQoKSB7CiAgICB9LCByYW5kb21fZ2V0KGJ1ZiwgYnVmX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmX2xlbjsgaSsrKSB7CiAgICAgICAgYnVmZmVyOFtidWYgKyBpXSA9IE1hdGgucmFuZG9tKCkgKiAyNTYgfCAwOwogICAgICB9CiAgICB9LCBzb2NrX3JlY3YoZmQsIHJpX2RhdGEsIHJpX2ZsYWdzKSB7CiAgICAgIHRocm93ICJzb2NrZXRzIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgc29ja19zZW5kKGZkLCBzaV9kYXRhLCBzaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2h1dGRvd24oZmQsIGhvdykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfYWNjZXB0KGZkLCBmbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0gfTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZkLmpzCnZhciBGZCA9IGNsYXNzIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfY2xvc2UoKSB7CiAgICByZXR1cm4gMDsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBmZHN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBwcmVzdGF0OiBudWxsIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRpcmVudDogbnVsbCB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9zeW5jKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9saW5rKHBhdGgsIGlub2RlLCBhbGxvd19kaXIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rKHBhdGgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aCwgZGlyZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9yZWFkbGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9yZW5hbWUob2xkX3BhdGgsIG5ld19mZCwgbmV3X3BhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9Cn07CnZhciBJbm9kZSA9IGNsYXNzIHsKfTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3QvZnNfbWVtLmpzCnZhciBPcGVuRmlsZSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBvZmZzZXQgKyBsZW4pIHsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIGxlbikpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIDApIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IHNpemUpIHsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheSh0aGlzLmZpbGUuZGF0YS5idWZmZXIuc2xpY2UoMCwgTnVtYmVyKHNpemUpKSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihzaXplKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcih0aGlzLmZpbGVfcG9zKSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KHNsaWNlLmxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIob2Zmc2V0KSwgTnVtYmVyKG9mZnNldCArIEJpZ0ludChzaXplKSkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICBsZXQgY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICBzd2l0Y2ggKHdoZW5jZSkgewogICAgICBjYXNlIFdIRU5DRV9TRVQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0NVUjoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IHRoaXMuZmlsZV9wb3MgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0VORDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IEJpZ0ludCh0aGlzLmZpbGUuZGF0YS5ieXRlTGVuZ3RoKSArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICBpZiAoY2FsY3VsYXRlZF9vZmZzZXQgPCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIHRoaXMuZmlsZV9wb3MgPSBjYWxjdWxhdGVkX29mZnNldDsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIodGhpcy5maWxlX3BvcykpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKG9mZnNldCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZmlsZS5zdGF0KCkgfTsKICB9CiAgY29uc3RydWN0b3IoZmlsZSkgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZmlsZV9wb3MgPSAwbjsKICAgIHRoaXMuZmlsZSA9IGZpbGU7CiAgfQp9Owp2YXIgT3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMCkgfTsKICB9CiAgZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKSB7CiAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICBkZWJ1Zy5sb2coInJlYWRkaXJfc2luZ2xlIiwgY29va2llKTsKICAgICAgZGVidWcubG9nKGNvb2tpZSwgdGhpcy5kaXIuY29udGVudHMua2V5cygpKTsKICAgIH0KICAgIGlmIChjb29raWUgPT0gMG4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMW4sICIuIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfSBlbHNlIGlmIChjb29raWUgPT0gMW4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMm4sICIuLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0KICAgIGlmIChjb29raWUgPj0gQmlnSW50KHRoaXMuZGlyLmNvbnRlbnRzLnNpemUpICsgMm4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IFtuYW1lLCBlbnRyeV0gPSBBcnJheS5mcm9tKHRoaXMuZGlyLmNvbnRlbnRzLmVudHJpZXMoKSlbTnVtYmVyKGNvb2tpZSAtIDJuKV07CiAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbmV3IERpcmVudChjb29raWUgKyAxbiwgbmFtZSwgZW50cnkuc3RhdCgpLmZpbGV0eXBlKSB9OwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX2VyciwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX2VyciwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBmaWxlc3RhdDogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogZW50cnkuc3RhdCgpIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGhfc3RyLCBkaXJmbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGhfc3RyLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBsZXQgeyByZXQsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfZW50cnlfZm9yX3BhdGgocGF0aCk7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICBpZiAocmV0ICE9IEVSUk5PX05PRU5UKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0LCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19DUkVBVCkgPT0gT0ZMQUdTX0NSRUFUKSB7CiAgICAgICAgY29uc3QgeyByZXQ6IHJldDIsIGVudHJ5OiBuZXdfZW50cnkgfSA9IHRoaXMuZGlyLmNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkpOwogICAgICAgIGlmIChuZXdfZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiByZXQyLCBmZF9vYmo6IG51bGwgfTsKICAgICAgICB9CiAgICAgICAgZW50cnkgPSBuZXdfZW50cnk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoKG9mbGFncyAmIE9GTEFHU19FWENMKSA9PSBPRkxBR1NfRVhDTCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4gZW50cnkucGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoLCBPRkxBR1NfQ1JFQVQgfCBPRkxBR1NfRElSRUNUT1JZLCAwbiwgMG4sIDApLnJldDsKICB9CiAgcGF0aF9saW5rKHBhdGhfc3RyLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgY29uc3Qgc291cmNlX2lzX2RpciA9IGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGNvbnN0IHRhcmdldF9pc19kaXIgPSBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBpZiAoc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgaWYgKGFsbG93X2RpciAmJiBlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgewogICAgICAgICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgPT0gMCkgewogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYgKHNvdXJjZV9pc19kaXIgJiYgIXRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgICB9IGVsc2UgaWYgKCFzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICAgIH0gZWxzZSBpZiAoaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFKSB7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICB9CiAgICB9CiAgICBpZiAoIWFsbG93X2RpciAmJiBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19QRVJNOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLnNldChmaWxlbmFtZSwgaW5vZGUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfdW5saW5rKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlID09PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgfHwgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgIH0KICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplICE9PSAwKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgIH0KICAgIGlmICghcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZGlyLnN0YXQoKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGNvbnN0cnVjdG9yKGRpcikgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGlyID0gZGlyOwogIH0KfTsKdmFyIFByZW9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIE9wZW5EaXJlY3RvcnkgewogIGZkX3ByZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBwcmVzdGF0OiBQcmVzdGF0LmRpcih0aGlzLnByZXN0YXRfbmFtZSkgfTsKICB9CiAgY29uc3RydWN0b3IobmFtZSwgY29udGVudHMpIHsKICAgIHN1cGVyKG5ldyBEaXJlY3RvcnkoY29udGVudHMpKTsKICAgIHRoaXMucHJlc3RhdF9uYW1lID0gbmFtZTsKICB9Cn07CnZhciBGaWxlID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICBpZiAodGhpcy5yZWFkb25seSAmJiAoZnNfcmlnaHRzX2Jhc2UgJiBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgPT0gQmlnSW50KFJJR0hUU19GRF9XUklURSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX1RSVU5DKSA9PSBPRkxBR1NfVFJVTkMpIHsKICAgICAgaWYgKHRoaXMucmVhZG9ubHkpCiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoW10pOwogICAgfQogICAgY29uc3QgZmlsZSA9IG5ldyBPcGVuRmlsZSh0aGlzKTsKICAgIGlmIChmZF9mbGFncyAmIEZERkxBR1NfQVBQRU5EKQogICAgICBmaWxlLmZkX3NlZWsoMG4sIFdIRU5DRV9FTkQpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IGZpbGUgfTsKICB9CiAgZ2V0IHNpemUoKSB7CiAgICByZXR1cm4gQmlnSW50KHRoaXMuZGF0YS5ieXRlTGVuZ3RoKTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCB0aGlzLnNpemUpOwogIH0KICBjb25zdHJ1Y3RvcihkYXRhLCBvcHRpb25zKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7CiAgICB0aGlzLnJlYWRvbmx5ID0gISFvcHRpb25zPy5yZWFkb25seTsKICB9Cn07CnZhciBQYXRoID0gY2xhc3MgUGF0aDIgewogIHN0YXRpYyBmcm9tKHBhdGgpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aC5lbmRzV2l0aCgiLyIpOwogICAgaWYgKHBhdGguc3RhcnRzV2l0aCgiLyIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgfQogICAgaWYgKHBhdGguaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5zcGxpdCgiLyIpKSB7CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIiIHx8IGNvbXBvbmVudCA9PT0gIi4iKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKGNvbXBvbmVudCA9PT0gIi4uIikgewogICAgICAgIGlmIChzZWxmLnBhcnRzLnBvcCgpID09IHZvaWQgMCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIHNlbGYucGFydHMucHVzaChjb21wb25lbnQpOwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXRoOiBzZWxmIH07CiAgfQogIHRvX3BhdGhfc3RyaW5nKCkgewogICAgbGV0IHMgPSB0aGlzLnBhcnRzLmpvaW4oIi8iKTsKICAgIGlmICh0aGlzLmlzX2RpcikgewogICAgICBzICs9ICIvIjsKICAgIH0KICAgIHJldHVybiBzOwogIH0KICBjb25zdHJ1Y3RvcigpIHsKICAgIHRoaXMucGFydHMgPSBbXTsKICAgIHRoaXMuaXNfZGlyID0gZmFsc2U7CiAgfQp9Owp2YXIgRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogbmV3IE9wZW5EaXJlY3RvcnkodGhpcykgfTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwbik7CiAgfQogIGdldF9lbnRyeV9mb3JfcGF0aChwYXRoKSB7CiAgICBsZXQgZW50cnkgPSB0aGlzOwogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGFsbG93X3VuZGVmaW5lZCkgewogICAgY29uc3QgZmlsZW5hbWUgPSBwYXRoLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogZW50cnlfcmV0LCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKCEocGFyZW50X2VudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IGVudHJ5ID0gcGFyZW50X2VudHJ5LmNvbnRlbnRzLmdldChmaWxlbmFtZSk7CiAgICBpZiAoZW50cnkgPT09IHZvaWQgMCkgewogICAgICBpZiAoIWFsbG93X3VuZGVmaW5lZCkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9OwogIH0KICBjcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIGlzX2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgZGVidWcubG9nKCJjcmVhdGUiLCBwYXRoKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvaW5kZXguanMKZnVuY3Rpb24gcGFyc2VJbXBvcnRzKG1vZHVsZUJ5dGVzKSB7CiAgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcyk7CiAgfSBlbHNlIGlmIChtb2R1bGVCeXRlcy5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcy5idWZmZXIpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoIkFyZ3VtZW50IG11c3QgYmUgYSBidWZmZXIgc291cmNlLCBsaWtlIFVpbnQ4QXJyYXkgb3IgQXJyYXlCdWZmZXIiKTsKICB9CiAgY29uc3QgcGFyc2VTdGF0ZSA9IG5ldyBQYXJzZVN0YXRlKG1vZHVsZUJ5dGVzKTsKICBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpOwogIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKTsKICBjb25zdCB0eXBlcyA9IFtdOwogIGNvbnN0IGltcG9ydHMgPSBbXTsKICB3aGlsZSAocGFyc2VTdGF0ZS5oYXNNb3JlQnl0ZXMoKSkgewogICAgY29uc3Qgc2VjdGlvbklkID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgY29uc3Qgc2VjdGlvblNpemUgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgc3dpdGNoIChzZWN0aW9uSWQpIHsKICAgICAgY2FzZSAxOiB7CiAgICAgICAgY29uc3QgdHlwZUNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVDb3VudDsgaSsrKSB7CiAgICAgICAgICB0eXBlcy5wdXNoKHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAyOiB7CiAgICAgICAgY29uc3QgaW1wb3J0Q291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW1wb3J0Q291bnQ7IGkrKykgewogICAgICAgICAgY29uc3QgbW9kdWxlID0gcGFyc2VTdGF0ZS5yZWFkTmFtZSgpOwogICAgICAgICAgY29uc3QgbmFtZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJmdW5jdGlvbiIsIHR5cGU6IHR5cGVzW2luZGV4XSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgIGltcG9ydHMucHVzaCh7IG1vZHVsZSwgbmFtZSwga2luZDogInRhYmxlIiwgdHlwZTogcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJtZW1vcnkiLCB0eXBlOiBwYXJzZUxpbWl0cyhwYXJzZVN0YXRlKSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgIGltcG9ydHMucHVzaCh7IG1vZHVsZSwgbmFtZSwga2luZDogImdsb2JhbCIsIHR5cGU6IHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gaW1wb3J0IGRlc2NyaXB0b3IgdHlwZSAke3R5cGV9YCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbXBvcnRzOwogICAgICB9CiAgICAgIGRlZmF1bHQ6IHsKICAgICAgICBwYXJzZVN0YXRlLnNraXBCeXRlcyhzZWN0aW9uU2l6ZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFtdOwp9CnZhciBQYXJzZVN0YXRlID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG1vZHVsZUJ5dGVzKSB7CiAgICB0aGlzLm1vZHVsZUJ5dGVzID0gbW9kdWxlQnl0ZXM7CiAgICB0aGlzLm9mZnNldCA9IDA7CiAgICB0aGlzLnRleHREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpOwogIH0KICBoYXNNb3JlQnl0ZXMoKSB7CiAgICByZXR1cm4gdGhpcy5vZmZzZXQgPCB0aGlzLm1vZHVsZUJ5dGVzLmxlbmd0aDsKICB9CiAgcmVhZEJ5dGUoKSB7CiAgICByZXR1cm4gdGhpcy5tb2R1bGVCeXRlc1t0aGlzLm9mZnNldCsrXTsKICB9CiAgc2tpcEJ5dGVzKGNvdW50KSB7CiAgICB0aGlzLm9mZnNldCArPSBjb3VudDsKICB9CiAgcmVhZFVuc2lnbmVkTEVCMTI4KCkgewogICAgbGV0IHJlc3VsdCA9IDA7CiAgICBsZXQgc2hpZnQgPSAwOwogICAgbGV0IGJ5dGU7CiAgICBkbyB7CiAgICAgIGJ5dGUgPSB0aGlzLnJlYWRCeXRlKCk7CiAgICAgIHJlc3VsdCB8PSAoYnl0ZSAmIDEyNykgPDwgc2hpZnQ7CiAgICAgIHNoaWZ0ICs9IDc7CiAgICB9IHdoaWxlIChieXRlICYgMTI4KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfQogIHJlYWROYW1lKCkgewogICAgY29uc3QgbmFtZUxlbmd0aCA9IHRoaXMucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICBjb25zdCBuYW1lQnl0ZXMgPSB0aGlzLm1vZHVsZUJ5dGVzLnNsaWNlKHRoaXMub2Zmc2V0LCB0aGlzLm9mZnNldCArIG5hbWVMZW5ndGgpOwogICAgY29uc3QgbmFtZSA9IHRoaXMudGV4dERlY29kZXIuZGVjb2RlKG5hbWVCeXRlcyk7CiAgICB0aGlzLm9mZnNldCArPSBuYW1lTGVuZ3RoOwogICAgcmV0dXJuIG5hbWU7CiAgfQogIGFzc2VydEJ5dGVzKGV4cGVjdGVkKSB7CiAgICBjb25zdCBiYXNlT2Zmc2V0ID0gdGhpcy5vZmZzZXQ7CiAgICBjb25zdCBleHBlY3RlZExlbmd0aCA9IGV4cGVjdGVkLmxlbmd0aDsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwZWN0ZWRMZW5ndGg7IGkrKykgewogICAgICBpZiAodGhpcy5tb2R1bGVCeXRlc1tiYXNlT2Zmc2V0ICsgaV0gIT09IGV4cGVjdGVkW2ldKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSBhdCBvZmZzZXQgJHtiYXNlT2Zmc2V0fWApOwogICAgICB9CiAgICB9CiAgICB0aGlzLm9mZnNldCArPSBleHBlY3RlZExlbmd0aDsKICB9Cn07CmZ1bmN0aW9uIHBhcnNlTWFnaWNOdW1iZXIocGFyc2VTdGF0ZSkgewogIGNvbnN0IGV4cGVjdGVkID0gWzAsIDk3LCAxMTUsIDEwOV07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VWZXJzaW9uKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFsxLCAwLCAwLCAwXTsKICBwYXJzZVN0YXRlLmFzc2VydEJ5dGVzKGV4cGVjdGVkKTsKfQpmdW5jdGlvbiBwYXJzZVRhYmxlVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgZWxlbWVudFR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgbGV0IGVsZW1lbnQ7CiAgc3dpdGNoIChlbGVtZW50VHlwZSkgewogICAgY2FzZSAxMTI6CiAgICAgIGVsZW1lbnQgPSAiZnVuY3JlZiI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAxMTE6CiAgICAgIGVsZW1lbnQgPSAiZXh0ZXJucmVmIjsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdGFibGUgZWxlbWVudCB0eXBlICR7ZWxlbWVudFR5cGV9YCk7CiAgfQogIGNvbnN0IHsgbWluaW11bSwgbWF4aW11bSB9ID0gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSk7CiAgaWYgKG1heGltdW0pIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0sIG1heGltdW0gfTsKICB9IGVsc2UgewogICAgcmV0dXJuIHsgZWxlbWVudCwgbWluaW11bSB9OwogIH0KfQpmdW5jdGlvbiBwYXJzZUxpbWl0cyhwYXJzZVN0YXRlKSB7CiAgY29uc3QgZmxhZ3MgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgY29uc3QgbWluaW11bSA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgY29uc3QgaGFzTWF4aW11bSA9IGZsYWdzICYgMTsKICBjb25zdCBzaGFyZWQgPSAoZmxhZ3MgJiAyKSAhPT0gMDsKICBjb25zdCBpc01lbW9yeTY0ID0gKGZsYWdzICYgNCkgIT09IDA7CiAgY29uc3QgaW5kZXggPSBpc01lbW9yeTY0ID8gImk2NCIgOiAiaTMyIjsKICBpZiAoaGFzTWF4aW11bSkgewogICAgY29uc3QgbWF4aW11bSA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4LCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IG1pbmltdW0sIHNoYXJlZCwgaW5kZXggfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VHbG9iYWxUeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCB2YWx1ZSA9IHBhcnNlVmFsdWVUeXBlKHBhcnNlU3RhdGUpOwogIGNvbnN0IG11dGFibGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCkgPT09IDE7CiAgcmV0dXJuIHsgdmFsdWUsIG11dGFibGUgfTsKfQpmdW5jdGlvbiBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdHlwZSA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgMTI3OgogICAgICByZXR1cm4gImkzMiI7CiAgICBjYXNlIDEyNjoKICAgICAgcmV0dXJuICJpNjQiOwogICAgY2FzZSAxMjU6CiAgICAgIHJldHVybiAiZjMyIjsKICAgIGNhc2UgMTI0OgogICAgICByZXR1cm4gImY2NCI7CiAgICBjYXNlIDExMjoKICAgICAgcmV0dXJuICJmdW5jcmVmIjsKICAgIGNhc2UgMTExOgogICAgICByZXR1cm4gImV4dGVybnJlZiI7CiAgICBjYXNlIDEyMzoKICAgICAgcmV0dXJuICJ2MTI4IjsKICAgIGRlZmF1bHQ6CiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB2YWx1ZSB0eXBlICR7dHlwZX1gKTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VGdW5jdGlvblR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZvcm0gPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgaWYgKGZvcm0gIT09IDk2KSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGZ1bmN0aW9uIHR5cGUgZm9ybSAweDYwLCBnb3QgJHtmb3JtfWApOwogIH0KICBjb25zdCBwYXJhbWV0ZXJzID0gW107CiAgY29uc3QgcGFyYW1ldGVyQ291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1ldGVyQ291bnQ7IGkrKykgewogICAgcGFyYW1ldGVycy5wdXNoKHBhcnNlVmFsdWVUeXBlKHBhcnNlU3RhdGUpKTsKICB9CiAgY29uc3QgcmVzdWx0cyA9IFtdOwogIGNvbnN0IHJlc3VsdENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdENvdW50OyBpKyspIHsKICAgIHJlc3VsdHMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIHJldHVybiB7IHBhcmFtZXRlcnMsIHJlc3VsdHMgfTsKfQoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvcG9seWZpbGwuanMKdmFyIGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQgPSAoKCkgPT4gewogIGNvbnN0IG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoWwogICAgMCwKICAgIDk3LAogICAgMTE1LAogICAgMTA5LAogICAgMSwKICAgIDAsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICA2LAogICAgMSwKICAgIDAsCiAgICAwLAogICAgMiwKICAgIDAsCiAgICAxCiAgXSk7CiAgY29uc3QgbW9kdWxlID0gbmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShtb2R1bGVCeXRlcyk7CiAgY29uc3QgaW1wb3J0cyA9IFdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgY29uc3QgbWVtb3J5SW1wb3J0ID0gaW1wb3J0c1swXTsKICByZXR1cm4gdHlwZW9mIG1lbW9yeUltcG9ydC50eXBlID09PSAib2JqZWN0IjsKfSkoKTsKZnVuY3Rpb24gcG9seWZpbGwoV2ViQXNzZW1ibHkzKSB7CiAgaWYgKGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQpIHsKICAgIHJldHVybiBXZWJBc3NlbWJseTM7CiAgfQogIGNvbnN0IG5ld1dlYkFzc2VtYmx5ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoV2ViQXNzZW1ibHkzKSkgewogICAgbmV3V2ViQXNzZW1ibHlba2V5XSA9IFdlYkFzc2VtYmx5M1trZXldOwogIH0KICBjb25zdCBwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbCA9IFN5bWJvbCgicG9seWZpbGxlZEltcG9ydHNTeW1ib2wiKTsKICBjb25zdCBhc3NpZ25JbXBvcnRzID0gKG1vZHVsZSwgc291cmNlQnl0ZXMpID0+IHsKICAgIG1vZHVsZVtwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbF0gPSBwYXJzZUltcG9ydHMoc291cmNlQnl0ZXMpOwogIH07CiAgY29uc3QgbmV3TW9kdWxlID0gbmV3V2ViQXNzZW1ibHkuTW9kdWxlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICAgIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseTMuTW9kdWxlKGJ5dGVzKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBieXRlcyk7CiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YobW9kdWxlLCBuZXdNb2R1bGUucHJvdG90eXBlKTsKICAgIHJldHVybiBtb2R1bGU7CiAgfTsKICBPYmplY3Quc2V0UHJvdG90eXBlT2YobmV3TW9kdWxlLnByb3RvdHlwZSwgV2ViQXNzZW1ibHkzLk1vZHVsZS5wcm90b3R5cGUpOwogIG5ld1dlYkFzc2VtYmx5LmNvbXBpbGUgPSBhc3luYyAoc291cmNlKSA9PiB7CiAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseTMuY29tcGlsZShzb3VyY2UpOwogICAgYXNzaWduSW1wb3J0cyhtb2R1bGUsIHNvdXJjZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgaWYgKFdlYkFzc2VtYmx5My5jb21waWxlU3RyZWFtaW5nKSB7CiAgICBuZXdXZWJBc3NlbWJseS5jb21waWxlU3RyZWFtaW5nID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNvdXJjZTsKICAgICAgY29uc3QgY2xvbmUgPSByZXNwb25zZS5jbG9uZSgpOwogICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseTMuY29tcGlsZVN0cmVhbWluZyhyZXNwb25zZSk7CiAgICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBuZXcgVWludDhBcnJheShhd2FpdCBjbG9uZS5hcnJheUJ1ZmZlcigpKSk7CiAgICAgIHJldHVybiBtb2R1bGU7CiAgICB9OwogIH0KICBuZXdNb2R1bGUuaW1wb3J0cyA9IChtb2R1bGUpID0+IHsKICAgIGNvbnN0IHBhcnNlZEltcG9ydHMgPSBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdOwogICAgaWYgKCFwYXJzZWRJbXBvcnRzKSB7CiAgICAgIHJldHVybiBXZWJBc3NlbWJseTMuTW9kdWxlLmltcG9ydHMobW9kdWxlKTsKICAgIH0KICAgIHJldHVybiBwYXJzZWRJbXBvcnRzOwogIH07CiAgcmV0dXJuIG5ld1dlYkFzc2VtYmx5Owp9CgovLyBlbnRyeXBvaW50L2ludHJpbnNpY3MudHMKdmFyIFdlYkFzc2VtYmx5MiA9IHBvbHlmaWxsKGdsb2JhbFRoaXMuV2ViQXNzZW1ibHkpOwp2YXIgTGluZURlY29kZXIgPSBjbGFzcyB7CiAgY29uc3RydWN0b3Iob25MaW5lKSB7CiAgICB0aGlzLmRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICB0aGlzLmJ1ZmZlciA9ICIiOwogICAgdGhpcy5vbkxpbmUgPSBvbkxpbmU7CiAgfQogIGRlY29kZXI7CiAgYnVmZmVyOwogIG9uTGluZTsKICBzZW5kKGNodW5rKSB7CiAgICB0aGlzLmJ1ZmZlciArPSB0aGlzLmRlY29kZXIuZGVjb2RlKGNodW5rLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgIGNvbnN0IGxpbmVzID0gdGhpcy5idWZmZXIuc3BsaXQoIlxuIik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykgewogICAgICB0aGlzLm9uTGluZShsaW5lc1tpXSk7CiAgICB9CiAgICB0aGlzLmJ1ZmZlciA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdOwogIH0KfTsKYXN5bmMgZnVuY3Rpb24gaW5zdGFudGlhdGUocmF3T3B0aW9ucywgZXh0cmFXYXNtSW1wb3J0cykgewogIGNvbnN0IG9wdGlvbnMgPSBkZWZhdWx0SW5zdGFudGlhdGlvbk9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0ID0gb3B0aW9ucy5zd2lmdDsKICBpZiAoIXN3aWZ0ICYmIG9wdGlvbnMuU3dpZnRSdW50aW1lKSB7CiAgICBzd2lmdCA9IG5ldyBvcHRpb25zLlN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJncyA9IG9wdGlvbnMuYXJncyB8fCBbXTsKICBjb25zdCBmZHMgPSBbCiAgICBuZXcgT3BlbkZpbGUobmV3IEZpbGUoW10pKSwKICAgIHN0ZG91dCwKICAgIHN0ZGVyciwKICAgIG5ldyBQcmVvcGVuRGlyZWN0b3J5KCIvIiwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSkKICBdOwogIGNvbnN0IGVudnMgPSBvcHRpb25zLmVudiA/IE9iamVjdC5lbnRyaWVzKG9wdGlvbnMuZW52KS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYCR7a2V5fT0ke3ZhbHVlfWApIDogW107CiAgY29uc3Qgd2FzaSA9IG5ldyBXQVNJKGFyZ3MsIGVudnMsIGZkcywgewogICAgZGVidWc6IGZhbHNlCiAgfSk7CiAgY29uc3QgY3JlYXRlV2FzbUltcG9ydE9iamVjdCA9IChleHRyYVdhc21JbXBvcnRzMiwgbW9kdWxlKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QyID0gewogICAgICB3YXNpX3NuYXBzaG90X3ByZXZpZXcxOiB3YXNpLndhc2lJbXBvcnQKICAgIH07CiAgICBpZiAoc3dpZnQpIHsKICAgICAgaW1wb3J0T2JqZWN0Mi5qYXZhc2NyaXB0X2tpdCA9IHN3aWZ0Lndhc21JbXBvcnRzOwogICAgfQogICAgaWYgKGV4dHJhV2FzbUltcG9ydHMyKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzMikgewogICAgICAgIGlmICghaW1wb3J0T2JqZWN0Mlttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0Mlttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHMyW21vZHVsZU5hbWVdKSB7CiAgICAgICAgICBpbXBvcnRPYmplY3QyW21vZHVsZU5hbWVdW2VudHJ5XSA9IGV4dHJhV2FzbUltcG9ydHMyW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgX2ltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Mi5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpKSB7CiAgICAgIGNvbnN0IGltcG9ydEVudHJ5ID0gX2ltcG9ydEVudHJ5OwogICAgICBpZiAoIWltcG9ydE9iamVjdDJbaW1wb3J0RW50cnkubW9kdWxlXSkgewogICAgICAgIGltcG9ydE9iamVjdDJbaW1wb3J0RW50cnkubW9kdWxlXSA9IHt9OwogICAgICB9CiAgICAgIGlmIChpbXBvcnRPYmplY3QyW2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0MltpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbXBvcnRlZCBmdW5jdGlvbiAke2ltcG9ydEVudHJ5Lm1vZHVsZX0uJHtpbXBvcnRFbnRyeS5uYW1lfSBub3QgaW1wbGVtZW50ZWRgKTsKICAgICAgICB9OwogICAgICB9IGVsc2UgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gIm1lbW9yeSIgJiYgaW1wb3J0RW50cnkubW9kdWxlID09ICJlbnYiICYmIGltcG9ydEVudHJ5Lm5hbWUgPT0gIm1lbW9yeSIpIHsKICAgICAgICBjb25zdCB0eXBlID0gaW1wb3J0RW50cnkudHlwZTsKICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0gewogICAgICAgICAgaW5pdGlhbDogdHlwZS5taW5pbXVtLAogICAgICAgICAgbWF4aW11bTogdHlwZS5tYXhpbXVtLAogICAgICAgICAgc2hhcmVkOiB0eXBlLnNoYXJlZAogICAgICAgIH07CiAgICAgICAgaW1wb3J0T2JqZWN0MltpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gbmV3IFdlYkFzc2VtYmx5Mi5NZW1vcnkoZGVzY3JpcHRvcik7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBpbXBvcnRPYmplY3QyOwogIH07CiAgY29uc3QgaW1wb3J0T2JqZWN0ID0gY3JlYXRlV2FzbUltcG9ydE9iamVjdChleHRyYVdhc21JbXBvcnRzLCBvcHRpb25zLm1vZHVsZSk7CiAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBXZWJBc3NlbWJseTIuaW5zdGFudGlhdGUob3B0aW9ucy5tb2R1bGUsIGltcG9ydE9iamVjdCk7CiAgaWYgKHN3aWZ0ICYmIGluc3RhbmNlLmV4cG9ydHMuc3dqc19saWJyYXJ5X3ZlcnNpb24pIHsKICAgIHN3aWZ0LnNldEluc3RhbmNlKGluc3RhbmNlKTsKICB9CiAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9zdGFydCA9PT0gImZ1bmN0aW9uIikgewogICAgd2FzaS5zdGFydChpbnN0YW5jZSk7CiAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICB3YXNpLmluaXRpYWxpemUoaW5zdGFuY2UpOwogICAgaWYgKHN3aWZ0ICYmIHN3aWZ0Lm1haW4pIHsKICAgICAgc3dpZnQubWFpbigpOwogICAgfSBlbHNlIHsKICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLm1haW4gPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2KDAsIDApOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiB7IGluc3RhbmNlIH07Cn0KZnVuY3Rpb24gZGVmYXVsdEluc3RhbnRpYXRpb25PcHRpb25zKG9wdGlvbnMpIHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIGNvbnN0IGlzTm9kZUpzID0gdHlwZW9mIHByb2Nlc3MgIT09ICJ1bmRlZmluZWQiICYmIHByb2Nlc3MucmVsZWFzZS5uYW1lID09PSAibm9kZSI7CiAgY29uc3QgaXNXZWJCcm93c2VyID0gdHlwZW9mIHdpbmRvdyAhPT0gInVuZGVmaW5lZCI7CiAgaWYgKGlzTm9kZUpzKSB7CiAgICBpZiAoIW9wdGlvbnMub25TdGRvdXQpIHsKICAgICAgb3B0aW9ucy5vblN0ZG91dCA9IChjaHVuaykgPT4gcHJvY2Vzcy5zdGRvdXQud3JpdGUoY2h1bmspOwogICAgfQogICAgaWYgKCFvcHRpb25zLm9uU3RkZXJyKSB7CiAgICAgIG9wdGlvbnMub25TdGRlcnIgPSAoY2h1bmspID0+IHByb2Nlc3Muc3RkZXJyLndyaXRlKGNodW5rKTsKICAgIH0KICB9IGVsc2UgaWYgKGlzV2ViQnJvd3NlcikgewogICAgaWYgKCFvcHRpb25zLm9uU3Rkb3V0TGluZSkgewogICAgICBvcHRpb25zLm9uU3Rkb3V0TGluZSA9IChsaW5lKSA9PiBjb25zb2xlLmxvZyhsaW5lKTsKICAgIH0KICAgIGlmICghb3B0aW9ucy5vblN0ZGVyckxpbmUpIHsKICAgICAgb3B0aW9ucy5vblN0ZGVyckxpbmUgPSAobGluZSkgPT4gY29uc29sZS53YXJuKGxpbmUpOwogICAgfQogIH0KICByZXR1cm4gb3B0aW9uczsKfQoKLy8gZW50cnlwb2ludC9idW5kbGUudHMKdmFyIHN0YXJ0V2FzaVRhc2sgPSBhc3luYyAoKSA9PiB7CiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgiUkVQTEFDRV9USElTX1dJVEhfVEhFX01BSU5fV0VCQVNTRU1CTFlfTU9EVUxFIik7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICB9IGNhdGNoIHsKICB9CiAgYXdhaXQgaW5zdGFudGlhdGUoewogICAgbW9kdWxlOiBhd2FpdCBXZWJBc3NlbWJseS5jb21waWxlU3RyZWFtaW5nKHJlc3BvbnNlKSwKICAgIG9uU3Rkb3V0TGluZShsaW5lKSB7CiAgICAgIGNvbnNvbGUubG9nKGxpbmUpOwogICAgfSwKICAgIG9uU3RkZXJyTGluZShsaW5lKSB7CiAgICAgIGNvbnNvbGUuZXJyb3IobGluZSk7CiAgICB9LAogICAgU3dpZnRSdW50aW1lOiBydW50aW1lQ29uc3RydWN0b3IKICB9KTsKfTsKYXN5bmMgZnVuY3Rpb24gbWFpbigpIHsKICBhd2FpdCBzdGFydFdhc2lUYXNrKCk7Cn0KbWFpbigpOwo=")! + public static let test: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL3JlY29ubmVjdGluZy13ZWJzb2NrZXQvZGlzdC9yZWNvbm5lY3Rpbmctd2Vic29ja2V0LW1qcy5qcwp2YXIgZXh0ZW5kU3RhdGljcyA9IGZ1bmN0aW9uKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8IHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24oZDIsIGIyKSB7CiAgICBkMi5fX3Byb3RvX18gPSBiMjsKICB9IHx8IGZ1bmN0aW9uKGQyLCBiMikgewogICAgZm9yICh2YXIgcCBpbiBiMikKICAgICAgaWYgKGIyLmhhc093blByb3BlcnR5KHApKQogICAgICAgIGQyW3BdID0gYjJbcF07CiAgfTsKICByZXR1cm4gZXh0ZW5kU3RhdGljcyhkLCBiKTsKfTsKZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHsKICBleHRlbmRTdGF0aWNzKGQsIGIpOwogIGZ1bmN0aW9uIF9fKCkgewogICAgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7CiAgfQogIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTsKfQpmdW5jdGlvbiBfX3ZhbHVlcyhvKSB7CiAgdmFyIG0gPSB0eXBlb2YgU3ltYm9sID09PSAiZnVuY3Rpb24iICYmIG9bU3ltYm9sLml0ZXJhdG9yXSwgaSA9IDA7CiAgaWYgKG0pCiAgICByZXR1cm4gbS5jYWxsKG8pOwogIHJldHVybiB7CiAgICBuZXh0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKG8gJiYgaSA+PSBvLmxlbmd0aCkKICAgICAgICBvID0gdm9pZCAwOwogICAgICByZXR1cm4geyB2YWx1ZTogbyAmJiBvW2krK10sIGRvbmU6ICFvIH07CiAgICB9CiAgfTsKfQpmdW5jdGlvbiBfX3JlYWQobywgbikgewogIHZhciBtID0gdHlwZW9mIFN5bWJvbCA9PT0gImZ1bmN0aW9uIiAmJiBvW1N5bWJvbC5pdGVyYXRvcl07CiAgaWYgKCFtKQogICAgcmV0dXJuIG87CiAgdmFyIGkgPSBtLmNhbGwobyksIHIsIGFyID0gW10sIGU7CiAgdHJ5IHsKICAgIHdoaWxlICgobiA9PT0gdm9pZCAwIHx8IG4tLSA+IDApICYmICEociA9IGkubmV4dCgpKS5kb25lKQogICAgICBhci5wdXNoKHIudmFsdWUpOwogIH0gY2F0Y2ggKGVycm9yKSB7CiAgICBlID0geyBlcnJvciB9OwogIH0gZmluYWxseSB7CiAgICB0cnkgewogICAgICBpZiAociAmJiAhci5kb25lICYmIChtID0gaVsicmV0dXJuIl0pKQogICAgICAgIG0uY2FsbChpKTsKICAgIH0gZmluYWxseSB7CiAgICAgIGlmIChlKQogICAgICAgIHRocm93IGUuZXJyb3I7CiAgICB9CiAgfQogIHJldHVybiBhcjsKfQpmdW5jdGlvbiBfX3NwcmVhZCgpIHsKICBmb3IgKHZhciBhciA9IFtdLCBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykKICAgIGFyID0gYXIuY29uY2F0KF9fcmVhZChhcmd1bWVudHNbaV0pKTsKICByZXR1cm4gYXI7Cn0KdmFyIEV2ZW50ID0gZnVuY3Rpb24oKSB7CiAgZnVuY3Rpb24gRXZlbnQyKHR5cGUsIHRhcmdldCkgewogICAgdGhpcy50YXJnZXQgPSB0YXJnZXQ7CiAgICB0aGlzLnR5cGUgPSB0eXBlOwogIH0KICByZXR1cm4gRXZlbnQyOwp9KCk7CnZhciBFcnJvckV2ZW50ID0gZnVuY3Rpb24oX3N1cGVyKSB7CiAgX19leHRlbmRzKEVycm9yRXZlbnQyLCBfc3VwZXIpOwogIGZ1bmN0aW9uIEVycm9yRXZlbnQyKGVycm9yLCB0YXJnZXQpIHsKICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJlcnJvciIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLm1lc3NhZ2UgPSBlcnJvci5tZXNzYWdlOwogICAgX3RoaXMuZXJyb3IgPSBlcnJvcjsKICAgIHJldHVybiBfdGhpczsKICB9CiAgcmV0dXJuIEVycm9yRXZlbnQyOwp9KEV2ZW50KTsKdmFyIENsb3NlRXZlbnQgPSBmdW5jdGlvbihfc3VwZXIpIHsKICBfX2V4dGVuZHMoQ2xvc2VFdmVudDIsIF9zdXBlcik7CiAgZnVuY3Rpb24gQ2xvc2VFdmVudDIoY29kZSwgcmVhc29uLCB0YXJnZXQpIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIGlmIChyZWFzb24gPT09IHZvaWQgMCkgewogICAgICByZWFzb24gPSAiIjsKICAgIH0KICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsICJjbG9zZSIsIHRhcmdldCkgfHwgdGhpczsKICAgIF90aGlzLndhc0NsZWFuID0gdHJ1ZTsKICAgIF90aGlzLmNvZGUgPSBjb2RlOwogICAgX3RoaXMucmVhc29uID0gcmVhc29uOwogICAgcmV0dXJuIF90aGlzOwogIH0KICByZXR1cm4gQ2xvc2VFdmVudDI7Cn0oRXZlbnQpOwp2YXIgZ2V0R2xvYmFsV2ViU29ja2V0ID0gZnVuY3Rpb24oKSB7CiAgaWYgKHR5cGVvZiBXZWJTb2NrZXQgIT09ICJ1bmRlZmluZWQiKSB7CiAgICByZXR1cm4gV2ViU29ja2V0OwogIH0KfTsKdmFyIGlzV2ViU29ja2V0ID0gZnVuY3Rpb24odykgewogIHJldHVybiB0eXBlb2YgdyAhPT0gInVuZGVmaW5lZCIgJiYgISF3ICYmIHcuQ0xPU0lORyA9PT0gMjsKfTsKdmFyIERFRkFVTFQgPSB7CiAgbWF4UmVjb25uZWN0aW9uRGVsYXk6IDFlNCwKICBtaW5SZWNvbm5lY3Rpb25EZWxheTogMWUzICsgTWF0aC5yYW5kb20oKSAqIDRlMywKICBtaW5VcHRpbWU6IDVlMywKICByZWNvbm5lY3Rpb25EZWxheUdyb3dGYWN0b3I6IDEuMywKICBjb25uZWN0aW9uVGltZW91dDogNGUzLAogIG1heFJldHJpZXM6IEluZmluaXR5LAogIG1heEVucXVldWVkTWVzc2FnZXM6IEluZmluaXR5LAogIHN0YXJ0Q2xvc2VkOiBmYWxzZSwKICBkZWJ1ZzogZmFsc2UKfTsKdmFyIFJlY29ubmVjdGluZ1dlYlNvY2tldCA9IGZ1bmN0aW9uKCkgewogIGZ1bmN0aW9uIFJlY29ubmVjdGluZ1dlYlNvY2tldDIodXJsLCBwcm90b2NvbHMsIG9wdGlvbnMpIHsKICAgIHZhciBfdGhpcyA9IHRoaXM7CiAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7CiAgICAgIG9wdGlvbnMgPSB7fTsKICAgIH0KICAgIHRoaXMuX2xpc3RlbmVycyA9IHsKICAgICAgZXJyb3I6IFtdLAogICAgICBtZXNzYWdlOiBbXSwKICAgICAgb3BlbjogW10sCiAgICAgIGNsb3NlOiBbXQogICAgfTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIHRoaXMuX3Nob3VsZFJlY29ubmVjdCA9IHRydWU7CiAgICB0aGlzLl9jb25uZWN0TG9jayA9IGZhbHNlOwogICAgdGhpcy5fYmluYXJ5VHlwZSA9ICJibG9iIjsKICAgIHRoaXMuX2Nsb3NlQ2FsbGVkID0gZmFsc2U7CiAgICB0aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgIHRoaXMub25jbG9zZSA9IG51bGw7CiAgICB0aGlzLm9uZXJyb3IgPSBudWxsOwogICAgdGhpcy5vbm1lc3NhZ2UgPSBudWxsOwogICAgdGhpcy5vbm9wZW4gPSBudWxsOwogICAgdGhpcy5faGFuZGxlT3BlbiA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICAgIF90aGlzLl9kZWJ1Zygib3BlbiBldmVudCIpOwogICAgICB2YXIgX2EgPSBfdGhpcy5fb3B0aW9ucy5taW5VcHRpbWUsIG1pblVwdGltZSA9IF9hID09PSB2b2lkIDAgPyBERUZBVUxULm1pblVwdGltZSA6IF9hOwogICAgICBjbGVhclRpbWVvdXQoX3RoaXMuX2Nvbm5lY3RUaW1lb3V0KTsKICAgICAgX3RoaXMuX3VwdGltZVRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5fYWNjZXB0T3BlbigpOwogICAgICB9LCBtaW5VcHRpbWUpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fbWVzc2FnZVF1ZXVlLmZvckVhY2goZnVuY3Rpb24obWVzc2FnZSkgewogICAgICAgIHJldHVybiBfdGhpcy5fd3Muc2VuZChtZXNzYWdlKTsKICAgICAgfSk7CiAgICAgIF90aGlzLl9tZXNzYWdlUXVldWUgPSBbXTsKICAgICAgaWYgKF90aGlzLm9ub3BlbikgewogICAgICAgIF90aGlzLm9ub3BlbihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5vcGVuLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZU1lc3NhZ2UgPSBmdW5jdGlvbihldmVudCkgewogICAgICBfdGhpcy5fZGVidWcoIm1lc3NhZ2UgZXZlbnQiKTsKICAgICAgaWYgKF90aGlzLm9ubWVzc2FnZSkgewogICAgICAgIF90aGlzLm9ubWVzc2FnZShldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2xpc3RlbmVycy5tZXNzYWdlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUVycm9yID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJlcnJvciBldmVudCIsIGV2ZW50Lm1lc3NhZ2UpOwogICAgICBfdGhpcy5fZGlzY29ubmVjdCh2b2lkIDAsIGV2ZW50Lm1lc3NhZ2UgPT09ICJUSU1FT1VUIiA/ICJ0aW1lb3V0IiA6IHZvaWQgMCk7CiAgICAgIGlmIChfdGhpcy5vbmVycm9yKSB7CiAgICAgICAgX3RoaXMub25lcnJvcihldmVudCk7CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJleGVjIGVycm9yIGxpc3RlbmVycyIpOwogICAgICBfdGhpcy5fbGlzdGVuZXJzLmVycm9yLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgICBfdGhpcy5fY29ubmVjdCgpOwogICAgfTsKICAgIHRoaXMuX2hhbmRsZUNsb3NlID0gZnVuY3Rpb24oZXZlbnQpIHsKICAgICAgX3RoaXMuX2RlYnVnKCJjbG9zZSBldmVudCIpOwogICAgICBfdGhpcy5fY2xlYXJUaW1lb3V0cygpOwogICAgICBpZiAoX3RoaXMuX3Nob3VsZFJlY29ubmVjdCkgewogICAgICAgIF90aGlzLl9jb25uZWN0KCk7CiAgICAgIH0KICAgICAgaWYgKF90aGlzLm9uY2xvc2UpIHsKICAgICAgICBfdGhpcy5vbmNsb3NlKGV2ZW50KTsKICAgICAgfQogICAgICBfdGhpcy5fbGlzdGVuZXJzLmNsb3NlLmZvckVhY2goZnVuY3Rpb24obGlzdGVuZXIpIHsKICAgICAgICByZXR1cm4gX3RoaXMuX2NhbGxFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lcik7CiAgICAgIH0pOwogICAgfTsKICAgIHRoaXMuX3VybCA9IHVybDsKICAgIHRoaXMuX3Byb3RvY29scyA9IHByb3RvY29sczsKICAgIHRoaXMuX29wdGlvbnMgPSBvcHRpb25zOwogICAgaWYgKHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQpIHsKICAgICAgdGhpcy5fc2hvdWxkUmVjb25uZWN0ID0gZmFsc2U7CiAgICB9CiAgICB0aGlzLl9jb25uZWN0KCk7CiAgfQogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ09OTkVDVElORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiAwOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0MiwgIk9QRU4iLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gMTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIsICJDTE9TSU5HIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLCAiQ0xPU0VEIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIDM7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNPTk5FQ1RJTkciLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5DT05ORUNUSU5HOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJPUEVOIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIFJlY29ubmVjdGluZ1dlYlNvY2tldDIuT1BFTjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiQ0xPU0lORyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NJTkc7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZSwgIkNMT1NFRCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRDsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYmluYXJ5VHlwZSIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmJpbmFyeVR5cGUgOiB0aGlzLl9iaW5hcnlUeXBlOwogICAgfSwKICAgIHNldDogZnVuY3Rpb24odmFsdWUpIHsKICAgICAgdGhpcy5fYmluYXJ5VHlwZSA9IHZhbHVlOwogICAgICBpZiAodGhpcy5fd3MpIHsKICAgICAgICB0aGlzLl93cy5iaW5hcnlUeXBlID0gdmFsdWU7CiAgICAgIH0KICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicmV0cnlDb3VudCIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBNYXRoLm1heCh0aGlzLl9yZXRyeUNvdW50LCAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiYnVmZmVyZWRBbW91bnQiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICB2YXIgYnl0ZXMgPSB0aGlzLl9tZXNzYWdlUXVldWUucmVkdWNlKGZ1bmN0aW9uKGFjYywgbWVzc2FnZSkgewogICAgICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gInN0cmluZyIpIHsKICAgICAgICAgIGFjYyArPSBtZXNzYWdlLmxlbmd0aDsKICAgICAgICB9IGVsc2UgaWYgKG1lc3NhZ2UgaW5zdGFuY2VvZiBCbG9iKSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5zaXplOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBhY2MgKz0gbWVzc2FnZS5ieXRlTGVuZ3RoOwogICAgICAgIH0KICAgICAgICByZXR1cm4gYWNjOwogICAgICB9LCAwKTsKICAgICAgcmV0dXJuIGJ5dGVzICsgKHRoaXMuX3dzID8gdGhpcy5fd3MuYnVmZmVyZWRBbW91bnQgOiAwKTsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAiZXh0ZW5zaW9ucyIsIHsKICAgIGdldDogZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiB0aGlzLl93cyA/IHRoaXMuX3dzLmV4dGVuc2lvbnMgOiAiIjsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAicHJvdG9jb2wiLCB7CiAgICBnZXQ6IGZ1bmN0aW9uKCkgewogICAgICByZXR1cm4gdGhpcy5fd3MgPyB0aGlzLl93cy5wcm90b2NvbCA6ICIiOwogICAgfSwKICAgIGVudW1lcmFibGU6IHRydWUsCiAgICBjb25maWd1cmFibGU6IHRydWUKICB9KTsKICBPYmplY3QuZGVmaW5lUHJvcGVydHkoUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUsICJyZWFkeVN0YXRlIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgaWYgKHRoaXMuX3dzKSB7CiAgICAgICAgcmV0dXJuIHRoaXMuX3dzLnJlYWR5U3RhdGU7CiAgICAgIH0KICAgICAgcmV0dXJuIHRoaXMuX29wdGlvbnMuc3RhcnRDbG9zZWQgPyBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLkNMT1NFRCA6IFJlY29ubmVjdGluZ1dlYlNvY2tldDIuQ09OTkVDVElORzsKICAgIH0sCiAgICBlbnVtZXJhYmxlOiB0cnVlLAogICAgY29uZmlndXJhYmxlOiB0cnVlCiAgfSk7CiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLCAidXJsIiwgewogICAgZ2V0OiBmdW5jdGlvbigpIHsKICAgICAgcmV0dXJuIHRoaXMuX3dzID8gdGhpcy5fd3MudXJsIDogIiI7CiAgICB9LAogICAgZW51bWVyYWJsZTogdHJ1ZSwKICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZQogIH0pOwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICBpZiAoY29kZSA9PT0gdm9pZCAwKSB7CiAgICAgIGNvZGUgPSAxZTM7CiAgICB9CiAgICB0aGlzLl9jbG9zZUNhbGxlZCA9IHRydWU7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSBmYWxzZTsKICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlIGVucXVldWVkOiBubyB3cyBpbnN0YW5jZSIpOwogICAgICByZXR1cm47CiAgICB9CiAgICBpZiAodGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fZGVidWcoImNsb3NlOiBhbHJlYWR5IGNsb3NlZCIpOwogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oY29kZSwgcmVhc29uKSB7CiAgICB0aGlzLl9zaG91bGRSZWNvbm5lY3QgPSB0cnVlOwogICAgdGhpcy5fY2xvc2VDYWxsZWQgPSBmYWxzZTsKICAgIHRoaXMuX3JldHJ5Q291bnQgPSAtMTsKICAgIGlmICghdGhpcy5fd3MgfHwgdGhpcy5fd3MucmVhZHlTdGF0ZSA9PT0gdGhpcy5DTE9TRUQpIHsKICAgICAgdGhpcy5fY29ubmVjdCgpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5fZGlzY29ubmVjdChjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9jb25uZWN0KCk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24oZGF0YSkgewogICAgaWYgKHRoaXMuX3dzICYmIHRoaXMuX3dzLnJlYWR5U3RhdGUgPT09IHRoaXMuT1BFTikgewogICAgICB0aGlzLl9kZWJ1Zygic2VuZCIsIGRhdGEpOwogICAgICB0aGlzLl93cy5zZW5kKGRhdGEpOwogICAgfSBlbHNlIHsKICAgICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucy5tYXhFbnF1ZXVlZE1lc3NhZ2VzLCBtYXhFbnF1ZXVlZE1lc3NhZ2VzID0gX2EgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4RW5xdWV1ZWRNZXNzYWdlcyA6IF9hOwogICAgICBpZiAodGhpcy5fbWVzc2FnZVF1ZXVlLmxlbmd0aCA8IG1heEVucXVldWVkTWVzc2FnZXMpIHsKICAgICAgICB0aGlzLl9kZWJ1ZygiZW5xdWV1ZSIsIGRhdGEpOwogICAgICAgIHRoaXMuX21lc3NhZ2VRdWV1ZS5wdXNoKGRhdGEpOwogICAgICB9CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdLnB1c2gobGlzdGVuZXIpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuZGlzcGF0Y2hFdmVudCA9IGZ1bmN0aW9uKGV2ZW50KSB7CiAgICB2YXIgZV8xLCBfYTsKICAgIHZhciBsaXN0ZW5lcnMgPSB0aGlzLl9saXN0ZW5lcnNbZXZlbnQudHlwZV07CiAgICBpZiAobGlzdGVuZXJzKSB7CiAgICAgIHRyeSB7CiAgICAgICAgZm9yICh2YXIgbGlzdGVuZXJzXzEgPSBfX3ZhbHVlcyhsaXN0ZW5lcnMpLCBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpOyAhbGlzdGVuZXJzXzFfMS5kb25lOyBsaXN0ZW5lcnNfMV8xID0gbGlzdGVuZXJzXzEubmV4dCgpKSB7CiAgICAgICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNfMV8xLnZhbHVlOwogICAgICAgICAgdGhpcy5fY2FsbEV2ZW50TGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyKTsKICAgICAgICB9CiAgICAgIH0gY2F0Y2ggKGVfMV8xKSB7CiAgICAgICAgZV8xID0geyBlcnJvcjogZV8xXzEgfTsKICAgICAgfSBmaW5hbGx5IHsKICAgICAgICB0cnkgewogICAgICAgICAgaWYgKGxpc3RlbmVyc18xXzEgJiYgIWxpc3RlbmVyc18xXzEuZG9uZSAmJiAoX2EgPSBsaXN0ZW5lcnNfMS5yZXR1cm4pKQogICAgICAgICAgICBfYS5jYWxsKGxpc3RlbmVyc18xKTsKICAgICAgICB9IGZpbmFsbHkgewogICAgICAgICAgaWYgKGVfMSkKICAgICAgICAgICAgdGhyb3cgZV8xLmVycm9yOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHRydWU7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHsKICAgIGlmICh0aGlzLl9saXN0ZW5lcnNbdHlwZV0pIHsKICAgICAgdGhpcy5fbGlzdGVuZXJzW3R5cGVdID0gdGhpcy5fbGlzdGVuZXJzW3R5cGVdLmZpbHRlcihmdW5jdGlvbihsKSB7CiAgICAgICAgcmV0dXJuIGwgIT09IGxpc3RlbmVyOwogICAgICB9KTsKICAgIH0KICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9kZWJ1ZyA9IGZ1bmN0aW9uKCkgewogICAgdmFyIGFyZ3MgPSBbXTsKICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7CiAgICAgIGFyZ3NbX2ldID0gYXJndW1lbnRzW19pXTsKICAgIH0KICAgIGlmICh0aGlzLl9vcHRpb25zLmRlYnVnKSB7CiAgICAgIGNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsIF9fc3ByZWFkKFsiUldTPiJdLCBhcmdzKSk7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fZ2V0TmV4dERlbGF5ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX2EgPSB0aGlzLl9vcHRpb25zLCBfYiA9IF9hLnJlY29ubmVjdGlvbkRlbGF5R3Jvd0ZhY3RvciwgcmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQucmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yIDogX2IsIF9jID0gX2EubWluUmVjb25uZWN0aW9uRGVsYXksIG1pblJlY29ubmVjdGlvbkRlbGF5ID0gX2MgPT09IHZvaWQgMCA/IERFRkFVTFQubWluUmVjb25uZWN0aW9uRGVsYXkgOiBfYywgX2QgPSBfYS5tYXhSZWNvbm5lY3Rpb25EZWxheSwgbWF4UmVjb25uZWN0aW9uRGVsYXkgPSBfZCA9PT0gdm9pZCAwID8gREVGQVVMVC5tYXhSZWNvbm5lY3Rpb25EZWxheSA6IF9kOwogICAgdmFyIGRlbGF5ID0gMDsKICAgIGlmICh0aGlzLl9yZXRyeUNvdW50ID4gMCkgewogICAgICBkZWxheSA9IG1pblJlY29ubmVjdGlvbkRlbGF5ICogTWF0aC5wb3cocmVjb25uZWN0aW9uRGVsYXlHcm93RmFjdG9yLCB0aGlzLl9yZXRyeUNvdW50IC0gMSk7CiAgICAgIGlmIChkZWxheSA+IG1heFJlY29ubmVjdGlvbkRlbGF5KSB7CiAgICAgICAgZGVsYXkgPSBtYXhSZWNvbm5lY3Rpb25EZWxheTsKICAgICAgfQogICAgfQogICAgdGhpcy5fZGVidWcoIm5leHQgZGVsYXkiLCBkZWxheSk7CiAgICByZXR1cm4gZGVsYXk7CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fd2FpdCA9IGZ1bmN0aW9uKCkgewogICAgdmFyIF90aGlzID0gdGhpczsKICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlKSB7CiAgICAgIHNldFRpbWVvdXQocmVzb2x2ZSwgX3RoaXMuX2dldE5leHREZWxheSgpKTsKICAgIH0pOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2dldE5leHRVcmwgPSBmdW5jdGlvbih1cmxQcm92aWRlcikgewogICAgaWYgKHR5cGVvZiB1cmxQcm92aWRlciA9PT0gInN0cmluZyIpIHsKICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh1cmxQcm92aWRlcik7CiAgICB9CiAgICBpZiAodHlwZW9mIHVybFByb3ZpZGVyID09PSAiZnVuY3Rpb24iKSB7CiAgICAgIHZhciB1cmwgPSB1cmxQcm92aWRlcigpOwogICAgICBpZiAodHlwZW9mIHVybCA9PT0gInN0cmluZyIpIHsKICAgICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKHVybCk7CiAgICAgIH0KICAgICAgaWYgKCEhdXJsLnRoZW4pIHsKICAgICAgICByZXR1cm4gdXJsOwogICAgICB9CiAgICB9CiAgICB0aHJvdyBFcnJvcigiSW52YWxpZCBVUkwiKTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jb25uZWN0ID0gZnVuY3Rpb24oKSB7CiAgICB2YXIgX3RoaXMgPSB0aGlzOwogICAgaWYgKHRoaXMuX2Nvbm5lY3RMb2NrIHx8ICF0aGlzLl9zaG91bGRSZWNvbm5lY3QpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fY29ubmVjdExvY2sgPSB0cnVlOwogICAgdmFyIF9hID0gdGhpcy5fb3B0aW9ucywgX2IgPSBfYS5tYXhSZXRyaWVzLCBtYXhSZXRyaWVzID0gX2IgPT09IHZvaWQgMCA/IERFRkFVTFQubWF4UmV0cmllcyA6IF9iLCBfYyA9IF9hLmNvbm5lY3Rpb25UaW1lb3V0LCBjb25uZWN0aW9uVGltZW91dCA9IF9jID09PSB2b2lkIDAgPyBERUZBVUxULmNvbm5lY3Rpb25UaW1lb3V0IDogX2MsIF9kID0gX2EuV2ViU29ja2V0LCBXZWJTb2NrZXQyID0gX2QgPT09IHZvaWQgMCA/IGdldEdsb2JhbFdlYlNvY2tldCgpIDogX2Q7CiAgICBpZiAodGhpcy5fcmV0cnlDb3VudCA+PSBtYXhSZXRyaWVzKSB7CiAgICAgIHRoaXMuX2RlYnVnKCJtYXggcmV0cmllcyByZWFjaGVkIiwgdGhpcy5fcmV0cnlDb3VudCwgIj49IiwgbWF4UmV0cmllcyk7CiAgICAgIHJldHVybjsKICAgIH0KICAgIHRoaXMuX3JldHJ5Q291bnQrKzsKICAgIHRoaXMuX2RlYnVnKCJjb25uZWN0IiwgdGhpcy5fcmV0cnlDb3VudCk7CiAgICB0aGlzLl9yZW1vdmVMaXN0ZW5lcnMoKTsKICAgIGlmICghaXNXZWJTb2NrZXQoV2ViU29ja2V0MikpIHsKICAgICAgdGhyb3cgRXJyb3IoIk5vIHZhbGlkIFdlYlNvY2tldCBjbGFzcyBwcm92aWRlZCIpOwogICAgfQogICAgdGhpcy5fd2FpdCgpLnRoZW4oZnVuY3Rpb24oKSB7CiAgICAgIHJldHVybiBfdGhpcy5fZ2V0TmV4dFVybChfdGhpcy5fdXJsKTsKICAgIH0pLnRoZW4oZnVuY3Rpb24odXJsKSB7CiAgICAgIGlmIChfdGhpcy5fY2xvc2VDYWxsZWQpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgICAgX3RoaXMuX2RlYnVnKCJjb25uZWN0IiwgeyB1cmwsIHByb3RvY29sczogX3RoaXMuX3Byb3RvY29scyB9KTsKICAgICAgX3RoaXMuX3dzID0gX3RoaXMuX3Byb3RvY29scyA/IG5ldyBXZWJTb2NrZXQyKHVybCwgX3RoaXMuX3Byb3RvY29scykgOiBuZXcgV2ViU29ja2V0Mih1cmwpOwogICAgICBfdGhpcy5fd3MuYmluYXJ5VHlwZSA9IF90aGlzLl9iaW5hcnlUeXBlOwogICAgICBfdGhpcy5fY29ubmVjdExvY2sgPSBmYWxzZTsKICAgICAgX3RoaXMuX2FkZExpc3RlbmVycygpOwogICAgICBfdGhpcy5fY29ubmVjdFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgewogICAgICAgIHJldHVybiBfdGhpcy5faGFuZGxlVGltZW91dCgpOwogICAgICB9LCBjb25uZWN0aW9uVGltZW91dCk7CiAgICB9KTsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9oYW5kbGVUaW1lb3V0ID0gZnVuY3Rpb24oKSB7CiAgICB0aGlzLl9kZWJ1ZygidGltZW91dCBldmVudCIpOwogICAgdGhpcy5faGFuZGxlRXJyb3IobmV3IEVycm9yRXZlbnQoRXJyb3IoIlRJTUVPVVQiKSwgdGhpcykpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2Rpc2Nvbm5lY3QgPSBmdW5jdGlvbihjb2RlLCByZWFzb24pIHsKICAgIGlmIChjb2RlID09PSB2b2lkIDApIHsKICAgICAgY29kZSA9IDFlMzsKICAgIH0KICAgIHRoaXMuX2NsZWFyVGltZW91dHMoKTsKICAgIGlmICghdGhpcy5fd3MpIHsKICAgICAgcmV0dXJuOwogICAgfQogICAgdGhpcy5fcmVtb3ZlTGlzdGVuZXJzKCk7CiAgICB0cnkgewogICAgICB0aGlzLl93cy5jbG9zZShjb2RlLCByZWFzb24pOwogICAgICB0aGlzLl9oYW5kbGVDbG9zZShuZXcgQ2xvc2VFdmVudChjb2RlLCByZWFzb24sIHRoaXMpKTsKICAgIH0gY2F0Y2ggKGVycm9yKSB7CiAgICB9CiAgfTsKICBSZWNvbm5lY3RpbmdXZWJTb2NrZXQyLnByb3RvdHlwZS5fYWNjZXB0T3BlbiA9IGZ1bmN0aW9uKCkgewogICAgdGhpcy5fZGVidWcoImFjY2VwdCBvcGVuIik7CiAgICB0aGlzLl9yZXRyeUNvdW50ID0gMDsKICB9OwogIFJlY29ubmVjdGluZ1dlYlNvY2tldDIucHJvdG90eXBlLl9jYWxsRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBsaXN0ZW5lcikgewogICAgaWYgKCJoYW5kbGVFdmVudCIgaW4gbGlzdGVuZXIpIHsKICAgICAgbGlzdGVuZXIuaGFuZGxlRXZlbnQoZXZlbnQpOwogICAgfSBlbHNlIHsKICAgICAgbGlzdGVuZXIoZXZlbnQpOwogICAgfQogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX3JlbW92ZUxpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygicmVtb3ZlTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5yZW1vdmVFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLnJlbW92ZUV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2FkZExpc3RlbmVycyA9IGZ1bmN0aW9uKCkgewogICAgaWYgKCF0aGlzLl93cykgewogICAgICByZXR1cm47CiAgICB9CiAgICB0aGlzLl9kZWJ1ZygiYWRkTGlzdGVuZXJzIik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJvcGVuIiwgdGhpcy5faGFuZGxlT3Blbik7CiAgICB0aGlzLl93cy5hZGRFdmVudExpc3RlbmVyKCJjbG9zZSIsIHRoaXMuX2hhbmRsZUNsb3NlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoIm1lc3NhZ2UiLCB0aGlzLl9oYW5kbGVNZXNzYWdlKTsKICAgIHRoaXMuX3dzLmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIiwgdGhpcy5faGFuZGxlRXJyb3IpOwogIH07CiAgUmVjb25uZWN0aW5nV2ViU29ja2V0Mi5wcm90b3R5cGUuX2NsZWFyVGltZW91dHMgPSBmdW5jdGlvbigpIHsKICAgIGNsZWFyVGltZW91dCh0aGlzLl9jb25uZWN0VGltZW91dCk7CiAgICBjbGVhclRpbWVvdXQodGhpcy5fdXB0aW1lVGltZW91dCk7CiAgfTsKICByZXR1cm4gUmVjb25uZWN0aW5nV2ViU29ja2V0MjsKfSgpOwp2YXIgcmVjb25uZWN0aW5nX3dlYnNvY2tldF9tanNfZGVmYXVsdCA9IFJlY29ubmVjdGluZ1dlYlNvY2tldDsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJncywgZW52LCBmZHMsIG9wdGlvbnMgPSB7fSkgewogICAgdGhpcy5hcmdzID0gW107CiAgICB0aGlzLmVudiA9IFtdOwogICAgdGhpcy5mZHMgPSBbXTsKICAgIGRlYnVnLmVuYWJsZShvcHRpb25zLmRlYnVnKTsKICAgIHRoaXMuYXJncyA9IGFyZ3M7CiAgICB0aGlzLmVudiA9IGVudjsKICAgIHRoaXMuZmRzID0gZmRzOwogICAgY29uc3Qgc2VsZiA9IHRoaXM7CiAgICB0aGlzLndhc2lJbXBvcnQgPSB7IGFyZ3Nfc2l6ZXNfZ2V0KGFyZ2MsIGFyZ3ZfYnVmX3NpemUpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ2MsIHNlbGYuYXJncy5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGFyZyBvZiBzZWxmLmFyZ3MpIHsKICAgICAgICBidWZfc2l6ZSArPSBhcmcubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3ZfYnVmX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoYXJnYywgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGFyZ3NfZ2V0KGFyZ3YsIGFyZ3ZfYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2FyZ3ZfYnVmID0gYXJndl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5hcmdzLmxlbmd0aDsgaSsrKSB7CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihhcmd2LCBhcmd2X2J1ZiwgdHJ1ZSk7CiAgICAgICAgYXJndiArPSA0OwogICAgICAgIGNvbnN0IGFyZyA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmFyZ3NbaV0pOwogICAgICAgIGJ1ZmZlcjguc2V0KGFyZywgYXJndl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChhcmd2X2J1ZiArIGFyZy5sZW5ndGgsIDApOwogICAgICAgIGFyZ3ZfYnVmICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgICAgZGVidWcubG9nKG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvcmlnX2FyZ3ZfYnVmLCBhcmd2X2J1ZikpKTsKICAgICAgfQogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fc2l6ZXNfZ2V0KGVudmlyb25fY291bnQsIGVudmlyb25fc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9jb3VudCwgc2VsZi5lbnYubGVuZ3RoLCB0cnVlKTsKICAgICAgbGV0IGJ1Zl9zaXplID0gMDsKICAgICAgZm9yIChjb25zdCBlbnZpcm9uIG9mIHNlbGYuZW52KSB7CiAgICAgICAgYnVmX3NpemUgKz0gZW52aXJvbi5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbl9zaXplLCBidWZfc2l6ZSwgdHJ1ZSk7CiAgICAgIGRlYnVnLmxvZyhidWZmZXIuZ2V0VWludDMyKGVudmlyb25fY291bnQsIHRydWUpLCBidWZmZXIuZ2V0VWludDMyKGVudmlyb25fc2l6ZSwgdHJ1ZSkpOwogICAgICByZXR1cm4gMDsKICAgIH0sIGVudmlyb25fZ2V0KGVudmlyb24sIGVudmlyb25fYnVmKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBvcmlnX2Vudmlyb25fYnVmID0gZW52aXJvbl9idWY7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc2VsZi5lbnYubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGVudmlyb24sIGVudmlyb25fYnVmLCB0cnVlKTsKICAgICAgICBlbnZpcm9uICs9IDQ7CiAgICAgICAgY29uc3QgZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShzZWxmLmVudltpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoZSwgZW52aXJvbl9idWYpOwogICAgICAgIGJ1ZmZlci5zZXRVaW50OChlbnZpcm9uX2J1ZiArIGUubGVuZ3RoLCAwKTsKICAgICAgICBlbnZpcm9uX2J1ZiArPSBlLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfZW52aXJvbl9idWYsIGVudmlyb25fYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgY2xvY2tfcmVzX2dldChpZCwgcmVzX3B0cikgewogICAgICBsZXQgcmVzb2x1dGlvblZhbHVlOwogICAgICBzd2l0Y2ggKGlkKSB7CiAgICAgICAgY2FzZSBDTE9DS0lEX01PTk9UT05JQzogewogICAgICAgICAgcmVzb2x1dGlvblZhbHVlID0gNTAwMG47CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgY2FzZSBDTE9DS0lEX1JFQUxUSU1FOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSAxMDAwMDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgcmV0dXJuIEVSUk5PX05PU1lTOwogICAgICB9CiAgICAgIGNvbnN0IHZpZXcgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIHZpZXcuc2V0QmlnVWludDY0KHJlc19wdHIsIHJlc29sdXRpb25WYWx1ZSwgdHJ1ZSk7CiAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgfSwgY2xvY2tfdGltZV9nZXQoaWQsIHByZWNpc2lvbiwgdGltZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChpZCA9PT0gQ0xPQ0tJRF9SRUFMVElNRSkgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgQmlnSW50KG5ldyBEYXRlKCkuZ2V0VGltZSgpKSAqIDEwMDAwMDBuLCB0cnVlKTsKICAgICAgfSBlbHNlIGlmIChpZCA9PSBDTE9DS0lEX01PTk9UT05JQykgewogICAgICAgIGxldCBtb25vdG9uaWNfdGltZTsKICAgICAgICB0cnkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSBCaWdJbnQoTWF0aC5yb3VuZChwZXJmb3JtYW5jZS5ub3coKSAqIDFlNikpOwogICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgIG1vbm90b25pY190aW1lID0gMG47CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgbW9ub3RvbmljX3RpbWUsIHRydWUpOwogICAgICB9IGVsc2UgewogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQodGltZSwgMG4sIHRydWUpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZmRfYWR2aXNlKGZkLCBvZmZzZXQsIGxlbiwgYWR2aWNlKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2FsbG9jYXRlKGZkLCBvZmZzZXQsIGxlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9jbG9zZShmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW2ZkXS5mZF9jbG9zZSgpOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9kYXRhc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfZ2V0KGZkLCBmZHN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZkc3RhdCB9ID0gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmRzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZkc3RhdC53cml0ZV9ieXRlcyhuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlciksIGZkc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9mZHN0YXRfc2V0X2ZsYWdzKGZkLCBmbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZkLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X2dldChmZCwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfZ2V0KCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfc2V0X3NpemUoZmQsIHNpemUpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLmZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlYWQoaW92ZWMuYnVmX2xlbiwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgb2Zmc2V0ICs9IEJpZ0ludChkYXRhLmxlbmd0aCk7CiAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggIT0gaW92ZWMuYnVmX2xlbikgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9nZXQoZmQsIGJ1Zl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBwcmVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgYnVmX3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3ByZXN0YXRfZGlyX25hbWUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBwcmVzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHJlc3RhdF9nZXQoKTsKICAgICAgICBpZiAocHJlc3RhdCA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBjb25zdCBwcmVzdGF0X2Rpcl9uYW1lID0gcHJlc3RhdC5pbm5lci5wcl9uYW1lOwogICAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgICBidWZmZXI4LnNldChwcmVzdGF0X2Rpcl9uYW1lLnNsaWNlKDAsIHBhdGhfbGVuKSwgcGF0aF9wdHIpOwogICAgICAgIHJldHVybiBwcmVzdGF0X2Rpcl9uYW1lLmJ5dGVMZW5ndGggPiBwYXRoX2xlbiA/IEVSUk5PX05BTUVUT09MT05HIDogRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHdyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG9mZnNldCwgbndyaXR0ZW5fcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IENpb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbndyaXR0ZW4gPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCBkYXRhID0gYnVmZmVyOC5zbGljZShpb3ZlYy5idWYsIGlvdmVjLmJ1ZiArIGlvdmVjLmJ1Zl9sZW4pOwogICAgICAgICAgY29uc3QgeyByZXQsIG53cml0dGVuOiBud3JpdHRlbl9wYXJ0IH0gPSBzZWxmLmZkc1tmZF0uZmRfcHdyaXRlKGRhdGEsIG9mZnNldCk7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIG53cml0dGVuICs9IG53cml0dGVuX3BhcnQ7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KG53cml0dGVuX3BhcnQpOwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG5yZWFkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBJb3ZlYy5yZWFkX2J5dGVzX2FycmF5KGJ1ZmZlciwgaW92c19wdHIsIGlvdnNfbGVuKTsKICAgICAgICBsZXQgbnJlYWQgPSAwOwogICAgICAgIGZvciAoY29uc3QgaW92ZWMgb2YgaW92ZWNzKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLmZkX3JlYWQoaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIG5yZWFkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGEsIGlvdmVjLmJ1Zik7CiAgICAgICAgICBucmVhZCArPSBkYXRhLmxlbmd0aDsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZWFkZGlyKGZkLCBidWYsIGJ1Zl9sZW4sIGNvb2tpZSwgYnVmdXNlZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgbGV0IGJ1ZnVzZWQgPSAwOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICBjb25zdCB7IHJldCwgZGlyZW50IH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKTsKICAgICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChkaXJlbnQgPT0gbnVsbCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5oZWFkX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGNvbnN0IGhlYWRfYnl0ZXMgPSBuZXcgQXJyYXlCdWZmZXIoZGlyZW50LmhlYWRfbGVuZ3RoKCkpOwogICAgICAgICAgZGlyZW50LndyaXRlX2hlYWRfYnl0ZXMobmV3IERhdGFWaWV3KGhlYWRfYnl0ZXMpLCAwKTsKICAgICAgICAgIGJ1ZmZlcjguc2V0KG5ldyBVaW50OEFycmF5KGhlYWRfYnl0ZXMpLnNsaWNlKDAsIE1hdGgubWluKGhlYWRfYnl0ZXMuYnl0ZUxlbmd0aCwgYnVmX2xlbiAtIGJ1ZnVzZWQpKSwgYnVmKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50LmhlYWRfbGVuZ3RoKCk7CiAgICAgICAgICBpZiAoYnVmX2xlbiAtIGJ1ZnVzZWQgPCBkaXJlbnQubmFtZV9sZW5ndGgoKSkgewogICAgICAgICAgICBidWZ1c2VkID0gYnVmX2xlbjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgICBkaXJlbnQud3JpdGVfbmFtZV9ieXRlcyhidWZmZXI4LCBidWYsIGJ1Zl9sZW4gLSBidWZ1c2VkKTsKICAgICAgICAgIGJ1ZiArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGJ1ZnVzZWQgKz0gZGlyZW50Lm5hbWVfbGVuZ3RoKCk7CiAgICAgICAgICBjb29raWUgPSBkaXJlbnQuZF9uZXh0OwogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKGJ1ZnVzZWRfcHRyLCBidWZ1c2VkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcmVudW1iZXIoZmQsIHRvKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW3RvXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCByZXQgPSBzZWxmLmZkc1t0b10uZmRfY2xvc2UoKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzW3RvXSA9IHNlbGYuZmRzW2ZkXTsKICAgICAgICBzZWxmLmZkc1tmZF0gPSB2b2lkIDA7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3NlZWsoZmQsIG9mZnNldCwgd2hlbmNlLCBvZmZzZXRfb3V0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIG9mZnNldDogb2Zmc2V0X291dCB9ID0gc2VsZi5mZHNbZmRdLmZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdJbnQ2NChvZmZzZXRfb3V0X3B0ciwgb2Zmc2V0X291dCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc3luYyhmZCkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfc3luYygpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF90ZWxsKGZkLCBvZmZzZXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfdGVsbCgpOwogICAgICAgIGJ1ZmZlci5zZXRCaWdVaW50NjQob2Zmc2V0X3B0ciwgb2Zmc2V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF93cml0ZShmZCwgaW92c19wdHIsIGlvdnNfbGVuLCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF93cml0ZShkYXRhKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIGlmIChud3JpdHRlbl9wYXJ0ICE9IGRhdGEuYnl0ZUxlbmd0aCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldFVpbnQzMihud3JpdHRlbl9wdHIsIG53cml0dGVuLCB0cnVlKTsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9nZXQoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGZpbGVzdGF0X3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGZpbGVzdGF0IH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2xpbmsob2xkX2ZkLCBvbGRfZmxhZ3MsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW29sZF9mZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW29sZF9mZF0ucGF0aF9sb29rdXAob2xkX3BhdGgsIG9sZF9mbGFncyk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXR1cm4gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgZmFsc2UpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX29wZW4oZmQsIGRpcmZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncywgb3BlbmVkX2ZkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgpOwogICAgICAgIGNvbnN0IHsgcmV0LCBmZF9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGgsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncyk7CiAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBzZWxmLmZkcy5wdXNoKGZkX29iaik7CiAgICAgICAgY29uc3Qgb3BlbmVkX2ZkID0gc2VsZi5mZHMubGVuZ3RoIC0gMTsKICAgICAgICBidWZmZXIuc2V0VWludDMyKG9wZW5lZF9mZF9wdHIsIG9wZW5lZF9mZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVhZGxpbmsoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbiwgYnVmX3B0ciwgYnVmX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3JlYWRsaW5rKHBhdGgpOwogICAgICAgIGlmIChkYXRhICE9IG51bGwpIHsKICAgICAgICAgIGNvbnN0IGRhdGFfYnVmID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGRhdGEpOwogICAgICAgICAgaWYgKGRhdGFfYnVmLmxlbmd0aCA+IGJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIDAsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgICAgIH0KICAgICAgICAgIGJ1ZmZlcjguc2V0KGRhdGFfYnVmLCBidWZfcHRyKTsKICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBkYXRhX2J1Zi5sZW5ndGgsIHRydWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbW92ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3JlbmFtZShmZCwgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCAmJiBzZWxmLmZkc1tuZXdfZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICBsZXQgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfdW5saW5rKG9sZF9wYXRoKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldCA9IHNlbGYuZmRzW25ld19mZF0ucGF0aF9saW5rKG5ld19wYXRoLCBpbm9kZV9vYmosIHRydWUpOwogICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgaWYgKHNlbGYuZmRzW2ZkXS5wYXRoX2xpbmsob2xkX3BhdGgsIGlub2RlX29iaiwgdHJ1ZSkgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICB0aHJvdyAicGF0aF9saW5rIHNob3VsZCBhbHdheXMgcmV0dXJuIHN1Y2Nlc3Mgd2hlbiByZWxpbmtpbmcgYW4gaW5vZGUgYmFjayB0byB0aGUgb3JpZ2luYWwgcGxhY2UiOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3N5bWxpbmsob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIGZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfdW5saW5rX2ZpbGUoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmtfZmlsZShwYXRoKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZsYWdzLCBwYXRoLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGgsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfcmVhZGxpbmsocGF0aCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG51bGwgfTsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQp9Owp2YXIgSW5vZGUgPSBjbGFzcyB7Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZzX21lbS5qcwp2YXIgT3BlbkZpbGUgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gb2Zmc2V0ICsgbGVuKSB7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBsZW4pKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCAwKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBzaXplKSB7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkodGhpcy5maWxlLmRhdGEuYnVmZmVyLnNsaWNlKDAsIE51bWJlcihzaXplKSkpOwogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIoc2l6ZSkpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIodGhpcy5maWxlX3BvcyksIE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KHNpemUpKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChzbGljZS5sZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKG9mZnNldCksIE51bWJlcihvZmZzZXQgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgbGV0IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgc3dpdGNoICh3aGVuY2UpIHsKICAgICAgY2FzZSBXSEVOQ0VfU0VUOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9DVVI6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSB0aGlzLmZpbGVfcG9zICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIFdIRU5DRV9FTkQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBCaWdJbnQodGhpcy5maWxlLmRhdGEuYnl0ZUxlbmd0aCkgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGRlZmF1bHQ6CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgaWYgKGNhbGN1bGF0ZWRfb2Zmc2V0IDwgMCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICB0aGlzLmZpbGVfcG9zID0gY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcih0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgaWYgKHRoaXMuZmlsZS5yZWFkb25seSkKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogICAgaWYgKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcihvZmZzZXQpKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmZpbGUuc3RhdCgpIH07CiAgfQogIGNvbnN0cnVjdG9yKGZpbGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmZpbGVfcG9zID0gMG47CiAgICB0aGlzLmZpbGUgPSBmaWxlOwogIH0KfTsKdmFyIE9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9ESVJFQ1RPUlksIDApIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgZGVidWcubG9nKCJyZWFkZGlyX3NpbmdsZSIsIGNvb2tpZSk7CiAgICAgIGRlYnVnLmxvZyhjb29raWUsIHRoaXMuZGlyLmNvbnRlbnRzLmtleXMoKSk7CiAgICB9CiAgICBpZiAoY29va2llID09IDBuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDFuLCAiLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0gZWxzZSBpZiAoY29va2llID09IDFuKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZGlyZW50OiBuZXcgRGlyZW50KDJuLCAiLi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9CiAgICBpZiAoY29va2llID49IEJpZ0ludCh0aGlzLmRpci5jb250ZW50cy5zaXplKSArIDJuKSB7CiAgICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBbbmFtZSwgZW50cnldID0gQXJyYXkuZnJvbSh0aGlzLmRpci5jb250ZW50cy5lbnRyaWVzKCkpW051bWJlcihjb29raWUgLSAybildOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG5ldyBEaXJlbnQoY29va2llICsgMW4sIG5hbWUsIGVudHJ5LnN0YXQoKS5maWxldHlwZSkgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9lcnIsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IGVudHJ5LnN0YXQoKSB9OwogIH0KICBwYXRoX2xvb2t1cChwYXRoX3N0ciwgZGlyZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoX3N0ciwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgaWYgKHJldCAhPSBFUlJOT19OT0VOVCkgewogICAgICAgIHJldHVybiB7IHJldCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfQ1JFQVQpID09IE9GTEFHU19DUkVBVCkgewogICAgICAgIGNvbnN0IHsgcmV0OiByZXQyLCBlbnRyeTogbmV3X2VudHJ5IH0gPSB0aGlzLmRpci5jcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZKTsKICAgICAgICBpZiAobmV3X2VudHJ5ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiB7IHJldDogcmV0MiwgZmRfb2JqOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGVudHJ5ID0gbmV3X2VudHJ5OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICB9IGVsc2UgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRVhDTCkgPT0gT0ZMQUdTX0VYQ0wpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIGVudHJ5LnBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncyk7CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoKSB7CiAgICByZXR1cm4gdGhpcy5wYXRoX29wZW4oMCwgcGF0aCwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIGNvbnN0IHNvdXJjZV9pc19kaXIgPSBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBjb25zdCB0YXJnZXRfaXNfZGlyID0gZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgaWYgKHNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIGlmIChhbGxvd19kaXIgJiYgZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHsKICAgICAgICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplID09IDApIHsKICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICAgIH0KICAgICAgfSBlbHNlIGlmIChzb3VyY2VfaXNfZGlyICYmICF0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgICAgfSBlbHNlIGlmICghc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgICB9IGVsc2UgaWYgKGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgJiYgZW50cnkuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSkgewogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgfQogICAgfQogICAgaWYgKCFhbGxvd19kaXIgJiYgaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fUEVSTTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIGlub2RlKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3VubGluayhwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGlub2RlX29iajogZW50cnkgfTsKICB9CiAgcGF0aF91bmxpbmtfZmlsZShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBmYWxzZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCB8fCBlbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpIHx8IGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICB9CiAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSAhPT0gMCkgewogICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICB9CiAgICBpZiAoIXBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpKSB7CiAgICAgIHJldHVybiBFUlJOT19OT0VOVDsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiB0aGlzLmRpci5zdGF0KCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgfQogIGZkX3JlYWQoc2l6ZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcHdyaXRlKGRhdGEsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBjb25zdHJ1Y3RvcihkaXIpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRpciA9IGRpcjsKICB9Cn07CnZhciBQcmVvcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBPcGVuRGlyZWN0b3J5IHsKICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgcHJlc3RhdDogUHJlc3RhdC5kaXIodGhpcy5wcmVzdGF0X25hbWUpIH07CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUsIGNvbnRlbnRzKSB7CiAgICBzdXBlcihuZXcgRGlyZWN0b3J5KGNvbnRlbnRzKSk7CiAgICB0aGlzLnByZXN0YXRfbmFtZSA9IG5hbWU7CiAgfQp9Owp2YXIgRmlsZSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgaWYgKHRoaXMucmVhZG9ubHkgJiYgKGZzX3JpZ2h0c19iYXNlICYgQmlnSW50KFJJR0hUU19GRF9XUklURSkpID09IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19UUlVOQykgPT0gT0ZMQUdTX1RSVU5DKSB7CiAgICAgIGlmICh0aGlzLnJlYWRvbmx5KQogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fUEVSTSwgZmRfb2JqOiBudWxsIH07CiAgICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KFtdKTsKICAgIH0KICAgIGNvbnN0IGZpbGUgPSBuZXcgT3BlbkZpbGUodGhpcyk7CiAgICBpZiAoZmRfZmxhZ3MgJiBGREZMQUdTX0FQUEVORCkKICAgICAgZmlsZS5mZF9zZWVrKDBuLCBXSEVOQ0VfRU5EKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZmRfb2JqOiBmaWxlIH07CiAgfQogIGdldCBzaXplKCkgewogICAgcmV0dXJuIEJpZ0ludCh0aGlzLmRhdGEuYnl0ZUxlbmd0aCk7CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgdGhpcy5zaXplKTsKICB9CiAgY29uc3RydWN0b3IoZGF0YSwgb3B0aW9ucykgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGF0YSA9IG5ldyBVaW50OEFycmF5KGRhdGEpOwogICAgdGhpcy5yZWFkb25seSA9ICEhb3B0aW9ucz8ucmVhZG9ubHk7CiAgfQp9Owp2YXIgUGF0aCA9IGNsYXNzIFBhdGgyIHsKICBzdGF0aWMgZnJvbShwYXRoKSB7CiAgICBjb25zdCBzZWxmID0gbmV3IFBhdGgyKCk7CiAgICBzZWxmLmlzX2RpciA9IHBhdGguZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoLnN0YXJ0c1dpdGgoIi8iKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVENBUEFCTEUsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGlmIChwYXRoLmluY2x1ZGVzKCJcMCIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhdGg6IG51bGwgfTsKICAgIH0KICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGguc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aCkgewogICAgbGV0IGVudHJ5ID0gdGhpczsKICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHBhdGgucGFydHMpIHsKICAgICAgaWYgKCEoZW50cnkgaW5zdGFuY2VvZiBEaXJlY3RvcnkpKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgICAgY29uc3QgY2hpbGQgPSBlbnRyeS5jb250ZW50cy5nZXQoY29tcG9uZW50KTsKICAgICAgaWYgKGNoaWxkICE9PSB2b2lkIDApIHsKICAgICAgICBlbnRyeSA9IGNoaWxkOwogICAgICB9IGVsc2UgewogICAgICAgIGRlYnVnLmxvZyhjb21wb25lbnQpOwogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCBhbGxvd191bmRlZmluZWQpIHsKICAgIGNvbnN0IGZpbGVuYW1lID0gcGF0aC5wYXJ0cy5wb3AoKTsKICAgIGlmIChmaWxlbmFtZSA9PT0gdm9pZCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldDogZW50cnlfcmV0LCBlbnRyeTogcGFyZW50X2VudHJ5IH0gPSB0aGlzLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfTsKICB9CiAgY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCBpc19kaXIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXJlbnRfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19FWElTVCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGRlYnVnLmxvZygiY3JlYXRlIiwgcGF0aCk7CiAgICBsZXQgbmV3X2NoaWxkOwogICAgaWYgKCFpc19kaXIpIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IEZpbGUobmV3IEFycmF5QnVmZmVyKDApKTsKICAgIH0gZWxzZSB7CiAgICAgIG5ld19jaGlsZCA9IG5ldyBEaXJlY3RvcnkoLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSk7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBuZXdfY2hpbGQpOwogICAgZW50cnkgPSBuZXdfY2hpbGQ7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGNvbnN0cnVjdG9yKGNvbnRlbnRzKSB7CiAgICBzdXBlcigpOwogICAgaWYgKGNvbnRlbnRzIGluc3RhbmNlb2YgQXJyYXkpIHsKICAgICAgdGhpcy5jb250ZW50cyA9IG5ldyBNYXAoY29udGVudHMpOwogICAgfSBlbHNlIHsKICAgICAgdGhpcy5jb250ZW50cyA9IGNvbnRlbnRzOwogICAgfQogIH0KfTsKdmFyIENvbnNvbGVTdGRvdXQgPSBjbGFzcyBleHRlbmRzIEZkIHsKICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmaWxlc3RhdCA9IG5ldyBGaWxlc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCBCaWdJbnQoMCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdCB9OwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgY29uc3QgZmRzdGF0ID0gbmV3IEZkc3RhdChGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFLCAwKTsKICAgIGZkc3RhdC5mc19yaWdodHNfYmFzZSA9IEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgdGhpcy53cml0ZShkYXRhKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBzdGF0aWMgbGluZUJ1ZmZlcmVkKHdyaXRlKSB7CiAgICBjb25zdCBkZWMgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICBsZXQgbGluZV9idWYgPSAiIjsKICAgIHJldHVybiBuZXcgQ29uc29sZVN0ZG91dCgoYnVmZmVyKSA9PiB7CiAgICAgIGxpbmVfYnVmICs9IGRlYy5kZWNvZGUoYnVmZmVyLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgICAgY29uc3QgbGluZXMgPSBsaW5lX2J1Zi5zcGxpdCgiXG4iKTsKICAgICAgZm9yIChjb25zdCBbaSwgbGluZV0gb2YgbGluZXMuZW50cmllcygpKSB7CiAgICAgICAgaWYgKGkgPCBsaW5lcy5sZW5ndGggLSAxKSB7CiAgICAgICAgICB3cml0ZShsaW5lKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgbGluZV9idWYgPSBsaW5lOwogICAgICAgIH0KICAgICAgfQogICAgfSk7CiAgfQogIGNvbnN0cnVjdG9yKHdyaXRlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy53cml0ZSA9IHdyaXRlOwogIH0KfTsKCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL2luZGV4LmpzCmZ1bmN0aW9uIHBhcnNlSW1wb3J0cyhtb2R1bGVCeXRlcykgewogIGlmIChtb2R1bGVCeXRlcyBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsKICB9IGVsc2UgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMpOwogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMuYnVmZmVyIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHsKICAgIG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkobW9kdWxlQnl0ZXMuYnVmZmVyKTsKICB9IGVsc2UgewogICAgdGhyb3cgbmV3IEVycm9yKCJBcmd1bWVudCBtdXN0IGJlIGEgYnVmZmVyIHNvdXJjZSwgbGlrZSBVaW50OEFycmF5IG9yIEFycmF5QnVmZmVyIik7CiAgfQogIGNvbnN0IHBhcnNlU3RhdGUgPSBuZXcgUGFyc2VTdGF0ZShtb2R1bGVCeXRlcyk7CiAgcGFyc2VNYWdpY051bWJlcihwYXJzZVN0YXRlKTsKICBwYXJzZVZlcnNpb24ocGFyc2VTdGF0ZSk7CiAgY29uc3QgdHlwZXMgPSBbXTsKICBjb25zdCBpbXBvcnRzID0gW107CiAgd2hpbGUgKHBhcnNlU3RhdGUuaGFzTW9yZUJ5dGVzKCkpIHsKICAgIGNvbnN0IHNlY3Rpb25JZCA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICAgIGNvbnN0IHNlY3Rpb25TaXplID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgIHN3aXRjaCAoc2VjdGlvbklkKSB7CiAgICAgIGNhc2UgMTogewogICAgICAgIGNvbnN0IHR5cGVDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0eXBlQ291bnQ7IGkrKykgewogICAgICAgICAgdHlwZXMucHVzaChwYXJzZUZ1bmN0aW9uVHlwZShwYXJzZVN0YXRlKSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgICB9CiAgICAgIGNhc2UgMjogewogICAgICAgIGNvbnN0IGltcG9ydENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGltcG9ydENvdW50OyBpKyspIHsKICAgICAgICAgIGNvbnN0IG1vZHVsZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseS5Nb2R1bGUobW9kdWxlQnl0ZXMpOwogIGNvbnN0IGltcG9ydHMgPSBXZWJBc3NlbWJseS5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpOwogIGNvbnN0IG1lbW9yeUltcG9ydCA9IGltcG9ydHNbMF07CiAgcmV0dXJuIHR5cGVvZiBtZW1vcnlJbXBvcnQudHlwZSA9PT0gIm9iamVjdCI7Cn0pKCk7CmZ1bmN0aW9uIHBvbHlmaWxsKFdlYkFzc2VtYmx5MykgewogIGlmIChoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0KSB7CiAgICByZXR1cm4gV2ViQXNzZW1ibHkzOwogIH0KICBjb25zdCBuZXdXZWJBc3NlbWJseSA9IHt9OwogIGZvciAoY29uc3Qga2V5IGluIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKFdlYkFzc2VtYmx5MykpIHsKICAgIG5ld1dlYkFzc2VtYmx5W2tleV0gPSBXZWJBc3NlbWJseTNba2V5XTsKICB9CiAgY29uc3QgcG9seWZpbGxlZEltcG9ydHNTeW1ib2wgPSBTeW1ib2woInBvbHlmaWxsZWRJbXBvcnRzU3ltYm9sIik7CiAgY29uc3QgYXNzaWduSW1wb3J0cyA9IChtb2R1bGUsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdID0gcGFyc2VJbXBvcnRzKHNvdXJjZUJ5dGVzKTsKICB9OwogIGNvbnN0IG5ld01vZHVsZSA9IG5ld1dlYkFzc2VtYmx5Lk1vZHVsZSA9IGZ1bmN0aW9uKGJ5dGVzKSB7CiAgICBjb25zdCBtb2R1bGUgPSBuZXcgV2ViQXNzZW1ibHkzLk1vZHVsZShieXRlcyk7CiAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZSwgbmV3TW9kdWxlLnByb3RvdHlwZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG5ld01vZHVsZS5wcm90b3R5cGUsIFdlYkFzc2VtYmx5My5Nb2R1bGUucHJvdG90eXBlKTsKICBuZXdXZWJBc3NlbWJseS5jb21waWxlID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBzb3VyY2UpOwogICAgcmV0dXJuIG1vZHVsZTsKICB9OwogIGlmIChXZWJBc3NlbWJseTMuY29tcGlsZVN0cmVhbWluZykgewogICAgbmV3V2ViQXNzZW1ibHkuY29tcGlsZVN0cmVhbWluZyA9IGFzeW5jIChzb3VyY2UpID0+IHsKICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBzb3VyY2U7CiAgICAgIGNvbnN0IGNsb25lID0gcmVzcG9uc2UuY2xvbmUoKTsKICAgICAgY29uc3QgbW9kdWxlID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZSwgbmV3IFVpbnQ4QXJyYXkoYXdhaXQgY2xvbmUuYXJyYXlCdWZmZXIoKSkpOwogICAgICByZXR1cm4gbW9kdWxlOwogICAgfTsKICB9CiAgbmV3TW9kdWxlLmltcG9ydHMgPSAobW9kdWxlKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXTsKICAgIGlmICghcGFyc2VkSW1wb3J0cykgewogICAgICByZXR1cm4gV2ViQXNzZW1ibHkzLk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgICB9CiAgICByZXR1cm4gcGFyc2VkSW1wb3J0czsKICB9OwogIHJldHVybiBuZXdXZWJBc3NlbWJseTsKfQoKLy8gZW50cnlwb2ludC9pbnRyaW5zaWNzLnRzCnZhciBXZWJBc3NlbWJseTIgPSBwb2x5ZmlsbChnbG9iYWxUaGlzLldlYkFzc2VtYmx5KTsKdmFyIExpbmVEZWNvZGVyID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG9uTGluZSkgewogICAgdGhpcy5kZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIsIHsgZmF0YWw6IGZhbHNlIH0pOwogICAgdGhpcy5idWZmZXIgPSAiIjsKICAgIHRoaXMub25MaW5lID0gb25MaW5lOwogIH0KICBkZWNvZGVyOwogIGJ1ZmZlcjsKICBvbkxpbmU7CiAgc2VuZChjaHVuaykgewogICAgdGhpcy5idWZmZXIgKz0gdGhpcy5kZWNvZGVyLmRlY29kZShjaHVuaywgeyBzdHJlYW06IHRydWUgfSk7CiAgICBjb25zdCBsaW5lcyA9IHRoaXMuYnVmZmVyLnNwbGl0KCJcbiIpOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGggLSAxOyBpKyspIHsKICAgICAgdGhpcy5vbkxpbmUobGluZXNbaV0pOwogICAgfQogICAgdGhpcy5idWZmZXIgPSBsaW5lc1tsaW5lcy5sZW5ndGggLSAxXTsKICB9Cn07CmFzeW5jIGZ1bmN0aW9uIGluc3RhbnRpYXRlKHJhd09wdGlvbnMsIGV4dHJhV2FzbUltcG9ydHMpIHsKICBjb25zdCBvcHRpb25zID0gZGVmYXVsdEluc3RhbnRpYXRpb25PcHRpb25zKHJhd09wdGlvbnMpOwogIGxldCBzd2lmdCA9IG9wdGlvbnMuc3dpZnQ7CiAgaWYgKCFzd2lmdCAmJiBvcHRpb25zLlN3aWZ0UnVudGltZSkgewogICAgc3dpZnQgPSBuZXcgb3B0aW9ucy5Td2lmdFJ1bnRpbWUoKTsKICB9CiAgbGV0IHN0ZG91dExpbmUgPSB2b2lkIDA7CiAgaWYgKG9wdGlvbnMub25TdGRvdXRMaW5lICE9IG51bGwpIHsKICAgIHN0ZG91dExpbmUgPSBuZXcgTGluZURlY29kZXIob3B0aW9ucy5vblN0ZG91dExpbmUpOwogIH0KICBjb25zdCBzdGRvdXQgPSBuZXcgQ29uc29sZVN0ZG91dCgoY2h1bmspID0+IHsKICAgIG9wdGlvbnMub25TdGRvdXQ/LmNhbGwodm9pZCAwLCBjaHVuayk7CiAgICBzdGRvdXRMaW5lPy5zZW5kKGNodW5rKTsKICB9KTsKICBsZXQgc3RkZXJyTGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZGVyckxpbmUgIT0gbnVsbCkgewogICAgc3RkZXJyTGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3RkZXJyTGluZSk7CiAgfQogIGNvbnN0IHN0ZGVyciA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZGVycj8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZGVyckxpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGNvbnN0IGFyZ3MgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzLCBlbnZzLCBmZHMsIHsKICAgIGRlYnVnOiBmYWxzZQogIH0pOwogIGNvbnN0IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QgPSAoZXh0cmFXYXNtSW1wb3J0czIsIG1vZHVsZSkgPT4gewogICAgY29uc3QgaW1wb3J0T2JqZWN0MiA9IHsKICAgICAgd2FzaV9zbmFwc2hvdF9wcmV2aWV3MTogd2FzaS53YXNpSW1wb3J0CiAgICB9OwogICAgaWYgKHN3aWZ0KSB7CiAgICAgIGltcG9ydE9iamVjdDIuamF2YXNjcmlwdF9raXQgPSBzd2lmdC53YXNtSW1wb3J0czsKICAgIH0KICAgIGlmIChleHRyYVdhc21JbXBvcnRzMikgewogICAgICBmb3IgKGNvbnN0IG1vZHVsZU5hbWUgaW4gZXh0cmFXYXNtSW1wb3J0czIpIHsKICAgICAgICBpZiAoIWltcG9ydE9iamVjdDJbbW9kdWxlTmFtZV0pIHsKICAgICAgICAgIGltcG9ydE9iamVjdDJbbW9kdWxlTmFtZV0gPSB7fTsKICAgICAgICB9CiAgICAgICAgZm9yIChjb25zdCBlbnRyeSBpbiBleHRyYVdhc21JbXBvcnRzMlttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0Mlttb2R1bGVOYW1lXVtlbnRyeV0gPSBleHRyYVdhc21JbXBvcnRzMlttb2R1bGVOYW1lXVtlbnRyeV07CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBmb3IgKGNvbnN0IF9pbXBvcnRFbnRyeSBvZiBXZWJBc3NlbWJseTIuTW9kdWxlLmltcG9ydHMobW9kdWxlKSkgewogICAgICBjb25zdCBpbXBvcnRFbnRyeSA9IF9pbXBvcnRFbnRyeTsKICAgICAgaWYgKCFpbXBvcnRPYmplY3QyW2ltcG9ydEVudHJ5Lm1vZHVsZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3QyW2ltcG9ydEVudHJ5Lm1vZHVsZV0gPSB7fTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0T2JqZWN0MltpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gImZ1bmN0aW9uIikgewogICAgICAgIGltcG9ydE9iamVjdDJbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfSBlbHNlIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJtZW1vcnkiICYmIGltcG9ydEVudHJ5Lm1vZHVsZSA9PSAiZW52IiAmJiBpbXBvcnRFbnRyeS5uYW1lID09ICJtZW1vcnkiKSB7CiAgICAgICAgY29uc3QgdHlwZSA9IGltcG9ydEVudHJ5LnR5cGU7CiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsKICAgICAgICAgIGluaXRpYWw6IHR5cGUubWluaW11bSwKICAgICAgICAgIG1heGltdW06IHR5cGUubWF4aW11bSwKICAgICAgICAgIHNoYXJlZDogdHlwZS5zaGFyZWQKICAgICAgICB9OwogICAgICAgIGltcG9ydE9iamVjdDJbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9IG5ldyBXZWJBc3NlbWJseTIuTWVtb3J5KGRlc2NyaXB0b3IpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0MjsKICB9OwogIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgb3B0aW9ucy5tb2R1bGUpOwogIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgV2ViQXNzZW1ibHkyLmluc3RhbnRpYXRlKG9wdGlvbnMubW9kdWxlLCBpbXBvcnRPYmplY3QpOwogIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICBzd2lmdC5zZXRJbnN0YW5jZShpbnN0YW5jZSk7CiAgfQogIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgIHdhc2kuc3RhcnQoaW5zdGFuY2UpOwogIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUgPT0gImZ1bmN0aW9uIikgewogICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgIGlmIChzd2lmdCAmJiBzd2lmdC5tYWluKSB7CiAgICAgIHN3aWZ0Lm1haW4oKTsKICAgIH0gZWxzZSB7CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5tYWluID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5tYWluKCk7CiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndigwLCAwKTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4geyBpbnN0YW5jZSB9Owp9CmZ1bmN0aW9uIGRlZmF1bHRJbnN0YW50aWF0aW9uT3B0aW9ucyhvcHRpb25zKSB7CiAgaWYgKG9wdGlvbnMuYXJncyA9PSBudWxsKSB7CiAgICBvcHRpb25zLmFyZ3MgPSBbIm1haW4ud2FzbSJdOwogIH0KICBjb25zdCBpc05vZGVKcyA9IHR5cGVvZiBwcm9jZXNzICE9PSAidW5kZWZpbmVkIiAmJiBwcm9jZXNzLnJlbGVhc2UubmFtZSA9PT0gIm5vZGUiOwogIGNvbnN0IGlzV2ViQnJvd3NlciA9IHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiOwogIGlmIChpc05vZGVKcykgewogICAgaWYgKCFvcHRpb25zLm9uU3Rkb3V0KSB7CiAgICAgIG9wdGlvbnMub25TdGRvdXQgPSAoY2h1bmspID0+IHByb2Nlc3Muc3Rkb3V0LndyaXRlKGNodW5rKTsKICAgIH0KICAgIGlmICghb3B0aW9ucy5vblN0ZGVycikgewogICAgICBvcHRpb25zLm9uU3RkZXJyID0gKGNodW5rKSA9PiBwcm9jZXNzLnN0ZGVyci53cml0ZShjaHVuayk7CiAgICB9CiAgfSBlbHNlIGlmIChpc1dlYkJyb3dzZXIpIHsKICAgIGlmICghb3B0aW9ucy5vblN0ZG91dExpbmUpIHsKICAgICAgb3B0aW9ucy5vblN0ZG91dExpbmUgPSAobGluZSkgPT4gY29uc29sZS5sb2cobGluZSk7CiAgICB9CiAgICBpZiAoIW9wdGlvbnMub25TdGRlcnJMaW5lKSB7CiAgICAgIG9wdGlvbnMub25TdGRlcnJMaW5lID0gKGxpbmUpID0+IGNvbnNvbGUud2FybihsaW5lKTsKICAgIH0KICB9CiAgcmV0dXJuIG9wdGlvbnM7Cn0KCi8vIGVudHJ5cG9pbnQvdGVzdC50cwp2YXIgc29ja2V0ID0gbmV3IHJlY29ubmVjdGluZ193ZWJzb2NrZXRfbWpzX2RlZmF1bHQoYHdzOi8vJHtsb2NhdGlvbi5ob3N0fS93YXRjaGVyYCk7CnNvY2tldC5hZGRFdmVudExpc3RlbmVyKCJtZXNzYWdlIiwgKG1lc3NhZ2UpID0+IHsKICBpZiAobWVzc2FnZS5kYXRhID09PSAicmVsb2FkIikgewogICAgbG9jYXRpb24ucmVsb2FkKCk7CiAgfQp9KTsKdmFyIHN0YXJ0V2FzaVRhc2sgPSBhc3luYyAoKSA9PiB7CiAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaCgiL21haW4ud2FzbSIpOwogIGxldCBydW50aW1lQ29uc3RydWN0b3IgPSB2b2lkIDA7CiAgdHJ5IHsKICAgIGNvbnN0IHsgU3dpZnRSdW50aW1lIH0gPSBhd2FpdCBpbXBvcnQoCiAgICAgIC8vIEB0cy1pZ25vcmUKICAgICAgIi4vSmF2YVNjcmlwdEtpdF9KYXZhU2NyaXB0S2l0LnJlc291cmNlcy9SdW50aW1lL2luZGV4Lm1qcyIKICAgICk7CiAgICBydW50aW1lQ29uc3RydWN0b3IgPSBTd2lmdFJ1bnRpbWU7CiAgfSBjYXRjaCB7CiAgICBjb25zb2xlLmxvZygiSmF2YVNjcmlwdEtpdCBtb2R1bGUgbm90IGF2YWlsYWJsZSwgcnVubmluZyB3aXRob3V0IEphdmFTY3JpcHRLaXQgcnVudGltZS4iKTsKICB9CiAgY29uc3QgY29uZmlnID0gYXdhaXQgZmV0Y2goIi9wcm9jZXNzLWluZm8uanNvbiIpLnRoZW4oKHJlc3BvbnNlMikgPT4gcmVzcG9uc2UyLmpzb24oKSk7CiAgbGV0IHRlc3RSdW5PdXRwdXQgPSAiIjsKICBjb25zdCBoYW5kbGVFeGl0T3JFcnJvciA9IChlcnJvcikgPT4gewogICAgaWYgKGVycm9yIGluc3RhbmNlb2YgV0FTSVByb2NFeGl0KSB7CiAgICAgIHNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KHsga2luZDogInRlc3RSdW5PdXRwdXQiLCB0ZXN0UnVuT3V0cHV0IH0pKTsKICAgICAgaWYgKGVycm9yLmNvZGUgPT09IDApIHsKICAgICAgICBzb2NrZXQuc2VuZChKU09OLnN0cmluZ2lmeSh7IGtpbmQ6ICJ0ZXN0UGFzc2VkIiB9KSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgaGFuZGxlRXJyb3IoZXJyb3IpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBoYW5kbGVFcnJvcihlcnJvcik7CiAgICB9CiAgICBjb25zdCBkaXZFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgicCIpOwogICAgZGl2RWxlbWVudC5pbm5lckhUTUwgPSAiVGVzdCBydW4gZmluaXNoZWQuIENoZWNrIHRoZSBvdXRwdXQgb2YgPGNvZGU+Y2FydG9uIHRlc3Q8L2NvZGU+IGZvciBkZXRhaWxzLiI7CiAgICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGRpdkVsZW1lbnQpOwogIH07CiAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoInVuaGFuZGxlZHJlamVjdGlvbiIsIChldmVudCkgPT4gewogICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsKICAgIGNvbnN0IGVycm9yID0gZXZlbnQucmVhc29uOwogICAgaGFuZGxlRXhpdE9yRXJyb3IoZXJyb3IpOwogIH0pOwogIHRyeSB7CiAgICBhd2FpdCBpbnN0YW50aWF0ZSh7CiAgICAgIG1vZHVsZTogYXdhaXQgV2ViQXNzZW1ibHkuY29tcGlsZVN0cmVhbWluZyhyZXNwb25zZSksCiAgICAgIGVudjogY29uZmlnLmVudiwKICAgICAgb25TdGRvdXRMaW5lOiAobGluZSkgPT4gewogICAgICAgIGNvbnNvbGUubG9nKGxpbmUpOwogICAgICAgIHRlc3RSdW5PdXRwdXQgKz0gbGluZSArICJcbiI7CiAgICAgIH0sCiAgICAgIG9uU3RkZXJyTGluZTogKGxpbmUpID0+IHsKICAgICAgICBjb25zb2xlLmVycm9yKGxpbmUpOwogICAgICB9LAogICAgICBTd2lmdFJ1bnRpbWU6IHJ1bnRpbWVDb25zdHJ1Y3RvcgogICAgfSk7CiAgfSBjYXRjaCAoZXJyb3IpIHsKICAgIGhhbmRsZUV4aXRPckVycm9yKGVycm9yKTsKICAgIHJldHVybjsKICB9Cn07CmZ1bmN0aW9uIGhhbmRsZUVycm9yKGUpIHsKICBjb25zb2xlLmVycm9yKGUpOwogIGlmIChlIGluc3RhbmNlb2YgRXJyb3IpIHsKICAgIGNvbnN0IHN0YWNrID0gZS5zdGFjazsKICAgIGlmIChzdGFjayAhPSBudWxsKSB7CiAgICAgIHNvY2tldC5zZW5kKEpTT04uc3RyaW5naWZ5KHsKICAgICAgICBraW5kOiAic3RhY2tUcmFjZSIsCiAgICAgICAgc3RhY2tUcmFjZTogc3RhY2sKICAgICAgfSkpOwogICAgfQogIH0KICBzb2NrZXQuc2VuZChKU09OLnN0cmluZ2lmeSh7CiAgICBraW5kOiAiZXJyb3JSZXBvcnQiLAogICAgZXJyb3JSZXBvcnQ6IGUudG9TdHJpbmcoKQogIH0pKTsKfQphc3luYyBmdW5jdGlvbiBtYWluKCkgewogIHRyeSB7CiAgICBhd2FpdCBzdGFydFdhc2lUYXNrKCk7CiAgfSBjYXRjaCAoZSkgewogICAgaGFuZGxlRXJyb3IoZSk7CiAgfQp9Cm1haW4oKTsKLyohCiAqIFJlY29ubmVjdGluZyBXZWJTb2NrZXQKICogYnkgUGVkcm8gTGFkYXJpYSA8cGVkcm8ubGFkYXJpYUBnbWFpbC5jb20+CiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9wbGFkYXJpYS9yZWNvbm5lY3Rpbmctd2Vic29ja2V0CiAqIExpY2Vuc2UgTUlUCiAqLwovKiEgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgQ29ycG9yYXRpb24uIEFsbCByaWdodHMgcmVzZXJ2ZWQuCkxpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSAiTGljZW5zZSIpOyB5b3UgbWF5IG5vdCB1c2UKdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUKTGljZW5zZSBhdCBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKClRISVMgQ09ERSBJUyBQUk9WSURFRCBPTiBBTiAqQVMgSVMqIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkKS0lORCwgRUlUSEVSIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBBTlkgSU1QTElFRApXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgVElUTEUsIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLApNRVJDSEFOVEFCTElUWSBPUiBOT04tSU5GUklOR0VNRU5ULgoKU2VlIHRoZSBBcGFjaGUgVmVyc2lvbiAyLjAgTGljZW5zZSBmb3Igc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zCmFuZCBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8K")! + public static let testNode: Data = Data(base64Encoded: "dmFyIF9fY3JlYXRlID0gT2JqZWN0LmNyZWF0ZTsKdmFyIF9fZGVmUHJvcCA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eTsKdmFyIF9fZ2V0T3duUHJvcERlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yOwp2YXIgX19nZXRPd25Qcm9wTmFtZXMgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lczsKdmFyIF9fZ2V0UHJvdG9PZiA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjsKdmFyIF9faGFzT3duUHJvcCA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7CnZhciBfX2NvcHlQcm9wcyA9ICh0bywgZnJvbSwgZXhjZXB0LCBkZXNjKSA9PiB7CiAgaWYgKGZyb20gJiYgdHlwZW9mIGZyb20gPT09ICJvYmplY3QiIHx8IHR5cGVvZiBmcm9tID09PSAiZnVuY3Rpb24iKSB7CiAgICBmb3IgKGxldCBrZXkgb2YgX19nZXRPd25Qcm9wTmFtZXMoZnJvbSkpCiAgICAgIGlmICghX19oYXNPd25Qcm9wLmNhbGwodG8sIGtleSkgJiYga2V5ICE9PSBleGNlcHQpCiAgICAgICAgX19kZWZQcm9wKHRvLCBrZXksIHsgZ2V0OiAoKSA9PiBmcm9tW2tleV0sIGVudW1lcmFibGU6ICEoZGVzYyA9IF9fZ2V0T3duUHJvcERlc2MoZnJvbSwga2V5KSkgfHwgZGVzYy5lbnVtZXJhYmxlIH0pOwogIH0KICByZXR1cm4gdG87Cn07CnZhciBfX3RvRVNNID0gKG1vZCwgaXNOb2RlTW9kZSwgdGFyZ2V0KSA9PiAodGFyZ2V0ID0gbW9kICE9IG51bGwgPyBfX2NyZWF0ZShfX2dldFByb3RvT2YobW9kKSkgOiB7fSwgX19jb3B5UHJvcHMoaXNOb2RlTW9kZSB8fCAhbW9kIHx8ICFtb2QuX19lc01vZHVsZSA/IF9fZGVmUHJvcCh0YXJnZXQsICJkZWZhdWx0IiwgeyB2YWx1ZTogbW9kLCBlbnVtZXJhYmxlOiB0cnVlIH0pIDogdGFyZ2V0LCBtb2QpKTsKCi8vIGVudHJ5cG9pbnQvdGVzdE5vZGUudHMKdmFyIGltcG9ydF9wcm9taXNlcyA9IF9fdG9FU00ocmVxdWlyZSgiZnMvcHJvbWlzZXMiKSk7CnZhciBpbXBvcnRfcGF0aCA9IF9fdG9FU00ocmVxdWlyZSgicGF0aCIpKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaV9kZWZzLmpzCnZhciBDTE9DS0lEX1JFQUxUSU1FID0gMDsKdmFyIENMT0NLSURfTU9OT1RPTklDID0gMTsKdmFyIEVSUk5PX1NVQ0NFU1MgPSAwOwp2YXIgRVJSTk9fQkFERiA9IDg7CnZhciBFUlJOT19FWElTVCA9IDIwOwp2YXIgRVJSTk9fSU5WQUwgPSAyODsKdmFyIEVSUk5PX0lTRElSID0gMzE7CnZhciBFUlJOT19OQU1FVE9PTE9ORyA9IDM3Owp2YXIgRVJSTk9fTk9FTlQgPSA0NDsKdmFyIEVSUk5PX05PU1lTID0gNTI7CnZhciBFUlJOT19OT1RESVIgPSA1NDsKdmFyIEVSUk5PX05PVEVNUFRZID0gNTU7CnZhciBFUlJOT19OT1RTVVAgPSA1ODsKdmFyIEVSUk5PX1BFUk0gPSA2MzsKdmFyIEVSUk5PX05PVENBUEFCTEUgPSA3NjsKdmFyIFJJR0hUU19GRF9EQVRBU1lOQyA9IDEgPDwgMDsKdmFyIFJJR0hUU19GRF9SRUFEID0gMSA8PCAxOwp2YXIgUklHSFRTX0ZEX1NFRUsgPSAxIDw8IDI7CnZhciBSSUdIVFNfRkRfRkRTVEFUX1NFVF9GTEFHUyA9IDEgPDwgMzsKdmFyIFJJR0hUU19GRF9TWU5DID0gMSA8PCA0Owp2YXIgUklHSFRTX0ZEX1RFTEwgPSAxIDw8IDU7CnZhciBSSUdIVFNfRkRfV1JJVEUgPSAxIDw8IDY7CnZhciBSSUdIVFNfRkRfQURWSVNFID0gMSA8PCA3Owp2YXIgUklHSFRTX0ZEX0FMTE9DQVRFID0gMSA8PCA4Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0RJUkVDVE9SWSA9IDEgPDwgOTsKdmFyIFJJR0hUU19QQVRIX0NSRUFURV9GSUxFID0gMSA8PCAxMDsKdmFyIFJJR0hUU19QQVRIX0xJTktfU09VUkNFID0gMSA8PCAxMTsKdmFyIFJJR0hUU19QQVRIX0xJTktfVEFSR0VUID0gMSA8PCAxMjsKdmFyIFJJR0hUU19QQVRIX09QRU4gPSAxIDw8IDEzOwp2YXIgUklHSFRTX0ZEX1JFQURESVIgPSAxIDw8IDE0Owp2YXIgUklHSFRTX1BBVEhfUkVBRExJTksgPSAxIDw8IDE1Owp2YXIgUklHSFRTX1BBVEhfUkVOQU1FX1NPVVJDRSA9IDEgPDwgMTY7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfVEFSR0VUID0gMSA8PCAxNzsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMTg7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMTk7CnZhciBSSUdIVFNfUEFUSF9GSUxFU1RBVF9TRVRfVElNRVMgPSAxIDw8IDIwOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX0dFVCA9IDEgPDwgMjE7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1NJWkUgPSAxIDw8IDIyOwp2YXIgUklHSFRTX0ZEX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjM7CnZhciBSSUdIVFNfUEFUSF9TWU1MSU5LID0gMSA8PCAyNDsKdmFyIFJJR0hUU19QQVRIX1JFTU9WRV9ESVJFQ1RPUlkgPSAxIDw8IDI1Owp2YXIgUklHSFRTX1BBVEhfVU5MSU5LX0ZJTEUgPSAxIDw8IDI2Owp2YXIgUklHSFRTX1BPTExfRkRfUkVBRFdSSVRFID0gMSA8PCAyNzsKdmFyIFJJR0hUU19TT0NLX1NIVVRET1dOID0gMSA8PCAyODsKdmFyIElvdmVjID0gY2xhc3MgewogIHN0YXRpYyByZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgY29uc3QgaW92ZWMgPSBuZXcgSW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goSW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBDaW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBDaW92ZWMoKTsKICAgIGlvdmVjLmJ1ZiA9IHZpZXcuZ2V0VWludDMyKHB0ciwgdHJ1ZSk7CiAgICBpb3ZlYy5idWZfbGVuID0gdmlldy5nZXRVaW50MzIocHRyICsgNCwgdHJ1ZSk7CiAgICByZXR1cm4gaW92ZWM7CiAgfQogIHN0YXRpYyByZWFkX2J5dGVzX2FycmF5KHZpZXcsIHB0ciwgbGVuKSB7CiAgICBjb25zdCBpb3ZlY3MgPSBbXTsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgaW92ZWNzLnB1c2goQ2lvdmVjLnJlYWRfYnl0ZXModmlldywgcHRyICsgOCAqIGkpKTsKICAgIH0KICAgIHJldHVybiBpb3ZlY3M7CiAgfQp9Owp2YXIgV0hFTkNFX1NFVCA9IDA7CnZhciBXSEVOQ0VfQ1VSID0gMTsKdmFyIFdIRU5DRV9FTkQgPSAyOwp2YXIgRklMRVRZUEVfQ0hBUkFDVEVSX0RFVklDRSA9IDI7CnZhciBGSUxFVFlQRV9ESVJFQ1RPUlkgPSAzOwp2YXIgRklMRVRZUEVfUkVHVUxBUl9GSUxFID0gNDsKdmFyIERpcmVudCA9IGNsYXNzIHsKICBoZWFkX2xlbmd0aCgpIHsKICAgIHJldHVybiAyNDsKICB9CiAgbmFtZV9sZW5ndGgoKSB7CiAgICByZXR1cm4gdGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoOwogIH0KICB3cml0ZV9oZWFkX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRfbmV4dCwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmRfaW5vLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDMyKHB0ciArIDE2LCB0aGlzLmRpcl9uYW1lLmxlbmd0aCwgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDIwLCB0aGlzLmRfdHlwZSk7CiAgfQogIHdyaXRlX25hbWVfYnl0ZXModmlldzgsIHB0ciwgYnVmX2xlbikgewogICAgdmlldzguc2V0KHRoaXMuZGlyX25hbWUuc2xpY2UoMCwgTWF0aC5taW4odGhpcy5kaXJfbmFtZS5ieXRlTGVuZ3RoLCBidWZfbGVuKSksIHB0cik7CiAgfQogIGNvbnN0cnVjdG9yKG5leHRfY29va2llLCBuYW1lLCB0eXBlKSB7CiAgICB0aGlzLmRfaW5vID0gMG47CiAgICBjb25zdCBlbmNvZGVkX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgICB0aGlzLmRfbmV4dCA9IG5leHRfY29va2llOwogICAgdGhpcy5kX25hbWxlbiA9IGVuY29kZWRfbmFtZS5ieXRlTGVuZ3RoOwogICAgdGhpcy5kX3R5cGUgPSB0eXBlOwogICAgdGhpcy5kaXJfbmFtZSA9IGVuY29kZWRfbmFtZTsKICB9Cn07CnZhciBGREZMQUdTX0FQUEVORCA9IDEgPDwgMDsKdmFyIEZERkxBR1NfRFNZTkMgPSAxIDw8IDE7CnZhciBGREZMQUdTX05PTkJMT0NLID0gMSA8PCAyOwp2YXIgRkRGTEFHU19SU1lOQyA9IDEgPDwgMzsKdmFyIEZERkxBR1NfU1lOQyA9IDEgPDwgNDsKdmFyIEZkc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDgocHRyLCB0aGlzLmZzX2ZpbGV0eXBlKTsKICAgIHZpZXcuc2V0VWludDE2KHB0ciArIDIsIHRoaXMuZnNfZmxhZ3MsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5mc19yaWdodHNfYmFzZSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAxNiwgdGhpcy5mc19yaWdodHNfaW5oZXJpdGVkLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIGZsYWdzKSB7CiAgICB0aGlzLmZzX3JpZ2h0c19iYXNlID0gMG47CiAgICB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQgPSAwbjsKICAgIHRoaXMuZnNfZmlsZXR5cGUgPSBmaWxldHlwZTsKICAgIHRoaXMuZnNfZmxhZ3MgPSBmbGFnczsKICB9Cn07CnZhciBGU1RGTEFHU19BVElNID0gMSA8PCAwOwp2YXIgRlNURkxBR1NfQVRJTV9OT1cgPSAxIDw8IDE7CnZhciBGU1RGTEFHU19NVElNID0gMSA8PCAyOwp2YXIgRlNURkxBR1NfTVRJTV9OT1cgPSAxIDw8IDM7CnZhciBPRkxBR1NfQ1JFQVQgPSAxIDw8IDA7CnZhciBPRkxBR1NfRElSRUNUT1JZID0gMSA8PCAxOwp2YXIgT0ZMQUdTX0VYQ0wgPSAxIDw8IDI7CnZhciBPRkxBR1NfVFJVTkMgPSAxIDw8IDM7CnZhciBGaWxlc3RhdCA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciwgdGhpcy5kZXYsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgOCwgdGhpcy5pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50OChwdHIgKyAxNiwgdGhpcy5maWxldHlwZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAyNCwgdGhpcy5ubGluaywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyAzMiwgdGhpcy5zaXplLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDM4LCB0aGlzLmF0aW0sIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgNDYsIHRoaXMubXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA1MiwgdGhpcy5jdGltLCB0cnVlKTsKICB9CiAgY29uc3RydWN0b3IoZmlsZXR5cGUsIHNpemUpIHsKICAgIHRoaXMuZGV2ID0gMG47CiAgICB0aGlzLmlubyA9IDBuOwogICAgdGhpcy5ubGluayA9IDBuOwogICAgdGhpcy5hdGltID0gMG47CiAgICB0aGlzLm10aW0gPSAwbjsKICAgIHRoaXMuY3RpbSA9IDBuOwogICAgdGhpcy5maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5zaXplID0gc2l6ZTsKICB9Cn07CnZhciBFVkVOVFJXRkxBR1NfRkRfUkVBRFdSSVRFX0hBTkdVUCA9IDEgPDwgMDsKdmFyIFNVQkNMT0NLRkxBR1NfU1VCU0NSSVBUSU9OX0NMT0NLX0FCU1RJTUUgPSAxIDw8IDA7CnZhciBSSUZMQUdTX1JFQ1ZfUEVFSyA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9XQUlUQUxMID0gMSA8PCAxOwp2YXIgUk9GTEFHU19SRUNWX0RBVEFfVFJVTkNBVEVEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19SRCA9IDEgPDwgMDsKdmFyIFNERkxBR1NfV1IgPSAxIDw8IDE7CnZhciBQUkVPUEVOVFlQRV9ESVIgPSAwOwp2YXIgUHJlc3RhdERpciA9IGNsYXNzIHsKICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy5wcl9uYW1lLmJ5dGVMZW5ndGgsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihuYW1lKSB7CiAgICB0aGlzLnByX25hbWUgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUobmFtZSk7CiAgfQp9Owp2YXIgUHJlc3RhdCA9IGNsYXNzIHsKICBzdGF0aWMgZGlyKG5hbWUpIHsKICAgIGNvbnN0IHByZXN0YXQgPSBuZXcgUHJlc3RhdCgpOwogICAgcHJlc3RhdC50YWcgPSBQUkVPUEVOVFlQRV9ESVI7CiAgICBwcmVzdGF0LmlubmVyID0gbmV3IFByZXN0YXREaXIobmFtZSk7CiAgICByZXR1cm4gcHJlc3RhdDsKICB9CiAgd3JpdGVfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldFVpbnQzMihwdHIsIHRoaXMudGFnLCB0cnVlKTsKICAgIHRoaXMuaW5uZXIud3JpdGVfYnl0ZXModmlldywgcHRyICsgNCk7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9kZWJ1Zy5qcwp2YXIgRGVidWcgPSBjbGFzcyBEZWJ1ZzIgewogIGVuYWJsZShlbmFibGVkKSB7CiAgICB0aGlzLmxvZyA9IGNyZWF0ZUxvZ2dlcihlbmFibGVkID09PSB2b2lkIDAgPyB0cnVlIDogZW5hYmxlZCwgdGhpcy5wcmVmaXgpOwogIH0KICBnZXQgZW5hYmxlZCgpIHsKICAgIHJldHVybiB0aGlzLmlzRW5hYmxlZDsKICB9CiAgY29uc3RydWN0b3IoaXNFbmFibGVkKSB7CiAgICB0aGlzLmlzRW5hYmxlZCA9IGlzRW5hYmxlZDsKICAgIHRoaXMucHJlZml4ID0gIndhc2k6IjsKICAgIHRoaXMuZW5hYmxlKGlzRW5hYmxlZCk7CiAgfQp9OwpmdW5jdGlvbiBjcmVhdGVMb2dnZXIoZW5hYmxlZCwgcHJlZml4KSB7CiAgaWYgKGVuYWJsZWQpIHsKICAgIGNvbnN0IGEgPSBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUsICIlYyVzIiwgImNvbG9yOiAjMjY1QkEwIiwgcHJlZml4KTsKICAgIHJldHVybiBhOwogIH0gZWxzZSB7CiAgICByZXR1cm4gKCkgPT4gewogICAgfTsKICB9Cn0KdmFyIGRlYnVnID0gbmV3IERlYnVnKGZhbHNlKTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3Qvd2FzaS5qcwp2YXIgV0FTSVByb2NFeGl0ID0gY2xhc3MgZXh0ZW5kcyBFcnJvciB7CiAgY29uc3RydWN0b3IoY29kZSkgewogICAgc3VwZXIoImV4aXQgd2l0aCBleGl0IGNvZGUgIiArIGNvZGUpOwogICAgdGhpcy5jb2RlID0gY29kZTsKICB9Cn07CnZhciBXQVNJID0gY2xhc3MgV0FTSTIgewogIHN0YXJ0KGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIHRyeSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX3N0YXJ0KCk7CiAgICAgIHJldHVybiAwOwogICAgfSBjYXRjaCAoZSkgewogICAgICBpZiAoZSBpbnN0YW5jZW9mIFdBU0lQcm9jRXhpdCkgewogICAgICAgIHJldHVybiBlLmNvZGU7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgdGhyb3cgZTsKICAgICAgfQogICAgfQogIH0KICBpbml0aWFsaXplKGluc3RhbmNlKSB7CiAgICB0aGlzLmluc3QgPSBpbnN0YW5jZTsKICAgIGlmIChpbnN0YW5jZS5leHBvcnRzLl9pbml0aWFsaXplKSB7CiAgICAgIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUoKTsKICAgIH0KICB9CiAgY29uc3RydWN0b3IoYXJnczIsIGVudiwgZmRzLCBvcHRpb25zID0ge30pIHsKICAgIHRoaXMuYXJncyA9IFtdOwogICAgdGhpcy5lbnYgPSBbXTsKICAgIHRoaXMuZmRzID0gW107CiAgICBkZWJ1Zy5lbmFibGUob3B0aW9ucy5kZWJ1Zyk7CiAgICB0aGlzLmFyZ3MgPSBhcmdzMjsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gc2VsZi5mZHNbZmRdLnBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfZ2V0KGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aDIpOwogICAgICAgIGlmIChmaWxlc3RhdCAhPSBudWxsKSB7CiAgICAgICAgICBmaWxlc3RhdC53cml0ZV9ieXRlcyhidWZmZXIsIGZpbGVzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfZmlsZXN0YXRfc2V0X3RpbWVzKGZkLCBmbGFncywgcGF0aF9wdHIsIHBhdGhfbGVuLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X3NldF90aW1lcyhmbGFncywgcGF0aDIsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgZGVidWcubG9nKHBhdGgyKTsKICAgICAgICBjb25zdCB7IHJldCwgZmRfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoMiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aDIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aDIpOwogICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF9yZWFkbGluayhwYXRoMik7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoMiA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZW5hbWUoZmQsIG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBuZXdfZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgbGV0IHsgcmV0LCBpbm9kZV9vYmogfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX3VubGluayhvbGRfcGF0aCk7CiAgICAgICAgaWYgKGlub2RlX29iaiA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICByZXQgPSBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKTsKICAgICAgICBpZiAocmV0ICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgIGlmIChzZWxmLmZkc1tmZF0ucGF0aF9saW5rKG9sZF9wYXRoLCBpbm9kZV9vYmosIHRydWUpICE9IEVSUk5PX1NVQ0NFU1MpIHsKICAgICAgICAgICAgdGhyb3cgInBhdGhfbGluayBzaG91bGQgYWx3YXlzIHJldHVybiBzdWNjZXNzIHdoZW4gcmVsaW5raW5nIGFuIGlub2RlIGJhY2sgdG8gdGhlIG9yaWdpbmFsIHBsYWNlIjsKICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9zeW1saW5rKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfbGVuLCBmZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IG9sZF9wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9sZF9wYXRoX3B0ciwgb2xkX3BhdGhfcHRyICsgb2xkX3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgbmV3X3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UobmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9wdHIgKyBuZXdfcGF0aF9sZW4pKTsKICAgICAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX3VubGlua19maWxlKGZkLCBwYXRoX3B0ciwgcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGgyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgyKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcG9sbF9vbmVvZmYoaW5fLCBvdXQsIG5zdWJzY3JpcHRpb25zKSB7CiAgICAgIHRocm93ICJhc3luYyBpbyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHByb2NfZXhpdChleGl0X2NvZGUpIHsKICAgICAgdGhyb3cgbmV3IFdBU0lQcm9jRXhpdChleGl0X2NvZGUpOwogICAgfSwgcHJvY19yYWlzZShzaWcpIHsKICAgICAgdGhyb3cgInJhaXNlZCBzaWduYWwgIiArIHNpZzsKICAgIH0sIHNjaGVkX3lpZWxkKCkgewogICAgfSwgcmFuZG9tX2dldChidWYsIGJ1Zl9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGJ1Zl9sZW47IGkrKykgewogICAgICAgIGJ1ZmZlcjhbYnVmICsgaV0gPSBNYXRoLnJhbmRvbSgpICogMjU2IHwgMDsKICAgICAgfQogICAgfSwgc29ja19yZWN2KGZkLCByaV9kYXRhLCByaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2VuZChmZCwgc2lfZGF0YSwgc2lfZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX3NodXRkb3duKGZkLCBob3cpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9LCBzb2NrX2FjY2VwdChmZCwgZmxhZ3MpIHsKICAgICAgdGhyb3cgInNvY2tldHMgbm90IHN1cHBvcnRlZCI7CiAgICB9IH07CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mZC5qcwp2YXIgRmQgPSBjbGFzcyB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Nsb3NlKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmRzdGF0OiBudWxsIH07CiAgfQogIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2Zkc3RhdF9zZXRfcmlnaHRzKGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGZpbGVzdGF0OiBudWxsIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgcHJlc3RhdDogbnVsbCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkaXJlbnQ6IG51bGwgfTsKICB9CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfc3luYygpIHsKICAgIHJldHVybiAwOwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIG53cml0dGVuOiAwIH07CiAgfQogIHBhdGhfY3JlYXRlX2RpcmVjdG9yeShwYXRoMikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9maWxlc3RhdF9nZXQoZmxhZ3MsIHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgyLCBhdGltLCBtdGltLCBmc3RfZmxhZ3MpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfbGluayhwYXRoMiwgaW5vZGUsIGFsbG93X2RpcikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF91bmxpbmsocGF0aDIpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aDIsIGRpcmZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgaW5vZGVfb2JqOiBudWxsIH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aDIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGZkX29iajogbnVsbCB9OwogIH0KICBwYXRoX3JlYWRsaW5rKHBhdGgyKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfcmVuYW1lKG9sZF9wYXRoLCBuZXdfZmQsIG5ld19wYXRoKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGgyKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KfTsKdmFyIElub2RlID0gY2xhc3Mgewp9OwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC9mc19tZW0uanMKdmFyIE9wZW5GaWxlID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IG9mZnNldCArIGxlbikgewogICAgfSBlbHNlIHsKICAgICAgY29uc3QgbmV3X2RhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgbGVuKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX1JFR1VMQVJfRklMRSwgMCkgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgaWYgKHRoaXMuZmlsZS5zaXplID4gc2l6ZSkgewogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KHRoaXMuZmlsZS5kYXRhLmJ1ZmZlci5zbGljZSgwLCBOdW1iZXIoc2l6ZSkpKTsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHNpemUpKTsKICAgICAgbmV3X2RhdGEuc2V0KHRoaXMuZmlsZS5kYXRhLCAwKTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXdfZGF0YTsKICAgIH0KICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIGNvbnN0IHNsaWNlID0gdGhpcy5maWxlLmRhdGEuc2xpY2UoTnVtYmVyKHRoaXMuZmlsZV9wb3MpLCBOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChzaXplKSkpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoc2xpY2UubGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgZGF0YTogc2xpY2UgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcihvZmZzZXQpLCBOdW1iZXIob2Zmc2V0ICsgQmlnSW50KHNpemUpKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIGxldCBjYWxjdWxhdGVkX29mZnNldDsKICAgIHN3aXRjaCAod2hlbmNlKSB7CiAgICAgIGNhc2UgV0hFTkNFX1NFVDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfQ1VSOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gdGhpcy5maWxlX3BvcyArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgY2FzZSBXSEVOQ0VfRU5EOgogICAgICAgIGNhbGN1bGF0ZWRfb2Zmc2V0ID0gQmlnSW50KHRoaXMuZmlsZS5kYXRhLmJ5dGVMZW5ndGgpICsgb2Zmc2V0OwogICAgICAgIGJyZWFrOwogICAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIGlmIChjYWxjdWxhdGVkX29mZnNldCA8IDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgb2Zmc2V0OiAwbiB9OwogICAgfQogICAgdGhpcy5maWxlX3BvcyA9IGNhbGN1bGF0ZWRfb2Zmc2V0OwogICAgcmV0dXJuIHsgcmV0OiAwLCBvZmZzZXQ6IHRoaXMuZmlsZV9wb3MgfTsKICB9CiAgZmRfdGVsbCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3dyaXRlKGRhdGEpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmICh0aGlzLmZpbGVfcG9zICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpKSk7CiAgICAgIHRoaXMuZmlsZS5kYXRhLnNldChvbGQpOwogICAgfQogICAgdGhpcy5maWxlLmRhdGEuc2V0KGRhdGEsIE51bWJlcih0aGlzLmZpbGVfcG9zKSk7CiAgICB0aGlzLmZpbGVfcG9zICs9IEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIGlmICh0aGlzLmZpbGUucmVhZG9ubHkpCiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICAgIGlmIChvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSA+IHRoaXMuZmlsZS5zaXplKSB7CiAgICAgIGNvbnN0IG9sZCA9IHRoaXMuZmlsZS5kYXRhOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihvZmZzZXQgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIob2Zmc2V0KSk7CiAgICByZXR1cm4geyByZXQ6IDAsIG53cml0dGVuOiBkYXRhLmJ5dGVMZW5ndGggfTsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5maWxlLnN0YXQoKSB9OwogIH0KICBjb25zdHJ1Y3RvcihmaWxlKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5maWxlX3BvcyA9IDBuOwogICAgdGhpcy5maWxlID0gZmlsZTsKICB9Cn07CnZhciBPcGVuRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBGZCB7CiAgZmRfc2VlayhvZmZzZXQsIHdoZW5jZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG9mZnNldDogMG4gfTsKICB9CiAgZmRfYWxsb2NhdGUob2Zmc2V0LCBsZW4pIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9mZHN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmZHN0YXQ6IG5ldyBGZHN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwKSB9OwogIH0KICBmZF9yZWFkZGlyX3NpbmdsZShjb29raWUpIHsKICAgIGlmIChkZWJ1Zy5lbmFibGVkKSB7CiAgICAgIGRlYnVnLmxvZygicmVhZGRpcl9zaW5nbGUiLCBjb29raWUpOwogICAgICBkZWJ1Zy5sb2coY29va2llLCB0aGlzLmRpci5jb250ZW50cy5rZXlzKCkpOwogICAgfQogICAgaWYgKGNvb2tpZSA9PSAwbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgxbiwgIi4iLCBGSUxFVFlQRV9ESVJFQ1RPUlkpIH07CiAgICB9IGVsc2UgaWYgKGNvb2tpZSA9PSAxbikgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGRpcmVudDogbmV3IERpcmVudCgybiwgIi4uIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfQogICAgaWYgKGNvb2tpZSA+PSBCaWdJbnQodGhpcy5kaXIuY29udGVudHMuc2l6ZSkgKyAybikgewogICAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbnVsbCB9OwogICAgfQogICAgY29uc3QgW25hbWUsIGVudHJ5XSA9IEFycmF5LmZyb20odGhpcy5kaXIuY29udGVudHMuZW50cmllcygpKVtOdW1iZXIoY29va2llIC0gMm4pXTsKICAgIHJldHVybiB7IHJldDogMCwgZGlyZW50OiBuZXcgRGlyZW50KGNvb2tpZSArIDFuLCBuYW1lLCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUpIH07CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoX3N0cikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfZXJyLCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9lcnIsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGZpbGVzdGF0OiBudWxsIH07CiAgICB9CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0OiBlbnRyeS5zdGF0KCkgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aF9zdHIsIGRpcmZsYWdzKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBjb25zdCB7IHJldCwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9lbnRyeV9mb3JfcGF0aChwYXRoMik7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfb3BlbihkaXJmbGFncywgcGF0aF9zdHIsIG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nLCBmZF9mbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChlbnRyeSA9PSBudWxsKSB7CiAgICAgIGlmIChyZXQgIT0gRVJSTk9fTk9FTlQpIHsKICAgICAgICByZXR1cm4geyByZXQsIGZkX29iajogbnVsbCB9OwogICAgICB9CiAgICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0NSRUFUKSA9PSBPRkxBR1NfQ1JFQVQpIHsKICAgICAgICBjb25zdCB7IHJldDogcmV0MiwgZW50cnk6IG5ld19lbnRyeSB9ID0gdGhpcy5kaXIuY3JlYXRlX2VudHJ5X2Zvcl9wYXRoKHBhdGhfc3RyLCAob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSk7CiAgICAgICAgaWYgKG5ld19lbnRyeSA9PSBudWxsKSB7CiAgICAgICAgICByZXR1cm4geyByZXQ6IHJldDIsIGZkX29iajogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBlbnRyeSA9IG5ld19lbnRyeTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgfSBlbHNlIGlmICgob2ZsYWdzICYgT0ZMQUdTX0VYQ0wpID09IE9GTEFHU19FWENMKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfRElSRUNUT1JZKSA9PSBPRkxBR1NfRElSRUNUT1JZICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiBlbnRyeS5wYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpOwogIH0KICBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkocGF0aDIpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoMiwgT0ZMQUdTX0NSRUFUIHwgT0ZMQUdTX0RJUkVDVE9SWSwgMG4sIDBuLCAwKS5yZXQ7CiAgfQogIHBhdGhfbGluayhwYXRoX3N0ciwgaW5vZGUsIGFsbG93X2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoOiBwYXRoMiB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoMiA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoMi5pc19kaXIpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aDIsIHRydWUpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICBjb25zdCBzb3VyY2VfaXNfZGlyID0gaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX0RJUkVDVE9SWTsKICAgICAgY29uc3QgdGFyZ2V0X2lzX2RpciA9IGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGlmIChzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICBpZiAoYWxsb3dfZGlyICYmIGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB7CiAgICAgICAgICBpZiAoZW50cnkuY29udGVudHMuc2l6ZSA9PSAwKSB7CiAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gRVJSTk9fTk9URU1QVFk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgIHJldHVybiBFUlJOT19FWElTVDsKICAgICAgICB9CiAgICAgIH0gZWxzZSBpZiAoc291cmNlX2lzX2RpciAmJiAhdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19OT1RESVI7CiAgICAgIH0gZWxzZSBpZiAoIXNvdXJjZV9pc19kaXIgJiYgdGFyZ2V0X2lzX2RpcikgewogICAgICAgIHJldHVybiBFUlJOT19JU0RJUjsKICAgICAgfSBlbHNlIGlmIChpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFICYmIGVudHJ5LnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUpIHsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgIH0KICAgIH0KICAgIGlmICghYWxsb3dfZGlyICYmIGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX1BFUk07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuc2V0KGZpbGVuYW1lLCBpbm9kZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF91bmxpbmsocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5kZWxldGUoZmlsZW5hbWUpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBpbm9kZV9vYmo6IGVudHJ5IH07CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aDogcGF0aDIgfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aDIgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGF0aF9yZXQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgZmFsc2UpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsIHx8IGZpbGVuYW1lID09IG51bGwgfHwgZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4gcGFyZW50X3JldDsKICAgIH0KICAgIGlmICghKGVudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSB8fCBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgfQogICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgIT09IDApIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgfQogICAgaWYgKCFwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKSkgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfZmlsZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogdGhpcy5kaXIuc3RhdCgpIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIHJldHVybiBFUlJOT19CQURGOwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVhZChzaXplLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgbndyaXR0ZW46IDAgfTsKICB9CiAgY29uc3RydWN0b3IoZGlyKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kaXIgPSBkaXI7CiAgfQp9Owp2YXIgUHJlb3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgT3BlbkRpcmVjdG9yeSB7CiAgZmRfcHJlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIHByZXN0YXQ6IFByZXN0YXQuZGlyKHRoaXMucHJlc3RhdF9uYW1lKSB9OwogIH0KICBjb25zdHJ1Y3RvcihuYW1lLCBjb250ZW50cykgewogICAgc3VwZXIobmV3IERpcmVjdG9yeShjb250ZW50cykpOwogICAgdGhpcy5wcmVzdGF0X25hbWUgPSBuYW1lOwogIH0KfTsKdmFyIEZpbGUgPSBjbGFzcyBleHRlbmRzIElub2RlIHsKICBwYXRoX29wZW4ob2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZmRfZmxhZ3MpIHsKICAgIGlmICh0aGlzLnJlYWRvbmx5ICYmIChmc19yaWdodHNfYmFzZSAmIEJpZ0ludChSSUdIVFNfRkRfV1JJVEUpKSA9PSBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKChvZmxhZ3MgJiBPRkxBR1NfVFJVTkMpID09IE9GTEFHU19UUlVOQykgewogICAgICBpZiAodGhpcy5yZWFkb25seSkKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX1BFUk0sIGZkX29iajogbnVsbCB9OwogICAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShbXSk7CiAgICB9CiAgICBjb25zdCBmaWxlID0gbmV3IE9wZW5GaWxlKHRoaXMpOwogICAgaWYgKGZkX2ZsYWdzICYgRkRGTEFHU19BUFBFTkQpCiAgICAgIGZpbGUuZmRfc2VlaygwbiwgV0hFTkNFX0VORCk7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogZmlsZSB9OwogIH0KICBnZXQgc2l6ZSgpIHsKICAgIHJldHVybiBCaWdJbnQodGhpcy5kYXRhLmJ5dGVMZW5ndGgpOwogIH0KICBzdGF0KCkgewogICAgcmV0dXJuIG5ldyBGaWxlc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIHRoaXMuc2l6ZSk7CiAgfQogIGNvbnN0cnVjdG9yKGRhdGEsIG9wdGlvbnMpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLmRhdGEgPSBuZXcgVWludDhBcnJheShkYXRhKTsKICAgIHRoaXMucmVhZG9ubHkgPSAhIW9wdGlvbnM/LnJlYWRvbmx5OwogIH0KfTsKdmFyIFBhdGggPSBjbGFzcyBQYXRoMiB7CiAgc3RhdGljIGZyb20ocGF0aDIpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aDIuZW5kc1dpdGgoIi8iKTsKICAgIGlmIChwYXRoMi5zdGFydHNXaXRoKCIvIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICB9CiAgICBpZiAocGF0aDIuaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aDIuc3BsaXQoIi8iKSkgewogICAgICBpZiAoY29tcG9uZW50ID09PSAiIiB8fCBjb21wb25lbnQgPT09ICIuIikgewogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIuLiIpIHsKICAgICAgICBpZiAoc2VsZi5wYXJ0cy5wb3AoKSA9PSB2b2lkIDApIHsKICAgICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgICAgIH0KICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBzZWxmLnBhcnRzLnB1c2goY29tcG9uZW50KTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGF0aDogc2VsZiB9OwogIH0KICB0b19wYXRoX3N0cmluZygpIHsKICAgIGxldCBzID0gdGhpcy5wYXJ0cy5qb2luKCIvIik7CiAgICBpZiAodGhpcy5pc19kaXIpIHsKICAgICAgcyArPSAiLyI7CiAgICB9CiAgICByZXR1cm4gczsKICB9CiAgY29uc3RydWN0b3IoKSB7CiAgICB0aGlzLnBhcnRzID0gW107CiAgICB0aGlzLmlzX2RpciA9IGZhbHNlOwogIH0KfTsKdmFyIERpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgSW5vZGUgewogIHBhdGhfb3BlbihvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmZF9mbGFncykgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IG5ldyBPcGVuRGlyZWN0b3J5KHRoaXMpIH07CiAgfQogIHN0YXQoKSB7CiAgICByZXR1cm4gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMG4pOwogIH0KICBnZXRfZW50cnlfZm9yX3BhdGgocGF0aDIpIHsKICAgIGxldCBlbnRyeSA9IHRoaXM7CiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiBwYXRoMi5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGVudHJ5IH07CiAgfQogIGdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoMiwgYWxsb3dfdW5kZWZpbmVkKSB7CiAgICBjb25zdCBmaWxlbmFtZSA9IHBhdGgyLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgyKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IGVudHJ5X3JldCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmICghKHBhcmVudF9lbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBjb25zdCBlbnRyeSA9IHBhcmVudF9lbnRyeS5jb250ZW50cy5nZXQoZmlsZW5hbWUpOwogICAgaWYgKGVudHJ5ID09PSB2b2lkIDApIHsKICAgICAgaWYgKCFhbGxvd191bmRlZmluZWQpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PRU5ULCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGgyLmlzX2RpcikgewogICAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH07CiAgfQogIGNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgaXNfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGg6IHBhdGgyIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGgyID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGxldCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgyLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGFyZW50X3JldCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGlmIChlbnRyeSAhPSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fRVhJU1QsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBkZWJ1Zy5sb2coImNyZWF0ZSIsIHBhdGgyKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvaW5kZXguanMKZnVuY3Rpb24gcGFyc2VJbXBvcnRzKG1vZHVsZUJ5dGVzKSB7CiAgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcyk7CiAgfSBlbHNlIGlmIChtb2R1bGVCeXRlcy5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcy5idWZmZXIpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoIkFyZ3VtZW50IG11c3QgYmUgYSBidWZmZXIgc291cmNlLCBsaWtlIFVpbnQ4QXJyYXkgb3IgQXJyYXlCdWZmZXIiKTsKICB9CiAgY29uc3QgcGFyc2VTdGF0ZSA9IG5ldyBQYXJzZVN0YXRlKG1vZHVsZUJ5dGVzKTsKICBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpOwogIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKTsKICBjb25zdCB0eXBlcyA9IFtdOwogIGNvbnN0IGltcG9ydHMgPSBbXTsKICB3aGlsZSAocGFyc2VTdGF0ZS5oYXNNb3JlQnl0ZXMoKSkgewogICAgY29uc3Qgc2VjdGlvbklkID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgY29uc3Qgc2VjdGlvblNpemUgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgc3dpdGNoIChzZWN0aW9uSWQpIHsKICAgICAgY2FzZSAxOiB7CiAgICAgICAgY29uc3QgdHlwZUNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVDb3VudDsgaSsrKSB7CiAgICAgICAgICB0eXBlcy5wdXNoKHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAyOiB7CiAgICAgICAgY29uc3QgaW1wb3J0Q291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW1wb3J0Q291bnQ7IGkrKykgewogICAgICAgICAgY29uc3QgbW9kdWxlMiA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IG5hbWUgPSBwYXJzZVN0YXRlLnJlYWROYW1lKCk7CiAgICAgICAgICBjb25zdCB0eXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgICAgICAgc3dpdGNoICh0eXBlKSB7CiAgICAgICAgICAgIGNhc2UgMDoKICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlOiBtb2R1bGUyLCBuYW1lLCBraW5kOiAiZnVuY3Rpb24iLCB0eXBlOiB0eXBlc1tpbmRleF0gfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMToKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGU6IG1vZHVsZTIsIG5hbWUsIGtpbmQ6ICJ0YWJsZSIsIHR5cGU6IHBhcnNlVGFibGVUeXBlKHBhcnNlU3RhdGUpIH0pOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIDI6CiAgICAgICAgICAgICAgaW1wb3J0cy5wdXNoKHsgbW9kdWxlOiBtb2R1bGUyLCBuYW1lLCBraW5kOiAibWVtb3J5IiwgdHlwZTogcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGU6IG1vZHVsZTIsIG5hbWUsIGtpbmQ6ICJnbG9iYWwiLCB0eXBlOiBwYXJzZUdsb2JhbFR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIGltcG9ydCBkZXNjcmlwdG9yIHR5cGUgJHt0eXBlfWApOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gaW1wb3J0czsKICAgICAgfQogICAgICBkZWZhdWx0OiB7CiAgICAgICAgcGFyc2VTdGF0ZS5za2lwQnl0ZXMoc2VjdGlvblNpemUpOwogICAgICAgIGJyZWFrOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbXTsKfQp2YXIgUGFyc2VTdGF0ZSA9IGNsYXNzIHsKICBjb25zdHJ1Y3Rvcihtb2R1bGVCeXRlcykgewogICAgdGhpcy5tb2R1bGVCeXRlcyA9IG1vZHVsZUJ5dGVzOwogICAgdGhpcy5vZmZzZXQgPSAwOwogICAgdGhpcy50ZXh0RGVjb2RlciA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKTsKICB9CiAgaGFzTW9yZUJ5dGVzKCkgewogICAgcmV0dXJuIHRoaXMub2Zmc2V0IDwgdGhpcy5tb2R1bGVCeXRlcy5sZW5ndGg7CiAgfQogIHJlYWRCeXRlKCkgewogICAgcmV0dXJuIHRoaXMubW9kdWxlQnl0ZXNbdGhpcy5vZmZzZXQrK107CiAgfQogIHNraXBCeXRlcyhjb3VudCkgewogICAgdGhpcy5vZmZzZXQgKz0gY291bnQ7CiAgfQogIHJlYWRVbnNpZ25lZExFQjEyOCgpIHsKICAgIGxldCByZXN1bHQgPSAwOwogICAgbGV0IHNoaWZ0ID0gMDsKICAgIGxldCBieXRlOwogICAgZG8gewogICAgICBieXRlID0gdGhpcy5yZWFkQnl0ZSgpOwogICAgICByZXN1bHQgfD0gKGJ5dGUgJiAxMjcpIDw8IHNoaWZ0OwogICAgICBzaGlmdCArPSA3OwogICAgfSB3aGlsZSAoYnl0ZSAmIDEyOCk7CiAgICByZXR1cm4gcmVzdWx0OwogIH0KICByZWFkTmFtZSgpIHsKICAgIGNvbnN0IG5hbWVMZW5ndGggPSB0aGlzLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgY29uc3QgbmFtZUJ5dGVzID0gdGhpcy5tb2R1bGVCeXRlcy5zbGljZSh0aGlzLm9mZnNldCwgdGhpcy5vZmZzZXQgKyBuYW1lTGVuZ3RoKTsKICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHREZWNvZGVyLmRlY29kZShuYW1lQnl0ZXMpOwogICAgdGhpcy5vZmZzZXQgKz0gbmFtZUxlbmd0aDsKICAgIHJldHVybiBuYW1lOwogIH0KICBhc3NlcnRCeXRlcyhleHBlY3RlZCkgewogICAgY29uc3QgYmFzZU9mZnNldCA9IHRoaXMub2Zmc2V0OwogICAgY29uc3QgZXhwZWN0ZWRMZW5ndGggPSBleHBlY3RlZC5sZW5ndGg7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cGVjdGVkTGVuZ3RoOyBpKyspIHsKICAgICAgaWYgKHRoaXMubW9kdWxlQnl0ZXNbYmFzZU9mZnNldCArIGldICE9PSBleHBlY3RlZFtpXSkgewogICAgICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgJHtleHBlY3RlZH0gYXQgb2Zmc2V0ICR7YmFzZU9mZnNldH1gKTsKICAgICAgfQogICAgfQogICAgdGhpcy5vZmZzZXQgKz0gZXhwZWN0ZWRMZW5ndGg7CiAgfQp9OwpmdW5jdGlvbiBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFswLCA5NywgMTE1LCAxMDldOwogIHBhcnNlU3RhdGUuYXNzZXJ0Qnl0ZXMoZXhwZWN0ZWQpOwp9CmZ1bmN0aW9uIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKSB7CiAgY29uc3QgZXhwZWN0ZWQgPSBbMSwgMCwgMCwgMF07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGVsZW1lbnRUeXBlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGxldCBlbGVtZW50OwogIHN3aXRjaCAoZWxlbWVudFR5cGUpIHsKICAgIGNhc2UgMTEyOgogICAgICBlbGVtZW50ID0gImZ1bmNyZWYiOwogICAgICBicmVhazsKICAgIGNhc2UgMTExOgogICAgICBlbGVtZW50ID0gImV4dGVybnJlZiI7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIHRhYmxlIGVsZW1lbnQgdHlwZSAke2VsZW1lbnRUeXBlfWApOwogIH0KICBjb25zdCB7IG1pbmltdW0sIG1heGltdW0gfSA9IHBhcnNlTGltaXRzKHBhcnNlU3RhdGUpOwogIGlmIChtYXhpbXVtKSB7CiAgICByZXR1cm4geyBlbGVtZW50LCBtaW5pbXVtLCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0gfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZsYWdzID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGNvbnN0IG1pbmltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGNvbnN0IGhhc01heGltdW0gPSBmbGFncyAmIDE7CiAgY29uc3Qgc2hhcmVkID0gKGZsYWdzICYgMikgIT09IDA7CiAgY29uc3QgaXNNZW1vcnk2NCA9IChmbGFncyAmIDQpICE9PSAwOwogIGNvbnN0IGluZGV4ID0gaXNNZW1vcnk2NCA/ICJpNjQiIDogImkzMiI7CiAgaWYgKGhhc01heGltdW0pIHsKICAgIGNvbnN0IG1heGltdW0gPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgcmV0dXJuIHsgbWluaW11bSwgc2hhcmVkLCBpbmRleCwgbWF4aW11bSB9OwogIH0gZWxzZSB7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4IH07CiAgfQp9CmZ1bmN0aW9uIHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdmFsdWUgPSBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKTsKICBjb25zdCBtdXRhYmxlID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpID09PSAxOwogIHJldHVybiB7IHZhbHVlLCBtdXRhYmxlIH07Cn0KZnVuY3Rpb24gcGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIDEyNzoKICAgICAgcmV0dXJuICJpMzIiOwogICAgY2FzZSAxMjY6CiAgICAgIHJldHVybiAiaTY0IjsKICAgIGNhc2UgMTI1OgogICAgICByZXR1cm4gImYzMiI7CiAgICBjYXNlIDEyNDoKICAgICAgcmV0dXJuICJmNjQiOwogICAgY2FzZSAxMTI6CiAgICAgIHJldHVybiAiZnVuY3JlZiI7CiAgICBjYXNlIDExMToKICAgICAgcmV0dXJuICJleHRlcm5yZWYiOwogICAgY2FzZSAxMjM6CiAgICAgIHJldHVybiAidjEyOCI7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdmFsdWUgdHlwZSAke3R5cGV9YCk7CiAgfQp9CmZ1bmN0aW9uIHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCBmb3JtID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogIGlmIChmb3JtICE9PSA5NikgewogICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBmdW5jdGlvbiB0eXBlIGZvcm0gMHg2MCwgZ290ICR7Zm9ybX1gKTsKICB9CiAgY29uc3QgcGFyYW1ldGVycyA9IFtdOwogIGNvbnN0IHBhcmFtZXRlckNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHBhcmFtZXRlckNvdW50OyBpKyspIHsKICAgIHBhcmFtZXRlcnMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIGNvbnN0IHJlc3VsdHMgPSBbXTsKICBjb25zdCByZXN1bHRDb3VudCA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgZm9yIChsZXQgaSA9IDA7IGkgPCByZXN1bHRDb3VudDsgaSsrKSB7CiAgICByZXN1bHRzLnB1c2gocGFyc2VWYWx1ZVR5cGUocGFyc2VTdGF0ZSkpOwogIH0KICByZXR1cm4geyBwYXJhbWV0ZXJzLCByZXN1bHRzIH07Cn0KCi8vIG5vZGVfbW9kdWxlcy93YXNtLWltcG9ydHMtcGFyc2VyL3BvbHlmaWxsLmpzCnZhciBoYXNXYXNtVHlwZVJlZmxlY3Rpb25TdXBwb3J0ID0gKCgpID0+IHsKICBjb25zdCBtb2R1bGVCeXRlcyA9IG5ldyBVaW50OEFycmF5KFsKICAgIDAsCiAgICA5NywKICAgIDExNSwKICAgIDEwOSwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDAsCiAgICAyLAogICAgNiwKICAgIDEsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICAwLAogICAgMQogIF0pOwogIGNvbnN0IG1vZHVsZTIgPSBuZXcgV2ViQXNzZW1ibHkuTW9kdWxlKG1vZHVsZUJ5dGVzKTsKICBjb25zdCBpbXBvcnRzID0gV2ViQXNzZW1ibHkuTW9kdWxlLmltcG9ydHMobW9kdWxlMik7CiAgY29uc3QgbWVtb3J5SW1wb3J0ID0gaW1wb3J0c1swXTsKICByZXR1cm4gdHlwZW9mIG1lbW9yeUltcG9ydC50eXBlID09PSAib2JqZWN0IjsKfSkoKTsKZnVuY3Rpb24gcG9seWZpbGwoV2ViQXNzZW1ibHkzKSB7CiAgaWYgKGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQpIHsKICAgIHJldHVybiBXZWJBc3NlbWJseTM7CiAgfQogIGNvbnN0IG5ld1dlYkFzc2VtYmx5ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoV2ViQXNzZW1ibHkzKSkgewogICAgbmV3V2ViQXNzZW1ibHlba2V5XSA9IFdlYkFzc2VtYmx5M1trZXldOwogIH0KICBjb25zdCBwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbCA9IFN5bWJvbCgicG9seWZpbGxlZEltcG9ydHNTeW1ib2wiKTsKICBjb25zdCBhc3NpZ25JbXBvcnRzID0gKG1vZHVsZTIsIHNvdXJjZUJ5dGVzKSA9PiB7CiAgICBtb2R1bGUyW3BvbHlmaWxsZWRJbXBvcnRzU3ltYm9sXSA9IHBhcnNlSW1wb3J0cyhzb3VyY2VCeXRlcyk7CiAgfTsKICBjb25zdCBuZXdNb2R1bGUgPSBuZXdXZWJBc3NlbWJseS5Nb2R1bGUgPSBmdW5jdGlvbihieXRlcykgewogICAgY29uc3QgbW9kdWxlMiA9IG5ldyBXZWJBc3NlbWJseTMuTW9kdWxlKGJ5dGVzKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlMiwgYnl0ZXMpOwogICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKG1vZHVsZTIsIG5ld01vZHVsZS5wcm90b3R5cGUpOwogICAgcmV0dXJuIG1vZHVsZTI7CiAgfTsKICBPYmplY3Quc2V0UHJvdG90eXBlT2YobmV3TW9kdWxlLnByb3RvdHlwZSwgV2ViQXNzZW1ibHkzLk1vZHVsZS5wcm90b3R5cGUpOwogIG5ld1dlYkFzc2VtYmx5LmNvbXBpbGUgPSBhc3luYyAoc291cmNlKSA9PiB7CiAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGUoc291cmNlKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlMiwgc291cmNlKTsKICAgIHJldHVybiBtb2R1bGUyOwogIH07CiAgaWYgKFdlYkFzc2VtYmx5My5jb21waWxlU3RyZWFtaW5nKSB7CiAgICBuZXdXZWJBc3NlbWJseS5jb21waWxlU3RyZWFtaW5nID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNvdXJjZTsKICAgICAgY29uc3QgY2xvbmUgPSByZXNwb25zZS5jbG9uZSgpOwogICAgICBjb25zdCBtb2R1bGUyID0gYXdhaXQgV2ViQXNzZW1ibHkzLmNvbXBpbGVTdHJlYW1pbmcocmVzcG9uc2UpOwogICAgICBhc3NpZ25JbXBvcnRzKG1vZHVsZTIsIG5ldyBVaW50OEFycmF5KGF3YWl0IGNsb25lLmFycmF5QnVmZmVyKCkpKTsKICAgICAgcmV0dXJuIG1vZHVsZTI7CiAgICB9OwogIH0KICBuZXdNb2R1bGUuaW1wb3J0cyA9IChtb2R1bGUyKSA9PiB7CiAgICBjb25zdCBwYXJzZWRJbXBvcnRzID0gbW9kdWxlMltwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbF07CiAgICBpZiAoIXBhcnNlZEltcG9ydHMpIHsKICAgICAgcmV0dXJuIFdlYkFzc2VtYmx5My5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUyKTsKICAgIH0KICAgIHJldHVybiBwYXJzZWRJbXBvcnRzOwogIH07CiAgcmV0dXJuIG5ld1dlYkFzc2VtYmx5Owp9CgovLyBlbnRyeXBvaW50L2ludHJpbnNpY3MudHMKdmFyIFdlYkFzc2VtYmx5MiA9IHBvbHlmaWxsKGdsb2JhbFRoaXMuV2ViQXNzZW1ibHkpOwp2YXIgTGluZURlY29kZXIgPSBjbGFzcyB7CiAgY29uc3RydWN0b3Iob25MaW5lKSB7CiAgICB0aGlzLmRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICB0aGlzLmJ1ZmZlciA9ICIiOwogICAgdGhpcy5vbkxpbmUgPSBvbkxpbmU7CiAgfQogIGRlY29kZXI7CiAgYnVmZmVyOwogIG9uTGluZTsKICBzZW5kKGNodW5rKSB7CiAgICB0aGlzLmJ1ZmZlciArPSB0aGlzLmRlY29kZXIuZGVjb2RlKGNodW5rLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgIGNvbnN0IGxpbmVzID0gdGhpcy5idWZmZXIuc3BsaXQoIlxuIik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykgewogICAgICB0aGlzLm9uTGluZShsaW5lc1tpXSk7CiAgICB9CiAgICB0aGlzLmJ1ZmZlciA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdOwogIH0KfTsKYXN5bmMgZnVuY3Rpb24gaW5zdGFudGlhdGUocmF3T3B0aW9ucywgZXh0cmFXYXNtSW1wb3J0cykgewogIGNvbnN0IG9wdGlvbnMgPSBkZWZhdWx0SW5zdGFudGlhdGlvbk9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0ID0gb3B0aW9ucy5zd2lmdDsKICBpZiAoIXN3aWZ0ICYmIG9wdGlvbnMuU3dpZnRSdW50aW1lKSB7CiAgICBzd2lmdCA9IG5ldyBvcHRpb25zLlN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJnczIgPSBvcHRpb25zLmFyZ3MgfHwgW107CiAgY29uc3QgZmRzID0gWwogICAgbmV3IE9wZW5GaWxlKG5ldyBGaWxlKFtdKSksCiAgICBzdGRvdXQsCiAgICBzdGRlcnIsCiAgICBuZXcgUHJlb3BlbkRpcmVjdG9yeSgiLyIsIC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCkpCiAgXTsKICBjb25zdCBlbnZzID0gb3B0aW9ucy5lbnYgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLmVudikubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2tleX09JHt2YWx1ZX1gKSA6IFtdOwogIGNvbnN0IHdhc2kgPSBuZXcgV0FTSShhcmdzMiwgZW52cywgZmRzLCB7CiAgICBkZWJ1ZzogZmFsc2UKICB9KTsKICBjb25zdCBjcmVhdGVXYXNtSW1wb3J0T2JqZWN0ID0gKGV4dHJhV2FzbUltcG9ydHMyLCBtb2R1bGUyKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QyID0gewogICAgICB3YXNpX3NuYXBzaG90X3ByZXZpZXcxOiB3YXNpLndhc2lJbXBvcnQKICAgIH07CiAgICBpZiAoc3dpZnQpIHsKICAgICAgaW1wb3J0T2JqZWN0Mi5qYXZhc2NyaXB0X2tpdCA9IHN3aWZ0Lndhc21JbXBvcnRzOwogICAgfQogICAgaWYgKGV4dHJhV2FzbUltcG9ydHMyKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzMikgewogICAgICAgIGlmICghaW1wb3J0T2JqZWN0Mlttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0Mlttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHMyW21vZHVsZU5hbWVdKSB7CiAgICAgICAgICBpbXBvcnRPYmplY3QyW21vZHVsZU5hbWVdW2VudHJ5XSA9IGV4dHJhV2FzbUltcG9ydHMyW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgX2ltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Mi5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUyKSkgewogICAgICBjb25zdCBpbXBvcnRFbnRyeSA9IF9pbXBvcnRFbnRyeTsKICAgICAgaWYgKCFpbXBvcnRPYmplY3QyW2ltcG9ydEVudHJ5Lm1vZHVsZV0pIHsKICAgICAgICBpbXBvcnRPYmplY3QyW2ltcG9ydEVudHJ5Lm1vZHVsZV0gPSB7fTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0T2JqZWN0MltpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gImZ1bmN0aW9uIikgewogICAgICAgIGltcG9ydE9iamVjdDJbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9ICgpID0+IHsKICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0ZWQgZnVuY3Rpb24gJHtpbXBvcnRFbnRyeS5tb2R1bGV9LiR7aW1wb3J0RW50cnkubmFtZX0gbm90IGltcGxlbWVudGVkYCk7CiAgICAgICAgfTsKICAgICAgfSBlbHNlIGlmIChpbXBvcnRFbnRyeS5raW5kID09ICJtZW1vcnkiICYmIGltcG9ydEVudHJ5Lm1vZHVsZSA9PSAiZW52IiAmJiBpbXBvcnRFbnRyeS5uYW1lID09ICJtZW1vcnkiKSB7CiAgICAgICAgY29uc3QgdHlwZSA9IGltcG9ydEVudHJ5LnR5cGU7CiAgICAgICAgY29uc3QgZGVzY3JpcHRvciA9IHsKICAgICAgICAgIGluaXRpYWw6IHR5cGUubWluaW11bSwKICAgICAgICAgIG1heGltdW06IHR5cGUubWF4aW11bSwKICAgICAgICAgIHNoYXJlZDogdHlwZS5zaGFyZWQKICAgICAgICB9OwogICAgICAgIGltcG9ydE9iamVjdDJbaW1wb3J0RW50cnkubW9kdWxlXVtpbXBvcnRFbnRyeS5uYW1lXSA9IG5ldyBXZWJBc3NlbWJseTIuTWVtb3J5KGRlc2NyaXB0b3IpOwogICAgICB9CiAgICB9CiAgICByZXR1cm4gaW1wb3J0T2JqZWN0MjsKICB9OwogIGNvbnN0IGltcG9ydE9iamVjdCA9IGNyZWF0ZVdhc21JbXBvcnRPYmplY3QoZXh0cmFXYXNtSW1wb3J0cywgb3B0aW9ucy5tb2R1bGUpOwogIGNvbnN0IGluc3RhbmNlID0gYXdhaXQgV2ViQXNzZW1ibHkyLmluc3RhbnRpYXRlKG9wdGlvbnMubW9kdWxlLCBpbXBvcnRPYmplY3QpOwogIGlmIChzd2lmdCAmJiBpbnN0YW5jZS5leHBvcnRzLnN3anNfbGlicmFyeV92ZXJzaW9uKSB7CiAgICBzd2lmdC5zZXRJbnN0YW5jZShpbnN0YW5jZSk7CiAgfQogIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQgPT09ICJmdW5jdGlvbiIpIHsKICAgIHdhc2kuc3RhcnQoaW5zdGFuY2UpOwogIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUgPT0gImZ1bmN0aW9uIikgewogICAgd2FzaS5pbml0aWFsaXplKGluc3RhbmNlKTsKICAgIGlmIChzd2lmdCAmJiBzd2lmdC5tYWluKSB7CiAgICAgIHN3aWZ0Lm1haW4oKTsKICAgIH0gZWxzZSB7CiAgICAgIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5tYWluID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5tYWluKCk7CiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndiA9PT0gImZ1bmN0aW9uIikgewogICAgICAgIGluc3RhbmNlLmV4cG9ydHMuX19tYWluX2FyZ2NfYXJndigwLCAwKTsKICAgICAgfQogICAgfQogIH0KICByZXR1cm4geyBpbnN0YW5jZSB9Owp9CmZ1bmN0aW9uIGRlZmF1bHRJbnN0YW50aWF0aW9uT3B0aW9ucyhvcHRpb25zKSB7CiAgaWYgKG9wdGlvbnMuYXJncyA9PSBudWxsKSB7CiAgICBvcHRpb25zLmFyZ3MgPSBbIm1haW4ud2FzbSJdOwogIH0KICBjb25zdCBpc05vZGVKcyA9IHR5cGVvZiBwcm9jZXNzICE9PSAidW5kZWZpbmVkIiAmJiBwcm9jZXNzLnJlbGVhc2UubmFtZSA9PT0gIm5vZGUiOwogIGNvbnN0IGlzV2ViQnJvd3NlciA9IHR5cGVvZiB3aW5kb3cgIT09ICJ1bmRlZmluZWQiOwogIGlmIChpc05vZGVKcykgewogICAgaWYgKCFvcHRpb25zLm9uU3Rkb3V0KSB7CiAgICAgIG9wdGlvbnMub25TdGRvdXQgPSAoY2h1bmspID0+IHByb2Nlc3Muc3Rkb3V0LndyaXRlKGNodW5rKTsKICAgIH0KICAgIGlmICghb3B0aW9ucy5vblN0ZGVycikgewogICAgICBvcHRpb25zLm9uU3RkZXJyID0gKGNodW5rKSA9PiBwcm9jZXNzLnN0ZGVyci53cml0ZShjaHVuayk7CiAgICB9CiAgfSBlbHNlIGlmIChpc1dlYkJyb3dzZXIpIHsKICAgIGlmICghb3B0aW9ucy5vblN0ZG91dExpbmUpIHsKICAgICAgb3B0aW9ucy5vblN0ZG91dExpbmUgPSAobGluZSkgPT4gY29uc29sZS5sb2cobGluZSk7CiAgICB9CiAgICBpZiAoIW9wdGlvbnMub25TdGRlcnJMaW5lKSB7CiAgICAgIG9wdGlvbnMub25TdGRlcnJMaW5lID0gKGxpbmUpID0+IGNvbnNvbGUud2FybihsaW5lKTsKICAgIH0KICB9CiAgcmV0dXJuIG9wdGlvbnM7Cn0KCi8vIGVudHJ5cG9pbnQvdGVzdE5vZGUudHMKdmFyIGFyZ3MgPSBbLi4ucHJvY2Vzcy5hcmd2XTsKYXJncy5zaGlmdCgpOwphcmdzLnNoaWZ0KCk7CnZhciBbd2FzbUZpbGUsIC4uLnRlc3RBcmdzXSA9IGFyZ3M7CnRlc3RBcmdzLnVuc2hpZnQoaW1wb3J0X3BhdGguZGVmYXVsdC5iYXNlbmFtZSh3YXNtRmlsZSkpOwppZiAoIXdhc21GaWxlKSB7CiAgdGhyb3cgRXJyb3IoIk5vIFdBU00gdGVzdCBmaWxlIHNwZWNpZmllZCwgY2FuIG5vdCBydW4gdGVzdHMiKTsKfQp2YXIgc3RhcnRXYXNpVGFzayA9IGFzeW5jICgpID0+IHsKICBjb25zdCB3YXNtQnl0ZXMgPSBhd2FpdCBpbXBvcnRfcHJvbWlzZXMuZGVmYXVsdC5yZWFkRmlsZSh3YXNtRmlsZSk7CiAgbGV0IHJ1bnRpbWVDb25zdHJ1Y3RvciA9IHZvaWQgMDsKICB0cnkgewogICAgY29uc3QgeyBTd2lmdFJ1bnRpbWUgfSA9IGF3YWl0IGltcG9ydCgKICAgICAgLy8gQHRzLWlnbm9yZQogICAgICAiLi9KYXZhU2NyaXB0S2l0X0phdmFTY3JpcHRLaXQucmVzb3VyY2VzL1J1bnRpbWUvaW5kZXgubWpzIgogICAgKTsKICAgIHJ1bnRpbWVDb25zdHJ1Y3RvciA9IFN3aWZ0UnVudGltZTsKICAgIGdsb2JhbC5yZXF1aXJlID0gcmVxdWlyZTsKICB9IGNhdGNoIHsKICB9CiAgY29uc3QgZW52ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gcHJvY2Vzcy5lbnYpIHsKICAgIGNvbnN0IHZhbHVlID0gcHJvY2Vzcy5lbnZba2V5XTsKICAgIGlmICh2YWx1ZSkgewogICAgICBlbnZba2V5XSA9IHZhbHVlOwogICAgfQogIH0KICBsZXQgcHJvY0V4aXRDYWxsZWQgPSBmYWxzZTsKICBwcm9jZXNzLm9uKCJiZWZvcmVFeGl0IiwgKCkgPT4gewogICAgaWYgKCFwcm9jRXhpdENhbGxlZCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoYFRlc3QgaGFybmVzcyBwcm9jZXNzIGV4aXRlZCBiZWZvcmUgdGVzdCBwcm9jZXNzLgpUaGlzIHVzdWFsbHkgbWVhbnMgdGhlcmUgYXJlIHNvbWUgZGFuZ2xpbmcgY29udGludWF0aW9ucywgd2hpY2ggYXJlIGF3YWl0ZWQgYnV0IG5ldmVyIHJlc3VtZWQuYCk7CiAgICB9CiAgfSk7CiAgYXdhaXQgaW5zdGFudGlhdGUoewogICAgbW9kdWxlOiBhd2FpdCBXZWJBc3NlbWJseS5jb21waWxlKHdhc21CeXRlcyksCiAgICBhcmdzOiB0ZXN0QXJncywKICAgIGVudiwKICAgIG9uU3Rkb3V0TGluZTogKGxpbmUpID0+IHsKICAgICAgY29uc29sZS5sb2cobGluZSk7CiAgICB9LAogICAgb25TdGRlcnJMaW5lOiAobGluZSkgPT4gewogICAgICBjb25zb2xlLmVycm9yKGxpbmUpOwogICAgfSwKICAgIFN3aWZ0UnVudGltZTogcnVudGltZUNvbnN0cnVjdG9yCiAgfSwgewogICAgIndhc2lfc25hcHNob3RfcHJldmlldzEiOiB7CiAgICAgIHByb2NfZXhpdDogKGNvZGUpID0+IHsKICAgICAgICBwcm9jRXhpdENhbGxlZCA9IHRydWU7CiAgICAgICAgcHJvY2Vzcy5leGl0KGNvZGUpOwogICAgICB9CiAgICB9CiAgfSk7Cn07CnN0YXJ0V2FzaVRhc2soKS5jYXRjaCgoZSkgPT4gewogIHRocm93IGU7Cn0pOwo=")! + public static let intrinsics: Data = Data(base64Encoded: "Ly8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpX2RlZnMuanMKdmFyIENMT0NLSURfUkVBTFRJTUUgPSAwOwp2YXIgQ0xPQ0tJRF9NT05PVE9OSUMgPSAxOwp2YXIgRVJSTk9fU1VDQ0VTUyA9IDA7CnZhciBFUlJOT19CQURGID0gODsKdmFyIEVSUk5PX0VYSVNUID0gMjA7CnZhciBFUlJOT19JTlZBTCA9IDI4Owp2YXIgRVJSTk9fSVNESVIgPSAzMTsKdmFyIEVSUk5PX05BTUVUT09MT05HID0gMzc7CnZhciBFUlJOT19OT0VOVCA9IDQ0Owp2YXIgRVJSTk9fTk9TWVMgPSA1MjsKdmFyIEVSUk5PX05PVERJUiA9IDU0Owp2YXIgRVJSTk9fTk9URU1QVFkgPSA1NTsKdmFyIEVSUk5PX05PVFNVUCA9IDU4Owp2YXIgRVJSTk9fUEVSTSA9IDYzOwp2YXIgRVJSTk9fTk9UQ0FQQUJMRSA9IDc2Owp2YXIgUklHSFRTX0ZEX0RBVEFTWU5DID0gMSA8PCAwOwp2YXIgUklHSFRTX0ZEX1JFQUQgPSAxIDw8IDE7CnZhciBSSUdIVFNfRkRfU0VFSyA9IDEgPDwgMjsKdmFyIFJJR0hUU19GRF9GRFNUQVRfU0VUX0ZMQUdTID0gMSA8PCAzOwp2YXIgUklHSFRTX0ZEX1NZTkMgPSAxIDw8IDQ7CnZhciBSSUdIVFNfRkRfVEVMTCA9IDEgPDwgNTsKdmFyIFJJR0hUU19GRF9XUklURSA9IDEgPDwgNjsKdmFyIFJJR0hUU19GRF9BRFZJU0UgPSAxIDw8IDc7CnZhciBSSUdIVFNfRkRfQUxMT0NBVEUgPSAxIDw8IDg7CnZhciBSSUdIVFNfUEFUSF9DUkVBVEVfRElSRUNUT1JZID0gMSA8PCA5Owp2YXIgUklHSFRTX1BBVEhfQ1JFQVRFX0ZJTEUgPSAxIDw8IDEwOwp2YXIgUklHSFRTX1BBVEhfTElOS19TT1VSQ0UgPSAxIDw8IDExOwp2YXIgUklHSFRTX1BBVEhfTElOS19UQVJHRVQgPSAxIDw8IDEyOwp2YXIgUklHSFRTX1BBVEhfT1BFTiA9IDEgPDwgMTM7CnZhciBSSUdIVFNfRkRfUkVBRERJUiA9IDEgPDwgMTQ7CnZhciBSSUdIVFNfUEFUSF9SRUFETElOSyA9IDEgPDwgMTU7CnZhciBSSUdIVFNfUEFUSF9SRU5BTUVfU09VUkNFID0gMSA8PCAxNjsKdmFyIFJJR0hUU19QQVRIX1JFTkFNRV9UQVJHRVQgPSAxIDw8IDE3Owp2YXIgUklHSFRTX1BBVEhfRklMRVNUQVRfR0VUID0gMSA8PCAxODsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9TSVpFID0gMSA8PCAxOTsKdmFyIFJJR0hUU19QQVRIX0ZJTEVTVEFUX1NFVF9USU1FUyA9IDEgPDwgMjA7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfR0VUID0gMSA8PCAyMTsKdmFyIFJJR0hUU19GRF9GSUxFU1RBVF9TRVRfU0laRSA9IDEgPDwgMjI7CnZhciBSSUdIVFNfRkRfRklMRVNUQVRfU0VUX1RJTUVTID0gMSA8PCAyMzsKdmFyIFJJR0hUU19QQVRIX1NZTUxJTksgPSAxIDw8IDI0Owp2YXIgUklHSFRTX1BBVEhfUkVNT1ZFX0RJUkVDVE9SWSA9IDEgPDwgMjU7CnZhciBSSUdIVFNfUEFUSF9VTkxJTktfRklMRSA9IDEgPDwgMjY7CnZhciBSSUdIVFNfUE9MTF9GRF9SRUFEV1JJVEUgPSAxIDw8IDI3Owp2YXIgUklHSFRTX1NPQ0tfU0hVVERPV04gPSAxIDw8IDI4Owp2YXIgSW92ZWMgPSBjbGFzcyB7CiAgc3RhdGljIHJlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICBjb25zdCBpb3ZlYyA9IG5ldyBJb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChJb3ZlYy5yZWFkX2J5dGVzKHZpZXcsIHB0ciArIDggKiBpKSk7CiAgICB9CiAgICByZXR1cm4gaW92ZWNzOwogIH0KfTsKdmFyIENpb3ZlYyA9IGNsYXNzIHsKICBzdGF0aWMgcmVhZF9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIGNvbnN0IGlvdmVjID0gbmV3IENpb3ZlYygpOwogICAgaW92ZWMuYnVmID0gdmlldy5nZXRVaW50MzIocHRyLCB0cnVlKTsKICAgIGlvdmVjLmJ1Zl9sZW4gPSB2aWV3LmdldFVpbnQzMihwdHIgKyA0LCB0cnVlKTsKICAgIHJldHVybiBpb3ZlYzsKICB9CiAgc3RhdGljIHJlYWRfYnl0ZXNfYXJyYXkodmlldywgcHRyLCBsZW4pIHsKICAgIGNvbnN0IGlvdmVjcyA9IFtdOwogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW47IGkrKykgewogICAgICBpb3ZlY3MucHVzaChDaW92ZWMucmVhZF9ieXRlcyh2aWV3LCBwdHIgKyA4ICogaSkpOwogICAgfQogICAgcmV0dXJuIGlvdmVjczsKICB9Cn07CnZhciBXSEVOQ0VfU0VUID0gMDsKdmFyIFdIRU5DRV9DVVIgPSAxOwp2YXIgV0hFTkNFX0VORCA9IDI7CnZhciBGSUxFVFlQRV9DSEFSQUNURVJfREVWSUNFID0gMjsKdmFyIEZJTEVUWVBFX0RJUkVDVE9SWSA9IDM7CnZhciBGSUxFVFlQRV9SRUdVTEFSX0ZJTEUgPSA0Owp2YXIgRGlyZW50ID0gY2xhc3MgewogIGhlYWRfbGVuZ3RoKCkgewogICAgcmV0dXJuIDI0OwogIH0KICBuYW1lX2xlbmd0aCgpIHsKICAgIHJldHVybiB0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGg7CiAgfQogIHdyaXRlX2hlYWRfYnl0ZXModmlldywgcHRyKSB7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIsIHRoaXMuZF9uZXh0LCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDgsIHRoaXMuZF9pbm8sIHRydWUpOwogICAgdmlldy5zZXRVaW50MzIocHRyICsgMTYsIHRoaXMuZGlyX25hbWUubGVuZ3RoLCB0cnVlKTsKICAgIHZpZXcuc2V0VWludDgocHRyICsgMjAsIHRoaXMuZF90eXBlKTsKICB9CiAgd3JpdGVfbmFtZV9ieXRlcyh2aWV3OCwgcHRyLCBidWZfbGVuKSB7CiAgICB2aWV3OC5zZXQodGhpcy5kaXJfbmFtZS5zbGljZSgwLCBNYXRoLm1pbih0aGlzLmRpcl9uYW1lLmJ5dGVMZW5ndGgsIGJ1Zl9sZW4pKSwgcHRyKTsKICB9CiAgY29uc3RydWN0b3IobmV4dF9jb29raWUsIG5hbWUsIHR5cGUpIHsKICAgIHRoaXMuZF9pbm8gPSAwbjsKICAgIGNvbnN0IGVuY29kZWRfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICAgIHRoaXMuZF9uZXh0ID0gbmV4dF9jb29raWU7CiAgICB0aGlzLmRfbmFtbGVuID0gZW5jb2RlZF9uYW1lLmJ5dGVMZW5ndGg7CiAgICB0aGlzLmRfdHlwZSA9IHR5cGU7CiAgICB0aGlzLmRpcl9uYW1lID0gZW5jb2RlZF9uYW1lOwogIH0KfTsKdmFyIEZERkxBR1NfQVBQRU5EID0gMSA8PCAwOwp2YXIgRkRGTEFHU19EU1lOQyA9IDEgPDwgMTsKdmFyIEZERkxBR1NfTk9OQkxPQ0sgPSAxIDw8IDI7CnZhciBGREZMQUdTX1JTWU5DID0gMSA8PCAzOwp2YXIgRkRGTEFHU19TWU5DID0gMSA8PCA0Owp2YXIgRmRzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50OChwdHIsIHRoaXMuZnNfZmlsZXR5cGUpOwogICAgdmlldy5zZXRVaW50MTYocHRyICsgMiwgdGhpcy5mc19mbGFncywgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmZzX3JpZ2h0c19iYXNlLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDE2LCB0aGlzLmZzX3JpZ2h0c19pbmhlcml0ZWQsIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgZmxhZ3MpIHsKICAgIHRoaXMuZnNfcmlnaHRzX2Jhc2UgPSAwbjsKICAgIHRoaXMuZnNfcmlnaHRzX2luaGVyaXRlZCA9IDBuOwogICAgdGhpcy5mc19maWxldHlwZSA9IGZpbGV0eXBlOwogICAgdGhpcy5mc19mbGFncyA9IGZsYWdzOwogIH0KfTsKdmFyIEZTVEZMQUdTX0FUSU0gPSAxIDw8IDA7CnZhciBGU1RGTEFHU19BVElNX05PVyA9IDEgPDwgMTsKdmFyIEZTVEZMQUdTX01USU0gPSAxIDw8IDI7CnZhciBGU1RGTEFHU19NVElNX05PVyA9IDEgPDwgMzsKdmFyIE9GTEFHU19DUkVBVCA9IDEgPDwgMDsKdmFyIE9GTEFHU19ESVJFQ1RPUlkgPSAxIDw8IDE7CnZhciBPRkxBR1NfRVhDTCA9IDEgPDwgMjsKdmFyIE9GTEFHU19UUlVOQyA9IDEgPDwgMzsKdmFyIEZpbGVzdGF0ID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRCaWdVaW50NjQocHRyLCB0aGlzLmRldiwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA4LCB0aGlzLmlubywgdHJ1ZSk7CiAgICB2aWV3LnNldFVpbnQ4KHB0ciArIDE2LCB0aGlzLmZpbGV0eXBlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDI0LCB0aGlzLm5saW5rLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDMyLCB0aGlzLnNpemUsIHRydWUpOwogICAgdmlldy5zZXRCaWdVaW50NjQocHRyICsgMzgsIHRoaXMuYXRpbSwgdHJ1ZSk7CiAgICB2aWV3LnNldEJpZ1VpbnQ2NChwdHIgKyA0NiwgdGhpcy5tdGltLCB0cnVlKTsKICAgIHZpZXcuc2V0QmlnVWludDY0KHB0ciArIDUyLCB0aGlzLmN0aW0sIHRydWUpOwogIH0KICBjb25zdHJ1Y3RvcihmaWxldHlwZSwgc2l6ZSkgewogICAgdGhpcy5kZXYgPSAwbjsKICAgIHRoaXMuaW5vID0gMG47CiAgICB0aGlzLm5saW5rID0gMG47CiAgICB0aGlzLmF0aW0gPSAwbjsKICAgIHRoaXMubXRpbSA9IDBuOwogICAgdGhpcy5jdGltID0gMG47CiAgICB0aGlzLmZpbGV0eXBlID0gZmlsZXR5cGU7CiAgICB0aGlzLnNpemUgPSBzaXplOwogIH0KfTsKdmFyIEVWRU5UUldGTEFHU19GRF9SRUFEV1JJVEVfSEFOR1VQID0gMSA8PCAwOwp2YXIgU1VCQ0xPQ0tGTEFHU19TVUJTQ1JJUFRJT05fQ0xPQ0tfQUJTVElNRSA9IDEgPDwgMDsKdmFyIFJJRkxBR1NfUkVDVl9QRUVLID0gMSA8PCAwOwp2YXIgUklGTEFHU19SRUNWX1dBSVRBTEwgPSAxIDw8IDE7CnZhciBST0ZMQUdTX1JFQ1ZfREFUQV9UUlVOQ0FURUQgPSAxIDw8IDA7CnZhciBTREZMQUdTX1JEID0gMSA8PCAwOwp2YXIgU0RGTEFHU19XUiA9IDEgPDwgMTsKdmFyIFBSRU9QRU5UWVBFX0RJUiA9IDA7CnZhciBQcmVzdGF0RGlyID0gY2xhc3MgewogIHdyaXRlX2J5dGVzKHZpZXcsIHB0cikgewogICAgdmlldy5zZXRVaW50MzIocHRyLCB0aGlzLnByX25hbWUuYnl0ZUxlbmd0aCwgdHJ1ZSk7CiAgfQogIGNvbnN0cnVjdG9yKG5hbWUpIHsKICAgIHRoaXMucHJfbmFtZSA9IG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZShuYW1lKTsKICB9Cn07CnZhciBQcmVzdGF0ID0gY2xhc3MgewogIHN0YXRpYyBkaXIobmFtZSkgewogICAgY29uc3QgcHJlc3RhdCA9IG5ldyBQcmVzdGF0KCk7CiAgICBwcmVzdGF0LnRhZyA9IFBSRU9QRU5UWVBFX0RJUjsKICAgIHByZXN0YXQuaW5uZXIgPSBuZXcgUHJlc3RhdERpcihuYW1lKTsKICAgIHJldHVybiBwcmVzdGF0OwogIH0KICB3cml0ZV9ieXRlcyh2aWV3LCBwdHIpIHsKICAgIHZpZXcuc2V0VWludDMyKHB0ciwgdGhpcy50YWcsIHRydWUpOwogICAgdGhpcy5pbm5lci53cml0ZV9ieXRlcyh2aWV3LCBwdHIgKyA0KTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2RlYnVnLmpzCnZhciBEZWJ1ZyA9IGNsYXNzIERlYnVnMiB7CiAgZW5hYmxlKGVuYWJsZWQpIHsKICAgIHRoaXMubG9nID0gY3JlYXRlTG9nZ2VyKGVuYWJsZWQgPT09IHZvaWQgMCA/IHRydWUgOiBlbmFibGVkLCB0aGlzLnByZWZpeCk7CiAgfQogIGdldCBlbmFibGVkKCkgewogICAgcmV0dXJuIHRoaXMuaXNFbmFibGVkOwogIH0KICBjb25zdHJ1Y3Rvcihpc0VuYWJsZWQpIHsKICAgIHRoaXMuaXNFbmFibGVkID0gaXNFbmFibGVkOwogICAgdGhpcy5wcmVmaXggPSAid2FzaToiOwogICAgdGhpcy5lbmFibGUoaXNFbmFibGVkKTsKICB9Cn07CmZ1bmN0aW9uIGNyZWF0ZUxvZ2dlcihlbmFibGVkLCBwcmVmaXgpIHsKICBpZiAoZW5hYmxlZCkgewogICAgY29uc3QgYSA9IGNvbnNvbGUubG9nLmJpbmQoY29uc29sZSwgIiVjJXMiLCAiY29sb3I6ICMyNjVCQTAiLCBwcmVmaXgpOwogICAgcmV0dXJuIGE7CiAgfSBlbHNlIHsKICAgIHJldHVybiAoKSA9PiB7CiAgICB9OwogIH0KfQp2YXIgZGVidWcgPSBuZXcgRGVidWcoZmFsc2UpOwoKLy8gbm9kZV9tb2R1bGVzL0Biam9ybjMvYnJvd3Nlcl93YXNpX3NoaW0vZGlzdC93YXNpLmpzCnZhciBXQVNJUHJvY0V4aXQgPSBjbGFzcyBleHRlbmRzIEVycm9yIHsKICBjb25zdHJ1Y3Rvcihjb2RlKSB7CiAgICBzdXBlcigiZXhpdCB3aXRoIGV4aXQgY29kZSAiICsgY29kZSk7CiAgICB0aGlzLmNvZGUgPSBjb2RlOwogIH0KfTsKdmFyIFdBU0kgPSBjbGFzcyBXQVNJMiB7CiAgc3RhcnQoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgdHJ5IHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fc3RhcnQoKTsKICAgICAgcmV0dXJuIDA7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIGlmIChlIGluc3RhbmNlb2YgV0FTSVByb2NFeGl0KSB7CiAgICAgICAgcmV0dXJuIGUuY29kZTsKICAgICAgfSBlbHNlIHsKICAgICAgICB0aHJvdyBlOwogICAgICB9CiAgICB9CiAgfQogIGluaXRpYWxpemUoaW5zdGFuY2UpIHsKICAgIHRoaXMuaW5zdCA9IGluc3RhbmNlOwogICAgaWYgKGluc3RhbmNlLmV4cG9ydHMuX2luaXRpYWxpemUpIHsKICAgICAgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSgpOwogICAgfQogIH0KICBjb25zdHJ1Y3RvcihhcmdzLCBlbnYsIGZkcywgb3B0aW9ucyA9IHt9KSB7CiAgICB0aGlzLmFyZ3MgPSBbXTsKICAgIHRoaXMuZW52ID0gW107CiAgICB0aGlzLmZkcyA9IFtdOwogICAgZGVidWcuZW5hYmxlKG9wdGlvbnMuZGVidWcpOwogICAgdGhpcy5hcmdzID0gYXJnczsKICAgIHRoaXMuZW52ID0gZW52OwogICAgdGhpcy5mZHMgPSBmZHM7CiAgICBjb25zdCBzZWxmID0gdGhpczsKICAgIHRoaXMud2FzaUltcG9ydCA9IHsgYXJnc19zaXplc19nZXQoYXJnYywgYXJndl9idWZfc2l6ZSkgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJnYywgc2VsZi5hcmdzLmxlbmd0aCwgdHJ1ZSk7CiAgICAgIGxldCBidWZfc2l6ZSA9IDA7CiAgICAgIGZvciAoY29uc3QgYXJnIG9mIHNlbGYuYXJncykgewogICAgICAgIGJ1Zl9zaXplICs9IGFyZy5sZW5ndGggKyAxOwogICAgICB9CiAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYXJndl9idWZfc2l6ZSwgYnVmX3NpemUsIHRydWUpOwogICAgICBkZWJ1Zy5sb2coYnVmZmVyLmdldFVpbnQzMihhcmdjLCB0cnVlKSwgYnVmZmVyLmdldFVpbnQzMihhcmd2X2J1Zl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgYXJnc19nZXQoYXJndiwgYXJndl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfYXJndl9idWYgPSBhcmd2X2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmFyZ3MubGVuZ3RoOyBpKyspIHsKICAgICAgICBidWZmZXIuc2V0VWludDMyKGFyZ3YsIGFyZ3ZfYnVmLCB0cnVlKTsKICAgICAgICBhcmd2ICs9IDQ7CiAgICAgICAgY29uc3QgYXJnID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuYXJnc1tpXSk7CiAgICAgICAgYnVmZmVyOC5zZXQoYXJnLCBhcmd2X2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGFyZ3ZfYnVmICsgYXJnLmxlbmd0aCwgMCk7CiAgICAgICAgYXJndl9idWYgKz0gYXJnLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgaWYgKGRlYnVnLmVuYWJsZWQpIHsKICAgICAgICBkZWJ1Zy5sb2cobmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG9yaWdfYXJndl9idWYsIGFyZ3ZfYnVmKSkpOwogICAgICB9CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9zaXplc19nZXQoZW52aXJvbl9jb3VudCwgZW52aXJvbl9zaXplKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX2NvdW50LCBzZWxmLmVudi5sZW5ndGgsIHRydWUpOwogICAgICBsZXQgYnVmX3NpemUgPSAwOwogICAgICBmb3IgKGNvbnN0IGVudmlyb24gb2Ygc2VsZi5lbnYpIHsKICAgICAgICBidWZfc2l6ZSArPSBlbnZpcm9uLmxlbmd0aCArIDE7CiAgICAgIH0KICAgICAgYnVmZmVyLnNldFVpbnQzMihlbnZpcm9uX3NpemUsIGJ1Zl9zaXplLCB0cnVlKTsKICAgICAgZGVidWcubG9nKGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9jb3VudCwgdHJ1ZSksIGJ1ZmZlci5nZXRVaW50MzIoZW52aXJvbl9zaXplLCB0cnVlKSk7CiAgICAgIHJldHVybiAwOwogICAgfSwgZW52aXJvbl9nZXQoZW52aXJvbiwgZW52aXJvbl9idWYpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IG9yaWdfZW52aXJvbl9idWYgPSBlbnZpcm9uX2J1ZjsKICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBzZWxmLmVudi5sZW5ndGg7IGkrKykgewogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoZW52aXJvbiwgZW52aXJvbl9idWYsIHRydWUpOwogICAgICAgIGVudmlyb24gKz0gNDsKICAgICAgICBjb25zdCBlID0gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKHNlbGYuZW52W2ldKTsKICAgICAgICBidWZmZXI4LnNldChlLCBlbnZpcm9uX2J1Zik7CiAgICAgICAgYnVmZmVyLnNldFVpbnQ4KGVudmlyb25fYnVmICsgZS5sZW5ndGgsIDApOwogICAgICAgIGVudmlyb25fYnVmICs9IGUubGVuZ3RoICsgMTsKICAgICAgfQogICAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICAgIGRlYnVnLmxvZyhuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob3JpZ19lbnZpcm9uX2J1ZiwgZW52aXJvbl9idWYpKSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBjbG9ja19yZXNfZ2V0KGlkLCByZXNfcHRyKSB7CiAgICAgIGxldCByZXNvbHV0aW9uVmFsdWU7CiAgICAgIHN3aXRjaCAoaWQpIHsKICAgICAgICBjYXNlIENMT0NLSURfTU9OT1RPTklDOiB7CiAgICAgICAgICByZXNvbHV0aW9uVmFsdWUgPSA1MDAwbjsKICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIENMT0NLSURfUkVBTFRJTUU6IHsKICAgICAgICAgIHJlc29sdXRpb25WYWx1ZSA9IDEwMDAwMDBuOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICByZXR1cm4gRVJSTk9fTk9TWVM7CiAgICAgIH0KICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgdmlldy5zZXRCaWdVaW50NjQocmVzX3B0ciwgcmVzb2x1dGlvblZhbHVlLCB0cnVlKTsKICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICB9LCBjbG9ja190aW1lX2dldChpZCwgcHJlY2lzaW9uLCB0aW1lKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKGlkID09PSBDTE9DS0lEX1JFQUxUSU1FKSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBCaWdJbnQobmV3IERhdGUoKS5nZXRUaW1lKCkpICogMTAwMDAwMG4sIHRydWUpOwogICAgICB9IGVsc2UgaWYgKGlkID09IENMT0NLSURfTU9OT1RPTklDKSB7CiAgICAgICAgbGV0IG1vbm90b25pY190aW1lOwogICAgICAgIHRyeSB7CiAgICAgICAgICBtb25vdG9uaWNfdGltZSA9IEJpZ0ludChNYXRoLnJvdW5kKHBlcmZvcm1hbmNlLm5vdygpICogMWU2KSk7CiAgICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgICAgbW9ub3RvbmljX3RpbWUgPSAwbjsKICAgICAgICB9CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCBtb25vdG9uaWNfdGltZSwgdHJ1ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NCh0aW1lLCAwbiwgdHJ1ZSk7CiAgICAgIH0KICAgICAgcmV0dXJuIDA7CiAgICB9LCBmZF9hZHZpc2UoZmQsIG9mZnNldCwgbGVuLCBhZHZpY2UpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfYWxsb2NhdGUoZmQsIG9mZnNldCwgbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9hbGxvY2F0ZShvZmZzZXQsIGxlbik7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Nsb3NlKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcmV0ID0gc2VsZi5mZHNbZmRdLmZkX2Nsb3NlKCk7CiAgICAgICAgc2VsZi5mZHNbZmRdID0gdm9pZCAwOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2RhdGFzeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9nZXQoZmQsIGZkc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmRzdGF0IH0gPSBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X2dldCgpOwogICAgICAgIGlmIChmZHN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmRzdGF0LndyaXRlX2J5dGVzKG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKSwgZmRzdGF0X3B0cik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2Zkc3RhdF9zZXRfZmxhZ3MoZmQsIGZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9mZHN0YXRfc2V0X2ZsYWdzKGZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmRzdGF0X3NldF9yaWdodHMoZmQsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZykgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfZmlsZXN0YXRfZ2V0KGZkLCBmaWxlc3RhdF9wdHIpIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9nZXQoKTsKICAgICAgICBpZiAoZmlsZXN0YXQgIT0gbnVsbCkgewogICAgICAgICAgZmlsZXN0YXQud3JpdGVfYnl0ZXMobmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpLCBmaWxlc3RhdF9wdHIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9maWxlc3RhdF9zZXRfc2l6ZShmZCwgc2l6ZSkgewogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0uZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX2ZpbGVzdGF0X3NldF90aW1lcyhmZCwgYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9maWxlc3RhdF9zZXRfdGltZXMoYXRpbSwgbXRpbSwgZnN0X2ZsYWdzKTsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gSW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG5yZWFkID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgeyByZXQsIGRhdGEgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVhZChpb3ZlYy5idWZfbGVuLCBvZmZzZXQpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBidWZmZXI4LnNldChkYXRhLCBpb3ZlYy5idWYpOwogICAgICAgICAgbnJlYWQgKz0gZGF0YS5sZW5ndGg7CiAgICAgICAgICBvZmZzZXQgKz0gQmlnSW50KGRhdGEubGVuZ3RoKTsKICAgICAgICAgIGlmIChkYXRhLmxlbmd0aCAhPSBpb3ZlYy5idWZfbGVuKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wcmVzdGF0X2dldChmZCwgYnVmX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIHByZXN0YXQud3JpdGVfYnl0ZXMoYnVmZmVyLCBidWZfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfcHJlc3RhdF9kaXJfbmFtZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgeyByZXQsIHByZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wcmVzdGF0X2dldCgpOwogICAgICAgIGlmIChwcmVzdGF0ID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIGNvbnN0IHByZXN0YXRfZGlyX25hbWUgPSBwcmVzdGF0LmlubmVyLnByX25hbWU7CiAgICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICAgIGJ1ZmZlcjguc2V0KHByZXN0YXRfZGlyX25hbWUuc2xpY2UoMCwgcGF0aF9sZW4pLCBwYXRoX3B0cik7CiAgICAgICAgcmV0dXJuIHByZXN0YXRfZGlyX25hbWUuYnl0ZUxlbmd0aCA+IHBhdGhfbGVuID8gRVJSTk9fTkFNRVRPT0xPTkcgOiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9wd3JpdGUoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgb2Zmc2V0LCBud3JpdHRlbl9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgaW92ZWNzID0gQ2lvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBud3JpdHRlbiA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IGRhdGEgPSBidWZmZXI4LnNsaWNlKGlvdmVjLmJ1ZiwgaW92ZWMuYnVmICsgaW92ZWMuYnVmX2xlbik7CiAgICAgICAgICBjb25zdCB7IHJldCwgbndyaXR0ZW46IG53cml0dGVuX3BhcnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgbndyaXR0ZW4gKz0gbndyaXR0ZW5fcGFydDsKICAgICAgICAgIG9mZnNldCArPSBCaWdJbnQobndyaXR0ZW5fcGFydCk7CiAgICAgICAgICBpZiAobndyaXR0ZW5fcGFydCAhPSBkYXRhLmJ5dGVMZW5ndGgpIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWQoZmQsIGlvdnNfcHRyLCBpb3ZzX2xlbiwgbnJlYWRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IGlvdmVjcyA9IElvdmVjLnJlYWRfYnl0ZXNfYXJyYXkoYnVmZmVyLCBpb3ZzX3B0ciwgaW92c19sZW4pOwogICAgICAgIGxldCBucmVhZCA9IDA7CiAgICAgICAgZm9yIChjb25zdCBpb3ZlYyBvZiBpb3ZlY3MpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkYXRhIH0gPSBzZWxmLmZkc1tmZF0uZmRfcmVhZChpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGlmIChyZXQgIT0gRVJSTk9fU1VDQ0VTUykgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgbnJlYWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YSwgaW92ZWMuYnVmKTsKICAgICAgICAgIG5yZWFkICs9IGRhdGEubGVuZ3RoOwogICAgICAgICAgaWYgKGRhdGEubGVuZ3RoICE9IGlvdmVjLmJ1Zl9sZW4pIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobnJlYWRfcHRyLCBucmVhZCwgdHJ1ZSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3JlYWRkaXIoZmQsIGJ1ZiwgYnVmX2xlbiwgY29va2llLCBidWZ1c2VkX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBsZXQgYnVmdXNlZCA9IDA7CiAgICAgICAgd2hpbGUgKHRydWUpIHsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBkaXJlbnQgfSA9IHNlbGYuZmRzW2ZkXS5mZF9yZWFkZGlyX3NpbmdsZShjb29raWUpOwogICAgICAgICAgaWYgKHJldCAhPSAwKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgICAgfQogICAgICAgICAgaWYgKGRpcmVudCA9PSBudWxsKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgaWYgKGJ1Zl9sZW4gLSBidWZ1c2VkIDwgZGlyZW50LmhlYWRfbGVuZ3RoKCkpIHsKICAgICAgICAgICAgYnVmdXNlZCA9IGJ1Zl9sZW47CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgICAgY29uc3QgaGVhZF9ieXRlcyA9IG5ldyBBcnJheUJ1ZmZlcihkaXJlbnQuaGVhZF9sZW5ndGgoKSk7CiAgICAgICAgICBkaXJlbnQud3JpdGVfaGVhZF9ieXRlcyhuZXcgRGF0YVZpZXcoaGVhZF9ieXRlcyksIDApOwogICAgICAgICAgYnVmZmVyOC5zZXQobmV3IFVpbnQ4QXJyYXkoaGVhZF9ieXRlcykuc2xpY2UoMCwgTWF0aC5taW4oaGVhZF9ieXRlcy5ieXRlTGVuZ3RoLCBidWZfbGVuIC0gYnVmdXNlZCkpLCBidWYpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5oZWFkX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQuaGVhZF9sZW5ndGgoKTsKICAgICAgICAgIGlmIChidWZfbGVuIC0gYnVmdXNlZCA8IGRpcmVudC5uYW1lX2xlbmd0aCgpKSB7CiAgICAgICAgICAgIGJ1ZnVzZWQgPSBidWZfbGVuOwogICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgICAgIGRpcmVudC53cml0ZV9uYW1lX2J5dGVzKGJ1ZmZlcjgsIGJ1ZiwgYnVmX2xlbiAtIGJ1ZnVzZWQpOwogICAgICAgICAgYnVmICs9IGRpcmVudC5uYW1lX2xlbmd0aCgpOwogICAgICAgICAgYnVmdXNlZCArPSBkaXJlbnQubmFtZV9sZW5ndGgoKTsKICAgICAgICAgIGNvb2tpZSA9IGRpcmVudC5kX25leHQ7CiAgICAgICAgfQogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIoYnVmdXNlZF9wdHIsIGJ1ZnVzZWQsIHRydWUpOwogICAgICAgIHJldHVybiAwOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9yZW51bWJlcihmZCwgdG8pIHsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbdG9dICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHJldCA9IHNlbGYuZmRzW3RvXS5mZF9jbG9zZSgpOwogICAgICAgIGlmIChyZXQgIT0gMCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgc2VsZi5mZHNbdG9dID0gc2VsZi5mZHNbZmRdOwogICAgICAgIHNlbGYuZmRzW2ZkXSA9IHZvaWQgMDsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgZmRfc2VlayhmZCwgb2Zmc2V0LCB3aGVuY2UsIG9mZnNldF9vdXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCB7IHJldCwgb2Zmc2V0OiBvZmZzZXRfb3V0IH0gPSBzZWxmLmZkc1tmZF0uZmRfc2VlayhvZmZzZXQsIHdoZW5jZSk7CiAgICAgICAgYnVmZmVyLnNldEJpZ0ludDY0KG9mZnNldF9vdXRfcHRyLCBvZmZzZXRfb3V0LCB0cnVlKTsKICAgICAgICByZXR1cm4gcmV0OwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBmZF9zeW5jKGZkKSB7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5mZF9zeW5jKCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3RlbGwoZmQsIG9mZnNldF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHsgcmV0LCBvZmZzZXQgfSA9IHNlbGYuZmRzW2ZkXS5mZF90ZWxsKCk7CiAgICAgICAgYnVmZmVyLnNldEJpZ1VpbnQ2NChvZmZzZXRfcHRyLCBvZmZzZXQsIHRydWUpOwogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIGZkX3dyaXRlKGZkLCBpb3ZzX3B0ciwgaW92c19sZW4sIG53cml0dGVuX3B0cikgewogICAgICBjb25zdCBidWZmZXIgPSBuZXcgRGF0YVZpZXcoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBpb3ZlY3MgPSBDaW92ZWMucmVhZF9ieXRlc19hcnJheShidWZmZXIsIGlvdnNfcHRyLCBpb3ZzX2xlbik7CiAgICAgICAgbGV0IG53cml0dGVuID0gMDsKICAgICAgICBmb3IgKGNvbnN0IGlvdmVjIG9mIGlvdmVjcykgewogICAgICAgICAgY29uc3QgZGF0YSA9IGJ1ZmZlcjguc2xpY2UoaW92ZWMuYnVmLCBpb3ZlYy5idWYgKyBpb3ZlYy5idWZfbGVuKTsKICAgICAgICAgIGNvbnN0IHsgcmV0LCBud3JpdHRlbjogbndyaXR0ZW5fcGFydCB9ID0gc2VsZi5mZHNbZmRdLmZkX3dyaXRlKGRhdGEpOwogICAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIGJ1ZmZlci5zZXRVaW50MzIobndyaXR0ZW5fcHRyLCBud3JpdHRlbiwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgICB9CiAgICAgICAgICBud3JpdHRlbiArPSBud3JpdHRlbl9wYXJ0OwogICAgICAgICAgaWYgKG53cml0dGVuX3BhcnQgIT0gZGF0YS5ieXRlTGVuZ3RoKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBidWZmZXIuc2V0VWludDMyKG53cml0dGVuX3B0ciwgbndyaXR0ZW4sIHRydWUpOwogICAgICAgIHJldHVybiBFUlJOT19TVUNDRVNTOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2NyZWF0ZV9kaXJlY3RvcnkoZmQsIHBhdGhfcHRyLCBwYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwYXRoX2ZpbGVzdGF0X2dldChmZCwgZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgZmlsZXN0YXRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCB7IHJldCwgZmlsZXN0YXQgfSA9IHNlbGYuZmRzW2ZkXS5wYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aCk7CiAgICAgICAgaWYgKGZpbGVzdGF0ICE9IG51bGwpIHsKICAgICAgICAgIGZpbGVzdGF0LndyaXRlX2J5dGVzKGJ1ZmZlciwgZmlsZXN0YXRfcHRyKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJldDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmQsIGZsYWdzLCBwYXRoX3B0ciwgcGF0aF9sZW4sIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIHJldHVybiBzZWxmLmZkc1tmZF0ucGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncyk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfbGluayhvbGRfZmQsIG9sZF9mbGFncywgb2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9sZW4sIG5ld19mZCwgbmV3X3BhdGhfcHRyLCBuZXdfcGF0aF9sZW4pIHsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbb2xkX2ZkXSAhPSB2b2lkIDAgJiYgc2VsZi5mZHNbbmV3X2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgY29uc3QgeyByZXQsIGlub2RlX29iaiB9ID0gc2VsZi5mZHNbb2xkX2ZkXS5wYXRoX2xvb2t1cChvbGRfcGF0aCwgb2xkX2ZsYWdzKTsKICAgICAgICBpZiAoaW5vZGVfb2JqID09IG51bGwpIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHJldHVybiBzZWxmLmZkc1tuZXdfZmRdLnBhdGhfbGluayhuZXdfcGF0aCwgaW5vZGVfb2JqLCBmYWxzZSk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfb3BlbihmZCwgZGlyZmxhZ3MsIHBhdGhfcHRyLCBwYXRoX2xlbiwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzLCBvcGVuZWRfZmRfcHRyKSB7CiAgICAgIGNvbnN0IGJ1ZmZlciA9IG5ldyBEYXRhVmlldyhzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgY29uc3QgYnVmZmVyOCA9IG5ldyBVaW50OEFycmF5KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBpZiAoc2VsZi5mZHNbZmRdICE9IHZvaWQgMCkgewogICAgICAgIGNvbnN0IHBhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2UocGF0aF9wdHIsIHBhdGhfcHRyICsgcGF0aF9sZW4pKTsKICAgICAgICBkZWJ1Zy5sb2cocGF0aCk7CiAgICAgICAgY29uc3QgeyByZXQsIGZkX29iaiB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfb3BlbihkaXJmbGFncywgcGF0aCwgb2ZsYWdzLCBmc19yaWdodHNfYmFzZSwgZnNfcmlnaHRzX2luaGVyaXRpbmcsIGZkX2ZsYWdzKTsKICAgICAgICBpZiAocmV0ICE9IDApIHsKICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgICAgIHNlbGYuZmRzLnB1c2goZmRfb2JqKTsKICAgICAgICBjb25zdCBvcGVuZWRfZmQgPSBzZWxmLmZkcy5sZW5ndGggLSAxOwogICAgICAgIGJ1ZmZlci5zZXRVaW50MzIob3BlbmVkX2ZkX3B0ciwgb3BlbmVkX2ZkLCB0cnVlKTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF9yZWFkbGluayhmZCwgcGF0aF9wdHIsIHBhdGhfbGVuLCBidWZfcHRyLCBidWZfbGVuLCBucmVhZF9wdHIpIHsKICAgICAgY29uc3QgYnVmZmVyID0gbmV3IERhdGFWaWV3KHNlbGYuaW5zdC5leHBvcnRzLm1lbW9yeS5idWZmZXIpOwogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3QgcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShwYXRoX3B0ciwgcGF0aF9wdHIgKyBwYXRoX2xlbikpOwogICAgICAgIGRlYnVnLmxvZyhwYXRoKTsKICAgICAgICBjb25zdCB7IHJldCwgZGF0YSB9ID0gc2VsZi5mZHNbZmRdLnBhdGhfcmVhZGxpbmsocGF0aCk7CiAgICAgICAgaWYgKGRhdGEgIT0gbnVsbCkgewogICAgICAgICAgY29uc3QgZGF0YV9idWYgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoZGF0YSk7CiAgICAgICAgICBpZiAoZGF0YV9idWYubGVuZ3RoID4gYnVmX2xlbikgewogICAgICAgICAgICBidWZmZXIuc2V0VWludDMyKG5yZWFkX3B0ciwgMCwgdHJ1ZSk7CiAgICAgICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICAgICAgfQogICAgICAgICAgYnVmZmVyOC5zZXQoZGF0YV9idWYsIGJ1Zl9wdHIpOwogICAgICAgICAgYnVmZmVyLnNldFVpbnQzMihucmVhZF9wdHIsIGRhdGFfYnVmLmxlbmd0aCwgdHJ1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVtb3ZlX2RpcmVjdG9yeShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfcmVuYW1lKGZkLCBvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgbmV3X2ZkLCBuZXdfcGF0aF9wdHIsIG5ld19wYXRoX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGlmIChzZWxmLmZkc1tmZF0gIT0gdm9pZCAwICYmIHNlbGYuZmRzW25ld19mZF0gIT0gdm9pZCAwKSB7CiAgICAgICAgY29uc3Qgb2xkX3BhdGggPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IikuZGVjb2RlKGJ1ZmZlcjguc2xpY2Uob2xkX3BhdGhfcHRyLCBvbGRfcGF0aF9wdHIgKyBvbGRfcGF0aF9sZW4pKTsKICAgICAgICBjb25zdCBuZXdfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShuZXdfcGF0aF9wdHIsIG5ld19wYXRoX3B0ciArIG5ld19wYXRoX2xlbikpOwogICAgICAgIGxldCB7IHJldCwgaW5vZGVfb2JqIH0gPSBzZWxmLmZkc1tmZF0ucGF0aF91bmxpbmsob2xkX3BhdGgpOwogICAgICAgIGlmIChpbm9kZV9vYmogPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgcmV0ID0gc2VsZi5mZHNbbmV3X2ZkXS5wYXRoX2xpbmsobmV3X3BhdGgsIGlub2RlX29iaiwgdHJ1ZSk7CiAgICAgICAgaWYgKHJldCAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICBpZiAoc2VsZi5mZHNbZmRdLnBhdGhfbGluayhvbGRfcGF0aCwgaW5vZGVfb2JqLCB0cnVlKSAhPSBFUlJOT19TVUNDRVNTKSB7CiAgICAgICAgICAgIHRocm93ICJwYXRoX2xpbmsgc2hvdWxkIGFsd2F5cyByZXR1cm4gc3VjY2VzcyB3aGVuIHJlbGlua2luZyBhbiBpbm9kZSBiYWNrIHRvIHRoZSBvcmlnaW5hbCBwbGFjZSI7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0JBREY7CiAgICAgIH0KICAgIH0sIHBhdGhfc3ltbGluayhvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX2xlbiwgZmQsIG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBvbGRfcGF0aCA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiKS5kZWNvZGUoYnVmZmVyOC5zbGljZShvbGRfcGF0aF9wdHIsIG9sZF9wYXRoX3B0ciArIG9sZF9wYXRoX2xlbikpOwogICAgICAgIGNvbnN0IG5ld19wYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKG5ld19wYXRoX3B0ciwgbmV3X3BhdGhfcHRyICsgbmV3X3BhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICAgICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gRVJSTk9fQkFERjsKICAgICAgfQogICAgfSwgcGF0aF91bmxpbmtfZmlsZShmZCwgcGF0aF9wdHIsIHBhdGhfbGVuKSB7CiAgICAgIGNvbnN0IGJ1ZmZlcjggPSBuZXcgVWludDhBcnJheShzZWxmLmluc3QuZXhwb3J0cy5tZW1vcnkuYnVmZmVyKTsKICAgICAgaWYgKHNlbGYuZmRzW2ZkXSAhPSB2b2lkIDApIHsKICAgICAgICBjb25zdCBwYXRoID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpLmRlY29kZShidWZmZXI4LnNsaWNlKHBhdGhfcHRyLCBwYXRoX3B0ciArIHBhdGhfbGVuKSk7CiAgICAgICAgcmV0dXJuIHNlbGYuZmRzW2ZkXS5wYXRoX3VubGlua19maWxlKHBhdGgpOwogICAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBFUlJOT19CQURGOwogICAgICB9CiAgICB9LCBwb2xsX29uZW9mZihpbl8sIG91dCwgbnN1YnNjcmlwdGlvbnMpIHsKICAgICAgdGhyb3cgImFzeW5jIGlvIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgcHJvY19leGl0KGV4aXRfY29kZSkgewogICAgICB0aHJvdyBuZXcgV0FTSVByb2NFeGl0KGV4aXRfY29kZSk7CiAgICB9LCBwcm9jX3JhaXNlKHNpZykgewogICAgICB0aHJvdyAicmFpc2VkIHNpZ25hbCAiICsgc2lnOwogICAgfSwgc2NoZWRfeWllbGQoKSB7CiAgICB9LCByYW5kb21fZ2V0KGJ1ZiwgYnVmX2xlbikgewogICAgICBjb25zdCBidWZmZXI4ID0gbmV3IFVpbnQ4QXJyYXkoc2VsZi5pbnN0LmV4cG9ydHMubWVtb3J5LmJ1ZmZlcik7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYnVmX2xlbjsgaSsrKSB7CiAgICAgICAgYnVmZmVyOFtidWYgKyBpXSA9IE1hdGgucmFuZG9tKCkgKiAyNTYgfCAwOwogICAgICB9CiAgICB9LCBzb2NrX3JlY3YoZmQsIHJpX2RhdGEsIHJpX2ZsYWdzKSB7CiAgICAgIHRocm93ICJzb2NrZXRzIG5vdCBzdXBwb3J0ZWQiOwogICAgfSwgc29ja19zZW5kKGZkLCBzaV9kYXRhLCBzaV9mbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfc2h1dGRvd24oZmQsIGhvdykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0sIHNvY2tfYWNjZXB0KGZkLCBmbGFncykgewogICAgICB0aHJvdyAic29ja2V0cyBub3Qgc3VwcG9ydGVkIjsKICAgIH0gfTsKICB9Cn07CgovLyBub2RlX21vZHVsZXMvQGJqb3JuMy9icm93c2VyX3dhc2lfc2hpbS9kaXN0L2ZkLmpzCnZhciBGZCA9IGNsYXNzIHsKICBmZF9hbGxvY2F0ZShvZmZzZXQsIGxlbikgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfY2xvc2UoKSB7CiAgICByZXR1cm4gMDsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBmZHN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmRzdGF0X3NldF9mbGFncyhmbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmRzdGF0X3NldF9yaWdodHMoZnNfcmlnaHRzX2Jhc2UsIGZzX3JpZ2h0c19pbmhlcml0aW5nKSB7CiAgICByZXR1cm4gRVJSTk9fTk9UU1VQOwogIH0KICBmZF9maWxlc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3NpemUoc2l6ZSkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfZmlsZXN0YXRfc2V0X3RpbWVzKGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbmV3IFVpbnQ4QXJyYXkoKSB9OwogIH0KICBmZF9wcmVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBwcmVzdGF0OiBudWxsIH07CiAgfQogIGZkX3B3cml0ZShkYXRhLCBvZmZzZXQpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9yZWFkKHNpemUpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBkYXRhOiBuZXcgVWludDhBcnJheSgpIH07CiAgfQogIGZkX3JlYWRkaXJfc2luZ2xlKGNvb2tpZSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RTVVAsIGRpcmVudDogbnVsbCB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF9zeW5jKCkgewogICAgcmV0dXJuIDA7CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgbndyaXR0ZW46IDAgfTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfZmlsZXN0YXRfZ2V0KGZsYWdzLCBwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZmlsZXN0YXQ6IG51bGwgfTsKICB9CiAgcGF0aF9maWxlc3RhdF9zZXRfdGltZXMoZmxhZ3MsIHBhdGgsIGF0aW0sIG10aW0sIGZzdF9mbGFncykgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9saW5rKHBhdGgsIGlub2RlLCBhbGxvd19kaXIpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rKHBhdGgpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9sb29rdXAocGF0aCwgZGlyZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UU1VQLCBpbm9kZV9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9vcGVuKGRpcmZsYWdzLCBwYXRoLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9URElSLCBmZF9vYmo6IG51bGwgfTsKICB9CiAgcGF0aF9yZWFkbGluayhwYXRoKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVFNVUCwgZGF0YTogbnVsbCB9OwogIH0KICBwYXRoX3JlbW92ZV9kaXJlY3RvcnkocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9CiAgcGF0aF9yZW5hbWUob2xkX3BhdGgsIG5ld19mZCwgbmV3X3BhdGgpIHsKICAgIHJldHVybiBFUlJOT19OT1RTVVA7CiAgfQogIHBhdGhfdW5saW5rX2ZpbGUocGF0aCkgewogICAgcmV0dXJuIEVSUk5PX05PVFNVUDsKICB9Cn07CnZhciBJbm9kZSA9IGNsYXNzIHsKfTsKCi8vIG5vZGVfbW9kdWxlcy9AYmpvcm4zL2Jyb3dzZXJfd2FzaV9zaGltL2Rpc3QvZnNfbWVtLmpzCnZhciBPcGVuRmlsZSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICBpZiAodGhpcy5maWxlLnNpemUgPiBvZmZzZXQgKyBsZW4pIHsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5ld19kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKG9mZnNldCArIGxlbikpOwogICAgICBuZXdfZGF0YS5zZXQodGhpcy5maWxlLmRhdGEsIDApOwogICAgICB0aGlzLmZpbGUuZGF0YSA9IG5ld19kYXRhOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdDogbmV3IEZkc3RhdChGSUxFVFlQRV9SRUdVTEFSX0ZJTEUsIDApIH07CiAgfQogIGZkX2ZpbGVzdGF0X3NldF9zaXplKHNpemUpIHsKICAgIGlmICh0aGlzLmZpbGUuc2l6ZSA+IHNpemUpIHsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheSh0aGlzLmZpbGUuZGF0YS5idWZmZXIuc2xpY2UoMCwgTnVtYmVyKHNpemUpKSk7CiAgICB9IGVsc2UgewogICAgICBjb25zdCBuZXdfZGF0YSA9IG5ldyBVaW50OEFycmF5KE51bWJlcihzaXplKSk7CiAgICAgIG5ld19kYXRhLnNldCh0aGlzLmZpbGUuZGF0YSwgMCk7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3X2RhdGE7CiAgICB9CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICBjb25zdCBzbGljZSA9IHRoaXMuZmlsZS5kYXRhLnNsaWNlKE51bWJlcih0aGlzLmZpbGVfcG9zKSwgTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoc2l6ZSkpKTsKICAgIHRoaXMuZmlsZV9wb3MgKz0gQmlnSW50KHNsaWNlLmxlbmd0aCk7CiAgICByZXR1cm4geyByZXQ6IDAsIGRhdGE6IHNsaWNlIH07CiAgfQogIGZkX3ByZWFkKHNpemUsIG9mZnNldCkgewogICAgY29uc3Qgc2xpY2UgPSB0aGlzLmZpbGUuZGF0YS5zbGljZShOdW1iZXIob2Zmc2V0KSwgTnVtYmVyKG9mZnNldCArIEJpZ0ludChzaXplKSkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBkYXRhOiBzbGljZSB9OwogIH0KICBmZF9zZWVrKG9mZnNldCwgd2hlbmNlKSB7CiAgICBsZXQgY2FsY3VsYXRlZF9vZmZzZXQ7CiAgICBzd2l0Y2ggKHdoZW5jZSkgewogICAgICBjYXNlIFdIRU5DRV9TRVQ6CiAgICAgICAgY2FsY3VsYXRlZF9vZmZzZXQgPSBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0NVUjoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IHRoaXMuZmlsZV9wb3MgKyBvZmZzZXQ7CiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgV0hFTkNFX0VORDoKICAgICAgICBjYWxjdWxhdGVkX29mZnNldCA9IEJpZ0ludCh0aGlzLmZpbGUuZGF0YS5ieXRlTGVuZ3RoKSArIG9mZnNldDsKICAgICAgICBicmVhazsKICAgICAgZGVmYXVsdDoKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0lOVkFMLCBvZmZzZXQ6IDBuIH07CiAgICB9CiAgICBpZiAoY2FsY3VsYXRlZF9vZmZzZXQgPCAwKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fSU5WQUwsIG9mZnNldDogMG4gfTsKICAgIH0KICAgIHRoaXMuZmlsZV9wb3MgPSBjYWxjdWxhdGVkX29mZnNldDsKICAgIHJldHVybiB7IHJldDogMCwgb2Zmc2V0OiB0aGlzLmZpbGVfcG9zIH07CiAgfQogIGZkX3RlbGwoKSB7CiAgICByZXR1cm4geyByZXQ6IDAsIG9mZnNldDogdGhpcy5maWxlX3BvcyB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAodGhpcy5maWxlX3BvcyArIEJpZ0ludChkYXRhLmJ5dGVMZW5ndGgpID4gdGhpcy5maWxlLnNpemUpIHsKICAgICAgY29uc3Qgb2xkID0gdGhpcy5maWxlLmRhdGE7CiAgICAgIHRoaXMuZmlsZS5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoTnVtYmVyKHRoaXMuZmlsZV9wb3MgKyBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKSkpOwogICAgICB0aGlzLmZpbGUuZGF0YS5zZXQob2xkKTsKICAgIH0KICAgIHRoaXMuZmlsZS5kYXRhLnNldChkYXRhLCBOdW1iZXIodGhpcy5maWxlX3BvcykpOwogICAgdGhpcy5maWxlX3BvcyArPSBCaWdJbnQoZGF0YS5ieXRlTGVuZ3RoKTsKICAgIHJldHVybiB7IHJldDogMCwgbndyaXR0ZW46IGRhdGEuYnl0ZUxlbmd0aCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICBpZiAodGhpcy5maWxlLnJlYWRvbmx5KQogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgICBpZiAob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkgPiB0aGlzLmZpbGUuc2l6ZSkgewogICAgICBjb25zdCBvbGQgPSB0aGlzLmZpbGUuZGF0YTsKICAgICAgdGhpcy5maWxlLmRhdGEgPSBuZXcgVWludDhBcnJheShOdW1iZXIob2Zmc2V0ICsgQmlnSW50KGRhdGEuYnl0ZUxlbmd0aCkpKTsKICAgICAgdGhpcy5maWxlLmRhdGEuc2V0KG9sZCk7CiAgICB9CiAgICB0aGlzLmZpbGUuZGF0YS5zZXQoZGF0YSwgTnVtYmVyKG9mZnNldCkpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZmlsZS5zdGF0KCkgfTsKICB9CiAgY29uc3RydWN0b3IoZmlsZSkgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZmlsZV9wb3MgPSAwbjsKICAgIHRoaXMuZmlsZSA9IGZpbGU7CiAgfQp9Owp2YXIgT3BlbkRpcmVjdG9yeSA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX3NlZWsob2Zmc2V0LCB3aGVuY2UpIHsKICAgIHJldHVybiB7IHJldDogRVJSTk9fQkFERiwgb2Zmc2V0OiAwbiB9OwogIH0KICBmZF90ZWxsKCkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBvZmZzZXQ6IDBuIH07CiAgfQogIGZkX2FsbG9jYXRlKG9mZnNldCwgbGVuKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfZmRzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmRzdGF0OiBuZXcgRmRzdGF0KEZJTEVUWVBFX0RJUkVDVE9SWSwgMCkgfTsKICB9CiAgZmRfcmVhZGRpcl9zaW5nbGUoY29va2llKSB7CiAgICBpZiAoZGVidWcuZW5hYmxlZCkgewogICAgICBkZWJ1Zy5sb2coInJlYWRkaXJfc2luZ2xlIiwgY29va2llKTsKICAgICAgZGVidWcubG9nKGNvb2tpZSwgdGhpcy5kaXIuY29udGVudHMua2V5cygpKTsKICAgIH0KICAgIGlmIChjb29raWUgPT0gMG4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMW4sICIuIiwgRklMRVRZUEVfRElSRUNUT1JZKSB9OwogICAgfSBlbHNlIGlmIChjb29raWUgPT0gMW4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBkaXJlbnQ6IG5ldyBEaXJlbnQoMm4sICIuLiIsIEZJTEVUWVBFX0RJUkVDVE9SWSkgfTsKICAgIH0KICAgIGlmIChjb29raWUgPj0gQmlnSW50KHRoaXMuZGlyLmNvbnRlbnRzLnNpemUpICsgMm4pIHsKICAgICAgcmV0dXJuIHsgcmV0OiAwLCBkaXJlbnQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IFtuYW1lLCBlbnRyeV0gPSBBcnJheS5mcm9tKHRoaXMuZGlyLmNvbnRlbnRzLmVudHJpZXMoKSlbTnVtYmVyKGNvb2tpZSAtIDJuKV07CiAgICByZXR1cm4geyByZXQ6IDAsIGRpcmVudDogbmV3IERpcmVudChjb29raWUgKyAxbiwgbmFtZSwgZW50cnkuc3RhdCgpLmZpbGV0eXBlKSB9OwogIH0KICBwYXRoX2ZpbGVzdGF0X2dldChmbGFncywgcGF0aF9zdHIpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX2VyciwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX2VyciwgZmlsZXN0YXQ6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBmaWxlc3RhdDogbnVsbCB9OwogICAgfQogICAgcmV0dXJuIHsgcmV0OiAwLCBmaWxlc3RhdDogZW50cnkuc3RhdCgpIH07CiAgfQogIHBhdGhfbG9va3VwKHBhdGhfc3RyLCBkaXJmbGFncykgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0LCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0LCBpbm9kZV9vYmo6IG51bGwgfTsKICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX29wZW4oZGlyZmxhZ3MsIHBhdGhfc3RyLCBvZmxhZ3MsIGZzX3JpZ2h0c19iYXNlLCBmc19yaWdodHNfaW5oZXJpdGluZywgZmRfZmxhZ3MpIHsKICAgIGNvbnN0IHsgcmV0OiBwYXRoX3JldCwgcGF0aCB9ID0gUGF0aC5mcm9tKHBhdGhfc3RyKTsKICAgIGlmIChwYXRoID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBwYXRoX3JldCwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICBsZXQgeyByZXQsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfZW50cnlfZm9yX3BhdGgocGF0aCk7CiAgICBpZiAoZW50cnkgPT0gbnVsbCkgewogICAgICBpZiAocmV0ICE9IEVSUk5PX05PRU5UKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0LCBmZF9vYmo6IG51bGwgfTsKICAgICAgfQogICAgICBpZiAoKG9mbGFncyAmIE9GTEFHU19DUkVBVCkgPT0gT0ZMQUdTX0NSRUFUKSB7CiAgICAgICAgY29uc3QgeyByZXQ6IHJldDIsIGVudHJ5OiBuZXdfZW50cnkgfSA9IHRoaXMuZGlyLmNyZWF0ZV9lbnRyeV9mb3JfcGF0aChwYXRoX3N0ciwgKG9mbGFncyAmIE9GTEFHU19ESVJFQ1RPUlkpID09IE9GTEFHU19ESVJFQ1RPUlkpOwogICAgICAgIGlmIChuZXdfZW50cnkgPT0gbnVsbCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiByZXQyLCBmZF9vYmo6IG51bGwgfTsKICAgICAgICB9CiAgICAgICAgZW50cnkgPSBuZXdfZW50cnk7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZmRfb2JqOiBudWxsIH07CiAgICAgIH0KICAgIH0gZWxzZSBpZiAoKG9mbGFncyAmIE9GTEFHU19FWENMKSA9PSBPRkxBR1NfRVhDTCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX0RJUkVDVE9SWSkgPT0gT0ZMQUdTX0RJUkVDVE9SWSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT09IEZJTEVUWVBFX0RJUkVDVE9SWSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZmRfb2JqOiBudWxsIH07CiAgICB9CiAgICByZXR1cm4gZW50cnkucGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKTsKICB9CiAgcGF0aF9jcmVhdGVfZGlyZWN0b3J5KHBhdGgpIHsKICAgIHJldHVybiB0aGlzLnBhdGhfb3BlbigwLCBwYXRoLCBPRkxBR1NfQ1JFQVQgfCBPRkxBR1NfRElSRUNUT1JZLCAwbiwgMG4sIDApLnJldDsKICB9CiAgcGF0aF9saW5rKHBhdGhfc3RyLCBpbm9kZSwgYWxsb3dfZGlyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGlmIChwYXRoLmlzX2RpcikgewogICAgICByZXR1cm4gRVJSTk9fTk9FTlQ7CiAgICB9CiAgICBjb25zdCB7IHJldDogcGFyZW50X3JldCwgcGFyZW50X2VudHJ5LCBmaWxlbmFtZSwgZW50cnkgfSA9IHRoaXMuZGlyLmdldF9wYXJlbnRfZGlyX2FuZF9lbnRyeV9mb3JfcGF0aChwYXRoLCB0cnVlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXJlbnRfcmV0OwogICAgfQogICAgaWYgKGVudHJ5ICE9IG51bGwpIHsKICAgICAgY29uc3Qgc291cmNlX2lzX2RpciA9IGlub2RlLnN0YXQoKS5maWxldHlwZSA9PSBGSUxFVFlQRV9ESVJFQ1RPUlk7CiAgICAgIGNvbnN0IHRhcmdldF9pc19kaXIgPSBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZOwogICAgICBpZiAoc291cmNlX2lzX2RpciAmJiB0YXJnZXRfaXNfZGlyKSB7CiAgICAgICAgaWYgKGFsbG93X2RpciAmJiBlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgewogICAgICAgICAgaWYgKGVudHJ5LmNvbnRlbnRzLnNpemUgPT0gMCkgewogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIEVSUk5PX05PVEVNUFRZOwogICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICByZXR1cm4gRVJSTk9fRVhJU1Q7CiAgICAgICAgfQogICAgICB9IGVsc2UgaWYgKHNvdXJjZV9pc19kaXIgJiYgIXRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fTk9URElSOwogICAgICB9IGVsc2UgaWYgKCFzb3VyY2VfaXNfZGlyICYmIHRhcmdldF9pc19kaXIpIHsKICAgICAgICByZXR1cm4gRVJSTk9fSVNESVI7CiAgICAgIH0gZWxzZSBpZiAoaW5vZGUuc3RhdCgpLmZpbGV0eXBlID09IEZJTEVUWVBFX1JFR1VMQVJfRklMRSAmJiBlbnRyeS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfUkVHVUxBUl9GSUxFKSB7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIEVSUk5PX0VYSVNUOwogICAgICB9CiAgICB9CiAgICBpZiAoIWFsbG93X2RpciAmJiBpbm9kZS5zdGF0KCkuZmlsZXR5cGUgPT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgIHJldHVybiBFUlJOT19QRVJNOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLnNldChmaWxlbmFtZSwgaW5vZGUpOwogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIHBhdGhfdW5saW5rKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogcGF0aF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgY29uc3QgeyByZXQ6IHBhcmVudF9yZXQsIHBhcmVudF9lbnRyeSwgZmlsZW5hbWUsIGVudHJ5IH0gPSB0aGlzLmRpci5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGlub2RlX29iajogbnVsbCB9OwogICAgfQogICAgaWYgKGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgaW5vZGVfb2JqOiBudWxsIH07CiAgICB9CiAgICBwYXJlbnRfZW50cnkuY29udGVudHMuZGVsZXRlKGZpbGVuYW1lKTsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgaW5vZGVfb2JqOiBlbnRyeSB9OwogIH0KICBwYXRoX3VubGlua19maWxlKHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoZW50cnkuc3RhdCgpLmZpbGV0eXBlID09PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX0lTRElSOwogICAgfQogICAgcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSk7CiAgICByZXR1cm4gRVJSTk9fU1VDQ0VTUzsKICB9CiAgcGF0aF9yZW1vdmVfZGlyZWN0b3J5KHBhdGhfc3RyKSB7CiAgICBjb25zdCB7IHJldDogcGF0aF9yZXQsIHBhdGggfSA9IFBhdGguZnJvbShwYXRoX3N0cik7CiAgICBpZiAocGF0aCA9PSBudWxsKSB7CiAgICAgIHJldHVybiBwYXRoX3JldDsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5kaXIuZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGZhbHNlKTsKICAgIGlmIChwYXJlbnRfZW50cnkgPT0gbnVsbCB8fCBmaWxlbmFtZSA9PSBudWxsIHx8IGVudHJ5ID09IG51bGwpIHsKICAgICAgcmV0dXJuIHBhcmVudF9yZXQ7CiAgICB9CiAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkgfHwgZW50cnkuc3RhdCgpLmZpbGV0eXBlICE9PSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PVERJUjsKICAgIH0KICAgIGlmIChlbnRyeS5jb250ZW50cy5zaXplICE9PSAwKSB7CiAgICAgIHJldHVybiBFUlJOT19OT1RFTVBUWTsKICAgIH0KICAgIGlmICghcGFyZW50X2VudHJ5LmNvbnRlbnRzLmRlbGV0ZShmaWxlbmFtZSkpIHsKICAgICAgcmV0dXJuIEVSUk5PX05PRU5UOwogICAgfQogICAgcmV0dXJuIEVSUk5PX1NVQ0NFU1M7CiAgfQogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIHJldHVybiB7IHJldDogMCwgZmlsZXN0YXQ6IHRoaXMuZGlyLnN0YXQoKSB9OwogIH0KICBmZF9maWxlc3RhdF9zZXRfc2l6ZShzaXplKSB7CiAgICByZXR1cm4gRVJSTk9fQkFERjsKICB9CiAgZmRfcmVhZChzaXplKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfcHJlYWQoc2l6ZSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIGRhdGE6IG5ldyBVaW50OEFycmF5KCkgfTsKICB9CiAgZmRfd3JpdGUoZGF0YSkgewogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19CQURGLCBud3JpdHRlbjogMCB9OwogIH0KICBmZF9wd3JpdGUoZGF0YSwgb2Zmc2V0KSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX0JBREYsIG53cml0dGVuOiAwIH07CiAgfQogIGNvbnN0cnVjdG9yKGRpcikgewogICAgc3VwZXIoKTsKICAgIHRoaXMuZGlyID0gZGlyOwogIH0KfTsKdmFyIFByZW9wZW5EaXJlY3RvcnkgPSBjbGFzcyBleHRlbmRzIE9wZW5EaXJlY3RvcnkgewogIGZkX3ByZXN0YXRfZ2V0KCkgewogICAgcmV0dXJuIHsgcmV0OiAwLCBwcmVzdGF0OiBQcmVzdGF0LmRpcih0aGlzLnByZXN0YXRfbmFtZSkgfTsKICB9CiAgY29uc3RydWN0b3IobmFtZSwgY29udGVudHMpIHsKICAgIHN1cGVyKG5ldyBEaXJlY3RvcnkoY29udGVudHMpKTsKICAgIHRoaXMucHJlc3RhdF9uYW1lID0gbmFtZTsKICB9Cn07CnZhciBGaWxlID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICBpZiAodGhpcy5yZWFkb25seSAmJiAoZnNfcmlnaHRzX2Jhc2UgJiBCaWdJbnQoUklHSFRTX0ZEX1dSSVRFKSkgPT0gQmlnSW50KFJJR0hUU19GRF9XUklURSkpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgIH0KICAgIGlmICgob2ZsYWdzICYgT0ZMQUdTX1RSVU5DKSA9PSBPRkxBR1NfVFJVTkMpIHsKICAgICAgaWYgKHRoaXMucmVhZG9ubHkpCiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19QRVJNLCBmZF9vYmo6IG51bGwgfTsKICAgICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoW10pOwogICAgfQogICAgY29uc3QgZmlsZSA9IG5ldyBPcGVuRmlsZSh0aGlzKTsKICAgIGlmIChmZF9mbGFncyAmIEZERkxBR1NfQVBQRU5EKQogICAgICBmaWxlLmZkX3NlZWsoMG4sIFdIRU5DRV9FTkQpOwogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBmZF9vYmo6IGZpbGUgfTsKICB9CiAgZ2V0IHNpemUoKSB7CiAgICByZXR1cm4gQmlnSW50KHRoaXMuZGF0YS5ieXRlTGVuZ3RoKTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfUkVHVUxBUl9GSUxFLCB0aGlzLnNpemUpOwogIH0KICBjb25zdHJ1Y3RvcihkYXRhLCBvcHRpb25zKSB7CiAgICBzdXBlcigpOwogICAgdGhpcy5kYXRhID0gbmV3IFVpbnQ4QXJyYXkoZGF0YSk7CiAgICB0aGlzLnJlYWRvbmx5ID0gISFvcHRpb25zPy5yZWFkb25seTsKICB9Cn07CnZhciBQYXRoID0gY2xhc3MgUGF0aDIgewogIHN0YXRpYyBmcm9tKHBhdGgpIHsKICAgIGNvbnN0IHNlbGYgPSBuZXcgUGF0aDIoKTsKICAgIHNlbGYuaXNfZGlyID0gcGF0aC5lbmRzV2l0aCgiLyIpOwogICAgaWYgKHBhdGguc3RhcnRzV2l0aCgiLyIpKSB7CiAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9UQ0FQQUJMRSwgcGF0aDogbnVsbCB9OwogICAgfQogICAgaWYgKHBhdGguaW5jbHVkZXMoIlwwIikpIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGF0aDogbnVsbCB9OwogICAgfQogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5zcGxpdCgiLyIpKSB7CiAgICAgIGlmIChjb21wb25lbnQgPT09ICIiIHx8IGNvbXBvbmVudCA9PT0gIi4iKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KICAgICAgaWYgKGNvbXBvbmVudCA9PT0gIi4uIikgewogICAgICAgIGlmIChzZWxmLnBhcnRzLnBvcCgpID09IHZvaWQgMCkgewogICAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RDQVBBQkxFLCBwYXRoOiBudWxsIH07CiAgICAgICAgfQogICAgICAgIGNvbnRpbnVlOwogICAgICB9CiAgICAgIHNlbGYucGFydHMucHVzaChjb21wb25lbnQpOwogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXRoOiBzZWxmIH07CiAgfQogIHRvX3BhdGhfc3RyaW5nKCkgewogICAgbGV0IHMgPSB0aGlzLnBhcnRzLmpvaW4oIi8iKTsKICAgIGlmICh0aGlzLmlzX2RpcikgewogICAgICBzICs9ICIvIjsKICAgIH0KICAgIHJldHVybiBzOwogIH0KICBjb25zdHJ1Y3RvcigpIHsKICAgIHRoaXMucGFydHMgPSBbXTsKICAgIHRoaXMuaXNfZGlyID0gZmFsc2U7CiAgfQp9Owp2YXIgRGlyZWN0b3J5ID0gY2xhc3MgZXh0ZW5kcyBJbm9kZSB7CiAgcGF0aF9vcGVuKG9mbGFncywgZnNfcmlnaHRzX2Jhc2UsIGZkX2ZsYWdzKSB7CiAgICByZXR1cm4geyByZXQ6IEVSUk5PX1NVQ0NFU1MsIGZkX29iajogbmV3IE9wZW5EaXJlY3RvcnkodGhpcykgfTsKICB9CiAgc3RhdCgpIHsKICAgIHJldHVybiBuZXcgRmlsZXN0YXQoRklMRVRZUEVfRElSRUNUT1JZLCAwbik7CiAgfQogIGdldF9lbnRyeV9mb3JfcGF0aChwYXRoKSB7CiAgICBsZXQgZW50cnkgPSB0aGlzOwogICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgcGF0aC5wYXJ0cykgewogICAgICBpZiAoIShlbnRyeSBpbnN0YW5jZW9mIERpcmVjdG9yeSkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgICBjb25zdCBjaGlsZCA9IGVudHJ5LmNvbnRlbnRzLmdldChjb21wb25lbnQpOwogICAgICBpZiAoY2hpbGQgIT09IHZvaWQgMCkgewogICAgICAgIGVudHJ5ID0gY2hpbGQ7CiAgICAgIH0gZWxzZSB7CiAgICAgICAgZGVidWcubG9nKGNvbXBvbmVudCk7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT0VOVCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgaWYgKHBhdGguaXNfZGlyKSB7CiAgICAgIGlmIChlbnRyeS5zdGF0KCkuZmlsZXR5cGUgIT0gRklMRVRZUEVfRElSRUNUT1JZKSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19OT1RESVIsIGVudHJ5OiBudWxsIH07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgZ2V0X3BhcmVudF9kaXJfYW5kX2VudHJ5X2Zvcl9wYXRoKHBhdGgsIGFsbG93X3VuZGVmaW5lZCkgewogICAgY29uc3QgZmlsZW5hbWUgPSBwYXRoLnBhcnRzLnBvcCgpOwogICAgaWYgKGZpbGVuYW1lID09PSB2b2lkIDApIHsKICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19JTlZBTCwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IHsgcmV0OiBlbnRyeV9yZXQsIGVudHJ5OiBwYXJlbnRfZW50cnkgfSA9IHRoaXMuZ2V0X2VudHJ5X2Zvcl9wYXRoKHBhdGgpOwogICAgaWYgKHBhcmVudF9lbnRyeSA9PSBudWxsKSB7CiAgICAgIHJldHVybiB7IHJldDogZW50cnlfcmV0LCBwYXJlbnRfZW50cnk6IG51bGwsIGZpbGVuYW1lOiBudWxsLCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgaWYgKCEocGFyZW50X2VudHJ5IGluc3RhbmNlb2YgRGlyZWN0b3J5KSkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgIH0KICAgIGNvbnN0IGVudHJ5ID0gcGFyZW50X2VudHJ5LmNvbnRlbnRzLmdldChmaWxlbmFtZSk7CiAgICBpZiAoZW50cnkgPT09IHZvaWQgMCkgewogICAgICBpZiAoIWFsbG93X3VuZGVmaW5lZCkgewogICAgICAgIHJldHVybiB7IHJldDogRVJSTk9fTk9FTlQsIHBhcmVudF9lbnRyeTogbnVsbCwgZmlsZW5hbWU6IG51bGwsIGVudHJ5OiBudWxsIH07CiAgICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeTogbnVsbCB9OwogICAgICB9CiAgICB9CiAgICBpZiAocGF0aC5pc19kaXIpIHsKICAgICAgaWYgKGVudHJ5LnN0YXQoKS5maWxldHlwZSAhPSBGSUxFVFlQRV9ESVJFQ1RPUlkpIHsKICAgICAgICByZXR1cm4geyByZXQ6IEVSUk5PX05PVERJUiwgcGFyZW50X2VudHJ5OiBudWxsLCBmaWxlbmFtZTogbnVsbCwgZW50cnk6IG51bGwgfTsKICAgICAgfQogICAgfQogICAgcmV0dXJuIHsgcmV0OiBFUlJOT19TVUNDRVNTLCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9OwogIH0KICBjcmVhdGVfZW50cnlfZm9yX3BhdGgocGF0aF9zdHIsIGlzX2RpcikgewogICAgY29uc3QgeyByZXQ6IHBhdGhfcmV0LCBwYXRoIH0gPSBQYXRoLmZyb20ocGF0aF9zdHIpOwogICAgaWYgKHBhdGggPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhdGhfcmV0LCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgbGV0IHsgcmV0OiBwYXJlbnRfcmV0LCBwYXJlbnRfZW50cnksIGZpbGVuYW1lLCBlbnRyeSB9ID0gdGhpcy5nZXRfcGFyZW50X2Rpcl9hbmRfZW50cnlfZm9yX3BhdGgocGF0aCwgdHJ1ZSk7CiAgICBpZiAocGFyZW50X2VudHJ5ID09IG51bGwgfHwgZmlsZW5hbWUgPT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IHBhcmVudF9yZXQsIGVudHJ5OiBudWxsIH07CiAgICB9CiAgICBpZiAoZW50cnkgIT0gbnVsbCkgewogICAgICByZXR1cm4geyByZXQ6IEVSUk5PX0VYSVNULCBlbnRyeTogbnVsbCB9OwogICAgfQogICAgZGVidWcubG9nKCJjcmVhdGUiLCBwYXRoKTsKICAgIGxldCBuZXdfY2hpbGQ7CiAgICBpZiAoIWlzX2RpcikgewogICAgICBuZXdfY2hpbGQgPSBuZXcgRmlsZShuZXcgQXJyYXlCdWZmZXIoMCkpOwogICAgfSBlbHNlIHsKICAgICAgbmV3X2NoaWxkID0gbmV3IERpcmVjdG9yeSgvKiBAX19QVVJFX18gKi8gbmV3IE1hcCgpKTsKICAgIH0KICAgIHBhcmVudF9lbnRyeS5jb250ZW50cy5zZXQoZmlsZW5hbWUsIG5ld19jaGlsZCk7CiAgICBlbnRyeSA9IG5ld19jaGlsZDsKICAgIHJldHVybiB7IHJldDogRVJSTk9fU1VDQ0VTUywgZW50cnkgfTsKICB9CiAgY29uc3RydWN0b3IoY29udGVudHMpIHsKICAgIHN1cGVyKCk7CiAgICBpZiAoY29udGVudHMgaW5zdGFuY2VvZiBBcnJheSkgewogICAgICB0aGlzLmNvbnRlbnRzID0gbmV3IE1hcChjb250ZW50cyk7CiAgICB9IGVsc2UgewogICAgICB0aGlzLmNvbnRlbnRzID0gY29udGVudHM7CiAgICB9CiAgfQp9Owp2YXIgQ29uc29sZVN0ZG91dCA9IGNsYXNzIGV4dGVuZHMgRmQgewogIGZkX2ZpbGVzdGF0X2dldCgpIHsKICAgIGNvbnN0IGZpbGVzdGF0ID0gbmV3IEZpbGVzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIEJpZ0ludCgwKSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZpbGVzdGF0IH07CiAgfQogIGZkX2Zkc3RhdF9nZXQoKSB7CiAgICBjb25zdCBmZHN0YXQgPSBuZXcgRmRzdGF0KEZJTEVUWVBFX0NIQVJBQ1RFUl9ERVZJQ0UsIDApOwogICAgZmRzdGF0LmZzX3JpZ2h0c19iYXNlID0gQmlnSW50KFJJR0hUU19GRF9XUklURSk7CiAgICByZXR1cm4geyByZXQ6IDAsIGZkc3RhdCB9OwogIH0KICBmZF93cml0ZShkYXRhKSB7CiAgICB0aGlzLndyaXRlKGRhdGEpOwogICAgcmV0dXJuIHsgcmV0OiAwLCBud3JpdHRlbjogZGF0YS5ieXRlTGVuZ3RoIH07CiAgfQogIHN0YXRpYyBsaW5lQnVmZmVyZWQod3JpdGUpIHsKICAgIGNvbnN0IGRlYyA9IG5ldyBUZXh0RGVjb2RlcigidXRmLTgiLCB7IGZhdGFsOiBmYWxzZSB9KTsKICAgIGxldCBsaW5lX2J1ZiA9ICIiOwogICAgcmV0dXJuIG5ldyBDb25zb2xlU3Rkb3V0KChidWZmZXIpID0+IHsKICAgICAgbGluZV9idWYgKz0gZGVjLmRlY29kZShidWZmZXIsIHsgc3RyZWFtOiB0cnVlIH0pOwogICAgICBjb25zdCBsaW5lcyA9IGxpbmVfYnVmLnNwbGl0KCJcbiIpOwogICAgICBmb3IgKGNvbnN0IFtpLCBsaW5lXSBvZiBsaW5lcy5lbnRyaWVzKCkpIHsKICAgICAgICBpZiAoaSA8IGxpbmVzLmxlbmd0aCAtIDEpIHsKICAgICAgICAgIHdyaXRlKGxpbmUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICBsaW5lX2J1ZiA9IGxpbmU7CiAgICAgICAgfQogICAgICB9CiAgICB9KTsKICB9CiAgY29uc3RydWN0b3Iod3JpdGUpIHsKICAgIHN1cGVyKCk7CiAgICB0aGlzLndyaXRlID0gd3JpdGU7CiAgfQp9OwoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvaW5kZXguanMKZnVuY3Rpb24gcGFyc2VJbXBvcnRzKG1vZHVsZUJ5dGVzKSB7CiAgaWYgKG1vZHVsZUJ5dGVzIGluc3RhbmNlb2YgVWludDhBcnJheSkgewogIH0gZWxzZSBpZiAobW9kdWxlQnl0ZXMgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcyk7CiAgfSBlbHNlIGlmIChtb2R1bGVCeXRlcy5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikgewogICAgbW9kdWxlQnl0ZXMgPSBuZXcgVWludDhBcnJheShtb2R1bGVCeXRlcy5idWZmZXIpOwogIH0gZWxzZSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoIkFyZ3VtZW50IG11c3QgYmUgYSBidWZmZXIgc291cmNlLCBsaWtlIFVpbnQ4QXJyYXkgb3IgQXJyYXlCdWZmZXIiKTsKICB9CiAgY29uc3QgcGFyc2VTdGF0ZSA9IG5ldyBQYXJzZVN0YXRlKG1vZHVsZUJ5dGVzKTsKICBwYXJzZU1hZ2ljTnVtYmVyKHBhcnNlU3RhdGUpOwogIHBhcnNlVmVyc2lvbihwYXJzZVN0YXRlKTsKICBjb25zdCB0eXBlcyA9IFtdOwogIGNvbnN0IGltcG9ydHMgPSBbXTsKICB3aGlsZSAocGFyc2VTdGF0ZS5oYXNNb3JlQnl0ZXMoKSkgewogICAgY29uc3Qgc2VjdGlvbklkID0gcGFyc2VTdGF0ZS5yZWFkQnl0ZSgpOwogICAgY29uc3Qgc2VjdGlvblNpemUgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgc3dpdGNoIChzZWN0aW9uSWQpIHsKICAgICAgY2FzZSAxOiB7CiAgICAgICAgY29uc3QgdHlwZUNvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHR5cGVDb3VudDsgaSsrKSB7CiAgICAgICAgICB0eXBlcy5wdXNoKHBhcnNlRnVuY3Rpb25UeXBlKHBhcnNlU3RhdGUpKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgY2FzZSAyOiB7CiAgICAgICAgY29uc3QgaW1wb3J0Q291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW1wb3J0Q291bnQ7IGkrKykgewogICAgICAgICAgY29uc3QgbW9kdWxlID0gcGFyc2VTdGF0ZS5yZWFkTmFtZSgpOwogICAgICAgICAgY29uc3QgbmFtZSA9IHBhcnNlU3RhdGUucmVhZE5hbWUoKTsKICAgICAgICAgIGNvbnN0IHR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKICAgICAgICAgICAgY2FzZSAwOgogICAgICAgICAgICAgIGNvbnN0IGluZGV4ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJmdW5jdGlvbiIsIHR5cGU6IHR5cGVzW2luZGV4XSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAxOgogICAgICAgICAgICAgIGltcG9ydHMucHVzaCh7IG1vZHVsZSwgbmFtZSwga2luZDogInRhYmxlIiwgdHlwZTogcGFyc2VUYWJsZVR5cGUocGFyc2VTdGF0ZSkgfSk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgMjoKICAgICAgICAgICAgICBpbXBvcnRzLnB1c2goeyBtb2R1bGUsIG5hbWUsIGtpbmQ6ICJtZW1vcnkiLCB0eXBlOiBwYXJzZUxpbWl0cyhwYXJzZVN0YXRlKSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgIGltcG9ydHMucHVzaCh7IG1vZHVsZSwgbmFtZSwga2luZDogImdsb2JhbCIsIHR5cGU6IHBhcnNlR2xvYmFsVHlwZShwYXJzZVN0YXRlKSB9KTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gaW1wb3J0IGRlc2NyaXB0b3IgdHlwZSAke3R5cGV9YCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHJldHVybiBpbXBvcnRzOwogICAgICB9CiAgICAgIGRlZmF1bHQ6IHsKICAgICAgICBwYXJzZVN0YXRlLnNraXBCeXRlcyhzZWN0aW9uU2l6ZSk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICB9CiAgcmV0dXJuIFtdOwp9CnZhciBQYXJzZVN0YXRlID0gY2xhc3MgewogIGNvbnN0cnVjdG9yKG1vZHVsZUJ5dGVzKSB7CiAgICB0aGlzLm1vZHVsZUJ5dGVzID0gbW9kdWxlQnl0ZXM7CiAgICB0aGlzLm9mZnNldCA9IDA7CiAgICB0aGlzLnRleHREZWNvZGVyID0gbmV3IFRleHREZWNvZGVyKCJ1dGYtOCIpOwogIH0KICBoYXNNb3JlQnl0ZXMoKSB7CiAgICByZXR1cm4gdGhpcy5vZmZzZXQgPCB0aGlzLm1vZHVsZUJ5dGVzLmxlbmd0aDsKICB9CiAgcmVhZEJ5dGUoKSB7CiAgICByZXR1cm4gdGhpcy5tb2R1bGVCeXRlc1t0aGlzLm9mZnNldCsrXTsKICB9CiAgc2tpcEJ5dGVzKGNvdW50KSB7CiAgICB0aGlzLm9mZnNldCArPSBjb3VudDsKICB9CiAgcmVhZFVuc2lnbmVkTEVCMTI4KCkgewogICAgbGV0IHJlc3VsdCA9IDA7CiAgICBsZXQgc2hpZnQgPSAwOwogICAgbGV0IGJ5dGU7CiAgICBkbyB7CiAgICAgIGJ5dGUgPSB0aGlzLnJlYWRCeXRlKCk7CiAgICAgIHJlc3VsdCB8PSAoYnl0ZSAmIDEyNykgPDwgc2hpZnQ7CiAgICAgIHNoaWZ0ICs9IDc7CiAgICB9IHdoaWxlIChieXRlICYgMTI4KTsKICAgIHJldHVybiByZXN1bHQ7CiAgfQogIHJlYWROYW1lKCkgewogICAgY29uc3QgbmFtZUxlbmd0aCA9IHRoaXMucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICBjb25zdCBuYW1lQnl0ZXMgPSB0aGlzLm1vZHVsZUJ5dGVzLnNsaWNlKHRoaXMub2Zmc2V0LCB0aGlzLm9mZnNldCArIG5hbWVMZW5ndGgpOwogICAgY29uc3QgbmFtZSA9IHRoaXMudGV4dERlY29kZXIuZGVjb2RlKG5hbWVCeXRlcyk7CiAgICB0aGlzLm9mZnNldCArPSBuYW1lTGVuZ3RoOwogICAgcmV0dXJuIG5hbWU7CiAgfQogIGFzc2VydEJ5dGVzKGV4cGVjdGVkKSB7CiAgICBjb25zdCBiYXNlT2Zmc2V0ID0gdGhpcy5vZmZzZXQ7CiAgICBjb25zdCBleHBlY3RlZExlbmd0aCA9IGV4cGVjdGVkLmxlbmd0aDsKICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwZWN0ZWRMZW5ndGg7IGkrKykgewogICAgICBpZiAodGhpcy5tb2R1bGVCeXRlc1tiYXNlT2Zmc2V0ICsgaV0gIT09IGV4cGVjdGVkW2ldKSB7CiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkfSBhdCBvZmZzZXQgJHtiYXNlT2Zmc2V0fWApOwogICAgICB9CiAgICB9CiAgICB0aGlzLm9mZnNldCArPSBleHBlY3RlZExlbmd0aDsKICB9Cn07CmZ1bmN0aW9uIHBhcnNlTWFnaWNOdW1iZXIocGFyc2VTdGF0ZSkgewogIGNvbnN0IGV4cGVjdGVkID0gWzAsIDk3LCAxMTUsIDEwOV07CiAgcGFyc2VTdGF0ZS5hc3NlcnRCeXRlcyhleHBlY3RlZCk7Cn0KZnVuY3Rpb24gcGFyc2VWZXJzaW9uKHBhcnNlU3RhdGUpIHsKICBjb25zdCBleHBlY3RlZCA9IFsxLCAwLCAwLCAwXTsKICBwYXJzZVN0YXRlLmFzc2VydEJ5dGVzKGV4cGVjdGVkKTsKfQpmdW5jdGlvbiBwYXJzZVRhYmxlVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgZWxlbWVudFR5cGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgbGV0IGVsZW1lbnQ7CiAgc3dpdGNoIChlbGVtZW50VHlwZSkgewogICAgY2FzZSAxMTI6CiAgICAgIGVsZW1lbnQgPSAiZnVuY3JlZiI7CiAgICAgIGJyZWFrOwogICAgY2FzZSAxMTE6CiAgICAgIGVsZW1lbnQgPSAiZXh0ZXJucmVmIjsKICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gdGFibGUgZWxlbWVudCB0eXBlICR7ZWxlbWVudFR5cGV9YCk7CiAgfQogIGNvbnN0IHsgbWluaW11bSwgbWF4aW11bSB9ID0gcGFyc2VMaW1pdHMocGFyc2VTdGF0ZSk7CiAgaWYgKG1heGltdW0pIHsKICAgIHJldHVybiB7IGVsZW1lbnQsIG1pbmltdW0sIG1heGltdW0gfTsKICB9IGVsc2UgewogICAgcmV0dXJuIHsgZWxlbWVudCwgbWluaW11bSB9OwogIH0KfQpmdW5jdGlvbiBwYXJzZUxpbWl0cyhwYXJzZVN0YXRlKSB7CiAgY29uc3QgZmxhZ3MgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgY29uc3QgbWluaW11bSA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgY29uc3QgaGFzTWF4aW11bSA9IGZsYWdzICYgMTsKICBjb25zdCBzaGFyZWQgPSAoZmxhZ3MgJiAyKSAhPT0gMDsKICBjb25zdCBpc01lbW9yeTY0ID0gKGZsYWdzICYgNCkgIT09IDA7CiAgY29uc3QgaW5kZXggPSBpc01lbW9yeTY0ID8gImk2NCIgOiAiaTMyIjsKICBpZiAoaGFzTWF4aW11bSkgewogICAgY29uc3QgbWF4aW11bSA9IHBhcnNlU3RhdGUucmVhZFVuc2lnbmVkTEVCMTI4KCk7CiAgICByZXR1cm4geyBtaW5pbXVtLCBzaGFyZWQsIGluZGV4LCBtYXhpbXVtIH07CiAgfSBlbHNlIHsKICAgIHJldHVybiB7IG1pbmltdW0sIHNoYXJlZCwgaW5kZXggfTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VHbG9iYWxUeXBlKHBhcnNlU3RhdGUpIHsKICBjb25zdCB2YWx1ZSA9IHBhcnNlVmFsdWVUeXBlKHBhcnNlU3RhdGUpOwogIGNvbnN0IG11dGFibGUgPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCkgPT09IDE7CiAgcmV0dXJuIHsgdmFsdWUsIG11dGFibGUgfTsKfQpmdW5jdGlvbiBwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSB7CiAgY29uc3QgdHlwZSA9IHBhcnNlU3RhdGUucmVhZEJ5dGUoKTsKICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgMTI3OgogICAgICByZXR1cm4gImkzMiI7CiAgICBjYXNlIDEyNjoKICAgICAgcmV0dXJuICJpNjQiOwogICAgY2FzZSAxMjU6CiAgICAgIHJldHVybiAiZjMyIjsKICAgIGNhc2UgMTI0OgogICAgICByZXR1cm4gImY2NCI7CiAgICBjYXNlIDExMjoKICAgICAgcmV0dXJuICJmdW5jcmVmIjsKICAgIGNhc2UgMTExOgogICAgICByZXR1cm4gImV4dGVybnJlZiI7CiAgICBjYXNlIDEyMzoKICAgICAgcmV0dXJuICJ2MTI4IjsKICAgIGRlZmF1bHQ6CiAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biB2YWx1ZSB0eXBlICR7dHlwZX1gKTsKICB9Cn0KZnVuY3Rpb24gcGFyc2VGdW5jdGlvblR5cGUocGFyc2VTdGF0ZSkgewogIGNvbnN0IGZvcm0gPSBwYXJzZVN0YXRlLnJlYWRCeXRlKCk7CiAgaWYgKGZvcm0gIT09IDk2KSB7CiAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIGZ1bmN0aW9uIHR5cGUgZm9ybSAweDYwLCBnb3QgJHtmb3JtfWApOwogIH0KICBjb25zdCBwYXJhbWV0ZXJzID0gW107CiAgY29uc3QgcGFyYW1ldGVyQ291bnQgPSBwYXJzZVN0YXRlLnJlYWRVbnNpZ25lZExFQjEyOCgpOwogIGZvciAobGV0IGkgPSAwOyBpIDwgcGFyYW1ldGVyQ291bnQ7IGkrKykgewogICAgcGFyYW1ldGVycy5wdXNoKHBhcnNlVmFsdWVUeXBlKHBhcnNlU3RhdGUpKTsKICB9CiAgY29uc3QgcmVzdWx0cyA9IFtdOwogIGNvbnN0IHJlc3VsdENvdW50ID0gcGFyc2VTdGF0ZS5yZWFkVW5zaWduZWRMRUIxMjgoKTsKICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdENvdW50OyBpKyspIHsKICAgIHJlc3VsdHMucHVzaChwYXJzZVZhbHVlVHlwZShwYXJzZVN0YXRlKSk7CiAgfQogIHJldHVybiB7IHBhcmFtZXRlcnMsIHJlc3VsdHMgfTsKfQoKLy8gbm9kZV9tb2R1bGVzL3dhc20taW1wb3J0cy1wYXJzZXIvcG9seWZpbGwuanMKdmFyIGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQgPSAoKCkgPT4gewogIGNvbnN0IG1vZHVsZUJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoWwogICAgMCwKICAgIDk3LAogICAgMTE1LAogICAgMTA5LAogICAgMSwKICAgIDAsCiAgICAwLAogICAgMCwKICAgIDIsCiAgICA2LAogICAgMSwKICAgIDAsCiAgICAwLAogICAgMiwKICAgIDAsCiAgICAxCiAgXSk7CiAgY29uc3QgbW9kdWxlID0gbmV3IFdlYkFzc2VtYmx5Lk1vZHVsZShtb2R1bGVCeXRlcyk7CiAgY29uc3QgaW1wb3J0cyA9IFdlYkFzc2VtYmx5Lk1vZHVsZS5pbXBvcnRzKG1vZHVsZSk7CiAgY29uc3QgbWVtb3J5SW1wb3J0ID0gaW1wb3J0c1swXTsKICByZXR1cm4gdHlwZW9mIG1lbW9yeUltcG9ydC50eXBlID09PSAib2JqZWN0IjsKfSkoKTsKZnVuY3Rpb24gcG9seWZpbGwoV2ViQXNzZW1ibHkzKSB7CiAgaWYgKGhhc1dhc21UeXBlUmVmbGVjdGlvblN1cHBvcnQpIHsKICAgIHJldHVybiBXZWJBc3NlbWJseTM7CiAgfQogIGNvbnN0IG5ld1dlYkFzc2VtYmx5ID0ge307CiAgZm9yIChjb25zdCBrZXkgaW4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcnMoV2ViQXNzZW1ibHkzKSkgewogICAgbmV3V2ViQXNzZW1ibHlba2V5XSA9IFdlYkFzc2VtYmx5M1trZXldOwogIH0KICBjb25zdCBwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbCA9IFN5bWJvbCgicG9seWZpbGxlZEltcG9ydHNTeW1ib2wiKTsKICBjb25zdCBhc3NpZ25JbXBvcnRzID0gKG1vZHVsZSwgc291cmNlQnl0ZXMpID0+IHsKICAgIG1vZHVsZVtwb2x5ZmlsbGVkSW1wb3J0c1N5bWJvbF0gPSBwYXJzZUltcG9ydHMoc291cmNlQnl0ZXMpOwogIH07CiAgY29uc3QgbmV3TW9kdWxlID0gbmV3V2ViQXNzZW1ibHkuTW9kdWxlID0gZnVuY3Rpb24oYnl0ZXMpIHsKICAgIGNvbnN0IG1vZHVsZSA9IG5ldyBXZWJBc3NlbWJseTMuTW9kdWxlKGJ5dGVzKTsKICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBieXRlcyk7CiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YobW9kdWxlLCBuZXdNb2R1bGUucHJvdG90eXBlKTsKICAgIHJldHVybiBtb2R1bGU7CiAgfTsKICBPYmplY3Quc2V0UHJvdG90eXBlT2YobmV3TW9kdWxlLnByb3RvdHlwZSwgV2ViQXNzZW1ibHkzLk1vZHVsZS5wcm90b3R5cGUpOwogIG5ld1dlYkFzc2VtYmx5LmNvbXBpbGUgPSBhc3luYyAoc291cmNlKSA9PiB7CiAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseTMuY29tcGlsZShzb3VyY2UpOwogICAgYXNzaWduSW1wb3J0cyhtb2R1bGUsIHNvdXJjZSk7CiAgICByZXR1cm4gbW9kdWxlOwogIH07CiAgaWYgKFdlYkFzc2VtYmx5My5jb21waWxlU3RyZWFtaW5nKSB7CiAgICBuZXdXZWJBc3NlbWJseS5jb21waWxlU3RyZWFtaW5nID0gYXN5bmMgKHNvdXJjZSkgPT4gewogICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHNvdXJjZTsKICAgICAgY29uc3QgY2xvbmUgPSByZXNwb25zZS5jbG9uZSgpOwogICAgICBjb25zdCBtb2R1bGUgPSBhd2FpdCBXZWJBc3NlbWJseTMuY29tcGlsZVN0cmVhbWluZyhyZXNwb25zZSk7CiAgICAgIGFzc2lnbkltcG9ydHMobW9kdWxlLCBuZXcgVWludDhBcnJheShhd2FpdCBjbG9uZS5hcnJheUJ1ZmZlcigpKSk7CiAgICAgIHJldHVybiBtb2R1bGU7CiAgICB9OwogIH0KICBuZXdNb2R1bGUuaW1wb3J0cyA9IChtb2R1bGUpID0+IHsKICAgIGNvbnN0IHBhcnNlZEltcG9ydHMgPSBtb2R1bGVbcG9seWZpbGxlZEltcG9ydHNTeW1ib2xdOwogICAgaWYgKCFwYXJzZWRJbXBvcnRzKSB7CiAgICAgIHJldHVybiBXZWJBc3NlbWJseTMuTW9kdWxlLmltcG9ydHMobW9kdWxlKTsKICAgIH0KICAgIHJldHVybiBwYXJzZWRJbXBvcnRzOwogIH07CiAgcmV0dXJuIG5ld1dlYkFzc2VtYmx5Owp9CgovLyBlbnRyeXBvaW50L2ludHJpbnNpY3MudHMKdmFyIFdlYkFzc2VtYmx5MiA9IHBvbHlmaWxsKGdsb2JhbFRoaXMuV2ViQXNzZW1ibHkpOwp2YXIgTGluZURlY29kZXIgPSBjbGFzcyB7CiAgY29uc3RydWN0b3Iob25MaW5lKSB7CiAgICB0aGlzLmRlY29kZXIgPSBuZXcgVGV4dERlY29kZXIoInV0Zi04IiwgeyBmYXRhbDogZmFsc2UgfSk7CiAgICB0aGlzLmJ1ZmZlciA9ICIiOwogICAgdGhpcy5vbkxpbmUgPSBvbkxpbmU7CiAgfQogIGRlY29kZXI7CiAgYnVmZmVyOwogIG9uTGluZTsKICBzZW5kKGNodW5rKSB7CiAgICB0aGlzLmJ1ZmZlciArPSB0aGlzLmRlY29kZXIuZGVjb2RlKGNodW5rLCB7IHN0cmVhbTogdHJ1ZSB9KTsKICAgIGNvbnN0IGxpbmVzID0gdGhpcy5idWZmZXIuc3BsaXQoIlxuIik7CiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aCAtIDE7IGkrKykgewogICAgICB0aGlzLm9uTGluZShsaW5lc1tpXSk7CiAgICB9CiAgICB0aGlzLmJ1ZmZlciA9IGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdOwogIH0KfTsKYXN5bmMgZnVuY3Rpb24gaW5zdGFudGlhdGUocmF3T3B0aW9ucywgZXh0cmFXYXNtSW1wb3J0cykgewogIGNvbnN0IG9wdGlvbnMgPSBkZWZhdWx0SW5zdGFudGlhdGlvbk9wdGlvbnMocmF3T3B0aW9ucyk7CiAgbGV0IHN3aWZ0ID0gb3B0aW9ucy5zd2lmdDsKICBpZiAoIXN3aWZ0ICYmIG9wdGlvbnMuU3dpZnRSdW50aW1lKSB7CiAgICBzd2lmdCA9IG5ldyBvcHRpb25zLlN3aWZ0UnVudGltZSgpOwogIH0KICBsZXQgc3Rkb3V0TGluZSA9IHZvaWQgMDsKICBpZiAob3B0aW9ucy5vblN0ZG91dExpbmUgIT0gbnVsbCkgewogICAgc3Rkb3V0TGluZSA9IG5ldyBMaW5lRGVjb2RlcihvcHRpb25zLm9uU3Rkb3V0TGluZSk7CiAgfQogIGNvbnN0IHN0ZG91dCA9IG5ldyBDb25zb2xlU3Rkb3V0KChjaHVuaykgPT4gewogICAgb3B0aW9ucy5vblN0ZG91dD8uY2FsbCh2b2lkIDAsIGNodW5rKTsKICAgIHN0ZG91dExpbmU/LnNlbmQoY2h1bmspOwogIH0pOwogIGxldCBzdGRlcnJMaW5lID0gdm9pZCAwOwogIGlmIChvcHRpb25zLm9uU3RkZXJyTGluZSAhPSBudWxsKSB7CiAgICBzdGRlcnJMaW5lID0gbmV3IExpbmVEZWNvZGVyKG9wdGlvbnMub25TdGRlcnJMaW5lKTsKICB9CiAgY29uc3Qgc3RkZXJyID0gbmV3IENvbnNvbGVTdGRvdXQoKGNodW5rKSA9PiB7CiAgICBvcHRpb25zLm9uU3RkZXJyPy5jYWxsKHZvaWQgMCwgY2h1bmspOwogICAgc3RkZXJyTGluZT8uc2VuZChjaHVuayk7CiAgfSk7CiAgY29uc3QgYXJncyA9IG9wdGlvbnMuYXJncyB8fCBbXTsKICBjb25zdCBmZHMgPSBbCiAgICBuZXcgT3BlbkZpbGUobmV3IEZpbGUoW10pKSwKICAgIHN0ZG91dCwKICAgIHN0ZGVyciwKICAgIG5ldyBQcmVvcGVuRGlyZWN0b3J5KCIvIiwgLyogQF9fUFVSRV9fICovIG5ldyBNYXAoKSkKICBdOwogIGNvbnN0IGVudnMgPSBvcHRpb25zLmVudiA/IE9iamVjdC5lbnRyaWVzKG9wdGlvbnMuZW52KS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gYCR7a2V5fT0ke3ZhbHVlfWApIDogW107CiAgY29uc3Qgd2FzaSA9IG5ldyBXQVNJKGFyZ3MsIGVudnMsIGZkcywgewogICAgZGVidWc6IGZhbHNlCiAgfSk7CiAgY29uc3QgY3JlYXRlV2FzbUltcG9ydE9iamVjdCA9IChleHRyYVdhc21JbXBvcnRzMiwgbW9kdWxlKSA9PiB7CiAgICBjb25zdCBpbXBvcnRPYmplY3QyID0gewogICAgICB3YXNpX3NuYXBzaG90X3ByZXZpZXcxOiB3YXNpLndhc2lJbXBvcnQKICAgIH07CiAgICBpZiAoc3dpZnQpIHsKICAgICAgaW1wb3J0T2JqZWN0Mi5qYXZhc2NyaXB0X2tpdCA9IHN3aWZ0Lndhc21JbXBvcnRzOwogICAgfQogICAgaWYgKGV4dHJhV2FzbUltcG9ydHMyKSB7CiAgICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBpbiBleHRyYVdhc21JbXBvcnRzMikgewogICAgICAgIGlmICghaW1wb3J0T2JqZWN0Mlttb2R1bGVOYW1lXSkgewogICAgICAgICAgaW1wb3J0T2JqZWN0Mlttb2R1bGVOYW1lXSA9IHt9OwogICAgICAgIH0KICAgICAgICBmb3IgKGNvbnN0IGVudHJ5IGluIGV4dHJhV2FzbUltcG9ydHMyW21vZHVsZU5hbWVdKSB7CiAgICAgICAgICBpbXBvcnRPYmplY3QyW21vZHVsZU5hbWVdW2VudHJ5XSA9IGV4dHJhV2FzbUltcG9ydHMyW21vZHVsZU5hbWVdW2VudHJ5XTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICAgIGZvciAoY29uc3QgX2ltcG9ydEVudHJ5IG9mIFdlYkFzc2VtYmx5Mi5Nb2R1bGUuaW1wb3J0cyhtb2R1bGUpKSB7CiAgICAgIGNvbnN0IGltcG9ydEVudHJ5ID0gX2ltcG9ydEVudHJ5OwogICAgICBpZiAoIWltcG9ydE9iamVjdDJbaW1wb3J0RW50cnkubW9kdWxlXSkgewogICAgICAgIGltcG9ydE9iamVjdDJbaW1wb3J0RW50cnkubW9kdWxlXSA9IHt9OwogICAgICB9CiAgICAgIGlmIChpbXBvcnRPYmplY3QyW2ltcG9ydEVudHJ5Lm1vZHVsZV1baW1wb3J0RW50cnkubmFtZV0pIHsKICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICBpZiAoaW1wb3J0RW50cnkua2luZCA9PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW1wb3J0T2JqZWN0MltpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gKCkgPT4gewogICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbXBvcnRlZCBmdW5jdGlvbiAke2ltcG9ydEVudHJ5Lm1vZHVsZX0uJHtpbXBvcnRFbnRyeS5uYW1lfSBub3QgaW1wbGVtZW50ZWRgKTsKICAgICAgICB9OwogICAgICB9IGVsc2UgaWYgKGltcG9ydEVudHJ5LmtpbmQgPT0gIm1lbW9yeSIgJiYgaW1wb3J0RW50cnkubW9kdWxlID09ICJlbnYiICYmIGltcG9ydEVudHJ5Lm5hbWUgPT0gIm1lbW9yeSIpIHsKICAgICAgICBjb25zdCB0eXBlID0gaW1wb3J0RW50cnkudHlwZTsKICAgICAgICBjb25zdCBkZXNjcmlwdG9yID0gewogICAgICAgICAgaW5pdGlhbDogdHlwZS5taW5pbXVtLAogICAgICAgICAgbWF4aW11bTogdHlwZS5tYXhpbXVtLAogICAgICAgICAgc2hhcmVkOiB0eXBlLnNoYXJlZAogICAgICAgIH07CiAgICAgICAgaW1wb3J0T2JqZWN0MltpbXBvcnRFbnRyeS5tb2R1bGVdW2ltcG9ydEVudHJ5Lm5hbWVdID0gbmV3IFdlYkFzc2VtYmx5Mi5NZW1vcnkoZGVzY3JpcHRvcik7CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBpbXBvcnRPYmplY3QyOwogIH07CiAgY29uc3QgaW1wb3J0T2JqZWN0ID0gY3JlYXRlV2FzbUltcG9ydE9iamVjdChleHRyYVdhc21JbXBvcnRzLCBvcHRpb25zLm1vZHVsZSk7CiAgY29uc3QgaW5zdGFuY2UgPSBhd2FpdCBXZWJBc3NlbWJseTIuaW5zdGFudGlhdGUob3B0aW9ucy5tb2R1bGUsIGltcG9ydE9iamVjdCk7CiAgaWYgKHN3aWZ0ICYmIGluc3RhbmNlLmV4cG9ydHMuc3dqc19saWJyYXJ5X3ZlcnNpb24pIHsKICAgIHN3aWZ0LnNldEluc3RhbmNlKGluc3RhbmNlKTsKICB9CiAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLl9zdGFydCA9PT0gImZ1bmN0aW9uIikgewogICAgd2FzaS5zdGFydChpbnN0YW5jZSk7CiAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5faW5pdGlhbGl6ZSA9PSAiZnVuY3Rpb24iKSB7CiAgICB3YXNpLmluaXRpYWxpemUoaW5zdGFuY2UpOwogICAgaWYgKHN3aWZ0ICYmIHN3aWZ0Lm1haW4pIHsKICAgICAgc3dpZnQubWFpbigpOwogICAgfSBlbHNlIHsKICAgICAgaWYgKHR5cGVvZiBpbnN0YW5jZS5leHBvcnRzLm1haW4gPT09ICJmdW5jdGlvbiIpIHsKICAgICAgICBpbnN0YW5jZS5leHBvcnRzLm1haW4oKTsKICAgICAgfSBlbHNlIGlmICh0eXBlb2YgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2ID09PSAiZnVuY3Rpb24iKSB7CiAgICAgICAgaW5zdGFuY2UuZXhwb3J0cy5fX21haW5fYXJnY19hcmd2KDAsIDApOwogICAgICB9CiAgICB9CiAgfQogIHJldHVybiB7IGluc3RhbmNlIH07Cn0KZnVuY3Rpb24gZGVmYXVsdEluc3RhbnRpYXRpb25PcHRpb25zKG9wdGlvbnMpIHsKICBpZiAob3B0aW9ucy5hcmdzID09IG51bGwpIHsKICAgIG9wdGlvbnMuYXJncyA9IFsibWFpbi53YXNtIl07CiAgfQogIGNvbnN0IGlzTm9kZUpzID0gdHlwZW9mIHByb2Nlc3MgIT09ICJ1bmRlZmluZWQiICYmIHByb2Nlc3MucmVsZWFzZS5uYW1lID09PSAibm9kZSI7CiAgY29uc3QgaXNXZWJCcm93c2VyID0gdHlwZW9mIHdpbmRvdyAhPT0gInVuZGVmaW5lZCI7CiAgaWYgKGlzTm9kZUpzKSB7CiAgICBpZiAoIW9wdGlvbnMub25TdGRvdXQpIHsKICAgICAgb3B0aW9ucy5vblN0ZG91dCA9IChjaHVuaykgPT4gcHJvY2Vzcy5zdGRvdXQud3JpdGUoY2h1bmspOwogICAgfQogICAgaWYgKCFvcHRpb25zLm9uU3RkZXJyKSB7CiAgICAgIG9wdGlvbnMub25TdGRlcnIgPSAoY2h1bmspID0+IHByb2Nlc3Muc3RkZXJyLndyaXRlKGNodW5rKTsKICAgIH0KICB9IGVsc2UgaWYgKGlzV2ViQnJvd3NlcikgewogICAgaWYgKCFvcHRpb25zLm9uU3Rkb3V0TGluZSkgewogICAgICBvcHRpb25zLm9uU3Rkb3V0TGluZSA9IChsaW5lKSA9PiBjb25zb2xlLmxvZyhsaW5lKTsKICAgIH0KICAgIGlmICghb3B0aW9ucy5vblN0ZGVyckxpbmUpIHsKICAgICAgb3B0aW9ucy5vblN0ZGVyckxpbmUgPSAobGluZSkgPT4gY29uc29sZS53YXJuKGxpbmUpOwogICAgfQogIH0KICByZXR1cm4gb3B0aW9uczsKfQpleHBvcnQgewogIGluc3RhbnRpYXRlCn07Cg==")! } \ No newline at end of file diff --git a/Sources/carton-frontend-slim/CartonFrontendBundleCommand.swift b/Sources/carton-frontend-slim/CartonFrontendBundleCommand.swift index 2d9d2983..ba5066e7 100644 --- a/Sources/carton-frontend-slim/CartonFrontendBundleCommand.swift +++ b/Sources/carton-frontend-slim/CartonFrontendBundleCommand.swift @@ -134,7 +134,8 @@ struct CartonFrontendBundleCommand: AsyncParsableCommand { topLevelResourcePaths: resources ) - terminal.write("Bundle successfully generated at \(bundleDirectory)\n", inColor: .green, bold: true) + terminal.write( + "Bundle successfully generated at \(bundleDirectory)\n", inColor: .green, bold: true) } func optimize(_ inputPath: AbsolutePath, outputPath: AbsolutePath, terminal: InteractiveWriter) @@ -171,7 +172,10 @@ struct CartonFrontendBundleCommand: AsyncParsableCommand { ) throws { // Rename the final binary to use a part of its hash to bust browsers and CDN caches. let wasmFileHash = try localFileSystem.readFileContents(wasmOutputFilePath).hexChecksum - let mainModuleName = contentHash ? "\(wasmFileHash).wasm" : URL(fileURLWithPath: mainWasmPath).lastPathComponent + let mainModuleBaseName = URL(fileURLWithPath: mainWasmPath).deletingPathExtension() + .lastPathComponent + let mainModuleName = + contentHash ? "\(mainModuleBaseName).\(wasmFileHash).wasm" : "\(mainModuleBaseName).wasm" let mainModulePath = try AbsolutePath(validating: mainModuleName, relativeTo: bundleDirectory) try localFileSystem.move(from: wasmOutputFilePath, to: mainModulePath) @@ -183,7 +187,7 @@ struct CartonFrontendBundleCommand: AsyncParsableCommand { with: mainModuleName ) ) - let entrypointName = contentHash ? "\(entrypoint.hexChecksum).js" : "index.js" + let entrypointName = contentHash ? "app.\(entrypoint.hexChecksum).js" : "app.js" try localFileSystem.writeFileContents( AbsolutePath(validating: entrypointName, relativeTo: bundleDirectory), bytes: entrypoint @@ -198,7 +202,37 @@ struct CartonFrontendBundleCommand: AsyncParsableCommand { )) ) - for directoryName in try localFileSystem.resourcesDirectoryNames(relativeTo: buildDirectory) { + try localFileSystem.writeFileContents( + AbsolutePath(validating: "intrinsics.js", relativeTo: bundleDirectory), + bytes: ByteString(StaticResource.intrinsics) + ) + + let resourcesDirectoryNames = try localFileSystem.resourcesDirectoryNames( + relativeTo: buildDirectory) + let hasJavaScriptKitResources = resourcesDirectoryNames.contains( + "JavaScriptKit_JavaScriptKit.resources") + + try localFileSystem.writeFileContents( + AbsolutePath(validating: "index.js", relativeTo: bundleDirectory), + bytes: ByteString( + encodingAsUTF8: indexJsContent( + mainModuleName: mainModuleName, hasJavaScriptKitResources: hasJavaScriptKitResources) + ) + ) + + try localFileSystem.writeFileContents( + AbsolutePath(validating: "package.json", relativeTo: bundleDirectory), + bytes: ByteString( + encodingAsUTF8: """ + { + "type": "module", + "main": "./index.js" + } + """ + ) + ) + + for directoryName in resourcesDirectoryNames { let resourcesPath = buildDirectory.appending(component: directoryName) let targetDirectory = bundleDirectory.appending(component: directoryName) @@ -212,7 +246,8 @@ struct CartonFrontendBundleCommand: AsyncParsableCommand { validating: resourcesPath, relativeTo: localFileSystem.currentWorkingDirectory!) for file in try localFileSystem.traverseRecursively(resourcesPath) { let targetPath = bundleDirectory.appending(component: file.basename) - let sourcePath = bundleDirectory.appending(component: resourcesPath.basename).appending(component: file.basename) + let sourcePath = bundleDirectory.appending(component: resourcesPath.basename).appending( + component: file.basename) guard localFileSystem.exists(sourcePath, followSymlink: true), !localFileSystem.exists(targetPath, followSymlink: true) @@ -223,6 +258,58 @@ struct CartonFrontendBundleCommand: AsyncParsableCommand { } } } + + private func indexJsContent(mainModuleName: String, hasJavaScriptKitResources: Bool) -> String { + var content = """ + import { instantiate as internalInstantiate } from './intrinsics.js'; + + """ + if hasJavaScriptKitResources { + content += """ + import { SwiftRuntime } from './JavaScriptKit_JavaScriptKit.resources/Runtime/index.mjs'; + + """ + } + content += """ + export const wasmFileName = '\(mainModuleName)'; + + export async function instantiate(options, imports) { + if (!options) { + options = {}; + } + const isNodeJs = (typeof process !== 'undefined') && (process.release.name === 'node'); + const isWebBrowser = (typeof window !== 'undefined'); + + if (!options.module) { + if (isNodeJs) { + const module = await import(/* webpackIgnore: true */'node:module'); + const importMeta = import.meta; + const require = module.default.createRequire(importMeta.url); + const fs = require('fs/promises'); + const url = require('url'); + const filePath = import.meta.resolve('./' + wasmFileName); + options.module = await WebAssembly.compile(await fs.readFile(url.fileURLToPath(filePath))); + } else if (isWebBrowser) { + options.module = await WebAssembly.compileStreaming(fetch(wasmFileName)); + } else { + throw new Error('Unsupported environment to automatically load the WebAssembly module. Please provide the \"module\" option with the compiled WebAssembly module manually.'); + } + } + + """ + if hasJavaScriptKitResources { + content += """ + options.SwiftRuntime = SwiftRuntime; + + """ + } + content += """ + return internalInstantiate(options, imports); + } + """ + + return content + } } extension ByteString { diff --git a/Sources/carton-release/HashArchive.swift b/Sources/carton-release/HashArchive.swift index bd27a895..8d5d88ef 100644 --- a/Sources/carton-release/HashArchive.swift +++ b/Sources/carton-release/HashArchive.swift @@ -39,13 +39,13 @@ struct HashArchive: AsyncParsableCommand { let staticPath = try AbsolutePath(validating: "static", relativeTo: cwd) var fileContent = """ - import Foundation + import Foundation - public enum StaticResource { + public enum StaticResource { - """ + """ - for entrypoint in ["dev", "bundle", "test", "testNode"] { + for entrypoint in ["dev", "bundle", "test", "testNode", "intrinsics"] { let tsFilename = "\(entrypoint).ts" let filename = "\(entrypoint).js" var arguments = [ @@ -75,15 +75,15 @@ struct HashArchive: AsyncParsableCommand { $0.base64EncodedString() } fileContent += """ - public static let \(entrypoint): Data = Data(base64Encoded: \"\(base64Content)\")! + public static let \(entrypoint): Data = Data(base64Encoded: \"\(base64Content)\")! - """ + """ } fileContent += """ - } - """ + } + """ try localFileSystem.writeFileContents( AbsolutePath( diff --git a/entrypoint/bundle.ts b/entrypoint/bundle.ts index 676bb441..9f2930f6 100644 --- a/entrypoint/bundle.ts +++ b/entrypoint/bundle.ts @@ -12,13 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { WasmRunner } from "./common.js"; +import { instantiate } from "./intrinsics.js"; import type { SwiftRuntimeConstructor } from "./JavaScriptKit_JavaScriptKit.resources/Runtime"; const startWasiTask = async () => { // Fetch our Wasm File const response = await fetch("REPLACE_THIS_WITH_THE_MAIN_WEBASSEMBLY_MODULE"); - const responseArrayBuffer = await response.arrayBuffer(); let runtimeConstructor: SwiftRuntimeConstructor | undefined = undefined; try { @@ -31,22 +30,21 @@ const startWasiTask = async () => { // JavaScriptKit module not available, running without JavaScriptKit runtime. } - const wasmRunner = WasmRunner({ + // Instantiate the WebAssembly file + await instantiate({ + module: await WebAssembly.compileStreaming(response), onStdoutLine(line) { console.log(line); }, onStderrLine(line) { console.error(line); - } - }, runtimeConstructor); - - // Instantiate the WebAssembly file - const wasmBytes = new Uint8Array(responseArrayBuffer).buffer; - await wasmRunner.run(wasmBytes); + }, + SwiftRuntime: runtimeConstructor, + }); }; async function main(): Promise { await startWasiTask(); } -main(); \ No newline at end of file +main(); diff --git a/entrypoint/dev.ts b/entrypoint/dev.ts index 083bb69d..9e503c79 100644 --- a/entrypoint/dev.ts +++ b/entrypoint/dev.ts @@ -13,7 +13,7 @@ // limitations under the License. import ReconnectingWebSocket from "reconnecting-websocket"; -import { WasmRunner } from "./common"; +import { instantiate } from "./intrinsics"; import type { SwiftRuntimeConstructor } from "./JavaScriptKit_JavaScriptKit.resources/Runtime"; const socket = new ReconnectingWebSocket(`ws://${location.host}/watcher`); @@ -27,7 +27,6 @@ socket.addEventListener("message", (message) => { const startWasiTask = async () => { // Fetch our Wasm File const response = await fetch("/main.wasm"); - const responseArrayBuffer = await response.arrayBuffer(); let runtimeConstructor: SwiftRuntimeConstructor | undefined = undefined; try { @@ -42,8 +41,10 @@ const startWasiTask = async () => { ); } - const wasmRunner = WasmRunner( + // Instantiate the WebAssembly file + await instantiate( { + module: await WebAssembly.compileStreaming(response), onStdout(chunk) { const kindBuffer = new ArrayBuffer(2); new DataView(kindBuffer).setUint16(0, 1001, true); @@ -69,14 +70,10 @@ const startWasiTask = async () => { }, onStderrLine(line) { console.error(line); - } - }, - runtimeConstructor + }, + SwiftRuntime: runtimeConstructor, + } ); - - // Instantiate the WebAssembly file - const wasmBytes = new Uint8Array(responseArrayBuffer).buffer; - await wasmRunner.run(wasmBytes); }; function handleError(e: any) { @@ -108,4 +105,4 @@ async function main(): Promise { } } -main(); \ No newline at end of file +main(); diff --git a/entrypoint/common.ts b/entrypoint/intrinsics.ts similarity index 67% rename from entrypoint/common.ts rename to entrypoint/intrinsics.ts index 4e2afe9d..db5e4547 100644 --- a/entrypoint/common.ts +++ b/entrypoint/intrinsics.ts @@ -21,7 +21,7 @@ import type { ImportEntry } from "wasm-imports-parser"; // https://github.com/WebAssembly/js-types/blob/main/proposals/js-types/Overview.md const WebAssembly = polyfillWebAssemblyTypeReflection(globalThis.WebAssembly); -export class LineDecoder { +class LineDecoder { constructor(onLine: (line: string) => void) { this.decoder = new TextDecoder("utf-8", { fatal: false }); this.buffer = ""; @@ -44,25 +44,26 @@ export class LineDecoder { } } -export type Options = { +export type InstantiationOptions = { + module: WebAssembly.Module; args?: string[]; env?: Record; onStdout?: (chunk: Uint8Array) => void; onStdoutLine?: (line: string) => void; onStderr?: (chunk: Uint8Array) => void; onStderrLine?: (line: string) => void; + swift?: SwiftRuntime; + SwiftRuntime?: SwiftRuntimeConstructor; }; -export type WasmRunner = { - run(wasmBytes: ArrayBufferLike, extraWasmImports?: WebAssembly.Imports): Promise -}; - -export const WasmRunner = (rawOptions: Options, SwiftRuntime: SwiftRuntimeConstructor | undefined): WasmRunner => { - const options: Options = defaultRunnerOptions(rawOptions); +export async function instantiate(rawOptions: InstantiationOptions, extraWasmImports?: WebAssembly.Imports): Promise<{ + instance: WebAssembly.Instance; +}> { + const options: InstantiationOptions = defaultInstantiationOptions(rawOptions); - let swift: SwiftRuntime; - if (SwiftRuntime) { - swift = new SwiftRuntime(); + let swift: SwiftRuntime | undefined = options.swift; + if (!swift && options.SwiftRuntime) { + swift = new options.SwiftRuntime(); } let stdoutLine: LineDecoder | undefined = undefined; @@ -99,7 +100,7 @@ export const WasmRunner = (rawOptions: Options, SwiftRuntime: SwiftRuntimeConstr }); const createWasmImportObject = ( - extraWasmImports: WebAssembly.Imports, + extraWasmImports: WebAssembly.Imports | undefined, module: WebAssembly.Module, ): WebAssembly.Imports => { const importObject: WebAssembly.Imports = { @@ -149,50 +150,56 @@ export const WasmRunner = (rawOptions: Options, SwiftRuntime: SwiftRuntimeConstr return importObject; }; - return { - async run(wasmBytes: ArrayBufferLike, extraWasmImports?: WebAssembly.Imports) { - if (!extraWasmImports) { - extraWasmImports = {}; - } - extraWasmImports.__stack_sanitizer = { - report_stack_overflow: () => { - throw new Error("Detected stack buffer overflow."); - }, - }; - const module = await WebAssembly.compile(wasmBytes); - const importObject = createWasmImportObject(extraWasmImports, module); - const instance = await WebAssembly.instantiate(module, importObject); - - if (swift && instance.exports.swjs_library_version) { - swift.setInstance(instance); - } + const importObject = createWasmImportObject(extraWasmImports, options.module); + const instance = await WebAssembly.instantiate(options.module, importObject); - if (typeof instance.exports._start === "function") { - // Start the WebAssembly WASI instance - wasi.start(instance as any); - } else if (typeof instance.exports._initialize == "function") { - // Initialize and start Reactor - wasi.initialize(instance as any); - if (swift && swift.main) { - // Use JavaScriptKit's entry point if it's available - swift.main(); - } else { - // For older versions of JavaScriptKit, we need to handle it manually - if (typeof instance.exports.main === "function") { - instance.exports.main(); - } else if (typeof instance.exports.__main_argc_argv === "function") { - // Swift 6.0 and later use `__main_argc_argv` instead of `main`. - instance.exports.__main_argc_argv(0, 0); - } - } + if (swift && instance.exports.swjs_library_version) { + swift.setInstance(instance); + } + + if (typeof instance.exports._start === "function") { + // Start the WebAssembly WASI instance + wasi.start(instance as any); + } else if (typeof instance.exports._initialize == "function") { + // Initialize and start Reactor + wasi.initialize(instance as any); + if (swift && swift.main) { + // Use JavaScriptKit's entry point if it's available + swift.main(); + } else { + // For older versions of JavaScriptKit, we need to handle it manually + if (typeof instance.exports.main === "function") { + instance.exports.main(); + } else if (typeof instance.exports.__main_argc_argv === "function") { + // Swift 6.0 and later use `__main_argc_argv` instead of `main`. + instance.exports.__main_argc_argv(0, 0); } - }, - }; -}; + } + } + + return { instance }; +} -const defaultRunnerOptions = (options: Options): Options => { +function defaultInstantiationOptions(options: InstantiationOptions): InstantiationOptions { if (options.args == null) { options.args = ["main.wasm"]; } + const isNodeJs = (typeof process !== 'undefined') && (process.release.name === 'node'); + const isWebBrowser = (typeof window !== 'undefined'); + if (isNodeJs) { + if (!options.onStdout) { + options.onStdout = (chunk) => process.stdout.write(chunk); + } + if (!options.onStderr) { + options.onStderr = (chunk) => process.stderr.write(chunk); + } + } else if (isWebBrowser) { + if (!options.onStdoutLine) { + options.onStdoutLine = (line) => console.log(line); + } + if (!options.onStderrLine) { + options.onStderrLine = (line) => console.warn(line); + } + } return options; -}; +} diff --git a/entrypoint/test.ts b/entrypoint/test.ts index 658898fc..a38c87fc 100644 --- a/entrypoint/test.ts +++ b/entrypoint/test.ts @@ -14,7 +14,7 @@ import ReconnectingWebSocket from "reconnecting-websocket"; import { WASIProcExit } from "@bjorn3/browser_wasi_shim"; -import { WasmRunner } from "./common.js"; +import { instantiate } from "./intrinsics.js"; import type { SwiftRuntimeConstructor } from "./JavaScriptKit_JavaScriptKit.resources/Runtime"; const socket = new ReconnectingWebSocket(`ws://${location.host}/watcher`); @@ -27,7 +27,6 @@ socket.addEventListener("message", (message) => { const startWasiTask = async () => { // Fetch our Wasm File const response = await fetch("/main.wasm"); - const responseArrayBuffer = await response.arrayBuffer(); let runtimeConstructor: SwiftRuntimeConstructor | undefined = undefined; try { @@ -46,22 +45,6 @@ const startWasiTask = async () => { const config = await fetch("/process-info.json").then((response) => response.json()); let testRunOutput = ""; - const wasmRunner = WasmRunner( - { - env: config.env, - onStdoutLine: (line) => { - console.log(line); - testRunOutput += line + "\n"; - }, - onStderrLine: (line) => { - console.error(line); - }, - }, - runtimeConstructor - ); - - // Instantiate the WebAssembly file - const wasmBytes = new Uint8Array(responseArrayBuffer).buffer; // There are 6 cases to exit test // 1. Successfully finished XCTest with `exit(0)` synchronously @@ -97,7 +80,21 @@ const startWasiTask = async () => { }); // Start the WebAssembly WASI instance try { - await wasmRunner.run(wasmBytes); + // Instantiate the WebAssembly file + await instantiate( + { + module: await WebAssembly.compileStreaming(response), + env: config.env, + onStdoutLine: (line) => { + console.log(line); + testRunOutput += line + "\n"; + }, + onStderrLine: (line) => { + console.error(line); + }, + SwiftRuntime: runtimeConstructor, + } + ); } catch (error) { // Handle synchronous exits (case 1, 2, 5) handleExitOrError(error) diff --git a/entrypoint/testNode.ts b/entrypoint/testNode.ts index 8bfe17ce..019793c8 100644 --- a/entrypoint/testNode.ts +++ b/entrypoint/testNode.ts @@ -14,7 +14,7 @@ import fs from "fs/promises"; import path from "path"; -import { WasmRunner } from "./common.js"; +import { instantiate } from "./intrinsics.js"; import type { SwiftRuntimeConstructor } from "./JavaScriptKit_JavaScriptKit.resources/Runtime"; const args = [...process.argv]; @@ -55,16 +55,6 @@ const startWasiTask = async () => { } } - const wasmRunner = WasmRunner({ - args: testArgs, - env, - onStdoutLine: (line) => { - console.log(line); - }, - onStderrLine: (line) => { - console.error(line); - }, - }, runtimeConstructor); let procExitCalled = false; process.on("beforeExit", () => { @@ -74,16 +64,30 @@ This usually means there are some dangling continuations, which are awaited but } }); - await wasmRunner.run(wasmBytes, { - "wasi_snapshot_preview1": { - // @bjorn3/browser_wasi_shim raises an exception when - // the process exits, but we just want to exit the process itself. - proc_exit: (code: number) => { - procExitCalled = true; - process.exit(code); + await instantiate( + { + module: await WebAssembly.compile(wasmBytes), + args: testArgs, + env, + onStdoutLine: (line) => { + console.log(line); + }, + onStderrLine: (line) => { + console.error(line); }, + SwiftRuntime: runtimeConstructor, + }, + { + "wasi_snapshot_preview1": { + // @bjorn3/browser_wasi_shim raises an exception when + // the process exits, but we just want to exit the process itself. + proc_exit: (code: number) => { + procExitCalled = true; + process.exit(code); + }, + } } - }); + ); }; startWasiTask().catch((e) => {