hy-virtual-tree 2.0.2 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/dist/index.js +11 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* hy-virtual-tree v2.0.
|
|
1
|
+
/* hy-virtual-tree v2.0.4 */
|
|
2
2
|
import './svg_bundle.js';
|
|
3
3
|
const isString = (e) => typeof e === 'string';
|
|
4
4
|
const isNumber = (e) => typeof e === 'number';
|
|
@@ -7989,6 +7989,7 @@ const useHandleFun = (config) => {
|
|
|
7989
7989
|
case DataType.TEAM: // 队伍
|
|
7990
7990
|
case DataType.USER: // 用户
|
|
7991
7991
|
case DataType.CS: // 采集站
|
|
7992
|
+
case DataType.PLAN_GROUP: // 预案分组
|
|
7992
7993
|
return node.id;
|
|
7993
7994
|
case DataType.DEVICE: // 设备
|
|
7994
7995
|
return node.deviceId;
|
|
@@ -8732,9 +8733,9 @@ function useFilter(config, filterMethod, tree = {
|
|
|
8732
8733
|
hiddenKeys.clear();
|
|
8733
8734
|
// 是否为过滤的根节点
|
|
8734
8735
|
const isFilterLeaf = (node) => {
|
|
8735
|
-
if (config.business && [Business.CHANNEL, Business.PLAN_GROUP_DEVICE].includes(config.business))
|
|
8736
|
+
if (config.business && ![Business.CHANNEL, Business.PLAN_GROUP_DEVICE].includes(config.business))
|
|
8736
8737
|
return node.isLeaf;
|
|
8737
|
-
return node.data.dataType ===
|
|
8738
|
+
return node.data.dataType === DataType.DEVICE || node.isLeaf;
|
|
8738
8739
|
};
|
|
8739
8740
|
function traverse(nodes, isShow = false) {
|
|
8740
8741
|
let count = 0;
|
|
@@ -8760,7 +8761,7 @@ function useFilter(config, filterMethod, tree = {
|
|
|
8760
8761
|
total += childTotal;
|
|
8761
8762
|
}
|
|
8762
8763
|
// 拥有道通的设备
|
|
8763
|
-
else if (!hiddenKeys.has(node.key) && node.data.dataType ===
|
|
8764
|
+
else if (!hiddenKeys.has(node.key) && node.data.dataType === DataType.DEVICE && !node.isLeaf) {
|
|
8764
8765
|
if (isCountFiler && countFilter) {
|
|
8765
8766
|
count += countFilter(node.data) ? 1 : 0;
|
|
8766
8767
|
}
|
|
@@ -9106,7 +9107,7 @@ function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
|
|
|
9106
9107
|
};
|
|
9107
9108
|
}
|
|
9108
9109
|
|
|
9109
|
-
var WorkerFactory = /*#__PURE__*/createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgY29uc3QgaXNTdHJpbmcgPSAoZSkgPT4gdHlwZW9mIGUgPT09ICdzdHJpbmcnOwogIGNvbnN0IGlzTnVtYmVyID0gKGUpID0+IHR5cGVvZiBlID09PSAnbnVtYmVyJzsKICBjb25zdCBpc09iamVjdCA9IChlKSA9PiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZSkgPT09ICdbb2JqZWN0IE9iamVjdF0nOwogIGNvbnN0IGlzQXJyYXkgPSAoZSkgPT4gQXJyYXkuaXNBcnJheShlKTsKCiAgdmFyIGNvbW1vbmpzR2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDoge307CgogIGZ1bmN0aW9uIGdldEF1Z21lbnRlZE5hbWVzcGFjZShuKSB7CiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sICdfX2VzTW9kdWxlJykpIHJldHVybiBuOwogICAgdmFyIGYgPSBuLmRlZmF1bHQ7CiAgCWlmICh0eXBlb2YgZiA9PSAiZnVuY3Rpb24iKSB7CiAgCQl2YXIgYSA9IGZ1bmN0aW9uIGEgKCkgewogIAkJCXZhciBpc0luc3RhbmNlID0gZmFsc2U7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGlzSW5zdGFuY2UgPSB0aGlzIGluc3RhbmNlb2YgYTsKICAgICAgICB9IGNhdGNoIHt9CiAgCQkJaWYgKGlzSW5zdGFuY2UpIHsKICAgICAgICAgIHJldHVybiBSZWZsZWN0LmNvbnN0cnVjdChmLCBhcmd1bWVudHMsIHRoaXMuY29uc3RydWN0b3IpOwogIAkJCX0KICAJCQlyZXR1cm4gZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogIAkJfTsKICAJCWEucHJvdG90eXBlID0gZi5wcm90b3R5cGU7CiAgICB9IGVsc2UgYSA9IHt9OwogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGEsICdfX2VzTW9kdWxlJywge3ZhbHVlOiB0cnVlfSk7CiAgCU9iamVjdC5rZXlzKG4pLmZvckVhY2goZnVuY3Rpb24gKGspIHsKICAJCXZhciBkID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihuLCBrKTsKICAJCU9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLCBrLCBkLmdldCA/IGQgOiB7CiAgCQkJZW51bWVyYWJsZTogdHJ1ZSwKICAJCQlnZXQ6IGZ1bmN0aW9uICgpIHsKICAJCQkJcmV0dXJuIG5ba107CiAgCQkJfQogIAkJfSk7CiAgCX0pOwogIAlyZXR1cm4gYTsKICB9CgogIHZhciBjcnlwdG9KcyQxID0ge2V4cG9ydHM6IHt9fTsKCiAgZnVuY3Rpb24gY29tbW9uanNSZXF1aXJlKHBhdGgpIHsKICAJdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZHluYW1pY2FsbHkgcmVxdWlyZSAiJyArIHBhdGggKyAnIi4gUGxlYXNlIGNvbmZpZ3VyZSB0aGUgZHluYW1pY1JlcXVpcmVUYXJnZXRzIG9yL2FuZCBpZ25vcmVEeW5hbWljUmVxdWlyZXMgb3B0aW9uIG9mIEByb2xsdXAvcGx1Z2luLWNvbW1vbmpzIGFwcHJvcHJpYXRlbHkgZm9yIHRoaXMgcmVxdWlyZSBjYWxsIHRvIHdvcmsuJyk7CiAgfQoKICB2YXIgY29yZSQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIF9ub2RlUmVzb2x2ZV9lbXB0eSA9IHt9OwoKICB2YXIgX25vZGVSZXNvbHZlX2VtcHR5JDEgPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7CiAgICBfX3Byb3RvX186IG51bGwsCiAgICBkZWZhdWx0OiBfbm9kZVJlc29sdmVfZW1wdHkKICB9KTsKCiAgdmFyIHJlcXVpcmUkJDAgPSAvKkBfX1BVUkVfXyovZ2V0QXVnbWVudGVkTmFtZXNwYWNlKF9ub2RlUmVzb2x2ZV9lbXB0eSQxKTsKCiAgdmFyIGNvcmUgPSBjb3JlJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRDb3JlOwogIGZ1bmN0aW9uIHJlcXVpcmVDb3JlKCkgewogICAgaWYgKGhhc1JlcXVpcmVkQ29yZSkgcmV0dXJuIGNvcmUkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRDb3JlID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpOwogICAgICAgIH0KICAgICAgfSkoY29yZSwgZnVuY3Rpb24gKCkgewogICAgICAgIC8qZ2xvYmFscyB3aW5kb3csIGdsb2JhbCwgcmVxdWlyZSovCgogICAgICAgIC8qKgogICAgICAgICAqIENyeXB0b0pTIGNvcmUgY29tcG9uZW50cy4KICAgICAgICAgKi8KICAgICAgICB2YXIgQ3J5cHRvSlMgPSBDcnlwdG9KUyB8fCBmdW5jdGlvbiAoTWF0aCwgdW5kZWZpbmVkJDEpIHsKICAgICAgICAgIHZhciBjcnlwdG87CgogICAgICAgICAgLy8gTmF0aXZlIGNyeXB0byBmcm9tIHdpbmRvdyAoQnJvd3NlcikKICAgICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuY3J5cHRvKSB7CiAgICAgICAgICAgIGNyeXB0byA9IHdpbmRvdy5jcnlwdG87CiAgICAgICAgICB9CgogICAgICAgICAgLy8gTmF0aXZlIGNyeXB0byBpbiB3ZWIgd29ya2VyIChCcm93c2VyKQogICAgICAgICAgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyAmJiBzZWxmLmNyeXB0bykgewogICAgICAgICAgICBjcnlwdG8gPSBzZWxmLmNyeXB0bzsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBOYXRpdmUgY3J5cHRvIGZyb20gd29ya2VyCiAgICAgICAgICBpZiAodHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbFRoaXMuY3J5cHRvKSB7CiAgICAgICAgICAgIGNyeXB0byA9IGdsb2JhbFRoaXMuY3J5cHRvOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIE5hdGl2ZSAoZXhwZXJpbWVudGFsIElFIDExKSBjcnlwdG8gZnJvbSB3aW5kb3cgKEJyb3dzZXIpCiAgICAgICAgICBpZiAoIWNyeXB0byAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cubXNDcnlwdG8pIHsKICAgICAgICAgICAgY3J5cHRvID0gd2luZG93Lm1zQ3J5cHRvOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIE5hdGl2ZSBjcnlwdG8gZnJvbSBnbG9iYWwgKE5vZGVKUykKICAgICAgICAgIGlmICghY3J5cHRvICYmIHR5cGVvZiBjb21tb25qc0dsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgJiYgY29tbW9uanNHbG9iYWwuY3J5cHRvKSB7CiAgICAgICAgICAgIGNyeXB0byA9IGNvbW1vbmpzR2xvYmFsLmNyeXB0bzsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBOYXRpdmUgY3J5cHRvIGltcG9ydCB2aWEgcmVxdWlyZSAoTm9kZUpTKQogICAgICAgICAgaWYgKCFjcnlwdG8gJiYgdHlwZW9mIGNvbW1vbmpzUmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIGNyeXB0byA9IHJlcXVpcmUkJDA7CiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge30KICAgICAgICAgIH0KCiAgICAgICAgICAvKgogICAgICAgICAgICogQ3J5cHRvZ3JhcGhpY2FsbHkgc2VjdXJlIHBzZXVkb3JhbmRvbSBudW1iZXIgZ2VuZXJhdG9yCiAgICAgICAgICAgKgogICAgICAgICAgICogQXMgTWF0aC5yYW5kb20oKSBpcyBjcnlwdG9ncmFwaGljYWxseSBub3Qgc2FmZSB0byB1c2UKICAgICAgICAgICAqLwogICAgICAgICAgdmFyIGNyeXB0b1NlY3VyZVJhbmRvbUludCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKGNyeXB0bykgewogICAgICAgICAgICAgIC8vIFVzZSBnZXRSYW5kb21WYWx1ZXMgbWV0aG9kIChCcm93c2VyKQogICAgICAgICAgICAgIGlmICh0eXBlb2YgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQzMkFycmF5KDEpKVswXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge30KICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFVzZSByYW5kb21CeXRlcyBtZXRob2QgKE5vZGVKUykKICAgICAgICAgICAgICBpZiAodHlwZW9mIGNyeXB0by5yYW5kb21CeXRlcyA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyeXB0by5yYW5kb21CeXRlcyg0KS5yZWFkSW50MzJMRSgpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7fQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05hdGl2ZSBjcnlwdG8gbW9kdWxlIGNvdWxkIG5vdCBiZSB1c2VkIHRvIGdldCBzZWN1cmUgcmFuZG9tIG51bWJlci4nKTsKICAgICAgICAgIH07CgogICAgICAgICAgLyoKICAgICAgICAgICAqIExvY2FsIHBvbHlmaWxsIG9mIE9iamVjdC5jcmVhdGUKICAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBjcmVhdGUgPSBPYmplY3QuY3JlYXRlIHx8IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZnVuY3Rpb24gRigpIHt9CiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAob2JqKSB7CiAgICAgICAgICAgICAgdmFyIHN1YnR5cGU7CiAgICAgICAgICAgICAgRi5wcm90b3R5cGUgPSBvYmo7CiAgICAgICAgICAgICAgc3VidHlwZSA9IG5ldyBGKCk7CiAgICAgICAgICAgICAgRi5wcm90b3R5cGUgPSBudWxsOwogICAgICAgICAgICAgIHJldHVybiBzdWJ0eXBlOwogICAgICAgICAgICB9OwogICAgICAgICAgfSgpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQ3J5cHRvSlMgbmFtZXNwYWNlLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgQyA9IHt9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogTGlicmFyeSBuYW1lc3BhY2UuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliID0ge307CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBCYXNlIG9iamVjdCBmb3IgcHJvdG90eXBhbCBpbmhlcml0YW5jZS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgb2JqZWN0IHRoYXQgaW5oZXJpdHMgZnJvbSB0aGlzIG9iamVjdC4KICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvdmVycmlkZXMgUHJvcGVydGllcyB0byBjb3B5IGludG8gdGhlIG5ldyBvYmplY3QuCiAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBuZXcgb2JqZWN0LgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqICAgICB2YXIgTXlUeXBlID0gQ3J5cHRvSlMubGliLkJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgICAgKiAgICAgICAgIGZpZWxkOiAndmFsdWUnLAogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogICAgICAgICBtZXRob2Q6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgKiAgICAgICAgIH0KICAgICAgICAgICAgICAgKiAgICAgfSk7CiAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgZXh0ZW5kOiBmdW5jdGlvbiAob3ZlcnJpZGVzKSB7CiAgICAgICAgICAgICAgICAvLyBTcGF3bgogICAgICAgICAgICAgICAgdmFyIHN1YnR5cGUgPSBjcmVhdGUodGhpcyk7CgogICAgICAgICAgICAgICAgLy8gQXVnbWVudAogICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlcykgewogICAgICAgICAgICAgICAgICBzdWJ0eXBlLm1peEluKG92ZXJyaWRlcyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGRlZmF1bHQgaW5pdGlhbGl6ZXIKICAgICAgICAgICAgICAgIGlmICghc3VidHlwZS5oYXNPd25Qcm9wZXJ0eSgnaW5pdCcpIHx8IHRoaXMuaW5pdCA9PT0gc3VidHlwZS5pbml0KSB7CiAgICAgICAgICAgICAgICAgIHN1YnR5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlLiRzdXBlci5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZXIncyBwcm90b3R5cGUgaXMgdGhlIHN1YnR5cGUgb2JqZWN0CiAgICAgICAgICAgICAgICBzdWJ0eXBlLmluaXQucHJvdG90eXBlID0gc3VidHlwZTsKCiAgICAgICAgICAgICAgICAvLyBSZWZlcmVuY2Ugc3VwZXJ0eXBlCiAgICAgICAgICAgICAgICBzdWJ0eXBlLiRzdXBlciA9IHRoaXM7CiAgICAgICAgICAgICAgICByZXR1cm4gc3VidHlwZTsKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAqIEV4dGVuZHMgdGhpcyBvYmplY3QgYW5kIHJ1bnMgdGhlIGluaXQgbWV0aG9kLgogICAgICAgICAgICAgICAqIEFyZ3VtZW50cyB0byBjcmVhdGUoKSB3aWxsIGJlIHBhc3NlZCB0byBpbml0KCkuCiAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBuZXcgb2JqZWN0LgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqICAgICB2YXIgaW5zdGFuY2UgPSBNeVR5cGUuY3JlYXRlKCk7CiAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgY3JlYXRlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2UgPSB0aGlzLmV4dGVuZCgpOwogICAgICAgICAgICAgICAgaW5zdGFuY2UuaW5pdC5hcHBseShpbnN0YW5jZSwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBvYmplY3QuCiAgICAgICAgICAgICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gYWRkIHNvbWUgbG9naWMgd2hlbiB5b3VyIG9iamVjdHMgYXJlIGNyZWF0ZWQuCiAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogICAgIHZhciBNeVR5cGUgPSBDcnlwdG9KUy5saWIuQmFzZS5leHRlbmQoewogICAgICAgICAgICAgICAqICAgICAgICAgaW5pdDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAqICAgICAgICAgICAgIC8vIC4uLgogICAgICAgICAgICAgICAqICAgICAgICAgfQogICAgICAgICAgICAgICAqICAgICB9KTsKICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICBpbml0OiBmdW5jdGlvbiAoKSB7fSwKICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgKiBDb3BpZXMgcHJvcGVydGllcyBpbnRvIHRoaXMgb2JqZWN0LgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IHByb3BlcnRpZXMgVGhlIHByb3BlcnRpZXMgdG8gbWl4IGluLgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqICAgICBNeVR5cGUubWl4SW4oewogICAgICAgICAgICAgICAqICAgICAgICAgZmllbGQ6ICd2YWx1ZScKICAgICAgICAgICAgICAgKiAgICAgfSk7CiAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgbWl4SW46IGZ1bmN0aW9uIChwcm9wZXJ0aWVzKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBwcm9wZXJ0eU5hbWUgaW4gcHJvcGVydGllcykgewogICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpc1twcm9wZXJ0eU5hbWVdID0gcHJvcGVydGllc1twcm9wZXJ0eU5hbWVdOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gSUUgd29uJ3QgY29weSB0b1N0cmluZyB1c2luZyB0aGUgbG9vcCBhYm92ZQogICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMuaGFzT3duUHJvcGVydHkoJ3RvU3RyaW5nJykpIHsKICAgICAgICAgICAgICAgICAgdGhpcy50b1N0cmluZyA9IHByb3BlcnRpZXMudG9TdHJpbmc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIG9iamVjdC4KICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIGNsb25lLgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqICAgICB2YXIgY2xvbmUgPSBpbnN0YW5jZS5jbG9uZSgpOwogICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbml0LnByb3RvdHlwZS5leHRlbmQodGhpcyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgICAgfSgpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHdvcmRzIFRoZSBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gc2lnQnl0ZXMgVGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBieXRlcyBpbiB0aGlzIHdvcmQgYXJyYXkuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXkgPSBCYXNlLmV4dGVuZCh7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgKE9wdGlvbmFsKSBBbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaWdCeXRlcyAoT3B0aW9uYWwpIFRoZSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgYnl0ZXMgaW4gdGhlIHdvcmRzLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKCk7CiAgICAgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMubGliLldvcmRBcnJheS5jcmVhdGUoWzB4MDAwMTAyMDMsIDB4MDQwNTA2MDddKTsKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbMHgwMDAxMDIwMywgMHgwNDA1MDYwN10sIDYpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKHdvcmRzLCBzaWdCeXRlcykgewogICAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdOwogICAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQkMSkgewogICAgICAgICAgICAgICAgdGhpcy5zaWdCeXRlcyA9IHNpZ0J5dGVzOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLnNpZ0J5dGVzID0gd29yZHMubGVuZ3RoICogNDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIHdvcmQgYXJyYXkgdG8gYSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlciAoT3B0aW9uYWwpIFRoZSBlbmNvZGluZyBzdHJhdGVneSB0byB1c2UuIERlZmF1bHQ6IENyeXB0b0pTLmVuYy5IZXgKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3RyaW5naWZpZWQgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkgKyAnJzsKICAgICAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkudG9TdHJpbmcoKTsKICAgICAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkudG9TdHJpbmcoQ3J5cHRvSlMuZW5jLlV0ZjgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdG9TdHJpbmc6IGZ1bmN0aW9uIChlbmNvZGVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIChlbmNvZGVyIHx8IEhleCkuc3RyaW5naWZ5KHRoaXMpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29uY2F0ZW5hdGVzIGEgd29yZCBhcnJheSB0byB0aGlzIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkgdG8gYXBwZW5kLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoaXMgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHdvcmRBcnJheTEuY29uY2F0KHdvcmRBcnJheTIpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY29uY2F0OiBmdW5jdGlvbiAod29yZEFycmF5KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHRoaXNXb3JkcyA9IHRoaXMud29yZHM7CiAgICAgICAgICAgICAgdmFyIHRoYXRXb3JkcyA9IHdvcmRBcnJheS53b3JkczsKICAgICAgICAgICAgICB2YXIgdGhpc1NpZ0J5dGVzID0gdGhpcy5zaWdCeXRlczsKICAgICAgICAgICAgICB2YXIgdGhhdFNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzOwoKICAgICAgICAgICAgICAvLyBDbGFtcCBleGNlc3MgYml0cwogICAgICAgICAgICAgIHRoaXMuY2xhbXAoKTsKCiAgICAgICAgICAgICAgLy8gQ29uY2F0CiAgICAgICAgICAgICAgaWYgKHRoaXNTaWdCeXRlcyAlIDQpIHsKICAgICAgICAgICAgICAgIC8vIENvcHkgb25lIGJ5dGUgYXQgYSB0aW1lCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoYXRTaWdCeXRlczsgaSsrKSB7CiAgICAgICAgICAgICAgICAgIHZhciB0aGF0Qnl0ZSA9IHRoYXRXb3Jkc1tpID4+PiAyXSA+Pj4gMjQgLSBpICUgNCAqIDggJiAweGZmOwogICAgICAgICAgICAgICAgICB0aGlzV29yZHNbdGhpc1NpZ0J5dGVzICsgaSA+Pj4gMl0gfD0gdGhhdEJ5dGUgPDwgMjQgLSAodGhpc1NpZ0J5dGVzICsgaSkgJSA0ICogODsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gQ29weSBvbmUgd29yZCBhdCBhIHRpbWUKICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGhhdFNpZ0J5dGVzOyBqICs9IDQpIHsKICAgICAgICAgICAgICAgICAgdGhpc1dvcmRzW3RoaXNTaWdCeXRlcyArIGogPj4+IDJdID0gdGhhdFdvcmRzW2ogPj4+IDJdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB0aGlzLnNpZ0J5dGVzICs9IHRoYXRTaWdCeXRlczsKCiAgICAgICAgICAgICAgLy8gQ2hhaW5hYmxlCiAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZW1vdmVzIGluc2lnbmlmaWNhbnQgYml0cy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHdvcmRBcnJheS5jbGFtcCgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2xhbXA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgd29yZHMgPSB0aGlzLndvcmRzOwogICAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHRoaXMuc2lnQnl0ZXM7CgogICAgICAgICAgICAgIC8vIENsYW1wCiAgICAgICAgICAgICAgd29yZHNbc2lnQnl0ZXMgPj4+IDJdICY9IDB4ZmZmZmZmZmYgPDwgMzIgLSBzaWdCeXRlcyAlIDQgKiA4OwogICAgICAgICAgICAgIHdvcmRzLmxlbmd0aCA9IE1hdGguY2VpbChzaWdCeXRlcyAvIDQpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBjbG9uZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBjbG9uZSA9IHdvcmRBcnJheS5jbG9uZSgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgY2xvbmUgPSBCYXNlLmNsb25lLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgY2xvbmUud29yZHMgPSB0aGlzLndvcmRzLnNsaWNlKDApOwogICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENyZWF0ZXMgYSB3b3JkIGFycmF5IGZpbGxlZCB3aXRoIHJhbmRvbSBieXRlcy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG5CeXRlcyBUaGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZW5lcmF0ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcmFuZG9tIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSgxNik7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICByYW5kb206IGZ1bmN0aW9uIChuQnl0ZXMpIHsKICAgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5CeXRlczsgaSArPSA0KSB7CiAgICAgICAgICAgICAgICB3b3Jkcy5wdXNoKGNyeXB0b1NlY3VyZVJhbmRvbUludCgpKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIG5ldyBXb3JkQXJyYXkuaW5pdCh3b3JkcywgbkJ5dGVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBFbmNvZGVyIG5hbWVzcGFjZS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIENfZW5jID0gQy5lbmMgPSB7fTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEhleCBlbmNvZGluZyBzdHJhdGVneS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIEhleCA9IENfZW5jLkhleCA9IHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIGhleCBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGhleCBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBoZXhTdHJpbmcgPSBDcnlwdG9KUy5lbmMuSGV4LnN0cmluZ2lmeSh3b3JkQXJyYXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzOwogICAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlczsKCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHZhciBoZXhDaGFycyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGJpdGUgPSB3b3Jkc1tpID4+PiAyXSA+Pj4gMjQgLSBpICUgNCAqIDggJiAweGZmOwogICAgICAgICAgICAgICAgaGV4Q2hhcnMucHVzaCgoYml0ZSA+Pj4gNCkudG9TdHJpbmcoMTYpKTsKICAgICAgICAgICAgICAgIGhleENoYXJzLnB1c2goKGJpdGUgJiAweDBmKS50b1N0cmluZygxNikpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gaGV4Q2hhcnMuam9pbignJyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBhIGhleCBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gaGV4U3RyIFRoZSBoZXggc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMuZW5jLkhleC5wYXJzZShoZXhTdHJpbmcpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChoZXhTdHIpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBoZXhTdHJMZW5ndGggPSBoZXhTdHIubGVuZ3RoOwoKICAgICAgICAgICAgICAvLyBDb252ZXJ0CiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXhTdHJMZW5ndGg7IGkgKz0gMikgewogICAgICAgICAgICAgICAgd29yZHNbaSA+Pj4gM10gfD0gcGFyc2VJbnQoaGV4U3RyLnN1YnN0cihpLCAyKSwgMTYpIDw8IDI0IC0gaSAlIDggKiA0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHdvcmRzLCBoZXhTdHJMZW5ndGggLyAyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIExhdGluMSBlbmNvZGluZyBzdHJhdGVneS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIExhdGluMSA9IENfZW5jLkxhdGluMSA9IHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIExhdGluMSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIExhdGluMSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBsYXRpbjFTdHJpbmcgPSBDcnlwdG9KUy5lbmMuTGF0aW4xLnN0cmluZ2lmeSh3b3JkQXJyYXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzOwogICAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlczsKCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHZhciBsYXRpbjFDaGFycyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGJpdGUgPSB3b3Jkc1tpID4+PiAyXSA+Pj4gMjQgLSBpICUgNCAqIDggJiAweGZmOwogICAgICAgICAgICAgICAgbGF0aW4xQ2hhcnMucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJpdGUpKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIGxhdGluMUNoYXJzLmpvaW4oJycpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSBMYXRpbjEgc3RyaW5nIHRvIGEgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGxhdGluMVN0ciBUaGUgTGF0aW4xIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5MYXRpbjEucGFyc2UobGF0aW4xU3RyaW5nKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAobGF0aW4xU3RyKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgbGF0aW4xU3RyTGVuZ3RoID0gbGF0aW4xU3RyLmxlbmd0aDsKCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGF0aW4xU3RyTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHdvcmRzW2kgPj4+IDJdIHw9IChsYXRpbjFTdHIuY2hhckNvZGVBdChpKSAmIDB4ZmYpIDw8IDI0IC0gaSAlIDQgKiA4OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHdvcmRzLCBsYXRpbjFTdHJMZW5ndGgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogVVRGLTggZW5jb2Rpbmcgc3RyYXRlZ3kuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmOCA9IHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIFVURi04IHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTggc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgdXRmOFN0cmluZyA9IENyeXB0b0pTLmVuYy5VdGY4LnN0cmluZ2lmeSh3b3JkQXJyYXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7CiAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKExhdGluMS5zdHJpbmdpZnkod29yZEFycmF5KSkpOwogICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWFsZm9ybWVkIFVURi04IGRhdGEnKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi04IHN0cmluZyB0byBhIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1dGY4U3RyIFRoZSBVVEYtOCBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuVXRmOC5wYXJzZSh1dGY4U3RyaW5nKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAodXRmOFN0cikgewogICAgICAgICAgICAgIHJldHVybiBMYXRpbjEucGFyc2UodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHV0ZjhTdHIpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBBYnN0cmFjdCBidWZmZXJlZCBibG9jayBhbGdvcml0aG0gdGVtcGxhdGUuCiAgICAgICAgICAgKgogICAgICAgICAgICogVGhlIHByb3BlcnR5IGJsb2NrU2l6ZSBtdXN0IGJlIGltcGxlbWVudGVkIGluIGEgY29uY3JldGUgc3VidHlwZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gX21pbkJ1ZmZlclNpemUgVGhlIG51bWJlciBvZiBibG9ja3MgdGhhdCBzaG91bGQgYmUga2VwdCB1bnByb2Nlc3NlZCBpbiB0aGUgYnVmZmVyLiBEZWZhdWx0OiAwCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBCdWZmZXJlZEJsb2NrQWxnb3JpdGhtID0gQ19saWIuQnVmZmVyZWRCbG9ja0FsZ29yaXRobSA9IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJlc2V0cyB0aGlzIGJsb2NrIGFsZ29yaXRobSdzIGRhdGEgYnVmZmVyIHRvIGl0cyBpbml0aWFsIHN0YXRlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5yZXNldCgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlcwogICAgICAgICAgICAgIHRoaXMuX2RhdGEgPSBuZXcgV29yZEFycmF5LmluaXQoKTsKICAgICAgICAgICAgICB0aGlzLl9uRGF0YUJ5dGVzID0gMDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEFkZHMgbmV3IGRhdGEgdG8gdGhpcyBibG9jayBhbGdvcml0aG0ncyBidWZmZXIuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gZGF0YSBUaGUgZGF0YSB0byBhcHBlbmQuIFN0cmluZ3MgYXJlIGNvbnZlcnRlZCB0byBhIFdvcmRBcnJheSB1c2luZyBVVEYtOC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIGJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uX2FwcGVuZCgnZGF0YScpOwogICAgICAgICAgICAgKiAgICAgYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fYXBwZW5kKHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBfYXBwZW5kOiBmdW5jdGlvbiAoZGF0YSkgewogICAgICAgICAgICAgIC8vIENvbnZlcnQgc3RyaW5nIHRvIFdvcmRBcnJheSwgZWxzZSBhc3N1bWUgV29yZEFycmF5IGFscmVhZHkKICAgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgICAgIGRhdGEgPSBVdGY4LnBhcnNlKGRhdGEpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gQXBwZW5kCiAgICAgICAgICAgICAgdGhpcy5fZGF0YS5jb25jYXQoZGF0YSk7CiAgICAgICAgICAgICAgdGhpcy5fbkRhdGFCeXRlcyArPSBkYXRhLnNpZ0J5dGVzOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUHJvY2Vzc2VzIGF2YWlsYWJsZSBkYXRhIGJsb2Nrcy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogVGhpcyBtZXRob2QgaW52b2tlcyBfZG9Qcm9jZXNzQmxvY2sob2Zmc2V0KSwgd2hpY2ggbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhIGNvbmNyZXRlIHN1YnR5cGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZG9GbHVzaCBXaGV0aGVyIGFsbCBibG9ja3MgYW5kIHBhcnRpYWwgYmxvY2tzIHNob3VsZCBiZSBwcm9jZXNzZWQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHByb2Nlc3NlZCBkYXRhLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHByb2Nlc3NlZERhdGEgPSBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9wcm9jZXNzKCk7CiAgICAgICAgICAgICAqICAgICB2YXIgcHJvY2Vzc2VkRGF0YSA9IGJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uX3Byb2Nlc3MoISEnZmx1c2gnKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIF9wcm9jZXNzOiBmdW5jdGlvbiAoZG9GbHVzaCkgewogICAgICAgICAgICAgIHZhciBwcm9jZXNzZWRXb3JkczsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICAgICAgICAgIHZhciBkYXRhV29yZHMgPSBkYXRhLndvcmRzOwogICAgICAgICAgICAgIHZhciBkYXRhU2lnQnl0ZXMgPSBkYXRhLnNpZ0J5dGVzOwogICAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSB0aGlzLmJsb2NrU2l6ZTsKICAgICAgICAgICAgICB2YXIgYmxvY2tTaXplQnl0ZXMgPSBibG9ja1NpemUgKiA0OwoKICAgICAgICAgICAgICAvLyBDb3VudCBibG9ja3MgcmVhZHkKICAgICAgICAgICAgICB2YXIgbkJsb2Nrc1JlYWR5ID0gZGF0YVNpZ0J5dGVzIC8gYmxvY2tTaXplQnl0ZXM7CiAgICAgICAgICAgICAgaWYgKGRvRmx1c2gpIHsKICAgICAgICAgICAgICAgIC8vIFJvdW5kIHVwIHRvIGluY2x1ZGUgcGFydGlhbCBibG9ja3MKICAgICAgICAgICAgICAgIG5CbG9ja3NSZWFkeSA9IE1hdGguY2VpbChuQmxvY2tzUmVhZHkpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBSb3VuZCBkb3duIHRvIGluY2x1ZGUgb25seSBmdWxsIGJsb2NrcywKICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhlIG51bWJlciBvZiBibG9ja3MgdGhhdCBtdXN0IHJlbWFpbiBpbiB0aGUgYnVmZmVyCiAgICAgICAgICAgICAgICBuQmxvY2tzUmVhZHkgPSBNYXRoLm1heCgobkJsb2Nrc1JlYWR5IHwgMCkgLSB0aGlzLl9taW5CdWZmZXJTaXplLCAwKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIENvdW50IHdvcmRzIHJlYWR5CiAgICAgICAgICAgICAgdmFyIG5Xb3Jkc1JlYWR5ID0gbkJsb2Nrc1JlYWR5ICogYmxvY2tTaXplOwoKICAgICAgICAgICAgICAvLyBDb3VudCBieXRlcyByZWFkeQogICAgICAgICAgICAgIHZhciBuQnl0ZXNSZWFkeSA9IE1hdGgubWluKG5Xb3Jkc1JlYWR5ICogNCwgZGF0YVNpZ0J5dGVzKTsKCiAgICAgICAgICAgICAgLy8gUHJvY2VzcyBibG9ja3MKICAgICAgICAgICAgICBpZiAobldvcmRzUmVhZHkpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIG9mZnNldCA9IDA7IG9mZnNldCA8IG5Xb3Jkc1JlYWR5OyBvZmZzZXQgKz0gYmxvY2tTaXplKSB7CiAgICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtYWxnb3JpdGhtIGxvZ2ljCiAgICAgICAgICAgICAgICAgIHRoaXMuX2RvUHJvY2Vzc0Jsb2NrKGRhdGFXb3Jkcywgb2Zmc2V0KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgcHJvY2Vzc2VkIHdvcmRzCiAgICAgICAgICAgICAgICBwcm9jZXNzZWRXb3JkcyA9IGRhdGFXb3Jkcy5zcGxpY2UoMCwgbldvcmRzUmVhZHkpOwogICAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyAtPSBuQnl0ZXNSZWFkeTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFJldHVybiBwcm9jZXNzZWQgd29yZHMKICAgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHByb2Nlc3NlZFdvcmRzLCBuQnl0ZXNSZWFkeSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIG9iamVjdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgY2xvbmUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgY2xvbmUgPSBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLmNsb25lKCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBjbG9uZSA9IEJhc2UuY2xvbmUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgICBjbG9uZS5fZGF0YSA9IHRoaXMuX2RhdGEuY2xvbmUoKTsKICAgICAgICAgICAgICByZXR1cm4gY2xvbmU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9taW5CdWZmZXJTaXplOiAwCiAgICAgICAgICB9KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFic3RyYWN0IGhhc2hlciB0ZW1wbGF0ZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgaGFzaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiAxNiAoNTEyIGJpdHMpCiAgICAgICAgICAgKi8KICAgICAgICAgIENfbGliLkhhc2hlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNmZzogQmFzZS5leHRlbmQoKSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBoYXNoZXIuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBoYXNoIGNvbXB1dGF0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGhhc2hlciA9IENyeXB0b0pTLmFsZ28uU0hBMjU2LmNyZWF0ZSgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKGNmZykgewogICAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0cwogICAgICAgICAgICAgIHRoaXMuY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7CgogICAgICAgICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlcwogICAgICAgICAgICAgIHRoaXMucmVzZXQoKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJlc2V0cyB0aGlzIGhhc2hlciB0byBpdHMgaW5pdGlhbCBzdGF0ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIGhhc2hlci5yZXNldCgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBSZXNldCBkYXRhIGJ1ZmZlcgogICAgICAgICAgICAgIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQuY2FsbCh0aGlzKTsKCiAgICAgICAgICAgICAgLy8gUGVyZm9ybSBjb25jcmV0ZS1oYXNoZXIgbG9naWMKICAgICAgICAgICAgICB0aGlzLl9kb1Jlc2V0KCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBVcGRhdGVzIHRoaXMgaGFzaGVyIHdpdGggYSBtZXNzYWdlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgVGhlIG1lc3NhZ2UgdG8gYXBwZW5kLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtIYXNoZXJ9IFRoaXMgaGFzaGVyLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgaGFzaGVyLnVwZGF0ZSgnbWVzc2FnZScpOwogICAgICAgICAgICAgKiAgICAgaGFzaGVyLnVwZGF0ZSh3b3JkQXJyYXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkgewogICAgICAgICAgICAgIC8vIEFwcGVuZAogICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChtZXNzYWdlVXBkYXRlKTsKCiAgICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBoYXNoCiAgICAgICAgICAgICAgdGhpcy5fcHJvY2VzcygpOwoKICAgICAgICAgICAgICAvLyBDaGFpbmFibGUKICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEZpbmFsaXplcyB0aGUgaGFzaCBjb21wdXRhdGlvbi4KICAgICAgICAgICAgICogTm90ZSB0aGF0IHRoZSBmaW5hbGl6ZSBvcGVyYXRpb24gaXMgZWZmZWN0aXZlbHkgYSBkZXN0cnVjdGl2ZSwgcmVhZC1vbmNlIG9wZXJhdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlVXBkYXRlIChPcHRpb25hbCkgQSBmaW5hbCBtZXNzYWdlIHVwZGF0ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgaGFzaC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBoYXNoID0gaGFzaGVyLmZpbmFsaXplKCk7CiAgICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpOwogICAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBoYXNoZXIuZmluYWxpemUod29yZEFycmF5KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkgewogICAgICAgICAgICAgIC8vIEZpbmFsIG1lc3NhZ2UgdXBkYXRlCiAgICAgICAgICAgICAgaWYgKG1lc3NhZ2VVcGRhdGUpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChtZXNzYWdlVXBkYXRlKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtaGFzaGVyIGxvZ2ljCiAgICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9kb0ZpbmFsaXplKCk7CiAgICAgICAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGJsb2NrU2l6ZTogNTEyIC8gMzIsCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDcmVhdGVzIGEgc2hvcnRjdXQgZnVuY3Rpb24gdG8gYSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoZXIgdG8gY3JlYXRlIGEgaGVscGVyIGZvci4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIFNIQTI1NiA9IENyeXB0b0pTLmxpYi5IYXNoZXIuX2NyZWF0ZUhlbHBlcihDcnlwdG9KUy5hbGdvLlNIQTI1Nik7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBfY3JlYXRlSGVscGVyOiBmdW5jdGlvbiAoaGFzaGVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChtZXNzYWdlLCBjZmcpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgaGFzaGVyLmluaXQoY2ZnKS5maW5hbGl6ZShtZXNzYWdlKTsKICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ3JlYXRlcyBhIHNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZSBpbiB0aGlzIEhNQUMgaGVscGVyLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIHNob3J0Y3V0IGZ1bmN0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgSG1hY1NIQTI1NiA9IENyeXB0b0pTLmxpYi5IYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoQ3J5cHRvSlMuYWxnby5TSEEyNTYpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgX2NyZWF0ZUhtYWNIZWxwZXI6IGZ1bmN0aW9uIChoYXNoZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGtleSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDX2FsZ28uSE1BQy5pbml0KGhhc2hlciwga2V5KS5maW5hbGl6ZShtZXNzYWdlKTsKICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFsZ29yaXRobSBuYW1lc3BhY2UuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ28gPSB7fTsKICAgICAgICAgIHJldHVybiBDOwogICAgICAgIH0oTWF0aCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTOwogICAgICB9KTsKICAgIH0pKGNvcmUkMSk7CiAgICByZXR1cm4gY29yZSQxLmV4cG9ydHM7CiAgfQoKICB2YXIgeDY0Q29yZSQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIHg2NENvcmUgPSB4NjRDb3JlJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRYNjRDb3JlOwogIGZ1bmN0aW9uIHJlcXVpcmVYNjRDb3JlKCkgewogICAgaWYgKGhhc1JlcXVpcmVkWDY0Q29yZSkgcmV0dXJuIHg2NENvcmUkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRYNjRDb3JlID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHg2NENvcmUsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAodW5kZWZpbmVkJDEpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlOwogICAgICAgICAgdmFyIFgzMldvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIHg2NCBuYW1lc3BhY2UuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDX3g2NCA9IEMueDY0ID0ge307CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBBIDY0LWJpdCB3b3JkLgogICAgICAgICAgICovCiAgICAgICAgICBDX3g2NC5Xb3JkID0gQmFzZS5leHRlbmQoewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIDY0LWJpdCB3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gaGlnaCBUaGUgaGlnaCAzMiBiaXRzLgogICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93IFRoZSBsb3cgMzIgYml0cy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB4NjRXb3JkID0gQ3J5cHRvSlMueDY0LldvcmQuY3JlYXRlKDB4MDAwMTAyMDMsIDB4MDQwNTA2MDcpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKGhpZ2gsIGxvdykgewogICAgICAgICAgICAgIHRoaXMuaGlnaCA9IGhpZ2g7CiAgICAgICAgICAgICAgdGhpcy5sb3cgPSBsb3c7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBCaXR3aXNlIE5PVHMgdGhpcyB3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtYNjRXb3JkfSBBIG5ldyB4NjQtV29yZCBvYmplY3QgYWZ0ZXIgbmVnYXRpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgbmVnYXRlZCA9IHg2NFdvcmQubm90KCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICAvLyBub3Q6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSB+dGhpcy5oaWdoOwogICAgICAgICAgICAvLyB2YXIgbG93ID0gfnRoaXMubG93OwoKICAgICAgICAgICAgLy8gcmV0dXJuIFg2NFdvcmQuY3JlYXRlKGhpZ2gsIGxvdyk7CiAgICAgICAgICAgIC8vIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQml0d2lzZSBBTkRzIHRoaXMgd29yZCB3aXRoIHRoZSBwYXNzZWQgd29yZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtYNjRXb3JkfSB3b3JkIFRoZSB4NjQtV29yZCB0byBBTkQgd2l0aCB0aGlzIHdvcmQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1g2NFdvcmR9IEEgbmV3IHg2NC1Xb3JkIG9iamVjdCBhZnRlciBBTkRpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgYW5kZWQgPSB4NjRXb3JkLmFuZChhbm90aGVyWDY0V29yZCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICAvLyBhbmQ6IGZ1bmN0aW9uICh3b3JkKSB7CiAgICAgICAgICAgIC8vIHZhciBoaWdoID0gdGhpcy5oaWdoICYgd29yZC5oaWdoOwogICAgICAgICAgICAvLyB2YXIgbG93ID0gdGhpcy5sb3cgJiB3b3JkLmxvdzsKCiAgICAgICAgICAgIC8vIHJldHVybiBYNjRXb3JkLmNyZWF0ZShoaWdoLCBsb3cpOwogICAgICAgICAgICAvLyB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEJpdHdpc2UgT1JzIHRoaXMgd29yZCB3aXRoIHRoZSBwYXNzZWQgd29yZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtYNjRXb3JkfSB3b3JkIFRoZSB4NjQtV29yZCB0byBPUiB3aXRoIHRoaXMgd29yZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIE9SaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIG9yZWQgPSB4NjRXb3JkLm9yKGFub3RoZXJYNjRXb3JkKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIC8vIG9yOiBmdW5jdGlvbiAod29yZCkgewogICAgICAgICAgICAvLyB2YXIgaGlnaCA9IHRoaXMuaGlnaCB8IHdvcmQuaGlnaDsKICAgICAgICAgICAgLy8gdmFyIGxvdyA9IHRoaXMubG93IHwgd29yZC5sb3c7CgogICAgICAgICAgICAvLyByZXR1cm4gWDY0V29yZC5jcmVhdGUoaGlnaCwgbG93KTsKICAgICAgICAgICAgLy8gfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBCaXR3aXNlIFhPUnMgdGhpcyB3b3JkIHdpdGggdGhlIHBhc3NlZCB3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1g2NFdvcmR9IHdvcmQgVGhlIHg2NC1Xb3JkIHRvIFhPUiB3aXRoIHRoaXMgd29yZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIFhPUmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB4b3JlZCA9IHg2NFdvcmQueG9yKGFub3RoZXJYNjRXb3JkKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIC8vIHhvcjogZnVuY3Rpb24gKHdvcmQpIHsKICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSB0aGlzLmhpZ2ggXiB3b3JkLmhpZ2g7CiAgICAgICAgICAgIC8vIHZhciBsb3cgPSB0aGlzLmxvdyBeIHdvcmQubG93OwoKICAgICAgICAgICAgLy8gcmV0dXJuIFg2NFdvcmQuY3JlYXRlKGhpZ2gsIGxvdyk7CiAgICAgICAgICAgIC8vIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2hpZnRzIHRoaXMgd29yZCBuIGJpdHMgdG8gdGhlIGxlZnQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIHNoaWZ0aW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHNoaWZ0ZWQgPSB4NjRXb3JkLnNoaWZ0TCgyNSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICAvLyBzaGlmdEw6IGZ1bmN0aW9uIChuKSB7CiAgICAgICAgICAgIC8vIGlmIChuIDwgMzIpIHsKICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSAodGhpcy5oaWdoIDw8IG4pIHwgKHRoaXMubG93ID4+PiAoMzIgLSBuKSk7CiAgICAgICAgICAgIC8vIHZhciBsb3cgPSB0aGlzLmxvdyA8PCBuOwogICAgICAgICAgICAvLyB9IGVsc2UgewogICAgICAgICAgICAvLyB2YXIgaGlnaCA9IHRoaXMubG93IDw8IChuIC0gMzIpOwogICAgICAgICAgICAvLyB2YXIgbG93ID0gMDsKICAgICAgICAgICAgLy8gfQoKICAgICAgICAgICAgLy8gcmV0dXJuIFg2NFdvcmQuY3JlYXRlKGhpZ2gsIGxvdyk7CiAgICAgICAgICAgIC8vIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2hpZnRzIHRoaXMgd29yZCBuIGJpdHMgdG8gdGhlIHJpZ2h0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1g2NFdvcmR9IEEgbmV3IHg2NC1Xb3JkIG9iamVjdCBhZnRlciBzaGlmdGluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBzaGlmdGVkID0geDY0V29yZC5zaGlmdFIoNyk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICAvLyBzaGlmdFI6IGZ1bmN0aW9uIChuKSB7CiAgICAgICAgICAgIC8vIGlmIChuIDwgMzIpIHsKICAgICAgICAgICAgLy8gdmFyIGxvdyA9ICh0aGlzLmxvdyA+Pj4gbikgfCAodGhpcy5oaWdoIDw8ICgzMiAtIG4pKTsKICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSB0aGlzLmhpZ2ggPj4+IG47CiAgICAgICAgICAgIC8vIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIHZhciBsb3cgPSB0aGlzLmhpZ2ggPj4+IChuIC0gMzIpOwogICAgICAgICAgICAvLyB2YXIgaGlnaCA9IDA7CiAgICAgICAgICAgIC8vIH0KCiAgICAgICAgICAgIC8vIHJldHVybiBYNjRXb3JkLmNyZWF0ZShoaWdoLCBsb3cpOwogICAgICAgICAgICAvLyB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJvdGF0ZXMgdGhpcyB3b3JkIG4gYml0cyB0byB0aGUgbGVmdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHJvdGF0ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIHJvdGF0aW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHJvdGF0ZWQgPSB4NjRXb3JkLnJvdEwoMjUpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgLy8gcm90TDogZnVuY3Rpb24gKG4pIHsKICAgICAgICAgICAgLy8gcmV0dXJuIHRoaXMuc2hpZnRMKG4pLm9yKHRoaXMuc2hpZnRSKDY0IC0gbikpOwogICAgICAgICAgICAvLyB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJvdGF0ZXMgdGhpcyB3b3JkIG4gYml0cyB0byB0aGUgcmlnaHQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byByb3RhdGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1g2NFdvcmR9IEEgbmV3IHg2NC1Xb3JkIG9iamVjdCBhZnRlciByb3RhdGluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciByb3RhdGVkID0geDY0V29yZC5yb3RSKDcpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgLy8gcm90UjogZnVuY3Rpb24gKG4pIHsKICAgICAgICAgICAgLy8gcmV0dXJuIHRoaXMuc2hpZnRSKG4pLm9yKHRoaXMuc2hpZnRMKDY0IC0gbikpOwogICAgICAgICAgICAvLyB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEFkZHMgdGhpcyB3b3JkIHdpdGggdGhlIHBhc3NlZCB3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1g2NFdvcmR9IHdvcmQgVGhlIHg2NC1Xb3JkIHRvIGFkZCB3aXRoIHRoaXMgd29yZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIGFkZGluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBhZGRlZCA9IHg2NFdvcmQuYWRkKGFub3RoZXJYNjRXb3JkKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIC8vIGFkZDogZnVuY3Rpb24gKHdvcmQpIHsKICAgICAgICAgICAgLy8gdmFyIGxvdyA9ICh0aGlzLmxvdyArIHdvcmQubG93KSB8IDA7CiAgICAgICAgICAgIC8vIHZhciBjYXJyeSA9IChsb3cgPj4+IDApIDwgKHRoaXMubG93ID4+PiAwKSA/IDEgOiAwOwogICAgICAgICAgICAvLyB2YXIgaGlnaCA9ICh0aGlzLmhpZ2ggKyB3b3JkLmhpZ2ggKyBjYXJyeSkgfCAwOwoKICAgICAgICAgICAgLy8gcmV0dXJuIFg2NFdvcmQuY3JlYXRlKGhpZ2gsIGxvdyk7CiAgICAgICAgICAgIC8vIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQW4gYXJyYXkgb2YgNjQtYml0IHdvcmRzLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHdvcmRzIFRoZSBhcnJheSBvZiBDcnlwdG9KUy54NjQuV29yZCBvYmplY3RzLgogICAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IHNpZ0J5dGVzIFRoZSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgYnl0ZXMgaW4gdGhpcyB3b3JkIGFycmF5LgogICAgICAgICAgICovCiAgICAgICAgICBDX3g2NC5Xb3JkQXJyYXkgPSBCYXNlLmV4dGVuZCh7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgKE9wdGlvbmFsKSBBbiBhcnJheSBvZiBDcnlwdG9KUy54NjQuV29yZCBvYmplY3RzLgogICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gc2lnQnl0ZXMgKE9wdGlvbmFsKSBUaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHRoZSB3b3Jkcy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy54NjQuV29yZEFycmF5LmNyZWF0ZSgpOwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLng2NC5Xb3JkQXJyYXkuY3JlYXRlKFsKICAgICAgICAgICAgICogICAgICAgICBDcnlwdG9KUy54NjQuV29yZC5jcmVhdGUoMHgwMDAxMDIwMywgMHgwNDA1MDYwNyksCiAgICAgICAgICAgICAqICAgICAgICAgQ3J5cHRvSlMueDY0LldvcmQuY3JlYXRlKDB4MTgxOTFhMWIsIDB4MWMxZDFlMWYpCiAgICAgICAgICAgICAqICAgICBdKTsKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy54NjQuV29yZEFycmF5LmNyZWF0ZShbCiAgICAgICAgICAgICAqICAgICAgICAgQ3J5cHRvSlMueDY0LldvcmQuY3JlYXRlKDB4MDAwMTAyMDMsIDB4MDQwNTA2MDcpLAogICAgICAgICAgICAgKiAgICAgICAgIENyeXB0b0pTLng2NC5Xb3JkLmNyZWF0ZSgweDE4MTkxYTFiLCAweDFjMWQxZTFmKQogICAgICAgICAgICAgKiAgICAgXSwgMTApOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKHdvcmRzLCBzaWdCeXRlcykgewogICAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdOwogICAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQkMSkgewogICAgICAgICAgICAgICAgdGhpcy5zaWdCeXRlcyA9IHNpZ0J5dGVzOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLnNpZ0J5dGVzID0gd29yZHMubGVuZ3RoICogODsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIDY0LWJpdCB3b3JkIGFycmF5IHRvIGEgMzItYml0IHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge0NyeXB0b0pTLmxpYi5Xb3JkQXJyYXl9IFRoaXMgd29yZCBhcnJheSdzIGRhdGEgYXMgYSAzMi1iaXQgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB4MzJXb3JkQXJyYXkgPSB4NjRXb3JkQXJyYXkudG9YMzIoKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHRvWDMyOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHg2NFdvcmRzID0gdGhpcy53b3JkczsKICAgICAgICAgICAgICB2YXIgeDY0V29yZHNMZW5ndGggPSB4NjRXb3Jkcy5sZW5ndGg7CgogICAgICAgICAgICAgIC8vIENvbnZlcnQKICAgICAgICAgICAgICB2YXIgeDMyV29yZHMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHg2NFdvcmRzTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciB4NjRXb3JkID0geDY0V29yZHNbaV07CiAgICAgICAgICAgICAgICB4MzJXb3Jkcy5wdXNoKHg2NFdvcmQuaGlnaCk7CiAgICAgICAgICAgICAgICB4MzJXb3Jkcy5wdXNoKHg2NFdvcmQubG93KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIFgzMldvcmRBcnJheS5jcmVhdGUoeDMyV29yZHMsIHRoaXMuc2lnQnl0ZXMpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtYNjRXb3JkQXJyYXl9IFRoZSBjbG9uZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBjbG9uZSA9IHg2NFdvcmRBcnJheS5jbG9uZSgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgY2xvbmUgPSBCYXNlLmNsb25lLmNhbGwodGhpcyk7CgogICAgICAgICAgICAgIC8vIENsb25lICJ3b3JkcyIgYXJyYXkKICAgICAgICAgICAgICB2YXIgd29yZHMgPSBjbG9uZS53b3JkcyA9IHRoaXMud29yZHMuc2xpY2UoMCk7CgogICAgICAgICAgICAgIC8vIENsb25lIGVhY2ggWDY0V29yZCBvYmplY3QKICAgICAgICAgICAgICB2YXIgd29yZHNMZW5ndGggPSB3b3Jkcy5sZW5ndGg7CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB3b3Jkc0xlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB3b3Jkc1tpXSA9IHdvcmRzW2ldLmNsb25lKCk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlM7CiAgICAgIH0pOwogICAgfSkoeDY0Q29yZSQxKTsKICAgIHJldHVybiB4NjRDb3JlJDEuZXhwb3J0czsKICB9CgogIHZhciBsaWJUeXBlZGFycmF5cyQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIGxpYlR5cGVkYXJyYXlzID0gbGliVHlwZWRhcnJheXMkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZExpYlR5cGVkYXJyYXlzOwogIGZ1bmN0aW9uIHJlcXVpcmVMaWJUeXBlZGFycmF5cygpIHsKICAgIGlmIChoYXNSZXF1aXJlZExpYlR5cGVkYXJyYXlzKSByZXR1cm4gbGliVHlwZWRhcnJheXMkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRMaWJUeXBlZGFycmF5cyA9IDE7CiAgICAoZnVuY3Rpb24gKG1vZHVsZSwgZXhwb3J0cyQxKSB7CiAgICAgIChmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShsaWJUeXBlZGFycmF5cywgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIENoZWNrIGlmIHR5cGVkIGFycmF5cyBhcmUgc3VwcG9ydGVkCiAgICAgICAgICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKCiAgICAgICAgICAvLyBSZWZlcmVuY2Ugb3JpZ2luYWwgaW5pdAogICAgICAgICAgdmFyIHN1cGVySW5pdCA9IFdvcmRBcnJheS5pbml0OwoKICAgICAgICAgIC8vIEF1Z21lbnQgV29yZEFycmF5LmluaXQgdG8gaGFuZGxlIHR5cGVkIGFycmF5cwogICAgICAgICAgdmFyIHN1YkluaXQgPSBXb3JkQXJyYXkuaW5pdCA9IGZ1bmN0aW9uICh0eXBlZEFycmF5KSB7CiAgICAgICAgICAgIC8vIENvbnZlcnQgYnVmZmVycyB0byB1aW50OAogICAgICAgICAgICBpZiAodHlwZWRBcnJheSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7CiAgICAgICAgICAgICAgdHlwZWRBcnJheSA9IG5ldyBVaW50OEFycmF5KHR5cGVkQXJyYXkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDb252ZXJ0IG90aGVyIGFycmF5IHZpZXdzIHRvIHVpbnQ4CiAgICAgICAgICAgIGlmICh0eXBlZEFycmF5IGluc3RhbmNlb2YgSW50OEFycmF5IHx8IHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSAhPT0gInVuZGVmaW5lZCIgJiYgdHlwZWRBcnJheSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5IHx8IHR5cGVkQXJyYXkgaW5zdGFuY2VvZiBJbnQxNkFycmF5IHx8IHR5cGVkQXJyYXkgaW5zdGFuY2VvZiBVaW50MTZBcnJheSB8fCB0eXBlZEFycmF5IGluc3RhbmNlb2YgSW50MzJBcnJheSB8fCB0eXBlZEFycmF5IGluc3RhbmNlb2YgVWludDMyQXJyYXkgfHwgdHlwZWRBcnJheSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSB8fCB0eXBlZEFycmF5IGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5KSB7CiAgICAgICAgICAgICAgdHlwZWRBcnJheSA9IG5ldyBVaW50OEFycmF5KHR5cGVkQXJyYXkuYnVmZmVyLCB0eXBlZEFycmF5LmJ5dGVPZmZzZXQsIHR5cGVkQXJyYXkuYnl0ZUxlbmd0aCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEhhbmRsZSBVaW50OEFycmF5CiAgICAgICAgICAgIGlmICh0eXBlZEFycmF5IGluc3RhbmNlb2YgVWludDhBcnJheSkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgdmFyIHR5cGVkQXJyYXlCeXRlTGVuZ3RoID0gdHlwZWRBcnJheS5ieXRlTGVuZ3RoOwoKICAgICAgICAgICAgICAvLyBFeHRyYWN0IGJ5dGVzCiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlZEFycmF5Qnl0ZUxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB3b3Jkc1tpID4+PiAyXSB8PSB0eXBlZEFycmF5W2ldIDw8IDI0IC0gaSAlIDQgKiA4OwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGlzIHdvcmQgYXJyYXkKICAgICAgICAgICAgICBzdXBlckluaXQuY2FsbCh0aGlzLCB3b3JkcywgdHlwZWRBcnJheUJ5dGVMZW5ndGgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIC8vIEVsc2UgY2FsbCBub3JtYWwgaW5pdAogICAgICAgICAgICAgIHN1cGVySW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwogICAgICAgICAgc3ViSW5pdC5wcm90b3R5cGUgPSBXb3JkQXJyYXk7CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMubGliLldvcmRBcnJheTsKICAgICAgfSk7CiAgICB9KShsaWJUeXBlZGFycmF5cyQxKTsKICAgIHJldHVybiBsaWJUeXBlZGFycmF5cyQxLmV4cG9ydHM7CiAgfQoKICB2YXIgZW5jVXRmMTYkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBlbmNVdGYxNiA9IGVuY1V0ZjE2JDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRFbmNVdGYxNjsKICBmdW5jdGlvbiByZXF1aXJlRW5jVXRmMTYoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRFbmNVdGYxNikgcmV0dXJuIGVuY1V0ZjE2JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkRW5jVXRmMTYgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHsKICAgICAgICB7CiAgICAgICAgICAvLyBDb21tb25KUwogICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmVDb3JlKCkpOwogICAgICAgIH0KICAgICAgfSkoZW5jVXRmMTYsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgQ19lbmMgPSBDLmVuYzsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFVURi0xNiBCRSBlbmNvZGluZyBzdHJhdGVneS4KICAgICAgICAgICAqLwogICAgICAgICAgQ19lbmMuVXRmMTYgPSBDX2VuYy5VdGYxNkJFID0gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgVVRGLTE2IEJFIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTE2IEJFIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHV0ZjE2U3RyaW5nID0gQ3J5cHRvSlMuZW5jLlV0ZjE2LnN0cmluZ2lmeSh3b3JkQXJyYXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzOwogICAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlczsKCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHZhciB1dGYxNkNoYXJzID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWdCeXRlczsgaSArPSAyKSB7CiAgICAgICAgICAgICAgICB2YXIgY29kZVBvaW50ID0gd29yZHNbaSA+Pj4gMl0gPj4+IDE2IC0gaSAlIDQgKiA4ICYgMHhmZmZmOwogICAgICAgICAgICAgICAgdXRmMTZDaGFycy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZVBvaW50KSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB1dGYxNkNoYXJzLmpvaW4oJycpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSBVVEYtMTYgQkUgc3RyaW5nIHRvIGEgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHV0ZjE2U3RyIFRoZSBVVEYtMTYgQkUgc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMuZW5jLlV0ZjE2LnBhcnNlKHV0ZjE2U3RyaW5nKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAodXRmMTZTdHIpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciB1dGYxNlN0ckxlbmd0aCA9IHV0ZjE2U3RyLmxlbmd0aDsKCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdXRmMTZTdHJMZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgd29yZHNbaSA+Pj4gMV0gfD0gdXRmMTZTdHIuY2hhckNvZGVBdChpKSA8PCAxNiAtIGkgJSAyICogMTY7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiBXb3JkQXJyYXkuY3JlYXRlKHdvcmRzLCB1dGYxNlN0ckxlbmd0aCAqIDIpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogVVRGLTE2IExFIGVuY29kaW5nIHN0cmF0ZWd5LgogICAgICAgICAgICovCiAgICAgICAgICBDX2VuYy5VdGYxNkxFID0gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgVVRGLTE2IExFIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTE2IExFIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHV0ZjE2U3RyID0gQ3J5cHRvSlMuZW5jLlV0ZjE2TEUuc3RyaW5naWZ5KHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgd29yZHMgPSB3b3JkQXJyYXkud29yZHM7CiAgICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzOwoKICAgICAgICAgICAgICAvLyBDb252ZXJ0CiAgICAgICAgICAgICAgdmFyIHV0ZjE2Q2hhcnMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpICs9IDIpIHsKICAgICAgICAgICAgICAgIHZhciBjb2RlUG9pbnQgPSBzd2FwRW5kaWFuKHdvcmRzW2kgPj4+IDJdID4+PiAxNiAtIGkgJSA0ICogOCAmIDB4ZmZmZik7CiAgICAgICAgICAgICAgICB1dGYxNkNoYXJzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlUG9pbnQpKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHV0ZjE2Q2hhcnMuam9pbignJyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi0xNiBMRSBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXRmMTZTdHIgVGhlIFVURi0xNiBMRSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuVXRmMTZMRS5wYXJzZSh1dGYxNlN0cik7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwYXJzZTogZnVuY3Rpb24gKHV0ZjE2U3RyKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgdXRmMTZTdHJMZW5ndGggPSB1dGYxNlN0ci5sZW5ndGg7CgogICAgICAgICAgICAgIC8vIENvbnZlcnQKICAgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHV0ZjE2U3RyTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHdvcmRzW2kgPj4+IDFdIHw9IHN3YXBFbmRpYW4odXRmMTZTdHIuY2hhckNvZGVBdChpKSA8PCAxNiAtIGkgJSAyICogMTYpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gV29yZEFycmF5LmNyZWF0ZSh3b3JkcywgdXRmMTZTdHJMZW5ndGggKiAyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKICAgICAgICAgIGZ1bmN0aW9uIHN3YXBFbmRpYW4od29yZCkgewogICAgICAgICAgICByZXR1cm4gd29yZCA8PCA4ICYgMHhmZjAwZmYwMCB8IHdvcmQgPj4+IDggJiAweDAwZmYwMGZmOwogICAgICAgICAgfQogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLmVuYy5VdGYxNjsKICAgICAgfSk7CiAgICB9KShlbmNVdGYxNiQxKTsKICAgIHJldHVybiBlbmNVdGYxNiQxLmV4cG9ydHM7CiAgfQoKICB2YXIgZW5jQmFzZTY0JDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgZW5jQmFzZTY0ID0gZW5jQmFzZTY0JDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRFbmNCYXNlNjQ7CiAgZnVuY3Rpb24gcmVxdWlyZUVuY0Jhc2U2NCgpIHsKICAgIGlmIChoYXNSZXF1aXJlZEVuY0Jhc2U2NCkgcmV0dXJuIGVuY0Jhc2U2NCQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZEVuY0Jhc2U2NCA9IDE7CiAgICAoZnVuY3Rpb24gKG1vZHVsZSwgZXhwb3J0cyQxKSB7CiAgICAgIChmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShlbmNCYXNlNjQsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgQ19lbmMgPSBDLmVuYzsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEJhc2U2NCBlbmNvZGluZyBzdHJhdGVneS4KICAgICAgICAgICAqLwogICAgICAgICAgQ19lbmMuQmFzZTY0ID0gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgQmFzZTY0IHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgQmFzZTY0IHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGJhc2U2NFN0cmluZyA9IENyeXB0b0pTLmVuYy5CYXNlNjQuc3RyaW5naWZ5KHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgd29yZHMgPSB3b3JkQXJyYXkud29yZHM7CiAgICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzOwogICAgICAgICAgICAgIHZhciBtYXAgPSB0aGlzLl9tYXA7CgogICAgICAgICAgICAgIC8vIENsYW1wIGV4Y2VzcyBiaXRzCiAgICAgICAgICAgICAgd29yZEFycmF5LmNsYW1wKCk7CgogICAgICAgICAgICAgIC8vIENvbnZlcnQKICAgICAgICAgICAgICB2YXIgYmFzZTY0Q2hhcnMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpICs9IDMpIHsKICAgICAgICAgICAgICAgIHZhciBieXRlMSA9IHdvcmRzW2kgPj4+IDJdID4+PiAyNCAtIGkgJSA0ICogOCAmIDB4ZmY7CiAgICAgICAgICAgICAgICB2YXIgYnl0ZTIgPSB3b3Jkc1tpICsgMSA+Pj4gMl0gPj4+IDI0IC0gKGkgKyAxKSAlIDQgKiA4ICYgMHhmZjsKICAgICAgICAgICAgICAgIHZhciBieXRlMyA9IHdvcmRzW2kgKyAyID4+PiAyXSA+Pj4gMjQgLSAoaSArIDIpICUgNCAqIDggJiAweGZmOwogICAgICAgICAgICAgICAgdmFyIHRyaXBsZXQgPSBieXRlMSA8PCAxNiB8IGJ5dGUyIDw8IDggfCBieXRlMzsKICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgNCAmJiBpICsgaiAqIDAuNzUgPCBzaWdCeXRlczsgaisrKSB7CiAgICAgICAgICAgICAgICAgIGJhc2U2NENoYXJzLnB1c2gobWFwLmNoYXJBdCh0cmlwbGV0ID4+PiA2ICogKDMgLSBqKSAmIDB4M2YpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nCiAgICAgICAgICAgICAgdmFyIHBhZGRpbmdDaGFyID0gbWFwLmNoYXJBdCg2NCk7CiAgICAgICAgICAgICAgaWYgKHBhZGRpbmdDaGFyKSB7CiAgICAgICAgICAgICAgICB3aGlsZSAoYmFzZTY0Q2hhcnMubGVuZ3RoICUgNCkgewogICAgICAgICAgICAgICAgICBiYXNlNjRDaGFycy5wdXNoKHBhZGRpbmdDaGFyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIGJhc2U2NENoYXJzLmpvaW4oJycpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSBCYXNlNjQgc3RyaW5nIHRvIGEgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2U2NFN0ciBUaGUgQmFzZTY0IHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5CYXNlNjQucGFyc2UoYmFzZTY0U3RyaW5nKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAoYmFzZTY0U3RyKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGJhc2U2NFN0ckxlbmd0aCA9IGJhc2U2NFN0ci5sZW5ndGg7CiAgICAgICAgICAgICAgdmFyIG1hcCA9IHRoaXMuX21hcDsKICAgICAgICAgICAgICB2YXIgcmV2ZXJzZU1hcCA9IHRoaXMuX3JldmVyc2VNYXA7CiAgICAgICAgICAgICAgaWYgKCFyZXZlcnNlTWFwKSB7CiAgICAgICAgICAgICAgICByZXZlcnNlTWFwID0gdGhpcy5fcmV2ZXJzZU1hcCA9IFtdOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtYXAubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgcmV2ZXJzZU1hcFttYXAuY2hhckNvZGVBdChqKV0gPSBqOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gSWdub3JlIHBhZGRpbmcKICAgICAgICAgICAgICB2YXIgcGFkZGluZ0NoYXIgPSBtYXAuY2hhckF0KDY0KTsKICAgICAgICAgICAgICBpZiAocGFkZGluZ0NoYXIpIHsKICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nSW5kZXggPSBiYXNlNjRTdHIuaW5kZXhPZihwYWRkaW5nQ2hhcik7CiAgICAgICAgICAgICAgICBpZiAocGFkZGluZ0luZGV4ICE9PSAtMSkgewogICAgICAgICAgICAgICAgICBiYXNlNjRTdHJMZW5ndGggPSBwYWRkaW5nSW5kZXg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBDb252ZXJ0CiAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlTG9vcChiYXNlNjRTdHIsIGJhc2U2NFN0ckxlbmd0aCwgcmV2ZXJzZU1hcCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9tYXA6ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPScKICAgICAgICAgIH07CiAgICAgICAgICBmdW5jdGlvbiBwYXJzZUxvb3AoYmFzZTY0U3RyLCBiYXNlNjRTdHJMZW5ndGgsIHJldmVyc2VNYXApIHsKICAgICAgICAgICAgdmFyIHdvcmRzID0gW107CiAgICAgICAgICAgIHZhciBuQnl0ZXMgPSAwOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJhc2U2NFN0ckxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgaWYgKGkgJSA0KSB7CiAgICAgICAgICAgICAgICB2YXIgYml0czEgPSByZXZlcnNlTWFwW2Jhc2U2NFN0ci5jaGFyQ29kZUF0KGkgLSAxKV0gPDwgaSAlIDQgKiAyOwogICAgICAgICAgICAgICAgdmFyIGJpdHMyID0gcmV2ZXJzZU1hcFtiYXNlNjRTdHIuY2hhckNvZGVBdChpKV0gPj4+IDYgLSBpICUgNCAqIDI7CiAgICAgICAgICAgICAgICB2YXIgYml0c0NvbWJpbmVkID0gYml0czEgfCBiaXRzMjsKICAgICAgICAgICAgICAgIHdvcmRzW25CeXRlcyA+Pj4gMl0gfD0gYml0c0NvbWJpbmVkIDw8IDI0IC0gbkJ5dGVzICUgNCAqIDg7CiAgICAgICAgICAgICAgICBuQnl0ZXMrKzsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIFdvcmRBcnJheS5jcmVhdGUod29yZHMsIG5CeXRlcyk7CiAgICAgICAgICB9CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMuZW5jLkJhc2U2NDsKICAgICAgfSk7CiAgICB9KShlbmNCYXNlNjQkMSk7CiAgICByZXR1cm4gZW5jQmFzZTY0JDEuZXhwb3J0czsKICB9CgogIHZhciBlbmNCYXNlNjR1cmwkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBlbmNCYXNlNjR1cmwgPSBlbmNCYXNlNjR1cmwkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZEVuY0Jhc2U2NHVybDsKICBmdW5jdGlvbiByZXF1aXJlRW5jQmFzZTY0dXJsKCkgewogICAgaWYgKGhhc1JlcXVpcmVkRW5jQmFzZTY0dXJsKSByZXR1cm4gZW5jQmFzZTY0dXJsJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkRW5jQmFzZTY0dXJsID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKGVuY0Jhc2U2NHVybCwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKICAgICAgICAgIHZhciBDX2VuYyA9IEMuZW5jOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQmFzZTY0dXJsIGVuY29kaW5nIHN0cmF0ZWd5LgogICAgICAgICAgICovCiAgICAgICAgICBDX2VuYy5CYXNlNjR1cmwgPSB7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBCYXNlNjR1cmwgc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHVybFNhZmUgV2hldGhlciB0byB1c2UgdXJsIHNhZmUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgQmFzZTY0dXJsIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGJhc2U2NFN0cmluZyA9IENyeXB0b0pTLmVuYy5CYXNlNjR1cmwuc3RyaW5naWZ5KHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXksIHVybFNhZmUpIHsKICAgICAgICAgICAgICBpZiAodXJsU2FmZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICB1cmxTYWZlID0gdHJ1ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzOwogICAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlczsKICAgICAgICAgICAgICB2YXIgbWFwID0gdXJsU2FmZSA/IHRoaXMuX3NhZmVfbWFwIDogdGhpcy5fbWFwOwoKICAgICAgICAgICAgICAvLyBDbGFtcCBleGNlc3MgYml0cwogICAgICAgICAgICAgIHdvcmRBcnJheS5jbGFtcCgpOwoKICAgICAgICAgICAgICAvLyBDb252ZXJ0CiAgICAgICAgICAgICAgdmFyIGJhc2U2NENoYXJzID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWdCeXRlczsgaSArPSAzKSB7CiAgICAgICAgICAgICAgICB2YXIgYnl0ZTEgPSB3b3Jkc1tpID4+PiAyXSA+Pj4gMjQgLSBpICUgNCAqIDggJiAweGZmOwogICAgICAgICAgICAgICAgdmFyIGJ5dGUyID0gd29yZHNbaSArIDEgPj4+IDJdID4+PiAyNCAtIChpICsgMSkgJSA0ICogOCAmIDB4ZmY7CiAgICAgICAgICAgICAgICB2YXIgYnl0ZTMgPSB3b3Jkc1tpICsgMiA+Pj4gMl0gPj4+IDI0IC0gKGkgKyAyKSAlIDQgKiA4ICYgMHhmZjsKICAgICAgICAgICAgICAgIHZhciB0cmlwbGV0ID0gYnl0ZTEgPDwgMTYgfCBieXRlMiA8PCA4IHwgYnl0ZTM7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IDQgJiYgaSArIGogKiAwLjc1IDwgc2lnQnl0ZXM7IGorKykgewogICAgICAgICAgICAgICAgICBiYXNlNjRDaGFycy5wdXNoKG1hcC5jaGFyQXQodHJpcGxldCA+Pj4gNiAqICgzIC0gaikgJiAweDNmKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBBZGQgcGFkZGluZwogICAgICAgICAgICAgIHZhciBwYWRkaW5nQ2hhciA9IG1hcC5jaGFyQXQoNjQpOwogICAgICAgICAgICAgIGlmIChwYWRkaW5nQ2hhcikgewogICAgICAgICAgICAgICAgd2hpbGUgKGJhc2U2NENoYXJzLmxlbmd0aCAlIDQpIHsKICAgICAgICAgICAgICAgICAgYmFzZTY0Q2hhcnMucHVzaChwYWRkaW5nQ2hhcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiBiYXNlNjRDaGFycy5qb2luKCcnKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGEgQmFzZTY0dXJsIHN0cmluZyB0byBhIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlNjRTdHIgVGhlIEJhc2U2NHVybCBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXJsU2FmZSBXaGV0aGVyIHRvIHVzZSB1cmwgc2FmZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMuZW5jLkJhc2U2NHVybC5wYXJzZShiYXNlNjRTdHJpbmcpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChiYXNlNjRTdHIsIHVybFNhZmUpIHsKICAgICAgICAgICAgICBpZiAodXJsU2FmZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICB1cmxTYWZlID0gdHJ1ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBiYXNlNjRTdHJMZW5ndGggPSBiYXNlNjRTdHIubGVuZ3RoOwogICAgICAgICAgICAgIHZhciBtYXAgPSB1cmxTYWZlID8gdGhpcy5fc2FmZV9tYXAgOiB0aGlzLl9tYXA7CiAgICAgICAgICAgICAgdmFyIHJldmVyc2VNYXAgPSB0aGlzLl9yZXZlcnNlTWFwOwogICAgICAgICAgICAgIGlmICghcmV2ZXJzZU1hcCkgewogICAgICAgICAgICAgICAgcmV2ZXJzZU1hcCA9IHRoaXMuX3JldmVyc2VNYXAgPSBbXTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWFwLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgIHJldmVyc2VNYXBbbWFwLmNoYXJDb2RlQXQoaildID0gajsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIElnbm9yZSBwYWRkaW5nCiAgICAgICAgICAgICAgdmFyIHBhZGRpbmdDaGFyID0gbWFwLmNoYXJBdCg2NCk7CiAgICAgICAgICAgICAgaWYgKHBhZGRpbmdDaGFyKSB7CiAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0luZGV4ID0gYmFzZTY0U3RyLmluZGV4T2YocGFkZGluZ0NoYXIpOwogICAgICAgICAgICAgICAgaWYgKHBhZGRpbmdJbmRleCAhPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgYmFzZTY0U3RyTGVuZ3RoID0gcGFkZGluZ0luZGV4OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHJldHVybiBwYXJzZUxvb3AoYmFzZTY0U3RyLCBiYXNlNjRTdHJMZW5ndGgsIHJldmVyc2VNYXApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfbWFwOiAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz0nLAogICAgICAgICAgICBfc2FmZV9tYXA6ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OS1fJwogICAgICAgICAgfTsKICAgICAgICAgIGZ1bmN0aW9uIHBhcnNlTG9vcChiYXNlNjRTdHIsIGJhc2U2NFN0ckxlbmd0aCwgcmV2ZXJzZU1hcCkgewogICAgICAgICAgICB2YXIgd29yZHMgPSBbXTsKICAgICAgICAgICAgdmFyIG5CeXRlcyA9IDA7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmFzZTY0U3RyTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICBpZiAoaSAlIDQpIHsKICAgICAgICAgICAgICAgIHZhciBiaXRzMSA9IHJldmVyc2VNYXBbYmFzZTY0U3RyLmNoYXJDb2RlQXQoaSAtIDEpXSA8PCBpICUgNCAqIDI7CiAgICAgICAgICAgICAgICB2YXIgYml0czIgPSByZXZlcnNlTWFwW2Jhc2U2NFN0ci5jaGFyQ29kZUF0KGkpXSA+Pj4gNiAtIGkgJSA0ICogMjsKICAgICAgICAgICAgICAgIHZhciBiaXRzQ29tYmluZWQgPSBiaXRzMSB8IGJpdHMyOwogICAgICAgICAgICAgICAgd29yZHNbbkJ5dGVzID4+PiAyXSB8PSBiaXRzQ29tYmluZWQgPDwgMjQgLSBuQnl0ZXMgJSA0ICogODsKICAgICAgICAgICAgICAgIG5CeXRlcysrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gV29yZEFycmF5LmNyZWF0ZSh3b3JkcywgbkJ5dGVzKTsKICAgICAgICAgIH0KICAgICAgICB9KSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5lbmMuQmFzZTY0dXJsOwogICAgICB9KTsKICAgIH0pKGVuY0Jhc2U2NHVybCQxKTsKICAgIHJldHVybiBlbmNCYXNlNjR1cmwkMS5leHBvcnRzOwogIH0KCiAgdmFyIG1kNSQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIG1kNSA9IG1kNSQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkTWQ1OwogIGZ1bmN0aW9uIHJlcXVpcmVNZDUoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRNZDUpIHJldHVybiBtZDUkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRNZDUgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHsKICAgICAgICB7CiAgICAgICAgICAvLyBDb21tb25KUwogICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmVDb3JlKCkpOwogICAgICAgIH0KICAgICAgfSkobWQ1LCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAoZnVuY3Rpb24gKE1hdGgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKICAgICAgICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7CiAgICAgICAgICB2YXIgQ19hbGdvID0gQy5hbGdvOwoKICAgICAgICAgIC8vIENvbnN0YW50cyB0YWJsZQogICAgICAgICAgdmFyIFQgPSBbXTsKCiAgICAgICAgICAvLyBDb21wdXRlIGNvbnN0YW50cwogICAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA2NDsgaSsrKSB7CiAgICAgICAgICAgICAgVFtpXSA9IE1hdGguYWJzKE1hdGguc2luKGkgKyAxKSkgKiAweDEwMDAwMDAwMCB8IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pKCk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBNRDUgaGFzaCBhbGdvcml0aG0uCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBNRDUgPSBDX2FsZ28uTUQ1ID0gSGFzaGVyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSwgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3Nl0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAvLyBTd2FwIGVuZGlhbgogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykgewogICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0X2kgPSBvZmZzZXQgKyBpOwogICAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0X2kgPSBNW29mZnNldF9pXTsKICAgICAgICAgICAgICAgIE1bb2Zmc2V0X2ldID0gKE1fb2Zmc2V0X2kgPDwgOCB8IE1fb2Zmc2V0X2kgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoTV9vZmZzZXRfaSA8PCAyNCB8IE1fb2Zmc2V0X2kgPj4+IDgpICYgMHhmZjAwZmYwMDsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBIID0gdGhpcy5faGFzaC53b3JkczsKICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMCA9IE1bb2Zmc2V0ICsgMF07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEgPSBNW29mZnNldCArIDFdOwogICAgICAgICAgICAgIHZhciBNX29mZnNldF8yID0gTVtvZmZzZXQgKyAyXTsKICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMyA9IE1bb2Zmc2V0ICsgM107CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzQgPSBNW29mZnNldCArIDRdOwogICAgICAgICAgICAgIHZhciBNX29mZnNldF81ID0gTVtvZmZzZXQgKyA1XTsKICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfNiA9IE1bb2Zmc2V0ICsgNl07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzcgPSBNW29mZnNldCArIDddOwogICAgICAgICAgICAgIHZhciBNX29mZnNldF84ID0gTVtvZmZzZXQgKyA4XTsKICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfOSA9IE1bb2Zmc2V0ICsgOV07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEwID0gTVtvZmZzZXQgKyAxMF07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzExID0gTVtvZmZzZXQgKyAxMV07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEyID0gTVtvZmZzZXQgKyAxMl07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEzID0gTVtvZmZzZXQgKyAxM107CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzE0ID0gTVtvZmZzZXQgKyAxNF07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzE1ID0gTVtvZmZzZXQgKyAxNV07CgogICAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzCiAgICAgICAgICAgICAgdmFyIGEgPSBIWzBdOwogICAgICAgICAgICAgIHZhciBiID0gSFsxXTsKICAgICAgICAgICAgICB2YXIgYyA9IEhbMl07CiAgICAgICAgICAgICAgdmFyIGQgPSBIWzNdOwoKICAgICAgICAgICAgICAvLyBDb21wdXRhdGlvbgogICAgICAgICAgICAgIGEgPSBGRihhLCBiLCBjLCBkLCBNX29mZnNldF8wLCA3LCBUWzBdKTsKICAgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfMSwgMTIsIFRbMV0pOwogICAgICAgICAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBNX29mZnNldF8yLCAxNywgVFsyXSk7CiAgICAgICAgICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzMsIDIyLCBUWzNdKTsKICAgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfNCwgNywgVFs0XSk7CiAgICAgICAgICAgICAgZCA9IEZGKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzUsIDEyLCBUWzVdKTsKICAgICAgICAgICAgICBjID0gRkYoYywgZCwgYSwgYiwgTV9vZmZzZXRfNiwgMTcsIFRbNl0pOwogICAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF83LCAyMiwgVFs3XSk7CiAgICAgICAgICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzgsIDcsIFRbOF0pOwogICAgICAgICAgICAgIGQgPSBGRihkLCBhLCBiLCBjLCBNX29mZnNldF85LCAxMiwgVFs5XSk7CiAgICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzEwLCAxNywgVFsxMF0pOwogICAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF8xMSwgMjIsIFRbMTFdKTsKICAgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTIsIDcsIFRbMTJdKTsKICAgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTMsIDEyLCBUWzEzXSk7CiAgICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE0LCAxNywgVFsxNF0pOwogICAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF8xNSwgMjIsIFRbMTVdKTsKICAgICAgICAgICAgICBhID0gR0coYSwgYiwgYywgZCwgTV9vZmZzZXRfMSwgNSwgVFsxNl0pOwogICAgICAgICAgICAgIGQgPSBHRyhkLCBhLCBiLCBjLCBNX29mZnNldF82LCA5LCBUWzE3XSk7CiAgICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzExLCAxNCwgVFsxOF0pOwogICAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF8wLCAyMCwgVFsxOV0pOwogICAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF81LCA1LCBUWzIwXSk7CiAgICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzEwLCA5LCBUWzIxXSk7CiAgICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE1LCAxNCwgVFsyMl0pOwogICAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF80LCAyMCwgVFsyM10pOwogICAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF85LCA1LCBUWzI0XSk7CiAgICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzE0LCA5LCBUWzI1XSk7CiAgICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzMsIDE0LCBUWzI2XSk7CiAgICAgICAgICAgICAgYiA9IEdHKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzgsIDIwLCBUWzI3XSk7CiAgICAgICAgICAgICAgYSA9IEdHKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEzLCA1LCBUWzI4XSk7CiAgICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzIsIDksIFRbMjldKTsKICAgICAgICAgICAgICBjID0gR0coYywgZCwgYSwgYiwgTV9vZmZzZXRfNywgMTQsIFRbMzBdKTsKICAgICAgICAgICAgICBiID0gR0coYiwgYywgZCwgYSwgTV9vZmZzZXRfMTIsIDIwLCBUWzMxXSk7CiAgICAgICAgICAgICAgYSA9IEhIKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzUsIDQsIFRbMzJdKTsKICAgICAgICAgICAgICBkID0gSEgoZCwgYSwgYiwgYywgTV9vZmZzZXRfOCwgMTEsIFRbMzNdKTsKICAgICAgICAgICAgICBjID0gSEgoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTEsIDE2LCBUWzM0XSk7CiAgICAgICAgICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzE0LCAyMywgVFszNV0pOwogICAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF8xLCA0LCBUWzM2XSk7CiAgICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzQsIDExLCBUWzM3XSk7CiAgICAgICAgICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzcsIDE2LCBUWzM4XSk7CiAgICAgICAgICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEwLCAyMywgVFszOV0pOwogICAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF8xMywgNCwgVFs0MF0pOwogICAgICAgICAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBNX29mZnNldF8wLCAxMSwgVFs0MV0pOwogICAgICAgICAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBNX29mZnNldF8zLCAxNiwgVFs0Ml0pOwogICAgICAgICAgICAgIGIgPSBISChiLCBjLCBkLCBhLCBNX29mZnNldF82LCAyMywgVFs0M10pOwogICAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF85LCA0LCBUWzQ0XSk7CiAgICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzEyLCAxMSwgVFs0NV0pOwogICAgICAgICAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBNX29mZnNldF8xNSwgMTYsIFRbNDZdKTsKICAgICAgICAgICAgICBiID0gSEgoYiwgYywgZCwgYSwgTV9vZmZzZXRfMiwgMjMsIFRbNDddKTsKICAgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfMCwgNiwgVFs0OF0pOwogICAgICAgICAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBNX29mZnNldF83LCAxMCwgVFs0OV0pOwogICAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF8xNCwgMTUsIFRbNTBdKTsKICAgICAgICAgICAgICBiID0gSUkoYiwgYywgZCwgYSwgTV9vZmZzZXRfNSwgMjEsIFRbNTFdKTsKICAgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTIsIDYsIFRbNTJdKTsKICAgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfMywgMTAsIFRbNTNdKTsKICAgICAgICAgICAgICBjID0gSUkoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTAsIDE1LCBUWzU0XSk7CiAgICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEsIDIxLCBUWzU1XSk7CiAgICAgICAgICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzgsIDYsIFRbNTZdKTsKICAgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTUsIDEwLCBUWzU3XSk7CiAgICAgICAgICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzYsIDE1LCBUWzU4XSk7CiAgICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEzLCAyMSwgVFs1OV0pOwogICAgICAgICAgICAgIGEgPSBJSShhLCBiLCBjLCBkLCBNX29mZnNldF80LCA2LCBUWzYwXSk7CiAgICAgICAgICAgICAgZCA9IElJKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzExLCAxMCwgVFs2MV0pOwogICAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF8yLCAxNSwgVFs2Ml0pOwogICAgICAgICAgICAgIGIgPSBJSShiLCBjLCBkLCBhLCBNX29mZnNldF85LCAyMSwgVFs2M10pOwoKICAgICAgICAgICAgICAvLyBJbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZQogICAgICAgICAgICAgIEhbMF0gPSBIWzBdICsgYSB8IDA7CiAgICAgICAgICAgICAgSFsxXSA9IEhbMV0gKyBiIHwgMDsKICAgICAgICAgICAgICBIWzJdID0gSFsyXSArIGMgfCAwOwogICAgICAgICAgICAgIEhbM10gPSBIWzNdICsgZCB8IDA7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9kb0ZpbmFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICAgICAgICAgIHZhciBkYXRhV29yZHMgPSBkYXRhLndvcmRzOwogICAgICAgICAgICAgIHZhciBuQml0c1RvdGFsID0gdGhpcy5fbkRhdGFCeXRlcyAqIDg7CiAgICAgICAgICAgICAgdmFyIG5CaXRzTGVmdCA9IGRhdGEuc2lnQnl0ZXMgKiA4OwoKICAgICAgICAgICAgICAvLyBBZGQgcGFkZGluZwogICAgICAgICAgICAgIGRhdGFXb3Jkc1tuQml0c0xlZnQgPj4+IDVdIHw9IDB4ODAgPDwgMjQgLSBuQml0c0xlZnQgJSAzMjsKICAgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbEggPSBNYXRoLmZsb29yKG5CaXRzVG90YWwgLyAweDEwMDAwMDAwMCk7CiAgICAgICAgICAgICAgdmFyIG5CaXRzVG90YWxMID0gbkJpdHNUb3RhbDsKICAgICAgICAgICAgICBkYXRhV29yZHNbKG5CaXRzTGVmdCArIDY0ID4+PiA5IDw8IDQpICsgMTVdID0gKG5CaXRzVG90YWxIIDw8IDggfCBuQml0c1RvdGFsSCA+Pj4gMjQpICYgMHgwMGZmMDBmZiB8IChuQml0c1RvdGFsSCA8PCAyNCB8IG5CaXRzVG90YWxIID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgZGF0YVdvcmRzWyhuQml0c0xlZnQgKyA2NCA+Pj4gOSA8PCA0KSArIDE0XSA9IChuQml0c1RvdGFsTCA8PCA4IHwgbkJpdHNUb3RhbEwgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAobkJpdHNUb3RhbEwgPDwgMjQgfCBuQml0c1RvdGFsTCA+Pj4gOCkgJiAweGZmMDBmZjAwOwogICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgPSAoZGF0YVdvcmRzLmxlbmd0aCArIDEpICogNDsKCiAgICAgICAgICAgICAgLy8gSGFzaCBmaW5hbCBibG9ja3MKICAgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBoYXNoID0gdGhpcy5faGFzaDsKICAgICAgICAgICAgICB2YXIgSCA9IGhhc2gud29yZHM7CgogICAgICAgICAgICAgIC8vIFN3YXAgZW5kaWFuCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgICB2YXIgSF9pID0gSFtpXTsKICAgICAgICAgICAgICAgIEhbaV0gPSAoSF9pIDw8IDggfCBIX2kgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoSF9pIDw8IDI0IHwgSF9pID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaAogICAgICAgICAgICAgIHJldHVybiBoYXNoOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBjbG9uZSA9IEhhc2hlci5jbG9uZS5jYWxsKHRoaXMpOwogICAgICAgICAgICAgIGNsb25lLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpOwogICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBmdW5jdGlvbiBGRihhLCBiLCBjLCBkLCB4LCBzLCB0KSB7CiAgICAgICAgICAgIHZhciBuID0gYSArIChiICYgYyB8IH5iICYgZCkgKyB4ICsgdDsKICAgICAgICAgICAgcmV0dXJuIChuIDw8IHMgfCBuID4+PiAzMiAtIHMpICsgYjsKICAgICAgICAgIH0KICAgICAgICAgIGZ1bmN0aW9uIEdHKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHsKICAgICAgICAgICAgdmFyIG4gPSBhICsgKGIgJiBkIHwgYyAmIH5kKSArIHggKyB0OwogICAgICAgICAgICByZXR1cm4gKG4gPDwgcyB8IG4gPj4+IDMyIC0gcykgKyBiOwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gSEgoYSwgYiwgYywgZCwgeCwgcywgdCkgewogICAgICAgICAgICB2YXIgbiA9IGEgKyAoYiBeIGMgXiBkKSArIHggKyB0OwogICAgICAgICAgICByZXR1cm4gKG4gPDwgcyB8IG4gPj4+IDMyIC0gcykgKyBiOwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gSUkoYSwgYiwgYywgZCwgeCwgcywgdCkgewogICAgICAgICAgICB2YXIgbiA9IGEgKyAoYyBeIChiIHwgfmQpKSArIHggKyB0OwogICAgICAgICAgICByZXR1cm4gKG4gPDwgcyB8IG4gPj4+IDMyIC0gcykgKyBiOwogICAgICAgICAgfQoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIGhhc2hlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5NRDUoJ21lc3NhZ2UnKTsKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLk1ENSh3b3JkQXJyYXkpOwogICAgICAgICAgICovCiAgICAgICAgICBDLk1ENSA9IEhhc2hlci5fY3JlYXRlSGVscGVyKE1ENSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNNRDUobWVzc2FnZSwga2V5KTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5IbWFjTUQ1ID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKE1ENSk7CiAgICAgICAgfSkoTWF0aCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLk1ENTsKICAgICAgfSk7CiAgICB9KShtZDUkMSk7CiAgICByZXR1cm4gbWQ1JDEuZXhwb3J0czsKICB9CgogIHZhciBzaGExJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgc2hhMSA9IHNoYTEkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFNoYTE7CiAgZnVuY3Rpb24gcmVxdWlyZVNoYTEoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRTaGExKSByZXR1cm4gc2hhMSQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZFNoYTEgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHsKICAgICAgICB7CiAgICAgICAgICAvLyBDb21tb25KUwogICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmVDb3JlKCkpOwogICAgICAgIH0KICAgICAgfSkoc2hhMSwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKICAgICAgICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7CiAgICAgICAgICB2YXIgQ19hbGdvID0gQy5hbGdvOwoKICAgICAgICAgIC8vIFJldXNhYmxlIG9iamVjdAogICAgICAgICAgdmFyIFcgPSBbXTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNIQS0xIGhhc2ggYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgU0hBMSA9IENfYWxnby5TSEExID0gSGFzaGVyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSwgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3NiwgMHhjM2QyZTFmMF0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBIID0gdGhpcy5faGFzaC53b3JkczsKCiAgICAgICAgICAgICAgLy8gV29ya2luZyB2YXJpYWJsZXMKICAgICAgICAgICAgICB2YXIgYSA9IEhbMF07CiAgICAgICAgICAgICAgdmFyIGIgPSBIWzFdOwogICAgICAgICAgICAgIHZhciBjID0gSFsyXTsKICAgICAgICAgICAgICB2YXIgZCA9IEhbM107CiAgICAgICAgICAgICAgdmFyIGUgPSBIWzRdOwoKICAgICAgICAgICAgICAvLyBDb21wdXRhdGlvbgogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODA7IGkrKykgewogICAgICAgICAgICAgICAgaWYgKGkgPCAxNikgewogICAgICAgICAgICAgICAgICBXW2ldID0gTVtvZmZzZXQgKyBpXSB8IDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICB2YXIgbiA9IFdbaSAtIDNdIF4gV1tpIC0gOF0gXiBXW2kgLSAxNF0gXiBXW2kgLSAxNl07CiAgICAgICAgICAgICAgICAgIFdbaV0gPSBuIDw8IDEgfCBuID4+PiAzMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciB0ID0gKGEgPDwgNSB8IGEgPj4+IDI3KSArIGUgKyBXW2ldOwogICAgICAgICAgICAgICAgaWYgKGkgPCAyMCkgewogICAgICAgICAgICAgICAgICB0ICs9IChiICYgYyB8IH5iICYgZCkgKyAweDVhODI3OTk5OwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpIDwgNDApIHsKICAgICAgICAgICAgICAgICAgdCArPSAoYiBeIGMgXiBkKSArIDB4NmVkOWViYTE7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGkgPCA2MCkgewogICAgICAgICAgICAgICAgICB0ICs9IChiICYgYyB8IGIgJiBkIHwgYyAmIGQpIC0gMHg3MGU0NDMyNDsKICAgICAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAoaSA8IDgwKSAqL3sKICAgICAgICAgICAgICAgICAgICB0ICs9IChiIF4gYyBeIGQpIC0gMHgzNTlkM2UyYTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZSA9IGQ7CiAgICAgICAgICAgICAgICBkID0gYzsKICAgICAgICAgICAgICAgIGMgPSBiIDw8IDMwIHwgYiA+Pj4gMjsKICAgICAgICAgICAgICAgIGIgPSBhOwogICAgICAgICAgICAgICAgYSA9IHQ7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBJbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZQogICAgICAgICAgICAgIEhbMF0gPSBIWzBdICsgYSB8IDA7CiAgICAgICAgICAgICAgSFsxXSA9IEhbMV0gKyBiIHwgMDsKICAgICAgICAgICAgICBIWzJdID0gSFsyXSArIGMgfCAwOwogICAgICAgICAgICAgIEhbM10gPSBIWzNdICsgZCB8IDA7CiAgICAgICAgICAgICAgSFs0XSA9IEhbNF0gKyBlIHwgMDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7CiAgICAgICAgICAgICAgdmFyIG5CaXRzVG90YWwgPSB0aGlzLl9uRGF0YUJ5dGVzICogODsKICAgICAgICAgICAgICB2YXIgbkJpdHNMZWZ0ID0gZGF0YS5zaWdCeXRlcyAqIDg7CgogICAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nCiAgICAgICAgICAgICAgZGF0YVdvcmRzW25CaXRzTGVmdCA+Pj4gNV0gfD0gMHg4MCA8PCAyNCAtIG5CaXRzTGVmdCAlIDMyOwogICAgICAgICAgICAgIGRhdGFXb3Jkc1sobkJpdHNMZWZ0ICsgNjQgPj4+IDkgPDwgNCkgKyAxNF0gPSBNYXRoLmZsb29yKG5CaXRzVG90YWwgLyAweDEwMDAwMDAwMCk7CiAgICAgICAgICAgICAgZGF0YVdvcmRzWyhuQml0c0xlZnQgKyA2NCA+Pj4gOSA8PCA0KSArIDE1XSA9IG5CaXRzVG90YWw7CiAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGRhdGFXb3Jkcy5sZW5ndGggKiA0OwoKICAgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2NrcwogICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTsKCiAgICAgICAgICAgICAgLy8gUmV0dXJuIGZpbmFsIGNvbXB1dGVkIGhhc2gKICAgICAgICAgICAgICByZXR1cm4gdGhpcy5faGFzaDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgICBjbG9uZS5faGFzaCA9IHRoaXMuX2hhc2guY2xvbmUoKTsKICAgICAgICAgICAgICByZXR1cm4gY2xvbmU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIGhhc2hlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEExKCdtZXNzYWdlJyk7CiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEExKHdvcmRBcnJheSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuU0hBMSA9IEhhc2hlci5fY3JlYXRlSGVscGVyKFNIQTEpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBDcnlwdG9KUy5IbWFjU0hBMShtZXNzYWdlLCBrZXkpOwogICAgICAgICAgICovCiAgICAgICAgICBDLkhtYWNTSEExID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKFNIQTEpOwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlNIQTE7CiAgICAgIH0pOwogICAgfSkoc2hhMSQxKTsKICAgIHJldHVybiBzaGExJDEuZXhwb3J0czsKICB9CgogIHZhciBzaGEyNTYkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBzaGEyNTYgPSBzaGEyNTYkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFNoYTI1NjsKICBmdW5jdGlvbiByZXF1aXJlU2hhMjU2KCkgewogICAgaWYgKGhhc1JlcXVpcmVkU2hhMjU2KSByZXR1cm4gc2hhMjU2JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkU2hhMjU2ID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHNoYTI1NiwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uIChNYXRoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyOwogICAgICAgICAgdmFyIENfYWxnbyA9IEMuYWxnbzsKCiAgICAgICAgICAvLyBJbml0aWFsaXphdGlvbiBhbmQgcm91bmQgY29uc3RhbnRzIHRhYmxlcwogICAgICAgICAgdmFyIEggPSBbXTsKICAgICAgICAgIHZhciBLID0gW107CgogICAgICAgICAgLy8gQ29tcHV0ZSBjb25zdGFudHMKICAgICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGlzUHJpbWUobikgewogICAgICAgICAgICAgIHZhciBzcXJ0TiA9IE1hdGguc3FydChuKTsKICAgICAgICAgICAgICBmb3IgKHZhciBmYWN0b3IgPSAyOyBmYWN0b3IgPD0gc3FydE47IGZhY3RvcisrKSB7CiAgICAgICAgICAgICAgICBpZiAoIShuICUgZmFjdG9yKSkgewogICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZ1bmN0aW9uIGdldEZyYWN0aW9uYWxCaXRzKG4pIHsKICAgICAgICAgICAgICByZXR1cm4gKG4gLSAobiB8IDApKSAqIDB4MTAwMDAwMDAwIHwgMDsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgbiA9IDI7CiAgICAgICAgICAgIHZhciBuUHJpbWUgPSAwOwogICAgICAgICAgICB3aGlsZSAoblByaW1lIDwgNjQpIHsKICAgICAgICAgICAgICBpZiAoaXNQcmltZShuKSkgewogICAgICAgICAgICAgICAgaWYgKG5QcmltZSA8IDgpIHsKICAgICAgICAgICAgICAgICAgSFtuUHJpbWVdID0gZ2V0RnJhY3Rpb25hbEJpdHMoTWF0aC5wb3cobiwgMSAvIDIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEtbblByaW1lXSA9IGdldEZyYWN0aW9uYWxCaXRzKE1hdGgucG93KG4sIDEgLyAzKSk7CiAgICAgICAgICAgICAgICBuUHJpbWUrKzsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgbisrOwogICAgICAgICAgICB9CiAgICAgICAgICB9KSgpOwoKICAgICAgICAgIC8vIFJldXNhYmxlIG9iamVjdAogICAgICAgICAgdmFyIFcgPSBbXTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNIQS0yNTYgaGFzaCBhbGdvcml0aG0uCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBTSEEyNTYgPSBDX2FsZ28uU0hBMjU2ID0gSGFzaGVyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChILnNsaWNlKDApKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgSCA9IHRoaXMuX2hhc2gud29yZHM7CgogICAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzCiAgICAgICAgICAgICAgdmFyIGEgPSBIWzBdOwogICAgICAgICAgICAgIHZhciBiID0gSFsxXTsKICAgICAgICAgICAgICB2YXIgYyA9IEhbMl07CiAgICAgICAgICAgICAgdmFyIGQgPSBIWzNdOwogICAgICAgICAgICAgIHZhciBlID0gSFs0XTsKICAgICAgICAgICAgICB2YXIgZiA9IEhbNV07CiAgICAgICAgICAgICAgdmFyIGcgPSBIWzZdOwogICAgICAgICAgICAgIHZhciBoID0gSFs3XTsKCiAgICAgICAgICAgICAgLy8gQ29tcHV0YXRpb24KICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDY0OyBpKyspIHsKICAgICAgICAgICAgICAgIGlmIChpIDwgMTYpIHsKICAgICAgICAgICAgICAgICAgV1tpXSA9IE1bb2Zmc2V0ICsgaV0gfCAwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMHggPSBXW2kgLSAxNV07CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTAgPSAoZ2FtbWEweCA8PCAyNSB8IGdhbW1hMHggPj4+IDcpIF4gKGdhbW1hMHggPDwgMTQgfCBnYW1tYTB4ID4+PiAxOCkgXiBnYW1tYTB4ID4+PiAzOwogICAgICAgICAgICAgICAgICB2YXIgZ2FtbWExeCA9IFdbaSAtIDJdOwogICAgICAgICAgICAgICAgICB2YXIgZ2FtbWExID0gKGdhbW1hMXggPDwgMTUgfCBnYW1tYTF4ID4+PiAxNykgXiAoZ2FtbWExeCA8PCAxMyB8IGdhbW1hMXggPj4+IDE5KSBeIGdhbW1hMXggPj4+IDEwOwogICAgICAgICAgICAgICAgICBXW2ldID0gZ2FtbWEwICsgV1tpIC0gN10gKyBnYW1tYTEgKyBXW2kgLSAxNl07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgY2ggPSBlICYgZiBeIH5lICYgZzsKICAgICAgICAgICAgICAgIHZhciBtYWogPSBhICYgYiBeIGEgJiBjIF4gYiAmIGM7CiAgICAgICAgICAgICAgICB2YXIgc2lnbWEwID0gKGEgPDwgMzAgfCBhID4+PiAyKSBeIChhIDw8IDE5IHwgYSA+Pj4gMTMpIF4gKGEgPDwgMTAgfCBhID4+PiAyMik7CiAgICAgICAgICAgICAgICB2YXIgc2lnbWExID0gKGUgPDwgMjYgfCBlID4+PiA2KSBeIChlIDw8IDIxIHwgZSA+Pj4gMTEpIF4gKGUgPDwgNyB8IGUgPj4+IDI1KTsKICAgICAgICAgICAgICAgIHZhciB0MSA9IGggKyBzaWdtYTEgKyBjaCArIEtbaV0gKyBXW2ldOwogICAgICAgICAgICAgICAgdmFyIHQyID0gc2lnbWEwICsgbWFqOwogICAgICAgICAgICAgICAgaCA9IGc7CiAgICAgICAgICAgICAgICBnID0gZjsKICAgICAgICAgICAgICAgIGYgPSBlOwogICAgICAgICAgICAgICAgZSA9IGQgKyB0MSB8IDA7CiAgICAgICAgICAgICAgICBkID0gYzsKICAgICAgICAgICAgICAgIGMgPSBiOwogICAgICAgICAgICAgICAgYiA9IGE7CiAgICAgICAgICAgICAgICBhID0gdDEgKyB0MiB8IDA7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBJbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZQogICAgICAgICAgICAgIEhbMF0gPSBIWzBdICsgYSB8IDA7CiAgICAgICAgICAgICAgSFsxXSA9IEhbMV0gKyBiIHwgMDsKICAgICAgICAgICAgICBIWzJdID0gSFsyXSArIGMgfCAwOwogICAgICAgICAgICAgIEhbM10gPSBIWzNdICsgZCB8IDA7CiAgICAgICAgICAgICAgSFs0XSA9IEhbNF0gKyBlIHwgMDsKICAgICAgICAgICAgICBIWzVdID0gSFs1XSArIGYgfCAwOwogICAgICAgICAgICAgIEhbNl0gPSBIWzZdICsgZyB8IDA7CiAgICAgICAgICAgICAgSFs3XSA9IEhbN10gKyBoIHwgMDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7CiAgICAgICAgICAgICAgdmFyIG5CaXRzVG90YWwgPSB0aGlzLl9uRGF0YUJ5dGVzICogODsKICAgICAgICAgICAgICB2YXIgbkJpdHNMZWZ0ID0gZGF0YS5zaWdCeXRlcyAqIDg7CgogICAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nCiAgICAgICAgICAgICAgZGF0YVdvcmRzW25CaXRzTGVmdCA+Pj4gNV0gfD0gMHg4MCA8PCAyNCAtIG5CaXRzTGVmdCAlIDMyOwogICAgICAgICAgICAgIGRhdGFXb3Jkc1sobkJpdHNMZWZ0ICsgNjQgPj4+IDkgPDwgNCkgKyAxNF0gPSBNYXRoLmZsb29yKG5CaXRzVG90YWwgLyAweDEwMDAwMDAwMCk7CiAgICAgICAgICAgICAgZGF0YVdvcmRzWyhuQml0c0xlZnQgKyA2NCA+Pj4gOSA8PCA0KSArIDE1XSA9IG5CaXRzVG90YWw7CiAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGRhdGFXb3Jkcy5sZW5ndGggKiA0OwoKICAgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2NrcwogICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTsKCiAgICAgICAgICAgICAgLy8gUmV0dXJuIGZpbmFsIGNvbXB1dGVkIGhhc2gKICAgICAgICAgICAgICByZXR1cm4gdGhpcy5faGFzaDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgICBjbG9uZS5faGFzaCA9IHRoaXMuX2hhc2guY2xvbmUoKTsKICAgICAgICAgICAgICByZXR1cm4gY2xvbmU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIGhhc2hlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEEyNTYoJ21lc3NhZ2UnKTsKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTI1Nih3b3JkQXJyYXkpOwogICAgICAgICAgICovCiAgICAgICAgICBDLlNIQTI1NiA9IEhhc2hlci5fY3JlYXRlSGVscGVyKFNIQTI1Nik7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNTSEEyNTYobWVzc2FnZSwga2V5KTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5IbWFjU0hBMjU2ID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKFNIQTI1Nik7CiAgICAgICAgfSkoTWF0aCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlNIQTI1NjsKICAgICAgfSk7CiAgICB9KShzaGEyNTYkMSk7CiAgICByZXR1cm4gc2hhMjU2JDEuZXhwb3J0czsKICB9CgogIHZhciBzaGEyMjQkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBzaGEyMjQgPSBzaGEyMjQkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFNoYTIyNDsKICBmdW5jdGlvbiByZXF1aXJlU2hhMjI0KCkgewogICAgaWYgKGhhc1JlcXVpcmVkU2hhMjI0KSByZXR1cm4gc2hhMjI0JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkU2hhMjI0ID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZVNoYTI1NigpKTsKICAgICAgICB9CiAgICAgIH0pKHNoYTIyNCwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CiAgICAgICAgICB2YXIgU0hBMjU2ID0gQ19hbGdvLlNIQTI1NjsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNIQS0yMjQgaGFzaCBhbGdvcml0aG0uCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBTSEEyMjQgPSBDX2FsZ28uU0hBMjI0ID0gU0hBMjU2LmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbMHhjMTA1OWVkOCwgMHgzNjdjZDUwNywgMHgzMDcwZGQxNywgMHhmNzBlNTkzOSwgMHhmZmMwMGIzMSwgMHg2ODU4MTUxMSwgMHg2NGY5OGZhNywgMHhiZWZhNGZhNF0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBoYXNoID0gU0hBMjU2Ll9kb0ZpbmFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgaGFzaC5zaWdCeXRlcyAtPSA0OwogICAgICAgICAgICAgIHJldHVybiBoYXNoOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGhhc2guCiAgICAgICAgICAgKgogICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICoKICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgKgogICAgICAgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMjI0KCdtZXNzYWdlJyk7CiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEEyMjQod29yZEFycmF5KTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5TSEEyMjQgPSBTSEEyNTYuX2NyZWF0ZUhlbHBlcihTSEEyMjQpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBDcnlwdG9KUy5IbWFjU0hBMjI0KG1lc3NhZ2UsIGtleSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuSG1hY1NIQTIyNCA9IFNIQTI1Ni5fY3JlYXRlSG1hY0hlbHBlcihTSEEyMjQpOwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlNIQTIyNDsKICAgICAgfSk7CiAgICB9KShzaGEyMjQkMSk7CiAgICByZXR1cm4gc2hhMjI0JDEuZXhwb3J0czsKICB9CgogIHZhciBzaGE1MTIkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBzaGE1MTIgPSBzaGE1MTIkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFNoYTUxMjsKICBmdW5jdGlvbiByZXF1aXJlU2hhNTEyKCkgewogICAgaWYgKGhhc1JlcXVpcmVkU2hhNTEyKSByZXR1cm4gc2hhNTEyJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkU2hhNTEyID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZVg2NENvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShzaGE1MTIsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7CiAgICAgICAgICB2YXIgQ194NjQgPSBDLng2NDsKICAgICAgICAgIHZhciBYNjRXb3JkID0gQ194NjQuV29yZDsKICAgICAgICAgIHZhciBYNjRXb3JkQXJyYXkgPSBDX3g2NC5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgQ19hbGdvID0gQy5hbGdvOwogICAgICAgICAgZnVuY3Rpb24gWDY0V29yZF9jcmVhdGUoKSB7CiAgICAgICAgICAgIHJldHVybiBYNjRXb3JkLmNyZWF0ZS5hcHBseShYNjRXb3JkLCBhcmd1bWVudHMpOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIENvbnN0YW50cwogICAgICAgICAgdmFyIEsgPSBbWDY0V29yZF9jcmVhdGUoMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiksIFg2NFdvcmRfY3JlYXRlKDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QpLCBYNjRXb3JkX2NyZWF0ZSgweGI1YzBmYmNmLCAweGVjNGQzYjJmKSwgWDY0V29yZF9jcmVhdGUoMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyksIFg2NFdvcmRfY3JlYXRlKDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgpLCBYNjRXb3JkX2NyZWF0ZSgweDU5ZjExMWYxLCAweGI2MDVkMDE5KSwgWDY0V29yZF9jcmVhdGUoMHg5MjNmODJhNCwgMHhhZjE5NGY5YiksIFg2NFdvcmRfY3JlYXRlKDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgpLCBYNjRXb3JkX2NyZWF0ZSgweGQ4MDdhYTk4LCAweGEzMDMwMjQyKSwgWDY0V29yZF9jcmVhdGUoMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSksIFg2NFdvcmRfY3JlYXRlKDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMpLCBYNjRXb3JkX2NyZWF0ZSgweDU1MGM3ZGMzLCAweGQ1ZmZiNGUyKSwgWDY0V29yZF9jcmVhdGUoMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiksIFg2NFdvcmRfY3JlYXRlKDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEpLCBYNjRXb3JkX2NyZWF0ZSgweDliZGMwNmE3LCAweDI1YzcxMjM1KSwgWDY0V29yZF9jcmVhdGUoMHhjMTliZjE3NCwgMHhjZjY5MjY5NCksIFg2NFdvcmRfY3JlYXRlKDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIpLCBYNjRXb3JkX2NyZWF0ZSgweGVmYmU0Nzg2LCAweDM4NGYyNWUzKSwgWDY0V29yZF9jcmVhdGUoMHgwZmMxOWRjNiwgMHg4YjhjZDViNSksIFg2NFdvcmRfY3JlYXRlKDB4MjQwY2ExY2MsIDB4NzdhYzljNjUpLCBYNjRXb3JkX2NyZWF0ZSgweDJkZTkyYzZmLCAweDU5MmIwMjc1KSwgWDY0V29yZF9jcmVhdGUoMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyksIFg2NFdvcmRfY3JlYXRlKDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQpLCBYNjRXb3JkX2NyZWF0ZSgweDc2Zjk4OGRhLCAweDgzMTE1M2I1KSwgWDY0V29yZF9jcmVhdGUoMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiksIFg2NFdvcmRfY3JlYXRlKDB4YTgzMWM2NmQsIDB4MmRiNDMyMTApLCBYNjRXb3JkX2NyZWF0ZSgweGIwMDMyN2M4LCAweDk4ZmIyMTNmKSwgWDY0V29yZF9jcmVhdGUoMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCksIFg2NFdvcmRfY3JlYXRlKDB4YzZlMDBiZjMsIDB4M2RhODhmYzIpLCBYNjRXb3JkX2NyZWF0ZSgweGQ1YTc5MTQ3LCAweDkzMGFhNzI1KSwgWDY0V29yZF9jcmVhdGUoMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiksIFg2NFdvcmRfY3JlYXRlKDB4MTQyOTI5NjcsIDB4MGEwZTZlNzApLCBYNjRXb3JkX2NyZWF0ZSgweDI3YjcwYTg1LCAweDQ2ZDIyZmZjKSwgWDY0V29yZF9jcmVhdGUoMHgyZTFiMjEzOCwgMHg1YzI2YzkyNiksIFg2NFdvcmRfY3JlYXRlKDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQpLCBYNjRXb3JkX2NyZWF0ZSgweDUzMzgwZDEzLCAweDlkOTViM2RmKSwgWDY0V29yZF9jcmVhdGUoMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSksIFg2NFdvcmRfY3JlYXRlKDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgpLCBYNjRXb3JkX2NyZWF0ZSgweDgxYzJjOTJlLCAweDQ3ZWRhZWU2KSwgWDY0V29yZF9jcmVhdGUoMHg5MjcyMmM4NSwgMHgxNDgyMzUzYiksIFg2NFdvcmRfY3JlYXRlKDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQpLCBYNjRXb3JkX2NyZWF0ZSgweGE4MWE2NjRiLCAweGJjNDIzMDAxKSwgWDY0V29yZF9jcmVhdGUoMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSksIFg2NFdvcmRfY3JlYXRlKDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzApLCBYNjRXb3JkX2NyZWF0ZSgweGQxOTJlODE5LCAweGQ2ZWY1MjE4KSwgWDY0V29yZF9jcmVhdGUoMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCksIFg2NFdvcmRfY3JlYXRlKDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEpLCBYNjRXb3JkX2NyZWF0ZSgweDEwNmFhMDcwLCAweDMyYmJkMWI4KSwgWDY0V29yZF9jcmVhdGUoMHgxOWE0YzExNiwgMHhiOGQyZDBjOCksIFg2NFdvcmRfY3JlYXRlKDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMpLCBYNjRXb3JkX2NyZWF0ZSgweDI3NDg3NzRjLCAweGRmOGVlYjk5KSwgWDY0V29yZF9jcmVhdGUoMHgzNGIwYmNiNSwgMHhlMTliNDhhOCksIFg2NFdvcmRfY3JlYXRlKDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMpLCBYNjRXb3JkX2NyZWF0ZSgweDRlZDhhYTRhLCAweGUzNDE4YWNiKSwgWDY0V29yZF9jcmVhdGUoMHg1YjljY2E0ZiwgMHg3NzYzZTM3MyksIFg2NFdvcmRfY3JlYXRlKDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMpLCBYNjRXb3JkX2NyZWF0ZSgweDc0OGY4MmVlLCAweDVkZWZiMmZjKSwgWDY0V29yZF9jcmVhdGUoMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCksIFg2NFdvcmRfY3JlYXRlKDB4ODRjODc4MTQsIDB4YTFmMGFiNzIpLCBYNjRXb3JkX2NyZWF0ZSgweDhjYzcwMjA4LCAweDFhNjQzOWVjKSwgWDY0V29yZF9jcmVhdGUoMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCksIFg2NFdvcmRfY3JlYXRlKDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTkpLCBYNjRXb3JkX2NyZWF0ZSgweGJlZjlhM2Y3LCAweGIyYzY3OTE1KSwgWDY0V29yZF9jcmVhdGUoMHhjNjcxNzhmMiwgMHhlMzcyNTMyYiksIFg2NFdvcmRfY3JlYXRlKDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMpLCBYNjRXb3JkX2NyZWF0ZSgweGQxODZiOGM3LCAweDIxYzBjMjA3KSwgWDY0V29yZF9jcmVhdGUoMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSksIFg2NFdvcmRfY3JlYXRlKDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgpLCBYNjRXb3JkX2NyZWF0ZSgweDA2ZjA2N2FhLCAweDcyMTc2ZmJhKSwgWDY0V29yZF9jcmVhdGUoMHgwYTYzN2RjNSwgMHhhMmM4OThhNiksIFg2NFdvcmRfY3JlYXRlKDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUpLCBYNjRXb3JkX2NyZWF0ZSgweDFiNzEwYjM1LCAweDEzMWM0NzFiKSwgWDY0V29yZF9jcmVhdGUoMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCksIFg2NFdvcmRfY3JlYXRlKDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMpLCBYNjRXb3JkX2NyZWF0ZSgweDNjOWViZTBhLCAweDE1YzliZWJjKSwgWDY0V29yZF9jcmVhdGUoMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyksIFg2NFdvcmRfY3JlYXRlKDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYpLCBYNjRXb3JkX2NyZWF0ZSgweDU5N2YyOTljLCAweGZjNjU3ZTJhKSwgWDY0V29yZF9jcmVhdGUoMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYyksIFg2NFdvcmRfY3JlYXRlKDB4NmM0NDE5OGMsIDB4NGE0NzU4MTcpXTsKCiAgICAgICAgICAvLyBSZXVzYWJsZSBvYmplY3RzCiAgICAgICAgICB2YXIgVyA9IFtdOwogICAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4MDsgaSsrKSB7CiAgICAgICAgICAgICAgV1tpXSA9IFg2NFdvcmRfY3JlYXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pKCk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTSEEtNTEyIGhhc2ggYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgU0hBNTEyID0gQ19hbGdvLlNIQTUxMiA9IEhhc2hlci5leHRlbmQoewogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHRoaXMuX2hhc2ggPSBuZXcgWDY0V29yZEFycmF5LmluaXQoW25ldyBYNjRXb3JkLmluaXQoMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCksIG5ldyBYNjRXb3JkLmluaXQoMHhiYjY3YWU4NSwgMHg4NGNhYTczYiksIG5ldyBYNjRXb3JkLmluaXQoMHgzYzZlZjM3MiwgMHhmZTk0ZjgyYiksIG5ldyBYNjRXb3JkLmluaXQoMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSksIG5ldyBYNjRXb3JkLmluaXQoMHg1MTBlNTI3ZiwgMHhhZGU2ODJkMSksIG5ldyBYNjRXb3JkLmluaXQoMHg5YjA1Njg4YywgMHgyYjNlNmMxZiksIG5ldyBYNjRXb3JkLmluaXQoMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YiksIG5ldyBYNjRXb3JkLmluaXQoMHg1YmUwY2QxOSwgMHgxMzdlMjE3OSldKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIEggPSB0aGlzLl9oYXNoLndvcmRzOwogICAgICAgICAgICAgIHZhciBIMCA9IEhbMF07CiAgICAgICAgICAgICAgdmFyIEgxID0gSFsxXTsKICAgICAgICAgICAgICB2YXIgSDIgPSBIWzJdOwogICAgICAgICAgICAgIHZhciBIMyA9IEhbM107CiAgICAgICAgICAgICAgdmFyIEg0ID0gSFs0XTsKICAgICAgICAgICAgICB2YXIgSDUgPSBIWzVdOwogICAgICAgICAgICAgIHZhciBINiA9IEhbNl07CiAgICAgICAgICAgICAgdmFyIEg3ID0gSFs3XTsKICAgICAgICAgICAgICB2YXIgSDBoID0gSDAuaGlnaDsKICAgICAgICAgICAgICB2YXIgSDBsID0gSDAubG93OwogICAgICAgICAgICAgIHZhciBIMWggPSBIMS5oaWdoOwogICAgICAgICAgICAgIHZhciBIMWwgPSBIMS5sb3c7CiAgICAgICAgICAgICAgdmFyIEgyaCA9IEgyLmhpZ2g7CiAgICAgICAgICAgICAgdmFyIEgybCA9IEgyLmxvdzsKICAgICAgICAgICAgICB2YXIgSDNoID0gSDMuaGlnaDsKICAgICAgICAgICAgICB2YXIgSDNsID0gSDMubG93OwogICAgICAgICAgICAgIHZhciBINGggPSBINC5oaWdoOwogICAgICAgICAgICAgIHZhciBINGwgPSBINC5sb3c7CiAgICAgICAgICAgICAgdmFyIEg1aCA9IEg1LmhpZ2g7CiAgICAgICAgICAgICAgdmFyIEg1bCA9IEg1LmxvdzsKICAgICAgICAgICAgICB2YXIgSDZoID0gSDYuaGlnaDsKICAgICAgICAgICAgICB2YXIgSDZsID0gSDYubG93OwogICAgICAgICAgICAgIHZhciBIN2ggPSBINy5oaWdoOwogICAgICAgICAgICAgIHZhciBIN2wgPSBINy5sb3c7CgogICAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzCiAgICAgICAgICAgICAgdmFyIGFoID0gSDBoOwogICAgICAgICAgICAgIHZhciBhbCA9IEgwbDsKICAgICAgICAgICAgICB2YXIgYmggPSBIMWg7CiAgICAgICAgICAgICAgdmFyIGJsID0gSDFsOwogICAgICAgICAgICAgIHZhciBjaCA9IEgyaDsKICAgICAgICAgICAgICB2YXIgY2wgPSBIMmw7CiAgICAgICAgICAgICAgdmFyIGRoID0gSDNoOwogICAgICAgICAgICAgIHZhciBkbCA9IEgzbDsKICAgICAgICAgICAgICB2YXIgZWggPSBINGg7CiAgICAgICAgICAgICAgdmFyIGVsID0gSDRsOwogICAgICAgICAgICAgIHZhciBmaCA9IEg1aDsKICAgICAgICAgICAgICB2YXIgZmwgPSBINWw7CiAgICAgICAgICAgICAgdmFyIGdoID0gSDZoOwogICAgICAgICAgICAgIHZhciBnbCA9IEg2bDsKICAgICAgICAgICAgICB2YXIgaGggPSBIN2g7CiAgICAgICAgICAgICAgdmFyIGhsID0gSDdsOwoKICAgICAgICAgICAgICAvLyBSb3VuZHMKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDgwOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBXaWw7CiAgICAgICAgICAgICAgICB2YXIgV2loOwoKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgICB2YXIgV2kgPSBXW2ldOwoKICAgICAgICAgICAgICAgIC8vIEV4dGVuZCBtZXNzYWdlCiAgICAgICAgICAgICAgICBpZiAoaSA8IDE2KSB7CiAgICAgICAgICAgICAgICAgIFdpaCA9IFdpLmhpZ2ggPSBNW29mZnNldCArIGkgKiAyXSB8IDA7CiAgICAgICAgICAgICAgICAgIFdpbCA9IFdpLmxvdyA9IE1bb2Zmc2V0ICsgaSAqIDIgKyAxXSB8IDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAvLyBHYW1tYTAKICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMHggPSBXW2kgLSAxNV07CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTB4aCA9IGdhbW1hMHguaGlnaDsKICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMHhsID0gZ2FtbWEweC5sb3c7CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTBoID0gKGdhbW1hMHhoID4+PiAxIHwgZ2FtbWEweGwgPDwgMzEpIF4gKGdhbW1hMHhoID4+PiA4IHwgZ2FtbWEweGwgPDwgMjQpIF4gZ2FtbWEweGggPj4+IDc7CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTBsID0gKGdhbW1hMHhsID4+PiAxIHwgZ2FtbWEweGggPDwgMzEpIF4gKGdhbW1hMHhsID4+PiA4IHwgZ2FtbWEweGggPDwgMjQpIF4gKGdhbW1hMHhsID4+PiA3IHwgZ2FtbWEweGggPDwgMjUpOwoKICAgICAgICAgICAgICAgICAgLy8gR2FtbWExCiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTF4ID0gV1tpIC0gMl07CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTF4aCA9IGdhbW1hMXguaGlnaDsKICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMXhsID0gZ2FtbWExeC5sb3c7CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTFoID0gKGdhbW1hMXhoID4+PiAxOSB8IGdhbW1hMXhsIDw8IDEzKSBeIChnYW1tYTF4aCA8PCAzIHwgZ2FtbWExeGwgPj4+IDI5KSBeIGdhbW1hMXhoID4+PiA2OwogICAgICAgICAgICAgICAgICB2YXIgZ2FtbWExbCA9IChnYW1tYTF4bCA+Pj4gMTkgfCBnYW1tYTF4aCA8PCAxMykgXiAoZ2FtbWExeGwgPDwgMyB8IGdhbW1hMXhoID4+PiAyOSkgXiAoZ2FtbWExeGwgPj4+IDYgfCBnYW1tYTF4aCA8PCAyNik7CgogICAgICAgICAgICAgICAgICAvLyBXW2ldID0gZ2FtbWEwICsgV1tpIC0gN10gKyBnYW1tYTEgKyBXW2kgLSAxNl0KICAgICAgICAgICAgICAgICAgdmFyIFdpNyA9IFdbaSAtIDddOwogICAgICAgICAgICAgICAgICB2YXIgV2k3aCA9IFdpNy5oaWdoOwogICAgICAgICAgICAgICAgICB2YXIgV2k3bCA9IFdpNy5sb3c7CiAgICAgICAgICAgICAgICAgIHZhciBXaTE2ID0gV1tpIC0gMTZdOwogICAgICAgICAgICAgICAgICB2YXIgV2kxNmggPSBXaTE2LmhpZ2g7CiAgICAgICAgICAgICAgICAgIHZhciBXaTE2bCA9IFdpMTYubG93OwogICAgICAgICAgICAgICAgICBXaWwgPSBnYW1tYTBsICsgV2k3bDsKICAgICAgICAgICAgICAgICAgV2loID0gZ2FtbWEwaCArIFdpN2ggKyAoV2lsID4+PiAwIDwgZ2FtbWEwbCA+Pj4gMCA/IDEgOiAwKTsKICAgICAgICAgICAgICAgICAgV2lsID0gV2lsICsgZ2FtbWExbDsKICAgICAgICAgICAgICAgICAgV2loID0gV2loICsgZ2FtbWExaCArIChXaWwgPj4+IDAgPCBnYW1tYTFsID4+PiAwID8gMSA6IDApOwogICAgICAgICAgICAgICAgICBXaWwgPSBXaWwgKyBXaTE2bDsKICAgICAgICAgICAgICAgICAgV2loID0gV2loICsgV2kxNmggKyAoV2lsID4+PiAwIDwgV2kxNmwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgICAgIFdpLmhpZ2ggPSBXaWg7CiAgICAgICAgICAgICAgICAgIFdpLmxvdyA9IFdpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBjaGggPSBlaCAmIGZoIF4gfmVoICYgZ2g7CiAgICAgICAgICAgICAgICB2YXIgY2hsID0gZWwgJiBmbCBeIH5lbCAmIGdsOwogICAgICAgICAgICAgICAgdmFyIG1hamggPSBhaCAmIGJoIF4gYWggJiBjaCBeIGJoICYgY2g7CiAgICAgICAgICAgICAgICB2YXIgbWFqbCA9IGFsICYgYmwgXiBhbCAmIGNsIF4gYmwgJiBjbDsKICAgICAgICAgICAgICAgIHZhciBzaWdtYTBoID0gKGFoID4+PiAyOCB8IGFsIDw8IDQpIF4gKGFoIDw8IDMwIHwgYWwgPj4+IDIpIF4gKGFoIDw8IDI1IHwgYWwgPj4+IDcpOwogICAgICAgICAgICAgICAgdmFyIHNpZ21hMGwgPSAoYWwgPj4+IDI4IHwgYWggPDwgNCkgXiAoYWwgPDwgMzAgfCBhaCA+Pj4gMikgXiAoYWwgPDwgMjUgfCBhaCA+Pj4gNyk7CiAgICAgICAgICAgICAgICB2YXIgc2lnbWExaCA9IChlaCA+Pj4gMTQgfCBlbCA8PCAxOCkgXiAoZWggPj4+IDE4IHwgZWwgPDwgMTQpIF4gKGVoIDw8IDIzIHwgZWwgPj4+IDkpOwogICAgICAgICAgICAgICAgdmFyIHNpZ21hMWwgPSAoZWwgPj4+IDE0IHwgZWggPDwgMTgpIF4gKGVsID4+PiAxOCB8IGVoIDw8IDE0KSBeIChlbCA8PCAyMyB8IGVoID4+PiA5KTsKCiAgICAgICAgICAgICAgICAvLyB0MSA9IGggKyBzaWdtYTEgKyBjaCArIEtbaV0gKyBXW2ldCiAgICAgICAgICAgICAgICB2YXIgS2kgPSBLW2ldOwogICAgICAgICAgICAgICAgdmFyIEtpaCA9IEtpLmhpZ2g7CiAgICAgICAgICAgICAgICB2YXIgS2lsID0gS2kubG93OwogICAgICAgICAgICAgICAgdmFyIHQxbCA9IGhsICsgc2lnbWExbDsKICAgICAgICAgICAgICAgIHZhciB0MWggPSBoaCArIHNpZ21hMWggKyAodDFsID4+PiAwIDwgaGwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgICB2YXIgdDFsID0gdDFsICsgY2hsOwogICAgICAgICAgICAgICAgdmFyIHQxaCA9IHQxaCArIGNoaCArICh0MWwgPj4+IDAgPCBjaGwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgICB2YXIgdDFsID0gdDFsICsgS2lsOwogICAgICAgICAgICAgICAgdmFyIHQxaCA9IHQxaCArIEtpaCArICh0MWwgPj4+IDAgPCBLaWwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgICB2YXIgdDFsID0gdDFsICsgV2lsOwogICAgICAgICAgICAgICAgdmFyIHQxaCA9IHQxaCArIFdpaCArICh0MWwgPj4+IDAgPCBXaWwgPj4+IDAgPyAxIDogMCk7CgogICAgICAgICAgICAgICAgLy8gdDIgPSBzaWdtYTAgKyBtYWoKICAgICAgICAgICAgICAgIHZhciB0MmwgPSBzaWdtYTBsICsgbWFqbDsKICAgICAgICAgICAgICAgIHZhciB0MmggPSBzaWdtYTBoICsgbWFqaCArICh0MmwgPj4+IDAgPCBzaWdtYTBsID4+PiAwID8gMSA6IDApOwoKICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSB3b3JraW5nIHZhcmlhYmxlcwogICAgICAgICAgICAgICAgaGggPSBnaDsKICAgICAgICAgICAgICAgIGhsID0gZ2w7CiAgICAgICAgICAgICAgICBnaCA9IGZoOwogICAgICAgICAgICAgICAgZ2wgPSBmbDsKICAgICAgICAgICAgICAgIGZoID0gZWg7CiAgICAgICAgICAgICAgICBmbCA9IGVsOwogICAgICAgICAgICAgICAgZWwgPSBkbCArIHQxbCB8IDA7CiAgICAgICAgICAgICAgICBlaCA9IGRoICsgdDFoICsgKGVsID4+PiAwIDwgZGwgPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICAgICAgZGggPSBjaDsKICAgICAgICAgICAgICAgIGRsID0gY2w7CiAgICAgICAgICAgICAgICBjaCA9IGJoOwogICAgICAgICAgICAgICAgY2wgPSBibDsKICAgICAgICAgICAgICAgIGJoID0gYWg7CiAgICAgICAgICAgICAgICBibCA9IGFsOwogICAgICAgICAgICAgICAgYWwgPSB0MWwgKyB0MmwgfCAwOwogICAgICAgICAgICAgICAgYWggPSB0MWggKyB0MmggKyAoYWwgPj4+IDAgPCB0MWwgPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gSW50ZXJtZWRpYXRlIGhhc2ggdmFsdWUKICAgICAgICAgICAgICBIMGwgPSBIMC5sb3cgPSBIMGwgKyBhbDsKICAgICAgICAgICAgICBIMC5oaWdoID0gSDBoICsgYWggKyAoSDBsID4+PiAwIDwgYWwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgSDFsID0gSDEubG93ID0gSDFsICsgYmw7CiAgICAgICAgICAgICAgSDEuaGlnaCA9IEgxaCArIGJoICsgKEgxbCA+Pj4gMCA8IGJsID4+PiAwID8gMSA6IDApOwogICAgICAgICAgICAgIEgybCA9IEgyLmxvdyA9IEgybCArIGNsOwogICAgICAgICAgICAgIEgyLmhpZ2ggPSBIMmggKyBjaCArIChIMmwgPj4+IDAgPCBjbCA+Pj4gMCA/IDEgOiAwKTsKICAgICAgICAgICAgICBIM2wgPSBIMy5sb3cgPSBIM2wgKyBkbDsKICAgICAgICAgICAgICBIMy5oaWdoID0gSDNoICsgZGggKyAoSDNsID4+PiAwIDwgZGwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgSDRsID0gSDQubG93ID0gSDRsICsgZWw7CiAgICAgICAgICAgICAgSDQuaGlnaCA9IEg0aCArIGVoICsgKEg0bCA+Pj4gMCA8IGVsID4+PiAwID8gMSA6IDApOwogICAgICAgICAgICAgIEg1bCA9IEg1LmxvdyA9IEg1bCArIGZsOwogICAgICAgICAgICAgIEg1LmhpZ2ggPSBINWggKyBmaCArIChINWwgPj4+IDAgPCBmbCA+Pj4gMCA/IDEgOiAwKTsKICAgICAgICAgICAgICBINmwgPSBINi5sb3cgPSBINmwgKyBnbDsKICAgICAgICAgICAgICBINi5oaWdoID0gSDZoICsgZ2ggKyAoSDZsID4+PiAwIDwgZ2wgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgSDdsID0gSDcubG93ID0gSDdsICsgaGw7CiAgICAgICAgICAgICAgSDcuaGlnaCA9IEg3aCArIGhoICsgKEg3bCA+Pj4gMCA8IGhsID4+PiAwID8gMSA6IDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTsKICAgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3JkczsKICAgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbCA9IHRoaXMuX25EYXRhQnl0ZXMgKiA4OwogICAgICAgICAgICAgIHZhciBuQml0c0xlZnQgPSBkYXRhLnNpZ0J5dGVzICogODsKCiAgICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmcKICAgICAgICAgICAgICBkYXRhV29yZHNbbkJpdHNMZWZ0ID4+PiA1XSB8PSAweDgwIDw8IDI0IC0gbkJpdHNMZWZ0ICUgMzI7CiAgICAgICAgICAgICAgZGF0YVdvcmRzWyhuQml0c0xlZnQgKyAxMjggPj4+IDEwIDw8IDUpICsgMzBdID0gTWF0aC5mbG9vcihuQml0c1RvdGFsIC8gMHgxMDAwMDAwMDApOwogICAgICAgICAgICAgIGRhdGFXb3Jkc1sobkJpdHNMZWZ0ICsgMTI4ID4+PiAxMCA8PCA1KSArIDMxXSA9IG5CaXRzVG90YWw7CiAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGRhdGFXb3Jkcy5sZW5ndGggKiA0OwoKICAgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2NrcwogICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTsKCiAgICAgICAgICAgICAgLy8gQ29udmVydCBoYXNoIHRvIDMyLWJpdCB3b3JkIGFycmF5IGJlZm9yZSByZXR1cm5pbmcKICAgICAgICAgICAgICB2YXIgaGFzaCA9IHRoaXMuX2hhc2gudG9YMzIoKTsKCiAgICAgICAgICAgICAgLy8gUmV0dXJuIGZpbmFsIGNvbXB1dGVkIGhhc2gKICAgICAgICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgICBjbG9uZS5faGFzaCA9IHRoaXMuX2hhc2guY2xvbmUoKTsKICAgICAgICAgICAgICByZXR1cm4gY2xvbmU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGJsb2NrU2l6ZTogMTAyNCAvIDMyCiAgICAgICAgICB9KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGhhc2guCiAgICAgICAgICAgKgogICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICoKICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgKgogICAgICAgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBNTEyKCdtZXNzYWdlJyk7CiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEE1MTIod29yZEFycmF5KTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5TSEE1MTIgPSBIYXNoZXIuX2NyZWF0ZUhlbHBlcihTSEE1MTIpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBDcnlwdG9KUy5IbWFjU0hBNTEyKG1lc3NhZ2UsIGtleSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuSG1hY1NIQTUxMiA9IEhhc2hlci5fY3JlYXRlSG1hY0hlbHBlcihTSEE1MTIpOwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlNIQTUxMjsKICAgICAgfSk7CiAgICB9KShzaGE1MTIkMSk7CiAgICByZXR1cm4gc2hhNTEyJDEuZXhwb3J0czsKICB9CgogIHZhciBzaGEzODQkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBzaGEzODQgPSBzaGEzODQkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFNoYTM4NDsKICBmdW5jdGlvbiByZXF1aXJlU2hhMzg0KCkgewogICAgaWYgKGhhc1JlcXVpcmVkU2hhMzg0KSByZXR1cm4gc2hhMzg0JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkU2hhMzg0ID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZVg2NENvcmUoKSwgcmVxdWlyZVNoYTUxMigpKTsKICAgICAgICB9CiAgICAgIH0pKHNoYTM4NCwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX3g2NCA9IEMueDY0OwogICAgICAgICAgdmFyIFg2NFdvcmQgPSBDX3g2NC5Xb3JkOwogICAgICAgICAgdmFyIFg2NFdvcmRBcnJheSA9IENfeDY0LldvcmRBcnJheTsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CiAgICAgICAgICB2YXIgU0hBNTEyID0gQ19hbGdvLlNIQTUxMjsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNIQS0zODQgaGFzaCBhbGdvcml0aG0uCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBTSEEzODQgPSBDX2FsZ28uU0hBMzg0ID0gU0hBNTEyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBYNjRXb3JkQXJyYXkuaW5pdChbbmV3IFg2NFdvcmQuaW5pdCgweGNiYmI5ZDVkLCAweGMxMDU5ZWQ4KSwgbmV3IFg2NFdvcmQuaW5pdCgweDYyOWEyOTJhLCAweDM2N2NkNTA3KSwgbmV3IFg2NFdvcmQuaW5pdCgweDkxNTkwMTVhLCAweDMwNzBkZDE3KSwgbmV3IFg2NFdvcmQuaW5pdCgweDE1MmZlY2Q4LCAweGY3MGU1OTM5KSwgbmV3IFg2NFdvcmQuaW5pdCgweDY3MzMyNjY3LCAweGZmYzAwYjMxKSwgbmV3IFg2NFdvcmQuaW5pdCgweDhlYjQ0YTg3LCAweDY4NTgxNTExKSwgbmV3IFg2NFdvcmQuaW5pdCgweGRiMGMyZTBkLCAweDY0Zjk4ZmE3KSwgbmV3IFg2NFdvcmQuaW5pdCgweDQ3YjU0ODFkLCAweGJlZmE0ZmE0KV0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBoYXNoID0gU0hBNTEyLl9kb0ZpbmFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgaGFzaC5zaWdCeXRlcyAtPSAxNjsKICAgICAgICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTM4NCgnbWVzc2FnZScpOwogICAgICAgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMzg0KHdvcmRBcnJheSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuU0hBMzg0ID0gU0hBNTEyLl9jcmVhdGVIZWxwZXIoU0hBMzg0KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC4KICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICoKICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgKgogICAgICAgICAgICogICAgIHZhciBobWFjID0gQ3J5cHRvSlMuSG1hY1NIQTM4NChtZXNzYWdlLCBrZXkpOwogICAgICAgICAgICovCiAgICAgICAgICBDLkhtYWNTSEEzODQgPSBTSEE1MTIuX2NyZWF0ZUhtYWNIZWxwZXIoU0hBMzg0KTsKICAgICAgICB9KSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5TSEEzODQ7CiAgICAgIH0pOwogICAgfSkoc2hhMzg0JDEpOwogICAgcmV0dXJuIHNoYTM4NCQxLmV4cG9ydHM7CiAgfQoKICB2YXIgc2hhMyQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIHNoYTMgPSBzaGEzJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRTaGEzOwogIGZ1bmN0aW9uIHJlcXVpcmVTaGEzKCkgewogICAgaWYgKGhhc1JlcXVpcmVkU2hhMykgcmV0dXJuIHNoYTMkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRTaGEzID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZVg2NENvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShzaGEzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAoZnVuY3Rpb24gKE1hdGgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKICAgICAgICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7CiAgICAgICAgICB2YXIgQ194NjQgPSBDLng2NDsKICAgICAgICAgIHZhciBYNjRXb3JkID0gQ194NjQuV29yZDsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CgogICAgICAgICAgLy8gQ29uc3RhbnRzIHRhYmxlcwogICAgICAgICAgdmFyIFJIT19PRkZTRVRTID0gW107CiAgICAgICAgICB2YXIgUElfSU5ERVhFUyA9IFtdOwogICAgICAgICAgdmFyIFJPVU5EX0NPTlNUQU5UUyA9IFtdOwoKICAgICAgICAgIC8vIENvbXB1dGUgQ29uc3RhbnRzCiAgICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAvLyBDb21wdXRlIHJobyBvZmZzZXQgY29uc3RhbnRzCiAgICAgICAgICAgIHZhciB4ID0gMSwKICAgICAgICAgICAgICB5ID0gMDsKICAgICAgICAgICAgZm9yICh2YXIgdCA9IDA7IHQgPCAyNDsgdCsrKSB7CiAgICAgICAgICAgICAgUkhPX09GRlNFVFNbeCArIDUgKiB5XSA9ICh0ICsgMSkgKiAodCArIDIpIC8gMiAlIDY0OwogICAgICAgICAgICAgIHZhciBuZXdYID0geSAlIDU7CiAgICAgICAgICAgICAgdmFyIG5ld1kgPSAoMiAqIHggKyAzICogeSkgJSA1OwogICAgICAgICAgICAgIHggPSBuZXdYOwogICAgICAgICAgICAgIHkgPSBuZXdZOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDb21wdXRlIHBpIGluZGV4IGNvbnN0YW50cwogICAgICAgICAgICBmb3IgKHZhciB4ID0gMDsgeCA8IDU7IHgrKykgewogICAgICAgICAgICAgIGZvciAodmFyIHkgPSAwOyB5IDwgNTsgeSsrKSB7CiAgICAgICAgICAgICAgICBQSV9JTkRFWEVTW3ggKyA1ICogeV0gPSB5ICsgKDIgKiB4ICsgMyAqIHkpICUgNSAqIDU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDb21wdXRlIHJvdW5kIGNvbnN0YW50cwogICAgICAgICAgICB2YXIgTEZTUiA9IDB4MDE7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjQ7IGkrKykgewogICAgICAgICAgICAgIHZhciByb3VuZENvbnN0YW50TXN3ID0gMDsKICAgICAgICAgICAgICB2YXIgcm91bmRDb25zdGFudExzdyA9IDA7CiAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCA3OyBqKyspIHsKICAgICAgICAgICAgICAgIGlmIChMRlNSICYgMHgwMSkgewogICAgICAgICAgICAgICAgICB2YXIgYml0UG9zaXRpb24gPSAoMSA8PCBqKSAtIDE7CiAgICAgICAgICAgICAgICAgIGlmIChiaXRQb3NpdGlvbiA8IDMyKSB7CiAgICAgICAgICAgICAgICAgICAgcm91bmRDb25zdGFudExzdyBePSAxIDw8IGJpdFBvc2l0aW9uOwogICAgICAgICAgICAgICAgICB9IGVsc2UgLyogaWYgKGJpdFBvc2l0aW9uID49IDMyKSAqL3sKICAgICAgICAgICAgICAgICAgICAgIHJvdW5kQ29uc3RhbnRNc3cgXj0gMSA8PCBiaXRQb3NpdGlvbiAtIDMyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBDb21wdXRlIG5leHQgTEZTUgogICAgICAgICAgICAgICAgaWYgKExGU1IgJiAweDgwKSB7CiAgICAgICAgICAgICAgICAgIC8vIFByaW1pdGl2ZSBwb2x5bm9taWFsIG92ZXIgR0YoMik6IHheOCArIHheNiArIHheNSArIHheNCArIDEKICAgICAgICAgICAgICAgICAgTEZTUiA9IExGU1IgPDwgMSBeIDB4NzE7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBMRlNSIDw8PSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBST1VORF9DT05TVEFOVFNbaV0gPSBYNjRXb3JkLmNyZWF0ZShyb3VuZENvbnN0YW50TXN3LCByb3VuZENvbnN0YW50THN3KTsKICAgICAgICAgICAgfQogICAgICAgICAgfSkoKTsKCiAgICAgICAgICAvLyBSZXVzYWJsZSBvYmplY3RzIGZvciB0ZW1wb3JhcnkgdmFsdWVzCiAgICAgICAgICB2YXIgVCA9IFtdOwogICAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTsgaSsrKSB7CiAgICAgICAgICAgICAgVFtpXSA9IFg2NFdvcmQuY3JlYXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pKCk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTSEEtMyBoYXNoIGFsZ29yaXRobS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIFNIQTMgPSBDX2FsZ28uU0hBMyA9IEhhc2hlci5leHRlbmQoewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gb3V0cHV0TGVuZ3RoCiAgICAgICAgICAgICAqICAgVGhlIGRlc2lyZWQgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIG91dHB1dCBoYXNoLgogICAgICAgICAgICAgKiAgIE9ubHkgdmFsdWVzIHBlcm1pdHRlZCBhcmU6IDIyNCwgMjU2LCAzODQsIDUxMi4KICAgICAgICAgICAgICogICBEZWZhdWx0OiA1MTIKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNmZzogSGFzaGVyLmNmZy5leHRlbmQoewogICAgICAgICAgICAgIG91dHB1dExlbmd0aDogNTEyCiAgICAgICAgICAgIH0pLAogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBzdGF0ZSA9IHRoaXMuX3N0YXRlID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTsgaSsrKSB7CiAgICAgICAgICAgICAgICBzdGF0ZVtpXSA9IG5ldyBYNjRXb3JkLmluaXQoKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgdGhpcy5ibG9ja1NpemUgPSAoMTYwMCAtIDIgKiB0aGlzLmNmZy5vdXRwdXRMZW5ndGgpIC8gMzI7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9kb1Byb2Nlc3NCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBzdGF0ZSA9IHRoaXMuX3N0YXRlOwogICAgICAgICAgICAgIHZhciBuQmxvY2tTaXplTGFuZXMgPSB0aGlzLmJsb2NrU2l6ZSAvIDI7CgogICAgICAgICAgICAgIC8vIEFic29yYgogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbkJsb2NrU2l6ZUxhbmVzOyBpKyspIHsKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgdmFyIE0yaSA9IE1bb2Zmc2V0ICsgMiAqIGldOwogICAgICAgICAgICAgICAgdmFyIE0yaTEgPSBNW29mZnNldCArIDIgKiBpICsgMV07CgogICAgICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW4KICAgICAgICAgICAgICAgIE0yaSA9IChNMmkgPDwgOCB8IE0yaSA+Pj4gMjQpICYgMHgwMGZmMDBmZiB8IChNMmkgPDwgMjQgfCBNMmkgPj4+IDgpICYgMHhmZjAwZmYwMDsKICAgICAgICAgICAgICAgIE0yaTEgPSAoTTJpMSA8PCA4IHwgTTJpMSA+Pj4gMjQpICYgMHgwMGZmMDBmZiB8IChNMmkxIDw8IDI0IHwgTTJpMSA+Pj4gOCkgJiAweGZmMDBmZjAwOwoKICAgICAgICAgICAgICAgIC8vIEFic29yYiBtZXNzYWdlIGludG8gc3RhdGUKICAgICAgICAgICAgICAgIHZhciBsYW5lID0gc3RhdGVbaV07CiAgICAgICAgICAgICAgICBsYW5lLmhpZ2ggXj0gTTJpMTsKICAgICAgICAgICAgICAgIGxhbmUubG93IF49IE0yaTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFJvdW5kcwogICAgICAgICAgICAgIGZvciAodmFyIHJvdW5kID0gMDsgcm91bmQgPCAyNDsgcm91bmQrKykgewogICAgICAgICAgICAgICAgLy8gVGhldGEKICAgICAgICAgICAgICAgIGZvciAodmFyIHggPSAwOyB4IDwgNTsgeCsrKSB7CiAgICAgICAgICAgICAgICAgIC8vIE1peCBjb2x1bW4gbGFuZXMKICAgICAgICAgICAgICAgICAgdmFyIHRNc3cgPSAwLAogICAgICAgICAgICAgICAgICAgIHRMc3cgPSAwOwogICAgICAgICAgICAgICAgICBmb3IgKHZhciB5ID0gMDsgeSA8IDU7IHkrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBsYW5lID0gc3RhdGVbeCArIDUgKiB5XTsKICAgICAgICAgICAgICAgICAgICB0TXN3IF49IGxhbmUuaGlnaDsKICAgICAgICAgICAgICAgICAgICB0THN3IF49IGxhbmUubG93OwogICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAvLyBUZW1wb3JhcnkgdmFsdWVzCiAgICAgICAgICAgICAgICAgIHZhciBUeCA9IFRbeF07CiAgICAgICAgICAgICAgICAgIFR4LmhpZ2ggPSB0TXN3OwogICAgICAgICAgICAgICAgICBUeC5sb3cgPSB0THN3OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yICh2YXIgeCA9IDA7IHggPCA1OyB4KyspIHsKICAgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgICAgIHZhciBUeDQgPSBUWyh4ICsgNCkgJSA1XTsKICAgICAgICAgICAgICAgICAgdmFyIFR4MSA9IFRbKHggKyAxKSAlIDVdOwogICAgICAgICAgICAgICAgICB2YXIgVHgxTXN3ID0gVHgxLmhpZ2g7CiAgICAgICAgICAgICAgICAgIHZhciBUeDFMc3cgPSBUeDEubG93OwoKICAgICAgICAgICAgICAgICAgLy8gTWl4IHN1cnJvdW5kaW5nIGNvbHVtbnMKICAgICAgICAgICAgICAgICAgdmFyIHRNc3cgPSBUeDQuaGlnaCBeIChUeDFNc3cgPDwgMSB8IFR4MUxzdyA+Pj4gMzEpOwogICAgICAgICAgICAgICAgICB2YXIgdExzdyA9IFR4NC5sb3cgXiAoVHgxTHN3IDw8IDEgfCBUeDFNc3cgPj4+IDMxKTsKICAgICAgICAgICAgICAgICAgZm9yICh2YXIgeSA9IDA7IHkgPCA1OyB5KyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbGFuZSA9IHN0YXRlW3ggKyA1ICogeV07CiAgICAgICAgICAgICAgICAgICAgbGFuZS5oaWdoIF49IHRNc3c7CiAgICAgICAgICAgICAgICAgICAgbGFuZS5sb3cgXj0gdExzdzsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFJobyBQaQogICAgICAgICAgICAgICAgZm9yICh2YXIgbGFuZUluZGV4ID0gMTsgbGFuZUluZGV4IDwgMjU7IGxhbmVJbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgIHZhciB0TXN3OwogICAgICAgICAgICAgICAgICB2YXIgdExzdzsKCiAgICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgICB2YXIgbGFuZSA9IHN0YXRlW2xhbmVJbmRleF07CiAgICAgICAgICAgICAgICAgIHZhciBsYW5lTXN3ID0gbGFuZS5oaWdoOwogICAgICAgICAgICAgICAgICB2YXIgbGFuZUxzdyA9IGxhbmUubG93OwogICAgICAgICAgICAgICAgICB2YXIgcmhvT2Zmc2V0ID0gUkhPX09GRlNFVFNbbGFuZUluZGV4XTsKCiAgICAgICAgICAgICAgICAgIC8vIFJvdGF0ZSBsYW5lcwogICAgICAgICAgICAgICAgICBpZiAocmhvT2Zmc2V0IDwgMzIpIHsKICAgICAgICAgICAgICAgICAgICB0TXN3ID0gbGFuZU1zdyA8PCByaG9PZmZzZXQgfCBsYW5lTHN3ID4+PiAzMiAtIHJob09mZnNldDsKICAgICAgICAgICAgICAgICAgICB0THN3ID0gbGFuZUxzdyA8PCByaG9PZmZzZXQgfCBsYW5lTXN3ID4+PiAzMiAtIHJob09mZnNldDsKICAgICAgICAgICAgICAgICAgfSBlbHNlIC8qIGlmIChyaG9PZmZzZXQgPj0gMzIpICovewogICAgICAgICAgICAgICAgICAgICAgdE1zdyA9IGxhbmVMc3cgPDwgcmhvT2Zmc2V0IC0gMzIgfCBsYW5lTXN3ID4+PiA2NCAtIHJob09mZnNldDsKICAgICAgICAgICAgICAgICAgICAgIHRMc3cgPSBsYW5lTXN3IDw8IHJob09mZnNldCAtIDMyIHwgbGFuZUxzdyA+Pj4gNjQgLSByaG9PZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgLy8gVHJhbnNwb3NlIGxhbmVzCiAgICAgICAgICAgICAgICAgIHZhciBUUGlMYW5lID0gVFtQSV9JTkRFWEVTW2xhbmVJbmRleF1dOwogICAgICAgICAgICAgICAgICBUUGlMYW5lLmhpZ2ggPSB0TXN3OwogICAgICAgICAgICAgICAgICBUUGlMYW5lLmxvdyA9IHRMc3c7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gUmhvIHBpIGF0IHggPSB5ID0gMAogICAgICAgICAgICAgICAgdmFyIFQwID0gVFswXTsKICAgICAgICAgICAgICAgIHZhciBzdGF0ZTAgPSBzdGF0ZVswXTsKICAgICAgICAgICAgICAgIFQwLmhpZ2ggPSBzdGF0ZTAuaGlnaDsKICAgICAgICAgICAgICAgIFQwLmxvdyA9IHN0YXRlMC5sb3c7CgogICAgICAgICAgICAgICAgLy8gQ2hpCiAgICAgICAgICAgICAgICBmb3IgKHZhciB4ID0gMDsgeCA8IDU7IHgrKykgewogICAgICAgICAgICAgICAgICBmb3IgKHZhciB5ID0gMDsgeSA8IDU7IHkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgICAgIHZhciBsYW5lSW5kZXggPSB4ICsgNSAqIHk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGxhbmUgPSBzdGF0ZVtsYW5lSW5kZXhdOwogICAgICAgICAgICAgICAgICAgIHZhciBUTGFuZSA9IFRbbGFuZUluZGV4XTsKICAgICAgICAgICAgICAgICAgICB2YXIgVHgxTGFuZSA9IFRbKHggKyAxKSAlIDUgKyA1ICogeV07CiAgICAgICAgICAgICAgICAgICAgdmFyIFR4MkxhbmUgPSBUWyh4ICsgMikgJSA1ICsgNSAqIHldOwoKICAgICAgICAgICAgICAgICAgICAvLyBNaXggcm93cwogICAgICAgICAgICAgICAgICAgIGxhbmUuaGlnaCA9IFRMYW5lLmhpZ2ggXiB+VHgxTGFuZS5oaWdoICYgVHgyTGFuZS5oaWdoOwogICAgICAgICAgICAgICAgICAgIGxhbmUubG93ID0gVExhbmUubG93IF4gflR4MUxhbmUubG93ICYgVHgyTGFuZS5sb3c7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBJb3RhCiAgICAgICAgICAgICAgICB2YXIgbGFuZSA9IHN0YXRlWzBdOwogICAgICAgICAgICAgICAgdmFyIHJvdW5kQ29uc3RhbnQgPSBST1VORF9DT05TVEFOVFNbcm91bmRdOwogICAgICAgICAgICAgICAgbGFuZS5oaWdoIF49IHJvdW5kQ29uc3RhbnQuaGlnaDsKICAgICAgICAgICAgICAgIGxhbmUubG93IF49IHJvdW5kQ29uc3RhbnQubG93OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7CiAgICAgICAgICAgICAgdGhpcy5fbkRhdGFCeXRlcyAqIDg7CiAgICAgICAgICAgICAgdmFyIG5CaXRzTGVmdCA9IGRhdGEuc2lnQnl0ZXMgKiA4OwogICAgICAgICAgICAgIHZhciBibG9ja1NpemVCaXRzID0gdGhpcy5ibG9ja1NpemUgKiAzMjsKCiAgICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmcKICAgICAgICAgICAgICBkYXRhV29yZHNbbkJpdHNMZWZ0ID4+PiA1XSB8PSAweDEgPDwgMjQgLSBuQml0c0xlZnQgJSAzMjsKICAgICAgICAgICAgICBkYXRhV29yZHNbKE1hdGguY2VpbCgobkJpdHNMZWZ0ICsgMSkgLyBibG9ja1NpemVCaXRzKSAqIGJsb2NrU2l6ZUJpdHMgPj4+IDUpIC0gMV0gfD0gMHg4MDsKICAgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzID0gZGF0YVdvcmRzLmxlbmd0aCAqIDQ7CgogICAgICAgICAgICAgIC8vIEhhc2ggZmluYWwgYmxvY2tzCiAgICAgICAgICAgICAgdGhpcy5fcHJvY2VzcygpOwoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgc3RhdGUgPSB0aGlzLl9zdGF0ZTsKICAgICAgICAgICAgICB2YXIgb3V0cHV0TGVuZ3RoQnl0ZXMgPSB0aGlzLmNmZy5vdXRwdXRMZW5ndGggLyA4OwogICAgICAgICAgICAgIHZhciBvdXRwdXRMZW5ndGhMYW5lcyA9IG91dHB1dExlbmd0aEJ5dGVzIC8gODsKCiAgICAgICAgICAgICAgLy8gU3F1ZWV6ZQogICAgICAgICAgICAgIHZhciBoYXNoV29yZHMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG91dHB1dExlbmd0aExhbmVzOyBpKyspIHsKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgdmFyIGxhbmUgPSBzdGF0ZVtpXTsKICAgICAgICAgICAgICAgIHZhciBsYW5lTXN3ID0gbGFuZS5oaWdoOwogICAgICAgICAgICAgICAgdmFyIGxhbmVMc3cgPSBsYW5lLmxvdzsKCiAgICAgICAgICAgICAgICAvLyBTd2FwIGVuZGlhbgogICAgICAgICAgICAgICAgbGFuZU1zdyA9IChsYW5lTXN3IDw8IDggfCBsYW5lTXN3ID4+PiAyNCkgJiAweDAwZmYwMGZmIHwgKGxhbmVNc3cgPDwgMjQgfCBsYW5lTXN3ID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgICBsYW5lTHN3ID0gKGxhbmVMc3cgPDwgOCB8IGxhbmVMc3cgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAobGFuZUxzdyA8PCAyNCB8IGxhbmVMc3cgPj4+IDgpICYgMHhmZjAwZmYwMDsKCiAgICAgICAgICAgICAgICAvLyBTcXVlZXplIHN0YXRlIHRvIHJldHJpZXZlIGhhc2gKICAgICAgICAgICAgICAgIGhhc2hXb3Jkcy5wdXNoKGxhbmVMc3cpOwogICAgICAgICAgICAgICAgaGFzaFdvcmRzLnB1c2gobGFuZU1zdyk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaAogICAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQoaGFzaFdvcmRzLCBvdXRwdXRMZW5ndGhCeXRlcyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdmFyIGNsb25lID0gSGFzaGVyLmNsb25lLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgdmFyIHN0YXRlID0gY2xvbmUuX3N0YXRlID0gdGhpcy5fc3RhdGUuc2xpY2UoMCk7CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTsgaSsrKSB7CiAgICAgICAgICAgICAgICBzdGF0ZVtpXSA9IHN0YXRlW2ldLmNsb25lKCk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTMoJ21lc3NhZ2UnKTsKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTMod29yZEFycmF5KTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5TSEEzID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoU0hBMyk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNTSEEzKG1lc3NhZ2UsIGtleSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuSG1hY1NIQTMgPSBIYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoU0hBMyk7CiAgICAgICAgfSkoTWF0aCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlNIQTM7CiAgICAgIH0pOwogICAgfSkoc2hhMyQxKTsKICAgIHJldHVybiBzaGEzJDEuZXhwb3J0czsKICB9CgogIHZhciByaXBlbWQxNjAkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciByaXBlbWQxNjAgPSByaXBlbWQxNjAkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFJpcGVtZDE2MDsKICBmdW5jdGlvbiByZXF1aXJlUmlwZW1kMTYwKCkgewogICAgaWYgKGhhc1JlcXVpcmVkUmlwZW1kMTYwKSByZXR1cm4gcmlwZW1kMTYwJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUmlwZW1kMTYwID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHJpcGVtZDE2MCwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgLyoqIEBwcmVzZXJ2ZQogICAgICAgIChjKSAyMDEyIGJ5IEPDqWRyaWMgTWVzbmlsLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogICAgICAgIAlSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6CiAgICAgICAgCSAgICAtIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICAgICAgICAgICAgLSBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCiAgICAgICAgCVRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAgICAgICAgKi8KCiAgICAgICAgKGZ1bmN0aW9uIChNYXRoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyOwogICAgICAgICAgdmFyIENfYWxnbyA9IEMuYWxnbzsKCiAgICAgICAgICAvLyBDb25zdGFudHMgdGFibGUKICAgICAgICAgIHZhciBfemwgPSBXb3JkQXJyYXkuY3JlYXRlKFswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LCA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LCAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLCAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLCA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXSk7CiAgICAgICAgICB2YXIgX3pyID0gV29yZEFycmF5LmNyZWF0ZShbNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMiwgNiwgMTEsIDMsIDcsIDAsIDEzLCA1LCAxMCwgMTQsIDE1LCA4LCAxMiwgNCwgOSwgMSwgMiwgMTUsIDUsIDEsIDMsIDcsIDE0LCA2LCA5LCAxMSwgOCwgMTIsIDIsIDEwLCAwLCA0LCAxMywgOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNCwgMTIsIDE1LCAxMCwgNCwgMSwgNSwgOCwgNywgNiwgMiwgMTMsIDE0LCAwLCAzLCA5LCAxMV0pOwogICAgICAgICAgdmFyIF9zbCA9IFdvcmRBcnJheS5jcmVhdGUoWzExLCAxNCwgMTUsIDEyLCA1LCA4LCA3LCA5LCAxMSwgMTMsIDE0LCAxNSwgNiwgNywgOSwgOCwgNywgNiwgOCwgMTMsIDExLCA5LCA3LCAxNSwgNywgMTIsIDE1LCA5LCAxMSwgNywgMTMsIDEyLCAxMSwgMTMsIDYsIDcsIDE0LCA5LCAxMywgMTUsIDE0LCA4LCAxMywgNiwgNSwgMTIsIDcsIDUsIDExLCAxMiwgMTQsIDE1LCAxNCwgMTUsIDksIDgsIDksIDE0LCA1LCA2LCA4LCA2LCA1LCAxMiwgOSwgMTUsIDUsIDExLCA2LCA4LCAxMywgMTIsIDUsIDEyLCAxMywgMTQsIDExLCA4LCA1LCA2XSk7CiAgICAgICAgICB2YXIgX3NyID0gV29yZEFycmF5LmNyZWF0ZShbOCwgOSwgOSwgMTEsIDEzLCAxNSwgMTUsIDUsIDcsIDcsIDgsIDExLCAxNCwgMTQsIDEyLCA2LCA5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTEsIDksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNSwgMTUsIDUsIDgsIDExLCAxNCwgMTQsIDYsIDE0LCA2LCA5LCAxMiwgOSwgMTIsIDUsIDE1LCA4LCA4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFdKTsKICAgICAgICAgIHZhciBfaGwgPSBXb3JkQXJyYXkuY3JlYXRlKFsweDAwMDAwMDAwLCAweDVBODI3OTk5LCAweDZFRDlFQkExLCAweDhGMUJCQ0RDLCAweEE5NTNGRDRFXSk7CiAgICAgICAgICB2YXIgX2hyID0gV29yZEFycmF5LmNyZWF0ZShbMHg1MEEyOEJFNiwgMHg1QzRERDEyNCwgMHg2RDcwM0VGMywgMHg3QTZENzZFOSwgMHgwMDAwMDAwMF0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogUklQRU1EMTYwIGhhc2ggYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgUklQRU1EMTYwID0gQ19hbGdvLlJJUEVNRDE2MCA9IEhhc2hlci5leHRlbmQoewogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHRoaXMuX2hhc2ggPSBXb3JkQXJyYXkuY3JlYXRlKFsweDY3NDUyMzAxLCAweEVGQ0RBQjg5LCAweDk4QkFEQ0ZFLCAweDEwMzI1NDc2LCAweEMzRDJFMUYwXSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9kb1Byb2Nlc3NCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkgewogICAgICAgICAgICAgIC8vIFN3YXAgZW5kaWFuCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7CiAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICAgIHZhciBvZmZzZXRfaSA9IG9mZnNldCArIGk7CiAgICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfaSA9IE1bb2Zmc2V0X2ldOwoKICAgICAgICAgICAgICAgIC8vIFN3YXAKICAgICAgICAgICAgICAgIE1bb2Zmc2V0X2ldID0gKE1fb2Zmc2V0X2kgPDwgOCB8IE1fb2Zmc2V0X2kgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoTV9vZmZzZXRfaSA8PCAyNCB8IE1fb2Zmc2V0X2kgPj4+IDgpICYgMHhmZjAwZmYwMDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgSCA9IHRoaXMuX2hhc2gud29yZHM7CiAgICAgICAgICAgICAgdmFyIGhsID0gX2hsLndvcmRzOwogICAgICAgICAgICAgIHZhciBociA9IF9oci53b3JkczsKICAgICAgICAgICAgICB2YXIgemwgPSBfemwud29yZHM7CiAgICAgICAgICAgICAgdmFyIHpyID0gX3pyLndvcmRzOwogICAgICAgICAgICAgIHZhciBzbCA9IF9zbC53b3JkczsKICAgICAgICAgICAgICB2YXIgc3IgPSBfc3Iud29yZHM7CgogICAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzCiAgICAgICAgICAgICAgdmFyIGFsLCBibCwgY2wsIGRsLCBlbDsKICAgICAgICAgICAgICB2YXIgYXIsIGJyLCBjciwgZHIsIGVyOwogICAgICAgICAgICAgIGFyID0gYWwgPSBIWzBdOwogICAgICAgICAgICAgIGJyID0gYmwgPSBIWzFdOwogICAgICAgICAgICAgIGNyID0gY2wgPSBIWzJdOwogICAgICAgICAgICAgIGRyID0gZGwgPSBIWzNdOwogICAgICAgICAgICAgIGVyID0gZWwgPSBIWzRdOwogICAgICAgICAgICAgIC8vIENvbXB1dGF0aW9uCiAgICAgICAgICAgICAgdmFyIHQ7CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4MDsgaSArPSAxKSB7CiAgICAgICAgICAgICAgICB0ID0gYWwgKyBNW29mZnNldCArIHpsW2ldXSB8IDA7CiAgICAgICAgICAgICAgICBpZiAoaSA8IDE2KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjEoYmwsIGNsLCBkbCkgKyBobFswXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDMyKSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjIoYmwsIGNsLCBkbCkgKyBobFsxXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDQ4KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjMoYmwsIGNsLCBkbCkgKyBobFsyXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDY0KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjQoYmwsIGNsLCBkbCkgKyBobFszXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIC8vIGlmIChpPDgwKSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjUoYmwsIGNsLCBkbCkgKyBobFs0XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHQgPSB0IHwgMDsKICAgICAgICAgICAgICAgIHQgPSByb3RsKHQsIHNsW2ldKTsKICAgICAgICAgICAgICAgIHQgPSB0ICsgZWwgfCAwOwogICAgICAgICAgICAgICAgYWwgPSBlbDsKICAgICAgICAgICAgICAgIGVsID0gZGw7CiAgICAgICAgICAgICAgICBkbCA9IHJvdGwoY2wsIDEwKTsKICAgICAgICAgICAgICAgIGNsID0gYmw7CiAgICAgICAgICAgICAgICBibCA9IHQ7CiAgICAgICAgICAgICAgICB0ID0gYXIgKyBNW29mZnNldCArIHpyW2ldXSB8IDA7CiAgICAgICAgICAgICAgICBpZiAoaSA8IDE2KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjUoYnIsIGNyLCBkcikgKyBoclswXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDMyKSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjQoYnIsIGNyLCBkcikgKyBoclsxXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDQ4KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjMoYnIsIGNyLCBkcikgKyBoclsyXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDY0KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjIoYnIsIGNyLCBkcikgKyBoclszXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIC8vIGlmIChpPDgwKSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjEoYnIsIGNyLCBkcikgKyBocls0XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHQgPSB0IHwgMDsKICAgICAgICAgICAgICAgIHQgPSByb3RsKHQsIHNyW2ldKTsKICAgICAgICAgICAgICAgIHQgPSB0ICsgZXIgfCAwOwogICAgICAgICAgICAgICAgYXIgPSBlcjsKICAgICAgICAgICAgICAgIGVyID0gZHI7CiAgICAgICAgICAgICAgICBkciA9IHJvdGwoY3IsIDEwKTsKICAgICAgICAgICAgICAgIGNyID0gYnI7CiAgICAgICAgICAgICAgICBiciA9IHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8vIEludGVybWVkaWF0ZSBoYXNoIHZhbHVlCiAgICAgICAgICAgICAgdCA9IEhbMV0gKyBjbCArIGRyIHwgMDsKICAgICAgICAgICAgICBIWzFdID0gSFsyXSArIGRsICsgZXIgfCAwOwogICAgICAgICAgICAgIEhbMl0gPSBIWzNdICsgZWwgKyBhciB8IDA7CiAgICAgICAgICAgICAgSFszXSA9IEhbNF0gKyBhbCArIGJyIHwgMDsKICAgICAgICAgICAgICBIWzRdID0gSFswXSArIGJsICsgY3IgfCAwOwogICAgICAgICAgICAgIEhbMF0gPSB0OwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTsKICAgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3JkczsKICAgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbCA9IHRoaXMuX25EYXRhQnl0ZXMgKiA4OwogICAgICAgICAgICAgIHZhciBuQml0c0xlZnQgPSBkYXRhLnNpZ0J5dGVzICogODsKCiAgICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmcKICAgICAgICAgICAgICBkYXRhV29yZHNbbkJpdHNMZWZ0ID4+PiA1XSB8PSAweDgwIDw8IDI0IC0gbkJpdHNMZWZ0ICUgMzI7CiAgICAgICAgICAgICAgZGF0YVdvcmRzWyhuQml0c0xlZnQgKyA2NCA+Pj4gOSA8PCA0KSArIDE0XSA9IChuQml0c1RvdGFsIDw8IDggfCBuQml0c1RvdGFsID4+PiAyNCkgJiAweDAwZmYwMGZmIHwgKG5CaXRzVG90YWwgPDwgMjQgfCBuQml0c1RvdGFsID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IChkYXRhV29yZHMubGVuZ3RoICsgMSkgKiA0OwoKICAgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2NrcwogICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoOwogICAgICAgICAgICAgIHZhciBIID0gaGFzaC53b3JkczsKCiAgICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW4KICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDU7IGkrKykgewogICAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICAgIHZhciBIX2kgPSBIW2ldOwoKICAgICAgICAgICAgICAgIC8vIFN3YXAKICAgICAgICAgICAgICAgIEhbaV0gPSAoSF9pIDw8IDggfCBIX2kgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoSF9pIDw8IDI0IHwgSF9pID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaAogICAgICAgICAgICAgIHJldHVybiBoYXNoOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBjbG9uZSA9IEhhc2hlci5jbG9uZS5jYWxsKHRoaXMpOwogICAgICAgICAgICAgIGNsb25lLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpOwogICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBmdW5jdGlvbiBmMSh4LCB5LCB6KSB7CiAgICAgICAgICAgIHJldHVybiB4IF4geSBeIHo7CiAgICAgICAgICB9CiAgICAgICAgICBmdW5jdGlvbiBmMih4LCB5LCB6KSB7CiAgICAgICAgICAgIHJldHVybiB4ICYgeSB8IH54ICYgejsKICAgICAgICAgIH0KICAgICAgICAgIGZ1bmN0aW9uIGYzKHgsIHksIHopIHsKICAgICAgICAgICAgcmV0dXJuICh4IHwgfnkpIF4gejsKICAgICAgICAgIH0KICAgICAgICAgIGZ1bmN0aW9uIGY0KHgsIHksIHopIHsKICAgICAgICAgICAgcmV0dXJuIHggJiB6IHwgeSAmIH56OwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gZjUoeCwgeSwgeikgewogICAgICAgICAgICByZXR1cm4geCBeICh5IHwgfnopOwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gcm90bCh4LCBuKSB7CiAgICAgICAgICAgIHJldHVybiB4IDw8IG4gfCB4ID4+PiAzMiAtIG47CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlJJUEVNRDE2MCgnbWVzc2FnZScpOwogICAgICAgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuUklQRU1EMTYwKHdvcmRBcnJheSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuUklQRU1EMTYwID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoUklQRU1EMTYwKTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC4KICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICoKICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgKgogICAgICAgICAgICogICAgIHZhciBobWFjID0gQ3J5cHRvSlMuSG1hY1JJUEVNRDE2MChtZXNzYWdlLCBrZXkpOwogICAgICAgICAgICovCiAgICAgICAgICBDLkhtYWNSSVBFTUQxNjAgPSBIYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoUklQRU1EMTYwKTsKICAgICAgICB9KSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5SSVBFTUQxNjA7CiAgICAgIH0pOwogICAgfSkocmlwZW1kMTYwJDEpOwogICAgcmV0dXJuIHJpcGVtZDE2MCQxLmV4cG9ydHM7CiAgfQoKICB2YXIgaG1hYyQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIGhtYWMgPSBobWFjJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRIbWFjOwogIGZ1bmN0aW9uIHJlcXVpcmVIbWFjKCkgewogICAgaWYgKGhhc1JlcXVpcmVkSG1hYykgcmV0dXJuIGhtYWMkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRIbWFjID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKGhtYWMsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBCYXNlID0gQ19saWIuQmFzZTsKICAgICAgICAgIHZhciBDX2VuYyA9IEMuZW5jOwogICAgICAgICAgdmFyIFV0ZjggPSBDX2VuYy5VdGY4OwogICAgICAgICAgdmFyIENfYWxnbyA9IEMuYWxnbzsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEhNQUMgYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICBDX2FsZ28uSE1BQyA9IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBITUFDLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGhtYWNIYXNoZXIgPSBDcnlwdG9KUy5hbGdvLkhNQUMuY3JlYXRlKENyeXB0b0pTLmFsZ28uU0hBMjU2LCBrZXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKGhhc2hlciwga2V5KSB7CiAgICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXIKICAgICAgICAgICAgICBoYXNoZXIgPSB0aGlzLl9oYXNoZXIgPSBuZXcgaGFzaGVyLmluaXQoKTsKCiAgICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeQogICAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ID09ICdzdHJpbmcnKSB7CiAgICAgICAgICAgICAgICBrZXkgPSBVdGY4LnBhcnNlKGtleSk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgaGFzaGVyQmxvY2tTaXplID0gaGFzaGVyLmJsb2NrU2l6ZTsKICAgICAgICAgICAgICB2YXIgaGFzaGVyQmxvY2tTaXplQnl0ZXMgPSBoYXNoZXJCbG9ja1NpemUgKiA0OwoKICAgICAgICAgICAgICAvLyBBbGxvdyBhcmJpdHJhcnkgbGVuZ3RoIGtleXMKICAgICAgICAgICAgICBpZiAoa2V5LnNpZ0J5dGVzID4gaGFzaGVyQmxvY2tTaXplQnl0ZXMpIHsKICAgICAgICAgICAgICAgIGtleSA9IGhhc2hlci5maW5hbGl6ZShrZXkpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gQ2xhbXAgZXhjZXNzIGJpdHMKICAgICAgICAgICAgICBrZXkuY2xhbXAoKTsKCiAgICAgICAgICAgICAgLy8gQ2xvbmUga2V5IGZvciBpbm5lciBhbmQgb3V0ZXIgcGFkcwogICAgICAgICAgICAgIHZhciBvS2V5ID0gdGhpcy5fb0tleSA9IGtleS5jbG9uZSgpOwogICAgICAgICAgICAgIHZhciBpS2V5ID0gdGhpcy5faUtleSA9IGtleS5jbG9uZSgpOwoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgb0tleVdvcmRzID0gb0tleS53b3JkczsKICAgICAgICAgICAgICB2YXIgaUtleVdvcmRzID0gaUtleS53b3JkczsKCiAgICAgICAgICAgICAgLy8gWE9SIGtleXMgd2l0aCBwYWQgY29uc3RhbnRzCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoZXJCbG9ja1NpemU7IGkrKykgewogICAgICAgICAgICAgICAgb0tleVdvcmRzW2ldIF49IDB4NWM1YzVjNWM7CiAgICAgICAgICAgICAgICBpS2V5V29yZHNbaV0gXj0gMHgzNjM2MzYzNjsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgb0tleS5zaWdCeXRlcyA9IGlLZXkuc2lnQnl0ZXMgPSBoYXNoZXJCbG9ja1NpemVCeXRlczsKCiAgICAgICAgICAgICAgLy8gU2V0IGluaXRpYWwgdmFsdWVzCiAgICAgICAgICAgICAgdGhpcy5yZXNldCgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUmVzZXRzIHRoaXMgSE1BQyB0byBpdHMgaW5pdGlhbCBzdGF0ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIGhtYWNIYXNoZXIucmVzZXQoKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgaGFzaGVyID0gdGhpcy5faGFzaGVyOwoKICAgICAgICAgICAgICAvLyBSZXNldAogICAgICAgICAgICAgIGhhc2hlci5yZXNldCgpOwogICAgICAgICAgICAgIGhhc2hlci51cGRhdGUodGhpcy5faUtleSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBVcGRhdGVzIHRoaXMgSE1BQyB3aXRoIGEgbWVzc2FnZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlVXBkYXRlIFRoZSBtZXNzYWdlIHRvIGFwcGVuZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7SE1BQ30gVGhpcyBITUFDIGluc3RhbmNlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgaG1hY0hhc2hlci51cGRhdGUoJ21lc3NhZ2UnKTsKICAgICAgICAgICAgICogICAgIGhtYWNIYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICB1cGRhdGU6IGZ1bmN0aW9uIChtZXNzYWdlVXBkYXRlKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaGVyLnVwZGF0ZShtZXNzYWdlVXBkYXRlKTsKCiAgICAgICAgICAgICAgLy8gQ2hhaW5hYmxlCiAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBGaW5hbGl6ZXMgdGhlIEhNQUMgY29tcHV0YXRpb24uCiAgICAgICAgICAgICAqIE5vdGUgdGhhdCB0aGUgZmluYWxpemUgb3BlcmF0aW9uIGlzIGVmZmVjdGl2ZWx5IGEgZGVzdHJ1Y3RpdmUsIHJlYWQtb25jZSBvcGVyYXRpb24uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSAoT3B0aW9uYWwpIEEgZmluYWwgbWVzc2FnZSB1cGRhdGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgaG1hYyA9IGhtYWNIYXNoZXIuZmluYWxpemUoKTsKICAgICAgICAgICAgICogICAgIHZhciBobWFjID0gaG1hY0hhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpOwogICAgICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBobWFjSGFzaGVyLmZpbmFsaXplKHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmaW5hbGl6ZTogZnVuY3Rpb24gKG1lc3NhZ2VVcGRhdGUpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBoYXNoZXIgPSB0aGlzLl9oYXNoZXI7CgogICAgICAgICAgICAgIC8vIENvbXB1dGUgSE1BQwogICAgICAgICAgICAgIHZhciBpbm5lckhhc2ggPSBoYXNoZXIuZmluYWxpemUobWVzc2FnZVVwZGF0ZSk7CiAgICAgICAgICAgICAgaGFzaGVyLnJlc2V0KCk7CiAgICAgICAgICAgICAgdmFyIGhtYWMgPSBoYXNoZXIuZmluYWxpemUodGhpcy5fb0tleS5jbG9uZSgpLmNvbmNhdChpbm5lckhhc2gpKTsKICAgICAgICAgICAgICByZXR1cm4gaG1hYzsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSkoKTsKICAgICAgfSk7CiAgICB9KShobWFjJDEpOwogICAgcmV0dXJuIGhtYWMkMS5leHBvcnRzOwogIH0KCiAgdmFyIHBia2RmMiQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIHBia2RmMiA9IHBia2RmMiQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkUGJrZGYyOwogIGZ1bmN0aW9uIHJlcXVpcmVQYmtkZjIoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRQYmtkZjIpIHJldHVybiBwYmtkZjIkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRQYmtkZjIgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlU2hhMjU2KCksIHJlcXVpcmVIbWFjKCkpOwogICAgICAgIH0KICAgICAgfSkocGJrZGYyLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICB2YXIgQyA9IENyeXB0b0pTOwogICAgICAgICAgdmFyIENfbGliID0gQy5saWI7CiAgICAgICAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7CiAgICAgICAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5OwogICAgICAgICAgdmFyIENfYWxnbyA9IEMuYWxnbzsKICAgICAgICAgIHZhciBTSEEyNTYgPSBDX2FsZ28uU0hBMjU2OwogICAgICAgICAgdmFyIEhNQUMgPSBDX2FsZ28uSE1BQzsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFBhc3N3b3JkLUJhc2VkIEtleSBEZXJpdmF0aW9uIEZ1bmN0aW9uIDIgYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgUEJLREYyID0gQ19hbGdvLlBCS0RGMiA9IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGtleVNpemUgVGhlIGtleSBzaXplIGluIHdvcmRzIHRvIGdlbmVyYXRlLiBEZWZhdWx0OiA0ICgxMjggYml0cykKICAgICAgICAgICAgICogQHByb3BlcnR5IHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZS4gRGVmYXVsdDogU0hBMjU2CiAgICAgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpdGVyYXRpb25zIFRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucyB0byBwZXJmb3JtLiBEZWZhdWx0OiAyNTAwMDAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNmZzogQmFzZS5leHRlbmQoewogICAgICAgICAgICAgIGtleVNpemU6IDEyOCAvIDMyLAogICAgICAgICAgICAgIGhhc2hlcjogU0hBMjU2LAogICAgICAgICAgICAgIGl0ZXJhdGlvbnM6IDI1MDAwMAogICAgICAgICAgICB9KSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGUgZGVyaXZhdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLlBCS0RGMi5jcmVhdGUoKTsKICAgICAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLlBCS0RGMi5jcmVhdGUoeyBrZXlTaXplOiA4IH0pOwogICAgICAgICAgICAgKiAgICAgdmFyIGtkZiA9IENyeXB0b0pTLmFsZ28uUEJLREYyLmNyZWF0ZSh7IGtleVNpemU6IDgsIGl0ZXJhdGlvbnM6IDEwMDAgfSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2ZnKSB7CiAgICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbXB1dGVzIHRoZSBQYXNzd29yZC1CYXNlZCBLZXkgRGVyaXZhdGlvbiBGdW5jdGlvbiAyLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC4KICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBzYWx0IEEgc2FsdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGVyaXZlZCBrZXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIga2V5ID0ga2RmLmNvbXB1dGUocGFzc3dvcmQsIHNhbHQpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY29tcHV0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5jZmc7CgogICAgICAgICAgICAgIC8vIEluaXQgSE1BQwogICAgICAgICAgICAgIHZhciBobWFjID0gSE1BQy5jcmVhdGUoY2ZnLmhhc2hlciwgcGFzc3dvcmQpOwoKICAgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlcwogICAgICAgICAgICAgIHZhciBkZXJpdmVkS2V5ID0gV29yZEFycmF5LmNyZWF0ZSgpOwogICAgICAgICAgICAgIHZhciBibG9ja0luZGV4ID0gV29yZEFycmF5LmNyZWF0ZShbMHgwMDAwMDAwMV0pOwoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgZGVyaXZlZEtleVdvcmRzID0gZGVyaXZlZEtleS53b3JkczsKICAgICAgICAgICAgICB2YXIgYmxvY2tJbmRleFdvcmRzID0gYmxvY2tJbmRleC53b3JkczsKICAgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGNmZy5rZXlTaXplOwogICAgICAgICAgICAgIHZhciBpdGVyYXRpb25zID0gY2ZnLml0ZXJhdGlvbnM7CgogICAgICAgICAgICAgIC8vIEdlbmVyYXRlIGtleQogICAgICAgICAgICAgIHdoaWxlIChkZXJpdmVkS2V5V29yZHMubGVuZ3RoIDwga2V5U2l6ZSkgewogICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gaG1hYy51cGRhdGUoc2FsdCkuZmluYWxpemUoYmxvY2tJbmRleCk7CiAgICAgICAgICAgICAgICBobWFjLnJlc2V0KCk7CgogICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgICB2YXIgYmxvY2tXb3JkcyA9IGJsb2NrLndvcmRzOwogICAgICAgICAgICAgICAgdmFyIGJsb2NrV29yZHNMZW5ndGggPSBibG9ja1dvcmRzLmxlbmd0aDsKCiAgICAgICAgICAgICAgICAvLyBJdGVyYXRpb25zCiAgICAgICAgICAgICAgICB2YXIgaW50ZXJtZWRpYXRlID0gYmxvY2s7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGl0ZXJhdGlvbnM7IGkrKykgewogICAgICAgICAgICAgICAgICBpbnRlcm1lZGlhdGUgPSBobWFjLmZpbmFsaXplKGludGVybWVkaWF0ZSk7CiAgICAgICAgICAgICAgICAgIGhtYWMucmVzZXQoKTsKCiAgICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgICAgIHZhciBpbnRlcm1lZGlhdGVXb3JkcyA9IGludGVybWVkaWF0ZS53b3JkczsKCiAgICAgICAgICAgICAgICAgIC8vIFhPUiBpbnRlcm1lZGlhdGUgd2l0aCBibG9jawogICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGJsb2NrV29yZHNMZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGJsb2NrV29yZHNbal0gXj0gaW50ZXJtZWRpYXRlV29yZHNbal07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRlcml2ZWRLZXkuY29uY2F0KGJsb2NrKTsKICAgICAgICAgICAgICAgIGJsb2NrSW5kZXhXb3Jkc1swXSsrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBkZXJpdmVkS2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7CiAgICAgICAgICAgICAgcmV0dXJuIGRlcml2ZWRLZXk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQ29tcHV0ZXMgdGhlIFBhc3N3b3JkLUJhc2VkIEtleSBEZXJpdmF0aW9uIEZ1bmN0aW9uIDIuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgQSBzYWx0LgogICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIGNvbXB1dGF0aW9uLgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRlcml2ZWQga2V5LgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuUEJLREYyKHBhc3N3b3JkLCBzYWx0KTsKICAgICAgICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuUEJLREYyKHBhc3N3b3JkLCBzYWx0LCB7IGtleVNpemU6IDggfSk7CiAgICAgICAgICAgKiAgICAgdmFyIGtleSA9IENyeXB0b0pTLlBCS0RGMihwYXNzd29yZCwgc2FsdCwgeyBrZXlTaXplOiA4LCBpdGVyYXRpb25zOiAxMDAwIH0pOwogICAgICAgICAgICovCiAgICAgICAgICBDLlBCS0RGMiA9IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCwgY2ZnKSB7CiAgICAgICAgICAgIHJldHVybiBQQktERjIuY3JlYXRlKGNmZykuY29tcHV0ZShwYXNzd29yZCwgc2FsdCk7CiAgICAgICAgICB9OwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlBCS0RGMjsKICAgICAgfSk7CiAgICB9KShwYmtkZjIkMSk7CiAgICByZXR1cm4gcGJrZGYyJDEuZXhwb3J0czsKICB9CgogIHZhciBldnBrZGYkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBldnBrZGYgPSBldnBrZGYkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZEV2cGtkZjsKICBmdW5jdGlvbiByZXF1aXJlRXZwa2RmKCkgewogICAgaWYgKGhhc1JlcXVpcmVkRXZwa2RmKSByZXR1cm4gZXZwa2RmJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkRXZwa2RmID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZVNoYTEoKSwgcmVxdWlyZUhtYWMoKSk7CiAgICAgICAgfQogICAgICB9KShldnBrZGYsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBCYXNlID0gQ19saWIuQmFzZTsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgQ19hbGdvID0gQy5hbGdvOwogICAgICAgICAgdmFyIE1ENSA9IENfYWxnby5NRDU7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBUaGlzIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIGlzIG1lYW50IHRvIGNvbmZvcm0gd2l0aCBFVlBfQnl0ZXNUb0tleS4KICAgICAgICAgICAqIHd3dy5vcGVuc3NsLm9yZy9kb2NzL2NyeXB0by9FVlBfQnl0ZXNUb0tleS5odG1sCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBFdnBLREYgPSBDX2FsZ28uRXZwS0RGID0gQmFzZS5leHRlbmQoewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0ga2V5U2l6ZSBUaGUga2V5IHNpemUgaW4gd29yZHMgdG8gZ2VuZXJhdGUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKQogICAgICAgICAgICAgKiBAcHJvcGVydHkge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuIERlZmF1bHQ6IE1ENQogICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gaXRlcmF0aW9ucyBUaGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgdG8gcGVyZm9ybS4gRGVmYXVsdDogMQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCh7CiAgICAgICAgICAgICAga2V5U2l6ZTogMTI4IC8gMzIsCiAgICAgICAgICAgICAgaGFzaGVyOiBNRDUsCiAgICAgICAgICAgICAgaXRlcmF0aW9uczogMQogICAgICAgICAgICB9KSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGUgZGVyaXZhdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoKTsKICAgICAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoeyBrZXlTaXplOiA4IH0pOwogICAgICAgICAgICAgKiAgICAgdmFyIGtkZiA9IENyeXB0b0pTLmFsZ28uRXZwS0RGLmNyZWF0ZSh7IGtleVNpemU6IDgsIGl0ZXJhdGlvbnM6IDEwMDAgfSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2ZnKSB7CiAgICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIERlcml2ZXMgYSBrZXkgZnJvbSBhIHBhc3N3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC4KICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBzYWx0IEEgc2FsdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGVyaXZlZCBrZXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIga2V5ID0ga2RmLmNvbXB1dGUocGFzc3dvcmQsIHNhbHQpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY29tcHV0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0KSB7CiAgICAgICAgICAgICAgdmFyIGJsb2NrOwoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBjZmcgPSB0aGlzLmNmZzsKCiAgICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXIKICAgICAgICAgICAgICB2YXIgaGFzaGVyID0gY2ZnLmhhc2hlci5jcmVhdGUoKTsKCiAgICAgICAgICAgICAgLy8gSW5pdGlhbCB2YWx1ZXMKICAgICAgICAgICAgICB2YXIgZGVyaXZlZEtleSA9IFdvcmRBcnJheS5jcmVhdGUoKTsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGRlcml2ZWRLZXlXb3JkcyA9IGRlcml2ZWRLZXkud29yZHM7CiAgICAgICAgICAgICAgdmFyIGtleVNpemUgPSBjZmcua2V5U2l6ZTsKICAgICAgICAgICAgICB2YXIgaXRlcmF0aW9ucyA9IGNmZy5pdGVyYXRpb25zOwoKICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBrZXkKICAgICAgICAgICAgICB3aGlsZSAoZGVyaXZlZEtleVdvcmRzLmxlbmd0aCA8IGtleVNpemUpIHsKICAgICAgICAgICAgICAgIGlmIChibG9jaykgewogICAgICAgICAgICAgICAgICBoYXNoZXIudXBkYXRlKGJsb2NrKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJsb2NrID0gaGFzaGVyLnVwZGF0ZShwYXNzd29yZCkuZmluYWxpemUoc2FsdCk7CiAgICAgICAgICAgICAgICBoYXNoZXIucmVzZXQoKTsKCiAgICAgICAgICAgICAgICAvLyBJdGVyYXRpb25zCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGl0ZXJhdGlvbnM7IGkrKykgewogICAgICAgICAgICAgICAgICBibG9jayA9IGhhc2hlci5maW5hbGl6ZShibG9jayk7CiAgICAgICAgICAgICAgICAgIGhhc2hlci5yZXNldCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVyaXZlZEtleS5jb25jYXQoYmxvY2spOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBkZXJpdmVkS2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7CiAgICAgICAgICAgICAgcmV0dXJuIGRlcml2ZWRLZXk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogRGVyaXZlcyBhIGtleSBmcm9tIGEgcGFzc3dvcmQuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgQSBzYWx0LgogICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIGNvbXB1dGF0aW9uLgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRlcml2ZWQga2V5LgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0KTsKICAgICAgICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0LCB7IGtleVNpemU6IDggfSk7CiAgICAgICAgICAgKiAgICAgdmFyIGtleSA9IENyeXB0b0pTLkV2cEtERihwYXNzd29yZCwgc2FsdCwgeyBrZXlTaXplOiA4LCBpdGVyYXRpb25zOiAxMDAwIH0pOwogICAgICAgICAgICovCiAgICAgICAgICBDLkV2cEtERiA9IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCwgY2ZnKSB7CiAgICAgICAgICAgIHJldHVybiBFdnBLREYuY3JlYXRlKGNmZykuY29tcHV0ZShwYXNzd29yZCwgc2FsdCk7CiAgICAgICAgICB9OwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLkV2cEtERjsKICAgICAgfSk7CiAgICB9KShldnBrZGYkMSk7CiAgICByZXR1cm4gZXZwa2RmJDEuZXhwb3J0czsKICB9CgogIHZhciBjaXBoZXJDb3JlJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgY2lwaGVyQ29yZSA9IGNpcGhlckNvcmUkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZENpcGhlckNvcmU7CiAgZnVuY3Rpb24gcmVxdWlyZUNpcGhlckNvcmUoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRDaXBoZXJDb3JlKSByZXR1cm4gY2lwaGVyQ29yZSQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZENpcGhlckNvcmUgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlRXZwa2RmKCkpOwogICAgICAgIH0KICAgICAgfSkoY2lwaGVyQ29yZSwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgLyoqCiAgICAgICAgICogQ2lwaGVyIGNvcmUgY29tcG9uZW50cy4KICAgICAgICAgKi8KICAgICAgICBDcnlwdG9KUy5saWIuQ2lwaGVyIHx8IGZ1bmN0aW9uICh1bmRlZmluZWQkMSkgewogICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICB2YXIgQyA9IENyeXB0b0pTOwogICAgICAgICAgdmFyIENfbGliID0gQy5saWI7CiAgICAgICAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7CiAgICAgICAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5OwogICAgICAgICAgdmFyIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBDX2xpYi5CdWZmZXJlZEJsb2NrQWxnb3JpdGhtOwogICAgICAgICAgdmFyIENfZW5jID0gQy5lbmM7CiAgICAgICAgICBDX2VuYy5VdGY4OwogICAgICAgICAgdmFyIEJhc2U2NCA9IENfZW5jLkJhc2U2NDsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CiAgICAgICAgICB2YXIgRXZwS0RGID0gQ19hbGdvLkV2cEtERjsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFic3RyYWN0IGJhc2UgY2lwaGVyIHRlbXBsYXRlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBrZXlTaXplIFRoaXMgY2lwaGVyJ3Mga2V5IHNpemUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKQogICAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGl2U2l6ZSBUaGlzIGNpcGhlcidzIElWIHNpemUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKQogICAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9FTkNfWEZPUk1fTU9ERSBBIGNvbnN0YW50IHJlcHJlc2VudGluZyBlbmNyeXB0aW9uIG1vZGUuCiAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gX0RFQ19YRk9STV9NT0RFIEEgY29uc3RhbnQgcmVwcmVzZW50aW5nIGRlY3J5cHRpb24gbW9kZS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIENpcGhlciA9IENfbGliLkNpcGhlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IGl2IFRoZSBJViB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ3JlYXRlcyB0aGlzIGNpcGhlciBpbiBlbmNyeXB0aW9uIG1vZGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS4KICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7Q2lwaGVyfSBBIGNpcGhlciBpbnN0YW5jZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlciA9IENyeXB0b0pTLmFsZ28uQUVTLmNyZWF0ZUVuY3J5cHRvcihrZXlXb3JkQXJyYXksIHsgaXY6IGl2V29yZEFycmF5IH0pOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY3JlYXRlRW5jcnlwdG9yOiBmdW5jdGlvbiAoa2V5LCBjZmcpIHsKICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUodGhpcy5fRU5DX1hGT1JNX01PREUsIGtleSwgY2ZnKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENyZWF0ZXMgdGhpcyBjaXBoZXIgaW4gZGVjcnlwdGlvbiBtb2RlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge0NpcGhlcn0gQSBjaXBoZXIgaW5zdGFuY2UuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBjaXBoZXIgPSBDcnlwdG9KUy5hbGdvLkFFUy5jcmVhdGVEZWNyeXB0b3Ioa2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNyZWF0ZURlY3J5cHRvcjogZnVuY3Rpb24gKGtleSwgY2ZnKSB7CiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlKHRoaXMuX0RFQ19YRk9STV9NT0RFLCBrZXksIGNmZyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgY2lwaGVyLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0geGZvcm1Nb2RlIEVpdGhlciB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uIHRyYW5zb3JtYXRpb24gbW9kZSBjb25zdGFudC4KICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGtleSBUaGUga2V5LgogICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlciA9IENyeXB0b0pTLmFsZ28uQUVTLmNyZWF0ZShDcnlwdG9KUy5hbGdvLkFFUy5fRU5DX1hGT1JNX01PREUsIGtleVdvcmRBcnJheSwgeyBpdjogaXZXb3JkQXJyYXkgfSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbml0OiBmdW5jdGlvbiAoeGZvcm1Nb2RlLCBrZXksIGNmZykgewogICAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0cwogICAgICAgICAgICAgIHRoaXMuY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7CgogICAgICAgICAgICAgIC8vIFN0b3JlIHRyYW5zZm9ybSBtb2RlIGFuZCBrZXkKICAgICAgICAgICAgICB0aGlzLl94Zm9ybU1vZGUgPSB4Zm9ybU1vZGU7CiAgICAgICAgICAgICAgdGhpcy5fa2V5ID0ga2V5OwoKICAgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZXMKICAgICAgICAgICAgICB0aGlzLnJlc2V0KCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZXNldHMgdGhpcyBjaXBoZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICBjaXBoZXIucmVzZXQoKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgLy8gUmVzZXQgZGF0YSBidWZmZXIKICAgICAgICAgICAgICBCdWZmZXJlZEJsb2NrQWxnb3JpdGhtLnJlc2V0LmNhbGwodGhpcyk7CgogICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtY2lwaGVyIGxvZ2ljCiAgICAgICAgICAgICAgdGhpcy5fZG9SZXNldCgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQWRkcyBkYXRhIHRvIGJlIGVuY3J5cHRlZCBvciBkZWNyeXB0ZWQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gZGF0YVVwZGF0ZSBUaGUgZGF0YSB0byBlbmNyeXB0IG9yIGRlY3J5cHQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRhdGEgYWZ0ZXIgcHJvY2Vzc2luZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIucHJvY2VzcygnZGF0YScpOwogICAgICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5wcm9jZXNzKHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwcm9jZXNzOiBmdW5jdGlvbiAoZGF0YVVwZGF0ZSkgewogICAgICAgICAgICAgIC8vIEFwcGVuZAogICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChkYXRhVXBkYXRlKTsKCiAgICAgICAgICAgICAgLy8gUHJvY2VzcyBhdmFpbGFibGUgYmxvY2tzCiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3MoKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEZpbmFsaXplcyB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uIHByb2Nlc3MuCiAgICAgICAgICAgICAqIE5vdGUgdGhhdCB0aGUgZmluYWxpemUgb3BlcmF0aW9uIGlzIGVmZmVjdGl2ZWx5IGEgZGVzdHJ1Y3RpdmUsIHJlYWQtb25jZSBvcGVyYXRpb24uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gZGF0YVVwZGF0ZSBUaGUgZmluYWwgZGF0YSB0byBlbmNyeXB0IG9yIGRlY3J5cHQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRhdGEgYWZ0ZXIgZmluYWwgcHJvY2Vzc2luZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUoKTsKICAgICAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUoJ2RhdGEnKTsKICAgICAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUod29yZEFycmF5KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAoZGF0YVVwZGF0ZSkgewogICAgICAgICAgICAgIC8vIEZpbmFsIGRhdGEgdXBkYXRlCiAgICAgICAgICAgICAgaWYgKGRhdGFVcGRhdGUpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChkYXRhVXBkYXRlKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtY2lwaGVyIGxvZ2ljCiAgICAgICAgICAgICAgdmFyIGZpbmFsUHJvY2Vzc2VkRGF0YSA9IHRoaXMuX2RvRmluYWxpemUoKTsKICAgICAgICAgICAgICByZXR1cm4gZmluYWxQcm9jZXNzZWREYXRhOwogICAgICAgICAgICB9LAogICAgICAgICAgICBrZXlTaXplOiAxMjggLyAzMiwKICAgICAgICAgICAgaXZTaXplOiAxMjggLyAzMiwKICAgICAgICAgICAgX0VOQ19YRk9STV9NT0RFOiAxLAogICAgICAgICAgICBfREVDX1hGT1JNX01PREU6IDIsCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDcmVhdGVzIHNob3J0Y3V0IGZ1bmN0aW9ucyB0byBhIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgVGhlIGNpcGhlciB0byBjcmVhdGUgYSBoZWxwZXIgZm9yLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFuIG9iamVjdCB3aXRoIGVuY3J5cHQgYW5kIGRlY3J5cHQgc2hvcnRjdXQgZnVuY3Rpb25zLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgQUVTID0gQ3J5cHRvSlMubGliLkNpcGhlci5fY3JlYXRlSGVscGVyKENyeXB0b0pTLmFsZ28uQUVTKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIF9jcmVhdGVIZWxwZXI6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICBmdW5jdGlvbiBzZWxlY3RDaXBoZXJTdHJhdGVneShrZXkpIHsKICAgICAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ID09ICdzdHJpbmcnKSB7CiAgICAgICAgICAgICAgICAgIHJldHVybiBQYXNzd29yZEJhc2VkQ2lwaGVyOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmV0dXJuIFNlcmlhbGl6YWJsZUNpcGhlcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChjaXBoZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgIGVuY3J5cHQ6IGZ1bmN0aW9uIChtZXNzYWdlLCBrZXksIGNmZykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RDaXBoZXJTdHJhdGVneShrZXkpLmVuY3J5cHQoY2lwaGVyLCBtZXNzYWdlLCBrZXksIGNmZyk7CiAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXJ0ZXh0LCBrZXksIGNmZykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RDaXBoZXJTdHJhdGVneShrZXkpLmRlY3J5cHQoY2lwaGVyLCBjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSgpCiAgICAgICAgICB9KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFic3RyYWN0IGJhc2Ugc3RyZWFtIGNpcGhlciB0ZW1wbGF0ZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgY2lwaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiAxICgzMiBiaXRzKQogICAgICAgICAgICovCiAgICAgICAgICBDX2xpYi5TdHJlYW1DaXBoZXIgPSBDaXBoZXIuZXh0ZW5kKHsKICAgICAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBQcm9jZXNzIHBhcnRpYWwgYmxvY2tzCiAgICAgICAgICAgICAgdmFyIGZpbmFsUHJvY2Vzc2VkQmxvY2tzID0gdGhpcy5fcHJvY2Vzcyh0cnVlKTsKICAgICAgICAgICAgICByZXR1cm4gZmluYWxQcm9jZXNzZWRCbG9ja3M7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGJsb2NrU2l6ZTogMQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBNb2RlIG5hbWVzcGFjZS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIENfbW9kZSA9IEMubW9kZSA9IHt9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQWJzdHJhY3QgYmFzZSBibG9jayBjaXBoZXIgbW9kZSB0ZW1wbGF0ZS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIEJsb2NrQ2lwaGVyTW9kZSA9IENfbGliLkJsb2NrQ2lwaGVyTW9kZSA9IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENyZWF0ZXMgdGhpcyBtb2RlIGZvciBlbmNyeXB0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIEEgYmxvY2sgY2lwaGVyIGluc3RhbmNlLgogICAgICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBpdiBUaGUgSVYgd29yZHMuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBtb2RlID0gQ3J5cHRvSlMubW9kZS5DQkMuY3JlYXRlRW5jcnlwdG9yKGNpcGhlciwgaXYud29yZHMpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY3JlYXRlRW5jcnlwdG9yOiBmdW5jdGlvbiAoY2lwaGVyLCBpdikgewogICAgICAgICAgICAgIHJldHVybiB0aGlzLkVuY3J5cHRvci5jcmVhdGUoY2lwaGVyLCBpdik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDcmVhdGVzIHRoaXMgbW9kZSBmb3IgZGVjcnlwdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBBIGJsb2NrIGNpcGhlciBpbnN0YW5jZS4KICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gaXYgVGhlIElWIHdvcmRzLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgbW9kZSA9IENyeXB0b0pTLm1vZGUuQ0JDLmNyZWF0ZURlY3J5cHRvcihjaXBoZXIsIGl2LndvcmRzKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNyZWF0ZURlY3J5cHRvcjogZnVuY3Rpb24gKGNpcGhlciwgaXYpIHsKICAgICAgICAgICAgICByZXR1cm4gdGhpcy5EZWNyeXB0b3IuY3JlYXRlKGNpcGhlciwgaXYpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG1vZGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgQSBibG9jayBjaXBoZXIgaW5zdGFuY2UuCiAgICAgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGl2IFRoZSBJViB3b3Jkcy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBtb2RlID0gQ3J5cHRvSlMubW9kZS5DQkMuRW5jcnlwdG9yLmNyZWF0ZShjaXBoZXIsIGl2LndvcmRzKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjaXBoZXIsIGl2KSB7CiAgICAgICAgICAgICAgdGhpcy5fY2lwaGVyID0gY2lwaGVyOwogICAgICAgICAgICAgIHRoaXMuX2l2ID0gaXY7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQ2lwaGVyIEJsb2NrIENoYWluaW5nIG1vZGUuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDQkMgPSBDX21vZGUuQ0JDID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQWJzdHJhY3QgYmFzZSBDQkMgbW9kZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHZhciBDQkMgPSBCbG9ja0NpcGhlck1vZGUuZXh0ZW5kKCk7CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ0JDIGVuY3J5cHRvci4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIENCQy5FbmNyeXB0b3IgPSBDQkMuZXh0ZW5kKHsKICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgKiBQcm9jZXNzZXMgdGhlIGRhdGEgYmxvY2sgYXQgb2Zmc2V0LgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgVGhlIGRhdGEgd29yZHMgdG8gb3BlcmF0ZSBvbi4KICAgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IFRoZSBvZmZzZXQgd2hlcmUgdGhlIGJsb2NrIHN0YXJ0cy4KICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgKiAgICAgbW9kZS5wcm9jZXNzQmxvY2soZGF0YS53b3Jkcywgb2Zmc2V0KTsKICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICAgIHZhciBjaXBoZXIgPSB0aGlzLl9jaXBoZXI7CiAgICAgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTsKCiAgICAgICAgICAgICAgICAvLyBYT1IgYW5kIGVuY3J5cHQKICAgICAgICAgICAgICAgIHhvckJsb2NrLmNhbGwodGhpcywgd29yZHMsIG9mZnNldCwgYmxvY2tTaXplKTsKICAgICAgICAgICAgICAgIGNpcGhlci5lbmNyeXB0QmxvY2sod29yZHMsIG9mZnNldCk7CgogICAgICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhpcyBibG9jayB0byB1c2Ugd2l0aCBuZXh0IGJsb2NrCiAgICAgICAgICAgICAgICB0aGlzLl9wcmV2QmxvY2sgPSB3b3Jkcy5zbGljZShvZmZzZXQsIG9mZnNldCArIGJsb2NrU2l6ZSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDQkMgZGVjcnlwdG9yLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgQ0JDLkRlY3J5cHRvciA9IENCQy5leHRlbmQoewogICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAqIFByb2Nlc3NlcyB0aGUgZGF0YSBibG9jayBhdCBvZmZzZXQuCiAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSB3b3JkcyBUaGUgZGF0YSB3b3JkcyB0byBvcGVyYXRlIG9uLgogICAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgVGhlIG9mZnNldCB3aGVyZSB0aGUgYmxvY2sgc3RhcnRzLgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqICAgICBtb2RlLnByb2Nlc3NCbG9jayhkYXRhLndvcmRzLCBvZmZzZXQpOwogICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgdmFyIGNpcGhlciA9IHRoaXMuX2NpcGhlcjsKICAgICAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSBjaXBoZXIuYmxvY2tTaXplOwoKICAgICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoaXMgYmxvY2sgdG8gdXNlIHdpdGggbmV4dCBibG9jawogICAgICAgICAgICAgICAgdmFyIHRoaXNCbG9jayA9IHdvcmRzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgYmxvY2tTaXplKTsKCiAgICAgICAgICAgICAgICAvLyBEZWNyeXB0IGFuZCBYT1IKICAgICAgICAgICAgICAgIGNpcGhlci5kZWNyeXB0QmxvY2sod29yZHMsIG9mZnNldCk7CiAgICAgICAgICAgICAgICB4b3JCbG9jay5jYWxsKHRoaXMsIHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSk7CgogICAgICAgICAgICAgICAgLy8gVGhpcyBibG9jayBiZWNvbWVzIHRoZSBwcmV2aW91cyBibG9jawogICAgICAgICAgICAgICAgdGhpcy5fcHJldkJsb2NrID0gdGhpc0Jsb2NrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGZ1bmN0aW9uIHhvckJsb2NrKHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSkgewogICAgICAgICAgICAgIHZhciBibG9jazsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLl9pdjsKCiAgICAgICAgICAgICAgLy8gQ2hvb3NlIG1peGluZyBibG9jawogICAgICAgICAgICAgIGlmIChpdikgewogICAgICAgICAgICAgICAgYmxvY2sgPSBpdjsKCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgSVYgZm9yIHN1YnNlcXVlbnQgYmxvY2tzCiAgICAgICAgICAgICAgICB0aGlzLl9pdiA9IHVuZGVmaW5lZCQxOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBibG9jayA9IHRoaXMuX3ByZXZCbG9jazsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFhPUiBibG9ja3MKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrU2l6ZTsgaSsrKSB7CiAgICAgICAgICAgICAgICB3b3Jkc1tvZmZzZXQgKyBpXSBePSBibG9ja1tpXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIENCQzsKICAgICAgICAgIH0oKTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFBhZGRpbmcgbmFtZXNwYWNlLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgQ19wYWQgPSBDLnBhZCA9IHt9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogUEtDUyAjNS83IHBhZGRpbmcgc3RyYXRlZ3kuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBQa2NzNyA9IENfcGFkLlBrY3M3ID0gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUGFkcyBkYXRhIHVzaW5nIHRoZSBhbGdvcml0aG0gZGVmaW5lZCBpbiBQS0NTICM1LzcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBkYXRhIFRoZSBkYXRhIHRvIHBhZC4KICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGJsb2NrU2l6ZSBUaGUgbXVsdGlwbGUgdGhhdCB0aGUgZGF0YSBzaG91bGQgYmUgcGFkZGVkIHRvLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICBDcnlwdG9KUy5wYWQuUGtjczcucGFkKHdvcmRBcnJheSwgNCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwYWQ6IGZ1bmN0aW9uIChkYXRhLCBibG9ja1NpemUpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBibG9ja1NpemVCeXRlcyA9IGJsb2NrU2l6ZSAqIDQ7CgogICAgICAgICAgICAgIC8vIENvdW50IHBhZGRpbmcgYnl0ZXMKICAgICAgICAgICAgICB2YXIgblBhZGRpbmdCeXRlcyA9IGJsb2NrU2l6ZUJ5dGVzIC0gZGF0YS5zaWdCeXRlcyAlIGJsb2NrU2l6ZUJ5dGVzOwoKICAgICAgICAgICAgICAvLyBDcmVhdGUgcGFkZGluZyB3b3JkCiAgICAgICAgICAgICAgdmFyIHBhZGRpbmdXb3JkID0gblBhZGRpbmdCeXRlcyA8PCAyNCB8IG5QYWRkaW5nQnl0ZXMgPDwgMTYgfCBuUGFkZGluZ0J5dGVzIDw8IDggfCBuUGFkZGluZ0J5dGVzOwoKICAgICAgICAgICAgICAvLyBDcmVhdGUgcGFkZGluZwogICAgICAgICAgICAgIHZhciBwYWRkaW5nV29yZHMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5QYWRkaW5nQnl0ZXM7IGkgKz0gNCkgewogICAgICAgICAgICAgICAgcGFkZGluZ1dvcmRzLnB1c2gocGFkZGluZ1dvcmQpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB2YXIgcGFkZGluZyA9IFdvcmRBcnJheS5jcmVhdGUocGFkZGluZ1dvcmRzLCBuUGFkZGluZ0J5dGVzKTsKCiAgICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmcKICAgICAgICAgICAgICBkYXRhLmNvbmNhdChwYWRkaW5nKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFVucGFkcyBkYXRhIHRoYXQgaGFkIGJlZW4gcGFkZGVkIHVzaW5nIHRoZSBhbGdvcml0aG0gZGVmaW5lZCBpbiBQS0NTICM1LzcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBkYXRhIFRoZSBkYXRhIHRvIHVucGFkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICBDcnlwdG9KUy5wYWQuUGtjczcudW5wYWQod29yZEFycmF5KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHVucGFkOiBmdW5jdGlvbiAoZGF0YSkgewogICAgICAgICAgICAgIC8vIEdldCBudW1iZXIgb2YgcGFkZGluZyBieXRlcyBmcm9tIGxhc3QgYnl0ZQogICAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gZGF0YS53b3Jkc1tkYXRhLnNpZ0J5dGVzIC0gMSA+Pj4gMl0gJiAweGZmOwoKICAgICAgICAgICAgICAvLyBSZW1vdmUgcGFkZGluZwogICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgLT0gblBhZGRpbmdCeXRlczsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFic3RyYWN0IGJhc2UgYmxvY2sgY2lwaGVyIHRlbXBsYXRlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG51bWJlciBvZiAzMi1iaXQgd29yZHMgdGhpcyBjaXBoZXIgb3BlcmF0ZXMgb24uIERlZmF1bHQ6IDQgKDEyOCBiaXRzKQogICAgICAgICAgICovCiAgICAgICAgICBDX2xpYi5CbG9ja0NpcGhlciA9IENpcGhlci5leHRlbmQoewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcHJvcGVydHkge01vZGV9IG1vZGUgVGhlIGJsb2NrIG1vZGUgdG8gdXNlLiBEZWZhdWx0OiBDQkMKICAgICAgICAgICAgICogQHByb3BlcnR5IHtQYWRkaW5nfSBwYWRkaW5nIFRoZSBwYWRkaW5nIHN0cmF0ZWd5IHRvIHVzZS4gRGVmYXVsdDogUGtjczcKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNmZzogQ2lwaGVyLmNmZy5leHRlbmQoewogICAgICAgICAgICAgIG1vZGU6IENCQywKICAgICAgICAgICAgICBwYWRkaW5nOiBQa2NzNwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgbW9kZUNyZWF0b3I7CgogICAgICAgICAgICAgIC8vIFJlc2V0IGNpcGhlcgogICAgICAgICAgICAgIENpcGhlci5yZXNldC5jYWxsKHRoaXMpOwoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5jZmc7CiAgICAgICAgICAgICAgdmFyIGl2ID0gY2ZnLml2OwogICAgICAgICAgICAgIHZhciBtb2RlID0gY2ZnLm1vZGU7CgogICAgICAgICAgICAgIC8vIFJlc2V0IGJsb2NrIG1vZGUKICAgICAgICAgICAgICBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0VOQ19YRk9STV9NT0RFKSB7CiAgICAgICAgICAgICAgICBtb2RlQ3JlYXRvciA9IG1vZGUuY3JlYXRlRW5jcnlwdG9yOwogICAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqL3sKICAgICAgICAgICAgICAgICAgbW9kZUNyZWF0b3IgPSBtb2RlLmNyZWF0ZURlY3J5cHRvcjsKICAgICAgICAgICAgICAgICAgLy8gS2VlcCBhdCBsZWFzdCBvbmUgYmxvY2sgaW4gdGhlIGJ1ZmZlciBmb3IgdW5wYWRkaW5nCiAgICAgICAgICAgICAgICAgIHRoaXMuX21pbkJ1ZmZlclNpemUgPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmICh0aGlzLl9tb2RlICYmIHRoaXMuX21vZGUuX19jcmVhdG9yID09IG1vZGVDcmVhdG9yKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlLmluaXQodGhpcywgaXYgJiYgaXYud29yZHMpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlID0gbW9kZUNyZWF0b3IuY2FsbChtb2RlLCB0aGlzLCBpdiAmJiBpdi53b3Jkcyk7CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlLl9fY3JlYXRvciA9IG1vZGVDcmVhdG9yOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkgewogICAgICAgICAgICAgIHRoaXMuX21vZGUucHJvY2Vzc0Jsb2NrKHdvcmRzLCBvZmZzZXQpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBmaW5hbFByb2Nlc3NlZEJsb2NrczsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgcGFkZGluZyA9IHRoaXMuY2ZnLnBhZGRpbmc7CgogICAgICAgICAgICAgIC8vIEZpbmFsaXplCiAgICAgICAgICAgICAgaWYgKHRoaXMuX3hmb3JtTW9kZSA9PSB0aGlzLl9FTkNfWEZPUk1fTU9ERSkgewogICAgICAgICAgICAgICAgLy8gUGFkIGRhdGEKICAgICAgICAgICAgICAgIHBhZGRpbmcucGFkKHRoaXMuX2RhdGEsIHRoaXMuYmxvY2tTaXplKTsKCiAgICAgICAgICAgICAgICAvLyBQcm9jZXNzIGZpbmFsIGJsb2NrcwogICAgICAgICAgICAgICAgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKHRydWUpOwogICAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqL3sKICAgICAgICAgICAgICAgICAgLy8gUHJvY2VzcyBmaW5hbCBibG9ja3MKICAgICAgICAgICAgICAgICAgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKHRydWUpOwoKICAgICAgICAgICAgICAgICAgLy8gVW5wYWQgZGF0YQogICAgICAgICAgICAgICAgICBwYWRkaW5nLnVucGFkKGZpbmFsUHJvY2Vzc2VkQmxvY2tzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gZmluYWxQcm9jZXNzZWRCbG9ja3M7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGJsb2NrU2l6ZTogMTI4IC8gMzIKICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQSBjb2xsZWN0aW9uIG9mIGNpcGhlciBwYXJhbWV0ZXJzLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwcm9wZXJ0eSB7V29yZEFycmF5fSBjaXBoZXJ0ZXh0IFRoZSByYXcgY2lwaGVydGV4dC4KICAgICAgICAgICAqIEBwcm9wZXJ0eSB7V29yZEFycmF5fSBrZXkgVGhlIGtleSB0byB0aGlzIGNpcGhlcnRleHQuCiAgICAgICAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gaXYgVGhlIElWIHVzZWQgaW4gdGhlIGNpcGhlcmluZyBvcGVyYXRpb24uCiAgICAgICAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gc2FsdCBUaGUgc2FsdCB1c2VkIHdpdGggYSBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi4KICAgICAgICAgICAqIEBwcm9wZXJ0eSB7Q2lwaGVyfSBhbGdvcml0aG0gVGhlIGNpcGhlciBhbGdvcml0aG0uCiAgICAgICAgICAgKiBAcHJvcGVydHkge01vZGV9IG1vZGUgVGhlIGJsb2NrIG1vZGUgdXNlZCBpbiB0aGUgY2lwaGVyaW5nIG9wZXJhdGlvbi4KICAgICAgICAgICAqIEBwcm9wZXJ0eSB7UGFkZGluZ30gcGFkZGluZyBUaGUgcGFkZGluZyBzY2hlbWUgdXNlZCBpbiB0aGUgY2lwaGVyaW5nIG9wZXJhdGlvbi4KICAgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIGJsb2NrIHNpemUgb2YgdGhlIGNpcGhlci4KICAgICAgICAgICAqIEBwcm9wZXJ0eSB7Rm9ybWF0fSBmb3JtYXR0ZXIgVGhlIGRlZmF1bHQgZm9ybWF0dGluZyBzdHJhdGVneSB0byBjb252ZXJ0IHRoaXMgY2lwaGVyIHBhcmFtcyBvYmplY3QgdG8gYSBzdHJpbmcuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDaXBoZXJQYXJhbXMgPSBDX2xpYi5DaXBoZXJQYXJhbXMgPSBCYXNlLmV4dGVuZCh7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgY2lwaGVyIHBhcmFtcyBvYmplY3QuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjaXBoZXJQYXJhbXMgQW4gb2JqZWN0IHdpdGggYW55IG9mIHRoZSBwb3NzaWJsZSBjaXBoZXIgcGFyYW1ldGVycy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBjaXBoZXJQYXJhbXMgPSBDcnlwdG9KUy5saWIuQ2lwaGVyUGFyYW1zLmNyZWF0ZSh7CiAgICAgICAgICAgICAqICAgICAgICAgY2lwaGVydGV4dDogY2lwaGVydGV4dFdvcmRBcnJheSwKICAgICAgICAgICAgICogICAgICAgICBrZXk6IGtleVdvcmRBcnJheSwKICAgICAgICAgICAgICogICAgICAgICBpdjogaXZXb3JkQXJyYXksCiAgICAgICAgICAgICAqICAgICAgICAgc2FsdDogc2FsdFdvcmRBcnJheSwKICAgICAgICAgICAgICogICAgICAgICBhbGdvcml0aG06IENyeXB0b0pTLmFsZ28uQUVTLAogICAgICAgICAgICAgKiAgICAgICAgIG1vZGU6IENyeXB0b0pTLm1vZGUuQ0JDLAogICAgICAgICAgICAgKiAgICAgICAgIHBhZGRpbmc6IENyeXB0b0pTLnBhZC5QS0NTNywKICAgICAgICAgICAgICogICAgICAgICBibG9ja1NpemU6IDQsCiAgICAgICAgICAgICAqICAgICAgICAgZm9ybWF0dGVyOiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTAogICAgICAgICAgICAgKiAgICAgfSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2lwaGVyUGFyYW1zKSB7CiAgICAgICAgICAgICAgdGhpcy5taXhJbihjaXBoZXJQYXJhbXMpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgdGhpcyBjaXBoZXIgcGFyYW1zIG9iamVjdCB0byBhIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtGb3JtYXR9IGZvcm1hdHRlciAoT3B0aW9uYWwpIFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIHVzZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3RyaW5naWZpZWQgY2lwaGVyIHBhcmFtcy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHRocm93cyBFcnJvciBJZiBuZWl0aGVyIHRoZSBmb3JtYXR0ZXIgbm9yIHRoZSBkZWZhdWx0IGZvcm1hdHRlciBpcyBzZXQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zICsgJyc7CiAgICAgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zLnRvU3RyaW5nKENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHRvU3RyaW5nOiBmdW5jdGlvbiAoZm9ybWF0dGVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIChmb3JtYXR0ZXIgfHwgdGhpcy5mb3JtYXR0ZXIpLnN0cmluZ2lmeSh0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBGb3JtYXQgbmFtZXNwYWNlLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgQ19mb3JtYXQgPSBDLmZvcm1hdCA9IHt9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogT3BlblNTTCBmb3JtYXR0aW5nIHN0cmF0ZWd5LgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgT3BlblNTTEZvcm1hdHRlciA9IENfZm9ybWF0Lk9wZW5TU0wgPSB7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBhIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfSBjaXBoZXJQYXJhbXMgVGhlIGNpcGhlciBwYXJhbXMgb2JqZWN0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBPcGVuU1NMLWNvbXBhdGlibGUgc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgb3BlblNTTFN0cmluZyA9IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMLnN0cmluZ2lmeShjaXBoZXJQYXJhbXMpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAoY2lwaGVyUGFyYW1zKSB7CiAgICAgICAgICAgICAgdmFyIHdvcmRBcnJheTsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGNpcGhlcnRleHQgPSBjaXBoZXJQYXJhbXMuY2lwaGVydGV4dDsKICAgICAgICAgICAgICB2YXIgc2FsdCA9IGNpcGhlclBhcmFtcy5zYWx0OwoKICAgICAgICAgICAgICAvLyBGb3JtYXQKICAgICAgICAgICAgICBpZiAoc2FsdCkgewogICAgICAgICAgICAgICAgd29yZEFycmF5ID0gV29yZEFycmF5LmNyZWF0ZShbMHg1MzYxNmM3NCwgMHg2NTY0NWY1Zl0pLmNvbmNhdChzYWx0KS5jb25jYXQoY2lwaGVydGV4dCk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHdvcmRBcnJheSA9IGNpcGhlcnRleHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB3b3JkQXJyYXkudG9TdHJpbmcoQmFzZTY0KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcgdG8gYSBjaXBoZXIgcGFyYW1zIG9iamVjdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IG9wZW5TU0xTdHIgVGhlIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge0NpcGhlclBhcmFtc30gVGhlIGNpcGhlciBwYXJhbXMgb2JqZWN0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgY2lwaGVyUGFyYW1zID0gQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wucGFyc2Uob3BlblNTTFN0cmluZyk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwYXJzZTogZnVuY3Rpb24gKG9wZW5TU0xTdHIpIHsKICAgICAgICAgICAgICB2YXIgc2FsdDsKCiAgICAgICAgICAgICAgLy8gUGFyc2UgYmFzZTY0CiAgICAgICAgICAgICAgdmFyIGNpcGhlcnRleHQgPSBCYXNlNjQucGFyc2Uob3BlblNTTFN0cik7CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgdmFyIGNpcGhlcnRleHRXb3JkcyA9IGNpcGhlcnRleHQud29yZHM7CgogICAgICAgICAgICAgIC8vIFRlc3QgZm9yIHNhbHQKICAgICAgICAgICAgICBpZiAoY2lwaGVydGV4dFdvcmRzWzBdID09IDB4NTM2MTZjNzQgJiYgY2lwaGVydGV4dFdvcmRzWzFdID09IDB4NjU2NDVmNWYpIHsKICAgICAgICAgICAgICAgIC8vIEV4dHJhY3Qgc2FsdAogICAgICAgICAgICAgICAgc2FsdCA9IFdvcmRBcnJheS5jcmVhdGUoY2lwaGVydGV4dFdvcmRzLnNsaWNlKDIsIDQpKTsKCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgc2FsdCBmcm9tIGNpcGhlcnRleHQKICAgICAgICAgICAgICAgIGNpcGhlcnRleHRXb3Jkcy5zcGxpY2UoMCwgNCk7CiAgICAgICAgICAgICAgICBjaXBoZXJ0ZXh0LnNpZ0J5dGVzIC09IDE2OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gQ2lwaGVyUGFyYW1zLmNyZWF0ZSh7CiAgICAgICAgICAgICAgICBjaXBoZXJ0ZXh0OiBjaXBoZXJ0ZXh0LAogICAgICAgICAgICAgICAgc2FsdDogc2FsdAogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQSBjaXBoZXIgd3JhcHBlciB0aGF0IHJldHVybnMgY2lwaGVydGV4dCBhcyBhIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zIG9iamVjdC4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIFNlcmlhbGl6YWJsZUNpcGhlciA9IENfbGliLlNlcmlhbGl6YWJsZUNpcGhlciA9IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHByb3BlcnR5IHtGb3JtYXR0ZXJ9IGZvcm1hdCBUaGUgZm9ybWF0dGluZyBzdHJhdGVneSB0byBjb252ZXJ0IGNpcGhlciBwYXJhbSBvYmplY3RzIHRvIGFuZCBmcm9tIGEgc3RyaW5nLiBEZWZhdWx0OiBPcGVuU1NMCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjZmc6IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgICBmb3JtYXQ6IE9wZW5TU0xGb3JtYXR0ZXIKICAgICAgICAgICAgfSksCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBFbmNyeXB0cyBhIG1lc3NhZ2UuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgVGhlIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlLgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gZW5jcnlwdC4KICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGtleSBUaGUga2V5LgogICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IEEgY2lwaGVyIHBhcmFtcyBvYmplY3QuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBtZXNzYWdlLCBrZXkpOwogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuU2VyaWFsaXphYmxlQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsIGtleSwgeyBpdjogaXYgfSk7CiAgICAgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5TZXJpYWxpemFibGVDaXBoZXIuZW5jcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgbWVzc2FnZSwga2V5LCB7IGl2OiBpdiwgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGVuY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXIsIG1lc3NhZ2UsIGtleSwgY2ZnKSB7CiAgICAgICAgICAgICAgLy8gQXBwbHkgY29uZmlnIGRlZmF1bHRzCiAgICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7CgogICAgICAgICAgICAgIC8vIEVuY3J5cHQKICAgICAgICAgICAgICB2YXIgZW5jcnlwdG9yID0gY2lwaGVyLmNyZWF0ZUVuY3J5cHRvcihrZXksIGNmZyk7CiAgICAgICAgICAgICAgdmFyIGNpcGhlcnRleHQgPSBlbmNyeXB0b3IuZmluYWxpemUobWVzc2FnZSk7CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgdmFyIGNpcGhlckNmZyA9IGVuY3J5cHRvci5jZmc7CgogICAgICAgICAgICAgIC8vIENyZWF0ZSBhbmQgcmV0dXJuIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zCiAgICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoewogICAgICAgICAgICAgICAgY2lwaGVydGV4dDogY2lwaGVydGV4dCwKICAgICAgICAgICAgICAgIGtleToga2V5LAogICAgICAgICAgICAgICAgaXY6IGNpcGhlckNmZy5pdiwKICAgICAgICAgICAgICAgIGFsZ29yaXRobTogY2lwaGVyLAogICAgICAgICAgICAgICAgbW9kZTogY2lwaGVyQ2ZnLm1vZGUsCiAgICAgICAgICAgICAgICBwYWRkaW5nOiBjaXBoZXJDZmcucGFkZGluZywKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogY2lwaGVyLmJsb2NrU2l6ZSwKICAgICAgICAgICAgICAgIGZvcm1hdHRlcjogY2ZnLmZvcm1hdAogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogRGVjcnlwdHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS4KICAgICAgICAgICAgICogQHBhcmFtIHtDaXBoZXJQYXJhbXN8c3RyaW5nfSBjaXBoZXJ0ZXh0IFRoZSBjaXBoZXJ0ZXh0IHRvIGRlY3J5cHQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS4KICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcGxhaW50ZXh0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pOwogICAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCA9IENyeXB0b0pTLmxpYi5TZXJpYWxpemFibGVDaXBoZXIuZGVjcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgY2lwaGVydGV4dFBhcmFtcywga2V5LCB7IGl2OiBpdiwgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXIsIGNpcGhlcnRleHQsIGtleSwgY2ZnKSB7CiAgICAgICAgICAgICAgLy8gQXBwbHkgY29uZmlnIGRlZmF1bHRzCiAgICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7CgogICAgICAgICAgICAgIC8vIENvbnZlcnQgc3RyaW5nIHRvIENpcGhlclBhcmFtcwogICAgICAgICAgICAgIGNpcGhlcnRleHQgPSB0aGlzLl9wYXJzZShjaXBoZXJ0ZXh0LCBjZmcuZm9ybWF0KTsKCiAgICAgICAgICAgICAgLy8gRGVjcnlwdAogICAgICAgICAgICAgIHZhciBwbGFpbnRleHQgPSBjaXBoZXIuY3JlYXRlRGVjcnlwdG9yKGtleSwgY2ZnKS5maW5hbGl6ZShjaXBoZXJ0ZXh0LmNpcGhlcnRleHQpOwogICAgICAgICAgICAgIHJldHVybiBwbGFpbnRleHQ7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBzZXJpYWxpemVkIGNpcGhlcnRleHQgdG8gQ2lwaGVyUGFyYW1zLAogICAgICAgICAgICAgKiBlbHNlIGFzc3VtZWQgQ2lwaGVyUGFyYW1zIGFscmVhZHkgYW5kIHJldHVybnMgY2lwaGVydGV4dCB1bmNoYW5nZWQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfHN0cmluZ30gY2lwaGVydGV4dCBUaGUgY2lwaGVydGV4dC4KICAgICAgICAgICAgICogQHBhcmFtIHtGb3JtYXR0ZXJ9IGZvcm1hdCBUaGUgZm9ybWF0dGluZyBzdHJhdGVneSB0byB1c2UgdG8gcGFyc2Ugc2VyaWFsaXplZCBjaXBoZXJ0ZXh0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IFRoZSB1bnNlcmlhbGl6ZWQgY2lwaGVydGV4dC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuU2VyaWFsaXphYmxlQ2lwaGVyLl9wYXJzZShjaXBoZXJ0ZXh0U3RyaW5nT3JQYXJhbXMsIGZvcm1hdCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBfcGFyc2U6IGZ1bmN0aW9uIChjaXBoZXJ0ZXh0LCBmb3JtYXQpIHsKICAgICAgICAgICAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXQucGFyc2UoY2lwaGVydGV4dCwgdGhpcyk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBjaXBoZXJ0ZXh0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBLZXkgZGVyaXZhdGlvbiBmdW5jdGlvbiBuYW1lc3BhY2UuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDX2tkZiA9IEMua2RmID0ge307CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBPcGVuU1NMIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgT3BlblNTTEtkZiA9IENfa2RmLk9wZW5TU0wgPSB7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBEZXJpdmVzIGEga2V5IGFuZCBJViBmcm9tIGEgcGFzc3dvcmQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQgdG8gZGVyaXZlIGZyb20uCiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBrZXlTaXplIFRoZSBzaXplIGluIHdvcmRzIG9mIHRoZSBrZXkgdG8gZ2VuZXJhdGUuCiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpdlNpemUgVGhlIHNpemUgaW4gd29yZHMgb2YgdGhlIElWIHRvIGdlbmVyYXRlLgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgKE9wdGlvbmFsKSBBIDY0LWJpdCBzYWx0IHRvIHVzZS4gSWYgb21pdHRlZCwgYSBzYWx0IHdpbGwgYmUgZ2VuZXJhdGVkIHJhbmRvbWx5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IEEgY2lwaGVyIHBhcmFtcyBvYmplY3Qgd2l0aCB0aGUga2V5LCBJViwgYW5kIHNhbHQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMik7CiAgICAgICAgICAgICAqICAgICB2YXIgZGVyaXZlZFBhcmFtcyA9IENyeXB0b0pTLmtkZi5PcGVuU1NMLmV4ZWN1dGUoJ1Bhc3N3b3JkJywgMjU2LzMyLCAxMjgvMzIsICdzYWx0c2FsdCcpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZXhlY3V0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBrZXlTaXplLCBpdlNpemUsIHNhbHQsIGhhc2hlcikgewogICAgICAgICAgICAgIC8vIEdlbmVyYXRlIHJhbmRvbSBzYWx0CiAgICAgICAgICAgICAgaWYgKCFzYWx0KSB7CiAgICAgICAgICAgICAgICBzYWx0ID0gV29yZEFycmF5LnJhbmRvbSg2NCAvIDgpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gRGVyaXZlIGtleSBhbmQgSVYKICAgICAgICAgICAgICBpZiAoIWhhc2hlcikgewogICAgICAgICAgICAgICAgdmFyIGtleSA9IEV2cEtERi5jcmVhdGUoewogICAgICAgICAgICAgICAgICBrZXlTaXplOiBrZXlTaXplICsgaXZTaXplCiAgICAgICAgICAgICAgICB9KS5jb21wdXRlKHBhc3N3b3JkLCBzYWx0KTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGtleSA9IEV2cEtERi5jcmVhdGUoewogICAgICAgICAgICAgICAgICBrZXlTaXplOiBrZXlTaXplICsgaXZTaXplLAogICAgICAgICAgICAgICAgICBoYXNoZXI6IGhhc2hlcgogICAgICAgICAgICAgICAgfSkuY29tcHV0ZShwYXNzd29yZCwgc2FsdCk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBTZXBhcmF0ZSBrZXkgYW5kIElWCiAgICAgICAgICAgICAgdmFyIGl2ID0gV29yZEFycmF5LmNyZWF0ZShrZXkud29yZHMuc2xpY2Uoa2V5U2l6ZSksIGl2U2l6ZSAqIDQpOwogICAgICAgICAgICAgIGtleS5zaWdCeXRlcyA9IGtleVNpemUgKiA0OwoKICAgICAgICAgICAgICAvLyBSZXR1cm4gcGFyYW1zCiAgICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoewogICAgICAgICAgICAgICAga2V5OiBrZXksCiAgICAgICAgICAgICAgICBpdjogaXYsCiAgICAgICAgICAgICAgICBzYWx0OiBzYWx0CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBBIHNlcmlhbGl6YWJsZSBjaXBoZXIgd3JhcHBlciB0aGF0IGRlcml2ZXMgdGhlIGtleSBmcm9tIGEgcGFzc3dvcmQsCiAgICAgICAgICAgKiBhbmQgcmV0dXJucyBjaXBoZXJ0ZXh0IGFzIGEgc2VyaWFsaXphYmxlIGNpcGhlciBwYXJhbXMgb2JqZWN0LgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgUGFzc3dvcmRCYXNlZENpcGhlciA9IENfbGliLlBhc3N3b3JkQmFzZWRDaXBoZXIgPSBTZXJpYWxpemFibGVDaXBoZXIuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHByb3BlcnR5IHtLREZ9IGtkZiBUaGUga2V5IGRlcml2YXRpb24gZnVuY3Rpb24gdG8gdXNlIHRvIGdlbmVyYXRlIGEga2V5IGFuZCBJViBmcm9tIGEgcGFzc3dvcmQuIERlZmF1bHQ6IE9wZW5TU0wKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNmZzogU2VyaWFsaXphYmxlQ2lwaGVyLmNmZy5leHRlbmQoewogICAgICAgICAgICAgIGtkZjogT3BlblNTTEtkZgogICAgICAgICAgICB9KSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEVuY3J5cHRzIGEgbWVzc2FnZSB1c2luZyBhIHBhc3N3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS4KICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGVuY3J5cHQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge0NpcGhlclBhcmFtc30gQSBjaXBoZXIgcGFyYW1zIG9iamVjdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5lbmNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBtZXNzYWdlLCAncGFzc3dvcmQnKTsKICAgICAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlBhc3N3b3JkQmFzZWRDaXBoZXIuZW5jcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgbWVzc2FnZSwgJ3Bhc3N3b3JkJywgeyBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZW5jcnlwdDogZnVuY3Rpb24gKGNpcGhlciwgbWVzc2FnZSwgcGFzc3dvcmQsIGNmZykgewogICAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0cwogICAgICAgICAgICAgIGNmZyA9IHRoaXMuY2ZnLmV4dGVuZChjZmcpOwoKICAgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXMKICAgICAgICAgICAgICB2YXIgZGVyaXZlZFBhcmFtcyA9IGNmZy5rZGYuZXhlY3V0ZShwYXNzd29yZCwgY2lwaGVyLmtleVNpemUsIGNpcGhlci5pdlNpemUsIGNmZy5zYWx0LCBjZmcuaGFzaGVyKTsKCiAgICAgICAgICAgICAgLy8gQWRkIElWIHRvIGNvbmZpZwogICAgICAgICAgICAgIGNmZy5pdiA9IGRlcml2ZWRQYXJhbXMuaXY7CgogICAgICAgICAgICAgIC8vIEVuY3J5cHQKICAgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IFNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0LmNhbGwodGhpcywgY2lwaGVyLCBtZXNzYWdlLCBkZXJpdmVkUGFyYW1zLmtleSwgY2ZnKTsKCiAgICAgICAgICAgICAgLy8gTWl4IGluIGRlcml2ZWQgcGFyYW1zCiAgICAgICAgICAgICAgY2lwaGVydGV4dC5taXhJbihkZXJpdmVkUGFyYW1zKTsKICAgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIERlY3J5cHRzIHNlcmlhbGl6ZWQgY2lwaGVydGV4dCB1c2luZyBhIHBhc3N3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS4KICAgICAgICAgICAgICogQHBhcmFtIHtDaXBoZXJQYXJhbXN8c3RyaW5nfSBjaXBoZXJ0ZXh0IFRoZSBjaXBoZXJ0ZXh0IHRvIGRlY3J5cHQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHBsYWludGV4dC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmRlY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIGZvcm1hdHRlZENpcGhlcnRleHQsICdwYXNzd29yZCcsIHsgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTsKICAgICAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBkZWNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBjaXBoZXJ0ZXh0LCBwYXNzd29yZCwgY2ZnKSB7CiAgICAgICAgICAgICAgLy8gQXBwbHkgY29uZmlnIGRlZmF1bHRzCiAgICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7CgogICAgICAgICAgICAgIC8vIENvbnZlcnQgc3RyaW5nIHRvIENpcGhlclBhcmFtcwogICAgICAgICAgICAgIGNpcGhlcnRleHQgPSB0aGlzLl9wYXJzZShjaXBoZXJ0ZXh0LCBjZmcuZm9ybWF0KTsKCiAgICAgICAgICAgICAgLy8gRGVyaXZlIGtleSBhbmQgb3RoZXIgcGFyYW1zCiAgICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplLCBjaXBoZXJ0ZXh0LnNhbHQsIGNmZy5oYXNoZXIpOwoKICAgICAgICAgICAgICAvLyBBZGQgSVYgdG8gY29uZmlnCiAgICAgICAgICAgICAgY2ZnLml2ID0gZGVyaXZlZFBhcmFtcy5pdjsKCiAgICAgICAgICAgICAgLy8gRGVjcnlwdAogICAgICAgICAgICAgIHZhciBwbGFpbnRleHQgPSBTZXJpYWxpemFibGVDaXBoZXIuZGVjcnlwdC5jYWxsKHRoaXMsIGNpcGhlciwgY2lwaGVydGV4dCwgZGVyaXZlZFBhcmFtcy5rZXksIGNmZyk7CiAgICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSgpOwogICAgICB9KTsKICAgIH0pKGNpcGhlckNvcmUkMSk7CiAgICByZXR1cm4gY2lwaGVyQ29yZSQxLmV4cG9ydHM7CiAgfQoKICB2YXIgbW9kZUNmYiQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIG1vZGVDZmIgPSBtb2RlQ2ZiJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRNb2RlQ2ZiOwogIGZ1bmN0aW9uIHJlcXVpcmVNb2RlQ2ZiKCkgewogICAgaWYgKGhhc1JlcXVpcmVkTW9kZUNmYikgcmV0dXJuIG1vZGVDZmIkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRNb2RlQ2ZiID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShtb2RlQ2ZiLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAvKioKICAgICAgICAgKiBDaXBoZXIgRmVlZGJhY2sgYmxvY2sgbW9kZS4KICAgICAgICAgKi8KICAgICAgICBDcnlwdG9KUy5tb2RlLkNGQiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgIHZhciBDRkIgPSBDcnlwdG9KUy5saWIuQmxvY2tDaXBoZXJNb2RlLmV4dGVuZCgpOwogICAgICAgICAgQ0ZCLkVuY3J5cHRvciA9IENGQi5leHRlbmQoewogICAgICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGNpcGhlciA9IHRoaXMuX2NpcGhlcjsKICAgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTsKICAgICAgICAgICAgICBnZW5lcmF0ZUtleXN0cmVhbUFuZEVuY3J5cHQuY2FsbCh0aGlzLCB3b3Jkcywgb2Zmc2V0LCBibG9ja1NpemUsIGNpcGhlcik7CgogICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoaXMgYmxvY2sgdG8gdXNlIHdpdGggbmV4dCBibG9jawogICAgICAgICAgICAgIHRoaXMuX3ByZXZCbG9jayA9IHdvcmRzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBDRkIuRGVjcnlwdG9yID0gQ0ZCLmV4dGVuZCh7CiAgICAgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyOwogICAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSBjaXBoZXIuYmxvY2tTaXplOwoKICAgICAgICAgICAgICAvLyBSZW1lbWJlciB0aGlzIGJsb2NrIHRvIHVzZSB3aXRoIG5leHQgYmxvY2sKICAgICAgICAgICAgICB2YXIgdGhpc0Jsb2NrID0gd29yZHMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBibG9ja1NpemUpOwogICAgICAgICAgICAgIGdlbmVyYXRlS2V5c3RyZWFtQW5kRW5jcnlwdC5jYWxsKHRoaXMsIHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSwgY2lwaGVyKTsKCiAgICAgICAgICAgICAgLy8gVGhpcyBibG9jayBiZWNvbWVzIHRoZSBwcmV2aW91cyBibG9jawogICAgICAgICAgICAgIHRoaXMuX3ByZXZCbG9jayA9IHRoaXNCbG9jazsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBmdW5jdGlvbiBnZW5lcmF0ZUtleXN0cmVhbUFuZEVuY3J5cHQod29yZHMsIG9mZnNldCwgYmxvY2tTaXplLCBjaXBoZXIpIHsKICAgICAgICAgICAgdmFyIGtleXN0cmVhbTsKCiAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgIHZhciBpdiA9IHRoaXMuX2l2OwoKICAgICAgICAgICAgLy8gR2VuZXJhdGUga2V5c3RyZWFtCiAgICAgICAgICAgIGlmIChpdikgewogICAgICAgICAgICAgIGtleXN0cmVhbSA9IGl2LnNsaWNlKDApOwoKICAgICAgICAgICAgICAvLyBSZW1vdmUgSVYgZm9yIHN1YnNlcXVlbnQgYmxvY2tzCiAgICAgICAgICAgICAgdGhpcy5faXYgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAga2V5c3RyZWFtID0gdGhpcy5fcHJldkJsb2NrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNpcGhlci5lbmNyeXB0QmxvY2soa2V5c3RyZWFtLCAwKTsKCiAgICAgICAgICAgIC8vIEVuY3J5cHQKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja1NpemU7IGkrKykgewogICAgICAgICAgICAgIHdvcmRzW29mZnNldCArIGldIF49IGtleXN0cmVhbVtpXTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIENGQjsKICAgICAgICB9KCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLm1vZGUuQ0ZCOwogICAgICB9KTsKICAgIH0pKG1vZGVDZmIkMSk7CiAgICByZXR1cm4gbW9kZUNmYiQxLmV4cG9ydHM7CiAgfQoKICB2YXIgbW9kZUN0ciQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIG1vZGVDdHIgPSBtb2RlQ3RyJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRNb2RlQ3RyOwogIGZ1bmN0aW9uIHJlcXVpcmVNb2RlQ3RyKCkgewogICAgaWYgKGhhc1JlcXVpcmVkTW9kZUN0cikgcmV0dXJuIG1vZGVDdHIkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRNb2RlQ3RyID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShtb2RlQ3RyLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAvKioKICAgICAgICAgKiBDb3VudGVyIGJsb2NrIG1vZGUuCiAgICAgICAgICovCiAgICAgICAgQ3J5cHRvSlMubW9kZS5DVFIgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICB2YXIgQ1RSID0gQ3J5cHRvSlMubGliLkJsb2NrQ2lwaGVyTW9kZS5leHRlbmQoKTsKICAgICAgICAgIHZhciBFbmNyeXB0b3IgPSBDVFIuRW5jcnlwdG9yID0gQ1RSLmV4dGVuZCh7CiAgICAgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyOwogICAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSBjaXBoZXIuYmxvY2tTaXplOwogICAgICAgICAgICAgIHZhciBpdiA9IHRoaXMuX2l2OwogICAgICAgICAgICAgIHZhciBjb3VudGVyID0gdGhpcy5fY291bnRlcjsKCiAgICAgICAgICAgICAgLy8gR2VuZXJhdGUga2V5c3RyZWFtCiAgICAgICAgICAgICAgaWYgKGl2KSB7CiAgICAgICAgICAgICAgICBjb3VudGVyID0gdGhpcy5fY291bnRlciA9IGl2LnNsaWNlKDApOwoKICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBJViBmb3Igc3Vic2VxdWVudCBibG9ja3MKICAgICAgICAgICAgICAgIHRoaXMuX2l2ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB2YXIga2V5c3RyZWFtID0gY291bnRlci5zbGljZSgwKTsKICAgICAgICAgICAgICBjaXBoZXIuZW5jcnlwdEJsb2NrKGtleXN0cmVhbSwgMCk7CgogICAgICAgICAgICAgIC8vIEluY3JlbWVudCBjb3VudGVyCiAgICAgICAgICAgICAgY291bnRlcltibG9ja1NpemUgLSAxXSA9IGNvdW50ZXJbYmxvY2tTaXplIC0gMV0gKyAxIHwgMDsKCiAgICAgICAgICAgICAgLy8gRW5jcnlwdAogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIHdvcmRzW29mZnNldCArIGldIF49IGtleXN0cmVhbVtpXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgICAgQ1RSLkRlY3J5cHRvciA9IEVuY3J5cHRvcjsKICAgICAgICAgIHJldHVybiBDVFI7CiAgICAgICAgfSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5tb2RlLkNUUjsKICAgICAgfSk7CiAgICB9KShtb2RlQ3RyJDEpOwogICAgcmV0dXJuIG1vZGVDdHIkMS5leHBvcnRzOwogIH0KCiAgdmFyIG1vZGVDdHJHbGFkbWFuJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgbW9kZUN0ckdsYWRtYW4gPSBtb2RlQ3RyR2xhZG1hbiQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkTW9kZUN0ckdsYWRtYW47CiAgZnVuY3Rpb24gcmVxdWlyZU1vZGVDdHJHbGFkbWFuKCkgewogICAgaWYgKGhhc1JlcXVpcmVkTW9kZUN0ckdsYWRtYW4pIHJldHVybiBtb2RlQ3RyR2xhZG1hbiQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZE1vZGVDdHJHbGFkbWFuID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShtb2RlQ3RyR2xhZG1hbiwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgLyoqIEBwcmVzZXJ2ZQogICAgICAgICAqIENvdW50ZXIgYmxvY2sgbW9kZSBjb21wYXRpYmxlIHdpdGggIERyIEJyaWFuIEdsYWRtYW4gZmlsZWVuYy5jCiAgICAgICAgICogZGVyaXZlZCBmcm9tIENyeXB0b0pTLm1vZGUuQ1RSCiAgICAgICAgICogSmFuIEhydWJ5IGpocnVieS53ZWJAZ21haWwuY29tCiAgICAgICAgICovCiAgICAgICAgQ3J5cHRvSlMubW9kZS5DVFJHbGFkbWFuID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgdmFyIENUUkdsYWRtYW4gPSBDcnlwdG9KUy5saWIuQmxvY2tDaXBoZXJNb2RlLmV4dGVuZCgpOwogICAgICAgICAgZnVuY3Rpb24gaW5jV29yZCh3b3JkKSB7CiAgICAgICAgICAgIGlmICgod29yZCA+PiAyNCAmIDB4ZmYpID09PSAweGZmKSB7CiAgICAgICAgICAgICAgLy9vdmVyZmxvdwogICAgICAgICAgICAgIHZhciBiMSA9IHdvcmQgPj4gMTYgJiAweGZmOwogICAgICAgICAgICAgIHZhciBiMiA9IHdvcmQgPj4gOCAmIDB4ZmY7CiAgICAgICAgICAgICAgdmFyIGIzID0gd29yZCAmIDB4ZmY7CiAgICAgICAgICAgICAgaWYgKGIxID09PSAweGZmKQogICAgICAgICAgICAgICAgLy8gb3ZlcmZsb3cgYjEKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgYjEgPSAwOwogICAgICAgICAgICAgICAgICBpZiAoYjIgPT09IDB4ZmYpIHsKICAgICAgICAgICAgICAgICAgICBiMiA9IDA7CiAgICAgICAgICAgICAgICAgICAgaWYgKGIzID09PSAweGZmKSB7CiAgICAgICAgICAgICAgICAgICAgICBiMyA9IDA7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICsrYjM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICsrYjI7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICArK2IxOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB3b3JkID0gMDsKICAgICAgICAgICAgICB3b3JkICs9IGIxIDw8IDE2OwogICAgICAgICAgICAgIHdvcmQgKz0gYjIgPDwgODsKICAgICAgICAgICAgICB3b3JkICs9IGIzOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHdvcmQgKz0gMHgwMSA8PCAyNDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gd29yZDsKICAgICAgICAgIH0KICAgICAgICAgIGZ1bmN0aW9uIGluY0NvdW50ZXIoY291bnRlcikgewogICAgICAgICAgICBpZiAoKGNvdW50ZXJbMF0gPSBpbmNXb3JkKGNvdW50ZXJbMF0pKSA9PT0gMCkgewogICAgICAgICAgICAgIC8vIGVuY3JfZGF0YSBpbiBmaWxlZW5jLmMgZnJvbSAgRHIgQnJpYW4gR2xhZG1hbidzIGNvdW50cyBvbmx5IHdpdGggRFdPUkQgaiA8IDgKICAgICAgICAgICAgICBjb3VudGVyWzFdID0gaW5jV29yZChjb3VudGVyWzFdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY291bnRlcjsKICAgICAgICAgIH0KICAgICAgICAgIHZhciBFbmNyeXB0b3IgPSBDVFJHbGFkbWFuLkVuY3J5cHRvciA9IENUUkdsYWRtYW4uZXh0ZW5kKHsKICAgICAgICAgICAgcHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBjaXBoZXIgPSB0aGlzLl9jaXBoZXI7CiAgICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZSA9IGNpcGhlci5ibG9ja1NpemU7CiAgICAgICAgICAgICAgdmFyIGl2ID0gdGhpcy5faXY7CiAgICAgICAgICAgICAgdmFyIGNvdW50ZXIgPSB0aGlzLl9jb3VudGVyOwoKICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBrZXlzdHJlYW0KICAgICAgICAgICAgICBpZiAoaXYpIHsKICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB0aGlzLl9jb3VudGVyID0gaXYuc2xpY2UoMCk7CgogICAgICAgICAgICAgICAgLy8gUmVtb3ZlIElWIGZvciBzdWJzZXF1ZW50IGJsb2NrcwogICAgICAgICAgICAgICAgdGhpcy5faXYgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGluY0NvdW50ZXIoY291bnRlcik7CiAgICAgICAgICAgICAgdmFyIGtleXN0cmVhbSA9IGNvdW50ZXIuc2xpY2UoMCk7CiAgICAgICAgICAgICAgY2lwaGVyLmVuY3J5cHRCbG9jayhrZXlzdHJlYW0sIDApOwoKICAgICAgICAgICAgICAvLyBFbmNyeXB0CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja1NpemU7IGkrKykgewogICAgICAgICAgICAgICAgd29yZHNbb2Zmc2V0ICsgaV0gXj0ga2V5c3RyZWFtW2ldOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBDVFJHbGFkbWFuLkRlY3J5cHRvciA9IEVuY3J5cHRvcjsKICAgICAgICAgIHJldHVybiBDVFJHbGFkbWFuOwogICAgICAgIH0oKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMubW9kZS5DVFJHbGFkbWFuOwogICAgICB9KTsKICAgIH0pKG1vZGVDdHJHbGFkbWFuJDEpOwogICAgcmV0dXJuIG1vZGVDdHJHbGFkbWFuJDEuZXhwb3J0czsKICB9CgogIHZhciBtb2RlT2ZiJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgbW9kZU9mYiA9IG1vZGVPZmIkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZE1vZGVPZmI7CiAgZnVuY3Rpb24gcmVxdWlyZU1vZGVPZmIoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRNb2RlT2ZiKSByZXR1cm4gbW9kZU9mYiQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZE1vZGVPZmIgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKG1vZGVPZmIsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIC8qKgogICAgICAgICAqIE91dHB1dCBGZWVkYmFjayBibG9jayBtb2RlLgogICAgICAgICAqLwogICAgICAgIENyeXB0b0pTLm1vZGUuT0ZCID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgdmFyIE9GQiA9IENyeXB0b0pTLmxpYi5CbG9ja0NpcGhlck1vZGUuZXh0ZW5kKCk7CiAgICAgICAgICB2YXIgRW5jcnlwdG9yID0gT0ZCLkVuY3J5cHRvciA9IE9GQi5leHRlbmQoewogICAgICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGNpcGhlciA9IHRoaXMuX2NpcGhlcjsKICAgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTsKICAgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLl9pdjsKICAgICAgICAgICAgICB2YXIga2V5c3RyZWFtID0gdGhpcy5fa2V5c3RyZWFtOwoKICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBrZXlzdHJlYW0KICAgICAgICAgICAgICBpZiAoaXYpIHsKICAgICAgICAgICAgICAgIGtleXN0cmVhbSA9IHRoaXMuX2tleXN0cmVhbSA9IGl2LnNsaWNlKDApOwoKICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBJViBmb3Igc3Vic2VxdWVudCBibG9ja3MKICAgICAgICAgICAgICAgIHRoaXMuX2l2ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBjaXBoZXIuZW5jcnlwdEJsb2NrKGtleXN0cmVhbSwgMCk7CgogICAgICAgICAgICAgIC8vIEVuY3J5cHQKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrU2l6ZTsgaSsrKSB7CiAgICAgICAgICAgICAgICB3b3Jkc1tvZmZzZXQgKyBpXSBePSBrZXlzdHJlYW1baV07CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICAgIE9GQi5EZWNyeXB0b3IgPSBFbmNyeXB0b3I7CiAgICAgICAgICByZXR1cm4gT0ZCOwogICAgICAgIH0oKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMubW9kZS5PRkI7CiAgICAgIH0pOwogICAgfSkobW9kZU9mYiQxKTsKICAgIHJldHVybiBtb2RlT2ZiJDEuZXhwb3J0czsKICB9CgogIHZhciBtb2RlRWNiJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgbW9kZUVjYiA9IG1vZGVFY2IkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZE1vZGVFY2I7CiAgZnVuY3Rpb24gcmVxdWlyZU1vZGVFY2IoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRNb2RlRWNiKSByZXR1cm4gbW9kZUVjYiQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZE1vZGVFY2IgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKG1vZGVFY2IsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIC8qKgogICAgICAgICAqIEVsZWN0cm9uaWMgQ29kZWJvb2sgYmxvY2sgbW9kZS4KICAgICAgICAgKi8KICAgICAgICBDcnlwdG9KUy5tb2RlLkVDQiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgIHZhciBFQ0IgPSBDcnlwdG9KUy5saWIuQmxvY2tDaXBoZXJNb2RlLmV4dGVuZCgpOwogICAgICAgICAgRUNCLkVuY3J5cHRvciA9IEVDQi5leHRlbmQoewogICAgICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgdGhpcy5fY2lwaGVyLmVuY3J5cHRCbG9jayh3b3Jkcywgb2Zmc2V0KTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBFQ0IuRGVjcnlwdG9yID0gRUNCLmV4dGVuZCh7CiAgICAgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHsKICAgICAgICAgICAgICB0aGlzLl9jaXBoZXIuZGVjcnlwdEJsb2NrKHdvcmRzLCBvZmZzZXQpOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICAgIHJldHVybiBFQ0I7CiAgICAgICAgfSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5tb2RlLkVDQjsKICAgICAgfSk7CiAgICB9KShtb2RlRWNiJDEpOwogICAgcmV0dXJuIG1vZGVFY2IkMS5leHBvcnRzOwogIH0KCiAgdmFyIHBhZEFuc2l4OTIzJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgcGFkQW5zaXg5MjMgPSBwYWRBbnNpeDkyMyQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkUGFkQW5zaXg5MjM7CiAgZnVuY3Rpb24gcmVxdWlyZVBhZEFuc2l4OTIzKCkgewogICAgaWYgKGhhc1JlcXVpcmVkUGFkQW5zaXg5MjMpIHJldHVybiBwYWRBbnNpeDkyMyQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZFBhZEFuc2l4OTIzID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShwYWRBbnNpeDkyMywgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgLyoqCiAgICAgICAgICogQU5TSSBYLjkyMyBwYWRkaW5nIHN0cmF0ZWd5LgogICAgICAgICAqLwogICAgICAgIENyeXB0b0pTLnBhZC5BbnNpWDkyMyA9IHsKICAgICAgICAgIHBhZDogZnVuY3Rpb24gKGRhdGEsIGJsb2NrU2l6ZSkgewogICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgdmFyIGRhdGFTaWdCeXRlcyA9IGRhdGEuc2lnQnl0ZXM7CiAgICAgICAgICAgIHZhciBibG9ja1NpemVCeXRlcyA9IGJsb2NrU2l6ZSAqIDQ7CgogICAgICAgICAgICAvLyBDb3VudCBwYWRkaW5nIGJ5dGVzCiAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gYmxvY2tTaXplQnl0ZXMgLSBkYXRhU2lnQnl0ZXMgJSBibG9ja1NpemVCeXRlczsKCiAgICAgICAgICAgIC8vIENvbXB1dGUgbGFzdCBieXRlIHBvc2l0aW9uCiAgICAgICAgICAgIHZhciBsYXN0Qnl0ZVBvcyA9IGRhdGFTaWdCeXRlcyArIG5QYWRkaW5nQnl0ZXMgLSAxOwoKICAgICAgICAgICAgLy8gUGFkCiAgICAgICAgICAgIGRhdGEuY2xhbXAoKTsKICAgICAgICAgICAgZGF0YS53b3Jkc1tsYXN0Qnl0ZVBvcyA+Pj4gMl0gfD0gblBhZGRpbmdCeXRlcyA8PCAyNCAtIGxhc3RCeXRlUG9zICUgNCAqIDg7CiAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgKz0gblBhZGRpbmdCeXRlczsKICAgICAgICAgIH0sCiAgICAgICAgICB1bnBhZDogZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgICAgICAgLy8gR2V0IG51bWJlciBvZiBwYWRkaW5nIGJ5dGVzIGZyb20gbGFzdCBieXRlCiAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gZGF0YS53b3Jkc1tkYXRhLnNpZ0J5dGVzIC0gMSA+Pj4gMl0gJiAweGZmOwoKICAgICAgICAgICAgLy8gUmVtb3ZlIHBhZGRpbmcKICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyAtPSBuUGFkZGluZ0J5dGVzOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLnBhZC5BbnNpeDkyMzsKICAgICAgfSk7CiAgICB9KShwYWRBbnNpeDkyMyQxKTsKICAgIHJldHVybiBwYWRBbnNpeDkyMyQxLmV4cG9ydHM7CiAgfQoKICB2YXIgcGFkSXNvMTAxMjYkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBwYWRJc28xMDEyNiA9IHBhZElzbzEwMTI2JDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRQYWRJc28xMDEyNjsKICBmdW5jdGlvbiByZXF1aXJlUGFkSXNvMTAxMjYoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRQYWRJc28xMDEyNikgcmV0dXJuIHBhZElzbzEwMTI2JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUGFkSXNvMTAxMjYgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHBhZElzbzEwMTI2LCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAvKioKICAgICAgICAgKiBJU08gMTAxMjYgcGFkZGluZyBzdHJhdGVneS4KICAgICAgICAgKi8KICAgICAgICBDcnlwdG9KUy5wYWQuSXNvMTAxMjYgPSB7CiAgICAgICAgICBwYWQ6IGZ1bmN0aW9uIChkYXRhLCBibG9ja1NpemUpIHsKICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDsKCiAgICAgICAgICAgIC8vIENvdW50IHBhZGRpbmcgYnl0ZXMKICAgICAgICAgICAgdmFyIG5QYWRkaW5nQnl0ZXMgPSBibG9ja1NpemVCeXRlcyAtIGRhdGEuc2lnQnl0ZXMgJSBibG9ja1NpemVCeXRlczsKCiAgICAgICAgICAgIC8vIFBhZAogICAgICAgICAgICBkYXRhLmNvbmNhdChDcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbShuUGFkZGluZ0J5dGVzIC0gMSkpLmNvbmNhdChDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbblBhZGRpbmdCeXRlcyA8PCAyNF0sIDEpKTsKICAgICAgICAgIH0sCiAgICAgICAgICB1bnBhZDogZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgICAgICAgLy8gR2V0IG51bWJlciBvZiBwYWRkaW5nIGJ5dGVzIGZyb20gbGFzdCBieXRlCiAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gZGF0YS53b3Jkc1tkYXRhLnNpZ0J5dGVzIC0gMSA+Pj4gMl0gJiAweGZmOwoKICAgICAgICAgICAgLy8gUmVtb3ZlIHBhZGRpbmcKICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyAtPSBuUGFkZGluZ0J5dGVzOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLnBhZC5Jc28xMDEyNjsKICAgICAgfSk7CiAgICB9KShwYWRJc28xMDEyNiQxKTsKICAgIHJldHVybiBwYWRJc28xMDEyNiQxLmV4cG9ydHM7CiAgfQoKICB2YXIgcGFkSXNvOTc5NzEkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBwYWRJc285Nzk3MSA9IHBhZElzbzk3OTcxJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRQYWRJc285Nzk3MTsKICBmdW5jdGlvbiByZXF1aXJlUGFkSXNvOTc5NzEoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRQYWRJc285Nzk3MSkgcmV0dXJuIHBhZElzbzk3OTcxJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUGFkSXNvOTc5NzEgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHBhZElzbzk3OTcxLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAvKioKICAgICAgICAgKiBJU08vSUVDIDk3OTctMSBQYWRkaW5nIE1ldGhvZCAyLgogICAgICAgICAqLwogICAgICAgIENyeXB0b0pTLnBhZC5Jc285Nzk3MSA9IHsKICAgICAgICAgIHBhZDogZnVuY3Rpb24gKGRhdGEsIGJsb2NrU2l6ZSkgewogICAgICAgICAgICAvLyBBZGQgMHg4MCBieXRlCiAgICAgICAgICAgIGRhdGEuY29uY2F0KENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKFsweDgwMDAwMDAwXSwgMSkpOwoKICAgICAgICAgICAgLy8gWmVybyBwYWQgdGhlIHJlc3QKICAgICAgICAgICAgQ3J5cHRvSlMucGFkLlplcm9QYWRkaW5nLnBhZChkYXRhLCBibG9ja1NpemUpOwogICAgICAgICAgfSwKICAgICAgICAgIHVucGFkOiBmdW5jdGlvbiAoZGF0YSkgewogICAgICAgICAgICAvLyBSZW1vdmUgemVybyBwYWRkaW5nCiAgICAgICAgICAgIENyeXB0b0pTLnBhZC5aZXJvUGFkZGluZy51bnBhZChkYXRhKTsKCiAgICAgICAgICAgIC8vIFJlbW92ZSBvbmUgbW9yZSBieXRlIC0tIHRoZSAweDgwIGJ5dGUKICAgICAgICAgICAgZGF0YS5zaWdCeXRlcy0tOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLnBhZC5Jc285Nzk3MTsKICAgICAgfSk7CiAgICB9KShwYWRJc285Nzk3MSQxKTsKICAgIHJldHVybiBwYWRJc285Nzk3MSQxLmV4cG9ydHM7CiAgfQoKICB2YXIgcGFkWmVyb3BhZGRpbmckMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBwYWRaZXJvcGFkZGluZyA9IHBhZFplcm9wYWRkaW5nJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRQYWRaZXJvcGFkZGluZzsKICBmdW5jdGlvbiByZXF1aXJlUGFkWmVyb3BhZGRpbmcoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRQYWRaZXJvcGFkZGluZykgcmV0dXJuIHBhZFplcm9wYWRkaW5nJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUGFkWmVyb3BhZGRpbmcgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHBhZFplcm9wYWRkaW5nLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAvKioKICAgICAgICAgKiBaZXJvIHBhZGRpbmcgc3RyYXRlZ3kuCiAgICAgICAgICovCiAgICAgICAgQ3J5cHRvSlMucGFkLlplcm9QYWRkaW5nID0gewogICAgICAgICAgcGFkOiBmdW5jdGlvbiAoZGF0YSwgYmxvY2tTaXplKSB7CiAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgIHZhciBibG9ja1NpemVCeXRlcyA9IGJsb2NrU2l6ZSAqIDQ7CgogICAgICAgICAgICAvLyBQYWQKICAgICAgICAgICAgZGF0YS5jbGFtcCgpOwogICAgICAgICAgICBkYXRhLnNpZ0J5dGVzICs9IGJsb2NrU2l6ZUJ5dGVzIC0gKGRhdGEuc2lnQnl0ZXMgJSBibG9ja1NpemVCeXRlcyB8fCBibG9ja1NpemVCeXRlcyk7CiAgICAgICAgICB9LAogICAgICAgICAgdW5wYWQ6IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgIHZhciBkYXRhV29yZHMgPSBkYXRhLndvcmRzOwoKICAgICAgICAgICAgLy8gVW5wYWQKICAgICAgICAgICAgdmFyIGkgPSBkYXRhLnNpZ0J5dGVzIC0gMTsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IGRhdGEuc2lnQnl0ZXMgLSAxOyBpID49IDA7IGktLSkgewogICAgICAgICAgICAgIGlmIChkYXRhV29yZHNbaSA+Pj4gMl0gPj4+IDI0IC0gaSAlIDQgKiA4ICYgMHhmZikgewogICAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGkgKyAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMucGFkLlplcm9QYWRkaW5nOwogICAgICB9KTsKICAgIH0pKHBhZFplcm9wYWRkaW5nJDEpOwogICAgcmV0dXJuIHBhZFplcm9wYWRkaW5nJDEuZXhwb3J0czsKICB9CgogIHZhciBwYWROb3BhZGRpbmckMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBwYWROb3BhZGRpbmcgPSBwYWROb3BhZGRpbmckMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFBhZE5vcGFkZGluZzsKICBmdW5jdGlvbiByZXF1aXJlUGFkTm9wYWRkaW5nKCkgewogICAgaWYgKGhhc1JlcXVpcmVkUGFkTm9wYWRkaW5nKSByZXR1cm4gcGFkTm9wYWRkaW5nJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUGFkTm9wYWRkaW5nID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShwYWROb3BhZGRpbmcsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIC8qKgogICAgICAgICAqIEEgbm9vcCBwYWRkaW5nIHN0cmF0ZWd5LgogICAgICAgICAqLwogICAgICAgIENyeXB0b0pTLnBhZC5Ob1BhZGRpbmcgPSB7CiAgICAgICAgICBwYWQ6IGZ1bmN0aW9uICgpIHt9LAogICAgICAgICAgdW5wYWQ6IGZ1bmN0aW9uICgpIHt9CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMucGFkLk5vUGFkZGluZzsKICAgICAgfSk7CiAgICB9KShwYWROb3BhZGRpbmckMSk7CiAgICByZXR1cm4gcGFkTm9wYWRkaW5nJDEuZXhwb3J0czsKICB9CgogIHZhciBmb3JtYXRIZXgkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBmb3JtYXRIZXggPSBmb3JtYXRIZXgkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZEZvcm1hdEhleDsKICBmdW5jdGlvbiByZXF1aXJlRm9ybWF0SGV4KCkgewogICAgaWYgKGhhc1JlcXVpcmVkRm9ybWF0SGV4KSByZXR1cm4gZm9ybWF0SGV4JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkRm9ybWF0SGV4ID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShmb3JtYXRIZXgsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAodW5kZWZpbmVkJDEpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIENpcGhlclBhcmFtcyA9IENfbGliLkNpcGhlclBhcmFtczsKICAgICAgICAgIHZhciBDX2VuYyA9IEMuZW5jOwogICAgICAgICAgdmFyIEhleCA9IENfZW5jLkhleDsKICAgICAgICAgIHZhciBDX2Zvcm1hdCA9IEMuZm9ybWF0OwogICAgICAgICAgQ19mb3JtYXQuSGV4ID0gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgdGhlIGNpcGhlcnRleHQgb2YgYSBjaXBoZXIgcGFyYW1zIG9iamVjdCB0byBhIGhleGFkZWNpbWFsbHkgZW5jb2RlZCBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfSBjaXBoZXJQYXJhbXMgVGhlIGNpcGhlciBwYXJhbXMgb2JqZWN0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBoZXhhZGVjaW1hbGx5IGVuY29kZWQgc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgaGV4U3RyaW5nID0gQ3J5cHRvSlMuZm9ybWF0LkhleC5zdHJpbmdpZnkoY2lwaGVyUGFyYW1zKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKGNpcGhlclBhcmFtcykgewogICAgICAgICAgICAgIHJldHVybiBjaXBoZXJQYXJhbXMuY2lwaGVydGV4dC50b1N0cmluZyhIZXgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSBoZXhhZGVjaW1hbGx5IGVuY29kZWQgY2lwaGVydGV4dCBzdHJpbmcgdG8gYSBjaXBoZXIgcGFyYW1zIG9iamVjdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IFRoZSBoZXhhZGVjaW1hbGx5IGVuY29kZWQgc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IFRoZSBjaXBoZXIgcGFyYW1zIG9iamVjdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlclBhcmFtcyA9IENyeXB0b0pTLmZvcm1hdC5IZXgucGFyc2UoaGV4U3RyaW5nKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAoaW5wdXQpIHsKICAgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IEhleC5wYXJzZShpbnB1dCk7CiAgICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoewogICAgICAgICAgICAgICAgY2lwaGVydGV4dDogY2lwaGVydGV4dAogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLmZvcm1hdC5IZXg7CiAgICAgIH0pOwogICAgfSkoZm9ybWF0SGV4JDEpOwogICAgcmV0dXJuIGZvcm1hdEhleCQxLmV4cG9ydHM7CiAgfQoKICB2YXIgYWVzJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgYWVzID0gYWVzJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRBZXM7CiAgZnVuY3Rpb24gcmVxdWlyZUFlcygpIHsKICAgIGlmIChoYXNSZXF1aXJlZEFlcykgcmV0dXJuIGFlcyQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZEFlcyA9IDE7CiAgICAoZnVuY3Rpb24gKG1vZHVsZSwgZXhwb3J0cyQxKSB7CiAgICAgIChmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHsKICAgICAgICB7CiAgICAgICAgICAvLyBDb21tb25KUwogICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmVDb3JlKCksIHJlcXVpcmVFbmNCYXNlNjQoKSwgcmVxdWlyZU1kNSgpLCByZXF1aXJlRXZwa2RmKCksIHJlcXVpcmVDaXBoZXJDb3JlKCkpOwogICAgICAgIH0KICAgICAgfSkoYWVzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICB2YXIgQyA9IENyeXB0b0pTOwogICAgICAgICAgdmFyIENfbGliID0gQy5saWI7CiAgICAgICAgICB2YXIgQmxvY2tDaXBoZXIgPSBDX2xpYi5CbG9ja0NpcGhlcjsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CgogICAgICAgICAgLy8gTG9va3VwIHRhYmxlcwogICAgICAgICAgdmFyIFNCT1ggPSBbXTsKICAgICAgICAgIHZhciBJTlZfU0JPWCA9IFtdOwogICAgICAgICAgdmFyIFNVQl9NSVhfMCA9IFtdOwogICAgICAgICAgdmFyIFNVQl9NSVhfMSA9IFtdOwogICAgICAgICAgdmFyIFNVQl9NSVhfMiA9IFtdOwogICAgICAgICAgdmFyIFNVQl9NSVhfMyA9IFtdOwogICAgICAgICAgdmFyIElOVl9TVUJfTUlYXzAgPSBbXTsKICAgICAgICAgIHZhciBJTlZfU1VCX01JWF8xID0gW107CiAgICAgICAgICB2YXIgSU5WX1NVQl9NSVhfMiA9IFtdOwogICAgICAgICAgdmFyIElOVl9TVUJfTUlYXzMgPSBbXTsKCiAgICAgICAgICAvLyBDb21wdXRlIGxvb2t1cCB0YWJsZXMKICAgICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIENvbXB1dGUgZG91YmxlIHRhYmxlCiAgICAgICAgICAgIHZhciBkID0gW107CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgICBpZiAoaSA8IDEyOCkgewogICAgICAgICAgICAgICAgZFtpXSA9IGkgPDwgMTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZFtpXSA9IGkgPDwgMSBeIDB4MTFiOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gV2FsayBHRigyXjgpCiAgICAgICAgICAgIHZhciB4ID0gMDsKICAgICAgICAgICAgdmFyIHhpID0gMDsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICAgIC8vIENvbXB1dGUgc2JveAogICAgICAgICAgICAgIHZhciBzeCA9IHhpIF4geGkgPDwgMSBeIHhpIDw8IDIgXiB4aSA8PCAzIF4geGkgPDwgNDsKICAgICAgICAgICAgICBzeCA9IHN4ID4+PiA4IF4gc3ggJiAweGZmIF4gMHg2MzsKICAgICAgICAgICAgICBTQk9YW3hdID0gc3g7CiAgICAgICAgICAgICAgSU5WX1NCT1hbc3hdID0geDsKCiAgICAgICAgICAgICAgLy8gQ29tcHV0ZSBtdWx0aXBsaWNhdGlvbgogICAgICAgICAgICAgIHZhciB4MiA9IGRbeF07CiAgICAgICAgICAgICAgdmFyIHg0ID0gZFt4Ml07CiAgICAgICAgICAgICAgdmFyIHg4ID0gZFt4NF07CgogICAgICAgICAgICAgIC8vIENvbXB1dGUgc3ViIGJ5dGVzLCBtaXggY29sdW1ucyB0YWJsZXMKICAgICAgICAgICAgICB2YXIgdCA9IGRbc3hdICogMHgxMDEgXiBzeCAqIDB4MTAxMDEwMDsKICAgICAgICAgICAgICBTVUJfTUlYXzBbeF0gPSB0IDw8IDI0IHwgdCA+Pj4gODsKICAgICAgICAgICAgICBTVUJfTUlYXzFbeF0gPSB0IDw8IDE2IHwgdCA+Pj4gMTY7CiAgICAgICAgICAgICAgU1VCX01JWF8yW3hdID0gdCA8PCA4IHwgdCA+Pj4gMjQ7CiAgICAgICAgICAgICAgU1VCX01JWF8zW3hdID0gdDsKCiAgICAgICAgICAgICAgLy8gQ29tcHV0ZSBpbnYgc3ViIGJ5dGVzLCBpbnYgbWl4IGNvbHVtbnMgdGFibGVzCiAgICAgICAgICAgICAgdmFyIHQgPSB4OCAqIDB4MTAxMDEwMSBeIHg0ICogMHgxMDAwMSBeIHgyICogMHgxMDEgXiB4ICogMHgxMDEwMTAwOwogICAgICAgICAgICAgIElOVl9TVUJfTUlYXzBbc3hdID0gdCA8PCAyNCB8IHQgPj4+IDg7CiAgICAgICAgICAgICAgSU5WX1NVQl9NSVhfMVtzeF0gPSB0IDw8IDE2IHwgdCA+Pj4gMTY7CiAgICAgICAgICAgICAgSU5WX1NVQl9NSVhfMltzeF0gPSB0IDw8IDggfCB0ID4+PiAyNDsKICAgICAgICAgICAgICBJTlZfU1VCX01JWF8zW3N4XSA9IHQ7CgogICAgICAgICAgICAgIC8vIENvbXB1dGUgbmV4dCBjb3VudGVyCiAgICAgICAgICAgICAgaWYgKCF4KSB7CiAgICAgICAgICAgICAgICB4ID0geGkgPSAxOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB4ID0geDIgXiBkW2RbZFt4OCBeIHgyXV1dOwogICAgICAgICAgICAgICAgeGkgXj0gZFtkW3hpXV07CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9KSgpOwoKICAgICAgICAgIC8vIFByZWNvbXB1dGVkIFJjb24gbG9va3VwCiAgICAgICAgICB2YXIgUkNPTiA9IFsweDAwLCAweDAxLCAweDAyLCAweDA0LCAweDA4LCAweDEwLCAweDIwLCAweDQwLCAweDgwLCAweDFiLCAweDM2XTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFFUyBibG9jayBjaXBoZXIgYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgQUVTID0gQ19hbGdvLkFFUyA9IEJsb2NrQ2lwaGVyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdmFyIHQ7CgogICAgICAgICAgICAgIC8vIFNraXAgcmVzZXQgb2YgblJvdW5kcyBoYXMgYmVlbiBzZXQgYmVmb3JlIGFuZCBrZXkgZGlkIG5vdCBjaGFuZ2UKICAgICAgICAgICAgICBpZiAodGhpcy5fblJvdW5kcyAmJiB0aGlzLl9rZXlQcmlvclJlc2V0ID09PSB0aGlzLl9rZXkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBrZXkgPSB0aGlzLl9rZXlQcmlvclJlc2V0ID0gdGhpcy5fa2V5OwogICAgICAgICAgICAgIHZhciBrZXlXb3JkcyA9IGtleS53b3JkczsKICAgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGtleS5zaWdCeXRlcyAvIDQ7CgogICAgICAgICAgICAgIC8vIENvbXB1dGUgbnVtYmVyIG9mIHJvdW5kcwogICAgICAgICAgICAgIHZhciBuUm91bmRzID0gdGhpcy5fblJvdW5kcyA9IGtleVNpemUgKyA2OwoKICAgICAgICAgICAgICAvLyBDb21wdXRlIG51bWJlciBvZiBrZXkgc2NoZWR1bGUgcm93cwogICAgICAgICAgICAgIHZhciBrc1Jvd3MgPSAoblJvdW5kcyArIDEpICogNDsKCiAgICAgICAgICAgICAgLy8gQ29tcHV0ZSBrZXkgc2NoZWR1bGUKICAgICAgICAgICAgICB2YXIga2V5U2NoZWR1bGUgPSB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGtzUm93ID0gMDsga3NSb3cgPCBrc1Jvd3M7IGtzUm93KyspIHsKICAgICAgICAgICAgICAgIGlmIChrc1JvdyA8IGtleVNpemUpIHsKICAgICAgICAgICAgICAgICAga2V5U2NoZWR1bGVba3NSb3ddID0ga2V5V29yZHNba3NSb3ddOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgdCA9IGtleVNjaGVkdWxlW2tzUm93IC0gMV07CiAgICAgICAgICAgICAgICAgIGlmICghKGtzUm93ICUga2V5U2l6ZSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBSb3Qgd29yZAogICAgICAgICAgICAgICAgICAgIHQgPSB0IDw8IDggfCB0ID4+PiAyNDsKCiAgICAgICAgICAgICAgICAgICAgLy8gU3ViIHdvcmQKICAgICAgICAgICAgICAgICAgICB0ID0gU0JPWFt0ID4+PiAyNF0gPDwgMjQgfCBTQk9YW3QgPj4+IDE2ICYgMHhmZl0gPDwgMTYgfCBTQk9YW3QgPj4+IDggJiAweGZmXSA8PCA4IHwgU0JPWFt0ICYgMHhmZl07CgogICAgICAgICAgICAgICAgICAgIC8vIE1peCBSY29uCiAgICAgICAgICAgICAgICAgICAgdCBePSBSQ09OW2tzUm93IC8ga2V5U2l6ZSB8IDBdIDw8IDI0OwogICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PSA0KSB7CiAgICAgICAgICAgICAgICAgICAgLy8gU3ViIHdvcmQKICAgICAgICAgICAgICAgICAgICB0ID0gU0JPWFt0ID4+PiAyNF0gPDwgMjQgfCBTQk9YW3QgPj4+IDE2ICYgMHhmZl0gPDwgMTYgfCBTQk9YW3QgPj4+IDggJiAweGZmXSA8PCA4IHwgU0JPWFt0ICYgMHhmZl07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAga2V5U2NoZWR1bGVba3NSb3ddID0ga2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBDb21wdXRlIGludiBrZXkgc2NoZWR1bGUKICAgICAgICAgICAgICB2YXIgaW52S2V5U2NoZWR1bGUgPSB0aGlzLl9pbnZLZXlTY2hlZHVsZSA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGludktzUm93ID0gMDsgaW52S3NSb3cgPCBrc1Jvd3M7IGludktzUm93KyspIHsKICAgICAgICAgICAgICAgIHZhciBrc1JvdyA9IGtzUm93cyAtIGludktzUm93OwogICAgICAgICAgICAgICAgaWYgKGludktzUm93ICUgNCkgewogICAgICAgICAgICAgICAgICB2YXIgdCA9IGtleVNjaGVkdWxlW2tzUm93XTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHZhciB0ID0ga2V5U2NoZWR1bGVba3NSb3cgLSA0XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpbnZLc1JvdyA8IDQgfHwga3NSb3cgPD0gNCkgewogICAgICAgICAgICAgICAgICBpbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSB0OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW52S2V5U2NoZWR1bGVbaW52S3NSb3ddID0gSU5WX1NVQl9NSVhfMFtTQk9YW3QgPj4+IDI0XV0gXiBJTlZfU1VCX01JWF8xW1NCT1hbdCA+Pj4gMTYgJiAweGZmXV0gXiBJTlZfU1VCX01JWF8yW1NCT1hbdCA+Pj4gOCAmIDB4ZmZdXSBeIElOVl9TVUJfTUlYXzNbU0JPWFt0ICYgMHhmZl1dOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgZW5jcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgdGhpcy5fZG9DcnlwdEJsb2NrKE0sIG9mZnNldCwgdGhpcy5fa2V5U2NoZWR1bGUsIFNVQl9NSVhfMCwgU1VCX01JWF8xLCBTVUJfTUlYXzIsIFNVQl9NSVhfMywgU0JPWCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGRlY3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkgewogICAgICAgICAgICAgIC8vIFN3YXAgMm5kIGFuZCA0dGggcm93cwogICAgICAgICAgICAgIHZhciB0ID0gTVtvZmZzZXQgKyAxXTsKICAgICAgICAgICAgICBNW29mZnNldCArIDFdID0gTVtvZmZzZXQgKyAzXTsKICAgICAgICAgICAgICBNW29mZnNldCArIDNdID0gdDsKICAgICAgICAgICAgICB0aGlzLl9kb0NyeXB0QmxvY2soTSwgb2Zmc2V0LCB0aGlzLl9pbnZLZXlTY2hlZHVsZSwgSU5WX1NVQl9NSVhfMCwgSU5WX1NVQl9NSVhfMSwgSU5WX1NVQl9NSVhfMiwgSU5WX1NVQl9NSVhfMywgSU5WX1NCT1gpOwoKICAgICAgICAgICAgICAvLyBJbnYgc3dhcCAybmQgYW5kIDR0aCByb3dzCiAgICAgICAgICAgICAgdmFyIHQgPSBNW29mZnNldCArIDFdOwogICAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSBNW29mZnNldCArIDNdOwogICAgICAgICAgICAgIE1bb2Zmc2V0ICsgM10gPSB0OwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9DcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0LCBrZXlTY2hlZHVsZSwgU1VCX01JWF8wLCBTVUJfTUlYXzEsIFNVQl9NSVhfMiwgU1VCX01JWF8zLCBTQk9YKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgblJvdW5kcyA9IHRoaXMuX25Sb3VuZHM7CgogICAgICAgICAgICAgIC8vIEdldCBpbnB1dCwgYWRkIHJvdW5kIGtleQogICAgICAgICAgICAgIHZhciBzMCA9IE1bb2Zmc2V0XSBeIGtleVNjaGVkdWxlWzBdOwogICAgICAgICAgICAgIHZhciBzMSA9IE1bb2Zmc2V0ICsgMV0gXiBrZXlTY2hlZHVsZVsxXTsKICAgICAgICAgICAgICB2YXIgczIgPSBNW29mZnNldCArIDJdIF4ga2V5U2NoZWR1bGVbMl07CiAgICAgICAgICAgICAgdmFyIHMzID0gTVtvZmZzZXQgKyAzXSBeIGtleVNjaGVkdWxlWzNdOwoKICAgICAgICAgICAgICAvLyBLZXkgc2NoZWR1bGUgcm93IGNvdW50ZXIKICAgICAgICAgICAgICB2YXIga3NSb3cgPSA0OwoKICAgICAgICAgICAgICAvLyBSb3VuZHMKICAgICAgICAgICAgICBmb3IgKHZhciByb3VuZCA9IDE7IHJvdW5kIDwgblJvdW5kczsgcm91bmQrKykgewogICAgICAgICAgICAgICAgLy8gU2hpZnQgcm93cywgc3ViIGJ5dGVzLCBtaXggY29sdW1ucywgYWRkIHJvdW5kIGtleQogICAgICAgICAgICAgICAgdmFyIHQwID0gU1VCX01JWF8wW3MwID4+PiAyNF0gXiBTVUJfTUlYXzFbczEgPj4+IDE2ICYgMHhmZl0gXiBTVUJfTUlYXzJbczIgPj4+IDggJiAweGZmXSBeIFNVQl9NSVhfM1tzMyAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107CiAgICAgICAgICAgICAgICB2YXIgdDEgPSBTVUJfTUlYXzBbczEgPj4+IDI0XSBeIFNVQl9NSVhfMVtzMiA+Pj4gMTYgJiAweGZmXSBeIFNVQl9NSVhfMltzMyA+Pj4gOCAmIDB4ZmZdIF4gU1VCX01JWF8zW3MwICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTsKICAgICAgICAgICAgICAgIHZhciB0MiA9IFNVQl9NSVhfMFtzMiA+Pj4gMjRdIF4gU1VCX01JWF8xW3MzID4+PiAxNiAmIDB4ZmZdIF4gU1VCX01JWF8yW3MwID4+PiA4ICYgMHhmZl0gXiBTVUJfTUlYXzNbczEgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdOwogICAgICAgICAgICAgICAgdmFyIHQzID0gU1VCX01JWF8wW3MzID4+PiAyNF0gXiBTVUJfTUlYXzFbczAgPj4+IDE2ICYgMHhmZl0gXiBTVUJfTUlYXzJbczEgPj4+IDggJiAweGZmXSBeIFNVQl9NSVhfM1tzMiAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107CgogICAgICAgICAgICAgICAgLy8gVXBkYXRlIHN0YXRlCiAgICAgICAgICAgICAgICBzMCA9IHQwOwogICAgICAgICAgICAgICAgczEgPSB0MTsKICAgICAgICAgICAgICAgIHMyID0gdDI7CiAgICAgICAgICAgICAgICBzMyA9IHQzOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gU2hpZnQgcm93cywgc3ViIGJ5dGVzLCBhZGQgcm91bmQga2V5CiAgICAgICAgICAgICAgdmFyIHQwID0gKFNCT1hbczAgPj4+IDI0XSA8PCAyNCB8IFNCT1hbczEgPj4+IDE2ICYgMHhmZl0gPDwgMTYgfCBTQk9YW3MyID4+PiA4ICYgMHhmZl0gPDwgOCB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTsKICAgICAgICAgICAgICB2YXIgdDEgPSAoU0JPWFtzMSA+Pj4gMjRdIDw8IDI0IHwgU0JPWFtzMiA+Pj4gMTYgJiAweGZmXSA8PCAxNiB8IFNCT1hbczMgPj4+IDggJiAweGZmXSA8PCA4IHwgU0JPWFtzMCAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdOwogICAgICAgICAgICAgIHZhciB0MiA9IChTQk9YW3MyID4+PiAyNF0gPDwgMjQgfCBTQk9YW3MzID4+PiAxNiAmIDB4ZmZdIDw8IDE2IHwgU0JPWFtzMCA+Pj4gOCAmIDB4ZmZdIDw8IDggfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK107CiAgICAgICAgICAgICAgdmFyIHQzID0gKFNCT1hbczMgPj4+IDI0XSA8PCAyNCB8IFNCT1hbczAgPj4+IDE2ICYgMHhmZl0gPDwgMTYgfCBTQk9YW3MxID4+PiA4ICYgMHhmZl0gPDwgOCB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTsKCiAgICAgICAgICAgICAgLy8gU2V0IG91dHB1dAogICAgICAgICAgICAgIE1bb2Zmc2V0XSA9IHQwOwogICAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSB0MTsKICAgICAgICAgICAgICBNW29mZnNldCArIDJdID0gdDI7CiAgICAgICAgICAgICAgTVtvZmZzZXQgKyAzXSA9IHQzOwogICAgICAgICAgICB9LAogICAgICAgICAgICBrZXlTaXplOiAyNTYgLyAzMgogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5BRVMuZW5jcnlwdChtZXNzYWdlLCBrZXksIGNmZyk7CiAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCAgPSBDcnlwdG9KUy5BRVMuZGVjcnlwdChjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuQUVTID0gQmxvY2tDaXBoZXIuX2NyZWF0ZUhlbHBlcihBRVMpOwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLkFFUzsKICAgICAgfSk7CiAgICB9KShhZXMkMSk7CiAgICByZXR1cm4gYWVzJDEuZXhwb3J0czsKICB9CgogIHZhciB0cmlwbGVkZXMkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciB0cmlwbGVkZXMgPSB0cmlwbGVkZXMkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFRyaXBsZWRlczsKICBmdW5jdGlvbiByZXF1aXJlVHJpcGxlZGVzKCkgewogICAgaWYgKGhhc1JlcXVpcmVkVHJpcGxlZGVzKSByZXR1cm4gdHJpcGxlZGVzJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkVHJpcGxlZGVzID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUVuY0Jhc2U2NCgpLCByZXF1aXJlTWQ1KCksIHJlcXVpcmVFdnBrZGYoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KSh0cmlwbGVkZXMsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgQmxvY2tDaXBoZXIgPSBDX2xpYi5CbG9ja0NpcGhlcjsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CgogICAgICAgICAgLy8gUGVybXV0ZWQgQ2hvaWNlIDEgY29uc3RhbnRzCiAgICAgICAgICB2YXIgUEMxID0gWzU3LCA0OSwgNDEsIDMzLCAyNSwgMTcsIDksIDEsIDU4LCA1MCwgNDIsIDM0LCAyNiwgMTgsIDEwLCAyLCA1OSwgNTEsIDQzLCAzNSwgMjcsIDE5LCAxMSwgMywgNjAsIDUyLCA0NCwgMzYsIDYzLCA1NSwgNDcsIDM5LCAzMSwgMjMsIDE1LCA3LCA2MiwgNTQsIDQ2LCAzOCwgMzAsIDIyLCAxNCwgNiwgNjEsIDUzLCA0NSwgMzcsIDI5LCAyMSwgMTMsIDUsIDI4LCAyMCwgMTIsIDRdOwoKICAgICAgICAgIC8vIFBlcm11dGVkIENob2ljZSAyIGNvbnN0YW50cwogICAgICAgICAgdmFyIFBDMiA9IFsxNCwgMTcsIDExLCAyNCwgMSwgNSwgMywgMjgsIDE1LCA2LCAyMSwgMTAsIDIzLCAxOSwgMTIsIDQsIDI2LCA4LCAxNiwgNywgMjcsIDIwLCAxMywgMiwgNDEsIDUyLCAzMSwgMzcsIDQ3LCA1NSwgMzAsIDQwLCA1MSwgNDUsIDMzLCA0OCwgNDQsIDQ5LCAzOSwgNTYsIDM0LCA1MywgNDYsIDQyLCA1MCwgMzYsIDI5LCAzMl07CgogICAgICAgICAgLy8gQ3VtdWxhdGl2ZSBiaXQgc2hpZnQgY29uc3RhbnRzCiAgICAgICAgICB2YXIgQklUX1NISUZUUyA9IFsxLCAyLCA0LCA2LCA4LCAxMCwgMTIsIDE0LCAxNSwgMTcsIDE5LCAyMSwgMjMsIDI1LCAyNywgMjhdOwoKICAgICAgICAgIC8vIFNCT1hlcyBhbmQgcm91bmQgcGVybXV0YXRpb24gY29uc3RhbnRzCiAgICAgICAgICB2YXIgU0JPWF9QID0gW3sKICAgICAgICAgICAgMHgwOiAweDgwODIwMCwKICAgICAgICAgICAgMHgxMDAwMDAwMDogMHg4MDAwLAogICAgICAgICAgICAweDIwMDAwMDAwOiAweDgwODAwMiwKICAgICAgICAgICAgMHgzMDAwMDAwMDogMHgyLAogICAgICAgICAgICAweDQwMDAwMDAwOiAweDIwMCwKICAgICAgICAgICAgMHg1MDAwMDAwMDogMHg4MDgyMDIsCiAgICAgICAgICAgIDB4NjAwMDAwMDA6IDB4ODAwMjAyLAogICAgICAgICAgICAweDcwMDAwMDAwOiAweDgwMDAwMCwKICAgICAgICAgICAgMHg4MDAwMDAwMDogMHgyMDIsCiAgICAgICAgICAgIDB4OTAwMDAwMDA6IDB4ODAwMjAwLAogICAgICAgICAgICAweGEwMDAwMDAwOiAweDgyMDAsCiAgICAgICAgICAgIDB4YjAwMDAwMDA6IDB4ODA4MDAwLAogICAgICAgICAgICAweGMwMDAwMDAwOiAweDgwMDIsCiAgICAgICAgICAgIDB4ZDAwMDAwMDA6IDB4ODAwMDAyLAogICAgICAgICAgICAweGUwMDAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4ZjAwMDAwMDA6IDB4ODIwMiwKICAgICAgICAgICAgMHg4MDAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4MTgwMDAwMDA6IDB4ODA4MjAyLAogICAgICAgICAgICAweDI4MDAwMDAwOiAweDgyMDIsCiAgICAgICAgICAgIDB4MzgwMDAwMDA6IDB4ODAwMCwKICAgICAgICAgICAgMHg0ODAwMDAwMDogMHg4MDgyMDAsCiAgICAgICAgICAgIDB4NTgwMDAwMDA6IDB4MjAwLAogICAgICAgICAgICAweDY4MDAwMDAwOiAweDgwODAwMiwKICAgICAgICAgICAgMHg3ODAwMDAwMDogMHgyLAogICAgICAgICAgICAweDg4MDAwMDAwOiAweDgwMDIwMCwKICAgICAgICAgICAgMHg5ODAwMDAwMDogMHg4MjAwLAogICAgICAgICAgICAweGE4MDAwMDAwOiAweDgwODAwMCwKICAgICAgICAgICAgMHhiODAwMDAwMDogMHg4MDAyMDIsCiAgICAgICAgICAgIDB4YzgwMDAwMDA6IDB4ODAwMDAyLAogICAgICAgICAgICAweGQ4MDAwMDAwOiAweDgwMDIsCiAgICAgICAgICAgIDB4ZTgwMDAwMDA6IDB4MjAyLAogICAgICAgICAgICAweGY4MDAwMDAwOiAweDgwMDAwMCwKICAgICAgICAgICAgMHgxOiAweDgwMDAsCiAgICAgICAgICAgIDB4MTAwMDAwMDE6IDB4MiwKICAgICAgICAgICAgMHgyMDAwMDAwMTogMHg4MDgyMDAsCiAgICAgICAgICAgIDB4MzAwMDAwMDE6IDB4ODAwMDAwLAogICAgICAgICAgICAweDQwMDAwMDAxOiAweDgwODAwMiwKICAgICAgICAgICAgMHg1MDAwMDAwMTogMHg4MjAwLAogICAgICAgICAgICAweDYwMDAwMDAxOiAweDIwMCwKICAgICAgICAgICAgMHg3MDAwMDAwMTogMHg4MDAyMDIsCiAgICAgICAgICAgIDB4ODAwMDAwMDE6IDB4ODA4MjAyLAogICAgICAgICAgICAweDkwMDAwMDAxOiAweDgwODAwMCwKICAgICAgICAgICAgMHhhMDAwMDAwMTogMHg4MDAwMDIsCiAgICAgICAgICAgIDB4YjAwMDAwMDE6IDB4ODIwMiwKICAgICAgICAgICAgMHhjMDAwMDAwMTogMHgyMDIsCiAgICAgICAgICAgIDB4ZDAwMDAwMDE6IDB4ODAwMjAwLAogICAgICAgICAgICAweGUwMDAwMDAxOiAweDgwMDIsCiAgICAgICAgICAgIDB4ZjAwMDAwMDE6IDB4MCwKICAgICAgICAgICAgMHg4MDAwMDAxOiAweDgwODIwMiwKICAgICAgICAgICAgMHgxODAwMDAwMTogMHg4MDgwMDAsCiAgICAgICAgICAgIDB4MjgwMDAwMDE6IDB4ODAwMDAwLAogICAgICAgICAgICAweDM4MDAwMDAxOiAweDIwMCwKICAgICAgICAgICAgMHg0ODAwMDAwMTogMHg4MDAwLAogICAgICAgICAgICAweDU4MDAwMDAxOiAweDgwMDAwMiwKICAgICAgICAgICAgMHg2ODAwMDAwMTogMHgyLAogICAgICAgICAgICAweDc4MDAwMDAxOiAweDgyMDIsCiAgICAgICAgICAgIDB4ODgwMDAwMDE6IDB4ODAwMiwKICAgICAgICAgICAgMHg5ODAwMDAwMTogMHg4MDAyMDIsCiAgICAgICAgICAgIDB4YTgwMDAwMDE6IDB4MjAyLAogICAgICAgICAgICAweGI4MDAwMDAxOiAweDgwODIwMCwKICAgICAgICAgICAgMHhjODAwMDAwMTogMHg4MDAyMDAsCiAgICAgICAgICAgIDB4ZDgwMDAwMDE6IDB4MCwKICAgICAgICAgICAgMHhlODAwMDAwMTogMHg4MjAwLAogICAgICAgICAgICAweGY4MDAwMDAxOiAweDgwODAwMgogICAgICAgICAgfSwgewogICAgICAgICAgICAweDA6IDB4NDAwODQwMTAsCiAgICAgICAgICAgIDB4MTAwMDAwMDogMHg0MDAwLAogICAgICAgICAgICAweDIwMDAwMDA6IDB4ODAwMDAsCiAgICAgICAgICAgIDB4MzAwMDAwMDogMHg0MDA4MDAxMCwKICAgICAgICAgICAgMHg0MDAwMDAwOiAweDQwMDAwMDEwLAogICAgICAgICAgICAweDUwMDAwMDA6IDB4NDAwODQwMDAsCiAgICAgICAgICAgIDB4NjAwMDAwMDogMHg0MDAwNDAwMCwKICAgICAgICAgICAgMHg3MDAwMDAwOiAweDEwLAogICAgICAgICAgICAweDgwMDAwMDA6IDB4ODQwMDAsCiAgICAgICAgICAgIDB4OTAwMDAwMDogMHg0MDAwNDAxMCwKICAgICAgICAgICAgMHhhMDAwMDAwOiAweDQwMDAwMDAwLAogICAgICAgICAgICAweGIwMDAwMDA6IDB4ODQwMTAsCiAgICAgICAgICAgIDB4YzAwMDAwMDogMHg4MDAxMCwKICAgICAgICAgICAgMHhkMDAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4ZTAwMDAwMDogMHg0MDEwLAogICAgICAgICAgICAweGYwMDAwMDA6IDB4NDAwODAwMDAsCiAgICAgICAgICAgIDB4ODAwMDAwOiAweDQwMDA0MDAwLAogICAgICAgICAgICAweDE4MDAwMDA6IDB4ODQwMTAsCiAgICAgICAgICAgIDB4MjgwMDAwMDogMHgxMCwKICAgICAgICAgICAgMHgzODAwMDAwOiAweDQwMDA0MDEwLAogICAgICAgICAgICAweDQ4MDAwMDA6IDB4NDAwODQwMTAsCiAgICAgICAgICAgIDB4NTgwMDAwMDogMHg0MDAwMDAwMCwKICAgICAgICAgICAgMHg2ODAwMDAwOiAweDgwMDAwLAogICAgICAgICAgICAweDc4MDAwMDA6IDB4NDAwODAwMTAsCiAgICAgICAgICAgIDB4ODgwMDAwMDogMHg4MDAxMCwKICAgICAgICAgICAgMHg5ODAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4YTgwMDAwMDogMHg0MDAwLAogICAgICAgICAgICAweGI4MDAwMDA6IDB4NDAwODAwMDAsCiAgICAgICAgICAgIDB4YzgwMDAwMDogMHg0MDAwMDAxMCwKICAgICAgICAgICAgMHhkODAwMDAwOiAweDg0MDAwLAogICAgICAgICAgICAweGU4MDAwMDA6IDB4NDAwODQwMDAsCiAgICAgICAgICAgIDB4ZjgwMDAwMDogMHg0MDEwLAogICAgICAgICAgICAweDEwMDAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4MTEwMDAwMDA6IDB4NDAwODAwMTAsCiAgICAgICAgICAgIDB4MTIwMDAwMDA6IDB4NDAwMDQwMTAsCiAgICAgICAgICAgIDB4MTMwMDAwMDA6IDB4NDAwODQwMDAsCiAgICAgICAgICAgIDB4MTQwMDAwMDA6IDB4NDAwODAwMDAsCiAgICAgICAgICAgIDB4MTUwMDAwMDA6IDB4MTAsCiAgICAgICAgICAgIDB4MTYwMDAwMDA6IDB4ODQwMTAsCiAgICAgICAgICAgIDB4MTcwMDAwMDA6IDB4NDAwMCwKICAgICAgICAgICAgMHgxODAwMDAwMDogMHg0MDEwLAogICAgICAgICAgICAweDE5MDAwMDAwOiAweDgwMDAwLAogICAgICAgICAgICAweDFhMDAwMDAwOiAweDgwMDEwLAogICAgICAgICAgICAweDFiMDAwMDAwOiAweDQwMDAwMDEwLAogICAgICAgICAgICAweDFjMDAwMDAwOiAweDg0MDAwLAogICAgICAgICAgICAweDFkMDAwMDAwOiAweDQwMDA0MDAwLAogICAgICAgICAgICAweDFlMDAwMDAwOiAweDQwMDAwMDAwLAogICAgICAgICAgICAweDFmMDAwMDAwOiAweDQwMDg0MDEwLAogICAgICAgICAgICAweDEwODAwMDAwOiAweDg0MDEwLAogICAgICAgICAgICAweDExODAwMDAwOiAweDgwMDAwLAogICAgICAgICAgICAweDEyODAwMDAwOiAweDQwMDgwMDAwLAogICAgICAgICAgICAweDEzODAwMDAwOiAweDQwMDAsCiAgICAgICAgICAgIDB4MTQ4MDAwMDA6IDB4NDAwMDQwMDAsCiAgICAgICAgICAgIDB4MTU4MDAwMDA6IDB4NDAwODQwMTAsCiAgICAgICAgICAgIDB4MTY4MDAwMDA6IDB4MTAsCiAgICAgICAgICAgIDB4MTc4MDAwMDA6IDB4NDAwMDAwMDAsCiAgICAgICAgICAgIDB4MTg4MDAwMDA6IDB4NDAwODQwMDAsCiAgICAgICAgICAgIDB4MTk4MDAwMDA6IDB4NDAwMDAwMTAsCiAgICAgICAgICAgIDB4MWE4MDAwMDA6IDB4NDAwMDQwMTAsCiAgICAgICAgICAgIDB4MWI4MDAwMDA6IDB4ODAwMTAsCiAgICAgICAgICAgIDB4MWM4MDAwMDA6IDB4MCwKICAgICAgICAgICAgMHgxZDgwMDAwMDogMHg0MDEwLAogICAgICAgICAgICAweDFlODAwMDAwOiAweDQwMDgwMDEwLAogICAgICAgICAgICAweDFmODAwMDAwOiAweDg0MDAwCiAgICAgICAgICB9LCB7CiAgICAgICAgICAgIDB4MDogMHgxMDQsCiAgICAgICAgICAgIDB4MTAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4MjAwMDAwOiAweDQwMDAxMDAsCiAgICAgICAgICAgIDB4MzAwMDAwOiAweDEwMTA0LAogICAgICAgICAgICAweDQwMDAwMDogMHgxMDAwNCwKICAgICAgICAgICAgMHg1MDAwMDA6IDB4NDAwMDAwNCwKICAgICAgICAgICAgMHg2MDAwMDA6IDB4NDAxMDEwNCwKICAgICAgICAgICAgMHg3MDAwMDA6IDB4NDAxMDAwMCwKICAgICAgICAgICAgMHg4MDAwMDA6IDB4NDAwMDAwMCwKICAgICAgICAgICAgMHg5MDAwMDA6IDB4NDAxMDEwMCwKICAgICAgICAgICAgMHhhMDAwMDA6IDB4MTAxMDAsCiAgICAgICAgICAgIDB4YjAwMDAwOiAweDQwMTAwMDQsCiAgICAgICAgICAgIDB4YzAwMDAwOiAweDQwMDAxMDQsCiAgICAgICAgICAgIDB4ZDAwMDAwOiAweDEwMDAwLAogICAgICAgICAgICAweGUwMDAwMDogMHg0LAogICAgICAgICAgICAweGYwMDAwMDogMHgxMDAsCiAgICAgICAgICAgIDB4ODAwMDA6IDB4NDAxMDEwMCwKICAgICAgICAgICAgMHgxODAwMDA6IDB4NDAxMDAwNCwKICAgICAgICAgICAgMHgyODAwMDA6IDB4MCwKICAgICAgICAgICAgMHgzODAwMDA6IDB4NDAwMDEwMCwKICAgICAgICAgICAgMHg0ODAwMDA6IDB4NDAwMDAwNCwKICAgICAgICAgICAgMHg1ODAwMDA6IDB4MTAwMDAsCiAgICAgICAgICAgIDB4NjgwMDAwOiAweDEwMDA0LAogICAgICAgICAgICAweDc4MDAwMDogMHgxMDQsCiAgICAgICAgICAgIDB4ODgwMDAwOiAweDQsCiAgICAgICAgICAgIDB4OTgwMDAwOiAweDEwMCwKICAgICAgICAgICAgMHhhODAwMDA6IDB4NDAxMDAwMCwKICAgICAgICAgICAgMHhiODAwMDA6IDB4MTAxMDQsCiAgICAgICAgICAgIDB4YzgwMDAwOiAweDEwMTAwLAogICAgICAgICAgICAweGQ4MDAwMDogMHg0MDAwMTA0LAogICAgICAgICAgICAweGU4MDAwMDogMHg0MDEwMTA0LAogICAgICAgICAgICAweGY4MDAwMDogMHg0MDAwMDAwLAogICAgICAgICAgICAweDEwMDAwMDA6IDB4NDAxMDEwMCwKICAgICAgICAgICAgMHgxMTAwMDAwOiAweDEwMDA0LAogICAgICAgICAgICAweDEyMDAwMDA6IDB4MTAwMDAsCiAgICAgICAgICAgIDB4MTMwMDAwMDogMHg0MDAwMTAwLAogICAgICAgICAgICAweDE0MDAwMDA6IDB4MTAwLAogICAgICAgICAgICAweDE1MDAwMDA6IDB4NDAxMDEwNCwKICAgICAgICAgICAgMHgxNjAwMDAwOiAweDQwMDAwMDQsCiAgICAgICAgICAgIDB4MTcwMDAwMDogMHgwLAogICAgICAgICAgICAweDE4MDAwMDA6IDB4NDAwMDEwNCwKICAgICAgICAgICAgMHgxOTAwMDAwOiAweDQwMDAwMDAsCiAgICAgICAgICAgIDB4MWEwMDAwMDogMHg0LAogICAgICAgICAgICAweDFiMDAwMDA6IDB4MTAxMDAsCiAgICAgICAgICAgIDB4MWMwMDAwMDogMHg0MDEwMDAwLAogICAgICAgICAgICAweDFkMDAwMDA6IDB4MTA0LAogICAgICAgICAgICAweDFlMDAwMDA6IDB4MTAxMDQsCiAgICAgICAgICAgIDB4MWYwMDAwMDogMHg0MDEwMDA0LAogICAgICAgICAgICAweDEwODAwMDA6IDB4NDAwMDAwMCwKICAgICAgICAgICAgMHgxMTgwMDAwOiAweDEwNCwKICAgICAgICAgICAgMHgxMjgwMDAwOiAweDQwMTAxMDAsCiAgICAgICAgICAgIDB4MTM4MDAwMDogMHgwLAogICAgICAgICAgICAweDE0ODAwMDA6IDB4MTAwMDQsCiAgICAgICAgICAgIDB4MTU4MDAwMDogMHg0MDAwMTAwLAogICAgICAgICAgICAweDE2ODAwMDA6IDB4MTAwLAogICAgICAgICAgICAweDE3ODAwMDA6IDB4NDAxMDAwNCwKICAgICAgICAgICAgMHgxODgwMDAwOiAweDEwMDAwLAogICAgICAgICAgICAweDE5ODAwMDA6IDB4NDAxMDEwNCwKICAgICAgICAgICAgMHgxYTgwMDAwOiAweDEwMTA0LAogICAgICAgICAgICAweDFiODAwMDA6IDB4NDAwMDAwNCwKICAgICAgICAgICAgMHgxYzgwMDAwOiAweDQwMDAxMDQsCiAgICAgICAgICAgIDB4MWQ4MDAwMDogMHg0MDEwMDAwLAogICAgICAgICAgICAweDFlODAwMDA6IDB4NCwKICAgICAgICAgICAgMHgxZjgwMDAwOiAweDEwMTAwCiAgICAgICAgICB9LCB7CiAgICAgICAgICAgIDB4MDogMHg4MDQwMTAwMCwKICAgICAgICAgICAgMHgxMDAwMDogMHg4MDAwMTA0MCwKICAgICAgICAgICAgMHgyMDAwMDogMHg0MDEwNDAsCiAgICAgICAgICAgIDB4MzAwMDA6IDB4ODA0MDAwMDAsCiAgICAgICAgICAgIDB4NDAwMDA6IDB4MCwKICAgICAgICAgICAgMHg1MDAwMDogMHg0MDEwMDAsCiAgICAgICAgICAgIDB4NjAwMDA6IDB4ODAwMDAwNDAsCiAgICAgICAgICAgIDB4NzAwMDA6IDB4NDAwMDQwLAogICAgICAgICAgICAweDgwMDAwOiAweDgwMDAwMDAwLAogICAgICAgICAgICAweDkwMDAwOiAweDQwMDAwMCwKICAgICAgICAgICAgMHhhMDAwMDogMHg0MCwKICAgICAgICAgICAgMHhiMDAwMDogMHg4MDAwMTAwMCwKICAgICAgICAgICAgMHhjMDAwMDogMHg4MDQwMDA0MCwKICAgICAgICAgICAgMHhkMDAwMDogMHgxMDQwLAogICAgICAgICAgICAweGUwMDAwOiAweDEwMDAsCiAgICAgICAgICAgIDB4ZjAwMDA6IDB4ODA0MDEwNDAsCiAgICAgICAgICAgIDB4ODAwMDogMHg4MDAwMTA0MCwKICAgICAgICAgICAgMHgxODAwMDogMHg0MCwKICAgICAgICAgICAgMHgyODAwMDogMHg4MDQwMDA0MCwKICAgICAgICAgICAgMHgzODAwMDogMHg4MDAwMTAwMCwKICAgICAgICAgICAgMHg0ODAwMDogMHg0MDEwMDAsCiAgICAgICAgICAgIDB4NTgwMDA6IDB4ODA0MDEwNDAsCiAgICAgICAgICAgIDB4NjgwMDA6IDB4MCwKICAgICAgICAgICAgMHg3ODAwMDogMHg4MDQwMDAwMCwKICAgICAgICAgICAgMHg4ODAwMDogMHgxMDAwLAogICAgICAgICAgICAweDk4MDAwOiAweDgwNDAxMDAwLAogICAgICAgICAgICAweGE4MDAwOiAweDQwMDAwMCwKICAgICAgICAgICAgMHhiODAwMDogMHgxMDQwLAogICAgICAgICAgICAweGM4MDAwOiAweDgwMDAwMDAwLAogICAgICAgICAgICAweGQ4MDAwOiAweDQwMDA0MCwKICAgICAgICAgICAgMHhlODAwMDogMHg0MDEwNDAsCiAgICAgICAgICAgIDB4ZjgwMDA6IDB4ODAwMDAwNDAsCiAgICAgICAgICAgIDB4MTAwMDAwOiAweDQwMDA0MCwKICAgICAgICAgICAgMHgxMTAwMDA6IDB4NDAxMDAwLAogICAgICAgICAgICAweDEyMDAwMDogMHg4MDAwMDA0MCwKICAgICAgICAgICAgMHgxMzAwMDA6IDB4MCwKICAgICAgICAgICAgMHgxNDAwMDA6IDB4MTA0MCwKICAgICAgICAgICAgMHgxNTAwMDA6IDB4ODA0MDAwNDAsCiAgICAgICAgICAgIDB4MTYwMDAwOiAweDgwNDAxMDAwLAogICAgICAgICAgICAweDE3MDAwMDogMHg4MDAwMTA0MCwKICAgICAgICAgICAgMHgxODAwMDA6IDB4ODA0MDEwNDAsCiAgICAgICAgICAgIDB4MTkwMDAwOiAweDgwMDAwMDAwLAogICAgICAgICAgICAweDFhMDAwMDogMHg4MDQwMDAwMCwKICAgICAgICAgICAgMHgxYjAwMDA6IDB4NDAxMDQwLAogICAgICAgICAgICAweDFjMDAwMDogMHg4MDAwMTAwMCwKICAgICAgICAgICAgMHgxZDAwMDA6IDB4NDAwMDAwLAogICAgICAgICAgICAweDFlMDAwMDogMHg0MCwKICAgICAgICAgICAgMHgxZjAwMDA6IDB4MTAwMCwKICAgICAgICAgICAgMHgxMDgwMDA6IDB4ODA0MDAwMDAsCiAgICAgICAgICAgIDB4MTE4MDAwOiAweDgwNDAxMDQwLAogICAgICAgICAgICAweDEyODAwMDogMHgwLAogICAgICAgICAgICAweDEzODAwMDogMHg0MDEwMDAsCiAgICAgICAgICAgIDB4MTQ4MDAwOiAweDQwMDA0MCwKICAgICAgICAgICAgMHgxNTgwMDA6IDB4ODAwMDAwMDAsCiAgICAgICAgICAgIDB4MTY4MDAwOiAweDgwMDAxMDQwLAogICAgICAgICAgICAweDE3ODAwMDogMHg0MCwKICAgICAgICAgICAgMHgxODgwMDA6IDB4ODAwMDAwNDAsCiAgICAgICAgICAgIDB4MTk4MDAwOiAweDEwMDAsCiAgICAgICAgICAgIDB4MWE4MDAwOiAweDgwMDAxMDAwLAogICAgICAgICAgICAweDFiODAwMDogMHg4MDQwMDA0MCwKICAgICAgICAgICAgMHgxYzgwMDA6IDB4MTA0MCwKICAgICAgICAgICAgMHgxZDgwMDA6IDB4ODA0MDEwMDAsCiAgICAgICAgICAgIDB4MWU4MDAwOiAweDQwMDAwMCwKICAgICAgICAgICAgMHgxZjgwMDA6IDB4NDAxMDQwCiAgICAgICAgICB9LCB7CiAgICAgICAgICAgIDB4MDogMHg4MCwKICAgICAgICAgICAgMHgxMDAwOiAweDEwNDAwMDAsCiAgICAgICAgICAgIDB4MjAwMDogMHg0MDAwMCwKICAgICAgICAgICAgMHgzMDAwOiAweDIwMDAwMDAwLAogICAgICAgICAgICAweDQwMDA6IDB4MjAwNDAwODAsCiAgICAgICAgICAgIDB4NTAwMDogMHgxMDAwMDgwLAogICAgICAgICAgICAweDYwMDA6IDB4MjEwMDAwODAsCiAgICAgICAgICAgIDB4NzAwMDogMHg0MDA4MCwKICAgICAgICAgICAgMHg4MDAwOiAweDEwMDAwMDAsCiAgICAgICAgICAgIDB4OTAwMDogMHgyMDA0MDAwMCwKICAgICAgICAgICAgMHhhMDAwOiAweDIwMDAwMDgwLAogICAgICAgICAgICAweGIwMDA6IDB4MjEwNDAwODAsCiAgICAgICAgICAgIDB4YzAwMDogMHgyMTA0MDAwMCwKICAgICAgICAgICAgMHhkMDAwOiAweDAsCiAgICAgICAgICAgIDB4ZTAwMDogMHgxMDQwMDgwLAogICAgICAgICAgICAweGYwMDA6IDB4MjEwMDAwMDAsCiAgICAgICAgICAgIDB4ODAwOiAweDEwNDAwODAsCiAgICAgICAgICAgIDB4MTgwMDogMHgyMTAwMDA4MCwKICAgICAgICAgICAgMHgyODAwOiAweDgwLAogICAgICAgICAgICAweDM4MDA6IDB4MTA0MDAwMCwKICAgICAgICAgICAgMHg0ODAwOiAweDQwMDAwLAogICAgICAgICAgICAweDU4MDA6IDB4MjAwNDAwODAsCiAgICAgICAgICAgIDB4NjgwMDogMHgyMTA0MDAwMCwKICAgICAgICAgICAgMHg3ODAwOiAweDIwMDAwMDAwLAogICAgICAgICAgICAweDg4MDA6IDB4MjAwNDAwMDAsCiAgICAgICAgICAgIDB4OTgwMDogMHgwLAogICAgICAgICAgICAweGE4MDA6IDB4MjEwNDAwODAsCiAgICAgICAgICAgIDB4YjgwMDogMHgxMDAwMDgwLAogICAgICAgICAgICAweGM4MDA6IDB4MjAwMDAwODAsCiAgICAgICAgICAgIDB4ZDgwMDogMHgyMTAwMDAwMCwKICAgICAgICAgICAgMHhlODAwOiAweDEwMDAwMDAsCiAgICAgICAgICAgIDB4ZjgwMDogMHg0MDA4MCwKICAgICAgICAgICAgMHgxMDAwMDogMHg0MDAwMCwKICAgICAgICAgICAgMHgxMTAwMDogMHg4MCwKICAgICAgICAgICAgMHgxMjAwMDogMHgyMDAwMDAwMCwKICAgICAgICAgICAgMHgxMzAwMDogMHgyMTAwMDA4MCwKICAgICAgICAgICAgMHgxNDAwMDogMHgxMDAwMDgwLAogICAgICAgICAgICAweDE1MDAwOiAweDIxMDQwMDAwLAogICAgICAgICAgICAweDE2MDAwOiAweDIwMDQwMDgwLAogICAgICAgICAgICAweDE3MDAwOiAweDEwMDAwMDAsCiAgICAgICAgICAgIDB4MTgwMDA6IDB4MjEwNDAwODAsCiAgICAgICAgICAgIDB4MTkwMDA6IDB4MjEwMDAwMDAsCiAgICAgICAgICAgIDB4MWEwMDA6IDB4MTA0MDAwMCwKICAgICAgICAgICAgMHgxYjAwMDogMHgyMDA0MDAwMCwKICAgICAgICAgICAgMHgxYzAwMDogMHg0MDA4MCwKICAgICAgICAgICAgMHgxZDAwMDogMHgyMDAwMDA4MCwKICAgICAgICAgICAgMHgxZTAwMDogMHgwLAogICAgICAgICAgICAweDFmMDAwOiAweDEwNDAwODAsCiAgICAgICAgICAgIDB4MTA4MDA6IDB4MjEwMDAwODAsCiAgICAgICAgICAgIDB4MTE4MDA6IDB4MTAwMDAwMCwKICAgICAgICAgICAgMHgxMjgwMDogMHgxMDQwMDAwLAogICAgICAgICAgICAweDEzODAwOiAweDIwMDQwMDgwLAogICAgICAgICAgICAweDE0ODAwOiAweDIwMDAwMDAwLAogICAgICAgICAgICAweDE1ODAwOiAweDEwNDAwODAsCiAgICAgICAgICAgIDB4MTY4MDA6IDB4ODAsCiAgICAgICAgICAgIDB4MTc4MDA6IDB4MjEwNDAwMDAsCiAgICAgICAgICAgIDB4MTg4MDA6IDB4NDAwODAsCiAgICAgICAgICAgIDB4MTk4MDA6IDB4MjEwNDAwODAsCiAgICAgICAgICAgIDB4MWE4MDA6IDB4MCwKICAgICAgICAgICAgMHgxYjgwMDogMHgyMTAwMDAwMCwKICAgICAgICAgICAgMHgxYzgwMDogMHgxMDAwMDgwLAogICAgICAgICAgICAweDFkODAwOiAweDQwMDAwLAogICAgICAgICAgICAweDFlODAwOiAweDIwMDQwMDAwLAogICAgICAgICAgICAweDFmODAwOiAweDIwMDAwMDgwCiAgICAgICAgICB9LCB7CiAgICAgICAgICAgIDB4MDogMHgxMDAwMDAwOCwKICAgICAgICAgICAgMHgxMDA6IDB4MjAwMCwKICAgICAgICAgICAgMHgyMDA6IDB4MTAyMDAwMDAsCiAgICAgICAgICAgIDB4MzAwOiAweDEwMjAyMDA4LAogICAgICAgICAgICAweDQwMDogMHgxMDAwMjAwMCwKICAgICAgICAgICAgMHg1MDA6IDB4MjAwMDAwLAogICAgICAgICAgICAweDYwMDogMHgyMDAwMDgsCiAgICAgICAgICAgIDB4NzAwOiAweDEwMDAwMDAwLAogICAgICAgICAgICAweDgwMDogMHgwLAogICAgICAgICAgICAweDkwMDogMHgxMDAwMjAwOCwKICAgICAgICAgICAgMHhhMDA6IDB4MjAyMDAwLAogICAgICAgICAgICAweGIwMDogMHg4LAogICAgICAgICAgICAweGMwMDogMHgxMDIwMDAwOCwKICAgICAgICAgICAgMHhkMDA6IDB4MjAyMDA4LAogICAgICAgICAgICAweGUwMDogMHgyMDA4LAogICAgICAgICAgICAweGYwMDogMHgxMDIwMjAwMCwKICAgICAgICAgICAgMHg4MDogMHgxMDIwMDAwMCwKICAgICAgICAgICAgMHgxODA6IDB4MTAyMDIwMDgsCiAgICAgICAgICAgIDB4MjgwOiAweDgsCiAgICAgICAgICAgIDB4MzgwOiAweDIwMDAwMCwKICAgICAgICAgICAgMHg0ODA6IDB4MjAyMDA4LAogICAgICAgICAgICAweDU4MDogMHgxMDAwMDAwOCwKICAgICAgICAgICAgMHg2ODA6IDB4MTAwMDIwMDAsCiAgICAgICAgICAgIDB4NzgwOiAweDIwMDgsCiAgICAgICAgICAgIDB4ODgwOiAweDIwMDAwOCwKICAgICAgICAgICAgMHg5ODA6IDB4MjAwMCwKICAgICAgICAgICAgMHhhODA6IDB4MTAwMDIwMDgsCiAgICAgICAgICAgIDB4YjgwOiAweDEwMjAwMDA4LAogICAgICAgICAgICAweGM4MDogMHgwLAogICAgICAgICAgICAweGQ4MDogMHgxMDIwMjAwMCwKICAgICAgICAgICAgMHhlODA6IDB4MjAyMDAwLAogICAgICAgICAgICAweGY4MDogMHgxMDAwMDAwMCwKICAgICAgICAgICAgMHgxMDAwOiAweDEwMDAyMDAwLAogICAgICAgICAgICAweDExMDA6IDB4MTAyMDAwMDgsCiAgICAgICAgICAgIDB4MTIwMDogMHgxMDIwMjAwOCwKICAgICAgICAgICAgMHgxMzAwOiAweDIwMDgsCiAgICAgICAgICAgIDB4MTQwMDogMHgyMDAwMDAsCiAgICAgICAgICAgIDB4MTUwMDogMHgxMDAwMDAwMCwKICAgICAgICAgICAgMHgxNjAwOiAweDEwMDAwMDA4LAogICAgICAgICAgICAweDE3MDA6IDB4MjAyMDAwLAogICAgICAgICAgICAweDE4MDA6IDB4MjAyMDA4LAogICAgICAgICAgICAweDE5MDA6IDB4MCwKICAgICAgICAgICAgMHgxYTAwOiAweDgsCiAgICAgICAgICAgIDB4MWIwMDogMHgxMDIwMDAwMCwKICAgICAgICAgICAgMHgxYzAwOiAweDIwMDAsCiAgICAgICAgICAgIDB4MWQwMDogMHgxMDAwMjAwOCwKICAgICAgICAgICAgMHgxZTAwOiAweDEwMjAyMDAwLAogICAgICAgICAgICAweDFmMDA6IDB4MjAwMDA4LAogICAgICAgICAgICAweDEwODA6IDB4OCwKICAgICAgICAgICAgMHgxMTgwOiAweDIwMjAwMCwKICAgICAgICAgICAgMHgxMjgwOiAweDIwMDAwMCwKICAgICAgICAgICAgMHgxMzgwOiAweDEwMDAwMDA4LAogICAgICAgICAgICAweDE0ODA6IDB4MTAwMDIwMDAsCiAgICAgICAgICAgIDB4MTU4MDogMHgyMDA4LAogICAgICAgICAgICAweDE2ODA6IDB4MTAyMDIwMDgsCiAgICAgICAgICAgIDB4MTc4MDogMHgxMDIwMDAwMCwKICAgICAgICAgICAgMHgxODgwOiAweDEwMjAyMDAwLAogICAgICAgICAgICAweDE5ODA6IDB4MTAyMDAwMDgsCiAgICAgICAgICAgIDB4MWE4MDogMHgyMDAwLAogICAgICAgICAgICAweDFiODA6IDB4MjAyMDA4LAogICAgICAgICAgICAweDFjODA6IDB4MjAwMDA4LAogICAgICAgICAgICAweDFkODA6IDB4MCwKICAgICAgICAgICAgMHgxZTgwOiAweDEwMDAwMDAwLAogICAgICAgICAgICAweDFmODA6IDB4MTAwMDIwMDgKICAgICAgICAgIH0sIHsKICAgICAgICAgICAgMHgwOiAweDEwMDAwMCwKICAgICAgICAgICAgMHgxMDogMHgyMDAwNDAxLAogICAgICAgICAgICAweDIwOiAweDQwMCwKICAgICAgICAgICAgMHgzMDogMHgxMDA0MDEsCiAgICAgICAgICAgIDB4NDA6IDB4MjEwMDQwMSwKICAgICAgICAgICAgMHg1MDogMHgwLAogICAgICAgICAgICAweDYwOiAweDEsCiAgICAgICAgICAgIDB4NzA6IDB4MjEwMDAwMSwKICAgICAgICAgICAgMHg4MDogMHgyMDAwNDAwLAogICAgICAgICAgICAweDkwOiAweDEwMDAwMSwKICAgICAgICAgICAgMHhhMDogMHgyMDAwMDAxLAogICAgICAgICAgICAweGIwOiAweDIxMDA0MDAsCiAgICAgICAgICAgIDB4YzA6IDB4MjEwMDAwMCwKICAgICAgICAgICAgMHhkMDogMHg0MDEsCiAgICAgICAgICAgIDB4ZTA6IDB4MTAwNDAwLAogICAgICAgICAgICAweGYwOiAweDIwMDAwMDAsCiAgICAgICAgICAgIDB4ODogMHgyMTAwMDAxLAogICAgICAgICAgICAweDE4OiAweDAsCiAgICAgICAgICAgIDB4Mjg6IDB4MjAwMDQwMSwKICAgICAgICAgICAgMHgzODogMHgyMTAwNDAwLAogICAgICAgICAgICAweDQ4OiAweDEwMDAwMCwKICAgICAgICAgICAgMHg1ODogMHgyMDAwMDAxLAogICAgICAgICAgICAweDY4OiAweDIwMDAwMDAsCiAgICAgICAgICAgIDB4Nzg6IDB4NDAxLAogICAgICAgICAgICAweDg4OiAweDEwMDQwMSwKICAgICAgICAgICAgMHg5ODogMHgyMDAwNDAwLAogICAgICAgICAgICAweGE4OiAweDIxMDAwMDAsCiAgICAgICAgICAgIDB4Yjg6IDB4MTAwMDAxLAogICAgICAgICAgICAweGM4OiAweDQwMCwKICAgICAgICAgICAgMHhkODogMHgyMTAwNDAxLAogICAgICAgICAgICAweGU4OiAweDEsCiAgICAgICAgICAgIDB4Zjg6IDB4MTAwNDAwLAogICAgICAgICAgICAweDEwMDogMHgyMDAwMDAwLAogICAgICAgICAgICAweDExMDogMHgxMDAwMDAsCiAgICAgICAgICAgIDB4MTIwOiAweDIwMDA0MDEsCiAgICAgICAgICAgIDB4MTMwOiAweDIxMDAwMDEsCiAgICAgICAgICAgIDB4MTQwOiAweDEwMDAwMSwKICAgICAgICAgICAgMHgxNTA6IDB4MjAwMDQwMCwKICAgICAgICAgICAgMHgxNjA6IDB4MjEwMDQwMCwKICAgICAgICAgICAgMHgxNzA6IDB4MTAwNDAxLAogICAgICAgICAgICAweDE4MDogMHg0MDEsCiAgICAgICAgICAgIDB4MTkwOiAweDIxMDA0MDEsCiAgICAgICAgICAgIDB4MWEwOiAweDEwMDQwMCwKICAgICAgICAgICAgMHgxYjA6IDB4MSwKICAgICAgICAgICAgMHgxYzA6IDB4MCwKICAgICAgICAgICAgMHgxZDA6IDB4MjEwMDAwMCwKICAgICAgICAgICAgMHgxZTA6IDB4MjAwMDAwMSwKICAgICAgICAgICAgMHgxZjA6IDB4NDAwLAogICAgICAgICAgICAweDEwODogMHgxMDA0MDAsCiAgICAgICAgICAgIDB4MTE4OiAweDIwMDA0MDEsCiAgICAgICAgICAgIDB4MTI4OiAweDIxMDAwMDEsCiAgICAgICAgICAgIDB4MTM4OiAweDEsCiAgICAgICAgICAgIDB4MTQ4OiAweDIwMDAwMDAsCiAgICAgICAgICAgIDB4MTU4OiAweDEwMDAwMCwKICAgICAgICAgICAgMHgxNjg6IDB4NDAxLAogICAgICAgICAgICAweDE3ODogMHgyMTAwNDAwLAogICAgICAgICAgICAweDE4ODogMHgyMDAwMDAxLAogICAgICAgICAgICAweDE5ODogMHgyMTAwMDAwLAogICAgICAgICAgICAweDFhODogMHgwLAogICAgICAgICAgICAweDFiODogMHgyMTAwNDAxLAogICAgICAgICAgICAweDFjODogMHgxMDA0MDEsCiAgICAgICAgICAgIDB4MWQ4OiAweDQwMCwKICAgICAgICAgICAgMHgxZTg6IDB4MjAwMDQwMCwKICAgICAgICAgICAgMHgxZjg6IDB4MTAwMDAxCiAgICAgICAgICB9LCB7CiAgICAgICAgICAgIDB4MDogMHg4MDAwODIwLAogICAgICAgICAgICAweDE6IDB4MjAwMDAsCiAgICAgICAgICAgIDB4MjogMHg4MDAwMDAwLAogICAgICAgICAgICAweDM6IDB4MjAsCiAgICAgICAgICAgIDB4NDogMHgyMDAyMCwKICAgICAgICAgICAgMHg1OiAweDgwMjA4MjAsCiAgICAgICAgICAgIDB4NjogMHg4MDIwODAwLAogICAgICAgICAgICAweDc6IDB4ODAwLAogICAgICAgICAgICAweDg6IDB4ODAyMDAwMCwKICAgICAgICAgICAgMHg5OiAweDgwMDA4MDAsCiAgICAgICAgICAgIDB4YTogMHgyMDgwMCwKICAgICAgICAgICAgMHhiOiAweDgwMjAwMjAsCiAgICAgICAgICAgIDB4YzogMHg4MjAsCiAgICAgICAgICAgIDB4ZDogMHgwLAogICAgICAgICAgICAweGU6IDB4ODAwMDAyMCwKICAgICAgICAgICAgMHhmOiAweDIwODIwLAogICAgICAgICAgICAweDgwMDAwMDAwOiAweDgwMCwKICAgICAgICAgICAgMHg4MDAwMDAwMTogMHg4MDIwODIwLAogICAgICAgICAgICAweDgwMDAwMDAyOiAweDgwMDA4MjAsCiAgICAgICAgICAgIDB4ODAwMDAwMDM6IDB4ODAwMDAwMCwKICAgICAgICAgICAgMHg4MDAwMDAwNDogMHg4MDIwMDAwLAogICAgICAgICAgICAweDgwMDAwMDA1OiAweDIwODAwLAogICAgICAgICAgICAweDgwMDAwMDA2OiAweDIwODIwLAogICAgICAgICAgICAweDgwMDAwMDA3OiAweDIwLAogICAgICAgICAgICAweDgwMDAwMDA4OiAweDgwMDAwMjAsCiAgICAgICAgICAgIDB4ODAwMDAwMDk6IDB4ODIwLAogICAgICAgICAgICAweDgwMDAwMDBhOiAweDIwMDIwLAogICAgICAgICAgICAweDgwMDAwMDBiOiAweDgwMjA4MDAsCiAgICAgICAgICAgIDB4ODAwMDAwMGM6IDB4MCwKICAgICAgICAgICAgMHg4MDAwMDAwZDogMHg4MDIwMDIwLAogICAgICAgICAgICAweDgwMDAwMDBlOiAweDgwMDA4MDAsCiAgICAgICAgICAgIDB4ODAwMDAwMGY6IDB4MjAwMDAsCiAgICAgICAgICAgIDB4MTA6IDB4MjA4MjAsCiAgICAgICAgICAgIDB4MTE6IDB4ODAyMDgwMCwKICAgICAgICAgICAgMHgxMjogMHgyMCwKICAgICAgICAgICAgMHgxMzogMHg4MDAsCiAgICAgICAgICAgIDB4MTQ6IDB4ODAwMDgwMCwKICAgICAgICAgICAgMHgxNTogMHg4MDAwMDIwLAogICAgICAgICAgICAweDE2OiAweDgwMjAwMjAsCiAgICAgICAgICAgIDB4MTc6IDB4MjAwMDAsCiAgICAgICAgICAgIDB4MTg6IDB4MCwKICAgICAgICAgICAgMHgxOTogMHgyMDAyMCwKICAgICAgICAgICAgMHgxYTogMHg4MDIwMDAwLAogICAgICAgICAgICAweDFiOiAweDgwMDA4MjAsCiAgICAgICAgICAgIDB4MWM6IDB4ODAyMDgyMCwKICAgICAgICAgICAgMHgxZDogMHgyMDgwMCwKICAgICAgICAgICAgMHgxZTogMHg4MjAsCiAgICAgICAgICAgIDB4MWY6IDB4ODAwMDAwMCwKICAgICAgICAgICAgMHg4MDAwMDAxMDogMHgyMDAwMCwKICAgICAgICAgICAgMHg4MDAwMDAxMTogMHg4MDAsCiAgICAgICAgICAgIDB4ODAwMDAwMTI6IDB4ODAyMDAyMCwKICAgICAgICAgICAgMHg4MDAwMDAxMzogMHgyMDgyMCwKICAgICAgICAgICAgMHg4MDAwMDAxNDogMHgyMCwKICAgICAgICAgICAgMHg4MDAwMDAxNTogMHg4MDIwMDAwLAogICAgICAgICAgICAweDgwMDAwMDE2OiAweDgwMDAwMDAsCiAgICAgICAgICAgIDB4ODAwMDAwMTc6IDB4ODAwMDgyMCwKICAgICAgICAgICAgMHg4MDAwMDAxODogMHg4MDIwODIwLAogICAgICAgICAgICAweDgwMDAwMDE5OiAweDgwMDAwMjAsCiAgICAgICAgICAgIDB4ODAwMDAwMWE6IDB4ODAwMDgwMCwKICAgICAgICAgICAgMHg4MDAwMDAxYjogMHgwLAogICAgICAgICAgICAweDgwMDAwMDFjOiAweDIwODAwLAogICAgICAgICAgICAweDgwMDAwMDFkOiAweDgyMCwKICAgICAgICAgICAgMHg4MDAwMDAxZTogMHgyMDAyMCwKICAgICAgICAgICAgMHg4MDAwMDAxZjogMHg4MDIwODAwCiAgICAgICAgICB9XTsKCiAgICAgICAgICAvLyBNYXNrcyB0aGF0IHNlbGVjdCB0aGUgU0JPWCBpbnB1dAogICAgICAgICAgdmFyIFNCT1hfTUFTSyA9IFsweGY4MDAwMDAxLCAweDFmODAwMDAwLCAweDAxZjgwMDAwLCAweDAwMWY4MDAwLCAweDAwMDFmODAwLCAweDAwMDAxZjgwLCAweDAwMDAwMWY4LCAweDgwMDAwMDFmXTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIERFUyBibG9jayBjaXBoZXIgYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgREVTID0gQ19hbGdvLkRFUyA9IEJsb2NrQ2lwaGVyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGtleSA9IHRoaXMuX2tleTsKICAgICAgICAgICAgICB2YXIga2V5V29yZHMgPSBrZXkud29yZHM7CgogICAgICAgICAgICAgIC8vIFNlbGVjdCA1NiBiaXRzIGFjY29yZGluZyB0byBQQzEKICAgICAgICAgICAgICB2YXIga2V5Qml0cyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNTY7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGtleUJpdFBvcyA9IFBDMVtpXSAtIDE7CiAgICAgICAgICAgICAgICBrZXlCaXRzW2ldID0ga2V5V29yZHNba2V5Qml0UG9zID4+PiA1XSA+Pj4gMzEgLSBrZXlCaXRQb3MgJSAzMiAmIDE7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBBc3NlbWJsZSAxNiBzdWJrZXlzCiAgICAgICAgICAgICAgdmFyIHN1YktleXMgPSB0aGlzLl9zdWJLZXlzID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgblN1YktleSA9IDA7IG5TdWJLZXkgPCAxNjsgblN1YktleSsrKSB7CiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgc3Via2V5CiAgICAgICAgICAgICAgICB2YXIgc3ViS2V5ID0gc3ViS2V5c1tuU3ViS2V5XSA9IFtdOwoKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgICB2YXIgYml0U2hpZnQgPSBCSVRfU0hJRlRTW25TdWJLZXldOwoKICAgICAgICAgICAgICAgIC8vIFNlbGVjdCA0OCBiaXRzIGFjY29yZGluZyB0byBQQzIKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjQ7IGkrKykgewogICAgICAgICAgICAgICAgICAvLyBTZWxlY3QgZnJvbSB0aGUgbGVmdCAyOCBrZXkgYml0cwogICAgICAgICAgICAgICAgICBzdWJLZXlbaSAvIDYgfCAwXSB8PSBrZXlCaXRzWyhQQzJbaV0gLSAxICsgYml0U2hpZnQpICUgMjhdIDw8IDMxIC0gaSAlIDY7CgogICAgICAgICAgICAgICAgICAvLyBTZWxlY3QgZnJvbSB0aGUgcmlnaHQgMjgga2V5IGJpdHMKICAgICAgICAgICAgICAgICAgc3ViS2V5WzQgKyAoaSAvIDYgfCAwKV0gfD0ga2V5Qml0c1syOCArIChQQzJbaSArIDI0XSAtIDEgKyBiaXRTaGlmdCkgJSAyOF0gPDwgMzEgLSBpICUgNjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTaW5jZSBlYWNoIHN1YmtleSBpcyBhcHBsaWVkIHRvIGFuIGV4cGFuZGVkIDMyLWJpdCBpbnB1dCwKICAgICAgICAgICAgICAgIC8vIHRoZSBzdWJrZXkgY2FuIGJlIGJyb2tlbiBpbnRvIDggdmFsdWVzIHNjYWxlZCB0byAzMi1iaXRzLAogICAgICAgICAgICAgICAgLy8gd2hpY2ggYWxsb3dzIHRoZSBrZXkgdG8gYmUgdXNlZCB3aXRob3V0IGV4cGFuc2lvbgogICAgICAgICAgICAgICAgc3ViS2V5WzBdID0gc3ViS2V5WzBdIDw8IDEgfCBzdWJLZXlbMF0gPj4+IDMxOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCA3OyBpKyspIHsKICAgICAgICAgICAgICAgICAgc3ViS2V5W2ldID0gc3ViS2V5W2ldID4+PiAoaSAtIDEpICogNCArIDM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdWJLZXlbN10gPSBzdWJLZXlbN10gPDwgNSB8IHN1YktleVs3XSA+Pj4gMjc7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBDb21wdXRlIGludmVyc2Ugc3Via2V5cwogICAgICAgICAgICAgIHZhciBpbnZTdWJLZXlzID0gdGhpcy5faW52U3ViS2V5cyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykgewogICAgICAgICAgICAgICAgaW52U3ViS2V5c1tpXSA9IHN1YktleXNbMTUgLSBpXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGVuY3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkgewogICAgICAgICAgICAgIHRoaXMuX2RvQ3J5cHRCbG9jayhNLCBvZmZzZXQsIHRoaXMuX3N1YktleXMpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBkZWNyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICB0aGlzLl9kb0NyeXB0QmxvY2soTSwgb2Zmc2V0LCB0aGlzLl9pbnZTdWJLZXlzKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvQ3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCwgc3ViS2V5cykgewogICAgICAgICAgICAgIC8vIEdldCBpbnB1dAogICAgICAgICAgICAgIHRoaXMuX2xCbG9jayA9IE1bb2Zmc2V0XTsKICAgICAgICAgICAgICB0aGlzLl9yQmxvY2sgPSBNW29mZnNldCArIDFdOwoKICAgICAgICAgICAgICAvLyBJbml0aWFsIHBlcm11dGF0aW9uCiAgICAgICAgICAgICAgZXhjaGFuZ2VMUi5jYWxsKHRoaXMsIDQsIDB4MGYwZjBmMGYpOwogICAgICAgICAgICAgIGV4Y2hhbmdlTFIuY2FsbCh0aGlzLCAxNiwgMHgwMDAwZmZmZik7CiAgICAgICAgICAgICAgZXhjaGFuZ2VSTC5jYWxsKHRoaXMsIDIsIDB4MzMzMzMzMzMpOwogICAgICAgICAgICAgIGV4Y2hhbmdlUkwuY2FsbCh0aGlzLCA4LCAweDAwZmYwMGZmKTsKICAgICAgICAgICAgICBleGNoYW5nZUxSLmNhbGwodGhpcywgMSwgMHg1NTU1NTU1NSk7CgogICAgICAgICAgICAgIC8vIFJvdW5kcwogICAgICAgICAgICAgIGZvciAodmFyIHJvdW5kID0gMDsgcm91bmQgPCAxNjsgcm91bmQrKykgewogICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgICB2YXIgc3ViS2V5ID0gc3ViS2V5c1tyb3VuZF07CiAgICAgICAgICAgICAgICB2YXIgbEJsb2NrID0gdGhpcy5fbEJsb2NrOwogICAgICAgICAgICAgICAgdmFyIHJCbG9jayA9IHRoaXMuX3JCbG9jazsKCiAgICAgICAgICAgICAgICAvLyBGZWlzdGVsIGZ1bmN0aW9uCiAgICAgICAgICAgICAgICB2YXIgZiA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykgewogICAgICAgICAgICAgICAgICBmIHw9IFNCT1hfUFtpXVsoKHJCbG9jayBeIHN1YktleVtpXSkgJiBTQk9YX01BU0tbaV0pID4+PiAwXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX2xCbG9jayA9IHJCbG9jazsKICAgICAgICAgICAgICAgIHRoaXMuX3JCbG9jayA9IGxCbG9jayBeIGY7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBVbmRvIHN3YXAgZnJvbSBsYXN0IHJvdW5kCiAgICAgICAgICAgICAgdmFyIHQgPSB0aGlzLl9sQmxvY2s7CiAgICAgICAgICAgICAgdGhpcy5fbEJsb2NrID0gdGhpcy5fckJsb2NrOwogICAgICAgICAgICAgIHRoaXMuX3JCbG9jayA9IHQ7CgogICAgICAgICAgICAgIC8vIEZpbmFsIHBlcm11dGF0aW9uCiAgICAgICAgICAgICAgZXhjaGFuZ2VMUi5jYWxsKHRoaXMsIDEsIDB4NTU1NTU1NTUpOwogICAgICAgICAgICAgIGV4Y2hhbmdlUkwuY2FsbCh0aGlzLCA4LCAweDAwZmYwMGZmKTsKICAgICAgICAgICAgICBleGNoYW5nZVJMLmNhbGwodGhpcywgMiwgMHgzMzMzMzMzMyk7CiAgICAgICAgICAgICAgZXhjaGFuZ2VMUi5jYWxsKHRoaXMsIDE2LCAweDAwMDBmZmZmKTsKICAgICAgICAgICAgICBleGNoYW5nZUxSLmNhbGwodGhpcywgNCwgMHgwZjBmMGYwZik7CgogICAgICAgICAgICAgIC8vIFNldCBvdXRwdXQKICAgICAgICAgICAgICBNW29mZnNldF0gPSB0aGlzLl9sQmxvY2s7CiAgICAgICAgICAgICAgTVtvZmZzZXQgKyAxXSA9IHRoaXMuX3JCbG9jazsKICAgICAgICAgICAgfSwKICAgICAgICAgICAga2V5U2l6ZTogNjQgLyAzMiwKICAgICAgICAgICAgaXZTaXplOiA2NCAvIDMyLAogICAgICAgICAgICBibG9ja1NpemU6IDY0IC8gMzIKICAgICAgICAgIH0pOwoKICAgICAgICAgIC8vIFN3YXAgYml0cyBhY3Jvc3MgdGhlIGxlZnQgYW5kIHJpZ2h0IHdvcmRzCiAgICAgICAgICBmdW5jdGlvbiBleGNoYW5nZUxSKG9mZnNldCwgbWFzaykgewogICAgICAgICAgICB2YXIgdCA9ICh0aGlzLl9sQmxvY2sgPj4+IG9mZnNldCBeIHRoaXMuX3JCbG9jaykgJiBtYXNrOwogICAgICAgICAgICB0aGlzLl9yQmxvY2sgXj0gdDsKICAgICAgICAgICAgdGhpcy5fbEJsb2NrIF49IHQgPDwgb2Zmc2V0OwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gZXhjaGFuZ2VSTChvZmZzZXQsIG1hc2spIHsKICAgICAgICAgICAgdmFyIHQgPSAodGhpcy5fckJsb2NrID4+PiBvZmZzZXQgXiB0aGlzLl9sQmxvY2spICYgbWFzazsKICAgICAgICAgICAgdGhpcy5fbEJsb2NrIF49IHQ7CiAgICAgICAgICAgIHRoaXMuX3JCbG9jayBePSB0IDw8IG9mZnNldDsKICAgICAgICAgIH0KCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9ucyB0byB0aGUgY2lwaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dCA9IENyeXB0b0pTLkRFUy5lbmNyeXB0KG1lc3NhZ2UsIGtleSwgY2ZnKTsKICAgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ICA9IENyeXB0b0pTLkRFUy5kZWNyeXB0KGNpcGhlcnRleHQsIGtleSwgY2ZnKTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5ERVMgPSBCbG9ja0NpcGhlci5fY3JlYXRlSGVscGVyKERFUyk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBUcmlwbGUtREVTIGJsb2NrIGNpcGhlciBhbGdvcml0aG0uCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBUcmlwbGVERVMgPSBDX2FsZ28uVHJpcGxlREVTID0gQmxvY2tDaXBoZXIuZXh0ZW5kKHsKICAgICAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIga2V5ID0gdGhpcy5fa2V5OwogICAgICAgICAgICAgIHZhciBrZXlXb3JkcyA9IGtleS53b3JkczsKICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIGtleSBsZW5ndGggaXMgdmFsaWQgKDY0LCAxMjggb3IgPj0gMTkyIGJpdCkKICAgICAgICAgICAgICBpZiAoa2V5V29yZHMubGVuZ3RoICE9PSAyICYmIGtleVdvcmRzLmxlbmd0aCAhPT0gNCAmJiBrZXlXb3Jkcy5sZW5ndGggPCA2KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5IGxlbmd0aCAtIDNERVMgcmVxdWlyZXMgdGhlIGtleSBsZW5ndGggdG8gYmUgNjQsIDEyOCwgMTkyIG9yID4xOTIuJyk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBFeHRlbmQgdGhlIGtleSBhY2NvcmRpbmcgdG8gdGhlIGtleWluZyBvcHRpb25zIGRlZmluZWQgaW4gM0RFUyBzdGFuZGFyZAogICAgICAgICAgICAgIHZhciBrZXkxID0ga2V5V29yZHMuc2xpY2UoMCwgMik7CiAgICAgICAgICAgICAgdmFyIGtleTIgPSBrZXlXb3Jkcy5sZW5ndGggPCA0ID8ga2V5V29yZHMuc2xpY2UoMCwgMikgOiBrZXlXb3Jkcy5zbGljZSgyLCA0KTsKICAgICAgICAgICAgICB2YXIga2V5MyA9IGtleVdvcmRzLmxlbmd0aCA8IDYgPyBrZXlXb3Jkcy5zbGljZSgwLCAyKSA6IGtleVdvcmRzLnNsaWNlKDQsIDYpOwoKICAgICAgICAgICAgICAvLyBDcmVhdGUgREVTIGluc3RhbmNlcwogICAgICAgICAgICAgIHRoaXMuX2RlczEgPSBERVMuY3JlYXRlRW5jcnlwdG9yKFdvcmRBcnJheS5jcmVhdGUoa2V5MSkpOwogICAgICAgICAgICAgIHRoaXMuX2RlczIgPSBERVMuY3JlYXRlRW5jcnlwdG9yKFdvcmRBcnJheS5jcmVhdGUoa2V5MikpOwogICAgICAgICAgICAgIHRoaXMuX2RlczMgPSBERVMuY3JlYXRlRW5jcnlwdG9yKFdvcmRBcnJheS5jcmVhdGUoa2V5MykpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBlbmNyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICB0aGlzLl9kZXMxLmVuY3J5cHRCbG9jayhNLCBvZmZzZXQpOwogICAgICAgICAgICAgIHRoaXMuX2RlczIuZGVjcnlwdEJsb2NrKE0sIG9mZnNldCk7CiAgICAgICAgICAgICAgdGhpcy5fZGVzMy5lbmNyeXB0QmxvY2soTSwgb2Zmc2V0KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZGVjcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgdGhpcy5fZGVzMy5kZWNyeXB0QmxvY2soTSwgb2Zmc2V0KTsKICAgICAgICAgICAgICB0aGlzLl9kZXMyLmVuY3J5cHRCbG9jayhNLCBvZmZzZXQpOwogICAgICAgICAgICAgIHRoaXMuX2RlczEuZGVjcnlwdEJsb2NrKE0sIG9mZnNldCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGtleVNpemU6IDE5MiAvIDMyLAogICAgICAgICAgICBpdlNpemU6IDY0IC8gMzIsCiAgICAgICAgICAgIGJsb2NrU2l6ZTogNjQgLyAzMgogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5UcmlwbGVERVMuZW5jcnlwdChtZXNzYWdlLCBrZXksIGNmZyk7CiAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCAgPSBDcnlwdG9KUy5UcmlwbGVERVMuZGVjcnlwdChjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuVHJpcGxlREVTID0gQmxvY2tDaXBoZXIuX2NyZWF0ZUhlbHBlcihUcmlwbGVERVMpOwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlRyaXBsZURFUzsKICAgICAgfSk7CiAgICB9KSh0cmlwbGVkZXMkMSk7CiAgICByZXR1cm4gdHJpcGxlZGVzJDEuZXhwb3J0czsKICB9CgogIHZhciByYzQkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciByYzQgPSByYzQkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFJjNDsKICBmdW5jdGlvbiByZXF1aXJlUmM0KCkgewogICAgaWYgKGhhc1JlcXVpcmVkUmM0KSByZXR1cm4gcmM0JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUmM0ID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUVuY0Jhc2U2NCgpLCByZXF1aXJlTWQ1KCksIHJlcXVpcmVFdnBrZGYoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShyYzQsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBTdHJlYW1DaXBoZXIgPSBDX2xpYi5TdHJlYW1DaXBoZXI7CiAgICAgICAgICB2YXIgQ19hbGdvID0gQy5hbGdvOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogUkM0IHN0cmVhbSBjaXBoZXIgYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgUkM0ID0gQ19hbGdvLlJDNCA9IFN0cmVhbUNpcGhlci5leHRlbmQoewogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBrZXkgPSB0aGlzLl9rZXk7CiAgICAgICAgICAgICAgdmFyIGtleVdvcmRzID0ga2V5LndvcmRzOwogICAgICAgICAgICAgIHZhciBrZXlTaWdCeXRlcyA9IGtleS5zaWdCeXRlczsKCiAgICAgICAgICAgICAgLy8gSW5pdCBzYm94CiAgICAgICAgICAgICAgdmFyIFMgPSB0aGlzLl9TID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICAgICAgU1tpXSA9IGk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBLZXkgc2V0dXAKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaiA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGtleUJ5dGVJbmRleCA9IGkgJSBrZXlTaWdCeXRlczsKICAgICAgICAgICAgICAgIHZhciBrZXlCeXRlID0ga2V5V29yZHNba2V5Qnl0ZUluZGV4ID4+PiAyXSA+Pj4gMjQgLSBrZXlCeXRlSW5kZXggJSA0ICogOCAmIDB4ZmY7CiAgICAgICAgICAgICAgICBqID0gKGogKyBTW2ldICsga2V5Qnl0ZSkgJSAyNTY7CgogICAgICAgICAgICAgICAgLy8gU3dhcAogICAgICAgICAgICAgICAgdmFyIHQgPSBTW2ldOwogICAgICAgICAgICAgICAgU1tpXSA9IFNbal07CiAgICAgICAgICAgICAgICBTW2pdID0gdDsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIENvdW50ZXJzCiAgICAgICAgICAgICAgdGhpcy5faSA9IHRoaXMuX2ogPSAwOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICBNW29mZnNldF0gXj0gZ2VuZXJhdGVLZXlzdHJlYW1Xb3JkLmNhbGwodGhpcyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGtleVNpemU6IDI1NiAvIDMyLAogICAgICAgICAgICBpdlNpemU6IDAKICAgICAgICAgIH0pOwogICAgICAgICAgZnVuY3Rpb24gZ2VuZXJhdGVLZXlzdHJlYW1Xb3JkKCkgewogICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgdmFyIFMgPSB0aGlzLl9TOwogICAgICAgICAgICB2YXIgaSA9IHRoaXMuX2k7CiAgICAgICAgICAgIHZhciBqID0gdGhpcy5fajsKCiAgICAgICAgICAgIC8vIEdlbmVyYXRlIGtleXN0cmVhbSB3b3JkCiAgICAgICAgICAgIHZhciBrZXlzdHJlYW1Xb3JkID0gMDsKICAgICAgICAgICAgZm9yICh2YXIgbiA9IDA7IG4gPCA0OyBuKyspIHsKICAgICAgICAgICAgICBpID0gKGkgKyAxKSAlIDI1NjsKICAgICAgICAgICAgICBqID0gKGogKyBTW2ldKSAlIDI1NjsKCiAgICAgICAgICAgICAgLy8gU3dhcAogICAgICAgICAgICAgIHZhciB0ID0gU1tpXTsKICAgICAgICAgICAgICBTW2ldID0gU1tqXTsKICAgICAgICAgICAgICBTW2pdID0gdDsKICAgICAgICAgICAgICBrZXlzdHJlYW1Xb3JkIHw9IFNbKFNbaV0gKyBTW2pdKSAlIDI1Nl0gPDwgMjQgLSBuICogODsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVXBkYXRlIGNvdW50ZXJzCiAgICAgICAgICAgIHRoaXMuX2kgPSBpOwogICAgICAgICAgICB0aGlzLl9qID0gajsKICAgICAgICAgICAgcmV0dXJuIGtleXN0cmVhbVdvcmQ7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5SQzQuZW5jcnlwdChtZXNzYWdlLCBrZXksIGNmZyk7CiAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCAgPSBDcnlwdG9KUy5SQzQuZGVjcnlwdChjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuUkM0ID0gU3RyZWFtQ2lwaGVyLl9jcmVhdGVIZWxwZXIoUkM0KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIE1vZGlmaWVkIFJDNCBzdHJlYW0gY2lwaGVyIGFsZ29yaXRobS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIFJDNERyb3AgPSBDX2FsZ28uUkM0RHJvcCA9IFJDNC5leHRlbmQoewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gZHJvcCBUaGUgbnVtYmVyIG9mIGtleXN0cmVhbSB3b3JkcyB0byBkcm9wLiBEZWZhdWx0IDE5MgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2ZnOiBSQzQuY2ZnLmV4dGVuZCh7CiAgICAgICAgICAgICAgZHJvcDogMTkyCiAgICAgICAgICAgIH0pLAogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIFJDNC5fZG9SZXNldC5jYWxsKHRoaXMpOwoKICAgICAgICAgICAgICAvLyBEcm9wCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IHRoaXMuY2ZnLmRyb3A7IGkgPiAwOyBpLS0pIHsKICAgICAgICAgICAgICAgIGdlbmVyYXRlS2V5c3RyZWFtV29yZC5jYWxsKHRoaXMpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5SQzREcm9wLmVuY3J5cHQobWVzc2FnZSwga2V5LCBjZmcpOwogICAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgID0gQ3J5cHRvSlMuUkM0RHJvcC5kZWNyeXB0KGNpcGhlcnRleHQsIGtleSwgY2ZnKTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5SQzREcm9wID0gU3RyZWFtQ2lwaGVyLl9jcmVhdGVIZWxwZXIoUkM0RHJvcCk7CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMuUkM0OwogICAgICB9KTsKICAgIH0pKHJjNCQxKTsKICAgIHJldHVybiByYzQkMS5leHBvcnRzOwogIH0KCiAgdmFyIHJhYmJpdCQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIHJhYmJpdCA9IHJhYmJpdCQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkUmFiYml0OwogIGZ1bmN0aW9uIHJlcXVpcmVSYWJiaXQoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRSYWJiaXQpIHJldHVybiByYWJiaXQkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRSYWJiaXQgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlRW5jQmFzZTY0KCksIHJlcXVpcmVNZDUoKSwgcmVxdWlyZUV2cGtkZigpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHJhYmJpdCwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFN0cmVhbUNpcGhlciA9IENfbGliLlN0cmVhbUNpcGhlcjsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CgogICAgICAgICAgLy8gUmV1c2FibGUgb2JqZWN0cwogICAgICAgICAgdmFyIFMgPSBbXTsKICAgICAgICAgIHZhciBDXyA9IFtdOwogICAgICAgICAgdmFyIEcgPSBbXTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFJhYmJpdCBzdHJlYW0gY2lwaGVyIGFsZ29yaXRobQogICAgICAgICAgICovCiAgICAgICAgICB2YXIgUmFiYml0ID0gQ19hbGdvLlJhYmJpdCA9IFN0cmVhbUNpcGhlci5leHRlbmQoewogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBLID0gdGhpcy5fa2V5LndvcmRzOwogICAgICAgICAgICAgIHZhciBpdiA9IHRoaXMuY2ZnLml2OwoKICAgICAgICAgICAgICAvLyBTd2FwIGVuZGlhbgogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgICAgICAgICBLW2ldID0gKEtbaV0gPDwgOCB8IEtbaV0gPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoS1tpXSA8PCAyNCB8IEtbaV0gPj4+IDgpICYgMHhmZjAwZmYwMDsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIEdlbmVyYXRlIGluaXRpYWwgc3RhdGUgdmFsdWVzCiAgICAgICAgICAgICAgdmFyIFggPSB0aGlzLl9YID0gW0tbMF0sIEtbM10gPDwgMTYgfCBLWzJdID4+PiAxNiwgS1sxXSwgS1swXSA8PCAxNiB8IEtbM10gPj4+IDE2LCBLWzJdLCBLWzFdIDw8IDE2IHwgS1swXSA+Pj4gMTYsIEtbM10sIEtbMl0gPDwgMTYgfCBLWzFdID4+PiAxNl07CgogICAgICAgICAgICAgIC8vIEdlbmVyYXRlIGluaXRpYWwgY291bnRlciB2YWx1ZXMKICAgICAgICAgICAgICB2YXIgQyA9IHRoaXMuX0MgPSBbS1syXSA8PCAxNiB8IEtbMl0gPj4+IDE2LCBLWzBdICYgMHhmZmZmMDAwMCB8IEtbMV0gJiAweDAwMDBmZmZmLCBLWzNdIDw8IDE2IHwgS1szXSA+Pj4gMTYsIEtbMV0gJiAweGZmZmYwMDAwIHwgS1syXSAmIDB4MDAwMGZmZmYsIEtbMF0gPDwgMTYgfCBLWzBdID4+PiAxNiwgS1syXSAmIDB4ZmZmZjAwMDAgfCBLWzNdICYgMHgwMDAwZmZmZiwgS1sxXSA8PCAxNiB8IEtbMV0gPj4+IDE2LCBLWzNdICYgMHhmZmZmMDAwMCB8IEtbMF0gJiAweDAwMDBmZmZmXTsKCiAgICAgICAgICAgICAgLy8gQ2FycnkgYml0CiAgICAgICAgICAgICAgdGhpcy5fYiA9IDA7CgogICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhlIHN5c3RlbSBmb3VyIHRpbWVzCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgICAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gTW9kaWZ5IHRoZSBjb3VudGVycwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODsgaSsrKSB7CiAgICAgICAgICAgICAgICBDW2ldIF49IFhbaSArIDQgJiA3XTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIElWIHNldHVwCiAgICAgICAgICAgICAgaWYgKGl2KSB7CiAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICAgIHZhciBJViA9IGl2LndvcmRzOwogICAgICAgICAgICAgICAgdmFyIElWXzAgPSBJVlswXTsKICAgICAgICAgICAgICAgIHZhciBJVl8xID0gSVZbMV07CgogICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgZm91ciBzdWJ2ZWN0b3JzCiAgICAgICAgICAgICAgICB2YXIgaTAgPSAoSVZfMCA8PCA4IHwgSVZfMCA+Pj4gMjQpICYgMHgwMGZmMDBmZiB8IChJVl8wIDw8IDI0IHwgSVZfMCA+Pj4gOCkgJiAweGZmMDBmZjAwOwogICAgICAgICAgICAgICAgdmFyIGkyID0gKElWXzEgPDwgOCB8IElWXzEgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoSVZfMSA8PCAyNCB8IElWXzEgPj4+IDgpICYgMHhmZjAwZmYwMDsKICAgICAgICAgICAgICAgIHZhciBpMSA9IGkwID4+PiAxNiB8IGkyICYgMHhmZmZmMDAwMDsKICAgICAgICAgICAgICAgIHZhciBpMyA9IGkyIDw8IDE2IHwgaTAgJiAweDAwMDBmZmZmOwoKICAgICAgICAgICAgICAgIC8vIE1vZGlmeSBjb3VudGVyIHZhbHVlcwogICAgICAgICAgICAgICAgQ1swXSBePSBpMDsKICAgICAgICAgICAgICAgIENbMV0gXj0gaTE7CiAgICAgICAgICAgICAgICBDWzJdIF49IGkyOwogICAgICAgICAgICAgICAgQ1szXSBePSBpMzsKICAgICAgICAgICAgICAgIENbNF0gXj0gaTA7CiAgICAgICAgICAgICAgICBDWzVdIF49IGkxOwogICAgICAgICAgICAgICAgQ1s2XSBePSBpMjsKICAgICAgICAgICAgICAgIENbN10gXj0gaTM7CgogICAgICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aGUgc3lzdGVtIGZvdXIgdGltZXMKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgWCA9IHRoaXMuX1g7CgogICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhlIHN5c3RlbQogICAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpOwoKICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBmb3VyIGtleXN0cmVhbSB3b3JkcwogICAgICAgICAgICAgIFNbMF0gPSBYWzBdIF4gWFs1XSA+Pj4gMTYgXiBYWzNdIDw8IDE2OwogICAgICAgICAgICAgIFNbMV0gPSBYWzJdIF4gWFs3XSA+Pj4gMTYgXiBYWzVdIDw8IDE2OwogICAgICAgICAgICAgIFNbMl0gPSBYWzRdIF4gWFsxXSA+Pj4gMTYgXiBYWzddIDw8IDE2OwogICAgICAgICAgICAgIFNbM10gPSBYWzZdIF4gWFszXSA+Pj4gMTYgXiBYWzFdIDw8IDE2OwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgICAgICAgICAvLyBTd2FwIGVuZGlhbgogICAgICAgICAgICAgICAgU1tpXSA9IChTW2ldIDw8IDggfCBTW2ldID4+PiAyNCkgJiAweDAwZmYwMGZmIHwgKFNbaV0gPDwgMjQgfCBTW2ldID4+PiA4KSAmIDB4ZmYwMGZmMDA7CgogICAgICAgICAgICAgICAgLy8gRW5jcnlwdAogICAgICAgICAgICAgICAgTVtvZmZzZXQgKyBpXSBePSBTW2ldOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgYmxvY2tTaXplOiAxMjggLyAzMiwKICAgICAgICAgICAgaXZTaXplOiA2NCAvIDMyCiAgICAgICAgICB9KTsKICAgICAgICAgIGZ1bmN0aW9uIG5leHRTdGF0ZSgpIHsKICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgIHZhciBYID0gdGhpcy5fWDsKICAgICAgICAgICAgdmFyIEMgPSB0aGlzLl9DOwoKICAgICAgICAgICAgLy8gU2F2ZSBvbGQgY291bnRlciB2YWx1ZXMKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHsKICAgICAgICAgICAgICBDX1tpXSA9IENbaV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBuZXcgY291bnRlciB2YWx1ZXMKICAgICAgICAgICAgQ1swXSA9IENbMF0gKyAweDRkMzRkMzRkICsgdGhpcy5fYiB8IDA7CiAgICAgICAgICAgIENbMV0gPSBDWzFdICsgMHhkMzRkMzRkMyArIChDWzBdID4+PiAwIDwgQ19bMF0gPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICBDWzJdID0gQ1syXSArIDB4MzRkMzRkMzQgKyAoQ1sxXSA+Pj4gMCA8IENfWzFdID4+PiAwID8gMSA6IDApIHwgMDsKICAgICAgICAgICAgQ1szXSA9IENbM10gKyAweDRkMzRkMzRkICsgKENbMl0gPj4+IDAgPCBDX1syXSA+Pj4gMCA/IDEgOiAwKSB8IDA7CiAgICAgICAgICAgIENbNF0gPSBDWzRdICsgMHhkMzRkMzRkMyArIChDWzNdID4+PiAwIDwgQ19bM10gPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICBDWzVdID0gQ1s1XSArIDB4MzRkMzRkMzQgKyAoQ1s0XSA+Pj4gMCA8IENfWzRdID4+PiAwID8gMSA6IDApIHwgMDsKICAgICAgICAgICAgQ1s2XSA9IENbNl0gKyAweDRkMzRkMzRkICsgKENbNV0gPj4+IDAgPCBDX1s1XSA+Pj4gMCA/IDEgOiAwKSB8IDA7CiAgICAgICAgICAgIENbN10gPSBDWzddICsgMHhkMzRkMzRkMyArIChDWzZdID4+PiAwIDwgQ19bNl0gPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICB0aGlzLl9iID0gQ1s3XSA+Pj4gMCA8IENfWzddID4+PiAwID8gMSA6IDA7CgogICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGctdmFsdWVzCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODsgaSsrKSB7CiAgICAgICAgICAgICAgdmFyIGd4ID0gWFtpXSArIENbaV07CgogICAgICAgICAgICAgIC8vIENvbnN0cnVjdCBoaWdoIGFuZCBsb3cgYXJndW1lbnQgZm9yIHNxdWFyaW5nCiAgICAgICAgICAgICAgdmFyIGdhID0gZ3ggJiAweGZmZmY7CiAgICAgICAgICAgICAgdmFyIGdiID0gZ3ggPj4+IDE2OwoKICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgaGlnaCBhbmQgbG93IHJlc3VsdCBvZiBzcXVhcmluZwogICAgICAgICAgICAgIHZhciBnaCA9ICgoZ2EgKiBnYSA+Pj4gMTcpICsgZ2EgKiBnYiA+Pj4gMTUpICsgZ2IgKiBnYjsKICAgICAgICAgICAgICB2YXIgZ2wgPSAoKGd4ICYgMHhmZmZmMDAwMCkgKiBneCB8IDApICsgKChneCAmIDB4MDAwMGZmZmYpICogZ3ggfCAwKTsKCiAgICAgICAgICAgICAgLy8gSGlnaCBYT1IgbG93CiAgICAgICAgICAgICAgR1tpXSA9IGdoIF4gZ2w7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBuZXcgc3RhdGUgdmFsdWVzCiAgICAgICAgICAgIFhbMF0gPSBHWzBdICsgKEdbN10gPDwgMTYgfCBHWzddID4+PiAxNikgKyAoR1s2XSA8PCAxNiB8IEdbNl0gPj4+IDE2KSB8IDA7CiAgICAgICAgICAgIFhbMV0gPSBHWzFdICsgKEdbMF0gPDwgOCB8IEdbMF0gPj4+IDI0KSArIEdbN10gfCAwOwogICAgICAgICAgICBYWzJdID0gR1syXSArIChHWzFdIDw8IDE2IHwgR1sxXSA+Pj4gMTYpICsgKEdbMF0gPDwgMTYgfCBHWzBdID4+PiAxNikgfCAwOwogICAgICAgICAgICBYWzNdID0gR1szXSArIChHWzJdIDw8IDggfCBHWzJdID4+PiAyNCkgKyBHWzFdIHwgMDsKICAgICAgICAgICAgWFs0XSA9IEdbNF0gKyAoR1szXSA8PCAxNiB8IEdbM10gPj4+IDE2KSArIChHWzJdIDw8IDE2IHwgR1syXSA+Pj4gMTYpIHwgMDsKICAgICAgICAgICAgWFs1XSA9IEdbNV0gKyAoR1s0XSA8PCA4IHwgR1s0XSA+Pj4gMjQpICsgR1szXSB8IDA7CiAgICAgICAgICAgIFhbNl0gPSBHWzZdICsgKEdbNV0gPDwgMTYgfCBHWzVdID4+PiAxNikgKyAoR1s0XSA8PCAxNiB8IEdbNF0gPj4+IDE2KSB8IDA7CiAgICAgICAgICAgIFhbN10gPSBHWzddICsgKEdbNl0gPDwgOCB8IEdbNl0gPj4+IDI0KSArIEdbNV0gfCAwOwogICAgICAgICAgfQoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb25zIHRvIHRoZSBjaXBoZXIncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgKgogICAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0ID0gQ3J5cHRvSlMuUmFiYml0LmVuY3J5cHQobWVzc2FnZSwga2V5LCBjZmcpOwogICAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgID0gQ3J5cHRvSlMuUmFiYml0LmRlY3J5cHQoY2lwaGVydGV4dCwga2V5LCBjZmcpOwogICAgICAgICAgICovCiAgICAgICAgICBDLlJhYmJpdCA9IFN0cmVhbUNpcGhlci5fY3JlYXRlSGVscGVyKFJhYmJpdCk7CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMuUmFiYml0OwogICAgICB9KTsKICAgIH0pKHJhYmJpdCQxKTsKICAgIHJldHVybiByYWJiaXQkMS5leHBvcnRzOwogIH0KCiAgdmFyIHJhYmJpdExlZ2FjeSQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIHJhYmJpdExlZ2FjeSA9IHJhYmJpdExlZ2FjeSQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkUmFiYml0TGVnYWN5OwogIGZ1bmN0aW9uIHJlcXVpcmVSYWJiaXRMZWdhY3koKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRSYWJiaXRMZWdhY3kpIHJldHVybiByYWJiaXRMZWdhY3kkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRSYWJiaXRMZWdhY3kgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlRW5jQmFzZTY0KCksIHJlcXVpcmVNZDUoKSwgcmVxdWlyZUV2cGtkZigpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHJhYmJpdExlZ2FjeSwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFN0cmVhbUNpcGhlciA9IENfbGliLlN0cmVhbUNpcGhlcjsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CgogICAgICAgICAgLy8gUmV1c2FibGUgb2JqZWN0cwogICAgICAgICAgdmFyIFMgPSBbXTsKICAgICAgICAgIHZhciBDXyA9IFtdOwogICAgICAgICAgdmFyIEcgPSBbXTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFJhYmJpdCBzdHJlYW0gY2lwaGVyIGFsZ29yaXRobS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBUaGlzIGlzIGEgbGVnYWN5IHZlcnNpb24gdGhhdCBuZWdsZWN0ZWQgdG8gY29udmVydCB0aGUga2V5IHRvIGxpdHRsZS1lbmRpYW4uCiAgICAgICAgICAgKiBUaGlzIGVycm9yIGRvZXNuJ3QgYWZmZWN0IHRoZSBjaXBoZXIncyBzZWN1cml0eSwKICAgICAgICAgICAqIGJ1dCBpdCBkb2VzIGFmZmVjdCBpdHMgY29tcGF0aWJpbGl0eSB3aXRoIG90aGVyIGltcGxlbWVudGF0aW9ucy4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIFJhYmJpdExlZ2FjeSA9IENfYWxnby5SYWJiaXRMZWdhY3kgPSBTdHJlYW1DaXBoZXIuZXh0ZW5kKHsKICAgICAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgSyA9IHRoaXMuX2tleS53b3JkczsKICAgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLmNmZy5pdjsKCiAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgaW5pdGlhbCBzdGF0ZSB2YWx1ZXMKICAgICAgICAgICAgICB2YXIgWCA9IHRoaXMuX1ggPSBbS1swXSwgS1szXSA8PCAxNiB8IEtbMl0gPj4+IDE2LCBLWzFdLCBLWzBdIDw8IDE2IHwgS1szXSA+Pj4gMTYsIEtbMl0sIEtbMV0gPDwgMTYgfCBLWzBdID4+PiAxNiwgS1szXSwgS1syXSA8PCAxNiB8IEtbMV0gPj4+IDE2XTsKCiAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgaW5pdGlhbCBjb3VudGVyIHZhbHVlcwogICAgICAgICAgICAgIHZhciBDID0gdGhpcy5fQyA9IFtLWzJdIDw8IDE2IHwgS1syXSA+Pj4gMTYsIEtbMF0gJiAweGZmZmYwMDAwIHwgS1sxXSAmIDB4MDAwMGZmZmYsIEtbM10gPDwgMTYgfCBLWzNdID4+PiAxNiwgS1sxXSAmIDB4ZmZmZjAwMDAgfCBLWzJdICYgMHgwMDAwZmZmZiwgS1swXSA8PCAxNiB8IEtbMF0gPj4+IDE2LCBLWzJdICYgMHhmZmZmMDAwMCB8IEtbM10gJiAweDAwMDBmZmZmLCBLWzFdIDw8IDE2IHwgS1sxXSA+Pj4gMTYsIEtbM10gJiAweGZmZmYwMDAwIHwgS1swXSAmIDB4MDAwMGZmZmZdOwoKICAgICAgICAgICAgICAvLyBDYXJyeSBiaXQKICAgICAgICAgICAgICB0aGlzLl9iID0gMDsKCiAgICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aGUgc3lzdGVtIGZvdXIgdGltZXMKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykgewogICAgICAgICAgICAgICAgbmV4dFN0YXRlLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBNb2RpZnkgdGhlIGNvdW50ZXJzCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHsKICAgICAgICAgICAgICAgIENbaV0gXj0gWFtpICsgNCAmIDddOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gSVYgc2V0dXAKICAgICAgICAgICAgICBpZiAoaXYpIHsKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgdmFyIElWID0gaXYud29yZHM7CiAgICAgICAgICAgICAgICB2YXIgSVZfMCA9IElWWzBdOwogICAgICAgICAgICAgICAgdmFyIElWXzEgPSBJVlsxXTsKCiAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBmb3VyIHN1YnZlY3RvcnMKICAgICAgICAgICAgICAgIHZhciBpMCA9IChJVl8wIDw8IDggfCBJVl8wID4+PiAyNCkgJiAweDAwZmYwMGZmIHwgKElWXzAgPDwgMjQgfCBJVl8wID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgICB2YXIgaTIgPSAoSVZfMSA8PCA4IHwgSVZfMSA+Pj4gMjQpICYgMHgwMGZmMDBmZiB8IChJVl8xIDw8IDI0IHwgSVZfMSA+Pj4gOCkgJiAweGZmMDBmZjAwOwogICAgICAgICAgICAgICAgdmFyIGkxID0gaTAgPj4+IDE2IHwgaTIgJiAweGZmZmYwMDAwOwogICAgICAgICAgICAgICAgdmFyIGkzID0gaTIgPDwgMTYgfCBpMCAmIDB4MDAwMGZmZmY7CgogICAgICAgICAgICAgICAgLy8gTW9kaWZ5IGNvdW50ZXIgdmFsdWVzCiAgICAgICAgICAgICAgICBDWzBdIF49IGkwOwogICAgICAgICAgICAgICAgQ1sxXSBePSBpMTsKICAgICAgICAgICAgICAgIENbMl0gXj0gaTI7CiAgICAgICAgICAgICAgICBDWzNdIF49IGkzOwogICAgICAgICAgICAgICAgQ1s0XSBePSBpMDsKICAgICAgICAgICAgICAgIENbNV0gXj0gaTE7CiAgICAgICAgICAgICAgICBDWzZdIF49IGkyOwogICAgICAgICAgICAgICAgQ1s3XSBePSBpMzsKCiAgICAgICAgICAgICAgICAvLyBJdGVyYXRlIHRoZSBzeXN0ZW0gZm91ciB0aW1lcwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgICAgICAgICAgICAgICAgbmV4dFN0YXRlLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBYID0gdGhpcy5fWDsKCiAgICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aGUgc3lzdGVtCiAgICAgICAgICAgICAgbmV4dFN0YXRlLmNhbGwodGhpcyk7CgogICAgICAgICAgICAgIC8vIEdlbmVyYXRlIGZvdXIga2V5c3RyZWFtIHdvcmRzCiAgICAgICAgICAgICAgU1swXSA9IFhbMF0gXiBYWzVdID4+PiAxNiBeIFhbM10gPDwgMTY7CiAgICAgICAgICAgICAgU1sxXSA9IFhbMl0gXiBYWzddID4+PiAxNiBeIFhbNV0gPDwgMTY7CiAgICAgICAgICAgICAgU1syXSA9IFhbNF0gXiBYWzFdID4+PiAxNiBeIFhbN10gPDwgMTY7CiAgICAgICAgICAgICAgU1szXSA9IFhbNl0gXiBYWzNdID4+PiAxNiBeIFhbMV0gPDwgMTY7CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgICAgICAgICAgICAgIC8vIFN3YXAgZW5kaWFuCiAgICAgICAgICAgICAgICBTW2ldID0gKFNbaV0gPDwgOCB8IFNbaV0gPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoU1tpXSA8PCAyNCB8IFNbaV0gPj4+IDgpICYgMHhmZjAwZmYwMDsKCiAgICAgICAgICAgICAgICAvLyBFbmNyeXB0CiAgICAgICAgICAgICAgICBNW29mZnNldCArIGldIF49IFNbaV07CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBibG9ja1NpemU6IDEyOCAvIDMyLAogICAgICAgICAgICBpdlNpemU6IDY0IC8gMzIKICAgICAgICAgIH0pOwogICAgICAgICAgZnVuY3Rpb24gbmV4dFN0YXRlKCkgewogICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgdmFyIFggPSB0aGlzLl9YOwogICAgICAgICAgICB2YXIgQyA9IHRoaXMuX0M7CgogICAgICAgICAgICAvLyBTYXZlIG9sZCBjb3VudGVyIHZhbHVlcwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykgewogICAgICAgICAgICAgIENfW2ldID0gQ1tpXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBjb3VudGVyIHZhbHVlcwogICAgICAgICAgICBDWzBdID0gQ1swXSArIDB4NGQzNGQzNGQgKyB0aGlzLl9iIHwgMDsKICAgICAgICAgICAgQ1sxXSA9IENbMV0gKyAweGQzNGQzNGQzICsgKENbMF0gPj4+IDAgPCBDX1swXSA+Pj4gMCA/IDEgOiAwKSB8IDA7CiAgICAgICAgICAgIENbMl0gPSBDWzJdICsgMHgzNGQzNGQzNCArIChDWzFdID4+PiAwIDwgQ19bMV0gPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICBDWzNdID0gQ1szXSArIDB4NGQzNGQzNGQgKyAoQ1syXSA+Pj4gMCA8IENfWzJdID4+PiAwID8gMSA6IDApIHwgMDsKICAgICAgICAgICAgQ1s0XSA9IENbNF0gKyAweGQzNGQzNGQzICsgKENbM10gPj4+IDAgPCBDX1szXSA+Pj4gMCA/IDEgOiAwKSB8IDA7CiAgICAgICAgICAgIENbNV0gPSBDWzVdICsgMHgzNGQzNGQzNCArIChDWzRdID4+PiAwIDwgQ19bNF0gPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICBDWzZdID0gQ1s2XSArIDB4NGQzNGQzNGQgKyAoQ1s1XSA+Pj4gMCA8IENfWzVdID4+PiAwID8gMSA6IDApIHwgMDsKICAgICAgICAgICAgQ1s3XSA9IENbN10gKyAweGQzNGQzNGQzICsgKENbNl0gPj4+IDAgPCBDX1s2XSA+Pj4gMCA/IDEgOiAwKSB8IDA7CiAgICAgICAgICAgIHRoaXMuX2IgPSBDWzddID4+PiAwIDwgQ19bN10gPj4+IDAgPyAxIDogMDsKCiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZy12YWx1ZXMKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHsKICAgICAgICAgICAgICB2YXIgZ3ggPSBYW2ldICsgQ1tpXTsKCiAgICAgICAgICAgICAgLy8gQ29uc3RydWN0IGhpZ2ggYW5kIGxvdyBhcmd1bWVudCBmb3Igc3F1YXJpbmcKICAgICAgICAgICAgICB2YXIgZ2EgPSBneCAmIDB4ZmZmZjsKICAgICAgICAgICAgICB2YXIgZ2IgPSBneCA+Pj4gMTY7CgogICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBoaWdoIGFuZCBsb3cgcmVzdWx0IG9mIHNxdWFyaW5nCiAgICAgICAgICAgICAgdmFyIGdoID0gKChnYSAqIGdhID4+PiAxNykgKyBnYSAqIGdiID4+PiAxNSkgKyBnYiAqIGdiOwogICAgICAgICAgICAgIHZhciBnbCA9ICgoZ3ggJiAweGZmZmYwMDAwKSAqIGd4IHwgMCkgKyAoKGd4ICYgMHgwMDAwZmZmZikgKiBneCB8IDApOwoKICAgICAgICAgICAgICAvLyBIaWdoIFhPUiBsb3cKICAgICAgICAgICAgICBHW2ldID0gZ2ggXiBnbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBzdGF0ZSB2YWx1ZXMKICAgICAgICAgICAgWFswXSA9IEdbMF0gKyAoR1s3XSA8PCAxNiB8IEdbN10gPj4+IDE2KSArIChHWzZdIDw8IDE2IHwgR1s2XSA+Pj4gMTYpIHwgMDsKICAgICAgICAgICAgWFsxXSA9IEdbMV0gKyAoR1swXSA8PCA4IHwgR1swXSA+Pj4gMjQpICsgR1s3XSB8IDA7CiAgICAgICAgICAgIFhbMl0gPSBHWzJdICsgKEdbMV0gPDwgMTYgfCBHWzFdID4+PiAxNikgKyAoR1swXSA8PCAxNiB8IEdbMF0gPj4+IDE2KSB8IDA7CiAgICAgICAgICAgIFhbM10gPSBHWzNdICsgKEdbMl0gPDwgOCB8IEdbMl0gPj4+IDI0KSArIEdbMV0gfCAwOwogICAgICAgICAgICBYWzRdID0gR1s0XSArIChHWzNdIDw8IDE2IHwgR1szXSA+Pj4gMTYpICsgKEdbMl0gPDwgMTYgfCBHWzJdID4+PiAxNikgfCAwOwogICAgICAgICAgICBYWzVdID0gR1s1XSArIChHWzRdIDw8IDggfCBHWzRdID4+PiAyNCkgKyBHWzNdIHwgMDsKICAgICAgICAgICAgWFs2XSA9IEdbNl0gKyAoR1s1XSA8PCAxNiB8IEdbNV0gPj4+IDE2KSArIChHWzRdIDw8IDE2IHwgR1s0XSA+Pj4gMTYpIHwgMDsKICAgICAgICAgICAgWFs3XSA9IEdbN10gKyAoR1s2XSA8PCA4IHwgR1s2XSA+Pj4gMjQpICsgR1s1XSB8IDA7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5SYWJiaXRMZWdhY3kuZW5jcnlwdChtZXNzYWdlLCBrZXksIGNmZyk7CiAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCAgPSBDcnlwdG9KUy5SYWJiaXRMZWdhY3kuZGVjcnlwdChjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuUmFiYml0TGVnYWN5ID0gU3RyZWFtQ2lwaGVyLl9jcmVhdGVIZWxwZXIoUmFiYml0TGVnYWN5KTsKICAgICAgICB9KSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5SYWJiaXRMZWdhY3k7CiAgICAgIH0pOwogICAgfSkocmFiYml0TGVnYWN5JDEpOwogICAgcmV0dXJuIHJhYmJpdExlZ2FjeSQxLmV4cG9ydHM7CiAgfQoKICB2YXIgYmxvd2Zpc2gkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBibG93ZmlzaCA9IGJsb3dmaXNoJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRCbG93ZmlzaDsKICBmdW5jdGlvbiByZXF1aXJlQmxvd2Zpc2goKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRCbG93ZmlzaCkgcmV0dXJuIGJsb3dmaXNoJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkQmxvd2Zpc2ggPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlRW5jQmFzZTY0KCksIHJlcXVpcmVNZDUoKSwgcmVxdWlyZUV2cGtkZigpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKGJsb3dmaXNoLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICB2YXIgQyA9IENyeXB0b0pTOwogICAgICAgICAgdmFyIENfbGliID0gQy5saWI7CiAgICAgICAgICB2YXIgQmxvY2tDaXBoZXIgPSBDX2xpYi5CbG9ja0NpcGhlcjsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CiAgICAgICAgICBjb25zdCBOID0gMTY7CgogICAgICAgICAgLy9PcmlnaW4gcGJveCBhbmQgc2JveCwgZGVyaXZlZCBmcm9tIFBJCiAgICAgICAgICBjb25zdCBPUklHX1AgPSBbMHgyNDNGNkE4OCwgMHg4NUEzMDhEMywgMHgxMzE5OEEyRSwgMHgwMzcwNzM0NCwgMHhBNDA5MzgyMiwgMHgyOTlGMzFEMCwgMHgwODJFRkE5OCwgMHhFQzRFNkM4OSwgMHg0NTI4MjFFNiwgMHgzOEQwMTM3NywgMHhCRTU0NjZDRiwgMHgzNEU5MEM2QywgMHhDMEFDMjlCNywgMHhDOTdDNTBERCwgMHgzRjg0RDVCNSwgMHhCNTQ3MDkxNywgMHg5MjE2RDVEOSwgMHg4OTc5RkIxQl07CiAgICAgICAgICBjb25zdCBPUklHX1MgPSBbWzB4RDEzMTBCQTYsIDB4OThERkI1QUMsIDB4MkZGRDcyREIsIDB4RDAxQURGQjcsIDB4QjhFMUFGRUQsIDB4NkEyNjdFOTYsIDB4QkE3QzkwNDUsIDB4RjEyQzdGOTksIDB4MjRBMTk5NDcsIDB4QjM5MTZDRjcsIDB4MDgwMUYyRTIsIDB4ODU4RUZDMTYsIDB4NjM2OTIwRDgsIDB4NzE1NzRFNjksIDB4QTQ1OEZFQTMsIDB4RjQ5MzNEN0UsIDB4MEQ5NTc0OEYsIDB4NzI4RUI2NTgsIDB4NzE4QkNENTgsIDB4ODIxNTRBRUUsIDB4N0I1NEE0MUQsIDB4QzI1QTU5QjUsIDB4OUMzMEQ1MzksIDB4MkFGMjYwMTMsIDB4QzVEMUIwMjMsIDB4Mjg2MDg1RjAsIDB4Q0E0MTc5MTgsIDB4QjhEQjM4RUYsIDB4OEU3OURDQjAsIDB4NjAzQTE4MEUsIDB4NkM5RTBFOEIsIDB4QjAxRThBM0UsIDB4RDcxNTc3QzEsIDB4QkQzMTRCMjcsIDB4NzhBRjJGREEsIDB4NTU2MDVDNjAsIDB4RTY1NTI1RjMsIDB4QUE1NUFCOTQsIDB4NTc0ODk4NjIsIDB4NjNFODE0NDAsIDB4NTVDQTM5NkEsIDB4MkFBQjEwQjYsIDB4QjRDQzVDMzQsIDB4MTE0MUU4Q0UsIDB4QTE1NDg2QUYsIDB4N0M3MkU5OTMsIDB4QjNFRTE0MTEsIDB4NjM2RkJDMkEsIDB4MkJBOUM1NUQsIDB4NzQxODMxRjYsIDB4Q0U1QzNFMTYsIDB4OUI4NzkzMUUsIDB4QUZENkJBMzMsIDB4NkMyNENGNUMsIDB4N0EzMjUzODEsIDB4Mjg5NTg2NzcsIDB4M0I4RjQ4OTgsIDB4NkI0QkI5QUYsIDB4QzRCRkU4MUIsIDB4NjYyODIxOTMsIDB4NjFEODA5Q0MsIDB4RkIyMUE5OTEsIDB4NDg3Q0FDNjAsIDB4NURFQzgwMzIsIDB4RUY4NDVENUQsIDB4RTk4NTc1QjEsIDB4REMyNjIzMDIsIDB4RUI2NTFCODgsIDB4MjM4OTNFODEsIDB4RDM5NkFDQzUsIDB4MEY2RDZGRjMsIDB4ODNGNDQyMzksIDB4MkUwQjQ0ODIsIDB4QTQ4NDIwMDQsIDB4NjlDOEYwNEEsIDB4OUUxRjlCNUUsIDB4MjFDNjY4NDIsIDB4RjZFOTZDOUEsIDB4NjcwQzlDNjEsIDB4QUJEMzg4RjAsIDB4NkE1MUEwRDIsIDB4RDg1NDJGNjgsIDB4OTYwRkE3MjgsIDB4QUI1MTMzQTMsIDB4NkVFRjBCNkMsIDB4MTM3QTNCRTQsIDB4QkEzQkYwNTAsIDB4N0VGQjJBOTgsIDB4QTFGMTY1MUQsIDB4MzlBRjAxNzYsIDB4NjZDQTU5M0UsIDB4ODI0MzBFODgsIDB4OENFRTg2MTksIDB4NDU2RjlGQjQsIDB4N0Q4NEE1QzMsIDB4M0I4QjVFQkUsIDB4RTA2Rjc1RDgsIDB4ODVDMTIwNzMsIDB4NDAxQTQ0OUYsIDB4NTZDMTZBQTYsIDB4NEVEM0FBNjIsIDB4MzYzRjc3MDYsIDB4MUJGRURGNzIsIDB4NDI5QjAyM0QsIDB4MzdEMEQ3MjQsIDB4RDAwQTEyNDgsIDB4REIwRkVBRDMsIDB4NDlGMUMwOUIsIDB4MDc1MzcyQzksIDB4ODA5OTFCN0IsIDB4MjVENDc5RDgsIDB4RjZFOERFRjcsIDB4RTNGRTUwMUEsIDB4QjY3OTRDM0IsIDB4OTc2Q0UwQkQsIDB4MDRDMDA2QkEsIDB4QzFBOTRGQjYsIDB4NDA5RjYwQzQsIDB4NUU1QzlFQzIsIDB4MTk2QTI0NjMsIDB4NjhGQjZGQUYsIDB4M0U2QzUzQjUsIDB4MTMzOUIyRUIsIDB4M0I1MkVDNkYsIDB4NkRGQzUxMUYsIDB4OUIzMDk1MkMsIDB4Q0M4MTQ1NDQsIDB4QUY1RUJEMDksIDB4QkVFM0QwMDQsIDB4REUzMzRBRkQsIDB4NjYwRjI4MDcsIDB4MTkyRTRCQjMsIDB4QzBDQkE4NTcsIDB4NDVDODc0MEYsIDB4RDIwQjVGMzksIDB4QjlEM0ZCREIsIDB4NTU3OUMwQkQsIDB4MUE2MDMyMEEsIDB4RDZBMTAwQzYsIDB4NDAyQzcyNzksIDB4Njc5RjI1RkUsIDB4RkIxRkEzQ0MsIDB4OEVBNUU5RjgsIDB4REIzMjIyRjgsIDB4M0M3NTE2REYsIDB4RkQ2MTZCMTUsIDB4MkY1MDFFQzgsIDB4QUQwNTUyQUIsIDB4MzIzREI1RkEsIDB4RkQyMzg3NjAsIDB4NTMzMTdCNDgsIDB4M0UwMERGODIsIDB4OUU1QzU3QkIsIDB4Q0E2RjhDQTAsIDB4MUE4NzU2MkUsIDB4REYxNzY5REIsIDB4RDU0MkE4RjYsIDB4Mjg3RUZGQzMsIDB4QUM2NzMyQzYsIDB4OEM0RjU1NzMsIDB4Njk1QjI3QjAsIDB4QkJDQTU4QzgsIDB4RTFGRkEzNUQsIDB4QjhGMDExQTAsIDB4MTBGQTNEOTgsIDB4RkQyMTgzQjgsIDB4NEFGQ0I1NkMsIDB4MkREMUQzNUIsIDB4OUE1M0U0NzksIDB4QjZGODQ1NjUsIDB4RDI4RTQ5QkMsIDB4NEJGQjk3OTAsIDB4RTFEREYyREEsIDB4QTRDQjdFMzMsIDB4NjJGQjEzNDEsIDB4Q0VFNEM2RTgsIDB4RUYyMENBREEsIDB4MzY3NzRDMDEsIDB4RDA3RTlFRkUsIDB4MkJGMTFGQjQsIDB4OTVEQkRBNEQsIDB4QUU5MDkxOTgsIDB4RUFBRDhFNzEsIDB4NkI5M0Q1QTAsIDB4RDA4RUQxRDAsIDB4QUZDNzI1RTAsIDB4OEUzQzVCMkYsIDB4OEU3NTk0QjcsIDB4OEZGNkUyRkIsIDB4RjIxMjJCNjQsIDB4ODg4OEI4MTIsIDB4OTAwREYwMUMsIDB4NEZBRDVFQTAsIDB4Njg4RkMzMUMsIDB4RDFDRkYxOTEsIDB4QjNBOEMxQUQsIDB4MkYyRjIyMTgsIDB4QkUwRTE3NzcsIDB4RUE3NTJERkUsIDB4OEIwMjFGQTEsIDB4RTVBMENDMEYsIDB4QjU2Rjc0RTgsIDB4MThBQ0YzRDYsIDB4Q0U4OUUyOTksIDB4QjRBODRGRTAsIDB4RkQxM0UwQjcsIDB4N0NDNDNCODEsIDB4RDJBREE4RDksIDB4MTY1RkEyNjYsIDB4ODA5NTc3MDUsIDB4OTNDQzczMTQsIDB4MjExQTE0NzcsIDB4RTZBRDIwNjUsIDB4NzdCNUZBODYsIDB4Qzc1NDQyRjUsIDB4RkI5RDM1Q0YsIDB4RUJDREFGMEMsIDB4N0IzRTg5QTAsIDB4RDY0MTFCRDMsIDB4QUUxRTdFNDksIDB4MDAyNTBFMkQsIDB4MjA3MUIzNUUsIDB4MjI2ODAwQkIsIDB4NTdCOEUwQUYsIDB4MjQ2NDM2OUIsIDB4RjAwOUI5MUUsIDB4NTU2MzkxMUQsIDB4NTlERkE2QUEsIDB4NzhDMTQzODksIDB4RDk1QTUzN0YsIDB4MjA3RDVCQTIsIDB4MDJFNUI5QzUsIDB4ODMyNjAzNzYsIDB4NjI5NUNGQTksIDB4MTFDODE5NjgsIDB4NEU3MzRBNDEsIDB4QjM0NzJEQ0EsIDB4N0IxNEE5NEEsIDB4MUI1MTAwNTIsIDB4OUE1MzI5MTUsIDB4RDYwRjU3M0YsIDB4QkM5QkM2RTQsIDB4MkI2MEE0NzYsIDB4ODFFNjc0MDAsIDB4MDhCQTZGQjUsIDB4NTcxQkU5MUYsIDB4RjI5NkVDNkIsIDB4MkEwREQ5MTUsIDB4QjY2MzY1MjEsIDB4RTdCOUY5QjYsIDB4RkYzNDA1MkUsIDB4QzU4NTU2NjQsIDB4NTNCMDJENUQsIDB4QTk5RjhGQTEsIDB4MDhCQTQ3OTksIDB4NkU4NTA3NkFdLCBbMHg0QjdBNzBFOSwgMHhCNUIzMjk0NCwgMHhEQjc1MDkyRSwgMHhDNDE5MjYyMywgMHhBRDZFQTZCMCwgMHg0OUE3REY3RCwgMHg5Q0VFNjBCOCwgMHg4RkVEQjI2NiwgMHhFQ0FBOEM3MSwgMHg2OTlBMTdGRiwgMHg1NjY0NTI2QywgMHhDMkIxOUVFMSwgMHgxOTM2MDJBNSwgMHg3NTA5NEMyOSwgMHhBMDU5MTM0MCwgMHhFNDE4M0EzRSwgMHgzRjU0OTg5QSwgMHg1QjQyOUQ2NSwgMHg2QjhGRTRENiwgMHg5OUY3M0ZENiwgMHhBMUQyOUMwNywgMHhFRkU4MzBGNSwgMHg0RDJEMzhFNiwgMHhGMDI1NURDMSwgMHg0Q0REMjA4NiwgMHg4NDcwRUIyNiwgMHg2MzgyRTlDNiwgMHgwMjFFQ0M1RSwgMHgwOTY4NkIzRiwgMHgzRUJBRUZDOSwgMHgzQzk3MTgxNCwgMHg2QjZBNzBBMSwgMHg2ODdGMzU4NCwgMHg1MkEwRTI4NiwgMHhCNzlDNTMwNSwgMHhBQTUwMDczNywgMHgzRTA3ODQxQywgMHg3RkRFQUU1QywgMHg4RTdENDRFQywgMHg1NzE2RjJCOCwgMHhCMDNBREEzNywgMHhGMDUwMEMwRCwgMHhGMDFDMUYwNCwgMHgwMjAwQjNGRiwgMHhBRTBDRjUxQSwgMHgzQ0I1NzRCMiwgMHgyNTgzN0E1OCwgMHhEQzA5MjFCRCwgMHhEMTkxMTNGOSwgMHg3Q0E5MkZGNiwgMHg5NDMyNDc3MywgMHgyMkY1NDcwMSwgMHgzQUU1RTU4MSwgMHgzN0MyREFEQywgMHhDOEI1NzYzNCwgMHg5QUYzRERBNywgMHhBOTQ0NjE0NiwgMHgwRkQwMDMwRSwgMHhFQ0M4QzczRSwgMHhBNDc1MUU0MSwgMHhFMjM4Q0Q5OSwgMHgzQkVBMEUyRiwgMHgzMjgwQkJBMSwgMHgxODNFQjMzMSwgMHg0RTU0OEIzOCwgMHg0RjZEQjkwOCwgMHg2RjQyMEQwMywgMHhGNjBBMDRCRiwgMHgyQ0I4MTI5MCwgMHgyNDk3N0M3OSwgMHg1Njc5QjA3MiwgMHhCQ0FGODlBRiwgMHhERTlBNzcxRiwgMHhEOTkzMDgxMCwgMHhCMzhCQUUxMiwgMHhEQ0NGM0YyRSwgMHg1NTEyNzIxRiwgMHgyRTZCNzEyNCwgMHg1MDFBRERFNiwgMHg5Rjg0Q0Q4NywgMHg3QTU4NDcxOCwgMHg3NDA4REExNywgMHhCQzlGOUFCQywgMHhFOTRCN0Q4QywgMHhFQzdBRUMzQSwgMHhEQjg1MURGQSwgMHg2MzA5NDM2NiwgMHhDNDY0QzNEMiwgMHhFRjFDMTg0NywgMHgzMjE1RDkwOCwgMHhERDQzM0IzNywgMHgyNEMyQkExNiwgMHgxMkExNEQ0MywgMHgyQTY1QzQ1MSwgMHg1MDk0MDAwMiwgMHgxMzNBRTRERCwgMHg3MURGRjg5RSwgMHgxMDMxNEU1NSwgMHg4MUFDNzdENiwgMHg1RjExMTk5QiwgMHgwNDM1NTZGMSwgMHhEN0EzQzc2QiwgMHgzQzExMTgzQiwgMHg1OTI0QTUwOSwgMHhGMjhGRTZFRCwgMHg5N0YxRkJGQSwgMHg5RUJBQkYyQywgMHgxRTE1M0M2RSwgMHg4NkUzNDU3MCwgMHhFQUU5NkZCMSwgMHg4NjBFNUUwQSwgMHg1QTNFMkFCMywgMHg3NzFGRTcxQywgMHg0RTNEMDZGQSwgMHgyOTY1RENCOSwgMHg5OUU3MUQwRiwgMHg4MDNFODlENiwgMHg1MjY2QzgyNSwgMHgyRTRDQzk3OCwgMHg5QzEwQjM2QSwgMHhDNjE1MEVCQSwgMHg5NEUyRUE3OCwgMHhBNUZDM0M1MywgMHgxRTBBMkRGNCwgMHhGMkY3NEVBNywgMHgzNjFEMkIzRCwgMHgxOTM5MjYwRiwgMHgxOUMyNzk2MCwgMHg1MjIzQTcwOCwgMHhGNzEzMTJCNiwgMHhFQkFERkU2RSwgMHhFQUMzMUY2NiwgMHhFM0JDNDU5NSwgMHhBNjdCQzg4MywgMHhCMTdGMzdEMSwgMHgwMThDRkYyOCwgMHhDMzMyRERFRiwgMHhCRTZDNUFBNSwgMHg2NTU4MjE4NSwgMHg2OEFCOTgwMiwgMHhFRUNFQTUwRiwgMHhEQjJGOTUzQiwgMHgyQUVGN0RBRCwgMHg1QjZFMkY4NCwgMHgxNTIxQjYyOCwgMHgyOTA3NjE3MCwgMHhFQ0RENDc3NSwgMHg2MTlGMTUxMCwgMHgxM0NDQTgzMCwgMHhFQjYxQkQ5NiwgMHgwMzM0RkUxRSwgMHhBQTAzNjNDRiwgMHhCNTczNUM5MCwgMHg0QzcwQTIzOSwgMHhENTlFOUUwQiwgMHhDQkFBREUxNCwgMHhFRUNDODZCQywgMHg2MDYyMkNBNywgMHg5Q0FCNUNBQiwgMHhCMkYzODQ2RSwgMHg2NDhCMUVBRiwgMHgxOUJERjBDQSwgMHhBMDIzNjlCOSwgMHg2NTVBQkI1MCwgMHg0MDY4NUEzMiwgMHgzQzJBQjRCMywgMHgzMTlFRTlENSwgMHhDMDIxQjhGNywgMHg5QjU0MEIxOSwgMHg4NzVGQTA5OSwgMHg5NUY3OTk3RSwgMHg2MjNEN0RBOCwgMHhGODM3ODg5QSwgMHg5N0UzMkQ3NywgMHgxMUVEOTM1RiwgMHgxNjY4MTI4MSwgMHgwRTM1ODgyOSwgMHhDN0U2MUZENiwgMHg5NkRFREZBMSwgMHg3ODU4QkE5OSwgMHg1N0Y1ODRBNSwgMHgxQjIyNzI2MywgMHg5QjgzQzNGRiwgMHgxQUMyNDY5NiwgMHhDREIzMEFFQiwgMHg1MzJFMzA1NCwgMHg4RkQ5NDhFNCwgMHg2REJDMzEyOCwgMHg1OEVCRjJFRiwgMHgzNEM2RkZFQSwgMHhGRTI4RUQ2MSwgMHhFRTdDM0M3MywgMHg1RDRBMTREOSwgMHhFODY0QjdFMywgMHg0MjEwNUQxNCwgMHgyMDNFMTNFMCwgMHg0NUVFRTJCNiwgMHhBM0FBQUJFQSwgMHhEQjZDNEYxNSwgMHhGQUNCNEZEMCwgMHhDNzQyRjQ0MiwgMHhFRjZBQkJCNSwgMHg2NTRGM0IxRCwgMHg0MUNEMjEwNSwgMHhEODFFNzk5RSwgMHg4Njg1NERDNywgMHhFNDRCNDc2QSwgMHgzRDgxNjI1MCwgMHhDRjYyQTFGMiwgMHg1QjhEMjY0NiwgMHhGQzg4ODNBMCwgMHhDMUM3QjZBMywgMHg3RjE1MjRDMywgMHg2OUNCNzQ5MiwgMHg0Nzg0OEEwQiwgMHg1NjkyQjI4NSwgMHgwOTVCQkYwMCwgMHhBRDE5NDg5RCwgMHgxNDYyQjE3NCwgMHgyMzgyMEUwMCwgMHg1ODQyOEQyQSwgMHgwQzU1RjVFQSwgMHgxREFERjQzRSwgMHgyMzNGNzA2MSwgMHgzMzcyRjA5MiwgMHg4RDkzN0U0MSwgMHhENjVGRUNGMSwgMHg2QzIyM0JEQiwgMHg3Q0RFMzc1OSwgMHhDQkVFNzQ2MCwgMHg0MDg1RjJBNywgMHhDRTc3MzI2RSwgMHhBNjA3ODA4NCwgMHgxOUY4NTA5RSwgMHhFOEVGRDg1NSwgMHg2MUQ5OTczNSwgMHhBOTY5QTdBQSwgMHhDNTBDMDZDMiwgMHg1QTA0QUJGQywgMHg4MDBCQ0FEQywgMHg5RTQ0N0EyRSwgMHhDMzQ1MzQ4NCwgMHhGREQ1NjcwNSwgMHgwRTFFOUVDOSwgMHhEQjczREJEMywgMHgxMDU1ODhDRCwgMHg2NzVGREE3OSwgMHhFMzY3NDM0MCwgMHhDNUM0MzQ2NSwgMHg3MTNFMzhEOCwgMHgzRDI4Rjg5RSwgMHhGMTZERkYyMCwgMHgxNTNFMjFFNywgMHg4RkIwM0Q0QSwgMHhFNkUzOUYyQiwgMHhEQjgzQURGN10sIFsweEU5M0Q1QTY4LCAweDk0ODE0MEY3LCAweEY2NEMyNjFDLCAweDk0NjkyOTM0LCAweDQxMTUyMEY3LCAweDc2MDJENEY3LCAweEJDRjQ2QjJFLCAweEQ0QTIwMDY4LCAweEQ0MDgyNDcxLCAweDMzMjBGNDZBLCAweDQzQjdENEI3LCAweDUwMDA2MUFGLCAweDFFMzlGNjJFLCAweDk3MjQ0NTQ2LCAweDE0MjE0Rjc0LCAweEJGOEI4ODQwLCAweDREOTVGQzFELCAweDk2QjU5MUFGLCAweDcwRjREREQzLCAweDY2QTAyRjQ1LCAweEJGQkMwOUVDLCAweDAzQkQ5Nzg1LCAweDdGQUM2REQwLCAweDMxQ0I4NTA0LCAweDk2RUIyN0IzLCAweDU1RkQzOTQxLCAweERBMjU0N0U2LCAweEFCQ0EwQTlBLCAweDI4NTA3ODI1LCAweDUzMDQyOUY0LCAweDBBMkM4NkRBLCAweEU5QjY2REZCLCAweDY4REMxNDYyLCAweEQ3NDg2OTAwLCAweDY4MEVDMEE0LCAweDI3QTE4REVFLCAweDRGM0ZGRUEyLCAweEU4ODdBRDhDLCAweEI1OENFMDA2LCAweDdBRjRENkI2LCAweEFBQ0UxRTdDLCAweEQzMzc1RkVDLCAweENFNzhBMzk5LCAweDQwNkIyQTQyLCAweDIwRkU5RTM1LCAweEQ5RjM4NUI5LCAweEVFMzlEN0FCLCAweDNCMTI0RThCLCAweDFEQzlGQUY3LCAweDRCNkQxODU2LCAweDI2QTM2NjMxLCAweEVBRTM5N0IyLCAweDNBNkVGQTc0LCAweERENUI0MzMyLCAweDY4NDFFN0Y3LCAweENBNzgyMEZCLCAweEZCMEFGNTRFLCAweEQ4RkVCMzk3LCAweDQ1NDA1NkFDLCAweEJBNDg5NTI3LCAweDU1NTMzQTNBLCAweDIwODM4RDg3LCAweEZFNkJBOUI3LCAweEQwOTY5NTRCLCAweDU1QTg2N0JDLCAweEExMTU5QTU4LCAweENDQTkyOTYzLCAweDk5RTFEQjMzLCAweEE2MkE0QTU2LCAweDNGMzEyNUY5LCAweDVFRjQ3RTFDLCAweDkwMjkzMTdDLCAweEZERjhFODAyLCAweDA0MjcyRjcwLCAweDgwQkIxNTVDLCAweDA1MjgyQ0UzLCAweDk1QzExNTQ4LCAweEU0QzY2RDIyLCAweDQ4QzExMzNGLCAweEM3MEY4NkRDLCAweDA3RjlDOUVFLCAweDQxMDQxRjBGLCAweDQwNDc3OUE0LCAweDVEODg2RTE3LCAweDMyNUY1MUVCLCAweEQ1OUJDMEQxLCAweEYyQkNDMThGLCAweDQxMTEzNTY0LCAweDI1N0I3ODM0LCAweDYwMkE5QzYwLCAweERGRjhFOEEzLCAweDFGNjM2QzFCLCAweDBFMTJCNEMyLCAweDAyRTEzMjlFLCAweEFGNjY0RkQxLCAweENBRDE4MTE1LCAweDZCMjM5NUUwLCAweDMzM0U5MkUxLCAweDNCMjQwQjYyLCAweEVFQkVCOTIyLCAweDg1QjJBMjBFLCAweEU2QkEwRDk5LCAweERFNzIwQzhDLCAweDJEQTJGNzI4LCAweEQwMTI3ODQ1LCAweDk1Qjc5NEZELCAweDY0N0QwODYyLCAweEU3Q0NGNUYwLCAweDU0NDlBMzZGLCAweDg3N0Q0OEZBLCAweEMzOURGRDI3LCAweEYzM0U4RDFFLCAweDBBNDc2MzQxLCAweDk5MkVGRjc0LCAweDNBNkY2RUFCLCAweEY0RjhGRDM3LCAweEE4MTJEQzYwLCAweEExRUJEREY4LCAweDk5MUJFMTRDLCAweERCNkU2QjBELCAweEM2N0I1NTEwLCAweDZENjcyQzM3LCAweDI3NjVENDNCLCAweERDRDBFODA0LCAweEYxMjkwREM3LCAweENDMDBGRkEzLCAweEI1MzkwRjkyLCAweDY5MEZFRDBCLCAweDY2N0I5RkZCLCAweENFREI3RDlDLCAweEEwOTFDRjBCLCAweEQ5MTU1RUEzLCAweEJCMTMyRjg4LCAweDUxNUJBRDI0LCAweDdCOTQ3OUJGLCAweDc2M0JENkVCLCAweDM3MzkyRUIzLCAweENDMTE1OTc5LCAweDgwMjZFMjk3LCAweEY0MkUzMTJELCAweDY4NDJBREE3LCAweEM2NkEyQjNCLCAweDEyNzU0Q0NDLCAweDc4MkVGMTFDLCAweDZBMTI0MjM3LCAweEI3OTI1MUU3LCAweDA2QTFCQkU2LCAweDRCRkI2MzUwLCAweDFBNkIxMDE4LCAweDExQ0FFREZBLCAweDNEMjVCREQ4LCAweEUyRTFDM0M5LCAweDQ0NDIxNjU5LCAweDBBMTIxMzg2LCAweEQ5MENFQzZFLCAweEQ1QUJFQTJBLCAweDY0QUY2NzRFLCAweERBODZBODVGLCAweEJFQkZFOTg4LCAweDY0RTRDM0ZFLCAweDlEQkM4MDU3LCAweEYwRjdDMDg2LCAweDYwNzg3QkY4LCAweDYwMDM2MDRELCAweEQxRkQ4MzQ2LCAweEY2MzgxRkIwLCAweDc3NDVBRTA0LCAweEQ3MzZGQ0NDLCAweDgzNDI2QjMzLCAweEYwMUVBQjcxLCAweEIwODA0MTg3LCAweDNDMDA1RTVGLCAweDc3QTA1N0JFLCAweEJERThBRTI0LCAweDU1NDY0Mjk5LCAweEJGNTgyRTYxLCAweDRFNThGNDhGLCAweEYyRERGREEyLCAweEY0NzRFRjM4LCAweDg3ODlCREMyLCAweDUzNjZGOUMzLCAweEM4QjM4RTc0LCAweEI0NzVGMjU1LCAweDQ2RkNEOUI5LCAweDdBRUIyNjYxLCAweDhCMURERjg0LCAweDg0NkEwRTc5LCAweDkxNUY5NUUyLCAweDQ2NkU1OThFLCAweDIwQjQ1NzcwLCAweDhDRDU1NTkxLCAweEM5MDJERTRDLCAweEI5MEJBQ0UxLCAweEJCODIwNUQwLCAweDExQTg2MjQ4LCAweDc1NzRBOTlFLCAweEI3N0YxOUI2LCAweEUwQTlEQzA5LCAweDY2MkQwOUExLCAweEM0MzI0NjMzLCAweEU4NUExRjAyLCAweDA5RjBCRThDLCAweDRBOTlBMDI1LCAweDFENkVGRTEwLCAweDFBQjkzRDFELCAweDBCQTVBNERGLCAweEExODZGMjBGLCAweDI4NjhGMTY5LCAweERDQjdEQTgzLCAweDU3MzkwNkZFLCAweEExRTJDRTlCLCAweDRGQ0Q3RjUyLCAweDUwMTE1RTAxLCAweEE3MDY4M0ZBLCAweEEwMDJCNUM0LCAweDBERTZEMDI3LCAweDlBRjg4QzI3LCAweDc3M0Y4NjQxLCAweEMzNjA0QzA2LCAweDYxQTgwNkI1LCAweEYwMTc3QTI4LCAweEMwRjU4NkUwLCAweDAwNjA1OEFBLCAweDMwREM3RDYyLCAweDExRTY5RUQ3LCAweDIzMzhFQTYzLCAweDUzQzJERDk0LCAweEMyQzIxNjM0LCAweEJCQ0JFRTU2LCAweDkwQkNCNkRFLCAweEVCRkM3REExLCAweENFNTkxRDc2LCAweDZGMDVFNDA5LCAweDRCN0MwMTg4LCAweDM5NzIwQTNELCAweDdDOTI3QzI0LCAweDg2RTM3MjVGLCAweDcyNEQ5REI5LCAweDFBQzE1QkI0LCAweEQzOUVCOEZDLCAweEVENTQ1NTc4LCAweDA4RkNBNUI1LCAweEQ4M0Q3Q0QzLCAweDREQUQwRkM0LCAweDFFNTBFRjVFLCAweEIxNjFFNkY4LCAweEEyODUxNEQ5LCAweDZDNTExMzNDLCAweDZGRDVDN0U3LCAweDU2RTE0RUM0LCAweDM2MkFCRkNFLCAweEREQzZDODM3LCAweEQ3OUEzMjM0LCAweDkyNjM4MjEyLCAweDY3MEVGQThFLCAweDQwNjAwMEUwXSwgWzB4M0EzOUNFMzcsIDB4RDNGQUY1Q0YsIDB4QUJDMjc3MzcsIDB4NUFDNTJEMUIsIDB4NUNCMDY3OUUsIDB4NEZBMzM3NDIsIDB4RDM4MjI3NDAsIDB4OTlCQzlCQkUsIDB4RDUxMThFOUQsIDB4QkYwRjczMTUsIDB4RDYyRDFDN0UsIDB4QzcwMEM0N0IsIDB4Qjc4QzFCNkIsIDB4MjFBMTkwNDUsIDB4QjI2RUIxQkUsIDB4NkEzNjZFQjQsIDB4NTc0OEFCMkYsIDB4QkM5NDZFNzksIDB4QzZBMzc2RDIsIDB4NjU0OUMyQzgsIDB4NTMwRkY4RUUsIDB4NDY4RERFN0QsIDB4RDU3MzBBMUQsIDB4NENEMDREQzYsIDB4MjkzOUJCREIsIDB4QTlCQTQ2NTAsIDB4QUM5NTI2RTgsIDB4QkU1RUUzMDQsIDB4QTFGQUQ1RjAsIDB4NkEyRDUxOUEsIDB4NjNFRjhDRTIsIDB4OUE4NkVFMjIsIDB4QzA4OUMyQjgsIDB4NDMyNDJFRjYsIDB4QTUxRTAzQUEsIDB4OUNGMkQwQTQsIDB4ODNDMDYxQkEsIDB4OUJFOTZBNEQsIDB4OEZFNTE1NTAsIDB4QkE2NDVCRDYsIDB4MjgyNkEyRjksIDB4QTczQTNBRTEsIDB4NEJBOTk1ODYsIDB4RUY1NTYyRTksIDB4QzcyRkVGRDMsIDB4Rjc1MkY3REEsIDB4M0YwNDZGNjksIDB4NzdGQTBBNTksIDB4ODBFNEE5MTUsIDB4ODdCMDg2MDEsIDB4OUIwOUU2QUQsIDB4M0IzRUU1OTMsIDB4RTk5MEZENUEsIDB4OUUzNEQ3OTcsIDB4MkNGMEI3RDksIDB4MDIyQjhCNTEsIDB4OTZENUFDM0EsIDB4MDE3REE2N0QsIDB4RDFDRjNFRDYsIDB4N0M3RDJEMjgsIDB4MUY5RjI1Q0YsIDB4QURGMkI4OUIsIDB4NUFENkI0NzIsIDB4NUE4OEY1NEMsIDB4RTAyOUFDNzEsIDB4RTAxOUE1RTYsIDB4NDdCMEFDRkQsIDB4RUQ5M0ZBOUIsIDB4RThEM0M0OEQsIDB4MjgzQjU3Q0MsIDB4RjhENTY2MjksIDB4NzkxMzJFMjgsIDB4Nzg1RjAxOTEsIDB4RUQ3NTYwNTUsIDB4Rjc5NjBFNDQsIDB4RTNEMzVFOEMsIDB4MTUwNTZERDQsIDB4ODhGNDZEQkEsIDB4MDNBMTYxMjUsIDB4MDU2NEYwQkQsIDB4QzNFQjlFMTUsIDB4M0M5MDU3QTIsIDB4OTcyNzFBRUMsIDB4QTkzQTA3MkEsIDB4MUIzRjZEOUIsIDB4MUU2MzIxRjUsIDB4RjU5QzY2RkIsIDB4MjZEQ0YzMTksIDB4NzUzM0Q5MjgsIDB4QjE1NUZERjUsIDB4MDM1NjM0ODIsIDB4OEFCQTNDQkIsIDB4Mjg1MTc3MTEsIDB4QzIwQUQ5RjgsIDB4QUJDQzUxNjcsIDB4Q0NBRDkyNUYsIDB4NERFODE3NTEsIDB4MzgzMERDOEUsIDB4Mzc5RDU4NjIsIDB4OTMyMEY5OTEsIDB4RUE3QTkwQzIsIDB4RkIzRTdCQ0UsIDB4NTEyMUNFNjQsIDB4Nzc0RkJFMzIsIDB4QThCNkUzN0UsIDB4QzMyOTNENDYsIDB4NDhERTUzNjksIDB4NjQxM0U2ODAsIDB4QTJBRTA4MTAsIDB4REQ2REIyMjQsIDB4Njk4NTJERkQsIDB4MDkwNzIxNjYsIDB4QjM5QTQ2MEEsIDB4NjQ0NUMwREQsIDB4NTg2Q0RFQ0YsIDB4MUMyMEM4QUUsIDB4NUJCRUY3REQsIDB4MUI1ODhENDAsIDB4Q0NEMjAxN0YsIDB4NkJCNEUzQkIsIDB4RERBMjZBN0UsIDB4M0E1OUZGNDUsIDB4M0UzNTBBNDQsIDB4QkNCNENERDUsIDB4NzJFQUNFQTgsIDB4RkE2NDg0QkIsIDB4OEQ2NjEyQUUsIDB4QkYzQzZGNDcsIDB4RDI5QkU0NjMsIDB4NTQyRjVEOUUsIDB4QUVDMjc3MUIsIDB4RjY0RTYzNzAsIDB4NzQwRTBEOEQsIDB4RTc1QjEzNTcsIDB4Rjg3MjE2NzEsIDB4QUY1MzdENUQsIDB4NDA0MENCMDgsIDB4NEVCNEUyQ0MsIDB4MzREMjQ2NkEsIDB4MDExNUFGODQsIDB4RTFCMDA0MjgsIDB4OTU5ODNBMUQsIDB4MDZCODlGQjQsIDB4Q0U2RUEwNDgsIDB4NkYzRjNCODIsIDB4MzUyMEFCODIsIDB4MDExQTFENEIsIDB4Mjc3MjI3RjgsIDB4NjExNTYwQjEsIDB4RTc5MzNGREMsIDB4QkIzQTc5MkIsIDB4MzQ0NTI1QkQsIDB4QTA4ODM5RTEsIDB4NTFDRTc5NEIsIDB4MkYzMkM5QjcsIDB4QTAxRkJBQzksIDB4RTAxQ0M4N0UsIDB4QkNDN0QxRjYsIDB4Q0YwMTExQzMsIDB4QTFFOEFBQzcsIDB4MUE5MDg3NDksIDB4RDQ0RkJEOUEsIDB4RDBEQURFQ0IsIDB4RDUwQURBMzgsIDB4MDMzOUMzMkEsIDB4QzY5MTM2NjcsIDB4OERGOTMxN0MsIDB4RTBCMTJCNEYsIDB4Rjc5RTU5QjcsIDB4NDNGNUJCM0EsIDB4RjJENTE5RkYsIDB4MjdEOTQ1OUMsIDB4QkY5NzIyMkMsIDB4MTVFNkZDMkEsIDB4MEY5MUZDNzEsIDB4OUI5NDE1MjUsIDB4RkFFNTkzNjEsIDB4Q0VCNjlDRUIsIDB4QzJBODY0NTksIDB4MTJCQUE4RDEsIDB4QjZDMTA3NUUsIDB4RTMwNTZBMEMsIDB4MTBEMjUwNjUsIDB4Q0IwM0E0NDIsIDB4RTBFQzZFMEUsIDB4MTY5OERCM0IsIDB4NEM5OEEwQkUsIDB4MzI3OEU5NjQsIDB4OUYxRjk1MzIsIDB4RTBEMzkyREYsIDB4RDNBMDM0MkIsIDB4ODk3MUYyMUUsIDB4MUIwQTc0NDEsIDB4NEJBMzM0OEMsIDB4QzVCRTcxMjAsIDB4QzM3NjMyRDgsIDB4REYzNTlGOEQsIDB4OUI5OTJGMkUsIDB4RTYwQjZGNDcsIDB4MEZFM0YxMUQsIDB4RTU0Q0RBNTQsIDB4MUVEQUQ4OTEsIDB4Q0U2Mjc5Q0YsIDB4Q0QzRTdFNkYsIDB4MTYxOEIxNjYsIDB4RkQyQzFEMDUsIDB4ODQ4RkQyQzUsIDB4RjZGQjIyOTksIDB4RjUyM0YzNTcsIDB4QTYzMjc2MjMsIDB4OTNBODM1MzEsIDB4NTZDQ0NEMDIsIDB4QUNGMDgxNjIsIDB4NUE3NUVCQjUsIDB4NkUxNjM2OTcsIDB4ODhEMjczQ0MsIDB4REU5NjYyOTIsIDB4ODFCOTQ5RDAsIDB4NEM1MDkwMUIsIDB4NzFDNjU2MTQsIDB4RTZDNkM3QkQsIDB4MzI3QTE0MEEsIDB4NDVFMUQwMDYsIDB4QzNGMjdCOUEsIDB4QzlBQTUzRkQsIDB4NjJBODBGMDAsIDB4QkIyNUJGRTIsIDB4MzVCREQyRjYsIDB4NzExMjY5MDUsIDB4QjIwNDAyMjIsIDB4QjZDQkNGN0MsIDB4Q0Q3NjlDMkIsIDB4NTMxMTNFQzAsIDB4MTY0MEUzRDMsIDB4MzhBQkJENjAsIDB4MjU0N0FERjAsIDB4QkEzODIwOUMsIDB4Rjc0NkNFNzYsIDB4NzdBRkExQzUsIDB4MjA3NTYwNjAsIDB4ODVDQkZFNEUsIDB4OEFFODhERDgsIDB4N0FBQUY5QjAsIDB4NENGOUFBN0UsIDB4MTk0OEMyNUMsIDB4MDJGQjhBOEMsIDB4MDFDMzZBRTQsIDB4RDZFQkUxRjksIDB4OTBENEY4NjksIDB4QTY1Q0RFQTAsIDB4M0YwOTI1MkQsIDB4QzIwOEU2OUYsIDB4Qjc0RTYxMzIsIDB4Q0U3N0UyNUIsIDB4NTc4RkRGRTMsIDB4M0FDMzcyRTZdXTsKICAgICAgICAgIHZhciBCTE9XRklTSF9DVFggPSB7CiAgICAgICAgICAgIHBib3g6IFtdLAogICAgICAgICAgICBzYm94OiBbXQogICAgICAgICAgfTsKICAgICAgICAgIGZ1bmN0aW9uIEYoY3R4LCB4KSB7CiAgICAgICAgICAgIGxldCBhID0geCA+PiAyNCAmIDB4RkY7CiAgICAgICAgICAgIGxldCBiID0geCA+PiAxNiAmIDB4RkY7CiAgICAgICAgICAgIGxldCBjID0geCA+PiA4ICYgMHhGRjsKICAgICAgICAgICAgbGV0IGQgPSB4ICYgMHhGRjsKICAgICAgICAgICAgbGV0IHkgPSBjdHguc2JveFswXVthXSArIGN0eC5zYm94WzFdW2JdOwogICAgICAgICAgICB5ID0geSBeIGN0eC5zYm94WzJdW2NdOwogICAgICAgICAgICB5ID0geSArIGN0eC5zYm94WzNdW2RdOwogICAgICAgICAgICByZXR1cm4geTsKICAgICAgICAgIH0KICAgICAgICAgIGZ1bmN0aW9uIEJsb3dGaXNoX0VuY3J5cHQoY3R4LCBsZWZ0LCByaWdodCkgewogICAgICAgICAgICBsZXQgWGwgPSBsZWZ0OwogICAgICAgICAgICBsZXQgWHIgPSByaWdodDsKICAgICAgICAgICAgbGV0IHRlbXA7CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgKytpKSB7CiAgICAgICAgICAgICAgWGwgPSBYbCBeIGN0eC5wYm94W2ldOwogICAgICAgICAgICAgIFhyID0gRihjdHgsIFhsKSBeIFhyOwogICAgICAgICAgICAgIHRlbXAgPSBYbDsKICAgICAgICAgICAgICBYbCA9IFhyOwogICAgICAgICAgICAgIFhyID0gdGVtcDsKICAgICAgICAgICAgfQogICAgICAgICAgICB0ZW1wID0gWGw7CiAgICAgICAgICAgIFhsID0gWHI7CiAgICAgICAgICAgIFhyID0gdGVtcDsKICAgICAgICAgICAgWHIgPSBYciBeIGN0eC5wYm94W05dOwogICAgICAgICAgICBYbCA9IFhsIF4gY3R4LnBib3hbTiArIDFdOwogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgIGxlZnQ6IFhsLAogICAgICAgICAgICAgIHJpZ2h0OiBYcgogICAgICAgICAgICB9OwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gQmxvd0Zpc2hfRGVjcnlwdChjdHgsIGxlZnQsIHJpZ2h0KSB7CiAgICAgICAgICAgIGxldCBYbCA9IGxlZnQ7CiAgICAgICAgICAgIGxldCBYciA9IHJpZ2h0OwogICAgICAgICAgICBsZXQgdGVtcDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IE4gKyAxOyBpID4gMTsgLS1pKSB7CiAgICAgICAgICAgICAgWGwgPSBYbCBeIGN0eC5wYm94W2ldOwogICAgICAgICAgICAgIFhyID0gRihjdHgsIFhsKSBeIFhyOwogICAgICAgICAgICAgIHRlbXAgPSBYbDsKICAgICAgICAgICAgICBYbCA9IFhyOwogICAgICAgICAgICAgIFhyID0gdGVtcDsKICAgICAgICAgICAgfQogICAgICAgICAgICB0ZW1wID0gWGw7CiAgICAgICAgICAgIFhsID0gWHI7CiAgICAgICAgICAgIFhyID0gdGVtcDsKICAgICAgICAgICAgWHIgPSBYciBeIGN0eC5wYm94WzFdOwogICAgICAgICAgICBYbCA9IFhsIF4gY3R4LnBib3hbMF07CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgbGVmdDogWGwsCiAgICAgICAgICAgICAgcmlnaHQ6IFhyCiAgICAgICAgICAgIH07CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBJbml0aWFsaXphdGlvbiBjdHgncyBwYm94IGFuZCBzYm94LgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjdHggVGhlIG9iamVjdCBoYXMgcGJveCBhbmQgc2JveC4KICAgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGtleSBBbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAgICAgICAgICAgKiBAcGFyYW0ge2ludH0ga2V5c2l6ZSBUaGUgbGVuZ3RoIG9mIHRoZSBrZXkuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgQmxvd0Zpc2hJbml0KEJMT1dGSVNIX0NUWCwga2V5LCAxMjgvMzIpOwogICAgICAgICAgICovCiAgICAgICAgICBmdW5jdGlvbiBCbG93RmlzaEluaXQoY3R4LCBrZXksIGtleXNpemUpIHsKICAgICAgICAgICAgZm9yIChsZXQgUm93ID0gMDsgUm93IDwgNDsgUm93KyspIHsKICAgICAgICAgICAgICBjdHguc2JveFtSb3ddID0gW107CiAgICAgICAgICAgICAgZm9yIChsZXQgQ29sID0gMDsgQ29sIDwgMjU2OyBDb2wrKykgewogICAgICAgICAgICAgICAgY3R4LnNib3hbUm93XVtDb2xdID0gT1JJR19TW1Jvd11bQ29sXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGV0IGtleUluZGV4ID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IE4gKyAyOyBpbmRleCsrKSB7CiAgICAgICAgICAgICAgY3R4LnBib3hbaW5kZXhdID0gT1JJR19QW2luZGV4XSBeIGtleVtrZXlJbmRleF07CiAgICAgICAgICAgICAga2V5SW5kZXgrKzsKICAgICAgICAgICAgICBpZiAoa2V5SW5kZXggPj0ga2V5c2l6ZSkgewogICAgICAgICAgICAgICAga2V5SW5kZXggPSAwOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgRGF0YTEgPSAwOwogICAgICAgICAgICBsZXQgRGF0YTIgPSAwOwogICAgICAgICAgICBsZXQgcmVzID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBOICsgMjsgaSArPSAyKSB7CiAgICAgICAgICAgICAgcmVzID0gQmxvd0Zpc2hfRW5jcnlwdChjdHgsIERhdGExLCBEYXRhMik7CiAgICAgICAgICAgICAgRGF0YTEgPSByZXMubGVmdDsKICAgICAgICAgICAgICBEYXRhMiA9IHJlcy5yaWdodDsKICAgICAgICAgICAgICBjdHgucGJveFtpXSA9IERhdGExOwogICAgICAgICAgICAgIGN0eC5wYm94W2kgKyAxXSA9IERhdGEyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCAyNTY7IGogKz0gMikgewogICAgICAgICAgICAgICAgcmVzID0gQmxvd0Zpc2hfRW5jcnlwdChjdHgsIERhdGExLCBEYXRhMik7CiAgICAgICAgICAgICAgICBEYXRhMSA9IHJlcy5sZWZ0OwogICAgICAgICAgICAgICAgRGF0YTIgPSByZXMucmlnaHQ7CiAgICAgICAgICAgICAgICBjdHguc2JveFtpXVtqXSA9IERhdGExOwogICAgICAgICAgICAgICAgY3R4LnNib3hbaV1baiArIDFdID0gRGF0YTI7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgfQoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQmxvd2Zpc2ggYmxvY2sgY2lwaGVyIGFsZ29yaXRobS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIEJsb3dmaXNoID0gQ19hbGdvLkJsb3dmaXNoID0gQmxvY2tDaXBoZXIuZXh0ZW5kKHsKICAgICAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTa2lwIHJlc2V0IG9mIG5Sb3VuZHMgaGFzIGJlZW4gc2V0IGJlZm9yZSBhbmQga2V5IGRpZCBub3QgY2hhbmdlCiAgICAgICAgICAgICAgaWYgKHRoaXMuX2tleVByaW9yUmVzZXQgPT09IHRoaXMuX2tleSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGtleSA9IHRoaXMuX2tleVByaW9yUmVzZXQgPSB0aGlzLl9rZXk7CiAgICAgICAgICAgICAgdmFyIGtleVdvcmRzID0ga2V5LndvcmRzOwogICAgICAgICAgICAgIHZhciBrZXlTaXplID0ga2V5LnNpZ0J5dGVzIC8gNDsKCiAgICAgICAgICAgICAgLy9Jbml0aWFsaXphdGlvbiBwYm94IGFuZCBzYm94CiAgICAgICAgICAgICAgQmxvd0Zpc2hJbml0KEJMT1dGSVNIX0NUWCwga2V5V29yZHMsIGtleVNpemUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBlbmNyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICB2YXIgcmVzID0gQmxvd0Zpc2hfRW5jcnlwdChCTE9XRklTSF9DVFgsIE1bb2Zmc2V0XSwgTVtvZmZzZXQgKyAxXSk7CiAgICAgICAgICAgICAgTVtvZmZzZXRdID0gcmVzLmxlZnQ7CiAgICAgICAgICAgICAgTVtvZmZzZXQgKyAxXSA9IHJlcy5yaWdodDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZGVjcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgdmFyIHJlcyA9IEJsb3dGaXNoX0RlY3J5cHQoQkxPV0ZJU0hfQ1RYLCBNW29mZnNldF0sIE1bb2Zmc2V0ICsgMV0pOwogICAgICAgICAgICAgIE1bb2Zmc2V0XSA9IHJlcy5sZWZ0OwogICAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSByZXMucmlnaHQ7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGJsb2NrU2l6ZTogNjQgLyAzMiwKICAgICAgICAgICAga2V5U2l6ZTogMTI4IC8gMzIsCiAgICAgICAgICAgIGl2U2l6ZTogNjQgLyAzMgogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5CbG93ZmlzaC5lbmNyeXB0KG1lc3NhZ2UsIGtleSwgY2ZnKTsKICAgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ICA9IENyeXB0b0pTLkJsb3dmaXNoLmRlY3J5cHQoY2lwaGVydGV4dCwga2V5LCBjZmcpOwogICAgICAgICAgICovCiAgICAgICAgICBDLkJsb3dmaXNoID0gQmxvY2tDaXBoZXIuX2NyZWF0ZUhlbHBlcihCbG93ZmlzaCk7CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMuQmxvd2Zpc2g7CiAgICAgIH0pOwogICAgfSkoYmxvd2Zpc2gkMSk7CiAgICByZXR1cm4gYmxvd2Zpc2gkMS5leHBvcnRzOwogIH0KCiAgdmFyIGNyeXB0b0pzID0gY3J5cHRvSnMkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZENyeXB0b0pzOwogIGZ1bmN0aW9uIHJlcXVpcmVDcnlwdG9KcygpIHsKICAgIGlmIChoYXNSZXF1aXJlZENyeXB0b0pzKSByZXR1cm4gY3J5cHRvSnMkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRDcnlwdG9KcyA9IDE7CiAgICAoZnVuY3Rpb24gKG1vZHVsZSwgZXhwb3J0cyQxKSB7CiAgICAgIChmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHsKICAgICAgICB7CiAgICAgICAgICAvLyBDb21tb25KUwogICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmVDb3JlKCksIHJlcXVpcmVYNjRDb3JlKCksIHJlcXVpcmVMaWJUeXBlZGFycmF5cygpLCByZXF1aXJlRW5jVXRmMTYoKSwgcmVxdWlyZUVuY0Jhc2U2NCgpLCByZXF1aXJlRW5jQmFzZTY0dXJsKCksIHJlcXVpcmVNZDUoKSwgcmVxdWlyZVNoYTEoKSwgcmVxdWlyZVNoYTI1NigpLCByZXF1aXJlU2hhMjI0KCksIHJlcXVpcmVTaGE1MTIoKSwgcmVxdWlyZVNoYTM4NCgpLCByZXF1aXJlU2hhMygpLCByZXF1aXJlUmlwZW1kMTYwKCksIHJlcXVpcmVIbWFjKCksIHJlcXVpcmVQYmtkZjIoKSwgcmVxdWlyZUV2cGtkZigpLCByZXF1aXJlQ2lwaGVyQ29yZSgpLCByZXF1aXJlTW9kZUNmYigpLCByZXF1aXJlTW9kZUN0cigpLCByZXF1aXJlTW9kZUN0ckdsYWRtYW4oKSwgcmVxdWlyZU1vZGVPZmIoKSwgcmVxdWlyZU1vZGVFY2IoKSwgcmVxdWlyZVBhZEFuc2l4OTIzKCksIHJlcXVpcmVQYWRJc28xMDEyNigpLCByZXF1aXJlUGFkSXNvOTc5NzEoKSwgcmVxdWlyZVBhZFplcm9wYWRkaW5nKCksIHJlcXVpcmVQYWROb3BhZGRpbmcoKSwgcmVxdWlyZUZvcm1hdEhleCgpLCByZXF1aXJlQWVzKCksIHJlcXVpcmVUcmlwbGVkZXMoKSwgcmVxdWlyZVJjNCgpLCByZXF1aXJlUmFiYml0KCksIHJlcXVpcmVSYWJiaXRMZWdhY3koKSwgcmVxdWlyZUJsb3dmaXNoKCkpOwogICAgICAgIH0KICAgICAgfSkoY3J5cHRvSnMsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIHJldHVybiBDcnlwdG9KUzsKICAgICAgfSk7CiAgICB9KShjcnlwdG9KcyQxKTsKICAgIHJldHVybiBjcnlwdG9KcyQxLmV4cG9ydHM7CiAgfQoKICByZXF1aXJlQ3J5cHRvSnMoKTsKCiAgY29uc3QgY2xvbmVEZWVwID0gKHRhcmdldCkgPT4gewogICAgICBpZiAoaXNBcnJheSh0YXJnZXQpKSB7CiAgICAgICAgICByZXR1cm4gdGFyZ2V0LnJlZHVjZSgobGlzdCwgaXRlbSkgPT4gewogICAgICAgICAgICAgIGxpc3QucHVzaChjbG9uZURlZXAoaXRlbSkpOwogICAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgICAgfSwgW10pOwogICAgICB9CiAgICAgIGlmIChpc09iamVjdCh0YXJnZXQpKSB7CiAgICAgICAgICBjb25zdCBvYmogPSB7fTsKICAgICAgICAgIE9iamVjdC5rZXlzKHRhcmdldCkuZm9yRWFjaCgoa2V5KSA9PiB7CiAgICAgICAgICAgICAgb2JqW2tleV0gPSBjbG9uZURlZXAodGFyZ2V0W2tleV0pOwogICAgICAgICAgfSk7CiAgICAgICAgICByZXR1cm4gb2JqOwogICAgICB9CiAgICAgIHJldHVybiB0YXJnZXQ7CiAgfTsKCiAgY29uc3QgZGVmYXVsdENvbmZpZyA9IHsKICAgICAgZGV2aWNlOiB7CiAgICAgICAgICBzdGF0dXM6IHsKICAgICAgICAgICAgICAwOiAn56a757q/JywKICAgICAgICAgICAgICAxOiAn5Zyo57q/JywKICAgICAgICAgICAgICAyOiAn55uR5o6n5LitJywKICAgICAgICAgICAgICAzOiAn6YCa6K+d5LitJywKICAgICAgICAgICAgICA0OiAn5b2V5YOP5LitJywKICAgICAgICAgICAgICA1OiAn5b2V6Z+z5LitJywKICAgICAgICAgICAgICA2OiAn5bm/5pKt5LitJywKICAgICAgICAgICAgICA3OiAnU09TJywKICAgICAgICAgICAgICA4OiAn6Z+z6aKR5LitJywKICAgICAgICAgIH0sCiAgICAgICAgICB1c2VJY29uOiB1bmRlZmluZWQKICAgICAgfSwKICAgICAgdG9vbHRpcDogewogICAgICAgICAgc3R5bGU6IHsKICAgICAgICAgICAgICBtYXhXaWR0aDogJzYwMHB4JywKICAgICAgICAgICAgICBjb2xvcjogJyNmZmYnLAogICAgICAgICAgICAgIGZvbnRTaXplOiAnMTJweCcsCiAgICAgICAgICAgICAgZm9udFdlaWdodDogJzQwMCcsCiAgICAgICAgICAgICAgbGluZUhlaWdodDogJzIwcHgnLAogICAgICAgICAgICAgIGJhY2tncm91bmQ6ICcjMUMzMjRCJywKICAgICAgICAgICAgICBib3JkZXJXaWR0aDogJzJweCcsCiAgICAgICAgICAgICAgYm9yZGVyQ29sb3I6ICcjMzc1Qzg2JywKICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc0cHgnLAogICAgICAgICAgICAgIHBhZGRpbmc6ICc3cHggOXB4JywKICAgICAgICAgICAgICB6SW5kZXg6IDMyMDAKICAgICAgICAgIH0sCiAgICAgICAgICBwcm9wczogewogICAgICAgICAgICAgIC8vIOWBj+enu+i3neemuwogICAgICAgICAgICAgIG9mZnNldDogMCwKICAgICAgICAgIH0KICAgICAgfSwKICAgICAgdHJlZTogewogICAgICAgICAgaXRlbUhlaWdodDogMzAsCiAgICAgICAgICBpdGVtR2FwOiAxMCwKICAgICAgICAgIGNvbG9yOiAnI2ZmZicsCiAgICAgICAgICBwbGFjZWhvbGRlckNvbG9yOiAnIzkwOTM5OScsCiAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLAogICAgICAgICAgYmdDb2xvcjogJycsCiAgICAgICAgICBub2RlQmdDb2xvcjogJyMxYzMzNGEnLAogICAgICAgICAgY2hhbm5lbEJnQ29sb3I6ICcjMTAyNjNCJywKICAgICAgICAgIGVtcHR5VGV4dDogJ+aaguaXoOaVsOaNricsCiAgICAgICAgICBidWZmZXJTaXplOiA1MCwKICAgICAgICAgIGV4cGFuZE9uQ2xpY2tOb2RlOiB0cnVlLAogICAgICAgICAgY2hlY2tPbkNsaWNrTm9kZTogZmFsc2UsCiAgICAgICAgICBjaGVja09uQ2xpY2tMZWFmOiB0cnVlLAogICAgICAgICAgY2hlY2tPbkRibGNsaWNrUGFyZW50Tm9kZTogdHJ1ZSwKICAgICAgICAgIGluZGVudDogMTYsCiAgICAgIH0KICB9OwoKICAvLyDorr7lpIfphY3nva4KICBjbG9uZURlZXAoZGVmYXVsdENvbmZpZy5kZXZpY2UpOwogIC8vIHRvb2x0aXDphY3nva4KICBjbG9uZURlZXAoZGVmYXVsdENvbmZpZy50b29sdGlwKTsKICAvLyB2aXJ0dWFsVHJlZemFjee9rgogIGNsb25lRGVlcChkZWZhdWx0Q29uZmlnLnRyZWUpOwoKICAvLyDkuJrliqHnsbvlnosoY29uZmlnLmJ1c2luZXNzKSBkZXZpY2Ut6K6+5aSHIGNoYW5uZWwt6YCa6YGT6K6+5aSHIGdyb3VwRGV2aWNlLee+pOe7hOiuvuWkhyBncm91cC3nvqTnu4QgdXNlci3nlKjmiLcgY3Mt6YeH6ZuG56uZCiAgdmFyIEJ1c2luZXNzOwogIChmdW5jdGlvbiAoQnVzaW5lc3MpIHsKICAgICAgQnVzaW5lc3NbIkRFVklDRSJdID0gImRldmljZSI7CiAgICAgIEJ1c2luZXNzWyJDSEFOTkVMIl0gPSAiY2hhbm5lbCI7CiAgICAgIEJ1c2luZXNzWyJHUk9VUF9ERVZJQ0UiXSA9ICJncm91cERldmljZSI7CiAgICAgIEJ1c2luZXNzWyJHUk9VUCJdID0gImdyb3VwIjsKICAgICAgQnVzaW5lc3NbIlVTRVIiXSA9ICJ1c2VyIjsKICAgICAgQnVzaW5lc3NbIlRFQU1fVVNFUiJdID0gInRlYW1Vc2VyIjsKICAgICAgQnVzaW5lc3NbIkNTIl0gPSAiY3MiOwogICAgICBCdXNpbmVzc1siUExBTl9HUk9VUF9ERVZJQ0UiXSA9ICJwbGFuR3JvdXBEZXZpY2UiOwogIH0pKEJ1c2luZXNzIHx8IChCdXNpbmVzcyA9IHt9KSk7CiAgLy8g6K6+5aSH54q25oCBKGRhdGEuZGV2aWNlU3RhdHVzKSAwLeemu+e6vyAxLeWcqOe6vyAyLeebkeaOp+S4rSAzLemAmuivneS4rSA0LeW9leWDj+S4rSA1LeW9lemfs+S4rSA2LeW5v+aSreS4rSA3LVNPUyA4Lemfs+mikeS4rQogIHZhciBEZXZpY2VTdGF0dXM7CiAgKGZ1bmN0aW9uIChEZXZpY2VTdGF0dXMpIHsKICAgICAgRGV2aWNlU3RhdHVzW0RldmljZVN0YXR1c1siT0ZGX0xJTkUiXSA9IDBdID0gIk9GRl9MSU5FIjsKICAgICAgRGV2aWNlU3RhdHVzW0RldmljZVN0YXR1c1siT05fTElORSJdID0gMV0gPSAiT05fTElORSI7CiAgICAgIERldmljZVN0YXR1c1tEZXZpY2VTdGF0dXNbIkJFX01PTklUT1IiXSA9IDJdID0gIkJFX01PTklUT1IiOwogICAgICBEZXZpY2VTdGF0dXNbRGV2aWNlU3RhdHVzWyJJTl9DQUxMIl0gPSAzXSA9ICJJTl9DQUxMIjsKICAgICAgRGV2aWNlU3RhdHVzW0RldmljZVN0YXR1c1siSU5fVklERU9fUkVDT1JEIl0gPSA0XSA9ICJJTl9WSURFT19SRUNPUkQiOwogICAgICBEZXZpY2VTdGF0dXNbRGV2aWNlU3RhdHVzWyJJTl9BVURJT19SRUNPUkQiXSA9IDVdID0gIklOX0FVRElPX1JFQ09SRCI7CiAgICAgIERldmljZVN0YXR1c1tEZXZpY2VTdGF0dXNbIklOX0JST0FEQ0FTRSJdID0gNl0gPSAiSU5fQlJPQURDQVNFIjsKICAgICAgRGV2aWNlU3RhdHVzW0RldmljZVN0YXR1c1siU09TIl0gPSA3XSA9ICJTT1MiOwogICAgICBEZXZpY2VTdGF0dXNbRGV2aWNlU3RhdHVzWyJJTlRFUkNPTV9DQUxMIl0gPSA4XSA9ICJJTlRFUkNPTV9DQUxMIjsKICB9KShEZXZpY2VTdGF0dXMgfHwgKERldmljZVN0YXR1cyA9IHt9KSk7CiAgLy8g5Lia5Yqh5pWw5o2u57G75Z6LKGRhdGEuZGF0YVR5cGUpIDEt6YOo6ZeoIDMt6K6+5aSHIDQt576k57uEIDUt55So5oi3IDYt6ICD5YukIDct5rC05rqQ54K5IDgt6YeH6ZuG56uZIDkt6K6+5aSH6YCa6YGTIDEwLemYn+S8jSAxMS3pooTmoYjliIbnu4QKICB2YXIgRGF0YVR5cGU7CiAgKGZ1bmN0aW9uIChEYXRhVHlwZSkgewogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiVU5LTk9XXzEiXSA9IDBdID0gIlVOS05PV18xIjsKICAgICAgRGF0YVR5cGVbRGF0YVR5cGVbIkRFUFQiXSA9IDFdID0gIkRFUFQiOwogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiVU5LTk9XXzIiXSA9IDJdID0gIlVOS05PV18yIjsKICAgICAgRGF0YVR5cGVbRGF0YVR5cGVbIkRFVklDRSJdID0gM10gPSAiREVWSUNFIjsKICAgICAgRGF0YVR5cGVbRGF0YVR5cGVbIkdST1VQIl0gPSA0XSA9ICJHUk9VUCI7CiAgICAgIERhdGFUeXBlW0RhdGFUeXBlWyJVU0VSIl0gPSA1XSA9ICJVU0VSIjsKICAgICAgRGF0YVR5cGVbRGF0YVR5cGVbIkFUVEVOREFOQ0UiXSA9IDZdID0gIkFUVEVOREFOQ0UiOwogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiV0FURVJfU09VUkNFIl0gPSA3XSA9ICJXQVRFUl9TT1VSQ0UiOwogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiQ1MiXSA9IDhdID0gIkNTIjsKICAgICAgRGF0YVR5cGVbRGF0YVR5cGVbIkNIQU5ORUwiXSA9IDldID0gIkNIQU5ORUwiOwogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiVEVBTSJdID0gMTBdID0gIlRFQU0iOwogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiUExBTl9HUk9VUCJdID0gMTFdID0gIlBMQU5fR1JPVVAiOwogIH0pKERhdGFUeXBlIHx8IChEYXRhVHlwZSA9IHt9KSk7CgogIC8qKiDnlJ/miJDlpITnkIblh73mlbAgKi8KICBjb25zdCB1c2VIYW5kbGVGdW4gPSAoY29uZmlnKSA9PiB7CiAgICAgIGNvbnN0IHsgYnVzaW5lc3MgfSA9IGNvbmZpZzsKICAgICAgY29uc3QgcHJvcHMgPSB7IC4uLmNvbmZpZy5wcm9wcyB9OwogICAgICBsZXQgeyBjb3VudEZpbHRlciwgdG90YWxGaWx0ZXIgfSA9IHByb3BzOwogICAgICAvKiog6I635Y+Wa2V55YC8ICovCiAgICAgIGZ1bmN0aW9uIGdldEtleShub2RlLCBpc0J1c2luZXNzID0gZmFsc2UpIHsKICAgICAgICAgIGlmICghbm9kZSkKICAgICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgICBpZiAoYnVzaW5lc3MgJiYgaXNCdXNpbmVzcykgewogICAgICAgICAgICAgIHN3aXRjaCAobm9kZS5kYXRhVHlwZSkgewogICAgICAgICAgICAgICAgICBjYXNlIERhdGFUeXBlLkRFUFQ6IC8vIOmDqOmXqAogICAgICAgICAgICAgICAgICBjYXNlIERhdGFUeXBlLkdST1VQOiAvLyDnvqTnu4QKICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhVHlwZS5URUFNOiAvLyDpmJ/kvI0KICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhVHlwZS5VU0VSOiAvLyDnlKjmiLcKICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhVHlwZS5DUzogLy8g6YeH6ZuG56uZCiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5pZDsKICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhVHlwZS5ERVZJQ0U6IC8vIOiuvuWkhwogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUuZGV2aWNlSWQ7CiAgICAgICAgICAgICAgICAgIGNhc2UgRGF0YVR5cGUuQ0hBTk5FTDogLy8g6K6+5aSH6YCa6YGTCiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5jaGFubmVsSWQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIG5vZGVbcHJvcHMudmFsdWVdOwogICAgICB9CiAgICAgIC8qKiDojrflj5ZsYWJlbOWAvCAqLwogICAgICBmdW5jdGlvbiBnZXRMYWJlbChub2RlKSB7CiAgICAgICAgICBpZiAoIW5vZGUpCiAgICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgcmV0dXJuIG5vZGVbcHJvcHMubGFiZWxdOwogICAgICB9CiAgICAgIC8qKiDojrflj5ZjaGlsZHJlbuWAvCAqLwogICAgICBmdW5jdGlvbiBnZXRDaGlsZHJlbihub2RlKSB7CiAgICAgICAgICBpZiAoIW5vZGUpCiAgICAgICAgICAgICAgcmV0dXJuIFtdOwogICAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBub2RlW3Byb3BzLmNoaWxkcmVuXTsKICAgICAgICAgIHJldHVybiBjaGlsZHJlbiA/IFsuLi5jaGlsZHJlbl0gOiBbXTsKICAgICAgfQogICAgICAvKiog6I635Y+WY291bnTlgLwgKi8KICAgICAgZnVuY3Rpb24gZ2V0Q291bnQobm9kZSkgewogICAgICAgICAgaWYgKCFub2RlKQogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIHJldHVybiBub2RlW3Byb3BzLmNvdW50XTsKICAgICAgfQogICAgICAvKiog6I635Y+WdG90YWzlgLwgKi8KICAgICAgZnVuY3Rpb24gZ2V0VG90YWwobm9kZSkgewogICAgICAgICAgaWYgKCFub2RlKQogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIHJldHVybiBub2RlW3Byb3BzLnRvdGFsXTsKICAgICAgfQogICAgICBpZiAoYnVzaW5lc3MgJiYgW0J1c2luZXNzLkRFVklDRSwgQnVzaW5lc3MuQ0hBTk5FTCwgQnVzaW5lc3MuR1JPVVBfREVWSUNFLCBCdXNpbmVzcy5QTEFOX0dST1VQX0RFVklDRV0uaW5jbHVkZXMoYnVzaW5lc3MpKSB7CiAgICAgICAgICBjb3VudEZpbHRlciA9IChkYXRhKSA9PiB7CiAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YVR5cGUgPT09IERhdGFUeXBlLkRFVklDRSAmJiBkYXRhLm9ubGluZVN0YXRlID09PSAxOwogICAgICAgICAgfTsKICAgICAgICAgIHRvdGFsRmlsdGVyID0gKGRhdGEpID0+IHsKICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuREVWSUNFOwogICAgICAgICAgfTsKICAgICAgfQogICAgICBlbHNlIGlmIChidXNpbmVzcyAmJiBbQnVzaW5lc3MuVVNFUiwgQnVzaW5lc3MuVEVBTV9VU0VSXS5pbmNsdWRlcyhidXNpbmVzcykpIHsKICAgICAgICAgIGNvdW50RmlsdGVyID0gdG90YWxGaWx0ZXIgPSAoZGF0YSkgPT4gewogICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGFUeXBlID09PSBEYXRhVHlwZS5VU0VSOwogICAgICAgICAgfTsKICAgICAgfQogICAgICBlbHNlIGlmIChidXNpbmVzcyA9PT0gQnVzaW5lc3MuQ1MpIHsKICAgICAgICAgIGNvdW50RmlsdGVyID0gdG90YWxGaWx0ZXIgPSAoZGF0YSkgPT4gewogICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGFUeXBlID09PSBEYXRhVHlwZS5DUzsKICAgICAgICAgIH07CiAgICAgIH0KICAgICAgcmV0dXJuIHsKICAgICAgICAgIGdldEtleSwKICAgICAgICAgIGdldExhYmVsLAogICAgICAgICAgZ2V0Q2hpbGRyZW4sCiAgICAgICAgICBnZXRDb3VudCwKICAgICAgICAgIGdldFRvdGFsLAogICAgICAgICAgY291bnRGaWx0ZXIsCiAgICAgICAgICB0b3RhbEZpbHRlciwKICAgICAgICAgIGdldE5vZGVEYXRhLAogICAgICAgICAgLy8g6K6+572u6K6+5aSH54q25oCBCiAgICAgICAgICBzZXREZXZpY2VTdGF0dXM6IChkYXRhKSA9PiB7CiAgICAgICAgICAgICAgLy8g6YCa6YGT54q25oCBCiAgICAgICAgICAgICAgaWYgKGRhdGEuZGF0YVR5cGUgPT09IERhdGFUeXBlLkNIQU5ORUwpIHsKICAgICAgICAgICAgICAgICAgaWYgKGRhdGEub25saW5lU3RhdGUgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgIC8vIOebkeaOp+S4rQogICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEuYmVNb25pdG9yID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERldmljZVN0YXR1cy5CRV9NT05JVE9SOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgLy8g5Zyo57q/CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLk9OX0xJTkU7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g56a757q/CiAgICAgICAgICAgICAgICAgIHJldHVybiBEZXZpY2VTdGF0dXMuT0ZGX0xJTkU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8vIOiuvuWkh+eKtuaAgQogICAgICAgICAgICAgIGlmIChkYXRhLm9ubGluZVN0YXRlID09PSAxKSB7CiAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmludGVyY29tR3JvdXBUZW0gPT09IDEgfHwgZGF0YS5pbnRlcmNvbUNhbGwgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgIC8vIOmfs+mikeS4rQogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERldmljZVN0YXR1cy5JTlRFUkNPTV9DQUxMOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOebkeaOp+S4rQogICAgICAgICAgICAgICAgICBpZiAoZGF0YS5tb25pdG9yID09PSAxIHx8IGRhdGEuYmVNb25pdG9yID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLkJFX01PTklUT1I7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6YCa6K+d5LitCiAgICAgICAgICAgICAgICAgIGlmIChkYXRhLnZpZGVvQ2FsbCA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERldmljZVN0YXR1cy5JTl9DQUxMOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOW9leWDj+S4rQogICAgICAgICAgICAgICAgICBpZiAoZGF0YS52aWRlb1JlY29yZGluZyA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERldmljZVN0YXR1cy5JTl9WSURFT19SRUNPUkQ7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g5b2V6Z+z5LitCiAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmF1ZGlvUmVjb3JkaW5nID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLklOX0FVRElPX1JFQ09SRDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDlub/mkq3kuK0KICAgICAgICAgICAgICAgICAgaWYgKGRhdGEuYnJvYWRjYXN0ID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLklOX0JST0FEQ0FTRTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyBTT1MKICAgICAgICAgICAgICAgICAgaWYgKGRhdGEuc29zID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLlNPUzsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDlnKjnur8KICAgICAgICAgICAgICAgICAgcmV0dXJuIERldmljZVN0YXR1cy5PTl9MSU5FOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvLyDnprvnur8KICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLk9GRl9MSU5FOwogICAgICAgICAgfQogICAgICB9OwogIH07CiAgLyoqIOiOt+WPluiKgueCueaVsOaNriAqLwogIGNvbnN0IGdldE5vZGVEYXRhID0gKG5vZGUpID0+IHsKICAgICAgaWYgKG5vZGUuZGF0YS5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuQ0hBTk5FTCkgewogICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAuLi5ub2RlLnBhcmVudC5kYXRhLAogICAgICAgICAgICAgIC4uLm5vZGUuZGF0YQogICAgICAgICAgfTsKICAgICAgfQogICAgICByZXR1cm4gbm9kZS5kYXRhOwogIH07CgogIC8vIOWkhOeQhmZpbHRlckNvbmZpZwogIGZ1bmN0aW9uIGhhbmRsZUZpbHRlckNvbmZpZyhmaWx0ZXJDb25maWcpIHsKICAgICAgcmV0dXJuIChmaWx0ZXJDb25maWcgfHwgW10pLmZpbHRlcigoaXRlbSkgPT4gewogICAgICAgICAgcmV0dXJuIChpc1N0cmluZyhpdGVtLnByb3ApICYmCiAgICAgICAgICAgICAgKGlzU3RyaW5nKGl0ZW0udmFsdWUpIHx8CiAgICAgICAgICAgICAgICAgIGlzTnVtYmVyKGl0ZW0udmFsdWUpIHx8CiAgICAgICAgICAgICAgICAgIChpc0FycmF5KGl0ZW0udmFsdWUpICYmIGl0ZW0uY29uZGl0aW9uID09PSAnYmV0d2VlbicpKSAmJgogICAgICAgICAgICAgIC9eKGVxfG5lfGlufG5vdElufGJldHdlZW58Z3R8bHR8Z2V8bGUpJC8udGVzdChpdGVtLmNvbmRpdGlvbikpOwogICAgICB9KTsKICB9CiAgLy8g5qCh6aqMZmlsdGVyQ29uZmlnCiAgZnVuY3Rpb24gdXNlRmlsdGVyQ29uZmlnKGRhdGEsIGZpbHRlckxpc3QpIHsKICAgICAgaWYgKCFmaWx0ZXJMaXN0IHx8ICFmaWx0ZXJMaXN0Lmxlbmd0aCkKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICByZXR1cm4gZmlsdGVyTGlzdC5ldmVyeSgoeyBwcm9wLCB2YWx1ZSwgY29uZGl0aW9uIH0pID0+IHsKICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGRhdGFbcHJvcF07CiAgICAgICAgICBzd2l0Y2ggKGNvbmRpdGlvbikgewogICAgICAgICAgICAgIGNhc2UgJ2VxJzoKICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldCA9PT0gdmFsdWU7CiAgICAgICAgICAgICAgY2FzZSAnbmUnOgogICAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0ICE9PSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgewogICAgICAgICAgICAgIGlmIChjb25kaXRpb24gPT09ICdiZXR3ZWVuJykgewogICAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoCiAgICAgICAgICAgICAgICAgICAgICA/IHRhcmdldCA+PSB2YWx1ZVswXSAmJiB0YXJnZXQgPD0gdmFsdWVbMV0KICAgICAgICAgICAgICAgICAgICAgIDogZmFsc2U7CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgaWYgKGlzTnVtYmVyKHRhcmdldCkpIHsKICAgICAgICAgICAgICBpZiAoIWlzTnVtYmVyKHZhbHVlKSkKICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgIHN3aXRjaCAoY29uZGl0aW9uKSB7CiAgICAgICAgICAgICAgICAgIGNhc2UgJ2d0JzoKICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXQgPiB2YWx1ZTsKICAgICAgICAgICAgICAgICAgY2FzZSAnbHQnOgogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldCA8IHZhbHVlOwogICAgICAgICAgICAgICAgICBjYXNlICdnZSc6CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0ID49IHZhbHVlOwogICAgICAgICAgICAgICAgICBjYXNlICdsZSc6CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0IDw9IHZhbHVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKHRhcmdldCkpIHsKICAgICAgICAgICAgICBjb25zdCBpc0luID0gdGFyZ2V0LmluY2x1ZGVzKGAke3ZhbHVlfWApOwogICAgICAgICAgICAgIHN3aXRjaCAoY29uZGl0aW9uKSB7CiAgICAgICAgICAgICAgICAgIGNhc2UgJ2luJzoKICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpc0luOwogICAgICAgICAgICAgICAgICBjYXNlICdub3RJbic6CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIWlzSW47CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9KTsKICB9CgogIC8vIOiuvuWkh+agkee7k+aehAogIGZ1bmN0aW9uIGdlbmVyYXRlRGV2aWNlVHJlZShkYXRhLCBjb25maWcpIHsKICAgICAgY29uc3QgeyBleHBhbmRlZEtleVNldCB9ID0gY29uZmlnOwogICAgICBjb25zdCB7IHNvcnRCeVN0YXR1cywgc2hvd09ubGluZVN0YXRlLCBjbGVhckVtcHR5QnVzaW5lc3MgfSA9IGNvbmZpZy5idXNpbmVzc0NvbmZpZzsKICAgICAgY29uc3QgeyBnZXRLZXksIGdldExhYmVsLCBnZXRDaGlsZHJlbiwgY291bnRGaWx0ZXIsIHRvdGFsRmlsdGVyLCBzZXREZXZpY2VTdGF0dXMgfSA9IHVzZUhhbmRsZUZ1bihjb25maWcpOwogICAgICBjb25zdCBmaWx0ZXJMaXN0ID0gaGFuZGxlRmlsdGVyQ29uZmlnKGNvbmZpZy5idXNpbmVzc0NvbmZpZz8uZmlsdGVyQ29uZmlnKTsKICAgICAgLyoqIOiuvuWkh+agkSAqLwogICAgICBmdW5jdGlvbiBjcmVhdGVEZXZpY2VUcmVlKGRhdGEpIHsKICAgICAgICAgIGxldCBtYXhMZXZlbCA9IDE7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZU1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IGxldmVsVHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBkZXZpY2VNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBoaWRkZW5Ob2RlS2V5U2V0ID0gbmV3IFNldCgpOwogICAgICAgICAgY29uc3QgdHJhdmVyc2UgPSAobm9kZXMsIGxldmVsID0gMSwgcGFyZW50ID0gdW5kZWZpbmVkKSA9PiB7CiAgICAgICAgICAgICAgY29uc3Qgc2libGluZ3MgPSBbXTsKICAgICAgICAgICAgICBsZXQgY291bnQgPSAwOwogICAgICAgICAgICAgIGxldCB0b3RhbCA9IDA7CiAgICAgICAgICAgICAgZm9yIChsZXQgcmF3Tm9kZSBvZiBub2RlcykgewogICAgICAgICAgICAgICAgICAvLyDkuJrliqHpgLvovpEKICAgICAgICAgICAgICAgICAgbGV0IGNoaWxkcmVuID0gZ2V0Q2hpbGRyZW4ocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlICE9PSAzKSB7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZXZpY2VMaXN0ID0gW1tdLCBbXV07CiAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuID8gY2hpbGRyZW4gOiBbXTsKICAgICAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRldmljZUxpc3QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlLmRldmljZUxpc3QuZm9yRWFjaCgodikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkICsgJy0nICsgdi5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiB2LmRldk5hbWUgfHwgdi5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiAzLCAvLyDku6Pooajorr7lpIcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZVN0YXR1czogc2V0RGV2aWNlU3RhdHVzKHYpIC8vIOiuvuWkh+eKtuaAgQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlRmlsdGVyQ29uZmlnKHRhcmdldCwgZmlsdGVyTGlzdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuZGV2aWNlU3RhdHVzID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlTGlzdFtzb3J0QnlTdGF0dXMgPyAxIDogMF0ucHVzaCh0YXJnZXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaG93T25saW5lU3RhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldC5hZGQoZ2V0S2V5KHRhcmdldCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZUxpc3RbMF0ucHVzaCh0YXJnZXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBbLi4uY2hpbGRyZW4sIC4uLmRldmljZUxpc3RbMF0sIC4uLmRldmljZUxpc3RbMV1dOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5yYXdOb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogMSwgLy8g6YOo6ZeoCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHJhd05vZGUub3JnTmFtZSB8fCByYXdOb2RlLmNvbXBhbnlOYW1lCiAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieiuvuWkh+eahOmDqOmXqOWSjOe+pOe7hCDmraXpqqTkuIAKICAgICAgICAgICAgICAgICAgaWYgKGNsZWFyRW1wdHlCdXNpbmVzcykgewogICAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZHJlbiB8fCBjaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgcmF3Tm9kZS5kYXRhVHlwZSAhPT0gMykgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOmAmueUqOmAu+i+kQogICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGdldEtleShyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsLAogICAgICAgICAgICAgICAgICAgICAga2V5OiB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHJhd05vZGUKICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgbm9kZS5sYWJlbCA9IGdldExhYmVsKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICBub2RlLnBhcmVudCA9IHBhcmVudDsKICAgICAgICAgICAgICAgICAgbm9kZS5pc0xlYWYgPSAhY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwOwogICAgICAgICAgICAgICAgICBub2RlLmV4cGFuZGVkID0gZXhwYW5kZWRLZXlTZXQuaGFzKHZhbHVlKTsKICAgICAgICAgICAgICAgICAgLy8g6ZqQ6JeP5rKh5pyJ5Zyo57q/6K6+5aSH55qE6YOo6Zeo5ZKM576k57uECiAgICAgICAgICAgICAgICAgIGlmIChzaG93T25saW5lU3RhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmIHJhd05vZGUuZGF0YVR5cGUgIT09IDMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChub2RlLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBsaXN0LCBjb3VudDogY2hpbGRDb3VudCwgdG90YWw6IGNoaWxkVG90YWwgfSA9IHRyYXZlcnNlKGNoaWxkcmVuLCBsZXZlbCArIDEsIG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgLy8g6L+H5ruk5rKh5pyJ55So5oi355qE6YOo6ZeoIOatpemqpOS6jAogICAgICAgICAgICAgICAgICAgICAgaWYgKCFzaG93T25saW5lU3RhdGUgJiYgY2xlYXJFbXB0eUJ1c2luZXNzICYmIGNoaWxkVG90YWwgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4gPSBsaXN0OwogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jb3VudCA9IGNoaWxkQ291bnQgOwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IGNoaWxkVG90YWwgOwogICAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gY2hpbGRDb3VudDsKICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IGNoaWxkVG90YWw7CiAgICAgICAgICAgICAgICAgICAgICAvLyDku4XmmL7npLrlnKjnur/orr7lpIfml7bvvIzpmpDol4/msqHmnInlnKjnur/orr7lpIfnmoTpg6jpl6jlkoznvqTnu4QKICAgICAgICAgICAgICAgICAgICAgIGlmIChzaG93T25saW5lU3RhdGUgJiYgIWNoaWxkQ291bnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChub2RlLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gMDsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUudG90YWwgPSAwOwogICAgICAgICAgICAgICAgICAgICAgLy8g57uf6K6hCiAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNob3dPbmxpbmVTdGF0ZSB8fCAhaGlkZGVuTm9kZUtleVNldC5oYXMobm9kZS5rZXkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjb3VudEZpbHRlcihyYXdOb2RlKSA/IDEgOiAwOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRvdGFsRmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIHNpYmxpbmdzLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIHRyZWVOb2RlTWFwLnNldCh2YWx1ZSwgbm9kZSk7CiAgICAgICAgICAgICAgICAgIGlmICghbGV2ZWxUcmVlTm9kZU1hcC5oYXMobGV2ZWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLnNldChsZXZlbCwgW10pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGlmIChsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuZ2V0KGxldmVsKS5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOiuvuWkhwogICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kYXRhVHlwZSA9PT0gMykgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBkZXZpY2VJZCB9ID0gbm9kZS5kYXRhOwogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV2aWNlSW5mbyA9IGRldmljZU1hcC5nZXQoZGV2aWNlSWQpIHx8IFtdOwogICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSW5mby5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgZGV2aWNlTWFwLnNldChkZXZpY2VJZCwgZGV2aWNlSW5mbyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKGxldmVsID4gbWF4TGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgbWF4TGV2ZWwgPSBsZXZlbDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHsgbGlzdDogc2libGluZ3MsIGNvdW50LCB0b3RhbCB9OwogICAgICAgICAgfTsKICAgICAgICAgIGNvbnN0IHsgbGlzdCB9ID0gdHJhdmVyc2UoZGF0YSB8fCBbXSk7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZXMgPSBsaXN0OwogICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICB0cmVlTm9kZU1hcCwKICAgICAgICAgICAgICBkZXZpY2VNYXAsCiAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcCwKICAgICAgICAgICAgICBtYXhMZXZlbCwKICAgICAgICAgICAgICB0cmVlTm9kZXMsCiAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldAogICAgICAgICAgfTsKICAgICAgfQogICAgICByZXR1cm4gY3JlYXRlRGV2aWNlVHJlZShkYXRhKTsKICB9CiAgLy8g6YCa6YGT6K6+5aSH5qCR57uT5p6ECiAgZnVuY3Rpb24gZ2VuZXJhdGVDaGFubmVsRGV2aWNlVHJlZShkYXRhLCBjb25maWcpIHsKICAgICAgY29uc3QgeyBleHBhbmRlZEtleVNldCB9ID0gY29uZmlnOwogICAgICBjb25zdCB7IHNvcnRCeVN0YXR1cywgc2hvd09ubGluZVN0YXRlLCBjbGVhckVtcHR5QnVzaW5lc3MgfSA9IGNvbmZpZy5idXNpbmVzc0NvbmZpZzsKICAgICAgY29uc3QgeyBnZXRLZXksIGdldExhYmVsLCBnZXRDaGlsZHJlbiwgY291bnRGaWx0ZXIsIHRvdGFsRmlsdGVyLCBzZXREZXZpY2VTdGF0dXMgfSA9IHVzZUhhbmRsZUZ1bihjb25maWcpOwogICAgICBjb25zdCBmaWx0ZXJMaXN0ID0gaGFuZGxlRmlsdGVyQ29uZmlnKGNvbmZpZy5idXNpbmVzc0NvbmZpZz8uZmlsdGVyQ29uZmlnKTsKICAgICAgLyoqIOiuvuWkh+agkSAqLwogICAgICBmdW5jdGlvbiBjcmVhdGVEZXZpY2VUcmVlKGRhdGEpIHsKICAgICAgICAgIGxldCBtYXhMZXZlbCA9IDE7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZU1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IGxldmVsVHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBkZXZpY2VNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBjaGFubmVsTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgaGlkZGVuTm9kZUtleVNldCA9IG5ldyBTZXQoKTsKICAgICAgICAgIGNvbnN0IHRyYXZlcnNlID0gKG5vZGVzLCBsZXZlbCA9IDEsIHBhcmVudCA9IHVuZGVmaW5lZCkgPT4gewogICAgICAgICAgICAgIGNvbnN0IHNpYmxpbmdzID0gW107CiAgICAgICAgICAgICAgbGV0IGNvdW50ID0gMDsKICAgICAgICAgICAgICBsZXQgdG90YWwgPSAwOwogICAgICAgICAgICAgIGZvciAobGV0IHJhd05vZGUgb2Ygbm9kZXMpIHsKICAgICAgICAgICAgICAgICAgLy8g5Lia5Yqh6YC76L6RCiAgICAgICAgICAgICAgICAgIGxldCBjaGlsZHJlbiA9IGdldENoaWxkcmVuKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICAvLyDpnZ7orr7lpIfnsbvlnosKICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUuZGF0YVR5cGUgIT09IERhdGFUeXBlLkRFVklDRSkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV2aWNlTGlzdCA9IFtbXSwgW11dOwogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiA/IGNoaWxkcmVuIDogW107CiAgICAgICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kZXZpY2VMaXN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS5kZXZpY2VMaXN0LmZvckVhY2goKHYpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCArICctJyArIHYuZGV2aWNlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdi5kZXZOYW1lIHx8IHYuZGV2aWNlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogRGF0YVR5cGUuREVWSUNFLCAvLyDku6Pooajorr7lpIcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZVN0YXR1czogc2V0RGV2aWNlU3RhdHVzKHYpIC8vIOiuvuWkh+eKtuaAgQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlRmlsdGVyQ29uZmlnKHRhcmdldCwgZmlsdGVyTGlzdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuZGV2aWNlU3RhdHVzID09PSBEZXZpY2VTdGF0dXMuT0ZGX0xJTkUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VMaXN0W3NvcnRCeVN0YXR1cyA/IDEgOiAwXS5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNob3dPbmxpbmVTdGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChnZXRLZXkodGFyZ2V0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlTGlzdFswXS5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IFsuLi5jaGlsZHJlbiwgLi4uZGV2aWNlTGlzdFswXSwgLi4uZGV2aWNlTGlzdFsxXV07CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlID0gewogICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJhd05vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiBEYXRhVHlwZS5ERVBULCAvLyDpg6jpl6gKICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcmF3Tm9kZS5vcmdOYW1lIHx8IHJhd05vZGUuY29tcGFueU5hbWUKICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6L+H5ruk5rKh5pyJ6K6+5aSH55qE6YOo6Zeo5ZKM576k57uEIOatpemqpOS4gAogICAgICAgICAgICAgICAgICBpZiAoY2xlYXJFbXB0eUJ1c2luZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMCAmJiByYXdOb2RlLmRhdGFUeXBlICE9PSAzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6YCa55So6YC76L6RCiAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZ2V0S2V5KHJhd05vZGUpOwogICAgICAgICAgICAgICAgICBjb25zdCBub2RlID0gewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICBrZXk6IHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgZGF0YTogcmF3Tm9kZSwKICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBnZXRMYWJlbChyYXdOb2RlKSwKICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkOiBleHBhbmRlZEtleVNldC5oYXModmFsdWUpCiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIC8vIOmakOiXj+ayoeacieWcqOe6v+iuvuWkh+eahOmDqOmXqOWSjOe+pOe7hAogICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMCAmJiByYXdOb2RlLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5ERVZJQ0UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChub2RlLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6Z2e6K6+5aSH57G75Z6L5pWw5o2uCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5ERVZJQ0UgJiYgY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGxpc3QsIGNvdW50OiBjaGlsZENvdW50LCB0b3RhbDogY2hpbGRUb3RhbCB9ID0gdHJhdmVyc2UoY2hpbGRyZW4sIGxldmVsICsgMSwgbm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInnlKjmiLfnmoTpg6jpl6gg5q2l6aqk5LqMCiAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNob3dPbmxpbmVTdGF0ZSAmJiBjbGVhckVtcHR5QnVzaW5lc3MgJiYgY2hpbGRUb3RhbCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IGxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hpbGRDb3VudCA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gY2hpbGRUb3RhbCA7CiAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGlsZENvdW50OwogICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hpbGRUb3RhbDsKICAgICAgICAgICAgICAgICAgICAgIC8vIOS7heaYvuekuuWcqOe6v+iuvuWkh+aXtu+8jOmakOiXj+ayoeacieWcqOe6v+iuvuWkh+eahOmDqOmXqOWSjOe+pOe7hAogICAgICAgICAgICAgICAgICAgICAgaWYgKHNob3dPbmxpbmVTdGF0ZSAmJiAhY2hpbGRDb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGRlbk5vZGVLZXlTZXQuYWRkKG5vZGUua2V5KTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAvLyDnu5/orqEKICAgICAgICAgICAgICAgICAgICAgIGlmICghc2hvd09ubGluZVN0YXRlIHx8ICFoaWRkZW5Ob2RlS2V5U2V0Lmhhcyhub2RlLmtleSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNvdW50RmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdG90YWxGaWx0ZXIocmF3Tm9kZSkgPyAxIDogMDsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6K6+5aSH57G75Z6L5pWw5o2u77yM5LiU5pyJ6YCa6YGT5pWw5o2u5aSE55CGCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlID09PSBEYXRhVHlwZS5ERVZJQ0UgJiYgcmF3Tm9kZS52aWRlb0NoYW5uZWxMaXN0Py5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxMZXZlbCA9IGxldmVsICsgMTsKICAgICAgICAgICAgICAgICAgICAgIGlmICghbGV2ZWxUcmVlTm9kZU1hcC5oYXMoY2hhbm5lbExldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGNoYW5uZWxMZXZlbCwgW10pOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbExpc3QgPSBbW10sIFtdXTsKICAgICAgICAgICAgICAgICAgICAgIGxldCBjaGFubmVsT25saW5lQ291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbGV0IGhhc0JlTW9uaXRvciA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS52aWRlb0NoYW5uZWxMaXN0LmZvckVhY2goKGMpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IHJhd05vZGUub25seUlkICsgJy0nICsgYy5jaGFubmVsSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjLmNoYW5uZWxOYW1lIHx8IGMuY2hhbm5lbElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbDogbGV2ZWwgKyAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWw6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNMZWFmOiB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSWQ6IHJhd05vZGUuZGV2aWNlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZOYW1lOiByYXdOb2RlLmRldk5hbWUgfHwgcmF3Tm9kZS5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5vbmx5SWQgKyAnLScgKyBjLmNoYW5uZWxJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjLmNoYW5uZWxOYW1lIHx8IGMuY2hhbm5lbElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLkNIQU5ORUwsIC8vIOS7o+ihqOmAmumBkwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlU3RhdHVzOiBzZXREZXZpY2VTdGF0dXMoYykgLy8g6K6+5aSH6YCa6YGT54q25oCBCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogbm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgIGhhc0JlTW9uaXRvciA9IGhhc0JlTW9uaXRvciB8fCBjaGFubmVsLmRhdGEuZGV2aWNlU3RhdHVzID09PSBEZXZpY2VTdGF0dXMuQkVfTU9OSVRPUjsKICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbC5kYXRhLmRldmljZVN0YXR1cyA9PT0gRGV2aWNlU3RhdHVzLk9GRl9MSU5FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0W3NvcnRCeVN0YXR1cyA/IDEgOiAwXS5wdXNoKGNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChjaGFubmVsLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxPbmxpbmVDb3VudCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFswXS5wdXNoKGNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTWFwLnNldChjLmNoYW5uZWxJZCwgY2hhbm5lbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KGNoYW5uZWwua2V5LCBjaGFubmVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLmdldChjaGFubmVsTGV2ZWwpLnB1c2goY2hhbm5lbCk7CiAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gWy4uLmNoYW5uZWxMaXN0WzBdLCAuLi5jaGFubmVsTGlzdFsxXV07CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hhbm5lbE9ubGluZUNvdW50OwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IHNob3dPbmxpbmVTdGF0ZSA/IG5vZGUuY291bnQgOiBjaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNoaWxkcmVuID0gY2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICBtYXhMZXZlbCA9IE1hdGgubWF4KGNoYW5uZWxMZXZlbCwgbWF4TGV2ZWwpOwogICAgICAgICAgICAgICAgICAgICAgLy8g6YCa6YGT54q25oCB5Li655uR5o6n5Lit77yM6K6+5aSH54q25oCB5Li65Zyo57q/77yM5bCG6K6+5aSH54q25oCB5pu05pS55Li655uR5o6n5LitCiAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzQmVNb25pdG9yICYmIG5vZGUuZGF0YS5kZXZpY2VTdGF0dXMgPT09IERldmljZVN0YXR1cy5PTl9MSU5FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5kYXRhLmRldmljZVN0YXR1cyA9IERldmljZVN0YXR1cy5CRV9NT05JVE9SOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgc2libGluZ3MucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KHZhbHVlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgaWYgKCFsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGxldmVsLCBbXSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKGxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5nZXQobGV2ZWwpLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6K6+5aSHCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlID09PSBEYXRhVHlwZS5ERVZJQ0UpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgZGV2aWNlSWQgfSA9IG5vZGUuZGF0YTsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRldmljZUluZm8gPSBkZXZpY2VNYXAuZ2V0KGRldmljZUlkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZUluZm8ucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZU1hcC5zZXQoZGV2aWNlSWQsIGRldmljZUluZm8pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChsZXZlbCA+IG1heExldmVsKSB7CiAgICAgICAgICAgICAgICAgIG1heExldmVsID0gbGV2ZWw7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB7IGxpc3Q6IHNpYmxpbmdzLCBjb3VudCwgdG90YWwgfTsKICAgICAgICAgIH07CiAgICAgICAgICBjb25zdCB7IGxpc3QgfSA9IHRyYXZlcnNlKGRhdGEgfHwgW10pOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVzID0gbGlzdDsKICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgY2hhbm5lbE1hcCwKICAgICAgICAgICAgICB0cmVlTm9kZU1hcCwKICAgICAgICAgICAgICBkZXZpY2VNYXAsCiAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcCwKICAgICAgICAgICAgICBtYXhMZXZlbCwKICAgICAgICAgICAgICB0cmVlTm9kZXMsCiAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldAogICAgICAgICAgfTsKICAgICAgfQogICAgICByZXR1cm4gY3JlYXRlRGV2aWNlVHJlZShkYXRhKTsKICB9CiAgLy8g576k57uE6K6+5aSH5qCR57uT5p6ECiAgZnVuY3Rpb24gZ2VuZXJhdGVHcm91cERldmljZVRyZWUoZGF0YSwgY29uZmlnKSB7CiAgICAgIGNvbnN0IHsgZXhwYW5kZWRLZXlTZXQgfSA9IGNvbmZpZzsKICAgICAgY29uc3QgeyBzb3J0QnlTdGF0dXMsIHNob3dPbmxpbmVTdGF0ZSwgY2xlYXJFbXB0eUJ1c2luZXNzIH0gPSBjb25maWcuYnVzaW5lc3NDb25maWc7CiAgICAgIGNvbnN0IHsgZ2V0S2V5LCBnZXRMYWJlbCwgZ2V0Q2hpbGRyZW4sIGNvdW50RmlsdGVyLCB0b3RhbEZpbHRlciwgc2V0RGV2aWNlU3RhdHVzIH0gPSB1c2VIYW5kbGVGdW4oY29uZmlnKTsKICAgICAgY29uc3QgZmlsdGVyTGlzdCA9IGhhbmRsZUZpbHRlckNvbmZpZyhjb25maWcuYnVzaW5lc3NDb25maWc/LmZpbHRlckNvbmZpZyk7CiAgICAgIC8qKiDnvqTnu4Torr7lpIfmoJEgKi8KICAgICAgZnVuY3Rpb24gY3JlYXRlRGV2aWNlVHJlZShkYXRhKSB7CiAgICAgICAgICBsZXQgbWF4TGV2ZWwgPSAxOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBsZXZlbFRyZWVOb2RlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgZGV2aWNlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgaGlkZGVuTm9kZUtleVNldCA9IG5ldyBTZXQoKTsKICAgICAgICAgIGNvbnN0IHRyYXZlcnNlID0gKG5vZGVzLCBsZXZlbCA9IDEsIHBhcmVudCA9IHVuZGVmaW5lZCkgPT4gewogICAgICAgICAgICAgIGNvbnN0IHNpYmxpbmdzID0gW107CiAgICAgICAgICAgICAgbGV0IGNvdW50ID0gMDsKICAgICAgICAgICAgICBsZXQgdG90YWwgPSAwOwogICAgICAgICAgICAgIGZvciAobGV0IHJhd05vZGUgb2Ygbm9kZXMpIHsKICAgICAgICAgICAgICAgICAgLy8g5Lia5Yqh6YC76L6RCiAgICAgICAgICAgICAgICAgIGxldCBjaGlsZHJlbiA9IGdldENoaWxkcmVuKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICAvLyDnvqTnu4QKICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUuY2hpbGRyZW4/Lmxlbmd0aCB8fAogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS5ncm91cExpc3Q/Lmxlbmd0aCB8fAogICAgICAgICAgICAgICAgICAgICAgIVszLCA0XS5pbmNsdWRlcyhyYXdOb2RlLmRhdGFUeXBlKSkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ3JvdXBMaXN0ID0gW107CiAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuID8gY2hpbGRyZW4gOiBbXTsKICAgICAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmdyb3VwTGlzdD8ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS5ncm91cExpc3QuZm9yRWFjaCgodikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkICsgJy0nICsgdi5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiB2Lmdyb3VwTmFtZSB8fCB2LmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IDQgLy8g5Luj6KGo576k57uECiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwTGlzdC5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBbLi4uY2hpbGRyZW4sIC4uLmdyb3VwTGlzdF07CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlID0gewogICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJhd05vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiAxLCAvLyDpg6jpl6gKICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcmF3Tm9kZS5vcmdOYW1lIHx8IHJhd05vZGUuY29tcGFueU5hbWUKICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6K6+5aSHCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRldmljZUxpc3Q/Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV2aWNlTGlzdCA9IFtbXSwgW11dOwogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiA/IGNoaWxkcmVuIDogW107CiAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlLmRldmljZUxpc3QuZm9yRWFjaCgodikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkICsgJy0nICsgdi5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHYuZGV2TmFtZSB8fCB2LmRldmljZUlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogMywgLy8g5Luj6KGo6K6+5aSHCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZVN0YXR1czogc2V0RGV2aWNlU3RhdHVzKHYpIC8vIOiuvuWkh+eKtuaAgQogICAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVzZUZpbHRlckNvbmZpZyh0YXJnZXQsIGZpbHRlckxpc3QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuZGV2aWNlU3RhdHVzID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VMaXN0W3NvcnRCeVN0YXR1cyA/IDEgOiAwXS5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldC5hZGQoZ2V0S2V5KHRhcmdldCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlTGlzdFswXS5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gWy4uLmNoaWxkcmVuLCAuLi5kZXZpY2VMaXN0WzBdLCAuLi5kZXZpY2VMaXN0WzFdXTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInorr7lpIfnmoTpg6jpl6jlkoznvqTnu4Qg5q2l6aqk5LiACiAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmIHJhd05vZGUuZGF0YVR5cGUgIT09IDMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDpgJrnlKjpgLvovpEKICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRLZXkocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgIGtleTogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhOiByYXdOb2RlCiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIG5vZGUubGFiZWwgPSBnZXRMYWJlbChyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgbm9kZS5leHBhbmRlZCA9IGV4cGFuZGVkS2V5U2V0Lmhhcyh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgIC8vIOmakOiXj+ayoeacieWcqOe6v+iuvuWkh+eahOmDqOmXqOWSjOe+pOe7hAogICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMCAmJiByYXdOb2RlLmRhdGFUeXBlICE9PSAzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldC5hZGQobm9kZS5rZXkpOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbGlzdCwgY291bnQ6IGNoaWxkQ291bnQsIHRvdGFsOiBjaGlsZFRvdGFsIH0gPSB0cmF2ZXJzZShjaGlsZHJlbiwgbGV2ZWwgKyAxLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieiuvuWkh+eahOmDqOmXqOWSjOe+pOe7hCDmraXpqqTkuowKICAgICAgICAgICAgICAgICAgICAgIGlmICghc2hvd09ubGluZVN0YXRlICYmIGNsZWFyRW1wdHlCdXNpbmVzcyAmJiBjaGlsZFRvdGFsID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNoaWxkcmVuID0gbGlzdDsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSBjaGlsZENvdW50IDsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUudG90YWwgPSBjaGlsZFRvdGFsIDsKICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNoaWxkQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSBjaGlsZFRvdGFsOwogICAgICAgICAgICAgICAgICAgICAgLy8g5LuF5pi+56S65Zyo57q/6K6+5aSH5pe277yM6ZqQ6JeP5rKh5pyJ5Zyo57q/6K6+5aSH55qE6YOo6Zeo5ZKM576k57uECiAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlICYmICFjaGlsZENvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldC5hZGQobm9kZS5rZXkpOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gMDsKICAgICAgICAgICAgICAgICAgICAgIC8vIOe7n+iuoQogICAgICAgICAgICAgICAgICAgICAgaWYgKCFzaG93T25saW5lU3RhdGUgfHwgIWhpZGRlbk5vZGVLZXlTZXQuaGFzKG5vZGUua2V5KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gY291bnRGaWx0ZXIocmF3Tm9kZSkgPyAxIDogMDsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0b3RhbEZpbHRlcihyYXdOb2RlKSA/IDEgOiAwOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBzaWJsaW5ncy5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICB0cmVlTm9kZU1hcC5zZXQodmFsdWUsIG5vZGUpOwogICAgICAgICAgICAgICAgICBpZiAoIWxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5zZXQobGV2ZWwsIFtdKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAobGV2ZWxUcmVlTm9kZU1hcC5oYXMobGV2ZWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLmdldChsZXZlbCkucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDorr7lpIcKICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUuZGF0YVR5cGUgPT09IDMpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgZGV2aWNlSWQgfSA9IG5vZGUuZGF0YTsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRldmljZUluZm8gPSBkZXZpY2VNYXAuZ2V0KGRldmljZUlkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZUluZm8ucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZU1hcC5zZXQoZGV2aWNlSWQsIGRldmljZUluZm8pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChsZXZlbCA+IG1heExldmVsKSB7CiAgICAgICAgICAgICAgICAgIG1heExldmVsID0gbGV2ZWw7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB7IGxpc3Q6IHNpYmxpbmdzLCBjb3VudCwgdG90YWwgfTsKICAgICAgICAgIH07CiAgICAgICAgICBjb25zdCB7IGxpc3QgfSA9IHRyYXZlcnNlKGRhdGEgfHwgW10pOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVzID0gbGlzdDsKICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgdHJlZU5vZGVNYXAsCiAgICAgICAgICAgICAgZGV2aWNlTWFwLAogICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAsCiAgICAgICAgICAgICAgbWF4TGV2ZWwsCiAgICAgICAgICAgICAgdHJlZU5vZGVzLAogICAgICAgICAgICAgIGhpZGRlbk5vZGVLZXlTZXQKICAgICAgICAgIH07CiAgICAgIH0KICAgICAgcmV0dXJuIGNyZWF0ZURldmljZVRyZWUoZGF0YSk7CiAgfQogIC8vIOe+pOe7hOagkee7k+aehAogIGZ1bmN0aW9uIGdlbmVyYXRlR3JvdXBUcmVlKGRhdGEsIGNvbmZpZykgewogICAgICBjb25zdCB7IGV4cGFuZGVkS2V5U2V0IH0gPSBjb25maWc7CiAgICAgIGNvbnN0IHsgY2xlYXJFbXB0eUJ1c2luZXNzIH0gPSBjb25maWcuYnVzaW5lc3NDb25maWc7CiAgICAgIGNvbnN0IHsgZ2V0S2V5LCBnZXRMYWJlbCwgZ2V0Q2hpbGRyZW59ID0gdXNlSGFuZGxlRnVuKGNvbmZpZyk7CiAgICAgIC8qKiDnvqTnu4TmoJEgKi8KICAgICAgZnVuY3Rpb24gY3JlYXRlR3JvdXBUcmVlKGRhdGEpIHsKICAgICAgICAgIGxldCBtYXhMZXZlbCA9IDE7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZU1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IGxldmVsVHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCB0cmF2ZXJzZSA9IChub2RlcywgbGV2ZWwgPSAxLCBwYXJlbnQgPSB1bmRlZmluZWQpID0+IHsKICAgICAgICAgICAgICBjb25zdCBzaWJsaW5ncyA9IFtdOwogICAgICAgICAgICAgIGxldCBjb3VudCA9IDA7CiAgICAgICAgICAgICAgbGV0IHRvdGFsID0gMDsKICAgICAgICAgICAgICBmb3IgKGxldCByYXdOb2RlIG9mIG5vZGVzKSB7CiAgICAgICAgICAgICAgICAgIGxldCBkZXZpY2VDb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgIGxldCBkZXZpY2VUb3RhbCA9IDA7CiAgICAgICAgICAgICAgICAgIC8vIOS4muWKoemAu+i+kQogICAgICAgICAgICAgICAgICBsZXQgY2hpbGRyZW4gPSBnZXRDaGlsZHJlbihyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgLy8g576k57uECiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmNoaWxkcmVuPy5sZW5ndGggfHwKICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUuZ3JvdXBMaXN0Py5sZW5ndGggfHwKICAgICAgICAgICAgICAgICAgICAgICFbMywgNF0uaW5jbHVkZXMocmF3Tm9kZS5kYXRhVHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdyb3VwTGlzdCA9IFtdOwogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiA/IGNoaWxkcmVuIDogW107CiAgICAgICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5ncm91cExpc3Q/Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUuZ3JvdXBMaXN0LmZvckVhY2goKHYpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCArICctJyArIHYuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdi5ncm91cE5hbWUgfHwgdi5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiA0IC8vIOS7o+ihqOe+pOe7hAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cExpc3QucHVzaCh0YXJnZXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gWy4uLmNoaWxkcmVuLCAuLi5ncm91cExpc3RdOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5yYXdOb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogMSwgLy8g6YOo6ZeoCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHJhd05vZGUub3JnTmFtZSB8fCByYXdOb2RlLmNvbXBhbnlOYW1lCiAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOiuvuWkhwogICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kZXZpY2VMaXN0Py5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZUNvdW50ID0gcmF3Tm9kZS5kZXZpY2VMaXN0LnJlZHVjZSgodmFsdWUsIHYpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUgKyAodi5vbmxpbmVTdGF0ZSA9PT0gMSA/IDEgOiAwKTsKICAgICAgICAgICAgICAgICAgICAgIH0sIGRldmljZUNvdW50KTsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZVRvdGFsID0gcmF3Tm9kZS5kZXZpY2VMaXN0Lmxlbmd0aCB8fCAwOwogICAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gZGV2aWNlQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSBkZXZpY2VUb3RhbDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInorr7lpIflkoznvqTnu4TnmoTpg6jpl6gg5q2l6aqk5LiACiAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmICFbMywgNF0uaW5jbHVkZXMocmF3Tm9kZS5kYXRhVHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDlpITnkIbpgLvovpEKICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRLZXkocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgIGtleTogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhOiByYXdOb2RlCiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIG5vZGUubGFiZWwgPSBnZXRMYWJlbChyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgbm9kZS5leHBhbmRlZCA9IGV4cGFuZGVkS2V5U2V0Lmhhcyh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbGlzdCwgY291bnQ6IGNoaWxkQ291bnQsIHRvdGFsOiBjaGlsZFRvdGFsIH0gPSB0cmF2ZXJzZShjaGlsZHJlbiwgbGV2ZWwgKyAxLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieiuvuWkh+eahOmDqOmXqOWSjOe+pOe7hCDmraXpqqTkuowKICAgICAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MgJiYgY2hpbGRUb3RhbCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IGxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hpbGRDb3VudCA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gY2hpbGRUb3RhbCA7CiAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGlsZENvdW50OwogICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hpbGRUb3RhbDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIGlmIChyYXdOb2RlLmRhdGFUeXBlICE9PSAzKSB7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gZGV2aWNlQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gZGV2aWNlVG90YWw7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgc2libGluZ3MucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KHZhbHVlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgaWYgKCFsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGxldmVsLCBbXSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKGxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5nZXQobGV2ZWwpLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKGxldmVsID4gbWF4TGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgbWF4TGV2ZWwgPSBsZXZlbDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHsgbGlzdDogc2libGluZ3MsIGNvdW50LCB0b3RhbCB9OwogICAgICAgICAgfTsKICAgICAgICAgIGNvbnN0IHsgbGlzdCB9ID0gdHJhdmVyc2UoZGF0YSB8fCBbXSk7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZXMgPSBsaXN0OwogICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICB0cmVlTm9kZU1hcCwKICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIG1heExldmVsLAogICAgICAgICAgICAgIHRyZWVOb2RlcywKICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0OiBuZXcgU2V0KCkKICAgICAgICAgIH07CiAgICAgIH0KICAgICAgcmV0dXJuIGNyZWF0ZUdyb3VwVHJlZShkYXRhKTsKICB9CiAgLy8g55So5oi35qCR57uT5p6ECiAgZnVuY3Rpb24gZ2VuZXJhdGVVc2VyVHJlZShkYXRhLCBjb25maWcpIHsKICAgICAgY29uc3QgeyBleHBhbmRlZEtleVNldCB9ID0gY29uZmlnOwogICAgICBjb25zdCB7IGNsZWFyRW1wdHlCdXNpbmVzcyB9ID0gY29uZmlnLmJ1c2luZXNzQ29uZmlnOwogICAgICBjb25zdCB7IGdldEtleSwgZ2V0TGFiZWwsIGdldENoaWxkcmVuLCBjb3VudEZpbHRlciwgdG90YWxGaWx0ZXIgfSA9IHVzZUhhbmRsZUZ1bihjb25maWcpOwogICAgICBjb25zdCBmaWx0ZXJMaXN0ID0gaGFuZGxlRmlsdGVyQ29uZmlnKGNvbmZpZy5idXNpbmVzc0NvbmZpZz8uZmlsdGVyQ29uZmlnKTsKICAgICAgLyoqIOeUqOaIt+agkSAqLwogICAgICBmdW5jdGlvbiBjcmVhdGVVc2VyVHJlZShkYXRhKSB7CiAgICAgICAgICBsZXQgbWF4TGV2ZWwgPSAxOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBsZXZlbFRyZWVOb2RlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgdXNlck1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IHRyYXZlcnNlID0gKG5vZGVzLCBsZXZlbCA9IDEsIHBhcmVudCA9IHVuZGVmaW5lZCkgPT4gewogICAgICAgICAgICAgIGNvbnN0IHNpYmxpbmdzID0gW107CiAgICAgICAgICAgICAgbGV0IGNvdW50ID0gMDsKICAgICAgICAgICAgICBsZXQgdG90YWwgPSAwOwogICAgICAgICAgICAgIGZvciAobGV0IHJhd05vZGUgb2Ygbm9kZXMpIHsKICAgICAgICAgICAgICAgICAgLy8g5Lia5Yqh6YC76L6RCiAgICAgICAgICAgICAgICAgIGxldCBjaGlsZHJlbiA9IGdldENoaWxkcmVuKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kYXRhVHlwZSAhPT0gNSkgewogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiA/IGNoaWxkcmVuIDogW107CiAgICAgICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kZXZpY2VVc2VyTGlzdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUuZGV2aWNlVXNlckxpc3QuZm9yRWFjaCgodikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkICsgJy0nICsgdi5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiB2Lm5hbWUgfHwgdi5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiA1LCAvLyDku6PooajnlKjmiLcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVzZUZpbHRlckNvbmZpZyh0YXJnZXQsIGZpbHRlckxpc3QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucmF3Tm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5SWQ6IHJhd05vZGUuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IDEsIC8vIOmDqOmXqAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiByYXdOb2RlLm9yZ05hbWUgfHwgcmF3Tm9kZS5jb21wYW55TmFtZQogICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInnlKjmiLfnmoTpg6jpl6gg5q2l6aqk5LiACiAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmIHJhd05vZGUuZGF0YVR5cGUgIT09IDUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDpgJrnlKjpgLvovpEKICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRLZXkocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgIGtleTogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhOiByYXdOb2RlCiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIG5vZGUubGFiZWwgPSBnZXRMYWJlbChyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgbm9kZS5leHBhbmRlZCA9IGV4cGFuZGVkS2V5U2V0Lmhhcyh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbGlzdCwgY291bnQ6IGNoaWxkQ291bnQsIHRvdGFsOiBjaGlsZFRvdGFsIH0gPSB0cmF2ZXJzZShjaGlsZHJlbiwgbGV2ZWwgKyAxLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieeUqOaIt+eahOmDqOmXqCDmraXpqqTkuowKICAgICAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MgJiYgY2hpbGRUb3RhbCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IGxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hpbGRDb3VudCA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gY2hpbGRUb3RhbCA7CiAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGlsZENvdW50OwogICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hpbGRUb3RhbDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAvLyDnu5/orqEKICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjb3VudEZpbHRlcihyYXdOb2RlKSA/IDEgOiAwOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRvdGFsRmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgc2libGluZ3MucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KHZhbHVlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgaWYgKCFsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGxldmVsLCBbXSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKGxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5nZXQobGV2ZWwpLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g55So5oi3CiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlID09PSA1KSB7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGlkIH0gPSBub2RlLmRhdGE7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1c2VyTGlzdCA9IHVzZXJNYXAuZ2V0KGlkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIHVzZXJMaXN0LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICB1c2VyTWFwLnNldChpZCwgdXNlckxpc3QpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChsZXZlbCA+IG1heExldmVsKSB7CiAgICAgICAgICAgICAgICAgIG1heExldmVsID0gbGV2ZWw7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB7IGxpc3Q6IHNpYmxpbmdzLCBjb3VudCwgdG90YWwgfTsKICAgICAgICAgIH07CiAgICAgICAgICBjb25zdCB7IGxpc3QgfSA9IHRyYXZlcnNlKGRhdGEgfHwgW10pOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVzID0gbGlzdDsKICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgdHJlZU5vZGVNYXAsCiAgICAgICAgICAgICAgdXNlck1hcCwKICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIG1heExldmVsLAogICAgICAgICAgICAgIHRyZWVOb2RlcywKICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0OiBuZXcgU2V0KCkKICAgICAgICAgIH07CiAgICAgIH0KICAgICAgcmV0dXJuIGNyZWF0ZVVzZXJUcmVlKGRhdGEpOwogIH0KICAvLyDpmJ/kvI3nlKjmiLfmoJHnu5PmnoQKICBmdW5jdGlvbiBnZW5lcmF0ZVRlYW1Vc2VyVHJlZShkYXRhLCBjb25maWcpIHsKICAgICAgY29uc3QgeyBleHBhbmRlZEtleVNldCB9ID0gY29uZmlnOwogICAgICBjb25zdCB7IGNsZWFyRW1wdHlCdXNpbmVzcyB9ID0gY29uZmlnLmJ1c2luZXNzQ29uZmlnOwogICAgICBjb25zdCB7IGdldEtleSwgZ2V0TGFiZWwsIGdldENoaWxkcmVuLCBjb3VudEZpbHRlciwgdG90YWxGaWx0ZXIgfSA9IHVzZUhhbmRsZUZ1bihjb25maWcpOwogICAgICBjb25zdCBmaWx0ZXJMaXN0ID0gaGFuZGxlRmlsdGVyQ29uZmlnKGNvbmZpZy5idXNpbmVzc0NvbmZpZz8uZmlsdGVyQ29uZmlnKTsKICAgICAgLyoqIOmYn+S8jeeUqOaIt+agkSAqLwogICAgICBmdW5jdGlvbiBjcmVhdGVVc2VyVHJlZShkYXRhKSB7CiAgICAgICAgICBsZXQgbWF4TGV2ZWwgPSAxOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBsZXZlbFRyZWVOb2RlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgdXNlck1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IHRlYW1NYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCB0cmF2ZXJzZSA9IChub2RlcywgbGV2ZWwgPSAxLCBwYXJlbnQgPSB1bmRlZmluZWQpID0+IHsKICAgICAgICAgICAgICBjb25zdCBzaWJsaW5ncyA9IFtdOwogICAgICAgICAgICAgIGxldCBjb3VudCA9IDA7CiAgICAgICAgICAgICAgbGV0IHRvdGFsID0gMDsKICAgICAgICAgICAgICBmb3IgKGxldCByYXdOb2RlIG9mIG5vZGVzKSB7CiAgICAgICAgICAgICAgICAgIC8vIOS4muWKoemAu+i+kQogICAgICAgICAgICAgICAgICBsZXQgY2hpbGRyZW4gPSBnZXRDaGlsZHJlbihyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgLy8g6Zif5LyNCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmNoaWxkcmVuPy5sZW5ndGggfHwKICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUudGFza1RlYW1MaXN0Py5sZW5ndGggfHwKICAgICAgICAgICAgICAgICAgICAgICFbRGF0YVR5cGUuVVNFUiwgRGF0YVR5cGUuVEVBTV0uaW5jbHVkZXMocmF3Tm9kZS5kYXRhVHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gY2hpbGRyZW4gPyBjaGlsZHJlbiA6IFtdOwogICAgICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUudGFza1RlYW1MaXN0Py5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlLnRhc2tUZWFtTGlzdC5mb3JFYWNoKCh2KSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCArICctJyArIHYuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdi50ZWFtTmFtZSB8fCB2LmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLlRFQU0sIC8vIOmYn+S8jQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucmF3Tm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5SWQ6IHJhd05vZGUuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLkRFUFQsIC8vIOmDqOmXqAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiByYXdOb2RlLm9yZ05hbWUgfHwgcmF3Tm9kZS5jb21wYW55TmFtZQogICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDnlKjmiLcKICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUubWVtYmVyTGlzdD8ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuID8gY2hpbGRyZW4gOiBbXTsKICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUubWVtYmVyTGlzdC5mb3JFYWNoKCh2KSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5SWQ6IHJhd05vZGUuaWQgKyAnLScgKyB2LnVzZXJJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHYubmFtZSB8fCB2LnVzZXJJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLlVTRVIsIC8vIOS7o+ihqOeUqOaItwogICAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVzZUZpbHRlckNvbmZpZyh0YXJnZXQsIGZpbHRlckxpc3QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2godGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInnlKjmiLfnmoTpg6jpl6jmiJbpmJ/kvI0g5q2l6aqk5LiACiAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmIHJhd05vZGUuZGF0YVR5cGUgIT09IERhdGFUeXBlLlVTRVIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDpgJrnlKjpgLvovpEKICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRLZXkocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgIGtleTogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhOiByYXdOb2RlCiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIG5vZGUubGFiZWwgPSBnZXRMYWJlbChyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgbm9kZS5leHBhbmRlZCA9IGV4cGFuZGVkS2V5U2V0Lmhhcyh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbGlzdCwgY291bnQ6IGNoaWxkQ291bnQsIHRvdGFsOiBjaGlsZFRvdGFsIH0gPSB0cmF2ZXJzZShjaGlsZHJlbiwgbGV2ZWwgKyAxLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieeUqOaIt+eahOmDqOmXqCDmraXpqqTkuowKICAgICAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MgJiYgY2hpbGRUb3RhbCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IGxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hpbGRDb3VudCA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gY2hpbGRUb3RhbCA7CiAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGlsZENvdW50OwogICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hpbGRUb3RhbDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAvLyDnu5/orqEKICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjb3VudEZpbHRlcihyYXdOb2RlKSA/IDEgOiAwOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRvdGFsRmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgc2libGluZ3MucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KHZhbHVlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgaWYgKCFsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGxldmVsLCBbXSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKGxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5nZXQobGV2ZWwpLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6Zif5LyNCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlID09PSBEYXRhVHlwZS5URUFNKSB7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGlkIH0gPSBub2RlLmRhdGE7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZWFtTGlzdCA9IHRlYW1NYXAuZ2V0KGlkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIHRlYW1MaXN0LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICB0ZWFtTWFwLnNldChpZCwgdGVhbUxpc3QpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOeUqOaItwogICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuVVNFUikgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyB1c2VySWQgfSA9IG5vZGUuZGF0YTsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVzZXJMaXN0ID0gdXNlck1hcC5nZXQodXNlcklkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIHVzZXJMaXN0LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICB1c2VyTWFwLnNldCh1c2VySWQsIHVzZXJMaXN0KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAobGV2ZWwgPiBtYXhMZXZlbCkgewogICAgICAgICAgICAgICAgICBtYXhMZXZlbCA9IGxldmVsOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4geyBsaXN0OiBzaWJsaW5ncywgY291bnQsIHRvdGFsIH07CiAgICAgICAgICB9OwogICAgICAgICAgY29uc3QgeyBsaXN0IH0gPSB0cmF2ZXJzZShkYXRhIHx8IFtdKTsKICAgICAgICAgIGNvbnN0IHRyZWVOb2RlcyA9IGxpc3Q7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgIHRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIHRlYW1NYXAsCiAgICAgICAgICAgICAgdXNlck1hcCwKICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIG1heExldmVsLAogICAgICAgICAgICAgIHRyZWVOb2RlcywKICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0OiBuZXcgU2V0KCkKICAgICAgICAgIH07CiAgICAgIH0KICAgICAgcmV0dXJuIGNyZWF0ZVVzZXJUcmVlKGRhdGEpOwogIH0KICAvLyDph4fpm4bnq5nmoJHnu5PmnoQKICBmdW5jdGlvbiBnZW5lcmF0ZUNzVHJlZShkYXRhLCBjb25maWcpIHsKICAgICAgY29uc3QgeyBleHBhbmRlZEtleVNldCB9ID0gY29uZmlnOwogICAgICBjb25zdCB7IGNsZWFyRW1wdHlCdXNpbmVzcyB9ID0gY29uZmlnLmJ1c2luZXNzQ29uZmlnOwogICAgICBjb25zdCB7IGdldEtleSwgZ2V0TGFiZWwsIGdldENoaWxkcmVuLCBjb3VudEZpbHRlciwgdG90YWxGaWx0ZXIgfSA9IHVzZUhhbmRsZUZ1bihjb25maWcpOwogICAgICBjb25zdCBmaWx0ZXJMaXN0ID0gaGFuZGxlRmlsdGVyQ29uZmlnKGNvbmZpZy5idXNpbmVzc0NvbmZpZz8uZmlsdGVyQ29uZmlnKTsKICAgICAgLyoqIOmHh+mbhuermeagkSAqLwogICAgICBmdW5jdGlvbiBjcmVhdGVDc1RyZWUoZGF0YSkgewogICAgICAgICAgbGV0IG1heExldmVsID0gMTsKICAgICAgICAgIGNvbnN0IHRyZWVOb2RlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgbGV2ZWxUcmVlTm9kZU1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IGNzTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgdHJhdmVyc2UgPSAobm9kZXMsIGxldmVsID0gMSwgcGFyZW50ID0gdW5kZWZpbmVkKSA9PiB7CiAgICAgICAgICAgICAgY29uc3Qgc2libGluZ3MgPSBbXTsKICAgICAgICAgICAgICBsZXQgY291bnQgPSAwOwogICAgICAgICAgICAgIGxldCB0b3RhbCA9IDA7CiAgICAgICAgICAgICAgZm9yIChsZXQgcmF3Tm9kZSBvZiBub2RlcykgewogICAgICAgICAgICAgICAgICAvLyDkuJrliqHpgLvovpEKICAgICAgICAgICAgICAgICAgbGV0IGNoaWxkcmVuID0gZ2V0Q2hpbGRyZW4ocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlICE9PSA4KSB7CiAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuID8gY2hpbGRyZW4gOiBbXTsKICAgICAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmNzTGlzdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUuY3NMaXN0LmZvckVhY2goKHYpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCArICctJyArIHYuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdi5zbmFtZSB8fCB2LnNjb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IDgsIC8vIOS7o+ihqOmHh+mbhuermQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlRmlsdGVyQ29uZmlnKHRhcmdldCwgZmlsdGVyTGlzdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2godGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5yYXdOb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogMSwgLy8g6YOo6ZeoCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHJhd05vZGUub3JnTmFtZSB8fCByYXdOb2RlLmNvbXBhbnlOYW1lCiAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeaciemHh+mbhuWZqOeahOmDqOmXqCDmraXpqqTkuIAKICAgICAgICAgICAgICAgICAgaWYgKGNsZWFyRW1wdHlCdXNpbmVzcykgewogICAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZHJlbiB8fCBjaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgcmF3Tm9kZS5kYXRhVHlwZSAhPT0gOCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOmAmueUqOmAu+i+kQogICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGdldEtleShyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsLAogICAgICAgICAgICAgICAgICAgICAga2V5OiB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHJhd05vZGUKICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgbm9kZS5sYWJlbCA9IGdldExhYmVsKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICBub2RlLnBhcmVudCA9IHBhcmVudDsKICAgICAgICAgICAgICAgICAgbm9kZS5pc0xlYWYgPSAhY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwOwogICAgICAgICAgICAgICAgICBub2RlLmV4cGFuZGVkID0gZXhwYW5kZWRLZXlTZXQuaGFzKHZhbHVlKTsKICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBsaXN0LCBjb3VudDogY2hpbGRDb3VudCwgdG90YWw6IGNoaWxkVG90YWwgfSA9IHRyYXZlcnNlKGNoaWxkcmVuLCBsZXZlbCArIDEsIG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgLy8g6L+H5ruk5rKh5pyJ6YeH6ZuG5Zmo55qE6YOo6ZeoIOatpemqpOS6jAogICAgICAgICAgICAgICAgICAgICAgaWYgKGNsZWFyRW1wdHlCdXNpbmVzcyAmJiBjaGlsZFRvdGFsID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNoaWxkcmVuID0gbGlzdDsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSBjaGlsZENvdW50IDsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUudG90YWwgPSBjaGlsZFRvdGFsIDsKICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNoaWxkQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSBjaGlsZFRvdGFsOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gMDsKICAgICAgICAgICAgICAgICAgICAgIC8vIOe7n+iuoQogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNvdW50RmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdG90YWxGaWx0ZXIocmF3Tm9kZSkgPyAxIDogMDsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBzaWJsaW5ncy5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICB0cmVlTm9kZU1hcC5zZXQodmFsdWUsIG5vZGUpOwogICAgICAgICAgICAgICAgICBpZiAoIWxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5zZXQobGV2ZWwsIFtdKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAobGV2ZWxUcmVlTm9kZU1hcC5oYXMobGV2ZWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLmdldChsZXZlbCkucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDph4fpm4bnq5kKICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUuZGF0YVR5cGUgPT09IDgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgaWQgfSA9IG5vZGUuZGF0YTsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVzZXJMaXN0ID0gY3NNYXAuZ2V0KGlkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIHVzZXJMaXN0LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICBjc01hcC5zZXQoaWQsIHVzZXJMaXN0KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAobGV2ZWwgPiBtYXhMZXZlbCkgewogICAgICAgICAgICAgICAgICBtYXhMZXZlbCA9IGxldmVsOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4geyBsaXN0OiBzaWJsaW5ncywgY291bnQsIHRvdGFsIH07CiAgICAgICAgICB9OwogICAgICAgICAgY29uc3QgeyBsaXN0IH0gPSB0cmF2ZXJzZShkYXRhIHx8IFtdKTsKICAgICAgICAgIGNvbnN0IHRyZWVOb2RlcyA9IGxpc3Q7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgIHRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIGNzTWFwLAogICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAsCiAgICAgICAgICAgICAgbWF4TGV2ZWwsCiAgICAgICAgICAgICAgdHJlZU5vZGVzLAogICAgICAgICAgICAgIGhpZGRlbk5vZGVLZXlTZXQ6IG5ldyBTZXQoKQogICAgICAgICAgfTsKICAgICAgfQogICAgICByZXR1cm4gY3JlYXRlQ3NUcmVlKGRhdGEpOwogIH0KICAvLyDpooTmoYjliIbnu4Torr7lpIfmoJHnu5PmnoQKICBmdW5jdGlvbiBnZW5lcmF0ZVBsYW5Hcm91cERldmljZVRyZWUoZGF0YSwgY29uZmlnKSB7CiAgICAgIGNvbnN0IHsgZXhwYW5kZWRLZXlTZXQgfSA9IGNvbmZpZzsKICAgICAgY29uc3QgeyBzb3J0QnlTdGF0dXMsIHNob3dPbmxpbmVTdGF0ZSwgY2xlYXJFbXB0eUJ1c2luZXNzIH0gPSBjb25maWcuYnVzaW5lc3NDb25maWc7CiAgICAgIGNvbnN0IHsgZ2V0S2V5LCBnZXRMYWJlbCwgZ2V0Q2hpbGRyZW4sIGNvdW50RmlsdGVyLCB0b3RhbEZpbHRlciwgc2V0RGV2aWNlU3RhdHVzIH0gPSB1c2VIYW5kbGVGdW4oY29uZmlnKTsKICAgICAgY29uc3QgZmlsdGVyTGlzdCA9IGhhbmRsZUZpbHRlckNvbmZpZyhjb25maWcuYnVzaW5lc3NDb25maWc/LmZpbHRlckNvbmZpZyk7CiAgICAgIC8qKiDpooTmoYjliIbnu4Torr7lpIfmoJEgKi8KICAgICAgZnVuY3Rpb24gY3JlYXRlRGV2aWNlVHJlZShkYXRhKSB7CiAgICAgICAgICBsZXQgbWF4TGV2ZWwgPSAxOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBsZXZlbFRyZWVOb2RlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgZGV2aWNlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgY2hhbm5lbE1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IGhpZGRlbk5vZGVLZXlTZXQgPSBuZXcgU2V0KCk7CiAgICAgICAgICBjb25zdCB0cmF2ZXJzZSA9IChub2RlcywgbGV2ZWwgPSAxLCBwYXJlbnQgPSB1bmRlZmluZWQpID0+IHsKICAgICAgICAgICAgICBjb25zdCBzaWJsaW5ncyA9IFtdOwogICAgICAgICAgICAgIGxldCBjb3VudCA9IDA7CiAgICAgICAgICAgICAgbGV0IHRvdGFsID0gMDsKICAgICAgICAgICAgICBmb3IgKGxldCByYXdOb2RlIG9mIG5vZGVzKSB7CiAgICAgICAgICAgICAgICAgIC8vIOS4muWKoemAu+i+kQogICAgICAgICAgICAgICAgICBsZXQgY2hpbGRyZW4gPSBnZXRDaGlsZHJlbihyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgLy8g6aKE5qGI5YiG57uECiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmNoaWxkcmVuPy5sZW5ndGggfHwKICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUucGxhbkdyb3VwTGlzdD8ubGVuZ3RoIHx8CiAgICAgICAgICAgICAgICAgICAgICAhW0RhdGFUeXBlLkRFVklDRSwgRGF0YVR5cGUuUExBTl9HUk9VUF0uaW5jbHVkZXMocmF3Tm9kZS5kYXRhVHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBsYW5Hcm91cExpc3QgPSBbXTsKICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gY2hpbGRyZW4gPyBjaGlsZHJlbiA6IFtdOwogICAgICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUucGxhbkdyb3VwTGlzdD8ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS5wbGFuR3JvdXBMaXN0LmZvckVhY2goKHYpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCArICctJyArIHYuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdi5ncm91cE5hbWUgfHwgdi5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiBEYXRhVHlwZS5QTEFOX0dST1VQIC8vIOS7o+ihqOmihOahiOWIhue7hAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFuR3JvdXBMaXN0LnB1c2godGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IFsuLi5jaGlsZHJlbiwgLi4ucGxhbkdyb3VwTGlzdF07CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlID0gewogICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJhd05vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiBEYXRhVHlwZS5ERVBULCAvLyDpg6jpl6gKICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcmF3Tm9kZS5vcmdOYW1lIHx8IHJhd05vZGUuY29tcGFueU5hbWUKICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6K6+5aSHCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRldmljZUxpc3Q/Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV2aWNlTGlzdCA9IFtbXSwgW11dOwogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiA/IGNoaWxkcmVuIDogW107CiAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlLmRldmljZUxpc3QuZm9yRWFjaCgodikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkICsgJy0nICsgdi5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHYuZGV2TmFtZSB8fCB2LmRldmljZUlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogRGF0YVR5cGUuREVWSUNFLCAvLyDku6Pooajorr7lpIcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlU3RhdHVzOiBzZXREZXZpY2VTdGF0dXModikgLy8g6K6+5aSH54q25oCBCiAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlRmlsdGVyQ29uZmlnKHRhcmdldCwgZmlsdGVyTGlzdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldC5kZXZpY2VTdGF0dXMgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZUxpc3Rbc29ydEJ5U3RhdHVzID8gMSA6IDBdLnB1c2godGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaG93T25saW5lU3RhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChnZXRLZXkodGFyZ2V0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VMaXN0WzBdLnB1c2godGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBbLi4uY2hpbGRyZW4sIC4uLmRldmljZUxpc3RbMF0sIC4uLmRldmljZUxpc3RbMV1dOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieiuvuWkh+eahOmDqOmXqOWSjOe+pOe7hCDmraXpqqTkuIAKICAgICAgICAgICAgICAgICAgaWYgKGNsZWFyRW1wdHlCdXNpbmVzcykgewogICAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZHJlbiB8fCBjaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgcmF3Tm9kZS5kYXRhVHlwZSAhPT0gMykgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOmAmueUqOmAu+i+kQogICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGdldEtleShyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsLAogICAgICAgICAgICAgICAgICAgICAga2V5OiB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHJhd05vZGUKICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgbm9kZS5sYWJlbCA9IGdldExhYmVsKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICBub2RlLnBhcmVudCA9IHBhcmVudDsKICAgICAgICAgICAgICAgICAgbm9kZS5pc0xlYWYgPSAhY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwOwogICAgICAgICAgICAgICAgICBub2RlLmV4cGFuZGVkID0gZXhwYW5kZWRLZXlTZXQuaGFzKHZhbHVlKTsKICAgICAgICAgICAgICAgICAgLy8g6ZqQ6JeP5rKh5pyJ5Zyo57q/6K6+5aSH55qE6YOo6Zeo5ZKM576k57uECiAgICAgICAgICAgICAgICAgIGlmIChzaG93T25saW5lU3RhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmIHJhd05vZGUuZGF0YVR5cGUgIT09IDMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChub2RlLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6Z2e6K6+5aSH57G75Z6L5pWw5o2uCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5ERVZJQ0UgJiYgY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGxpc3QsIGNvdW50OiBjaGlsZENvdW50LCB0b3RhbDogY2hpbGRUb3RhbCB9ID0gdHJhdmVyc2UoY2hpbGRyZW4sIGxldmVsICsgMSwgbm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInorr7lpIfnmoTpg6jpl6jlkozpooTmoYjliIbnu4Qg5q2l6aqk5LqMCiAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNob3dPbmxpbmVTdGF0ZSAmJiBjbGVhckVtcHR5QnVzaW5lc3MgJiYgY2hpbGRUb3RhbCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IGxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hpbGRDb3VudCA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gY2hpbGRUb3RhbCA7CiAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGlsZENvdW50OwogICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hpbGRUb3RhbDsKICAgICAgICAgICAgICAgICAgICAgIC8vIOS7heaYvuekuuWcqOe6v+iuvuWkh+aXtu+8jOmakOiXj+ayoeacieWcqOe6v+iuvuWkh+eahOmDqOmXqOWSjOmihOahiOWIhue7hAogICAgICAgICAgICAgICAgICAgICAgaWYgKHNob3dPbmxpbmVTdGF0ZSAmJiAhY2hpbGRDb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGRlbk5vZGVLZXlTZXQuYWRkKG5vZGUua2V5KTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAvLyDnu5/orqEKICAgICAgICAgICAgICAgICAgICAgIGlmICghc2hvd09ubGluZVN0YXRlIHx8ICFoaWRkZW5Ob2RlS2V5U2V0Lmhhcyhub2RlLmtleSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNvdW50RmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdG90YWxGaWx0ZXIocmF3Tm9kZSkgPyAxIDogMDsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6K6+5aSH57G75Z6L5pWw5o2u77yM5LiU5pyJ6YCa6YGT5pWw5o2u5aSE55CGCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlID09PSBEYXRhVHlwZS5ERVZJQ0UgJiYgcmF3Tm9kZS52aWRlb0NoYW5uZWxMaXN0Py5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxMZXZlbCA9IGxldmVsICsgMTsKICAgICAgICAgICAgICAgICAgICAgIGlmICghbGV2ZWxUcmVlTm9kZU1hcC5oYXMoY2hhbm5lbExldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGNoYW5uZWxMZXZlbCwgW10pOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbExpc3QgPSBbW10sIFtdXTsKICAgICAgICAgICAgICAgICAgICAgIGxldCBjaGFubmVsT25saW5lQ291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbGV0IGhhc0JlTW9uaXRvciA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS52aWRlb0NoYW5uZWxMaXN0LmZvckVhY2goKGMpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IHJhd05vZGUub25seUlkICsgJy0nICsgYy5jaGFubmVsSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjLmNoYW5uZWxOYW1lIHx8IGMuY2hhbm5lbElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbDogbGV2ZWwgKyAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWw6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNMZWFmOiB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSWQ6IHJhd05vZGUuZGV2aWNlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZOYW1lOiByYXdOb2RlLmRldk5hbWUgfHwgcmF3Tm9kZS5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5vbmx5SWQgKyAnLScgKyBjLmNoYW5uZWxJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjLmNoYW5uZWxOYW1lIHx8IGMuY2hhbm5lbElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLkNIQU5ORUwsIC8vIOS7o+ihqOmAmumBkwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlU3RhdHVzOiBzZXREZXZpY2VTdGF0dXMoYykgLy8g6K6+5aSH6YCa6YGT54q25oCBCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogbm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgIGhhc0JlTW9uaXRvciA9IGhhc0JlTW9uaXRvciB8fCBjaGFubmVsLmRhdGEuZGV2aWNlU3RhdHVzID09PSBEZXZpY2VTdGF0dXMuQkVfTU9OSVRPUjsKICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbC5kYXRhLmRldmljZVN0YXR1cyA9PT0gRGV2aWNlU3RhdHVzLk9GRl9MSU5FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0W3NvcnRCeVN0YXR1cyA/IDEgOiAwXS5wdXNoKGNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChjaGFubmVsLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxPbmxpbmVDb3VudCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFswXS5wdXNoKGNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTWFwLnNldChjLmNoYW5uZWxJZCwgY2hhbm5lbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KGNoYW5uZWwua2V5LCBjaGFubmVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLmdldChjaGFubmVsTGV2ZWwpLnB1c2goY2hhbm5lbCk7CiAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gWy4uLmNoYW5uZWxMaXN0WzBdLCAuLi5jaGFubmVsTGlzdFsxXV07CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hhbm5lbE9ubGluZUNvdW50OwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IHNob3dPbmxpbmVTdGF0ZSA/IG5vZGUuY291bnQgOiBjaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNoaWxkcmVuID0gY2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICBtYXhMZXZlbCA9IE1hdGgubWF4KGNoYW5uZWxMZXZlbCwgbWF4TGV2ZWwpOwogICAgICAgICAgICAgICAgICAgICAgLy8g6YCa6YGT54q25oCB5Li655uR5o6n5Lit77yM6K6+5aSH54q25oCB5Li65Zyo57q/77yM5bCG6K6+5aSH54q25oCB5pu05pS55Li655uR5o6n5LitCiAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzQmVNb25pdG9yICYmIG5vZGUuZGF0YS5kZXZpY2VTdGF0dXMgPT09IERldmljZVN0YXR1cy5PTl9MSU5FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5kYXRhLmRldmljZVN0YXR1cyA9IERldmljZVN0YXR1cy5CRV9NT05JVE9SOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIHNpYmxpbmdzLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIHRyZWVOb2RlTWFwLnNldCh2YWx1ZSwgbm9kZSk7CiAgICAgICAgICAgICAgICAgIGlmICghbGV2ZWxUcmVlTm9kZU1hcC5oYXMobGV2ZWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLnNldChsZXZlbCwgW10pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGlmIChsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuZ2V0KGxldmVsKS5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOiuvuWkhwogICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kYXRhVHlwZSA9PT0gMykgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBkZXZpY2VJZCB9ID0gbm9kZS5kYXRhOwogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV2aWNlSW5mbyA9IGRldmljZU1hcC5nZXQoZGV2aWNlSWQpIHx8IFtdOwogICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSW5mby5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgZGV2aWNlTWFwLnNldChkZXZpY2VJZCwgZGV2aWNlSW5mbyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKGxldmVsID4gbWF4TGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgbWF4TGV2ZWwgPSBsZXZlbDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHsgbGlzdDogc2libGluZ3MsIGNvdW50LCB0b3RhbCB9OwogICAgICAgICAgfTsKICAgICAgICAgIGNvbnN0IHsgbGlzdCB9ID0gdHJhdmVyc2UoZGF0YSB8fCBbXSk7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZXMgPSBsaXN0OwogICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICBjaGFubmVsTWFwLAogICAgICAgICAgICAgIHRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIGRldmljZU1hcCwKICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIG1heExldmVsLAogICAgICAgICAgICAgIHRyZWVOb2RlcywKICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0CiAgICAgICAgICB9OwogICAgICB9CiAgICAgIHJldHVybiBjcmVhdGVEZXZpY2VUcmVlKGRhdGEpOwogIH0KICBjb25zdCBnZW5lcmF0ZU1hcCA9IHsKICAgICAgLy8g6K6+5aSH5qCRCiAgICAgIFtCdXNpbmVzcy5ERVZJQ0VdOiBnZW5lcmF0ZURldmljZVRyZWUsCiAgICAgIC8vIOmAmumBk+iuvuWkh+agkQogICAgICBbQnVzaW5lc3MuQ0hBTk5FTF06IGdlbmVyYXRlQ2hhbm5lbERldmljZVRyZWUsCiAgICAgIC8vIOe+pOe7hOiuvuWkh+agkQogICAgICBbQnVzaW5lc3MuR1JPVVBfREVWSUNFXTogZ2VuZXJhdGVHcm91cERldmljZVRyZWUsCiAgICAgIC8vIOe+pOe7hOagkQogICAgICBbQnVzaW5lc3MuR1JPVVBdOiBnZW5lcmF0ZUdyb3VwVHJlZSwKICAgICAgLy8g55So5oi35qCRCiAgICAgIFtCdXNpbmVzcy5VU0VSXTogZ2VuZXJhdGVVc2VyVHJlZSwKICAgICAgLy8g6Zif5LyN55So5oi35qCRCiAgICAgIFtCdXNpbmVzcy5URUFNX1VTRVJdOiBnZW5lcmF0ZVRlYW1Vc2VyVHJlZSwKICAgICAgLy8g6YeH6ZuG56uZCiAgICAgIFtCdXNpbmVzcy5DU106IGdlbmVyYXRlQ3NUcmVlLAogICAgICAvLyDpooTmoYjliIbnu4Torr7lpIfmoJEKICAgICAgW0J1c2luZXNzLlBMQU5fR1JPVVBfREVWSUNFXTogZ2VuZXJhdGVQbGFuR3JvdXBEZXZpY2VUcmVlLAogIH07CgogIHNlbGYub25tZXNzYWdlID0gYXN5bmMgKGV2ZW50KSA9PiB7CiAgICAgIGNvbnN0IHsgZGF0YSwgY29uZmlnIH0gPSBldmVudC5kYXRhOwogICAgICBjb25zdCBnZW5lcmF0ZVRyZWUgPSBnZW5lcmF0ZU1hcFtjb25maWcuYnVzaW5lc3NdOwogICAgICBpZiAoIWdlbmVyYXRlVHJlZSkgewogICAgICAgICAgc2VsZi5jbG9zZSgpOwogICAgICAgICAgcmV0dXJuOwogICAgICB9CiAgICAgIGNvbnN0IHRyZWUgPSBnZW5lcmF0ZVRyZWUoZGF0YSwgY29uZmlnKTsKICAgICAgc2VsZi5wb3N0TWVzc2FnZSh0cmVlKTsKICB9OwoKfSkoKTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9Z2VuZXJhdGVUcmVlLmpzLm1hcAoK');
|
|
9110
|
+
var WorkerFactory = /*#__PURE__*/createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICd1c2Ugc3RyaWN0JzsKCiAgY29uc3QgaXNTdHJpbmcgPSAoZSkgPT4gdHlwZW9mIGUgPT09ICdzdHJpbmcnOwogIGNvbnN0IGlzTnVtYmVyID0gKGUpID0+IHR5cGVvZiBlID09PSAnbnVtYmVyJzsKICBjb25zdCBpc09iamVjdCA9IChlKSA9PiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZSkgPT09ICdbb2JqZWN0IE9iamVjdF0nOwogIGNvbnN0IGlzQXJyYXkgPSAoZSkgPT4gQXJyYXkuaXNBcnJheShlKTsKCiAgdmFyIGNvbW1vbmpzR2xvYmFsID0gdHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsVGhpcyA6IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogdHlwZW9mIGdsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgPyBnbG9iYWwgOiB0eXBlb2Ygc2VsZiAhPT0gJ3VuZGVmaW5lZCcgPyBzZWxmIDoge307CgogIGZ1bmN0aW9uIGdldEF1Z21lbnRlZE5hbWVzcGFjZShuKSB7CiAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG4sICdfX2VzTW9kdWxlJykpIHJldHVybiBuOwogICAgdmFyIGYgPSBuLmRlZmF1bHQ7CiAgCWlmICh0eXBlb2YgZiA9PSAiZnVuY3Rpb24iKSB7CiAgCQl2YXIgYSA9IGZ1bmN0aW9uIGEgKCkgewogIAkJCXZhciBpc0luc3RhbmNlID0gZmFsc2U7CiAgICAgICAgdHJ5IHsKICAgICAgICAgIGlzSW5zdGFuY2UgPSB0aGlzIGluc3RhbmNlb2YgYTsKICAgICAgICB9IGNhdGNoIHt9CiAgCQkJaWYgKGlzSW5zdGFuY2UpIHsKICAgICAgICAgIHJldHVybiBSZWZsZWN0LmNvbnN0cnVjdChmLCBhcmd1bWVudHMsIHRoaXMuY29uc3RydWN0b3IpOwogIAkJCX0KICAJCQlyZXR1cm4gZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogIAkJfTsKICAJCWEucHJvdG90eXBlID0gZi5wcm90b3R5cGU7CiAgICB9IGVsc2UgYSA9IHt9OwogICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGEsICdfX2VzTW9kdWxlJywge3ZhbHVlOiB0cnVlfSk7CiAgCU9iamVjdC5rZXlzKG4pLmZvckVhY2goZnVuY3Rpb24gKGspIHsKICAJCXZhciBkID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihuLCBrKTsKICAJCU9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLCBrLCBkLmdldCA/IGQgOiB7CiAgCQkJZW51bWVyYWJsZTogdHJ1ZSwKICAJCQlnZXQ6IGZ1bmN0aW9uICgpIHsKICAJCQkJcmV0dXJuIG5ba107CiAgCQkJfQogIAkJfSk7CiAgCX0pOwogIAlyZXR1cm4gYTsKICB9CgogIHZhciBjcnlwdG9KcyQxID0ge2V4cG9ydHM6IHt9fTsKCiAgZnVuY3Rpb24gY29tbW9uanNSZXF1aXJlKHBhdGgpIHsKICAJdGhyb3cgbmV3IEVycm9yKCdDb3VsZCBub3QgZHluYW1pY2FsbHkgcmVxdWlyZSAiJyArIHBhdGggKyAnIi4gUGxlYXNlIGNvbmZpZ3VyZSB0aGUgZHluYW1pY1JlcXVpcmVUYXJnZXRzIG9yL2FuZCBpZ25vcmVEeW5hbWljUmVxdWlyZXMgb3B0aW9uIG9mIEByb2xsdXAvcGx1Z2luLWNvbW1vbmpzIGFwcHJvcHJpYXRlbHkgZm9yIHRoaXMgcmVxdWlyZSBjYWxsIHRvIHdvcmsuJyk7CiAgfQoKICB2YXIgY29yZSQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIF9ub2RlUmVzb2x2ZV9lbXB0eSA9IHt9OwoKICB2YXIgX25vZGVSZXNvbHZlX2VtcHR5JDEgPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7CiAgICBfX3Byb3RvX186IG51bGwsCiAgICBkZWZhdWx0OiBfbm9kZVJlc29sdmVfZW1wdHkKICB9KTsKCiAgdmFyIHJlcXVpcmUkJDAgPSAvKkBfX1BVUkVfXyovZ2V0QXVnbWVudGVkTmFtZXNwYWNlKF9ub2RlUmVzb2x2ZV9lbXB0eSQxKTsKCiAgdmFyIGNvcmUgPSBjb3JlJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRDb3JlOwogIGZ1bmN0aW9uIHJlcXVpcmVDb3JlKCkgewogICAgaWYgKGhhc1JlcXVpcmVkQ29yZSkgcmV0dXJuIGNvcmUkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRDb3JlID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeSgpOwogICAgICAgIH0KICAgICAgfSkoY29yZSwgZnVuY3Rpb24gKCkgewogICAgICAgIC8qZ2xvYmFscyB3aW5kb3csIGdsb2JhbCwgcmVxdWlyZSovCgogICAgICAgIC8qKgogICAgICAgICAqIENyeXB0b0pTIGNvcmUgY29tcG9uZW50cy4KICAgICAgICAgKi8KICAgICAgICB2YXIgQ3J5cHRvSlMgPSBDcnlwdG9KUyB8fCBmdW5jdGlvbiAoTWF0aCwgdW5kZWZpbmVkJDEpIHsKICAgICAgICAgIHZhciBjcnlwdG87CgogICAgICAgICAgLy8gTmF0aXZlIGNyeXB0byBmcm9tIHdpbmRvdyAoQnJvd3NlcikKICAgICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuY3J5cHRvKSB7CiAgICAgICAgICAgIGNyeXB0byA9IHdpbmRvdy5jcnlwdG87CiAgICAgICAgICB9CgogICAgICAgICAgLy8gTmF0aXZlIGNyeXB0byBpbiB3ZWIgd29ya2VyIChCcm93c2VyKQogICAgICAgICAgaWYgKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyAmJiBzZWxmLmNyeXB0bykgewogICAgICAgICAgICBjcnlwdG8gPSBzZWxmLmNyeXB0bzsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBOYXRpdmUgY3J5cHRvIGZyb20gd29ya2VyCiAgICAgICAgICBpZiAodHlwZW9mIGdsb2JhbFRoaXMgIT09ICd1bmRlZmluZWQnICYmIGdsb2JhbFRoaXMuY3J5cHRvKSB7CiAgICAgICAgICAgIGNyeXB0byA9IGdsb2JhbFRoaXMuY3J5cHRvOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIE5hdGl2ZSAoZXhwZXJpbWVudGFsIElFIDExKSBjcnlwdG8gZnJvbSB3aW5kb3cgKEJyb3dzZXIpCiAgICAgICAgICBpZiAoIWNyeXB0byAmJiB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cubXNDcnlwdG8pIHsKICAgICAgICAgICAgY3J5cHRvID0gd2luZG93Lm1zQ3J5cHRvOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIE5hdGl2ZSBjcnlwdG8gZnJvbSBnbG9iYWwgKE5vZGVKUykKICAgICAgICAgIGlmICghY3J5cHRvICYmIHR5cGVvZiBjb21tb25qc0dsb2JhbCAhPT0gJ3VuZGVmaW5lZCcgJiYgY29tbW9uanNHbG9iYWwuY3J5cHRvKSB7CiAgICAgICAgICAgIGNyeXB0byA9IGNvbW1vbmpzR2xvYmFsLmNyeXB0bzsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBOYXRpdmUgY3J5cHRvIGltcG9ydCB2aWEgcmVxdWlyZSAoTm9kZUpTKQogICAgICAgICAgaWYgKCFjcnlwdG8gJiYgdHlwZW9mIGNvbW1vbmpzUmVxdWlyZSA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgIGNyeXB0byA9IHJlcXVpcmUkJDA7CiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge30KICAgICAgICAgIH0KCiAgICAgICAgICAvKgogICAgICAgICAgICogQ3J5cHRvZ3JhcGhpY2FsbHkgc2VjdXJlIHBzZXVkb3JhbmRvbSBudW1iZXIgZ2VuZXJhdG9yCiAgICAgICAgICAgKgogICAgICAgICAgICogQXMgTWF0aC5yYW5kb20oKSBpcyBjcnlwdG9ncmFwaGljYWxseSBub3Qgc2FmZSB0byB1c2UKICAgICAgICAgICAqLwogICAgICAgICAgdmFyIGNyeXB0b1NlY3VyZVJhbmRvbUludCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgaWYgKGNyeXB0bykgewogICAgICAgICAgICAgIC8vIFVzZSBnZXRSYW5kb21WYWx1ZXMgbWV0aG9kIChCcm93c2VyKQogICAgICAgICAgICAgIGlmICh0eXBlb2YgY3J5cHRvLmdldFJhbmRvbVZhbHVlcyA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQzMkFycmF5KDEpKVswXTsKICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge30KICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFVzZSByYW5kb21CeXRlcyBtZXRob2QgKE5vZGVKUykKICAgICAgICAgICAgICBpZiAodHlwZW9mIGNyeXB0by5yYW5kb21CeXRlcyA9PT0gJ2Z1bmN0aW9uJykgewogICAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgICAgcmV0dXJuIGNyeXB0by5yYW5kb21CeXRlcyg0KS5yZWFkSW50MzJMRSgpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7fQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05hdGl2ZSBjcnlwdG8gbW9kdWxlIGNvdWxkIG5vdCBiZSB1c2VkIHRvIGdldCBzZWN1cmUgcmFuZG9tIG51bWJlci4nKTsKICAgICAgICAgIH07CgogICAgICAgICAgLyoKICAgICAgICAgICAqIExvY2FsIHBvbHlmaWxsIG9mIE9iamVjdC5jcmVhdGUKICAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBjcmVhdGUgPSBPYmplY3QuY3JlYXRlIHx8IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZnVuY3Rpb24gRigpIHt9CiAgICAgICAgICAgIHJldHVybiBmdW5jdGlvbiAob2JqKSB7CiAgICAgICAgICAgICAgdmFyIHN1YnR5cGU7CiAgICAgICAgICAgICAgRi5wcm90b3R5cGUgPSBvYmo7CiAgICAgICAgICAgICAgc3VidHlwZSA9IG5ldyBGKCk7CiAgICAgICAgICAgICAgRi5wcm90b3R5cGUgPSBudWxsOwogICAgICAgICAgICAgIHJldHVybiBzdWJ0eXBlOwogICAgICAgICAgICB9OwogICAgICAgICAgfSgpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQ3J5cHRvSlMgbmFtZXNwYWNlLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgQyA9IHt9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogTGlicmFyeSBuYW1lc3BhY2UuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliID0ge307CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBCYXNlIG9iamVjdCBmb3IgcHJvdG90eXBhbCBpbmhlcml0YW5jZS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAqIENyZWF0ZXMgYSBuZXcgb2JqZWN0IHRoYXQgaW5oZXJpdHMgZnJvbSB0aGlzIG9iamVjdC4KICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvdmVycmlkZXMgUHJvcGVydGllcyB0byBjb3B5IGludG8gdGhlIG5ldyBvYmplY3QuCiAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBuZXcgb2JqZWN0LgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqICAgICB2YXIgTXlUeXBlID0gQ3J5cHRvSlMubGliLkJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgICAgKiAgICAgICAgIGZpZWxkOiAndmFsdWUnLAogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogICAgICAgICBtZXRob2Q6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgKiAgICAgICAgIH0KICAgICAgICAgICAgICAgKiAgICAgfSk7CiAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgZXh0ZW5kOiBmdW5jdGlvbiAob3ZlcnJpZGVzKSB7CiAgICAgICAgICAgICAgICAvLyBTcGF3bgogICAgICAgICAgICAgICAgdmFyIHN1YnR5cGUgPSBjcmVhdGUodGhpcyk7CgogICAgICAgICAgICAgICAgLy8gQXVnbWVudAogICAgICAgICAgICAgICAgaWYgKG92ZXJyaWRlcykgewogICAgICAgICAgICAgICAgICBzdWJ0eXBlLm1peEluKG92ZXJyaWRlcyk7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGRlZmF1bHQgaW5pdGlhbGl6ZXIKICAgICAgICAgICAgICAgIGlmICghc3VidHlwZS5oYXNPd25Qcm9wZXJ0eSgnaW5pdCcpIHx8IHRoaXMuaW5pdCA9PT0gc3VidHlwZS5pbml0KSB7CiAgICAgICAgICAgICAgICAgIHN1YnR5cGUuaW5pdCA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlLiRzdXBlci5pbml0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7CiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZXIncyBwcm90b3R5cGUgaXMgdGhlIHN1YnR5cGUgb2JqZWN0CiAgICAgICAgICAgICAgICBzdWJ0eXBlLmluaXQucHJvdG90eXBlID0gc3VidHlwZTsKCiAgICAgICAgICAgICAgICAvLyBSZWZlcmVuY2Ugc3VwZXJ0eXBlCiAgICAgICAgICAgICAgICBzdWJ0eXBlLiRzdXBlciA9IHRoaXM7CiAgICAgICAgICAgICAgICByZXR1cm4gc3VidHlwZTsKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAqIEV4dGVuZHMgdGhpcyBvYmplY3QgYW5kIHJ1bnMgdGhlIGluaXQgbWV0aG9kLgogICAgICAgICAgICAgICAqIEFyZ3VtZW50cyB0byBjcmVhdGUoKSB3aWxsIGJlIHBhc3NlZCB0byBpbml0KCkuCiAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IFRoZSBuZXcgb2JqZWN0LgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqICAgICB2YXIgaW5zdGFuY2UgPSBNeVR5cGUuY3JlYXRlKCk7CiAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgY3JlYXRlOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICB2YXIgaW5zdGFuY2UgPSB0aGlzLmV4dGVuZCgpOwogICAgICAgICAgICAgICAgaW5zdGFuY2UuaW5pdC5hcHBseShpbnN0YW5jZSwgYXJndW1lbnRzKTsKICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZTsKICAgICAgICAgICAgICB9LAogICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBvYmplY3QuCiAgICAgICAgICAgICAgICogT3ZlcnJpZGUgdGhpcyBtZXRob2QgdG8gYWRkIHNvbWUgbG9naWMgd2hlbiB5b3VyIG9iamVjdHMgYXJlIGNyZWF0ZWQuCiAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogICAgIHZhciBNeVR5cGUgPSBDcnlwdG9KUy5saWIuQmFzZS5leHRlbmQoewogICAgICAgICAgICAgICAqICAgICAgICAgaW5pdDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgICAqICAgICAgICAgICAgIC8vIC4uLgogICAgICAgICAgICAgICAqICAgICAgICAgfQogICAgICAgICAgICAgICAqICAgICB9KTsKICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICBpbml0OiBmdW5jdGlvbiAoKSB7fSwKICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgKiBDb3BpZXMgcHJvcGVydGllcyBpbnRvIHRoaXMgb2JqZWN0LgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IHByb3BlcnRpZXMgVGhlIHByb3BlcnRpZXMgdG8gbWl4IGluLgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqICAgICBNeVR5cGUubWl4SW4oewogICAgICAgICAgICAgICAqICAgICAgICAgZmllbGQ6ICd2YWx1ZScKICAgICAgICAgICAgICAgKiAgICAgfSk7CiAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgbWl4SW46IGZ1bmN0aW9uIChwcm9wZXJ0aWVzKSB7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBwcm9wZXJ0eU5hbWUgaW4gcHJvcGVydGllcykgewogICAgICAgICAgICAgICAgICBpZiAocHJvcGVydGllcy5oYXNPd25Qcm9wZXJ0eShwcm9wZXJ0eU5hbWUpKSB7CiAgICAgICAgICAgICAgICAgICAgdGhpc1twcm9wZXJ0eU5hbWVdID0gcHJvcGVydGllc1twcm9wZXJ0eU5hbWVdOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gSUUgd29uJ3QgY29weSB0b1N0cmluZyB1c2luZyB0aGUgbG9vcCBhYm92ZQogICAgICAgICAgICAgICAgaWYgKHByb3BlcnRpZXMuaGFzT3duUHJvcGVydHkoJ3RvU3RyaW5nJykpIHsKICAgICAgICAgICAgICAgICAgdGhpcy50b1N0cmluZyA9IHByb3BlcnRpZXMudG9TdHJpbmc7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfSwKICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIG9iamVjdC4KICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gVGhlIGNsb25lLgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqICAgICB2YXIgY2xvbmUgPSBpbnN0YW5jZS5jbG9uZSgpOwogICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbml0LnByb3RvdHlwZS5leHRlbmQodGhpcyk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9OwogICAgICAgICAgfSgpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQW4gYXJyYXkgb2YgMzItYml0IHdvcmRzLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHdvcmRzIFRoZSBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gc2lnQnl0ZXMgVGhlIG51bWJlciBvZiBzaWduaWZpY2FudCBieXRlcyBpbiB0aGlzIHdvcmQgYXJyYXkuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXkgPSBCYXNlLmV4dGVuZCh7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgKE9wdGlvbmFsKSBBbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzaWdCeXRlcyAoT3B0aW9uYWwpIFRoZSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgYnl0ZXMgaW4gdGhlIHdvcmRzLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKCk7CiAgICAgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMubGliLldvcmRBcnJheS5jcmVhdGUoWzB4MDAwMTAyMDMsIDB4MDQwNTA2MDddKTsKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbMHgwMDAxMDIwMywgMHgwNDA1MDYwN10sIDYpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKHdvcmRzLCBzaWdCeXRlcykgewogICAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdOwogICAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQkMSkgewogICAgICAgICAgICAgICAgdGhpcy5zaWdCeXRlcyA9IHNpZ0J5dGVzOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLnNpZ0J5dGVzID0gd29yZHMubGVuZ3RoICogNDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIHdvcmQgYXJyYXkgdG8gYSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7RW5jb2Rlcn0gZW5jb2RlciAoT3B0aW9uYWwpIFRoZSBlbmNvZGluZyBzdHJhdGVneSB0byB1c2UuIERlZmF1bHQ6IENyeXB0b0pTLmVuYy5IZXgKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3RyaW5naWZpZWQgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkgKyAnJzsKICAgICAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkudG9TdHJpbmcoKTsKICAgICAgICAgICAgICogICAgIHZhciBzdHJpbmcgPSB3b3JkQXJyYXkudG9TdHJpbmcoQ3J5cHRvSlMuZW5jLlV0ZjgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdG9TdHJpbmc6IGZ1bmN0aW9uIChlbmNvZGVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIChlbmNvZGVyIHx8IEhleCkuc3RyaW5naWZ5KHRoaXMpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29uY2F0ZW5hdGVzIGEgd29yZCBhcnJheSB0byB0aGlzIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkgdG8gYXBwZW5kLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoaXMgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHdvcmRBcnJheTEuY29uY2F0KHdvcmRBcnJheTIpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY29uY2F0OiBmdW5jdGlvbiAod29yZEFycmF5KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHRoaXNXb3JkcyA9IHRoaXMud29yZHM7CiAgICAgICAgICAgICAgdmFyIHRoYXRXb3JkcyA9IHdvcmRBcnJheS53b3JkczsKICAgICAgICAgICAgICB2YXIgdGhpc1NpZ0J5dGVzID0gdGhpcy5zaWdCeXRlczsKICAgICAgICAgICAgICB2YXIgdGhhdFNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzOwoKICAgICAgICAgICAgICAvLyBDbGFtcCBleGNlc3MgYml0cwogICAgICAgICAgICAgIHRoaXMuY2xhbXAoKTsKCiAgICAgICAgICAgICAgLy8gQ29uY2F0CiAgICAgICAgICAgICAgaWYgKHRoaXNTaWdCeXRlcyAlIDQpIHsKICAgICAgICAgICAgICAgIC8vIENvcHkgb25lIGJ5dGUgYXQgYSB0aW1lCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoYXRTaWdCeXRlczsgaSsrKSB7CiAgICAgICAgICAgICAgICAgIHZhciB0aGF0Qnl0ZSA9IHRoYXRXb3Jkc1tpID4+PiAyXSA+Pj4gMjQgLSBpICUgNCAqIDggJiAweGZmOwogICAgICAgICAgICAgICAgICB0aGlzV29yZHNbdGhpc1NpZ0J5dGVzICsgaSA+Pj4gMl0gfD0gdGhhdEJ5dGUgPDwgMjQgLSAodGhpc1NpZ0J5dGVzICsgaSkgJSA0ICogODsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLy8gQ29weSBvbmUgd29yZCBhdCBhIHRpbWUKICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgdGhhdFNpZ0J5dGVzOyBqICs9IDQpIHsKICAgICAgICAgICAgICAgICAgdGhpc1dvcmRzW3RoaXNTaWdCeXRlcyArIGogPj4+IDJdID0gdGhhdFdvcmRzW2ogPj4+IDJdOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB0aGlzLnNpZ0J5dGVzICs9IHRoYXRTaWdCeXRlczsKCiAgICAgICAgICAgICAgLy8gQ2hhaW5hYmxlCiAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZW1vdmVzIGluc2lnbmlmaWNhbnQgYml0cy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHdvcmRBcnJheS5jbGFtcCgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2xhbXA6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgd29yZHMgPSB0aGlzLndvcmRzOwogICAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHRoaXMuc2lnQnl0ZXM7CgogICAgICAgICAgICAgIC8vIENsYW1wCiAgICAgICAgICAgICAgd29yZHNbc2lnQnl0ZXMgPj4+IDJdICY9IDB4ZmZmZmZmZmYgPDwgMzIgLSBzaWdCeXRlcyAlIDQgKiA4OwogICAgICAgICAgICAgIHdvcmRzLmxlbmd0aCA9IE1hdGguY2VpbChzaWdCeXRlcyAvIDQpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBjbG9uZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBjbG9uZSA9IHdvcmRBcnJheS5jbG9uZSgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgY2xvbmUgPSBCYXNlLmNsb25lLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgY2xvbmUud29yZHMgPSB0aGlzLndvcmRzLnNsaWNlKDApOwogICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENyZWF0ZXMgYSB3b3JkIGFycmF5IGZpbGxlZCB3aXRoIHJhbmRvbSBieXRlcy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG5CeXRlcyBUaGUgbnVtYmVyIG9mIHJhbmRvbSBieXRlcyB0byBnZW5lcmF0ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcmFuZG9tIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbSgxNik7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICByYW5kb206IGZ1bmN0aW9uIChuQnl0ZXMpIHsKICAgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5CeXRlczsgaSArPSA0KSB7CiAgICAgICAgICAgICAgICB3b3Jkcy5wdXNoKGNyeXB0b1NlY3VyZVJhbmRvbUludCgpKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIG5ldyBXb3JkQXJyYXkuaW5pdCh3b3JkcywgbkJ5dGVzKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBFbmNvZGVyIG5hbWVzcGFjZS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIENfZW5jID0gQy5lbmMgPSB7fTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEhleCBlbmNvZGluZyBzdHJhdGVneS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIEhleCA9IENfZW5jLkhleCA9IHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIGhleCBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGhleCBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBoZXhTdHJpbmcgPSBDcnlwdG9KUy5lbmMuSGV4LnN0cmluZ2lmeSh3b3JkQXJyYXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzOwogICAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlczsKCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHZhciBoZXhDaGFycyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGJpdGUgPSB3b3Jkc1tpID4+PiAyXSA+Pj4gMjQgLSBpICUgNCAqIDggJiAweGZmOwogICAgICAgICAgICAgICAgaGV4Q2hhcnMucHVzaCgoYml0ZSA+Pj4gNCkudG9TdHJpbmcoMTYpKTsKICAgICAgICAgICAgICAgIGhleENoYXJzLnB1c2goKGJpdGUgJiAweDBmKS50b1N0cmluZygxNikpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gaGV4Q2hhcnMuam9pbignJyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBhIGhleCBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gaGV4U3RyIFRoZSBoZXggc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMuZW5jLkhleC5wYXJzZShoZXhTdHJpbmcpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChoZXhTdHIpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBoZXhTdHJMZW5ndGggPSBoZXhTdHIubGVuZ3RoOwoKICAgICAgICAgICAgICAvLyBDb252ZXJ0CiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZXhTdHJMZW5ndGg7IGkgKz0gMikgewogICAgICAgICAgICAgICAgd29yZHNbaSA+Pj4gM10gfD0gcGFyc2VJbnQoaGV4U3RyLnN1YnN0cihpLCAyKSwgMTYpIDw8IDI0IC0gaSAlIDggKiA0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHdvcmRzLCBoZXhTdHJMZW5ndGggLyAyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIExhdGluMSBlbmNvZGluZyBzdHJhdGVneS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIExhdGluMSA9IENfZW5jLkxhdGluMSA9IHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIExhdGluMSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSB3b3JkQXJyYXkgVGhlIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIExhdGluMSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBsYXRpbjFTdHJpbmcgPSBDcnlwdG9KUy5lbmMuTGF0aW4xLnN0cmluZ2lmeSh3b3JkQXJyYXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzOwogICAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlczsKCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHZhciBsYXRpbjFDaGFycyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2lnQnl0ZXM7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGJpdGUgPSB3b3Jkc1tpID4+PiAyXSA+Pj4gMjQgLSBpICUgNCAqIDggJiAweGZmOwogICAgICAgICAgICAgICAgbGF0aW4xQ2hhcnMucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKGJpdGUpKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIGxhdGluMUNoYXJzLmpvaW4oJycpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSBMYXRpbjEgc3RyaW5nIHRvIGEgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGxhdGluMVN0ciBUaGUgTGF0aW4xIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5MYXRpbjEucGFyc2UobGF0aW4xU3RyaW5nKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAobGF0aW4xU3RyKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgbGF0aW4xU3RyTGVuZ3RoID0gbGF0aW4xU3RyLmxlbmd0aDsKCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGF0aW4xU3RyTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHdvcmRzW2kgPj4+IDJdIHw9IChsYXRpbjFTdHIuY2hhckNvZGVBdChpKSAmIDB4ZmYpIDw8IDI0IC0gaSAlIDQgKiA4OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHdvcmRzLCBsYXRpbjFTdHJMZW5ndGgpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogVVRGLTggZW5jb2Rpbmcgc3RyYXRlZ3kuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBVdGY4ID0gQ19lbmMuVXRmOCA9IHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGEgd29yZCBhcnJheSB0byBhIFVURi04IHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTggc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgdXRmOFN0cmluZyA9IENyeXB0b0pTLmVuYy5VdGY4LnN0cmluZ2lmeSh3b3JkQXJyYXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7CiAgICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICAgIHJldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKExhdGluMS5zdHJpbmdpZnkod29yZEFycmF5KSkpOwogICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTWFsZm9ybWVkIFVURi04IGRhdGEnKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi04IHN0cmluZyB0byBhIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSB1dGY4U3RyIFRoZSBVVEYtOCBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuVXRmOC5wYXJzZSh1dGY4U3RyaW5nKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAodXRmOFN0cikgewogICAgICAgICAgICAgIHJldHVybiBMYXRpbjEucGFyc2UodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHV0ZjhTdHIpKSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBBYnN0cmFjdCBidWZmZXJlZCBibG9jayBhbGdvcml0aG0gdGVtcGxhdGUuCiAgICAgICAgICAgKgogICAgICAgICAgICogVGhlIHByb3BlcnR5IGJsb2NrU2l6ZSBtdXN0IGJlIGltcGxlbWVudGVkIGluIGEgY29uY3JldGUgc3VidHlwZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gX21pbkJ1ZmZlclNpemUgVGhlIG51bWJlciBvZiBibG9ja3MgdGhhdCBzaG91bGQgYmUga2VwdCB1bnByb2Nlc3NlZCBpbiB0aGUgYnVmZmVyLiBEZWZhdWx0OiAwCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBCdWZmZXJlZEJsb2NrQWxnb3JpdGhtID0gQ19saWIuQnVmZmVyZWRCbG9ja0FsZ29yaXRobSA9IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJlc2V0cyB0aGlzIGJsb2NrIGFsZ29yaXRobSdzIGRhdGEgYnVmZmVyIHRvIGl0cyBpbml0aWFsIHN0YXRlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5yZXNldCgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlcwogICAgICAgICAgICAgIHRoaXMuX2RhdGEgPSBuZXcgV29yZEFycmF5LmluaXQoKTsKICAgICAgICAgICAgICB0aGlzLl9uRGF0YUJ5dGVzID0gMDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEFkZHMgbmV3IGRhdGEgdG8gdGhpcyBibG9jayBhbGdvcml0aG0ncyBidWZmZXIuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gZGF0YSBUaGUgZGF0YSB0byBhcHBlbmQuIFN0cmluZ3MgYXJlIGNvbnZlcnRlZCB0byBhIFdvcmRBcnJheSB1c2luZyBVVEYtOC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIGJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uX2FwcGVuZCgnZGF0YScpOwogICAgICAgICAgICAgKiAgICAgYnVmZmVyZWRCbG9ja0FsZ29yaXRobS5fYXBwZW5kKHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBfYXBwZW5kOiBmdW5jdGlvbiAoZGF0YSkgewogICAgICAgICAgICAgIC8vIENvbnZlcnQgc3RyaW5nIHRvIFdvcmRBcnJheSwgZWxzZSBhc3N1bWUgV29yZEFycmF5IGFscmVhZHkKICAgICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgICAgIGRhdGEgPSBVdGY4LnBhcnNlKGRhdGEpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gQXBwZW5kCiAgICAgICAgICAgICAgdGhpcy5fZGF0YS5jb25jYXQoZGF0YSk7CiAgICAgICAgICAgICAgdGhpcy5fbkRhdGFCeXRlcyArPSBkYXRhLnNpZ0J5dGVzOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUHJvY2Vzc2VzIGF2YWlsYWJsZSBkYXRhIGJsb2Nrcy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogVGhpcyBtZXRob2QgaW52b2tlcyBfZG9Qcm9jZXNzQmxvY2sob2Zmc2V0KSwgd2hpY2ggbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBhIGNvbmNyZXRlIHN1YnR5cGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gZG9GbHVzaCBXaGV0aGVyIGFsbCBibG9ja3MgYW5kIHBhcnRpYWwgYmxvY2tzIHNob3VsZCBiZSBwcm9jZXNzZWQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHByb2Nlc3NlZCBkYXRhLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHByb2Nlc3NlZERhdGEgPSBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLl9wcm9jZXNzKCk7CiAgICAgICAgICAgICAqICAgICB2YXIgcHJvY2Vzc2VkRGF0YSA9IGJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uX3Byb2Nlc3MoISEnZmx1c2gnKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIF9wcm9jZXNzOiBmdW5jdGlvbiAoZG9GbHVzaCkgewogICAgICAgICAgICAgIHZhciBwcm9jZXNzZWRXb3JkczsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICAgICAgICAgIHZhciBkYXRhV29yZHMgPSBkYXRhLndvcmRzOwogICAgICAgICAgICAgIHZhciBkYXRhU2lnQnl0ZXMgPSBkYXRhLnNpZ0J5dGVzOwogICAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSB0aGlzLmJsb2NrU2l6ZTsKICAgICAgICAgICAgICB2YXIgYmxvY2tTaXplQnl0ZXMgPSBibG9ja1NpemUgKiA0OwoKICAgICAgICAgICAgICAvLyBDb3VudCBibG9ja3MgcmVhZHkKICAgICAgICAgICAgICB2YXIgbkJsb2Nrc1JlYWR5ID0gZGF0YVNpZ0J5dGVzIC8gYmxvY2tTaXplQnl0ZXM7CiAgICAgICAgICAgICAgaWYgKGRvRmx1c2gpIHsKICAgICAgICAgICAgICAgIC8vIFJvdW5kIHVwIHRvIGluY2x1ZGUgcGFydGlhbCBibG9ja3MKICAgICAgICAgICAgICAgIG5CbG9ja3NSZWFkeSA9IE1hdGguY2VpbChuQmxvY2tzUmVhZHkpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAvLyBSb3VuZCBkb3duIHRvIGluY2x1ZGUgb25seSBmdWxsIGJsb2NrcywKICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhlIG51bWJlciBvZiBibG9ja3MgdGhhdCBtdXN0IHJlbWFpbiBpbiB0aGUgYnVmZmVyCiAgICAgICAgICAgICAgICBuQmxvY2tzUmVhZHkgPSBNYXRoLm1heCgobkJsb2Nrc1JlYWR5IHwgMCkgLSB0aGlzLl9taW5CdWZmZXJTaXplLCAwKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIENvdW50IHdvcmRzIHJlYWR5CiAgICAgICAgICAgICAgdmFyIG5Xb3Jkc1JlYWR5ID0gbkJsb2Nrc1JlYWR5ICogYmxvY2tTaXplOwoKICAgICAgICAgICAgICAvLyBDb3VudCBieXRlcyByZWFkeQogICAgICAgICAgICAgIHZhciBuQnl0ZXNSZWFkeSA9IE1hdGgubWluKG5Xb3Jkc1JlYWR5ICogNCwgZGF0YVNpZ0J5dGVzKTsKCiAgICAgICAgICAgICAgLy8gUHJvY2VzcyBibG9ja3MKICAgICAgICAgICAgICBpZiAobldvcmRzUmVhZHkpIHsKICAgICAgICAgICAgICAgIGZvciAodmFyIG9mZnNldCA9IDA7IG9mZnNldCA8IG5Xb3Jkc1JlYWR5OyBvZmZzZXQgKz0gYmxvY2tTaXplKSB7CiAgICAgICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtYWxnb3JpdGhtIGxvZ2ljCiAgICAgICAgICAgICAgICAgIHRoaXMuX2RvUHJvY2Vzc0Jsb2NrKGRhdGFXb3Jkcywgb2Zmc2V0KTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgcHJvY2Vzc2VkIHdvcmRzCiAgICAgICAgICAgICAgICBwcm9jZXNzZWRXb3JkcyA9IGRhdGFXb3Jkcy5zcGxpY2UoMCwgbldvcmRzUmVhZHkpOwogICAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyAtPSBuQnl0ZXNSZWFkeTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFJldHVybiBwcm9jZXNzZWQgd29yZHMKICAgICAgICAgICAgICByZXR1cm4gbmV3IFdvcmRBcnJheS5pbml0KHByb2Nlc3NlZFdvcmRzLCBuQnl0ZXNSZWFkeSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDcmVhdGVzIGEgY29weSBvZiB0aGlzIG9iamVjdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSBUaGUgY2xvbmUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgY2xvbmUgPSBidWZmZXJlZEJsb2NrQWxnb3JpdGhtLmNsb25lKCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBjbG9uZSA9IEJhc2UuY2xvbmUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgICBjbG9uZS5fZGF0YSA9IHRoaXMuX2RhdGEuY2xvbmUoKTsKICAgICAgICAgICAgICByZXR1cm4gY2xvbmU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9taW5CdWZmZXJTaXplOiAwCiAgICAgICAgICB9KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFic3RyYWN0IGhhc2hlciB0ZW1wbGF0ZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgaGFzaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiAxNiAoNTEyIGJpdHMpCiAgICAgICAgICAgKi8KICAgICAgICAgIENfbGliLkhhc2hlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNmZzogQmFzZS5leHRlbmQoKSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBoYXNoZXIuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBoYXNoIGNvbXB1dGF0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGhhc2hlciA9IENyeXB0b0pTLmFsZ28uU0hBMjU2LmNyZWF0ZSgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKGNmZykgewogICAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0cwogICAgICAgICAgICAgIHRoaXMuY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7CgogICAgICAgICAgICAgIC8vIFNldCBpbml0aWFsIHZhbHVlcwogICAgICAgICAgICAgIHRoaXMucmVzZXQoKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJlc2V0cyB0aGlzIGhhc2hlciB0byBpdHMgaW5pdGlhbCBzdGF0ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIGhhc2hlci5yZXNldCgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBSZXNldCBkYXRhIGJ1ZmZlcgogICAgICAgICAgICAgIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0ucmVzZXQuY2FsbCh0aGlzKTsKCiAgICAgICAgICAgICAgLy8gUGVyZm9ybSBjb25jcmV0ZS1oYXNoZXIgbG9naWMKICAgICAgICAgICAgICB0aGlzLl9kb1Jlc2V0KCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBVcGRhdGVzIHRoaXMgaGFzaGVyIHdpdGggYSBtZXNzYWdlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2VVcGRhdGUgVGhlIG1lc3NhZ2UgdG8gYXBwZW5kLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtIYXNoZXJ9IFRoaXMgaGFzaGVyLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgaGFzaGVyLnVwZGF0ZSgnbWVzc2FnZScpOwogICAgICAgICAgICAgKiAgICAgaGFzaGVyLnVwZGF0ZSh3b3JkQXJyYXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkgewogICAgICAgICAgICAgIC8vIEFwcGVuZAogICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChtZXNzYWdlVXBkYXRlKTsKCiAgICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBoYXNoCiAgICAgICAgICAgICAgdGhpcy5fcHJvY2VzcygpOwoKICAgICAgICAgICAgICAvLyBDaGFpbmFibGUKICAgICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEZpbmFsaXplcyB0aGUgaGFzaCBjb21wdXRhdGlvbi4KICAgICAgICAgICAgICogTm90ZSB0aGF0IHRoZSBmaW5hbGl6ZSBvcGVyYXRpb24gaXMgZWZmZWN0aXZlbHkgYSBkZXN0cnVjdGl2ZSwgcmVhZC1vbmNlIG9wZXJhdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlVXBkYXRlIChPcHRpb25hbCkgQSBmaW5hbCBtZXNzYWdlIHVwZGF0ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgaGFzaC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBoYXNoID0gaGFzaGVyLmZpbmFsaXplKCk7CiAgICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IGhhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpOwogICAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBoYXNoZXIuZmluYWxpemUod29yZEFycmF5KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAobWVzc2FnZVVwZGF0ZSkgewogICAgICAgICAgICAgIC8vIEZpbmFsIG1lc3NhZ2UgdXBkYXRlCiAgICAgICAgICAgICAgaWYgKG1lc3NhZ2VVcGRhdGUpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChtZXNzYWdlVXBkYXRlKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtaGFzaGVyIGxvZ2ljCiAgICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9kb0ZpbmFsaXplKCk7CiAgICAgICAgICAgICAgcmV0dXJuIGhhc2g7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGJsb2NrU2l6ZTogNTEyIC8gMzIsCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDcmVhdGVzIGEgc2hvcnRjdXQgZnVuY3Rpb24gdG8gYSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoZXIgdG8gY3JlYXRlIGEgaGVscGVyIGZvci4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7RnVuY3Rpb259IFRoZSBzaG9ydGN1dCBmdW5jdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIFNIQTI1NiA9IENyeXB0b0pTLmxpYi5IYXNoZXIuX2NyZWF0ZUhlbHBlcihDcnlwdG9KUy5hbGdvLlNIQTI1Nik7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBfY3JlYXRlSGVscGVyOiBmdW5jdGlvbiAoaGFzaGVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChtZXNzYWdlLCBjZmcpIHsKICAgICAgICAgICAgICAgIHJldHVybiBuZXcgaGFzaGVyLmluaXQoY2ZnKS5maW5hbGl6ZShtZXNzYWdlKTsKICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ3JlYXRlcyBhIHNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZSBpbiB0aGlzIEhNQUMgaGVscGVyLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn0gVGhlIHNob3J0Y3V0IGZ1bmN0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgSG1hY1NIQTI1NiA9IENyeXB0b0pTLmxpYi5IYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoQ3J5cHRvSlMuYWxnby5TSEEyNTYpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgX2NyZWF0ZUhtYWNIZWxwZXI6IGZ1bmN0aW9uIChoYXNoZXIpIHsKICAgICAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1lc3NhZ2UsIGtleSkgewogICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBDX2FsZ28uSE1BQy5pbml0KGhhc2hlciwga2V5KS5maW5hbGl6ZShtZXNzYWdlKTsKICAgICAgICAgICAgICB9OwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFsZ29yaXRobSBuYW1lc3BhY2UuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ28gPSB7fTsKICAgICAgICAgIHJldHVybiBDOwogICAgICAgIH0oTWF0aCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTOwogICAgICB9KTsKICAgIH0pKGNvcmUkMSk7CiAgICByZXR1cm4gY29yZSQxLmV4cG9ydHM7CiAgfQoKICB2YXIgeDY0Q29yZSQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIHg2NENvcmUgPSB4NjRDb3JlJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRYNjRDb3JlOwogIGZ1bmN0aW9uIHJlcXVpcmVYNjRDb3JlKCkgewogICAgaWYgKGhhc1JlcXVpcmVkWDY0Q29yZSkgcmV0dXJuIHg2NENvcmUkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRYNjRDb3JlID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHg2NENvcmUsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAodW5kZWZpbmVkJDEpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIEJhc2UgPSBDX2xpYi5CYXNlOwogICAgICAgICAgdmFyIFgzMldvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIHg2NCBuYW1lc3BhY2UuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDX3g2NCA9IEMueDY0ID0ge307CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBBIDY0LWJpdCB3b3JkLgogICAgICAgICAgICovCiAgICAgICAgICBDX3g2NC5Xb3JkID0gQmFzZS5leHRlbmQoewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIDY0LWJpdCB3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gaGlnaCBUaGUgaGlnaCAzMiBiaXRzLgogICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbG93IFRoZSBsb3cgMzIgYml0cy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB4NjRXb3JkID0gQ3J5cHRvSlMueDY0LldvcmQuY3JlYXRlKDB4MDAwMTAyMDMsIDB4MDQwNTA2MDcpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKGhpZ2gsIGxvdykgewogICAgICAgICAgICAgIHRoaXMuaGlnaCA9IGhpZ2g7CiAgICAgICAgICAgICAgdGhpcy5sb3cgPSBsb3c7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBCaXR3aXNlIE5PVHMgdGhpcyB3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtYNjRXb3JkfSBBIG5ldyB4NjQtV29yZCBvYmplY3QgYWZ0ZXIgbmVnYXRpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgbmVnYXRlZCA9IHg2NFdvcmQubm90KCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICAvLyBub3Q6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSB+dGhpcy5oaWdoOwogICAgICAgICAgICAvLyB2YXIgbG93ID0gfnRoaXMubG93OwoKICAgICAgICAgICAgLy8gcmV0dXJuIFg2NFdvcmQuY3JlYXRlKGhpZ2gsIGxvdyk7CiAgICAgICAgICAgIC8vIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQml0d2lzZSBBTkRzIHRoaXMgd29yZCB3aXRoIHRoZSBwYXNzZWQgd29yZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtYNjRXb3JkfSB3b3JkIFRoZSB4NjQtV29yZCB0byBBTkQgd2l0aCB0aGlzIHdvcmQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1g2NFdvcmR9IEEgbmV3IHg2NC1Xb3JkIG9iamVjdCBhZnRlciBBTkRpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgYW5kZWQgPSB4NjRXb3JkLmFuZChhbm90aGVyWDY0V29yZCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICAvLyBhbmQ6IGZ1bmN0aW9uICh3b3JkKSB7CiAgICAgICAgICAgIC8vIHZhciBoaWdoID0gdGhpcy5oaWdoICYgd29yZC5oaWdoOwogICAgICAgICAgICAvLyB2YXIgbG93ID0gdGhpcy5sb3cgJiB3b3JkLmxvdzsKCiAgICAgICAgICAgIC8vIHJldHVybiBYNjRXb3JkLmNyZWF0ZShoaWdoLCBsb3cpOwogICAgICAgICAgICAvLyB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEJpdHdpc2UgT1JzIHRoaXMgd29yZCB3aXRoIHRoZSBwYXNzZWQgd29yZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtYNjRXb3JkfSB3b3JkIFRoZSB4NjQtV29yZCB0byBPUiB3aXRoIHRoaXMgd29yZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIE9SaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIG9yZWQgPSB4NjRXb3JkLm9yKGFub3RoZXJYNjRXb3JkKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIC8vIG9yOiBmdW5jdGlvbiAod29yZCkgewogICAgICAgICAgICAvLyB2YXIgaGlnaCA9IHRoaXMuaGlnaCB8IHdvcmQuaGlnaDsKICAgICAgICAgICAgLy8gdmFyIGxvdyA9IHRoaXMubG93IHwgd29yZC5sb3c7CgogICAgICAgICAgICAvLyByZXR1cm4gWDY0V29yZC5jcmVhdGUoaGlnaCwgbG93KTsKICAgICAgICAgICAgLy8gfSwKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBCaXR3aXNlIFhPUnMgdGhpcyB3b3JkIHdpdGggdGhlIHBhc3NlZCB3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1g2NFdvcmR9IHdvcmQgVGhlIHg2NC1Xb3JkIHRvIFhPUiB3aXRoIHRoaXMgd29yZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIFhPUmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB4b3JlZCA9IHg2NFdvcmQueG9yKGFub3RoZXJYNjRXb3JkKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIC8vIHhvcjogZnVuY3Rpb24gKHdvcmQpIHsKICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSB0aGlzLmhpZ2ggXiB3b3JkLmhpZ2g7CiAgICAgICAgICAgIC8vIHZhciBsb3cgPSB0aGlzLmxvdyBeIHdvcmQubG93OwoKICAgICAgICAgICAgLy8gcmV0dXJuIFg2NFdvcmQuY3JlYXRlKGhpZ2gsIGxvdyk7CiAgICAgICAgICAgIC8vIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2hpZnRzIHRoaXMgd29yZCBuIGJpdHMgdG8gdGhlIGxlZnQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byBzaGlmdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIHNoaWZ0aW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHNoaWZ0ZWQgPSB4NjRXb3JkLnNoaWZ0TCgyNSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICAvLyBzaGlmdEw6IGZ1bmN0aW9uIChuKSB7CiAgICAgICAgICAgIC8vIGlmIChuIDwgMzIpIHsKICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSAodGhpcy5oaWdoIDw8IG4pIHwgKHRoaXMubG93ID4+PiAoMzIgLSBuKSk7CiAgICAgICAgICAgIC8vIHZhciBsb3cgPSB0aGlzLmxvdyA8PCBuOwogICAgICAgICAgICAvLyB9IGVsc2UgewogICAgICAgICAgICAvLyB2YXIgaGlnaCA9IHRoaXMubG93IDw8IChuIC0gMzIpOwogICAgICAgICAgICAvLyB2YXIgbG93ID0gMDsKICAgICAgICAgICAgLy8gfQoKICAgICAgICAgICAgLy8gcmV0dXJuIFg2NFdvcmQuY3JlYXRlKGhpZ2gsIGxvdyk7CiAgICAgICAgICAgIC8vIH0sCgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogU2hpZnRzIHRoaXMgd29yZCBuIGJpdHMgdG8gdGhlIHJpZ2h0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIGJpdHMgdG8gc2hpZnQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1g2NFdvcmR9IEEgbmV3IHg2NC1Xb3JkIG9iamVjdCBhZnRlciBzaGlmdGluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBzaGlmdGVkID0geDY0V29yZC5zaGlmdFIoNyk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICAvLyBzaGlmdFI6IGZ1bmN0aW9uIChuKSB7CiAgICAgICAgICAgIC8vIGlmIChuIDwgMzIpIHsKICAgICAgICAgICAgLy8gdmFyIGxvdyA9ICh0aGlzLmxvdyA+Pj4gbikgfCAodGhpcy5oaWdoIDw8ICgzMiAtIG4pKTsKICAgICAgICAgICAgLy8gdmFyIGhpZ2ggPSB0aGlzLmhpZ2ggPj4+IG47CiAgICAgICAgICAgIC8vIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIHZhciBsb3cgPSB0aGlzLmhpZ2ggPj4+IChuIC0gMzIpOwogICAgICAgICAgICAvLyB2YXIgaGlnaCA9IDA7CiAgICAgICAgICAgIC8vIH0KCiAgICAgICAgICAgIC8vIHJldHVybiBYNjRXb3JkLmNyZWF0ZShoaWdoLCBsb3cpOwogICAgICAgICAgICAvLyB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJvdGF0ZXMgdGhpcyB3b3JkIG4gYml0cyB0byB0aGUgbGVmdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG4gVGhlIG51bWJlciBvZiBiaXRzIHRvIHJvdGF0ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIHJvdGF0aW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHJvdGF0ZWQgPSB4NjRXb3JkLnJvdEwoMjUpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgLy8gcm90TDogZnVuY3Rpb24gKG4pIHsKICAgICAgICAgICAgLy8gcmV0dXJuIHRoaXMuc2hpZnRMKG4pLm9yKHRoaXMuc2hpZnRSKDY0IC0gbikpOwogICAgICAgICAgICAvLyB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFJvdGF0ZXMgdGhpcyB3b3JkIG4gYml0cyB0byB0aGUgcmlnaHQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBuIFRoZSBudW1iZXIgb2YgYml0cyB0byByb3RhdGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1g2NFdvcmR9IEEgbmV3IHg2NC1Xb3JkIG9iamVjdCBhZnRlciByb3RhdGluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciByb3RhdGVkID0geDY0V29yZC5yb3RSKDcpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgLy8gcm90UjogZnVuY3Rpb24gKG4pIHsKICAgICAgICAgICAgLy8gcmV0dXJuIHRoaXMuc2hpZnRSKG4pLm9yKHRoaXMuc2hpZnRMKDY0IC0gbikpOwogICAgICAgICAgICAvLyB9LAoKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEFkZHMgdGhpcyB3b3JkIHdpdGggdGhlIHBhc3NlZCB3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1g2NFdvcmR9IHdvcmQgVGhlIHg2NC1Xb3JkIHRvIGFkZCB3aXRoIHRoaXMgd29yZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7WDY0V29yZH0gQSBuZXcgeDY0LVdvcmQgb2JqZWN0IGFmdGVyIGFkZGluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBhZGRlZCA9IHg2NFdvcmQuYWRkKGFub3RoZXJYNjRXb3JkKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIC8vIGFkZDogZnVuY3Rpb24gKHdvcmQpIHsKICAgICAgICAgICAgLy8gdmFyIGxvdyA9ICh0aGlzLmxvdyArIHdvcmQubG93KSB8IDA7CiAgICAgICAgICAgIC8vIHZhciBjYXJyeSA9IChsb3cgPj4+IDApIDwgKHRoaXMubG93ID4+PiAwKSA/IDEgOiAwOwogICAgICAgICAgICAvLyB2YXIgaGlnaCA9ICh0aGlzLmhpZ2ggKyB3b3JkLmhpZ2ggKyBjYXJyeSkgfCAwOwoKICAgICAgICAgICAgLy8gcmV0dXJuIFg2NFdvcmQuY3JlYXRlKGhpZ2gsIGxvdyk7CiAgICAgICAgICAgIC8vIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQW4gYXJyYXkgb2YgNjQtYml0IHdvcmRzLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwcm9wZXJ0eSB7QXJyYXl9IHdvcmRzIFRoZSBhcnJheSBvZiBDcnlwdG9KUy54NjQuV29yZCBvYmplY3RzLgogICAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IHNpZ0J5dGVzIFRoZSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgYnl0ZXMgaW4gdGhpcyB3b3JkIGFycmF5LgogICAgICAgICAgICovCiAgICAgICAgICBDX3g2NC5Xb3JkQXJyYXkgPSBCYXNlLmV4dGVuZCh7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgKE9wdGlvbmFsKSBBbiBhcnJheSBvZiBDcnlwdG9KUy54NjQuV29yZCBvYmplY3RzLgogICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gc2lnQnl0ZXMgKE9wdGlvbmFsKSBUaGUgbnVtYmVyIG9mIHNpZ25pZmljYW50IGJ5dGVzIGluIHRoZSB3b3Jkcy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy54NjQuV29yZEFycmF5LmNyZWF0ZSgpOwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLng2NC5Xb3JkQXJyYXkuY3JlYXRlKFsKICAgICAgICAgICAgICogICAgICAgICBDcnlwdG9KUy54NjQuV29yZC5jcmVhdGUoMHgwMDAxMDIwMywgMHgwNDA1MDYwNyksCiAgICAgICAgICAgICAqICAgICAgICAgQ3J5cHRvSlMueDY0LldvcmQuY3JlYXRlKDB4MTgxOTFhMWIsIDB4MWMxZDFlMWYpCiAgICAgICAgICAgICAqICAgICBdKTsKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy54NjQuV29yZEFycmF5LmNyZWF0ZShbCiAgICAgICAgICAgICAqICAgICAgICAgQ3J5cHRvSlMueDY0LldvcmQuY3JlYXRlKDB4MDAwMTAyMDMsIDB4MDQwNTA2MDcpLAogICAgICAgICAgICAgKiAgICAgICAgIENyeXB0b0pTLng2NC5Xb3JkLmNyZWF0ZSgweDE4MTkxYTFiLCAweDFjMWQxZTFmKQogICAgICAgICAgICAgKiAgICAgXSwgMTApOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKHdvcmRzLCBzaWdCeXRlcykgewogICAgICAgICAgICAgIHdvcmRzID0gdGhpcy53b3JkcyA9IHdvcmRzIHx8IFtdOwogICAgICAgICAgICAgIGlmIChzaWdCeXRlcyAhPSB1bmRlZmluZWQkMSkgewogICAgICAgICAgICAgICAgdGhpcy5zaWdCeXRlcyA9IHNpZ0J5dGVzOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLnNpZ0J5dGVzID0gd29yZHMubGVuZ3RoICogODsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyB0aGlzIDY0LWJpdCB3b3JkIGFycmF5IHRvIGEgMzItYml0IHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge0NyeXB0b0pTLmxpYi5Xb3JkQXJyYXl9IFRoaXMgd29yZCBhcnJheSdzIGRhdGEgYXMgYSAzMi1iaXQgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB4MzJXb3JkQXJyYXkgPSB4NjRXb3JkQXJyYXkudG9YMzIoKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHRvWDMyOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHg2NFdvcmRzID0gdGhpcy53b3JkczsKICAgICAgICAgICAgICB2YXIgeDY0V29yZHNMZW5ndGggPSB4NjRXb3Jkcy5sZW5ndGg7CgogICAgICAgICAgICAgIC8vIENvbnZlcnQKICAgICAgICAgICAgICB2YXIgeDMyV29yZHMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHg2NFdvcmRzTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciB4NjRXb3JkID0geDY0V29yZHNbaV07CiAgICAgICAgICAgICAgICB4MzJXb3Jkcy5wdXNoKHg2NFdvcmQuaGlnaCk7CiAgICAgICAgICAgICAgICB4MzJXb3Jkcy5wdXNoKHg2NFdvcmQubG93KTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIFgzMldvcmRBcnJheS5jcmVhdGUoeDMyV29yZHMsIHRoaXMuc2lnQnl0ZXMpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ3JlYXRlcyBhIGNvcHkgb2YgdGhpcyB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtYNjRXb3JkQXJyYXl9IFRoZSBjbG9uZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBjbG9uZSA9IHg2NFdvcmRBcnJheS5jbG9uZSgpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgY2xvbmUgPSBCYXNlLmNsb25lLmNhbGwodGhpcyk7CgogICAgICAgICAgICAgIC8vIENsb25lICJ3b3JkcyIgYXJyYXkKICAgICAgICAgICAgICB2YXIgd29yZHMgPSBjbG9uZS53b3JkcyA9IHRoaXMud29yZHMuc2xpY2UoMCk7CgogICAgICAgICAgICAgIC8vIENsb25lIGVhY2ggWDY0V29yZCBvYmplY3QKICAgICAgICAgICAgICB2YXIgd29yZHNMZW5ndGggPSB3b3Jkcy5sZW5ndGg7CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB3b3Jkc0xlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB3b3Jkc1tpXSA9IHdvcmRzW2ldLmNsb25lKCk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlM7CiAgICAgIH0pOwogICAgfSkoeDY0Q29yZSQxKTsKICAgIHJldHVybiB4NjRDb3JlJDEuZXhwb3J0czsKICB9CgogIHZhciBsaWJUeXBlZGFycmF5cyQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIGxpYlR5cGVkYXJyYXlzID0gbGliVHlwZWRhcnJheXMkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZExpYlR5cGVkYXJyYXlzOwogIGZ1bmN0aW9uIHJlcXVpcmVMaWJUeXBlZGFycmF5cygpIHsKICAgIGlmIChoYXNSZXF1aXJlZExpYlR5cGVkYXJyYXlzKSByZXR1cm4gbGliVHlwZWRhcnJheXMkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRMaWJUeXBlZGFycmF5cyA9IDE7CiAgICAoZnVuY3Rpb24gKG1vZHVsZSwgZXhwb3J0cyQxKSB7CiAgICAgIChmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShsaWJUeXBlZGFycmF5cywgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIENoZWNrIGlmIHR5cGVkIGFycmF5cyBhcmUgc3VwcG9ydGVkCiAgICAgICAgICBpZiAodHlwZW9mIEFycmF5QnVmZmVyICE9ICdmdW5jdGlvbicpIHsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKCiAgICAgICAgICAvLyBSZWZlcmVuY2Ugb3JpZ2luYWwgaW5pdAogICAgICAgICAgdmFyIHN1cGVySW5pdCA9IFdvcmRBcnJheS5pbml0OwoKICAgICAgICAgIC8vIEF1Z21lbnQgV29yZEFycmF5LmluaXQgdG8gaGFuZGxlIHR5cGVkIGFycmF5cwogICAgICAgICAgdmFyIHN1YkluaXQgPSBXb3JkQXJyYXkuaW5pdCA9IGZ1bmN0aW9uICh0eXBlZEFycmF5KSB7CiAgICAgICAgICAgIC8vIENvbnZlcnQgYnVmZmVycyB0byB1aW50OAogICAgICAgICAgICBpZiAodHlwZWRBcnJheSBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7CiAgICAgICAgICAgICAgdHlwZWRBcnJheSA9IG5ldyBVaW50OEFycmF5KHR5cGVkQXJyYXkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDb252ZXJ0IG90aGVyIGFycmF5IHZpZXdzIHRvIHVpbnQ4CiAgICAgICAgICAgIGlmICh0eXBlZEFycmF5IGluc3RhbmNlb2YgSW50OEFycmF5IHx8IHR5cGVvZiBVaW50OENsYW1wZWRBcnJheSAhPT0gInVuZGVmaW5lZCIgJiYgdHlwZWRBcnJheSBpbnN0YW5jZW9mIFVpbnQ4Q2xhbXBlZEFycmF5IHx8IHR5cGVkQXJyYXkgaW5zdGFuY2VvZiBJbnQxNkFycmF5IHx8IHR5cGVkQXJyYXkgaW5zdGFuY2VvZiBVaW50MTZBcnJheSB8fCB0eXBlZEFycmF5IGluc3RhbmNlb2YgSW50MzJBcnJheSB8fCB0eXBlZEFycmF5IGluc3RhbmNlb2YgVWludDMyQXJyYXkgfHwgdHlwZWRBcnJheSBpbnN0YW5jZW9mIEZsb2F0MzJBcnJheSB8fCB0eXBlZEFycmF5IGluc3RhbmNlb2YgRmxvYXQ2NEFycmF5KSB7CiAgICAgICAgICAgICAgdHlwZWRBcnJheSA9IG5ldyBVaW50OEFycmF5KHR5cGVkQXJyYXkuYnVmZmVyLCB0eXBlZEFycmF5LmJ5dGVPZmZzZXQsIHR5cGVkQXJyYXkuYnl0ZUxlbmd0aCk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIEhhbmRsZSBVaW50OEFycmF5CiAgICAgICAgICAgIGlmICh0eXBlZEFycmF5IGluc3RhbmNlb2YgVWludDhBcnJheSkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgdmFyIHR5cGVkQXJyYXlCeXRlTGVuZ3RoID0gdHlwZWRBcnJheS5ieXRlTGVuZ3RoOwoKICAgICAgICAgICAgICAvLyBFeHRyYWN0IGJ5dGVzCiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlZEFycmF5Qnl0ZUxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgICB3b3Jkc1tpID4+PiAyXSB8PSB0eXBlZEFycmF5W2ldIDw8IDI0IC0gaSAlIDQgKiA4OwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGlzIHdvcmQgYXJyYXkKICAgICAgICAgICAgICBzdXBlckluaXQuY2FsbCh0aGlzLCB3b3JkcywgdHlwZWRBcnJheUJ5dGVMZW5ndGgpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIC8vIEVsc2UgY2FsbCBub3JtYWwgaW5pdAogICAgICAgICAgICAgIHN1cGVySW5pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwogICAgICAgICAgc3ViSW5pdC5wcm90b3R5cGUgPSBXb3JkQXJyYXk7CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMubGliLldvcmRBcnJheTsKICAgICAgfSk7CiAgICB9KShsaWJUeXBlZGFycmF5cyQxKTsKICAgIHJldHVybiBsaWJUeXBlZGFycmF5cyQxLmV4cG9ydHM7CiAgfQoKICB2YXIgZW5jVXRmMTYkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBlbmNVdGYxNiA9IGVuY1V0ZjE2JDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRFbmNVdGYxNjsKICBmdW5jdGlvbiByZXF1aXJlRW5jVXRmMTYoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRFbmNVdGYxNikgcmV0dXJuIGVuY1V0ZjE2JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkRW5jVXRmMTYgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHsKICAgICAgICB7CiAgICAgICAgICAvLyBDb21tb25KUwogICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmVDb3JlKCkpOwogICAgICAgIH0KICAgICAgfSkoZW5jVXRmMTYsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgQ19lbmMgPSBDLmVuYzsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFVURi0xNiBCRSBlbmNvZGluZyBzdHJhdGVneS4KICAgICAgICAgICAqLwogICAgICAgICAgQ19lbmMuVXRmMTYgPSBDX2VuYy5VdGYxNkJFID0gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgVVRGLTE2IEJFIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTE2IEJFIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHV0ZjE2U3RyaW5nID0gQ3J5cHRvSlMuZW5jLlV0ZjE2LnN0cmluZ2lmeSh3b3JkQXJyYXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAod29yZEFycmF5KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzOwogICAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlczsKCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHZhciB1dGYxNkNoYXJzID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWdCeXRlczsgaSArPSAyKSB7CiAgICAgICAgICAgICAgICB2YXIgY29kZVBvaW50ID0gd29yZHNbaSA+Pj4gMl0gPj4+IDE2IC0gaSAlIDQgKiA4ICYgMHhmZmZmOwogICAgICAgICAgICAgICAgdXRmMTZDaGFycy5wdXNoKFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZVBvaW50KSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB1dGYxNkNoYXJzLmpvaW4oJycpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSBVVEYtMTYgQkUgc3RyaW5nIHRvIGEgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHV0ZjE2U3RyIFRoZSBVVEYtMTYgQkUgc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMuZW5jLlV0ZjE2LnBhcnNlKHV0ZjE2U3RyaW5nKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAodXRmMTZTdHIpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciB1dGYxNlN0ckxlbmd0aCA9IHV0ZjE2U3RyLmxlbmd0aDsKCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHZhciB3b3JkcyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdXRmMTZTdHJMZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgd29yZHNbaSA+Pj4gMV0gfD0gdXRmMTZTdHIuY2hhckNvZGVBdChpKSA8PCAxNiAtIGkgJSAyICogMTY7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiBXb3JkQXJyYXkuY3JlYXRlKHdvcmRzLCB1dGYxNlN0ckxlbmd0aCAqIDIpOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogVVRGLTE2IExFIGVuY29kaW5nIHN0cmF0ZWd5LgogICAgICAgICAgICovCiAgICAgICAgICBDX2VuYy5VdGYxNkxFID0gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgVVRGLTE2IExFIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgVVRGLTE2IExFIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHV0ZjE2U3RyID0gQ3J5cHRvSlMuZW5jLlV0ZjE2TEUuc3RyaW5naWZ5KHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgd29yZHMgPSB3b3JkQXJyYXkud29yZHM7CiAgICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzOwoKICAgICAgICAgICAgICAvLyBDb252ZXJ0CiAgICAgICAgICAgICAgdmFyIHV0ZjE2Q2hhcnMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpICs9IDIpIHsKICAgICAgICAgICAgICAgIHZhciBjb2RlUG9pbnQgPSBzd2FwRW5kaWFuKHdvcmRzW2kgPj4+IDJdID4+PiAxNiAtIGkgJSA0ICogOCAmIDB4ZmZmZik7CiAgICAgICAgICAgICAgICB1dGYxNkNoYXJzLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlUG9pbnQpKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHV0ZjE2Q2hhcnMuam9pbignJyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBhIFVURi0xNiBMRSBzdHJpbmcgdG8gYSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ30gdXRmMTZTdHIgVGhlIFVURi0xNiBMRSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciB3b3JkQXJyYXkgPSBDcnlwdG9KUy5lbmMuVXRmMTZMRS5wYXJzZSh1dGYxNlN0cik7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwYXJzZTogZnVuY3Rpb24gKHV0ZjE2U3RyKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgdXRmMTZTdHJMZW5ndGggPSB1dGYxNlN0ci5sZW5ndGg7CgogICAgICAgICAgICAgIC8vIENvbnZlcnQKICAgICAgICAgICAgICB2YXIgd29yZHMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHV0ZjE2U3RyTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIHdvcmRzW2kgPj4+IDFdIHw9IHN3YXBFbmRpYW4odXRmMTZTdHIuY2hhckNvZGVBdChpKSA8PCAxNiAtIGkgJSAyICogMTYpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gV29yZEFycmF5LmNyZWF0ZSh3b3JkcywgdXRmMTZTdHJMZW5ndGggKiAyKTsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKICAgICAgICAgIGZ1bmN0aW9uIHN3YXBFbmRpYW4od29yZCkgewogICAgICAgICAgICByZXR1cm4gd29yZCA8PCA4ICYgMHhmZjAwZmYwMCB8IHdvcmQgPj4+IDggJiAweDAwZmYwMGZmOwogICAgICAgICAgfQogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLmVuYy5VdGYxNjsKICAgICAgfSk7CiAgICB9KShlbmNVdGYxNiQxKTsKICAgIHJldHVybiBlbmNVdGYxNiQxLmV4cG9ydHM7CiAgfQoKICB2YXIgZW5jQmFzZTY0JDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgZW5jQmFzZTY0ID0gZW5jQmFzZTY0JDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRFbmNCYXNlNjQ7CiAgZnVuY3Rpb24gcmVxdWlyZUVuY0Jhc2U2NCgpIHsKICAgIGlmIChoYXNSZXF1aXJlZEVuY0Jhc2U2NCkgcmV0dXJuIGVuY0Jhc2U2NCQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZEVuY0Jhc2U2NCA9IDE7CiAgICAoZnVuY3Rpb24gKG1vZHVsZSwgZXhwb3J0cyQxKSB7CiAgICAgIChmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSkgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShlbmNCYXNlNjQsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgQ19lbmMgPSBDLmVuYzsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEJhc2U2NCBlbmNvZGluZyBzdHJhdGVneS4KICAgICAgICAgICAqLwogICAgICAgICAgQ19lbmMuQmFzZTY0ID0gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSB3b3JkIGFycmF5IHRvIGEgQmFzZTY0IHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IHdvcmRBcnJheSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgQmFzZTY0IHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGJhc2U2NFN0cmluZyA9IENyeXB0b0pTLmVuYy5CYXNlNjQuc3RyaW5naWZ5KHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXkpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgd29yZHMgPSB3b3JkQXJyYXkud29yZHM7CiAgICAgICAgICAgICAgdmFyIHNpZ0J5dGVzID0gd29yZEFycmF5LnNpZ0J5dGVzOwogICAgICAgICAgICAgIHZhciBtYXAgPSB0aGlzLl9tYXA7CgogICAgICAgICAgICAgIC8vIENsYW1wIGV4Y2VzcyBiaXRzCiAgICAgICAgICAgICAgd29yZEFycmF5LmNsYW1wKCk7CgogICAgICAgICAgICAgIC8vIENvbnZlcnQKICAgICAgICAgICAgICB2YXIgYmFzZTY0Q2hhcnMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNpZ0J5dGVzOyBpICs9IDMpIHsKICAgICAgICAgICAgICAgIHZhciBieXRlMSA9IHdvcmRzW2kgPj4+IDJdID4+PiAyNCAtIGkgJSA0ICogOCAmIDB4ZmY7CiAgICAgICAgICAgICAgICB2YXIgYnl0ZTIgPSB3b3Jkc1tpICsgMSA+Pj4gMl0gPj4+IDI0IC0gKGkgKyAxKSAlIDQgKiA4ICYgMHhmZjsKICAgICAgICAgICAgICAgIHZhciBieXRlMyA9IHdvcmRzW2kgKyAyID4+PiAyXSA+Pj4gMjQgLSAoaSArIDIpICUgNCAqIDggJiAweGZmOwogICAgICAgICAgICAgICAgdmFyIHRyaXBsZXQgPSBieXRlMSA8PCAxNiB8IGJ5dGUyIDw8IDggfCBieXRlMzsKICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgNCAmJiBpICsgaiAqIDAuNzUgPCBzaWdCeXRlczsgaisrKSB7CiAgICAgICAgICAgICAgICAgIGJhc2U2NENoYXJzLnB1c2gobWFwLmNoYXJBdCh0cmlwbGV0ID4+PiA2ICogKDMgLSBqKSAmIDB4M2YpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nCiAgICAgICAgICAgICAgdmFyIHBhZGRpbmdDaGFyID0gbWFwLmNoYXJBdCg2NCk7CiAgICAgICAgICAgICAgaWYgKHBhZGRpbmdDaGFyKSB7CiAgICAgICAgICAgICAgICB3aGlsZSAoYmFzZTY0Q2hhcnMubGVuZ3RoICUgNCkgewogICAgICAgICAgICAgICAgICBiYXNlNjRDaGFycy5wdXNoKHBhZGRpbmdDaGFyKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIGJhc2U2NENoYXJzLmpvaW4oJycpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSBCYXNlNjQgc3RyaW5nIHRvIGEgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGJhc2U2NFN0ciBUaGUgQmFzZTY0IHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgd29yZCBhcnJheS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHdvcmRBcnJheSA9IENyeXB0b0pTLmVuYy5CYXNlNjQucGFyc2UoYmFzZTY0U3RyaW5nKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAoYmFzZTY0U3RyKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGJhc2U2NFN0ckxlbmd0aCA9IGJhc2U2NFN0ci5sZW5ndGg7CiAgICAgICAgICAgICAgdmFyIG1hcCA9IHRoaXMuX21hcDsKICAgICAgICAgICAgICB2YXIgcmV2ZXJzZU1hcCA9IHRoaXMuX3JldmVyc2VNYXA7CiAgICAgICAgICAgICAgaWYgKCFyZXZlcnNlTWFwKSB7CiAgICAgICAgICAgICAgICByZXZlcnNlTWFwID0gdGhpcy5fcmV2ZXJzZU1hcCA9IFtdOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtYXAubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgICAgcmV2ZXJzZU1hcFttYXAuY2hhckNvZGVBdChqKV0gPSBqOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gSWdub3JlIHBhZGRpbmcKICAgICAgICAgICAgICB2YXIgcGFkZGluZ0NoYXIgPSBtYXAuY2hhckF0KDY0KTsKICAgICAgICAgICAgICBpZiAocGFkZGluZ0NoYXIpIHsKICAgICAgICAgICAgICAgIHZhciBwYWRkaW5nSW5kZXggPSBiYXNlNjRTdHIuaW5kZXhPZihwYWRkaW5nQ2hhcik7CiAgICAgICAgICAgICAgICBpZiAocGFkZGluZ0luZGV4ICE9PSAtMSkgewogICAgICAgICAgICAgICAgICBiYXNlNjRTdHJMZW5ndGggPSBwYWRkaW5nSW5kZXg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBDb252ZXJ0CiAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlTG9vcChiYXNlNjRTdHIsIGJhc2U2NFN0ckxlbmd0aCwgcmV2ZXJzZU1hcCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9tYXA6ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvPScKICAgICAgICAgIH07CiAgICAgICAgICBmdW5jdGlvbiBwYXJzZUxvb3AoYmFzZTY0U3RyLCBiYXNlNjRTdHJMZW5ndGgsIHJldmVyc2VNYXApIHsKICAgICAgICAgICAgdmFyIHdvcmRzID0gW107CiAgICAgICAgICAgIHZhciBuQnl0ZXMgPSAwOwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJhc2U2NFN0ckxlbmd0aDsgaSsrKSB7CiAgICAgICAgICAgICAgaWYgKGkgJSA0KSB7CiAgICAgICAgICAgICAgICB2YXIgYml0czEgPSByZXZlcnNlTWFwW2Jhc2U2NFN0ci5jaGFyQ29kZUF0KGkgLSAxKV0gPDwgaSAlIDQgKiAyOwogICAgICAgICAgICAgICAgdmFyIGJpdHMyID0gcmV2ZXJzZU1hcFtiYXNlNjRTdHIuY2hhckNvZGVBdChpKV0gPj4+IDYgLSBpICUgNCAqIDI7CiAgICAgICAgICAgICAgICB2YXIgYml0c0NvbWJpbmVkID0gYml0czEgfCBiaXRzMjsKICAgICAgICAgICAgICAgIHdvcmRzW25CeXRlcyA+Pj4gMl0gfD0gYml0c0NvbWJpbmVkIDw8IDI0IC0gbkJ5dGVzICUgNCAqIDg7CiAgICAgICAgICAgICAgICBuQnl0ZXMrKzsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIFdvcmRBcnJheS5jcmVhdGUod29yZHMsIG5CeXRlcyk7CiAgICAgICAgICB9CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMuZW5jLkJhc2U2NDsKICAgICAgfSk7CiAgICB9KShlbmNCYXNlNjQkMSk7CiAgICByZXR1cm4gZW5jQmFzZTY0JDEuZXhwb3J0czsKICB9CgogIHZhciBlbmNCYXNlNjR1cmwkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBlbmNCYXNlNjR1cmwgPSBlbmNCYXNlNjR1cmwkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZEVuY0Jhc2U2NHVybDsKICBmdW5jdGlvbiByZXF1aXJlRW5jQmFzZTY0dXJsKCkgewogICAgaWYgKGhhc1JlcXVpcmVkRW5jQmFzZTY0dXJsKSByZXR1cm4gZW5jQmFzZTY0dXJsJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkRW5jQmFzZTY0dXJsID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKGVuY0Jhc2U2NHVybCwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKICAgICAgICAgIHZhciBDX2VuYyA9IEMuZW5jOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQmFzZTY0dXJsIGVuY29kaW5nIHN0cmF0ZWd5LgogICAgICAgICAgICovCiAgICAgICAgICBDX2VuYy5CYXNlNjR1cmwgPSB7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBhIHdvcmQgYXJyYXkgdG8gYSBCYXNlNjR1cmwgc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0gd29yZEFycmF5IFRoZSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IHVybFNhZmUgV2hldGhlciB0byB1c2UgdXJsIHNhZmUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgQmFzZTY0dXJsIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGJhc2U2NFN0cmluZyA9IENyeXB0b0pTLmVuYy5CYXNlNjR1cmwuc3RyaW5naWZ5KHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzdHJpbmdpZnk6IGZ1bmN0aW9uICh3b3JkQXJyYXksIHVybFNhZmUpIHsKICAgICAgICAgICAgICBpZiAodXJsU2FmZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICB1cmxTYWZlID0gdHJ1ZTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIHdvcmRzID0gd29yZEFycmF5LndvcmRzOwogICAgICAgICAgICAgIHZhciBzaWdCeXRlcyA9IHdvcmRBcnJheS5zaWdCeXRlczsKICAgICAgICAgICAgICB2YXIgbWFwID0gdXJsU2FmZSA/IHRoaXMuX3NhZmVfbWFwIDogdGhpcy5fbWFwOwoKICAgICAgICAgICAgICAvLyBDbGFtcCBleGNlc3MgYml0cwogICAgICAgICAgICAgIHdvcmRBcnJheS5jbGFtcCgpOwoKICAgICAgICAgICAgICAvLyBDb252ZXJ0CiAgICAgICAgICAgICAgdmFyIGJhc2U2NENoYXJzID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzaWdCeXRlczsgaSArPSAzKSB7CiAgICAgICAgICAgICAgICB2YXIgYnl0ZTEgPSB3b3Jkc1tpID4+PiAyXSA+Pj4gMjQgLSBpICUgNCAqIDggJiAweGZmOwogICAgICAgICAgICAgICAgdmFyIGJ5dGUyID0gd29yZHNbaSArIDEgPj4+IDJdID4+PiAyNCAtIChpICsgMSkgJSA0ICogOCAmIDB4ZmY7CiAgICAgICAgICAgICAgICB2YXIgYnl0ZTMgPSB3b3Jkc1tpICsgMiA+Pj4gMl0gPj4+IDI0IC0gKGkgKyAyKSAlIDQgKiA4ICYgMHhmZjsKICAgICAgICAgICAgICAgIHZhciB0cmlwbGV0ID0gYnl0ZTEgPDwgMTYgfCBieXRlMiA8PCA4IHwgYnl0ZTM7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IDQgJiYgaSArIGogKiAwLjc1IDwgc2lnQnl0ZXM7IGorKykgewogICAgICAgICAgICAgICAgICBiYXNlNjRDaGFycy5wdXNoKG1hcC5jaGFyQXQodHJpcGxldCA+Pj4gNiAqICgzIC0gaikgJiAweDNmKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBBZGQgcGFkZGluZwogICAgICAgICAgICAgIHZhciBwYWRkaW5nQ2hhciA9IG1hcC5jaGFyQXQoNjQpOwogICAgICAgICAgICAgIGlmIChwYWRkaW5nQ2hhcikgewogICAgICAgICAgICAgICAgd2hpbGUgKGJhc2U2NENoYXJzLmxlbmd0aCAlIDQpIHsKICAgICAgICAgICAgICAgICAgYmFzZTY0Q2hhcnMucHVzaChwYWRkaW5nQ2hhcik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiBiYXNlNjRDaGFycy5qb2luKCcnKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGEgQmFzZTY0dXJsIHN0cmluZyB0byBhIHdvcmQgYXJyYXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBiYXNlNjRTdHIgVGhlIEJhc2U2NHVybCBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Ym9vbGVhbn0gdXJsU2FmZSBXaGV0aGVyIHRvIHVzZSB1cmwgc2FmZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSB3b3JkIGFycmF5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgd29yZEFycmF5ID0gQ3J5cHRvSlMuZW5jLkJhc2U2NHVybC5wYXJzZShiYXNlNjRTdHJpbmcpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcGFyc2U6IGZ1bmN0aW9uIChiYXNlNjRTdHIsIHVybFNhZmUpIHsKICAgICAgICAgICAgICBpZiAodXJsU2FmZSA9PT0gdW5kZWZpbmVkKSB7CiAgICAgICAgICAgICAgICB1cmxTYWZlID0gdHJ1ZTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBiYXNlNjRTdHJMZW5ndGggPSBiYXNlNjRTdHIubGVuZ3RoOwogICAgICAgICAgICAgIHZhciBtYXAgPSB1cmxTYWZlID8gdGhpcy5fc2FmZV9tYXAgOiB0aGlzLl9tYXA7CiAgICAgICAgICAgICAgdmFyIHJldmVyc2VNYXAgPSB0aGlzLl9yZXZlcnNlTWFwOwogICAgICAgICAgICAgIGlmICghcmV2ZXJzZU1hcCkgewogICAgICAgICAgICAgICAgcmV2ZXJzZU1hcCA9IHRoaXMuX3JldmVyc2VNYXAgPSBbXTsKICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgbWFwLmxlbmd0aDsgaisrKSB7CiAgICAgICAgICAgICAgICAgIHJldmVyc2VNYXBbbWFwLmNoYXJDb2RlQXQoaildID0gajsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIElnbm9yZSBwYWRkaW5nCiAgICAgICAgICAgICAgdmFyIHBhZGRpbmdDaGFyID0gbWFwLmNoYXJBdCg2NCk7CiAgICAgICAgICAgICAgaWYgKHBhZGRpbmdDaGFyKSB7CiAgICAgICAgICAgICAgICB2YXIgcGFkZGluZ0luZGV4ID0gYmFzZTY0U3RyLmluZGV4T2YocGFkZGluZ0NoYXIpOwogICAgICAgICAgICAgICAgaWYgKHBhZGRpbmdJbmRleCAhPT0gLTEpIHsKICAgICAgICAgICAgICAgICAgYmFzZTY0U3RyTGVuZ3RoID0gcGFkZGluZ0luZGV4OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gQ29udmVydAogICAgICAgICAgICAgIHJldHVybiBwYXJzZUxvb3AoYmFzZTY0U3RyLCBiYXNlNjRTdHJMZW5ndGgsIHJldmVyc2VNYXApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfbWFwOiAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz0nLAogICAgICAgICAgICBfc2FmZV9tYXA6ICdBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OS1fJwogICAgICAgICAgfTsKICAgICAgICAgIGZ1bmN0aW9uIHBhcnNlTG9vcChiYXNlNjRTdHIsIGJhc2U2NFN0ckxlbmd0aCwgcmV2ZXJzZU1hcCkgewogICAgICAgICAgICB2YXIgd29yZHMgPSBbXTsKICAgICAgICAgICAgdmFyIG5CeXRlcyA9IDA7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmFzZTY0U3RyTGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICBpZiAoaSAlIDQpIHsKICAgICAgICAgICAgICAgIHZhciBiaXRzMSA9IHJldmVyc2VNYXBbYmFzZTY0U3RyLmNoYXJDb2RlQXQoaSAtIDEpXSA8PCBpICUgNCAqIDI7CiAgICAgICAgICAgICAgICB2YXIgYml0czIgPSByZXZlcnNlTWFwW2Jhc2U2NFN0ci5jaGFyQ29kZUF0KGkpXSA+Pj4gNiAtIGkgJSA0ICogMjsKICAgICAgICAgICAgICAgIHZhciBiaXRzQ29tYmluZWQgPSBiaXRzMSB8IGJpdHMyOwogICAgICAgICAgICAgICAgd29yZHNbbkJ5dGVzID4+PiAyXSB8PSBiaXRzQ29tYmluZWQgPDwgMjQgLSBuQnl0ZXMgJSA0ICogODsKICAgICAgICAgICAgICAgIG5CeXRlcysrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gV29yZEFycmF5LmNyZWF0ZSh3b3JkcywgbkJ5dGVzKTsKICAgICAgICAgIH0KICAgICAgICB9KSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5lbmMuQmFzZTY0dXJsOwogICAgICB9KTsKICAgIH0pKGVuY0Jhc2U2NHVybCQxKTsKICAgIHJldHVybiBlbmNCYXNlNjR1cmwkMS5leHBvcnRzOwogIH0KCiAgdmFyIG1kNSQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIG1kNSA9IG1kNSQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkTWQ1OwogIGZ1bmN0aW9uIHJlcXVpcmVNZDUoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRNZDUpIHJldHVybiBtZDUkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRNZDUgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHsKICAgICAgICB7CiAgICAgICAgICAvLyBDb21tb25KUwogICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmVDb3JlKCkpOwogICAgICAgIH0KICAgICAgfSkobWQ1LCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAoZnVuY3Rpb24gKE1hdGgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKICAgICAgICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7CiAgICAgICAgICB2YXIgQ19hbGdvID0gQy5hbGdvOwoKICAgICAgICAgIC8vIENvbnN0YW50cyB0YWJsZQogICAgICAgICAgdmFyIFQgPSBbXTsKCiAgICAgICAgICAvLyBDb21wdXRlIGNvbnN0YW50cwogICAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA2NDsgaSsrKSB7CiAgICAgICAgICAgICAgVFtpXSA9IE1hdGguYWJzKE1hdGguc2luKGkgKyAxKSkgKiAweDEwMDAwMDAwMCB8IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pKCk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBNRDUgaGFzaCBhbGdvcml0aG0uCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBNRDUgPSBDX2FsZ28uTUQ1ID0gSGFzaGVyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSwgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3Nl0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAvLyBTd2FwIGVuZGlhbgogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykgewogICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0X2kgPSBvZmZzZXQgKyBpOwogICAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0X2kgPSBNW29mZnNldF9pXTsKICAgICAgICAgICAgICAgIE1bb2Zmc2V0X2ldID0gKE1fb2Zmc2V0X2kgPDwgOCB8IE1fb2Zmc2V0X2kgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoTV9vZmZzZXRfaSA8PCAyNCB8IE1fb2Zmc2V0X2kgPj4+IDgpICYgMHhmZjAwZmYwMDsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBIID0gdGhpcy5faGFzaC53b3JkczsKICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMCA9IE1bb2Zmc2V0ICsgMF07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEgPSBNW29mZnNldCArIDFdOwogICAgICAgICAgICAgIHZhciBNX29mZnNldF8yID0gTVtvZmZzZXQgKyAyXTsKICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfMyA9IE1bb2Zmc2V0ICsgM107CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzQgPSBNW29mZnNldCArIDRdOwogICAgICAgICAgICAgIHZhciBNX29mZnNldF81ID0gTVtvZmZzZXQgKyA1XTsKICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfNiA9IE1bb2Zmc2V0ICsgNl07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzcgPSBNW29mZnNldCArIDddOwogICAgICAgICAgICAgIHZhciBNX29mZnNldF84ID0gTVtvZmZzZXQgKyA4XTsKICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfOSA9IE1bb2Zmc2V0ICsgOV07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEwID0gTVtvZmZzZXQgKyAxMF07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzExID0gTVtvZmZzZXQgKyAxMV07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEyID0gTVtvZmZzZXQgKyAxMl07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzEzID0gTVtvZmZzZXQgKyAxM107CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzE0ID0gTVtvZmZzZXQgKyAxNF07CiAgICAgICAgICAgICAgdmFyIE1fb2Zmc2V0XzE1ID0gTVtvZmZzZXQgKyAxNV07CgogICAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzCiAgICAgICAgICAgICAgdmFyIGEgPSBIWzBdOwogICAgICAgICAgICAgIHZhciBiID0gSFsxXTsKICAgICAgICAgICAgICB2YXIgYyA9IEhbMl07CiAgICAgICAgICAgICAgdmFyIGQgPSBIWzNdOwoKICAgICAgICAgICAgICAvLyBDb21wdXRhdGlvbgogICAgICAgICAgICAgIGEgPSBGRihhLCBiLCBjLCBkLCBNX29mZnNldF8wLCA3LCBUWzBdKTsKICAgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfMSwgMTIsIFRbMV0pOwogICAgICAgICAgICAgIGMgPSBGRihjLCBkLCBhLCBiLCBNX29mZnNldF8yLCAxNywgVFsyXSk7CiAgICAgICAgICAgICAgYiA9IEZGKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzMsIDIyLCBUWzNdKTsKICAgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfNCwgNywgVFs0XSk7CiAgICAgICAgICAgICAgZCA9IEZGKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzUsIDEyLCBUWzVdKTsKICAgICAgICAgICAgICBjID0gRkYoYywgZCwgYSwgYiwgTV9vZmZzZXRfNiwgMTcsIFRbNl0pOwogICAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF83LCAyMiwgVFs3XSk7CiAgICAgICAgICAgICAgYSA9IEZGKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzgsIDcsIFRbOF0pOwogICAgICAgICAgICAgIGQgPSBGRihkLCBhLCBiLCBjLCBNX29mZnNldF85LCAxMiwgVFs5XSk7CiAgICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzEwLCAxNywgVFsxMF0pOwogICAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF8xMSwgMjIsIFRbMTFdKTsKICAgICAgICAgICAgICBhID0gRkYoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTIsIDcsIFRbMTJdKTsKICAgICAgICAgICAgICBkID0gRkYoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTMsIDEyLCBUWzEzXSk7CiAgICAgICAgICAgICAgYyA9IEZGKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE0LCAxNywgVFsxNF0pOwogICAgICAgICAgICAgIGIgPSBGRihiLCBjLCBkLCBhLCBNX29mZnNldF8xNSwgMjIsIFRbMTVdKTsKICAgICAgICAgICAgICBhID0gR0coYSwgYiwgYywgZCwgTV9vZmZzZXRfMSwgNSwgVFsxNl0pOwogICAgICAgICAgICAgIGQgPSBHRyhkLCBhLCBiLCBjLCBNX29mZnNldF82LCA5LCBUWzE3XSk7CiAgICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzExLCAxNCwgVFsxOF0pOwogICAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF8wLCAyMCwgVFsxOV0pOwogICAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF81LCA1LCBUWzIwXSk7CiAgICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzEwLCA5LCBUWzIxXSk7CiAgICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzE1LCAxNCwgVFsyMl0pOwogICAgICAgICAgICAgIGIgPSBHRyhiLCBjLCBkLCBhLCBNX29mZnNldF80LCAyMCwgVFsyM10pOwogICAgICAgICAgICAgIGEgPSBHRyhhLCBiLCBjLCBkLCBNX29mZnNldF85LCA1LCBUWzI0XSk7CiAgICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzE0LCA5LCBUWzI1XSk7CiAgICAgICAgICAgICAgYyA9IEdHKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzMsIDE0LCBUWzI2XSk7CiAgICAgICAgICAgICAgYiA9IEdHKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzgsIDIwLCBUWzI3XSk7CiAgICAgICAgICAgICAgYSA9IEdHKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzEzLCA1LCBUWzI4XSk7CiAgICAgICAgICAgICAgZCA9IEdHKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzIsIDksIFRbMjldKTsKICAgICAgICAgICAgICBjID0gR0coYywgZCwgYSwgYiwgTV9vZmZzZXRfNywgMTQsIFRbMzBdKTsKICAgICAgICAgICAgICBiID0gR0coYiwgYywgZCwgYSwgTV9vZmZzZXRfMTIsIDIwLCBUWzMxXSk7CiAgICAgICAgICAgICAgYSA9IEhIKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzUsIDQsIFRbMzJdKTsKICAgICAgICAgICAgICBkID0gSEgoZCwgYSwgYiwgYywgTV9vZmZzZXRfOCwgMTEsIFRbMzNdKTsKICAgICAgICAgICAgICBjID0gSEgoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTEsIDE2LCBUWzM0XSk7CiAgICAgICAgICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzE0LCAyMywgVFszNV0pOwogICAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF8xLCA0LCBUWzM2XSk7CiAgICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzQsIDExLCBUWzM3XSk7CiAgICAgICAgICAgICAgYyA9IEhIKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzcsIDE2LCBUWzM4XSk7CiAgICAgICAgICAgICAgYiA9IEhIKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEwLCAyMywgVFszOV0pOwogICAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF8xMywgNCwgVFs0MF0pOwogICAgICAgICAgICAgIGQgPSBISChkLCBhLCBiLCBjLCBNX29mZnNldF8wLCAxMSwgVFs0MV0pOwogICAgICAgICAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBNX29mZnNldF8zLCAxNiwgVFs0Ml0pOwogICAgICAgICAgICAgIGIgPSBISChiLCBjLCBkLCBhLCBNX29mZnNldF82LCAyMywgVFs0M10pOwogICAgICAgICAgICAgIGEgPSBISChhLCBiLCBjLCBkLCBNX29mZnNldF85LCA0LCBUWzQ0XSk7CiAgICAgICAgICAgICAgZCA9IEhIKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzEyLCAxMSwgVFs0NV0pOwogICAgICAgICAgICAgIGMgPSBISChjLCBkLCBhLCBiLCBNX29mZnNldF8xNSwgMTYsIFRbNDZdKTsKICAgICAgICAgICAgICBiID0gSEgoYiwgYywgZCwgYSwgTV9vZmZzZXRfMiwgMjMsIFRbNDddKTsKICAgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfMCwgNiwgVFs0OF0pOwogICAgICAgICAgICAgIGQgPSBJSShkLCBhLCBiLCBjLCBNX29mZnNldF83LCAxMCwgVFs0OV0pOwogICAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF8xNCwgMTUsIFRbNTBdKTsKICAgICAgICAgICAgICBiID0gSUkoYiwgYywgZCwgYSwgTV9vZmZzZXRfNSwgMjEsIFRbNTFdKTsKICAgICAgICAgICAgICBhID0gSUkoYSwgYiwgYywgZCwgTV9vZmZzZXRfMTIsIDYsIFRbNTJdKTsKICAgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfMywgMTAsIFRbNTNdKTsKICAgICAgICAgICAgICBjID0gSUkoYywgZCwgYSwgYiwgTV9vZmZzZXRfMTAsIDE1LCBUWzU0XSk7CiAgICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEsIDIxLCBUWzU1XSk7CiAgICAgICAgICAgICAgYSA9IElJKGEsIGIsIGMsIGQsIE1fb2Zmc2V0XzgsIDYsIFRbNTZdKTsKICAgICAgICAgICAgICBkID0gSUkoZCwgYSwgYiwgYywgTV9vZmZzZXRfMTUsIDEwLCBUWzU3XSk7CiAgICAgICAgICAgICAgYyA9IElJKGMsIGQsIGEsIGIsIE1fb2Zmc2V0XzYsIDE1LCBUWzU4XSk7CiAgICAgICAgICAgICAgYiA9IElJKGIsIGMsIGQsIGEsIE1fb2Zmc2V0XzEzLCAyMSwgVFs1OV0pOwogICAgICAgICAgICAgIGEgPSBJSShhLCBiLCBjLCBkLCBNX29mZnNldF80LCA2LCBUWzYwXSk7CiAgICAgICAgICAgICAgZCA9IElJKGQsIGEsIGIsIGMsIE1fb2Zmc2V0XzExLCAxMCwgVFs2MV0pOwogICAgICAgICAgICAgIGMgPSBJSShjLCBkLCBhLCBiLCBNX29mZnNldF8yLCAxNSwgVFs2Ml0pOwogICAgICAgICAgICAgIGIgPSBJSShiLCBjLCBkLCBhLCBNX29mZnNldF85LCAyMSwgVFs2M10pOwoKICAgICAgICAgICAgICAvLyBJbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZQogICAgICAgICAgICAgIEhbMF0gPSBIWzBdICsgYSB8IDA7CiAgICAgICAgICAgICAgSFsxXSA9IEhbMV0gKyBiIHwgMDsKICAgICAgICAgICAgICBIWzJdID0gSFsyXSArIGMgfCAwOwogICAgICAgICAgICAgIEhbM10gPSBIWzNdICsgZCB8IDA7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9kb0ZpbmFsaXplOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGRhdGEgPSB0aGlzLl9kYXRhOwogICAgICAgICAgICAgIHZhciBkYXRhV29yZHMgPSBkYXRhLndvcmRzOwogICAgICAgICAgICAgIHZhciBuQml0c1RvdGFsID0gdGhpcy5fbkRhdGFCeXRlcyAqIDg7CiAgICAgICAgICAgICAgdmFyIG5CaXRzTGVmdCA9IGRhdGEuc2lnQnl0ZXMgKiA4OwoKICAgICAgICAgICAgICAvLyBBZGQgcGFkZGluZwogICAgICAgICAgICAgIGRhdGFXb3Jkc1tuQml0c0xlZnQgPj4+IDVdIHw9IDB4ODAgPDwgMjQgLSBuQml0c0xlZnQgJSAzMjsKICAgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbEggPSBNYXRoLmZsb29yKG5CaXRzVG90YWwgLyAweDEwMDAwMDAwMCk7CiAgICAgICAgICAgICAgdmFyIG5CaXRzVG90YWxMID0gbkJpdHNUb3RhbDsKICAgICAgICAgICAgICBkYXRhV29yZHNbKG5CaXRzTGVmdCArIDY0ID4+PiA5IDw8IDQpICsgMTVdID0gKG5CaXRzVG90YWxIIDw8IDggfCBuQml0c1RvdGFsSCA+Pj4gMjQpICYgMHgwMGZmMDBmZiB8IChuQml0c1RvdGFsSCA8PCAyNCB8IG5CaXRzVG90YWxIID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgZGF0YVdvcmRzWyhuQml0c0xlZnQgKyA2NCA+Pj4gOSA8PCA0KSArIDE0XSA9IChuQml0c1RvdGFsTCA8PCA4IHwgbkJpdHNUb3RhbEwgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAobkJpdHNUb3RhbEwgPDwgMjQgfCBuQml0c1RvdGFsTCA+Pj4gOCkgJiAweGZmMDBmZjAwOwogICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgPSAoZGF0YVdvcmRzLmxlbmd0aCArIDEpICogNDsKCiAgICAgICAgICAgICAgLy8gSGFzaCBmaW5hbCBibG9ja3MKICAgICAgICAgICAgICB0aGlzLl9wcm9jZXNzKCk7CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBoYXNoID0gdGhpcy5faGFzaDsKICAgICAgICAgICAgICB2YXIgSCA9IGhhc2gud29yZHM7CgogICAgICAgICAgICAgIC8vIFN3YXAgZW5kaWFuCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgICB2YXIgSF9pID0gSFtpXTsKICAgICAgICAgICAgICAgIEhbaV0gPSAoSF9pIDw8IDggfCBIX2kgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoSF9pIDw8IDI0IHwgSF9pID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaAogICAgICAgICAgICAgIHJldHVybiBoYXNoOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBjbG9uZSA9IEhhc2hlci5jbG9uZS5jYWxsKHRoaXMpOwogICAgICAgICAgICAgIGNsb25lLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpOwogICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBmdW5jdGlvbiBGRihhLCBiLCBjLCBkLCB4LCBzLCB0KSB7CiAgICAgICAgICAgIHZhciBuID0gYSArIChiICYgYyB8IH5iICYgZCkgKyB4ICsgdDsKICAgICAgICAgICAgcmV0dXJuIChuIDw8IHMgfCBuID4+PiAzMiAtIHMpICsgYjsKICAgICAgICAgIH0KICAgICAgICAgIGZ1bmN0aW9uIEdHKGEsIGIsIGMsIGQsIHgsIHMsIHQpIHsKICAgICAgICAgICAgdmFyIG4gPSBhICsgKGIgJiBkIHwgYyAmIH5kKSArIHggKyB0OwogICAgICAgICAgICByZXR1cm4gKG4gPDwgcyB8IG4gPj4+IDMyIC0gcykgKyBiOwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gSEgoYSwgYiwgYywgZCwgeCwgcywgdCkgewogICAgICAgICAgICB2YXIgbiA9IGEgKyAoYiBeIGMgXiBkKSArIHggKyB0OwogICAgICAgICAgICByZXR1cm4gKG4gPDwgcyB8IG4gPj4+IDMyIC0gcykgKyBiOwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gSUkoYSwgYiwgYywgZCwgeCwgcywgdCkgewogICAgICAgICAgICB2YXIgbiA9IGEgKyAoYyBeIChiIHwgfmQpKSArIHggKyB0OwogICAgICAgICAgICByZXR1cm4gKG4gPDwgcyB8IG4gPj4+IDMyIC0gcykgKyBiOwogICAgICAgICAgfQoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIGhhc2hlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5NRDUoJ21lc3NhZ2UnKTsKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLk1ENSh3b3JkQXJyYXkpOwogICAgICAgICAgICovCiAgICAgICAgICBDLk1ENSA9IEhhc2hlci5fY3JlYXRlSGVscGVyKE1ENSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNNRDUobWVzc2FnZSwga2V5KTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5IbWFjTUQ1ID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKE1ENSk7CiAgICAgICAgfSkoTWF0aCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLk1ENTsKICAgICAgfSk7CiAgICB9KShtZDUkMSk7CiAgICByZXR1cm4gbWQ1JDEuZXhwb3J0czsKICB9CgogIHZhciBzaGExJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgc2hhMSA9IHNoYTEkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFNoYTE7CiAgZnVuY3Rpb24gcmVxdWlyZVNoYTEoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRTaGExKSByZXR1cm4gc2hhMSQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZFNoYTEgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHsKICAgICAgICB7CiAgICAgICAgICAvLyBDb21tb25KUwogICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmVDb3JlKCkpOwogICAgICAgIH0KICAgICAgfSkoc2hhMSwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKICAgICAgICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7CiAgICAgICAgICB2YXIgQ19hbGdvID0gQy5hbGdvOwoKICAgICAgICAgIC8vIFJldXNhYmxlIG9iamVjdAogICAgICAgICAgdmFyIFcgPSBbXTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNIQS0xIGhhc2ggYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgU0hBMSA9IENfYWxnby5TSEExID0gSGFzaGVyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbMHg2NzQ1MjMwMSwgMHhlZmNkYWI4OSwgMHg5OGJhZGNmZSwgMHgxMDMyNTQ3NiwgMHhjM2QyZTFmMF0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBIID0gdGhpcy5faGFzaC53b3JkczsKCiAgICAgICAgICAgICAgLy8gV29ya2luZyB2YXJpYWJsZXMKICAgICAgICAgICAgICB2YXIgYSA9IEhbMF07CiAgICAgICAgICAgICAgdmFyIGIgPSBIWzFdOwogICAgICAgICAgICAgIHZhciBjID0gSFsyXTsKICAgICAgICAgICAgICB2YXIgZCA9IEhbM107CiAgICAgICAgICAgICAgdmFyIGUgPSBIWzRdOwoKICAgICAgICAgICAgICAvLyBDb21wdXRhdGlvbgogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODA7IGkrKykgewogICAgICAgICAgICAgICAgaWYgKGkgPCAxNikgewogICAgICAgICAgICAgICAgICBXW2ldID0gTVtvZmZzZXQgKyBpXSB8IDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICB2YXIgbiA9IFdbaSAtIDNdIF4gV1tpIC0gOF0gXiBXW2kgLSAxNF0gXiBXW2kgLSAxNl07CiAgICAgICAgICAgICAgICAgIFdbaV0gPSBuIDw8IDEgfCBuID4+PiAzMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciB0ID0gKGEgPDwgNSB8IGEgPj4+IDI3KSArIGUgKyBXW2ldOwogICAgICAgICAgICAgICAgaWYgKGkgPCAyMCkgewogICAgICAgICAgICAgICAgICB0ICs9IChiICYgYyB8IH5iICYgZCkgKyAweDVhODI3OTk5OwogICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpIDwgNDApIHsKICAgICAgICAgICAgICAgICAgdCArPSAoYiBeIGMgXiBkKSArIDB4NmVkOWViYTE7CiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGkgPCA2MCkgewogICAgICAgICAgICAgICAgICB0ICs9IChiICYgYyB8IGIgJiBkIHwgYyAmIGQpIC0gMHg3MGU0NDMyNDsKICAgICAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAoaSA8IDgwKSAqL3sKICAgICAgICAgICAgICAgICAgICB0ICs9IChiIF4gYyBeIGQpIC0gMHgzNTlkM2UyYTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZSA9IGQ7CiAgICAgICAgICAgICAgICBkID0gYzsKICAgICAgICAgICAgICAgIGMgPSBiIDw8IDMwIHwgYiA+Pj4gMjsKICAgICAgICAgICAgICAgIGIgPSBhOwogICAgICAgICAgICAgICAgYSA9IHQ7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBJbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZQogICAgICAgICAgICAgIEhbMF0gPSBIWzBdICsgYSB8IDA7CiAgICAgICAgICAgICAgSFsxXSA9IEhbMV0gKyBiIHwgMDsKICAgICAgICAgICAgICBIWzJdID0gSFsyXSArIGMgfCAwOwogICAgICAgICAgICAgIEhbM10gPSBIWzNdICsgZCB8IDA7CiAgICAgICAgICAgICAgSFs0XSA9IEhbNF0gKyBlIHwgMDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7CiAgICAgICAgICAgICAgdmFyIG5CaXRzVG90YWwgPSB0aGlzLl9uRGF0YUJ5dGVzICogODsKICAgICAgICAgICAgICB2YXIgbkJpdHNMZWZ0ID0gZGF0YS5zaWdCeXRlcyAqIDg7CgogICAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nCiAgICAgICAgICAgICAgZGF0YVdvcmRzW25CaXRzTGVmdCA+Pj4gNV0gfD0gMHg4MCA8PCAyNCAtIG5CaXRzTGVmdCAlIDMyOwogICAgICAgICAgICAgIGRhdGFXb3Jkc1sobkJpdHNMZWZ0ICsgNjQgPj4+IDkgPDwgNCkgKyAxNF0gPSBNYXRoLmZsb29yKG5CaXRzVG90YWwgLyAweDEwMDAwMDAwMCk7CiAgICAgICAgICAgICAgZGF0YVdvcmRzWyhuQml0c0xlZnQgKyA2NCA+Pj4gOSA8PCA0KSArIDE1XSA9IG5CaXRzVG90YWw7CiAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGRhdGFXb3Jkcy5sZW5ndGggKiA0OwoKICAgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2NrcwogICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTsKCiAgICAgICAgICAgICAgLy8gUmV0dXJuIGZpbmFsIGNvbXB1dGVkIGhhc2gKICAgICAgICAgICAgICByZXR1cm4gdGhpcy5faGFzaDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgICBjbG9uZS5faGFzaCA9IHRoaXMuX2hhc2guY2xvbmUoKTsKICAgICAgICAgICAgICByZXR1cm4gY2xvbmU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIGhhc2hlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEExKCdtZXNzYWdlJyk7CiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEExKHdvcmRBcnJheSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuU0hBMSA9IEhhc2hlci5fY3JlYXRlSGVscGVyKFNIQTEpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBDcnlwdG9KUy5IbWFjU0hBMShtZXNzYWdlLCBrZXkpOwogICAgICAgICAgICovCiAgICAgICAgICBDLkhtYWNTSEExID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKFNIQTEpOwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlNIQTE7CiAgICAgIH0pOwogICAgfSkoc2hhMSQxKTsKICAgIHJldHVybiBzaGExJDEuZXhwb3J0czsKICB9CgogIHZhciBzaGEyNTYkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBzaGEyNTYgPSBzaGEyNTYkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFNoYTI1NjsKICBmdW5jdGlvbiByZXF1aXJlU2hhMjU2KCkgewogICAgaWYgKGhhc1JlcXVpcmVkU2hhMjU2KSByZXR1cm4gc2hhMjU2JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkU2hhMjU2ID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHNoYTI1NiwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uIChNYXRoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyOwogICAgICAgICAgdmFyIENfYWxnbyA9IEMuYWxnbzsKCiAgICAgICAgICAvLyBJbml0aWFsaXphdGlvbiBhbmQgcm91bmQgY29uc3RhbnRzIHRhYmxlcwogICAgICAgICAgdmFyIEggPSBbXTsKICAgICAgICAgIHZhciBLID0gW107CgogICAgICAgICAgLy8gQ29tcHV0ZSBjb25zdGFudHMKICAgICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIGZ1bmN0aW9uIGlzUHJpbWUobikgewogICAgICAgICAgICAgIHZhciBzcXJ0TiA9IE1hdGguc3FydChuKTsKICAgICAgICAgICAgICBmb3IgKHZhciBmYWN0b3IgPSAyOyBmYWN0b3IgPD0gc3FydE47IGZhY3RvcisrKSB7CiAgICAgICAgICAgICAgICBpZiAoIShuICUgZmFjdG9yKSkgewogICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZ1bmN0aW9uIGdldEZyYWN0aW9uYWxCaXRzKG4pIHsKICAgICAgICAgICAgICByZXR1cm4gKG4gLSAobiB8IDApKSAqIDB4MTAwMDAwMDAwIHwgMDsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXIgbiA9IDI7CiAgICAgICAgICAgIHZhciBuUHJpbWUgPSAwOwogICAgICAgICAgICB3aGlsZSAoblByaW1lIDwgNjQpIHsKICAgICAgICAgICAgICBpZiAoaXNQcmltZShuKSkgewogICAgICAgICAgICAgICAgaWYgKG5QcmltZSA8IDgpIHsKICAgICAgICAgICAgICAgICAgSFtuUHJpbWVdID0gZ2V0RnJhY3Rpb25hbEJpdHMoTWF0aC5wb3cobiwgMSAvIDIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIEtbblByaW1lXSA9IGdldEZyYWN0aW9uYWxCaXRzKE1hdGgucG93KG4sIDEgLyAzKSk7CiAgICAgICAgICAgICAgICBuUHJpbWUrKzsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgbisrOwogICAgICAgICAgICB9CiAgICAgICAgICB9KSgpOwoKICAgICAgICAgIC8vIFJldXNhYmxlIG9iamVjdAogICAgICAgICAgdmFyIFcgPSBbXTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNIQS0yNTYgaGFzaCBhbGdvcml0aG0uCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBTSEEyNTYgPSBDX2FsZ28uU0hBMjU2ID0gSGFzaGVyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChILnNsaWNlKDApKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgSCA9IHRoaXMuX2hhc2gud29yZHM7CgogICAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzCiAgICAgICAgICAgICAgdmFyIGEgPSBIWzBdOwogICAgICAgICAgICAgIHZhciBiID0gSFsxXTsKICAgICAgICAgICAgICB2YXIgYyA9IEhbMl07CiAgICAgICAgICAgICAgdmFyIGQgPSBIWzNdOwogICAgICAgICAgICAgIHZhciBlID0gSFs0XTsKICAgICAgICAgICAgICB2YXIgZiA9IEhbNV07CiAgICAgICAgICAgICAgdmFyIGcgPSBIWzZdOwogICAgICAgICAgICAgIHZhciBoID0gSFs3XTsKCiAgICAgICAgICAgICAgLy8gQ29tcHV0YXRpb24KICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDY0OyBpKyspIHsKICAgICAgICAgICAgICAgIGlmIChpIDwgMTYpIHsKICAgICAgICAgICAgICAgICAgV1tpXSA9IE1bb2Zmc2V0ICsgaV0gfCAwOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMHggPSBXW2kgLSAxNV07CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTAgPSAoZ2FtbWEweCA8PCAyNSB8IGdhbW1hMHggPj4+IDcpIF4gKGdhbW1hMHggPDwgMTQgfCBnYW1tYTB4ID4+PiAxOCkgXiBnYW1tYTB4ID4+PiAzOwogICAgICAgICAgICAgICAgICB2YXIgZ2FtbWExeCA9IFdbaSAtIDJdOwogICAgICAgICAgICAgICAgICB2YXIgZ2FtbWExID0gKGdhbW1hMXggPDwgMTUgfCBnYW1tYTF4ID4+PiAxNykgXiAoZ2FtbWExeCA8PCAxMyB8IGdhbW1hMXggPj4+IDE5KSBeIGdhbW1hMXggPj4+IDEwOwogICAgICAgICAgICAgICAgICBXW2ldID0gZ2FtbWEwICsgV1tpIC0gN10gKyBnYW1tYTEgKyBXW2kgLSAxNl07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB2YXIgY2ggPSBlICYgZiBeIH5lICYgZzsKICAgICAgICAgICAgICAgIHZhciBtYWogPSBhICYgYiBeIGEgJiBjIF4gYiAmIGM7CiAgICAgICAgICAgICAgICB2YXIgc2lnbWEwID0gKGEgPDwgMzAgfCBhID4+PiAyKSBeIChhIDw8IDE5IHwgYSA+Pj4gMTMpIF4gKGEgPDwgMTAgfCBhID4+PiAyMik7CiAgICAgICAgICAgICAgICB2YXIgc2lnbWExID0gKGUgPDwgMjYgfCBlID4+PiA2KSBeIChlIDw8IDIxIHwgZSA+Pj4gMTEpIF4gKGUgPDwgNyB8IGUgPj4+IDI1KTsKICAgICAgICAgICAgICAgIHZhciB0MSA9IGggKyBzaWdtYTEgKyBjaCArIEtbaV0gKyBXW2ldOwogICAgICAgICAgICAgICAgdmFyIHQyID0gc2lnbWEwICsgbWFqOwogICAgICAgICAgICAgICAgaCA9IGc7CiAgICAgICAgICAgICAgICBnID0gZjsKICAgICAgICAgICAgICAgIGYgPSBlOwogICAgICAgICAgICAgICAgZSA9IGQgKyB0MSB8IDA7CiAgICAgICAgICAgICAgICBkID0gYzsKICAgICAgICAgICAgICAgIGMgPSBiOwogICAgICAgICAgICAgICAgYiA9IGE7CiAgICAgICAgICAgICAgICBhID0gdDEgKyB0MiB8IDA7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBJbnRlcm1lZGlhdGUgaGFzaCB2YWx1ZQogICAgICAgICAgICAgIEhbMF0gPSBIWzBdICsgYSB8IDA7CiAgICAgICAgICAgICAgSFsxXSA9IEhbMV0gKyBiIHwgMDsKICAgICAgICAgICAgICBIWzJdID0gSFsyXSArIGMgfCAwOwogICAgICAgICAgICAgIEhbM10gPSBIWzNdICsgZCB8IDA7CiAgICAgICAgICAgICAgSFs0XSA9IEhbNF0gKyBlIHwgMDsKICAgICAgICAgICAgICBIWzVdID0gSFs1XSArIGYgfCAwOwogICAgICAgICAgICAgIEhbNl0gPSBIWzZdICsgZyB8IDA7CiAgICAgICAgICAgICAgSFs3XSA9IEhbN10gKyBoIHwgMDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7CiAgICAgICAgICAgICAgdmFyIG5CaXRzVG90YWwgPSB0aGlzLl9uRGF0YUJ5dGVzICogODsKICAgICAgICAgICAgICB2YXIgbkJpdHNMZWZ0ID0gZGF0YS5zaWdCeXRlcyAqIDg7CgogICAgICAgICAgICAgIC8vIEFkZCBwYWRkaW5nCiAgICAgICAgICAgICAgZGF0YVdvcmRzW25CaXRzTGVmdCA+Pj4gNV0gfD0gMHg4MCA8PCAyNCAtIG5CaXRzTGVmdCAlIDMyOwogICAgICAgICAgICAgIGRhdGFXb3Jkc1sobkJpdHNMZWZ0ICsgNjQgPj4+IDkgPDwgNCkgKyAxNF0gPSBNYXRoLmZsb29yKG5CaXRzVG90YWwgLyAweDEwMDAwMDAwMCk7CiAgICAgICAgICAgICAgZGF0YVdvcmRzWyhuQml0c0xlZnQgKyA2NCA+Pj4gOSA8PCA0KSArIDE1XSA9IG5CaXRzVG90YWw7CiAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGRhdGFXb3Jkcy5sZW5ndGggKiA0OwoKICAgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2NrcwogICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTsKCiAgICAgICAgICAgICAgLy8gUmV0dXJuIGZpbmFsIGNvbXB1dGVkIGhhc2gKICAgICAgICAgICAgICByZXR1cm4gdGhpcy5faGFzaDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgICBjbG9uZS5faGFzaCA9IHRoaXMuX2hhc2guY2xvbmUoKTsKICAgICAgICAgICAgICByZXR1cm4gY2xvbmU7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIGhhc2hlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEEyNTYoJ21lc3NhZ2UnKTsKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTI1Nih3b3JkQXJyYXkpOwogICAgICAgICAgICovCiAgICAgICAgICBDLlNIQTI1NiA9IEhhc2hlci5fY3JlYXRlSGVscGVyKFNIQTI1Nik7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNTSEEyNTYobWVzc2FnZSwga2V5KTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5IbWFjU0hBMjU2ID0gSGFzaGVyLl9jcmVhdGVIbWFjSGVscGVyKFNIQTI1Nik7CiAgICAgICAgfSkoTWF0aCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlNIQTI1NjsKICAgICAgfSk7CiAgICB9KShzaGEyNTYkMSk7CiAgICByZXR1cm4gc2hhMjU2JDEuZXhwb3J0czsKICB9CgogIHZhciBzaGEyMjQkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBzaGEyMjQgPSBzaGEyMjQkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFNoYTIyNDsKICBmdW5jdGlvbiByZXF1aXJlU2hhMjI0KCkgewogICAgaWYgKGhhc1JlcXVpcmVkU2hhMjI0KSByZXR1cm4gc2hhMjI0JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkU2hhMjI0ID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZVNoYTI1NigpKTsKICAgICAgICB9CiAgICAgIH0pKHNoYTIyNCwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CiAgICAgICAgICB2YXIgU0hBMjU2ID0gQ19hbGdvLlNIQTI1NjsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNIQS0yMjQgaGFzaCBhbGdvcml0aG0uCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBTSEEyMjQgPSBDX2FsZ28uU0hBMjI0ID0gU0hBMjU2LmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBXb3JkQXJyYXkuaW5pdChbMHhjMTA1OWVkOCwgMHgzNjdjZDUwNywgMHgzMDcwZGQxNywgMHhmNzBlNTkzOSwgMHhmZmMwMGIzMSwgMHg2ODU4MTUxMSwgMHg2NGY5OGZhNywgMHhiZWZhNGZhNF0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBoYXNoID0gU0hBMjU2Ll9kb0ZpbmFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgaGFzaC5zaWdCeXRlcyAtPSA0OwogICAgICAgICAgICAgIHJldHVybiBoYXNoOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGhhc2guCiAgICAgICAgICAgKgogICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICoKICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgKgogICAgICAgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMjI0KCdtZXNzYWdlJyk7CiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEEyMjQod29yZEFycmF5KTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5TSEEyMjQgPSBTSEEyNTYuX2NyZWF0ZUhlbHBlcihTSEEyMjQpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBDcnlwdG9KUy5IbWFjU0hBMjI0KG1lc3NhZ2UsIGtleSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuSG1hY1NIQTIyNCA9IFNIQTI1Ni5fY3JlYXRlSG1hY0hlbHBlcihTSEEyMjQpOwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlNIQTIyNDsKICAgICAgfSk7CiAgICB9KShzaGEyMjQkMSk7CiAgICByZXR1cm4gc2hhMjI0JDEuZXhwb3J0czsKICB9CgogIHZhciBzaGE1MTIkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBzaGE1MTIgPSBzaGE1MTIkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFNoYTUxMjsKICBmdW5jdGlvbiByZXF1aXJlU2hhNTEyKCkgewogICAgaWYgKGhhc1JlcXVpcmVkU2hhNTEyKSByZXR1cm4gc2hhNTEyJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkU2hhNTEyID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZVg2NENvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShzaGE1MTIsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7CiAgICAgICAgICB2YXIgQ194NjQgPSBDLng2NDsKICAgICAgICAgIHZhciBYNjRXb3JkID0gQ194NjQuV29yZDsKICAgICAgICAgIHZhciBYNjRXb3JkQXJyYXkgPSBDX3g2NC5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgQ19hbGdvID0gQy5hbGdvOwogICAgICAgICAgZnVuY3Rpb24gWDY0V29yZF9jcmVhdGUoKSB7CiAgICAgICAgICAgIHJldHVybiBYNjRXb3JkLmNyZWF0ZS5hcHBseShYNjRXb3JkLCBhcmd1bWVudHMpOwogICAgICAgICAgfQoKICAgICAgICAgIC8vIENvbnN0YW50cwogICAgICAgICAgdmFyIEsgPSBbWDY0V29yZF9jcmVhdGUoMHg0MjhhMmY5OCwgMHhkNzI4YWUyMiksIFg2NFdvcmRfY3JlYXRlKDB4NzEzNzQ0OTEsIDB4MjNlZjY1Y2QpLCBYNjRXb3JkX2NyZWF0ZSgweGI1YzBmYmNmLCAweGVjNGQzYjJmKSwgWDY0V29yZF9jcmVhdGUoMHhlOWI1ZGJhNSwgMHg4MTg5ZGJiYyksIFg2NFdvcmRfY3JlYXRlKDB4Mzk1NmMyNWIsIDB4ZjM0OGI1MzgpLCBYNjRXb3JkX2NyZWF0ZSgweDU5ZjExMWYxLCAweGI2MDVkMDE5KSwgWDY0V29yZF9jcmVhdGUoMHg5MjNmODJhNCwgMHhhZjE5NGY5YiksIFg2NFdvcmRfY3JlYXRlKDB4YWIxYzVlZDUsIDB4ZGE2ZDgxMTgpLCBYNjRXb3JkX2NyZWF0ZSgweGQ4MDdhYTk4LCAweGEzMDMwMjQyKSwgWDY0V29yZF9jcmVhdGUoMHgxMjgzNWIwMSwgMHg0NTcwNmZiZSksIFg2NFdvcmRfY3JlYXRlKDB4MjQzMTg1YmUsIDB4NGVlNGIyOGMpLCBYNjRXb3JkX2NyZWF0ZSgweDU1MGM3ZGMzLCAweGQ1ZmZiNGUyKSwgWDY0V29yZF9jcmVhdGUoMHg3MmJlNWQ3NCwgMHhmMjdiODk2ZiksIFg2NFdvcmRfY3JlYXRlKDB4ODBkZWIxZmUsIDB4M2IxNjk2YjEpLCBYNjRXb3JkX2NyZWF0ZSgweDliZGMwNmE3LCAweDI1YzcxMjM1KSwgWDY0V29yZF9jcmVhdGUoMHhjMTliZjE3NCwgMHhjZjY5MjY5NCksIFg2NFdvcmRfY3JlYXRlKDB4ZTQ5YjY5YzEsIDB4OWVmMTRhZDIpLCBYNjRXb3JkX2NyZWF0ZSgweGVmYmU0Nzg2LCAweDM4NGYyNWUzKSwgWDY0V29yZF9jcmVhdGUoMHgwZmMxOWRjNiwgMHg4YjhjZDViNSksIFg2NFdvcmRfY3JlYXRlKDB4MjQwY2ExY2MsIDB4NzdhYzljNjUpLCBYNjRXb3JkX2NyZWF0ZSgweDJkZTkyYzZmLCAweDU5MmIwMjc1KSwgWDY0V29yZF9jcmVhdGUoMHg0YTc0ODRhYSwgMHg2ZWE2ZTQ4MyksIFg2NFdvcmRfY3JlYXRlKDB4NWNiMGE5ZGMsIDB4YmQ0MWZiZDQpLCBYNjRXb3JkX2NyZWF0ZSgweDc2Zjk4OGRhLCAweDgzMTE1M2I1KSwgWDY0V29yZF9jcmVhdGUoMHg5ODNlNTE1MiwgMHhlZTY2ZGZhYiksIFg2NFdvcmRfY3JlYXRlKDB4YTgzMWM2NmQsIDB4MmRiNDMyMTApLCBYNjRXb3JkX2NyZWF0ZSgweGIwMDMyN2M4LCAweDk4ZmIyMTNmKSwgWDY0V29yZF9jcmVhdGUoMHhiZjU5N2ZjNywgMHhiZWVmMGVlNCksIFg2NFdvcmRfY3JlYXRlKDB4YzZlMDBiZjMsIDB4M2RhODhmYzIpLCBYNjRXb3JkX2NyZWF0ZSgweGQ1YTc5MTQ3LCAweDkzMGFhNzI1KSwgWDY0V29yZF9jcmVhdGUoMHgwNmNhNjM1MSwgMHhlMDAzODI2ZiksIFg2NFdvcmRfY3JlYXRlKDB4MTQyOTI5NjcsIDB4MGEwZTZlNzApLCBYNjRXb3JkX2NyZWF0ZSgweDI3YjcwYTg1LCAweDQ2ZDIyZmZjKSwgWDY0V29yZF9jcmVhdGUoMHgyZTFiMjEzOCwgMHg1YzI2YzkyNiksIFg2NFdvcmRfY3JlYXRlKDB4NGQyYzZkZmMsIDB4NWFjNDJhZWQpLCBYNjRXb3JkX2NyZWF0ZSgweDUzMzgwZDEzLCAweDlkOTViM2RmKSwgWDY0V29yZF9jcmVhdGUoMHg2NTBhNzM1NCwgMHg4YmFmNjNkZSksIFg2NFdvcmRfY3JlYXRlKDB4NzY2YTBhYmIsIDB4M2M3N2IyYTgpLCBYNjRXb3JkX2NyZWF0ZSgweDgxYzJjOTJlLCAweDQ3ZWRhZWU2KSwgWDY0V29yZF9jcmVhdGUoMHg5MjcyMmM4NSwgMHgxNDgyMzUzYiksIFg2NFdvcmRfY3JlYXRlKDB4YTJiZmU4YTEsIDB4NGNmMTAzNjQpLCBYNjRXb3JkX2NyZWF0ZSgweGE4MWE2NjRiLCAweGJjNDIzMDAxKSwgWDY0V29yZF9jcmVhdGUoMHhjMjRiOGI3MCwgMHhkMGY4OTc5MSksIFg2NFdvcmRfY3JlYXRlKDB4Yzc2YzUxYTMsIDB4MDY1NGJlMzApLCBYNjRXb3JkX2NyZWF0ZSgweGQxOTJlODE5LCAweGQ2ZWY1MjE4KSwgWDY0V29yZF9jcmVhdGUoMHhkNjk5MDYyNCwgMHg1NTY1YTkxMCksIFg2NFdvcmRfY3JlYXRlKDB4ZjQwZTM1ODUsIDB4NTc3MTIwMmEpLCBYNjRXb3JkX2NyZWF0ZSgweDEwNmFhMDcwLCAweDMyYmJkMWI4KSwgWDY0V29yZF9jcmVhdGUoMHgxOWE0YzExNiwgMHhiOGQyZDBjOCksIFg2NFdvcmRfY3JlYXRlKDB4MWUzNzZjMDgsIDB4NTE0MWFiNTMpLCBYNjRXb3JkX2NyZWF0ZSgweDI3NDg3NzRjLCAweGRmOGVlYjk5KSwgWDY0V29yZF9jcmVhdGUoMHgzNGIwYmNiNSwgMHhlMTliNDhhOCksIFg2NFdvcmRfY3JlYXRlKDB4MzkxYzBjYjMsIDB4YzVjOTVhNjMpLCBYNjRXb3JkX2NyZWF0ZSgweDRlZDhhYTRhLCAweGUzNDE4YWNiKSwgWDY0V29yZF9jcmVhdGUoMHg1YjljY2E0ZiwgMHg3NzYzZTM3MyksIFg2NFdvcmRfY3JlYXRlKDB4NjgyZTZmZjMsIDB4ZDZiMmI4YTMpLCBYNjRXb3JkX2NyZWF0ZSgweDc0OGY4MmVlLCAweDVkZWZiMmZjKSwgWDY0V29yZF9jcmVhdGUoMHg3OGE1NjM2ZiwgMHg0MzE3MmY2MCksIFg2NFdvcmRfY3JlYXRlKDB4ODRjODc4MTQsIDB4YTFmMGFiNzIpLCBYNjRXb3JkX2NyZWF0ZSgweDhjYzcwMjA4LCAweDFhNjQzOWVjKSwgWDY0V29yZF9jcmVhdGUoMHg5MGJlZmZmYSwgMHgyMzYzMWUyOCksIFg2NFdvcmRfY3JlYXRlKDB4YTQ1MDZjZWIsIDB4ZGU4MmJkZTkpLCBYNjRXb3JkX2NyZWF0ZSgweGJlZjlhM2Y3LCAweGIyYzY3OTE1KSwgWDY0V29yZF9jcmVhdGUoMHhjNjcxNzhmMiwgMHhlMzcyNTMyYiksIFg2NFdvcmRfY3JlYXRlKDB4Y2EyNzNlY2UsIDB4ZWEyNjYxOWMpLCBYNjRXb3JkX2NyZWF0ZSgweGQxODZiOGM3LCAweDIxYzBjMjA3KSwgWDY0V29yZF9jcmVhdGUoMHhlYWRhN2RkNiwgMHhjZGUwZWIxZSksIFg2NFdvcmRfY3JlYXRlKDB4ZjU3ZDRmN2YsIDB4ZWU2ZWQxNzgpLCBYNjRXb3JkX2NyZWF0ZSgweDA2ZjA2N2FhLCAweDcyMTc2ZmJhKSwgWDY0V29yZF9jcmVhdGUoMHgwYTYzN2RjNSwgMHhhMmM4OThhNiksIFg2NFdvcmRfY3JlYXRlKDB4MTEzZjk4MDQsIDB4YmVmOTBkYWUpLCBYNjRXb3JkX2NyZWF0ZSgweDFiNzEwYjM1LCAweDEzMWM0NzFiKSwgWDY0V29yZF9jcmVhdGUoMHgyOGRiNzdmNSwgMHgyMzA0N2Q4NCksIFg2NFdvcmRfY3JlYXRlKDB4MzJjYWFiN2IsIDB4NDBjNzI0OTMpLCBYNjRXb3JkX2NyZWF0ZSgweDNjOWViZTBhLCAweDE1YzliZWJjKSwgWDY0V29yZF9jcmVhdGUoMHg0MzFkNjdjNCwgMHg5YzEwMGQ0YyksIFg2NFdvcmRfY3JlYXRlKDB4NGNjNWQ0YmUsIDB4Y2IzZTQyYjYpLCBYNjRXb3JkX2NyZWF0ZSgweDU5N2YyOTljLCAweGZjNjU3ZTJhKSwgWDY0V29yZF9jcmVhdGUoMHg1ZmNiNmZhYiwgMHgzYWQ2ZmFlYyksIFg2NFdvcmRfY3JlYXRlKDB4NmM0NDE5OGMsIDB4NGE0NzU4MTcpXTsKCiAgICAgICAgICAvLyBSZXVzYWJsZSBvYmplY3RzCiAgICAgICAgICB2YXIgVyA9IFtdOwogICAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4MDsgaSsrKSB7CiAgICAgICAgICAgICAgV1tpXSA9IFg2NFdvcmRfY3JlYXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pKCk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTSEEtNTEyIGhhc2ggYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgU0hBNTEyID0gQ19hbGdvLlNIQTUxMiA9IEhhc2hlci5leHRlbmQoewogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHRoaXMuX2hhc2ggPSBuZXcgWDY0V29yZEFycmF5LmluaXQoW25ldyBYNjRXb3JkLmluaXQoMHg2YTA5ZTY2NywgMHhmM2JjYzkwOCksIG5ldyBYNjRXb3JkLmluaXQoMHhiYjY3YWU4NSwgMHg4NGNhYTczYiksIG5ldyBYNjRXb3JkLmluaXQoMHgzYzZlZjM3MiwgMHhmZTk0ZjgyYiksIG5ldyBYNjRXb3JkLmluaXQoMHhhNTRmZjUzYSwgMHg1ZjFkMzZmMSksIG5ldyBYNjRXb3JkLmluaXQoMHg1MTBlNTI3ZiwgMHhhZGU2ODJkMSksIG5ldyBYNjRXb3JkLmluaXQoMHg5YjA1Njg4YywgMHgyYjNlNmMxZiksIG5ldyBYNjRXb3JkLmluaXQoMHgxZjgzZDlhYiwgMHhmYjQxYmQ2YiksIG5ldyBYNjRXb3JkLmluaXQoMHg1YmUwY2QxOSwgMHgxMzdlMjE3OSldKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIEggPSB0aGlzLl9oYXNoLndvcmRzOwogICAgICAgICAgICAgIHZhciBIMCA9IEhbMF07CiAgICAgICAgICAgICAgdmFyIEgxID0gSFsxXTsKICAgICAgICAgICAgICB2YXIgSDIgPSBIWzJdOwogICAgICAgICAgICAgIHZhciBIMyA9IEhbM107CiAgICAgICAgICAgICAgdmFyIEg0ID0gSFs0XTsKICAgICAgICAgICAgICB2YXIgSDUgPSBIWzVdOwogICAgICAgICAgICAgIHZhciBINiA9IEhbNl07CiAgICAgICAgICAgICAgdmFyIEg3ID0gSFs3XTsKICAgICAgICAgICAgICB2YXIgSDBoID0gSDAuaGlnaDsKICAgICAgICAgICAgICB2YXIgSDBsID0gSDAubG93OwogICAgICAgICAgICAgIHZhciBIMWggPSBIMS5oaWdoOwogICAgICAgICAgICAgIHZhciBIMWwgPSBIMS5sb3c7CiAgICAgICAgICAgICAgdmFyIEgyaCA9IEgyLmhpZ2g7CiAgICAgICAgICAgICAgdmFyIEgybCA9IEgyLmxvdzsKICAgICAgICAgICAgICB2YXIgSDNoID0gSDMuaGlnaDsKICAgICAgICAgICAgICB2YXIgSDNsID0gSDMubG93OwogICAgICAgICAgICAgIHZhciBINGggPSBINC5oaWdoOwogICAgICAgICAgICAgIHZhciBINGwgPSBINC5sb3c7CiAgICAgICAgICAgICAgdmFyIEg1aCA9IEg1LmhpZ2g7CiAgICAgICAgICAgICAgdmFyIEg1bCA9IEg1LmxvdzsKICAgICAgICAgICAgICB2YXIgSDZoID0gSDYuaGlnaDsKICAgICAgICAgICAgICB2YXIgSDZsID0gSDYubG93OwogICAgICAgICAgICAgIHZhciBIN2ggPSBINy5oaWdoOwogICAgICAgICAgICAgIHZhciBIN2wgPSBINy5sb3c7CgogICAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzCiAgICAgICAgICAgICAgdmFyIGFoID0gSDBoOwogICAgICAgICAgICAgIHZhciBhbCA9IEgwbDsKICAgICAgICAgICAgICB2YXIgYmggPSBIMWg7CiAgICAgICAgICAgICAgdmFyIGJsID0gSDFsOwogICAgICAgICAgICAgIHZhciBjaCA9IEgyaDsKICAgICAgICAgICAgICB2YXIgY2wgPSBIMmw7CiAgICAgICAgICAgICAgdmFyIGRoID0gSDNoOwogICAgICAgICAgICAgIHZhciBkbCA9IEgzbDsKICAgICAgICAgICAgICB2YXIgZWggPSBINGg7CiAgICAgICAgICAgICAgdmFyIGVsID0gSDRsOwogICAgICAgICAgICAgIHZhciBmaCA9IEg1aDsKICAgICAgICAgICAgICB2YXIgZmwgPSBINWw7CiAgICAgICAgICAgICAgdmFyIGdoID0gSDZoOwogICAgICAgICAgICAgIHZhciBnbCA9IEg2bDsKICAgICAgICAgICAgICB2YXIgaGggPSBIN2g7CiAgICAgICAgICAgICAgdmFyIGhsID0gSDdsOwoKICAgICAgICAgICAgICAvLyBSb3VuZHMKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDgwOyBpKyspIHsKICAgICAgICAgICAgICAgIHZhciBXaWw7CiAgICAgICAgICAgICAgICB2YXIgV2loOwoKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgICB2YXIgV2kgPSBXW2ldOwoKICAgICAgICAgICAgICAgIC8vIEV4dGVuZCBtZXNzYWdlCiAgICAgICAgICAgICAgICBpZiAoaSA8IDE2KSB7CiAgICAgICAgICAgICAgICAgIFdpaCA9IFdpLmhpZ2ggPSBNW29mZnNldCArIGkgKiAyXSB8IDA7CiAgICAgICAgICAgICAgICAgIFdpbCA9IFdpLmxvdyA9IE1bb2Zmc2V0ICsgaSAqIDIgKyAxXSB8IDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAvLyBHYW1tYTAKICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMHggPSBXW2kgLSAxNV07CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTB4aCA9IGdhbW1hMHguaGlnaDsKICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMHhsID0gZ2FtbWEweC5sb3c7CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTBoID0gKGdhbW1hMHhoID4+PiAxIHwgZ2FtbWEweGwgPDwgMzEpIF4gKGdhbW1hMHhoID4+PiA4IHwgZ2FtbWEweGwgPDwgMjQpIF4gZ2FtbWEweGggPj4+IDc7CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTBsID0gKGdhbW1hMHhsID4+PiAxIHwgZ2FtbWEweGggPDwgMzEpIF4gKGdhbW1hMHhsID4+PiA4IHwgZ2FtbWEweGggPDwgMjQpIF4gKGdhbW1hMHhsID4+PiA3IHwgZ2FtbWEweGggPDwgMjUpOwoKICAgICAgICAgICAgICAgICAgLy8gR2FtbWExCiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTF4ID0gV1tpIC0gMl07CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTF4aCA9IGdhbW1hMXguaGlnaDsKICAgICAgICAgICAgICAgICAgdmFyIGdhbW1hMXhsID0gZ2FtbWExeC5sb3c7CiAgICAgICAgICAgICAgICAgIHZhciBnYW1tYTFoID0gKGdhbW1hMXhoID4+PiAxOSB8IGdhbW1hMXhsIDw8IDEzKSBeIChnYW1tYTF4aCA8PCAzIHwgZ2FtbWExeGwgPj4+IDI5KSBeIGdhbW1hMXhoID4+PiA2OwogICAgICAgICAgICAgICAgICB2YXIgZ2FtbWExbCA9IChnYW1tYTF4bCA+Pj4gMTkgfCBnYW1tYTF4aCA8PCAxMykgXiAoZ2FtbWExeGwgPDwgMyB8IGdhbW1hMXhoID4+PiAyOSkgXiAoZ2FtbWExeGwgPj4+IDYgfCBnYW1tYTF4aCA8PCAyNik7CgogICAgICAgICAgICAgICAgICAvLyBXW2ldID0gZ2FtbWEwICsgV1tpIC0gN10gKyBnYW1tYTEgKyBXW2kgLSAxNl0KICAgICAgICAgICAgICAgICAgdmFyIFdpNyA9IFdbaSAtIDddOwogICAgICAgICAgICAgICAgICB2YXIgV2k3aCA9IFdpNy5oaWdoOwogICAgICAgICAgICAgICAgICB2YXIgV2k3bCA9IFdpNy5sb3c7CiAgICAgICAgICAgICAgICAgIHZhciBXaTE2ID0gV1tpIC0gMTZdOwogICAgICAgICAgICAgICAgICB2YXIgV2kxNmggPSBXaTE2LmhpZ2g7CiAgICAgICAgICAgICAgICAgIHZhciBXaTE2bCA9IFdpMTYubG93OwogICAgICAgICAgICAgICAgICBXaWwgPSBnYW1tYTBsICsgV2k3bDsKICAgICAgICAgICAgICAgICAgV2loID0gZ2FtbWEwaCArIFdpN2ggKyAoV2lsID4+PiAwIDwgZ2FtbWEwbCA+Pj4gMCA/IDEgOiAwKTsKICAgICAgICAgICAgICAgICAgV2lsID0gV2lsICsgZ2FtbWExbDsKICAgICAgICAgICAgICAgICAgV2loID0gV2loICsgZ2FtbWExaCArIChXaWwgPj4+IDAgPCBnYW1tYTFsID4+PiAwID8gMSA6IDApOwogICAgICAgICAgICAgICAgICBXaWwgPSBXaWwgKyBXaTE2bDsKICAgICAgICAgICAgICAgICAgV2loID0gV2loICsgV2kxNmggKyAoV2lsID4+PiAwIDwgV2kxNmwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgICAgIFdpLmhpZ2ggPSBXaWg7CiAgICAgICAgICAgICAgICAgIFdpLmxvdyA9IFdpbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZhciBjaGggPSBlaCAmIGZoIF4gfmVoICYgZ2g7CiAgICAgICAgICAgICAgICB2YXIgY2hsID0gZWwgJiBmbCBeIH5lbCAmIGdsOwogICAgICAgICAgICAgICAgdmFyIG1hamggPSBhaCAmIGJoIF4gYWggJiBjaCBeIGJoICYgY2g7CiAgICAgICAgICAgICAgICB2YXIgbWFqbCA9IGFsICYgYmwgXiBhbCAmIGNsIF4gYmwgJiBjbDsKICAgICAgICAgICAgICAgIHZhciBzaWdtYTBoID0gKGFoID4+PiAyOCB8IGFsIDw8IDQpIF4gKGFoIDw8IDMwIHwgYWwgPj4+IDIpIF4gKGFoIDw8IDI1IHwgYWwgPj4+IDcpOwogICAgICAgICAgICAgICAgdmFyIHNpZ21hMGwgPSAoYWwgPj4+IDI4IHwgYWggPDwgNCkgXiAoYWwgPDwgMzAgfCBhaCA+Pj4gMikgXiAoYWwgPDwgMjUgfCBhaCA+Pj4gNyk7CiAgICAgICAgICAgICAgICB2YXIgc2lnbWExaCA9IChlaCA+Pj4gMTQgfCBlbCA8PCAxOCkgXiAoZWggPj4+IDE4IHwgZWwgPDwgMTQpIF4gKGVoIDw8IDIzIHwgZWwgPj4+IDkpOwogICAgICAgICAgICAgICAgdmFyIHNpZ21hMWwgPSAoZWwgPj4+IDE0IHwgZWggPDwgMTgpIF4gKGVsID4+PiAxOCB8IGVoIDw8IDE0KSBeIChlbCA8PCAyMyB8IGVoID4+PiA5KTsKCiAgICAgICAgICAgICAgICAvLyB0MSA9IGggKyBzaWdtYTEgKyBjaCArIEtbaV0gKyBXW2ldCiAgICAgICAgICAgICAgICB2YXIgS2kgPSBLW2ldOwogICAgICAgICAgICAgICAgdmFyIEtpaCA9IEtpLmhpZ2g7CiAgICAgICAgICAgICAgICB2YXIgS2lsID0gS2kubG93OwogICAgICAgICAgICAgICAgdmFyIHQxbCA9IGhsICsgc2lnbWExbDsKICAgICAgICAgICAgICAgIHZhciB0MWggPSBoaCArIHNpZ21hMWggKyAodDFsID4+PiAwIDwgaGwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgICB2YXIgdDFsID0gdDFsICsgY2hsOwogICAgICAgICAgICAgICAgdmFyIHQxaCA9IHQxaCArIGNoaCArICh0MWwgPj4+IDAgPCBjaGwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgICB2YXIgdDFsID0gdDFsICsgS2lsOwogICAgICAgICAgICAgICAgdmFyIHQxaCA9IHQxaCArIEtpaCArICh0MWwgPj4+IDAgPCBLaWwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgICB2YXIgdDFsID0gdDFsICsgV2lsOwogICAgICAgICAgICAgICAgdmFyIHQxaCA9IHQxaCArIFdpaCArICh0MWwgPj4+IDAgPCBXaWwgPj4+IDAgPyAxIDogMCk7CgogICAgICAgICAgICAgICAgLy8gdDIgPSBzaWdtYTAgKyBtYWoKICAgICAgICAgICAgICAgIHZhciB0MmwgPSBzaWdtYTBsICsgbWFqbDsKICAgICAgICAgICAgICAgIHZhciB0MmggPSBzaWdtYTBoICsgbWFqaCArICh0MmwgPj4+IDAgPCBzaWdtYTBsID4+PiAwID8gMSA6IDApOwoKICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSB3b3JraW5nIHZhcmlhYmxlcwogICAgICAgICAgICAgICAgaGggPSBnaDsKICAgICAgICAgICAgICAgIGhsID0gZ2w7CiAgICAgICAgICAgICAgICBnaCA9IGZoOwogICAgICAgICAgICAgICAgZ2wgPSBmbDsKICAgICAgICAgICAgICAgIGZoID0gZWg7CiAgICAgICAgICAgICAgICBmbCA9IGVsOwogICAgICAgICAgICAgICAgZWwgPSBkbCArIHQxbCB8IDA7CiAgICAgICAgICAgICAgICBlaCA9IGRoICsgdDFoICsgKGVsID4+PiAwIDwgZGwgPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICAgICAgZGggPSBjaDsKICAgICAgICAgICAgICAgIGRsID0gY2w7CiAgICAgICAgICAgICAgICBjaCA9IGJoOwogICAgICAgICAgICAgICAgY2wgPSBibDsKICAgICAgICAgICAgICAgIGJoID0gYWg7CiAgICAgICAgICAgICAgICBibCA9IGFsOwogICAgICAgICAgICAgICAgYWwgPSB0MWwgKyB0MmwgfCAwOwogICAgICAgICAgICAgICAgYWggPSB0MWggKyB0MmggKyAoYWwgPj4+IDAgPCB0MWwgPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gSW50ZXJtZWRpYXRlIGhhc2ggdmFsdWUKICAgICAgICAgICAgICBIMGwgPSBIMC5sb3cgPSBIMGwgKyBhbDsKICAgICAgICAgICAgICBIMC5oaWdoID0gSDBoICsgYWggKyAoSDBsID4+PiAwIDwgYWwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgSDFsID0gSDEubG93ID0gSDFsICsgYmw7CiAgICAgICAgICAgICAgSDEuaGlnaCA9IEgxaCArIGJoICsgKEgxbCA+Pj4gMCA8IGJsID4+PiAwID8gMSA6IDApOwogICAgICAgICAgICAgIEgybCA9IEgyLmxvdyA9IEgybCArIGNsOwogICAgICAgICAgICAgIEgyLmhpZ2ggPSBIMmggKyBjaCArIChIMmwgPj4+IDAgPCBjbCA+Pj4gMCA/IDEgOiAwKTsKICAgICAgICAgICAgICBIM2wgPSBIMy5sb3cgPSBIM2wgKyBkbDsKICAgICAgICAgICAgICBIMy5oaWdoID0gSDNoICsgZGggKyAoSDNsID4+PiAwIDwgZGwgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgSDRsID0gSDQubG93ID0gSDRsICsgZWw7CiAgICAgICAgICAgICAgSDQuaGlnaCA9IEg0aCArIGVoICsgKEg0bCA+Pj4gMCA8IGVsID4+PiAwID8gMSA6IDApOwogICAgICAgICAgICAgIEg1bCA9IEg1LmxvdyA9IEg1bCArIGZsOwogICAgICAgICAgICAgIEg1LmhpZ2ggPSBINWggKyBmaCArIChINWwgPj4+IDAgPCBmbCA+Pj4gMCA/IDEgOiAwKTsKICAgICAgICAgICAgICBINmwgPSBINi5sb3cgPSBINmwgKyBnbDsKICAgICAgICAgICAgICBINi5oaWdoID0gSDZoICsgZ2ggKyAoSDZsID4+PiAwIDwgZ2wgPj4+IDAgPyAxIDogMCk7CiAgICAgICAgICAgICAgSDdsID0gSDcubG93ID0gSDdsICsgaGw7CiAgICAgICAgICAgICAgSDcuaGlnaCA9IEg3aCArIGhoICsgKEg3bCA+Pj4gMCA8IGhsID4+PiAwID8gMSA6IDApOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTsKICAgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3JkczsKICAgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbCA9IHRoaXMuX25EYXRhQnl0ZXMgKiA4OwogICAgICAgICAgICAgIHZhciBuQml0c0xlZnQgPSBkYXRhLnNpZ0J5dGVzICogODsKCiAgICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmcKICAgICAgICAgICAgICBkYXRhV29yZHNbbkJpdHNMZWZ0ID4+PiA1XSB8PSAweDgwIDw8IDI0IC0gbkJpdHNMZWZ0ICUgMzI7CiAgICAgICAgICAgICAgZGF0YVdvcmRzWyhuQml0c0xlZnQgKyAxMjggPj4+IDEwIDw8IDUpICsgMzBdID0gTWF0aC5mbG9vcihuQml0c1RvdGFsIC8gMHgxMDAwMDAwMDApOwogICAgICAgICAgICAgIGRhdGFXb3Jkc1sobkJpdHNMZWZ0ICsgMTI4ID4+PiAxMCA8PCA1KSArIDMxXSA9IG5CaXRzVG90YWw7CiAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGRhdGFXb3Jkcy5sZW5ndGggKiA0OwoKICAgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2NrcwogICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTsKCiAgICAgICAgICAgICAgLy8gQ29udmVydCBoYXNoIHRvIDMyLWJpdCB3b3JkIGFycmF5IGJlZm9yZSByZXR1cm5pbmcKICAgICAgICAgICAgICB2YXIgaGFzaCA9IHRoaXMuX2hhc2gudG9YMzIoKTsKCiAgICAgICAgICAgICAgLy8gUmV0dXJuIGZpbmFsIGNvbXB1dGVkIGhhc2gKICAgICAgICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgY2xvbmU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgY2xvbmUgPSBIYXNoZXIuY2xvbmUuY2FsbCh0aGlzKTsKICAgICAgICAgICAgICBjbG9uZS5faGFzaCA9IHRoaXMuX2hhc2guY2xvbmUoKTsKICAgICAgICAgICAgICByZXR1cm4gY2xvbmU7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGJsb2NrU2l6ZTogMTAyNCAvIDMyCiAgICAgICAgICB9KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBoYXNoZXIncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGhhc2guCiAgICAgICAgICAgKgogICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICoKICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgKgogICAgICAgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBNTEyKCdtZXNzYWdlJyk7CiAgICAgICAgICAgKiAgICAgdmFyIGhhc2ggPSBDcnlwdG9KUy5TSEE1MTIod29yZEFycmF5KTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5TSEE1MTIgPSBIYXNoZXIuX2NyZWF0ZUhlbHBlcihTSEE1MTIpOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb24gdG8gdGhlIEhNQUMncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZSBUaGUgbWVzc2FnZSB0byBoYXNoLgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBrZXkgVGhlIHNlY3JldCBrZXkuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgSE1BQy4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBDcnlwdG9KUy5IbWFjU0hBNTEyKG1lc3NhZ2UsIGtleSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuSG1hY1NIQTUxMiA9IEhhc2hlci5fY3JlYXRlSG1hY0hlbHBlcihTSEE1MTIpOwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlNIQTUxMjsKICAgICAgfSk7CiAgICB9KShzaGE1MTIkMSk7CiAgICByZXR1cm4gc2hhNTEyJDEuZXhwb3J0czsKICB9CgogIHZhciBzaGEzODQkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBzaGEzODQgPSBzaGEzODQkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFNoYTM4NDsKICBmdW5jdGlvbiByZXF1aXJlU2hhMzg0KCkgewogICAgaWYgKGhhc1JlcXVpcmVkU2hhMzg0KSByZXR1cm4gc2hhMzg0JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkU2hhMzg0ID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZVg2NENvcmUoKSwgcmVxdWlyZVNoYTUxMigpKTsKICAgICAgICB9CiAgICAgIH0pKHNoYTM4NCwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX3g2NCA9IEMueDY0OwogICAgICAgICAgdmFyIFg2NFdvcmQgPSBDX3g2NC5Xb3JkOwogICAgICAgICAgdmFyIFg2NFdvcmRBcnJheSA9IENfeDY0LldvcmRBcnJheTsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CiAgICAgICAgICB2YXIgU0hBNTEyID0gQ19hbGdvLlNIQTUxMjsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNIQS0zODQgaGFzaCBhbGdvcml0aG0uCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBTSEEzODQgPSBDX2FsZ28uU0hBMzg0ID0gU0hBNTEyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaCA9IG5ldyBYNjRXb3JkQXJyYXkuaW5pdChbbmV3IFg2NFdvcmQuaW5pdCgweGNiYmI5ZDVkLCAweGMxMDU5ZWQ4KSwgbmV3IFg2NFdvcmQuaW5pdCgweDYyOWEyOTJhLCAweDM2N2NkNTA3KSwgbmV3IFg2NFdvcmQuaW5pdCgweDkxNTkwMTVhLCAweDMwNzBkZDE3KSwgbmV3IFg2NFdvcmQuaW5pdCgweDE1MmZlY2Q4LCAweGY3MGU1OTM5KSwgbmV3IFg2NFdvcmQuaW5pdCgweDY3MzMyNjY3LCAweGZmYzAwYjMxKSwgbmV3IFg2NFdvcmQuaW5pdCgweDhlYjQ0YTg3LCAweDY4NTgxNTExKSwgbmV3IFg2NFdvcmQuaW5pdCgweGRiMGMyZTBkLCAweDY0Zjk4ZmE3KSwgbmV3IFg2NFdvcmQuaW5pdCgweDQ3YjU0ODFkLCAweGJlZmE0ZmE0KV0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBoYXNoID0gU0hBNTEyLl9kb0ZpbmFsaXplLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgaGFzaC5zaWdCeXRlcyAtPSAxNjsKICAgICAgICAgICAgICByZXR1cm4gaGFzaDsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTM4NCgnbWVzc2FnZScpOwogICAgICAgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuU0hBMzg0KHdvcmRBcnJheSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuU0hBMzg0ID0gU0hBNTEyLl9jcmVhdGVIZWxwZXIoU0hBMzg0KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC4KICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICoKICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgKgogICAgICAgICAgICogICAgIHZhciBobWFjID0gQ3J5cHRvSlMuSG1hY1NIQTM4NChtZXNzYWdlLCBrZXkpOwogICAgICAgICAgICovCiAgICAgICAgICBDLkhtYWNTSEEzODQgPSBTSEE1MTIuX2NyZWF0ZUhtYWNIZWxwZXIoU0hBMzg0KTsKICAgICAgICB9KSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5TSEEzODQ7CiAgICAgIH0pOwogICAgfSkoc2hhMzg0JDEpOwogICAgcmV0dXJuIHNoYTM4NCQxLmV4cG9ydHM7CiAgfQoKICB2YXIgc2hhMyQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIHNoYTMgPSBzaGEzJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRTaGEzOwogIGZ1bmN0aW9uIHJlcXVpcmVTaGEzKCkgewogICAgaWYgKGhhc1JlcXVpcmVkU2hhMykgcmV0dXJuIHNoYTMkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRTaGEzID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZVg2NENvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShzaGEzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAoZnVuY3Rpb24gKE1hdGgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFdvcmRBcnJheSA9IENfbGliLldvcmRBcnJheTsKICAgICAgICAgIHZhciBIYXNoZXIgPSBDX2xpYi5IYXNoZXI7CiAgICAgICAgICB2YXIgQ194NjQgPSBDLng2NDsKICAgICAgICAgIHZhciBYNjRXb3JkID0gQ194NjQuV29yZDsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CgogICAgICAgICAgLy8gQ29uc3RhbnRzIHRhYmxlcwogICAgICAgICAgdmFyIFJIT19PRkZTRVRTID0gW107CiAgICAgICAgICB2YXIgUElfSU5ERVhFUyA9IFtdOwogICAgICAgICAgdmFyIFJPVU5EX0NPTlNUQU5UUyA9IFtdOwoKICAgICAgICAgIC8vIENvbXB1dGUgQ29uc3RhbnRzCiAgICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgICAvLyBDb21wdXRlIHJobyBvZmZzZXQgY29uc3RhbnRzCiAgICAgICAgICAgIHZhciB4ID0gMSwKICAgICAgICAgICAgICB5ID0gMDsKICAgICAgICAgICAgZm9yICh2YXIgdCA9IDA7IHQgPCAyNDsgdCsrKSB7CiAgICAgICAgICAgICAgUkhPX09GRlNFVFNbeCArIDUgKiB5XSA9ICh0ICsgMSkgKiAodCArIDIpIC8gMiAlIDY0OwogICAgICAgICAgICAgIHZhciBuZXdYID0geSAlIDU7CiAgICAgICAgICAgICAgdmFyIG5ld1kgPSAoMiAqIHggKyAzICogeSkgJSA1OwogICAgICAgICAgICAgIHggPSBuZXdYOwogICAgICAgICAgICAgIHkgPSBuZXdZOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDb21wdXRlIHBpIGluZGV4IGNvbnN0YW50cwogICAgICAgICAgICBmb3IgKHZhciB4ID0gMDsgeCA8IDU7IHgrKykgewogICAgICAgICAgICAgIGZvciAodmFyIHkgPSAwOyB5IDwgNTsgeSsrKSB7CiAgICAgICAgICAgICAgICBQSV9JTkRFWEVTW3ggKyA1ICogeV0gPSB5ICsgKDIgKiB4ICsgMyAqIHkpICUgNSAqIDU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvLyBDb21wdXRlIHJvdW5kIGNvbnN0YW50cwogICAgICAgICAgICB2YXIgTEZTUiA9IDB4MDE7CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjQ7IGkrKykgewogICAgICAgICAgICAgIHZhciByb3VuZENvbnN0YW50TXN3ID0gMDsKICAgICAgICAgICAgICB2YXIgcm91bmRDb25zdGFudExzdyA9IDA7CiAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCA3OyBqKyspIHsKICAgICAgICAgICAgICAgIGlmIChMRlNSICYgMHgwMSkgewogICAgICAgICAgICAgICAgICB2YXIgYml0UG9zaXRpb24gPSAoMSA8PCBqKSAtIDE7CiAgICAgICAgICAgICAgICAgIGlmIChiaXRQb3NpdGlvbiA8IDMyKSB7CiAgICAgICAgICAgICAgICAgICAgcm91bmRDb25zdGFudExzdyBePSAxIDw8IGJpdFBvc2l0aW9uOwogICAgICAgICAgICAgICAgICB9IGVsc2UgLyogaWYgKGJpdFBvc2l0aW9uID49IDMyKSAqL3sKICAgICAgICAgICAgICAgICAgICAgIHJvdW5kQ29uc3RhbnRNc3cgXj0gMSA8PCBiaXRQb3NpdGlvbiAtIDMyOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBDb21wdXRlIG5leHQgTEZTUgogICAgICAgICAgICAgICAgaWYgKExGU1IgJiAweDgwKSB7CiAgICAgICAgICAgICAgICAgIC8vIFByaW1pdGl2ZSBwb2x5bm9taWFsIG92ZXIgR0YoMik6IHheOCArIHheNiArIHheNSArIHheNCArIDEKICAgICAgICAgICAgICAgICAgTEZTUiA9IExGU1IgPDwgMSBeIDB4NzE7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICBMRlNSIDw8PSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBST1VORF9DT05TVEFOVFNbaV0gPSBYNjRXb3JkLmNyZWF0ZShyb3VuZENvbnN0YW50TXN3LCByb3VuZENvbnN0YW50THN3KTsKICAgICAgICAgICAgfQogICAgICAgICAgfSkoKTsKCiAgICAgICAgICAvLyBSZXVzYWJsZSBvYmplY3RzIGZvciB0ZW1wb3JhcnkgdmFsdWVzCiAgICAgICAgICB2YXIgVCA9IFtdOwogICAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTsgaSsrKSB7CiAgICAgICAgICAgICAgVFtpXSA9IFg2NFdvcmQuY3JlYXRlKCk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pKCk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTSEEtMyBoYXNoIGFsZ29yaXRobS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIFNIQTMgPSBDX2FsZ28uU0hBMyA9IEhhc2hlci5leHRlbmQoewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gb3V0cHV0TGVuZ3RoCiAgICAgICAgICAgICAqICAgVGhlIGRlc2lyZWQgbnVtYmVyIG9mIGJpdHMgaW4gdGhlIG91dHB1dCBoYXNoLgogICAgICAgICAgICAgKiAgIE9ubHkgdmFsdWVzIHBlcm1pdHRlZCBhcmU6IDIyNCwgMjU2LCAzODQsIDUxMi4KICAgICAgICAgICAgICogICBEZWZhdWx0OiA1MTIKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNmZzogSGFzaGVyLmNmZy5leHRlbmQoewogICAgICAgICAgICAgIG91dHB1dExlbmd0aDogNTEyCiAgICAgICAgICAgIH0pLAogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBzdGF0ZSA9IHRoaXMuX3N0YXRlID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTsgaSsrKSB7CiAgICAgICAgICAgICAgICBzdGF0ZVtpXSA9IG5ldyBYNjRXb3JkLmluaXQoKTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgdGhpcy5ibG9ja1NpemUgPSAoMTYwMCAtIDIgKiB0aGlzLmNmZy5vdXRwdXRMZW5ndGgpIC8gMzI7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9kb1Byb2Nlc3NCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBzdGF0ZSA9IHRoaXMuX3N0YXRlOwogICAgICAgICAgICAgIHZhciBuQmxvY2tTaXplTGFuZXMgPSB0aGlzLmJsb2NrU2l6ZSAvIDI7CgogICAgICAgICAgICAgIC8vIEFic29yYgogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbkJsb2NrU2l6ZUxhbmVzOyBpKyspIHsKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgdmFyIE0yaSA9IE1bb2Zmc2V0ICsgMiAqIGldOwogICAgICAgICAgICAgICAgdmFyIE0yaTEgPSBNW29mZnNldCArIDIgKiBpICsgMV07CgogICAgICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW4KICAgICAgICAgICAgICAgIE0yaSA9IChNMmkgPDwgOCB8IE0yaSA+Pj4gMjQpICYgMHgwMGZmMDBmZiB8IChNMmkgPDwgMjQgfCBNMmkgPj4+IDgpICYgMHhmZjAwZmYwMDsKICAgICAgICAgICAgICAgIE0yaTEgPSAoTTJpMSA8PCA4IHwgTTJpMSA+Pj4gMjQpICYgMHgwMGZmMDBmZiB8IChNMmkxIDw8IDI0IHwgTTJpMSA+Pj4gOCkgJiAweGZmMDBmZjAwOwoKICAgICAgICAgICAgICAgIC8vIEFic29yYiBtZXNzYWdlIGludG8gc3RhdGUKICAgICAgICAgICAgICAgIHZhciBsYW5lID0gc3RhdGVbaV07CiAgICAgICAgICAgICAgICBsYW5lLmhpZ2ggXj0gTTJpMTsKICAgICAgICAgICAgICAgIGxhbmUubG93IF49IE0yaTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFJvdW5kcwogICAgICAgICAgICAgIGZvciAodmFyIHJvdW5kID0gMDsgcm91bmQgPCAyNDsgcm91bmQrKykgewogICAgICAgICAgICAgICAgLy8gVGhldGEKICAgICAgICAgICAgICAgIGZvciAodmFyIHggPSAwOyB4IDwgNTsgeCsrKSB7CiAgICAgICAgICAgICAgICAgIC8vIE1peCBjb2x1bW4gbGFuZXMKICAgICAgICAgICAgICAgICAgdmFyIHRNc3cgPSAwLAogICAgICAgICAgICAgICAgICAgIHRMc3cgPSAwOwogICAgICAgICAgICAgICAgICBmb3IgKHZhciB5ID0gMDsgeSA8IDU7IHkrKykgewogICAgICAgICAgICAgICAgICAgIHZhciBsYW5lID0gc3RhdGVbeCArIDUgKiB5XTsKICAgICAgICAgICAgICAgICAgICB0TXN3IF49IGxhbmUuaGlnaDsKICAgICAgICAgICAgICAgICAgICB0THN3IF49IGxhbmUubG93OwogICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAvLyBUZW1wb3JhcnkgdmFsdWVzCiAgICAgICAgICAgICAgICAgIHZhciBUeCA9IFRbeF07CiAgICAgICAgICAgICAgICAgIFR4LmhpZ2ggPSB0TXN3OwogICAgICAgICAgICAgICAgICBUeC5sb3cgPSB0THN3OwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZm9yICh2YXIgeCA9IDA7IHggPCA1OyB4KyspIHsKICAgICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgICAgIHZhciBUeDQgPSBUWyh4ICsgNCkgJSA1XTsKICAgICAgICAgICAgICAgICAgdmFyIFR4MSA9IFRbKHggKyAxKSAlIDVdOwogICAgICAgICAgICAgICAgICB2YXIgVHgxTXN3ID0gVHgxLmhpZ2g7CiAgICAgICAgICAgICAgICAgIHZhciBUeDFMc3cgPSBUeDEubG93OwoKICAgICAgICAgICAgICAgICAgLy8gTWl4IHN1cnJvdW5kaW5nIGNvbHVtbnMKICAgICAgICAgICAgICAgICAgdmFyIHRNc3cgPSBUeDQuaGlnaCBeIChUeDFNc3cgPDwgMSB8IFR4MUxzdyA+Pj4gMzEpOwogICAgICAgICAgICAgICAgICB2YXIgdExzdyA9IFR4NC5sb3cgXiAoVHgxTHN3IDw8IDEgfCBUeDFNc3cgPj4+IDMxKTsKICAgICAgICAgICAgICAgICAgZm9yICh2YXIgeSA9IDA7IHkgPCA1OyB5KyspIHsKICAgICAgICAgICAgICAgICAgICB2YXIgbGFuZSA9IHN0YXRlW3ggKyA1ICogeV07CiAgICAgICAgICAgICAgICAgICAgbGFuZS5oaWdoIF49IHRNc3c7CiAgICAgICAgICAgICAgICAgICAgbGFuZS5sb3cgXj0gdExzdzsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIC8vIFJobyBQaQogICAgICAgICAgICAgICAgZm9yICh2YXIgbGFuZUluZGV4ID0gMTsgbGFuZUluZGV4IDwgMjU7IGxhbmVJbmRleCsrKSB7CiAgICAgICAgICAgICAgICAgIHZhciB0TXN3OwogICAgICAgICAgICAgICAgICB2YXIgdExzdzsKCiAgICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgICB2YXIgbGFuZSA9IHN0YXRlW2xhbmVJbmRleF07CiAgICAgICAgICAgICAgICAgIHZhciBsYW5lTXN3ID0gbGFuZS5oaWdoOwogICAgICAgICAgICAgICAgICB2YXIgbGFuZUxzdyA9IGxhbmUubG93OwogICAgICAgICAgICAgICAgICB2YXIgcmhvT2Zmc2V0ID0gUkhPX09GRlNFVFNbbGFuZUluZGV4XTsKCiAgICAgICAgICAgICAgICAgIC8vIFJvdGF0ZSBsYW5lcwogICAgICAgICAgICAgICAgICBpZiAocmhvT2Zmc2V0IDwgMzIpIHsKICAgICAgICAgICAgICAgICAgICB0TXN3ID0gbGFuZU1zdyA8PCByaG9PZmZzZXQgfCBsYW5lTHN3ID4+PiAzMiAtIHJob09mZnNldDsKICAgICAgICAgICAgICAgICAgICB0THN3ID0gbGFuZUxzdyA8PCByaG9PZmZzZXQgfCBsYW5lTXN3ID4+PiAzMiAtIHJob09mZnNldDsKICAgICAgICAgICAgICAgICAgfSBlbHNlIC8qIGlmIChyaG9PZmZzZXQgPj0gMzIpICovewogICAgICAgICAgICAgICAgICAgICAgdE1zdyA9IGxhbmVMc3cgPDwgcmhvT2Zmc2V0IC0gMzIgfCBsYW5lTXN3ID4+PiA2NCAtIHJob09mZnNldDsKICAgICAgICAgICAgICAgICAgICAgIHRMc3cgPSBsYW5lTXN3IDw8IHJob09mZnNldCAtIDMyIHwgbGFuZUxzdyA+Pj4gNjQgLSByaG9PZmZzZXQ7CiAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgLy8gVHJhbnNwb3NlIGxhbmVzCiAgICAgICAgICAgICAgICAgIHZhciBUUGlMYW5lID0gVFtQSV9JTkRFWEVTW2xhbmVJbmRleF1dOwogICAgICAgICAgICAgICAgICBUUGlMYW5lLmhpZ2ggPSB0TXN3OwogICAgICAgICAgICAgICAgICBUUGlMYW5lLmxvdyA9IHRMc3c7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLy8gUmhvIHBpIGF0IHggPSB5ID0gMAogICAgICAgICAgICAgICAgdmFyIFQwID0gVFswXTsKICAgICAgICAgICAgICAgIHZhciBzdGF0ZTAgPSBzdGF0ZVswXTsKICAgICAgICAgICAgICAgIFQwLmhpZ2ggPSBzdGF0ZTAuaGlnaDsKICAgICAgICAgICAgICAgIFQwLmxvdyA9IHN0YXRlMC5sb3c7CgogICAgICAgICAgICAgICAgLy8gQ2hpCiAgICAgICAgICAgICAgICBmb3IgKHZhciB4ID0gMDsgeCA8IDU7IHgrKykgewogICAgICAgICAgICAgICAgICBmb3IgKHZhciB5ID0gMDsgeSA8IDU7IHkrKykgewogICAgICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgICAgIHZhciBsYW5lSW5kZXggPSB4ICsgNSAqIHk7CiAgICAgICAgICAgICAgICAgICAgdmFyIGxhbmUgPSBzdGF0ZVtsYW5lSW5kZXhdOwogICAgICAgICAgICAgICAgICAgIHZhciBUTGFuZSA9IFRbbGFuZUluZGV4XTsKICAgICAgICAgICAgICAgICAgICB2YXIgVHgxTGFuZSA9IFRbKHggKyAxKSAlIDUgKyA1ICogeV07CiAgICAgICAgICAgICAgICAgICAgdmFyIFR4MkxhbmUgPSBUWyh4ICsgMikgJSA1ICsgNSAqIHldOwoKICAgICAgICAgICAgICAgICAgICAvLyBNaXggcm93cwogICAgICAgICAgICAgICAgICAgIGxhbmUuaGlnaCA9IFRMYW5lLmhpZ2ggXiB+VHgxTGFuZS5oaWdoICYgVHgyTGFuZS5oaWdoOwogICAgICAgICAgICAgICAgICAgIGxhbmUubG93ID0gVExhbmUubG93IF4gflR4MUxhbmUubG93ICYgVHgyTGFuZS5sb3c7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBJb3RhCiAgICAgICAgICAgICAgICB2YXIgbGFuZSA9IHN0YXRlWzBdOwogICAgICAgICAgICAgICAgdmFyIHJvdW5kQ29uc3RhbnQgPSBST1VORF9DT05TVEFOVFNbcm91bmRdOwogICAgICAgICAgICAgICAgbGFuZS5oaWdoIF49IHJvdW5kQ29uc3RhbnQuaGlnaDsKICAgICAgICAgICAgICAgIGxhbmUubG93IF49IHJvdW5kQ29uc3RhbnQubG93OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7CiAgICAgICAgICAgICAgdmFyIGRhdGFXb3JkcyA9IGRhdGEud29yZHM7CiAgICAgICAgICAgICAgdGhpcy5fbkRhdGFCeXRlcyAqIDg7CiAgICAgICAgICAgICAgdmFyIG5CaXRzTGVmdCA9IGRhdGEuc2lnQnl0ZXMgKiA4OwogICAgICAgICAgICAgIHZhciBibG9ja1NpemVCaXRzID0gdGhpcy5ibG9ja1NpemUgKiAzMjsKCiAgICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmcKICAgICAgICAgICAgICBkYXRhV29yZHNbbkJpdHNMZWZ0ID4+PiA1XSB8PSAweDEgPDwgMjQgLSBuQml0c0xlZnQgJSAzMjsKICAgICAgICAgICAgICBkYXRhV29yZHNbKE1hdGguY2VpbCgobkJpdHNMZWZ0ICsgMSkgLyBibG9ja1NpemVCaXRzKSAqIGJsb2NrU2l6ZUJpdHMgPj4+IDUpIC0gMV0gfD0gMHg4MDsKICAgICAgICAgICAgICBkYXRhLnNpZ0J5dGVzID0gZGF0YVdvcmRzLmxlbmd0aCAqIDQ7CgogICAgICAgICAgICAgIC8vIEhhc2ggZmluYWwgYmxvY2tzCiAgICAgICAgICAgICAgdGhpcy5fcHJvY2VzcygpOwoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgc3RhdGUgPSB0aGlzLl9zdGF0ZTsKICAgICAgICAgICAgICB2YXIgb3V0cHV0TGVuZ3RoQnl0ZXMgPSB0aGlzLmNmZy5vdXRwdXRMZW5ndGggLyA4OwogICAgICAgICAgICAgIHZhciBvdXRwdXRMZW5ndGhMYW5lcyA9IG91dHB1dExlbmd0aEJ5dGVzIC8gODsKCiAgICAgICAgICAgICAgLy8gU3F1ZWV6ZQogICAgICAgICAgICAgIHZhciBoYXNoV29yZHMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG91dHB1dExlbmd0aExhbmVzOyBpKyspIHsKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgdmFyIGxhbmUgPSBzdGF0ZVtpXTsKICAgICAgICAgICAgICAgIHZhciBsYW5lTXN3ID0gbGFuZS5oaWdoOwogICAgICAgICAgICAgICAgdmFyIGxhbmVMc3cgPSBsYW5lLmxvdzsKCiAgICAgICAgICAgICAgICAvLyBTd2FwIGVuZGlhbgogICAgICAgICAgICAgICAgbGFuZU1zdyA9IChsYW5lTXN3IDw8IDggfCBsYW5lTXN3ID4+PiAyNCkgJiAweDAwZmYwMGZmIHwgKGxhbmVNc3cgPDwgMjQgfCBsYW5lTXN3ID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgICBsYW5lTHN3ID0gKGxhbmVMc3cgPDwgOCB8IGxhbmVMc3cgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAobGFuZUxzdyA8PCAyNCB8IGxhbmVMc3cgPj4+IDgpICYgMHhmZjAwZmYwMDsKCiAgICAgICAgICAgICAgICAvLyBTcXVlZXplIHN0YXRlIHRvIHJldHJpZXZlIGhhc2gKICAgICAgICAgICAgICAgIGhhc2hXb3Jkcy5wdXNoKGxhbmVMc3cpOwogICAgICAgICAgICAgICAgaGFzaFdvcmRzLnB1c2gobGFuZU1zdyk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaAogICAgICAgICAgICAgIHJldHVybiBuZXcgV29yZEFycmF5LmluaXQoaGFzaFdvcmRzLCBvdXRwdXRMZW5ndGhCeXRlcyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGNsb25lOiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdmFyIGNsb25lID0gSGFzaGVyLmNsb25lLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgdmFyIHN0YXRlID0gY2xvbmUuX3N0YXRlID0gdGhpcy5fc3RhdGUuc2xpY2UoMCk7CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTsgaSsrKSB7CiAgICAgICAgICAgICAgICBzdGF0ZVtpXSA9IHN0YXRlW2ldLmNsb25lKCk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTMoJ21lc3NhZ2UnKTsKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlNIQTMod29yZEFycmF5KTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5TSEEzID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoU0hBMyk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgSE1BQydzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGhhc2guCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IGtleSBUaGUgc2VjcmV0IGtleS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBITUFDLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaG1hYyA9IENyeXB0b0pTLkhtYWNTSEEzKG1lc3NhZ2UsIGtleSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuSG1hY1NIQTMgPSBIYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoU0hBMyk7CiAgICAgICAgfSkoTWF0aCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlNIQTM7CiAgICAgIH0pOwogICAgfSkoc2hhMyQxKTsKICAgIHJldHVybiBzaGEzJDEuZXhwb3J0czsKICB9CgogIHZhciByaXBlbWQxNjAkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciByaXBlbWQxNjAgPSByaXBlbWQxNjAkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFJpcGVtZDE2MDsKICBmdW5jdGlvbiByZXF1aXJlUmlwZW1kMTYwKCkgewogICAgaWYgKGhhc1JlcXVpcmVkUmlwZW1kMTYwKSByZXR1cm4gcmlwZW1kMTYwJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUmlwZW1kMTYwID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHJpcGVtZDE2MCwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgLyoqIEBwcmVzZXJ2ZQogICAgICAgIChjKSAyMDEyIGJ5IEPDqWRyaWMgTWVzbmlsLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogICAgICAgIAlSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6CiAgICAgICAgCSAgICAtIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICAgICAgICAgICAgLSBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCiAgICAgICAgCVRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAgICAgICAgKi8KCiAgICAgICAgKGZ1bmN0aW9uIChNYXRoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgSGFzaGVyID0gQ19saWIuSGFzaGVyOwogICAgICAgICAgdmFyIENfYWxnbyA9IEMuYWxnbzsKCiAgICAgICAgICAvLyBDb25zdGFudHMgdGFibGUKICAgICAgICAgIHZhciBfemwgPSBXb3JkQXJyYXkuY3JlYXRlKFswLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LCA3LCA0LCAxMywgMSwgMTAsIDYsIDE1LCAzLCAxMiwgMCwgOSwgNSwgMiwgMTQsIDExLCA4LCAzLCAxMCwgMTQsIDQsIDksIDE1LCA4LCAxLCAyLCA3LCAwLCA2LCAxMywgMTEsIDUsIDEyLCAxLCA5LCAxMSwgMTAsIDAsIDgsIDEyLCA0LCAxMywgMywgNywgMTUsIDE0LCA1LCA2LCAyLCA0LCAwLCA1LCA5LCA3LCAxMiwgMiwgMTAsIDE0LCAxLCAzLCA4LCAxMSwgNiwgMTUsIDEzXSk7CiAgICAgICAgICB2YXIgX3pyID0gV29yZEFycmF5LmNyZWF0ZShbNSwgMTQsIDcsIDAsIDksIDIsIDExLCA0LCAxMywgNiwgMTUsIDgsIDEsIDEwLCAzLCAxMiwgNiwgMTEsIDMsIDcsIDAsIDEzLCA1LCAxMCwgMTQsIDE1LCA4LCAxMiwgNCwgOSwgMSwgMiwgMTUsIDUsIDEsIDMsIDcsIDE0LCA2LCA5LCAxMSwgOCwgMTIsIDIsIDEwLCAwLCA0LCAxMywgOCwgNiwgNCwgMSwgMywgMTEsIDE1LCAwLCA1LCAxMiwgMiwgMTMsIDksIDcsIDEwLCAxNCwgMTIsIDE1LCAxMCwgNCwgMSwgNSwgOCwgNywgNiwgMiwgMTMsIDE0LCAwLCAzLCA5LCAxMV0pOwogICAgICAgICAgdmFyIF9zbCA9IFdvcmRBcnJheS5jcmVhdGUoWzExLCAxNCwgMTUsIDEyLCA1LCA4LCA3LCA5LCAxMSwgMTMsIDE0LCAxNSwgNiwgNywgOSwgOCwgNywgNiwgOCwgMTMsIDExLCA5LCA3LCAxNSwgNywgMTIsIDE1LCA5LCAxMSwgNywgMTMsIDEyLCAxMSwgMTMsIDYsIDcsIDE0LCA5LCAxMywgMTUsIDE0LCA4LCAxMywgNiwgNSwgMTIsIDcsIDUsIDExLCAxMiwgMTQsIDE1LCAxNCwgMTUsIDksIDgsIDksIDE0LCA1LCA2LCA4LCA2LCA1LCAxMiwgOSwgMTUsIDUsIDExLCA2LCA4LCAxMywgMTIsIDUsIDEyLCAxMywgMTQsIDExLCA4LCA1LCA2XSk7CiAgICAgICAgICB2YXIgX3NyID0gV29yZEFycmF5LmNyZWF0ZShbOCwgOSwgOSwgMTEsIDEzLCAxNSwgMTUsIDUsIDcsIDcsIDgsIDExLCAxNCwgMTQsIDEyLCA2LCA5LCAxMywgMTUsIDcsIDEyLCA4LCA5LCAxMSwgNywgNywgMTIsIDcsIDYsIDE1LCAxMywgMTEsIDksIDcsIDE1LCAxMSwgOCwgNiwgNiwgMTQsIDEyLCAxMywgNSwgMTQsIDEzLCAxMywgNywgNSwgMTUsIDUsIDgsIDExLCAxNCwgMTQsIDYsIDE0LCA2LCA5LCAxMiwgOSwgMTIsIDUsIDE1LCA4LCA4LCA1LCAxMiwgOSwgMTIsIDUsIDE0LCA2LCA4LCAxMywgNiwgNSwgMTUsIDEzLCAxMSwgMTFdKTsKICAgICAgICAgIHZhciBfaGwgPSBXb3JkQXJyYXkuY3JlYXRlKFsweDAwMDAwMDAwLCAweDVBODI3OTk5LCAweDZFRDlFQkExLCAweDhGMUJCQ0RDLCAweEE5NTNGRDRFXSk7CiAgICAgICAgICB2YXIgX2hyID0gV29yZEFycmF5LmNyZWF0ZShbMHg1MEEyOEJFNiwgMHg1QzRERDEyNCwgMHg2RDcwM0VGMywgMHg3QTZENzZFOSwgMHgwMDAwMDAwMF0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogUklQRU1EMTYwIGhhc2ggYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgUklQRU1EMTYwID0gQ19hbGdvLlJJUEVNRDE2MCA9IEhhc2hlci5leHRlbmQoewogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHRoaXMuX2hhc2ggPSBXb3JkQXJyYXkuY3JlYXRlKFsweDY3NDUyMzAxLCAweEVGQ0RBQjg5LCAweDk4QkFEQ0ZFLCAweDEwMzI1NDc2LCAweEMzRDJFMUYwXSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIF9kb1Byb2Nlc3NCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkgewogICAgICAgICAgICAgIC8vIFN3YXAgZW5kaWFuCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxNjsgaSsrKSB7CiAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICAgIHZhciBvZmZzZXRfaSA9IG9mZnNldCArIGk7CiAgICAgICAgICAgICAgICB2YXIgTV9vZmZzZXRfaSA9IE1bb2Zmc2V0X2ldOwoKICAgICAgICAgICAgICAgIC8vIFN3YXAKICAgICAgICAgICAgICAgIE1bb2Zmc2V0X2ldID0gKE1fb2Zmc2V0X2kgPDwgOCB8IE1fb2Zmc2V0X2kgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoTV9vZmZzZXRfaSA8PCAyNCB8IE1fb2Zmc2V0X2kgPj4+IDgpICYgMHhmZjAwZmYwMDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgSCA9IHRoaXMuX2hhc2gud29yZHM7CiAgICAgICAgICAgICAgdmFyIGhsID0gX2hsLndvcmRzOwogICAgICAgICAgICAgIHZhciBociA9IF9oci53b3JkczsKICAgICAgICAgICAgICB2YXIgemwgPSBfemwud29yZHM7CiAgICAgICAgICAgICAgdmFyIHpyID0gX3pyLndvcmRzOwogICAgICAgICAgICAgIHZhciBzbCA9IF9zbC53b3JkczsKICAgICAgICAgICAgICB2YXIgc3IgPSBfc3Iud29yZHM7CgogICAgICAgICAgICAgIC8vIFdvcmtpbmcgdmFyaWFibGVzCiAgICAgICAgICAgICAgdmFyIGFsLCBibCwgY2wsIGRsLCBlbDsKICAgICAgICAgICAgICB2YXIgYXIsIGJyLCBjciwgZHIsIGVyOwogICAgICAgICAgICAgIGFyID0gYWwgPSBIWzBdOwogICAgICAgICAgICAgIGJyID0gYmwgPSBIWzFdOwogICAgICAgICAgICAgIGNyID0gY2wgPSBIWzJdOwogICAgICAgICAgICAgIGRyID0gZGwgPSBIWzNdOwogICAgICAgICAgICAgIGVyID0gZWwgPSBIWzRdOwogICAgICAgICAgICAgIC8vIENvbXB1dGF0aW9uCiAgICAgICAgICAgICAgdmFyIHQ7CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4MDsgaSArPSAxKSB7CiAgICAgICAgICAgICAgICB0ID0gYWwgKyBNW29mZnNldCArIHpsW2ldXSB8IDA7CiAgICAgICAgICAgICAgICBpZiAoaSA8IDE2KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjEoYmwsIGNsLCBkbCkgKyBobFswXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDMyKSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjIoYmwsIGNsLCBkbCkgKyBobFsxXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDQ4KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjMoYmwsIGNsLCBkbCkgKyBobFsyXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDY0KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjQoYmwsIGNsLCBkbCkgKyBobFszXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIC8vIGlmIChpPDgwKSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjUoYmwsIGNsLCBkbCkgKyBobFs0XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHQgPSB0IHwgMDsKICAgICAgICAgICAgICAgIHQgPSByb3RsKHQsIHNsW2ldKTsKICAgICAgICAgICAgICAgIHQgPSB0ICsgZWwgfCAwOwogICAgICAgICAgICAgICAgYWwgPSBlbDsKICAgICAgICAgICAgICAgIGVsID0gZGw7CiAgICAgICAgICAgICAgICBkbCA9IHJvdGwoY2wsIDEwKTsKICAgICAgICAgICAgICAgIGNsID0gYmw7CiAgICAgICAgICAgICAgICBibCA9IHQ7CiAgICAgICAgICAgICAgICB0ID0gYXIgKyBNW29mZnNldCArIHpyW2ldXSB8IDA7CiAgICAgICAgICAgICAgICBpZiAoaSA8IDE2KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjUoYnIsIGNyLCBkcikgKyBoclswXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDMyKSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjQoYnIsIGNyLCBkcikgKyBoclsxXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDQ4KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjMoYnIsIGNyLCBkcikgKyBoclsyXTsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaSA8IDY0KSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjIoYnIsIGNyLCBkcikgKyBoclszXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIC8vIGlmIChpPDgwKSB7CiAgICAgICAgICAgICAgICAgIHQgKz0gZjEoYnIsIGNyLCBkcikgKyBocls0XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHQgPSB0IHwgMDsKICAgICAgICAgICAgICAgIHQgPSByb3RsKHQsIHNyW2ldKTsKICAgICAgICAgICAgICAgIHQgPSB0ICsgZXIgfCAwOwogICAgICAgICAgICAgICAgYXIgPSBlcjsKICAgICAgICAgICAgICAgIGVyID0gZHI7CiAgICAgICAgICAgICAgICBkciA9IHJvdGwoY3IsIDEwKTsKICAgICAgICAgICAgICAgIGNyID0gYnI7CiAgICAgICAgICAgICAgICBiciA9IHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8vIEludGVybWVkaWF0ZSBoYXNoIHZhbHVlCiAgICAgICAgICAgICAgdCA9IEhbMV0gKyBjbCArIGRyIHwgMDsKICAgICAgICAgICAgICBIWzFdID0gSFsyXSArIGRsICsgZXIgfCAwOwogICAgICAgICAgICAgIEhbMl0gPSBIWzNdICsgZWwgKyBhciB8IDA7CiAgICAgICAgICAgICAgSFszXSA9IEhbNF0gKyBhbCArIGJyIHwgMDsKICAgICAgICAgICAgICBIWzRdID0gSFswXSArIGJsICsgY3IgfCAwOwogICAgICAgICAgICAgIEhbMF0gPSB0OwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBkYXRhID0gdGhpcy5fZGF0YTsKICAgICAgICAgICAgICB2YXIgZGF0YVdvcmRzID0gZGF0YS53b3JkczsKICAgICAgICAgICAgICB2YXIgbkJpdHNUb3RhbCA9IHRoaXMuX25EYXRhQnl0ZXMgKiA4OwogICAgICAgICAgICAgIHZhciBuQml0c0xlZnQgPSBkYXRhLnNpZ0J5dGVzICogODsKCiAgICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmcKICAgICAgICAgICAgICBkYXRhV29yZHNbbkJpdHNMZWZ0ID4+PiA1XSB8PSAweDgwIDw8IDI0IC0gbkJpdHNMZWZ0ICUgMzI7CiAgICAgICAgICAgICAgZGF0YVdvcmRzWyhuQml0c0xlZnQgKyA2NCA+Pj4gOSA8PCA0KSArIDE0XSA9IChuQml0c1RvdGFsIDw8IDggfCBuQml0c1RvdGFsID4+PiAyNCkgJiAweDAwZmYwMGZmIHwgKG5CaXRzVG90YWwgPDwgMjQgfCBuQml0c1RvdGFsID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IChkYXRhV29yZHMubGVuZ3RoICsgMSkgKiA0OwoKICAgICAgICAgICAgICAvLyBIYXNoIGZpbmFsIGJsb2NrcwogICAgICAgICAgICAgIHRoaXMuX3Byb2Nlc3MoKTsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGhhc2ggPSB0aGlzLl9oYXNoOwogICAgICAgICAgICAgIHZhciBIID0gaGFzaC53b3JkczsKCiAgICAgICAgICAgICAgLy8gU3dhcCBlbmRpYW4KICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDU7IGkrKykgewogICAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICAgIHZhciBIX2kgPSBIW2ldOwoKICAgICAgICAgICAgICAgIC8vIFN3YXAKICAgICAgICAgICAgICAgIEhbaV0gPSAoSF9pIDw8IDggfCBIX2kgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoSF9pIDw8IDI0IHwgSF9pID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBSZXR1cm4gZmluYWwgY29tcHV0ZWQgaGFzaAogICAgICAgICAgICAgIHJldHVybiBoYXNoOwogICAgICAgICAgICB9LAogICAgICAgICAgICBjbG9uZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBjbG9uZSA9IEhhc2hlci5jbG9uZS5jYWxsKHRoaXMpOwogICAgICAgICAgICAgIGNsb25lLl9oYXNoID0gdGhpcy5faGFzaC5jbG9uZSgpOwogICAgICAgICAgICAgIHJldHVybiBjbG9uZTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBmdW5jdGlvbiBmMSh4LCB5LCB6KSB7CiAgICAgICAgICAgIHJldHVybiB4IF4geSBeIHo7CiAgICAgICAgICB9CiAgICAgICAgICBmdW5jdGlvbiBmMih4LCB5LCB6KSB7CiAgICAgICAgICAgIHJldHVybiB4ICYgeSB8IH54ICYgejsKICAgICAgICAgIH0KICAgICAgICAgIGZ1bmN0aW9uIGYzKHgsIHksIHopIHsKICAgICAgICAgICAgcmV0dXJuICh4IHwgfnkpIF4gejsKICAgICAgICAgIH0KICAgICAgICAgIGZ1bmN0aW9uIGY0KHgsIHksIHopIHsKICAgICAgICAgICAgcmV0dXJuIHggJiB6IHwgeSAmIH56OwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gZjUoeCwgeSwgeikgewogICAgICAgICAgICByZXR1cm4geCBeICh5IHwgfnopOwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gcm90bCh4LCBuKSB7CiAgICAgICAgICAgIHJldHVybiB4IDw8IG4gfCB4ID4+PiAzMiAtIG47CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbiB0byB0aGUgaGFzaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcmV0dXJuIHtXb3JkQXJyYXl9IFRoZSBoYXNoLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgaGFzaCA9IENyeXB0b0pTLlJJUEVNRDE2MCgnbWVzc2FnZScpOwogICAgICAgICAgICogICAgIHZhciBoYXNoID0gQ3J5cHRvSlMuUklQRU1EMTYwKHdvcmRBcnJheSk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuUklQRU1EMTYwID0gSGFzaGVyLl9jcmVhdGVIZWxwZXIoUklQRU1EMTYwKTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9uIHRvIHRoZSBITUFDJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gaGFzaC4KICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICoKICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgKgogICAgICAgICAgICogICAgIHZhciBobWFjID0gQ3J5cHRvSlMuSG1hY1JJUEVNRDE2MChtZXNzYWdlLCBrZXkpOwogICAgICAgICAgICovCiAgICAgICAgICBDLkhtYWNSSVBFTUQxNjAgPSBIYXNoZXIuX2NyZWF0ZUhtYWNIZWxwZXIoUklQRU1EMTYwKTsKICAgICAgICB9KSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5SSVBFTUQxNjA7CiAgICAgIH0pOwogICAgfSkocmlwZW1kMTYwJDEpOwogICAgcmV0dXJuIHJpcGVtZDE2MCQxLmV4cG9ydHM7CiAgfQoKICB2YXIgaG1hYyQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIGhtYWMgPSBobWFjJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRIbWFjOwogIGZ1bmN0aW9uIHJlcXVpcmVIbWFjKCkgewogICAgaWYgKGhhc1JlcXVpcmVkSG1hYykgcmV0dXJuIGhtYWMkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRIbWFjID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5KSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKGhtYWMsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBCYXNlID0gQ19saWIuQmFzZTsKICAgICAgICAgIHZhciBDX2VuYyA9IEMuZW5jOwogICAgICAgICAgdmFyIFV0ZjggPSBDX2VuYy5VdGY4OwogICAgICAgICAgdmFyIENfYWxnbyA9IEMuYWxnbzsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEhNQUMgYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICBDX2FsZ28uSE1BQyA9IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBITUFDLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30ga2V5IFRoZSBzZWNyZXQga2V5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGhtYWNIYXNoZXIgPSBDcnlwdG9KUy5hbGdvLkhNQUMuY3JlYXRlKENyeXB0b0pTLmFsZ28uU0hBMjU2LCBrZXkpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaW5pdDogZnVuY3Rpb24gKGhhc2hlciwga2V5KSB7CiAgICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXIKICAgICAgICAgICAgICBoYXNoZXIgPSB0aGlzLl9oYXNoZXIgPSBuZXcgaGFzaGVyLmluaXQoKTsKCiAgICAgICAgICAgICAgLy8gQ29udmVydCBzdHJpbmcgdG8gV29yZEFycmF5LCBlbHNlIGFzc3VtZSBXb3JkQXJyYXkgYWxyZWFkeQogICAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ID09ICdzdHJpbmcnKSB7CiAgICAgICAgICAgICAgICBrZXkgPSBVdGY4LnBhcnNlKGtleSk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgaGFzaGVyQmxvY2tTaXplID0gaGFzaGVyLmJsb2NrU2l6ZTsKICAgICAgICAgICAgICB2YXIgaGFzaGVyQmxvY2tTaXplQnl0ZXMgPSBoYXNoZXJCbG9ja1NpemUgKiA0OwoKICAgICAgICAgICAgICAvLyBBbGxvdyBhcmJpdHJhcnkgbGVuZ3RoIGtleXMKICAgICAgICAgICAgICBpZiAoa2V5LnNpZ0J5dGVzID4gaGFzaGVyQmxvY2tTaXplQnl0ZXMpIHsKICAgICAgICAgICAgICAgIGtleSA9IGhhc2hlci5maW5hbGl6ZShrZXkpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gQ2xhbXAgZXhjZXNzIGJpdHMKICAgICAgICAgICAgICBrZXkuY2xhbXAoKTsKCiAgICAgICAgICAgICAgLy8gQ2xvbmUga2V5IGZvciBpbm5lciBhbmQgb3V0ZXIgcGFkcwogICAgICAgICAgICAgIHZhciBvS2V5ID0gdGhpcy5fb0tleSA9IGtleS5jbG9uZSgpOwogICAgICAgICAgICAgIHZhciBpS2V5ID0gdGhpcy5faUtleSA9IGtleS5jbG9uZSgpOwoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgb0tleVdvcmRzID0gb0tleS53b3JkczsKICAgICAgICAgICAgICB2YXIgaUtleVdvcmRzID0gaUtleS53b3JkczsKCiAgICAgICAgICAgICAgLy8gWE9SIGtleXMgd2l0aCBwYWQgY29uc3RhbnRzCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoYXNoZXJCbG9ja1NpemU7IGkrKykgewogICAgICAgICAgICAgICAgb0tleVdvcmRzW2ldIF49IDB4NWM1YzVjNWM7CiAgICAgICAgICAgICAgICBpS2V5V29yZHNbaV0gXj0gMHgzNjM2MzYzNjsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgb0tleS5zaWdCeXRlcyA9IGlLZXkuc2lnQnl0ZXMgPSBoYXNoZXJCbG9ja1NpemVCeXRlczsKCiAgICAgICAgICAgICAgLy8gU2V0IGluaXRpYWwgdmFsdWVzCiAgICAgICAgICAgICAgdGhpcy5yZXNldCgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUmVzZXRzIHRoaXMgSE1BQyB0byBpdHMgaW5pdGlhbCBzdGF0ZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIGhtYWNIYXNoZXIucmVzZXQoKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgaGFzaGVyID0gdGhpcy5faGFzaGVyOwoKICAgICAgICAgICAgICAvLyBSZXNldAogICAgICAgICAgICAgIGhhc2hlci5yZXNldCgpOwogICAgICAgICAgICAgIGhhc2hlci51cGRhdGUodGhpcy5faUtleSk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBVcGRhdGVzIHRoaXMgSE1BQyB3aXRoIGEgbWVzc2FnZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlVXBkYXRlIFRoZSBtZXNzYWdlIHRvIGFwcGVuZC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7SE1BQ30gVGhpcyBITUFDIGluc3RhbmNlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgaG1hY0hhc2hlci51cGRhdGUoJ21lc3NhZ2UnKTsKICAgICAgICAgICAgICogICAgIGhtYWNIYXNoZXIudXBkYXRlKHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICB1cGRhdGU6IGZ1bmN0aW9uIChtZXNzYWdlVXBkYXRlKSB7CiAgICAgICAgICAgICAgdGhpcy5faGFzaGVyLnVwZGF0ZShtZXNzYWdlVXBkYXRlKTsKCiAgICAgICAgICAgICAgLy8gQ2hhaW5hYmxlCiAgICAgICAgICAgICAgcmV0dXJuIHRoaXM7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBGaW5hbGl6ZXMgdGhlIEhNQUMgY29tcHV0YXRpb24uCiAgICAgICAgICAgICAqIE5vdGUgdGhhdCB0aGUgZmluYWxpemUgb3BlcmF0aW9uIGlzIGVmZmVjdGl2ZWx5IGEgZGVzdHJ1Y3RpdmUsIHJlYWQtb25jZSBvcGVyYXRpb24uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gbWVzc2FnZVVwZGF0ZSAoT3B0aW9uYWwpIEEgZmluYWwgbWVzc2FnZSB1cGRhdGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIEhNQUMuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgaG1hYyA9IGhtYWNIYXNoZXIuZmluYWxpemUoKTsKICAgICAgICAgICAgICogICAgIHZhciBobWFjID0gaG1hY0hhc2hlci5maW5hbGl6ZSgnbWVzc2FnZScpOwogICAgICAgICAgICAgKiAgICAgdmFyIGhtYWMgPSBobWFjSGFzaGVyLmZpbmFsaXplKHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBmaW5hbGl6ZTogZnVuY3Rpb24gKG1lc3NhZ2VVcGRhdGUpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBoYXNoZXIgPSB0aGlzLl9oYXNoZXI7CgogICAgICAgICAgICAgIC8vIENvbXB1dGUgSE1BQwogICAgICAgICAgICAgIHZhciBpbm5lckhhc2ggPSBoYXNoZXIuZmluYWxpemUobWVzc2FnZVVwZGF0ZSk7CiAgICAgICAgICAgICAgaGFzaGVyLnJlc2V0KCk7CiAgICAgICAgICAgICAgdmFyIGhtYWMgPSBoYXNoZXIuZmluYWxpemUodGhpcy5fb0tleS5jbG9uZSgpLmNvbmNhdChpbm5lckhhc2gpKTsKICAgICAgICAgICAgICByZXR1cm4gaG1hYzsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSkoKTsKICAgICAgfSk7CiAgICB9KShobWFjJDEpOwogICAgcmV0dXJuIGhtYWMkMS5leHBvcnRzOwogIH0KCiAgdmFyIHBia2RmMiQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIHBia2RmMiA9IHBia2RmMiQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkUGJrZGYyOwogIGZ1bmN0aW9uIHJlcXVpcmVQYmtkZjIoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRQYmtkZjIpIHJldHVybiBwYmtkZjIkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRQYmtkZjIgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlU2hhMjU2KCksIHJlcXVpcmVIbWFjKCkpOwogICAgICAgIH0KICAgICAgfSkocGJrZGYyLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICB2YXIgQyA9IENyeXB0b0pTOwogICAgICAgICAgdmFyIENfbGliID0gQy5saWI7CiAgICAgICAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7CiAgICAgICAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5OwogICAgICAgICAgdmFyIENfYWxnbyA9IEMuYWxnbzsKICAgICAgICAgIHZhciBTSEEyNTYgPSBDX2FsZ28uU0hBMjU2OwogICAgICAgICAgdmFyIEhNQUMgPSBDX2FsZ28uSE1BQzsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFBhc3N3b3JkLUJhc2VkIEtleSBEZXJpdmF0aW9uIEZ1bmN0aW9uIDIgYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgUEJLREYyID0gQ19hbGdvLlBCS0RGMiA9IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGtleVNpemUgVGhlIGtleSBzaXplIGluIHdvcmRzIHRvIGdlbmVyYXRlLiBEZWZhdWx0OiA0ICgxMjggYml0cykKICAgICAgICAgICAgICogQHByb3BlcnR5IHtIYXNoZXJ9IGhhc2hlciBUaGUgaGFzaGVyIHRvIHVzZS4gRGVmYXVsdDogU0hBMjU2CiAgICAgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpdGVyYXRpb25zIFRoZSBudW1iZXIgb2YgaXRlcmF0aW9ucyB0byBwZXJmb3JtLiBEZWZhdWx0OiAyNTAwMDAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNmZzogQmFzZS5leHRlbmQoewogICAgICAgICAgICAgIGtleVNpemU6IDEyOCAvIDMyLAogICAgICAgICAgICAgIGhhc2hlcjogU0hBMjU2LAogICAgICAgICAgICAgIGl0ZXJhdGlvbnM6IDI1MDAwMAogICAgICAgICAgICB9KSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGUgZGVyaXZhdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLlBCS0RGMi5jcmVhdGUoKTsKICAgICAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLlBCS0RGMi5jcmVhdGUoeyBrZXlTaXplOiA4IH0pOwogICAgICAgICAgICAgKiAgICAgdmFyIGtkZiA9IENyeXB0b0pTLmFsZ28uUEJLREYyLmNyZWF0ZSh7IGtleVNpemU6IDgsIGl0ZXJhdGlvbnM6IDEwMDAgfSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2ZnKSB7CiAgICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbXB1dGVzIHRoZSBQYXNzd29yZC1CYXNlZCBLZXkgRGVyaXZhdGlvbiBGdW5jdGlvbiAyLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC4KICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBzYWx0IEEgc2FsdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGVyaXZlZCBrZXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIga2V5ID0ga2RmLmNvbXB1dGUocGFzc3dvcmQsIHNhbHQpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY29tcHV0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5jZmc7CgogICAgICAgICAgICAgIC8vIEluaXQgSE1BQwogICAgICAgICAgICAgIHZhciBobWFjID0gSE1BQy5jcmVhdGUoY2ZnLmhhc2hlciwgcGFzc3dvcmQpOwoKICAgICAgICAgICAgICAvLyBJbml0aWFsIHZhbHVlcwogICAgICAgICAgICAgIHZhciBkZXJpdmVkS2V5ID0gV29yZEFycmF5LmNyZWF0ZSgpOwogICAgICAgICAgICAgIHZhciBibG9ja0luZGV4ID0gV29yZEFycmF5LmNyZWF0ZShbMHgwMDAwMDAwMV0pOwoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgZGVyaXZlZEtleVdvcmRzID0gZGVyaXZlZEtleS53b3JkczsKICAgICAgICAgICAgICB2YXIgYmxvY2tJbmRleFdvcmRzID0gYmxvY2tJbmRleC53b3JkczsKICAgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGNmZy5rZXlTaXplOwogICAgICAgICAgICAgIHZhciBpdGVyYXRpb25zID0gY2ZnLml0ZXJhdGlvbnM7CgogICAgICAgICAgICAgIC8vIEdlbmVyYXRlIGtleQogICAgICAgICAgICAgIHdoaWxlIChkZXJpdmVkS2V5V29yZHMubGVuZ3RoIDwga2V5U2l6ZSkgewogICAgICAgICAgICAgICAgdmFyIGJsb2NrID0gaG1hYy51cGRhdGUoc2FsdCkuZmluYWxpemUoYmxvY2tJbmRleCk7CiAgICAgICAgICAgICAgICBobWFjLnJlc2V0KCk7CgogICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgICB2YXIgYmxvY2tXb3JkcyA9IGJsb2NrLndvcmRzOwogICAgICAgICAgICAgICAgdmFyIGJsb2NrV29yZHNMZW5ndGggPSBibG9ja1dvcmRzLmxlbmd0aDsKCiAgICAgICAgICAgICAgICAvLyBJdGVyYXRpb25zCiAgICAgICAgICAgICAgICB2YXIgaW50ZXJtZWRpYXRlID0gYmxvY2s7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGl0ZXJhdGlvbnM7IGkrKykgewogICAgICAgICAgICAgICAgICBpbnRlcm1lZGlhdGUgPSBobWFjLmZpbmFsaXplKGludGVybWVkaWF0ZSk7CiAgICAgICAgICAgICAgICAgIGhtYWMucmVzZXQoKTsKCiAgICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgICAgIHZhciBpbnRlcm1lZGlhdGVXb3JkcyA9IGludGVybWVkaWF0ZS53b3JkczsKCiAgICAgICAgICAgICAgICAgIC8vIFhPUiBpbnRlcm1lZGlhdGUgd2l0aCBibG9jawogICAgICAgICAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGJsb2NrV29yZHNMZW5ndGg7IGorKykgewogICAgICAgICAgICAgICAgICAgIGJsb2NrV29yZHNbal0gXj0gaW50ZXJtZWRpYXRlV29yZHNbal07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRlcml2ZWRLZXkuY29uY2F0KGJsb2NrKTsKICAgICAgICAgICAgICAgIGJsb2NrSW5kZXhXb3Jkc1swXSsrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBkZXJpdmVkS2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7CiAgICAgICAgICAgICAgcmV0dXJuIGRlcml2ZWRLZXk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQ29tcHV0ZXMgdGhlIFBhc3N3b3JkLUJhc2VkIEtleSBEZXJpdmF0aW9uIEZ1bmN0aW9uIDIuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgQSBzYWx0LgogICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIGNvbXB1dGF0aW9uLgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRlcml2ZWQga2V5LgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuUEJLREYyKHBhc3N3b3JkLCBzYWx0KTsKICAgICAgICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuUEJLREYyKHBhc3N3b3JkLCBzYWx0LCB7IGtleVNpemU6IDggfSk7CiAgICAgICAgICAgKiAgICAgdmFyIGtleSA9IENyeXB0b0pTLlBCS0RGMihwYXNzd29yZCwgc2FsdCwgeyBrZXlTaXplOiA4LCBpdGVyYXRpb25zOiAxMDAwIH0pOwogICAgICAgICAgICovCiAgICAgICAgICBDLlBCS0RGMiA9IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCwgY2ZnKSB7CiAgICAgICAgICAgIHJldHVybiBQQktERjIuY3JlYXRlKGNmZykuY29tcHV0ZShwYXNzd29yZCwgc2FsdCk7CiAgICAgICAgICB9OwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlBCS0RGMjsKICAgICAgfSk7CiAgICB9KShwYmtkZjIkMSk7CiAgICByZXR1cm4gcGJrZGYyJDEuZXhwb3J0czsKICB9CgogIHZhciBldnBrZGYkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBldnBrZGYgPSBldnBrZGYkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZEV2cGtkZjsKICBmdW5jdGlvbiByZXF1aXJlRXZwa2RmKCkgewogICAgaWYgKGhhc1JlcXVpcmVkRXZwa2RmKSByZXR1cm4gZXZwa2RmJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkRXZwa2RmID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZVNoYTEoKSwgcmVxdWlyZUhtYWMoKSk7CiAgICAgICAgfQogICAgICB9KShldnBrZGYsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBCYXNlID0gQ19saWIuQmFzZTsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgQ19hbGdvID0gQy5hbGdvOwogICAgICAgICAgdmFyIE1ENSA9IENfYWxnby5NRDU7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBUaGlzIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uIGlzIG1lYW50IHRvIGNvbmZvcm0gd2l0aCBFVlBfQnl0ZXNUb0tleS4KICAgICAgICAgICAqIHd3dy5vcGVuc3NsLm9yZy9kb2NzL2NyeXB0by9FVlBfQnl0ZXNUb0tleS5odG1sCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBFdnBLREYgPSBDX2FsZ28uRXZwS0RGID0gQmFzZS5leHRlbmQoewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0ga2V5U2l6ZSBUaGUga2V5IHNpemUgaW4gd29yZHMgdG8gZ2VuZXJhdGUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKQogICAgICAgICAgICAgKiBAcHJvcGVydHkge0hhc2hlcn0gaGFzaGVyIFRoZSBoYXNoIGFsZ29yaXRobSB0byB1c2UuIERlZmF1bHQ6IE1ENQogICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gaXRlcmF0aW9ucyBUaGUgbnVtYmVyIG9mIGl0ZXJhdGlvbnMgdG8gcGVyZm9ybS4gRGVmYXVsdDogMQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCh7CiAgICAgICAgICAgICAga2V5U2l6ZTogMTI4IC8gMzIsCiAgICAgICAgICAgICAgaGFzaGVyOiBNRDUsCiAgICAgICAgICAgICAgaXRlcmF0aW9uczogMQogICAgICAgICAgICB9KSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEluaXRpYWxpemVzIGEgbmV3bHkgY3JlYXRlZCBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGUgZGVyaXZhdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoKTsKICAgICAgICAgICAgICogICAgIHZhciBrZGYgPSBDcnlwdG9KUy5hbGdvLkV2cEtERi5jcmVhdGUoeyBrZXlTaXplOiA4IH0pOwogICAgICAgICAgICAgKiAgICAgdmFyIGtkZiA9IENyeXB0b0pTLmFsZ28uRXZwS0RGLmNyZWF0ZSh7IGtleVNpemU6IDgsIGl0ZXJhdGlvbnM6IDEwMDAgfSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2ZnKSB7CiAgICAgICAgICAgICAgdGhpcy5jZmcgPSB0aGlzLmNmZy5leHRlbmQoY2ZnKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIERlcml2ZXMgYSBrZXkgZnJvbSBhIHBhc3N3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHBhc3N3b3JkIFRoZSBwYXNzd29yZC4KICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBzYWx0IEEgc2FsdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgZGVyaXZlZCBrZXkuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIga2V5ID0ga2RmLmNvbXB1dGUocGFzc3dvcmQsIHNhbHQpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY29tcHV0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBzYWx0KSB7CiAgICAgICAgICAgICAgdmFyIGJsb2NrOwoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBjZmcgPSB0aGlzLmNmZzsKCiAgICAgICAgICAgICAgLy8gSW5pdCBoYXNoZXIKICAgICAgICAgICAgICB2YXIgaGFzaGVyID0gY2ZnLmhhc2hlci5jcmVhdGUoKTsKCiAgICAgICAgICAgICAgLy8gSW5pdGlhbCB2YWx1ZXMKICAgICAgICAgICAgICB2YXIgZGVyaXZlZEtleSA9IFdvcmRBcnJheS5jcmVhdGUoKTsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGRlcml2ZWRLZXlXb3JkcyA9IGRlcml2ZWRLZXkud29yZHM7CiAgICAgICAgICAgICAgdmFyIGtleVNpemUgPSBjZmcua2V5U2l6ZTsKICAgICAgICAgICAgICB2YXIgaXRlcmF0aW9ucyA9IGNmZy5pdGVyYXRpb25zOwoKICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBrZXkKICAgICAgICAgICAgICB3aGlsZSAoZGVyaXZlZEtleVdvcmRzLmxlbmd0aCA8IGtleVNpemUpIHsKICAgICAgICAgICAgICAgIGlmIChibG9jaykgewogICAgICAgICAgICAgICAgICBoYXNoZXIudXBkYXRlKGJsb2NrKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJsb2NrID0gaGFzaGVyLnVwZGF0ZShwYXNzd29yZCkuZmluYWxpemUoc2FsdCk7CiAgICAgICAgICAgICAgICBoYXNoZXIucmVzZXQoKTsKCiAgICAgICAgICAgICAgICAvLyBJdGVyYXRpb25zCiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGl0ZXJhdGlvbnM7IGkrKykgewogICAgICAgICAgICAgICAgICBibG9jayA9IGhhc2hlci5maW5hbGl6ZShibG9jayk7CiAgICAgICAgICAgICAgICAgIGhhc2hlci5yZXNldCgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZGVyaXZlZEtleS5jb25jYXQoYmxvY2spOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBkZXJpdmVkS2V5LnNpZ0J5dGVzID0ga2V5U2l6ZSAqIDQ7CiAgICAgICAgICAgICAgcmV0dXJuIGRlcml2ZWRLZXk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogRGVyaXZlcyBhIGtleSBmcm9tIGEgcGFzc3dvcmQuCiAgICAgICAgICAgKgogICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuCiAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgQSBzYWx0LgogICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIGNvbXB1dGF0aW9uLgogICAgICAgICAgICoKICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRlcml2ZWQga2V5LgogICAgICAgICAgICoKICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0KTsKICAgICAgICAgICAqICAgICB2YXIga2V5ID0gQ3J5cHRvSlMuRXZwS0RGKHBhc3N3b3JkLCBzYWx0LCB7IGtleVNpemU6IDggfSk7CiAgICAgICAgICAgKiAgICAgdmFyIGtleSA9IENyeXB0b0pTLkV2cEtERihwYXNzd29yZCwgc2FsdCwgeyBrZXlTaXplOiA4LCBpdGVyYXRpb25zOiAxMDAwIH0pOwogICAgICAgICAgICovCiAgICAgICAgICBDLkV2cEtERiA9IGZ1bmN0aW9uIChwYXNzd29yZCwgc2FsdCwgY2ZnKSB7CiAgICAgICAgICAgIHJldHVybiBFdnBLREYuY3JlYXRlKGNmZykuY29tcHV0ZShwYXNzd29yZCwgc2FsdCk7CiAgICAgICAgICB9OwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLkV2cEtERjsKICAgICAgfSk7CiAgICB9KShldnBrZGYkMSk7CiAgICByZXR1cm4gZXZwa2RmJDEuZXhwb3J0czsKICB9CgogIHZhciBjaXBoZXJDb3JlJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgY2lwaGVyQ29yZSA9IGNpcGhlckNvcmUkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZENpcGhlckNvcmU7CiAgZnVuY3Rpb24gcmVxdWlyZUNpcGhlckNvcmUoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRDaXBoZXJDb3JlKSByZXR1cm4gY2lwaGVyQ29yZSQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZENpcGhlckNvcmUgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlRXZwa2RmKCkpOwogICAgICAgIH0KICAgICAgfSkoY2lwaGVyQ29yZSwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgLyoqCiAgICAgICAgICogQ2lwaGVyIGNvcmUgY29tcG9uZW50cy4KICAgICAgICAgKi8KICAgICAgICBDcnlwdG9KUy5saWIuQ2lwaGVyIHx8IGZ1bmN0aW9uICh1bmRlZmluZWQkMSkgewogICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICB2YXIgQyA9IENyeXB0b0pTOwogICAgICAgICAgdmFyIENfbGliID0gQy5saWI7CiAgICAgICAgICB2YXIgQmFzZSA9IENfbGliLkJhc2U7CiAgICAgICAgICB2YXIgV29yZEFycmF5ID0gQ19saWIuV29yZEFycmF5OwogICAgICAgICAgdmFyIEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0gPSBDX2xpYi5CdWZmZXJlZEJsb2NrQWxnb3JpdGhtOwogICAgICAgICAgdmFyIENfZW5jID0gQy5lbmM7CiAgICAgICAgICBDX2VuYy5VdGY4OwogICAgICAgICAgdmFyIEJhc2U2NCA9IENfZW5jLkJhc2U2NDsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CiAgICAgICAgICB2YXIgRXZwS0RGID0gQ19hbGdvLkV2cEtERjsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFic3RyYWN0IGJhc2UgY2lwaGVyIHRlbXBsYXRlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBrZXlTaXplIFRoaXMgY2lwaGVyJ3Mga2V5IHNpemUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKQogICAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IGl2U2l6ZSBUaGlzIGNpcGhlcidzIElWIHNpemUuIERlZmF1bHQ6IDQgKDEyOCBiaXRzKQogICAgICAgICAgICogQHByb3BlcnR5IHtudW1iZXJ9IF9FTkNfWEZPUk1fTU9ERSBBIGNvbnN0YW50IHJlcHJlc2VudGluZyBlbmNyeXB0aW9uIG1vZGUuCiAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gX0RFQ19YRk9STV9NT0RFIEEgY29uc3RhbnQgcmVwcmVzZW50aW5nIGRlY3J5cHRpb24gbW9kZS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIENpcGhlciA9IENfbGliLkNpcGhlciA9IEJ1ZmZlcmVkQmxvY2tBbGdvcml0aG0uZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHByb3BlcnR5IHtXb3JkQXJyYXl9IGl2IFRoZSBJViB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2ZnOiBCYXNlLmV4dGVuZCgpLAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ3JlYXRlcyB0aGlzIGNpcGhlciBpbiBlbmNyeXB0aW9uIG1vZGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS4KICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7Q2lwaGVyfSBBIGNpcGhlciBpbnN0YW5jZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlciA9IENyeXB0b0pTLmFsZ28uQUVTLmNyZWF0ZUVuY3J5cHRvcihrZXlXb3JkQXJyYXksIHsgaXY6IGl2V29yZEFycmF5IH0pOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY3JlYXRlRW5jcnlwdG9yOiBmdW5jdGlvbiAoa2V5LCBjZmcpIHsKICAgICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGUodGhpcy5fRU5DX1hGT1JNX01PREUsIGtleSwgY2ZnKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENyZWF0ZXMgdGhpcyBjaXBoZXIgaW4gZGVjcnlwdGlvbiBtb2RlLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheX0ga2V5IFRoZSBrZXkuCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge0NpcGhlcn0gQSBjaXBoZXIgaW5zdGFuY2UuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBjaXBoZXIgPSBDcnlwdG9KUy5hbGdvLkFFUy5jcmVhdGVEZWNyeXB0b3Ioa2V5V29yZEFycmF5LCB7IGl2OiBpdldvcmRBcnJheSB9KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNyZWF0ZURlY3J5cHRvcjogZnVuY3Rpb24gKGtleSwgY2ZnKSB7CiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlKHRoaXMuX0RFQ19YRk9STV9NT0RFLCBrZXksIGNmZyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgY2lwaGVyLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0geGZvcm1Nb2RlIEVpdGhlciB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uIHRyYW5zb3JtYXRpb24gbW9kZSBjb25zdGFudC4KICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGtleSBUaGUga2V5LgogICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlciA9IENyeXB0b0pTLmFsZ28uQUVTLmNyZWF0ZShDcnlwdG9KUy5hbGdvLkFFUy5fRU5DX1hGT1JNX01PREUsIGtleVdvcmRBcnJheSwgeyBpdjogaXZXb3JkQXJyYXkgfSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbml0OiBmdW5jdGlvbiAoeGZvcm1Nb2RlLCBrZXksIGNmZykgewogICAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0cwogICAgICAgICAgICAgIHRoaXMuY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7CgogICAgICAgICAgICAgIC8vIFN0b3JlIHRyYW5zZm9ybSBtb2RlIGFuZCBrZXkKICAgICAgICAgICAgICB0aGlzLl94Zm9ybU1vZGUgPSB4Zm9ybU1vZGU7CiAgICAgICAgICAgICAgdGhpcy5fa2V5ID0ga2V5OwoKICAgICAgICAgICAgICAvLyBTZXQgaW5pdGlhbCB2YWx1ZXMKICAgICAgICAgICAgICB0aGlzLnJlc2V0KCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBSZXNldHMgdGhpcyBjaXBoZXIgdG8gaXRzIGluaXRpYWwgc3RhdGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICBjaXBoZXIucmVzZXQoKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgLy8gUmVzZXQgZGF0YSBidWZmZXIKICAgICAgICAgICAgICBCdWZmZXJlZEJsb2NrQWxnb3JpdGhtLnJlc2V0LmNhbGwodGhpcyk7CgogICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtY2lwaGVyIGxvZ2ljCiAgICAgICAgICAgICAgdGhpcy5fZG9SZXNldCgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQWRkcyBkYXRhIHRvIGJlIGVuY3J5cHRlZCBvciBkZWNyeXB0ZWQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gZGF0YVVwZGF0ZSBUaGUgZGF0YSB0byBlbmNyeXB0IG9yIGRlY3J5cHQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRhdGEgYWZ0ZXIgcHJvY2Vzc2luZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIucHJvY2VzcygnZGF0YScpOwogICAgICAgICAgICAgKiAgICAgdmFyIGVuY3J5cHRlZCA9IGNpcGhlci5wcm9jZXNzKHdvcmRBcnJheSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwcm9jZXNzOiBmdW5jdGlvbiAoZGF0YVVwZGF0ZSkgewogICAgICAgICAgICAgIC8vIEFwcGVuZAogICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChkYXRhVXBkYXRlKTsKCiAgICAgICAgICAgICAgLy8gUHJvY2VzcyBhdmFpbGFibGUgYmxvY2tzCiAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3Byb2Nlc3MoKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEZpbmFsaXplcyB0aGUgZW5jcnlwdGlvbiBvciBkZWNyeXB0aW9uIHByb2Nlc3MuCiAgICAgICAgICAgICAqIE5vdGUgdGhhdCB0aGUgZmluYWxpemUgb3BlcmF0aW9uIGlzIGVmZmVjdGl2ZWx5IGEgZGVzdHJ1Y3RpdmUsIHJlYWQtb25jZSBvcGVyYXRpb24uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fHN0cmluZ30gZGF0YVVwZGF0ZSBUaGUgZmluYWwgZGF0YSB0byBlbmNyeXB0IG9yIGRlY3J5cHQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIGRhdGEgYWZ0ZXIgZmluYWwgcHJvY2Vzc2luZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUoKTsKICAgICAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUoJ2RhdGEnKTsKICAgICAgICAgICAgICogICAgIHZhciBlbmNyeXB0ZWQgPSBjaXBoZXIuZmluYWxpemUod29yZEFycmF5KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZpbmFsaXplOiBmdW5jdGlvbiAoZGF0YVVwZGF0ZSkgewogICAgICAgICAgICAgIC8vIEZpbmFsIGRhdGEgdXBkYXRlCiAgICAgICAgICAgICAgaWYgKGRhdGFVcGRhdGUpIHsKICAgICAgICAgICAgICAgIHRoaXMuX2FwcGVuZChkYXRhVXBkYXRlKTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFBlcmZvcm0gY29uY3JldGUtY2lwaGVyIGxvZ2ljCiAgICAgICAgICAgICAgdmFyIGZpbmFsUHJvY2Vzc2VkRGF0YSA9IHRoaXMuX2RvRmluYWxpemUoKTsKICAgICAgICAgICAgICByZXR1cm4gZmluYWxQcm9jZXNzZWREYXRhOwogICAgICAgICAgICB9LAogICAgICAgICAgICBrZXlTaXplOiAxMjggLyAzMiwKICAgICAgICAgICAgaXZTaXplOiAxMjggLyAzMiwKICAgICAgICAgICAgX0VOQ19YRk9STV9NT0RFOiAxLAogICAgICAgICAgICBfREVDX1hGT1JNX01PREU6IDIsCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDcmVhdGVzIHNob3J0Y3V0IGZ1bmN0aW9ucyB0byBhIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgVGhlIGNpcGhlciB0byBjcmVhdGUgYSBoZWxwZXIgZm9yLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IEFuIG9iamVjdCB3aXRoIGVuY3J5cHQgYW5kIGRlY3J5cHQgc2hvcnRjdXQgZnVuY3Rpb25zLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgQUVTID0gQ3J5cHRvSlMubGliLkNpcGhlci5fY3JlYXRlSGVscGVyKENyeXB0b0pTLmFsZ28uQUVTKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIF9jcmVhdGVIZWxwZXI6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICBmdW5jdGlvbiBzZWxlY3RDaXBoZXJTdHJhdGVneShrZXkpIHsKICAgICAgICAgICAgICAgIGlmICh0eXBlb2Yga2V5ID09ICdzdHJpbmcnKSB7CiAgICAgICAgICAgICAgICAgIHJldHVybiBQYXNzd29yZEJhc2VkQ2lwaGVyOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgcmV0dXJuIFNlcmlhbGl6YWJsZUNpcGhlcjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChjaXBoZXIpIHsKICAgICAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgICAgIGVuY3J5cHQ6IGZ1bmN0aW9uIChtZXNzYWdlLCBrZXksIGNmZykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RDaXBoZXJTdHJhdGVneShrZXkpLmVuY3J5cHQoY2lwaGVyLCBtZXNzYWdlLCBrZXksIGNmZyk7CiAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXJ0ZXh0LCBrZXksIGNmZykgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBzZWxlY3RDaXBoZXJTdHJhdGVneShrZXkpLmRlY3J5cHQoY2lwaGVyLCBjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgfSgpCiAgICAgICAgICB9KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFic3RyYWN0IGJhc2Ugc3RyZWFtIGNpcGhlciB0ZW1wbGF0ZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gYmxvY2tTaXplIFRoZSBudW1iZXIgb2YgMzItYml0IHdvcmRzIHRoaXMgY2lwaGVyIG9wZXJhdGVzIG9uLiBEZWZhdWx0OiAxICgzMiBiaXRzKQogICAgICAgICAgICovCiAgICAgICAgICBDX2xpYi5TdHJlYW1DaXBoZXIgPSBDaXBoZXIuZXh0ZW5kKHsKICAgICAgICAgICAgX2RvRmluYWxpemU6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBQcm9jZXNzIHBhcnRpYWwgYmxvY2tzCiAgICAgICAgICAgICAgdmFyIGZpbmFsUHJvY2Vzc2VkQmxvY2tzID0gdGhpcy5fcHJvY2Vzcyh0cnVlKTsKICAgICAgICAgICAgICByZXR1cm4gZmluYWxQcm9jZXNzZWRCbG9ja3M7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGJsb2NrU2l6ZTogMQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBNb2RlIG5hbWVzcGFjZS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIENfbW9kZSA9IEMubW9kZSA9IHt9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQWJzdHJhY3QgYmFzZSBibG9jayBjaXBoZXIgbW9kZSB0ZW1wbGF0ZS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIEJsb2NrQ2lwaGVyTW9kZSA9IENfbGliLkJsb2NrQ2lwaGVyTW9kZSA9IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENyZWF0ZXMgdGhpcyBtb2RlIGZvciBlbmNyeXB0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIEEgYmxvY2sgY2lwaGVyIGluc3RhbmNlLgogICAgICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBpdiBUaGUgSVYgd29yZHMuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBtb2RlID0gQ3J5cHRvSlMubW9kZS5DQkMuY3JlYXRlRW5jcnlwdG9yKGNpcGhlciwgaXYud29yZHMpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY3JlYXRlRW5jcnlwdG9yOiBmdW5jdGlvbiAoY2lwaGVyLCBpdikgewogICAgICAgICAgICAgIHJldHVybiB0aGlzLkVuY3J5cHRvci5jcmVhdGUoY2lwaGVyLCBpdik7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDcmVhdGVzIHRoaXMgbW9kZSBmb3IgZGVjcnlwdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtDaXBoZXJ9IGNpcGhlciBBIGJsb2NrIGNpcGhlciBpbnN0YW5jZS4KICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gaXYgVGhlIElWIHdvcmRzLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgbW9kZSA9IENyeXB0b0pTLm1vZGUuQ0JDLmNyZWF0ZURlY3J5cHRvcihjaXBoZXIsIGl2LndvcmRzKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNyZWF0ZURlY3J5cHRvcjogZnVuY3Rpb24gKGNpcGhlciwgaXYpIHsKICAgICAgICAgICAgICByZXR1cm4gdGhpcy5EZWNyeXB0b3IuY3JlYXRlKGNpcGhlciwgaXYpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogSW5pdGlhbGl6ZXMgYSBuZXdseSBjcmVhdGVkIG1vZGUuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgQSBibG9jayBjaXBoZXIgaW5zdGFuY2UuCiAgICAgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGl2IFRoZSBJViB3b3Jkcy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBtb2RlID0gQ3J5cHRvSlMubW9kZS5DQkMuRW5jcnlwdG9yLmNyZWF0ZShjaXBoZXIsIGl2LndvcmRzKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGluaXQ6IGZ1bmN0aW9uIChjaXBoZXIsIGl2KSB7CiAgICAgICAgICAgICAgdGhpcy5fY2lwaGVyID0gY2lwaGVyOwogICAgICAgICAgICAgIHRoaXMuX2l2ID0gaXY7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQ2lwaGVyIEJsb2NrIENoYWluaW5nIG1vZGUuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDQkMgPSBDX21vZGUuQ0JDID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQWJzdHJhY3QgYmFzZSBDQkMgbW9kZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHZhciBDQkMgPSBCbG9ja0NpcGhlck1vZGUuZXh0ZW5kKCk7CgogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ0JDIGVuY3J5cHRvci4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIENCQy5FbmNyeXB0b3IgPSBDQkMuZXh0ZW5kKHsKICAgICAgICAgICAgICAvKioKICAgICAgICAgICAgICAgKiBQcm9jZXNzZXMgdGhlIGRhdGEgYmxvY2sgYXQgb2Zmc2V0LgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gd29yZHMgVGhlIGRhdGEgd29yZHMgdG8gb3BlcmF0ZSBvbi4KICAgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gb2Zmc2V0IFRoZSBvZmZzZXQgd2hlcmUgdGhlIGJsb2NrIHN0YXJ0cy4KICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgKiAgICAgbW9kZS5wcm9jZXNzQmxvY2soZGF0YS53b3Jkcywgb2Zmc2V0KTsKICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICAgIHZhciBjaXBoZXIgPSB0aGlzLl9jaXBoZXI7CiAgICAgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTsKCiAgICAgICAgICAgICAgICAvLyBYT1IgYW5kIGVuY3J5cHQKICAgICAgICAgICAgICAgIHhvckJsb2NrLmNhbGwodGhpcywgd29yZHMsIG9mZnNldCwgYmxvY2tTaXplKTsKICAgICAgICAgICAgICAgIGNpcGhlci5lbmNyeXB0QmxvY2sod29yZHMsIG9mZnNldCk7CgogICAgICAgICAgICAgICAgLy8gUmVtZW1iZXIgdGhpcyBibG9jayB0byB1c2Ugd2l0aCBuZXh0IGJsb2NrCiAgICAgICAgICAgICAgICB0aGlzLl9wcmV2QmxvY2sgPSB3b3Jkcy5zbGljZShvZmZzZXQsIG9mZnNldCArIGJsb2NrU2l6ZSk7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9KTsKCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDQkMgZGVjcnlwdG9yLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgQ0JDLkRlY3J5cHRvciA9IENCQy5leHRlbmQoewogICAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgICAqIFByb2Nlc3NlcyB0aGUgZGF0YSBibG9jayBhdCBvZmZzZXQuCiAgICAgICAgICAgICAgICoKICAgICAgICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSB3b3JkcyBUaGUgZGF0YSB3b3JkcyB0byBvcGVyYXRlIG9uLgogICAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBvZmZzZXQgVGhlIG9mZnNldCB3aGVyZSB0aGUgYmxvY2sgc3RhcnRzLgogICAgICAgICAgICAgICAqCiAgICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAqICAgICBtb2RlLnByb2Nlc3NCbG9jayhkYXRhLndvcmRzLCBvZmZzZXQpOwogICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgdmFyIGNpcGhlciA9IHRoaXMuX2NpcGhlcjsKICAgICAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSBjaXBoZXIuYmxvY2tTaXplOwoKICAgICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoaXMgYmxvY2sgdG8gdXNlIHdpdGggbmV4dCBibG9jawogICAgICAgICAgICAgICAgdmFyIHRoaXNCbG9jayA9IHdvcmRzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgYmxvY2tTaXplKTsKCiAgICAgICAgICAgICAgICAvLyBEZWNyeXB0IGFuZCBYT1IKICAgICAgICAgICAgICAgIGNpcGhlci5kZWNyeXB0QmxvY2sod29yZHMsIG9mZnNldCk7CiAgICAgICAgICAgICAgICB4b3JCbG9jay5jYWxsKHRoaXMsIHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSk7CgogICAgICAgICAgICAgICAgLy8gVGhpcyBibG9jayBiZWNvbWVzIHRoZSBwcmV2aW91cyBibG9jawogICAgICAgICAgICAgICAgdGhpcy5fcHJldkJsb2NrID0gdGhpc0Jsb2NrOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIGZ1bmN0aW9uIHhvckJsb2NrKHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSkgewogICAgICAgICAgICAgIHZhciBibG9jazsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLl9pdjsKCiAgICAgICAgICAgICAgLy8gQ2hvb3NlIG1peGluZyBibG9jawogICAgICAgICAgICAgIGlmIChpdikgewogICAgICAgICAgICAgICAgYmxvY2sgPSBpdjsKCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgSVYgZm9yIHN1YnNlcXVlbnQgYmxvY2tzCiAgICAgICAgICAgICAgICB0aGlzLl9pdiA9IHVuZGVmaW5lZCQxOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBibG9jayA9IHRoaXMuX3ByZXZCbG9jazsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFhPUiBibG9ja3MKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrU2l6ZTsgaSsrKSB7CiAgICAgICAgICAgICAgICB3b3Jkc1tvZmZzZXQgKyBpXSBePSBibG9ja1tpXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIENCQzsKICAgICAgICAgIH0oKTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFBhZGRpbmcgbmFtZXNwYWNlLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgQ19wYWQgPSBDLnBhZCA9IHt9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogUEtDUyAjNS83IHBhZGRpbmcgc3RyYXRlZ3kuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBQa2NzNyA9IENfcGFkLlBrY3M3ID0gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogUGFkcyBkYXRhIHVzaW5nIHRoZSBhbGdvcml0aG0gZGVmaW5lZCBpbiBQS0NTICM1LzcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBkYXRhIFRoZSBkYXRhIHRvIHBhZC4KICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IGJsb2NrU2l6ZSBUaGUgbXVsdGlwbGUgdGhhdCB0aGUgZGF0YSBzaG91bGQgYmUgcGFkZGVkIHRvLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICBDcnlwdG9KUy5wYWQuUGtjczcucGFkKHdvcmRBcnJheSwgNCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwYWQ6IGZ1bmN0aW9uIChkYXRhLCBibG9ja1NpemUpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBibG9ja1NpemVCeXRlcyA9IGJsb2NrU2l6ZSAqIDQ7CgogICAgICAgICAgICAgIC8vIENvdW50IHBhZGRpbmcgYnl0ZXMKICAgICAgICAgICAgICB2YXIgblBhZGRpbmdCeXRlcyA9IGJsb2NrU2l6ZUJ5dGVzIC0gZGF0YS5zaWdCeXRlcyAlIGJsb2NrU2l6ZUJ5dGVzOwoKICAgICAgICAgICAgICAvLyBDcmVhdGUgcGFkZGluZyB3b3JkCiAgICAgICAgICAgICAgdmFyIHBhZGRpbmdXb3JkID0gblBhZGRpbmdCeXRlcyA8PCAyNCB8IG5QYWRkaW5nQnl0ZXMgPDwgMTYgfCBuUGFkZGluZ0J5dGVzIDw8IDggfCBuUGFkZGluZ0J5dGVzOwoKICAgICAgICAgICAgICAvLyBDcmVhdGUgcGFkZGluZwogICAgICAgICAgICAgIHZhciBwYWRkaW5nV29yZHMgPSBbXTsKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5QYWRkaW5nQnl0ZXM7IGkgKz0gNCkgewogICAgICAgICAgICAgICAgcGFkZGluZ1dvcmRzLnB1c2gocGFkZGluZ1dvcmQpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB2YXIgcGFkZGluZyA9IFdvcmRBcnJheS5jcmVhdGUocGFkZGluZ1dvcmRzLCBuUGFkZGluZ0J5dGVzKTsKCiAgICAgICAgICAgICAgLy8gQWRkIHBhZGRpbmcKICAgICAgICAgICAgICBkYXRhLmNvbmNhdChwYWRkaW5nKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIFVucGFkcyBkYXRhIHRoYXQgaGFkIGJlZW4gcGFkZGVkIHVzaW5nIHRoZSBhbGdvcml0aG0gZGVmaW5lZCBpbiBQS0NTICM1LzcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBkYXRhIFRoZSBkYXRhIHRvIHVucGFkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICBDcnlwdG9KUy5wYWQuUGtjczcudW5wYWQod29yZEFycmF5KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHVucGFkOiBmdW5jdGlvbiAoZGF0YSkgewogICAgICAgICAgICAgIC8vIEdldCBudW1iZXIgb2YgcGFkZGluZyBieXRlcyBmcm9tIGxhc3QgYnl0ZQogICAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gZGF0YS53b3Jkc1tkYXRhLnNpZ0J5dGVzIC0gMSA+Pj4gMl0gJiAweGZmOwoKICAgICAgICAgICAgICAvLyBSZW1vdmUgcGFkZGluZwogICAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgLT0gblBhZGRpbmdCeXRlczsKICAgICAgICAgICAgfQogICAgICAgICAgfTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFic3RyYWN0IGJhc2UgYmxvY2sgY2lwaGVyIHRlbXBsYXRlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIG51bWJlciBvZiAzMi1iaXQgd29yZHMgdGhpcyBjaXBoZXIgb3BlcmF0ZXMgb24uIERlZmF1bHQ6IDQgKDEyOCBiaXRzKQogICAgICAgICAgICovCiAgICAgICAgICBDX2xpYi5CbG9ja0NpcGhlciA9IENpcGhlci5leHRlbmQoewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcHJvcGVydHkge01vZGV9IG1vZGUgVGhlIGJsb2NrIG1vZGUgdG8gdXNlLiBEZWZhdWx0OiBDQkMKICAgICAgICAgICAgICogQHByb3BlcnR5IHtQYWRkaW5nfSBwYWRkaW5nIFRoZSBwYWRkaW5nIHN0cmF0ZWd5IHRvIHVzZS4gRGVmYXVsdDogUGtjczcKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNmZzogQ2lwaGVyLmNmZy5leHRlbmQoewogICAgICAgICAgICAgIG1vZGU6IENCQywKICAgICAgICAgICAgICBwYWRkaW5nOiBQa2NzNwogICAgICAgICAgICB9KSwKICAgICAgICAgICAgcmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICB2YXIgbW9kZUNyZWF0b3I7CgogICAgICAgICAgICAgIC8vIFJlc2V0IGNpcGhlcgogICAgICAgICAgICAgIENpcGhlci5yZXNldC5jYWxsKHRoaXMpOwoKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgY2ZnID0gdGhpcy5jZmc7CiAgICAgICAgICAgICAgdmFyIGl2ID0gY2ZnLml2OwogICAgICAgICAgICAgIHZhciBtb2RlID0gY2ZnLm1vZGU7CgogICAgICAgICAgICAgIC8vIFJlc2V0IGJsb2NrIG1vZGUKICAgICAgICAgICAgICBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0VOQ19YRk9STV9NT0RFKSB7CiAgICAgICAgICAgICAgICBtb2RlQ3JlYXRvciA9IG1vZGUuY3JlYXRlRW5jcnlwdG9yOwogICAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqL3sKICAgICAgICAgICAgICAgICAgbW9kZUNyZWF0b3IgPSBtb2RlLmNyZWF0ZURlY3J5cHRvcjsKICAgICAgICAgICAgICAgICAgLy8gS2VlcCBhdCBsZWFzdCBvbmUgYmxvY2sgaW4gdGhlIGJ1ZmZlciBmb3IgdW5wYWRkaW5nCiAgICAgICAgICAgICAgICAgIHRoaXMuX21pbkJ1ZmZlclNpemUgPSAxOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmICh0aGlzLl9tb2RlICYmIHRoaXMuX21vZGUuX19jcmVhdG9yID09IG1vZGVDcmVhdG9yKSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlLmluaXQodGhpcywgaXYgJiYgaXYud29yZHMpOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlID0gbW9kZUNyZWF0b3IuY2FsbChtb2RlLCB0aGlzLCBpdiAmJiBpdi53b3Jkcyk7CiAgICAgICAgICAgICAgICB0aGlzLl9tb2RlLl9fY3JlYXRvciA9IG1vZGVDcmVhdG9yOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkgewogICAgICAgICAgICAgIHRoaXMuX21vZGUucHJvY2Vzc0Jsb2NrKHdvcmRzLCBvZmZzZXQpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9GaW5hbGl6ZTogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIHZhciBmaW5hbFByb2Nlc3NlZEJsb2NrczsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgcGFkZGluZyA9IHRoaXMuY2ZnLnBhZGRpbmc7CgogICAgICAgICAgICAgIC8vIEZpbmFsaXplCiAgICAgICAgICAgICAgaWYgKHRoaXMuX3hmb3JtTW9kZSA9PSB0aGlzLl9FTkNfWEZPUk1fTU9ERSkgewogICAgICAgICAgICAgICAgLy8gUGFkIGRhdGEKICAgICAgICAgICAgICAgIHBhZGRpbmcucGFkKHRoaXMuX2RhdGEsIHRoaXMuYmxvY2tTaXplKTsKCiAgICAgICAgICAgICAgICAvLyBQcm9jZXNzIGZpbmFsIGJsb2NrcwogICAgICAgICAgICAgICAgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKHRydWUpOwogICAgICAgICAgICAgIH0gZWxzZSAvKiBpZiAodGhpcy5feGZvcm1Nb2RlID09IHRoaXMuX0RFQ19YRk9STV9NT0RFKSAqL3sKICAgICAgICAgICAgICAgICAgLy8gUHJvY2VzcyBmaW5hbCBibG9ja3MKICAgICAgICAgICAgICAgICAgZmluYWxQcm9jZXNzZWRCbG9ja3MgPSB0aGlzLl9wcm9jZXNzKHRydWUpOwoKICAgICAgICAgICAgICAgICAgLy8gVW5wYWQgZGF0YQogICAgICAgICAgICAgICAgICBwYWRkaW5nLnVucGFkKGZpbmFsUHJvY2Vzc2VkQmxvY2tzKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gZmluYWxQcm9jZXNzZWRCbG9ja3M7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGJsb2NrU2l6ZTogMTI4IC8gMzIKICAgICAgICAgIH0pOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQSBjb2xsZWN0aW9uIG9mIGNpcGhlciBwYXJhbWV0ZXJzLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwcm9wZXJ0eSB7V29yZEFycmF5fSBjaXBoZXJ0ZXh0IFRoZSByYXcgY2lwaGVydGV4dC4KICAgICAgICAgICAqIEBwcm9wZXJ0eSB7V29yZEFycmF5fSBrZXkgVGhlIGtleSB0byB0aGlzIGNpcGhlcnRleHQuCiAgICAgICAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gaXYgVGhlIElWIHVzZWQgaW4gdGhlIGNpcGhlcmluZyBvcGVyYXRpb24uCiAgICAgICAgICAgKiBAcHJvcGVydHkge1dvcmRBcnJheX0gc2FsdCBUaGUgc2FsdCB1c2VkIHdpdGggYSBrZXkgZGVyaXZhdGlvbiBmdW5jdGlvbi4KICAgICAgICAgICAqIEBwcm9wZXJ0eSB7Q2lwaGVyfSBhbGdvcml0aG0gVGhlIGNpcGhlciBhbGdvcml0aG0uCiAgICAgICAgICAgKiBAcHJvcGVydHkge01vZGV9IG1vZGUgVGhlIGJsb2NrIG1vZGUgdXNlZCBpbiB0aGUgY2lwaGVyaW5nIG9wZXJhdGlvbi4KICAgICAgICAgICAqIEBwcm9wZXJ0eSB7UGFkZGluZ30gcGFkZGluZyBUaGUgcGFkZGluZyBzY2hlbWUgdXNlZCBpbiB0aGUgY2lwaGVyaW5nIG9wZXJhdGlvbi4KICAgICAgICAgICAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBibG9ja1NpemUgVGhlIGJsb2NrIHNpemUgb2YgdGhlIGNpcGhlci4KICAgICAgICAgICAqIEBwcm9wZXJ0eSB7Rm9ybWF0fSBmb3JtYXR0ZXIgVGhlIGRlZmF1bHQgZm9ybWF0dGluZyBzdHJhdGVneSB0byBjb252ZXJ0IHRoaXMgY2lwaGVyIHBhcmFtcyBvYmplY3QgdG8gYSBzdHJpbmcuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDaXBoZXJQYXJhbXMgPSBDX2xpYi5DaXBoZXJQYXJhbXMgPSBCYXNlLmV4dGVuZCh7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ld2x5IGNyZWF0ZWQgY2lwaGVyIHBhcmFtcyBvYmplY3QuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjaXBoZXJQYXJhbXMgQW4gb2JqZWN0IHdpdGggYW55IG9mIHRoZSBwb3NzaWJsZSBjaXBoZXIgcGFyYW1ldGVycy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBjaXBoZXJQYXJhbXMgPSBDcnlwdG9KUy5saWIuQ2lwaGVyUGFyYW1zLmNyZWF0ZSh7CiAgICAgICAgICAgICAqICAgICAgICAgY2lwaGVydGV4dDogY2lwaGVydGV4dFdvcmRBcnJheSwKICAgICAgICAgICAgICogICAgICAgICBrZXk6IGtleVdvcmRBcnJheSwKICAgICAgICAgICAgICogICAgICAgICBpdjogaXZXb3JkQXJyYXksCiAgICAgICAgICAgICAqICAgICAgICAgc2FsdDogc2FsdFdvcmRBcnJheSwKICAgICAgICAgICAgICogICAgICAgICBhbGdvcml0aG06IENyeXB0b0pTLmFsZ28uQUVTLAogICAgICAgICAgICAgKiAgICAgICAgIG1vZGU6IENyeXB0b0pTLm1vZGUuQ0JDLAogICAgICAgICAgICAgKiAgICAgICAgIHBhZGRpbmc6IENyeXB0b0pTLnBhZC5QS0NTNywKICAgICAgICAgICAgICogICAgICAgICBibG9ja1NpemU6IDQsCiAgICAgICAgICAgICAqICAgICAgICAgZm9ybWF0dGVyOiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTAogICAgICAgICAgICAgKiAgICAgfSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpbml0OiBmdW5jdGlvbiAoY2lwaGVyUGFyYW1zKSB7CiAgICAgICAgICAgICAgdGhpcy5taXhJbihjaXBoZXJQYXJhbXMpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgdGhpcyBjaXBoZXIgcGFyYW1zIG9iamVjdCB0byBhIHN0cmluZy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtGb3JtYXR9IGZvcm1hdHRlciAoT3B0aW9uYWwpIFRoZSBmb3JtYXR0aW5nIHN0cmF0ZWd5IHRvIHVzZS4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgc3RyaW5naWZpZWQgY2lwaGVyIHBhcmFtcy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHRocm93cyBFcnJvciBJZiBuZWl0aGVyIHRoZSBmb3JtYXR0ZXIgbm9yIHRoZSBkZWZhdWx0IGZvcm1hdHRlciBpcyBzZXQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zICsgJyc7CiAgICAgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zLnRvU3RyaW5nKCk7CiAgICAgICAgICAgICAqICAgICB2YXIgc3RyaW5nID0gY2lwaGVyUGFyYW1zLnRvU3RyaW5nKENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHRvU3RyaW5nOiBmdW5jdGlvbiAoZm9ybWF0dGVyKSB7CiAgICAgICAgICAgICAgcmV0dXJuIChmb3JtYXR0ZXIgfHwgdGhpcy5mb3JtYXR0ZXIpLnN0cmluZ2lmeSh0aGlzKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBGb3JtYXQgbmFtZXNwYWNlLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgQ19mb3JtYXQgPSBDLmZvcm1hdCA9IHt9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogT3BlblNTTCBmb3JtYXR0aW5nIHN0cmF0ZWd5LgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgT3BlblNTTEZvcm1hdHRlciA9IENfZm9ybWF0Lk9wZW5TU0wgPSB7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBhIGNpcGhlciBwYXJhbXMgb2JqZWN0IHRvIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfSBjaXBoZXJQYXJhbXMgVGhlIGNpcGhlciBwYXJhbXMgb2JqZWN0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBPcGVuU1NMLWNvbXBhdGlibGUgc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgb3BlblNTTFN0cmluZyA9IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMLnN0cmluZ2lmeShjaXBoZXJQYXJhbXMpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc3RyaW5naWZ5OiBmdW5jdGlvbiAoY2lwaGVyUGFyYW1zKSB7CiAgICAgICAgICAgICAgdmFyIHdvcmRBcnJheTsKCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGNpcGhlcnRleHQgPSBjaXBoZXJQYXJhbXMuY2lwaGVydGV4dDsKICAgICAgICAgICAgICB2YXIgc2FsdCA9IGNpcGhlclBhcmFtcy5zYWx0OwoKICAgICAgICAgICAgICAvLyBGb3JtYXQKICAgICAgICAgICAgICBpZiAoc2FsdCkgewogICAgICAgICAgICAgICAgd29yZEFycmF5ID0gV29yZEFycmF5LmNyZWF0ZShbMHg1MzYxNmM3NCwgMHg2NTY0NWY1Zl0pLmNvbmNhdChzYWx0KS5jb25jYXQoY2lwaGVydGV4dCk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHdvcmRBcnJheSA9IGNpcGhlcnRleHQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB3b3JkQXJyYXkudG9TdHJpbmcoQmFzZTY0KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbnZlcnRzIGFuIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcgdG8gYSBjaXBoZXIgcGFyYW1zIG9iamVjdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IG9wZW5TU0xTdHIgVGhlIE9wZW5TU0wtY29tcGF0aWJsZSBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge0NpcGhlclBhcmFtc30gVGhlIGNpcGhlciBwYXJhbXMgb2JqZWN0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgY2lwaGVyUGFyYW1zID0gQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wucGFyc2Uob3BlblNTTFN0cmluZyk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBwYXJzZTogZnVuY3Rpb24gKG9wZW5TU0xTdHIpIHsKICAgICAgICAgICAgICB2YXIgc2FsdDsKCiAgICAgICAgICAgICAgLy8gUGFyc2UgYmFzZTY0CiAgICAgICAgICAgICAgdmFyIGNpcGhlcnRleHQgPSBCYXNlNjQucGFyc2Uob3BlblNTTFN0cik7CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgdmFyIGNpcGhlcnRleHRXb3JkcyA9IGNpcGhlcnRleHQud29yZHM7CgogICAgICAgICAgICAgIC8vIFRlc3QgZm9yIHNhbHQKICAgICAgICAgICAgICBpZiAoY2lwaGVydGV4dFdvcmRzWzBdID09IDB4NTM2MTZjNzQgJiYgY2lwaGVydGV4dFdvcmRzWzFdID09IDB4NjU2NDVmNWYpIHsKICAgICAgICAgICAgICAgIC8vIEV4dHJhY3Qgc2FsdAogICAgICAgICAgICAgICAgc2FsdCA9IFdvcmRBcnJheS5jcmVhdGUoY2lwaGVydGV4dFdvcmRzLnNsaWNlKDIsIDQpKTsKCiAgICAgICAgICAgICAgICAvLyBSZW1vdmUgc2FsdCBmcm9tIGNpcGhlcnRleHQKICAgICAgICAgICAgICAgIGNpcGhlcnRleHRXb3Jkcy5zcGxpY2UoMCwgNCk7CiAgICAgICAgICAgICAgICBjaXBoZXJ0ZXh0LnNpZ0J5dGVzIC09IDE2OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4gQ2lwaGVyUGFyYW1zLmNyZWF0ZSh7CiAgICAgICAgICAgICAgICBjaXBoZXJ0ZXh0OiBjaXBoZXJ0ZXh0LAogICAgICAgICAgICAgICAgc2FsdDogc2FsdAogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQSBjaXBoZXIgd3JhcHBlciB0aGF0IHJldHVybnMgY2lwaGVydGV4dCBhcyBhIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zIG9iamVjdC4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIFNlcmlhbGl6YWJsZUNpcGhlciA9IENfbGliLlNlcmlhbGl6YWJsZUNpcGhlciA9IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHByb3BlcnR5IHtGb3JtYXR0ZXJ9IGZvcm1hdCBUaGUgZm9ybWF0dGluZyBzdHJhdGVneSB0byBjb252ZXJ0IGNpcGhlciBwYXJhbSBvYmplY3RzIHRvIGFuZCBmcm9tIGEgc3RyaW5nLiBEZWZhdWx0OiBPcGVuU1NMCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjZmc6IEJhc2UuZXh0ZW5kKHsKICAgICAgICAgICAgICBmb3JtYXQ6IE9wZW5TU0xGb3JtYXR0ZXIKICAgICAgICAgICAgfSksCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBFbmNyeXB0cyBhIG1lc3NhZ2UuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyfSBjaXBoZXIgVGhlIGNpcGhlciBhbGdvcml0aG0gdG8gdXNlLgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gZW5jcnlwdC4KICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl9IGtleSBUaGUga2V5LgogICAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gY2ZnIChPcHRpb25hbCkgVGhlIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byB1c2UgZm9yIHRoaXMgb3BlcmF0aW9uLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IEEgY2lwaGVyIHBhcmFtcyBvYmplY3QuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBtZXNzYWdlLCBrZXkpOwogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuU2VyaWFsaXphYmxlQ2lwaGVyLmVuY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIG1lc3NhZ2UsIGtleSwgeyBpdjogaXYgfSk7CiAgICAgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dFBhcmFtcyA9IENyeXB0b0pTLmxpYi5TZXJpYWxpemFibGVDaXBoZXIuZW5jcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgbWVzc2FnZSwga2V5LCB7IGl2OiBpdiwgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGVuY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXIsIG1lc3NhZ2UsIGtleSwgY2ZnKSB7CiAgICAgICAgICAgICAgLy8gQXBwbHkgY29uZmlnIGRlZmF1bHRzCiAgICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7CgogICAgICAgICAgICAgIC8vIEVuY3J5cHQKICAgICAgICAgICAgICB2YXIgZW5jcnlwdG9yID0gY2lwaGVyLmNyZWF0ZUVuY3J5cHRvcihrZXksIGNmZyk7CiAgICAgICAgICAgICAgdmFyIGNpcGhlcnRleHQgPSBlbmNyeXB0b3IuZmluYWxpemUobWVzc2FnZSk7CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgdmFyIGNpcGhlckNmZyA9IGVuY3J5cHRvci5jZmc7CgogICAgICAgICAgICAgIC8vIENyZWF0ZSBhbmQgcmV0dXJuIHNlcmlhbGl6YWJsZSBjaXBoZXIgcGFyYW1zCiAgICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoewogICAgICAgICAgICAgICAgY2lwaGVydGV4dDogY2lwaGVydGV4dCwKICAgICAgICAgICAgICAgIGtleToga2V5LAogICAgICAgICAgICAgICAgaXY6IGNpcGhlckNmZy5pdiwKICAgICAgICAgICAgICAgIGFsZ29yaXRobTogY2lwaGVyLAogICAgICAgICAgICAgICAgbW9kZTogY2lwaGVyQ2ZnLm1vZGUsCiAgICAgICAgICAgICAgICBwYWRkaW5nOiBjaXBoZXJDZmcucGFkZGluZywKICAgICAgICAgICAgICAgIGJsb2NrU2l6ZTogY2lwaGVyLmJsb2NrU2l6ZSwKICAgICAgICAgICAgICAgIGZvcm1hdHRlcjogY2ZnLmZvcm1hdAogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogRGVjcnlwdHMgc2VyaWFsaXplZCBjaXBoZXJ0ZXh0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS4KICAgICAgICAgICAgICogQHBhcmFtIHtDaXBoZXJQYXJhbXN8c3RyaW5nfSBjaXBoZXJ0ZXh0IFRoZSBjaXBoZXJ0ZXh0IHRvIGRlY3J5cHQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7V29yZEFycmF5fSBrZXkgVGhlIGtleS4KICAgICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGNmZyAoT3B0aW9uYWwpIFRoZSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gdXNlIGZvciB0aGlzIG9wZXJhdGlvbi4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHJldHVybiB7V29yZEFycmF5fSBUaGUgcGxhaW50ZXh0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ID0gQ3J5cHRvSlMubGliLlNlcmlhbGl6YWJsZUNpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBmb3JtYXR0ZWRDaXBoZXJ0ZXh0LCBrZXksIHsgaXY6IGl2LCBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pOwogICAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCA9IENyeXB0b0pTLmxpYi5TZXJpYWxpemFibGVDaXBoZXIuZGVjcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgY2lwaGVydGV4dFBhcmFtcywga2V5LCB7IGl2OiBpdiwgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGRlY3J5cHQ6IGZ1bmN0aW9uIChjaXBoZXIsIGNpcGhlcnRleHQsIGtleSwgY2ZnKSB7CiAgICAgICAgICAgICAgLy8gQXBwbHkgY29uZmlnIGRlZmF1bHRzCiAgICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7CgogICAgICAgICAgICAgIC8vIENvbnZlcnQgc3RyaW5nIHRvIENpcGhlclBhcmFtcwogICAgICAgICAgICAgIGNpcGhlcnRleHQgPSB0aGlzLl9wYXJzZShjaXBoZXJ0ZXh0LCBjZmcuZm9ybWF0KTsKCiAgICAgICAgICAgICAgLy8gRGVjcnlwdAogICAgICAgICAgICAgIHZhciBwbGFpbnRleHQgPSBjaXBoZXIuY3JlYXRlRGVjcnlwdG9yKGtleSwgY2ZnKS5maW5hbGl6ZShjaXBoZXJ0ZXh0LmNpcGhlcnRleHQpOwogICAgICAgICAgICAgIHJldHVybiBwbGFpbnRleHQ7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBDb252ZXJ0cyBzZXJpYWxpemVkIGNpcGhlcnRleHQgdG8gQ2lwaGVyUGFyYW1zLAogICAgICAgICAgICAgKiBlbHNlIGFzc3VtZWQgQ2lwaGVyUGFyYW1zIGFscmVhZHkgYW5kIHJldHVybnMgY2lwaGVydGV4dCB1bmNoYW5nZWQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfHN0cmluZ30gY2lwaGVydGV4dCBUaGUgY2lwaGVydGV4dC4KICAgICAgICAgICAgICogQHBhcmFtIHtGb3JtYXR0ZXJ9IGZvcm1hdCBUaGUgZm9ybWF0dGluZyBzdHJhdGVneSB0byB1c2UgdG8gcGFyc2Ugc2VyaWFsaXplZCBjaXBoZXJ0ZXh0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IFRoZSB1bnNlcmlhbGl6ZWQgY2lwaGVydGV4dC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuU2VyaWFsaXphYmxlQ2lwaGVyLl9wYXJzZShjaXBoZXJ0ZXh0U3RyaW5nT3JQYXJhbXMsIGZvcm1hdCk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBfcGFyc2U6IGZ1bmN0aW9uIChjaXBoZXJ0ZXh0LCBmb3JtYXQpIHsKICAgICAgICAgICAgICBpZiAodHlwZW9mIGNpcGhlcnRleHQgPT0gJ3N0cmluZycpIHsKICAgICAgICAgICAgICAgIHJldHVybiBmb3JtYXQucGFyc2UoY2lwaGVydGV4dCwgdGhpcyk7CiAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJldHVybiBjaXBoZXJ0ZXh0OwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBLZXkgZGVyaXZhdGlvbiBmdW5jdGlvbiBuYW1lc3BhY2UuCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBDX2tkZiA9IEMua2RmID0ge307CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBPcGVuU1NMIGtleSBkZXJpdmF0aW9uIGZ1bmN0aW9uLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgT3BlblNTTEtkZiA9IENfa2RmLk9wZW5TU0wgPSB7CiAgICAgICAgICAgIC8qKgogICAgICAgICAgICAgKiBEZXJpdmVzIGEga2V5IGFuZCBJViBmcm9tIGEgcGFzc3dvcmQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQgdG8gZGVyaXZlIGZyb20uCiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBrZXlTaXplIFRoZSBzaXplIGluIHdvcmRzIG9mIHRoZSBrZXkgdG8gZ2VuZXJhdGUuCiAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpdlNpemUgVGhlIHNpemUgaW4gd29yZHMgb2YgdGhlIElWIHRvIGdlbmVyYXRlLgogICAgICAgICAgICAgKiBAcGFyYW0ge1dvcmRBcnJheXxzdHJpbmd9IHNhbHQgKE9wdGlvbmFsKSBBIDY0LWJpdCBzYWx0IHRvIHVzZS4gSWYgb21pdHRlZCwgYSBzYWx0IHdpbGwgYmUgZ2VuZXJhdGVkIHJhbmRvbWx5LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IEEgY2lwaGVyIHBhcmFtcyBvYmplY3Qgd2l0aCB0aGUga2V5LCBJViwgYW5kIHNhbHQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBzdGF0aWMKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAgICoKICAgICAgICAgICAgICogICAgIHZhciBkZXJpdmVkUGFyYW1zID0gQ3J5cHRvSlMua2RmLk9wZW5TU0wuZXhlY3V0ZSgnUGFzc3dvcmQnLCAyNTYvMzIsIDEyOC8zMik7CiAgICAgICAgICAgICAqICAgICB2YXIgZGVyaXZlZFBhcmFtcyA9IENyeXB0b0pTLmtkZi5PcGVuU1NMLmV4ZWN1dGUoJ1Bhc3N3b3JkJywgMjU2LzMyLCAxMjgvMzIsICdzYWx0c2FsdCcpOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZXhlY3V0ZTogZnVuY3Rpb24gKHBhc3N3b3JkLCBrZXlTaXplLCBpdlNpemUsIHNhbHQsIGhhc2hlcikgewogICAgICAgICAgICAgIC8vIEdlbmVyYXRlIHJhbmRvbSBzYWx0CiAgICAgICAgICAgICAgaWYgKCFzYWx0KSB7CiAgICAgICAgICAgICAgICBzYWx0ID0gV29yZEFycmF5LnJhbmRvbSg2NCAvIDgpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gRGVyaXZlIGtleSBhbmQgSVYKICAgICAgICAgICAgICBpZiAoIWhhc2hlcikgewogICAgICAgICAgICAgICAgdmFyIGtleSA9IEV2cEtERi5jcmVhdGUoewogICAgICAgICAgICAgICAgICBrZXlTaXplOiBrZXlTaXplICsgaXZTaXplCiAgICAgICAgICAgICAgICB9KS5jb21wdXRlKHBhc3N3b3JkLCBzYWx0KTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdmFyIGtleSA9IEV2cEtERi5jcmVhdGUoewogICAgICAgICAgICAgICAgICBrZXlTaXplOiBrZXlTaXplICsgaXZTaXplLAogICAgICAgICAgICAgICAgICBoYXNoZXI6IGhhc2hlcgogICAgICAgICAgICAgICAgfSkuY29tcHV0ZShwYXNzd29yZCwgc2FsdCk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBTZXBhcmF0ZSBrZXkgYW5kIElWCiAgICAgICAgICAgICAgdmFyIGl2ID0gV29yZEFycmF5LmNyZWF0ZShrZXkud29yZHMuc2xpY2Uoa2V5U2l6ZSksIGl2U2l6ZSAqIDQpOwogICAgICAgICAgICAgIGtleS5zaWdCeXRlcyA9IGtleVNpemUgKiA0OwoKICAgICAgICAgICAgICAvLyBSZXR1cm4gcGFyYW1zCiAgICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoewogICAgICAgICAgICAgICAga2V5OiBrZXksCiAgICAgICAgICAgICAgICBpdjogaXYsCiAgICAgICAgICAgICAgICBzYWx0OiBzYWx0CiAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH07CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBBIHNlcmlhbGl6YWJsZSBjaXBoZXIgd3JhcHBlciB0aGF0IGRlcml2ZXMgdGhlIGtleSBmcm9tIGEgcGFzc3dvcmQsCiAgICAgICAgICAgKiBhbmQgcmV0dXJucyBjaXBoZXJ0ZXh0IGFzIGEgc2VyaWFsaXphYmxlIGNpcGhlciBwYXJhbXMgb2JqZWN0LgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgUGFzc3dvcmRCYXNlZENpcGhlciA9IENfbGliLlBhc3N3b3JkQmFzZWRDaXBoZXIgPSBTZXJpYWxpemFibGVDaXBoZXIuZXh0ZW5kKHsKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIENvbmZpZ3VyYXRpb24gb3B0aW9ucy4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHByb3BlcnR5IHtLREZ9IGtkZiBUaGUga2V5IGRlcml2YXRpb24gZnVuY3Rpb24gdG8gdXNlIHRvIGdlbmVyYXRlIGEga2V5IGFuZCBJViBmcm9tIGEgcGFzc3dvcmQuIERlZmF1bHQ6IE9wZW5TU0wKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGNmZzogU2VyaWFsaXphYmxlQ2lwaGVyLmNmZy5leHRlbmQoewogICAgICAgICAgICAgIGtkZjogT3BlblNTTEtkZgogICAgICAgICAgICB9KSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIEVuY3J5cHRzIGEgbWVzc2FnZSB1c2luZyBhIHBhc3N3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS4KICAgICAgICAgICAgICogQHBhcmFtIHtXb3JkQXJyYXl8c3RyaW5nfSBtZXNzYWdlIFRoZSBtZXNzYWdlIHRvIGVuY3J5cHQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge0NpcGhlclBhcmFtc30gQSBjaXBoZXIgcGFyYW1zIG9iamVjdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHRQYXJhbXMgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5lbmNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBtZXNzYWdlLCAncGFzc3dvcmQnKTsKICAgICAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0UGFyYW1zID0gQ3J5cHRvSlMubGliLlBhc3N3b3JkQmFzZWRDaXBoZXIuZW5jcnlwdChDcnlwdG9KUy5hbGdvLkFFUywgbWVzc2FnZSwgJ3Bhc3N3b3JkJywgeyBmb3JtYXQ6IENyeXB0b0pTLmZvcm1hdC5PcGVuU1NMIH0pOwogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZW5jcnlwdDogZnVuY3Rpb24gKGNpcGhlciwgbWVzc2FnZSwgcGFzc3dvcmQsIGNmZykgewogICAgICAgICAgICAgIC8vIEFwcGx5IGNvbmZpZyBkZWZhdWx0cwogICAgICAgICAgICAgIGNmZyA9IHRoaXMuY2ZnLmV4dGVuZChjZmcpOwoKICAgICAgICAgICAgICAvLyBEZXJpdmUga2V5IGFuZCBvdGhlciBwYXJhbXMKICAgICAgICAgICAgICB2YXIgZGVyaXZlZFBhcmFtcyA9IGNmZy5rZGYuZXhlY3V0ZShwYXNzd29yZCwgY2lwaGVyLmtleVNpemUsIGNpcGhlci5pdlNpemUsIGNmZy5zYWx0LCBjZmcuaGFzaGVyKTsKCiAgICAgICAgICAgICAgLy8gQWRkIElWIHRvIGNvbmZpZwogICAgICAgICAgICAgIGNmZy5pdiA9IGRlcml2ZWRQYXJhbXMuaXY7CgogICAgICAgICAgICAgIC8vIEVuY3J5cHQKICAgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IFNlcmlhbGl6YWJsZUNpcGhlci5lbmNyeXB0LmNhbGwodGhpcywgY2lwaGVyLCBtZXNzYWdlLCBkZXJpdmVkUGFyYW1zLmtleSwgY2ZnKTsKCiAgICAgICAgICAgICAgLy8gTWl4IGluIGRlcml2ZWQgcGFyYW1zCiAgICAgICAgICAgICAgY2lwaGVydGV4dC5taXhJbihkZXJpdmVkUGFyYW1zKTsKICAgICAgICAgICAgICByZXR1cm4gY2lwaGVydGV4dDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgLyoqCiAgICAgICAgICAgICAqIERlY3J5cHRzIHNlcmlhbGl6ZWQgY2lwaGVydGV4dCB1c2luZyBhIHBhc3N3b3JkLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcGFyYW0ge0NpcGhlcn0gY2lwaGVyIFRoZSBjaXBoZXIgYWxnb3JpdGhtIHRvIHVzZS4KICAgICAgICAgICAgICogQHBhcmFtIHtDaXBoZXJQYXJhbXN8c3RyaW5nfSBjaXBoZXJ0ZXh0IFRoZSBjaXBoZXJ0ZXh0IHRvIGRlY3J5cHQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfSBwYXNzd29yZCBUaGUgcGFzc3dvcmQuCiAgICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjZmcgKE9wdGlvbmFsKSBUaGUgY29uZmlndXJhdGlvbiBvcHRpb25zIHRvIHVzZSBmb3IgdGhpcyBvcGVyYXRpb24uCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEByZXR1cm4ge1dvcmRBcnJheX0gVGhlIHBsYWludGV4dC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCA9IENyeXB0b0pTLmxpYi5QYXNzd29yZEJhc2VkQ2lwaGVyLmRlY3J5cHQoQ3J5cHRvSlMuYWxnby5BRVMsIGZvcm1hdHRlZENpcGhlcnRleHQsICdwYXNzd29yZCcsIHsgZm9ybWF0OiBDcnlwdG9KUy5mb3JtYXQuT3BlblNTTCB9KTsKICAgICAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgPSBDcnlwdG9KUy5saWIuUGFzc3dvcmRCYXNlZENpcGhlci5kZWNyeXB0KENyeXB0b0pTLmFsZ28uQUVTLCBjaXBoZXJ0ZXh0UGFyYW1zLCAncGFzc3dvcmQnLCB7IGZvcm1hdDogQ3J5cHRvSlMuZm9ybWF0Lk9wZW5TU0wgfSk7CiAgICAgICAgICAgICAqLwogICAgICAgICAgICBkZWNyeXB0OiBmdW5jdGlvbiAoY2lwaGVyLCBjaXBoZXJ0ZXh0LCBwYXNzd29yZCwgY2ZnKSB7CiAgICAgICAgICAgICAgLy8gQXBwbHkgY29uZmlnIGRlZmF1bHRzCiAgICAgICAgICAgICAgY2ZnID0gdGhpcy5jZmcuZXh0ZW5kKGNmZyk7CgogICAgICAgICAgICAgIC8vIENvbnZlcnQgc3RyaW5nIHRvIENpcGhlclBhcmFtcwogICAgICAgICAgICAgIGNpcGhlcnRleHQgPSB0aGlzLl9wYXJzZShjaXBoZXJ0ZXh0LCBjZmcuZm9ybWF0KTsKCiAgICAgICAgICAgICAgLy8gRGVyaXZlIGtleSBhbmQgb3RoZXIgcGFyYW1zCiAgICAgICAgICAgICAgdmFyIGRlcml2ZWRQYXJhbXMgPSBjZmcua2RmLmV4ZWN1dGUocGFzc3dvcmQsIGNpcGhlci5rZXlTaXplLCBjaXBoZXIuaXZTaXplLCBjaXBoZXJ0ZXh0LnNhbHQsIGNmZy5oYXNoZXIpOwoKICAgICAgICAgICAgICAvLyBBZGQgSVYgdG8gY29uZmlnCiAgICAgICAgICAgICAgY2ZnLml2ID0gZGVyaXZlZFBhcmFtcy5pdjsKCiAgICAgICAgICAgICAgLy8gRGVjcnlwdAogICAgICAgICAgICAgIHZhciBwbGFpbnRleHQgPSBTZXJpYWxpemFibGVDaXBoZXIuZGVjcnlwdC5jYWxsKHRoaXMsIGNpcGhlciwgY2lwaGVydGV4dCwgZGVyaXZlZFBhcmFtcy5rZXksIGNmZyk7CiAgICAgICAgICAgICAgcmV0dXJuIHBsYWludGV4dDsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgfSgpOwogICAgICB9KTsKICAgIH0pKGNpcGhlckNvcmUkMSk7CiAgICByZXR1cm4gY2lwaGVyQ29yZSQxLmV4cG9ydHM7CiAgfQoKICB2YXIgbW9kZUNmYiQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIG1vZGVDZmIgPSBtb2RlQ2ZiJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRNb2RlQ2ZiOwogIGZ1bmN0aW9uIHJlcXVpcmVNb2RlQ2ZiKCkgewogICAgaWYgKGhhc1JlcXVpcmVkTW9kZUNmYikgcmV0dXJuIG1vZGVDZmIkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRNb2RlQ2ZiID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShtb2RlQ2ZiLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAvKioKICAgICAgICAgKiBDaXBoZXIgRmVlZGJhY2sgYmxvY2sgbW9kZS4KICAgICAgICAgKi8KICAgICAgICBDcnlwdG9KUy5tb2RlLkNGQiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgIHZhciBDRkIgPSBDcnlwdG9KUy5saWIuQmxvY2tDaXBoZXJNb2RlLmV4dGVuZCgpOwogICAgICAgICAgQ0ZCLkVuY3J5cHRvciA9IENGQi5leHRlbmQoewogICAgICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGNpcGhlciA9IHRoaXMuX2NpcGhlcjsKICAgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTsKICAgICAgICAgICAgICBnZW5lcmF0ZUtleXN0cmVhbUFuZEVuY3J5cHQuY2FsbCh0aGlzLCB3b3Jkcywgb2Zmc2V0LCBibG9ja1NpemUsIGNpcGhlcik7CgogICAgICAgICAgICAgIC8vIFJlbWVtYmVyIHRoaXMgYmxvY2sgdG8gdXNlIHdpdGggbmV4dCBibG9jawogICAgICAgICAgICAgIHRoaXMuX3ByZXZCbG9jayA9IHdvcmRzLnNsaWNlKG9mZnNldCwgb2Zmc2V0ICsgYmxvY2tTaXplKTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBDRkIuRGVjcnlwdG9yID0gQ0ZCLmV4dGVuZCh7CiAgICAgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyOwogICAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSBjaXBoZXIuYmxvY2tTaXplOwoKICAgICAgICAgICAgICAvLyBSZW1lbWJlciB0aGlzIGJsb2NrIHRvIHVzZSB3aXRoIG5leHQgYmxvY2sKICAgICAgICAgICAgICB2YXIgdGhpc0Jsb2NrID0gd29yZHMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBibG9ja1NpemUpOwogICAgICAgICAgICAgIGdlbmVyYXRlS2V5c3RyZWFtQW5kRW5jcnlwdC5jYWxsKHRoaXMsIHdvcmRzLCBvZmZzZXQsIGJsb2NrU2l6ZSwgY2lwaGVyKTsKCiAgICAgICAgICAgICAgLy8gVGhpcyBibG9jayBiZWNvbWVzIHRoZSBwcmV2aW91cyBibG9jawogICAgICAgICAgICAgIHRoaXMuX3ByZXZCbG9jayA9IHRoaXNCbG9jazsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBmdW5jdGlvbiBnZW5lcmF0ZUtleXN0cmVhbUFuZEVuY3J5cHQod29yZHMsIG9mZnNldCwgYmxvY2tTaXplLCBjaXBoZXIpIHsKICAgICAgICAgICAgdmFyIGtleXN0cmVhbTsKCiAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgIHZhciBpdiA9IHRoaXMuX2l2OwoKICAgICAgICAgICAgLy8gR2VuZXJhdGUga2V5c3RyZWFtCiAgICAgICAgICAgIGlmIChpdikgewogICAgICAgICAgICAgIGtleXN0cmVhbSA9IGl2LnNsaWNlKDApOwoKICAgICAgICAgICAgICAvLyBSZW1vdmUgSVYgZm9yIHN1YnNlcXVlbnQgYmxvY2tzCiAgICAgICAgICAgICAgdGhpcy5faXYgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAga2V5c3RyZWFtID0gdGhpcy5fcHJldkJsb2NrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGNpcGhlci5lbmNyeXB0QmxvY2soa2V5c3RyZWFtLCAwKTsKCiAgICAgICAgICAgIC8vIEVuY3J5cHQKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja1NpemU7IGkrKykgewogICAgICAgICAgICAgIHdvcmRzW29mZnNldCArIGldIF49IGtleXN0cmVhbVtpXTsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIENGQjsKICAgICAgICB9KCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLm1vZGUuQ0ZCOwogICAgICB9KTsKICAgIH0pKG1vZGVDZmIkMSk7CiAgICByZXR1cm4gbW9kZUNmYiQxLmV4cG9ydHM7CiAgfQoKICB2YXIgbW9kZUN0ciQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIG1vZGVDdHIgPSBtb2RlQ3RyJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRNb2RlQ3RyOwogIGZ1bmN0aW9uIHJlcXVpcmVNb2RlQ3RyKCkgewogICAgaWYgKGhhc1JlcXVpcmVkTW9kZUN0cikgcmV0dXJuIG1vZGVDdHIkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRNb2RlQ3RyID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShtb2RlQ3RyLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAvKioKICAgICAgICAgKiBDb3VudGVyIGJsb2NrIG1vZGUuCiAgICAgICAgICovCiAgICAgICAgQ3J5cHRvSlMubW9kZS5DVFIgPSBmdW5jdGlvbiAoKSB7CiAgICAgICAgICB2YXIgQ1RSID0gQ3J5cHRvSlMubGliLkJsb2NrQ2lwaGVyTW9kZS5leHRlbmQoKTsKICAgICAgICAgIHZhciBFbmNyeXB0b3IgPSBDVFIuRW5jcnlwdG9yID0gQ1RSLmV4dGVuZCh7CiAgICAgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgY2lwaGVyID0gdGhpcy5fY2lwaGVyOwogICAgICAgICAgICAgIHZhciBibG9ja1NpemUgPSBjaXBoZXIuYmxvY2tTaXplOwogICAgICAgICAgICAgIHZhciBpdiA9IHRoaXMuX2l2OwogICAgICAgICAgICAgIHZhciBjb3VudGVyID0gdGhpcy5fY291bnRlcjsKCiAgICAgICAgICAgICAgLy8gR2VuZXJhdGUga2V5c3RyZWFtCiAgICAgICAgICAgICAgaWYgKGl2KSB7CiAgICAgICAgICAgICAgICBjb3VudGVyID0gdGhpcy5fY291bnRlciA9IGl2LnNsaWNlKDApOwoKICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBJViBmb3Igc3Vic2VxdWVudCBibG9ja3MKICAgICAgICAgICAgICAgIHRoaXMuX2l2ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB2YXIga2V5c3RyZWFtID0gY291bnRlci5zbGljZSgwKTsKICAgICAgICAgICAgICBjaXBoZXIuZW5jcnlwdEJsb2NrKGtleXN0cmVhbSwgMCk7CgogICAgICAgICAgICAgIC8vIEluY3JlbWVudCBjb3VudGVyCiAgICAgICAgICAgICAgY291bnRlcltibG9ja1NpemUgLSAxXSA9IGNvdW50ZXJbYmxvY2tTaXplIC0gMV0gKyAxIHwgMDsKCiAgICAgICAgICAgICAgLy8gRW5jcnlwdAogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYmxvY2tTaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIHdvcmRzW29mZnNldCArIGldIF49IGtleXN0cmVhbVtpXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgIH0pOwogICAgICAgICAgQ1RSLkRlY3J5cHRvciA9IEVuY3J5cHRvcjsKICAgICAgICAgIHJldHVybiBDVFI7CiAgICAgICAgfSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5tb2RlLkNUUjsKICAgICAgfSk7CiAgICB9KShtb2RlQ3RyJDEpOwogICAgcmV0dXJuIG1vZGVDdHIkMS5leHBvcnRzOwogIH0KCiAgdmFyIG1vZGVDdHJHbGFkbWFuJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgbW9kZUN0ckdsYWRtYW4gPSBtb2RlQ3RyR2xhZG1hbiQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkTW9kZUN0ckdsYWRtYW47CiAgZnVuY3Rpb24gcmVxdWlyZU1vZGVDdHJHbGFkbWFuKCkgewogICAgaWYgKGhhc1JlcXVpcmVkTW9kZUN0ckdsYWRtYW4pIHJldHVybiBtb2RlQ3RyR2xhZG1hbiQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZE1vZGVDdHJHbGFkbWFuID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShtb2RlQ3RyR2xhZG1hbiwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgLyoqIEBwcmVzZXJ2ZQogICAgICAgICAqIENvdW50ZXIgYmxvY2sgbW9kZSBjb21wYXRpYmxlIHdpdGggIERyIEJyaWFuIEdsYWRtYW4gZmlsZWVuYy5jCiAgICAgICAgICogZGVyaXZlZCBmcm9tIENyeXB0b0pTLm1vZGUuQ1RSCiAgICAgICAgICogSmFuIEhydWJ5IGpocnVieS53ZWJAZ21haWwuY29tCiAgICAgICAgICovCiAgICAgICAgQ3J5cHRvSlMubW9kZS5DVFJHbGFkbWFuID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgdmFyIENUUkdsYWRtYW4gPSBDcnlwdG9KUy5saWIuQmxvY2tDaXBoZXJNb2RlLmV4dGVuZCgpOwogICAgICAgICAgZnVuY3Rpb24gaW5jV29yZCh3b3JkKSB7CiAgICAgICAgICAgIGlmICgod29yZCA+PiAyNCAmIDB4ZmYpID09PSAweGZmKSB7CiAgICAgICAgICAgICAgLy9vdmVyZmxvdwogICAgICAgICAgICAgIHZhciBiMSA9IHdvcmQgPj4gMTYgJiAweGZmOwogICAgICAgICAgICAgIHZhciBiMiA9IHdvcmQgPj4gOCAmIDB4ZmY7CiAgICAgICAgICAgICAgdmFyIGIzID0gd29yZCAmIDB4ZmY7CiAgICAgICAgICAgICAgaWYgKGIxID09PSAweGZmKQogICAgICAgICAgICAgICAgLy8gb3ZlcmZsb3cgYjEKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgYjEgPSAwOwogICAgICAgICAgICAgICAgICBpZiAoYjIgPT09IDB4ZmYpIHsKICAgICAgICAgICAgICAgICAgICBiMiA9IDA7CiAgICAgICAgICAgICAgICAgICAgaWYgKGIzID09PSAweGZmKSB7CiAgICAgICAgICAgICAgICAgICAgICBiMyA9IDA7CiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICsrYjM7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICsrYjI7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICArK2IxOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB3b3JkID0gMDsKICAgICAgICAgICAgICB3b3JkICs9IGIxIDw8IDE2OwogICAgICAgICAgICAgIHdvcmQgKz0gYjIgPDwgODsKICAgICAgICAgICAgICB3b3JkICs9IGIzOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIHdvcmQgKz0gMHgwMSA8PCAyNDsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gd29yZDsKICAgICAgICAgIH0KICAgICAgICAgIGZ1bmN0aW9uIGluY0NvdW50ZXIoY291bnRlcikgewogICAgICAgICAgICBpZiAoKGNvdW50ZXJbMF0gPSBpbmNXb3JkKGNvdW50ZXJbMF0pKSA9PT0gMCkgewogICAgICAgICAgICAgIC8vIGVuY3JfZGF0YSBpbiBmaWxlZW5jLmMgZnJvbSAgRHIgQnJpYW4gR2xhZG1hbidzIGNvdW50cyBvbmx5IHdpdGggRFdPUkQgaiA8IDgKICAgICAgICAgICAgICBjb3VudGVyWzFdID0gaW5jV29yZChjb3VudGVyWzFdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gY291bnRlcjsKICAgICAgICAgIH0KICAgICAgICAgIHZhciBFbmNyeXB0b3IgPSBDVFJHbGFkbWFuLkVuY3J5cHRvciA9IENUUkdsYWRtYW4uZXh0ZW5kKHsKICAgICAgICAgICAgcHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAod29yZHMsIG9mZnNldCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBjaXBoZXIgPSB0aGlzLl9jaXBoZXI7CiAgICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZSA9IGNpcGhlci5ibG9ja1NpemU7CiAgICAgICAgICAgICAgdmFyIGl2ID0gdGhpcy5faXY7CiAgICAgICAgICAgICAgdmFyIGNvdW50ZXIgPSB0aGlzLl9jb3VudGVyOwoKICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBrZXlzdHJlYW0KICAgICAgICAgICAgICBpZiAoaXYpIHsKICAgICAgICAgICAgICAgIGNvdW50ZXIgPSB0aGlzLl9jb3VudGVyID0gaXYuc2xpY2UoMCk7CgogICAgICAgICAgICAgICAgLy8gUmVtb3ZlIElWIGZvciBzdWJzZXF1ZW50IGJsb2NrcwogICAgICAgICAgICAgICAgdGhpcy5faXYgPSB1bmRlZmluZWQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGluY0NvdW50ZXIoY291bnRlcik7CiAgICAgICAgICAgICAgdmFyIGtleXN0cmVhbSA9IGNvdW50ZXIuc2xpY2UoMCk7CiAgICAgICAgICAgICAgY2lwaGVyLmVuY3J5cHRCbG9jayhrZXlzdHJlYW0sIDApOwoKICAgICAgICAgICAgICAvLyBFbmNyeXB0CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBibG9ja1NpemU7IGkrKykgewogICAgICAgICAgICAgICAgd29yZHNbb2Zmc2V0ICsgaV0gXj0ga2V5c3RyZWFtW2ldOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBDVFJHbGFkbWFuLkRlY3J5cHRvciA9IEVuY3J5cHRvcjsKICAgICAgICAgIHJldHVybiBDVFJHbGFkbWFuOwogICAgICAgIH0oKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMubW9kZS5DVFJHbGFkbWFuOwogICAgICB9KTsKICAgIH0pKG1vZGVDdHJHbGFkbWFuJDEpOwogICAgcmV0dXJuIG1vZGVDdHJHbGFkbWFuJDEuZXhwb3J0czsKICB9CgogIHZhciBtb2RlT2ZiJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgbW9kZU9mYiA9IG1vZGVPZmIkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZE1vZGVPZmI7CiAgZnVuY3Rpb24gcmVxdWlyZU1vZGVPZmIoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRNb2RlT2ZiKSByZXR1cm4gbW9kZU9mYiQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZE1vZGVPZmIgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKG1vZGVPZmIsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIC8qKgogICAgICAgICAqIE91dHB1dCBGZWVkYmFjayBibG9jayBtb2RlLgogICAgICAgICAqLwogICAgICAgIENyeXB0b0pTLm1vZGUuT0ZCID0gZnVuY3Rpb24gKCkgewogICAgICAgICAgdmFyIE9GQiA9IENyeXB0b0pTLmxpYi5CbG9ja0NpcGhlck1vZGUuZXh0ZW5kKCk7CiAgICAgICAgICB2YXIgRW5jcnlwdG9yID0gT0ZCLkVuY3J5cHRvciA9IE9GQi5leHRlbmQoewogICAgICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGNpcGhlciA9IHRoaXMuX2NpcGhlcjsKICAgICAgICAgICAgICB2YXIgYmxvY2tTaXplID0gY2lwaGVyLmJsb2NrU2l6ZTsKICAgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLl9pdjsKICAgICAgICAgICAgICB2YXIga2V5c3RyZWFtID0gdGhpcy5fa2V5c3RyZWFtOwoKICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBrZXlzdHJlYW0KICAgICAgICAgICAgICBpZiAoaXYpIHsKICAgICAgICAgICAgICAgIGtleXN0cmVhbSA9IHRoaXMuX2tleXN0cmVhbSA9IGl2LnNsaWNlKDApOwoKICAgICAgICAgICAgICAgIC8vIFJlbW92ZSBJViBmb3Igc3Vic2VxdWVudCBibG9ja3MKICAgICAgICAgICAgICAgIHRoaXMuX2l2ID0gdW5kZWZpbmVkOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBjaXBoZXIuZW5jcnlwdEJsb2NrKGtleXN0cmVhbSwgMCk7CgogICAgICAgICAgICAgIC8vIEVuY3J5cHQKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJsb2NrU2l6ZTsgaSsrKSB7CiAgICAgICAgICAgICAgICB3b3Jkc1tvZmZzZXQgKyBpXSBePSBrZXlzdHJlYW1baV07CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICAgIE9GQi5EZWNyeXB0b3IgPSBFbmNyeXB0b3I7CiAgICAgICAgICByZXR1cm4gT0ZCOwogICAgICAgIH0oKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMubW9kZS5PRkI7CiAgICAgIH0pOwogICAgfSkobW9kZU9mYiQxKTsKICAgIHJldHVybiBtb2RlT2ZiJDEuZXhwb3J0czsKICB9CgogIHZhciBtb2RlRWNiJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgbW9kZUVjYiA9IG1vZGVFY2IkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZE1vZGVFY2I7CiAgZnVuY3Rpb24gcmVxdWlyZU1vZGVFY2IoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRNb2RlRWNiKSByZXR1cm4gbW9kZUVjYiQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZE1vZGVFY2IgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKG1vZGVFY2IsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIC8qKgogICAgICAgICAqIEVsZWN0cm9uaWMgQ29kZWJvb2sgYmxvY2sgbW9kZS4KICAgICAgICAgKi8KICAgICAgICBDcnlwdG9KUy5tb2RlLkVDQiA9IGZ1bmN0aW9uICgpIHsKICAgICAgICAgIHZhciBFQ0IgPSBDcnlwdG9KUy5saWIuQmxvY2tDaXBoZXJNb2RlLmV4dGVuZCgpOwogICAgICAgICAgRUNCLkVuY3J5cHRvciA9IEVDQi5leHRlbmQoewogICAgICAgICAgICBwcm9jZXNzQmxvY2s6IGZ1bmN0aW9uICh3b3Jkcywgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgdGhpcy5fY2lwaGVyLmVuY3J5cHRCbG9jayh3b3Jkcywgb2Zmc2V0KTsKICAgICAgICAgICAgfQogICAgICAgICAgfSk7CiAgICAgICAgICBFQ0IuRGVjcnlwdG9yID0gRUNCLmV4dGVuZCh7CiAgICAgICAgICAgIHByb2Nlc3NCbG9jazogZnVuY3Rpb24gKHdvcmRzLCBvZmZzZXQpIHsKICAgICAgICAgICAgICB0aGlzLl9jaXBoZXIuZGVjcnlwdEJsb2NrKHdvcmRzLCBvZmZzZXQpOwogICAgICAgICAgICB9CiAgICAgICAgICB9KTsKICAgICAgICAgIHJldHVybiBFQ0I7CiAgICAgICAgfSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5tb2RlLkVDQjsKICAgICAgfSk7CiAgICB9KShtb2RlRWNiJDEpOwogICAgcmV0dXJuIG1vZGVFY2IkMS5leHBvcnRzOwogIH0KCiAgdmFyIHBhZEFuc2l4OTIzJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgcGFkQW5zaXg5MjMgPSBwYWRBbnNpeDkyMyQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkUGFkQW5zaXg5MjM7CiAgZnVuY3Rpb24gcmVxdWlyZVBhZEFuc2l4OTIzKCkgewogICAgaWYgKGhhc1JlcXVpcmVkUGFkQW5zaXg5MjMpIHJldHVybiBwYWRBbnNpeDkyMyQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZFBhZEFuc2l4OTIzID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShwYWRBbnNpeDkyMywgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgLyoqCiAgICAgICAgICogQU5TSSBYLjkyMyBwYWRkaW5nIHN0cmF0ZWd5LgogICAgICAgICAqLwogICAgICAgIENyeXB0b0pTLnBhZC5BbnNpWDkyMyA9IHsKICAgICAgICAgIHBhZDogZnVuY3Rpb24gKGRhdGEsIGJsb2NrU2l6ZSkgewogICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgdmFyIGRhdGFTaWdCeXRlcyA9IGRhdGEuc2lnQnl0ZXM7CiAgICAgICAgICAgIHZhciBibG9ja1NpemVCeXRlcyA9IGJsb2NrU2l6ZSAqIDQ7CgogICAgICAgICAgICAvLyBDb3VudCBwYWRkaW5nIGJ5dGVzCiAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gYmxvY2tTaXplQnl0ZXMgLSBkYXRhU2lnQnl0ZXMgJSBibG9ja1NpemVCeXRlczsKCiAgICAgICAgICAgIC8vIENvbXB1dGUgbGFzdCBieXRlIHBvc2l0aW9uCiAgICAgICAgICAgIHZhciBsYXN0Qnl0ZVBvcyA9IGRhdGFTaWdCeXRlcyArIG5QYWRkaW5nQnl0ZXMgLSAxOwoKICAgICAgICAgICAgLy8gUGFkCiAgICAgICAgICAgIGRhdGEuY2xhbXAoKTsKICAgICAgICAgICAgZGF0YS53b3Jkc1tsYXN0Qnl0ZVBvcyA+Pj4gMl0gfD0gblBhZGRpbmdCeXRlcyA8PCAyNCAtIGxhc3RCeXRlUG9zICUgNCAqIDg7CiAgICAgICAgICAgIGRhdGEuc2lnQnl0ZXMgKz0gblBhZGRpbmdCeXRlczsKICAgICAgICAgIH0sCiAgICAgICAgICB1bnBhZDogZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgICAgICAgLy8gR2V0IG51bWJlciBvZiBwYWRkaW5nIGJ5dGVzIGZyb20gbGFzdCBieXRlCiAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gZGF0YS53b3Jkc1tkYXRhLnNpZ0J5dGVzIC0gMSA+Pj4gMl0gJiAweGZmOwoKICAgICAgICAgICAgLy8gUmVtb3ZlIHBhZGRpbmcKICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyAtPSBuUGFkZGluZ0J5dGVzOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLnBhZC5BbnNpeDkyMzsKICAgICAgfSk7CiAgICB9KShwYWRBbnNpeDkyMyQxKTsKICAgIHJldHVybiBwYWRBbnNpeDkyMyQxLmV4cG9ydHM7CiAgfQoKICB2YXIgcGFkSXNvMTAxMjYkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBwYWRJc28xMDEyNiA9IHBhZElzbzEwMTI2JDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRQYWRJc28xMDEyNjsKICBmdW5jdGlvbiByZXF1aXJlUGFkSXNvMTAxMjYoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRQYWRJc28xMDEyNikgcmV0dXJuIHBhZElzbzEwMTI2JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUGFkSXNvMTAxMjYgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHBhZElzbzEwMTI2LCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAvKioKICAgICAgICAgKiBJU08gMTAxMjYgcGFkZGluZyBzdHJhdGVneS4KICAgICAgICAgKi8KICAgICAgICBDcnlwdG9KUy5wYWQuSXNvMTAxMjYgPSB7CiAgICAgICAgICBwYWQ6IGZ1bmN0aW9uIChkYXRhLCBibG9ja1NpemUpIHsKICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgdmFyIGJsb2NrU2l6ZUJ5dGVzID0gYmxvY2tTaXplICogNDsKCiAgICAgICAgICAgIC8vIENvdW50IHBhZGRpbmcgYnl0ZXMKICAgICAgICAgICAgdmFyIG5QYWRkaW5nQnl0ZXMgPSBibG9ja1NpemVCeXRlcyAtIGRhdGEuc2lnQnl0ZXMgJSBibG9ja1NpemVCeXRlczsKCiAgICAgICAgICAgIC8vIFBhZAogICAgICAgICAgICBkYXRhLmNvbmNhdChDcnlwdG9KUy5saWIuV29yZEFycmF5LnJhbmRvbShuUGFkZGluZ0J5dGVzIC0gMSkpLmNvbmNhdChDcnlwdG9KUy5saWIuV29yZEFycmF5LmNyZWF0ZShbblBhZGRpbmdCeXRlcyA8PCAyNF0sIDEpKTsKICAgICAgICAgIH0sCiAgICAgICAgICB1bnBhZDogZnVuY3Rpb24gKGRhdGEpIHsKICAgICAgICAgICAgLy8gR2V0IG51bWJlciBvZiBwYWRkaW5nIGJ5dGVzIGZyb20gbGFzdCBieXRlCiAgICAgICAgICAgIHZhciBuUGFkZGluZ0J5dGVzID0gZGF0YS53b3Jkc1tkYXRhLnNpZ0J5dGVzIC0gMSA+Pj4gMl0gJiAweGZmOwoKICAgICAgICAgICAgLy8gUmVtb3ZlIHBhZGRpbmcKICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyAtPSBuUGFkZGluZ0J5dGVzOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLnBhZC5Jc28xMDEyNjsKICAgICAgfSk7CiAgICB9KShwYWRJc28xMDEyNiQxKTsKICAgIHJldHVybiBwYWRJc28xMDEyNiQxLmV4cG9ydHM7CiAgfQoKICB2YXIgcGFkSXNvOTc5NzEkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBwYWRJc285Nzk3MSA9IHBhZElzbzk3OTcxJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRQYWRJc285Nzk3MTsKICBmdW5jdGlvbiByZXF1aXJlUGFkSXNvOTc5NzEoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRQYWRJc285Nzk3MSkgcmV0dXJuIHBhZElzbzk3OTcxJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUGFkSXNvOTc5NzEgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHBhZElzbzk3OTcxLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAvKioKICAgICAgICAgKiBJU08vSUVDIDk3OTctMSBQYWRkaW5nIE1ldGhvZCAyLgogICAgICAgICAqLwogICAgICAgIENyeXB0b0pTLnBhZC5Jc285Nzk3MSA9IHsKICAgICAgICAgIHBhZDogZnVuY3Rpb24gKGRhdGEsIGJsb2NrU2l6ZSkgewogICAgICAgICAgICAvLyBBZGQgMHg4MCBieXRlCiAgICAgICAgICAgIGRhdGEuY29uY2F0KENyeXB0b0pTLmxpYi5Xb3JkQXJyYXkuY3JlYXRlKFsweDgwMDAwMDAwXSwgMSkpOwoKICAgICAgICAgICAgLy8gWmVybyBwYWQgdGhlIHJlc3QKICAgICAgICAgICAgQ3J5cHRvSlMucGFkLlplcm9QYWRkaW5nLnBhZChkYXRhLCBibG9ja1NpemUpOwogICAgICAgICAgfSwKICAgICAgICAgIHVucGFkOiBmdW5jdGlvbiAoZGF0YSkgewogICAgICAgICAgICAvLyBSZW1vdmUgemVybyBwYWRkaW5nCiAgICAgICAgICAgIENyeXB0b0pTLnBhZC5aZXJvUGFkZGluZy51bnBhZChkYXRhKTsKCiAgICAgICAgICAgIC8vIFJlbW92ZSBvbmUgbW9yZSBieXRlIC0tIHRoZSAweDgwIGJ5dGUKICAgICAgICAgICAgZGF0YS5zaWdCeXRlcy0tOwogICAgICAgICAgfQogICAgICAgIH07CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLnBhZC5Jc285Nzk3MTsKICAgICAgfSk7CiAgICB9KShwYWRJc285Nzk3MSQxKTsKICAgIHJldHVybiBwYWRJc285Nzk3MSQxLmV4cG9ydHM7CiAgfQoKICB2YXIgcGFkWmVyb3BhZGRpbmckMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBwYWRaZXJvcGFkZGluZyA9IHBhZFplcm9wYWRkaW5nJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRQYWRaZXJvcGFkZGluZzsKICBmdW5jdGlvbiByZXF1aXJlUGFkWmVyb3BhZGRpbmcoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRQYWRaZXJvcGFkZGluZykgcmV0dXJuIHBhZFplcm9wYWRkaW5nJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUGFkWmVyb3BhZGRpbmcgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHBhZFplcm9wYWRkaW5nLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAvKioKICAgICAgICAgKiBaZXJvIHBhZGRpbmcgc3RyYXRlZ3kuCiAgICAgICAgICovCiAgICAgICAgQ3J5cHRvSlMucGFkLlplcm9QYWRkaW5nID0gewogICAgICAgICAgcGFkOiBmdW5jdGlvbiAoZGF0YSwgYmxvY2tTaXplKSB7CiAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgIHZhciBibG9ja1NpemVCeXRlcyA9IGJsb2NrU2l6ZSAqIDQ7CgogICAgICAgICAgICAvLyBQYWQKICAgICAgICAgICAgZGF0YS5jbGFtcCgpOwogICAgICAgICAgICBkYXRhLnNpZ0J5dGVzICs9IGJsb2NrU2l6ZUJ5dGVzIC0gKGRhdGEuc2lnQnl0ZXMgJSBibG9ja1NpemVCeXRlcyB8fCBibG9ja1NpemVCeXRlcyk7CiAgICAgICAgICB9LAogICAgICAgICAgdW5wYWQ6IGZ1bmN0aW9uIChkYXRhKSB7CiAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgIHZhciBkYXRhV29yZHMgPSBkYXRhLndvcmRzOwoKICAgICAgICAgICAgLy8gVW5wYWQKICAgICAgICAgICAgdmFyIGkgPSBkYXRhLnNpZ0J5dGVzIC0gMTsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IGRhdGEuc2lnQnl0ZXMgLSAxOyBpID49IDA7IGktLSkgewogICAgICAgICAgICAgIGlmIChkYXRhV29yZHNbaSA+Pj4gMl0gPj4+IDI0IC0gaSAlIDQgKiA4ICYgMHhmZikgewogICAgICAgICAgICAgICAgZGF0YS5zaWdCeXRlcyA9IGkgKyAxOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMucGFkLlplcm9QYWRkaW5nOwogICAgICB9KTsKICAgIH0pKHBhZFplcm9wYWRkaW5nJDEpOwogICAgcmV0dXJuIHBhZFplcm9wYWRkaW5nJDEuZXhwb3J0czsKICB9CgogIHZhciBwYWROb3BhZGRpbmckMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBwYWROb3BhZGRpbmcgPSBwYWROb3BhZGRpbmckMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFBhZE5vcGFkZGluZzsKICBmdW5jdGlvbiByZXF1aXJlUGFkTm9wYWRkaW5nKCkgewogICAgaWYgKGhhc1JlcXVpcmVkUGFkTm9wYWRkaW5nKSByZXR1cm4gcGFkTm9wYWRkaW5nJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUGFkTm9wYWRkaW5nID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShwYWROb3BhZGRpbmcsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIC8qKgogICAgICAgICAqIEEgbm9vcCBwYWRkaW5nIHN0cmF0ZWd5LgogICAgICAgICAqLwogICAgICAgIENyeXB0b0pTLnBhZC5Ob1BhZGRpbmcgPSB7CiAgICAgICAgICBwYWQ6IGZ1bmN0aW9uICgpIHt9LAogICAgICAgICAgdW5wYWQ6IGZ1bmN0aW9uICgpIHt9CiAgICAgICAgfTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMucGFkLk5vUGFkZGluZzsKICAgICAgfSk7CiAgICB9KShwYWROb3BhZGRpbmckMSk7CiAgICByZXR1cm4gcGFkTm9wYWRkaW5nJDEuZXhwb3J0czsKICB9CgogIHZhciBmb3JtYXRIZXgkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBmb3JtYXRIZXggPSBmb3JtYXRIZXgkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZEZvcm1hdEhleDsKICBmdW5jdGlvbiByZXF1aXJlRm9ybWF0SGV4KCkgewogICAgaWYgKGhhc1JlcXVpcmVkRm9ybWF0SGV4KSByZXR1cm4gZm9ybWF0SGV4JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkRm9ybWF0SGV4ID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShmb3JtYXRIZXgsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAodW5kZWZpbmVkJDEpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIENpcGhlclBhcmFtcyA9IENfbGliLkNpcGhlclBhcmFtczsKICAgICAgICAgIHZhciBDX2VuYyA9IEMuZW5jOwogICAgICAgICAgdmFyIEhleCA9IENfZW5jLkhleDsKICAgICAgICAgIHZhciBDX2Zvcm1hdCA9IEMuZm9ybWF0OwogICAgICAgICAgQ19mb3JtYXQuSGV4ID0gewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgdGhlIGNpcGhlcnRleHQgb2YgYSBjaXBoZXIgcGFyYW1zIG9iamVjdCB0byBhIGhleGFkZWNpbWFsbHkgZW5jb2RlZCBzdHJpbmcuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBwYXJhbSB7Q2lwaGVyUGFyYW1zfSBjaXBoZXJQYXJhbXMgVGhlIGNpcGhlciBwYXJhbXMgb2JqZWN0LgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBoZXhhZGVjaW1hbGx5IGVuY29kZWQgc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAc3RhdGljCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqICAgICB2YXIgaGV4U3RyaW5nID0gQ3J5cHRvSlMuZm9ybWF0LkhleC5zdHJpbmdpZnkoY2lwaGVyUGFyYW1zKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHN0cmluZ2lmeTogZnVuY3Rpb24gKGNpcGhlclBhcmFtcykgewogICAgICAgICAgICAgIHJldHVybiBjaXBoZXJQYXJhbXMuY2lwaGVydGV4dC50b1N0cmluZyhIZXgpOwogICAgICAgICAgICB9LAogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29udmVydHMgYSBoZXhhZGVjaW1hbGx5IGVuY29kZWQgY2lwaGVydGV4dCBzdHJpbmcgdG8gYSBjaXBoZXIgcGFyYW1zIG9iamVjdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IGlucHV0IFRoZSBoZXhhZGVjaW1hbGx5IGVuY29kZWQgc3RyaW5nLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcmV0dXJuIHtDaXBoZXJQYXJhbXN9IFRoZSBjaXBoZXIgcGFyYW1zIG9iamVjdC4KICAgICAgICAgICAgICoKICAgICAgICAgICAgICogQHN0YXRpYwogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlclBhcmFtcyA9IENyeXB0b0pTLmZvcm1hdC5IZXgucGFyc2UoaGV4U3RyaW5nKTsKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHBhcnNlOiBmdW5jdGlvbiAoaW5wdXQpIHsKICAgICAgICAgICAgICB2YXIgY2lwaGVydGV4dCA9IEhleC5wYXJzZShpbnB1dCk7CiAgICAgICAgICAgICAgcmV0dXJuIENpcGhlclBhcmFtcy5jcmVhdGUoewogICAgICAgICAgICAgICAgY2lwaGVydGV4dDogY2lwaGVydGV4dAogICAgICAgICAgICAgIH0pOwogICAgICAgICAgICB9CiAgICAgICAgICB9OwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLmZvcm1hdC5IZXg7CiAgICAgIH0pOwogICAgfSkoZm9ybWF0SGV4JDEpOwogICAgcmV0dXJuIGZvcm1hdEhleCQxLmV4cG9ydHM7CiAgfQoKICB2YXIgYWVzJDEgPSB7ZXhwb3J0czoge319OwoKICB2YXIgYWVzID0gYWVzJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRBZXM7CiAgZnVuY3Rpb24gcmVxdWlyZUFlcygpIHsKICAgIGlmIChoYXNSZXF1aXJlZEFlcykgcmV0dXJuIGFlcyQxLmV4cG9ydHM7CiAgICBoYXNSZXF1aXJlZEFlcyA9IDE7CiAgICAoZnVuY3Rpb24gKG1vZHVsZSwgZXhwb3J0cyQxKSB7CiAgICAgIChmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHsKICAgICAgICB7CiAgICAgICAgICAvLyBDb21tb25KUwogICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmVDb3JlKCksIHJlcXVpcmVFbmNCYXNlNjQoKSwgcmVxdWlyZU1kNSgpLCByZXF1aXJlRXZwa2RmKCksIHJlcXVpcmVDaXBoZXJDb3JlKCkpOwogICAgICAgIH0KICAgICAgfSkoYWVzLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICB2YXIgQyA9IENyeXB0b0pTOwogICAgICAgICAgdmFyIENfbGliID0gQy5saWI7CiAgICAgICAgICB2YXIgQmxvY2tDaXBoZXIgPSBDX2xpYi5CbG9ja0NpcGhlcjsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CgogICAgICAgICAgLy8gTG9va3VwIHRhYmxlcwogICAgICAgICAgdmFyIFNCT1ggPSBbXTsKICAgICAgICAgIHZhciBJTlZfU0JPWCA9IFtdOwogICAgICAgICAgdmFyIFNVQl9NSVhfMCA9IFtdOwogICAgICAgICAgdmFyIFNVQl9NSVhfMSA9IFtdOwogICAgICAgICAgdmFyIFNVQl9NSVhfMiA9IFtdOwogICAgICAgICAgdmFyIFNVQl9NSVhfMyA9IFtdOwogICAgICAgICAgdmFyIElOVl9TVUJfTUlYXzAgPSBbXTsKICAgICAgICAgIHZhciBJTlZfU1VCX01JWF8xID0gW107CiAgICAgICAgICB2YXIgSU5WX1NVQl9NSVhfMiA9IFtdOwogICAgICAgICAgdmFyIElOVl9TVUJfTUlYXzMgPSBbXTsKCiAgICAgICAgICAvLyBDb21wdXRlIGxvb2t1cCB0YWJsZXMKICAgICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgIC8vIENvbXB1dGUgZG91YmxlIHRhYmxlCiAgICAgICAgICAgIHZhciBkID0gW107CiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKICAgICAgICAgICAgICBpZiAoaSA8IDEyOCkgewogICAgICAgICAgICAgICAgZFtpXSA9IGkgPDwgMTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZFtpXSA9IGkgPDwgMSBeIDB4MTFiOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gV2FsayBHRigyXjgpCiAgICAgICAgICAgIHZhciB4ID0gMDsKICAgICAgICAgICAgdmFyIHhpID0gMDsKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICAgIC8vIENvbXB1dGUgc2JveAogICAgICAgICAgICAgIHZhciBzeCA9IHhpIF4geGkgPDwgMSBeIHhpIDw8IDIgXiB4aSA8PCAzIF4geGkgPDwgNDsKICAgICAgICAgICAgICBzeCA9IHN4ID4+PiA4IF4gc3ggJiAweGZmIF4gMHg2MzsKICAgICAgICAgICAgICBTQk9YW3hdID0gc3g7CiAgICAgICAgICAgICAgSU5WX1NCT1hbc3hdID0geDsKCiAgICAgICAgICAgICAgLy8gQ29tcHV0ZSBtdWx0aXBsaWNhdGlvbgogICAgICAgICAgICAgIHZhciB4MiA9IGRbeF07CiAgICAgICAgICAgICAgdmFyIHg0ID0gZFt4Ml07CiAgICAgICAgICAgICAgdmFyIHg4ID0gZFt4NF07CgogICAgICAgICAgICAgIC8vIENvbXB1dGUgc3ViIGJ5dGVzLCBtaXggY29sdW1ucyB0YWJsZXMKICAgICAgICAgICAgICB2YXIgdCA9IGRbc3hdICogMHgxMDEgXiBzeCAqIDB4MTAxMDEwMDsKICAgICAgICAgICAgICBTVUJfTUlYXzBbeF0gPSB0IDw8IDI0IHwgdCA+Pj4gODsKICAgICAgICAgICAgICBTVUJfTUlYXzFbeF0gPSB0IDw8IDE2IHwgdCA+Pj4gMTY7CiAgICAgICAgICAgICAgU1VCX01JWF8yW3hdID0gdCA8PCA4IHwgdCA+Pj4gMjQ7CiAgICAgICAgICAgICAgU1VCX01JWF8zW3hdID0gdDsKCiAgICAgICAgICAgICAgLy8gQ29tcHV0ZSBpbnYgc3ViIGJ5dGVzLCBpbnYgbWl4IGNvbHVtbnMgdGFibGVzCiAgICAgICAgICAgICAgdmFyIHQgPSB4OCAqIDB4MTAxMDEwMSBeIHg0ICogMHgxMDAwMSBeIHgyICogMHgxMDEgXiB4ICogMHgxMDEwMTAwOwogICAgICAgICAgICAgIElOVl9TVUJfTUlYXzBbc3hdID0gdCA8PCAyNCB8IHQgPj4+IDg7CiAgICAgICAgICAgICAgSU5WX1NVQl9NSVhfMVtzeF0gPSB0IDw8IDE2IHwgdCA+Pj4gMTY7CiAgICAgICAgICAgICAgSU5WX1NVQl9NSVhfMltzeF0gPSB0IDw8IDggfCB0ID4+PiAyNDsKICAgICAgICAgICAgICBJTlZfU1VCX01JWF8zW3N4XSA9IHQ7CgogICAgICAgICAgICAgIC8vIENvbXB1dGUgbmV4dCBjb3VudGVyCiAgICAgICAgICAgICAgaWYgKCF4KSB7CiAgICAgICAgICAgICAgICB4ID0geGkgPSAxOwogICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB4ID0geDIgXiBkW2RbZFt4OCBeIHgyXV1dOwogICAgICAgICAgICAgICAgeGkgXj0gZFtkW3hpXV07CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9KSgpOwoKICAgICAgICAgIC8vIFByZWNvbXB1dGVkIFJjb24gbG9va3VwCiAgICAgICAgICB2YXIgUkNPTiA9IFsweDAwLCAweDAxLCAweDAyLCAweDA0LCAweDA4LCAweDEwLCAweDIwLCAweDQwLCAweDgwLCAweDFiLCAweDM2XTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIEFFUyBibG9jayBjaXBoZXIgYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgQUVTID0gQ19hbGdvLkFFUyA9IEJsb2NrQ2lwaGVyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgdmFyIHQ7CgogICAgICAgICAgICAgIC8vIFNraXAgcmVzZXQgb2YgblJvdW5kcyBoYXMgYmVlbiBzZXQgYmVmb3JlIGFuZCBrZXkgZGlkIG5vdCBjaGFuZ2UKICAgICAgICAgICAgICBpZiAodGhpcy5fblJvdW5kcyAmJiB0aGlzLl9rZXlQcmlvclJlc2V0ID09PSB0aGlzLl9rZXkpIHsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBrZXkgPSB0aGlzLl9rZXlQcmlvclJlc2V0ID0gdGhpcy5fa2V5OwogICAgICAgICAgICAgIHZhciBrZXlXb3JkcyA9IGtleS53b3JkczsKICAgICAgICAgICAgICB2YXIga2V5U2l6ZSA9IGtleS5zaWdCeXRlcyAvIDQ7CgogICAgICAgICAgICAgIC8vIENvbXB1dGUgbnVtYmVyIG9mIHJvdW5kcwogICAgICAgICAgICAgIHZhciBuUm91bmRzID0gdGhpcy5fblJvdW5kcyA9IGtleVNpemUgKyA2OwoKICAgICAgICAgICAgICAvLyBDb21wdXRlIG51bWJlciBvZiBrZXkgc2NoZWR1bGUgcm93cwogICAgICAgICAgICAgIHZhciBrc1Jvd3MgPSAoblJvdW5kcyArIDEpICogNDsKCiAgICAgICAgICAgICAgLy8gQ29tcHV0ZSBrZXkgc2NoZWR1bGUKICAgICAgICAgICAgICB2YXIga2V5U2NoZWR1bGUgPSB0aGlzLl9rZXlTY2hlZHVsZSA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGtzUm93ID0gMDsga3NSb3cgPCBrc1Jvd3M7IGtzUm93KyspIHsKICAgICAgICAgICAgICAgIGlmIChrc1JvdyA8IGtleVNpemUpIHsKICAgICAgICAgICAgICAgICAga2V5U2NoZWR1bGVba3NSb3ddID0ga2V5V29yZHNba3NSb3ddOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgdCA9IGtleVNjaGVkdWxlW2tzUm93IC0gMV07CiAgICAgICAgICAgICAgICAgIGlmICghKGtzUm93ICUga2V5U2l6ZSkpIHsKICAgICAgICAgICAgICAgICAgICAvLyBSb3Qgd29yZAogICAgICAgICAgICAgICAgICAgIHQgPSB0IDw8IDggfCB0ID4+PiAyNDsKCiAgICAgICAgICAgICAgICAgICAgLy8gU3ViIHdvcmQKICAgICAgICAgICAgICAgICAgICB0ID0gU0JPWFt0ID4+PiAyNF0gPDwgMjQgfCBTQk9YW3QgPj4+IDE2ICYgMHhmZl0gPDwgMTYgfCBTQk9YW3QgPj4+IDggJiAweGZmXSA8PCA4IHwgU0JPWFt0ICYgMHhmZl07CgogICAgICAgICAgICAgICAgICAgIC8vIE1peCBSY29uCiAgICAgICAgICAgICAgICAgICAgdCBePSBSQ09OW2tzUm93IC8ga2V5U2l6ZSB8IDBdIDw8IDI0OwogICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGtleVNpemUgPiA2ICYmIGtzUm93ICUga2V5U2l6ZSA9PSA0KSB7CiAgICAgICAgICAgICAgICAgICAgLy8gU3ViIHdvcmQKICAgICAgICAgICAgICAgICAgICB0ID0gU0JPWFt0ID4+PiAyNF0gPDwgMjQgfCBTQk9YW3QgPj4+IDE2ICYgMHhmZl0gPDwgMTYgfCBTQk9YW3QgPj4+IDggJiAweGZmXSA8PCA4IHwgU0JPWFt0ICYgMHhmZl07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAga2V5U2NoZWR1bGVba3NSb3ddID0ga2V5U2NoZWR1bGVba3NSb3cgLSBrZXlTaXplXSBeIHQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBDb21wdXRlIGludiBrZXkgc2NoZWR1bGUKICAgICAgICAgICAgICB2YXIgaW52S2V5U2NoZWR1bGUgPSB0aGlzLl9pbnZLZXlTY2hlZHVsZSA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGludktzUm93ID0gMDsgaW52S3NSb3cgPCBrc1Jvd3M7IGludktzUm93KyspIHsKICAgICAgICAgICAgICAgIHZhciBrc1JvdyA9IGtzUm93cyAtIGludktzUm93OwogICAgICAgICAgICAgICAgaWYgKGludktzUm93ICUgNCkgewogICAgICAgICAgICAgICAgICB2YXIgdCA9IGtleVNjaGVkdWxlW2tzUm93XTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgIHZhciB0ID0ga2V5U2NoZWR1bGVba3NSb3cgLSA0XTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChpbnZLc1JvdyA8IDQgfHwga3NSb3cgPD0gNCkgewogICAgICAgICAgICAgICAgICBpbnZLZXlTY2hlZHVsZVtpbnZLc1Jvd10gPSB0OwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgaW52S2V5U2NoZWR1bGVbaW52S3NSb3ddID0gSU5WX1NVQl9NSVhfMFtTQk9YW3QgPj4+IDI0XV0gXiBJTlZfU1VCX01JWF8xW1NCT1hbdCA+Pj4gMTYgJiAweGZmXV0gXiBJTlZfU1VCX01JWF8yW1NCT1hbdCA+Pj4gOCAmIDB4ZmZdXSBeIElOVl9TVUJfTUlYXzNbU0JPWFt0ICYgMHhmZl1dOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgZW5jcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgdGhpcy5fZG9DcnlwdEJsb2NrKE0sIG9mZnNldCwgdGhpcy5fa2V5U2NoZWR1bGUsIFNVQl9NSVhfMCwgU1VCX01JWF8xLCBTVUJfTUlYXzIsIFNVQl9NSVhfMywgU0JPWCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGRlY3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkgewogICAgICAgICAgICAgIC8vIFN3YXAgMm5kIGFuZCA0dGggcm93cwogICAgICAgICAgICAgIHZhciB0ID0gTVtvZmZzZXQgKyAxXTsKICAgICAgICAgICAgICBNW29mZnNldCArIDFdID0gTVtvZmZzZXQgKyAzXTsKICAgICAgICAgICAgICBNW29mZnNldCArIDNdID0gdDsKICAgICAgICAgICAgICB0aGlzLl9kb0NyeXB0QmxvY2soTSwgb2Zmc2V0LCB0aGlzLl9pbnZLZXlTY2hlZHVsZSwgSU5WX1NVQl9NSVhfMCwgSU5WX1NVQl9NSVhfMSwgSU5WX1NVQl9NSVhfMiwgSU5WX1NVQl9NSVhfMywgSU5WX1NCT1gpOwoKICAgICAgICAgICAgICAvLyBJbnYgc3dhcCAybmQgYW5kIDR0aCByb3dzCiAgICAgICAgICAgICAgdmFyIHQgPSBNW29mZnNldCArIDFdOwogICAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSBNW29mZnNldCArIDNdOwogICAgICAgICAgICAgIE1bb2Zmc2V0ICsgM10gPSB0OwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9DcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0LCBrZXlTY2hlZHVsZSwgU1VCX01JWF8wLCBTVUJfTUlYXzEsIFNVQl9NSVhfMiwgU1VCX01JWF8zLCBTQk9YKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgblJvdW5kcyA9IHRoaXMuX25Sb3VuZHM7CgogICAgICAgICAgICAgIC8vIEdldCBpbnB1dCwgYWRkIHJvdW5kIGtleQogICAgICAgICAgICAgIHZhciBzMCA9IE1bb2Zmc2V0XSBeIGtleVNjaGVkdWxlWzBdOwogICAgICAgICAgICAgIHZhciBzMSA9IE1bb2Zmc2V0ICsgMV0gXiBrZXlTY2hlZHVsZVsxXTsKICAgICAgICAgICAgICB2YXIgczIgPSBNW29mZnNldCArIDJdIF4ga2V5U2NoZWR1bGVbMl07CiAgICAgICAgICAgICAgdmFyIHMzID0gTVtvZmZzZXQgKyAzXSBeIGtleVNjaGVkdWxlWzNdOwoKICAgICAgICAgICAgICAvLyBLZXkgc2NoZWR1bGUgcm93IGNvdW50ZXIKICAgICAgICAgICAgICB2YXIga3NSb3cgPSA0OwoKICAgICAgICAgICAgICAvLyBSb3VuZHMKICAgICAgICAgICAgICBmb3IgKHZhciByb3VuZCA9IDE7IHJvdW5kIDwgblJvdW5kczsgcm91bmQrKykgewogICAgICAgICAgICAgICAgLy8gU2hpZnQgcm93cywgc3ViIGJ5dGVzLCBtaXggY29sdW1ucywgYWRkIHJvdW5kIGtleQogICAgICAgICAgICAgICAgdmFyIHQwID0gU1VCX01JWF8wW3MwID4+PiAyNF0gXiBTVUJfTUlYXzFbczEgPj4+IDE2ICYgMHhmZl0gXiBTVUJfTUlYXzJbczIgPj4+IDggJiAweGZmXSBeIFNVQl9NSVhfM1tzMyAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107CiAgICAgICAgICAgICAgICB2YXIgdDEgPSBTVUJfTUlYXzBbczEgPj4+IDI0XSBeIFNVQl9NSVhfMVtzMiA+Pj4gMTYgJiAweGZmXSBeIFNVQl9NSVhfMltzMyA+Pj4gOCAmIDB4ZmZdIF4gU1VCX01JWF8zW3MwICYgMHhmZl0gXiBrZXlTY2hlZHVsZVtrc1JvdysrXTsKICAgICAgICAgICAgICAgIHZhciB0MiA9IFNVQl9NSVhfMFtzMiA+Pj4gMjRdIF4gU1VCX01JWF8xW3MzID4+PiAxNiAmIDB4ZmZdIF4gU1VCX01JWF8yW3MwID4+PiA4ICYgMHhmZl0gXiBTVUJfTUlYXzNbczEgJiAweGZmXSBeIGtleVNjaGVkdWxlW2tzUm93KytdOwogICAgICAgICAgICAgICAgdmFyIHQzID0gU1VCX01JWF8wW3MzID4+PiAyNF0gXiBTVUJfTUlYXzFbczAgPj4+IDE2ICYgMHhmZl0gXiBTVUJfTUlYXzJbczEgPj4+IDggJiAweGZmXSBeIFNVQl9NSVhfM1tzMiAmIDB4ZmZdIF4ga2V5U2NoZWR1bGVba3NSb3crK107CgogICAgICAgICAgICAgICAgLy8gVXBkYXRlIHN0YXRlCiAgICAgICAgICAgICAgICBzMCA9IHQwOwogICAgICAgICAgICAgICAgczEgPSB0MTsKICAgICAgICAgICAgICAgIHMyID0gdDI7CiAgICAgICAgICAgICAgICBzMyA9IHQzOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gU2hpZnQgcm93cywgc3ViIGJ5dGVzLCBhZGQgcm91bmQga2V5CiAgICAgICAgICAgICAgdmFyIHQwID0gKFNCT1hbczAgPj4+IDI0XSA8PCAyNCB8IFNCT1hbczEgPj4+IDE2ICYgMHhmZl0gPDwgMTYgfCBTQk9YW3MyID4+PiA4ICYgMHhmZl0gPDwgOCB8IFNCT1hbczMgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTsKICAgICAgICAgICAgICB2YXIgdDEgPSAoU0JPWFtzMSA+Pj4gMjRdIDw8IDI0IHwgU0JPWFtzMiA+Pj4gMTYgJiAweGZmXSA8PCAxNiB8IFNCT1hbczMgPj4+IDggJiAweGZmXSA8PCA4IHwgU0JPWFtzMCAmIDB4ZmZdKSBeIGtleVNjaGVkdWxlW2tzUm93KytdOwogICAgICAgICAgICAgIHZhciB0MiA9IChTQk9YW3MyID4+PiAyNF0gPDwgMjQgfCBTQk9YW3MzID4+PiAxNiAmIDB4ZmZdIDw8IDE2IHwgU0JPWFtzMCA+Pj4gOCAmIDB4ZmZdIDw8IDggfCBTQk9YW3MxICYgMHhmZl0pIF4ga2V5U2NoZWR1bGVba3NSb3crK107CiAgICAgICAgICAgICAgdmFyIHQzID0gKFNCT1hbczMgPj4+IDI0XSA8PCAyNCB8IFNCT1hbczAgPj4+IDE2ICYgMHhmZl0gPDwgMTYgfCBTQk9YW3MxID4+PiA4ICYgMHhmZl0gPDwgOCB8IFNCT1hbczIgJiAweGZmXSkgXiBrZXlTY2hlZHVsZVtrc1JvdysrXTsKCiAgICAgICAgICAgICAgLy8gU2V0IG91dHB1dAogICAgICAgICAgICAgIE1bb2Zmc2V0XSA9IHQwOwogICAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSB0MTsKICAgICAgICAgICAgICBNW29mZnNldCArIDJdID0gdDI7CiAgICAgICAgICAgICAgTVtvZmZzZXQgKyAzXSA9IHQzOwogICAgICAgICAgICB9LAogICAgICAgICAgICBrZXlTaXplOiAyNTYgLyAzMgogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5BRVMuZW5jcnlwdChtZXNzYWdlLCBrZXksIGNmZyk7CiAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCAgPSBDcnlwdG9KUy5BRVMuZGVjcnlwdChjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuQUVTID0gQmxvY2tDaXBoZXIuX2NyZWF0ZUhlbHBlcihBRVMpOwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLkFFUzsKICAgICAgfSk7CiAgICB9KShhZXMkMSk7CiAgICByZXR1cm4gYWVzJDEuZXhwb3J0czsKICB9CgogIHZhciB0cmlwbGVkZXMkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciB0cmlwbGVkZXMgPSB0cmlwbGVkZXMkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFRyaXBsZWRlczsKICBmdW5jdGlvbiByZXF1aXJlVHJpcGxlZGVzKCkgewogICAgaWYgKGhhc1JlcXVpcmVkVHJpcGxlZGVzKSByZXR1cm4gdHJpcGxlZGVzJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkVHJpcGxlZGVzID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUVuY0Jhc2U2NCgpLCByZXF1aXJlTWQ1KCksIHJlcXVpcmVFdnBrZGYoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KSh0cmlwbGVkZXMsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBXb3JkQXJyYXkgPSBDX2xpYi5Xb3JkQXJyYXk7CiAgICAgICAgICB2YXIgQmxvY2tDaXBoZXIgPSBDX2xpYi5CbG9ja0NpcGhlcjsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CgogICAgICAgICAgLy8gUGVybXV0ZWQgQ2hvaWNlIDEgY29uc3RhbnRzCiAgICAgICAgICB2YXIgUEMxID0gWzU3LCA0OSwgNDEsIDMzLCAyNSwgMTcsIDksIDEsIDU4LCA1MCwgNDIsIDM0LCAyNiwgMTgsIDEwLCAyLCA1OSwgNTEsIDQzLCAzNSwgMjcsIDE5LCAxMSwgMywgNjAsIDUyLCA0NCwgMzYsIDYzLCA1NSwgNDcsIDM5LCAzMSwgMjMsIDE1LCA3LCA2MiwgNTQsIDQ2LCAzOCwgMzAsIDIyLCAxNCwgNiwgNjEsIDUzLCA0NSwgMzcsIDI5LCAyMSwgMTMsIDUsIDI4LCAyMCwgMTIsIDRdOwoKICAgICAgICAgIC8vIFBlcm11dGVkIENob2ljZSAyIGNvbnN0YW50cwogICAgICAgICAgdmFyIFBDMiA9IFsxNCwgMTcsIDExLCAyNCwgMSwgNSwgMywgMjgsIDE1LCA2LCAyMSwgMTAsIDIzLCAxOSwgMTIsIDQsIDI2LCA4LCAxNiwgNywgMjcsIDIwLCAxMywgMiwgNDEsIDUyLCAzMSwgMzcsIDQ3LCA1NSwgMzAsIDQwLCA1MSwgNDUsIDMzLCA0OCwgNDQsIDQ5LCAzOSwgNTYsIDM0LCA1MywgNDYsIDQyLCA1MCwgMzYsIDI5LCAzMl07CgogICAgICAgICAgLy8gQ3VtdWxhdGl2ZSBiaXQgc2hpZnQgY29uc3RhbnRzCiAgICAgICAgICB2YXIgQklUX1NISUZUUyA9IFsxLCAyLCA0LCA2LCA4LCAxMCwgMTIsIDE0LCAxNSwgMTcsIDE5LCAyMSwgMjMsIDI1LCAyNywgMjhdOwoKICAgICAgICAgIC8vIFNCT1hlcyBhbmQgcm91bmQgcGVybXV0YXRpb24gY29uc3RhbnRzCiAgICAgICAgICB2YXIgU0JPWF9QID0gW3sKICAgICAgICAgICAgMHgwOiAweDgwODIwMCwKICAgICAgICAgICAgMHgxMDAwMDAwMDogMHg4MDAwLAogICAgICAgICAgICAweDIwMDAwMDAwOiAweDgwODAwMiwKICAgICAgICAgICAgMHgzMDAwMDAwMDogMHgyLAogICAgICAgICAgICAweDQwMDAwMDAwOiAweDIwMCwKICAgICAgICAgICAgMHg1MDAwMDAwMDogMHg4MDgyMDIsCiAgICAgICAgICAgIDB4NjAwMDAwMDA6IDB4ODAwMjAyLAogICAgICAgICAgICAweDcwMDAwMDAwOiAweDgwMDAwMCwKICAgICAgICAgICAgMHg4MDAwMDAwMDogMHgyMDIsCiAgICAgICAgICAgIDB4OTAwMDAwMDA6IDB4ODAwMjAwLAogICAgICAgICAgICAweGEwMDAwMDAwOiAweDgyMDAsCiAgICAgICAgICAgIDB4YjAwMDAwMDA6IDB4ODA4MDAwLAogICAgICAgICAgICAweGMwMDAwMDAwOiAweDgwMDIsCiAgICAgICAgICAgIDB4ZDAwMDAwMDA6IDB4ODAwMDAyLAogICAgICAgICAgICAweGUwMDAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4ZjAwMDAwMDA6IDB4ODIwMiwKICAgICAgICAgICAgMHg4MDAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4MTgwMDAwMDA6IDB4ODA4MjAyLAogICAgICAgICAgICAweDI4MDAwMDAwOiAweDgyMDIsCiAgICAgICAgICAgIDB4MzgwMDAwMDA6IDB4ODAwMCwKICAgICAgICAgICAgMHg0ODAwMDAwMDogMHg4MDgyMDAsCiAgICAgICAgICAgIDB4NTgwMDAwMDA6IDB4MjAwLAogICAgICAgICAgICAweDY4MDAwMDAwOiAweDgwODAwMiwKICAgICAgICAgICAgMHg3ODAwMDAwMDogMHgyLAogICAgICAgICAgICAweDg4MDAwMDAwOiAweDgwMDIwMCwKICAgICAgICAgICAgMHg5ODAwMDAwMDogMHg4MjAwLAogICAgICAgICAgICAweGE4MDAwMDAwOiAweDgwODAwMCwKICAgICAgICAgICAgMHhiODAwMDAwMDogMHg4MDAyMDIsCiAgICAgICAgICAgIDB4YzgwMDAwMDA6IDB4ODAwMDAyLAogICAgICAgICAgICAweGQ4MDAwMDAwOiAweDgwMDIsCiAgICAgICAgICAgIDB4ZTgwMDAwMDA6IDB4MjAyLAogICAgICAgICAgICAweGY4MDAwMDAwOiAweDgwMDAwMCwKICAgICAgICAgICAgMHgxOiAweDgwMDAsCiAgICAgICAgICAgIDB4MTAwMDAwMDE6IDB4MiwKICAgICAgICAgICAgMHgyMDAwMDAwMTogMHg4MDgyMDAsCiAgICAgICAgICAgIDB4MzAwMDAwMDE6IDB4ODAwMDAwLAogICAgICAgICAgICAweDQwMDAwMDAxOiAweDgwODAwMiwKICAgICAgICAgICAgMHg1MDAwMDAwMTogMHg4MjAwLAogICAgICAgICAgICAweDYwMDAwMDAxOiAweDIwMCwKICAgICAgICAgICAgMHg3MDAwMDAwMTogMHg4MDAyMDIsCiAgICAgICAgICAgIDB4ODAwMDAwMDE6IDB4ODA4MjAyLAogICAgICAgICAgICAweDkwMDAwMDAxOiAweDgwODAwMCwKICAgICAgICAgICAgMHhhMDAwMDAwMTogMHg4MDAwMDIsCiAgICAgICAgICAgIDB4YjAwMDAwMDE6IDB4ODIwMiwKICAgICAgICAgICAgMHhjMDAwMDAwMTogMHgyMDIsCiAgICAgICAgICAgIDB4ZDAwMDAwMDE6IDB4ODAwMjAwLAogICAgICAgICAgICAweGUwMDAwMDAxOiAweDgwMDIsCiAgICAgICAgICAgIDB4ZjAwMDAwMDE6IDB4MCwKICAgICAgICAgICAgMHg4MDAwMDAxOiAweDgwODIwMiwKICAgICAgICAgICAgMHgxODAwMDAwMTogMHg4MDgwMDAsCiAgICAgICAgICAgIDB4MjgwMDAwMDE6IDB4ODAwMDAwLAogICAgICAgICAgICAweDM4MDAwMDAxOiAweDIwMCwKICAgICAgICAgICAgMHg0ODAwMDAwMTogMHg4MDAwLAogICAgICAgICAgICAweDU4MDAwMDAxOiAweDgwMDAwMiwKICAgICAgICAgICAgMHg2ODAwMDAwMTogMHgyLAogICAgICAgICAgICAweDc4MDAwMDAxOiAweDgyMDIsCiAgICAgICAgICAgIDB4ODgwMDAwMDE6IDB4ODAwMiwKICAgICAgICAgICAgMHg5ODAwMDAwMTogMHg4MDAyMDIsCiAgICAgICAgICAgIDB4YTgwMDAwMDE6IDB4MjAyLAogICAgICAgICAgICAweGI4MDAwMDAxOiAweDgwODIwMCwKICAgICAgICAgICAgMHhjODAwMDAwMTogMHg4MDAyMDAsCiAgICAgICAgICAgIDB4ZDgwMDAwMDE6IDB4MCwKICAgICAgICAgICAgMHhlODAwMDAwMTogMHg4MjAwLAogICAgICAgICAgICAweGY4MDAwMDAxOiAweDgwODAwMgogICAgICAgICAgfSwgewogICAgICAgICAgICAweDA6IDB4NDAwODQwMTAsCiAgICAgICAgICAgIDB4MTAwMDAwMDogMHg0MDAwLAogICAgICAgICAgICAweDIwMDAwMDA6IDB4ODAwMDAsCiAgICAgICAgICAgIDB4MzAwMDAwMDogMHg0MDA4MDAxMCwKICAgICAgICAgICAgMHg0MDAwMDAwOiAweDQwMDAwMDEwLAogICAgICAgICAgICAweDUwMDAwMDA6IDB4NDAwODQwMDAsCiAgICAgICAgICAgIDB4NjAwMDAwMDogMHg0MDAwNDAwMCwKICAgICAgICAgICAgMHg3MDAwMDAwOiAweDEwLAogICAgICAgICAgICAweDgwMDAwMDA6IDB4ODQwMDAsCiAgICAgICAgICAgIDB4OTAwMDAwMDogMHg0MDAwNDAxMCwKICAgICAgICAgICAgMHhhMDAwMDAwOiAweDQwMDAwMDAwLAogICAgICAgICAgICAweGIwMDAwMDA6IDB4ODQwMTAsCiAgICAgICAgICAgIDB4YzAwMDAwMDogMHg4MDAxMCwKICAgICAgICAgICAgMHhkMDAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4ZTAwMDAwMDogMHg0MDEwLAogICAgICAgICAgICAweGYwMDAwMDA6IDB4NDAwODAwMDAsCiAgICAgICAgICAgIDB4ODAwMDAwOiAweDQwMDA0MDAwLAogICAgICAgICAgICAweDE4MDAwMDA6IDB4ODQwMTAsCiAgICAgICAgICAgIDB4MjgwMDAwMDogMHgxMCwKICAgICAgICAgICAgMHgzODAwMDAwOiAweDQwMDA0MDEwLAogICAgICAgICAgICAweDQ4MDAwMDA6IDB4NDAwODQwMTAsCiAgICAgICAgICAgIDB4NTgwMDAwMDogMHg0MDAwMDAwMCwKICAgICAgICAgICAgMHg2ODAwMDAwOiAweDgwMDAwLAogICAgICAgICAgICAweDc4MDAwMDA6IDB4NDAwODAwMTAsCiAgICAgICAgICAgIDB4ODgwMDAwMDogMHg4MDAxMCwKICAgICAgICAgICAgMHg5ODAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4YTgwMDAwMDogMHg0MDAwLAogICAgICAgICAgICAweGI4MDAwMDA6IDB4NDAwODAwMDAsCiAgICAgICAgICAgIDB4YzgwMDAwMDogMHg0MDAwMDAxMCwKICAgICAgICAgICAgMHhkODAwMDAwOiAweDg0MDAwLAogICAgICAgICAgICAweGU4MDAwMDA6IDB4NDAwODQwMDAsCiAgICAgICAgICAgIDB4ZjgwMDAwMDogMHg0MDEwLAogICAgICAgICAgICAweDEwMDAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4MTEwMDAwMDA6IDB4NDAwODAwMTAsCiAgICAgICAgICAgIDB4MTIwMDAwMDA6IDB4NDAwMDQwMTAsCiAgICAgICAgICAgIDB4MTMwMDAwMDA6IDB4NDAwODQwMDAsCiAgICAgICAgICAgIDB4MTQwMDAwMDA6IDB4NDAwODAwMDAsCiAgICAgICAgICAgIDB4MTUwMDAwMDA6IDB4MTAsCiAgICAgICAgICAgIDB4MTYwMDAwMDA6IDB4ODQwMTAsCiAgICAgICAgICAgIDB4MTcwMDAwMDA6IDB4NDAwMCwKICAgICAgICAgICAgMHgxODAwMDAwMDogMHg0MDEwLAogICAgICAgICAgICAweDE5MDAwMDAwOiAweDgwMDAwLAogICAgICAgICAgICAweDFhMDAwMDAwOiAweDgwMDEwLAogICAgICAgICAgICAweDFiMDAwMDAwOiAweDQwMDAwMDEwLAogICAgICAgICAgICAweDFjMDAwMDAwOiAweDg0MDAwLAogICAgICAgICAgICAweDFkMDAwMDAwOiAweDQwMDA0MDAwLAogICAgICAgICAgICAweDFlMDAwMDAwOiAweDQwMDAwMDAwLAogICAgICAgICAgICAweDFmMDAwMDAwOiAweDQwMDg0MDEwLAogICAgICAgICAgICAweDEwODAwMDAwOiAweDg0MDEwLAogICAgICAgICAgICAweDExODAwMDAwOiAweDgwMDAwLAogICAgICAgICAgICAweDEyODAwMDAwOiAweDQwMDgwMDAwLAogICAgICAgICAgICAweDEzODAwMDAwOiAweDQwMDAsCiAgICAgICAgICAgIDB4MTQ4MDAwMDA6IDB4NDAwMDQwMDAsCiAgICAgICAgICAgIDB4MTU4MDAwMDA6IDB4NDAwODQwMTAsCiAgICAgICAgICAgIDB4MTY4MDAwMDA6IDB4MTAsCiAgICAgICAgICAgIDB4MTc4MDAwMDA6IDB4NDAwMDAwMDAsCiAgICAgICAgICAgIDB4MTg4MDAwMDA6IDB4NDAwODQwMDAsCiAgICAgICAgICAgIDB4MTk4MDAwMDA6IDB4NDAwMDAwMTAsCiAgICAgICAgICAgIDB4MWE4MDAwMDA6IDB4NDAwMDQwMTAsCiAgICAgICAgICAgIDB4MWI4MDAwMDA6IDB4ODAwMTAsCiAgICAgICAgICAgIDB4MWM4MDAwMDA6IDB4MCwKICAgICAgICAgICAgMHgxZDgwMDAwMDogMHg0MDEwLAogICAgICAgICAgICAweDFlODAwMDAwOiAweDQwMDgwMDEwLAogICAgICAgICAgICAweDFmODAwMDAwOiAweDg0MDAwCiAgICAgICAgICB9LCB7CiAgICAgICAgICAgIDB4MDogMHgxMDQsCiAgICAgICAgICAgIDB4MTAwMDAwOiAweDAsCiAgICAgICAgICAgIDB4MjAwMDAwOiAweDQwMDAxMDAsCiAgICAgICAgICAgIDB4MzAwMDAwOiAweDEwMTA0LAogICAgICAgICAgICAweDQwMDAwMDogMHgxMDAwNCwKICAgICAgICAgICAgMHg1MDAwMDA6IDB4NDAwMDAwNCwKICAgICAgICAgICAgMHg2MDAwMDA6IDB4NDAxMDEwNCwKICAgICAgICAgICAgMHg3MDAwMDA6IDB4NDAxMDAwMCwKICAgICAgICAgICAgMHg4MDAwMDA6IDB4NDAwMDAwMCwKICAgICAgICAgICAgMHg5MDAwMDA6IDB4NDAxMDEwMCwKICAgICAgICAgICAgMHhhMDAwMDA6IDB4MTAxMDAsCiAgICAgICAgICAgIDB4YjAwMDAwOiAweDQwMTAwMDQsCiAgICAgICAgICAgIDB4YzAwMDAwOiAweDQwMDAxMDQsCiAgICAgICAgICAgIDB4ZDAwMDAwOiAweDEwMDAwLAogICAgICAgICAgICAweGUwMDAwMDogMHg0LAogICAgICAgICAgICAweGYwMDAwMDogMHgxMDAsCiAgICAgICAgICAgIDB4ODAwMDA6IDB4NDAxMDEwMCwKICAgICAgICAgICAgMHgxODAwMDA6IDB4NDAxMDAwNCwKICAgICAgICAgICAgMHgyODAwMDA6IDB4MCwKICAgICAgICAgICAgMHgzODAwMDA6IDB4NDAwMDEwMCwKICAgICAgICAgICAgMHg0ODAwMDA6IDB4NDAwMDAwNCwKICAgICAgICAgICAgMHg1ODAwMDA6IDB4MTAwMDAsCiAgICAgICAgICAgIDB4NjgwMDAwOiAweDEwMDA0LAogICAgICAgICAgICAweDc4MDAwMDogMHgxMDQsCiAgICAgICAgICAgIDB4ODgwMDAwOiAweDQsCiAgICAgICAgICAgIDB4OTgwMDAwOiAweDEwMCwKICAgICAgICAgICAgMHhhODAwMDA6IDB4NDAxMDAwMCwKICAgICAgICAgICAgMHhiODAwMDA6IDB4MTAxMDQsCiAgICAgICAgICAgIDB4YzgwMDAwOiAweDEwMTAwLAogICAgICAgICAgICAweGQ4MDAwMDogMHg0MDAwMTA0LAogICAgICAgICAgICAweGU4MDAwMDogMHg0MDEwMTA0LAogICAgICAgICAgICAweGY4MDAwMDogMHg0MDAwMDAwLAogICAgICAgICAgICAweDEwMDAwMDA6IDB4NDAxMDEwMCwKICAgICAgICAgICAgMHgxMTAwMDAwOiAweDEwMDA0LAogICAgICAgICAgICAweDEyMDAwMDA6IDB4MTAwMDAsCiAgICAgICAgICAgIDB4MTMwMDAwMDogMHg0MDAwMTAwLAogICAgICAgICAgICAweDE0MDAwMDA6IDB4MTAwLAogICAgICAgICAgICAweDE1MDAwMDA6IDB4NDAxMDEwNCwKICAgICAgICAgICAgMHgxNjAwMDAwOiAweDQwMDAwMDQsCiAgICAgICAgICAgIDB4MTcwMDAwMDogMHgwLAogICAgICAgICAgICAweDE4MDAwMDA6IDB4NDAwMDEwNCwKICAgICAgICAgICAgMHgxOTAwMDAwOiAweDQwMDAwMDAsCiAgICAgICAgICAgIDB4MWEwMDAwMDogMHg0LAogICAgICAgICAgICAweDFiMDAwMDA6IDB4MTAxMDAsCiAgICAgICAgICAgIDB4MWMwMDAwMDogMHg0MDEwMDAwLAogICAgICAgICAgICAweDFkMDAwMDA6IDB4MTA0LAogICAgICAgICAgICAweDFlMDAwMDA6IDB4MTAxMDQsCiAgICAgICAgICAgIDB4MWYwMDAwMDogMHg0MDEwMDA0LAogICAgICAgICAgICAweDEwODAwMDA6IDB4NDAwMDAwMCwKICAgICAgICAgICAgMHgxMTgwMDAwOiAweDEwNCwKICAgICAgICAgICAgMHgxMjgwMDAwOiAweDQwMTAxMDAsCiAgICAgICAgICAgIDB4MTM4MDAwMDogMHgwLAogICAgICAgICAgICAweDE0ODAwMDA6IDB4MTAwMDQsCiAgICAgICAgICAgIDB4MTU4MDAwMDogMHg0MDAwMTAwLAogICAgICAgICAgICAweDE2ODAwMDA6IDB4MTAwLAogICAgICAgICAgICAweDE3ODAwMDA6IDB4NDAxMDAwNCwKICAgICAgICAgICAgMHgxODgwMDAwOiAweDEwMDAwLAogICAgICAgICAgICAweDE5ODAwMDA6IDB4NDAxMDEwNCwKICAgICAgICAgICAgMHgxYTgwMDAwOiAweDEwMTA0LAogICAgICAgICAgICAweDFiODAwMDA6IDB4NDAwMDAwNCwKICAgICAgICAgICAgMHgxYzgwMDAwOiAweDQwMDAxMDQsCiAgICAgICAgICAgIDB4MWQ4MDAwMDogMHg0MDEwMDAwLAogICAgICAgICAgICAweDFlODAwMDA6IDB4NCwKICAgICAgICAgICAgMHgxZjgwMDAwOiAweDEwMTAwCiAgICAgICAgICB9LCB7CiAgICAgICAgICAgIDB4MDogMHg4MDQwMTAwMCwKICAgICAgICAgICAgMHgxMDAwMDogMHg4MDAwMTA0MCwKICAgICAgICAgICAgMHgyMDAwMDogMHg0MDEwNDAsCiAgICAgICAgICAgIDB4MzAwMDA6IDB4ODA0MDAwMDAsCiAgICAgICAgICAgIDB4NDAwMDA6IDB4MCwKICAgICAgICAgICAgMHg1MDAwMDogMHg0MDEwMDAsCiAgICAgICAgICAgIDB4NjAwMDA6IDB4ODAwMDAwNDAsCiAgICAgICAgICAgIDB4NzAwMDA6IDB4NDAwMDQwLAogICAgICAgICAgICAweDgwMDAwOiAweDgwMDAwMDAwLAogICAgICAgICAgICAweDkwMDAwOiAweDQwMDAwMCwKICAgICAgICAgICAgMHhhMDAwMDogMHg0MCwKICAgICAgICAgICAgMHhiMDAwMDogMHg4MDAwMTAwMCwKICAgICAgICAgICAgMHhjMDAwMDogMHg4MDQwMDA0MCwKICAgICAgICAgICAgMHhkMDAwMDogMHgxMDQwLAogICAgICAgICAgICAweGUwMDAwOiAweDEwMDAsCiAgICAgICAgICAgIDB4ZjAwMDA6IDB4ODA0MDEwNDAsCiAgICAgICAgICAgIDB4ODAwMDogMHg4MDAwMTA0MCwKICAgICAgICAgICAgMHgxODAwMDogMHg0MCwKICAgICAgICAgICAgMHgyODAwMDogMHg4MDQwMDA0MCwKICAgICAgICAgICAgMHgzODAwMDogMHg4MDAwMTAwMCwKICAgICAgICAgICAgMHg0ODAwMDogMHg0MDEwMDAsCiAgICAgICAgICAgIDB4NTgwMDA6IDB4ODA0MDEwNDAsCiAgICAgICAgICAgIDB4NjgwMDA6IDB4MCwKICAgICAgICAgICAgMHg3ODAwMDogMHg4MDQwMDAwMCwKICAgICAgICAgICAgMHg4ODAwMDogMHgxMDAwLAogICAgICAgICAgICAweDk4MDAwOiAweDgwNDAxMDAwLAogICAgICAgICAgICAweGE4MDAwOiAweDQwMDAwMCwKICAgICAgICAgICAgMHhiODAwMDogMHgxMDQwLAogICAgICAgICAgICAweGM4MDAwOiAweDgwMDAwMDAwLAogICAgICAgICAgICAweGQ4MDAwOiAweDQwMDA0MCwKICAgICAgICAgICAgMHhlODAwMDogMHg0MDEwNDAsCiAgICAgICAgICAgIDB4ZjgwMDA6IDB4ODAwMDAwNDAsCiAgICAgICAgICAgIDB4MTAwMDAwOiAweDQwMDA0MCwKICAgICAgICAgICAgMHgxMTAwMDA6IDB4NDAxMDAwLAogICAgICAgICAgICAweDEyMDAwMDogMHg4MDAwMDA0MCwKICAgICAgICAgICAgMHgxMzAwMDA6IDB4MCwKICAgICAgICAgICAgMHgxNDAwMDA6IDB4MTA0MCwKICAgICAgICAgICAgMHgxNTAwMDA6IDB4ODA0MDAwNDAsCiAgICAgICAgICAgIDB4MTYwMDAwOiAweDgwNDAxMDAwLAogICAgICAgICAgICAweDE3MDAwMDogMHg4MDAwMTA0MCwKICAgICAgICAgICAgMHgxODAwMDA6IDB4ODA0MDEwNDAsCiAgICAgICAgICAgIDB4MTkwMDAwOiAweDgwMDAwMDAwLAogICAgICAgICAgICAweDFhMDAwMDogMHg4MDQwMDAwMCwKICAgICAgICAgICAgMHgxYjAwMDA6IDB4NDAxMDQwLAogICAgICAgICAgICAweDFjMDAwMDogMHg4MDAwMTAwMCwKICAgICAgICAgICAgMHgxZDAwMDA6IDB4NDAwMDAwLAogICAgICAgICAgICAweDFlMDAwMDogMHg0MCwKICAgICAgICAgICAgMHgxZjAwMDA6IDB4MTAwMCwKICAgICAgICAgICAgMHgxMDgwMDA6IDB4ODA0MDAwMDAsCiAgICAgICAgICAgIDB4MTE4MDAwOiAweDgwNDAxMDQwLAogICAgICAgICAgICAweDEyODAwMDogMHgwLAogICAgICAgICAgICAweDEzODAwMDogMHg0MDEwMDAsCiAgICAgICAgICAgIDB4MTQ4MDAwOiAweDQwMDA0MCwKICAgICAgICAgICAgMHgxNTgwMDA6IDB4ODAwMDAwMDAsCiAgICAgICAgICAgIDB4MTY4MDAwOiAweDgwMDAxMDQwLAogICAgICAgICAgICAweDE3ODAwMDogMHg0MCwKICAgICAgICAgICAgMHgxODgwMDA6IDB4ODAwMDAwNDAsCiAgICAgICAgICAgIDB4MTk4MDAwOiAweDEwMDAsCiAgICAgICAgICAgIDB4MWE4MDAwOiAweDgwMDAxMDAwLAogICAgICAgICAgICAweDFiODAwMDogMHg4MDQwMDA0MCwKICAgICAgICAgICAgMHgxYzgwMDA6IDB4MTA0MCwKICAgICAgICAgICAgMHgxZDgwMDA6IDB4ODA0MDEwMDAsCiAgICAgICAgICAgIDB4MWU4MDAwOiAweDQwMDAwMCwKICAgICAgICAgICAgMHgxZjgwMDA6IDB4NDAxMDQwCiAgICAgICAgICB9LCB7CiAgICAgICAgICAgIDB4MDogMHg4MCwKICAgICAgICAgICAgMHgxMDAwOiAweDEwNDAwMDAsCiAgICAgICAgICAgIDB4MjAwMDogMHg0MDAwMCwKICAgICAgICAgICAgMHgzMDAwOiAweDIwMDAwMDAwLAogICAgICAgICAgICAweDQwMDA6IDB4MjAwNDAwODAsCiAgICAgICAgICAgIDB4NTAwMDogMHgxMDAwMDgwLAogICAgICAgICAgICAweDYwMDA6IDB4MjEwMDAwODAsCiAgICAgICAgICAgIDB4NzAwMDogMHg0MDA4MCwKICAgICAgICAgICAgMHg4MDAwOiAweDEwMDAwMDAsCiAgICAgICAgICAgIDB4OTAwMDogMHgyMDA0MDAwMCwKICAgICAgICAgICAgMHhhMDAwOiAweDIwMDAwMDgwLAogICAgICAgICAgICAweGIwMDA6IDB4MjEwNDAwODAsCiAgICAgICAgICAgIDB4YzAwMDogMHgyMTA0MDAwMCwKICAgICAgICAgICAgMHhkMDAwOiAweDAsCiAgICAgICAgICAgIDB4ZTAwMDogMHgxMDQwMDgwLAogICAgICAgICAgICAweGYwMDA6IDB4MjEwMDAwMDAsCiAgICAgICAgICAgIDB4ODAwOiAweDEwNDAwODAsCiAgICAgICAgICAgIDB4MTgwMDogMHgyMTAwMDA4MCwKICAgICAgICAgICAgMHgyODAwOiAweDgwLAogICAgICAgICAgICAweDM4MDA6IDB4MTA0MDAwMCwKICAgICAgICAgICAgMHg0ODAwOiAweDQwMDAwLAogICAgICAgICAgICAweDU4MDA6IDB4MjAwNDAwODAsCiAgICAgICAgICAgIDB4NjgwMDogMHgyMTA0MDAwMCwKICAgICAgICAgICAgMHg3ODAwOiAweDIwMDAwMDAwLAogICAgICAgICAgICAweDg4MDA6IDB4MjAwNDAwMDAsCiAgICAgICAgICAgIDB4OTgwMDogMHgwLAogICAgICAgICAgICAweGE4MDA6IDB4MjEwNDAwODAsCiAgICAgICAgICAgIDB4YjgwMDogMHgxMDAwMDgwLAogICAgICAgICAgICAweGM4MDA6IDB4MjAwMDAwODAsCiAgICAgICAgICAgIDB4ZDgwMDogMHgyMTAwMDAwMCwKICAgICAgICAgICAgMHhlODAwOiAweDEwMDAwMDAsCiAgICAgICAgICAgIDB4ZjgwMDogMHg0MDA4MCwKICAgICAgICAgICAgMHgxMDAwMDogMHg0MDAwMCwKICAgICAgICAgICAgMHgxMTAwMDogMHg4MCwKICAgICAgICAgICAgMHgxMjAwMDogMHgyMDAwMDAwMCwKICAgICAgICAgICAgMHgxMzAwMDogMHgyMTAwMDA4MCwKICAgICAgICAgICAgMHgxNDAwMDogMHgxMDAwMDgwLAogICAgICAgICAgICAweDE1MDAwOiAweDIxMDQwMDAwLAogICAgICAgICAgICAweDE2MDAwOiAweDIwMDQwMDgwLAogICAgICAgICAgICAweDE3MDAwOiAweDEwMDAwMDAsCiAgICAgICAgICAgIDB4MTgwMDA6IDB4MjEwNDAwODAsCiAgICAgICAgICAgIDB4MTkwMDA6IDB4MjEwMDAwMDAsCiAgICAgICAgICAgIDB4MWEwMDA6IDB4MTA0MDAwMCwKICAgICAgICAgICAgMHgxYjAwMDogMHgyMDA0MDAwMCwKICAgICAgICAgICAgMHgxYzAwMDogMHg0MDA4MCwKICAgICAgICAgICAgMHgxZDAwMDogMHgyMDAwMDA4MCwKICAgICAgICAgICAgMHgxZTAwMDogMHgwLAogICAgICAgICAgICAweDFmMDAwOiAweDEwNDAwODAsCiAgICAgICAgICAgIDB4MTA4MDA6IDB4MjEwMDAwODAsCiAgICAgICAgICAgIDB4MTE4MDA6IDB4MTAwMDAwMCwKICAgICAgICAgICAgMHgxMjgwMDogMHgxMDQwMDAwLAogICAgICAgICAgICAweDEzODAwOiAweDIwMDQwMDgwLAogICAgICAgICAgICAweDE0ODAwOiAweDIwMDAwMDAwLAogICAgICAgICAgICAweDE1ODAwOiAweDEwNDAwODAsCiAgICAgICAgICAgIDB4MTY4MDA6IDB4ODAsCiAgICAgICAgICAgIDB4MTc4MDA6IDB4MjEwNDAwMDAsCiAgICAgICAgICAgIDB4MTg4MDA6IDB4NDAwODAsCiAgICAgICAgICAgIDB4MTk4MDA6IDB4MjEwNDAwODAsCiAgICAgICAgICAgIDB4MWE4MDA6IDB4MCwKICAgICAgICAgICAgMHgxYjgwMDogMHgyMTAwMDAwMCwKICAgICAgICAgICAgMHgxYzgwMDogMHgxMDAwMDgwLAogICAgICAgICAgICAweDFkODAwOiAweDQwMDAwLAogICAgICAgICAgICAweDFlODAwOiAweDIwMDQwMDAwLAogICAgICAgICAgICAweDFmODAwOiAweDIwMDAwMDgwCiAgICAgICAgICB9LCB7CiAgICAgICAgICAgIDB4MDogMHgxMDAwMDAwOCwKICAgICAgICAgICAgMHgxMDA6IDB4MjAwMCwKICAgICAgICAgICAgMHgyMDA6IDB4MTAyMDAwMDAsCiAgICAgICAgICAgIDB4MzAwOiAweDEwMjAyMDA4LAogICAgICAgICAgICAweDQwMDogMHgxMDAwMjAwMCwKICAgICAgICAgICAgMHg1MDA6IDB4MjAwMDAwLAogICAgICAgICAgICAweDYwMDogMHgyMDAwMDgsCiAgICAgICAgICAgIDB4NzAwOiAweDEwMDAwMDAwLAogICAgICAgICAgICAweDgwMDogMHgwLAogICAgICAgICAgICAweDkwMDogMHgxMDAwMjAwOCwKICAgICAgICAgICAgMHhhMDA6IDB4MjAyMDAwLAogICAgICAgICAgICAweGIwMDogMHg4LAogICAgICAgICAgICAweGMwMDogMHgxMDIwMDAwOCwKICAgICAgICAgICAgMHhkMDA6IDB4MjAyMDA4LAogICAgICAgICAgICAweGUwMDogMHgyMDA4LAogICAgICAgICAgICAweGYwMDogMHgxMDIwMjAwMCwKICAgICAgICAgICAgMHg4MDogMHgxMDIwMDAwMCwKICAgICAgICAgICAgMHgxODA6IDB4MTAyMDIwMDgsCiAgICAgICAgICAgIDB4MjgwOiAweDgsCiAgICAgICAgICAgIDB4MzgwOiAweDIwMDAwMCwKICAgICAgICAgICAgMHg0ODA6IDB4MjAyMDA4LAogICAgICAgICAgICAweDU4MDogMHgxMDAwMDAwOCwKICAgICAgICAgICAgMHg2ODA6IDB4MTAwMDIwMDAsCiAgICAgICAgICAgIDB4NzgwOiAweDIwMDgsCiAgICAgICAgICAgIDB4ODgwOiAweDIwMDAwOCwKICAgICAgICAgICAgMHg5ODA6IDB4MjAwMCwKICAgICAgICAgICAgMHhhODA6IDB4MTAwMDIwMDgsCiAgICAgICAgICAgIDB4YjgwOiAweDEwMjAwMDA4LAogICAgICAgICAgICAweGM4MDogMHgwLAogICAgICAgICAgICAweGQ4MDogMHgxMDIwMjAwMCwKICAgICAgICAgICAgMHhlODA6IDB4MjAyMDAwLAogICAgICAgICAgICAweGY4MDogMHgxMDAwMDAwMCwKICAgICAgICAgICAgMHgxMDAwOiAweDEwMDAyMDAwLAogICAgICAgICAgICAweDExMDA6IDB4MTAyMDAwMDgsCiAgICAgICAgICAgIDB4MTIwMDogMHgxMDIwMjAwOCwKICAgICAgICAgICAgMHgxMzAwOiAweDIwMDgsCiAgICAgICAgICAgIDB4MTQwMDogMHgyMDAwMDAsCiAgICAgICAgICAgIDB4MTUwMDogMHgxMDAwMDAwMCwKICAgICAgICAgICAgMHgxNjAwOiAweDEwMDAwMDA4LAogICAgICAgICAgICAweDE3MDA6IDB4MjAyMDAwLAogICAgICAgICAgICAweDE4MDA6IDB4MjAyMDA4LAogICAgICAgICAgICAweDE5MDA6IDB4MCwKICAgICAgICAgICAgMHgxYTAwOiAweDgsCiAgICAgICAgICAgIDB4MWIwMDogMHgxMDIwMDAwMCwKICAgICAgICAgICAgMHgxYzAwOiAweDIwMDAsCiAgICAgICAgICAgIDB4MWQwMDogMHgxMDAwMjAwOCwKICAgICAgICAgICAgMHgxZTAwOiAweDEwMjAyMDAwLAogICAgICAgICAgICAweDFmMDA6IDB4MjAwMDA4LAogICAgICAgICAgICAweDEwODA6IDB4OCwKICAgICAgICAgICAgMHgxMTgwOiAweDIwMjAwMCwKICAgICAgICAgICAgMHgxMjgwOiAweDIwMDAwMCwKICAgICAgICAgICAgMHgxMzgwOiAweDEwMDAwMDA4LAogICAgICAgICAgICAweDE0ODA6IDB4MTAwMDIwMDAsCiAgICAgICAgICAgIDB4MTU4MDogMHgyMDA4LAogICAgICAgICAgICAweDE2ODA6IDB4MTAyMDIwMDgsCiAgICAgICAgICAgIDB4MTc4MDogMHgxMDIwMDAwMCwKICAgICAgICAgICAgMHgxODgwOiAweDEwMjAyMDAwLAogICAgICAgICAgICAweDE5ODA6IDB4MTAyMDAwMDgsCiAgICAgICAgICAgIDB4MWE4MDogMHgyMDAwLAogICAgICAgICAgICAweDFiODA6IDB4MjAyMDA4LAogICAgICAgICAgICAweDFjODA6IDB4MjAwMDA4LAogICAgICAgICAgICAweDFkODA6IDB4MCwKICAgICAgICAgICAgMHgxZTgwOiAweDEwMDAwMDAwLAogICAgICAgICAgICAweDFmODA6IDB4MTAwMDIwMDgKICAgICAgICAgIH0sIHsKICAgICAgICAgICAgMHgwOiAweDEwMDAwMCwKICAgICAgICAgICAgMHgxMDogMHgyMDAwNDAxLAogICAgICAgICAgICAweDIwOiAweDQwMCwKICAgICAgICAgICAgMHgzMDogMHgxMDA0MDEsCiAgICAgICAgICAgIDB4NDA6IDB4MjEwMDQwMSwKICAgICAgICAgICAgMHg1MDogMHgwLAogICAgICAgICAgICAweDYwOiAweDEsCiAgICAgICAgICAgIDB4NzA6IDB4MjEwMDAwMSwKICAgICAgICAgICAgMHg4MDogMHgyMDAwNDAwLAogICAgICAgICAgICAweDkwOiAweDEwMDAwMSwKICAgICAgICAgICAgMHhhMDogMHgyMDAwMDAxLAogICAgICAgICAgICAweGIwOiAweDIxMDA0MDAsCiAgICAgICAgICAgIDB4YzA6IDB4MjEwMDAwMCwKICAgICAgICAgICAgMHhkMDogMHg0MDEsCiAgICAgICAgICAgIDB4ZTA6IDB4MTAwNDAwLAogICAgICAgICAgICAweGYwOiAweDIwMDAwMDAsCiAgICAgICAgICAgIDB4ODogMHgyMTAwMDAxLAogICAgICAgICAgICAweDE4OiAweDAsCiAgICAgICAgICAgIDB4Mjg6IDB4MjAwMDQwMSwKICAgICAgICAgICAgMHgzODogMHgyMTAwNDAwLAogICAgICAgICAgICAweDQ4OiAweDEwMDAwMCwKICAgICAgICAgICAgMHg1ODogMHgyMDAwMDAxLAogICAgICAgICAgICAweDY4OiAweDIwMDAwMDAsCiAgICAgICAgICAgIDB4Nzg6IDB4NDAxLAogICAgICAgICAgICAweDg4OiAweDEwMDQwMSwKICAgICAgICAgICAgMHg5ODogMHgyMDAwNDAwLAogICAgICAgICAgICAweGE4OiAweDIxMDAwMDAsCiAgICAgICAgICAgIDB4Yjg6IDB4MTAwMDAxLAogICAgICAgICAgICAweGM4OiAweDQwMCwKICAgICAgICAgICAgMHhkODogMHgyMTAwNDAxLAogICAgICAgICAgICAweGU4OiAweDEsCiAgICAgICAgICAgIDB4Zjg6IDB4MTAwNDAwLAogICAgICAgICAgICAweDEwMDogMHgyMDAwMDAwLAogICAgICAgICAgICAweDExMDogMHgxMDAwMDAsCiAgICAgICAgICAgIDB4MTIwOiAweDIwMDA0MDEsCiAgICAgICAgICAgIDB4MTMwOiAweDIxMDAwMDEsCiAgICAgICAgICAgIDB4MTQwOiAweDEwMDAwMSwKICAgICAgICAgICAgMHgxNTA6IDB4MjAwMDQwMCwKICAgICAgICAgICAgMHgxNjA6IDB4MjEwMDQwMCwKICAgICAgICAgICAgMHgxNzA6IDB4MTAwNDAxLAogICAgICAgICAgICAweDE4MDogMHg0MDEsCiAgICAgICAgICAgIDB4MTkwOiAweDIxMDA0MDEsCiAgICAgICAgICAgIDB4MWEwOiAweDEwMDQwMCwKICAgICAgICAgICAgMHgxYjA6IDB4MSwKICAgICAgICAgICAgMHgxYzA6IDB4MCwKICAgICAgICAgICAgMHgxZDA6IDB4MjEwMDAwMCwKICAgICAgICAgICAgMHgxZTA6IDB4MjAwMDAwMSwKICAgICAgICAgICAgMHgxZjA6IDB4NDAwLAogICAgICAgICAgICAweDEwODogMHgxMDA0MDAsCiAgICAgICAgICAgIDB4MTE4OiAweDIwMDA0MDEsCiAgICAgICAgICAgIDB4MTI4OiAweDIxMDAwMDEsCiAgICAgICAgICAgIDB4MTM4OiAweDEsCiAgICAgICAgICAgIDB4MTQ4OiAweDIwMDAwMDAsCiAgICAgICAgICAgIDB4MTU4OiAweDEwMDAwMCwKICAgICAgICAgICAgMHgxNjg6IDB4NDAxLAogICAgICAgICAgICAweDE3ODogMHgyMTAwNDAwLAogICAgICAgICAgICAweDE4ODogMHgyMDAwMDAxLAogICAgICAgICAgICAweDE5ODogMHgyMTAwMDAwLAogICAgICAgICAgICAweDFhODogMHgwLAogICAgICAgICAgICAweDFiODogMHgyMTAwNDAxLAogICAgICAgICAgICAweDFjODogMHgxMDA0MDEsCiAgICAgICAgICAgIDB4MWQ4OiAweDQwMCwKICAgICAgICAgICAgMHgxZTg6IDB4MjAwMDQwMCwKICAgICAgICAgICAgMHgxZjg6IDB4MTAwMDAxCiAgICAgICAgICB9LCB7CiAgICAgICAgICAgIDB4MDogMHg4MDAwODIwLAogICAgICAgICAgICAweDE6IDB4MjAwMDAsCiAgICAgICAgICAgIDB4MjogMHg4MDAwMDAwLAogICAgICAgICAgICAweDM6IDB4MjAsCiAgICAgICAgICAgIDB4NDogMHgyMDAyMCwKICAgICAgICAgICAgMHg1OiAweDgwMjA4MjAsCiAgICAgICAgICAgIDB4NjogMHg4MDIwODAwLAogICAgICAgICAgICAweDc6IDB4ODAwLAogICAgICAgICAgICAweDg6IDB4ODAyMDAwMCwKICAgICAgICAgICAgMHg5OiAweDgwMDA4MDAsCiAgICAgICAgICAgIDB4YTogMHgyMDgwMCwKICAgICAgICAgICAgMHhiOiAweDgwMjAwMjAsCiAgICAgICAgICAgIDB4YzogMHg4MjAsCiAgICAgICAgICAgIDB4ZDogMHgwLAogICAgICAgICAgICAweGU6IDB4ODAwMDAyMCwKICAgICAgICAgICAgMHhmOiAweDIwODIwLAogICAgICAgICAgICAweDgwMDAwMDAwOiAweDgwMCwKICAgICAgICAgICAgMHg4MDAwMDAwMTogMHg4MDIwODIwLAogICAgICAgICAgICAweDgwMDAwMDAyOiAweDgwMDA4MjAsCiAgICAgICAgICAgIDB4ODAwMDAwMDM6IDB4ODAwMDAwMCwKICAgICAgICAgICAgMHg4MDAwMDAwNDogMHg4MDIwMDAwLAogICAgICAgICAgICAweDgwMDAwMDA1OiAweDIwODAwLAogICAgICAgICAgICAweDgwMDAwMDA2OiAweDIwODIwLAogICAgICAgICAgICAweDgwMDAwMDA3OiAweDIwLAogICAgICAgICAgICAweDgwMDAwMDA4OiAweDgwMDAwMjAsCiAgICAgICAgICAgIDB4ODAwMDAwMDk6IDB4ODIwLAogICAgICAgICAgICAweDgwMDAwMDBhOiAweDIwMDIwLAogICAgICAgICAgICAweDgwMDAwMDBiOiAweDgwMjA4MDAsCiAgICAgICAgICAgIDB4ODAwMDAwMGM6IDB4MCwKICAgICAgICAgICAgMHg4MDAwMDAwZDogMHg4MDIwMDIwLAogICAgICAgICAgICAweDgwMDAwMDBlOiAweDgwMDA4MDAsCiAgICAgICAgICAgIDB4ODAwMDAwMGY6IDB4MjAwMDAsCiAgICAgICAgICAgIDB4MTA6IDB4MjA4MjAsCiAgICAgICAgICAgIDB4MTE6IDB4ODAyMDgwMCwKICAgICAgICAgICAgMHgxMjogMHgyMCwKICAgICAgICAgICAgMHgxMzogMHg4MDAsCiAgICAgICAgICAgIDB4MTQ6IDB4ODAwMDgwMCwKICAgICAgICAgICAgMHgxNTogMHg4MDAwMDIwLAogICAgICAgICAgICAweDE2OiAweDgwMjAwMjAsCiAgICAgICAgICAgIDB4MTc6IDB4MjAwMDAsCiAgICAgICAgICAgIDB4MTg6IDB4MCwKICAgICAgICAgICAgMHgxOTogMHgyMDAyMCwKICAgICAgICAgICAgMHgxYTogMHg4MDIwMDAwLAogICAgICAgICAgICAweDFiOiAweDgwMDA4MjAsCiAgICAgICAgICAgIDB4MWM6IDB4ODAyMDgyMCwKICAgICAgICAgICAgMHgxZDogMHgyMDgwMCwKICAgICAgICAgICAgMHgxZTogMHg4MjAsCiAgICAgICAgICAgIDB4MWY6IDB4ODAwMDAwMCwKICAgICAgICAgICAgMHg4MDAwMDAxMDogMHgyMDAwMCwKICAgICAgICAgICAgMHg4MDAwMDAxMTogMHg4MDAsCiAgICAgICAgICAgIDB4ODAwMDAwMTI6IDB4ODAyMDAyMCwKICAgICAgICAgICAgMHg4MDAwMDAxMzogMHgyMDgyMCwKICAgICAgICAgICAgMHg4MDAwMDAxNDogMHgyMCwKICAgICAgICAgICAgMHg4MDAwMDAxNTogMHg4MDIwMDAwLAogICAgICAgICAgICAweDgwMDAwMDE2OiAweDgwMDAwMDAsCiAgICAgICAgICAgIDB4ODAwMDAwMTc6IDB4ODAwMDgyMCwKICAgICAgICAgICAgMHg4MDAwMDAxODogMHg4MDIwODIwLAogICAgICAgICAgICAweDgwMDAwMDE5OiAweDgwMDAwMjAsCiAgICAgICAgICAgIDB4ODAwMDAwMWE6IDB4ODAwMDgwMCwKICAgICAgICAgICAgMHg4MDAwMDAxYjogMHgwLAogICAgICAgICAgICAweDgwMDAwMDFjOiAweDIwODAwLAogICAgICAgICAgICAweDgwMDAwMDFkOiAweDgyMCwKICAgICAgICAgICAgMHg4MDAwMDAxZTogMHgyMDAyMCwKICAgICAgICAgICAgMHg4MDAwMDAxZjogMHg4MDIwODAwCiAgICAgICAgICB9XTsKCiAgICAgICAgICAvLyBNYXNrcyB0aGF0IHNlbGVjdCB0aGUgU0JPWCBpbnB1dAogICAgICAgICAgdmFyIFNCT1hfTUFTSyA9IFsweGY4MDAwMDAxLCAweDFmODAwMDAwLCAweDAxZjgwMDAwLCAweDAwMWY4MDAwLCAweDAwMDFmODAwLCAweDAwMDAxZjgwLCAweDAwMDAwMWY4LCAweDgwMDAwMDFmXTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIERFUyBibG9jayBjaXBoZXIgYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgREVTID0gQ19hbGdvLkRFUyA9IEJsb2NrQ2lwaGVyLmV4dGVuZCh7CiAgICAgICAgICAgIF9kb1Jlc2V0OiBmdW5jdGlvbiAoKSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGtleSA9IHRoaXMuX2tleTsKICAgICAgICAgICAgICB2YXIga2V5V29yZHMgPSBrZXkud29yZHM7CgogICAgICAgICAgICAgIC8vIFNlbGVjdCA1NiBiaXRzIGFjY29yZGluZyB0byBQQzEKICAgICAgICAgICAgICB2YXIga2V5Qml0cyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNTY7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGtleUJpdFBvcyA9IFBDMVtpXSAtIDE7CiAgICAgICAgICAgICAgICBrZXlCaXRzW2ldID0ga2V5V29yZHNba2V5Qml0UG9zID4+PiA1XSA+Pj4gMzEgLSBrZXlCaXRQb3MgJSAzMiAmIDE7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBBc3NlbWJsZSAxNiBzdWJrZXlzCiAgICAgICAgICAgICAgdmFyIHN1YktleXMgPSB0aGlzLl9zdWJLZXlzID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgblN1YktleSA9IDA7IG5TdWJLZXkgPCAxNjsgblN1YktleSsrKSB7CiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgc3Via2V5CiAgICAgICAgICAgICAgICB2YXIgc3ViS2V5ID0gc3ViS2V5c1tuU3ViS2V5XSA9IFtdOwoKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0CiAgICAgICAgICAgICAgICB2YXIgYml0U2hpZnQgPSBCSVRfU0hJRlRTW25TdWJLZXldOwoKICAgICAgICAgICAgICAgIC8vIFNlbGVjdCA0OCBiaXRzIGFjY29yZGluZyB0byBQQzIKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMjQ7IGkrKykgewogICAgICAgICAgICAgICAgICAvLyBTZWxlY3QgZnJvbSB0aGUgbGVmdCAyOCBrZXkgYml0cwogICAgICAgICAgICAgICAgICBzdWJLZXlbaSAvIDYgfCAwXSB8PSBrZXlCaXRzWyhQQzJbaV0gLSAxICsgYml0U2hpZnQpICUgMjhdIDw8IDMxIC0gaSAlIDY7CgogICAgICAgICAgICAgICAgICAvLyBTZWxlY3QgZnJvbSB0aGUgcmlnaHQgMjgga2V5IGJpdHMKICAgICAgICAgICAgICAgICAgc3ViS2V5WzQgKyAoaSAvIDYgfCAwKV0gfD0ga2V5Qml0c1syOCArIChQQzJbaSArIDI0XSAtIDEgKyBiaXRTaGlmdCkgJSAyOF0gPDwgMzEgLSBpICUgNjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvLyBTaW5jZSBlYWNoIHN1YmtleSBpcyBhcHBsaWVkIHRvIGFuIGV4cGFuZGVkIDMyLWJpdCBpbnB1dCwKICAgICAgICAgICAgICAgIC8vIHRoZSBzdWJrZXkgY2FuIGJlIGJyb2tlbiBpbnRvIDggdmFsdWVzIHNjYWxlZCB0byAzMi1iaXRzLAogICAgICAgICAgICAgICAgLy8gd2hpY2ggYWxsb3dzIHRoZSBrZXkgdG8gYmUgdXNlZCB3aXRob3V0IGV4cGFuc2lvbgogICAgICAgICAgICAgICAgc3ViS2V5WzBdID0gc3ViS2V5WzBdIDw8IDEgfCBzdWJLZXlbMF0gPj4+IDMxOwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCA3OyBpKyspIHsKICAgICAgICAgICAgICAgICAgc3ViS2V5W2ldID0gc3ViS2V5W2ldID4+PiAoaSAtIDEpICogNCArIDM7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBzdWJLZXlbN10gPSBzdWJLZXlbN10gPDwgNSB8IHN1YktleVs3XSA+Pj4gMjc7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBDb21wdXRlIGludmVyc2Ugc3Via2V5cwogICAgICAgICAgICAgIHZhciBpbnZTdWJLZXlzID0gdGhpcy5faW52U3ViS2V5cyA9IFtdOwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgMTY7IGkrKykgewogICAgICAgICAgICAgICAgaW52U3ViS2V5c1tpXSA9IHN1YktleXNbMTUgLSBpXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGVuY3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCkgewogICAgICAgICAgICAgIHRoaXMuX2RvQ3J5cHRCbG9jayhNLCBvZmZzZXQsIHRoaXMuX3N1YktleXMpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBkZWNyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICB0aGlzLl9kb0NyeXB0QmxvY2soTSwgb2Zmc2V0LCB0aGlzLl9pbnZTdWJLZXlzKTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvQ3J5cHRCbG9jazogZnVuY3Rpb24gKE0sIG9mZnNldCwgc3ViS2V5cykgewogICAgICAgICAgICAgIC8vIEdldCBpbnB1dAogICAgICAgICAgICAgIHRoaXMuX2xCbG9jayA9IE1bb2Zmc2V0XTsKICAgICAgICAgICAgICB0aGlzLl9yQmxvY2sgPSBNW29mZnNldCArIDFdOwoKICAgICAgICAgICAgICAvLyBJbml0aWFsIHBlcm11dGF0aW9uCiAgICAgICAgICAgICAgZXhjaGFuZ2VMUi5jYWxsKHRoaXMsIDQsIDB4MGYwZjBmMGYpOwogICAgICAgICAgICAgIGV4Y2hhbmdlTFIuY2FsbCh0aGlzLCAxNiwgMHgwMDAwZmZmZik7CiAgICAgICAgICAgICAgZXhjaGFuZ2VSTC5jYWxsKHRoaXMsIDIsIDB4MzMzMzMzMzMpOwogICAgICAgICAgICAgIGV4Y2hhbmdlUkwuY2FsbCh0aGlzLCA4LCAweDAwZmYwMGZmKTsKICAgICAgICAgICAgICBleGNoYW5nZUxSLmNhbGwodGhpcywgMSwgMHg1NTU1NTU1NSk7CgogICAgICAgICAgICAgIC8vIFJvdW5kcwogICAgICAgICAgICAgIGZvciAodmFyIHJvdW5kID0gMDsgcm91bmQgPCAxNjsgcm91bmQrKykgewogICAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgICB2YXIgc3ViS2V5ID0gc3ViS2V5c1tyb3VuZF07CiAgICAgICAgICAgICAgICB2YXIgbEJsb2NrID0gdGhpcy5fbEJsb2NrOwogICAgICAgICAgICAgICAgdmFyIHJCbG9jayA9IHRoaXMuX3JCbG9jazsKCiAgICAgICAgICAgICAgICAvLyBGZWlzdGVsIGZ1bmN0aW9uCiAgICAgICAgICAgICAgICB2YXIgZiA9IDA7CiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykgewogICAgICAgICAgICAgICAgICBmIHw9IFNCT1hfUFtpXVsoKHJCbG9jayBeIHN1YktleVtpXSkgJiBTQk9YX01BU0tbaV0pID4+PiAwXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHRoaXMuX2xCbG9jayA9IHJCbG9jazsKICAgICAgICAgICAgICAgIHRoaXMuX3JCbG9jayA9IGxCbG9jayBeIGY7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBVbmRvIHN3YXAgZnJvbSBsYXN0IHJvdW5kCiAgICAgICAgICAgICAgdmFyIHQgPSB0aGlzLl9sQmxvY2s7CiAgICAgICAgICAgICAgdGhpcy5fbEJsb2NrID0gdGhpcy5fckJsb2NrOwogICAgICAgICAgICAgIHRoaXMuX3JCbG9jayA9IHQ7CgogICAgICAgICAgICAgIC8vIEZpbmFsIHBlcm11dGF0aW9uCiAgICAgICAgICAgICAgZXhjaGFuZ2VMUi5jYWxsKHRoaXMsIDEsIDB4NTU1NTU1NTUpOwogICAgICAgICAgICAgIGV4Y2hhbmdlUkwuY2FsbCh0aGlzLCA4LCAweDAwZmYwMGZmKTsKICAgICAgICAgICAgICBleGNoYW5nZVJMLmNhbGwodGhpcywgMiwgMHgzMzMzMzMzMyk7CiAgICAgICAgICAgICAgZXhjaGFuZ2VMUi5jYWxsKHRoaXMsIDE2LCAweDAwMDBmZmZmKTsKICAgICAgICAgICAgICBleGNoYW5nZUxSLmNhbGwodGhpcywgNCwgMHgwZjBmMGYwZik7CgogICAgICAgICAgICAgIC8vIFNldCBvdXRwdXQKICAgICAgICAgICAgICBNW29mZnNldF0gPSB0aGlzLl9sQmxvY2s7CiAgICAgICAgICAgICAgTVtvZmZzZXQgKyAxXSA9IHRoaXMuX3JCbG9jazsKICAgICAgICAgICAgfSwKICAgICAgICAgICAga2V5U2l6ZTogNjQgLyAzMiwKICAgICAgICAgICAgaXZTaXplOiA2NCAvIDMyLAogICAgICAgICAgICBibG9ja1NpemU6IDY0IC8gMzIKICAgICAgICAgIH0pOwoKICAgICAgICAgIC8vIFN3YXAgYml0cyBhY3Jvc3MgdGhlIGxlZnQgYW5kIHJpZ2h0IHdvcmRzCiAgICAgICAgICBmdW5jdGlvbiBleGNoYW5nZUxSKG9mZnNldCwgbWFzaykgewogICAgICAgICAgICB2YXIgdCA9ICh0aGlzLl9sQmxvY2sgPj4+IG9mZnNldCBeIHRoaXMuX3JCbG9jaykgJiBtYXNrOwogICAgICAgICAgICB0aGlzLl9yQmxvY2sgXj0gdDsKICAgICAgICAgICAgdGhpcy5fbEJsb2NrIF49IHQgPDwgb2Zmc2V0OwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gZXhjaGFuZ2VSTChvZmZzZXQsIG1hc2spIHsKICAgICAgICAgICAgdmFyIHQgPSAodGhpcy5fckJsb2NrID4+PiBvZmZzZXQgXiB0aGlzLl9sQmxvY2spICYgbWFzazsKICAgICAgICAgICAgdGhpcy5fbEJsb2NrIF49IHQ7CiAgICAgICAgICAgIHRoaXMuX3JCbG9jayBePSB0IDw8IG9mZnNldDsKICAgICAgICAgIH0KCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFNob3J0Y3V0IGZ1bmN0aW9ucyB0byB0aGUgY2lwaGVyJ3Mgb2JqZWN0IGludGVyZmFjZS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBAZXhhbXBsZQogICAgICAgICAgICoKICAgICAgICAgICAqICAgICB2YXIgY2lwaGVydGV4dCA9IENyeXB0b0pTLkRFUy5lbmNyeXB0KG1lc3NhZ2UsIGtleSwgY2ZnKTsKICAgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ICA9IENyeXB0b0pTLkRFUy5kZWNyeXB0KGNpcGhlcnRleHQsIGtleSwgY2ZnKTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5ERVMgPSBCbG9ja0NpcGhlci5fY3JlYXRlSGVscGVyKERFUyk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBUcmlwbGUtREVTIGJsb2NrIGNpcGhlciBhbGdvcml0aG0uCiAgICAgICAgICAgKi8KICAgICAgICAgIHZhciBUcmlwbGVERVMgPSBDX2FsZ28uVHJpcGxlREVTID0gQmxvY2tDaXBoZXIuZXh0ZW5kKHsKICAgICAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIga2V5ID0gdGhpcy5fa2V5OwogICAgICAgICAgICAgIHZhciBrZXlXb3JkcyA9IGtleS53b3JkczsKICAgICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhlIGtleSBsZW5ndGggaXMgdmFsaWQgKDY0LCAxMjggb3IgPj0gMTkyIGJpdCkKICAgICAgICAgICAgICBpZiAoa2V5V29yZHMubGVuZ3RoICE9PSAyICYmIGtleVdvcmRzLmxlbmd0aCAhPT0gNCAmJiBrZXlXb3Jkcy5sZW5ndGggPCA2KSB7CiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQga2V5IGxlbmd0aCAtIDNERVMgcmVxdWlyZXMgdGhlIGtleSBsZW5ndGggdG8gYmUgNjQsIDEyOCwgMTkyIG9yID4xOTIuJyk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBFeHRlbmQgdGhlIGtleSBhY2NvcmRpbmcgdG8gdGhlIGtleWluZyBvcHRpb25zIGRlZmluZWQgaW4gM0RFUyBzdGFuZGFyZAogICAgICAgICAgICAgIHZhciBrZXkxID0ga2V5V29yZHMuc2xpY2UoMCwgMik7CiAgICAgICAgICAgICAgdmFyIGtleTIgPSBrZXlXb3Jkcy5sZW5ndGggPCA0ID8ga2V5V29yZHMuc2xpY2UoMCwgMikgOiBrZXlXb3Jkcy5zbGljZSgyLCA0KTsKICAgICAgICAgICAgICB2YXIga2V5MyA9IGtleVdvcmRzLmxlbmd0aCA8IDYgPyBrZXlXb3Jkcy5zbGljZSgwLCAyKSA6IGtleVdvcmRzLnNsaWNlKDQsIDYpOwoKICAgICAgICAgICAgICAvLyBDcmVhdGUgREVTIGluc3RhbmNlcwogICAgICAgICAgICAgIHRoaXMuX2RlczEgPSBERVMuY3JlYXRlRW5jcnlwdG9yKFdvcmRBcnJheS5jcmVhdGUoa2V5MSkpOwogICAgICAgICAgICAgIHRoaXMuX2RlczIgPSBERVMuY3JlYXRlRW5jcnlwdG9yKFdvcmRBcnJheS5jcmVhdGUoa2V5MikpOwogICAgICAgICAgICAgIHRoaXMuX2RlczMgPSBERVMuY3JlYXRlRW5jcnlwdG9yKFdvcmRBcnJheS5jcmVhdGUoa2V5MykpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBlbmNyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICB0aGlzLl9kZXMxLmVuY3J5cHRCbG9jayhNLCBvZmZzZXQpOwogICAgICAgICAgICAgIHRoaXMuX2RlczIuZGVjcnlwdEJsb2NrKE0sIG9mZnNldCk7CiAgICAgICAgICAgICAgdGhpcy5fZGVzMy5lbmNyeXB0QmxvY2soTSwgb2Zmc2V0KTsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZGVjcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgdGhpcy5fZGVzMy5kZWNyeXB0QmxvY2soTSwgb2Zmc2V0KTsKICAgICAgICAgICAgICB0aGlzLl9kZXMyLmVuY3J5cHRCbG9jayhNLCBvZmZzZXQpOwogICAgICAgICAgICAgIHRoaXMuX2RlczEuZGVjcnlwdEJsb2NrKE0sIG9mZnNldCk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGtleVNpemU6IDE5MiAvIDMyLAogICAgICAgICAgICBpdlNpemU6IDY0IC8gMzIsCiAgICAgICAgICAgIGJsb2NrU2l6ZTogNjQgLyAzMgogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5UcmlwbGVERVMuZW5jcnlwdChtZXNzYWdlLCBrZXksIGNmZyk7CiAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCAgPSBDcnlwdG9KUy5UcmlwbGVERVMuZGVjcnlwdChjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuVHJpcGxlREVTID0gQmxvY2tDaXBoZXIuX2NyZWF0ZUhlbHBlcihUcmlwbGVERVMpOwogICAgICAgIH0pKCk7CiAgICAgICAgcmV0dXJuIENyeXB0b0pTLlRyaXBsZURFUzsKICAgICAgfSk7CiAgICB9KSh0cmlwbGVkZXMkMSk7CiAgICByZXR1cm4gdHJpcGxlZGVzJDEuZXhwb3J0czsKICB9CgogIHZhciByYzQkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciByYzQgPSByYzQkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZFJjNDsKICBmdW5jdGlvbiByZXF1aXJlUmM0KCkgewogICAgaWYgKGhhc1JlcXVpcmVkUmM0KSByZXR1cm4gcmM0JDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkUmM0ID0gMTsKICAgIChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHsKICAgICAgKGZ1bmN0aW9uIChyb290LCBmYWN0b3J5LCB1bmRlZikgewogICAgICAgIHsKICAgICAgICAgIC8vIENvbW1vbkpTCiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkocmVxdWlyZUNvcmUoKSwgcmVxdWlyZUVuY0Jhc2U2NCgpLCByZXF1aXJlTWQ1KCksIHJlcXVpcmVFdnBrZGYoKSwgcmVxdWlyZUNpcGhlckNvcmUoKSk7CiAgICAgICAgfQogICAgICB9KShyYzQsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIChmdW5jdGlvbiAoKSB7CiAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgIHZhciBDID0gQ3J5cHRvSlM7CiAgICAgICAgICB2YXIgQ19saWIgPSBDLmxpYjsKICAgICAgICAgIHZhciBTdHJlYW1DaXBoZXIgPSBDX2xpYi5TdHJlYW1DaXBoZXI7CiAgICAgICAgICB2YXIgQ19hbGdvID0gQy5hbGdvOwoKICAgICAgICAgIC8qKgogICAgICAgICAgICogUkM0IHN0cmVhbSBjaXBoZXIgYWxnb3JpdGhtLgogICAgICAgICAgICovCiAgICAgICAgICB2YXIgUkM0ID0gQ19hbGdvLlJDNCA9IFN0cmVhbUNpcGhlci5leHRlbmQoewogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBrZXkgPSB0aGlzLl9rZXk7CiAgICAgICAgICAgICAgdmFyIGtleVdvcmRzID0ga2V5LndvcmRzOwogICAgICAgICAgICAgIHZhciBrZXlTaWdCeXRlcyA9IGtleS5zaWdCeXRlczsKCiAgICAgICAgICAgICAgLy8gSW5pdCBzYm94CiAgICAgICAgICAgICAgdmFyIFMgPSB0aGlzLl9TID0gW107CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICAgICAgU1tpXSA9IGk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBLZXkgc2V0dXAKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgaiA9IDA7IGkgPCAyNTY7IGkrKykgewogICAgICAgICAgICAgICAgdmFyIGtleUJ5dGVJbmRleCA9IGkgJSBrZXlTaWdCeXRlczsKICAgICAgICAgICAgICAgIHZhciBrZXlCeXRlID0ga2V5V29yZHNba2V5Qnl0ZUluZGV4ID4+PiAyXSA+Pj4gMjQgLSBrZXlCeXRlSW5kZXggJSA0ICogOCAmIDB4ZmY7CiAgICAgICAgICAgICAgICBqID0gKGogKyBTW2ldICsga2V5Qnl0ZSkgJSAyNTY7CgogICAgICAgICAgICAgICAgLy8gU3dhcAogICAgICAgICAgICAgICAgdmFyIHQgPSBTW2ldOwogICAgICAgICAgICAgICAgU1tpXSA9IFNbal07CiAgICAgICAgICAgICAgICBTW2pdID0gdDsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIENvdW50ZXJzCiAgICAgICAgICAgICAgdGhpcy5faSA9IHRoaXMuX2ogPSAwOwogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICBNW29mZnNldF0gXj0gZ2VuZXJhdGVLZXlzdHJlYW1Xb3JkLmNhbGwodGhpcyk7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGtleVNpemU6IDI1NiAvIDMyLAogICAgICAgICAgICBpdlNpemU6IDAKICAgICAgICAgIH0pOwogICAgICAgICAgZnVuY3Rpb24gZ2VuZXJhdGVLZXlzdHJlYW1Xb3JkKCkgewogICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgdmFyIFMgPSB0aGlzLl9TOwogICAgICAgICAgICB2YXIgaSA9IHRoaXMuX2k7CiAgICAgICAgICAgIHZhciBqID0gdGhpcy5fajsKCiAgICAgICAgICAgIC8vIEdlbmVyYXRlIGtleXN0cmVhbSB3b3JkCiAgICAgICAgICAgIHZhciBrZXlzdHJlYW1Xb3JkID0gMDsKICAgICAgICAgICAgZm9yICh2YXIgbiA9IDA7IG4gPCA0OyBuKyspIHsKICAgICAgICAgICAgICBpID0gKGkgKyAxKSAlIDI1NjsKICAgICAgICAgICAgICBqID0gKGogKyBTW2ldKSAlIDI1NjsKCiAgICAgICAgICAgICAgLy8gU3dhcAogICAgICAgICAgICAgIHZhciB0ID0gU1tpXTsKICAgICAgICAgICAgICBTW2ldID0gU1tqXTsKICAgICAgICAgICAgICBTW2pdID0gdDsKICAgICAgICAgICAgICBrZXlzdHJlYW1Xb3JkIHw9IFNbKFNbaV0gKyBTW2pdKSAlIDI1Nl0gPDwgMjQgLSBuICogODsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gVXBkYXRlIGNvdW50ZXJzCiAgICAgICAgICAgIHRoaXMuX2kgPSBpOwogICAgICAgICAgICB0aGlzLl9qID0gajsKICAgICAgICAgICAgcmV0dXJuIGtleXN0cmVhbVdvcmQ7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5SQzQuZW5jcnlwdChtZXNzYWdlLCBrZXksIGNmZyk7CiAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCAgPSBDcnlwdG9KUy5SQzQuZGVjcnlwdChjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuUkM0ID0gU3RyZWFtQ2lwaGVyLl9jcmVhdGVIZWxwZXIoUkM0KTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIE1vZGlmaWVkIFJDNCBzdHJlYW0gY2lwaGVyIGFsZ29yaXRobS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIFJDNERyb3AgPSBDX2FsZ28uUkM0RHJvcCA9IFJDNC5leHRlbmQoewogICAgICAgICAgICAvKioKICAgICAgICAgICAgICogQ29uZmlndXJhdGlvbiBvcHRpb25zLgogICAgICAgICAgICAgKgogICAgICAgICAgICAgKiBAcHJvcGVydHkge251bWJlcn0gZHJvcCBUaGUgbnVtYmVyIG9mIGtleXN0cmVhbSB3b3JkcyB0byBkcm9wLiBEZWZhdWx0IDE5MgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY2ZnOiBSQzQuY2ZnLmV4dGVuZCh7CiAgICAgICAgICAgICAgZHJvcDogMTkyCiAgICAgICAgICAgIH0pLAogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIFJDNC5fZG9SZXNldC5jYWxsKHRoaXMpOwoKICAgICAgICAgICAgICAvLyBEcm9wCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IHRoaXMuY2ZnLmRyb3A7IGkgPiAwOyBpLS0pIHsKICAgICAgICAgICAgICAgIGdlbmVyYXRlS2V5c3RyZWFtV29yZC5jYWxsKHRoaXMpOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5SQzREcm9wLmVuY3J5cHQobWVzc2FnZSwga2V5LCBjZmcpOwogICAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgID0gQ3J5cHRvSlMuUkM0RHJvcC5kZWNyeXB0KGNpcGhlcnRleHQsIGtleSwgY2ZnKTsKICAgICAgICAgICAqLwogICAgICAgICAgQy5SQzREcm9wID0gU3RyZWFtQ2lwaGVyLl9jcmVhdGVIZWxwZXIoUkM0RHJvcCk7CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMuUkM0OwogICAgICB9KTsKICAgIH0pKHJjNCQxKTsKICAgIHJldHVybiByYzQkMS5leHBvcnRzOwogIH0KCiAgdmFyIHJhYmJpdCQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIHJhYmJpdCA9IHJhYmJpdCQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkUmFiYml0OwogIGZ1bmN0aW9uIHJlcXVpcmVSYWJiaXQoKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRSYWJiaXQpIHJldHVybiByYWJiaXQkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRSYWJiaXQgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlRW5jQmFzZTY0KCksIHJlcXVpcmVNZDUoKSwgcmVxdWlyZUV2cGtkZigpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHJhYmJpdCwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFN0cmVhbUNpcGhlciA9IENfbGliLlN0cmVhbUNpcGhlcjsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CgogICAgICAgICAgLy8gUmV1c2FibGUgb2JqZWN0cwogICAgICAgICAgdmFyIFMgPSBbXTsKICAgICAgICAgIHZhciBDXyA9IFtdOwogICAgICAgICAgdmFyIEcgPSBbXTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFJhYmJpdCBzdHJlYW0gY2lwaGVyIGFsZ29yaXRobQogICAgICAgICAgICovCiAgICAgICAgICB2YXIgUmFiYml0ID0gQ19hbGdvLlJhYmJpdCA9IFN0cmVhbUNpcGhlci5leHRlbmQoewogICAgICAgICAgICBfZG9SZXNldDogZnVuY3Rpb24gKCkgewogICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgIHZhciBLID0gdGhpcy5fa2V5LndvcmRzOwogICAgICAgICAgICAgIHZhciBpdiA9IHRoaXMuY2ZnLml2OwoKICAgICAgICAgICAgICAvLyBTd2FwIGVuZGlhbgogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgICAgICAgICBLW2ldID0gKEtbaV0gPDwgOCB8IEtbaV0gPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoS1tpXSA8PCAyNCB8IEtbaV0gPj4+IDgpICYgMHhmZjAwZmYwMDsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIEdlbmVyYXRlIGluaXRpYWwgc3RhdGUgdmFsdWVzCiAgICAgICAgICAgICAgdmFyIFggPSB0aGlzLl9YID0gW0tbMF0sIEtbM10gPDwgMTYgfCBLWzJdID4+PiAxNiwgS1sxXSwgS1swXSA8PCAxNiB8IEtbM10gPj4+IDE2LCBLWzJdLCBLWzFdIDw8IDE2IHwgS1swXSA+Pj4gMTYsIEtbM10sIEtbMl0gPDwgMTYgfCBLWzFdID4+PiAxNl07CgogICAgICAgICAgICAgIC8vIEdlbmVyYXRlIGluaXRpYWwgY291bnRlciB2YWx1ZXMKICAgICAgICAgICAgICB2YXIgQyA9IHRoaXMuX0MgPSBbS1syXSA8PCAxNiB8IEtbMl0gPj4+IDE2LCBLWzBdICYgMHhmZmZmMDAwMCB8IEtbMV0gJiAweDAwMDBmZmZmLCBLWzNdIDw8IDE2IHwgS1szXSA+Pj4gMTYsIEtbMV0gJiAweGZmZmYwMDAwIHwgS1syXSAmIDB4MDAwMGZmZmYsIEtbMF0gPDwgMTYgfCBLWzBdID4+PiAxNiwgS1syXSAmIDB4ZmZmZjAwMDAgfCBLWzNdICYgMHgwMDAwZmZmZiwgS1sxXSA8PCAxNiB8IEtbMV0gPj4+IDE2LCBLWzNdICYgMHhmZmZmMDAwMCB8IEtbMF0gJiAweDAwMDBmZmZmXTsKCiAgICAgICAgICAgICAgLy8gQ2FycnkgYml0CiAgICAgICAgICAgICAgdGhpcy5fYiA9IDA7CgogICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhlIHN5c3RlbSBmb3VyIHRpbWVzCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgICAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gTW9kaWZ5IHRoZSBjb3VudGVycwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODsgaSsrKSB7CiAgICAgICAgICAgICAgICBDW2ldIF49IFhbaSArIDQgJiA3XTsKICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgIC8vIElWIHNldHVwCiAgICAgICAgICAgICAgaWYgKGl2KSB7CiAgICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICAgIHZhciBJViA9IGl2LndvcmRzOwogICAgICAgICAgICAgICAgdmFyIElWXzAgPSBJVlswXTsKICAgICAgICAgICAgICAgIHZhciBJVl8xID0gSVZbMV07CgogICAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgZm91ciBzdWJ2ZWN0b3JzCiAgICAgICAgICAgICAgICB2YXIgaTAgPSAoSVZfMCA8PCA4IHwgSVZfMCA+Pj4gMjQpICYgMHgwMGZmMDBmZiB8IChJVl8wIDw8IDI0IHwgSVZfMCA+Pj4gOCkgJiAweGZmMDBmZjAwOwogICAgICAgICAgICAgICAgdmFyIGkyID0gKElWXzEgPDwgOCB8IElWXzEgPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoSVZfMSA8PCAyNCB8IElWXzEgPj4+IDgpICYgMHhmZjAwZmYwMDsKICAgICAgICAgICAgICAgIHZhciBpMSA9IGkwID4+PiAxNiB8IGkyICYgMHhmZmZmMDAwMDsKICAgICAgICAgICAgICAgIHZhciBpMyA9IGkyIDw8IDE2IHwgaTAgJiAweDAwMDBmZmZmOwoKICAgICAgICAgICAgICAgIC8vIE1vZGlmeSBjb3VudGVyIHZhbHVlcwogICAgICAgICAgICAgICAgQ1swXSBePSBpMDsKICAgICAgICAgICAgICAgIENbMV0gXj0gaTE7CiAgICAgICAgICAgICAgICBDWzJdIF49IGkyOwogICAgICAgICAgICAgICAgQ1szXSBePSBpMzsKICAgICAgICAgICAgICAgIENbNF0gXj0gaTA7CiAgICAgICAgICAgICAgICBDWzVdIF49IGkxOwogICAgICAgICAgICAgICAgQ1s2XSBePSBpMjsKICAgICAgICAgICAgICAgIENbN10gXj0gaTM7CgogICAgICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aGUgc3lzdGVtIGZvdXIgdGltZXMKICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgX2RvUHJvY2Vzc0Jsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgLy8gU2hvcnRjdXQKICAgICAgICAgICAgICB2YXIgWCA9IHRoaXMuX1g7CgogICAgICAgICAgICAgIC8vIEl0ZXJhdGUgdGhlIHN5c3RlbQogICAgICAgICAgICAgIG5leHRTdGF0ZS5jYWxsKHRoaXMpOwoKICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBmb3VyIGtleXN0cmVhbSB3b3JkcwogICAgICAgICAgICAgIFNbMF0gPSBYWzBdIF4gWFs1XSA+Pj4gMTYgXiBYWzNdIDw8IDE2OwogICAgICAgICAgICAgIFNbMV0gPSBYWzJdIF4gWFs3XSA+Pj4gMTYgXiBYWzVdIDw8IDE2OwogICAgICAgICAgICAgIFNbMl0gPSBYWzRdIF4gWFsxXSA+Pj4gMTYgXiBYWzddIDw8IDE2OwogICAgICAgICAgICAgIFNbM10gPSBYWzZdIF4gWFszXSA+Pj4gMTYgXiBYWzFdIDw8IDE2OwogICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgICAgICAgICAvLyBTd2FwIGVuZGlhbgogICAgICAgICAgICAgICAgU1tpXSA9IChTW2ldIDw8IDggfCBTW2ldID4+PiAyNCkgJiAweDAwZmYwMGZmIHwgKFNbaV0gPDwgMjQgfCBTW2ldID4+PiA4KSAmIDB4ZmYwMGZmMDA7CgogICAgICAgICAgICAgICAgLy8gRW5jcnlwdAogICAgICAgICAgICAgICAgTVtvZmZzZXQgKyBpXSBePSBTW2ldOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSwKICAgICAgICAgICAgYmxvY2tTaXplOiAxMjggLyAzMiwKICAgICAgICAgICAgaXZTaXplOiA2NCAvIDMyCiAgICAgICAgICB9KTsKICAgICAgICAgIGZ1bmN0aW9uIG5leHRTdGF0ZSgpIHsKICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgIHZhciBYID0gdGhpcy5fWDsKICAgICAgICAgICAgdmFyIEMgPSB0aGlzLl9DOwoKICAgICAgICAgICAgLy8gU2F2ZSBvbGQgY291bnRlciB2YWx1ZXMKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHsKICAgICAgICAgICAgICBDX1tpXSA9IENbaV07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBuZXcgY291bnRlciB2YWx1ZXMKICAgICAgICAgICAgQ1swXSA9IENbMF0gKyAweDRkMzRkMzRkICsgdGhpcy5fYiB8IDA7CiAgICAgICAgICAgIENbMV0gPSBDWzFdICsgMHhkMzRkMzRkMyArIChDWzBdID4+PiAwIDwgQ19bMF0gPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICBDWzJdID0gQ1syXSArIDB4MzRkMzRkMzQgKyAoQ1sxXSA+Pj4gMCA8IENfWzFdID4+PiAwID8gMSA6IDApIHwgMDsKICAgICAgICAgICAgQ1szXSA9IENbM10gKyAweDRkMzRkMzRkICsgKENbMl0gPj4+IDAgPCBDX1syXSA+Pj4gMCA/IDEgOiAwKSB8IDA7CiAgICAgICAgICAgIENbNF0gPSBDWzRdICsgMHhkMzRkMzRkMyArIChDWzNdID4+PiAwIDwgQ19bM10gPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICBDWzVdID0gQ1s1XSArIDB4MzRkMzRkMzQgKyAoQ1s0XSA+Pj4gMCA8IENfWzRdID4+PiAwID8gMSA6IDApIHwgMDsKICAgICAgICAgICAgQ1s2XSA9IENbNl0gKyAweDRkMzRkMzRkICsgKENbNV0gPj4+IDAgPCBDX1s1XSA+Pj4gMCA/IDEgOiAwKSB8IDA7CiAgICAgICAgICAgIENbN10gPSBDWzddICsgMHhkMzRkMzRkMyArIChDWzZdID4+PiAwIDwgQ19bNl0gPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICB0aGlzLl9iID0gQ1s3XSA+Pj4gMCA8IENfWzddID4+PiAwID8gMSA6IDA7CgogICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGctdmFsdWVzCiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgODsgaSsrKSB7CiAgICAgICAgICAgICAgdmFyIGd4ID0gWFtpXSArIENbaV07CgogICAgICAgICAgICAgIC8vIENvbnN0cnVjdCBoaWdoIGFuZCBsb3cgYXJndW1lbnQgZm9yIHNxdWFyaW5nCiAgICAgICAgICAgICAgdmFyIGdhID0gZ3ggJiAweGZmZmY7CiAgICAgICAgICAgICAgdmFyIGdiID0gZ3ggPj4+IDE2OwoKICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgaGlnaCBhbmQgbG93IHJlc3VsdCBvZiBzcXVhcmluZwogICAgICAgICAgICAgIHZhciBnaCA9ICgoZ2EgKiBnYSA+Pj4gMTcpICsgZ2EgKiBnYiA+Pj4gMTUpICsgZ2IgKiBnYjsKICAgICAgICAgICAgICB2YXIgZ2wgPSAoKGd4ICYgMHhmZmZmMDAwMCkgKiBneCB8IDApICsgKChneCAmIDB4MDAwMGZmZmYpICogZ3ggfCAwKTsKCiAgICAgICAgICAgICAgLy8gSGlnaCBYT1IgbG93CiAgICAgICAgICAgICAgR1tpXSA9IGdoIF4gZ2w7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBuZXcgc3RhdGUgdmFsdWVzCiAgICAgICAgICAgIFhbMF0gPSBHWzBdICsgKEdbN10gPDwgMTYgfCBHWzddID4+PiAxNikgKyAoR1s2XSA8PCAxNiB8IEdbNl0gPj4+IDE2KSB8IDA7CiAgICAgICAgICAgIFhbMV0gPSBHWzFdICsgKEdbMF0gPDwgOCB8IEdbMF0gPj4+IDI0KSArIEdbN10gfCAwOwogICAgICAgICAgICBYWzJdID0gR1syXSArIChHWzFdIDw8IDE2IHwgR1sxXSA+Pj4gMTYpICsgKEdbMF0gPDwgMTYgfCBHWzBdID4+PiAxNikgfCAwOwogICAgICAgICAgICBYWzNdID0gR1szXSArIChHWzJdIDw8IDggfCBHWzJdID4+PiAyNCkgKyBHWzFdIHwgMDsKICAgICAgICAgICAgWFs0XSA9IEdbNF0gKyAoR1szXSA8PCAxNiB8IEdbM10gPj4+IDE2KSArIChHWzJdIDw8IDE2IHwgR1syXSA+Pj4gMTYpIHwgMDsKICAgICAgICAgICAgWFs1XSA9IEdbNV0gKyAoR1s0XSA8PCA4IHwgR1s0XSA+Pj4gMjQpICsgR1szXSB8IDA7CiAgICAgICAgICAgIFhbNl0gPSBHWzZdICsgKEdbNV0gPDwgMTYgfCBHWzVdID4+PiAxNikgKyAoR1s0XSA8PCAxNiB8IEdbNF0gPj4+IDE2KSB8IDA7CiAgICAgICAgICAgIFhbN10gPSBHWzddICsgKEdbNl0gPDwgOCB8IEdbNl0gPj4+IDI0KSArIEdbNV0gfCAwOwogICAgICAgICAgfQoKICAgICAgICAgIC8qKgogICAgICAgICAgICogU2hvcnRjdXQgZnVuY3Rpb25zIHRvIHRoZSBjaXBoZXIncyBvYmplY3QgaW50ZXJmYWNlLgogICAgICAgICAgICoKICAgICAgICAgICAqIEBleGFtcGxlCiAgICAgICAgICAgKgogICAgICAgICAgICogICAgIHZhciBjaXBoZXJ0ZXh0ID0gQ3J5cHRvSlMuUmFiYml0LmVuY3J5cHQobWVzc2FnZSwga2V5LCBjZmcpOwogICAgICAgICAgICogICAgIHZhciBwbGFpbnRleHQgID0gQ3J5cHRvSlMuUmFiYml0LmRlY3J5cHQoY2lwaGVydGV4dCwga2V5LCBjZmcpOwogICAgICAgICAgICovCiAgICAgICAgICBDLlJhYmJpdCA9IFN0cmVhbUNpcGhlci5fY3JlYXRlSGVscGVyKFJhYmJpdCk7CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMuUmFiYml0OwogICAgICB9KTsKICAgIH0pKHJhYmJpdCQxKTsKICAgIHJldHVybiByYWJiaXQkMS5leHBvcnRzOwogIH0KCiAgdmFyIHJhYmJpdExlZ2FjeSQxID0ge2V4cG9ydHM6IHt9fTsKCiAgdmFyIHJhYmJpdExlZ2FjeSA9IHJhYmJpdExlZ2FjeSQxLmV4cG9ydHM7CiAgdmFyIGhhc1JlcXVpcmVkUmFiYml0TGVnYWN5OwogIGZ1bmN0aW9uIHJlcXVpcmVSYWJiaXRMZWdhY3koKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRSYWJiaXRMZWdhY3kpIHJldHVybiByYWJiaXRMZWdhY3kkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRSYWJiaXRMZWdhY3kgPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlRW5jQmFzZTY0KCksIHJlcXVpcmVNZDUoKSwgcmVxdWlyZUV2cGtkZigpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKHJhYmJpdExlZ2FjeSwgZnVuY3Rpb24gKENyeXB0b0pTKSB7CiAgICAgICAgKGZ1bmN0aW9uICgpIHsKICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgdmFyIEMgPSBDcnlwdG9KUzsKICAgICAgICAgIHZhciBDX2xpYiA9IEMubGliOwogICAgICAgICAgdmFyIFN0cmVhbUNpcGhlciA9IENfbGliLlN0cmVhbUNpcGhlcjsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CgogICAgICAgICAgLy8gUmV1c2FibGUgb2JqZWN0cwogICAgICAgICAgdmFyIFMgPSBbXTsKICAgICAgICAgIHZhciBDXyA9IFtdOwogICAgICAgICAgdmFyIEcgPSBbXTsKCiAgICAgICAgICAvKioKICAgICAgICAgICAqIFJhYmJpdCBzdHJlYW0gY2lwaGVyIGFsZ29yaXRobS4KICAgICAgICAgICAqCiAgICAgICAgICAgKiBUaGlzIGlzIGEgbGVnYWN5IHZlcnNpb24gdGhhdCBuZWdsZWN0ZWQgdG8gY29udmVydCB0aGUga2V5IHRvIGxpdHRsZS1lbmRpYW4uCiAgICAgICAgICAgKiBUaGlzIGVycm9yIGRvZXNuJ3QgYWZmZWN0IHRoZSBjaXBoZXIncyBzZWN1cml0eSwKICAgICAgICAgICAqIGJ1dCBpdCBkb2VzIGFmZmVjdCBpdHMgY29tcGF0aWJpbGl0eSB3aXRoIG90aGVyIGltcGxlbWVudGF0aW9ucy4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIFJhYmJpdExlZ2FjeSA9IENfYWxnby5SYWJiaXRMZWdhY3kgPSBTdHJlYW1DaXBoZXIuZXh0ZW5kKHsKICAgICAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgICB2YXIgSyA9IHRoaXMuX2tleS53b3JkczsKICAgICAgICAgICAgICB2YXIgaXYgPSB0aGlzLmNmZy5pdjsKCiAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgaW5pdGlhbCBzdGF0ZSB2YWx1ZXMKICAgICAgICAgICAgICB2YXIgWCA9IHRoaXMuX1ggPSBbS1swXSwgS1szXSA8PCAxNiB8IEtbMl0gPj4+IDE2LCBLWzFdLCBLWzBdIDw8IDE2IHwgS1szXSA+Pj4gMTYsIEtbMl0sIEtbMV0gPDwgMTYgfCBLWzBdID4+PiAxNiwgS1szXSwgS1syXSA8PCAxNiB8IEtbMV0gPj4+IDE2XTsKCiAgICAgICAgICAgICAgLy8gR2VuZXJhdGUgaW5pdGlhbCBjb3VudGVyIHZhbHVlcwogICAgICAgICAgICAgIHZhciBDID0gdGhpcy5fQyA9IFtLWzJdIDw8IDE2IHwgS1syXSA+Pj4gMTYsIEtbMF0gJiAweGZmZmYwMDAwIHwgS1sxXSAmIDB4MDAwMGZmZmYsIEtbM10gPDwgMTYgfCBLWzNdID4+PiAxNiwgS1sxXSAmIDB4ZmZmZjAwMDAgfCBLWzJdICYgMHgwMDAwZmZmZiwgS1swXSA8PCAxNiB8IEtbMF0gPj4+IDE2LCBLWzJdICYgMHhmZmZmMDAwMCB8IEtbM10gJiAweDAwMDBmZmZmLCBLWzFdIDw8IDE2IHwgS1sxXSA+Pj4gMTYsIEtbM10gJiAweGZmZmYwMDAwIHwgS1swXSAmIDB4MDAwMGZmZmZdOwoKICAgICAgICAgICAgICAvLyBDYXJyeSBiaXQKICAgICAgICAgICAgICB0aGlzLl9iID0gMDsKCiAgICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aGUgc3lzdGVtIGZvdXIgdGltZXMKICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykgewogICAgICAgICAgICAgICAgbmV4dFN0YXRlLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAvLyBNb2RpZnkgdGhlIGNvdW50ZXJzCiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHsKICAgICAgICAgICAgICAgIENbaV0gXj0gWFtpICsgNCAmIDddOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gSVYgc2V0dXAKICAgICAgICAgICAgICBpZiAoaXYpIHsKICAgICAgICAgICAgICAgIC8vIFNob3J0Y3V0cwogICAgICAgICAgICAgICAgdmFyIElWID0gaXYud29yZHM7CiAgICAgICAgICAgICAgICB2YXIgSVZfMCA9IElWWzBdOwogICAgICAgICAgICAgICAgdmFyIElWXzEgPSBJVlsxXTsKCiAgICAgICAgICAgICAgICAvLyBHZW5lcmF0ZSBmb3VyIHN1YnZlY3RvcnMKICAgICAgICAgICAgICAgIHZhciBpMCA9IChJVl8wIDw8IDggfCBJVl8wID4+PiAyNCkgJiAweDAwZmYwMGZmIHwgKElWXzAgPDwgMjQgfCBJVl8wID4+PiA4KSAmIDB4ZmYwMGZmMDA7CiAgICAgICAgICAgICAgICB2YXIgaTIgPSAoSVZfMSA8PCA4IHwgSVZfMSA+Pj4gMjQpICYgMHgwMGZmMDBmZiB8IChJVl8xIDw8IDI0IHwgSVZfMSA+Pj4gOCkgJiAweGZmMDBmZjAwOwogICAgICAgICAgICAgICAgdmFyIGkxID0gaTAgPj4+IDE2IHwgaTIgJiAweGZmZmYwMDAwOwogICAgICAgICAgICAgICAgdmFyIGkzID0gaTIgPDwgMTYgfCBpMCAmIDB4MDAwMGZmZmY7CgogICAgICAgICAgICAgICAgLy8gTW9kaWZ5IGNvdW50ZXIgdmFsdWVzCiAgICAgICAgICAgICAgICBDWzBdIF49IGkwOwogICAgICAgICAgICAgICAgQ1sxXSBePSBpMTsKICAgICAgICAgICAgICAgIENbMl0gXj0gaTI7CiAgICAgICAgICAgICAgICBDWzNdIF49IGkzOwogICAgICAgICAgICAgICAgQ1s0XSBePSBpMDsKICAgICAgICAgICAgICAgIENbNV0gXj0gaTE7CiAgICAgICAgICAgICAgICBDWzZdIF49IGkyOwogICAgICAgICAgICAgICAgQ1s3XSBePSBpMzsKCiAgICAgICAgICAgICAgICAvLyBJdGVyYXRlIHRoZSBzeXN0ZW0gZm91ciB0aW1lcwogICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgICAgICAgICAgICAgICAgbmV4dFN0YXRlLmNhbGwodGhpcyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBfZG9Qcm9jZXNzQmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICAvLyBTaG9ydGN1dAogICAgICAgICAgICAgIHZhciBYID0gdGhpcy5fWDsKCiAgICAgICAgICAgICAgLy8gSXRlcmF0ZSB0aGUgc3lzdGVtCiAgICAgICAgICAgICAgbmV4dFN0YXRlLmNhbGwodGhpcyk7CgogICAgICAgICAgICAgIC8vIEdlbmVyYXRlIGZvdXIga2V5c3RyZWFtIHdvcmRzCiAgICAgICAgICAgICAgU1swXSA9IFhbMF0gXiBYWzVdID4+PiAxNiBeIFhbM10gPDwgMTY7CiAgICAgICAgICAgICAgU1sxXSA9IFhbMl0gXiBYWzddID4+PiAxNiBeIFhbNV0gPDwgMTY7CiAgICAgICAgICAgICAgU1syXSA9IFhbNF0gXiBYWzFdID4+PiAxNiBeIFhbN10gPDwgMTY7CiAgICAgICAgICAgICAgU1szXSA9IFhbNl0gXiBYWzNdID4+PiAxNiBeIFhbMV0gPDwgMTY7CiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OyBpKyspIHsKICAgICAgICAgICAgICAgIC8vIFN3YXAgZW5kaWFuCiAgICAgICAgICAgICAgICBTW2ldID0gKFNbaV0gPDwgOCB8IFNbaV0gPj4+IDI0KSAmIDB4MDBmZjAwZmYgfCAoU1tpXSA8PCAyNCB8IFNbaV0gPj4+IDgpICYgMHhmZjAwZmYwMDsKCiAgICAgICAgICAgICAgICAvLyBFbmNyeXB0CiAgICAgICAgICAgICAgICBNW29mZnNldCArIGldIF49IFNbaV07CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LAogICAgICAgICAgICBibG9ja1NpemU6IDEyOCAvIDMyLAogICAgICAgICAgICBpdlNpemU6IDY0IC8gMzIKICAgICAgICAgIH0pOwogICAgICAgICAgZnVuY3Rpb24gbmV4dFN0YXRlKCkgewogICAgICAgICAgICAvLyBTaG9ydGN1dHMKICAgICAgICAgICAgdmFyIFggPSB0aGlzLl9YOwogICAgICAgICAgICB2YXIgQyA9IHRoaXMuX0M7CgogICAgICAgICAgICAvLyBTYXZlIG9sZCBjb3VudGVyIHZhbHVlcwogICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDg7IGkrKykgewogICAgICAgICAgICAgIENfW2ldID0gQ1tpXTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBjb3VudGVyIHZhbHVlcwogICAgICAgICAgICBDWzBdID0gQ1swXSArIDB4NGQzNGQzNGQgKyB0aGlzLl9iIHwgMDsKICAgICAgICAgICAgQ1sxXSA9IENbMV0gKyAweGQzNGQzNGQzICsgKENbMF0gPj4+IDAgPCBDX1swXSA+Pj4gMCA/IDEgOiAwKSB8IDA7CiAgICAgICAgICAgIENbMl0gPSBDWzJdICsgMHgzNGQzNGQzNCArIChDWzFdID4+PiAwIDwgQ19bMV0gPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICBDWzNdID0gQ1szXSArIDB4NGQzNGQzNGQgKyAoQ1syXSA+Pj4gMCA8IENfWzJdID4+PiAwID8gMSA6IDApIHwgMDsKICAgICAgICAgICAgQ1s0XSA9IENbNF0gKyAweGQzNGQzNGQzICsgKENbM10gPj4+IDAgPCBDX1szXSA+Pj4gMCA/IDEgOiAwKSB8IDA7CiAgICAgICAgICAgIENbNV0gPSBDWzVdICsgMHgzNGQzNGQzNCArIChDWzRdID4+PiAwIDwgQ19bNF0gPj4+IDAgPyAxIDogMCkgfCAwOwogICAgICAgICAgICBDWzZdID0gQ1s2XSArIDB4NGQzNGQzNGQgKyAoQ1s1XSA+Pj4gMCA8IENfWzVdID4+PiAwID8gMSA6IDApIHwgMDsKICAgICAgICAgICAgQ1s3XSA9IENbN10gKyAweGQzNGQzNGQzICsgKENbNl0gPj4+IDAgPCBDX1s2XSA+Pj4gMCA/IDEgOiAwKSB8IDA7CiAgICAgICAgICAgIHRoaXMuX2IgPSBDWzddID4+PiAwIDwgQ19bN10gPj4+IDAgPyAxIDogMDsKCiAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgZy12YWx1ZXMKICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA4OyBpKyspIHsKICAgICAgICAgICAgICB2YXIgZ3ggPSBYW2ldICsgQ1tpXTsKCiAgICAgICAgICAgICAgLy8gQ29uc3RydWN0IGhpZ2ggYW5kIGxvdyBhcmd1bWVudCBmb3Igc3F1YXJpbmcKICAgICAgICAgICAgICB2YXIgZ2EgPSBneCAmIDB4ZmZmZjsKICAgICAgICAgICAgICB2YXIgZ2IgPSBneCA+Pj4gMTY7CgogICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSBoaWdoIGFuZCBsb3cgcmVzdWx0IG9mIHNxdWFyaW5nCiAgICAgICAgICAgICAgdmFyIGdoID0gKChnYSAqIGdhID4+PiAxNykgKyBnYSAqIGdiID4+PiAxNSkgKyBnYiAqIGdiOwogICAgICAgICAgICAgIHZhciBnbCA9ICgoZ3ggJiAweGZmZmYwMDAwKSAqIGd4IHwgMCkgKyAoKGd4ICYgMHgwMDAwZmZmZikgKiBneCB8IDApOwoKICAgICAgICAgICAgICAvLyBIaWdoIFhPUiBsb3cKICAgICAgICAgICAgICBHW2ldID0gZ2ggXiBnbDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIG5ldyBzdGF0ZSB2YWx1ZXMKICAgICAgICAgICAgWFswXSA9IEdbMF0gKyAoR1s3XSA8PCAxNiB8IEdbN10gPj4+IDE2KSArIChHWzZdIDw8IDE2IHwgR1s2XSA+Pj4gMTYpIHwgMDsKICAgICAgICAgICAgWFsxXSA9IEdbMV0gKyAoR1swXSA8PCA4IHwgR1swXSA+Pj4gMjQpICsgR1s3XSB8IDA7CiAgICAgICAgICAgIFhbMl0gPSBHWzJdICsgKEdbMV0gPDwgMTYgfCBHWzFdID4+PiAxNikgKyAoR1swXSA8PCAxNiB8IEdbMF0gPj4+IDE2KSB8IDA7CiAgICAgICAgICAgIFhbM10gPSBHWzNdICsgKEdbMl0gPDwgOCB8IEdbMl0gPj4+IDI0KSArIEdbMV0gfCAwOwogICAgICAgICAgICBYWzRdID0gR1s0XSArIChHWzNdIDw8IDE2IHwgR1szXSA+Pj4gMTYpICsgKEdbMl0gPDwgMTYgfCBHWzJdID4+PiAxNikgfCAwOwogICAgICAgICAgICBYWzVdID0gR1s1XSArIChHWzRdIDw8IDggfCBHWzRdID4+PiAyNCkgKyBHWzNdIHwgMDsKICAgICAgICAgICAgWFs2XSA9IEdbNl0gKyAoR1s1XSA8PCAxNiB8IEdbNV0gPj4+IDE2KSArIChHWzRdIDw8IDE2IHwgR1s0XSA+Pj4gMTYpIHwgMDsKICAgICAgICAgICAgWFs3XSA9IEdbN10gKyAoR1s2XSA8PCA4IHwgR1s2XSA+Pj4gMjQpICsgR1s1XSB8IDA7CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5SYWJiaXRMZWdhY3kuZW5jcnlwdChtZXNzYWdlLCBrZXksIGNmZyk7CiAgICAgICAgICAgKiAgICAgdmFyIHBsYWludGV4dCAgPSBDcnlwdG9KUy5SYWJiaXRMZWdhY3kuZGVjcnlwdChjaXBoZXJ0ZXh0LCBrZXksIGNmZyk7CiAgICAgICAgICAgKi8KICAgICAgICAgIEMuUmFiYml0TGVnYWN5ID0gU3RyZWFtQ2lwaGVyLl9jcmVhdGVIZWxwZXIoUmFiYml0TGVnYWN5KTsKICAgICAgICB9KSgpOwogICAgICAgIHJldHVybiBDcnlwdG9KUy5SYWJiaXRMZWdhY3k7CiAgICAgIH0pOwogICAgfSkocmFiYml0TGVnYWN5JDEpOwogICAgcmV0dXJuIHJhYmJpdExlZ2FjeSQxLmV4cG9ydHM7CiAgfQoKICB2YXIgYmxvd2Zpc2gkMSA9IHtleHBvcnRzOiB7fX07CgogIHZhciBibG93ZmlzaCA9IGJsb3dmaXNoJDEuZXhwb3J0czsKICB2YXIgaGFzUmVxdWlyZWRCbG93ZmlzaDsKICBmdW5jdGlvbiByZXF1aXJlQmxvd2Zpc2goKSB7CiAgICBpZiAoaGFzUmVxdWlyZWRCbG93ZmlzaCkgcmV0dXJuIGJsb3dmaXNoJDEuZXhwb3J0czsKICAgIGhhc1JlcXVpcmVkQmxvd2Zpc2ggPSAxOwogICAgKGZ1bmN0aW9uIChtb2R1bGUsIGV4cG9ydHMkMSkgewogICAgICAoZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnksIHVuZGVmKSB7CiAgICAgICAgewogICAgICAgICAgLy8gQ29tbW9uSlMKICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlQ29yZSgpLCByZXF1aXJlRW5jQmFzZTY0KCksIHJlcXVpcmVNZDUoKSwgcmVxdWlyZUV2cGtkZigpLCByZXF1aXJlQ2lwaGVyQ29yZSgpKTsKICAgICAgICB9CiAgICAgIH0pKGJsb3dmaXNoLCBmdW5jdGlvbiAoQ3J5cHRvSlMpIHsKICAgICAgICAoZnVuY3Rpb24gKCkgewogICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICB2YXIgQyA9IENyeXB0b0pTOwogICAgICAgICAgdmFyIENfbGliID0gQy5saWI7CiAgICAgICAgICB2YXIgQmxvY2tDaXBoZXIgPSBDX2xpYi5CbG9ja0NpcGhlcjsKICAgICAgICAgIHZhciBDX2FsZ28gPSBDLmFsZ287CiAgICAgICAgICBjb25zdCBOID0gMTY7CgogICAgICAgICAgLy9PcmlnaW4gcGJveCBhbmQgc2JveCwgZGVyaXZlZCBmcm9tIFBJCiAgICAgICAgICBjb25zdCBPUklHX1AgPSBbMHgyNDNGNkE4OCwgMHg4NUEzMDhEMywgMHgxMzE5OEEyRSwgMHgwMzcwNzM0NCwgMHhBNDA5MzgyMiwgMHgyOTlGMzFEMCwgMHgwODJFRkE5OCwgMHhFQzRFNkM4OSwgMHg0NTI4MjFFNiwgMHgzOEQwMTM3NywgMHhCRTU0NjZDRiwgMHgzNEU5MEM2QywgMHhDMEFDMjlCNywgMHhDOTdDNTBERCwgMHgzRjg0RDVCNSwgMHhCNTQ3MDkxNywgMHg5MjE2RDVEOSwgMHg4OTc5RkIxQl07CiAgICAgICAgICBjb25zdCBPUklHX1MgPSBbWzB4RDEzMTBCQTYsIDB4OThERkI1QUMsIDB4MkZGRDcyREIsIDB4RDAxQURGQjcsIDB4QjhFMUFGRUQsIDB4NkEyNjdFOTYsIDB4QkE3QzkwNDUsIDB4RjEyQzdGOTksIDB4MjRBMTk5NDcsIDB4QjM5MTZDRjcsIDB4MDgwMUYyRTIsIDB4ODU4RUZDMTYsIDB4NjM2OTIwRDgsIDB4NzE1NzRFNjksIDB4QTQ1OEZFQTMsIDB4RjQ5MzNEN0UsIDB4MEQ5NTc0OEYsIDB4NzI4RUI2NTgsIDB4NzE4QkNENTgsIDB4ODIxNTRBRUUsIDB4N0I1NEE0MUQsIDB4QzI1QTU5QjUsIDB4OUMzMEQ1MzksIDB4MkFGMjYwMTMsIDB4QzVEMUIwMjMsIDB4Mjg2MDg1RjAsIDB4Q0E0MTc5MTgsIDB4QjhEQjM4RUYsIDB4OEU3OURDQjAsIDB4NjAzQTE4MEUsIDB4NkM5RTBFOEIsIDB4QjAxRThBM0UsIDB4RDcxNTc3QzEsIDB4QkQzMTRCMjcsIDB4NzhBRjJGREEsIDB4NTU2MDVDNjAsIDB4RTY1NTI1RjMsIDB4QUE1NUFCOTQsIDB4NTc0ODk4NjIsIDB4NjNFODE0NDAsIDB4NTVDQTM5NkEsIDB4MkFBQjEwQjYsIDB4QjRDQzVDMzQsIDB4MTE0MUU4Q0UsIDB4QTE1NDg2QUYsIDB4N0M3MkU5OTMsIDB4QjNFRTE0MTEsIDB4NjM2RkJDMkEsIDB4MkJBOUM1NUQsIDB4NzQxODMxRjYsIDB4Q0U1QzNFMTYsIDB4OUI4NzkzMUUsIDB4QUZENkJBMzMsIDB4NkMyNENGNUMsIDB4N0EzMjUzODEsIDB4Mjg5NTg2NzcsIDB4M0I4RjQ4OTgsIDB4NkI0QkI5QUYsIDB4QzRCRkU4MUIsIDB4NjYyODIxOTMsIDB4NjFEODA5Q0MsIDB4RkIyMUE5OTEsIDB4NDg3Q0FDNjAsIDB4NURFQzgwMzIsIDB4RUY4NDVENUQsIDB4RTk4NTc1QjEsIDB4REMyNjIzMDIsIDB4RUI2NTFCODgsIDB4MjM4OTNFODEsIDB4RDM5NkFDQzUsIDB4MEY2RDZGRjMsIDB4ODNGNDQyMzksIDB4MkUwQjQ0ODIsIDB4QTQ4NDIwMDQsIDB4NjlDOEYwNEEsIDB4OUUxRjlCNUUsIDB4MjFDNjY4NDIsIDB4RjZFOTZDOUEsIDB4NjcwQzlDNjEsIDB4QUJEMzg4RjAsIDB4NkE1MUEwRDIsIDB4RDg1NDJGNjgsIDB4OTYwRkE3MjgsIDB4QUI1MTMzQTMsIDB4NkVFRjBCNkMsIDB4MTM3QTNCRTQsIDB4QkEzQkYwNTAsIDB4N0VGQjJBOTgsIDB4QTFGMTY1MUQsIDB4MzlBRjAxNzYsIDB4NjZDQTU5M0UsIDB4ODI0MzBFODgsIDB4OENFRTg2MTksIDB4NDU2RjlGQjQsIDB4N0Q4NEE1QzMsIDB4M0I4QjVFQkUsIDB4RTA2Rjc1RDgsIDB4ODVDMTIwNzMsIDB4NDAxQTQ0OUYsIDB4NTZDMTZBQTYsIDB4NEVEM0FBNjIsIDB4MzYzRjc3MDYsIDB4MUJGRURGNzIsIDB4NDI5QjAyM0QsIDB4MzdEMEQ3MjQsIDB4RDAwQTEyNDgsIDB4REIwRkVBRDMsIDB4NDlGMUMwOUIsIDB4MDc1MzcyQzksIDB4ODA5OTFCN0IsIDB4MjVENDc5RDgsIDB4RjZFOERFRjcsIDB4RTNGRTUwMUEsIDB4QjY3OTRDM0IsIDB4OTc2Q0UwQkQsIDB4MDRDMDA2QkEsIDB4QzFBOTRGQjYsIDB4NDA5RjYwQzQsIDB4NUU1QzlFQzIsIDB4MTk2QTI0NjMsIDB4NjhGQjZGQUYsIDB4M0U2QzUzQjUsIDB4MTMzOUIyRUIsIDB4M0I1MkVDNkYsIDB4NkRGQzUxMUYsIDB4OUIzMDk1MkMsIDB4Q0M4MTQ1NDQsIDB4QUY1RUJEMDksIDB4QkVFM0QwMDQsIDB4REUzMzRBRkQsIDB4NjYwRjI4MDcsIDB4MTkyRTRCQjMsIDB4QzBDQkE4NTcsIDB4NDVDODc0MEYsIDB4RDIwQjVGMzksIDB4QjlEM0ZCREIsIDB4NTU3OUMwQkQsIDB4MUE2MDMyMEEsIDB4RDZBMTAwQzYsIDB4NDAyQzcyNzksIDB4Njc5RjI1RkUsIDB4RkIxRkEzQ0MsIDB4OEVBNUU5RjgsIDB4REIzMjIyRjgsIDB4M0M3NTE2REYsIDB4RkQ2MTZCMTUsIDB4MkY1MDFFQzgsIDB4QUQwNTUyQUIsIDB4MzIzREI1RkEsIDB4RkQyMzg3NjAsIDB4NTMzMTdCNDgsIDB4M0UwMERGODIsIDB4OUU1QzU3QkIsIDB4Q0E2RjhDQTAsIDB4MUE4NzU2MkUsIDB4REYxNzY5REIsIDB4RDU0MkE4RjYsIDB4Mjg3RUZGQzMsIDB4QUM2NzMyQzYsIDB4OEM0RjU1NzMsIDB4Njk1QjI3QjAsIDB4QkJDQTU4QzgsIDB4RTFGRkEzNUQsIDB4QjhGMDExQTAsIDB4MTBGQTNEOTgsIDB4RkQyMTgzQjgsIDB4NEFGQ0I1NkMsIDB4MkREMUQzNUIsIDB4OUE1M0U0NzksIDB4QjZGODQ1NjUsIDB4RDI4RTQ5QkMsIDB4NEJGQjk3OTAsIDB4RTFEREYyREEsIDB4QTRDQjdFMzMsIDB4NjJGQjEzNDEsIDB4Q0VFNEM2RTgsIDB4RUYyMENBREEsIDB4MzY3NzRDMDEsIDB4RDA3RTlFRkUsIDB4MkJGMTFGQjQsIDB4OTVEQkRBNEQsIDB4QUU5MDkxOTgsIDB4RUFBRDhFNzEsIDB4NkI5M0Q1QTAsIDB4RDA4RUQxRDAsIDB4QUZDNzI1RTAsIDB4OEUzQzVCMkYsIDB4OEU3NTk0QjcsIDB4OEZGNkUyRkIsIDB4RjIxMjJCNjQsIDB4ODg4OEI4MTIsIDB4OTAwREYwMUMsIDB4NEZBRDVFQTAsIDB4Njg4RkMzMUMsIDB4RDFDRkYxOTEsIDB4QjNBOEMxQUQsIDB4MkYyRjIyMTgsIDB4QkUwRTE3NzcsIDB4RUE3NTJERkUsIDB4OEIwMjFGQTEsIDB4RTVBMENDMEYsIDB4QjU2Rjc0RTgsIDB4MThBQ0YzRDYsIDB4Q0U4OUUyOTksIDB4QjRBODRGRTAsIDB4RkQxM0UwQjcsIDB4N0NDNDNCODEsIDB4RDJBREE4RDksIDB4MTY1RkEyNjYsIDB4ODA5NTc3MDUsIDB4OTNDQzczMTQsIDB4MjExQTE0NzcsIDB4RTZBRDIwNjUsIDB4NzdCNUZBODYsIDB4Qzc1NDQyRjUsIDB4RkI5RDM1Q0YsIDB4RUJDREFGMEMsIDB4N0IzRTg5QTAsIDB4RDY0MTFCRDMsIDB4QUUxRTdFNDksIDB4MDAyNTBFMkQsIDB4MjA3MUIzNUUsIDB4MjI2ODAwQkIsIDB4NTdCOEUwQUYsIDB4MjQ2NDM2OUIsIDB4RjAwOUI5MUUsIDB4NTU2MzkxMUQsIDB4NTlERkE2QUEsIDB4NzhDMTQzODksIDB4RDk1QTUzN0YsIDB4MjA3RDVCQTIsIDB4MDJFNUI5QzUsIDB4ODMyNjAzNzYsIDB4NjI5NUNGQTksIDB4MTFDODE5NjgsIDB4NEU3MzRBNDEsIDB4QjM0NzJEQ0EsIDB4N0IxNEE5NEEsIDB4MUI1MTAwNTIsIDB4OUE1MzI5MTUsIDB4RDYwRjU3M0YsIDB4QkM5QkM2RTQsIDB4MkI2MEE0NzYsIDB4ODFFNjc0MDAsIDB4MDhCQTZGQjUsIDB4NTcxQkU5MUYsIDB4RjI5NkVDNkIsIDB4MkEwREQ5MTUsIDB4QjY2MzY1MjEsIDB4RTdCOUY5QjYsIDB4RkYzNDA1MkUsIDB4QzU4NTU2NjQsIDB4NTNCMDJENUQsIDB4QTk5RjhGQTEsIDB4MDhCQTQ3OTksIDB4NkU4NTA3NkFdLCBbMHg0QjdBNzBFOSwgMHhCNUIzMjk0NCwgMHhEQjc1MDkyRSwgMHhDNDE5MjYyMywgMHhBRDZFQTZCMCwgMHg0OUE3REY3RCwgMHg5Q0VFNjBCOCwgMHg4RkVEQjI2NiwgMHhFQ0FBOEM3MSwgMHg2OTlBMTdGRiwgMHg1NjY0NTI2QywgMHhDMkIxOUVFMSwgMHgxOTM2MDJBNSwgMHg3NTA5NEMyOSwgMHhBMDU5MTM0MCwgMHhFNDE4M0EzRSwgMHgzRjU0OTg5QSwgMHg1QjQyOUQ2NSwgMHg2QjhGRTRENiwgMHg5OUY3M0ZENiwgMHhBMUQyOUMwNywgMHhFRkU4MzBGNSwgMHg0RDJEMzhFNiwgMHhGMDI1NURDMSwgMHg0Q0REMjA4NiwgMHg4NDcwRUIyNiwgMHg2MzgyRTlDNiwgMHgwMjFFQ0M1RSwgMHgwOTY4NkIzRiwgMHgzRUJBRUZDOSwgMHgzQzk3MTgxNCwgMHg2QjZBNzBBMSwgMHg2ODdGMzU4NCwgMHg1MkEwRTI4NiwgMHhCNzlDNTMwNSwgMHhBQTUwMDczNywgMHgzRTA3ODQxQywgMHg3RkRFQUU1QywgMHg4RTdENDRFQywgMHg1NzE2RjJCOCwgMHhCMDNBREEzNywgMHhGMDUwMEMwRCwgMHhGMDFDMUYwNCwgMHgwMjAwQjNGRiwgMHhBRTBDRjUxQSwgMHgzQ0I1NzRCMiwgMHgyNTgzN0E1OCwgMHhEQzA5MjFCRCwgMHhEMTkxMTNGOSwgMHg3Q0E5MkZGNiwgMHg5NDMyNDc3MywgMHgyMkY1NDcwMSwgMHgzQUU1RTU4MSwgMHgzN0MyREFEQywgMHhDOEI1NzYzNCwgMHg5QUYzRERBNywgMHhBOTQ0NjE0NiwgMHgwRkQwMDMwRSwgMHhFQ0M4QzczRSwgMHhBNDc1MUU0MSwgMHhFMjM4Q0Q5OSwgMHgzQkVBMEUyRiwgMHgzMjgwQkJBMSwgMHgxODNFQjMzMSwgMHg0RTU0OEIzOCwgMHg0RjZEQjkwOCwgMHg2RjQyMEQwMywgMHhGNjBBMDRCRiwgMHgyQ0I4MTI5MCwgMHgyNDk3N0M3OSwgMHg1Njc5QjA3MiwgMHhCQ0FGODlBRiwgMHhERTlBNzcxRiwgMHhEOTkzMDgxMCwgMHhCMzhCQUUxMiwgMHhEQ0NGM0YyRSwgMHg1NTEyNzIxRiwgMHgyRTZCNzEyNCwgMHg1MDFBRERFNiwgMHg5Rjg0Q0Q4NywgMHg3QTU4NDcxOCwgMHg3NDA4REExNywgMHhCQzlGOUFCQywgMHhFOTRCN0Q4QywgMHhFQzdBRUMzQSwgMHhEQjg1MURGQSwgMHg2MzA5NDM2NiwgMHhDNDY0QzNEMiwgMHhFRjFDMTg0NywgMHgzMjE1RDkwOCwgMHhERDQzM0IzNywgMHgyNEMyQkExNiwgMHgxMkExNEQ0MywgMHgyQTY1QzQ1MSwgMHg1MDk0MDAwMiwgMHgxMzNBRTRERCwgMHg3MURGRjg5RSwgMHgxMDMxNEU1NSwgMHg4MUFDNzdENiwgMHg1RjExMTk5QiwgMHgwNDM1NTZGMSwgMHhEN0EzQzc2QiwgMHgzQzExMTgzQiwgMHg1OTI0QTUwOSwgMHhGMjhGRTZFRCwgMHg5N0YxRkJGQSwgMHg5RUJBQkYyQywgMHgxRTE1M0M2RSwgMHg4NkUzNDU3MCwgMHhFQUU5NkZCMSwgMHg4NjBFNUUwQSwgMHg1QTNFMkFCMywgMHg3NzFGRTcxQywgMHg0RTNEMDZGQSwgMHgyOTY1RENCOSwgMHg5OUU3MUQwRiwgMHg4MDNFODlENiwgMHg1MjY2QzgyNSwgMHgyRTRDQzk3OCwgMHg5QzEwQjM2QSwgMHhDNjE1MEVCQSwgMHg5NEUyRUE3OCwgMHhBNUZDM0M1MywgMHgxRTBBMkRGNCwgMHhGMkY3NEVBNywgMHgzNjFEMkIzRCwgMHgxOTM5MjYwRiwgMHgxOUMyNzk2MCwgMHg1MjIzQTcwOCwgMHhGNzEzMTJCNiwgMHhFQkFERkU2RSwgMHhFQUMzMUY2NiwgMHhFM0JDNDU5NSwgMHhBNjdCQzg4MywgMHhCMTdGMzdEMSwgMHgwMThDRkYyOCwgMHhDMzMyRERFRiwgMHhCRTZDNUFBNSwgMHg2NTU4MjE4NSwgMHg2OEFCOTgwMiwgMHhFRUNFQTUwRiwgMHhEQjJGOTUzQiwgMHgyQUVGN0RBRCwgMHg1QjZFMkY4NCwgMHgxNTIxQjYyOCwgMHgyOTA3NjE3MCwgMHhFQ0RENDc3NSwgMHg2MTlGMTUxMCwgMHgxM0NDQTgzMCwgMHhFQjYxQkQ5NiwgMHgwMzM0RkUxRSwgMHhBQTAzNjNDRiwgMHhCNTczNUM5MCwgMHg0QzcwQTIzOSwgMHhENTlFOUUwQiwgMHhDQkFBREUxNCwgMHhFRUNDODZCQywgMHg2MDYyMkNBNywgMHg5Q0FCNUNBQiwgMHhCMkYzODQ2RSwgMHg2NDhCMUVBRiwgMHgxOUJERjBDQSwgMHhBMDIzNjlCOSwgMHg2NTVBQkI1MCwgMHg0MDY4NUEzMiwgMHgzQzJBQjRCMywgMHgzMTlFRTlENSwgMHhDMDIxQjhGNywgMHg5QjU0MEIxOSwgMHg4NzVGQTA5OSwgMHg5NUY3OTk3RSwgMHg2MjNEN0RBOCwgMHhGODM3ODg5QSwgMHg5N0UzMkQ3NywgMHgxMUVEOTM1RiwgMHgxNjY4MTI4MSwgMHgwRTM1ODgyOSwgMHhDN0U2MUZENiwgMHg5NkRFREZBMSwgMHg3ODU4QkE5OSwgMHg1N0Y1ODRBNSwgMHgxQjIyNzI2MywgMHg5QjgzQzNGRiwgMHgxQUMyNDY5NiwgMHhDREIzMEFFQiwgMHg1MzJFMzA1NCwgMHg4RkQ5NDhFNCwgMHg2REJDMzEyOCwgMHg1OEVCRjJFRiwgMHgzNEM2RkZFQSwgMHhGRTI4RUQ2MSwgMHhFRTdDM0M3MywgMHg1RDRBMTREOSwgMHhFODY0QjdFMywgMHg0MjEwNUQxNCwgMHgyMDNFMTNFMCwgMHg0NUVFRTJCNiwgMHhBM0FBQUJFQSwgMHhEQjZDNEYxNSwgMHhGQUNCNEZEMCwgMHhDNzQyRjQ0MiwgMHhFRjZBQkJCNSwgMHg2NTRGM0IxRCwgMHg0MUNEMjEwNSwgMHhEODFFNzk5RSwgMHg4Njg1NERDNywgMHhFNDRCNDc2QSwgMHgzRDgxNjI1MCwgMHhDRjYyQTFGMiwgMHg1QjhEMjY0NiwgMHhGQzg4ODNBMCwgMHhDMUM3QjZBMywgMHg3RjE1MjRDMywgMHg2OUNCNzQ5MiwgMHg0Nzg0OEEwQiwgMHg1NjkyQjI4NSwgMHgwOTVCQkYwMCwgMHhBRDE5NDg5RCwgMHgxNDYyQjE3NCwgMHgyMzgyMEUwMCwgMHg1ODQyOEQyQSwgMHgwQzU1RjVFQSwgMHgxREFERjQzRSwgMHgyMzNGNzA2MSwgMHgzMzcyRjA5MiwgMHg4RDkzN0U0MSwgMHhENjVGRUNGMSwgMHg2QzIyM0JEQiwgMHg3Q0RFMzc1OSwgMHhDQkVFNzQ2MCwgMHg0MDg1RjJBNywgMHhDRTc3MzI2RSwgMHhBNjA3ODA4NCwgMHgxOUY4NTA5RSwgMHhFOEVGRDg1NSwgMHg2MUQ5OTczNSwgMHhBOTY5QTdBQSwgMHhDNTBDMDZDMiwgMHg1QTA0QUJGQywgMHg4MDBCQ0FEQywgMHg5RTQ0N0EyRSwgMHhDMzQ1MzQ4NCwgMHhGREQ1NjcwNSwgMHgwRTFFOUVDOSwgMHhEQjczREJEMywgMHgxMDU1ODhDRCwgMHg2NzVGREE3OSwgMHhFMzY3NDM0MCwgMHhDNUM0MzQ2NSwgMHg3MTNFMzhEOCwgMHgzRDI4Rjg5RSwgMHhGMTZERkYyMCwgMHgxNTNFMjFFNywgMHg4RkIwM0Q0QSwgMHhFNkUzOUYyQiwgMHhEQjgzQURGN10sIFsweEU5M0Q1QTY4LCAweDk0ODE0MEY3LCAweEY2NEMyNjFDLCAweDk0NjkyOTM0LCAweDQxMTUyMEY3LCAweDc2MDJENEY3LCAweEJDRjQ2QjJFLCAweEQ0QTIwMDY4LCAweEQ0MDgyNDcxLCAweDMzMjBGNDZBLCAweDQzQjdENEI3LCAweDUwMDA2MUFGLCAweDFFMzlGNjJFLCAweDk3MjQ0NTQ2LCAweDE0MjE0Rjc0LCAweEJGOEI4ODQwLCAweDREOTVGQzFELCAweDk2QjU5MUFGLCAweDcwRjREREQzLCAweDY2QTAyRjQ1LCAweEJGQkMwOUVDLCAweDAzQkQ5Nzg1LCAweDdGQUM2REQwLCAweDMxQ0I4NTA0LCAweDk2RUIyN0IzLCAweDU1RkQzOTQxLCAweERBMjU0N0U2LCAweEFCQ0EwQTlBLCAweDI4NTA3ODI1LCAweDUzMDQyOUY0LCAweDBBMkM4NkRBLCAweEU5QjY2REZCLCAweDY4REMxNDYyLCAweEQ3NDg2OTAwLCAweDY4MEVDMEE0LCAweDI3QTE4REVFLCAweDRGM0ZGRUEyLCAweEU4ODdBRDhDLCAweEI1OENFMDA2LCAweDdBRjRENkI2LCAweEFBQ0UxRTdDLCAweEQzMzc1RkVDLCAweENFNzhBMzk5LCAweDQwNkIyQTQyLCAweDIwRkU5RTM1LCAweEQ5RjM4NUI5LCAweEVFMzlEN0FCLCAweDNCMTI0RThCLCAweDFEQzlGQUY3LCAweDRCNkQxODU2LCAweDI2QTM2NjMxLCAweEVBRTM5N0IyLCAweDNBNkVGQTc0LCAweERENUI0MzMyLCAweDY4NDFFN0Y3LCAweENBNzgyMEZCLCAweEZCMEFGNTRFLCAweEQ4RkVCMzk3LCAweDQ1NDA1NkFDLCAweEJBNDg5NTI3LCAweDU1NTMzQTNBLCAweDIwODM4RDg3LCAweEZFNkJBOUI3LCAweEQwOTY5NTRCLCAweDU1QTg2N0JDLCAweEExMTU5QTU4LCAweENDQTkyOTYzLCAweDk5RTFEQjMzLCAweEE2MkE0QTU2LCAweDNGMzEyNUY5LCAweDVFRjQ3RTFDLCAweDkwMjkzMTdDLCAweEZERjhFODAyLCAweDA0MjcyRjcwLCAweDgwQkIxNTVDLCAweDA1MjgyQ0UzLCAweDk1QzExNTQ4LCAweEU0QzY2RDIyLCAweDQ4QzExMzNGLCAweEM3MEY4NkRDLCAweDA3RjlDOUVFLCAweDQxMDQxRjBGLCAweDQwNDc3OUE0LCAweDVEODg2RTE3LCAweDMyNUY1MUVCLCAweEQ1OUJDMEQxLCAweEYyQkNDMThGLCAweDQxMTEzNTY0LCAweDI1N0I3ODM0LCAweDYwMkE5QzYwLCAweERGRjhFOEEzLCAweDFGNjM2QzFCLCAweDBFMTJCNEMyLCAweDAyRTEzMjlFLCAweEFGNjY0RkQxLCAweENBRDE4MTE1LCAweDZCMjM5NUUwLCAweDMzM0U5MkUxLCAweDNCMjQwQjYyLCAweEVFQkVCOTIyLCAweDg1QjJBMjBFLCAweEU2QkEwRDk5LCAweERFNzIwQzhDLCAweDJEQTJGNzI4LCAweEQwMTI3ODQ1LCAweDk1Qjc5NEZELCAweDY0N0QwODYyLCAweEU3Q0NGNUYwLCAweDU0NDlBMzZGLCAweDg3N0Q0OEZBLCAweEMzOURGRDI3LCAweEYzM0U4RDFFLCAweDBBNDc2MzQxLCAweDk5MkVGRjc0LCAweDNBNkY2RUFCLCAweEY0RjhGRDM3LCAweEE4MTJEQzYwLCAweEExRUJEREY4LCAweDk5MUJFMTRDLCAweERCNkU2QjBELCAweEM2N0I1NTEwLCAweDZENjcyQzM3LCAweDI3NjVENDNCLCAweERDRDBFODA0LCAweEYxMjkwREM3LCAweENDMDBGRkEzLCAweEI1MzkwRjkyLCAweDY5MEZFRDBCLCAweDY2N0I5RkZCLCAweENFREI3RDlDLCAweEEwOTFDRjBCLCAweEQ5MTU1RUEzLCAweEJCMTMyRjg4LCAweDUxNUJBRDI0LCAweDdCOTQ3OUJGLCAweDc2M0JENkVCLCAweDM3MzkyRUIzLCAweENDMTE1OTc5LCAweDgwMjZFMjk3LCAweEY0MkUzMTJELCAweDY4NDJBREE3LCAweEM2NkEyQjNCLCAweDEyNzU0Q0NDLCAweDc4MkVGMTFDLCAweDZBMTI0MjM3LCAweEI3OTI1MUU3LCAweDA2QTFCQkU2LCAweDRCRkI2MzUwLCAweDFBNkIxMDE4LCAweDExQ0FFREZBLCAweDNEMjVCREQ4LCAweEUyRTFDM0M5LCAweDQ0NDIxNjU5LCAweDBBMTIxMzg2LCAweEQ5MENFQzZFLCAweEQ1QUJFQTJBLCAweDY0QUY2NzRFLCAweERBODZBODVGLCAweEJFQkZFOTg4LCAweDY0RTRDM0ZFLCAweDlEQkM4MDU3LCAweEYwRjdDMDg2LCAweDYwNzg3QkY4LCAweDYwMDM2MDRELCAweEQxRkQ4MzQ2LCAweEY2MzgxRkIwLCAweDc3NDVBRTA0LCAweEQ3MzZGQ0NDLCAweDgzNDI2QjMzLCAweEYwMUVBQjcxLCAweEIwODA0MTg3LCAweDNDMDA1RTVGLCAweDc3QTA1N0JFLCAweEJERThBRTI0LCAweDU1NDY0Mjk5LCAweEJGNTgyRTYxLCAweDRFNThGNDhGLCAweEYyRERGREEyLCAweEY0NzRFRjM4LCAweDg3ODlCREMyLCAweDUzNjZGOUMzLCAweEM4QjM4RTc0LCAweEI0NzVGMjU1LCAweDQ2RkNEOUI5LCAweDdBRUIyNjYxLCAweDhCMURERjg0LCAweDg0NkEwRTc5LCAweDkxNUY5NUUyLCAweDQ2NkU1OThFLCAweDIwQjQ1NzcwLCAweDhDRDU1NTkxLCAweEM5MDJERTRDLCAweEI5MEJBQ0UxLCAweEJCODIwNUQwLCAweDExQTg2MjQ4LCAweDc1NzRBOTlFLCAweEI3N0YxOUI2LCAweEUwQTlEQzA5LCAweDY2MkQwOUExLCAweEM0MzI0NjMzLCAweEU4NUExRjAyLCAweDA5RjBCRThDLCAweDRBOTlBMDI1LCAweDFENkVGRTEwLCAweDFBQjkzRDFELCAweDBCQTVBNERGLCAweEExODZGMjBGLCAweDI4NjhGMTY5LCAweERDQjdEQTgzLCAweDU3MzkwNkZFLCAweEExRTJDRTlCLCAweDRGQ0Q3RjUyLCAweDUwMTE1RTAxLCAweEE3MDY4M0ZBLCAweEEwMDJCNUM0LCAweDBERTZEMDI3LCAweDlBRjg4QzI3LCAweDc3M0Y4NjQxLCAweEMzNjA0QzA2LCAweDYxQTgwNkI1LCAweEYwMTc3QTI4LCAweEMwRjU4NkUwLCAweDAwNjA1OEFBLCAweDMwREM3RDYyLCAweDExRTY5RUQ3LCAweDIzMzhFQTYzLCAweDUzQzJERDk0LCAweEMyQzIxNjM0LCAweEJCQ0JFRTU2LCAweDkwQkNCNkRFLCAweEVCRkM3REExLCAweENFNTkxRDc2LCAweDZGMDVFNDA5LCAweDRCN0MwMTg4LCAweDM5NzIwQTNELCAweDdDOTI3QzI0LCAweDg2RTM3MjVGLCAweDcyNEQ5REI5LCAweDFBQzE1QkI0LCAweEQzOUVCOEZDLCAweEVENTQ1NTc4LCAweDA4RkNBNUI1LCAweEQ4M0Q3Q0QzLCAweDREQUQwRkM0LCAweDFFNTBFRjVFLCAweEIxNjFFNkY4LCAweEEyODUxNEQ5LCAweDZDNTExMzNDLCAweDZGRDVDN0U3LCAweDU2RTE0RUM0LCAweDM2MkFCRkNFLCAweEREQzZDODM3LCAweEQ3OUEzMjM0LCAweDkyNjM4MjEyLCAweDY3MEVGQThFLCAweDQwNjAwMEUwXSwgWzB4M0EzOUNFMzcsIDB4RDNGQUY1Q0YsIDB4QUJDMjc3MzcsIDB4NUFDNTJEMUIsIDB4NUNCMDY3OUUsIDB4NEZBMzM3NDIsIDB4RDM4MjI3NDAsIDB4OTlCQzlCQkUsIDB4RDUxMThFOUQsIDB4QkYwRjczMTUsIDB4RDYyRDFDN0UsIDB4QzcwMEM0N0IsIDB4Qjc4QzFCNkIsIDB4MjFBMTkwNDUsIDB4QjI2RUIxQkUsIDB4NkEzNjZFQjQsIDB4NTc0OEFCMkYsIDB4QkM5NDZFNzksIDB4QzZBMzc2RDIsIDB4NjU0OUMyQzgsIDB4NTMwRkY4RUUsIDB4NDY4RERFN0QsIDB4RDU3MzBBMUQsIDB4NENEMDREQzYsIDB4MjkzOUJCREIsIDB4QTlCQTQ2NTAsIDB4QUM5NTI2RTgsIDB4QkU1RUUzMDQsIDB4QTFGQUQ1RjAsIDB4NkEyRDUxOUEsIDB4NjNFRjhDRTIsIDB4OUE4NkVFMjIsIDB4QzA4OUMyQjgsIDB4NDMyNDJFRjYsIDB4QTUxRTAzQUEsIDB4OUNGMkQwQTQsIDB4ODNDMDYxQkEsIDB4OUJFOTZBNEQsIDB4OEZFNTE1NTAsIDB4QkE2NDVCRDYsIDB4MjgyNkEyRjksIDB4QTczQTNBRTEsIDB4NEJBOTk1ODYsIDB4RUY1NTYyRTksIDB4QzcyRkVGRDMsIDB4Rjc1MkY3REEsIDB4M0YwNDZGNjksIDB4NzdGQTBBNTksIDB4ODBFNEE5MTUsIDB4ODdCMDg2MDEsIDB4OUIwOUU2QUQsIDB4M0IzRUU1OTMsIDB4RTk5MEZENUEsIDB4OUUzNEQ3OTcsIDB4MkNGMEI3RDksIDB4MDIyQjhCNTEsIDB4OTZENUFDM0EsIDB4MDE3REE2N0QsIDB4RDFDRjNFRDYsIDB4N0M3RDJEMjgsIDB4MUY5RjI1Q0YsIDB4QURGMkI4OUIsIDB4NUFENkI0NzIsIDB4NUE4OEY1NEMsIDB4RTAyOUFDNzEsIDB4RTAxOUE1RTYsIDB4NDdCMEFDRkQsIDB4RUQ5M0ZBOUIsIDB4RThEM0M0OEQsIDB4MjgzQjU3Q0MsIDB4RjhENTY2MjksIDB4NzkxMzJFMjgsIDB4Nzg1RjAxOTEsIDB4RUQ3NTYwNTUsIDB4Rjc5NjBFNDQsIDB4RTNEMzVFOEMsIDB4MTUwNTZERDQsIDB4ODhGNDZEQkEsIDB4MDNBMTYxMjUsIDB4MDU2NEYwQkQsIDB4QzNFQjlFMTUsIDB4M0M5MDU3QTIsIDB4OTcyNzFBRUMsIDB4QTkzQTA3MkEsIDB4MUIzRjZEOUIsIDB4MUU2MzIxRjUsIDB4RjU5QzY2RkIsIDB4MjZEQ0YzMTksIDB4NzUzM0Q5MjgsIDB4QjE1NUZERjUsIDB4MDM1NjM0ODIsIDB4OEFCQTNDQkIsIDB4Mjg1MTc3MTEsIDB4QzIwQUQ5RjgsIDB4QUJDQzUxNjcsIDB4Q0NBRDkyNUYsIDB4NERFODE3NTEsIDB4MzgzMERDOEUsIDB4Mzc5RDU4NjIsIDB4OTMyMEY5OTEsIDB4RUE3QTkwQzIsIDB4RkIzRTdCQ0UsIDB4NTEyMUNFNjQsIDB4Nzc0RkJFMzIsIDB4QThCNkUzN0UsIDB4QzMyOTNENDYsIDB4NDhERTUzNjksIDB4NjQxM0U2ODAsIDB4QTJBRTA4MTAsIDB4REQ2REIyMjQsIDB4Njk4NTJERkQsIDB4MDkwNzIxNjYsIDB4QjM5QTQ2MEEsIDB4NjQ0NUMwREQsIDB4NTg2Q0RFQ0YsIDB4MUMyMEM4QUUsIDB4NUJCRUY3REQsIDB4MUI1ODhENDAsIDB4Q0NEMjAxN0YsIDB4NkJCNEUzQkIsIDB4RERBMjZBN0UsIDB4M0E1OUZGNDUsIDB4M0UzNTBBNDQsIDB4QkNCNENERDUsIDB4NzJFQUNFQTgsIDB4RkE2NDg0QkIsIDB4OEQ2NjEyQUUsIDB4QkYzQzZGNDcsIDB4RDI5QkU0NjMsIDB4NTQyRjVEOUUsIDB4QUVDMjc3MUIsIDB4RjY0RTYzNzAsIDB4NzQwRTBEOEQsIDB4RTc1QjEzNTcsIDB4Rjg3MjE2NzEsIDB4QUY1MzdENUQsIDB4NDA0MENCMDgsIDB4NEVCNEUyQ0MsIDB4MzREMjQ2NkEsIDB4MDExNUFGODQsIDB4RTFCMDA0MjgsIDB4OTU5ODNBMUQsIDB4MDZCODlGQjQsIDB4Q0U2RUEwNDgsIDB4NkYzRjNCODIsIDB4MzUyMEFCODIsIDB4MDExQTFENEIsIDB4Mjc3MjI3RjgsIDB4NjExNTYwQjEsIDB4RTc5MzNGREMsIDB4QkIzQTc5MkIsIDB4MzQ0NTI1QkQsIDB4QTA4ODM5RTEsIDB4NTFDRTc5NEIsIDB4MkYzMkM5QjcsIDB4QTAxRkJBQzksIDB4RTAxQ0M4N0UsIDB4QkNDN0QxRjYsIDB4Q0YwMTExQzMsIDB4QTFFOEFBQzcsIDB4MUE5MDg3NDksIDB4RDQ0RkJEOUEsIDB4RDBEQURFQ0IsIDB4RDUwQURBMzgsIDB4MDMzOUMzMkEsIDB4QzY5MTM2NjcsIDB4OERGOTMxN0MsIDB4RTBCMTJCNEYsIDB4Rjc5RTU5QjcsIDB4NDNGNUJCM0EsIDB4RjJENTE5RkYsIDB4MjdEOTQ1OUMsIDB4QkY5NzIyMkMsIDB4MTVFNkZDMkEsIDB4MEY5MUZDNzEsIDB4OUI5NDE1MjUsIDB4RkFFNTkzNjEsIDB4Q0VCNjlDRUIsIDB4QzJBODY0NTksIDB4MTJCQUE4RDEsIDB4QjZDMTA3NUUsIDB4RTMwNTZBMEMsIDB4MTBEMjUwNjUsIDB4Q0IwM0E0NDIsIDB4RTBFQzZFMEUsIDB4MTY5OERCM0IsIDB4NEM5OEEwQkUsIDB4MzI3OEU5NjQsIDB4OUYxRjk1MzIsIDB4RTBEMzkyREYsIDB4RDNBMDM0MkIsIDB4ODk3MUYyMUUsIDB4MUIwQTc0NDEsIDB4NEJBMzM0OEMsIDB4QzVCRTcxMjAsIDB4QzM3NjMyRDgsIDB4REYzNTlGOEQsIDB4OUI5OTJGMkUsIDB4RTYwQjZGNDcsIDB4MEZFM0YxMUQsIDB4RTU0Q0RBNTQsIDB4MUVEQUQ4OTEsIDB4Q0U2Mjc5Q0YsIDB4Q0QzRTdFNkYsIDB4MTYxOEIxNjYsIDB4RkQyQzFEMDUsIDB4ODQ4RkQyQzUsIDB4RjZGQjIyOTksIDB4RjUyM0YzNTcsIDB4QTYzMjc2MjMsIDB4OTNBODM1MzEsIDB4NTZDQ0NEMDIsIDB4QUNGMDgxNjIsIDB4NUE3NUVCQjUsIDB4NkUxNjM2OTcsIDB4ODhEMjczQ0MsIDB4REU5NjYyOTIsIDB4ODFCOTQ5RDAsIDB4NEM1MDkwMUIsIDB4NzFDNjU2MTQsIDB4RTZDNkM3QkQsIDB4MzI3QTE0MEEsIDB4NDVFMUQwMDYsIDB4QzNGMjdCOUEsIDB4QzlBQTUzRkQsIDB4NjJBODBGMDAsIDB4QkIyNUJGRTIsIDB4MzVCREQyRjYsIDB4NzExMjY5MDUsIDB4QjIwNDAyMjIsIDB4QjZDQkNGN0MsIDB4Q0Q3NjlDMkIsIDB4NTMxMTNFQzAsIDB4MTY0MEUzRDMsIDB4MzhBQkJENjAsIDB4MjU0N0FERjAsIDB4QkEzODIwOUMsIDB4Rjc0NkNFNzYsIDB4NzdBRkExQzUsIDB4MjA3NTYwNjAsIDB4ODVDQkZFNEUsIDB4OEFFODhERDgsIDB4N0FBQUY5QjAsIDB4NENGOUFBN0UsIDB4MTk0OEMyNUMsIDB4MDJGQjhBOEMsIDB4MDFDMzZBRTQsIDB4RDZFQkUxRjksIDB4OTBENEY4NjksIDB4QTY1Q0RFQTAsIDB4M0YwOTI1MkQsIDB4QzIwOEU2OUYsIDB4Qjc0RTYxMzIsIDB4Q0U3N0UyNUIsIDB4NTc4RkRGRTMsIDB4M0FDMzcyRTZdXTsKICAgICAgICAgIHZhciBCTE9XRklTSF9DVFggPSB7CiAgICAgICAgICAgIHBib3g6IFtdLAogICAgICAgICAgICBzYm94OiBbXQogICAgICAgICAgfTsKICAgICAgICAgIGZ1bmN0aW9uIEYoY3R4LCB4KSB7CiAgICAgICAgICAgIGxldCBhID0geCA+PiAyNCAmIDB4RkY7CiAgICAgICAgICAgIGxldCBiID0geCA+PiAxNiAmIDB4RkY7CiAgICAgICAgICAgIGxldCBjID0geCA+PiA4ICYgMHhGRjsKICAgICAgICAgICAgbGV0IGQgPSB4ICYgMHhGRjsKICAgICAgICAgICAgbGV0IHkgPSBjdHguc2JveFswXVthXSArIGN0eC5zYm94WzFdW2JdOwogICAgICAgICAgICB5ID0geSBeIGN0eC5zYm94WzJdW2NdOwogICAgICAgICAgICB5ID0geSArIGN0eC5zYm94WzNdW2RdOwogICAgICAgICAgICByZXR1cm4geTsKICAgICAgICAgIH0KICAgICAgICAgIGZ1bmN0aW9uIEJsb3dGaXNoX0VuY3J5cHQoY3R4LCBsZWZ0LCByaWdodCkgewogICAgICAgICAgICBsZXQgWGwgPSBsZWZ0OwogICAgICAgICAgICBsZXQgWHIgPSByaWdodDsKICAgICAgICAgICAgbGV0IHRlbXA7CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgTjsgKytpKSB7CiAgICAgICAgICAgICAgWGwgPSBYbCBeIGN0eC5wYm94W2ldOwogICAgICAgICAgICAgIFhyID0gRihjdHgsIFhsKSBeIFhyOwogICAgICAgICAgICAgIHRlbXAgPSBYbDsKICAgICAgICAgICAgICBYbCA9IFhyOwogICAgICAgICAgICAgIFhyID0gdGVtcDsKICAgICAgICAgICAgfQogICAgICAgICAgICB0ZW1wID0gWGw7CiAgICAgICAgICAgIFhsID0gWHI7CiAgICAgICAgICAgIFhyID0gdGVtcDsKICAgICAgICAgICAgWHIgPSBYciBeIGN0eC5wYm94W05dOwogICAgICAgICAgICBYbCA9IFhsIF4gY3R4LnBib3hbTiArIDFdOwogICAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgIGxlZnQ6IFhsLAogICAgICAgICAgICAgIHJpZ2h0OiBYcgogICAgICAgICAgICB9OwogICAgICAgICAgfQogICAgICAgICAgZnVuY3Rpb24gQmxvd0Zpc2hfRGVjcnlwdChjdHgsIGxlZnQsIHJpZ2h0KSB7CiAgICAgICAgICAgIGxldCBYbCA9IGxlZnQ7CiAgICAgICAgICAgIGxldCBYciA9IHJpZ2h0OwogICAgICAgICAgICBsZXQgdGVtcDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IE4gKyAxOyBpID4gMTsgLS1pKSB7CiAgICAgICAgICAgICAgWGwgPSBYbCBeIGN0eC5wYm94W2ldOwogICAgICAgICAgICAgIFhyID0gRihjdHgsIFhsKSBeIFhyOwogICAgICAgICAgICAgIHRlbXAgPSBYbDsKICAgICAgICAgICAgICBYbCA9IFhyOwogICAgICAgICAgICAgIFhyID0gdGVtcDsKICAgICAgICAgICAgfQogICAgICAgICAgICB0ZW1wID0gWGw7CiAgICAgICAgICAgIFhsID0gWHI7CiAgICAgICAgICAgIFhyID0gdGVtcDsKICAgICAgICAgICAgWHIgPSBYciBeIGN0eC5wYm94WzFdOwogICAgICAgICAgICBYbCA9IFhsIF4gY3R4LnBib3hbMF07CiAgICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgbGVmdDogWGwsCiAgICAgICAgICAgICAgcmlnaHQ6IFhyCiAgICAgICAgICAgIH07CiAgICAgICAgICB9CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBJbml0aWFsaXphdGlvbiBjdHgncyBwYm94IGFuZCBzYm94LgogICAgICAgICAgICoKICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjdHggVGhlIG9iamVjdCBoYXMgcGJveCBhbmQgc2JveC4KICAgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGtleSBBbiBhcnJheSBvZiAzMi1iaXQgd29yZHMuCiAgICAgICAgICAgKiBAcGFyYW0ge2ludH0ga2V5c2l6ZSBUaGUgbGVuZ3RoIG9mIHRoZSBrZXkuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgQmxvd0Zpc2hJbml0KEJMT1dGSVNIX0NUWCwga2V5LCAxMjgvMzIpOwogICAgICAgICAgICovCiAgICAgICAgICBmdW5jdGlvbiBCbG93RmlzaEluaXQoY3R4LCBrZXksIGtleXNpemUpIHsKICAgICAgICAgICAgZm9yIChsZXQgUm93ID0gMDsgUm93IDwgNDsgUm93KyspIHsKICAgICAgICAgICAgICBjdHguc2JveFtSb3ddID0gW107CiAgICAgICAgICAgICAgZm9yIChsZXQgQ29sID0gMDsgQ29sIDwgMjU2OyBDb2wrKykgewogICAgICAgICAgICAgICAgY3R4LnNib3hbUm93XVtDb2xdID0gT1JJR19TW1Jvd11bQ29sXTsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbGV0IGtleUluZGV4ID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IE4gKyAyOyBpbmRleCsrKSB7CiAgICAgICAgICAgICAgY3R4LnBib3hbaW5kZXhdID0gT1JJR19QW2luZGV4XSBeIGtleVtrZXlJbmRleF07CiAgICAgICAgICAgICAga2V5SW5kZXgrKzsKICAgICAgICAgICAgICBpZiAoa2V5SW5kZXggPj0ga2V5c2l6ZSkgewogICAgICAgICAgICAgICAga2V5SW5kZXggPSAwOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBsZXQgRGF0YTEgPSAwOwogICAgICAgICAgICBsZXQgRGF0YTIgPSAwOwogICAgICAgICAgICBsZXQgcmVzID0gMDsKICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBOICsgMjsgaSArPSAyKSB7CiAgICAgICAgICAgICAgcmVzID0gQmxvd0Zpc2hfRW5jcnlwdChjdHgsIERhdGExLCBEYXRhMik7CiAgICAgICAgICAgICAgRGF0YTEgPSByZXMubGVmdDsKICAgICAgICAgICAgICBEYXRhMiA9IHJlcy5yaWdodDsKICAgICAgICAgICAgICBjdHgucGJveFtpXSA9IERhdGExOwogICAgICAgICAgICAgIGN0eC5wYm94W2kgKyAxXSA9IERhdGEyOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgNDsgaSsrKSB7CiAgICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCAyNTY7IGogKz0gMikgewogICAgICAgICAgICAgICAgcmVzID0gQmxvd0Zpc2hfRW5jcnlwdChjdHgsIERhdGExLCBEYXRhMik7CiAgICAgICAgICAgICAgICBEYXRhMSA9IHJlcy5sZWZ0OwogICAgICAgICAgICAgICAgRGF0YTIgPSByZXMucmlnaHQ7CiAgICAgICAgICAgICAgICBjdHguc2JveFtpXVtqXSA9IERhdGExOwogICAgICAgICAgICAgICAgY3R4LnNib3hbaV1baiArIDFdID0gRGF0YTI7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgICAgfQoKICAgICAgICAgIC8qKgogICAgICAgICAgICogQmxvd2Zpc2ggYmxvY2sgY2lwaGVyIGFsZ29yaXRobS4KICAgICAgICAgICAqLwogICAgICAgICAgdmFyIEJsb3dmaXNoID0gQ19hbGdvLkJsb3dmaXNoID0gQmxvY2tDaXBoZXIuZXh0ZW5kKHsKICAgICAgICAgICAgX2RvUmVzZXQ6IGZ1bmN0aW9uICgpIHsKICAgICAgICAgICAgICAvLyBTa2lwIHJlc2V0IG9mIG5Sb3VuZHMgaGFzIGJlZW4gc2V0IGJlZm9yZSBhbmQga2V5IGRpZCBub3QgY2hhbmdlCiAgICAgICAgICAgICAgaWYgKHRoaXMuX2tleVByaW9yUmVzZXQgPT09IHRoaXMuX2tleSkgewogICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgLy8gU2hvcnRjdXRzCiAgICAgICAgICAgICAgdmFyIGtleSA9IHRoaXMuX2tleVByaW9yUmVzZXQgPSB0aGlzLl9rZXk7CiAgICAgICAgICAgICAgdmFyIGtleVdvcmRzID0ga2V5LndvcmRzOwogICAgICAgICAgICAgIHZhciBrZXlTaXplID0ga2V5LnNpZ0J5dGVzIC8gNDsKCiAgICAgICAgICAgICAgLy9Jbml0aWFsaXphdGlvbiBwYm94IGFuZCBzYm94CiAgICAgICAgICAgICAgQmxvd0Zpc2hJbml0KEJMT1dGSVNIX0NUWCwga2V5V29yZHMsIGtleVNpemUpOwogICAgICAgICAgICB9LAogICAgICAgICAgICBlbmNyeXB0QmxvY2s6IGZ1bmN0aW9uIChNLCBvZmZzZXQpIHsKICAgICAgICAgICAgICB2YXIgcmVzID0gQmxvd0Zpc2hfRW5jcnlwdChCTE9XRklTSF9DVFgsIE1bb2Zmc2V0XSwgTVtvZmZzZXQgKyAxXSk7CiAgICAgICAgICAgICAgTVtvZmZzZXRdID0gcmVzLmxlZnQ7CiAgICAgICAgICAgICAgTVtvZmZzZXQgKyAxXSA9IHJlcy5yaWdodDsKICAgICAgICAgICAgfSwKICAgICAgICAgICAgZGVjcnlwdEJsb2NrOiBmdW5jdGlvbiAoTSwgb2Zmc2V0KSB7CiAgICAgICAgICAgICAgdmFyIHJlcyA9IEJsb3dGaXNoX0RlY3J5cHQoQkxPV0ZJU0hfQ1RYLCBNW29mZnNldF0sIE1bb2Zmc2V0ICsgMV0pOwogICAgICAgICAgICAgIE1bb2Zmc2V0XSA9IHJlcy5sZWZ0OwogICAgICAgICAgICAgIE1bb2Zmc2V0ICsgMV0gPSByZXMucmlnaHQ7CiAgICAgICAgICAgIH0sCiAgICAgICAgICAgIGJsb2NrU2l6ZTogNjQgLyAzMiwKICAgICAgICAgICAga2V5U2l6ZTogMTI4IC8gMzIsCiAgICAgICAgICAgIGl2U2l6ZTogNjQgLyAzMgogICAgICAgICAgfSk7CgogICAgICAgICAgLyoqCiAgICAgICAgICAgKiBTaG9ydGN1dCBmdW5jdGlvbnMgdG8gdGhlIGNpcGhlcidzIG9iamVjdCBpbnRlcmZhY2UuCiAgICAgICAgICAgKgogICAgICAgICAgICogQGV4YW1wbGUKICAgICAgICAgICAqCiAgICAgICAgICAgKiAgICAgdmFyIGNpcGhlcnRleHQgPSBDcnlwdG9KUy5CbG93ZmlzaC5lbmNyeXB0KG1lc3NhZ2UsIGtleSwgY2ZnKTsKICAgICAgICAgICAqICAgICB2YXIgcGxhaW50ZXh0ICA9IENyeXB0b0pTLkJsb3dmaXNoLmRlY3J5cHQoY2lwaGVydGV4dCwga2V5LCBjZmcpOwogICAgICAgICAgICovCiAgICAgICAgICBDLkJsb3dmaXNoID0gQmxvY2tDaXBoZXIuX2NyZWF0ZUhlbHBlcihCbG93ZmlzaCk7CiAgICAgICAgfSkoKTsKICAgICAgICByZXR1cm4gQ3J5cHRvSlMuQmxvd2Zpc2g7CiAgICAgIH0pOwogICAgfSkoYmxvd2Zpc2gkMSk7CiAgICByZXR1cm4gYmxvd2Zpc2gkMS5leHBvcnRzOwogIH0KCiAgdmFyIGNyeXB0b0pzID0gY3J5cHRvSnMkMS5leHBvcnRzOwogIHZhciBoYXNSZXF1aXJlZENyeXB0b0pzOwogIGZ1bmN0aW9uIHJlcXVpcmVDcnlwdG9KcygpIHsKICAgIGlmIChoYXNSZXF1aXJlZENyeXB0b0pzKSByZXR1cm4gY3J5cHRvSnMkMS5leHBvcnRzOwogICAgaGFzUmVxdWlyZWRDcnlwdG9KcyA9IDE7CiAgICAoZnVuY3Rpb24gKG1vZHVsZSwgZXhwb3J0cyQxKSB7CiAgICAgIChmdW5jdGlvbiAocm9vdCwgZmFjdG9yeSwgdW5kZWYpIHsKICAgICAgICB7CiAgICAgICAgICAvLyBDb21tb25KUwogICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJlcXVpcmVDb3JlKCksIHJlcXVpcmVYNjRDb3JlKCksIHJlcXVpcmVMaWJUeXBlZGFycmF5cygpLCByZXF1aXJlRW5jVXRmMTYoKSwgcmVxdWlyZUVuY0Jhc2U2NCgpLCByZXF1aXJlRW5jQmFzZTY0dXJsKCksIHJlcXVpcmVNZDUoKSwgcmVxdWlyZVNoYTEoKSwgcmVxdWlyZVNoYTI1NigpLCByZXF1aXJlU2hhMjI0KCksIHJlcXVpcmVTaGE1MTIoKSwgcmVxdWlyZVNoYTM4NCgpLCByZXF1aXJlU2hhMygpLCByZXF1aXJlUmlwZW1kMTYwKCksIHJlcXVpcmVIbWFjKCksIHJlcXVpcmVQYmtkZjIoKSwgcmVxdWlyZUV2cGtkZigpLCByZXF1aXJlQ2lwaGVyQ29yZSgpLCByZXF1aXJlTW9kZUNmYigpLCByZXF1aXJlTW9kZUN0cigpLCByZXF1aXJlTW9kZUN0ckdsYWRtYW4oKSwgcmVxdWlyZU1vZGVPZmIoKSwgcmVxdWlyZU1vZGVFY2IoKSwgcmVxdWlyZVBhZEFuc2l4OTIzKCksIHJlcXVpcmVQYWRJc28xMDEyNigpLCByZXF1aXJlUGFkSXNvOTc5NzEoKSwgcmVxdWlyZVBhZFplcm9wYWRkaW5nKCksIHJlcXVpcmVQYWROb3BhZGRpbmcoKSwgcmVxdWlyZUZvcm1hdEhleCgpLCByZXF1aXJlQWVzKCksIHJlcXVpcmVUcmlwbGVkZXMoKSwgcmVxdWlyZVJjNCgpLCByZXF1aXJlUmFiYml0KCksIHJlcXVpcmVSYWJiaXRMZWdhY3koKSwgcmVxdWlyZUJsb3dmaXNoKCkpOwogICAgICAgIH0KICAgICAgfSkoY3J5cHRvSnMsIGZ1bmN0aW9uIChDcnlwdG9KUykgewogICAgICAgIHJldHVybiBDcnlwdG9KUzsKICAgICAgfSk7CiAgICB9KShjcnlwdG9KcyQxKTsKICAgIHJldHVybiBjcnlwdG9KcyQxLmV4cG9ydHM7CiAgfQoKICByZXF1aXJlQ3J5cHRvSnMoKTsKCiAgY29uc3QgY2xvbmVEZWVwID0gKHRhcmdldCkgPT4gewogICAgICBpZiAoaXNBcnJheSh0YXJnZXQpKSB7CiAgICAgICAgICByZXR1cm4gdGFyZ2V0LnJlZHVjZSgobGlzdCwgaXRlbSkgPT4gewogICAgICAgICAgICAgIGxpc3QucHVzaChjbG9uZURlZXAoaXRlbSkpOwogICAgICAgICAgICAgIHJldHVybiBsaXN0OwogICAgICAgICAgfSwgW10pOwogICAgICB9CiAgICAgIGlmIChpc09iamVjdCh0YXJnZXQpKSB7CiAgICAgICAgICBjb25zdCBvYmogPSB7fTsKICAgICAgICAgIE9iamVjdC5rZXlzKHRhcmdldCkuZm9yRWFjaCgoa2V5KSA9PiB7CiAgICAgICAgICAgICAgb2JqW2tleV0gPSBjbG9uZURlZXAodGFyZ2V0W2tleV0pOwogICAgICAgICAgfSk7CiAgICAgICAgICByZXR1cm4gb2JqOwogICAgICB9CiAgICAgIHJldHVybiB0YXJnZXQ7CiAgfTsKCiAgY29uc3QgZGVmYXVsdENvbmZpZyA9IHsKICAgICAgZGV2aWNlOiB7CiAgICAgICAgICBzdGF0dXM6IHsKICAgICAgICAgICAgICAwOiAn56a757q/JywKICAgICAgICAgICAgICAxOiAn5Zyo57q/JywKICAgICAgICAgICAgICAyOiAn55uR5o6n5LitJywKICAgICAgICAgICAgICAzOiAn6YCa6K+d5LitJywKICAgICAgICAgICAgICA0OiAn5b2V5YOP5LitJywKICAgICAgICAgICAgICA1OiAn5b2V6Z+z5LitJywKICAgICAgICAgICAgICA2OiAn5bm/5pKt5LitJywKICAgICAgICAgICAgICA3OiAnU09TJywKICAgICAgICAgICAgICA4OiAn6Z+z6aKR5LitJywKICAgICAgICAgIH0sCiAgICAgICAgICB1c2VJY29uOiB1bmRlZmluZWQKICAgICAgfSwKICAgICAgdG9vbHRpcDogewogICAgICAgICAgc3R5bGU6IHsKICAgICAgICAgICAgICBtYXhXaWR0aDogJzYwMHB4JywKICAgICAgICAgICAgICBjb2xvcjogJyNmZmYnLAogICAgICAgICAgICAgIGZvbnRTaXplOiAnMTJweCcsCiAgICAgICAgICAgICAgZm9udFdlaWdodDogJzQwMCcsCiAgICAgICAgICAgICAgbGluZUhlaWdodDogJzIwcHgnLAogICAgICAgICAgICAgIGJhY2tncm91bmQ6ICcjMUMzMjRCJywKICAgICAgICAgICAgICBib3JkZXJXaWR0aDogJzJweCcsCiAgICAgICAgICAgICAgYm9yZGVyQ29sb3I6ICcjMzc1Qzg2JywKICAgICAgICAgICAgICBib3JkZXJSYWRpdXM6ICc0cHgnLAogICAgICAgICAgICAgIHBhZGRpbmc6ICc3cHggOXB4JywKICAgICAgICAgICAgICB6SW5kZXg6IDMyMDAKICAgICAgICAgIH0sCiAgICAgICAgICBwcm9wczogewogICAgICAgICAgICAgIC8vIOWBj+enu+i3neemuwogICAgICAgICAgICAgIG9mZnNldDogMCwKICAgICAgICAgIH0KICAgICAgfSwKICAgICAgdHJlZTogewogICAgICAgICAgaXRlbUhlaWdodDogMzAsCiAgICAgICAgICBpdGVtR2FwOiAxMCwKICAgICAgICAgIGNvbG9yOiAnI2ZmZicsCiAgICAgICAgICBwbGFjZWhvbGRlckNvbG9yOiAnIzkwOTM5OScsCiAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLAogICAgICAgICAgYmdDb2xvcjogJycsCiAgICAgICAgICBub2RlQmdDb2xvcjogJyMxYzMzNGEnLAogICAgICAgICAgY2hhbm5lbEJnQ29sb3I6ICcjMTAyNjNCJywKICAgICAgICAgIGVtcHR5VGV4dDogJ+aaguaXoOaVsOaNricsCiAgICAgICAgICBidWZmZXJTaXplOiA1MCwKICAgICAgICAgIGV4cGFuZE9uQ2xpY2tOb2RlOiB0cnVlLAogICAgICAgICAgY2hlY2tPbkNsaWNrTm9kZTogZmFsc2UsCiAgICAgICAgICBjaGVja09uQ2xpY2tMZWFmOiB0cnVlLAogICAgICAgICAgY2hlY2tPbkRibGNsaWNrUGFyZW50Tm9kZTogdHJ1ZSwKICAgICAgICAgIGluZGVudDogMTYsCiAgICAgIH0KICB9OwoKICAvLyDorr7lpIfphY3nva4KICBjbG9uZURlZXAoZGVmYXVsdENvbmZpZy5kZXZpY2UpOwogIC8vIHRvb2x0aXDphY3nva4KICBjbG9uZURlZXAoZGVmYXVsdENvbmZpZy50b29sdGlwKTsKICAvLyB2aXJ0dWFsVHJlZemFjee9rgogIGNsb25lRGVlcChkZWZhdWx0Q29uZmlnLnRyZWUpOwoKICAvLyDkuJrliqHnsbvlnosoY29uZmlnLmJ1c2luZXNzKSBkZXZpY2Ut6K6+5aSHIGNoYW5uZWwt6YCa6YGT6K6+5aSHIGdyb3VwRGV2aWNlLee+pOe7hOiuvuWkhyBncm91cC3nvqTnu4QgdXNlci3nlKjmiLcgY3Mt6YeH6ZuG56uZCiAgdmFyIEJ1c2luZXNzOwogIChmdW5jdGlvbiAoQnVzaW5lc3MpIHsKICAgICAgQnVzaW5lc3NbIkRFVklDRSJdID0gImRldmljZSI7CiAgICAgIEJ1c2luZXNzWyJDSEFOTkVMIl0gPSAiY2hhbm5lbCI7CiAgICAgIEJ1c2luZXNzWyJHUk9VUF9ERVZJQ0UiXSA9ICJncm91cERldmljZSI7CiAgICAgIEJ1c2luZXNzWyJHUk9VUCJdID0gImdyb3VwIjsKICAgICAgQnVzaW5lc3NbIlVTRVIiXSA9ICJ1c2VyIjsKICAgICAgQnVzaW5lc3NbIlRFQU1fVVNFUiJdID0gInRlYW1Vc2VyIjsKICAgICAgQnVzaW5lc3NbIkNTIl0gPSAiY3MiOwogICAgICBCdXNpbmVzc1siUExBTl9HUk9VUF9ERVZJQ0UiXSA9ICJwbGFuR3JvdXBEZXZpY2UiOwogIH0pKEJ1c2luZXNzIHx8IChCdXNpbmVzcyA9IHt9KSk7CiAgLy8g6K6+5aSH54q25oCBKGRhdGEuZGV2aWNlU3RhdHVzKSAwLeemu+e6vyAxLeWcqOe6vyAyLeebkeaOp+S4rSAzLemAmuivneS4rSA0LeW9leWDj+S4rSA1LeW9lemfs+S4rSA2LeW5v+aSreS4rSA3LVNPUyA4Lemfs+mikeS4rQogIHZhciBEZXZpY2VTdGF0dXM7CiAgKGZ1bmN0aW9uIChEZXZpY2VTdGF0dXMpIHsKICAgICAgRGV2aWNlU3RhdHVzW0RldmljZVN0YXR1c1siT0ZGX0xJTkUiXSA9IDBdID0gIk9GRl9MSU5FIjsKICAgICAgRGV2aWNlU3RhdHVzW0RldmljZVN0YXR1c1siT05fTElORSJdID0gMV0gPSAiT05fTElORSI7CiAgICAgIERldmljZVN0YXR1c1tEZXZpY2VTdGF0dXNbIkJFX01PTklUT1IiXSA9IDJdID0gIkJFX01PTklUT1IiOwogICAgICBEZXZpY2VTdGF0dXNbRGV2aWNlU3RhdHVzWyJJTl9DQUxMIl0gPSAzXSA9ICJJTl9DQUxMIjsKICAgICAgRGV2aWNlU3RhdHVzW0RldmljZVN0YXR1c1siSU5fVklERU9fUkVDT1JEIl0gPSA0XSA9ICJJTl9WSURFT19SRUNPUkQiOwogICAgICBEZXZpY2VTdGF0dXNbRGV2aWNlU3RhdHVzWyJJTl9BVURJT19SRUNPUkQiXSA9IDVdID0gIklOX0FVRElPX1JFQ09SRCI7CiAgICAgIERldmljZVN0YXR1c1tEZXZpY2VTdGF0dXNbIklOX0JST0FEQ0FTRSJdID0gNl0gPSAiSU5fQlJPQURDQVNFIjsKICAgICAgRGV2aWNlU3RhdHVzW0RldmljZVN0YXR1c1siU09TIl0gPSA3XSA9ICJTT1MiOwogICAgICBEZXZpY2VTdGF0dXNbRGV2aWNlU3RhdHVzWyJJTlRFUkNPTV9DQUxMIl0gPSA4XSA9ICJJTlRFUkNPTV9DQUxMIjsKICB9KShEZXZpY2VTdGF0dXMgfHwgKERldmljZVN0YXR1cyA9IHt9KSk7CiAgLy8g5Lia5Yqh5pWw5o2u57G75Z6LKGRhdGEuZGF0YVR5cGUpIDEt6YOo6ZeoIDMt6K6+5aSHIDQt576k57uEIDUt55So5oi3IDYt6ICD5YukIDct5rC05rqQ54K5IDgt6YeH6ZuG56uZIDkt6K6+5aSH6YCa6YGTIDEwLemYn+S8jSAxMS3pooTmoYjliIbnu4QKICB2YXIgRGF0YVR5cGU7CiAgKGZ1bmN0aW9uIChEYXRhVHlwZSkgewogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiVU5LTk9XXzEiXSA9IDBdID0gIlVOS05PV18xIjsKICAgICAgRGF0YVR5cGVbRGF0YVR5cGVbIkRFUFQiXSA9IDFdID0gIkRFUFQiOwogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiVU5LTk9XXzIiXSA9IDJdID0gIlVOS05PV18yIjsKICAgICAgRGF0YVR5cGVbRGF0YVR5cGVbIkRFVklDRSJdID0gM10gPSAiREVWSUNFIjsKICAgICAgRGF0YVR5cGVbRGF0YVR5cGVbIkdST1VQIl0gPSA0XSA9ICJHUk9VUCI7CiAgICAgIERhdGFUeXBlW0RhdGFUeXBlWyJVU0VSIl0gPSA1XSA9ICJVU0VSIjsKICAgICAgRGF0YVR5cGVbRGF0YVR5cGVbIkFUVEVOREFOQ0UiXSA9IDZdID0gIkFUVEVOREFOQ0UiOwogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiV0FURVJfU09VUkNFIl0gPSA3XSA9ICJXQVRFUl9TT1VSQ0UiOwogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiQ1MiXSA9IDhdID0gIkNTIjsKICAgICAgRGF0YVR5cGVbRGF0YVR5cGVbIkNIQU5ORUwiXSA9IDldID0gIkNIQU5ORUwiOwogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiVEVBTSJdID0gMTBdID0gIlRFQU0iOwogICAgICBEYXRhVHlwZVtEYXRhVHlwZVsiUExBTl9HUk9VUCJdID0gMTFdID0gIlBMQU5fR1JPVVAiOwogIH0pKERhdGFUeXBlIHx8IChEYXRhVHlwZSA9IHt9KSk7CgogIC8qKiDnlJ/miJDlpITnkIblh73mlbAgKi8KICBjb25zdCB1c2VIYW5kbGVGdW4gPSAoY29uZmlnKSA9PiB7CiAgICAgIGNvbnN0IHsgYnVzaW5lc3MgfSA9IGNvbmZpZzsKICAgICAgY29uc3QgcHJvcHMgPSB7IC4uLmNvbmZpZy5wcm9wcyB9OwogICAgICBsZXQgeyBjb3VudEZpbHRlciwgdG90YWxGaWx0ZXIgfSA9IHByb3BzOwogICAgICAvKiog6I635Y+Wa2V55YC8ICovCiAgICAgIGZ1bmN0aW9uIGdldEtleShub2RlLCBpc0J1c2luZXNzID0gZmFsc2UpIHsKICAgICAgICAgIGlmICghbm9kZSkKICAgICAgICAgICAgICByZXR1cm4gJyc7CiAgICAgICAgICBpZiAoYnVzaW5lc3MgJiYgaXNCdXNpbmVzcykgewogICAgICAgICAgICAgIHN3aXRjaCAobm9kZS5kYXRhVHlwZSkgewogICAgICAgICAgICAgICAgICBjYXNlIERhdGFUeXBlLkRFUFQ6IC8vIOmDqOmXqAogICAgICAgICAgICAgICAgICBjYXNlIERhdGFUeXBlLkdST1VQOiAvLyDnvqTnu4QKICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhVHlwZS5URUFNOiAvLyDpmJ/kvI0KICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhVHlwZS5VU0VSOiAvLyDnlKjmiLcKICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhVHlwZS5DUzogLy8g6YeH6ZuG56uZCiAgICAgICAgICAgICAgICAgIGNhc2UgRGF0YVR5cGUuUExBTl9HUk9VUDogLy8g6aKE5qGI5YiG57uECiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5pZDsKICAgICAgICAgICAgICAgICAgY2FzZSBEYXRhVHlwZS5ERVZJQ0U6IC8vIOiuvuWkhwogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5vZGUuZGV2aWNlSWQ7CiAgICAgICAgICAgICAgICAgIGNhc2UgRGF0YVR5cGUuQ0hBTk5FTDogLy8g6K6+5aSH6YCa6YGTCiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbm9kZS5jaGFubmVsSWQ7CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIG5vZGVbcHJvcHMudmFsdWVdOwogICAgICB9CiAgICAgIC8qKiDojrflj5ZsYWJlbOWAvCAqLwogICAgICBmdW5jdGlvbiBnZXRMYWJlbChub2RlKSB7CiAgICAgICAgICBpZiAoIW5vZGUpCiAgICAgICAgICAgICAgcmV0dXJuICcnOwogICAgICAgICAgcmV0dXJuIG5vZGVbcHJvcHMubGFiZWxdOwogICAgICB9CiAgICAgIC8qKiDojrflj5ZjaGlsZHJlbuWAvCAqLwogICAgICBmdW5jdGlvbiBnZXRDaGlsZHJlbihub2RlKSB7CiAgICAgICAgICBpZiAoIW5vZGUpCiAgICAgICAgICAgICAgcmV0dXJuIFtdOwogICAgICAgICAgY29uc3QgY2hpbGRyZW4gPSBub2RlW3Byb3BzLmNoaWxkcmVuXTsKICAgICAgICAgIHJldHVybiBjaGlsZHJlbiA/IFsuLi5jaGlsZHJlbl0gOiBbXTsKICAgICAgfQogICAgICAvKiog6I635Y+WY291bnTlgLwgKi8KICAgICAgZnVuY3Rpb24gZ2V0Q291bnQobm9kZSkgewogICAgICAgICAgaWYgKCFub2RlKQogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIHJldHVybiBub2RlW3Byb3BzLmNvdW50XTsKICAgICAgfQogICAgICAvKiog6I635Y+WdG90YWzlgLwgKi8KICAgICAgZnVuY3Rpb24gZ2V0VG90YWwobm9kZSkgewogICAgICAgICAgaWYgKCFub2RlKQogICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgIHJldHVybiBub2RlW3Byb3BzLnRvdGFsXTsKICAgICAgfQogICAgICBpZiAoYnVzaW5lc3MgJiYgW0J1c2luZXNzLkRFVklDRSwgQnVzaW5lc3MuQ0hBTk5FTCwgQnVzaW5lc3MuR1JPVVBfREVWSUNFLCBCdXNpbmVzcy5QTEFOX0dST1VQX0RFVklDRV0uaW5jbHVkZXMoYnVzaW5lc3MpKSB7CiAgICAgICAgICBjb3VudEZpbHRlciA9IChkYXRhKSA9PiB7CiAgICAgICAgICAgICAgcmV0dXJuIGRhdGEuZGF0YVR5cGUgPT09IERhdGFUeXBlLkRFVklDRSAmJiBkYXRhLm9ubGluZVN0YXRlID09PSAxOwogICAgICAgICAgfTsKICAgICAgICAgIHRvdGFsRmlsdGVyID0gKGRhdGEpID0+IHsKICAgICAgICAgICAgICByZXR1cm4gZGF0YS5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuREVWSUNFOwogICAgICAgICAgfTsKICAgICAgfQogICAgICBlbHNlIGlmIChidXNpbmVzcyAmJiBbQnVzaW5lc3MuVVNFUiwgQnVzaW5lc3MuVEVBTV9VU0VSXS5pbmNsdWRlcyhidXNpbmVzcykpIHsKICAgICAgICAgIGNvdW50RmlsdGVyID0gdG90YWxGaWx0ZXIgPSAoZGF0YSkgPT4gewogICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGFUeXBlID09PSBEYXRhVHlwZS5VU0VSOwogICAgICAgICAgfTsKICAgICAgfQogICAgICBlbHNlIGlmIChidXNpbmVzcyA9PT0gQnVzaW5lc3MuQ1MpIHsKICAgICAgICAgIGNvdW50RmlsdGVyID0gdG90YWxGaWx0ZXIgPSAoZGF0YSkgPT4gewogICAgICAgICAgICAgIHJldHVybiBkYXRhLmRhdGFUeXBlID09PSBEYXRhVHlwZS5DUzsKICAgICAgICAgIH07CiAgICAgIH0KICAgICAgcmV0dXJuIHsKICAgICAgICAgIGdldEtleSwKICAgICAgICAgIGdldExhYmVsLAogICAgICAgICAgZ2V0Q2hpbGRyZW4sCiAgICAgICAgICBnZXRDb3VudCwKICAgICAgICAgIGdldFRvdGFsLAogICAgICAgICAgY291bnRGaWx0ZXIsCiAgICAgICAgICB0b3RhbEZpbHRlciwKICAgICAgICAgIGdldE5vZGVEYXRhLAogICAgICAgICAgLy8g6K6+572u6K6+5aSH54q25oCBCiAgICAgICAgICBzZXREZXZpY2VTdGF0dXM6IChkYXRhKSA9PiB7CiAgICAgICAgICAgICAgLy8g6YCa6YGT54q25oCBCiAgICAgICAgICAgICAgaWYgKGRhdGEuZGF0YVR5cGUgPT09IERhdGFUeXBlLkNIQU5ORUwpIHsKICAgICAgICAgICAgICAgICAgaWYgKGRhdGEub25saW5lU3RhdGUgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgIC8vIOebkeaOp+S4rQogICAgICAgICAgICAgICAgICAgICAgaWYgKGRhdGEuYmVNb25pdG9yID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERldmljZVN0YXR1cy5CRV9NT05JVE9SOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgLy8g5Zyo57q/CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLk9OX0xJTkU7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g56a757q/CiAgICAgICAgICAgICAgICAgIHJldHVybiBEZXZpY2VTdGF0dXMuT0ZGX0xJTkU7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIC8vIOiuvuWkh+eKtuaAgQogICAgICAgICAgICAgIGlmIChkYXRhLm9ubGluZVN0YXRlID09PSAxKSB7CiAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmludGVyY29tR3JvdXBUZW0gPT09IDEgfHwgZGF0YS5pbnRlcmNvbUNhbGwgPT09IDEpIHsKICAgICAgICAgICAgICAgICAgICAgIC8vIOmfs+mikeS4rQogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERldmljZVN0YXR1cy5JTlRFUkNPTV9DQUxMOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOebkeaOp+S4rQogICAgICAgICAgICAgICAgICBpZiAoZGF0YS5tb25pdG9yID09PSAxIHx8IGRhdGEuYmVNb25pdG9yID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLkJFX01PTklUT1I7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6YCa6K+d5LitCiAgICAgICAgICAgICAgICAgIGlmIChkYXRhLnZpZGVvQ2FsbCA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERldmljZVN0YXR1cy5JTl9DQUxMOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOW9leWDj+S4rQogICAgICAgICAgICAgICAgICBpZiAoZGF0YS52aWRlb1JlY29yZGluZyA9PT0gMSkgewogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIERldmljZVN0YXR1cy5JTl9WSURFT19SRUNPUkQ7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g5b2V6Z+z5LitCiAgICAgICAgICAgICAgICAgIGlmIChkYXRhLmF1ZGlvUmVjb3JkaW5nID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLklOX0FVRElPX1JFQ09SRDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDlub/mkq3kuK0KICAgICAgICAgICAgICAgICAgaWYgKGRhdGEuYnJvYWRjYXN0ID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLklOX0JST0FEQ0FTRTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyBTT1MKICAgICAgICAgICAgICAgICAgaWYgKGRhdGEuc29zID09PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLlNPUzsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDlnKjnur8KICAgICAgICAgICAgICAgICAgcmV0dXJuIERldmljZVN0YXR1cy5PTl9MSU5FOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAvLyDnprvnur8KICAgICAgICAgICAgICByZXR1cm4gRGV2aWNlU3RhdHVzLk9GRl9MSU5FOwogICAgICAgICAgfQogICAgICB9OwogIH07CiAgLyoqIOiOt+WPluiKgueCueaVsOaNriAqLwogIGNvbnN0IGdldE5vZGVEYXRhID0gKG5vZGUpID0+IHsKICAgICAgaWYgKG5vZGUuZGF0YS5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuQ0hBTk5FTCkgewogICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICAuLi5ub2RlLnBhcmVudC5kYXRhLAogICAgICAgICAgICAgIC4uLm5vZGUuZGF0YQogICAgICAgICAgfTsKICAgICAgfQogICAgICByZXR1cm4gbm9kZS5kYXRhOwogIH07CgogIC8vIOWkhOeQhmZpbHRlckNvbmZpZwogIGZ1bmN0aW9uIGhhbmRsZUZpbHRlckNvbmZpZyhmaWx0ZXJDb25maWcpIHsKICAgICAgcmV0dXJuIChmaWx0ZXJDb25maWcgfHwgW10pLmZpbHRlcigoaXRlbSkgPT4gewogICAgICAgICAgcmV0dXJuIChpc1N0cmluZyhpdGVtLnByb3ApICYmCiAgICAgICAgICAgICAgKGlzU3RyaW5nKGl0ZW0udmFsdWUpIHx8CiAgICAgICAgICAgICAgICAgIGlzTnVtYmVyKGl0ZW0udmFsdWUpIHx8CiAgICAgICAgICAgICAgICAgIChpc0FycmF5KGl0ZW0udmFsdWUpICYmIGl0ZW0uY29uZGl0aW9uID09PSAnYmV0d2VlbicpKSAmJgogICAgICAgICAgICAgIC9eKGVxfG5lfGlufG5vdElufGJldHdlZW58Z3R8bHR8Z2V8bGUpJC8udGVzdChpdGVtLmNvbmRpdGlvbikpOwogICAgICB9KTsKICB9CiAgLy8g5qCh6aqMZmlsdGVyQ29uZmlnCiAgZnVuY3Rpb24gdXNlRmlsdGVyQ29uZmlnKGRhdGEsIGZpbHRlckxpc3QpIHsKICAgICAgaWYgKCFmaWx0ZXJMaXN0IHx8ICFmaWx0ZXJMaXN0Lmxlbmd0aCkKICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICByZXR1cm4gZmlsdGVyTGlzdC5ldmVyeSgoeyBwcm9wLCB2YWx1ZSwgY29uZGl0aW9uIH0pID0+IHsKICAgICAgICAgIGNvbnN0IHRhcmdldCA9IGRhdGFbcHJvcF07CiAgICAgICAgICBzd2l0Y2ggKGNvbmRpdGlvbikgewogICAgICAgICAgICAgIGNhc2UgJ2VxJzoKICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldCA9PT0gdmFsdWU7CiAgICAgICAgICAgICAgY2FzZSAnbmUnOgogICAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0ICE9PSB2YWx1ZTsKICAgICAgICAgIH0KICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkgewogICAgICAgICAgICAgIGlmIChjb25kaXRpb24gPT09ICdiZXR3ZWVuJykgewogICAgICAgICAgICAgICAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoCiAgICAgICAgICAgICAgICAgICAgICA/IHRhcmdldCA+PSB2YWx1ZVswXSAmJiB0YXJnZXQgPD0gdmFsdWVbMV0KICAgICAgICAgICAgICAgICAgICAgIDogZmFsc2U7CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgaWYgKGlzTnVtYmVyKHRhcmdldCkpIHsKICAgICAgICAgICAgICBpZiAoIWlzTnVtYmVyKHZhbHVlKSkKICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICAgIHN3aXRjaCAoY29uZGl0aW9uKSB7CiAgICAgICAgICAgICAgICAgIGNhc2UgJ2d0JzoKICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0YXJnZXQgPiB2YWx1ZTsKICAgICAgICAgICAgICAgICAgY2FzZSAnbHQnOgogICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRhcmdldCA8IHZhbHVlOwogICAgICAgICAgICAgICAgICBjYXNlICdnZSc6CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0ID49IHZhbHVlOwogICAgICAgICAgICAgICAgICBjYXNlICdsZSc6CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdGFyZ2V0IDw9IHZhbHVlOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgaWYgKGlzU3RyaW5nKHRhcmdldCkpIHsKICAgICAgICAgICAgICBjb25zdCBpc0luID0gdGFyZ2V0LmluY2x1ZGVzKGAke3ZhbHVlfWApOwogICAgICAgICAgICAgIHN3aXRjaCAoY29uZGl0aW9uKSB7CiAgICAgICAgICAgICAgICAgIGNhc2UgJ2luJzoKICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpc0luOwogICAgICAgICAgICAgICAgICBjYXNlICdub3RJbic6CiAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gIWlzSW47CiAgICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICB9KTsKICB9CgogIC8vIOiuvuWkh+agkee7k+aehAogIGZ1bmN0aW9uIGdlbmVyYXRlRGV2aWNlVHJlZShkYXRhLCBjb25maWcpIHsKICAgICAgY29uc3QgeyBleHBhbmRlZEtleVNldCB9ID0gY29uZmlnOwogICAgICBjb25zdCB7IHNvcnRCeVN0YXR1cywgc2hvd09ubGluZVN0YXRlLCBjbGVhckVtcHR5QnVzaW5lc3MgfSA9IGNvbmZpZy5idXNpbmVzc0NvbmZpZzsKICAgICAgY29uc3QgeyBnZXRLZXksIGdldExhYmVsLCBnZXRDaGlsZHJlbiwgY291bnRGaWx0ZXIsIHRvdGFsRmlsdGVyLCBzZXREZXZpY2VTdGF0dXMgfSA9IHVzZUhhbmRsZUZ1bihjb25maWcpOwogICAgICBjb25zdCBmaWx0ZXJMaXN0ID0gaGFuZGxlRmlsdGVyQ29uZmlnKGNvbmZpZy5idXNpbmVzc0NvbmZpZz8uZmlsdGVyQ29uZmlnKTsKICAgICAgLyoqIOiuvuWkh+agkSAqLwogICAgICBmdW5jdGlvbiBjcmVhdGVEZXZpY2VUcmVlKGRhdGEpIHsKICAgICAgICAgIGxldCBtYXhMZXZlbCA9IDE7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZU1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IGxldmVsVHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBkZXZpY2VNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBoaWRkZW5Ob2RlS2V5U2V0ID0gbmV3IFNldCgpOwogICAgICAgICAgY29uc3QgdHJhdmVyc2UgPSAobm9kZXMsIGxldmVsID0gMSwgcGFyZW50ID0gdW5kZWZpbmVkKSA9PiB7CiAgICAgICAgICAgICAgY29uc3Qgc2libGluZ3MgPSBbXTsKICAgICAgICAgICAgICBsZXQgY291bnQgPSAwOwogICAgICAgICAgICAgIGxldCB0b3RhbCA9IDA7CiAgICAgICAgICAgICAgZm9yIChsZXQgcmF3Tm9kZSBvZiBub2RlcykgewogICAgICAgICAgICAgICAgICAvLyDkuJrliqHpgLvovpEKICAgICAgICAgICAgICAgICAgbGV0IGNoaWxkcmVuID0gZ2V0Q2hpbGRyZW4ocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlICE9PSAzKSB7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBkZXZpY2VMaXN0ID0gW1tdLCBbXV07CiAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuID8gY2hpbGRyZW4gOiBbXTsKICAgICAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRldmljZUxpc3QpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlLmRldmljZUxpc3QuZm9yRWFjaCgodikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkICsgJy0nICsgdi5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiB2LmRldk5hbWUgfHwgdi5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiAzLCAvLyDku6Pooajorr7lpIcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZVN0YXR1czogc2V0RGV2aWNlU3RhdHVzKHYpIC8vIOiuvuWkh+eKtuaAgQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlRmlsdGVyQ29uZmlnKHRhcmdldCwgZmlsdGVyTGlzdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuZGV2aWNlU3RhdHVzID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlTGlzdFtzb3J0QnlTdGF0dXMgPyAxIDogMF0ucHVzaCh0YXJnZXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaG93T25saW5lU3RhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldC5hZGQoZ2V0S2V5KHRhcmdldCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZUxpc3RbMF0ucHVzaCh0YXJnZXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBbLi4uY2hpbGRyZW4sIC4uLmRldmljZUxpc3RbMF0sIC4uLmRldmljZUxpc3RbMV1dOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5yYXdOb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogMSwgLy8g6YOo6ZeoCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHJhd05vZGUub3JnTmFtZSB8fCByYXdOb2RlLmNvbXBhbnlOYW1lCiAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieiuvuWkh+eahOmDqOmXqOWSjOe+pOe7hCDmraXpqqTkuIAKICAgICAgICAgICAgICAgICAgaWYgKGNsZWFyRW1wdHlCdXNpbmVzcykgewogICAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZHJlbiB8fCBjaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgcmF3Tm9kZS5kYXRhVHlwZSAhPT0gMykgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOmAmueUqOmAu+i+kQogICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGdldEtleShyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsLAogICAgICAgICAgICAgICAgICAgICAga2V5OiB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHJhd05vZGUKICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgbm9kZS5sYWJlbCA9IGdldExhYmVsKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICBub2RlLnBhcmVudCA9IHBhcmVudDsKICAgICAgICAgICAgICAgICAgbm9kZS5pc0xlYWYgPSAhY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwOwogICAgICAgICAgICAgICAgICBub2RlLmV4cGFuZGVkID0gZXhwYW5kZWRLZXlTZXQuaGFzKHZhbHVlKTsKICAgICAgICAgICAgICAgICAgLy8g6ZqQ6JeP5rKh5pyJ5Zyo57q/6K6+5aSH55qE6YOo6Zeo5ZKM576k57uECiAgICAgICAgICAgICAgICAgIGlmIChzaG93T25saW5lU3RhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmIHJhd05vZGUuZGF0YVR5cGUgIT09IDMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChub2RlLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBsaXN0LCBjb3VudDogY2hpbGRDb3VudCwgdG90YWw6IGNoaWxkVG90YWwgfSA9IHRyYXZlcnNlKGNoaWxkcmVuLCBsZXZlbCArIDEsIG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgLy8g6L+H5ruk5rKh5pyJ55So5oi355qE6YOo6ZeoIOatpemqpOS6jAogICAgICAgICAgICAgICAgICAgICAgaWYgKCFzaG93T25saW5lU3RhdGUgJiYgY2xlYXJFbXB0eUJ1c2luZXNzICYmIGNoaWxkVG90YWwgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY2hpbGRyZW4gPSBsaXN0OwogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jb3VudCA9IGNoaWxkQ291bnQgOwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IGNoaWxkVG90YWwgOwogICAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gY2hpbGRDb3VudDsKICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IGNoaWxkVG90YWw7CiAgICAgICAgICAgICAgICAgICAgICAvLyDku4XmmL7npLrlnKjnur/orr7lpIfml7bvvIzpmpDol4/msqHmnInlnKjnur/orr7lpIfnmoTpg6jpl6jlkoznvqTnu4QKICAgICAgICAgICAgICAgICAgICAgIGlmIChzaG93T25saW5lU3RhdGUgJiYgIWNoaWxkQ291bnQpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChub2RlLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gMDsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUudG90YWwgPSAwOwogICAgICAgICAgICAgICAgICAgICAgLy8g57uf6K6hCiAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNob3dPbmxpbmVTdGF0ZSB8fCAhaGlkZGVuTm9kZUtleVNldC5oYXMobm9kZS5rZXkpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjb3VudEZpbHRlcihyYXdOb2RlKSA/IDEgOiAwOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRvdGFsRmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIHNpYmxpbmdzLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIHRyZWVOb2RlTWFwLnNldCh2YWx1ZSwgbm9kZSk7CiAgICAgICAgICAgICAgICAgIGlmICghbGV2ZWxUcmVlTm9kZU1hcC5oYXMobGV2ZWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLnNldChsZXZlbCwgW10pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGlmIChsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuZ2V0KGxldmVsKS5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOiuvuWkhwogICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kYXRhVHlwZSA9PT0gMykgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBkZXZpY2VJZCB9ID0gbm9kZS5kYXRhOwogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV2aWNlSW5mbyA9IGRldmljZU1hcC5nZXQoZGV2aWNlSWQpIHx8IFtdOwogICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSW5mby5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgZGV2aWNlTWFwLnNldChkZXZpY2VJZCwgZGV2aWNlSW5mbyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKGxldmVsID4gbWF4TGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgbWF4TGV2ZWwgPSBsZXZlbDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHsgbGlzdDogc2libGluZ3MsIGNvdW50LCB0b3RhbCB9OwogICAgICAgICAgfTsKICAgICAgICAgIGNvbnN0IHsgbGlzdCB9ID0gdHJhdmVyc2UoZGF0YSB8fCBbXSk7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZXMgPSBsaXN0OwogICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICB0cmVlTm9kZU1hcCwKICAgICAgICAgICAgICBkZXZpY2VNYXAsCiAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcCwKICAgICAgICAgICAgICBtYXhMZXZlbCwKICAgICAgICAgICAgICB0cmVlTm9kZXMsCiAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldAogICAgICAgICAgfTsKICAgICAgfQogICAgICByZXR1cm4gY3JlYXRlRGV2aWNlVHJlZShkYXRhKTsKICB9CiAgLy8g6YCa6YGT6K6+5aSH5qCR57uT5p6ECiAgZnVuY3Rpb24gZ2VuZXJhdGVDaGFubmVsRGV2aWNlVHJlZShkYXRhLCBjb25maWcpIHsKICAgICAgY29uc3QgeyBleHBhbmRlZEtleVNldCB9ID0gY29uZmlnOwogICAgICBjb25zdCB7IHNvcnRCeVN0YXR1cywgc2hvd09ubGluZVN0YXRlLCBjbGVhckVtcHR5QnVzaW5lc3MgfSA9IGNvbmZpZy5idXNpbmVzc0NvbmZpZzsKICAgICAgY29uc3QgeyBnZXRLZXksIGdldExhYmVsLCBnZXRDaGlsZHJlbiwgY291bnRGaWx0ZXIsIHRvdGFsRmlsdGVyLCBzZXREZXZpY2VTdGF0dXMgfSA9IHVzZUhhbmRsZUZ1bihjb25maWcpOwogICAgICBjb25zdCBmaWx0ZXJMaXN0ID0gaGFuZGxlRmlsdGVyQ29uZmlnKGNvbmZpZy5idXNpbmVzc0NvbmZpZz8uZmlsdGVyQ29uZmlnKTsKICAgICAgLyoqIOiuvuWkh+agkSAqLwogICAgICBmdW5jdGlvbiBjcmVhdGVEZXZpY2VUcmVlKGRhdGEpIHsKICAgICAgICAgIGxldCBtYXhMZXZlbCA9IDE7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZU1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IGxldmVsVHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBkZXZpY2VNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBjaGFubmVsTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgaGlkZGVuTm9kZUtleVNldCA9IG5ldyBTZXQoKTsKICAgICAgICAgIGNvbnN0IHRyYXZlcnNlID0gKG5vZGVzLCBsZXZlbCA9IDEsIHBhcmVudCA9IHVuZGVmaW5lZCkgPT4gewogICAgICAgICAgICAgIGNvbnN0IHNpYmxpbmdzID0gW107CiAgICAgICAgICAgICAgbGV0IGNvdW50ID0gMDsKICAgICAgICAgICAgICBsZXQgdG90YWwgPSAwOwogICAgICAgICAgICAgIGZvciAobGV0IHJhd05vZGUgb2Ygbm9kZXMpIHsKICAgICAgICAgICAgICAgICAgLy8g5Lia5Yqh6YC76L6RCiAgICAgICAgICAgICAgICAgIGxldCBjaGlsZHJlbiA9IGdldENoaWxkcmVuKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICAvLyDpnZ7orr7lpIfnsbvlnosKICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUuZGF0YVR5cGUgIT09IERhdGFUeXBlLkRFVklDRSkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV2aWNlTGlzdCA9IFtbXSwgW11dOwogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiA/IGNoaWxkcmVuIDogW107CiAgICAgICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kZXZpY2VMaXN0KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS5kZXZpY2VMaXN0LmZvckVhY2goKHYpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCArICctJyArIHYuZGV2aWNlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdi5kZXZOYW1lIHx8IHYuZGV2aWNlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogRGF0YVR5cGUuREVWSUNFLCAvLyDku6Pooajorr7lpIcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZVN0YXR1czogc2V0RGV2aWNlU3RhdHVzKHYpIC8vIOiuvuWkh+eKtuaAgQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlRmlsdGVyQ29uZmlnKHRhcmdldCwgZmlsdGVyTGlzdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuZGV2aWNlU3RhdHVzID09PSBEZXZpY2VTdGF0dXMuT0ZGX0xJTkUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VMaXN0W3NvcnRCeVN0YXR1cyA/IDEgOiAwXS5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNob3dPbmxpbmVTdGF0ZSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChnZXRLZXkodGFyZ2V0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlTGlzdFswXS5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IFsuLi5jaGlsZHJlbiwgLi4uZGV2aWNlTGlzdFswXSwgLi4uZGV2aWNlTGlzdFsxXV07CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlID0gewogICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJhd05vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiBEYXRhVHlwZS5ERVBULCAvLyDpg6jpl6gKICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcmF3Tm9kZS5vcmdOYW1lIHx8IHJhd05vZGUuY29tcGFueU5hbWUKICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6L+H5ruk5rKh5pyJ6K6+5aSH55qE6YOo6Zeo5ZKM576k57uEIOatpemqpOS4gAogICAgICAgICAgICAgICAgICBpZiAoY2xlYXJFbXB0eUJ1c2luZXNzKSB7CiAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMCAmJiByYXdOb2RlLmRhdGFUeXBlICE9PSAzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6YCa55So6YC76L6RCiAgICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gZ2V0S2V5KHJhd05vZGUpOwogICAgICAgICAgICAgICAgICBjb25zdCBub2RlID0gewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWwsCiAgICAgICAgICAgICAgICAgICAgICBrZXk6IHZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgZGF0YTogcmF3Tm9kZSwKICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBnZXRMYWJlbChyYXdOb2RlKSwKICAgICAgICAgICAgICAgICAgICAgIHBhcmVudCwKICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkOiBleHBhbmRlZEtleVNldC5oYXModmFsdWUpCiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIC8vIOmakOiXj+ayoeacieWcqOe6v+iuvuWkh+eahOmDqOmXqOWSjOe+pOe7hAogICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMCAmJiByYXdOb2RlLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5ERVZJQ0UpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChub2RlLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6Z2e6K6+5aSH57G75Z6L5pWw5o2uCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5ERVZJQ0UgJiYgY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGxpc3QsIGNvdW50OiBjaGlsZENvdW50LCB0b3RhbDogY2hpbGRUb3RhbCB9ID0gdHJhdmVyc2UoY2hpbGRyZW4sIGxldmVsICsgMSwgbm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInnlKjmiLfnmoTpg6jpl6gg5q2l6aqk5LqMCiAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNob3dPbmxpbmVTdGF0ZSAmJiBjbGVhckVtcHR5QnVzaW5lc3MgJiYgY2hpbGRUb3RhbCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IGxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hpbGRDb3VudCA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gY2hpbGRUb3RhbCA7CiAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGlsZENvdW50OwogICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hpbGRUb3RhbDsKICAgICAgICAgICAgICAgICAgICAgIC8vIOS7heaYvuekuuWcqOe6v+iuvuWkh+aXtu+8jOmakOiXj+ayoeacieWcqOe6v+iuvuWkh+eahOmDqOmXqOWSjOe+pOe7hAogICAgICAgICAgICAgICAgICAgICAgaWYgKHNob3dPbmxpbmVTdGF0ZSAmJiAhY2hpbGRDb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGRlbk5vZGVLZXlTZXQuYWRkKG5vZGUua2V5KTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAvLyDnu5/orqEKICAgICAgICAgICAgICAgICAgICAgIGlmICghc2hvd09ubGluZVN0YXRlIHx8ICFoaWRkZW5Ob2RlS2V5U2V0Lmhhcyhub2RlLmtleSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNvdW50RmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdG90YWxGaWx0ZXIocmF3Tm9kZSkgPyAxIDogMDsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6K6+5aSH57G75Z6L5pWw5o2u77yM5LiU5pyJ6YCa6YGT5pWw5o2u5aSE55CGCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlID09PSBEYXRhVHlwZS5ERVZJQ0UgJiYgcmF3Tm9kZS52aWRlb0NoYW5uZWxMaXN0Py5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxMZXZlbCA9IGxldmVsICsgMTsKICAgICAgICAgICAgICAgICAgICAgIGlmICghbGV2ZWxUcmVlTm9kZU1hcC5oYXMoY2hhbm5lbExldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGNoYW5uZWxMZXZlbCwgW10pOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbExpc3QgPSBbW10sIFtdXTsKICAgICAgICAgICAgICAgICAgICAgIGxldCBjaGFubmVsT25saW5lQ291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbGV0IGhhc0JlTW9uaXRvciA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS52aWRlb0NoYW5uZWxMaXN0LmZvckVhY2goKGMpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IHJhd05vZGUub25seUlkICsgJy0nICsgYy5jaGFubmVsSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjLmNoYW5uZWxOYW1lIHx8IGMuY2hhbm5lbElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbDogbGV2ZWwgKyAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWw6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNMZWFmOiB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSWQ6IHJhd05vZGUuZGV2aWNlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZOYW1lOiByYXdOb2RlLmRldk5hbWUgfHwgcmF3Tm9kZS5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5vbmx5SWQgKyAnLScgKyBjLmNoYW5uZWxJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjLmNoYW5uZWxOYW1lIHx8IGMuY2hhbm5lbElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLkNIQU5ORUwsIC8vIOS7o+ihqOmAmumBkwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlU3RhdHVzOiBzZXREZXZpY2VTdGF0dXMoYykgLy8g6K6+5aSH6YCa6YGT54q25oCBCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogbm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgIGhhc0JlTW9uaXRvciA9IGhhc0JlTW9uaXRvciB8fCBjaGFubmVsLmRhdGEuZGV2aWNlU3RhdHVzID09PSBEZXZpY2VTdGF0dXMuQkVfTU9OSVRPUjsKICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbC5kYXRhLmRldmljZVN0YXR1cyA9PT0gRGV2aWNlU3RhdHVzLk9GRl9MSU5FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0W3NvcnRCeVN0YXR1cyA/IDEgOiAwXS5wdXNoKGNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChjaGFubmVsLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxPbmxpbmVDb3VudCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFswXS5wdXNoKGNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTWFwLnNldChjLmNoYW5uZWxJZCwgY2hhbm5lbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KGNoYW5uZWwua2V5LCBjaGFubmVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLmdldChjaGFubmVsTGV2ZWwpLnB1c2goY2hhbm5lbCk7CiAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gWy4uLmNoYW5uZWxMaXN0WzBdLCAuLi5jaGFubmVsTGlzdFsxXV07CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hhbm5lbE9ubGluZUNvdW50OwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IHNob3dPbmxpbmVTdGF0ZSA/IG5vZGUuY291bnQgOiBjaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNoaWxkcmVuID0gY2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICBtYXhMZXZlbCA9IE1hdGgubWF4KGNoYW5uZWxMZXZlbCwgbWF4TGV2ZWwpOwogICAgICAgICAgICAgICAgICAgICAgLy8g6YCa6YGT54q25oCB5Li655uR5o6n5Lit77yM6K6+5aSH54q25oCB5Li65Zyo57q/77yM5bCG6K6+5aSH54q25oCB5pu05pS55Li655uR5o6n5LitCiAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzQmVNb25pdG9yICYmIG5vZGUuZGF0YS5kZXZpY2VTdGF0dXMgPT09IERldmljZVN0YXR1cy5PTl9MSU5FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5kYXRhLmRldmljZVN0YXR1cyA9IERldmljZVN0YXR1cy5CRV9NT05JVE9SOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgc2libGluZ3MucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KHZhbHVlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgaWYgKCFsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGxldmVsLCBbXSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKGxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5nZXQobGV2ZWwpLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6K6+5aSHCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlID09PSBEYXRhVHlwZS5ERVZJQ0UpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgZGV2aWNlSWQgfSA9IG5vZGUuZGF0YTsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRldmljZUluZm8gPSBkZXZpY2VNYXAuZ2V0KGRldmljZUlkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZUluZm8ucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZU1hcC5zZXQoZGV2aWNlSWQsIGRldmljZUluZm8pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChsZXZlbCA+IG1heExldmVsKSB7CiAgICAgICAgICAgICAgICAgIG1heExldmVsID0gbGV2ZWw7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB7IGxpc3Q6IHNpYmxpbmdzLCBjb3VudCwgdG90YWwgfTsKICAgICAgICAgIH07CiAgICAgICAgICBjb25zdCB7IGxpc3QgfSA9IHRyYXZlcnNlKGRhdGEgfHwgW10pOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVzID0gbGlzdDsKICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgY2hhbm5lbE1hcCwKICAgICAgICAgICAgICB0cmVlTm9kZU1hcCwKICAgICAgICAgICAgICBkZXZpY2VNYXAsCiAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcCwKICAgICAgICAgICAgICBtYXhMZXZlbCwKICAgICAgICAgICAgICB0cmVlTm9kZXMsCiAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldAogICAgICAgICAgfTsKICAgICAgfQogICAgICByZXR1cm4gY3JlYXRlRGV2aWNlVHJlZShkYXRhKTsKICB9CiAgLy8g576k57uE6K6+5aSH5qCR57uT5p6ECiAgZnVuY3Rpb24gZ2VuZXJhdGVHcm91cERldmljZVRyZWUoZGF0YSwgY29uZmlnKSB7CiAgICAgIGNvbnN0IHsgZXhwYW5kZWRLZXlTZXQgfSA9IGNvbmZpZzsKICAgICAgY29uc3QgeyBzb3J0QnlTdGF0dXMsIHNob3dPbmxpbmVTdGF0ZSwgY2xlYXJFbXB0eUJ1c2luZXNzIH0gPSBjb25maWcuYnVzaW5lc3NDb25maWc7CiAgICAgIGNvbnN0IHsgZ2V0S2V5LCBnZXRMYWJlbCwgZ2V0Q2hpbGRyZW4sIGNvdW50RmlsdGVyLCB0b3RhbEZpbHRlciwgc2V0RGV2aWNlU3RhdHVzIH0gPSB1c2VIYW5kbGVGdW4oY29uZmlnKTsKICAgICAgY29uc3QgZmlsdGVyTGlzdCA9IGhhbmRsZUZpbHRlckNvbmZpZyhjb25maWcuYnVzaW5lc3NDb25maWc/LmZpbHRlckNvbmZpZyk7CiAgICAgIC8qKiDnvqTnu4Torr7lpIfmoJEgKi8KICAgICAgZnVuY3Rpb24gY3JlYXRlRGV2aWNlVHJlZShkYXRhKSB7CiAgICAgICAgICBsZXQgbWF4TGV2ZWwgPSAxOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBsZXZlbFRyZWVOb2RlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgZGV2aWNlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgaGlkZGVuTm9kZUtleVNldCA9IG5ldyBTZXQoKTsKICAgICAgICAgIGNvbnN0IHRyYXZlcnNlID0gKG5vZGVzLCBsZXZlbCA9IDEsIHBhcmVudCA9IHVuZGVmaW5lZCkgPT4gewogICAgICAgICAgICAgIGNvbnN0IHNpYmxpbmdzID0gW107CiAgICAgICAgICAgICAgbGV0IGNvdW50ID0gMDsKICAgICAgICAgICAgICBsZXQgdG90YWwgPSAwOwogICAgICAgICAgICAgIGZvciAobGV0IHJhd05vZGUgb2Ygbm9kZXMpIHsKICAgICAgICAgICAgICAgICAgLy8g5Lia5Yqh6YC76L6RCiAgICAgICAgICAgICAgICAgIGxldCBjaGlsZHJlbiA9IGdldENoaWxkcmVuKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICAvLyDnvqTnu4QKICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUuY2hpbGRyZW4/Lmxlbmd0aCB8fAogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS5ncm91cExpc3Q/Lmxlbmd0aCB8fAogICAgICAgICAgICAgICAgICAgICAgIVszLCA0XS5pbmNsdWRlcyhyYXdOb2RlLmRhdGFUeXBlKSkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZ3JvdXBMaXN0ID0gW107CiAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuID8gY2hpbGRyZW4gOiBbXTsKICAgICAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmdyb3VwTGlzdD8ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS5ncm91cExpc3QuZm9yRWFjaCgodikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkICsgJy0nICsgdi5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiB2Lmdyb3VwTmFtZSB8fCB2LmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IDQgLy8g5Luj6KGo576k57uECiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwTGlzdC5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBbLi4uY2hpbGRyZW4sIC4uLmdyb3VwTGlzdF07CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlID0gewogICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJhd05vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiAxLCAvLyDpg6jpl6gKICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcmF3Tm9kZS5vcmdOYW1lIHx8IHJhd05vZGUuY29tcGFueU5hbWUKICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6K6+5aSHCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRldmljZUxpc3Q/Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV2aWNlTGlzdCA9IFtbXSwgW11dOwogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiA/IGNoaWxkcmVuIDogW107CiAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlLmRldmljZUxpc3QuZm9yRWFjaCgodikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkICsgJy0nICsgdi5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHYuZGV2TmFtZSB8fCB2LmRldmljZUlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogMywgLy8g5Luj6KGo6K6+5aSHCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZVN0YXR1czogc2V0RGV2aWNlU3RhdHVzKHYpIC8vIOiuvuWkh+eKtuaAgQogICAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVzZUZpbHRlckNvbmZpZyh0YXJnZXQsIGZpbHRlckxpc3QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0YXJnZXQuZGV2aWNlU3RhdHVzID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VMaXN0W3NvcnRCeVN0YXR1cyA/IDEgOiAwXS5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldC5hZGQoZ2V0S2V5KHRhcmdldCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlTGlzdFswXS5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gWy4uLmNoaWxkcmVuLCAuLi5kZXZpY2VMaXN0WzBdLCAuLi5kZXZpY2VMaXN0WzFdXTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInorr7lpIfnmoTpg6jpl6jlkoznvqTnu4Qg5q2l6aqk5LiACiAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmIHJhd05vZGUuZGF0YVR5cGUgIT09IDMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDpgJrnlKjpgLvovpEKICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRLZXkocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgIGtleTogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhOiByYXdOb2RlCiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIG5vZGUubGFiZWwgPSBnZXRMYWJlbChyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgbm9kZS5leHBhbmRlZCA9IGV4cGFuZGVkS2V5U2V0Lmhhcyh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgIC8vIOmakOiXj+ayoeacieWcqOe6v+iuvuWkh+eahOmDqOmXqOWSjOe+pOe7hAogICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMCAmJiByYXdOb2RlLmRhdGFUeXBlICE9PSAzKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldC5hZGQobm9kZS5rZXkpOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbGlzdCwgY291bnQ6IGNoaWxkQ291bnQsIHRvdGFsOiBjaGlsZFRvdGFsIH0gPSB0cmF2ZXJzZShjaGlsZHJlbiwgbGV2ZWwgKyAxLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieiuvuWkh+eahOmDqOmXqOWSjOe+pOe7hCDmraXpqqTkuowKICAgICAgICAgICAgICAgICAgICAgIGlmICghc2hvd09ubGluZVN0YXRlICYmIGNsZWFyRW1wdHlCdXNpbmVzcyAmJiBjaGlsZFRvdGFsID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNoaWxkcmVuID0gbGlzdDsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSBjaGlsZENvdW50IDsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUudG90YWwgPSBjaGlsZFRvdGFsIDsKICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNoaWxkQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSBjaGlsZFRvdGFsOwogICAgICAgICAgICAgICAgICAgICAgLy8g5LuF5pi+56S65Zyo57q/6K6+5aSH5pe277yM6ZqQ6JeP5rKh5pyJ5Zyo57q/6K6+5aSH55qE6YOo6Zeo5ZKM576k57uECiAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlICYmICFjaGlsZENvdW50KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldC5hZGQobm9kZS5rZXkpOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gMDsKICAgICAgICAgICAgICAgICAgICAgIC8vIOe7n+iuoQogICAgICAgICAgICAgICAgICAgICAgaWYgKCFzaG93T25saW5lU3RhdGUgfHwgIWhpZGRlbk5vZGVLZXlTZXQuaGFzKG5vZGUua2V5KSkgewogICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gY291bnRGaWx0ZXIocmF3Tm9kZSkgPyAxIDogMDsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSB0b3RhbEZpbHRlcihyYXdOb2RlKSA/IDEgOiAwOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBzaWJsaW5ncy5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICB0cmVlTm9kZU1hcC5zZXQodmFsdWUsIG5vZGUpOwogICAgICAgICAgICAgICAgICBpZiAoIWxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5zZXQobGV2ZWwsIFtdKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAobGV2ZWxUcmVlTm9kZU1hcC5oYXMobGV2ZWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLmdldChsZXZlbCkucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDorr7lpIcKICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUuZGF0YVR5cGUgPT09IDMpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgZGV2aWNlSWQgfSA9IG5vZGUuZGF0YTsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGRldmljZUluZm8gPSBkZXZpY2VNYXAuZ2V0KGRldmljZUlkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZUluZm8ucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZU1hcC5zZXQoZGV2aWNlSWQsIGRldmljZUluZm8pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChsZXZlbCA+IG1heExldmVsKSB7CiAgICAgICAgICAgICAgICAgIG1heExldmVsID0gbGV2ZWw7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB7IGxpc3Q6IHNpYmxpbmdzLCBjb3VudCwgdG90YWwgfTsKICAgICAgICAgIH07CiAgICAgICAgICBjb25zdCB7IGxpc3QgfSA9IHRyYXZlcnNlKGRhdGEgfHwgW10pOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVzID0gbGlzdDsKICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgdHJlZU5vZGVNYXAsCiAgICAgICAgICAgICAgZGV2aWNlTWFwLAogICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAsCiAgICAgICAgICAgICAgbWF4TGV2ZWwsCiAgICAgICAgICAgICAgdHJlZU5vZGVzLAogICAgICAgICAgICAgIGhpZGRlbk5vZGVLZXlTZXQKICAgICAgICAgIH07CiAgICAgIH0KICAgICAgcmV0dXJuIGNyZWF0ZURldmljZVRyZWUoZGF0YSk7CiAgfQogIC8vIOe+pOe7hOagkee7k+aehAogIGZ1bmN0aW9uIGdlbmVyYXRlR3JvdXBUcmVlKGRhdGEsIGNvbmZpZykgewogICAgICBjb25zdCB7IGV4cGFuZGVkS2V5U2V0IH0gPSBjb25maWc7CiAgICAgIGNvbnN0IHsgY2xlYXJFbXB0eUJ1c2luZXNzIH0gPSBjb25maWcuYnVzaW5lc3NDb25maWc7CiAgICAgIGNvbnN0IHsgZ2V0S2V5LCBnZXRMYWJlbCwgZ2V0Q2hpbGRyZW59ID0gdXNlSGFuZGxlRnVuKGNvbmZpZyk7CiAgICAgIC8qKiDnvqTnu4TmoJEgKi8KICAgICAgZnVuY3Rpb24gY3JlYXRlR3JvdXBUcmVlKGRhdGEpIHsKICAgICAgICAgIGxldCBtYXhMZXZlbCA9IDE7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZU1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IGxldmVsVHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCB0cmF2ZXJzZSA9IChub2RlcywgbGV2ZWwgPSAxLCBwYXJlbnQgPSB1bmRlZmluZWQpID0+IHsKICAgICAgICAgICAgICBjb25zdCBzaWJsaW5ncyA9IFtdOwogICAgICAgICAgICAgIGxldCBjb3VudCA9IDA7CiAgICAgICAgICAgICAgbGV0IHRvdGFsID0gMDsKICAgICAgICAgICAgICBmb3IgKGxldCByYXdOb2RlIG9mIG5vZGVzKSB7CiAgICAgICAgICAgICAgICAgIGxldCBkZXZpY2VDb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgIGxldCBkZXZpY2VUb3RhbCA9IDA7CiAgICAgICAgICAgICAgICAgIC8vIOS4muWKoemAu+i+kQogICAgICAgICAgICAgICAgICBsZXQgY2hpbGRyZW4gPSBnZXRDaGlsZHJlbihyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgLy8g576k57uECiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmNoaWxkcmVuPy5sZW5ndGggfHwKICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUuZ3JvdXBMaXN0Py5sZW5ndGggfHwKICAgICAgICAgICAgICAgICAgICAgICFbMywgNF0uaW5jbHVkZXMocmF3Tm9kZS5kYXRhVHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGdyb3VwTGlzdCA9IFtdOwogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiA/IGNoaWxkcmVuIDogW107CiAgICAgICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5ncm91cExpc3Q/Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUuZ3JvdXBMaXN0LmZvckVhY2goKHYpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCArICctJyArIHYuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdi5ncm91cE5hbWUgfHwgdi5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiA0IC8vIOS7o+ihqOe+pOe7hAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cExpc3QucHVzaCh0YXJnZXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gWy4uLmNoaWxkcmVuLCAuLi5ncm91cExpc3RdOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5yYXdOb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogMSwgLy8g6YOo6ZeoCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHJhd05vZGUub3JnTmFtZSB8fCByYXdOb2RlLmNvbXBhbnlOYW1lCiAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOiuvuWkhwogICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kZXZpY2VMaXN0Py5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZUNvdW50ID0gcmF3Tm9kZS5kZXZpY2VMaXN0LnJlZHVjZSgodmFsdWUsIHYpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdmFsdWUgKyAodi5vbmxpbmVTdGF0ZSA9PT0gMSA/IDEgOiAwKTsKICAgICAgICAgICAgICAgICAgICAgIH0sIGRldmljZUNvdW50KTsKICAgICAgICAgICAgICAgICAgICAgIGRldmljZVRvdGFsID0gcmF3Tm9kZS5kZXZpY2VMaXN0Lmxlbmd0aCB8fCAwOwogICAgICAgICAgICAgICAgICAgICAgY291bnQgKz0gZGV2aWNlQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSBkZXZpY2VUb3RhbDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInorr7lpIflkoznvqTnu4TnmoTpg6jpl6gg5q2l6aqk5LiACiAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmICFbMywgNF0uaW5jbHVkZXMocmF3Tm9kZS5kYXRhVHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDlpITnkIbpgLvovpEKICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRLZXkocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgIGtleTogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhOiByYXdOb2RlCiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIG5vZGUubGFiZWwgPSBnZXRMYWJlbChyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgbm9kZS5leHBhbmRlZCA9IGV4cGFuZGVkS2V5U2V0Lmhhcyh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbGlzdCwgY291bnQ6IGNoaWxkQ291bnQsIHRvdGFsOiBjaGlsZFRvdGFsIH0gPSB0cmF2ZXJzZShjaGlsZHJlbiwgbGV2ZWwgKyAxLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieiuvuWkh+eahOmDqOmXqOWSjOe+pOe7hCDmraXpqqTkuowKICAgICAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MgJiYgY2hpbGRUb3RhbCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IGxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hpbGRDb3VudCA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gY2hpbGRUb3RhbCA7CiAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGlsZENvdW50OwogICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hpbGRUb3RhbDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIGlmIChyYXdOb2RlLmRhdGFUeXBlICE9PSAzKSB7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gZGV2aWNlQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gZGV2aWNlVG90YWw7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgc2libGluZ3MucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KHZhbHVlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgaWYgKCFsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGxldmVsLCBbXSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKGxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5nZXQobGV2ZWwpLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKGxldmVsID4gbWF4TGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgbWF4TGV2ZWwgPSBsZXZlbDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHsgbGlzdDogc2libGluZ3MsIGNvdW50LCB0b3RhbCB9OwogICAgICAgICAgfTsKICAgICAgICAgIGNvbnN0IHsgbGlzdCB9ID0gdHJhdmVyc2UoZGF0YSB8fCBbXSk7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZXMgPSBsaXN0OwogICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICB0cmVlTm9kZU1hcCwKICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIG1heExldmVsLAogICAgICAgICAgICAgIHRyZWVOb2RlcywKICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0OiBuZXcgU2V0KCkKICAgICAgICAgIH07CiAgICAgIH0KICAgICAgcmV0dXJuIGNyZWF0ZUdyb3VwVHJlZShkYXRhKTsKICB9CiAgLy8g55So5oi35qCR57uT5p6ECiAgZnVuY3Rpb24gZ2VuZXJhdGVVc2VyVHJlZShkYXRhLCBjb25maWcpIHsKICAgICAgY29uc3QgeyBleHBhbmRlZEtleVNldCB9ID0gY29uZmlnOwogICAgICBjb25zdCB7IGNsZWFyRW1wdHlCdXNpbmVzcyB9ID0gY29uZmlnLmJ1c2luZXNzQ29uZmlnOwogICAgICBjb25zdCB7IGdldEtleSwgZ2V0TGFiZWwsIGdldENoaWxkcmVuLCBjb3VudEZpbHRlciwgdG90YWxGaWx0ZXIgfSA9IHVzZUhhbmRsZUZ1bihjb25maWcpOwogICAgICBjb25zdCBmaWx0ZXJMaXN0ID0gaGFuZGxlRmlsdGVyQ29uZmlnKGNvbmZpZy5idXNpbmVzc0NvbmZpZz8uZmlsdGVyQ29uZmlnKTsKICAgICAgLyoqIOeUqOaIt+agkSAqLwogICAgICBmdW5jdGlvbiBjcmVhdGVVc2VyVHJlZShkYXRhKSB7CiAgICAgICAgICBsZXQgbWF4TGV2ZWwgPSAxOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBsZXZlbFRyZWVOb2RlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgdXNlck1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IHRyYXZlcnNlID0gKG5vZGVzLCBsZXZlbCA9IDEsIHBhcmVudCA9IHVuZGVmaW5lZCkgPT4gewogICAgICAgICAgICAgIGNvbnN0IHNpYmxpbmdzID0gW107CiAgICAgICAgICAgICAgbGV0IGNvdW50ID0gMDsKICAgICAgICAgICAgICBsZXQgdG90YWwgPSAwOwogICAgICAgICAgICAgIGZvciAobGV0IHJhd05vZGUgb2Ygbm9kZXMpIHsKICAgICAgICAgICAgICAgICAgLy8g5Lia5Yqh6YC76L6RCiAgICAgICAgICAgICAgICAgIGxldCBjaGlsZHJlbiA9IGdldENoaWxkcmVuKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kYXRhVHlwZSAhPT0gNSkgewogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiA/IGNoaWxkcmVuIDogW107CiAgICAgICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kZXZpY2VVc2VyTGlzdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUuZGV2aWNlVXNlckxpc3QuZm9yRWFjaCgodikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0YXJnZXQgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkICsgJy0nICsgdi5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiB2Lm5hbWUgfHwgdi5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiA1LCAvLyDku6PooajnlKjmiLcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVzZUZpbHRlckNvbmZpZyh0YXJnZXQsIGZpbHRlckxpc3QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbi5wdXNoKHRhcmdldCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucmF3Tm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5SWQ6IHJhd05vZGUuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IDEsIC8vIOmDqOmXqAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiByYXdOb2RlLm9yZ05hbWUgfHwgcmF3Tm9kZS5jb21wYW55TmFtZQogICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInnlKjmiLfnmoTpg6jpl6gg5q2l6aqk5LiACiAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmIHJhd05vZGUuZGF0YVR5cGUgIT09IDUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDpgJrnlKjpgLvovpEKICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRLZXkocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgIGtleTogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhOiByYXdOb2RlCiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIG5vZGUubGFiZWwgPSBnZXRMYWJlbChyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgbm9kZS5leHBhbmRlZCA9IGV4cGFuZGVkS2V5U2V0Lmhhcyh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbGlzdCwgY291bnQ6IGNoaWxkQ291bnQsIHRvdGFsOiBjaGlsZFRvdGFsIH0gPSB0cmF2ZXJzZShjaGlsZHJlbiwgbGV2ZWwgKyAxLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieeUqOaIt+eahOmDqOmXqCDmraXpqqTkuowKICAgICAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MgJiYgY2hpbGRUb3RhbCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IGxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hpbGRDb3VudCA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gY2hpbGRUb3RhbCA7CiAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGlsZENvdW50OwogICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hpbGRUb3RhbDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAvLyDnu5/orqEKICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjb3VudEZpbHRlcihyYXdOb2RlKSA/IDEgOiAwOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRvdGFsRmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgc2libGluZ3MucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KHZhbHVlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgaWYgKCFsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGxldmVsLCBbXSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKGxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5nZXQobGV2ZWwpLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g55So5oi3CiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlID09PSA1KSB7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGlkIH0gPSBub2RlLmRhdGE7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1c2VyTGlzdCA9IHVzZXJNYXAuZ2V0KGlkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIHVzZXJMaXN0LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICB1c2VyTWFwLnNldChpZCwgdXNlckxpc3QpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIGlmIChsZXZlbCA+IG1heExldmVsKSB7CiAgICAgICAgICAgICAgICAgIG1heExldmVsID0gbGV2ZWw7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIHJldHVybiB7IGxpc3Q6IHNpYmxpbmdzLCBjb3VudCwgdG90YWwgfTsKICAgICAgICAgIH07CiAgICAgICAgICBjb25zdCB7IGxpc3QgfSA9IHRyYXZlcnNlKGRhdGEgfHwgW10pOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVzID0gbGlzdDsKICAgICAgICAgIHJldHVybiB7CiAgICAgICAgICAgICAgdHJlZU5vZGVNYXAsCiAgICAgICAgICAgICAgdXNlck1hcCwKICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIG1heExldmVsLAogICAgICAgICAgICAgIHRyZWVOb2RlcywKICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0OiBuZXcgU2V0KCkKICAgICAgICAgIH07CiAgICAgIH0KICAgICAgcmV0dXJuIGNyZWF0ZVVzZXJUcmVlKGRhdGEpOwogIH0KICAvLyDpmJ/kvI3nlKjmiLfmoJHnu5PmnoQKICBmdW5jdGlvbiBnZW5lcmF0ZVRlYW1Vc2VyVHJlZShkYXRhLCBjb25maWcpIHsKICAgICAgY29uc3QgeyBleHBhbmRlZEtleVNldCB9ID0gY29uZmlnOwogICAgICBjb25zdCB7IGNsZWFyRW1wdHlCdXNpbmVzcyB9ID0gY29uZmlnLmJ1c2luZXNzQ29uZmlnOwogICAgICBjb25zdCB7IGdldEtleSwgZ2V0TGFiZWwsIGdldENoaWxkcmVuLCBjb3VudEZpbHRlciwgdG90YWxGaWx0ZXIgfSA9IHVzZUhhbmRsZUZ1bihjb25maWcpOwogICAgICBjb25zdCBmaWx0ZXJMaXN0ID0gaGFuZGxlRmlsdGVyQ29uZmlnKGNvbmZpZy5idXNpbmVzc0NvbmZpZz8uZmlsdGVyQ29uZmlnKTsKICAgICAgLyoqIOmYn+S8jeeUqOaIt+agkSAqLwogICAgICBmdW5jdGlvbiBjcmVhdGVVc2VyVHJlZShkYXRhKSB7CiAgICAgICAgICBsZXQgbWF4TGV2ZWwgPSAxOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBsZXZlbFRyZWVOb2RlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgdXNlck1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IHRlYW1NYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCB0cmF2ZXJzZSA9IChub2RlcywgbGV2ZWwgPSAxLCBwYXJlbnQgPSB1bmRlZmluZWQpID0+IHsKICAgICAgICAgICAgICBjb25zdCBzaWJsaW5ncyA9IFtdOwogICAgICAgICAgICAgIGxldCBjb3VudCA9IDA7CiAgICAgICAgICAgICAgbGV0IHRvdGFsID0gMDsKICAgICAgICAgICAgICBmb3IgKGxldCByYXdOb2RlIG9mIG5vZGVzKSB7CiAgICAgICAgICAgICAgICAgIC8vIOS4muWKoemAu+i+kQogICAgICAgICAgICAgICAgICBsZXQgY2hpbGRyZW4gPSBnZXRDaGlsZHJlbihyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgLy8g6Zif5LyNCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmNoaWxkcmVuPy5sZW5ndGggfHwKICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUudGFza1RlYW1MaXN0Py5sZW5ndGggfHwKICAgICAgICAgICAgICAgICAgICAgICFbRGF0YVR5cGUuVVNFUiwgRGF0YVR5cGUuVEVBTV0uaW5jbHVkZXMocmF3Tm9kZS5kYXRhVHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gY2hpbGRyZW4gPyBjaGlsZHJlbiA6IFtdOwogICAgICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUudGFza1RlYW1MaXN0Py5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlLnRhc2tUZWFtTGlzdC5mb3JFYWNoKCh2KSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2goewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCArICctJyArIHYuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdi50ZWFtTmFtZSB8fCB2LmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLlRFQU0sIC8vIOmYn+S8jQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgLi4ucmF3Tm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5SWQ6IHJhd05vZGUuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLkRFUFQsIC8vIOmDqOmXqAogICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiByYXdOb2RlLm9yZ05hbWUgfHwgcmF3Tm9kZS5jb21wYW55TmFtZQogICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDnlKjmiLcKICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUubWVtYmVyTGlzdD8ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuID8gY2hpbGRyZW4gOiBbXTsKICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUubWVtYmVyTGlzdC5mb3JFYWNoKCh2KSA9PiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi52LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbmx5SWQ6IHJhd05vZGUuaWQgKyAnLScgKyB2LnVzZXJJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHYubmFtZSB8fCB2LnVzZXJJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLlVTRVIsIC8vIOS7o+ihqOeUqOaItwogICAgICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHVzZUZpbHRlckNvbmZpZyh0YXJnZXQsIGZpbHRlckxpc3QpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2godGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInnlKjmiLfnmoTpg6jpl6jmiJbpmJ/kvI0g5q2l6aqk5LiACiAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmIHJhd05vZGUuZGF0YVR5cGUgIT09IERhdGFUeXBlLlVTRVIpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDpgJrnlKjpgLvovpEKICAgICAgICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBnZXRLZXkocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGNvbnN0IG5vZGUgPSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbCwKICAgICAgICAgICAgICAgICAgICAgIGtleTogdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICBkYXRhOiByYXdOb2RlCiAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIG5vZGUubGFiZWwgPSBnZXRMYWJlbChyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgbm9kZS5wYXJlbnQgPSBwYXJlbnQ7CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgbm9kZS5leHBhbmRlZCA9IGV4cGFuZGVkS2V5U2V0Lmhhcyh2YWx1ZSk7CiAgICAgICAgICAgICAgICAgIGlmIChjaGlsZHJlbiAmJiBjaGlsZHJlbi5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgbGlzdCwgY291bnQ6IGNoaWxkQ291bnQsIHRvdGFsOiBjaGlsZFRvdGFsIH0gPSB0cmF2ZXJzZShjaGlsZHJlbiwgbGV2ZWwgKyAxLCBub2RlKTsKICAgICAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieeUqOaIt+eahOmDqOmXqCDmraXpqqTkuowKICAgICAgICAgICAgICAgICAgICAgIGlmIChjbGVhckVtcHR5QnVzaW5lc3MgJiYgY2hpbGRUb3RhbCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IGxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hpbGRDb3VudCA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gY2hpbGRUb3RhbCA7CiAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGlsZENvdW50OwogICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hpbGRUb3RhbDsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAvLyDnu5/orqEKICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjb3VudEZpbHRlcihyYXdOb2RlKSA/IDEgOiAwOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIHRvdGFsICs9IHRvdGFsRmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgc2libGluZ3MucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KHZhbHVlLCBub2RlKTsKICAgICAgICAgICAgICAgICAgaWYgKCFsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGxldmVsLCBbXSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgaWYgKGxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5nZXQobGV2ZWwpLnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6Zif5LyNCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlID09PSBEYXRhVHlwZS5URUFNKSB7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGlkIH0gPSBub2RlLmRhdGE7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0ZWFtTGlzdCA9IHRlYW1NYXAuZ2V0KGlkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIHRlYW1MaXN0LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICB0ZWFtTWFwLnNldChpZCwgdGVhbUxpc3QpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOeUqOaItwogICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuVVNFUikgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyB1c2VySWQgfSA9IG5vZGUuZGF0YTsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVzZXJMaXN0ID0gdXNlck1hcC5nZXQodXNlcklkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIHVzZXJMaXN0LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICB1c2VyTWFwLnNldCh1c2VySWQsIHVzZXJMaXN0KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAobGV2ZWwgPiBtYXhMZXZlbCkgewogICAgICAgICAgICAgICAgICBtYXhMZXZlbCA9IGxldmVsOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4geyBsaXN0OiBzaWJsaW5ncywgY291bnQsIHRvdGFsIH07CiAgICAgICAgICB9OwogICAgICAgICAgY29uc3QgeyBsaXN0IH0gPSB0cmF2ZXJzZShkYXRhIHx8IFtdKTsKICAgICAgICAgIGNvbnN0IHRyZWVOb2RlcyA9IGxpc3Q7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgIHRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIHRlYW1NYXAsCiAgICAgICAgICAgICAgdXNlck1hcCwKICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIG1heExldmVsLAogICAgICAgICAgICAgIHRyZWVOb2RlcywKICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0OiBuZXcgU2V0KCkKICAgICAgICAgIH07CiAgICAgIH0KICAgICAgcmV0dXJuIGNyZWF0ZVVzZXJUcmVlKGRhdGEpOwogIH0KICAvLyDph4fpm4bnq5nmoJHnu5PmnoQKICBmdW5jdGlvbiBnZW5lcmF0ZUNzVHJlZShkYXRhLCBjb25maWcpIHsKICAgICAgY29uc3QgeyBleHBhbmRlZEtleVNldCB9ID0gY29uZmlnOwogICAgICBjb25zdCB7IGNsZWFyRW1wdHlCdXNpbmVzcyB9ID0gY29uZmlnLmJ1c2luZXNzQ29uZmlnOwogICAgICBjb25zdCB7IGdldEtleSwgZ2V0TGFiZWwsIGdldENoaWxkcmVuLCBjb3VudEZpbHRlciwgdG90YWxGaWx0ZXIgfSA9IHVzZUhhbmRsZUZ1bihjb25maWcpOwogICAgICBjb25zdCBmaWx0ZXJMaXN0ID0gaGFuZGxlRmlsdGVyQ29uZmlnKGNvbmZpZy5idXNpbmVzc0NvbmZpZz8uZmlsdGVyQ29uZmlnKTsKICAgICAgLyoqIOmHh+mbhuermeagkSAqLwogICAgICBmdW5jdGlvbiBjcmVhdGVDc1RyZWUoZGF0YSkgewogICAgICAgICAgbGV0IG1heExldmVsID0gMTsKICAgICAgICAgIGNvbnN0IHRyZWVOb2RlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgbGV2ZWxUcmVlTm9kZU1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IGNzTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgdHJhdmVyc2UgPSAobm9kZXMsIGxldmVsID0gMSwgcGFyZW50ID0gdW5kZWZpbmVkKSA9PiB7CiAgICAgICAgICAgICAgY29uc3Qgc2libGluZ3MgPSBbXTsKICAgICAgICAgICAgICBsZXQgY291bnQgPSAwOwogICAgICAgICAgICAgIGxldCB0b3RhbCA9IDA7CiAgICAgICAgICAgICAgZm9yIChsZXQgcmF3Tm9kZSBvZiBub2RlcykgewogICAgICAgICAgICAgICAgICAvLyDkuJrliqHpgLvovpEKICAgICAgICAgICAgICAgICAgbGV0IGNoaWxkcmVuID0gZ2V0Q2hpbGRyZW4ocmF3Tm9kZSk7CiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlICE9PSA4KSB7CiAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IGNoaWxkcmVuID8gY2hpbGRyZW4gOiBbXTsKICAgICAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmNzTGlzdCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUuY3NMaXN0LmZvckVhY2goKHYpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCArICctJyArIHYuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdi5zbmFtZSB8fCB2LnNjb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IDgsIC8vIOS7o+ihqOmHh+mbhuermQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlRmlsdGVyQ29uZmlnKHRhcmdldCwgZmlsdGVyTGlzdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLnB1c2godGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5yYXdOb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogMSwgLy8g6YOo6ZeoCiAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHJhd05vZGUub3JnTmFtZSB8fCByYXdOb2RlLmNvbXBhbnlOYW1lCiAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeaciemHh+mbhuWZqOeahOmDqOmXqCDmraXpqqTkuIAKICAgICAgICAgICAgICAgICAgaWYgKGNsZWFyRW1wdHlCdXNpbmVzcykgewogICAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZHJlbiB8fCBjaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgcmF3Tm9kZS5kYXRhVHlwZSAhPT0gOCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOmAmueUqOmAu+i+kQogICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGdldEtleShyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsLAogICAgICAgICAgICAgICAgICAgICAga2V5OiB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHJhd05vZGUKICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgbm9kZS5sYWJlbCA9IGdldExhYmVsKHJhd05vZGUpOwogICAgICAgICAgICAgICAgICBub2RlLnBhcmVudCA9IHBhcmVudDsKICAgICAgICAgICAgICAgICAgbm9kZS5pc0xlYWYgPSAhY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwOwogICAgICAgICAgICAgICAgICBub2RlLmV4cGFuZGVkID0gZXhwYW5kZWRLZXlTZXQuaGFzKHZhbHVlKTsKICAgICAgICAgICAgICAgICAgaWYgKGNoaWxkcmVuICYmIGNoaWxkcmVuLmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBsaXN0LCBjb3VudDogY2hpbGRDb3VudCwgdG90YWw6IGNoaWxkVG90YWwgfSA9IHRyYXZlcnNlKGNoaWxkcmVuLCBsZXZlbCArIDEsIG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgLy8g6L+H5ruk5rKh5pyJ6YeH6ZuG5Zmo55qE6YOo6ZeoIOatpemqpOS6jAogICAgICAgICAgICAgICAgICAgICAgaWYgKGNsZWFyRW1wdHlCdXNpbmVzcyAmJiBjaGlsZFRvdGFsID09PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNoaWxkcmVuID0gbGlzdDsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSBjaGlsZENvdW50IDsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUudG90YWwgPSBjaGlsZFRvdGFsIDsKICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNoaWxkQ291bnQ7CiAgICAgICAgICAgICAgICAgICAgICB0b3RhbCArPSBjaGlsZFRvdGFsOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jb3VudCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gMDsKICAgICAgICAgICAgICAgICAgICAgIC8vIOe7n+iuoQogICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNvdW50RmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdG90YWxGaWx0ZXIocmF3Tm9kZSkgPyAxIDogMDsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBzaWJsaW5ncy5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICB0cmVlTm9kZU1hcC5zZXQodmFsdWUsIG5vZGUpOwogICAgICAgICAgICAgICAgICBpZiAoIWxldmVsVHJlZU5vZGVNYXAuaGFzKGxldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcC5zZXQobGV2ZWwsIFtdKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBpZiAobGV2ZWxUcmVlTm9kZU1hcC5oYXMobGV2ZWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLmdldChsZXZlbCkucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAvLyDph4fpm4bnq5kKICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUuZGF0YVR5cGUgPT09IDgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHsgaWQgfSA9IG5vZGUuZGF0YTsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVzZXJMaXN0ID0gY3NNYXAuZ2V0KGlkKSB8fCBbXTsKICAgICAgICAgICAgICAgICAgICAgIHVzZXJMaXN0LnB1c2gobm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICBjc01hcC5zZXQoaWQsIHVzZXJMaXN0KTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICBpZiAobGV2ZWwgPiBtYXhMZXZlbCkgewogICAgICAgICAgICAgICAgICBtYXhMZXZlbCA9IGxldmVsOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgICByZXR1cm4geyBsaXN0OiBzaWJsaW5ncywgY291bnQsIHRvdGFsIH07CiAgICAgICAgICB9OwogICAgICAgICAgY29uc3QgeyBsaXN0IH0gPSB0cmF2ZXJzZShkYXRhIHx8IFtdKTsKICAgICAgICAgIGNvbnN0IHRyZWVOb2RlcyA9IGxpc3Q7CiAgICAgICAgICByZXR1cm4gewogICAgICAgICAgICAgIHRyZWVOb2RlTWFwLAogICAgICAgICAgICAgIGNzTWFwLAogICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAsCiAgICAgICAgICAgICAgbWF4TGV2ZWwsCiAgICAgICAgICAgICAgdHJlZU5vZGVzLAogICAgICAgICAgICAgIGhpZGRlbk5vZGVLZXlTZXQ6IG5ldyBTZXQoKQogICAgICAgICAgfTsKICAgICAgfQogICAgICByZXR1cm4gY3JlYXRlQ3NUcmVlKGRhdGEpOwogIH0KICAvLyDpooTmoYjliIbnu4Torr7lpIfmoJHnu5PmnoQKICBmdW5jdGlvbiBnZW5lcmF0ZVBsYW5Hcm91cERldmljZVRyZWUoZGF0YSwgY29uZmlnKSB7CiAgICAgIGNvbnN0IHsgZXhwYW5kZWRLZXlTZXQgfSA9IGNvbmZpZzsKICAgICAgY29uc3QgeyBzb3J0QnlTdGF0dXMsIHNob3dPbmxpbmVTdGF0ZSwgY2xlYXJFbXB0eUJ1c2luZXNzIH0gPSBjb25maWcuYnVzaW5lc3NDb25maWc7CiAgICAgIGNvbnN0IHsgZ2V0S2V5LCBnZXRMYWJlbCwgZ2V0Q2hpbGRyZW4sIGNvdW50RmlsdGVyLCB0b3RhbEZpbHRlciwgc2V0RGV2aWNlU3RhdHVzIH0gPSB1c2VIYW5kbGVGdW4oY29uZmlnKTsKICAgICAgY29uc3QgZmlsdGVyTGlzdCA9IGhhbmRsZUZpbHRlckNvbmZpZyhjb25maWcuYnVzaW5lc3NDb25maWc/LmZpbHRlckNvbmZpZyk7CiAgICAgIC8qKiDpooTmoYjliIbnu4Torr7lpIfmoJEgKi8KICAgICAgZnVuY3Rpb24gY3JlYXRlRGV2aWNlVHJlZShkYXRhKSB7CiAgICAgICAgICBsZXQgbWF4TGV2ZWwgPSAxOwogICAgICAgICAgY29uc3QgdHJlZU5vZGVNYXAgPSBuZXcgTWFwKCk7CiAgICAgICAgICBjb25zdCBsZXZlbFRyZWVOb2RlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgcGxhbkdyb3VwTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgZGV2aWNlTWFwID0gbmV3IE1hcCgpOwogICAgICAgICAgY29uc3QgY2hhbm5lbE1hcCA9IG5ldyBNYXAoKTsKICAgICAgICAgIGNvbnN0IGhpZGRlbk5vZGVLZXlTZXQgPSBuZXcgU2V0KCk7CiAgICAgICAgICBjb25zdCB0cmF2ZXJzZSA9IChub2RlcywgbGV2ZWwgPSAxLCBwYXJlbnQgPSB1bmRlZmluZWQpID0+IHsKICAgICAgICAgICAgICBjb25zdCBzaWJsaW5ncyA9IFtdOwogICAgICAgICAgICAgIGxldCBjb3VudCA9IDA7CiAgICAgICAgICAgICAgbGV0IHRvdGFsID0gMDsKICAgICAgICAgICAgICBmb3IgKGxldCByYXdOb2RlIG9mIG5vZGVzKSB7CiAgICAgICAgICAgICAgICAgIC8vIOS4muWKoemAu+i+kQogICAgICAgICAgICAgICAgICBsZXQgY2hpbGRyZW4gPSBnZXRDaGlsZHJlbihyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgLy8g6aKE5qGI5YiG57uECiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmNoaWxkcmVuPy5sZW5ndGggfHwKICAgICAgICAgICAgICAgICAgICAgIHJhd05vZGUucGxhbkdyb3VwTGlzdD8ubGVuZ3RoIHx8CiAgICAgICAgICAgICAgICAgICAgICAhW0RhdGFUeXBlLkRFVklDRSwgRGF0YVR5cGUuUExBTl9HUk9VUF0uaW5jbHVkZXMocmF3Tm9kZS5kYXRhVHlwZSkpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBsYW5Hcm91cExpc3QgPSBbXTsKICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gY2hpbGRyZW4gPyBjaGlsZHJlbiA6IFtdOwogICAgICAgICAgICAgICAgICAgICAgaWYgKHJhd05vZGUucGxhbkdyb3VwTGlzdD8ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS5wbGFuR3JvdXBMaXN0LmZvckVhY2goKHYpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdGFyZ2V0ID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5pZCArICctJyArIHYuaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogdi5ncm91cE5hbWUgfHwgdi5pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiBEYXRhVHlwZS5QTEFOX0dST1VQIC8vIOS7o+ihqOmihOahiOWIhue7hAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwbGFuR3JvdXBMaXN0LnB1c2godGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgICAgICBjaGlsZHJlbiA9IFsuLi5jaGlsZHJlbiwgLi4ucGxhbkdyb3VwTGlzdF07CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlID0gewogICAgICAgICAgICAgICAgICAgICAgICAgIC4uLnJhd05vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkLAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUeXBlOiBEYXRhVHlwZS5ERVBULCAvLyDpg6jpl6gKICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogcmF3Tm9kZS5vcmdOYW1lIHx8IHJhd05vZGUuY29tcGFueU5hbWUKICAgICAgICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6K6+5aSHCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRldmljZUxpc3Q/Lmxlbmd0aCkgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV2aWNlTGlzdCA9IFtbXSwgW11dOwogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbiA/IGNoaWxkcmVuIDogW107CiAgICAgICAgICAgICAgICAgICAgICByYXdOb2RlLmRldmljZUxpc3QuZm9yRWFjaCgodikgPT4gewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4udiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb25seUlkOiByYXdOb2RlLmlkICsgJy0nICsgdi5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6IHYuZGV2TmFtZSB8fCB2LmRldmljZUlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhVHlwZTogRGF0YVR5cGUuREVWSUNFLCAvLyDku6Pooajorr7lpIcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlU3RhdHVzOiBzZXREZXZpY2VTdGF0dXModikgLy8g6K6+5aSH54q25oCBCiAgICAgICAgICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodXNlRmlsdGVyQ29uZmlnKHRhcmdldCwgZmlsdGVyTGlzdCkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldC5kZXZpY2VTdGF0dXMgPT09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRldmljZUxpc3Rbc29ydEJ5U3RhdHVzID8gMSA6IDBdLnB1c2godGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzaG93T25saW5lU3RhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChnZXRLZXkodGFyZ2V0KSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZpY2VMaXN0WzBdLnB1c2godGFyZ2V0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgIH0pOwogICAgICAgICAgICAgICAgICAgICAgY2hpbGRyZW4gPSBbLi4uY2hpbGRyZW4sIC4uLmRldmljZUxpc3RbMF0sIC4uLmRldmljZUxpc3RbMV1dOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOi/h+a7pOayoeacieiuvuWkh+eahOmDqOmXqOWSjOe+pOe7hCDmraXpqqTkuIAKICAgICAgICAgICAgICAgICAgaWYgKGNsZWFyRW1wdHlCdXNpbmVzcykgewogICAgICAgICAgICAgICAgICAgICAgaWYgKCFjaGlsZHJlbiB8fCBjaGlsZHJlbi5sZW5ndGggPT09IDAgJiYgcmF3Tm9kZS5kYXRhVHlwZSAhPT0gMykgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOmAmueUqOmAu+i+kQogICAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZSA9IGdldEtleShyYXdOb2RlKTsKICAgICAgICAgICAgICAgICAgY29uc3Qgbm9kZSA9IHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsLAogICAgICAgICAgICAgICAgICAgICAga2V5OiB2YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHJhd05vZGUsCiAgICAgICAgICAgICAgICAgICAgICBsYWJlbDogZ2V0TGFiZWwocmF3Tm9kZSksCiAgICAgICAgICAgICAgICAgICAgICBwYXJlbnQsCiAgICAgICAgICAgICAgICAgICAgICBleHBhbmRlZDogZXhwYW5kZWRLZXlTZXQuaGFzKHZhbHVlKSwKICAgICAgICAgICAgICAgICAgICAgIGlzTGVhZjogZmFsc2UKICAgICAgICAgICAgICAgICAgfTsKICAgICAgICAgICAgICAgICAgLy8g6ZqQ6JeP5rKh5pyJ5Zyo57q/6K6+5aSH55qE6YOo6Zeo5ZKM576k57uECiAgICAgICAgICAgICAgICAgIGlmIChzaG93T25saW5lU3RhdGUpIHsKICAgICAgICAgICAgICAgICAgICAgIGlmICghY2hpbGRyZW4gfHwgY2hpbGRyZW4ubGVuZ3RoID09PSAwICYmIHJhd05vZGUuZGF0YVR5cGUgIT09IDMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChub2RlLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6Z2e6K6+5aSH57G75Z6L5pWw5o2uCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlICE9PSBEYXRhVHlwZS5ERVZJQ0UgJiYgY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB7CiAgICAgICAgICAgICAgICAgICAgICBjb25zdCB7IGxpc3QsIGNvdW50OiBjaGlsZENvdW50LCB0b3RhbDogY2hpbGRUb3RhbCB9ID0gdHJhdmVyc2UoY2hpbGRyZW4sIGxldmVsICsgMSwgbm9kZSk7CiAgICAgICAgICAgICAgICAgICAgICAvLyDov4fmu6TmsqHmnInorr7lpIfnmoTpg6jpl6jlkozpooTmoYjliIbnu4Qg5q2l6aqk5LqMCiAgICAgICAgICAgICAgICAgICAgICBpZiAoIXNob3dPbmxpbmVTdGF0ZSAmJiBjbGVhckVtcHR5QnVzaW5lc3MgJiYgY2hpbGRUb3RhbCA9PT0gMCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiA9IGxpc3Q7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hpbGRDb3VudCA7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLnRvdGFsID0gY2hpbGRUb3RhbCA7CiAgICAgICAgICAgICAgICAgICAgICBjb3VudCArPSBjaGlsZENvdW50OwogICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gY2hpbGRUb3RhbDsKICAgICAgICAgICAgICAgICAgICAgIC8vIOS7heaYvuekuuWcqOe6v+iuvuWkh+aXtu+8jOmakOiXj+ayoeacieWcqOe6v+iuvuWkh+eahOmDqOmXqOWSjOmihOahiOWIhue7hAogICAgICAgICAgICAgICAgICAgICAgaWYgKHNob3dPbmxpbmVTdGF0ZSAmJiAhY2hpbGRDb3VudCkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGhpZGRlbk5vZGVLZXlTZXQuYWRkKG5vZGUua2V5KTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgIG5vZGUuY291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAvLyDnu5/orqEKICAgICAgICAgICAgICAgICAgICAgIGlmICghc2hvd09ubGluZVN0YXRlIHx8ICFoaWRkZW5Ob2RlS2V5U2V0Lmhhcyhub2RlLmtleSkpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvdW50ICs9IGNvdW50RmlsdGVyKHJhd05vZGUpID8gMSA6IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWwgKz0gdG90YWxGaWx0ZXIocmF3Tm9kZSkgPyAxIDogMDsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgLy8g6K6+5aSH57G75Z6L5pWw5o2u77yM5LiU5pyJ6YCa6YGT5pWw5o2u5aSE55CGCiAgICAgICAgICAgICAgICAgIGlmIChyYXdOb2RlLmRhdGFUeXBlID09PSBEYXRhVHlwZS5ERVZJQ0UgJiYgcmF3Tm9kZS52aWRlb0NoYW5uZWxMaXN0Py5sZW5ndGgpIHsKICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWxMZXZlbCA9IGxldmVsICsgMTsKICAgICAgICAgICAgICAgICAgICAgIGlmICghbGV2ZWxUcmVlTm9kZU1hcC5oYXMoY2hhbm5lbExldmVsKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuc2V0KGNoYW5uZWxMZXZlbCwgW10pOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhbm5lbExpc3QgPSBbW10sIFtdXTsKICAgICAgICAgICAgICAgICAgICAgIGxldCBjaGFubmVsT25saW5lQ291bnQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgbGV0IGhhc0JlTW9uaXRvciA9IGZhbHNlOwogICAgICAgICAgICAgICAgICAgICAgcmF3Tm9kZS52aWRlb0NoYW5uZWxMaXN0LmZvckVhY2goKGMpID0+IHsKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFubmVsID0gewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IHJhd05vZGUub25seUlkICsgJy0nICsgYy5jaGFubmVsSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjLmNoYW5uZWxOYW1lIHx8IGMuY2hhbm5lbElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbDogbGV2ZWwgKyAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudDogMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG90YWw6IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGFuZGVkOiBmYWxzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNMZWFmOiB0cnVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5jLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSWQ6IHJhd05vZGUuZGV2aWNlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXZOYW1lOiByYXdOb2RlLmRldk5hbWUgfHwgcmF3Tm9kZS5kZXZpY2VJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ubHlJZDogcmF3Tm9kZS5vbmx5SWQgKyAnLScgKyBjLmNoYW5uZWxJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVsOiBjLmNoYW5uZWxOYW1lIHx8IGMuY2hhbm5lbElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6IERhdGFUeXBlLkNIQU5ORUwsIC8vIOS7o+ihqOmAmumBkwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGV2aWNlU3RhdHVzOiBzZXREZXZpY2VTdGF0dXMoYykgLy8g6K6+5aSH6YCa6YGT54q25oCBCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmVudDogbm9kZSwKICAgICAgICAgICAgICAgICAgICAgICAgICB9OwogICAgICAgICAgICAgICAgICAgICAgICAgIGhhc0JlTW9uaXRvciA9IGhhc0JlTW9uaXRvciB8fCBjaGFubmVsLmRhdGEuZGV2aWNlU3RhdHVzID09PSBEZXZpY2VTdGF0dXMuQkVfTU9OSVRPUjsKICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhbm5lbC5kYXRhLmRldmljZVN0YXR1cyA9PT0gRGV2aWNlU3RhdHVzLk9GRl9MSU5FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxMaXN0W3NvcnRCeVN0YXR1cyA/IDEgOiAwXS5wdXNoKGNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2hvd09ubGluZVN0YXRlKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWRkZW5Ob2RlS2V5U2V0LmFkZChjaGFubmVsLmtleSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYW5uZWxPbmxpbmVDb3VudCsrOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTGlzdFswXS5wdXNoKGNoYW5uZWwpOwogICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFubmVsTWFwLnNldChjLmNoYW5uZWxJZCwgY2hhbm5lbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJlZU5vZGVNYXAuc2V0KGNoYW5uZWwua2V5LCBjaGFubmVsKTsKICAgICAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLmdldChjaGFubmVsTGV2ZWwpLnB1c2goY2hhbm5lbCk7CiAgICAgICAgICAgICAgICAgICAgICB9KTsKICAgICAgICAgICAgICAgICAgICAgIGNoaWxkcmVuID0gWy4uLmNoYW5uZWxMaXN0WzBdLCAuLi5jaGFubmVsTGlzdFsxXV07CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNvdW50ID0gY2hhbm5lbE9ubGluZUNvdW50OwogICAgICAgICAgICAgICAgICAgICAgbm9kZS50b3RhbCA9IHNob3dPbmxpbmVTdGF0ZSA/IG5vZGUuY291bnQgOiBjaGlsZHJlbi5sZW5ndGg7CiAgICAgICAgICAgICAgICAgICAgICBub2RlLmNoaWxkcmVuID0gY2hpbGRyZW47CiAgICAgICAgICAgICAgICAgICAgICBtYXhMZXZlbCA9IE1hdGgubWF4KGNoYW5uZWxMZXZlbCwgbWF4TGV2ZWwpOwogICAgICAgICAgICAgICAgICAgICAgLy8g6YCa6YGT54q25oCB5Li655uR5o6n5Lit77yM6K6+5aSH54q25oCB5Li65Zyo57q/77yM5bCG6K6+5aSH54q25oCB5pu05pS55Li655uR5o6n5LitCiAgICAgICAgICAgICAgICAgICAgICBpZiAoaGFzQmVNb25pdG9yICYmIG5vZGUuZGF0YS5kZXZpY2VTdGF0dXMgPT09IERldmljZVN0YXR1cy5PTl9MSU5FKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgbm9kZS5kYXRhLmRldmljZVN0YXR1cyA9IERldmljZVN0YXR1cy5CRV9NT05JVE9SOwogICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIG5vZGUuaXNMZWFmID0gIWNoaWxkcmVuIHx8IGNoaWxkcmVuLmxlbmd0aCA9PT0gMDsKICAgICAgICAgICAgICAgICAgc2libGluZ3MucHVzaChub2RlKTsKICAgICAgICAgICAgICAgICAgaWYgKG5vZGUuZGF0YS5kYXRhVHlwZSA9PT0gRGF0YVR5cGUuUExBTl9HUk9VUCkgewogICAgICAgICAgICAgICAgICAgICAgcGxhbkdyb3VwTWFwLnNldChub2RlLmRhdGEuaWQsIG5vZGUpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIHRyZWVOb2RlTWFwLnNldCh2YWx1ZSwgbm9kZSk7CiAgICAgICAgICAgICAgICAgIGlmICghbGV2ZWxUcmVlTm9kZU1hcC5oYXMobGV2ZWwpKSB7CiAgICAgICAgICAgICAgICAgICAgICBsZXZlbFRyZWVOb2RlTWFwLnNldChsZXZlbCwgW10pOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIGlmIChsZXZlbFRyZWVOb2RlTWFwLmhhcyhsZXZlbCkpIHsKICAgICAgICAgICAgICAgICAgICAgIGxldmVsVHJlZU5vZGVNYXAuZ2V0KGxldmVsKS5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIC8vIOiuvuWkhwogICAgICAgICAgICAgICAgICBpZiAocmF3Tm9kZS5kYXRhVHlwZSA9PT0gMykgewogICAgICAgICAgICAgICAgICAgICAgY29uc3QgeyBkZXZpY2VJZCB9ID0gbm9kZS5kYXRhOwogICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGV2aWNlSW5mbyA9IGRldmljZU1hcC5nZXQoZGV2aWNlSWQpIHx8IFtdOwogICAgICAgICAgICAgICAgICAgICAgZGV2aWNlSW5mby5wdXNoKG5vZGUpOwogICAgICAgICAgICAgICAgICAgICAgZGV2aWNlTWFwLnNldChkZXZpY2VJZCwgZGV2aWNlSW5mbyk7CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgaWYgKGxldmVsID4gbWF4TGV2ZWwpIHsKICAgICAgICAgICAgICAgICAgbWF4TGV2ZWwgPSBsZXZlbDsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgcmV0dXJuIHsgbGlzdDogc2libGluZ3MsIGNvdW50LCB0b3RhbCB9OwogICAgICAgICAgfTsKICAgICAgICAgIGNvbnN0IHsgbGlzdCB9ID0gdHJhdmVyc2UoZGF0YSB8fCBbXSk7CiAgICAgICAgICBjb25zdCB0cmVlTm9kZXMgPSBsaXN0OwogICAgICAgICAgcmV0dXJuIHsKICAgICAgICAgICAgICBwbGFuR3JvdXBNYXAsCiAgICAgICAgICAgICAgY2hhbm5lbE1hcCwKICAgICAgICAgICAgICB0cmVlTm9kZU1hcCwKICAgICAgICAgICAgICBkZXZpY2VNYXAsCiAgICAgICAgICAgICAgbGV2ZWxUcmVlTm9kZU1hcCwKICAgICAgICAgICAgICBtYXhMZXZlbCwKICAgICAgICAgICAgICB0cmVlTm9kZXMsCiAgICAgICAgICAgICAgaGlkZGVuTm9kZUtleVNldAogICAgICAgICAgfTsKICAgICAgfQogICAgICByZXR1cm4gY3JlYXRlRGV2aWNlVHJlZShkYXRhKTsKICB9CiAgY29uc3QgZ2VuZXJhdGVNYXAgPSB7CiAgICAgIC8vIOiuvuWkh+agkQogICAgICBbQnVzaW5lc3MuREVWSUNFXTogZ2VuZXJhdGVEZXZpY2VUcmVlLAogICAgICAvLyDpgJrpgZPorr7lpIfmoJEKICAgICAgW0J1c2luZXNzLkNIQU5ORUxdOiBnZW5lcmF0ZUNoYW5uZWxEZXZpY2VUcmVlLAogICAgICAvLyDnvqTnu4Torr7lpIfmoJEKICAgICAgW0J1c2luZXNzLkdST1VQX0RFVklDRV06IGdlbmVyYXRlR3JvdXBEZXZpY2VUcmVlLAogICAgICAvLyDnvqTnu4TmoJEKICAgICAgW0J1c2luZXNzLkdST1VQXTogZ2VuZXJhdGVHcm91cFRyZWUsCiAgICAgIC8vIOeUqOaIt+agkQogICAgICBbQnVzaW5lc3MuVVNFUl06IGdlbmVyYXRlVXNlclRyZWUsCiAgICAgIC8vIOmYn+S8jeeUqOaIt+agkQogICAgICBbQnVzaW5lc3MuVEVBTV9VU0VSXTogZ2VuZXJhdGVUZWFtVXNlclRyZWUsCiAgICAgIC8vIOmHh+mbhuermQogICAgICBbQnVzaW5lc3MuQ1NdOiBnZW5lcmF0ZUNzVHJlZSwKICAgICAgLy8g6aKE5qGI5YiG57uE6K6+5aSH5qCRCiAgICAgIFtCdXNpbmVzcy5QTEFOX0dST1VQX0RFVklDRV06IGdlbmVyYXRlUGxhbkdyb3VwRGV2aWNlVHJlZSwKICB9OwoKICBzZWxmLm9ubWVzc2FnZSA9IGFzeW5jIChldmVudCkgPT4gewogICAgICBjb25zdCB7IGRhdGEsIGNvbmZpZyB9ID0gZXZlbnQuZGF0YTsKICAgICAgY29uc3QgZ2VuZXJhdGVUcmVlID0gZ2VuZXJhdGVNYXBbY29uZmlnLmJ1c2luZXNzXTsKICAgICAgaWYgKCFnZW5lcmF0ZVRyZWUpIHsKICAgICAgICAgIHNlbGYuY2xvc2UoKTsKICAgICAgICAgIHJldHVybjsKICAgICAgfQogICAgICBjb25zdCB0cmVlID0gZ2VuZXJhdGVUcmVlKGRhdGEsIGNvbmZpZyk7CiAgICAgIHNlbGYucG9zdE1lc3NhZ2UodHJlZSk7CiAgfTsKCn0pKCk7Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPWdlbmVyYXRlVHJlZS5qcy5tYXAKCg==');
|
|
9110
9111
|
/* eslint-enable */
|
|
9111
9112
|
|
|
9112
9113
|
// 设备树
|
|
@@ -10251,7 +10252,7 @@ class VirtualTree {
|
|
|
10251
10252
|
return list;
|
|
10252
10253
|
};
|
|
10253
10254
|
return (params) => {
|
|
10254
|
-
const { id, isBusiness = false } = params;
|
|
10255
|
+
const { id, dataType, isBusiness = false } = params;
|
|
10255
10256
|
if (!id) {
|
|
10256
10257
|
throw Error('getDeviceIntegrated:id不能为空');
|
|
10257
10258
|
}
|
|
@@ -10261,7 +10262,6 @@ class VirtualTree {
|
|
|
10261
10262
|
case Business.DEVICE:
|
|
10262
10263
|
case Business.CHANNEL:
|
|
10263
10264
|
case Business.GROUP_DEVICE:
|
|
10264
|
-
case Business.PLAN_GROUP_DEVICE:
|
|
10265
10265
|
node = (this._tree.deviceMap && this._tree.deviceMap.get(id)) || [];
|
|
10266
10266
|
break;
|
|
10267
10267
|
case Business.USER:
|
|
@@ -10273,6 +10273,10 @@ class VirtualTree {
|
|
|
10273
10273
|
}
|
|
10274
10274
|
node = node?.[0];
|
|
10275
10275
|
}
|
|
10276
|
+
if (!node && dataType === DataType.PLAN_GROUP) {
|
|
10277
|
+
node = this._tree.planGroupMap?.get(params.id);
|
|
10278
|
+
console.log('node', node);
|
|
10279
|
+
}
|
|
10276
10280
|
node = node || this._tree.treeNodeMap.get(params.id);
|
|
10277
10281
|
if (!node) {
|
|
10278
10282
|
throw Error('getDeviceIntegrated:找不到节点');
|