You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@allura.apache.org by he...@apache.org on 2015/12/07 17:14:50 UTC

[6/6] allura git commit: Include Ticket Description in the api search results

Include Ticket Description in the api search results


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/a87dc108
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/a87dc108
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/a87dc108

Branch: refs/heads/hs/tracker/api
Commit: a87dc10827517b0c8230ddf105ee5060b62c4096
Parents: 36303a1
Author: Heith Seewald <he...@gmail.com>
Authored: Mon Dec 7 11:08:09 2015 -0500
Committer: Heith Seewald <he...@gmail.com>
Committed: Mon Dec 7 11:12:33 2015 -0500

----------------------------------------------------------------------
 .eslintrc                                       |   177 +
 .../docs/api-rest/examples/searchedTickets.json |     3 +-
 .../docs/api-rest/schemas/searchedTickets.json  |     5 +-
 ForgeTracker/forgetracker/tracker_main.py       |     2 +-
 .../context-menu.es6.js                         |    79 +
 tmp/babel-cache_path-KE9lkE0D.tmp/navbar.es6.js |   637 +
 .../tooltip.es6.js                              |    93 +
 tmp/babel-input_base_path-9J5sAGDS.tmp/0        |     1 +
 .../context-menu.es6.js                         |     1 +
 .../navbar.es6.js                               |     1 +
 .../tooltip.es6.js                              |     1 +
 .../0                                           |     1 +
 .../1                                           |     1 +
 .../0                                           |     1 +
 .../1                                           |     1 +
 .../context-menu.es6.js                         |     1 +
 .../lib                                         |     1 +
 .../navbar.es6.js                               |     1 +
 .../public                                      |     1 +
 .../tooltip.es6.js                              |     1 +
 .../navbar.js                                   |     1 +
 .../navbar.map                                  |     1 +
 .../transpiled.js                               |     1 +
 .../transpiled.map                              |     1 +
 .../0                                           |     1 +
 .../0                                           |     1 +
 .../transpiled.js                               |   809 +
 .../transpiled.map                              |     1 +
 .../navbar.js                                   | 21906 +++++++++++++++++
 .../navbar.map                                  |     1 +
 tmp/funnel-input_base_path-OAZnLPUf.tmp/0       |     1 +
 tmp/funnel-input_base_path-UolpY1sh.tmp/0       |     1 +
 .../widgets/resources/js/jquery.lightbox_me.js  |     1 +
 .../public/nf/js/admin_modal.js                 |     1 +
 .../public/nf/js/react-dom.js                   |     1 +
 .../public/nf/js/react-drag.min.js              |     1 +
 .../public/nf/js/react-reorderable.min.js       |     1 +
 .../public/nf/js/react-with-addons.js           |     1 +
 .../public/nf/js/underscore-min.js              |     1 +
 .../context-menu.es6.js                         |     1 +
 .../navbar.es6.js                               |     1 +
 .../tooltip.es6.js                              |     1 +
 42 files changed, 23741 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/a87dc108/.eslintrc
----------------------------------------------------------------------
diff --git a/.eslintrc b/.eslintrc
new file mode 100644
index 0000000..7c92495
--- /dev/null
+++ b/.eslintrc
@@ -0,0 +1,177 @@
+{
+  "plugins": [
+    "react"
+  ],
+  "parser": "babel-eslint",
+  "ecmaFeatures": {
+    "arrowFunctions": true,
+    "blockBindings": true,
+    "classes": true,
+    "defaultParams": true,
+    "destructuring": true,
+    "forOf": true,
+    "objectLiteralComputedProperties": true,
+    "objectLiteralShorthandMethods": true,
+    "objectLiteralShorthandProperties": true,
+    "restParams": true,
+    "spread": true,
+    "superInFunctions": true,
+    "templateStrings": true,
+    "jsx": true
+  },
+  "env": {
+    "browser": true,
+    "node": true,
+    "jasmine": true,
+    "jquery": true
+  },
+  "globals": {
+    "If": true,
+    "Else": true
+  },
+  "rules": {
+    "strict": [
+      2,
+      "global"
+    ],
+    "block-scoped-var": 2,
+    "curly": 2,
+    "dot-notation": [
+      2,
+      {
+        "allowKeywords": false,
+        "allowPattern": "^[a-z]+(_[a-z]+)+$"
+      }
+    ],
+    "guard-for-in": 2,
+    "no-else-return": 2,
+    "wrap-iife": [
+      2,
+      "inside"
+    ],
+    "no-throw-literal": 2,
+    "indent": [
+      2,
+      4,
+      {
+        "SwitchCase": 1
+      }
+    ],
+    "brace-style": [
+      2,
+      "1tbs",
+      {
+        "allowSingleLine": true
+      }
+    ],
+    "camelcase": 2,
+    "eol-last": 2,
+    "new-cap": [
+      2,
+      {
+        "newIsCap": true,
+        "capIsNew": false
+      }
+    ],
+    "no-mixed-spaces-and-tabs": 2,
+    "no-multiple-empty-lines": [
+      1,
+      {
+        "max": 2
+      }
+    ],
+    "semi-spacing": [
+      2,
+      {
+        "before": false,
+        "after": true
+      }
+    ],
+    "no-spaced-func": 2,
+    "no-trailing-spaces": 2,
+    "no-underscore-dangle": 0,
+    "no-extra-parens": [
+      2,
+      "functions"
+    ],
+    "no-var": 2,
+    "object-shorthand": [
+      2,
+      "always"
+    ],
+    "operator-assignment": [
+      2,
+      "always"
+    ],
+    "prefer-const": 0,
+    "semi": [
+      2,
+      "always"
+    ],
+    "space-before-function-paren": [
+      2,
+      {
+        "anonymous": "always",
+        "named": "never"
+      }
+    ],
+    "space-in-parens": [
+      2,
+      "never"
+    ],
+    "space-infix-ops": 2,
+    "space-return-throw-case": 2,
+    "space-unary-ops": [
+      2,
+      {
+        "words": true,
+        "nonwords": false
+      }
+    ],
+    "react/display-name": 1,
+    "react/jsx-boolean-value": [
+      2,
+      "always"
+    ],
+    "react/jsx-curly-spacing": [
+      2,
+      "never"
+    ],
+    "react/jsx-max-props-per-line": 0,
+    "react/jsx-no-duplicate-props": [
+      2,
+      {
+        "ignoreCase": true
+      }
+    ],
+    "react/jsx-no-literals": 0,
+    "react/jsx-no-undef": 2,
+    "react/jsx-quotes": [
+      2,
+      "double"
+    ],
+    "react/jsx-sort-prop-types": [
+      2,
+      {
+        "ignoreCase": true
+      }
+    ],
+    "react/jsx-sort-prop": 0,
+    "react/jsx-uses-react": 1,
+    "react/jsx-uses-vars": 1,
+    "react/no-danger": 2,
+    "react/no-did-mount-set-state": [
+      1,
+      "allowed-in-func"
+    ],
+    "react/no-did-update-set-state": 1,
+    "react/no-multi-comp": 1,
+    "react/no-unknown-property": 1,
+    "react/prop-types": 0,
+    "react/react-in-jsx-scope": 1,
+    "react/require-extension": 0,
+    "react/self-closing-comp": 1,
+    "react/sort-comp": 1,
+    "react/wrap-multilines": 1
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/a87dc108/Allura/docs/api-rest/examples/searchedTickets.json
----------------------------------------------------------------------
diff --git a/Allura/docs/api-rest/examples/searchedTickets.json b/Allura/docs/api-rest/examples/searchedTickets.json
index a5502c5..41cef1a 100755
--- a/Allura/docs/api-rest/examples/searchedTickets.json
+++ b/Allura/docs/api-rest/examples/searchedTickets.json
@@ -107,7 +107,8 @@
       "discussion_disabled": false,
       "assigned_to_id": "511aa8756d19cd161e8c1b04",
       "private": false,
-      "summary": "Site admin search tables can overflow the page width",
+      "summary": "If you do a search for users and the results are really wide...",
+      "description": "Details about ",
       "mod_date": "2015-07-14 08:40:35.931000",
       "votes_down": 0,
       "votes_up": 0,

http://git-wip-us.apache.org/repos/asf/allura/blob/a87dc108/Allura/docs/api-rest/schemas/searchedTickets.json
----------------------------------------------------------------------
diff --git a/Allura/docs/api-rest/schemas/searchedTickets.json b/Allura/docs/api-rest/schemas/searchedTickets.json
index cf66f55..f07595f 100755
--- a/Allura/docs/api-rest/schemas/searchedTickets.json
+++ b/Allura/docs/api-rest/schemas/searchedTickets.json
@@ -152,7 +152,10 @@
                     }, 
                     "summary": {
                         "type": "string"
-                    }, 
+                    },
+                    "description": {
+                        "type": "string"
+                    },
                     "assigned_to_id": {
                         "type": ["string", "null"]
                     }, 

http://git-wip-us.apache.org/repos/asf/allura/blob/a87dc108/ForgeTracker/forgetracker/tracker_main.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 45d24b4..b66370e 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -1826,7 +1826,7 @@ class RootRestController(BaseController, AppRestControllerMixin):
         def _convert_ticket(t):
             t = t.__json__()
             # just pop out all the heavy stuff
-            for field in ['description', 'discussion_thread']:
+            for field in ['discussion_thread']:
                 t.pop(field, None)
             return t
 

http://git-wip-us.apache.org/repos/asf/allura/blob/a87dc108/tmp/babel-cache_path-KE9lkE0D.tmp/context-menu.es6.js
----------------------------------------------------------------------
diff --git a/tmp/babel-cache_path-KE9lkE0D.tmp/context-menu.es6.js b/tmp/babel-cache_path-KE9lkE0D.tmp/context-menu.es6.js
new file mode 100644
index 0000000..6619840
--- /dev/null
+++ b/tmp/babel-cache_path-KE9lkE0D.tmp/context-menu.es6.js
@@ -0,0 +1,79 @@
+
+'use strict';
+
+var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var ContextMenu = (function (_React$Component) {
+    _inherits(ContextMenu, _React$Component);
+
+    function ContextMenu(props) {
+        _classCallCheck(this, ContextMenu);
+
+        _React$Component.call(this, props);
+    }
+
+    ContextMenu.prototype.componentWillMount = function componentWillMount() {
+        var _this = this;
+        var mount_point;
+        $('body').on('click.contextMenu', function (evt) {
+            if ($(evt.target).is(':not(.contextMenu)')) {
+                if ($(evt.target).is('.config-tool')) {
+                    mount_point = $(evt.target).next().data('mount-point');
+                } else {
+                    mount_point = "";
+                }
+                _this.props.onOptionClick(mount_point);
+            }
+        });
+    };
+
+    ContextMenu.prototype.componentWillUnmount = function componentWillUnmount() {
+        $("body").off('click.contextMenu');
+    };
+
+    ContextMenu.prototype.render = function render() {
+        var _this = this;
+        return React.createElement(
+            'div',
+            { className: 'contextMenu' },
+            React.createElement(
+                'ul',
+                null,
+                this.props.items.map(function (o, i) {
+                    return React.createElement(
+                        'li',
+                        { key: i },
+                        React.createElement(ToolTipLink, {
+                            href: o.href,
+                            classes: _this.props.classes.concat([o.className]),
+                            toolTip: o.tooltip,
+                            text: o.text })
+                    );
+                })
+            )
+        );
+    };
+
+    _createClass(ContextMenu, null, [{
+        key: 'propTypes',
+        value: {
+            classes: React.PropTypes.array.isRequired,
+            items: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
+            onOptionClick: React.PropTypes.func.isRequired
+        },
+        enumerable: true
+    }, {
+        key: 'defaultOptions',
+        value: {
+            classes: []
+        },
+        enumerable: true
+    }]);
+
+    return ContextMenu;
+})(React.Component);
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNvbnRleHQtbWVudS5lczYuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQWtCQSxZQUFZLENBQUM7Ozs7Ozs7O0lBR1AsV0FBVztjQUFYLFdBQVc7O0FBQ0YsYUFEVCxXQUFXLENBQ0QsS0FBSyxFQUFFOzhCQURqQixXQUFXOztBQUVULG9DQUFNLEtBQUssQ0FBQyxDQUFDO0tBQ2hCOztBQUhDLGVBQVcsV0FlYixrQkFBa0IsR0FBQSw4QkFBRztBQUNqQixZQUFJLEtBQUssR0FBRyxJQUFJLENBQUM7QUFDakIsWUFBSSxXQUFXLENBQUM7QUFDaEIsU0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsRUFBRSxVQUFVLEdBQUcsRUFBRTtBQUc3QyxnQkFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFO0FBS3hDLG9CQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxFQUFFO0FBQ2xDLCtCQUFXLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7aUJBQzFELE1BQU07QUFFSCwrQkFBVyxHQUFHLEVBQUUsQ0FBQztpQkFDcEI7QUFDRCxxQkFBSyxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUM7YUFDMUM7U0FDSixDQUFDLENBQUM7S0FDTjs7QUFuQ0M
 sZUFBVyxXQXFDYixvQkFBb0IsR0FBQSxnQ0FBRztBQUNuQixTQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLENBQUM7S0FDdEM7O0FBdkNDLGVBQVcsV0F5Q2IsTUFBTSxHQUFBLGtCQUFHO0FBQ0wsWUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2pCLGVBQ0k7O2NBQUssU0FBUyxFQUFDLGFBQWE7WUFDeEI7OztnQkFDSSxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxFQUFFO0FBQ2pDLDJCQUFROzswQkFBSSxHQUFHLEVBQUUsQ0FBQyxBQUFDO3dCQUNmLG9CQUFDLFdBQVc7QUFDUixnQ0FBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEFBQUM7QUFDYixtQ0FBTyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxBQUFDO0FBQ25ELG1DQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQUFBQztBQUNuQixnQ0FBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLEFBQUMsR0FBRTtxQkFDbEIsQ0FBQztpQkFDVCxDQUFDO2FBQ0Q7U0FDSCxDQUNUO0tBQ0o7O2lCQTFEQyxXQUFXOztlQUtNO0FBQ2YsbUJBQU8sRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxVQUFVO0FBQ3pDLGlCQUFLLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxVQUFVO0FBQ2pFLHlCQUFhLEVBQUUs
 S0FBSyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVTtTQUNqRDs7OztlQUV1QjtBQUNwQixtQkFBTyxFQUFFLEVBQUU7U0FDZDs7OztXQWJDLFdBQVc7R0FBUyxLQUFLLENBQUMsU0FBUyIsImZpbGUiOiJjb250ZXh0LW1lbnUuZXM2LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXG4gb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXG4gZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZSBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXG4gdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxuIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuXG4gVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLFxuIHNvZnR3YXJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uI
 GFuXG4gXCJBUyBJU1wiIEJBU0lTLCBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTllcbiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGVcbiBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kIGxpbWl0YXRpb25zXG4gdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbid1c2Ugc3RyaWN0JztcblxuXG5jbGFzcyBDb250ZXh0TWVudSBleHRlbmRzIFJlYWN0LkNvbXBvbmVudCB7XG4gICAgY29uc3RydWN0b3IocHJvcHMpIHtcbiAgICAgICAgc3VwZXIocHJvcHMpO1xuICAgIH1cblxuICAgIHN0YXRpYyBwcm9wVHlwZXMgPSB7XG4gICAgICAgIGNsYXNzZXM6IFJlYWN0LlByb3BUeXBlcy5hcnJheS5pc1JlcXVpcmVkLFxuICAgICAgICBpdGVtczogUmVhY3QuUHJvcFR5cGVzLmFycmF5T2YoUmVhY3QuUHJvcFR5cGVzLm9iamVjdCkuaXNSZXF1aXJlZCxcbiAgICAgICAgb25PcHRpb25DbGljazogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZFxuICAgIH07XG5cbiAgICBzdGF0aWMgZGVmYXVsdE9wdGlvbnMgPSB7XG4gICAgICAgIGNsYXNzZXM6IFtdXG4gICAgfTtcblxuICAgIGNvbXBvbmVudFdpbGxNb3VudCgpIHtcbiAgICAgICAgbGV0IF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIG1vdW50X3BvaW50O1xuICAgICAgICAkKCdib2R5Jykub24oJ2NsaWNrLmNvbnRleHRNZW51JywgZnVuY3Rpb24gKGV2dC
 kge1xuICAgICAgICAgICAgLyogdGhlIDpub3QgZmlsdGVyIHNob3VsZCd2ZSB3b3JrZWQgYXMgYSAybmQgcGFyYW0gdG8gLm9uKCkgaW5zdGVhZCBvZiB0aGlzLFxuICAgICAgICAgICAgIGJ1dCBjbGlja3MgaW4gdGhlIHBhZ2UgZ3V0dGVyIHdlcmUgYmVpbmcgZGVsYXllZCBmb3Igc29tZSByZWFzb24gKi9cbiAgICAgICAgICAgIGlmICgkKGV2dC50YXJnZXQpLmlzKCc6bm90KC5jb250ZXh0TWVudSknKSkge1xuXG4gICAgICAgICAgICAgICAgLyogaWYgY2xpY2tpbmcgZGlyZWN0bHkgb250byBhbm90aGVyIGdlYXIsIHNldCBpdCBkaXJlY3RseS5cbiAgICAgICAgICAgICAgICAgdGhpcyBpcyBuZWNlc3Nhcnkgc2luY2Ugc29tZXRpbWVzIG91ciBqcXVlcnkgZXZlbnRzIHNlZW0gdG8gaW50ZXJmZXJlIHdpdGggdGhlIHJlYWN0IGV2ZW50XG4gICAgICAgICAgICAgICAgIHRoYXQgaXMgc3VwcG9zZWQgdG8gaGFuZGxlIHRoaXMga2luZCBvZiB0aGluZyAqL1xuICAgICAgICAgICAgICAgIGlmICgkKGV2dC50YXJnZXQpLmlzKCcuY29uZmlnLXRvb2wnKSkge1xuICAgICAgICAgICAgICAgICAgICBtb3VudF9wb2ludCA9ICQoZXZ0LnRhcmdldCkubmV4dCgpLmRhdGEoJ21vdW50LXBvaW50Jyk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gbm8gY3VycmVudCBvcHRpb24gbWVudVxuICAgICAgICAgICAgICAgICAgICBtb3VudF9wb2ludCA9IFwiXCI7XG4gICAgICAgICA
 gICAgICAgfVxuICAgICAgICAgICAgICAgIF90aGlzLnByb3BzLm9uT3B0aW9uQ2xpY2sobW91bnRfcG9pbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICAgICAgJChcImJvZHlcIikub2ZmKCdjbGljay5jb250ZXh0TWVudScpOyAgLy8gZGUtcmVnaXN0ZXIgb3VyIHNwZWNpZmljIGNsaWNrIGhhbmRsZXJcbiAgICB9XG5cbiAgICByZW5kZXIoKSB7XG4gICAgICAgIGxldCBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImNvbnRleHRNZW51XCI+XG4gICAgICAgICAgICAgICAgPHVsPntcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcm9wcy5pdGVtcy5tYXAoZnVuY3Rpb24gKG8sIGkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAoPGxpIGtleT17aX0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPFRvb2xUaXBMaW5rXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhyZWY9e28uaHJlZn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3Nlcz17X3RoaXMucHJvcHMuY2xhc3Nlcy5jb25jYXQoW28uY2xhc3NOYW1lXSl9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xUaXA9e28udG9vbHRpcH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dD17by50ZXh0fS8+XG4gICAg
 ICAgICAgICAgICAgICAgICAgICA8L2xpPilcbiAgICAgICAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApXG4gICAgfVxufVxuIl19
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/allura/blob/a87dc108/tmp/babel-cache_path-KE9lkE0D.tmp/navbar.es6.js
----------------------------------------------------------------------
diff --git a/tmp/babel-cache_path-KE9lkE0D.tmp/navbar.es6.js b/tmp/babel-cache_path-KE9lkE0D.tmp/navbar.es6.js
new file mode 100644
index 0000000..7d4e1e1
--- /dev/null
+++ b/tmp/babel-cache_path-KE9lkE0D.tmp/navbar.es6.js
@@ -0,0 +1,637 @@
+
+'use strict';
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+function _getProjectUrl() {
+    var rest = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
+
+    var nbhd, proj, nbhd_proj;
+    var ident_classes = document.getElementById('page-body').className.split(' ');
+    var _iteratorNormalCompletion = true;
+    var _didIteratorError = false;
+    var _iteratorError = undefined;
+
+    try {
+        for (var _iterator = ident_classes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
+            var cls = _step.value;
+
+            if (cls.indexOf('project-') === 0) {
+                proj = cls.slice('project-'.length);
+            }
+        }
+    } catch (err) {
+        _didIteratorError = true;
+        _iteratorError = err;
+    } finally {
+        try {
+            if (!_iteratorNormalCompletion && _iterator['return']) {
+                _iterator['return']();
+            }
+        } finally {
+            if (_didIteratorError) {
+                throw _iteratorError;
+            }
+        }
+    }
+
+    nbhd = window.location.pathname.split('/')[1];
+    if (proj === '--init--') {
+        nbhd_proj = nbhd;
+    } else {
+        nbhd_proj = nbhd + '/' + proj;
+    }
+    return (rest ? '/rest/' : '/') + nbhd_proj;
+}
+
+function getMountPoint(node) {
+    if (node.hasOwnProperty('mount_point') && node['mount_point'] !== null) {
+        return node['mount_point'];
+    }
+    return node.props.children[0].props.mount_point;
+}
+
+function getUrlByNode(node) {
+    if (node.hasOwnProperty('url') && node['url'] !== null) {
+        return node['url'];
+    }
+    return node.props.children[0].props.url;
+}
+
+var ToolsPropType = React.PropTypes.shape({
+    mount_point: React.PropTypes.string,
+    name: React.PropTypes.string.isRequired,
+    url: React.PropTypes.string.isRequired,
+    is_anchored: React.PropTypes.bool.isRequired,
+    tool_name: React.PropTypes.string.isRequired,
+    icon: React.PropTypes.string,
+    children: React.PropTypes.array,
+    admin_options: React.PropTypes.array
+});
+
+var NavBarItem = React.createClass({
+    displayName: 'NavBarItem',
+
+    propTypes: {
+        name: React.PropTypes.string.isRequired,
+        url: React.PropTypes.string.isRequired,
+        currentOptionMenu: React.PropTypes.object,
+        onOptionClick: React.PropTypes.func.isRequired,
+        options: React.PropTypes.array
+    },
+
+    isAnchored: function isAnchored() {
+        return this.props.is_anchored !== null;
+    },
+
+    render: function render() {
+        var divClasses = "tb-item tb-item-edit";
+        if (this.props.is_anchored) {
+            divClasses += " anchored";
+        }
+        var spanClasses = this.props.handleType + " ordinal-item";
+        if (this.props.isGrouper) {
+            spanClasses += " toolbar-grouper";
+        }
+
+        return React.createElement(
+            'div',
+            { className: divClasses },
+            React.createElement(
+                'a',
+                null,
+                !_.isEmpty(this.props.options) && React.createElement('i', { className: 'config-tool fa fa-cog', onClick: this.handleOptionClick }),
+                React.createElement(
+                    'span',
+                    {
+                        className: spanClasses,
+                        'data-mount-point': this.props.mount_point },
+                    this.props.name
+                )
+            ),
+            this.props.currentOptionMenu.tool && this.props.currentOptionMenu.tool === this.props.mount_point && React.createElement(ContextMenu, _extends({}, this.props, {
+                classes: ['tool-options'],
+                items: this.props.options,
+                onOptionClick: this.props.onOptionClick
+            }))
+        );
+    },
+
+    handleOptionClick: function handleOptionClick(event) {
+        this.props.onOptionClick(this.props.mount_point);
+    }
+});
+
+var GroupingThreshold = React.createClass({
+    displayName: 'GroupingThreshold',
+
+    propTypes: {
+        initialValue: React.PropTypes.number.isRequired
+    },
+    getInitialState: function getInitialState() {
+        return {
+            value: this.props.initialValue
+        };
+    },
+
+    handleChange: function handleChange(event) {
+        this.setState({
+            value: event.target.value
+        });
+        this.props.onUpdateThreshold(event);
+    },
+
+    render: function render() {
+        return React.createElement(
+            'div',
+            null,
+            !!this.props.isHidden && React.createElement(
+                'div',
+                { id: 'threshold-config' },
+                React.createElement(
+                    'span',
+                    null,
+                    React.createElement(
+                        'label',
+                        { htmlFor: 'threshold-input' },
+                        'Grouping Threshold'
+                    ),
+                    React.createElement('input', { type: 'number', name: 'threshold-input', className: 'tooltip',
+                        title: 'Number of tools allowed before grouping.',
+                        value: this.state.value,
+                        onChange: this.handleChange,
+                        min: '1', max: '10' })
+                )
+            )
+        );
+    }
+});
+
+var NormalNavItem = React.createClass({
+    displayName: 'NormalNavItem',
+
+    mixins: [React.addons.PureRenderMixin],
+
+    render: function render() {
+
+        return React.createElement(
+            'li',
+            { key: 'tb-norm-' + _.uniqueId() },
+            React.createElement(
+                'a',
+                { href: this.props.url, className: this.props.classes },
+                this.props.name
+            ),
+            this.props.children
+        );
+    }
+});
+
+var ToggleAddNewTool = React.createClass({
+    displayName: 'ToggleAddNewTool',
+
+    getInitialState: function getInitialState() {
+        return {
+            visible: false
+        };
+    },
+    handleToggle: function handleToggle() {
+        this.setState({
+            visible: !this.state.visible
+        });
+    },
+    handleOptionClick: function handleOptionClick(event) {
+        console.log('event', event);
+    },
+
+    render: function render() {
+        return React.createElement(
+            'div',
+            null,
+            React.createElement(
+                'a',
+                { onClick: this.handleToggle, className: 'add-tool-toggle' },
+                'Add New...'
+            ),
+            this.state.visible && React.createElement(ContextMenu, _extends({}, this.props, {
+                classes: ['admin_modal'],
+                onOptionClick: this.handleOptionClick,
+                items: this.props.installableTools }))
+        );
+    }
+});
+
+var NormalNavBar = React.createClass({
+    displayName: 'NormalNavBar',
+
+    buildMenu: function buildMenu(item, i) {
+        var classes = window.location.pathname.startsWith(item.url) ? 'active-nav-link' : '';
+
+        var subMenu;
+        if (item.children) {
+            subMenu = item.children.map(this.buildMenu);
+        }
+        return React.createElement(
+            NormalNavItem,
+            { url: item.url, name: item.name, classes: classes, key: 'normal-nav-' + _.uniqueId() },
+            React.createElement(
+                'ul',
+                null,
+                subMenu
+            )
+        );
+    },
+
+    onOptionClick: function onOptionClick(e) {
+        console.log(e);
+    },
+    render: function render() {
+        var listItems = this.props.items.map(this.buildMenu);
+
+        var mount_points = [];
+        var _iteratorNormalCompletion2 = true;
+        var _didIteratorError2 = false;
+        var _iteratorError2 = undefined;
+
+        try {
+            for (var _iterator2 = this.props.items[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
+                var item = _step2.value;
+
+                if (item.hasOwnProperty('mount_point') && item.mount_point !== null) {
+                    mount_points.push(item.mount_point);
+                } else if (item.hasOwnProperty('children')) {
+                    var _iteratorNormalCompletion3 = true;
+                    var _didIteratorError3 = false;
+                    var _iteratorError3 = undefined;
+
+                    try {
+                        for (var _iterator3 = item.children[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {
+                            var child = _step3.value;
+
+                            mount_points.push(child.mount_point);
+                        }
+                    } catch (err) {
+                        _didIteratorError3 = true;
+                        _iteratorError3 = err;
+                    } finally {
+                        try {
+                            if (!_iteratorNormalCompletion3 && _iterator3['return']) {
+                                _iterator3['return']();
+                            }
+                        } finally {
+                            if (_didIteratorError3) {
+                                throw _iteratorError3;
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (err) {
+            _didIteratorError2 = true;
+            _iteratorError2 = err;
+        } finally {
+            try {
+                if (!_iteratorNormalCompletion2 && _iterator2['return']) {
+                    _iterator2['return']();
+                }
+            } finally {
+                if (_didIteratorError2) {
+                    throw _iteratorError2;
+                }
+            }
+        }
+
+        console.log("mount_points", mount_points);
+        return React.createElement(
+            'ul',
+            {
+                id: 'normal-nav-bar',
+                className: 'dropdown' },
+            listItems,
+            React.createElement(
+                'li',
+                { id: 'add-tool-container' },
+                React.createElement(ToggleAddNewTool, _extends({}, this.props, {
+                    items: this.props.installableTools,
+                    onOptionClick: this.onOptionClick }))
+            )
+        );
+    }
+});
+
+var AdminNav = React.createClass({
+    displayName: 'AdminNav',
+
+    propTypes: {
+        tools: React.PropTypes.arrayOf(ToolsPropType),
+        currentOptionMenu: React.PropTypes.object,
+        onOptionClick: React.PropTypes.func.isRequired
+    },
+
+    buildMenu: function buildMenu(items) {
+        var isSubMenu = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1];
+
+        var _this = this;
+        var tools = [];
+        var anchored_tools = [];
+        var end_tools = [];
+
+        var subMenu, childOptionsOpen;
+
+        var _iteratorNormalCompletion4 = true;
+        var _didIteratorError4 = false;
+        var _iteratorError4 = undefined;
+
+        try {
+            for (var _iterator4 = items[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {
+                var item = _step4.value;
+
+                if (item.children) {
+                    subMenu = this.buildMenu(item.children, true);
+                } else {
+                    subMenu = null;
+                }
+
+                var _handle = isSubMenu ? "draggable-handle-sub" : 'draggable-handle';
+
+                var tool_list, is_anchored;
+                if (item.mount_point === 'admin') {
+                    tool_list = end_tools;
+                    is_anchored = true;
+                } else if (item.is_anchored) {
+                    tool_list = anchored_tools;
+                    is_anchored = true;
+                } else {
+                    tool_list = tools;
+                    is_anchored = false;
+                }
+                var core_item = React.createElement(NavBarItem, _extends({}, _this.props, {
+                    mount_point: item.mount_point,
+                    name: item.name,
+                    handleType: _handle,
+                    isGrouper: item.children && item.children.length > 0,
+                    url: item.url,
+                    key: 'tb-item-' + _.uniqueId(),
+                    is_anchored: is_anchored,
+                    options: item.admin_options
+                }));
+                if (subMenu) {
+                    childOptionsOpen = _.contains(_.pluck(item.children, 'mount_point'), this.props.currentOptionMenu.tool);
+                    tool_list.push(React.createElement(NavBarItemWithSubMenu, { key: _.uniqueId(), tool: core_item, subMenu: subMenu, childOptionsOpen: childOptionsOpen }));
+                } else {
+                    tool_list.push(core_item);
+                }
+            }
+        } catch (err) {
+            _didIteratorError4 = true;
+            _iteratorError4 = err;
+        } finally {
+            try {
+                if (!_iteratorNormalCompletion4 && _iterator4['return']) {
+                    _iterator4['return']();
+                }
+            } finally {
+                if (_didIteratorError4) {
+                    throw _iteratorError4;
+                }
+            }
+        }
+
+        return React.createElement(
+            'div',
+            { className: 'react-drag' },
+            anchored_tools,
+            React.createElement(
+                ReactReorderable,
+                {
+                    key: 'reorder-' + _.uniqueId(),
+                    handle: "." + _handle,
+                    mode: isSubMenu ? 'list' : 'grid',
+                    onDragStart: _this.props.onToolDragStart,
+                    onDrop: _this.props.onToolReorder },
+                tools
+            ),
+            end_tools
+        );
+    },
+
+    render: function render() {
+        var tools = this.buildMenu(this.props.tools);
+        return React.createElement(
+            'div',
+            null,
+            tools
+        );
+    }
+});
+
+var NavBarItemWithSubMenu = React.createClass({
+    displayName: 'NavBarItemWithSubMenu',
+
+    render: function render() {
+        return React.createElement(
+            'div',
+            { className: "tb-item-container" + (this.props.childOptionsOpen ? " child-options-open" : "") },
+            this.props.tool,
+            this.props.subMenu && React.createElement(
+                AdminItemGroup,
+                { key: _.uniqueId() },
+                this.props.subMenu
+            )
+        );
+    }
+});
+
+var AdminItemGroup = React.createClass({
+    displayName: 'AdminItemGroup',
+
+    render: function render() {
+        return React.createElement(
+            'div',
+            { className: 'tb-item-grouper' },
+            this.props.children
+        );
+    }
+});
+
+var ToggleAdminButton = React.createClass({
+    displayName: 'ToggleAdminButton',
+
+    propTypes: {
+        visible: React.PropTypes.bool
+    },
+    render: function render() {
+        var classes = this.props.visible ? 'fa fa-unlock' : 'fa fa-lock';
+        return React.createElement(
+            'button',
+            { id: 'toggle-admin-btn', onClick: this.props.handleButtonPush, className: 'admin-toolbar-right' },
+            React.createElement('i', { className: classes })
+        );
+    }
+});
+
+var Main = React.createClass({
+    displayName: 'Main',
+
+    propTypes: {
+        initialData: React.PropTypes.shape({
+            menu: React.PropTypes.arrayOf(ToolsPropType),
+            installableTools: React.PropTypes.array,
+            grouping_threshold: React.PropTypes.number.isRequired
+        }),
+        installableTools: React.PropTypes.array
+    },
+    getInitialState: function getInitialState() {
+        return {
+            data: this.props.initialData,
+            visible: true,
+            _session_id: $.cookie('_session_id'),
+            currentOptionMenu: {
+                tool: null
+            }
+        };
+    },
+
+    getNavJson: function getNavJson() {
+        $.get(_getProjectUrl(false) + '/_nav.json?admin_options=1', (function (result) {
+            if (this.isMounted()) {
+                this.setState({
+                    data: result
+                });
+            }
+        }).bind(this));
+    },
+
+    handleToggleAdmin: function handleToggleAdmin() {
+        this.setState({
+            visible: !this.state.visible
+        });
+    },
+
+    handleShowOptionMenu: function handleShowOptionMenu(mount_point) {
+        this.setState({
+            currentOptionMenu: {
+                tool: mount_point
+            }
+        });
+    },
+
+    onUpdateThreshold: function onUpdateThreshold(event) {
+        var _this = this;
+        var thres = event.target.value;
+        var url = _getProjectUrl() + '/admin/configure_tool_grouping';
+        var csrf = $.cookie('_session_id');
+        var data = {
+            _session_id: csrf,
+            grouping_threshold: thres
+        };
+        var _data = this.state.data;
+        _data.grouping_threshold = thres;
+        this.setState({
+            data: _data
+        });
+        this.setState({
+            in_progress: true
+        });
+        $.post(url, data, (function () {}).bind(this)).always(function () {
+            _this.setState({
+                in_progress: false
+            });
+        });
+
+        _this.getNavJson();
+        return false;
+    },
+
+    onToolReorder: function onToolReorder() {
+        $('.react-drag.dragging').removeClass('dragging');
+
+        var params = { _session_id: $.cookie('_session_id') };
+        var toolNodes = $(ReactDOM.findDOMNode(this)).find('span.ordinal-item').not(".toolbar-grouper");
+        for (var i = 0; i < toolNodes.length; i++) {
+            params[i] = toolNodes[i].dataset.mountPoint;
+        }
+
+        var _this = this;
+        var url = _getProjectUrl() + '/admin/mount_order';
+        $.ajax({
+            type: 'POST',
+            url: url,
+            data: params,
+            success: function success() {
+                $('#messages').notify('Tool order updated', {
+                    status: 'confirm',
+                    interval: 500,
+                    timer: 2000
+                });
+                _this.getNavJson();
+            },
+
+            error: function error() {
+                $('#messages').notify('Error saving tool order.', {
+                    status: 'error'
+                });
+            }
+        });
+    },
+
+    onToolDragStart: function onToolDragStart(obj) {
+        var dragging_mount_point = obj.props.children.props.mount_point;
+        $('[data-mount-point=' + dragging_mount_point + ']').closest('.react-drag').addClass('dragging');
+    },
+
+    render: function render() {
+        var _this2 = this;
+
+        var _this = this;
+        var navBarSwitch = function navBarSwitch(showAdmin) {
+            if (showAdmin) {
+                return React.createElement(AdminNav, {
+                    tools: _this.state.data.menu,
+                    installableTools: _this.state.data.installable_tools,
+                    data: _this.state.data,
+                    onToolReorder: _this.onToolReorder,
+                    onToolDragStart: _this.onToolDragStart,
+                    editMode: _this.state.visible,
+                    currentOptionMenu: _this.state.currentOptionMenu,
+                    onOptionClick: _this.handleShowOptionMenu,
+                    currentToolOptions: _this2.state.currentToolOptions
+                });
+            } else {
+                return React.createElement(
+                    'div',
+                    null,
+                    React.createElement(NormalNavBar, {
+                        items: _this.state.data.menu,
+                        installableTools: _this.state.data.installable_tools
+                    })
+                );
+            }
+        };
+        var navBar = navBarSwitch(this.state.visible);
+
+        var max_tool_count = _.chain(this.state.data.menu).map(function (item) {
+            return item.children ? _.pluck(item.children, 'tool_name') : item.tool_name;
+        }).flatten().countBy().values().max().value();
+        var show_grouping_threshold = max_tool_count > 1;
+
+        return React.createElement(
+            'div',
+            {
+                className: 'nav_admin ' },
+            navBar,
+            React.createElement(
+                'div',
+                { id: 'bar-config' },
+                show_grouping_threshold && React.createElement(GroupingThreshold, {
+                    onUpdateThreshold: this.onUpdateThreshold,
+                    isHidden: this.state.visible,
+                    initialValue: parseInt(this.state.data.grouping_threshold) })
+            ),
+            React.createElement(ToggleAdminButton, {
+                handleButtonPush: this.handleToggleAdmin,
+                visible: this.state.visible })
+        );
+    }
+});
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5hdmJhci5lczYuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQWtCQSxZQUFZLENBQUM7Ozs7QUFTYixTQUFTLGNBQWMsR0FBYztRQUFiLElBQUkseURBQUcsSUFBSTs7QUFDL0IsUUFBSSxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQztBQUMxQixRQUFJLGFBQWEsR0FBRyxRQUFRLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Ozs7OztBQUM5RSw2QkFBZ0IsYUFBYSw4SEFBRTtnQkFBdEIsR0FBRzs7QUFDUixnQkFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRTtBQUMvQixvQkFBSSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ3ZDO1NBQ0o7Ozs7Ozs7Ozs7Ozs7Ozs7QUFDRCxRQUFJLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzlDLFFBQUksSUFBSSxLQUFLLFVBQVUsRUFBRTtBQUNyQixpQkFBUyxHQUFHLElBQUksQ0FBQztLQUNwQixNQUFNO0FBQ0gsaUJBQVMsR0FBTSxJQUFJLFNBQUksSUFBSSxBQUFFLENBQUM7S0FDakM7QUFDRCxXQUFPLENBQUMsSUFBSSxHQUFHLFFBQVEsR0FBRyxHQUFHLENBQUEsR0FBSSxTQUFTLENBQUM7Q0FDOUM
 7O0FBU0QsU0FBUyxhQUFhLENBQUMsSUFBSSxFQUFFO0FBQ3pCLFFBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssSUFBSSxFQUFDO0FBQ2xFLGVBQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0tBQzlCO0FBQ0QsV0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDO0NBQ25EOztBQVNELFNBQVMsWUFBWSxDQUFDLElBQUksRUFBRTtBQUN4QixRQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksRUFBQztBQUNsRCxlQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztLQUN0QjtBQUNELFdBQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQztDQUMzQzs7QUFFRCxJQUFNLGFBQWEsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQztBQUN4QyxlQUFXLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNO0FBQ25DLFFBQUksRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVO0FBQ3ZDLE9BQUcsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVO0FBQ3RDLGVBQVcsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVO0FBQzVDLGFBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxD
 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
 OUIsWUFBSSx1QkFBdUIsR0FBRyxjQUFjLEdBQUcsQ0FBQyxDQUFDOztBQUVqRCxlQUNJOzs7QUFDSSx5QkFBUyxFQUFHLFlBQVksQUFBQztZQUN2QixNQUFNO1lBQ1I7O2tCQUFLLEVBQUUsRUFBQyxZQUFZO2dCQUNmLHVCQUF1QixJQUN4QixvQkFBQyxpQkFBaUI7QUFDZCxxQ0FBaUIsRUFBRyxJQUFJLENBQUMsaUJBQWlCLEFBQUU7QUFDNUMsNEJBQVEsRUFBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQUFBRTtBQUMvQixnQ0FBWSxFQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxBQUFFLEdBQUU7YUFDakU7WUFDTixvQkFBQyxpQkFBaUI7QUFDZCxnQ0FBZ0IsRUFBRyxJQUFJLENBQUMsaUJBQWlCLEFBQUU7QUFDM0MsdUJBQU8sRUFBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQUFBRSxHQUFFO1NBQ2xDLENBQ1I7S0FDTDtDQUNKLENBQUMsQ0FBQyIsImZpbGUiOiJuYXZiYXIuZXM2LmpzIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgICAgICBMaWNlbnNlZCB0byB0aGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gKEFTRikgdW5kZXIgb25lXG4gICAgICAgb3IgbW9yZSBjb250cmlidXRvciBsaWNlbnNlIGFncmVlbWVudHMuICBTZWUgdGhlIE5PVElDRSBmaWxlXG4gICAgICAgZGlzdHJpYnV0ZWQgd2l0aCB0aGlzIHdvcmsgZm9yIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25cbiAgICAgICByZWdhcmRpbmcgY29weXJpZ2h0IG93bmVyc2hpcC4gIFRoZ
 SBBU0YgbGljZW5zZXMgdGhpcyBmaWxlXG4gICAgICAgdG8geW91IHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZVxuICAgICAgIFwiTGljZW5zZVwiKTsgeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZVxuICAgICAgIHdpdGggdGhlIExpY2Vuc2UuICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcblxuICAgICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG5cbiAgICAgICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsXG4gICAgICAgc29mdHdhcmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW5cbiAgICAgICBcIkFTIElTXCIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWVxuICAgICAgIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZVxuICAgICAgIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQgbGltaXRhdGlvbnNcbiAgICAgICB1bmRlciB0aGUgTGljZW5zZS5cbiovXG4ndXNlIHN0cmljdCc7XG5cbi8qKlxuICogR2V0cyB0aGUgY3VycmVudCBwcm9qZWN0IHVybC5cblxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge2Jvb2x9IHJlc3QgLSBSZXR1cm4gYSBcIn
 Jlc3RcIiB2ZXJzaW9uIG9mIHRoZSB1cmwuXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBfZ2V0UHJvamVjdFVybChyZXN0ID0gdHJ1ZSkge1xuICAgIHZhciBuYmhkLCBwcm9qLCBuYmhkX3Byb2o7XG4gICAgdmFyIGlkZW50X2NsYXNzZXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgncGFnZS1ib2R5JykuY2xhc3NOYW1lLnNwbGl0KCcgJyk7XG4gICAgZm9yICh2YXIgY2xzIG9mIGlkZW50X2NsYXNzZXMpIHtcbiAgICAgICAgaWYgKGNscy5pbmRleE9mKCdwcm9qZWN0LScpID09PSAwKSB7XG4gICAgICAgICAgICBwcm9qID0gY2xzLnNsaWNlKCdwcm9qZWN0LScubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBuYmhkID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lLnNwbGl0KCcvJylbMV07XG4gICAgaWYgKHByb2ogPT09ICctLWluaXQtLScpIHtcbiAgICAgICAgbmJoZF9wcm9qID0gbmJoZDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBuYmhkX3Byb2ogPSBgJHtuYmhkfS8ke3Byb2p9YDtcbiAgICB9XG4gICAgcmV0dXJuIChyZXN0ID8gJy9yZXN0LycgOiAnLycpICsgbmJoZF9wcm9qO1xufVxuXG4vKipcbiAqIEdldCBhIG1vdW50IHBvaW50IGZyb20gYSBOYXZCYXJJdGVtIG5vZGUuXG5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtOYXZCYXJJdGVtfSBub2RlXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBnZXRNb3VudFBvaW50KG5vZGUpIHtcbiA
 gICBpZihub2RlLmhhc093blByb3BlcnR5KCdtb3VudF9wb2ludCcpICYmIG5vZGVbJ21vdW50X3BvaW50J10gIT09IG51bGwpe1xuICAgICAgICByZXR1cm4gbm9kZVsnbW91bnRfcG9pbnQnXTtcbiAgICB9XG4gICAgcmV0dXJuIG5vZGUucHJvcHMuY2hpbGRyZW5bMF0ucHJvcHMubW91bnRfcG9pbnQ7XG59XG5cbi8qKlxuICogR2V0IGEgdXJsIGZyb20gYSBOYXZCYXJJdGVtIG5vZGUuXG5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtOYXZCYXJJdGVtfSBub2RlXG4gKiBAcmV0dXJucyB7c3RyaW5nfVxuICovXG5mdW5jdGlvbiBnZXRVcmxCeU5vZGUobm9kZSkge1xuICAgIGlmKG5vZGUuaGFzT3duUHJvcGVydHkoJ3VybCcpICYmIG5vZGVbJ3VybCddICE9PSBudWxsKXtcbiAgICAgICAgcmV0dXJuIG5vZGVbJ3VybCddO1xuICAgIH1cbiAgICByZXR1cm4gbm9kZS5wcm9wcy5jaGlsZHJlblswXS5wcm9wcy51cmw7XG59XG5cbmNvbnN0IFRvb2xzUHJvcFR5cGUgPSBSZWFjdC5Qcm9wVHlwZXMuc2hhcGUoe1xuICAgIG1vdW50X3BvaW50OiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIG5hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICB1cmw6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICBpc19hbmNob3JlZDogUmVhY3QuUHJvcFR5cGVzLmJvb2wuaXNSZXF1aXJlZCxcbiAgICB0b29sX25hbWU6IFJlYWN0LlByb3BUeXBlcy5zdHJpbmcuaXNS
 ZXF1aXJlZCxcbiAgICBpY29uOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLFxuICAgIGNoaWxkcmVuOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgYWRtaW5fb3B0aW9uczogUmVhY3QuUHJvcFR5cGVzLmFycmF5XG59KTtcblxuLyoqXG4gKiBBIHNpbmdsZSBOYXZCYXIgaXRlbS5cblxuICogQGNvbnN0cnVjdG9yXG4gKi9cbnZhciBOYXZCYXJJdGVtID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIHByb3BUeXBlczoge1xuICAgICAgICBuYW1lOiBSZWFjdC5Qcm9wVHlwZXMuc3RyaW5nLmlzUmVxdWlyZWQsXG4gICAgICAgIHVybDogUmVhY3QuUHJvcFR5cGVzLnN0cmluZy5pc1JlcXVpcmVkLFxuICAgICAgICBjdXJyZW50T3B0aW9uTWVudTogUmVhY3QuUHJvcFR5cGVzLm9iamVjdCxcbiAgICAgICAgb25PcHRpb25DbGljazogUmVhY3QuUHJvcFR5cGVzLmZ1bmMuaXNSZXF1aXJlZCxcbiAgICAgICAgb3B0aW9uczogUmVhY3QuUHJvcFR5cGVzLmFycmF5XG4gICAgfSxcblxuICAgIGlzQW5jaG9yZWQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5wcm9wcy5pc19hbmNob3JlZCAhPT0gbnVsbDtcbiAgICB9LFxuXG4gICAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGRpdkNsYXNzZXMgPSBcInRiLWl0ZW0gdGItaXRlbS1lZGl0XCI7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmlzX2FuY2hvcmVkKSB7XG4gICAgICAgICAgICBkaXZDbGFzc2VzICs9IFwiIGFuY2hvcmVkXCI7X
 G4gICAgICAgIH1cbiAgICAgICAgdmFyIHNwYW5DbGFzc2VzID0gdGhpcy5wcm9wcy5oYW5kbGVUeXBlICsgXCIgb3JkaW5hbC1pdGVtXCI7XG4gICAgICAgIGlmICh0aGlzLnByb3BzLmlzR3JvdXBlcikge1xuICAgICAgICAgICAgc3BhbkNsYXNzZXMgKz0gXCIgdG9vbGJhci1ncm91cGVyXCJcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT17IGRpdkNsYXNzZXMgfT5cbiAgICAgICAgICAgICAgICA8YT5cbiAgICAgICAgICAgICAgICAgICAgeyFfLmlzRW1wdHkodGhpcy5wcm9wcy5vcHRpb25zKSAmJiA8aSBjbGFzc05hbWU9J2NvbmZpZy10b29sIGZhIGZhLWNvZycgb25DbGljaz17dGhpcy5oYW5kbGVPcHRpb25DbGlja30+PC9pPn1cbiAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17c3BhbkNsYXNzZXN9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhLW1vdW50LXBvaW50PXt0aGlzLnByb3BzLm1vdW50X3BvaW50fT5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLm5hbWV9XG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAge3RoaXMucHJvcHMuY3VycmVudE9wdGlvbk1lbnUudG9vbCAmJiB0aGlzLnByb3BzLmN1cnJlbnRPcHRpb25NZW51LnRvb2wgPT09IHRoaXMucHJvcHMubW91bnRfcG9pbn
 QgJiZcbiAgICAgICAgICAgICAgICAgICAgPENvbnRleHRNZW51XG4gICAgICAgICAgICAgICAgICAgICAgICB7Li4udGhpcy5wcm9wc31cbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzZXM9e1sndG9vbC1vcHRpb25zJ119XG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtcz17dGhpcy5wcm9wcy5vcHRpb25zfVxuICAgICAgICAgICAgICAgICAgICAgICAgb25PcHRpb25DbGljaz17dGhpcy5wcm9wcy5vbk9wdGlvbkNsaWNrfVxuICAgICAgICAgICAgICAgICAgICAvPn1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH0sXG5cbiAgICBoYW5kbGVPcHRpb25DbGljazogZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgdGhpcy5wcm9wcy5vbk9wdGlvbkNsaWNrKHRoaXMucHJvcHMubW91bnRfcG9pbnQpO1xuICAgIH1cbn0pO1xuXG4vKipcbiAqIEFuIGlucHV0IGNvbXBvbmVudCB0aGF0IHVwZGF0ZXMgdGhlIE5hdkJhcidzIGdyb3VwaW5nIHRocmVzaG9sZC5cblxuICogQGNvbnN0cnVjdG9yXG4gKi9cbnZhciBHcm91cGluZ1RocmVzaG9sZCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBwcm9wVHlwZXM6IHtcbiAgICAgICAgaW5pdGlhbFZhbHVlOiBSZWFjdC5Qcm9wVHlwZXMubnVtYmVyLmlzUmVxdWlyZWRcbiAgICB9LFxuICAgIGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWx1ZTogdGhpcy5wcm9wcy5pbml0aWF
 sVmFsdWVcbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgaGFuZGxlQ2hhbmdlOiBmdW5jdGlvbihldmVudCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHZhbHVlOiBldmVudC50YXJnZXQudmFsdWVcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMucHJvcHMub25VcGRhdGVUaHJlc2hvbGQoZXZlbnQpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICB7ICEhdGhpcy5wcm9wcy5pc0hpZGRlbiAmJlxuICAgICAgICAgICAgICAgIDxkaXYgaWQ9J3RocmVzaG9sZC1jb25maWcnPlxuICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgIDxsYWJlbCBodG1sRm9yPSd0aHJlc2hvbGQtaW5wdXQnPkdyb3VwaW5nIFRocmVzaG9sZDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0IHR5cGU9J251bWJlcicgbmFtZT0ndGhyZXNob2xkLWlucHV0JyBjbGFzc05hbWU9J3Rvb2x0aXAnXG4gICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPSdOdW1iZXIgb2YgdG9vbHMgYWxsb3dlZCBiZWZvcmUgZ3JvdXBpbmcuJ1xuICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZT17IHRoaXMuc3RhdGUudmFsdWUgfVxuICAgICAgICAgICAgICAgICAgICAgICBvbkNoYW5nZT17IHRoaXMuaGFuZGxlQ2hhbmdlIH1cbiAgICAgICAgICAgICAgICAgICAgICAgbWluPScxJyBtYXg9JzEwJy8+
 XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2Rpdj4gfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfVxufSk7XG5cbi8qKlxuICogVGhlIE5hdkJhciB3aGVuIGluIFwiTm9ybWFsXCIgbW9kZS5cblxuICogQGNvbnN0cnVjdG9yXG4gKi9cbnZhciBOb3JtYWxOYXZJdGVtID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICBtaXhpbnM6IFtSZWFjdC5hZGRvbnMuUHVyZVJlbmRlck1peGluXSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxsaSBrZXk9e2B0Yi1ub3JtLSR7Xy51bmlxdWVJZCgpfWB9PlxuICAgICAgICAgICAgICAgIDxhIGhyZWY9eyB0aGlzLnByb3BzLnVybCB9IGNsYXNzTmFtZT17IHRoaXMucHJvcHMuY2xhc3NlcyB9PlxuICAgICAgICAgICAgICAgICAgICB7IHRoaXMucHJvcHMubmFtZSB9XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLmNoaWxkcmVufVxuICAgICAgICAgICAgPC9saT5cbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuLyoqXG4gKiBUb2dnbGUgQnV0dG9uXG5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG52YXIgVG9nZ2xlQWRkTmV3VG9vbCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmlzaWJsZTogZmFsc2VcbiAgI
 CAgICAgfTtcbiAgICB9LFxuICAgIGhhbmRsZVRvZ2dsZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgdmlzaWJsZTogIXRoaXMuc3RhdGUudmlzaWJsZVxuICAgICAgICB9KTtcbiAgICB9LFxuICAgICAgICBoYW5kbGVPcHRpb25DbGljazogZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKCdldmVudCcsIGV2ZW50KTtcbiAgICAgICAgLy90aGlzLnByb3BzLm9uT3B0aW9uQ2xpY2sodGhpcy5wcm9wcy5tb3VudF9wb2ludCk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdj5cbiAgICAgICAgICAgICAgICA8YSBvbkNsaWNrPXsgdGhpcy5oYW5kbGVUb2dnbGUgfSBjbGFzc05hbWU9XCJhZGQtdG9vbC10b2dnbGVcIj5cbiAgICAgICAgICAgICAgICAgICAgQWRkIE5ldy4uLlxuICAgICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgICB7dGhpcy5zdGF0ZS52aXNpYmxlICYmXG4gICAgICAgICAgICAgICAgPENvbnRleHRNZW51XG4gICAgICAgICAgICAgICAgICAgIHsuLi50aGlzLnByb3BzfVxuICAgICAgICAgICAgICAgICAgICBjbGFzc2VzPXtbJ2FkbWluX21vZGFsJ119XG4gICAgICAgICAgICAgICAgICAgIG9uT3B0aW9uQ2xpY2s9e3RoaXMuaGFuZGxlT3B0aW9uQ2xpY2t9XG4gICAgICAgICAgICAgICAgICAgIGl0ZW1zPXt0aGlzLnByb3BzLm
 luc3RhbGxhYmxlVG9vbHN9IC8+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIClcbiAgICB9XG59KTtcblxuLyoqXG4gKiBUaGUgTmF2QmFyIHdoZW4gaW4gXCJOb3JtYWxcIiBtb2RlLlxuXG4gKiBAY29uc3RydWN0b3JcbiAqL1xudmFyIE5vcm1hbE5hdkJhciA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICBidWlsZE1lbnU6IGZ1bmN0aW9uKGl0ZW0sIGkpIHtcbiAgICAgICAgbGV0IGNsYXNzZXMgPSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWUuc3RhcnRzV2l0aChpdGVtLnVybCkgPyAnYWN0aXZlLW5hdi1saW5rJyA6ICcnO1xuXG4gICAgICAgIHZhciBzdWJNZW51O1xuICAgICAgICBpZiAoaXRlbS5jaGlsZHJlbikge1xuICAgICAgICAgICAgc3ViTWVudSA9IGl0ZW0uY2hpbGRyZW4ubWFwKHRoaXMuYnVpbGRNZW51KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPE5vcm1hbE5hdkl0ZW0gdXJsPXtpdGVtLnVybH0gbmFtZT17aXRlbS5uYW1lfSBjbGFzc2VzPXtjbGFzc2VzfSBrZXk9e2Bub3JtYWwtbmF2LSR7Xy51bmlxdWVJZCgpfWB9PlxuICAgICAgICAgICAgICAgIDx1bD5cbiAgICAgICAgICAgICAgICAgICAge3N1Yk1lbnV9XG4gICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgIDwvTm9ybWFsTmF2SXRlbT5cbiAgICAgICAgKTtcbiAgICB9LFxuXG4gICAgb25PcHRpb25DbGljazogZnVuY3Rpb24oZSl7XG4gICAgICA
 gIGNvbnNvbGUubG9nKGUpO1xuICAgIH0sXG4gICAgcmVuZGVyOiBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIGxpc3RJdGVtcyA9IHRoaXMucHJvcHMuaXRlbXMubWFwKHRoaXMuYnVpbGRNZW51KTtcblxuICAgICAgICB2YXIgbW91bnRfcG9pbnRzID0gW107XG4gICAgICAgIGZvcihsZXQgaXRlbSBvZiB0aGlzLnByb3BzLml0ZW1zKXtcbiAgICAgICAgICAgIGlmKGl0ZW0uaGFzT3duUHJvcGVydHkoJ21vdW50X3BvaW50JykgJiYgaXRlbS5tb3VudF9wb2ludCAhPT0gbnVsbCl7XG4gICAgICAgICAgICAgICAgbW91bnRfcG9pbnRzLnB1c2goaXRlbS5tb3VudF9wb2ludCk7XG4gICAgICAgICAgICB9IGVsc2UgaWYoaXRlbS5oYXNPd25Qcm9wZXJ0eSgnY2hpbGRyZW4nKSl7XG4gICAgICAgICAgICAgICAgZm9yKGxldCBjaGlsZCBvZiBpdGVtLmNoaWxkcmVuKXtcbiAgICAgICAgICAgICAgICAgICAgbW91bnRfcG9pbnRzLnB1c2goY2hpbGQubW91bnRfcG9pbnQpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKFwibW91bnRfcG9pbnRzXCIsIG1vdW50X3BvaW50cyk7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8dWxcbiAgICAgICAgICAgICAgICBpZD1cIm5vcm1hbC1uYXYtYmFyXCJcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCJkcm9wZG93blwiPlxuICAgICAgICAgICAgICAgIHsgbGlzdEl0ZW1zIH1cbiAgICAgICAg
 ICAgICAgICA8bGkgaWQ9XCJhZGQtdG9vbC1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPFRvZ2dsZUFkZE5ld1Rvb2xcbiAgICAgICAgICAgICAgICAgICAgICAgIHsuLi50aGlzLnByb3BzfVxuICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXM9e3RoaXMucHJvcHMuaW5zdGFsbGFibGVUb29sc31cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uT3B0aW9uQ2xpY2s9e3RoaXMub25PcHRpb25DbGlja30gLz5cbiAgICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgPC91bD5cbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuLyoqXG4gKiBUaGUgTmF2QmFyIHdoZW4gaW4gXCJBZG1pblwiIG1vZGUuXG4gKiBAY29uc3RydWN0b3JcbiAqL1xudmFyIEFkbWluTmF2ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuICAgIHByb3BUeXBlczoge1xuICAgICAgICB0b29sczogUmVhY3QuUHJvcFR5cGVzLmFycmF5T2YoVG9vbHNQcm9wVHlwZSksXG4gICAgICAgIGN1cnJlbnRPcHRpb25NZW51OiBSZWFjdC5Qcm9wVHlwZXMub2JqZWN0LFxuICAgICAgICBvbk9wdGlvbkNsaWNrOiBSZWFjdC5Qcm9wVHlwZXMuZnVuYy5pc1JlcXVpcmVkXG4gICAgfSxcblxuICAgIGJ1aWxkTWVudTogZnVuY3Rpb24gKGl0ZW1zLCBpc1N1Yk1lbnU9ZmFsc2UpIHtcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcbiAgICAgICAgdmFyIFt0b29scywgYW5jaG9yZWRfdG9vbHMsIGVuZF90b29sc10gPSBbW10sIFtdLCBbXV07X
 G4gICAgICAgIHZhciBzdWJNZW51LCBjaGlsZE9wdGlvbnNPcGVuO1xuXG4gICAgICAgIGZvciAobGV0IGl0ZW0gb2YgaXRlbXMpIHtcbiAgICAgICAgICAgIGlmIChpdGVtLmNoaWxkcmVuKSB7XG4gICAgICAgICAgICAgICAgc3ViTWVudSA9IHRoaXMuYnVpbGRNZW51KGl0ZW0uY2hpbGRyZW4sIHRydWUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBzdWJNZW51ID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIF9oYW5kbGUgPSBpc1N1Yk1lbnUgPyBcImRyYWdnYWJsZS1oYW5kbGUtc3ViXCIgOiAnZHJhZ2dhYmxlLWhhbmRsZSc7XG5cbiAgICAgICAgICAgIHZhciB0b29sX2xpc3QsIGlzX2FuY2hvcmVkO1xuICAgICAgICAgICAgaWYgKGl0ZW0ubW91bnRfcG9pbnQgPT09ICdhZG1pbicpIHtcbiAgICAgICAgICAgICAgICAvLyBmb3JjZSBhZG1pbiB0byBlbmQsIGp1c3QgbGlrZSAnUHJvamVjdC5zaXRlbWFwKCknIGRvZXNcbiAgICAgICAgICAgICAgICB0b29sX2xpc3QgPSBlbmRfdG9vbHM7XG4gICAgICAgICAgICAgICAgaXNfYW5jaG9yZWQgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChpdGVtLmlzX2FuY2hvcmVkKSB7XG4gICAgICAgICAgICAgICAgdG9vbF9saXN0ID0gYW5jaG9yZWRfdG9vbHM7XG4gICAgICAgICAgICAgICAgaXNfYW5jaG9yZWQgPSB0cnVlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0b29sX2
 xpc3QgPSB0b29scztcbiAgICAgICAgICAgICAgICBpc19hbmNob3JlZCA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdmFyIGNvcmVfaXRlbSA9IDxOYXZCYXJJdGVtXG4gICAgICAgICAgICAgICAgey4uLl90aGlzLnByb3BzfVxuICAgICAgICAgICAgICAgIG1vdW50X3BvaW50PXsgaXRlbS5tb3VudF9wb2ludCB9XG4gICAgICAgICAgICAgICAgbmFtZT17IGl0ZW0ubmFtZSB9XG4gICAgICAgICAgICAgICAgaGFuZGxlVHlwZT17X2hhbmRsZX1cbiAgICAgICAgICAgICAgICBpc0dyb3VwZXI9e2l0ZW0uY2hpbGRyZW4gJiYgaXRlbS5jaGlsZHJlbi5sZW5ndGggPiAwfVxuICAgICAgICAgICAgICAgIHVybD17IGl0ZW0udXJsIH1cbiAgICAgICAgICAgICAgICBrZXk9eyAndGItaXRlbS0nICsgXy51bmlxdWVJZCgpIH1cbiAgICAgICAgICAgICAgICBpc19hbmNob3JlZD17IGlzX2FuY2hvcmVkIH1cbiAgICAgICAgICAgICAgICBvcHRpb25zPXsgaXRlbS5hZG1pbl9vcHRpb25zIH1cbiAgICAgICAgICAgIC8+O1xuICAgICAgICAgICAgaWYgKHN1Yk1lbnUpIHtcbiAgICAgICAgICAgICAgICBjaGlsZE9wdGlvbnNPcGVuID0gXy5jb250YWlucyhfLnBsdWNrKGl0ZW0uY2hpbGRyZW4sICdtb3VudF9wb2ludCcpLCB0aGlzLnByb3BzLmN1cnJlbnRPcHRpb25NZW51LnRvb2wpO1xuICAgICAgICAgICAgICAgIHRvb2xfbGlzdC5wdXNoKDxOYXZCYXJJdGVtV2l0aFN1Yk1lbnUga2V5PXtfLnVuaXF
 1ZUlkKCl9IHRvb2w9e2NvcmVfaXRlbX0gc3ViTWVudT17c3ViTWVudX0gY2hpbGRPcHRpb25zT3Blbj17Y2hpbGRPcHRpb25zT3Blbn0vPik7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRvb2xfbGlzdC5wdXNoKGNvcmVfaXRlbSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9J3JlYWN0LWRyYWcnPlxuICAgICAgICAgICAgICAgIHsgYW5jaG9yZWRfdG9vbHMgfVxuICAgICAgICAgICAgICAgIDxSZWFjdFJlb3JkZXJhYmxlXG4gICAgICAgICAgICAgICAgICAgIGtleT17ICdyZW9yZGVyLScgKyBfLnVuaXF1ZUlkKCkgfVxuICAgICAgICAgICAgICAgICAgICBoYW5kbGU9e1wiLlwiICsgX2hhbmRsZX1cbiAgICAgICAgICAgICAgICAgICAgbW9kZT17IGlzU3ViTWVudSA/ICdsaXN0JyA6ICdncmlkJyB9XG4gICAgICAgICAgICAgICAgICAgIG9uRHJhZ1N0YXJ0PXsgX3RoaXMucHJvcHMub25Ub29sRHJhZ1N0YXJ0IH1cbiAgICAgICAgICAgICAgICAgICAgb25Ecm9wPXsgX3RoaXMucHJvcHMub25Ub29sUmVvcmRlciB9PlxuICAgICAgICAgICAgICAgICAgICB7IHRvb2xzIH1cbiAgICAgICAgICAgICAgICA8L1JlYWN0UmVvcmRlcmFibGU+XG4gICAgICAgICAgICAgICAgeyBlbmRfdG9vbHMgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICk7XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVu
 Y3Rpb24gKCkge1xuICAgICAgICB2YXIgdG9vbHMgPSB0aGlzLmJ1aWxkTWVudSh0aGlzLnByb3BzLnRvb2xzKTtcbiAgICAgICAgcmV0dXJuIDxkaXY+e3Rvb2xzfTwvZGl2PjtcbiAgICB9XG59KTtcblxudmFyIE5hdkJhckl0ZW1XaXRoU3ViTWVudSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPXtcInRiLWl0ZW0tY29udGFpbmVyXCIgKyAodGhpcy5wcm9wcy5jaGlsZE9wdGlvbnNPcGVuID8gXCIgY2hpbGQtb3B0aW9ucy1vcGVuXCIgOiBcIlwiKX0+XG4gICAgICAgICAgICAgICAgeyB0aGlzLnByb3BzLnRvb2wgfVxuICAgICAgICAgICAgICAgIHt0aGlzLnByb3BzLnN1Yk1lbnUgJiZcbiAgICAgICAgICAgICAgICA8QWRtaW5JdGVtR3JvdXAga2V5PXtfLnVuaXF1ZUlkKCl9PlxuICAgICAgICAgICAgICAgICAgICB7dGhpcy5wcm9wcy5zdWJNZW51fVxuICAgICAgICAgICAgICAgIDwvQWRtaW5JdGVtR3JvdXA+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG5cbi8qKlxuICogVGhlIE5hdkJhciB3aGVuIGluIFwiQWRtaW5cIiBtb2RlLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbnZhciBBZG1pbkl0ZW1Hcm91cCA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcbiAgICByZW5kZXI6IGZ1bmN0aW9uICgpIHtcbiAgICAgI
 CAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwidGItaXRlbS1ncm91cGVyXCI+XG4gICAgICAgICAgICAgICAge3RoaXMucHJvcHMuY2hpbGRyZW59XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICB9XG59KTtcblxuLyoqXG4gKiBUaGUgYnV0dG9uIHRoYXQgdG9nZ2xlcyBOYXZCYXIgbW9kZXMuXG5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG52YXIgVG9nZ2xlQWRtaW5CdXR0b24gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIHZpc2libGU6IFJlYWN0LlByb3BUeXBlcy5ib29sXG4gICAgfSxcbiAgICByZW5kZXI6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgY2xhc3NlcyA9IHRoaXMucHJvcHMudmlzaWJsZSA/ICdmYSBmYS11bmxvY2snIDogJ2ZhIGZhLWxvY2snO1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPGJ1dHRvbiBpZD0ndG9nZ2xlLWFkbWluLWJ0bicgb25DbGljaz17IHRoaXMucHJvcHMuaGFuZGxlQnV0dG9uUHVzaCB9IGNsYXNzTmFtZT0nYWRtaW4tdG9vbGJhci1yaWdodCc+XG4gICAgICAgICAgICAgICAgPGkgY2xhc3NOYW1lPXsgY2xhc3NlcyB9PjwvaT5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICApO1xuICAgIH1cbn0pO1xuXG4vKipcbiAqIFRoZSBtYWluIFwiY29udHJvbGxlciB2aWV3XCIgb2YgdGhlIE5hdkJhci5cblxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH
 0gaW5pdGlhbERhdGFcbiAqL1xudmFyIE1haW4gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGluaXRpYWxEYXRhOiBSZWFjdC5Qcm9wVHlwZXMuc2hhcGUoe1xuICAgICAgICAgICAgbWVudTogUmVhY3QuUHJvcFR5cGVzLmFycmF5T2YoVG9vbHNQcm9wVHlwZSksXG4gICAgICAgICAgICBpbnN0YWxsYWJsZVRvb2xzOiBSZWFjdC5Qcm9wVHlwZXMuYXJyYXksXG4gICAgICAgICAgICBncm91cGluZ190aHJlc2hvbGQ6IFJlYWN0LlByb3BUeXBlcy5udW1iZXIuaXNSZXF1aXJlZFxuICAgICAgICB9KSxcbiAgICAgICAgaW5zdGFsbGFibGVUb29sczogUmVhY3QuUHJvcFR5cGVzLmFycmF5XG4gICAgfSxcbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGF0YTogdGhpcy5wcm9wcy5pbml0aWFsRGF0YSxcbiAgICAgICAgICAgIHZpc2libGU6IHRydWUsXG4gICAgICAgICAgICBfc2Vzc2lvbl9pZDogJC5jb29raWUoJ19zZXNzaW9uX2lkJyksXG4gICAgICAgICAgICBjdXJyZW50T3B0aW9uTWVudToge1xuICAgICAgICAgICAgICAgIHRvb2w6IG51bGxcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogV2hlbiBpbnZva2VkLCB0aGlzIHVwZGF0ZXMgdGhlIHN0YXRlIHdpdGggdGhlIGxhdGVzdCBkYXRhIGZyb20gdGhlIHNlcnZlci5cbiAgICAgKi9cbiAgICBnZXR
 OYXZKc29uOiBmdW5jdGlvbigpIHtcbiAgICAgICAgJC5nZXQoYCR7X2dldFByb2plY3RVcmwoZmFsc2UpfS9fbmF2Lmpzb24/YWRtaW5fb3B0aW9ucz0xYCwgZnVuY3Rpb24ocmVzdWx0KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc01vdW50ZWQoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgICAgICBkYXRhOiByZXN1bHRcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfS5iaW5kKHRoaXMpKTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgdGhlIGxvY2tpbmcgYW5kIHVubG9ja2luZyBvZiB0aGUgTmF2QmFyXG4gICAgICovXG4gICAgaGFuZGxlVG9nZ2xlQWRtaW46IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHtcbiAgICAgICAgICAgIHZpc2libGU6ICF0aGlzLnN0YXRlLnZpc2libGVcbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIGhhbmRsZVNob3dPcHRpb25NZW51OiBmdW5jdGlvbiAobW91bnRfcG9pbnQpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBjdXJyZW50T3B0aW9uTWVudToge1xuICAgICAgICAgICAgICAgIHRvb2w6IG1vdW50X3BvaW50LFxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogSGFuZGxlcyB0aGUgY2hhbmdpbmcgb2YgdGhlIE5hdkJhcnMgZ3JvdXBpbmcgdGhyZXNob2xkLlxuXG4gICAg
 ICogQHBhcmFtIHtvYmplY3R9IGV2ZW50XG4gICAgICovXG4gICAgb25VcGRhdGVUaHJlc2hvbGQ6IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB0aHJlcyA9IGV2ZW50LnRhcmdldC52YWx1ZTtcbiAgICAgICAgdmFyIHVybCA9IGAke19nZXRQcm9qZWN0VXJsKCl9L2FkbWluL2NvbmZpZ3VyZV90b29sX2dyb3VwaW5nYDtcbiAgICAgICAgdmFyIGNzcmYgPSAkLmNvb2tpZSgnX3Nlc3Npb25faWQnKTtcbiAgICAgICAgdmFyIGRhdGEgPSB7XG4gICAgICAgICAgICBfc2Vzc2lvbl9pZDogY3NyZixcbiAgICAgICAgICAgIGdyb3VwaW5nX3RocmVzaG9sZDogdGhyZXNcbiAgICAgICAgfTtcbiAgICAgICAgdmFyIF9kYXRhID0gdGhpcy5zdGF0ZS5kYXRhO1xuICAgICAgICBfZGF0YS5ncm91cGluZ190aHJlc2hvbGQgPSB0aHJlcztcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBkYXRhOiBfZGF0YVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICAgICAgICBpbl9wcm9ncmVzczogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgICAgJC5wb3N0KHVybCwgZGF0YSwgZnVuY3Rpb24oKSB7XG4gICAgICAgIH0uYmluZCh0aGlzKSkuYWx3YXlzKGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgX3RoaXMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgICAgIGluX3Byb2dyZXNzOiBmYWxzZVxuICAgICAgICAgICAgfSk7XG4gI
 CAgICAgIH0pO1xuXG4gICAgICAgIF90aGlzLmdldE5hdkpzb24oKTtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBIYW5kbGVzIHRoZSBzZW5kaW5nIGFuZCB1cGRhdGluZyB0b29sIG9yZGluYWxzLlxuXG4gICAgICogQHBhcmFtIHthcnJheX0gZGF0YSAtIEFycmF5IG9mIHRvb2xzXG4gICAgICovXG4gICAgb25Ub29sUmVvcmRlcjogZnVuY3Rpb24oKSB7XG4gICAgICAgICQoJy5yZWFjdC1kcmFnLmRyYWdnaW5nJykucmVtb3ZlQ2xhc3MoJ2RyYWdnaW5nJyk7XG5cbiAgICAgICAgdmFyIHBhcmFtcyA9IHtfc2Vzc2lvbl9pZDogJC5jb29raWUoJ19zZXNzaW9uX2lkJyl9O1xuICAgICAgICB2YXIgdG9vbE5vZGVzID0gJChSZWFjdERPTS5maW5kRE9NTm9kZSh0aGlzKSkuZmluZCgnc3Bhbi5vcmRpbmFsLWl0ZW0nKS5ub3QoXCIudG9vbGJhci1ncm91cGVyXCIpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRvb2xOb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgcGFyYW1zW2ldID0gdG9vbE5vZGVzW2ldLmRhdGFzZXQubW91bnRQb2ludDtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHZhciB1cmwgPSBfZ2V0UHJvamVjdFVybCgpICsgJy9hZG1pbi9tb3VudF9vcmRlcic7XG4gICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICB1cmw6IHVybCxcbiAgICAgIC
 AgICAgIGRhdGE6IHBhcmFtcyxcbiAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAkKCcjbWVzc2FnZXMnKS5ub3RpZnkoJ1Rvb2wgb3JkZXIgdXBkYXRlZCcsXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogJ2NvbmZpcm0nLFxuICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWw6IDUwMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVyOiAyMDAwXG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIF90aGlzLmdldE5hdkpzb24oKTtcbiAgICAgICAgICAgIH0sXG5cbiAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICAkKCcjbWVzc2FnZXMnKS5ub3RpZnkoJ0Vycm9yIHNhdmluZyB0b29sIG9yZGVyLicsXG4gICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1czogJ2Vycm9yJ1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSxcblxuICAgIG9uVG9vbERyYWdTdGFydDogZnVuY3Rpb24ob2JqKSB7XG4gICAgICAgIC8vIHRoaXMgaXMgZG9uZSB3aXRoIGpRdWVyeSBpbnN0ZWFkIG9mIHJlbmRlcmluZyBkaWZmZXJlbnQgSFRNTCB3aXRoIHJlYWN0XG4gICAgICAgIC8vIGJlY2F1c2UgdGhhdCBtZWFucyB5b3UgcmUtcmVuZGVyIHRoZSBIVE1MIHdoaWx
 lIHRoZSBkcmFnIGlzIGhhcHBlbmluZ1xuICAgICAgICAvLyBhbmQgdGhlIGFjdHVhbCBkcmFnZ2luZyBkb2Vzbid0IHdvcmsgYW55IG1vcmVcbiAgICAgICAgdmFyIGRyYWdnaW5nX21vdW50X3BvaW50ID0gb2JqLnByb3BzLmNoaWxkcmVuLnByb3BzLm1vdW50X3BvaW50O1xuICAgICAgICAkKGBbZGF0YS1tb3VudC1wb2ludD0ke2RyYWdnaW5nX21vdW50X3BvaW50fV1gKS5jbG9zZXN0KCcucmVhY3QtZHJhZycpLmFkZENsYXNzKCdkcmFnZ2luZycpO1xuICAgIH0sXG5cbiAgICByZW5kZXI6IGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgbmF2QmFyU3dpdGNoID0gKHNob3dBZG1pbikgPT4ge1xuICAgICAgICAgICAgaWYgKHNob3dBZG1pbikge1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIDxBZG1pbk5hdlxuICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHM9eyBfdGhpcy5zdGF0ZS5kYXRhLm1lbnUgfVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5zdGFsbGFibGVUb29scz17IF90aGlzLnN0YXRlLmRhdGEuaW5zdGFsbGFibGVfdG9vbHMgfVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT17IF90aGlzLnN0YXRlLmRhdGEgfVxuICAgICAgICAgICAgICAgICAgICAgICAgb25Ub29sUmVvcmRlcj17IF90aGlzLm9uVG9vbFJlb3JkZXIgfVxuICAgICAgICAgICAgICAgICAgICAgICAgb25Ub29sRHJhZ1N0YXJ0PXsg
 X3RoaXMub25Ub29sRHJhZ1N0YXJ0IH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGVkaXRNb2RlPXsgX3RoaXMuc3RhdGUudmlzaWJsZSB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50T3B0aW9uTWVudT17IF90aGlzLnN0YXRlLmN1cnJlbnRPcHRpb25NZW51IH1cbiAgICAgICAgICAgICAgICAgICAgICAgIG9uT3B0aW9uQ2xpY2s9eyBfdGhpcy5oYW5kbGVTaG93T3B0aW9uTWVudSB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50VG9vbE9wdGlvbnM9e3RoaXMuc3RhdGUuY3VycmVudFRvb2xPcHRpb25zfVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8Tm9ybWFsTmF2QmFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXRlbXM9eyBfdGhpcy5zdGF0ZS5kYXRhLm1lbnUgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RhbGxhYmxlVG9vbHM9eyBfdGhpcy5zdGF0ZS5kYXRhLmluc3RhbGxhYmxlX3Rvb2xzIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICB2YXIgbmF2QmFyID0gbmF2QmFyU3dpd
 GNoKHRoaXMuc3RhdGUudmlzaWJsZSk7XG5cbiAgICAgICAgdmFyIG1heF90b29sX2NvdW50ID0gXy5jaGFpbih0aGlzLnN0YXRlLmRhdGEubWVudSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcCgoaXRlbSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGl0ZW0uY2hpbGRyZW4gPyBfLnBsdWNrKGl0ZW0uY2hpbGRyZW4sICd0b29sX25hbWUnKSA6IGl0ZW0udG9vbF9uYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5mbGF0dGVuKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvdW50QnkoKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAudmFsdWVzKClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1heCgpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWx1ZSgpO1xuICAgICAgICB2YXIgc2hvd19ncm91cGluZ190aHJlc2hvbGQgPSBtYXhfdG9vbF9jb3VudCA+IDE7XG5cbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9eyAnbmF2X2FkbWluICd9PlxuICAgICAgICAgICAgICAgIHsgbmF2QmFyIH1cbiAgICAgICAgICAgICAgICA8ZGl2IGlkPSdiYXItY29uZmlnJz5cbiAgICAgICAgICAgICAgICAgICAge3Nob3dfZ3JvdXBpbmdfdGhyZXNob2xkICYmXG4gICAgICAgICAgICAgIC
 AgICAgIDxHcm91cGluZ1RocmVzaG9sZFxuICAgICAgICAgICAgICAgICAgICAgICAgb25VcGRhdGVUaHJlc2hvbGQ9eyB0aGlzLm9uVXBkYXRlVGhyZXNob2xkIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGlzSGlkZGVuPXsgdGhpcy5zdGF0ZS52aXNpYmxlIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGluaXRpYWxWYWx1ZT17IHBhcnNlSW50KHRoaXMuc3RhdGUuZGF0YS5ncm91cGluZ190aHJlc2hvbGQpIH0vPiB9XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPFRvZ2dsZUFkbWluQnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZUJ1dHRvblB1c2g9eyB0aGlzLmhhbmRsZVRvZ2dsZUFkbWluIH1cbiAgICAgICAgICAgICAgICAgICAgdmlzaWJsZT17IHRoaXMuc3RhdGUudmlzaWJsZSB9Lz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICApO1xuICAgIH1cbn0pO1xuIl19
\ No newline at end of file